aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig10
-rw-r--r--drivers/acpi/Makefile4
-rw-r--r--drivers/acpi/acpica/tbutils.c7
-rw-r--r--drivers/acpi/acpica/uteval.c21
-rw-r--r--drivers/acpi/battery.c25
-rw-r--r--drivers/acpi/bus.c9
-rw-r--r--drivers/acpi/container.c5
-rw-r--r--drivers/acpi/dock.c16
-rw-r--r--drivers/acpi/ec.c80
-rw-r--r--drivers/acpi/event.c6
-rw-r--r--drivers/acpi/glue.c8
-rw-r--r--drivers/acpi/numa.c2
-rw-r--r--drivers/acpi/osl.c4
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/processor_idle.c667
-rw-r--r--drivers/acpi/processor_perflib.c105
-rw-r--r--drivers/acpi/sleep.c (renamed from drivers/acpi/main.c)69
-rw-r--r--drivers/acpi/tables.c7
-rw-r--r--drivers/acpi/thermal.c16
-rw-r--r--drivers/acpi/video.c16
-rw-r--r--drivers/amba/bus.c4
-rw-r--r--drivers/ata/Kconfig15
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/ahci.c96
-rw-r--r--drivers/ata/ata_generic.c4
-rw-r--r--drivers/ata/ata_piix.c131
-rw-r--r--drivers/ata/libata-core.c197
-rw-r--r--drivers/ata/libata-eh.c113
-rw-r--r--drivers/ata/libata-pmp.c2
-rw-r--r--drivers/ata/libata-scsi.c38
-rw-r--r--drivers/ata/libata-sff.c137
-rw-r--r--drivers/ata/libata.h6
-rw-r--r--drivers/ata/pata_acpi.c6
-rw-r--r--drivers/ata/pata_ali.c56
-rw-r--r--drivers/ata/pata_amd.c146
-rw-r--r--drivers/ata/pata_artop.c49
-rw-r--r--drivers/ata/pata_at32.c4
-rw-r--r--drivers/ata/pata_atiixp.c38
-rw-r--r--drivers/ata/pata_bf54x.c2
-rw-r--r--drivers/ata/pata_cmd640.c2
-rw-r--r--drivers/ata/pata_cmd64x.c24
-rw-r--r--drivers/ata/pata_cs5520.c2
-rw-r--r--drivers/ata/pata_cs5530.c8
-rw-r--r--drivers/ata/pata_cs5535.c4
-rw-r--r--drivers/ata/pata_cs5536.c4
-rw-r--r--drivers/ata/pata_cypress.c4
-rw-r--r--drivers/ata/pata_efar.c6
-rw-r--r--drivers/ata/pata_hpt366.c4
-rw-r--r--drivers/ata/pata_hpt37x.c28
-rw-r--r--drivers/ata/pata_hpt3x2n.c4
-rw-r--r--drivers/ata/pata_hpt3x3.c6
-rw-r--r--drivers/ata/pata_icside.c4
-rw-r--r--drivers/ata/pata_isapnp.c14
-rw-r--r--drivers/ata/pata_it8213.c4
-rw-r--r--drivers/ata/pata_it821x.c19
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c2
-rw-r--r--drivers/ata/pata_jmicron.c4
-rw-r--r--drivers/ata/pata_legacy.c9
-rw-r--r--drivers/ata/pata_marvell.c8
-rw-r--r--drivers/ata/pata_mpc52xx.c4
-rw-r--r--drivers/ata/pata_mpiix.c2
-rw-r--r--drivers/ata/pata_netcell.c4
-rw-r--r--drivers/ata/pata_ninja32.c2
-rw-r--r--drivers/ata/pata_ns87410.c2
-rw-r--r--drivers/ata/pata_ns87415.c8
-rw-r--r--drivers/ata/pata_octeon_cf.c965
-rw-r--r--drivers/ata/pata_oldpiix.c4
-rw-r--r--drivers/ata/pata_opti.c2
-rw-r--r--drivers/ata/pata_optidma.c10
-rw-r--r--drivers/ata/pata_pcmcia.c36
-rw-r--r--drivers/ata/pata_pdc2027x.c12
-rw-r--r--drivers/ata/pata_pdc202xx_old.c12
-rw-r--r--drivers/ata/pata_qdi.c6
-rw-r--r--drivers/ata/pata_radisys.c6
-rw-r--r--drivers/ata/pata_rb532_cf.c66
-rw-r--r--drivers/ata/pata_rz1000.c2
-rw-r--r--drivers/ata/pata_sc1200.c35
-rw-r--r--drivers/ata/pata_scc.c4
-rw-r--r--drivers/ata/pata_sch.c6
-rw-r--r--drivers/ata/pata_serverworks.c20
-rw-r--r--drivers/ata/pata_sil680.c8
-rw-r--r--drivers/ata/pata_sis.c32
-rw-r--r--drivers/ata/pata_sl82c105.c6
-rw-r--r--drivers/ata/pata_triflex.c4
-rw-r--r--drivers/ata/pata_via.c50
-rw-r--r--drivers/ata/pata_winbond.c2
-rw-r--r--drivers/ata/pdc_adma.c4
-rw-r--r--drivers/ata/sata_fsl.c6
-rw-r--r--drivers/ata/sata_inic162x.c4
-rw-r--r--drivers/ata/sata_mv.c931
-rw-r--r--drivers/ata/sata_nv.c98
-rw-r--r--drivers/ata/sata_promise.c30
-rw-r--r--drivers/ata/sata_qstor.c3
-rw-r--r--drivers/ata/sata_sil.c55
-rw-r--r--drivers/ata/sata_sil24.c18
-rw-r--r--drivers/ata/sata_sis.c4
-rw-r--r--drivers/ata/sata_svw.c16
-rw-r--r--drivers/ata/sata_sx4.c4
-rw-r--r--drivers/ata/sata_uli.c2
-rw-r--r--drivers/ata/sata_via.c18
-rw-r--r--drivers/ata/sata_vsc.c7
-rw-r--r--drivers/atm/firestream.c8
-rw-r--r--drivers/atm/fore200e.c4
-rw-r--r--drivers/atm/iphase.c4
-rw-r--r--drivers/atm/lanai.c2
-rw-r--r--drivers/atm/solos-attrlist.c70
-rw-r--r--drivers/atm/solos-pci.c825
-rw-r--r--drivers/base/base.h33
-rw-r--r--drivers/base/bus.c44
-rw-r--r--drivers/base/core.c104
-rw-r--r--drivers/base/dd.c45
-rw-r--r--drivers/base/driver.c15
-rw-r--r--drivers/base/firmware_class.c4
-rw-r--r--drivers/base/node.c2
-rw-r--r--drivers/base/platform.c60
-rw-r--r--drivers/base/power/main.c47
-rw-r--r--drivers/base/power/power.h8
-rw-r--r--drivers/base/sys.c61
-rw-r--r--drivers/block/Kconfig7
-rw-r--r--drivers/block/Makefile4
-rw-r--r--drivers/block/aoe/aoe.h1
-rw-r--r--drivers/block/aoe/aoedev.c2
-rw-r--r--drivers/block/aoe/aoenet.c4
-rw-r--r--drivers/block/ataflop.c4
-rw-r--r--drivers/block/cciss.c224
-rw-r--r--drivers/block/cpqarray.c1
-rw-r--r--drivers/block/floppy.c82
-rw-r--r--drivers/block/loop.c51
-rw-r--r--drivers/block/nbd.c9
-rw-r--r--drivers/block/paride/pg.c2
-rw-r--r--drivers/block/ps3disk.c18
-rw-r--r--drivers/block/ps3vram.c865
-rw-r--r--drivers/block/swim.c995
-rw-r--r--drivers/block/swim_asm.S247
-rw-r--r--drivers/block/ub.c11
-rw-r--r--drivers/block/xen-blkfront.c32
-rw-r--r--drivers/block/xsysace.c22
-rw-r--r--drivers/bluetooth/bfusb.c3
-rw-r--r--drivers/bluetooth/bt3c_cs.c4
-rw-r--r--drivers/bluetooth/btusb.c40
-rw-r--r--drivers/bluetooth/hci_h4.c3
-rw-r--r--drivers/bluetooth/hci_ll.c3
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/agp/amd64-agp.c13
-rw-r--r--drivers/char/agp/intel-agp.c8
-rw-r--r--drivers/char/agp/parisc-agp.c23
-rw-r--r--drivers/char/hvc_console.c2
-rw-r--r--drivers/char/hvc_iucv.c259
-rw-r--r--drivers/char/hvcs.c9
-rw-r--r--drivers/char/hvsi.c1
-rw-r--r--drivers/char/hw_random/Kconfig14
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/omap-rng.c2
-rw-r--r--drivers/char/hw_random/timeriomem-rng.c151
-rw-r--r--drivers/char/pcmcia/synclink_cs.c18
-rw-r--r--drivers/char/ps3flash.c18
-rw-r--r--drivers/char/random.c6
-rw-r--r--drivers/char/scc.h2
-rw-r--r--drivers/char/selection.c2
-rw-r--r--drivers/char/sonypi.c7
-rw-r--r--drivers/char/sx.c13
-rw-r--r--drivers/char/synclink.c18
-rw-r--r--drivers/char/synclink_gt.c18
-rw-r--r--drivers/char/synclinkmp.c18
-rw-r--r--drivers/char/tpm/tpm.c530
-rw-r--r--drivers/char/tpm/tpm.h142
-rw-r--r--drivers/char/tpm/tpm_atmel.c28
-rw-r--r--drivers/char/tpm/tpm_infineon.c4
-rw-r--r--drivers/char/tpm/tpm_tis.c28
-rw-r--r--drivers/char/tty_io.c9
-rw-r--r--drivers/char/vc_screen.c16
-rw-r--r--drivers/char/vt.c5
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/sh_cmt.c615
-rw-r--r--drivers/connector/cn_queue.c80
-rw-r--r--drivers/connector/connector.c19
-rw-r--r--drivers/cpufreq/cpufreq.c106
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c404
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c121
-rw-r--r--drivers/cpufreq/cpufreq_stats.c74
-rw-r--r--drivers/cpufreq/cpufreq_userspace.c27
-rw-r--r--drivers/cpufreq/freq_table.c18
-rw-r--r--drivers/crypto/Kconfig15
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/amcc/Makefile2
-rw-r--r--drivers/crypto/amcc/crypto4xx_alg.c293
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.c1310
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.h177
-rw-r--r--drivers/crypto/amcc/crypto4xx_reg_def.h284
-rw-r--r--drivers/crypto/amcc/crypto4xx_sa.c108
-rw-r--r--drivers/crypto/amcc/crypto4xx_sa.h243
-rw-r--r--drivers/crypto/ixp4xx_crypto.c6
-rw-r--r--drivers/crypto/padlock-aes.c2
-rw-r--r--drivers/crypto/padlock-sha.c4
-rw-r--r--drivers/dca/dca-core.c53
-rw-r--r--drivers/dca/dca-sysfs.c21
-rw-r--r--drivers/dio/dio.c4
-rw-r--r--drivers/dma/Kconfig19
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/dmaengine.c10
-rw-r--r--drivers/dma/dmatest.c41
-rw-r--r--drivers/dma/dw_dmac.c7
-rw-r--r--drivers/dma/dw_dmac_regs.h2
-rw-r--r--drivers/dma/fsldma.c16
-rw-r--r--drivers/dma/ioat.c2
-rw-r--r--drivers/dma/ioat_dca.c26
-rw-r--r--drivers/dma/ioat_dma.c39
-rw-r--r--drivers/dma/ioatdma.h8
-rw-r--r--drivers/dma/ioatdma_hw.h2
-rw-r--r--drivers/dma/ioatdma_registers.h2
-rw-r--r--drivers/dma/iop-adma.c18
-rw-r--r--drivers/dma/ipu/Makefile1
-rw-r--r--drivers/dma/ipu/ipu_idmac.c1740
-rw-r--r--drivers/dma/ipu/ipu_intern.h176
-rw-r--r--drivers/dma/ipu/ipu_irq.c413
-rw-r--r--drivers/dma/mv_xor.c18
-rw-r--r--drivers/edac/cell_edac.c10
-rw-r--r--drivers/edac/mpc85xx_edac.c2
-rw-r--r--drivers/edac/mv64x60_edac.c8
-rw-r--r--drivers/eisa/eisa-bus.c4
-rw-r--r--drivers/firewire/fw-card.c13
-rw-r--r--drivers/firewire/fw-device.c123
-rw-r--r--drivers/firewire/fw-device.h1
-rw-r--r--drivers/firewire/fw-ohci.c6
-rw-r--r--drivers/firewire/fw-sbp2.c89
-rw-r--r--drivers/firewire/fw-topology.c12
-rw-r--r--drivers/firewire/fw-transaction.h9
-rw-r--r--drivers/firmware/dell_rbu.c4
-rw-r--r--drivers/firmware/dmi_scan.c74
-rw-r--r--drivers/firmware/memmap.c2
-rw-r--r--drivers/gpio/bt8xxgpio.c2
-rw-r--r--drivers/gpio/gpiolib.c1
-rw-r--r--drivers/gpu/drm/Kconfig15
-rw-r--r--drivers/gpu/drm/drm_agpsupport.c3
-rw-r--r--drivers/gpu/drm/drm_bufs.c2
-rw-r--r--drivers/gpu/drm/drm_crtc.c17
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c270
-rw-r--r--drivers/gpu/drm/drm_drv.c4
-rw-r--r--drivers/gpu/drm/drm_edid.c8
-rw-r--r--drivers/gpu/drm/drm_fops.c23
-rw-r--r--drivers/gpu/drm/drm_gem.c81
-rw-r--r--drivers/gpu/drm/drm_irq.c188
-rw-r--r--drivers/gpu/drm/drm_lock.c3
-rw-r--r--drivers/gpu/drm/drm_memory.c7
-rw-r--r--drivers/gpu/drm/drm_stub.c18
-rw-r--r--drivers/gpu/drm/drm_sysfs.c4
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c77
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c30
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h41
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c548
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c97
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c24
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h11
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c11
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c14
-rw-r--r--drivers/gpu/drm/i915/intel_display.c216
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c8
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c4
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c67
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c872
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo_regs.h404
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c27
-rw-r--r--drivers/hid/hid-core.c17
-rw-r--r--drivers/hid/hid-ids.h5
-rw-r--r--drivers/hid/hid-microsoft.c13
-rw-r--r--drivers/hid/hidraw.c14
-rw-r--r--drivers/hid/usbhid/hiddev.c11
-rw-r--r--drivers/hwmon/Kconfig4
-rw-r--r--drivers/hwmon/abituguru3.c7
-rw-r--r--drivers/hwmon/applesmc.c30
-rw-r--r--drivers/hwmon/f71882fg.c4
-rw-r--r--drivers/hwmon/f75375s.c2
-rw-r--r--drivers/hwmon/hp_accel.c94
-rw-r--r--drivers/hwmon/it87.c8
-rw-r--r--drivers/hwmon/lis3lv02d.c195
-rw-r--r--drivers/hwmon/lis3lv02d.h21
-rw-r--r--drivers/hwmon/lm85.c8
-rw-r--r--drivers/hwmon/lm90.c8
-rw-r--r--drivers/hwmon/vt1211.c2
-rw-r--r--drivers/hwmon/w83627ehf.c2
-rw-r--r--drivers/i2c/busses/i2c-acorn.c6
-rw-r--r--drivers/i2c/busses/i2c-ali1535.c1
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c1
-rw-r--r--drivers/i2c/busses/i2c-ali15x3.c1
-rw-r--r--drivers/i2c/busses/i2c-amd756.c1
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c5
-rw-r--r--drivers/i2c/busses/i2c-au1550.c1
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c1
-rw-r--r--drivers/i2c/busses/i2c-elektor.c1
-rw-r--r--drivers/i2c/busses/i2c-hydra.c1
-rw-r--r--drivers/i2c/busses/i2c-i801.c1
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c1
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c1
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c3
-rw-r--r--drivers/i2c/busses/i2c-mpc.c1
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c5
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c1
-rw-r--r--drivers/i2c/busses/i2c-parport-light.c1
-rw-r--r--drivers/i2c/busses/i2c-parport.c1
-rw-r--r--drivers/i2c/busses/i2c-pca-isa.c1
-rw-r--r--drivers/i2c/busses/i2c-piix4.c1
-rw-r--r--drivers/i2c/busses/i2c-pxa.c2
-rw-r--r--drivers/i2c/busses/i2c-sibyte.c2
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c1
-rw-r--r--drivers/i2c/busses/i2c-sis630.c1
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c1
-rw-r--r--drivers/i2c/busses/i2c-via.c1
-rw-r--r--drivers/i2c/busses/i2c-viapro.c1
-rw-r--r--drivers/i2c/busses/i2c-voodoo3.c2
-rw-r--r--drivers/i2c/busses/scx200_acb.c1
-rw-r--r--drivers/i2c/busses/scx200_i2c.c3
-rw-r--r--drivers/i2c/chips/Kconfig37
-rw-r--r--drivers/i2c/chips/Makefile2
-rw-r--r--drivers/i2c/i2c-core.c5
-rw-r--r--drivers/i2c/i2c-dev.c6
-rw-r--r--drivers/ide/Kconfig25
-rw-r--r--drivers/ide/Makefile6
-rw-r--r--drivers/ide/aec62xx.c4
-rw-r--r--drivers/ide/alim15x3.c2
-rw-r--r--drivers/ide/amd74xx.c16
-rw-r--r--drivers/ide/at91_ide.c467
-rw-r--r--drivers/ide/atiixp.c7
-rw-r--r--drivers/ide/au1xxx-ide.c36
-rw-r--r--drivers/ide/cmd64x.c2
-rw-r--r--drivers/ide/cs5520.c3
-rw-r--r--drivers/ide/cs5530.c2
-rw-r--r--drivers/ide/cs5536.c308
-rw-r--r--drivers/ide/delkin_cb.c2
-rw-r--r--drivers/ide/falconide.c2
-rw-r--r--drivers/ide/hpt366.c4
-rw-r--r--drivers/ide/icside.c2
-rw-r--r--drivers/ide/ide-acpi.c214
-rw-r--r--drivers/ide/ide-atapi.c53
-rw-r--r--drivers/ide/ide-cd.c42
-rw-r--r--drivers/ide/ide-cd.h2
-rw-r--r--drivers/ide/ide-devsets.c190
-rw-r--r--drivers/ide/ide-disk_proc.c2
-rw-r--r--drivers/ide/ide-dma.c69
-rw-r--r--drivers/ide/ide-eh.c428
-rw-r--r--drivers/ide/ide-floppy.c6
-rw-r--r--drivers/ide/ide-floppy_proc.c2
-rw-r--r--drivers/ide/ide-gd.c26
-rw-r--r--drivers/ide/ide-gd.h2
-rw-r--r--drivers/ide/ide-io-std.c316
-rw-r--r--drivers/ide/ide-io.c332
-rw-r--r--drivers/ide/ide-iops.c740
-rw-r--r--drivers/ide/ide-lib.c240
-rw-r--r--drivers/ide/ide-park.c25
-rw-r--r--drivers/ide/ide-pci-generic.c4
-rw-r--r--drivers/ide/ide-probe.c308
-rw-r--r--drivers/ide/ide-proc.c4
-rw-r--r--drivers/ide/ide-tape.c31
-rw-r--r--drivers/ide/ide-xfer-mode.c246
-rw-r--r--drivers/ide/ide.c167
-rw-r--r--drivers/ide/it821x.c7
-rw-r--r--drivers/ide/ns87415.c4
-rw-r--r--drivers/ide/palm_bk3710.c11
-rw-r--r--drivers/ide/pdc202xx_new.c4
-rw-r--r--drivers/ide/pdc202xx_old.c4
-rw-r--r--drivers/ide/piix.c13
-rw-r--r--drivers/ide/qd65xx.c2
-rw-r--r--drivers/ide/qd65xx.h2
-rw-r--r--drivers/ide/serverworks.c13
-rw-r--r--drivers/ide/setup-pci.c27
-rw-r--r--drivers/ide/siimage.c2
-rw-r--r--drivers/ide/sis5513.c4
-rw-r--r--drivers/ide/sl82c105.c4
-rw-r--r--drivers/ide/slc90e66.c1
-rw-r--r--drivers/ide/trm290.c3
-rw-r--r--drivers/ide/tx4939ide.c4
-rw-r--r--drivers/ide/via82cxxx.c7
-rw-r--r--drivers/ieee1394/dma.h1
-rw-r--r--drivers/ieee1394/dv1394.c14
-rw-r--r--drivers/ieee1394/ieee1394.h4
-rw-r--r--drivers/ieee1394/ieee1394_core.c19
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c31
-rw-r--r--drivers/ieee1394/ieee1394_transactions.h2
-rw-r--r--drivers/ieee1394/iso.h1
-rw-r--r--drivers/ieee1394/nodemgr.c10
-rw-r--r--drivers/ieee1394/nodemgr.h18
-rw-r--r--drivers/ieee1394/ohci1394.h2
-rw-r--r--drivers/ieee1394/pcilynx.c1
-rw-r--r--drivers/ieee1394/sbp2.c54
-rw-r--r--drivers/infiniband/core/cm.c15
-rw-r--r--drivers/infiniband/core/cm_msgs.h22
-rw-r--r--drivers/infiniband/core/device.c4
-rw-r--r--drivers/infiniband/core/mad.c40
-rw-r--r--drivers/infiniband/core/mad_rmpp.c2
-rw-r--r--drivers/infiniband/core/sa_query.c2
-rw-r--r--drivers/infiniband/core/sysfs.c19
-rw-r--r--drivers/infiniband/hw/amso1100/c2.c41
-rw-r--r--drivers/infiniband/hw/amso1100/c2.h2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c22
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c33
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.h5
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_wr.h6
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.c15
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_ev.c5
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c17
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c16
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.c18
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c6
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mcast.c4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c144
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c32
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_sqp.c10
-rw-r--r--drivers/infiniband/hw/ehca/ehca_tools.h2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_uverbs.c2
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.c56
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_eeprom.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mad.c95
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_sdma.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_uc.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_pages.c8
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_sdma.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h10
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c27
-rw-r--r--drivers/infiniband/hw/mlx4/main.c5
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c50
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c25
-rw-r--r--drivers/infiniband/hw/nes/nes.c2
-rw-r--r--drivers/infiniband/hw/nes/nes.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c625
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h12
-rw-r--r--drivers/infiniband/hw/nes/nes_context.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c19
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h5
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c171
-rw-r--r--drivers/infiniband/hw/nes/nes_user.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_utils.c2
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c251
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.h3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c54
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c11
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c7
-rw-r--r--drivers/input/evdev.c5
-rw-r--r--drivers/input/joydev.c5
-rw-r--r--drivers/input/joystick/maplecontrol.c4
-rw-r--r--drivers/input/keyboard/atkbd.c4
-rw-r--r--drivers/input/keyboard/bf54x-keys.c4
-rw-r--r--drivers/input/keyboard/corgikbd.c8
-rw-r--r--drivers/input/keyboard/maple_keyb.c37
-rw-r--r--drivers/input/keyboard/omap-keypad.c8
-rw-r--r--drivers/input/keyboard/sh_keysc.c26
-rw-r--r--drivers/input/keyboard/spitzkbd.c8
-rw-r--r--drivers/input/mouse/Kconfig2
-rw-r--r--drivers/input/mouse/elantech.c32
-rw-r--r--drivers/input/mouse/pxa930_trkball.c2
-rw-r--r--drivers/input/mouse/synaptics.c9
-rw-r--r--drivers/input/mousedev.c5
-rw-r--r--drivers/input/serio/ambakmi.c6
-rw-r--r--drivers/input/serio/gscps2.c2
-rw-r--r--drivers/input/serio/sa1111ps2.c4
-rw-r--r--drivers/input/serio/serio_raw.c4
-rw-r--r--drivers/input/touchscreen/atmel_tsadcc.c2
-rw-r--r--drivers/input/touchscreen/corgi_ts.c9
-rw-r--r--drivers/input/touchscreen/tsc2007.c3
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c20
-rw-r--r--drivers/isdn/act2000/act2000_isa.c6
-rw-r--r--drivers/isdn/capi/capi.c2
-rw-r--r--drivers/isdn/capi/kcapi_proc.c2
-rw-r--r--drivers/isdn/gigaset/Kconfig14
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c16
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c3
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c8
-rw-r--r--drivers/isdn/hardware/eicon/debug.c2
-rw-r--r--drivers/isdn/hardware/eicon/message.c70
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c2
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c4
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c6
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.h6
-rw-r--r--drivers/isdn/hisax/callc.c1
-rw-r--r--drivers/isdn/hisax/config.c6
-rw-r--r--drivers/isdn/hisax/hfcscard.c2
-rw-r--r--drivers/isdn/hisax/hisax.h9
-rw-r--r--drivers/isdn/hisax/isdnl1.c4
-rw-r--r--drivers/isdn/hisax/sedlbauer.c2
-rw-r--r--drivers/isdn/hisax/teles0.c2
-rw-r--r--drivers/isdn/hisax/teles3.c1
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c2
-rw-r--r--drivers/isdn/mISDN/clock.c10
-rw-r--r--drivers/isdn/mISDN/timerdev.c3
-rw-r--r--drivers/isdn/pcbit/layer2.c6
-rw-r--r--drivers/isdn/sc/shmem.c2
-rw-r--r--drivers/leds/Kconfig3
-rw-r--r--drivers/lguest/core.c2
-rw-r--r--drivers/lguest/lguest_device.c6
-rw-r--r--drivers/lguest/lguest_user.c5
-rw-r--r--drivers/mca/mca-bus.c4
-rw-r--r--drivers/md/dm-crypt.c43
-rw-r--r--drivers/md/dm-io.c4
-rw-r--r--drivers/md/dm-ioctl.c7
-rw-r--r--drivers/md/dm-kcopyd.c2
-rw-r--r--drivers/md/dm.c32
-rw-r--r--drivers/md/linear.c6
-rw-r--r--drivers/md/md.c58
-rw-r--r--drivers/md/raid1.c6
-rw-r--r--drivers/md/raid10.c19
-rw-r--r--drivers/media/common/saa7146_video.c1
-rw-r--r--drivers/media/common/tuners/mxl5007t.c2
-rw-r--r--drivers/media/common/tuners/tuner-simple.c10
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c65
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c3
-rw-r--r--drivers/media/dvb/bt8xx/dst.c2
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c16
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c24
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.h6
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c16
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c7
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-fe.c2
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c30
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c18
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h2
-rw-r--r--drivers/media/dvb/firewire/Kconfig22
-rw-r--r--drivers/media/dvb/firewire/Makefile8
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c285
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c1315
-rw-r--r--drivers/media/dvb/firewire/firedtv-ci.c260
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c364
-rw-r--r--drivers/media/dvb/firewire/firedtv-fe.c247
-rw-r--r--drivers/media/dvb/firewire/firedtv-rc.c190
-rw-r--r--drivers/media/dvb/firewire/firedtv.h182
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c2
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c7
-rw-r--r--drivers/media/dvb/frontends/stb0899_algo.c17
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c2
-rw-r--r--drivers/media/dvb/frontends/stb0899_priv.h12
-rw-r--r--drivers/media/dvb/frontends/stb6100.c4
-rw-r--r--drivers/media/dvb/frontends/zl10353.c2
-rw-r--r--drivers/media/dvb/frontends/zl10353.h3
-rw-r--r--drivers/media/dvb/ttpci/budget.c1
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c2
-rw-r--r--drivers/media/radio/radio-mr800.c12
-rw-r--r--drivers/media/radio/radio-si470x.c55
-rw-r--r--drivers/media/radio/radio-tea5764.c3
-rw-r--r--drivers/media/video/cs5345.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c3
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c5
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c8
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c7
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c72
-rw-r--r--drivers/media/video/cx88/cx88.h2
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c23
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c32
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c20
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c20
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c45
-rw-r--r--drivers/media/video/em28xx/em28xx.h21
-rw-r--r--drivers/media/video/gspca/gspca.c9
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c26
-rw-r--r--drivers/media/video/pwc/pwc-if.c1
-rw-r--r--drivers/media/video/pxa_camera.c26
-rw-r--r--drivers/media/video/saa7127.c52
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c14
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c1
-rw-r--r--drivers/media/video/saa717x.c1
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c13
-rw-r--r--drivers/media/video/tda9875.c2
-rw-r--r--drivers/media/video/tvaudio.c2
-rw-r--r--drivers/media/video/tveeprom.c3
-rw-r--r--drivers/media/video/tvp514x.c2
-rw-r--r--drivers/media/video/upd64031a.c1
-rw-r--r--drivers/media/video/upd64083.c1
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c2
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c7
-rw-r--r--drivers/media/video/uvc/uvc_driver.c55
-rw-r--r--drivers/media/video/uvc/uvc_isight.c2
-rw-r--r--drivers/media/video/uvc/uvc_queue.c31
-rw-r--r--drivers/media/video/uvc/uvc_status.c13
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c10
-rw-r--r--drivers/media/video/uvc/uvc_video.c31
-rw-r--r--drivers/media/video/uvc/uvcvideo.h232
-rw-r--r--drivers/media/video/v4l2-device.c2
-rw-r--r--drivers/media/video/v4l2-subdev.c4
-rw-r--r--drivers/media/video/zoran/Kconfig1
-rw-r--r--drivers/media/video/zoran/zoran.h12
-rw-r--r--drivers/media/video/zoran/zoran_card.c620
-rw-r--r--drivers/media/video/zoran/zoran_card.h2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c105
-rw-r--r--drivers/message/fusion/lsi/mpi.h7
-rw-r--r--drivers/message/fusion/lsi/mpi_cnfg.h47
-rw-r--r--drivers/message/fusion/lsi/mpi_fc.h2
-rw-r--r--drivers/message/fusion/lsi/mpi_history.txt86
-rw-r--r--drivers/message/fusion/lsi/mpi_init.h2
-rw-r--r--drivers/message/fusion/lsi/mpi_ioc.h22
-rw-r--r--drivers/message/fusion/lsi/mpi_lan.h2
-rw-r--r--drivers/message/fusion/lsi/mpi_log_fc.h2
-rw-r--r--drivers/message/fusion/lsi/mpi_log_sas.h37
-rw-r--r--drivers/message/fusion/lsi/mpi_raid.h11
-rw-r--r--drivers/message/fusion/lsi/mpi_sas.h18
-rw-r--r--drivers/message/fusion/lsi/mpi_targ.h2
-rw-r--r--drivers/message/fusion/lsi/mpi_tool.h2
-rw-r--r--drivers/message/fusion/lsi/mpi_type.h4
-rw-r--r--drivers/message/fusion/mptbase.c87
-rw-r--r--drivers/message/fusion/mptbase.h3
-rw-r--r--drivers/message/fusion/mptscsih.c3
-rw-r--r--drivers/mfd/htc-egpio.c4
-rw-r--r--drivers/mfd/mcp-core.c2
-rw-r--r--drivers/mfd/pcf50633-core.c2
-rw-r--r--drivers/mfd/sm501.c26
-rw-r--r--drivers/mfd/twl4030-core.c2
-rw-r--r--drivers/mfd/ucb1x00-core.c2
-rw-r--r--drivers/mfd/wm8350-core.c53
-rw-r--r--drivers/mfd/wm8350-regmap.c2
-rw-r--r--drivers/misc/Kconfig10
-rw-r--r--drivers/misc/Makefile3
-rw-r--r--drivers/misc/atmel-ssc.c2
-rw-r--r--drivers/misc/eeprom/Kconfig59
-rw-r--r--drivers/misc/eeprom/Makefile4
-rw-r--r--drivers/misc/eeprom/at24.c (renamed from drivers/i2c/chips/at24.c)0
-rw-r--r--drivers/misc/eeprom/at25.c (renamed from drivers/spi/at25.c)0
-rw-r--r--drivers/misc/eeprom/eeprom.c (renamed from drivers/i2c/chips/eeprom.c)0
-rw-r--r--drivers/misc/eeprom/eeprom_93cx6.c (renamed from drivers/misc/eeprom_93cx6.c)0
-rw-r--r--drivers/misc/hpilo.c9
-rw-r--r--drivers/misc/hpilo.h2
-rw-r--r--drivers/misc/sgi-xp/xpc.h5
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c3
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c34
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c13
-rw-r--r--drivers/misc/sgi-xp/xpnet.c3
-rw-r--r--drivers/mmc/card/block.c2
-rw-r--r--drivers/mmc/card/mmc_test.c2
-rw-r--r--drivers/mmc/core/mmc_ops.c15
-rw-r--r--drivers/mmc/host/Kconfig20
-rw-r--r--drivers/mmc/host/Makefile2
-rw-r--r--drivers/mmc/host/atmel-mci.c7
-rw-r--r--drivers/mmc/host/mmci.c37
-rw-r--r--drivers/mmc/host/mmci.h28
-rw-r--r--drivers/mmc/host/mxcmmc.c880
-rw-r--r--drivers/mmc/host/of_mmc_spi.c2
-rw-r--r--drivers/mmc/host/omap_hsmmc.c1280
-rw-r--r--drivers/mmc/host/pxamci.c25
-rw-r--r--drivers/mmc/host/ricoh_mmc.c8
-rw-r--r--drivers/mmc/host/s3cmci.c7
-rw-r--r--drivers/mmc/host/sdhci-pci.c4
-rw-r--r--drivers/mmc/host/sdhci.c12
-rw-r--r--drivers/mmc/host/sdhci.h5
-rw-r--r--drivers/mtd/chips/map_rom.c8
-rw-r--r--drivers/mtd/devices/Kconfig7
-rw-r--r--drivers/mtd/devices/Makefile1
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c3
-rw-r--r--drivers/mtd/devices/ps3vram.c768
-rw-r--r--drivers/mtd/devices/slram.c14
-rw-r--r--drivers/mtd/lpddr/Kconfig1
-rw-r--r--drivers/mtd/maps/Kconfig14
-rw-r--r--drivers/mtd/maps/Makefile1
-rw-r--r--drivers/mtd/maps/bfin-async-flash.c6
-rw-r--r--drivers/mtd/maps/ck804xrom.c2
-rw-r--r--drivers/mtd/maps/physmap.c41
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c37
-rw-r--r--drivers/mtd/maps/sa1100-flash.c4
-rw-r--r--drivers/mtd/maps/vmu-flash.c832
-rw-r--r--drivers/mtd/nand/atmel_nand.c3
-rw-r--r--drivers/mtd/nand/excite_nandflash.c25
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c8
-rw-r--r--drivers/mtd/nand/ndfc.c2
-rw-r--r--drivers/mtd/nand/orion_nand.c2
-rw-r--r--drivers/mtd/nand/pasemi_nand.c4
-rw-r--r--drivers/mtd/onenand/generic.c26
-rw-r--r--drivers/mtd/onenand/omap2.c6
-rw-r--r--drivers/mtd/ubi/Kconfig.debug10
-rw-r--r--drivers/mtd/ubi/build.c21
-rw-r--r--drivers/mtd/ubi/cdev.c184
-rw-r--r--drivers/mtd/ubi/gluebi.c11
-rw-r--r--drivers/mtd/ubi/scan.c8
-rw-r--r--drivers/mtd/ubi/ubi.h11
-rw-r--r--drivers/mtd/ubi/upd.c21
-rw-r--r--drivers/mtd/ubi/vmt.c17
-rw-r--r--drivers/net/3c501.c17
-rw-r--r--drivers/net/3c505.c44
-rw-r--r--drivers/net/3c507.c15
-rw-r--r--drivers/net/3c509.c26
-rw-r--r--drivers/net/3c515.c21
-rw-r--r--drivers/net/3c523.c25
-rw-r--r--drivers/net/3c527.c19
-rw-r--r--drivers/net/3c59x.c61
-rw-r--r--drivers/net/8139cp.c30
-rw-r--r--drivers/net/8139too.c32
-rw-r--r--drivers/net/82596.c17
-rw-r--r--drivers/net/Kconfig58
-rw-r--r--drivers/net/Makefile8
-rw-r--r--drivers/net/a2065.c19
-rw-r--r--drivers/net/acenic.c2
-rw-r--r--drivers/net/amd8111e.c6
-rw-r--r--drivers/net/arcnet/arc-rawmode.c4
-rw-r--r--drivers/net/arcnet/arcnet.c72
-rw-r--r--drivers/net/arcnet/capmode.c6
-rw-r--r--drivers/net/arcnet/com20020-isa.c2
-rw-r--r--drivers/net/arcnet/com20020-pci.c3
-rw-r--r--drivers/net/arcnet/com20020.c11
-rw-r--r--drivers/net/arcnet/rfc1051.c12
-rw-r--r--drivers/net/arcnet/rfc1201.c47
-rw-r--r--drivers/net/arm/Makefile2
-rw-r--r--drivers/net/arm/am79c961a.c20
-rw-r--r--drivers/net/arm/ep93xx_eth.c8
-rw-r--r--drivers/net/arm/etherh.c12
-rw-r--r--drivers/net/arm/ixp4xx_eth.c12
-rw-r--r--drivers/net/arm/ks8695net.c4
-rw-r--r--drivers/net/at1700.c2
-rw-r--r--drivers/net/atl1c/Makefile2
-rw-r--r--drivers/net/atl1c/atl1c.h605
-rw-r--r--drivers/net/atl1c/atl1c_ethtool.c317
-rw-r--r--drivers/net/atl1c/atl1c_hw.c527
-rw-r--r--drivers/net/atl1c/atl1c_hw.h859
-rw-r--r--drivers/net/atl1c/atl1c_main.c2797
-rw-r--r--drivers/net/atl1e/atl1e.h2
-rw-r--r--drivers/net/atl1e/atl1e_main.c6
-rw-r--r--drivers/net/atl1e/atl1e_param.c2
-rw-r--r--drivers/net/atlx/atl1.c2
-rw-r--r--drivers/net/atlx/atl2.c2
-rw-r--r--drivers/net/au1000_eth.c1051
-rw-r--r--drivers/net/ax88796.c31
-rw-r--r--drivers/net/b44.c21
-rw-r--r--drivers/net/benet/Kconfig7
-rw-r--r--drivers/net/benet/Makefile7
-rw-r--r--drivers/net/benet/be.h328
-rw-r--r--drivers/net/benet/be_cmds.c861
-rw-r--r--drivers/net/benet/be_cmds.h688
-rw-r--r--drivers/net/benet/be_ethtool.c362
-rw-r--r--drivers/net/benet/be_hw.h211
-rw-r--r--drivers/net/benet/be_main.c1947
-rw-r--r--drivers/net/bfin_mac.c12
-rw-r--r--drivers/net/bmac.c3
-rw-r--r--drivers/net/bnx2.c68
-rw-r--r--drivers/net/bnx2.h2
-rw-r--r--drivers/net/bnx2_fw.h8515
-rw-r--r--drivers/net/bnx2_fw2.h8795
-rw-r--r--drivers/net/bnx2x.h199
-rw-r--r--drivers/net/bnx2x_dump.h526
-rw-r--r--drivers/net/bnx2x_fw_defs.h153
-rw-r--r--drivers/net/bnx2x_hsi.h559
-rw-r--r--drivers/net/bnx2x_init.h167
-rw-r--r--drivers/net/bnx2x_init_values.h26545
-rw-r--r--drivers/net/bnx2x_link.c1480
-rw-r--r--drivers/net/bnx2x_link.h23
-rw-r--r--drivers/net/bnx2x_main.c2881
-rw-r--r--drivers/net/bnx2x_reg.h316
-rw-r--r--drivers/net/bonding/bond_3ad.h2
-rw-r--r--drivers/net/bonding/bond_alb.c12
-rw-r--r--drivers/net/bonding/bond_main.c44
-rw-r--r--drivers/net/cassini.c12
-rw-r--r--drivers/net/chelsio/sge.c7
-rw-r--r--drivers/net/cpmac.c12
-rw-r--r--drivers/net/cxgb3/adapter.h21
-rw-r--r--drivers/net/cxgb3/ael1002.c3
-rw-r--r--drivers/net/cxgb3/common.h6
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c255
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c12
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.h7
-rw-r--r--drivers/net/cxgb3/regs.h21
-rw-r--r--drivers/net/cxgb3/sge.c317
-rw-r--r--drivers/net/cxgb3/t3_hw.c171
-rw-r--r--drivers/net/cxgb3/version.h4
-rw-r--r--drivers/net/cxgb3/xgmac.c85
-rw-r--r--drivers/net/declance.c6
-rw-r--r--drivers/net/defxx.c2
-rw-r--r--drivers/net/depca.c6
-rw-r--r--drivers/net/dm9000.c6
-rw-r--r--drivers/net/dnet.c994
-rw-r--r--drivers/net/dnet.h225
-rw-r--r--drivers/net/e100.c99
-rw-r--r--drivers/net/e1000/e1000.h2
-rw-r--r--drivers/net/e1000/e1000_main.c168
-rw-r--r--drivers/net/e1000e/82571.c279
-rw-r--r--drivers/net/e1000e/defines.h1
-rw-r--r--drivers/net/e1000e/e1000.h4
-rw-r--r--drivers/net/e1000e/ethtool.c3
-rw-r--r--drivers/net/e1000e/hw.h12
-rw-r--r--drivers/net/e1000e/ich8lan.c17
-rw-r--r--drivers/net/e1000e/lib.c66
-rw-r--r--drivers/net/e1000e/netdev.c261
-rw-r--r--drivers/net/e2100.c6
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c189
-rw-r--r--drivers/net/ehea/ehea_qmr.c4
-rw-r--r--drivers/net/enic/enic.h3
-rw-r--r--drivers/net/enic/enic_main.c84
-rw-r--r--drivers/net/enic/vnic_dev.c33
-rw-r--r--drivers/net/enic/vnic_dev.h2
-rw-r--r--drivers/net/enic/vnic_devcmd.h8
-rw-r--r--drivers/net/enic/vnic_intr.h14
-rw-r--r--drivers/net/epic100.c6
-rw-r--r--drivers/net/eql.c2
-rw-r--r--drivers/net/fealnx.c4
-rw-r--r--drivers/net/fec.c890
-rw-r--r--drivers/net/fec.h11
-rw-r--r--drivers/net/forcedeth.c763
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c4
-rw-r--r--drivers/net/fsl_pq_mdio.c (renamed from drivers/net/gianfar_mii.c)263
-rw-r--r--drivers/net/fsl_pq_mdio.h45
-rw-r--r--drivers/net/gianfar.c199
-rw-r--r--drivers/net/gianfar.h22
-rw-r--r--drivers/net/gianfar_ethtool.c1
-rw-r--r--drivers/net/gianfar_mii.h54
-rw-r--r--drivers/net/gianfar_sysfs.c33
-rw-r--r--drivers/net/hamachi.c10
-rw-r--r--drivers/net/hamradio/6pack.c20
-rw-r--r--drivers/net/hamradio/baycom_epp.c43
-rw-r--r--drivers/net/hamradio/bpqether.c47
-rw-r--r--drivers/net/hamradio/dmascc.c54
-rw-r--r--drivers/net/hamradio/hdlcdrv.c45
-rw-r--r--drivers/net/hamradio/mkiss.c55
-rw-r--r--drivers/net/hamradio/scc.c24
-rw-r--r--drivers/net/hamradio/yam.c68
-rw-r--r--drivers/net/hp-plus.c2
-rw-r--r--drivers/net/ibm_newemac/core.c5
-rw-r--r--drivers/net/ibm_newemac/phy.c4
-rw-r--r--drivers/net/ibmveth.c8
-rw-r--r--drivers/net/igb/Makefile4
-rw-r--r--drivers/net/igb/e1000_82575.c152
-rw-r--r--drivers/net/igb/e1000_82575.h64
-rw-r--r--drivers/net/igb/e1000_defines.h134
-rw-r--r--drivers/net/igb/e1000_hw.h202
-rw-r--r--drivers/net/igb/e1000_mac.c66
-rw-r--r--drivers/net/igb/e1000_mac.h9
-rw-r--r--drivers/net/igb/e1000_mbx.c447
-rw-r--r--drivers/net/igb/e1000_mbx.h77
-rw-r--r--drivers/net/igb/e1000_nvm.c44
-rw-r--r--drivers/net/igb/e1000_phy.c352
-rw-r--r--drivers/net/igb/e1000_phy.h3
-rw-r--r--drivers/net/igb/e1000_regs.h103
-rw-r--r--drivers/net/igb/igb.h93
-rw-r--r--drivers/net/igb/igb_ethtool.c206
-rw-r--r--drivers/net/igb/igb_main.c1939
-rw-r--r--drivers/net/irda/ali-ircc.c23
-rw-r--r--drivers/net/irda/irda-usb.c18
-rw-r--r--drivers/net/irda/kingsun-sir.c11
-rw-r--r--drivers/net/irda/ks959-sir.c11
-rw-r--r--drivers/net/irda/ksdazzle-sir.c12
-rw-r--r--drivers/net/irda/mcs7780.c15
-rw-r--r--drivers/net/irda/nsc-ircc.c23
-rw-r--r--drivers/net/irda/sir_dev.c17
-rw-r--r--drivers/net/irda/smsc-ircc2.c30
-rw-r--r--drivers/net/irda/stir4200.c12
-rw-r--r--drivers/net/irda/via-ircc.c22
-rw-r--r--drivers/net/irda/vlsi_ir.c14
-rw-r--r--drivers/net/irda/w83977af_ir.c13
-rw-r--r--drivers/net/ixgb/ixgb_main.c76
-rw-r--r--drivers/net/ixgbe/Makefile7
-rw-r--r--drivers/net/ixgbe/ixgbe.h66
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c336
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c1292
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c483
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h15
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb.c19
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb.h56
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.c3
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c467
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.h127
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c205
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c130
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1454
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c592
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.h18
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h828
-rw-r--r--drivers/net/ixp2000/ixpdev.c4
-rw-r--r--drivers/net/jazzsonic.c6
-rw-r--r--drivers/net/jme.c34
-rw-r--r--drivers/net/jme.h8
-rw-r--r--drivers/net/korina.c19
-rw-r--r--drivers/net/lance.c11
-rw-r--r--drivers/net/macb.c29
-rw-r--r--drivers/net/macsonic.c15
-rw-r--r--drivers/net/macvlan.c84
-rw-r--r--drivers/net/mipsnet.c26
-rw-r--r--drivers/net/mlx4/Makefile2
-rw-r--r--drivers/net/mlx4/catas.c16
-rw-r--r--drivers/net/mlx4/en_rx.c5
-rw-r--r--drivers/net/mlx4/eq.c16
-rw-r--r--drivers/net/mlx4/main.c106
-rw-r--r--drivers/net/mlx4/mlx4.h27
-rw-r--r--drivers/net/mlx4/port.c13
-rw-r--r--drivers/net/mlx4/profile.c6
-rw-r--r--drivers/net/mlx4/sense.c156
-rw-r--r--drivers/net/mv643xx_eth.c448
-rw-r--r--drivers/net/myri10ge/myri10ge.c22
-rw-r--r--drivers/net/myri10ge/myri10ge_mcp_gen_header.h9
-rw-r--r--drivers/net/myri_sbus.c20
-rw-r--r--drivers/net/natsemi.c8
-rw-r--r--drivers/net/ne2k-pci.c5
-rw-r--r--drivers/net/netxen/Makefile9
-rw-r--r--drivers/net/netxen/netxen_nic.h182
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c201
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c186
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h21
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c617
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h63
-rw-r--r--drivers/net/netxen/netxen_nic_init.c920
-rw-r--r--drivers/net/netxen/netxen_nic_main.c1266
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c230
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h10
-rw-r--r--drivers/net/ni65.c11
-rw-r--r--drivers/net/niu.c1059
-rw-r--r--drivers/net/niu.h19
-rw-r--r--drivers/net/ns83820.c5
-rw-r--r--drivers/net/pasemi_mac.c6
-rw-r--r--drivers/net/pcmcia/3c574_cs.c26
-rw-r--r--drivers/net/pcmcia/3c589_cs.c28
-rw-r--r--drivers/net/pcmcia/axnet_cs.c70
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c59
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c23
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c36
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c79
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c66
-rw-r--r--drivers/net/pcnet32.c6
-rw-r--r--drivers/net/phy/mdio-gpio.c15
-rw-r--r--drivers/net/phy/mdio_bus.c58
-rw-r--r--drivers/net/phy/phy.c41
-rw-r--r--drivers/net/phy/smsc.c43
-rw-r--r--drivers/net/ppp_async.c9
-rw-r--r--drivers/net/ppp_generic.c494
-rw-r--r--drivers/net/ppp_synctty.c6
-rw-r--r--drivers/net/pppoe.c521
-rw-r--r--drivers/net/pppol2tp.c192
-rw-r--r--drivers/net/pppox.c3
-rw-r--r--drivers/net/ps3_gelic_net.c26
-rw-r--r--drivers/net/ps3_gelic_wireless.c30
-rw-r--r--drivers/net/qla3xxx.c6
-rw-r--r--drivers/net/qlge/qlge.h172
-rw-r--r--drivers/net/qlge/qlge_dbg.c9
-rw-r--r--drivers/net/qlge/qlge_ethtool.c3
-rw-r--r--drivers/net/qlge/qlge_main.c733
-rw-r--r--drivers/net/qlge/qlge_mpi.c835
-rw-r--r--drivers/net/r6040.c15
-rw-r--r--drivers/net/r8169.c107
-rw-r--r--drivers/net/rionet.c3
-rw-r--r--drivers/net/s2io.c15
-rw-r--r--drivers/net/sb1250-mac.c16
-rw-r--r--drivers/net/sc92031.c27
-rw-r--r--drivers/net/sfc/Kconfig1
-rw-r--r--drivers/net/sfc/bitfield.h4
-rw-r--r--drivers/net/sfc/boards.c74
-rw-r--r--drivers/net/sfc/boards.h1
-rw-r--r--drivers/net/sfc/efx.c131
-rw-r--r--drivers/net/sfc/efx.h13
-rw-r--r--drivers/net/sfc/ethtool.c31
-rw-r--r--drivers/net/sfc/falcon.c128
-rw-r--r--drivers/net/sfc/falcon.h2
-rw-r--r--drivers/net/sfc/falcon_io.h13
-rw-r--r--drivers/net/sfc/mdio_10g.c219
-rw-r--r--drivers/net/sfc/mdio_10g.h11
-rw-r--r--drivers/net/sfc/mtd.c1
-rw-r--r--drivers/net/sfc/net_driver.h38
-rw-r--r--drivers/net/sfc/phy.h9
-rw-r--r--drivers/net/sfc/rx.c209
-rw-r--r--drivers/net/sfc/rx.h3
-rw-r--r--drivers/net/sfc/selftest.c7
-rw-r--r--drivers/net/sfc/sfe4001.c57
-rw-r--r--drivers/net/sfc/tenxpress.c354
-rw-r--r--drivers/net/sfc/tx.c13
-rw-r--r--drivers/net/sfc/workarounds.h14
-rw-r--r--drivers/net/sfc/xfp_phy.c105
-rw-r--r--drivers/net/sh_eth.c20
-rw-r--r--drivers/net/sh_eth.h4
-rw-r--r--drivers/net/sis900.c4
-rw-r--r--drivers/net/skfp/h/smc.h17
-rw-r--r--drivers/net/skfp/hwmtm.c9
-rw-r--r--drivers/net/skfp/pcmplc.c3
-rw-r--r--drivers/net/skfp/skfddi.c7
-rw-r--r--drivers/net/skfp/smt.c10
-rw-r--r--drivers/net/skge.c6
-rw-r--r--drivers/net/sky2.c273
-rw-r--r--drivers/net/smc911x.c6
-rw-r--r--drivers/net/smc911x.h12
-rw-r--r--drivers/net/smc91x.c140
-rw-r--r--drivers/net/smc91x.h10
-rw-r--r--drivers/net/smsc911x.c221
-rw-r--r--drivers/net/smsc911x.h7
-rw-r--r--drivers/net/smsc9420.c31
-rw-r--r--drivers/net/smsc9420.h1
-rw-r--r--drivers/net/spider_net.c44
-rw-r--r--drivers/net/starfire.c8
-rw-r--r--drivers/net/sun3lance.c2
-rw-r--r--drivers/net/sunbmac.c22
-rw-r--r--drivers/net/sundance.c7
-rw-r--r--drivers/net/sungem.c29
-rw-r--r--drivers/net/sungem_phy.c2
-rw-r--r--drivers/net/sunhme.c44
-rw-r--r--drivers/net/sunlance.c21
-rw-r--r--drivers/net/sunqe.c19
-rw-r--r--drivers/net/sunvnet.c18
-rw-r--r--drivers/net/tc35815.c10
-rw-r--r--drivers/net/tehuti.c45
-rw-r--r--drivers/net/tehuti.h1
-rw-r--r--drivers/net/tehuti_fw.h10712
-rw-r--r--drivers/net/tg3.c868
-rw-r--r--drivers/net/tg3.h19
-rw-r--r--drivers/net/tokenring/3c359.c17
-rw-r--r--drivers/net/tokenring/abyss.c10
-rw-r--r--drivers/net/tokenring/ibmtr.c43
-rw-r--r--drivers/net/tokenring/lanstreamer.c45
-rw-r--r--drivers/net/tokenring/lanstreamer.h1
-rw-r--r--drivers/net/tokenring/madgemc.c2
-rw-r--r--drivers/net/tokenring/olympic.c39
-rw-r--r--drivers/net/tokenring/olympic.h1
-rw-r--r--drivers/net/tokenring/smctr.c13
-rw-r--r--drivers/net/tokenring/smctr.h1
-rw-r--r--drivers/net/tokenring/tms380tr.c21
-rw-r--r--drivers/net/tokenring/tms380tr.h1
-rw-r--r--drivers/net/tokenring/tmspci.c22
-rw-r--r--drivers/net/tsi108_eth.c10
-rw-r--r--drivers/net/tulip/21142.c23
-rw-r--r--drivers/net/tulip/de2104x.c5
-rw-r--r--drivers/net/tulip/de4x5.c7
-rw-r--r--drivers/net/tulip/dmfe.c2
-rw-r--r--drivers/net/tulip/interrupt.c94
-rw-r--r--drivers/net/tulip/media.c8
-rw-r--r--drivers/net/tulip/tulip.h32
-rw-r--r--drivers/net/tulip/tulip_core.c45
-rw-r--r--drivers/net/tulip/uli526x.c2
-rw-r--r--drivers/net/tulip/winbond-840.c7
-rw-r--r--drivers/net/tun.c538
-rw-r--r--drivers/net/typhoon-firmware.h3778
-rw-r--r--drivers/net/typhoon.c104
-rw-r--r--drivers/net/typhoon.h234
-rw-r--r--drivers/net/ucc_geth.c61
-rw-r--r--drivers/net/ucc_geth.h19
-rw-r--r--drivers/net/ucc_geth_ethtool.c1
-rw-r--r--drivers/net/ucc_geth_mii.c285
-rw-r--r--drivers/net/ucc_geth_mii.h100
-rw-r--r--drivers/net/usb/asix.c55
-rw-r--r--drivers/net/usb/catc.c52
-rw-r--r--drivers/net/usb/cdc_ether.c5
-rw-r--r--drivers/net/usb/dm9601.c20
-rw-r--r--drivers/net/usb/hso.c47
-rw-r--r--drivers/net/usb/mcs7830.c36
-rw-r--r--drivers/net/usb/rndis_host.c38
-rw-r--r--drivers/net/usb/rtl8150.c48
-rw-r--r--drivers/net/usb/smsc95xx.c25
-rw-r--r--drivers/net/usb/usbnet.c44
-rw-r--r--drivers/net/usb/zaurus.c5
-rw-r--r--drivers/net/veth.c105
-rw-r--r--drivers/net/via-rhine.c9
-rw-r--r--drivers/net/via-velocity.c17
-rw-r--r--drivers/net/via-velocity.h6
-rw-r--r--drivers/net/virtio_net.c254
-rw-r--r--drivers/net/wan/c101.c12
-rw-r--r--drivers/net/wan/cosa.c21
-rw-r--r--drivers/net/wan/cycx_x25.c41
-rw-r--r--drivers/net/wan/dlci.c54
-rw-r--r--drivers/net/wan/dscc4.c18
-rw-r--r--drivers/net/wan/farsync.c18
-rw-r--r--drivers/net/wan/hd64572.c4
-rw-r--r--drivers/net/wan/hdlc.c33
-rw-r--r--drivers/net/wan/hdlc_cisco.c17
-rw-r--r--drivers/net/wan/hdlc_fr.c44
-rw-r--r--drivers/net/wan/hdlc_ppp.c6
-rw-r--r--drivers/net/wan/hdlc_raw.c5
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c8
-rw-r--r--drivers/net/wan/hdlc_x25.c2
-rw-r--r--drivers/net/wan/hostess_sv11.c12
-rw-r--r--drivers/net/wan/ixp4xx_hss.c24
-rw-r--r--drivers/net/wan/lapbether.c39
-rw-r--r--drivers/net/wan/lmc/lmc_main.c19
-rw-r--r--drivers/net/wan/lmc/lmc_proto.c17
-rw-r--r--drivers/net/wan/n2.c12
-rw-r--r--drivers/net/wan/pc300too.c12
-rw-r--r--drivers/net/wan/pci200syn.c12
-rw-r--r--drivers/net/wan/sbni.c105
-rw-r--r--drivers/net/wan/sealevel.c12
-rw-r--r--drivers/net/wan/wanxl.c14
-rw-r--r--drivers/net/wan/x25_asy.c44
-rw-r--r--drivers/net/wan/x25_asy.h4
-rw-r--r--drivers/net/wan/z85230.c3
-rw-r--r--drivers/net/wimax/i2400m/Makefile1
-rw-r--r--drivers/net/wimax/i2400m/control.c149
-rw-r--r--drivers/net/wimax/i2400m/debug-levels.h1
-rw-r--r--drivers/net/wimax/i2400m/debugfs.c14
-rw-r--r--drivers/net/wimax/i2400m/driver.c44
-rw-r--r--drivers/net/wimax/i2400m/fw.c65
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h91
-rw-r--r--drivers/net/wimax/i2400m/netdev.c120
-rw-r--r--drivers/net/wimax/i2400m/rx.c749
-rw-r--r--drivers/net/wimax/i2400m/sdio.c27
-rw-r--r--drivers/net/wimax/i2400m/sysfs.c80
-rw-r--r--drivers/net/wimax/i2400m/usb-notif.c2
-rw-r--r--drivers/net/wimax/i2400m/usb-rx.c9
-rw-r--r--drivers/net/wimax/i2400m/usb.c30
-rw-r--r--drivers/net/wireless/Kconfig145
-rw-r--r--drivers/net/wireless/Makefile4
-rw-r--r--drivers/net/wireless/airo.c1210
-rw-r--r--drivers/net/wireless/airo_cs.c73
-rw-r--r--drivers/net/wireless/at76c50x-usb.c2501
-rw-r--r--drivers/net/wireless/at76c50x-usb.h463
-rw-r--r--drivers/net/wireless/ath5k/Makefile1
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h80
-rw-r--r--drivers/net/wireless/ath5k/attach.c31
-rw-r--r--drivers/net/wireless/ath5k/base.c417
-rw-r--r--drivers/net/wireless/ath5k/base.h4
-rw-r--r--drivers/net/wireless/ath5k/caps.c6
-rw-r--r--drivers/net/wireless/ath5k/debug.c53
-rw-r--r--drivers/net/wireless/ath5k/debug.h1
-rw-r--r--drivers/net/wireless/ath5k/eeprom.c177
-rw-r--r--drivers/net/wireless/ath5k/eeprom.h1
-rw-r--r--drivers/net/wireless/ath5k/gpio.c10
-rw-r--r--drivers/net/wireless/ath5k/initvals.c1575
-rw-r--r--drivers/net/wireless/ath5k/led.c174
-rw-r--r--drivers/net/wireless/ath5k/pcu.c23
-rw-r--r--drivers/net/wireless/ath5k/phy.c2029
-rw-r--r--drivers/net/wireless/ath5k/qcu.c47
-rw-r--r--drivers/net/wireless/ath5k/reg.h124
-rw-r--r--drivers/net/wireless/ath5k/reset.c950
-rw-r--r--drivers/net/wireless/ath5k/rfbuffer.h1181
-rw-r--r--drivers/net/wireless/ath5k/rfgain.h516
-rw-r--r--drivers/net/wireless/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath9k/ahb.c192
-rw-r--r--drivers/net/wireless/ath9k/ani.c288
-rw-r--r--drivers/net/wireless/ath9k/ani.h138
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h1733
-rw-r--r--drivers/net/wireless/ath9k/beacon.c768
-rw-r--r--drivers/net/wireless/ath9k/calib.c553
-rw-r--r--drivers/net/wireless/ath9k/calib.h124
-rw-r--r--drivers/net/wireless/ath9k/core.h754
-rw-r--r--drivers/net/wireless/ath9k/debug.c415
-rw-r--r--drivers/net/wireless/ath9k/debug.h165
-rw-r--r--drivers/net/wireless/ath9k/eeprom.c3173
-rw-r--r--drivers/net/wireless/ath9k/eeprom.h506
-rw-r--r--drivers/net/wireless/ath9k/hw.c1723
-rw-r--r--drivers/net/wireless/ath9k/hw.h1557
-rw-r--r--drivers/net/wireless/ath9k/initvals.h716
-rw-r--r--drivers/net/wireless/ath9k/mac.c233
-rw-r--r--drivers/net/wireless/ath9k/mac.h680
-rw-r--r--drivers/net/wireless/ath9k/main.c1948
-rw-r--r--drivers/net/wireless/ath9k/pci.c313
-rw-r--r--drivers/net/wireless/ath9k/phy.c240
-rw-r--r--drivers/net/wireless/ath9k/phy.h49
-rw-r--r--drivers/net/wireless/ath9k/rc.c347
-rw-r--r--drivers/net/wireless/ath9k/rc.h28
-rw-r--r--drivers/net/wireless/ath9k/recv.c170
-rw-r--r--drivers/net/wireless/ath9k/reg.h123
-rw-r--r--drivers/net/wireless/ath9k/regd.c1246
-rw-r--r--drivers/net/wireless/ath9k/regd.h207
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h2058
-rw-r--r--drivers/net/wireless/ath9k/virtual.c662
-rw-r--r--drivers/net/wireless/ath9k/xmit.c2871
-rw-r--r--drivers/net/wireless/atmel.c483
-rw-r--r--drivers/net/wireless/b43/Kconfig14
-rw-r--r--drivers/net/wireless/b43/Makefile1
-rw-r--r--drivers/net/wireless/b43/b43.h43
-rw-r--r--drivers/net/wireless/b43/debugfs.c48
-rw-r--r--drivers/net/wireless/b43/debugfs.h5
-rw-r--r--drivers/net/wireless/b43/dma.c65
-rw-r--r--drivers/net/wireless/b43/dma.h17
-rw-r--r--drivers/net/wireless/b43/lo.c77
-rw-r--r--drivers/net/wireless/b43/main.c458
-rw-r--r--drivers/net/wireless/b43/main.h25
-rw-r--r--drivers/net/wireless/b43/phy_a.c111
-rw-r--r--drivers/net/wireless/b43/phy_g.c614
-rw-r--r--drivers/net/wireless/b43/phy_lp.c395
-rw-r--r--drivers/net/wireless/b43/phy_lp.h329
-rw-r--r--drivers/net/wireless/b43/pio.c16
-rw-r--r--drivers/net/wireless/b43/rfkill.c2
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.c394
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.h31
-rw-r--r--drivers/net/wireless/b43/wa.c113
-rw-r--r--drivers/net/wireless/b43/xmit.c17
-rw-r--r--drivers/net/wireless/b43legacy/leds.c8
-rw-r--r--drivers/net/wireless/b43legacy/main.c2
-rw-r--r--drivers/net/wireless/hostap/hostap.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c111
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c51
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c146
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h6
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c37
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c7
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c117
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h1
-rw-r--r--drivers/net/wireless/ipw2x00/Kconfig3
-rw-r--r--drivers/net/wireless/ipw2x00/ieee80211.h1087
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c74
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.h8
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c198
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.h7
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_geo.c2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c49
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c122
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_tx.c12
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_wx.c27
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig99
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c73
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-commands.h1702
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debug.h167
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-fh.h188
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h227
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-io.h404
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c77
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c311
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h206
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c1174
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h761
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c215
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c239
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h (renamed from drivers/net/wireless/iwlwifi/iwl-3945-core.h)59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c158
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c108
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c304
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h57
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1361
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c93
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h511
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c785
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h100
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h183
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h133
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c102
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c184
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c108
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c293
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c5572
-rw-r--r--drivers/net/wireless/libertas/Makefile2
-rw-r--r--drivers/net/wireless/libertas/debugfs.c14
-rw-r--r--drivers/net/wireless/libertas/defs.h3
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/ethtool.c12
-rw-r--r--drivers/net/wireless/libertas/host.h1
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h99
-rw-r--r--drivers/net/wireless/libertas/if_cs.c4
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c20
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1218
-rw-r--r--drivers/net/wireless/libertas/if_spi.h208
-rw-r--r--drivers/net/wireless/libertas/if_usb.c4
-rw-r--r--drivers/net/wireless/libertas/main.c103
-rw-r--r--drivers/net/wireless/libertas/persistcfg.c16
-rw-r--r--drivers/net/wireless/libertas/rx.c18
-rw-r--r--drivers/net/wireless/libertas/scan.c6
-rw-r--r--drivers/net/wireless/libertas/tx.c10
-rw-r--r--drivers/net/wireless/libertas/wext.c74
-rw-r--r--drivers/net/wireless/libertas_tf/cmd.c2
-rw-r--r--drivers/net/wireless/libertas_tf/libertas_tf.h2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c358
-rw-r--r--drivers/net/wireless/mwl8k.c3789
-rw-r--r--drivers/net/wireless/netwave_cs.c91
-rw-r--r--drivers/net/wireless/orinoco/Kconfig120
-rw-r--r--drivers/net/wireless/orinoco/Makefile3
-rw-r--r--drivers/net/wireless/orinoco/airport.c37
-rw-r--r--drivers/net/wireless/orinoco/fw.c390
-rw-r--r--drivers/net/wireless/orinoco/fw.h21
-rw-r--r--drivers/net/wireless/orinoco/hermes.c116
-rw-r--r--drivers/net/wireless/orinoco/hermes.h35
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.c132
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.h12
-rw-r--r--drivers/net/wireless/orinoco/hw.c586
-rw-r--r--drivers/net/wireless/orinoco/hw.h47
-rw-r--r--drivers/net/wireless/orinoco/main.c2667
-rw-r--r--drivers/net/wireless/orinoco/main.h63
-rw-r--r--drivers/net/wireless/orinoco/mic.c79
-rw-r--r--drivers/net/wireless/orinoco/mic.h22
-rw-r--r--drivers/net/wireless/orinoco/orinoco.c6152
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h28
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c33
-rw-r--r--drivers/net/wireless/orinoco/orinoco_nortel.c7
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.c5
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.h12
-rw-r--r--drivers/net/wireless/orinoco/orinoco_plx.c3
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c4
-rw-r--r--drivers/net/wireless/orinoco/scan.c233
-rw-r--r--drivers/net/wireless/orinoco/scan.h29
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c19
-rw-r--r--drivers/net/wireless/orinoco/wext.c2325
-rw-r--r--drivers/net/wireless/orinoco/wext.h13
-rw-r--r--drivers/net/wireless/p54/Kconfig10
-rw-r--r--drivers/net/wireless/p54/Makefile1
-rw-r--r--drivers/net/wireless/p54/p54.h64
-rw-r--r--drivers/net/wireless/p54/p54common.c820
-rw-r--r--drivers/net/wireless/p54/p54common.h132
-rw-r--r--drivers/net/wireless/p54/p54pci.c42
-rw-r--r--drivers/net/wireless/p54/p54spi.c765
-rw-r--r--drivers/net/wireless/p54/p54spi.h125
-rw-r--r--drivers/net/wireless/p54/p54spi_eeprom.h678
-rw-r--r--drivers/net/wireless/p54/p54usb.c135
-rw-r--r--drivers/net/wireless/p54/p54usb.h1
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c3
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c40
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h3
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c18
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.h6
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c2
-rw-r--r--drivers/net/wireless/ray_cs.c3815
-rw-r--r--drivers/net/wireless/rndis_wlan.c119
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig7
-rw-r--r--drivers/net/wireless/rt2x00/Makefile1
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c103
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c131
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c80
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h14
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h154
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c15
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c49
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c416
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dump.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c29
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h106
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c471
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c77
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c215
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h22
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c127
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c64
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h13
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c244
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h13
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c240
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h19
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h4
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c99
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.c10
-rw-r--r--drivers/net/wireless/strip.c28
-rw-r--r--drivers/net/wireless/wavelan.c11
-rw-r--r--drivers/net/wireless/wavelan_cs.c79
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h6
-rw-r--r--drivers/net/wireless/wl3501.h2
-rw-r--r--drivers/net/wireless/wl3501_cs.c51
-rw-r--r--drivers/net/wireless/zd1201.c55
-rw-r--r--drivers/net/wireless/zd1201.h1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c21
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_def.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c46
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--drivers/net/xen-netfront.c8
-rw-r--r--drivers/net/xtsonic.c2
-rw-r--r--drivers/net/yellowfin.c6
-rw-r--r--drivers/net/znet.c17
-rw-r--r--drivers/oprofile/cpu_buffer.c5
-rw-r--r--drivers/oprofile/cpu_buffer.h7
-rw-r--r--drivers/parisc/dino.c13
-rw-r--r--drivers/parisc/gsc.c39
-rw-r--r--drivers/parisc/iosapic.c16
-rw-r--r--drivers/parisc/lba_pci.c4
-rw-r--r--drivers/parisc/sba_iommu.c81
-rw-r--r--drivers/parport/parport_atari.c6
-rw-r--r--drivers/parport/parport_serial.c5
-rw-r--r--drivers/pci/dmar.c73
-rw-r--r--drivers/pci/hotplug/Kconfig2
-rw-r--r--drivers/pci/hotplug/Makefile6
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c2
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c3
-rw-r--r--drivers/pci/hotplug/fakephp.c42
-rw-r--r--drivers/pci/hotplug/pciehp.h2
-rw-r--r--drivers/pci/hotplug/pciehp_core.c11
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c15
-rw-r--r--drivers/pci/intel-iommu.c30
-rw-r--r--drivers/pci/intr_remapping.c23
-rw-r--r--drivers/pci/msi.c27
-rw-r--r--drivers/pci/pci-driver.c266
-rw-r--r--drivers/pci/pci-sysfs.c4
-rw-r--r--drivers/pci/pci.c84
-rw-r--r--drivers/pci/pci.h26
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c51
-rw-r--r--drivers/pci/pcie/aspm.c4
-rw-r--r--drivers/pci/pcie/portdrv_pci.c19
-rw-r--r--drivers/pci/quirks.c151
-rw-r--r--drivers/pci/rom.c9
-rw-r--r--drivers/pcmcia/au1000_generic.c37
-rw-r--r--drivers/pcmcia/i82365.c28
-rw-r--r--drivers/pcmcia/m32r_cfc.c30
-rw-r--r--drivers/pcmcia/m32r_pcc.c30
-rw-r--r--drivers/pcmcia/rsrc_mgr.c2
-rw-r--r--drivers/pcmcia/sa1100_generic.c38
-rw-r--r--drivers/pcmcia/tcic.c30
-rw-r--r--drivers/pcmcia/vrc4171_card.c34
-rw-r--r--drivers/platform/x86/Kconfig40
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c4
-rw-r--r--drivers/platform/x86/asus-laptop.c179
-rw-r--r--drivers/platform/x86/asus_acpi.c16
-rw-r--r--drivers/platform/x86/dell-laptop.c (renamed from drivers/misc/dell-laptop.c)2
-rw-r--r--drivers/platform/x86/eeepc-laptop.c172
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c25
-rw-r--r--drivers/platform/x86/hp-wmi.c12
-rw-r--r--drivers/platform/x86/panasonic-laptop.c2
-rw-r--r--drivers/platform/x86/sony-laptop.c7
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c918
-rw-r--r--drivers/platform/x86/wmi.c2
-rw-r--r--drivers/power/ds2760_battery.c11
-rw-r--r--drivers/power/pcf50633-charger.c3
-rw-r--r--drivers/power/pda_power.c2
-rw-r--r--drivers/ps3/ps3-lpm.c16
-rw-r--r--drivers/ps3/ps3-vuart.c32
-rw-r--r--drivers/ps3/ps3stor_lib.c14
-rw-r--r--drivers/rapidio/rio-driver.c2
-rw-r--r--drivers/regulator/bq24022.c6
-rw-r--r--drivers/regulator/wm8350-regulator.c2
-rw-r--r--drivers/regulator/wm8400-regulator.c2
-rw-r--r--drivers/rtc/Kconfig6
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-at91sam9.c4
-rw-r--r--drivers/rtc/rtc-au1xxx.c2
-rw-r--r--drivers/rtc/rtc-dm355evm.c175
-rw-r--r--drivers/rtc/rtc-ds1390.c1
-rw-r--r--drivers/rtc/rtc-omap.c4
-rw-r--r--drivers/rtc/rtc-pxa.c2
-rw-r--r--drivers/rtc/rtc-sh.c246
-rw-r--r--drivers/rtc/rtc-twl4030.c2
-rw-r--r--drivers/s390/Makefile3
-rw-r--r--drivers/s390/block/dasd.c295
-rw-r--r--drivers/s390/block/dasd_3990_erp.c871
-rw-r--r--drivers/s390/block/dasd_alias.c35
-rw-r--r--drivers/s390/block/dasd_devmap.c45
-rw-r--r--drivers/s390/block/dasd_diag.c66
-rw-r--r--drivers/s390/block/dasd_eckd.c1297
-rw-r--r--drivers/s390/block/dasd_eckd.h49
-rw-r--r--drivers/s390/block/dasd_eer.c27
-rw-r--r--drivers/s390/block/dasd_erp.c21
-rw-r--r--drivers/s390/block/dasd_fba.c77
-rw-r--r--drivers/s390/block/dasd_genhd.c7
-rw-r--r--drivers/s390/block/dasd_int.h13
-rw-r--r--drivers/s390/block/dasd_ioctl.c46
-rw-r--r--drivers/s390/block/dasd_proc.c22
-rw-r--r--drivers/s390/char/sclp.c5
-rw-r--r--drivers/s390/char/sclp_cmd.c5
-rw-r--r--drivers/s390/char/tape.h2
-rw-r--r--drivers/s390/char/tape_34xx.c161
-rw-r--r--drivers/s390/char/tape_3590.c367
-rw-r--r--drivers/s390/char/tape_block.c18
-rw-r--r--drivers/s390/char/tape_char.c7
-rw-r--r--drivers/s390/char/tape_core.c68
-rw-r--r--drivers/s390/char/tape_proc.c3
-rw-r--r--drivers/s390/char/tape_std.c25
-rw-r--r--drivers/s390/char/zcore.c90
-rw-r--r--drivers/s390/cio/Makefile2
-rw-r--r--drivers/s390/cio/airq.c6
-rw-r--r--drivers/s390/cio/blacklist.c3
-rw-r--r--drivers/s390/cio/ccwgroup.c78
-rw-r--r--drivers/s390/cio/chp.c6
-rw-r--r--drivers/s390/cio/chsc.c7
-rw-r--r--drivers/s390/cio/chsc_sch.c4
-rw-r--r--drivers/s390/cio/cio.c21
-rw-r--r--drivers/s390/cio/crw.c159
-rw-r--r--drivers/s390/cio/css.c62
-rw-r--r--drivers/s390/cio/device.c57
-rw-r--r--drivers/s390/cio/device.h2
-rw-r--r--drivers/s390/cio/device_fsm.c8
-rw-r--r--drivers/s390/cio/device_ops.c2
-rw-r--r--drivers/s390/cio/qdio.h8
-rw-r--r--drivers/s390/cio/qdio_debug.c3
-rw-r--r--drivers/s390/cio/qdio_main.c222
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/cio/qdio_thinint.c23
-rw-r--r--drivers/s390/crypto/zcrypt_api.c6
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c3
-rw-r--r--drivers/s390/ebcdic.c246
-rw-r--r--drivers/s390/net/Makefile2
-rw-r--r--drivers/s390/net/claw.c485
-rw-r--r--drivers/s390/net/ctcm_fsms.c5
-rw-r--r--drivers/s390/net/ctcm_main.c39
-rw-r--r--drivers/s390/net/ctcm_mpc.c17
-rw-r--r--drivers/s390/net/lcs.c41
-rw-r--r--drivers/s390/net/netiucv.c16
-rw-r--r--drivers/s390/net/qeth_core.h8
-rw-r--r--drivers/s390/net/qeth_core_main.c165
-rw-r--r--drivers/s390/net/qeth_core_offl.c699
-rw-r--r--drivers/s390/net/qeth_core_offl.h76
-rw-r--r--drivers/s390/net/qeth_core_sys.c4
-rw-r--r--drivers/s390/net/qeth_l2_main.c99
-rw-r--r--drivers/s390/net/qeth_l3_main.c129
-rw-r--r--drivers/s390/s390mach.c538
-rw-r--r--drivers/s390/s390mach.h122
-rw-r--r--drivers/s390/sysinfo.c469
-rw-r--r--drivers/sbus/char/bbc_i2c.c2
-rw-r--r--drivers/sbus/char/jsflash.c3
-rw-r--r--drivers/sbus/char/openprom.c1
-rw-r--r--drivers/scsi/a4000t.c29
-rw-r--r--drivers/scsi/atari_NCR5380.c2
-rw-r--r--drivers/scsi/atari_scsi.c2
-rw-r--r--drivers/scsi/bvme6000_scsi.c29
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i.h21
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c19
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.h5
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_init.c4
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c22
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c146
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.h29
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.c275
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.h2
-rw-r--r--drivers/scsi/fcoe/fc_transport_fcoe.c91
-rw-r--r--drivers/scsi/fcoe/fcoe_sw.c56
-rw-r--r--drivers/scsi/fcoe/libfcoe.c318
-rw-r--r--drivers/scsi/hptiop.c1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c33
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h8
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c1
-rw-r--r--drivers/scsi/ipr.c2
-rw-r--r--drivers/scsi/lasi700.c2
-rw-r--r--drivers/scsi/libfc/fc_disc.c63
-rw-r--r--drivers/scsi/libfc/fc_exch.c32
-rw-r--r--drivers/scsi/libfc/fc_fcp.c56
-rw-r--r--drivers/scsi/libfc/fc_lport.c173
-rw-r--r--drivers/scsi/libfc/fc_rport.c197
-rw-r--r--drivers/scsi/libiscsi.c4
-rw-r--r--drivers/scsi/libiscsi_tcp.c3
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c1
-rw-r--r--drivers/scsi/mvme16x_scsi.c29
-rw-r--r--drivers/scsi/ps3rom.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c28
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_devtbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h10
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c137
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c63
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c59
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c23
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c51
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c25
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h1
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c10
-rw-r--r--drivers/scsi/scsi.c5
-rw-r--r--drivers/scsi/scsi_devinfo.c1
-rw-r--r--drivers/scsi/scsi_lib.c5
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/scsi_transport_fc.c16
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c12
-rw-r--r--drivers/scsi/sd.c33
-rw-r--r--drivers/scsi/sg.c6
-rw-r--r--drivers/scsi/zalon.c2
-rw-r--r--drivers/serial/8250.c15
-rw-r--r--drivers/serial/8250_pci.c42
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/atmel_serial.c4
-rw-r--r--drivers/serial/jsm/jsm_driver.c5
-rw-r--r--drivers/serial/jsm/jsm_tty.c6
-rw-r--r--drivers/serial/mcf.c11
-rw-r--r--drivers/serial/of_serial.c1
-rw-r--r--drivers/serial/sh-sci.c12
-rw-r--r--drivers/serial/sh-sci.h22
-rw-r--r--drivers/serial/sunzilog.c4
-rw-r--r--drivers/sh/intc.c47
-rw-r--r--drivers/sh/maple/maple.c471
-rw-r--r--drivers/sh/superhyway/superhyway.c4
-rw-r--r--drivers/spi/Kconfig11
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/atmel_spi.c8
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c2
-rw-r--r--drivers/spi/omap2_mcspi.c2
-rw-r--r--drivers/spi/omap_uwire.c12
-rw-r--r--drivers/spi/orion_spi.c2
-rw-r--r--drivers/spi/pxa2xx_spi.c4
-rw-r--r--drivers/spi/spi_bfin5xx.c4
-rw-r--r--drivers/spi/spi_gpio.c4
-rw-r--r--drivers/spi/spi_imx.c5
-rw-r--r--drivers/spi/spi_mpc83xx.c4
-rw-r--r--drivers/spi/spi_txx9.c3
-rw-r--r--drivers/ssb/Makefile1
-rw-r--r--drivers/ssb/b43_pci_bridge.c2
-rw-r--r--drivers/ssb/driver_chipcommon.c14
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c508
-rw-r--r--drivers/ssb/pci.c88
-rw-r--r--drivers/ssb/sprom.c36
-rw-r--r--drivers/ssb/ssb_private.h1
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/agnx/agnx.h2
-rw-r--r--drivers/staging/altpciechdma/altpciechdma.c4
-rw-r--r--drivers/staging/android/Kconfig1
-rw-r--r--drivers/staging/android/binder.c16
-rw-r--r--drivers/staging/android/lowmemorykiller.txt16
-rw-r--r--drivers/staging/android/ram_console.c14
-rw-r--r--drivers/staging/android/timed_gpio.c5
-rw-r--r--drivers/staging/at76_usb/Kconfig2
-rw-r--r--drivers/staging/at76_usb/at76_usb.c4620
-rw-r--r--drivers/staging/at76_usb/at76_usb.h227
-rw-r--r--drivers/staging/benet/Kconfig7
-rw-r--r--drivers/staging/benet/MAINTAINERS6
-rw-r--r--drivers/staging/benet/Makefile14
-rw-r--r--drivers/staging/benet/TODO6
-rw-r--r--drivers/staging/benet/asyncmesg.h82
-rw-r--r--drivers/staging/benet/be_cm.h134
-rw-r--r--drivers/staging/benet/be_common.h53
-rw-r--r--drivers/staging/benet/be_ethtool.c348
-rw-r--r--drivers/staging/benet/be_init.c1382
-rw-r--r--drivers/staging/benet/be_int.c863
-rw-r--r--drivers/staging/benet/be_netif.c705
-rw-r--r--drivers/staging/benet/benet.h429
-rw-r--r--drivers/staging/benet/bestatus.h103
-rw-r--r--drivers/staging/benet/cev.h243
-rw-r--r--drivers/staging/benet/cq.c211
-rw-r--r--drivers/staging/benet/descriptors.h71
-rw-r--r--drivers/staging/benet/doorbells.h179
-rw-r--r--drivers/staging/benet/ep.h66
-rw-r--r--drivers/staging/benet/eq.c299
-rw-r--r--drivers/staging/benet/eth.c1273
-rw-r--r--drivers/staging/benet/etx_context.h55
-rw-r--r--drivers/staging/benet/funcobj.c565
-rw-r--r--drivers/staging/benet/fwcmd_common.h222
-rw-r--r--drivers/staging/benet/fwcmd_common_bmap.h717
-rw-r--r--drivers/staging/benet/fwcmd_eth_bmap.h280
-rw-r--r--drivers/staging/benet/fwcmd_hdr_bmap.h54
-rw-r--r--drivers/staging/benet/fwcmd_mcc.h94
-rw-r--r--drivers/staging/benet/fwcmd_opcodes.h244
-rw-r--r--drivers/staging/benet/fwcmd_types_bmap.h29
-rw-r--r--drivers/staging/benet/host_struct.h182
-rw-r--r--drivers/staging/benet/hwlib.h830
-rw-r--r--drivers/staging/benet/mpu.c1364
-rw-r--r--drivers/staging/benet/mpu.h74
-rw-r--r--drivers/staging/benet/mpu_context.h46
-rw-r--r--drivers/staging/benet/pcicfg.h825
-rw-r--r--drivers/staging/benet/post_codes.h111
-rw-r--r--drivers/staging/benet/regmap.h68
-rw-r--r--drivers/staging/comedi/Kconfig1
-rw-r--r--drivers/staging/go7007/snd-go7007.c7
-rw-r--r--drivers/staging/meilhaus/Kconfig21
-rw-r--r--drivers/staging/panel/panel.c33
-rw-r--r--drivers/staging/poch/poch.c2
-rw-r--r--drivers/staging/rtl8187se/Kconfig1
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c19
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c2
-rw-r--r--drivers/staging/usbip/usbip_common.c16
-rw-r--r--drivers/staging/winbond/wbusb.c20
-rw-r--r--drivers/tc/tc.c8
-rw-r--r--drivers/uio/Kconfig18
-rw-r--r--drivers/uio/Makefile1
-rw-r--r--drivers/uio/uio.c25
-rw-r--r--drivers/uio/uio_aec.c175
-rw-r--r--drivers/usb/Kconfig1
-rw-r--r--drivers/usb/Makefile3
-rw-r--r--drivers/usb/atm/cxacru.c3
-rw-r--r--drivers/usb/class/cdc-acm.c15
-rw-r--r--drivers/usb/class/usblp.c12
-rw-r--r--drivers/usb/class/usbtmc.c4
-rw-r--r--drivers/usb/core/devices.c2
-rw-r--r--drivers/usb/core/devio.c53
-rw-r--r--drivers/usb/core/driver.c2
-rw-r--r--drivers/usb/core/endpoint.c9
-rw-r--r--drivers/usb/core/hcd-pci.c112
-rw-r--r--drivers/usb/core/hcd.c33
-rw-r--r--drivers/usb/core/hcd.h2
-rw-r--r--drivers/usb/core/hub.c38
-rw-r--r--drivers/usb/core/inode.c1
-rw-r--r--drivers/usb/core/message.c62
-rw-r--r--drivers/usb/core/quirks.c4
-rw-r--r--drivers/usb/core/sysfs.c4
-rw-r--r--drivers/usb/core/urb.c4
-rw-r--r--drivers/usb/core/usb.h6
-rw-r--r--drivers/usb/gadget/Kconfig2
-rw-r--r--drivers/usb/gadget/amd5536udc.c2
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c20
-rw-r--r--drivers/usb/gadget/cdc2.c8
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c3
-rw-r--r--drivers/usb/gadget/composite.c22
-rw-r--r--drivers/usb/gadget/dummy_hcd.c4
-rw-r--r--drivers/usb/gadget/epautoconf.c2
-rw-r--r--drivers/usb/gadget/ether.c8
-rw-r--r--drivers/usb/gadget/f_acm.c10
-rw-r--r--drivers/usb/gadget/f_ecm.c16
-rw-r--r--drivers/usb/gadget/f_loopback.c10
-rw-r--r--drivers/usb/gadget/f_obex.c12
-rw-r--r--drivers/usb/gadget/f_phonet.c8
-rw-r--r--drivers/usb/gadget/f_rndis.c12
-rw-r--r--drivers/usb/gadget/f_serial.c4
-rw-r--r--drivers/usb/gadget/f_sourcesink.c56
-rw-r--r--drivers/usb/gadget/f_subset.c14
-rw-r--r--drivers/usb/gadget/file_storage.c35
-rw-r--r--drivers/usb/gadget/fsl_qe_udc.c46
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.c11
-rw-r--r--drivers/usb/gadget/g_zero.h4
-rw-r--r--drivers/usb/gadget/gmidi.c23
-rw-r--r--drivers/usb/gadget/goku_udc.c8
-rw-r--r--drivers/usb/gadget/imx_udc.c250
-rw-r--r--drivers/usb/gadget/imx_udc.h49
-rw-r--r--drivers/usb/gadget/inode.c4
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c16
-rw-r--r--drivers/usb/gadget/net2280.c16
-rw-r--r--drivers/usb/gadget/printer.c18
-rw-r--r--drivers/usb/gadget/pxa25x_udc.c4
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c272
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h10
-rw-r--r--drivers/usb/gadget/rndis.c99
-rw-r--r--drivers/usb/gadget/serial.c12
-rw-r--r--drivers/usb/gadget/u_serial.c2
-rw-r--r--drivers/usb/gadget/zero.c78
-rw-r--r--drivers/usb/host/Kconfig25
-rw-r--r--drivers/usb/host/Makefile6
-rw-r--r--drivers/usb/host/ehci-hcd.c38
-rw-r--r--drivers/usb/host/ehci-mem.c1
-rw-r--r--drivers/usb/host/ehci-pci.c4
-rw-r--r--drivers/usb/host/ehci-q.c35
-rw-r--r--drivers/usb/host/ehci-sched.c68
-rw-r--r--drivers/usb/host/ehci.h43
-rw-r--r--drivers/usb/host/fhci-dbg.c139
-rw-r--r--drivers/usb/host/fhci-hcd.c836
-rw-r--r--drivers/usb/host/fhci-hub.c345
-rw-r--r--drivers/usb/host/fhci-mem.c113
-rw-r--r--drivers/usb/host/fhci-q.c284
-rw-r--r--drivers/usb/host/fhci-sched.c888
-rw-r--r--drivers/usb/host/fhci-tds.c626
-rw-r--r--drivers/usb/host/fhci.h607
-rw-r--r--drivers/usb/host/hwa-hc.c3
-rw-r--r--drivers/usb/host/isp116x-hcd.c2
-rw-r--r--drivers/usb/host/isp116x.h8
-rw-r--r--drivers/usb/host/isp1760-hcd.c25
-rw-r--r--drivers/usb/host/isp1760-hcd.h7
-rw-r--r--drivers/usb/host/isp1760-if.c95
-rw-r--r--drivers/usb/host/ohci-hcd.c13
-rw-r--r--drivers/usb/host/ohci-omap.c6
-rw-r--r--drivers/usb/host/ohci-pci.c2
-rw-r--r--drivers/usb/host/ohci-s3c2410.c6
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c24
-rw-r--r--drivers/usb/host/oxu210hp.h8
-rw-r--r--drivers/usb/host/pci-quirks.c2
-rw-r--r--drivers/usb/host/r8a66597-hcd.c118
-rw-r--r--drivers/usb/host/r8a66597.h2
-rw-r--r--drivers/usb/host/sl811-hcd.c4
-rw-r--r--drivers/usb/host/uhci-debug.c4
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/host/uhci-hcd.h10
-rw-r--r--drivers/usb/host/uhci-q.c21
-rw-r--r--drivers/usb/host/whci/asl.c13
-rw-r--r--drivers/usb/host/whci/hw.c15
-rw-r--r--drivers/usb/host/whci/pzl.c13
-rw-r--r--drivers/usb/host/whci/whcd.h1
-rw-r--r--drivers/usb/image/mdc800.c9
-rw-r--r--drivers/usb/misc/Kconfig39
-rw-r--r--drivers/usb/misc/Makefile4
-rw-r--r--drivers/usb/misc/adutux.c6
-rw-r--r--drivers/usb/misc/ftdi-elan.c6
-rw-r--r--drivers/usb/misc/ldusb.c2
-rw-r--r--drivers/usb/misc/phidget.c43
-rw-r--r--drivers/usb/misc/phidget.h12
-rw-r--r--drivers/usb/misc/phidgetkit.c740
-rw-r--r--drivers/usb/misc/phidgetmotorcontrol.c465
-rw-r--r--drivers/usb/misc/phidgetservo.c375
-rw-r--r--drivers/usb/misc/vstusb.c1
-rw-r--r--drivers/usb/mon/mon_bin.c239
-rw-r--r--drivers/usb/musb/Kconfig9
-rw-r--r--drivers/usb/musb/cppi_dma.c10
-rw-r--r--drivers/usb/musb/davinci.c91
-rw-r--r--drivers/usb/musb/davinci.h23
-rw-r--r--drivers/usb/musb/musb_core.c20
-rw-r--r--drivers/usb/musb/musb_core.h5
-rw-r--r--drivers/usb/musb/musb_gadget.c10
-rw-r--r--drivers/usb/musb/musb_host.c237
-rw-r--r--drivers/usb/musb/musb_virthub.c2
-rw-r--r--drivers/usb/musb/tusb6010_omap.c4
-rw-r--r--drivers/usb/otg/Kconfig14
-rw-r--r--drivers/usb/otg/Makefile1
-rw-r--r--drivers/usb/otg/gpio_vbus.c42
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c180
-rw-r--r--drivers/usb/otg/twl4030-usb.c73
-rw-r--r--drivers/usb/serial/Kconfig28
-rw-r--r--drivers/usb/serial/Makefile4
-rw-r--r--drivers/usb/serial/aircable.c4
-rw-r--r--drivers/usb/serial/ch341.c396
-rw-r--r--drivers/usb/serial/cp210x.c (renamed from drivers/usb/serial/cp2101.c)164
-rw-r--r--drivers/usb/serial/ftdi_sio.c41
-rw-r--r--drivers/usb/serial/ftdi_sio.h32
-rw-r--r--drivers/usb/serial/generic.c9
-rw-r--r--drivers/usb/serial/ipaq.c43
-rw-r--r--drivers/usb/serial/keyspan.c2
-rw-r--r--drivers/usb/serial/opticon.c215
-rw-r--r--drivers/usb/serial/option.c206
-rw-r--r--drivers/usb/serial/qcserial.c147
-rw-r--r--drivers/usb/serial/symbolserial.c399
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c13
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.h4
-rw-r--r--drivers/usb/serial/usb-serial.c20
-rw-r--r--drivers/usb/storage/Kconfig48
-rw-r--r--drivers/usb/storage/Makefile41
-rw-r--r--drivers/usb/storage/alauda.c192
-rw-r--r--drivers/usb/storage/alauda.h100
-rw-r--r--drivers/usb/storage/cypress_atacb.c106
-rw-r--r--drivers/usb/storage/datafab.c104
-rw-r--r--drivers/usb/storage/datafab.h40
-rw-r--r--drivers/usb/storage/freecom.c99
-rw-r--r--drivers/usb/storage/isd200.c97
-rw-r--r--drivers/usb/storage/jumpshot.c103
-rw-r--r--drivers/usb/storage/jumpshot.h39
-rw-r--r--drivers/usb/storage/karma.c100
-rw-r--r--drivers/usb/storage/karma.h7
-rw-r--r--drivers/usb/storage/libusual.c33
-rw-r--r--drivers/usb/storage/onetouch.c94
-rw-r--r--drivers/usb/storage/onetouch.h9
-rw-r--r--drivers/usb/storage/protocol.c3
-rw-r--r--drivers/usb/storage/scsiglue.c10
-rw-r--r--drivers/usb/storage/sddr09.c147
-rw-r--r--drivers/usb/storage/sddr09.h38
-rw-r--r--drivers/usb/storage/sddr55.c99
-rw-r--r--drivers/usb/storage/shuttle_usbat.c202
-rw-r--r--drivers/usb/storage/shuttle_usbat.h123
-rw-r--r--drivers/usb/storage/transport.c46
-rw-r--r--drivers/usb/storage/unusual_alauda.h (renamed from drivers/usb/storage/freecom.h)29
-rw-r--r--drivers/usb/storage/unusual_cypress.h34
-rw-r--r--drivers/usb/storage/unusual_datafab.h98
-rw-r--r--drivers/usb/storage/unusual_devs.h380
-rw-r--r--drivers/usb/storage/unusual_freecom.h (renamed from drivers/usb/storage/cypress_atacb.h)19
-rw-r--r--drivers/usb/storage/unusual_isd200.h57
-rw-r--r--drivers/usb/storage/unusual_jumpshot.h (renamed from drivers/usb/storage/sddr55.h)23
-rw-r--r--drivers/usb/storage/unusual_karma.h (renamed from drivers/usb/storage/isd200.h)21
-rw-r--r--drivers/usb/storage/unusual_onetouch.h36
-rw-r--r--drivers/usb/storage/unusual_sddr09.h56
-rw-r--r--drivers/usb/storage/unusual_sddr55.h44
-rw-r--r--drivers/usb/storage/unusual_usbat.h43
-rw-r--r--drivers/usb/storage/usb.c344
-rw-r--r--drivers/usb/storage/usb.h21
-rw-r--r--drivers/usb/storage/usual-tables.c116
-rw-r--r--drivers/usb/usb-skeleton.c6
-rw-r--r--drivers/usb/wusbcore/cbaf.c3
-rw-r--r--drivers/usb/wusbcore/devconnect.c3
-rw-r--r--drivers/usb/wusbcore/rh.c3
-rw-r--r--drivers/usb/wusbcore/security.c2
-rw-r--r--drivers/usb/wusbcore/wa-xfer.c4
-rw-r--r--drivers/uwb/allocator.c1
-rw-r--r--drivers/uwb/drp.c4
-rw-r--r--drivers/uwb/rsv.c21
-rw-r--r--drivers/video/Kconfig22
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/atafb.c22
-rw-r--r--drivers/video/aty/aty128fb.c44
-rw-r--r--drivers/video/aty/atyfb_base.c42
-rw-r--r--drivers/video/aty/mach64_ct.c11
-rw-r--r--drivers/video/aty/radeon_base.c10
-rw-r--r--drivers/video/aty/radeon_i2c.c1
-rw-r--r--drivers/video/aty/radeon_pm.c137
-rw-r--r--drivers/video/aty/radeonfb.h2
-rw-r--r--drivers/video/au1100fb.c31
-rw-r--r--drivers/video/au1200fb.c25
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/da903x_bl.c (renamed from drivers/video/backlight/da903x.c)0
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c2
-rw-r--r--drivers/video/fbcmap.c20
-rw-r--r--drivers/video/fbmem.c135
-rw-r--r--drivers/video/geode/gx1fb_core.c17
-rw-r--r--drivers/video/geode/gxfb_core.c17
-rw-r--r--drivers/video/geode/lxfb_core.c17
-rw-r--r--drivers/video/i810/i810-i2c.c1
-rw-r--r--drivers/video/i810/i810_main.c5
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c1
-rw-r--r--drivers/video/logo/logo_linux_clut224.ppm4428
-rw-r--r--drivers/video/logo/logo_linux_vga16.ppm4339
-rw-r--r--drivers/video/mx3fb.c1555
-rw-r--r--drivers/video/nvidia/nv_i2c.c1
-rw-r--r--drivers/video/omap/lcdc.c4
-rw-r--r--drivers/video/pmag-ba-fb.c17
-rw-r--r--drivers/video/pmagb-b-fb.c17
-rw-r--r--drivers/video/ps3fb.c6
-rw-r--r--drivers/video/pvr2fb.c16
-rw-r--r--drivers/video/pxafb.c2
-rw-r--r--drivers/video/savage/savagefb-i2c.c1
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c72
-rw-r--r--drivers/video/tmiofb.c2
-rw-r--r--drivers/video/uvesafb.c5
-rw-r--r--drivers/virtio/virtio_pci.c2
-rw-r--r--drivers/w1/masters/w1-gpio.c2
-rw-r--r--drivers/w1/slaves/Kconfig6
-rw-r--r--drivers/w1/slaves/Makefile1
-rw-r--r--drivers/w1/slaves/w1_ds2433.c7
-rw-r--r--drivers/w1/slaves/w1_therm.c2
-rw-r--r--drivers/watchdog/Kconfig23
-rw-r--r--drivers/watchdog/acquirewdt.c8
-rw-r--r--drivers/watchdog/advantechwdt.c7
-rw-r--r--drivers/watchdog/alim1535_wdt.c20
-rw-r--r--drivers/watchdog/alim7101_wdt.c6
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c5
-rw-r--r--drivers/watchdog/at91sam9_wdt.c3
-rw-r--r--drivers/watchdog/cpwd.c101
-rw-r--r--drivers/watchdog/davinci_wdt.c45
-rw-r--r--drivers/watchdog/eurotechwdt.c22
-rw-r--r--drivers/watchdog/gef_wdt.c2
-rw-r--r--drivers/watchdog/geodewdt.c11
-rw-r--r--drivers/watchdog/hpwdt.c20
-rw-r--r--drivers/watchdog/i6300esb.c101
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c38
-rw-r--r--drivers/watchdog/iTCO_wdt.c50
-rw-r--r--drivers/watchdog/it87_wdt.c12
-rw-r--r--drivers/watchdog/ks8695_wdt.c1
-rw-r--r--drivers/watchdog/mpc5200_wdt.c4
-rw-r--r--drivers/watchdog/mpcore_wdt.c2
-rw-r--r--drivers/watchdog/mtx-1_wdt.c2
-rw-r--r--drivers/watchdog/orion5x_wdt.c75
-rw-r--r--drivers/watchdog/pc87413_wdt.c6
-rw-r--r--drivers/watchdog/pcwd.c44
-rw-r--r--drivers/watchdog/pcwd_pci.c108
-rw-r--r--drivers/watchdog/pcwd_usb.c175
-rw-r--r--drivers/watchdog/pnx4008_wdt.c18
-rw-r--r--drivers/watchdog/rc32434_wdt.c275
-rw-r--r--drivers/watchdog/riowd.c23
-rw-r--r--drivers/watchdog/rm9k_wdt.c27
-rw-r--r--drivers/watchdog/sa1100_wdt.c6
-rw-r--r--drivers/watchdog/sbc60xxwdt.c2
-rw-r--r--drivers/watchdog/sbc8360.c12
-rw-r--r--drivers/watchdog/sbc_epx_c3.c3
-rw-r--r--drivers/watchdog/sc1200wdt.c7
-rw-r--r--drivers/watchdog/sc520_wdt.c9
-rw-r--r--drivers/watchdog/smsc37b787_wdt.c30
-rw-r--r--drivers/watchdog/softdog.c5
-rw-r--r--drivers/watchdog/w83697hf_wdt.c3
-rw-r--r--drivers/watchdog/w83697ug_wdt.c23
-rw-r--r--drivers/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/watchdog/wd501p.h24
-rw-r--r--drivers/watchdog/wdt.c152
-rw-r--r--drivers/watchdog/wdt977.c2
-rw-r--r--drivers/xen/balloon.c41
-rw-r--r--drivers/xen/manage.c8
-rw-r--r--drivers/xen/xenfs/xenbus.c11
-rw-r--r--drivers/zorro/zorro.c4
1951 files changed, 167410 insertions, 124854 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index d7f9839ba26..8a851d0f438 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -9,6 +9,7 @@ menuconfig ACPI
depends on PCI
depends on PM
select PNP
+ select CPU_IDLE
default y
---help---
Advanced Configuration and Power Interface (ACPI) support for
@@ -253,13 +254,6 @@ config ACPI_PCI_SLOT
help you correlate PCI bus addresses with the physical geography
of your slots. If you are unsure, say N.
-config ACPI_SYSTEM
- bool
- default y
- help
- This driver will enable your system to shut down using ACPI, and
- dump your ACPI DSDT table using /proc/acpi/dsdt.
-
config X86_PM_TIMER
bool "Power Management Timer Support" if EMBEDDED
depends on X86
@@ -287,7 +281,7 @@ config ACPI_CONTAINER
support physical cpu/memory hot-plug.
If one selects "m", this driver can be loaded with
- "modprobe acpi_container".
+ "modprobe container".
config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug"
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index d80f4cc2e0d..b130ea0d075 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -19,7 +19,7 @@ obj-y += osl.o utils.o reboot.o\
# sleep related files
obj-y += wakeup.o
-obj-y += main.o
+obj-y += sleep.o
obj-$(CONFIG_ACPI_SLEEP) += proc.o
@@ -52,7 +52,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_CONTAINER) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-y += power.o
-obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o
+obj-y += system.o event.o
obj-$(CONFIG_ACPI_DEBUG) += debug.o
obj-$(CONFIG_ACPI_NUMA) += numa.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 9684cc82793..22ce4898572 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -538,10 +538,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
if (ACPI_FAILURE(status)) {
ACPI_WARNING((AE_INFO,
"Truncating %u table entries!",
- (unsigned)
- (acpi_gbl_root_table_list.size -
- acpi_gbl_root_table_list.
- count)));
+ (unsigned) (table_count -
+ (acpi_gbl_root_table_list.
+ count - 2))));
break;
}
}
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index da9450bc60f..9c9897dbe90 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -116,9 +116,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
return_ACPI_STATUS(AE_NO_MEMORY);
}
- /* Default return value is SUPPORTED */
+ /* Default return value is 0, NOT-SUPPORTED */
- return_desc->integer.value = ACPI_UINT32_MAX;
+ return_desc->integer.value = 0;
walk_state->return_desc = return_desc;
/* Compare input string to static table of supported interfaces */
@@ -127,10 +127,8 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
if (!ACPI_STRCMP
(string_desc->string.pointer,
acpi_interfaces_supported[i])) {
-
- /* The interface is supported */
-
- return_ACPI_STATUS(AE_OK);
+ return_desc->integer.value = ACPI_UINT32_MAX;
+ goto done;
}
}
@@ -141,15 +139,14 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
*/
status = acpi_os_validate_interface(string_desc->string.pointer);
if (ACPI_SUCCESS(status)) {
-
- /* The interface is supported */
-
- return_ACPI_STATUS(AE_OK);
+ return_desc->integer.value = ACPI_UINT32_MAX;
}
- /* The interface is not supported */
+done:
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
+ string_desc->string.pointer,
+ return_desc->integer.value == 0 ? "not-" : ""));
- return_desc->integer.value = 0;
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 65132f92045..69cbc57c2d1 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -138,6 +138,29 @@ static int acpi_battery_technology(struct acpi_battery *battery)
static int acpi_battery_get_state(struct acpi_battery *battery);
+static int acpi_battery_is_charged(struct acpi_battery *battery)
+{
+ /* either charging or discharging */
+ if (battery->state != 0)
+ return 0;
+
+ /* battery not reporting charge */
+ if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
+ battery->capacity_now == 0)
+ return 0;
+
+ /* good batteries update full_charge as the batteries degrade */
+ if (battery->full_charge_capacity == battery->capacity_now)
+ return 1;
+
+ /* fallback to using design values for broken batteries */
+ if (battery->design_capacity == battery->capacity_now)
+ return 1;
+
+ /* we don't do any sort of metric based on percentages */
+ return 0;
+}
+
static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -155,7 +178,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (battery->state & 0x02)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
- else if (battery->state == 0)
+ else if (acpi_battery_is_charged(battery))
val->intval = POWER_SUPPLY_STATUS_FULL;
else
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 765fd1c56cd..bee64b73c91 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -758,8 +758,7 @@ static int __init acpi_bus_init(void)
acpi_status status = AE_OK;
extern acpi_status acpi_os_initialize1(void);
-
- status = acpi_os_initialize1();
+ acpi_os_initialize1();
status =
acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
@@ -769,12 +768,6 @@ static int __init acpi_bus_init(void)
goto error1;
}
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX
- "Unable to initialize ACPI OS objects\n");
- goto error1;
- }
-
/*
* ACPI 2.0 requires the EC driver to be loaded and work before
* the EC device is found in the namespace (i.e. before acpi_initialize_objects()
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 17020c12623..fe0cdf83641 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -163,7 +163,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
case ACPI_NOTIFY_BUS_CHECK:
/* Fall through */
case ACPI_NOTIFY_DEVICE_CHECK:
- printk("Container driver received %s event\n",
+ printk(KERN_WARNING "Container driver received %s event\n",
(type == ACPI_NOTIFY_BUS_CHECK) ?
"ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
status = acpi_bus_get_device(handle, &device);
@@ -174,7 +174,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
kobject_uevent(&device->dev.kobj,
KOBJ_ONLINE);
else
- printk("Failed to add container\n");
+ printk(KERN_WARNING
+ "Failed to add container\n");
}
} else {
if (ACPI_SUCCESS(status)) {
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 5b30b8d91d7..7af7db1ba8c 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -855,10 +855,14 @@ fdd_out:
static ssize_t show_docked(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ struct acpi_device *tmp;
+
struct dock_station *dock_station = *((struct dock_station **)
dev->platform_data);
- return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
+ if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp)))
+ return snprintf(buf, PAGE_SIZE, "1\n");
+ return snprintf(buf, PAGE_SIZE, "0\n");
}
static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
@@ -973,7 +977,7 @@ static int dock_add(acpi_handle handle)
sizeof(struct dock_station *));
/* we want the dock device to send uevents */
- dock_device->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&dock_device->dev, 0);
if (is_dock(handle))
dock_station->flags |= DOCK_IS_DOCK;
@@ -984,7 +988,7 @@ static int dock_add(acpi_handle handle)
ret = device_create_file(&dock_device->dev, &dev_attr_docked);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
platform_device_unregister(dock_device);
kfree(dock_station);
dock_station = NULL;
@@ -992,7 +996,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_undock);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
platform_device_unregister(dock_device);
kfree(dock_station);
@@ -1001,7 +1005,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_uid);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock);
platform_device_unregister(dock_device);
@@ -1011,7 +1015,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_flags);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock);
device_remove_file(&dock_device->dev, &dev_attr_uid);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 8dfcbb8aff7..2fe15060dcd 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -120,30 +120,7 @@ static struct acpi_ec {
spinlock_t curr_lock;
} *boot_ec, *first_ec;
-/*
- * Some Asus system have exchanged ECDT data/command IO addresses.
- */
-static int print_ecdt_error(const struct dmi_system_id *id)
-{
- printk(KERN_NOTICE PREFIX "%s detected - "
- "ECDT has exchanged control/data I/O address\n",
- id->ident);
- return 0;
-}
-
-static struct dmi_system_id __cpuinitdata ec_dmi_table[] = {
- {
- print_ecdt_error, "Asus L4R", {
- DMI_MATCH(DMI_BIOS_VERSION, "1008.006"),
- DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),
- DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL},
- {
- print_ecdt_error, "Asus M6R", {
- DMI_MATCH(DMI_BIOS_VERSION, "0207"),
- DMI_MATCH(DMI_PRODUCT_NAME, "M6R"),
- DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL},
- {},
-};
+static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
/* --------------------------------------------------------------------------
Transaction Management
@@ -284,6 +261,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
acpi_disable_gpe(NULL, ec->gpe);
}
+ if (EC_FLAGS_MSI)
+ udelay(ACPI_EC_DELAY);
/* start transaction */
spin_lock_irqsave(&ec->curr_lock, tmp);
/* following two actions should be kept atomic */
@@ -983,8 +962,8 @@ static const struct acpi_device_id ec_device_ids[] = {
int __init acpi_ec_ecdt_probe(void)
{
acpi_status status;
+ struct acpi_ec *saved_ec = NULL;
struct acpi_table_ecdt *ecdt_ptr;
- acpi_handle dummy;
boot_ec = make_acpi_ec();
if (!boot_ec)
@@ -992,27 +971,27 @@ int __init acpi_ec_ecdt_probe(void)
/*
* Generate a boot ec context
*/
+ if (dmi_name_in_vendors("Micro-Star") ||
+ dmi_name_in_vendors("Notebook")) {
+ pr_info(PREFIX "Enabling special treatment for EC from MSI.\n");
+ EC_FLAGS_MSI = 1;
+ }
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_SUCCESS(status)) {
pr_info(PREFIX "EC description table is found, configuring boot EC\n");
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
- if (dmi_check_system(ec_dmi_table)) {
- /*
- * If the board falls into ec_dmi_table, it means
- * that ECDT table gives the incorrect command/status
- * & data I/O address. Just fix it.
- */
- boot_ec->data_addr = ecdt_ptr->control.address;
- boot_ec->command_addr = ecdt_ptr->data.address;
- }
boot_ec->gpe = ecdt_ptr->gpe;
boot_ec->handle = ACPI_ROOT_OBJECT;
acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
- /* Add some basic check against completely broken table */
- if (boot_ec->data_addr != boot_ec->command_addr)
+ /* Don't trust ECDT, which comes from ASUSTek */
+ if (!dmi_name_in_vendors("ASUS"))
goto install;
+ saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+ if (!saved_ec)
+ return -ENOMEM;
+ memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
/* fall through */
}
/* This workaround is needed only on some broken machines,
@@ -1023,12 +1002,29 @@ int __init acpi_ec_ecdt_probe(void)
/* Check that acpi_get_devices actually find something */
if (ACPI_FAILURE(status) || !boot_ec->handle)
goto error;
- /* We really need to limit this workaround, the only ASUS,
- * which needs it, has fake EC._INI method, so use it as flag.
- * Keep boot_ec struct as it will be needed soon.
- */
- if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy)))
- return -ENODEV;
+ if (saved_ec) {
+ /* try to find good ECDT from ASUSTek */
+ if (saved_ec->command_addr != boot_ec->command_addr ||
+ saved_ec->data_addr != boot_ec->data_addr ||
+ saved_ec->gpe != boot_ec->gpe ||
+ saved_ec->handle != boot_ec->handle)
+ pr_info(PREFIX "ASUSTek keeps feeding us with broken "
+ "ECDT tables, which are very hard to workaround. "
+ "Trying to use DSDT EC info instead. Please send "
+ "output of acpidump to linux-acpi@vger.kernel.org\n");
+ kfree(saved_ec);
+ saved_ec = NULL;
+ } else {
+ /* We really need to limit this workaround, the only ASUS,
+ * which needs it, has fake EC._INI method, so use it as flag.
+ * Keep boot_ec struct as it will be needed soon.
+ */
+ acpi_handle dummy;
+ if (!dmi_name_in_vendors("ASUS") ||
+ ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI",
+ &dummy)))
+ return -ENODEV;
+ }
install:
if (!ec_install_handlers(boot_ec)) {
first_ec = boot_ec;
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 0c24bd4d656..aeb7e5fb4a0 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -235,11 +235,7 @@ int acpi_bus_generate_netlink_event(const char *device_class,
return result;
}
- result =
- genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
- if (result)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Failed to send a Genetlink message!\n"));
+ genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
return 0;
}
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index adec3d15810..5479b9f4251 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -255,12 +255,12 @@ static int acpi_platform_notify(struct device *dev)
}
type = acpi_get_bus_type(dev->bus);
if (!type) {
- DBG("No ACPI bus support for %s\n", dev->bus_id);
+ DBG("No ACPI bus support for %s\n", dev_name(dev));
ret = -EINVAL;
goto end;
}
if ((ret = type->find_device(dev, &handle)) != 0)
- DBG("Can't get handler for %s\n", dev->bus_id);
+ DBG("Can't get handler for %s\n", dev_name(dev));
end:
if (!ret)
acpi_bind_one(dev, handle);
@@ -271,10 +271,10 @@ static int acpi_platform_notify(struct device *dev)
acpi_get_name(dev->archdata.acpi_handle,
ACPI_FULL_PATHNAME, &buffer);
- DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
+ DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
kfree(buffer.pointer);
} else
- DBG("Device %s -> No ACPI support\n", dev->bus_id);
+ DBG("Device %s -> No ACPI support\n", dev_name(dev));
#endif
return ret;
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index c5e292aab0e..3a0d8ef25c7 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -277,7 +277,7 @@ int acpi_get_node(acpi_handle *handle)
int pxm, node = -1;
pxm = acpi_get_pxm(handle);
- if (pxm >= 0)
+ if (pxm >= 0 && pxm < MAX_PXM_DOMAINS)
node = acpi_map_pxm_to_node(pxm);
return node;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 6729a4992f2..1e35f342957 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -228,10 +228,10 @@ void acpi_os_vprintf(const char *fmt, va_list args)
if (acpi_in_debugger) {
kdb_printf("%s", buffer);
} else {
- printk("%s", buffer);
+ printk(KERN_CONT "%s", buffer);
}
#else
- printk("%s", buffer);
+ printk(KERN_CONT "%s", buffer);
#endif
}
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 1c6e73c7865..6c772ca76bd 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -593,7 +593,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
return -ENODEV;
} else {
acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
- printk(PREFIX "%s [%s] enabled at IRQ %d\n",
+ printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
acpi_device_name(link->device),
acpi_device_bid(link->device), link->irq.active);
}
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 66a9d814556..7bc22a471fe 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -66,43 +66,17 @@ ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
-#ifndef CONFIG_CPU_IDLE
-#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
-#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
-static void (*pm_idle_save) (void) __read_mostly;
-#else
#define C2_OVERHEAD 1 /* 1us */
#define C3_OVERHEAD 1 /* 1us */
-#endif
#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
-#ifdef CONFIG_CPU_IDLE
module_param(max_cstate, uint, 0000);
-#else
-module_param(max_cstate, uint, 0644);
-#endif
static unsigned int nocst __read_mostly;
module_param(nocst, uint, 0000);
-#ifndef CONFIG_CPU_IDLE
-/*
- * bm_history -- bit-mask with a bit per jiffy of bus-master activity
- * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
- * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms
- * 100 HZ: 0x0000000F: 4 jiffies = 40ms
- * reduce history for more aggressive entry into C3
- */
-static unsigned int bm_history __read_mostly =
- (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
-module_param(bm_history, uint, 0644);
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr);
-
-#else /* CONFIG_CPU_IDLE */
static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644);
-#endif
/*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -224,71 +198,6 @@ static void acpi_safe_halt(void)
current_thread_info()->status |= TS_POLLING;
}
-#ifndef CONFIG_CPU_IDLE
-
-static void
-acpi_processor_power_activate(struct acpi_processor *pr,
- struct acpi_processor_cx *new)
-{
- struct acpi_processor_cx *old;
-
- if (!pr || !new)
- return;
-
- old = pr->power.state;
-
- if (old)
- old->promotion.count = 0;
- new->demotion.count = 0;
-
- /* Cleanup from old state. */
- if (old) {
- switch (old->type) {
- case ACPI_STATE_C3:
- /* Disable bus master reload */
- if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- break;
- }
- }
-
- /* Prepare to use new state. */
- switch (new->type) {
- case ACPI_STATE_C3:
- /* Enable bus master reload */
- if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
- break;
- }
-
- pr->power.state = new;
-
- return;
-}
-
-static atomic_t c3_cpu_count;
-
-/* Common C-state entry for C2, C3, .. */
-static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
-{
- /* Don't trace irqs off for idle */
- stop_critical_timings();
- if (cstate->entry_method == ACPI_CSTATE_FFH) {
- /* Call into architectural FFH based C-state */
- acpi_processor_ffh_cstate_enter(cstate);
- } else {
- int unused;
- /* IO port based C-state */
- inb(cstate->address);
- /* Dummy wait op - must do something useless after P_LVL2 read
- because chipsets cannot guarantee that STPCLK# signal
- gets asserted in time to freeze execution properly. */
- unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
- }
- start_critical_timings();
-}
-#endif /* !CONFIG_CPU_IDLE */
-
#ifdef ARCH_APICTIMER_STOPS_ON_C3
/*
@@ -390,421 +299,6 @@ static int tsc_halts_in_c(int state)
}
#endif
-#ifndef CONFIG_CPU_IDLE
-static void acpi_processor_idle(void)
-{
- struct acpi_processor *pr = NULL;
- struct acpi_processor_cx *cx = NULL;
- struct acpi_processor_cx *next_state = NULL;
- int sleep_ticks = 0;
- u32 t1, t2 = 0;
-
- /*
- * Interrupts must be disabled during bus mastering calculations and
- * for C2/C3 transitions.
- */
- local_irq_disable();
-
- pr = __get_cpu_var(processors);
- if (!pr) {
- local_irq_enable();
- return;
- }
-
- /*
- * Check whether we truly need to go idle, or should
- * reschedule:
- */
- if (unlikely(need_resched())) {
- local_irq_enable();
- return;
- }
-
- cx = pr->power.state;
- if (!cx || acpi_idle_suspend) {
- if (pm_idle_save) {
- pm_idle_save(); /* enables IRQs */
- } else {
- acpi_safe_halt();
- local_irq_enable();
- }
-
- return;
- }
-
- /*
- * Check BM Activity
- * -----------------
- * Check for bus mastering activity (if required), record, and check
- * for demotion.
- */
- if (pr->flags.bm_check) {
- u32 bm_status = 0;
- unsigned long diff = jiffies - pr->power.bm_check_timestamp;
-
- if (diff > 31)
- diff = 31;
-
- pr->power.bm_activity <<= diff;
-
- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
- if (bm_status) {
- pr->power.bm_activity |= 0x1;
- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
- }
- /*
- * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
- * the true state of bus mastering activity; forcing us to
- * manually check the BMIDEA bit of each IDE channel.
- */
- else if (errata.piix4.bmisx) {
- if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
- || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
- pr->power.bm_activity |= 0x1;
- }
-
- pr->power.bm_check_timestamp = jiffies;
-
- /*
- * If bus mastering is or was active this jiffy, demote
- * to avoid a faulty transition. Note that the processor
- * won't enter a low-power state during this call (to this
- * function) but should upon the next.
- *
- * TBD: A better policy might be to fallback to the demotion
- * state (use it for this quantum only) istead of
- * demoting -- and rely on duration as our sole demotion
- * qualification. This may, however, introduce DMA
- * issues (e.g. floppy DMA transfer overrun/underrun).
- */
- if ((pr->power.bm_activity & 0x1) &&
- cx->demotion.threshold.bm) {
- local_irq_enable();
- next_state = cx->demotion.state;
- goto end;
- }
- }
-
-#ifdef CONFIG_HOTPLUG_CPU
- /*
- * Check for P_LVL2_UP flag before entering C2 and above on
- * an SMP system. We do it here instead of doing it at _CST/P_LVL
- * detection phase, to work cleanly with logical CPU hotplug.
- */
- if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
- !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
- cx = &pr->power.states[ACPI_STATE_C1];
-#endif
-
- /*
- * Sleep:
- * ------
- * Invoke the current Cx state to put the processor to sleep.
- */
- if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
- if (need_resched()) {
- current_thread_info()->status |= TS_POLLING;
- local_irq_enable();
- return;
- }
- }
-
- switch (cx->type) {
-
- case ACPI_STATE_C1:
- /*
- * Invoke C1.
- * Use the appropriate idle routine, the one that would
- * be used without acpi C-states.
- */
- if (pm_idle_save) {
- pm_idle_save(); /* enables IRQs */
- } else {
- acpi_safe_halt();
- local_irq_enable();
- }
-
- /*
- * TBD: Can't get time duration while in C1, as resumes
- * go to an ISR rather than here. Need to instrument
- * base interrupt handler.
- *
- * Note: the TSC better not stop in C1, sched_clock() will
- * skew otherwise.
- */
- sleep_ticks = 0xFFFFFFFF;
-
- break;
-
- case ACPI_STATE_C2:
- /* Get start time (ticks) */
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- /* Tell the scheduler that we are going deep-idle: */
- sched_clock_idle_sleep_event();
- /* Invoke C2 */
- acpi_state_timer_broadcast(pr, cx, 1);
- acpi_cstate_enter(cx);
- /* Get end time (ticks) */
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
- /* TSC halts in C2, so notify users */
- if (tsc_halts_in_c(ACPI_STATE_C2))
- mark_tsc_unstable("possible TSC halt in C2");
-#endif
- /* Compute time (ticks) that we were actually asleep */
- sleep_ticks = ticks_elapsed(t1, t2);
-
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
- /* Re-enable interrupts */
- local_irq_enable();
- /* Do not account our idle-switching overhead: */
- sleep_ticks -= cx->latency_ticks + C2_OVERHEAD;
-
- current_thread_info()->status |= TS_POLLING;
- acpi_state_timer_broadcast(pr, cx, 0);
- break;
-
- case ACPI_STATE_C3:
- acpi_unlazy_tlb(smp_processor_id());
- /*
- * Must be done before busmaster disable as we might
- * need to access HPET !
- */
- acpi_state_timer_broadcast(pr, cx, 1);
- /*
- * disable bus master
- * bm_check implies we need ARB_DIS
- * !bm_check implies we need cache flush
- * bm_control implies whether we can do ARB_DIS
- *
- * That leaves a case where bm_check is set and bm_control is
- * not set. In that case we cannot do much, we enter C3
- * without doing anything.
- */
- if (pr->flags.bm_check && pr->flags.bm_control) {
- if (atomic_inc_return(&c3_cpu_count) ==
- num_online_cpus()) {
- /*
- * All CPUs are trying to go to C3
- * Disable bus master arbitration
- */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
- }
- } else if (!pr->flags.bm_check) {
- /* SMP with no shared cache... Invalidate cache */
- ACPI_FLUSH_CPU_CACHE();
- }
-
- /* Get start time (ticks) */
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- /* Invoke C3 */
- /* Tell the scheduler that we are going deep-idle: */
- sched_clock_idle_sleep_event();
- acpi_cstate_enter(cx);
- /* Get end time (ticks) */
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- if (pr->flags.bm_check && pr->flags.bm_control) {
- /* Enable bus master arbitration */
- atomic_dec(&c3_cpu_count);
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
- }
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
- /* TSC halts in C3, so notify users */
- if (tsc_halts_in_c(ACPI_STATE_C3))
- mark_tsc_unstable("TSC halts in C3");
-#endif
- /* Compute time (ticks) that we were actually asleep */
- sleep_ticks = ticks_elapsed(t1, t2);
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
- /* Re-enable interrupts */
- local_irq_enable();
- /* Do not account our idle-switching overhead: */
- sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
-
- current_thread_info()->status |= TS_POLLING;
- acpi_state_timer_broadcast(pr, cx, 0);
- break;
-
- default:
- local_irq_enable();
- return;
- }
- cx->usage++;
- if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0))
- cx->time += sleep_ticks;
-
- next_state = pr->power.state;
-
-#ifdef CONFIG_HOTPLUG_CPU
- /* Don't do promotion/demotion */
- if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) &&
- !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) {
- next_state = cx;
- goto end;
- }
-#endif
-
- /*
- * Promotion?
- * ----------
- * Track the number of longs (time asleep is greater than threshold)
- * and promote when the count threshold is reached. Note that bus
- * mastering activity may prevent promotions.
- * Do not promote above max_cstate.
- */
- if (cx->promotion.state &&
- ((cx->promotion.state - pr->power.states) <= max_cstate)) {
- if (sleep_ticks > cx->promotion.threshold.ticks &&
- cx->promotion.state->latency <=
- pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
- cx->promotion.count++;
- cx->demotion.count = 0;
- if (cx->promotion.count >=
- cx->promotion.threshold.count) {
- if (pr->flags.bm_check) {
- if (!
- (pr->power.bm_activity & cx->
- promotion.threshold.bm)) {
- next_state =
- cx->promotion.state;
- goto end;
- }
- } else {
- next_state = cx->promotion.state;
- goto end;
- }
- }
- }
- }
-
- /*
- * Demotion?
- * ---------
- * Track the number of shorts (time asleep is less than time threshold)
- * and demote when the usage threshold is reached.
- */
- if (cx->demotion.state) {
- if (sleep_ticks < cx->demotion.threshold.ticks) {
- cx->demotion.count++;
- cx->promotion.count = 0;
- if (cx->demotion.count >= cx->demotion.threshold.count) {
- next_state = cx->demotion.state;
- goto end;
- }
- }
- }
-
- end:
- /*
- * Demote if current state exceeds max_cstate
- * or if the latency of the current state is unacceptable
- */
- if ((pr->power.state - pr->power.states) > max_cstate ||
- pr->power.state->latency >
- pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
- if (cx->demotion.state)
- next_state = cx->demotion.state;
- }
-
- /*
- * New Cx State?
- * -------------
- * If we're going to start using a new Cx state we must clean up
- * from the previous and prepare to use the new.
- */
- if (next_state != pr->power.state)
- acpi_processor_power_activate(pr, next_state);
-}
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr)
-{
- unsigned int i;
- unsigned int state_is_set = 0;
- struct acpi_processor_cx *lower = NULL;
- struct acpi_processor_cx *higher = NULL;
- struct acpi_processor_cx *cx;
-
-
- if (!pr)
- return -EINVAL;
-
- /*
- * This function sets the default Cx state policy (OS idle handler).
- * Our scheme is to promote quickly to C2 but more conservatively
- * to C3. We're favoring C2 for its characteristics of low latency
- * (quick response), good power savings, and ability to allow bus
- * mastering activity. Note that the Cx state policy is completely
- * customizable and can be altered dynamically.
- */
-
- /* startup state */
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (!state_is_set)
- pr->power.state = cx;
- state_is_set++;
- break;
- }
-
- if (!state_is_set)
- return -ENODEV;
-
- /* demotion */
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (lower) {
- cx->demotion.state = lower;
- cx->demotion.threshold.ticks = cx->latency_ticks;
- cx->demotion.threshold.count = 1;
- if (cx->type == ACPI_STATE_C3)
- cx->demotion.threshold.bm = bm_history;
- }
-
- lower = cx;
- }
-
- /* promotion */
- for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (higher) {
- cx->promotion.state = higher;
- cx->promotion.threshold.ticks = cx->latency_ticks;
- if (cx->type >= ACPI_STATE_C2)
- cx->promotion.threshold.count = 4;
- else
- cx->promotion.threshold.count = 10;
- if (higher->type == ACPI_STATE_C3)
- cx->promotion.threshold.bm = bm_history;
- }
-
- higher = cx;
- }
-
- return 0;
-}
-#endif /* !CONFIG_CPU_IDLE */
-
static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
{
@@ -1047,11 +541,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
*/
cx->valid = 1;
-#ifndef CONFIG_CPU_IDLE
- cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
cx->latency_ticks = cx->latency;
-#endif
return;
}
@@ -1121,7 +611,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
" for C3 to be enabled on SMP systems\n"));
return;
}
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
}
/*
@@ -1132,11 +621,16 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
*/
cx->valid = 1;
-#ifndef CONFIG_CPU_IDLE
- cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
cx->latency_ticks = cx->latency;
-#endif
+ /*
+ * On older chipsets, BM_RLD needs to be set
+ * in order for Bus Master activity to wake the
+ * system from C3. Newer chipsets handle DMA
+ * during C3 automatically and BM_RLD is a NOP.
+ * In either case, the proper way to
+ * handle BM_RLD is to set it and leave it set.
+ */
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
return;
}
@@ -1201,20 +695,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
pr->power.count = acpi_processor_power_verify(pr);
-#ifndef CONFIG_CPU_IDLE
- /*
- * Set Default Policy
- * ------------------
- * Now that we know which states are supported, set the default
- * policy. Note that this policy can be changed dynamically
- * (e.g. encourage deeper sleeps to conserve battery life when
- * not on AC).
- */
- result = acpi_processor_set_power_policy(pr);
- if (result)
- return result;
-#endif
-
/*
* if one state of type C2 or C3 is available, mark this
* CPU as being "idle manageable"
@@ -1312,69 +792,6 @@ static const struct file_operations acpi_processor_power_fops = {
.release = single_release,
};
-#ifndef CONFIG_CPU_IDLE
-
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
- int result = 0;
-
- if (boot_option_idle_override)
- return 0;
-
- if (!pr)
- return -EINVAL;
-
- if (nocst) {
- return -ENODEV;
- }
-
- if (!pr->flags.power_setup_done)
- return -ENODEV;
-
- /*
- * Fall back to the default idle loop, when pm_idle_save had
- * been initialized.
- */
- if (pm_idle_save) {
- pm_idle = pm_idle_save;
- /* Relies on interrupts forcing exit from idle. */
- synchronize_sched();
- }
-
- pr->flags.power = 0;
- result = acpi_processor_get_power_info(pr);
- if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
- pm_idle = acpi_processor_idle;
-
- return result;
-}
-
-#ifdef CONFIG_SMP
-static void smp_callback(void *v)
-{
- /* we already woke the CPU up, nothing more to do */
-}
-
-/*
- * This function gets called when a part of the kernel has a new latency
- * requirement. This means we need to get all processors out of their C-state,
- * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
- * wakes them all right up.
- */
-static int acpi_processor_latency_notify(struct notifier_block *b,
- unsigned long l, void *v)
-{
- smp_call_function(smp_callback, NULL, 1);
- return NOTIFY_OK;
-}
-
-static struct notifier_block acpi_processor_latency_notifier = {
- .notifier_call = acpi_processor_latency_notify,
-};
-
-#endif
-
-#else /* CONFIG_CPU_IDLE */
/**
* acpi_idle_bm_check - checks if bus master activity was detected
@@ -1383,7 +800,7 @@ static int acpi_idle_bm_check(void)
{
u32 bm_status = 0;
- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+ acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
if (bm_status)
acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
/*
@@ -1400,25 +817,6 @@ static int acpi_idle_bm_check(void)
}
/**
- * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
- * @pr: the processor
- * @target: the new target state
- */
-static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
- struct acpi_processor_cx *target)
-{
- if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- pr->flags.bm_rld_set = 0;
- }
-
- if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
- pr->flags.bm_rld_set = 1;
- }
-}
-
-/**
* acpi_idle_do_entry - a helper function that does C2 and C3 type entry
* @cx: cstate data
*
@@ -1473,9 +871,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
return 0;
}
- if (pr->flags.bm_check)
- acpi_idle_update_bm_rld(pr, cx);
-
t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
acpi_idle_do_entry(cx);
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -1527,9 +922,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
*/
acpi_state_timer_broadcast(pr, cx, 1);
- if (pr->flags.bm_check)
- acpi_idle_update_bm_rld(pr, cx);
-
if (cx->type == ACPI_STATE_C3)
ACPI_FLUSH_CPU_CACHE();
@@ -1621,8 +1013,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
*/
acpi_state_timer_broadcast(pr, cx, 1);
- acpi_idle_update_bm_rld(pr, cx);
-
/*
* disable bus master
* bm_check implies we need ARB_DIS
@@ -1795,8 +1185,6 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
return ret;
}
-#endif /* CONFIG_CPU_IDLE */
-
int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
struct acpi_device *device)
{
@@ -1825,10 +1213,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
"ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
-#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP)
- pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
- &acpi_processor_latency_notifier);
-#endif
}
if (!pr)
@@ -1852,11 +1236,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
* platforms that only support C1.
*/
if (pr->flags.power) {
-#ifdef CONFIG_CPU_IDLE
acpi_processor_setup_cpuidle(pr);
if (cpuidle_register_device(&pr->power.dev))
return -EIO;
-#endif
printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
for (i = 1; i <= pr->power.count; i++)
@@ -1864,13 +1246,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
printk(" C%d[C%d]", i,
pr->power.states[i].type);
printk(")\n");
-
-#ifndef CONFIG_CPU_IDLE
- if (pr->id == 0) {
- pm_idle_save = pm_idle;
- pm_idle = acpi_processor_idle;
- }
-#endif
}
/* 'power' [R] */
@@ -1889,34 +1264,12 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
if (boot_option_idle_override)
return 0;
-#ifdef CONFIG_CPU_IDLE
cpuidle_unregister_device(&pr->power.dev);
-#endif
pr->flags.power_setup_done = 0;
if (acpi_device_dir(device))
remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
acpi_device_dir(device));
-#ifndef CONFIG_CPU_IDLE
-
- /* Unregister the idle handler when processor #0 is removed. */
- if (pr->id == 0) {
- if (pm_idle_save)
- pm_idle = pm_idle_save;
-
- /*
- * We are about to unload the current idle thread pm callback
- * (pm_idle), Wait for all processors to update cached/local
- * copies of pm_idle before proceeding.
- */
- cpu_idle_wait();
-#ifdef CONFIG_SMP
- pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
- &acpi_processor_latency_notifier);
-#endif
- }
-#endif
-
return 0;
}
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 846e227592d..9cc769b587f 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -31,14 +31,6 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#endif
-
#ifdef CONFIG_X86
#include <asm/cpufeature.h>
#endif
@@ -434,96 +426,6 @@ int acpi_processor_notify_smm(struct module *calling_module)
EXPORT_SYMBOL(acpi_processor_notify_smm);
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-/* /proc/acpi/processor/../performance interface (DEPRECATED) */
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
- .owner = THIS_MODULE,
- .open = acpi_processor_perf_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
-{
- struct acpi_processor *pr = seq->private;
- int i;
-
-
- if (!pr)
- goto end;
-
- if (!pr->performance) {
- seq_puts(seq, "<not supported>\n");
- goto end;
- }
-
- seq_printf(seq, "state count: %d\n"
- "active state: P%d\n",
- pr->performance->state_count, pr->performance->state);
-
- seq_puts(seq, "states:\n");
- for (i = 0; i < pr->performance->state_count; i++)
- seq_printf(seq,
- " %cP%d: %d MHz, %d mW, %d uS\n",
- (i == pr->performance->state ? '*' : ' '), i,
- (u32) pr->performance->states[i].core_frequency,
- (u32) pr->performance->states[i].power,
- (u32) pr->performance->states[i].transition_latency);
-
- end:
- return 0;
-}
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_processor_perf_seq_show,
- PDE(inode)->data);
-}
-
-static void acpi_cpufreq_add_file(struct acpi_processor *pr)
-{
- struct acpi_device *device = NULL;
-
-
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
- /* add file 'performance' [R/W] */
- proc_create_data(ACPI_PROCESSOR_FILE_PERFORMANCE, S_IFREG | S_IRUGO,
- acpi_device_dir(device),
- &acpi_processor_perf_fops, acpi_driver_data(device));
- return;
-}
-
-static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
-{
- struct acpi_device *device = NULL;
-
-
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
- /* remove file 'performance' */
- remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
- acpi_device_dir(device));
-
- return;
-}
-
-#else
-static void acpi_cpufreq_add_file(struct acpi_processor *pr)
-{
- return;
-}
-static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
-{
- return;
-}
-#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
-
static int acpi_processor_get_psd(struct acpi_processor *pr)
{
int result = 0;
@@ -747,14 +649,12 @@ err_ret:
}
EXPORT_SYMBOL(acpi_processor_preregister_performance);
-
int
acpi_processor_register_performance(struct acpi_processor_performance
*performance, unsigned int cpu)
{
struct acpi_processor *pr;
-
if (!(acpi_processor_ppc_status & PPC_REGISTERED))
return -EINVAL;
@@ -781,8 +681,6 @@ acpi_processor_register_performance(struct acpi_processor_performance
return -EIO;
}
- acpi_cpufreq_add_file(pr);
-
mutex_unlock(&performance_mutex);
return 0;
}
@@ -795,7 +693,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
{
struct acpi_processor *pr;
-
mutex_lock(&performance_mutex);
pr = per_cpu(processors, cpu);
@@ -808,8 +705,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
kfree(pr->performance->states);
pr->performance = NULL;
- acpi_cpufreq_remove_file(pr);
-
mutex_unlock(&performance_mutex);
return;
diff --git a/drivers/acpi/main.c b/drivers/acpi/sleep.c
index 7e3c609cbef..00456fccfa3 100644
--- a/drivers/acpi/main.c
+++ b/drivers/acpi/sleep.c
@@ -90,31 +90,6 @@ void __init acpi_old_suspend_ordering(void)
old_suspend_ordering = true;
}
-/*
- * According to the ACPI specification the BIOS should make sure that ACPI is
- * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
- * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
- * on such systems during resume. Unfortunately that doesn't help in
- * particularly pathological cases in which SCI_EN has to be set directly on
- * resume, although the specification states very clearly that this flag is
- * owned by the hardware. The set_sci_en_on_resume variable will be set in such
- * cases.
- */
-static bool set_sci_en_on_resume;
-/*
- * The ACPI specification wants us to save NVS memory regions during hibernation
- * and to restore them during the subsequent resume. However, it is not certain
- * if this mechanism is going to work on all machines, so we allow the user to
- * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
- * option.
- */
-static bool s4_no_nvs;
-
-void __init acpi_s4_no_nvs(void)
-{
- s4_no_nvs = true;
-}
-
/**
* acpi_pm_disable_gpes - Disable the GPEs.
*/
@@ -193,6 +168,18 @@ static void acpi_pm_end(void)
#endif /* CONFIG_ACPI_SLEEP */
#ifdef CONFIG_SUSPEND
+/*
+ * According to the ACPI specification the BIOS should make sure that ACPI is
+ * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
+ * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
+ * on such systems during resume. Unfortunately that doesn't help in
+ * particularly pathological cases in which SCI_EN has to be set directly on
+ * resume, although the specification states very clearly that this flag is
+ * owned by the hardware. The set_sci_en_on_resume variable will be set in such
+ * cases.
+ */
+static bool set_sci_en_on_resume;
+
extern void do_suspend_lowlevel(void);
static u32 acpi_suspend_states[] = {
@@ -391,11 +378,41 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
},
},
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "M2N8L"),
+ },
+ },
+ {
+ .callback = init_set_sci_en_on_resume,
+ .ident = "Toshiba Satellite L300",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"),
+ },
+ },
{},
};
#endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION
+/*
+ * The ACPI specification wants us to save NVS memory regions during hibernation
+ * and to restore them during the subsequent resume. However, it is not certain
+ * if this mechanism is going to work on all machines, so we allow the user to
+ * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
+ * option.
+ */
+static bool s4_no_nvs;
+
+void __init acpi_s4_no_nvs(void)
+{
+ s4_no_nvs = true;
+}
+
static unsigned long s4_hardware_signature;
static struct acpi_table_facs *facs;
static bool nosigcheck;
@@ -679,7 +696,7 @@ static void acpi_power_off_prepare(void)
static void acpi_power_off(void)
{
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
- printk("%s called\n", __func__);
+ printk(KERN_DEBUG "%s called\n", __func__);
local_irq_disable();
acpi_enable_wakeup_device(ACPI_STATE_S5);
acpi_enter_sleep_state(ACPI_STATE_S5);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 775c97a282b..a8852952fac 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -293,7 +293,12 @@ static void __init check_multiple_madt(void)
int __init acpi_table_init(void)
{
- acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+ acpi_status status;
+
+ status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+ if (ACPI_FAILURE(status))
+ return 1;
+
check_multiple_madt();
return 0;
}
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 073ff09218a..99e6f1f8ea4 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -416,7 +416,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
}
/* Passive (optional) */
- if (flag & ACPI_TRIPS_PASSIVE) {
+ if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) ||
+ (flag == ACPI_TRIPS_INIT)) {
valid = tz->trips.passive.flags.valid;
if (psv == -1) {
status = AE_SUPPORT;
@@ -462,8 +463,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
memset(&devices, 0, sizeof(struct acpi_handle_list));
status = acpi_evaluate_reference(tz->device->handle, "_PSL",
NULL, &devices);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_WARNING PREFIX
+ "Invalid passive threshold\n");
tz->trips.passive.flags.valid = 0;
+ }
else
tz->trips.passive.flags.valid = 1;
@@ -487,7 +491,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
if (act == -1)
break; /* disable all active trip points */
- if (flag & ACPI_TRIPS_ACTIVE) {
+ if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) &&
+ tz->trips.active[i].flags.valid)) {
status = acpi_evaluate_integer(tz->device->handle,
name, NULL, &tmp);
if (ACPI_FAILURE(status)) {
@@ -521,8 +526,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
memset(&devices, 0, sizeof(struct acpi_handle_list));
status = acpi_evaluate_reference(tz->device->handle,
name, NULL, &devices);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_WARNING PREFIX
+ "Invalid active%d threshold\n", i);
tz->trips.active[i].flags.valid = 0;
+ }
else
tz->trips.active[i].flags.valid = 1;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index f261737636d..bb5ed059114 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1020,7 +1020,7 @@ acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
}
seq_printf(seq, "levels: ");
- for (i = 0; i < dev->brightness->count; i++)
+ for (i = 2; i < dev->brightness->count; i++)
seq_printf(seq, " %d", dev->brightness->levels[i]);
seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
@@ -1059,7 +1059,7 @@ acpi_video_device_write_brightness(struct file *file,
return -EFAULT;
/* validate through the list of available levels */
- for (i = 0; i < dev->brightness->count; i++)
+ for (i = 2; i < dev->brightness->count; i++)
if (level == dev->brightness->levels[i]) {
if (ACPI_SUCCESS
(acpi_video_device_lcd_set_level(dev, level)))
@@ -1260,7 +1260,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
printk(KERN_WARNING PREFIX
"This indicates a BIOS bug. Please contact the manufacturer.\n");
}
- printk("%llx\n", options);
+ printk(KERN_WARNING "%llx\n", options);
seq_printf(seq, "can POST: <integrated video>");
if (options & 2)
seq_printf(seq, " <PCI video>");
@@ -1712,7 +1712,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
max = max_below = 0;
min = min_above = 255;
/* Find closest level to level_current */
- for (i = 0; i < device->brightness->count; i++) {
+ for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (abs(l - level_current) < abs(delta)) {
delta = l - level_current;
@@ -1722,7 +1722,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
}
/* Ajust level_current to closest available level */
level_current += delta;
- for (i = 0; i < device->brightness->count; i++) {
+ for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (l < min)
min = l;
@@ -2006,6 +2006,12 @@ static int acpi_video_bus_add(struct acpi_device *device)
device->pnp.bus_id[3] = '0' + instance;
instance ++;
}
+ /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */
+ if (!strcmp(device->pnp.bus_id, "VGA")) {
+ if (instance)
+ device->pnp.bus_id[3] = '0' + instance;
+ instance++;
+ }
video->device = device;
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 00c46e0b40e..3d763fdf99b 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -210,7 +210,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
dev->dev.release = amba_device_release;
dev->dev.bus = &amba_bustype;
dev->dev.dma_mask = &dev->dma_mask;
- dev->res.name = dev->dev.bus_id;
+ dev->res.name = dev_name(&dev->dev);
if (!dev->dev.coherent_dma_mask && dev->dma_mask)
dev_warn(&dev->dev, "coherent dma mask is unset\n");
@@ -294,7 +294,7 @@ static int amba_find_match(struct device *dev, void *data)
if (d->parent)
r &= d->parent == dev->parent;
if (d->busid)
- r &= strcmp(dev->bus_id, d->busid) == 0;
+ r &= strcmp(dev_name(dev), d->busid) == 0;
if (r) {
get_device(dev);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 1a7be96d627..0bcf2646467 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -112,11 +112,11 @@ config ATA_PIIX
If unsure, say N.
config SATA_MV
- tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ tristate "Marvell SATA support"
help
This option enables support for the Marvell Serial ATA family.
- Currently supports 88SX[56]0[48][01] chips.
+ Currently supports 88SX[56]0[48][01] PCI(-X) chips,
+ as well as the newer [67]042 PCI-X/PCIe and SOC devices.
If unsure, say N.
@@ -698,6 +698,15 @@ config PATA_IXP4XX_CF
If unsure, say N.
+config PATA_OCTEON_CF
+ tristate "OCTEON Boot Bus Compact Flash support"
+ depends on CPU_CAVIUM_OCTEON
+ help
+ This option enables a polled compact flash driver for use with
+ compact flash cards attached to the OCTEON boot bus.
+
+ If unsure, say N.
+
config PATA_SCC
tristate "Toshiba's Cell Reference Set IDE support"
depends on PCI && PPC_CELLEB
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 674965fa326..7f1ecf99528 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
obj-$(CONFIG_PATA_SCC) += pata_scc.o
obj-$(CONFIG_PATA_SCH) += pata_sch.o
obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o
+obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o
obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 96039671e3b..788bba2b1e1 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -61,9 +61,14 @@
#define EM_MSG_LED_VALUE_ON 0x00010000
static int ahci_skip_host_reset;
+static int ahci_ignore_sss;
+
module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444);
MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)");
+module_param_named(ignore_sss, ahci_ignore_sss, int, 0444);
+MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)");
+
static int ahci_enable_alpm(struct ata_port *ap,
enum link_pm policy);
static void ahci_disable_alpm(struct ata_port *ap);
@@ -399,7 +404,7 @@ static const struct ata_port_info ahci_port_info[] = {
/* board_ahci */
{
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -407,7 +412,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_vt8251_ops,
},
@@ -415,7 +420,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -425,7 +430,7 @@ static const struct ata_port_info ahci_port_info[] = {
AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
AHCI_HFLAG_SECT255),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_sb600_ops,
},
@@ -435,7 +440,7 @@ static const struct ata_port_info ahci_port_info[] = {
AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -443,7 +448,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_sb600_ops,
},
@@ -451,7 +456,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -459,7 +464,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -577,18 +582,18 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci }, /* MCP79 */
{ PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci }, /* MCP79 */
{ PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci }, /* MCP79 */
- { PCI_VDEVICE(NVIDIA, 0x0bc8), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bc9), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bca), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bcb), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bcc), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bcd), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bce), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bcf), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bc4), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bc5), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bc6), board_ahci }, /* MCP7B */
- { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */
+ { PCI_VDEVICE(NVIDIA, 0x0d84), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d85), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d86), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d87), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d88), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d89), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d8a), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d8b), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d8c), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d8d), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d8e), board_ahci }, /* MCP89 */
+ { PCI_VDEVICE(NVIDIA, 0x0d8f), board_ahci }, /* MCP89 */
/* SiS */
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
@@ -1343,7 +1348,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
writel(message[1], mmio + hpriv->em_loc+4);
/* save off new led state for port/slot */
- emp->led_state = message[1];
+ emp->led_state = state;
/*
* tell hardware to transmit the message
@@ -2548,6 +2553,41 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
}
}
+static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
+{
+ static const struct dmi_system_id broken_systems[] = {
+ {
+ .ident = "HP Compaq nx6310",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6310"),
+ },
+ /* PCI slot number of the controller */
+ .driver_data = (void *)0x1FUL,
+ },
+ {
+ .ident = "HP Compaq 6720s",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6720s"),
+ },
+ /* PCI slot number of the controller */
+ .driver_data = (void *)0x1FUL,
+ },
+
+ { } /* terminate list */
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
+
+ if (dmi) {
+ unsigned long slot = (unsigned long)dmi->driver_data;
+ /* apply the quirk only to on-board controllers */
+ return slot == PCI_SLOT(pdev->devfn);
+ }
+
+ return false;
+}
+
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
@@ -2616,8 +2656,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
- if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
- pci_intx(pdev, 1);
+ if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
+ pci_enable_msi(pdev);
/* save initial config */
ahci_save_initial_config(pdev, hpriv);
@@ -2647,6 +2687,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
+ if (ahci_broken_system_poweroff(pdev)) {
+ pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN;
+ dev_info(&pdev->dev,
+ "quirky BIOS, skipping spindown on poweroff\n");
+ }
+
/* CAP.NP sometimes indicate the index of the last enabled
* port, at other times, that of the last possible port, so
* determining the maximum port number requires looking at
@@ -2660,8 +2706,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
host->iomap = pcim_iomap_table(pdev);
host->private_data = hpriv;
- if (!(hpriv->cap & HOST_CAP_SSS))
+ if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
host->flags |= ATA_HOST_PARALLEL_SCAN;
+ else
+ printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n");
if (pi.flags & ATA_FLAG_EM)
ahci_reset_em(host);
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index dc48a6398ab..ecfd22b4f1c 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -118,8 +118,8 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
u16 command;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &generic_port_ops
};
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 887d8f46a28..e5cbe80ce17 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -446,34 +446,34 @@ static struct ata_port_info piix_port_info[] = {
[piix_pata_mwdma] = /* PIIX3 MWDMA only */
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
.port_ops = &piix_pata_ops,
},
[piix_pata_33] = /* PIIX4 at 33MHz */
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
- .udma_mask = ATA_UDMA_MASK_40C,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+ .udma_mask = ATA_UDMA2,
.port_ops = &piix_pata_ops,
},
[ich_pata_33] = /* ICH0 - ICH at 33Mhz*/
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio 0-4 */
- .mwdma_mask = 0x06, /* Check: maybe 0x07 */
- .udma_mask = ATA_UDMA2, /* UDMA33 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* Check: maybe MWDMA0 is ok */
+ .udma_mask = ATA_UDMA2,
.port_ops = &ich_pata_ops,
},
[ich_pata_66] = /* ICH controllers up to 66MHz */
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio 0-4 */
- .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* MWDMA0 is broken on chip */
.udma_mask = ATA_UDMA4,
.port_ops = &ich_pata_ops,
},
@@ -481,17 +481,17 @@ static struct ata_port_info piix_port_info[] = {
[ich_pata_100] =
{
.flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x06, /* mwdma1-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY,
+ .udma_mask = ATA_UDMA5,
.port_ops = &ich_pata_ops,
},
[ich5_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -499,8 +499,8 @@ static struct ata_port_info piix_port_info[] = {
[ich6_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -508,8 +508,8 @@ static struct ata_port_info piix_port_info[] = {
[ich6m_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -517,8 +517,8 @@ static struct ata_port_info piix_port_info[] = {
[ich8_sata] =
{
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -526,8 +526,8 @@ static struct ata_port_info piix_port_info[] = {
[ich8_2port_sata] =
{
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -535,8 +535,8 @@ static struct ata_port_info piix_port_info[] = {
[tolapai_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -544,8 +544,8 @@ static struct ata_port_info piix_port_info[] = {
[ich8m_apple_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -553,9 +553,9 @@ static struct ata_port_info piix_port_info[] = {
[piix_pata_vmw] =
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
- .udma_mask = ATA_UDMA_MASK_40C,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+ .udma_mask = ATA_UDMA2,
.port_ops = &piix_vmw_ops,
},
@@ -1289,6 +1289,39 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev,
return map;
}
+static bool piix_no_sidpr(struct ata_host *host)
+{
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+
+ /*
+ * Samsung DB-P70 only has three ATA ports exposed and
+ * curiously the unconnected first port reports link online
+ * while not responding to SRST protocol causing excessive
+ * detection delay.
+ *
+ * Unfortunately, the system doesn't carry enough DMI
+ * information to identify the machine but does have subsystem
+ * vendor and device set. As it's unclear whether the
+ * subsystem vendor/device is used only for this specific
+ * board, the port can't be disabled solely with the
+ * information; however, turning off SIDPR access works around
+ * the problem. Turn it off.
+ *
+ * This problem is reported in bnc#441240.
+ *
+ * https://bugzilla.novell.com/show_bug.cgi?id=441420
+ */
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2920 &&
+ pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG &&
+ pdev->subsystem_device == 0xb049) {
+ dev_printk(KERN_WARNING, host->dev,
+ "Samsung DB-P70 detected, disabling SIDPR\n");
+ return true;
+ }
+
+ return false;
+}
+
static int __devinit piix_init_sidpr(struct ata_host *host)
{
struct pci_dev *pdev = to_pci_dev(host->dev);
@@ -1302,6 +1335,10 @@ static int __devinit piix_init_sidpr(struct ata_host *host)
if (hpriv->map[i] == IDE)
return 0;
+ /* is it blacklisted? */
+ if (piix_no_sidpr(host))
+ return 0;
+
if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
return 0;
@@ -1387,6 +1424,32 @@ static void piix_iocfg_bit18_quirk(struct ata_host *host)
}
}
+static bool piix_broken_system_poweroff(struct pci_dev *pdev)
+{
+ static const struct dmi_system_id broken_systems[] = {
+ {
+ .ident = "HP Compaq 2510p",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 2510p"),
+ },
+ /* PCI slot number of the controller */
+ .driver_data = (void *)0x1FUL,
+ },
+
+ { } /* terminate list */
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
+
+ if (dmi) {
+ unsigned long slot = (unsigned long)dmi->driver_data;
+ /* apply the quirk only to on-board controllers */
+ return slot == PCI_SLOT(pdev->devfn);
+ }
+
+ return false;
+}
+
/**
* piix_init_one - Register PIIX ATA PCI device with kernel services
* @pdev: PCI device to register
@@ -1422,6 +1485,14 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
if (!in_module_init)
return -ENODEV;
+ if (piix_broken_system_poweroff(pdev)) {
+ piix_port_info[ent->driver_data].flags |=
+ ATA_FLAG_NO_POWEROFF_SPINDOWN |
+ ATA_FLAG_NO_HIBERNATE_SPINDOWN;
+ dev_info(&pdev->dev, "quirky BIOS, skipping spindown "
+ "on poweroff and hibernation\n");
+ }
+
port_info[0] = piix_port_info[ent->driver_data];
port_info[1] = piix_port_info[ent->driver_data];
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 71218d76d75..e7ea77cf606 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -57,6 +57,7 @@
#include <linux/scatterlist.h>
#include <linux/io.h>
#include <linux/async.h>
+#include <linux/log2.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
@@ -164,6 +165,11 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+static bool ata_sstatus_online(u32 sstatus)
+{
+ return (sstatus & 0xf) == 0x3;
+}
+
/**
* ata_link_next - link iteration helper
* @link: the previous link, NULL to start
@@ -1015,18 +1021,6 @@ static const char *sata_spd_string(unsigned int spd)
return spd_str[spd - 1];
}
-void ata_dev_disable(struct ata_device *dev)
-{
- if (ata_dev_enabled(dev)) {
- if (ata_msg_drv(dev->link->ap))
- ata_dev_printk(dev, KERN_WARNING, "disabled\n");
- ata_acpi_on_disable(dev);
- ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 |
- ATA_DNXFER_QUIET);
- dev->class++;
- }
-}
-
static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
{
struct ata_link *link = dev->link;
@@ -1329,14 +1323,16 @@ static u64 ata_id_n_sectors(const u16 *id)
{
if (ata_id_has_lba(id)) {
if (ata_id_has_lba48(id))
- return ata_id_u64(id, 100);
+ return ata_id_u64(id, ATA_ID_LBA_CAPACITY_2);
else
- return ata_id_u32(id, 60);
+ return ata_id_u32(id, ATA_ID_LBA_CAPACITY);
} else {
if (ata_id_current_chs_valid(id))
- return ata_id_u32(id, 57);
+ return id[ATA_ID_CUR_CYLS] * id[ATA_ID_CUR_HEADS] *
+ id[ATA_ID_CUR_SECTORS];
else
- return id[1] * id[3] * id[6];
+ return id[ATA_ID_CYLS] * id[ATA_ID_HEADS] *
+ id[ATA_ID_SECTORS];
}
}
@@ -2239,6 +2235,40 @@ retry:
return rc;
}
+static int ata_do_link_spd_horkage(struct ata_device *dev)
+{
+ struct ata_link *plink = ata_dev_phys_link(dev);
+ u32 target, target_limit;
+
+ if (!sata_scr_valid(plink))
+ return 0;
+
+ if (dev->horkage & ATA_HORKAGE_1_5_GBPS)
+ target = 1;
+ else
+ return 0;
+
+ target_limit = (1 << target) - 1;
+
+ /* if already on stricter limit, no need to push further */
+ if (plink->sata_spd_limit <= target_limit)
+ return 0;
+
+ plink->sata_spd_limit = target_limit;
+
+ /* Request another EH round by returning -EAGAIN if link is
+ * going faster than the target speed. Forward progress is
+ * guaranteed by setting sata_spd_limit to target_limit above.
+ */
+ if (plink->sata_spd > target) {
+ ata_dev_printk(dev, KERN_INFO,
+ "applying link speed limit horkage to %s\n",
+ sata_spd_string(target));
+ return -EAGAIN;
+ }
+ return 0;
+}
+
static inline u8 ata_dev_knobble(struct ata_device *dev)
{
struct ata_port *ap = dev->link->ap;
@@ -2329,6 +2359,10 @@ int ata_dev_configure(struct ata_device *dev)
return 0;
}
+ rc = ata_do_link_spd_horkage(dev);
+ if (rc)
+ return rc;
+
/* let ACPI work its magic */
rc = ata_acpi_on_devcfg(dev);
if (rc)
@@ -2356,6 +2390,7 @@ int ata_dev_configure(struct ata_device *dev)
dev->cylinders = 0;
dev->heads = 0;
dev->sectors = 0;
+ dev->multi_count = 0;
/*
* common ATA, ATAPI feature tests
@@ -2393,8 +2428,15 @@ int ata_dev_configure(struct ata_device *dev)
dev->n_sectors = ata_id_n_sectors(id);
- if (dev->id[59] & 0x100)
- dev->multi_count = dev->id[59] & 0xff;
+ /* get current R/W Multiple count setting */
+ if ((dev->id[47] >> 8) == 0x80 && (dev->id[59] & 0x100)) {
+ unsigned int max = dev->id[47] & 0xff;
+ unsigned int cnt = dev->id[59] & 0xff;
+ /* only recognize/allow powers of two here */
+ if (is_power_of_2(max) && is_power_of_2(cnt))
+ if (cnt <= max)
+ dev->multi_count = cnt;
+ }
if (ata_id_has_lba(id)) {
const char *lba_desc;
@@ -2784,7 +2826,7 @@ int ata_bus_probe(struct ata_port *ap)
/* This is the last chance, better to slow
* down than lose it.
*/
- sata_down_spd_limit(&ap->link);
+ sata_down_spd_limit(&ap->link, 0);
ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
}
}
@@ -2880,21 +2922,27 @@ void ata_port_disable(struct ata_port *ap)
/**
* sata_down_spd_limit - adjust SATA spd limit downward
* @link: Link to adjust SATA spd limit for
+ * @spd_limit: Additional limit
*
* Adjust SATA spd limit of @link downward. Note that this
* function only adjusts the limit. The change must be applied
* using sata_set_spd().
*
+ * If @spd_limit is non-zero, the speed is limited to equal to or
+ * lower than @spd_limit if such speed is supported. If
+ * @spd_limit is slower than any supported speed, only the lowest
+ * supported speed is allowed.
+ *
* LOCKING:
* Inherited from caller.
*
* RETURNS:
* 0 on success, negative errno on failure
*/
-int sata_down_spd_limit(struct ata_link *link)
+int sata_down_spd_limit(struct ata_link *link, u32 spd_limit)
{
u32 sstatus, spd, mask;
- int rc, highbit;
+ int rc, bit;
if (!sata_scr_valid(link))
return -EOPNOTSUPP;
@@ -2903,7 +2951,7 @@ int sata_down_spd_limit(struct ata_link *link)
* If not, use cached value in link->sata_spd.
*/
rc = sata_scr_read(link, SCR_STATUS, &sstatus);
- if (rc == 0)
+ if (rc == 0 && ata_sstatus_online(sstatus))
spd = (sstatus >> 4) & 0xf;
else
spd = link->sata_spd;
@@ -2913,8 +2961,8 @@ int sata_down_spd_limit(struct ata_link *link)
return -EINVAL;
/* unconditionally mask off the highest bit */
- highbit = fls(mask) - 1;
- mask &= ~(1 << highbit);
+ bit = fls(mask) - 1;
+ mask &= ~(1 << bit);
/* Mask off all speeds higher than or equal to the current
* one. Force 1.5Gbps if current SPD is not available.
@@ -2928,6 +2976,15 @@ int sata_down_spd_limit(struct ata_link *link)
if (!mask)
return -EINVAL;
+ if (spd_limit) {
+ if (mask & ((1 << spd_limit) - 1))
+ mask &= (1 << spd_limit) - 1;
+ else {
+ bit = ffs(mask) - 1;
+ mask = 1 << bit;
+ }
+ }
+
link->sata_spd_limit = mask;
ata_link_printk(link, KERN_WARNING, "limiting SATA link speed to %s\n",
@@ -3029,33 +3086,33 @@ int sata_set_spd(struct ata_link *link)
*/
static const struct ata_timing ata_timing[] = {
-/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
- { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 },
- { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 },
- { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 },
- { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 },
- { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 },
- { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 },
- { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 },
-
- { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 },
- { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 },
- { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 },
-
- { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 },
- { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 },
- { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 },
- { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 },
- { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 },
-
-/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 }, */
- { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 },
- { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 },
- { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 },
- { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 },
- { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 },
- { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
- { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
+/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 0, 960, 0 }, */
+ { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 0, 600, 0 },
+ { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 0, 383, 0 },
+ { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 0, 240, 0 },
+ { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 0, 180, 0 },
+ { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 0, 120, 0 },
+ { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 0, 100, 0 },
+ { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 0, 80, 0 },
+
+ { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 50, 960, 0 },
+ { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 30, 480, 0 },
+ { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 20, 240, 0 },
+
+ { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 20, 480, 0 },
+ { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 5, 150, 0 },
+ { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 5, 120, 0 },
+ { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 5, 100, 0 },
+ { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 5, 80, 0 },
+
+/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 0, 150 }, */
+ { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 0, 120 },
+ { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 0, 80 },
+ { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 0, 60 },
+ { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 0, 45 },
+ { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 0, 30 },
+ { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 },
+ { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 },
{ 0xFF }
};
@@ -3065,14 +3122,15 @@ static const struct ata_timing ata_timing[] = {
static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT)
{
- q->setup = EZ(t->setup * 1000, T);
- q->act8b = EZ(t->act8b * 1000, T);
- q->rec8b = EZ(t->rec8b * 1000, T);
- q->cyc8b = EZ(t->cyc8b * 1000, T);
- q->active = EZ(t->active * 1000, T);
- q->recover = EZ(t->recover * 1000, T);
- q->cycle = EZ(t->cycle * 1000, T);
- q->udma = EZ(t->udma * 1000, UT);
+ q->setup = EZ(t->setup * 1000, T);
+ q->act8b = EZ(t->act8b * 1000, T);
+ q->rec8b = EZ(t->rec8b * 1000, T);
+ q->cyc8b = EZ(t->cyc8b * 1000, T);
+ q->active = EZ(t->active * 1000, T);
+ q->recover = EZ(t->recover * 1000, T);
+ q->dmack_hold = EZ(t->dmack_hold * 1000, T);
+ q->cycle = EZ(t->cycle * 1000, T);
+ q->udma = EZ(t->udma * 1000, UT);
}
void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
@@ -3084,6 +3142,7 @@ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b);
if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active);
if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
+ if (what & ATA_TIMING_DMACK_HOLD) m->dmack_hold = max(a->dmack_hold, b->dmack_hold);
if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle);
if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma);
}
@@ -4213,6 +4272,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
/* Devices that do not need bridging limits applied */
{ "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, },
+ /* Devices which aren't very happy with higher link speeds */
+ { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, },
+
/* End Marker */
{ }
};
@@ -4561,7 +4623,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
VPRINTK("unmapping %u sg elements\n", qc->n_elem);
if (qc->n_elem)
- dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
+ dma_unmap_sg(ap->dev, sg, qc->orig_n_elem, dir);
qc->flags &= ~ATA_QCFLAG_DMAMAP;
qc->sg = NULL;
@@ -4676,7 +4738,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
return -1;
DPRINTK("%d sg elements mapped\n", n_elem);
-
+ qc->orig_n_elem = qc->n_elem;
qc->n_elem = n_elem;
qc->flags |= ATA_QCFLAG_DMAMAP;
@@ -4707,8 +4769,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
/**
* ata_qc_new - Request an available ATA command, for queueing
- * @ap: Port associated with device @dev
- * @dev: Device from whom we request an available command structure
+ * @ap: target port
*
* LOCKING:
* None.
@@ -5173,7 +5234,7 @@ bool ata_phys_link_online(struct ata_link *link)
u32 sstatus;
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
- (sstatus & 0xf) == 0x3)
+ ata_sstatus_online(sstatus))
return true;
return false;
}
@@ -5197,7 +5258,7 @@ bool ata_phys_link_offline(struct ata_link *link)
u32 sstatus;
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
- (sstatus & 0xf) != 0x3)
+ !ata_sstatus_online(sstatus))
return true;
return false;
}
@@ -5410,8 +5471,8 @@ void ata_dev_init(struct ata_device *dev)
dev->horkage = 0;
spin_unlock_irqrestore(ap->lock, flags);
- memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0,
- sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET);
+ memset((void *)dev + ATA_DEVICE_CLEAR_BEGIN, 0,
+ ATA_DEVICE_CLEAR_END - ATA_DEVICE_CLEAR_BEGIN);
dev->pio_mask = UINT_MAX;
dev->mwdma_mask = UINT_MAX;
dev->udma_mask = UINT_MAX;
@@ -6638,7 +6699,6 @@ EXPORT_SYMBOL_GPL(ata_dev_pair);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_wait_register);
-EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
@@ -6658,6 +6718,7 @@ EXPORT_SYMBOL_GPL(ata_id_c_string);
EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+EXPORT_SYMBOL_GPL(ata_pio_queue_task);
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
EXPORT_SYMBOL_GPL(ata_timing_find_mode);
EXPORT_SYMBOL_GPL(ata_timing_compute);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 8147a838637..01831312c36 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -82,6 +82,10 @@ enum {
ATA_EH_FASTDRAIN_INTERVAL = 3000,
ATA_EH_UA_TRIES = 5,
+
+ /* probe speed down parameters, see ata_eh_schedule_probe() */
+ ATA_EH_PROBE_TRIAL_INTERVAL = 60000, /* 1 min */
+ ATA_EH_PROBE_TRIALS = 2,
};
/* The following table determines how we sequence resets. Each entry
@@ -543,7 +547,7 @@ void ata_scsi_error(struct Scsi_Host *host)
/* For new EH, all qcs are finished in one of three ways -
* normal completion, error completion, and SCSI timeout.
- * Both cmpletions can race against SCSI timeout. When normal
+ * Both completions can race against SCSI timeout. When normal
* completion wins, the qc never reaches EH. When error
* completion wins, the qc has ATA_QCFLAG_FAILED set.
*
@@ -558,7 +562,19 @@ void ata_scsi_error(struct Scsi_Host *host)
int nr_timedout = 0;
spin_lock_irqsave(ap->lock, flags);
-
+
+ /* This must occur under the ap->lock as we don't want
+ a polled recovery to race the real interrupt handler
+
+ The lost_interrupt handler checks for any completed but
+ non-notified command and completes much like an IRQ handler.
+
+ We then fall into the error recovery code which will treat
+ this as if normal completion won the race */
+
+ if (ap->ops->lost_interrupt)
+ ap->ops->lost_interrupt(ap);
+
list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
struct ata_queued_cmd *qc;
@@ -602,6 +618,9 @@ void ata_scsi_error(struct Scsi_Host *host)
ap->eh_tries = ATA_EH_MAX_TRIES;
} else
spin_unlock_wait(ap->lock);
+
+ /* If we timed raced normal completion and there is nothing to
+ recover nr_timedout == 0 why exactly are we doing error recovery ? */
repeat:
/* invoke error handler */
@@ -1176,6 +1195,32 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc)
}
/**
+ * ata_dev_disable - disable ATA device
+ * @dev: ATA device to disable
+ *
+ * Disable @dev.
+ *
+ * Locking:
+ * EH context.
+ */
+void ata_dev_disable(struct ata_device *dev)
+{
+ if (!ata_dev_enabled(dev))
+ return;
+
+ if (ata_msg_drv(dev->link->ap))
+ ata_dev_printk(dev, KERN_WARNING, "disabled\n");
+ ata_acpi_on_disable(dev);
+ ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);
+ dev->class++;
+
+ /* From now till the next successful probe, ering is used to
+ * track probe failures. Clear accumulated device error info.
+ */
+ ata_ering_clear(&dev->ering);
+}
+
+/**
* ata_eh_detach_dev - detach ATA device
* @dev: ATA device to detach
*
@@ -1849,7 +1894,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
/* speed down? */
if (verdict & ATA_EH_SPDN_SPEED_DOWN) {
/* speed down SATA link speed if possible */
- if (sata_down_spd_limit(link) == 0) {
+ if (sata_down_spd_limit(link, 0) == 0) {
action |= ATA_EH_RESET;
goto done;
}
@@ -2393,11 +2438,14 @@ int ata_eh_reset(struct ata_link *link, int classify,
}
/* prereset() might have cleared ATA_EH_RESET. If so,
- * bang classes and return.
+ * bang classes, thaw and return.
*/
if (reset && !(ehc->i.action & ATA_EH_RESET)) {
ata_for_each_dev(dev, link, ALL)
classes[dev->devno] = ATA_DEV_NONE;
+ if ((ap->pflags & ATA_PFLAG_FROZEN) &&
+ ata_is_host_link(link))
+ ata_eh_thaw_port(ap);
rc = 0;
goto out;
}
@@ -2601,11 +2649,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
}
if (try == max_tries - 1) {
- sata_down_spd_limit(link);
+ sata_down_spd_limit(link, 0);
if (slave)
- sata_down_spd_limit(slave);
+ sata_down_spd_limit(slave, 0);
} else if (rc == -EPIPE)
- sata_down_spd_limit(failed_link);
+ sata_down_spd_limit(failed_link, 0);
if (hardreset)
reset = hardreset;
@@ -2744,6 +2792,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
readid_flags, dev->id);
switch (rc) {
case 0:
+ /* clear error info accumulated during probe */
+ ata_ering_clear(&dev->ering);
new_mask |= 1 << dev->devno;
break;
case -ENOENT:
@@ -2869,7 +2919,7 @@ static int atapi_eh_clear_ua(struct ata_device *dev)
int i;
for (i = 0; i < ATA_EH_UA_TRIES; i++) {
- u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
+ u8 *sense_buffer = dev->link->ap->sector_buf;
u8 sense_key = 0;
unsigned int err_mask;
@@ -2947,9 +2997,24 @@ static int ata_eh_skip_recovery(struct ata_link *link)
return 1;
}
+static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg)
+{
+ u64 interval = msecs_to_jiffies(ATA_EH_PROBE_TRIAL_INTERVAL);
+ u64 now = get_jiffies_64();
+ int *trials = void_arg;
+
+ if (ent->timestamp < now - min(now, interval))
+ return -1;
+
+ (*trials)++;
+ return 0;
+}
+
static int ata_eh_schedule_probe(struct ata_device *dev)
{
struct ata_eh_context *ehc = &dev->link->eh_context;
+ struct ata_link *link = ata_dev_phys_link(dev);
+ int trials = 0;
if (!(ehc->i.probe_mask & (1 << dev->devno)) ||
(ehc->did_probe_mask & (1 << dev->devno)))
@@ -2962,6 +3027,25 @@ static int ata_eh_schedule_probe(struct ata_device *dev)
ehc->saved_xfer_mode[dev->devno] = 0;
ehc->saved_ncq_enabled &= ~(1 << dev->devno);
+ /* Record and count probe trials on the ering. The specific
+ * error mask used is irrelevant. Because a successful device
+ * detection clears the ering, this count accumulates only if
+ * there are consecutive failed probes.
+ *
+ * If the count is equal to or higher than ATA_EH_PROBE_TRIALS
+ * in the last ATA_EH_PROBE_TRIAL_INTERVAL, link speed is
+ * forced to 1.5Gbps.
+ *
+ * This is to work around cases where failed link speed
+ * negotiation results in device misdetection leading to
+ * infinite DEVXCHG or PHRDY CHG events.
+ */
+ ata_ering_record(&dev->ering, 0, AC_ERR_OTHER);
+ ata_ering_map(&dev->ering, ata_count_probe_trials_cb, &trials);
+
+ if (trials > ATA_EH_PROBE_TRIALS)
+ sata_down_spd_limit(link, 1);
+
return 1;
}
@@ -2969,7 +3053,11 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
{
struct ata_eh_context *ehc = &dev->link->eh_context;
- ehc->tries[dev->devno]--;
+ /* -EAGAIN from EH routine indicates retry without prejudice.
+ * The requester is responsible for ensuring forward progress.
+ */
+ if (err != -EAGAIN)
+ ehc->tries[dev->devno]--;
switch (err) {
case -ENODEV:
@@ -2979,12 +3067,13 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
/* give it just one more chance */
ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
case -EIO:
- if (ehc->tries[dev->devno] == 1 && dev->pio_mode > XFER_PIO_0) {
+ if (ehc->tries[dev->devno] == 1) {
/* This is the last chance, better to slow
* down than lose it.
*/
- sata_down_spd_limit(ata_dev_phys_link(dev));
- ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
+ sata_down_spd_limit(ata_dev_phys_link(dev), 0);
+ if (dev->pio_mode > XFER_PIO_0)
+ ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
}
}
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 98ca07a2db8..619f2c33950 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -729,7 +729,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
if (tries) {
/* consecutive revalidation failures? speed down */
if (reval_failed)
- sata_down_spd_limit(link);
+ sata_down_spd_limit(link, 0);
else
reval_failed = 1;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9e92107691f..b9747fa59e5 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -46,6 +46,7 @@
#include <linux/libata.h>
#include <linux/hdreg.h>
#include <linux/uaccess.h>
+#include <linux/suspend.h>
#include "libata.h"
@@ -414,6 +415,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
/**
* ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
+ * @ap: target port
* @sdev: SCSI device to get identify data for
* @arg: User buffer area for identify data
*
@@ -423,9 +425,9 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
* RETURNS:
* Zero on success, negative errno on error.
*/
-static int ata_get_identity(struct scsi_device *sdev, void __user *arg)
+static int ata_get_identity(struct ata_port *ap, struct scsi_device *sdev,
+ void __user *arg)
{
- struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
u16 __user *dst = arg;
char buf[40];
@@ -645,7 +647,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
return rc;
}
-int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
+int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
+ int cmd, void __user *arg)
{
int val = -EINVAL, rc = -EINVAL;
@@ -663,7 +666,7 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
return 0;
case HDIO_GET_IDENTITY:
- return ata_get_identity(scsidev, arg);
+ return ata_get_identity(ap, scsidev, arg);
case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
@@ -682,6 +685,14 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
return rc;
}
+EXPORT_SYMBOL_GPL(ata_sas_scsi_ioctl);
+
+int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
+{
+ return ata_sas_scsi_ioctl(ata_shost_to_port(scsidev->host),
+ scsidev, cmd, arg);
+}
+EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
/**
* ata_scsi_qc_new - acquire new ata_queued_cmd reference
@@ -1294,6 +1305,17 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
} else {
+ /* Some odd clown BIOSen issue spindown on power off (ACPI S4
+ * or S5) causing some drives to spin up and down again.
+ */
+ if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) &&
+ system_state == SYSTEM_POWER_OFF)
+ goto skip;
+
+ if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) &&
+ system_entering_hibernation())
+ goto skip;
+
/* XXX: This is for backward compatibility, will be
* removed. Read Documentation/feature-removal-schedule.txt
* for more info.
@@ -1317,8 +1339,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
scmd->scsi_done = qc->scsidone;
qc->scsidone = ata_delayed_done;
}
- scmd->result = SAM_STAT_GOOD;
- return 1;
+ goto skip;
}
/* Issue ATA STANDBY IMMEDIATE command */
@@ -1334,10 +1355,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
return 0;
-invalid_fld:
+ invalid_fld:
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
+ skip:
+ scmd->result = SAM_STAT_GOOD;
+ return 1;
}
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 5a4aad123c4..8332e97a9de 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -52,6 +52,7 @@ const struct ata_port_operations ata_sff_port_ops = {
.softreset = ata_sff_softreset,
.hardreset = sata_sff_hardreset,
.postreset = ata_sff_postreset,
+ .drain_fifo = ata_sff_drain_fifo,
.error_handler = ata_sff_error_handler,
.post_internal_cmd = ata_sff_post_internal_cmd,
@@ -64,6 +65,8 @@ const struct ata_port_operations ata_sff_port_ops = {
.sff_irq_on = ata_sff_irq_on,
.sff_irq_clear = ata_sff_irq_clear,
+ .lost_interrupt = ata_sff_lost_interrupt,
+
.port_start = ata_sff_port_start,
};
EXPORT_SYMBOL_GPL(ata_sff_port_ops);
@@ -773,18 +776,32 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
else
iowrite32_rep(data_addr, buf, words);
+ /* Transfer trailing bytes, if any */
if (unlikely(slop)) {
- __le32 pad;
+ unsigned char pad[4];
+
+ /* Point buf to the tail of buffer */
+ buf += buflen - slop;
+
+ /*
+ * Use io*_rep() accessors here as well to avoid pointlessly
+ * swapping bytes to and fro on the big endian machines...
+ */
if (rw == READ) {
- pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
- memcpy(buf + buflen - slop, &pad, slop);
+ if (slop < 3)
+ ioread16_rep(data_addr, pad, 1);
+ else
+ ioread32_rep(data_addr, pad, 1);
+ memcpy(buf, pad, slop);
} else {
- memcpy(&pad, buf + buflen - slop, slop);
- iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ memcpy(pad, buf, slop);
+ if (slop < 3)
+ iowrite16_rep(data_addr, pad, 1);
+ else
+ iowrite32_rep(data_addr, pad, 1);
}
- words++;
}
- return words << 2;
+ return (buflen + 1) & ~1;
}
EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
@@ -1322,7 +1339,7 @@ fsm_start:
* condition. Mark hint.
*/
ata_ehi_push_desc(ehi, "ST-ATA: "
- "DRQ=1 with device error, "
+ "DRQ=0 without device error, "
"dev_stat 0x%X", status);
qc->err_mask |= AC_ERR_HSM |
AC_ERR_NODEV_HINT;
@@ -1358,6 +1375,16 @@ fsm_start:
qc->err_mask |= AC_ERR_HSM;
}
+ /* There are oddball controllers with
+ * status register stuck at 0x7f and
+ * lbal/m/h at zero which makes it
+ * pass all other presence detection
+ * mechanisms we have. Set NODEV_HINT
+ * for it. Kernel bz#7241.
+ */
+ if (status == 0x7f)
+ qc->err_mask |= AC_ERR_NODEV_HINT;
+
/* ata_pio_sectors() might change the
* state to HSM_ST_LAST. so, the state
* is changed after ata_pio_sectors().
@@ -1622,7 +1649,7 @@ EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
* RETURNS:
* One if interrupt was handled, zero if not (shared irq).
*/
-inline unsigned int ata_sff_host_intr(struct ata_port *ap,
+unsigned int ata_sff_host_intr(struct ata_port *ap,
struct ata_queued_cmd *qc)
{
struct ata_eh_info *ehi = &ap->link.eh_info;
@@ -1751,6 +1778,48 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
EXPORT_SYMBOL_GPL(ata_sff_interrupt);
/**
+ * ata_sff_lost_interrupt - Check for an apparent lost interrupt
+ * @ap: port that appears to have timed out
+ *
+ * Called from the libata error handlers when the core code suspects
+ * an interrupt has been lost. If it has complete anything we can and
+ * then return. Interface must support altstatus for this faster
+ * recovery to occur.
+ *
+ * Locking:
+ * Caller holds host lock
+ */
+
+void ata_sff_lost_interrupt(struct ata_port *ap)
+{
+ u8 status;
+ struct ata_queued_cmd *qc;
+
+ /* Only one outstanding command per SFF channel */
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ /* Check we have a live one.. */
+ if (qc == NULL || !(qc->flags & ATA_QCFLAG_ACTIVE))
+ return;
+ /* We cannot lose an interrupt on a polled command */
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ return;
+ /* See if the controller thinks it is still busy - if so the command
+ isn't a lost IRQ but is still in progress */
+ status = ata_sff_altstatus(ap);
+ if (status & ATA_BUSY)
+ return;
+
+ /* There was a command running, we are no longer busy and we have
+ no interrupt. */
+ ata_port_printk(ap, KERN_WARNING, "lost interrupt (Status 0x%x)\n",
+ status);
+ /* Run the host interrupt logic as if the interrupt had not been
+ lost */
+ ata_sff_host_intr(ap, qc);
+}
+EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt);
+
+/**
* ata_sff_freeze - Freeze SFF controller port
* @ap: port to freeze
*
@@ -2042,6 +2111,7 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
udelay(20); /* FIXME: flush */
iowrite8(ap->ctl, ioaddr->ctl_addr);
+ ap->last_ctl = ap->ctl;
/* wait the port to become ready */
return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
@@ -2166,12 +2236,47 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
}
/* set up device control */
- if (ap->ioaddr.ctl_addr)
+ if (ap->ioaddr.ctl_addr) {
iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
+ ap->last_ctl = ap->ctl;
+ }
}
EXPORT_SYMBOL_GPL(ata_sff_postreset);
/**
+ * ata_sff_drain_fifo - Stock FIFO drain logic for SFF controllers
+ * @qc: command
+ *
+ * Drain the FIFO and device of any stuck data following a command
+ * failing to complete. In some cases this is neccessary before a
+ * reset will recover the device.
+ *
+ */
+
+void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
+{
+ int count;
+ struct ata_port *ap;
+
+ /* We only need to flush incoming data when a command was running */
+ if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+ return;
+
+ ap = qc->ap;
+ /* Drain up to 64K of data before we give up this recovery method */
+ for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
+ && count < 32768; count++)
+ ioread16(ap->ioaddr.data_addr);
+
+ /* Can become DEBUG later */
+ if (count)
+ ata_port_printk(ap, KERN_DEBUG,
+ "drained %d bytes to clear DRQ.\n", count);
+
+}
+EXPORT_SYMBOL_GPL(ata_sff_drain_fifo);
+
+/**
* ata_sff_error_handler - Stock error handler for BMDMA controller
* @ap: port to handle error for
*
@@ -2212,7 +2317,8 @@ void ata_sff_error_handler(struct ata_port *ap)
* really a timeout event, adjust error mask and
* cancel frozen state.
*/
- if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
+ if (qc->err_mask == AC_ERR_TIMEOUT
+ && (host_stat & ATA_DMA_ERR)) {
qc->err_mask = AC_ERR_HOST_BUS;
thaw = 1;
}
@@ -2223,6 +2329,13 @@ void ata_sff_error_handler(struct ata_port *ap)
ata_sff_sync(ap); /* FIXME: We don't need this */
ap->ops->sff_check_status(ap);
ap->ops->sff_irq_clear(ap);
+ /* We *MUST* do FIFO draining before we issue a reset as several
+ * devices helpfully clear their internal state and will lock solid
+ * if we touch the data port post reset. Pass qc in case anyone wants
+ * to do different PIO/DMA recovery or has per command fixups
+ */
+ if (ap->ops->drain_fifo)
+ ap->ops->drain_fifo(qc);
spin_unlock_irqrestore(ap->lock, flags);
@@ -2510,6 +2623,7 @@ void ata_bus_reset(struct ata_port *ap)
if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
/* set up device control for ATA_FLAG_SATA_RESET */
iowrite8(ap->ctl, ioaddr->ctl_addr);
+ ap->last_ctl = ap->ctl;
}
DPRINTK("EXIT\n");
@@ -2931,4 +3045,3 @@ out:
EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
#endif /* CONFIG_PCI */
-
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index fe2839e5877..89a1e0018e7 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -79,9 +79,6 @@ extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
unsigned int tag);
extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
-extern void ata_dev_disable(struct ata_device *dev);
-extern void ata_pio_queue_task(struct ata_port *ap, void *data,
- unsigned long delay);
extern void ata_port_flush_task(struct ata_port *ap);
extern unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
@@ -100,7 +97,7 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
unsigned int readid_flags);
extern int ata_dev_configure(struct ata_device *dev);
-extern int sata_down_spd_limit(struct ata_link *link);
+extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
extern void ata_sg_clean(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc);
@@ -160,6 +157,7 @@ extern void ata_scsi_error(struct Scsi_Host *host);
extern void ata_port_wait_eh(struct ata_port *ap);
extern void ata_eh_fastdrain_timerfn(unsigned long arg);
extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
+extern void ata_dev_disable(struct ata_device *dev);
extern void ata_eh_detach_dev(struct ata_device *dev);
extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
unsigned int action);
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 8b77a9802df..d8f35fe4442 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -246,9 +246,9 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &pacpi_ops,
};
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index a7999c19f0c..751b7ea4816 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -41,7 +41,7 @@ static int ali_atapi_dma = 0;
module_param_named(atapi_dma, ali_atapi_dma, int, 0644);
MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)");
-static struct pci_dev *isa_bridge;
+static struct pci_dev *ali_isa_bridge;
/*
* Cable special cases
@@ -346,13 +346,13 @@ static void ali_c2_c3_postreset(struct ata_link *link, unsigned int *classes)
int port_bit = 4 << link->ap->port_no;
/* If our bridge is an ALI 1533 then do the extra work */
- if (isa_bridge) {
+ if (ali_isa_bridge) {
/* Tristate and re-enable the bus signals */
- pci_read_config_byte(isa_bridge, 0x58, &r);
+ pci_read_config_byte(ali_isa_bridge, 0x58, &r);
r &= ~port_bit;
- pci_write_config_byte(isa_bridge, 0x58, r);
+ pci_write_config_byte(ali_isa_bridge, 0x58, r);
r |= port_bit;
- pci_write_config_byte(isa_bridge, 0x58, r);
+ pci_write_config_byte(ali_isa_bridge, 0x58, r);
}
ata_sff_postreset(link, classes);
}
@@ -467,14 +467,14 @@ static void ali_init_chipset(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x53, tmp);
}
north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
- if (north && north->vendor == PCI_VENDOR_ID_AL && isa_bridge) {
+ if (north && north->vendor == PCI_VENDOR_ID_AL && ali_isa_bridge) {
/* Configure the ALi bridge logic. For non ALi rely on BIOS.
Set the south bridge enable bit */
- pci_read_config_byte(isa_bridge, 0x79, &tmp);
+ pci_read_config_byte(ali_isa_bridge, 0x79, &tmp);
if (pdev->revision == 0xC2)
- pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04);
+ pci_write_config_byte(ali_isa_bridge, 0x79, tmp | 0x04);
else if (pdev->revision > 0xC2 && pdev->revision < 0xC5)
- pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
+ pci_write_config_byte(ali_isa_bridge, 0x79, tmp | 0x02);
}
pci_dev_put(north);
ata_pci_bmdma_clear_simplex(pdev);
@@ -492,53 +492,53 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info_early = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &ali_early_port_ops
};
/* Revision 0x20 added DMA */
static const struct ata_port_info info_20 = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &ali_20_port_ops
};
/* Revision 0x20 with support logic added UDMA */
static const struct ata_port_info info_20_udma = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07, /* UDMA33 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &ali_20_port_ops
};
/* Revision 0xC2 adds UDMA66 */
static const struct ata_port_info info_c2 = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC3 is UDMA66 for now */
static const struct ata_port_info info_c3 = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC4 is UDMA100 */
static const struct ata_port_info info_c4 = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &ali_c4_port_ops
};
/* Revision 0xC5 is UDMA133 with LBA48 DMA */
static const struct ata_port_info info_c5 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &ali_c5_port_ops
};
@@ -571,9 +571,9 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
ali_init_chipset(pdev);
- if (isa_bridge && pdev->revision >= 0x20 && pdev->revision < 0xC2) {
+ if (ali_isa_bridge && pdev->revision >= 0x20 && pdev->revision < 0xC2) {
/* Are we paired with a UDMA capable chip */
- pci_read_config_byte(isa_bridge, 0x5E, &tmp);
+ pci_read_config_byte(ali_isa_bridge, 0x5E, &tmp);
if ((tmp & 0x1E) == 0x12)
ppi[0] = &info_20_udma;
}
@@ -617,11 +617,11 @@ static struct pci_driver ali_pci_driver = {
static int __init ali_init(void)
{
int ret;
- isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
+ ali_isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
ret = pci_register_driver(&ali_pci_driver);
if (ret < 0)
- pci_dev_put(isa_bridge);
+ pci_dev_put(ali_isa_bridge);
return ret;
}
@@ -629,7 +629,7 @@ static int __init ali_init(void)
static void __exit ali_exit(void)
{
pci_unregister_driver(&ali_pci_driver);
- pci_dev_put(isa_bridge);
+ pci_dev_put(ali_isa_bridge);
}
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 63719ab9ea4..33a74f11171 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -24,7 +24,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_amd"
-#define DRV_VERSION "0.3.11"
+#define DRV_VERSION "0.4.1"
/**
* timing_setup - shared timing computation and load
@@ -145,6 +145,13 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline)
return ata_sff_prereset(link, deadline);
}
+/**
+ * amd_cable_detect - report cable type
+ * @ap: port
+ *
+ * AMD controller/BIOS setups record the cable type in word 0x42
+ */
+
static int amd_cable_detect(struct ata_port *ap)
{
static const u32 bitmask[2] = {0x03, 0x0C};
@@ -158,6 +165,40 @@ static int amd_cable_detect(struct ata_port *ap)
}
/**
+ * amd_fifo_setup - set the PIO FIFO for ATA/ATAPI
+ * @ap: ATA interface
+ * @adev: ATA device
+ *
+ * Set the PCI fifo for this device according to the devices present
+ * on the bus at this point in time. We need to turn the post write buffer
+ * off for ATAPI devices as we may need to issue a word sized write to the
+ * device as the final I/O
+ */
+
+static void amd_fifo_setup(struct ata_port *ap)
+{
+ struct ata_device *adev;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ static const u8 fifobit[2] = { 0xC0, 0x30};
+ u8 fifo = fifobit[ap->port_no];
+ u8 r;
+
+
+ ata_for_each_dev(adev, &ap->link, ENABLED) {
+ if (adev->class == ATA_DEV_ATAPI)
+ fifo = 0;
+ }
+ if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) /* FIFO is broken */
+ fifo = 0;
+
+ /* On the later chips the read prefetch bits become no-op bits */
+ pci_read_config_byte(pdev, 0x41, &r);
+ r &= ~fifobit[ap->port_no];
+ r |= fifo;
+ pci_write_config_byte(pdev, 0x41, r);
+}
+
+/**
* amd33_set_piomode - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
@@ -167,21 +208,25 @@ static int amd_cable_detect(struct ata_port *ap)
static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
+ amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 1);
}
static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
+ amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 2);
}
static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
+ amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 3);
}
static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
+ amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 4);
}
@@ -397,77 +442,87 @@ static struct ata_port_operations nv133_port_ops = {
.set_dmamode = nv133_set_dmamode,
};
+static void amd_clear_fifo(struct pci_dev *pdev)
+{
+ u8 fifo;
+ /* Disable the FIFO, the FIFO logic will re-enable it as
+ appropriate */
+ pci_read_config_byte(pdev, 0x41, &fifo);
+ fifo &= 0x0F;
+ pci_write_config_byte(pdev, 0x41, fifo);
+}
+
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info[10] = {
- { /* 0: AMD 7401 */
+ { /* 0: AMD 7401 - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07, /* No SWDMA */
- .udma_mask = 0x07, /* UDMA 33 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &amd33_port_ops
},
{ /* 1: Early AMD7409 - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA4, /* UDMA 66 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
.port_ops = &amd66_port_ops
},
- { /* 2: AMD 7409, no swdma errata */
+ { /* 2: AMD 7409 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA4, /* UDMA 66 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
.port_ops = &amd66_port_ops
},
{ /* 3: AMD 7411 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &amd100_port_ops
},
{ /* 4: AMD 7441 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &amd100_port_ops
},
- { /* 5: AMD 8111*/
+ { /* 5: AMD 8111 - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &amd133_port_ops
},
- { /* 6: AMD 8111 UDMA 100 (Serenade) */
+ { /* 6: AMD 8111 UDMA 100 (Serenade) - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100, no swdma */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &amd133_port_ops
},
{ /* 7: Nvidia Nforce */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &nv100_port_ops
},
- { /* 8: Nvidia Nforce2 and later */
+ { /* 8: Nvidia Nforce2 and later - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &nv133_port_ops
},
{ /* 9: AMD CS5536 (Geode companion) */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &amd100_port_ops
}
};
@@ -503,14 +558,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (type < 3)
ata_pci_bmdma_clear_simplex(pdev);
-
- /* Check for AMD7411 */
- if (type == 3)
- /* FIFO is broken */
- pci_write_config_byte(pdev, 0x41, fifo & 0x0F);
- else
- pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
-
+ if (pdev->vendor == PCI_VENDOR_ID_AMD)
+ amd_clear_fifo(pdev);
/* Cable detection on Nvidia chips doesn't work too well,
* cache BIOS programmed UDMA mode.
*/
@@ -536,18 +585,11 @@ static int amd_reinit_one(struct pci_dev *pdev)
return rc;
if (pdev->vendor == PCI_VENDOR_ID_AMD) {
- u8 fifo;
- pci_read_config_byte(pdev, 0x41, &fifo);
- if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
- /* FIFO is broken */
- pci_write_config_byte(pdev, 0x41, fifo & 0x0F);
- else
- pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
+ amd_clear_fifo(pdev);
if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 ||
pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401)
ata_pci_bmdma_clear_simplex(pdev);
}
-
ata_host_resume(host);
return 0;
}
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 6b3092c75ff..d332cfdb0f3 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -12,7 +12,6 @@
* performance Alessandro Zummo <alessandro.zummo@towertech.it>
*
* TODO
- * 850 serialization once the core supports it
* Investigate no_dsc on 850R
* Clock detect
*/
@@ -29,7 +28,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_artop"
-#define DRV_VERSION "0.4.4"
+#define DRV_VERSION "0.4.5"
/*
* The ARTOP has 33 Mhz and "over clocked" timing tables. Until we
@@ -283,6 +282,31 @@ static void artop6260_set_dmamode (struct ata_port *ap, struct ata_device *adev)
pci_write_config_byte(pdev, 0x44 + ap->port_no, ultra);
}
+/**
+ * artop_6210_qc_defer - implement serialization
+ * @qc: command
+ *
+ * Issue commands per host on this chip.
+ */
+
+static int artop6210_qc_defer(struct ata_queued_cmd *qc)
+{
+ struct ata_host *host = qc->ap->host;
+ struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
+ int rc;
+
+ /* First apply the usual rules */
+ rc = ata_std_qc_defer(qc);
+ if (rc != 0)
+ return rc;
+
+ /* Now apply serialization rules. Only allow a command if the
+ other channel state machine is idle */
+ if (alt && alt->qc_active)
+ return ATA_DEFER_PORT;
+ return 0;
+}
+
static struct scsi_host_template artop_sht = {
ATA_BMDMA_SHT(DRV_NAME),
};
@@ -293,6 +317,7 @@ static struct ata_port_operations artop6210_ops = {
.set_piomode = artop6210_set_piomode,
.set_dmamode = artop6210_set_dmamode,
.prereset = artop6210_pre_reset,
+ .qc_defer = artop6210_qc_defer,
};
static struct ata_port_operations artop6260_ops = {
@@ -323,29 +348,29 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version;
static const struct ata_port_info info_6210 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &artop6210_ops,
};
static const struct ata_port_info info_626x = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &artop6260_ops,
};
static const struct ata_port_info info_628x = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &artop6260_ops,
};
static const struct ata_port_info info_628x_fast = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &artop6260_ops,
};
@@ -362,12 +387,8 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
if (id->driver_data == 0) { /* 6210 variant */
ppi[0] = &info_6210;
- ppi[1] = &ata_dummy_port_info;
/* BIOS may have left us in UDMA, clear it before libata probe */
pci_write_config_byte(pdev, 0x54, 0);
- /* For the moment (also lacks dsc) */
- printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n");
- printk(KERN_WARNING "Secondary ATA ports will not be activated.\n");
}
else if (id->driver_data == 1) /* 6260 */
ppi[0] = &info_626x;
diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c
index ab61095093b..5c129f99a7e 100644
--- a/drivers/ata/pata_at32.c
+++ b/drivers/ata/pata_at32.c
@@ -67,7 +67,9 @@
*
* Alter PIO_MASK below according to table to set maximal PIO mode.
*/
-#define PIO_MASK (0x1f)
+enum {
+ PIO_MASK = ATA_PIO4,
+};
/*
* Struct containing private information about device.
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 0e2cde8f997..bec0b8ade66 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -32,21 +32,6 @@ enum {
ATIIXP_IDE_UDMA_MODE = 0x56
};
-static int atiixp_pre_reset(struct ata_link *link, unsigned long deadline)
-{
- struct ata_port *ap = link->ap;
- static const struct pci_bits atiixp_enable_bits[] = {
- { 0x48, 1, 0x01, 0x00 },
- { 0x48, 1, 0x08, 0x00 }
- };
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
- if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
- return -ENOENT;
-
- return ata_sff_prereset(link, deadline);
-}
-
static int atiixp_cable_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
@@ -229,20 +214,29 @@ static struct ata_port_operations atiixp_port_ops = {
.cable_detect = atiixp_cable_detect,
.set_piomode = atiixp_set_piomode,
.set_dmamode = atiixp_set_dmamode,
- .prereset = atiixp_pre_reset,
};
-static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x06, /* No MWDMA0 support */
- .udma_mask = 0x3F,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY,
+ .udma_mask = ATA_UDMA5,
.port_ops = &atiixp_port_ops
};
- const struct ata_port_info *ppi[] = { &info, NULL };
- return ata_pci_sff_init_one(dev, ppi, &atiixp_sht, NULL);
+ static const struct pci_bits atiixp_enable_bits[] = {
+ { 0x48, 1, 0x01, 0x00 },
+ { 0x48, 1, 0x08, 0x00 }
+ };
+ const struct ata_port_info *ppi[] = { &info, &info };
+ int i;
+
+ for (i = 0; i < 2; i++)
+ if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i]))
+ ppi[i] = &ata_dummy_port_info;
+
+ return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL);
}
static const struct pci_device_id atiixp[] = {
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 1050fed96b2..c4b47a3e544 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1502,7 +1502,7 @@ static struct ata_port_info bfin_port_info[] = {
.flags = ATA_FLAG_SLAVE_POSS
| ATA_FLAG_MMIO
| ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.mwdma_mask = 0,
.udma_mask = 0,
.port_ops = &bfin_pata_ops,
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 34a394264c3..5acf9fa9b39 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -211,7 +211,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &cmd640_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 3167d8fed2f..f98dffedf4b 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -299,40 +299,40 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info cmd_info[6] = {
{ /* CMD 643 - no UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with broken UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with working UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 rev 1 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &cmd646r1_port_ops
},
{ /* CMD 648 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &cmd648_port_ops
},
{ /* CMD 649 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &cmd648_port_ops
}
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 1186bcd2781..db6a96984f3 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -158,7 +158,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
struct ata_port_info pi = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &cs5520_port_ops,
};
const struct ata_port_info *ppi[2];
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index bba453381f4..c974b05e412 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -298,15 +298,15 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &cs5530_port_ops
};
/* The docking connector doesn't do UDMA, and it seems not MWDMA */
static const struct ata_port_info info_palmax_secondary = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &cs5530_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 8b236af84c2..d33aa28239a 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -181,8 +181,8 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &cs5535_port_ops
};
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index afed9297619..6da4cb486c8 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -241,8 +241,8 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &cs5536_port_ops,
};
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index d546425cd38..8fb040bf736 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -124,8 +124,8 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &cy82c693_port_ops
};
const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index ac6392ea35b..2085e0a3a05 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -251,9 +251,9 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma1-2 */
- .udma_mask = 0x0f, /* UDMA 66 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
.port_ops = &efar_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 65c28e5a6cd..d7f2da127d1 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -336,8 +336,8 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_hpt366 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &hpt366_port_ops
};
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 42163998de9..81ab57003ab 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -753,55 +753,55 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370a_port_ops
};
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370_33 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a_33 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370a_port_ops
};
/* HPT371, 372 and friends - UDMA133 */
static const struct ata_port_info info_hpt372 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt372_port_ops
};
/* HPT374 - UDMA100, function 1 uses different prereset method */
static const struct ata_port_info info_hpt374_fn0 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt372_port_ops
};
static const struct ata_port_info info_hpt374_fn1 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt374_fn1_port_ops
};
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index d5c9fd7b82b..3d59fe0a408 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -441,8 +441,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* HPT372N and friends - UDMA133 */
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt3x2n_port_ops
};
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index f19cc645881..7e310253b36 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -188,11 +188,11 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
#if defined(CONFIG_PATA_HPT3X3_DMA)
/* Further debug needed */
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
#endif
.port_ops = &hpt3x3_port_ops
};
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index cf9e9848f8b..e7347db5b6c 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -297,7 +297,7 @@ static int icside_dma_init(struct pata_icside_info *info)
if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
state->dma = ec->dma;
- info->mwdma_mask = 0x07; /* MW0..2 */
+ info->mwdma_mask = ATA_MWDMA2;
}
return 0;
@@ -473,7 +473,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
for (i = 0; i < info->nr_ports; i++) {
struct ata_port *ap = host->ports[i];
- ap->pio_mask = 0x1f;
+ ap->pio_mask = ATA_PIO4;
ap->mwdma_mask = info->mwdma_mask;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ops = &pata_icside_port_ops;
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 15cdb9148aa..4bceb8803a1 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -17,7 +17,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_isapnp"
-#define DRV_VERSION "0.2.2"
+#define DRV_VERSION "0.2.5"
static struct scsi_host_template isapnp_sht = {
ATA_PIO_SHT(DRV_NAME),
@@ -28,6 +28,13 @@ static struct ata_port_operations isapnp_port_ops = {
.cable_detect = ata_cable_40wire,
};
+static struct ata_port_operations isapnp_noalt_port_ops = {
+ .inherits = &ata_sff_port_ops,
+ .cable_detect = ata_cable_40wire,
+ /* No altstatus so we don't want to use the lost interrupt poll */
+ .lost_interrupt = ATA_OP_NULL,
+};
+
/**
* isapnp_init_one - attach an isapnp interface
* @idev: PnP device
@@ -65,8 +72,8 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
ap = host->ports[0];
- ap->ops = &isapnp_port_ops;
- ap->pio_mask = 1;
+ ap->ops = &isapnp_noalt_port_ops;
+ ap->pio_mask = ATA_PIO0;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = cmd_addr;
@@ -76,6 +83,7 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
pnp_port_start(idev, 1), 1);
ap->ioaddr.altstatus_addr = ctl_addr;
ap->ioaddr.ctl_addr = ctl_addr;
+ ap->ops = &isapnp_port_ops;
}
ata_sff_std_ports(&ap->ioaddr);
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index c113d7c079c..f156da8076f 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -262,8 +262,8 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4, /* FIXME: want UDMA 100? */
.port_ops = &it8213_ops,
};
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index f1bb2f9fecb..188bc2fcd22 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -557,6 +557,9 @@ static unsigned int it821x_read_id(struct ata_device *adev,
id[83] |= 0x4400; /* Word 83 is valid and LBA48 */
id[86] |= 0x0400; /* LBA48 on */
id[ATA_ID_MAJOR_VER] |= 0x1F;
+ /* Clear the serial number because it's different each boot
+ which breaks validation on resume */
+ memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN);
}
return err_mask;
}
@@ -872,29 +875,29 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info info_smart = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &it821x_smart_port_ops
};
static const struct ata_port_info info_passthru = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &it821x_passthru_port_ops
};
static const struct ata_port_info info_rdc = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &it821x_rdc_port_ops
};
static const struct ata_port_info info_rdc_11 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
/* No UDMA */
.port_ops = &it821x_rdc_port_ops
};
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index b173c157ab0..19fdecf319a 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -176,7 +176,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
ap = host->ports[0];
ap->ops = &ixp4xx_port_ops;
- ap->pio_mask = 0x1f; /* PIO4 */
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
ixp4xx_setup_port(ap, data, cs0->start, cs1->start);
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 38cf1ab2d28..3a1474ac883 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -136,8 +136,8 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &jmicron_ops,
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 6c1d778b63a..3f830f0fe2c 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -129,7 +129,7 @@ static int qdi; /* Set to probe QDI controllers */
static int winbond; /* Set to probe Winbond controllers,
give I/O port if non standard */
static int autospeed; /* Chip present which snoops speed changes */
-static int pio_mask = 0x1F; /* PIO range for autospeed devices */
+static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */
static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */
/**
@@ -283,9 +283,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
static unsigned int pdc_data_xfer_vlb(struct ata_device *dev,
unsigned char *buf, unsigned int buflen, int rw)
{
- if (ata_id_has_dword_io(dev->id)) {
+ int slop = buflen & 3;
+ /* 32bit I/O capable *and* we need to write a whole number of dwords */
+ if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) {
struct ata_port *ap = dev->link->ap;
- int slop = buflen & 3;
unsigned long flags;
local_irq_save(flags);
@@ -735,7 +736,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf,
struct ata_port *ap = adev->link->ap;
int slop = buflen & 3;
- if (ata_id_has_dword_io(adev->id)) {
+ if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) {
if (rw == WRITE)
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 76e399bf8c1..2096fb737f8 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -126,8 +126,8 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &marvell_ops,
@@ -136,8 +136,8 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
/* Slave possible as its magically mapped not real */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &marvell_ops,
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 50ae6d13078..68d27bc70d0 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -737,10 +737,10 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
*/
prop = of_get_property(op->node, "mwdma-mode", &proplen);
if ((prop) && (proplen >= 4))
- mwdma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
+ mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1);
prop = of_get_property(op->node, "udma-mode", &proplen);
if ((prop) && (proplen >= 4))
- udma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
+ udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1);
ata_irq = irq_of_parse_and_map(op->node, 0);
if (ata_irq == NO_IRQ) {
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index aa576cac4d1..b21f0021f54 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -200,7 +200,7 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
the MPIIX your box goes castors up */
ap->ops = &mpiix_port_ops;
- ap->pio_mask = 0x1F;
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = cmd_addr;
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index 9dc05e1656a..bdb236957cb 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -51,8 +51,8 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
.flags = ATA_FLAG_SLAVE_POSS,
/* Actually we don't really care about these as the
firmware deals with it */
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5, /* UDMA 133 */
.port_ops = &netcell_ops,
};
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c
index 4dd9a3b031e..0fb6b1b1e63 100644
--- a/drivers/ata/pata_ninja32.c
+++ b/drivers/ata/pata_ninja32.c
@@ -136,7 +136,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (!base)
return -ENOMEM;
ap->ops = &ninja32_port_ops;
- ap->pio_mask = 0x1F;
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = base + 0x10;
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 40d411c460d..ca53fac0671 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -144,7 +144,7 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x0F,
+ .pio_mask = ATA_PIO3,
.port_ops = &ns87410_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c
index 89bf5f865d6..773b1590b49 100644
--- a/drivers/ata/pata_ns87415.c
+++ b/drivers/ata/pata_ns87415.c
@@ -346,8 +346,8 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &ns87415_pata_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
@@ -355,8 +355,8 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e
#if defined(CONFIG_SUPERIO)
static const struct ata_port_info info87560 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &ns87560_pata_ops,
};
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c
new file mode 100644
index 00000000000..efe2c1985af
--- /dev/null
+++ b/drivers/ata/pata_octeon_cf.c
@@ -0,0 +1,965 @@
+/*
+ * Driver for the Octeon bootbus compact flash.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 - 2009 Cavium Networks
+ * Copyright (C) 2008 Wind River Systems
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/libata.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <scsi/scsi_host.h>
+
+#include <asm/octeon/octeon.h>
+
+/*
+ * The Octeon bootbus compact flash interface is connected in at least
+ * 3 different configurations on various evaluation boards:
+ *
+ * -- 8 bits no irq, no DMA
+ * -- 16 bits no irq, no DMA
+ * -- 16 bits True IDE mode with DMA, but no irq.
+ *
+ * In the last case the DMA engine can generate an interrupt when the
+ * transfer is complete. For the first two cases only PIO is supported.
+ *
+ */
+
+#define DRV_NAME "pata_octeon_cf"
+#define DRV_VERSION "2.1"
+
+
+struct octeon_cf_port {
+ struct workqueue_struct *wq;
+ struct delayed_work delayed_finish;
+ struct ata_port *ap;
+ int dma_finished;
+};
+
+static struct scsi_host_template octeon_cf_sht = {
+ ATA_PIO_SHT(DRV_NAME),
+};
+
+/**
+ * Convert nanosecond based time to setting used in the
+ * boot bus timing register, based on timing multiple
+ */
+static unsigned int ns_to_tim_reg(unsigned int tim_mult, unsigned int nsecs)
+{
+ unsigned int val;
+
+ /*
+ * Compute # of eclock periods to get desired duration in
+ * nanoseconds.
+ */
+ val = DIV_ROUND_UP(nsecs * (octeon_get_clock_rate() / 1000000),
+ 1000 * tim_mult);
+
+ return val;
+}
+
+static void octeon_cf_set_boot_reg_cfg(int cs)
+{
+ union cvmx_mio_boot_reg_cfgx reg_cfg;
+ reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
+ reg_cfg.s.dmack = 0; /* Don't assert DMACK on access */
+ reg_cfg.s.tim_mult = 2; /* Timing mutiplier 2x */
+ reg_cfg.s.rd_dly = 0; /* Sample on falling edge of BOOT_OE */
+ reg_cfg.s.sam = 0; /* Don't combine write and output enable */
+ reg_cfg.s.we_ext = 0; /* No write enable extension */
+ reg_cfg.s.oe_ext = 0; /* No read enable extension */
+ reg_cfg.s.en = 1; /* Enable this region */
+ reg_cfg.s.orbit = 0; /* Don't combine with previous region */
+ reg_cfg.s.ale = 0; /* Don't do address multiplexing */
+ cvmx_write_csr(CVMX_MIO_BOOT_REG_CFGX(cs), reg_cfg.u64);
+}
+
+/**
+ * Called after libata determines the needed PIO mode. This
+ * function programs the Octeon bootbus regions to support the
+ * timing requirements of the PIO mode.
+ *
+ * @ap: ATA port information
+ * @dev: ATA device
+ */
+static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev)
+{
+ struct octeon_cf_data *ocd = ap->dev->platform_data;
+ union cvmx_mio_boot_reg_timx reg_tim;
+ int cs = ocd->base_region;
+ int T;
+ struct ata_timing timing;
+
+ int use_iordy;
+ int trh;
+ int pause;
+ /* These names are timing parameters from the ATA spec */
+ int t1;
+ int t2;
+ int t2i;
+
+ T = (int)(2000000000000LL / octeon_get_clock_rate());
+
+ if (ata_timing_compute(dev, dev->pio_mode, &timing, T, T))
+ BUG();
+
+ t1 = timing.setup;
+ if (t1)
+ t1--;
+ t2 = timing.active;
+ if (t2)
+ t2--;
+ t2i = timing.act8b;
+ if (t2i)
+ t2i--;
+
+ trh = ns_to_tim_reg(2, 20);
+ if (trh)
+ trh--;
+
+ pause = timing.cycle - timing.active - timing.setup - trh;
+ if (pause)
+ pause--;
+
+ octeon_cf_set_boot_reg_cfg(cs);
+ if (ocd->dma_engine >= 0)
+ /* True IDE mode, program both chip selects. */
+ octeon_cf_set_boot_reg_cfg(cs + 1);
+
+
+ use_iordy = ata_pio_need_iordy(dev);
+
+ reg_tim.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_TIMX(cs));
+ /* Disable page mode */
+ reg_tim.s.pagem = 0;
+ /* Enable dynamic timing */
+ reg_tim.s.waitm = use_iordy;
+ /* Pages are disabled */
+ reg_tim.s.pages = 0;
+ /* We don't use multiplexed address mode */
+ reg_tim.s.ale = 0;
+ /* Not used */
+ reg_tim.s.page = 0;
+ /* Time after IORDY to coninue to assert the data */
+ reg_tim.s.wait = 0;
+ /* Time to wait to complete the cycle. */
+ reg_tim.s.pause = pause;
+ /* How long to hold after a write to de-assert CE. */
+ reg_tim.s.wr_hld = trh;
+ /* How long to wait after a read to de-assert CE. */
+ reg_tim.s.rd_hld = trh;
+ /* How long write enable is asserted */
+ reg_tim.s.we = t2;
+ /* How long read enable is asserted */
+ reg_tim.s.oe = t2;
+ /* Time after CE that read/write starts */
+ reg_tim.s.ce = ns_to_tim_reg(2, 5);
+ /* Time before CE that address is valid */
+ reg_tim.s.adr = 0;
+
+ /* Program the bootbus region timing for the data port chip select. */
+ cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs), reg_tim.u64);
+ if (ocd->dma_engine >= 0)
+ /* True IDE mode, program both chip selects. */
+ cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs + 1), reg_tim.u64);
+}
+
+static void octeon_cf_set_dmamode(struct ata_port *ap, struct ata_device *dev)
+{
+ struct octeon_cf_data *ocd = dev->link->ap->dev->platform_data;
+ union cvmx_mio_boot_dma_timx dma_tim;
+ unsigned int oe_a;
+ unsigned int oe_n;
+ unsigned int dma_ackh;
+ unsigned int dma_arq;
+ unsigned int pause;
+ unsigned int T0, Tkr, Td;
+ unsigned int tim_mult;
+
+ const struct ata_timing *timing;
+
+ timing = ata_timing_find_mode(dev->dma_mode);
+ T0 = timing->cycle;
+ Td = timing->active;
+ Tkr = timing->recover;
+ dma_ackh = timing->dmack_hold;
+
+ dma_tim.u64 = 0;
+ /* dma_tim.s.tim_mult = 0 --> 4x */
+ tim_mult = 4;
+
+ /* not spec'ed, value in eclocks, not affected by tim_mult */
+ dma_arq = 8;
+ pause = 25 - dma_arq * 1000 /
+ (octeon_get_clock_rate() / 1000000); /* Tz */
+
+ oe_a = Td;
+ /* Tkr from cf spec, lengthened to meet T0 */
+ oe_n = max(T0 - oe_a, Tkr);
+
+ dma_tim.s.dmack_pi = 1;
+
+ dma_tim.s.oe_n = ns_to_tim_reg(tim_mult, oe_n);
+ dma_tim.s.oe_a = ns_to_tim_reg(tim_mult, oe_a);
+
+ /*
+ * This is tI, C.F. spec. says 0, but Sony CF card requires
+ * more, we use 20 nS.
+ */
+ dma_tim.s.dmack_s = ns_to_tim_reg(tim_mult, 20);;
+ dma_tim.s.dmack_h = ns_to_tim_reg(tim_mult, dma_ackh);
+
+ dma_tim.s.dmarq = dma_arq;
+ dma_tim.s.pause = ns_to_tim_reg(tim_mult, pause);
+
+ dma_tim.s.rd_dly = 0; /* Sample right on edge */
+
+ /* writes only */
+ dma_tim.s.we_n = ns_to_tim_reg(tim_mult, oe_n);
+ dma_tim.s.we_a = ns_to_tim_reg(tim_mult, oe_a);
+
+ pr_debug("ns to ticks (mult %d) of %d is: %d\n", tim_mult, 60,
+ ns_to_tim_reg(tim_mult, 60));
+ pr_debug("oe_n: %d, oe_a: %d, dmack_s: %d, dmack_h: "
+ "%d, dmarq: %d, pause: %d\n",
+ dma_tim.s.oe_n, dma_tim.s.oe_a, dma_tim.s.dmack_s,
+ dma_tim.s.dmack_h, dma_tim.s.dmarq, dma_tim.s.pause);
+
+ cvmx_write_csr(CVMX_MIO_BOOT_DMA_TIMX(ocd->dma_engine),
+ dma_tim.u64);
+
+}
+
+/**
+ * Handle an 8 bit I/O request.
+ *
+ * @dev: Device to access
+ * @buffer: Data buffer
+ * @buflen: Length of the buffer.
+ * @rw: True to write.
+ */
+static unsigned int octeon_cf_data_xfer8(struct ata_device *dev,
+ unsigned char *buffer,
+ unsigned int buflen,
+ int rw)
+{
+ struct ata_port *ap = dev->link->ap;
+ void __iomem *data_addr = ap->ioaddr.data_addr;
+ unsigned long words;
+ int count;
+
+ words = buflen;
+ if (rw) {
+ count = 16;
+ while (words--) {
+ iowrite8(*buffer, data_addr);
+ buffer++;
+ /*
+ * Every 16 writes do a read so the bootbus
+ * FIFO doesn't fill up.
+ */
+ if (--count == 0) {
+ ioread8(ap->ioaddr.altstatus_addr);
+ count = 16;
+ }
+ }
+ } else {
+ ioread8_rep(data_addr, buffer, words);
+ }
+ return buflen;
+}
+
+/**
+ * Handle a 16 bit I/O request.
+ *
+ * @dev: Device to access
+ * @buffer: Data buffer
+ * @buflen: Length of the buffer.
+ * @rw: True to write.
+ */
+static unsigned int octeon_cf_data_xfer16(struct ata_device *dev,
+ unsigned char *buffer,
+ unsigned int buflen,
+ int rw)
+{
+ struct ata_port *ap = dev->link->ap;
+ void __iomem *data_addr = ap->ioaddr.data_addr;
+ unsigned long words;
+ int count;
+
+ words = buflen / 2;
+ if (rw) {
+ count = 16;
+ while (words--) {
+ iowrite16(*(uint16_t *)buffer, data_addr);
+ buffer += sizeof(uint16_t);
+ /*
+ * Every 16 writes do a read so the bootbus
+ * FIFO doesn't fill up.
+ */
+ if (--count == 0) {
+ ioread8(ap->ioaddr.altstatus_addr);
+ count = 16;
+ }
+ }
+ } else {
+ while (words--) {
+ *(uint16_t *)buffer = ioread16(data_addr);
+ buffer += sizeof(uint16_t);
+ }
+ }
+ /* Transfer trailing 1 byte, if any. */
+ if (unlikely(buflen & 0x01)) {
+ __le16 align_buf[1] = { 0 };
+
+ if (rw == READ) {
+ align_buf[0] = cpu_to_le16(ioread16(data_addr));
+ memcpy(buffer, align_buf, 1);
+ } else {
+ memcpy(align_buf, buffer, 1);
+ iowrite16(le16_to_cpu(align_buf[0]), data_addr);
+ }
+ words++;
+ }
+ return buflen;
+}
+
+/**
+ * Read the taskfile for 16bit non-True IDE only.
+ */
+static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf)
+{
+ u16 blob;
+ /* The base of the registers is at ioaddr.data_addr. */
+ void __iomem *base = ap->ioaddr.data_addr;
+
+ blob = __raw_readw(base + 0xc);
+ tf->feature = blob >> 8;
+
+ blob = __raw_readw(base + 2);
+ tf->nsect = blob & 0xff;
+ tf->lbal = blob >> 8;
+
+ blob = __raw_readw(base + 4);
+ tf->lbam = blob & 0xff;
+ tf->lbah = blob >> 8;
+
+ blob = __raw_readw(base + 6);
+ tf->device = blob & 0xff;
+ tf->command = blob >> 8;
+
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ if (likely(ap->ioaddr.ctl_addr)) {
+ iowrite8(tf->ctl | ATA_HOB, ap->ioaddr.ctl_addr);
+
+ blob = __raw_readw(base + 0xc);
+ tf->hob_feature = blob >> 8;
+
+ blob = __raw_readw(base + 2);
+ tf->hob_nsect = blob & 0xff;
+ tf->hob_lbal = blob >> 8;
+
+ blob = __raw_readw(base + 4);
+ tf->hob_lbam = blob & 0xff;
+ tf->hob_lbah = blob >> 8;
+
+ iowrite8(tf->ctl, ap->ioaddr.ctl_addr);
+ ap->last_ctl = tf->ctl;
+ } else {
+ WARN_ON(1);
+ }
+ }
+}
+
+static u8 octeon_cf_check_status16(struct ata_port *ap)
+{
+ u16 blob;
+ void __iomem *base = ap->ioaddr.data_addr;
+
+ blob = __raw_readw(base + 6);
+ return blob >> 8;
+}
+
+static int octeon_cf_softreset16(struct ata_link *link, unsigned int *classes,
+ unsigned long deadline)
+{
+ struct ata_port *ap = link->ap;
+ void __iomem *base = ap->ioaddr.data_addr;
+ int rc;
+ u8 err;
+
+ DPRINTK("about to softreset\n");
+ __raw_writew(ap->ctl, base + 0xe);
+ udelay(20);
+ __raw_writew(ap->ctl | ATA_SRST, base + 0xe);
+ udelay(20);
+ __raw_writew(ap->ctl, base + 0xe);
+
+ rc = ata_sff_wait_after_reset(link, 1, deadline);
+ if (rc) {
+ ata_link_printk(link, KERN_ERR, "SRST failed (errno=%d)\n", rc);
+ return rc;
+ }
+
+ /* determine by signature whether we have ATA or ATAPI devices */
+ classes[0] = ata_sff_dev_classify(&link->device[0], 1, &err);
+ DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
+ return 0;
+}
+
+/**
+ * Load the taskfile for 16bit non-True IDE only. The device_addr is
+ * not loaded, we do this as part of octeon_cf_exec_command16.
+ */
+static void octeon_cf_tf_load16(struct ata_port *ap,
+ const struct ata_taskfile *tf)
+{
+ unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+ /* The base of the registers is at ioaddr.data_addr. */
+ void __iomem *base = ap->ioaddr.data_addr;
+
+ if (tf->ctl != ap->last_ctl) {
+ iowrite8(tf->ctl, ap->ioaddr.ctl_addr);
+ ap->last_ctl = tf->ctl;
+ ata_wait_idle(ap);
+ }
+ if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+ __raw_writew(tf->hob_feature << 8, base + 0xc);
+ __raw_writew(tf->hob_nsect | tf->hob_lbal << 8, base + 2);
+ __raw_writew(tf->hob_lbam | tf->hob_lbah << 8, base + 4);
+ VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
+ tf->hob_feature,
+ tf->hob_nsect,
+ tf->hob_lbal,
+ tf->hob_lbam,
+ tf->hob_lbah);
+ }
+ if (is_addr) {
+ __raw_writew(tf->feature << 8, base + 0xc);
+ __raw_writew(tf->nsect | tf->lbal << 8, base + 2);
+ __raw_writew(tf->lbam | tf->lbah << 8, base + 4);
+ VPRINTK("feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
+ tf->feature,
+ tf->nsect,
+ tf->lbal,
+ tf->lbam,
+ tf->lbah);
+ }
+ ata_wait_idle(ap);
+}
+
+
+static void octeon_cf_dev_select(struct ata_port *ap, unsigned int device)
+{
+/* There is only one device, do nothing. */
+ return;
+}
+
+/*
+ * Issue ATA command to host controller. The device_addr is also sent
+ * as it must be written in a combined write with the command.
+ */
+static void octeon_cf_exec_command16(struct ata_port *ap,
+ const struct ata_taskfile *tf)
+{
+ /* The base of the registers is at ioaddr.data_addr. */
+ void __iomem *base = ap->ioaddr.data_addr;
+ u16 blob;
+
+ if (tf->flags & ATA_TFLAG_DEVICE) {
+ VPRINTK("device 0x%X\n", tf->device);
+ blob = tf->device;
+ } else {
+ blob = 0;
+ }
+
+ DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
+ blob |= (tf->command << 8);
+ __raw_writew(blob, base + 6);
+
+
+ ata_wait_idle(ap);
+}
+
+static u8 octeon_cf_irq_on(struct ata_port *ap)
+{
+ return 0;
+}
+
+static void octeon_cf_irq_clear(struct ata_port *ap)
+{
+ return;
+}
+
+static void octeon_cf_dma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct octeon_cf_port *cf_port;
+
+ cf_port = (struct octeon_cf_port *)ap->private_data;
+ DPRINTK("ENTER\n");
+ /* issue r/w command */
+ qc->cursg = qc->sg;
+ cf_port->dma_finished = 0;
+ ap->ops->sff_exec_command(ap, &qc->tf);
+ DPRINTK("EXIT\n");
+}
+
+/**
+ * Start a DMA transfer that was already setup
+ *
+ * @qc: Information about the DMA
+ */
+static void octeon_cf_dma_start(struct ata_queued_cmd *qc)
+{
+ struct octeon_cf_data *ocd = qc->ap->dev->platform_data;
+ union cvmx_mio_boot_dma_cfgx mio_boot_dma_cfg;
+ union cvmx_mio_boot_dma_intx mio_boot_dma_int;
+ struct scatterlist *sg;
+
+ VPRINTK("%d scatterlists\n", qc->n_elem);
+
+ /* Get the scatter list entry we need to DMA into */
+ sg = qc->cursg;
+ BUG_ON(!sg);
+
+ /*
+ * Clear the DMA complete status.
+ */
+ mio_boot_dma_int.u64 = 0;
+ mio_boot_dma_int.s.done = 1;
+ cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine),
+ mio_boot_dma_int.u64);
+
+ /* Enable the interrupt. */
+ cvmx_write_csr(CVMX_MIO_BOOT_DMA_INT_ENX(ocd->dma_engine),
+ mio_boot_dma_int.u64);
+
+ /* Set the direction of the DMA */
+ mio_boot_dma_cfg.u64 = 0;
+ mio_boot_dma_cfg.s.en = 1;
+ mio_boot_dma_cfg.s.rw = ((qc->tf.flags & ATA_TFLAG_WRITE) != 0);
+
+ /*
+ * Don't stop the DMA if the device deasserts DMARQ. Many
+ * compact flashes deassert DMARQ for a short time between
+ * sectors. Instead of stopping and restarting the DMA, we'll
+ * let the hardware do it. If the DMA is really stopped early
+ * due to an error condition, a later timeout will force us to
+ * stop.
+ */
+ mio_boot_dma_cfg.s.clr = 0;
+
+ /* Size is specified in 16bit words and minus one notation */
+ mio_boot_dma_cfg.s.size = sg_dma_len(sg) / 2 - 1;
+
+ /* We need to swap the high and low bytes of every 16 bits */
+ mio_boot_dma_cfg.s.swap8 = 1;
+
+ mio_boot_dma_cfg.s.adr = sg_dma_address(sg);
+
+ VPRINTK("%s %d bytes address=%p\n",
+ (mio_boot_dma_cfg.s.rw) ? "write" : "read", sg->length,
+ (void *)(unsigned long)mio_boot_dma_cfg.s.adr);
+
+ cvmx_write_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine),
+ mio_boot_dma_cfg.u64);
+}
+
+/**
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ *
+ */
+static unsigned int octeon_cf_dma_finished(struct ata_port *ap,
+ struct ata_queued_cmd *qc)
+{
+ struct ata_eh_info *ehi = &ap->link.eh_info;
+ struct octeon_cf_data *ocd = ap->dev->platform_data;
+ union cvmx_mio_boot_dma_cfgx dma_cfg;
+ union cvmx_mio_boot_dma_intx dma_int;
+ struct octeon_cf_port *cf_port;
+ u8 status;
+
+ VPRINTK("ata%u: protocol %d task_state %d\n",
+ ap->print_id, qc->tf.protocol, ap->hsm_task_state);
+
+
+ if (ap->hsm_task_state != HSM_ST_LAST)
+ return 0;
+
+ cf_port = (struct octeon_cf_port *)ap->private_data;
+
+ dma_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine));
+ if (dma_cfg.s.size != 0xfffff) {
+ /* Error, the transfer was not complete. */
+ qc->err_mask |= AC_ERR_HOST_BUS;
+ ap->hsm_task_state = HSM_ST_ERR;
+ }
+
+ /* Stop and clear the dma engine. */
+ dma_cfg.u64 = 0;
+ dma_cfg.s.size = -1;
+ cvmx_write_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine), dma_cfg.u64);
+
+ /* Disable the interrupt. */
+ dma_int.u64 = 0;
+ cvmx_write_csr(CVMX_MIO_BOOT_DMA_INT_ENX(ocd->dma_engine), dma_int.u64);
+
+ /* Clear the DMA complete status */
+ dma_int.s.done = 1;
+ cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine), dma_int.u64);
+
+ status = ap->ops->sff_check_status(ap);
+
+ ata_sff_hsm_move(ap, qc, status, 0);
+
+ if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA))
+ ata_ehi_push_desc(ehi, "DMA stat 0x%x", status);
+
+ return 1;
+}
+
+/*
+ * Check if any queued commands have more DMAs, if so start the next
+ * transfer, else do end of transfer handling.
+ */
+static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ struct octeon_cf_port *cf_port;
+ int i;
+ unsigned int handled = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ DPRINTK("ENTER\n");
+ for (i = 0; i < host->n_ports; i++) {
+ u8 status;
+ struct ata_port *ap;
+ struct ata_queued_cmd *qc;
+ union cvmx_mio_boot_dma_intx dma_int;
+ union cvmx_mio_boot_dma_cfgx dma_cfg;
+ struct octeon_cf_data *ocd;
+
+ ap = host->ports[i];
+ ocd = ap->dev->platform_data;
+ if (!ap || (ap->flags & ATA_FLAG_DISABLED))
+ continue;
+
+ ocd = ap->dev->platform_data;
+ cf_port = (struct octeon_cf_port *)ap->private_data;
+ dma_int.u64 =
+ cvmx_read_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine));
+ dma_cfg.u64 =
+ cvmx_read_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine));
+
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+
+ if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
+ (qc->flags & ATA_QCFLAG_ACTIVE)) {
+ if (dma_int.s.done && !dma_cfg.s.en) {
+ if (!sg_is_last(qc->cursg)) {
+ qc->cursg = sg_next(qc->cursg);
+ handled = 1;
+ octeon_cf_dma_start(qc);
+ continue;
+ } else {
+ cf_port->dma_finished = 1;
+ }
+ }
+ if (!cf_port->dma_finished)
+ continue;
+ status = ioread8(ap->ioaddr.altstatus_addr);
+ if (status & (ATA_BUSY | ATA_DRQ)) {
+ /*
+ * We are busy, try to handle it
+ * later. This is the DMA finished
+ * interrupt, and it could take a
+ * little while for the card to be
+ * ready for more commands.
+ */
+ /* Clear DMA irq. */
+ dma_int.u64 = 0;
+ dma_int.s.done = 1;
+ cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine),
+ dma_int.u64);
+
+ queue_delayed_work(cf_port->wq,
+ &cf_port->delayed_finish, 1);
+ handled = 1;
+ } else {
+ handled |= octeon_cf_dma_finished(ap, qc);
+ }
+ }
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
+ DPRINTK("EXIT\n");
+ return IRQ_RETVAL(handled);
+}
+
+static void octeon_cf_delayed_finish(struct work_struct *work)
+{
+ struct octeon_cf_port *cf_port = container_of(work,
+ struct octeon_cf_port,
+ delayed_finish.work);
+ struct ata_port *ap = cf_port->ap;
+ struct ata_host *host = ap->host;
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ u8 status;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ /*
+ * If the port is not waiting for completion, it must have
+ * handled it previously. The hsm_task_state is
+ * protected by host->lock.
+ */
+ if (ap->hsm_task_state != HSM_ST_LAST || !cf_port->dma_finished)
+ goto out;
+
+ status = ioread8(ap->ioaddr.altstatus_addr);
+ if (status & (ATA_BUSY | ATA_DRQ)) {
+ /* Still busy, try again. */
+ queue_delayed_work(cf_port->wq,
+ &cf_port->delayed_finish, 1);
+ goto out;
+ }
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
+ (qc->flags & ATA_QCFLAG_ACTIVE))
+ octeon_cf_dma_finished(ap, qc);
+out:
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void octeon_cf_dev_config(struct ata_device *dev)
+{
+ /*
+ * A maximum of 2^20 - 1 16 bit transfers are possible with
+ * the bootbus DMA. So we need to throttle max_sectors to
+ * (2^12 - 1 == 4095) to assure that this can never happen.
+ */
+ dev->max_sectors = min(dev->max_sectors, 4095U);
+}
+
+/*
+ * Trap if driver tries to do standard bmdma commands. They are not
+ * supported.
+ */
+static void unreachable_qc(struct ata_queued_cmd *qc)
+{
+ BUG();
+}
+
+static u8 unreachable_port(struct ata_port *ap)
+{
+ BUG();
+}
+
+/*
+ * We don't do ATAPI DMA so return 0.
+ */
+static int octeon_cf_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ return 0;
+}
+
+static unsigned int octeon_cf_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_DMA:
+ WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+
+ ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */
+ octeon_cf_dma_setup(qc); /* set up dma */
+ octeon_cf_dma_start(qc); /* initiate dma */
+ ap->hsm_task_state = HSM_ST_LAST;
+ break;
+
+ case ATAPI_PROT_DMA:
+ dev_err(ap->dev, "Error, ATAPI not supported\n");
+ BUG();
+
+ default:
+ return ata_sff_qc_issue(qc);
+ }
+
+ return 0;
+}
+
+static struct ata_port_operations octeon_cf_ops = {
+ .inherits = &ata_sff_port_ops,
+ .check_atapi_dma = octeon_cf_check_atapi_dma,
+ .qc_prep = ata_noop_qc_prep,
+ .qc_issue = octeon_cf_qc_issue,
+ .sff_dev_select = octeon_cf_dev_select,
+ .sff_irq_on = octeon_cf_irq_on,
+ .sff_irq_clear = octeon_cf_irq_clear,
+ .bmdma_setup = unreachable_qc,
+ .bmdma_start = unreachable_qc,
+ .bmdma_stop = unreachable_qc,
+ .bmdma_status = unreachable_port,
+ .cable_detect = ata_cable_40wire,
+ .set_piomode = octeon_cf_set_piomode,
+ .set_dmamode = octeon_cf_set_dmamode,
+ .dev_config = octeon_cf_dev_config,
+};
+
+static int __devinit octeon_cf_probe(struct platform_device *pdev)
+{
+ struct resource *res_cs0, *res_cs1;
+
+ void __iomem *cs0;
+ void __iomem *cs1 = NULL;
+ struct ata_host *host;
+ struct ata_port *ap;
+ struct octeon_cf_data *ocd;
+ int irq = 0;
+ irq_handler_t irq_handler = NULL;
+ void __iomem *base;
+ struct octeon_cf_port *cf_port;
+
+ res_cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res_cs0)
+ return -EINVAL;
+
+ ocd = pdev->dev.platform_data;
+
+ cs0 = devm_ioremap_nocache(&pdev->dev, res_cs0->start,
+ res_cs0->end - res_cs0->start + 1);
+
+ if (!cs0)
+ return -ENOMEM;
+
+ /* Determine from availability of DMA if True IDE mode or not */
+ if (ocd->dma_engine >= 0) {
+ res_cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res_cs1)
+ return -EINVAL;
+
+ cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start,
+ res_cs0->end - res_cs1->start + 1);
+
+ if (!cs1)
+ return -ENOMEM;
+ }
+
+ cf_port = kzalloc(sizeof(*cf_port), GFP_KERNEL);
+ if (!cf_port)
+ return -ENOMEM;
+
+ /* allocate host */
+ host = ata_host_alloc(&pdev->dev, 1);
+ if (!host)
+ goto free_cf_port;
+
+ ap = host->ports[0];
+ ap->private_data = cf_port;
+ cf_port->ap = ap;
+ ap->ops = &octeon_cf_ops;
+ ap->pio_mask = ATA_PIO6;
+ ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
+ | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING;
+
+ base = cs0 + ocd->base_region_bias;
+ if (!ocd->is16bit) {
+ ap->ioaddr.cmd_addr = base;
+ ata_sff_std_ports(&ap->ioaddr);
+
+ ap->ioaddr.altstatus_addr = base + 0xe;
+ ap->ioaddr.ctl_addr = base + 0xe;
+ octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer8;
+ } else if (cs1) {
+ /* Presence of cs1 indicates True IDE mode. */
+ ap->ioaddr.cmd_addr = base + (ATA_REG_CMD << 1) + 1;
+ ap->ioaddr.data_addr = base + (ATA_REG_DATA << 1);
+ ap->ioaddr.error_addr = base + (ATA_REG_ERR << 1) + 1;
+ ap->ioaddr.feature_addr = base + (ATA_REG_FEATURE << 1) + 1;
+ ap->ioaddr.nsect_addr = base + (ATA_REG_NSECT << 1) + 1;
+ ap->ioaddr.lbal_addr = base + (ATA_REG_LBAL << 1) + 1;
+ ap->ioaddr.lbam_addr = base + (ATA_REG_LBAM << 1) + 1;
+ ap->ioaddr.lbah_addr = base + (ATA_REG_LBAH << 1) + 1;
+ ap->ioaddr.device_addr = base + (ATA_REG_DEVICE << 1) + 1;
+ ap->ioaddr.status_addr = base + (ATA_REG_STATUS << 1) + 1;
+ ap->ioaddr.command_addr = base + (ATA_REG_CMD << 1) + 1;
+ ap->ioaddr.altstatus_addr = cs1 + (6 << 1) + 1;
+ ap->ioaddr.ctl_addr = cs1 + (6 << 1) + 1;
+ octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16;
+
+ ap->mwdma_mask = ATA_MWDMA4;
+ irq = platform_get_irq(pdev, 0);
+ irq_handler = octeon_cf_interrupt;
+
+ /* True IDE mode needs delayed work to poll for not-busy. */
+ cf_port->wq = create_singlethread_workqueue(DRV_NAME);
+ if (!cf_port->wq)
+ goto free_cf_port;
+ INIT_DELAYED_WORK(&cf_port->delayed_finish,
+ octeon_cf_delayed_finish);
+
+ } else {
+ /* 16 bit but not True IDE */
+ octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16;
+ octeon_cf_ops.softreset = octeon_cf_softreset16;
+ octeon_cf_ops.sff_check_status = octeon_cf_check_status16;
+ octeon_cf_ops.sff_tf_read = octeon_cf_tf_read16;
+ octeon_cf_ops.sff_tf_load = octeon_cf_tf_load16;
+ octeon_cf_ops.sff_exec_command = octeon_cf_exec_command16;
+
+ ap->ioaddr.data_addr = base + ATA_REG_DATA;
+ ap->ioaddr.nsect_addr = base + ATA_REG_NSECT;
+ ap->ioaddr.lbal_addr = base + ATA_REG_LBAL;
+ ap->ioaddr.ctl_addr = base + 0xe;
+ ap->ioaddr.altstatus_addr = base + 0xe;
+ }
+
+ ata_port_desc(ap, "cmd %p ctl %p", base, ap->ioaddr.ctl_addr);
+
+
+ dev_info(&pdev->dev, "version " DRV_VERSION" %d bit%s.\n",
+ (ocd->is16bit) ? 16 : 8,
+ (cs1) ? ", True IDE" : "");
+
+
+ return ata_host_activate(host, irq, irq_handler, 0, &octeon_cf_sht);
+
+free_cf_port:
+ kfree(cf_port);
+ return -ENOMEM;
+}
+
+static struct platform_driver octeon_cf_driver = {
+ .probe = octeon_cf_probe,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init octeon_cf_init(void)
+{
+ return platform_driver_register(&octeon_cf_driver);
+}
+
+
+MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
+MODULE_DESCRIPTION("low-level driver for Cavium OCTEON Compact Flash PATA");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:" DRV_NAME);
+
+module_init(octeon_cf_init);
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 2c1a91c40c1..84ac5033ac8 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -238,8 +238,8 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma1-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &oldpiix_pata_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index e4fa4d565e9..99eddda2d2e 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -163,7 +163,7 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &opti_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 93bb6e91973..86885a445f9 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -399,15 +399,15 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_82c700 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &optidma_port_ops
};
static const struct ata_port_info info_82c700_udma = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &optiplus_port_ops
};
const struct ata_port_info *ppi[] = { &info_82c700, NULL };
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 64b2e2281ee..f4d009ed50a 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -42,7 +42,7 @@
#define DRV_NAME "pata_pcmcia"
-#define DRV_VERSION "0.3.3"
+#define DRV_VERSION "0.3.5"
/*
* Private data structure to glue stuff together
@@ -126,6 +126,37 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev,
return buflen;
}
+/**
+ * pcmcia_8bit_drain_fifo - Stock FIFO drain logic for SFF controllers
+ * @qc: command
+ *
+ * Drain the FIFO and device of any stuck data following a command
+ * failing to complete. In some cases this is neccessary before a
+ * reset will recover the device.
+ *
+ */
+
+void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc)
+{
+ int count;
+ struct ata_port *ap;
+
+ /* We only need to flush incoming data when a command was running */
+ if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+ return;
+
+ ap = qc->ap;
+
+ /* Drain up to 64K of data before we give up this recovery method */
+ for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
+ && count++ < 65536;)
+ ioread8(ap->ioaddr.data_addr);
+
+ if (count)
+ ata_port_printk(ap, KERN_WARNING, "drained %d bytes to clear DRQ.\n",
+ count);
+
+}
static struct scsi_host_template pcmcia_sht = {
ATA_PIO_SHT(DRV_NAME),
@@ -143,6 +174,7 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
.sff_data_xfer = ata_data_xfer_8bit,
.cable_detect = ata_cable_40wire,
.set_mode = pcmcia_set_mode_8bit,
+ .drain_fifo = pcmcia_8bit_drain_fifo,
};
#define CS_CHECK(fn, ret) \
@@ -299,7 +331,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
ap = host->ports[p];
ap->ops = ops;
- ap->pio_mask = 1; /* ISA so PIO 0 cycles */
+ ap->pio_mask = ATA_PIO0; /* ISA so PIO 0 cycles */
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = io_addr + 0x10 * p;
ap->ioaddr.altstatus_addr = ctl_addr + 0x10 * p;
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index e94efccaa48..ca5cad0fd80 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -152,18 +152,18 @@ static struct ata_port_info pdc2027x_port_info[] = {
{
.flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
ATA_FLAG_MMIO,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &pdc2027x_pata100_ops,
},
/* PDC_UDMA_133 */
{
.flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
ATA_FLAG_MMIO,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA6, /* udma0-6 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc2027x_pata133_ops,
},
};
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 799a6a09871..5fedb3d4032 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -291,22 +291,22 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
static const struct ata_port_info info[3] = {
{
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &pdc2024x_port_ops
},
{
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &pdc2026x_port_ops
},
{
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &pdc2026x_port_ops
}
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 3080f371222..45879dc6fa4 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -12,7 +12,7 @@
*
* Probe code based on drivers/ide/legacy/qd65xx.c
* Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
*/
#include <linux/kernel.h>
@@ -212,11 +212,11 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
if (type == 6580) {
ap->ops = &qdi6580_port_ops;
- ap->pio_mask = 0x1F;
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
} else {
ap->ops = &qdi6500_port_ops;
- ap->pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */
+ ap->pio_mask = ATA_PIO2; /* Actually PIO3 !IORDY is possible */
ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
}
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 695d44ae52c..4401b332eaa 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -216,9 +216,9 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma1-2 */
- .udma_mask = 0x14, /* UDMA33/66 only */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY,
+ .udma_mask = ATA_UDMA24_ONLY,
.port_ops = &radisys_pata_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c
index c2e6fb9f2ef..8e3cdef8a25 100644
--- a/drivers/ata/pata_rb532_cf.c
+++ b/drivers/ata/pata_rb532_cf.c
@@ -48,65 +48,11 @@
struct rb532_cf_info {
void __iomem *iobase;
unsigned int gpio_line;
- int frozen;
unsigned int irq;
};
/* ------------------------------------------------------------------------ */
-static inline void rb532_pata_finish_io(struct ata_port *ap)
-{
- struct ata_host *ah = ap->host;
- struct rb532_cf_info *info = ah->private_data;
-
- /* FIXME: Keep previous delay. If this is merely a fence then
- ata_sff_sync might be sufficient. */
- ata_sff_dma_pause(ap);
- ndelay(RB500_CF_IO_DELAY);
-
- set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
-}
-
-static void rb532_pata_exec_command(struct ata_port *ap,
- const struct ata_taskfile *tf)
-{
- writeb(tf->command, ap->ioaddr.command_addr);
- rb532_pata_finish_io(ap);
-}
-
-static unsigned int rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
-{
- struct ata_port *ap = adev->link->ap;
- void __iomem *ioaddr = ap->ioaddr.data_addr;
- int retlen = buflen;
-
- if (write_data) {
- for (; buflen > 0; buflen--, buf++)
- writeb(*buf, ioaddr);
- } else {
- for (; buflen > 0; buflen--, buf++)
- *buf = readb(ioaddr);
- }
-
- rb532_pata_finish_io(adev->link->ap);
- return retlen;
-}
-
-static void rb532_pata_freeze(struct ata_port *ap)
-{
- struct rb532_cf_info *info = ap->host->private_data;
-
- info->frozen = 1;
-}
-
-static void rb532_pata_thaw(struct ata_port *ap)
-{
- struct rb532_cf_info *info = ap->host->private_data;
-
- info->frozen = 0;
-}
-
static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
{
struct ata_host *ah = dev_instance;
@@ -114,8 +60,7 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
if (gpio_get_value(info->gpio_line)) {
set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
- if (!info->frozen)
- ata_sff_interrupt(info->irq, dev_instance);
+ ata_sff_interrupt(info->irq, dev_instance);
} else {
set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
}
@@ -125,10 +70,7 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
static struct ata_port_operations rb532_pata_port_ops = {
.inherits = &ata_sff_port_ops,
- .sff_exec_command = rb532_pata_exec_command,
- .sff_data_xfer = rb532_pata_data_xfer,
- .freeze = rb532_pata_freeze,
- .thaw = rb532_pata_thaw,
+ .sff_data_xfer = ata_sff_data_xfer32,
};
/* ------------------------------------------------------------------------ */
@@ -147,7 +89,7 @@ static void rb532_pata_setup_ports(struct ata_host *ah)
ap = ah->ports[0];
ap->ops = &rb532_pata_port_ops;
- ap->pio_mask = 0x1f; /* PIO4 */
+ ap->pio_mask = ATA_PIO4;
ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO;
ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_BASE;
@@ -162,7 +104,7 @@ static void rb532_pata_setup_ports(struct ata_host *ah)
static __devinit int rb532_pata_driver_probe(struct platform_device *pdev)
{
- unsigned int irq;
+ int irq;
int gpio;
struct resource *res;
struct ata_host *ah;
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 46d6bc1bf1e..0c574c065c6 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -88,7 +88,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &rz1000_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 9a4bdca5461..f49814d6fd2 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -2,7 +2,6 @@
* New ATA layer SC1200 driver Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* TODO: Mode selection filtering
- * TODO: Can't enable second channel until ATA core has serialize
* TODO: Needs custom DMA cleanup code
*
* Based very heavily on
@@ -178,6 +177,31 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
return ata_sff_qc_issue(qc);
}
+/**
+ * sc1200_qc_defer - implement serialization
+ * @qc: command
+ *
+ * Serialize command issue on this controller.
+ */
+
+static int sc1200_qc_defer(struct ata_queued_cmd *qc)
+{
+ struct ata_host *host = qc->ap->host;
+ struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
+ int rc;
+
+ /* First apply the usual rules */
+ rc = ata_std_qc_defer(qc);
+ if (rc != 0)
+ return rc;
+
+ /* Now apply serialization rules. Only allow a command if the
+ other channel state machine is idle */
+ if (alt && alt->qc_active)
+ return ATA_DEFER_PORT;
+ return 0;
+}
+
static struct scsi_host_template sc1200_sht = {
ATA_BMDMA_SHT(DRV_NAME),
.sg_tablesize = LIBATA_DUMB_MAX_PRD,
@@ -187,6 +211,7 @@ static struct ata_port_operations sc1200_port_ops = {
.inherits = &ata_bmdma_port_ops,
.qc_prep = ata_sff_dumb_qc_prep,
.qc_issue = sc1200_qc_issue,
+ .qc_defer = sc1200_qc_defer,
.cable_detect = ata_cable_40wire,
.set_piomode = sc1200_set_piomode,
.set_dmamode = sc1200_set_dmamode,
@@ -205,13 +230,13 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &sc1200_port_ops
};
/* Can't enable port 2 yet, see top comments */
- const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
+ const struct ata_port_info *ppi[] = { &info, };
return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
}
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index d447f1cb46e..4257d6b40af 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -1001,8 +1001,8 @@ static struct ata_port_operations scc_pata_ops = {
static struct ata_port_info scc_port_info[] = {
{
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x00,
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &scc_pata_ops,
},
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c
index 6aeeeeb3412..99cceb458e2 100644
--- a/drivers/ata/pata_sch.c
+++ b/drivers/ata/pata_sch.c
@@ -84,9 +84,9 @@ static struct ata_port_operations sch_pata_ops = {
static struct ata_port_info sch_port_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = ATA_PIO4, /* pio0-4 */
- .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sch_pata_ops,
};
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index 8d2fd9dd40c..beaed12d50e 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -398,26 +398,26 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
static const struct ata_port_info info[4] = {
{ /* OSB4 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &serverworks_osb4_port_ops
}, { /* OSB4 no UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x00,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ /* No UDMA */
.port_ops = &serverworks_osb4_port_ops
}, { /* CSB5 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &serverworks_csb_port_ops
}, { /* CSB5 - later revisions*/
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &serverworks_csb_port_ops
}
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 9e764e5747e..4cb649d8d38 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -282,15 +282,15 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &sil680_port_ops
};
static const struct ata_port_info info_slow = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil680_port_ops
};
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 27ceb42a774..488e77bcd22 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -552,51 +552,57 @@ static struct ata_port_operations sis_old_ops = {
static const struct ata_port_info sis_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07,
- .udma_mask = 0,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ /* No UDMA */
.port_ops = &sis_old_ops,
};
static const struct ata_port_info sis_info33 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA2, /* UDMA 33 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &sis_old_ops,
};
static const struct ata_port_info sis_info66 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = ATA_UDMA4, /* UDMA 66 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
+ .udma_mask = ATA_UDMA4,
.port_ops = &sis_66_ops,
};
static const struct ata_port_info sis_info100 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA5,
.port_ops = &sis_100_ops,
};
static const struct ata_port_info sis_info100_early = {
.flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA5,
- .pio_mask = 0x1f, /* pio0-4 */
.port_ops = &sis_66_ops,
};
static const struct ata_port_info sis_info133 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_ops,
};
const struct ata_port_info sis_info133_for_sata = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_for_sata_ops,
};
static const struct ata_port_info sis_info133_early = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_early_ops,
};
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index 1b0e7b6d8ef..29f733c3206 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -283,13 +283,13 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
{
static const struct ata_port_info info_dma = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &sl82c105_port_ops
};
static const struct ata_port_info info_early = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &sl82c105_port_ops
};
/* for now use only the first port */
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index ef9597517cd..f1f13ff222f 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -191,8 +191,8 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &triflex_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 681169c9c64..b08e6e0f82b 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -86,6 +86,10 @@ enum {
VIA_SATA_PATA = 0x800, /* SATA/PATA combined configuration */
};
+enum {
+ VIA_IDFLAG_SINGLE = (1 << 0), /* single channel controller) */
+};
+
/*
* VIA SouthBridge chips.
*/
@@ -97,12 +101,17 @@ static const struct via_isa_bridge {
u8 rev_max;
u16 flags;
} via_isa_bridges[] = {
+ { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
{ "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 |
VIA_BAD_AST | VIA_SATA_PATA },
+ { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
- { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
+ { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
+ { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
{ "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -122,6 +131,8 @@ static const struct via_isa_bridge {
{ "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
+ { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST },
{ NULL }
};
@@ -411,46 +422,46 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Early VIA without UDMA support */
static const struct ata_port_info via_mwdma_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &via_port_ops
};
/* Ditto with IRQ masking required */
static const struct ata_port_info via_mwdma_info_borked = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &via_port_ops_noirq,
};
/* VIA UDMA 33 devices (and borked 66) */
static const struct ata_port_info via_udma33_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &via_port_ops
};
/* VIA UDMA 66 devices */
static const struct ata_port_info via_udma66_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &via_port_ops
};
/* VIA UDMA 100 devices */
static const struct ata_port_info via_udma100_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &via_port_ops
};
/* UDMA133 with bad AST (All current 133) */
static const struct ata_port_info via_udma133_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */
.port_ops = &via_port_ops
};
@@ -460,6 +471,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version;
u8 enable;
u32 timing;
+ unsigned long flags = id->driver_data;
int rc;
if (!printed_version++)
@@ -469,9 +481,13 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
+ if (flags & VIA_IDFLAG_SINGLE)
+ ppi[1] = &ata_dummy_port_info;
+
/* To find out how the IDE will behave and what features we
actually have to look at the bridge not the IDE controller */
- for (config = via_isa_bridges; config->id; config++)
+ for (config = via_isa_bridges; config->id != PCI_DEVICE_ID_VIA_ANON;
+ config++)
if ((isa = pci_get_device(PCI_VENDOR_ID_VIA +
!!(config->flags & VIA_BAD_ID),
config->id, NULL))) {
@@ -482,10 +498,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_dev_put(isa);
}
- if (!config->id) {
- printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n");
- return -ENODEV;
- }
pci_dev_put(isa);
if (!(config->flags & VIA_NO_ENABLES)) {
@@ -582,11 +594,13 @@ static int via_reinit_one(struct pci_dev *pdev)
#endif
static const struct pci_device_id via[] = {
+ { PCI_VDEVICE(VIA, 0x0415), },
{ PCI_VDEVICE(VIA, 0x0571), },
{ PCI_VDEVICE(VIA, 0x0581), },
{ PCI_VDEVICE(VIA, 0x1571), },
{ PCI_VDEVICE(VIA, 0x3164), },
{ PCI_VDEVICE(VIA, 0x5324), },
+ { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE },
{ },
};
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 319e164a3d7..6d8619b6f67 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -193,7 +193,7 @@ static __init int winbond_init_one(unsigned long port)
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port);
ap->ops = &winbond_port_ops;
- ap->pio_mask = 0x1F;
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = cmd_addr;
ap->ioaddr.altstatus_addr = ctl_addr;
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index be53545c9f6..39588178d02 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -148,6 +148,8 @@ static struct scsi_host_template adma_ata_sht = {
static struct ata_port_operations adma_ata_ops = {
.inherits = &ata_sff_port_ops,
+ .lost_interrupt = ATA_OP_NULL,
+
.check_atapi_dma = adma_check_atapi_dma,
.qc_prep = adma_qc_prep,
.qc_issue = adma_qc_issue,
@@ -166,7 +168,7 @@ static struct ata_port_info adma_port_info[] = {
.flags = ATA_FLAG_SLAVE_POSS |
ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
ATA_FLAG_PIO_POLLING,
- .pio_mask = 0x10, /* pio4 */
+ .pio_mask = ATA_PIO4_ONLY,
.udma_mask = ATA_UDMA4,
.port_ops = &adma_ata_ops,
},
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 1a56db92ff7..c2e90e1fece 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -1279,8 +1279,8 @@ static struct ata_port_operations sata_fsl_ops = {
static const struct ata_port_info sata_fsl_port_info[] = {
{
.flags = SATA_FSL_HOST_FLAGS,
- .pio_mask = 0x1f, /* pio 0-4 */
- .udma_mask = 0x7f, /* udma 0-6 */
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
.port_ops = &sata_fsl_ops,
},
};
@@ -1288,7 +1288,7 @@ static const struct ata_port_info sata_fsl_port_info[] = {
static int sata_fsl_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
- int retval = 0;
+ int retval = -ENXIO;
void __iomem *hcr_base = NULL;
void __iomem *ssr_base = NULL;
void __iomem *csr_base = NULL;
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index fbbd87c96f1..305a4f825f5 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -744,8 +744,8 @@ static struct ata_port_operations inic_port_ops = {
static struct ata_port_info inic_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &inic_port_ops
};
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 86918634a4c..a377226b81c 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1,10 +1,13 @@
/*
* sata_mv.c - Marvell SATA support
*
- * Copyright 2008: Marvell Corporation, all rights reserved.
+ * Copyright 2008-2009: Marvell Corporation, all rights reserved.
* Copyright 2005: EMC Corporation, all rights reserved.
* Copyright 2005 Red Hat, Inc. All rights reserved.
*
+ * Originally written by Brett Russ.
+ * Extensive overhaul and enhancement by Mark Lord <mlord@pobox.com>.
+ *
* Please ALWAYS copy linux-ide@vger.kernel.org on emails.
*
* This program is free software; you can redistribute it and/or modify
@@ -25,24 +28,13 @@
/*
* sata_mv TODO list:
*
- * --> Errata workaround for NCQ device errors.
- *
* --> More errata workarounds for PCI-X.
*
* --> Complete a full errata audit for all chipsets to identify others.
*
- * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it).
- *
- * --> Investigate problems with PCI Message Signalled Interrupts (MSI).
- *
- * --> Cache frequently-accessed registers in mv_port_priv to reduce overhead.
- *
* --> Develop a low-power-consumption strategy, and implement it.
*
- * --> [Experiment, low priority] Investigate interrupt coalescing.
- * Quite often, especially with PCI Message Signalled Interrupts (MSI),
- * the overhead reduced by interrupt mitigation is quite often not
- * worth the latency cost.
+ * --> Add sysfs attributes for per-chip / per-HC IRQ coalescing thresholds.
*
* --> [Experiment, Marvell value added] Is it possible to use target
* mode to cross-connect two Linux boxes with Marvell cards? If so,
@@ -72,7 +64,27 @@
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "1.24"
+#define DRV_VERSION "1.27"
+
+/*
+ * module options
+ */
+
+static int msi;
+#ifdef CONFIG_PCI
+module_param(msi, int, S_IRUGO);
+MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
+#endif
+
+static int irq_coalescing_io_count;
+module_param(irq_coalescing_io_count, int, S_IRUGO);
+MODULE_PARM_DESC(irq_coalescing_io_count,
+ "IRQ coalescing I/O count threshold (0..255)");
+
+static int irq_coalescing_usecs;
+module_param(irq_coalescing_usecs, int, S_IRUGO);
+MODULE_PARM_DESC(irq_coalescing_usecs,
+ "IRQ coalescing time threshold in usecs");
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -83,13 +95,32 @@ enum {
MV_MAJOR_REG_AREA_SZ = 0x10000, /* 64KB */
MV_MINOR_REG_AREA_SZ = 0x2000, /* 8KB */
+ /* For use with both IRQ coalescing methods ("all ports" or "per-HC" */
+ COAL_CLOCKS_PER_USEC = 150, /* for calculating COAL_TIMEs */
+ MAX_COAL_TIME_THRESHOLD = ((1 << 24) - 1), /* internal clocks count */
+ MAX_COAL_IO_COUNT = 255, /* completed I/O count */
+
MV_PCI_REG_BASE = 0,
- MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */
- MV_IRQ_COAL_CAUSE = (MV_IRQ_COAL_REG_BASE + 0x08),
- MV_IRQ_COAL_CAUSE_LO = (MV_IRQ_COAL_REG_BASE + 0x88),
- MV_IRQ_COAL_CAUSE_HI = (MV_IRQ_COAL_REG_BASE + 0x8c),
- MV_IRQ_COAL_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xcc),
- MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0),
+
+ /*
+ * Per-chip ("all ports") interrupt coalescing feature.
+ * This is only for GEN_II / GEN_IIE hardware.
+ *
+ * Coalescing defers the interrupt until either the IO_THRESHOLD
+ * (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
+ */
+ MV_COAL_REG_BASE = 0x18000,
+ MV_IRQ_COAL_CAUSE = (MV_COAL_REG_BASE + 0x08),
+ ALL_PORTS_COAL_IRQ = (1 << 4), /* all ports irq event */
+
+ MV_IRQ_COAL_IO_THRESHOLD = (MV_COAL_REG_BASE + 0xcc),
+ MV_IRQ_COAL_TIME_THRESHOLD = (MV_COAL_REG_BASE + 0xd0),
+
+ /*
+ * Registers for the (unused here) transaction coalescing feature:
+ */
+ MV_TRAN_COAL_CAUSE_LO = (MV_COAL_REG_BASE + 0x88),
+ MV_TRAN_COAL_CAUSE_HI = (MV_COAL_REG_BASE + 0x8c),
MV_SATAHC0_REG_BASE = 0x20000,
MV_FLASH_CTL_OFS = 0x1046c,
@@ -121,17 +152,16 @@ enum {
/* Host Flags */
MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */
- MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
- ATA_FLAG_PIO_POLLING,
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
- MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE,
+ MV_GEN_I_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NO_ATAPI,
- MV_GENIIE_FLAGS = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ | ATA_FLAG_AN,
+ MV_GEN_II_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NCQ |
+ ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA,
+
+ MV_GEN_IIE_FLAGS = MV_GEN_II_FLAGS | ATA_FLAG_AN,
CRQB_FLAG_READ = (1 << 0),
CRQB_TAG_SHIFT = 1,
@@ -184,16 +214,18 @@ enum {
PCI_HC_MAIN_IRQ_MASK_OFS = 0x1d64,
SOC_HC_MAIN_IRQ_CAUSE_OFS = 0x20020,
SOC_HC_MAIN_IRQ_MASK_OFS = 0x20024,
- ERR_IRQ = (1 << 0), /* shift by port # */
- DONE_IRQ = (1 << 1), /* shift by port # */
+ ERR_IRQ = (1 << 0), /* shift by (2 * port #) */
+ DONE_IRQ = (1 << 1), /* shift by (2 * port #) */
HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */
HC_SHIFT = 9, /* bits 9-17 = HC1's ports */
+ DONE_IRQ_0_3 = 0x000000aa, /* DONE_IRQ ports 0,1,2,3 */
+ DONE_IRQ_4_7 = (DONE_IRQ_0_3 << HC_SHIFT), /* 4,5,6,7 */
PCI_ERR = (1 << 18),
- TRAN_LO_DONE = (1 << 19), /* 6xxx: IRQ coalescing */
- TRAN_HI_DONE = (1 << 20), /* 6xxx: IRQ coalescing */
- PORTS_0_3_COAL_DONE = (1 << 8),
- PORTS_4_7_COAL_DONE = (1 << 17),
- PORTS_0_7_COAL_DONE = (1 << 21), /* 6xxx: IRQ coalescing */
+ TRAN_COAL_LO_DONE = (1 << 19), /* transaction coalescing */
+ TRAN_COAL_HI_DONE = (1 << 20), /* transaction coalescing */
+ PORTS_0_3_COAL_DONE = (1 << 8), /* HC0 IRQ coalescing */
+ PORTS_4_7_COAL_DONE = (1 << 17), /* HC1 IRQ coalescing */
+ ALL_PORTS_COAL_DONE = (1 << 21), /* GEN_II(E) IRQ coalescing */
GPIO_INT = (1 << 22),
SELF_INT = (1 << 23),
TWSI_INT = (1 << 24),
@@ -209,6 +241,21 @@ enum {
HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */
DEV_IRQ = (1 << 8), /* shift by port # */
+ /*
+ * Per-HC (Host-Controller) interrupt coalescing feature.
+ * This is present on all chip generations.
+ *
+ * Coalescing defers the interrupt until either the IO_THRESHOLD
+ * (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
+ */
+ HC_IRQ_COAL_IO_THRESHOLD_OFS = 0x000c,
+ HC_IRQ_COAL_TIME_THRESHOLD_OFS = 0x0010,
+
+ SOC_LED_CTRL_OFS = 0x2c,
+ SOC_LED_CTRL_BLINK = (1 << 0), /* Active LED blink */
+ SOC_LED_CTRL_ACT_PRESENCE = (1 << 2), /* Multiplex dev presence */
+ /* with dev activity LED */
+
/* Shadow block registers */
SHD_BLK_OFS = 0x100,
SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */
@@ -350,8 +397,12 @@ enum {
EDMA_ARB_CFG_OFS = 0x38,
EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */
+ EDMA_UNKNOWN_RSVD_OFS = 0x6C, /* GenIIe unknown/reserved */
- GEN_II_NCQ_MAX_SECTORS = 256, /* max sects/io on Gen2 w/NCQ */
+ BMDMA_CMD_OFS = 0x224, /* bmdma command register */
+ BMDMA_STATUS_OFS = 0x228, /* bmdma status register */
+ BMDMA_PRD_LOW_OFS = 0x22c, /* bmdma PRD addr 31:0 */
+ BMDMA_PRD_HIGH_OFS = 0x230, /* bmdma PRD addr 63:32 */
/* Host private flags (hp_flags) */
MV_HP_FLAG_MSI = (1 << 0),
@@ -365,12 +416,14 @@ enum {
MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */
MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */
MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */
+ MV_HP_QUIRK_LED_BLINK_EN = (1 << 12), /* is led blinking enabled? */
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */
MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */
MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */
+ MV_PP_FLAG_FAKE_ATA_BUSY = (1 << 4), /* ignore initial ATA_DRDY */
};
#define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
@@ -439,6 +492,18 @@ struct mv_sg {
__le32 reserved;
};
+/*
+ * We keep a local cache of a few frequently accessed port
+ * registers here, to avoid having to read them (very slow)
+ * when switching between EDMA and non-EDMA modes.
+ */
+struct mv_cached_regs {
+ u32 fiscfg;
+ u32 ltmode;
+ u32 haltcond;
+ u32 unknown_rsvd;
+};
+
struct mv_port_priv {
struct mv_crqb *crqb;
dma_addr_t crqb_dma;
@@ -451,6 +516,7 @@ struct mv_port_priv {
unsigned int resp_idx;
u32 pp_flags;
+ struct mv_cached_regs cached;
unsigned int delayed_eh_pmp_map;
};
@@ -541,7 +607,7 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
static int mv_stop_edma(struct ata_port *ap);
static int mv_stop_edma_engine(void __iomem *port_mmio);
-static void mv_edma_cfg(struct ata_port *ap, int want_ncq);
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma);
static void mv_pmp_select(struct ata_port *ap, int pmp);
static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class,
@@ -552,6 +618,14 @@ static void mv_pmp_error_handler(struct ata_port *ap);
static void mv_process_crpb_entries(struct ata_port *ap,
struct mv_port_priv *pp);
+static void mv_sff_irq_clear(struct ata_port *ap);
+static int mv_check_atapi_dma(struct ata_queued_cmd *qc);
+static void mv_bmdma_setup(struct ata_queued_cmd *qc);
+static void mv_bmdma_start(struct ata_queued_cmd *qc);
+static void mv_bmdma_stop(struct ata_queued_cmd *qc);
+static u8 mv_bmdma_status(struct ata_port *ap);
+static u8 mv_sff_check_status(struct ata_port *ap);
+
/* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
* because we have to allow room for worst case splitting of
* PRDs for 64K boundaries in mv_fill_sg().
@@ -572,6 +646,8 @@ static struct scsi_host_template mv6_sht = {
static struct ata_port_operations mv5_ops = {
.inherits = &ata_sff_port_ops,
+ .lost_interrupt = ATA_OP_NULL,
+
.qc_defer = mv_qc_defer,
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
@@ -599,6 +675,14 @@ static struct ata_port_operations mv6_ops = {
.pmp_softreset = mv_softreset,
.softreset = mv_softreset,
.error_handler = mv_pmp_error_handler,
+
+ .sff_check_status = mv_sff_check_status,
+ .sff_irq_clear = mv_sff_irq_clear,
+ .check_atapi_dma = mv_check_atapi_dma,
+ .bmdma_setup = mv_bmdma_setup,
+ .bmdma_start = mv_bmdma_start,
+ .bmdma_stop = mv_bmdma_stop,
+ .bmdma_status = mv_bmdma_status,
};
static struct ata_port_operations mv_iie_ops = {
@@ -609,53 +693,49 @@ static struct ata_port_operations mv_iie_ops = {
static const struct ata_port_info mv_port_info[] = {
{ /* chip_504x */
- .flags = MV_COMMON_FLAGS,
+ .flags = MV_GEN_I_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_508x */
- .flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_5080 */
- .flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_604x */
- .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ,
+ .flags = MV_GEN_II_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_608x */
- .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_II_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_6042 */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_7042 */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_soc */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
@@ -669,8 +749,8 @@ static const struct pci_device_id mv_pci_tbl[] = {
{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
/* RocketRAID 1720/174x have different identifiers */
{ PCI_VDEVICE(TTI, 0x1720), chip_6042 },
- { PCI_VDEVICE(TTI, 0x1740), chip_508x },
- { PCI_VDEVICE(TTI, 0x1742), chip_508x },
+ { PCI_VDEVICE(TTI, 0x1740), chip_6042 },
+ { PCI_VDEVICE(TTI, 0x1742), chip_6042 },
{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
@@ -800,6 +880,44 @@ static inline int mv_get_hc_count(unsigned long port_flags)
return ((port_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
}
+/**
+ * mv_save_cached_regs - (re-)initialize cached port registers
+ * @ap: the port whose registers we are caching
+ *
+ * Initialize the local cache of port registers,
+ * so that reading them over and over again can
+ * be avoided on the hotter paths of this driver.
+ * This saves a few microseconds each time we switch
+ * to/from EDMA mode to perform (eg.) a drive cache flush.
+ */
+static void mv_save_cached_regs(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+
+ pp->cached.fiscfg = readl(port_mmio + FISCFG_OFS);
+ pp->cached.ltmode = readl(port_mmio + LTMODE_OFS);
+ pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+ pp->cached.unknown_rsvd = readl(port_mmio + EDMA_UNKNOWN_RSVD_OFS);
+}
+
+/**
+ * mv_write_cached_reg - write to a cached port register
+ * @addr: hardware address of the register
+ * @old: pointer to cached value of the register
+ * @new: new value for the register
+ *
+ * Write a new value to a cached register,
+ * but only if the value is different from before.
+ */
+static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new)
+{
+ if (new != *old) {
+ *old = new;
+ writel(new, addr);
+ }
+}
+
static void mv_set_edma_ptrs(void __iomem *port_mmio,
struct mv_host_priv *hpriv,
struct mv_port_priv *pp)
@@ -831,6 +949,23 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio,
port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
}
+static void mv_write_main_irq_mask(u32 mask, struct mv_host_priv *hpriv)
+{
+ /*
+ * When writing to the main_irq_mask in hardware,
+ * we must ensure exclusivity between the interrupt coalescing bits
+ * and the corresponding individual port DONE_IRQ bits.
+ *
+ * Note that this register is really an "IRQ enable" register,
+ * not an "IRQ mask" register as Marvell's naming might suggest.
+ */
+ if (mask & (ALL_PORTS_COAL_DONE | PORTS_0_3_COAL_DONE))
+ mask &= ~DONE_IRQ_0_3;
+ if (mask & (ALL_PORTS_COAL_DONE | PORTS_4_7_COAL_DONE))
+ mask &= ~DONE_IRQ_4_7;
+ writelfl(mask, hpriv->main_irq_mask_addr);
+}
+
static void mv_set_main_irq_mask(struct ata_host *host,
u32 disable_bits, u32 enable_bits)
{
@@ -841,7 +976,7 @@ static void mv_set_main_irq_mask(struct ata_host *host,
new_mask = (old_mask & ~disable_bits) | enable_bits;
if (new_mask != old_mask) {
hpriv->main_irq_mask = new_mask;
- writelfl(new_mask, hpriv->main_irq_mask_addr);
+ mv_write_main_irq_mask(new_mask, hpriv);
}
}
@@ -858,8 +993,94 @@ static void mv_enable_port_irqs(struct ata_port *ap,
mv_set_main_irq_mask(ap->host, disable_bits, enable_bits);
}
+static void mv_clear_and_enable_port_irqs(struct ata_port *ap,
+ void __iomem *port_mmio,
+ unsigned int port_irqs)
+{
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ int hardport = mv_hardport_from_port(ap->port_no);
+ void __iomem *hc_mmio = mv_hc_base_from_port(
+ mv_host_base(ap->host), ap->port_no);
+ u32 hc_irq_cause;
+
+ /* clear EDMA event indicators, if any */
+ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
+ /* clear pending irq events */
+ hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
+ writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+
+ /* clear FIS IRQ Cause */
+ if (IS_GEN_IIE(hpriv))
+ writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+
+ mv_enable_port_irqs(ap, port_irqs);
+}
+
+static void mv_set_irq_coalescing(struct ata_host *host,
+ unsigned int count, unsigned int usecs)
+{
+ struct mv_host_priv *hpriv = host->private_data;
+ void __iomem *mmio = hpriv->base, *hc_mmio;
+ u32 coal_enable = 0;
+ unsigned long flags;
+ unsigned int clks, is_dual_hc = hpriv->n_ports > MV_PORTS_PER_HC;
+ const u32 coal_disable = PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE |
+ ALL_PORTS_COAL_DONE;
+
+ /* Disable IRQ coalescing if either threshold is zero */
+ if (!usecs || !count) {
+ clks = count = 0;
+ } else {
+ /* Respect maximum limits of the hardware */
+ clks = usecs * COAL_CLOCKS_PER_USEC;
+ if (clks > MAX_COAL_TIME_THRESHOLD)
+ clks = MAX_COAL_TIME_THRESHOLD;
+ if (count > MAX_COAL_IO_COUNT)
+ count = MAX_COAL_IO_COUNT;
+ }
+
+ spin_lock_irqsave(&host->lock, flags);
+ mv_set_main_irq_mask(host, coal_disable, 0);
+
+ if (is_dual_hc && !IS_GEN_I(hpriv)) {
+ /*
+ * GEN_II/GEN_IIE with dual host controllers:
+ * one set of global thresholds for the entire chip.
+ */
+ writel(clks, mmio + MV_IRQ_COAL_TIME_THRESHOLD);
+ writel(count, mmio + MV_IRQ_COAL_IO_THRESHOLD);
+ /* clear leftover coal IRQ bit */
+ writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE);
+ if (count)
+ coal_enable = ALL_PORTS_COAL_DONE;
+ clks = count = 0; /* force clearing of regular regs below */
+ }
+
+ /*
+ * All chips: independent thresholds for each HC on the chip.
+ */
+ hc_mmio = mv_hc_base_from_port(mmio, 0);
+ writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS);
+ writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS);
+ writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS);
+ if (count)
+ coal_enable |= PORTS_0_3_COAL_DONE;
+ if (is_dual_hc) {
+ hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC);
+ writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS);
+ writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS);
+ writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS);
+ if (count)
+ coal_enable |= PORTS_4_7_COAL_DONE;
+ }
+
+ mv_set_main_irq_mask(host, 0, coal_enable);
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
/**
- * mv_start_dma - Enable eDMA engine
+ * mv_start_edma - Enable eDMA engine
* @base: port base address
* @pp: port private data
*
@@ -869,7 +1090,7 @@ static void mv_enable_port_irqs(struct ata_port *ap,
* LOCKING:
* Inherited from caller.
*/
-static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
+static void mv_start_edma(struct ata_port *ap, void __iomem *port_mmio,
struct mv_port_priv *pp, u8 protocol)
{
int want_ncq = (protocol == ATA_PROT_NCQ);
@@ -881,30 +1102,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
}
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
struct mv_host_priv *hpriv = ap->host->private_data;
- int hardport = mv_hardport_from_port(ap->port_no);
- void __iomem *hc_mmio = mv_hc_base_from_port(
- mv_host_base(ap->host), hardport);
- u32 hc_irq_cause, ipending;
-
- /* clear EDMA event indicators, if any */
- writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
-
- /* clear EDMA interrupt indicator, if any */
- hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
- ipending = (DEV_IRQ | DMA_IRQ) << hardport;
- if (hc_irq_cause & ipending) {
- writelfl(hc_irq_cause & ~ipending,
- hc_mmio + HC_IRQ_CAUSE_OFS);
- }
- mv_edma_cfg(ap, want_ncq);
-
- /* clear FIS IRQ Cause */
- if (IS_GEN_IIE(hpriv))
- writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+ mv_edma_cfg(ap, want_ncq, 1);
mv_set_edma_ptrs(port_mmio, hpriv, pp);
- mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ);
+ mv_clear_and_enable_port_irqs(ap, port_mmio, DONE_IRQ|ERR_IRQ);
writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
@@ -962,6 +1164,7 @@ static int mv_stop_edma(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
+ int err = 0;
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
return 0;
@@ -969,9 +1172,10 @@ static int mv_stop_edma(struct ata_port *ap)
mv_wait_for_edma_empty_idle(ap);
if (mv_stop_edma_engine(port_mmio)) {
ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
- return -EIO;
+ err = -EIO;
}
- return 0;
+ mv_edma_cfg(ap, 0, 0);
+ return err;
}
#ifdef ATA_DEBUG
@@ -1099,20 +1303,12 @@ static void mv6_dev_config(struct ata_device *adev)
*
* Gen-II does not support NCQ over a port multiplier
* (no FIS-based switching).
- *
- * We don't have hob_nsect when doing NCQ commands on Gen-II.
- * See mv_qc_prep() for more info.
*/
if (adev->flags & ATA_DFLAG_NCQ) {
if (sata_pmp_attached(adev->link->ap)) {
adev->flags &= ~ATA_DFLAG_NCQ;
ata_dev_printk(adev, KERN_INFO,
"NCQ disabled for command-based switching\n");
- } else if (adev->max_sectors > GEN_II_NCQ_MAX_SECTORS) {
- adev->max_sectors = GEN_II_NCQ_MAX_SECTORS;
- ata_dev_printk(adev, KERN_INFO,
- "max_sectors limited to %u for NCQ\n",
- adev->max_sectors);
}
}
}
@@ -1148,35 +1344,33 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
return ATA_DEFER_PORT;
}
-static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs)
+static void mv_config_fbs(struct ata_port *ap, int want_ncq, int want_fbs)
{
- u32 new_fiscfg, old_fiscfg;
- u32 new_ltmode, old_ltmode;
- u32 new_haltcond, old_haltcond;
+ struct mv_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio;
- old_fiscfg = readl(port_mmio + FISCFG_OFS);
- old_ltmode = readl(port_mmio + LTMODE_OFS);
- old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+ u32 fiscfg, *old_fiscfg = &pp->cached.fiscfg;
+ u32 ltmode, *old_ltmode = &pp->cached.ltmode;
+ u32 haltcond, *old_haltcond = &pp->cached.haltcond;
- new_fiscfg = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
- new_ltmode = old_ltmode & ~LTMODE_BIT8;
- new_haltcond = old_haltcond | EDMA_ERR_DEV;
+ ltmode = *old_ltmode & ~LTMODE_BIT8;
+ haltcond = *old_haltcond | EDMA_ERR_DEV;
if (want_fbs) {
- new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC;
- new_ltmode = old_ltmode | LTMODE_BIT8;
+ fiscfg = *old_fiscfg | FISCFG_SINGLE_SYNC;
+ ltmode = *old_ltmode | LTMODE_BIT8;
if (want_ncq)
- new_haltcond &= ~EDMA_ERR_DEV;
+ haltcond &= ~EDMA_ERR_DEV;
else
- new_fiscfg |= FISCFG_WAIT_DEV_ERR;
+ fiscfg |= FISCFG_WAIT_DEV_ERR;
+ } else {
+ fiscfg = *old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
}
- if (new_fiscfg != old_fiscfg)
- writelfl(new_fiscfg, port_mmio + FISCFG_OFS);
- if (new_ltmode != old_ltmode)
- writelfl(new_ltmode, port_mmio + LTMODE_OFS);
- if (new_haltcond != old_haltcond)
- writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS);
+ port_mmio = mv_ap_base(ap);
+ mv_write_cached_reg(port_mmio + FISCFG_OFS, old_fiscfg, fiscfg);
+ mv_write_cached_reg(port_mmio + LTMODE_OFS, old_ltmode, ltmode);
+ mv_write_cached_reg(port_mmio + EDMA_HALTCOND_OFS, old_haltcond, haltcond);
}
static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
@@ -1194,7 +1388,86 @@ static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS);
}
-static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
+/**
+ * mv_bmdma_enable - set a magic bit on GEN_IIE to allow bmdma
+ * @ap: Port being initialized
+ *
+ * There are two DMA modes on these chips: basic DMA, and EDMA.
+ *
+ * Bit-0 of the "EDMA RESERVED" register enables/disables use
+ * of basic DMA on the GEN_IIE versions of the chips.
+ *
+ * This bit survives EDMA resets, and must be set for basic DMA
+ * to function, and should be cleared when EDMA is active.
+ */
+static void mv_bmdma_enable_iie(struct ata_port *ap, int enable_bmdma)
+{
+ struct mv_port_priv *pp = ap->private_data;
+ u32 new, *old = &pp->cached.unknown_rsvd;
+
+ if (enable_bmdma)
+ new = *old | 1;
+ else
+ new = *old & ~1;
+ mv_write_cached_reg(mv_ap_base(ap) + EDMA_UNKNOWN_RSVD_OFS, old, new);
+}
+
+/*
+ * SOC chips have an issue whereby the HDD LEDs don't always blink
+ * during I/O when NCQ is enabled. Enabling a special "LED blink" mode
+ * of the SOC takes care of it, generating a steady blink rate when
+ * any drive on the chip is active.
+ *
+ * Unfortunately, the blink mode is a global hardware setting for the SOC,
+ * so we must use it whenever at least one port on the SOC has NCQ enabled.
+ *
+ * We turn "LED blink" off when NCQ is not in use anywhere, because the normal
+ * LED operation works then, and provides better (more accurate) feedback.
+ *
+ * Note that this code assumes that an SOC never has more than one HC onboard.
+ */
+static void mv_soc_led_blink_enable(struct ata_port *ap)
+{
+ struct ata_host *host = ap->host;
+ struct mv_host_priv *hpriv = host->private_data;
+ void __iomem *hc_mmio;
+ u32 led_ctrl;
+
+ if (hpriv->hp_flags & MV_HP_QUIRK_LED_BLINK_EN)
+ return;
+ hpriv->hp_flags |= MV_HP_QUIRK_LED_BLINK_EN;
+ hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no);
+ led_ctrl = readl(hc_mmio + SOC_LED_CTRL_OFS);
+ writel(led_ctrl | SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL_OFS);
+}
+
+static void mv_soc_led_blink_disable(struct ata_port *ap)
+{
+ struct ata_host *host = ap->host;
+ struct mv_host_priv *hpriv = host->private_data;
+ void __iomem *hc_mmio;
+ u32 led_ctrl;
+ unsigned int port;
+
+ if (!(hpriv->hp_flags & MV_HP_QUIRK_LED_BLINK_EN))
+ return;
+
+ /* disable led-blink only if no ports are using NCQ */
+ for (port = 0; port < hpriv->n_ports; port++) {
+ struct ata_port *this_ap = host->ports[port];
+ struct mv_port_priv *pp = this_ap->private_data;
+
+ if (pp->pp_flags & MV_PP_FLAG_NCQ_EN)
+ return;
+ }
+
+ hpriv->hp_flags &= ~MV_HP_QUIRK_LED_BLINK_EN;
+ hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no);
+ led_ctrl = readl(hc_mmio + SOC_LED_CTRL_OFS);
+ writel(led_ctrl & ~SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL_OFS);
+}
+
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma)
{
u32 cfg;
struct mv_port_priv *pp = ap->private_data;
@@ -1203,7 +1476,8 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
/* set up non-NCQ EDMA configuration */
cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */
- pp->pp_flags &= ~MV_PP_FLAG_FBS_EN;
+ pp->pp_flags &=
+ ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY);
if (IS_GEN_I(hpriv))
cfg |= (1 << 8); /* enab config burst size mask */
@@ -1224,7 +1498,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
*/
want_fbs &= want_ncq;
- mv_config_fbs(port_mmio, want_ncq, want_fbs);
+ mv_config_fbs(ap, want_ncq, want_fbs);
if (want_fbs) {
pp->pp_flags |= MV_PP_FLAG_FBS_EN;
@@ -1232,18 +1506,27 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
}
cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */
- cfg |= (1 << 22); /* enab 4-entry host queue cache */
- if (!IS_SOC(hpriv))
- cfg |= (1 << 18); /* enab early completion */
+ if (want_edma) {
+ cfg |= (1 << 22); /* enab 4-entry host queue cache */
+ if (!IS_SOC(hpriv))
+ cfg |= (1 << 18); /* enab early completion */
+ }
if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
+ mv_bmdma_enable_iie(ap, !want_edma);
+
+ if (IS_SOC(hpriv)) {
+ if (want_ncq)
+ mv_soc_led_blink_enable(ap);
+ else
+ mv_soc_led_blink_disable(ap);
+ }
}
if (want_ncq) {
cfg |= EDMA_CFG_NCQ;
pp->pp_flags |= MV_PP_FLAG_NCQ_EN;
- } else
- pp->pp_flags &= ~MV_PP_FLAG_NCQ_EN;
+ }
writelfl(cfg, port_mmio + EDMA_CFG_OFS);
}
@@ -1327,6 +1610,8 @@ static int mv_port_start(struct ata_port *ap)
pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0];
}
}
+ mv_save_cached_regs(ap);
+ mv_edma_cfg(ap, 0, 0);
return 0;
out_port_free_dma_mem:
@@ -1375,12 +1660,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
u32 offset = addr & 0xffff;
u32 len = sg_len;
- if ((offset + sg_len > 0x10000))
+ if (offset + len > 0x10000)
len = 0x10000 - offset;
mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
mv_sg->flags_size = cpu_to_le32(len & 0xffff);
+ mv_sg->reserved = 0;
sg_len -= len;
addr += len;
@@ -1392,6 +1678,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
if (likely(last_sg))
last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+ mb(); /* ensure data structure is visible to the chipset */
}
static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
@@ -1402,6 +1689,147 @@ static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
}
/**
+ * mv_sff_irq_clear - Clear hardware interrupt after DMA.
+ * @ap: Port associated with this ATA transaction.
+ *
+ * We need this only for ATAPI bmdma transactions,
+ * as otherwise we experience spurious interrupts
+ * after libata-sff handles the bmdma interrupts.
+ */
+static void mv_sff_irq_clear(struct ata_port *ap)
+{
+ mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), ERR_IRQ);
+}
+
+/**
+ * mv_check_atapi_dma - Filter ATAPI cmds which are unsuitable for DMA.
+ * @qc: queued command to check for chipset/DMA compatibility.
+ *
+ * The bmdma engines cannot handle speculative data sizes
+ * (bytecount under/over flow). So only allow DMA for
+ * data transfer commands with known data sizes.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *scmd = qc->scsicmd;
+
+ if (scmd) {
+ switch (scmd->cmnd[0]) {
+ case READ_6:
+ case READ_10:
+ case READ_12:
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_12:
+ case GPCMD_READ_CD:
+ case GPCMD_SEND_DVD_STRUCTURE:
+ case GPCMD_SEND_CUE_SHEET:
+ return 0; /* DMA is safe */
+ }
+ }
+ return -EOPNOTSUPP; /* use PIO instead */
+}
+
+/**
+ * mv_bmdma_setup - Set up BMDMA transaction
+ * @qc: queued command to prepare DMA for.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+
+ mv_fill_sg(qc);
+
+ /* clear all DMA cmd bits */
+ writel(0, port_mmio + BMDMA_CMD_OFS);
+
+ /* load PRD table addr. */
+ writel((pp->sg_tbl_dma[qc->tag] >> 16) >> 16,
+ port_mmio + BMDMA_PRD_HIGH_OFS);
+ writelfl(pp->sg_tbl_dma[qc->tag],
+ port_mmio + BMDMA_PRD_LOW_OFS);
+
+ /* issue r/w command */
+ ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+/**
+ * mv_bmdma_start - Start a BMDMA transaction
+ * @qc: queued command to start DMA on.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+ u32 cmd = (rw ? 0 : ATA_DMA_WR) | ATA_DMA_START;
+
+ /* start host DMA transaction */
+ writelfl(cmd, port_mmio + BMDMA_CMD_OFS);
+}
+
+/**
+ * mv_bmdma_stop - Stop BMDMA transfer
+ * @qc: queued command to stop DMA on.
+ *
+ * Clears the ATA_DMA_START flag in the bmdma control register
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 cmd;
+
+ /* clear start/stop bit */
+ cmd = readl(port_mmio + BMDMA_CMD_OFS);
+ cmd &= ~ATA_DMA_START;
+ writelfl(cmd, port_mmio + BMDMA_CMD_OFS);
+
+ /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+ ata_sff_dma_pause(ap);
+}
+
+/**
+ * mv_bmdma_status - Read BMDMA status
+ * @ap: port for which to retrieve DMA status.
+ *
+ * Read and return equivalent of the sff BMDMA status register.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static u8 mv_bmdma_status(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 reg, status;
+
+ /*
+ * Other bits are valid only if ATA_DMA_ACTIVE==0,
+ * and the ATA_DMA_INTR bit doesn't exist.
+ */
+ reg = readl(port_mmio + BMDMA_STATUS_OFS);
+ if (reg & ATA_DMA_ACTIVE)
+ status = ATA_DMA_ACTIVE;
+ else
+ status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR;
+ return status;
+}
+
+/**
* mv_qc_prep - Host specific command preparation.
* @qc: queued command to prepare
*
@@ -1450,7 +1878,8 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
* only 11 bytes...so we must pick and choose required
* registers based on the command. So, we drop feature and
* hob_feature for [RW] DMA commands, but they are needed for
- * NCQ. NCQ will drop hob_nsect.
+ * NCQ. NCQ will drop hob_nsect, which is not needed there
+ * (nsect is used only for the tag; feat/hob_feat hold true nsect).
*/
switch (tf->command) {
case ATA_CMD_READ:
@@ -1562,6 +1991,132 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
}
/**
+ * mv_sff_check_status - fetch device status, if valid
+ * @ap: ATA port to fetch status from
+ *
+ * When using command issue via mv_qc_issue_fis(),
+ * the initial ATA_BUSY state does not show up in the
+ * ATA status (shadow) register. This can confuse libata!
+ *
+ * So we have a hook here to fake ATA_BUSY for that situation,
+ * until the first time a BUSY, DRQ, or ERR bit is seen.
+ *
+ * The rest of the time, it simply returns the ATA status register.
+ */
+static u8 mv_sff_check_status(struct ata_port *ap)
+{
+ u8 stat = ioread8(ap->ioaddr.status_addr);
+ struct mv_port_priv *pp = ap->private_data;
+
+ if (pp->pp_flags & MV_PP_FLAG_FAKE_ATA_BUSY) {
+ if (stat & (ATA_BUSY | ATA_DRQ | ATA_ERR))
+ pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY;
+ else
+ stat = ATA_BUSY;
+ }
+ return stat;
+}
+
+/**
+ * mv_send_fis - Send a FIS, using the "Vendor-Unique FIS" register
+ * @fis: fis to be sent
+ * @nwords: number of 32-bit words in the fis
+ */
+static unsigned int mv_send_fis(struct ata_port *ap, u32 *fis, int nwords)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 ifctl, old_ifctl, ifstat;
+ int i, timeout = 200, final_word = nwords - 1;
+
+ /* Initiate FIS transmission mode */
+ old_ifctl = readl(port_mmio + SATA_IFCTL_OFS);
+ ifctl = 0x100 | (old_ifctl & 0xf);
+ writelfl(ifctl, port_mmio + SATA_IFCTL_OFS);
+
+ /* Send all words of the FIS except for the final word */
+ for (i = 0; i < final_word; ++i)
+ writel(fis[i], port_mmio + VENDOR_UNIQUE_FIS_OFS);
+
+ /* Flag end-of-transmission, and then send the final word */
+ writelfl(ifctl | 0x200, port_mmio + SATA_IFCTL_OFS);
+ writelfl(fis[final_word], port_mmio + VENDOR_UNIQUE_FIS_OFS);
+
+ /*
+ * Wait for FIS transmission to complete.
+ * This typically takes just a single iteration.
+ */
+ do {
+ ifstat = readl(port_mmio + SATA_IFSTAT_OFS);
+ } while (!(ifstat & 0x1000) && --timeout);
+
+ /* Restore original port configuration */
+ writelfl(old_ifctl, port_mmio + SATA_IFCTL_OFS);
+
+ /* See if it worked */
+ if ((ifstat & 0x3000) != 0x1000) {
+ ata_port_printk(ap, KERN_WARNING,
+ "%s transmission error, ifstat=%08x\n",
+ __func__, ifstat);
+ return AC_ERR_OTHER;
+ }
+ return 0;
+}
+
+/**
+ * mv_qc_issue_fis - Issue a command directly as a FIS
+ * @qc: queued command to start
+ *
+ * Note that the ATA shadow registers are not updated
+ * after command issue, so the device will appear "READY"
+ * if polled, even while it is BUSY processing the command.
+ *
+ * So we use a status hook to fake ATA_BUSY until the drive changes state.
+ *
+ * Note: we don't get updated shadow regs on *completion*
+ * of non-data commands. So avoid sending them via this function,
+ * as they will appear to have completed immediately.
+ *
+ * GEN_IIE has special registers that we could get the result tf from,
+ * but earlier chipsets do not. For now, we ignore those registers.
+ */
+static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mv_port_priv *pp = ap->private_data;
+ struct ata_link *link = qc->dev->link;
+ u32 fis[5];
+ int err = 0;
+
+ ata_tf_to_fis(&qc->tf, link->pmp, 1, (void *)fis);
+ err = mv_send_fis(ap, fis, sizeof(fis) / sizeof(fis[0]));
+ if (err)
+ return err;
+
+ switch (qc->tf.protocol) {
+ case ATAPI_PROT_PIO:
+ pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY;
+ /* fall through */
+ case ATAPI_PROT_NODATA:
+ ap->hsm_task_state = HSM_ST_FIRST;
+ break;
+ case ATA_PROT_PIO:
+ pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY;
+ if (qc->tf.flags & ATA_TFLAG_WRITE)
+ ap->hsm_task_state = HSM_ST_FIRST;
+ else
+ ap->hsm_task_state = HSM_ST;
+ break;
+ default:
+ ap->hsm_task_state = HSM_ST_LAST;
+ break;
+ }
+
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_pio_queue_task(ap, qc, 0);
+ return 0;
+}
+
+/**
* mv_qc_issue - Initiate a command to the host
* @qc: queued command to start
*
@@ -1575,14 +2130,28 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
*/
static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
{
+ static int limit_warnings = 10;
struct ata_port *ap = qc->ap;
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
u32 in_index;
+ unsigned int port_irqs;
- if ((qc->tf.protocol != ATA_PROT_DMA) &&
- (qc->tf.protocol != ATA_PROT_NCQ)) {
- static int limit_warnings = 10;
+ pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY; /* paranoia */
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_DMA:
+ case ATA_PROT_NCQ:
+ mv_start_edma(ap, port_mmio, pp, qc->tf.protocol);
+ pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
+ in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
+
+ /* Write the request in pointer to kick the EDMA to life */
+ writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
+ port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+ return 0;
+
+ case ATA_PROT_PIO:
/*
* Errata SATA#16, SATA#24: warn if multiple DRQs expected.
*
@@ -1600,27 +2169,46 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
": attempting PIO w/multiple DRQ: "
"this may fail due to h/w errata\n");
}
- /*
- * We're about to send a non-EDMA capable command to the
- * port. Turn off EDMA so there won't be problems accessing
- * shadow block, etc registers.
- */
- mv_stop_edma(ap);
- mv_enable_port_irqs(ap, ERR_IRQ);
- mv_pmp_select(ap, qc->dev->link->pmp);
- return ata_sff_qc_issue(qc);
+ /* drop through */
+ case ATA_PROT_NODATA:
+ case ATAPI_PROT_PIO:
+ case ATAPI_PROT_NODATA:
+ if (ap->flags & ATA_FLAG_PIO_POLLING)
+ qc->tf.flags |= ATA_TFLAG_POLLING;
+ break;
}
- mv_start_dma(ap, port_mmio, pp, qc->tf.protocol);
-
- pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
- in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ port_irqs = ERR_IRQ; /* mask device interrupt when polling */
+ else
+ port_irqs = ERR_IRQ | DONE_IRQ; /* unmask all interrupts */
- /* and write the request in pointer to kick the EDMA to life */
- writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
- port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+ /*
+ * We're about to send a non-EDMA capable command to the
+ * port. Turn off EDMA so there won't be problems accessing
+ * shadow block, etc registers.
+ */
+ mv_stop_edma(ap);
+ mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
+ mv_pmp_select(ap, qc->dev->link->pmp);
- return 0;
+ if (qc->tf.command == ATA_CMD_READ_LOG_EXT) {
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ /*
+ * Workaround for 88SX60x1 FEr SATA#25 (part 2).
+ *
+ * After any NCQ error, the READ_LOG_EXT command
+ * from libata-eh *must* use mv_qc_issue_fis().
+ * Otherwise it might fail, due to chip errata.
+ *
+ * Rather than special-case it, we'll just *always*
+ * use this method here for READ_LOG_EXT, making for
+ * easier testing.
+ */
+ if (IS_GEN_II(hpriv))
+ return mv_qc_issue_fis(qc);
+ }
+ return ata_sff_qc_issue(qc);
}
static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
@@ -1631,8 +2219,12 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
if (pp->pp_flags & MV_PP_FLAG_NCQ_EN)
return NULL;
qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
- qc = NULL;
+ if (qc) {
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ qc = NULL;
+ else if (!(qc->flags & ATA_QCFLAG_ACTIVE))
+ qc = NULL;
+ }
return qc;
}
@@ -2101,6 +2693,10 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause)
void __iomem *mmio = hpriv->base, *hc_mmio;
unsigned int handled = 0, port;
+ /* If asserted, clear the "all ports" IRQ coalescing bit */
+ if (main_irq_cause & ALL_PORTS_COAL_DONE)
+ writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE);
+
for (port = 0; port < hpriv->n_ports; port++) {
struct ata_port *ap = host->ports[port];
unsigned int p, shift, hardport, port_cause;
@@ -2133,6 +2729,8 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause)
* to ack (only) those ports via hc_irq_cause.
*/
ack_irqs = 0;
+ if (hc_cause & PORTS_0_3_COAL_DONE)
+ ack_irqs = HC_COAL_IRQ;
for (p = 0; p < MV_PORTS_PER_HC; ++p) {
if ((port + p) >= hpriv->n_ports)
break;
@@ -2214,9 +2812,15 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
struct ata_host *host = dev_instance;
struct mv_host_priv *hpriv = host->private_data;
unsigned int handled = 0;
+ int using_msi = hpriv->hp_flags & MV_HP_FLAG_MSI;
u32 main_irq_cause, pending_irqs;
spin_lock(&host->lock);
+
+ /* for MSI: block new interrupts while in here */
+ if (using_msi)
+ mv_write_main_irq_mask(0, hpriv);
+
main_irq_cause = readl(hpriv->main_irq_cause_addr);
pending_irqs = main_irq_cause & hpriv->main_irq_mask;
/*
@@ -2229,7 +2833,13 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
else
handled = mv_host_intr(host, pending_irqs);
}
+
+ /* for MSI: unmask; interrupt cause bits will retrigger now */
+ if (using_msi)
+ mv_write_main_irq_mask(hpriv->main_irq_mask, hpriv);
+
spin_unlock(&host->lock);
+
return IRQ_RETVAL(handled);
}
@@ -2779,6 +3389,8 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
mv_reset_channel(hpriv, mmio, ap->port_no);
pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ pp->pp_flags &=
+ ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY);
/* Workaround for errata FEr SATA#10 (part 2) */
do {
@@ -2798,6 +3410,8 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
extra = HZ; /* only extend it once, max */
}
} while (sstatus != 0x0 && sstatus != 0x113 && sstatus != 0x123);
+ mv_save_cached_regs(ap);
+ mv_edma_cfg(ap, 0, 0);
return rc;
}
@@ -2821,8 +3435,7 @@ static void mv_eh_thaw(struct ata_port *ap)
writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
/* clear pending irq events */
- hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
- hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
+ hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
mv_enable_port_irqs(ap, ERR_IRQ);
@@ -3075,6 +3688,9 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS;
}
+ /* initialize shadow irq mask with register's value */
+ hpriv->main_irq_mask = readl(hpriv->main_irq_mask_addr);
+
/* global interrupt mask: 0 == mask everything */
mv_set_main_irq_mask(host, ~0, 0);
@@ -3118,19 +3734,19 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
}
- if (!IS_SOC(hpriv)) {
- /* Clear any currently outstanding host interrupt conditions */
- writelfl(0, mmio + hpriv->irq_cause_ofs);
+ /* Clear any currently outstanding host interrupt conditions */
+ writelfl(0, mmio + hpriv->irq_cause_ofs);
- /* and unmask interrupt generation for host regs */
- writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
+ /* and unmask interrupt generation for host regs */
+ writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
- /*
- * enable only global host interrupts for now.
- * The per-port interrupts get done later as ports are set up.
- */
- mv_set_main_irq_mask(host, 0, PCI_ERR);
- }
+ /*
+ * enable only global host interrupts for now.
+ * The per-port interrupts get done later as ports are set up.
+ */
+ mv_set_main_irq_mask(host, 0, PCI_ERR);
+ mv_set_irq_coalescing(host, irq_coalescing_io_count,
+ irq_coalescing_usecs);
done:
return rc;
}
@@ -3292,12 +3908,6 @@ static struct pci_driver mv_pci_driver = {
.remove = ata_pci_remove_one,
};
-/*
- * module options
- */
-static int msi; /* Use PCI msi; either zero (off, default) or non-zero */
-
-
/* move to PCI layer or libata core? */
static int pci_go_64(struct pci_dev *pdev)
{
@@ -3430,9 +4040,9 @@ static int mv_pci_init_one(struct pci_dev *pdev,
if (rc)
return rc;
- /* Enable interrupts */
- if (msi && pci_enable_msi(pdev))
- pci_intx(pdev, 1);
+ /* Enable message-switched interrupts, if requested */
+ if (msi && pci_enable_msi(pdev) == 0)
+ hpriv->hp_flags |= MV_HP_FLAG_MSI;
mv_dump_pci_cfg(pdev, 0x68);
mv_print_info(host);
@@ -3479,10 +4089,5 @@ MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:" DRV_NAME);
-#ifdef CONFIG_PCI
-module_param(msi, int, 0444);
-MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
-#endif
-
module_init(mv_init);
module_exit(mv_exit);
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 6f146061432..6cda12ba812 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -57,9 +57,9 @@ enum {
NV_MMIO_BAR = 5,
NV_PORTS = 2,
- NV_PIO_MASK = 0x1f,
- NV_MWDMA_MASK = 0x07,
- NV_UDMA_MASK = 0x7f,
+ NV_PIO_MASK = ATA_PIO4,
+ NV_MWDMA_MASK = ATA_MWDMA2,
+ NV_UDMA_MASK = ATA_UDMA6,
NV_PORT0_SCR_REG_OFFSET = 0x00,
NV_PORT1_SCR_REG_OFFSET = 0x40,
@@ -305,10 +305,10 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance);
static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
+static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
static void nv_nf2_freeze(struct ata_port *ap);
static void nv_nf2_thaw(struct ata_port *ap);
-static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline);
static void nv_ck804_freeze(struct ata_port *ap);
static void nv_ck804_thaw(struct ata_port *ap);
static int nv_adma_slave_config(struct scsi_device *sdev);
@@ -352,6 +352,7 @@ enum nv_host_type
NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */
CK804,
ADMA,
+ MCP5x,
SWNCQ,
};
@@ -363,10 +364,10 @@ static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), SWNCQ },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), SWNCQ },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), SWNCQ },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), SWNCQ },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), MCP5x },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), MCP5x },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), MCP5x },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), MCP5x },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
@@ -407,6 +408,7 @@ static struct scsi_host_template nv_swncq_sht = {
static struct ata_port_operations nv_common_ops = {
.inherits = &ata_bmdma_port_ops,
+ .lost_interrupt = ATA_OP_NULL,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
};
@@ -420,26 +422,33 @@ static struct ata_port_operations nv_generic_ops = {
.hardreset = ATA_OP_NULL,
};
-/* OSDL bz3352 reports that nf2/3 controllers can't determine device
- * signature reliably. Also, the following thread reports detection
- * failure on cold boot with the standard debouncing timing.
+/* nf2 is ripe with hardreset related problems.
+ *
+ * kernel bz#3352 reports nf2/3 controllers can't determine device
+ * signature reliably. The following thread reports detection failure
+ * on cold boot with the standard debouncing timing.
*
* http://thread.gmane.org/gmane.linux.ide/34098
*
- * Debounce with hotplug timing and request follow-up SRST.
+ * And bz#12176 reports that hardreset simply doesn't work on nf2.
+ * Give up on it and just don't do hardreset.
*/
static struct ata_port_operations nv_nf2_ops = {
- .inherits = &nv_common_ops,
+ .inherits = &nv_generic_ops,
.freeze = nv_nf2_freeze,
.thaw = nv_nf2_thaw,
- .hardreset = nv_nf2_hardreset,
};
-/* CK804 finally gets hardreset right */
+/* For initial probing after boot and hot plugging, hardreset mostly
+ * works fine on CK804 but curiously, reprobing on the initial port by
+ * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS
+ * in somewhat undeterministic way. Use noclassify hardreset.
+ */
static struct ata_port_operations nv_ck804_ops = {
.inherits = &nv_common_ops,
.freeze = nv_ck804_freeze,
.thaw = nv_ck804_thaw,
+ .hardreset = nv_noclassify_hardreset,
.host_stop = nv_ck804_host_stop,
};
@@ -467,8 +476,19 @@ static struct ata_port_operations nv_adma_ops = {
.host_stop = nv_adma_host_stop,
};
+/* Kernel bz#12351 reports that when SWNCQ is enabled, for hotplug to
+ * work, hardreset should be used and hardreset can't report proper
+ * signature, which suggests that mcp5x is closer to nf2 as long as
+ * reset quirkiness is concerned. Define separate ops for mcp5x with
+ * nv_noclassify_hardreset().
+ */
+static struct ata_port_operations nv_mcp5x_ops = {
+ .inherits = &nv_common_ops,
+ .hardreset = nv_noclassify_hardreset,
+};
+
static struct ata_port_operations nv_swncq_ops = {
- .inherits = &nv_generic_ops,
+ .inherits = &nv_mcp5x_ops,
.qc_defer = ata_std_qc_defer,
.qc_prep = nv_swncq_qc_prep,
@@ -531,6 +551,15 @@ static const struct ata_port_info nv_port_info[] = {
.port_ops = &nv_adma_ops,
.private_data = NV_PI_PRIV(nv_adma_interrupt, &nv_adma_sht),
},
+ /* MCP5x */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .pio_mask = NV_PIO_MASK,
+ .mwdma_mask = NV_MWDMA_MASK,
+ .udma_mask = NV_UDMA_MASK,
+ .port_ops = &nv_mcp5x_ops,
+ .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht),
+ },
/* SWNCQ */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
@@ -1530,6 +1559,17 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
return 0;
}
+static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ bool online;
+ int rc;
+
+ rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
+ &online, NULL);
+ return online ? -EAGAIN : rc;
+}
+
static void nv_nf2_freeze(struct ata_port *ap)
{
void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
@@ -1554,17 +1594,6 @@ static void nv_nf2_thaw(struct ata_port *ap)
iowrite8(mask, scr_addr + NV_INT_ENABLE);
}
-static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- bool online;
- int rc;
-
- rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
- &online, NULL);
- return online ? -EAGAIN : rc;
-}
-
static void nv_ck804_freeze(struct ata_port *ap)
{
void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
@@ -2355,14 +2384,9 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (type == CK804 && adma_enabled) {
dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
type = ADMA;
- }
-
- if (type == SWNCQ) {
- if (swncq_enabled)
- dev_printk(KERN_NOTICE, &pdev->dev,
- "Using SWNCQ mode\n");
- else
- type = GENERIC;
+ } else if (type == MCP5x && swncq_enabled) {
+ dev_printk(KERN_NOTICE, &pdev->dev, "Using SWNCQ mode\n");
+ type = SWNCQ;
}
ppi[0] = &nv_port_info[type];
@@ -2500,7 +2524,7 @@ static void __exit nv_exit(void)
module_init(nv_init);
module_exit(nv_exit);
module_param_named(adma, adma_enabled, bool, 0444);
-MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: true)");
+MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: false)");
module_param_named(swncq, swncq_enabled, bool, 0444);
MODULE_PARM_DESC(swncq, "Enable use of SWNCQ (Default: true)");
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index ba9a2570a74..b1fd7d62071 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -176,7 +176,9 @@ static const struct ata_port_operations pdc_common_ops = {
.check_atapi_dma = pdc_check_atapi_dma,
.qc_prep = pdc_qc_prep,
.qc_issue = pdc_qc_issue,
+
.sff_irq_clear = pdc_irq_clear,
+ .lost_interrupt = ATA_OP_NULL,
.post_internal_cmd = pdc_post_internal_cmd,
.error_handler = pdc_error_handler,
@@ -213,8 +215,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
PDC_FLAG_SATA_PATA,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_old_sata_ops,
},
@@ -222,8 +224,8 @@ static const struct ata_port_info pdc_port_info[] = {
[board_2037x_pata] =
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -232,8 +234,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
PDC_FLAG_4_PORTS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_old_sata_ops,
},
@@ -242,8 +244,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
PDC_FLAG_4_PORTS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -252,8 +254,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_sata_ops,
},
@@ -262,8 +264,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
PDC_FLAG_GEN_II,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -272,8 +274,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_sata_ops,
},
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index a000c86ac85..c3936d35cda 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -147,6 +147,7 @@ static struct ata_port_operations qs_ata_ops = {
.softreset = ATA_OP_NULL,
.error_handler = qs_error_handler,
.post_internal_cmd = ATA_OP_NULL,
+ .lost_interrupt = ATA_OP_NULL,
.scr_read = qs_scr_read,
.scr_write = qs_scr_write,
@@ -160,7 +161,7 @@ static const struct ata_port_info qs_port_info[] = {
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
- .pio_mask = 0x10, /* pio4 */
+ .pio_mask = ATA_PIO4_ONLY,
.udma_mask = ATA_UDMA6,
.port_ops = &qs_ata_ops,
},
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 564c142b03b..e67ce8e5caa 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -44,6 +44,7 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include <linux/dmi.h>
#define DRV_NAME "sata_sil"
#define DRV_VERSION "2.4"
@@ -199,8 +200,8 @@ static const struct ata_port_info sil_port_info[] = {
/* sil_3112 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
@@ -208,24 +209,24 @@ static const struct ata_port_info sil_port_info[] = {
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
SIL_FLAG_NO_SATA_IRQ,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
/* sil_3512 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
/* sil_3114 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
@@ -323,7 +324,7 @@ static void sil_fill_sg(struct ata_queued_cmd *qc)
prd->addr = cpu_to_le32(addr);
prd->flags_len = cpu_to_le32(sg_len);
- VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, sg_len);
+ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len);
last_prd = prd;
prd++;
@@ -695,11 +696,38 @@ static void sil_init_controller(struct ata_host *host)
}
}
+static bool sil_broken_system_poweroff(struct pci_dev *pdev)
+{
+ static const struct dmi_system_id broken_systems[] = {
+ {
+ .ident = "HP Compaq nx6325",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
+ },
+ /* PCI slot number of the controller */
+ .driver_data = (void *)0x12UL,
+ },
+
+ { } /* terminate list */
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
+
+ if (dmi) {
+ unsigned long slot = (unsigned long)dmi->driver_data;
+ /* apply the quirk only to on-board controllers */
+ return slot == PCI_SLOT(pdev->devfn);
+ }
+
+ return false;
+}
+
static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
int board_id = ent->driver_data;
- const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL };
+ struct ata_port_info pi = sil_port_info[board_id];
+ const struct ata_port_info *ppi[] = { &pi, NULL };
struct ata_host *host;
void __iomem *mmio_base;
int n_ports, rc;
@@ -713,6 +741,13 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == sil_3114)
n_ports = 4;
+ if (sil_broken_system_poweroff(pdev)) {
+ pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN |
+ ATA_FLAG_NO_HIBERNATE_SPINDOWN;
+ dev_info(&pdev->dev, "quirky BIOS, skipping spindown "
+ "on poweroff and hibernation\n");
+ }
+
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
if (!host)
return -ENOMEM;
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 2590c2279fa..0d8990dcdfc 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -429,25 +429,25 @@ static const struct ata_port_info sil24_port_info[] = {
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
SIL24_FLAG_PCIX_IRQ_WOC,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil24_ops,
},
/* sil_3132 */
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil24_ops,
},
/* sil_3131/sil_3531 */
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil24_ops,
},
};
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 9c43b4e7c4a..8f983322861 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -97,8 +97,8 @@ static struct ata_port_operations sis_ops = {
static const struct ata_port_info sis_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x7,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &sis_ops,
};
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 609d147813a..7257f2d5c52 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -361,8 +361,8 @@ static const struct ata_port_info k2_port_info[] = {
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
@@ -371,8 +371,8 @@ static const struct ata_port_info k2_port_info[] = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
K2_FLAG_SATA_8_PORTS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
@@ -380,8 +380,8 @@ static const struct ata_port_info k2_port_info[] = {
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
@@ -389,8 +389,8 @@ static const struct ata_port_info k2_port_info[] = {
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ec04b8d3c79..dce3dccced3 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -265,8 +265,8 @@ static const struct ata_port_info pdc_port_info[] = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_20621_ops,
},
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 019575bb3e0..e5bff47e8aa 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -89,7 +89,7 @@ static struct ata_port_operations uli_ops = {
static const struct ata_port_info uli_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_IGN_SIMPLEX,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &uli_ops,
};
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index c18935f0bda..98e8c50703b 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -92,6 +92,8 @@ static const struct pci_device_id svia_pci_tbl[] = {
{ PCI_VDEVICE(VIA, 0x5372), vt6420 },
{ PCI_VDEVICE(VIA, 0x7372), vt6420 },
{ PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */
+ { PCI_VDEVICE(VIA, 0x9000), vt8251 },
+ { PCI_VDEVICE(VIA, 0x9040), vt8251 },
{ } /* terminate list */
};
@@ -144,24 +146,24 @@ static struct ata_port_operations vt8251_ops = {
static const struct ata_port_info vt6420_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &vt6420_sata_ops,
};
static struct ata_port_info vt6421_sport_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &vt6421_sata_ops,
};
static struct ata_port_info vt6421_pport_info = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0,
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &vt6421_pata_ops,
};
@@ -169,8 +171,8 @@ static struct ata_port_info vt6421_pport_info = {
static struct ata_port_info vt8251_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS |
ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &vt8251_ops,
};
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index c57cdff9e6b..ed70bd28fa2 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -308,6 +308,9 @@ static struct scsi_host_template vsc_sata_sht = {
static struct ata_port_operations vsc_sata_ops = {
.inherits = &ata_bmdma_port_ops,
+ /* The IRQ handling is not quite standard SFF behaviour so we
+ cannot use the default lost interrupt handler */
+ .lost_interrupt = ATA_OP_NULL,
.sff_tf_load = vsc_sata_tf_load,
.sff_tf_read = vsc_sata_tf_read,
.freeze = vsc_freeze,
@@ -345,8 +348,8 @@ static int __devinit vsc_sata_init_one(struct pci_dev *pdev,
static const struct ata_port_info pi = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &vsc_sata_ops,
};
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 98099f526d8..b119640e1ee 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1690,17 +1690,17 @@ static int __devinit fs_init (struct fs_dev *dev)
| (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
| (1 * SARMODE0_INTMODE_READCLEAR)
| (1 * SARMODE0_CWRE)
- | IS_FS50(dev)?SARMODE0_PRPWT_FS50_5:
- SARMODE0_PRPWT_FS155_3
+ | (IS_FS50(dev) ? SARMODE0_PRPWT_FS50_5:
+ SARMODE0_PRPWT_FS155_3)
| (1 * SARMODE0_CALSUP_1)
- | IS_FS50 (dev)?(0
+ | (IS_FS50(dev) ? (0
| SARMODE0_RXVCS_32
| SARMODE0_ABRVCS_32
| SARMODE0_TXVCS_32):
(0
| SARMODE0_RXVCS_1k
| SARMODE0_ABRVCS_1k
- | SARMODE0_TXVCS_1k));
+ | SARMODE0_TXVCS_1k)));
/* 10ms * 100 is 1 second. That should be enough, as AN3:9 says it takes
1ms. */
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 937c9c0ef4c..10f000dbe44 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -2519,8 +2519,8 @@ fore200e_load_and_start_fw(struct fore200e* fore200e)
return err;
sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
- if (request_firmware(&firmware, buf, device) == 1) {
- printk(FORE200E "missing %s firmware image\n", fore200e->bus->model_name);
+ if ((err = request_firmware(&firmware, buf, device)) < 0) {
+ printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
return err;
}
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index e1c7611e914..78c9736c357 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -977,9 +977,7 @@ static void xdump( u_char* cp, int length, char* prefix )
else
pBuf += sprintf( pBuf, "." );
}
- sprintf( pBuf, "\n" );
- // SPrint(prntBuf);
- printk(prntBuf);
+ printk("%s\n", prntBuf);
count += col;
pBuf = prntBuf;
}
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 144a49f1522..8733a2ea04c 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -901,7 +901,7 @@ static int __devinit eeprom_read(struct lanai_dev *lanai)
clock_l(); udelay(5);
for (i = 128; i != 0; i >>= 1) { /* write command out */
tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) |
- (data & i) ? CONFIG1_PROMDATA : 0;
+ ((data & i) ? CONFIG1_PROMDATA : 0);
if (lanai->conf1 != tmp) {
set_config1(tmp);
udelay(5); /* Let new data settle */
diff --git a/drivers/atm/solos-attrlist.c b/drivers/atm/solos-attrlist.c
new file mode 100644
index 00000000000..efa2808dd94
--- /dev/null
+++ b/drivers/atm/solos-attrlist.c
@@ -0,0 +1,70 @@
+SOLOS_ATTR_RO(DriverVersion)
+SOLOS_ATTR_RO(APIVersion)
+SOLOS_ATTR_RO(FirmwareVersion)
+// SOLOS_ATTR_RO(DspVersion)
+// SOLOS_ATTR_RO(CommonHandshake)
+SOLOS_ATTR_RO(Connected)
+SOLOS_ATTR_RO(OperationalMode)
+SOLOS_ATTR_RO(State)
+SOLOS_ATTR_RO(Watchdog)
+SOLOS_ATTR_RO(OperationProgress)
+SOLOS_ATTR_RO(LastFailed)
+SOLOS_ATTR_RO(TxBitRate)
+SOLOS_ATTR_RO(RxBitRate)
+// SOLOS_ATTR_RO(DeltACTATPds)
+// SOLOS_ATTR_RO(DeltACTATPus)
+SOLOS_ATTR_RO(TxATTNDR)
+SOLOS_ATTR_RO(RxATTNDR)
+SOLOS_ATTR_RO(AnnexType)
+SOLOS_ATTR_RO(GeneralFailure)
+SOLOS_ATTR_RO(InterleaveDpDn)
+SOLOS_ATTR_RO(InterleaveDpUp)
+SOLOS_ATTR_RO(RSCorrectedErrorsDn)
+SOLOS_ATTR_RO(RSUnCorrectedErrorsDn)
+SOLOS_ATTR_RO(RSCorrectedErrorsUp)
+SOLOS_ATTR_RO(RSUnCorrectedErrorsUp)
+SOLOS_ATTR_RO(InterleaveRDn)
+SOLOS_ATTR_RO(InterleaveRUp)
+SOLOS_ATTR_RO(ShowtimeStart)
+SOLOS_ATTR_RO(ATURVendor)
+SOLOS_ATTR_RO(ATUCCountry)
+SOLOS_ATTR_RO(ATURANSIRev)
+SOLOS_ATTR_RO(ATURANSISTD)
+SOLOS_ATTR_RO(ATUCANSIRev)
+SOLOS_ATTR_RO(ATUCANSIId)
+SOLOS_ATTR_RO(ATUCANSISTD)
+SOLOS_ATTR_RO(DataBoost)
+SOLOS_ATTR_RO(LocalITUCountryCode)
+SOLOS_ATTR_RO(LocalSEF)
+SOLOS_ATTR_RO(LocalEndLOS)
+SOLOS_ATTR_RO(LocalSNRMargin)
+SOLOS_ATTR_RO(LocalLineAttn)
+SOLOS_ATTR_RO(RawAttn)
+SOLOS_ATTR_RO(LocalTxPower)
+SOLOS_ATTR_RO(RemoteTxPower)
+SOLOS_ATTR_RO(RemoteSEF)
+SOLOS_ATTR_RO(RemoteLOS)
+SOLOS_ATTR_RO(RemoteLineAttn)
+SOLOS_ATTR_RO(RemoteSNRMargin)
+SOLOS_ATTR_RO(LineUpCount)
+SOLOS_ATTR_RO(SRACnt)
+SOLOS_ATTR_RO(SRACntUp)
+SOLOS_ATTR_RO(ProfileStatus)
+SOLOS_ATTR_RW(Action)
+SOLOS_ATTR_RW(ActivateLine)
+SOLOS_ATTR_RO(LineStatus)
+SOLOS_ATTR_RW(HostControl)
+SOLOS_ATTR_RW(AutoStart)
+SOLOS_ATTR_RW(Failsafe)
+SOLOS_ATTR_RW(ShowtimeLed)
+SOLOS_ATTR_RW(Retrain)
+SOLOS_ATTR_RW(Defaults)
+SOLOS_ATTR_RW(LineMode)
+SOLOS_ATTR_RW(Profile)
+SOLOS_ATTR_RW(DetectNoise)
+SOLOS_ATTR_RO(SupportedAnnexes)
+SOLOS_ATTR_RO(Status)
+SOLOS_ATTR_RO(TotalStart)
+SOLOS_ATTR_RO(RecentShowtimeStart)
+SOLOS_ATTR_RO(TotalRxBlocks)
+SOLOS_ATTR_RO(TotalTxBlocks)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 72fc0f799a6..be204308cc1 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -9,6 +9,7 @@
*
* Authors: Nathan Williams <nathan@traverse.com.au>
* David Woodhouse <dwmw2@infradead.org>
+ * Treker Chen <treker@xrio.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -36,8 +37,11 @@
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/kobject.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
+#include <linux/swab.h>
-#define VERSION "0.04"
+#define VERSION "0.07"
#define PTAG "solos-pci"
#define CONFIG_RAM_SIZE 128
@@ -45,16 +49,31 @@
#define IRQ_EN_ADDR 0x78
#define FPGA_VER 0x74
#define IRQ_CLEAR 0x70
-#define BUG_FLAG 0x6C
+#define WRITE_FLASH 0x6C
+#define PORTS 0x68
+#define FLASH_BLOCK 0x64
+#define FLASH_BUSY 0x60
+#define FPGA_MODE 0x5C
+#define FLASH_MODE 0x58
+#define TX_DMA_ADDR(port) (0x40 + (4 * (port)))
+#define RX_DMA_ADDR(port) (0x30 + (4 * (port)))
#define DATA_RAM_SIZE 32768
#define BUF_SIZE 4096
+#define FPGA_PAGE 528 /* FPGA flash page size*/
+#define SOLOS_PAGE 512 /* Solos flash page size*/
+#define FPGA_BLOCK (FPGA_PAGE * 8) /* FPGA flash block size*/
+#define SOLOS_BLOCK (SOLOS_PAGE * 8) /* Solos flash block size*/
#define RX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2)
#define TX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2 + BUF_SIZE)
-static int debug = 0;
+#define RX_DMA_SIZE 2048
+
+static int reset = 0;
static int atmdebug = 0;
+static int firmware_upgrade = 0;
+static int fpga_upgrade = 0;
struct pkt_hdr {
__le16 size;
@@ -63,23 +82,48 @@ struct pkt_hdr {
__le16 type;
};
+struct solos_skb_cb {
+ struct atm_vcc *vcc;
+ uint32_t dma_addr;
+};
+
+
+#define SKB_CB(skb) ((struct solos_skb_cb *)skb->cb)
+
#define PKT_DATA 0
#define PKT_COMMAND 1
#define PKT_POPEN 3
#define PKT_PCLOSE 4
+#define PKT_STATUS 5
struct solos_card {
void __iomem *config_regs;
void __iomem *buffers;
int nr_ports;
+ int tx_mask;
struct pci_dev *dev;
struct atm_dev *atmdev[4];
struct tasklet_struct tlet;
spinlock_t tx_lock;
spinlock_t tx_queue_lock;
spinlock_t cli_queue_lock;
+ spinlock_t param_queue_lock;
+ struct list_head param_queue;
struct sk_buff_head tx_queue[4];
struct sk_buff_head cli_queue[4];
+ struct sk_buff *tx_skb[4];
+ struct sk_buff *rx_skb[4];
+ wait_queue_head_t param_wq;
+ wait_queue_head_t fw_wq;
+ int using_dma;
+};
+
+
+struct solos_param {
+ struct list_head list;
+ pid_t pid;
+ int port;
+ struct sk_buff *response;
};
#define SOLOS_CHAN(atmdev) ((int)(unsigned long)(atmdev)->phy_data)
@@ -88,19 +132,22 @@ MODULE_AUTHOR("Traverse Technologies <support@traverse.com.au>");
MODULE_DESCRIPTION("Solos PCI driver");
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(debug, "Enable Loopback");
+MODULE_PARM_DESC(reset, "Reset Solos chips on startup");
MODULE_PARM_DESC(atmdebug, "Print ATM data");
-module_param(debug, int, 0444);
-module_param(atmdebug, int, 0444);
-
-static int opens;
+MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade");
+MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade");
+module_param(reset, int, 0444);
+module_param(atmdebug, int, 0644);
+module_param(firmware_upgrade, int, 0444);
+module_param(fpga_upgrade, int, 0444);
static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
struct atm_vcc *vcc);
-static int fpga_tx(struct solos_card *);
+static uint32_t fpga_tx(struct solos_card *);
static irqreturn_t solos_irq(int irq, void *dev_id);
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
static int list_vccs(int vci);
+static void release_vccs(struct atm_dev *dev);
static int atm_init(struct solos_card *);
static void atm_remove(struct solos_card *);
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -115,6 +162,264 @@ static inline void solos_pop(struct atm_vcc *vcc, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
+static ssize_t solos_param_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
+ struct solos_card *card = atmdev->dev_data;
+ struct solos_param prm;
+ struct sk_buff *skb;
+ struct pkt_hdr *header;
+ int buflen;
+
+ buflen = strlen(attr->attr.name) + 10;
+
+ skb = alloc_skb(sizeof(*header) + buflen, GFP_KERNEL);
+ if (!skb) {
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff in solos_param_show()\n");
+ return -ENOMEM;
+ }
+
+ header = (void *)skb_put(skb, sizeof(*header));
+
+ buflen = snprintf((void *)&header[1], buflen - 1,
+ "L%05d\n%s\n", current->pid, attr->attr.name);
+ skb_put(skb, buflen);
+
+ header->size = cpu_to_le16(buflen);
+ header->vpi = cpu_to_le16(0);
+ header->vci = cpu_to_le16(0);
+ header->type = cpu_to_le16(PKT_COMMAND);
+
+ prm.pid = current->pid;
+ prm.response = NULL;
+ prm.port = SOLOS_CHAN(atmdev);
+
+ spin_lock_irq(&card->param_queue_lock);
+ list_add(&prm.list, &card->param_queue);
+ spin_unlock_irq(&card->param_queue_lock);
+
+ fpga_queue(card, prm.port, skb, NULL);
+
+ wait_event_timeout(card->param_wq, prm.response, 5 * HZ);
+
+ spin_lock_irq(&card->param_queue_lock);
+ list_del(&prm.list);
+ spin_unlock_irq(&card->param_queue_lock);
+
+ if (!prm.response)
+ return -EIO;
+
+ buflen = prm.response->len;
+ memcpy(buf, prm.response->data, buflen);
+ kfree_skb(prm.response);
+
+ return buflen;
+}
+
+static ssize_t solos_param_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
+ struct solos_card *card = atmdev->dev_data;
+ struct solos_param prm;
+ struct sk_buff *skb;
+ struct pkt_hdr *header;
+ int buflen;
+ ssize_t ret;
+
+ buflen = strlen(attr->attr.name) + 11 + count;
+
+ skb = alloc_skb(sizeof(*header) + buflen, GFP_KERNEL);
+ if (!skb) {
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff in solos_param_store()\n");
+ return -ENOMEM;
+ }
+
+ header = (void *)skb_put(skb, sizeof(*header));
+
+ buflen = snprintf((void *)&header[1], buflen - 1,
+ "L%05d\n%s\n%s\n", current->pid, attr->attr.name, buf);
+
+ skb_put(skb, buflen);
+ header->size = cpu_to_le16(buflen);
+ header->vpi = cpu_to_le16(0);
+ header->vci = cpu_to_le16(0);
+ header->type = cpu_to_le16(PKT_COMMAND);
+
+ prm.pid = current->pid;
+ prm.response = NULL;
+ prm.port = SOLOS_CHAN(atmdev);
+
+ spin_lock_irq(&card->param_queue_lock);
+ list_add(&prm.list, &card->param_queue);
+ spin_unlock_irq(&card->param_queue_lock);
+
+ fpga_queue(card, prm.port, skb, NULL);
+
+ wait_event_timeout(card->param_wq, prm.response, 5 * HZ);
+
+ spin_lock_irq(&card->param_queue_lock);
+ list_del(&prm.list);
+ spin_unlock_irq(&card->param_queue_lock);
+
+ skb = prm.response;
+
+ if (!skb)
+ return -EIO;
+
+ buflen = skb->len;
+
+ /* Sometimes it has a newline, sometimes it doesn't. */
+ if (skb->data[buflen - 1] == '\n')
+ buflen--;
+
+ if (buflen == 2 && !strncmp(skb->data, "OK", 2))
+ ret = count;
+ else if (buflen == 5 && !strncmp(skb->data, "ERROR", 5))
+ ret = -EIO;
+ else {
+ /* We know we have enough space allocated for this; we allocated
+ it ourselves */
+ skb->data[buflen] = 0;
+
+ dev_warn(&card->dev->dev, "Unexpected parameter response: '%s'\n",
+ skb->data);
+ ret = -EIO;
+ }
+ kfree_skb(skb);
+
+ return ret;
+}
+
+static char *next_string(struct sk_buff *skb)
+{
+ int i = 0;
+ char *this = skb->data;
+
+ for (i = 0; i < skb->len; i++) {
+ if (this[i] == '\n') {
+ this[i] = 0;
+ skb_pull(skb, i + 1);
+ return this;
+ }
+ if (!isprint(this[i]))
+ return NULL;
+ }
+ return NULL;
+}
+
+/*
+ * Status packet has fields separated by \n, starting with a version number
+ * for the information therein. Fields are....
+ *
+ * packet version
+ * RxBitRate (version >= 1)
+ * TxBitRate (version >= 1)
+ * State (version >= 1)
+ * LocalSNRMargin (version >= 1)
+ * LocalLineAttn (version >= 1)
+ */
+static int process_status(struct solos_card *card, int port, struct sk_buff *skb)
+{
+ char *str, *end, *state_str, *snr, *attn;
+ int ver, rate_up, rate_down;
+
+ if (!card->atmdev[port])
+ return -ENODEV;
+
+ str = next_string(skb);
+ if (!str)
+ return -EIO;
+
+ ver = simple_strtol(str, NULL, 10);
+ if (ver < 1) {
+ dev_warn(&card->dev->dev, "Unexpected status interrupt version %d\n",
+ ver);
+ return -EIO;
+ }
+
+ str = next_string(skb);
+ if (!str)
+ return -EIO;
+ if (!strcmp(str, "ERROR")) {
+ dev_dbg(&card->dev->dev, "Status packet indicated Solos error on port %d (starting up?)\n",
+ port);
+ return 0;
+ }
+
+ rate_down = simple_strtol(str, &end, 10);
+ if (*end)
+ return -EIO;
+
+ str = next_string(skb);
+ if (!str)
+ return -EIO;
+ rate_up = simple_strtol(str, &end, 10);
+ if (*end)
+ return -EIO;
+
+ state_str = next_string(skb);
+ if (!state_str)
+ return -EIO;
+
+ /* Anything but 'Showtime' is down */
+ if (strcmp(state_str, "Showtime")) {
+ card->atmdev[port]->signal = ATM_PHY_SIG_LOST;
+ release_vccs(card->atmdev[port]);
+ dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
+ return 0;
+ }
+
+ snr = next_string(skb);
+ if (!str)
+ return -EIO;
+ attn = next_string(skb);
+ if (!attn)
+ return -EIO;
+
+ dev_info(&card->dev->dev, "Port %d: %s @%d/%d kb/s%s%s%s%s\n",
+ port, state_str, rate_down/1000, rate_up/1000,
+ snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn);
+
+ card->atmdev[port]->link_rate = rate_down / 424;
+ card->atmdev[port]->signal = ATM_PHY_SIG_FOUND;
+
+ return 0;
+}
+
+static int process_command(struct solos_card *card, int port, struct sk_buff *skb)
+{
+ struct solos_param *prm;
+ unsigned long flags;
+ int cmdpid;
+ int found = 0;
+
+ if (skb->len < 7)
+ return 0;
+
+ if (skb->data[0] != 'L' || !isdigit(skb->data[1]) ||
+ !isdigit(skb->data[2]) || !isdigit(skb->data[3]) ||
+ !isdigit(skb->data[4]) || !isdigit(skb->data[5]) ||
+ skb->data[6] != '\n')
+ return 0;
+
+ cmdpid = simple_strtol(&skb->data[1], NULL, 10);
+
+ spin_lock_irqsave(&card->param_queue_lock, flags);
+ list_for_each_entry(prm, &card->param_queue, list) {
+ if (prm->port == port && prm->pid == cmdpid) {
+ prm->response = skb;
+ skb_pull(skb, 7);
+ wake_up(&card->param_wq);
+ found = 1;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&card->param_queue_lock, flags);
+ return found;
+}
+
static ssize_t console_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -140,8 +445,6 @@ static int send_command(struct solos_card *card, int dev, const char *buf, size_
struct sk_buff *skb;
struct pkt_hdr *header;
-// dev_dbg(&card->dev->dev, "size: %d\n", size);
-
if (size > (BUF_SIZE - sizeof(*header))) {
dev_dbg(&card->dev->dev, "Command is too big. Dropping request\n");
return 0;
@@ -180,82 +483,181 @@ static ssize_t console_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(console, 0644, console_show, console_store);
+
+#define SOLOS_ATTR_RO(x) static DEVICE_ATTR(x, 0444, solos_param_show, NULL);
+#define SOLOS_ATTR_RW(x) static DEVICE_ATTR(x, 0644, solos_param_show, solos_param_store);
+
+#include "solos-attrlist.c"
+
+#undef SOLOS_ATTR_RO
+#undef SOLOS_ATTR_RW
+
+#define SOLOS_ATTR_RO(x) &dev_attr_##x.attr,
+#define SOLOS_ATTR_RW(x) &dev_attr_##x.attr,
+
+static struct attribute *solos_attrs[] = {
+#include "solos-attrlist.c"
+ NULL
+};
+
+static struct attribute_group solos_attr_group = {
+ .attrs = solos_attrs,
+ .name = "parameters",
+};
+
+static int flash_upgrade(struct solos_card *card, int chip)
+{
+ const struct firmware *fw;
+ const char *fw_name;
+ uint32_t data32 = 0;
+ int blocksize = 0;
+ int numblocks = 0;
+ int offset;
+
+ if (chip == 0) {
+ fw_name = "solos-FPGA.bin";
+ blocksize = FPGA_BLOCK;
+ } else {
+ fw_name = "solos-Firmware.bin";
+ blocksize = SOLOS_BLOCK;
+ }
+
+ if (request_firmware(&fw, fw_name, &card->dev->dev))
+ return -ENOENT;
+
+ dev_info(&card->dev->dev, "Flash upgrade starting\n");
+
+ numblocks = fw->size / blocksize;
+ dev_info(&card->dev->dev, "Firmware size: %zd\n", fw->size);
+ dev_info(&card->dev->dev, "Number of blocks: %d\n", numblocks);
+
+ dev_info(&card->dev->dev, "Changing FPGA to Update mode\n");
+ iowrite32(1, card->config_regs + FPGA_MODE);
+ data32 = ioread32(card->config_regs + FPGA_MODE);
+
+ /* Set mode to Chip Erase */
+ dev_info(&card->dev->dev, "Set FPGA Flash mode to %s Chip Erase\n",
+ chip?"Solos":"FPGA");
+ iowrite32((chip * 2), card->config_regs + FLASH_MODE);
+
+
+ iowrite32(1, card->config_regs + WRITE_FLASH);
+ wait_event(card->fw_wq, !ioread32(card->config_regs + FLASH_BUSY));
+
+ for (offset = 0; offset < fw->size; offset += blocksize) {
+ int i;
+
+ /* Clear write flag */
+ iowrite32(0, card->config_regs + WRITE_FLASH);
+
+ /* Set mode to Block Write */
+ /* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */
+ iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE);
+
+ /* Copy block to buffer, swapping each 16 bits */
+ for(i = 0; i < blocksize; i += 4) {
+ uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i));
+ iowrite32(word, RX_BUF(card, 3) + i);
+ }
+
+ /* Specify block number and then trigger flash write */
+ iowrite32(offset / blocksize, card->config_regs + FLASH_BLOCK);
+ iowrite32(1, card->config_regs + WRITE_FLASH);
+ wait_event(card->fw_wq, !ioread32(card->config_regs + FLASH_BUSY));
+ }
+
+ release_firmware(fw);
+ iowrite32(0, card->config_regs + WRITE_FLASH);
+ iowrite32(0, card->config_regs + FPGA_MODE);
+ iowrite32(0, card->config_regs + FLASH_MODE);
+ dev_info(&card->dev->dev, "Returning FPGA to Data mode\n");
+ return 0;
+}
+
static irqreturn_t solos_irq(int irq, void *dev_id)
{
struct solos_card *card = dev_id;
int handled = 1;
- //ACK IRQ
iowrite32(0, card->config_regs + IRQ_CLEAR);
- //Disable IRQs from FPGA
- iowrite32(0, card->config_regs + IRQ_EN_ADDR);
- /* If we only do it when the device is open, we lose console
- messages */
- if (1 || opens)
+ /* If we're up and running, just kick the tasklet to process TX/RX */
+ if (card->atmdev[0])
tasklet_schedule(&card->tlet);
+ else
+ wake_up(&card->fw_wq);
- //Enable IRQs from FPGA
- iowrite32(1, card->config_regs + IRQ_EN_ADDR);
return IRQ_RETVAL(handled);
}
void solos_bh(unsigned long card_arg)
{
struct solos_card *card = (void *)card_arg;
- int port;
uint32_t card_flags;
- uint32_t tx_mask;
uint32_t rx_done = 0;
+ int port;
- card_flags = ioread32(card->config_regs + FLAGS_ADDR);
-
- /* The TX bits are set if the channel is busy; clear if not. We want to
- invoke fpga_tx() unless _all_ the bits for active channels are set */
- tx_mask = (1 << card->nr_ports) - 1;
- if ((card_flags & tx_mask) != tx_mask)
- fpga_tx(card);
+ /*
+ * Since fpga_tx() is going to need to read the flags under its lock,
+ * it can return them to us so that we don't have to hit PCI MMIO
+ * again for the same information
+ */
+ card_flags = fpga_tx(card);
for (port = 0; port < card->nr_ports; port++) {
if (card_flags & (0x10 << port)) {
- struct pkt_hdr header;
+ struct pkt_hdr _hdr, *header;
struct sk_buff *skb;
struct atm_vcc *vcc;
int size;
- rx_done |= 0x10 << port;
+ if (card->using_dma) {
+ skb = card->rx_skb[port];
+ card->rx_skb[port] = NULL;
- memcpy_fromio(&header, RX_BUF(card, port), sizeof(header));
+ pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+ RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
- size = le16_to_cpu(header.size);
+ header = (void *)skb->data;
+ size = le16_to_cpu(header->size);
+ skb_put(skb, size + sizeof(*header));
+ skb_pull(skb, sizeof(*header));
+ } else {
+ header = &_hdr;
- skb = alloc_skb(size, GFP_ATOMIC);
- if (!skb) {
- if (net_ratelimit())
- dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
- continue;
- }
+ rx_done |= 0x10 << port;
+
+ memcpy_fromio(header, RX_BUF(card, port), sizeof(*header));
- memcpy_fromio(skb_put(skb, size),
- RX_BUF(card, port) + sizeof(header),
- size);
+ size = le16_to_cpu(header->size);
+ skb = alloc_skb(size + 1, GFP_ATOMIC);
+ if (!skb) {
+ if (net_ratelimit())
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
+ continue;
+ }
+
+ memcpy_fromio(skb_put(skb, size),
+ RX_BUF(card, port) + sizeof(*header),
+ size);
+ }
if (atmdebug) {
dev_info(&card->dev->dev, "Received: device %d\n", port);
dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
- size, le16_to_cpu(header.vpi),
- le16_to_cpu(header.vci));
+ size, le16_to_cpu(header->vpi),
+ le16_to_cpu(header->vci));
print_buffer(skb);
}
- switch (le16_to_cpu(header.type)) {
+ switch (le16_to_cpu(header->type)) {
case PKT_DATA:
- vcc = find_vcc(card->atmdev[port], le16_to_cpu(header.vpi),
- le16_to_cpu(header.vci));
+ vcc = find_vcc(card->atmdev[port], le16_to_cpu(header->vpi),
+ le16_to_cpu(header->vci));
if (!vcc) {
if (net_ratelimit())
dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
- le16_to_cpu(header.vci), le16_to_cpu(header.vpi),
+ le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
port);
continue;
}
@@ -264,19 +666,50 @@ void solos_bh(unsigned long card_arg)
atomic_inc(&vcc->stats->rx);
break;
+ case PKT_STATUS:
+ if (process_status(card, port, skb) &&
+ net_ratelimit()) {
+ dev_warn(&card->dev->dev, "Bad status packet of %d bytes on port %d:\n", skb->len, port);
+ print_buffer(skb);
+ }
+ dev_kfree_skb_any(skb);
+ break;
+
case PKT_COMMAND:
default: /* FIXME: Not really, surely? */
+ if (process_command(card, port, skb))
+ break;
spin_lock(&card->cli_queue_lock);
if (skb_queue_len(&card->cli_queue[port]) > 10) {
if (net_ratelimit())
dev_warn(&card->dev->dev, "Dropping console response on port %d\n",
port);
+ dev_kfree_skb_any(skb);
} else
skb_queue_tail(&card->cli_queue[port], skb);
spin_unlock(&card->cli_queue_lock);
break;
}
}
+ /* Allocate RX skbs for any ports which need them */
+ if (card->using_dma && card->atmdev[port] &&
+ !card->rx_skb[port]) {
+ struct sk_buff *skb = alloc_skb(RX_DMA_SIZE, GFP_ATOMIC);
+ if (skb) {
+ SKB_CB(skb)->dma_addr =
+ pci_map_single(card->dev, skb->data,
+ RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
+ iowrite32(SKB_CB(skb)->dma_addr,
+ card->config_regs + RX_DMA_ADDR(port));
+ card->rx_skb[port] = skb;
+ } else {
+ if (net_ratelimit())
+ dev_warn(&card->dev->dev, "Failed to allocate RX skb");
+
+ /* We'll have to try again later */
+ tasklet_schedule(&card->tlet);
+ }
+ }
}
if (rx_done)
iowrite32(rx_done, card->config_regs + FLAGS_ADDR);
@@ -326,7 +759,7 @@ static int list_vccs(int vci)
vcc->vci);
}
} else {
- for(i=0; i<32; i++){
+ for(i = 0; i < VCC_HTABLE_SIZE; i++){
head = &vcc_hash[i];
sk_for_each(s, node, head) {
num_found ++;
@@ -342,6 +775,28 @@ static int list_vccs(int vci)
return num_found;
}
+static void release_vccs(struct atm_dev *dev)
+{
+ int i;
+
+ write_lock_irq(&vcc_sklist_lock);
+ for (i = 0; i < VCC_HTABLE_SIZE; i++) {
+ struct hlist_head *head = &vcc_hash[i];
+ struct hlist_node *node, *tmp;
+ struct sock *s;
+ struct atm_vcc *vcc;
+
+ sk_for_each_safe(s, node, tmp, head) {
+ vcc = atm_sk(s);
+ if (vcc->dev == dev) {
+ vcc_release_async(vcc, -EPIPE);
+ sk_del_node_init(s);
+ }
+ }
+ }
+ write_unlock_irq(&vcc_sklist_lock);
+}
+
static int popen(struct atm_vcc *vcc)
{
@@ -349,6 +804,12 @@ static int popen(struct atm_vcc *vcc)
struct sk_buff *skb;
struct pkt_hdr *header;
+ if (vcc->qos.aal != ATM_AAL5) {
+ dev_warn(&card->dev->dev, "Unsupported ATM type %d\n",
+ vcc->qos.aal);
+ return -EINVAL;
+ }
+
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
if (!skb && net_ratelimit()) {
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
@@ -356,22 +817,17 @@ static int popen(struct atm_vcc *vcc)
}
header = (void *)skb_put(skb, sizeof(*header));
- header->size = cpu_to_le16(sizeof(*header));
+ header->size = cpu_to_le16(0);
header->vpi = cpu_to_le16(vcc->vpi);
header->vci = cpu_to_le16(vcc->vci);
header->type = cpu_to_le16(PKT_POPEN);
fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
-// dev_dbg(&card->dev->dev, "Open for vpi %d and vci %d on interface %d\n", vcc->vpi, vcc->vci, SOLOS_CHAN(vcc->dev));
- set_bit(ATM_VF_ADDR, &vcc->flags); // accept the vpi / vci
+ set_bit(ATM_VF_ADDR, &vcc->flags);
set_bit(ATM_VF_READY, &vcc->flags);
list_vccs(0);
- if (!opens)
- iowrite32(1, card->config_regs + IRQ_EN_ADDR);
-
- opens++; //count open PVCs
return 0;
}
@@ -389,17 +845,13 @@ static void pclose(struct atm_vcc *vcc)
}
header = (void *)skb_put(skb, sizeof(*header));
- header->size = cpu_to_le16(sizeof(*header));
+ header->size = cpu_to_le16(0);
header->vpi = cpu_to_le16(vcc->vpi);
header->vci = cpu_to_le16(vcc->vci);
header->type = cpu_to_le16(PKT_PCLOSE);
fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
-// dev_dbg(&card->dev->dev, "Close for vpi %d and vci %d on interface %d\n", vcc->vpi, vcc->vci, SOLOS_CHAN(vcc->dev));
- if (!--opens)
- iowrite32(0, card->config_regs + IRQ_EN_ADDR);
-
clear_bit(ATM_VF_ADDR, &vcc->flags);
clear_bit(ATM_VF_READY, &vcc->flags);
@@ -439,22 +891,26 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
struct atm_vcc *vcc)
{
int old_len;
+ unsigned long flags;
- *(void **)skb->cb = vcc;
+ SKB_CB(skb)->vcc = vcc;
- spin_lock(&card->tx_queue_lock);
+ spin_lock_irqsave(&card->tx_queue_lock, flags);
old_len = skb_queue_len(&card->tx_queue[port]);
skb_queue_tail(&card->tx_queue[port], skb);
- spin_unlock(&card->tx_queue_lock);
+ if (!old_len)
+ card->tx_mask |= (1 << port);
+ spin_unlock_irqrestore(&card->tx_queue_lock, flags);
- /* If TX might need to be started, do so */
+ /* Theoretically we could just schedule the tasklet here, but
+ that introduces latency we don't want -- it's noticeable */
if (!old_len)
fpga_tx(card);
}
-static int fpga_tx(struct solos_card *card)
+static uint32_t fpga_tx(struct solos_card *card)
{
- uint32_t tx_pending;
+ uint32_t tx_pending, card_flags;
uint32_t tx_started = 0;
struct sk_buff *skb;
struct atm_vcc *vcc;
@@ -462,69 +918,77 @@ static int fpga_tx(struct solos_card *card)
unsigned long flags;
spin_lock_irqsave(&card->tx_lock, flags);
-
- tx_pending = ioread32(card->config_regs + FLAGS_ADDR);
-
- dev_vdbg(&card->dev->dev, "TX Flags are %X\n", tx_pending);
-
- for (port = 0; port < card->nr_ports; port++) {
- if (!(tx_pending & (1 << port))) {
+
+ card_flags = ioread32(card->config_regs + FLAGS_ADDR);
+ /*
+ * The queue lock is required for _writing_ to tx_mask, but we're
+ * OK to read it here without locking. The only potential update
+ * that we could race with is in fpga_queue() where it sets a bit
+ * for a new port... but it's going to call this function again if
+ * it's doing that, anyway.
+ */
+ tx_pending = card->tx_mask & ~card_flags;
+
+ for (port = 0; tx_pending; tx_pending >>= 1, port++) {
+ if (tx_pending & 1) {
+ struct sk_buff *oldskb = card->tx_skb[port];
+ if (oldskb)
+ pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr,
+ oldskb->len, PCI_DMA_TODEVICE);
spin_lock(&card->tx_queue_lock);
skb = skb_dequeue(&card->tx_queue[port]);
+ if (!skb)
+ card->tx_mask &= ~(1 << port);
spin_unlock(&card->tx_queue_lock);
- if (!skb)
+ if (skb && !card->using_dma) {
+ memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
+ tx_started |= 1 << port;
+ oldskb = skb; /* We're done with this skb already */
+ } else if (skb && card->using_dma) {
+ SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
+ iowrite32(SKB_CB(skb)->dma_addr,
+ card->config_regs + TX_DMA_ADDR(port));
+ }
+
+ if (!oldskb)
continue;
+ /* Clean up and free oldskb now it's gone */
if (atmdebug) {
dev_info(&card->dev->dev, "Transmitted: port %d\n",
port);
- print_buffer(skb);
+ print_buffer(oldskb);
}
- memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
- vcc = *(void **)skb->cb;
+ vcc = SKB_CB(oldskb)->vcc;
if (vcc) {
atomic_inc(&vcc->stats->tx);
- solos_pop(vcc, skb);
+ solos_pop(vcc, oldskb);
} else
- dev_kfree_skb_irq(skb);
+ dev_kfree_skb_irq(oldskb);
- tx_started |= 1 << port; //Set TX full flag
}
}
+ /* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */
if (tx_started)
iowrite32(tx_started, card->config_regs + FLAGS_ADDR);
spin_unlock_irqrestore(&card->tx_lock, flags);
- return 0;
+ return card_flags;
}
static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
{
struct solos_card *card = vcc->dev->dev_data;
- struct sk_buff *skb2 = NULL;
struct pkt_hdr *header;
+ int pktlen;
- //dev_dbg(&card->dev->dev, "psend called.\n");
- //dev_dbg(&card->dev->dev, "dev,vpi,vci = %d,%d,%d\n",SOLOS_CHAN(vcc->dev),vcc->vpi,vcc->vci);
-
- if (debug) {
- skb2 = atm_alloc_charge(vcc, skb->len, GFP_ATOMIC);
- if (skb2) {
- memcpy(skb2->data, skb->data, skb->len);
- skb_put(skb2, skb->len);
- vcc->push(vcc, skb2);
- atomic_inc(&vcc->stats->rx);
- }
- atomic_inc(&vcc->stats->tx);
- solos_pop(vcc, skb);
- return 0;
- }
-
- if (skb->len > (BUF_SIZE - sizeof(*header))) {
+ pktlen = skb->len;
+ if (pktlen > (BUF_SIZE - sizeof(*header))) {
dev_warn(&card->dev->dev, "Length of PDU is too large. Dropping PDU.\n");
solos_pop(vcc, skb);
return 0;
@@ -539,6 +1003,7 @@ static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
ret = pskb_expand_head(skb, expand_by, 0, GFP_ATOMIC);
if (ret) {
+ dev_warn(&card->dev->dev, "pskb_expand_head failed.\n");
solos_pop(vcc, skb);
return ret;
}
@@ -546,7 +1011,8 @@ static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
header = (void *)skb_push(skb, sizeof(*header));
- header->size = cpu_to_le16(skb->len);
+ /* This does _not_ include the size of the header */
+ header->size = cpu_to_le16(pktlen);
header->vpi = cpu_to_le16(vcc->vpi);
header->vci = cpu_to_le16(vcc->vci);
header->type = cpu_to_le16(PKT_DATA);
@@ -573,20 +1039,19 @@ static struct atmdev_ops fpga_ops = {
static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
- int err, i;
+ int err;
uint16_t fpga_ver;
uint8_t major_ver, minor_ver;
uint32_t data32;
struct solos_card *card;
- if (debug)
- return 0;
-
card = kzalloc(sizeof(*card), GFP_KERNEL);
if (!card)
return -ENOMEM;
card->dev = dev;
+ init_waitqueue_head(&card->fw_wq);
+ init_waitqueue_head(&card->param_wq);
err = pci_enable_device(dev);
if (err) {
@@ -594,6 +1059,12 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto out;
}
+ err = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+ if (err) {
+ dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n");
+ goto out;
+ }
+
err = pci_request_regions(dev, "solos");
if (err) {
dev_warn(&dev->dev, "Failed to request regions\n");
@@ -611,17 +1082,13 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto out_unmap_config;
}
-// for(i=0;i<64 ;i+=4){
-// data32=ioread32(card->buffers + i);
-// dev_dbg(&card->dev->dev, "%08lX\n",(unsigned long)data32);
-// }
+ if (reset) {
+ iowrite32(1, card->config_regs + FPGA_MODE);
+ data32 = ioread32(card->config_regs + FPGA_MODE);
- //Fill Config Mem with zeros
- for(i = 0; i < 128; i += 4)
- iowrite32(0, card->config_regs + i);
-
- //Set RX empty flags
- iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
+ iowrite32(0, card->config_regs + FPGA_MODE);
+ data32 = ioread32(card->config_regs + FPGA_MODE);
+ }
data32 = ioread32(card->config_regs + FPGA_VER);
fpga_ver = (data32 & 0x0000FFFF);
@@ -630,61 +1097,60 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
major_ver, minor_ver, fpga_ver);
- card->nr_ports = 2; /* FIXME: Detect daughterboard */
+ if (0 && fpga_ver > 27)
+ card->using_dma = 1;
+ else {
+ /* Set RX empty flag for all ports */
+ iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
+ }
- err = atm_init(card);
- if (err)
- goto out_unmap_both;
+ data32 = ioread32(card->config_regs + PORTS);
+ card->nr_ports = (data32 & 0x000000FF);
pci_set_drvdata(dev, card);
+
tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
spin_lock_init(&card->tx_lock);
spin_lock_init(&card->tx_queue_lock);
spin_lock_init(&card->cli_queue_lock);
-/*
- // Set Loopback mode
- data32 = 0x00010000;
- iowrite32(data32,card->config_regs + FLAGS_ADDR);
-*/
-/*
- // Fill Buffers with zeros
- for (i = 0; i < BUF_SIZE * 8; i += 4)
- iowrite32(0, card->buffers + i);
-*/
-/*
- for(i = 0; i < (BUF_SIZE * 1); i += 4)
- iowrite32(0x12345678, card->buffers + i + (0*BUF_SIZE));
- for(i = 0; i < (BUF_SIZE * 1); i += 4)
- iowrite32(0xabcdef98, card->buffers + i + (1*BUF_SIZE));
-
- // Read Config Memory
- printk(KERN_DEBUG "Reading Config MEM\n");
- i = 0;
- for(i = 0; i < 16; i++) {
- data32=ioread32(card->buffers + i*(BUF_SIZE/2));
- printk(KERN_ALERT "Addr: %lX Data: %08lX\n",
- (unsigned long)(addr_start + i*(BUF_SIZE/2)),
- (unsigned long)data32);
- }
-*/
- //dev_dbg(&card->dev->dev, "Requesting IRQ: %d\n",dev->irq);
- err = request_irq(dev->irq, solos_irq, IRQF_DISABLED|IRQF_SHARED,
+ spin_lock_init(&card->param_queue_lock);
+ INIT_LIST_HEAD(&card->param_queue);
+
+ err = request_irq(dev->irq, solos_irq, IRQF_SHARED,
"solos-pci", card);
- if (err)
+ if (err) {
dev_dbg(&card->dev->dev, "Failed to request interrupt IRQ: %d\n", dev->irq);
+ goto out_unmap_both;
+ }
- // Enable IRQs
iowrite32(1, card->config_regs + IRQ_EN_ADDR);
+ if (fpga_upgrade)
+ flash_upgrade(card, 0);
+
+ if (firmware_upgrade)
+ flash_upgrade(card, 1);
+
+ err = atm_init(card);
+ if (err)
+ goto out_free_irq;
+
return 0;
+ out_free_irq:
+ iowrite32(0, card->config_regs + IRQ_EN_ADDR);
+ free_irq(dev->irq, card);
+ tasklet_kill(&card->tlet);
+
out_unmap_both:
+ pci_set_drvdata(dev, NULL);
pci_iounmap(dev, card->config_regs);
out_unmap_config:
pci_iounmap(dev, card->buffers);
out_release_regions:
pci_release_regions(dev);
out:
+ kfree(card);
return err;
}
@@ -692,9 +1158,10 @@ static int atm_init(struct solos_card *card)
{
int i;
- opens = 0;
-
for (i = 0; i < card->nr_ports; i++) {
+ struct sk_buff *skb;
+ struct pkt_hdr *header;
+
skb_queue_head_init(&card->tx_queue[i]);
skb_queue_head_init(&card->cli_queue[i]);
@@ -706,6 +1173,8 @@ static int atm_init(struct solos_card *card)
}
if (device_create_file(&card->atmdev[i]->class_dev, &dev_attr_console))
dev_err(&card->dev->dev, "Could not register console for ATM device %d\n", i);
+ if (sysfs_create_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group))
+ dev_err(&card->dev->dev, "Could not register parameter group for ATM device %d\n", i);
dev_info(&card->dev->dev, "Registered ATM device %d\n", card->atmdev[i]->number);
@@ -713,6 +1182,22 @@ static int atm_init(struct solos_card *card)
card->atmdev[i]->ci_range.vci_bits = 16;
card->atmdev[i]->dev_data = card;
card->atmdev[i]->phy_data = (void *)(unsigned long)i;
+ card->atmdev[i]->signal = ATM_PHY_SIG_UNKNOWN;
+
+ skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
+ if (!skb) {
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n");
+ continue;
+ }
+
+ header = (void *)skb_put(skb, sizeof(*header));
+
+ header->size = cpu_to_le16(0);
+ header->vpi = cpu_to_le16(0);
+ header->vci = cpu_to_le16(0);
+ header->type = cpu_to_le16(PKT_STATUS);
+
+ fpga_queue(card, i, skb, NULL);
}
return 0;
}
@@ -723,8 +1208,28 @@ static void atm_remove(struct solos_card *card)
for (i = 0; i < card->nr_ports; i++) {
if (card->atmdev[i]) {
+ struct sk_buff *skb;
+
dev_info(&card->dev->dev, "Unregistering ATM device %d\n", card->atmdev[i]->number);
+
+ sysfs_remove_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group);
atm_dev_deregister(card->atmdev[i]);
+
+ skb = card->rx_skb[i];
+ if (skb) {
+ pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+ RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(skb);
+ }
+ skb = card->tx_skb[i];
+ if (skb) {
+ pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+ skb->len, PCI_DMA_TODEVICE);
+ dev_kfree_skb(skb);
+ }
+ while ((skb = skb_dequeue(&card->tx_queue[i])))
+ dev_kfree_skb(skb);
+
}
}
}
@@ -732,31 +1237,31 @@ static void atm_remove(struct solos_card *card)
static void fpga_remove(struct pci_dev *dev)
{
struct solos_card *card = pci_get_drvdata(dev);
+
+ /* Disable IRQs */
+ iowrite32(0, card->config_regs + IRQ_EN_ADDR);
- if (debug)
- return;
+ /* Reset FPGA */
+ iowrite32(1, card->config_regs + FPGA_MODE);
+ (void)ioread32(card->config_regs + FPGA_MODE);
atm_remove(card);
- dev_vdbg(&dev->dev, "Freeing IRQ\n");
- // Disable IRQs from FPGA
- iowrite32(0, card->config_regs + IRQ_EN_ADDR);
free_irq(dev->irq, card);
tasklet_kill(&card->tlet);
- // iowrite32(0x01,pciregs);
- dev_vdbg(&dev->dev, "Unmapping PCI resource\n");
+ /* Release device from reset */
+ iowrite32(0, card->config_regs + FPGA_MODE);
+ (void)ioread32(card->config_regs + FPGA_MODE);
+
pci_iounmap(dev, card->buffers);
pci_iounmap(dev, card->config_regs);
- dev_vdbg(&dev->dev, "Releasing PCI Region\n");
pci_release_regions(dev);
pci_disable_device(dev);
pci_set_drvdata(dev, NULL);
kfree(card);
-// dev_dbg(&card->dev->dev, "fpga_remove\n");
- return;
}
static struct pci_device_id fpga_pci_tbl[] __devinitdata = {
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 0a5f055dffb..ddc97496db4 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -63,6 +63,32 @@ struct class_private {
#define to_class(obj) \
container_of(obj, struct class_private, class_subsys.kobj)
+/**
+ * struct device_private - structure to hold the private to the driver core portions of the device structure.
+ *
+ * @klist_children - klist containing all children of this device
+ * @knode_parent - node in sibling list
+ * @knode_driver - node in driver list
+ * @knode_bus - node in bus list
+ * @device - pointer back to the struct class that this structure is
+ * associated with.
+ *
+ * Nothing outside of the driver core should ever touch these fields.
+ */
+struct device_private {
+ struct klist klist_children;
+ struct klist_node knode_parent;
+ struct klist_node knode_driver;
+ struct klist_node knode_bus;
+ struct device *device;
+};
+#define to_device_private_parent(obj) \
+ container_of(obj, struct device_private, knode_parent)
+#define to_device_private_driver(obj) \
+ container_of(obj, struct device_private, knode_driver)
+#define to_device_private_bus(obj) \
+ container_of(obj, struct device_private, knode_bus)
+
/* initialisation functions */
extern int devices_init(void);
extern int buses_init(void);
@@ -86,10 +112,13 @@ extern void bus_remove_driver(struct device_driver *drv);
extern void driver_detach(struct device_driver *drv);
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+static inline int driver_match_device(struct device_driver *drv,
+ struct device *dev)
+{
+ return drv->bus->match && drv->bus->match(dev, drv);
+}
extern void sysdev_shutdown(void);
-extern int sysdev_suspend(pm_message_t state);
-extern int sysdev_resume(void);
extern char *make_class_name(const char *name, struct kobject *kobj);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 83f32b891fa..dc030f1f00f 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device_driver *drv,
int err = -ENODEV;
dev = bus_find_device_by_name(bus, NULL, buf);
- if (dev && dev->driver == NULL) {
+ if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
@@ -253,7 +253,14 @@ static ssize_t store_drivers_probe(struct bus_type *bus,
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_bus) : NULL;
+ struct device *dev = NULL;
+ struct device_private *dev_prv;
+
+ if (n) {
+ dev_prv = to_device_private_bus(n);
+ dev = dev_prv->device;
+ }
+ return dev;
}
/**
@@ -286,7 +293,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start,
return -EINVAL;
klist_iter_init_node(&bus->p->klist_devices, &i,
- (start ? &start->knode_bus : NULL));
+ (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -320,7 +327,7 @@ struct device *bus_find_device(struct bus_type *bus,
return NULL;
klist_iter_init_node(&bus->p->klist_devices, &i,
- (start ? &start->knode_bus : NULL));
+ (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -507,7 +514,8 @@ void bus_attach_device(struct device *dev)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
- klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
+ klist_add_tail(&dev->p->knode_bus,
+ &bus->p->klist_devices);
}
}
@@ -528,8 +536,8 @@ void bus_remove_device(struct device *dev)
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
- if (klist_node_attached(&dev->knode_bus))
- klist_del(&dev->knode_bus);
+ if (klist_node_attached(&dev->p->knode_bus))
+ klist_del(&dev->p->knode_bus);
pr_debug("bus: '%s': remove device %s\n",
dev->bus->name, dev_name(dev));
@@ -831,14 +839,16 @@ static void bus_remove_attrs(struct bus_type *bus)
static void klist_devices_get(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_bus);
+ struct device_private *dev_prv = to_device_private_bus(n);
+ struct device *dev = dev_prv->device;
get_device(dev);
}
static void klist_devices_put(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_bus);
+ struct device_private *dev_prv = to_device_private_bus(n);
+ struct device *dev = dev_prv->device;
put_device(dev);
}
@@ -932,6 +942,7 @@ bus_uevent_fail:
kset_unregister(&bus->p->subsys);
kfree(bus->p);
out:
+ bus->p = NULL;
return retval;
}
EXPORT_SYMBOL_GPL(bus_register);
@@ -953,6 +964,7 @@ void bus_unregister(struct bus_type *bus)
bus_remove_file(bus, &bus_attr_uevent);
kset_unregister(&bus->p->subsys);
kfree(bus->p);
+ bus->p = NULL;
}
EXPORT_SYMBOL_GPL(bus_unregister);
@@ -993,18 +1005,20 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list
{
struct list_head *pos;
struct klist_node *n;
+ struct device_private *dev_prv;
struct device *b;
list_for_each(pos, list) {
n = container_of(pos, struct klist_node, n_node);
- b = container_of(n, struct device, knode_bus);
+ dev_prv = to_device_private_bus(n);
+ b = dev_prv->device;
if (compare(a, b) <= 0) {
- list_move_tail(&a->knode_bus.n_node,
- &b->knode_bus.n_node);
+ list_move_tail(&a->p->knode_bus.n_node,
+ &b->p->knode_bus.n_node);
return;
}
}
- list_move_tail(&a->knode_bus.n_node, list);
+ list_move_tail(&a->p->knode_bus.n_node, list);
}
void bus_sort_breadthfirst(struct bus_type *bus,
@@ -1014,6 +1028,7 @@ void bus_sort_breadthfirst(struct bus_type *bus,
LIST_HEAD(sorted_devices);
struct list_head *pos, *tmp;
struct klist_node *n;
+ struct device_private *dev_prv;
struct device *dev;
struct klist *device_klist;
@@ -1022,7 +1037,8 @@ void bus_sort_breadthfirst(struct bus_type *bus,
spin_lock(&device_klist->k_lock);
list_for_each_safe(pos, tmp, &device_klist->k_list) {
n = container_of(pos, struct klist_node, n_node);
- dev = container_of(n, struct device, knode_bus);
+ dev_prv = to_device_private_bus(n);
+ dev = dev_prv->device;
device_insertion_sort_klist(dev, &sorted_devices, compare);
}
list_splice(&sorted_devices, &device_klist->k_list);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 8079afca497..e73c92d13a2 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -109,6 +109,7 @@ static struct sysfs_ops dev_sysfs_ops = {
static void device_release(struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
+ struct device_private *p = dev->p;
if (dev->release)
dev->release(dev);
@@ -120,6 +121,7 @@ static void device_release(struct kobject *kobj)
WARN(1, KERN_ERR "Device '%s' does not have a release() "
"function, it is broken and must be fixed.\n",
dev_name(dev));
+ kfree(p);
}
static struct kobj_type device_ktype = {
@@ -134,8 +136,6 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
if (ktype == &device_ktype) {
struct device *dev = to_dev(kobj);
- if (dev->uevent_suppress)
- return 0;
if (dev->bus)
return 1;
if (dev->class)
@@ -507,14 +507,16 @@ EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
static void klist_children_get(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_parent);
+ struct device_private *p = to_device_private_parent(n);
+ struct device *dev = p->device;
get_device(dev);
}
static void klist_children_put(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_parent);
+ struct device_private *p = to_device_private_parent(n);
+ struct device *dev = p->device;
put_device(dev);
}
@@ -538,8 +540,6 @@ void device_initialize(struct device *dev)
{
dev->kobj.kset = devices_kset;
kobject_init(&dev->kobj, &device_ktype);
- klist_init(&dev->klist_children, klist_children_get,
- klist_children_put);
INIT_LIST_HEAD(&dev->dma_pools);
init_MUTEX(&dev->sem);
spin_lock_init(&dev->devres_lock);
@@ -777,11 +777,12 @@ static void device_remove_class_symlinks(struct device *dev)
int dev_set_name(struct device *dev, const char *fmt, ...)
{
va_list vargs;
+ int err;
va_start(vargs, fmt);
- vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs);
+ err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
va_end(vargs);
- return 0;
+ return err;
}
EXPORT_SYMBOL_GPL(dev_set_name);
@@ -858,12 +859,26 @@ int device_add(struct device *dev)
if (!dev)
goto done;
- /* Temporarily support init_name if it is set.
- * It will override bus_id for now */
- if (dev->init_name)
- dev_set_name(dev, "%s", dev->init_name);
+ dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
+ if (!dev->p) {
+ error = -ENOMEM;
+ goto done;
+ }
+ dev->p->device = dev;
+ klist_init(&dev->p->klist_children, klist_children_get,
+ klist_children_put);
- if (!strlen(dev->bus_id))
+ /*
+ * for statically allocated devices, which should all be converted
+ * some day, we need to initialize the name. We prevent reading back
+ * the name, and force the use of dev_name()
+ */
+ if (dev->init_name) {
+ dev_set_name(dev, dev->init_name);
+ dev->init_name = NULL;
+ }
+
+ if (!dev_name(dev))
goto done;
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
@@ -922,7 +937,8 @@ int device_add(struct device *dev)
kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_attach_device(dev);
if (parent)
- klist_add_tail(&dev->knode_parent, &parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &parent->p->klist_children);
if (dev->class) {
mutex_lock(&dev->class->p->class_mutex);
@@ -1036,7 +1052,7 @@ void device_del(struct device *dev)
device_pm_remove(dev);
dpm_sysfs_remove(dev);
if (parent)
- klist_del(&dev->knode_parent);
+ klist_del(&dev->p->knode_parent);
if (MAJOR(dev->devt)) {
device_remove_sys_dev_entry(dev);
device_remove_file(dev, &devt_attr);
@@ -1097,7 +1113,14 @@ void device_unregister(struct device *dev)
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+ struct device *dev = NULL;
+ struct device_private *p;
+
+ if (n) {
+ p = to_device_private_parent(n);
+ dev = p->device;
+ }
+ return dev;
}
/**
@@ -1119,7 +1142,7 @@ int device_for_each_child(struct device *parent, void *data,
struct device *child;
int error = 0;
- klist_iter_init(&parent->klist_children, &i);
+ klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)) && !error)
error = fn(child, data);
klist_iter_exit(&i);
@@ -1150,7 +1173,7 @@ struct device *device_find_child(struct device *parent, void *data,
if (!parent)
return NULL;
- klist_iter_init(&parent->klist_children, &i);
+ klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)))
if (match(child, data) && get_device(child))
break;
@@ -1274,7 +1297,7 @@ EXPORT_SYMBOL_GPL(__root_device_register);
/**
* root_device_unregister - unregister and free a root device
- * @root: device going away.
+ * @dev: device going away
*
* This function unregisters and cleans up a device that was created by
* root_device_register().
@@ -1342,7 +1365,10 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
dev->release = device_create_release;
dev_set_drvdata(dev, drvdata);
- vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
+ retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
+ if (retval)
+ goto error;
+
retval = device_register(dev);
if (retval)
goto error;
@@ -1446,19 +1472,15 @@ int device_rename(struct device *dev, char *new_name)
old_class_name = make_class_name(dev->class->name, &dev->kobj);
#endif
- old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
+ old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!old_device_name) {
error = -ENOMEM;
goto out;
}
- strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
- strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
error = kobject_rename(&dev->kobj, new_name);
- if (error) {
- strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
+ if (error)
goto out;
- }
#ifdef CONFIG_SYSFS_DEPRECATED
if (old_class_name) {
@@ -1539,8 +1561,10 @@ out:
* device_move - moves a device to a new parent
* @dev: the pointer to the struct device to be moved
* @new_parent: the new parent of the device (can by NULL)
+ * @dpm_order: how to reorder the dpm_list
*/
-int device_move(struct device *dev, struct device *new_parent)
+int device_move(struct device *dev, struct device *new_parent,
+ enum dpm_order dpm_order)
{
int error;
struct device *old_parent;
@@ -1550,6 +1574,7 @@ int device_move(struct device *dev, struct device *new_parent)
if (!dev)
return -EINVAL;
+ device_pm_lock();
new_parent = get_device(new_parent);
new_parent_kobj = get_device_parent(dev, new_parent);
@@ -1564,9 +1589,10 @@ int device_move(struct device *dev, struct device *new_parent)
old_parent = dev->parent;
dev->parent = new_parent;
if (old_parent)
- klist_remove(&dev->knode_parent);
+ klist_remove(&dev->p->knode_parent);
if (new_parent) {
- klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &new_parent->p->klist_children);
set_dev_node(dev, dev_to_node(new_parent));
}
@@ -1578,11 +1604,11 @@ int device_move(struct device *dev, struct device *new_parent)
device_move_class_links(dev, new_parent, old_parent);
if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
if (new_parent)
- klist_remove(&dev->knode_parent);
+ klist_remove(&dev->p->knode_parent);
dev->parent = old_parent;
if (old_parent) {
- klist_add_tail(&dev->knode_parent,
- &old_parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &old_parent->p->klist_children);
set_dev_node(dev, dev_to_node(old_parent));
}
}
@@ -1590,9 +1616,23 @@ int device_move(struct device *dev, struct device *new_parent)
put_device(new_parent);
goto out;
}
+ switch (dpm_order) {
+ case DPM_ORDER_NONE:
+ break;
+ case DPM_ORDER_DEV_AFTER_PARENT:
+ device_pm_move_after(dev, new_parent);
+ break;
+ case DPM_ORDER_PARENT_BEFORE_DEV:
+ device_pm_move_before(new_parent, dev);
+ break;
+ case DPM_ORDER_DEV_LAST:
+ device_pm_move_last(dev);
+ break;
+ }
out_put:
put_device(old_parent);
out:
+ device_pm_unlock();
put_device(dev);
return error;
}
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 315bed8d5e7..f17c3266a0e 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -18,9 +18,11 @@
*/
#include <linux/device.h>
+#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
+#include <linux/async.h>
#include "base.h"
#include "power/power.h"
@@ -28,7 +30,7 @@
static void driver_bound(struct device *dev)
{
- if (klist_node_attached(&dev->knode_driver)) {
+ if (klist_node_attached(&dev->p->knode_driver)) {
printk(KERN_WARNING "%s: device %s already bound\n",
__func__, kobject_name(&dev->kobj));
return;
@@ -41,7 +43,7 @@ static void driver_bound(struct device *dev)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BOUND_DRIVER, dev);
- klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices);
+ klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
}
static int driver_sysfs_add(struct device *dev)
@@ -168,18 +170,23 @@ int driver_probe_done(void)
}
/**
+ * wait_for_device_probe
+ * Wait for device probing to be completed.
+ */
+void wait_for_device_probe(void)
+{
+ /* wait for the known devices to complete their probing */
+ wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
+ async_synchronize_full();
+}
+
+/**
* driver_probe_device - attempt to bind device & driver together
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*
- * First, we call the bus's match function, if one present, which should
- * compare the device IDs the driver supports with the device IDs of the
- * device. Note we don't do this ourselves because we don't know the
- * format of the ID structures, nor what is to be considered a match and
- * what is not.
- *
- * This function returns 1 if a match is found, -ENODEV if the device is
- * not registered, and 0 otherwise.
+ * This function returns -ENODEV if the device is not registered,
+ * 1 if the device is bound sucessfully and 0 otherwise.
*
* This function must be called with @dev->sem held. When called for a
* USB interface, @dev->parent->sem must be held as well.
@@ -190,21 +197,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
if (!device_is_registered(dev))
return -ENODEV;
- if (drv->bus->match && !drv->bus->match(dev, drv))
- goto done;
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __func__, dev_name(dev), drv->name);
ret = really_probe(dev, drv);
-done:
return ret;
}
static int __device_attach(struct device_driver *drv, void *data)
{
struct device *dev = data;
+
+ if (!driver_match_device(drv, dev))
+ return 0;
+
return driver_probe_device(drv, dev);
}
@@ -257,7 +265,7 @@ static int __driver_attach(struct device *dev, void *data)
* is an error.
*/
- if (drv->bus->match && !drv->bus->match(dev, drv))
+ if (!driver_match_device(drv, dev))
return 0;
if (dev->parent) /* Needed for USB */
@@ -310,7 +318,7 @@ static void __device_release_driver(struct device *dev)
drv->remove(dev);
devres_release_all(dev);
dev->driver = NULL;
- klist_remove(&dev->knode_driver);
+ klist_remove(&dev->p->knode_driver);
}
}
@@ -340,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver);
*/
void driver_detach(struct device_driver *drv)
{
+ struct device_private *dev_prv;
struct device *dev;
for (;;) {
@@ -348,8 +357,10 @@ void driver_detach(struct device_driver *drv)
spin_unlock(&drv->p->klist_devices.k_lock);
break;
}
- dev = list_entry(drv->p->klist_devices.k_list.prev,
- struct device, knode_driver.n_node);
+ dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
+ struct device_private,
+ knode_driver.n_node);
+ dev = dev_prv->device;
get_device(dev);
spin_unlock(&drv->p->klist_devices.k_lock);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 1e2bda780e4..c51f11bb29a 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -19,7 +19,14 @@
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_driver) : NULL;
+ struct device *dev = NULL;
+ struct device_private *dev_prv;
+
+ if (n) {
+ dev_prv = to_device_private_driver(n);
+ dev = dev_prv->device;
+ }
+ return dev;
}
/**
@@ -42,7 +49,7 @@ int driver_for_each_device(struct device_driver *drv, struct device *start,
return -EINVAL;
klist_iter_init_node(&drv->p->klist_devices, &i,
- start ? &start->knode_driver : NULL);
+ start ? &start->p->knode_driver : NULL);
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -76,7 +83,7 @@ struct device *driver_find_device(struct device_driver *drv,
return NULL;
klist_iter_init_node(&drv->p->klist_devices, &i,
- (start ? &start->knode_driver : NULL));
+ (start ? &start->p->knode_driver : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -216,6 +223,8 @@ int driver_register(struct device_driver *drv)
int ret;
struct device_driver *other;
+ BUG_ON(!drv->bus->p);
+
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 44699d9dd85..d3a59c688fe 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -319,7 +319,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
f_dev->parent = device;
f_dev->class = &firmware_class;
dev_set_drvdata(f_dev, fw_priv);
- f_dev->uevent_suppress = 1;
+ dev_set_uevent_suppress(f_dev, 1);
retval = device_register(f_dev);
if (retval) {
dev_err(device, "%s: device_register failed\n", __func__);
@@ -366,7 +366,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
}
if (uevent)
- f_dev->uevent_suppress = 0;
+ dev_set_uevent_suppress(f_dev, 0);
*dev_p = f_dev;
goto out;
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 43fa90b837e..f8f578a71b2 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -303,7 +303,7 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk)
sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index);
sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1;
for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
- unsigned int nid;
+ int nid;
nid = get_nid_for_pfn(pfn);
if (nid < 0)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 349a1013603..d2198f64ad4 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -217,6 +217,7 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
if (d) {
memcpy(d, data, size);
pdev->dev.platform_data = d;
+ pdev->platform_data = d;
}
return d ? 0 : -ENOMEM;
}
@@ -246,6 +247,21 @@ int platform_device_add(struct platform_device *pdev)
else
dev_set_name(&pdev->dev, pdev->name);
+ /* We will remove platform_data field from struct device
+ * if all platform devices pass its platform specific data
+ * from platform_device. The conversion is going to be a
+ * long time, so we allow the two cases coexist to make
+ * this kind of fix more easily*/
+ if (pdev->platform_data && pdev->dev.platform_data) {
+ printk(KERN_ERR
+ "%s: use which platform_data?\n",
+ dev_name(&pdev->dev));
+ } else if (pdev->platform_data) {
+ pdev->dev.platform_data = pdev->platform_data;
+ } else if (pdev->dev.platform_data) {
+ pdev->platform_data = pdev->dev.platform_data;
+ }
+
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];
@@ -584,10 +600,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct platform_device *pdev = to_platform_device(dev);
- add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
+ add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
+ (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
return 0;
}
+static const struct platform_device_id *platform_match_id(
+ struct platform_device_id *id,
+ struct platform_device *pdev)
+{
+ while (id->name[0]) {
+ if (strcmp(pdev->name, id->name) == 0) {
+ pdev->id_entry = id;
+ return id;
+ }
+ id++;
+ }
+ return NULL;
+}
+
/**
* platform_match - bind platform device to platform driver.
* @dev: device.
@@ -603,9 +634,14 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
*/
static int platform_match(struct device *dev, struct device_driver *drv)
{
- struct platform_device *pdev;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct platform_driver *pdrv = to_platform_driver(drv);
- pdev = container_of(dev, struct platform_device, dev);
+ /* match against the id table first */
+ if (pdrv->id_table)
+ return platform_match_id(pdrv->id_table, pdev) != NULL;
+
+ /* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
@@ -623,26 +659,24 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
{
- struct platform_driver *drv = to_platform_driver(dev->driver);
- struct platform_device *pdev;
+ struct platform_driver *pdrv = to_platform_driver(dev->driver);
+ struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
- pdev = container_of(dev, struct platform_device, dev);
- if (dev->driver && drv->suspend_late)
- ret = drv->suspend_late(pdev, mesg);
+ if (dev->driver && pdrv->suspend_late)
+ ret = pdrv->suspend_late(pdev, mesg);
return ret;
}
static int platform_legacy_resume_early(struct device *dev)
{
- struct platform_driver *drv = to_platform_driver(dev->driver);
- struct platform_device *pdev;
+ struct platform_driver *pdrv = to_platform_driver(dev->driver);
+ struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
- pdev = container_of(dev, struct platform_device, dev);
- if (dev->driver && drv->resume_early)
- ret = drv->resume_early(pdev);
+ if (dev->driver && pdrv->resume_early)
+ ret = pdrv->resume_early(pdev);
return ret;
}
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 670c9d6c140..e255341682c 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -107,6 +107,50 @@ void device_pm_remove(struct device *dev)
}
/**
+ * device_pm_move_before - move device in dpm_list
+ * @deva: Device to move in dpm_list
+ * @devb: Device @deva should come before
+ */
+void device_pm_move_before(struct device *deva, struct device *devb)
+{
+ pr_debug("PM: Moving %s:%s before %s:%s\n",
+ deva->bus ? deva->bus->name : "No Bus",
+ kobject_name(&deva->kobj),
+ devb->bus ? devb->bus->name : "No Bus",
+ kobject_name(&devb->kobj));
+ /* Delete deva from dpm_list and reinsert before devb. */
+ list_move_tail(&deva->power.entry, &devb->power.entry);
+}
+
+/**
+ * device_pm_move_after - move device in dpm_list
+ * @deva: Device to move in dpm_list
+ * @devb: Device @deva should come after
+ */
+void device_pm_move_after(struct device *deva, struct device *devb)
+{
+ pr_debug("PM: Moving %s:%s after %s:%s\n",
+ deva->bus ? deva->bus->name : "No Bus",
+ kobject_name(&deva->kobj),
+ devb->bus ? devb->bus->name : "No Bus",
+ kobject_name(&devb->kobj));
+ /* Delete deva from dpm_list and reinsert after devb. */
+ list_move(&deva->power.entry, &devb->power.entry);
+}
+
+/**
+ * device_pm_move_last - move device to end of dpm_list
+ * @dev: Device to move in dpm_list
+ */
+void device_pm_move_last(struct device *dev)
+{
+ pr_debug("PM: Moving %s:%s to end of list\n",
+ dev->bus ? dev->bus->name : "No Bus",
+ kobject_name(&dev->kobj));
+ list_move_tail(&dev->power.entry, &dpm_list);
+}
+
+/**
* pm_op - execute the PM operation appropiate for given PM event
* @dev: Device.
* @ops: PM operations to choose from.
@@ -333,7 +377,6 @@ static void dpm_power_up(pm_message_t state)
*/
void device_power_up(pm_message_t state)
{
- sysdev_resume();
dpm_power_up(state);
}
EXPORT_SYMBOL_GPL(device_power_up);
@@ -577,8 +620,6 @@ int device_power_down(pm_message_t state)
}
dev->power.status = DPM_OFF_IRQ;
}
- if (!error)
- error = sysdev_suspend(state);
if (error)
dpm_power_up(resume_event(state));
return error;
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 41f51fae042..c7cb4fc3735 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -18,11 +18,19 @@ static inline struct device *to_device(struct list_head *entry)
extern void device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
+extern void device_pm_move_before(struct device *, struct device *);
+extern void device_pm_move_after(struct device *, struct device *);
+extern void device_pm_move_last(struct device *);
#else /* CONFIG_PM_SLEEP */
static inline void device_pm_add(struct device *dev) {}
static inline void device_pm_remove(struct device *dev) {}
+static inline void device_pm_move_before(struct device *deva,
+ struct device *devb) {}
+static inline void device_pm_move_after(struct device *deva,
+ struct device *devb) {}
+static inline void device_pm_move_last(struct device *dev) {}
#endif
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index c98c31ec2f7..cbd36cf59a0 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -30,10 +30,10 @@
static ssize_t
-sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
+sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
{
- struct sys_device * sysdev = to_sysdev(kobj);
- struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+ struct sys_device *sysdev = to_sysdev(kobj);
+ struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->show)
return sysdev_attr->show(sysdev, sysdev_attr, buffer);
@@ -42,11 +42,11 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
static ssize_t
-sysdev_store(struct kobject * kobj, struct attribute * attr,
- const char * buffer, size_t count)
+sysdev_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
{
- struct sys_device * sysdev = to_sysdev(kobj);
- struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+ struct sys_device *sysdev = to_sysdev(kobj);
+ struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->store)
return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
@@ -63,13 +63,13 @@ static struct kobj_type ktype_sysdev = {
};
-int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a)
+int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a)
{
return sysfs_create_file(&s->kobj, &a->attr);
}
-void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
+void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a)
{
sysfs_remove_file(&s->kobj, &a->attr);
}
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file);
static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
char *buffer)
{
- struct sysdev_class * class = to_sysdev_class(kobj);
+ struct sysdev_class *class = to_sysdev_class(kobj);
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
if (class_attr->show)
@@ -95,8 +95,8 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t count)
{
- struct sysdev_class * class = to_sysdev_class(kobj);
- struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr);
+ struct sysdev_class *class = to_sysdev_class(kobj);
+ struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
if (class_attr->store)
return class_attr->store(class, buffer, count);
@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
static struct kset *system_kset;
-int sysdev_class_register(struct sysdev_class * cls)
+int sysdev_class_register(struct sysdev_class *cls)
{
pr_debug("Registering sysdev class '%s'\n", cls->name);
@@ -141,7 +141,7 @@ int sysdev_class_register(struct sysdev_class * cls)
return kset_register(&cls->kset);
}
-void sysdev_class_unregister(struct sysdev_class * cls)
+void sysdev_class_unregister(struct sysdev_class *cls)
{
pr_debug("Unregistering sysdev class '%s'\n",
kobject_name(&cls->kset.kobj));
@@ -203,8 +203,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
* @cls: Class driver belongs to.
* @drv: Driver.
*/
-void sysdev_driver_unregister(struct sysdev_class * cls,
- struct sysdev_driver * drv)
+void sysdev_driver_unregister(struct sysdev_class *cls,
+ struct sysdev_driver *drv)
{
mutex_lock(&sysdev_drivers_lock);
list_del_init(&drv->entry);
@@ -229,10 +229,10 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
* @sysdev: device in question
*
*/
-int sysdev_register(struct sys_device * sysdev)
+int sysdev_register(struct sys_device *sysdev)
{
int error;
- struct sysdev_class * cls = sysdev->cls;
+ struct sysdev_class *cls = sysdev->cls;
if (!cls)
return -EINVAL;
@@ -252,7 +252,7 @@ int sysdev_register(struct sys_device * sysdev)
sysdev->id);
if (!error) {
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;
pr_debug("Registering sys device '%s'\n",
kobject_name(&sysdev->kobj));
@@ -274,9 +274,9 @@ int sysdev_register(struct sys_device * sysdev)
return error;
}
-void sysdev_unregister(struct sys_device * sysdev)
+void sysdev_unregister(struct sys_device *sysdev)
{
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;
mutex_lock(&sysdev_drivers_lock);
list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
@@ -303,22 +303,21 @@ void sysdev_unregister(struct sys_device * sysdev)
* is guaranteed by virtue of the fact that child devices are registered
* after their parents.
*/
-
void sysdev_shutdown(void)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;
pr_debug("Shutting Down System Devices\n");
mutex_lock(&sysdev_drivers_lock);
list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
- struct sys_device * sysdev;
+ struct sys_device *sysdev;
pr_debug("Shutting down type '%s':\n",
kobject_name(&cls->kset.kobj));
list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;
pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call auxillary drivers first */
@@ -363,10 +362,9 @@ static void __sysdev_resume(struct sys_device *dev)
* This is only called by the device PM core, so we let them handle
* all synchronization.
*/
-
int sysdev_suspend(pm_message_t state)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;
struct sys_device *sysdev, *err_dev;
struct sysdev_driver *drv, *err_drv;
int ret;
@@ -432,7 +430,7 @@ aux_driver:
}
return ret;
}
-
+EXPORT_SYMBOL_GPL(sysdev_suspend);
/**
* sysdev_resume - Bring system devices back to life.
@@ -442,15 +440,14 @@ aux_driver:
*
* Note: Interrupts are disabled when called.
*/
-
int sysdev_resume(void)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;
pr_debug("Resuming System Devices\n");
list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
- struct sys_device * sysdev;
+ struct sys_device *sysdev;
pr_debug("Resuming type '%s':\n",
kobject_name(&cls->kset.kobj));
@@ -463,7 +460,7 @@ int sysdev_resume(void)
}
return 0;
}
-
+EXPORT_SYMBOL_GPL(sysdev_resume);
int __init system_bus_init(void)
{
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 0344a8a8321..e7b8aa0cb47 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -45,6 +45,13 @@ config MAC_FLOPPY
If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple)
floppy controller, say Y here. Most commonly found in PowerMacs.
+config BLK_DEV_SWIM
+ tristate "Support for SWIM Macintosh floppy"
+ depends on M68K && MAC
+ help
+ You should select this option if you want floppy support
+ and you don't have a II, IIfx, Q900, Q950 or AV series.
+
config AMIGA_Z2RAM
tristate "Amiga Zorro II ramdisk support"
depends on ZORRO
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 204332b2957..3145141cef7 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -6,9 +6,11 @@
#
obj-$(CONFIG_MAC_FLOPPY) += swim3.o
+obj-$(CONFIG_BLK_DEV_SWIM) += swim_mod.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
obj-$(CONFIG_PS3_DISK) += ps3disk.o
+obj-$(CONFIG_PS3_VRAM) += ps3vram.o
obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
obj-$(CONFIG_BLK_DEV_RAM) += brd.o
@@ -32,3 +34,5 @@ obj-$(CONFIG_BLK_DEV_UB) += ub.o
obj-$(CONFIG_BLK_DEV_HD) += hd.o
obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o
+
+swim_mod-objs := swim.o swim_asm.o
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index c237527b1aa..5e41e6dd657 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -18,6 +18,7 @@
enum {
AOECMD_ATA,
AOECMD_CFG,
+ AOECMD_VEND_MIN = 0xf0,
AOEFL_RSP = (1<<3),
AOEFL_ERR = (1<<2),
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index cc250577d40..eeea477d960 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -173,7 +173,7 @@ skbfree(struct sk_buff *skb)
return;
while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0)
msleep(Sms);
- if (i <= 0) {
+ if (i < 0) {
printk(KERN_ERR
"aoe: %s holds ref: %s\n",
skb->dev ? skb->dev->name : "netif",
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 30de5b1c647..ce0d62cd71b 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -142,6 +142,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
aoecmd_cfg_rsp(skb);
break;
default:
+ if (h->cmd >= AOECMD_VEND_MIN)
+ break; /* don't complain about vendor commands */
printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
}
exit:
@@ -149,7 +151,7 @@ exit:
return 0;
}
-static struct packet_type aoe_pt = {
+static struct packet_type aoe_pt __read_mostly = {
.type = __constant_htons(ETH_P_AOE),
.func = aoenet_rcv,
};
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 69e1df7dfa1..4234c11c1e4 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1730,7 +1730,7 @@ static int __init fd_test_drive_present( int drive )
timeout = jiffies + 2*HZ+HZ/2;
while (time_before(jiffies, timeout))
- if (!(mfp.par_dt_reg & 0x20))
+ if (!(st_mfp.par_dt_reg & 0x20))
break;
status = FDC_READ( FDCREG_STATUS );
@@ -1747,7 +1747,7 @@ static int __init fd_test_drive_present( int drive )
/* dummy seek command to make WP bit accessible */
FDC_WRITE( FDCREG_DATA, 0 );
FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );
- while( mfp.par_dt_reg & 0x20 )
+ while( st_mfp.par_dt_reg & 0x20 )
;
status = FDC_READ( FDCREG_STATUS );
}
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 01e69383d9c..5d0e135824f 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3390,6 +3390,203 @@ static void free_hba(int i)
kfree(p);
}
+/* Send a message CDB to the firmware. */
+static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, unsigned char type)
+{
+ typedef struct {
+ CommandListHeader_struct CommandHeader;
+ RequestBlock_struct Request;
+ ErrDescriptor_struct ErrorDescriptor;
+ } Command;
+ static const size_t cmd_sz = sizeof(Command) + sizeof(ErrorInfo_struct);
+ Command *cmd;
+ dma_addr_t paddr64;
+ uint32_t paddr32, tag;
+ void __iomem *vaddr;
+ int i, err;
+
+ vaddr = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+ if (vaddr == NULL)
+ return -ENOMEM;
+
+ /* The Inbound Post Queue only accepts 32-bit physical addresses for the
+ CCISS commands, so they must be allocated from the lower 4GiB of
+ memory. */
+ err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err) {
+ iounmap(vaddr);
+ return -ENOMEM;
+ }
+
+ cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64);
+ if (cmd == NULL) {
+ iounmap(vaddr);
+ return -ENOMEM;
+ }
+
+ /* This must fit, because of the 32-bit consistent DMA mask. Also,
+ although there's no guarantee, we assume that the address is at
+ least 4-byte aligned (most likely, it's page-aligned). */
+ paddr32 = paddr64;
+
+ cmd->CommandHeader.ReplyQueue = 0;
+ cmd->CommandHeader.SGList = 0;
+ cmd->CommandHeader.SGTotal = 0;
+ cmd->CommandHeader.Tag.lower = paddr32;
+ cmd->CommandHeader.Tag.upper = 0;
+ memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8);
+
+ cmd->Request.CDBLen = 16;
+ cmd->Request.Type.Type = TYPE_MSG;
+ cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE;
+ cmd->Request.Type.Direction = XFER_NONE;
+ cmd->Request.Timeout = 0; /* Don't time out */
+ cmd->Request.CDB[0] = opcode;
+ cmd->Request.CDB[1] = type;
+ memset(&cmd->Request.CDB[2], 0, 14); /* the rest of the CDB is reserved */
+
+ cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(Command);
+ cmd->ErrorDescriptor.Addr.upper = 0;
+ cmd->ErrorDescriptor.Len = sizeof(ErrorInfo_struct);
+
+ writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET);
+
+ for (i = 0; i < 10; i++) {
+ tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
+ if ((tag & ~3) == paddr32)
+ break;
+ schedule_timeout_uninterruptible(HZ);
+ }
+
+ iounmap(vaddr);
+
+ /* we leak the DMA buffer here ... no choice since the controller could
+ still complete the command. */
+ if (i == 10) {
+ printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n",
+ opcode, type);
+ return -ETIMEDOUT;
+ }
+
+ pci_free_consistent(pdev, cmd_sz, cmd, paddr64);
+
+ if (tag & 2) {
+ printk(KERN_ERR "cciss: controller message %02x:%02x failed\n",
+ opcode, type);
+ return -EIO;
+ }
+
+ printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n",
+ opcode, type);
+ return 0;
+}
+
+#define cciss_soft_reset_controller(p) cciss_message(p, 1, 0)
+#define cciss_noop(p) cciss_message(p, 3, 0)
+
+static __devinit int cciss_reset_msi(struct pci_dev *pdev)
+{
+/* the #defines are stolen from drivers/pci/msi.h. */
+#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
+#define PCI_MSIX_FLAGS_ENABLE (1 << 15)
+
+ int pos;
+ u16 control = 0;
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_MSI);
+ if (pos) {
+ pci_read_config_word(pdev, msi_control_reg(pos), &control);
+ if (control & PCI_MSI_FLAGS_ENABLE) {
+ printk(KERN_INFO "cciss: resetting MSI\n");
+ pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE);
+ }
+ }
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
+ if (pos) {
+ pci_read_config_word(pdev, msi_control_reg(pos), &control);
+ if (control & PCI_MSIX_FLAGS_ENABLE) {
+ printk(KERN_INFO "cciss: resetting MSI-X\n");
+ pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE);
+ }
+ }
+
+ return 0;
+}
+
+/* This does a hard reset of the controller using PCI power management
+ * states. */
+static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev)
+{
+ u16 pmcsr, saved_config_space[32];
+ int i, pos;
+
+ printk(KERN_INFO "cciss: using PCI PM to reset controller\n");
+
+ /* This is very nearly the same thing as
+
+ pci_save_state(pci_dev);
+ pci_set_power_state(pci_dev, PCI_D3hot);
+ pci_set_power_state(pci_dev, PCI_D0);
+ pci_restore_state(pci_dev);
+
+ but we can't use these nice canned kernel routines on
+ kexec, because they also check the MSI/MSI-X state in PCI
+ configuration space and do the wrong thing when it is
+ set/cleared. Also, the pci_save/restore_state functions
+ violate the ordering requirements for restoring the
+ configuration space from the CCISS document (see the
+ comment below). So we roll our own .... */
+
+ for (i = 0; i < 32; i++)
+ pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
+ if (pos == 0) {
+ printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n");
+ return -ENODEV;
+ }
+
+ /* Quoting from the Open CISS Specification: "The Power
+ * Management Control/Status Register (CSR) controls the power
+ * state of the device. The normal operating state is D0,
+ * CSR=00h. The software off state is D3, CSR=03h. To reset
+ * the controller, place the interface device in D3 then to
+ * D0, this causes a secondary PCI reset which will reset the
+ * controller." */
+
+ /* enter the D3hot power management state */
+ pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
+ pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ pmcsr |= PCI_D3hot;
+ pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+
+ schedule_timeout_uninterruptible(HZ >> 1);
+
+ /* enter the D0 power management state */
+ pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ pmcsr |= PCI_D0;
+ pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+
+ schedule_timeout_uninterruptible(HZ >> 1);
+
+ /* Restore the PCI configuration space. The Open CISS
+ * Specification says, "Restore the PCI Configuration
+ * Registers, offsets 00h through 60h. It is important to
+ * restore the command register, 16-bits at offset 04h,
+ * last. Do not restore the configuration status register,
+ * 16-bits at offset 06h." Note that the offset is 2*i. */
+ for (i = 0; i < 32; i++) {
+ if (i == 2 || i == 3)
+ continue;
+ pci_write_config_word(pdev, 2*i, saved_config_space[i]);
+ }
+ wmb();
+ pci_write_config_word(pdev, 4, saved_config_space[2]);
+
+ return 0;
+}
+
/*
* This is it. Find all the controllers and register them. I really hate
* stealing all these major device numbers.
@@ -3404,6 +3601,26 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
int dac, return_code;
InquiryData_struct *inq_buff = NULL;
+ if (reset_devices) {
+ /* Reset the controller with a PCI power-cycle */
+ if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev))
+ return -ENODEV;
+
+ /* Now try to get the controller to respond to a no-op. Some
+ devices (notably the HP Smart Array 5i Controller) need
+ up to 30 seconds to respond. */
+ for (i=0; i<30; i++) {
+ if (cciss_noop(pdev) == 0)
+ break;
+
+ schedule_timeout_uninterruptible(HZ);
+ }
+ if (i == 30) {
+ printk(KERN_ERR "cciss: controller seems dead\n");
+ return -EBUSY;
+ }
+ }
+
i = alloc_cciss_hba();
if (i < 0)
return -1;
@@ -3681,6 +3898,13 @@ static struct pci_driver cciss_pci_driver = {
*/
static int __init cciss_init(void)
{
+ /*
+ * The hardware requires that commands are aligned on a 64-bit
+ * boundary. Given that we use pci_alloc_consistent() to allocate an
+ * array of them, the size must be a multiple of 8 bytes.
+ */
+ BUILD_BUG_ON(sizeof(CommandList_struct) % 8);
+
printk(KERN_INFO DRIVER_NAME "\n");
/* Register for our PCI devices */
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 5d39df14ed9..ca268ca1115 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -617,6 +617,7 @@ static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
int i;
c->pci_dev = pdev;
+ pci_set_master(pdev);
if (pci_enable_device(pdev)) {
printk(KERN_ERR "cpqarray: Unable to Enable PCI device\n");
return -1;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index cf29cc4e6ab..c2c95e61450 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -558,6 +558,8 @@ static void process_fd_request(void);
static void recalibrate_floppy(void);
static void floppy_shutdown(unsigned long);
+static int floppy_request_regions(int);
+static void floppy_release_regions(int);
static int floppy_grab_irq_and_dma(void);
static void floppy_release_irq_and_dma(void);
@@ -4133,10 +4135,9 @@ static int have_no_fdc = -ENODEV;
static ssize_t floppy_cmos_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct platform_device *p;
+ struct platform_device *p = to_platform_device(dev);
int drive;
- p = container_of(dev, struct platform_device,dev);
drive = p->id;
return sprintf(buf, "%X\n", UDP->cmos);
}
@@ -4274,8 +4275,7 @@ static int __init floppy_init(void)
FDCS->rawcmd = 2;
if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) {
/* free ioports reserved by floppy_grab_irq_and_dma() */
- release_region(FDCS->address + 2, 4);
- release_region(FDCS->address + 7, 1);
+ floppy_release_regions(fdc);
FDCS->address = -1;
FDCS->version = FDC_NONE;
continue;
@@ -4284,8 +4284,7 @@ static int __init floppy_init(void)
FDCS->version = get_fdc_version();
if (FDCS->version == FDC_NONE) {
/* free ioports reserved by floppy_grab_irq_and_dma() */
- release_region(FDCS->address + 2, 4);
- release_region(FDCS->address + 7, 1);
+ floppy_release_regions(fdc);
FDCS->address = -1;
continue;
}
@@ -4358,6 +4357,47 @@ out_put_disk:
static DEFINE_SPINLOCK(floppy_usage_lock);
+static const struct io_region {
+ int offset;
+ int size;
+} io_regions[] = {
+ { 2, 1 },
+ /* address + 3 is sometimes reserved by pnp bios for motherboard */
+ { 4, 2 },
+ /* address + 6 is reserved, and may be taken by IDE.
+ * Unfortunately, Adaptec doesn't know this :-(, */
+ { 7, 1 },
+};
+
+static void floppy_release_allocated_regions(int fdc, const struct io_region *p)
+{
+ while (p != io_regions) {
+ p--;
+ release_region(FDCS->address + p->offset, p->size);
+ }
+}
+
+#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)]))
+
+static int floppy_request_regions(int fdc)
+{
+ const struct io_region *p;
+
+ for (p = io_regions; p < ARRAY_END(io_regions); p++) {
+ if (!request_region(FDCS->address + p->offset, p->size, "floppy")) {
+ DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset);
+ floppy_release_allocated_regions(fdc, p);
+ return -EBUSY;
+ }
+ }
+ return 0;
+}
+
+static void floppy_release_regions(int fdc)
+{
+ floppy_release_allocated_regions(fdc, ARRAY_END(io_regions));
+}
+
static int floppy_grab_irq_and_dma(void)
{
unsigned long flags;
@@ -4399,18 +4439,8 @@ static int floppy_grab_irq_and_dma(void)
for (fdc = 0; fdc < N_FDC; fdc++) {
if (FDCS->address != -1) {
- if (!request_region(FDCS->address + 2, 4, "floppy")) {
- DPRINT("Floppy io-port 0x%04lx in use\n",
- FDCS->address + 2);
- goto cleanup1;
- }
- if (!request_region(FDCS->address + 7, 1, "floppy DIR")) {
- DPRINT("Floppy io-port 0x%04lx in use\n",
- FDCS->address + 7);
- goto cleanup2;
- }
- /* address + 6 is reserved, and may be taken by IDE.
- * Unfortunately, Adaptec doesn't know this :-(, */
+ if (floppy_request_regions(fdc))
+ goto cleanup;
}
}
for (fdc = 0; fdc < N_FDC; fdc++) {
@@ -4432,15 +4462,11 @@ static int floppy_grab_irq_and_dma(void)
fdc = 0;
irqdma_allocated = 1;
return 0;
-cleanup2:
- release_region(FDCS->address + 2, 4);
-cleanup1:
+cleanup:
fd_free_irq();
fd_free_dma();
- while (--fdc >= 0) {
- release_region(FDCS->address + 2, 4);
- release_region(FDCS->address + 7, 1);
- }
+ while (--fdc >= 0)
+ floppy_release_regions(fdc);
spin_lock_irqsave(&floppy_usage_lock, flags);
usage_count--;
spin_unlock_irqrestore(&floppy_usage_lock, flags);
@@ -4501,10 +4527,8 @@ static void floppy_release_irq_and_dma(void)
#endif
old_fdc = fdc;
for (fdc = 0; fdc < N_FDC; fdc++)
- if (FDCS->address != -1) {
- release_region(FDCS->address + 2, 4);
- release_region(FDCS->address + 7, 1);
- }
+ if (FDCS->address != -1)
+ floppy_release_regions(fdc);
fdc = old_fdc;
}
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index edbaac6c057..2621ed2ce6d 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -392,8 +392,7 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
struct loop_device *lo = p->lo;
struct page *page = buf->page;
sector_t IV;
- size_t size;
- int ret;
+ int size, ret;
ret = buf->ops->confirm(pipe, buf);
if (unlikely(ret))
@@ -475,10 +474,35 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
int ret;
pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
- if (bio_rw(bio) == WRITE)
+
+ if (bio_rw(bio) == WRITE) {
+ int barrier = bio_barrier(bio);
+ struct file *file = lo->lo_backing_file;
+
+ if (barrier) {
+ if (unlikely(!file->f_op->fsync)) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ ret = vfs_fsync(file, file->f_path.dentry, 0);
+ if (unlikely(ret)) {
+ ret = -EIO;
+ goto out;
+ }
+ }
+
ret = lo_send(lo, bio, pos);
- else
+
+ if (barrier && !ret) {
+ ret = vfs_fsync(file, file->f_path.dentry, 0);
+ if (unlikely(ret))
+ ret = -EIO;
+ }
+ } else
ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
+
+out:
return ret;
}
@@ -827,6 +851,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
lo->lo_queue->queuedata = lo;
lo->lo_queue->unplug_fn = loop_unplug;
+ if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
+ blk_queue_ordered(lo->lo_queue, QUEUE_ORDERED_DRAIN, NULL);
+
set_capacity(lo->lo_disk, size);
bd_set_size(bdev, size << 9);
@@ -942,11 +969,18 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
bd_set_size(bdev, 0);
mapping_set_gfp_mask(filp->f_mapping, gfp);
lo->lo_state = Lo_unbound;
- fput(filp);
/* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE);
if (max_part > 0)
ioctl_by_bdev(bdev, BLKRRPART, 0);
+ mutex_unlock(&lo->lo_ctl_mutex);
+ /*
+ * Need not hold lo_ctl_mutex to fput backing file.
+ * Calling fput holding lo_ctl_mutex triggers a circular
+ * lock dependency possibility warning as fput can take
+ * bd_mutex which is usually taken before lo_ctl_mutex.
+ */
+ fput(filp);
return 0;
}
@@ -1164,7 +1198,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
struct loop_device *lo = bdev->bd_disk->private_data;
int err;
- mutex_lock(&lo->lo_ctl_mutex);
+ mutex_lock_nested(&lo->lo_ctl_mutex, 1);
switch (cmd) {
case LOOP_SET_FD:
err = loop_set_fd(lo, mode, bdev, arg);
@@ -1173,7 +1207,10 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
err = loop_change_fd(lo, bdev, arg);
break;
case LOOP_CLR_FD:
+ /* loop_clr_fd would have unlocked lo_ctl_mutex on success */
err = loop_clr_fd(lo, bdev);
+ if (!err)
+ goto out_unlocked;
break;
case LOOP_SET_STATUS:
err = loop_set_status_old(lo, (struct loop_info __user *) arg);
@@ -1191,6 +1228,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
}
mutex_unlock(&lo->lo_ctl_mutex);
+
+out_unlocked:
return err;
}
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 34f80fa6fed..8299e2d3b61 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -549,6 +549,15 @@ static void do_nbd_request(struct request_queue * q)
BUG_ON(lo->magic != LO_MAGIC);
+ if (unlikely(!lo->sock)) {
+ printk(KERN_ERR "%s: Attempted send on closed socket\n",
+ lo->disk->disk_name);
+ req->errors++;
+ nbd_end_request(req);
+ spin_lock_irq(q->queue_lock);
+ continue;
+ }
+
spin_lock_irq(&lo->queue_lock);
list_add_tail(&req->queuelist, &lo->waiting_queue);
spin_unlock_irq(&lo->queue_lock);
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 9dfa2716300..c397b3ddba9 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -422,7 +422,7 @@ static void xs(char *buf, char *targ, int len)
for (k = 0; k < len; k++) {
char c = *buf++;
- if (c != ' ' || c != l)
+ if (c != ' ' && c != l)
l = *targ++ = c;
}
if (l == ' ')
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 936466f62af..bccc42bb921 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -141,7 +141,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
start_sector = req->sector * priv->blocking_factor;
sectors = req->nr_sectors * priv->blocking_factor;
- dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n",
+ dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
__func__, __LINE__, op, sectors, start_sector);
if (write) {
@@ -178,7 +178,7 @@ static int ps3disk_submit_flush_request(struct ps3_storage_device *dev,
LV1_STORAGE_ATA_HDDOUT, 0, 0, 0,
0, &dev->tag);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
__func__, __LINE__, res);
end_request(req, 0);
return 0;
@@ -238,11 +238,11 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
if (tag != dev->tag)
dev_err(&dev->sbd.core,
- "%s:%u: tag mismatch, got %lx, expected %lx\n",
+ "%s:%u: tag mismatch, got %llx, expected %llx\n",
__func__, __LINE__, tag, dev->tag);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
__func__, __LINE__, res, status);
return IRQ_HANDLED;
}
@@ -269,7 +269,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
op = read ? "read" : "write";
}
if (status) {
- dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
+ dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
__LINE__, op, status);
error = -EIO;
} else {
@@ -297,7 +297,7 @@ static int ps3disk_sync_cache(struct ps3_storage_device *dev)
res = ps3stor_send_command(dev, LV1_STORAGE_ATA_HDDOUT, 0, 0, 0, 0);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
__func__, __LINE__, res);
return -EIO;
}
@@ -388,7 +388,7 @@ static int ps3disk_identify(struct ps3_storage_device *dev)
sizeof(ata_cmnd), ata_cmnd.buffer,
ata_cmnd.arglen);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%llx\n",
__func__, __LINE__, res);
return -EIO;
}
@@ -426,7 +426,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
if (dev->blk_size < 512) {
dev_err(&dev->sbd.core,
- "%s:%u: cannot handle block size %lu\n", __func__,
+ "%s:%u: cannot handle block size %llu\n", __func__,
__LINE__, dev->blk_size);
return -EINVAL;
}
@@ -512,7 +512,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
dev->regions[dev->region_idx].size*priv->blocking_factor);
dev_info(&dev->sbd.core,
- "%s is a %s (%lu MiB total, %lu MiB for OtherOS)\n",
+ "%s is a %s (%llu MiB total, %lu MiB for OtherOS)\n",
gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
get_capacity(gendisk) >> 11);
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
new file mode 100644
index 00000000000..393ed6760d7
--- /dev/null
+++ b/drivers/block/ps3vram.c
@@ -0,0 +1,865 @@
+/*
+ * ps3vram - Use extra PS3 video ram as MTD block device.
+ *
+ * Copyright 2009 Sony Corporation
+ *
+ * Based on the MTD ps3vram driver, which is
+ * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com>
+ * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr>
+ */
+
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/firmware.h>
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+
+
+#define DEVICE_NAME "ps3vram"
+
+
+#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */
+#define XDR_IOIF 0x0c000000
+
+#define FIFO_BASE XDR_IOIF
+#define FIFO_SIZE (64 * 1024)
+
+#define DMA_PAGE_SIZE (4 * 1024)
+
+#define CACHE_PAGE_SIZE (256 * 1024)
+#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE)
+
+#define CACHE_OFFSET CACHE_PAGE_SIZE
+#define FIFO_OFFSET 0
+
+#define CTRL_PUT 0x10
+#define CTRL_GET 0x11
+#define CTRL_TOP 0x15
+
+#define UPLOAD_SUBCH 1
+#define DOWNLOAD_SUBCH 2
+
+#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104
+
+#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
+
+#define CACHE_PAGE_PRESENT 1
+#define CACHE_PAGE_DIRTY 2
+
+struct ps3vram_tag {
+ unsigned int address;
+ unsigned int flags;
+};
+
+struct ps3vram_cache {
+ unsigned int page_count;
+ unsigned int page_size;
+ struct ps3vram_tag *tags;
+ unsigned int hit;
+ unsigned int miss;
+};
+
+struct ps3vram_priv {
+ struct request_queue *queue;
+ struct gendisk *gendisk;
+
+ u64 size;
+
+ u64 memory_handle;
+ u64 context_handle;
+ u32 *ctrl;
+ u32 *reports;
+ u8 __iomem *ddr_base;
+ u8 *xdr_buf;
+
+ u32 *fifo_base;
+ u32 *fifo_ptr;
+
+ struct ps3vram_cache cache;
+
+ /* Used to serialize cache/DMA operations */
+ struct mutex lock;
+};
+
+
+static int ps3vram_major;
+
+
+static struct block_device_operations ps3vram_fops = {
+ .owner = THIS_MODULE,
+};
+
+
+#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */
+#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */
+#define DMA_NOTIFIER_SIZE 0x40
+#define NOTIFIER 7 /* notifier used for completion report */
+
+static char *size = "256M";
+module_param(size, charp, 0);
+MODULE_PARM_DESC(size, "memory size");
+
+static u32 *ps3vram_get_notifier(u32 *reports, int notifier)
+{
+ return (void *)reports + DMA_NOTIFIER_OFFSET_BASE +
+ DMA_NOTIFIER_SIZE * notifier;
+}
+
+static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
+ int i;
+
+ for (i = 0; i < 4; i++)
+ notify[i] = 0xffffffff;
+}
+
+static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
+ unsigned int timeout_ms)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
+ unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+
+ do {
+ if (!notify[3])
+ return 0;
+ msleep(1);
+ } while (time_before(jiffies, timeout));
+
+ return -ETIMEDOUT;
+}
+
+static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+
+ priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
+ priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
+}
+
+static int ps3vram_wait_ring(struct ps3_system_bus_device *dev,
+ unsigned int timeout_ms)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+
+ do {
+ if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET])
+ return 0;
+ msleep(1);
+ } while (time_before(jiffies, timeout));
+
+ dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n",
+ priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET],
+ priv->ctrl[CTRL_TOP]);
+
+ return -ETIMEDOUT;
+}
+
+static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data)
+{
+ *(priv->fifo_ptr)++ = data;
+}
+
+static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag,
+ u32 size)
+{
+ ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag);
+}
+
+static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ int status;
+
+ ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
+
+ priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
+
+ /* asking the HV for a blit will kick the FIFO */
+ status = lv1_gpu_context_attribute(priv->context_handle,
+ L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
+ 0, 0, 0);
+ if (status)
+ dev_err(&dev->core,
+ "%s: lv1_gpu_context_attribute failed %d\n", __func__,
+ status);
+
+ priv->fifo_ptr = priv->fifo_base;
+}
+
+static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ int status;
+
+ mutex_lock(&ps3_gpu_mutex);
+
+ priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET +
+ (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
+
+ /* asking the HV for a blit will kick the FIFO */
+ status = lv1_gpu_context_attribute(priv->context_handle,
+ L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
+ 0, 0, 0);
+ if (status)
+ dev_err(&dev->core,
+ "%s: lv1_gpu_context_attribute failed %d\n", __func__,
+ status);
+
+ if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
+ FIFO_SIZE - 1024) {
+ dev_dbg(&dev->core, "FIFO full, rewinding\n");
+ ps3vram_wait_ring(dev, 200);
+ ps3vram_rewind_ring(dev);
+ }
+
+ mutex_unlock(&ps3_gpu_mutex);
+}
+
+static void ps3vram_bind(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+
+ ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
+ ps3vram_out_ring(priv, 0x31337303);
+ ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3);
+ ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
+ ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */
+ ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */
+
+ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1);
+ ps3vram_out_ring(priv, 0x3137c0de);
+ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3);
+ ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
+ ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */
+ ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */
+
+ ps3vram_fire_ring(dev);
+}
+
+static int ps3vram_upload(struct ps3_system_bus_device *dev,
+ unsigned int src_offset, unsigned int dst_offset,
+ int len, int count)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+
+ ps3vram_begin_ring(priv, UPLOAD_SUBCH,
+ NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+ ps3vram_out_ring(priv, XDR_IOIF + src_offset);
+ ps3vram_out_ring(priv, dst_offset);
+ ps3vram_out_ring(priv, len);
+ ps3vram_out_ring(priv, len);
+ ps3vram_out_ring(priv, len);
+ ps3vram_out_ring(priv, count);
+ ps3vram_out_ring(priv, (1 << 8) | 1);
+ ps3vram_out_ring(priv, 0);
+
+ ps3vram_notifier_reset(dev);
+ ps3vram_begin_ring(priv, UPLOAD_SUBCH,
+ NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
+ ps3vram_out_ring(priv, 0);
+ ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1);
+ ps3vram_out_ring(priv, 0);
+ ps3vram_fire_ring(dev);
+ if (ps3vram_notifier_wait(dev, 200) < 0) {
+ dev_warn(&dev->core, "%s: Notifier timeout\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ps3vram_download(struct ps3_system_bus_device *dev,
+ unsigned int src_offset, unsigned int dst_offset,
+ int len, int count)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+
+ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
+ NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+ ps3vram_out_ring(priv, src_offset);
+ ps3vram_out_ring(priv, XDR_IOIF + dst_offset);
+ ps3vram_out_ring(priv, len);
+ ps3vram_out_ring(priv, len);
+ ps3vram_out_ring(priv, len);
+ ps3vram_out_ring(priv, count);
+ ps3vram_out_ring(priv, (1 << 8) | 1);
+ ps3vram_out_ring(priv, 0);
+
+ ps3vram_notifier_reset(dev);
+ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
+ NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
+ ps3vram_out_ring(priv, 0);
+ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1);
+ ps3vram_out_ring(priv, 0);
+ ps3vram_fire_ring(dev);
+ if (ps3vram_notifier_wait(dev, 200) < 0) {
+ dev_warn(&dev->core, "%s: Notifier timeout\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ struct ps3vram_cache *cache = &priv->cache;
+
+ if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY))
+ return;
+
+ dev_dbg(&dev->core, "Flushing %d: 0x%08x\n", entry,
+ cache->tags[entry].address);
+ if (ps3vram_upload(dev, CACHE_OFFSET + entry * cache->page_size,
+ cache->tags[entry].address, DMA_PAGE_SIZE,
+ cache->page_size / DMA_PAGE_SIZE) < 0) {
+ dev_err(&dev->core,
+ "Failed to upload from 0x%x to " "0x%x size 0x%x\n",
+ entry * cache->page_size, cache->tags[entry].address,
+ cache->page_size);
+ }
+ cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY;
+}
+
+static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry,
+ unsigned int address)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ struct ps3vram_cache *cache = &priv->cache;
+
+ dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address);
+ if (ps3vram_download(dev, address,
+ CACHE_OFFSET + entry * cache->page_size,
+ DMA_PAGE_SIZE,
+ cache->page_size / DMA_PAGE_SIZE) < 0) {
+ dev_err(&dev->core,
+ "Failed to download from 0x%x to 0x%x size 0x%x\n",
+ address, entry * cache->page_size, cache->page_size);
+ }
+
+ cache->tags[entry].address = address;
+ cache->tags[entry].flags |= CACHE_PAGE_PRESENT;
+}
+
+
+static void ps3vram_cache_flush(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ struct ps3vram_cache *cache = &priv->cache;
+ int i;
+
+ dev_dbg(&dev->core, "FLUSH\n");
+ for (i = 0; i < cache->page_count; i++) {
+ ps3vram_cache_evict(dev, i);
+ cache->tags[i].flags = 0;
+ }
+}
+
+static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev,
+ loff_t address)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ struct ps3vram_cache *cache = &priv->cache;
+ unsigned int base;
+ unsigned int offset;
+ int i;
+ static int counter;
+
+ offset = (unsigned int) (address & (cache->page_size - 1));
+ base = (unsigned int) (address - offset);
+
+ /* fully associative check */
+ for (i = 0; i < cache->page_count; i++) {
+ if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) &&
+ cache->tags[i].address == base) {
+ cache->hit++;
+ dev_dbg(&dev->core, "Found entry %d: 0x%08x\n", i,
+ cache->tags[i].address);
+ return i;
+ }
+ }
+
+ /* choose a random entry */
+ i = (jiffies + (counter++)) % cache->page_count;
+ dev_dbg(&dev->core, "Using entry %d\n", i);
+
+ ps3vram_cache_evict(dev, i);
+ ps3vram_cache_load(dev, i, base);
+
+ cache->miss++;
+ return i;
+}
+
+static int ps3vram_cache_init(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+
+ priv->cache.page_count = CACHE_PAGE_COUNT;
+ priv->cache.page_size = CACHE_PAGE_SIZE;
+ priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) *
+ CACHE_PAGE_COUNT, GFP_KERNEL);
+ if (priv->cache.tags == NULL) {
+ dev_err(&dev->core, "Could not allocate cache tags\n");
+ return -ENOMEM;
+ }
+
+ dev_info(&dev->core, "Created ram cache: %d entries, %d KiB each\n",
+ CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024);
+
+ return 0;
+}
+
+static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+
+ ps3vram_cache_flush(dev);
+ kfree(priv->cache.tags);
+}
+
+static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
+ size_t len, size_t *retlen, u_char *buf)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ unsigned int cached, count;
+
+ dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__,
+ (unsigned int)from, len);
+
+ if (from >= priv->size)
+ return -EIO;
+
+ if (len > priv->size - from)
+ len = priv->size - from;
+
+ /* Copy from vram to buf */
+ count = len;
+ while (count) {
+ unsigned int offset, avail;
+ unsigned int entry;
+
+ offset = (unsigned int) (from & (priv->cache.page_size - 1));
+ avail = priv->cache.page_size - offset;
+
+ mutex_lock(&priv->lock);
+
+ entry = ps3vram_cache_match(dev, from);
+ cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
+
+ dev_dbg(&dev->core, "%s: from=%08x cached=%08x offset=%08x "
+ "avail=%08x count=%08x\n", __func__,
+ (unsigned int)from, cached, offset, avail, count);
+
+ if (avail > count)
+ avail = count;
+ memcpy(buf, priv->xdr_buf + cached, avail);
+
+ mutex_unlock(&priv->lock);
+
+ buf += avail;
+ count -= avail;
+ from += avail;
+ }
+
+ *retlen = len;
+ return 0;
+}
+
+static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
+ size_t len, size_t *retlen, const u_char *buf)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ unsigned int cached, count;
+
+ if (to >= priv->size)
+ return -EIO;
+
+ if (len > priv->size - to)
+ len = priv->size - to;
+
+ /* Copy from buf to vram */
+ count = len;
+ while (count) {
+ unsigned int offset, avail;
+ unsigned int entry;
+
+ offset = (unsigned int) (to & (priv->cache.page_size - 1));
+ avail = priv->cache.page_size - offset;
+
+ mutex_lock(&priv->lock);
+
+ entry = ps3vram_cache_match(dev, to);
+ cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
+
+ dev_dbg(&dev->core, "%s: to=%08x cached=%08x offset=%08x "
+ "avail=%08x count=%08x\n", __func__, (unsigned int)to,
+ cached, offset, avail, count);
+
+ if (avail > count)
+ avail = count;
+ memcpy(priv->xdr_buf + cached, buf, avail);
+
+ priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
+
+ mutex_unlock(&priv->lock);
+
+ buf += avail;
+ count -= avail;
+ to += avail;
+ }
+
+ *retlen = len;
+ return 0;
+}
+
+static int ps3vram_proc_show(struct seq_file *m, void *v)
+{
+ struct ps3vram_priv *priv = m->private;
+
+ seq_printf(m, "hit:%u\nmiss:%u\n", priv->cache.hit, priv->cache.miss);
+ return 0;
+}
+
+static int ps3vram_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ps3vram_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations ps3vram_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ps3vram_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+ struct proc_dir_entry *pde;
+
+ pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops);
+ if (!pde) {
+ dev_warn(&dev->core, "failed to create /proc entry\n");
+ return;
+ }
+
+ pde->owner = THIS_MODULE;
+ pde->data = priv;
+}
+
+static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
+{
+ struct ps3_system_bus_device *dev = q->queuedata;
+ int write = bio_data_dir(bio) == WRITE;
+ const char *op = write ? "write" : "read";
+ loff_t offset = bio->bi_sector << 9;
+ int error = 0;
+ struct bio_vec *bvec;
+ unsigned int i;
+
+ dev_dbg(&dev->core, "%s\n", __func__);
+
+ bio_for_each_segment(bvec, bio, i) {
+ /* PS3 is ppc64, so we don't handle highmem */
+ char *ptr = page_address(bvec->bv_page) + bvec->bv_offset;
+ size_t len = bvec->bv_len, retlen;
+
+ dev_dbg(&dev->core, " %s %zu bytes at offset %llu\n", op,
+ len, offset);
+ if (write)
+ error = ps3vram_write(dev, offset, len, &retlen, ptr);
+ else
+ error = ps3vram_read(dev, offset, len, &retlen, ptr);
+
+ if (error) {
+ dev_err(&dev->core, "%s failed\n", op);
+ goto out;
+ }
+
+ if (retlen != len) {
+ dev_err(&dev->core, "Short %s\n", op);
+ goto out;
+ }
+
+ offset += len;
+ }
+
+ dev_dbg(&dev->core, "%s completed\n", op);
+
+out:
+ bio_endio(bio, error);
+ return 0;
+}
+
+static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv;
+ int error, status;
+ struct request_queue *queue;
+ struct gendisk *gendisk;
+ u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size,
+ reports_size;
+ char *rest;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ error = -ENOMEM;
+ goto fail;
+ }
+
+ mutex_init(&priv->lock);
+ dev->core.driver_data = priv;
+
+ priv = dev->core.driver_data;
+
+ /* Allocate XDR buffer (1MiB aligned) */
+ priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
+ get_order(XDR_BUF_SIZE));
+ if (priv->xdr_buf == NULL) {
+ dev_err(&dev->core, "Could not allocate XDR buffer\n");
+ error = -ENOMEM;
+ goto fail_free_priv;
+ }
+
+ /* Put FIFO at begginning of XDR buffer */
+ priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET);
+ priv->fifo_ptr = priv->fifo_base;
+
+ /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */
+ if (ps3_open_hv_device(dev)) {
+ dev_err(&dev->core, "ps3_open_hv_device failed\n");
+ error = -EAGAIN;
+ goto out_close_gpu;
+ }
+
+ /* Request memory */
+ status = -1;
+ ddr_size = ALIGN(memparse(size, &rest), 1024*1024);
+ if (!ddr_size) {
+ dev_err(&dev->core, "Specified size is too small\n");
+ error = -EINVAL;
+ goto out_close_gpu;
+ }
+
+ while (ddr_size > 0) {
+ status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0,
+ &priv->memory_handle,
+ &ddr_lpar);
+ if (!status)
+ break;
+ ddr_size -= 1024*1024;
+ }
+ if (status) {
+ dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n",
+ status);
+ error = -ENOMEM;
+ goto out_free_xdr_buf;
+ }
+
+ /* Request context */
+ status = lv1_gpu_context_allocate(priv->memory_handle, 0,
+ &priv->context_handle, &ctrl_lpar,
+ &info_lpar, &reports_lpar,
+ &reports_size);
+ if (status) {
+ dev_err(&dev->core, "lv1_gpu_context_allocate failed %d\n",
+ status);
+ error = -ENOMEM;
+ goto out_free_memory;
+ }
+
+ /* Map XDR buffer to RSX */
+ status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
+ ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
+ XDR_BUF_SIZE, 0);
+ if (status) {
+ dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n",
+ status);
+ error = -ENOMEM;
+ goto out_free_context;
+ }
+
+ priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
+
+ if (!priv->ddr_base) {
+ dev_err(&dev->core, "ioremap DDR failed\n");
+ error = -ENOMEM;
+ goto out_free_context;
+ }
+
+ priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
+ if (!priv->ctrl) {
+ dev_err(&dev->core, "ioremap CTRL failed\n");
+ error = -ENOMEM;
+ goto out_unmap_vram;
+ }
+
+ priv->reports = ioremap(reports_lpar, reports_size);
+ if (!priv->reports) {
+ dev_err(&dev->core, "ioremap REPORTS failed\n");
+ error = -ENOMEM;
+ goto out_unmap_ctrl;
+ }
+
+ mutex_lock(&ps3_gpu_mutex);
+ ps3vram_init_ring(dev);
+ mutex_unlock(&ps3_gpu_mutex);
+
+ priv->size = ddr_size;
+
+ ps3vram_bind(dev);
+
+ mutex_lock(&ps3_gpu_mutex);
+ error = ps3vram_wait_ring(dev, 100);
+ mutex_unlock(&ps3_gpu_mutex);
+ if (error < 0) {
+ dev_err(&dev->core, "Failed to initialize channels\n");
+ error = -ETIMEDOUT;
+ goto out_unmap_reports;
+ }
+
+ ps3vram_cache_init(dev);
+ ps3vram_proc_init(dev);
+
+ queue = blk_alloc_queue(GFP_KERNEL);
+ if (!queue) {
+ dev_err(&dev->core, "blk_alloc_queue failed\n");
+ error = -ENOMEM;
+ goto out_cache_cleanup;
+ }
+
+ priv->queue = queue;
+ queue->queuedata = dev;
+ blk_queue_make_request(queue, ps3vram_make_request);
+ blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS);
+ blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS);
+ blk_queue_max_segment_size(queue, MAX_SEGMENT_SIZE);
+ blk_queue_max_sectors(queue, SAFE_MAX_SECTORS);
+
+ gendisk = alloc_disk(1);
+ if (!gendisk) {
+ dev_err(&dev->core, "alloc_disk failed\n");
+ error = -ENOMEM;
+ goto fail_cleanup_queue;
+ }
+
+ priv->gendisk = gendisk;
+ gendisk->major = ps3vram_major;
+ gendisk->first_minor = 0;
+ gendisk->fops = &ps3vram_fops;
+ gendisk->queue = queue;
+ gendisk->private_data = dev;
+ gendisk->driverfs_dev = &dev->core;
+ strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name));
+ set_capacity(gendisk, priv->size >> 9);
+
+ dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n",
+ gendisk->disk_name, get_capacity(gendisk) >> 11);
+
+ add_disk(gendisk);
+ return 0;
+
+fail_cleanup_queue:
+ blk_cleanup_queue(queue);
+out_cache_cleanup:
+ remove_proc_entry(DEVICE_NAME, NULL);
+ ps3vram_cache_cleanup(dev);
+out_unmap_reports:
+ iounmap(priv->reports);
+out_unmap_ctrl:
+ iounmap(priv->ctrl);
+out_unmap_vram:
+ iounmap(priv->ddr_base);
+out_free_context:
+ lv1_gpu_context_free(priv->context_handle);
+out_free_memory:
+ lv1_gpu_memory_free(priv->memory_handle);
+out_close_gpu:
+ ps3_close_hv_device(dev);
+out_free_xdr_buf:
+ free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
+fail_free_priv:
+ kfree(priv);
+ dev->core.driver_data = NULL;
+fail:
+ return error;
+}
+
+static int ps3vram_remove(struct ps3_system_bus_device *dev)
+{
+ struct ps3vram_priv *priv = dev->core.driver_data;
+
+ del_gendisk(priv->gendisk);
+ put_disk(priv->gendisk);
+ blk_cleanup_queue(priv->queue);
+ remove_proc_entry(DEVICE_NAME, NULL);
+ ps3vram_cache_cleanup(dev);
+ iounmap(priv->reports);
+ iounmap(priv->ctrl);
+ iounmap(priv->ddr_base);
+ lv1_gpu_context_free(priv->context_handle);
+ lv1_gpu_memory_free(priv->memory_handle);
+ ps3_close_hv_device(dev);
+ free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
+ kfree(priv);
+ dev->core.driver_data = NULL;
+ return 0;
+}
+
+static struct ps3_system_bus_driver ps3vram = {
+ .match_id = PS3_MATCH_ID_GPU,
+ .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK,
+ .core.name = DEVICE_NAME,
+ .core.owner = THIS_MODULE,
+ .probe = ps3vram_probe,
+ .remove = ps3vram_remove,
+ .shutdown = ps3vram_remove,
+};
+
+
+static int __init ps3vram_init(void)
+{
+ int error;
+
+ if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+ return -ENODEV;
+
+ error = register_blkdev(0, DEVICE_NAME);
+ if (error <= 0) {
+ pr_err("%s: register_blkdev failed %d\n", DEVICE_NAME, error);
+ return error;
+ }
+ ps3vram_major = error;
+
+ pr_info("%s: registered block device major %d\n", DEVICE_NAME,
+ ps3vram_major);
+
+ error = ps3_system_bus_driver_register(&ps3vram);
+ if (error)
+ unregister_blkdev(ps3vram_major, DEVICE_NAME);
+
+ return error;
+}
+
+static void __exit ps3vram_exit(void)
+{
+ ps3_system_bus_driver_unregister(&ps3vram);
+ unregister_blkdev(ps3vram_major, DEVICE_NAME);
+}
+
+module_init(ps3vram_init);
+module_exit(ps3vram_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PS3 Video RAM Storage Driver");
+MODULE_AUTHOR("Sony Corporation");
+MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK);
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
new file mode 100644
index 00000000000..d22cc385693
--- /dev/null
+++ b/drivers/block/swim.c
@@ -0,0 +1,995 @@
+/*
+ * Driver for SWIM (Sander Woz Integrated Machine) floppy controller
+ *
+ * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
+ *
+ * based on Alastair Bridgewater SWIM analysis, 2001
+ * based on SWIM3 driver (c) Paul Mackerras, 1996
+ * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
+ *
+ * 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.
+ *
+ * 2004-08-21 (lv) - Initial implementation
+ * 2008-10-30 (lv) - Port to 2.6
+ */
+
+#include <linux/module.h>
+#include <linux/fd.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/macintosh.h>
+#include <asm/mac_via.h>
+
+#define CARDNAME "swim"
+
+struct sector_header {
+ unsigned char side;
+ unsigned char track;
+ unsigned char sector;
+ unsigned char size;
+ unsigned char crc0;
+ unsigned char crc1;
+} __attribute__((packed));
+
+#define DRIVER_VERSION "Version 0.2 (2008-10-30)"
+
+#define REG(x) unsigned char x, x ## _pad[0x200 - 1];
+
+struct swim {
+ REG(write_data)
+ REG(write_mark)
+ REG(write_CRC)
+ REG(write_parameter)
+ REG(write_phase)
+ REG(write_setup)
+ REG(write_mode0)
+ REG(write_mode1)
+
+ REG(read_data)
+ REG(read_mark)
+ REG(read_error)
+ REG(read_parameter)
+ REG(read_phase)
+ REG(read_setup)
+ REG(read_status)
+ REG(read_handshake)
+} __attribute__((packed));
+
+#define swim_write(base, reg, v) out_8(&(base)->write_##reg, (v))
+#define swim_read(base, reg) in_8(&(base)->read_##reg)
+
+/* IWM registers */
+
+struct iwm {
+ REG(ph0L)
+ REG(ph0H)
+ REG(ph1L)
+ REG(ph1H)
+ REG(ph2L)
+ REG(ph2H)
+ REG(ph3L)
+ REG(ph3H)
+ REG(mtrOff)
+ REG(mtrOn)
+ REG(intDrive)
+ REG(extDrive)
+ REG(q6L)
+ REG(q6H)
+ REG(q7L)
+ REG(q7H)
+} __attribute__((packed));
+
+#define iwm_write(base, reg, v) out_8(&(base)->reg, (v))
+#define iwm_read(base, reg) in_8(&(base)->reg)
+
+/* bits in phase register */
+
+#define SEEK_POSITIVE 0x070
+#define SEEK_NEGATIVE 0x074
+#define STEP 0x071
+#define MOTOR_ON 0x072
+#define MOTOR_OFF 0x076
+#define INDEX 0x073
+#define EJECT 0x077
+#define SETMFM 0x171
+#define SETGCR 0x175
+
+#define RELAX 0x033
+#define LSTRB 0x008
+
+#define CA_MASK 0x077
+
+/* Select values for swim_select and swim_readbit */
+
+#define READ_DATA_0 0x074
+#define TWOMEG_DRIVE 0x075
+#define SINGLE_SIDED 0x076
+#define DRIVE_PRESENT 0x077
+#define DISK_IN 0x170
+#define WRITE_PROT 0x171
+#define TRACK_ZERO 0x172
+#define TACHO 0x173
+#define READ_DATA_1 0x174
+#define MFM_MODE 0x175
+#define SEEK_COMPLETE 0x176
+#define ONEMEG_MEDIA 0x177
+
+/* Bits in handshake register */
+
+#define MARK_BYTE 0x01
+#define CRC_ZERO 0x02
+#define RDDATA 0x04
+#define SENSE 0x08
+#define MOTEN 0x10
+#define ERROR 0x20
+#define DAT2BYTE 0x40
+#define DAT1BYTE 0x80
+
+/* bits in setup register */
+
+#define S_INV_WDATA 0x01
+#define S_3_5_SELECT 0x02
+#define S_GCR 0x04
+#define S_FCLK_DIV2 0x08
+#define S_ERROR_CORR 0x10
+#define S_IBM_DRIVE 0x20
+#define S_GCR_WRITE 0x40
+#define S_TIMEOUT 0x80
+
+/* bits in mode register */
+
+#define CLFIFO 0x01
+#define ENBL1 0x02
+#define ENBL2 0x04
+#define ACTION 0x08
+#define WRITE_MODE 0x10
+#define HEDSEL 0x20
+#define MOTON 0x80
+
+/*----------------------------------------------------------------------------*/
+
+enum drive_location {
+ INTERNAL_DRIVE = 0x02,
+ EXTERNAL_DRIVE = 0x04,
+};
+
+enum media_type {
+ DD_MEDIA,
+ HD_MEDIA,
+};
+
+struct floppy_state {
+
+ /* physical properties */
+
+ enum drive_location location; /* internal or external drive */
+ int head_number; /* single- or double-sided drive */
+
+ /* media */
+
+ int disk_in;
+ int ejected;
+ enum media_type type;
+ int write_protected;
+
+ int total_secs;
+ int secpercyl;
+ int secpertrack;
+
+ /* in-use information */
+
+ int track;
+ int ref_count;
+
+ struct gendisk *disk;
+
+ /* parent controller */
+
+ struct swim_priv *swd;
+};
+
+enum motor_action {
+ OFF,
+ ON,
+};
+
+enum head {
+ LOWER_HEAD = 0,
+ UPPER_HEAD = 1,
+};
+
+#define FD_MAX_UNIT 2
+
+struct swim_priv {
+ struct swim __iomem *base;
+ spinlock_t lock;
+ struct request_queue *queue;
+ int floppy_count;
+ struct floppy_state unit[FD_MAX_UNIT];
+};
+
+extern int swim_read_sector_header(struct swim __iomem *base,
+ struct sector_header *header);
+extern int swim_read_sector_data(struct swim __iomem *base,
+ unsigned char *data);
+
+static inline void set_swim_mode(struct swim __iomem *base, int enable)
+{
+ struct iwm __iomem *iwm_base;
+ unsigned long flags;
+
+ if (!enable) {
+ swim_write(base, mode0, 0xf8);
+ return;
+ }
+
+ iwm_base = (struct iwm __iomem *)base;
+ local_irq_save(flags);
+
+ iwm_read(iwm_base, q7L);
+ iwm_read(iwm_base, mtrOff);
+ iwm_read(iwm_base, q6H);
+
+ iwm_write(iwm_base, q7H, 0x57);
+ iwm_write(iwm_base, q7H, 0x17);
+ iwm_write(iwm_base, q7H, 0x57);
+ iwm_write(iwm_base, q7H, 0x57);
+
+ local_irq_restore(flags);
+}
+
+static inline int get_swim_mode(struct swim __iomem *base)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ swim_write(base, phase, 0xf5);
+ if (swim_read(base, phase) != 0xf5)
+ goto is_iwm;
+ swim_write(base, phase, 0xf6);
+ if (swim_read(base, phase) != 0xf6)
+ goto is_iwm;
+ swim_write(base, phase, 0xf7);
+ if (swim_read(base, phase) != 0xf7)
+ goto is_iwm;
+ local_irq_restore(flags);
+ return 1;
+is_iwm:
+ local_irq_restore(flags);
+ return 0;
+}
+
+static inline void swim_select(struct swim __iomem *base, int sel)
+{
+ swim_write(base, phase, RELAX);
+
+ via1_set_head(sel & 0x100);
+
+ swim_write(base, phase, sel & CA_MASK);
+}
+
+static inline void swim_action(struct swim __iomem *base, int action)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ swim_select(base, action);
+ udelay(1);
+ swim_write(base, phase, (LSTRB<<4) | LSTRB);
+ udelay(1);
+ swim_write(base, phase, (LSTRB<<4) | ((~LSTRB) & 0x0F));
+ udelay(1);
+
+ local_irq_restore(flags);
+}
+
+static inline int swim_readbit(struct swim __iomem *base, int bit)
+{
+ int stat;
+
+ swim_select(base, bit);
+
+ udelay(10);
+
+ stat = swim_read(base, handshake);
+
+ return (stat & SENSE) == 0;
+}
+
+static inline void swim_drive(struct swim __iomem *base,
+ enum drive_location location)
+{
+ if (location == INTERNAL_DRIVE) {
+ swim_write(base, mode0, EXTERNAL_DRIVE); /* clear drive 1 bit */
+ swim_write(base, mode1, INTERNAL_DRIVE); /* set drive 0 bit */
+ } else if (location == EXTERNAL_DRIVE) {
+ swim_write(base, mode0, INTERNAL_DRIVE); /* clear drive 0 bit */
+ swim_write(base, mode1, EXTERNAL_DRIVE); /* set drive 1 bit */
+ }
+}
+
+static inline void swim_motor(struct swim __iomem *base,
+ enum motor_action action)
+{
+ if (action == ON) {
+ int i;
+
+ swim_action(base, MOTOR_ON);
+
+ for (i = 0; i < 2*HZ; i++) {
+ swim_select(base, RELAX);
+ if (swim_readbit(base, MOTOR_ON))
+ break;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+ } else if (action == OFF) {
+ swim_action(base, MOTOR_OFF);
+ swim_select(base, RELAX);
+ }
+}
+
+static inline void swim_eject(struct swim __iomem *base)
+{
+ int i;
+
+ swim_action(base, EJECT);
+
+ for (i = 0; i < 2*HZ; i++) {
+ swim_select(base, RELAX);
+ if (!swim_readbit(base, DISK_IN))
+ break;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+ swim_select(base, RELAX);
+}
+
+static inline void swim_head(struct swim __iomem *base, enum head head)
+{
+ /* wait drive is ready */
+
+ if (head == UPPER_HEAD)
+ swim_select(base, READ_DATA_1);
+ else if (head == LOWER_HEAD)
+ swim_select(base, READ_DATA_0);
+}
+
+static inline int swim_step(struct swim __iomem *base)
+{
+ int wait;
+
+ swim_action(base, STEP);
+
+ for (wait = 0; wait < HZ; wait++) {
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+
+ swim_select(base, RELAX);
+ if (!swim_readbit(base, STEP))
+ return 0;
+ }
+ return -1;
+}
+
+static inline int swim_track00(struct swim __iomem *base)
+{
+ int try;
+
+ swim_action(base, SEEK_NEGATIVE);
+
+ for (try = 0; try < 100; try++) {
+
+ swim_select(base, RELAX);
+ if (swim_readbit(base, TRACK_ZERO))
+ break;
+
+ if (swim_step(base))
+ return -1;
+ }
+
+ if (swim_readbit(base, TRACK_ZERO))
+ return 0;
+
+ return -1;
+}
+
+static inline int swim_seek(struct swim __iomem *base, int step)
+{
+ if (step == 0)
+ return 0;
+
+ if (step < 0) {
+ swim_action(base, SEEK_NEGATIVE);
+ step = -step;
+ } else
+ swim_action(base, SEEK_POSITIVE);
+
+ for ( ; step > 0; step--) {
+ if (swim_step(base))
+ return -1;
+ }
+
+ return 0;
+}
+
+static inline int swim_track(struct floppy_state *fs, int track)
+{
+ struct swim __iomem *base = fs->swd->base;
+ int ret;
+
+ ret = swim_seek(base, track - fs->track);
+
+ if (ret == 0)
+ fs->track = track;
+ else {
+ swim_track00(base);
+ fs->track = 0;
+ }
+
+ return ret;
+}
+
+static int floppy_eject(struct floppy_state *fs)
+{
+ struct swim __iomem *base = fs->swd->base;
+
+ swim_drive(base, fs->location);
+ swim_motor(base, OFF);
+ swim_eject(base);
+
+ fs->disk_in = 0;
+ fs->ejected = 1;
+
+ return 0;
+}
+
+static inline int swim_read_sector(struct floppy_state *fs,
+ int side, int track,
+ int sector, unsigned char *buffer)
+{
+ struct swim __iomem *base = fs->swd->base;
+ unsigned long flags;
+ struct sector_header header;
+ int ret = -1;
+ short i;
+
+ swim_track(fs, track);
+
+ swim_write(base, mode1, MOTON);
+ swim_head(base, side);
+ swim_write(base, mode0, side);
+
+ local_irq_save(flags);
+ for (i = 0; i < 36; i++) {
+ ret = swim_read_sector_header(base, &header);
+ if (!ret && (header.sector == sector)) {
+ /* found */
+
+ ret = swim_read_sector_data(base, buffer);
+ break;
+ }
+ }
+ local_irq_restore(flags);
+
+ swim_write(base, mode0, MOTON);
+
+ if ((header.side != side) || (header.track != track) ||
+ (header.sector != sector))
+ return 0;
+
+ return ret;
+}
+
+static int floppy_read_sectors(struct floppy_state *fs,
+ int req_sector, int sectors_nb,
+ unsigned char *buffer)
+{
+ struct swim __iomem *base = fs->swd->base;
+ int ret;
+ int side, track, sector;
+ int i, try;
+
+
+ swim_drive(base, fs->location);
+ for (i = req_sector; i < req_sector + sectors_nb; i++) {
+ int x;
+ track = i / fs->secpercyl;
+ x = i % fs->secpercyl;
+ side = x / fs->secpertrack;
+ sector = x % fs->secpertrack + 1;
+
+ try = 5;
+ do {
+ ret = swim_read_sector(fs, side, track, sector,
+ buffer);
+ if (try-- == 0)
+ return -1;
+ } while (ret != 512);
+
+ buffer += ret;
+ }
+
+ return 0;
+}
+
+static void redo_fd_request(struct request_queue *q)
+{
+ struct request *req;
+ struct floppy_state *fs;
+
+ while ((req = elv_next_request(q))) {
+
+ fs = req->rq_disk->private_data;
+ if (req->sector < 0 || req->sector >= fs->total_secs) {
+ end_request(req, 0);
+ continue;
+ }
+ if (req->current_nr_sectors == 0) {
+ end_request(req, 1);
+ continue;
+ }
+ if (!fs->disk_in) {
+ end_request(req, 0);
+ continue;
+ }
+ if (rq_data_dir(req) == WRITE) {
+ if (fs->write_protected) {
+ end_request(req, 0);
+ continue;
+ }
+ }
+ switch (rq_data_dir(req)) {
+ case WRITE:
+ /* NOT IMPLEMENTED */
+ end_request(req, 0);
+ break;
+ case READ:
+ if (floppy_read_sectors(fs, req->sector,
+ req->current_nr_sectors,
+ req->buffer)) {
+ end_request(req, 0);
+ continue;
+ }
+ req->nr_sectors -= req->current_nr_sectors;
+ req->sector += req->current_nr_sectors;
+ req->buffer += req->current_nr_sectors * 512;
+ end_request(req, 1);
+ break;
+ }
+ }
+}
+
+static void do_fd_request(struct request_queue *q)
+{
+ redo_fd_request(q);
+}
+
+static struct floppy_struct floppy_type[4] = {
+ { 0, 0, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, NULL }, /* no testing */
+ { 720, 9, 1, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 360KB SS 3.5"*/
+ { 1440, 9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 720KB 3.5" */
+ { 2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, NULL }, /* 1.44MB 3.5" */
+};
+
+static int get_floppy_geometry(struct floppy_state *fs, int type,
+ struct floppy_struct **g)
+{
+ if (type >= ARRAY_SIZE(floppy_type))
+ return -EINVAL;
+
+ if (type)
+ *g = &floppy_type[type];
+ else if (fs->type == HD_MEDIA) /* High-Density media */
+ *g = &floppy_type[3];
+ else if (fs->head_number == 2) /* double-sided */
+ *g = &floppy_type[2];
+ else
+ *g = &floppy_type[1];
+
+ return 0;
+}
+
+static void setup_medium(struct floppy_state *fs)
+{
+ struct swim __iomem *base = fs->swd->base;
+
+ if (swim_readbit(base, DISK_IN)) {
+ struct floppy_struct *g;
+ fs->disk_in = 1;
+ fs->write_protected = swim_readbit(base, WRITE_PROT);
+ fs->type = swim_readbit(base, ONEMEG_MEDIA);
+
+ if (swim_track00(base))
+ printk(KERN_ERR
+ "SWIM: cannot move floppy head to track 0\n");
+
+ swim_track00(base);
+
+ get_floppy_geometry(fs, 0, &g);
+ fs->total_secs = g->size;
+ fs->secpercyl = g->head * g->sect;
+ fs->secpertrack = g->sect;
+ fs->track = 0;
+ } else {
+ fs->disk_in = 0;
+ }
+}
+
+static int floppy_open(struct block_device *bdev, fmode_t mode)
+{
+ struct floppy_state *fs = bdev->bd_disk->private_data;
+ struct swim __iomem *base = fs->swd->base;
+ int err;
+
+ if (fs->ref_count == -1 || (fs->ref_count && mode & FMODE_EXCL))
+ return -EBUSY;
+
+ if (mode & FMODE_EXCL)
+ fs->ref_count = -1;
+ else
+ fs->ref_count++;
+
+ swim_write(base, setup, S_IBM_DRIVE | S_FCLK_DIV2);
+ udelay(10);
+ swim_drive(base, INTERNAL_DRIVE);
+ swim_motor(base, ON);
+ swim_action(base, SETMFM);
+ if (fs->ejected)
+ setup_medium(fs);
+ if (!fs->disk_in) {
+ err = -ENXIO;
+ goto out;
+ }
+
+ if (mode & FMODE_NDELAY)
+ return 0;
+
+ if (mode & (FMODE_READ|FMODE_WRITE)) {
+ check_disk_change(bdev);
+ if ((mode & FMODE_WRITE) && fs->write_protected) {
+ err = -EROFS;
+ goto out;
+ }
+ }
+ return 0;
+out:
+ if (fs->ref_count < 0)
+ fs->ref_count = 0;
+ else if (fs->ref_count > 0)
+ --fs->ref_count;
+
+ if (fs->ref_count == 0)
+ swim_motor(base, OFF);
+ return err;
+}
+
+static int floppy_release(struct gendisk *disk, fmode_t mode)
+{
+ struct floppy_state *fs = disk->private_data;
+ struct swim __iomem *base = fs->swd->base;
+
+ if (fs->ref_count < 0)
+ fs->ref_count = 0;
+ else if (fs->ref_count > 0)
+ --fs->ref_count;
+
+ if (fs->ref_count == 0)
+ swim_motor(base, OFF);
+
+ return 0;
+}
+
+static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long param)
+{
+ struct floppy_state *fs = bdev->bd_disk->private_data;
+ int err;
+
+ if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ switch (cmd) {
+ case FDEJECT:
+ if (fs->ref_count != 1)
+ return -EBUSY;
+ err = floppy_eject(fs);
+ return err;
+
+ case FDGETPRM:
+ if (copy_to_user((void __user *) param, (void *) &floppy_type,
+ sizeof(struct floppy_struct)))
+ return -EFAULT;
+ break;
+
+ default:
+ printk(KERN_DEBUG "SWIM floppy_ioctl: unknown cmd %d\n",
+ cmd);
+ return -ENOSYS;
+ }
+ return 0;
+}
+
+static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ struct floppy_state *fs = bdev->bd_disk->private_data;
+ struct floppy_struct *g;
+ int ret;
+
+ ret = get_floppy_geometry(fs, 0, &g);
+ if (ret)
+ return ret;
+
+ geo->heads = g->head;
+ geo->sectors = g->sect;
+ geo->cylinders = g->track;
+
+ return 0;
+}
+
+static int floppy_check_change(struct gendisk *disk)
+{
+ struct floppy_state *fs = disk->private_data;
+
+ return fs->ejected;
+}
+
+static int floppy_revalidate(struct gendisk *disk)
+{
+ struct floppy_state *fs = disk->private_data;
+ struct swim __iomem *base = fs->swd->base;
+
+ swim_drive(base, fs->location);
+
+ if (fs->ejected)
+ setup_medium(fs);
+
+ if (!fs->disk_in)
+ swim_motor(base, OFF);
+ else
+ fs->ejected = 0;
+
+ return !fs->disk_in;
+}
+
+static struct block_device_operations floppy_fops = {
+ .owner = THIS_MODULE,
+ .open = floppy_open,
+ .release = floppy_release,
+ .locked_ioctl = floppy_ioctl,
+ .getgeo = floppy_getgeo,
+ .media_changed = floppy_check_change,
+ .revalidate_disk = floppy_revalidate,
+};
+
+static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+{
+ struct swim_priv *swd = data;
+ int drive = (*part & 3);
+
+ if (drive > swd->floppy_count)
+ return NULL;
+
+ *part = 0;
+ return get_disk(swd->unit[drive].disk);
+}
+
+static int __devinit swim_add_floppy(struct swim_priv *swd,
+ enum drive_location location)
+{
+ struct floppy_state *fs = &swd->unit[swd->floppy_count];
+ struct swim __iomem *base = swd->base;
+
+ fs->location = location;
+
+ swim_drive(base, location);
+
+ swim_motor(base, OFF);
+
+ if (swim_readbit(base, SINGLE_SIDED))
+ fs->head_number = 1;
+ else
+ fs->head_number = 2;
+ fs->ref_count = 0;
+ fs->ejected = 1;
+
+ swd->floppy_count++;
+
+ return 0;
+}
+
+static int __devinit swim_floppy_init(struct swim_priv *swd)
+{
+ int err;
+ int drive;
+ struct swim __iomem *base = swd->base;
+
+ /* scan floppy drives */
+
+ swim_drive(base, INTERNAL_DRIVE);
+ if (swim_readbit(base, DRIVE_PRESENT))
+ swim_add_floppy(swd, INTERNAL_DRIVE);
+ swim_drive(base, EXTERNAL_DRIVE);
+ if (swim_readbit(base, DRIVE_PRESENT))
+ swim_add_floppy(swd, EXTERNAL_DRIVE);
+
+ /* register floppy drives */
+
+ err = register_blkdev(FLOPPY_MAJOR, "fd");
+ if (err) {
+ printk(KERN_ERR "Unable to get major %d for SWIM floppy\n",
+ FLOPPY_MAJOR);
+ return -EBUSY;
+ }
+
+ for (drive = 0; drive < swd->floppy_count; drive++) {
+ swd->unit[drive].disk = alloc_disk(1);
+ if (swd->unit[drive].disk == NULL) {
+ err = -ENOMEM;
+ goto exit_put_disks;
+ }
+ swd->unit[drive].swd = swd;
+ }
+
+ swd->queue = blk_init_queue(do_fd_request, &swd->lock);
+ if (!swd->queue) {
+ err = -ENOMEM;
+ goto exit_put_disks;
+ }
+
+ for (drive = 0; drive < swd->floppy_count; drive++) {
+ swd->unit[drive].disk->flags = GENHD_FL_REMOVABLE;
+ swd->unit[drive].disk->major = FLOPPY_MAJOR;
+ swd->unit[drive].disk->first_minor = drive;
+ sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
+ swd->unit[drive].disk->fops = &floppy_fops;
+ swd->unit[drive].disk->private_data = &swd->unit[drive];
+ swd->unit[drive].disk->queue = swd->queue;
+ set_capacity(swd->unit[drive].disk, 2880);
+ add_disk(swd->unit[drive].disk);
+ }
+
+ blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
+ floppy_find, NULL, swd);
+
+ return 0;
+
+exit_put_disks:
+ unregister_blkdev(FLOPPY_MAJOR, "fd");
+ while (drive--)
+ put_disk(swd->unit[drive].disk);
+ return err;
+}
+
+static int __devinit swim_probe(struct platform_device *dev)
+{
+ struct resource *res;
+ struct swim __iomem *swim_base;
+ struct swim_priv *swd;
+ int ret;
+
+ res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+ if (!res) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res), CARDNAME)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ swim_base = ioremap(res->start, resource_size(res));
+ if (!swim_base) {
+ return -ENOMEM;
+ goto out_release_io;
+ }
+
+ /* probe device */
+
+ set_swim_mode(swim_base, 1);
+ if (!get_swim_mode(swim_base)) {
+ printk(KERN_INFO "SWIM device not found !\n");
+ ret = -ENODEV;
+ goto out_iounmap;
+ }
+
+ /* set platform driver data */
+
+ swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL);
+ if (!swd) {
+ ret = -ENOMEM;
+ goto out_iounmap;
+ }
+ platform_set_drvdata(dev, swd);
+
+ swd->base = swim_base;
+
+ ret = swim_floppy_init(swd);
+ if (ret)
+ goto out_kfree;
+
+ return 0;
+
+out_kfree:
+ platform_set_drvdata(dev, NULL);
+ kfree(swd);
+out_iounmap:
+ iounmap(swim_base);
+out_release_io:
+ release_mem_region(res->start, resource_size(res));
+out:
+ return ret;
+}
+
+static int __devexit swim_remove(struct platform_device *dev)
+{
+ struct swim_priv *swd = platform_get_drvdata(dev);
+ int drive;
+ struct resource *res;
+
+ blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+
+ for (drive = 0; drive < swd->floppy_count; drive++) {
+ del_gendisk(swd->unit[drive].disk);
+ put_disk(swd->unit[drive].disk);
+ }
+
+ unregister_blkdev(FLOPPY_MAJOR, "fd");
+
+ blk_cleanup_queue(swd->queue);
+
+ /* eject floppies */
+
+ for (drive = 0; drive < swd->floppy_count; drive++)
+ floppy_eject(&swd->unit[drive]);
+
+ iounmap(swd->base);
+
+ res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+ if (res)
+ release_mem_region(res->start, resource_size(res));
+
+ platform_set_drvdata(dev, NULL);
+ kfree(swd);
+
+ return 0;
+}
+
+static struct platform_driver swim_driver = {
+ .probe = swim_probe,
+ .remove = __devexit_p(swim_remove),
+ .driver = {
+ .name = CARDNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init swim_init(void)
+{
+ printk(KERN_INFO "SWIM floppy driver %s\n", DRIVER_VERSION);
+
+ return platform_driver_register(&swim_driver);
+}
+module_init(swim_init);
+
+static void __exit swim_exit(void)
+{
+ platform_driver_unregister(&swim_driver);
+}
+module_exit(swim_exit);
+
+MODULE_DESCRIPTION("Driver for SWIM floppy controller");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Laurent Vivier <laurent@lvivier.info>");
+MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR);
diff --git a/drivers/block/swim_asm.S b/drivers/block/swim_asm.S
new file mode 100644
index 00000000000..c9668206857
--- /dev/null
+++ b/drivers/block/swim_asm.S
@@ -0,0 +1,247 @@
+/*
+ * low-level functions for the SWIM floppy controller
+ *
+ * needs assembly language because is very timing dependent
+ * this controller exists only on macintosh 680x0 based
+ *
+ * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
+ *
+ * based on Alastair Bridgewater SWIM analysis, 2001
+ * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
+ *
+ * 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.
+ *
+ * 2004-08-21 (lv) - Initial implementation
+ * 2008-11-05 (lv) - add get_swim_mode
+ */
+
+ .equ write_data, 0x0000
+ .equ write_mark, 0x0200
+ .equ write_CRC, 0x0400
+ .equ write_parameter,0x0600
+ .equ write_phase, 0x0800
+ .equ write_setup, 0x0a00
+ .equ write_mode0, 0x0c00
+ .equ write_mode1, 0x0e00
+ .equ read_data, 0x1000
+ .equ read_mark, 0x1200
+ .equ read_error, 0x1400
+ .equ read_parameter, 0x1600
+ .equ read_phase, 0x1800
+ .equ read_setup, 0x1a00
+ .equ read_status, 0x1c00
+ .equ read_handshake, 0x1e00
+
+ .equ o_side, 0
+ .equ o_track, 1
+ .equ o_sector, 2
+ .equ o_size, 3
+ .equ o_crc0, 4
+ .equ o_crc1, 5
+
+ .equ seek_time, 30000
+ .equ max_retry, 40
+ .equ sector_size, 512
+
+ .global swim_read_sector_header
+swim_read_sector_header:
+ link %a6, #0
+ moveml %d1-%d5/%a0-%a4,%sp@-
+ movel %a6@(0x0c), %a4
+ bsr mfm_read_addrmark
+ moveml %sp@+, %d1-%d5/%a0-%a4
+ unlk %a6
+ rts
+
+sector_address_mark:
+ .byte 0xa1, 0xa1, 0xa1, 0xfe
+sector_data_mark:
+ .byte 0xa1, 0xa1, 0xa1, 0xfb
+
+mfm_read_addrmark:
+ movel %a6@(0x08), %a3
+ lea %a3@(read_handshake), %a2
+ lea %a3@(read_mark), %a3
+ moveq #-1, %d0
+ movew #seek_time, %d2
+
+wait_header_init:
+ tstb %a3@(read_error - read_mark)
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ moveb #0x01, %a3@(write_mode1 - read_mark)
+ moveb #0x01, %a3@(write_mode0 - read_mark)
+ tstb %a3@(read_error - read_mark)
+ moveb #0x08, %a3@(write_mode1 - read_mark)
+
+ lea sector_address_mark, %a0
+ moveq #3, %d1
+
+wait_addr_mark_byte:
+
+ tstb %a2@
+ dbmi %d2, wait_addr_mark_byte
+ bpl header_exit
+
+ moveb %a3@, %d3
+ cmpb %a0@+, %d3
+ dbne %d1, wait_addr_mark_byte
+ bne wait_header_init
+
+ moveq #max_retry, %d2
+
+amark0: tstb %a2@
+ dbmi %d2, amark0
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_track)
+
+ moveq #max_retry, %d2
+
+amark1: tstb %a2@
+ dbmi %d2, amark1
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_side)
+
+ moveq #max_retry, %d2
+
+amark2: tstb %a2@
+ dbmi %d2, amark2
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_sector)
+
+ moveq #max_retry, %d2
+
+amark3: tstb %a2@
+ dbmi %d2, amark3
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_size)
+
+ moveq #max_retry, %d2
+
+crc0: tstb %a2@
+ dbmi %d2, crc0
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_crc0)
+
+ moveq #max_retry, %d2
+
+crc1: tstb %a2@
+ dbmi %d2, crc1
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_crc1)
+
+ tstb %a3@(read_error - read_mark)
+
+header_exit:
+ moveq #0, %d0
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ rts
+signal_nonyb:
+ moveq #-1, %d0
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ rts
+
+ .global swim_read_sector_data
+swim_read_sector_data:
+ link %a6, #0
+ moveml %d1-%d5/%a0-%a5,%sp@-
+ movel %a6@(0x0c), %a4
+ bsr mfm_read_data
+ moveml %sp@+, %d1-%d5/%a0-%a5
+ unlk %a6
+ rts
+
+mfm_read_data:
+ movel %a6@(0x08), %a3
+ lea %a3@(read_handshake), %a2
+ lea %a3@(read_data), %a5
+ lea %a3@(read_mark), %a3
+ movew #seek_time, %d2
+
+wait_data_init:
+ tstb %a3@(read_error - read_mark)
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ moveb #0x01, %a3@(write_mode1 - read_mark)
+ moveb #0x01, %a3@(write_mode0 - read_mark)
+ tstb %a3@(read_error - read_mark)
+ moveb #0x08, %a3@(write_mode1 - read_mark)
+
+ lea sector_data_mark, %a0
+ moveq #3, %d1
+
+ /* wait data address mark */
+
+wait_data_mark_byte:
+
+ tstb %a2@
+ dbmi %d2, wait_data_mark_byte
+ bpl data_exit
+
+ moveb %a3@, %d3
+ cmpb %a0@+, %d3
+ dbne %d1, wait_data_mark_byte
+ bne wait_data_init
+
+ /* read data */
+
+ tstb %a3@(read_error - read_mark)
+
+ movel #sector_size-1, %d4 /* sector size */
+read_new_data:
+ movew #max_retry, %d2
+read_data_loop:
+ moveb %a2@, %d5
+ andb #0xc0, %d5
+ dbne %d2, read_data_loop
+ beq data_exit
+ moveb %a5@, %a4@+
+ andb #0x40, %d5
+ dbne %d4, read_new_data
+ beq exit_loop
+ moveb %a5@, %a4@+
+ dbra %d4, read_new_data
+exit_loop:
+
+ /* read CRC */
+
+ movew #max_retry, %d2
+data_crc0:
+
+ tstb %a2@
+ dbmi %d2, data_crc0
+ bpl data_exit
+
+ moveb %a3@, %d5
+
+ moveq #max_retry, %d2
+
+data_crc1:
+
+ tstb %a2@
+ dbmi %d2, data_crc1
+ bpl data_exit
+
+ moveb %a3@, %d5
+
+ tstb %a3@(read_error - read_mark)
+
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+
+ /* return number of bytes read */
+
+ movel #sector_size, %d0
+ addw #1, %d4
+ subl %d4, %d0
+ rts
+data_exit:
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ moveq #-1, %d0
+ rts
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 12fb816db7b..69b7f8e7759 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -391,7 +391,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum);
*/
#ifdef CONFIG_USB_LIBUSUAL
-#define ub_usb_ids storage_usb_ids
+#define ub_usb_ids usb_storage_usb_ids
#else
static struct usb_device_id ub_usb_ids[] = {
@@ -2146,10 +2146,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
ep = &altsetting->endpoint[i].desc;
/* Is it a BULK endpoint? */
- if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_BULK) {
+ if (usb_endpoint_xfer_bulk(ep)) {
/* BULK in or out? */
- if (ep->bEndpointAddress & USB_DIR_IN) {
+ if (usb_endpoint_dir_in(ep)) {
if (ep_in == NULL)
ep_in = ep;
} else {
@@ -2168,9 +2167,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
sc->send_ctrl_pipe = usb_sndctrlpipe(dev, 0);
sc->recv_ctrl_pipe = usb_rcvctrlpipe(dev, 0);
sc->send_bulk_pipe = usb_sndbulkpipe(dev,
- ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_out));
sc->recv_bulk_pipe = usb_rcvbulkpipe(dev,
- ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_in));
return 0;
}
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 918ef725de4..8f905089b72 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -40,6 +40,7 @@
#include <linux/hdreg.h>
#include <linux/cdrom.h>
#include <linux/module.h>
+#include <linux/scatterlist.h>
#include <xen/xenbus.h>
#include <xen/grant_table.h>
@@ -82,6 +83,7 @@ struct blkfront_info
enum blkif_state connected;
int ring_ref;
struct blkif_front_ring ring;
+ struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
unsigned int evtchn, irq;
struct request_queue *rq;
struct work_struct work;
@@ -204,12 +206,11 @@ static int blkif_queue_request(struct request *req)
struct blkfront_info *info = req->rq_disk->private_data;
unsigned long buffer_mfn;
struct blkif_request *ring_req;
- struct req_iterator iter;
- struct bio_vec *bvec;
unsigned long id;
unsigned int fsect, lsect;
- int ref;
+ int i, ref;
grant_ref_t gref_head;
+ struct scatterlist *sg;
if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
return 1;
@@ -238,12 +239,13 @@ static int blkif_queue_request(struct request *req)
if (blk_barrier_rq(req))
ring_req->operation = BLKIF_OP_WRITE_BARRIER;
- ring_req->nr_segments = 0;
- rq_for_each_segment(bvec, req, iter) {
- BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST);
- buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page));
- fsect = bvec->bv_offset >> 9;
- lsect = fsect + (bvec->bv_len >> 9) - 1;
+ ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
+ BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
+
+ for_each_sg(info->sg, sg, ring_req->nr_segments, i) {
+ buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg)));
+ fsect = sg->offset >> 9;
+ lsect = fsect + (sg->length >> 9) - 1;
/* install a grant reference. */
ref = gnttab_claim_grant_reference(&gref_head);
BUG_ON(ref == -ENOSPC);
@@ -254,16 +256,12 @@ static int blkif_queue_request(struct request *req)
buffer_mfn,
rq_data_dir(req) );
- info->shadow[id].frame[ring_req->nr_segments] =
- mfn_to_pfn(buffer_mfn);
-
- ring_req->seg[ring_req->nr_segments] =
+ info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn);
+ ring_req->seg[i] =
(struct blkif_request_segment) {
.gref = ref,
.first_sect = fsect,
.last_sect = lsect };
-
- ring_req->nr_segments++;
}
info->ring.req_prod_pvt++;
@@ -622,6 +620,8 @@ static int setup_blkring(struct xenbus_device *dev,
SHARED_RING_INIT(sring);
FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
+ sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+
err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
if (err < 0) {
free_page((unsigned long)sring);
@@ -977,6 +977,8 @@ static void backend_changed(struct xenbus_device *dev,
break;
case XenbusStateClosing:
+ if (info->gd == NULL)
+ xenbus_dev_fatal(dev, -ENODEV, "gd is NULL");
bd = bdget_disk(info->gd, 0);
if (bd == NULL)
xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 381d686fc1a..119be3442f2 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -489,6 +489,28 @@ static void ace_fsm_dostate(struct ace_device *ace)
ace->fsm_state, ace->id_req_count);
#endif
+ /* Verify that there is actually a CF in the slot. If not, then
+ * bail out back to the idle state and wake up all the waiters */
+ status = ace_in32(ace, ACE_STATUS);
+ if ((status & ACE_STATUS_CFDETECT) == 0) {
+ ace->fsm_state = ACE_FSM_STATE_IDLE;
+ ace->media_change = 1;
+ set_capacity(ace->gd, 0);
+ dev_info(ace->dev, "No CF in slot\n");
+
+ /* Drop all pending requests */
+ while ((req = elv_next_request(ace->queue)) != NULL)
+ end_request(req, 0);
+
+ /* Drop back to IDLE state and notify waiters */
+ ace->fsm_state = ACE_FSM_STATE_IDLE;
+ ace->id_result = -EIO;
+ while (ace->id_req_count) {
+ complete(&ace->id_completion);
+ ace->id_req_count--;
+ }
+ }
+
switch (ace->fsm_state) {
case ACE_FSM_STATE_IDLE:
/* See if there is anything to do */
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index d3f14bee0f1..2a00707aba3 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -257,8 +257,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
if (hdr & 0x10) {
BT_ERR("%s error in block", data->hdev->name);
- if (data->reassembly)
- kfree_skb(data->reassembly);
+ kfree_skb(data->reassembly);
data->reassembly = NULL;
return -EIO;
}
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index ff195c23082..d58e22b9f06 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -359,9 +359,9 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
BT_ERR("Very strange (stat=0x%04x)", stat);
} else if ((stat & 0xff) != 0xff) {
if (stat & 0x0020) {
- int stat = bt3c_read(iobase, 0x7002) & 0x10;
+ int status = bt3c_read(iobase, 0x7002) & 0x10;
BT_INFO("%s: Antenna %s", info->hdev->name,
- stat ? "out" : "in");
+ status ? "out" : "in");
}
if (stat & 0x0001)
bt3c_receive(info);
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index b5fbda6d490..e70c57ee422 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -35,7 +35,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
-#define VERSION "0.4"
+#define VERSION "0.5"
static int ignore_dga;
static int ignore_csr;
@@ -171,6 +171,7 @@ struct btusb_data {
__u8 cmdreq_type;
+ unsigned int sco_num;
int isoc_altsetting;
int suspend_count;
};
@@ -496,11 +497,23 @@ static int btusb_open(struct hci_dev *hdev)
return 0;
err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
+ if (err < 0)
+ goto failed;
+
+ err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
if (err < 0) {
- clear_bit(BTUSB_INTR_RUNNING, &data->flags);
- clear_bit(HCI_RUNNING, &hdev->flags);
+ usb_kill_anchored_urbs(&data->intr_anchor);
+ goto failed;
}
+ set_bit(BTUSB_BULK_RUNNING, &data->flags);
+ btusb_submit_bulk_urb(hdev, GFP_KERNEL);
+
+ return 0;
+
+failed:
+ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+ clear_bit(HCI_RUNNING, &hdev->flags);
return err;
}
@@ -655,19 +668,10 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
BT_DBG("%s evt %d", hdev->name, evt);
- if (hdev->conn_hash.acl_num > 0) {
- if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
- if (btusb_submit_bulk_urb(hdev, GFP_ATOMIC) < 0)
- clear_bit(BTUSB_BULK_RUNNING, &data->flags);
- else
- btusb_submit_bulk_urb(hdev, GFP_ATOMIC);
- }
- } else {
- clear_bit(BTUSB_BULK_RUNNING, &data->flags);
- usb_unlink_anchored_urbs(&data->bulk_anchor);
+ if (hdev->conn_hash.sco_num != data->sco_num) {
+ data->sco_num = hdev->conn_hash.sco_num;
+ schedule_work(&data->work);
}
-
- schedule_work(&data->work);
}
static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
@@ -982,9 +986,11 @@ static int btusb_resume(struct usb_interface *intf)
}
if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
- if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0)
+ err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
+ if (err < 0) {
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
- else
+ return err;
+ } else
btusb_submit_bulk_urb(hdev, GFP_NOIO);
}
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index b0fafb05599..c0ce8134814 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -102,8 +102,7 @@ static int h4_close(struct hci_uart *hu)
skb_queue_purge(&h4->txq);
- if (h4->rx_skb)
- kfree_skb(h4->rx_skb);
+ kfree_skb(h4->rx_skb);
hu->priv = NULL;
kfree(h4);
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index b91d45a41b2..5c65014635b 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -163,8 +163,7 @@ static int ll_close(struct hci_uart *hu)
skb_queue_purge(&ll->tx_wait_q);
skb_queue_purge(&ll->txq);
- if (ll->rx_skb)
- kfree_skb(ll->rx_skb);
+ kfree_skb(ll->rx_skb);
hu->priv = NULL;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index f5be8081cd8..735bbe2be51 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -761,7 +761,7 @@ source "drivers/char/hw_random/Kconfig"
config NVRAM
tristate "/dev/nvram support"
- depends on ATARI || X86 || ARM || GENERIC_NVRAM
+ depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
---help---
If you say Y here and create a character special file /dev/nvram
with major number 10 and minor number 144 using mknod ("man mknod"),
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 52f4361eb6e..d765afda9c2 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -271,15 +271,15 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
nb_order = (nb_order >> 1) & 7;
pci_read_config_dword(nb, AMD64_GARTAPERTUREBASE, &nb_base);
nb_aper = nb_base << 25;
- if (agp_aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) {
- return 0;
- }
/* Northbridge seems to contain crap. Try the AGP bridge. */
pci_read_config_word(agp, cap+0x14, &apsize);
- if (apsize == 0xffff)
+ if (apsize == 0xffff) {
+ if (agp_aperture_valid(nb_aper, (32*1024*1024)<<nb_order))
+ return 0;
return -1;
+ }
apsize &= 0xfff;
/* Some BIOS use weird encodings not in the AGPv3 table. */
@@ -301,6 +301,11 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
order = nb_order;
}
+ if (nb_order >= order) {
+ if (agp_aperture_valid(nb_aper, (32*1024*1024)<<nb_order))
+ return 0;
+ }
+
dev_info(&agp->dev, "aperture from AGP @ %Lx size %u MB\n",
aper, 32 << order);
if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order))
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index c7714185f83..4373adb2119 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -633,13 +633,15 @@ static void intel_i830_init_gtt_entries(void)
break;
}
}
- if (gtt_entries > 0)
+ if (gtt_entries > 0) {
dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n",
gtt_entries / KB(1), local ? "local" : "stolen");
- else
+ gtt_entries /= KB(4);
+ } else {
dev_info(&agp_bridge->dev->dev,
"no pre-allocated video memory detected\n");
- gtt_entries /= KB(4);
+ gtt_entries = 0;
+ }
intel_private.gtt_entries = gtt_entries;
}
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index db60539bf67..699e3422ad9 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -359,9 +359,16 @@ fail:
return error;
}
-static struct device *next_device(struct klist_iter *i) {
- struct klist_node * n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+static int
+find_quicksilver(struct device *dev, void *data)
+{
+ struct parisc_device **lba = data;
+ struct parisc_device *padev = to_parisc_device(dev);
+
+ if (IS_QUICKSILVER(padev))
+ *lba = padev;
+
+ return 0;
}
static int
@@ -372,8 +379,6 @@ parisc_agp_init(void)
int err = -1;
struct parisc_device *sba = NULL, *lba = NULL;
struct lba_device *lbadev = NULL;
- struct device *dev = NULL;
- struct klist_iter i;
if (!sba_list)
goto out;
@@ -386,13 +391,7 @@ parisc_agp_init(void)
}
/* Now search our Pluto for our precious AGP device... */
- klist_iter_init(&sba->dev.klist_children, &i);
- while ((dev = next_device(&i))) {
- struct parisc_device *padev = to_parisc_device(dev);
- if (IS_QUICKSILVER(padev))
- lba = padev;
- }
- klist_iter_exit(&i);
+ device_for_each_child(&sba->dev, &lba, find_quicksilver);
if (!lba) {
printk(KERN_INFO DRVPFX "No AGP devices found.\n");
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 09676b4e5d8..94e7e3c8c05 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -318,8 +318,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
} /* else count == 0 */
tty->driver_data = hp;
- if (!hp->irq_requested)
- tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */
hp->tty = tty;
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index a53496828b7..54481a88776 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -13,10 +13,11 @@
#include <linux/types.h>
#include <asm/ebcdic.h>
+#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/mempool.h>
-#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/tty.h>
#include <linux/wait.h>
#include <net/iucv/iucv.h>
@@ -95,6 +96,12 @@ static unsigned long hvc_iucv_devices = 1;
/* Array of allocated hvc iucv tty lines... */
static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
#define IUCV_HVC_CON_IDX (0)
+/* List of z/VM user ID filter entries (struct iucv_vmid_filter) */
+#define MAX_VMID_FILTER (500)
+static size_t hvc_iucv_filter_size;
+static void *hvc_iucv_filter;
+static const char *hvc_iucv_filter_string;
+static DEFINE_RWLOCK(hvc_iucv_filter_lock);
/* Kmem cache and mempool for iucv_tty_buffer elements */
static struct kmem_cache *hvc_iucv_buffer_cache;
@@ -618,6 +625,27 @@ static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
}
/**
+ * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID
+ * @ipvmid: Originating z/VM user ID (right padded with blanks)
+ *
+ * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise
+ * non-zero.
+ */
+static int hvc_iucv_filter_connreq(u8 ipvmid[8])
+{
+ size_t i;
+
+ /* Note: default policy is ACCEPT if no filter is set */
+ if (!hvc_iucv_filter_size)
+ return 0;
+
+ for (i = 0; i < hvc_iucv_filter_size; i++)
+ if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
+ return 0;
+ return 1;
+}
+
+/**
* hvc_iucv_path_pending() - IUCV handler to process a connection request.
* @path: Pending path (struct iucv_path)
* @ipvmid: z/VM system identifier of originator
@@ -641,6 +669,7 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
{
struct hvc_iucv_private *priv;
u8 nuser_data[16];
+ u8 vm_user_id[9];
int i, rc;
priv = NULL;
@@ -653,6 +682,20 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
if (!priv)
return -ENODEV;
+ /* Enforce that ipvmid is allowed to connect to us */
+ read_lock(&hvc_iucv_filter_lock);
+ rc = hvc_iucv_filter_connreq(ipvmid);
+ read_unlock(&hvc_iucv_filter_lock);
+ if (rc) {
+ iucv_path_sever(path, ipuser);
+ iucv_path_free(path);
+ memcpy(vm_user_id, ipvmid, 8);
+ vm_user_id[8] = 0;
+ pr_info("A connection request from z/VM user ID %s "
+ "was refused\n", vm_user_id);
+ return 0;
+ }
+
spin_lock(&priv->lock);
/* If the terminal is already connected or being severed, then sever
@@ -877,6 +920,171 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
}
/**
+ * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID
+ * @filter: String containing a comma-separated list of z/VM user IDs
+ */
+static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
+{
+ const char *nextdelim, *residual;
+ size_t len;
+
+ nextdelim = strchr(filter, ',');
+ if (nextdelim) {
+ len = nextdelim - filter;
+ residual = nextdelim + 1;
+ } else {
+ len = strlen(filter);
+ residual = filter + len;
+ }
+
+ if (len == 0)
+ return ERR_PTR(-EINVAL);
+
+ /* check for '\n' (if called from sysfs) */
+ if (filter[len - 1] == '\n')
+ len--;
+
+ if (len > 8)
+ return ERR_PTR(-EINVAL);
+
+ /* pad with blanks and save upper case version of user ID */
+ memset(dest, ' ', 8);
+ while (len--)
+ dest[len] = toupper(filter[len]);
+ return residual;
+}
+
+/**
+ * hvc_iucv_setup_filter() - Set up z/VM user ID filter
+ * @filter: String consisting of a comma-separated list of z/VM user IDs
+ *
+ * The function parses the @filter string and creates an array containing
+ * the list of z/VM user ID filter entries.
+ * Return code 0 means success, -EINVAL if the filter is syntactically
+ * incorrect, -ENOMEM if there was not enough memory to allocate the
+ * filter list array, or -ENOSPC if too many z/VM user IDs have been specified.
+ */
+static int hvc_iucv_setup_filter(const char *val)
+{
+ const char *residual;
+ int err;
+ size_t size, count;
+ void *array, *old_filter;
+
+ count = strlen(val);
+ if (count == 0 || (count == 1 && val[0] == '\n')) {
+ size = 0;
+ array = NULL;
+ goto out_replace_filter; /* clear filter */
+ }
+
+ /* count user IDs in order to allocate sufficient memory */
+ size = 1;
+ residual = val;
+ while ((residual = strchr(residual, ',')) != NULL) {
+ residual++;
+ size++;
+ }
+
+ /* check if the specified list exceeds the filter limit */
+ if (size > MAX_VMID_FILTER)
+ return -ENOSPC;
+
+ array = kzalloc(size * 8, GFP_KERNEL);
+ if (!array)
+ return -ENOMEM;
+
+ count = size;
+ residual = val;
+ while (*residual && count) {
+ residual = hvc_iucv_parse_filter(residual,
+ array + ((size - count) * 8));
+ if (IS_ERR(residual)) {
+ err = PTR_ERR(residual);
+ kfree(array);
+ goto out_err;
+ }
+ count--;
+ }
+
+out_replace_filter:
+ write_lock_bh(&hvc_iucv_filter_lock);
+ old_filter = hvc_iucv_filter;
+ hvc_iucv_filter_size = size;
+ hvc_iucv_filter = array;
+ write_unlock_bh(&hvc_iucv_filter_lock);
+ kfree(old_filter);
+
+ err = 0;
+out_err:
+ return err;
+}
+
+/**
+ * param_set_vmidfilter() - Set z/VM user ID filter parameter
+ * @val: String consisting of a comma-separated list of z/VM user IDs
+ * @kp: Kernel parameter pointing to hvc_iucv_filter array
+ *
+ * The function sets up the z/VM user ID filter specified as comma-separated
+ * list of user IDs in @val.
+ * Note: If it is called early in the boot process, @val is stored and
+ * parsed later in hvc_iucv_init().
+ */
+static int param_set_vmidfilter(const char *val, struct kernel_param *kp)
+{
+ int rc;
+
+ if (!MACHINE_IS_VM || !hvc_iucv_devices)
+ return -ENODEV;
+
+ if (!val)
+ return -EINVAL;
+
+ rc = 0;
+ if (slab_is_available())
+ rc = hvc_iucv_setup_filter(val);
+ else
+ hvc_iucv_filter_string = val; /* defer... */
+ return rc;
+}
+
+/**
+ * param_get_vmidfilter() - Get z/VM user ID filter
+ * @buffer: Buffer to store z/VM user ID filter,
+ * (buffer size assumption PAGE_SIZE)
+ * @kp: Kernel parameter pointing to the hvc_iucv_filter array
+ *
+ * The function stores the filter as a comma-separated list of z/VM user IDs
+ * in @buffer. Typically, sysfs routines call this function for attr show.
+ */
+static int param_get_vmidfilter(char *buffer, struct kernel_param *kp)
+{
+ int rc;
+ size_t index, len;
+ void *start, *end;
+
+ if (!MACHINE_IS_VM || !hvc_iucv_devices)
+ return -ENODEV;
+
+ rc = 0;
+ read_lock_bh(&hvc_iucv_filter_lock);
+ for (index = 0; index < hvc_iucv_filter_size; index++) {
+ start = hvc_iucv_filter + (8 * index);
+ end = memchr(start, ' ', 8);
+ len = (end) ? end - start : 8;
+ memcpy(buffer + rc, start, len);
+ rc += len;
+ buffer[rc++] = ',';
+ }
+ read_unlock_bh(&hvc_iucv_filter_lock);
+ if (rc)
+ buffer[--rc] = '\0'; /* replace last comma and update rc */
+ return rc;
+}
+
+#define param_check_vmidfilter(name, p) __param_check(name, p, void)
+
+/**
* hvc_iucv_init() - z/VM IUCV HVC device driver initialization
*/
static int __init hvc_iucv_init(void)
@@ -884,24 +1092,53 @@ static int __init hvc_iucv_init(void)
int rc;
unsigned int i;
+ if (!hvc_iucv_devices)
+ return -ENODEV;
+
if (!MACHINE_IS_VM) {
- pr_info("The z/VM IUCV HVC device driver cannot "
+ pr_notice("The z/VM IUCV HVC device driver cannot "
"be used without z/VM\n");
- return -ENODEV;
+ rc = -ENODEV;
+ goto out_error;
}
- if (!hvc_iucv_devices)
- return -ENODEV;
+ if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) {
+ pr_err("%lu is not a valid value for the hvc_iucv= "
+ "kernel parameter\n", hvc_iucv_devices);
+ rc = -EINVAL;
+ goto out_error;
+ }
- if (hvc_iucv_devices > MAX_HVC_IUCV_LINES)
- return -EINVAL;
+ /* parse hvc_iucv_allow string and create z/VM user ID filter list */
+ if (hvc_iucv_filter_string) {
+ rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
+ switch (rc) {
+ case 0:
+ break;
+ case -ENOMEM:
+ pr_err("Allocating memory failed with "
+ "reason code=%d\n", 3);
+ goto out_error;
+ case -EINVAL:
+ pr_err("hvc_iucv_allow= does not specify a valid "
+ "z/VM user ID list\n");
+ goto out_error;
+ case -ENOSPC:
+ pr_err("hvc_iucv_allow= specifies too many "
+ "z/VM user IDs\n");
+ goto out_error;
+ default:
+ goto out_error;
+ }
+ }
hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
sizeof(struct iucv_tty_buffer),
0, 0, NULL);
if (!hvc_iucv_buffer_cache) {
pr_err("Allocating memory failed with reason code=%d\n", 1);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out_error;
}
hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
@@ -909,7 +1146,8 @@ static int __init hvc_iucv_init(void)
if (!hvc_iucv_mempool) {
pr_err("Allocating memory failed with reason code=%d\n", 2);
kmem_cache_destroy(hvc_iucv_buffer_cache);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out_error;
}
/* register the first terminal device as console
@@ -953,6 +1191,8 @@ out_error_hvc:
out_error_memory:
mempool_destroy(hvc_iucv_mempool);
kmem_cache_destroy(hvc_iucv_buffer_cache);
+out_error:
+ hvc_iucv_devices = 0; /* ensure that we do not provide any device */
return rc;
}
@@ -968,3 +1208,4 @@ static int __init hvc_iucv_config(char *val)
device_initcall(hvc_iucv_init);
__setup("hvc_iucv=", hvc_iucv_config);
+core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 6e6eb445d37..c76bccf5354 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -1139,15 +1139,6 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
hvcsd->tty = tty;
tty->driver_data = hvcsd;
- /*
- * Set this driver to low latency so that we actually have a chance at
- * catching a throttled TTY after we flip_buffer_push. Otherwise the
- * flush_to_async may not execute until after the kernel_thread has
- * yielded and resumed the next flip_buffer_push resulting in data
- * loss.
- */
- tty->low_latency = 1;
-
memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN);
/*
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index 406f8742a26..2989056a9e3 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -810,7 +810,6 @@ static int hvsi_open(struct tty_struct *tty, struct file *filp)
hp = &hvsi_ports[line];
tty->driver_data = hp;
- tty->low_latency = 1; /* avoid throttle/tty_flip_buffer_push race */
mb();
if (hp->state == HVSI_FSP_DIED)
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 8822eca58ff..5fab6470f4b 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -20,6 +20,20 @@ config HW_RANDOM
If unsure, say Y.
+config HW_RANDOM_TIMERIOMEM
+ tristate "Timer IOMEM HW Random Number Generator support"
+ depends on HW_RANDOM && HAS_IOMEM
+ ---help---
+ This driver provides kernel-side support for a generic Random
+ Number Generator used by reading a 'dumb' iomem address that
+ is to be read no faster than, for example, once a second;
+ the default FPGA bitstream on the TS-7800 has such functionality.
+
+ To compile this driver as a module, choose M here: the
+ module will be called timeriomem-rng.
+
+ If unsure, say Y.
+
config HW_RANDOM_INTEL
tristate "Intel HW Random Number Generator support"
depends on HW_RANDOM && (X86 || IA64) && PCI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index b6effb7522c..e81d21a5f28 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_HW_RANDOM) += rng-core.o
rng-core-y := core.o
+obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index d4e7dca06e4..ba68a4671cb 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -102,7 +102,7 @@ static int __init omap_rng_probe(struct platform_device *pdev)
return -EBUSY;
if (cpu_is_omap24xx()) {
- rng_ick = clk_get(NULL, "rng_ick");
+ rng_ick = clk_get(&pdev->dev, "rng_ick");
if (IS_ERR(rng_ick)) {
dev_err(&pdev->dev, "Could not get rng_ick\n");
ret = PTR_ERR(rng_ick);
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
new file mode 100644
index 00000000000..10ad41be589
--- /dev/null
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -0,0 +1,151 @@
+/*
+ * drivers/char/hw_random/timeriomem-rng.c
+ *
+ * Copyright (C) 2009 Alexander Clouter <alex@digriz.org.uk>
+ *
+ * Derived from drivers/char/hw_random/omap-rng.c
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Overview:
+ * This driver is useful for platforms that have an IO range that provides
+ * periodic random data from a single IO memory address. All the platform
+ * has to do is provide the address and 'wait time' that new data becomes
+ * available.
+ *
+ * TODO: add support for reading sizes other than 32bits and masking
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/timeriomem-rng.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
+
+static struct timeriomem_rng_data *timeriomem_rng_data;
+
+static void timeriomem_rng_trigger(unsigned long);
+static DEFINE_TIMER(timeriomem_rng_timer, timeriomem_rng_trigger, 0, 0);
+
+/*
+ * have data return 1, however return 0 if we have nothing
+ */
+static int timeriomem_rng_data_present(struct hwrng *rng, int wait)
+{
+ if (rng->priv == 0)
+ return 1;
+
+ if (!wait || timeriomem_rng_data->present)
+ return timeriomem_rng_data->present;
+
+ wait_for_completion(&timeriomem_rng_data->completion);
+
+ return 1;
+}
+
+static int timeriomem_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ unsigned long cur;
+ s32 delay;
+
+ *data = readl(timeriomem_rng_data->address);
+
+ if (rng->priv != 0) {
+ cur = jiffies;
+
+ delay = cur - timeriomem_rng_timer.expires;
+ delay = rng->priv - (delay % rng->priv);
+
+ timeriomem_rng_timer.expires = cur + delay;
+ timeriomem_rng_data->present = 0;
+
+ init_completion(&timeriomem_rng_data->completion);
+ add_timer(&timeriomem_rng_timer);
+ }
+
+ return 4;
+}
+
+static void timeriomem_rng_trigger(unsigned long dummy)
+{
+ timeriomem_rng_data->present = 1;
+ complete(&timeriomem_rng_data->completion);
+}
+
+static struct hwrng timeriomem_rng_ops = {
+ .name = "timeriomem",
+ .data_present = timeriomem_rng_data_present,
+ .data_read = timeriomem_rng_data_read,
+ .priv = 0,
+};
+
+static int __init timeriomem_rng_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ timeriomem_rng_data = pdev->dev.platform_data;
+
+ if (timeriomem_rng_data->period != 0
+ && usecs_to_jiffies(timeriomem_rng_data->period) > 0) {
+ timeriomem_rng_timer.expires = jiffies;
+
+ timeriomem_rng_ops.priv = usecs_to_jiffies(
+ timeriomem_rng_data->period);
+ }
+ timeriomem_rng_data->present = 1;
+
+ ret = hwrng_register(&timeriomem_rng_ops);
+ if (ret) {
+ dev_err(&pdev->dev, "problem registering\n");
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
+ timeriomem_rng_data->address,
+ timeriomem_rng_data->period);
+
+ return 0;
+}
+
+static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
+{
+ del_timer_sync(&timeriomem_rng_timer);
+ hwrng_unregister(&timeriomem_rng_ops);
+
+ return 0;
+}
+
+static struct platform_driver timeriomem_rng_driver = {
+ .driver = {
+ .name = "timeriomem_rng",
+ .owner = THIS_MODULE,
+ },
+ .probe = timeriomem_rng_probe,
+ .remove = __devexit_p(timeriomem_rng_remove),
+};
+
+static int __init timeriomem_rng_init(void)
+{
+ return platform_driver_register(&timeriomem_rng_driver);
+}
+
+static void __exit timeriomem_rng_exit(void)
+{
+ platform_driver_unregister(&timeriomem_rng_driver);
+}
+
+module_init(timeriomem_rng_init);
+module_exit(timeriomem_rng_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
+MODULE_DESCRIPTION("Timer IOMEM H/W RNG driver");
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index dc073e167ab..5608a1e5a3b 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -4311,10 +4311,17 @@ static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
dev->stats.rx_bytes += size;
netif_rx(skb);
-
- dev->last_rx = jiffies;
}
+static const struct net_device_ops hdlcdev_ops = {
+ .ndo_open = hdlcdev_open,
+ .ndo_stop = hdlcdev_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
/**
* called by device driver when adding device instance
* do generic HDLC initialization
@@ -4341,11 +4348,8 @@ static int hdlcdev_init(MGSLPC_INFO *info)
dev->irq = info->irq_level;
/* network layer callbacks and settings */
- dev->do_ioctl = hdlcdev_ioctl;
- dev->open = hdlcdev_open;
- dev->stop = hdlcdev_close;
- dev->tx_timeout = hdlcdev_tx_timeout;
- dev->watchdog_timeo = 10*HZ;
+ dev->netdev_ops = &hdlcdev_ops;
+ dev->watchdog_timeo = 10 * HZ;
dev->tx_queue_len = 50;
/* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index 79b6f461be7..afbe45676d7 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -44,7 +44,7 @@ static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev,
u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors,
write);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
+ dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
__LINE__, write ? "write" : "read", res);
return -EIO;
}
@@ -59,7 +59,7 @@ static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev,
max_sectors = dev->bounce_size / dev->blk_size;
if (sectors > max_sectors) {
- dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %lu\n",
+ dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %llu\n",
__func__, __LINE__, max_sectors);
sectors = max_sectors;
}
@@ -144,7 +144,7 @@ static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count,
goto fail;
}
- n = min(remaining, sectors_read*dev->blk_size-offset);
+ n = min_t(u64, remaining, sectors_read*dev->blk_size-offset);
dev_dbg(&dev->sbd.core,
"%s:%u: copy %lu bytes from 0x%p to user 0x%p\n",
__func__, __LINE__, n, dev->bounce_buf+offset, buf);
@@ -225,7 +225,7 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf,
if (end_read_sector >= start_read_sector) {
/* Merge head and tail */
dev_dbg(&dev->sbd.core,
- "Merged head and tail: %lu sectors at %lu\n",
+ "Merged head and tail: %llu sectors at %llu\n",
chunk_sectors, start_write_sector);
res = ps3flash_read_sectors(dev, start_write_sector,
chunk_sectors, 0);
@@ -235,7 +235,7 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf,
if (head) {
/* Read head */
dev_dbg(&dev->sbd.core,
- "head: %lu sectors at %lu\n", head,
+ "head: %llu sectors at %llu\n", head,
start_write_sector);
res = ps3flash_read_sectors(dev,
start_write_sector,
@@ -247,7 +247,7 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf,
start_write_sector+chunk_sectors) {
/* Read tail */
dev_dbg(&dev->sbd.core,
- "tail: %lu sectors at %lu\n", tail,
+ "tail: %llu sectors at %llu\n", tail,
start_read_sector);
sec_off = start_read_sector-start_write_sector;
res = ps3flash_read_sectors(dev,
@@ -258,7 +258,7 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf,
}
}
- n = min(remaining, dev->bounce_size-offset);
+ n = min_t(u64, remaining, dev->bounce_size-offset);
dev_dbg(&dev->sbd.core,
"%s:%u: copy %lu bytes from user 0x%p to 0x%p\n",
__func__, __LINE__, n, buf, dev->bounce_buf+offset);
@@ -299,11 +299,11 @@ static irqreturn_t ps3flash_interrupt(int irq, void *data)
if (tag != dev->tag)
dev_err(&dev->sbd.core,
- "%s:%u: tag mismatch, got %lx, expected %lx\n",
+ "%s:%u: tag mismatch, got %llx, expected %llx\n",
__func__, __LINE__, tag, dev->tag);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
__func__, __LINE__, res, status);
} else {
dev->lv1_status = status;
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7c13581ca9c..7c43ae782b2 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -241,6 +241,10 @@
#include <linux/percpu.h>
#include <linux/cryptohash.h>
+#ifdef CONFIG_GENERIC_HARDIRQS
+# include <linux/irq.h>
+#endif
+
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
@@ -558,7 +562,7 @@ struct timer_rand_state {
unsigned dont_count_entropy:1;
};
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
static struct timer_rand_state *irq_timer_state[NR_IRQS];
diff --git a/drivers/char/scc.h b/drivers/char/scc.h
index 93998f5baff..341b1142bea 100644
--- a/drivers/char/scc.h
+++ b/drivers/char/scc.h
@@ -387,7 +387,7 @@ struct scc_port {
/* The SCC needs 3.5 PCLK cycles recovery time between to register
* accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 *
* 125 ns = 437.5 ns. This is too short for udelay().
- * 10/16/95: A tstb mfp.par_dt_reg takes 600ns (sure?) and thus should be
+ * 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be
* quite right
*/
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index f29fbe9b8ed..cb8ca569896 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -268,7 +268,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
/* Allocate a new buffer before freeing the old one ... */
multiplier = use_unicode ? 3 : 1; /* chars can take up to 3 bytes */
- bp = kmalloc((sel_end-sel_start)/2*multiplier+1, GFP_KERNEL);
+ bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL);
if (!bp) {
printk(KERN_WARNING "selection: kmalloc() failed\n");
clear_selection();
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index f4374437a03..fd3dced9777 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -888,12 +888,7 @@ found:
static int sonypi_misc_fasync(int fd, struct file *filp, int on)
{
- int retval;
-
- retval = fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
- if (retval < 0)
- return retval;
- return 0;
+ return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
}
static int sonypi_misc_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index b60be7b0dec..518f2a25d91 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1713,8 +1713,8 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
for (i = 0; i < SX_NBOARDS; i++)
sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags);
sx_dprintk(SX_DEBUG_FIRMWARE, "\n");
- unlock_kernel();
- return -EIO;
+ rc = -EIO;
+ goto out;
}
switch (cmd) {
@@ -1746,8 +1746,10 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc);
break;
case SXIO_DO_RAMTEST:
- if (sx_initialized) /* Already initialized: better not ramtest the board. */
- return -EPERM;
+ if (sx_initialized) { /* Already initialized: better not ramtest the board. */
+ rc = -EPERM;
+ break;
+ }
if (IS_SX_BOARD(board)) {
rc = do_memtest(board, 0, 0x7000);
if (!rc)
@@ -1787,7 +1789,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
nbytes - i : SX_CHUNK_SIZE)) {
kfree(tmp);
rc = -EFAULT;
- break;
+ goto out;
}
memcpy_toio(board->base2 + offset + i, tmp,
(i + SX_CHUNK_SIZE > nbytes) ?
@@ -1844,6 +1846,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
rc = -ENOTTY;
break;
}
+out:
unlock_kernel();
func_exit();
return rc;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index b8063d4cad3..0057a8f58cb 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -8007,10 +8007,17 @@ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
dev->stats.rx_bytes += size;
netif_rx(skb);
-
- dev->last_rx = jiffies;
}
+static const struct net_device_ops hdlcdev_ops = {
+ .ndo_open = hdlcdev_open,
+ .ndo_stop = hdlcdev_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
/**
* called by device driver when adding device instance
* do generic HDLC initialization
@@ -8038,11 +8045,8 @@ static int hdlcdev_init(struct mgsl_struct *info)
dev->dma = info->dma_level;
/* network layer callbacks and settings */
- dev->do_ioctl = hdlcdev_ioctl;
- dev->open = hdlcdev_open;
- dev->stop = hdlcdev_close;
- dev->tx_timeout = hdlcdev_tx_timeout;
- dev->watchdog_timeo = 10*HZ;
+ dev->netdev_ops = &hdlcdev_ops;
+ dev->watchdog_timeo = 10 * HZ;
dev->tx_queue_len = 50;
/* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index f329f459817..efb3dc928a4 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1763,10 +1763,17 @@ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
dev->stats.rx_bytes += size;
netif_rx(skb);
-
- dev->last_rx = jiffies;
}
+static const struct net_device_ops hdlcdev_ops = {
+ .ndo_open = hdlcdev_open,
+ .ndo_stop = hdlcdev_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
/**
* called by device driver when adding device instance
* do generic HDLC initialization
@@ -1794,11 +1801,8 @@ static int hdlcdev_init(struct slgt_info *info)
dev->irq = info->irq_level;
/* network layer callbacks and settings */
- dev->do_ioctl = hdlcdev_ioctl;
- dev->open = hdlcdev_open;
- dev->stop = hdlcdev_close;
- dev->tx_timeout = hdlcdev_tx_timeout;
- dev->watchdog_timeo = 10*HZ;
+ dev->netdev_ops = &hdlcdev_ops;
+ dev->watchdog_timeo = 10 * HZ;
dev->tx_queue_len = 50;
/* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 7b0c5b2dd26..8eb6c89a980 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1907,10 +1907,17 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
dev->stats.rx_bytes += size;
netif_rx(skb);
-
- dev->last_rx = jiffies;
}
+static const struct net_device_ops hdlcdev_ops = {
+ .ndo_open = hdlcdev_open,
+ .ndo_stop = hdlcdev_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
/**
* called by device driver when adding device instance
* do generic HDLC initialization
@@ -1938,11 +1945,8 @@ static int hdlcdev_init(SLMP_INFO *info)
dev->irq = info->irq_level;
/* network layer callbacks and settings */
- dev->do_ioctl = hdlcdev_ioctl;
- dev->open = hdlcdev_open;
- dev->stop = hdlcdev_close;
- dev->tx_timeout = hdlcdev_tx_timeout;
- dev->watchdog_timeo = 10*HZ;
+ dev->netdev_ops = &hdlcdev_ops;
+ dev->watchdog_timeo = 10 * HZ;
dev->tx_queue_len = 50;
/* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 9c47dc48c9f..ccdd828adce 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -429,134 +429,148 @@ out:
#define TPM_DIGEST_SIZE 20
#define TPM_ERROR_SIZE 10
#define TPM_RET_CODE_IDX 6
-#define TPM_GET_CAP_RET_SIZE_IDX 10
-#define TPM_GET_CAP_RET_UINT32_1_IDX 14
-#define TPM_GET_CAP_RET_UINT32_2_IDX 18
-#define TPM_GET_CAP_RET_UINT32_3_IDX 22
-#define TPM_GET_CAP_RET_UINT32_4_IDX 26
-#define TPM_GET_CAP_PERM_DISABLE_IDX 16
-#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
-#define TPM_GET_CAP_RET_BOOL_1_IDX 14
-#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
-
-#define TPM_CAP_IDX 13
-#define TPM_CAP_SUBCAP_IDX 21
enum tpm_capabilities {
- TPM_CAP_FLAG = 4,
- TPM_CAP_PROP = 5,
+ TPM_CAP_FLAG = cpu_to_be32(4),
+ TPM_CAP_PROP = cpu_to_be32(5),
+ CAP_VERSION_1_1 = cpu_to_be32(0x06),
+ CAP_VERSION_1_2 = cpu_to_be32(0x1A)
};
enum tpm_sub_capabilities {
- TPM_CAP_PROP_PCR = 0x1,
- TPM_CAP_PROP_MANUFACTURER = 0x3,
- TPM_CAP_FLAG_PERM = 0x8,
- TPM_CAP_FLAG_VOL = 0x9,
- TPM_CAP_PROP_OWNER = 0x11,
- TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
- TPM_CAP_PROP_TIS_DURATION = 0x20,
-};
+ TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
+ TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
+ TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
+ TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
+ TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
+ TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
+ TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
-/*
- * This is a semi generic GetCapability command for use
- * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
- * and their associated sub_capabilities.
- */
-
-static const u8 tpm_cap[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 22, /* length */
- 0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 0, /* TPM_CAP_<TYPE> */
- 0, 0, 0, 4, /* TPM_CAP_SUB_<TYPE> size */
- 0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */
};
-static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
- char *desc)
+static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
+ int len, const char *desc)
{
int err;
- len = tpm_transmit(chip, data, len);
+ len = tpm_transmit(chip,(u8 *) cmd, len);
if (len < 0)
return len;
if (len == TPM_ERROR_SIZE) {
- err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
+ err = be32_to_cpu(cmd->header.out.return_code);
dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
return err;
}
return 0;
}
+#define TPM_INTERNAL_RESULT_SIZE 200
+#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
+#define TPM_ORD_GET_CAP cpu_to_be32(101)
+
+static const struct tpm_input_header tpm_getcap_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(22),
+ .ordinal = TPM_ORD_GET_CAP
+};
+
+ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
+ const char *desc)
+{
+ struct tpm_cmd_t tpm_cmd;
+ int rc;
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+
+ tpm_cmd.header.in = tpm_getcap_header;
+ if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
+ tpm_cmd.params.getcap_in.cap = subcap_id;
+ /*subcap field not necessary */
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(0);
+ tpm_cmd.header.in.length -= cpu_to_be32(sizeof(__be32));
+ } else {
+ if (subcap_id == TPM_CAP_FLAG_PERM ||
+ subcap_id == TPM_CAP_FLAG_VOL)
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_FLAG;
+ else
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ tpm_cmd.params.getcap_in.subcap = subcap_id;
+ }
+ rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
+ if (!rc)
+ *cap = tpm_cmd.params.getcap_out.cap;
+ return rc;
+}
+
void tpm_gen_interrupt(struct tpm_chip *chip)
{
- u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+ struct tpm_cmd_t tpm_cmd;
ssize_t rc;
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+ tpm_cmd.header.in = tpm_getcap_header;
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
- rc = transmit_cmd(chip, data, sizeof(data),
+ rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the timeouts");
}
EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
void tpm_get_timeouts(struct tpm_chip *chip)
{
- u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+ struct tpm_cmd_t tpm_cmd;
+ struct timeout_t *timeout_cap;
+ struct duration_t *duration_cap;
ssize_t rc;
u32 timeout;
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+ tpm_cmd.header.in = tpm_getcap_header;
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
- rc = transmit_cmd(chip, data, sizeof(data),
+ rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the timeouts");
if (rc)
goto duration;
- if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+ if (be32_to_cpu(tpm_cmd.header.out.length)
!= 4 * sizeof(u32))
goto duration;
+ timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout;
/* Don't overwrite default if value is 0 */
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+ timeout = be32_to_cpu(timeout_cap->a);
if (timeout)
chip->vendor.timeout_a = usecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+ timeout = be32_to_cpu(timeout_cap->b);
if (timeout)
chip->vendor.timeout_b = usecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+ timeout = be32_to_cpu(timeout_cap->c);
if (timeout)
chip->vendor.timeout_c = usecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
+ timeout = be32_to_cpu(timeout_cap->d);
if (timeout)
chip->vendor.timeout_d = usecs_to_jiffies(timeout);
duration:
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
+ tpm_cmd.header.in = tpm_getcap_header;
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
- rc = transmit_cmd(chip, data, sizeof(data),
+ rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the durations");
if (rc)
return;
- if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+ if (be32_to_cpu(tpm_cmd.header.out.return_code)
!= 3 * sizeof(u32))
return;
-
+ duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
chip->vendor.duration[TPM_SHORT] =
- usecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_1_IDX))));
+ usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
/* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
* value wrong and apparently reports msecs rather than usecs. So we
* fix up the resulting too-small TPM_SHORT value to make things work.
@@ -565,13 +579,9 @@ duration:
chip->vendor.duration[TPM_SHORT] = HZ;
chip->vendor.duration[TPM_MEDIUM] =
- usecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_2_IDX))));
+ usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_medium));
chip->vendor.duration[TPM_LONG] =
- usecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_3_IDX))));
+ usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_long));
}
EXPORT_SYMBOL_GPL(tpm_get_timeouts);
@@ -587,36 +597,18 @@ void tpm_continue_selftest(struct tpm_chip *chip)
}
EXPORT_SYMBOL_GPL(tpm_continue_selftest);
-#define TPM_INTERNAL_RESULT_SIZE 200
-
ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attemtping to determine the permanent enabled state");
- if (rc) {
- kfree(data);
+ rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
+ "attempting to determine the permanent enabled state");
+ if (rc)
return 0;
- }
-
- rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
- kfree(data);
+ rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_show_enabled);
@@ -624,31 +616,15 @@ EXPORT_SYMBOL_GPL(tpm_show_enabled);
ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attemtping to determine the permanent active state");
- if (rc) {
- kfree(data);
+ rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
+ "attempting to determine the permanent active state");
+ if (rc)
return 0;
- }
- rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
-
- kfree(data);
+ rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_show_active);
@@ -656,31 +632,15 @@ EXPORT_SYMBOL_GPL(tpm_show_active);
ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attempting to determine the owner state");
- if (rc) {
- kfree(data);
+ rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap,
+ "attempting to determine the owner state");
+ if (rc)
return 0;
- }
-
- rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
- kfree(data);
+ rc = sprintf(buf, "%d\n", cap.owned);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_show_owned);
@@ -688,116 +648,180 @@ EXPORT_SYMBOL_GPL(tpm_show_owned);
ssize_t tpm_show_temp_deactivated(struct device * dev,
struct device_attribute * attr, char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
+ rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap,
+ "attempting to determine the temporary state");
+ if (rc)
+ return 0;
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
+ rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
+/*
+ * tpm_chip_find_get - return tpm_chip for given chip number
+ */
+static struct tpm_chip *tpm_chip_find_get(int chip_num)
+{
+ struct tpm_chip *pos, *chip = NULL;
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attempting to determine the temporary state");
- if (rc) {
- kfree(data);
- return 0;
+ rcu_read_lock();
+ list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
+ if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
+ continue;
+
+ if (try_module_get(pos->dev->driver->owner)) {
+ chip = pos;
+ break;
+ }
}
+ rcu_read_unlock();
+ return chip;
+}
- rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
+#define TPM_ORDINAL_PCRREAD cpu_to_be32(21)
+#define READ_PCR_RESULT_SIZE 30
+static struct tpm_input_header pcrread_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(14),
+ .ordinal = TPM_ORDINAL_PCRREAD
+};
- kfree(data);
+int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+{
+ int rc;
+ struct tpm_cmd_t cmd;
+
+ cmd.header.in = pcrread_header;
+ cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
+ BUILD_BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE);
+ rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
+ "attempting to read a pcr value");
+
+ if (rc == 0)
+ memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
+ TPM_DIGEST_SIZE);
return rc;
}
-EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
-static const u8 pcrread[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 14, /* length */
- 0, 0, 0, 21, /* TPM_ORD_PcrRead */
- 0, 0, 0, 0 /* PCR index */
+/**
+ * tpm_pcr_read - read a pcr value
+ * @chip_num: tpm idx # or ANY
+ * @pcr_idx: pcr idx to retrieve
+ * @res_buf: TPM_PCR value
+ * size of res_buf is 20 bytes (or NULL if you don't care)
+ *
+ * The TPM driver should be built-in, but for whatever reason it
+ * isn't, protect against the chip disappearing, by incrementing
+ * the module usage count.
+ */
+int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
+{
+ struct tpm_chip *chip;
+ int rc;
+
+ chip = tpm_chip_find_get(chip_num);
+ if (chip == NULL)
+ return -ENODEV;
+ rc = __tpm_pcr_read(chip, pcr_idx, res_buf);
+ module_put(chip->dev->driver->owner);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_pcr_read);
+
+/**
+ * tpm_pcr_extend - extend pcr value with hash
+ * @chip_num: tpm idx # or AN&
+ * @pcr_idx: pcr idx to extend
+ * @hash: hash value used to extend pcr value
+ *
+ * The TPM driver should be built-in, but for whatever reason it
+ * isn't, protect against the chip disappearing, by incrementing
+ * the module usage count.
+ */
+#define TPM_ORD_PCR_EXTEND cpu_to_be32(20)
+#define EXTEND_PCR_SIZE 34
+static struct tpm_input_header pcrextend_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(34),
+ .ordinal = TPM_ORD_PCR_EXTEND
};
+int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
+{
+ struct tpm_cmd_t cmd;
+ int rc;
+ struct tpm_chip *chip;
+
+ chip = tpm_chip_find_get(chip_num);
+ if (chip == NULL)
+ return -ENODEV;
+
+ cmd.header.in = pcrextend_header;
+ BUILD_BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE);
+ cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
+ memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
+ rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
+ "attempting extend a PCR value");
+
+ module_put(chip->dev->driver->owner);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_pcr_extend);
+
ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
+ u8 digest[TPM_DIGEST_SIZE];
ssize_t rc;
int i, j, num_pcrs;
- __be32 index;
char *str = buf;
-
struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
+ rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap,
"attempting to determine the number of PCRS");
- if (rc) {
- kfree(data);
+ if (rc)
return 0;
- }
- num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
+ num_pcrs = be32_to_cpu(cap.num_pcrs);
for (i = 0; i < num_pcrs; i++) {
- memcpy(data, pcrread, sizeof(pcrread));
- index = cpu_to_be32(i);
- memcpy(data + 10, &index, 4);
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attempting to read a PCR");
+ rc = __tpm_pcr_read(chip, i, digest);
if (rc)
- goto out;
+ break;
str += sprintf(str, "PCR-%02d: ", i);
for (j = 0; j < TPM_DIGEST_SIZE; j++)
- str += sprintf(str, "%02X ", *(data + 10 + j));
+ str += sprintf(str, "%02X ", digest[j]);
str += sprintf(str, "\n");
}
-out:
- kfree(data);
return str - buf;
}
EXPORT_SYMBOL_GPL(tpm_show_pcrs);
#define READ_PUBEK_RESULT_SIZE 314
-static const u8 readpubek[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 30, /* length */
- 0, 0, 0, 124, /* TPM_ORD_ReadPubek */
+#define TPM_ORD_READPUBEK cpu_to_be32(124)
+struct tpm_input_header tpm_readpubek_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(30),
+ .ordinal = TPM_ORD_READPUBEK
};
ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
char *buf)
{
u8 *data;
+ struct tpm_cmd_t tpm_cmd;
ssize_t err;
int i, rc;
char *str = buf;
struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
- data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, readpubek, sizeof(readpubek));
-
- err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
+ tpm_cmd.header.in = tpm_readpubek_header;
+ err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
"attempting to read the PUBEK");
if (err)
goto out;
@@ -812,7 +836,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
256 byte modulus
ignore checksum 20 bytes
*/
-
+ data = tpm_cmd.params.readpubek_out_buffer;
str +=
sprintf(str,
"Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
@@ -832,65 +856,33 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
}
out:
rc = str - buf;
- kfree(data);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_show_pubek);
-#define CAP_VERSION_1_1 6
-#define CAP_VERSION_1_2 0x1A
-#define CAP_VERSION_IDX 13
-static const u8 cap_version[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 18, /* length */
- 0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 0,
- 0, 0, 0, 0
-};
ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
char *str = buf;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
+ rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
"attempting to determine the manufacturer");
- if (rc) {
- kfree(data);
+ if (rc)
return 0;
- }
-
str += sprintf(str, "Manufacturer: 0x%x\n",
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
+ be32_to_cpu(cap.manufacturer_id));
- memcpy(data, cap_version, sizeof(cap_version));
- data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attempting to determine the 1.1 version");
+ rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap,
+ "attempting to determine the 1.1 version");
if (rc)
- goto out;
-
+ return 0;
str += sprintf(str,
"TCG version: %d.%d\nFirmware version: %d.%d\n",
- (int) data[14], (int) data[15], (int) data[16],
- (int) data[17]);
-
-out:
- kfree(data);
+ cap.tpm_version.Major, cap.tpm_version.Minor,
+ cap.tpm_version.revMajor, cap.tpm_version.revMinor);
return str - buf;
}
EXPORT_SYMBOL_GPL(tpm_show_caps);
@@ -898,51 +890,25 @@ EXPORT_SYMBOL_GPL(tpm_show_caps);
ssize_t tpm_show_caps_1_2(struct device * dev,
struct device_attribute * attr, char *buf)
{
- u8 *data;
- ssize_t len;
+ cap_t cap;
+ ssize_t rc;
char *str = buf;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
- len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
- if (len <= TPM_ERROR_SIZE) {
- dev_dbg(chip->dev, "A TPM error (%d) occurred "
- "attempting to determine the manufacturer\n",
- be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
- kfree(data);
+ rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
+ "attempting to determine the manufacturer");
+ if (rc)
return 0;
- }
-
str += sprintf(str, "Manufacturer: 0x%x\n",
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
-
- memcpy(data, cap_version, sizeof(cap_version));
- data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
-
- len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
- if (len <= TPM_ERROR_SIZE) {
- dev_err(chip->dev, "A TPM error (%d) occurred "
- "attempting to determine the 1.2 version\n",
- be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
- goto out;
- }
+ be32_to_cpu(cap.manufacturer_id));
+ rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap,
+ "attempting to determine the 1.2 version");
+ if (rc)
+ return 0;
str += sprintf(str,
"TCG version: %d.%d\nFirmware version: %d.%d\n",
- (int) data[16], (int) data[17], (int) data[18],
- (int) data[19]);
-
-out:
- kfree(data);
+ cap.tpm_version_1_2.Major, cap.tpm_version_1_2.Minor,
+ cap.tpm_version_1_2.revMajor,
+ cap.tpm_version_1_2.revMinor);
return str - buf;
}
EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 8e30df4a438..8e00b4ddd08 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -26,6 +26,7 @@
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/tpm.h>
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
@@ -123,6 +124,147 @@ static inline void tpm_write_index(int base, int index, int value)
outb(index, base);
outb(value & 0xFF, base+1);
}
+struct tpm_input_header {
+ __be16 tag;
+ __be32 length;
+ __be32 ordinal;
+}__attribute__((packed));
+
+struct tpm_output_header {
+ __be16 tag;
+ __be32 length;
+ __be32 return_code;
+}__attribute__((packed));
+
+struct stclear_flags_t {
+ __be16 tag;
+ u8 deactivated;
+ u8 disableForceClear;
+ u8 physicalPresence;
+ u8 physicalPresenceLock;
+ u8 bGlobalLock;
+}__attribute__((packed));
+
+struct tpm_version_t {
+ u8 Major;
+ u8 Minor;
+ u8 revMajor;
+ u8 revMinor;
+}__attribute__((packed));
+
+struct tpm_version_1_2_t {
+ __be16 tag;
+ u8 Major;
+ u8 Minor;
+ u8 revMajor;
+ u8 revMinor;
+}__attribute__((packed));
+
+struct timeout_t {
+ __be32 a;
+ __be32 b;
+ __be32 c;
+ __be32 d;
+}__attribute__((packed));
+
+struct duration_t {
+ __be32 tpm_short;
+ __be32 tpm_medium;
+ __be32 tpm_long;
+}__attribute__((packed));
+
+struct permanent_flags_t {
+ __be16 tag;
+ u8 disable;
+ u8 ownership;
+ u8 deactivated;
+ u8 readPubek;
+ u8 disableOwnerClear;
+ u8 allowMaintenance;
+ u8 physicalPresenceLifetimeLock;
+ u8 physicalPresenceHWEnable;
+ u8 physicalPresenceCMDEnable;
+ u8 CEKPUsed;
+ u8 TPMpost;
+ u8 TPMpostLock;
+ u8 FIPS;
+ u8 operator;
+ u8 enableRevokeEK;
+ u8 nvLocked;
+ u8 readSRKPub;
+ u8 tpmEstablished;
+ u8 maintenanceDone;
+ u8 disableFullDALogicInfo;
+}__attribute__((packed));
+
+typedef union {
+ struct permanent_flags_t perm_flags;
+ struct stclear_flags_t stclear_flags;
+ bool owned;
+ __be32 num_pcrs;
+ struct tpm_version_t tpm_version;
+ struct tpm_version_1_2_t tpm_version_1_2;
+ __be32 manufacturer_id;
+ struct timeout_t timeout;
+ struct duration_t duration;
+} cap_t;
+
+struct tpm_getcap_params_in {
+ __be32 cap;
+ __be32 subcap_size;
+ __be32 subcap;
+}__attribute__((packed));
+
+struct tpm_getcap_params_out {
+ __be32 cap_size;
+ cap_t cap;
+}__attribute__((packed));
+
+struct tpm_readpubek_params_out {
+ u8 algorithm[4];
+ u8 encscheme[2];
+ u8 sigscheme[2];
+ u8 parameters[12]; /*assuming RSA*/
+ __be32 keysize;
+ u8 modulus[256];
+ u8 checksum[20];
+}__attribute__((packed));
+
+typedef union {
+ struct tpm_input_header in;
+ struct tpm_output_header out;
+} tpm_cmd_header;
+
+#define TPM_DIGEST_SIZE 20
+struct tpm_pcrread_out {
+ u8 pcr_result[TPM_DIGEST_SIZE];
+}__attribute__((packed));
+
+struct tpm_pcrread_in {
+ __be32 pcr_idx;
+}__attribute__((packed));
+
+struct tpm_pcrextend_in {
+ __be32 pcr_idx;
+ u8 hash[TPM_DIGEST_SIZE];
+}__attribute__((packed));
+
+typedef union {
+ struct tpm_getcap_params_out getcap_out;
+ struct tpm_readpubek_params_out readpubek_out;
+ u8 readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
+ struct tpm_getcap_params_in getcap_in;
+ struct tpm_pcrread_in pcrread_in;
+ struct tpm_pcrread_out pcrread_out;
+ struct tpm_pcrextend_in pcrextend_in;
+} tpm_cmd_params;
+
+struct tpm_cmd_t {
+ tpm_cmd_header header;
+ tpm_cmd_params params;
+}__attribute__((packed));
+
+ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
extern void tpm_get_timeouts(struct tpm_chip *);
extern void tpm_gen_interrupt(struct tpm_chip *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index d0e7926eb48..c64a1bc6534 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -168,12 +168,22 @@ static void atml_plat_remove(void)
}
}
-static struct device_driver atml_drv = {
- .name = "tpm_atmel",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_atml_resume(struct platform_device *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver atml_drv = {
+ .driver = {
+ .name = "tpm_atmel",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tpm_atml_suspend,
+ .resume = tpm_atml_resume,
};
static int __init init_atmel(void)
@@ -184,7 +194,7 @@ static int __init init_atmel(void)
unsigned long base;
struct tpm_chip *chip;
- rc = driver_register(&atml_drv);
+ rc = platform_driver_register(&atml_drv);
if (rc)
return rc;
@@ -223,13 +233,13 @@ err_rel_reg:
atmel_release_region(base,
region_size);
err_unreg_drv:
- driver_unregister(&atml_drv);
+ platform_driver_unregister(&atml_drv);
return rc;
}
static void __exit cleanup_atmel(void)
{
- driver_unregister(&atml_drv);
+ platform_driver_unregister(&atml_drv);
atml_plat_remove();
}
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 726ee8a0277..ecba4942fc8 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -4,7 +4,7 @@
* SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
* Specifications at www.trustedcomputinggroup.org
*
- * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
+ * Copyright (C) 2005, Marcel Selhorst <m.selhorst@sirrix.com>
* Sirrix AG - security technologies, http://www.sirrix.com and
* Applied Data Security Group, Ruhr-University Bochum, Germany
* Project-Homepage: http://www.prosec.rub.de/tpm
@@ -636,7 +636,7 @@ static void __exit cleanup_inf(void)
module_init(init_inf);
module_exit(cleanup_inf);
-MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
+MODULE_AUTHOR("Marcel Selhorst <m.selhorst@sirrix.com>");
MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
MODULE_VERSION("1.9");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 717af7ad1bd..aec1931608a 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -654,12 +654,22 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
-static struct device_driver tis_drv = {
- .name = "tpm_tis",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_tis_resume(struct platform_device *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver tis_drv = {
+ .driver = {
+ .name = "tpm_tis",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tpm_tis_suspend,
+ .resume = tpm_tis_resume,
};
static struct platform_device *pdev;
@@ -672,14 +682,14 @@ static int __init init_tis(void)
int rc;
if (force) {
- rc = driver_register(&tis_drv);
+ rc = platform_driver_register(&tis_drv);
if (rc < 0)
return rc;
if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
return PTR_ERR(pdev);
if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
platform_device_unregister(pdev);
- driver_unregister(&tis_drv);
+ platform_driver_unregister(&tis_drv);
}
return rc;
}
@@ -711,7 +721,7 @@ static void __exit cleanup_tis(void)
if (force) {
platform_device_unregister(pdev);
- driver_unregister(&tis_drv);
+ platform_driver_unregister(&tis_drv);
} else
pnp_unregister_driver(&tis_pnp_driver);
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index d33e5ab0617..224f271d8cb 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1817,8 +1817,10 @@ got_driver:
/* check whether we're reopening an existing tty */
tty = tty_driver_lookup_tty(driver, inode, index);
- if (IS_ERR(tty))
+ if (IS_ERR(tty)) {
+ mutex_unlock(&tty_mutex);
return PTR_ERR(tty);
+ }
}
if (tty) {
@@ -2160,13 +2162,12 @@ static int fionbio(struct file *file, int __user *p)
if (get_user(nonblock, p))
return -EFAULT;
- /* file->f_flags is still BKL protected in the fs layer - vomit */
- lock_kernel();
+ spin_lock(&file->f_lock);
if (nonblock)
file->f_flags |= O_NONBLOCK;
else
file->f_flags &= ~O_NONBLOCK;
- unlock_kernel();
+ spin_unlock(&file->f_lock);
return 0;
}
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 4f3b3f95fc4..d94d25c12aa 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -479,18 +479,18 @@ static const struct file_operations vcs_fops = {
static struct class *vc_class;
-void vcs_make_sysfs(struct tty_struct *tty)
+void vcs_make_sysfs(int index)
{
- device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL,
- "vcs%u", tty->index + 1);
- device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL,
- "vcsa%u", tty->index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
+ "vcs%u", index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
+ "vcsa%u", index + 1);
}
-void vcs_remove_sysfs(struct tty_struct *tty)
+void vcs_remove_sysfs(int index)
{
- device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
- device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
+ device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
+ device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
}
int __init vcs_init(void)
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 7900bd63b36..2c1d133819b 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -778,6 +778,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
}
vc->vc_kmalloced = 1;
vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+ vcs_make_sysfs(currcons);
atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
}
return 0;
@@ -987,7 +988,9 @@ void vc_deallocate(unsigned int currcons)
if (vc_cons_allocated(currcons)) {
struct vc_data *vc = vc_cons[currcons].d;
struct vt_notifier_param param = { .vc = vc };
+
atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
+ vcs_remove_sysfs(currcons);
vc->vc_sw->con_deinit(vc);
put_pid(vc->vt_pid);
module_put(vc->vc_sw->owner);
@@ -2775,7 +2778,6 @@ static int con_open(struct tty_struct *tty, struct file *filp)
tty->termios->c_iflag |= IUTF8;
else
tty->termios->c_iflag &= ~IUTF8;
- vcs_make_sysfs(tty);
release_console_sem();
return ret;
}
@@ -2795,7 +2797,6 @@ static void con_shutdown(struct tty_struct *tty)
BUG_ON(vc == NULL);
acquire_console_sem();
vc->vc_tty = NULL;
- vcs_remove_sysfs(tty);
release_console_sem();
tty_shutdown(tty);
}
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 1525882190f..1efb2879a94 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
+obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
new file mode 100644
index 00000000000..7783b42f691
--- /dev/null
+++ b/drivers/clocksource/sh_cmt.c
@@ -0,0 +1,615 @@
+/*
+ * SuperH Timer Support - CMT
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/sh_cmt.h>
+
+struct sh_cmt_priv {
+ void __iomem *mapbase;
+ struct clk *clk;
+ unsigned long width; /* 16 or 32 bit version of hardware block */
+ unsigned long overflow_bit;
+ unsigned long clear_bits;
+ struct irqaction irqaction;
+ struct platform_device *pdev;
+
+ unsigned long flags;
+ unsigned long match_value;
+ unsigned long next_match_value;
+ unsigned long max_match_value;
+ unsigned long rate;
+ spinlock_t lock;
+ struct clock_event_device ced;
+ unsigned long total_cycles;
+};
+
+static DEFINE_SPINLOCK(sh_cmt_lock);
+
+#define CMSTR -1 /* shared register */
+#define CMCSR 0 /* channel register */
+#define CMCNT 1 /* channel register */
+#define CMCOR 2 /* channel register */
+
+static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == CMSTR) {
+ offs = 0;
+ base -= cfg->channel_offset;
+ } else
+ offs = reg_nr;
+
+ if (p->width == 16)
+ offs <<= 1;
+ else {
+ offs <<= 2;
+ if ((reg_nr == CMCNT) || (reg_nr == CMCOR))
+ return ioread32(base + offs);
+ }
+
+ return ioread16(base + offs);
+}
+
+static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
+ unsigned long value)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == CMSTR) {
+ offs = 0;
+ base -= cfg->channel_offset;
+ } else
+ offs = reg_nr;
+
+ if (p->width == 16)
+ offs <<= 1;
+ else {
+ offs <<= 2;
+ if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) {
+ iowrite32(value, base + offs);
+ return;
+ }
+ }
+
+ iowrite16(value, base + offs);
+}
+
+static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
+ int *has_wrapped)
+{
+ unsigned long v1, v2, v3;
+
+ /* Make sure the timer value is stable. Stolen from acpi_pm.c */
+ do {
+ v1 = sh_cmt_read(p, CMCNT);
+ v2 = sh_cmt_read(p, CMCNT);
+ v3 = sh_cmt_read(p, CMCNT);
+ } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+ || (v3 > v1 && v3 < v2)));
+
+ *has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+ return v2;
+}
+
+
+static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ unsigned long flags, value;
+
+ /* start stop register shared by multiple timer channels */
+ spin_lock_irqsave(&sh_cmt_lock, flags);
+ value = sh_cmt_read(p, CMSTR);
+
+ if (start)
+ value |= 1 << cfg->timer_bit;
+ else
+ value &= ~(1 << cfg->timer_bit);
+
+ sh_cmt_write(p, CMSTR, value);
+ spin_unlock_irqrestore(&sh_cmt_lock, flags);
+}
+
+static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ int ret;
+
+ /* enable clock */
+ ret = clk_enable(p->clk);
+ if (ret) {
+ pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk);
+ return ret;
+ }
+ *rate = clk_get_rate(p->clk) / 8;
+
+ /* make sure channel is disabled */
+ sh_cmt_start_stop_ch(p, 0);
+
+ /* configure channel, periodic mode and maximum timeout */
+ if (p->width == 16)
+ sh_cmt_write(p, CMCSR, 0);
+ else
+ sh_cmt_write(p, CMCSR, 0x01a4);
+
+ sh_cmt_write(p, CMCOR, 0xffffffff);
+ sh_cmt_write(p, CMCNT, 0);
+
+ /* enable channel */
+ sh_cmt_start_stop_ch(p, 1);
+ return 0;
+}
+
+static void sh_cmt_disable(struct sh_cmt_priv *p)
+{
+ /* disable channel */
+ sh_cmt_start_stop_ch(p, 0);
+
+ /* stop clock */
+ clk_disable(p->clk);
+}
+
+/* private flags */
+#define FLAG_CLOCKEVENT (1 << 0)
+#define FLAG_CLOCKSOURCE (1 << 1)
+#define FLAG_REPROGRAM (1 << 2)
+#define FLAG_SKIPEVENT (1 << 3)
+#define FLAG_IRQCONTEXT (1 << 4)
+
+static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
+ int absolute)
+{
+ unsigned long new_match;
+ unsigned long value = p->next_match_value;
+ unsigned long delay = 0;
+ unsigned long now = 0;
+ int has_wrapped;
+
+ now = sh_cmt_get_counter(p, &has_wrapped);
+ p->flags |= FLAG_REPROGRAM; /* force reprogram */
+
+ if (has_wrapped) {
+ /* we're competing with the interrupt handler.
+ * -> let the interrupt handler reprogram the timer.
+ * -> interrupt number two handles the event.
+ */
+ p->flags |= FLAG_SKIPEVENT;
+ return;
+ }
+
+ if (absolute)
+ now = 0;
+
+ do {
+ /* reprogram the timer hardware,
+ * but don't save the new match value yet.
+ */
+ new_match = now + value + delay;
+ if (new_match > p->max_match_value)
+ new_match = p->max_match_value;
+
+ sh_cmt_write(p, CMCOR, new_match);
+
+ now = sh_cmt_get_counter(p, &has_wrapped);
+ if (has_wrapped && (new_match > p->match_value)) {
+ /* we are changing to a greater match value,
+ * so this wrap must be caused by the counter
+ * matching the old value.
+ * -> first interrupt reprograms the timer.
+ * -> interrupt number two handles the event.
+ */
+ p->flags |= FLAG_SKIPEVENT;
+ break;
+ }
+
+ if (has_wrapped) {
+ /* we are changing to a smaller match value,
+ * so the wrap must be caused by the counter
+ * matching the new value.
+ * -> save programmed match value.
+ * -> let isr handle the event.
+ */
+ p->match_value = new_match;
+ break;
+ }
+
+ /* be safe: verify hardware settings */
+ if (now < new_match) {
+ /* timer value is below match value, all good.
+ * this makes sure we won't miss any match events.
+ * -> save programmed match value.
+ * -> let isr handle the event.
+ */
+ p->match_value = new_match;
+ break;
+ }
+
+ /* the counter has reached a value greater
+ * than our new match value. and since the
+ * has_wrapped flag isn't set we must have
+ * programmed a too close event.
+ * -> increase delay and retry.
+ */
+ if (delay)
+ delay <<= 1;
+ else
+ delay = 1;
+
+ if (!delay)
+ pr_warning("sh_cmt: too long delay\n");
+
+ } while (delay);
+}
+
+static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+{
+ unsigned long flags;
+
+ if (delta > p->max_match_value)
+ pr_warning("sh_cmt: delta out of range\n");
+
+ spin_lock_irqsave(&p->lock, flags);
+ p->next_match_value = delta;
+ sh_cmt_clock_event_program_verify(p, 0);
+ spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
+{
+ struct sh_cmt_priv *p = dev_id;
+
+ /* clear flags */
+ sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
+
+ /* update clock source counter to begin with if enabled
+ * the wrap flag should be cleared by the timer specific
+ * isr before we end up here.
+ */
+ if (p->flags & FLAG_CLOCKSOURCE)
+ p->total_cycles += p->match_value;
+
+ if (!(p->flags & FLAG_REPROGRAM))
+ p->next_match_value = p->max_match_value;
+
+ p->flags |= FLAG_IRQCONTEXT;
+
+ if (p->flags & FLAG_CLOCKEVENT) {
+ if (!(p->flags & FLAG_SKIPEVENT)) {
+ if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
+ p->next_match_value = p->max_match_value;
+ p->flags |= FLAG_REPROGRAM;
+ }
+
+ p->ced.event_handler(&p->ced);
+ }
+ }
+
+ p->flags &= ~FLAG_SKIPEVENT;
+
+ if (p->flags & FLAG_REPROGRAM) {
+ p->flags &= ~FLAG_REPROGRAM;
+ sh_cmt_clock_event_program_verify(p, 1);
+
+ if (p->flags & FLAG_CLOCKEVENT)
+ if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
+ || (p->match_value == p->next_match_value))
+ p->flags &= ~FLAG_REPROGRAM;
+ }
+
+ p->flags &= ~FLAG_IRQCONTEXT;
+
+ return IRQ_HANDLED;
+}
+
+static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&p->lock, flags);
+
+ if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+ ret = sh_cmt_enable(p, &p->rate);
+
+ if (ret)
+ goto out;
+ p->flags |= flag;
+
+ /* setup timeout if no clockevent */
+ if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
+ sh_cmt_set_next(p, p->max_match_value);
+ out:
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ return ret;
+}
+
+static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
+{
+ unsigned long flags;
+ unsigned long f;
+
+ spin_lock_irqsave(&p->lock, flags);
+
+ f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
+ p->flags &= ~flag;
+
+ if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+ sh_cmt_disable(p);
+
+ /* adjust the timeout to maximum if only clocksource left */
+ if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
+ sh_cmt_set_next(p, p->max_match_value);
+
+ spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
+{
+ return container_of(ced, struct sh_cmt_priv, ced);
+}
+
+static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
+{
+ struct clock_event_device *ced = &p->ced;
+
+ sh_cmt_start(p, FLAG_CLOCKEVENT);
+
+ /* TODO: calculate good shift from rate and counter bit width */
+
+ ced->shift = 32;
+ ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
+ ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
+ ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
+
+ if (periodic)
+ sh_cmt_set_next(p, (p->rate + HZ/2) / HZ);
+ else
+ sh_cmt_set_next(p, p->max_match_value);
+}
+
+static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
+ struct clock_event_device *ced)
+{
+ struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+ /* deal with old setting first */
+ switch (ced->mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_ONESHOT:
+ sh_cmt_stop(p, FLAG_CLOCKEVENT);
+ break;
+ default:
+ break;
+ }
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_info("sh_cmt: %s used for periodic clock events\n",
+ ced->name);
+ sh_cmt_clock_event_start(p, 1);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ pr_info("sh_cmt: %s used for oneshot clock events\n",
+ ced->name);
+ sh_cmt_clock_event_start(p, 0);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ sh_cmt_stop(p, FLAG_CLOCKEVENT);
+ break;
+ default:
+ break;
+ }
+}
+
+static int sh_cmt_clock_event_next(unsigned long delta,
+ struct clock_event_device *ced)
+{
+ struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+ BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
+ if (likely(p->flags & FLAG_IRQCONTEXT))
+ p->next_match_value = delta;
+ else
+ sh_cmt_set_next(p, delta);
+
+ return 0;
+}
+
+static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
+ char *name, unsigned long rating)
+{
+ struct clock_event_device *ced = &p->ced;
+
+ memset(ced, 0, sizeof(*ced));
+
+ ced->name = name;
+ ced->features = CLOCK_EVT_FEAT_PERIODIC;
+ ced->features |= CLOCK_EVT_FEAT_ONESHOT;
+ ced->rating = rating;
+ ced->cpumask = cpumask_of(0);
+ ced->set_next_event = sh_cmt_clock_event_next;
+ ced->set_mode = sh_cmt_clock_event_mode;
+
+ pr_info("sh_cmt: %s used for clock events\n", ced->name);
+ ced->mult = 1; /* work around misplaced WARN_ON() in clockevents.c */
+ clockevents_register_device(ced);
+}
+
+int sh_cmt_register(struct sh_cmt_priv *p, char *name,
+ unsigned long clockevent_rating,
+ unsigned long clocksource_rating)
+{
+ if (p->width == (sizeof(p->max_match_value) * 8))
+ p->max_match_value = ~0;
+ else
+ p->max_match_value = (1 << p->width) - 1;
+
+ p->match_value = p->max_match_value;
+ spin_lock_init(&p->lock);
+
+ if (clockevent_rating)
+ sh_cmt_register_clockevent(p, name, clockevent_rating);
+
+ return 0;
+}
+
+static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+{
+ struct sh_cmt_config *cfg = pdev->dev.platform_data;
+ struct resource *res;
+ int irq, ret;
+ ret = -ENXIO;
+
+ memset(p, 0, sizeof(*p));
+ p->pdev = pdev;
+
+ if (!cfg) {
+ dev_err(&p->pdev->dev, "missing platform data\n");
+ goto err0;
+ }
+
+ platform_set_drvdata(pdev, p);
+
+ res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+ goto err0;
+ }
+
+ irq = platform_get_irq(p->pdev, 0);
+ if (irq < 0) {
+ dev_err(&p->pdev->dev, "failed to get irq\n");
+ goto err0;
+ }
+
+ /* map memory, let mapbase point to our channel */
+ p->mapbase = ioremap_nocache(res->start, resource_size(res));
+ if (p->mapbase == NULL) {
+ pr_err("sh_cmt: failed to remap I/O memory\n");
+ goto err0;
+ }
+
+ /* request irq using setup_irq() (too early for request_irq()) */
+ p->irqaction.name = cfg->name;
+ p->irqaction.handler = sh_cmt_interrupt;
+ p->irqaction.dev_id = p;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+ p->irqaction.mask = CPU_MASK_NONE;
+ ret = setup_irq(irq, &p->irqaction);
+ if (ret) {
+ pr_err("sh_cmt: failed to request irq %d\n", irq);
+ goto err1;
+ }
+
+ /* get hold of clock */
+ p->clk = clk_get(&p->pdev->dev, cfg->clk);
+ if (IS_ERR(p->clk)) {
+ pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk);
+ ret = PTR_ERR(p->clk);
+ goto err2;
+ }
+
+ if (resource_size(res) == 6) {
+ p->width = 16;
+ p->overflow_bit = 0x80;
+ p->clear_bits = ~0xc0;
+ } else {
+ p->width = 32;
+ p->overflow_bit = 0x8000;
+ p->clear_bits = ~0xc000;
+ }
+
+ return sh_cmt_register(p, cfg->name,
+ cfg->clockevent_rating,
+ cfg->clocksource_rating);
+ err2:
+ free_irq(irq, p);
+ err1:
+ iounmap(p->mapbase);
+ err0:
+ return ret;
+}
+
+static int __devinit sh_cmt_probe(struct platform_device *pdev)
+{
+ struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+ int ret;
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(&pdev->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ ret = sh_cmt_setup(p, pdev);
+ if (ret) {
+ kfree(p);
+
+ platform_set_drvdata(pdev, NULL);
+ }
+ return ret;
+}
+
+static int __devexit sh_cmt_remove(struct platform_device *pdev)
+{
+ return -EBUSY; /* cannot unregister clockevent and clocksource */
+}
+
+static struct platform_driver sh_cmt_device_driver = {
+ .probe = sh_cmt_probe,
+ .remove = __devexit_p(sh_cmt_remove),
+ .driver = {
+ .name = "sh_cmt",
+ }
+};
+
+static int __init sh_cmt_init(void)
+{
+ return platform_driver_register(&sh_cmt_device_driver);
+}
+
+static void __exit sh_cmt_exit(void)
+{
+ platform_driver_unregister(&sh_cmt_device_driver);
+}
+
+module_init(sh_cmt_init);
+module_exit(sh_cmt_exit);
+
+MODULE_AUTHOR("Magnus Damm");
+MODULE_DESCRIPTION("SuperH CMT Timer Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index b6fe7e7a2c2..c769ef269fb 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -1,9 +1,9 @@
/*
* cn_queue.c
- *
+ *
* 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
* All rights reserved.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -31,6 +31,48 @@
#include <linux/connector.h>
#include <linux/delay.h>
+
+/*
+ * This job is sent to the kevent workqueue.
+ * While no event is once sent to any callback, the connector workqueue
+ * is not created to avoid a useless waiting kernel task.
+ * Once the first event is received, we create this dedicated workqueue which
+ * is necessary because the flow of data can be high and we don't want
+ * to encumber keventd with that.
+ */
+static void cn_queue_create(struct work_struct *work)
+{
+ struct cn_queue_dev *dev;
+
+ dev = container_of(work, struct cn_queue_dev, wq_creation);
+
+ dev->cn_queue = create_singlethread_workqueue(dev->name);
+ /* If we fail, we will use keventd for all following connector jobs */
+ WARN_ON(!dev->cn_queue);
+}
+
+/*
+ * Queue a data sent to a callback.
+ * If the connector workqueue is already created, we queue the job on it.
+ * Otherwise, we queue the job to kevent and queue the connector workqueue
+ * creation too.
+ */
+int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work)
+{
+ struct cn_queue_dev *pdev = cbq->pdev;
+
+ if (likely(pdev->cn_queue))
+ return queue_work(pdev->cn_queue, work);
+
+ /* Don't create the connector workqueue twice */
+ if (atomic_inc_return(&pdev->wq_requested) == 1)
+ schedule_work(&pdev->wq_creation);
+ else
+ atomic_dec(&pdev->wq_requested);
+
+ return schedule_work(work);
+}
+
void cn_queue_wrapper(struct work_struct *work)
{
struct cn_callback_entry *cbq =
@@ -58,14 +100,17 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc
snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
memcpy(&cbq->id.id, id, sizeof(struct cb_id));
cbq->data.callback = callback;
-
+
INIT_WORK(&cbq->work, &cn_queue_wrapper);
return cbq;
}
static void cn_queue_free_callback(struct cn_callback_entry *cbq)
{
- flush_workqueue(cbq->pdev->cn_queue);
+ /* The first jobs have been sent to kevent, flush them too */
+ flush_scheduled_work();
+ if (cbq->pdev->cn_queue)
+ flush_workqueue(cbq->pdev->cn_queue);
kfree(cbq);
}
@@ -143,14 +188,11 @@ struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
atomic_set(&dev->refcnt, 0);
INIT_LIST_HEAD(&dev->queue_list);
spin_lock_init(&dev->queue_lock);
+ init_waitqueue_head(&dev->wq_created);
dev->nls = nls;
- dev->cn_queue = create_singlethread_workqueue(dev->name);
- if (!dev->cn_queue) {
- kfree(dev);
- return NULL;
- }
+ INIT_WORK(&dev->wq_creation, cn_queue_create);
return dev;
}
@@ -158,9 +200,25 @@ struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
void cn_queue_free_dev(struct cn_queue_dev *dev)
{
struct cn_callback_entry *cbq, *n;
+ long timeout;
+ DEFINE_WAIT(wait);
+
+ /* Flush the first pending jobs queued on kevent */
+ flush_scheduled_work();
+
+ /* If the connector workqueue creation is still pending, wait for it */
+ prepare_to_wait(&dev->wq_created, &wait, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&dev->wq_requested) && !dev->cn_queue) {
+ timeout = schedule_timeout(HZ * 2);
+ if (!timeout && !dev->cn_queue)
+ WARN_ON(1);
+ }
+ finish_wait(&dev->wq_created, &wait);
- flush_workqueue(dev->cn_queue);
- destroy_workqueue(dev->cn_queue);
+ if (dev->cn_queue) {
+ flush_workqueue(dev->cn_queue);
+ destroy_workqueue(dev->cn_queue);
+ }
spin_lock_bh(&dev->queue_lock);
list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index bf4830082a1..fd336c5a905 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -1,9 +1,9 @@
/*
* connector.c
- *
+ *
* 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
* All rights reserved.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -145,14 +145,13 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
__cbq->data.ddata = data;
__cbq->data.destruct_data = destruct_data;
- if (queue_work(dev->cbdev->cn_queue,
- &__cbq->work))
+ if (queue_cn_work(__cbq, &__cbq->work))
err = 0;
else
err = -EINVAL;
} else {
struct cn_callback_data *d;
-
+
err = -ENOMEM;
__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
if (__new_cbq) {
@@ -163,10 +162,12 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
d->destruct_data = destruct_data;
d->free = __new_cbq;
+ __new_cbq->pdev = __cbq->pdev;
+
INIT_WORK(&__new_cbq->work,
&cn_queue_wrapper);
- if (queue_work(dev->cbdev->cn_queue,
+ if (queue_cn_work(__new_cbq,
&__new_cbq->work))
err = 0;
else {
@@ -237,7 +238,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
req = (struct cn_notify_req *)ctl->data;
for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
- if (id->idx >= req->first &&
+ if (id->idx >= req->first &&
id->idx < req->first + req->range) {
idx_found = 1;
break;
@@ -245,7 +246,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
}
for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
- if (id->val >= req->first &&
+ if (id->val >= req->first &&
id->val < req->first + req->range) {
val_found = 1;
break;
@@ -459,7 +460,7 @@ static int __devinit cn_init(void)
netlink_kernel_release(dev->nls);
return -EINVAL;
}
-
+
cn_already_initialized = 1;
err = cn_add_callback(&dev->id, "connector", &cn_callback);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b55cb67435b..d270e8eb3e6 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -104,7 +104,8 @@ EXPORT_SYMBOL_GPL(unlock_policy_rwsem_write);
/* internal prototypes */
-static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
+static int __cpufreq_governor(struct cpufreq_policy *policy,
+ unsigned int event);
static unsigned int __cpufreq_get(unsigned int cpu);
static void handle_update(struct work_struct *work);
@@ -128,7 +129,7 @@ static int __init init_cpufreq_transition_notifier_list(void)
pure_initcall(init_cpufreq_transition_notifier_list);
static LIST_HEAD(cpufreq_governor_list);
-static DEFINE_MUTEX (cpufreq_governor_mutex);
+static DEFINE_MUTEX(cpufreq_governor_mutex);
struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
{
@@ -371,7 +372,7 @@ static struct cpufreq_governor *__find_governor(const char *str_governor)
struct cpufreq_governor *t;
list_for_each_entry(t, &cpufreq_governor_list, governor_list)
- if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN))
+ if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
return t;
return NULL;
@@ -429,15 +430,11 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
mutex_unlock(&cpufreq_governor_mutex);
}
- out:
+out:
return err;
}
-/* drivers/base/cpu.c */
-extern struct sysdev_class cpu_sysdev_class;
-
-
/**
* cpufreq_per_cpu_attr_read() / show_##file_name() -
* print out cpufreq information
@@ -450,11 +447,12 @@ extern struct sysdev_class cpu_sysdev_class;
static ssize_t show_##file_name \
(struct cpufreq_policy *policy, char *buf) \
{ \
- return sprintf (buf, "%u\n", policy->object); \
+ return sprintf(buf, "%u\n", policy->object); \
}
show_one(cpuinfo_min_freq, cpuinfo.min_freq);
show_one(cpuinfo_max_freq, cpuinfo.max_freq);
+show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
show_one(scaling_min_freq, min);
show_one(scaling_max_freq, max);
show_one(scaling_cur_freq, cur);
@@ -476,7 +474,7 @@ static ssize_t store_##file_name \
if (ret) \
return -EINVAL; \
\
- ret = sscanf (buf, "%u", &new_policy.object); \
+ ret = sscanf(buf, "%u", &new_policy.object); \
if (ret != 1) \
return -EINVAL; \
\
@@ -486,8 +484,8 @@ static ssize_t store_##file_name \
return ret ? ret : count; \
}
-store_one(scaling_min_freq,min);
-store_one(scaling_max_freq,max);
+store_one(scaling_min_freq, min);
+store_one(scaling_max_freq, max);
/**
* show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
@@ -507,12 +505,13 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
*/
static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
{
- if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
+ if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
return sprintf(buf, "powersave\n");
else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
return sprintf(buf, "performance\n");
else if (policy->governor)
- return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name);
+ return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n",
+ policy->governor->name);
return -EINVAL;
}
@@ -531,7 +530,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
if (ret)
return ret;
- ret = sscanf (buf, "%15s", str_governor);
+ ret = sscanf(buf, "%15s", str_governor);
if (ret != 1)
return -EINVAL;
@@ -575,7 +574,8 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
}
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
- if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
+ if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
+ - (CPUFREQ_NAME_LEN + 2)))
goto out;
i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
}
@@ -594,7 +594,7 @@ static ssize_t show_cpus(const struct cpumask *mask, char *buf)
i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
if (i >= (PAGE_SIZE - 5))
- break;
+ break;
}
i += sprintf(&buf[i], "\n");
return i;
@@ -660,6 +660,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
define_one_ro0400(cpuinfo_cur_freq);
define_one_ro(cpuinfo_min_freq);
define_one_ro(cpuinfo_max_freq);
+define_one_ro(cpuinfo_transition_latency);
define_one_ro(scaling_available_governors);
define_one_ro(scaling_driver);
define_one_ro(scaling_cur_freq);
@@ -673,6 +674,7 @@ define_one_rw(scaling_setspeed);
static struct attribute *default_attrs[] = {
&cpuinfo_min_freq.attr,
&cpuinfo_max_freq.attr,
+ &cpuinfo_transition_latency.attr,
&scaling_min_freq.attr,
&scaling_max_freq.attr,
&affected_cpus.attr,
@@ -684,10 +686,10 @@ static struct attribute *default_attrs[] = {
NULL
};
-#define to_policy(k) container_of(k,struct cpufreq_policy,kobj)
-#define to_attr(a) container_of(a,struct freq_attr,attr)
+#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
+#define to_attr(a) container_of(a, struct freq_attr, attr)
-static ssize_t show(struct kobject *kobj, struct attribute *attr ,char *buf)
+static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct cpufreq_policy *policy = to_policy(kobj);
struct freq_attr *fattr = to_attr(attr);
@@ -754,11 +756,6 @@ static struct kobj_type ktype_cpufreq = {
.release = cpufreq_sysfs_release,
};
-static struct kobj_type ktype_empty_cpufreq = {
- .sysfs_ops = &sysfs_ops,
- .release = cpufreq_sysfs_release,
-};
-
/**
* cpufreq_add_dev - add a CPU device
@@ -858,10 +855,10 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
if (cpu == j)
continue;
- /* check for existing affected CPUs. They may not be aware
- * of it due to CPU Hotplug.
+ /* Check for existing affected CPUs.
+ * They may not be aware of it due to CPU Hotplug.
*/
- managed_policy = cpufreq_cpu_get(j); // FIXME: Where is this released? What about error paths?
+ managed_policy = cpufreq_cpu_get(j); /* FIXME: Where is this released? What about error paths? */
if (unlikely(managed_policy)) {
/* Set proper policy_cpu */
@@ -892,36 +889,26 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
/* prepare interface data */
- if (!cpufreq_driver->hide_interface) {
- ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
- &sys_dev->kobj, "cpufreq");
+ ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
+ "cpufreq");
+ if (ret)
+ goto err_out_driver_exit;
+
+ /* set up files for this cpu device */
+ drv_attr = cpufreq_driver->attr;
+ while ((drv_attr) && (*drv_attr)) {
+ ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
if (ret)
goto err_out_driver_exit;
-
- /* set up files for this cpu device */
- drv_attr = cpufreq_driver->attr;
- while ((drv_attr) && (*drv_attr)) {
- ret = sysfs_create_file(&policy->kobj,
- &((*drv_attr)->attr));
- if (ret)
- goto err_out_driver_exit;
- drv_attr++;
- }
- if (cpufreq_driver->get) {
- ret = sysfs_create_file(&policy->kobj,
- &cpuinfo_cur_freq.attr);
- if (ret)
- goto err_out_driver_exit;
- }
- if (cpufreq_driver->target) {
- ret = sysfs_create_file(&policy->kobj,
- &scaling_cur_freq.attr);
- if (ret)
- goto err_out_driver_exit;
- }
- } else {
- ret = kobject_init_and_add(&policy->kobj, &ktype_empty_cpufreq,
- &sys_dev->kobj, "cpufreq");
+ drv_attr++;
+ }
+ if (cpufreq_driver->get) {
+ ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
+ if (ret)
+ goto err_out_driver_exit;
+ }
+ if (cpufreq_driver->target) {
+ ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
if (ret)
goto err_out_driver_exit;
}
@@ -1142,8 +1129,8 @@ static void handle_update(struct work_struct *work)
* @old_freq: CPU frequency the kernel thinks the CPU runs at
* @new_freq: CPU frequency the CPU actually runs at
*
- * We adjust to current frequency first, and need to clean up later. So either call
- * to cpufreq_update_policy() or schedule handle_update()).
+ * We adjust to current frequency first, and need to clean up later.
+ * So either call to cpufreq_update_policy() or schedule handle_update()).
*/
static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
unsigned int new_freq)
@@ -1625,7 +1612,8 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
/**
* cpufreq_get_policy - get the current cpufreq_policy
- * @policy: struct cpufreq_policy into which the current cpufreq_policy is written
+ * @policy: struct cpufreq_policy into which the current cpufreq_policy
+ * is written
*
* Reads the current cpufreq policy.
*/
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 0320962c4ec..2ecd95e4ab1 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -4,7 +4,7 @@
* Copyright (C) 2001 Russell King
* (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
* Jun Nakajima <jun.nakajima@intel.com>
- * (C) 2004 Alexander Clouter <alex-kernel@digriz.org.uk>
+ * (C) 2009 Alexander Clouter <alex@digriz.org.uk>
*
* 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
@@ -13,22 +13,17 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/smp.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ctype.h>
#include <linux/cpufreq.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/sysfs.h>
#include <linux/cpu.h>
-#include <linux/kmod.h>
-#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <linux/kernel_stat.h>
-#include <linux/percpu.h>
#include <linux/mutex.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <linux/ktime.h>
+#include <linux/sched.h>
+
/*
* dbs is used in this file as a shortform for demandbased switching
* It helps to keep variable names smaller, simpler
@@ -43,19 +38,31 @@
* latency of the processor. The governor will work on any processor with
* transition latency <= 10mS, using appropriate sampling
* rate.
- * For CPUs with transition latency > 10mS (mostly drivers
- * with CPUFREQ_ETERNAL), this governor will not work.
+ * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
+ * this governor will not work.
* All times here are in uS.
*/
static unsigned int def_sampling_rate;
#define MIN_SAMPLING_RATE_RATIO (2)
/* for correct statistics, we need at least 10 ticks between each measure */
-#define MIN_STAT_SAMPLING_RATE \
+#define MIN_STAT_SAMPLING_RATE \
(MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
#define MIN_SAMPLING_RATE \
(def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
+/* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon
+ * Define the minimal settable sampling rate to the greater of:
+ * - "HW transition latency" * 100 (same as default sampling / 10)
+ * - MIN_STAT_SAMPLING_RATE
+ * To avoid that userspace shoots itself.
+*/
+static unsigned int minimum_sampling_rate(void)
+{
+ return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE);
+}
+
+/* This will also vanish soon with removing sampling_rate_max */
#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
-#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
+#define LATENCY_MULTIPLIER (1000)
#define DEF_SAMPLING_DOWN_FACTOR (1)
#define MAX_SAMPLING_DOWN_FACTOR (10)
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
@@ -63,12 +70,15 @@ static unsigned int def_sampling_rate;
static void do_dbs_timer(struct work_struct *work);
struct cpu_dbs_info_s {
+ cputime64_t prev_cpu_idle;
+ cputime64_t prev_cpu_wall;
+ cputime64_t prev_cpu_nice;
struct cpufreq_policy *cur_policy;
- unsigned int prev_cpu_idle_up;
- unsigned int prev_cpu_idle_down;
- unsigned int enable;
+ struct delayed_work work;
unsigned int down_skip;
unsigned int requested_freq;
+ int cpu;
+ unsigned int enable:1;
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
@@ -82,19 +92,18 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */
* cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
* is recursive for the same process. -Venki
*/
-static DEFINE_MUTEX (dbs_mutex);
-static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer);
+static DEFINE_MUTEX(dbs_mutex);
-struct dbs_tuners {
+static struct workqueue_struct *kconservative_wq;
+
+static struct dbs_tuners {
unsigned int sampling_rate;
unsigned int sampling_down_factor;
unsigned int up_threshold;
unsigned int down_threshold;
unsigned int ignore_nice;
unsigned int freq_step;
-};
-
-static struct dbs_tuners dbs_tuners_ins = {
+} dbs_tuners_ins = {
.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
.down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD,
.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
@@ -102,18 +111,37 @@ static struct dbs_tuners dbs_tuners_ins = {
.freq_step = 5,
};
-static inline unsigned int get_cpu_idle_time(unsigned int cpu)
+static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
+ cputime64_t *wall)
{
- unsigned int add_nice = 0, ret;
+ cputime64_t idle_time;
+ cputime64_t cur_wall_time;
+ cputime64_t busy_time;
- if (dbs_tuners_ins.ignore_nice)
- add_nice = kstat_cpu(cpu).cpustat.nice;
+ cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
+ busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user,
+ kstat_cpu(cpu).cpustat.system);
+
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq);
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq);
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal);
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.nice);
+
+ idle_time = cputime64_sub(cur_wall_time, busy_time);
+ if (wall)
+ *wall = cur_wall_time;
+
+ return idle_time;
+}
+
+static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
+{
+ u64 idle_time = get_cpu_idle_time_us(cpu, wall);
- ret = kstat_cpu(cpu).cpustat.idle +
- kstat_cpu(cpu).cpustat.iowait +
- add_nice;
+ if (idle_time == -1ULL)
+ return get_cpu_idle_time_jiffy(cpu, wall);
- return ret;
+ return idle_time;
}
/* keep track of frequency transitions */
@@ -125,10 +153,21 @@ dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info,
freq->cpu);
+ struct cpufreq_policy *policy;
+
if (!this_dbs_info->enable)
return 0;
- this_dbs_info->requested_freq = freq->new;
+ policy = this_dbs_info->cur_policy;
+
+ /*
+ * we only care if our internally tracked freq moves outside
+ * the 'valid' ranges of freqency available to us otherwise
+ * we do not change it
+ */
+ if (this_dbs_info->requested_freq > policy->max
+ || this_dbs_info->requested_freq < policy->min)
+ this_dbs_info->requested_freq = freq->new;
return 0;
}
@@ -140,16 +179,31 @@ static struct notifier_block dbs_cpufreq_notifier_block = {
/************************** sysfs interface ************************/
static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
{
- return sprintf (buf, "%u\n", MAX_SAMPLING_RATE);
+ static int print_once;
+
+ if (!print_once) {
+ printk(KERN_INFO "CPUFREQ: conservative sampling_rate_max "
+ "sysfs file is deprecated - used by: %s\n",
+ current->comm);
+ print_once = 1;
+ }
+ return sprintf(buf, "%u\n", MAX_SAMPLING_RATE);
}
static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
{
- return sprintf (buf, "%u\n", MIN_SAMPLING_RATE);
+ static int print_once;
+
+ if (!print_once) {
+ printk(KERN_INFO "CPUFREQ: conservative sampling_rate_max "
+ "sysfs file is deprecated - used by: %s\n", current->comm);
+ print_once = 1;
+ }
+ return sprintf(buf, "%u\n", MIN_SAMPLING_RATE);
}
-#define define_one_ro(_name) \
-static struct freq_attr _name = \
+#define define_one_ro(_name) \
+static struct freq_attr _name = \
__ATTR(_name, 0444, show_##_name, NULL)
define_one_ro(sampling_rate_max);
@@ -174,7 +228,8 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
{
unsigned int input;
int ret;
- ret = sscanf (buf, "%u", &input);
+ ret = sscanf(buf, "%u", &input);
+
if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
return -EINVAL;
@@ -190,15 +245,13 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
{
unsigned int input;
int ret;
- ret = sscanf (buf, "%u", &input);
+ ret = sscanf(buf, "%u", &input);
- mutex_lock(&dbs_mutex);
- if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
- mutex_unlock(&dbs_mutex);
+ if (ret != 1)
return -EINVAL;
- }
- dbs_tuners_ins.sampling_rate = input;
+ mutex_lock(&dbs_mutex);
+ dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate());
mutex_unlock(&dbs_mutex);
return count;
@@ -209,10 +262,11 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
{
unsigned int input;
int ret;
- ret = sscanf (buf, "%u", &input);
+ ret = sscanf(buf, "%u", &input);
mutex_lock(&dbs_mutex);
- if (ret != 1 || input > 100 || input <= dbs_tuners_ins.down_threshold) {
+ if (ret != 1 || input > 100 ||
+ input <= dbs_tuners_ins.down_threshold) {
mutex_unlock(&dbs_mutex);
return -EINVAL;
}
@@ -228,10 +282,12 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused,
{
unsigned int input;
int ret;
- ret = sscanf (buf, "%u", &input);
+ ret = sscanf(buf, "%u", &input);
mutex_lock(&dbs_mutex);
- if (ret != 1 || input > 100 || input >= dbs_tuners_ins.up_threshold) {
+ /* cannot be lower than 11 otherwise freq will not fall */
+ if (ret != 1 || input < 11 || input > 100 ||
+ input >= dbs_tuners_ins.up_threshold) {
mutex_unlock(&dbs_mutex);
return -EINVAL;
}
@@ -264,12 +320,14 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
}
dbs_tuners_ins.ignore_nice = input;
- /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */
+ /* we need to re-evaluate prev_cpu_idle */
for_each_online_cpu(j) {
- struct cpu_dbs_info_s *j_dbs_info;
- j_dbs_info = &per_cpu(cpu_dbs_info, j);
- j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
- j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
+ struct cpu_dbs_info_s *dbs_info;
+ dbs_info = &per_cpu(cpu_dbs_info, j);
+ dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
+ &dbs_info->prev_cpu_wall);
+ if (dbs_tuners_ins.ignore_nice)
+ dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
}
mutex_unlock(&dbs_mutex);
@@ -281,7 +339,6 @@ static ssize_t store_freq_step(struct cpufreq_policy *policy,
{
unsigned int input;
int ret;
-
ret = sscanf(buf, "%u", &input);
if (ret != 1)
@@ -310,7 +367,7 @@ define_one_rw(down_threshold);
define_one_rw(ignore_nice_load);
define_one_rw(freq_step);
-static struct attribute * dbs_attributes[] = {
+static struct attribute *dbs_attributes[] = {
&sampling_rate_max.attr,
&sampling_rate_min.attr,
&sampling_rate.attr,
@@ -329,55 +386,78 @@ static struct attribute_group dbs_attr_group = {
/************************** sysfs end ************************/
-static void dbs_check_cpu(int cpu)
+static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
{
- unsigned int idle_ticks, up_idle_ticks, down_idle_ticks;
- unsigned int tmp_idle_ticks, total_idle_ticks;
+ unsigned int load = 0;
unsigned int freq_target;
- unsigned int freq_down_sampling_rate;
- struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
- struct cpufreq_policy *policy;
- if (!this_dbs_info->enable)
- return;
+ struct cpufreq_policy *policy;
+ unsigned int j;
policy = this_dbs_info->cur_policy;
/*
- * The default safe range is 20% to 80%
- * Every sampling_rate, we check
- * - If current idle time is less than 20%, then we try to
- * increase frequency
- * Every sampling_rate*sampling_down_factor, we check
- * - If current idle time is more than 80%, then we try to
- * decrease frequency
+ * Every sampling_rate, we check, if current idle time is less
+ * than 20% (default), then we try to increase frequency
+ * Every sampling_rate*sampling_down_factor, we check, if current
+ * idle time is more than 80%, then we try to decrease frequency
*
* Any frequency increase takes it to the maximum frequency.
* Frequency reduction happens at minimum steps of
- * 5% (default) of max_frequency
+ * 5% (default) of maximum frequency
*/
- /* Check for frequency increase */
- idle_ticks = UINT_MAX;
+ /* Get Absolute Load */
+ for_each_cpu(j, policy->cpus) {
+ struct cpu_dbs_info_s *j_dbs_info;
+ cputime64_t cur_wall_time, cur_idle_time;
+ unsigned int idle_time, wall_time;
- /* Check for frequency increase */
- total_idle_ticks = get_cpu_idle_time(cpu);
- tmp_idle_ticks = total_idle_ticks -
- this_dbs_info->prev_cpu_idle_up;
- this_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+ j_dbs_info = &per_cpu(cpu_dbs_info, j);
+
+ cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
+
+ wall_time = (unsigned int) cputime64_sub(cur_wall_time,
+ j_dbs_info->prev_cpu_wall);
+ j_dbs_info->prev_cpu_wall = cur_wall_time;
+
+ idle_time = (unsigned int) cputime64_sub(cur_idle_time,
+ j_dbs_info->prev_cpu_idle);
+ j_dbs_info->prev_cpu_idle = cur_idle_time;
+
+ if (dbs_tuners_ins.ignore_nice) {
+ cputime64_t cur_nice;
+ unsigned long cur_nice_jiffies;
+
+ cur_nice = cputime64_sub(kstat_cpu(j).cpustat.nice,
+ j_dbs_info->prev_cpu_nice);
+ /*
+ * Assumption: nice time between sampling periods will
+ * be less than 2^32 jiffies for 32 bit sys
+ */
+ cur_nice_jiffies = (unsigned long)
+ cputime64_to_jiffies64(cur_nice);
- if (tmp_idle_ticks < idle_ticks)
- idle_ticks = tmp_idle_ticks;
+ j_dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
+ idle_time += jiffies_to_usecs(cur_nice_jiffies);
+ }
+
+ if (unlikely(!wall_time || wall_time < idle_time))
+ continue;
+
+ load = 100 * (wall_time - idle_time) / wall_time;
+ }
- /* Scale idle ticks by 100 and compare with up and down ticks */
- idle_ticks *= 100;
- up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
- usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+ /*
+ * break out if we 'cannot' reduce the speed as the user might
+ * want freq_step to be zero
+ */
+ if (dbs_tuners_ins.freq_step == 0)
+ return;
- if (idle_ticks < up_idle_ticks) {
+ /* Check for frequency increase */
+ if (load > dbs_tuners_ins.up_threshold) {
this_dbs_info->down_skip = 0;
- this_dbs_info->prev_cpu_idle_down =
- this_dbs_info->prev_cpu_idle_up;
/* if we are already at full speed then break out early */
if (this_dbs_info->requested_freq == policy->max)
@@ -398,49 +478,24 @@ static void dbs_check_cpu(int cpu)
return;
}
- /* Check for frequency decrease */
- this_dbs_info->down_skip++;
- if (this_dbs_info->down_skip < dbs_tuners_ins.sampling_down_factor)
- return;
-
- /* Check for frequency decrease */
- total_idle_ticks = this_dbs_info->prev_cpu_idle_up;
- tmp_idle_ticks = total_idle_ticks -
- this_dbs_info->prev_cpu_idle_down;
- this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
-
- if (tmp_idle_ticks < idle_ticks)
- idle_ticks = tmp_idle_ticks;
-
- /* Scale idle ticks by 100 and compare with up and down ticks */
- idle_ticks *= 100;
- this_dbs_info->down_skip = 0;
-
- freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
- dbs_tuners_ins.sampling_down_factor;
- down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
- usecs_to_jiffies(freq_down_sampling_rate);
-
- if (idle_ticks > down_idle_ticks) {
- /*
- * if we are already at the lowest speed then break out early
- * or if we 'cannot' reduce the speed as the user might want
- * freq_target to be zero
- */
- if (this_dbs_info->requested_freq == policy->min
- || dbs_tuners_ins.freq_step == 0)
- return;
-
+ /*
+ * The optimal frequency is the frequency that is the lowest that
+ * can support the current CPU usage without triggering the up
+ * policy. To be safe, we focus 10 points under the threshold.
+ */
+ if (load < (dbs_tuners_ins.down_threshold - 10)) {
freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
- /* max freq cannot be less than 100. But who knows.... */
- if (unlikely(freq_target == 0))
- freq_target = 5;
-
this_dbs_info->requested_freq -= freq_target;
if (this_dbs_info->requested_freq < policy->min)
this_dbs_info->requested_freq = policy->min;
+ /*
+ * if we cannot reduce the frequency anymore, break out early
+ */
+ if (policy->cur == policy->min)
+ return;
+
__cpufreq_driver_target(policy, this_dbs_info->requested_freq,
CPUFREQ_RELATION_H);
return;
@@ -449,27 +504,45 @@ static void dbs_check_cpu(int cpu)
static void do_dbs_timer(struct work_struct *work)
{
- int i;
- mutex_lock(&dbs_mutex);
- for_each_online_cpu(i)
- dbs_check_cpu(i);
- schedule_delayed_work(&dbs_work,
- usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
- mutex_unlock(&dbs_mutex);
+ struct cpu_dbs_info_s *dbs_info =
+ container_of(work, struct cpu_dbs_info_s, work.work);
+ unsigned int cpu = dbs_info->cpu;
+
+ /* We want all CPUs to do sampling nearly on same jiffy */
+ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+
+ delay -= jiffies % delay;
+
+ if (lock_policy_rwsem_write(cpu) < 0)
+ return;
+
+ if (!dbs_info->enable) {
+ unlock_policy_rwsem_write(cpu);
+ return;
+ }
+
+ dbs_check_cpu(dbs_info);
+
+ queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay);
+ unlock_policy_rwsem_write(cpu);
}
-static inline void dbs_timer_init(void)
+static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
{
- init_timer_deferrable(&dbs_work.timer);
- schedule_delayed_work(&dbs_work,
- usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
- return;
+ /* We want all CPUs to do sampling nearly on same jiffy */
+ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+ delay -= jiffies % delay;
+
+ dbs_info->enable = 1;
+ INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
+ queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work,
+ delay);
}
-static inline void dbs_timer_exit(void)
+static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
{
- cancel_delayed_work(&dbs_work);
- return;
+ dbs_info->enable = 0;
+ cancel_delayed_work(&dbs_info->work);
}
static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -503,11 +576,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
j_dbs_info = &per_cpu(cpu_dbs_info, j);
j_dbs_info->cur_policy = policy;
- j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(cpu);
- j_dbs_info->prev_cpu_idle_down
- = j_dbs_info->prev_cpu_idle_up;
+ j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
+ &j_dbs_info->prev_cpu_wall);
+ if (dbs_tuners_ins.ignore_nice) {
+ j_dbs_info->prev_cpu_nice =
+ kstat_cpu(j).cpustat.nice;
+ }
}
- this_dbs_info->enable = 1;
this_dbs_info->down_skip = 0;
this_dbs_info->requested_freq = policy->cur;
@@ -523,38 +598,36 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
if (latency == 0)
latency = 1;
- def_sampling_rate = 10 * latency *
- DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
-
- if (def_sampling_rate < MIN_STAT_SAMPLING_RATE)
- def_sampling_rate = MIN_STAT_SAMPLING_RATE;
+ def_sampling_rate =
+ max(latency * LATENCY_MULTIPLIER,
+ MIN_STAT_SAMPLING_RATE);
dbs_tuners_ins.sampling_rate = def_sampling_rate;
- dbs_timer_init();
cpufreq_register_notifier(
&dbs_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
}
+ dbs_timer_init(this_dbs_info);
mutex_unlock(&dbs_mutex);
+
break;
case CPUFREQ_GOV_STOP:
mutex_lock(&dbs_mutex);
- this_dbs_info->enable = 0;
+ dbs_timer_exit(this_dbs_info);
sysfs_remove_group(&policy->kobj, &dbs_attr_group);
dbs_enable--;
+
/*
* Stop the timerschedule work, when this governor
* is used for first time
*/
- if (dbs_enable == 0) {
- dbs_timer_exit();
+ if (dbs_enable == 0)
cpufreq_unregister_notifier(
&dbs_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
- }
mutex_unlock(&dbs_mutex);
@@ -571,6 +644,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L);
mutex_unlock(&dbs_mutex);
+
break;
}
return 0;
@@ -588,23 +662,33 @@ struct cpufreq_governor cpufreq_gov_conservative = {
static int __init cpufreq_gov_dbs_init(void)
{
- return cpufreq_register_governor(&cpufreq_gov_conservative);
+ int err;
+
+ kconservative_wq = create_workqueue("kconservative");
+ if (!kconservative_wq) {
+ printk(KERN_ERR "Creation of kconservative failed\n");
+ return -EFAULT;
+ }
+
+ err = cpufreq_register_governor(&cpufreq_gov_conservative);
+ if (err)
+ destroy_workqueue(kconservative_wq);
+
+ return err;
}
static void __exit cpufreq_gov_dbs_exit(void)
{
- /* Make sure that the scheduled work is indeed not running */
- flush_scheduled_work();
-
cpufreq_unregister_governor(&cpufreq_gov_conservative);
+ destroy_workqueue(kconservative_wq);
}
-MODULE_AUTHOR ("Alexander Clouter <alex-kernel@digriz.org.uk>");
-MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for "
+MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
+MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for "
"Low Latency Frequency Transition capable processors "
"optimised for use in a battery environment");
-MODULE_LICENSE ("GPL");
+MODULE_LICENSE("GPL");
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
fs_initcall(cpufreq_gov_dbs_init);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 6a2b036c938..338f428a15b 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -21,6 +21,7 @@
#include <linux/hrtimer.h>
#include <linux/tick.h>
#include <linux/ktime.h>
+#include <linux/sched.h>
/*
* dbs is used in this file as a shortform for demandbased switching
@@ -51,8 +52,20 @@ static unsigned int def_sampling_rate;
(MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
#define MIN_SAMPLING_RATE \
(def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
+/* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon
+ * Define the minimal settable sampling rate to the greater of:
+ * - "HW transition latency" * 100 (same as default sampling / 10)
+ * - MIN_STAT_SAMPLING_RATE
+ * To avoid that userspace shoots itself.
+*/
+static unsigned int minimum_sampling_rate(void)
+{
+ return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE);
+}
+
+/* This will also vanish soon with removing sampling_rate_max */
#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
-#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
+#define LATENCY_MULTIPLIER (1000)
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
static void do_dbs_timer(struct work_struct *work);
@@ -65,14 +78,14 @@ struct cpu_dbs_info_s {
cputime64_t prev_cpu_wall;
cputime64_t prev_cpu_nice;
struct cpufreq_policy *cur_policy;
- struct delayed_work work;
+ struct delayed_work work;
struct cpufreq_frequency_table *freq_table;
unsigned int freq_lo;
unsigned int freq_lo_jiffies;
unsigned int freq_hi_jiffies;
int cpu;
unsigned int enable:1,
- sample_type:1;
+ sample_type:1;
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
@@ -117,11 +130,7 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq);
busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq);
busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal);
-
- if (!dbs_tuners_ins.ignore_nice) {
- busy_time = cputime64_add(busy_time,
- kstat_cpu(cpu).cpustat.nice);
- }
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.nice);
idle_time = cputime64_sub(cur_wall_time, busy_time);
if (wall)
@@ -137,23 +146,6 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
if (idle_time == -1ULL)
return get_cpu_idle_time_jiffy(cpu, wall);
- if (dbs_tuners_ins.ignore_nice) {
- cputime64_t cur_nice;
- unsigned long cur_nice_jiffies;
- struct cpu_dbs_info_s *dbs_info;
-
- dbs_info = &per_cpu(cpu_dbs_info, cpu);
- cur_nice = cputime64_sub(kstat_cpu(cpu).cpustat.nice,
- dbs_info->prev_cpu_nice);
- /*
- * Assumption: nice time between sampling periods will be
- * less than 2^32 jiffies for 32 bit sys
- */
- cur_nice_jiffies = (unsigned long)
- cputime64_to_jiffies64(cur_nice);
- dbs_info->prev_cpu_nice = kstat_cpu(cpu).cpustat.nice;
- return idle_time + jiffies_to_usecs(cur_nice_jiffies);
- }
return idle_time;
}
@@ -224,12 +216,28 @@ static void ondemand_powersave_bias_init(void)
/************************** sysfs interface ************************/
static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
{
- return sprintf (buf, "%u\n", MAX_SAMPLING_RATE);
+ static int print_once;
+
+ if (!print_once) {
+ printk(KERN_INFO "CPUFREQ: ondemand sampling_rate_max "
+ "sysfs file is deprecated - used by: %s\n",
+ current->comm);
+ print_once = 1;
+ }
+ return sprintf(buf, "%u\n", MAX_SAMPLING_RATE);
}
static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
{
- return sprintf (buf, "%u\n", MIN_SAMPLING_RATE);
+ static int print_once;
+
+ if (!print_once) {
+ printk(KERN_INFO "CPUFREQ: ondemand sampling_rate_min "
+ "sysfs file is deprecated - used by: %s\n",
+ current->comm);
+ print_once = 1;
+ }
+ return sprintf(buf, "%u\n", MIN_SAMPLING_RATE);
}
#define define_one_ro(_name) \
@@ -259,13 +267,11 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
ret = sscanf(buf, "%u", &input);
mutex_lock(&dbs_mutex);
- if (ret != 1 || input > MAX_SAMPLING_RATE
- || input < MIN_SAMPLING_RATE) {
+ if (ret != 1) {
mutex_unlock(&dbs_mutex);
return -EINVAL;
}
-
- dbs_tuners_ins.sampling_rate = input;
+ dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate());
mutex_unlock(&dbs_mutex);
return count;
@@ -300,14 +306,14 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
unsigned int j;
ret = sscanf(buf, "%u", &input);
- if ( ret != 1 )
+ if (ret != 1)
return -EINVAL;
- if ( input > 1 )
+ if (input > 1)
input = 1;
mutex_lock(&dbs_mutex);
- if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
+ if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */
mutex_unlock(&dbs_mutex);
return count;
}
@@ -319,6 +325,9 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
dbs_info = &per_cpu(cpu_dbs_info, j);
dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
&dbs_info->prev_cpu_wall);
+ if (dbs_tuners_ins.ignore_nice)
+ dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
+
}
mutex_unlock(&dbs_mutex);
@@ -355,7 +364,7 @@ define_one_rw(up_threshold);
define_one_rw(ignore_nice_load);
define_one_rw(powersave_bias);
-static struct attribute * dbs_attributes[] = {
+static struct attribute *dbs_attributes[] = {
&sampling_rate_max.attr,
&sampling_rate_min.attr,
&sampling_rate.attr,
@@ -419,6 +428,23 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
j_dbs_info->prev_cpu_idle);
j_dbs_info->prev_cpu_idle = cur_idle_time;
+ if (dbs_tuners_ins.ignore_nice) {
+ cputime64_t cur_nice;
+ unsigned long cur_nice_jiffies;
+
+ cur_nice = cputime64_sub(kstat_cpu(j).cpustat.nice,
+ j_dbs_info->prev_cpu_nice);
+ /*
+ * Assumption: nice time between sampling periods will
+ * be less than 2^32 jiffies for 32 bit sys
+ */
+ cur_nice_jiffies = (unsigned long)
+ cputime64_to_jiffies64(cur_nice);
+
+ j_dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
+ idle_time += jiffies_to_usecs(cur_nice_jiffies);
+ }
+
if (unlikely(!wall_time || wall_time < idle_time))
continue;
@@ -513,8 +539,7 @@ static void do_dbs_timer(struct work_struct *work)
}
} else {
__cpufreq_driver_target(dbs_info->cur_policy,
- dbs_info->freq_lo,
- CPUFREQ_RELATION_H);
+ dbs_info->freq_lo, CPUFREQ_RELATION_H);
}
queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay);
unlock_policy_rwsem_write(cpu);
@@ -531,7 +556,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
dbs_info->sample_type = DBS_NORMAL_SAMPLE;
INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
- delay);
+ delay);
}
static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
@@ -575,6 +600,10 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
&j_dbs_info->prev_cpu_wall);
+ if (dbs_tuners_ins.ignore_nice) {
+ j_dbs_info->prev_cpu_nice =
+ kstat_cpu(j).cpustat.nice;
+ }
}
this_dbs_info->cpu = cpu;
/*
@@ -588,11 +617,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
if (latency == 0)
latency = 1;
- def_sampling_rate = latency *
- DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
-
- if (def_sampling_rate < MIN_STAT_SAMPLING_RATE)
- def_sampling_rate = MIN_STAT_SAMPLING_RATE;
+ def_sampling_rate =
+ max(latency * LATENCY_MULTIPLIER,
+ MIN_STAT_SAMPLING_RATE);
dbs_tuners_ins.sampling_rate = def_sampling_rate;
}
@@ -614,12 +641,10 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
mutex_lock(&dbs_mutex);
if (policy->max < this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy,
- policy->max,
- CPUFREQ_RELATION_H);
+ policy->max, CPUFREQ_RELATION_H);
else if (policy->min > this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy,
- policy->min,
- CPUFREQ_RELATION_L);
+ policy->min, CPUFREQ_RELATION_L);
mutex_unlock(&dbs_mutex);
break;
}
@@ -674,7 +699,7 @@ static void __exit cpufreq_gov_dbs_exit(void)
MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>");
MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>");
MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
- "Low Latency Frequency Transition capable processors");
+ "Low Latency Frequency Transition capable processors");
MODULE_LICENSE("GPL");
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index c0ff97d375d..5a62d678dd1 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -2,7 +2,7 @@
* drivers/cpufreq/cpufreq_stats.c
*
* Copyright (C) 2003-2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
- * (C) 2004 Zou Nan hai <nanhai.zou@intel.com>.
+ * (C) 2004 Zou Nan hai <nanhai.zou@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
@@ -23,7 +23,7 @@
static spinlock_t cpufreq_stats_lock;
-#define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
+#define CPUFREQ_STATDEVICE_ATTR(_name, _mode, _show) \
static struct freq_attr _attr_##_name = {\
.attr = {.name = __stringify(_name), .mode = _mode, }, \
.show = _show,\
@@ -50,8 +50,7 @@ struct cpufreq_stats_attribute {
ssize_t(*show) (struct cpufreq_stats *, char *);
};
-static int
-cpufreq_stats_update (unsigned int cpu)
+static int cpufreq_stats_update(unsigned int cpu)
{
struct cpufreq_stats *stat;
unsigned long long cur_time;
@@ -68,8 +67,7 @@ cpufreq_stats_update (unsigned int cpu)
return 0;
}
-static ssize_t
-show_total_trans(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf)
{
struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
if (!stat)
@@ -78,8 +76,7 @@ show_total_trans(struct cpufreq_policy *policy, char *buf)
per_cpu(cpufreq_stats_table, stat->cpu)->total_trans);
}
-static ssize_t
-show_time_in_state(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)
{
ssize_t len = 0;
int i;
@@ -89,14 +86,14 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf)
cpufreq_stats_update(stat->cpu);
for (i = 0; i < stat->state_num; i++) {
len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i],
- (unsigned long long)cputime64_to_clock_t(stat->time_in_state[i]));
+ (unsigned long long)
+ cputime64_to_clock_t(stat->time_in_state[i]));
}
return len;
}
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
-static ssize_t
-show_trans_table(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
{
ssize_t len = 0;
int i, j;
@@ -139,11 +136,11 @@ show_trans_table(struct cpufreq_policy *policy, char *buf)
return PAGE_SIZE;
return len;
}
-CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table);
+CPUFREQ_STATDEVICE_ATTR(trans_table, 0444, show_trans_table);
#endif
-CPUFREQ_STATDEVICE_ATTR(total_trans,0444,show_total_trans);
-CPUFREQ_STATDEVICE_ATTR(time_in_state,0444,show_time_in_state);
+CPUFREQ_STATDEVICE_ATTR(total_trans, 0444, show_total_trans);
+CPUFREQ_STATDEVICE_ATTR(time_in_state, 0444, show_time_in_state);
static struct attribute *default_attrs[] = {
&_attr_total_trans.attr,
@@ -158,8 +155,7 @@ static struct attribute_group stats_attr_group = {
.name = "stats"
};
-static int
-freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
+static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
{
int index;
for (index = 0; index < stat->max_state; index++)
@@ -183,8 +179,7 @@ static void cpufreq_stats_free_table(unsigned int cpu)
cpufreq_cpu_put(policy);
}
-static int
-cpufreq_stats_create_table (struct cpufreq_policy *policy,
+static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table)
{
unsigned int i, j, count = 0, ret = 0;
@@ -194,7 +189,8 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
unsigned int cpu = policy->cpu;
if (per_cpu(cpufreq_stats_table, cpu))
return -EBUSY;
- if ((stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
+ stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL);
+ if ((stat) == NULL)
return -ENOMEM;
data = cpufreq_cpu_get(cpu);
@@ -203,13 +199,14 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
goto error_get_fail;
}
- if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group)))
+ ret = sysfs_create_group(&data->kobj, &stats_attr_group);
+ if (ret)
goto error_out;
stat->cpu = cpu;
per_cpu(cpufreq_stats_table, cpu) = stat;
- for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
@@ -255,9 +252,8 @@ error_get_fail:
return ret;
}
-static int
-cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val,
- void *data)
+static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
+ unsigned long val, void *data)
{
int ret;
struct cpufreq_policy *policy = data;
@@ -268,14 +264,14 @@ cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val,
table = cpufreq_frequency_get_table(cpu);
if (!table)
return 0;
- if ((ret = cpufreq_stats_create_table(policy, table)))
+ ret = cpufreq_stats_create_table(policy, table);
+ if (ret)
return ret;
return 0;
}
-static int
-cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
- void *data)
+static int cpufreq_stat_notifier_trans(struct notifier_block *nb,
+ unsigned long val, void *data)
{
struct cpufreq_freqs *freq = data;
struct cpufreq_stats *stat;
@@ -340,19 +336,20 @@ static struct notifier_block notifier_trans_block = {
.notifier_call = cpufreq_stat_notifier_trans
};
-static int
-__init cpufreq_stats_init(void)
+static int __init cpufreq_stats_init(void)
{
int ret;
unsigned int cpu;
spin_lock_init(&cpufreq_stats_lock);
- if ((ret = cpufreq_register_notifier(&notifier_policy_block,
- CPUFREQ_POLICY_NOTIFIER)))
+ ret = cpufreq_register_notifier(&notifier_policy_block,
+ CPUFREQ_POLICY_NOTIFIER);
+ if (ret)
return ret;
- if ((ret = cpufreq_register_notifier(&notifier_trans_block,
- CPUFREQ_TRANSITION_NOTIFIER))) {
+ ret = cpufreq_register_notifier(&notifier_trans_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ if (ret) {
cpufreq_unregister_notifier(&notifier_policy_block,
CPUFREQ_POLICY_NOTIFIER);
return ret;
@@ -364,8 +361,7 @@ __init cpufreq_stats_init(void)
}
return 0;
}
-static void
-__exit cpufreq_stats_exit(void)
+static void __exit cpufreq_stats_exit(void)
{
unsigned int cpu;
@@ -379,10 +375,10 @@ __exit cpufreq_stats_exit(void)
}
}
-MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
-MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats "
+MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>");
+MODULE_DESCRIPTION("'cpufreq_stats' - A driver to export cpufreq stats "
"through sysfs filesystem");
-MODULE_LICENSE ("GPL");
+MODULE_LICENSE("GPL");
module_init(cpufreq_stats_init);
module_exit(cpufreq_stats_exit);
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index 1442bbada05..66d2d1d6c80 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -24,9 +24,6 @@
#include <linux/sysfs.h>
#include <linux/mutex.h>
-#include <asm/uaccess.h>
-
-
/**
* A few values needed by the userspace governor
*/
@@ -37,7 +34,7 @@ static DEFINE_PER_CPU(unsigned int, cpu_set_freq); /* CPU freq desired by
userspace */
static DEFINE_PER_CPU(unsigned int, cpu_is_managed);
-static DEFINE_MUTEX (userspace_mutex);
+static DEFINE_MUTEX(userspace_mutex);
static int cpus_using_userspace_governor;
#define dprintk(msg...) \
@@ -46,9 +43,9 @@ static int cpus_using_userspace_governor;
/* keep track of frequency transitions */
static int
userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
- void *data)
+ void *data)
{
- struct cpufreq_freqs *freq = data;
+ struct cpufreq_freqs *freq = data;
if (!per_cpu(cpu_is_managed, freq->cpu))
return 0;
@@ -57,11 +54,11 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
freq->cpu, freq->new);
per_cpu(cpu_cur_freq, freq->cpu) = freq->new;
- return 0;
+ return 0;
}
static struct notifier_block userspace_cpufreq_notifier_block = {
- .notifier_call = userspace_cpufreq_notifier
+ .notifier_call = userspace_cpufreq_notifier
};
@@ -93,8 +90,11 @@ static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq)
* We're safe from concurrent calls to ->target() here
* as we hold the userspace_mutex lock. If we were calling
* cpufreq_driver_target, a deadlock situation might occur:
- * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock)
- * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex)
+ * A: cpufreq_set (lock userspace_mutex) ->
+ * cpufreq_driver_target(lock policy->lock)
+ * B: cpufreq_set_policy(lock policy->lock) ->
+ * __cpufreq_governor ->
+ * cpufreq_governor_userspace (lock userspace_mutex)
*/
ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
@@ -210,9 +210,10 @@ static void __exit cpufreq_gov_userspace_exit(void)
}
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, "
+ "Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'");
+MODULE_LICENSE("GPL");
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
fs_initcall(cpufreq_gov_userspace_init);
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 9071d80fbba..a9bd3a05a68 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -28,7 +28,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
unsigned int max_freq = 0;
unsigned int i;
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID) {
dprintk("table entry %u is invalid, skipping\n", i);
@@ -70,7 +70,7 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
@@ -125,13 +125,13 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
if (!cpu_online(policy->cpu))
return -EINVAL;
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
if ((freq < policy->min) || (freq > policy->max))
continue;
- switch(relation) {
+ switch (relation) {
case CPUFREQ_RELATION_H:
if (freq <= target_freq) {
if (freq >= optimal.frequency) {
@@ -178,7 +178,7 @@ static DEFINE_PER_CPU(struct cpufreq_frequency_table *, show_table);
/**
* show_available_freqs - show available frequencies for the specified CPU
*/
-static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
+static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf)
{
unsigned int i = 0;
unsigned int cpu = policy->cpu;
@@ -190,7 +190,7 @@ static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
table = per_cpu(show_table, cpu);
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
continue;
count += sprintf(&buf[count], "%d ", table[i].frequency);
@@ -234,6 +234,6 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("CPUfreq frequency table helpers");
+MODULE_LICENSE("GPL");
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index e522144cba3..01afd758072 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -86,7 +86,7 @@ config ZCRYPT_MONOLITHIC
config CRYPTO_SHA1_S390
tristate "SHA1 digest algorithm"
depends on S390
- select CRYPTO_ALGAPI
+ select CRYPTO_HASH
help
This is the s390 hardware accelerated implementation of the
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
@@ -94,7 +94,7 @@ config CRYPTO_SHA1_S390
config CRYPTO_SHA256_S390
tristate "SHA256 digest algorithm"
depends on S390
- select CRYPTO_ALGAPI
+ select CRYPTO_HASH
help
This is the s390 hardware accelerated implementation of the
SHA256 secure hash standard (DFIPS 180-2).
@@ -105,7 +105,7 @@ config CRYPTO_SHA256_S390
config CRYPTO_SHA512_S390
tristate "SHA384 and SHA512 digest algorithm"
depends on S390
- select CRYPTO_ALGAPI
+ select CRYPTO_HASH
help
This is the s390 hardware accelerated implementation of the
SHA512 secure hash standard.
@@ -200,4 +200,13 @@ config CRYPTO_DEV_IXP4XX
help
Driver for the IXP4xx NPE crypto engine.
+config CRYPTO_DEV_PPC4XX
+ tristate "Driver AMCC PPC4xx crypto accelerator"
+ depends on PPC && 4xx
+ select CRYPTO_HASH
+ select CRYPTO_ALGAPI
+ select CRYPTO_BLKCIPHER
+ help
+ This option allows you to have support for AMCC crypto acceleration.
+
endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 73557b2968d..9bf4a2bc884 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
+obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
diff --git a/drivers/crypto/amcc/Makefile b/drivers/crypto/amcc/Makefile
new file mode 100644
index 00000000000..aa376e8d5ed
--- /dev/null
+++ b/drivers/crypto/amcc/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += crypto4xx.o
+crypto4xx-objs := crypto4xx_core.o crypto4xx_alg.o crypto4xx_sa.o
diff --git a/drivers/crypto/amcc/crypto4xx_alg.c b/drivers/crypto/amcc/crypto4xx_alg.c
new file mode 100644
index 00000000000..61b6e1bec8c
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_alg.c
@@ -0,0 +1,293 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This file implements the Linux crypto algorithms.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <linux/hash.h>
+#include <crypto/internal/hash.h>
+#include <linux/dma-mapping.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/sha.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_sa.h"
+#include "crypto4xx_core.h"
+
+void set_dynamic_sa_command_0(struct dynamic_sa_ctl *sa, u32 save_h,
+ u32 save_iv, u32 ld_h, u32 ld_iv, u32 hdr_proc,
+ u32 h, u32 c, u32 pad_type, u32 op_grp, u32 op,
+ u32 dir)
+{
+ sa->sa_command_0.w = 0;
+ sa->sa_command_0.bf.save_hash_state = save_h;
+ sa->sa_command_0.bf.save_iv = save_iv;
+ sa->sa_command_0.bf.load_hash_state = ld_h;
+ sa->sa_command_0.bf.load_iv = ld_iv;
+ sa->sa_command_0.bf.hdr_proc = hdr_proc;
+ sa->sa_command_0.bf.hash_alg = h;
+ sa->sa_command_0.bf.cipher_alg = c;
+ sa->sa_command_0.bf.pad_type = pad_type & 3;
+ sa->sa_command_0.bf.extend_pad = pad_type >> 2;
+ sa->sa_command_0.bf.op_group = op_grp;
+ sa->sa_command_0.bf.opcode = op;
+ sa->sa_command_0.bf.dir = dir;
+}
+
+void set_dynamic_sa_command_1(struct dynamic_sa_ctl *sa, u32 cm, u32 hmac_mc,
+ u32 cfb, u32 esn, u32 sn_mask, u32 mute,
+ u32 cp_pad, u32 cp_pay, u32 cp_hdr)
+{
+ sa->sa_command_1.w = 0;
+ sa->sa_command_1.bf.crypto_mode31 = (cm & 4) >> 2;
+ sa->sa_command_1.bf.crypto_mode9_8 = cm & 3;
+ sa->sa_command_1.bf.feedback_mode = cfb,
+ sa->sa_command_1.bf.sa_rev = 1;
+ sa->sa_command_1.bf.extended_seq_num = esn;
+ sa->sa_command_1.bf.seq_num_mask = sn_mask;
+ sa->sa_command_1.bf.mutable_bit_proc = mute;
+ sa->sa_command_1.bf.copy_pad = cp_pad;
+ sa->sa_command_1.bf.copy_payload = cp_pay;
+ sa->sa_command_1.bf.copy_hdr = cp_hdr;
+}
+
+int crypto4xx_encrypt(struct ablkcipher_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+ ctx->direction = DIR_OUTBOUND;
+ ctx->hash_final = 0;
+ ctx->is_hash = 0;
+ ctx->pd_ctl = 0x1;
+
+ return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
+ req->nbytes, req->info,
+ get_dynamic_sa_iv_size(ctx));
+}
+
+int crypto4xx_decrypt(struct ablkcipher_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+ ctx->direction = DIR_INBOUND;
+ ctx->hash_final = 0;
+ ctx->is_hash = 0;
+ ctx->pd_ctl = 1;
+
+ return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
+ req->nbytes, req->info,
+ get_dynamic_sa_iv_size(ctx));
+}
+
+/**
+ * AES Functions
+ */
+static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher,
+ const u8 *key,
+ unsigned int keylen,
+ unsigned char cm,
+ u8 fb)
+{
+ struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct dynamic_sa_ctl *sa;
+ int rc;
+
+ if (keylen != AES_KEYSIZE_256 &&
+ keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_128) {
+ crypto_ablkcipher_set_flags(cipher,
+ CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+
+ /* Create SA */
+ if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr)
+ crypto4xx_free_sa(ctx);
+
+ rc = crypto4xx_alloc_sa(ctx, SA_AES128_LEN + (keylen-16) / 4);
+ if (rc)
+ return rc;
+
+ if (ctx->state_record_dma_addr == 0) {
+ rc = crypto4xx_alloc_state_record(ctx);
+ if (rc) {
+ crypto4xx_free_sa(ctx);
+ return rc;
+ }
+ }
+ /* Setup SA */
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ ctx->hash_final = 0;
+
+ set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV,
+ SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE,
+ SA_NO_HEADER_PROC, SA_HASH_ALG_NULL,
+ SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO,
+ SA_OP_GROUP_BASIC, SA_OPCODE_DECRYPT,
+ DIR_INBOUND);
+
+ set_dynamic_sa_command_1(sa, cm, SA_HASH_MODE_HASH,
+ fb, SA_EXTENDED_SN_OFF,
+ SA_SEQ_MASK_OFF, SA_MC_ENABLE,
+ SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD,
+ SA_NOT_COPY_HDR);
+ crypto4xx_memcpy_le(ctx->sa_in + get_dynamic_sa_offset_key_field(ctx),
+ key, keylen);
+ sa->sa_contents = SA_AES_CONTENTS | (keylen << 2);
+ sa->sa_command_1.bf.key_len = keylen >> 3;
+ ctx->is_hash = 0;
+ ctx->direction = DIR_INBOUND;
+ memcpy(ctx->sa_in + get_dynamic_sa_offset_state_ptr_field(ctx),
+ (void *)&ctx->state_record_dma_addr, 4);
+ ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx);
+
+ memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4);
+ sa = (struct dynamic_sa_ctl *) ctx->sa_out;
+ sa->sa_command_0.bf.dir = DIR_OUTBOUND;
+
+ return 0;
+}
+
+int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher,
+ const u8 *key, unsigned int keylen)
+{
+ return crypto4xx_setkey_aes(cipher, key, keylen, CRYPTO_MODE_CBC,
+ CRYPTO_FEEDBACK_MODE_NO_FB);
+}
+
+/**
+ * HASH SHA1 Functions
+ */
+static int crypto4xx_hash_alg_init(struct crypto_tfm *tfm,
+ unsigned int sa_len,
+ unsigned char ha,
+ unsigned char hm)
+{
+ struct crypto_alg *alg = tfm->__crt_alg;
+ struct crypto4xx_alg *my_alg = crypto_alg_to_crypto4xx_alg(alg);
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct dynamic_sa_ctl *sa;
+ struct dynamic_sa_hash160 *sa_in;
+ int rc;
+
+ ctx->dev = my_alg->dev;
+ ctx->is_hash = 1;
+ ctx->hash_final = 0;
+
+ /* Create SA */
+ if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr)
+ crypto4xx_free_sa(ctx);
+
+ rc = crypto4xx_alloc_sa(ctx, sa_len);
+ if (rc)
+ return rc;
+
+ if (ctx->state_record_dma_addr == 0) {
+ crypto4xx_alloc_state_record(ctx);
+ if (!ctx->state_record_dma_addr) {
+ crypto4xx_free_sa(ctx);
+ return -ENOMEM;
+ }
+ }
+
+ tfm->crt_ahash.reqsize = sizeof(struct crypto4xx_ctx);
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV,
+ SA_NOT_LOAD_HASH, SA_LOAD_IV_FROM_SA,
+ SA_NO_HEADER_PROC, ha, SA_CIPHER_ALG_NULL,
+ SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC,
+ SA_OPCODE_HASH, DIR_INBOUND);
+ set_dynamic_sa_command_1(sa, 0, SA_HASH_MODE_HASH,
+ CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF,
+ SA_SEQ_MASK_OFF, SA_MC_ENABLE,
+ SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD,
+ SA_NOT_COPY_HDR);
+ ctx->direction = DIR_INBOUND;
+ sa->sa_contents = SA_HASH160_CONTENTS;
+ sa_in = (struct dynamic_sa_hash160 *) ctx->sa_in;
+ /* Need to zero hash digest in SA */
+ memset(sa_in->inner_digest, 0, sizeof(sa_in->inner_digest));
+ memset(sa_in->outer_digest, 0, sizeof(sa_in->outer_digest));
+ sa_in->state_ptr = ctx->state_record_dma_addr;
+ ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx);
+
+ return 0;
+}
+
+int crypto4xx_hash_init(struct ahash_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+ int ds;
+ struct dynamic_sa_ctl *sa;
+
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ ds = crypto_ahash_digestsize(
+ __crypto_ahash_cast(req->base.tfm));
+ sa->sa_command_0.bf.digest_len = ds >> 2;
+ sa->sa_command_0.bf.load_hash_state = SA_LOAD_HASH_FROM_SA;
+ ctx->is_hash = 1;
+ ctx->direction = DIR_INBOUND;
+
+ return 0;
+}
+
+int crypto4xx_hash_update(struct ahash_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+ ctx->is_hash = 1;
+ ctx->hash_final = 0;
+ ctx->pd_ctl = 0x11;
+ ctx->direction = DIR_INBOUND;
+
+ return crypto4xx_build_pd(&req->base, ctx, req->src,
+ (struct scatterlist *) req->result,
+ req->nbytes, NULL, 0);
+}
+
+int crypto4xx_hash_final(struct ahash_request *req)
+{
+ return 0;
+}
+
+int crypto4xx_hash_digest(struct ahash_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+ ctx->hash_final = 1;
+ ctx->pd_ctl = 0x11;
+ ctx->direction = DIR_INBOUND;
+
+ return crypto4xx_build_pd(&req->base, ctx, req->src,
+ (struct scatterlist *) req->result,
+ req->nbytes, NULL, 0);
+}
+
+/**
+ * SHA1 Algorithm
+ */
+int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm)
+{
+ return crypto4xx_hash_alg_init(tfm, SA_HASH160_LEN, SA_HASH_ALG_SHA1,
+ SA_HASH_MODE_HASH);
+}
+
+
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
new file mode 100644
index 00000000000..4c0dfb2b872
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -0,0 +1,1310 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This file implements AMCC crypto offload Linux device driver for use with
+ * Linux CryptoAPI.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/random.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
+#include <asm/cacheflush.h>
+#include <crypto/internal/hash.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/sha.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_core.h"
+#include "crypto4xx_sa.h"
+
+#define PPC4XX_SEC_VERSION_STR "0.5"
+
+/**
+ * PPC4xx Crypto Engine Initialization Routine
+ */
+static void crypto4xx_hw_init(struct crypto4xx_device *dev)
+{
+ union ce_ring_size ring_size;
+ union ce_ring_contol ring_ctrl;
+ union ce_part_ring_size part_ring_size;
+ union ce_io_threshold io_threshold;
+ u32 rand_num;
+ union ce_pe_dma_cfg pe_dma_cfg;
+
+ writel(PPC4XX_BYTE_ORDER, dev->ce_base + CRYPTO4XX_BYTE_ORDER_CFG);
+ /* setup pe dma, include reset sg, pdr and pe, then release reset */
+ pe_dma_cfg.w = 0;
+ pe_dma_cfg.bf.bo_sgpd_en = 1;
+ pe_dma_cfg.bf.bo_data_en = 0;
+ pe_dma_cfg.bf.bo_sa_en = 1;
+ pe_dma_cfg.bf.bo_pd_en = 1;
+ pe_dma_cfg.bf.dynamic_sa_en = 1;
+ pe_dma_cfg.bf.reset_sg = 1;
+ pe_dma_cfg.bf.reset_pdr = 1;
+ pe_dma_cfg.bf.reset_pe = 1;
+ writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+ /* un reset pe,sg and pdr */
+ pe_dma_cfg.bf.pe_mode = 0;
+ pe_dma_cfg.bf.reset_sg = 0;
+ pe_dma_cfg.bf.reset_pdr = 0;
+ pe_dma_cfg.bf.reset_pe = 0;
+ pe_dma_cfg.bf.bo_td_en = 0;
+ writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+ writel(dev->pdr_pa, dev->ce_base + CRYPTO4XX_PDR_BASE);
+ writel(dev->pdr_pa, dev->ce_base + CRYPTO4XX_RDR_BASE);
+ writel(PPC4XX_PRNG_CTRL_AUTO_EN, dev->ce_base + CRYPTO4XX_PRNG_CTRL);
+ get_random_bytes(&rand_num, sizeof(rand_num));
+ writel(rand_num, dev->ce_base + CRYPTO4XX_PRNG_SEED_L);
+ get_random_bytes(&rand_num, sizeof(rand_num));
+ writel(rand_num, dev->ce_base + CRYPTO4XX_PRNG_SEED_H);
+ ring_size.w = 0;
+ ring_size.bf.ring_offset = PPC4XX_PD_SIZE;
+ ring_size.bf.ring_size = PPC4XX_NUM_PD;
+ writel(ring_size.w, dev->ce_base + CRYPTO4XX_RING_SIZE);
+ ring_ctrl.w = 0;
+ writel(ring_ctrl.w, dev->ce_base + CRYPTO4XX_RING_CTRL);
+ writel(PPC4XX_DC_3DES_EN, dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
+ writel(dev->gdr_pa, dev->ce_base + CRYPTO4XX_GATH_RING_BASE);
+ writel(dev->sdr_pa, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE);
+ part_ring_size.w = 0;
+ part_ring_size.bf.sdr_size = PPC4XX_SDR_SIZE;
+ part_ring_size.bf.gdr_size = PPC4XX_GDR_SIZE;
+ writel(part_ring_size.w, dev->ce_base + CRYPTO4XX_PART_RING_SIZE);
+ writel(PPC4XX_SD_BUFFER_SIZE, dev->ce_base + CRYPTO4XX_PART_RING_CFG);
+ io_threshold.w = 0;
+ io_threshold.bf.output_threshold = PPC4XX_OUTPUT_THRESHOLD;
+ io_threshold.bf.input_threshold = PPC4XX_INPUT_THRESHOLD;
+ writel(io_threshold.w, dev->ce_base + CRYPTO4XX_IO_THRESHOLD);
+ writel(0, dev->ce_base + CRYPTO4XX_PDR_BASE_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_RDR_BASE_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_PKT_SRC_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_PKT_DEST_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_SA_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_GATH_RING_BASE_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE_UADDR);
+ /* un reset pe,sg and pdr */
+ pe_dma_cfg.bf.pe_mode = 1;
+ pe_dma_cfg.bf.reset_sg = 0;
+ pe_dma_cfg.bf.reset_pdr = 0;
+ pe_dma_cfg.bf.reset_pe = 0;
+ pe_dma_cfg.bf.bo_td_en = 0;
+ writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+ /*clear all pending interrupt*/
+ writel(PPC4XX_INTERRUPT_CLR, dev->ce_base + CRYPTO4XX_INT_CLR);
+ writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT);
+ writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT);
+ writel(PPC4XX_INT_CFG, dev->ce_base + CRYPTO4XX_INT_CFG);
+ writel(PPC4XX_PD_DONE_INT, dev->ce_base + CRYPTO4XX_INT_EN);
+}
+
+int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size)
+{
+ ctx->sa_in = dma_alloc_coherent(ctx->dev->core_dev->device, size * 4,
+ &ctx->sa_in_dma_addr, GFP_ATOMIC);
+ if (ctx->sa_in == NULL)
+ return -ENOMEM;
+
+ ctx->sa_out = dma_alloc_coherent(ctx->dev->core_dev->device, size * 4,
+ &ctx->sa_out_dma_addr, GFP_ATOMIC);
+ if (ctx->sa_out == NULL) {
+ dma_free_coherent(ctx->dev->core_dev->device,
+ ctx->sa_len * 4,
+ ctx->sa_in, ctx->sa_in_dma_addr);
+ return -ENOMEM;
+ }
+
+ memset(ctx->sa_in, 0, size * 4);
+ memset(ctx->sa_out, 0, size * 4);
+ ctx->sa_len = size;
+
+ return 0;
+}
+
+void crypto4xx_free_sa(struct crypto4xx_ctx *ctx)
+{
+ if (ctx->sa_in != NULL)
+ dma_free_coherent(ctx->dev->core_dev->device, ctx->sa_len * 4,
+ ctx->sa_in, ctx->sa_in_dma_addr);
+ if (ctx->sa_out != NULL)
+ dma_free_coherent(ctx->dev->core_dev->device, ctx->sa_len * 4,
+ ctx->sa_out, ctx->sa_out_dma_addr);
+
+ ctx->sa_in_dma_addr = 0;
+ ctx->sa_out_dma_addr = 0;
+ ctx->sa_len = 0;
+}
+
+u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx)
+{
+ ctx->state_record = dma_alloc_coherent(ctx->dev->core_dev->device,
+ sizeof(struct sa_state_record),
+ &ctx->state_record_dma_addr, GFP_ATOMIC);
+ if (!ctx->state_record_dma_addr)
+ return -ENOMEM;
+ memset(ctx->state_record, 0, sizeof(struct sa_state_record));
+
+ return 0;
+}
+
+void crypto4xx_free_state_record(struct crypto4xx_ctx *ctx)
+{
+ if (ctx->state_record != NULL)
+ dma_free_coherent(ctx->dev->core_dev->device,
+ sizeof(struct sa_state_record),
+ ctx->state_record,
+ ctx->state_record_dma_addr);
+ ctx->state_record_dma_addr = 0;
+}
+
+/**
+ * alloc memory for the gather ring
+ * no need to alloc buf for the ring
+ * gdr_tail, gdr_head and gdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev)
+{
+ int i;
+ struct pd_uinfo *pd_uinfo;
+ dev->pdr = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+ &dev->pdr_pa, GFP_ATOMIC);
+ if (!dev->pdr)
+ return -ENOMEM;
+
+ dev->pdr_uinfo = kzalloc(sizeof(struct pd_uinfo) * PPC4XX_NUM_PD,
+ GFP_KERNEL);
+ if (!dev->pdr_uinfo) {
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+ dev->pdr,
+ dev->pdr_pa);
+ return -ENOMEM;
+ }
+ memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD);
+ dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device,
+ 256 * PPC4XX_NUM_PD,
+ &dev->shadow_sa_pool_pa,
+ GFP_ATOMIC);
+ if (!dev->shadow_sa_pool)
+ return -ENOMEM;
+
+ dev->shadow_sr_pool = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
+ &dev->shadow_sr_pool_pa, GFP_ATOMIC);
+ if (!dev->shadow_sr_pool)
+ return -ENOMEM;
+ for (i = 0; i < PPC4XX_NUM_PD; i++) {
+ pd_uinfo = (struct pd_uinfo *) (dev->pdr_uinfo +
+ sizeof(struct pd_uinfo) * i);
+
+ /* alloc 256 bytes which is enough for any kind of dynamic sa */
+ pd_uinfo->sa_va = dev->shadow_sa_pool + 256 * i;
+ pd_uinfo->sa_pa = dev->shadow_sa_pool_pa + 256 * i;
+
+ /* alloc state record */
+ pd_uinfo->sr_va = dev->shadow_sr_pool +
+ sizeof(struct sa_state_record) * i;
+ pd_uinfo->sr_pa = dev->shadow_sr_pool_pa +
+ sizeof(struct sa_state_record) * i;
+ }
+
+ return 0;
+}
+
+static void crypto4xx_destroy_pdr(struct crypto4xx_device *dev)
+{
+ if (dev->pdr != NULL)
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+ dev->pdr, dev->pdr_pa);
+ if (dev->shadow_sa_pool)
+ dma_free_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD,
+ dev->shadow_sa_pool, dev->shadow_sa_pool_pa);
+ if (dev->shadow_sr_pool)
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
+ dev->shadow_sr_pool, dev->shadow_sr_pool_pa);
+
+ kfree(dev->pdr_uinfo);
+}
+
+static u32 crypto4xx_get_pd_from_pdr_nolock(struct crypto4xx_device *dev)
+{
+ u32 retval;
+ u32 tmp;
+
+ retval = dev->pdr_head;
+ tmp = (dev->pdr_head + 1) % PPC4XX_NUM_PD;
+
+ if (tmp == dev->pdr_tail)
+ return ERING_WAS_FULL;
+
+ dev->pdr_head = tmp;
+
+ return retval;
+}
+
+static u32 crypto4xx_put_pd_to_pdr(struct crypto4xx_device *dev, u32 idx)
+{
+ struct pd_uinfo *pd_uinfo;
+ unsigned long flags;
+
+ pd_uinfo = (struct pd_uinfo *)(dev->pdr_uinfo +
+ sizeof(struct pd_uinfo) * idx);
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
+ if (dev->pdr_tail != PPC4XX_LAST_PD)
+ dev->pdr_tail++;
+ else
+ dev->pdr_tail = 0;
+ pd_uinfo->state = PD_ENTRY_FREE;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+ return 0;
+}
+
+static struct ce_pd *crypto4xx_get_pdp(struct crypto4xx_device *dev,
+ dma_addr_t *pd_dma, u32 idx)
+{
+ *pd_dma = dev->pdr_pa + sizeof(struct ce_pd) * idx;
+
+ return dev->pdr + sizeof(struct ce_pd) * idx;
+}
+
+/**
+ * alloc memory for the gather ring
+ * no need to alloc buf for the ring
+ * gdr_tail, gdr_head and gdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_gdr(struct crypto4xx_device *dev)
+{
+ dev->gdr = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct ce_gd) * PPC4XX_NUM_GD,
+ &dev->gdr_pa, GFP_ATOMIC);
+ if (!dev->gdr)
+ return -ENOMEM;
+
+ memset(dev->gdr, 0, sizeof(struct ce_gd) * PPC4XX_NUM_GD);
+
+ return 0;
+}
+
+static inline void crypto4xx_destroy_gdr(struct crypto4xx_device *dev)
+{
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_gd) * PPC4XX_NUM_GD,
+ dev->gdr, dev->gdr_pa);
+}
+
+/*
+ * when this function is called.
+ * preemption or interrupt must be disabled
+ */
+u32 crypto4xx_get_n_gd(struct crypto4xx_device *dev, int n)
+{
+ u32 retval;
+ u32 tmp;
+ if (n >= PPC4XX_NUM_GD)
+ return ERING_WAS_FULL;
+
+ retval = dev->gdr_head;
+ tmp = (dev->gdr_head + n) % PPC4XX_NUM_GD;
+ if (dev->gdr_head > dev->gdr_tail) {
+ if (tmp < dev->gdr_head && tmp >= dev->gdr_tail)
+ return ERING_WAS_FULL;
+ } else if (dev->gdr_head < dev->gdr_tail) {
+ if (tmp < dev->gdr_head || tmp >= dev->gdr_tail)
+ return ERING_WAS_FULL;
+ }
+ dev->gdr_head = tmp;
+
+ return retval;
+}
+
+static u32 crypto4xx_put_gd_to_gdr(struct crypto4xx_device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
+ if (dev->gdr_tail == dev->gdr_head) {
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return 0;
+ }
+
+ if (dev->gdr_tail != PPC4XX_LAST_GD)
+ dev->gdr_tail++;
+ else
+ dev->gdr_tail = 0;
+
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+ return 0;
+}
+
+static inline struct ce_gd *crypto4xx_get_gdp(struct crypto4xx_device *dev,
+ dma_addr_t *gd_dma, u32 idx)
+{
+ *gd_dma = dev->gdr_pa + sizeof(struct ce_gd) * idx;
+
+ return (struct ce_gd *) (dev->gdr + sizeof(struct ce_gd) * idx);
+}
+
+/**
+ * alloc memory for the scatter ring
+ * need to alloc buf for the ring
+ * sdr_tail, sdr_head and sdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_sdr(struct crypto4xx_device *dev)
+{
+ int i;
+ struct ce_sd *sd_array;
+
+ /* alloc memory for scatter descriptor ring */
+ dev->sdr = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+ &dev->sdr_pa, GFP_ATOMIC);
+ if (!dev->sdr)
+ return -ENOMEM;
+
+ dev->scatter_buffer_size = PPC4XX_SD_BUFFER_SIZE;
+ dev->scatter_buffer_va =
+ dma_alloc_coherent(dev->core_dev->device,
+ dev->scatter_buffer_size * PPC4XX_NUM_SD,
+ &dev->scatter_buffer_pa, GFP_ATOMIC);
+ if (!dev->scatter_buffer_va) {
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+ dev->sdr, dev->sdr_pa);
+ return -ENOMEM;
+ }
+
+ sd_array = dev->sdr;
+
+ for (i = 0; i < PPC4XX_NUM_SD; i++) {
+ sd_array[i].ptr = dev->scatter_buffer_pa +
+ dev->scatter_buffer_size * i;
+ }
+
+ return 0;
+}
+
+static void crypto4xx_destroy_sdr(struct crypto4xx_device *dev)
+{
+ if (dev->sdr != NULL)
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+ dev->sdr, dev->sdr_pa);
+
+ if (dev->scatter_buffer_va != NULL)
+ dma_free_coherent(dev->core_dev->device,
+ dev->scatter_buffer_size * PPC4XX_NUM_SD,
+ dev->scatter_buffer_va,
+ dev->scatter_buffer_pa);
+}
+
+/*
+ * when this function is called.
+ * preemption or interrupt must be disabled
+ */
+static u32 crypto4xx_get_n_sd(struct crypto4xx_device *dev, int n)
+{
+ u32 retval;
+ u32 tmp;
+
+ if (n >= PPC4XX_NUM_SD)
+ return ERING_WAS_FULL;
+
+ retval = dev->sdr_head;
+ tmp = (dev->sdr_head + n) % PPC4XX_NUM_SD;
+ if (dev->sdr_head > dev->gdr_tail) {
+ if (tmp < dev->sdr_head && tmp >= dev->sdr_tail)
+ return ERING_WAS_FULL;
+ } else if (dev->sdr_head < dev->sdr_tail) {
+ if (tmp < dev->sdr_head || tmp >= dev->sdr_tail)
+ return ERING_WAS_FULL;
+ } /* the head = tail, or empty case is already take cared */
+ dev->sdr_head = tmp;
+
+ return retval;
+}
+
+static u32 crypto4xx_put_sd_to_sdr(struct crypto4xx_device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
+ if (dev->sdr_tail == dev->sdr_head) {
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return 0;
+ }
+ if (dev->sdr_tail != PPC4XX_LAST_SD)
+ dev->sdr_tail++;
+ else
+ dev->sdr_tail = 0;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+ return 0;
+}
+
+static inline struct ce_sd *crypto4xx_get_sdp(struct crypto4xx_device *dev,
+ dma_addr_t *sd_dma, u32 idx)
+{
+ *sd_dma = dev->sdr_pa + sizeof(struct ce_sd) * idx;
+
+ return (struct ce_sd *)(dev->sdr + sizeof(struct ce_sd) * idx);
+}
+
+static u32 crypto4xx_fill_one_page(struct crypto4xx_device *dev,
+ dma_addr_t *addr, u32 *length,
+ u32 *idx, u32 *offset, u32 *nbytes)
+{
+ u32 len;
+
+ if (*length > dev->scatter_buffer_size) {
+ memcpy(phys_to_virt(*addr),
+ dev->scatter_buffer_va +
+ *idx * dev->scatter_buffer_size + *offset,
+ dev->scatter_buffer_size);
+ *offset = 0;
+ *length -= dev->scatter_buffer_size;
+ *nbytes -= dev->scatter_buffer_size;
+ if (*idx == PPC4XX_LAST_SD)
+ *idx = 0;
+ else
+ (*idx)++;
+ *addr = *addr + dev->scatter_buffer_size;
+ return 1;
+ } else if (*length < dev->scatter_buffer_size) {
+ memcpy(phys_to_virt(*addr),
+ dev->scatter_buffer_va +
+ *idx * dev->scatter_buffer_size + *offset, *length);
+ if ((*offset + *length) == dev->scatter_buffer_size) {
+ if (*idx == PPC4XX_LAST_SD)
+ *idx = 0;
+ else
+ (*idx)++;
+ *nbytes -= *length;
+ *offset = 0;
+ } else {
+ *nbytes -= *length;
+ *offset += *length;
+ }
+
+ return 0;
+ } else {
+ len = (*nbytes <= dev->scatter_buffer_size) ?
+ (*nbytes) : dev->scatter_buffer_size;
+ memcpy(phys_to_virt(*addr),
+ dev->scatter_buffer_va +
+ *idx * dev->scatter_buffer_size + *offset,
+ len);
+ *offset = 0;
+ *nbytes -= len;
+
+ if (*idx == PPC4XX_LAST_SD)
+ *idx = 0;
+ else
+ (*idx)++;
+
+ return 0;
+ }
+}
+
+static void crypto4xx_copy_pkt_to_dst(struct crypto4xx_device *dev,
+ struct ce_pd *pd,
+ struct pd_uinfo *pd_uinfo,
+ u32 nbytes,
+ struct scatterlist *dst)
+{
+ dma_addr_t addr;
+ u32 this_sd;
+ u32 offset;
+ u32 len;
+ u32 i;
+ u32 sg_len;
+ struct scatterlist *sg;
+
+ this_sd = pd_uinfo->first_sd;
+ offset = 0;
+ i = 0;
+
+ while (nbytes) {
+ sg = &dst[i];
+ sg_len = sg->length;
+ addr = dma_map_page(dev->core_dev->device, sg_page(sg),
+ sg->offset, sg->length, DMA_TO_DEVICE);
+
+ if (offset == 0) {
+ len = (nbytes <= sg->length) ? nbytes : sg->length;
+ while (crypto4xx_fill_one_page(dev, &addr, &len,
+ &this_sd, &offset, &nbytes))
+ ;
+ if (!nbytes)
+ return;
+ i++;
+ } else {
+ len = (nbytes <= (dev->scatter_buffer_size - offset)) ?
+ nbytes : (dev->scatter_buffer_size - offset);
+ len = (sg->length < len) ? sg->length : len;
+ while (crypto4xx_fill_one_page(dev, &addr, &len,
+ &this_sd, &offset, &nbytes))
+ ;
+ if (!nbytes)
+ return;
+ sg_len -= len;
+ if (sg_len) {
+ addr += len;
+ while (crypto4xx_fill_one_page(dev, &addr,
+ &sg_len, &this_sd, &offset, &nbytes))
+ ;
+ }
+ i++;
+ }
+ }
+}
+
+static u32 crypto4xx_copy_digest_to_dst(struct pd_uinfo *pd_uinfo,
+ struct crypto4xx_ctx *ctx)
+{
+ struct dynamic_sa_ctl *sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ struct sa_state_record *state_record =
+ (struct sa_state_record *) pd_uinfo->sr_va;
+
+ if (sa->sa_command_0.bf.hash_alg == SA_HASH_ALG_SHA1) {
+ memcpy((void *) pd_uinfo->dest_va, state_record->save_digest,
+ SA_HASH_ALG_SHA1_DIGEST_SIZE);
+ }
+
+ return 0;
+}
+
+static void crypto4xx_ret_sg_desc(struct crypto4xx_device *dev,
+ struct pd_uinfo *pd_uinfo)
+{
+ int i;
+ if (pd_uinfo->num_gd) {
+ for (i = 0; i < pd_uinfo->num_gd; i++)
+ crypto4xx_put_gd_to_gdr(dev);
+ pd_uinfo->first_gd = 0xffffffff;
+ pd_uinfo->num_gd = 0;
+ }
+ if (pd_uinfo->num_sd) {
+ for (i = 0; i < pd_uinfo->num_sd; i++)
+ crypto4xx_put_sd_to_sdr(dev);
+
+ pd_uinfo->first_sd = 0xffffffff;
+ pd_uinfo->num_sd = 0;
+ }
+}
+
+static u32 crypto4xx_ablkcipher_done(struct crypto4xx_device *dev,
+ struct pd_uinfo *pd_uinfo,
+ struct ce_pd *pd)
+{
+ struct crypto4xx_ctx *ctx;
+ struct ablkcipher_request *ablk_req;
+ struct scatterlist *dst;
+ dma_addr_t addr;
+
+ ablk_req = ablkcipher_request_cast(pd_uinfo->async_req);
+ ctx = crypto_tfm_ctx(ablk_req->base.tfm);
+
+ if (pd_uinfo->using_sd) {
+ crypto4xx_copy_pkt_to_dst(dev, pd, pd_uinfo, ablk_req->nbytes,
+ ablk_req->dst);
+ } else {
+ dst = pd_uinfo->dest_va;
+ addr = dma_map_page(dev->core_dev->device, sg_page(dst),
+ dst->offset, dst->length, DMA_FROM_DEVICE);
+ }
+ crypto4xx_ret_sg_desc(dev, pd_uinfo);
+ if (ablk_req->base.complete != NULL)
+ ablk_req->base.complete(&ablk_req->base, 0);
+
+ return 0;
+}
+
+static u32 crypto4xx_ahash_done(struct crypto4xx_device *dev,
+ struct pd_uinfo *pd_uinfo)
+{
+ struct crypto4xx_ctx *ctx;
+ struct ahash_request *ahash_req;
+
+ ahash_req = ahash_request_cast(pd_uinfo->async_req);
+ ctx = crypto_tfm_ctx(ahash_req->base.tfm);
+
+ crypto4xx_copy_digest_to_dst(pd_uinfo,
+ crypto_tfm_ctx(ahash_req->base.tfm));
+ crypto4xx_ret_sg_desc(dev, pd_uinfo);
+ /* call user provided callback function x */
+ if (ahash_req->base.complete != NULL)
+ ahash_req->base.complete(&ahash_req->base, 0);
+
+ return 0;
+}
+
+static u32 crypto4xx_pd_done(struct crypto4xx_device *dev, u32 idx)
+{
+ struct ce_pd *pd;
+ struct pd_uinfo *pd_uinfo;
+
+ pd = dev->pdr + sizeof(struct ce_pd)*idx;
+ pd_uinfo = dev->pdr_uinfo + sizeof(struct pd_uinfo)*idx;
+ if (crypto_tfm_alg_type(pd_uinfo->async_req->tfm) ==
+ CRYPTO_ALG_TYPE_ABLKCIPHER)
+ return crypto4xx_ablkcipher_done(dev, pd_uinfo, pd);
+ else
+ return crypto4xx_ahash_done(dev, pd_uinfo);
+}
+
+/**
+ * Note: Only use this function to copy items that is word aligned.
+ */
+void crypto4xx_memcpy_le(unsigned int *dst,
+ const unsigned char *buf,
+ int len)
+{
+ u8 *tmp;
+ for (; len >= 4; buf += 4, len -= 4)
+ *dst++ = cpu_to_le32(*(unsigned int *) buf);
+
+ tmp = (u8 *)dst;
+ switch (len) {
+ case 3:
+ *tmp++ = 0;
+ *tmp++ = *(buf+2);
+ *tmp++ = *(buf+1);
+ *tmp++ = *buf;
+ break;
+ case 2:
+ *tmp++ = 0;
+ *tmp++ = 0;
+ *tmp++ = *(buf+1);
+ *tmp++ = *buf;
+ break;
+ case 1:
+ *tmp++ = 0;
+ *tmp++ = 0;
+ *tmp++ = 0;
+ *tmp++ = *buf;
+ break;
+ default:
+ break;
+ }
+}
+
+static void crypto4xx_stop_all(struct crypto4xx_core_device *core_dev)
+{
+ crypto4xx_destroy_pdr(core_dev->dev);
+ crypto4xx_destroy_gdr(core_dev->dev);
+ crypto4xx_destroy_sdr(core_dev->dev);
+ dev_set_drvdata(core_dev->device, NULL);
+ iounmap(core_dev->dev->ce_base);
+ kfree(core_dev->dev);
+ kfree(core_dev);
+}
+
+void crypto4xx_return_pd(struct crypto4xx_device *dev,
+ u32 pd_entry, struct ce_pd *pd,
+ struct pd_uinfo *pd_uinfo)
+{
+ /* irq should be already disabled */
+ dev->pdr_head = pd_entry;
+ pd->pd_ctl.w = 0;
+ pd->pd_ctl_len.w = 0;
+ pd_uinfo->state = PD_ENTRY_FREE;
+}
+
+/*
+ * derive number of elements in scatterlist
+ * Shamlessly copy from talitos.c
+ */
+static int get_sg_count(struct scatterlist *sg_list, int nbytes)
+{
+ struct scatterlist *sg = sg_list;
+ int sg_nents = 0;
+
+ while (nbytes) {
+ sg_nents++;
+ if (sg->length > nbytes)
+ break;
+ nbytes -= sg->length;
+ sg = sg_next(sg);
+ }
+
+ return sg_nents;
+}
+
+static u32 get_next_gd(u32 current)
+{
+ if (current != PPC4XX_LAST_GD)
+ return current + 1;
+ else
+ return 0;
+}
+
+static u32 get_next_sd(u32 current)
+{
+ if (current != PPC4XX_LAST_SD)
+ return current + 1;
+ else
+ return 0;
+}
+
+u32 crypto4xx_build_pd(struct crypto_async_request *req,
+ struct crypto4xx_ctx *ctx,
+ struct scatterlist *src,
+ struct scatterlist *dst,
+ unsigned int datalen,
+ void *iv, u32 iv_len)
+{
+ struct crypto4xx_device *dev = ctx->dev;
+ dma_addr_t addr, pd_dma, sd_dma, gd_dma;
+ struct dynamic_sa_ctl *sa;
+ struct scatterlist *sg;
+ struct ce_gd *gd;
+ struct ce_pd *pd;
+ u32 num_gd, num_sd;
+ u32 fst_gd = 0xffffffff;
+ u32 fst_sd = 0xffffffff;
+ u32 pd_entry;
+ unsigned long flags;
+ struct pd_uinfo *pd_uinfo = NULL;
+ unsigned int nbytes = datalen, idx;
+ unsigned int ivlen = 0;
+ u32 gd_idx = 0;
+
+ /* figure how many gd is needed */
+ num_gd = get_sg_count(src, datalen);
+ if (num_gd == 1)
+ num_gd = 0;
+
+ /* figure how many sd is needed */
+ if (sg_is_last(dst) || ctx->is_hash) {
+ num_sd = 0;
+ } else {
+ if (datalen > PPC4XX_SD_BUFFER_SIZE) {
+ num_sd = datalen / PPC4XX_SD_BUFFER_SIZE;
+ if (datalen % PPC4XX_SD_BUFFER_SIZE)
+ num_sd++;
+ } else {
+ num_sd = 1;
+ }
+ }
+
+ /*
+ * The follow section of code needs to be protected
+ * The gather ring and scatter ring needs to be consecutive
+ * In case of run out of any kind of descriptor, the descriptor
+ * already got must be return the original place.
+ */
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
+ if (num_gd) {
+ fst_gd = crypto4xx_get_n_gd(dev, num_gd);
+ if (fst_gd == ERING_WAS_FULL) {
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return -EAGAIN;
+ }
+ }
+ if (num_sd) {
+ fst_sd = crypto4xx_get_n_sd(dev, num_sd);
+ if (fst_sd == ERING_WAS_FULL) {
+ if (num_gd)
+ dev->gdr_head = fst_gd;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return -EAGAIN;
+ }
+ }
+ pd_entry = crypto4xx_get_pd_from_pdr_nolock(dev);
+ if (pd_entry == ERING_WAS_FULL) {
+ if (num_gd)
+ dev->gdr_head = fst_gd;
+ if (num_sd)
+ dev->sdr_head = fst_sd;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return -EAGAIN;
+ }
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+ pd_uinfo = (struct pd_uinfo *)(dev->pdr_uinfo +
+ sizeof(struct pd_uinfo) * pd_entry);
+ pd = crypto4xx_get_pdp(dev, &pd_dma, pd_entry);
+ pd_uinfo->async_req = req;
+ pd_uinfo->num_gd = num_gd;
+ pd_uinfo->num_sd = num_sd;
+
+ if (iv_len || ctx->is_hash) {
+ ivlen = iv_len;
+ pd->sa = pd_uinfo->sa_pa;
+ sa = (struct dynamic_sa_ctl *) pd_uinfo->sa_va;
+ if (ctx->direction == DIR_INBOUND)
+ memcpy(sa, ctx->sa_in, ctx->sa_len * 4);
+ else
+ memcpy(sa, ctx->sa_out, ctx->sa_len * 4);
+
+ memcpy((void *) sa + ctx->offset_to_sr_ptr,
+ &pd_uinfo->sr_pa, 4);
+
+ if (iv_len)
+ crypto4xx_memcpy_le(pd_uinfo->sr_va, iv, iv_len);
+ } else {
+ if (ctx->direction == DIR_INBOUND) {
+ pd->sa = ctx->sa_in_dma_addr;
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ } else {
+ pd->sa = ctx->sa_out_dma_addr;
+ sa = (struct dynamic_sa_ctl *) ctx->sa_out;
+ }
+ }
+ pd->sa_len = ctx->sa_len;
+ if (num_gd) {
+ /* get first gd we are going to use */
+ gd_idx = fst_gd;
+ pd_uinfo->first_gd = fst_gd;
+ pd_uinfo->num_gd = num_gd;
+ gd = crypto4xx_get_gdp(dev, &gd_dma, gd_idx);
+ pd->src = gd_dma;
+ /* enable gather */
+ sa->sa_command_0.bf.gather = 1;
+ idx = 0;
+ src = &src[0];
+ /* walk the sg, and setup gather array */
+ while (nbytes) {
+ sg = &src[idx];
+ addr = dma_map_page(dev->core_dev->device, sg_page(sg),
+ sg->offset, sg->length, DMA_TO_DEVICE);
+ gd->ptr = addr;
+ gd->ctl_len.len = sg->length;
+ gd->ctl_len.done = 0;
+ gd->ctl_len.ready = 1;
+ if (sg->length >= nbytes)
+ break;
+ nbytes -= sg->length;
+ gd_idx = get_next_gd(gd_idx);
+ gd = crypto4xx_get_gdp(dev, &gd_dma, gd_idx);
+ idx++;
+ }
+ } else {
+ pd->src = (u32)dma_map_page(dev->core_dev->device, sg_page(src),
+ src->offset, src->length, DMA_TO_DEVICE);
+ /*
+ * Disable gather in sa command
+ */
+ sa->sa_command_0.bf.gather = 0;
+ /*
+ * Indicate gather array is not used
+ */
+ pd_uinfo->first_gd = 0xffffffff;
+ pd_uinfo->num_gd = 0;
+ }
+ if (ctx->is_hash || sg_is_last(dst)) {
+ /*
+ * we know application give us dst a whole piece of memory
+ * no need to use scatter ring.
+ * In case of is_hash, the icv is always at end of src data.
+ */
+ pd_uinfo->using_sd = 0;
+ pd_uinfo->first_sd = 0xffffffff;
+ pd_uinfo->num_sd = 0;
+ pd_uinfo->dest_va = dst;
+ sa->sa_command_0.bf.scatter = 0;
+ if (ctx->is_hash)
+ pd->dest = virt_to_phys((void *)dst);
+ else
+ pd->dest = (u32)dma_map_page(dev->core_dev->device,
+ sg_page(dst), dst->offset,
+ dst->length, DMA_TO_DEVICE);
+ } else {
+ struct ce_sd *sd = NULL;
+ u32 sd_idx = fst_sd;
+ nbytes = datalen;
+ sa->sa_command_0.bf.scatter = 1;
+ pd_uinfo->using_sd = 1;
+ pd_uinfo->dest_va = dst;
+ pd_uinfo->first_sd = fst_sd;
+ pd_uinfo->num_sd = num_sd;
+ sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx);
+ pd->dest = sd_dma;
+ /* setup scatter descriptor */
+ sd->ctl.done = 0;
+ sd->ctl.rdy = 1;
+ /* sd->ptr should be setup by sd_init routine*/
+ idx = 0;
+ if (nbytes >= PPC4XX_SD_BUFFER_SIZE)
+ nbytes -= PPC4XX_SD_BUFFER_SIZE;
+ else
+ nbytes = 0;
+ while (nbytes) {
+ sd_idx = get_next_sd(sd_idx);
+ sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx);
+ /* setup scatter descriptor */
+ sd->ctl.done = 0;
+ sd->ctl.rdy = 1;
+ if (nbytes >= PPC4XX_SD_BUFFER_SIZE)
+ nbytes -= PPC4XX_SD_BUFFER_SIZE;
+ else
+ /*
+ * SD entry can hold PPC4XX_SD_BUFFER_SIZE,
+ * which is more than nbytes, so done.
+ */
+ nbytes = 0;
+ }
+ }
+
+ sa->sa_command_1.bf.hash_crypto_offset = 0;
+ pd->pd_ctl.w = ctx->pd_ctl;
+ pd->pd_ctl_len.w = 0x00400000 | (ctx->bypass << 24) | datalen;
+ pd_uinfo->state = PD_ENTRY_INUSE;
+ wmb();
+ /* write any value to push engine to read a pd */
+ writel(1, dev->ce_base + CRYPTO4XX_INT_DESCR_RD);
+ return -EINPROGRESS;
+}
+
+/**
+ * Algorithm Registration Functions
+ */
+static int crypto4xx_alg_init(struct crypto_tfm *tfm)
+{
+ struct crypto_alg *alg = tfm->__crt_alg;
+ struct crypto4xx_alg *amcc_alg = crypto_alg_to_crypto4xx_alg(alg);
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ ctx->dev = amcc_alg->dev;
+ ctx->sa_in = NULL;
+ ctx->sa_out = NULL;
+ ctx->sa_in_dma_addr = 0;
+ ctx->sa_out_dma_addr = 0;
+ ctx->sa_len = 0;
+
+ if (alg->cra_type == &crypto_ablkcipher_type)
+ tfm->crt_ablkcipher.reqsize = sizeof(struct crypto4xx_ctx);
+ else if (alg->cra_type == &crypto_ahash_type)
+ tfm->crt_ahash.reqsize = sizeof(struct crypto4xx_ctx);
+
+ return 0;
+}
+
+static void crypto4xx_alg_exit(struct crypto_tfm *tfm)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto4xx_free_sa(ctx);
+ crypto4xx_free_state_record(ctx);
+}
+
+int crypto4xx_register_alg(struct crypto4xx_device *sec_dev,
+ struct crypto_alg *crypto_alg, int array_size)
+{
+ struct crypto4xx_alg *alg;
+ int i;
+ int rc = 0;
+
+ for (i = 0; i < array_size; i++) {
+ alg = kzalloc(sizeof(struct crypto4xx_alg), GFP_KERNEL);
+ if (!alg)
+ return -ENOMEM;
+
+ alg->alg = crypto_alg[i];
+ INIT_LIST_HEAD(&alg->alg.cra_list);
+ if (alg->alg.cra_init == NULL)
+ alg->alg.cra_init = crypto4xx_alg_init;
+ if (alg->alg.cra_exit == NULL)
+ alg->alg.cra_exit = crypto4xx_alg_exit;
+ alg->dev = sec_dev;
+ rc = crypto_register_alg(&alg->alg);
+ if (rc) {
+ list_del(&alg->entry);
+ kfree(alg);
+ } else {
+ list_add_tail(&alg->entry, &sec_dev->alg_list);
+ }
+ }
+
+ return 0;
+}
+
+static void crypto4xx_unregister_alg(struct crypto4xx_device *sec_dev)
+{
+ struct crypto4xx_alg *alg, *tmp;
+
+ list_for_each_entry_safe(alg, tmp, &sec_dev->alg_list, entry) {
+ list_del(&alg->entry);
+ crypto_unregister_alg(&alg->alg);
+ kfree(alg);
+ }
+}
+
+static void crypto4xx_bh_tasklet_cb(unsigned long data)
+{
+ struct device *dev = (struct device *)data;
+ struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+ struct pd_uinfo *pd_uinfo;
+ struct ce_pd *pd;
+ u32 tail;
+
+ while (core_dev->dev->pdr_head != core_dev->dev->pdr_tail) {
+ tail = core_dev->dev->pdr_tail;
+ pd_uinfo = core_dev->dev->pdr_uinfo +
+ sizeof(struct pd_uinfo)*tail;
+ pd = core_dev->dev->pdr + sizeof(struct ce_pd) * tail;
+ if ((pd_uinfo->state == PD_ENTRY_INUSE) &&
+ pd->pd_ctl.bf.pe_done &&
+ !pd->pd_ctl.bf.host_ready) {
+ pd->pd_ctl.bf.pe_done = 0;
+ crypto4xx_pd_done(core_dev->dev, tail);
+ crypto4xx_put_pd_to_pdr(core_dev->dev, tail);
+ pd_uinfo->state = PD_ENTRY_FREE;
+ } else {
+ /* if tail not done, break */
+ break;
+ }
+ }
+}
+
+/**
+ * Top Half of isr.
+ */
+static irqreturn_t crypto4xx_ce_interrupt_handler(int irq, void *data)
+{
+ struct device *dev = (struct device *)data;
+ struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+
+ if (core_dev->dev->ce_base == 0)
+ return 0;
+
+ writel(PPC4XX_INTERRUPT_CLR,
+ core_dev->dev->ce_base + CRYPTO4XX_INT_CLR);
+ tasklet_schedule(&core_dev->tasklet);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * Supported Crypto Algorithms
+ */
+struct crypto_alg crypto4xx_alg[] = {
+ /* Crypto AES modes */
+ {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-ppc4xx",
+ .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto4xx_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_IV_SIZE,
+ .setkey = crypto4xx_setkey_aes_cbc,
+ .encrypt = crypto4xx_encrypt,
+ .decrypt = crypto4xx_decrypt,
+ }
+ }
+ },
+ /* Hash SHA1 */
+ {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-ppc4xx",
+ .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto4xx_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ahash_type,
+ .cra_init = crypto4xx_sha1_alg_init,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .ahash = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = crypto4xx_hash_init,
+ .update = crypto4xx_hash_update,
+ .final = crypto4xx_hash_final,
+ .digest = crypto4xx_hash_digest,
+ }
+ }
+ },
+};
+
+/**
+ * Module Initialization Routine
+ */
+static int __init crypto4xx_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ int rc;
+ struct resource res;
+ struct device *dev = &ofdev->dev;
+ struct crypto4xx_core_device *core_dev;
+
+ rc = of_address_to_resource(ofdev->node, 0, &res);
+ if (rc)
+ return -ENODEV;
+
+ if (of_find_compatible_node(NULL, NULL, "amcc,ppc460ex-crypto")) {
+ mtdcri(SDR0, PPC460EX_SDR0_SRST,
+ mfdcri(SDR0, PPC460EX_SDR0_SRST) | PPC460EX_CE_RESET);
+ mtdcri(SDR0, PPC460EX_SDR0_SRST,
+ mfdcri(SDR0, PPC460EX_SDR0_SRST) & ~PPC460EX_CE_RESET);
+ } else if (of_find_compatible_node(NULL, NULL,
+ "amcc,ppc405ex-crypto")) {
+ mtdcri(SDR0, PPC405EX_SDR0_SRST,
+ mfdcri(SDR0, PPC405EX_SDR0_SRST) | PPC405EX_CE_RESET);
+ mtdcri(SDR0, PPC405EX_SDR0_SRST,
+ mfdcri(SDR0, PPC405EX_SDR0_SRST) & ~PPC405EX_CE_RESET);
+ } else if (of_find_compatible_node(NULL, NULL,
+ "amcc,ppc460sx-crypto")) {
+ mtdcri(SDR0, PPC460SX_SDR0_SRST,
+ mfdcri(SDR0, PPC460SX_SDR0_SRST) | PPC460SX_CE_RESET);
+ mtdcri(SDR0, PPC460SX_SDR0_SRST,
+ mfdcri(SDR0, PPC460SX_SDR0_SRST) & ~PPC460SX_CE_RESET);
+ } else {
+ printk(KERN_ERR "Crypto Function Not supported!\n");
+ return -EINVAL;
+ }
+
+ core_dev = kzalloc(sizeof(struct crypto4xx_core_device), GFP_KERNEL);
+ if (!core_dev)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, core_dev);
+ core_dev->ofdev = ofdev;
+ core_dev->dev = kzalloc(sizeof(struct crypto4xx_device), GFP_KERNEL);
+ if (!core_dev->dev)
+ goto err_alloc_dev;
+
+ core_dev->dev->core_dev = core_dev;
+ core_dev->device = dev;
+ spin_lock_init(&core_dev->lock);
+ INIT_LIST_HEAD(&core_dev->dev->alg_list);
+ rc = crypto4xx_build_pdr(core_dev->dev);
+ if (rc)
+ goto err_build_pdr;
+
+ rc = crypto4xx_build_gdr(core_dev->dev);
+ if (rc)
+ goto err_build_gdr;
+
+ rc = crypto4xx_build_sdr(core_dev->dev);
+ if (rc)
+ goto err_build_sdr;
+
+ /* Init tasklet for bottom half processing */
+ tasklet_init(&core_dev->tasklet, crypto4xx_bh_tasklet_cb,
+ (unsigned long) dev);
+
+ /* Register for Crypto isr, Crypto Engine IRQ */
+ core_dev->irq = irq_of_parse_and_map(ofdev->node, 0);
+ rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0,
+ core_dev->dev->name, dev);
+ if (rc)
+ goto err_request_irq;
+
+ core_dev->dev->ce_base = of_iomap(ofdev->node, 0);
+ if (!core_dev->dev->ce_base) {
+ dev_err(dev, "failed to of_iomap\n");
+ goto err_iomap;
+ }
+
+ /* need to setup pdr, rdr, gdr and sdr before this */
+ crypto4xx_hw_init(core_dev->dev);
+
+ /* Register security algorithms with Linux CryptoAPI */
+ rc = crypto4xx_register_alg(core_dev->dev, crypto4xx_alg,
+ ARRAY_SIZE(crypto4xx_alg));
+ if (rc)
+ goto err_start_dev;
+
+ return 0;
+
+err_start_dev:
+ iounmap(core_dev->dev->ce_base);
+err_iomap:
+ free_irq(core_dev->irq, dev);
+ irq_dispose_mapping(core_dev->irq);
+ tasklet_kill(&core_dev->tasklet);
+err_request_irq:
+ crypto4xx_destroy_sdr(core_dev->dev);
+err_build_sdr:
+ crypto4xx_destroy_gdr(core_dev->dev);
+err_build_gdr:
+ crypto4xx_destroy_pdr(core_dev->dev);
+err_build_pdr:
+ kfree(core_dev->dev);
+err_alloc_dev:
+ kfree(core_dev);
+
+ return rc;
+}
+
+static int __exit crypto4xx_remove(struct of_device *ofdev)
+{
+ struct device *dev = &ofdev->dev;
+ struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+
+ free_irq(core_dev->irq, dev);
+ irq_dispose_mapping(core_dev->irq);
+
+ tasklet_kill(&core_dev->tasklet);
+ /* Un-register with Linux CryptoAPI */
+ crypto4xx_unregister_alg(core_dev->dev);
+ /* Free all allocated memory */
+ crypto4xx_stop_all(core_dev);
+
+ return 0;
+}
+
+static struct of_device_id crypto4xx_match[] = {
+ { .compatible = "amcc,ppc4xx-crypto",},
+ { },
+};
+
+static struct of_platform_driver crypto4xx_driver = {
+ .name = "crypto4xx",
+ .match_table = crypto4xx_match,
+ .probe = crypto4xx_probe,
+ .remove = crypto4xx_remove,
+};
+
+static int __init crypto4xx_init(void)
+{
+ return of_register_platform_driver(&crypto4xx_driver);
+}
+
+static void __exit crypto4xx_exit(void)
+{
+ of_unregister_platform_driver(&crypto4xx_driver);
+}
+
+module_init(crypto4xx_init);
+module_exit(crypto4xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Hsiao <jhsiao@amcc.com>");
+MODULE_DESCRIPTION("Driver for AMCC PPC4xx crypto accelerator");
+
diff --git a/drivers/crypto/amcc/crypto4xx_core.h b/drivers/crypto/amcc/crypto4xx_core.h
new file mode 100644
index 00000000000..1ef10344936
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_core.h
@@ -0,0 +1,177 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This is the header file for AMCC Crypto offload Linux device driver for
+ * use with Linux CryptoAPI.
+
+ */
+
+#ifndef __CRYPTO4XX_CORE_H__
+#define __CRYPTO4XX_CORE_H__
+
+#define PPC460SX_SDR0_SRST 0x201
+#define PPC405EX_SDR0_SRST 0x200
+#define PPC460EX_SDR0_SRST 0x201
+#define PPC460EX_CE_RESET 0x08000000
+#define PPC460SX_CE_RESET 0x20000000
+#define PPC405EX_CE_RESET 0x00000008
+
+#define CRYPTO4XX_CRYPTO_PRIORITY 300
+#define PPC4XX_LAST_PD 63
+#define PPC4XX_NUM_PD 64
+#define PPC4XX_LAST_GD 1023
+#define PPC4XX_NUM_GD 1024
+#define PPC4XX_LAST_SD 63
+#define PPC4XX_NUM_SD 64
+#define PPC4XX_SD_BUFFER_SIZE 2048
+
+#define PD_ENTRY_INUSE 1
+#define PD_ENTRY_FREE 0
+#define ERING_WAS_FULL 0xffffffff
+
+struct crypto4xx_device;
+
+struct pd_uinfo {
+ struct crypto4xx_device *dev;
+ u32 state;
+ u32 using_sd;
+ u32 first_gd; /* first gather discriptor
+ used by this packet */
+ u32 num_gd; /* number of gather discriptor
+ used by this packet */
+ u32 first_sd; /* first scatter discriptor
+ used by this packet */
+ u32 num_sd; /* number of scatter discriptors
+ used by this packet */
+ void *sa_va; /* shadow sa, when using cp from ctx->sa */
+ u32 sa_pa;
+ void *sr_va; /* state record for shadow sa */
+ u32 sr_pa;
+ struct scatterlist *dest_va;
+ struct crypto_async_request *async_req; /* base crypto request
+ for this packet */
+};
+
+struct crypto4xx_device {
+ struct crypto4xx_core_device *core_dev;
+ char *name;
+ u64 ce_phy_address;
+ void __iomem *ce_base;
+
+ void *pdr; /* base address of packet
+ descriptor ring */
+ dma_addr_t pdr_pa; /* physical address used to
+ program ce pdr_base_register */
+ void *gdr; /* gather descriptor ring */
+ dma_addr_t gdr_pa; /* physical address used to
+ program ce gdr_base_register */
+ void *sdr; /* scatter descriptor ring */
+ dma_addr_t sdr_pa; /* physical address used to
+ program ce sdr_base_register */
+ void *scatter_buffer_va;
+ dma_addr_t scatter_buffer_pa;
+ u32 scatter_buffer_size;
+
+ void *shadow_sa_pool; /* pool of memory for sa in pd_uinfo */
+ dma_addr_t shadow_sa_pool_pa;
+ void *shadow_sr_pool; /* pool of memory for sr in pd_uinfo */
+ dma_addr_t shadow_sr_pool_pa;
+ u32 pdr_tail;
+ u32 pdr_head;
+ u32 gdr_tail;
+ u32 gdr_head;
+ u32 sdr_tail;
+ u32 sdr_head;
+ void *pdr_uinfo;
+ struct list_head alg_list; /* List of algorithm supported
+ by this device */
+};
+
+struct crypto4xx_core_device {
+ struct device *device;
+ struct of_device *ofdev;
+ struct crypto4xx_device *dev;
+ u32 int_status;
+ u32 irq;
+ struct tasklet_struct tasklet;
+ spinlock_t lock;
+};
+
+struct crypto4xx_ctx {
+ struct crypto4xx_device *dev;
+ void *sa_in;
+ dma_addr_t sa_in_dma_addr;
+ void *sa_out;
+ dma_addr_t sa_out_dma_addr;
+ void *state_record;
+ dma_addr_t state_record_dma_addr;
+ u32 sa_len;
+ u32 offset_to_sr_ptr; /* offset to state ptr, in dynamic sa */
+ u32 direction;
+ u32 next_hdr;
+ u32 save_iv;
+ u32 pd_ctl_len;
+ u32 pd_ctl;
+ u32 bypass;
+ u32 is_hash;
+ u32 hash_final;
+};
+
+struct crypto4xx_req_ctx {
+ struct crypto4xx_device *dev; /* Device in which
+ operation to send to */
+ void *sa;
+ u32 sa_dma_addr;
+ u16 sa_len;
+};
+
+struct crypto4xx_alg {
+ struct list_head entry;
+ struct crypto_alg alg;
+ struct crypto4xx_device *dev;
+};
+
+#define crypto_alg_to_crypto4xx_alg(x) \
+ container_of(x, struct crypto4xx_alg, alg)
+
+extern int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size);
+extern void crypto4xx_free_sa(struct crypto4xx_ctx *ctx);
+extern u32 crypto4xx_alloc_sa_rctx(struct crypto4xx_ctx *ctx,
+ struct crypto4xx_ctx *rctx);
+extern void crypto4xx_free_sa_rctx(struct crypto4xx_ctx *rctx);
+extern void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx);
+extern u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx);
+extern void crypto4xx_memcpy_le(unsigned int *dst,
+ const unsigned char *buf, int len);
+extern u32 crypto4xx_build_pd(struct crypto_async_request *req,
+ struct crypto4xx_ctx *ctx,
+ struct scatterlist *src,
+ struct scatterlist *dst,
+ unsigned int datalen,
+ void *iv, u32 iv_len);
+extern int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher,
+ const u8 *key, unsigned int keylen);
+extern int crypto4xx_encrypt(struct ablkcipher_request *req);
+extern int crypto4xx_decrypt(struct ablkcipher_request *req);
+extern int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm);
+extern int crypto4xx_hash_digest(struct ahash_request *req);
+extern int crypto4xx_hash_final(struct ahash_request *req);
+extern int crypto4xx_hash_update(struct ahash_request *req);
+extern int crypto4xx_hash_init(struct ahash_request *req);
+#endif
diff --git a/drivers/crypto/amcc/crypto4xx_reg_def.h b/drivers/crypto/amcc/crypto4xx_reg_def.h
new file mode 100644
index 00000000000..7d4edb00261
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
@@ -0,0 +1,284 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This filr defines the register set for Security Subsystem
+ */
+
+#ifndef __CRYPTO4XX_REG_DEF_H__
+#define __CRYPTO4XX_REG_DEF_H__
+
+/* CRYPTO4XX Register offset */
+#define CRYPTO4XX_DESCRIPTOR 0x00000000
+#define CRYPTO4XX_CTRL_STAT 0x00000000
+#define CRYPTO4XX_SOURCE 0x00000004
+#define CRYPTO4XX_DEST 0x00000008
+#define CRYPTO4XX_SA 0x0000000C
+#define CRYPTO4XX_SA_LENGTH 0x00000010
+#define CRYPTO4XX_LENGTH 0x00000014
+
+#define CRYPTO4XX_PE_DMA_CFG 0x00000040
+#define CRYPTO4XX_PE_DMA_STAT 0x00000044
+#define CRYPTO4XX_PDR_BASE 0x00000048
+#define CRYPTO4XX_RDR_BASE 0x0000004c
+#define CRYPTO4XX_RING_SIZE 0x00000050
+#define CRYPTO4XX_RING_CTRL 0x00000054
+#define CRYPTO4XX_INT_RING_STAT 0x00000058
+#define CRYPTO4XX_EXT_RING_STAT 0x0000005c
+#define CRYPTO4XX_IO_THRESHOLD 0x00000060
+#define CRYPTO4XX_GATH_RING_BASE 0x00000064
+#define CRYPTO4XX_SCAT_RING_BASE 0x00000068
+#define CRYPTO4XX_PART_RING_SIZE 0x0000006c
+#define CRYPTO4XX_PART_RING_CFG 0x00000070
+
+#define CRYPTO4XX_PDR_BASE_UADDR 0x00000080
+#define CRYPTO4XX_RDR_BASE_UADDR 0x00000084
+#define CRYPTO4XX_PKT_SRC_UADDR 0x00000088
+#define CRYPTO4XX_PKT_DEST_UADDR 0x0000008c
+#define CRYPTO4XX_SA_UADDR 0x00000090
+#define CRYPTO4XX_GATH_RING_BASE_UADDR 0x000000A0
+#define CRYPTO4XX_SCAT_RING_BASE_UADDR 0x000000A4
+
+#define CRYPTO4XX_SEQ_RD 0x00000408
+#define CRYPTO4XX_SEQ_MASK_RD 0x0000040C
+
+#define CRYPTO4XX_SA_CMD_0 0x00010600
+#define CRYPTO4XX_SA_CMD_1 0x00010604
+
+#define CRYPTO4XX_STATE_PTR 0x000106dc
+#define CRYPTO4XX_STATE_IV 0x00010700
+#define CRYPTO4XX_STATE_HASH_BYTE_CNT_0 0x00010710
+#define CRYPTO4XX_STATE_HASH_BYTE_CNT_1 0x00010714
+
+#define CRYPTO4XX_STATE_IDIGEST_0 0x00010718
+#define CRYPTO4XX_STATE_IDIGEST_1 0x0001071c
+
+#define CRYPTO4XX_DATA_IN 0x00018000
+#define CRYPTO4XX_DATA_OUT 0x0001c000
+
+#define CRYPTO4XX_INT_UNMASK_STAT 0x000500a0
+#define CRYPTO4XX_INT_MASK_STAT 0x000500a4
+#define CRYPTO4XX_INT_CLR 0x000500a4
+#define CRYPTO4XX_INT_EN 0x000500a8
+
+#define CRYPTO4XX_INT_PKA 0x00000002
+#define CRYPTO4XX_INT_PDR_DONE 0x00008000
+#define CRYPTO4XX_INT_MA_WR_ERR 0x00020000
+#define CRYPTO4XX_INT_MA_RD_ERR 0x00010000
+#define CRYPTO4XX_INT_PE_ERR 0x00000200
+#define CRYPTO4XX_INT_USER_DMA_ERR 0x00000040
+#define CRYPTO4XX_INT_SLAVE_ERR 0x00000010
+#define CRYPTO4XX_INT_MASTER_ERR 0x00000008
+#define CRYPTO4XX_INT_ERROR 0x00030258
+
+#define CRYPTO4XX_INT_CFG 0x000500ac
+#define CRYPTO4XX_INT_DESCR_RD 0x000500b0
+#define CRYPTO4XX_INT_DESCR_CNT 0x000500b4
+#define CRYPTO4XX_INT_TIMEOUT_CNT 0x000500b8
+
+#define CRYPTO4XX_DEVICE_CTRL 0x00060080
+#define CRYPTO4XX_DEVICE_ID 0x00060084
+#define CRYPTO4XX_DEVICE_INFO 0x00060088
+#define CRYPTO4XX_DMA_USER_SRC 0x00060094
+#define CRYPTO4XX_DMA_USER_DEST 0x00060098
+#define CRYPTO4XX_DMA_USER_CMD 0x0006009C
+
+#define CRYPTO4XX_DMA_CFG 0x000600d4
+#define CRYPTO4XX_BYTE_ORDER_CFG 0x000600d8
+#define CRYPTO4XX_ENDIAN_CFG 0x000600d8
+
+#define CRYPTO4XX_PRNG_STAT 0x00070000
+#define CRYPTO4XX_PRNG_CTRL 0x00070004
+#define CRYPTO4XX_PRNG_SEED_L 0x00070008
+#define CRYPTO4XX_PRNG_SEED_H 0x0007000c
+
+#define CRYPTO4XX_PRNG_RES_0 0x00070020
+#define CRYPTO4XX_PRNG_RES_1 0x00070024
+#define CRYPTO4XX_PRNG_RES_2 0x00070028
+#define CRYPTO4XX_PRNG_RES_3 0x0007002C
+
+#define CRYPTO4XX_PRNG_LFSR_L 0x00070030
+#define CRYPTO4XX_PRNG_LFSR_H 0x00070034
+
+/**
+ * Initilize CRYPTO ENGINE registers, and memory bases.
+ */
+#define PPC4XX_PDR_POLL 0x3ff
+#define PPC4XX_OUTPUT_THRESHOLD 2
+#define PPC4XX_INPUT_THRESHOLD 2
+#define PPC4XX_PD_SIZE 6
+#define PPC4XX_CTX_DONE_INT 0x2000
+#define PPC4XX_PD_DONE_INT 0x8000
+#define PPC4XX_BYTE_ORDER 0x22222
+#define PPC4XX_INTERRUPT_CLR 0x3ffff
+#define PPC4XX_PRNG_CTRL_AUTO_EN 0x3
+#define PPC4XX_DC_3DES_EN 1
+#define PPC4XX_INT_DESCR_CNT 4
+#define PPC4XX_INT_TIMEOUT_CNT 0
+#define PPC4XX_INT_CFG 1
+/**
+ * all follow define are ad hoc
+ */
+#define PPC4XX_RING_RETRY 100
+#define PPC4XX_RING_POLL 100
+#define PPC4XX_SDR_SIZE PPC4XX_NUM_SD
+#define PPC4XX_GDR_SIZE PPC4XX_NUM_GD
+
+/**
+ * Generic Security Association (SA) with all possible fields. These will
+ * never likely used except for reference purpose. These structure format
+ * can be not changed as the hardware expects them to be layout as defined.
+ * Field can be removed or reduced but ordering can not be changed.
+ */
+#define CRYPTO4XX_DMA_CFG_OFFSET 0x40
+union ce_pe_dma_cfg {
+ struct {
+ u32 rsv:7;
+ u32 dir_host:1;
+ u32 rsv1:2;
+ u32 bo_td_en:1;
+ u32 dis_pdr_upd:1;
+ u32 bo_sgpd_en:1;
+ u32 bo_data_en:1;
+ u32 bo_sa_en:1;
+ u32 bo_pd_en:1;
+ u32 rsv2:4;
+ u32 dynamic_sa_en:1;
+ u32 pdr_mode:2;
+ u32 pe_mode:1;
+ u32 rsv3:5;
+ u32 reset_sg:1;
+ u32 reset_pdr:1;
+ u32 reset_pe:1;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_PDR_BASE_OFFSET 0x48
+#define CRYPTO4XX_RDR_BASE_OFFSET 0x4c
+#define CRYPTO4XX_RING_SIZE_OFFSET 0x50
+union ce_ring_size {
+ struct {
+ u32 ring_offset:16;
+ u32 rsv:6;
+ u32 ring_size:10;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_RING_CONTROL_OFFSET 0x54
+union ce_ring_contol {
+ struct {
+ u32 continuous:1;
+ u32 rsv:5;
+ u32 ring_retry_divisor:10;
+ u32 rsv1:4;
+ u32 ring_poll_divisor:10;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_IO_THRESHOLD_OFFSET 0x60
+union ce_io_threshold {
+ struct {
+ u32 rsv:6;
+ u32 output_threshold:10;
+ u32 rsv1:6;
+ u32 input_threshold:10;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_GATHER_RING_BASE_OFFSET 0x64
+#define CRYPTO4XX_SCATTER_RING_BASE_OFFSET 0x68
+
+union ce_part_ring_size {
+ struct {
+ u32 sdr_size:16;
+ u32 gdr_size:16;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define MAX_BURST_SIZE_32 0
+#define MAX_BURST_SIZE_64 1
+#define MAX_BURST_SIZE_128 2
+#define MAX_BURST_SIZE_256 3
+
+/* gather descriptor control length */
+struct gd_ctl_len {
+ u32 len:16;
+ u32 rsv:14;
+ u32 done:1;
+ u32 ready:1;
+} __attribute__((packed));
+
+struct ce_gd {
+ u32 ptr;
+ struct gd_ctl_len ctl_len;
+} __attribute__((packed));
+
+struct sd_ctl {
+ u32 ctl:30;
+ u32 done:1;
+ u32 rdy:1;
+} __attribute__((packed));
+
+struct ce_sd {
+ u32 ptr;
+ struct sd_ctl ctl;
+} __attribute__((packed));
+
+#define PD_PAD_CTL_32 0x10
+#define PD_PAD_CTL_64 0x20
+#define PD_PAD_CTL_128 0x40
+#define PD_PAD_CTL_256 0x80
+union ce_pd_ctl {
+ struct {
+ u32 pd_pad_ctl:8;
+ u32 status:8;
+ u32 next_hdr:8;
+ u32 rsv:2;
+ u32 cached_sa:1;
+ u32 hash_final:1;
+ u32 init_arc4:1;
+ u32 rsv1:1;
+ u32 pe_done:1;
+ u32 host_ready:1;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+union ce_pd_ctl_len {
+ struct {
+ u32 bypass:8;
+ u32 pe_done:1;
+ u32 host_ready:1;
+ u32 rsv:2;
+ u32 pkt_len:20;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+struct ce_pd {
+ union ce_pd_ctl pd_ctl;
+ u32 src;
+ u32 dest;
+ u32 sa; /* get from ctx->sa_dma_addr */
+ u32 sa_len; /* only if dynamic sa is used */
+ union ce_pd_ctl_len pd_ctl_len;
+
+} __attribute__((packed));
+#endif
diff --git a/drivers/crypto/amcc/crypto4xx_sa.c b/drivers/crypto/amcc/crypto4xx_sa.c
new file mode 100644
index 00000000000..466fd94cd4a
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_sa.c
@@ -0,0 +1,108 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * @file crypto4xx_sa.c
+ *
+ * This file implements the security context
+ * assoicate format.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mod_devicetable.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/highmem.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <crypto/algapi.h>
+#include <crypto/des.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_sa.h"
+#include "crypto4xx_core.h"
+
+u32 get_dynamic_sa_offset_iv_field(struct crypto4xx_ctx *ctx)
+{
+ u32 offset;
+ union dynamic_sa_contents cts;
+
+ if (ctx->direction == DIR_INBOUND)
+ cts.w = ((struct dynamic_sa_ctl *)(ctx->sa_in))->sa_contents;
+ else
+ cts.w = ((struct dynamic_sa_ctl *)(ctx->sa_out))->sa_contents;
+ offset = cts.bf.key_size
+ + cts.bf.inner_size
+ + cts.bf.outer_size
+ + cts.bf.spi
+ + cts.bf.seq_num0
+ + cts.bf.seq_num1
+ + cts.bf.seq_num_mask0
+ + cts.bf.seq_num_mask1
+ + cts.bf.seq_num_mask2
+ + cts.bf.seq_num_mask3;
+
+ return sizeof(struct dynamic_sa_ctl) + offset * 4;
+}
+
+u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx)
+{
+ u32 offset;
+ union dynamic_sa_contents cts;
+
+ if (ctx->direction == DIR_INBOUND)
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+ else
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+ offset = cts.bf.key_size
+ + cts.bf.inner_size
+ + cts.bf.outer_size
+ + cts.bf.spi
+ + cts.bf.seq_num0
+ + cts.bf.seq_num1
+ + cts.bf.seq_num_mask0
+ + cts.bf.seq_num_mask1
+ + cts.bf.seq_num_mask2
+ + cts.bf.seq_num_mask3
+ + cts.bf.iv0
+ + cts.bf.iv1
+ + cts.bf.iv2
+ + cts.bf.iv3;
+
+ return sizeof(struct dynamic_sa_ctl) + offset * 4;
+}
+
+u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx)
+{
+ union dynamic_sa_contents cts;
+
+ if (ctx->direction == DIR_INBOUND)
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+ else
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+ return (cts.bf.iv0 + cts.bf.iv1 + cts.bf.iv2 + cts.bf.iv3) * 4;
+}
+
+u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx)
+{
+ union dynamic_sa_contents cts;
+
+ if (ctx->direction == DIR_INBOUND)
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+ else
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+
+ return sizeof(struct dynamic_sa_ctl);
+}
diff --git a/drivers/crypto/amcc/crypto4xx_sa.h b/drivers/crypto/amcc/crypto4xx_sa.h
new file mode 100644
index 00000000000..4b83ed7e557
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_sa.h
@@ -0,0 +1,243 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This file defines the security context
+ * assoicate format.
+ */
+
+#ifndef __CRYPTO4XX_SA_H__
+#define __CRYPTO4XX_SA_H__
+
+#define AES_IV_SIZE 16
+
+/**
+ * Contents of Dynamic Security Association (SA) with all possible fields
+ */
+union dynamic_sa_contents {
+ struct {
+ u32 arc4_state_ptr:1;
+ u32 arc4_ij_ptr:1;
+ u32 state_ptr:1;
+ u32 iv3:1;
+ u32 iv2:1;
+ u32 iv1:1;
+ u32 iv0:1;
+ u32 seq_num_mask3:1;
+ u32 seq_num_mask2:1;
+ u32 seq_num_mask1:1;
+ u32 seq_num_mask0:1;
+ u32 seq_num1:1;
+ u32 seq_num0:1;
+ u32 spi:1;
+ u32 outer_size:5;
+ u32 inner_size:5;
+ u32 key_size:4;
+ u32 cmd_size:4;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define DIR_OUTBOUND 0
+#define DIR_INBOUND 1
+#define SA_OP_GROUP_BASIC 0
+#define SA_OPCODE_ENCRYPT 0
+#define SA_OPCODE_DECRYPT 0
+#define SA_OPCODE_HASH 3
+#define SA_CIPHER_ALG_DES 0
+#define SA_CIPHER_ALG_3DES 1
+#define SA_CIPHER_ALG_ARC4 2
+#define SA_CIPHER_ALG_AES 3
+#define SA_CIPHER_ALG_KASUMI 4
+#define SA_CIPHER_ALG_NULL 15
+
+#define SA_HASH_ALG_MD5 0
+#define SA_HASH_ALG_SHA1 1
+#define SA_HASH_ALG_NULL 15
+#define SA_HASH_ALG_SHA1_DIGEST_SIZE 20
+
+#define SA_LOAD_HASH_FROM_SA 0
+#define SA_LOAD_HASH_FROM_STATE 2
+#define SA_NOT_LOAD_HASH 3
+#define SA_LOAD_IV_FROM_SA 0
+#define SA_LOAD_IV_FROM_INPUT 1
+#define SA_LOAD_IV_FROM_STATE 2
+#define SA_LOAD_IV_GEN_IV 3
+
+#define SA_PAD_TYPE_CONSTANT 2
+#define SA_PAD_TYPE_ZERO 3
+#define SA_PAD_TYPE_TLS 5
+#define SA_PAD_TYPE_DTLS 5
+#define SA_NOT_SAVE_HASH 0
+#define SA_SAVE_HASH 1
+#define SA_NOT_SAVE_IV 0
+#define SA_SAVE_IV 1
+#define SA_HEADER_PROC 1
+#define SA_NO_HEADER_PROC 0
+
+union sa_command_0 {
+ struct {
+ u32 scatter:1;
+ u32 gather:1;
+ u32 save_hash_state:1;
+ u32 save_iv:1;
+ u32 load_hash_state:2;
+ u32 load_iv:2;
+ u32 digest_len:4;
+ u32 hdr_proc:1;
+ u32 extend_pad:1;
+ u32 stream_cipher_pad:1;
+ u32 rsv:1;
+ u32 hash_alg:4;
+ u32 cipher_alg:4;
+ u32 pad_type:2;
+ u32 op_group:2;
+ u32 dir:1;
+ u32 opcode:3;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO_MODE_ECB 0
+#define CRYPTO_MODE_CBC 1
+
+#define CRYPTO_FEEDBACK_MODE_NO_FB 0
+#define CRYPTO_FEEDBACK_MODE_64BIT_OFB 0
+#define CRYPTO_FEEDBACK_MODE_8BIT_CFB 1
+#define CRYPTO_FEEDBACK_MODE_1BIT_CFB 2
+#define CRYPTO_FEEDBACK_MODE_128BIT_CFB 3
+
+#define SA_AES_KEY_LEN_128 2
+#define SA_AES_KEY_LEN_192 3
+#define SA_AES_KEY_LEN_256 4
+
+#define SA_REV2 1
+/**
+ * The follow defines bits sa_command_1
+ * In Basic hash mode this bit define simple hash or hmac.
+ * In IPsec mode, this bit define muting control.
+ */
+#define SA_HASH_MODE_HASH 0
+#define SA_HASH_MODE_HMAC 1
+#define SA_MC_ENABLE 0
+#define SA_MC_DISABLE 1
+#define SA_NOT_COPY_HDR 0
+#define SA_COPY_HDR 1
+#define SA_NOT_COPY_PAD 0
+#define SA_COPY_PAD 1
+#define SA_NOT_COPY_PAYLOAD 0
+#define SA_COPY_PAYLOAD 1
+#define SA_EXTENDED_SN_OFF 0
+#define SA_EXTENDED_SN_ON 1
+#define SA_SEQ_MASK_OFF 0
+#define SA_SEQ_MASK_ON 1
+
+union sa_command_1 {
+ struct {
+ u32 crypto_mode31:1;
+ u32 save_arc4_state:1;
+ u32 arc4_stateful:1;
+ u32 key_len:5;
+ u32 hash_crypto_offset:8;
+ u32 sa_rev:2;
+ u32 byte_offset:1;
+ u32 hmac_muting:1;
+ u32 feedback_mode:2;
+ u32 crypto_mode9_8:2;
+ u32 extended_seq_num:1;
+ u32 seq_num_mask:1;
+ u32 mutable_bit_proc:1;
+ u32 ip_version:1;
+ u32 copy_pad:1;
+ u32 copy_payload:1;
+ u32 copy_hdr:1;
+ u32 rsv1:1;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+struct dynamic_sa_ctl {
+ u32 sa_contents;
+ union sa_command_0 sa_command_0;
+ union sa_command_1 sa_command_1;
+} __attribute__((packed));
+
+/**
+ * State Record for Security Association (SA)
+ */
+struct sa_state_record {
+ u32 save_iv[4];
+ u32 save_hash_byte_cnt[2];
+ u32 save_digest[16];
+} __attribute__((packed));
+
+/**
+ * Security Association (SA) for AES128
+ *
+ */
+struct dynamic_sa_aes128 {
+ struct dynamic_sa_ctl ctrl;
+ u32 key[4];
+ u32 iv[4]; /* for CBC, OFC, and CFB mode */
+ u32 state_ptr;
+ u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES128_LEN (sizeof(struct dynamic_sa_aes128)/4)
+#define SA_AES128_CONTENTS 0x3e000042
+
+/*
+ * Security Association (SA) for AES192
+ */
+struct dynamic_sa_aes192 {
+ struct dynamic_sa_ctl ctrl;
+ u32 key[6];
+ u32 iv[4]; /* for CBC, OFC, and CFB mode */
+ u32 state_ptr;
+ u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES192_LEN (sizeof(struct dynamic_sa_aes192)/4)
+#define SA_AES192_CONTENTS 0x3e000062
+
+/**
+ * Security Association (SA) for AES256
+ */
+struct dynamic_sa_aes256 {
+ struct dynamic_sa_ctl ctrl;
+ u32 key[8];
+ u32 iv[4]; /* for CBC, OFC, and CFB mode */
+ u32 state_ptr;
+ u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES256_LEN (sizeof(struct dynamic_sa_aes256)/4)
+#define SA_AES256_CONTENTS 0x3e000082
+#define SA_AES_CONTENTS 0x3e000002
+
+/**
+ * Security Association (SA) for HASH160: HMAC-SHA1
+ */
+struct dynamic_sa_hash160 {
+ struct dynamic_sa_ctl ctrl;
+ u32 inner_digest[5];
+ u32 outer_digest[5];
+ u32 state_ptr;
+ u32 reserved;
+} __attribute__((packed));
+#define SA_HASH160_LEN (sizeof(struct dynamic_sa_hash160)/4)
+#define SA_HASH160_CONTENTS 0x2000a502
+
+#endif
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 2d637e0fbc0..d9e751be8c5 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -457,10 +457,12 @@ static int init_ixp_crypto(void)
if (!ctx_pool) {
goto err;
}
- ret = qmgr_request_queue(SEND_QID, NPE_QLEN_TOTAL, 0, 0);
+ ret = qmgr_request_queue(SEND_QID, NPE_QLEN_TOTAL, 0, 0,
+ "ixp_crypto:out", NULL);
if (ret)
goto err;
- ret = qmgr_request_queue(RECV_QID, NPE_QLEN, 0, 0);
+ ret = qmgr_request_queue(RECV_QID, NPE_QLEN, 0, 0,
+ "ixp_crypto:in", NULL);
if (ret) {
qmgr_release_queue(SEND_QID);
goto err;
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 856b3cc2558..3f0fdd18255 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -489,4 +489,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algorithm support");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michal Ludvig");
-MODULE_ALIAS("aes");
+MODULE_ALIAS("aes-all");
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
index a7fbadebf62..a2c8e8514b6 100644
--- a/drivers/crypto/padlock-sha.c
+++ b/drivers/crypto/padlock-sha.c
@@ -304,7 +304,7 @@ MODULE_DESCRIPTION("VIA PadLock SHA1/SHA256 algorithms support.");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michal Ludvig");
-MODULE_ALIAS("sha1");
-MODULE_ALIAS("sha256");
+MODULE_ALIAS("sha1-all");
+MODULE_ALIAS("sha256-all");
MODULE_ALIAS("sha1-padlock");
MODULE_ALIAS("sha256-padlock");
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
index 55433849bfa..25b743abfb5 100644
--- a/drivers/dca/dca-core.c
+++ b/drivers/dca/dca-core.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -28,7 +28,7 @@
#include <linux/device.h>
#include <linux/dca.h>
-#define DCA_VERSION "1.4"
+#define DCA_VERSION "1.8"
MODULE_VERSION(DCA_VERSION);
MODULE_LICENSE("GPL");
@@ -60,16 +60,17 @@ int dca_add_requester(struct device *dev)
{
struct dca_provider *dca;
int err, slot = -ENODEV;
+ unsigned long flags;
if (!dev)
return -EFAULT;
- spin_lock(&dca_lock);
+ spin_lock_irqsave(&dca_lock, flags);
/* check if the requester has not been added already */
dca = dca_find_provider_by_dev(dev);
if (dca) {
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
return -EEXIST;
}
@@ -78,19 +79,21 @@ int dca_add_requester(struct device *dev)
if (slot >= 0)
break;
}
- if (slot < 0) {
- spin_unlock(&dca_lock);
+
+ spin_unlock_irqrestore(&dca_lock, flags);
+
+ if (slot < 0)
return slot;
- }
err = dca_sysfs_add_req(dca, dev, slot);
if (err) {
- dca->ops->remove_requester(dca, dev);
- spin_unlock(&dca_lock);
+ spin_lock_irqsave(&dca_lock, flags);
+ if (dca == dca_find_provider_by_dev(dev))
+ dca->ops->remove_requester(dca, dev);
+ spin_unlock_irqrestore(&dca_lock, flags);
return err;
}
- spin_unlock(&dca_lock);
return 0;
}
EXPORT_SYMBOL_GPL(dca_add_requester);
@@ -103,25 +106,25 @@ int dca_remove_requester(struct device *dev)
{
struct dca_provider *dca;
int slot;
+ unsigned long flags;
if (!dev)
return -EFAULT;
- spin_lock(&dca_lock);
+ spin_lock_irqsave(&dca_lock, flags);
dca = dca_find_provider_by_dev(dev);
if (!dca) {
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
return -ENODEV;
}
slot = dca->ops->remove_requester(dca, dev);
- if (slot < 0) {
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
+
+ if (slot < 0)
return slot;
- }
dca_sysfs_remove_req(dca, slot);
- spin_unlock(&dca_lock);
return 0;
}
EXPORT_SYMBOL_GPL(dca_remove_requester);
@@ -135,17 +138,18 @@ u8 dca_common_get_tag(struct device *dev, int cpu)
{
struct dca_provider *dca;
u8 tag;
+ unsigned long flags;
- spin_lock(&dca_lock);
+ spin_lock_irqsave(&dca_lock, flags);
dca = dca_find_provider_by_dev(dev);
if (!dca) {
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
return -ENODEV;
}
tag = dca->ops->get_tag(dca, dev, cpu);
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
return tag;
}
@@ -217,11 +221,16 @@ static BLOCKING_NOTIFIER_HEAD(dca_provider_chain);
int register_dca_provider(struct dca_provider *dca, struct device *dev)
{
int err;
+ unsigned long flags;
err = dca_sysfs_add_provider(dca, dev);
if (err)
return err;
+
+ spin_lock_irqsave(&dca_lock, flags);
list_add(&dca->node, &dca_providers);
+ spin_unlock_irqrestore(&dca_lock, flags);
+
blocking_notifier_call_chain(&dca_provider_chain,
DCA_PROVIDER_ADD, NULL);
return 0;
@@ -234,9 +243,15 @@ EXPORT_SYMBOL_GPL(register_dca_provider);
*/
void unregister_dca_provider(struct dca_provider *dca)
{
+ unsigned long flags;
+
blocking_notifier_call_chain(&dca_provider_chain,
DCA_PROVIDER_REMOVE, NULL);
+
+ spin_lock_irqsave(&dca_lock, flags);
list_del(&dca->node);
+ spin_unlock_irqrestore(&dca_lock, flags);
+
dca_sysfs_remove_provider(dca);
}
EXPORT_SYMBOL_GPL(unregister_dca_provider);
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
index bb538b9690e..ee916c9857e 100644
--- a/drivers/dca/dca-sysfs.c
+++ b/drivers/dca/dca-sysfs.c
@@ -1,3 +1,24 @@
+/*
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/device.h>
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index 10c3c498358..55dd88d82d6 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -182,7 +182,7 @@ static int __init dio_init(void)
/* Initialize the DIO bus */
INIT_LIST_HEAD(&dio_bus.devices);
- strcpy(dio_bus.dev.bus_id, "dio");
+ dev_set_name(&dio_bus.dev, "dio");
error = device_register(&dio_bus.dev);
if (error) {
pr_err("DIO: Error registering dio_bus\n");
@@ -237,7 +237,7 @@ static int __init dio_init(void)
dev->scode = scode;
dev->resource.start = pa;
dev->resource.end = pa + DIO_SIZE(scode, va);
- sprintf(dev->dev.bus_id,"%02x", scode);
+ dev_set_name(&dev->dev, "%02x", scode);
/* read the ID byte(s) and encode if necessary. */
prid = DIO_ID(va);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index e34b0642081..48ea59e7967 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -62,6 +62,25 @@ config MV_XOR
---help---
Enable support for the Marvell XOR engine.
+config MX3_IPU
+ bool "MX3x Image Processing Unit support"
+ depends on ARCH_MX3
+ select DMA_ENGINE
+ default y
+ help
+ If you plan to use the Image Processing unit in the i.MX3x, say
+ Y here. If unsure, select Y.
+
+config MX3_IPU_IRQS
+ int "Number of dynamically mapped interrupts for IPU"
+ depends on MX3_IPU
+ range 2 137
+ default 4
+ help
+ Out of 137 interrupt sources on i.MX31 IPU only very few are used.
+ To avoid bloating the irq_desc[] array we allocate a sufficient
+ number of IRQ slots and map them dynamically to specific sources.
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 14f59527d4f..2e5dc96700d 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
obj-$(CONFIG_FSL_DMA) += fsldma.o
obj-$(CONFIG_MV_XOR) += mv_xor.o
obj-$(CONFIG_DW_DMAC) += dw_dmac.o
+obj-$(CONFIG_MX3_IPU) += ipu/
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 403dbe78112..280a9d263eb 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -329,9 +329,6 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
struct dma_chan *chan;
int cpu;
- WARN_ONCE(dmaengine_ref_count == 0,
- "client called %s without a reference", __func__);
-
cpu = get_cpu();
chan = per_cpu_ptr(channel_table[tx_type], cpu)->chan;
put_cpu();
@@ -348,9 +345,6 @@ void dma_issue_pending_all(void)
struct dma_device *device;
struct dma_chan *chan;
- WARN_ONCE(dmaengine_ref_count == 0,
- "client called %s without a reference", __func__);
-
rcu_read_lock();
list_for_each_entry_rcu(device, &dma_device_list, global_node) {
if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
@@ -524,6 +518,7 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
dma_chan_name(chan), err);
else
break;
+ chan->private = NULL;
chan = NULL;
}
}
@@ -542,6 +537,7 @@ void dma_release_channel(struct dma_chan *chan)
WARN_ONCE(chan->client_count != 1,
"chan reference count %d != 1\n", chan->client_count);
dma_chan_put(chan);
+ chan->private = NULL;
mutex_unlock(&dma_list_mutex);
}
EXPORT_SYMBOL_GPL(dma_release_channel);
@@ -961,6 +957,8 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx)
if (!dep)
return;
+ /* we'll submit tx->next now, so clear the link */
+ tx->next = NULL;
chan = dep->chan;
/* keep submitting up until a channel switch is detected
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 3603f1ea5b2..e190d8b3070 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -217,6 +217,10 @@ static int dmatest_func(void *data)
chan = thread->chan;
while (!kthread_should_stop()) {
+ struct dma_device *dev = chan->device;
+ struct dma_async_tx_descriptor *tx;
+ dma_addr_t dma_src, dma_dest;
+
total_tests++;
len = dmatest_random() % test_buf_size + 1;
@@ -226,10 +230,30 @@ static int dmatest_func(void *data)
dmatest_init_srcbuf(thread->srcbuf, src_off, len);
dmatest_init_dstbuf(thread->dstbuf, dst_off, len);
- cookie = dma_async_memcpy_buf_to_buf(chan,
- thread->dstbuf + dst_off,
- thread->srcbuf + src_off,
- len);
+ dma_src = dma_map_single(dev->dev, thread->srcbuf + src_off,
+ len, DMA_TO_DEVICE);
+ /* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
+ dma_dest = dma_map_single(dev->dev, thread->dstbuf,
+ test_buf_size, DMA_BIDIRECTIONAL);
+
+ tx = dev->device_prep_dma_memcpy(chan, dma_dest + dst_off,
+ dma_src, len,
+ DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP);
+ if (!tx) {
+ dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
+ dma_unmap_single(dev->dev, dma_dest,
+ test_buf_size, DMA_BIDIRECTIONAL);
+ pr_warning("%s: #%u: prep error with src_off=0x%x "
+ "dst_off=0x%x len=0x%x\n",
+ thread_name, total_tests - 1,
+ src_off, dst_off, len);
+ msleep(100);
+ failed_tests++;
+ continue;
+ }
+ tx->callback = NULL;
+ cookie = tx->tx_submit(tx);
+
if (dma_submit_error(cookie)) {
pr_warning("%s: #%u: submit error %d with src_off=0x%x "
"dst_off=0x%x len=0x%x\n",
@@ -253,6 +277,9 @@ static int dmatest_func(void *data)
failed_tests++;
continue;
}
+ /* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
+ dma_unmap_single(dev->dev, dma_dest,
+ test_buf_size, DMA_BIDIRECTIONAL);
error_count = 0;
@@ -403,13 +430,15 @@ late_initcall(dmatest_init);
static void __exit dmatest_exit(void)
{
struct dmatest_chan *dtc, *_dtc;
+ struct dma_chan *chan;
list_for_each_entry_safe(dtc, _dtc, &dmatest_channels, node) {
list_del(&dtc->node);
+ chan = dtc->chan;
dmatest_cleanup_channel(dtc);
pr_debug("dmatest: dropped channel %s\n",
- dma_chan_name(dtc->chan));
- dma_release_channel(dtc->chan);
+ dma_chan_name(chan));
+ dma_release_channel(chan);
}
}
module_exit(dmatest_exit);
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 6b702cc46b3..20ad3d26bec 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -560,7 +560,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
unsigned long flags)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
- struct dw_dma_slave *dws = dwc->dws;
+ struct dw_dma_slave *dws = chan->private;
struct dw_desc *prev;
struct dw_desc *first;
u32 ctllo;
@@ -790,7 +790,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
cfghi = DWC_CFGH_FIFO_MODE;
cfglo = 0;
- dws = dwc->dws;
+ dws = chan->private;
if (dws) {
/*
* We need controller-specific data to set up slave
@@ -866,7 +866,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
spin_lock_bh(&dwc->lock);
list_splice_init(&dwc->free_list, &list);
dwc->descs_allocated = 0;
- dwc->dws = NULL;
/* Disable interrupts */
channel_clear_bit(dw, MASK.XFER, dwc->mask);
@@ -1012,7 +1011,7 @@ static int __init dw_probe(struct platform_device *pdev)
dma_writel(dw, CFG, DW_CFG_DMA_EN);
printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
- pdev->dev.bus_id, dw->dma.chancnt);
+ dev_name(&pdev->dev), dw->dma.chancnt);
dma_async_device_register(&dw->dma);
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index 00fdd187bb0..b252b202c5c 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -139,8 +139,6 @@ struct dw_dma_chan {
struct list_head queue;
struct list_head free_list;
- struct dw_dma_slave *dws;
-
unsigned int descs_allocated;
};
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index ca70a21afc6..86d6da47f55 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -158,7 +158,8 @@ static void dma_start(struct fsl_dma_chan *fsl_chan)
static void dma_halt(struct fsl_dma_chan *fsl_chan)
{
- int i = 0;
+ int i;
+
DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | FSL_DMA_MR_CA,
32);
@@ -166,8 +167,11 @@ static void dma_halt(struct fsl_dma_chan *fsl_chan)
DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & ~(FSL_DMA_MR_CS
| FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA), 32);
- while (!dma_is_idle(fsl_chan) && (i++ < 100))
+ for (i = 0; i < 100; i++) {
+ if (dma_is_idle(fsl_chan))
+ break;
udelay(10);
+ }
if (i >= 100 && !dma_is_idle(fsl_chan))
dev_err(fsl_chan->dev, "DMA halt timeout!\n");
}
@@ -822,7 +826,7 @@ static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,
*/
WARN_ON(fdev->feature != new_fsl_chan->feature);
- new_fsl_chan->dev = &new_fsl_chan->common.dev->device;
+ new_fsl_chan->dev = fdev->dev;
new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,
new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
@@ -875,7 +879,8 @@ static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,
}
dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
- compatible, new_fsl_chan->irq);
+ compatible,
+ new_fsl_chan->irq != NO_IRQ ? new_fsl_chan->irq : fdev->irq);
return 0;
@@ -890,7 +895,8 @@ err_no_reg:
static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan)
{
- free_irq(fchan->irq, fchan);
+ if (fchan->irq != NO_IRQ)
+ free_irq(fchan->irq, fchan);
list_del(&fchan->common.device_node);
iounmap(fchan->reg_base);
kfree(fchan);
diff --git a/drivers/dma/ioat.c b/drivers/dma/ioat.c
index 4105d6575b6..ed83dd9df19 100644
--- a/drivers/dma/ioat.c
+++ b/drivers/dma/ioat.c
@@ -1,6 +1,6 @@
/*
* Intel I/OAT DMA Linux driver
- * Copyright(c) 2007 Intel Corporation.
+ * Copyright(c) 2007 - 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,
diff --git a/drivers/dma/ioat_dca.c b/drivers/dma/ioat_dca.c
index 6cf622da028..c012a1e1504 100644
--- a/drivers/dma/ioat_dca.c
+++ b/drivers/dma/ioat_dca.c
@@ -1,6 +1,6 @@
/*
* Intel I/OAT DMA Linux driver
- * Copyright(c) 2007 Intel Corporation.
+ * Copyright(c) 2007 - 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,
@@ -49,6 +49,23 @@
#define DCA_TAG_MAP_MASK 0xDF
+/* expected tag map bytes for I/OAT ver.2 */
+#define DCA2_TAG_MAP_BYTE0 0x80
+#define DCA2_TAG_MAP_BYTE1 0x0
+#define DCA2_TAG_MAP_BYTE2 0x81
+#define DCA2_TAG_MAP_BYTE3 0x82
+#define DCA2_TAG_MAP_BYTE4 0x82
+
+/* verify if tag map matches expected values */
+static inline int dca2_tag_map_valid(u8 *tag_map)
+{
+ return ((tag_map[0] == DCA2_TAG_MAP_BYTE0) &&
+ (tag_map[1] == DCA2_TAG_MAP_BYTE1) &&
+ (tag_map[2] == DCA2_TAG_MAP_BYTE2) &&
+ (tag_map[3] == DCA2_TAG_MAP_BYTE3) &&
+ (tag_map[4] == DCA2_TAG_MAP_BYTE4));
+}
+
/*
* "Legacy" DCA systems do not implement the DCA register set in the
* I/OAT device. Software needs direct support for their tag mappings.
@@ -452,6 +469,13 @@ struct dca_provider *ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase)
ioatdca->tag_map[i] = 0;
}
+ if (!dca2_tag_map_valid(ioatdca->tag_map)) {
+ dev_err(&pdev->dev, "APICID_TAG_MAP set incorrectly by BIOS, "
+ "disabling DCA\n");
+ free_dca_provider(dca);
+ return NULL;
+ }
+
err = register_dca_provider(dca, &pdev->dev);
if (err) {
free_dca_provider(dca);
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index b3759c4b653..5905cd36bcd 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -1,6 +1,6 @@
/*
* Intel I/OAT DMA Linux driver
- * Copyright(c) 2004 - 2007 Intel Corporation.
+ * Copyright(c) 2004 - 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,
@@ -189,11 +189,13 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
ioat_chan->xfercap = xfercap;
ioat_chan->desccount = 0;
INIT_DELAYED_WORK(&ioat_chan->work, ioat_dma_chan_reset_part2);
- if (ioat_chan->device->version != IOAT_VER_1_2) {
- writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE
- | IOAT_DMA_DCA_ANY_CPU,
- ioat_chan->reg_base + IOAT_DCACTRL_OFFSET);
- }
+ if (ioat_chan->device->version == IOAT_VER_2_0)
+ writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE |
+ IOAT_DMA_DCA_ANY_CPU,
+ ioat_chan->reg_base + IOAT_DCACTRL_OFFSET);
+ else if (ioat_chan->device->version == IOAT_VER_3_0)
+ writel(IOAT_DMA_DCA_ANY_CPU,
+ ioat_chan->reg_base + IOAT_DCACTRL_OFFSET);
spin_lock_init(&ioat_chan->cleanup_lock);
spin_lock_init(&ioat_chan->desc_lock);
INIT_LIST_HEAD(&ioat_chan->free_desc);
@@ -1169,9 +1171,8 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
* up if the client is done with the descriptor
*/
if (async_tx_test_ack(&desc->async_tx)) {
- list_del(&desc->node);
- list_add_tail(&desc->node,
- &ioat_chan->free_desc);
+ list_move_tail(&desc->node,
+ &ioat_chan->free_desc);
} else
desc->async_tx.cookie = 0;
} else {
@@ -1362,6 +1363,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
dma_cookie_t cookie;
int err = 0;
struct completion cmp;
+ unsigned long tmo;
src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
if (!src)
@@ -1413,9 +1415,10 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
}
device->common.device_issue_pending(dma_chan);
- wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));
+ tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));
- if (device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL)
+ if (tmo == 0 ||
+ device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL)
!= DMA_SUCCESS) {
dev_err(&device->pdev->dev,
"Self-test copy timed out, disabling\n");
@@ -1657,6 +1660,13 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
" %d channels, device version 0x%02x, driver version %s\n",
device->common.chancnt, device->version, IOAT_DMA_VERSION);
+ if (!device->common.chancnt) {
+ dev_err(&device->pdev->dev,
+ "Intel(R) I/OAT DMA Engine problem found: "
+ "zero channels detected\n");
+ goto err_setup_interrupts;
+ }
+
err = ioat_dma_setup_interrupts(device);
if (err)
goto err_setup_interrupts;
@@ -1696,6 +1706,9 @@ void ioat_dma_remove(struct ioatdma_device *device)
struct dma_chan *chan, *_chan;
struct ioat_dma_chan *ioat_chan;
+ if (device->version != IOAT_VER_3_0)
+ cancel_delayed_work(&device->work);
+
ioat_dma_remove_interrupts(device);
dma_async_device_unregister(&device->common);
@@ -1707,10 +1720,6 @@ void ioat_dma_remove(struct ioatdma_device *device)
pci_release_regions(device->pdev);
pci_disable_device(device->pdev);
- if (device->version != IOAT_VER_3_0) {
- cancel_delayed_work(&device->work);
- }
-
list_for_each_entry_safe(chan, _chan,
&device->common.channels, device_node) {
ioat_chan = to_ioat_chan(chan);
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h
index a3306d0e137..a52ff4bd460 100644
--- a/drivers/dma/ioatdma.h
+++ b/drivers/dma/ioatdma.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -29,7 +29,7 @@
#include <linux/pci_ids.h>
#include <net/tcp.h>
-#define IOAT_DMA_VERSION "3.30"
+#define IOAT_DMA_VERSION "3.64"
enum ioat_interrupt {
none = 0,
@@ -135,12 +135,14 @@ static inline void ioat_set_tcp_copy_break(struct ioatdma_device *dev)
#ifdef CONFIG_NET_DMA
switch (dev->version) {
case IOAT_VER_1_2:
- case IOAT_VER_3_0:
sysctl_tcp_dma_copybreak = 4096;
break;
case IOAT_VER_2_0:
sysctl_tcp_dma_copybreak = 2048;
break;
+ case IOAT_VER_3_0:
+ sysctl_tcp_dma_copybreak = 262144;
+ break;
}
#endif
}
diff --git a/drivers/dma/ioatdma_hw.h b/drivers/dma/ioatdma_hw.h
index f1ae2c776f7..afa57eef86c 100644
--- a/drivers/dma/ioatdma_hw.h
+++ b/drivers/dma/ioatdma_hw.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/drivers/dma/ioatdma_registers.h b/drivers/dma/ioatdma_registers.h
index 827cb503cac..49bc277424f 100644
--- a/drivers/dma/ioatdma_registers.h
+++ b/drivers/dma/ioatdma_registers.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index ea5440dd10d..16adbe61cfb 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -928,19 +928,19 @@ iop_adma_xor_zero_sum_self_test(struct iop_adma_device *device)
for (src_idx = 0; src_idx < IOP_ADMA_NUM_SRC_TEST; src_idx++) {
xor_srcs[src_idx] = alloc_page(GFP_KERNEL);
- if (!xor_srcs[src_idx])
- while (src_idx--) {
+ if (!xor_srcs[src_idx]) {
+ while (src_idx--)
__free_page(xor_srcs[src_idx]);
- return -ENOMEM;
- }
+ return -ENOMEM;
+ }
}
dest = alloc_page(GFP_KERNEL);
- if (!dest)
- while (src_idx--) {
+ if (!dest) {
+ while (src_idx--)
__free_page(xor_srcs[src_idx]);
- return -ENOMEM;
- }
+ return -ENOMEM;
+ }
/* Fill in src buffers */
for (src_idx = 0; src_idx < IOP_ADMA_NUM_SRC_TEST; src_idx++) {
@@ -1401,7 +1401,7 @@ MODULE_ALIAS("platform:iop-adma");
static struct platform_driver iop_adma_driver = {
.probe = iop_adma_probe,
- .remove = iop_adma_remove,
+ .remove = __devexit_p(iop_adma_remove),
.driver = {
.owner = THIS_MODULE,
.name = "iop-adma",
diff --git a/drivers/dma/ipu/Makefile b/drivers/dma/ipu/Makefile
new file mode 100644
index 00000000000..6704cf48326
--- /dev/null
+++ b/drivers/dma/ipu/Makefile
@@ -0,0 +1 @@
+obj-y += ipu_irq.o ipu_idmac.o
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
new file mode 100644
index 00000000000..ae50a9d1a4e
--- /dev/null
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -0,0 +1,1740 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * Copyright (C) 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <mach/ipu.h>
+
+#include "ipu_intern.h"
+
+#define FS_VF_IN_VALID 0x00000002
+#define FS_ENC_IN_VALID 0x00000001
+
+/*
+ * There can be only one, we could allocate it dynamically, but then we'd have
+ * to add an extra parameter to some functions, and use something as ugly as
+ * struct ipu *ipu = to_ipu(to_idmac(ichan->dma_chan.device));
+ * in the ISR
+ */
+static struct ipu ipu_data;
+
+#define to_ipu(id) container_of(id, struct ipu, idmac)
+
+static u32 __idmac_read_icreg(struct ipu *ipu, unsigned long reg)
+{
+ return __raw_readl(ipu->reg_ic + reg);
+}
+
+#define idmac_read_icreg(ipu, reg) __idmac_read_icreg(ipu, reg - IC_CONF)
+
+static void __idmac_write_icreg(struct ipu *ipu, u32 value, unsigned long reg)
+{
+ __raw_writel(value, ipu->reg_ic + reg);
+}
+
+#define idmac_write_icreg(ipu, v, reg) __idmac_write_icreg(ipu, v, reg - IC_CONF)
+
+static u32 idmac_read_ipureg(struct ipu *ipu, unsigned long reg)
+{
+ return __raw_readl(ipu->reg_ipu + reg);
+}
+
+static void idmac_write_ipureg(struct ipu *ipu, u32 value, unsigned long reg)
+{
+ __raw_writel(value, ipu->reg_ipu + reg);
+}
+
+/*****************************************************************************
+ * IPU / IC common functions
+ */
+static void dump_idmac_reg(struct ipu *ipu)
+{
+ dev_dbg(ipu->dev, "IDMAC_CONF 0x%x, IC_CONF 0x%x, IDMAC_CHA_EN 0x%x, "
+ "IDMAC_CHA_PRI 0x%x, IDMAC_CHA_BUSY 0x%x\n",
+ idmac_read_icreg(ipu, IDMAC_CONF),
+ idmac_read_icreg(ipu, IC_CONF),
+ idmac_read_icreg(ipu, IDMAC_CHA_EN),
+ idmac_read_icreg(ipu, IDMAC_CHA_PRI),
+ idmac_read_icreg(ipu, IDMAC_CHA_BUSY));
+ dev_dbg(ipu->dev, "BUF0_RDY 0x%x, BUF1_RDY 0x%x, CUR_BUF 0x%x, "
+ "DB_MODE 0x%x, TASKS_STAT 0x%x\n",
+ idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY),
+ idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY),
+ idmac_read_ipureg(ipu, IPU_CHA_CUR_BUF),
+ idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL),
+ idmac_read_ipureg(ipu, IPU_TASKS_STAT));
+}
+
+static uint32_t bytes_per_pixel(enum pixel_fmt fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_GENERIC: /* generic data */
+ case IPU_PIX_FMT_RGB332:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YUV422P:
+ default:
+ return 1;
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_UYVY:
+ return 2;
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ return 3;
+ case IPU_PIX_FMT_GENERIC_32: /* generic data */
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_ABGR32:
+ return 4;
+ }
+}
+
+/* Enable / disable direct write to memory by the Camera Sensor Interface */
+static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
+{
+ uint32_t ic_conf, mask;
+
+ switch (channel) {
+ case IDMAC_IC_0:
+ mask = IC_CONF_PRPENC_EN;
+ break;
+ case IDMAC_IC_7:
+ mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
+ break;
+ default:
+ return;
+ }
+ ic_conf = idmac_read_icreg(ipu, IC_CONF) | mask;
+ idmac_write_icreg(ipu, ic_conf, IC_CONF);
+}
+
+static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
+{
+ uint32_t ic_conf, mask;
+
+ switch (channel) {
+ case IDMAC_IC_0:
+ mask = IC_CONF_PRPENC_EN;
+ break;
+ case IDMAC_IC_7:
+ mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
+ break;
+ default:
+ return;
+ }
+ ic_conf = idmac_read_icreg(ipu, IC_CONF) & ~mask;
+ idmac_write_icreg(ipu, ic_conf, IC_CONF);
+}
+
+static uint32_t ipu_channel_status(struct ipu *ipu, enum ipu_channel channel)
+{
+ uint32_t stat = TASK_STAT_IDLE;
+ uint32_t task_stat_reg = idmac_read_ipureg(ipu, IPU_TASKS_STAT);
+
+ switch (channel) {
+ case IDMAC_IC_7:
+ stat = (task_stat_reg & TSTAT_CSI2MEM_MASK) >>
+ TSTAT_CSI2MEM_OFFSET;
+ break;
+ case IDMAC_IC_0:
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ default:
+ break;
+ }
+ return stat;
+}
+
+struct chan_param_mem_planar {
+ /* Word 0 */
+ u32 xv:10;
+ u32 yv:10;
+ u32 xb:12;
+
+ u32 yb:12;
+ u32 res1:2;
+ u32 nsb:1;
+ u32 lnpb:6;
+ u32 ubo_l:11;
+
+ u32 ubo_h:15;
+ u32 vbo_l:17;
+
+ u32 vbo_h:9;
+ u32 res2:3;
+ u32 fw:12;
+ u32 fh_l:8;
+
+ u32 fh_h:4;
+ u32 res3:28;
+
+ /* Word 1 */
+ u32 eba0;
+
+ u32 eba1;
+
+ u32 bpp:3;
+ u32 sl:14;
+ u32 pfs:3;
+ u32 bam:3;
+ u32 res4:2;
+ u32 npb:6;
+ u32 res5:1;
+
+ u32 sat:2;
+ u32 res6:30;
+} __attribute__ ((packed));
+
+struct chan_param_mem_interleaved {
+ /* Word 0 */
+ u32 xv:10;
+ u32 yv:10;
+ u32 xb:12;
+
+ u32 yb:12;
+ u32 sce:1;
+ u32 res1:1;
+ u32 nsb:1;
+ u32 lnpb:6;
+ u32 sx:10;
+ u32 sy_l:1;
+
+ u32 sy_h:9;
+ u32 ns:10;
+ u32 sm:10;
+ u32 sdx_l:3;
+
+ u32 sdx_h:2;
+ u32 sdy:5;
+ u32 sdrx:1;
+ u32 sdry:1;
+ u32 sdr1:1;
+ u32 res2:2;
+ u32 fw:12;
+ u32 fh_l:8;
+
+ u32 fh_h:4;
+ u32 res3:28;
+
+ /* Word 1 */
+ u32 eba0;
+
+ u32 eba1;
+
+ u32 bpp:3;
+ u32 sl:14;
+ u32 pfs:3;
+ u32 bam:3;
+ u32 res4:2;
+ u32 npb:6;
+ u32 res5:1;
+
+ u32 sat:2;
+ u32 scc:1;
+ u32 ofs0:5;
+ u32 ofs1:5;
+ u32 ofs2:5;
+ u32 ofs3:5;
+ u32 wid0:3;
+ u32 wid1:3;
+ u32 wid2:3;
+
+ u32 wid3:3;
+ u32 dec_sel:1;
+ u32 res6:28;
+} __attribute__ ((packed));
+
+union chan_param_mem {
+ struct chan_param_mem_planar pp;
+ struct chan_param_mem_interleaved ip;
+};
+
+static void ipu_ch_param_set_plane_offset(union chan_param_mem *params,
+ u32 u_offset, u32 v_offset)
+{
+ params->pp.ubo_l = u_offset & 0x7ff;
+ params->pp.ubo_h = u_offset >> 11;
+ params->pp.vbo_l = v_offset & 0x1ffff;
+ params->pp.vbo_h = v_offset >> 17;
+}
+
+static void ipu_ch_param_set_size(union chan_param_mem *params,
+ uint32_t pixel_fmt, uint16_t width,
+ uint16_t height, uint16_t stride)
+{
+ u32 u_offset;
+ u32 v_offset;
+
+ params->pp.fw = width - 1;
+ params->pp.fh_l = height - 1;
+ params->pp.fh_h = (height - 1) >> 8;
+ params->pp.sl = stride - 1;
+
+ switch (pixel_fmt) {
+ case IPU_PIX_FMT_GENERIC:
+ /*Represents 8-bit Generic data */
+ params->pp.bpp = 3;
+ params->pp.pfs = 7;
+ params->pp.npb = 31;
+ params->pp.sat = 2; /* SAT = use 32-bit access */
+ break;
+ case IPU_PIX_FMT_GENERIC_32:
+ /*Represents 32-bit Generic data */
+ params->pp.bpp = 0;
+ params->pp.pfs = 7;
+ params->pp.npb = 7;
+ params->pp.sat = 2; /* SAT = use 32-bit access */
+ break;
+ case IPU_PIX_FMT_RGB565:
+ params->ip.bpp = 2;
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 0; /* Red bit offset */
+ params->ip.ofs1 = 5; /* Green bit offset */
+ params->ip.ofs2 = 11; /* Blue bit offset */
+ params->ip.ofs3 = 16; /* Alpha bit offset */
+ params->ip.wid0 = 4; /* Red bit width - 1 */
+ params->ip.wid1 = 5; /* Green bit width - 1 */
+ params->ip.wid2 = 4; /* Blue bit width - 1 */
+ break;
+ case IPU_PIX_FMT_BGR24:
+ params->ip.bpp = 1; /* 24 BPP & RGB PFS */
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 0; /* Red bit offset */
+ params->ip.ofs1 = 8; /* Green bit offset */
+ params->ip.ofs2 = 16; /* Blue bit offset */
+ params->ip.ofs3 = 24; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ break;
+ case IPU_PIX_FMT_RGB24:
+ params->ip.bpp = 1; /* 24 BPP & RGB PFS */
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 16; /* Red bit offset */
+ params->ip.ofs1 = 8; /* Green bit offset */
+ params->ip.ofs2 = 0; /* Blue bit offset */
+ params->ip.ofs3 = 24; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ break;
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_BGR32:
+ params->ip.bpp = 0;
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 8; /* Red bit offset */
+ params->ip.ofs1 = 16; /* Green bit offset */
+ params->ip.ofs2 = 24; /* Blue bit offset */
+ params->ip.ofs3 = 0; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ params->ip.wid3 = 7; /* Alpha bit width - 1 */
+ break;
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_RGB32:
+ params->ip.bpp = 0;
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 24; /* Red bit offset */
+ params->ip.ofs1 = 16; /* Green bit offset */
+ params->ip.ofs2 = 8; /* Blue bit offset */
+ params->ip.ofs3 = 0; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ params->ip.wid3 = 7; /* Alpha bit width - 1 */
+ break;
+ case IPU_PIX_FMT_ABGR32:
+ params->ip.bpp = 0;
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 8; /* Red bit offset */
+ params->ip.ofs1 = 16; /* Green bit offset */
+ params->ip.ofs2 = 24; /* Blue bit offset */
+ params->ip.ofs3 = 0; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ params->ip.wid3 = 7; /* Alpha bit width - 1 */
+ break;
+ case IPU_PIX_FMT_UYVY:
+ params->ip.bpp = 2;
+ params->ip.pfs = 6;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ break;
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ params->ip.bpp = 3;
+ params->ip.pfs = 3;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ u_offset = stride * height;
+ v_offset = u_offset + u_offset / 4;
+ ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
+ break;
+ case IPU_PIX_FMT_YVU422P:
+ params->ip.bpp = 3;
+ params->ip.pfs = 2;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ v_offset = stride * height;
+ u_offset = v_offset + v_offset / 2;
+ ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
+ break;
+ case IPU_PIX_FMT_YUV422P:
+ params->ip.bpp = 3;
+ params->ip.pfs = 2;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ u_offset = stride * height;
+ v_offset = u_offset + u_offset / 2;
+ ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
+ break;
+ default:
+ dev_err(ipu_data.dev,
+ "mxc ipu: unimplemented pixel format %d\n", pixel_fmt);
+ break;
+ }
+
+ params->pp.nsb = 1;
+}
+
+static void ipu_ch_param_set_burst_size(union chan_param_mem *params,
+ uint16_t burst_pixels)
+{
+ params->pp.npb = burst_pixels - 1;
+};
+
+static void ipu_ch_param_set_buffer(union chan_param_mem *params,
+ dma_addr_t buf0, dma_addr_t buf1)
+{
+ params->pp.eba0 = buf0;
+ params->pp.eba1 = buf1;
+};
+
+static void ipu_ch_param_set_rotation(union chan_param_mem *params,
+ enum ipu_rotate_mode rotate)
+{
+ params->pp.bam = rotate;
+};
+
+static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
+ uint32_t num_words)
+{
+ for (; num_words > 0; num_words--) {
+ dev_dbg(ipu_data.dev,
+ "write param mem - addr = 0x%08X, data = 0x%08X\n",
+ addr, *data);
+ idmac_write_ipureg(&ipu_data, addr, IPU_IMA_ADDR);
+ idmac_write_ipureg(&ipu_data, *data++, IPU_IMA_DATA);
+ addr++;
+ if ((addr & 0x7) == 5) {
+ addr &= ~0x7; /* set to word 0 */
+ addr += 8; /* increment to next row */
+ }
+ }
+}
+
+static int calc_resize_coeffs(uint32_t in_size, uint32_t out_size,
+ uint32_t *resize_coeff,
+ uint32_t *downsize_coeff)
+{
+ uint32_t temp_size;
+ uint32_t temp_downsize;
+
+ *resize_coeff = 1 << 13;
+ *downsize_coeff = 1 << 13;
+
+ /* Cannot downsize more than 8:1 */
+ if (out_size << 3 < in_size)
+ return -EINVAL;
+
+ /* compute downsizing coefficient */
+ temp_downsize = 0;
+ temp_size = in_size;
+ while (temp_size >= out_size * 2 && temp_downsize < 2) {
+ temp_size >>= 1;
+ temp_downsize++;
+ }
+ *downsize_coeff = temp_downsize;
+
+ /*
+ * compute resizing coefficient using the following formula:
+ * resize_coeff = M*(SI -1)/(SO - 1)
+ * where M = 2^13, SI - input size, SO - output size
+ */
+ *resize_coeff = (8192L * (temp_size - 1)) / (out_size - 1);
+ if (*resize_coeff >= 16384L) {
+ dev_err(ipu_data.dev, "Warning! Overflow on resize coeff.\n");
+ *resize_coeff = 0x3FFF;
+ }
+
+ dev_dbg(ipu_data.dev, "resizing from %u -> %u pixels, "
+ "downsize=%u, resize=%u.%lu (reg=%u)\n", in_size, out_size,
+ *downsize_coeff, *resize_coeff >= 8192L ? 1 : 0,
+ ((*resize_coeff & 0x1FFF) * 10000L) / 8192L, *resize_coeff);
+
+ return 0;
+}
+
+static enum ipu_color_space format_to_colorspace(enum pixel_fmt fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_RGB32:
+ return IPU_COLORSPACE_RGB;
+ default:
+ return IPU_COLORSPACE_YCBCR;
+ }
+}
+
+static int ipu_ic_init_prpenc(struct ipu *ipu,
+ union ipu_channel_param *params, bool src_is_csi)
+{
+ uint32_t reg, ic_conf;
+ uint32_t downsize_coeff, resize_coeff;
+ enum ipu_color_space in_fmt, out_fmt;
+
+ /* Setup vertical resizing */
+ calc_resize_coeffs(params->video.in_height,
+ params->video.out_height,
+ &resize_coeff, &downsize_coeff);
+ reg = (downsize_coeff << 30) | (resize_coeff << 16);
+
+ /* Setup horizontal resizing */
+ calc_resize_coeffs(params->video.in_width,
+ params->video.out_width,
+ &resize_coeff, &downsize_coeff);
+ reg |= (downsize_coeff << 14) | resize_coeff;
+
+ /* Setup color space conversion */
+ in_fmt = format_to_colorspace(params->video.in_pixel_fmt);
+ out_fmt = format_to_colorspace(params->video.out_pixel_fmt);
+
+ /*
+ * Colourspace conversion unsupported yet - see _init_csc() in
+ * Freescale sources
+ */
+ if (in_fmt != out_fmt) {
+ dev_err(ipu->dev, "Colourspace conversion unsupported!\n");
+ return -EOPNOTSUPP;
+ }
+
+ idmac_write_icreg(ipu, reg, IC_PRP_ENC_RSC);
+
+ ic_conf = idmac_read_icreg(ipu, IC_CONF);
+
+ if (src_is_csi)
+ ic_conf &= ~IC_CONF_RWS_EN;
+ else
+ ic_conf |= IC_CONF_RWS_EN;
+
+ idmac_write_icreg(ipu, ic_conf, IC_CONF);
+
+ return 0;
+}
+
+static uint32_t dma_param_addr(uint32_t dma_ch)
+{
+ /* Channel Parameter Memory */
+ return 0x10000 | (dma_ch << 4);
+};
+
+static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
+ bool prio)
+{
+ u32 reg = idmac_read_icreg(ipu, IDMAC_CHA_PRI);
+
+ if (prio)
+ reg |= 1UL << channel;
+ else
+ reg &= ~(1UL << channel);
+
+ idmac_write_icreg(ipu, reg, IDMAC_CHA_PRI);
+
+ dump_idmac_reg(ipu);
+}
+
+static uint32_t ipu_channel_conf_mask(enum ipu_channel channel)
+{
+ uint32_t mask;
+
+ switch (channel) {
+ case IDMAC_IC_0:
+ case IDMAC_IC_7:
+ mask = IPU_CONF_CSI_EN | IPU_CONF_IC_EN;
+ break;
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ mask = IPU_CONF_SDC_EN | IPU_CONF_DI_EN;
+ break;
+ default:
+ mask = 0;
+ break;
+ }
+
+ return mask;
+}
+
+/**
+ * ipu_enable_channel() - enable an IPU channel.
+ * @channel: channel ID.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
+{
+ struct ipu *ipu = to_ipu(idmac);
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ uint32_t reg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ /* Reset to buffer 0 */
+ idmac_write_ipureg(ipu, 1UL << channel, IPU_CHA_CUR_BUF);
+ ichan->active_buffer = 0;
+ ichan->status = IPU_CHANNEL_ENABLED;
+
+ switch (channel) {
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ case IDMAC_IC_7:
+ ipu_channel_set_priority(ipu, channel, true);
+ default:
+ break;
+ }
+
+ reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
+
+ idmac_write_icreg(ipu, reg | (1UL << channel), IDMAC_CHA_EN);
+
+ ipu_ic_enable_task(ipu, channel);
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+ return 0;
+}
+
+/**
+ * ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
+ * @channel: channel ID.
+ * @pixel_fmt: pixel format of buffer. Pixel format is a FOURCC ASCII code.
+ * @width: width of buffer in pixels.
+ * @height: height of buffer in pixels.
+ * @stride: stride length of buffer in pixels.
+ * @rot_mode: rotation mode of buffer. A rotation setting other than
+ * IPU_ROTATE_VERT_FLIP should only be used for input buffers of
+ * rotation channels.
+ * @phyaddr_0: buffer 0 physical address.
+ * @phyaddr_1: buffer 1 physical address. Setting this to a value other than
+ * NULL enables double buffering mode.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int ipu_init_channel_buffer(struct idmac_channel *ichan,
+ enum pixel_fmt pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ enum ipu_rotate_mode rot_mode,
+ dma_addr_t phyaddr_0, dma_addr_t phyaddr_1)
+{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ struct idmac *idmac = to_idmac(ichan->dma_chan.device);
+ struct ipu *ipu = to_ipu(idmac);
+ union chan_param_mem params = {};
+ unsigned long flags;
+ uint32_t reg;
+ uint32_t stride_bytes;
+
+ stride_bytes = stride * bytes_per_pixel(pixel_fmt);
+
+ if (stride_bytes % 4) {
+ dev_err(ipu->dev,
+ "Stride length must be 32-bit aligned, stride = %d, bytes = %d\n",
+ stride, stride_bytes);
+ return -EINVAL;
+ }
+
+ /* IC channel's stride must be a multiple of 8 pixels */
+ if ((channel <= 13) && (stride % 8)) {
+ dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
+ return -EINVAL;
+ }
+
+ /* Build parameter memory data for DMA channel */
+ ipu_ch_param_set_size(&params, pixel_fmt, width, height, stride_bytes);
+ ipu_ch_param_set_buffer(&params, phyaddr_0, phyaddr_1);
+ ipu_ch_param_set_rotation(&params, rot_mode);
+ /* Some channels (rotation) have restriction on burst length */
+ switch (channel) {
+ case IDMAC_IC_7: /* Hangs with burst 8, 16, other values
+ invalid - Table 44-30 */
+/*
+ ipu_ch_param_set_burst_size(&params, 8);
+ */
+ break;
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ /* In original code only IPU_PIX_FMT_RGB565 was setting burst */
+ ipu_ch_param_set_burst_size(&params, 16);
+ break;
+ case IDMAC_IC_0:
+ default:
+ break;
+ }
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ ipu_write_param_mem(dma_param_addr(channel), (uint32_t *)&params, 10);
+
+ reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL);
+
+ if (phyaddr_1)
+ reg |= 1UL << channel;
+ else
+ reg &= ~(1UL << channel);
+
+ idmac_write_ipureg(ipu, reg, IPU_CHA_DB_MODE_SEL);
+
+ ichan->status = IPU_CHANNEL_READY;
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ return 0;
+}
+
+/**
+ * ipu_select_buffer() - mark a channel's buffer as ready.
+ * @channel: channel ID.
+ * @buffer_n: buffer number to mark ready.
+ */
+static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
+{
+ /* No locking - this is a write-one-to-set register, cleared by IPU */
+ if (buffer_n == 0)
+ /* Mark buffer 0 as ready. */
+ idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF0_RDY);
+ else
+ /* Mark buffer 1 as ready. */
+ idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF1_RDY);
+}
+
+/**
+ * ipu_update_channel_buffer() - update physical address of a channel buffer.
+ * @channel: channel ID.
+ * @buffer_n: buffer number to update.
+ * 0 or 1 are the only valid values.
+ * @phyaddr: buffer physical address.
+ * @return: Returns 0 on success or negative error code on failure. This
+ * function will fail if the buffer is set to ready.
+ */
+/* Called under spin_lock(_irqsave)(&ichan->lock) */
+static int ipu_update_channel_buffer(enum ipu_channel channel,
+ int buffer_n, dma_addr_t phyaddr)
+{
+ uint32_t reg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ipu_data.lock, flags);
+
+ if (buffer_n == 0) {
+ reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
+ if (reg & (1UL << channel)) {
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+ return -EACCES;
+ }
+
+ /* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
+ idmac_write_ipureg(&ipu_data, dma_param_addr(channel) +
+ 0x0008UL, IPU_IMA_ADDR);
+ idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA);
+ } else {
+ reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
+ if (reg & (1UL << channel)) {
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+ return -EACCES;
+ }
+
+ /* Check if double-buffering is already enabled */
+ reg = idmac_read_ipureg(&ipu_data, IPU_CHA_DB_MODE_SEL);
+
+ if (!(reg & (1UL << channel)))
+ idmac_write_ipureg(&ipu_data, reg | (1UL << channel),
+ IPU_CHA_DB_MODE_SEL);
+
+ /* 44.3.3.1.9 - Row Number 1 (WORD1, offset 1) */
+ idmac_write_ipureg(&ipu_data, dma_param_addr(channel) +
+ 0x0009UL, IPU_IMA_ADDR);
+ idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA);
+ }
+
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+
+ return 0;
+}
+
+/* Called under spin_lock_irqsave(&ichan->lock) */
+static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
+ struct idmac_tx_desc *desc)
+{
+ struct scatterlist *sg;
+ int i, ret = 0;
+
+ for (i = 0, sg = desc->sg; i < 2 && sg; i++) {
+ if (!ichan->sg[i]) {
+ ichan->sg[i] = sg;
+
+ /*
+ * On first invocation this shouldn't be necessary, the
+ * call to ipu_init_channel_buffer() above will set
+ * addresses for us, so we could make it conditional
+ * on status >= IPU_CHANNEL_ENABLED, but doing it again
+ * shouldn't hurt either.
+ */
+ ret = ipu_update_channel_buffer(ichan->dma_chan.chan_id, i,
+ sg_dma_address(sg));
+ if (ret < 0)
+ return ret;
+
+ ipu_select_buffer(ichan->dma_chan.chan_id, i);
+
+ sg = sg_next(sg);
+ }
+ }
+
+ return ret;
+}
+
+static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct idmac_tx_desc *desc = to_tx_desc(tx);
+ struct idmac_channel *ichan = to_idmac_chan(tx->chan);
+ struct idmac *idmac = to_idmac(tx->chan->device);
+ struct ipu *ipu = to_ipu(idmac);
+ dma_cookie_t cookie;
+ unsigned long flags;
+
+ /* Sanity check */
+ if (!list_empty(&desc->list)) {
+ /* The descriptor doesn't belong to client */
+ dev_err(&ichan->dma_chan.dev->device,
+ "Descriptor %p not prepared!\n", tx);
+ return -EBUSY;
+ }
+
+ mutex_lock(&ichan->chan_mutex);
+
+ if (ichan->status < IPU_CHANNEL_READY) {
+ struct idmac_video_param *video = &ichan->params.video;
+ /*
+ * Initial buffer assignment - the first two sg-entries from
+ * the descriptor will end up in the IDMAC buffers
+ */
+ dma_addr_t dma_1 = sg_is_last(desc->sg) ? 0 :
+ sg_dma_address(&desc->sg[1]);
+
+ WARN_ON(ichan->sg[0] || ichan->sg[1]);
+
+ cookie = ipu_init_channel_buffer(ichan,
+ video->out_pixel_fmt,
+ video->out_width,
+ video->out_height,
+ video->out_stride,
+ IPU_ROTATE_NONE,
+ sg_dma_address(&desc->sg[0]),
+ dma_1);
+ if (cookie < 0)
+ goto out;
+ }
+
+ /* ipu->lock can be taken under ichan->lock, but not v.v. */
+ spin_lock_irqsave(&ichan->lock, flags);
+
+ /* submit_buffers() atomically verifies and fills empty sg slots */
+ cookie = ipu_submit_channel_buffers(ichan, desc);
+
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ if (cookie < 0)
+ goto out;
+
+ cookie = ichan->dma_chan.cookie;
+
+ if (++cookie < 0)
+ cookie = 1;
+
+ /* from dmaengine.h: "last cookie value returned to client" */
+ ichan->dma_chan.cookie = cookie;
+ tx->cookie = cookie;
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_add_tail(&desc->list, &ichan->queue);
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ if (ichan->status < IPU_CHANNEL_ENABLED) {
+ int ret = ipu_enable_channel(idmac, ichan);
+ if (ret < 0) {
+ cookie = ret;
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_del_init(&desc->list);
+ spin_unlock_irqrestore(&ichan->lock, flags);
+ tx->cookie = cookie;
+ ichan->dma_chan.cookie = cookie;
+ }
+ }
+
+ dump_idmac_reg(ipu);
+
+out:
+ mutex_unlock(&ichan->chan_mutex);
+
+ return cookie;
+}
+
+/* Called with ichan->chan_mutex held */
+static int idmac_desc_alloc(struct idmac_channel *ichan, int n)
+{
+ struct idmac_tx_desc *desc = vmalloc(n * sizeof(struct idmac_tx_desc));
+ struct idmac *idmac = to_idmac(ichan->dma_chan.device);
+
+ if (!desc)
+ return -ENOMEM;
+
+ /* No interrupts, just disable the tasklet for a moment */
+ tasklet_disable(&to_ipu(idmac)->tasklet);
+
+ ichan->n_tx_desc = n;
+ ichan->desc = desc;
+ INIT_LIST_HEAD(&ichan->queue);
+ INIT_LIST_HEAD(&ichan->free_list);
+
+ while (n--) {
+ struct dma_async_tx_descriptor *txd = &desc->txd;
+
+ memset(txd, 0, sizeof(*txd));
+ dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
+ txd->tx_submit = idmac_tx_submit;
+ txd->chan = &ichan->dma_chan;
+ INIT_LIST_HEAD(&txd->tx_list);
+
+ list_add(&desc->list, &ichan->free_list);
+
+ desc++;
+ }
+
+ tasklet_enable(&to_ipu(idmac)->tasklet);
+
+ return 0;
+}
+
+/**
+ * ipu_init_channel() - initialize an IPU channel.
+ * @idmac: IPU DMAC context.
+ * @ichan: pointer to the channel object.
+ * @return 0 on success or negative error code on failure.
+ */
+static int ipu_init_channel(struct idmac *idmac, struct idmac_channel *ichan)
+{
+ union ipu_channel_param *params = &ichan->params;
+ uint32_t ipu_conf;
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ unsigned long flags;
+ uint32_t reg;
+ struct ipu *ipu = to_ipu(idmac);
+ int ret = 0, n_desc = 0;
+
+ dev_dbg(ipu->dev, "init channel = %d\n", channel);
+
+ if (channel != IDMAC_SDC_0 && channel != IDMAC_SDC_1 &&
+ channel != IDMAC_IC_7)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ switch (channel) {
+ case IDMAC_IC_7:
+ n_desc = 16;
+ reg = idmac_read_icreg(ipu, IC_CONF);
+ idmac_write_icreg(ipu, reg & ~IC_CONF_CSI_MEM_WR_EN, IC_CONF);
+ break;
+ case IDMAC_IC_0:
+ n_desc = 16;
+ reg = idmac_read_ipureg(ipu, IPU_FS_PROC_FLOW);
+ idmac_write_ipureg(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW);
+ ret = ipu_ic_init_prpenc(ipu, params, true);
+ break;
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ n_desc = 4;
+ default:
+ break;
+ }
+
+ ipu->channel_init_mask |= 1L << channel;
+
+ /* Enable IPU sub module */
+ ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) |
+ ipu_channel_conf_mask(channel);
+ idmac_write_ipureg(ipu, ipu_conf, IPU_CONF);
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ if (n_desc && !ichan->desc)
+ ret = idmac_desc_alloc(ichan, n_desc);
+
+ dump_idmac_reg(ipu);
+
+ return ret;
+}
+
+/**
+ * ipu_uninit_channel() - uninitialize an IPU channel.
+ * @idmac: IPU DMAC context.
+ * @ichan: pointer to the channel object.
+ */
+static void ipu_uninit_channel(struct idmac *idmac, struct idmac_channel *ichan)
+{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ unsigned long flags;
+ uint32_t reg;
+ unsigned long chan_mask = 1UL << channel;
+ uint32_t ipu_conf;
+ struct ipu *ipu = to_ipu(idmac);
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ if (!(ipu->channel_init_mask & chan_mask)) {
+ dev_err(ipu->dev, "Channel already uninitialized %d\n",
+ channel);
+ spin_unlock_irqrestore(&ipu->lock, flags);
+ return;
+ }
+
+ /* Reset the double buffer */
+ reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL);
+ idmac_write_ipureg(ipu, reg & ~chan_mask, IPU_CHA_DB_MODE_SEL);
+
+ ichan->sec_chan_en = false;
+
+ switch (channel) {
+ case IDMAC_IC_7:
+ reg = idmac_read_icreg(ipu, IC_CONF);
+ idmac_write_icreg(ipu, reg & ~(IC_CONF_RWS_EN | IC_CONF_PRPENC_EN),
+ IC_CONF);
+ break;
+ case IDMAC_IC_0:
+ reg = idmac_read_icreg(ipu, IC_CONF);
+ idmac_write_icreg(ipu, reg & ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1),
+ IC_CONF);
+ break;
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ default:
+ break;
+ }
+
+ ipu->channel_init_mask &= ~(1L << channel);
+
+ ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) &
+ ~ipu_channel_conf_mask(channel);
+ idmac_write_ipureg(ipu, ipu_conf, IPU_CONF);
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ ichan->n_tx_desc = 0;
+ vfree(ichan->desc);
+ ichan->desc = NULL;
+}
+
+/**
+ * ipu_disable_channel() - disable an IPU channel.
+ * @idmac: IPU DMAC context.
+ * @ichan: channel object pointer.
+ * @wait_for_stop: flag to set whether to wait for channel end of frame or
+ * return immediately.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
+ bool wait_for_stop)
+{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ struct ipu *ipu = to_ipu(idmac);
+ uint32_t reg;
+ unsigned long flags;
+ unsigned long chan_mask = 1UL << channel;
+ unsigned int timeout;
+
+ if (wait_for_stop && channel != IDMAC_SDC_1 && channel != IDMAC_SDC_0) {
+ timeout = 40;
+ /* This waiting always fails. Related to spurious irq problem */
+ while ((idmac_read_icreg(ipu, IDMAC_CHA_BUSY) & chan_mask) ||
+ (ipu_channel_status(ipu, channel) == TASK_STAT_ACTIVE)) {
+ timeout--;
+ msleep(10);
+
+ if (!timeout) {
+ dev_dbg(ipu->dev,
+ "Warning: timeout waiting for channel %u to "
+ "stop: buf0_rdy = 0x%08X, buf1_rdy = 0x%08X, "
+ "busy = 0x%08X, tstat = 0x%08X\n", channel,
+ idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY),
+ idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY),
+ idmac_read_icreg(ipu, IDMAC_CHA_BUSY),
+ idmac_read_ipureg(ipu, IPU_TASKS_STAT));
+ break;
+ }
+ }
+ dev_dbg(ipu->dev, "timeout = %d * 10ms\n", 40 - timeout);
+ }
+ /* SDC BG and FG must be disabled before DMA is disabled */
+ if (wait_for_stop && (channel == IDMAC_SDC_0 ||
+ channel == IDMAC_SDC_1)) {
+ for (timeout = 5;
+ timeout && !ipu_irq_status(ichan->eof_irq); timeout--)
+ msleep(5);
+ }
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ /* Disable IC task */
+ ipu_ic_disable_task(ipu, channel);
+
+ /* Disable DMA channel(s) */
+ reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
+ idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN);
+
+ /*
+ * Problem (observed with channel DMAIC_7): after enabling the channel
+ * and initialising buffers, there comes an interrupt with current still
+ * pointing at buffer 0, whereas it should use buffer 0 first and only
+ * generate an interrupt when it is done, then current should already
+ * point to buffer 1. This spurious interrupt also comes on channel
+ * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the
+ * first interrupt, there comes the second with current correctly
+ * pointing to buffer 1 this time. But sometimes this second interrupt
+ * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling
+ * the channel seems to prevent the channel from hanging, but it doesn't
+ * prevent the spurious interrupt. This might also be unsafe. Think
+ * about the IDMAC controller trying to switch to a buffer, when we
+ * clear the ready bit, and re-enable it a moment later.
+ */
+ reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY);
+ idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY);
+ idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY);
+
+ reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY);
+ idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY);
+ idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY);
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ return 0;
+}
+
+/*
+ * We have several possibilities here:
+ * current BUF next BUF
+ *
+ * not last sg next not last sg
+ * not last sg next last sg
+ * last sg first sg from next descriptor
+ * last sg NULL
+ *
+ * Besides, the descriptor queue might be empty or not. We process all these
+ * cases carefully.
+ */
+static irqreturn_t idmac_interrupt(int irq, void *dev_id)
+{
+ struct idmac_channel *ichan = dev_id;
+ unsigned int chan_id = ichan->dma_chan.chan_id;
+ struct scatterlist **sg, *sgnext, *sgnew = NULL;
+ /* Next transfer descriptor */
+ struct idmac_tx_desc *desc = NULL, *descnew;
+ dma_async_tx_callback callback;
+ void *callback_param;
+ bool done = false;
+ u32 ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY),
+ ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY),
+ curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+
+ /* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
+
+ pr_debug("IDMAC irq %d\n", irq);
+ /* Other interrupts do not interfere with this channel */
+ spin_lock(&ichan->lock);
+
+ if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
+ ((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
+ int i = 100;
+
+ /* This doesn't help. See comment in ipu_disable_channel() */
+ while (--i) {
+ curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+ if (((curbuf >> chan_id) & 1) != ichan->active_buffer)
+ break;
+ cpu_relax();
+ }
+
+ if (!i) {
+ spin_unlock(&ichan->lock);
+ dev_dbg(ichan->dma_chan.device->dev,
+ "IRQ on active buffer on channel %x, active "
+ "%d, ready %x, %x, current %x!\n", chan_id,
+ ichan->active_buffer, ready0, ready1, curbuf);
+ return IRQ_NONE;
+ }
+ }
+
+ if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
+ (!ichan->active_buffer && (ready0 >> chan_id) & 1)
+ )) {
+ spin_unlock(&ichan->lock);
+ dev_dbg(ichan->dma_chan.device->dev,
+ "IRQ with active buffer still ready on channel %x, "
+ "active %d, ready %x, %x!\n", chan_id,
+ ichan->active_buffer, ready0, ready1);
+ return IRQ_NONE;
+ }
+
+ if (unlikely(list_empty(&ichan->queue))) {
+ spin_unlock(&ichan->lock);
+ dev_err(ichan->dma_chan.device->dev,
+ "IRQ without queued buffers on channel %x, active %d, "
+ "ready %x, %x!\n", chan_id,
+ ichan->active_buffer, ready0, ready1);
+ return IRQ_NONE;
+ }
+
+ /*
+ * active_buffer is a software flag, it shows which buffer we are
+ * currently expecting back from the hardware, IDMAC should be
+ * processing the other buffer already
+ */
+ sg = &ichan->sg[ichan->active_buffer];
+ sgnext = ichan->sg[!ichan->active_buffer];
+
+ /*
+ * if sgnext == NULL sg must be the last element in a scatterlist and
+ * queue must be empty
+ */
+ if (unlikely(!sgnext)) {
+ if (unlikely(sg_next(*sg))) {
+ dev_err(ichan->dma_chan.device->dev,
+ "Broken buffer-update locking on channel %x!\n",
+ chan_id);
+ /* We'll let the user catch up */
+ } else {
+ /* Underrun */
+ ipu_ic_disable_task(&ipu_data, chan_id);
+ dev_dbg(ichan->dma_chan.device->dev,
+ "Underrun on channel %x\n", chan_id);
+ ichan->status = IPU_CHANNEL_READY;
+ /* Continue to check for complete descriptor */
+ }
+ }
+
+ desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
+
+ /* First calculate and submit the next sg element */
+ if (likely(sgnext))
+ sgnew = sg_next(sgnext);
+
+ if (unlikely(!sgnew)) {
+ /* Start a new scatterlist, if any queued */
+ if (likely(desc->list.next != &ichan->queue)) {
+ descnew = list_entry(desc->list.next,
+ struct idmac_tx_desc, list);
+ sgnew = &descnew->sg[0];
+ }
+ }
+
+ if (unlikely(!sg_next(*sg)) || !sgnext) {
+ /*
+ * Last element in scatterlist done, remove from the queue,
+ * _init for debugging
+ */
+ list_del_init(&desc->list);
+ done = true;
+ }
+
+ *sg = sgnew;
+
+ if (likely(sgnew)) {
+ int ret;
+
+ ret = ipu_update_channel_buffer(chan_id, ichan->active_buffer,
+ sg_dma_address(*sg));
+ if (ret < 0)
+ dev_err(ichan->dma_chan.device->dev,
+ "Failed to update buffer on channel %x buffer %d!\n",
+ chan_id, ichan->active_buffer);
+ else
+ ipu_select_buffer(chan_id, ichan->active_buffer);
+ }
+
+ /* Flip the active buffer - even if update above failed */
+ ichan->active_buffer = !ichan->active_buffer;
+ if (done)
+ ichan->completed = desc->txd.cookie;
+
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+
+ spin_unlock(&ichan->lock);
+
+ if (done && (desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
+ callback(callback_param);
+
+ return IRQ_HANDLED;
+}
+
+static void ipu_gc_tasklet(unsigned long arg)
+{
+ struct ipu *ipu = (struct ipu *)arg;
+ int i;
+
+ for (i = 0; i < IPU_CHANNELS_NUM; i++) {
+ struct idmac_channel *ichan = ipu->channel + i;
+ struct idmac_tx_desc *desc;
+ unsigned long flags;
+ int j;
+
+ for (j = 0; j < ichan->n_tx_desc; j++) {
+ desc = ichan->desc + j;
+ spin_lock_irqsave(&ichan->lock, flags);
+ if (async_tx_test_ack(&desc->txd)) {
+ list_move(&desc->list, &ichan->free_list);
+ async_tx_clear_ack(&desc->txd);
+ }
+ spin_unlock_irqrestore(&ichan->lock, flags);
+ }
+ }
+}
+
+/*
+ * At the time .device_alloc_chan_resources() method is called, we cannot know,
+ * whether the client will accept the channel. Thus we must only check, if we
+ * can satisfy client's request but the only real criterion to verify, whether
+ * the client has accepted our offer is the client_count. That's why we have to
+ * perform the rest of our allocation tasks on the first call to this function.
+ */
+static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
+ struct scatterlist *sgl, unsigned int sg_len,
+ enum dma_data_direction direction, unsigned long tx_flags)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac_tx_desc *desc = NULL;
+ struct dma_async_tx_descriptor *txd = NULL;
+ unsigned long flags;
+
+ /* We only can handle these three channels so far */
+ if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 &&
+ ichan->dma_chan.chan_id != IDMAC_IC_7)
+ return NULL;
+
+ if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) {
+ dev_err(chan->device->dev, "Invalid DMA direction %d!\n", direction);
+ return NULL;
+ }
+
+ mutex_lock(&ichan->chan_mutex);
+
+ spin_lock_irqsave(&ichan->lock, flags);
+ if (!list_empty(&ichan->free_list)) {
+ desc = list_entry(ichan->free_list.next,
+ struct idmac_tx_desc, list);
+
+ list_del_init(&desc->list);
+
+ desc->sg_len = sg_len;
+ desc->sg = sgl;
+ txd = &desc->txd;
+ txd->flags = tx_flags;
+ }
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ mutex_unlock(&ichan->chan_mutex);
+
+ tasklet_schedule(&to_ipu(to_idmac(chan->device))->tasklet);
+
+ return txd;
+}
+
+/* Re-select the current buffer and re-activate the channel */
+static void idmac_issue_pending(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+ struct ipu *ipu = to_ipu(idmac);
+ unsigned long flags;
+
+ /* This is not always needed, but doesn't hurt either */
+ spin_lock_irqsave(&ipu->lock, flags);
+ ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer);
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ /*
+ * Might need to perform some parts of initialisation from
+ * ipu_enable_channel(), but not all, we do not want to reset to buffer
+ * 0, don't need to set priority again either, but re-enabling the task
+ * and the channel might be a good idea.
+ */
+}
+
+static void __idmac_terminate_all(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+ unsigned long flags;
+ int i;
+
+ ipu_disable_channel(idmac, ichan,
+ ichan->status >= IPU_CHANNEL_ENABLED);
+
+ tasklet_disable(&to_ipu(idmac)->tasklet);
+
+ /* ichan->queue is modified in ISR, have to spinlock */
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_splice_init(&ichan->queue, &ichan->free_list);
+
+ if (ichan->desc)
+ for (i = 0; i < ichan->n_tx_desc; i++) {
+ struct idmac_tx_desc *desc = ichan->desc + i;
+ if (list_empty(&desc->list))
+ /* Descriptor was prepared, but not submitted */
+ list_add(&desc->list,
+ &ichan->free_list);
+
+ async_tx_clear_ack(&desc->txd);
+ }
+
+ ichan->sg[0] = NULL;
+ ichan->sg[1] = NULL;
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ tasklet_enable(&to_ipu(idmac)->tasklet);
+
+ ichan->status = IPU_CHANNEL_INITIALIZED;
+}
+
+static void idmac_terminate_all(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+
+ mutex_lock(&ichan->chan_mutex);
+
+ __idmac_terminate_all(chan);
+
+ mutex_unlock(&ichan->chan_mutex);
+}
+
+static int idmac_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+ int ret;
+
+ /* dmaengine.c now guarantees to only offer free channels */
+ BUG_ON(chan->client_count > 1);
+ WARN_ON(ichan->status != IPU_CHANNEL_FREE);
+
+ chan->cookie = 1;
+ ichan->completed = -ENXIO;
+
+ ret = ipu_irq_map(ichan->dma_chan.chan_id);
+ if (ret < 0)
+ goto eimap;
+
+ ichan->eof_irq = ret;
+ ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
+ ichan->eof_name, ichan);
+ if (ret < 0)
+ goto erirq;
+
+ ret = ipu_init_channel(idmac, ichan);
+ if (ret < 0)
+ goto eichan;
+
+ ichan->status = IPU_CHANNEL_INITIALIZED;
+
+ dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n",
+ ichan->dma_chan.chan_id, ichan->eof_irq);
+
+ return ret;
+
+eichan:
+ free_irq(ichan->eof_irq, ichan);
+erirq:
+ ipu_irq_unmap(ichan->dma_chan.chan_id);
+eimap:
+ return ret;
+}
+
+static void idmac_free_chan_resources(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+
+ mutex_lock(&ichan->chan_mutex);
+
+ __idmac_terminate_all(chan);
+
+ if (ichan->status > IPU_CHANNEL_FREE) {
+ free_irq(ichan->eof_irq, ichan);
+ ipu_irq_unmap(ichan->dma_chan.chan_id);
+ }
+
+ ichan->status = IPU_CHANNEL_FREE;
+
+ ipu_uninit_channel(idmac, ichan);
+
+ mutex_unlock(&ichan->chan_mutex);
+
+ tasklet_schedule(&to_ipu(idmac)->tasklet);
+}
+
+static enum dma_status idmac_is_tx_complete(struct dma_chan *chan,
+ dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+
+ if (done)
+ *done = ichan->completed;
+ if (used)
+ *used = chan->cookie;
+ if (cookie != chan->cookie)
+ return DMA_ERROR;
+ return DMA_SUCCESS;
+}
+
+static int __init ipu_idmac_init(struct ipu *ipu)
+{
+ struct idmac *idmac = &ipu->idmac;
+ struct dma_device *dma = &idmac->dma;
+ int i;
+
+ dma_cap_set(DMA_SLAVE, dma->cap_mask);
+ dma_cap_set(DMA_PRIVATE, dma->cap_mask);
+
+ /* Compulsory common fields */
+ dma->dev = ipu->dev;
+ dma->device_alloc_chan_resources = idmac_alloc_chan_resources;
+ dma->device_free_chan_resources = idmac_free_chan_resources;
+ dma->device_is_tx_complete = idmac_is_tx_complete;
+ dma->device_issue_pending = idmac_issue_pending;
+
+ /* Compulsory for DMA_SLAVE fields */
+ dma->device_prep_slave_sg = idmac_prep_slave_sg;
+ dma->device_terminate_all = idmac_terminate_all;
+
+ INIT_LIST_HEAD(&dma->channels);
+ for (i = 0; i < IPU_CHANNELS_NUM; i++) {
+ struct idmac_channel *ichan = ipu->channel + i;
+ struct dma_chan *dma_chan = &ichan->dma_chan;
+
+ spin_lock_init(&ichan->lock);
+ mutex_init(&ichan->chan_mutex);
+
+ ichan->status = IPU_CHANNEL_FREE;
+ ichan->sec_chan_en = false;
+ ichan->completed = -ENXIO;
+ snprintf(ichan->eof_name, sizeof(ichan->eof_name), "IDMAC EOF %d", i);
+
+ dma_chan->device = &idmac->dma;
+ dma_chan->cookie = 1;
+ dma_chan->chan_id = i;
+ list_add_tail(&ichan->dma_chan.device_node, &dma->channels);
+ }
+
+ idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
+
+ return dma_async_device_register(&idmac->dma);
+}
+
+static void ipu_idmac_exit(struct ipu *ipu)
+{
+ int i;
+ struct idmac *idmac = &ipu->idmac;
+
+ for (i = 0; i < IPU_CHANNELS_NUM; i++) {
+ struct idmac_channel *ichan = ipu->channel + i;
+
+ idmac_terminate_all(&ichan->dma_chan);
+ idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
+ }
+
+ dma_async_device_unregister(&idmac->dma);
+}
+
+/*****************************************************************************
+ * IPU common probe / remove
+ */
+
+static int ipu_probe(struct platform_device *pdev)
+{
+ struct ipu_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *mem_ipu, *mem_ic;
+ int ret;
+
+ spin_lock_init(&ipu_data.lock);
+
+ mem_ipu = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mem_ic = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!pdata || !mem_ipu || !mem_ic)
+ return -EINVAL;
+
+ ipu_data.dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, &ipu_data);
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ goto err_noirq;
+
+ ipu_data.irq_fn = ret;
+ ret = platform_get_irq(pdev, 1);
+ if (ret < 0)
+ goto err_noirq;
+
+ ipu_data.irq_err = ret;
+ ipu_data.irq_base = pdata->irq_base;
+
+ dev_dbg(&pdev->dev, "fn irq %u, err irq %u, irq-base %u\n",
+ ipu_data.irq_fn, ipu_data.irq_err, ipu_data.irq_base);
+
+ /* Remap IPU common registers */
+ ipu_data.reg_ipu = ioremap(mem_ipu->start,
+ mem_ipu->end - mem_ipu->start + 1);
+ if (!ipu_data.reg_ipu) {
+ ret = -ENOMEM;
+ goto err_ioremap_ipu;
+ }
+
+ /* Remap Image Converter and Image DMA Controller registers */
+ ipu_data.reg_ic = ioremap(mem_ic->start,
+ mem_ic->end - mem_ic->start + 1);
+ if (!ipu_data.reg_ic) {
+ ret = -ENOMEM;
+ goto err_ioremap_ic;
+ }
+
+ /* Get IPU clock */
+ ipu_data.ipu_clk = clk_get(&pdev->dev, "ipu_clk");
+ if (IS_ERR(ipu_data.ipu_clk)) {
+ ret = PTR_ERR(ipu_data.ipu_clk);
+ goto err_clk_get;
+ }
+
+ /* Make sure IPU HSP clock is running */
+ clk_enable(ipu_data.ipu_clk);
+
+ /* Disable all interrupts */
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1);
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_2);
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_3);
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_4);
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_5);
+
+ dev_dbg(&pdev->dev, "%s @ 0x%08lx, fn irq %u, err irq %u\n", pdev->name,
+ (unsigned long)mem_ipu->start, ipu_data.irq_fn, ipu_data.irq_err);
+
+ ret = ipu_irq_attach_irq(&ipu_data, pdev);
+ if (ret < 0)
+ goto err_attach_irq;
+
+ /* Initialize DMA engine */
+ ret = ipu_idmac_init(&ipu_data);
+ if (ret < 0)
+ goto err_idmac_init;
+
+ tasklet_init(&ipu_data.tasklet, ipu_gc_tasklet, (unsigned long)&ipu_data);
+
+ ipu_data.dev = &pdev->dev;
+
+ dev_dbg(ipu_data.dev, "IPU initialized\n");
+
+ return 0;
+
+err_idmac_init:
+err_attach_irq:
+ ipu_irq_detach_irq(&ipu_data, pdev);
+ clk_disable(ipu_data.ipu_clk);
+ clk_put(ipu_data.ipu_clk);
+err_clk_get:
+ iounmap(ipu_data.reg_ic);
+err_ioremap_ic:
+ iounmap(ipu_data.reg_ipu);
+err_ioremap_ipu:
+err_noirq:
+ dev_err(&pdev->dev, "Failed to probe IPU: %d\n", ret);
+ return ret;
+}
+
+static int ipu_remove(struct platform_device *pdev)
+{
+ struct ipu *ipu = platform_get_drvdata(pdev);
+
+ ipu_idmac_exit(ipu);
+ ipu_irq_detach_irq(ipu, pdev);
+ clk_disable(ipu->ipu_clk);
+ clk_put(ipu->ipu_clk);
+ iounmap(ipu->reg_ic);
+ iounmap(ipu->reg_ipu);
+ tasklet_kill(&ipu->tasklet);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+/*
+ * We need two MEM resources - with IPU-common and Image Converter registers,
+ * including PF_CONF and IDMAC_* registers, and two IRQs - function and error
+ */
+static struct platform_driver ipu_platform_driver = {
+ .driver = {
+ .name = "ipu-core",
+ .owner = THIS_MODULE,
+ },
+ .remove = ipu_remove,
+};
+
+static int __init ipu_init(void)
+{
+ return platform_driver_probe(&ipu_platform_driver, ipu_probe);
+}
+subsys_initcall(ipu_init);
+
+MODULE_DESCRIPTION("IPU core driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_ALIAS("platform:ipu-core");
diff --git a/drivers/dma/ipu/ipu_intern.h b/drivers/dma/ipu/ipu_intern.h
new file mode 100644
index 00000000000..545cf11a94a
--- /dev/null
+++ b/drivers/dma/ipu/ipu_intern.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * Copyright (C) 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IPU_INTERN_H_
+#define _IPU_INTERN_H_
+
+#include <linux/dmaengine.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+/* IPU Common registers */
+#define IPU_CONF 0x00
+#define IPU_CHA_BUF0_RDY 0x04
+#define IPU_CHA_BUF1_RDY 0x08
+#define IPU_CHA_DB_MODE_SEL 0x0C
+#define IPU_CHA_CUR_BUF 0x10
+#define IPU_FS_PROC_FLOW 0x14
+#define IPU_FS_DISP_FLOW 0x18
+#define IPU_TASKS_STAT 0x1C
+#define IPU_IMA_ADDR 0x20
+#define IPU_IMA_DATA 0x24
+#define IPU_INT_CTRL_1 0x28
+#define IPU_INT_CTRL_2 0x2C
+#define IPU_INT_CTRL_3 0x30
+#define IPU_INT_CTRL_4 0x34
+#define IPU_INT_CTRL_5 0x38
+#define IPU_INT_STAT_1 0x3C
+#define IPU_INT_STAT_2 0x40
+#define IPU_INT_STAT_3 0x44
+#define IPU_INT_STAT_4 0x48
+#define IPU_INT_STAT_5 0x4C
+#define IPU_BRK_CTRL_1 0x50
+#define IPU_BRK_CTRL_2 0x54
+#define IPU_BRK_STAT 0x58
+#define IPU_DIAGB_CTRL 0x5C
+
+/* IPU_CONF Register bits */
+#define IPU_CONF_CSI_EN 0x00000001
+#define IPU_CONF_IC_EN 0x00000002
+#define IPU_CONF_ROT_EN 0x00000004
+#define IPU_CONF_PF_EN 0x00000008
+#define IPU_CONF_SDC_EN 0x00000010
+#define IPU_CONF_ADC_EN 0x00000020
+#define IPU_CONF_DI_EN 0x00000040
+#define IPU_CONF_DU_EN 0x00000080
+#define IPU_CONF_PXL_ENDIAN 0x00000100
+
+/* Image Converter Registers */
+#define IC_CONF 0x88
+#define IC_PRP_ENC_RSC 0x8C
+#define IC_PRP_VF_RSC 0x90
+#define IC_PP_RSC 0x94
+#define IC_CMBP_1 0x98
+#define IC_CMBP_2 0x9C
+#define PF_CONF 0xA0
+#define IDMAC_CONF 0xA4
+#define IDMAC_CHA_EN 0xA8
+#define IDMAC_CHA_PRI 0xAC
+#define IDMAC_CHA_BUSY 0xB0
+
+/* Image Converter Register bits */
+#define IC_CONF_PRPENC_EN 0x00000001
+#define IC_CONF_PRPENC_CSC1 0x00000002
+#define IC_CONF_PRPENC_ROT_EN 0x00000004
+#define IC_CONF_PRPVF_EN 0x00000100
+#define IC_CONF_PRPVF_CSC1 0x00000200
+#define IC_CONF_PRPVF_CSC2 0x00000400
+#define IC_CONF_PRPVF_CMB 0x00000800
+#define IC_CONF_PRPVF_ROT_EN 0x00001000
+#define IC_CONF_PP_EN 0x00010000
+#define IC_CONF_PP_CSC1 0x00020000
+#define IC_CONF_PP_CSC2 0x00040000
+#define IC_CONF_PP_CMB 0x00080000
+#define IC_CONF_PP_ROT_EN 0x00100000
+#define IC_CONF_IC_GLB_LOC_A 0x10000000
+#define IC_CONF_KEY_COLOR_EN 0x20000000
+#define IC_CONF_RWS_EN 0x40000000
+#define IC_CONF_CSI_MEM_WR_EN 0x80000000
+
+#define IDMA_CHAN_INVALID 0x000000FF
+#define IDMA_IC_0 0x00000001
+#define IDMA_IC_1 0x00000002
+#define IDMA_IC_2 0x00000004
+#define IDMA_IC_3 0x00000008
+#define IDMA_IC_4 0x00000010
+#define IDMA_IC_5 0x00000020
+#define IDMA_IC_6 0x00000040
+#define IDMA_IC_7 0x00000080
+#define IDMA_IC_8 0x00000100
+#define IDMA_IC_9 0x00000200
+#define IDMA_IC_10 0x00000400
+#define IDMA_IC_11 0x00000800
+#define IDMA_IC_12 0x00001000
+#define IDMA_IC_13 0x00002000
+#define IDMA_SDC_BG 0x00004000
+#define IDMA_SDC_FG 0x00008000
+#define IDMA_SDC_MASK 0x00010000
+#define IDMA_SDC_PARTIAL 0x00020000
+#define IDMA_ADC_SYS1_WR 0x00040000
+#define IDMA_ADC_SYS2_WR 0x00080000
+#define IDMA_ADC_SYS1_CMD 0x00100000
+#define IDMA_ADC_SYS2_CMD 0x00200000
+#define IDMA_ADC_SYS1_RD 0x00400000
+#define IDMA_ADC_SYS2_RD 0x00800000
+#define IDMA_PF_QP 0x01000000
+#define IDMA_PF_BSP 0x02000000
+#define IDMA_PF_Y_IN 0x04000000
+#define IDMA_PF_U_IN 0x08000000
+#define IDMA_PF_V_IN 0x10000000
+#define IDMA_PF_Y_OUT 0x20000000
+#define IDMA_PF_U_OUT 0x40000000
+#define IDMA_PF_V_OUT 0x80000000
+
+#define TSTAT_PF_H264_PAUSE 0x00000001
+#define TSTAT_CSI2MEM_MASK 0x0000000C
+#define TSTAT_CSI2MEM_OFFSET 2
+#define TSTAT_VF_MASK 0x00000600
+#define TSTAT_VF_OFFSET 9
+#define TSTAT_VF_ROT_MASK 0x000C0000
+#define TSTAT_VF_ROT_OFFSET 18
+#define TSTAT_ENC_MASK 0x00000180
+#define TSTAT_ENC_OFFSET 7
+#define TSTAT_ENC_ROT_MASK 0x00030000
+#define TSTAT_ENC_ROT_OFFSET 16
+#define TSTAT_PP_MASK 0x00001800
+#define TSTAT_PP_OFFSET 11
+#define TSTAT_PP_ROT_MASK 0x00300000
+#define TSTAT_PP_ROT_OFFSET 20
+#define TSTAT_PF_MASK 0x00C00000
+#define TSTAT_PF_OFFSET 22
+#define TSTAT_ADCSYS1_MASK 0x03000000
+#define TSTAT_ADCSYS1_OFFSET 24
+#define TSTAT_ADCSYS2_MASK 0x0C000000
+#define TSTAT_ADCSYS2_OFFSET 26
+
+#define TASK_STAT_IDLE 0
+#define TASK_STAT_ACTIVE 1
+#define TASK_STAT_WAIT4READY 2
+
+struct idmac {
+ struct dma_device dma;
+};
+
+struct ipu {
+ void __iomem *reg_ipu;
+ void __iomem *reg_ic;
+ unsigned int irq_fn; /* IPU Function IRQ to the CPU */
+ unsigned int irq_err; /* IPU Error IRQ to the CPU */
+ unsigned int irq_base; /* Beginning of the IPU IRQ range */
+ unsigned long channel_init_mask;
+ spinlock_t lock;
+ struct clk *ipu_clk;
+ struct device *dev;
+ struct idmac idmac;
+ struct idmac_channel channel[IPU_CHANNELS_NUM];
+ struct tasklet_struct tasklet;
+};
+
+#define to_idmac(d) container_of(d, struct idmac, dma)
+
+extern int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev);
+extern void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev);
+
+extern bool ipu_irq_status(uint32_t irq);
+extern int ipu_irq_map(unsigned int source);
+extern int ipu_irq_unmap(unsigned int source);
+
+#endif
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
new file mode 100644
index 00000000000..83f532cc767
--- /dev/null
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/ipu.h>
+
+#include "ipu_intern.h"
+
+/*
+ * Register read / write - shall be inlined by the compiler
+ */
+static u32 ipu_read_reg(struct ipu *ipu, unsigned long reg)
+{
+ return __raw_readl(ipu->reg_ipu + reg);
+}
+
+static void ipu_write_reg(struct ipu *ipu, u32 value, unsigned long reg)
+{
+ __raw_writel(value, ipu->reg_ipu + reg);
+}
+
+
+/*
+ * IPU IRQ chip driver
+ */
+
+#define IPU_IRQ_NR_FN_BANKS 3
+#define IPU_IRQ_NR_ERR_BANKS 2
+#define IPU_IRQ_NR_BANKS (IPU_IRQ_NR_FN_BANKS + IPU_IRQ_NR_ERR_BANKS)
+
+struct ipu_irq_bank {
+ unsigned int control;
+ unsigned int status;
+ spinlock_t lock;
+ struct ipu *ipu;
+};
+
+static struct ipu_irq_bank irq_bank[IPU_IRQ_NR_BANKS] = {
+ /* 3 groups of functional interrupts */
+ {
+ .control = IPU_INT_CTRL_1,
+ .status = IPU_INT_STAT_1,
+ }, {
+ .control = IPU_INT_CTRL_2,
+ .status = IPU_INT_STAT_2,
+ }, {
+ .control = IPU_INT_CTRL_3,
+ .status = IPU_INT_STAT_3,
+ },
+ /* 2 groups of error interrupts */
+ {
+ .control = IPU_INT_CTRL_4,
+ .status = IPU_INT_STAT_4,
+ }, {
+ .control = IPU_INT_CTRL_5,
+ .status = IPU_INT_STAT_5,
+ },
+};
+
+struct ipu_irq_map {
+ unsigned int irq;
+ int source;
+ struct ipu_irq_bank *bank;
+ struct ipu *ipu;
+};
+
+static struct ipu_irq_map irq_map[CONFIG_MX3_IPU_IRQS];
+/* Protects allocations from the above array of maps */
+static DEFINE_MUTEX(map_lock);
+/* Protects register accesses and individual mappings */
+static DEFINE_SPINLOCK(bank_lock);
+
+static struct ipu_irq_map *src2map(unsigned int src)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++)
+ if (irq_map[i].source == src)
+ return irq_map + i;
+
+ return NULL;
+}
+
+static void ipu_irq_unmask(unsigned int irq)
+{
+ struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_bank *bank;
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+
+ bank = map->bank;
+ if (!bank) {
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ return;
+ }
+
+ reg = ipu_read_reg(bank->ipu, bank->control);
+ reg |= (1UL << (map->source & 31));
+ ipu_write_reg(bank->ipu, reg, bank->control);
+
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+}
+
+static void ipu_irq_mask(unsigned int irq)
+{
+ struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_bank *bank;
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+
+ bank = map->bank;
+ if (!bank) {
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ return;
+ }
+
+ reg = ipu_read_reg(bank->ipu, bank->control);
+ reg &= ~(1UL << (map->source & 31));
+ ipu_write_reg(bank->ipu, reg, bank->control);
+
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+}
+
+static void ipu_irq_ack(unsigned int irq)
+{
+ struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_bank *bank;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+
+ bank = map->bank;
+ if (!bank) {
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ return;
+ }
+
+ ipu_write_reg(bank->ipu, 1UL << (map->source & 31), bank->status);
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+}
+
+/**
+ * ipu_irq_status() - returns the current interrupt status of the specified IRQ.
+ * @irq: interrupt line to get status for.
+ * @return: true if the interrupt is pending/asserted or false if the
+ * interrupt is not pending.
+ */
+bool ipu_irq_status(unsigned int irq)
+{
+ struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_bank *bank;
+ unsigned long lock_flags;
+ bool ret;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+ bank = map->bank;
+ ret = bank && ipu_read_reg(bank->ipu, bank->status) &
+ (1UL << (map->source & 31));
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+
+ return ret;
+}
+
+/**
+ * ipu_irq_map() - map an IPU interrupt source to an IRQ number
+ * @source: interrupt source bit position (see below)
+ * @return: mapped IRQ number or negative error code
+ *
+ * The source parameter has to be explained further. On i.MX31 IPU has 137 IRQ
+ * sources, they are broken down in 5 32-bit registers, like 32, 32, 24, 32, 17.
+ * However, the source argument of this function is not the sequence number of
+ * the possible IRQ, but rather its bit position. So, first interrupt in fourth
+ * register has source number 96, and not 88. This makes calculations easier,
+ * and also provides forward compatibility with any future IPU implementations
+ * with any interrupt bit assignments.
+ */
+int ipu_irq_map(unsigned int source)
+{
+ int i, ret = -ENOMEM;
+ struct ipu_irq_map *map;
+
+ might_sleep();
+
+ mutex_lock(&map_lock);
+ map = src2map(source);
+ if (map) {
+ pr_err("IPU: Source %u already mapped to IRQ %u\n", source, map->irq);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
+ if (irq_map[i].source < 0) {
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+ irq_map[i].source = source;
+ irq_map[i].bank = irq_bank + source / 32;
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+
+ ret = irq_map[i].irq;
+ pr_debug("IPU: mapped source %u to IRQ %u\n",
+ source, ret);
+ break;
+ }
+ }
+out:
+ mutex_unlock(&map_lock);
+
+ if (ret < 0)
+ pr_err("IPU: couldn't map source %u: %d\n", source, ret);
+
+ return ret;
+}
+
+/**
+ * ipu_irq_map() - map an IPU interrupt source to an IRQ number
+ * @source: interrupt source bit position (see ipu_irq_map())
+ * @return: 0 or negative error code
+ */
+int ipu_irq_unmap(unsigned int source)
+{
+ int i, ret = -EINVAL;
+
+ might_sleep();
+
+ mutex_lock(&map_lock);
+ for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
+ if (irq_map[i].source == source) {
+ unsigned long lock_flags;
+
+ pr_debug("IPU: unmapped source %u from IRQ %u\n",
+ source, irq_map[i].irq);
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+ irq_map[i].source = -EINVAL;
+ irq_map[i].bank = NULL;
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&map_lock);
+
+ return ret;
+}
+
+/* Chained IRQ handler for IPU error interrupt */
+static void ipu_irq_err(unsigned int irq, struct irq_desc *desc)
+{
+ struct ipu *ipu = get_irq_data(irq);
+ u32 status;
+ int i, line;
+
+ for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
+ struct ipu_irq_bank *bank = irq_bank + i;
+
+ spin_lock(&bank_lock);
+ status = ipu_read_reg(ipu, bank->status);
+ /*
+ * Don't think we have to clear all interrupts here, they will
+ * be acked by ->handle_irq() (handle_level_irq). However, we
+ * might want to clear unhandled interrupts after the loop...
+ */
+ status &= ipu_read_reg(ipu, bank->control);
+ spin_unlock(&bank_lock);
+ while ((line = ffs(status))) {
+ struct ipu_irq_map *map;
+
+ line--;
+ status &= ~(1UL << line);
+
+ spin_lock(&bank_lock);
+ map = src2map(32 * i + line);
+ if (map)
+ irq = map->irq;
+ spin_unlock(&bank_lock);
+
+ if (!map) {
+ pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
+ line, i);
+ continue;
+ }
+ generic_handle_irq(irq);
+ }
+ }
+}
+
+/* Chained IRQ handler for IPU function interrupt */
+static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc)
+{
+ struct ipu *ipu = get_irq_data(irq);
+ u32 status;
+ int i, line;
+
+ for (i = 0; i < IPU_IRQ_NR_FN_BANKS; i++) {
+ struct ipu_irq_bank *bank = irq_bank + i;
+
+ spin_lock(&bank_lock);
+ status = ipu_read_reg(ipu, bank->status);
+ /* Not clearing all interrupts, see above */
+ status &= ipu_read_reg(ipu, bank->control);
+ spin_unlock(&bank_lock);
+ while ((line = ffs(status))) {
+ struct ipu_irq_map *map;
+
+ line--;
+ status &= ~(1UL << line);
+
+ spin_lock(&bank_lock);
+ map = src2map(32 * i + line);
+ if (map)
+ irq = map->irq;
+ spin_unlock(&bank_lock);
+
+ if (!map) {
+ pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
+ line, i);
+ continue;
+ }
+ generic_handle_irq(irq);
+ }
+ }
+}
+
+static struct irq_chip ipu_irq_chip = {
+ .name = "ipu_irq",
+ .ack = ipu_irq_ack,
+ .mask = ipu_irq_mask,
+ .unmask = ipu_irq_unmask,
+};
+
+/* Install the IRQ handler */
+int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
+{
+ struct ipu_platform_data *pdata = dev->dev.platform_data;
+ unsigned int irq, irq_base, i;
+
+ irq_base = pdata->irq_base;
+
+ for (i = 0; i < IPU_IRQ_NR_BANKS; i++)
+ irq_bank[i].ipu = ipu;
+
+ for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
+ int ret;
+
+ irq = irq_base + i;
+ ret = set_irq_chip(irq, &ipu_irq_chip);
+ if (ret < 0)
+ return ret;
+ ret = set_irq_chip_data(irq, irq_map + i);
+ if (ret < 0)
+ return ret;
+ irq_map[i].ipu = ipu;
+ irq_map[i].irq = irq;
+ irq_map[i].source = -EINVAL;
+ set_irq_handler(irq, handle_level_irq);
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+#endif
+ }
+
+ set_irq_data(ipu->irq_fn, ipu);
+ set_irq_chained_handler(ipu->irq_fn, ipu_irq_fn);
+
+ set_irq_data(ipu->irq_err, ipu);
+ set_irq_chained_handler(ipu->irq_err, ipu_irq_err);
+
+ return 0;
+}
+
+void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev)
+{
+ struct ipu_platform_data *pdata = dev->dev.platform_data;
+ unsigned int irq, irq_base;
+
+ irq_base = pdata->irq_base;
+
+ set_irq_chained_handler(ipu->irq_fn, NULL);
+ set_irq_data(ipu->irq_fn, NULL);
+
+ set_irq_chained_handler(ipu->irq_err, NULL);
+ set_irq_data(ipu->irq_err, NULL);
+
+ for (irq = irq_base; irq < irq_base + CONFIG_MX3_IPU_IRQS; irq++) {
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, 0);
+#endif
+ set_irq_chip(irq, NULL);
+ set_irq_chip_data(irq, NULL);
+ }
+}
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index d35cbd1ff0b..cb7f26fb9f1 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -1019,19 +1019,19 @@ mv_xor_xor_self_test(struct mv_xor_device *device)
for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) {
xor_srcs[src_idx] = alloc_page(GFP_KERNEL);
- if (!xor_srcs[src_idx])
- while (src_idx--) {
+ if (!xor_srcs[src_idx]) {
+ while (src_idx--)
__free_page(xor_srcs[src_idx]);
- return -ENOMEM;
- }
+ return -ENOMEM;
+ }
}
dest = alloc_page(GFP_KERNEL);
- if (!dest)
- while (src_idx--) {
+ if (!dest) {
+ while (src_idx--)
__free_page(xor_srcs[src_idx]);
- return -ENOMEM;
- }
+ return -ENOMEM;
+ }
/* Fill in src buffers */
for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) {
@@ -1287,7 +1287,7 @@ mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp,
static struct platform_driver mv_xor_driver = {
.probe = mv_xor_probe,
- .remove = mv_xor_remove,
+ .remove = __devexit_p(mv_xor_remove),
.driver = {
.owner = THIS_MODULE,
.name = MV_XOR_NAME,
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
index cd2e3b8087e..cb0f639f049 100644
--- a/drivers/edac/cell_edac.c
+++ b/drivers/edac/cell_edac.c
@@ -36,7 +36,7 @@ static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar)
struct csrow_info *csrow = &mci->csrows[0];
unsigned long address, pfn, offset, syndrome;
- dev_dbg(mci->dev, "ECC CE err on node %d, channel %d, ar = 0x%016lx\n",
+ dev_dbg(mci->dev, "ECC CE err on node %d, channel %d, ar = 0x%016llx\n",
priv->node, chan, ar);
/* Address decoding is likely a bit bogus, to dbl check */
@@ -58,7 +58,7 @@ static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar)
struct csrow_info *csrow = &mci->csrows[0];
unsigned long address, pfn, offset;
- dev_dbg(mci->dev, "ECC UE err on node %d, channel %d, ar = 0x%016lx\n",
+ dev_dbg(mci->dev, "ECC UE err on node %d, channel %d, ar = 0x%016llx\n",
priv->node, chan, ar);
/* Address decoding is likely a bit bogus, to dbl check */
@@ -169,7 +169,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
/* Get channel population */
reg = in_be64(&regs->mic_mnt_cfg);
- dev_dbg(&pdev->dev, "MIC_MNT_CFG = 0x%016lx\n", reg);
+ dev_dbg(&pdev->dev, "MIC_MNT_CFG = 0x%016llx\n", reg);
chanmask = 0;
if (reg & CBE_MIC_MNT_CFG_CHAN_0_POP)
chanmask |= 0x1;
@@ -180,7 +180,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
"Yuck ! No channel populated ? Aborting !\n");
return -ENODEV;
}
- dev_dbg(&pdev->dev, "Initial FIR = 0x%016lx\n",
+ dev_dbg(&pdev->dev, "Initial FIR = 0x%016llx\n",
in_be64(&regs->mic_fir));
/* Allocate & init EDAC MC data structure */
@@ -198,7 +198,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
mci->edac_cap = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
mci->mod_name = "cell_edac";
mci->ctl_name = "MIC";
- mci->dev_name = pdev->dev.bus_id;
+ mci->dev_name = dev_name(&pdev->dev);
mci->edac_check = cell_edac_check;
cell_edac_init_csrows(mci);
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 853ef37ec00..4637a4a757d 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -218,7 +218,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
pci->dev = &op->dev;
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;
- pci->dev_name = op->dev.bus_id;
+ pci->dev_name = dev_name(&op->dev);
if (edac_op_state == EDAC_OPSTATE_POLL)
pci->edac_check = mpc85xx_pci_check;
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c
index 083ce8d0c63..5131aaae8e0 100644
--- a/drivers/edac/mv64x60_edac.c
+++ b/drivers/edac/mv64x60_edac.c
@@ -121,7 +121,7 @@ static int __devinit mv64x60_pci_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
platform_set_drvdata(pdev, pci);
pci->dev = &pdev->dev;
- pci->dev_name = pdev->dev.bus_id;
+ pci->dev_name = dev_name(&pdev->dev);
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;
@@ -294,7 +294,7 @@ static int __devinit mv64x60_sram_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
edac_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, edac_dev);
- edac_dev->dev_name = pdev->dev.bus_id;
+ edac_dev->dev_name = dev_name(&pdev->dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
@@ -462,7 +462,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
edac_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, edac_dev);
- edac_dev->dev_name = pdev->dev.bus_id;
+ edac_dev->dev_name = dev_name(&pdev->dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
@@ -713,7 +713,7 @@ static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mci);
pdata->name = "mv64x60_mc_err";
pdata->irq = NO_IRQ;
- mci->dev_name = pdev->dev.bus_id;
+ mci->dev_name = dev_name(&pdev->dev);
pdata->edac_idx = edac_mc_idx++;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index c950bf8606d..66958b3f10b 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -200,7 +200,7 @@ static int __init eisa_init_device (struct eisa_root_device *root,
edev->dev.bus = &eisa_bus_type;
edev->dev.dma_mask = &edev->dma_mask;
edev->dev.coherent_dma_mask = edev->dma_mask;
- sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot);
+ dev_set_name(&edev->dev, "%02X:%02X", root->bus_nr, slot);
for (i = 0; i < EISA_MAX_RESOURCES; i++) {
#ifdef CONFIG_EISA_NAMES
@@ -301,7 +301,7 @@ static int __init eisa_probe (struct eisa_root_device *root)
struct eisa_device *edev;
printk (KERN_INFO "EISA: Probing bus %d at %s\n",
- root->bus_nr, root->dev->bus_id);
+ root->bus_nr, dev_name(root->dev));
/* First try to get hold of slot 0. If there is no device
* here, simply fail, unless root->force_probe is set. */
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 6bd91a15d5e..a5dd7a665aa 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -232,7 +232,7 @@ fw_card_bm_work(struct work_struct *work)
root_id = root_node->node_id;
grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
- if (card->bm_generation + 1 == generation ||
+ if (is_next_generation(generation, card->bm_generation) ||
(card->bm_generation != generation && grace)) {
/*
* This first step is to figure out who is IRM and
@@ -412,6 +412,7 @@ fw_card_add(struct fw_card *card,
{
u32 *config_rom;
size_t length;
+ int err;
card->max_receive = max_receive;
card->link_speed = link_speed;
@@ -422,7 +423,13 @@ fw_card_add(struct fw_card *card,
list_add_tail(&card->link, &card_list);
mutex_unlock(&card_mutex);
- return card->driver->enable(card, config_rom, length);
+ err = card->driver->enable(card, config_rom, length);
+ if (err < 0) {
+ mutex_lock(&card_mutex);
+ list_del(&card->link);
+ mutex_unlock(&card_mutex);
+ }
+ return err;
}
EXPORT_SYMBOL(fw_card_add);
@@ -512,7 +519,7 @@ fw_core_remove_card(struct fw_card *card)
fw_core_initiate_bus_reset(card, 1);
mutex_lock(&card_mutex);
- list_del(&card->link);
+ list_del_init(&card->link);
mutex_unlock(&card_mutex);
/* Set up the dummy driver. */
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 2af5a8d1e01..bf53acb4565 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -25,6 +25,7 @@
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/idr.h>
+#include <linux/jiffies.h>
#include <linux/string.h>
#include <linux/rwsem.h>
#include <linux/semaphore.h>
@@ -634,12 +635,39 @@ struct fw_device *fw_device_get_by_devt(dev_t devt)
return device;
}
+/*
+ * These defines control the retry behavior for reading the config
+ * rom. It shouldn't be necessary to tweak these; if the device
+ * doesn't respond to a config rom read within 10 seconds, it's not
+ * going to respond at all. As for the initial delay, a lot of
+ * devices will be able to respond within half a second after bus
+ * reset. On the other hand, it's not really worth being more
+ * aggressive than that, since it scales pretty well; if 10 devices
+ * are plugged in, they're all getting read within one second.
+ */
+
+#define MAX_RETRIES 10
+#define RETRY_DELAY (3 * HZ)
+#define INITIAL_DELAY (HZ / 2)
+#define SHUTDOWN_DELAY (2 * HZ)
+
static void fw_device_shutdown(struct work_struct *work)
{
struct fw_device *device =
container_of(work, struct fw_device, work.work);
int minor = MINOR(device->device.devt);
+ if (time_is_after_jiffies(device->card->reset_jiffies + SHUTDOWN_DELAY)
+ && !list_empty(&device->card->link)) {
+ schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
+ return;
+ }
+
+ if (atomic_cmpxchg(&device->state,
+ FW_DEVICE_GONE,
+ FW_DEVICE_SHUTDOWN) != FW_DEVICE_GONE)
+ return;
+
fw_device_cdev_remove(device);
device_for_each_child(&device->device, NULL, shutdown_unit);
device_unregister(&device->device);
@@ -647,6 +675,7 @@ static void fw_device_shutdown(struct work_struct *work)
down_write(&fw_device_rwsem);
idr_remove(&fw_device_idr, minor);
up_write(&fw_device_rwsem);
+
fw_device_put(device);
}
@@ -654,25 +683,63 @@ static struct device_type fw_device_type = {
.release = fw_device_release,
};
+static void fw_device_update(struct work_struct *work);
+
/*
- * These defines control the retry behavior for reading the config
- * rom. It shouldn't be necessary to tweak these; if the device
- * doesn't respond to a config rom read within 10 seconds, it's not
- * going to respond at all. As for the initial delay, a lot of
- * devices will be able to respond within half a second after bus
- * reset. On the other hand, it's not really worth being more
- * aggressive than that, since it scales pretty well; if 10 devices
- * are plugged in, they're all getting read within one second.
+ * If a device was pending for deletion because its node went away but its
+ * bus info block and root directory header matches that of a newly discovered
+ * device, revive the existing fw_device.
+ * The newly allocated fw_device becomes obsolete instead.
*/
+static int lookup_existing_device(struct device *dev, void *data)
+{
+ struct fw_device *old = fw_device(dev);
+ struct fw_device *new = data;
+ struct fw_card *card = new->card;
+ int match = 0;
+
+ down_read(&fw_device_rwsem); /* serialize config_rom access */
+ spin_lock_irq(&card->lock); /* serialize node access */
+
+ if (memcmp(old->config_rom, new->config_rom, 6 * 4) == 0 &&
+ atomic_cmpxchg(&old->state,
+ FW_DEVICE_GONE,
+ FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
+ struct fw_node *current_node = new->node;
+ struct fw_node *obsolete_node = old->node;
+
+ new->node = obsolete_node;
+ new->node->data = new;
+ old->node = current_node;
+ old->node->data = old;
+
+ old->max_speed = new->max_speed;
+ old->node_id = current_node->node_id;
+ smp_wmb(); /* update node_id before generation */
+ old->generation = card->generation;
+ old->config_rom_retries = 0;
+ fw_notify("rediscovered device %s\n", dev_name(dev));
-#define MAX_RETRIES 10
-#define RETRY_DELAY (3 * HZ)
-#define INITIAL_DELAY (HZ / 2)
+ PREPARE_DELAYED_WORK(&old->work, fw_device_update);
+ schedule_delayed_work(&old->work, 0);
+
+ if (current_node == card->root_node)
+ fw_schedule_bm_work(card, 0);
+
+ match = 1;
+ }
+
+ spin_unlock_irq(&card->lock);
+ up_read(&fw_device_rwsem);
+
+ return match;
+}
static void fw_device_init(struct work_struct *work)
{
struct fw_device *device =
container_of(work, struct fw_device, work.work);
+ struct device *revived_dev;
int minor, err;
/*
@@ -696,6 +763,15 @@ static void fw_device_init(struct work_struct *work)
return;
}
+ revived_dev = device_find_child(device->card->device,
+ device, lookup_existing_device);
+ if (revived_dev) {
+ put_device(revived_dev);
+ fw_device_release(&device->device);
+
+ return;
+ }
+
device_initialize(&device->device);
fw_device_get(device);
@@ -734,9 +810,10 @@ static void fw_device_init(struct work_struct *work)
* fw_node_event().
*/
if (atomic_cmpxchg(&device->state,
- FW_DEVICE_INITIALIZING,
- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
- fw_device_shutdown(work);
+ FW_DEVICE_INITIALIZING,
+ FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
+ PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
+ schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
} else {
if (device->config_rom_retries)
fw_notify("created device %s: GUID %08x%08x, S%d00, "
@@ -847,8 +924,8 @@ static void fw_device_refresh(struct work_struct *work)
case REREAD_BIB_UNCHANGED:
if (atomic_cmpxchg(&device->state,
- FW_DEVICE_INITIALIZING,
- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
+ FW_DEVICE_INITIALIZING,
+ FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
goto gone;
fw_device_update(work);
@@ -879,8 +956,8 @@ static void fw_device_refresh(struct work_struct *work)
create_units(device);
if (atomic_cmpxchg(&device->state,
- FW_DEVICE_INITIALIZING,
- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
+ FW_DEVICE_INITIALIZING,
+ FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
goto gone;
fw_notify("refreshed device %s\n", dev_name(&device->device));
@@ -890,8 +967,9 @@ static void fw_device_refresh(struct work_struct *work)
give_up:
fw_notify("giving up on refresh of device %s\n", dev_name(&device->device));
gone:
- atomic_set(&device->state, FW_DEVICE_SHUTDOWN);
- fw_device_shutdown(work);
+ atomic_set(&device->state, FW_DEVICE_GONE);
+ PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
+ schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
out:
if (node_id == card->root_node->node_id)
fw_schedule_bm_work(card, 0);
@@ -995,9 +1073,10 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
*/
device = node->data;
if (atomic_xchg(&device->state,
- FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) {
+ FW_DEVICE_GONE) == FW_DEVICE_RUNNING) {
PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
- schedule_delayed_work(&device->work, 0);
+ schedule_delayed_work(&device->work,
+ list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);
}
break;
}
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index df51732608d..8ef6ec2ca21 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -28,6 +28,7 @@
enum fw_device_state {
FW_DEVICE_INITIALIZING,
FW_DEVICE_RUNNING,
+ FW_DEVICE_GONE,
FW_DEVICE_SHUTDOWN,
};
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index ab9c01e462e..6d19828a93a 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -226,7 +226,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
#define CONTEXT_DEAD 0x0800
#define CONTEXT_ACTIVE 0x0400
-#define OHCI1394_MAX_AT_REQ_RETRIES 0x2
+#define OHCI1394_MAX_AT_REQ_RETRIES 0xf
#define OHCI1394_MAX_AT_RESP_RETRIES 0x2
#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8
@@ -896,11 +896,11 @@ static void context_stop(struct context *ctx)
for (i = 0; i < 10; i++) {
reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs));
if ((reg & CONTEXT_ACTIVE) == 0)
- break;
+ return;
- fw_notify("context_stop: still active (0x%08x)\n", reg);
mdelay(1);
}
+ fw_error("Error: DMA context still active (0x%08x)\n", reg);
}
struct driver_data {
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index e88d5067448..c71c4419d9e 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -168,6 +168,7 @@ struct sbp2_target {
int address_high;
unsigned int workarounds;
unsigned int mgt_orb_timeout;
+ unsigned int max_payload;
int dont_block; /* counter for each logical unit */
int blocked; /* ditto */
@@ -310,14 +311,16 @@ struct sbp2_command_orb {
dma_addr_t page_table_bus;
};
+#define SBP2_ROM_VALUE_WILDCARD ~0 /* match all */
+#define SBP2_ROM_VALUE_MISSING 0xff000000 /* not present in the unit dir. */
+
/*
* List of devices with known bugs.
*
* The firmware_revision field, masked with 0xffff00, is the best
* indicator for the type of bridge chip of a device. It yields a few
* false positives but this did not break correctly behaving devices
- * so far. We use ~0 as a wildcard, since the 24 bit values we get
- * from the config rom can never match that.
+ * so far.
*/
static const struct {
u32 firmware_revision;
@@ -339,33 +342,35 @@ static const struct {
},
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
- .model = ~0,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_INQUIRY_36,
},
/* PL-3507 bridge with Prolific firmware */ {
.firmware_revision = 0x012800,
- .model = ~0,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_POWER_CONDITION,
},
/* Symbios bridge */ {
.firmware_revision = 0xa0b800,
- .model = ~0,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
/* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
.firmware_revision = 0x002600,
- .model = ~0,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
-
/*
- * There are iPods (2nd gen, 3rd gen) with model_id == 0, but
- * these iPods do not feature the read_capacity bug according
- * to one report. Read_capacity behaviour as well as model_id
- * could change due to Apple-supplied firmware updates though.
+ * iPod 2nd generation: needs 128k max transfer size workaround
+ * iPod 3rd generation: needs fix capacity workaround
*/
-
- /* iPod 4th generation. */ {
+ {
+ .firmware_revision = 0x0a2700,
+ .model = 0x000000,
+ .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS |
+ SBP2_WORKAROUND_FIX_CAPACITY,
+ },
+ /* iPod 4th generation */ {
.firmware_revision = 0x0a2700,
.model = 0x000021,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
@@ -1092,7 +1097,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
continue;
if (sbp2_workarounds_table[i].model != model &&
- sbp2_workarounds_table[i].model != ~0)
+ sbp2_workarounds_table[i].model != SBP2_ROM_VALUE_WILDCARD)
continue;
w |= sbp2_workarounds_table[i].workarounds;
@@ -1142,20 +1147,28 @@ static int sbp2_probe(struct device *dev)
fw_device_get(device);
fw_unit_get(unit);
- /* Initialize to values that won't match anything in our table. */
- firmware_revision = 0xff000000;
- model = 0xff000000;
-
/* implicit directory ID */
tgt->directory_id = ((unit->directory - device->config_rom) * 4
+ CSR_CONFIG_ROM) & 0xffffff;
+ firmware_revision = SBP2_ROM_VALUE_MISSING;
+ model = SBP2_ROM_VALUE_MISSING;
+
if (sbp2_scan_unit_dir(tgt, unit->directory, &model,
&firmware_revision) < 0)
goto fail_tgt_put;
sbp2_init_workarounds(tgt, model, firmware_revision);
+ /*
+ * At S100 we can do 512 bytes per packet, at S200 1024 bytes,
+ * and so on up to 4096 bytes. The SBP-2 max_payload field
+ * specifies the max payload size as 2 ^ (max_payload + 2), so
+ * if we set this to max_speed + 7, we get the right value.
+ */
+ tgt->max_payload = min(device->max_speed + 7, 10U);
+ tgt->max_payload = min(tgt->max_payload, device->card->max_receive - 1);
+
/* Do the login in a workqueue so we can easily reschedule retries. */
list_for_each_entry(lu, &tgt->lu_list, link)
sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
@@ -1273,6 +1286,19 @@ static struct fw_driver sbp2_driver = {
.id_table = sbp2_id_table,
};
+static void sbp2_unmap_scatterlist(struct device *card_device,
+ struct sbp2_command_orb *orb)
+{
+ if (scsi_sg_count(orb->cmd))
+ dma_unmap_sg(card_device, scsi_sglist(orb->cmd),
+ scsi_sg_count(orb->cmd),
+ orb->cmd->sc_data_direction);
+
+ if (orb->request.misc & cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT))
+ dma_unmap_single(card_device, orb->page_table_bus,
+ sizeof(orb->page_table), DMA_TO_DEVICE);
+}
+
static unsigned int
sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
{
@@ -1352,15 +1378,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
dma_unmap_single(device->card->device, orb->base.request_bus,
sizeof(orb->request), DMA_TO_DEVICE);
-
- if (scsi_sg_count(orb->cmd) > 0)
- dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
- scsi_sg_count(orb->cmd),
- orb->cmd->sc_data_direction);
-
- if (orb->page_table_bus != 0)
- dma_unmap_single(device->card->device, orb->page_table_bus,
- sizeof(orb->page_table), DMA_TO_DEVICE);
+ sbp2_unmap_scatterlist(device->card->device, orb);
orb->cmd->result = result;
orb->done(orb->cmd);
@@ -1434,7 +1452,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
struct sbp2_logical_unit *lu = cmd->device->hostdata;
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_command_orb *orb;
- unsigned int max_payload;
int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
/*
@@ -1462,17 +1479,9 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
orb->done = done;
orb->cmd = cmd;
- orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL);
- /*
- * At speed 100 we can do 512 bytes per packet, at speed 200,
- * 1024 bytes per packet etc. The SBP-2 max_payload field
- * specifies the max payload size as 2 ^ (max_payload + 2), so
- * if we set this to max_speed + 7, we get the right value.
- */
- max_payload = min(device->max_speed + 7,
- device->card->max_receive - 1);
+ orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL);
orb->request.misc = cpu_to_be32(
- COMMAND_ORB_MAX_PAYLOAD(max_payload) |
+ COMMAND_ORB_MAX_PAYLOAD(lu->tgt->max_payload) |
COMMAND_ORB_SPEED(device->max_speed) |
COMMAND_ORB_NOTIFY);
@@ -1491,8 +1500,10 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
orb->base.request_bus =
dma_map_single(device->card->device, &orb->request,
sizeof(orb->request), DMA_TO_DEVICE);
- if (dma_mapping_error(device->card->device, orb->base.request_bus))
+ if (dma_mapping_error(device->card->device, orb->base.request_bus)) {
+ sbp2_unmap_scatterlist(device->card->device, orb);
goto out;
+ }
sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation,
lu->command_block_agent_address + SBP2_ORB_POINTER);
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index c9be6e6948c..8dd6703b55c 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -518,6 +518,18 @@ fw_core_handle_bus_reset(struct fw_card *card,
struct fw_node *local_node;
unsigned long flags;
+ /*
+ * If the selfID buffer is not the immediate successor of the
+ * previously processed one, we cannot reliably compare the
+ * old and new topologies.
+ */
+ if (!is_next_generation(generation, card->generation) &&
+ card->local_node != NULL) {
+ fw_notify("skipped bus generations, destroying all nodes\n");
+ fw_destroy_nodes(card);
+ card->bm_retries = 0;
+ }
+
spin_lock_irqsave(&card->lock, flags);
card->node_id = node_id;
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index c9ab12a15f6..1d78e9cc594 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -276,6 +276,15 @@ static inline void fw_card_put(struct fw_card *card)
extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);
/*
+ * Check whether new_generation is the immediate successor of old_generation.
+ * Take counter roll-over at 255 (as per to OHCI) into account.
+ */
+static inline bool is_next_generation(int new_generation, int old_generation)
+{
+ return (new_generation & 0xff) == ((old_generation + 1) & 0xff);
+}
+
+/*
* The iso packet format allows for an immediate header/payload part
* stored in 'header' immediately after the packet info plus an
* indirect payload part that is pointer to by the 'payload' field.
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 13946ebd77d..b4704e150b2 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -576,7 +576,7 @@ static ssize_t read_rbu_image_type(struct kobject *kobj,
{
int size = 0;
if (!pos)
- size = sprintf(buffer, "%s\n", image_type);
+ size = scnprintf(buffer, count, "%s\n", image_type);
return size;
}
@@ -648,7 +648,7 @@ static ssize_t read_rbu_packet_size(struct kobject *kobj,
int size = 0;
if (!pos) {
spin_lock(&rbu_data.lock);
- size = sprintf(buffer, "%lu\n", rbu_data.packetsize);
+ size = scnprintf(buffer, count, "%lu\n", rbu_data.packetsize);
spin_unlock(&rbu_data.lock);
}
return size;
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index d76adfea5df..8f0f7c44930 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -415,6 +415,29 @@ void __init dmi_scan_machine(void)
}
/**
+ * dmi_matches - check if dmi_system_id structure matches system DMI data
+ * @dmi: pointer to the dmi_system_id structure to check
+ */
+static bool dmi_matches(const struct dmi_system_id *dmi)
+{
+ int i;
+
+ WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n");
+
+ for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) {
+ int s = dmi->matches[i].slot;
+ if (s == DMI_NONE)
+ continue;
+ if (dmi_ident[s]
+ && strstr(dmi_ident[s], dmi->matches[i].substr))
+ continue;
+ /* No match */
+ return false;
+ }
+ return true;
+}
+
+/**
* dmi_check_system - check system DMI data
* @list: array of dmi_system_id structures to match against
* All non-null elements of the list must match
@@ -429,32 +452,45 @@ void __init dmi_scan_machine(void)
*/
int dmi_check_system(const struct dmi_system_id *list)
{
- int i, count = 0;
- const struct dmi_system_id *d = list;
-
- WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n");
-
- while (d->ident) {
- for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
- int s = d->matches[i].slot;
- if (s == DMI_NONE)
- continue;
- if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
- continue;
- /* No match */
- goto fail;
+ int count = 0;
+ const struct dmi_system_id *d;
+
+ for (d = list; d->ident; d++)
+ if (dmi_matches(d)) {
+ count++;
+ if (d->callback && d->callback(d))
+ break;
}
- count++;
- if (d->callback && d->callback(d))
- break;
-fail: d++;
- }
return count;
}
EXPORT_SYMBOL(dmi_check_system);
/**
+ * dmi_first_match - find dmi_system_id structure matching system DMI data
+ * @list: array of dmi_system_id structures to match against
+ * All non-null elements of the list must match
+ * their slot's (field index's) data (i.e., each
+ * list string must be a substring of the specified
+ * DMI slot's string data) to be considered a
+ * successful match.
+ *
+ * Walk the blacklist table until the first match is found. Return the
+ * pointer to the matching entry or NULL if there's no match.
+ */
+const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list)
+{
+ const struct dmi_system_id *d;
+
+ for (d = list; d->ident; d++)
+ if (dmi_matches(d))
+ return d;
+
+ return NULL;
+}
+EXPORT_SYMBOL(dmi_first_match);
+
+/**
* dmi_get_system_info - return DMI data value
* @field: data index (see enum dmi_field)
*
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index 261b9aa3f24..05aa2d406ac 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/firmware/memmap.c
* Copyright (C) 2008 SUSE LINUX Products GmbH
- * by Bernhard Walle <bwalle@suse.de>
+ * by Bernhard Walle <bernhard.walle@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License v2.0 as published by
diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/bt8xxgpio.c
index 7a1168249dd..984b587f0f9 100644
--- a/drivers/gpio/bt8xxgpio.c
+++ b/drivers/gpio/bt8xxgpio.c
@@ -160,7 +160,7 @@ static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
{
struct gpio_chip *c = &bg->gpio;
- c->label = bg->pdev->dev.bus_id;
+ c->label = dev_name(&bg->pdev->dev);
c->owner = THIS_MODULE;
c->direction_input = bt8xxgpio_gpio_direction_input;
c->get = bt8xxgpio_gpio_get;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 35e7aea4222..42fb2fd24c0 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -789,6 +789,7 @@ int gpio_request(unsigned gpio, const char *label)
} else {
status = -EBUSY;
module_put(chip->owner);
+ goto done;
}
if (chip->request) {
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 5130b72d593..3a22eb9be37 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -70,7 +70,7 @@ config DRM_I915
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- depends on FB
+ select FB
tristate "i915 driver"
help
Choose this option if you have a system that has Intel 830M, 845G,
@@ -80,18 +80,17 @@ config DRM_I915
XFree86 4.4 and above. If unsure, build this and i830 as modules and
the X server will load the correct one.
-endchoice
-
config DRM_I915_KMS
bool "Enable modesetting on intel by default"
depends on DRM_I915
help
- Choose this option if you want kernel modesetting enabled by default,
- and you have a new enough userspace to support this. Running old
- userspaces with this enabled will cause pain. Note that this causes
- the driver to bind to PCI devices, which precludes loading things
- like intelfb.
+ Choose this option if you want kernel modesetting enabled by default,
+ and you have a new enough userspace to support this. Running old
+ userspaces with this enabled will cause pain. Note that this causes
+ the driver to bind to PCI devices, which precludes loading things
+ like intelfb.
+endchoice
config DRM_MGA
tristate "Matrox g200/g400"
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
index 3d33b8252b5..14796594e5d 100644
--- a/drivers/gpu/drm/drm_agpsupport.c
+++ b/drivers/gpu/drm/drm_agpsupport.c
@@ -33,10 +33,11 @@
#include "drmP.h"
#include <linux/module.h>
-#include <asm/agp.h>
#if __OS_HAS_AGP
+#include <asm/agp.h>
+
/**
* Get AGP information.
*
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 72c667f9bee..12715d3c078 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -420,7 +420,7 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
dev->sigdata.lock = NULL;
master->lock.hw_lock = NULL; /* SHM removed */
master->lock.file_priv = NULL;
- wake_up_interruptible(&master->lock.lock_queue);
+ wake_up_interruptible_all(&master->lock.lock_queue);
}
break;
case _DRM_AGP:
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5b2cbb77816..94a76887173 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -194,7 +194,6 @@ char *drm_get_connector_status_name(enum drm_connector_status status)
* @type: object type
*
* LOCKING:
- * Caller must hold DRM mode_config lock.
*
* Create a unique identifier based on @ptr in @dev's identifier space. Used
* for tracking modes, CRTCs and connectors.
@@ -209,15 +208,15 @@ static int drm_mode_object_get(struct drm_device *dev,
int new_id = 0;
int ret;
- WARN(!mutex_is_locked(&dev->mode_config.mutex),
- "%s called w/o mode_config lock\n", __func__);
again:
if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Ran out memory getting a mode number\n");
return -EINVAL;
}
+ mutex_lock(&dev->mode_config.idr_mutex);
ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
+ mutex_unlock(&dev->mode_config.idr_mutex);
if (ret == -EAGAIN)
goto again;
@@ -239,16 +238,20 @@ again:
static void drm_mode_object_put(struct drm_device *dev,
struct drm_mode_object *object)
{
+ mutex_lock(&dev->mode_config.idr_mutex);
idr_remove(&dev->mode_config.crtc_idr, object->id);
+ mutex_unlock(&dev->mode_config.idr_mutex);
}
void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
{
- struct drm_mode_object *obj;
+ struct drm_mode_object *obj = NULL;
+ mutex_lock(&dev->mode_config.idr_mutex);
obj = idr_find(&dev->mode_config.crtc_idr, id);
if (!obj || (obj->type != type) || (obj->id != id))
- return NULL;
+ obj = NULL;
+ mutex_unlock(&dev->mode_config.idr_mutex);
return obj;
}
@@ -786,6 +789,7 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property);
void drm_mode_config_init(struct drm_device *dev)
{
mutex_init(&dev->mode_config.mutex);
+ mutex_init(&dev->mode_config.idr_mutex);
INIT_LIST_HEAD(&dev->mode_config.fb_list);
INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
INIT_LIST_HEAD(&dev->mode_config.crtc_list);
@@ -1737,9 +1741,8 @@ out:
* RETURNS:
* Zero on success, errno on failure.
*/
-void drm_fb_release(struct file *filp)
+void drm_fb_release(struct drm_file *priv)
{
- struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_framebuffer *fb, *tfb;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index d8a982b7129..1c3a8c55714 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -36,7 +36,7 @@
/*
* Detailed mode info for 800x600@60Hz
*/
-static struct drm_display_mode std_mode[] = {
+static struct drm_display_mode std_modes[] = {
{ DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 40000, 800, 840,
968, 1056, 0, 600, 601, 605, 628, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
@@ -60,15 +60,18 @@ static struct drm_display_mode std_mode[] = {
* changes have occurred.
*
* FIXME: take into account monitor limits
+ *
+ * RETURNS:
+ * Number of modes found on @connector.
*/
-void drm_helper_probe_single_connector_modes(struct drm_connector *connector,
- uint32_t maxX, uint32_t maxY)
+int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
+ uint32_t maxX, uint32_t maxY)
{
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *t;
struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
- int ret;
+ int count = 0;
DRM_DEBUG("%s\n", drm_get_connector_name(connector));
/* set all modes to the unverified state */
@@ -81,14 +84,14 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector,
DRM_DEBUG("%s is disconnected\n",
drm_get_connector_name(connector));
/* TODO set EDID to NULL */
- return;
+ return 0;
}
- ret = (*connector_funcs->get_modes)(connector);
+ count = (*connector_funcs->get_modes)(connector);
+ if (!count)
+ return 0;
- if (ret) {
- drm_mode_connector_list_update(connector);
- }
+ drm_mode_connector_list_update(connector);
if (maxX && maxY)
drm_mode_validate_size(dev, &connector->modes, maxX,
@@ -102,25 +105,8 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector,
drm_mode_prune_invalid(dev, &connector->modes, true);
- if (list_empty(&connector->modes)) {
- struct drm_display_mode *stdmode;
-
- DRM_DEBUG("No valid modes on %s\n",
- drm_get_connector_name(connector));
-
- /* Should we do this here ???
- * When no valid EDID modes are available we end up
- * here and bailed in the past, now we add a standard
- * 640x480@60Hz mode and carry on.
- */
- stdmode = drm_mode_duplicate(dev, &std_mode[0]);
- drm_mode_probed_add(connector, stdmode);
- drm_mode_list_concat(&connector->probed_modes,
- &connector->modes);
-
- DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
- drm_get_connector_name(connector));
- }
+ if (list_empty(&connector->modes))
+ return 0;
drm_mode_sort(&connector->modes);
@@ -131,20 +117,58 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector,
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
drm_mode_debug_printmodeline(mode);
}
+
+ return count;
}
EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
-void drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
+int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
uint32_t maxY)
{
struct drm_connector *connector;
+ int count = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- drm_helper_probe_single_connector_modes(connector, maxX, maxY);
+ count += drm_helper_probe_single_connector_modes(connector,
+ maxX, maxY);
}
+
+ return count;
}
EXPORT_SYMBOL(drm_helper_probe_connector_modes);
+static void drm_helper_add_std_modes(struct drm_device *dev,
+ struct drm_connector *connector)
+{
+ struct drm_display_mode *mode, *t;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(std_modes); i++) {
+ struct drm_display_mode *stdmode;
+
+ /*
+ * When no valid EDID modes are available we end up
+ * here and bailed in the past, now we add some standard
+ * modes and move on.
+ */
+ stdmode = drm_mode_duplicate(dev, &std_modes[i]);
+ drm_mode_probed_add(connector, stdmode);
+ drm_mode_list_concat(&connector->probed_modes,
+ &connector->modes);
+
+ DRM_DEBUG("Adding mode %s to %s\n", stdmode->name,
+ drm_get_connector_name(connector));
+ }
+ drm_mode_sort(&connector->modes);
+
+ DRM_DEBUG("Added std modes on %s\n", drm_get_connector_name(connector));
+ list_for_each_entry_safe(mode, t, &connector->modes, head) {
+ mode->vrefresh = drm_mode_vrefresh(mode);
+
+ drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+ drm_mode_debug_printmodeline(mode);
+ }
+}
/**
* drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
@@ -237,6 +261,8 @@ static void drm_enable_connectors(struct drm_device *dev, bool *enabled)
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
enabled[i] = drm_connector_enabled(connector, true);
+ DRM_DEBUG("connector %d enabled? %s\n", connector->base.id,
+ enabled[i] ? "yes" : "no");
any_enabled |= enabled[i];
i++;
}
@@ -265,11 +291,17 @@ static bool drm_target_preferred(struct drm_device *dev,
continue;
}
+ DRM_DEBUG("looking for preferred mode on connector %d\n",
+ connector->base.id);
+
modes[i] = drm_has_preferred_mode(connector, width, height);
- if (!modes[i]) {
+ /* No preferred modes, pick one off the list */
+ if (!modes[i] && !list_empty(&connector->modes)) {
list_for_each_entry(modes[i], &connector->modes, head)
break;
}
+ DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name :
+ "none");
i++;
}
return true;
@@ -369,6 +401,8 @@ static void drm_setup_crtcs(struct drm_device *dev)
int width, height;
int i, ret;
+ DRM_DEBUG("\n");
+
width = dev->mode_config.max_width;
height = dev->mode_config.max_height;
@@ -390,6 +424,8 @@ static void drm_setup_crtcs(struct drm_device *dev)
if (!ret)
DRM_ERROR("Unable to find initial modes\n");
+ DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height);
+
drm_pick_crtcs(dev, crtcs, modes, 0, width, height);
i = 0;
@@ -403,6 +439,8 @@ static void drm_setup_crtcs(struct drm_device *dev)
}
if (mode && crtc) {
+ DRM_DEBUG("desired mode %s set on crtc %d\n",
+ mode->name, crtc->base.id);
crtc->desired_mode = mode;
connector->encoder->crtc = crtc;
} else
@@ -414,6 +452,59 @@ static void drm_setup_crtcs(struct drm_device *dev)
kfree(modes);
kfree(enabled);
}
+
+/**
+ * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
+ * @encoder: encoder to test
+ * @crtc: crtc to test
+ *
+ * Return false if @encoder can't be driven by @crtc, true otherwise.
+ */
+static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
+ struct drm_crtc *crtc)
+{
+ struct drm_device *dev;
+ struct drm_crtc *tmp;
+ int crtc_mask = 1;
+
+ WARN(!crtc, "checking null crtc?");
+
+ dev = crtc->dev;
+
+ list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
+ if (tmp == crtc)
+ break;
+ crtc_mask <<= 1;
+ }
+
+ if (encoder->possible_crtcs & crtc_mask)
+ return true;
+ return false;
+}
+
+/*
+ * Check the CRTC we're going to map each output to vs. its current
+ * CRTC. If they don't match, we have to disable the output and the CRTC
+ * since the driver will have to re-route things.
+ */
+static void
+drm_crtc_prepare_encoders(struct drm_device *dev)
+{
+ struct drm_encoder_helper_funcs *encoder_funcs;
+ struct drm_encoder *encoder;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ encoder_funcs = encoder->helper_private;
+ /* Disable unused encoders */
+ if (encoder->crtc == NULL)
+ (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+ /* Disable encoders whose CRTC is about to change */
+ if (encoder_funcs->get_crtc &&
+ encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
+ (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+ }
+}
+
/**
* drm_crtc_set_mode - set a mode
* @crtc: CRTC to program
@@ -442,6 +533,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
int saved_x, saved_y;
struct drm_encoder *encoder;
bool ret = true;
+ bool depth_changed, bpp_changed;
adjusted_mode = drm_mode_duplicate(dev, mode);
@@ -450,6 +542,15 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
if (!crtc->enabled)
return true;
+ if (old_fb && crtc->fb) {
+ depth_changed = (old_fb->depth != crtc->fb->depth);
+ bpp_changed = (old_fb->bits_per_pixel !=
+ crtc->fb->bits_per_pixel);
+ } else {
+ depth_changed = true;
+ bpp_changed = true;
+ }
+
saved_mode = crtc->mode;
saved_x = crtc->x;
saved_y = crtc->y;
@@ -462,9 +563,10 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
crtc->y = y;
if (drm_mode_equal(&saved_mode, &crtc->mode)) {
- if (saved_x != crtc->x || saved_y != crtc->y) {
- crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
- old_fb);
+ if (saved_x != crtc->x || saved_y != crtc->y ||
+ depth_changed || bpp_changed) {
+ ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
+ old_fb);
goto done;
}
}
@@ -498,12 +600,16 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
encoder_funcs->prepare(encoder);
}
+ drm_crtc_prepare_encoders(dev);
+
crtc_funcs->prepare(crtc);
/* Set up the DPLL and any encoders state that needs to adjust or depend
* on the DPLL.
*/
- crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
+ ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
+ if (!ret)
+ goto done;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -566,10 +672,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
struct drm_device *dev;
struct drm_crtc **save_crtcs, *new_crtc;
struct drm_encoder **save_encoders, *new_encoder;
- struct drm_framebuffer *old_fb;
+ struct drm_framebuffer *old_fb = NULL;
bool save_enabled;
- bool changed = false;
- bool flip_or_move = false;
+ bool mode_changed = false;
+ bool fb_changed = false;
struct drm_connector *connector;
int count = 0, ro, fail = 0;
struct drm_crtc_helper_funcs *crtc_funcs;
@@ -597,7 +703,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
/* save previous config */
save_enabled = set->crtc->enabled;
- /* this is meant to be num_connector not num_crtc */
+ /*
+ * We do mode_config.num_connectors here since we'll look at the
+ * CRTC and encoder associated with each connector later.
+ */
save_crtcs = kzalloc(dev->mode_config.num_connector *
sizeof(struct drm_crtc *), GFP_KERNEL);
if (!save_crtcs)
@@ -613,21 +722,26 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
/* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */
if (set->crtc->fb != set->fb) {
- /* if we have no fb then its a change not a flip */
- if (set->crtc->fb == NULL)
- changed = true;
+ /* If we have no fb then treat it as a full mode set */
+ if (set->crtc->fb == NULL) {
+ DRM_DEBUG("crtc has no fb, full mode set\n");
+ mode_changed = true;
+ } else if ((set->fb->bits_per_pixel !=
+ set->crtc->fb->bits_per_pixel) ||
+ set->fb->depth != set->crtc->fb->depth)
+ fb_changed = true;
else
- flip_or_move = true;
+ fb_changed = true;
}
if (set->x != set->crtc->x || set->y != set->crtc->y)
- flip_or_move = true;
+ fb_changed = true;
if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
- DRM_DEBUG("modes are different\n");
+ DRM_DEBUG("modes are different, full mode set\n");
drm_mode_debug_printmodeline(&set->crtc->mode);
drm_mode_debug_printmodeline(set->mode);
- changed = true;
+ mode_changed = true;
}
/* a) traverse passed in connector list and get encoders for them */
@@ -650,7 +764,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
}
if (new_encoder != connector->encoder) {
- changed = true;
+ DRM_DEBUG("encoder changed, full mode switch\n");
+ mode_changed = true;
connector->encoder = new_encoder;
}
}
@@ -676,17 +791,27 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if (set->connectors[ro] == connector)
new_crtc = set->crtc;
}
+
+ /* Make sure the new CRTC will work with the encoder */
+ if (new_crtc &&
+ !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
+ ret = -EINVAL;
+ goto fail_set_mode;
+ }
if (new_crtc != connector->encoder->crtc) {
- changed = true;
+ DRM_DEBUG("crtc changed, full mode switch\n");
+ mode_changed = true;
connector->encoder->crtc = new_crtc;
}
+ DRM_DEBUG("setting connector %d crtc to %p\n",
+ connector->base.id, new_crtc);
}
/* mode_set_base is not a required function */
- if (flip_or_move && !crtc_funcs->mode_set_base)
- changed = true;
+ if (fb_changed && !crtc_funcs->mode_set_base)
+ mode_changed = true;
- if (changed) {
+ if (mode_changed) {
old_fb = set->crtc->fb;
set->crtc->fb = set->fb;
set->crtc->enabled = (set->mode != NULL);
@@ -696,6 +821,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
set->x, set->y,
old_fb)) {
+ DRM_ERROR("failed to set mode on crtc %p\n",
+ set->crtc);
ret = -EINVAL;
goto fail_set_mode;
}
@@ -705,11 +832,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
set->crtc->desired_mode = set->mode;
}
drm_helper_disable_unused_functions(dev);
- } else if (flip_or_move) {
+ } else if (fb_changed) {
old_fb = set->crtc->fb;
if (set->crtc->fb != set->fb)
set->crtc->fb = set->fb;
- crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb);
+ ret = crtc_funcs->mode_set_base(set->crtc,
+ set->x, set->y, old_fb);
+ if (ret != 0)
+ goto fail_set_mode;
}
kfree(save_encoders);
@@ -718,9 +848,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
fail_set_mode:
set->crtc->enabled = save_enabled;
+ set->crtc->fb = old_fb;
count = 0;
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder)
+ continue;
+
connector->encoder->crtc = save_crtcs[count++];
+ }
fail_no_encoder:
kfree(save_crtcs);
count = 0;
@@ -764,10 +899,31 @@ bool drm_helper_plugged_event(struct drm_device *dev)
*/
bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
{
- int ret = false;
+ struct drm_connector *connector;
+ int count = 0;
- drm_helper_plugged_event(dev);
- return ret;
+ count = drm_helper_probe_connector_modes(dev,
+ dev->mode_config.max_width,
+ dev->mode_config.max_height);
+
+ /*
+ * None of the available connectors had any modes, so add some
+ * and try to light them up anyway
+ */
+ if (!count) {
+ DRM_ERROR("connectors have no modes, using standard modes\n");
+ list_for_each_entry(connector,
+ &dev->mode_config.connector_list,
+ head)
+ drm_helper_add_std_modes(dev, connector);
+ }
+
+ drm_setup_crtcs(dev);
+
+ /* alert the driver fb layer */
+ dev->mode_config.funcs->fb_changed(dev);
+
+ return 0;
}
EXPORT_SYMBOL(drm_helper_initial_config);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 5ff88d95222..14c7a23dc15 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -294,6 +294,7 @@ EXPORT_SYMBOL(drm_init);
*/
static void drm_cleanup(struct drm_device * dev)
{
+ struct drm_map_list *r_list, *list_temp;
DRM_DEBUG("\n");
if (!dev) {
@@ -325,6 +326,9 @@ static void drm_cleanup(struct drm_device * dev)
drm_ht_remove(&dev->map_hash);
drm_ctxbitmap_cleanup(dev);
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
+ drm_rmmap(dev, r_list->map);
+
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_put_minor(&dev->control);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 0fbb0da342c..a839a28d8ee 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -125,7 +125,7 @@ static bool edid_is_valid(struct edid *edid)
DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
goto bad;
}
- if (edid->revision <= 0 || edid->revision > 3) {
+ if (edid->revision > 3) {
DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision);
goto bad;
}
@@ -320,10 +320,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo);
mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo;
- mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) |
+ mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) |
pt->vsync_offset_lo);
mode->vsync_end = mode->vsync_start +
- ((pt->vsync_pulse_width_hi << 8) |
+ ((pt->vsync_pulse_width_hi << 4) |
pt->vsync_pulse_width_lo);
mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo);
@@ -660,7 +660,7 @@ struct edid *drm_get_edid(struct drm_connector *connector,
edid = (struct edid *)drm_ddc_read(adapter);
if (!edid) {
- dev_warn(&connector->dev->pdev->dev, "%s: no EDID data\n",
+ dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
drm_get_connector_name(connector));
return NULL;
}
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index b06a5371585..e13cb62bbae 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -337,14 +337,10 @@ int drm_fasync(int fd, struct file *filp, int on)
{
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
- int retcode;
DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
(long)old_encode_dev(priv->minor->device));
- retcode = fasync_helper(fd, filp, on, &dev->buf_async);
- if (retcode < 0)
- return retcode;
- return 0;
+ return fasync_helper(fd, filp, on, &dev->buf_async);
}
EXPORT_SYMBOL(drm_fasync);
@@ -457,6 +453,9 @@ int drm_release(struct inode *inode, struct file *filp)
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_release(dev, file_priv);
+ if (dev->driver->driver_features & DRIVER_MODESET)
+ drm_fb_release(file_priv);
+
mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n;
@@ -481,6 +480,7 @@ int drm_release(struct inode *inode, struct file *filp)
mutex_lock(&dev->struct_mutex);
if (file_priv->is_master) {
+ struct drm_master *master = file_priv->master;
struct drm_file *temp;
list_for_each_entry(temp, &dev->filelist, lhead) {
if ((temp->master == file_priv->master) &&
@@ -488,6 +488,19 @@ int drm_release(struct inode *inode, struct file *filp)
temp->authenticated = 0;
}
+ /**
+ * Since the master is disappearing, so is the
+ * possibility to lock.
+ */
+
+ if (master->lock.hw_lock) {
+ if (dev->sigdata.lock == master->lock.hw_lock)
+ dev->sigdata.lock = NULL;
+ master->lock.hw_lock = NULL;
+ master->lock.file_priv = NULL;
+ wake_up_interruptible_all(&master->lock.lock_queue);
+ }
+
if (file_priv->minor->master == file_priv->master) {
/* drop the reference held my the minor */
drm_master_put(&file_priv->minor->master);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 9da58145287..88d3368ffdd 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -104,8 +104,8 @@ drm_gem_init(struct drm_device *dev)
if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
DRM_FILE_PAGE_OFFSET_SIZE)) {
- drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
drm_ht_remove(&mm->offset_hash);
+ drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
return -ENOMEM;
}
@@ -136,7 +136,7 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
obj->dev = dev;
- obj->filp = shmem_file_setup("drm mm object", size, 0);
+ obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
if (IS_ERR(obj->filp)) {
kfree(obj);
return NULL;
@@ -295,35 +295,37 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
return -EBADF;
again:
- if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
- return -ENOMEM;
+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) {
+ ret = -ENOMEM;
+ goto err;
+ }
spin_lock(&dev->object_name_lock);
- if (obj->name) {
- args->name = obj->name;
+ if (!obj->name) {
+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
+ &obj->name);
+ args->name = (uint64_t) obj->name;
spin_unlock(&dev->object_name_lock);
- return 0;
- }
- ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
- &obj->name);
- spin_unlock(&dev->object_name_lock);
- if (ret == -EAGAIN)
- goto again;
- if (ret != 0) {
- mutex_lock(&dev->struct_mutex);
- drm_gem_object_unreference(obj);
- mutex_unlock(&dev->struct_mutex);
- return ret;
- }
+ if (ret == -EAGAIN)
+ goto again;
- /*
- * Leave the reference from the lookup around as the
- * name table now holds one
- */
- args->name = (uint64_t) obj->name;
+ if (ret != 0)
+ goto err;
- return 0;
+ /* Allocate a reference for the name table. */
+ drm_gem_object_reference(obj);
+ } else {
+ args->name = (uint64_t) obj->name;
+ spin_unlock(&dev->object_name_lock);
+ ret = 0;
+ }
+
+err:
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
}
/**
@@ -448,6 +450,7 @@ drm_gem_object_handle_free(struct kref *kref)
spin_lock(&dev->object_name_lock);
if (obj->name) {
idr_remove(&dev->object_name_idr, obj->name);
+ obj->name = 0;
spin_unlock(&dev->object_name_lock);
/*
* The object name held a reference to this object, drop
@@ -460,6 +463,26 @@ drm_gem_object_handle_free(struct kref *kref)
}
EXPORT_SYMBOL(drm_gem_object_handle_free);
+void drm_gem_vm_open(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+
+ drm_gem_object_reference(obj);
+}
+EXPORT_SYMBOL(drm_gem_vm_open);
+
+void drm_gem_vm_close(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+ struct drm_device *dev = obj->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+}
+EXPORT_SYMBOL(drm_gem_vm_close);
+
+
/**
* drm_gem_mmap - memory map routine for GEM objects
* @filp: DRM file pointer
@@ -521,6 +544,14 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
#endif
vma->vm_page_prot = __pgprot(prot);
+ /* Take a ref for this mapping of the object, so that the fault
+ * handler can dereference the mmap offset's pointer to the object.
+ * This reference is cleaned up by the corresponding vm_close
+ * (which should happen whether the vma was created by this call, or
+ * by a vm_open due to mremap or partial unmap or whatever).
+ */
+ drm_gem_object_reference(obj);
+
vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open_locked(vma);
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 724e505873c..93e677a481f 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -106,8 +106,6 @@ void drm_vblank_cleanup(struct drm_device *dev)
drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
DRM_MEM_DRIVER);
- drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
- DRM_MEM_DRIVER);
drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
dev->num_crtcs, DRM_MEM_DRIVER);
drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
@@ -132,7 +130,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
(unsigned long)dev);
spin_lock_init(&dev->vbl_lock);
- atomic_set(&dev->vbl_signal_pending, 0);
dev->num_crtcs = num_crtcs;
dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
@@ -140,11 +137,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
if (!dev->vbl_queue)
goto err;
- dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
- DRM_MEM_DRIVER);
- if (!dev->vbl_sigs)
- goto err;
-
dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
DRM_MEM_DRIVER);
if (!dev->_vblank_count)
@@ -177,7 +169,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
/* Zero per-crtc vblank stuff */
for (i = 0; i < num_crtcs; i++) {
init_waitqueue_head(&dev->vbl_queue[i]);
- INIT_LIST_HEAD(&dev->vbl_sigs[i]);
atomic_set(&dev->_vblank_count[i], 0);
atomic_set(&dev->vblank_refcount[i], 0);
}
@@ -267,7 +258,8 @@ EXPORT_SYMBOL(drm_irq_install);
*/
int drm_irq_uninstall(struct drm_device * dev)
{
- int irq_enabled;
+ unsigned long irqflags;
+ int irq_enabled, i;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
@@ -277,6 +269,17 @@ int drm_irq_uninstall(struct drm_device * dev)
dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);
+ /*
+ * Wake up any waiters so they don't hang.
+ */
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ for (i = 0; i < dev->num_crtcs; i++) {
+ DRM_WAKEUP(&dev->vbl_queue[i]);
+ dev->vblank_enabled[i] = 0;
+ dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
+ }
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+
if (!irq_enabled)
return -EINVAL;
@@ -432,6 +435,8 @@ EXPORT_SYMBOL(drm_vblank_get);
*/
void drm_vblank_put(struct drm_device *dev, int crtc)
{
+ BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0);
+
/* Last user schedules interrupt disable */
if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
@@ -457,8 +462,9 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
* so that interrupts remain enabled in the interim.
*/
if (!dev->vblank_inmodeset[crtc]) {
- dev->vblank_inmodeset[crtc] = 1;
- drm_vblank_get(dev, crtc);
+ dev->vblank_inmodeset[crtc] = 0x1;
+ if (drm_vblank_get(dev, crtc) == 0)
+ dev->vblank_inmodeset[crtc] |= 0x2;
}
}
EXPORT_SYMBOL(drm_vblank_pre_modeset);
@@ -470,9 +476,12 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
if (dev->vblank_inmodeset[crtc]) {
spin_lock_irqsave(&dev->vbl_lock, irqflags);
dev->vblank_disable_allowed = 1;
- dev->vblank_inmodeset[crtc] = 0;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- drm_vblank_put(dev, crtc);
+
+ if (dev->vblank_inmodeset[crtc] & 0x2)
+ drm_vblank_put(dev, crtc);
+
+ dev->vblank_inmodeset[crtc] = 0;
}
}
EXPORT_SYMBOL(drm_vblank_post_modeset);
@@ -529,15 +538,10 @@ out:
* \param data user argument, pointing to a drm_wait_vblank structure.
* \return zero on success or a negative number on failure.
*
- * Verifies the IRQ is installed.
- *
- * If a signal is requested checks if this task has already scheduled the same signal
- * for the same vblank sequence number - nothing to be done in
- * that case. If the number of tasks waiting for the interrupt exceeds 100 the
- * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
- * task.
- *
- * If a signal is not requested, then calls vblank_wait().
+ * This function enables the vblank interrupt on the pipe requested, then
+ * sleeps waiting for the requested sequence number to occur, and drops
+ * the vblank interrupt refcount afterwards. (vblank irq disable follows that
+ * after a timeout with no further vblank waits scheduled).
*/
int drm_wait_vblank(struct drm_device *dev, void *data,
struct drm_file *file_priv)
@@ -549,6 +553,9 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
if ((!dev->pdev->irq) || (!dev->irq_enabled))
return -EINVAL;
+ if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
+ return -EINVAL;
+
if (vblwait->request.type &
~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
@@ -586,88 +593,26 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
vblwait->request.sequence = seq + 1;
}
- if (flags & _DRM_VBLANK_SIGNAL) {
- unsigned long irqflags;
- struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
- struct drm_vbl_sig *vbl_sig;
-
- spin_lock_irqsave(&dev->vbl_lock, irqflags);
-
- /* Check if this task has already scheduled the same signal
- * for the same vblank sequence number; nothing to be done in
- * that case
- */
- list_for_each_entry(vbl_sig, vbl_sigs, head) {
- if (vbl_sig->sequence == vblwait->request.sequence
- && vbl_sig->info.si_signo ==
- vblwait->request.signal
- && vbl_sig->task == current) {
- spin_unlock_irqrestore(&dev->vbl_lock,
- irqflags);
- vblwait->reply.sequence = seq;
- goto done;
- }
- }
-
- if (atomic_read(&dev->vbl_signal_pending) >= 100) {
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- ret = -EBUSY;
- goto done;
- }
-
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
-
- vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
- DRM_MEM_DRIVER);
- if (!vbl_sig) {
- ret = -ENOMEM;
- goto done;
- }
-
- /* Get a refcount on the vblank, which will be released by
- * drm_vbl_send_signals().
- */
- ret = drm_vblank_get(dev, crtc);
- if (ret) {
- drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
- DRM_MEM_DRIVER);
- goto done;
- }
-
- atomic_inc(&dev->vbl_signal_pending);
-
- vbl_sig->sequence = vblwait->request.sequence;
- vbl_sig->info.si_signo = vblwait->request.signal;
- vbl_sig->task = current;
+ DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
+ vblwait->request.sequence, crtc);
+ dev->last_vblank_wait[crtc] = vblwait->request.sequence;
+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
+ (((drm_vblank_count(dev, crtc) -
+ vblwait->request.sequence) <= (1 << 23)) ||
+ !dev->irq_enabled));
- spin_lock_irqsave(&dev->vbl_lock, irqflags);
-
- list_add_tail(&vbl_sig->head, vbl_sigs);
+ if (ret != -EINTR) {
+ struct timeval now;
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+ do_gettimeofday(&now);
- vblwait->reply.sequence = seq;
+ vblwait->reply.tval_sec = now.tv_sec;
+ vblwait->reply.tval_usec = now.tv_usec;
+ vblwait->reply.sequence = drm_vblank_count(dev, crtc);
+ DRM_DEBUG("returning %d to client\n",
+ vblwait->reply.sequence);
} else {
- DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
- vblwait->request.sequence, crtc);
- dev->last_vblank_wait[crtc] = vblwait->request.sequence;
- DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
- ((drm_vblank_count(dev, crtc)
- - vblwait->request.sequence) <= (1 << 23)));
-
- if (ret != -EINTR) {
- struct timeval now;
-
- do_gettimeofday(&now);
-
- vblwait->reply.tval_sec = now.tv_sec;
- vblwait->reply.tval_usec = now.tv_usec;
- vblwait->reply.sequence = drm_vblank_count(dev, crtc);
- DRM_DEBUG("returning %d to client\n",
- vblwait->reply.sequence);
- } else {
- DRM_DEBUG("vblank wait interrupted by signal\n");
- }
+ DRM_DEBUG("vblank wait interrupted by signal\n");
}
done:
@@ -676,46 +621,6 @@ done:
}
/**
- * Send the VBLANK signals.
- *
- * \param dev DRM device.
- * \param crtc CRTC where the vblank event occurred
- *
- * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
- *
- * If a signal is not requested, then calls vblank_wait().
- */
-static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
-{
- struct drm_vbl_sig *vbl_sig, *tmp;
- struct list_head *vbl_sigs;
- unsigned int vbl_seq;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->vbl_lock, flags);
-
- vbl_sigs = &dev->vbl_sigs[crtc];
- vbl_seq = drm_vblank_count(dev, crtc);
-
- list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
- vbl_sig->info.si_code = vbl_seq;
- send_sig_info(vbl_sig->info.si_signo,
- &vbl_sig->info, vbl_sig->task);
-
- list_del(&vbl_sig->head);
-
- drm_free(vbl_sig, sizeof(*vbl_sig),
- DRM_MEM_DRIVER);
- atomic_dec(&dev->vbl_signal_pending);
- drm_vblank_put(dev, crtc);
- }
- }
-
- spin_unlock_irqrestore(&dev->vbl_lock, flags);
-}
-
-/**
* drm_handle_vblank - handle a vblank event
* @dev: DRM device
* @crtc: where this event occurred
@@ -727,6 +632,5 @@ void drm_handle_vblank(struct drm_device *dev, int crtc)
{
atomic_inc(&dev->_vblank_count[crtc]);
DRM_WAKEUP(&dev->vbl_queue[crtc]);
- drm_vbl_send_signals(dev, crtc);
}
EXPORT_SYMBOL(drm_handle_vblank);
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index 46e7b28f070..e2f70a516c3 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -80,6 +80,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
__set_current_state(TASK_INTERRUPTIBLE);
if (!master->lock.hw_lock) {
/* Device has been unregistered */
+ send_sig(SIGTERM, current, 0);
ret = -EINTR;
break;
}
@@ -93,7 +94,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
/* Contention */
schedule();
if (signal_pending(current)) {
- ret = -ERESTARTSYS;
+ ret = -EINTR;
break;
}
}
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index 803bc9e7ce3..bcc869bc409 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -171,9 +171,14 @@ EXPORT_SYMBOL(drm_core_ioremap);
void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev)
{
- map->handle = ioremap_wc(map->offset, map->size);
+ if (drm_core_has_AGP(dev) &&
+ dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
+ map->handle = agp_remap(map->offset, map->size, dev);
+ else
+ map->handle = ioremap_wc(map->offset, map->size);
}
EXPORT_SYMBOL(drm_core_ioremap_wc);
+
void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
{
if (!map->handle || !map->size)
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 5ca132afa4f..7c8b15b22bf 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -118,12 +118,20 @@ static void drm_master_destroy(struct kref *kref)
struct drm_master *master = container_of(kref, struct drm_master, refcount);
struct drm_magic_entry *pt, *next;
struct drm_device *dev = master->minor->dev;
+ struct drm_map_list *r_list, *list_temp;
list_del(&master->head);
if (dev->driver->master_destroy)
dev->driver->master_destroy(dev, master);
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
+ if (r_list->master == master) {
+ drm_rmmap_locked(dev, r_list->map);
+ r_list = NULL;
+ }
+ }
+
if (master->unique) {
drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER);
master->unique = NULL;
@@ -138,14 +146,6 @@ static void drm_master_destroy(struct kref *kref)
drm_ht_remove(&master->magiclist);
- if (master->lock.hw_lock) {
- if (dev->sigdata.lock == master->lock.hw_lock)
- dev->sigdata.lock = NULL;
- master->lock.hw_lock = NULL;
- master->lock.file_priv = NULL;
- wake_up_interruptible(&master->lock.lock_queue);
- }
-
drm_free(master, sizeof(*master), DRM_MEM_DRIVER);
}
@@ -168,7 +168,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
file_priv->minor->master != file_priv->master) {
mutex_lock(&dev->struct_mutex);
file_priv->minor->master = drm_master_get(file_priv->master);
- mutex_lock(&dev->struct_mutex);
+ mutex_unlock(&dev->struct_mutex);
}
return 0;
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 5aa6780652a..186d08159d4 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -359,8 +359,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
DRM_DEBUG("adding \"%s\" to sysfs\n",
drm_get_connector_name(connector));
- snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s",
- dev->primary->index, drm_get_connector_name(connector));
+ dev_set_name(&connector->kdev, "card%d-%s",
+ dev->primary->index, drm_get_connector_name(connector));
ret = device_register(&connector->kdev);
if (ret) {
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 62a4bf7b49d..6d21b9e48b8 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -177,6 +177,14 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
+ master_priv->sarea = drm_getsarea(dev);
+ if (master_priv->sarea) {
+ master_priv->sarea_priv = (drm_i915_sarea_t *)
+ ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset);
+ } else {
+ DRM_DEBUG("sarea not found assuming DRI2 userspace\n");
+ }
+
if (init->ring_size != 0) {
if (dev_priv->ring.ring_obj != NULL) {
i915_dma_cleanup(dev);
@@ -194,7 +202,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->ring.map.flags = 0;
dev_priv->ring.map.mtrr = 0;
- drm_core_ioremap(&dev_priv->ring.map, dev);
+ drm_core_ioremap_wc(&dev_priv->ring.map, dev);
if (dev_priv->ring.map.handle == NULL) {
i915_dma_cleanup(dev);
@@ -723,8 +731,11 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_GEM:
value = dev_priv->has_gem;
break;
+ case I915_PARAM_NUM_FENCES_AVAIL:
+ value = dev_priv->num_fence_regs - dev_priv->fence_reg_start;
+ break;
default:
- DRM_ERROR("Unknown parameter %d\n", param->param);
+ DRM_DEBUG("Unknown parameter %d\n", param->param);
return -EINVAL;
}
@@ -756,8 +767,15 @@ static int i915_setparam(struct drm_device *dev, void *data,
case I915_SETPARAM_ALLOW_BATCHBUFFER:
dev_priv->allow_batchbuffer = param->value;
break;
+ case I915_SETPARAM_NUM_USED_FENCES:
+ if (param->value > dev_priv->num_fence_regs ||
+ param->value < 0)
+ return -EINVAL;
+ /* Userspace can use first N regs */
+ dev_priv->fence_reg_start = param->value;
+ break;
default:
- DRM_ERROR("unknown parameter %d\n", param->param);
+ DRM_DEBUG("unknown parameter %d\n", param->param);
return -EINVAL;
}
@@ -793,7 +811,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
dev_priv->hws_map.flags = 0;
dev_priv->hws_map.mtrr = 0;
- drm_core_ioremap(&dev_priv->hws_map, dev);
+ drm_core_ioremap_wc(&dev_priv->hws_map, dev);
if (dev_priv->hws_map.handle == NULL) {
i915_dma_cleanup(dev);
dev_priv->status_gfx_addr = 0;
@@ -936,13 +954,14 @@ static int i915_load_modeset_init(struct drm_device *dev)
dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
0xff000000;
- DRM_DEBUG("*** fb base 0x%08lx\n", dev->mode_config.fb_base);
-
- if (IS_MOBILE(dev) || (IS_I9XX(dev) && !IS_I965G(dev) && !IS_G33(dev)))
+ if (IS_MOBILE(dev) || IS_I9XX(dev))
dev_priv->cursor_needs_physical = true;
else
dev_priv->cursor_needs_physical = false;
+ if (IS_I965G(dev) || IS_G33(dev))
+ dev_priv->cursor_needs_physical = false;
+
ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
if (ret)
goto kfree_devname;
@@ -957,10 +976,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto kfree_devname;
- dev_priv->mm.gtt_mapping =
- io_mapping_create_wc(dev->agp->base,
- dev->agp->agp_info.aper_size * 1024*1024);
-
/* Allow hardware batchbuffers unless told otherwise.
*/
dev_priv->allow_batchbuffer = 1;
@@ -1072,6 +1087,28 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto free_priv;
}
+ dev_priv->mm.gtt_mapping =
+ io_mapping_create_wc(dev->agp->base,
+ dev->agp->agp_info.aper_size * 1024*1024);
+ if (dev_priv->mm.gtt_mapping == NULL) {
+ ret = -EIO;
+ goto out_rmmap;
+ }
+
+ /* Set up a WC MTRR for non-PAT systems. This is more common than
+ * one would think, because the kernel disables PAT on first
+ * generation Core chips because WC PAT gets overridden by a UC
+ * MTRR if present. Even if a UC MTRR isn't present.
+ */
+ dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base,
+ dev->agp->agp_info.aper_size *
+ 1024 * 1024,
+ MTRR_TYPE_WRCOMB, 1);
+ if (dev_priv->mm.gtt_mtrr < 0) {
+ DRM_INFO("MTRR allocation failed. Graphics "
+ "performance may suffer.\n");
+ }
+
#ifdef CONFIG_HIGHMEM64G
/* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */
dev_priv->has_gem = 0;
@@ -1080,13 +1117,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->has_gem = 1;
#endif
+ dev->driver->get_vblank_counter = i915_get_vblank_counter;
+ if (IS_GM45(dev))
+ dev->driver->get_vblank_counter = gm45_get_vblank_counter;
+
i915_gem_load(dev);
/* Init HWS */
if (!I915_NEED_GFX_HWS(dev)) {
ret = i915_init_phys_hws(dev);
if (ret != 0)
- goto out_rmmap;
+ goto out_iomapfree;
}
/* On the 945G/GM, the chipset reports the MSI capability on the
@@ -1125,6 +1166,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
return 0;
+out_iomapfree:
+ io_mapping_free(dev_priv->mm.gtt_mapping);
out_rmmap:
iounmap(dev_priv->regs);
free_priv:
@@ -1136,8 +1179,14 @@ int i915_driver_unload(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ io_mapping_free(dev_priv->mm.gtt_mapping);
+ if (dev_priv->mm.gtt_mtrr >= 0) {
+ mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base,
+ dev->agp->agp_info.aper_size * 1024 * 1024);
+ dev_priv->mm.gtt_mtrr = -1;
+ }
+
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- io_mapping_free(dev_priv->mm.gtt_mapping);
drm_irq_uninstall(dev);
}
@@ -1152,6 +1201,8 @@ int i915_driver_unload(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
intel_modeset_cleanup(dev);
+ i915_gem_free_all_phys_object(dev);
+
mutex_lock(&dev->struct_mutex);
i915_gem_cleanup_ringbuffer(dev);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index f8b3df0926c..b293ef0bae7 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -27,6 +27,7 @@
*
*/
+#include <linux/device.h>
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
@@ -66,6 +67,14 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
i915_save_state(dev);
+ /* If KMS is active, we do the leavevt stuff here */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ if (i915_gem_idle(dev))
+ dev_err(&dev->pdev->dev,
+ "GEM idle failed, resume may fail\n");
+ drm_irq_uninstall(dev);
+ }
+
intel_opregion_free(dev);
if (state.event == PM_EVENT_SUSPEND) {
@@ -79,6 +88,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
static int i915_resume(struct drm_device *dev)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret = 0;
+
pci_set_power_state(dev->pdev, PCI_D0);
pci_restore_state(dev->pdev);
if (pci_enable_device(dev->pdev))
@@ -89,11 +101,26 @@ static int i915_resume(struct drm_device *dev)
intel_opregion_init(dev);
- return 0;
+ /* KMS EnterVT equivalent */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ mutex_lock(&dev->struct_mutex);
+ dev_priv->mm.suspended = 0;
+
+ ret = i915_gem_init_ringbuffer(dev);
+ if (ret != 0)
+ ret = -1;
+ mutex_unlock(&dev->struct_mutex);
+
+ drm_irq_install(dev);
+ }
+
+ return ret;
}
static struct vm_operations_struct i915_gem_vm_ops = {
.fault = i915_gem_fault,
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
};
static struct drm_driver driver = {
@@ -112,7 +139,6 @@ static struct drm_driver driver = {
.suspend = i915_suspend,
.resume = i915_resume,
.device_is_agp = i915_driver_device_is_agp,
- .get_vblank_counter = i915_get_vblank_counter,
.enable_vblank = i915_enable_vblank,
.disable_vblank = i915_disable_vblank,
.irq_preinstall = i915_driver_irq_preinstall,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 563de18063f..d6cc9861e0a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -72,6 +72,18 @@ enum pipe {
#define WATCH_INACTIVE 0
#define WATCH_PWRITE 0
+#define I915_GEM_PHYS_CURSOR_0 1
+#define I915_GEM_PHYS_CURSOR_1 2
+#define I915_GEM_PHYS_OVERLAY_REGS 3
+#define I915_MAX_PHYS_OBJECT (I915_GEM_PHYS_OVERLAY_REGS)
+
+struct drm_i915_gem_phys_object {
+ int id;
+ struct page **page_list;
+ drm_dma_handle_t *handle;
+ struct drm_gem_object *cur_obj;
+};
+
typedef struct _drm_i915_ring_buffer {
int tail_mask;
unsigned long Size;
@@ -172,6 +184,8 @@ typedef struct drm_i915_private {
unsigned int lvds_dither:1;
unsigned int lvds_vbt:1;
unsigned int int_crt_support:1;
+ unsigned int lvds_use_ssc:1;
+ int lvds_ssc_freq;
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
@@ -265,13 +279,13 @@ typedef struct drm_i915_private {
u8 saveAR_INDEX;
u8 saveAR[21];
u8 saveDACMASK;
- u8 saveDACDATA[256*3]; /* 256 3-byte colors */
u8 saveCR[37];
struct {
struct drm_mm gtt_space;
struct io_mapping *gtt_mapping;
+ int gtt_mtrr;
/**
* List of objects currently involved in rendering from the
@@ -358,6 +372,9 @@ typedef struct drm_i915_private {
uint32_t bit_6_swizzle_x;
/** Bit 6 swizzling required for Y tiling */
uint32_t bit_6_swizzle_y;
+
+ /* storage for physical objects */
+ struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
} mm;
} drm_i915_private_t;
@@ -436,6 +453,15 @@ struct drm_i915_gem_object {
/** User space pin count and filp owning the pin */
uint32_t user_pin_count;
struct drm_file *pin_filp;
+
+ /** for phy allocated objects */
+ struct drm_i915_gem_phys_object *phys_obj;
+
+ /**
+ * Used for checking the object doesn't appear more than once
+ * in an execbuffer object list.
+ */
+ int in_execbuffer;
};
/**
@@ -516,6 +542,7 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
extern int i915_enable_vblank(struct drm_device *dev, int crtc);
extern void i915_disable_vblank(struct drm_device *dev, int crtc);
extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
+extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
@@ -583,6 +610,7 @@ int i915_gem_init_object(struct drm_gem_object *obj);
void i915_gem_free_object(struct drm_gem_object *obj);
int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
void i915_gem_object_unpin(struct drm_gem_object *obj);
+int i915_gem_object_unbind(struct drm_gem_object *obj);
void i915_gem_lastclose(struct drm_device *dev);
uint32_t i915_get_gem_seqno(struct drm_device *dev);
void i915_gem_retire_requests(struct drm_device *dev);
@@ -595,9 +623,15 @@ int i915_gem_init_ringbuffer(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end);
+int i915_gem_idle(struct drm_device *dev);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
int write);
+int i915_gem_attach_phys_object(struct drm_device *dev,
+ struct drm_gem_object *obj, int id);
+void i915_gem_detach_phys_object(struct drm_device *dev,
+ struct drm_gem_object *obj);
+void i915_gem_free_all_phys_object(struct drm_device *dev);
/* i915_gem_tiling.c */
void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
@@ -761,6 +795,11 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
+/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
+ * rows, which changed the alignment requirements and fence programming.
+ */
+#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
+ IS_I915GM(dev)))
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1384d668655..37427e4016c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -34,10 +34,6 @@
#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
-static void
-i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
- uint32_t read_domains,
- uint32_t write_domain);
static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -52,9 +48,12 @@ static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
unsigned alignment);
-static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
+static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write);
static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
static int i915_gem_evict_something(struct drm_device *dev);
+static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pwrite *args,
+ struct drm_file *file_priv);
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end)
@@ -386,8 +385,10 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
* pread/pwrite currently are reading and writing from the CPU
* perspective, requiring manual detiling by the client.
*/
- if (obj_priv->tiling_mode == I915_TILING_NONE &&
- dev->gtt_total != 0)
+ if (obj_priv->phys_obj)
+ ret = i915_gem_phys_pwrite(dev, obj, args, file_priv);
+ else if (obj_priv->tiling_mode == I915_TILING_NONE &&
+ dev->gtt_total != 0)
ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
else
ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
@@ -562,6 +563,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
pgoff_t page_offset;
unsigned long pfn;
int ret = 0;
+ bool write = !!(vmf->flags & FAULT_FLAG_WRITE);
/* We don't use vmf->pgoff since that has the fake offset */
page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >>
@@ -580,8 +582,13 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
/* Need a new fence register? */
if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
- obj_priv->tiling_mode != I915_TILING_NONE)
- i915_gem_object_get_fence_reg(obj);
+ obj_priv->tiling_mode != I915_TILING_NONE) {
+ ret = i915_gem_object_get_fence_reg(obj, write);
+ if (ret) {
+ mutex_unlock(&dev->struct_mutex);
+ return VM_FAULT_SIGBUS;
+ }
+ }
pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
page_offset;
@@ -596,8 +603,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
case -EAGAIN:
return VM_FAULT_OOM;
case -EFAULT:
- case -EBUSY:
- DRM_ERROR("can't insert pfn?? fault or busy...\n");
return VM_FAULT_SIGBUS;
default:
return VM_FAULT_NOPAGE;
@@ -673,6 +678,30 @@ out_free_list:
return ret;
}
+static void
+i915_gem_free_mmap_offset(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_gem_mm *mm = dev->mm_private;
+ struct drm_map_list *list;
+
+ list = &obj->map_list;
+ drm_ht_remove_item(&mm->offset_hash, &list->hash);
+
+ if (list->file_offset_node) {
+ drm_mm_put_block(list->file_offset_node);
+ list->file_offset_node = NULL;
+ }
+
+ if (list->map) {
+ drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER);
+ list->map = NULL;
+ }
+
+ obj_priv->mmap_offset = 0;
+}
+
/**
* i915_gem_get_gtt_alignment - return required GTT alignment for an object
* @obj: object to check
@@ -747,8 +776,11 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
if (!obj_priv->mmap_offset) {
ret = i915_gem_create_mmap_offset(obj);
- if (ret)
+ if (ret) {
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return ret;
+ }
}
args->offset = obj_priv->mmap_offset;
@@ -1019,6 +1051,9 @@ i915_gem_retire_requests(struct drm_device *dev)
drm_i915_private_t *dev_priv = dev->dev_private;
uint32_t seqno;
+ if (!dev_priv->hw_status_page)
+ return;
+
seqno = i915_get_gem_seqno(dev);
while (!list_empty(&dev_priv->mm.request_list)) {
@@ -1206,7 +1241,7 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj)
/**
* Unbinds an object from the GTT aperture.
*/
-static int
+int
i915_gem_object_unbind(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
@@ -1440,21 +1475,26 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
int regnum = obj_priv->fence_reg;
- uint32_t val;
+ int tile_width;
+ uint32_t fence_reg, val;
uint32_t pitch_val;
if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
(obj_priv->gtt_offset & (obj->size - 1))) {
- WARN(1, "%s: object not 1M or size aligned\n", __func__);
+ WARN(1, "%s: object 0x%08x not 1M or size (0x%zx) aligned\n",
+ __func__, obj_priv->gtt_offset, obj->size);
return;
}
- if (obj_priv->tiling_mode == I915_TILING_Y && (IS_I945G(dev) ||
- IS_I945GM(dev) ||
- IS_G33(dev)))
- pitch_val = (obj_priv->stride / 128) - 1;
+ if (obj_priv->tiling_mode == I915_TILING_Y &&
+ HAS_128_BYTE_Y_TILING(dev))
+ tile_width = 128;
else
- pitch_val = (obj_priv->stride / 512) - 1;
+ tile_width = 512;
+
+ /* Note: pitch better be a power of two tile widths */
+ pitch_val = obj_priv->stride / tile_width;
+ pitch_val = ffs(pitch_val) - 1;
val = obj_priv->gtt_offset;
if (obj_priv->tiling_mode == I915_TILING_Y)
@@ -1463,7 +1503,11 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
val |= pitch_val << I830_FENCE_PITCH_SHIFT;
val |= I830_FENCE_REG_VALID;
- I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
+ if (regnum < 8)
+ fence_reg = FENCE_REG_830_0 + (regnum * 4);
+ else
+ fence_reg = FENCE_REG_945_8 + ((regnum - 8) * 4);
+ I915_WRITE(fence_reg, val);
}
static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
@@ -1478,7 +1522,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
(obj_priv->gtt_offset & (obj->size - 1))) {
- WARN(1, "%s: object not 1M or size aligned\n", __func__);
+ WARN(1, "%s: object 0x%08x not 1M or size aligned\n",
+ __func__, obj_priv->gtt_offset);
return;
}
@@ -1498,6 +1543,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
/**
* i915_gem_object_get_fence_reg - set up a fence reg for an object
* @obj: object to map through a fence reg
+ * @write: object is about to be written
*
* When mapping objects through the GTT, userspace wants to be able to write
* to them without having to worry about swizzling if the object is tiled.
@@ -1508,49 +1554,77 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
* It then sets up the reg based on the object's properties: address, pitch
* and tiling format.
*/
-static void
-i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
+static int
+i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write)
{
struct drm_device *dev = obj->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
struct drm_i915_fence_reg *reg = NULL;
- int i, ret;
+ struct drm_i915_gem_object *old_obj_priv = NULL;
+ int i, ret, avail;
switch (obj_priv->tiling_mode) {
case I915_TILING_NONE:
WARN(1, "allocating a fence for non-tiled object?\n");
break;
case I915_TILING_X:
- WARN(obj_priv->stride & (512 - 1),
- "object is X tiled but has non-512B pitch\n");
+ if (!obj_priv->stride)
+ return -EINVAL;
+ WARN((obj_priv->stride & (512 - 1)),
+ "object 0x%08x is X tiled but has non-512B pitch\n",
+ obj_priv->gtt_offset);
break;
case I915_TILING_Y:
- WARN(obj_priv->stride & (128 - 1),
- "object is Y tiled but has non-128B pitch\n");
+ if (!obj_priv->stride)
+ return -EINVAL;
+ WARN((obj_priv->stride & (128 - 1)),
+ "object 0x%08x is Y tiled but has non-128B pitch\n",
+ obj_priv->gtt_offset);
break;
}
/* First try to find a free reg */
+try_again:
+ avail = 0;
for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
reg = &dev_priv->fence_regs[i];
if (!reg->obj)
break;
+
+ old_obj_priv = reg->obj->driver_private;
+ if (!old_obj_priv->pin_count)
+ avail++;
}
/* None available, try to steal one or wait for a user to finish */
if (i == dev_priv->num_fence_regs) {
- struct drm_i915_gem_object *old_obj_priv = NULL;
+ uint32_t seqno = dev_priv->mm.next_gem_seqno;
loff_t offset;
-try_again:
- /* Could try to use LRU here instead... */
+ if (avail == 0)
+ return -ENOMEM;
+
for (i = dev_priv->fence_reg_start;
i < dev_priv->num_fence_regs; i++) {
+ uint32_t this_seqno;
+
reg = &dev_priv->fence_regs[i];
old_obj_priv = reg->obj->driver_private;
- if (!old_obj_priv->pin_count)
+
+ if (old_obj_priv->pin_count)
+ continue;
+
+ /* i915 uses fences for GPU access to tiled buffers */
+ if (IS_I965G(dev) || !old_obj_priv->active)
break;
+
+ /* find the seqno of the first available fence */
+ this_seqno = old_obj_priv->last_rendering_seqno;
+ if (this_seqno != 0 &&
+ reg->obj->write_domain == 0 &&
+ i915_seqno_passed(seqno, this_seqno))
+ seqno = this_seqno;
}
/*
@@ -1558,14 +1632,25 @@ try_again:
* objects to finish before trying again.
*/
if (i == dev_priv->num_fence_regs) {
- ret = i915_gem_object_wait_rendering(reg->obj);
- if (ret) {
- WARN(ret, "wait_rendering failed: %d\n", ret);
- return;
+ if (seqno == dev_priv->mm.next_gem_seqno) {
+ i915_gem_flush(dev,
+ I915_GEM_GPU_DOMAINS,
+ I915_GEM_GPU_DOMAINS);
+ seqno = i915_add_request(dev,
+ I915_GEM_GPU_DOMAINS);
+ if (seqno == 0)
+ return -ENOMEM;
}
+
+ ret = i915_wait_request(dev, seqno);
+ if (ret)
+ return ret;
goto try_again;
}
+ BUG_ON(old_obj_priv->active ||
+ (reg->obj->write_domain & I915_GEM_GPU_DOMAINS));
+
/*
* Zap this virtual mapping so we can set up a fence again
* for this object next time we need it.
@@ -1586,6 +1671,8 @@ try_again:
i915_write_fence_reg(reg);
else
i830_write_fence_reg(reg);
+
+ return 0;
}
/**
@@ -1604,8 +1691,17 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
if (IS_I965G(dev))
I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
- else
- I915_WRITE(FENCE_REG_830_0 + (obj_priv->fence_reg * 4), 0);
+ else {
+ uint32_t fence_reg;
+
+ if (obj_priv->fence_reg < 8)
+ fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
+ else
+ fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg -
+ 8) * 4;
+
+ I915_WRITE(fence_reg, 0);
+ }
dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL;
obj_priv->fence_reg = I915_FENCE_REG_NONE;
@@ -1626,7 +1722,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
if (dev_priv->mm.suspended)
return -EBUSY;
if (alignment == 0)
- alignment = PAGE_SIZE;
+ alignment = i915_gem_get_gtt_alignment(obj);
if (alignment & (PAGE_SIZE - 1)) {
DRM_ERROR("Invalid object alignment requested %u\n", alignment);
return -EINVAL;
@@ -1969,30 +2065,28 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
* drm_agp_chipset_flush
*/
static void
-i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
- uint32_t read_domains,
- uint32_t write_domain)
+i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
uint32_t invalidate_domains = 0;
uint32_t flush_domains = 0;
- BUG_ON(read_domains & I915_GEM_DOMAIN_CPU);
- BUG_ON(write_domain == I915_GEM_DOMAIN_CPU);
+ BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
+ BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
#if WATCH_BUF
DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
__func__, obj,
- obj->read_domains, read_domains,
- obj->write_domain, write_domain);
+ obj->read_domains, obj->pending_read_domains,
+ obj->write_domain, obj->pending_write_domain);
#endif
/*
* If the object isn't moving to a new write domain,
* let the object stay in multiple read domains
*/
- if (write_domain == 0)
- read_domains |= obj->read_domains;
+ if (obj->pending_write_domain == 0)
+ obj->pending_read_domains |= obj->read_domains;
else
obj_priv->dirty = 1;
@@ -2002,15 +2096,17 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
* any read domains which differ from the old
* write domain
*/
- if (obj->write_domain && obj->write_domain != read_domains) {
+ if (obj->write_domain &&
+ obj->write_domain != obj->pending_read_domains) {
flush_domains |= obj->write_domain;
- invalidate_domains |= read_domains & ~obj->write_domain;
+ invalidate_domains |=
+ obj->pending_read_domains & ~obj->write_domain;
}
/*
* Invalidate any read caches which may have
* stale data. That is, any new read domains.
*/
- invalidate_domains |= read_domains & ~obj->read_domains;
+ invalidate_domains |= obj->pending_read_domains & ~obj->read_domains;
if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
#if WATCH_BUF
DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
@@ -2019,9 +2115,15 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
i915_gem_clflush_object(obj);
}
- if ((write_domain | flush_domains) != 0)
- obj->write_domain = write_domain;
- obj->read_domains = read_domains;
+ /* The actual obj->write_domain will be updated with
+ * pending_write_domain after we emit the accumulated flush for all
+ * of our domain changes in execbuffers (which clears objects'
+ * write_domains). So if we have a current write domain that we
+ * aren't changing, set pending_write_domain to that.
+ */
+ if (flush_domains == 0 && obj->pending_write_domain == 0)
+ obj->pending_write_domain = obj->write_domain;
+ obj->read_domains = obj->pending_read_domains;
dev->invalidate_domains |= invalidate_domains;
dev->flush_domains |= flush_domains;
@@ -2224,6 +2326,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
(int) reloc.offset,
reloc.read_domains,
reloc.write_domain);
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
return -EINVAL;
}
@@ -2410,6 +2514,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_gem_exec_object *exec_list = NULL;
struct drm_gem_object **object_list = NULL;
struct drm_gem_object *batch_obj;
+ struct drm_i915_gem_object *obj_priv;
int ret, i, pinned = 0;
uint64_t exec_offset;
uint32_t seqno, flush_domains;
@@ -2453,13 +2558,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
if (dev_priv->mm.wedged) {
DRM_ERROR("Execbuf while wedged\n");
mutex_unlock(&dev->struct_mutex);
- return -EIO;
+ ret = -EIO;
+ goto pre_mutex_err;
}
if (dev_priv->mm.suspended) {
DRM_ERROR("Execbuf while VT-switched.\n");
mutex_unlock(&dev->struct_mutex);
- return -EBUSY;
+ ret = -EBUSY;
+ goto pre_mutex_err;
}
/* Look up object handles */
@@ -2472,6 +2579,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
ret = -EBADF;
goto err;
}
+
+ obj_priv = object_list[i]->driver_private;
+ if (obj_priv->in_execbuffer) {
+ DRM_ERROR("Object %p appears more than once in object list\n",
+ object_list[i]);
+ ret = -EBADF;
+ goto err;
+ }
+ obj_priv->in_execbuffer = true;
}
/* Pin and relocate */
@@ -2527,9 +2643,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_gem_object *obj = object_list[i];
/* Compute new gpu domains and update invalidate/flush */
- i915_gem_object_set_to_gpu_domain(obj,
- obj->pending_read_domains,
- obj->pending_write_domain);
+ i915_gem_object_set_to_gpu_domain(obj);
}
i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -2548,6 +2662,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
(void)i915_add_request(dev, dev->flush_domains);
}
+ for (i = 0; i < args->buffer_count; i++) {
+ struct drm_gem_object *obj = object_list[i];
+
+ obj->write_domain = obj->pending_write_domain;
+ }
+
i915_verify_inactive(dev, __FILE__, __LINE__);
#if WATCH_COHERENCY
@@ -2605,24 +2725,32 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
i915_verify_inactive(dev, __FILE__, __LINE__);
- /* Copy the new buffer offsets back to the user's exec list. */
- ret = copy_to_user((struct drm_i915_relocation_entry __user *)
- (uintptr_t) args->buffers_ptr,
- exec_list,
- sizeof(*exec_list) * args->buffer_count);
- if (ret)
- DRM_ERROR("failed to copy %d exec entries "
- "back to user (%d)\n",
- args->buffer_count, ret);
err:
for (i = 0; i < pinned; i++)
i915_gem_object_unpin(object_list[i]);
- for (i = 0; i < args->buffer_count; i++)
+ for (i = 0; i < args->buffer_count; i++) {
+ if (object_list[i]) {
+ obj_priv = object_list[i]->driver_private;
+ obj_priv->in_execbuffer = false;
+ }
drm_gem_object_unreference(object_list[i]);
+ }
mutex_unlock(&dev->struct_mutex);
+ if (!ret) {
+ /* Copy the new buffer offsets back to the user's exec list. */
+ ret = copy_to_user((struct drm_i915_relocation_entry __user *)
+ (uintptr_t) args->buffers_ptr,
+ exec_list,
+ sizeof(*exec_list) * args->buffer_count);
+ if (ret)
+ DRM_ERROR("failed to copy %d exec entries "
+ "back to user (%d)\n",
+ args->buffer_count, ret);
+ }
+
pre_mutex_err:
drm_free(object_list, sizeof(*object_list) * args->buffer_count,
DRM_MEM_DRIVER);
@@ -2644,7 +2772,22 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
ret = i915_gem_object_bind_to_gtt(obj, alignment);
if (ret != 0) {
if (ret != -EBUSY && ret != -ERESTARTSYS)
- DRM_ERROR("Failure to bind: %d", ret);
+ DRM_ERROR("Failure to bind: %d\n", ret);
+ return ret;
+ }
+ }
+ /*
+ * Pre-965 chips need a fence register set up in order to
+ * properly handle tiled surfaces.
+ */
+ if (!IS_I965G(dev) &&
+ obj_priv->fence_reg == I915_FENCE_REG_NONE &&
+ obj_priv->tiling_mode != I915_TILING_NONE) {
+ ret = i915_gem_object_get_fence_reg(obj, true);
+ if (ret != 0) {
+ if (ret != -EBUSY && ret != -ERESTARTSYS)
+ DRM_ERROR("Failure to install fence: %d\n",
+ ret);
return ret;
}
}
@@ -2718,6 +2861,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) {
DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
args->handle);
+ drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
@@ -2798,6 +2942,13 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
return -EBADF;
}
+ /* Update the active list for the hardware's current position.
+ * Otherwise this only updates on a delayed timer or when irqs are
+ * actually unmasked, and our working set ends up being larger than
+ * required.
+ */
+ i915_gem_retire_requests(dev);
+
obj_priv = obj->driver_private;
/* Don't count being on the flushing list against the object being
* done. Otherwise, a buffer left on the flushing list but not getting
@@ -2850,29 +3001,17 @@ int i915_gem_init_object(struct drm_gem_object *obj)
void i915_gem_free_object(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list;
- struct drm_map *map;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
while (obj_priv->pin_count > 0)
i915_gem_object_unpin(obj);
- i915_gem_object_unbind(obj);
-
- list = &obj->map_list;
- drm_ht_remove_item(&mm->offset_hash, &list->hash);
+ if (obj_priv->phys_obj)
+ i915_gem_detach_phys_object(dev, obj);
- if (list->file_offset_node) {
- drm_mm_put_block(list->file_offset_node);
- list->file_offset_node = NULL;
- }
+ i915_gem_object_unbind(obj);
- map = list->map;
- if (map) {
- drm_free(map, sizeof(*map), DRM_MEM_DRIVER);
- list->map = NULL;
- }
+ i915_gem_free_mmap_offset(obj);
drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
@@ -2911,7 +3050,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
return 0;
}
-static int
+int
i915_gem_idle(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -3057,6 +3196,7 @@ i915_gem_init_hws(struct drm_device *dev)
if (dev_priv->hw_status_page == NULL) {
DRM_ERROR("Failed to map status page.\n");
memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
+ i915_gem_object_unpin(obj);
drm_gem_object_unreference(obj);
return -EINVAL;
}
@@ -3069,6 +3209,31 @@ i915_gem_init_hws(struct drm_device *dev)
return 0;
}
+static void
+i915_gem_cleanup_hws(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ if (dev_priv->hws_obj == NULL)
+ return;
+
+ obj = dev_priv->hws_obj;
+ obj_priv = obj->driver_private;
+
+ kunmap(obj_priv->page_list[0]);
+ i915_gem_object_unpin(obj);
+ drm_gem_object_unreference(obj);
+ dev_priv->hws_obj = NULL;
+
+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
+ dev_priv->hw_status_page = NULL;
+
+ /* Write high address into HWS_PGA when disabling. */
+ I915_WRITE(HWS_PGA, 0x1ffff000);
+}
+
int
i915_gem_init_ringbuffer(struct drm_device *dev)
{
@@ -3086,6 +3251,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
obj = drm_gem_object_alloc(dev, 128 * 1024);
if (obj == NULL) {
DRM_ERROR("Failed to allocate ringbuffer\n");
+ i915_gem_cleanup_hws(dev);
return -ENOMEM;
}
obj_priv = obj->driver_private;
@@ -3093,6 +3259,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
ret = i915_gem_object_pin(obj, 4096);
if (ret != 0) {
drm_gem_object_unreference(obj);
+ i915_gem_cleanup_hws(dev);
return ret;
}
@@ -3110,7 +3277,9 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
if (ring->map.handle == NULL) {
DRM_ERROR("Failed to map ringbuffer.\n");
memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
+ i915_gem_object_unpin(obj);
drm_gem_object_unreference(obj);
+ i915_gem_cleanup_hws(dev);
return -EINVAL;
}
ring->ring_obj = obj;
@@ -3190,20 +3359,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
dev_priv->ring.ring_obj = NULL;
memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
- if (dev_priv->hws_obj != NULL) {
- struct drm_gem_object *obj = dev_priv->hws_obj;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
-
- kunmap(obj_priv->page_list[0]);
- i915_gem_object_unpin(obj);
- drm_gem_object_unreference(obj);
- dev_priv->hws_obj = NULL;
- memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
- dev_priv->hw_status_page = NULL;
-
- /* Write high address into HWS_PGA when disabling. */
- I915_WRITE(HWS_PGA, 0x1ffff000);
- }
+ i915_gem_cleanup_hws(dev);
}
int
@@ -3221,10 +3377,6 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
dev_priv->mm.wedged = 0;
}
- dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base,
- dev->agp->agp_info.aper_size
- * 1024 * 1024);
-
mutex_lock(&dev->struct_mutex);
dev_priv->mm.suspended = 0;
@@ -3247,7 +3399,6 @@ int
i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
int ret;
if (drm_core_check_feature(dev, DRIVER_MODESET))
@@ -3256,7 +3407,6 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
ret = i915_gem_idle(dev);
drm_irq_uninstall(dev);
- io_mapping_free(dev_priv->mm.gtt_mapping);
return ret;
}
@@ -3265,6 +3415,9 @@ i915_gem_lastclose(struct drm_device *dev)
{
int ret;
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return;
+
ret = i915_gem_idle(dev);
if (ret)
DRM_ERROR("failed to idle hardware: %d\n", ret);
@@ -3286,10 +3439,187 @@ i915_gem_load(struct drm_device *dev)
/* Old X drivers will take 0-2 for front, back, depth buffers */
dev_priv->fence_reg_start = 3;
- if (IS_I965G(dev))
+ if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
dev_priv->num_fence_regs = 16;
else
dev_priv->num_fence_regs = 8;
i915_gem_detect_bit_6_swizzle(dev);
}
+
+/*
+ * Create a physically contiguous memory object for this object
+ * e.g. for cursor + overlay regs
+ */
+int i915_gem_init_phys_object(struct drm_device *dev,
+ int id, int size)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_phys_object *phys_obj;
+ int ret;
+
+ if (dev_priv->mm.phys_objs[id - 1] || !size)
+ return 0;
+
+ phys_obj = drm_calloc(1, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER);
+ if (!phys_obj)
+ return -ENOMEM;
+
+ phys_obj->id = id;
+
+ phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff);
+ if (!phys_obj->handle) {
+ ret = -ENOMEM;
+ goto kfree_obj;
+ }
+#ifdef CONFIG_X86
+ set_memory_wc((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE);
+#endif
+
+ dev_priv->mm.phys_objs[id - 1] = phys_obj;
+
+ return 0;
+kfree_obj:
+ drm_free(phys_obj, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER);
+ return ret;
+}
+
+void i915_gem_free_phys_object(struct drm_device *dev, int id)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_phys_object *phys_obj;
+
+ if (!dev_priv->mm.phys_objs[id - 1])
+ return;
+
+ phys_obj = dev_priv->mm.phys_objs[id - 1];
+ if (phys_obj->cur_obj) {
+ i915_gem_detach_phys_object(dev, phys_obj->cur_obj);
+ }
+
+#ifdef CONFIG_X86
+ set_memory_wb((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE);
+#endif
+ drm_pci_free(dev, phys_obj->handle);
+ kfree(phys_obj);
+ dev_priv->mm.phys_objs[id - 1] = NULL;
+}
+
+void i915_gem_free_all_phys_object(struct drm_device *dev)
+{
+ int i;
+
+ for (i = I915_GEM_PHYS_CURSOR_0; i <= I915_MAX_PHYS_OBJECT; i++)
+ i915_gem_free_phys_object(dev, i);
+}
+
+void i915_gem_detach_phys_object(struct drm_device *dev,
+ struct drm_gem_object *obj)
+{
+ struct drm_i915_gem_object *obj_priv;
+ int i;
+ int ret;
+ int page_count;
+
+ obj_priv = obj->driver_private;
+ if (!obj_priv->phys_obj)
+ return;
+
+ ret = i915_gem_object_get_page_list(obj);
+ if (ret)
+ goto out;
+
+ page_count = obj->size / PAGE_SIZE;
+
+ for (i = 0; i < page_count; i++) {
+ char *dst = kmap_atomic(obj_priv->page_list[i], KM_USER0);
+ char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE);
+
+ memcpy(dst, src, PAGE_SIZE);
+ kunmap_atomic(dst, KM_USER0);
+ }
+ drm_clflush_pages(obj_priv->page_list, page_count);
+ drm_agp_chipset_flush(dev);
+out:
+ obj_priv->phys_obj->cur_obj = NULL;
+ obj_priv->phys_obj = NULL;
+}
+
+int
+i915_gem_attach_phys_object(struct drm_device *dev,
+ struct drm_gem_object *obj, int id)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv;
+ int ret = 0;
+ int page_count;
+ int i;
+
+ if (id > I915_MAX_PHYS_OBJECT)
+ return -EINVAL;
+
+ obj_priv = obj->driver_private;
+
+ if (obj_priv->phys_obj) {
+ if (obj_priv->phys_obj->id == id)
+ return 0;
+ i915_gem_detach_phys_object(dev, obj);
+ }
+
+
+ /* create a new object */
+ if (!dev_priv->mm.phys_objs[id - 1]) {
+ ret = i915_gem_init_phys_object(dev, id,
+ obj->size);
+ if (ret) {
+ DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size);
+ goto out;
+ }
+ }
+
+ /* bind to the object */
+ obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1];
+ obj_priv->phys_obj->cur_obj = obj;
+
+ ret = i915_gem_object_get_page_list(obj);
+ if (ret) {
+ DRM_ERROR("failed to get page list\n");
+ goto out;
+ }
+
+ page_count = obj->size / PAGE_SIZE;
+
+ for (i = 0; i < page_count; i++) {
+ char *src = kmap_atomic(obj_priv->page_list[i], KM_USER0);
+ char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE);
+
+ memcpy(dst, src, PAGE_SIZE);
+ kunmap_atomic(src, KM_USER0);
+ }
+
+ return 0;
+out:
+ return ret;
+}
+
+static int
+i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pwrite *args,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ void *obj_addr;
+ int ret;
+ char __user *user_data;
+
+ user_data = (char __user *) (uintptr_t) args->data_ptr;
+ obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
+
+ DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size);
+ ret = copy_from_user(obj_addr, user_data, args->size);
+ if (ret)
+ return -EFAULT;
+
+ drm_agp_chipset_flush(dev);
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 241f39b7f46..7fb4191ef93 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -173,6 +173,73 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
dev_priv->mm.bit_6_swizzle_y = swizzle_y;
}
+
+/**
+ * Returns the size of the fence for a tiled object of the given size.
+ */
+static int
+i915_get_fence_size(struct drm_device *dev, int size)
+{
+ int i;
+ int start;
+
+ if (IS_I965G(dev)) {
+ /* The 965 can have fences at any page boundary. */
+ return ALIGN(size, 4096);
+ } else {
+ /* Align the size to a power of two greater than the smallest
+ * fence size.
+ */
+ if (IS_I9XX(dev))
+ start = 1024 * 1024;
+ else
+ start = 512 * 1024;
+
+ for (i = start; i < size; i <<= 1)
+ ;
+
+ return i;
+ }
+}
+
+/* Check pitch constriants for all chips & tiling formats */
+static bool
+i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
+{
+ int tile_width;
+
+ /* Linear is always fine */
+ if (tiling_mode == I915_TILING_NONE)
+ return true;
+
+ if (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
+ tile_width = 128;
+ else
+ tile_width = 512;
+
+ /* 965+ just needs multiples of tile width */
+ if (IS_I965G(dev)) {
+ if (stride & (tile_width - 1))
+ return false;
+ return true;
+ }
+
+ /* Pre-965 needs power of two tile widths */
+ if (stride < tile_width)
+ return false;
+
+ if (stride & (stride - 1))
+ return false;
+
+ /* We don't handle the aperture area covered by the fence being bigger
+ * than the object size.
+ */
+ if (i915_get_fence_size(dev, size) != size)
+ return false;
+
+ return true;
+}
+
/**
* Sets the tiling mode of an object, returning the required swizzling of
* bit 6 of addresses in the object.
@@ -191,6 +258,11 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
return -EINVAL;
obj_priv = obj->driver_private;
+ if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
+ drm_gem_object_unreference(obj);
+ return -EINVAL;
+ }
+
mutex_lock(&dev->struct_mutex);
if (args->tiling_mode == I915_TILING_NONE) {
@@ -207,12 +279,28 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
}
}
- obj_priv->tiling_mode = args->tiling_mode;
- obj_priv->stride = args->stride;
+ if (args->tiling_mode != obj_priv->tiling_mode) {
+ int ret;
- mutex_unlock(&dev->struct_mutex);
+ /* Unbind the object, as switching tiling means we're
+ * switching the cache organization due to fencing, probably.
+ */
+ ret = i915_gem_object_unbind(obj);
+ if (ret != 0) {
+ WARN(ret != -ERESTARTSYS,
+ "failed to unbind object for tiling switch");
+ args->tiling_mode = obj_priv->tiling_mode;
+ mutex_unlock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+
+ return ret;
+ }
+ obj_priv->tiling_mode = args->tiling_mode;
+ }
+ obj_priv->stride = args->stride;
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
@@ -251,9 +339,8 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
DRM_ERROR("unknown tiling mode\n");
}
- mutex_unlock(&dev->struct_mutex);
-
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 0cadafbef41..87b6b603469 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -174,6 +174,19 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
return count;
}
+u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
+
+ if (!i915_pipe_enabled(dev, pipe)) {
+ DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+ return 0;
+ }
+
+ return I915_READ(reg);
+}
+
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -370,12 +383,13 @@ int i915_irq_emit(struct drm_device *dev, void *data,
drm_i915_irq_emit_t *emit = data;
int result;
- RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
-
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
+
+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
+
mutex_lock(&dev->struct_mutex);
result = i915_emit_irq(dev);
mutex_unlock(&dev->struct_mutex);
@@ -411,6 +425,12 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
+ int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+ u32 pipeconf;
+
+ pipeconf = I915_READ(pipeconf_reg);
+ if (!(pipeconf & PIPEACONF_ENABLE))
+ return -EINVAL;
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
if (IS_I965G(dev))
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 273162579e1..90600d89941 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -184,14 +184,15 @@
* Fence registers
*/
#define FENCE_REG_830_0 0x2000
+#define FENCE_REG_945_8 0x3000
#define I830_FENCE_START_MASK 0x07f80000
#define I830_FENCE_TILING_Y_SHIFT 12
-#define I830_FENCE_SIZE_BITS(size) ((get_order(size >> 19) - 1) << 8)
+#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
#define I830_FENCE_PITCH_SHIFT 4
#define I830_FENCE_REG_VALID (1<<0)
#define I915_FENCE_START_MASK 0x0ff00000
-#define I915_FENCE_SIZE_BITS(size) ((get_order(size >> 20) - 1) << 8)
+#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8)
#define FENCE_REG_965_0 0x03000
#define I965_FENCE_PITCH_SHIFT 2
@@ -1371,6 +1372,9 @@
#define PIPE_FRAME_LOW_SHIFT 24
#define PIPE_PIXEL_MASK 0x00ffffff
#define PIPE_PIXEL_SHIFT 0
+/* GM45+ just has to be different */
+#define PIPEA_FRMCOUNT_GM45 0x70040
+#define PIPEA_FLIPCOUNT_GM45 0x70044
/* Cursor A & B regs */
#define CURACNTR 0x70080
@@ -1439,6 +1443,9 @@
#define PIPEBSTAT 0x71024
#define PIPEBFRAMEHIGH 0x71040
#define PIPEBFRAMEPIXEL 0x71044
+#define PIPEB_FRMCOUNT_GM45 0x71040
+#define PIPEB_FLIPCOUNT_GM45 0x71044
+
/* Display B control */
#define DSPBCNTR 0x71180
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 5d84027ee8f..d669cc2b42c 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -119,11 +119,6 @@ static void i915_save_vga(struct drm_device *dev)
/* VGA color palette registers */
dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK);
- /* DACCRX automatically increments during read */
- I915_WRITE8(VGA_DACRX, 0);
- /* Read 3 bytes of color data from each index */
- for (i = 0; i < 256 * 3; i++)
- dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA);
/* MSR bits */
dev_priv->saveMSR = I915_READ8(VGA_MSR_READ);
@@ -225,12 +220,6 @@ static void i915_restore_vga(struct drm_device *dev)
/* VGA color palette registers */
I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK);
- /* DACCRX automatically increments during read */
- I915_WRITE8(VGA_DACWX, 0);
- /* Read 3 bytes of color data from each index */
- for (i = 0; i < 256 * 3; i++)
- I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]);
-
}
int i915_save_state(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4ca82a02552..fc28e2bbd54 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -111,6 +111,12 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
panel_fixed_mode->clock = dvo_timing->clock * 10;
panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
+ /* Some VBTs have bogus h/vtotal values */
+ if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
+ panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
+ if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
+ panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+
drm_mode_set_name(panel_fixed_mode);
dev_priv->vbt_mode = panel_fixed_mode;
@@ -135,6 +141,14 @@ parse_general_features(struct drm_i915_private *dev_priv,
if (general) {
dev_priv->int_tv_support = general->int_tv_support;
dev_priv->int_crt_support = general->int_crt_support;
+ dev_priv->lvds_use_ssc = general->enable_ssc;
+
+ if (dev_priv->lvds_use_ssc) {
+ if (IS_I855(dev_priv->dev))
+ dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48;
+ else
+ dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96;
+ }
}
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8ccb9c3ab86..a2834276cb3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -90,12 +90,12 @@ typedef struct {
#define I9XX_DOT_MAX 400000
#define I9XX_VCO_MIN 1400000
#define I9XX_VCO_MAX 2800000
-#define I9XX_N_MIN 3
-#define I9XX_N_MAX 8
+#define I9XX_N_MIN 1
+#define I9XX_N_MAX 6
#define I9XX_M_MIN 70
#define I9XX_M_MAX 120
#define I9XX_M1_MIN 10
-#define I9XX_M1_MAX 20
+#define I9XX_M1_MAX 22
#define I9XX_M2_MIN 5
#define I9XX_M2_MAX 9
#define I9XX_P_SDVO_DAC_MIN 5
@@ -189,19 +189,7 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
return limit;
}
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-
-static void i8xx_clock(int refclk, intel_clock_t *clock)
-{
- clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
- clock->p = clock->p1 * clock->p2;
- clock->vco = refclk * clock->m / (clock->n + 2);
- clock->dot = clock->vco / clock->p;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
-
-static void i9xx_clock(int refclk, intel_clock_t *clock)
+static void intel_clock(int refclk, intel_clock_t *clock)
{
clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
clock->p = clock->p1 * clock->p2;
@@ -209,15 +197,6 @@ static void i9xx_clock(int refclk, intel_clock_t *clock)
clock->dot = clock->vco / clock->p;
}
-static void intel_clock(struct drm_device *dev, int refclk,
- intel_clock_t *clock)
-{
- if (IS_I9XX(dev))
- i9xx_clock (refclk, clock);
- else
- i8xx_clock (refclk, clock);
-}
-
/**
* Returns whether any output on the specified pipe is of the specified type
*/
@@ -238,7 +217,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
return false;
}
-#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
+#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0)
/**
* Returns whether the given set of divisors are valid for a given refclk with
* the given connectors.
@@ -318,7 +297,7 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
clock.p1 <= limit->p1.max; clock.p1++) {
int this_err;
- intel_clock(dev, refclk, &clock);
+ intel_clock(refclk, &clock);
if (!intel_PLL_is_valid(crtc, &clock))
continue;
@@ -343,7 +322,7 @@ intel_wait_for_vblank(struct drm_device *dev)
udelay(20000);
}
-static void
+static int
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
@@ -361,11 +340,21 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
u32 dspcntr, alignment;
+ int ret;
/* no fb bound */
if (!crtc->fb) {
DRM_DEBUG("No FB bound\n");
- return;
+ return 0;
+ }
+
+ switch (pipe) {
+ case 0:
+ case 1:
+ break;
+ default:
+ DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
+ return -EINVAL;
}
intel_fb = to_intel_framebuffer(crtc->fb);
@@ -377,30 +366,34 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
alignment = 64 * 1024;
break;
case I915_TILING_X:
- if (IS_I9XX(dev))
- alignment = 1024 * 1024;
- else
- alignment = 512 * 1024;
+ /* pin() will align the object as required by fence */
+ alignment = 0;
break;
case I915_TILING_Y:
/* FIXME: Is this true? */
DRM_ERROR("Y tiled not allowed for scan out buffers\n");
- return;
+ return -EINVAL;
default:
BUG();
}
- if (i915_gem_object_pin(intel_fb->obj, alignment))
- return;
-
- i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
-
- Start = obj_priv->gtt_offset;
- Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_object_pin(intel_fb->obj, alignment);
+ if (ret != 0) {
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
- I915_WRITE(dspstride, crtc->fb->pitch);
+ ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
+ if (ret != 0) {
+ i915_gem_object_unpin(intel_fb->obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
dspcntr = I915_READ(dspcntr_reg);
+ /* Mask out pixel format bits in case we change it */
+ dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
switch (crtc->fb->bits_per_pixel) {
case 8:
dspcntr |= DISPPLANE_8BPP;
@@ -417,11 +410,17 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
break;
default:
DRM_ERROR("Unknown color depth\n");
- return;
+ i915_gem_object_unpin(intel_fb->obj);
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
}
I915_WRITE(dspcntr_reg, dspcntr);
+ Start = obj_priv->gtt_offset;
+ Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+
DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+ I915_WRITE(dspstride, crtc->fb->pitch);
if (IS_I965G(dev)) {
I915_WRITE(dspbase, Offset);
I915_READ(dspbase);
@@ -438,27 +437,24 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
intel_fb = to_intel_framebuffer(old_fb);
i915_gem_object_unpin(intel_fb->obj);
}
+ mutex_unlock(&dev->struct_mutex);
if (!dev->primary->master)
- return;
+ return 0;
master_priv = dev->primary->master->driver_priv;
if (!master_priv->sarea_priv)
- return;
+ return 0;
- switch (pipe) {
- case 0:
- master_priv->sarea_priv->pipeA_x = x;
- master_priv->sarea_priv->pipeA_y = y;
- break;
- case 1:
+ if (pipe) {
master_priv->sarea_priv->pipeB_x = x;
master_priv->sarea_priv->pipeB_y = y;
- break;
- default:
- DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
- break;
+ } else {
+ master_priv->sarea_priv->pipeA_x = x;
+ master_priv->sarea_priv->pipeA_y = y;
}
+
+ return 0;
}
@@ -706,11 +702,11 @@ static int intel_panel_fitter_pipe (struct drm_device *dev)
return 1;
}
-static void intel_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- int x, int y,
- struct drm_framebuffer *old_fb)
+static int intel_crtc_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -730,13 +726,14 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
- int refclk;
+ int refclk, num_outputs = 0;
intel_clock_t clock;
u32 dpll = 0, fp = 0, dspcntr, pipeconf;
bool ok, is_sdvo = false, is_dvo = false;
bool is_crt = false, is_lvds = false, is_tv = false;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;
+ int ret;
drm_vblank_pre_modeset(dev, pipe);
@@ -753,6 +750,8 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
case INTEL_OUTPUT_SDVO:
case INTEL_OUTPUT_HDMI:
is_sdvo = true;
+ if (intel_output->needs_tv_clock)
+ is_tv = true;
break;
case INTEL_OUTPUT_DVO:
is_dvo = true;
@@ -764,9 +763,14 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
is_crt = true;
break;
}
+
+ num_outputs++;
}
- if (IS_I9XX(dev)) {
+ if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
+ refclk = dev_priv->lvds_ssc_freq * 1000;
+ DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000);
+ } else if (IS_I9XX(dev)) {
refclk = 96000;
} else {
refclk = 48000;
@@ -775,7 +779,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
- return;
+ return -EINVAL;
}
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
@@ -825,11 +829,14 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
}
}
- if (is_tv) {
+ if (is_sdvo && is_tv)
+ dpll |= PLL_REF_INPUT_TVCLKINBC;
+ else if (is_tv)
/* XXX: just matching BIOS for now */
-/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
+ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */
dpll |= 3;
- }
+ else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
+ dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
@@ -946,9 +953,13 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(dspcntr_reg, dspcntr);
/* Flush the plane changes */
- intel_pipe_set_base(crtc, x, y, old_fb);
+ ret = intel_pipe_set_base(crtc, x, y, old_fb);
+ if (ret != 0)
+ return ret;
drm_vblank_post_modeset(dev, pipe);
+
+ return 0;
}
/** Loads the palette/gamma unit for the CRTC with the prepared values */
@@ -997,6 +1008,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
temp = CURSOR_MODE_DISABLE;
addr = 0;
bo = NULL;
+ mutex_lock(&dev->struct_mutex);
goto finish;
}
@@ -1014,21 +1026,26 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
if (bo->size < width * height * 4) {
DRM_ERROR("buffer is to small\n");
- drm_gem_object_unreference(bo);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto fail;
}
- if (dev_priv->cursor_needs_physical) {
- addr = dev->agp->base + obj_priv->gtt_offset;
- } else {
+ /* we only need to pin inside GTT if cursor is non-phy */
+ mutex_lock(&dev->struct_mutex);
+ if (!dev_priv->cursor_needs_physical) {
+ ret = i915_gem_object_pin(bo, PAGE_SIZE);
+ if (ret) {
+ DRM_ERROR("failed to pin cursor bo\n");
+ goto fail_locked;
+ }
addr = obj_priv->gtt_offset;
- }
-
- ret = i915_gem_object_pin(bo, PAGE_SIZE);
- if (ret) {
- DRM_ERROR("failed to pin cursor bo\n");
- drm_gem_object_unreference(bo);
- return ret;
+ } else {
+ ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
+ if (ret) {
+ DRM_ERROR("failed to attach phys object\n");
+ goto fail_locked;
+ }
+ addr = obj_priv->phys_obj->handle->busaddr;
}
temp = 0;
@@ -1041,14 +1058,25 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
I915_WRITE(base, addr);
if (intel_crtc->cursor_bo) {
- i915_gem_object_unpin(intel_crtc->cursor_bo);
+ if (dev_priv->cursor_needs_physical) {
+ if (intel_crtc->cursor_bo != bo)
+ i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
+ } else
+ i915_gem_object_unpin(intel_crtc->cursor_bo);
drm_gem_object_unreference(intel_crtc->cursor_bo);
}
+ mutex_unlock(&dev->struct_mutex);
intel_crtc->cursor_addr = addr;
intel_crtc->cursor_bo = bo;
return 0;
+fail:
+ mutex_lock(&dev->struct_mutex);
+fail_locked:
+ drm_gem_object_unreference(bo);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
}
static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
@@ -1273,7 +1301,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
}
/* XXX: Handle the 100Mhz refclk */
- i9xx_clock(96000, &clock);
+ intel_clock(96000, &clock);
} else {
bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
@@ -1285,9 +1313,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
if ((dpll & PLL_REF_INPUT_MASK) ==
PLLB_REF_INPUT_SPREADSPECTRUMIN) {
/* XXX: might not be 66MHz */
- i8xx_clock(66000, &clock);
+ intel_clock(66000, &clock);
} else
- i8xx_clock(48000, &clock);
+ intel_clock(48000, &clock);
} else {
if (dpll & PLL_P1_DIVIDE_BY_TWO)
clock.p1 = 2;
@@ -1300,7 +1328,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
else
clock.p2 = 2;
- i8xx_clock(48000, &clock);
+ intel_clock(48000, &clock);
}
}
@@ -1435,6 +1463,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
static void intel_setup_outputs(struct drm_device *dev)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
intel_crt_init(dev);
@@ -1446,13 +1475,16 @@ static void intel_setup_outputs(struct drm_device *dev)
if (IS_I9XX(dev)) {
int found;
- found = intel_sdvo_init(dev, SDVOB);
- if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
- intel_hdmi_init(dev, SDVOB);
-
- found = intel_sdvo_init(dev, SDVOC);
- if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
- intel_hdmi_init(dev, SDVOC);
+ if (I915_READ(SDVOB) & SDVO_DETECTED) {
+ found = intel_sdvo_init(dev, SDVOB);
+ if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+ intel_hdmi_init(dev, SDVOB);
+ }
+ if (!IS_G4X(dev) || (I915_READ(SDVOB) & SDVO_DETECTED)) {
+ found = intel_sdvo_init(dev, SDVOC);
+ if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+ intel_hdmi_init(dev, SDVOC);
+ }
} else
intel_dvo_init(dev);
@@ -1575,7 +1607,9 @@ intel_user_framebuffer_create(struct drm_device *dev,
ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj);
if (ret) {
+ mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return NULL;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8a4cc50c5b4..957daef8edf 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -82,6 +82,7 @@ struct intel_output {
struct intel_i2c_chan *i2c_bus; /* for control functions */
struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */
bool load_detect_temp;
+ bool needs_tv_clock;
void *dev_priv;
};
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index afd1217b8a0..b7f0ebe9f81 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -473,7 +473,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
ret = intel_framebuffer_create(dev, &mode_cmd, &fb, fbo);
if (ret) {
DRM_ERROR("failed to allocate fb.\n");
- goto out_unref;
+ goto out_unpin;
}
list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
@@ -484,7 +484,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
info = framebuffer_alloc(sizeof(struct intelfb_par), device);
if (!info) {
ret = -ENOMEM;
- goto out_unref;
+ goto out_unpin;
}
par = info->par;
@@ -513,7 +513,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
size);
if (!info->screen_base) {
ret = -ENOSPC;
- goto out_unref;
+ goto out_unpin;
}
info->screen_size = size;
@@ -608,6 +608,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
mutex_unlock(&dev->struct_mutex);
return 0;
+out_unpin:
+ i915_gem_object_unpin(fbo);
out_unref:
drm_gem_object_unreference(fbo);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index a5a2f5339e9..5ee9d4c2575 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -137,10 +137,6 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
chan->reg = reg;
snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
chan->adapter.owner = THIS_MODULE;
-#ifndef I2C_HW_B_INTELFB
-#define I2C_HW_B_INTELFB I2C_HW_B_I810
-#endif
- chan->adapter.id = I2C_HW_B_INTELFB;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &dev->pdev->dev;
chan->algo.setsda = set_data;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index ccecfaf6307..0d211af9885 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -27,6 +27,7 @@
* Jesse Barnes <jesse.barnes@intel.com>
*/
+#include <linux/dmi.h>
#include <linux/i2c.h>
#include "drmP.h"
#include "drm.h"
@@ -311,10 +312,8 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
if (dev_priv->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
- mutex_unlock(&dev->mode_config.mutex);
mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
drm_mode_probed_add(connector, mode);
- mutex_unlock(&dev->mode_config.mutex);
return 1;
}
@@ -340,6 +339,18 @@ static void intel_lvds_destroy(struct drm_connector *connector)
kfree(connector);
}
+static int intel_lvds_set_property(struct drm_connector *connector,
+ struct drm_property *property,
+ uint64_t value)
+{
+ struct drm_device *dev = connector->dev;
+
+ if (property == dev->mode_config.dpms_property && connector->encoder)
+ intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf));
+
+ return 0;
+}
+
static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
.dpms = intel_lvds_dpms,
.mode_fixup = intel_lvds_mode_fixup,
@@ -359,6 +370,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.restore = intel_lvds_restore,
.detect = intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
+ .set_property = intel_lvds_set_property,
.destroy = intel_lvds_destroy,
};
@@ -392,6 +404,16 @@ void intel_lvds_init(struct drm_device *dev)
u32 lvds;
int pipe;
+ /* Blacklist machines that we know falsely report LVDS. */
+ /* FIXME: add a check for the Aopen Mini PC */
+
+ /* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */
+ if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") ||
+ dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) {
+ DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n");
+ return;
+ }
+
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output) {
return;
@@ -445,7 +467,7 @@ void intel_lvds_init(struct drm_device *dev)
dev_priv->panel_fixed_mode =
drm_mode_duplicate(dev, scan);
mutex_unlock(&dev->mode_config.mutex);
- goto out; /* FIXME: check for quirks */
+ goto out;
}
mutex_unlock(&dev->mode_config.mutex);
}
@@ -456,6 +478,11 @@ void intel_lvds_init(struct drm_device *dev)
dev_priv->panel_fixed_mode =
drm_mode_duplicate(dev, dev_priv->vbt_mode);
mutex_unlock(&dev->mode_config.mutex);
+ if (dev_priv->panel_fixed_mode) {
+ dev_priv->panel_fixed_mode->type |=
+ DRM_MODE_TYPE_PREFERRED;
+ goto out;
+ }
}
/*
@@ -472,7 +499,7 @@ void intel_lvds_init(struct drm_device *dev)
if (dev_priv->panel_fixed_mode) {
dev_priv->panel_fixed_mode->type |=
DRM_MODE_TYPE_PREFERRED;
- goto out; /* FIXME: check for quirks */
+ goto out;
}
}
@@ -480,38 +507,6 @@ void intel_lvds_init(struct drm_device *dev)
if (!dev_priv->panel_fixed_mode)
goto failed;
- /* FIXME: detect aopen & mac mini type stuff automatically? */
- /*
- * Blacklist machines with BIOSes that list an LVDS panel without
- * actually having one.
- */
- if (IS_I945GM(dev)) {
- /* aopen mini pc */
- if (dev->pdev->subsystem_vendor == 0xa0a0)
- goto failed;
-
- if ((dev->pdev->subsystem_vendor == 0x8086) &&
- (dev->pdev->subsystem_device == 0x7270)) {
- /* It's a Mac Mini or Macbook Pro.
- *
- * Apple hardware is out to get us. The macbook pro
- * has a real LVDS panel, but the mac mini does not,
- * and they have the same device IDs. We'll
- * distinguish by panel size, on the assumption
- * that Apple isn't about to make any machines with an
- * 800x600 display.
- */
-
- if (dev_priv->panel_fixed_mode != NULL &&
- dev_priv->panel_fixed_mode->hdisplay == 800 &&
- dev_priv->panel_fixed_mode->vdisplay == 600) {
- DRM_DEBUG("Suspected Mac Mini, ignoring the LVDS\n");
- goto failed;
- }
- }
- }
-
-
out:
drm_sysfs_connector_add(connector);
return;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 40721546910..fbe6f3931b1 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -40,13 +40,59 @@
struct intel_sdvo_priv {
struct intel_i2c_chan *i2c_bus;
int slaveaddr;
+
+ /* Register for the SDVO device: SDVOB or SDVOC */
int output_device;
- u16 active_outputs;
+ /* Active outputs controlled by this SDVO output */
+ uint16_t controlled_output;
+ /*
+ * Capabilities of the SDVO device returned by
+ * i830_sdvo_get_capabilities()
+ */
struct intel_sdvo_caps caps;
+
+ /* Pixel clock limitations reported by the SDVO device, in kHz */
int pixel_clock_min, pixel_clock_max;
+ /**
+ * This is set if we're going to treat the device as TV-out.
+ *
+ * While we have these nice friendly flags for output types that ought
+ * to decide this for us, the S-Video output on our HDMI+S-Video card
+ * shows up as RGB1 (VGA).
+ */
+ bool is_tv;
+
+ /**
+ * This is set if we treat the device as HDMI, instead of DVI.
+ */
+ bool is_hdmi;
+
+ /**
+ * Returned SDTV resolutions allowed for the current format, if the
+ * device reported it.
+ */
+ struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions;
+
+ /**
+ * Current selected TV format.
+ *
+ * This is stored in the same structure that's passed to the device, for
+ * convenience.
+ */
+ struct intel_sdvo_tv_format tv_format;
+
+ /*
+ * supported encoding mode, used to determine whether HDMI is
+ * supported
+ */
+ struct intel_sdvo_encode encode;
+
+ /* DDC bus used by this SDVO output */
+ uint8_t ddc_bus;
+
int save_sdvo_mult;
u16 save_active_outputs;
struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
@@ -147,9 +193,9 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
/** Mapping of command numbers to names, for debug output */
-const static struct _sdvo_cmd_name {
- u8 cmd;
- char *name;
+static const struct _sdvo_cmd_name {
+ u8 cmd;
+ char *name;
} sdvo_cmd_names[] = {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
@@ -186,8 +232,35 @@ const static struct _sdvo_cmd_name {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
+ /* HDMI op code */
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
};
#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
@@ -506,6 +579,50 @@ static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
}
+static bool
+intel_sdvo_create_preferred_input_timing(struct intel_output *output,
+ uint16_t clock,
+ uint16_t width,
+ uint16_t height)
+{
+ struct intel_sdvo_preferred_input_timing_args args;
+ uint8_t status;
+
+ args.clock = clock;
+ args.width = width;
+ args.height = height;
+ intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+ &args, sizeof(args));
+ status = intel_sdvo_read_response(output, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return true;
+}
+
+static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
+ struct intel_sdvo_dtd *dtd)
+{
+ bool status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+ NULL, 0);
+
+ status = intel_sdvo_read_response(output, &dtd->part1,
+ sizeof(dtd->part1));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+ NULL, 0);
+
+ status = intel_sdvo_read_response(output, &dtd->part2,
+ sizeof(dtd->part2));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return false;
+}
static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
{
@@ -536,36 +653,12 @@ static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8
return true;
}
-static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO
- * device will be told of the multiplier during mode_set.
- */
- adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
- return true;
-}
-
-static void intel_sdvo_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
+ struct drm_display_mode *mode)
{
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = encoder->crtc;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
- u16 width, height;
- u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
- u16 h_sync_offset, v_sync_offset;
- u32 sdvox;
- struct intel_sdvo_dtd output_dtd;
- int sdvo_pixel_multiply;
-
- if (!mode)
- return;
+ uint16_t width, height;
+ uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
+ uint16_t h_sync_offset, v_sync_offset;
width = mode->crtc_hdisplay;
height = mode->crtc_vdisplay;
@@ -580,93 +673,423 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
- output_dtd.part1.clock = mode->clock / 10;
- output_dtd.part1.h_active = width & 0xff;
- output_dtd.part1.h_blank = h_blank_len & 0xff;
- output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
+ dtd->part1.clock = mode->clock / 10;
+ dtd->part1.h_active = width & 0xff;
+ dtd->part1.h_blank = h_blank_len & 0xff;
+ dtd->part1.h_high = (((width >> 8) & 0xf) << 4) |
((h_blank_len >> 8) & 0xf);
- output_dtd.part1.v_active = height & 0xff;
- output_dtd.part1.v_blank = v_blank_len & 0xff;
- output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
+ dtd->part1.v_active = height & 0xff;
+ dtd->part1.v_blank = v_blank_len & 0xff;
+ dtd->part1.v_high = (((height >> 8) & 0xf) << 4) |
((v_blank_len >> 8) & 0xf);
- output_dtd.part2.h_sync_off = h_sync_offset;
- output_dtd.part2.h_sync_width = h_sync_len & 0xff;
- output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
+ dtd->part2.h_sync_off = h_sync_offset;
+ dtd->part2.h_sync_width = h_sync_len & 0xff;
+ dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
(v_sync_len & 0xf);
- output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
+ dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
((v_sync_len & 0x30) >> 4);
- output_dtd.part2.dtd_flags = 0x18;
+ dtd->part2.dtd_flags = 0x18;
if (mode->flags & DRM_MODE_FLAG_PHSYNC)
- output_dtd.part2.dtd_flags |= 0x2;
+ dtd->part2.dtd_flags |= 0x2;
if (mode->flags & DRM_MODE_FLAG_PVSYNC)
- output_dtd.part2.dtd_flags |= 0x4;
+ dtd->part2.dtd_flags |= 0x4;
+
+ dtd->part2.sdvo_flags = 0;
+ dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
+ dtd->part2.reserved = 0;
+}
+
+static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
+ struct intel_sdvo_dtd *dtd)
+{
+ uint16_t width, height;
+ uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
+ uint16_t h_sync_offset, v_sync_offset;
+
+ width = mode->crtc_hdisplay;
+ height = mode->crtc_vdisplay;
+
+ /* do some mode translations */
+ h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
+ h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+
+ v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
+ v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
+
+ h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
+ v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
+
+ mode->hdisplay = dtd->part1.h_active;
+ mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
+ mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off;
+ mode->hsync_start += (dtd->part2.sync_off_width_high & 0xa0) << 2;
+ mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width;
+ mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
+ mode->htotal = mode->hdisplay + dtd->part1.h_blank;
+ mode->htotal += (dtd->part1.h_high & 0xf) << 8;
+
+ mode->vdisplay = dtd->part1.v_active;
+ mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
+ mode->vsync_start = mode->vdisplay;
+ mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
+ mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0a) << 2;
+ mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0;
+ mode->vsync_end = mode->vsync_start +
+ (dtd->part2.v_sync_off_width & 0xf);
+ mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
+ mode->vtotal = mode->vdisplay + dtd->part1.v_blank;
+ mode->vtotal += (dtd->part1.v_high & 0xf) << 8;
+
+ mode->clock = dtd->part1.clock * 10;
+
+ mode->flags &= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+ if (dtd->part2.dtd_flags & 0x2)
+ mode->flags |= DRM_MODE_FLAG_PHSYNC;
+ if (dtd->part2.dtd_flags & 0x4)
+ mode->flags |= DRM_MODE_FLAG_PVSYNC;
+}
+
+static bool intel_sdvo_get_supp_encode(struct intel_output *output,
+ struct intel_sdvo_encode *encode)
+{
+ uint8_t status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+ status = intel_sdvo_read_response(output, encode, sizeof(*encode));
+ if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
+ memset(encode, 0, sizeof(*encode));
+ return false;
+ }
+
+ return true;
+}
+
+static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode)
+{
+ uint8_t status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
+ status = intel_sdvo_read_response(output, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+
+static bool intel_sdvo_set_colorimetry(struct intel_output *output,
+ uint8_t mode)
+{
+ uint8_t status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+ status = intel_sdvo_read_response(output, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+
+#if 0
+static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
+{
+ int i, j;
+ uint8_t set_buf_index[2];
+ uint8_t av_split;
+ uint8_t buf_size;
+ uint8_t buf[48];
+ uint8_t *pos;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+ intel_sdvo_read_response(output, &av_split, 1);
+
+ for (i = 0; i <= av_split; i++) {
+ set_buf_index[0] = i; set_buf_index[1] = 0;
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+ set_buf_index, 2);
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+ intel_sdvo_read_response(output, &buf_size, 1);
+
+ pos = buf;
+ for (j = 0; j <= buf_size; j += 8) {
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA,
+ NULL, 0);
+ intel_sdvo_read_response(output, pos, 8);
+ pos += 8;
+ }
+ }
+}
+#endif
+
+static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
+ uint8_t *data, int8_t size, uint8_t tx_rate)
+{
+ uint8_t set_buf_index[2];
+
+ set_buf_index[0] = index;
+ set_buf_index[1] = 0;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+
+ for (; size > 0; size -= 8) {
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+ data += 8;
+ }
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+}
+
+static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
+{
+ uint8_t csum = 0;
+ int i;
+
+ for (i = 0; i < size; i++)
+ csum += data[i];
+
+ return 0x100 - csum;
+}
+
+#define DIP_TYPE_AVI 0x82
+#define DIP_VERSION_AVI 0x2
+#define DIP_LEN_AVI 13
+
+struct dip_infoframe {
+ uint8_t type;
+ uint8_t version;
+ uint8_t len;
+ uint8_t checksum;
+ union {
+ struct {
+ /* Packet Byte #1 */
+ uint8_t S:2;
+ uint8_t B:2;
+ uint8_t A:1;
+ uint8_t Y:2;
+ uint8_t rsvd1:1;
+ /* Packet Byte #2 */
+ uint8_t R:4;
+ uint8_t M:2;
+ uint8_t C:2;
+ /* Packet Byte #3 */
+ uint8_t SC:2;
+ uint8_t Q:2;
+ uint8_t EC:3;
+ uint8_t ITC:1;
+ /* Packet Byte #4 */
+ uint8_t VIC:7;
+ uint8_t rsvd2:1;
+ /* Packet Byte #5 */
+ uint8_t PR:4;
+ uint8_t rsvd3:4;
+ /* Packet Byte #6~13 */
+ uint16_t top_bar_end;
+ uint16_t bottom_bar_start;
+ uint16_t left_bar_end;
+ uint16_t right_bar_start;
+ } avi;
+ struct {
+ /* Packet Byte #1 */
+ uint8_t channel_count:3;
+ uint8_t rsvd1:1;
+ uint8_t coding_type:4;
+ /* Packet Byte #2 */
+ uint8_t sample_size:2; /* SS0, SS1 */
+ uint8_t sample_frequency:3;
+ uint8_t rsvd2:3;
+ /* Packet Byte #3 */
+ uint8_t coding_type_private:5;
+ uint8_t rsvd3:3;
+ /* Packet Byte #4 */
+ uint8_t channel_allocation;
+ /* Packet Byte #5 */
+ uint8_t rsvd4:3;
+ uint8_t level_shift:4;
+ uint8_t downmix_inhibit:1;
+ } audio;
+ uint8_t payload[28];
+ } __attribute__ ((packed)) u;
+} __attribute__((packed));
+
+static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
+ struct drm_display_mode * mode)
+{
+ struct dip_infoframe avi_if = {
+ .type = DIP_TYPE_AVI,
+ .version = DIP_VERSION_AVI,
+ .len = DIP_LEN_AVI,
+ };
+
+ avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
+ 4 + avi_if.len);
+ intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+ SDVO_HBUF_TX_VSYNC);
+}
+
+static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct intel_output *output = enc_to_intel_output(encoder);
+ struct intel_sdvo_priv *dev_priv = output->dev_priv;
- output_dtd.part2.sdvo_flags = 0;
- output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
- output_dtd.part2.reserved = 0;
+ if (!dev_priv->is_tv) {
+ /* Make the CRTC code factor in the SDVO pixel multiplier. The
+ * SDVO device will be told of the multiplier during mode_set.
+ */
+ adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
+ } else {
+ struct intel_sdvo_dtd output_dtd;
+ bool success;
+
+ /* We need to construct preferred input timings based on our
+ * output timings. To do that, we have to set the output
+ * timings, even though this isn't really the right place in
+ * the sequence to do it. Oh well.
+ */
+
+
+ /* Set output timings */
+ intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+ intel_sdvo_set_target_output(output,
+ dev_priv->controlled_output);
+ intel_sdvo_set_output_timing(output, &output_dtd);
+
+ /* Set the input timing to the screen. Assume always input 0. */
+ intel_sdvo_set_target_input(output, true, false);
+
+
+ success = intel_sdvo_create_preferred_input_timing(output,
+ mode->clock / 10,
+ mode->hdisplay,
+ mode->vdisplay);
+ if (success) {
+ struct intel_sdvo_dtd input_dtd;
- /* Set the output timing to the screen */
- intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs);
- intel_sdvo_set_output_timing(intel_output, &output_dtd);
+ intel_sdvo_get_preferred_input_timing(output,
+ &input_dtd);
+ intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void intel_sdvo_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = encoder->crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_output *output = enc_to_intel_output(encoder);
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ u32 sdvox = 0;
+ int sdvo_pixel_multiply;
+ struct intel_sdvo_in_out_map in_out;
+ struct intel_sdvo_dtd input_dtd;
+ u8 status;
+
+ if (!mode)
+ return;
+
+ /* First, set the input mapping for the first input to our controlled
+ * output. This is only correct if we're a single-input device, in
+ * which case the first input is the output from the appropriate SDVO
+ * channel on the motherboard. In a two-input device, the first input
+ * will be SDVOB and the second SDVOC.
+ */
+ in_out.in0 = sdvo_priv->controlled_output;
+ in_out.in1 = 0;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
+ &in_out, sizeof(in_out));
+ status = intel_sdvo_read_response(output, NULL, 0);
+
+ if (sdvo_priv->is_hdmi) {
+ intel_sdvo_set_avi_infoframe(output, mode);
+ sdvox |= SDVO_AUDIO_ENABLE;
+ }
+
+ intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
+
+ /* If it's a TV, we already set the output timing in mode_fixup.
+ * Otherwise, the output timing is equal to the input timing.
+ */
+ if (!sdvo_priv->is_tv) {
+ /* Set the output timing to the screen */
+ intel_sdvo_set_target_output(output,
+ sdvo_priv->controlled_output);
+ intel_sdvo_set_output_timing(output, &input_dtd);
+ }
/* Set the input timing to the screen. Assume always input 0. */
- intel_sdvo_set_target_input(intel_output, true, false);
+ intel_sdvo_set_target_input(output, true, false);
- /* We would like to use i830_sdvo_create_preferred_input_timing() to
+ /* We would like to use intel_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
* feature. However, presumably we would need to adjust the CRTC to
* output the preferred timing, and we don't support that currently.
*/
- intel_sdvo_set_input_timing(intel_output, &output_dtd);
+#if 0
+ success = intel_sdvo_create_preferred_input_timing(output, clock,
+ width, height);
+ if (success) {
+ struct intel_sdvo_dtd *input_dtd;
+
+ intel_sdvo_get_preferred_input_timing(output, &input_dtd);
+ intel_sdvo_set_input_timing(output, &input_dtd);
+ }
+#else
+ intel_sdvo_set_input_timing(output, &input_dtd);
+#endif
switch (intel_sdvo_get_pixel_multiplier(mode)) {
case 1:
- intel_sdvo_set_clock_rate_mult(intel_output,
+ intel_sdvo_set_clock_rate_mult(output,
SDVO_CLOCK_RATE_MULT_1X);
break;
case 2:
- intel_sdvo_set_clock_rate_mult(intel_output,
+ intel_sdvo_set_clock_rate_mult(output,
SDVO_CLOCK_RATE_MULT_2X);
break;
case 4:
- intel_sdvo_set_clock_rate_mult(intel_output,
+ intel_sdvo_set_clock_rate_mult(output,
SDVO_CLOCK_RATE_MULT_4X);
break;
}
/* Set the SDVO control regs. */
- if (0/*IS_I965GM(dev)*/) {
- sdvox = SDVO_BORDER_ENABLE;
- } else {
- sdvox = I915_READ(sdvo_priv->output_device);
- switch (sdvo_priv->output_device) {
- case SDVOB:
- sdvox &= SDVOB_PRESERVE_MASK;
- break;
- case SDVOC:
- sdvox &= SDVOC_PRESERVE_MASK;
- break;
- }
- sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
- }
+ if (IS_I965G(dev)) {
+ sdvox |= SDVO_BORDER_ENABLE |
+ SDVO_VSYNC_ACTIVE_HIGH |
+ SDVO_HSYNC_ACTIVE_HIGH;
+ } else {
+ sdvox |= I915_READ(sdvo_priv->output_device);
+ switch (sdvo_priv->output_device) {
+ case SDVOB:
+ sdvox &= SDVOB_PRESERVE_MASK;
+ break;
+ case SDVOC:
+ sdvox &= SDVOC_PRESERVE_MASK;
+ break;
+ }
+ sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
+ }
if (intel_crtc->pipe == 1)
sdvox |= SDVO_PIPE_B_SELECT;
sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
if (IS_I965G(dev)) {
- /* done in crtc_mode_set as the dpll_md reg must be written
- early */
- } else if (IS_I945G(dev) || IS_I945GM(dev)) {
- /* done in crtc_mode_set as it lives inside the
- dpll register */
+ /* done in crtc_mode_set as the dpll_md reg must be written early */
+ } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
+ /* done in crtc_mode_set as it lives inside the dpll register */
} else {
sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
}
- intel_sdvo_write_sdvox(intel_output, sdvox);
+ intel_sdvo_write_sdvox(output, sdvox);
}
static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
@@ -714,7 +1137,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
if (0)
intel_sdvo_set_encoder_power_state(intel_output, mode);
- intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs);
+ intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output);
}
return;
}
@@ -752,6 +1175,9 @@ static void intel_sdvo_save(struct drm_connector *connector)
&sdvo_priv->save_output_dtd[o]);
}
}
+ if (sdvo_priv->is_tv) {
+ /* XXX: Save TV format/enhancements. */
+ }
sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
}
@@ -759,7 +1185,6 @@ static void intel_sdvo_save(struct drm_connector *connector)
static void intel_sdvo_restore(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_output *intel_output = to_intel_output(connector);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
int o;
@@ -790,7 +1215,11 @@ static void intel_sdvo_restore(struct drm_connector *connector)
intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
- I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
+ if (sdvo_priv->is_tv) {
+ /* XXX: Restore TV format/enhancements. */
+ }
+
+ intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX);
if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
{
@@ -916,20 +1345,173 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
status = intel_sdvo_read_response(intel_output, &response, 2);
DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
+
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return connector_status_unknown;
+
if ((response[0] != 0) || (response[1] != 0))
return connector_status_connected;
else
return connector_status_disconnected;
}
-static int intel_sdvo_get_modes(struct drm_connector *connector)
+static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
{
struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
/* set the bus switch and get the modes */
- intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2);
+ intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
intel_ddc_get_modes(intel_output);
+#if 0
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ /* Mac mini hack. On this device, I get DDC through the analog, which
+ * load-detects as disconnected. I fail to DDC through the SDVO DDC,
+ * but it does load-detect as connected. So, just steal the DDC bits
+ * from analog when we fail at finding it the right way.
+ */
+ crt = xf86_config->output[0];
+ intel_output = crt->driver_private;
+ if (intel_output->type == I830_OUTPUT_ANALOG &&
+ crt->funcs->detect(crt) == XF86OutputStatusDisconnected) {
+ I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A");
+ edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus);
+ xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true);
+ }
+ if (edid_mon) {
+ xf86OutputSetEDID(output, edid_mon);
+ modes = xf86OutputGetEDIDModes(output);
+ }
+#endif
+}
+
+/**
+ * This function checks the current TV format, and chooses a default if
+ * it hasn't been set.
+ */
+static void
+intel_sdvo_check_tv_format(struct intel_output *output)
+{
+ struct intel_sdvo_priv *dev_priv = output->dev_priv;
+ struct intel_sdvo_tv_format format, unset;
+ uint8_t status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
+ status = intel_sdvo_read_response(output, &format, sizeof(format));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return;
+
+ memset(&unset, 0, sizeof(unset));
+ if (memcmp(&format, &unset, sizeof(format))) {
+ DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
+ SDVO_NAME(dev_priv));
+
+ format.ntsc_m = true;
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0);
+ status = intel_sdvo_read_response(output, NULL, 0);
+ }
+}
+
+/*
+ * Set of SDVO TV modes.
+ * Note! This is in reply order (see loop in get_tv_modes).
+ * XXX: all 60Hz refresh?
+ */
+struct drm_display_mode sdvo_tv_modes[] = {
+ { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416,
+ 200, 0, 232, 201, 233, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416,
+ 240, 0, 272, 241, 273, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496,
+ 300, 0, 332, 301, 333, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736,
+ 350, 0, 382, 351, 383, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
+ 400, 0, 432, 401, 433, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
+ 400, 0, 432, 401, 433, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800,
+ 480, 0, 512, 481, 513, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800,
+ 576, 0, 608, 577, 609, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816,
+ 350, 0, 382, 351, 383, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816,
+ 400, 0, 432, 401, 433, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816,
+ 480, 0, 512, 481, 513, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816,
+ 540, 0, 572, 541, 573, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816,
+ 576, 0, 608, 577, 609, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864,
+ 576, 0, 608, 577, 609, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896,
+ 600, 0, 632, 601, 633, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928,
+ 624, 0, 656, 625, 657, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016,
+ 766, 0, 798, 767, 799, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120,
+ 768, 0, 800, 769, 801, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376,
+ 1024, 0, 1056, 1025, 1057, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+};
+
+static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
+{
+ struct intel_output *output = to_intel_output(connector);
+ uint32_t reply = 0;
+ uint8_t status;
+ int i = 0;
+
+ intel_sdvo_check_tv_format(output);
+
+ /* Read the list of supported input resolutions for the selected TV
+ * format.
+ */
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
+ NULL, 0);
+ status = intel_sdvo_read_response(output, &reply, 3);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
+ if (reply & (1 << i))
+ drm_mode_probed_add(connector, &sdvo_tv_modes[i]);
+}
+
+static int intel_sdvo_get_modes(struct drm_connector *connector)
+{
+ struct intel_output *output = to_intel_output(connector);
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+
+ if (sdvo_priv->is_tv)
+ intel_sdvo_get_tv_modes(connector);
+ else
+ intel_sdvo_get_ddc_modes(connector);
+
if (list_empty(&connector->probed_modes))
return 0;
return 1;
@@ -978,6 +1560,65 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
};
+/**
+ * Choose the appropriate DDC bus for control bus switch command for this
+ * SDVO output based on the controlled output.
+ *
+ * DDC bus number assignment is in a priority order of RGB outputs, then TMDS
+ * outputs, then LVDS outputs.
+ */
+static void
+intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
+{
+ uint16_t mask = 0;
+ unsigned int num_bits;
+
+ /* Make a mask of outputs less than or equal to our own priority in the
+ * list.
+ */
+ switch (dev_priv->controlled_output) {
+ case SDVO_OUTPUT_LVDS1:
+ mask |= SDVO_OUTPUT_LVDS1;
+ case SDVO_OUTPUT_LVDS0:
+ mask |= SDVO_OUTPUT_LVDS0;
+ case SDVO_OUTPUT_TMDS1:
+ mask |= SDVO_OUTPUT_TMDS1;
+ case SDVO_OUTPUT_TMDS0:
+ mask |= SDVO_OUTPUT_TMDS0;
+ case SDVO_OUTPUT_RGB1:
+ mask |= SDVO_OUTPUT_RGB1;
+ case SDVO_OUTPUT_RGB0:
+ mask |= SDVO_OUTPUT_RGB0;
+ break;
+ }
+
+ /* Count bits to find what number we are in the priority list. */
+ mask &= dev_priv->caps.output_flags;
+ num_bits = hweight16(mask);
+ if (num_bits > 3) {
+ /* if more than 3 outputs, default to DDC bus 3 for now */
+ num_bits = 3;
+ }
+
+ /* Corresponds to SDVO_CONTROL_BUS_DDCx */
+ dev_priv->ddc_bus = 1 << num_bits;
+}
+
+static bool
+intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
+{
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ uint8_t status;
+
+ intel_sdvo_set_target_output(output, sdvo_priv->controlled_output);
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0);
+ status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+ return true;
+}
+
bool intel_sdvo_init(struct drm_device *dev, int output_device)
{
struct drm_connector *connector;
@@ -1040,45 +1681,76 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
- memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs));
+ if (sdvo_priv->caps.output_flags &
+ (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
+ if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+ sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0;
+ else
+ sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1;
+
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ encoder_type = DRM_MODE_ENCODER_TMDS;
+ connector_type = DRM_MODE_CONNECTOR_DVID;
- /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
- if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
+ if (intel_sdvo_get_supp_encode(intel_output,
+ &sdvo_priv->encode) &&
+ intel_sdvo_get_digital_encoding_mode(intel_output) &&
+ sdvo_priv->is_hdmi) {
+ /* enable hdmi encoding mode if supported */
+ intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
+ intel_sdvo_set_colorimetry(intel_output,
+ SDVO_COLORIMETRY_RGB256);
+ connector_type = DRM_MODE_CONNECTOR_HDMIA;
+ }
+ }
+ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
{
- sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
+ sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ encoder_type = DRM_MODE_ENCODER_TVDAC;
+ connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+ sdvo_priv->is_tv = true;
+ intel_output->needs_tv_clock = true;
+ }
+ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
+ {
+ sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
encoder_type = DRM_MODE_ENCODER_DAC;
connector_type = DRM_MODE_CONNECTOR_VGA;
}
else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
{
- sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
+ sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
encoder_type = DRM_MODE_ENCODER_DAC;
connector_type = DRM_MODE_CONNECTOR_VGA;
}
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0)
{
- sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
+ sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- encoder_type = DRM_MODE_ENCODER_TMDS;
- connector_type = DRM_MODE_CONNECTOR_DVID;
+ encoder_type = DRM_MODE_ENCODER_LVDS;
+ connector_type = DRM_MODE_CONNECTOR_LVDS;
}
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
+ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1)
{
- sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
+ sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- encoder_type = DRM_MODE_ENCODER_TMDS;
- connector_type = DRM_MODE_CONNECTOR_DVID;
+ encoder_type = DRM_MODE_ENCODER_LVDS;
+ connector_type = DRM_MODE_CONNECTOR_LVDS;
}
else
{
unsigned char bytes[2];
+ sdvo_priv->controlled_output = 0;
memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
- DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
+ DRM_DEBUG("%s: Unknown SDVO output type (0x%02x%02x)\n",
SDVO_NAME(sdvo_priv),
bytes[0], bytes[1]);
+ encoder_type = DRM_MODE_ENCODER_NONE;
+ connector_type = DRM_MODE_CONNECTOR_Unknown;
goto err_i2c;
}
@@ -1089,6 +1761,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
drm_sysfs_connector_add(connector);
+ intel_sdvo_select_ddc_bus(sdvo_priv);
+
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input(intel_output, true, false);
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h
index 861a43f8693..1117b9c151a 100644
--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h
+++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
@@ -173,6 +173,9 @@ struct intel_sdvo_get_trained_inputs_response {
* Returns two struct intel_sdvo_output_flags structures.
*/
#define SDVO_CMD_GET_IN_OUT_MAP 0x06
+struct intel_sdvo_in_out_map {
+ u16 in0, in1;
+};
/**
* Sets the current mapping of SDVO inputs to outputs on the device.
@@ -206,7 +209,8 @@ struct intel_sdvo_get_trained_inputs_response {
struct intel_sdvo_get_interrupt_event_source_response {
u16 interrupt_status;
unsigned int ambient_light_interrupt:1;
- unsigned int pad:7;
+ unsigned int hdmi_audio_encrypt_change:1;
+ unsigned int pad:6;
} __attribute__((packed));
/**
@@ -305,23 +309,411 @@ struct intel_sdvo_set_target_input_args {
# define SDVO_CLOCK_RATE_MULT_4X (1 << 3)
#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27
+/** 5 bytes of bit flags for TV formats shared by all TV format functions */
+struct intel_sdvo_tv_format {
+ unsigned int ntsc_m:1;
+ unsigned int ntsc_j:1;
+ unsigned int ntsc_443:1;
+ unsigned int pal_b:1;
+ unsigned int pal_d:1;
+ unsigned int pal_g:1;
+ unsigned int pal_h:1;
+ unsigned int pal_i:1;
+
+ unsigned int pal_m:1;
+ unsigned int pal_n:1;
+ unsigned int pal_nc:1;
+ unsigned int pal_60:1;
+ unsigned int secam_b:1;
+ unsigned int secam_d:1;
+ unsigned int secam_g:1;
+ unsigned int secam_k:1;
+
+ unsigned int secam_k1:1;
+ unsigned int secam_l:1;
+ unsigned int secam_60:1;
+ unsigned int hdtv_std_smpte_240m_1080i_59:1;
+ unsigned int hdtv_std_smpte_240m_1080i_60:1;
+ unsigned int hdtv_std_smpte_260m_1080i_59:1;
+ unsigned int hdtv_std_smpte_260m_1080i_60:1;
+ unsigned int hdtv_std_smpte_274m_1080i_50:1;
+
+ unsigned int hdtv_std_smpte_274m_1080i_59:1;
+ unsigned int hdtv_std_smpte_274m_1080i_60:1;
+ unsigned int hdtv_std_smpte_274m_1080p_23:1;
+ unsigned int hdtv_std_smpte_274m_1080p_24:1;
+ unsigned int hdtv_std_smpte_274m_1080p_25:1;
+ unsigned int hdtv_std_smpte_274m_1080p_29:1;
+ unsigned int hdtv_std_smpte_274m_1080p_30:1;
+ unsigned int hdtv_std_smpte_274m_1080p_50:1;
+
+ unsigned int hdtv_std_smpte_274m_1080p_59:1;
+ unsigned int hdtv_std_smpte_274m_1080p_60:1;
+ unsigned int hdtv_std_smpte_295m_1080i_50:1;
+ unsigned int hdtv_std_smpte_295m_1080p_50:1;
+ unsigned int hdtv_std_smpte_296m_720p_59:1;
+ unsigned int hdtv_std_smpte_296m_720p_60:1;
+ unsigned int hdtv_std_smpte_296m_720p_50:1;
+ unsigned int hdtv_std_smpte_293m_480p_59:1;
+
+ unsigned int hdtv_std_smpte_170m_480i_59:1;
+ unsigned int hdtv_std_iturbt601_576i_50:1;
+ unsigned int hdtv_std_iturbt601_576p_50:1;
+ unsigned int hdtv_std_eia_7702a_480i_60:1;
+ unsigned int hdtv_std_eia_7702a_480p_60:1;
+ unsigned int pad:3;
+} __attribute__((packed));
#define SDVO_CMD_GET_TV_FORMAT 0x28
#define SDVO_CMD_SET_TV_FORMAT 0x29
+/** Returns the resolutiosn that can be used with the given TV format */
+#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83
+struct intel_sdvo_sdtv_resolution_request {
+ unsigned int ntsc_m:1;
+ unsigned int ntsc_j:1;
+ unsigned int ntsc_443:1;
+ unsigned int pal_b:1;
+ unsigned int pal_d:1;
+ unsigned int pal_g:1;
+ unsigned int pal_h:1;
+ unsigned int pal_i:1;
+
+ unsigned int pal_m:1;
+ unsigned int pal_n:1;
+ unsigned int pal_nc:1;
+ unsigned int pal_60:1;
+ unsigned int secam_b:1;
+ unsigned int secam_d:1;
+ unsigned int secam_g:1;
+ unsigned int secam_k:1;
+
+ unsigned int secam_k1:1;
+ unsigned int secam_l:1;
+ unsigned int secam_60:1;
+ unsigned int pad:5;
+} __attribute__((packed));
+
+struct intel_sdvo_sdtv_resolution_reply {
+ unsigned int res_320x200:1;
+ unsigned int res_320x240:1;
+ unsigned int res_400x300:1;
+ unsigned int res_640x350:1;
+ unsigned int res_640x400:1;
+ unsigned int res_640x480:1;
+ unsigned int res_704x480:1;
+ unsigned int res_704x576:1;
+
+ unsigned int res_720x350:1;
+ unsigned int res_720x400:1;
+ unsigned int res_720x480:1;
+ unsigned int res_720x540:1;
+ unsigned int res_720x576:1;
+ unsigned int res_768x576:1;
+ unsigned int res_800x600:1;
+ unsigned int res_832x624:1;
+
+ unsigned int res_920x766:1;
+ unsigned int res_1024x768:1;
+ unsigned int res_1280x1024:1;
+ unsigned int pad:5;
+} __attribute__((packed));
+
+/* Get supported resolution with squire pixel aspect ratio that can be
+ scaled for the requested HDTV format */
+#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85
+
+struct intel_sdvo_hdtv_resolution_request {
+ unsigned int hdtv_std_smpte_240m_1080i_59:1;
+ unsigned int hdtv_std_smpte_240m_1080i_60:1;
+ unsigned int hdtv_std_smpte_260m_1080i_59:1;
+ unsigned int hdtv_std_smpte_260m_1080i_60:1;
+ unsigned int hdtv_std_smpte_274m_1080i_50:1;
+ unsigned int hdtv_std_smpte_274m_1080i_59:1;
+ unsigned int hdtv_std_smpte_274m_1080i_60:1;
+ unsigned int hdtv_std_smpte_274m_1080p_23:1;
+
+ unsigned int hdtv_std_smpte_274m_1080p_24:1;
+ unsigned int hdtv_std_smpte_274m_1080p_25:1;
+ unsigned int hdtv_std_smpte_274m_1080p_29:1;
+ unsigned int hdtv_std_smpte_274m_1080p_30:1;
+ unsigned int hdtv_std_smpte_274m_1080p_50:1;
+ unsigned int hdtv_std_smpte_274m_1080p_59:1;
+ unsigned int hdtv_std_smpte_274m_1080p_60:1;
+ unsigned int hdtv_std_smpte_295m_1080i_50:1;
+
+ unsigned int hdtv_std_smpte_295m_1080p_50:1;
+ unsigned int hdtv_std_smpte_296m_720p_59:1;
+ unsigned int hdtv_std_smpte_296m_720p_60:1;
+ unsigned int hdtv_std_smpte_296m_720p_50:1;
+ unsigned int hdtv_std_smpte_293m_480p_59:1;
+ unsigned int hdtv_std_smpte_170m_480i_59:1;
+ unsigned int hdtv_std_iturbt601_576i_50:1;
+ unsigned int hdtv_std_iturbt601_576p_50:1;
+
+ unsigned int hdtv_std_eia_7702a_480i_60:1;
+ unsigned int hdtv_std_eia_7702a_480p_60:1;
+ unsigned int pad:6;
+} __attribute__((packed));
+
+struct intel_sdvo_hdtv_resolution_reply {
+ unsigned int res_640x480:1;
+ unsigned int res_800x600:1;
+ unsigned int res_1024x768:1;
+ unsigned int res_1280x960:1;
+ unsigned int res_1400x1050:1;
+ unsigned int res_1600x1200:1;
+ unsigned int res_1920x1440:1;
+ unsigned int res_2048x1536:1;
+
+ unsigned int res_2560x1920:1;
+ unsigned int res_3200x2400:1;
+ unsigned int res_3840x2880:1;
+ unsigned int pad1:5;
+
+ unsigned int res_848x480:1;
+ unsigned int res_1064x600:1;
+ unsigned int res_1280x720:1;
+ unsigned int res_1360x768:1;
+ unsigned int res_1704x960:1;
+ unsigned int res_1864x1050:1;
+ unsigned int res_1920x1080:1;
+ unsigned int res_2128x1200:1;
+
+ unsigned int res_2560x1400:1;
+ unsigned int res_2728x1536:1;
+ unsigned int res_3408x1920:1;
+ unsigned int res_4264x2400:1;
+ unsigned int res_5120x2880:1;
+ unsigned int pad2:3;
+
+ unsigned int res_768x480:1;
+ unsigned int res_960x600:1;
+ unsigned int res_1152x720:1;
+ unsigned int res_1124x768:1;
+ unsigned int res_1536x960:1;
+ unsigned int res_1680x1050:1;
+ unsigned int res_1728x1080:1;
+ unsigned int res_1920x1200:1;
+
+ unsigned int res_2304x1440:1;
+ unsigned int res_2456x1536:1;
+ unsigned int res_3072x1920:1;
+ unsigned int res_3840x2400:1;
+ unsigned int res_4608x2880:1;
+ unsigned int pad3:3;
+
+ unsigned int res_1280x1024:1;
+ unsigned int pad4:7;
+
+ unsigned int res_1280x768:1;
+ unsigned int pad5:7;
+} __attribute__((packed));
+
+/* Get supported power state returns info for encoder and monitor, rely on
+ last SetTargetInput and SetTargetOutput calls */
#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a
+/* Get power state returns info for encoder and monitor, rely on last
+ SetTargetInput and SetTargetOutput calls */
+#define SDVO_CMD_GET_POWER_STATE 0x2b
#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b
#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c
# define SDVO_ENCODER_STATE_ON (1 << 0)
# define SDVO_ENCODER_STATE_STANDBY (1 << 1)
# define SDVO_ENCODER_STATE_SUSPEND (1 << 2)
# define SDVO_ENCODER_STATE_OFF (1 << 3)
+# define SDVO_MONITOR_STATE_ON (1 << 4)
+# define SDVO_MONITOR_STATE_STANDBY (1 << 5)
+# define SDVO_MONITOR_STATE_SUSPEND (1 << 6)
+# define SDVO_MONITOR_STATE_OFF (1 << 7)
+
+#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d
+#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e
+#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f
+/**
+ * The panel power sequencing parameters are in units of milliseconds.
+ * The high fields are bits 8:9 of the 10-bit values.
+ */
+struct sdvo_panel_power_sequencing {
+ u8 t0;
+ u8 t1;
+ u8 t2;
+ u8 t3;
+ u8 t4;
+
+ unsigned int t0_high:2;
+ unsigned int t1_high:2;
+ unsigned int t2_high:2;
+ unsigned int t3_high:2;
+
+ unsigned int t4_high:2;
+ unsigned int pad:6;
+} __attribute__((packed));
+
+#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30
+struct sdvo_max_backlight_reply {
+ u8 max_value;
+ u8 default_value;
+} __attribute__((packed));
+
+#define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31
+#define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32
+
+#define SDVO_CMD_GET_AMBIENT_LIGHT 0x33
+struct sdvo_get_ambient_light_reply {
+ u16 trip_low;
+ u16 trip_high;
+ u16 value;
+} __attribute__((packed));
+#define SDVO_CMD_SET_AMBIENT_LIGHT 0x34
+struct sdvo_set_ambient_light_reply {
+ u16 trip_low;
+ u16 trip_high;
+ unsigned int enable:1;
+ unsigned int pad:7;
+} __attribute__((packed));
+
+/* Set display power state */
+#define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d
+# define SDVO_DISPLAY_STATE_ON (1 << 0)
+# define SDVO_DISPLAY_STATE_STANDBY (1 << 1)
+# define SDVO_DISPLAY_STATE_SUSPEND (1 << 2)
+# define SDVO_DISPLAY_STATE_OFF (1 << 3)
+
+#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84
+struct intel_sdvo_enhancements_reply {
+ unsigned int flicker_filter:1;
+ unsigned int flicker_filter_adaptive:1;
+ unsigned int flicker_filter_2d:1;
+ unsigned int saturation:1;
+ unsigned int hue:1;
+ unsigned int brightness:1;
+ unsigned int contrast:1;
+ unsigned int overscan_h:1;
+
+ unsigned int overscan_v:1;
+ unsigned int position_h:1;
+ unsigned int position_v:1;
+ unsigned int sharpness:1;
+ unsigned int dot_crawl:1;
+ unsigned int dither:1;
+ unsigned int max_tv_chroma_filter:1;
+ unsigned int max_tv_luma_filter:1;
+} __attribute__((packed));
+
+/* Picture enhancement limits below are dependent on the current TV format,
+ * and thus need to be queried and set after it.
+ */
+#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d
+#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b
+#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52
+#define SDVO_CMD_GET_MAX_SATURATION 0x55
+#define SDVO_CMD_GET_MAX_HUE 0x58
+#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b
+#define SDVO_CMD_GET_MAX_CONTRAST 0x5e
+#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61
+#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64
+#define SDVO_CMD_GET_MAX_POSITION_H 0x67
+#define SDVO_CMD_GET_MAX_POSITION_V 0x6a
+#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d
+#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74
+#define SDVO_CMD_GET_MAX_TV_LUMA 0x77
+struct intel_sdvo_enhancement_limits_reply {
+ u16 max_value;
+ u16 default_value;
+} __attribute__((packed));
-#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93
+#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f
+#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80
+# define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0)
+# define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0)
+# define SDVO_LVDS_CONNECTOR_SPWG (0 << 2)
+# define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2)
+# define SDVO_LVDS_SINGLE_CHANNEL (0 << 4)
+# define SDVO_LVDS_DUAL_CHANNEL (1 << 4)
+
+#define SDVO_CMD_GET_FLICKER_FILTER 0x4e
+#define SDVO_CMD_SET_FLICKER_FILTER 0x4f
+#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50
+#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51
+#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53
+#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54
+#define SDVO_CMD_GET_SATURATION 0x56
+#define SDVO_CMD_SET_SATURATION 0x57
+#define SDVO_CMD_GET_HUE 0x59
+#define SDVO_CMD_SET_HUE 0x5a
+#define SDVO_CMD_GET_BRIGHTNESS 0x5c
+#define SDVO_CMD_SET_BRIGHTNESS 0x5d
+#define SDVO_CMD_GET_CONTRAST 0x5f
+#define SDVO_CMD_SET_CONTRAST 0x60
+#define SDVO_CMD_GET_OVERSCAN_H 0x62
+#define SDVO_CMD_SET_OVERSCAN_H 0x63
+#define SDVO_CMD_GET_OVERSCAN_V 0x65
+#define SDVO_CMD_SET_OVERSCAN_V 0x66
+#define SDVO_CMD_GET_POSITION_H 0x68
+#define SDVO_CMD_SET_POSITION_H 0x69
+#define SDVO_CMD_GET_POSITION_V 0x6b
+#define SDVO_CMD_SET_POSITION_V 0x6c
+#define SDVO_CMD_GET_SHARPNESS 0x6e
+#define SDVO_CMD_SET_SHARPNESS 0x6f
+#define SDVO_CMD_GET_TV_CHROMA 0x75
+#define SDVO_CMD_SET_TV_CHROMA 0x76
+#define SDVO_CMD_GET_TV_LUMA 0x78
+#define SDVO_CMD_SET_TV_LUMA 0x79
+struct intel_sdvo_enhancements_arg {
+ u16 value;
+}__attribute__((packed));
+
+#define SDVO_CMD_GET_DOT_CRAWL 0x70
+#define SDVO_CMD_SET_DOT_CRAWL 0x71
+# define SDVO_DOT_CRAWL_ON (1 << 0)
+# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1)
+
+#define SDVO_CMD_GET_DITHER 0x72
+#define SDVO_CMD_SET_DITHER 0x73
+# define SDVO_DITHER_ON (1 << 0)
+# define SDVO_DITHER_DEFAULT_ON (1 << 1)
#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a
-# define SDVO_CONTROL_BUS_PROM 0x0
-# define SDVO_CONTROL_BUS_DDC1 0x1
-# define SDVO_CONTROL_BUS_DDC2 0x2
-# define SDVO_CONTROL_BUS_DDC3 0x3
+# define SDVO_CONTROL_BUS_PROM (1 << 0)
+# define SDVO_CONTROL_BUS_DDC1 (1 << 1)
+# define SDVO_CONTROL_BUS_DDC2 (1 << 2)
+# define SDVO_CONTROL_BUS_DDC3 (1 << 3)
+
+/* HDMI op codes */
+#define SDVO_CMD_GET_SUPP_ENCODE 0x9d
+#define SDVO_CMD_GET_ENCODE 0x9e
+#define SDVO_CMD_SET_ENCODE 0x9f
+ #define SDVO_ENCODE_DVI 0x0
+ #define SDVO_ENCODE_HDMI 0x1
+#define SDVO_CMD_SET_PIXEL_REPLI 0x8b
+#define SDVO_CMD_GET_PIXEL_REPLI 0x8c
+#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d
+#define SDVO_CMD_SET_COLORIMETRY 0x8e
+ #define SDVO_COLORIMETRY_RGB256 0x0
+ #define SDVO_COLORIMETRY_RGB220 0x1
+ #define SDVO_COLORIMETRY_YCrCb422 0x3
+ #define SDVO_COLORIMETRY_YCrCb444 0x4
+#define SDVO_CMD_GET_COLORIMETRY 0x8f
+#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90
+#define SDVO_CMD_SET_AUDIO_STAT 0x91
+#define SDVO_CMD_GET_AUDIO_STAT 0x92
+#define SDVO_CMD_SET_HBUF_INDEX 0x93
+#define SDVO_CMD_GET_HBUF_INDEX 0x94
+#define SDVO_CMD_GET_HBUF_INFO 0x95
+#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96
+#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97
+#define SDVO_CMD_SET_HBUF_DATA 0x98
+#define SDVO_CMD_GET_HBUF_DATA 0x99
+#define SDVO_CMD_SET_HBUF_TXRATE 0x9a
+#define SDVO_CMD_GET_HBUF_TXRATE 0x9b
+ #define SDVO_HBUF_TX_DISABLED (0 << 6)
+ #define SDVO_HBUF_TX_ONCE (2 << 6)
+ #define SDVO_HBUF_TX_VSYNC (3 << 6)
+#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c
+
+struct intel_sdvo_encode{
+ u8 dvi_rev;
+ u8 hdmi_rev;
+} __attribute__ ((packed));
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index fbb35dc56f5..56485d67369 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -411,7 +411,7 @@ struct tv_mode {
* These values account for -1s required.
*/
-const static struct tv_mode tv_modes[] = {
+static const struct tv_mode tv_modes[] = {
{
.name = "NTSC-M",
.clock = 107520,
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 63212d7bbc2..92965dbb3c1 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -557,8 +557,10 @@ static int radeon_do_engine_reset(struct drm_device * dev)
}
static void radeon_cp_init_ring_buffer(struct drm_device * dev,
- drm_radeon_private_t * dev_priv)
+ drm_radeon_private_t *dev_priv,
+ struct drm_file *file_priv)
{
+ struct drm_radeon_master_private *master_priv;
u32 ring_start, cur_read_ptr;
u32 tmp;
@@ -677,6 +679,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
dev_priv->scratch[2] = 0;
RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0);
+ /* reset sarea copies of these */
+ master_priv = file_priv->master->driver_priv;
+ if (master_priv->sarea_priv) {
+ master_priv->sarea_priv->last_frame = 0;
+ master_priv->sarea_priv->last_dispatch = 0;
+ master_priv->sarea_priv->last_clear = 0;
+ }
+
radeon_do_wait_for_idle(dev_priv);
/* Sync everything up */
@@ -1039,9 +1049,9 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
- drm_core_ioremap(dev_priv->cp_ring, dev);
- drm_core_ioremap(dev_priv->ring_rptr, dev);
- drm_core_ioremap(dev->agp_buffer_map, dev);
+ drm_core_ioremap_wc(dev_priv->cp_ring, dev);
+ drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
+ drm_core_ioremap_wc(dev->agp_buffer_map, dev);
if (!dev_priv->cp_ring->handle ||
!dev_priv->ring_rptr->handle ||
!dev->agp_buffer_map->handle) {
@@ -1215,7 +1225,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
}
radeon_cp_load_microcode(dev_priv);
- radeon_cp_init_ring_buffer(dev, dev_priv);
+ radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
dev_priv->last_buf = 0;
@@ -1281,7 +1291,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev)
*
* Charl P. Botha <http://cpbotha.net>
*/
-static int radeon_do_resume_cp(struct drm_device * dev)
+static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -1304,7 +1314,7 @@ static int radeon_do_resume_cp(struct drm_device * dev)
}
radeon_cp_load_microcode(dev_priv);
- radeon_cp_init_ring_buffer(dev, dev_priv);
+ radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
radeon_do_engine_reset(dev);
radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
@@ -1479,8 +1489,7 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri
*/
int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
-
- return radeon_do_resume_cp(dev);
+ return radeon_do_resume_cp(dev, file_priv);
}
int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5d7640e49dc..1cc967448f4 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1218,6 +1218,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
}
EXPORT_SYMBOL_GPL(hid_connect);
+/* a list of devices for which there is a specialized driver on HID bus */
static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
@@ -1299,7 +1300,13 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
@@ -1476,6 +1483,7 @@ static struct bus_type hid_bus_type = {
.uevent = hid_uevent,
};
+/* a list of devices that shouldn't be handled by HID core at all */
static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) },
@@ -1603,15 +1611,14 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
@@ -1622,8 +1629,6 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
{ HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
{ }
};
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index acc1abc834a..88511970508 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -348,6 +348,9 @@
#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
+#define USB_VENDOR_ID_POWERCOM 0x0d9f
+#define USB_DEVICE_ID_POWERCOM_UPS 0x0002
+
#define USB_VENDOR_ID_SAITEK 0x06a3
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
@@ -362,6 +365,8 @@
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4 0x0044
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5 0x0045
#define USB_VENDOR_ID_SUN 0x0430
#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index d718b1607d0..25b10dcad90 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -30,7 +30,7 @@
#define MS_NOGET 0x10
/*
- * Microsoft Wireless Desktop Receiver (Model 1028) has several
+ * Microsoft Wireless Desktop Receiver (Model 1028) has
* 'Usage Min/Max' where it ought to have 'Physical Min/Max'
*/
static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -38,17 +38,12 @@ static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
{
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
- if ((quirks & MS_RDESC) && rsize == 571 && rdesc[284] == 0x19 &&
- rdesc[286] == 0x2a && rdesc[304] == 0x19 &&
- rdesc[306] == 0x29 && rdesc[352] == 0x1a &&
- rdesc[355] == 0x2a && rdesc[557] == 0x19 &&
+ if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 &&
rdesc[559] == 0x29) {
dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver "
"Model 1028 report descriptor\n");
- rdesc[284] = rdesc[304] = rdesc[557] = 0x35;
- rdesc[352] = 0x36;
- rdesc[286] = rdesc[355] = 0x46;
- rdesc[306] = rdesc[559] = 0x45;
+ rdesc[557] = 0x35;
+ rdesc[559] = 0x45;
}
}
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 73244962897..02b19db5442 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -267,8 +267,10 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
default:
{
struct hid_device *hid = dev->hid;
- if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
- return -EINVAL;
+ if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) {
+ ret = -EINVAL;
+ break;
+ }
if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
int len;
@@ -277,8 +279,9 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
len = strlen(hid->name) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- return copy_to_user(user_arg, hid->name, len) ?
+ ret = copy_to_user(user_arg, hid->name, len) ?
-EFAULT : len;
+ break;
}
if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
@@ -288,12 +291,13 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
len = strlen(hid->phys) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- return copy_to_user(user_arg, hid->phys, len) ?
+ ret = copy_to_user(user_arg, hid->phys, len) ?
-EFAULT : len;
+ break;
}
}
- ret = -ENOTTY;
+ ret = -ENOTTY;
}
unlock_kernel();
return ret;
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index d73eea382ab..aa214170baf 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -227,12 +227,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
*/
static int hiddev_fasync(int fd, struct file *file, int on)
{
- int retval;
struct hiddev_list *list = file->private_data;
- retval = fasync_helper(fd, file, on, &list->fasync);
-
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &list->fasync);
}
@@ -306,7 +303,7 @@ static int hiddev_open(struct inode *inode, struct file *file)
return 0;
bail:
file->private_data = NULL;
- kfree(list->hiddev);
+ kfree(list);
return res;
}
@@ -323,7 +320,7 @@ static ssize_t hiddev_write(struct file * file, const char __user * buffer, size
*/
static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
{
- DECLARE_WAITQUEUE(wait, current);
+ DEFINE_WAIT(wait);
struct hiddev_list *list = file->private_data;
int event_size;
int retval;
@@ -656,7 +653,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case HIDIOCGSTRING:
mutex_lock(&hiddev->existancelock);
- if (!hiddev->exist)
+ if (hiddev->exist)
r = hiddev_ioctl_string(hiddev, cmd, user_arg);
else
r = -ENODEV;
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index b84bf066879..b4eea0292c1 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -543,8 +543,8 @@ config SENSORS_LM90
help
If you say yes here you get support for National Semiconductor LM90,
LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim
- MAX6646, MAX6647, MAX6649, MAX6657, MAX6658, MAX6659, MAX6680 and
- MAX6681 sensor chips.
+ MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659,
+ MAX6680, MAX6681 and MAX6692 sensor chips.
This driver can also be built as a module. If so, the module
will be called lm90.
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index e52b38806d0..ad2b3431b72 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -760,8 +760,11 @@ static int abituguru3_read_increment_offset(struct abituguru3_data *data,
for (i = 0; i < offset_count; i++)
if ((x = abituguru3_read(data, bank, offset + i, count,
- buf + i * count)) != count)
- return i * count + (i && (x < 0)) ? 0 : x;
+ buf + i * count)) != count) {
+ if (x < 0)
+ return x;
+ return i * count + x;
+ }
return i * count;
}
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index e3018623658..678e34b01e5 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -83,7 +83,7 @@
/*
* Temperature sensors keys (sp78 - 2 bytes).
*/
-static const char* temperature_sensors_sets[][36] = {
+static const char *temperature_sensors_sets[][41] = {
/* Set 0: Macbook Pro */
{ "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
"Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
@@ -135,6 +135,13 @@ static const char* temperature_sensors_sets[][36] = {
{ "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0",
"TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P",
"Ts0S", NULL },
+/* Set 16: Mac Pro 3,1 (2 x Quad-Core) */
+ { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
+ "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "TH0P", "TH1P",
+ "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", "TM1P",
+ "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
+ "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
+ NULL },
};
/* List of keys used to read/write fan speeds */
@@ -1153,6 +1160,16 @@ static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
applesmc_show_temperature, NULL, 33);
static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
applesmc_show_temperature, NULL, 34);
+static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 35);
+static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 36);
+static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 37);
+static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 38);
+static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 39);
static struct attribute *temperature_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -1190,6 +1207,11 @@ static struct attribute *temperature_attributes[] = {
&sensor_dev_attr_temp33_input.dev_attr.attr,
&sensor_dev_attr_temp34_input.dev_attr.attr,
&sensor_dev_attr_temp35_input.dev_attr.attr,
+ &sensor_dev_attr_temp36_input.dev_attr.attr,
+ &sensor_dev_attr_temp37_input.dev_attr.attr,
+ &sensor_dev_attr_temp38_input.dev_attr.attr,
+ &sensor_dev_attr_temp39_input.dev_attr.attr,
+ &sensor_dev_attr_temp40_input.dev_attr.attr,
NULL
};
@@ -1312,6 +1334,8 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
{ .accelerometer = 0, .light = 0, .temperature_set = 14 },
/* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
{ .accelerometer = 1, .light = 1, .temperature_set = 15 },
+/* MacPro3,1: temperature set 16 */
+ { .accelerometer = 0, .light = 0, .temperature_set = 16 },
};
/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1369,6 +1393,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
&applesmc_dmi_data[4]},
+ { applesmc_dmi_match, "Apple MacPro3", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
+ &applesmc_dmi_data[16]},
{ applesmc_dmi_match, "Apple MacPro", {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 609cafff86b..5f81ddf7150 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -1872,7 +1872,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
devid = superio_inw(sioaddr, SIO_REG_MANID);
if (devid != SIO_FINTEK_ID) {
- printk(KERN_INFO DRVNAME ": Not a Fintek device\n");
+ pr_debug(DRVNAME ": Not a Fintek device\n");
goto exit;
}
@@ -1932,7 +1932,7 @@ static int __init f71882fg_device_add(unsigned short address,
res.name = f71882fg_pdev->name;
err = acpi_check_resource_conflict(&res);
if (err)
- return err;
+ goto exit_device_put;
err = platform_device_add_resources(f71882fg_pdev, &res, 1);
if (err) {
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 1692de36996..18a1ba88816 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -617,7 +617,7 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
static int f75375_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct f75375_data *data = i2c_get_clientdata(client);
+ struct f75375_data *data;
struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
int err;
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 03705240000..29c83b5b969 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -153,7 +153,10 @@ static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3};
static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3};
static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3};
static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3};
static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_rotated_right = {2, -1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3};
#define AXIS_DMI_MATCH(_ident, _name, _axis) { \
.ident = _ident, \
@@ -163,6 +166,18 @@ static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3};
}, \
.driver_data = &lis3lv02d_axis_##_axis \
}
+
+#define AXIS_DMI_MATCH2(_ident, _class1, _name1, \
+ _class2, _name2, \
+ _axis) { \
+ .ident = _ident, \
+ .callback = lis3lv02d_dmi_matched, \
+ .matches = { \
+ DMI_MATCH(DMI_##_class1, _name1), \
+ DMI_MATCH(DMI_##_class2, _name2), \
+ }, \
+ .driver_data = &lis3lv02d_axis_##_axis \
+}
static struct dmi_system_id lis3lv02d_dmi_ids[] = {
/* product names are truncated to match all kinds of a same model */
AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted),
@@ -172,10 +187,22 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
+ AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
+ AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
+ AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
+ AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted),
+ /* Intel-based HP Pavilion dv5 */
+ AXIS_DMI_MATCH2("HPDV5_I",
+ PRODUCT_NAME, "HP Pavilion dv5",
+ BOARD_NAME, "3603",
+ x_inverted),
+ /* AMD-based HP Pavilion dv5 */
+ AXIS_DMI_MATCH2("HPDV5_A",
+ PRODUCT_NAME, "HP Pavilion dv5",
+ BOARD_NAME, "3600",
+ y_inverted),
{ NULL, }
/* Laptop models without axis info (yet):
- * "NC651xx" "HP Compaq 651"
- * "NC671xx" "HP Compaq 671"
* "NC6910" "HP Compaq 6910"
* HP Compaq 8710x Notebook PC / Mobile Workstation
* "NC2400" "HP Compaq nc2400"
@@ -208,9 +235,49 @@ static struct delayed_led_classdev hpled_led = {
.set_brightness = hpled_set,
};
+static acpi_status
+lis3lv02d_get_resource(struct acpi_resource *resource, void *context)
+{
+ if (resource->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
+ struct acpi_resource_extended_irq *irq;
+ u32 *device_irq = context;
+
+ irq = &resource->data.extended_irq;
+ *device_irq = irq->interrupts[0];
+ }
+
+ return AE_OK;
+}
+
+static void lis3lv02d_enum_resources(struct acpi_device *device)
+{
+ acpi_status status;
+
+ status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+ lis3lv02d_get_resource, &adev.irq);
+ if (ACPI_FAILURE(status))
+ printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
+}
+
+static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
+{
+ u8 lo, hi;
+
+ adev.read(handle, reg - 1, &lo);
+ adev.read(handle, reg, &hi);
+ /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
+ return (s16)((hi << 8) | lo);
+}
+
+static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
+{
+ s8 lo;
+ adev.read(handle, reg, &lo);
+ return lo;
+}
+
static int lis3lv02d_add(struct acpi_device *device)
{
- u8 val;
int ret;
if (!device)
@@ -224,10 +291,22 @@ static int lis3lv02d_add(struct acpi_device *device)
strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
device->driver_data = &adev;
- lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val);
- if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) {
+ lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami);
+ switch (adev.whoami) {
+ case LIS_DOUBLE_ID:
+ printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
+ adev.read_data = lis3lv02d_read_16;
+ adev.mdps_max_val = 2048;
+ break;
+ case LIS_SINGLE_ID:
+ printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
+ adev.read_data = lis3lv02d_read_8;
+ adev.mdps_max_val = 128;
+ break;
+ default:
printk(KERN_ERR DRIVER_NAME
- ": Accelerometer chip not LIS3LV02D{L,Q}\n");
+ ": unknown sensor type 0x%X\n", adev.whoami);
+ return -EINVAL;
}
/* If possible use a "standard" axes order */
@@ -242,6 +321,9 @@ static int lis3lv02d_add(struct acpi_device *device)
if (ret)
return ret;
+ /* obtain IRQ number of our device from ACPI */
+ lis3lv02d_enum_resources(adev.device);
+
ret = lis3lv02d_init_device(&adev);
if (ret) {
flush_work(&hpled_led.work);
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 95a99c590da..9157247fed8 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -213,7 +213,7 @@ static inline u16 FAN16_TO_REG(long rpm)
#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\
((val)+500)/1000),-128,127))
-#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000)
+#define TEMP_FROM_REG(val) ((val) * 1000)
#define PWM_TO_REG(val) ((val) >> 1)
#define PWM_FROM_REG(val) (((val)&0x7f) << 1)
@@ -267,9 +267,9 @@ struct it87_data {
u8 has_fan; /* Bitfield, fans enabled */
u16 fan[5]; /* Register values, possibly combined */
u16 fan_min[5]; /* Register values, possibly combined */
- u8 temp[3]; /* Register value */
- u8 temp_high[3]; /* Register value */
- u8 temp_low[3]; /* Register value */
+ s8 temp[3]; /* Register value */
+ s8 temp_high[3]; /* Register value */
+ s8 temp_low[3]; /* Register value */
u8 sensor; /* Register value */
u8 fan_div[3]; /* Register encoding, shifted right */
u8 vid; /* Register encoding, combined */
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 219d2d0d5a6..8bb2158f045 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2007-2008 Yan Burman
* Copyright (C) 2008 Eric Piel
- * Copyright (C) 2008 Pavel Machek
+ * Copyright (C) 2008-2009 Pavel Machek
*
* 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
@@ -35,6 +35,7 @@
#include <linux/poll.h>
#include <linux/freezer.h>
#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
#include <acpi/acpi_drivers.h>
#include <asm/atomic.h>
#include "lis3lv02d.h"
@@ -52,24 +53,14 @@
* joystick.
*/
-/* Maximum value our axis may get for the input device (signed 12 bits) */
-#define MDPS_MAX_VAL 2048
+struct acpi_lis3lv02d adev = {
+ .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
+};
-struct acpi_lis3lv02d adev;
EXPORT_SYMBOL_GPL(adev);
static int lis3lv02d_add_fs(struct acpi_device *device);
-static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
-{
- u8 lo, hi;
-
- adev.read(handle, reg, &lo);
- adev.read(handle, reg + 1, &hi);
- /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
- return (s16)((hi << 8) | lo);
-}
-
/**
* lis3lv02d_get_axis - For the given axis, give the value converted
* @axis: 1,2,3 - can also be negative
@@ -98,9 +89,9 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
{
int position[3];
- position[0] = lis3lv02d_read_16(handle, OUTX_L);
- position[1] = lis3lv02d_read_16(handle, OUTY_L);
- position[2] = lis3lv02d_read_16(handle, OUTZ_L);
+ position[0] = adev.read_data(handle, OUTX);
+ position[1] = adev.read_data(handle, OUTY);
+ position[2] = adev.read_data(handle, OUTZ);
*x = lis3lv02d_get_axis(adev.ac.x, position);
*y = lis3lv02d_get_axis(adev.ac.y, position);
@@ -110,26 +101,13 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
void lis3lv02d_poweroff(acpi_handle handle)
{
adev.is_on = 0;
- /* disable X,Y,Z axis and power down */
- adev.write(handle, CTRL_REG1, 0x00);
}
EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
void lis3lv02d_poweron(acpi_handle handle)
{
- u8 val;
-
adev.is_on = 1;
adev.init(handle);
- adev.write(handle, FF_WU_CFG, 0);
- /*
- * BDU: LSB and MSB values are not updated until both have been read.
- * So the value read will always be correct.
- * IEN: Interrupt for free-fall and DD, not for data-ready.
- */
- adev.read(handle, CTRL_REG2, &val);
- val |= CTRL2_BDU | CTRL2_IEN;
- adev.write(handle, CTRL_REG2, val);
}
EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
@@ -162,6 +140,140 @@ static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev)
mutex_unlock(&dev->lock);
}
+static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
+{
+ /*
+ * Be careful: on some HP laptops the bios force DD when on battery and
+ * the lid is closed. This leads to interrupts as soon as a little move
+ * is done.
+ */
+ atomic_inc(&adev.count);
+
+ wake_up_interruptible(&adev.misc_wait);
+ kill_fasync(&adev.async_queue, SIGIO, POLL_IN);
+ return IRQ_HANDLED;
+}
+
+static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ if (test_and_set_bit(0, &adev.misc_opened))
+ return -EBUSY; /* already open */
+
+ atomic_set(&adev.count, 0);
+
+ /*
+ * The sensor can generate interrupts for free-fall and direction
+ * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep
+ * the things simple and _fast_ we activate it only for free-fall, so
+ * no need to read register (very slow with ACPI). For the same reason,
+ * we forbid shared interrupts.
+ *
+ * IRQF_TRIGGER_RISING seems pointless on HP laptops because the
+ * io-apic is not configurable (and generates a warning) but I keep it
+ * in case of support for other hardware.
+ */
+ ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
+ DRIVER_NAME, &adev);
+
+ if (ret) {
+ clear_bit(0, &adev.misc_opened);
+ printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq);
+ return -EBUSY;
+ }
+ lis3lv02d_increase_use(&adev);
+ printk("lis3: registered interrupt %d\n", adev.irq);
+ return 0;
+}
+
+static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
+{
+ fasync_helper(-1, file, 0, &adev.async_queue);
+ lis3lv02d_decrease_use(&adev);
+ free_irq(adev.irq, &adev);
+ clear_bit(0, &adev.misc_opened); /* release the device */
+ return 0;
+}
+
+static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ u32 data;
+ unsigned char byte_data;
+ ssize_t retval = 1;
+
+ if (count < 1)
+ return -EINVAL;
+
+ add_wait_queue(&adev.misc_wait, &wait);
+ while (true) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ data = atomic_xchg(&adev.count, 0);
+ if (data)
+ break;
+
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto out;
+ }
+
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ goto out;
+ }
+
+ schedule();
+ }
+
+ if (data < 255)
+ byte_data = data;
+ else
+ byte_data = 255;
+
+ /* make sure we are not going into copy_to_user() with
+ * TASK_INTERRUPTIBLE state */
+ set_current_state(TASK_RUNNING);
+ if (copy_to_user(buf, &byte_data, sizeof(byte_data)))
+ retval = -EFAULT;
+
+out:
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&adev.misc_wait, &wait);
+
+ return retval;
+}
+
+static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
+{
+ poll_wait(file, &adev.misc_wait, wait);
+ if (atomic_read(&adev.count))
+ return POLLIN | POLLRDNORM;
+ return 0;
+}
+
+static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
+{
+ return fasync_helper(fd, file, on, &adev.async_queue);
+}
+
+static const struct file_operations lis3lv02d_misc_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .read = lis3lv02d_misc_read,
+ .open = lis3lv02d_misc_open,
+ .release = lis3lv02d_misc_release,
+ .poll = lis3lv02d_misc_poll,
+ .fasync = lis3lv02d_misc_fasync,
+};
+
+static struct miscdevice lis3lv02d_misc_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "freefall",
+ .fops = &lis3lv02d_misc_fops,
+};
+
/**
* lis3lv02d_joystick_kthread - Kthread polling function
* @data: unused - here to conform to threadfn prototype
@@ -203,7 +315,6 @@ static void lis3lv02d_joystick_close(struct input_dev *input)
lis3lv02d_decrease_use(&adev);
}
-
static inline void lis3lv02d_calibrate_joystick(void)
{
lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib);
@@ -231,9 +342,9 @@ int lis3lv02d_joystick_enable(void)
adev.idev->close = lis3lv02d_joystick_close;
set_bit(EV_ABS, adev.idev->evbit);
- input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
- input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
- input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
+ input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+ input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+ input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
err = input_register_device(adev.idev);
if (err) {
@@ -250,6 +361,7 @@ void lis3lv02d_joystick_disable(void)
if (!adev.idev)
return;
+ misc_deregister(&lis3lv02d_misc_device);
input_unregister_device(adev.idev);
adev.idev = NULL;
}
@@ -268,6 +380,19 @@ int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
if (lis3lv02d_joystick_enable())
printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
+ printk("lis3_init_device: irq %d\n", dev->irq);
+
+ /* if we did not get an IRQ from ACPI - we have nothing more to do */
+ if (!dev->irq) {
+ printk(KERN_ERR DRIVER_NAME
+ ": No IRQ in ACPI. Disabling /dev/freefall\n");
+ goto out;
+ }
+
+ printk("lis3: registering device\n");
+ if (misc_register(&lis3lv02d_misc_device))
+ printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
+out:
lis3lv02d_decrease_use(dev);
return 0;
}
@@ -351,6 +476,6 @@ int lis3lv02d_remove_fs(void)
EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
-MODULE_AUTHOR("Yan Burman and Eric Piel");
+MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 223f1c0763b..75972bf372f 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -22,12 +22,15 @@
/*
* The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to
* be connected via SPI. There exists also several similar chips (such as LIS302DL or
- * LIS3L02DQ) but not in the HP laptops and they have slightly different registers.
+ * LIS3L02DQ) and they have slightly different registers, but we can provide a
+ * common interface for all of them.
* They can also be connected via I²C.
*/
-#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */
-#define LIS302DL_ID 0x3B /* Also the LIS202DL! */
+/* 2-byte registers */
+#define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */
+/* 1-byte registers */
+#define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */
enum lis3lv02d_reg {
WHO_AM_I = 0x0F,
@@ -44,10 +47,13 @@ enum lis3lv02d_reg {
STATUS_REG = 0x27,
OUTX_L = 0x28,
OUTX_H = 0x29,
+ OUTX = 0x29,
OUTY_L = 0x2A,
OUTY_H = 0x2B,
+ OUTY = 0x2B,
OUTZ_L = 0x2C,
OUTZ_H = 0x2D,
+ OUTZ = 0x2D,
FF_WU_CFG = 0x30,
FF_WU_SRC = 0x31,
FF_WU_ACK = 0x32,
@@ -159,6 +165,10 @@ struct acpi_lis3lv02d {
acpi_status (*write) (acpi_handle handle, int reg, u8 val);
acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
+ u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
+ s16 (*read_data) (acpi_handle handle, int reg);
+ int mdps_max_val;
+
struct input_dev *idev; /* input device */
struct task_struct *kthread; /* kthread for input */
struct mutex lock;
@@ -170,6 +180,11 @@ struct acpi_lis3lv02d {
unsigned char is_on; /* whether the device is on or off */
unsigned char usage; /* usage counter */
struct axis_conversion ac; /* hw -> logical axis */
+
+ u32 irq; /* IRQ number */
+ struct fasync_struct *async_queue; /* queue for the misc device */
+ wait_queue_head_t misc_wait; /* Wait queue for the misc device */
+ unsigned long misc_opened; /* bit0: whether the device is open */
};
int lis3lv02d_init_device(struct acpi_lis3lv02d *dev);
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index cfc1ee90f5a..b251d8674b4 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -72,6 +72,7 @@ I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100,
#define LM85_COMPANY_SMSC 0x5c
#define LM85_VERSTEP_VMASK 0xf0
#define LM85_VERSTEP_GENERIC 0x60
+#define LM85_VERSTEP_GENERIC2 0x70
#define LM85_VERSTEP_LM85C 0x60
#define LM85_VERSTEP_LM85B 0x62
#define LM85_VERSTEP_ADM1027 0x60
@@ -334,6 +335,7 @@ static struct lm85_data *lm85_update_device(struct device *dev);
static const struct i2c_device_id lm85_id[] = {
{ "adm1027", adm1027 },
{ "adt7463", adt7463 },
+ { "adt7468", adt7468 },
{ "lm85", any_chip },
{ "lm85b", lm85b },
{ "lm85c", lm85c },
@@ -408,7 +410,8 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
struct lm85_data *data = lm85_update_device(dev);
int vid;
- if (data->type == adt7463 && (data->vid & 0x80)) {
+ if ((data->type == adt7463 || data->type == adt7468) &&
+ (data->vid & 0x80)) {
/* 6-pin VID (VRM 10) */
vid = vid_from_reg(data->vid & 0x3f, data->vrm);
} else {
@@ -1153,7 +1156,8 @@ static int lm85_detect(struct i2c_client *client, int kind,
address, company, verstep);
/* All supported chips have the version in common */
- if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC) {
+ if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC &&
+ (verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC2) {
dev_dbg(&adapter->dev, "Autodetection failed: "
"unsupported version\n");
return -ENODEV;
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 96a70186672..1aff7575799 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -32,10 +32,10 @@
* supported by this driver. These chips lack the remote temperature
* offset feature.
*
- * This driver also supports the MAX6646, MAX6647 and MAX6649 chips
- * made by Maxim. These are again similar to the LM86, but they use
- * unsigned temperature values and can report temperatures from 0 to
- * 145 degrees.
+ * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and
+ * MAX6692 chips made by Maxim. These are again similar to the LM86,
+ * but they use unsigned temperature values and can report temperatures
+ * from 0 to 145 degrees.
*
* This driver also supports the MAX6680 and MAX6681, two other sensor
* chips made by Maxim. These are quite similar to the other Maxim
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index b0ce3785228..73f77a9b8b1 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -1262,7 +1262,7 @@ static int __init vt1211_device_add(unsigned short address)
res.name = pdev->name;
err = acpi_check_resource_conflict(&res);
if (err)
- goto EXIT;
+ goto EXIT_DEV_PUT;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index cb808d01536..feae743ba99 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -1548,7 +1548,7 @@ static int __init sensors_w83627ehf_init(void)
err = acpi_check_resource_conflict(&res);
if (err)
- goto exit;
+ goto exit_device_put;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c
index 75089febbc1..9aefb5e5864 100644
--- a/drivers/i2c/busses/i2c-acorn.c
+++ b/drivers/i2c/busses/i2c-acorn.c
@@ -79,11 +79,11 @@ static struct i2c_algo_bit_data ioc_data = {
.getsda = ioc_getsda,
.getscl = ioc_getscl,
.udelay = 80,
- .timeout = 100
+ .timeout = HZ,
};
static struct i2c_adapter ioc_ops = {
- .id = I2C_HW_B_IOC,
+ .nr = 0,
.algo_data = &ioc_data,
};
@@ -91,7 +91,7 @@ static int __init i2c_ioc_init(void)
{
force_ones = FORCE_ONES | SCL | SDA;
- return i2c_bit_add_bus(&ioc_ops);
+ return i2c_bit_add_numbered_bus(&ioc_ops);
}
module_init(i2c_ioc_init);
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index 9cead9b9458..981e080b32a 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -476,7 +476,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter ali1535_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_ALI1535,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index dd9e796fad6..f70f46582c6 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -386,7 +386,6 @@ static const struct i2c_algorithm ali1563_algorithm = {
static struct i2c_adapter ali1563_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_ALI1563,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &ali1563_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index 234fdde7d40..39066dee46e 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -473,7 +473,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter ali15x3_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_ALI15X3,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index 36bee5b9c95..220f4a1eee1 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -298,7 +298,6 @@ static const struct i2c_algorithm smbus_algorithm = {
struct i2c_adapter amd756_smbus = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_AMD756,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index 3972208876b..a7c59908c45 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -72,7 +72,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
{
int timeout = 500;
- while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF))
+ while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout)
udelay(1);
if (!timeout) {
@@ -88,7 +88,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
{
int timeout = 500;
- while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF))
+ while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout)
udelay(1);
if (!timeout) {
@@ -387,7 +387,6 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
smbus->adapter.owner = THIS_MODULE;
snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"SMBus2 AMD8111 adapter at %04x", smbus->base);
- smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index 66a04c2c660..f78ce523e3d 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -400,7 +400,6 @@ i2c_au1550_probe(struct platform_device *pdev)
priv->xfer_timeout = 200;
priv->ack_timeout = 200;
- priv->adap.id = I2C_HW_AU1550_PSC;
priv->adap.nr = pdev->id;
priv->adap.algo = &au1550_algo;
priv->adap.algo_data = priv;
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index 3fd2c417c1e..fc548b3d002 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -651,7 +651,6 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
iface->timeout_timer.data = (unsigned long)iface;
p_adap = &iface->adap;
- p_adap->id = I2C_HW_BLACKFIN;
p_adap->nr = pdev->id;
strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
p_adap->algo = &bfin_twi_algorithm;
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
index 0ed3ccb81b6..448b4bf35eb 100644
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -202,7 +202,6 @@ static struct i2c_algo_pcf_data pcf_isa_data = {
static struct i2c_adapter pcf_isa_ops = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .id = I2C_HW_P_ELEK,
.algo_data = &pcf_isa_data,
.name = "i2c-elektor",
};
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
index 648aa7baff8..bec9b845dd1 100644
--- a/drivers/i2c/busses/i2c-hydra.c
+++ b/drivers/i2c/busses/i2c-hydra.c
@@ -102,7 +102,6 @@ static struct i2c_algo_bit_data hydra_bit_data = {
static struct i2c_adapter hydra_adap = {
.owner = THIS_MODULE,
.name = "Hydra i2c",
- .id = I2C_HW_B_HYDRA,
.algo_data = &hydra_bit_data,
};
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 526625eaa84..230238df56c 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -556,7 +556,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter i801_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_I801,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 651f2f1ae5b..88f0db73b36 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -746,7 +746,6 @@ static int __devinit iic_probe(struct of_device *ofdev,
adap->dev.parent = &ofdev->dev;
strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
i2c_set_adapdata(adap, dev);
- adap->id = I2C_HW_OCP;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo = &iic_algo;
adap->timeout = 1;
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index fc2714ac0c0..3190690c26c 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -480,7 +480,6 @@ iop3xx_i2c_probe(struct platform_device *pdev)
}
memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
- new_adapter->id = I2C_HW_IOP3XX;
new_adapter->owner = THIS_MODULE;
new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
new_adapter->dev.parent = &pdev->dev;
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index 05d72e98135..c016f7a2c5f 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -114,9 +114,8 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.getsda = ixp2000_bit_getsda;
drv_data->algo_data.getscl = ixp2000_bit_getscl;
drv_data->algo_data.udelay = 6;
- drv_data->algo_data.timeout = 100;
+ drv_data->algo_data.timeout = HZ;
- drv_data->adapter.id = I2C_HW_B_IXP2000,
strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
sizeof(drv_data->adapter.name));
drv_data->adapter.algo_data = &drv_data->algo_data,
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index a9a45fcc854..aedbbe6618d 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -310,7 +310,6 @@ static const struct i2c_algorithm mpc_algo = {
static struct i2c_adapter mpc_ops = {
.owner = THIS_MODULE,
.name = "MPC adapter",
- .id = I2C_HW_MPC107,
.algo = &mpc_algo,
.timeout = 1,
};
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 9e8118d2fe6..7f186bbcb99 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -482,7 +482,7 @@ mv64xxx_i2c_map_regs(struct platform_device *pd,
return 0;
}
-static void __devexit
+static void
mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data)
{
if (drv_data->reg_base) {
@@ -527,7 +527,6 @@ mv64xxx_i2c_probe(struct platform_device *pd)
goto exit_unmap_regs;
}
drv_data->adapter.dev.parent = &pd->dev;
- drv_data->adapter.id = I2C_HW_MV64XXX;
drv_data->adapter.algo = &mv64xxx_i2c_algo;
drv_data->adapter.owner = THIS_MODULE;
drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
@@ -578,7 +577,7 @@ mv64xxx_i2c_remove(struct platform_device *dev)
static struct platform_driver mv64xxx_i2c_driver = {
.probe = mv64xxx_i2c_probe,
- .remove = mv64xxx_i2c_remove,
+ .remove = __devexit_p(mv64xxx_i2c_remove),
.driver = {
.owner = THIS_MODULE,
.name = MV64XXX_I2C_CTLR_NAME,
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 3b19bc41a60..05af6cd7f27 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -355,7 +355,6 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
return -EBUSY;
}
smbus->adapter.owner = THIS_MODULE;
- smbus->adapter.id = I2C_HW_SMBUS_NFORCE2;
smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
index b2b8380f660..322c5691e38 100644
--- a/drivers/i2c/busses/i2c-parport-light.c
+++ b/drivers/i2c/busses/i2c-parport-light.c
@@ -115,7 +115,6 @@ static struct i2c_algo_bit_data parport_algo_data = {
static struct i2c_adapter parport_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
- .id = I2C_HW_B_LP,
.algo_data = &parport_algo_data,
.name = "Parallel port adapter (light)",
};
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index a257cd5cd13..0d8998610c7 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -164,7 +164,6 @@ static void i2c_parport_attach (struct parport *port)
/* Fill the rest of the structure */
adapter->adapter.owner = THIS_MODULE;
adapter->adapter.class = I2C_CLASS_HWMON;
- adapter->adapter.id = I2C_HW_B_LP;
strlcpy(adapter->adapter.name, "Parallel port adapter",
sizeof(adapter->adapter.name));
adapter->algo_data = parport_algo_data;
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
index 9eb76268ec7..4aa8138cb0a 100644
--- a/drivers/i2c/busses/i2c-pca-isa.c
+++ b/drivers/i2c/busses/i2c-pca-isa.c
@@ -101,7 +101,6 @@ static struct i2c_algo_pca_data pca_isa_data = {
static struct i2c_adapter pca_isa_ops = {
.owner = THIS_MODULE,
- .id = I2C_HW_A_ISA,
.algo_data = &pca_isa_data,
.name = "PCA9564 ISA Adapter",
.timeout = 100,
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index eaa9b387543..761f9dd5362 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -403,7 +403,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter piix4_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_PIIX4,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 6af68146c34..bdb1f7510e9 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -644,7 +644,7 @@ static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
i2c_pxa_start_message(i2c);
- while (timeout-- && i2c->msg_num > 0) {
+ while (i2c->msg_num > 0 && --timeout) {
i2c_pxa_handler(0, i2c);
udelay(10);
}
diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c
index 4ddefbf238e..98b1ec48915 100644
--- a/drivers/i2c/busses/i2c-sibyte.c
+++ b/drivers/i2c/busses/i2c-sibyte.c
@@ -155,7 +155,6 @@ static struct i2c_algo_sibyte_data sibyte_board_data[2] = {
static struct i2c_adapter sibyte_board_adapter[2] = {
{
.owner = THIS_MODULE,
- .id = I2C_HW_SIBYTE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = NULL,
.algo_data = &sibyte_board_data[0],
@@ -164,7 +163,6 @@ static struct i2c_adapter sibyte_board_adapter[2] = {
},
{
.owner = THIS_MODULE,
- .id = I2C_HW_SIBYTE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = NULL,
.algo_data = &sibyte_board_data[1],
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 8ce2daff985..f320ab27da4 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -365,7 +365,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis5595_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_SIS5595,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index 9c9c016ff2b..50c3610e602 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -464,7 +464,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis630_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_SIS630,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index f1bba639664..7e1594b4057 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -241,7 +241,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis96x_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_SIS96X,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 29cef0433f3..8b24f192103 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -83,7 +83,6 @@ static struct i2c_algo_bit_data bit_data = {
static struct i2c_adapter vt586b_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_B_VIA,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.name = "VIA i2c",
.algo_data = &bit_data,
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 9f194d9efd9..02e6f724b05 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -321,7 +321,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter vt596_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_VIA2,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
index 1d4ae26ba73..1a474acc0dd 100644
--- a/drivers/i2c/busses/i2c-voodoo3.c
+++ b/drivers/i2c/busses/i2c-voodoo3.c
@@ -163,7 +163,6 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = {
static struct i2c_adapter voodoo3_i2c_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_B_VOO,
.class = I2C_CLASS_TV_ANALOG,
.name = "I2C Voodoo3/Banshee adapter",
.algo_data = &voo_i2c_bit_data,
@@ -180,7 +179,6 @@ static struct i2c_algo_bit_data voo_ddc_bit_data = {
static struct i2c_adapter voodoo3_ddc_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_B_VOO,
.class = I2C_CLASS_DDC,
.name = "DDC Voodoo3/Banshee adapter",
.algo_data = &voo_ddc_bit_data,
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index ed794b145a1..648ecc6f60e 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -440,7 +440,6 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
i2c_set_adapdata(adapter, iface);
snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
adapter->owner = THIS_MODULE;
- adapter->id = I2C_HW_SMBUS_SCX200;
adapter->algo = &scx200_acb_algorithm;
adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adapter->dev.parent = dev;
diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
index e4c98539c51..42df0eca43d 100644
--- a/drivers/i2c/busses/scx200_i2c.c
+++ b/drivers/i2c/busses/scx200_i2c.c
@@ -76,13 +76,12 @@ static struct i2c_algo_bit_data scx200_i2c_data = {
.getsda = scx200_i2c_getsda,
.getscl = scx200_i2c_getscl,
.udelay = 10,
- .timeout = 100,
+ .timeout = HZ,
};
static struct i2c_adapter scx200_i2c_ops = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .id = I2C_HW_B_SCX200,
.algo_data = &scx200_i2c_data,
.name = "NatSemi SCx200 I2C",
};
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index b9bef04b7be..c80312c1f38 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -16,43 +16,6 @@ config DS1682
This driver can also be built as a module. If so, the module
will be called ds1682.
-config AT24
- tristate "EEPROMs from most vendors"
- depends on SYSFS && EXPERIMENTAL
- help
- Enable this driver to get read/write support to most I2C EEPROMs,
- after you configure the driver to know about each EEPROM on
- your target board. Use these generic chip names, instead of
- vendor-specific ones like at24c64 or 24lc02:
-
- 24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08,
- 24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024
-
- Unless you like data loss puzzles, always be sure that any chip
- you configure as a 24c32 (32 kbit) or larger is NOT really a
- 24c16 (16 kbit) or smaller, and vice versa. Marking the chip
- as read-only won't help recover from this. Also, if your chip
- has any software write-protect mechanism you may want to review the
- code to make sure this driver won't turn it on by accident.
-
- If you use this with an SMBus adapter instead of an I2C adapter,
- full functionality is not available. Only smaller devices are
- supported (24c16 and below, max 4 kByte).
-
- This driver can also be built as a module. If so, the module
- will be called at24.
-
-config SENSORS_EEPROM
- tristate "EEPROM reader"
- depends on EXPERIMENTAL
- help
- If you say yes here you get read-only access to the EEPROM data
- available on modern memory DIMMs and Sony Vaio laptops. Such
- EEPROMs could theoretically be available on other devices as well.
-
- This driver can also be built as a module. If so, the module
- will be called eeprom.
-
config SENSORS_PCF8574
tristate "Philips PCF8574 and PCF8574A (DEPRECATED)"
depends on EXPERIMENTAL && GPIO_PCF857X = "n"
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 00fcb5193ac..d142f238a2d 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -11,8 +11,6 @@
#
obj-$(CONFIG_DS1682) += ds1682.o
-obj-$(CONFIG_AT24) += at24.o
-obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b1c9abe24c7..fbb9030b68a 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -841,7 +841,7 @@ int i2c_attach_client(struct i2c_client *client)
if (client->driver && !is_newstyle_driver(client->driver)) {
client->dev.release = i2c_client_release;
- client->dev.uevent_suppress = 1;
+ dev_set_uevent_suppress(&client->dev, 1);
} else
client->dev.release = i2c_client_dev_release;
@@ -1831,7 +1831,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
case I2C_SMBUS_QUICK:
msg[0].len = 0;
/* Special case: The read/write field is used as data */
- msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0;
+ msg[0].flags = flags | (read_write == I2C_SMBUS_READ ?
+ I2C_M_RD : 0);
num = 1;
break;
case I2C_SMBUS_BYTE:
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index c171988a9f5..7e13d2df9af 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -35,6 +35,7 @@
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/smp_lock.h>
+#include <linux/jiffies.h>
#include <asm/uaccess.h>
static struct i2c_driver i2cdev_driver;
@@ -422,7 +423,10 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
client->adapter->retries = arg;
break;
case I2C_TIMEOUT:
- client->adapter->timeout = arg;
+ /* For historical reasons, user-space sets the timeout
+ * value in units of 10 ms.
+ */
+ client->adapter->timeout = msecs_to_jiffies(arg * 10);
break;
default:
/* NOTE: returning a fault code here could cause trouble
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index b1c6f68d98c..640c9920724 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -46,7 +46,7 @@ menuconfig IDE
SMART parameters from disk drives.
To compile this driver as a module, choose M here: the
- module will be called ide.
+ module will be called ide-core.ko.
For further information, please read <file:Documentation/ide/ide.txt>.
@@ -56,8 +56,12 @@ if IDE
comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
+config IDE_XFER_MODE
+ bool
+
config IDE_TIMINGS
bool
+ select IDE_XFER_MODE
config IDE_ATAPI
bool
@@ -465,6 +469,16 @@ config BLK_DEV_CS5535
It is safe to say Y to this question.
+config BLK_DEV_CS5536
+ tristate "CS5536 chipset support"
+ depends on X86_32
+ select BLK_DEV_IDEDMA_PCI
+ help
+ This option enables support for the AMD CS5536
+ companion chip used with the Geode LX processor family.
+
+ If unsure, say N.
+
config BLK_DEV_HPT366
tristate "HPT36X/37X chipset support"
select BLK_DEV_IDEDMA_PCI
@@ -688,6 +702,7 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST
config BLK_DEV_IDE_AU1XXX
bool "IDE for AMD Alchemy Au1200"
depends on SOC_AU1200
+ select IDE_XFER_MODE
choice
prompt "IDE Mode for AMD Alchemy Au1200"
default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
@@ -711,6 +726,11 @@ config BLK_DEV_IDE_TX4939
depends on SOC_TX4939
select BLK_DEV_IDEDMA_SFF
+config BLK_DEV_IDE_AT91
+ tristate "Atmel AT91 (SAM9, CAP9, AT572D940HF) IDE support"
+ depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40
+ select IDE_TIMINGS
+
config IDE_ARM
tristate "ARM IDE support"
depends on ARM && (ARCH_RPC || ARCH_SHARK)
@@ -856,6 +876,7 @@ config BLK_DEV_ALI14XX
config BLK_DEV_DTC2278
tristate "DTC-2278 support"
+ select IDE_XFER_MODE
select IDE_LEGACY
help
This driver is enabled at runtime using the "dtc2278.probe" kernel
@@ -887,6 +908,7 @@ config BLK_DEV_QD65XX
config BLK_DEV_UMC8672
tristate "UMC-8672 support"
+ select IDE_XFER_MODE
select IDE_LEGACY
help
This driver is enabled at runtime using the "umc8672.probe" kernel
@@ -900,5 +922,6 @@ endif
config BLK_DEV_IDEDMA
def_bool BLK_DEV_IDEDMA_SFF || \
BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ select IDE_XFER_MODE
endif # IDE
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index c2b9c93f009..9b4bbe1cdc1 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -5,9 +5,11 @@
EXTRA_CFLAGS += -Idrivers/ide
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
- ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o
+ ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
+ ide-io-std.o ide-eh.o
# core IDE code
+ide-core-$(CONFIG_IDE_XFER_MODE) += ide-pio-blacklist.o ide-xfer-mode.o
ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o
ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o
ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
@@ -43,6 +45,7 @@ obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
+obj-$(CONFIG_BLK_DEV_CS5536) += cs5536.o
obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o
@@ -115,3 +118,4 @@ obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o
obj-$(CONFIG_BLK_DEV_IDE_TX4938) += tx4938ide.o
obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o
+obj-$(CONFIG_BLK_DEV_IDE_AT91) += at91_ide.o
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index 4485b9c6f0e..878f8ec6dbe 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -139,7 +139,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0);
}
-static unsigned int init_chipset_aec62xx(struct pci_dev *dev)
+static int init_chipset_aec62xx(struct pci_dev *dev)
{
/* These are necessary to get AEC6280 Macintosh cards to work */
if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) ||
@@ -156,7 +156,7 @@ static unsigned int init_chipset_aec62xx(struct pci_dev *dev)
pci_write_config_byte(dev, 0x4a, reg4ah | 0x80);
}
- return dev->irq;
+ return 0;
}
static u8 atp86x_cable_detect(ide_hwif_t *hwif)
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 66f43083408..d3513b6b853 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -212,7 +212,7 @@ static int ali15x3_dma_setup(ide_drive_t *drive)
* appropriate also sets up the 1533 southbridge.
*/
-static unsigned int init_chipset_ali15x3(struct pci_dev *dev)
+static int init_chipset_ali15x3(struct pci_dev *dev)
{
unsigned long flags;
u8 tmpbyte;
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index 69660a431cd..628cd2e5fed 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -140,7 +140,7 @@ static void amd7411_cable_detect(struct pci_dev *dev)
* The initialization callback. Initialize drive independent registers.
*/
-static unsigned int init_chipset_amd74xx(struct pci_dev *dev)
+static int init_chipset_amd74xx(struct pci_dev *dev)
{
u8 t = 0, offset = amd_offset(dev);
@@ -166,13 +166,13 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev)
* Check for broken FIFO support.
*/
if (dev->vendor == PCI_VENDOR_ID_AMD &&
- dev->vendor == PCI_DEVICE_ID_AMD_VIPER_7411)
+ dev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
t &= 0x0f;
else
t |= 0xf0;
pci_write_config_byte(dev, AMD_IDE_CONFIG + offset, t);
- return dev->irq;
+ return 0;
}
static u8 amd_cable_detect(ide_hwif_t *hwif)
@@ -183,14 +183,6 @@ static u8 amd_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA40;
}
-static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
-{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
-
- if (hwif->irq == 0) /* 0 is bogus but will do for now */
- hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
-}
-
static const struct ide_port_ops amd_port_ops = {
.set_pio_mode = amd_set_pio_mode,
.set_dma_mode = amd_set_drive,
@@ -207,7 +199,6 @@ static const struct ide_port_ops amd_port_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_amd74xx, \
- .init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
.port_ops = &amd_port_ops, \
.host_flags = IDE_HFLAGS_AMD, \
@@ -221,7 +212,6 @@ static const struct ide_port_ops amd_port_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_amd74xx, \
- .init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
.port_ops = &amd_port_ops, \
.host_flags = IDE_HFLAGS_AMD, \
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
new file mode 100644
index 00000000000..1bb50f46388
--- /dev/null
+++ b/drivers/ide/at91_ide.c
@@ -0,0 +1,467 @@
+/*
+ * IDE host driver for AT91 (SAM9, CAP9, AT572D940HF) Static Memory Controller
+ * with Compact Flash True IDE logic
+ *
+ * Copyright (c) 2008, 2009 Kelvatek Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/ide.h>
+#include <linux/platform_device.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9263.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91sam9263_matrix.h>
+
+#define DRV_NAME "at91_ide"
+
+#define perr(fmt, args...) pr_err(DRV_NAME ": " fmt, ##args)
+#define pdbg(fmt, args...) pr_debug("%s " fmt, __func__, ##args)
+
+/*
+ * Access to IDE device is possible through EBI Static Memory Controller
+ * with Compact Flash logic. For details see EBI and SMC datasheet sections
+ * of any microcontroller from AT91SAM9 family.
+ *
+ * Within SMC chip select address space, lines A[23:21] distinguish Compact
+ * Flash modes (I/O, common memory, attribute memory, True IDE). IDE modes are:
+ * 0x00c0000 - True IDE
+ * 0x00e0000 - Alternate True IDE (Alt Status Register)
+ *
+ * On True IDE mode Task File and Data Register are mapped at the same address.
+ * To distinguish access between these two different bus data width is used:
+ * 8Bit for Task File, 16Bit for Data I/O.
+ *
+ * After initialization we do 8/16 bit flipping (changes in SMC MODE register)
+ * only inside IDE callback routines which are serialized by IDE layer,
+ * so no additional locking needed.
+ */
+
+#define TASK_FILE 0x00c00000
+#define ALT_MODE 0x00e00000
+#define REGS_SIZE 8
+
+#define enter_16bit(cs, mode) do { \
+ mode = at91_sys_read(AT91_SMC_MODE(cs)); \
+ at91_sys_write(AT91_SMC_MODE(cs), mode | AT91_SMC_DBW_16); \
+} while (0)
+
+#define leave_16bit(cs, mode) at91_sys_write(AT91_SMC_MODE(cs), mode);
+
+static void set_smc_timings(const u8 chipselect, const u16 cycle,
+ const u16 setup, const u16 pulse,
+ const u16 data_float, int use_iordy)
+{
+ unsigned long mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
+ AT91_SMC_BAT_SELECT;
+
+ /* disable or enable waiting for IORDY signal */
+ if (use_iordy)
+ mode |= AT91_SMC_EXNWMODE_READY;
+
+ /* add data float cycles if needed */
+ if (data_float)
+ mode |= AT91_SMC_TDF_(data_float);
+
+ at91_sys_write(AT91_SMC_MODE(chipselect), mode);
+
+ /* setup timings in SMC */
+ at91_sys_write(AT91_SMC_SETUP(chipselect), AT91_SMC_NWESETUP_(setup) |
+ AT91_SMC_NCS_WRSETUP_(0) |
+ AT91_SMC_NRDSETUP_(setup) |
+ AT91_SMC_NCS_RDSETUP_(0));
+ at91_sys_write(AT91_SMC_PULSE(chipselect), AT91_SMC_NWEPULSE_(pulse) |
+ AT91_SMC_NCS_WRPULSE_(cycle) |
+ AT91_SMC_NRDPULSE_(pulse) |
+ AT91_SMC_NCS_RDPULSE_(cycle));
+ at91_sys_write(AT91_SMC_CYCLE(chipselect), AT91_SMC_NWECYCLE_(cycle) |
+ AT91_SMC_NRDCYCLE_(cycle));
+}
+
+static unsigned int calc_mck_cycles(unsigned int ns, unsigned int mck_hz)
+{
+ u64 tmp = ns;
+
+ tmp *= mck_hz;
+ tmp += 1000*1000*1000 - 1; /* round up */
+ do_div(tmp, 1000*1000*1000);
+ return (unsigned int) tmp;
+}
+
+static void apply_timings(const u8 chipselect, const u8 pio,
+ const struct ide_timing *timing, int use_iordy)
+{
+ unsigned int t0, t1, t2, t6z;
+ unsigned int cycle, setup, pulse, data_float;
+ unsigned int mck_hz;
+ struct clk *mck;
+
+ /* see table 22 of Compact Flash standard 4.1 for the meaning,
+ * we do not stretch active (t2) time, so setup (t1) + hold time (th)
+ * assure at least minimal recovery (t2i) time */
+ t0 = timing->cyc8b;
+ t1 = timing->setup;
+ t2 = timing->act8b;
+ t6z = (pio < 5) ? 30 : 20;
+
+ pdbg("t0=%u t1=%u t2=%u t6z=%u\n", t0, t1, t2, t6z);
+
+ mck = clk_get(NULL, "mck");
+ BUG_ON(IS_ERR(mck));
+ mck_hz = clk_get_rate(mck);
+ pdbg("mck_hz=%u\n", mck_hz);
+
+ cycle = calc_mck_cycles(t0, mck_hz);
+ setup = calc_mck_cycles(t1, mck_hz);
+ pulse = calc_mck_cycles(t2, mck_hz);
+ data_float = calc_mck_cycles(t6z, mck_hz);
+
+ pdbg("cycle=%u setup=%u pulse=%u data_float=%u\n",
+ cycle, setup, pulse, data_float);
+
+ set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy);
+}
+
+static void at91_ide_input_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ u8 chipselect = hwif->select_data;
+ unsigned long mode;
+
+ pdbg("cs %u buf %p len %d\n", chipselect, buf, len);
+
+ len++;
+
+ enter_16bit(chipselect, mode);
+ __ide_mm_insw((void __iomem *) io_ports->data_addr, buf, len / 2);
+ leave_16bit(chipselect, mode);
+}
+
+static void at91_ide_output_data(ide_drive_t *drive, struct request *rq,
+ void *buf, unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ u8 chipselect = hwif->select_data;
+ unsigned long mode;
+
+ pdbg("cs %u buf %p len %d\n", chipselect, buf, len);
+
+ enter_16bit(chipselect, mode);
+ __ide_mm_outsw((void __iomem *) io_ports->data_addr, buf, len / 2);
+ leave_16bit(chipselect, mode);
+}
+
+static u8 ide_mm_inb(unsigned long port)
+{
+ return readb((void __iomem *) port);
+}
+
+static void ide_mm_outb(u8 value, unsigned long port)
+{
+ writeb(value, (void __iomem *) port);
+}
+
+static void at91_ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+ u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+
+ if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ HIHI = 0xFF;
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
+ u16 data = (tf->hob_data << 8) | tf->data;
+
+ at91_ide_output_data(drive, NULL, &data, 2);
+ }
+
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ ide_mm_outb(tf->hob_feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ ide_mm_outb(tf->feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ ide_mm_outb(tf->nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ ide_mm_outb(tf->lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ ide_mm_outb(tf->lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ ide_mm_outb(tf->lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr);
+}
+
+static void at91_ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+
+ if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ u16 data;
+
+ at91_ide_input_data(drive, NULL, &data, 2);
+ tf->data = data & 0xff;
+ tf->hob_data = (data >> 8) & 0xff;
+ }
+
+ /* be sure we're looking at the low order bits */
+ ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+ tf->feature = ide_mm_inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ tf->nsect = ide_mm_inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ tf->lbal = ide_mm_inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ tf->lbam = ide_mm_inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ tf->lbah = ide_mm_inb(io_ports->lbah_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ tf->device = ide_mm_inb(io_ports->device_addr);
+
+ if (task->tf_flags & IDE_TFLAG_LBA48) {
+ ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ tf->hob_feature = ide_mm_inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
+ }
+}
+
+static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+ struct ide_timing *timing;
+ u8 chipselect = drive->hwif->select_data;
+ int use_iordy = 0;
+
+ pdbg("chipselect %u pio %u\n", chipselect, pio);
+
+ timing = ide_timing_find_mode(XFER_PIO_0 + pio);
+ BUG_ON(!timing);
+
+ if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
+ !(ata_id_is_cfa(drive->id) && pio > 4))
+ use_iordy = 1;
+
+ apply_timings(chipselect, pio, timing, use_iordy);
+}
+
+static const struct ide_tp_ops at91_ide_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .set_irq = ide_set_irq,
+
+ .tf_load = at91_ide_tf_load,
+ .tf_read = at91_ide_tf_read,
+
+ .input_data = at91_ide_input_data,
+ .output_data = at91_ide_output_data,
+};
+
+static const struct ide_port_ops at91_ide_port_ops = {
+ .set_pio_mode = at91_ide_set_pio_mode,
+};
+
+static const struct ide_port_info at91_ide_port_info __initdata = {
+ .port_ops = &at91_ide_port_ops,
+ .tp_ops = &at91_ide_tp_ops,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE |
+ IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS,
+ .pio_mask = ATA_PIO5,
+};
+
+/*
+ * If interrupt is delivered through GPIO, IRQ are triggered on falling
+ * and rising edge of signal. Whereas IDE device request interrupt on high
+ * level (rising edge in our case). This mean we have fake interrupts, so
+ * we need to check interrupt pin and exit instantly from ISR when line
+ * is on low level.
+ */
+
+irqreturn_t at91_irq_handler(int irq, void *dev_id)
+{
+ int ntries = 8;
+ int pin_val1, pin_val2;
+
+ /* additional deglitch, line can be noisy in badly designed PCB */
+ do {
+ pin_val1 = at91_get_gpio_value(irq);
+ pin_val2 = at91_get_gpio_value(irq);
+ } while (pin_val1 != pin_val2 && --ntries > 0);
+
+ if (pin_val1 == 0 || ntries <= 0)
+ return IRQ_HANDLED;
+
+ return ide_intr(irq, dev_id);
+}
+
+static int __init at91_ide_probe(struct platform_device *pdev)
+{
+ int ret;
+ hw_regs_t hw;
+ hw_regs_t *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_host *host;
+ struct resource *res;
+ unsigned long tf_base = 0, ctl_base = 0;
+ struct at91_cf_data *board = pdev->dev.platform_data;
+
+ if (!board)
+ return -ENODEV;
+
+ if (board->det_pin && at91_get_gpio_value(board->det_pin) != 0) {
+ perr("no device detected\n");
+ return -ENODEV;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ perr("can't get memory resource\n");
+ return -ENODEV;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, res->start + TASK_FILE,
+ REGS_SIZE, "ide") ||
+ !devm_request_mem_region(&pdev->dev, res->start + ALT_MODE,
+ REGS_SIZE, "alt")) {
+ perr("memory resources in use\n");
+ return -EBUSY;
+ }
+
+ pdbg("chipselect %u irq %u res %08lx\n", board->chipselect,
+ board->irq_pin, (unsigned long) res->start);
+
+ tf_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + TASK_FILE,
+ REGS_SIZE);
+ ctl_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + ALT_MODE,
+ REGS_SIZE);
+ if (!tf_base || !ctl_base) {
+ perr("can't map memory regions\n");
+ return -EBUSY;
+ }
+
+ memset(&hw, 0, sizeof(hw));
+
+ if (board->flags & AT91_IDE_SWAP_A0_A2) {
+ /* workaround for stupid hardware bug */
+ hw.io_ports.data_addr = tf_base + 0;
+ hw.io_ports.error_addr = tf_base + 4;
+ hw.io_ports.nsect_addr = tf_base + 2;
+ hw.io_ports.lbal_addr = tf_base + 6;
+ hw.io_ports.lbam_addr = tf_base + 1;
+ hw.io_ports.lbah_addr = tf_base + 5;
+ hw.io_ports.device_addr = tf_base + 3;
+ hw.io_ports.command_addr = tf_base + 7;
+ hw.io_ports.ctl_addr = ctl_base + 3;
+ } else
+ ide_std_init_ports(&hw, tf_base, ctl_base + 6);
+
+ hw.irq = board->irq_pin;
+ hw.chipset = ide_generic;
+ hw.dev = &pdev->dev;
+
+ host = ide_host_alloc(&at91_ide_port_info, hws);
+ if (!host) {
+ perr("failed to allocate ide host\n");
+ return -ENOMEM;
+ }
+
+ /* setup Static Memory Controller - PIO 0 as default */
+ apply_timings(board->chipselect, 0, ide_timing_find_mode(XFER_PIO_0), 0);
+
+ /* with GPIO interrupt we have to do quirks in handler */
+ if (board->irq_pin >= PIN_BASE)
+ host->irq_handler = at91_irq_handler;
+
+ host->ports[0]->select_data = board->chipselect;
+
+ ret = ide_host_register(host, &at91_ide_port_info, hws);
+ if (ret) {
+ perr("failed to register ide host\n");
+ goto err_free_host;
+ }
+ platform_set_drvdata(pdev, host);
+ return 0;
+
+err_free_host:
+ ide_host_free(host);
+ return ret;
+}
+
+static int __exit at91_ide_remove(struct platform_device *pdev)
+{
+ struct ide_host *host = platform_get_drvdata(pdev);
+
+ ide_host_remove(host);
+ return 0;
+}
+
+static struct platform_driver at91_ide_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(at91_ide_remove),
+};
+
+static int __init at91_ide_init(void)
+{
+ return platform_driver_probe(&at91_ide_driver, at91_ide_probe);
+}
+
+static void __exit at91_ide_exit(void)
+{
+ platform_driver_unregister(&at91_ide_driver);
+}
+
+module_init(at91_ide_init);
+module_exit(at91_ide_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Stanislaw Gruszka <stf_xl@wp.pl>");
+
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c
index b2735d28f5c..923cbfe259d 100644
--- a/drivers/ide/atiixp.c
+++ b/drivers/ide/atiixp.c
@@ -52,7 +52,7 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
unsigned long flags;
- int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
+ int timing_shift = (drive->dn ^ 1) * 8;
u32 pio_timing_data;
u16 pio_mode_data;
@@ -85,7 +85,7 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
unsigned long flags;
- int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
+ int timing_shift = (drive->dn ^ 1) * 8;
u32 tmp32;
u16 tmp16;
u16 udma_ctl = 0;
@@ -142,7 +142,6 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
.port_ops = &atiixp_port_ops,
- .host_flags = IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -151,7 +150,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
.port_ops = &atiixp_port_ops,
- .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 79a2dfed8eb..154ec2cf734 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -536,9 +536,8 @@ static const struct ide_port_info au1xxx_port_info = {
#endif
};
-static int au_ide_probe(struct device *dev)
+static int au_ide_probe(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
_auide_hwif *ahwif = &auide_hwif;
struct resource *res;
struct ide_host *host;
@@ -552,23 +551,23 @@ static int au_ide_probe(struct device *dev)
#endif
memset(&auide_hwif, 0, sizeof(_auide_hwif));
- ahwif->irq = platform_get_irq(pdev, 0);
+ ahwif->irq = platform_get_irq(dev, 0);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (res == NULL) {
- pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);
+ pr_debug("%s %d: no base address\n", DRV_NAME, dev->id);
ret = -ENODEV;
goto out;
}
if (ahwif->irq < 0) {
- pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id);
+ pr_debug("%s %d: no IRQ\n", DRV_NAME, dev->id);
ret = -ENODEV;
goto out;
}
if (!request_mem_region(res->start, res->end - res->start + 1,
- pdev->name)) {
+ dev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
ret = -EBUSY;
goto out;
@@ -583,7 +582,7 @@ static int au_ide_probe(struct device *dev)
memset(&hw, 0, sizeof(hw));
auide_setup_ports(&hw, ahwif);
hw.irq = ahwif->irq;
- hw.dev = dev;
+ hw.dev = &dev->dev;
hw.chipset = ide_au1xxx;
ret = ide_host_add(&au1xxx_port_info, hws, &host);
@@ -592,7 +591,7 @@ static int au_ide_probe(struct device *dev)
auide_hwif.hwif = host->ports[0];
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
@@ -600,38 +599,39 @@ static int au_ide_probe(struct device *dev)
return ret;
}
-static int au_ide_remove(struct device *dev)
+static int au_ide_remove(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
- struct ide_host *host = dev_get_drvdata(dev);
+ struct ide_host *host = platform_get_drvdata(dev);
_auide_hwif *ahwif = &auide_hwif;
ide_host_remove(host);
iounmap((void *)ahwif->regbase);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
release_mem_region(res->start, res->end - res->start + 1);
return 0;
}
-static struct device_driver au1200_ide_driver = {
- .name = "au1200-ide",
- .bus = &platform_bus_type,
+static struct platform_driver au1200_ide_driver = {
+ .driver = {
+ .name = "au1200-ide",
+ .owner = THIS_MODULE,
+ },
.probe = au_ide_probe,
.remove = au_ide_remove,
};
static int __init au_ide_init(void)
{
- return driver_register(&au1200_ide_driver);
+ return platform_driver_register(&au1200_ide_driver);
}
static void __exit au_ide_exit(void)
{
- driver_unregister(&au1200_ide_driver);
+ platform_driver_unregister(&au1200_ide_driver);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 2f9688d87ec..aeee036b150 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -333,7 +333,7 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
return (dma_stat & 7) != 4;
}
-static unsigned int init_chipset_cmd64x(struct pci_dev *dev)
+static int init_chipset_cmd64x(struct pci_dev *dev)
{
u8 mrdmode = 0;
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c
index d003bec56ff..58fb90e5b76 100644
--- a/drivers/ide/cs5520.c
+++ b/drivers/ide/cs5520.c
@@ -133,7 +133,8 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
* do all the device setup for us
*/
- ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]);
+ ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
+ hw[0].irq = 14;
return ide_host_add(d, hws, NULL);
}
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index d8ede85fe17..8e8b35a8990 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -135,7 +135,7 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
* Initialize the cs5530 bridge for reliable IDE DMA operation.
*/
-static unsigned int init_chipset_cs5530(struct pci_dev *dev)
+static int init_chipset_cs5530(struct pci_dev *dev)
{
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
new file mode 100644
index 00000000000..7a62db719a4
--- /dev/null
+++ b/drivers/ide/cs5536.c
@@ -0,0 +1,308 @@
+/*
+ * CS5536 PATA support
+ * (C) 2007 Martin K. Petersen <mkp@mkp.net>
+ * (C) 2009 Bartlomiej Zolnierkiewicz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Documentation:
+ * Available from AMD web site.
+ *
+ * The IDE timing registers for the CS5536 live in the Geode Machine
+ * Specific Register file and not PCI config space. Most BIOSes
+ * virtualize the PCI registers so the chip looks like a standard IDE
+ * controller. Unfortunately not all implementations get this right.
+ * In particular some have problems with unaligned accesses to the
+ * virtualized PCI registers. This driver always does full dword
+ * writes to work around the issue. Also, in case of a bad BIOS this
+ * driver can be loaded with the "msr=1" parameter which forces using
+ * the Machine Specific Registers to configure the device.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <asm/msr.h>
+
+#define DRV_NAME "cs5536"
+
+enum {
+ MSR_IDE_CFG = 0x51300010,
+ PCI_IDE_CFG = 0x40,
+
+ CFG = 0,
+ DTC = 2,
+ CAST = 3,
+ ETC = 4,
+
+ IDE_CFG_CHANEN = (1 << 1),
+ IDE_CFG_CABLE = (1 << 17) | (1 << 16),
+
+ IDE_D0_SHIFT = 24,
+ IDE_D1_SHIFT = 16,
+ IDE_DRV_MASK = 0xff,
+
+ IDE_CAST_D0_SHIFT = 6,
+ IDE_CAST_D1_SHIFT = 4,
+ IDE_CAST_DRV_MASK = 0x3,
+
+ IDE_CAST_CMD_SHIFT = 24,
+ IDE_CAST_CMD_MASK = 0xff,
+
+ IDE_ETC_UDMA_MASK = 0xc0,
+};
+
+static int use_msr;
+
+static int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
+{
+ if (unlikely(use_msr)) {
+ u32 dummy;
+
+ rdmsr(MSR_IDE_CFG + reg, *val, dummy);
+ return 0;
+ }
+
+ return pci_read_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static int cs5536_write(struct pci_dev *pdev, int reg, int val)
+{
+ if (unlikely(use_msr)) {
+ wrmsr(MSR_IDE_CFG + reg, val, 0);
+ return 0;
+ }
+
+ return pci_write_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static void cs5536_program_dtc(ide_drive_t *drive, u8 tim)
+{
+ struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+ int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ u32 dtc;
+
+ cs5536_read(pdev, DTC, &dtc);
+ dtc &= ~(IDE_DRV_MASK << dshift);
+ dtc |= tim << dshift;
+ cs5536_write(pdev, DTC, dtc);
+}
+
+/**
+ * cs5536_cable_detect - detect cable type
+ * @hwif: Port to detect on
+ *
+ * Perform cable detection for ATA66 capable cable.
+ *
+ * Returns a cable type.
+ */
+
+static u8 cs5536_cable_detect(ide_hwif_t *hwif)
+{
+ struct pci_dev *pdev = to_pci_dev(hwif->dev);
+ u32 cfg;
+
+ cs5536_read(pdev, CFG, &cfg);
+
+ if (cfg & IDE_CFG_CABLE)
+ return ATA_CBL_PATA80;
+ else
+ return ATA_CBL_PATA40;
+}
+
+/**
+ * cs5536_set_pio_mode - PIO timing setup
+ * @drive: ATA device
+ * @pio: PIO mode number
+ */
+
+static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+ static const u8 drv_timings[5] = {
+ 0x98, 0x55, 0x32, 0x21, 0x20,
+ };
+
+ static const u8 addr_timings[5] = {
+ 0x2, 0x1, 0x0, 0x0, 0x0,
+ };
+
+ static const u8 cmd_timings[5] = {
+ 0x99, 0x92, 0x90, 0x22, 0x20,
+ };
+
+ struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+ ide_drive_t *pair = ide_get_pair_dev(drive);
+ int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+ u32 cast;
+ u8 cmd_pio = pio;
+
+ if (pair)
+ cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4));
+
+ drive->drive_data &= (IDE_DRV_MASK << 8);
+ drive->drive_data |= drv_timings[pio];
+
+ cs5536_program_dtc(drive, drv_timings[pio]);
+
+ cs5536_read(pdev, CAST, &cast);
+
+ cast &= ~(IDE_CAST_DRV_MASK << cshift);
+ cast |= addr_timings[pio] << cshift;
+
+ cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT);
+ cast |= cmd_timings[cmd_pio] << IDE_CAST_CMD_SHIFT;
+
+ cs5536_write(pdev, CAST, cast);
+}
+
+/**
+ * cs5536_set_dma_mode - DMA timing setup
+ * @drive: ATA device
+ * @mode: DMA mode
+ */
+
+static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+ static const u8 udma_timings[6] = {
+ 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
+ };
+
+ static const u8 mwdma_timings[3] = {
+ 0x67, 0x21, 0x20,
+ };
+
+ struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+ int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ u32 etc;
+
+ cs5536_read(pdev, ETC, &etc);
+
+ if (mode >= XFER_UDMA_0) {
+ etc &= ~(IDE_DRV_MASK << dshift);
+ etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
+ } else { /* MWDMA */
+ etc &= ~(IDE_ETC_UDMA_MASK << dshift);
+ drive->drive_data &= IDE_DRV_MASK;
+ drive->drive_data |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
+ }
+
+ cs5536_write(pdev, ETC, etc);
+}
+
+static void cs5536_dma_start(ide_drive_t *drive)
+{
+ if (drive->current_speed < XFER_UDMA_0 &&
+ (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
+ cs5536_program_dtc(drive, drive->drive_data >> 8);
+
+ ide_dma_start(drive);
+}
+
+static int cs5536_dma_end(ide_drive_t *drive)
+{
+ int ret = ide_dma_end(drive);
+
+ if (drive->current_speed < XFER_UDMA_0 &&
+ (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
+ cs5536_program_dtc(drive, drive->drive_data & IDE_DRV_MASK);
+
+ return ret;
+}
+
+static const struct ide_port_ops cs5536_port_ops = {
+ .set_pio_mode = cs5536_set_pio_mode,
+ .set_dma_mode = cs5536_set_dma_mode,
+ .cable_detect = cs5536_cable_detect,
+};
+
+static const struct ide_dma_ops cs5536_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_start = cs5536_dma_start,
+ .dma_end = cs5536_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timeout = ide_dma_timeout,
+};
+
+static const struct ide_port_info cs5536_info = {
+ .name = DRV_NAME,
+ .port_ops = &cs5536_port_ops,
+ .dma_ops = &cs5536_dma_ops,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
+};
+
+/**
+ * cs5536_init_one
+ * @dev: PCI device
+ * @id: Entry in match table
+ */
+
+static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ u32 cfg;
+
+ if (use_msr)
+ printk(KERN_INFO DRV_NAME ": Using MSR regs instead of PCI\n");
+
+ cs5536_read(dev, CFG, &cfg);
+
+ if ((cfg & IDE_CFG_CHANEN) == 0) {
+ printk(KERN_ERR DRV_NAME ": disabled by BIOS\n");
+ return -ENODEV;
+ }
+
+ return ide_pci_init_one(dev, &cs5536_info, NULL);
+}
+
+static const struct pci_device_id cs5536_pci_tbl[] = {
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), },
+ { },
+};
+
+static struct pci_driver cs5536_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = cs5536_pci_tbl,
+ .probe = cs5536_init_one,
+ .remove = ide_pci_remove,
+ .suspend = ide_pci_suspend,
+ .resume = ide_pci_resume,
+};
+
+static int __init cs5536_init(void)
+{
+ return pci_register_driver(&cs5536_pci_driver);
+}
+
+static void __exit cs5536_exit(void)
+{
+ pci_unregister_driver(&cs5536_pci_driver);
+}
+
+MODULE_AUTHOR("Martin K. Petersen, Bartlomiej Zolnierkiewicz");
+MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, cs5536_pci_tbl);
+
+module_param_named(msr, use_msr, int, 0644);
+MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
+
+module_init(cs5536_init);
+module_exit(cs5536_exit);
diff --git a/drivers/ide/delkin_cb.c b/drivers/ide/delkin_cb.c
index 8f1b2d9f051..bacb1194c9c 100644
--- a/drivers/ide/delkin_cb.c
+++ b/drivers/ide/delkin_cb.c
@@ -46,7 +46,7 @@ static const struct ide_port_ops delkin_cb_port_ops = {
.quirkproc = ide_undecoded_slave,
};
-static unsigned int delkin_cb_init_chipset(struct pci_dev *dev)
+static int delkin_cb_init_chipset(struct pci_dev *dev)
{
unsigned long base = pci_resource_start(dev, 0);
int i;
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index a5ba820d69b..a638e952d67 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -82,7 +82,7 @@ static const struct ide_tp_ops falconide_tp_ops = {
static const struct ide_port_info falconide_port_info = {
.tp_ops = &falconide_tp_ops,
- .host_flags = IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_SERIALIZE,
};
static void __init falconide_setup_ports(hw_regs_t *hw)
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 3eb9b5c63a0..d3b3e824f44 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -995,7 +995,7 @@ static void hpt3xx_disable_fast_irq(struct pci_dev *dev, u8 mcr_addr)
pci_write_config_byte(dev, mcr_addr + 1, new_mcr);
}
-static unsigned int init_chipset_hpt366(struct pci_dev *dev)
+static int init_chipset_hpt366(struct pci_dev *dev)
{
unsigned long io_base = pci_resource_start(dev, 4);
struct hpt_info *info = hpt3xx_get_info(&dev->dev);
@@ -1237,7 +1237,7 @@ static unsigned int init_chipset_hpt366(struct pci_dev *dev)
hpt3xx_disable_fast_irq(dev, 0x50);
hpt3xx_disable_fast_irq(dev, 0x54);
- return dev->irq;
+ return 0;
}
static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 97a35c667ae..415d7e24f2b 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -534,7 +534,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
d.dma_ops = NULL;
}
- ret = ide_host_register(host, NULL, hws);
+ ret = ide_host_register(host, &d, hws);
if (ret)
goto err_free;
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index d8f295bdad7..5b704f1ea90 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -20,9 +20,6 @@
#include <acpi/acpi_bus.h>
#define REGS_PER_GTF 7
-struct taskfile_array {
- u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
-};
struct GTM_buffer {
u32 PIO_speed0;
@@ -89,12 +86,8 @@ static const struct dmi_system_id ide_acpi_dmi_table[] = {
{ } /* terminate list */
};
-static int ide_acpi_blacklist(void)
+int ide_acpi_init(void)
{
- static int done;
- if (done)
- return 0;
- done = 1;
dmi_check_system(ide_acpi_dmi_table);
return 0;
}
@@ -202,40 +195,6 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
}
/**
- * ide_acpi_drive_get_handle - Get ACPI object handle for a given drive
- * @drive: device to locate
- *
- * Retrieves the object handle of a given drive. According to the ACPI
- * spec the drive is a child of the hwif.
- *
- * Returns handle on success, 0 on error.
- */
-static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- int port;
- acpi_handle drive_handle;
-
- if (!hwif->acpidata)
- return NULL;
-
- if (!hwif->acpidata->obj_handle)
- return NULL;
-
- port = hwif->channel ? drive->dn - 2: drive->dn;
-
- DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
- drive->name, hwif->channel, port);
-
-
- /* TBD: could also check ACPI object VALID bits */
- drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port);
- DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle);
-
- return drive_handle;
-}
-
-/**
* do_drive_get_GTF - get the drive bootup default taskfile settings
* @drive: the drive for which the taskfile settings should be retrieved
* @gtf_length: number of bytes of _GTF data returned at @gtf_address
@@ -257,47 +216,15 @@ static int do_drive_get_GTF(ide_drive_t *drive,
acpi_status status;
struct acpi_buffer output;
union acpi_object *out_obj;
- ide_hwif_t *hwif = drive->hwif;
- struct device *dev = hwif->gendev.parent;
int err = -ENODEV;
- int port;
*gtf_length = 0;
*gtf_address = 0UL;
*obj_loc = 0UL;
- if (ide_noacpi)
- return 0;
-
- if (!dev) {
- DEBPRINT("no PCI device for %s\n", hwif->name);
- goto out;
- }
-
- if (!hwif->acpidata) {
- DEBPRINT("no ACPI data for %s\n", hwif->name);
- goto out;
- }
-
- port = hwif->channel ? drive->dn - 2: drive->dn;
-
- DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
- hwif->name, dev->bus_id, port, hwif->channel);
-
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) {
- DEBPRINT("%s drive %d:%d not present\n",
- hwif->name, hwif->channel, port);
- goto out;
- }
-
- /* Get this drive's _ADR info. if not already known. */
if (!drive->acpidata->obj_handle) {
- drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
- if (!drive->acpidata->obj_handle) {
- DEBPRINT("No ACPI object found for %s\n",
- drive->name);
- goto out;
- }
+ DEBPRINT("No ACPI object found for %s\n", drive->name);
+ goto out;
}
/* Setting up output buffer */
@@ -355,43 +282,6 @@ out:
}
/**
- * taskfile_load_raw - send taskfile registers to drive
- * @drive: drive to which output is sent
- * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
- *
- * Outputs IDE taskfile to the drive.
- */
-static int taskfile_load_raw(ide_drive_t *drive,
- const struct taskfile_array *gtf)
-{
- ide_task_t args;
- int err = 0;
-
- DEBPRINT("(0x1f1-1f7): hex: "
- "%02x %02x %02x %02x %02x %02x %02x\n",
- gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
- gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
-
- memset(&args, 0, sizeof(ide_task_t));
-
- /* convert gtf to IDE Taskfile */
- memcpy(&args.tf_array[7], &gtf->tfa, 7);
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-
- if (!ide_acpigtf) {
- DEBPRINT("_GTF execution disabled\n");
- return err;
- }
-
- err = ide_no_data_taskfile(drive, &args);
- if (err)
- printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
- __func__, err);
-
- return err;
-}
-
-/**
* do_drive_set_taskfiles - write the drive taskfile settings from _GTF
* @drive: the drive to which the taskfile command should be sent
* @gtf_length: total number of bytes of _GTF taskfiles
@@ -404,43 +294,41 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
unsigned int gtf_length,
unsigned long gtf_address)
{
- int rc = -ENODEV, err;
+ int rc = 0, err;
int gtf_count = gtf_length / REGS_PER_GTF;
int ix;
- struct taskfile_array *gtf;
-
- if (ide_noacpi)
- return 0;
-
- DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn);
-
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- goto out;
-
- if (!gtf_count) /* shouldn't be here */
- goto out;
DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n",
gtf_length, gtf_length, gtf_count, gtf_address);
- if (gtf_length % REGS_PER_GTF) {
- printk(KERN_ERR "%s: unexpected GTF length (%d)\n",
- __func__, gtf_length);
- goto out;
- }
-
- rc = 0;
+ /* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */
for (ix = 0; ix < gtf_count; ix++) {
- gtf = (struct taskfile_array *)
- (gtf_address + ix * REGS_PER_GTF);
+ u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF);
+ ide_task_t task;
- /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
- err = taskfile_load_raw(drive, gtf);
- if (err)
+ DEBPRINT("(0x1f1-1f7): "
+ "hex: %02x %02x %02x %02x %02x %02x %02x\n",
+ gtf[0], gtf[1], gtf[2],
+ gtf[3], gtf[4], gtf[5], gtf[6]);
+
+ if (!ide_acpigtf) {
+ DEBPRINT("_GTF execution disabled\n");
+ continue;
+ }
+
+ /* convert GTF to taskfile */
+ memset(&task, 0, sizeof(ide_task_t));
+ memcpy(&task.tf_array[7], gtf, REGS_PER_GTF);
+ task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ err = ide_no_data_taskfile(drive, &task);
+ if (err) {
+ printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
+ __func__, err);
rc = err;
+ }
}
-out:
return rc;
}
@@ -647,26 +535,23 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
DEBPRINT("no ACPI data for %s\n", hwif->name);
return;
}
+
/* channel first and then drives for power on and verse versa for power off */
if (on)
acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0);
- ide_port_for_each_dev(i, drive, hwif) {
- if (!drive->acpidata->obj_handle)
- drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
-
- if (drive->acpidata->obj_handle &&
- (drive->dev_flags & IDE_DFLAG_PRESENT)) {
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ if (drive->acpidata->obj_handle)
acpi_bus_set_power(drive->acpidata->obj_handle,
- on? ACPI_STATE_D0: ACPI_STATE_D3);
- }
+ on ? ACPI_STATE_D0 : ACPI_STATE_D3);
}
+
if (!on)
acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3);
}
/**
- * ide_acpi_init - initialize the ACPI link for an IDE interface
+ * ide_acpi_init_port - initialize the ACPI link for an IDE interface
* @hwif: target IDE interface (channel)
*
* The ACPI spec is not quite clear when the drive identify buffer
@@ -676,10 +561,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
* So we get the information during startup; but this means that
* any changes during run-time will be lost after resume.
*/
-void ide_acpi_init(ide_hwif_t *hwif)
+void ide_acpi_init_port(ide_hwif_t *hwif)
{
- ide_acpi_blacklist();
-
hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
if (!hwif->acpidata)
return;
@@ -708,15 +591,24 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
hwif->devices[0]->acpidata = &hwif->acpidata->master;
hwif->devices[1]->acpidata = &hwif->acpidata->slave;
- /*
- * Send IDENTIFY for each drive
- */
- ide_port_for_each_dev(i, drive, hwif) {
- memset(drive->acpidata, 0, sizeof(*drive->acpidata));
+ /* get _ADR info for each device */
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ acpi_handle dev_handle;
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
+ DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
+ drive->name, hwif->channel, drive->dn & 1);
+
+ /* TBD: could also check ACPI object VALID bits */
+ dev_handle = acpi_get_child(hwif->acpidata->obj_handle,
+ drive->dn & 1);
+
+ DEBPRINT("drive %s handle 0x%p\n", drive->name, dev_handle);
+
+ drive->acpidata->obj_handle = dev_handle;
+ }
+ /* send IDENTIFY for each device */
+ ide_port_for_each_present_dev(i, drive, hwif) {
err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
if (err)
DEBPRINT("identify device %s failed (%d)\n",
@@ -736,9 +628,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
ide_acpi_get_timing(hwif);
ide_acpi_push_timing(hwif);
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT)
- /* Execute ACPI startup code */
- ide_acpi_exec_tfs(drive);
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ ide_acpi_exec_tfs(drive);
}
}
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index e96c0126059..6adc5b4a440 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -140,10 +140,19 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
rq->cmd_flags |= REQ_PREEMPT;
rq->buffer = (char *)pc;
rq->rq_disk = disk;
+
+ if (pc->req_xfer) {
+ rq->data = pc->buf;
+ rq->data_len = pc->req_xfer;
+ }
+
memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1;
- ide_do_drive_cmd(drive, rq);
+
+ drive->hwif->rq = NULL;
+
+ elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
/*
@@ -159,6 +168,12 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_SPECIAL;
rq->buffer = (char *)pc;
+
+ if (pc->req_xfer) {
+ rq->data = pc->buf;
+ rq->data_len = pc->req_xfer;
+ }
+
memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1;
@@ -285,6 +300,21 @@ int ide_cd_get_xferlen(struct request *rq)
}
EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
+void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
+{
+ ide_task_t task;
+
+ memset(&task, 0, sizeof(task));
+ task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
+ IDE_TFLAG_IN_NSECT;
+
+ drive->hwif->tp_ops->tf_read(drive, &task);
+
+ *bcount = (task.tf.lbah << 8) | task.tf.lbam;
+ *ireason = task.tf.nsect & 3;
+}
+EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
+
/*
* This is the usual interrupt handler which will be called during a packet
* command. We will transfer some of the data (as requested by the drive)
@@ -444,6 +474,25 @@ next_irq:
return ide_started;
}
+static void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ ide_task_t task;
+ u8 dma = drive->dma;
+
+ memset(&task, 0, sizeof(task));
+ task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
+ IDE_TFLAG_OUT_FEATURE | tf_flags;
+ task.tf.feature = dma; /* Use PIO/DMA */
+ task.tf.lbam = bcount & 0xff;
+ task.tf.lbah = (bcount >> 8) & 0xff;
+
+ ide_tf_dump(drive->name, &task.tf);
+ hwif->tp_ops->set_irq(hwif, 1);
+ SELECT_MASK(drive, 0);
+ hwif->tp_ops->tf_load(drive, &task);
+}
+
static u8 ide_read_ireason(ide_drive_t *drive)
{
ide_task_t task;
@@ -617,7 +666,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
: WAIT_TAPE_CMD;
}
- ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);
+ ide_pktcmd_tf_load(drive, tf_flags, bcount);
/* Issue the packet command */
if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index cae69372cf4..2177cd11664 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -55,7 +55,7 @@
static DEFINE_MUTEX(idecd_ref_mutex);
-static void ide_cd_release(struct kref *);
+static void ide_cd_release(struct device *);
static struct cdrom_info *ide_cd_get(struct gendisk *disk)
{
@@ -67,7 +67,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk)
if (ide_device_get(cd->drive))
cd = NULL;
else
- kref_get(&cd->kref);
+ get_device(&cd->dev);
}
mutex_unlock(&idecd_ref_mutex);
@@ -79,7 +79,7 @@ static void ide_cd_put(struct cdrom_info *cd)
ide_drive_t *drive = cd->drive;
mutex_lock(&idecd_ref_mutex);
- kref_put(&cd->kref, ide_cd_release);
+ put_device(&cd->dev);
ide_device_put(drive);
mutex_unlock(&idecd_ref_mutex);
}
@@ -194,6 +194,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
bio_sectors = max(bio_sectors(failed_command->bio), 4U);
sector &= ~(bio_sectors - 1);
+ /*
+ * The SCSI specification allows for the value
+ * returned by READ CAPACITY to be up to 75 2K
+ * sectors past the last readable block.
+ * Therefore, if we hit a medium error within the
+ * last 75 2K sectors, we decrease the saved size
+ * value.
+ */
if (sector < get_capacity(info->disk) &&
drive->probed_capacity - sector < 4 * 75)
set_capacity(info->disk, sector);
@@ -234,7 +242,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n",
failed_command->cmd[0]);
- ide_do_drive_cmd(drive, rq);
+ drive->hwif->rq = NULL;
+
+ elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
static void cdrom_end_request(ide_drive_t *drive, int uptodate)
@@ -787,6 +797,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (blk_fs_request(rq)) {
ide_end_request(drive, 1, rq->nr_sectors);
return ide_stopped;
+ } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) {
+ ide_end_request(drive, 1, 1);
+ return ide_stopped;
}
goto end_request;
}
@@ -1787,15 +1800,17 @@ static void ide_cd_remove(ide_drive_t *drive)
ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
ide_proc_unregister_driver(drive, info->driver);
-
+ device_del(&info->dev);
del_gendisk(info->disk);
- ide_cd_put(info);
+ mutex_lock(&idecd_ref_mutex);
+ put_device(&info->dev);
+ mutex_unlock(&idecd_ref_mutex);
}
-static void ide_cd_release(struct kref *kref)
+static void ide_cd_release(struct device *dev)
{
- struct cdrom_info *info = to_ide_drv(kref, cdrom_info);
+ struct cdrom_info *info = to_ide_drv(dev, cdrom_info);
struct cdrom_device_info *devinfo = &info->devinfo;
ide_drive_t *drive = info->drive;
struct gendisk *g = info->disk;
@@ -1994,7 +2009,12 @@ static int ide_cd_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
- kref_init(&info->kref);
+ info->dev.parent = &drive->gendev;
+ info->dev.release = ide_cd_release;
+ dev_set_name(&info->dev, dev_name(&drive->gendev));
+
+ if (device_register(&info->dev))
+ goto out_free_disk;
info->drive = drive;
info->driver = &ide_cdrom_driver;
@@ -2008,7 +2028,7 @@ static int ide_cd_probe(ide_drive_t *drive)
g->driverfs_dev = &drive->gendev;
g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
if (ide_cdrom_setup(drive)) {
- ide_cd_release(&info->kref);
+ put_device(&info->dev);
goto failed;
}
@@ -2018,6 +2038,8 @@ static int ide_cd_probe(ide_drive_t *drive)
add_disk(g);
return 0;
+out_free_disk:
+ put_disk(g);
out_free_cd:
kfree(info);
failed:
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index ac40d6cb90a..c878bfcf111 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -80,7 +80,7 @@ struct cdrom_info {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
- struct kref kref;
+ struct device dev;
/* Buffer for table of contents. NULL if we haven't allocated
a TOC buffer for this device yet. */
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c
new file mode 100644
index 00000000000..7c3953414d4
--- /dev/null
+++ b/drivers/ide/ide-devsets.c
@@ -0,0 +1,190 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+DEFINE_MUTEX(ide_setting_mtx);
+
+ide_devset_get(io_32bit, io_32bit);
+
+static int set_io_32bit(ide_drive_t *drive, int arg)
+{
+ if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
+ return -EPERM;
+
+ if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
+ return -EINVAL;
+
+ drive->io_32bit = arg;
+
+ return 0;
+}
+
+ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
+
+static int set_ksettings(ide_drive_t *drive, int arg)
+{
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (arg)
+ drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
+ else
+ drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
+
+ return 0;
+}
+
+ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
+
+static int set_using_dma(ide_drive_t *drive, int arg)
+{
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ int err = -EPERM;
+
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (ata_id_has_dma(drive->id) == 0)
+ goto out;
+
+ if (drive->hwif->dma_ops == NULL)
+ goto out;
+
+ err = 0;
+
+ if (arg) {
+ if (ide_set_dma(drive))
+ err = -EIO;
+ } else
+ ide_dma_off(drive);
+
+out:
+ return err;
+#else
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ return -EPERM;
+#endif
+}
+
+/*
+ * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
+ */
+static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
+{
+ switch (req_pio) {
+ case 202:
+ case 201:
+ case 200:
+ case 102:
+ case 101:
+ case 100:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
+ case 9:
+ case 8:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
+ case 7:
+ case 6:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
+ default:
+ return 0;
+ }
+}
+
+static int set_pio_mode(ide_drive_t *drive, int arg)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (arg < 0 || arg > 255)
+ return -EINVAL;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return -ENOSYS;
+
+ if (set_pio_mode_abuse(drive->hwif, arg)) {
+ if (arg == 8 || arg == 9) {
+ unsigned long flags;
+
+ /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
+ spin_lock_irqsave(&hwif->lock, flags);
+ port_ops->set_pio_mode(drive, arg);
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ } else
+ port_ops->set_pio_mode(drive, arg);
+ } else {
+ int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+
+ ide_set_pio(drive, arg);
+
+ if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
+ if (keep_dma)
+ ide_dma_on(drive);
+ }
+ }
+
+ return 0;
+}
+
+ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
+
+static int set_unmaskirq(ide_drive_t *drive, int arg)
+{
+ if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
+ return -EPERM;
+
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (arg)
+ drive->dev_flags |= IDE_DFLAG_UNMASK;
+ else
+ drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+
+ return 0;
+}
+
+ide_ext_devset_rw_sync(io_32bit, io_32bit);
+ide_ext_devset_rw_sync(keepsettings, ksettings);
+ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
+ide_ext_devset_rw_sync(using_dma, using_dma);
+__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
+
+int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
+ int arg)
+{
+ struct request_queue *q = drive->queue;
+ struct request *rq;
+ int ret = 0;
+
+ if (!(setting->flags & DS_SYNC))
+ return setting->set(drive, arg);
+
+ rq = blk_get_request(q, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_len = 5;
+ rq->cmd[0] = REQ_DEVSET_EXEC;
+ *(int *)&rq->cmd[1] = arg;
+ rq->special = setting->set;
+
+ if (blk_execute_rq(q, NULL, rq, 0))
+ ret = rq->errors;
+ blk_put_request(rq);
+
+ return ret;
+}
+
+ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
+{
+ int err, (*setfunc)(ide_drive_t *, int) = rq->special;
+
+ err = setfunc(drive, *(int *)&rq->cmd[1]);
+ if (err)
+ rq->errors = err;
+ else
+ err = 1;
+ ide_end_request(drive, err, 0);
+ return ide_stopped;
+}
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 1146f4204c6..1f86dcbd2b1 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -125,5 +125,5 @@ const struct ide_proc_devset ide_disk_settings[] = {
IDE_PROC_DEVSET(multcount, 0, 16),
IDE_PROC_DEVSET(nowerr, 0, 1),
IDE_PROC_DEVSET(wcache, 0, 1),
- { 0 },
+ { NULL },
};
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 72ebab0bc75..a878f4734f8 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -128,6 +128,7 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
+ int i;
ide_map_sg(drive, rq);
@@ -136,8 +137,13 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq)
else
hwif->sg_dma_direction = DMA_TO_DEVICE;
- return dma_map_sg(hwif->dev, sg, hwif->sg_nents,
- hwif->sg_dma_direction);
+ i = dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction);
+ if (i) {
+ hwif->orig_sg_nents = hwif->sg_nents;
+ hwif->sg_nents = i;
+ }
+
+ return i;
}
EXPORT_SYMBOL_GPL(ide_build_sglist);
@@ -156,7 +162,7 @@ void ide_destroy_dmatable(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->sg_nents,
+ dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->orig_sg_nents,
hwif->sg_dma_direction);
}
EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
@@ -464,6 +470,63 @@ void ide_dma_timeout(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_dma_timeout);
+/*
+ * un-busy the port etc, and clear any pending DMA status. we want to
+ * retry the current request in pio mode instead of risking tossing it
+ * all away
+ */
+ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct request *rq;
+ ide_startstop_t ret = ide_stopped;
+
+ /*
+ * end current dma transaction
+ */
+
+ if (error < 0) {
+ printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
+ (void)hwif->dma_ops->dma_end(drive);
+ ret = ide_error(drive, "dma timeout error",
+ hwif->tp_ops->read_status(hwif));
+ } else {
+ printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
+ hwif->dma_ops->dma_timeout(drive);
+ }
+
+ /*
+ * disable dma for now, but remember that we did so because of
+ * a timeout -- we'll reenable after we finish this next request
+ * (or rather the first chunk of it) in pio.
+ */
+ drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY;
+ drive->retry_pio++;
+ ide_dma_off_quietly(drive);
+
+ /*
+ * un-busy drive etc and make sure request is sane
+ */
+
+ rq = hwif->rq;
+ if (!rq)
+ goto out;
+
+ hwif->rq = NULL;
+
+ rq->errors = 0;
+
+ if (!rq->bio)
+ goto out;
+
+ rq->sector = rq->bio->bi_sector;
+ rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+ rq->hard_cur_sectors = rq->current_nr_sectors;
+ rq->buffer = bio_data(rq->bio);
+out:
+ return ret;
+}
+
void ide_release_dma_engine(ide_hwif_t *hwif)
{
if (hwif->dmatable_cpu) {
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c
new file mode 100644
index 00000000000..1231b5e486f
--- /dev/null
+++ b/drivers/ide/ide-eh.c
@@ -0,0 +1,428 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <linux/delay.h>
+
+static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if ((stat & ATA_BUSY) ||
+ ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else if (stat & ATA_ERR) {
+ /* err has different meaning on cdrom and tape */
+ if (err == ATA_ABORTED) {
+ if ((drive->dev_flags & IDE_DFLAG_LBA) &&
+ /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
+ hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
+ return ide_stopped;
+ } else if ((err & BAD_CRC) == BAD_CRC) {
+ /* UDMA crc error, just retry the operation */
+ drive->crc_count++;
+ } else if (err & (ATA_BBK | ATA_UNC)) {
+ /* retries won't help these */
+ rq->errors = ERROR_MAX;
+ } else if (err & ATA_TRK0NF) {
+ /* help it find track zero */
+ rq->errors |= ERROR_RECAL;
+ }
+ }
+
+ if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
+ (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
+ int nsect = drive->mult_count ? drive->mult_count : 1;
+
+ ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
+ }
+
+ if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
+ ide_kill_rq(drive, rq);
+ return ide_stopped;
+ }
+
+ if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+ rq->errors |= ERROR_RESET;
+
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+
+ if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+ drive->special.b.recalibrate = 1;
+
+ ++rq->errors;
+
+ return ide_stopped;
+}
+
+static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if ((stat & ATA_BUSY) ||
+ ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else {
+ /* add decoding error stuff */
+ }
+
+ if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+ /* force an abort */
+ hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
+
+ if (rq->errors >= ERROR_MAX) {
+ ide_kill_rq(drive, rq);
+ } else {
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+ ++rq->errors;
+ }
+
+ return ide_stopped;
+}
+
+static ide_startstop_t __ide_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ if (drive->media == ide_disk)
+ return ide_ata_error(drive, rq, stat, err);
+ return ide_atapi_error(drive, rq, stat, err);
+}
+
+/**
+ * ide_error - handle an error on the IDE
+ * @drive: drive the error occurred on
+ * @msg: message to report
+ * @stat: status bits
+ *
+ * ide_error() takes action based on the error returned by the drive.
+ * For normal I/O that may well include retries. We deal with
+ * both new-style (taskfile) and old style command handling here.
+ * In the case of taskfile command handling there is work left to
+ * do
+ */
+
+ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
+{
+ struct request *rq;
+ u8 err;
+
+ err = ide_dump_status(drive, msg, stat);
+
+ rq = drive->hwif->rq;
+ if (rq == NULL)
+ return ide_stopped;
+
+ /* retry only "normal" I/O: */
+ if (!blk_fs_request(rq)) {
+ rq->errors = 1;
+ ide_end_drive_cmd(drive, stat, err);
+ return ide_stopped;
+ }
+
+ return __ide_error(drive, rq, stat, err);
+}
+EXPORT_SYMBOL_GPL(ide_error);
+
+static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
+{
+ struct request *rq = drive->hwif->rq;
+
+ if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
+ ide_end_request(drive, err ? err : 1, 0);
+}
+
+/* needed below */
+static ide_startstop_t do_reset1(ide_drive_t *, int);
+
+/*
+ * atapi_reset_pollfunc() gets invoked to poll the interface for completion
+ * every 50ms during an atapi drive reset operation. If the drive has not yet
+ * responded, and we have not yet hit our maximum waiting time, then the timer
+ * is restarted for another 50ms.
+ */
+static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 stat;
+
+ SELECT_DRIVE(drive);
+ udelay(10);
+ stat = hwif->tp_ops->read_status(hwif);
+
+ if (OK_STAT(stat, 0, ATA_BUSY))
+ printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
+ else {
+ if (time_before(jiffies, hwif->poll_timeout)) {
+ ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20,
+ NULL);
+ /* continue polling */
+ return ide_started;
+ }
+ /* end of polling */
+ hwif->polling = 0;
+ printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n",
+ drive->name, stat);
+ /* do it the old fashioned way */
+ return do_reset1(drive, 1);
+ }
+ /* done polling */
+ hwif->polling = 0;
+ ide_complete_drive_reset(drive, 0);
+ return ide_stopped;
+}
+
+static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
+{
+ static const char *err_master_vals[] =
+ { NULL, "passed", "formatter device error",
+ "sector buffer error", "ECC circuitry error",
+ "controlling MPU error" };
+
+ u8 err_master = err & 0x7f;
+
+ printk(KERN_ERR "%s: reset: master: ", hwif->name);
+ if (err_master && err_master < 6)
+ printk(KERN_CONT "%s", err_master_vals[err_master]);
+ else
+ printk(KERN_CONT "error (0x%02x?)", err);
+ if (err & 0x80)
+ printk(KERN_CONT "; slave: failed");
+ printk(KERN_CONT "\n");
+}
+
+/*
+ * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
+ * during an ide reset operation. If the drives have not yet responded,
+ * and we have not yet hit our maximum waiting time, then the timer is restarted
+ * for another 50ms.
+ */
+static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+ u8 tmp;
+ int err = 0;
+
+ if (port_ops && port_ops->reset_poll) {
+ err = port_ops->reset_poll(drive);
+ if (err) {
+ printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
+ hwif->name, drive->name);
+ goto out;
+ }
+ }
+
+ tmp = hwif->tp_ops->read_status(hwif);
+
+ if (!OK_STAT(tmp, 0, ATA_BUSY)) {
+ if (time_before(jiffies, hwif->poll_timeout)) {
+ ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
+ /* continue polling */
+ return ide_started;
+ }
+ printk(KERN_ERR "%s: reset timed-out, status=0x%02x\n",
+ hwif->name, tmp);
+ drive->failures++;
+ err = -EIO;
+ } else {
+ tmp = ide_read_error(drive);
+
+ if (tmp == 1) {
+ printk(KERN_INFO "%s: reset: success\n", hwif->name);
+ drive->failures = 0;
+ } else {
+ ide_reset_report_error(hwif, tmp);
+ drive->failures++;
+ err = -EIO;
+ }
+ }
+out:
+ hwif->polling = 0; /* done polling */
+ ide_complete_drive_reset(drive, err);
+ return ide_stopped;
+}
+
+static void ide_disk_pre_reset(ide_drive_t *drive)
+{
+ int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
+
+ drive->special.all = 0;
+ drive->special.b.set_geometry = legacy;
+ drive->special.b.recalibrate = legacy;
+
+ drive->mult_count = 0;
+ drive->dev_flags &= ~IDE_DFLAG_PARKED;
+
+ if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
+ (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
+ drive->mult_req = 0;
+
+ if (drive->mult_req != drive->mult_count)
+ drive->special.b.set_multmode = 1;
+}
+
+static void pre_reset(ide_drive_t *drive)
+{
+ const struct ide_port_ops *port_ops = drive->hwif->port_ops;
+
+ if (drive->media == ide_disk)
+ ide_disk_pre_reset(drive);
+ else
+ drive->dev_flags |= IDE_DFLAG_POST_RESET;
+
+ if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
+ if (drive->crc_count)
+ ide_check_dma_crc(drive);
+ else
+ ide_dma_off(drive);
+ }
+
+ if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
+ if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
+ drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+ drive->io_32bit = 0;
+ }
+ return;
+ }
+
+ if (port_ops && port_ops->pre_reset)
+ port_ops->pre_reset(drive);
+
+ if (drive->current_speed != 0xff)
+ drive->desired_speed = drive->current_speed;
+ drive->current_speed = 0xff;
+}
+
+/*
+ * do_reset1() attempts to recover a confused drive by resetting it.
+ * Unfortunately, resetting a disk drive actually resets all devices on
+ * the same interface, so it can really be thought of as resetting the
+ * interface rather than resetting the drive.
+ *
+ * ATAPI devices have their own reset mechanism which allows them to be
+ * individually reset without clobbering other devices on the same interface.
+ *
+ * Unfortunately, the IDE interface does not generate an interrupt to let
+ * us know when the reset operation has finished, so we must poll for this.
+ * Equally poor, though, is the fact that this may a very long time to complete,
+ * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
+ * we set a timer to poll at 50ms intervals.
+ */
+static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ const struct ide_port_ops *port_ops;
+ ide_drive_t *tdrive;
+ unsigned long flags, timeout;
+ int i;
+ DEFINE_WAIT(wait);
+
+ spin_lock_irqsave(&hwif->lock, flags);
+
+ /* We must not reset with running handlers */
+ BUG_ON(hwif->handler != NULL);
+
+ /* For an ATAPI device, first try an ATAPI SRST. */
+ if (drive->media != ide_disk && !do_not_try_atapi) {
+ pre_reset(drive);
+ SELECT_DRIVE(drive);
+ udelay(20);
+ tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
+ ndelay(400);
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
+ __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return ide_started;
+ }
+
+ /* We must not disturb devices in the IDE_DFLAG_PARKED state. */
+ do {
+ unsigned long now;
+
+ prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
+ timeout = jiffies;
+ ide_port_for_each_present_dev(i, tdrive, hwif) {
+ if ((tdrive->dev_flags & IDE_DFLAG_PARKED) &&
+ time_after(tdrive->sleep, timeout))
+ timeout = tdrive->sleep;
+ }
+
+ now = jiffies;
+ if (time_before_eq(timeout, now))
+ break;
+
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ timeout = schedule_timeout_uninterruptible(timeout - now);
+ spin_lock_irqsave(&hwif->lock, flags);
+ } while (timeout);
+ finish_wait(&ide_park_wq, &wait);
+
+ /*
+ * First, reset any device state data we were maintaining
+ * for any of the drives on this interface.
+ */
+ ide_port_for_each_dev(i, tdrive, hwif)
+ pre_reset(tdrive);
+
+ if (io_ports->ctl_addr == 0) {
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ ide_complete_drive_reset(drive, -ENXIO);
+ return ide_stopped;
+ }
+
+ /*
+ * Note that we also set nIEN while resetting the device,
+ * to mask unwanted interrupts from the interface during the reset.
+ * However, due to the design of PC hardware, this will cause an
+ * immediate interrupt due to the edge transition it produces.
+ * This single interrupt gives us a "fast poll" for drives that
+ * recover from reset very quickly, saving us the first 50ms wait time.
+ *
+ * TODO: add ->softreset method and stop abusing ->set_irq
+ */
+ /* set SRST and nIEN */
+ tp_ops->set_irq(hwif, 4);
+ /* more than enough time */
+ udelay(10);
+ /* clear SRST, leave nIEN (unless device is on the quirk list) */
+ tp_ops->set_irq(hwif, drive->quirk_list == 2);
+ /* more than enough time */
+ udelay(10);
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
+ __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
+
+ /*
+ * Some weird controller like resetting themselves to a strange
+ * state when the disks are reset this way. At least, the Winbond
+ * 553 documentation says that
+ */
+ port_ops = hwif->port_ops;
+ if (port_ops && port_ops->resetproc)
+ port_ops->resetproc(drive);
+
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return ide_started;
+}
+
+/*
+ * ide_do_reset() is the entry point to the drive/interface reset code.
+ */
+
+ide_startstop_t ide_do_reset(ide_drive_t *drive)
+{
+ return do_reset1(drive, 0);
+}
+EXPORT_SYMBOL(ide_do_reset);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 3eab1c6c9b3..317ec62c33d 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -327,8 +327,10 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
return ide_stopped;
}
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
+ if (blk_fs_request(rq) || pc->req_xfer) {
+ ide_init_sg_cmd(drive, rq);
+ ide_map_sg(drive, rq);
+ }
pc->sg = hwif->sg_table;
pc->sg_cnt = hwif->sg_nents;
diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c
index 3ec762cb60a..fcd4d8153df 100644
--- a/drivers/ide/ide-floppy_proc.c
+++ b/drivers/ide/ide-floppy_proc.c
@@ -29,5 +29,5 @@ const struct ide_proc_devset ide_floppy_settings[] = {
IDE_PROC_DEVSET(bios_head, 0, 255),
IDE_PROC_DEVSET(bios_sect, 0, 63),
IDE_PROC_DEVSET(ticks, 0, 255),
- { 0 },
+ { NULL },
};
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 7857b209c6d..04710941990 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -25,7 +25,7 @@ module_param(debug_mask, ulong, 0644);
static DEFINE_MUTEX(ide_disk_ref_mutex);
-static void ide_disk_release(struct kref *);
+static void ide_disk_release(struct device *);
static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
{
@@ -37,7 +37,7 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
if (ide_device_get(idkp->drive))
idkp = NULL;
else
- kref_get(&idkp->kref);
+ get_device(&idkp->dev);
}
mutex_unlock(&ide_disk_ref_mutex);
return idkp;
@@ -48,7 +48,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp)
ide_drive_t *drive = idkp->drive;
mutex_lock(&ide_disk_ref_mutex);
- kref_put(&idkp->kref, ide_disk_release);
+ put_device(&idkp->dev);
ide_device_put(drive);
mutex_unlock(&ide_disk_ref_mutex);
}
@@ -66,17 +66,18 @@ static void ide_gd_remove(ide_drive_t *drive)
struct gendisk *g = idkp->disk;
ide_proc_unregister_driver(drive, idkp->driver);
-
+ device_del(&idkp->dev);
del_gendisk(g);
-
drive->disk_ops->flush(drive);
- ide_disk_put(idkp);
+ mutex_lock(&ide_disk_ref_mutex);
+ put_device(&idkp->dev);
+ mutex_unlock(&ide_disk_ref_mutex);
}
-static void ide_disk_release(struct kref *kref)
+static void ide_disk_release(struct device *dev)
{
- struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj);
+ struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
struct gendisk *g = idkp->disk;
@@ -348,7 +349,12 @@ static int ide_gd_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
- kref_init(&idkp->kref);
+ idkp->dev.parent = &drive->gendev;
+ idkp->dev.release = ide_disk_release;
+ dev_set_name(&idkp->dev, dev_name(&drive->gendev));
+
+ if (device_register(&idkp->dev))
+ goto out_free_disk;
idkp->drive = drive;
idkp->driver = &ide_gd_driver;
@@ -373,6 +379,8 @@ static int ide_gd_probe(ide_drive_t *drive)
add_disk(g);
return 0;
+out_free_disk:
+ put_disk(g);
out_free_idkp:
kfree(idkp);
failed:
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
index a86779f0756..b604bdd318a 100644
--- a/drivers/ide/ide-gd.h
+++ b/drivers/ide/ide-gd.h
@@ -17,7 +17,7 @@ struct ide_disk_obj {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
- struct kref kref;
+ struct device dev;
unsigned int openers; /* protected by BKL for now */
/* Last failed packet command */
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
new file mode 100644
index 00000000000..45b43dd49cd
--- /dev/null
+++ b/drivers/ide/ide-io-std.c
@@ -0,0 +1,316 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+/*
+ * Conventional PIO operations for ATA devices
+ */
+
+static u8 ide_inb(unsigned long port)
+{
+ return (u8) inb(port);
+}
+
+static void ide_outb(u8 val, unsigned long port)
+{
+ outb(val, port);
+}
+
+/*
+ * MMIO operations, typically used for SATA controllers
+ */
+
+static u8 ide_mm_inb(unsigned long port)
+{
+ return (u8) readb((void __iomem *) port);
+}
+
+static void ide_mm_outb(u8 value, unsigned long port)
+{
+ writeb(value, (void __iomem *) port);
+}
+
+void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
+ else
+ outb(cmd, hwif->io_ports.command_addr);
+}
+EXPORT_SYMBOL_GPL(ide_exec_command);
+
+u8 ide_read_status(ide_hwif_t *hwif)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)hwif->io_ports.status_addr);
+ else
+ return inb(hwif->io_ports.status_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_status);
+
+u8 ide_read_altstatus(ide_hwif_t *hwif)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)hwif->io_ports.ctl_addr);
+ else
+ return inb(hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_altstatus);
+
+void ide_set_irq(ide_hwif_t *hwif, int on)
+{
+ u8 ctl = ATA_DEVCTL_OBS;
+
+ if (on == 4) { /* hack for SRST */
+ ctl |= 4;
+ on &= ~4;
+ }
+
+ ctl |= on ? 0 : 2;
+
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
+ else
+ outb(ctl, hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_set_irq);
+
+void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+ void (*tf_outb)(u8 addr, unsigned long port);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+
+ if (mmio)
+ tf_outb = ide_mm_outb;
+ else
+ tf_outb = ide_outb;
+
+ if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ HIHI = 0xFF;
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
+ u16 data = (tf->hob_data << 8) | tf->data;
+
+ if (mmio)
+ writew(data, (void __iomem *)io_ports->data_addr);
+ else
+ outw(data, io_ports->data_addr);
+ }
+
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ tf_outb(tf->hob_feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ tf_outb(tf->hob_nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ tf_outb(tf->hob_lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ tf_outb(tf->hob_lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ tf_outb(tf->hob_lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ tf_outb(tf->feature, io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ tf_outb(tf->nsect, io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ tf_outb(tf->lbal, io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ tf_outb(tf->lbam, io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ tf_outb(tf->lbah, io_ports->lbah_addr);
+
+ if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ tf_outb((tf->device & HIHI) | drive->select,
+ io_ports->device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_tf_load);
+
+void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &task->tf;
+ void (*tf_outb)(u8 addr, unsigned long port);
+ u8 (*tf_inb)(unsigned long port);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ if (mmio) {
+ tf_outb = ide_mm_outb;
+ tf_inb = ide_mm_inb;
+ } else {
+ tf_outb = ide_outb;
+ tf_inb = ide_inb;
+ }
+
+ if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ u16 data;
+
+ if (mmio)
+ data = readw((void __iomem *)io_ports->data_addr);
+ else
+ data = inw(io_ports->data_addr);
+
+ tf->data = data & 0xff;
+ tf->hob_data = (data >> 8) & 0xff;
+ }
+
+ /* be sure we're looking at the low order bits */
+ tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+ tf->feature = tf_inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ tf->nsect = tf_inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ tf->lbal = tf_inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ tf->lbam = tf_inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ tf->lbah = tf_inb(io_ports->lbah_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ tf->device = tf_inb(io_ports->device_addr);
+
+ if (task->tf_flags & IDE_TFLAG_LBA48) {
+ tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ tf->hob_feature = tf_inb(io_ports->feature_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tf_inb(io_ports->nsect_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tf_inb(io_ports->lbal_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tf_inb(io_ports->lbam_addr);
+ if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tf_inb(io_ports->lbah_addr);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_tf_read);
+
+/*
+ * Some localbus EIDE interfaces require a special access sequence
+ * when using 32-bit I/O instructions to transfer data. We call this
+ * the "vlb_sync" sequence, which consists of three successive reads
+ * of the sector count register location, with interrupts disabled
+ * to ensure that the reads all happen together.
+ */
+static void ata_vlb_sync(unsigned long port)
+{
+ (void)inb(port);
+ (void)inb(port);
+ (void)inb(port);
+}
+
+/*
+ * This is used for most PIO data transfers *from* the IDE interface
+ *
+ * These routines will round up any request for an odd number of bytes,
+ * so if an odd len is specified, be sure that there's at least one
+ * extra byte allocated for the buffer.
+ */
+void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
+ unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long data_addr = io_ports->data_addr;
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ len++;
+
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
+
+ if (mmio)
+ __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
+ else
+ insl(data_addr, buf, len / 4);
+
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
+
+ if ((len & 3) >= 2) {
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr,
+ (u8 *)buf + (len & ~3), 1);
+ else
+ insw(data_addr, (u8 *)buf + (len & ~3), 1);
+ }
+ } else {
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
+ else
+ insw(data_addr, buf, len / 2);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_input_data);
+
+/*
+ * This is used for most PIO data transfers *to* the IDE interface
+ */
+void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
+ unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long data_addr = io_ports->data_addr;
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ len++;
+
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
+
+ if (mmio)
+ __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
+ else
+ outsl(data_addr, buf, len / 4);
+
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
+
+ if ((len & 3) >= 2) {
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr,
+ (u8 *)buf + (len & ~3), 1);
+ else
+ outsw(data_addr, (u8 *)buf + (len & ~3), 1);
+ }
+ } else {
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
+ else
+ outsw(data_addr, buf, len / 2);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_output_data);
+
+const struct ide_tp_ops default_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+
+ .set_irq = ide_set_irq,
+
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index cc163319dfb..2e92497b58a 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -196,7 +196,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
}
EXPORT_SYMBOL(ide_end_drive_cmd);
-static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
+void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{
if (rq->rq_disk) {
struct ide_driver *drv;
@@ -207,133 +207,6 @@ static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
ide_end_request(drive, 0, 0);
}
-static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- if ((stat & ATA_BUSY) ||
- ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else if (stat & ATA_ERR) {
- /* err has different meaning on cdrom and tape */
- if (err == ATA_ABORTED) {
- if ((drive->dev_flags & IDE_DFLAG_LBA) &&
- /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
- hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
- return ide_stopped;
- } else if ((err & BAD_CRC) == BAD_CRC) {
- /* UDMA crc error, just retry the operation */
- drive->crc_count++;
- } else if (err & (ATA_BBK | ATA_UNC)) {
- /* retries won't help these */
- rq->errors = ERROR_MAX;
- } else if (err & ATA_TRK0NF) {
- /* help it find track zero */
- rq->errors |= ERROR_RECAL;
- }
- }
-
- if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
- (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
- int nsect = drive->mult_count ? drive->mult_count : 1;
-
- ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
- }
-
- if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
- ide_kill_rq(drive, rq);
- return ide_stopped;
- }
-
- if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
- rq->errors |= ERROR_RESET;
-
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
-
- if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
-
- ++rq->errors;
-
- return ide_stopped;
-}
-
-static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- if ((stat & ATA_BUSY) ||
- ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else {
- /* add decoding error stuff */
- }
-
- if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
- /* force an abort */
- hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
-
- if (rq->errors >= ERROR_MAX) {
- ide_kill_rq(drive, rq);
- } else {
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
- ++rq->errors;
- }
-
- return ide_stopped;
-}
-
-static ide_startstop_t
-__ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
- if (drive->media == ide_disk)
- return ide_ata_error(drive, rq, stat, err);
- return ide_atapi_error(drive, rq, stat, err);
-}
-
-/**
- * ide_error - handle an error on the IDE
- * @drive: drive the error occurred on
- * @msg: message to report
- * @stat: status bits
- *
- * ide_error() takes action based on the error returned by the drive.
- * For normal I/O that may well include retries. We deal with
- * both new-style (taskfile) and old style command handling here.
- * In the case of taskfile command handling there is work left to
- * do
- */
-
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
-{
- struct request *rq;
- u8 err;
-
- err = ide_dump_status(drive, msg, stat);
-
- rq = drive->hwif->rq;
- if (rq == NULL)
- return ide_stopped;
-
- /* retry only "normal" I/O: */
- if (!blk_fs_request(rq)) {
- rq->errors = 1;
- ide_end_drive_cmd(drive, stat, err);
- return ide_stopped;
- }
-
- return __ide_error(drive, rq, stat, err);
-}
-EXPORT_SYMBOL_GPL(ide_error);
-
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
{
tf->nsect = drive->sect;
@@ -418,11 +291,14 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq)
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
- if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) {
- hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
- } else {
+ if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
hwif->sg_nents = 1;
+ } else if (!rq->bio) {
+ sg_init_one(sg, rq->data, rq->data_len);
+ hwif->sg_nents = 1;
+ } else {
+ hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
}
}
@@ -487,71 +363,16 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
return ide_stopped;
}
-int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
- int arg)
-{
- struct request_queue *q = drive->queue;
- struct request *rq;
- int ret = 0;
-
- if (!(setting->flags & DS_SYNC))
- return setting->set(drive, arg);
-
- rq = blk_get_request(q, READ, __GFP_WAIT);
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_len = 5;
- rq->cmd[0] = REQ_DEVSET_EXEC;
- *(int *)&rq->cmd[1] = arg;
- rq->special = setting->set;
-
- if (blk_execute_rq(q, NULL, rq, 0))
- ret = rq->errors;
- blk_put_request(rq);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(ide_devset_execute);
-
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
{
u8 cmd = rq->cmd[0];
- if (cmd == REQ_PARK_HEADS || cmd == REQ_UNPARK_HEADS) {
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
-
- memset(&task, 0, sizeof(task));
- if (cmd == REQ_PARK_HEADS) {
- drive->sleep = *(unsigned long *)rq->special;
- drive->dev_flags |= IDE_DFLAG_SLEEPING;
- tf->command = ATA_CMD_IDLEIMMEDIATE;
- tf->feature = 0x44;
- tf->lbal = 0x4c;
- tf->lbam = 0x4e;
- tf->lbah = 0x55;
- task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
- } else /* cmd == REQ_UNPARK_HEADS */
- tf->command = ATA_CMD_CHK_POWER;
-
- task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- task.rq = rq;
- drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA;
- return do_rw_taskfile(drive, &task);
- }
-
switch (cmd) {
+ case REQ_PARK_HEADS:
+ case REQ_UNPARK_HEADS:
+ return ide_do_park_unpark(drive, rq);
case REQ_DEVSET_EXEC:
- {
- int err, (*setfunc)(ide_drive_t *, int) = rq->special;
-
- err = setfunc(drive, *(int *)&rq->cmd[1]);
- if (err)
- rq->errors = err;
- else
- err = 1;
- ide_end_request(drive, err, 0);
- return ide_stopped;
- }
+ return ide_do_devset(drive, rq);
case REQ_DRIVE_RESET:
return ide_do_reset(drive);
default:
@@ -817,63 +638,6 @@ plug_device_2:
blk_plug_device(q);
}
-/*
- * un-busy the port etc, and clear any pending DMA status. we want to
- * retry the current request in pio mode instead of risking tossing it
- * all away
- */
-static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq;
- ide_startstop_t ret = ide_stopped;
-
- /*
- * end current dma transaction
- */
-
- if (error < 0) {
- printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
- (void)hwif->dma_ops->dma_end(drive);
- ret = ide_error(drive, "dma timeout error",
- hwif->tp_ops->read_status(hwif));
- } else {
- printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
- hwif->dma_ops->dma_timeout(drive);
- }
-
- /*
- * disable dma for now, but remember that we did so because of
- * a timeout -- we'll reenable after we finish this next request
- * (or rather the first chunk of it) in pio.
- */
- drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY;
- drive->retry_pio++;
- ide_dma_off_quietly(drive);
-
- /*
- * un-busy drive etc and make sure request is sane
- */
-
- rq = hwif->rq;
- if (!rq)
- goto out;
-
- hwif->rq = NULL;
-
- rq->errors = 0;
-
- if (!rq->bio)
- goto out;
-
- rq->sector = rq->bio->bi_sector;
- rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->buffer = bio_data(rq->bio);
-out:
- return ret;
-}
-
static void ide_plug_device(ide_drive_t *drive)
{
struct request_queue *q = drive->queue;
@@ -885,6 +649,29 @@ static void ide_plug_device(ide_drive_t *drive)
spin_unlock_irqrestore(q->queue_lock, flags);
}
+static int drive_is_ready(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 stat = 0;
+
+ if (drive->waiting_for_dma)
+ return hwif->dma_ops->dma_test_irq(drive);
+
+ if (hwif->io_ports.ctl_addr &&
+ (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
+ stat = hwif->tp_ops->read_altstatus(hwif);
+ else
+ /* Note: this may clear a pending IRQ!! */
+ stat = hwif->tp_ops->read_status(hwif);
+
+ if (stat & ATA_BUSY)
+ /* drive busy: definitely not interrupting */
+ return 0;
+
+ /* drive ready: *might* be interrupting */
+ return 1;
+}
+
/**
* ide_timer_expiry - handle lack of an IDE interrupt
* @data: timer callback magic (hwif)
@@ -905,7 +692,7 @@ void ide_timer_expiry (unsigned long data)
ide_drive_t *uninitialized_var(drive);
ide_handler_t *handler;
unsigned long flags;
- unsigned long wait = -1;
+ int wait = -1;
int plug_device = 0;
spin_lock_irqsave(&hwif->lock, flags);
@@ -1159,54 +946,7 @@ out_early:
return irq_ret;
}
-
-/**
- * ide_do_drive_cmd - issue IDE special command
- * @drive: device to issue command
- * @rq: request to issue
- *
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * the rq is queued at the head of the request queue, displacing
- * the currently-being-processed request and this function
- * returns immediately without waiting for the new rq to be
- * completed. This is VERY DANGEROUS, and is intended for
- * careful use by the ATAPI tape/cdrom driver code.
- */
-
-void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
-{
- struct request_queue *q = drive->queue;
- unsigned long flags;
-
- drive->hwif->rq = NULL;
-
- spin_lock_irqsave(q->queue_lock, flags);
- __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
- spin_unlock_irqrestore(q->queue_lock, flags);
-}
-EXPORT_SYMBOL(ide_do_drive_cmd);
-
-void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
-{
- ide_hwif_t *hwif = drive->hwif;
- ide_task_t task;
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
- IDE_TFLAG_OUT_FEATURE | tf_flags;
- task.tf.feature = dma; /* Use PIO/DMA */
- task.tf.lbam = bcount & 0xff;
- task.tf.lbah = (bcount >> 8) & 0xff;
-
- ide_tf_dump(drive->name, &task.tf);
- hwif->tp_ops->set_irq(hwif, 1);
- SELECT_MASK(drive, 0);
- hwif->tp_ops->tf_load(drive, &task);
-}
-
-EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
+EXPORT_SYMBOL_GPL(ide_intr);
void ide_pad_transfer(ide_drive_t *drive, int write, int len)
{
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 753b92ebe0a..317c5dadd7c 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -27,35 +27,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-/*
- * Conventional PIO operations for ATA devices
- */
-
-static u8 ide_inb (unsigned long port)
-{
- return (u8) inb(port);
-}
-
-static void ide_outb (u8 val, unsigned long port)
-{
- outb(val, port);
-}
-
-/*
- * MMIO operations, typically used for SATA controllers
- */
-
-static u8 ide_mm_inb (unsigned long port)
-{
- return (u8) readb((void __iomem *) port);
-}
-
-static void ide_mm_outb (u8 value, unsigned long port)
-{
- writeb(value, (void __iomem *) port);
-}
-
-void SELECT_DRIVE (ide_drive_t *drive)
+void SELECT_DRIVE(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
@@ -78,275 +50,6 @@ void SELECT_MASK(ide_drive_t *drive, int mask)
port_ops->maskproc(drive, mask);
}
-void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
- else
- outb(cmd, hwif->io_ports.command_addr);
-}
-EXPORT_SYMBOL_GPL(ide_exec_command);
-
-u8 ide_read_status(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)hwif->io_ports.status_addr);
- else
- return inb(hwif->io_ports.status_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_status);
-
-u8 ide_read_altstatus(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)hwif->io_ports.ctl_addr);
- else
- return inb(hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_altstatus);
-
-void ide_set_irq(ide_hwif_t *hwif, int on)
-{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
- else
- outb(ctl, hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_set_irq);
-
-void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
- if (mmio)
- tf_outb = ide_mm_outb;
- else
- tf_outb = ide_outb;
-
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- if (mmio)
- writew(data, (void __iomem *)io_ports->data_addr);
- else
- outw(data, io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- tf_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- tf_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- tf_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- tf_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- tf_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
- tf_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
- tf_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
- tf_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
- tf_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
- tf_outb(tf->lbah, io_ports->lbah_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tf_outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
-}
-EXPORT_SYMBOL_GPL(ide_tf_load);
-
-void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
- u8 (*tf_inb)(unsigned long port);
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- if (mmio) {
- tf_outb = ide_mm_outb;
- tf_inb = ide_mm_inb;
- } else {
- tf_outb = ide_outb;
- tf_inb = ide_inb;
- }
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- if (mmio)
- data = readw((void __iomem *)io_ports->data_addr);
- else
- data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
- /* be sure we're looking at the low order bits */
- tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = tf_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = tf_inb(io_ports->device_addr);
-
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tf_inb(io_ports->lbah_addr);
- }
-}
-EXPORT_SYMBOL_GPL(ide_tf_read);
-
-/*
- * Some localbus EIDE interfaces require a special access sequence
- * when using 32-bit I/O instructions to transfer data. We call this
- * the "vlb_sync" sequence, which consists of three successive reads
- * of the sector count register location, with interrupts disabled
- * to ensure that the reads all happen together.
- */
-static void ata_vlb_sync(unsigned long port)
-{
- (void)inb(port);
- (void)inb(port);
- (void)inb(port);
-}
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd len is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
- unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned long data_addr = io_ports->data_addr;
- u8 io_32bit = drive->io_32bit;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- len++;
-
- if (io_32bit) {
- unsigned long uninitialized_var(flags);
-
- if ((io_32bit & 2) && !mmio) {
- local_irq_save(flags);
- ata_vlb_sync(io_ports->nsect_addr);
- }
-
- if (mmio)
- __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
- else
- insl(data_addr, buf, len / 4);
-
- if ((io_32bit & 2) && !mmio)
- local_irq_restore(flags);
-
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- insw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
- else
- insw(data_addr, buf, len / 2);
- }
-}
-EXPORT_SYMBOL_GPL(ide_input_data);
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
- unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned long data_addr = io_ports->data_addr;
- u8 io_32bit = drive->io_32bit;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- if (io_32bit) {
- unsigned long uninitialized_var(flags);
-
- if ((io_32bit & 2) && !mmio) {
- local_irq_save(flags);
- ata_vlb_sync(io_ports->nsect_addr);
- }
-
- if (mmio)
- __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
- else
- outsl(data_addr, buf, len / 4);
-
- if ((io_32bit & 2) && !mmio)
- local_irq_restore(flags);
-
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- outsw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
- else
- outsw(data_addr, buf, len / 2);
- }
-}
-EXPORT_SYMBOL_GPL(ide_output_data);
-
u8 ide_read_error(ide_drive_t *drive)
{
ide_task_t task;
@@ -360,35 +63,6 @@ u8 ide_read_error(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_read_error);
-void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
-{
- ide_task_t task;
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
- IDE_TFLAG_IN_NSECT;
-
- drive->hwif->tp_ops->tf_read(drive, &task);
-
- *bcount = (task.tf.lbah << 8) | task.tf.lbam;
- *ireason = task.tf.nsect & 3;
-}
-EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
-
-const struct ide_tp_ops default_tp_ops = {
- .exec_command = ide_exec_command,
- .read_status = ide_read_status,
- .read_altstatus = ide_read_altstatus,
-
- .set_irq = ide_set_irq,
-
- .tf_load = ide_tf_load,
- .tf_read = ide_tf_read,
-
- .input_data = ide_input_data,
- .output_data = ide_output_data,
-};
-
void ide_fix_driveid(u16 *id)
{
#ifndef __LITTLE_ENDIAN
@@ -410,7 +84,7 @@ void ide_fix_driveid(u16 *id)
* returned by the ATA_CMD_ID_ATA[PI] commands.
*/
-void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
+void ide_fixstring(u8 *s, const int bytecount, const int byteswap)
{
u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */
@@ -433,44 +107,9 @@ void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
while (p != end)
*p++ = '\0';
}
-
EXPORT_SYMBOL(ide_fixstring);
/*
- * Needed for PCI irq sharing
- */
-int drive_is_ready (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 stat = 0;
-
- if (drive->waiting_for_dma)
- return hwif->dma_ops->dma_test_irq(drive);
-
- /*
- * We do a passive status test under shared PCI interrupts on
- * cards that truly share the ATA side interrupt, but may also share
- * an interrupt with another pci card/device. We make no assumptions
- * about possible isa-pnp and pci-pnp issues yet.
- */
- if (hwif->io_ports.ctl_addr &&
- (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
- stat = hwif->tp_ops->read_altstatus(hwif);
- else
- /* Note: this may clear a pending IRQ!! */
- stat = hwif->tp_ops->read_status(hwif);
-
- if (stat & ATA_BUSY)
- /* drive busy: definitely not interrupting */
- return 0;
-
- /* drive ready: *might* be interrupting */
- return 1;
-}
-
-EXPORT_SYMBOL(drive_is_ready);
-
-/*
* This routine busy-waits for the drive status to be not "busy".
* It then checks the status for all of the "good" bits and none
* of the "bad" bits, and if all is okay it returns 0. All other
@@ -481,7 +120,8 @@ EXPORT_SYMBOL(drive_is_ready);
* setting a timer to wake up at half second intervals thereafter,
* until timeout is achieved, before timing out.
*/
-static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
+static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
+ unsigned long timeout, u8 *rstat)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
@@ -539,7 +179,8 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti
* The caller should return the updated value of "startstop" in this case,
* "startstop" is unchanged when the function returns 0.
*/
-int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout)
+int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good,
+ u8 bad, unsigned long timeout)
{
int err;
u8 stat;
@@ -559,7 +200,6 @@ int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 ba
return err;
}
-
EXPORT_SYMBOL(ide_wait_stat);
/**
@@ -580,7 +220,6 @@ int ide_in_drive_list(u16 *id, const struct drive_list_entry *table)
return 1;
return 0;
}
-
EXPORT_SYMBOL_GPL(ide_in_drive_list);
/*
@@ -605,7 +244,7 @@ static const struct drive_list_entry ivb_list[] = {
* All hosts that use the 80c ribbon must use!
* The name is derived from upper byte of word 93 and the 80c ribbon.
*/
-u8 eighty_ninty_three (ide_drive_t *drive)
+u8 eighty_ninty_three(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u16 *id = drive->id;
@@ -650,47 +289,19 @@ no_80w:
int ide_driveid_update(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
u16 *id;
- unsigned long flags;
- u8 stat;
-
- /*
- * Re-read drive->id for possible DMA mode
- * change (copied from ide-probe.c)
- */
+ int rc;
- SELECT_MASK(drive, 1);
- tp_ops->set_irq(hwif, 0);
- msleep(50);
- tp_ops->exec_command(hwif, ATA_CMD_ID_ATA);
-
- if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) {
- SELECT_MASK(drive, 0);
+ id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
+ if (id == NULL)
return 0;
- }
-
- msleep(50); /* wait for IRQ and ATA_DRQ */
- stat = tp_ops->read_status(hwif);
- if (!OK_STAT(stat, ATA_DRQ, BAD_R_STAT)) {
- SELECT_MASK(drive, 0);
- printk("%s: CHECK for good STATUS\n", drive->name);
- return 0;
- }
- local_irq_save(flags);
+ SELECT_MASK(drive, 1);
+ rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id);
SELECT_MASK(drive, 0);
- id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
- if (!id) {
- local_irq_restore(flags);
- return 0;
- }
- tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
- (void)tp_ops->read_status(hwif); /* clear drive IRQ */
- local_irq_enable();
- local_irq_restore(flags);
- ide_fix_driveid(id);
+
+ if (rc)
+ goto out_err;
drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES];
drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
@@ -703,6 +314,12 @@ int ide_driveid_update(ide_drive_t *drive)
ide_dma_off(drive);
return 1;
+out_err:
+ SELECT_MASK(drive, 0);
+ if (rc == 2)
+ printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__);
+ kfree(id);
+ return 0;
}
int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
@@ -729,18 +346,15 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
* but for some reason these don't work at
* this point (lost interrupt).
*/
- /*
- * Select the drive, and issue the SETFEATURES command
- */
- disable_irq_nosync(hwif->irq);
-
+
/*
* FIXME: we race against the running IRQ here if
* this is called from non IRQ context. If we use
* disable_irq() we hang on the error path. Work
* is needed.
*/
-
+ disable_irq_nosync(hwif->irq);
+
udelay(1);
SELECT_DRIVE(drive);
SELECT_MASK(drive, 1);
@@ -810,8 +424,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
*
* See also ide_execute_command
*/
-static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
- unsigned int timeout, ide_expiry_t *expiry)
+void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+ unsigned int timeout, ide_expiry_t *expiry)
{
ide_hwif_t *hwif = drive->hwif;
@@ -833,9 +447,8 @@ void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
__ide_set_handler(drive, handler, timeout, expiry);
spin_unlock_irqrestore(&hwif->lock, flags);
}
-
EXPORT_SYMBOL(ide_set_handler);
-
+
/**
* ide_execute_command - execute an IDE command
* @drive: IDE drive to issue the command against
@@ -845,7 +458,7 @@ EXPORT_SYMBOL(ide_set_handler);
* @expiry: handler to run on timeout
*
* Helper function to issue an IDE command. This handles the
- * atomicity requirements, command timing and ensures that the
+ * atomicity requirements, command timing and ensures that the
* handler and IRQ setup do not race. All IDE command kick off
* should go via this function or do equivalent locking.
*/
@@ -882,301 +495,6 @@ void ide_execute_pkt_cmd(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
-static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
-{
- struct request *rq = drive->hwif->rq;
-
- if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
- ide_end_request(drive, err ? err : 1, 0);
-}
-
-/* needed below */
-static ide_startstop_t do_reset1 (ide_drive_t *, int);
-
-/*
- * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an atapi drive reset operation. If the drive has not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 stat;
-
- SELECT_DRIVE(drive);
- udelay (10);
- stat = hwif->tp_ops->read_status(hwif);
-
- if (OK_STAT(stat, 0, ATA_BUSY))
- printk("%s: ATAPI reset complete\n", drive->name);
- else {
- if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
- /* continue polling */
- return ide_started;
- }
- /* end of polling */
- hwif->polling = 0;
- printk("%s: ATAPI reset timed-out, status=0x%02x\n",
- drive->name, stat);
- /* do it the old fashioned way */
- return do_reset1(drive, 1);
- }
- /* done polling */
- hwif->polling = 0;
- ide_complete_drive_reset(drive, 0);
- return ide_stopped;
-}
-
-static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
-{
- static const char *err_master_vals[] =
- { NULL, "passed", "formatter device error",
- "sector buffer error", "ECC circuitry error",
- "controlling MPU error" };
-
- u8 err_master = err & 0x7f;
-
- printk(KERN_ERR "%s: reset: master: ", hwif->name);
- if (err_master && err_master < 6)
- printk(KERN_CONT "%s", err_master_vals[err_master]);
- else
- printk(KERN_CONT "error (0x%02x?)", err);
- if (err & 0x80)
- printk(KERN_CONT "; slave: failed");
- printk(KERN_CONT "\n");
-}
-
-/*
- * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an ide reset operation. If the drives have not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- u8 tmp;
- int err = 0;
-
- if (port_ops && port_ops->reset_poll) {
- err = port_ops->reset_poll(drive);
- if (err) {
- printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
- hwif->name, drive->name);
- goto out;
- }
- }
-
- tmp = hwif->tp_ops->read_status(hwif);
-
- if (!OK_STAT(tmp, 0, ATA_BUSY)) {
- if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
- /* continue polling */
- return ide_started;
- }
- printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
- drive->failures++;
- err = -EIO;
- } else {
- tmp = ide_read_error(drive);
-
- if (tmp == 1) {
- printk(KERN_INFO "%s: reset: success\n", hwif->name);
- drive->failures = 0;
- } else {
- ide_reset_report_error(hwif, tmp);
- drive->failures++;
- err = -EIO;
- }
- }
-out:
- hwif->polling = 0; /* done polling */
- ide_complete_drive_reset(drive, err);
- return ide_stopped;
-}
-
-static void ide_disk_pre_reset(ide_drive_t *drive)
-{
- int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
-
- drive->special.all = 0;
- drive->special.b.set_geometry = legacy;
- drive->special.b.recalibrate = legacy;
-
- drive->mult_count = 0;
- drive->dev_flags &= ~IDE_DFLAG_PARKED;
-
- if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
- (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
- drive->mult_req = 0;
-
- if (drive->mult_req != drive->mult_count)
- drive->special.b.set_multmode = 1;
-}
-
-static void pre_reset(ide_drive_t *drive)
-{
- const struct ide_port_ops *port_ops = drive->hwif->port_ops;
-
- if (drive->media == ide_disk)
- ide_disk_pre_reset(drive);
- else
- drive->dev_flags |= IDE_DFLAG_POST_RESET;
-
- if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
- if (drive->crc_count)
- ide_check_dma_crc(drive);
- else
- ide_dma_off(drive);
- }
-
- if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
- drive->dev_flags &= ~IDE_DFLAG_UNMASK;
- drive->io_32bit = 0;
- }
- return;
- }
-
- if (port_ops && port_ops->pre_reset)
- port_ops->pre_reset(drive);
-
- if (drive->current_speed != 0xff)
- drive->desired_speed = drive->current_speed;
- drive->current_speed = 0xff;
-}
-
-/*
- * do_reset1() attempts to recover a confused drive by resetting it.
- * Unfortunately, resetting a disk drive actually resets all devices on
- * the same interface, so it can really be thought of as resetting the
- * interface rather than resetting the drive.
- *
- * ATAPI devices have their own reset mechanism which allows them to be
- * individually reset without clobbering other devices on the same interface.
- *
- * Unfortunately, the IDE interface does not generate an interrupt to let
- * us know when the reset operation has finished, so we must poll for this.
- * Equally poor, though, is the fact that this may a very long time to complete,
- * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
- * we set a timer to poll at 50ms intervals.
- */
-static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- const struct ide_port_ops *port_ops;
- ide_drive_t *tdrive;
- unsigned long flags, timeout;
- int i;
- DEFINE_WAIT(wait);
-
- spin_lock_irqsave(&hwif->lock, flags);
-
- /* We must not reset with running handlers */
- BUG_ON(hwif->handler != NULL);
-
- /* For an ATAPI device, first try an ATAPI SRST. */
- if (drive->media != ide_disk && !do_not_try_atapi) {
- pre_reset(drive);
- SELECT_DRIVE(drive);
- udelay (20);
- tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
- ndelay(400);
- hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwif->polling = 1;
- __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
- spin_unlock_irqrestore(&hwif->lock, flags);
- return ide_started;
- }
-
- /* We must not disturb devices in the IDE_DFLAG_PARKED state. */
- do {
- unsigned long now;
-
- prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
- timeout = jiffies;
- ide_port_for_each_dev(i, tdrive, hwif) {
- if (tdrive->dev_flags & IDE_DFLAG_PRESENT &&
- tdrive->dev_flags & IDE_DFLAG_PARKED &&
- time_after(tdrive->sleep, timeout))
- timeout = tdrive->sleep;
- }
-
- now = jiffies;
- if (time_before_eq(timeout, now))
- break;
-
- spin_unlock_irqrestore(&hwif->lock, flags);
- timeout = schedule_timeout_uninterruptible(timeout - now);
- spin_lock_irqsave(&hwif->lock, flags);
- } while (timeout);
- finish_wait(&ide_park_wq, &wait);
-
- /*
- * First, reset any device state data we were maintaining
- * for any of the drives on this interface.
- */
- ide_port_for_each_dev(i, tdrive, hwif)
- pre_reset(tdrive);
-
- if (io_ports->ctl_addr == 0) {
- spin_unlock_irqrestore(&hwif->lock, flags);
- ide_complete_drive_reset(drive, -ENXIO);
- return ide_stopped;
- }
-
- /*
- * Note that we also set nIEN while resetting the device,
- * to mask unwanted interrupts from the interface during the reset.
- * However, due to the design of PC hardware, this will cause an
- * immediate interrupt due to the edge transition it produces.
- * This single interrupt gives us a "fast poll" for drives that
- * recover from reset very quickly, saving us the first 50ms wait time.
- *
- * TODO: add ->softreset method and stop abusing ->set_irq
- */
- /* set SRST and nIEN */
- tp_ops->set_irq(hwif, 4);
- /* more than enough time */
- udelay(10);
- /* clear SRST, leave nIEN (unless device is on the quirk list) */
- tp_ops->set_irq(hwif, drive->quirk_list == 2);
- /* more than enough time */
- udelay(10);
- hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwif->polling = 1;
- __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
-
- /*
- * Some weird controller like resetting themselves to a strange
- * state when the disks are reset this way. At least, the Winbond
- * 553 documentation says that
- */
- port_ops = hwif->port_ops;
- if (port_ops && port_ops->resetproc)
- port_ops->resetproc(drive);
-
- spin_unlock_irqrestore(&hwif->lock, flags);
- return ide_started;
-}
-
-/*
- * ide_do_reset() is the entry point to the drive/interface reset code.
- */
-
-ide_startstop_t ide_do_reset (ide_drive_t *drive)
-{
- return do_reset1(drive, 0);
-}
-
-EXPORT_SYMBOL(ide_do_reset);
-
/*
* ide_wait_not_busy() waits for the currently selected device on the hwif
* to report a non-busy status, see comments in ide_probe_port().
@@ -1185,7 +503,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
{
u8 stat = 0;
- while(timeout--) {
+ while (timeout--) {
/*
* Turn this into a schedule() sleep once I'm sure
* about locking issues (2.5 work ?).
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 09526a0de73..f6c683dd298 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -5,163 +5,6 @@
#include <linux/ide.h>
#include <linux/bitops.h>
-static const char *udma_str[] =
- { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
- "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
-static const char *mwdma_str[] =
- { "MWDMA0", "MWDMA1", "MWDMA2" };
-static const char *swdma_str[] =
- { "SWDMA0", "SWDMA1", "SWDMA2" };
-static const char *pio_str[] =
- { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
-
-/**
- * ide_xfer_verbose - return IDE mode names
- * @mode: transfer mode
- *
- * Returns a constant string giving the name of the mode
- * requested.
- */
-
-const char *ide_xfer_verbose(u8 mode)
-{
- const char *s;
- u8 i = mode & 0xf;
-
- if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
- s = udma_str[i];
- else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
- s = mwdma_str[i];
- else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
- s = swdma_str[i];
- else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
- s = pio_str[i & 0x7];
- else if (mode == XFER_PIO_SLOW)
- s = "PIO SLOW";
- else
- s = "XFER ERROR";
-
- return s;
-}
-EXPORT_SYMBOL(ide_xfer_verbose);
-
-/**
- * ide_rate_filter - filter transfer mode
- * @drive: IDE device
- * @speed: desired speed
- *
- * Given the available transfer modes this function returns
- * the best available speed at or below the speed requested.
- *
- * TODO: check device PIO capabilities
- */
-
-static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 mode = ide_find_dma_mode(drive, speed);
-
- if (mode == 0) {
- if (hwif->pio_mask)
- mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
- else
- mode = XFER_PIO_4;
- }
-
-/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
-
- return min(speed, mode);
-}
-
-/**
- * ide_get_best_pio_mode - get PIO mode from drive
- * @drive: drive to consider
- * @mode_wanted: preferred mode
- * @max_mode: highest allowed mode
- *
- * This routine returns the recommended PIO settings for a given drive,
- * based on the drive->id information and the ide_pio_blacklist[].
- *
- * Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
- * This is used by most chipset support modules when "auto-tuning".
- */
-
-u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
-{
- u16 *id = drive->id;
- int pio_mode = -1, overridden = 0;
-
- if (mode_wanted != 255)
- return min_t(u8, mode_wanted, max_mode);
-
- if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
- pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
-
- if (pio_mode != -1) {
- printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
- } else {
- pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
- if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
- pio_mode = 2;
- overridden = 1;
- }
-
- if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
- if (ata_id_has_iordy(id)) {
- if (id[ATA_ID_PIO_MODES] & 7) {
- overridden = 0;
- if (id[ATA_ID_PIO_MODES] & 4)
- pio_mode = 5;
- else if (id[ATA_ID_PIO_MODES] & 2)
- pio_mode = 4;
- else
- pio_mode = 3;
- }
- }
- }
-
- if (overridden)
- printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
- drive->name);
- }
-
- if (pio_mode > max_mode)
- pio_mode = max_mode;
-
- return pio_mode;
-}
-EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
-
-/* req_pio == "255" for auto-tune */
-void ide_set_pio(ide_drive_t *drive, u8 req_pio)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- u8 host_pio, pio;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return;
-
- BUG_ON(hwif->pio_mask == 0x00);
-
- host_pio = fls(hwif->pio_mask) - 1;
-
- pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
-
- /*
- * TODO:
- * - report device max PIO mode
- * - check req_pio != 255 against device max PIO mode
- */
- printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
- drive->name, host_pio, req_pio,
- req_pio == 255 ? "(auto-tune)" : "", pio);
-
- (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
-}
-EXPORT_SYMBOL_GPL(ide_set_pio);
-
/**
* ide_toggle_bounce - handle bounce buffering
* @drive: drive to update
@@ -188,89 +31,6 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
blk_queue_bounce_limit(drive->queue, addr);
}
-int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
- return 0;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL)
- return -1;
-
- /*
- * TODO: temporary hack for some legacy host drivers that didn't
- * set transfer mode on the device in ->set_pio_mode method...
- */
- if (port_ops->set_dma_mode == NULL) {
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return 0;
- }
-
- if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
- if (ide_config_drive_speed(drive, mode))
- return -1;
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return 0;
- } else {
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return ide_config_drive_speed(drive, mode);
- }
-}
-
-int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
- return 0;
-
- if (port_ops == NULL || port_ops->set_dma_mode == NULL)
- return -1;
-
- if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
- if (ide_config_drive_speed(drive, mode))
- return -1;
- port_ops->set_dma_mode(drive, mode);
- return 0;
- } else {
- port_ops->set_dma_mode(drive, mode);
- return ide_config_drive_speed(drive, mode);
- }
-}
-EXPORT_SYMBOL_GPL(ide_set_dma_mode);
-
-/**
- * ide_set_xfer_rate - set transfer rate
- * @drive: drive to set
- * @rate: speed to attempt to set
- *
- * General helper for setting the speed of an IDE device. This
- * function knows about user enforced limits from the configuration
- * which ->set_pio_mode/->set_dma_mode does not.
- */
-
-int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return -1;
-
- rate = ide_rate_filter(drive, rate);
-
- BUG_ON(rate < XFER_PIO_0);
-
- if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
- return ide_set_pio_mode(drive, rate);
-
- return ide_set_dma_mode(drive, rate);
-}
-
static void ide_dump_opcode(ide_drive_t *drive)
{
struct request *rq = drive->hwif->rq;
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index c875a957596..f30e52152fc 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -1,5 +1,6 @@
#include <linux/kernel.h>
#include <linux/ide.h>
+#include <linux/hdreg.h>
#include <linux/jiffies.h>
#include <linux/blkdev.h>
@@ -60,6 +61,30 @@ out:
return;
}
+ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
+{
+ ide_task_t task;
+ struct ide_taskfile *tf = &task.tf;
+
+ memset(&task, 0, sizeof(task));
+ if (rq->cmd[0] == REQ_PARK_HEADS) {
+ drive->sleep = *(unsigned long *)rq->special;
+ drive->dev_flags |= IDE_DFLAG_SLEEPING;
+ tf->command = ATA_CMD_IDLEIMMEDIATE;
+ tf->feature = 0x44;
+ tf->lbal = 0x4c;
+ tf->lbam = 0x4e;
+ tf->lbah = 0x55;
+ task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
+ } else /* cmd == REQ_UNPARK_HEADS */
+ tf->command = ATA_CMD_CHK_POWER;
+
+ task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ task.rq = rq;
+ drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA;
+ return do_rw_taskfile(drive, &task);
+}
+
ssize_t ide_park_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c
index bddae2b329a..61111fd2713 100644
--- a/drivers/ide/ide-pci-generic.c
+++ b/drivers/ide/ide-pci-generic.c
@@ -33,8 +33,6 @@ static int ide_generic_all; /* Set to claim all devices */
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
-#define IDE_HFLAGS_UMC (IDE_HFLAG_NO_DMA | IDE_HFLAG_FORCE_LEGACY_IRQS)
-
#define DECLARE_GENERIC_PCI_DEV(extra_flags) \
{ \
.name = DRV_NAME, \
@@ -61,7 +59,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
/* 2: SAMURAI / HT6565 / HINT_IDE */
DECLARE_GENERIC_PCI_DEV(0),
/* 3: UM8673F / UM8886A / UM8886BF */
- DECLARE_GENERIC_PCI_DEV(IDE_HFLAGS_UMC),
+ DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_DMA),
/* 4: VIA_IDE / OPTI621V / Piccolo010{2,3,5} */
DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_AUTODMA),
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 312127ea443..974067043fb 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -181,16 +181,16 @@ static void ide_classify_atapi_dev(ide_drive_t *drive)
* do_identify - identify a drive
* @drive: drive to identify
* @cmd: command used
+ * @id: buffer for IDENTIFY data
*
* Called when we have issued a drive identify command to
* read and parse the results. This function is run with
* interrupts disabled.
*/
-static void do_identify(ide_drive_t *drive, u8 cmd)
+static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
{
ide_hwif_t *hwif = drive->hwif;
- u16 *id = drive->id;
char *m = (char *)&id[ATA_ID_PROD];
unsigned long flags;
int bswap = 1;
@@ -233,16 +233,6 @@ static void do_identify(ide_drive_t *drive, u8 cmd)
drive->dev_flags |= IDE_DFLAG_PRESENT;
drive->dev_flags &= ~IDE_DFLAG_DEAD;
- /*
- * Check for an ATAPI device
- */
- if (cmd == ATA_CMD_ID_ATAPI)
- ide_classify_atapi_dev(drive);
- else
- /*
- * Not an ATAPI device: looks like a "regular" hard disk
- */
- ide_classify_ata_dev(drive);
return;
err_misc:
kfree(id);
@@ -250,21 +240,19 @@ err_misc:
}
/**
- * actual_try_to_identify - send ata/atapi identify
+ * ide_dev_read_id - send ATA/ATAPI IDENTIFY command
* @drive: drive to identify
* @cmd: command to use
+ * @id: buffer for IDENTIFY data
*
- * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive
- * and waits for a response. It also monitors irqs while this is
- * happening, in hope of automatically determining which one is
- * being used by the interface.
+ * Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
*
* Returns: 0 device was identified
* 1 device timed-out (no response to identify request)
* 2 device aborted the command (refused to identify itself)
*/
-static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
+int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -273,6 +261,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
unsigned long timeout;
u8 s = 0, a = 0;
+ /*
+ * Disable device IRQ. Otherwise we'll get spurious interrupts
+ * during the identify phase that the IRQ handler isn't expecting.
+ */
+ if (io_ports->ctl_addr)
+ tp_ops->set_irq(hwif, 0);
+
/* take a deep breath */
msleep(50);
@@ -317,7 +312,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
/* drive returned ID */
- do_identify(drive, cmd);
+ do_identify(drive, cmd, id);
/* drive responded with ID */
rc = 0;
/* clear drive IRQ */
@@ -329,63 +324,6 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
return rc;
}
-/**
- * try_to_identify - try to identify a drive
- * @drive: drive to probe
- * @cmd: command to use
- *
- * Issue the identify command and then do IRQ probing to
- * complete the identification when needed by finding the
- * IRQ the drive is attached to
- */
-
-static int try_to_identify (ide_drive_t *drive, u8 cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- int retval;
- int autoprobe = 0;
- unsigned long cookie = 0;
-
- /*
- * Disable device irq unless we need to
- * probe for it. Otherwise we'll get spurious
- * interrupts during the identify-phase that
- * the irq handler isn't expecting.
- */
- if (hwif->io_ports.ctl_addr) {
- if (!hwif->irq) {
- autoprobe = 1;
- cookie = probe_irq_on();
- }
- tp_ops->set_irq(hwif, autoprobe);
- }
-
- retval = actual_try_to_identify(drive, cmd);
-
- if (autoprobe) {
- int irq;
-
- tp_ops->set_irq(hwif, 0);
- /* clear drive IRQ */
- (void)tp_ops->read_status(hwif);
- udelay(5);
- irq = probe_irq_off(cookie);
- if (!hwif->irq) {
- if (irq > 0) {
- hwif->irq = irq;
- } else {
- /* Mmmm.. multiple IRQs..
- * don't know which was ours
- */
- printk(KERN_ERR "%s: IRQ probe failed (0x%lx)\n",
- drive->name, cookie);
- }
- }
- }
- return retval;
-}
-
int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
{
u8 stat;
@@ -440,6 +378,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ u16 *id = drive->id;
int rc;
u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
@@ -475,11 +414,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
present || cmd == ATA_CMD_ID_ATAPI) {
- /* send cmd and wait */
- if ((rc = try_to_identify(drive, cmd))) {
+ rc = ide_dev_read_id(drive, cmd, id);
+ if (rc)
/* failed: try again */
- rc = try_to_identify(drive,cmd);
- }
+ rc = ide_dev_read_id(drive, cmd, id);
stat = tp_ops->read_status(hwif);
@@ -494,7 +432,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
- rc = try_to_identify(drive, cmd);
+ rc = ide_dev_read_id(drive, cmd, id);
}
/* ensure drive IRQ is clear */
@@ -517,37 +455,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
return rc;
}
-/*
- *
- */
-static void enable_nest (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- u8 stat;
-
- printk(KERN_INFO "%s: enabling %s -- ",
- hwif->name, (char *)&drive->id[ATA_ID_PROD]);
-
- SELECT_DRIVE(drive);
- msleep(50);
- tp_ops->exec_command(hwif, ATA_EXABYTE_ENABLE_NEST);
-
- if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 0)) {
- printk(KERN_CONT "failed (timeout)\n");
- return;
- }
-
- msleep(50);
-
- stat = tp_ops->read_status(hwif);
-
- if (!OK_STAT(stat, 0, BAD_STAT))
- printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
- else
- printk(KERN_CONT "success\n");
-}
-
/**
* probe_for_drives - upper level drive probe
* @drive: drive to probe for
@@ -563,6 +470,8 @@ static void enable_nest (ide_drive_t *drive)
static u8 probe_for_drive(ide_drive_t *drive)
{
char *m;
+ int rc;
+ u8 cmd;
/*
* In order to keep things simple we have an id
@@ -586,21 +495,19 @@ static u8 probe_for_drive(ide_drive_t *drive)
/* skip probing? */
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) {
-retry:
/* if !(success||timed-out) */
- if (do_probe(drive, ATA_CMD_ID_ATA) >= 2)
+ cmd = ATA_CMD_ID_ATA;
+ rc = do_probe(drive, cmd);
+ if (rc >= 2) {
/* look for ATAPI device */
- (void)do_probe(drive, ATA_CMD_ID_ATAPI);
+ cmd = ATA_CMD_ID_ATAPI;
+ rc = do_probe(drive, cmd);
+ }
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
/* drive not found */
return 0;
- if (strstr(m, "E X A B Y T E N E S T")) {
- enable_nest(drive);
- goto retry;
- }
-
/* identification failed? */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
if (drive->media == ide_disk) {
@@ -614,8 +521,12 @@ retry:
printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name);
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
}
+ } else {
+ if (cmd == ATA_CMD_ID_ATAPI)
+ ide_classify_atapi_dev(drive);
+ else
+ ide_classify_ata_dev(drive);
}
- /* drive was found */
}
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
@@ -649,7 +560,8 @@ static int ide_register_port(ide_hwif_t *hwif)
/* register with global device tree */
dev_set_name(&hwif->gendev, hwif->name);
hwif->gendev.driver_data = hwif;
- hwif->gendev.parent = hwif->dev;
+ if (hwif->gendev.parent == NULL)
+ hwif->gendev.parent = hwif->dev;
hwif->gendev.release = hwif_release_dev;
ret = device_register(&hwif->gendev);
@@ -778,7 +690,6 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
static int ide_probe_port(ide_hwif_t *hwif)
{
ide_drive_t *drive;
- unsigned long flags;
unsigned int irqd;
int i, rc = -ENODEV;
@@ -796,9 +707,6 @@ static int ide_probe_port(ide_hwif_t *hwif)
if (irqd)
disable_irq(hwif->irq);
- local_save_flags(flags);
- local_irq_enable_in_hardirq();
-
if (ide_port_wait_ready(hwif) == -EBUSY)
printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
@@ -812,8 +720,6 @@ static int ide_probe_port(ide_hwif_t *hwif)
rc = 0;
}
- local_irq_restore(flags);
-
/*
* Use cached IRQ number. It might be (and is...) changed by probe
* code above
@@ -830,29 +736,18 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
int i;
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- if (port_ops && port_ops->quirkproc)
- port_ops->quirkproc(drive);
- }
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ if (port_ops && port_ops->quirkproc)
+ port_ops->quirkproc(drive);
}
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- ide_set_max_pio(drive);
-
- drive->dev_flags |= IDE_DFLAG_NICE1;
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ ide_set_max_pio(drive);
- if (hwif->dma_ops)
- ide_set_dma(drive);
- }
- }
+ drive->dev_flags |= IDE_DFLAG_NICE1;
- ide_port_for_each_dev(i, drive, hwif) {
- if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
- drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
- else
- drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
+ if (hwif->dma_ops)
+ ide_set_dma(drive);
}
}
@@ -923,10 +818,7 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
int i, j = 0;
mutex_lock(&ide_cfg_mtx);
- ide_port_for_each_dev(i, drive, hwif) {
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
-
+ ide_port_for_each_present_dev(i, drive, hwif) {
if (ide_init_queue(drive)) {
printk(KERN_ERR "ide: failed to init %s\n",
drive->name);
@@ -949,14 +841,12 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
static int init_irq (ide_hwif_t *hwif)
{
struct ide_io_ports *io_ports = &hwif->io_ports;
+ irq_handler_t irq_handler;
int sa = 0;
- mutex_lock(&ide_cfg_mtx);
- spin_lock_init(&hwif->lock);
-
- init_timer(&hwif->timer);
- hwif->timer.function = &ide_timer_expiry;
- hwif->timer.data = (unsigned long)hwif;
+ irq_handler = hwif->host->irq_handler;
+ if (irq_handler == NULL)
+ irq_handler = ide_intr;
#if defined(__mc68000__)
sa = IRQF_SHARED;
@@ -968,7 +858,7 @@ static int init_irq (ide_hwif_t *hwif)
if (io_ports->ctl_addr)
hwif->tp_ops->set_irq(hwif, 1);
- if (request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwif))
+ if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
goto out_up;
if (!hwif->rqsize) {
@@ -991,10 +881,8 @@ static int init_irq (ide_hwif_t *hwif)
printk(KERN_CONT " (serialized)");
printk(KERN_CONT "\n");
- mutex_unlock(&ide_cfg_mtx);
return 0;
out_up:
- mutex_unlock(&ide_cfg_mtx);
return 1;
}
@@ -1093,14 +981,9 @@ static void drive_release_dev (struct device *dev)
static int hwif_init(ide_hwif_t *hwif)
{
- int old_irq;
-
if (!hwif->irq) {
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- if (!hwif->irq) {
- printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
- return 0;
- }
+ printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
+ return 0;
}
if (register_blkdev(hwif->major, hwif->name))
@@ -1118,29 +1001,12 @@ static int hwif_init(ide_hwif_t *hwif)
sg_init_table(hwif->sg_table, hwif->sg_max_nents);
- if (init_irq(hwif) == 0)
- goto done;
-
- old_irq = hwif->irq;
- /*
- * It failed to initialise. Find the default IRQ for
- * this port and try that.
- */
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- if (!hwif->irq) {
- printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
- hwif->name, old_irq);
- goto out;
- }
if (init_irq(hwif)) {
- printk(KERN_ERR "%s: probed IRQ %d and default IRQ %d failed\n",
- hwif->name, old_irq, hwif->irq);
+ printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
+ hwif->name, hwif->irq);
goto out;
}
- printk(KERN_WARNING "%s: probed IRQ %d failed, using default\n",
- hwif->name, hwif->irq);
-done:
blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
THIS_MODULE, ata_probe, ata_lock, hwif);
return 1;
@@ -1155,13 +1021,10 @@ static void hwif_register_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
unsigned int i;
- ide_port_for_each_dev(i, drive, hwif) {
+ ide_port_for_each_present_dev(i, drive, hwif) {
struct device *dev = &drive->gendev;
int ret;
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
-
dev_set_name(dev, "%u.%u", hwif->index, i);
dev->parent = &hwif->gendev;
dev->bus = &ide_bus_type;
@@ -1186,6 +1049,8 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
drive->io_32bit = 1;
+ if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
+ drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
drive->dev_flags |= IDE_DFLAG_UNMASK;
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
@@ -1207,10 +1072,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if (d->init_iops)
d->init_iops(hwif);
- if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
- (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
- hwif->irq = port ? 15 : 14;
-
/* ->host_flags may be set by ->init_iops (or even earlier...) */
hwif->host_flags |= d->host_flags;
hwif->pio_mask = d->pio_mask;
@@ -1311,6 +1172,12 @@ static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
hwif->name[2] = 'e';
hwif->name[3] = '0' + index;
+ spin_lock_init(&hwif->lock);
+
+ init_timer(&hwif->timer);
+ hwif->timer.function = &ide_timer_expiry;
+ hwif->timer.data = (unsigned long)hwif;
+
init_completion(&hwif->gendev_rel_comp);
hwif->tp_ops = &default_tp_ops;
@@ -1466,6 +1333,30 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
}
EXPORT_SYMBOL_GPL(ide_host_alloc);
+static void ide_port_free(ide_hwif_t *hwif)
+{
+ ide_port_free_devices(hwif);
+ ide_free_port_slot(hwif->index);
+ kfree(hwif);
+}
+
+static void ide_disable_port(ide_hwif_t *hwif)
+{
+ struct ide_host *host = hwif->host;
+ int i;
+
+ printk(KERN_INFO "%s: disabling port\n", hwif->name);
+
+ for (i = 0; i < MAX_HOST_PORTS; i++) {
+ if (host->ports[i] == hwif) {
+ host->ports[i] = NULL;
+ host->n_ports--;
+ }
+ }
+
+ ide_port_free(hwif);
+}
+
int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
hw_regs_t **hws)
{
@@ -1506,8 +1397,12 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
hwif->present = 1;
if (hwif->chipset != ide_4drives || !hwif->mate ||
- !hwif->mate->present)
- ide_register_port(hwif);
+ !hwif->mate->present) {
+ if (ide_register_port(hwif)) {
+ ide_disable_port(hwif);
+ continue;
+ }
+ }
if (hwif->present)
ide_port_tune_devices(hwif);
@@ -1520,7 +1415,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
if (hwif_init(hwif) == 0) {
printk(KERN_INFO "%s: failed to initialize IDE "
"interface\n", hwif->name);
- hwif->present = 0;
+ device_unregister(&hwif->gendev);
+ ide_disable_port(hwif);
continue;
}
@@ -1532,7 +1428,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
j++;
- ide_acpi_init(hwif);
+ ide_acpi_init_port(hwif);
if (hwif->present)
ide_acpi_port_init_devices(hwif);
@@ -1589,11 +1485,9 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
int i;
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- device_unregister(&drive->gendev);
- wait_for_completion(&drive->gendev_rel_comp);
- }
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ device_unregister(&drive->gendev);
+ wait_for_completion(&drive->gendev_rel_comp);
}
}
@@ -1659,12 +1553,8 @@ void ide_host_free(struct ide_host *host)
int i;
ide_host_for_each_port(i, hwif, host) {
- if (hwif == NULL)
- continue;
-
- ide_port_free_devices(hwif);
- ide_free_port_slot(hwif->index);
- kfree(hwif);
+ if (hwif)
+ ide_port_free(hwif);
}
kfree(host);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 1d8978b3314..417cde56eaf 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -231,7 +231,7 @@ static const struct ide_proc_devset ide_generic_settings[] = {
IDE_PROC_DEVSET(pio_mode, 0, 255),
IDE_PROC_DEVSET(unmaskirq, 0, 1),
IDE_PROC_DEVSET(using_dma, 0, 1),
- { 0 },
+ { NULL },
};
static void proc_ide_settings_warn(void)
@@ -600,7 +600,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif)
int i;
ide_port_for_each_dev(i, drive, hwif) {
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc)
+ if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
continue;
drive->proc = proc_mkdir(drive->name, parent);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index d7ecd3c7975..4e6181c7bbd 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -169,7 +169,7 @@ typedef struct ide_tape_obj {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
- struct kref kref;
+ struct device dev;
/*
* failed_pc points to the last failed packet command, or contains
@@ -267,7 +267,7 @@ static DEFINE_MUTEX(idetape_ref_mutex);
static struct class *idetape_sysfs_class;
-static void ide_tape_release(struct kref *);
+static void ide_tape_release(struct device *);
static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
{
@@ -279,7 +279,7 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
if (ide_device_get(tape->drive))
tape = NULL;
else
- kref_get(&tape->kref);
+ get_device(&tape->dev);
}
mutex_unlock(&idetape_ref_mutex);
return tape;
@@ -290,7 +290,7 @@ static void ide_tape_put(struct ide_tape_obj *tape)
ide_drive_t *drive = tape->drive;
mutex_lock(&idetape_ref_mutex);
- kref_put(&tape->kref, ide_tape_release);
+ put_device(&tape->dev);
ide_device_put(drive);
mutex_unlock(&idetape_ref_mutex);
}
@@ -308,7 +308,7 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
mutex_lock(&idetape_ref_mutex);
tape = idetape_devs[i];
if (tape)
- kref_get(&tape->kref);
+ get_device(&tape->dev);
mutex_unlock(&idetape_ref_mutex);
return tape;
}
@@ -2166,7 +2166,7 @@ static const struct ide_proc_devset idetape_settings[] = {
__IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL),
__IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
mulf_tdsc, divf_tdsc),
- { 0 },
+ { NULL },
};
#endif
@@ -2256,15 +2256,17 @@ static void ide_tape_remove(ide_drive_t *drive)
idetape_tape_t *tape = drive->driver_data;
ide_proc_unregister_driver(drive, tape->driver);
-
+ device_del(&tape->dev);
ide_unregister_region(tape->disk);
- ide_tape_put(tape);
+ mutex_lock(&idetape_ref_mutex);
+ put_device(&tape->dev);
+ mutex_unlock(&idetape_ref_mutex);
}
-static void ide_tape_release(struct kref *kref)
+static void ide_tape_release(struct device *dev)
{
- struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj);
+ struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj);
ide_drive_t *drive = tape->drive;
struct gendisk *g = tape->disk;
@@ -2407,7 +2409,12 @@ static int ide_tape_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
- kref_init(&tape->kref);
+ tape->dev.parent = &drive->gendev;
+ tape->dev.release = ide_tape_release;
+ dev_set_name(&tape->dev, dev_name(&drive->gendev));
+
+ if (device_register(&tape->dev))
+ goto out_free_disk;
tape->drive = drive;
tape->driver = &idetape_driver;
@@ -2436,6 +2443,8 @@ static int ide_tape_probe(ide_drive_t *drive)
return 0;
+out_free_disk:
+ put_disk(g);
out_free_tape:
kfree(tape);
failed:
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c
new file mode 100644
index 00000000000..6910f6a257e
--- /dev/null
+++ b/drivers/ide/ide-xfer-mode.c
@@ -0,0 +1,246 @@
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/ide.h>
+#include <linux/bitops.h>
+
+static const char *udma_str[] =
+ { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
+ "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
+static const char *mwdma_str[] =
+ { "MWDMA0", "MWDMA1", "MWDMA2" };
+static const char *swdma_str[] =
+ { "SWDMA0", "SWDMA1", "SWDMA2" };
+static const char *pio_str[] =
+ { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
+
+/**
+ * ide_xfer_verbose - return IDE mode names
+ * @mode: transfer mode
+ *
+ * Returns a constant string giving the name of the mode
+ * requested.
+ */
+
+const char *ide_xfer_verbose(u8 mode)
+{
+ const char *s;
+ u8 i = mode & 0xf;
+
+ if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
+ s = udma_str[i];
+ else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
+ s = mwdma_str[i];
+ else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
+ s = swdma_str[i];
+ else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
+ s = pio_str[i & 0x7];
+ else if (mode == XFER_PIO_SLOW)
+ s = "PIO SLOW";
+ else
+ s = "XFER ERROR";
+
+ return s;
+}
+EXPORT_SYMBOL(ide_xfer_verbose);
+
+/**
+ * ide_get_best_pio_mode - get PIO mode from drive
+ * @drive: drive to consider
+ * @mode_wanted: preferred mode
+ * @max_mode: highest allowed mode
+ *
+ * This routine returns the recommended PIO settings for a given drive,
+ * based on the drive->id information and the ide_pio_blacklist[].
+ *
+ * Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
+ * This is used by most chipset support modules when "auto-tuning".
+ */
+
+u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
+{
+ u16 *id = drive->id;
+ int pio_mode = -1, overridden = 0;
+
+ if (mode_wanted != 255)
+ return min_t(u8, mode_wanted, max_mode);
+
+ if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
+ pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
+
+ if (pio_mode != -1) {
+ printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
+ } else {
+ pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
+ if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
+ pio_mode = 2;
+ overridden = 1;
+ }
+
+ if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
+ if (ata_id_has_iordy(id)) {
+ if (id[ATA_ID_PIO_MODES] & 7) {
+ overridden = 0;
+ if (id[ATA_ID_PIO_MODES] & 4)
+ pio_mode = 5;
+ else if (id[ATA_ID_PIO_MODES] & 2)
+ pio_mode = 4;
+ else
+ pio_mode = 3;
+ }
+ }
+ }
+
+ if (overridden)
+ printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
+ drive->name);
+ }
+
+ if (pio_mode > max_mode)
+ pio_mode = max_mode;
+
+ return pio_mode;
+}
+EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
+
+int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+ return 0;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL)
+ return -1;
+
+ /*
+ * TODO: temporary hack for some legacy host drivers that didn't
+ * set transfer mode on the device in ->set_pio_mode method...
+ */
+ if (port_ops->set_dma_mode == NULL) {
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return 0;
+ }
+
+ if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+ if (ide_config_drive_speed(drive, mode))
+ return -1;
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return 0;
+ } else {
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return ide_config_drive_speed(drive, mode);
+ }
+}
+
+int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+ return 0;
+
+ if (port_ops == NULL || port_ops->set_dma_mode == NULL)
+ return -1;
+
+ if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+ if (ide_config_drive_speed(drive, mode))
+ return -1;
+ port_ops->set_dma_mode(drive, mode);
+ return 0;
+ } else {
+ port_ops->set_dma_mode(drive, mode);
+ return ide_config_drive_speed(drive, mode);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_set_dma_mode);
+
+/* req_pio == "255" for auto-tune */
+void ide_set_pio(ide_drive_t *drive, u8 req_pio)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+ u8 host_pio, pio;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return;
+
+ BUG_ON(hwif->pio_mask == 0x00);
+
+ host_pio = fls(hwif->pio_mask) - 1;
+
+ pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
+
+ /*
+ * TODO:
+ * - report device max PIO mode
+ * - check req_pio != 255 against device max PIO mode
+ */
+ printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
+ drive->name, host_pio, req_pio,
+ req_pio == 255 ? "(auto-tune)" : "", pio);
+
+ (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
+}
+EXPORT_SYMBOL_GPL(ide_set_pio);
+
+/**
+ * ide_rate_filter - filter transfer mode
+ * @drive: IDE device
+ * @speed: desired speed
+ *
+ * Given the available transfer modes this function returns
+ * the best available speed at or below the speed requested.
+ *
+ * TODO: check device PIO capabilities
+ */
+
+static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 mode = ide_find_dma_mode(drive, speed);
+
+ if (mode == 0) {
+ if (hwif->pio_mask)
+ mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
+ else
+ mode = XFER_PIO_4;
+ }
+
+/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
+
+ return min(speed, mode);
+}
+
+/**
+ * ide_set_xfer_rate - set transfer rate
+ * @drive: drive to set
+ * @rate: speed to attempt to set
+ *
+ * General helper for setting the speed of an IDE device. This
+ * function knows about user enforced limits from the configuration
+ * which ->set_pio_mode/->set_dma_mode does not.
+ */
+
+int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return -1;
+
+ rate = ide_rate_filter(drive, rate);
+
+ BUG_ON(rate < XFER_PIO_0);
+
+ if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
+ return ide_set_pio_mode(drive, rate);
+
+ return ide_set_dma_mode(drive, rate);
+}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 258805da15c..92c9b90931e 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -62,160 +62,6 @@
struct class *ide_port_class;
-/*
- * Locks for IDE setting functionality
- */
-
-DEFINE_MUTEX(ide_setting_mtx);
-
-ide_devset_get(io_32bit, io_32bit);
-
-static int set_io_32bit(ide_drive_t *drive, int arg)
-{
- if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
- return -EPERM;
-
- if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
- return -EINVAL;
-
- drive->io_32bit = arg;
-
- return 0;
-}
-
-ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
-
-static int set_ksettings(ide_drive_t *drive, int arg)
-{
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (arg)
- drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
- else
- drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
-
- return 0;
-}
-
-ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
-
-static int set_using_dma(ide_drive_t *drive, int arg)
-{
-#ifdef CONFIG_BLK_DEV_IDEDMA
- int err = -EPERM;
-
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (ata_id_has_dma(drive->id) == 0)
- goto out;
-
- if (drive->hwif->dma_ops == NULL)
- goto out;
-
- err = 0;
-
- if (arg) {
- if (ide_set_dma(drive))
- err = -EIO;
- } else
- ide_dma_off(drive);
-
-out:
- return err;
-#else
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- return -EPERM;
-#endif
-}
-
-/*
- * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
- */
-static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
-{
- switch (req_pio) {
- case 202:
- case 201:
- case 200:
- case 102:
- case 101:
- case 100:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
- case 9:
- case 8:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
- case 7:
- case 6:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
- default:
- return 0;
- }
-}
-
-static int set_pio_mode(ide_drive_t *drive, int arg)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (arg < 0 || arg > 255)
- return -EINVAL;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return -ENOSYS;
-
- if (set_pio_mode_abuse(drive->hwif, arg)) {
- if (arg == 8 || arg == 9) {
- unsigned long flags;
-
- /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
- spin_lock_irqsave(&hwif->lock, flags);
- port_ops->set_pio_mode(drive, arg);
- spin_unlock_irqrestore(&hwif->lock, flags);
- } else
- port_ops->set_pio_mode(drive, arg);
- } else {
- int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
-
- ide_set_pio(drive, arg);
-
- if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
- if (keep_dma)
- ide_dma_on(drive);
- }
- }
-
- return 0;
-}
-
-ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
-
-static int set_unmaskirq(ide_drive_t *drive, int arg)
-{
- if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
- return -EPERM;
-
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (arg)
- drive->dev_flags |= IDE_DFLAG_UNMASK;
- else
- drive->dev_flags &= ~IDE_DFLAG_UNMASK;
-
- return 0;
-}
-
-ide_ext_devset_rw_sync(io_32bit, io_32bit);
-ide_ext_devset_rw_sync(keepsettings, ksettings);
-ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
-ide_ext_devset_rw_sync(using_dma, using_dma);
-__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
-
/**
* ide_device_get - get an additional reference to a ide_drive_t
* @drive: device to get a reference to
@@ -337,6 +183,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
int a, b, i, j = 1;
unsigned int *dev_param_mask = (unsigned int *)kp->arg;
+ /* controller . device (0 or 1) [ : 1 (set) | 0 (clear) ] */
if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 &&
sscanf(s, "%d.%d", &a, &b) != 2)
return -EINVAL;
@@ -349,7 +196,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
if (j)
*dev_param_mask |= (1 << i);
else
- *dev_param_mask &= (1 << i);
+ *dev_param_mask &= ~(1 << i);
return 0;
}
@@ -392,6 +239,8 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp)
{
int a, b, c = 0, h = 0, s = 0, i, j = 1;
+ /* controller . device (0 or 1) : Cylinders , Heads , Sectors */
+ /* controller . device (0 or 1) : 1 (use CHS) | 0 (ignore CHS) */
if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 &&
sscanf(str, "%d.%d:%d", &a, &b, &j) != 3)
return -EINVAL;
@@ -407,7 +256,7 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp)
if (j)
ide_disks |= (1 << i);
else
- ide_disks &= (1 << i);
+ ide_disks &= ~(1 << i);
ide_disks_chs[i].cyl = c;
ide_disks_chs[i].head = h;
@@ -469,6 +318,8 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
{
int i, j = 1;
+ /* controller (ignore) */
+ /* controller : 1 (ignore) | 0 (use) */
if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1)
return -EINVAL;
@@ -478,7 +329,7 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
if (j)
ide_ignore_cable |= (1 << i);
else
- ide_ignore_cable &= (1 << i);
+ ide_ignore_cable &= ~(1 << i);
return 0;
}
@@ -522,6 +373,8 @@ static int __init ide_init(void)
goto out_port_class;
}
+ ide_acpi_init();
+
proc_ide_create();
return 0;
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index e1c4f543739..6b9fc950b4a 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -5,9 +5,8 @@
* May be copied or modified under the terms of the GNU General Public License
* Based in part on the ITE vendor provided SCSI driver.
*
- * Documentation available from
- * http://www.ite.com.tw/pc/IT8212F_V04.pdf
- * Some other documents are NDA.
+ * Documentation:
+ * Datasheet is freely available, some other documents under NDA.
*
* The ITE8212 isn't exactly a standard IDE controller. It has two
* modes. In pass through mode then it is an IDE controller. In its smart
@@ -604,7 +603,7 @@ static void it8212_disable_raid(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
}
-static unsigned int init_chipset_it821x(struct pci_dev *dev)
+static int init_chipset_it821x(struct pci_dev *dev)
{
u8 conf;
static char *mode[2] = { "pass through", "smart" };
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 83643ed9a42..ea48a3ee806 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -286,9 +286,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
}
if (!using_inta)
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- else if (!hwif->irq && hwif->mate && hwif->mate->irq)
- hwif->irq = hwif->mate->irq; /* share IRQ with mate */
+ hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
if (!hwif->dma_base)
return;
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index a7ac490c9ae..f38aac78044 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -346,7 +346,8 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
{
struct clk *clk;
struct resource *mem, *irq;
- unsigned long base, rate;
+ void __iomem *base;
+ unsigned long rate;
int i, rc;
hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
@@ -382,11 +383,13 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
base = IO_ADDRESS(mem->start);
/* Configure the Palm Chip controller */
- palm_bk3710_chipinit((void __iomem *)base);
+ palm_bk3710_chipinit(base);
for (i = 0; i < IDE_NR_PORTS - 2; i++)
- hw.io_ports_array[i] = base + IDE_PALM_ATA_PRI_REG_OFFSET + i;
- hw.io_ports.ctl_addr = base + IDE_PALM_ATA_PRI_CTL_OFFSET;
+ hw.io_ports_array[i] = (unsigned long)
+ (base + IDE_PALM_ATA_PRI_REG_OFFSET + i);
+ hw.io_ports.ctl_addr = (unsigned long)
+ (base + IDE_PALM_ATA_PRI_CTL_OFFSET);
hw.irq = irq->start;
hw.dev = &pdev->dev;
hw.chipset = ide_palm3710;
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c
index f21290c4b44..b68906c3c17 100644
--- a/drivers/ide/pdc202xx_new.c
+++ b/drivers/ide/pdc202xx_new.c
@@ -325,7 +325,7 @@ static void apple_kiwi_init(struct pci_dev *pdev)
}
#endif /* CONFIG_PPC_PMAC */
-static unsigned int init_chipset_pdcnew(struct pci_dev *dev)
+static int init_chipset_pdcnew(struct pci_dev *dev)
{
const char *name = DRV_NAME;
unsigned long dma_base = pci_resource_start(dev, 4);
@@ -444,7 +444,7 @@ static unsigned int init_chipset_pdcnew(struct pci_dev *dev)
#endif
out:
- return dev->irq;
+ return 0;
}
static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index 97193323aeb..cba66ebce4e 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -264,7 +264,7 @@ static void pdc202xx_dma_timeout(ide_drive_t *drive)
ide_dma_timeout(drive);
}
-static unsigned int init_chipset_pdc202xx(struct pci_dev *dev)
+static int init_chipset_pdc202xx(struct pci_dev *dev)
{
unsigned long dmabase = pci_resource_start(dev, 4);
u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
@@ -290,7 +290,7 @@ static unsigned int init_chipset_pdc202xx(struct pci_dev *dev)
printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
}
out:
- return dev->irq;
+ return 0;
}
static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index f1e2e4ef0d7..2aa69993306 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -204,7 +204,7 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
* out to be nice and simple.
*/
-static unsigned int init_chipset_ich(struct pci_dev *dev)
+static int init_chipset_ich(struct pci_dev *dev)
{
u32 extra = 0;
@@ -318,19 +318,12 @@ static const struct ide_port_ops ich_port_ops = {
.cable_detect = piix_cable_detect,
};
-#ifndef CONFIG_IA64
- #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS
-#else
- #define IDE_HFLAGS_PIIX 0
-#endif
-
#define DECLARE_PIIX_DEV(udma) \
{ \
.name = DRV_NAME, \
.init_hwif = init_hwif_piix, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
.port_ops = &piix_port_ops, \
- .host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
.mwdma_mask = ATA_MWDMA12_ONLY, \
@@ -344,7 +337,6 @@ static const struct ide_port_ops ich_port_ops = {
.init_hwif = init_hwif_piix, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
.port_ops = &ich_port_ops, \
- .host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
.mwdma_mask = ATA_MWDMA12_ONLY, \
@@ -360,8 +352,7 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = {
*/
.name = DRV_NAME,
.enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
- .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA |
- IDE_HFLAGS_PIIX,
+ .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
/* This is a painful system best to let it self tune for now */
},
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index 5b2e3af43c4..08c4fa35e9b 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -16,7 +16,7 @@
/*
* Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
*/
#include <linux/module.h>
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h
index 6636f9665d1..d7e67a1a1dc 100644
--- a/drivers/ide/qd65xx.h
+++ b/drivers/ide/qd65xx.h
@@ -4,7 +4,7 @@
/*
* Authors: Petr Soucek <petr@ryston.cz>
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
*/
/* truncates a in [b,c] */
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index 382102ba467..b6554ef9271 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -175,7 +175,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, ultra_enable);
}
-static unsigned int init_chipset_svwks(struct pci_dev *dev)
+static int init_chipset_svwks(struct pci_dev *dev)
{
unsigned int reg;
u8 btr;
@@ -270,7 +270,7 @@ static unsigned int init_chipset_svwks(struct pci_dev *dev)
pci_write_config_byte(dev, 0x5A, btr);
}
- return dev->irq;
+ return 0;
}
static u8 ata66_svwks_svwks(ide_hwif_t *hwif)
@@ -353,14 +353,11 @@ static const struct ide_port_ops svwks_port_ops = {
.cable_detect = svwks_cable_detect,
};
-#define IDE_HFLAGS_SVWKS IDE_HFLAG_LEGACY_IRQS
-
static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
{ /* 0: OSB4 */
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &osb4_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* UDMA is problematic on OSB4 */
@@ -369,7 +366,6 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -378,7 +374,6 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -387,7 +382,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -396,7 +391,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index e85d1ed29c2..24bc884826f 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -305,7 +305,6 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
* @dev: PCI device holding interface
* @d: IDE port info
* @port: port number
- * @irq: PCI IRQ
* @hw: hw_regs_t instance corresponding to this port
*
* Perform the initial set up for the hardware interface structure. This
@@ -316,7 +315,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
*/
static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
- unsigned int port, int irq, hw_regs_t *hw)
+ unsigned int port, hw_regs_t *hw)
{
unsigned long ctl = 0, base = 0;
@@ -344,7 +343,6 @@ static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
}
memset(hw, 0, sizeof(*hw));
- hw->irq = irq;
hw->dev = &dev->dev;
hw->chipset = d->chipset ? d->chipset : ide_pci;
ide_std_init_ports(hw, base, ctl | 2);
@@ -448,7 +446,6 @@ out:
* ide_pci_setup_ports - configure ports/devices on PCI IDE
* @dev: PCI device
* @d: IDE port info
- * @pciirq: IRQ line
* @hw: hw_regs_t instances corresponding to this PCI IDE device
* @hws: hw_regs_t pointers table to update
*
@@ -462,7 +459,7 @@ out:
*/
void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
- int pciirq, hw_regs_t *hw, hw_regs_t **hws)
+ hw_regs_t *hw, hw_regs_t **hws)
{
int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
u8 tmp;
@@ -481,7 +478,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
continue; /* port not enabled */
}
- if (ide_hw_configure(dev, d, port, pciirq, hw + port))
+ if (ide_hw_configure(dev, d, port, hw + port))
continue;
*(hws + port) = hw + port;
@@ -524,7 +521,7 @@ static int do_ide_setup_pci_device(struct pci_dev *dev,
if (noisy)
printk(KERN_INFO "%s %s: not 100%% native mode: will "
"probe irqs later\n", d->name, pci_name(dev));
- pciirq = ret;
+ pciirq = 0;
} else if (!pciirq && noisy) {
printk(KERN_WARNING "%s %s: bad irq (%d): will probe later\n",
d->name, pci_name(dev), pciirq);
@@ -549,7 +546,7 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
if (ret < 0)
goto out;
- ide_pci_setup_ports(dev, d, 0, &hw[0], &hws[0]);
+ ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
host = ide_host_alloc(d, hws);
if (host == NULL) {
@@ -568,7 +565,11 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
goto out;
/* fixup IRQ */
- hw[1].irq = hw[0].irq = ret;
+ if (ide_pci_is_in_compatibility_mode(dev)) {
+ hw[0].irq = pci_get_legacy_ide_irq(dev, 0);
+ hw[1].irq = pci_get_legacy_ide_irq(dev, 1);
+ } else
+ hw[1].irq = hw[0].irq = ret;
ret = ide_host_register(host, d, hws);
if (ret)
@@ -591,7 +592,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
if (ret < 0)
goto out;
- ide_pci_setup_ports(pdev[i], d, 0, &hw[i*2], &hws[i*2]);
+ ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]);
}
host = ide_host_alloc(d, hws);
@@ -619,7 +620,11 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
goto out;
/* fixup IRQ */
- hw[i*2 + 1].irq = hw[i*2].irq = ret;
+ if (ide_pci_is_in_compatibility_mode(pdev[i])) {
+ hw[i*2].irq = pci_get_legacy_ide_irq(pdev[i], 0);
+ hw[i*2 + 1].irq = pci_get_legacy_ide_irq(pdev[i], 1);
+ } else
+ hw[i*2 + 1].irq = hw[i*2].irq = ret;
}
ret = ide_host_register(host, d, hws);
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c
index cb2b352b876..1811ae9cd84 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -464,7 +464,7 @@ static void sil_sata_pre_reset(ide_drive_t *drive)
* to 133 MHz clocking if the system isn't already set up to do it.
*/
-static unsigned int init_chipset_siimage(struct pci_dev *dev)
+static int init_chipset_siimage(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
void __iomem *ioaddr = host->host_priv;
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index 9ec1a4a4432..afca22beaad 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -447,7 +447,7 @@ static int __devinit sis_find_family(struct pci_dev *dev)
return chipset_family;
}
-static unsigned int init_chipset_sis5513(struct pci_dev *dev)
+static int init_chipset_sis5513(struct pci_dev *dev)
{
/* Make general config ops here
1/ tell IDE channels to operate in Compatibility mode only
@@ -563,7 +563,7 @@ static const struct ide_port_info sis5513_chipset __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_sis5513,
.enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA,
+ .host_flags = IDE_HFLAG_NO_AUTODMA,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
};
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index 6297956507c..dba213c51ba 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -271,7 +271,7 @@ static u8 sl82c105_bridge_revision(struct pci_dev *dev)
* channel 0 here at least, but channel 1 has to be enabled by
* firmware or arch code. We still set both to 16 bits mode.
*/
-static unsigned int init_chipset_sl82c105(struct pci_dev *dev)
+static int init_chipset_sl82c105(struct pci_dev *dev)
{
u32 val;
@@ -281,7 +281,7 @@ static unsigned int init_chipset_sl82c105(struct pci_dev *dev)
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
- return dev->irq;
+ return 0;
}
static const struct ide_port_ops sl82c105_port_ops = {
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index 40b4b94a428..f55d7d6313e 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -136,7 +136,6 @@ static const struct ide_port_info slc90e66_chipset __devinitdata = {
.name = DRV_NAME,
.enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} },
.port_ops = &slc90e66_port_ops,
- .host_flags = IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.swdma_mask = ATA_SWDMA2_ONLY,
.mwdma_mask = ATA_MWDMA12_ONLY,
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index b6a1285a402..1c09e549c42 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -277,9 +277,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
if (reg & 0x10)
/* legacy mode */
hwif->irq = hwif->channel ? 15 : 14;
- else if (!hwif->irq && hwif->mate && hwif->mate->irq)
- /* sharing IRQ with mate */
- hwif->irq = hwif->mate->irq;
#if 1
{
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 882f6f07c47..40b0812a045 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -261,9 +261,9 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
bcount = cur_len;
/*
* This workaround for zero count seems required.
- * (standard ide_build_dmatable do it too)
+ * (standard ide_build_dmatable does it too)
*/
- if ((bcount & 0xffff) == 0x0000)
+ if (bcount == 0x10000)
bcount = 0x8000;
*table++ = bcount & 0xffff;
*table++ = cur_addr;
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 703c3eeb20a..3ff7231e485 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -267,7 +267,7 @@ static void via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
* and initialize its drive independent registers.
*/
-static unsigned int init_chipset_via82cxxx(struct pci_dev *dev)
+static int init_chipset_via82cxxx(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct via82cxxx_dev *vdev = host->host_priv;
@@ -443,11 +443,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
if ((via_config->flags & VIA_NO_UNMASK) == 0)
d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
-#ifdef CONFIG_PPC_CHRP
- if (machine_is(chrp) && _chrp_type == _CHRP_Pegasos)
- d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
-#endif
-
d.udma_mask = via_config->udma_mask;
vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
diff --git a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h
index 2727bcd2419..467373cab8e 100644
--- a/drivers/ieee1394/dma.h
+++ b/drivers/ieee1394/dma.h
@@ -12,6 +12,7 @@
#include <asm/types.h>
+struct file;
struct pci_dev;
struct scatterlist;
struct vm_area_struct;
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index a329e6bd5d2..cb15bfa38d7 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1325,11 +1325,7 @@ static int dv1394_fasync(int fd, struct file *file, int on)
struct video_card *video = file_to_video_card(file);
- int retval = fasync_helper(fd, file, on, &video->fasync);
-
- if (retval < 0)
- return retval;
- return 0;
+ return fasync_helper(fd, file, on, &video->fasync);
}
static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
@@ -1823,6 +1819,10 @@ static int dv1394_open(struct inode *inode, struct file *file)
#endif
+ printk(KERN_INFO "%s: NOTE, the dv1394 interface is unsupported "
+ "and will not be available in the new firewire driver stack. "
+ "Try libraw1394 based programs instead.\n", current->comm);
+
return 0;
}
@@ -2567,10 +2567,6 @@ static int __init dv1394_init_module(void)
{
int ret;
- printk(KERN_WARNING
- "NOTE: The dv1394 driver is unsupported and may be removed in a "
- "future Linux release. Use raw1394 instead.\n");
-
cdev_init(&dv1394_cdev, &dv1394_fops);
dv1394_cdev.owner = THIS_MODULE;
ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16);
diff --git a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h
index e0ae0d3d747..af320e2c507 100644
--- a/drivers/ieee1394/ieee1394.h
+++ b/drivers/ieee1394/ieee1394.h
@@ -54,9 +54,7 @@
#define IEEE1394_SPEED_800 0x03
#define IEEE1394_SPEED_1600 0x04
#define IEEE1394_SPEED_3200 0x05
-
-/* The current highest tested speed supported by the subsystem */
-#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800
+#define IEEE1394_SPEED_MAX IEEE1394_SPEED_3200
/* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[];
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index dcdb71a7718..87233800372 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -338,6 +338,7 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
u8 cldcnt[nodecount];
u8 *map = host->speed_map;
u8 *speedcap = host->speed;
+ u8 local_link_speed = host->csr.lnk_spd;
struct selfid *sid;
struct ext_selfid *esid;
int i, j, n;
@@ -373,8 +374,8 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++;
speedcap[n] = sid->speed;
- if (speedcap[n] > host->csr.lnk_spd)
- speedcap[n] = host->csr.lnk_spd;
+ if (speedcap[n] > local_link_speed)
+ speedcap[n] = local_link_speed;
n--;
}
}
@@ -407,12 +408,11 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
}
}
-#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX
- /* assume maximum speed for 1394b PHYs, nodemgr will correct it */
- for (n = 0; n < nodecount; n++)
- if (speedcap[n] == SELFID_SPEED_UNKNOWN)
- speedcap[n] = IEEE1394_SPEED_MAX;
-#endif
+ /* assume a maximum speed for 1394b PHYs, nodemgr will correct it */
+ if (local_link_speed > SELFID_SPEED_UNKNOWN)
+ for (i = 0; i < nodecount; i++)
+ if (speedcap[i] == SELFID_SPEED_UNKNOWN)
+ speedcap[i] = local_link_speed;
}
@@ -1275,7 +1275,7 @@ static void __exit ieee1394_cleanup(void)
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
}
-module_init(ieee1394_init);
+fs_initcall(ieee1394_init);
module_exit(ieee1394_cleanup);
/* Exported symbols */
@@ -1314,6 +1314,7 @@ EXPORT_SYMBOL(hpsb_make_lock64packet);
EXPORT_SYMBOL(hpsb_make_phypacket);
EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL(hpsb_write);
+EXPORT_SYMBOL(hpsb_lock);
EXPORT_SYMBOL(hpsb_packet_success);
/** highlevel.c **/
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index 10c3d9f8c03..675b3135d5f 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -501,8 +501,6 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
if (length == 0)
return -EINVAL;
- BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
-
packet = hpsb_make_readpacket(host, node, addr, length);
if (!packet) {
@@ -550,8 +548,6 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
if (length == 0)
return -EINVAL;
- BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
-
packet = hpsb_make_writepacket(host, node, addr, buffer, length);
if (!packet)
@@ -570,3 +566,30 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return retval;
}
+
+int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+ u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
+{
+ struct hpsb_packet *packet;
+ int retval = 0;
+
+ packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
+ if (!packet)
+ return -ENOMEM;
+
+ packet->generation = generation;
+ retval = hpsb_send_packet_and_wait(packet);
+ if (retval < 0)
+ goto hpsb_lock_fail;
+
+ retval = hpsb_packet_success(packet);
+
+ if (retval == 0)
+ *data = packet->data[0];
+
+hpsb_lock_fail:
+ hpsb_free_tlabel(packet);
+ hpsb_free_packet(packet);
+
+ return retval;
+}
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h
index d2d5bc3546d..20b693be14b 100644
--- a/drivers/ieee1394/ieee1394_transactions.h
+++ b/drivers/ieee1394/ieee1394_transactions.h
@@ -30,6 +30,8 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length);
int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length);
+int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+ u64 addr, int extcode, quadlet_t *data, quadlet_t arg);
#ifdef HPSB_DEBUG_TLABELS
extern spinlock_t hpsb_tlabel_lock;
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h
index b5de5f21ef7..c2089c093aa 100644
--- a/drivers/ieee1394/iso.h
+++ b/drivers/ieee1394/iso.h
@@ -13,6 +13,7 @@
#define IEEE1394_ISO_H
#include <linux/spinlock_types.h>
+#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/types.h>
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 906c5a98d81..53aada5bbe1 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -971,6 +971,9 @@ static struct unit_directory *nodemgr_process_unit_directory
ud->ud_kv = ud_kv;
ud->id = (*id)++;
+ /* inherit vendor_id from root directory if none exists in unit dir */
+ ud->vendor_id = ne->vendor_id;
+
csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) {
switch (kv->key.id) {
case CSR1212_KV_ID_VENDOR:
@@ -1265,7 +1268,8 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
csr1212_destroy_csr(csr);
}
- /* Mark the node current */
+ /* Finally, mark the node current */
+ smp_wmb();
ne->generation = generation;
if (ne->in_limbo) {
@@ -1798,7 +1802,7 @@ void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet)
{
packet->host = ne->host;
packet->generation = ne->generation;
- barrier();
+ smp_rmb();
packet->node_id = ne->nodeid;
}
@@ -1807,7 +1811,7 @@ int hpsb_node_write(struct node_entry *ne, u64 addr,
{
unsigned int generation = ne->generation;
- barrier();
+ smp_rmb();
return hpsb_write(ne->host, ne->nodeid, generation,
addr, buffer, length);
}
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index 15ea09733e8..ee5acdbd114 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -21,9 +21,11 @@
#define _IEEE1394_NODEMGR_H
#include <linux/device.h>
+#include <asm/system.h>
#include <asm/types.h>
#include "ieee1394_core.h"
+#include "ieee1394_transactions.h"
#include "ieee1394_types.h"
struct csr1212_csr;
@@ -154,6 +156,22 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne)
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet);
int hpsb_node_write(struct node_entry *ne, u64 addr,
quadlet_t *buffer, size_t length);
+static inline int hpsb_node_read(struct node_entry *ne, u64 addr,
+ quadlet_t *buffer, size_t length)
+{
+ unsigned int g = ne->generation;
+
+ smp_rmb();
+ return hpsb_read(ne->host, ne->nodeid, g, addr, buffer, length);
+}
+static inline int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode,
+ quadlet_t *buffer, quadlet_t arg)
+{
+ unsigned int g = ne->generation;
+
+ smp_rmb();
+ return hpsb_lock(ne->host, ne->nodeid, g, addr, extcode, buffer, arg);
+}
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *));
int init_ieee1394_nodemgr(void);
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h
index 4320bf01049..7fb8ab9780a 100644
--- a/drivers/ieee1394/ohci1394.h
+++ b/drivers/ieee1394/ohci1394.h
@@ -26,7 +26,7 @@
#define OHCI1394_DRIVER_NAME "ohci1394"
-#define OHCI1394_MAX_AT_REQ_RETRIES 0x2
+#define OHCI1394_MAX_AT_REQ_RETRIES 0xf
#define OHCI1394_MAX_AT_RESP_RETRIES 0x2
#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8
#define OHCI1394_MAX_SELF_ID_ERRORS 16
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index dc15cadb06e..38f71203620 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -1419,7 +1419,6 @@ static int __devinit add_card(struct pci_dev *dev,
i2c_ad = kzalloc(sizeof(*i2c_ad), GFP_KERNEL);
if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
- i2c_ad->id = I2C_HW_B_PCILYNX;
strlcpy(i2c_ad->name, "PCILynx I2C", sizeof(i2c_ad->name));
i2c_adapter_data = bit_data;
i2c_ad->algo_data = &i2c_adapter_data;
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index ab1034ccb7f..f3fd8657ce4 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -115,8 +115,8 @@
*/
static int sbp2_max_speed = IEEE1394_SPEED_MAX;
module_param_named(max_speed, sbp2_max_speed, int, 0644);
-MODULE_PARM_DESC(max_speed, "Force max speed "
- "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)");
+MODULE_PARM_DESC(max_speed, "Limit data transfer speed (5 <= 3200, "
+ "4 <= 1600, 3 <= 800, 2 <= 400, 1 <= 200, 0 = 100 Mb/s)");
/*
* Set serialize_io to 0 or N to use dynamically appended lists of command ORBs.
@@ -256,7 +256,7 @@ static int sbp2_set_busy_timeout(struct sbp2_lu *);
static int sbp2_max_speed_and_size(struct sbp2_lu *);
-static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
+static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xa, 0xa, 0xa };
static DEFINE_RWLOCK(sbp2_hi_logical_units_lock);
@@ -347,8 +347,8 @@ static struct scsi_host_template sbp2_shost_template = {
.sdev_attrs = sbp2_sysfs_sdev_attrs,
};
-/* for match-all entries in sbp2_workarounds_table */
-#define SBP2_ROM_VALUE_WILDCARD 0x1000000
+#define SBP2_ROM_VALUE_WILDCARD ~0 /* match all */
+#define SBP2_ROM_VALUE_MISSING 0xff000000 /* not present in the unit dir. */
/*
* List of devices with known bugs.
@@ -359,60 +359,70 @@ static struct scsi_host_template sbp2_shost_template = {
*/
static const struct {
u32 firmware_revision;
- u32 model_id;
+ u32 model;
unsigned workarounds;
} sbp2_workarounds_table[] = {
/* DViCO Momobay CX-1 with TSB42AA9 bridge */ {
.firmware_revision = 0x002800,
- .model_id = 0x001010,
+ .model = 0x001010,
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
SBP2_WORKAROUND_MODE_SENSE_8 |
SBP2_WORKAROUND_POWER_CONDITION,
},
/* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
.firmware_revision = 0x002800,
- .model_id = 0x000000,
+ .model = 0x000000,
.workarounds = SBP2_WORKAROUND_DELAY_INQUIRY |
SBP2_WORKAROUND_POWER_CONDITION,
},
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_INQUIRY_36,
},
/* PL-3507 bridge with Prolific firmware */ {
.firmware_revision = 0x012800,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_POWER_CONDITION,
},
/* Symbios bridge */ {
.firmware_revision = 0xa0b800,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
/* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
.firmware_revision = 0x002600,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
+ /*
+ * iPod 2nd generation: needs 128k max transfer size workaround
+ * iPod 3rd generation: needs fix capacity workaround
+ */
+ {
+ .firmware_revision = 0x0a2700,
+ .model = 0x000000,
+ .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS |
+ SBP2_WORKAROUND_FIX_CAPACITY,
+ },
/* iPod 4th generation */ {
.firmware_revision = 0x0a2700,
- .model_id = 0x000021,
+ .model = 0x000021,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
},
/* iPod mini */ {
.firmware_revision = 0x0a2700,
- .model_id = 0x000022,
+ .model = 0x000022,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
},
/* iPod mini */ {
.firmware_revision = 0x0a2700,
- .model_id = 0x000023,
+ .model = 0x000023,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
},
/* iPod Photo */ {
.firmware_revision = 0x0a2700,
- .model_id = 0x00007e,
+ .model = 0x00007e,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
}
};
@@ -1341,13 +1351,15 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
struct csr1212_keyval *kv;
struct csr1212_dentry *dentry;
u64 management_agent_addr;
- u32 unit_characteristics, firmware_revision;
+ u32 unit_characteristics, firmware_revision, model;
unsigned workarounds;
int i;
management_agent_addr = 0;
unit_characteristics = 0;
- firmware_revision = 0;
+ firmware_revision = SBP2_ROM_VALUE_MISSING;
+ model = ud->flags & UNIT_DIRECTORY_MODEL_ID ?
+ ud->model_id : SBP2_ROM_VALUE_MISSING;
csr1212_for_each_dir_entry(ud->ne->csr, kv, ud->ud_kv, dentry) {
switch (kv->key.id) {
@@ -1388,9 +1400,9 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
sbp2_workarounds_table[i].firmware_revision !=
(firmware_revision & 0xffff00))
continue;
- if (sbp2_workarounds_table[i].model_id !=
+ if (sbp2_workarounds_table[i].model !=
SBP2_ROM_VALUE_WILDCARD &&
- sbp2_workarounds_table[i].model_id != ud->model_id)
+ sbp2_workarounds_table[i].model != model)
continue;
workarounds |= sbp2_workarounds_table[i].workarounds;
break;
@@ -1403,7 +1415,7 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid),
workarounds, firmware_revision,
ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id,
- ud->model_id);
+ model);
/* We would need one SCSI host template for each target to adjust
* max_sectors on the fly, therefore warn only. */
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index f1e82a92e61..5130fc55b8e 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -927,8 +927,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
unsigned long flags;
int ret = 0;
- service_mask = service_mask ? service_mask :
- __constant_cpu_to_be64(~0ULL);
+ service_mask = service_mask ? service_mask : ~cpu_to_be64(0);
service_id &= service_mask;
if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID &&
(service_id != IB_CM_ASSIGN_SERVICE_ID))
@@ -954,7 +953,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
spin_lock_irqsave(&cm.lock, flags);
if (service_id == IB_CM_ASSIGN_SERVICE_ID) {
cm_id->service_id = cpu_to_be64(cm.listen_service_id++);
- cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id->service_mask = ~cpu_to_be64(0);
} else {
cm_id->service_id = service_id;
cm_id->service_mask = service_mask;
@@ -1134,7 +1133,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
goto error1;
}
cm_id->service_id = param->service_id;
- cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id->service_mask = ~cpu_to_be64(0);
cm_id_priv->timeout_ms = cm_convert_to_ms(
param->primary_path->packet_life_time) * 2 +
cm_convert_to_ms(
@@ -1545,7 +1544,7 @@ static int cm_req_handler(struct cm_work *work)
cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler;
cm_id_priv->id.context = listen_cm_id_priv->id.context;
cm_id_priv->id.service_id = req_msg->service_id;
- cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id_priv->id.service_mask = ~cpu_to_be64(0);
cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
@@ -2898,7 +2897,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
goto out;
cm_id->service_id = param->service_id;
- cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id->service_mask = ~cpu_to_be64(0);
cm_id_priv->timeout_ms = param->timeout_ms;
cm_id_priv->max_cm_retries = param->max_cm_retries;
ret = cm_alloc_msg(cm_id_priv, &msg);
@@ -2992,7 +2991,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler;
cm_id_priv->id.context = cur_cm_id_priv->id.context;
cm_id_priv->id.service_id = sidr_req_msg->service_id;
- cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id_priv->id.service_mask = ~cpu_to_be64(0);
cm_format_sidr_req_event(work, &cur_cm_id_priv->id);
cm_process_work(cm_id_priv, work);
@@ -3789,7 +3788,7 @@ static int __init ib_cm_init(void)
rwlock_init(&cm.device_lock);
spin_lock_init(&cm.lock);
cm.listen_service_table = RB_ROOT;
- cm.listen_service_id = __constant_be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
+ cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
cm.remote_id_table = RB_ROOT;
cm.remote_qp_table = RB_ROOT;
cm.remote_sidr_table = RB_ROOT;
diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
index aec9c7af825..7e63c08f697 100644
--- a/drivers/infiniband/core/cm_msgs.h
+++ b/drivers/infiniband/core/cm_msgs.h
@@ -44,17 +44,17 @@
#define IB_CM_CLASS_VERSION 2 /* IB specification 1.2 */
-#define CM_REQ_ATTR_ID __constant_htons(0x0010)
-#define CM_MRA_ATTR_ID __constant_htons(0x0011)
-#define CM_REJ_ATTR_ID __constant_htons(0x0012)
-#define CM_REP_ATTR_ID __constant_htons(0x0013)
-#define CM_RTU_ATTR_ID __constant_htons(0x0014)
-#define CM_DREQ_ATTR_ID __constant_htons(0x0015)
-#define CM_DREP_ATTR_ID __constant_htons(0x0016)
-#define CM_SIDR_REQ_ATTR_ID __constant_htons(0x0017)
-#define CM_SIDR_REP_ATTR_ID __constant_htons(0x0018)
-#define CM_LAP_ATTR_ID __constant_htons(0x0019)
-#define CM_APR_ATTR_ID __constant_htons(0x001A)
+#define CM_REQ_ATTR_ID cpu_to_be16(0x0010)
+#define CM_MRA_ATTR_ID cpu_to_be16(0x0011)
+#define CM_REJ_ATTR_ID cpu_to_be16(0x0012)
+#define CM_REP_ATTR_ID cpu_to_be16(0x0013)
+#define CM_RTU_ATTR_ID cpu_to_be16(0x0014)
+#define CM_DREQ_ATTR_ID cpu_to_be16(0x0015)
+#define CM_DREP_ATTR_ID cpu_to_be16(0x0016)
+#define CM_SIDR_REQ_ATTR_ID cpu_to_be16(0x0017)
+#define CM_SIDR_REP_ATTR_ID cpu_to_be16(0x0018)
+#define CM_LAP_ATTR_ID cpu_to_be16(0x0019)
+#define CM_APR_ATTR_ID cpu_to_be16(0x001A)
enum cm_msg_sequence {
CM_MSG_SEQUENCE_REQ,
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 7913b804311..d1fba415333 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -193,7 +193,7 @@ void ib_dealloc_device(struct ib_device *device)
BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
- ib_device_unregister_sysfs(device);
+ kobject_put(&device->dev.kobj);
}
EXPORT_SYMBOL(ib_dealloc_device);
@@ -348,6 +348,8 @@ void ib_unregister_device(struct ib_device *device)
mutex_unlock(&device_mutex);
+ ib_device_unregister_sysfs(device);
+
spin_lock_irqsave(&device->client_data_lock, flags);
list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
kfree(context);
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 5c54fc2350b..de922a04ca2 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -301,6 +301,16 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
mad_agent_priv->agent.context = context;
mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp;
mad_agent_priv->agent.port_num = port_num;
+ spin_lock_init(&mad_agent_priv->lock);
+ INIT_LIST_HEAD(&mad_agent_priv->send_list);
+ INIT_LIST_HEAD(&mad_agent_priv->wait_list);
+ INIT_LIST_HEAD(&mad_agent_priv->done_list);
+ INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
+ INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
+ INIT_LIST_HEAD(&mad_agent_priv->local_list);
+ INIT_WORK(&mad_agent_priv->local_work, local_completions);
+ atomic_set(&mad_agent_priv->refcount, 1);
+ init_completion(&mad_agent_priv->comp);
spin_lock_irqsave(&port_priv->reg_lock, flags);
mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
@@ -350,17 +360,6 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
list_add_tail(&mad_agent_priv->agent_list, &port_priv->agent_list);
spin_unlock_irqrestore(&port_priv->reg_lock, flags);
- spin_lock_init(&mad_agent_priv->lock);
- INIT_LIST_HEAD(&mad_agent_priv->send_list);
- INIT_LIST_HEAD(&mad_agent_priv->wait_list);
- INIT_LIST_HEAD(&mad_agent_priv->done_list);
- INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
- INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
- INIT_LIST_HEAD(&mad_agent_priv->local_list);
- INIT_WORK(&mad_agent_priv->local_work, local_completions);
- atomic_set(&mad_agent_priv->refcount, 1);
- init_completion(&mad_agent_priv->comp);
-
return &mad_agent_priv->agent;
error4:
@@ -743,9 +742,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
break;
case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
kmem_cache_free(ib_mad_cache, mad_priv);
- kfree(local);
- ret = 1;
- goto out;
+ break;
case IB_MAD_RESULT_SUCCESS:
/* Treat like an incoming receive MAD */
port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
@@ -756,10 +753,12 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
&mad_priv->mad.mad);
}
if (!port_priv || !recv_mad_agent) {
+ /*
+ * No receiving agent so drop packet and
+ * generate send completion.
+ */
kmem_cache_free(ib_mad_cache, mad_priv);
- kfree(local);
- ret = 0;
- goto out;
+ break;
}
local->mad_priv = mad_priv;
local->recv_mad_agent = recv_mad_agent;
@@ -2356,7 +2355,7 @@ static void local_completions(struct work_struct *work)
struct ib_mad_local_private *local;
struct ib_mad_agent_private *recv_mad_agent;
unsigned long flags;
- int recv = 0;
+ int free_mad;
struct ib_wc wc;
struct ib_mad_send_wc mad_send_wc;
@@ -2370,14 +2369,15 @@ static void local_completions(struct work_struct *work)
completion_list);
list_del(&local->completion_list);
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+ free_mad = 0;
if (local->mad_priv) {
recv_mad_agent = local->recv_mad_agent;
if (!recv_mad_agent) {
printk(KERN_ERR PFX "No receive MAD agent for local completion\n");
+ free_mad = 1;
goto local_send_completion;
}
- recv = 1;
/*
* Defined behavior is to complete response
* before request
@@ -2422,7 +2422,7 @@ local_send_completion:
spin_lock_irqsave(&mad_agent_priv->lock, flags);
atomic_dec(&mad_agent_priv->refcount);
- if (!recv)
+ if (free_mad)
kmem_cache_free(ib_mad_cache, local->mad_priv);
kfree(local);
}
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 3af2b84cd83..57a3c6f947b 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -735,7 +735,7 @@ process_rmpp_data(struct ib_mad_agent_private *agent,
goto bad;
}
- if (rmpp_hdr->seg_num == __constant_htonl(1)) {
+ if (rmpp_hdr->seg_num == cpu_to_be32(1)) {
if (!(ib_get_rmpp_flags(rmpp_hdr) & IB_MGMT_RMPP_FLAG_FIRST)) {
rmpp_status = IB_MGMT_RMPP_STATUS_BAD_SEG;
goto bad;
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 7863a50d56f..1865049e80f 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -395,6 +395,8 @@ static void update_sm_ah(struct work_struct *work)
}
spin_lock_irq(&port->ah_lock);
+ if (port->sm_ah)
+ kref_put(&port->sm_ah->ref, free_sm_ah);
port->sm_ah = new_ah;
spin_unlock_irq(&port->ah_lock);
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index b43f7d3682d..5c04cfb54cb 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -66,11 +66,6 @@ struct port_table_attribute {
int index;
};
-static inline int ibdev_is_alive(const struct ib_device *dev)
-{
- return dev->reg_state == IB_DEV_REGISTERED;
-}
-
static ssize_t port_attr_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
@@ -80,8 +75,6 @@ static ssize_t port_attr_show(struct kobject *kobj,
if (!port_attr->show)
return -EIO;
- if (!ibdev_is_alive(p->ibdev))
- return -ENODEV;
return port_attr->show(p, port_attr, buf);
}
@@ -562,9 +555,6 @@ static ssize_t show_node_type(struct device *device,
{
struct ib_device *dev = container_of(device, struct ib_device, dev);
- if (!ibdev_is_alive(dev))
- return -ENODEV;
-
switch (dev->node_type) {
case RDMA_NODE_IB_CA: return sprintf(buf, "%d: CA\n", dev->node_type);
case RDMA_NODE_RNIC: return sprintf(buf, "%d: RNIC\n", dev->node_type);
@@ -581,9 +571,6 @@ static ssize_t show_sys_image_guid(struct device *device,
struct ib_device_attr attr;
ssize_t ret;
- if (!ibdev_is_alive(dev))
- return -ENODEV;
-
ret = ib_query_device(dev, &attr);
if (ret)
return ret;
@@ -600,9 +587,6 @@ static ssize_t show_node_guid(struct device *device,
{
struct ib_device *dev = container_of(device, struct ib_device, dev);
- if (!ibdev_is_alive(dev))
- return -ENODEV;
-
return sprintf(buf, "%04x:%04x:%04x:%04x\n",
be16_to_cpu(((__be16 *) &dev->node_guid)[0]),
be16_to_cpu(((__be16 *) &dev->node_guid)[1]),
@@ -848,6 +832,9 @@ void ib_device_unregister_sysfs(struct ib_device *device)
struct kobject *p, *t;
struct ib_port *port;
+ /* Hold kobject until ib_dealloc_device() */
+ kobject_get(&device->dev.kobj);
+
list_for_each_entry_safe(p, t, &device->port_list, entry) {
list_del(&p->entry);
port = container_of(p, struct ib_port, kobj);
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
index 113f3c03c5b..7d79aa361e2 100644
--- a/drivers/infiniband/hw/amso1100/c2.c
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -76,7 +76,6 @@ static irqreturn_t c2_interrupt(int irq, void *dev_id);
static void c2_tx_timeout(struct net_device *netdev);
static int c2_change_mtu(struct net_device *netdev, int new_mtu);
static void c2_reset(struct c2_port *c2_port);
-static struct net_device_stats *c2_get_stats(struct net_device *netdev);
static struct pci_device_id c2_pci_table[] = {
{ PCI_DEVICE(0x18b8, 0xb001) },
@@ -349,7 +348,7 @@ static void c2_tx_clean(struct c2_port *c2_port)
elem->hw_desc + C2_TXP_ADDR);
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_DONE),
elem->hw_desc + C2_TXP_FLAGS);
- c2_port->netstats.tx_dropped++;
+ c2_port->netdev->stats.tx_dropped++;
break;
} else {
__raw_writew(0,
@@ -457,7 +456,7 @@ static void c2_rx_error(struct c2_port *c2_port, struct c2_element *elem)
elem->hw_desc + C2_RXP_FLAGS);
pr_debug("packet dropped\n");
- c2_port->netstats.rx_dropped++;
+ c2_port->netdev->stats.rx_dropped++;
}
static void c2_rx_interrupt(struct net_device *netdev)
@@ -532,8 +531,8 @@ static void c2_rx_interrupt(struct net_device *netdev)
netif_rx(skb);
netdev->last_rx = jiffies;
- c2_port->netstats.rx_packets++;
- c2_port->netstats.rx_bytes += buflen;
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += buflen;
}
/* Save where we left off */
@@ -797,8 +796,8 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
elem->hw_desc + C2_TXP_FLAGS);
- c2_port->netstats.tx_packets++;
- c2_port->netstats.tx_bytes += maplen;
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += maplen;
/* Loop thru additional data fragments and queue them */
if (skb_shinfo(skb)->nr_frags) {
@@ -823,8 +822,8 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
elem->hw_desc + C2_TXP_FLAGS);
- c2_port->netstats.tx_packets++;
- c2_port->netstats.tx_bytes += maplen;
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += maplen;
}
}
@@ -845,13 +844,6 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
-static struct net_device_stats *c2_get_stats(struct net_device *netdev)
-{
- struct c2_port *c2_port = netdev_priv(netdev);
-
- return &c2_port->netstats;
-}
-
static void c2_tx_timeout(struct net_device *netdev)
{
struct c2_port *c2_port = netdev_priv(netdev);
@@ -880,6 +872,16 @@ static int c2_change_mtu(struct net_device *netdev, int new_mtu)
return ret;
}
+static const struct net_device_ops c2_netdev = {
+ .ndo_open = c2_up,
+ .ndo_stop = c2_down,
+ .ndo_start_xmit = c2_xmit_frame,
+ .ndo_tx_timeout = c2_tx_timeout,
+ .ndo_change_mtu = c2_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* Initialize network device */
static struct net_device *c2_devinit(struct c2_dev *c2dev,
void __iomem * mmio_addr)
@@ -894,12 +896,7 @@ static struct net_device *c2_devinit(struct c2_dev *c2dev,
SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);
- netdev->open = c2_up;
- netdev->stop = c2_down;
- netdev->hard_start_xmit = c2_xmit_frame;
- netdev->get_stats = c2_get_stats;
- netdev->tx_timeout = c2_tx_timeout;
- netdev->change_mtu = c2_change_mtu;
+ netdev->netdev_ops = &c2_netdev;
netdev->watchdog_timeo = C2_TX_TIMEOUT;
netdev->irq = c2dev->pcidev->irq;
diff --git a/drivers/infiniband/hw/amso1100/c2.h b/drivers/infiniband/hw/amso1100/c2.h
index d12a24a84fd..f7ff66f9836 100644
--- a/drivers/infiniband/hw/amso1100/c2.h
+++ b/drivers/infiniband/hw/amso1100/c2.h
@@ -369,8 +369,6 @@ struct c2_port {
unsigned long mem_size;
u32 rx_buf_size;
-
- struct net_device_stats netstats;
};
/*
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index 5119d650818..f1948fad85d 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -708,26 +708,27 @@ static int c2_pseudo_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu)
{
- int ret = 0;
-
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
return -EINVAL;
netdev->mtu = new_mtu;
/* TODO: Tell rnic about new rmda interface mtu */
- return ret;
+ return 0;
}
+static const struct net_device_ops c2_pseudo_netdev_ops = {
+ .ndo_open = c2_pseudo_up,
+ .ndo_stop = c2_pseudo_down,
+ .ndo_start_xmit = c2_pseudo_xmit_frame,
+ .ndo_change_mtu = c2_pseudo_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static void setup(struct net_device *netdev)
{
- netdev->open = c2_pseudo_up;
- netdev->stop = c2_pseudo_down;
- netdev->hard_start_xmit = c2_pseudo_xmit_frame;
- netdev->get_stats = NULL;
- netdev->tx_timeout = NULL;
- netdev->set_mac_address = NULL;
- netdev->change_mtu = c2_pseudo_change_mtu;
+ netdev->netdev_ops = &c2_pseudo_netdev_ops;
+
netdev->watchdog_timeo = 0;
netdev->type = ARPHRD_ETHER;
netdev->mtu = 1500;
@@ -735,7 +736,6 @@ static void setup(struct net_device *netdev)
netdev->addr_len = ETH_ALEN;
netdev->tx_queue_len = 0;
netdev->flags |= IFF_NOARP;
- return;
}
static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 4dcf08b3fd8..a4a82bff710 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -450,7 +450,7 @@ static int cqe_completes_wr(struct t3_cqe *cqe, struct t3_wq *wq)
if ((CQE_OPCODE(*cqe) == T3_READ_RESP) && SQ_TYPE(*cqe))
return 0;
- if ((CQE_OPCODE(*cqe) == T3_SEND) && RQ_TYPE(*cqe) &&
+ if (CQE_SEND_OPCODE(*cqe) && RQ_TYPE(*cqe) &&
Q_EMPTY(wq->rq_rptr, wq->rq_wptr))
return 0;
@@ -701,6 +701,9 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
u32 stag_idx;
u32 wptr;
+ if (rdev_p->flags)
+ return -EIO;
+
stag_state = stag_state > 0;
stag_idx = (*stag) >> 8;
@@ -938,6 +941,23 @@ int cxio_rdev_open(struct cxio_rdev *rdev_p)
if (!rdev_p->t3cdev_p)
rdev_p->t3cdev_p = dev2t3cdev(netdev_p);
rdev_p->t3cdev_p->ulp = (void *) rdev_p;
+
+ err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, GET_EMBEDDED_INFO,
+ &(rdev_p->fw_info));
+ if (err) {
+ printk(KERN_ERR "%s t3cdev_p(%p)->ctl returned error %d.\n",
+ __func__, rdev_p->t3cdev_p, err);
+ goto err1;
+ }
+ if (G_FW_VERSION_MAJOR(rdev_p->fw_info.fw_vers) != CXIO_FW_MAJ) {
+ printk(KERN_ERR MOD "fatal firmware version mismatch: "
+ "need version %u but adapter has version %u\n",
+ CXIO_FW_MAJ,
+ G_FW_VERSION_MAJOR(rdev_p->fw_info.fw_vers));
+ err = -EINVAL;
+ goto err1;
+ }
+
err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, RDMA_GET_PARAMS,
&(rdev_p->rnic_info));
if (err) {
@@ -1204,11 +1224,12 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
}
/* incoming SEND with no receive posted failures */
- if ((CQE_OPCODE(*hw_cqe) == T3_SEND) && RQ_TYPE(*hw_cqe) &&
+ if (CQE_SEND_OPCODE(*hw_cqe) && RQ_TYPE(*hw_cqe) &&
Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
ret = -1;
goto skip_cqe;
}
+ BUG_ON((*cqe_flushed == 0) && !SW_CQE(*hw_cqe));
goto proc_cqe;
}
@@ -1223,6 +1244,13 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
* then we complete this with TPT_ERR_MSN and mark the wq in
* error.
*/
+
+ if (Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
+ wq->error = 1;
+ ret = -1;
+ goto skip_cqe;
+ }
+
if (unlikely((CQE_WRID_MSN(*hw_cqe) != (wq->rq_rptr + 1)))) {
wq->error = 1;
hw_cqe->header |= htonl(V_CQE_STATUS(TPT_ERR_MSN));
@@ -1277,6 +1305,7 @@ proc_cqe:
cxio_hal_pblpool_free(wq->rdev,
wq->rq[Q_PTR2IDX(wq->rq_rptr,
wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE);
+ BUG_ON(Q_EMPTY(wq->rq_rptr, wq->rq_wptr));
wq->rq_rptr++;
}
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 656fe47bc84..094a66d1480 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -61,6 +61,8 @@
#define T3_MAX_DEV_NAME_LEN 32
+#define CXIO_FW_MAJ 7
+
struct cxio_hal_ctrl_qp {
u32 wptr;
u32 rptr;
@@ -108,6 +110,9 @@ struct cxio_rdev {
struct gen_pool *pbl_pool;
struct gen_pool *rqt_pool;
struct list_head entry;
+ struct ch_embedded_info fw_info;
+ u32 flags;
+#define CXIO_ERROR_FATAL 1
};
static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h
index 04618f7bfbb..ff9be1a1310 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_wr.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h
@@ -604,6 +604,12 @@ struct t3_cqe {
#define CQE_STATUS(x) (G_CQE_STATUS(be32_to_cpu((x).header)))
#define CQE_OPCODE(x) (G_CQE_OPCODE(be32_to_cpu((x).header)))
+#define CQE_SEND_OPCODE(x)( \
+ (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND) || \
+ (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE) || \
+ (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_INV) || \
+ (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE_INV))
+
#define CQE_LEN(x) (be32_to_cpu((x).len))
/* used for RQ completion processing */
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index 4489c89d671..37a4fc264a0 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -51,13 +51,15 @@ cxgb3_cpl_handler_func t3c_handlers[NUM_CPL_CMDS];
static void open_rnic_dev(struct t3cdev *);
static void close_rnic_dev(struct t3cdev *);
+static void iwch_err_handler(struct t3cdev *, u32, u32);
struct cxgb3_client t3c_client = {
.name = "iw_cxgb3",
.add = open_rnic_dev,
.remove = close_rnic_dev,
.handlers = t3c_handlers,
- .redirect = iwch_ep_redirect
+ .redirect = iwch_ep_redirect,
+ .err_handler = iwch_err_handler
};
static LIST_HEAD(dev_list);
@@ -160,6 +162,17 @@ static void close_rnic_dev(struct t3cdev *tdev)
mutex_unlock(&dev_mutex);
}
+static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error)
+{
+ struct cxio_rdev *rdev = tdev->ulp;
+
+ if (status == OFFLOAD_STATUS_DOWN)
+ rdev->flags = CXIO_ERROR_FATAL;
+
+ return;
+
+}
+
static int __init iwch_init_module(void)
{
int err;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 44e936e48a3..8699947aaf6 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1678,6 +1678,9 @@ static int terminate(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
{
struct iwch_ep *ep = ctx;
+ if (state_read(&ep->com) != FPDU_MODE)
+ return CPL_RET_BUF_DONE;
+
PDBG("%s ep %p\n", __func__, ep);
skb_pull(skb, sizeof(struct cpl_rdma_terminate));
PDBG("%s saving %d bytes of term msg\n", __func__, skb->len);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c
index 7b67a677172..743c5d8b880 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_ev.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c
@@ -179,11 +179,6 @@ void iwch_ev_dispatch(struct cxio_rdev *rdev_p, struct sk_buff *skb)
case TPT_ERR_BOUND:
case TPT_ERR_INVALIDATE_SHARED_MR:
case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
- printk(KERN_ERR "%s - CQE Err qpid 0x%x opcode %d status 0x%x "
- "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __func__,
- CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
- CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
- CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
(*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1);
break;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 19661b2f040..c758fbd5847 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -99,8 +99,8 @@ static int build_rdma_write(union t3_wr *wqe, struct ib_send_wr *wr,
if (wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) {
plen = 4;
wqe->write.sgl[0].stag = wr->ex.imm_data;
- wqe->write.sgl[0].len = __constant_cpu_to_be32(0);
- wqe->write.num_sgle = __constant_cpu_to_be32(0);
+ wqe->write.sgl[0].len = cpu_to_be32(0);
+ wqe->write.num_sgle = cpu_to_be32(0);
*flit_cnt = 6;
} else {
plen = 0;
@@ -195,15 +195,12 @@ static int build_inv_stag(union t3_wr *wqe, struct ib_send_wr *wr,
return 0;
}
-/*
- * TBD: this is going to be moved to firmware. Missing pdid/qpid check for now.
- */
static int iwch_sgl2pbl_map(struct iwch_dev *rhp, struct ib_sge *sg_list,
u32 num_sgle, u32 * pbl_addr, u8 * page_size)
{
int i;
struct iwch_mr *mhp;
- u32 offset;
+ u64 offset;
for (i = 0; i < num_sgle; i++) {
mhp = get_mhp(rhp, (sg_list[i].lkey) >> 8);
@@ -235,8 +232,8 @@ static int iwch_sgl2pbl_map(struct iwch_dev *rhp, struct ib_sge *sg_list,
return -EINVAL;
}
offset = sg_list[i].addr - mhp->attr.va_fbo;
- offset += ((u32) mhp->attr.va_fbo) %
- (1UL << (12 + mhp->attr.page_size));
+ offset += mhp->attr.va_fbo &
+ ((1UL << (12 + mhp->attr.page_size)) - 1);
pbl_addr[i] = ((mhp->attr.pbl_addr -
rhp->rdev.rnic_info.pbl_base) >> 3) +
(offset >> (12 + mhp->attr.page_size));
@@ -266,8 +263,8 @@ static int build_rdma_recv(struct iwch_qp *qhp, union t3_wr *wqe,
wqe->recv.sgl[i].len = cpu_to_be32(wr->sg_list[i].length);
/* to in the WQE == the offset into the page */
- wqe->recv.sgl[i].to = cpu_to_be64(((u32) wr->sg_list[i].addr) %
- (1UL << (12 + page_size[i])));
+ wqe->recv.sgl[i].to = cpu_to_be64(((u32)wr->sg_list[i].addr) &
+ ((1UL << (12 + page_size[i])) - 1));
/* pbl_addr is the adapters address in the PBL */
wqe->recv.pbl_addr[i] = cpu_to_be32(pbl_addr[i]);
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 2f4c28a3027..97e4b231cdc 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -196,7 +196,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
if (h_ret != H_SUCCESS) {
ehca_err(device, "hipz_h_alloc_resource_cq() failed "
- "h_ret=%li device=%p", h_ret, device);
+ "h_ret=%lli device=%p", h_ret, device);
cq = ERR_PTR(ehca2ib_return_code(h_ret));
goto create_cq_exit2;
}
@@ -232,7 +232,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
if (h_ret < H_SUCCESS) {
ehca_err(device, "hipz_h_register_rpage_cq() failed "
- "ehca_cq=%p cq_num=%x h_ret=%li counter=%i "
+ "ehca_cq=%p cq_num=%x h_ret=%lli counter=%i "
"act_pages=%i", my_cq, my_cq->cq_number,
h_ret, counter, param.act_pages);
cq = ERR_PTR(-EINVAL);
@@ -244,7 +244,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
if ((h_ret != H_SUCCESS) || vpage) {
ehca_err(device, "Registration of pages not "
"complete ehca_cq=%p cq_num=%x "
- "h_ret=%li", my_cq, my_cq->cq_number,
+ "h_ret=%lli", my_cq, my_cq->cq_number,
h_ret);
cq = ERR_PTR(-EAGAIN);
goto create_cq_exit4;
@@ -252,7 +252,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
} else {
if (h_ret != H_PAGE_REGISTERED) {
ehca_err(device, "Registration of page failed "
- "ehca_cq=%p cq_num=%x h_ret=%li "
+ "ehca_cq=%p cq_num=%x h_ret=%lli "
"counter=%i act_pages=%i",
my_cq, my_cq->cq_number,
h_ret, counter, param.act_pages);
@@ -266,7 +266,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
gal = my_cq->galpas.kernel;
cqx_fec = hipz_galpa_load(gal, CQTEMM_OFFSET(cqx_fec));
- ehca_dbg(device, "ehca_cq=%p cq_num=%x CQX_FEC=%lx",
+ ehca_dbg(device, "ehca_cq=%p cq_num=%x CQX_FEC=%llx",
my_cq, my_cq->cq_number, cqx_fec);
my_cq->ib_cq.cqe = my_cq->nr_of_entries =
@@ -307,7 +307,7 @@ create_cq_exit3:
h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1);
if (h_ret != H_SUCCESS)
ehca_err(device, "hipz_h_destroy_cq() failed ehca_cq=%p "
- "cq_num=%x h_ret=%li", my_cq, my_cq->cq_number, h_ret);
+ "cq_num=%x h_ret=%lli", my_cq, my_cq->cq_number, h_ret);
create_cq_exit2:
write_lock_irqsave(&ehca_cq_idr_lock, flags);
@@ -355,7 +355,7 @@ int ehca_destroy_cq(struct ib_cq *cq)
h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0);
if (h_ret == H_R_STATE) {
/* cq in err: read err data and destroy it forcibly */
- ehca_dbg(device, "ehca_cq=%p cq_num=%x ressource=%lx in err "
+ ehca_dbg(device, "ehca_cq=%p cq_num=%x resource=%llx in err "
"state. Try to delete it forcibly.",
my_cq, cq_num, my_cq->ipz_cq_handle.handle);
ehca_error_data(shca, my_cq, my_cq->ipz_cq_handle.handle);
@@ -365,7 +365,7 @@ int ehca_destroy_cq(struct ib_cq *cq)
cq_num);
}
if (h_ret != H_SUCCESS) {
- ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%li "
+ ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%lli "
"ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num);
return ehca2ib_return_code(h_ret);
}
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 46288220cfb..9209c5332df 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -393,7 +393,7 @@ int ehca_modify_port(struct ib_device *ibdev,
hret = hipz_h_modify_port(shca->ipz_hca_handle, port,
cap, props->init_type, port_modify_mask);
if (hret != H_SUCCESS) {
- ehca_err(&shca->ib_device, "Modify port failed h_ret=%li",
+ ehca_err(&shca->ib_device, "Modify port failed h_ret=%lli",
hret);
ret = -EINVAL;
}
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 3128a5090db..99bcbd7ffb0 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -99,7 +99,7 @@ static void print_error_data(struct ehca_shca *shca, void *data,
return;
ehca_err(&shca->ib_device,
- "QP 0x%x (resource=%lx) has errors.",
+ "QP 0x%x (resource=%llx) has errors.",
qp->ib_qp.qp_num, resource);
break;
}
@@ -108,21 +108,21 @@ static void print_error_data(struct ehca_shca *shca, void *data,
struct ehca_cq *cq = (struct ehca_cq *)data;
ehca_err(&shca->ib_device,
- "CQ 0x%x (resource=%lx) has errors.",
+ "CQ 0x%x (resource=%llx) has errors.",
cq->cq_number, resource);
break;
}
default:
ehca_err(&shca->ib_device,
- "Unknown error type: %lx on %s.",
+ "Unknown error type: %llx on %s.",
type, shca->ib_device.name);
break;
}
- ehca_err(&shca->ib_device, "Error data is available: %lx.", resource);
+ ehca_err(&shca->ib_device, "Error data is available: %llx.", resource);
ehca_err(&shca->ib_device, "EHCA ----- error data begin "
"---------------------------------------------------");
- ehca_dmp(rblock, length, "resource=%lx", resource);
+ ehca_dmp(rblock, length, "resource=%llx", resource);
ehca_err(&shca->ib_device, "EHCA ----- error data end "
"----------------------------------------------------");
@@ -152,7 +152,7 @@ int ehca_error_data(struct ehca_shca *shca, void *data,
if (ret == H_R_STATE)
ehca_err(&shca->ib_device,
- "No error data is available: %lx.", resource);
+ "No error data is available: %llx.", resource);
else if (ret == H_SUCCESS) {
int length;
@@ -164,7 +164,7 @@ int ehca_error_data(struct ehca_shca *shca, void *data,
print_error_data(shca, data, rblock, length);
} else
ehca_err(&shca->ib_device,
- "Error data could not be fetched: %lx", resource);
+ "Error data could not be fetched: %llx", resource);
ehca_free_fw_ctrlblock(rblock);
@@ -514,7 +514,7 @@ static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe)
struct ehca_cq *cq;
eqe_value = eqe->entry;
- ehca_dbg(&shca->ib_device, "eqe_value=%lx", eqe_value);
+ ehca_dbg(&shca->ib_device, "eqe_value=%llx", eqe_value);
if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
ehca_dbg(&shca->ib_device, "Got completion event");
token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
@@ -603,7 +603,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
ret = hipz_h_eoi(eq->ist);
if (ret != H_SUCCESS)
ehca_err(&shca->ib_device,
- "bad return code EOI -rc = %ld\n", ret);
+ "bad return code EOI -rc = %lld\n", ret);
ehca_dbg(&shca->ib_device, "deadman found %x eqe", eqe_cnt);
}
if (unlikely(eqe_cnt == EHCA_EQE_CACHE_SIZE))
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index c7b8a506af6..368311ce332 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -304,7 +304,7 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
h_ret = hipz_h_query_hca(shca->ipz_hca_handle, rblock);
if (h_ret != H_SUCCESS) {
- ehca_gen_err("Cannot query device properties. h_ret=%li",
+ ehca_gen_err("Cannot query device properties. h_ret=%lli",
h_ret);
ret = -EPERM;
goto sense_attributes1;
@@ -391,7 +391,7 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
port = (struct hipz_query_port *)rblock;
h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
if (h_ret != H_SUCCESS) {
- ehca_gen_err("Cannot query port properties. h_ret=%li",
+ ehca_gen_err("Cannot query port properties. h_ret=%lli",
h_ret);
ret = -EPERM;
goto sense_attributes1;
@@ -682,7 +682,7 @@ static ssize_t ehca_show_adapter_handle(struct device *dev,
{
struct ehca_shca *shca = dev->driver_data;
- return sprintf(buf, "%lx\n", shca->ipz_hca_handle.handle);
+ return sprintf(buf, "%llx\n", shca->ipz_hca_handle.handle);
}
static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);
diff --git a/drivers/infiniband/hw/ehca/ehca_mcast.c b/drivers/infiniband/hw/ehca/ehca_mcast.c
index e3ef0264ccc..120aedf9f98 100644
--- a/drivers/infiniband/hw/ehca/ehca_mcast.c
+++ b/drivers/infiniband/hw/ehca/ehca_mcast.c
@@ -88,7 +88,7 @@ int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
if (h_ret != H_SUCCESS)
ehca_err(ibqp->device,
"ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed "
- "h_ret=%li", my_qp, ibqp->qp_num, h_ret);
+ "h_ret=%lli", my_qp, ibqp->qp_num, h_ret);
return ehca2ib_return_code(h_ret);
}
@@ -125,7 +125,7 @@ int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
if (h_ret != H_SUCCESS)
ehca_err(ibqp->device,
"ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed "
- "h_ret=%li", my_qp, ibqp->qp_num, h_ret);
+ "h_ret=%lli", my_qp, ibqp->qp_num, h_ret);
return ehca2ib_return_code(h_ret);
}
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index f974367cad4..72f83f7df61 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -204,7 +204,7 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
}
if ((size == 0) ||
(((u64)iova_start + size) < (u64)iova_start)) {
- ehca_err(pd->device, "bad input values: size=%lx iova_start=%p",
+ ehca_err(pd->device, "bad input values: size=%llx iova_start=%p",
size, iova_start);
ib_mr = ERR_PTR(-EINVAL);
goto reg_phys_mr_exit0;
@@ -309,8 +309,8 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
}
if (length == 0 || virt + length < virt) {
- ehca_err(pd->device, "bad input values: length=%lx "
- "virt_base=%lx", length, virt);
+ ehca_err(pd->device, "bad input values: length=%llx "
+ "virt_base=%llx", length, virt);
ib_mr = ERR_PTR(-EINVAL);
goto reg_user_mr_exit0;
}
@@ -373,7 +373,7 @@ reg_user_mr_fallback:
&e_mr->ib.ib_mr.rkey);
if (ret == -EINVAL && pginfo.hwpage_size > PAGE_SIZE) {
ehca_warn(pd->device, "failed to register mr "
- "with hwpage_size=%lx", hwpage_size);
+ "with hwpage_size=%llx", hwpage_size);
ehca_info(pd->device, "try to register mr with "
"kpage_size=%lx", PAGE_SIZE);
/*
@@ -509,7 +509,7 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
goto rereg_phys_mr_exit1;
if ((new_size == 0) ||
(((u64)iova_start + new_size) < (u64)iova_start)) {
- ehca_err(mr->device, "bad input values: new_size=%lx "
+ ehca_err(mr->device, "bad input values: new_size=%llx "
"iova_start=%p", new_size, iova_start);
ret = -EINVAL;
goto rereg_phys_mr_exit1;
@@ -580,8 +580,8 @@ int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
h_ret = hipz_h_query_mr(shca->ipz_hca_handle, e_mr, &hipzout);
if (h_ret != H_SUCCESS) {
- ehca_err(mr->device, "hipz_mr_query failed, h_ret=%li mr=%p "
- "hca_hndl=%lx mr_hndl=%lx lkey=%x",
+ ehca_err(mr->device, "hipz_mr_query failed, h_ret=%lli mr=%p "
+ "hca_hndl=%llx mr_hndl=%llx lkey=%x",
h_ret, mr, shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle, mr->lkey);
ret = ehca2ib_return_code(h_ret);
@@ -630,8 +630,8 @@ int ehca_dereg_mr(struct ib_mr *mr)
/* TODO: BUSY: MR still has bound window(s) */
h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr);
if (h_ret != H_SUCCESS) {
- ehca_err(mr->device, "hipz_free_mr failed, h_ret=%li shca=%p "
- "e_mr=%p hca_hndl=%lx mr_hndl=%lx mr->lkey=%x",
+ ehca_err(mr->device, "hipz_free_mr failed, h_ret=%lli shca=%p "
+ "e_mr=%p hca_hndl=%llx mr_hndl=%llx mr->lkey=%x",
h_ret, shca, e_mr, shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle, mr->lkey);
ret = ehca2ib_return_code(h_ret);
@@ -671,8 +671,8 @@ struct ib_mw *ehca_alloc_mw(struct ib_pd *pd)
h_ret = hipz_h_alloc_resource_mw(shca->ipz_hca_handle, e_mw,
e_pd->fw_pd, &hipzout);
if (h_ret != H_SUCCESS) {
- ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%li "
- "shca=%p hca_hndl=%lx mw=%p",
+ ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%lli "
+ "shca=%p hca_hndl=%llx mw=%p",
h_ret, shca, shca->ipz_hca_handle.handle, e_mw);
ib_mw = ERR_PTR(ehca2ib_return_code(h_ret));
goto alloc_mw_exit1;
@@ -713,8 +713,8 @@ int ehca_dealloc_mw(struct ib_mw *mw)
h_ret = hipz_h_free_resource_mw(shca->ipz_hca_handle, e_mw);
if (h_ret != H_SUCCESS) {
- ehca_err(mw->device, "hipz_free_mw failed, h_ret=%li shca=%p "
- "mw=%p rkey=%x hca_hndl=%lx mw_hndl=%lx",
+ ehca_err(mw->device, "hipz_free_mw failed, h_ret=%lli shca=%p "
+ "mw=%p rkey=%x hca_hndl=%llx mw_hndl=%llx",
h_ret, shca, mw, mw->rkey, shca->ipz_hca_handle.handle,
e_mw->ipz_mw_handle.handle);
return ehca2ib_return_code(h_ret);
@@ -840,7 +840,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
goto map_phys_fmr_exit0;
if (iova % e_fmr->fmr_page_size) {
/* only whole-numbered pages */
- ehca_err(fmr->device, "bad iova, iova=%lx fmr_page_size=%x",
+ ehca_err(fmr->device, "bad iova, iova=%llx fmr_page_size=%x",
iova, e_fmr->fmr_page_size);
ret = -EINVAL;
goto map_phys_fmr_exit0;
@@ -878,7 +878,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
map_phys_fmr_exit0:
if (ret)
ehca_err(fmr->device, "ret=%i fmr=%p page_list=%p list_len=%x "
- "iova=%lx", ret, fmr, page_list, list_len, iova);
+ "iova=%llx", ret, fmr, page_list, list_len, iova);
return ret;
} /* end ehca_map_phys_fmr() */
@@ -964,8 +964,8 @@ int ehca_dealloc_fmr(struct ib_fmr *fmr)
h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr);
if (h_ret != H_SUCCESS) {
- ehca_err(fmr->device, "hipz_free_mr failed, h_ret=%li e_fmr=%p "
- "hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x",
+ ehca_err(fmr->device, "hipz_free_mr failed, h_ret=%lli e_fmr=%p "
+ "hca_hndl=%llx fmr_hndl=%llx fmr->lkey=%x",
h_ret, e_fmr, shca->ipz_hca_handle.handle,
e_fmr->ipz_mr_handle.handle, fmr->lkey);
ret = ehca2ib_return_code(h_ret);
@@ -1007,8 +1007,8 @@ int ehca_reg_mr(struct ehca_shca *shca,
(u64)iova_start, size, hipz_acl,
e_pd->fw_pd, &hipzout);
if (h_ret != H_SUCCESS) {
- ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%li "
- "hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle);
+ ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%lli "
+ "hca_hndl=%llx", h_ret, shca->ipz_hca_handle.handle);
ret = ehca2ib_return_code(h_ret);
goto ehca_reg_mr_exit0;
}
@@ -1033,9 +1033,9 @@ int ehca_reg_mr(struct ehca_shca *shca,
ehca_reg_mr_exit1:
h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr);
if (h_ret != H_SUCCESS) {
- ehca_err(&shca->ib_device, "h_ret=%li shca=%p e_mr=%p "
- "iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x "
- "pginfo=%p num_kpages=%lx num_hwpages=%lx ret=%i",
+ ehca_err(&shca->ib_device, "h_ret=%lli shca=%p e_mr=%p "
+ "iova_start=%p size=%llx acl=%x e_pd=%p lkey=%x "
+ "pginfo=%p num_kpages=%llx num_hwpages=%llx ret=%i",
h_ret, shca, e_mr, iova_start, size, acl, e_pd,
hipzout.lkey, pginfo, pginfo->num_kpages,
pginfo->num_hwpages, ret);
@@ -1045,8 +1045,8 @@ ehca_reg_mr_exit1:
ehca_reg_mr_exit0:
if (ret)
ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p "
- "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "
- "num_kpages=%lx num_hwpages=%lx",
+ "iova_start=%p size=%llx acl=%x e_pd=%p pginfo=%p "
+ "num_kpages=%llx num_hwpages=%llx",
ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo,
pginfo->num_kpages, pginfo->num_hwpages);
return ret;
@@ -1116,8 +1116,8 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
*/
if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "last "
- "hipz_reg_rpage_mr failed, h_ret=%li "
- "e_mr=%p i=%x hca_hndl=%lx mr_hndl=%lx"
+ "hipz_reg_rpage_mr failed, h_ret=%lli "
+ "e_mr=%p i=%x hca_hndl=%llx mr_hndl=%llx"
" lkey=%x", h_ret, e_mr, i,
shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle,
@@ -1128,8 +1128,8 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
ret = 0;
} else if (h_ret != H_PAGE_REGISTERED) {
ehca_err(&shca->ib_device, "hipz_reg_rpage_mr failed, "
- "h_ret=%li e_mr=%p i=%x lkey=%x hca_hndl=%lx "
- "mr_hndl=%lx", h_ret, e_mr, i,
+ "h_ret=%lli e_mr=%p i=%x lkey=%x hca_hndl=%llx "
+ "mr_hndl=%llx", h_ret, e_mr, i,
e_mr->ib.ib_mr.lkey,
shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle);
@@ -1145,7 +1145,7 @@ ehca_reg_mr_rpages_exit1:
ehca_reg_mr_rpages_exit0:
if (ret)
ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p pginfo=%p "
- "num_kpages=%lx num_hwpages=%lx", ret, shca, e_mr,
+ "num_kpages=%llx num_hwpages=%llx", ret, shca, e_mr,
pginfo, pginfo->num_kpages, pginfo->num_hwpages);
return ret;
} /* end ehca_reg_mr_rpages() */
@@ -1184,7 +1184,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
ret = ehca_set_pagebuf(pginfo, pginfo->num_hwpages, kpage);
if (ret) {
ehca_err(&shca->ib_device, "set pagebuf failed, e_mr=%p "
- "pginfo=%p type=%x num_kpages=%lx num_hwpages=%lx "
+ "pginfo=%p type=%x num_kpages=%llx num_hwpages=%llx "
"kpage=%p", e_mr, pginfo, pginfo->type,
pginfo->num_kpages, pginfo->num_hwpages, kpage);
goto ehca_rereg_mr_rereg1_exit1;
@@ -1205,13 +1205,13 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
* (MW bound or MR is shared)
*/
ehca_warn(&shca->ib_device, "hipz_h_reregister_pmr failed "
- "(Rereg1), h_ret=%li e_mr=%p", h_ret, e_mr);
+ "(Rereg1), h_ret=%lli e_mr=%p", h_ret, e_mr);
*pginfo = pginfo_save;
ret = -EAGAIN;
} else if ((u64 *)hipzout.vaddr != iova_start) {
ehca_err(&shca->ib_device, "PHYP changed iova_start in "
- "rereg_pmr, iova_start=%p iova_start_out=%lx e_mr=%p "
- "mr_handle=%lx lkey=%x lkey_out=%x", iova_start,
+ "rereg_pmr, iova_start=%p iova_start_out=%llx e_mr=%p "
+ "mr_handle=%llx lkey=%x lkey_out=%x", iova_start,
hipzout.vaddr, e_mr, e_mr->ipz_mr_handle.handle,
e_mr->ib.ib_mr.lkey, hipzout.lkey);
ret = -EFAULT;
@@ -1235,7 +1235,7 @@ ehca_rereg_mr_rereg1_exit1:
ehca_rereg_mr_rereg1_exit0:
if ( ret && (ret != -EAGAIN) )
ehca_err(&shca->ib_device, "ret=%i lkey=%x rkey=%x "
- "pginfo=%p num_kpages=%lx num_hwpages=%lx",
+ "pginfo=%p num_kpages=%llx num_hwpages=%llx",
ret, *lkey, *rkey, pginfo, pginfo->num_kpages,
pginfo->num_hwpages);
return ret;
@@ -1263,7 +1263,7 @@ int ehca_rereg_mr(struct ehca_shca *shca,
(e_mr->num_hwpages > MAX_RPAGES) ||
(pginfo->num_hwpages > e_mr->num_hwpages)) {
ehca_dbg(&shca->ib_device, "Rereg3 case, "
- "pginfo->num_hwpages=%lx e_mr->num_hwpages=%x",
+ "pginfo->num_hwpages=%llx e_mr->num_hwpages=%x",
pginfo->num_hwpages, e_mr->num_hwpages);
rereg_1_hcall = 0;
rereg_3_hcall = 1;
@@ -1295,7 +1295,7 @@ int ehca_rereg_mr(struct ehca_shca *shca,
h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr);
if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "hipz_free_mr failed, "
- "h_ret=%li e_mr=%p hca_hndl=%lx mr_hndl=%lx "
+ "h_ret=%lli e_mr=%p hca_hndl=%llx mr_hndl=%llx "
"mr->lkey=%x",
h_ret, e_mr, shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle,
@@ -1328,8 +1328,8 @@ int ehca_rereg_mr(struct ehca_shca *shca,
ehca_rereg_mr_exit0:
if (ret)
ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p "
- "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "
- "num_kpages=%lx lkey=%x rkey=%x rereg_1_hcall=%x "
+ "iova_start=%p size=%llx acl=%x e_pd=%p pginfo=%p "
+ "num_kpages=%llx lkey=%x rkey=%x rereg_1_hcall=%x "
"rereg_3_hcall=%x", ret, shca, e_mr, iova_start, size,
acl, e_pd, pginfo, pginfo->num_kpages, *lkey, *rkey,
rereg_1_hcall, rereg_3_hcall);
@@ -1371,8 +1371,8 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
* FMRs are not shared and no MW bound to FMRs
*/
ehca_err(&shca->ib_device, "hipz_reregister_pmr failed "
- "(Rereg1), h_ret=%li e_fmr=%p hca_hndl=%lx "
- "mr_hndl=%lx lkey=%x lkey_out=%x",
+ "(Rereg1), h_ret=%lli e_fmr=%p hca_hndl=%llx "
+ "mr_hndl=%llx lkey=%x lkey_out=%x",
h_ret, e_fmr, shca->ipz_hca_handle.handle,
e_fmr->ipz_mr_handle.handle,
e_fmr->ib.ib_fmr.lkey, hipzout.lkey);
@@ -1383,7 +1383,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr);
if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "hipz_free_mr failed, "
- "h_ret=%li e_fmr=%p hca_hndl=%lx mr_hndl=%lx "
+ "h_ret=%lli e_fmr=%p hca_hndl=%llx mr_hndl=%llx "
"lkey=%x",
h_ret, e_fmr, shca->ipz_hca_handle.handle,
e_fmr->ipz_mr_handle.handle,
@@ -1447,9 +1447,9 @@ int ehca_reg_smr(struct ehca_shca *shca,
(u64)iova_start, hipz_acl, e_pd->fw_pd,
&hipzout);
if (h_ret != H_SUCCESS) {
- ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%li "
+ ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%lli "
"shca=%p e_origmr=%p e_newmr=%p iova_start=%p acl=%x "
- "e_pd=%p hca_hndl=%lx mr_hndl=%lx lkey=%x",
+ "e_pd=%p hca_hndl=%llx mr_hndl=%llx lkey=%x",
h_ret, shca, e_origmr, e_newmr, iova_start, acl, e_pd,
shca->ipz_hca_handle.handle,
e_origmr->ipz_mr_handle.handle,
@@ -1527,7 +1527,7 @@ int ehca_reg_internal_maxmr(
&e_mr->ib.ib_mr.rkey);
if (ret) {
ehca_err(&shca->ib_device, "reg of internal max MR failed, "
- "e_mr=%p iova_start=%p size_maxmr=%lx num_kpages=%x "
+ "e_mr=%p iova_start=%p size_maxmr=%llx num_kpages=%x "
"num_hwpages=%x", e_mr, iova_start, size_maxmr,
num_kpages, num_hwpages);
goto ehca_reg_internal_maxmr_exit1;
@@ -1573,8 +1573,8 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
(u64)iova_start, hipz_acl, e_pd->fw_pd,
&hipzout);
if (h_ret != H_SUCCESS) {
- ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%li "
- "e_origmr=%p hca_hndl=%lx mr_hndl=%lx lkey=%x",
+ ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%lli "
+ "e_origmr=%p hca_hndl=%llx mr_hndl=%llx lkey=%x",
h_ret, e_origmr, shca->ipz_hca_handle.handle,
e_origmr->ipz_mr_handle.handle,
e_origmr->ib.ib_mr.lkey);
@@ -1651,28 +1651,28 @@ int ehca_mr_chk_buf_and_calc_size(struct ib_phys_buf *phys_buf_array,
/* check first buffer */
if (((u64)iova_start & ~PAGE_MASK) != (pbuf->addr & ~PAGE_MASK)) {
ehca_gen_err("iova_start/addr mismatch, iova_start=%p "
- "pbuf->addr=%lx pbuf->size=%lx",
+ "pbuf->addr=%llx pbuf->size=%llx",
iova_start, pbuf->addr, pbuf->size);
return -EINVAL;
}
if (((pbuf->addr + pbuf->size) % PAGE_SIZE) &&
(num_phys_buf > 1)) {
- ehca_gen_err("addr/size mismatch in 1st buf, pbuf->addr=%lx "
- "pbuf->size=%lx", pbuf->addr, pbuf->size);
+ ehca_gen_err("addr/size mismatch in 1st buf, pbuf->addr=%llx "
+ "pbuf->size=%llx", pbuf->addr, pbuf->size);
return -EINVAL;
}
for (i = 0; i < num_phys_buf; i++) {
if ((i > 0) && (pbuf->addr % PAGE_SIZE)) {
- ehca_gen_err("bad address, i=%x pbuf->addr=%lx "
- "pbuf->size=%lx",
+ ehca_gen_err("bad address, i=%x pbuf->addr=%llx "
+ "pbuf->size=%llx",
i, pbuf->addr, pbuf->size);
return -EINVAL;
}
if (((i > 0) && /* not 1st */
(i < (num_phys_buf - 1)) && /* not last */
(pbuf->size % PAGE_SIZE)) || (pbuf->size == 0)) {
- ehca_gen_err("bad size, i=%x pbuf->size=%lx",
+ ehca_gen_err("bad size, i=%x pbuf->size=%llx",
i, pbuf->size);
return -EINVAL;
}
@@ -1705,7 +1705,7 @@ int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
page = page_list;
for (i = 0; i < list_len; i++) {
if (*page % e_fmr->fmr_page_size) {
- ehca_gen_err("bad page, i=%x *page=%lx page=%p fmr=%p "
+ ehca_gen_err("bad page, i=%x *page=%llx page=%p fmr=%p "
"fmr_page_size=%x", i, *page, page, e_fmr,
e_fmr->fmr_page_size);
return -EINVAL;
@@ -1743,9 +1743,9 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
(pginfo->next_hwpage *
pginfo->hwpage_size));
if ( !(*kpage) ) {
- ehca_gen_err("pgaddr=%lx "
- "chunk->page_list[i]=%lx "
- "i=%x next_hwpage=%lx",
+ ehca_gen_err("pgaddr=%llx "
+ "chunk->page_list[i]=%llx "
+ "i=%x next_hwpage=%llx",
pgaddr, (u64)sg_dma_address(
&chunk->page_list[i]),
i, pginfo->next_hwpage);
@@ -1795,11 +1795,11 @@ static int ehca_check_kpages_per_ate(struct scatterlist *page_list,
for (t = start_idx; t <= end_idx; t++) {
u64 pgaddr = page_to_pfn(sg_page(&page_list[t])) << PAGE_SHIFT;
if (ehca_debug_level >= 3)
- ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr,
+ ehca_gen_dbg("chunk_page=%llx value=%016llx", pgaddr,
*(u64 *)abs_to_virt(phys_to_abs(pgaddr)));
if (pgaddr - PAGE_SIZE != *prev_pgaddr) {
- ehca_gen_err("uncontiguous page found pgaddr=%lx "
- "prev_pgaddr=%lx page_list_i=%x",
+ ehca_gen_err("uncontiguous page found pgaddr=%llx "
+ "prev_pgaddr=%llx page_list_i=%x",
pgaddr, *prev_pgaddr, t);
return -EINVAL;
}
@@ -1833,7 +1833,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
<< PAGE_SHIFT );
*kpage = phys_to_abs(pgaddr);
if ( !(*kpage) ) {
- ehca_gen_err("pgaddr=%lx i=%x",
+ ehca_gen_err("pgaddr=%llx i=%x",
pgaddr, i);
ret = -EFAULT;
return ret;
@@ -1846,8 +1846,8 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
if (pginfo->hwpage_cnt) {
ehca_gen_err(
"invalid alignment "
- "pgaddr=%lx i=%x "
- "mr_pgsize=%lx",
+ "pgaddr=%llx i=%x "
+ "mr_pgsize=%llx",
pgaddr, i,
pginfo->hwpage_size);
ret = -EFAULT;
@@ -1866,8 +1866,8 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
if (ehca_debug_level >= 3) {
u64 val = *(u64 *)abs_to_virt(
phys_to_abs(pgaddr));
- ehca_gen_dbg("kpage=%lx chunk_page=%lx "
- "value=%016lx",
+ ehca_gen_dbg("kpage=%llx chunk_page=%llx "
+ "value=%016llx",
*kpage, pgaddr, val);
}
prev_pgaddr = pgaddr;
@@ -1944,9 +1944,9 @@ static int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
(pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
ehca_gen_err("kpage_cnt >= num_kpages, "
- "kpage_cnt=%lx num_kpages=%lx "
- "hwpage_cnt=%lx "
- "num_hwpages=%lx i=%x",
+ "kpage_cnt=%llx num_kpages=%llx "
+ "hwpage_cnt=%llx "
+ "num_hwpages=%llx i=%x",
pginfo->kpage_cnt,
pginfo->num_kpages,
pginfo->hwpage_cnt,
@@ -1957,8 +1957,8 @@ static int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
(pbuf->addr & ~(pginfo->hwpage_size - 1)) +
(pginfo->next_hwpage * pginfo->hwpage_size));
if ( !(*kpage) && pbuf->addr ) {
- ehca_gen_err("pbuf->addr=%lx pbuf->size=%lx "
- "next_hwpage=%lx", pbuf->addr,
+ ehca_gen_err("pbuf->addr=%llx pbuf->size=%llx "
+ "next_hwpage=%llx", pbuf->addr,
pbuf->size, pginfo->next_hwpage);
return -EFAULT;
}
@@ -1996,8 +1996,8 @@ static int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo,
*kpage = phys_to_abs((*fmrlist & ~(pginfo->hwpage_size - 1)) +
pginfo->next_hwpage * pginfo->hwpage_size);
if ( !(*kpage) ) {
- ehca_gen_err("*fmrlist=%lx fmrlist=%p "
- "next_listelem=%lx next_hwpage=%lx",
+ ehca_gen_err("*fmrlist=%llx fmrlist=%p "
+ "next_listelem=%llx next_hwpage=%llx",
*fmrlist, fmrlist,
pginfo->u.fmr.next_listelem,
pginfo->next_hwpage);
@@ -2025,7 +2025,7 @@ static int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo,
~(pginfo->hwpage_size - 1));
if (prev + pginfo->u.fmr.fmr_pgsize != p) {
ehca_gen_err("uncontiguous fmr pages "
- "found prev=%lx p=%lx "
+ "found prev=%llx p=%llx "
"idx=%x", prev, p, i + j);
return -EINVAL;
}
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index f161cf173db..00c10815971 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -331,7 +331,7 @@ static inline int init_qp_queue(struct ehca_shca *shca,
if (cnt == (nr_q_pages - 1)) { /* last page! */
if (h_ret != expected_hret) {
ehca_err(ib_dev, "hipz_qp_register_rpage() "
- "h_ret=%li", h_ret);
+ "h_ret=%lli", h_ret);
ret = ehca2ib_return_code(h_ret);
goto init_qp_queue1;
}
@@ -345,7 +345,7 @@ static inline int init_qp_queue(struct ehca_shca *shca,
} else {
if (h_ret != H_PAGE_REGISTERED) {
ehca_err(ib_dev, "hipz_qp_register_rpage() "
- "h_ret=%li", h_ret);
+ "h_ret=%lli", h_ret);
ret = ehca2ib_return_code(h_ret);
goto init_qp_queue1;
}
@@ -709,7 +709,7 @@ static struct ehca_qp *internal_create_qp(
h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms);
if (h_ret != H_SUCCESS) {
- ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%li",
+ ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%lli",
h_ret);
ret = ehca2ib_return_code(h_ret);
goto create_qp_exit1;
@@ -1010,7 +1010,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd,
mqpcb, my_qp->galpas.kernel);
if (hret != H_SUCCESS) {
ehca_err(pd->device, "Could not modify SRQ to INIT "
- "ehca_qp=%p qp_num=%x h_ret=%li",
+ "ehca_qp=%p qp_num=%x h_ret=%lli",
my_qp, my_qp->real_qp_num, hret);
goto create_srq2;
}
@@ -1024,7 +1024,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd,
mqpcb, my_qp->galpas.kernel);
if (hret != H_SUCCESS) {
ehca_err(pd->device, "Could not enable SRQ "
- "ehca_qp=%p qp_num=%x h_ret=%li",
+ "ehca_qp=%p qp_num=%x h_ret=%lli",
my_qp, my_qp->real_qp_num, hret);
goto create_srq2;
}
@@ -1038,7 +1038,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd,
mqpcb, my_qp->galpas.kernel);
if (hret != H_SUCCESS) {
ehca_err(pd->device, "Could not modify SRQ to RTR "
- "ehca_qp=%p qp_num=%x h_ret=%li",
+ "ehca_qp=%p qp_num=%x h_ret=%lli",
my_qp, my_qp->real_qp_num, hret);
goto create_srq2;
}
@@ -1078,7 +1078,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
&bad_send_wqe_p, NULL, 2);
if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "hipz_h_disable_and_get_wqe() failed"
- " ehca_qp=%p qp_num=%x h_ret=%li",
+ " ehca_qp=%p qp_num=%x h_ret=%lli",
my_qp, qp_num, h_ret);
return ehca2ib_return_code(h_ret);
}
@@ -1134,7 +1134,7 @@ static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue,
if (ipz_queue_abs_to_offset(ipz_queue, wqe_p, &q_ofs)) {
ehca_gen_err("Invalid offset for calculating left cqes "
- "wqe_p=%#lx wqe_v=%p\n", wqe_p, wqe_v);
+ "wqe_p=%#llx wqe_v=%p\n", wqe_p, wqe_v);
return -EFAULT;
}
@@ -1168,7 +1168,7 @@ static int check_for_left_cqes(struct ehca_qp *my_qp, struct ehca_shca *shca)
&send_wqe_p, &recv_wqe_p, 4);
if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "disable_and_get_wqe() "
- "failed ehca_qp=%p qp_num=%x h_ret=%li",
+ "failed ehca_qp=%p qp_num=%x h_ret=%lli",
my_qp, qp_num, h_ret);
return ehca2ib_return_code(h_ret);
}
@@ -1261,7 +1261,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
mqpcb, my_qp->galpas.kernel);
if (h_ret != H_SUCCESS) {
ehca_err(ibqp->device, "hipz_h_query_qp() failed "
- "ehca_qp=%p qp_num=%x h_ret=%li",
+ "ehca_qp=%p qp_num=%x h_ret=%lli",
my_qp, ibqp->qp_num, h_ret);
ret = ehca2ib_return_code(h_ret);
goto modify_qp_exit1;
@@ -1690,7 +1690,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
if (h_ret != H_SUCCESS) {
ret = ehca2ib_return_code(h_ret);
- ehca_err(ibqp->device, "hipz_h_modify_qp() failed h_ret=%li "
+ ehca_err(ibqp->device, "hipz_h_modify_qp() failed h_ret=%lli "
"ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num);
goto modify_qp_exit2;
}
@@ -1723,7 +1723,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
ret = ehca2ib_return_code(h_ret);
ehca_err(ibqp->device, "ENABLE in context of "
"RESET_2_INIT failed! Maybe you didn't get "
- "a LID h_ret=%li ehca_qp=%p qp_num=%x",
+ "a LID h_ret=%lli ehca_qp=%p qp_num=%x",
h_ret, my_qp, ibqp->qp_num);
goto modify_qp_exit2;
}
@@ -1909,7 +1909,7 @@ int ehca_query_qp(struct ib_qp *qp,
if (h_ret != H_SUCCESS) {
ret = ehca2ib_return_code(h_ret);
ehca_err(qp->device, "hipz_h_query_qp() failed "
- "ehca_qp=%p qp_num=%x h_ret=%li",
+ "ehca_qp=%p qp_num=%x h_ret=%lli",
my_qp, qp->qp_num, h_ret);
goto query_qp_exit1;
}
@@ -2074,7 +2074,7 @@ int ehca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
if (h_ret != H_SUCCESS) {
ret = ehca2ib_return_code(h_ret);
- ehca_err(ibsrq->device, "hipz_h_modify_qp() failed h_ret=%li "
+ ehca_err(ibsrq->device, "hipz_h_modify_qp() failed h_ret=%lli "
"ehca_qp=%p qp_num=%x",
h_ret, my_qp, my_qp->real_qp_num);
}
@@ -2108,7 +2108,7 @@ int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr)
if (h_ret != H_SUCCESS) {
ret = ehca2ib_return_code(h_ret);
ehca_err(srq->device, "hipz_h_query_qp() failed "
- "ehca_qp=%p qp_num=%x h_ret=%li",
+ "ehca_qp=%p qp_num=%x h_ret=%lli",
my_qp, my_qp->real_qp_num, h_ret);
goto query_srq_exit1;
}
@@ -2179,7 +2179,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
if (h_ret != H_SUCCESS) {
- ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li "
+ ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%lli "
"ehca_qp=%p qp_num=%x", h_ret, my_qp, qp_num);
return ehca2ib_return_code(h_ret);
}
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index c7112686782..5a3d96f84c7 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -822,7 +822,7 @@ static int generate_flush_cqes(struct ehca_qp *my_qp, struct ib_cq *cq,
offset = qmap->next_wqe_idx * ipz_queue->qe_size;
wqe = (struct ehca_wqe *)ipz_qeit_calc(ipz_queue, offset);
if (!wqe) {
- ehca_err(cq->device, "Invalid wqe offset=%#lx on "
+ ehca_err(cq->device, "Invalid wqe offset=%#llx on "
"qp_num=%#x", offset, my_qp->real_qp_num);
return nr;
}
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c
index 706d97ad555..c568b28f4e2 100644
--- a/drivers/infiniband/hw/ehca/ehca_sqp.c
+++ b/drivers/infiniband/hw/ehca/ehca_sqp.c
@@ -46,11 +46,11 @@
#include "ehca_iverbs.h"
#include "hcp_if.h"
-#define IB_MAD_STATUS_REDIRECT __constant_htons(0x0002)
-#define IB_MAD_STATUS_UNSUP_VERSION __constant_htons(0x0004)
-#define IB_MAD_STATUS_UNSUP_METHOD __constant_htons(0x0008)
+#define IB_MAD_STATUS_REDIRECT cpu_to_be16(0x0002)
+#define IB_MAD_STATUS_UNSUP_VERSION cpu_to_be16(0x0004)
+#define IB_MAD_STATUS_UNSUP_METHOD cpu_to_be16(0x0008)
-#define IB_PMA_CLASS_PORT_INFO __constant_htons(0x0001)
+#define IB_PMA_CLASS_PORT_INFO cpu_to_be16(0x0001)
/**
* ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
@@ -85,7 +85,7 @@ u64 ehca_define_sqp(struct ehca_shca *shca,
if (ret != H_SUCCESS) {
ehca_err(&shca->ib_device,
- "Can't define AQP1 for port %x. h_ret=%li",
+ "Can't define AQP1 for port %x. h_ret=%lli",
port, ret);
return ret;
}
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index 21f7d06f14a..f09914cccf5 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -116,7 +116,7 @@ extern int ehca_debug_level;
unsigned char *deb = (unsigned char *)(adr); \
for (x = 0; x < l; x += 16) { \
printk(KERN_INFO "EHCA_DMP:%s " format \
- " adr=%p ofs=%04x %016lx %016lx\n", \
+ " adr=%p ofs=%04x %016llx %016llx\n", \
__func__, ##args, deb, x, \
*((u64 *)&deb[0]), *((u64 *)&deb[8])); \
deb += 16; \
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index e43ed8f8a0c..3cb688d2913 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -114,7 +114,7 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas,
physical = galpas->user.fw_handle;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- ehca_gen_dbg("vsize=%lx physical=%lx", vsize, physical);
+ ehca_gen_dbg("vsize=%llx physical=%llx", vsize, physical);
/* VM_IO | VM_RESERVED are set by remap_pfn_range() */
ret = remap_4k_pfn(vma, vma->vm_start, physical >> EHCA_PAGESHIFT,
vma->vm_page_prot);
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index 415d3a465de..d0ab0c0d5e9 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -226,7 +226,7 @@ u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
u32 *eq_ist)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
u64 allocate_controls;
/* resource type */
@@ -249,7 +249,7 @@ u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
*eq_ist = (u32)outs[5];
if (ret == H_NOT_ENOUGH_RESOURCES)
- ehca_gen_err("Not enough resource - ret=%li ", ret);
+ ehca_gen_err("Not enough resource - ret=%lli ", ret);
return ret;
}
@@ -270,7 +270,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
struct ehca_alloc_cq_parms *param)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
adapter_handle.handle, /* r4 */
@@ -287,7 +287,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]);
if (ret == H_NOT_ENOUGH_RESOURCES)
- ehca_gen_err("Not enough resources. ret=%li", ret);
+ ehca_gen_err("Not enough resources. ret=%lli", ret);
return ret;
}
@@ -297,7 +297,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
{
u64 ret;
u64 allocate_controls, max_r10_reg, r11, r12;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
allocate_controls =
EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS, parms->ext_type)
@@ -362,7 +362,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
hcp_galpas_ctor(&parms->galpas, outs[6], outs[6]);
if (ret == H_NOT_ENOUGH_RESOURCES)
- ehca_gen_err("Not enough resources. ret=%li", ret);
+ ehca_gen_err("Not enough resources. ret=%lli", ret);
return ret;
}
@@ -454,7 +454,7 @@ u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,
const u64 count)
{
if (count != 1) {
- ehca_gen_err("Ppage counter=%lx", count);
+ ehca_gen_err("Ppage counter=%llx", count);
return H_PARAMETER;
}
return hipz_h_register_rpage(adapter_handle,
@@ -489,7 +489,7 @@ u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,
const struct h_galpa gal)
{
if (count != 1) {
- ehca_gen_err("Page counter=%lx", count);
+ ehca_gen_err("Page counter=%llx", count);
return H_PARAMETER;
}
@@ -508,7 +508,7 @@ u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
const struct h_galpa galpa)
{
if (count > 1) {
- ehca_gen_err("Page counter=%lx", count);
+ ehca_gen_err("Page counter=%llx", count);
return H_PARAMETER;
}
@@ -525,7 +525,7 @@ u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
int dis_and_get_function_code)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
adapter_handle.handle, /* r4 */
@@ -548,7 +548,7 @@ u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
struct h_galpa gal)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_MODIFY_QP, outs,
adapter_handle.handle, /* r4 */
qp_handle.handle, /* r5 */
@@ -557,7 +557,7 @@ u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
0, 0, 0, 0, 0);
if (ret == H_NOT_ENOUGH_RESOURCES)
- ehca_gen_err("Insufficient resources ret=%li", ret);
+ ehca_gen_err("Insufficient resources ret=%lli", ret);
return ret;
}
@@ -579,7 +579,7 @@ u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
struct ehca_qp *qp)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = hcp_galpas_dtor(&qp->galpas);
if (ret) {
@@ -593,7 +593,7 @@ u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
qp->ipz_qp_handle.handle, /* r6 */
0, 0, 0, 0, 0, 0);
if (ret == H_HARDWARE)
- ehca_gen_err("HCA not operational. ret=%li", ret);
+ ehca_gen_err("HCA not operational. ret=%lli", ret);
ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
adapter_handle.handle, /* r4 */
@@ -601,7 +601,7 @@ u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
0, 0, 0, 0, 0);
if (ret == H_RESOURCE)
- ehca_gen_err("Resource still in use. ret=%li", ret);
+ ehca_gen_err("Resource still in use. ret=%lli", ret);
return ret;
}
@@ -625,7 +625,7 @@ u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
u32 * bma_qp_nr)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs,
adapter_handle.handle, /* r4 */
@@ -636,7 +636,7 @@ u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
*bma_qp_nr = (u32)outs[1];
if (ret == H_ALIAS_EXIST)
- ehca_gen_err("AQP1 already exists. ret=%li", ret);
+ ehca_gen_err("AQP1 already exists. ret=%lli", ret);
return ret;
}
@@ -658,7 +658,7 @@ u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,
0, 0);
if (ret == H_NOT_ENOUGH_RESOURCES)
- ehca_gen_err("Not enough resources. ret=%li", ret);
+ ehca_gen_err("Not enough resources. ret=%lli", ret);
return ret;
}
@@ -697,7 +697,7 @@ u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,
0, 0, 0, 0);
if (ret == H_RESOURCE)
- ehca_gen_err("H_FREE_RESOURCE failed ret=%li ", ret);
+ ehca_gen_err("H_FREE_RESOURCE failed ret=%lli ", ret);
return ret;
}
@@ -719,7 +719,7 @@ u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,
0, 0, 0, 0, 0);
if (ret == H_RESOURCE)
- ehca_gen_err("Resource in use. ret=%li ", ret);
+ ehca_gen_err("Resource in use. ret=%lli ", ret);
return ret;
}
@@ -733,7 +733,7 @@ u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
struct ehca_mr_hipzout_parms *outparms)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
adapter_handle.handle, /* r4 */
@@ -774,9 +774,9 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
ehca_gen_err("logical_address_of_page not on a 4k boundary "
- "adapter_handle=%lx mr=%p mr_handle=%lx "
+ "adapter_handle=%llx mr=%p mr_handle=%llx "
"pagesize=%x queue_type=%x "
- "logical_address_of_page=%lx count=%lx",
+ "logical_address_of_page=%llx count=%llx",
adapter_handle.handle, mr,
mr->ipz_mr_handle.handle, pagesize, queue_type,
logical_address_of_page, count);
@@ -794,7 +794,7 @@ u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
struct ehca_mr_hipzout_parms *outparms)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_QUERY_MR, outs,
adapter_handle.handle, /* r4 */
@@ -828,7 +828,7 @@ u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
struct ehca_mr_hipzout_parms *outparms)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs,
adapter_handle.handle, /* r4 */
@@ -855,7 +855,7 @@ u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
struct ehca_mr_hipzout_parms *outparms)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs,
adapter_handle.handle, /* r4 */
@@ -877,7 +877,7 @@ u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
struct ehca_mw_hipzout_parms *outparms)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
adapter_handle.handle, /* r4 */
@@ -895,7 +895,7 @@ u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
struct ehca_mw_hipzout_parms *outparms)
{
u64 ret;
- u64 outs[PLPAR_HCALL9_BUFSIZE];
+ unsigned long outs[PLPAR_HCALL9_BUFSIZE];
ret = ehca_plpar_hcall9(H_QUERY_MW, outs,
adapter_handle.handle, /* r4 */
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 69c0ce321b4..cb9daa6ac02 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -2715,7 +2715,7 @@ static void ipath_hol_signal_up(struct ipath_devdata *dd)
* to prevent HoL blocking, then start the HoL timer that
* periodically continues, then stop procs, so they can detect
* link down if they want, and do something about it.
- * Timer may already be running, so use __mod_timer, not add_timer.
+ * Timer may already be running, so use mod_timer, not add_timer.
*/
void ipath_hol_down(struct ipath_devdata *dd)
{
@@ -2724,7 +2724,7 @@ void ipath_hol_down(struct ipath_devdata *dd)
dd->ipath_hol_next = IPATH_HOL_DOWNCONT;
dd->ipath_hol_timer.expires = jiffies +
msecs_to_jiffies(ipath_hol_timeout_ms);
- __mod_timer(&dd->ipath_hol_timer, dd->ipath_hol_timer.expires);
+ mod_timer(&dd->ipath_hol_timer, dd->ipath_hol_timer.expires);
}
/*
@@ -2763,7 +2763,7 @@ void ipath_hol_event(unsigned long opaque)
else {
dd->ipath_hol_timer.expires = jiffies +
msecs_to_jiffies(ipath_hol_timeout_ms);
- __mod_timer(&dd->ipath_hol_timer,
+ mod_timer(&dd->ipath_hol_timer,
dd->ipath_hol_timer.expires);
}
}
diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c
index dc37277f1c8..fc7181985e8 100644
--- a/drivers/infiniband/hw/ipath/ipath_eeprom.c
+++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c
@@ -772,8 +772,8 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd)
"0x%x, not 0x%x\n", csum, ifp->if_csum);
goto done;
}
- if (*(__be64 *) ifp->if_guid == 0ULL ||
- *(__be64 *) ifp->if_guid == __constant_cpu_to_be64(-1LL)) {
+ if (*(__be64 *) ifp->if_guid == cpu_to_be64(0) ||
+ *(__be64 *) ifp->if_guid == ~cpu_to_be64(0)) {
ipath_dev_err(dd, "Invalid GUID %llx from flash; "
"ignoring\n",
*(unsigned long long *) ifp->if_guid);
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 64aeefbd2a5..077879c0bdb 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -455,7 +455,7 @@ static void init_shadow_tids(struct ipath_devdata *dd)
if (!addrs) {
ipath_dev_err(dd, "failed to allocate shadow dma handle "
"array, no expected sends!\n");
- vfree(dd->ipath_pageshadow);
+ vfree(pages);
dd->ipath_pageshadow = NULL;
return;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c
index 17a12319747..16a702d4601 100644
--- a/drivers/infiniband/hw/ipath/ipath_mad.c
+++ b/drivers/infiniband/hw/ipath/ipath_mad.c
@@ -37,10 +37,10 @@
#include "ipath_verbs.h"
#include "ipath_common.h"
-#define IB_SMP_UNSUP_VERSION __constant_htons(0x0004)
-#define IB_SMP_UNSUP_METHOD __constant_htons(0x0008)
-#define IB_SMP_UNSUP_METH_ATTR __constant_htons(0x000C)
-#define IB_SMP_INVALID_FIELD __constant_htons(0x001C)
+#define IB_SMP_UNSUP_VERSION cpu_to_be16(0x0004)
+#define IB_SMP_UNSUP_METHOD cpu_to_be16(0x0008)
+#define IB_SMP_UNSUP_METH_ATTR cpu_to_be16(0x000C)
+#define IB_SMP_INVALID_FIELD cpu_to_be16(0x001C)
static int reply(struct ib_smp *smp)
{
@@ -789,12 +789,12 @@ static int recv_subn_set_pkeytable(struct ib_smp *smp,
return recv_subn_get_pkeytable(smp, ibdev);
}
-#define IB_PMA_CLASS_PORT_INFO __constant_htons(0x0001)
-#define IB_PMA_PORT_SAMPLES_CONTROL __constant_htons(0x0010)
-#define IB_PMA_PORT_SAMPLES_RESULT __constant_htons(0x0011)
-#define IB_PMA_PORT_COUNTERS __constant_htons(0x0012)
-#define IB_PMA_PORT_COUNTERS_EXT __constant_htons(0x001D)
-#define IB_PMA_PORT_SAMPLES_RESULT_EXT __constant_htons(0x001E)
+#define IB_PMA_CLASS_PORT_INFO cpu_to_be16(0x0001)
+#define IB_PMA_PORT_SAMPLES_CONTROL cpu_to_be16(0x0010)
+#define IB_PMA_PORT_SAMPLES_RESULT cpu_to_be16(0x0011)
+#define IB_PMA_PORT_COUNTERS cpu_to_be16(0x0012)
+#define IB_PMA_PORT_COUNTERS_EXT cpu_to_be16(0x001D)
+#define IB_PMA_PORT_SAMPLES_RESULT_EXT cpu_to_be16(0x001E)
struct ib_perf {
u8 base_version;
@@ -884,19 +884,19 @@ struct ib_pma_portcounters {
__be32 port_rcv_packets;
} __attribute__ ((packed));
-#define IB_PMA_SEL_SYMBOL_ERROR __constant_htons(0x0001)
-#define IB_PMA_SEL_LINK_ERROR_RECOVERY __constant_htons(0x0002)
-#define IB_PMA_SEL_LINK_DOWNED __constant_htons(0x0004)
-#define IB_PMA_SEL_PORT_RCV_ERRORS __constant_htons(0x0008)
-#define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS __constant_htons(0x0010)
-#define IB_PMA_SEL_PORT_XMIT_DISCARDS __constant_htons(0x0040)
-#define IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS __constant_htons(0x0200)
-#define IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS __constant_htons(0x0400)
-#define IB_PMA_SEL_PORT_VL15_DROPPED __constant_htons(0x0800)
-#define IB_PMA_SEL_PORT_XMIT_DATA __constant_htons(0x1000)
-#define IB_PMA_SEL_PORT_RCV_DATA __constant_htons(0x2000)
-#define IB_PMA_SEL_PORT_XMIT_PACKETS __constant_htons(0x4000)
-#define IB_PMA_SEL_PORT_RCV_PACKETS __constant_htons(0x8000)
+#define IB_PMA_SEL_SYMBOL_ERROR cpu_to_be16(0x0001)
+#define IB_PMA_SEL_LINK_ERROR_RECOVERY cpu_to_be16(0x0002)
+#define IB_PMA_SEL_LINK_DOWNED cpu_to_be16(0x0004)
+#define IB_PMA_SEL_PORT_RCV_ERRORS cpu_to_be16(0x0008)
+#define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS cpu_to_be16(0x0010)
+#define IB_PMA_SEL_PORT_XMIT_DISCARDS cpu_to_be16(0x0040)
+#define IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS cpu_to_be16(0x0200)
+#define IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS cpu_to_be16(0x0400)
+#define IB_PMA_SEL_PORT_VL15_DROPPED cpu_to_be16(0x0800)
+#define IB_PMA_SEL_PORT_XMIT_DATA cpu_to_be16(0x1000)
+#define IB_PMA_SEL_PORT_RCV_DATA cpu_to_be16(0x2000)
+#define IB_PMA_SEL_PORT_XMIT_PACKETS cpu_to_be16(0x4000)
+#define IB_PMA_SEL_PORT_RCV_PACKETS cpu_to_be16(0x8000)
struct ib_pma_portcounters_ext {
u8 reserved;
@@ -913,14 +913,14 @@ struct ib_pma_portcounters_ext {
__be64 port_multicast_rcv_packets;
} __attribute__ ((packed));
-#define IB_PMA_SELX_PORT_XMIT_DATA __constant_htons(0x0001)
-#define IB_PMA_SELX_PORT_RCV_DATA __constant_htons(0x0002)
-#define IB_PMA_SELX_PORT_XMIT_PACKETS __constant_htons(0x0004)
-#define IB_PMA_SELX_PORT_RCV_PACKETS __constant_htons(0x0008)
-#define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS __constant_htons(0x0010)
-#define IB_PMA_SELX_PORT_UNI_RCV_PACKETS __constant_htons(0x0020)
-#define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS __constant_htons(0x0040)
-#define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS __constant_htons(0x0080)
+#define IB_PMA_SELX_PORT_XMIT_DATA cpu_to_be16(0x0001)
+#define IB_PMA_SELX_PORT_RCV_DATA cpu_to_be16(0x0002)
+#define IB_PMA_SELX_PORT_XMIT_PACKETS cpu_to_be16(0x0004)
+#define IB_PMA_SELX_PORT_RCV_PACKETS cpu_to_be16(0x0008)
+#define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS cpu_to_be16(0x0010)
+#define IB_PMA_SELX_PORT_UNI_RCV_PACKETS cpu_to_be16(0x0020)
+#define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS cpu_to_be16(0x0040)
+#define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS cpu_to_be16(0x0080)
static int recv_pma_get_classportinfo(struct ib_perf *pmp)
{
@@ -933,7 +933,7 @@ static int recv_pma_get_classportinfo(struct ib_perf *pmp)
pmp->status |= IB_SMP_INVALID_FIELD;
/* Indicate AllPortSelect is valid (only one port anyway) */
- p->cap_mask = __constant_cpu_to_be16(1 << 8);
+ p->cap_mask = cpu_to_be16(1 << 8);
p->base_version = 1;
p->class_version = 1;
/*
@@ -951,12 +951,11 @@ static int recv_pma_get_classportinfo(struct ib_perf *pmp)
* We support 5 counters which only count the mandatory quantities.
*/
#define COUNTER_MASK(q, n) (q << ((9 - n) * 3))
-#define COUNTER_MASK0_9 \
- __constant_cpu_to_be32(COUNTER_MASK(1, 0) | \
- COUNTER_MASK(1, 1) | \
- COUNTER_MASK(1, 2) | \
- COUNTER_MASK(1, 3) | \
- COUNTER_MASK(1, 4))
+#define COUNTER_MASK0_9 cpu_to_be32(COUNTER_MASK(1, 0) | \
+ COUNTER_MASK(1, 1) | \
+ COUNTER_MASK(1, 2) | \
+ COUNTER_MASK(1, 3) | \
+ COUNTER_MASK(1, 4))
static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp,
struct ib_device *ibdev, u8 port)
@@ -1137,7 +1136,7 @@ static int recv_pma_get_portsamplesresult_ext(struct ib_perf *pmp,
status = dev->pma_sample_status;
p->sample_status = cpu_to_be16(status);
/* 64 bits */
- p->extended_width = __constant_cpu_to_be32(0x80000000);
+ p->extended_width = cpu_to_be32(0x80000000);
for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++)
p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 :
cpu_to_be64(
@@ -1185,7 +1184,7 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
pmp->status |= IB_SMP_INVALID_FIELD;
if (cntrs.symbol_error_counter > 0xFFFFUL)
- p->symbol_error_counter = __constant_cpu_to_be16(0xFFFF);
+ p->symbol_error_counter = cpu_to_be16(0xFFFF);
else
p->symbol_error_counter =
cpu_to_be16((u16)cntrs.symbol_error_counter);
@@ -1199,17 +1198,17 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
else
p->link_downed_counter = (u8)cntrs.link_downed_counter;
if (cntrs.port_rcv_errors > 0xFFFFUL)
- p->port_rcv_errors = __constant_cpu_to_be16(0xFFFF);
+ p->port_rcv_errors = cpu_to_be16(0xFFFF);
else
p->port_rcv_errors =
cpu_to_be16((u16) cntrs.port_rcv_errors);
if (cntrs.port_rcv_remphys_errors > 0xFFFFUL)
- p->port_rcv_remphys_errors = __constant_cpu_to_be16(0xFFFF);
+ p->port_rcv_remphys_errors = cpu_to_be16(0xFFFF);
else
p->port_rcv_remphys_errors =
cpu_to_be16((u16)cntrs.port_rcv_remphys_errors);
if (cntrs.port_xmit_discards > 0xFFFFUL)
- p->port_xmit_discards = __constant_cpu_to_be16(0xFFFF);
+ p->port_xmit_discards = cpu_to_be16(0xFFFF);
else
p->port_xmit_discards =
cpu_to_be16((u16)cntrs.port_xmit_discards);
@@ -1220,24 +1219,24 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) |
cntrs.excessive_buffer_overrun_errors;
if (cntrs.vl15_dropped > 0xFFFFUL)
- p->vl15_dropped = __constant_cpu_to_be16(0xFFFF);
+ p->vl15_dropped = cpu_to_be16(0xFFFF);
else
p->vl15_dropped = cpu_to_be16((u16)cntrs.vl15_dropped);
if (cntrs.port_xmit_data > 0xFFFFFFFFUL)
- p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF);
+ p->port_xmit_data = cpu_to_be32(0xFFFFFFFF);
else
p->port_xmit_data = cpu_to_be32((u32)cntrs.port_xmit_data);
if (cntrs.port_rcv_data > 0xFFFFFFFFUL)
- p->port_rcv_data = __constant_cpu_to_be32(0xFFFFFFFF);
+ p->port_rcv_data = cpu_to_be32(0xFFFFFFFF);
else
p->port_rcv_data = cpu_to_be32((u32)cntrs.port_rcv_data);
if (cntrs.port_xmit_packets > 0xFFFFFFFFUL)
- p->port_xmit_packets = __constant_cpu_to_be32(0xFFFFFFFF);
+ p->port_xmit_packets = cpu_to_be32(0xFFFFFFFF);
else
p->port_xmit_packets =
cpu_to_be32((u32)cntrs.port_xmit_packets);
if (cntrs.port_rcv_packets > 0xFFFFFFFFUL)
- p->port_rcv_packets = __constant_cpu_to_be32(0xFFFFFFFF);
+ p->port_rcv_packets = cpu_to_be32(0xFFFFFFFF);
else
p->port_rcv_packets =
cpu_to_be32((u32) cntrs.port_rcv_packets);
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index 9170710b950..79b3dbc9717 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -1744,7 +1744,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
/* Signal completion event if the solicited bit is set. */
ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
(ohdr->bth[0] &
- __constant_cpu_to_be32(1 << 23)) != 0);
+ cpu_to_be32(1 << 23)) != 0);
break;
case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c
index 8e255adf5d9..4b069859085 100644
--- a/drivers/infiniband/hw/ipath/ipath_sdma.c
+++ b/drivers/infiniband/hw/ipath/ipath_sdma.c
@@ -781,10 +781,10 @@ retry:
descqp = &dd->ipath_sdma_descq[dd->ipath_sdma_descq_cnt].qw[0];
descqp -= 2;
/* SDmaLastDesc */
- descqp[0] |= __constant_cpu_to_le64(1ULL << 11);
+ descqp[0] |= cpu_to_le64(1ULL << 11);
if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_INTREQ) {
/* SDmaIntReq */
- descqp[0] |= __constant_cpu_to_le64(1ULL << 15);
+ descqp[0] |= cpu_to_le64(1ULL << 15);
}
/* Commit writes to memory and advance the tail on the chip */
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c
index 82cc588b8bf..22e60998f1a 100644
--- a/drivers/infiniband/hw/ipath/ipath_uc.c
+++ b/drivers/infiniband/hw/ipath/ipath_uc.c
@@ -419,7 +419,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
/* Signal completion event if the solicited bit is set. */
ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
(ohdr->bth[0] &
- __constant_cpu_to_be32(1 << 23)) != 0);
+ cpu_to_be32(1 << 23)) != 0);
break;
case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 91c74cc797a..6076cb61bf6 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -370,7 +370,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
*/
ohdr->bth[1] = ah_attr->dlid >= IPATH_MULTICAST_LID_BASE &&
ah_attr->dlid != IPATH_PERMISSIVE_LID ?
- __constant_cpu_to_be32(IPATH_MULTICAST_QPN) :
+ cpu_to_be32(IPATH_MULTICAST_QPN) :
cpu_to_be32(wqe->wr.wr.ud.remote_qpn);
ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & IPATH_PSN_MASK);
/*
@@ -573,7 +573,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
/* Signal completion event if the solicited bit is set. */
ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
(ohdr->bth[0] &
- __constant_cpu_to_be32(1 << 23)) != 0);
+ cpu_to_be32(1 << 23)) != 0);
bail:;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index 0190edc8044..855911e7396 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -209,20 +209,20 @@ void ipath_release_user_pages_on_close(struct page **p, size_t num_pages)
mm = get_task_mm(current);
if (!mm)
- goto bail;
+ return;
work = kmalloc(sizeof(*work), GFP_KERNEL);
if (!work)
goto bail_mm;
- goto bail;
-
INIT_WORK(&work->work, user_pages_account);
work->mm = mm;
work->num_pages = num_pages;
+ schedule_work(&work->work);
+ return;
+
bail_mm:
mmput(mm);
-bail:
return;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/drivers/infiniband/hw/ipath/ipath_user_sdma.c
index 82d9a0b5ca2..7bff4b9baa0 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_sdma.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.c
@@ -667,13 +667,13 @@ static inline __le64 ipath_sdma_make_desc0(struct ipath_devdata *dd,
static inline __le64 ipath_sdma_make_first_desc0(__le64 descq)
{
- return descq | __constant_cpu_to_le64(1ULL << 12);
+ return descq | cpu_to_le64(1ULL << 12);
}
static inline __le64 ipath_sdma_make_last_desc0(__le64 descq)
{
/* last */ /* dma head */
- return descq | __constant_cpu_to_le64(1ULL << 11 | 1ULL << 13);
+ return descq | cpu_to_le64(1ULL << 11 | 1ULL << 13);
}
static inline __le64 ipath_sdma_make_desc1(u64 addr)
@@ -763,7 +763,7 @@ static int ipath_user_sdma_push_pkts(struct ipath_devdata *dd,
if (ofs >= IPATH_SMALLBUF_DWORDS) {
for (i = 0; i < pkt->naddr; i++) {
dd->ipath_sdma_descq[dtail].qw[0] |=
- __constant_cpu_to_le64(1ULL << 14);
+ cpu_to_le64(1ULL << 14);
if (++dtail == dd->ipath_sdma_descq_cnt)
dtail = 0;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index cdf0e6abd34..9289ab4b0ae 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1585,7 +1585,7 @@ static int ipath_query_port(struct ib_device *ibdev,
u64 ibcstat;
memset(props, 0, sizeof(*props));
- props->lid = lid ? lid : __constant_be16_to_cpu(IB_LID_PERMISSIVE);
+ props->lid = lid ? lid : be16_to_cpu(IB_LID_PERMISSIVE);
props->lmc = dd->ipath_lmc;
props->sm_lid = dev->sm_lid;
props->sm_sl = dev->sm_sl;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 11e3f613df9..ae6cff4abff 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -86,11 +86,11 @@
#define IB_PMA_SAMPLE_STATUS_RUNNING 0x02
/* Mandatory IB performance counter select values. */
-#define IB_PMA_PORT_XMIT_DATA __constant_htons(0x0001)
-#define IB_PMA_PORT_RCV_DATA __constant_htons(0x0002)
-#define IB_PMA_PORT_XMIT_PKTS __constant_htons(0x0003)
-#define IB_PMA_PORT_RCV_PKTS __constant_htons(0x0004)
-#define IB_PMA_PORT_XMIT_WAIT __constant_htons(0x0005)
+#define IB_PMA_PORT_XMIT_DATA cpu_to_be16(0x0001)
+#define IB_PMA_PORT_RCV_DATA cpu_to_be16(0x0002)
+#define IB_PMA_PORT_XMIT_PKTS cpu_to_be16(0x0003)
+#define IB_PMA_PORT_RCV_PKTS cpu_to_be16(0x0004)
+#define IB_PMA_PORT_XMIT_WAIT cpu_to_be16(0x0005)
struct ib_reth {
__be64 vaddr;
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 606f1e2ef28..19e68ab6616 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -147,7 +147,8 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl)
* Snoop SM MADs for port info and P_Key table sets, so we can
* synthesize LID change and P_Key change events.
*/
-static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
+static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad,
+ u16 prev_lid)
{
struct ib_event event;
@@ -157,6 +158,7 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
struct ib_port_info *pinfo =
(struct ib_port_info *) ((struct ib_smp *) mad)->data;
+ u16 lid = be16_to_cpu(pinfo->lid);
update_sm_ah(to_mdev(ibdev), port_num,
be16_to_cpu(pinfo->sm_lid),
@@ -165,12 +167,15 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
event.device = ibdev;
event.element.port_num = port_num;
- if (pinfo->clientrereg_resv_subnetto & 0x80)
+ if (pinfo->clientrereg_resv_subnetto & 0x80) {
event.event = IB_EVENT_CLIENT_REREGISTER;
- else
- event.event = IB_EVENT_LID_CHANGE;
+ ib_dispatch_event(&event);
+ }
- ib_dispatch_event(&event);
+ if (prev_lid != lid) {
+ event.event = IB_EVENT_LID_CHANGE;
+ ib_dispatch_event(&event);
+ }
}
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -228,8 +233,9 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
struct ib_wc *in_wc, struct ib_grh *in_grh,
struct ib_mad *in_mad, struct ib_mad *out_mad)
{
- u16 slid;
+ u16 slid, prev_lid = 0;
int err;
+ struct ib_port_attr pattr;
slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
@@ -263,6 +269,13 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
} else
return IB_MAD_RESULT_SUCCESS;
+ if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+ in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+ in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
+ in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
+ !ib_query_port(ibdev, port_num, &pattr))
+ prev_lid = pattr.lid;
+
err = mlx4_MAD_IFC(to_mdev(ibdev),
mad_flags & IB_MAD_IGNORE_MKEY,
mad_flags & IB_MAD_IGNORE_BKEY,
@@ -271,7 +284,7 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
return IB_MAD_RESULT_FAILURE;
if (!out_mad->mad_hdr.status) {
- smp_snoop(ibdev, port_num, in_mad);
+ smp_snoop(ibdev, port_num, in_mad, prev_lid);
node_desc_override(ibdev, out_mad);
}
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 61588bd273b..2ccb9d31771 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -699,11 +699,12 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
struct mlx4_ib_dev *ibdev = ibdev_ptr;
int p;
+ mlx4_ib_mad_cleanup(ibdev);
+ ib_unregister_device(&ibdev->ib_dev);
+
for (p = 1; p <= ibdev->num_ports; ++p)
mlx4_CLOSE_PORT(dev, p);
- mlx4_ib_mad_cleanup(ibdev);
- ib_unregister_device(&ibdev->ib_dev);
iounmap(ibdev->uar_map);
mlx4_uar_free(dev, &ibdev->priv_uar);
mlx4_pd_free(dev, ibdev->priv_pdn);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 39167a797f9..f385a24d31d 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -71,17 +71,17 @@ enum {
};
static const __be32 mlx4_ib_opcode[] = {
- [IB_WR_SEND] = __constant_cpu_to_be32(MLX4_OPCODE_SEND),
- [IB_WR_LSO] = __constant_cpu_to_be32(MLX4_OPCODE_LSO),
- [IB_WR_SEND_WITH_IMM] = __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM),
- [IB_WR_RDMA_WRITE] = __constant_cpu_to_be32(MLX4_OPCODE_RDMA_WRITE),
- [IB_WR_RDMA_WRITE_WITH_IMM] = __constant_cpu_to_be32(MLX4_OPCODE_RDMA_WRITE_IMM),
- [IB_WR_RDMA_READ] = __constant_cpu_to_be32(MLX4_OPCODE_RDMA_READ),
- [IB_WR_ATOMIC_CMP_AND_SWP] = __constant_cpu_to_be32(MLX4_OPCODE_ATOMIC_CS),
- [IB_WR_ATOMIC_FETCH_AND_ADD] = __constant_cpu_to_be32(MLX4_OPCODE_ATOMIC_FA),
- [IB_WR_SEND_WITH_INV] = __constant_cpu_to_be32(MLX4_OPCODE_SEND_INVAL),
- [IB_WR_LOCAL_INV] = __constant_cpu_to_be32(MLX4_OPCODE_LOCAL_INVAL),
- [IB_WR_FAST_REG_MR] = __constant_cpu_to_be32(MLX4_OPCODE_FMR),
+ [IB_WR_SEND] = cpu_to_be32(MLX4_OPCODE_SEND),
+ [IB_WR_LSO] = cpu_to_be32(MLX4_OPCODE_LSO),
+ [IB_WR_SEND_WITH_IMM] = cpu_to_be32(MLX4_OPCODE_SEND_IMM),
+ [IB_WR_RDMA_WRITE] = cpu_to_be32(MLX4_OPCODE_RDMA_WRITE),
+ [IB_WR_RDMA_WRITE_WITH_IMM] = cpu_to_be32(MLX4_OPCODE_RDMA_WRITE_IMM),
+ [IB_WR_RDMA_READ] = cpu_to_be32(MLX4_OPCODE_RDMA_READ),
+ [IB_WR_ATOMIC_CMP_AND_SWP] = cpu_to_be32(MLX4_OPCODE_ATOMIC_CS),
+ [IB_WR_ATOMIC_FETCH_AND_ADD] = cpu_to_be32(MLX4_OPCODE_ATOMIC_FA),
+ [IB_WR_SEND_WITH_INV] = cpu_to_be32(MLX4_OPCODE_SEND_INVAL),
+ [IB_WR_LOCAL_INV] = cpu_to_be32(MLX4_OPCODE_LOCAL_INVAL),
+ [IB_WR_FAST_REG_MR] = cpu_to_be32(MLX4_OPCODE_FMR),
};
static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp *mqp)
@@ -1462,7 +1462,8 @@ static void __set_data_seg(struct mlx4_wqe_data_seg *dseg, struct ib_sge *sg)
}
static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr,
- struct mlx4_ib_qp *qp, unsigned *lso_seg_len)
+ struct mlx4_ib_qp *qp, unsigned *lso_seg_len,
+ __be32 *lso_hdr_sz)
{
unsigned halign = ALIGN(sizeof *wqe + wr->wr.ud.hlen, 16);
@@ -1479,12 +1480,8 @@ static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr,
memcpy(wqe->header, wr->wr.ud.header, wr->wr.ud.hlen);
- /* make sure LSO header is written before overwriting stamping */
- wmb();
-
- wqe->mss_hdr_size = cpu_to_be32((wr->wr.ud.mss - wr->wr.ud.hlen) << 16 |
- wr->wr.ud.hlen);
-
+ *lso_hdr_sz = cpu_to_be32((wr->wr.ud.mss - wr->wr.ud.hlen) << 16 |
+ wr->wr.ud.hlen);
*lso_seg_len = halign;
return 0;
}
@@ -1518,6 +1515,9 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
int uninitialized_var(stamp);
int uninitialized_var(size);
unsigned uninitialized_var(seglen);
+ __be32 dummy;
+ __be32 *lso_wqe;
+ __be32 uninitialized_var(lso_hdr_sz);
int i;
spin_lock_irqsave(&qp->sq.lock, flags);
@@ -1525,6 +1525,8 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
ind = qp->sq_next_wqe;
for (nreq = 0; wr; ++nreq, wr = wr->next) {
+ lso_wqe = &dummy;
+
if (mlx4_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) {
err = -ENOMEM;
*bad_wr = wr;
@@ -1606,11 +1608,12 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
size += sizeof (struct mlx4_wqe_datagram_seg) / 16;
if (wr->opcode == IB_WR_LSO) {
- err = build_lso_seg(wqe, wr, qp, &seglen);
+ err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz);
if (unlikely(err)) {
*bad_wr = wr;
goto out;
}
+ lso_wqe = (__be32 *) wqe;
wqe += seglen;
size += seglen / 16;
}
@@ -1652,6 +1655,14 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
for (i = wr->num_sge - 1; i >= 0; --i, --dseg)
set_data_seg(dseg, wr->sg_list + i);
+ /*
+ * Possibly overwrite stamping in cacheline with LSO
+ * segment only after making sure all data segments
+ * are written.
+ */
+ wmb();
+ *lso_wqe = lso_hdr_sz;
+
ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ?
MLX4_WQE_CTRL_FENCE : 0) | size;
@@ -1686,7 +1697,6 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
stamp_send_wqe(qp, stamp, size * 16);
ind = pad_wraparound(qp, ind);
}
-
}
out:
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 640449582ab..5648659ff0b 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -104,7 +104,8 @@ static void update_sm_ah(struct mthca_dev *dev,
*/
static void smp_snoop(struct ib_device *ibdev,
u8 port_num,
- struct ib_mad *mad)
+ struct ib_mad *mad,
+ u16 prev_lid)
{
struct ib_event event;
@@ -114,6 +115,7 @@ static void smp_snoop(struct ib_device *ibdev,
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
struct ib_port_info *pinfo =
(struct ib_port_info *) ((struct ib_smp *) mad)->data;
+ u16 lid = be16_to_cpu(pinfo->lid);
mthca_update_rate(to_mdev(ibdev), port_num);
update_sm_ah(to_mdev(ibdev), port_num,
@@ -123,12 +125,15 @@ static void smp_snoop(struct ib_device *ibdev,
event.device = ibdev;
event.element.port_num = port_num;
- if (pinfo->clientrereg_resv_subnetto & 0x80)
+ if (pinfo->clientrereg_resv_subnetto & 0x80) {
event.event = IB_EVENT_CLIENT_REREGISTER;
- else
- event.event = IB_EVENT_LID_CHANGE;
+ ib_dispatch_event(&event);
+ }
- ib_dispatch_event(&event);
+ if (prev_lid != lid) {
+ event.event = IB_EVENT_LID_CHANGE;
+ ib_dispatch_event(&event);
+ }
}
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -196,6 +201,8 @@ int mthca_process_mad(struct ib_device *ibdev,
int err;
u8 status;
u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
+ u16 prev_lid = 0;
+ struct ib_port_attr pattr;
/* Forward locally generated traps to the SM */
if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
@@ -233,6 +240,12 @@ int mthca_process_mad(struct ib_device *ibdev,
return IB_MAD_RESULT_SUCCESS;
} else
return IB_MAD_RESULT_SUCCESS;
+ if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+ in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+ in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
+ in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
+ !ib_query_port(ibdev, port_num, &pattr))
+ prev_lid = pattr.lid;
err = mthca_MAD_IFC(to_mdev(ibdev),
mad_flags & IB_MAD_IGNORE_MKEY,
@@ -252,7 +265,7 @@ int mthca_process_mad(struct ib_device *ibdev,
}
if (!out_mad->mad_hdr.status) {
- smp_snoop(ibdev, port_num, in_mad);
+ smp_snoop(ibdev, port_num, in_mad, prev_lid);
node_desc_override(ibdev, out_mad);
}
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index b9611ade9ea..ca599767ffb 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index 13a5bb1a7bc..04b12ad2339 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index a01b4488208..52425154acd 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, 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
@@ -103,6 +103,7 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt);
static void nes_disconnect_worker(struct work_struct *work);
static int send_mpa_request(struct nes_cm_node *, struct sk_buff *);
+static int send_mpa_reject(struct nes_cm_node *);
static int send_syn(struct nes_cm_node *, u32, struct sk_buff *);
static int send_reset(struct nes_cm_node *, struct sk_buff *);
static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb);
@@ -113,8 +114,7 @@ static void process_packet(struct nes_cm_node *, struct sk_buff *,
static void active_open_err(struct nes_cm_node *, struct sk_buff *, int);
static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int);
static void cleanup_retrans_entry(struct nes_cm_node *);
-static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *,
- enum nes_cm_event_type);
+static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *);
static void free_retrans_entry(struct nes_cm_node *cm_node);
static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
struct sk_buff *skb, int optionsize, int passive);
@@ -124,6 +124,8 @@ static void cm_event_connected(struct nes_cm_event *);
static void cm_event_connect_error(struct nes_cm_event *);
static void cm_event_reset(struct nes_cm_event *);
static void cm_event_mpa_req(struct nes_cm_event *);
+static void cm_event_mpa_reject(struct nes_cm_event *);
+static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node);
static void print_core(struct nes_cm_core *core);
@@ -196,7 +198,6 @@ static struct nes_cm_event *create_event(struct nes_cm_node *cm_node,
*/
static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
{
- int ret;
if (!skb) {
nes_debug(NES_DBG_CM, "skb set to NULL\n");
return -1;
@@ -206,11 +207,27 @@ static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
cm_node->mpa_frame_size, SET_ACK);
- ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
- if (ret < 0)
- return ret;
+ return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
+}
- return 0;
+
+
+static int send_mpa_reject(struct nes_cm_node *cm_node)
+{
+ struct sk_buff *skb = NULL;
+
+ skb = dev_alloc_skb(MAX_CM_BUFFER);
+ if (!skb) {
+ nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
+ return -ENOMEM;
+ }
+
+ /* send an MPA reject frame */
+ form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
+ cm_node->mpa_frame_size, SET_ACK | SET_FIN);
+
+ cm_node->state = NES_CM_STATE_FIN_WAIT1;
+ return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
}
@@ -218,14 +235,17 @@ static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
* recv_mpa - process a received TCP pkt, we are expecting an
* IETF MPA frame
*/
-static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len)
+static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
+ u32 len)
{
struct ietf_mpa_frame *mpa_frame;
+ *type = NES_MPA_REQUEST_ACCEPT;
+
/* assume req frame is in tcp data payload */
if (len < sizeof(struct ietf_mpa_frame)) {
nes_debug(NES_DBG_CM, "The received ietf buffer was too small (%x)\n", len);
- return -1;
+ return -EINVAL;
}
mpa_frame = (struct ietf_mpa_frame *)buffer;
@@ -234,14 +254,25 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len)
if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) {
nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
" complete (%x + %x != %x)\n",
- cm_node->mpa_frame_size, (u32)sizeof(struct ietf_mpa_frame), len);
- return -1;
+ cm_node->mpa_frame_size,
+ (u32)sizeof(struct ietf_mpa_frame), len);
+ return -EINVAL;
+ }
+ /* make sure it does not exceed the max size */
+ if (len > MAX_CM_BUFFER) {
+ nes_debug(NES_DBG_CM, "The received ietf buffer was too large"
+ " (%x + %x != %x)\n",
+ cm_node->mpa_frame_size,
+ (u32)sizeof(struct ietf_mpa_frame), len);
+ return -EINVAL;
}
/* copy entire MPA frame to our cm_node's frame */
memcpy(cm_node->mpa_frame_buf, buffer + sizeof(struct ietf_mpa_frame),
cm_node->mpa_frame_size);
+ if (mpa_frame->flags & IETF_MPA_FLAGS_REJECT)
+ *type = NES_MPA_REQUEST_REJECT;
return 0;
}
@@ -380,7 +411,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
if (!new_send)
- return -1;
+ return -ENOMEM;
/* new_send->timetosend = currenttime */
new_send->retrycount = NES_DEFAULT_RETRYS;
@@ -394,9 +425,11 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
if (type == NES_TIMER_TYPE_CLOSE) {
new_send->timetosend += (HZ/10);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
- list_add_tail(&new_send->list, &cm_node->recv_list);
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
+ if (cm_node->recv_entry) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ cm_node->recv_entry = new_send;
}
if (type == NES_TIMER_TYPE_SEND) {
@@ -435,24 +468,78 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
return ret;
}
+static void nes_retrans_expired(struct nes_cm_node *cm_node)
+{
+ switch (cm_node->state) {
+ case NES_CM_STATE_SYN_RCVD:
+ case NES_CM_STATE_CLOSING:
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ break;
+ case NES_CM_STATE_LAST_ACK:
+ case NES_CM_STATE_FIN_WAIT1:
+ case NES_CM_STATE_MPAREJ_RCVD:
+ send_reset(cm_node, NULL);
+ break;
+ default:
+ create_event(cm_node, NES_CM_EVENT_ABORTED);
+ }
+}
+
+static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node)
+{
+ struct nes_timer_entry *recv_entry = cm_node->recv_entry;
+ struct iw_cm_id *cm_id = cm_node->cm_id;
+ struct nes_qp *nesqp;
+ unsigned long qplockflags;
+
+ if (!recv_entry)
+ return;
+ nesqp = (struct nes_qp *)recv_entry->skb;
+ if (nesqp) {
+ spin_lock_irqsave(&nesqp->lock, qplockflags);
+ if (nesqp->cm_id) {
+ nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
+ "refcount = %d: HIT A "
+ "NES_TIMER_TYPE_CLOSE with something "
+ "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
+ atomic_read(&nesqp->refcount));
+ nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
+ nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
+ nesqp->ibqp_state = IB_QPS_ERR;
+ spin_unlock_irqrestore(&nesqp->lock, qplockflags);
+ nes_cm_disconn(nesqp);
+ } else {
+ spin_unlock_irqrestore(&nesqp->lock, qplockflags);
+ nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
+ "refcount = %d: HIT A "
+ "NES_TIMER_TYPE_CLOSE with nothing "
+ "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
+ atomic_read(&nesqp->refcount));
+ }
+ } else if (rem_node) {
+ /* TIME_WAIT state */
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ }
+ if (cm_node->cm_id)
+ cm_id->rem_ref(cm_id);
+ kfree(recv_entry);
+ cm_node->recv_entry = NULL;
+}
/**
* nes_cm_timer_tick
*/
static void nes_cm_timer_tick(unsigned long pass)
{
- unsigned long flags, qplockflags;
+ unsigned long flags;
unsigned long nexttimeout = jiffies + NES_LONG_TIME;
- struct iw_cm_id *cm_id;
struct nes_cm_node *cm_node;
struct nes_timer_entry *send_entry, *recv_entry;
- struct list_head *list_core, *list_core_temp;
- struct list_head *list_node, *list_node_temp;
+ struct list_head *list_core_temp;
+ struct list_head *list_node;
struct nes_cm_core *cm_core = g_cm_core;
- struct nes_qp *nesqp;
u32 settimer = 0;
int ret = NETDEV_TX_OK;
- enum nes_cm_node_state last_state;
struct list_head timer_list;
INIT_LIST_HEAD(&timer_list);
@@ -461,7 +548,7 @@ static void nes_cm_timer_tick(unsigned long pass)
list_for_each_safe(list_node, list_core_temp,
&cm_core->connected_nodes) {
cm_node = container_of(list_node, struct nes_cm_node, list);
- if (!list_empty(&cm_node->recv_list) || (cm_node->send_entry)) {
+ if ((cm_node->recv_entry) || (cm_node->send_entry)) {
add_ref_cm_node(cm_node);
list_add(&cm_node->timer_entry, &timer_list);
}
@@ -471,54 +558,18 @@ static void nes_cm_timer_tick(unsigned long pass)
list_for_each_safe(list_node, list_core_temp, &timer_list) {
cm_node = container_of(list_node, struct nes_cm_node,
timer_entry);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
- list_for_each_safe(list_core, list_node_temp,
- &cm_node->recv_list) {
- recv_entry = container_of(list_core,
- struct nes_timer_entry, list);
- if (!recv_entry)
- break;
+ recv_entry = cm_node->recv_entry;
+
+ if (recv_entry) {
if (time_after(recv_entry->timetosend, jiffies)) {
if (nexttimeout > recv_entry->timetosend ||
- !settimer) {
+ !settimer) {
nexttimeout = recv_entry->timetosend;
settimer = 1;
}
- continue;
- }
- list_del(&recv_entry->list);
- cm_id = cm_node->cm_id;
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
- nesqp = (struct nes_qp *)recv_entry->skb;
- spin_lock_irqsave(&nesqp->lock, qplockflags);
- if (nesqp->cm_id) {
- nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
- "refcount = %d: HIT A "
- "NES_TIMER_TYPE_CLOSE with something "
- "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
- atomic_read(&nesqp->refcount));
- nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
- nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
- nesqp->ibqp_state = IB_QPS_ERR;
- spin_unlock_irqrestore(&nesqp->lock,
- qplockflags);
- nes_cm_disconn(nesqp);
- } else {
- spin_unlock_irqrestore(&nesqp->lock,
- qplockflags);
- nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
- "refcount = %d: HIT A "
- "NES_TIMER_TYPE_CLOSE with nothing "
- "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
- atomic_read(&nesqp->refcount));
- }
- if (cm_id)
- cm_id->rem_ref(cm_id);
-
- kfree(recv_entry);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
+ } else
+ handle_recv_entry(cm_node, 1);
}
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
do {
@@ -533,12 +584,11 @@ static void nes_cm_timer_tick(unsigned long pass)
nexttimeout =
send_entry->timetosend;
settimer = 1;
- break;
}
} else {
free_retrans_entry(cm_node);
- break;
}
+ break;
}
if ((cm_node->state == NES_CM_STATE_TSA) ||
@@ -550,16 +600,12 @@ static void nes_cm_timer_tick(unsigned long pass)
if (!send_entry->retranscount ||
!send_entry->retrycount) {
cm_packets_dropped++;
- last_state = cm_node->state;
- cm_node->state = NES_CM_STATE_CLOSED;
free_retrans_entry(cm_node);
+
spin_unlock_irqrestore(
&cm_node->retrans_list_lock, flags);
- if (last_state == NES_CM_STATE_SYN_RCVD)
- rem_ref_cm_node(cm_core, cm_node);
- else
- create_event(cm_node,
- NES_CM_EVENT_ABORTED);
+ nes_retrans_expired(cm_node);
+ cm_node->state = NES_CM_STATE_CLOSED;
spin_lock_irqsave(&cm_node->retrans_list_lock,
flags);
break;
@@ -714,7 +760,7 @@ static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb)
skb = dev_alloc_skb(MAX_CM_BUFFER);
if (!skb) {
nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
- return -1;
+ return -ENOMEM;
}
form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags);
@@ -778,14 +824,10 @@ static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
unsigned long flags;
struct list_head *hte;
struct nes_cm_node *cm_node;
- __be32 tmp_addr = cpu_to_be32(loc_addr);
/* get a handle on the hte */
hte = &cm_core->connected_nodes;
- nes_debug(NES_DBG_CM, "Searching for an owner node: %pI4:%x from core %p->%p\n",
- &tmp_addr, loc_port, cm_core, hte);
-
/* walk list and find cm_node associated with this session ID */
spin_lock_irqsave(&cm_core->ht_lock, flags);
list_for_each_entry(cm_node, hte, list) {
@@ -875,7 +917,8 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node
static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
struct nes_cm_listener *listener, int free_hanging_nodes)
{
- int ret = 1;
+ int ret = -EINVAL;
+ int err = 0;
unsigned long flags;
struct list_head *list_pos = NULL;
struct list_head *list_temp = NULL;
@@ -904,10 +947,60 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
list_for_each_safe(list_pos, list_temp, &reset_list) {
cm_node = container_of(list_pos, struct nes_cm_node,
- reset_entry);
- cleanup_retrans_entry(cm_node);
- send_reset(cm_node, NULL);
- rem_ref_cm_node(cm_node->cm_core, cm_node);
+ reset_entry);
+ {
+ struct nes_cm_node *loopback = cm_node->loopbackpartner;
+ if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) {
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ } else {
+ if (!loopback) {
+ cleanup_retrans_entry(cm_node);
+ err = send_reset(cm_node, NULL);
+ if (err) {
+ cm_node->state =
+ NES_CM_STATE_CLOSED;
+ WARN_ON(1);
+ } else {
+ cm_node->state =
+ NES_CM_STATE_CLOSED;
+ rem_ref_cm_node(
+ cm_node->cm_core,
+ cm_node);
+ }
+ } else {
+ struct nes_cm_event event;
+
+ event.cm_node = loopback;
+ event.cm_info.rem_addr =
+ loopback->rem_addr;
+ event.cm_info.loc_addr =
+ loopback->loc_addr;
+ event.cm_info.rem_port =
+ loopback->rem_port;
+ event.cm_info.loc_port =
+ loopback->loc_port;
+ event.cm_info.cm_id = loopback->cm_id;
+ cm_event_connect_error(&event);
+ loopback->state = NES_CM_STATE_CLOSED;
+
+ event.cm_node = cm_node;
+ event.cm_info.rem_addr =
+ cm_node->rem_addr;
+ event.cm_info.loc_addr =
+ cm_node->loc_addr;
+ event.cm_info.rem_port =
+ cm_node->rem_port;
+ event.cm_info.loc_port =
+ cm_node->loc_port;
+ event.cm_info.cm_id = cm_node->cm_id;
+ cm_event_reset(&event);
+
+ rem_ref_cm_node(cm_node->cm_core,
+ cm_node);
+
+ }
+ }
+ }
}
spin_lock_irqsave(&cm_core->listen_list_lock, flags);
@@ -968,6 +1061,7 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
if (cm_node->accept_pend) {
BUG_ON(!cm_node->listener);
atomic_dec(&cm_node->listener->pend_accepts_cnt);
+ cm_node->accept_pend = 0;
BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
}
@@ -994,7 +1088,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
memset(&fl, 0, sizeof fl);
fl.nl_u.ip4_u.daddr = htonl(dst_ip);
if (ip_route_output_key(&init_net, &rt, &fl)) {
- printk("%s: ip_route_output_key failed for 0x%08X\n",
+ printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n",
__func__, dst_ip);
return rc;
}
@@ -1057,8 +1151,6 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
cm_node->cm_id);
spin_lock_init(&cm_node->retrans_list_lock);
- INIT_LIST_HEAD(&cm_node->recv_list);
- spin_lock_init(&cm_node->recv_list_lock);
cm_node->loopbackpartner = NULL;
atomic_set(&cm_node->ref_count, 1);
@@ -1126,10 +1218,7 @@ static int add_ref_cm_node(struct nes_cm_node *cm_node)
static int rem_ref_cm_node(struct nes_cm_core *cm_core,
struct nes_cm_node *cm_node)
{
- unsigned long flags, qplockflags;
- struct nes_timer_entry *recv_entry;
- struct iw_cm_id *cm_id;
- struct list_head *list_core, *list_node_temp;
+ unsigned long flags;
struct nes_qp *nesqp;
if (!cm_node)
@@ -1150,38 +1239,9 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
atomic_dec(&cm_node->listener->pend_accepts_cnt);
BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
}
- BUG_ON(cm_node->send_entry);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
- list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) {
- recv_entry = container_of(list_core, struct nes_timer_entry,
- list);
- list_del(&recv_entry->list);
- cm_id = cm_node->cm_id;
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
- nesqp = (struct nes_qp *)recv_entry->skb;
- spin_lock_irqsave(&nesqp->lock, qplockflags);
- if (nesqp->cm_id) {
- nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
- "NES_TIMER_TYPE_CLOSE with something to do!\n",
- nesqp->hwqp.qp_id, cm_id);
- nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
- nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
- nesqp->ibqp_state = IB_QPS_ERR;
- spin_unlock_irqrestore(&nesqp->lock, qplockflags);
- nes_cm_disconn(nesqp);
- } else {
- spin_unlock_irqrestore(&nesqp->lock, qplockflags);
- nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
- "NES_TIMER_TYPE_CLOSE with nothing to do!\n",
- nesqp->hwqp.qp_id, cm_id);
- }
- cm_id->rem_ref(cm_id);
-
- kfree(recv_entry);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
- }
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
-
+ WARN_ON(cm_node->send_entry);
+ if (cm_node->recv_entry)
+ handle_recv_entry(cm_node, 0);
if (cm_node->listener) {
mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0);
} else {
@@ -1266,8 +1326,7 @@ static void drop_packet(struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
-static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
- struct tcphdr *tcph)
+static void handle_fin_pkt(struct nes_cm_node *cm_node)
{
nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. "
"refcnt=%d\n", cm_node, cm_node->state,
@@ -1279,23 +1338,30 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
case NES_CM_STATE_SYN_SENT:
case NES_CM_STATE_ESTABLISHED:
case NES_CM_STATE_MPAREQ_SENT:
+ case NES_CM_STATE_MPAREJ_RCVD:
cm_node->state = NES_CM_STATE_LAST_ACK;
- send_fin(cm_node, skb);
+ send_fin(cm_node, NULL);
break;
case NES_CM_STATE_FIN_WAIT1:
cm_node->state = NES_CM_STATE_CLOSING;
- send_ack(cm_node, skb);
+ send_ack(cm_node, NULL);
+ /* Wait for ACK as this is simultanous close..
+ * After we receive ACK, do not send anything..
+ * Just rm the node.. Done.. */
break;
case NES_CM_STATE_FIN_WAIT2:
cm_node->state = NES_CM_STATE_TIME_WAIT;
- send_ack(cm_node, skb);
+ send_ack(cm_node, NULL);
+ schedule_nes_timer(cm_node, NULL, NES_TIMER_TYPE_CLOSE, 1, 0);
+ break;
+ case NES_CM_STATE_TIME_WAIT:
cm_node->state = NES_CM_STATE_CLOSED;
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
break;
case NES_CM_STATE_TSA:
default:
nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n",
cm_node, cm_node->state);
- drop_packet(skb);
break;
}
}
@@ -1341,23 +1407,35 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
cleanup_retrans_entry(cm_node);
drop_packet(skb);
break;
+ case NES_CM_STATE_TIME_WAIT:
+ cleanup_retrans_entry(cm_node);
+ cm_node->state = NES_CM_STATE_CLOSED;
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ drop_packet(skb);
+ break;
+ case NES_CM_STATE_FIN_WAIT1:
+ cleanup_retrans_entry(cm_node);
+ nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
default:
drop_packet(skb);
break;
}
}
-static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
- enum nes_cm_event_type type)
+
+static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb)
{
- int ret;
+ int ret = 0;
int datasize = skb->len;
u8 *dataloc = skb->data;
- ret = parse_mpa(cm_node, dataloc, datasize);
- if (ret < 0) {
+
+ enum nes_cm_event_type type = NES_CM_EVENT_UNKNOWN;
+ u32 res_type;
+ ret = parse_mpa(cm_node, dataloc, &res_type, datasize);
+ if (ret) {
nes_debug(NES_DBG_CM, "didn't like MPA Request\n");
- if (type == NES_CM_EVENT_CONNECTED) {
+ if (cm_node->state == NES_CM_STATE_MPAREQ_SENT) {
nes_debug(NES_DBG_CM, "%s[%u] create abort for "
"cm_node=%p listener=%p state=%d\n", __func__,
__LINE__, cm_node, cm_node->listener,
@@ -1366,18 +1444,38 @@ static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
} else {
passive_open_err(cm_node, skb, 1);
}
- } else {
- cleanup_retrans_entry(cm_node);
- dev_kfree_skb_any(skb);
- if (type == NES_CM_EVENT_CONNECTED)
+ return;
+ }
+
+ switch (cm_node->state) {
+ case NES_CM_STATE_ESTABLISHED:
+ if (res_type == NES_MPA_REQUEST_REJECT) {
+ /*BIG problem as we are receiving the MPA.. So should
+ * not be REJECT.. This is Passive Open.. We can
+ * only receive it Reject for Active Open...*/
+ WARN_ON(1);
+ }
+ cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
+ type = NES_CM_EVENT_MPA_REQ;
+ atomic_set(&cm_node->passive_state,
+ NES_PASSIVE_STATE_INDICATED);
+ break;
+ case NES_CM_STATE_MPAREQ_SENT:
+ if (res_type == NES_MPA_REQUEST_REJECT) {
+ type = NES_CM_EVENT_MPA_REJECT;
+ cm_node->state = NES_CM_STATE_MPAREJ_RCVD;
+ } else {
+ type = NES_CM_EVENT_CONNECTED;
cm_node->state = NES_CM_STATE_TSA;
- else
- atomic_set(&cm_node->passive_state,
- NES_PASSIVE_STATE_INDICATED);
- create_event(cm_node, type);
+ }
+ break;
+ default:
+ WARN_ON(1);
+ break;
}
- return ;
+ dev_kfree_skb_any(skb);
+ create_event(cm_node, type);
}
static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb)
@@ -1465,8 +1563,6 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
break;
case NES_CM_STATE_LISTENING:
/* Passive OPEN */
- cm_node->accept_pend = 1;
- atomic_inc(&cm_node->listener->pend_accepts_cnt);
if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
cm_node->listener->backlog) {
nes_debug(NES_DBG_CM, "drop syn due to backlog "
@@ -1484,6 +1580,9 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
}
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
BUG_ON(cm_node->send_entry);
+ cm_node->accept_pend = 1;
+ atomic_inc(&cm_node->listener->pend_accepts_cnt);
+
cm_node->state = NES_CM_STATE_SYN_RCVD;
send_syn(cm_node, 1, skb);
break;
@@ -1518,6 +1617,7 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
inc_sequence = ntohl(tcph->seq);
switch (cm_node->state) {
case NES_CM_STATE_SYN_SENT:
+ cleanup_retrans_entry(cm_node);
/* active open */
if (check_syn(cm_node, tcph, skb))
return;
@@ -1567,10 +1667,7 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
u32 rem_seq;
int ret;
int optionsize;
- u32 temp_seq = cm_node->tcp_cntxt.loc_seq_num;
-
optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
- cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
if (check_seq(cm_node, tcph, skb))
return;
@@ -1580,7 +1677,7 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
rem_seq = ntohl(tcph->seq);
rem_seq_ack = ntohl(tcph->ack_seq);
datasize = skb->len;
-
+ cleanup_retrans_entry(cm_node);
switch (cm_node->state) {
case NES_CM_STATE_SYN_RCVD:
/* Passive OPEN */
@@ -1588,7 +1685,6 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
if (ret)
break;
cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
- cm_node->tcp_cntxt.loc_seq_num = temp_seq;
if (cm_node->tcp_cntxt.rem_ack_num !=
cm_node->tcp_cntxt.loc_seq_num) {
nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n");
@@ -1597,31 +1693,30 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
return;
}
cm_node->state = NES_CM_STATE_ESTABLISHED;
+ cleanup_retrans_entry(cm_node);
if (datasize) {
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
- cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
- handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_MPA_REQ);
- } else { /* rcvd ACK only */
+ handle_rcv_mpa(cm_node, skb);
+ } else { /* rcvd ACK only */
dev_kfree_skb_any(skb);
cleanup_retrans_entry(cm_node);
}
break;
case NES_CM_STATE_ESTABLISHED:
/* Passive OPEN */
- /* We expect mpa frame to be received only */
+ cleanup_retrans_entry(cm_node);
if (datasize) {
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
- cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
- handle_rcv_mpa(cm_node, skb,
- NES_CM_EVENT_MPA_REQ);
+ handle_rcv_mpa(cm_node, skb);
} else
drop_packet(skb);
break;
case NES_CM_STATE_MPAREQ_SENT:
+ cleanup_retrans_entry(cm_node);
cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
if (datasize) {
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
- handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_CONNECTED);
+ handle_rcv_mpa(cm_node, skb);
} else { /* Could be just an ack pkt.. */
cleanup_retrans_entry(cm_node);
dev_kfree_skb_any(skb);
@@ -1632,13 +1727,24 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
cleanup_retrans_entry(cm_node);
send_reset(cm_node, skb);
break;
+ case NES_CM_STATE_LAST_ACK:
+ cleanup_retrans_entry(cm_node);
+ cm_node->state = NES_CM_STATE_CLOSED;
+ cm_node->cm_id->rem_ref(cm_node->cm_id);
+ case NES_CM_STATE_CLOSING:
+ cleanup_retrans_entry(cm_node);
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ drop_packet(skb);
+ break;
case NES_CM_STATE_FIN_WAIT1:
+ cleanup_retrans_entry(cm_node);
+ drop_packet(skb);
+ cm_node->state = NES_CM_STATE_FIN_WAIT2;
+ break;
case NES_CM_STATE_SYN_SENT:
case NES_CM_STATE_FIN_WAIT2:
case NES_CM_STATE_TSA:
case NES_CM_STATE_MPAREQ_RCVD:
- case NES_CM_STATE_LAST_ACK:
- case NES_CM_STATE_CLOSING:
case NES_CM_STATE_UNKNOWN:
default:
drop_packet(skb);
@@ -1748,6 +1854,7 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
{
enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN;
struct tcphdr *tcph = tcp_hdr(skb);
+ u32 fin_set = 0;
skb_pull(skb, ip_hdr(skb)->ihl << 2);
nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d "
@@ -1760,10 +1867,10 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
pkt_type = NES_PKT_TYPE_SYN;
if (tcph->ack)
pkt_type = NES_PKT_TYPE_SYNACK;
- } else if (tcph->fin)
- pkt_type = NES_PKT_TYPE_FIN;
- else if (tcph->ack)
+ } else if (tcph->ack)
pkt_type = NES_PKT_TYPE_ACK;
+ if (tcph->fin)
+ fin_set = 1;
switch (pkt_type) {
case NES_PKT_TYPE_SYN:
@@ -1774,15 +1881,16 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
break;
case NES_PKT_TYPE_ACK:
handle_ack_pkt(cm_node, skb, tcph);
+ if (fin_set)
+ handle_fin_pkt(cm_node);
break;
case NES_PKT_TYPE_RST:
handle_rst_pkt(cm_node, skb, tcph);
break;
- case NES_PKT_TYPE_FIN:
- handle_fin_pkt(cm_node, skb, tcph);
- break;
default:
drop_packet(skb);
+ if (fin_set)
+ handle_fin_pkt(cm_node);
break;
}
}
@@ -1925,7 +2033,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
loopbackremotenode->tcp_cntxt.rcv_wscale;
loopbackremotenode->tcp_cntxt.snd_wscale =
cm_node->tcp_cntxt.rcv_wscale;
-
+ loopbackremotenode->state = NES_CM_STATE_MPAREQ_RCVD;
create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
}
return cm_node;
@@ -1980,7 +2088,11 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
{
int ret = 0;
+ int err = 0;
int passive_state;
+ struct nes_cm_event event;
+ struct iw_cm_id *cm_id = cm_node->cm_id;
+ struct nes_cm_node *loopback = cm_node->loopbackpartner;
nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n",
__func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state);
@@ -1989,12 +2101,38 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
return ret;
cleanup_retrans_entry(cm_node);
- passive_state = atomic_add_return(1, &cm_node->passive_state);
- cm_node->state = NES_CM_STATE_CLOSED;
- if (passive_state == NES_SEND_RESET_EVENT)
+ if (!loopback) {
+ passive_state = atomic_add_return(1, &cm_node->passive_state);
+ if (passive_state == NES_SEND_RESET_EVENT) {
+ cm_node->state = NES_CM_STATE_CLOSED;
+ rem_ref_cm_node(cm_core, cm_node);
+ } else {
+ ret = send_mpa_reject(cm_node);
+ if (ret) {
+ cm_node->state = NES_CM_STATE_CLOSED;
+ err = send_reset(cm_node, NULL);
+ if (err)
+ WARN_ON(1);
+ } else
+ cm_id->add_ref(cm_id);
+ }
+ } else {
+ cm_node->cm_id = NULL;
+ event.cm_node = loopback;
+ event.cm_info.rem_addr = loopback->rem_addr;
+ event.cm_info.loc_addr = loopback->loc_addr;
+ event.cm_info.rem_port = loopback->rem_port;
+ event.cm_info.loc_port = loopback->loc_port;
+ event.cm_info.cm_id = loopback->cm_id;
+ cm_event_mpa_reject(&event);
rem_ref_cm_node(cm_core, cm_node);
- else
- ret = send_reset(cm_node, NULL);
+ loopback->state = NES_CM_STATE_CLOSING;
+
+ cm_id = loopback->cm_id;
+ rem_ref_cm_node(cm_core, loopback);
+ cm_id->rem_ref(cm_id);
+ }
+
return ret;
}
@@ -2031,6 +2169,7 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
case NES_CM_STATE_CLOSING:
ret = -1;
break;
+ case NES_CM_STATE_MPAREJ_RCVD:
case NES_CM_STATE_LISTENING:
case NES_CM_STATE_UNKNOWN:
case NES_CM_STATE_INITED:
@@ -2227,15 +2366,15 @@ static int mini_cm_set(struct nes_cm_core *cm_core, u32 type, u32 value)
int ret = 0;
switch (type) {
- case NES_CM_SET_PKT_SIZE:
- cm_core->mtu = value;
- break;
- case NES_CM_SET_FREE_PKT_Q_SIZE:
- cm_core->free_tx_pkt_max = value;
- break;
- default:
- /* unknown set option */
- ret = -EINVAL;
+ case NES_CM_SET_PKT_SIZE:
+ cm_core->mtu = value;
+ break;
+ case NES_CM_SET_FREE_PKT_Q_SIZE:
+ cm_core->free_tx_pkt_max = value;
+ break;
+ default:
+ /* unknown set option */
+ ret = -EINVAL;
}
return ret;
@@ -2490,12 +2629,14 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt)
int ret = 0;
struct nes_vnic *nesvnic;
struct nes_device *nesdev;
+ struct nes_ib_device *nesibdev;
nesvnic = to_nesvnic(nesqp->ibqp.device);
if (!nesvnic)
return -EINVAL;
nesdev = nesvnic->nesdev;
+ nesibdev = nesvnic->nesibdev;
nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n",
atomic_read(&nesvnic->netdev->refcnt));
@@ -2507,6 +2648,8 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt)
} else {
/* Need to free the Last Streaming Mode Message */
if (nesqp->ietf_frame) {
+ if (nesqp->lsmm_mr)
+ nesibdev->ibdev.dereg_mr(nesqp->lsmm_mr);
pci_free_consistent(nesdev->pcidev,
nesqp->private_data_len+sizeof(struct ietf_mpa_frame),
nesqp->ietf_frame, nesqp->ietf_frame_pbase);
@@ -2543,6 +2686,12 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
u32 crc_value;
int ret;
int passive_state;
+ struct nes_ib_device *nesibdev;
+ struct ib_mr *ibmr = NULL;
+ struct ib_phys_buf ibphysbuf;
+ struct nes_pd *nespd;
+
+
ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
if (!ibqp)
@@ -2601,6 +2750,26 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
if (cm_id->remote_addr.sin_addr.s_addr !=
cm_id->local_addr.sin_addr.s_addr) {
u64temp = (unsigned long)nesqp;
+ nesibdev = nesvnic->nesibdev;
+ nespd = nesqp->nespd;
+ ibphysbuf.addr = nesqp->ietf_frame_pbase;
+ ibphysbuf.size = conn_param->private_data_len +
+ sizeof(struct ietf_mpa_frame);
+ ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd,
+ &ibphysbuf, 1,
+ IB_ACCESS_LOCAL_WRITE,
+ (u64 *)&nesqp->ietf_frame);
+ if (!ibmr) {
+ nes_debug(NES_DBG_CM, "Unable to register memory region"
+ "for lSMM for cm_node = %p \n",
+ cm_node);
+ return -ENOMEM;
+ }
+
+ ibmr->pd = &nespd->ibpd;
+ ibmr->device = nespd->ibpd.device;
+ nesqp->lsmm_mr = ibmr;
+
u64temp |= NES_SW_CONTEXT_ALIGN>>1;
set_wqe_64bit_value(wqe->wqe_words,
NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX,
@@ -2611,23 +2780,20 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] =
cpu_to_le32(conn_param->private_data_len +
sizeof(struct ietf_mpa_frame));
- wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] =
- cpu_to_le32((u32)nesqp->ietf_frame_pbase);
- wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] =
- cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32));
+ set_wqe_64bit_value(wqe->wqe_words,
+ NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
+ (u64)nesqp->ietf_frame);
wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
cpu_to_le32(conn_param->private_data_len +
sizeof(struct ietf_mpa_frame));
- wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
+ wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey;
nesqp->nesqp_context->ird_ord_sizes |=
cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
NES_QPCONTEXT_ORDIRD_WRPDU);
} else {
nesqp->nesqp_context->ird_ord_sizes |=
- cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
- NES_QPCONTEXT_ORDIRD_WRPDU |
- NES_QPCONTEXT_ORDIRD_ALSMM));
+ cpu_to_le32(NES_QPCONTEXT_ORDIRD_WRPDU);
}
nesqp->skip_lsmm = 1;
@@ -2749,23 +2915,35 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
{
struct nes_cm_node *cm_node;
+ struct nes_cm_node *loopback;
+
struct nes_cm_core *cm_core;
atomic_inc(&cm_rejects);
cm_node = (struct nes_cm_node *) cm_id->provider_data;
+ loopback = cm_node->loopbackpartner;
cm_core = cm_node->cm_core;
+ cm_node->cm_id = cm_id;
cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len;
+ if (cm_node->mpa_frame_size > MAX_CM_BUFFER)
+ return -EINVAL;
+
strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP);
- memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
+ if (loopback) {
+ memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len);
+ loopback->mpa_frame.priv_data_len = pdata_len;
+ loopback->mpa_frame_size = sizeof(struct ietf_mpa_frame) +
+ pdata_len;
+ } else {
+ memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
+ cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
+ }
- cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
cm_node->mpa_frame.rev = mpa_version;
cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT;
- cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
-
- return 0;
+ return cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
}
@@ -3274,13 +3452,56 @@ static void cm_event_mpa_req(struct nes_cm_event *event)
cm_event.remote_addr.sin_family = AF_INET;
cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
+ cm_event.private_data = cm_node->mpa_frame_buf;
+ cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
+
+ ret = cm_id->event_handler(cm_id, &cm_event);
+ if (ret)
+ printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
+ __func__, __LINE__, ret);
+ return;
+}
+
+
+static void cm_event_mpa_reject(struct nes_cm_event *event)
+{
+ struct iw_cm_id *cm_id;
+ struct iw_cm_event cm_event;
+ struct nes_cm_node *cm_node;
+ int ret;
+
+ cm_node = event->cm_node;
+ if (!cm_node)
+ return;
+ cm_id = cm_node->cm_id;
+
+ atomic_inc(&cm_connect_reqs);
+ nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
+ cm_node, cm_id, jiffies);
+
+ cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
+ cm_event.status = -ECONNREFUSED;
+ cm_event.provider_data = cm_id->provider_data;
+
+ cm_event.local_addr.sin_family = AF_INET;
+ cm_event.local_addr.sin_port = htons(event->cm_info.loc_port);
+ cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr);
+
+ cm_event.remote_addr.sin_family = AF_INET;
+ cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
+ cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
- cm_event.private_data = cm_node->mpa_frame_buf;
- cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
+ cm_event.private_data = cm_node->mpa_frame_buf;
+ cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
+
+ nes_debug(NES_DBG_CM, "call CM_EVENT_MPA_REJECTED, local_addr=%08x, "
+ "remove_addr=%08x\n",
+ cm_event.local_addr.sin_addr.s_addr,
+ cm_event.remote_addr.sin_addr.s_addr);
ret = cm_id->event_handler(cm_id, &cm_event);
if (ret)
- printk("%s[%u] OFA CM event_handler returned, ret=%d\n",
+ printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
__func__, __LINE__, ret);
return;
@@ -3345,6 +3566,14 @@ static void nes_cm_event_handler(struct work_struct *work)
cm_event_connected(event);
nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
break;
+ case NES_CM_EVENT_MPA_REJECT:
+ if ((!event->cm_node->cm_id) ||
+ (event->cm_node->state == NES_CM_STATE_TSA))
+ break;
+ cm_event_mpa_reject(event);
+ nes_debug(NES_DBG_CM, "CM Event: REJECT\n");
+ break;
+
case NES_CM_EVENT_ABORTED:
if ((!event->cm_node->cm_id) ||
(event->cm_node->state == NES_CM_STATE_TSA))
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index fafa35042eb..d5f778202eb 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, 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
@@ -39,6 +39,9 @@
#define NES_MANAGE_APBVT_DEL 0
#define NES_MANAGE_APBVT_ADD 1
+#define NES_MPA_REQUEST_ACCEPT 1
+#define NES_MPA_REQUEST_REJECT 2
+
/* IETF MPA -- defines, enums, structs */
#define IEFT_MPA_KEY_REQ "MPA ID Req Frame"
#define IEFT_MPA_KEY_REP "MPA ID Rep Frame"
@@ -186,6 +189,7 @@ enum nes_cm_node_state {
NES_CM_STATE_ACCEPTING,
NES_CM_STATE_MPAREQ_SENT,
NES_CM_STATE_MPAREQ_RCVD,
+ NES_CM_STATE_MPAREJ_RCVD,
NES_CM_STATE_TSA,
NES_CM_STATE_FIN_WAIT1,
NES_CM_STATE_FIN_WAIT2,
@@ -278,13 +282,12 @@ struct nes_cm_node {
struct nes_timer_entry *send_entry;
spinlock_t retrans_list_lock;
- struct list_head recv_list;
- spinlock_t recv_list_lock;
+ struct nes_timer_entry *recv_entry;
int send_write0;
union {
struct ietf_mpa_frame mpa_frame;
- u8 mpa_frame_buf[NES_CM_DEFAULT_MTU];
+ u8 mpa_frame_buf[MAX_CM_BUFFER];
};
u16 mpa_frame_size;
struct iw_cm_id *cm_id;
@@ -326,6 +329,7 @@ enum nes_cm_event_type {
NES_CM_EVENT_MPA_REQ,
NES_CM_EVENT_MPA_CONNECT,
NES_CM_EVENT_MPA_ACCEPT,
+ NES_CM_EVENT_MPA_REJECT,
NES_CM_EVENT_MPA_ESTABLISHED,
NES_CM_EVENT_CONNECTED,
NES_CM_EVENT_CLOSED,
diff --git a/drivers/infiniband/hw/nes/nes_context.h b/drivers/infiniband/hw/nes/nes_context.h
index da9daba8e66..0fb8d81d9a6 100644
--- a/drivers/infiniband/hw/nes/nes_context.h
+++ b/drivers/infiniband/hw/nes/nes_context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, 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
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 5d139db1b77..52e734042b8 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, 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
@@ -254,6 +254,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
u32 adapter_size;
u32 arp_table_size;
u16 vendor_id;
+ u16 device_id;
u8 OneG_Mode;
u8 func_index;
@@ -356,6 +357,13 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
return NULL;
}
+ nesadapter->vendor_id = (((u32) nesadapter->mac_addr_high) << 8) |
+ (nesadapter->mac_addr_low >> 24);
+
+ pci_bus_read_config_word(nesdev->pcidev->bus, nesdev->pcidev->devfn,
+ PCI_DEVICE_ID, &device_id);
+ nesadapter->vendor_part_id = device_id;
+
if (nes_init_serdes(nesdev, hw_rev, port_count, nesadapter,
OneG_Mode)) {
kfree(nesadapter);
@@ -1636,7 +1644,6 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
nesvnic->post_cqp_request = nes_post_cqp_request;
nesvnic->mcrq_mcast_filter = NULL;
- spin_lock_init(&nesvnic->nic.sq_lock);
spin_lock_init(&nesvnic->nic.rq_lock);
/* setup the RQ */
@@ -2261,6 +2268,8 @@ static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq)
if (++head >= aeq_size)
head = 0;
+
+ nes_write32(nesdev->regs + NES_AEQ_ALLOC, 1 << 16);
}
while (1);
aeq->aeq_head = head;
@@ -2541,7 +2550,7 @@ static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic
{
struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
- netif_rx_schedule(&nesvnic->napi);
+ napi_schedule(&nesvnic->napi);
}
@@ -2622,9 +2631,9 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
} else
break;
}
- if (skb)
- dev_kfree_skb_any(skb);
}
+ if (skb)
+ dev_kfree_skb_any(skb);
nesnic->sq_tail++;
nesnic->sq_tail &= nesnic->sq_size-1;
if (sq_cqes > 128) {
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index bc0b4de0445..f41a8710d2a 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+* Copyright (c) 2006 - 2009 Intel-NE, 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
@@ -61,6 +61,7 @@ enum pci_regs {
NES_CQ_ACK = 0x0034,
NES_WQE_ALLOC = 0x0040,
NES_CQE_ALLOC = 0x0044,
+ NES_AEQ_ALLOC = 0x0048
};
enum indexed_regs {
@@ -875,7 +876,6 @@ struct nes_hw_nic {
u8 replenishing_rq;
u8 reserved;
- spinlock_t sq_lock;
spinlock_t rq_lock;
};
@@ -1147,7 +1147,6 @@ struct nes_ib_device;
struct nes_vnic {
struct nes_ib_device *nesibdev;
u64 sq_full;
- u64 sq_locked;
u64 tso_requests;
u64 segmented_tso_requests;
u64 linearized_skbs;
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 57a47cf7e51..8d3e4c6f237 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, 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
@@ -111,7 +111,7 @@ static int nes_netdev_poll(struct napi_struct *napi, int budget)
nes_nic_ce_handler(nesdev, nescq);
if (nescq->cqes_pending == 0) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* clear out completed cqes and arm */
nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
nescq->cq_number | (nescq->cqe_allocs_pending << 16));
@@ -400,8 +400,7 @@ static int nes_nic_send(struct sk_buff *skb, struct net_device *netdev)
if (skb_headlen(skb) == skb->len) {
if (skb_headlen(skb) <= NES_FIRST_FRAG_SIZE) {
nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_2_1_IDX] = 0;
- nesnic->tx_skb[nesnic->sq_head] = NULL;
- dev_kfree_skb(skb);
+ nesnic->tx_skb[nesnic->sq_head] = skb;
}
} else {
/* Deal with Fragments */
@@ -453,7 +452,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
u32 wqe_count=1;
u32 send_rc;
struct iphdr *iph;
- unsigned long flags;
__le16 *wqe_fragment_length;
u32 nr_frags;
u32 original_first_length;
@@ -480,13 +478,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if (netif_queue_stopped(netdev))
return NETDEV_TX_BUSY;
- local_irq_save(flags);
- if (!spin_trylock(&nesnic->sq_lock)) {
- local_irq_restore(flags);
- nesvnic->sq_locked++;
- return NETDEV_TX_LOCKED;
- }
-
/* Check if SQ is full */
if ((((nesnic->sq_tail+(nesnic->sq_size*2))-nesnic->sq_head) & (nesnic->sq_size - 1)) == 1) {
if (!netif_queue_stopped(netdev)) {
@@ -498,7 +489,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
}
}
nesvnic->sq_full++;
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -531,7 +521,6 @@ sq_no_longer_full:
}
}
nesvnic->sq_full++;
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
nes_debug(NES_DBG_NIC_TX, "%s: HNIC SQ full- TSO request has too many frags!\n",
netdev->name);
return NETDEV_TX_BUSY;
@@ -656,17 +645,13 @@ tso_sq_no_longer_full:
skb_set_transport_header(skb, hoffset);
skb_set_network_header(skb, nhoffset);
send_rc = nes_nic_send(skb, netdev);
- if (send_rc != NETDEV_TX_OK) {
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
+ if (send_rc != NETDEV_TX_OK)
return NETDEV_TX_OK;
- }
}
} else {
send_rc = nes_nic_send(skb, netdev);
- if (send_rc != NETDEV_TX_OK) {
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
+ if (send_rc != NETDEV_TX_OK)
return NETDEV_TX_OK;
- }
}
barrier();
@@ -676,7 +661,6 @@ tso_sq_no_longer_full:
(wqe_count << 24) | (1 << 23) | nesvnic->nic.qp_id);
netdev->trans_start = jiffies;
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
return NETDEV_TX_OK;
}
@@ -1012,7 +996,6 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = {
"Pause Frames Received",
"Internal Routing Errors",
"SQ SW Dropped SKBs",
- "SQ Locked",
"SQ Full",
"Segmented TSO Requests",
"Rx Symbol Errors",
@@ -1129,16 +1112,17 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev,
struct nes_device *nesdev = nesvnic->nesdev;
u32 nic_count;
u32 u32temp;
+ u32 index = 0;
target_ethtool_stats->n_stats = NES_ETHTOOL_STAT_COUNT;
- target_stat_values[0] = nesvnic->nesdev->link_status_interrupts;
- target_stat_values[1] = nesvnic->linearized_skbs;
- target_stat_values[2] = nesvnic->tso_requests;
+ target_stat_values[index] = nesvnic->nesdev->link_status_interrupts;
+ target_stat_values[++index] = nesvnic->linearized_skbs;
+ target_stat_values[++index] = nesvnic->tso_requests;
u32temp = nes_read_indexed(nesdev,
NES_IDX_MAC_TX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200));
nesvnic->nesdev->mac_pause_frames_sent += u32temp;
- target_stat_values[3] = nesvnic->nesdev->mac_pause_frames_sent;
+ target_stat_values[++index] = nesvnic->nesdev->mac_pause_frames_sent;
u32temp = nes_read_indexed(nesdev,
NES_IDX_MAC_RX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200));
@@ -1209,60 +1193,59 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev,
nesvnic->endnode_ipv4_tcp_retransmits += u32temp;
}
- target_stat_values[4] = nesvnic->nesdev->mac_pause_frames_received;
- target_stat_values[5] = nesdev->nesadapter->nic_rx_eth_route_err;
- target_stat_values[6] = nesvnic->tx_sw_dropped;
- target_stat_values[7] = nesvnic->sq_locked;
- target_stat_values[8] = nesvnic->sq_full;
- target_stat_values[9] = nesvnic->segmented_tso_requests;
- target_stat_values[10] = nesvnic->nesdev->mac_rx_symbol_err_frames;
- target_stat_values[11] = nesvnic->nesdev->mac_rx_jabber_frames;
- target_stat_values[12] = nesvnic->nesdev->mac_rx_oversized_frames;
- target_stat_values[13] = nesvnic->nesdev->mac_rx_short_frames;
- target_stat_values[14] = nesvnic->endnode_nstat_rx_discard;
- target_stat_values[15] = nesvnic->endnode_nstat_rx_octets;
- target_stat_values[16] = nesvnic->endnode_nstat_rx_frames;
- target_stat_values[17] = nesvnic->endnode_nstat_tx_octets;
- target_stat_values[18] = nesvnic->endnode_nstat_tx_frames;
- target_stat_values[19] = mh_detected;
- target_stat_values[20] = mh_pauses_sent;
- target_stat_values[21] = nesvnic->endnode_ipv4_tcp_retransmits;
- target_stat_values[22] = atomic_read(&cm_connects);
- target_stat_values[23] = atomic_read(&cm_accepts);
- target_stat_values[24] = atomic_read(&cm_disconnects);
- target_stat_values[25] = atomic_read(&cm_connecteds);
- target_stat_values[26] = atomic_read(&cm_connect_reqs);
- target_stat_values[27] = atomic_read(&cm_rejects);
- target_stat_values[28] = atomic_read(&mod_qp_timouts);
- target_stat_values[29] = atomic_read(&qps_created);
- target_stat_values[30] = atomic_read(&sw_qps_destroyed);
- target_stat_values[31] = atomic_read(&qps_destroyed);
- target_stat_values[32] = atomic_read(&cm_closes);
- target_stat_values[33] = cm_packets_sent;
- target_stat_values[34] = cm_packets_bounced;
- target_stat_values[35] = cm_packets_created;
- target_stat_values[36] = cm_packets_received;
- target_stat_values[37] = cm_packets_dropped;
- target_stat_values[38] = cm_packets_retrans;
- target_stat_values[39] = cm_listens_created;
- target_stat_values[40] = cm_listens_destroyed;
- target_stat_values[41] = cm_backlog_drops;
- target_stat_values[42] = atomic_read(&cm_loopbacks);
- target_stat_values[43] = atomic_read(&cm_nodes_created);
- target_stat_values[44] = atomic_read(&cm_nodes_destroyed);
- target_stat_values[45] = atomic_read(&cm_accel_dropped_pkts);
- target_stat_values[46] = atomic_read(&cm_resets_recvd);
- target_stat_values[47] = int_mod_timer_init;
- target_stat_values[48] = int_mod_cq_depth_1;
- target_stat_values[49] = int_mod_cq_depth_4;
- target_stat_values[50] = int_mod_cq_depth_16;
- target_stat_values[51] = int_mod_cq_depth_24;
- target_stat_values[52] = int_mod_cq_depth_32;
- target_stat_values[53] = int_mod_cq_depth_128;
- target_stat_values[54] = int_mod_cq_depth_256;
- target_stat_values[55] = nesvnic->lro_mgr.stats.aggregated;
- target_stat_values[56] = nesvnic->lro_mgr.stats.flushed;
- target_stat_values[57] = nesvnic->lro_mgr.stats.no_desc;
+ target_stat_values[++index] = nesvnic->nesdev->mac_pause_frames_received;
+ target_stat_values[++index] = nesdev->nesadapter->nic_rx_eth_route_err;
+ target_stat_values[++index] = nesvnic->tx_sw_dropped;
+ target_stat_values[++index] = nesvnic->sq_full;
+ target_stat_values[++index] = nesvnic->segmented_tso_requests;
+ target_stat_values[++index] = nesvnic->nesdev->mac_rx_symbol_err_frames;
+ target_stat_values[++index] = nesvnic->nesdev->mac_rx_jabber_frames;
+ target_stat_values[++index] = nesvnic->nesdev->mac_rx_oversized_frames;
+ target_stat_values[++index] = nesvnic->nesdev->mac_rx_short_frames;
+ target_stat_values[++index] = nesvnic->endnode_nstat_rx_discard;
+ target_stat_values[++index] = nesvnic->endnode_nstat_rx_octets;
+ target_stat_values[++index] = nesvnic->endnode_nstat_rx_frames;
+ target_stat_values[++index] = nesvnic->endnode_nstat_tx_octets;
+ target_stat_values[++index] = nesvnic->endnode_nstat_tx_frames;
+ target_stat_values[++index] = mh_detected;
+ target_stat_values[++index] = mh_pauses_sent;
+ target_stat_values[++index] = nesvnic->endnode_ipv4_tcp_retransmits;
+ target_stat_values[++index] = atomic_read(&cm_connects);
+ target_stat_values[++index] = atomic_read(&cm_accepts);
+ target_stat_values[++index] = atomic_read(&cm_disconnects);
+ target_stat_values[++index] = atomic_read(&cm_connecteds);
+ target_stat_values[++index] = atomic_read(&cm_connect_reqs);
+ target_stat_values[++index] = atomic_read(&cm_rejects);
+ target_stat_values[++index] = atomic_read(&mod_qp_timouts);
+ target_stat_values[++index] = atomic_read(&qps_created);
+ target_stat_values[++index] = atomic_read(&sw_qps_destroyed);
+ target_stat_values[++index] = atomic_read(&qps_destroyed);
+ target_stat_values[++index] = atomic_read(&cm_closes);
+ target_stat_values[++index] = cm_packets_sent;
+ target_stat_values[++index] = cm_packets_bounced;
+ target_stat_values[++index] = cm_packets_created;
+ target_stat_values[++index] = cm_packets_received;
+ target_stat_values[++index] = cm_packets_dropped;
+ target_stat_values[++index] = cm_packets_retrans;
+ target_stat_values[++index] = cm_listens_created;
+ target_stat_values[++index] = cm_listens_destroyed;
+ target_stat_values[++index] = cm_backlog_drops;
+ target_stat_values[++index] = atomic_read(&cm_loopbacks);
+ target_stat_values[++index] = atomic_read(&cm_nodes_created);
+ target_stat_values[++index] = atomic_read(&cm_nodes_destroyed);
+ target_stat_values[++index] = atomic_read(&cm_accel_dropped_pkts);
+ target_stat_values[++index] = atomic_read(&cm_resets_recvd);
+ target_stat_values[++index] = int_mod_timer_init;
+ target_stat_values[++index] = int_mod_cq_depth_1;
+ target_stat_values[++index] = int_mod_cq_depth_4;
+ target_stat_values[++index] = int_mod_cq_depth_16;
+ target_stat_values[++index] = int_mod_cq_depth_24;
+ target_stat_values[++index] = int_mod_cq_depth_32;
+ target_stat_values[++index] = int_mod_cq_depth_128;
+ target_stat_values[++index] = int_mod_cq_depth_256;
+ target_stat_values[++index] = nesvnic->lro_mgr.stats.aggregated;
+ target_stat_values[++index] = nesvnic->lro_mgr.stats.flushed;
+ target_stat_values[++index] = nesvnic->lro_mgr.stats.no_desc;
}
@@ -1568,6 +1551,19 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
}
+static const struct net_device_ops nes_netdev_ops = {
+ .ndo_open = nes_netdev_open,
+ .ndo_stop = nes_netdev_stop,
+ .ndo_start_xmit = nes_netdev_start_xmit,
+ .ndo_get_stats = nes_netdev_get_stats,
+ .ndo_tx_timeout = nes_netdev_tx_timeout,
+ .ndo_set_mac_address = nes_netdev_set_mac_address,
+ .ndo_set_multicast_list = nes_netdev_set_multicast_list,
+ .ndo_change_mtu = nes_netdev_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_vlan_rx_register = nes_netdev_vlan_rx_register,
+};
/**
* nes_netdev_init - initialize network device
@@ -1576,7 +1572,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
void __iomem *mmio_addr)
{
u64 u64temp;
- struct nes_vnic *nesvnic = NULL;
+ struct nes_vnic *nesvnic;
struct net_device *netdev;
struct nic_qp_map *curr_qp_map;
u32 u32temp;
@@ -1588,22 +1584,12 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
printk(KERN_ERR PFX "nesvnic etherdev alloc failed");
return NULL;
}
+ nesvnic = netdev_priv(netdev);
nes_debug(NES_DBG_INIT, "netdev = %p, %s\n", netdev, netdev->name);
SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev);
- nesvnic = netdev_priv(netdev);
- memset(nesvnic, 0, sizeof(*nesvnic));
-
- netdev->open = nes_netdev_open;
- netdev->stop = nes_netdev_stop;
- netdev->hard_start_xmit = nes_netdev_start_xmit;
- netdev->get_stats = nes_netdev_get_stats;
- netdev->tx_timeout = nes_netdev_tx_timeout;
- netdev->set_mac_address = nes_netdev_set_mac_address;
- netdev->set_multicast_list = nes_netdev_set_multicast_list;
- netdev->change_mtu = nes_netdev_change_mtu;
netdev->watchdog_timeo = NES_TX_TIMEOUT;
netdev->irq = nesdev->pcidev->irq;
netdev->mtu = ETH_DATA_LEN;
@@ -1611,6 +1597,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
netdev->addr_len = ETH_ALEN;
netdev->type = ARPHRD_ETHER;
netdev->features = NETIF_F_HIGHDMA;
+ netdev->netdev_ops = &nes_netdev_ops;
netdev->ethtool_ops = &nes_ethtool_ops;
netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
diff --git a/drivers/infiniband/hw/nes/nes_user.h b/drivers/infiniband/hw/nes/nes_user.h
index e64306bce80..cc90c14b49e 100644
--- a/drivers/infiniband/hw/nes/nes_user.h
+++ b/drivers/infiniband/hw/nes/nes_user.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Cisco Systems. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c
index 6f3bc1b6bf2..a282031d15c 100644
--- a/drivers/infiniband/hw/nes/nes_utils.c
+++ b/drivers/infiniband/hw/nes/nes_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, 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
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 4fdb72454f9..7e5b5ba13a7 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, 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
@@ -551,6 +551,7 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
struct nes_device *nesdev = nesvnic->nesdev;
struct nes_adapter *nesadapter = nesdev->nesadapter;
int i = 0;
+ int rc;
/* free the resources */
if (nesfmr->leaf_pbl_cnt == 0) {
@@ -572,7 +573,9 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
nesmr->ibmw.rkey = ibfmr->rkey;
nesmr->ibmw.uobject = NULL;
- if (nesfmr->nesmr.pbls_used != 0) {
+ rc = nes_dealloc_mw(&nesmr->ibmw);
+
+ if ((rc == 0) && (nesfmr->nesmr.pbls_used != 0)) {
spin_lock_irqsave(&nesadapter->pbl_lock, flags);
if (nesfmr->nesmr.pbl_4k) {
nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used;
@@ -584,7 +587,7 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
}
- return nes_dealloc_mw(&nesmr->ibmw);
+ return rc;
}
@@ -1360,8 +1363,10 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
NES_QPCONTEXT_MISC_RQ_SIZE_SHIFT);
nesqp->nesqp_context->misc |= cpu_to_le32((u32)nesqp->hwqp.sq_encoded_size <<
NES_QPCONTEXT_MISC_SQ_SIZE_SHIFT);
+ if (!udata) {
nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_PRIV_EN);
nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_FAST_REGISTER_EN);
+ }
nesqp->nesqp_context->cqs = cpu_to_le32(nesqp->nesscq->hw_cq.cq_number +
((u32)nesqp->nesrcq->hw_cq.cq_number << 16));
u64temp = (u64)nesqp->hwqp.sq_pbase;
@@ -1884,21 +1889,75 @@ static int nes_destroy_cq(struct ib_cq *ib_cq)
return ret;
}
+/**
+ * root_256
+ */
+static u32 root_256(struct nes_device *nesdev,
+ struct nes_root_vpbl *root_vpbl,
+ struct nes_root_vpbl *new_root,
+ u16 pbl_count_4k,
+ u16 pbl_count_256)
+{
+ u64 leaf_pbl;
+ int i, j, k;
+
+ if (pbl_count_4k == 1) {
+ new_root->pbl_vbase = pci_alloc_consistent(nesdev->pcidev,
+ 512, &new_root->pbl_pbase);
+
+ if (new_root->pbl_vbase == NULL)
+ return 0;
+
+ leaf_pbl = (u64)root_vpbl->pbl_pbase;
+ for (i = 0; i < 16; i++) {
+ new_root->pbl_vbase[i].pa_low =
+ cpu_to_le32((u32)leaf_pbl);
+ new_root->pbl_vbase[i].pa_high =
+ cpu_to_le32((u32)((((u64)leaf_pbl) >> 32)));
+ leaf_pbl += 256;
+ }
+ } else {
+ for (i = 3; i >= 0; i--) {
+ j = i * 16;
+ root_vpbl->pbl_vbase[j] = root_vpbl->pbl_vbase[i];
+ leaf_pbl = le32_to_cpu(root_vpbl->pbl_vbase[j].pa_low) +
+ (((u64)le32_to_cpu(root_vpbl->pbl_vbase[j].pa_high))
+ << 32);
+ for (k = 1; k < 16; k++) {
+ leaf_pbl += 256;
+ root_vpbl->pbl_vbase[j + k].pa_low =
+ cpu_to_le32((u32)leaf_pbl);
+ root_vpbl->pbl_vbase[j + k].pa_high =
+ cpu_to_le32((u32)((((u64)leaf_pbl) >> 32)));
+ }
+ }
+ }
+
+ return 1;
+}
+
/**
* nes_reg_mr
*/
static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
u32 stag, u64 region_length, struct nes_root_vpbl *root_vpbl,
- dma_addr_t single_buffer, u16 pbl_count, u16 residual_page_count,
- int acc, u64 *iova_start)
+ dma_addr_t single_buffer, u16 pbl_count_4k,
+ u16 residual_page_count_4k, int acc, u64 *iova_start,
+ u16 *actual_pbl_cnt, u8 *used_4k_pbls)
{
struct nes_hw_cqp_wqe *cqp_wqe;
struct nes_cqp_request *cqp_request;
unsigned long flags;
int ret;
struct nes_adapter *nesadapter = nesdev->nesadapter;
- /* int count; */
+ uint pg_cnt = 0;
+ u16 pbl_count_256;
+ u16 pbl_count = 0;
+ u8 use_256_pbls = 0;
+ u8 use_4k_pbls = 0;
+ u16 use_two_level = (pbl_count_4k > 1) ? 1 : 0;
+ struct nes_root_vpbl new_root = {0, 0, 0};
u32 opcode = 0;
u16 major_code;
@@ -1911,41 +1970,70 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
cqp_request->waiting = 1;
cqp_wqe = &cqp_request->cqp_wqe;
- spin_lock_irqsave(&nesadapter->pbl_lock, flags);
- /* track PBL resources */
- if (pbl_count != 0) {
- if (pbl_count > 1) {
- /* Two level PBL */
- if ((pbl_count+1) > nesadapter->free_4kpbl) {
- nes_debug(NES_DBG_MR, "Out of 4KB Pbls for two level request.\n");
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
- nes_free_cqp_request(nesdev, cqp_request);
- return -ENOMEM;
- } else {
- nesadapter->free_4kpbl -= pbl_count+1;
- }
- } else if (residual_page_count > 32) {
- if (pbl_count > nesadapter->free_4kpbl) {
- nes_debug(NES_DBG_MR, "Out of 4KB Pbls.\n");
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
- nes_free_cqp_request(nesdev, cqp_request);
- return -ENOMEM;
- } else {
- nesadapter->free_4kpbl -= pbl_count;
+ if (pbl_count_4k) {
+ spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+
+ pg_cnt = ((pbl_count_4k - 1) * 512) + residual_page_count_4k;
+ pbl_count_256 = (pg_cnt + 31) / 32;
+ if (pg_cnt <= 32) {
+ if (pbl_count_256 <= nesadapter->free_256pbl)
+ use_256_pbls = 1;
+ else if (pbl_count_4k <= nesadapter->free_4kpbl)
+ use_4k_pbls = 1;
+ } else if (pg_cnt <= 2048) {
+ if (((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) &&
+ (nesadapter->free_4kpbl > (nesadapter->max_4kpbl >> 1))) {
+ use_4k_pbls = 1;
+ } else if ((pbl_count_256 + 1) <= nesadapter->free_256pbl) {
+ use_256_pbls = 1;
+ use_two_level = 1;
+ } else if ((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) {
+ use_4k_pbls = 1;
}
} else {
- if (pbl_count > nesadapter->free_256pbl) {
- nes_debug(NES_DBG_MR, "Out of 256B Pbls.\n");
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
- nes_free_cqp_request(nesdev, cqp_request);
- return -ENOMEM;
- } else {
- nesadapter->free_256pbl -= pbl_count;
- }
+ if ((pbl_count_4k + 1) <= nesadapter->free_4kpbl)
+ use_4k_pbls = 1;
}
+
+ if (use_256_pbls) {
+ pbl_count = pbl_count_256;
+ nesadapter->free_256pbl -= pbl_count + use_two_level;
+ } else if (use_4k_pbls) {
+ pbl_count = pbl_count_4k;
+ nesadapter->free_4kpbl -= pbl_count + use_two_level;
+ } else {
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+ nes_debug(NES_DBG_MR, "Out of Pbls\n");
+ nes_free_cqp_request(nesdev, cqp_request);
+ return -ENOMEM;
+ }
+
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
}
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+ if (use_256_pbls && use_two_level) {
+ if (root_256(nesdev, root_vpbl, &new_root, pbl_count_4k, pbl_count_256) == 1) {
+ if (new_root.pbl_pbase != 0)
+ root_vpbl = &new_root;
+ } else {
+ spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+ nesadapter->free_256pbl += pbl_count_256 + use_two_level;
+ use_256_pbls = 0;
+
+ if (pbl_count_4k == 1)
+ use_two_level = 0;
+ pbl_count = pbl_count_4k;
+
+ if ((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) {
+ nesadapter->free_4kpbl -= pbl_count + use_two_level;
+ use_4k_pbls = 1;
+ }
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+
+ if (use_4k_pbls == 0)
+ return -ENOMEM;
+ }
+ }
opcode = NES_CQP_REGISTER_STAG | NES_CQP_STAG_RIGHTS_LOCAL_READ |
NES_CQP_STAG_VA_TO | NES_CQP_STAG_MR;
@@ -1974,10 +2062,9 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
} else {
set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PA_LOW_IDX, root_vpbl->pbl_pbase);
set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX, pbl_count);
- set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX,
- (((pbl_count - 1) * 4096) + (residual_page_count*8)));
+ set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX, (pg_cnt * 8));
- if ((pbl_count > 1) || (residual_page_count > 32))
+ if (use_4k_pbls)
cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_STAG_PBL_BLK_SIZE);
}
barrier();
@@ -1994,13 +2081,25 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
major_code = cqp_request->major_code;
nes_put_cqp_request(nesdev, cqp_request);
+ if ((!ret || major_code) && pbl_count != 0) {
+ spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+ if (use_256_pbls)
+ nesadapter->free_256pbl += pbl_count + use_two_level;
+ else if (use_4k_pbls)
+ nesadapter->free_4kpbl += pbl_count + use_two_level;
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+ }
+ if (new_root.pbl_pbase)
+ pci_free_consistent(nesdev->pcidev, 512, new_root.pbl_vbase,
+ new_root.pbl_pbase);
+
if (!ret)
return -ETIME;
else if (major_code)
return -EIO;
- else
- return 0;
+ *actual_pbl_cnt = pbl_count + use_two_level;
+ *used_4k_pbls = use_4k_pbls;
return 0;
}
@@ -2165,18 +2264,14 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
pbl_count = root_pbl_index;
}
ret = nes_reg_mr(nesdev, nespd, stag, region_length, &root_vpbl,
- buffer_list[0].addr, pbl_count, (u16)cur_pbl_index, acc, iova_start);
+ buffer_list[0].addr, pbl_count, (u16)cur_pbl_index, acc, iova_start,
+ &nesmr->pbls_used, &nesmr->pbl_4k);
if (ret == 0) {
nesmr->ibmr.rkey = stag;
nesmr->ibmr.lkey = stag;
nesmr->mode = IWNES_MEMREG_TYPE_MEM;
ibmr = &nesmr->ibmr;
- nesmr->pbl_4k = ((pbl_count > 1) || (cur_pbl_index > 32)) ? 1 : 0;
- nesmr->pbls_used = pbl_count;
- if (pbl_count > 1) {
- nesmr->pbls_used++;
- }
} else {
kfree(nesmr);
ibmr = ERR_PTR(-ENOMEM);
@@ -2454,8 +2549,9 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
stag, (unsigned int)iova_start,
(unsigned int)region_length, stag_index,
(unsigned long long)region->length, pbl_count);
- ret = nes_reg_mr( nesdev, nespd, stag, region->length, &root_vpbl,
- first_dma_addr, pbl_count, (u16)cur_pbl_index, acc, &iova_start);
+ ret = nes_reg_mr(nesdev, nespd, stag, region->length, &root_vpbl,
+ first_dma_addr, pbl_count, (u16)cur_pbl_index, acc,
+ &iova_start, &nesmr->pbls_used, &nesmr->pbl_4k);
nes_debug(NES_DBG_MR, "ret=%d\n", ret);
@@ -2464,11 +2560,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
nesmr->ibmr.lkey = stag;
nesmr->mode = IWNES_MEMREG_TYPE_MEM;
ibmr = &nesmr->ibmr;
- nesmr->pbl_4k = ((pbl_count > 1) || (cur_pbl_index > 32)) ? 1 : 0;
- nesmr->pbls_used = pbl_count;
- if (pbl_count > 1) {
- nesmr->pbls_used++;
- }
} else {
ib_umem_release(region);
kfree(nesmr);
@@ -2607,24 +2698,6 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
cqp_request->waiting = 1;
cqp_wqe = &cqp_request->cqp_wqe;
- spin_lock_irqsave(&nesadapter->pbl_lock, flags);
- if (nesmr->pbls_used != 0) {
- if (nesmr->pbl_4k) {
- nesadapter->free_4kpbl += nesmr->pbls_used;
- if (nesadapter->free_4kpbl > nesadapter->max_4kpbl) {
- printk(KERN_ERR PFX "free 4KB PBLs(%u) has exceeded the max(%u)\n",
- nesadapter->free_4kpbl, nesadapter->max_4kpbl);
- }
- } else {
- nesadapter->free_256pbl += nesmr->pbls_used;
- if (nesadapter->free_256pbl > nesadapter->max_256pbl) {
- printk(KERN_ERR PFX "free 256B PBLs(%u) has exceeded the max(%u)\n",
- nesadapter->free_256pbl, nesadapter->max_256pbl);
- }
- }
- }
-
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
NES_CQP_DEALLOCATE_STAG | NES_CQP_STAG_VA_TO |
@@ -2642,11 +2715,6 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
" CQP Major:Minor codes = 0x%04X:0x%04X\n",
ib_mr->rkey, ret, cqp_request->major_code, cqp_request->minor_code);
- nes_free_resource(nesadapter, nesadapter->allocated_mrs,
- (ib_mr->rkey & 0x0fffff00) >> 8);
-
- kfree(nesmr);
-
major_code = cqp_request->major_code;
minor_code = cqp_request->minor_code;
@@ -2662,8 +2730,33 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
" to destroy STag, ib_mr=%p, rkey = 0x%08X\n",
major_code, minor_code, ib_mr, ib_mr->rkey);
return -EIO;
- } else
- return 0;
+ }
+
+ if (nesmr->pbls_used != 0) {
+ spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+ if (nesmr->pbl_4k) {
+ nesadapter->free_4kpbl += nesmr->pbls_used;
+ if (nesadapter->free_4kpbl > nesadapter->max_4kpbl)
+ printk(KERN_ERR PFX "free 4KB PBLs(%u) has "
+ "exceeded the max(%u)\n",
+ nesadapter->free_4kpbl,
+ nesadapter->max_4kpbl);
+ } else {
+ nesadapter->free_256pbl += nesmr->pbls_used;
+ if (nesadapter->free_256pbl > nesadapter->max_256pbl)
+ printk(KERN_ERR PFX "free 256B PBLs(%u) has "
+ "exceeded the max(%u)\n",
+ nesadapter->free_256pbl,
+ nesadapter->max_256pbl);
+ }
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+ }
+ nes_free_resource(nesadapter, nesadapter->allocated_mrs,
+ (ib_mr->rkey & 0x0fffff00) >> 8);
+
+ kfree(nesmr);
+
+ return 0;
}
diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h
index 6c6b4da5184..5e48f67fbe8 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.h
+++ b/drivers/infiniband/hw/nes/nes_verbs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
@@ -134,6 +134,7 @@ struct nes_qp {
struct ietf_mpa_frame *ietf_frame;
dma_addr_t ietf_frame_pbase;
wait_queue_head_t state_waitq;
+ struct ib_mr *lsmm_mr;
unsigned long socket;
struct nes_hw_qp hwqp;
struct work_struct work;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index a1925810be3..da608273983 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -446,11 +446,11 @@ poll_more:
if (dev->features & NETIF_F_LRO)
lro_flush_all(&priv->lro.lro_mgr);
- netif_rx_complete(napi);
+ napi_complete(napi);
if (unlikely(ib_req_notify_cq(priv->recv_cq,
IB_CQ_NEXT_COMP |
IB_CQ_REPORT_MISSED_EVENTS)) &&
- netif_rx_reschedule(napi))
+ napi_reschedule(napi))
goto poll_more;
}
@@ -462,7 +462,7 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
struct net_device *dev = dev_ptr;
struct ipoib_dev_priv *priv = netdev_priv(dev);
- netif_rx_schedule(&priv->napi);
+ napi_schedule(&priv->napi);
}
static void drain_tx_cq(struct net_device *dev)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index dce0443f9d6..421a6640c9b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -106,23 +106,17 @@ int ipoib_open(struct net_device *dev)
ipoib_dbg(priv, "bringing up interface\n");
- set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
+ if (!test_and_set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+ napi_enable(&priv->napi);
if (ipoib_pkey_dev_delay_open(dev))
return 0;
- napi_enable(&priv->napi);
+ if (ipoib_ib_dev_open(dev))
+ goto err_disable;
- if (ipoib_ib_dev_open(dev)) {
- napi_disable(&priv->napi);
- return -EINVAL;
- }
-
- if (ipoib_ib_dev_up(dev)) {
- ipoib_ib_dev_stop(dev, 1);
- napi_disable(&priv->napi);
- return -EINVAL;
- }
+ if (ipoib_ib_dev_up(dev))
+ goto err_stop;
if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
struct ipoib_dev_priv *cpriv;
@@ -144,6 +138,15 @@ int ipoib_open(struct net_device *dev)
netif_start_queue(dev);
return 0;
+
+err_stop:
+ ipoib_ib_dev_stop(dev, 1);
+
+err_disable:
+ napi_disable(&priv->napi);
+ clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
+
+ return -EINVAL;
}
static int ipoib_stop(struct net_device *dev)
@@ -657,8 +660,12 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
path = __path_find(dev, phdr->hwaddr + 4);
if (!path || !path->valid) {
- if (!path)
+ int new_path = 0;
+
+ if (!path) {
path = path_rec_create(dev, phdr->hwaddr + 4);
+ new_path = 1;
+ }
if (path) {
/* put pseudoheader back on for next time */
skb_push(skb, sizeof *phdr);
@@ -666,7 +673,8 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
if (!path->query && path_rec_start(dev, path)) {
spin_unlock_irqrestore(&priv->lock, flags);
- path_free(dev, path);
+ if (new_path)
+ path_free(dev, path);
return;
} else
__path_add(dev, path);
@@ -1013,18 +1021,22 @@ static void ipoib_lro_setup(struct ipoib_dev_priv *priv)
priv->lro.lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
}
+static const struct net_device_ops ipoib_netdev_ops = {
+ .ndo_open = ipoib_open,
+ .ndo_stop = ipoib_stop,
+ .ndo_change_mtu = ipoib_change_mtu,
+ .ndo_start_xmit = ipoib_start_xmit,
+ .ndo_tx_timeout = ipoib_timeout,
+ .ndo_set_multicast_list = ipoib_set_mcast_list,
+ .ndo_neigh_setup = ipoib_neigh_setup_dev,
+};
+
static void ipoib_setup(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
- dev->open = ipoib_open;
- dev->stop = ipoib_stop;
- dev->change_mtu = ipoib_change_mtu;
- dev->hard_start_xmit = ipoib_start_xmit;
- dev->tx_timeout = ipoib_timeout;
+ dev->netdev_ops = &ipoib_netdev_ops;
dev->header_ops = &ipoib_header_ops;
- dev->set_multicast_list = ipoib_set_mcast_list;
- dev->neigh_setup = ipoib_neigh_setup_dev;
ipoib_set_ethtool_ops(dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 59d02e0b8df..425e31112ed 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -409,7 +409,7 @@ static int ipoib_mcast_join_complete(int status,
}
if (mcast->logcount++ < 20) {
- if (status == -ETIMEDOUT) {
+ if (status == -ETIMEDOUT || status == -EAGAIN) {
ipoib_dbg_mcast(priv, "multicast join failed for %pI6, status %d\n",
mcast->mcmember.mgid.raw, status);
} else {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 2cf1a408871..5a76a551035 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -61,6 +61,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
ppriv = netdev_priv(pdev);
+ rtnl_lock();
mutex_lock(&ppriv->vlan_mutex);
/*
@@ -111,7 +112,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
goto device_init_failed;
}
- result = register_netdev(priv->dev);
+ result = register_netdevice(priv->dev);
if (result) {
ipoib_warn(priv, "failed to initialize; error %i", result);
goto register_failed;
@@ -134,12 +135,13 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
list_add_tail(&priv->list, &ppriv->child_intfs);
mutex_unlock(&ppriv->vlan_mutex);
+ rtnl_unlock();
return 0;
sysfs_failed:
ipoib_delete_debug_files(priv->dev);
- unregister_netdev(priv->dev);
+ unregister_netdevice(priv->dev);
register_failed:
ipoib_dev_cleanup(priv->dev);
@@ -149,6 +151,7 @@ device_init_failed:
err:
mutex_unlock(&ppriv->vlan_mutex);
+ rtnl_unlock();
return result;
}
@@ -162,10 +165,11 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
ppriv = netdev_priv(pdev);
+ rtnl_lock();
mutex_lock(&ppriv->vlan_mutex);
list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
if (priv->pkey == pkey) {
- unregister_netdev(priv->dev);
+ unregister_netdevice(priv->dev);
ipoib_dev_cleanup(priv->dev);
list_del(&priv->list);
free_netdev(priv->dev);
@@ -175,6 +179,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
}
}
mutex_unlock(&ppriv->vlan_mutex);
+ rtnl_unlock();
return ret;
}
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 319b188145b..ea9e1556e0d 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -401,13 +401,6 @@ static void iser_route_handler(struct rdma_cm_id *cma_id)
if (ret)
goto failure;
- iser_dbg("path.mtu is %d setting it to %d\n",
- cma_id->route.path_rec->mtu, IB_MTU_1024);
-
- /* we must set the MTU to 1024 as this is what the target is assuming */
- if (cma_id->route.path_rec->mtu > IB_MTU_1024)
- cma_id->route.path_rec->mtu = IB_MTU_1024;
-
memset(&conn_param, 0, sizeof conn_param);
conn_param.responder_resources = 4;
conn_param.initiator_depth = 1;
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index ed8baa0aec3..7a7a026ba71 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -94,11 +94,8 @@ static void evdev_event(struct input_handle *handle,
static int evdev_fasync(int fd, struct file *file, int on)
{
struct evdev_client *client = file->private_data;
- int retval;
-
- retval = fasync_helper(fd, file, on, &client->fasync);
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &client->fasync);
}
static int evdev_flush(struct file *file, fl_owner_t id)
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 6f2366220a5..4224f011284 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -159,12 +159,9 @@ static void joydev_event(struct input_handle *handle,
static int joydev_fasync(int fd, struct file *file, int on)
{
- int retval;
struct joydev_client *client = file->private_data;
- retval = fasync_helper(fd, file, on, &client->fasync);
-
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &client->fasync);
}
static void joydev_free(struct device *dev)
diff --git a/drivers/input/joystick/maplecontrol.c b/drivers/input/joystick/maplecontrol.c
index e50047bfe93..77cfde571bd 100644
--- a/drivers/input/joystick/maplecontrol.c
+++ b/drivers/input/joystick/maplecontrol.c
@@ -3,7 +3,7 @@
* Based on drivers/usb/iforce.c
*
* Copyright Yaegashi Takeshi, 2001
- * Adrian McMenamin, 2008
+ * Adrian McMenamin, 2008 - 2009
*/
#include <linux/kernel.h>
@@ -29,7 +29,7 @@ static void dc_pad_callback(struct mapleq *mq)
struct maple_device *mapledev = mq->dev;
struct dc_pad *pad = maple_get_drvdata(mapledev);
struct input_dev *dev = pad->dev;
- unsigned char *res = mq->recvbuf;
+ unsigned char *res = mq->recvbuf->buf;
buttons = ~le16_to_cpup((__le16 *)(res + 8));
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index c3c8b9bc40a..45470f18d7e 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -839,7 +839,7 @@ static void atkbd_disconnect(struct serio *serio)
*/
static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
{
- const unsigned int forced_release_keys[] = {
+ static const unsigned int forced_release_keys[] = {
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
};
int i;
@@ -856,7 +856,7 @@ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
*/
static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
{
- const unsigned int forced_release_keys[] = {
+ static const unsigned int forced_release_keys[] = {
0x94,
};
int i;
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index 19284016e0f..ee855c5202e 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -209,8 +209,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
goto out;
}
- if (!pdata->debounce_time || !pdata->debounce_time > MAX_MULT ||
- !pdata->coldrive_time || !pdata->coldrive_time > MAX_MULT) {
+ if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
+ !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
printk(KERN_ERR DRV_NAME
": Invalid Debounce/Columdrive Time from pdata\n");
bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index c8ed065ea0c..abb04c82c62 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -288,7 +288,7 @@ static int corgikbd_resume(struct platform_device *dev)
#define corgikbd_resume NULL
#endif
-static int __init corgikbd_probe(struct platform_device *pdev)
+static int __devinit corgikbd_probe(struct platform_device *pdev)
{
struct corgikbd *corgikbd;
struct input_dev *input_dev;
@@ -368,7 +368,7 @@ static int __init corgikbd_probe(struct platform_device *pdev)
return err;
}
-static int corgikbd_remove(struct platform_device *pdev)
+static int __devexit corgikbd_remove(struct platform_device *pdev)
{
int i;
struct corgikbd *corgikbd = platform_get_drvdata(pdev);
@@ -388,7 +388,7 @@ static int corgikbd_remove(struct platform_device *pdev)
static struct platform_driver corgikbd_driver = {
.probe = corgikbd_probe,
- .remove = corgikbd_remove,
+ .remove = __devexit_p(corgikbd_remove),
.suspend = corgikbd_suspend,
.resume = corgikbd_resume,
.driver = {
@@ -397,7 +397,7 @@ static struct platform_driver corgikbd_driver = {
},
};
-static int __devinit corgikbd_init(void)
+static int __init corgikbd_init(void)
{
return platform_driver_register(&corgikbd_driver);
}
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c
index 22f17a593be..5aa2361aef9 100644
--- a/drivers/input/keyboard/maple_keyb.c
+++ b/drivers/input/keyboard/maple_keyb.c
@@ -1,8 +1,8 @@
/*
* SEGA Dreamcast keyboard driver
* Based on drivers/usb/usbkbd.c
- * Copyright YAEGASHI Takeshi, 2001
- * Porting to 2.6 Copyright Adrian McMenamin, 2007, 2008
+ * Copyright (c) YAEGASHI Takeshi, 2001
+ * Porting to 2.6 Copyright (c) Adrian McMenamin, 2007 - 2009
*
* 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
@@ -33,7 +33,7 @@ static DEFINE_MUTEX(maple_keyb_mutex);
#define NR_SCANCODES 256
-MODULE_AUTHOR("YAEGASHI Takeshi, Adrian McMenamin");
+MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk");
MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver");
MODULE_LICENSE("GPL");
@@ -115,7 +115,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd)
input_event(dev, EV_MSC, MSC_SCAN, code);
input_report_key(dev, keycode, 0);
} else
- printk(KERN_DEBUG "maple_keyb: "
+ dev_dbg(&dev->dev,
"Unknown key (scancode %#x) released.",
code);
}
@@ -127,7 +127,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd)
input_event(dev, EV_MSC, MSC_SCAN, code);
input_report_key(dev, keycode, 1);
} else
- printk(KERN_DEBUG "maple_keyb: "
+ dev_dbg(&dev->dev,
"Unknown key (scancode %#x) pressed.",
code);
}
@@ -140,7 +140,7 @@ static void dc_kbd_callback(struct mapleq *mq)
{
struct maple_device *mapledev = mq->dev;
struct dc_kbd *kbd = maple_get_drvdata(mapledev);
- unsigned long *buf = mq->recvbuf;
+ unsigned long *buf = (unsigned long *)(mq->recvbuf->buf);
/*
* We should always get the lock because the only
@@ -159,22 +159,27 @@ static void dc_kbd_callback(struct mapleq *mq)
static int probe_maple_kbd(struct device *dev)
{
- struct maple_device *mdev = to_maple_dev(dev);
- struct maple_driver *mdrv = to_maple_driver(dev->driver);
+ struct maple_device *mdev;
+ struct maple_driver *mdrv;
int i, error;
struct dc_kbd *kbd;
struct input_dev *idev;
- if (!(mdev->function & MAPLE_FUNC_KEYBOARD))
- return -EINVAL;
+ mdev = to_maple_dev(dev);
+ mdrv = to_maple_driver(dev->driver);
kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
- idev = input_allocate_device();
- if (!kbd || !idev) {
+ if (!kbd) {
error = -ENOMEM;
goto fail;
}
+ idev = input_allocate_device();
+ if (!idev) {
+ error = -ENOMEM;
+ goto fail_idev_alloc;
+ }
+
kbd->dev = idev;
memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode));
@@ -195,7 +200,7 @@ static int probe_maple_kbd(struct device *dev)
error = input_register_device(idev);
if (error)
- goto fail;
+ goto fail_register;
/* Maple polling is locked to VBLANK - which may be just 50/s */
maple_getcond_callback(mdev, dc_kbd_callback, HZ/50,
@@ -207,10 +212,12 @@ static int probe_maple_kbd(struct device *dev)
return error;
-fail:
+fail_register:
+ maple_set_drvdata(mdev, NULL);
input_free_device(idev);
+fail_idev_alloc:
kfree(kbd);
- maple_set_drvdata(mdev, NULL);
+fail:
return error;
}
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 3f3d1198cdb..058fa8b02c2 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -279,7 +279,7 @@ static int omap_kp_resume(struct platform_device *dev)
#define omap_kp_resume NULL
#endif
-static int __init omap_kp_probe(struct platform_device *pdev)
+static int __devinit omap_kp_probe(struct platform_device *pdev)
{
struct omap_kp *omap_kp;
struct input_dev *input_dev;
@@ -422,7 +422,7 @@ err1:
return -EINVAL;
}
-static int omap_kp_remove(struct platform_device *pdev)
+static int __devexit omap_kp_remove(struct platform_device *pdev)
{
struct omap_kp *omap_kp = platform_get_drvdata(pdev);
@@ -454,7 +454,7 @@ static int omap_kp_remove(struct platform_device *pdev)
static struct platform_driver omap_kp_driver = {
.probe = omap_kp_probe,
- .remove = omap_kp_remove,
+ .remove = __devexit_p(omap_kp_remove),
.suspend = omap_kp_suspend,
.resume = omap_kp_resume,
.driver = {
@@ -463,7 +463,7 @@ static struct platform_driver omap_kp_driver = {
},
};
-static int __devinit omap_kp_init(void)
+static int __init omap_kp_init(void)
{
printk(KERN_INFO "OMAP Keypad Driver\n");
return platform_driver_register(&omap_kp_driver);
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index 5c8a1bcf7ca..e1480fb11de 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -219,6 +219,8 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
pdata->scan_timing, priv->iomem_base + KYCR1_OFFS);
iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
+
+ device_init_wakeup(&pdev->dev, 1);
return 0;
err5:
free_irq(irq, pdev);
@@ -253,17 +255,33 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
return 0;
}
+static int sh_keysc_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
+ unsigned short value;
+
+ value = ioread16(priv->iomem_base + KYCR1_OFFS);
+
+ if (device_may_wakeup(dev))
+ value |= 0x80;
+ else
+ value &= ~0x80;
-#define sh_keysc_suspend NULL
-#define sh_keysc_resume NULL
+ iowrite16(value, priv->iomem_base + KYCR1_OFFS);
+ return 0;
+}
+
+static struct dev_pm_ops sh_keysc_dev_pm_ops = {
+ .suspend = sh_keysc_suspend,
+};
struct platform_driver sh_keysc_device_driver = {
.probe = sh_keysc_probe,
.remove = __devexit_p(sh_keysc_remove),
- .suspend = sh_keysc_suspend,
- .resume = sh_keysc_resume,
.driver = {
.name = "sh_keysc",
+ .pm = &sh_keysc_dev_pm_ops,
}
};
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index c48b76a46a5..9d1781a618e 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -343,7 +343,7 @@ static int spitzkbd_resume(struct platform_device *dev)
#define spitzkbd_resume NULL
#endif
-static int __init spitzkbd_probe(struct platform_device *dev)
+static int __devinit spitzkbd_probe(struct platform_device *dev)
{
struct spitzkbd *spitzkbd;
struct input_dev *input_dev;
@@ -444,7 +444,7 @@ static int __init spitzkbd_probe(struct platform_device *dev)
return err;
}
-static int spitzkbd_remove(struct platform_device *dev)
+static int __devexit spitzkbd_remove(struct platform_device *dev)
{
int i;
struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
@@ -470,7 +470,7 @@ static int spitzkbd_remove(struct platform_device *dev)
static struct platform_driver spitzkbd_driver = {
.probe = spitzkbd_probe,
- .remove = spitzkbd_remove,
+ .remove = __devexit_p(spitzkbd_remove),
.suspend = spitzkbd_suspend,
.resume = spitzkbd_resume,
.driver = {
@@ -479,7 +479,7 @@ static struct platform_driver spitzkbd_driver = {
},
};
-static int __devinit spitzkbd_init(void)
+static int __init spitzkbd_init(void)
{
return platform_driver_register(&spitzkbd_driver);
}
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 093c8c1bca7..9705f3a00a3 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS
config MOUSE_PS2_LIFEBOOK
bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED
default y
- depends on MOUSE_PS2
+ depends on MOUSE_PS2 && X86
help
Say Y here if you have a Fujitsu B-series Lifebook PS/2
TouchScreen connected to your system.
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index b9a25d57bc5..6ab0eb1ada1 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -542,7 +542,7 @@ int elantech_detect(struct psmouse *psmouse, int set_properties)
ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
- pr_err("elantech.c: sending Elantech magic knock failed.\n");
+ pr_debug("elantech.c: sending Elantech magic knock failed.\n");
return -1;
}
@@ -551,8 +551,27 @@ int elantech_detect(struct psmouse *psmouse, int set_properties)
* set of magic numbers
*/
if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
- pr_info("elantech.c: unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
- param[0], param[1], param[2]);
+ pr_debug("elantech.c: "
+ "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
+ param[0], param[1], param[2]);
+ return -1;
+ }
+
+ /*
+ * Query touchpad's firmware version and see if it reports known
+ * value to avoid mis-detection. Logitech mice are known to respond
+ * to Elantech magic knock and there might be more.
+ */
+ if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
+ pr_debug("elantech.c: failed to query firmware version.\n");
+ return -1;
+ }
+
+ pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n",
+ param[0], param[1], param[2]);
+
+ if (param[0] == 0 || param[1] != 0) {
+ pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
return -1;
}
@@ -600,8 +619,7 @@ int elantech_init(struct psmouse *psmouse)
int i, error;
unsigned char param[3];
- etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL);
- psmouse->private = etd;
+ psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL);
if (!etd)
return -1;
@@ -610,14 +628,12 @@ int elantech_init(struct psmouse *psmouse)
etd->parity[i] = etd->parity[i & (i - 1)] ^ 1;
/*
- * Find out what version hardware this is
+ * Do the version query again so we can store the result
*/
if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
pr_err("elantech.c: failed to query firmware version.\n");
goto init_fail;
}
- pr_info("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n",
- param[0], param[1], param[2]);
etd->fw_version_maj = param[0];
etd->fw_version_min = param[2];
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c
index d297accf9a7..1e827ad0afb 100644
--- a/drivers/input/mouse/pxa930_trkball.c
+++ b/drivers/input/mouse/pxa930_trkball.c
@@ -83,7 +83,7 @@ static int write_tbcr(struct pxa930_trkball *trkball, int v)
__raw_writel(v, trkball->mmio_base + TBCR);
- while (i--) {
+ while (--i) {
if (__raw_readl(trkball->mmio_base + TBCR) == v)
break;
msleep(1);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 865fc69e9bc..f3e4f7b0240 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -182,11 +182,6 @@ static int synaptics_identify(struct psmouse *psmouse)
static int synaptics_query_hardware(struct psmouse *psmouse)
{
- int retries = 0;
-
- while ((retries++ < 3) && psmouse_reset(psmouse))
- /* empty */;
-
if (synaptics_identify(psmouse))
return -1;
if (synaptics_model_id(psmouse))
@@ -582,6 +577,8 @@ static int synaptics_reconnect(struct psmouse *psmouse)
struct synaptics_data *priv = psmouse->private;
struct synaptics_data old_priv = *priv;
+ psmouse_reset(psmouse);
+
if (synaptics_detect(psmouse, 0))
return -1;
@@ -640,6 +637,8 @@ int synaptics_init(struct psmouse *psmouse)
if (!priv)
return -1;
+ psmouse_reset(psmouse);
+
if (synaptics_query_hardware(psmouse)) {
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
goto init_fail;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index ef99a7e6d40..17fd6d46d08 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -403,12 +403,9 @@ static void mousedev_event(struct input_handle *handle,
static int mousedev_fasync(int fd, struct file *file, int on)
{
- int retval;
struct mousedev_client *client = file->private_data;
- retval = fasync_helper(fd, file, on, &client->fasync);
-
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &client->fasync);
}
static void mousedev_free(struct device *dev)
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index b10ffae7c39..e29cdc13a19 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -57,7 +57,7 @@ static int amba_kmi_write(struct serio *io, unsigned char val)
struct amba_kmi_port *kmi = io->port_data;
unsigned int timeleft = 10000; /* timeout in 100ms */
- while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--)
+ while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && --timeleft)
udelay(10);
if (timeleft)
@@ -129,8 +129,8 @@ static int amba_kmi_probe(struct amba_device *dev, void *id)
io->write = amba_kmi_write;
io->open = amba_kmi_open;
io->close = amba_kmi_close;
- strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
- strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
+ strlcpy(io->name, dev_name(&dev->dev), sizeof(io->name));
+ strlcpy(io->phys, dev_name(&dev->dev), sizeof(io->phys));
io->port_data = kmi;
io->dev.parent = &dev->dev;
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index adc3bd6e7f7..bd0f92d9f40 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -359,7 +359,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
- strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+ strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
serio->id.type = SERIO_8042;
serio->write = gscps2_write;
serio->open = gscps2_open;
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 2ad88780a17..57953c0eb82 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -246,8 +246,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev)
serio->write = ps2_write;
serio->open = ps2_open;
serio->close = ps2_close;
- strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
- strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+ strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name));
+ strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
serio->port_data = ps2if;
serio->dev.parent = &dev->dev;
ps2if->io = serio;
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 06bbd0e74c6..b03009bb746 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -58,10 +58,8 @@ static unsigned int serio_raw_no;
static int serio_raw_fasync(int fd, struct file *file, int on)
{
struct serio_raw_list *list = file->private_data;
- int retval;
- retval = fasync_helper(fd, file, on, &list->fasync);
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &list->fasync);
}
static struct serio_raw *serio_raw_locate(int minor)
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index a89a6a8f05e..055969e8be1 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -236,7 +236,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
ts_dev->bufferedmeasure = 0;
snprintf(ts_dev->phys, sizeof(ts_dev->phys),
- "%s/input0", pdev->dev.bus_id);
+ "%s/input0", dev_name(&pdev->dev));
input_dev->name = "atmel touch screen controller";
input_dev->phys = ts_dev->phys;
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 65202c9f63f..3fb51b54fe6 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -268,7 +268,7 @@ static int corgits_resume(struct platform_device *dev)
#define corgits_resume NULL
#endif
-static int __init corgits_probe(struct platform_device *pdev)
+static int __devinit corgits_probe(struct platform_device *pdev)
{
struct corgi_ts *corgi_ts;
struct input_dev *input_dev;
@@ -343,7 +343,7 @@ static int __init corgits_probe(struct platform_device *pdev)
return err;
}
-static int corgits_remove(struct platform_device *pdev)
+static int __devexit corgits_remove(struct platform_device *pdev)
{
struct corgi_ts *corgi_ts = platform_get_drvdata(pdev);
@@ -352,12 +352,13 @@ static int corgits_remove(struct platform_device *pdev)
corgi_ts->machinfo->put_hsync();
input_unregister_device(corgi_ts->input);
kfree(corgi_ts);
+
return 0;
}
static struct platform_driver corgits_driver = {
.probe = corgits_probe,
- .remove = corgits_remove,
+ .remove = __devexit_p(corgits_remove),
.suspend = corgits_suspend,
.resume = corgits_resume,
.driver = {
@@ -366,7 +367,7 @@ static struct platform_driver corgits_driver = {
},
};
-static int __devinit corgits_init(void)
+static int __init corgits_init(void)
{
return platform_driver_register(&corgits_driver);
}
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index b75dc299057..4ab07024689 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -289,7 +289,8 @@ static int tsc2007_probe(struct i2c_client *client,
pdata->init_platform_hw();
- snprintf(ts->phys, sizeof(ts->phys), "%s/input0", client->dev.bus_id);
+ snprintf(ts->phys, sizeof(ts->phys),
+ "%s/input0", dev_name(&client->dev));
input_dev->name = "TSC2007 Touchscreen";
input_dev->phys = ts->phys;
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 5080b26ba16..fb7cb9bdfbd 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -60,6 +60,10 @@ static int swap_xy;
module_param(swap_xy, bool, 0644);
MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
+static int hwcalib_xy;
+module_param(hwcalib_xy, bool, 0644);
+MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available");
+
/* device specifc data/functions */
struct usbtouch_usb;
struct usbtouch_device_info {
@@ -118,6 +122,7 @@ enum {
#define USB_DEVICE_HID_CLASS(vend, prod) \
.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \
+ | USB_DEVICE_ID_MATCH_INT_PROTOCOL \
| USB_DEVICE_ID_MATCH_DEVICE, \
.idVendor = (vend), \
.idProduct = (prod), \
@@ -260,8 +265,13 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
{
- dev->x = (pkt[8] << 8) | pkt[7];
- dev->y = (pkt[10] << 8) | pkt[9];
+ if (hwcalib_xy) {
+ dev->x = (pkt[4] << 8) | pkt[3];
+ dev->y = 0xffff - ((pkt[6] << 8) | pkt[5]);
+ } else {
+ dev->x = (pkt[8] << 8) | pkt[7];
+ dev->y = (pkt[10] << 8) | pkt[9];
+ }
dev->touch = (pkt[2] & 0x40) ? 1 : 0;
return 1;
@@ -294,6 +304,12 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
return ret;
}
+ /* Default min/max xy are the raw values, override if using hw-calib */
+ if (hwcalib_xy) {
+ input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0);
+ input_set_abs_params(usbtouch->input, ABS_Y, 0, 0xffff, 0, 0);
+ }
+
return 0;
}
#endif
diff --git a/drivers/isdn/act2000/act2000_isa.c b/drivers/isdn/act2000/act2000_isa.c
index 1bd8960ead3..fea5b783335 100644
--- a/drivers/isdn/act2000/act2000_isa.c
+++ b/drivers/isdn/act2000/act2000_isa.c
@@ -257,9 +257,9 @@ act2000_isa_receive(act2000_card *card)
printk(KERN_WARNING
"act2000_isa_receive: Invalid CAPI msg\n");
{
- int i; __u8 *p; __u8 *c; __u8 tmp[30];
- for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, c = tmp; i < 8; i++)
- c += sprintf(c, "%02x ", *(p++));
+ int i; __u8 *p; __u8 *t; __u8 tmp[30];
+ for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, t = tmp; i < 8; i++)
+ t += sprintf(t, "%02x ", *(p++));
printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp);
}
}
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 1b5bf87c4cf..3e468d2cf73 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -277,7 +277,7 @@ static void capiminor_free(struct capiminor *mp)
list_del(&mp->list);
write_unlock_irqrestore(&capiminor_list_lock, flags);
- if (mp->ttyskb) kfree_skb(mp->ttyskb);
+ kfree_skb(mp->ttyskb);
mp->ttyskb = NULL;
skb_queue_purge(&mp->inqueue);
skb_queue_purge(&mp->outqueue);
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
index c29208bd752..50ed778f63f 100644
--- a/drivers/isdn/capi/kcapi_proc.c
+++ b/drivers/isdn/capi/kcapi_proc.c
@@ -239,6 +239,7 @@ static const struct file_operations proc_applstats_ops = {
// ---------------------------------------------------------------------------
static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
+ __acquires(&capi_drivers_list_lock)
{
read_lock(&capi_drivers_list_lock);
return seq_list_start(&capi_drivers, *pos);
@@ -250,6 +251,7 @@ static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void capi_driver_stop(struct seq_file *seq, void *v)
+ __releases(&capi_drivers_list_lock)
{
read_unlock(&capi_drivers_list_lock);
}
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index 0017e50c694..9ca889adf12 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -1,5 +1,5 @@
menuconfig ISDN_DRV_GIGASET
- tristate "Siemens Gigaset support (isdn)"
+ tristate "Siemens Gigaset support"
select CRC_CCITT
select BITREVERSE
help
@@ -11,11 +11,11 @@ menuconfig ISDN_DRV_GIGASET
one of the connection specific parts that follow.
This will build a module called "gigaset".
-if ISDN_DRV_GIGASET!=n
+if ISDN_DRV_GIGASET
config GIGASET_BASE
tristate "Gigaset base station support"
- depends on ISDN_DRV_GIGASET && USB
+ depends on USB
help
Say M here if you want to use the USB interface of the Gigaset
base for connection to your system.
@@ -23,7 +23,7 @@ config GIGASET_BASE
config GIGASET_M105
tristate "Gigaset M105 support"
- depends on ISDN_DRV_GIGASET && USB
+ depends on USB
help
Say M here if you want to connect to the Gigaset base via DECT
using a Gigaset M105 (Sinus 45 Data 2) USB DECT device.
@@ -31,7 +31,6 @@ config GIGASET_M105
config GIGASET_M101
tristate "Gigaset M101 support"
- depends on ISDN_DRV_GIGASET
help
Say M here if you want to connect to the Gigaset base via DECT
using a Gigaset M101 (Sinus 45 Data 1) RS232 DECT device.
@@ -48,7 +47,6 @@ config GIGASET_UNDOCREQ
help
This enables support for USB requests we only know from
reverse engineering (currently M105 only). If you need
- features like configuration mode of M105, say yes. If you
- care about your device, say no.
+ features like configuration mode of M105, say yes.
-endif # ISDN_DRV_GIGASET != n
+endif # ISDN_DRV_GIGASET
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 18dd8aacbe8..831ddce1467 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -46,6 +46,9 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
#define IF_WRITEBUF 264
+/* interrupt pipe message size according to ibid. ch. 2.2 */
+#define IP_MSGSIZE 3
+
/* Values for the Gigaset 307x */
#define USB_GIGA_VENDOR_ID 0x0681
#define USB_3070_PRODUCT_ID 0x0001
@@ -110,7 +113,7 @@ struct bas_cardstate {
unsigned char *rcvbuf; /* AT reply receive buffer */
struct urb *urb_int_in; /* URB for interrupt pipe */
- unsigned char int_in_buf[3];
+ unsigned char *int_in_buf;
spinlock_t lock; /* locks all following */
int basstate; /* bitmap (BS_*) */
@@ -657,7 +660,7 @@ static void read_int_callback(struct urb *urb)
}
/* drop incomplete packets even if the missing bytes wouldn't matter */
- if (unlikely(urb->actual_length < 3)) {
+ if (unlikely(urb->actual_length < IP_MSGSIZE)) {
dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n",
urb->actual_length);
goto resubmit;
@@ -2127,6 +2130,7 @@ static void gigaset_reinitbcshw(struct bc_state *bcs)
static void gigaset_freecshw(struct cardstate *cs)
{
/* timers, URBs and rcvbuf are disposed of in disconnect */
+ kfree(cs->hw.bas->int_in_buf);
kfree(cs->hw.bas);
cs->hw.bas = NULL;
}
@@ -2140,6 +2144,12 @@ static int gigaset_initcshw(struct cardstate *cs)
pr_err("out of memory\n");
return 0;
}
+ ucs->int_in_buf = kmalloc(IP_MSGSIZE, GFP_KERNEL);
+ if (!ucs->int_in_buf) {
+ kfree(ucs);
+ pr_err("out of memory\n");
+ return 0;
+ }
ucs->urb_cmd_in = NULL;
ucs->urb_cmd_out = NULL;
@@ -2292,7 +2302,7 @@ static int gigaset_probe(struct usb_interface *interface,
usb_fill_int_urb(ucs->urb_int_in, udev,
usb_rcvintpipe(udev,
(endpoint->bEndpointAddress) & 0x0f),
- ucs->int_in_buf, 3, read_int_callback, cs,
+ ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs,
endpoint->bInterval);
if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) {
dev_err(cs->dev, "could not submit interrupt URB: %s\n",
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index ac245e7e96a..3071a52467e 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -389,8 +389,7 @@ static void gigaset_freecshw(struct cardstate *cs)
static void gigaset_device_release(struct device *dev)
{
- struct platform_device *pdev =
- container_of(dev, struct platform_device, dev);
+ struct platform_device *pdev = to_platform_device(dev);
/* adapted from platform_device_release() in drivers/base/platform.c */
//FIXME is this actually necessary?
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index fba61f67052..d7838516609 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -278,17 +278,17 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
unsigned new_state)
{
- return -EINVAL;
+ return -ENOTTY;
}
static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
{
- return -EINVAL;
+ return -ENOTTY;
}
static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
{
- return -EINVAL;
+ return -ENOTTY;
}
#endif
@@ -577,7 +577,7 @@ static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
0, 0, &buf, 6, 2000);
#else
- return -EINVAL;
+ return -ENOTTY;
#endif
}
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
index 84318ec8d13..33ce89eed65 100644
--- a/drivers/isdn/hardware/eicon/debug.c
+++ b/drivers/isdn/hardware/eicon/debug.c
@@ -1198,7 +1198,7 @@ int SuperTraceASSIGN (void* AdapterHandle, byte* data) {
pC->xbuffer[5] = (byte)(rx_dma_magic >> 8);
pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
- pC->xbuffer[8] = (byte)DIVA_MAX_MANAGEMENT_TRANSFER_SIZE;
+ pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);
pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
pC->xbuffer[10] = 0;
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 4cc94f200b7..31f91c18c69 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -1194,7 +1194,8 @@ static char hex_digit_table[0x10] =
/* translation function for each message */
/*------------------------------------------------------------------*/
-byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ch;
word i;
@@ -1411,7 +1412,8 @@ byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return 2;
}
-byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word i, Info;
word Reject;
@@ -1567,13 +1569,15 @@ byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return 1;
}
-byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
dbug(1,dprintf("connect_a_res"));
return false;
}
-byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word Info;
word i;
@@ -1628,7 +1632,8 @@ byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
return false;
}
-byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
dbug(1,dprintf("disconnect_res"));
if(plci)
@@ -1655,7 +1660,8 @@ byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
return 0;
}
-byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word Info;
byte i;
@@ -1704,7 +1710,8 @@ byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, A
return false;
}
-byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word i;
API_PARSE * ai;
@@ -1813,13 +1820,15 @@ byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APP
return false;
}
-byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
dbug(1,dprintf("info_res"));
return false;
}
-byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word Info;
byte ret;
@@ -1849,7 +1858,8 @@ byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, AP
return ret;
}
-byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word Info = 0;
word i = 0;
@@ -2599,13 +2609,15 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
dbug(1,dprintf("facility_res"));
return false;
}
-byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word Info = 0;
byte req;
@@ -2839,7 +2851,8 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
return false;
}
-byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
API_PARSE * ncpi;
@@ -2954,7 +2967,8 @@ byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
return false;
}
-byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
@@ -2974,7 +2988,8 @@ byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
return false;
}
-byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word Info;
word ncci;
@@ -3030,7 +3045,8 @@ byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
return false;
}
-byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
word i;
@@ -3086,7 +3102,8 @@ byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
return false;
}
-byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
NCCI *ncci_ptr;
DATA_B3_DESC *data;
@@ -3163,7 +3180,8 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word n;
word ncci;
@@ -3196,7 +3214,8 @@ byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word Info;
word ncci;
@@ -3237,7 +3256,8 @@ byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
@@ -3261,7 +3281,8 @@ byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
API_PARSE * ncpi;
@@ -3295,7 +3316,8 @@ byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI
}
-byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word Info=0;
word i;
@@ -8689,7 +8711,7 @@ static word add_modem_b23 (PLCI * plci, API_PARSE* bp_parms)
/* send a request for the signaling entity */
/*------------------------------------------------------------------*/
-void sig_req(PLCI * plci, byte req, byte Id)
+static void sig_req(PLCI *plci, byte req, byte Id)
{
if(!plci) return;
if(plci->adapter->adapter_disabled) return;
@@ -8789,7 +8811,7 @@ static void send_req(PLCI *plci)
dbug(1,dprintf("send_ok"));
}
-void send_data(PLCI * plci)
+static void send_data(PLCI *plci)
{
DIVA_CAPI_ADAPTER * a;
DATA_B3_DESC * data;
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 595ba8eb4a0..0b28141e43b 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -4599,6 +4599,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
printk(KERN_ERR "%s: no memory for coeffs\n",
__func__);
ret = -ENOMEM;
+ kfree(bch);
goto free_chan;
}
bch->nr = ch;
@@ -4767,6 +4768,7 @@ init_multi_port(struct hfc_multi *hc, int pt)
printk(KERN_ERR "%s: no memory for coeffs\n",
__func__);
ret = -ENOMEM;
+ kfree(bch);
goto free_chan;
}
bch->nr = ch + 1;
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index f0e14dfcf71..641a9cd1a53 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -56,8 +56,8 @@ static const char *hfcpci_revision = "2.0";
static int HFC_cnt;
static uint debug;
static uint poll, tics;
-struct timer_list hfc_tl;
-u32 hfc_jiffies;
+static struct timer_list hfc_tl;
+static unsigned long hfc_jiffies;
MODULE_AUTHOR("Karsten Keil");
MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index ba6925fbf38..9c427fb204e 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -35,7 +35,7 @@
#include <linux/mISDNhw.h>
#include "hfcsusb.h"
-const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
+static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
static unsigned int debug;
static int poll = DEFAULT_TRANSP_BURST_SZ;
@@ -974,7 +974,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
spin_unlock(&hw->lock);
}
-void
+static void
fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
void *buf, int num_packets, int packet_size, int interval,
usb_complete_t complete, void *context)
@@ -1720,7 +1720,7 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
/* Hardware Initialization */
-int
+static int
setup_hfcsusb(struct hfcsusb *hw)
{
int err;
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h
index 098486b8e8d..43efe7358fa 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.h
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.h
@@ -198,7 +198,7 @@ validconf[][19] = {
};
/* string description of chosen config */
-char *conf_str[] = {
+static char *conf_str[] = {
"4 Interrupt IN + 3 Isochron OUT",
"3 Interrupt IN + 3 Isochron OUT",
"4 Isochron IN + 3 Isochron OUT",
@@ -316,7 +316,7 @@ struct hfcsusb_vdata {
#define HFC_MAX_TE_LAYER1_STATE 8
#define HFC_MAX_NT_LAYER1_STATE 4
-const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
+static const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
"TE F0 - Reset",
"TE F1 - Reset",
"TE F2 - Sensing",
@@ -328,7 +328,7 @@ const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
"TE F8 - Lost framing",
};
-const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
+static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
"NT G0 - Reset",
"NT G1 - Deactive",
"NT G2 - Pending activation",
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index 7c56c44f0fd..025a20d487c 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -24,7 +24,6 @@
const char *lli_revision = "$Revision: 2.59.2.4 $";
extern struct IsdnCard cards[];
-extern int nrcards;
static int init_b_st(struct Channel *chanp, int incoming);
static void release_b_st(struct Channel *chanp);
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index ded9d0baf60..4fab18d4d02 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -361,12 +361,6 @@ module_param_array(io1, int, NULL, 0);
int nrcards;
-extern const char *l1_revision;
-extern const char *l2_revision;
-extern const char *l3_revision;
-extern const char *lli_revision;
-extern const char *tei_revision;
-
char *HiSax_getrev(const char *revision)
{
char *rev;
diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c
index cf082665cc8..20d7688b397 100644
--- a/drivers/isdn/hisax/hfcscard.c
+++ b/drivers/isdn/hisax/hfcscard.c
@@ -16,8 +16,6 @@
#include "hfc_2bds0.h"
#include "isdnl1.h"
-extern const char *CardType[];
-
static const char *hfcs_revision = "$Revision: 1.10.2.4 $";
static irqreturn_t
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index e8d429fda84..f8527046f19 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -121,6 +121,15 @@
#ifdef __KERNEL__
+extern const char *CardType[];
+extern int nrcards;
+
+extern const char *l1_revision;
+extern const char *l2_revision;
+extern const char *l3_revision;
+extern const char *lli_revision;
+extern const char *tei_revision;
+
/* include l3dss1 & ni1 specific process structures, but no other defines */
#ifdef CONFIG_HISAX_EURO
#define l3dss1_process
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index a14204ec88e..317f16f516f 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -18,12 +18,12 @@
*
*/
-const char *l1_revision = "$Revision: 2.46.2.5 $";
-
#include <linux/init.h>
#include "hisax.h"
#include "isdnl1.h"
+const char *l1_revision = "$Revision: 2.46.2.5 $";
+
#define TIMER3_VALUE 7000
static struct Fsm l1fsm_b;
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
index a10dfa82c73..5569a522e2a 100644
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -48,8 +48,6 @@
#include <linux/pci.h>
#include <linux/isapnp.h>
-extern const char *CardType[];
-
static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
static const char *Sedlbauer_Types[] =
diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c
index 48581335f43..3ca0bed1b88 100644
--- a/drivers/isdn/hisax/teles0.c
+++ b/drivers/isdn/hisax/teles0.c
@@ -21,8 +21,6 @@
#include "isac.h"
#include "hscx.h"
-extern const char *CardType[];
-
static const char *teles0_revision = "$Revision: 2.15.2.4 $";
#define TELES_IOMEM_SIZE 0x400
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c
index 5dc9f1a4362..e9f5bb4cdff 100644
--- a/drivers/isdn/hisax/teles3.c
+++ b/drivers/isdn/hisax/teles3.c
@@ -20,7 +20,6 @@
#include "hscx.h"
#include "isdnl1.h"
-extern const char *CardType[];
static const char *teles3_revision = "$Revision: 2.19.2.4 $";
#define byteout(addr,val) outb(val,addr)
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index a3551dd0324..aa30b5cb351 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -431,6 +431,7 @@ set_arg(void __user *b, void *val,int len)
return 0;
}
+#ifdef CONFIG_IPPP_FILTER
static int get_filter(void __user *arg, struct sock_filter **p)
{
struct sock_fprog uprog;
@@ -465,6 +466,7 @@ static int get_filter(void __user *arg, struct sock_filter **p)
*p = code;
return uprog.len;
}
+#endif /* CONFIG_IPPP_FILTER */
/*
* ippp device ioctl
diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c
index 44d9c3d5d33..f1bbc88763b 100644
--- a/drivers/isdn/mISDN/clock.c
+++ b/drivers/isdn/mISDN/clock.c
@@ -41,11 +41,11 @@
static u_int *debug;
static LIST_HEAD(iclock_list);
-DEFINE_RWLOCK(iclock_lock);
-u16 iclock_count; /* counter of last clock */
-struct timeval iclock_tv; /* time stamp of last clock */
-int iclock_tv_valid; /* already received one timestamp */
-struct mISDNclock *iclock_current;
+static DEFINE_RWLOCK(iclock_lock);
+static u16 iclock_count; /* counter of last clock */
+static struct timeval iclock_tv; /* time stamp of last clock */
+static int iclock_tv_valid; /* already received one timestamp */
+static struct mISDNclock *iclock_current;
void
mISDN_init_clock(u_int *dp)
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
index f2b32186d4a..bbd99d3282c 100644
--- a/drivers/isdn/mISDN/timerdev.c
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -152,8 +152,7 @@ dev_expire_timer(unsigned long data)
u_long flags;
spin_lock_irqsave(&timer->dev->lock, flags);
- list_del(&timer->list);
- list_add_tail(&timer->list, &timer->dev->expired);
+ list_move_tail(&timer->list, &timer->dev->expired);
spin_unlock_irqrestore(&timer->dev->lock, flags);
wake_up_interruptible(&timer->dev->wait);
}
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
index 5ba2a879df1..e075e8d2fce 100644
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -347,8 +347,7 @@ pcbit_receive(struct pcbit_dev *dev)
if (dev->read_frame) {
printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
/* discard previous queued frame */
- if (dev->read_frame->skb)
- kfree_skb(dev->read_frame->skb);
+ kfree_skb(dev->read_frame->skb);
kfree(dev->read_frame);
dev->read_frame = NULL;
}
@@ -601,8 +600,7 @@ pcbit_l2_err_recover(unsigned long data)
dev->w_busy = dev->r_busy = 1;
if (dev->read_frame) {
- if (dev->read_frame->skb)
- kfree_skb(dev->read_frame->skb);
+ kfree_skb(dev->read_frame->skb);
kfree(dev->read_frame);
dev->read_frame = NULL;
}
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c
index 712220cef13..7f16d75d2d8 100644
--- a/drivers/isdn/sc/shmem.c
+++ b/drivers/isdn/sc/shmem.c
@@ -54,7 +54,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
- pr_debug("%s: copying %d bytes from %#lx to %#lx\n",
+ pr_debug("%s: copying %zu bytes from %#lx to %#lx\n",
sc_adapter[card]->devicename, n,
(unsigned long) src,
sc_adapter[card]->rambase + ((unsigned long) dest %0x4000));
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 742713611bc..556aeca0d86 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -223,4 +223,7 @@ config LEDS_TRIGGER_DEFAULT_ON
This allows LEDs to be initialised in the ON state.
If unsure, say Y.
+comment "iptables trigger is under Netfilter config (LED target)"
+ depends on LEDS_TRIGGERS
+
endif # NEW_LEDS
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 90663e01a56..60156dfdc60 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -224,7 +224,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
break;
/* If the Guest asked to be stopped, we sleep. The Guest's
- * clock timer or LHCALL_BREAK from the Waker will wake us. */
+ * clock timer or LHREQ_BREAK from the Waker will wake us. */
if (cpu->halted) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index b4d44e571d7..8132533d71f 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -212,6 +212,9 @@ static void lg_notify(struct virtqueue *vq)
hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0);
}
+/* An extern declaration inside a C file is bad form. Don't do it. */
+extern void lguest_setup_irq(unsigned int irq);
+
/* This routine finds the first virtqueue described in the configuration of
* this device and sets it up.
*
@@ -266,6 +269,9 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
goto unmap;
}
+ /* Make sure the interrupt is allocated. */
+ lguest_setup_irq(lvq->config.irq);
+
/* Tell the interrupt for this virtqueue to go to the virtio_ring
* interrupt handler. */
/* FIXME: We used to have a flag for the Host to tell us we could use
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 34bc017b8b3..b8ee103eed5 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -307,9 +307,8 @@ static int close(struct inode *inode, struct file *file)
* kmalloc()ed string, either of which is ok to hand to kfree(). */
if (!IS_ERR(lg->dead))
kfree(lg->dead);
- /* We clear the entire structure, which also marks it as free for the
- * next user. */
- memset(lg, 0, sizeof(*lg));
+ /* Free the memory allocated to the lguest_struct */
+ kfree(lg);
/* Release lock and exit. */
mutex_unlock(&lguest_lock);
diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
index ef2dbfe7471..ada5ebbaa25 100644
--- a/drivers/mca/mca-bus.c
+++ b/drivers/mca/mca-bus.c
@@ -110,7 +110,7 @@ int __init mca_register_device(int bus, struct mca_device *mca_dev)
mca_dev->dev.parent = &mca_bus->dev;
mca_dev->dev.bus = &mca_bus_type;
- sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot);
+ dev_set_name(&mca_dev->dev, "%02d:%02X", bus, mca_dev->slot);
mca_dev->dma_mask = mca_bus->default_dma_mask;
mca_dev->dev.dma_mask = &mca_dev->dma_mask;
mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask;
@@ -151,7 +151,7 @@ struct mca_bus * __devinit mca_attach_bus(int bus)
if (!mca_bus)
return NULL;
- sprintf(mca_bus->dev.bus_id,"mca%d",bus);
+ dev_set_name(&mca_bus->dev, "mca%d", bus);
sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary");
if (device_register(&mca_bus->dev)) {
kfree(mca_bus);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 35bda49796f..bfefd079a95 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -60,6 +60,7 @@ struct dm_crypt_io {
};
struct dm_crypt_request {
+ struct convert_context *ctx;
struct scatterlist sg_in;
struct scatterlist sg_out;
};
@@ -335,6 +336,18 @@ static void crypt_convert_init(struct crypt_config *cc,
init_completion(&ctx->restart);
}
+static struct dm_crypt_request *dmreq_of_req(struct crypt_config *cc,
+ struct ablkcipher_request *req)
+{
+ return (struct dm_crypt_request *)((char *)req + cc->dmreq_start);
+}
+
+static struct ablkcipher_request *req_of_dmreq(struct crypt_config *cc,
+ struct dm_crypt_request *dmreq)
+{
+ return (struct ablkcipher_request *)((char *)dmreq - cc->dmreq_start);
+}
+
static int crypt_convert_block(struct crypt_config *cc,
struct convert_context *ctx,
struct ablkcipher_request *req)
@@ -345,10 +358,11 @@ static int crypt_convert_block(struct crypt_config *cc,
u8 *iv;
int r = 0;
- dmreq = (struct dm_crypt_request *)((char *)req + cc->dmreq_start);
+ dmreq = dmreq_of_req(cc, req);
iv = (u8 *)ALIGN((unsigned long)(dmreq + 1),
crypto_ablkcipher_alignmask(cc->tfm) + 1);
+ dmreq->ctx = ctx;
sg_init_table(&dmreq->sg_in, 1);
sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT,
bv_in->bv_offset + ctx->offset_in);
@@ -395,8 +409,9 @@ static void crypt_alloc_req(struct crypt_config *cc,
cc->req = mempool_alloc(cc->req_pool, GFP_NOIO);
ablkcipher_request_set_tfm(cc->req, cc->tfm);
ablkcipher_request_set_callback(cc->req, CRYPTO_TFM_REQ_MAY_BACKLOG |
- CRYPTO_TFM_REQ_MAY_SLEEP,
- kcryptd_async_done, ctx);
+ CRYPTO_TFM_REQ_MAY_SLEEP,
+ kcryptd_async_done,
+ dmreq_of_req(cc, cc->req));
}
/*
@@ -553,19 +568,22 @@ static void crypt_inc_pending(struct dm_crypt_io *io)
static void crypt_dec_pending(struct dm_crypt_io *io)
{
struct crypt_config *cc = io->target->private;
+ struct bio *base_bio = io->base_bio;
+ struct dm_crypt_io *base_io = io->base_io;
+ int error = io->error;
if (!atomic_dec_and_test(&io->pending))
return;
- if (likely(!io->base_io))
- bio_endio(io->base_bio, io->error);
+ mempool_free(io, cc->io_pool);
+
+ if (likely(!base_io))
+ bio_endio(base_bio, error);
else {
- if (io->error && !io->base_io->error)
- io->base_io->error = io->error;
- crypt_dec_pending(io->base_io);
+ if (error && !base_io->error)
+ base_io->error = error;
+ crypt_dec_pending(base_io);
}
-
- mempool_free(io, cc->io_pool);
}
/*
@@ -821,7 +839,8 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
static void kcryptd_async_done(struct crypto_async_request *async_req,
int error)
{
- struct convert_context *ctx = async_req->data;
+ struct dm_crypt_request *dmreq = async_req->data;
+ struct convert_context *ctx = dmreq->ctx;
struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx);
struct crypt_config *cc = io->target->private;
@@ -830,7 +849,7 @@ static void kcryptd_async_done(struct crypto_async_request *async_req,
return;
}
- mempool_free(ablkcipher_request_cast(async_req), cc->req_pool);
+ mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool);
if (!atomic_dec_and_test(&ctx->pending))
return;
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index a34338567a2..36e2b5e46a6 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -292,6 +292,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
(PAGE_SIZE >> SECTOR_SHIFT));
num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev),
num_bvecs);
+ if (unlikely(num_bvecs > BIO_MAX_PAGES))
+ num_bvecs = BIO_MAX_PAGES;
bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
bio->bi_sector = where->sector + (where->count - remaining);
bio->bi_bdev = where->bdev;
@@ -328,7 +330,7 @@ static void dispatch_io(int rw, unsigned int num_regions,
struct dpages old_pages = *dp;
if (sync)
- rw |= (1 << BIO_RW_SYNC);
+ rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
/*
* For multiple regions we need to be careful to rewind
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 54d0588fc1f..f01096549a9 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -704,7 +704,8 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
char *new_name = (char *) param + param->data_start;
if (new_name < param->data ||
- invalid_str(new_name, (void *) param + param_size)) {
+ invalid_str(new_name, (void *) param + param_size) ||
+ strlen(new_name) > DM_NAME_LEN - 1) {
DMWARN("Invalid new logical volume name supplied.");
return -EINVAL;
}
@@ -1063,7 +1064,7 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
r = populate_table(t, param, param_size);
if (r) {
- dm_table_put(t);
+ dm_table_destroy(t);
goto out;
}
@@ -1071,7 +1072,7 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
hc = dm_get_mdptr(md);
if (!hc || hc->md != md) {
DMWARN("device has been removed from the dev hash table.");
- dm_table_put(t);
+ dm_table_destroy(t);
up_write(&_hash_lock);
r = -ENXIO;
goto out;
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 3073618269e..0a225da2127 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -344,7 +344,7 @@ static int run_io_job(struct kcopyd_job *job)
{
int r;
struct dm_io_request io_req = {
- .bi_rw = job->rw | (1 << BIO_RW_SYNC),
+ .bi_rw = job->rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG),
.mem.type = DM_IO_PAGE_LIST,
.mem.ptr.pl = job->pages,
.mem.offset = job->offset,
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 51ba1db4b3e..8d40f27cce8 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -525,9 +525,12 @@ static int __noflush_suspending(struct mapped_device *md)
static void dec_pending(struct dm_io *io, int error)
{
unsigned long flags;
+ int io_error;
+ struct bio *bio;
+ struct mapped_device *md = io->md;
/* Push-back supersedes any I/O errors */
- if (error && !(io->error > 0 && __noflush_suspending(io->md)))
+ if (error && !(io->error > 0 && __noflush_suspending(md)))
io->error = error;
if (atomic_dec_and_test(&io->io_count)) {
@@ -537,24 +540,27 @@ static void dec_pending(struct dm_io *io, int error)
* This must be handled before the sleeper on
* suspend queue merges the pushback list.
*/
- spin_lock_irqsave(&io->md->pushback_lock, flags);
- if (__noflush_suspending(io->md))
- bio_list_add(&io->md->pushback, io->bio);
+ spin_lock_irqsave(&md->pushback_lock, flags);
+ if (__noflush_suspending(md))
+ bio_list_add(&md->pushback, io->bio);
else
/* noflush suspend was interrupted. */
io->error = -EIO;
- spin_unlock_irqrestore(&io->md->pushback_lock, flags);
+ spin_unlock_irqrestore(&md->pushback_lock, flags);
}
end_io_acct(io);
- if (io->error != DM_ENDIO_REQUEUE) {
- trace_block_bio_complete(io->md->queue, io->bio);
+ io_error = io->error;
+ bio = io->bio;
- bio_endio(io->bio, io->error);
- }
+ free_io(md, io);
+
+ if (io_error != DM_ENDIO_REQUEUE) {
+ trace_block_bio_complete(md->queue, bio);
- free_io(io->md, io);
+ bio_endio(bio, io_error);
+ }
}
}
@@ -562,6 +568,7 @@ static void clone_endio(struct bio *bio, int error)
{
int r = 0;
struct dm_target_io *tio = bio->bi_private;
+ struct dm_io *io = tio->io;
struct mapped_device *md = tio->io->md;
dm_endio_fn endio = tio->ti->type->end_io;
@@ -585,15 +592,14 @@ static void clone_endio(struct bio *bio, int error)
}
}
- dec_pending(tio->io, error);
-
/*
* Store md for cleanup instead of tio which is about to get freed.
*/
bio->bi_private = md->bs;
- bio_put(bio);
free_tio(md, tio);
+ bio_put(bio);
+ dec_pending(io, error);
}
static sector_t max_io_len(struct mapped_device *md,
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 1e3aea9eecf..09658b21847 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -25,13 +25,13 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
{
dev_info_t *hash;
linear_conf_t *conf = mddev_to_conf(mddev);
+ sector_t idx = sector >> conf->sector_shift;
/*
* sector_div(a,b) returns the remainer and sets a to a/b
*/
- sector >>= conf->sector_shift;
- (void)sector_div(sector, conf->spacing);
- hash = conf->hash_table[sector];
+ (void)sector_div(idx, conf->spacing);
+ hash = conf->hash_table[idx];
while (sector >= hash->num_sectors + hash->start_sector)
hash++;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 41e2509bf89..a307f87eb90 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -214,12 +214,7 @@ static inline mddev_t *mddev_get(mddev_t *mddev)
return mddev;
}
-static void mddev_delayed_delete(struct work_struct *ws)
-{
- mddev_t *mddev = container_of(ws, mddev_t, del_work);
- kobject_del(&mddev->kobj);
- kobject_put(&mddev->kobj);
-}
+static void mddev_delayed_delete(struct work_struct *ws);
static void mddev_put(mddev_t *mddev)
{
@@ -474,7 +469,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
* causes ENOTSUPP, we allocate a spare bio...
*/
struct bio *bio = bio_alloc(GFP_NOIO, 1);
- int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC);
+ int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNCIO) | (1<<BIO_RW_UNPLUG);
bio->bi_bdev = rdev->bdev;
bio->bi_sector = sector;
@@ -531,7 +526,7 @@ int sync_page_io(struct block_device *bdev, sector_t sector, int size,
struct completion event;
int ret;
- rw |= (1 << BIO_RW_SYNC);
+ rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
bio->bi_bdev = bdev;
bio->bi_sector = sector;
@@ -1481,6 +1476,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (find_rdev_nr(mddev, rdev->desc_nr))
return -EBUSY;
}
+ if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) {
+ printk(KERN_WARNING "md: %s: array is limited to %d devices\n",
+ mdname(mddev), mddev->max_disks);
+ return -EBUSY;
+ }
bdevname(rdev->bdev,b);
while ( (s=strchr(b, '/')) != NULL)
*s = '!';
@@ -2441,6 +2441,15 @@ static void analyze_sbs(mddev_t * mddev)
i = 0;
rdev_for_each(rdev, tmp, mddev) {
+ if (rdev->desc_nr >= mddev->max_disks ||
+ i > mddev->max_disks) {
+ printk(KERN_WARNING
+ "md: %s: %s: only %d devices permitted\n",
+ mdname(mddev), bdevname(rdev->bdev, b),
+ mddev->max_disks);
+ kick_rdev_from_array(rdev);
+ continue;
+ }
if (rdev != freshest)
if (super_types[mddev->major_version].
validate_super(mddev, rdev)) {
@@ -3528,6 +3537,21 @@ static struct kobj_type md_ktype = {
int mdp_major = 0;
+static void mddev_delayed_delete(struct work_struct *ws)
+{
+ mddev_t *mddev = container_of(ws, mddev_t, del_work);
+
+ if (mddev->private == &md_redundancy_group) {
+ sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
+ if (mddev->sysfs_action)
+ sysfs_put(mddev->sysfs_action);
+ mddev->sysfs_action = NULL;
+ mddev->private = NULL;
+ }
+ kobject_del(&mddev->kobj);
+ kobject_put(&mddev->kobj);
+}
+
static int md_alloc(dev_t dev, char *name)
{
static DEFINE_MUTEX(disks_mutex);
@@ -4019,13 +4043,9 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->unplug_fn = NULL;
mddev->queue->backing_dev_info.congested_fn = NULL;
- if (mddev->pers->sync_request) {
- sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
- if (mddev->sysfs_action)
- sysfs_put(mddev->sysfs_action);
- mddev->sysfs_action = NULL;
- }
module_put(mddev->pers->owner);
+ if (mddev->pers->sync_request)
+ mddev->private = &md_redundancy_group;
mddev->pers = NULL;
/* tell userspace to handle 'inactive' */
sysfs_notify_dirent(mddev->sysfs_state);
@@ -4614,13 +4634,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
* noticed in interrupt contexts ...
*/
- if (rdev->desc_nr == mddev->max_disks) {
- printk(KERN_WARNING "%s: can not hot-add to full array!\n",
- mdname(mddev));
- err = -EBUSY;
- goto abort_unbind_export;
- }
-
rdev->raid_disk = -1;
md_update_sb(mddev, 1);
@@ -4634,9 +4647,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
md_new_event(mddev);
return 0;
-abort_unbind_export:
- unbind_rdev_from_array(rdev);
-
abort_export:
export_rdev(rdev);
return err;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 7b4f5f7155d..e2466425d9c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error)
update_head_pos(mirror, r1_bio);
if (atomic_dec_and_test(&r1_bio->remaining)) {
- md_done_sync(mddev, r1_bio->sectors, uptodate);
+ sector_t s = r1_bio->sectors;
put_buf(r1_bio);
+ md_done_sync(mddev, s, uptodate);
}
}
@@ -1640,7 +1641,8 @@ static void raid1d(mddev_t *mddev)
}
bio = r1_bio->bios[r1_bio->read_disk];
- if ((disk=read_balance(conf, r1_bio)) == -1) {
+ if ((disk=read_balance(conf, r1_bio)) == -1 ||
+ disk == r1_bio->read_disk) {
printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
" read error for block %llu\n",
bdevname(bio->bi_bdev,b),
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 6736d6dff98..7301631abe0 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1236,6 +1236,7 @@ static void end_sync_read(struct bio *bio, int error)
/* for reconstruct, we always reschedule after a read.
* for resync, only after all reads
*/
+ rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
if (test_bit(R10BIO_IsRecover, &r10_bio->state) ||
atomic_dec_and_test(&r10_bio->remaining)) {
/* we have read all the blocks,
@@ -1243,7 +1244,6 @@ static void end_sync_read(struct bio *bio, int error)
*/
reschedule_retry(r10_bio);
}
- rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
}
static void end_sync_write(struct bio *bio, int error)
@@ -1264,11 +1264,13 @@ static void end_sync_write(struct bio *bio, int error)
update_head_pos(i, r10_bio);
+ rdev_dec_pending(conf->mirrors[d].rdev, mddev);
while (atomic_dec_and_test(&r10_bio->remaining)) {
if (r10_bio->master_bio == NULL) {
/* the primary of several recovery bios */
- md_done_sync(mddev, r10_bio->sectors, 1);
+ sector_t s = r10_bio->sectors;
put_buf(r10_bio);
+ md_done_sync(mddev, s, 1);
break;
} else {
r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio;
@@ -1276,7 +1278,6 @@ static void end_sync_write(struct bio *bio, int error)
r10_bio = r10_bio2;
}
}
- rdev_dec_pending(conf->mirrors[d].rdev, mddev);
}
/*
@@ -1749,8 +1750,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
if (!go_faster && conf->nr_waiting)
msleep_interruptible(1000);
- bitmap_cond_end_sync(mddev->bitmap, sector_nr);
-
/* Again, very different code for resync and recovery.
* Both must result in an r10bio with a list of bios that
* have bi_end_io, bi_sector, bi_bdev set,
@@ -1886,6 +1885,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* resync. Schedule a read for every block at this virt offset */
int count = 0;
+ bitmap_cond_end_sync(mddev->bitmap, sector_nr);
+
if (!bitmap_start_sync(mddev->bitmap, sector_nr,
&sync_blocks, mddev->degraded) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
@@ -2010,13 +2011,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* There is nowhere to write, so all non-sync
* drives must be failed, so try the next chunk...
*/
- {
- sector_t sec = max_sector - sector_nr;
- sectors_skipped += sec;
+ if (sector_nr + max_sync < max_sector)
+ max_sector = sector_nr + max_sync;
+
+ sectors_skipped += (max_sector - sector_nr);
chunks_skipped ++;
sector_nr = max_sector;
goto skipped;
- }
}
static int run(mddev_t *mddev)
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 6098b626811..47fee05eaef 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -576,6 +576,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
vv->vflip = c->value;
break;
default: {
+ mutex_unlock(&dev->lock);
return -EINVAL;
}
}
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 64379f2bf23..3ec28945c26 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -657,7 +657,7 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
{
struct mxl5007t_state *state = fe->tuner_priv;
int rf_locked, ref_locked;
- s32 rf_input_level;
+ s32 rf_input_level = 0;
int ret;
if (fe->ops.i2c_gate_ctrl)
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index de7adaf5fa5..78412c9c424 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -318,7 +318,6 @@ static int simple_std_setup(struct dvb_frontend *fe,
u8 *config, u8 *cb)
{
struct tuner_simple_priv *priv = fe->tuner_priv;
- u8 tuneraddr;
int rc;
/* tv norm specific stuff for multi-norm tuners */
@@ -387,6 +386,7 @@ static int simple_std_setup(struct dvb_frontend *fe,
case TUNER_PHILIPS_TUV1236D:
{
+ struct tuner_i2c_props i2c = priv->i2c_props;
/* 0x40 -> ATSC antenna input 1 */
/* 0x48 -> ATSC antenna input 2 */
/* 0x00 -> NTSC antenna input 1 */
@@ -398,17 +398,15 @@ static int simple_std_setup(struct dvb_frontend *fe,
buffer[1] = 0x04;
}
/* set to the correct mode (analog or digital) */
- tuneraddr = priv->i2c_props.addr;
- priv->i2c_props.addr = 0x0a;
- rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2);
+ i2c.addr = 0x0a;
+ rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2);
if (2 != rc)
tuner_warn("i2c i/o error: rc == %d "
"(should be 2)\n", rc);
- rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2);
+ rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2);
if (2 != rc)
tuner_warn("i2c i/o error: rc == %d "
"(should be 2)\n", rc);
- priv->i2c_props.addr = tuneraddr;
break;
}
}
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 40ebde53b3c..b0198691892 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -51,6 +51,10 @@ comment "Supported SDMC DM1105 Adapters"
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/dm1105/Kconfig"
+comment "Supported FireWire (IEEE 1394) Adapters"
+ depends on DVB_CORE && IEEE1394
+source "drivers/media/dvb/firewire/Kconfig"
+
comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index f91e9eb15e5..6092a5bb5a7 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -3,3 +3,5 @@
#
obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
+
+obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index b386cc66c6b..451974ba32f 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -192,6 +192,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
return 0;
}
+EXPORT_SYMBOL(flexcop_pid_feed_control);
void flexcop_hw_filter_init(struct flexcop_device *fc)
{
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 5b30dfc7846..76e37fd96bb 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -13,9 +13,9 @@ static int enable_pid_filtering = 1;
module_param(enable_pid_filtering, int, 0444);
MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
-static int irq_chk_intv;
+static int irq_chk_intv = 100;
module_param(irq_chk_intv, int, 0644);
-MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging).");
+MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
#define dprintk(level,args...) \
@@ -34,7 +34,9 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently jus
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug,
+ "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
+ DEBSTATUS);
#define DRIVER_VERSION "0.1"
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
@@ -58,6 +60,8 @@ struct flexcop_pci {
int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
int count;
+ int count_prev;
+ int stream_problem;
spinlock_t irq_lock;
@@ -103,18 +107,32 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)
container_of(work, struct flexcop_pci, irq_check_work.work);
struct flexcop_device *fc = fc_pci->fc_dev;
- flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
-
- flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4);
-
- if (v.sram_dest_reg_714.net_ovflow_error)
- deb_chk("sram net_ovflow_error\n");
- if (v.sram_dest_reg_714.media_ovflow_error)
- deb_chk("sram media_ovflow_error\n");
- if (v.sram_dest_reg_714.cai_ovflow_error)
- deb_chk("sram cai_ovflow_error\n");
- if (v.sram_dest_reg_714.cai_ovflow_error)
- deb_chk("sram cai_ovflow_error\n");
+ if (fc->feedcount) {
+
+ if (fc_pci->count == fc_pci->count_prev) {
+ deb_chk("no IRQ since the last check\n");
+ if (fc_pci->stream_problem++ == 3) {
+ struct dvb_demux_feed *feed;
+
+ spin_lock_irq(&fc->demux.lock);
+ list_for_each_entry(feed, &fc->demux.feed_list,
+ list_head) {
+ flexcop_pid_feed_control(fc, feed, 0);
+ }
+
+ list_for_each_entry(feed, &fc->demux.feed_list,
+ list_head) {
+ flexcop_pid_feed_control(fc, feed, 1);
+ }
+ spin_unlock_irq(&fc->demux.lock);
+
+ fc_pci->stream_problem = 0;
+ }
+ } else {
+ fc_pci->stream_problem = 0;
+ fc_pci->count_prev = fc_pci->count;
+ }
+ }
schedule_delayed_work(&fc_pci->irq_check_work,
msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
@@ -216,16 +234,12 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
deb_irq("IRQ enabled\n");
+ fc_pci->count_prev = fc_pci->count;
+
// fc_pci->active_dma1_addr = 0;
// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
- if (irq_chk_intv > 0)
- schedule_delayed_work(&fc_pci->irq_check_work,
- msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
} else {
- if (irq_chk_intv > 0)
- cancel_delayed_work(&fc_pci->irq_check_work);
-
flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
deb_irq("IRQ disabled\n");
@@ -299,8 +313,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
goto err_pci_iounmap;
-
-
fc_pci->init_state |= FC_PCI_INIT;
return ret;
@@ -375,6 +387,10 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
+ if (irq_chk_intv > 0)
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
+
return ret;
err_fc_exit:
@@ -393,6 +409,9 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
{
struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
+ if (irq_chk_intv > 0)
+ cancel_delayed_work(&fc_pci->irq_check_work);
+
flexcop_pci_dma_exit(fc_pci);
flexcop_device_exit(fc_pci->fc_dev);
flexcop_pci_exit(fc_pci);
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 676413a915b..91068952b50 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -212,8 +212,7 @@ void flexcop_reset_block_300(struct flexcop_device *fc)
v210.sw_reset_210.Block_reset_enable = 0xb2;
fc->write_ibi_reg(fc,sw_reset_210,v210);
- msleep(1);
-
+ udelay(1000);
fc->write_ibi_reg(fc,ctrl_208,v208_save);
}
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 29e8f1546ab..fec1d77fa85 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1683,7 +1683,7 @@ static int dst_tune_frontend(struct dvb_frontend* fe,
static int dst_get_tuning_algo(struct dvb_frontend *fe)
{
- return dst_algo;
+ return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW;
}
static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 0c733c66a44..069d847ba88 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -364,16 +364,15 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
enum dmx_success success)
{
struct dmxdev_filter *dmxdevfilter = filter->priv;
- unsigned long flags;
int ret;
if (dmxdevfilter->buffer.error) {
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
- spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+ spin_lock(&dmxdevfilter->dev->lock);
if (dmxdevfilter->state != DMXDEV_STATE_GO) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
return 0;
}
del_timer(&dmxdevfilter->timer);
@@ -392,7 +391,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
}
if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
dmxdevfilter->state = DMXDEV_STATE_DONE;
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
@@ -404,12 +403,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
- unsigned long flags;
int ret;
- spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+ spin_lock(&dmxdevfilter->dev->lock);
if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
return 0;
}
@@ -419,7 +417,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
else
buffer = &dmxdevfilter->dev->dvr_buffer;
if (buffer->error) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&buffer->queue);
return 0;
}
@@ -430,7 +428,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
dvb_ringbuffer_flush(buffer);
buffer->error = ret;
}
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&buffer->queue);
return 0;
}
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 98ee16773ff..7e3aeaa7370 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -93,6 +93,9 @@ struct dvb_ca_slot {
/* current state of the CAM */
int slot_state;
+ /* mutex used for serializing access to one CI slot */
+ struct mutex slot_lock;
+
/* Number of CAMCHANGES that have occurred since last processing */
atomic_t camchange_count;
@@ -711,14 +714,20 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
dprintk("%s\n", __func__);
- // sanity check
+ /* sanity check */
if (bytes_write > ca->slot_info[slot].link_buf_size)
return -EINVAL;
- /* check if interface is actually waiting for us to read from it, or if a read is in progress */
+ /* it is possible we are dealing with a single buffer implementation,
+ thus if there is data available for read or if there is even a read
+ already in progress, we do nothing but awake the kernel thread to
+ process the data if necessary. */
if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
goto exitnowrite;
if (status & (STATUSREG_DA | STATUSREG_RE)) {
+ if (status & STATUSREG_DA)
+ dvb_ca_en50221_thread_wakeup(ca);
+
status = -EAGAIN;
goto exitnowrite;
}
@@ -987,6 +996,8 @@ static int dvb_ca_en50221_thread(void *data)
/* go through all the slots processing them */
for (slot = 0; slot < ca->slot_count; slot++) {
+ mutex_lock(&ca->slot_info[slot].slot_lock);
+
// check the cam status + deal with CAMCHANGEs
while (dvb_ca_en50221_check_camstatus(ca, slot)) {
/* clear down an old CI slot if necessary */
@@ -1122,7 +1133,7 @@ static int dvb_ca_en50221_thread(void *data)
case DVB_CA_SLOTSTATE_RUNNING:
if (!ca->open)
- continue;
+ break;
// poll slots for data
pktcount = 0;
@@ -1146,6 +1157,8 @@ static int dvb_ca_en50221_thread(void *data)
}
break;
}
+
+ mutex_unlock(&ca->slot_info[slot].slot_lock);
}
}
@@ -1181,6 +1194,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case CA_RESET:
for (slot = 0; slot < ca->slot_count; slot++) {
+ mutex_lock(&ca->slot_info[slot].slot_lock);
if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
dvb_ca_en50221_slot_shutdown(ca, slot);
if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
@@ -1188,6 +1202,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
slot,
DVB_CA_EN50221_CAMCHANGE_INSERTED);
}
+ mutex_unlock(&ca->slot_info[slot].slot_lock);
}
ca->next_read_slot = 0;
dvb_ca_en50221_thread_wakeup(ca);
@@ -1308,7 +1323,9 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
goto exit;
}
+ mutex_lock(&ca->slot_info[slot].slot_lock);
status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
+ mutex_unlock(&ca->slot_info[slot].slot_lock);
if (status == (fraglen + 2)) {
written = 1;
break;
@@ -1664,6 +1681,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
atomic_set(&ca->slot_info[i].camchange_count, 0);
ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
+ mutex_init(&ca->slot_info[i].slot_lock);
}
if (signal_pending(current)) {
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
index 8467e63ddc0..7df2e141187 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
@@ -45,8 +45,10 @@ struct dvb_ca_en50221 {
/* the module owning this structure */
struct module* owner;
- /* NOTE: the read_*, write_* and poll_slot_status functions must use locks as
- * they may be called from several threads at once */
+ /* NOTE: the read_*, write_* and poll_slot_status functions will be
+ * called for different slots concurrently and need to use locks where
+ * and if appropriate. There will be no concurrent access to one slot.
+ */
/* functions for accessing attribute memory on the CAM */
int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index a2c1fd5d2f6..e2eca0b1fe7 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -399,9 +399,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count)
{
- unsigned long flags;
-
- spin_lock_irqsave(&demux->lock, flags);
+ spin_lock(&demux->lock);
while (count--) {
if (buf[0] == 0x47)
@@ -409,17 +407,16 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
buf += 188;
}
- spin_unlock_irqrestore(&demux->lock, flags);
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- unsigned long flags;
int p = 0, i, j;
- spin_lock_irqsave(&demux->lock, flags);
+ spin_lock(&demux->lock);
if (demux->tsbufp) {
i = demux->tsbufp;
@@ -452,18 +449,17 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
}
bailout:
- spin_unlock_irqrestore(&demux->lock, flags);
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- unsigned long flags;
int p = 0, i, j;
u8 tmppack[188];
- spin_lock_irqsave(&demux->lock, flags);
+ spin_lock(&demux->lock);
if (demux->tsbufp) {
i = demux->tsbufp;
@@ -504,7 +500,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
}
bailout:
- spin_unlock_irqrestore(&demux->lock, flags);
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_204);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 84340778508..8dcb3fbf7ac 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1290,9 +1290,6 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
dprintk("%s() Finalised property cache\n", __func__);
dtv_property_cache_submit(fe);
- /* Request the search algorithm to search */
- fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
-
r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND,
&fepriv->parameters);
break;
@@ -1717,6 +1714,10 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
fepriv->state = FESTATE_RETUNE;
+
+ /* Request the search algorithm to search */
+ fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
+
dvb_frontend_wakeup(fe);
dvb_frontend_add_event(fe, 0);
fepriv->status = 0;
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c
index b1a9c4cdec9..199ece0d488 100644
--- a/drivers/media/dvb/dvb-usb/af9005-fe.c
+++ b/drivers/media/dvb/dvb-usb/af9005-fe.c
@@ -220,7 +220,7 @@ static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
u16 * abort_count)
{
u32 loc_cw_count = 0, loc_err_count;
- u16 loc_abort_count;
+ u16 loc_abort_count = 0;
int ret;
ret =
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index e1e9aa5c6b8..6a97a40d3df 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -694,7 +694,12 @@ static int af9015_read_config(struct usb_device *udev)
/* IR remote controller */
req.addr = AF9015_EEPROM_IR_MODE;
- ret = af9015_rw_udev(udev, &req);
+ /* first message will timeout often due to possible hw bug */
+ for (i = 0; i < 4; i++) {
+ ret = af9015_rw_udev(udev, &req);
+ if (!ret)
+ break;
+ }
if (ret)
goto error;
deb_info("%s: IR mode:%d\n", __func__, val);
@@ -835,18 +840,19 @@ static int af9015_read_config(struct usb_device *udev)
if (!dvb_usb_af9015_dual_mode)
af9015_config.dual_mode = 0;
- /* set buffer size according to USB port speed */
+ /* Set adapter0 buffer size according to USB port speed, adapter1 buffer
+ size can be static because it is enabled only USB2.0 */
for (i = 0; i < af9015_properties_count; i++) {
/* USB1.1 set smaller buffersize and disable 2nd adapter */
if (udev->speed == USB_SPEED_FULL) {
- af9015_properties[i].adapter->stream.u.bulk.buffersize =
- TS_USB11_MAX_PACKET_SIZE;
+ af9015_properties[i].adapter[0].stream.u.bulk.buffersize
+ = TS_USB11_MAX_PACKET_SIZE;
/* disable 2nd adapter because we don't have
PID-filters */
af9015_config.dual_mode = 0;
} else {
- af9015_properties[i].adapter->stream.u.bulk.buffersize =
- TS_USB20_MAX_PACKET_SIZE;
+ af9015_properties[i].adapter[0].stream.u.bulk.buffersize
+ = TS_USB20_MAX_PACKET_SIZE;
}
}
@@ -1254,6 +1260,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.type = USB_BULK,
.count = 6,
.endpoint = 0x85,
+ .u = {
+ .bulk = {
+ .buffersize =
+ TS_USB20_MAX_PACKET_SIZE,
+ }
+ }
},
}
},
@@ -1353,6 +1365,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.type = USB_BULK,
.count = 6,
.endpoint = 0x85,
+ .u = {
+ .bulk = {
+ .buffersize =
+ TS_USB20_MAX_PACKET_SIZE,
+ }
+ }
},
}
},
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 39173278891..635d30a5507 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1393,6 +1393,9 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
+ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
+ { USB_DEVICE(USB_VID_TERRATEC,
+ USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1537,7 +1540,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "DiBcom STK7700D reference design",
{ &dib0700_usb_id_table[14], NULL },
{ NULL },
- }
+ },
+
},
.rc_interval = DEFAULT_RC_INTERVAL,
@@ -1557,7 +1561,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 2,
+ .num_device_descs = 3,
.devices = {
{ "ASUS My Cinema U3000 Mini DVBT Tuner",
{ &dib0700_usb_id_table[23], NULL },
@@ -1566,6 +1570,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Yuan EC372S",
{ &dib0700_usb_id_table[31], NULL },
{ NULL },
+ },
+ { "Terratec Cinergy T Express",
+ { &dib0700_usb_id_table[42], NULL },
+ { NULL },
}
},
@@ -1653,7 +1661,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
}
},
- .num_device_descs = 4,
+ .num_device_descs = 5,
.devices = {
{ "DiBcom STK7070PD reference design",
{ &dib0700_usb_id_table[17], NULL },
@@ -1670,6 +1678,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Hauppauge Nova-TD-500 (84xxx)",
{ &dib0700_usb_id_table[36], NULL },
{ NULL },
+ },
+ { "Terratec Cinergy DT USB XS Diversity",
+ { &dib0700_usb_id_table[43], NULL },
+ { NULL },
}
}
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index a4fca3fca5e..0db0c06ee6f 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -162,8 +162,10 @@
#define USB_PID_AVERMEDIA_A309 0xa309
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
+#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060
+#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
#define USB_PID_PINNACLE_PCTV2000E 0x022c
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig
new file mode 100644
index 00000000000..69028253e98
--- /dev/null
+++ b/drivers/media/dvb/firewire/Kconfig
@@ -0,0 +1,22 @@
+config DVB_FIREDTV
+ tristate "FireDTV and FloppyDTV"
+ depends on DVB_CORE && IEEE1394
+ help
+ Support for DVB receivers from Digital Everywhere
+ which are connected via IEEE 1394 (FireWire).
+
+ These devices don't have an MPEG decoder built in,
+ so you need an external software decoder to watch TV.
+
+ To compile this driver as a module, say M here:
+ the module will be called firedtv.
+
+if DVB_FIREDTV
+
+config DVB_FIREDTV_IEEE1394
+ def_bool IEEE1394
+
+config DVB_FIREDTV_INPUT
+ def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
+
+endif # DVB_FIREDTV
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile
new file mode 100644
index 00000000000..2034695ba19
--- /dev/null
+++ b/drivers/media/dvb/firewire/Makefile
@@ -0,0 +1,8 @@
+obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
+
+firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o
+firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
+firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
+
+ccflags-y += -Idrivers/media/dvb/dvb-core
+ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
new file mode 100644
index 00000000000..4e207658c5d
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -0,0 +1,285 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <dma.h>
+#include <csr1212.h>
+#include <highlevel.h>
+#include <hosts.h>
+#include <ieee1394.h>
+#include <iso.h>
+#include <nodemgr.h>
+
+#include "firedtv.h"
+
+static LIST_HEAD(node_list);
+static DEFINE_SPINLOCK(node_list_lock);
+
+#define FIREWIRE_HEADER_SIZE 4
+#define CIP_HEADER_SIZE 8
+
+static void rawiso_activity_cb(struct hpsb_iso *iso)
+{
+ struct firedtv *f, *fdtv = NULL;
+ unsigned int i, num, packet;
+ unsigned char *buf;
+ unsigned long flags;
+ int count;
+
+ spin_lock_irqsave(&node_list_lock, flags);
+ list_for_each_entry(f, &node_list, list)
+ if (f->backend_data == iso) {
+ fdtv = f;
+ break;
+ }
+ spin_unlock_irqrestore(&node_list_lock, flags);
+
+ packet = iso->first_packet;
+ num = hpsb_iso_n_ready(iso);
+
+ if (!fdtv) {
+ dev_err(fdtv->device, "received at unknown iso channel\n");
+ goto out;
+ }
+
+ for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) {
+ buf = dma_region_i(&iso->data_buf, unsigned char,
+ iso->infos[packet].offset + CIP_HEADER_SIZE);
+ count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
+ (188 + FIREWIRE_HEADER_SIZE);
+
+ /* ignore empty packet */
+ if (iso->infos[packet].len <= CIP_HEADER_SIZE)
+ continue;
+
+ while (count--) {
+ if (buf[FIREWIRE_HEADER_SIZE] == 0x47)
+ dvb_dmx_swfilter_packets(&fdtv->demux,
+ &buf[FIREWIRE_HEADER_SIZE], 1);
+ else
+ dev_err(fdtv->device,
+ "skipping invalid packet\n");
+ buf += 188 + FIREWIRE_HEADER_SIZE;
+ }
+ }
+out:
+ hpsb_iso_recv_release_packets(iso, num);
+}
+
+static inline struct node_entry *node_of(struct firedtv *fdtv)
+{
+ return container_of(fdtv->device, struct unit_directory, device)->ne;
+}
+
+static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg)
+{
+ return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data,
+ (__force quadlet_t)arg);
+}
+
+static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+{
+ return hpsb_node_read(node_of(fdtv), addr, data, len);
+}
+
+static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+{
+ return hpsb_node_write(node_of(fdtv), addr, data, len);
+}
+
+#define FDTV_ISO_BUFFER_PACKETS 256
+#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200)
+
+static int start_iso(struct firedtv *fdtv)
+{
+ struct hpsb_iso *iso_handle;
+ int ret;
+
+ iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host,
+ FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS,
+ fdtv->isochannel, HPSB_ISO_DMA_DEFAULT,
+ -1, /* stat.config.irq_interval */
+ rawiso_activity_cb);
+ if (iso_handle == NULL) {
+ dev_err(fdtv->device, "cannot initialize iso receive\n");
+ return -ENOMEM;
+ }
+ fdtv->backend_data = iso_handle;
+
+ ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0);
+ if (ret != 0) {
+ dev_err(fdtv->device, "cannot start iso receive\n");
+ hpsb_iso_shutdown(iso_handle);
+ fdtv->backend_data = NULL;
+ }
+ return ret;
+}
+
+static void stop_iso(struct firedtv *fdtv)
+{
+ struct hpsb_iso *iso_handle = fdtv->backend_data;
+
+ if (iso_handle != NULL) {
+ hpsb_iso_stop(iso_handle);
+ hpsb_iso_shutdown(iso_handle);
+ }
+ fdtv->backend_data = NULL;
+}
+
+static const struct firedtv_backend fdtv_1394_backend = {
+ .lock = node_lock,
+ .read = node_read,
+ .write = node_write,
+ .start_iso = start_iso,
+ .stop_iso = stop_iso,
+};
+
+static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
+ int cts, u8 *data, size_t length)
+{
+ struct firedtv *f, *fdtv = NULL;
+ unsigned long flags;
+ int su;
+
+ if (length == 0 || (data[0] & 0xf0) != 0)
+ return;
+
+ su = data[1] & 0x7;
+
+ spin_lock_irqsave(&node_list_lock, flags);
+ list_for_each_entry(f, &node_list, list)
+ if (node_of(f)->host == host &&
+ node_of(f)->nodeid == nodeid &&
+ (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
+ fdtv = f;
+ break;
+ }
+ spin_unlock_irqrestore(&node_list_lock, flags);
+
+ if (fdtv)
+ avc_recv(fdtv, data, length);
+}
+
+static int node_probe(struct device *dev)
+{
+ struct unit_directory *ud =
+ container_of(dev, struct unit_directory, device);
+ struct firedtv *fdtv;
+ int kv_len, err;
+ void *kv_str;
+
+ kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t);
+ kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
+
+ fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
+ if (!fdtv)
+ return -ENOMEM;
+
+ /*
+ * Work around a bug in udev's path_id script: Use the fw-host's dev
+ * instead of the unit directory's dev as parent of the input device.
+ */
+ err = fdtv_register_rc(fdtv, dev->parent->parent);
+ if (err)
+ goto fail_free;
+
+ spin_lock_irq(&node_list_lock);
+ list_add_tail(&fdtv->list, &node_list);
+ spin_unlock_irq(&node_list_lock);
+
+ err = avc_identify_subunit(fdtv);
+ if (err)
+ goto fail;
+
+ err = fdtv_dvb_register(fdtv);
+ if (err)
+ goto fail;
+
+ avc_register_remote_control(fdtv);
+ return 0;
+fail:
+ spin_lock_irq(&node_list_lock);
+ list_del(&fdtv->list);
+ spin_unlock_irq(&node_list_lock);
+ fdtv_unregister_rc(fdtv);
+fail_free:
+ kfree(fdtv);
+ return err;
+}
+
+static int node_remove(struct device *dev)
+{
+ struct firedtv *fdtv = dev->driver_data;
+
+ fdtv_dvb_unregister(fdtv);
+
+ spin_lock_irq(&node_list_lock);
+ list_del(&fdtv->list);
+ spin_unlock_irq(&node_list_lock);
+
+ cancel_work_sync(&fdtv->remote_ctrl_work);
+ fdtv_unregister_rc(fdtv);
+
+ kfree(fdtv);
+ return 0;
+}
+
+static int node_update(struct unit_directory *ud)
+{
+ struct firedtv *fdtv = ud->device.driver_data;
+
+ if (fdtv->isochannel >= 0)
+ cmp_establish_pp_connection(fdtv, fdtv->subunit,
+ fdtv->isochannel);
+ return 0;
+}
+
+static struct hpsb_protocol_driver fdtv_driver = {
+ .name = "firedtv",
+ .update = node_update,
+ .driver = {
+ .probe = node_probe,
+ .remove = node_remove,
+ },
+};
+
+static struct hpsb_highlevel fdtv_highlevel = {
+ .name = "firedtv",
+ .fcp_request = fcp_request,
+};
+
+int __init fdtv_1394_init(struct ieee1394_device_id id_table[])
+{
+ int ret;
+
+ hpsb_register_highlevel(&fdtv_highlevel);
+ fdtv_driver.id_table = id_table;
+ ret = hpsb_register_protocol(&fdtv_driver);
+ if (ret) {
+ printk(KERN_ERR "firedtv: failed to register protocol\n");
+ hpsb_unregister_highlevel(&fdtv_highlevel);
+ }
+ return ret;
+}
+
+void __exit fdtv_1394_exit(void)
+{
+ hpsb_unregister_protocol(&fdtv_driver);
+ hpsb_unregister_highlevel(&fdtv_highlevel);
+}
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
new file mode 100644
index 00000000000..b55d9ccaf33
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -0,0 +1,1315 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bug.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/stringify.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include "firedtv.h"
+
+#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL
+
+#define AVC_CTYPE_CONTROL 0x0
+#define AVC_CTYPE_STATUS 0x1
+#define AVC_CTYPE_NOTIFY 0x3
+
+#define AVC_RESPONSE_ACCEPTED 0x9
+#define AVC_RESPONSE_STABLE 0xc
+#define AVC_RESPONSE_CHANGED 0xd
+#define AVC_RESPONSE_INTERIM 0xf
+
+#define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3)
+#define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3)
+
+#define AVC_OPCODE_VENDOR 0x00
+#define AVC_OPCODE_READ_DESCRIPTOR 0x09
+#define AVC_OPCODE_DSIT 0xc8
+#define AVC_OPCODE_DSD 0xcb
+
+#define DESCRIPTOR_TUNER_STATUS 0x80
+#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
+
+#define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */
+#define SFE_VENDOR_DE_COMPANYID_1 0x12
+#define SFE_VENDOR_DE_COMPANYID_2 0x87
+
+#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a
+#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52
+#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */
+
+#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00
+#define SFE_VENDOR_OPCODE_HOST2CA 0x56
+#define SFE_VENDOR_OPCODE_CA2HOST 0x57
+#define SFE_VENDOR_OPCODE_CISTATUS 0x59
+#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */
+
+#define SFE_VENDOR_TAG_CA_RESET 0x00
+#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01
+#define SFE_VENDOR_TAG_CA_PMT 0x02
+#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04
+#define SFE_VENDOR_TAG_CA_MMI 0x05
+#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07
+
+#define EN50221_LIST_MANAGEMENT_ONLY 0x03
+#define EN50221_TAG_APP_INFO 0x9f8021
+#define EN50221_TAG_CA_INFO 0x9f8031
+
+struct avc_command_frame {
+ int length;
+ u8 ctype;
+ u8 subunit;
+ u8 opcode;
+ u8 operand[509];
+};
+
+struct avc_response_frame {
+ int length;
+ u8 response;
+ u8 subunit;
+ u8 opcode;
+ u8 operand[509];
+};
+
+#define AVC_DEBUG_FCP_SUBACTIONS 1
+#define AVC_DEBUG_FCP_PAYLOADS 2
+
+static int avc_debug;
+module_param_named(debug, avc_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
+ ", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS)
+ ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS)
+ ", or all = -1)");
+
+static const char *debug_fcp_ctype(unsigned int ctype)
+{
+ static const char *ctypes[] = {
+ [0x0] = "CONTROL", [0x1] = "STATUS",
+ [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY",
+ [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED",
+ [0x9] = "ACCEPTED", [0xa] = "REJECTED",
+ [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE",
+ [0xd] = "CHANGED", [0xf] = "INTERIM",
+ };
+ const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL;
+
+ return ret ? ret : "?";
+}
+
+static const char *debug_fcp_opcode(unsigned int opcode,
+ const u8 *data, size_t length)
+{
+ switch (opcode) {
+ case AVC_OPCODE_VENDOR: break;
+ case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor";
+ case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type";
+ case AVC_OPCODE_DSD: return "DirectSelectData";
+ default: return "?";
+ }
+
+ if (length < 7 ||
+ data[3] != SFE_VENDOR_DE_COMPANYID_0 ||
+ data[4] != SFE_VENDOR_DE_COMPANYID_1 ||
+ data[5] != SFE_VENDOR_DE_COMPANYID_2)
+ return "Vendor";
+
+ switch (data[6]) {
+ case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC";
+ case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl";
+ case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK";
+ case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA";
+ case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host";
+ }
+ return "Vendor";
+}
+
+static void debug_fcp(const u8 *data, size_t length)
+{
+ unsigned int subunit_type, subunit_id, op;
+ const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
+
+ if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) {
+ subunit_type = data[1] >> 3;
+ subunit_id = data[1] & 7;
+ op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
+ printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
+ prefix, subunit_type, subunit_id, length,
+ debug_fcp_ctype(data[0]),
+ debug_fcp_opcode(op, data, length));
+ }
+
+ if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
+ print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1,
+ data, length, false);
+}
+
+static int __avc_write(struct firedtv *fdtv,
+ const struct avc_command_frame *c, struct avc_response_frame *r)
+{
+ int err, retry;
+
+ if (r)
+ fdtv->avc_reply_received = false;
+
+ for (retry = 0; retry < 6; retry++) {
+ if (unlikely(avc_debug))
+ debug_fcp(&c->ctype, c->length);
+
+ err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER,
+ (void *)&c->ctype, c->length);
+ if (err) {
+ fdtv->avc_reply_received = true;
+ dev_err(fdtv->device, "FCP command write failed\n");
+ return err;
+ }
+
+ if (!r)
+ return 0;
+
+ /*
+ * AV/C specs say that answers should be sent within 150 ms.
+ * Time out after 200 ms.
+ */
+ if (wait_event_timeout(fdtv->avc_wait,
+ fdtv->avc_reply_received,
+ msecs_to_jiffies(200)) != 0) {
+ r->length = fdtv->response_length;
+ memcpy(&r->response, fdtv->response, r->length);
+
+ return 0;
+ }
+ }
+ dev_err(fdtv->device, "FCP response timed out\n");
+ return -ETIMEDOUT;
+}
+
+static int avc_write(struct firedtv *fdtv,
+ const struct avc_command_frame *c, struct avc_response_frame *r)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = __avc_write(fdtv, c, r);
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+int avc_recv(struct firedtv *fdtv, void *data, size_t length)
+{
+ struct avc_response_frame *r =
+ data - offsetof(struct avc_response_frame, response);
+
+ if (unlikely(avc_debug))
+ debug_fcp(data, length);
+
+ if (length >= 8 &&
+ r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
+ r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
+ r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
+ r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
+ if (r->response == AVC_RESPONSE_CHANGED) {
+ fdtv_handle_rc(fdtv,
+ r->operand[4] << 8 | r->operand[5]);
+ schedule_work(&fdtv->remote_ctrl_work);
+ } else if (r->response != AVC_RESPONSE_INTERIM) {
+ dev_info(fdtv->device,
+ "remote control result = %d\n", r->response);
+ }
+ return 0;
+ }
+
+ if (fdtv->avc_reply_received) {
+ dev_err(fdtv->device, "out-of-order AVC response, ignored\n");
+ return -EIO;
+ }
+
+ memcpy(fdtv->response, data, length);
+ fdtv->response_length = length;
+
+ fdtv->avc_reply_received = true;
+ wake_up(&fdtv->avc_wait);
+
+ return 0;
+}
+
+/*
+ * tuning command for setting the relative LNB frequency
+ * (not supported by the AVC standard)
+ */
+static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
+ struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
+
+ c->operand[4] = (params->frequency >> 24) & 0xff;
+ c->operand[5] = (params->frequency >> 16) & 0xff;
+ c->operand[6] = (params->frequency >> 8) & 0xff;
+ c->operand[7] = params->frequency & 0xff;
+
+ c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff;
+ c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff;
+
+ switch (params->u.qpsk.fec_inner) {
+ case FEC_1_2: c->operand[10] = 0x1; break;
+ case FEC_2_3: c->operand[10] = 0x2; break;
+ case FEC_3_4: c->operand[10] = 0x3; break;
+ case FEC_5_6: c->operand[10] = 0x4; break;
+ case FEC_7_8: c->operand[10] = 0x5; break;
+ case FEC_4_5:
+ case FEC_8_9:
+ case FEC_AUTO:
+ default: c->operand[10] = 0x0;
+ }
+
+ if (fdtv->voltage == 0xff)
+ c->operand[11] = 0xff;
+ else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */
+ c->operand[11] = 0;
+ else
+ c->operand[11] = 1;
+
+ if (fdtv->tone == 0xff)
+ c->operand[12] = 0xff;
+ else if (fdtv->tone == SEC_TONE_ON) /* band */
+ c->operand[12] = 1;
+ else
+ c->operand[12] = 0;
+
+ if (fdtv->type == FIREDTV_DVB_S2) {
+ c->operand[13] = 0x1;
+ c->operand[14] = 0xff;
+ c->operand[15] = 0xff;
+ c->length = 20;
+ } else {
+ c->length = 16;
+ }
+}
+
+static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x11; /* system_specific_multiplex selection_length */
+
+ /* multiplex_valid_flags, high byte */
+ c->operand[5] = 0 << 7 /* reserved */
+ | 0 << 6 /* Polarisation */
+ | 0 << 5 /* Orbital_Pos */
+ | 1 << 4 /* Frequency */
+ | 1 << 3 /* Symbol_Rate */
+ | 0 << 2 /* FEC_outer */
+ | (params->u.qam.fec_inner != FEC_AUTO ? 1 << 1 : 0)
+ | (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0);
+
+ /* multiplex_valid_flags, low byte */
+ c->operand[6] = 0 << 7 /* NetworkID */
+ | 0 << 0 /* reserved */ ;
+
+ c->operand[7] = 0x00;
+ c->operand[8] = 0x00;
+ c->operand[9] = 0x00;
+ c->operand[10] = 0x00;
+
+ c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6);
+ c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff;
+ c->operand[13] = (params->frequency / 4000) & 0xff;
+ c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff;
+ c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff;
+ c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0;
+ c->operand[17] = 0x00;
+
+ switch (params->u.qpsk.fec_inner) {
+ case FEC_1_2: c->operand[18] = 0x1; break;
+ case FEC_2_3: c->operand[18] = 0x2; break;
+ case FEC_3_4: c->operand[18] = 0x3; break;
+ case FEC_5_6: c->operand[18] = 0x4; break;
+ case FEC_7_8: c->operand[18] = 0x5; break;
+ case FEC_8_9: c->operand[18] = 0x6; break;
+ case FEC_4_5: c->operand[18] = 0x8; break;
+ case FEC_AUTO:
+ default: c->operand[18] = 0x0;
+ }
+
+ switch (params->u.qam.modulation) {
+ case QAM_16: c->operand[19] = 0x08; break;
+ case QAM_32: c->operand[19] = 0x10; break;
+ case QAM_64: c->operand[19] = 0x18; break;
+ case QAM_128: c->operand[19] = 0x20; break;
+ case QAM_256: c->operand[19] = 0x28; break;
+ case QAM_AUTO:
+ default: c->operand[19] = 0x00;
+ }
+
+ c->operand[20] = 0x00;
+ c->operand[21] = 0x00;
+ /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
+ c->operand[22] = 0x00;
+
+ c->length = 28;
+}
+
+static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
+
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */
+
+ /* multiplex_valid_flags, high byte */
+ c->operand[5] =
+ 0 << 7 /* reserved */
+ | 1 << 6 /* CenterFrequency */
+ | (ofdm->bandwidth != BANDWIDTH_AUTO ? 1 << 5 : 0)
+ | (ofdm->constellation != QAM_AUTO ? 1 << 4 : 0)
+ | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0)
+ | (ofdm->code_rate_HP != FEC_AUTO ? 1 << 2 : 0)
+ | (ofdm->code_rate_LP != FEC_AUTO ? 1 << 1 : 0)
+ | (ofdm->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0);
+
+ /* multiplex_valid_flags, low byte */
+ c->operand[6] =
+ 0 << 7 /* NetworkID */
+ | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0)
+ | 0 << 5 /* OtherFrequencyFlag */
+ | 0 << 0 /* reserved */ ;
+
+ c->operand[7] = 0x0;
+ c->operand[8] = (params->frequency / 10) >> 24;
+ c->operand[9] = ((params->frequency / 10) >> 16) & 0xff;
+ c->operand[10] = ((params->frequency / 10) >> 8) & 0xff;
+ c->operand[11] = (params->frequency / 10) & 0xff;
+
+ switch (ofdm->bandwidth) {
+ case BANDWIDTH_7_MHZ: c->operand[12] = 0x20; break;
+ case BANDWIDTH_8_MHZ:
+ case BANDWIDTH_6_MHZ: /* not defined by AVC spec */
+ case BANDWIDTH_AUTO:
+ default: c->operand[12] = 0x00;
+ }
+
+ switch (ofdm->constellation) {
+ case QAM_16: c->operand[13] = 1 << 6; break;
+ case QAM_64: c->operand[13] = 2 << 6; break;
+ case QPSK:
+ default: c->operand[13] = 0x00;
+ }
+
+ switch (ofdm->hierarchy_information) {
+ case HIERARCHY_1: c->operand[13] |= 1 << 3; break;
+ case HIERARCHY_2: c->operand[13] |= 2 << 3; break;
+ case HIERARCHY_4: c->operand[13] |= 3 << 3; break;
+ case HIERARCHY_AUTO:
+ case HIERARCHY_NONE:
+ default: break;
+ }
+
+ switch (ofdm->code_rate_HP) {
+ case FEC_2_3: c->operand[13] |= 1; break;
+ case FEC_3_4: c->operand[13] |= 2; break;
+ case FEC_5_6: c->operand[13] |= 3; break;
+ case FEC_7_8: c->operand[13] |= 4; break;
+ case FEC_1_2:
+ default: break;
+ }
+
+ switch (ofdm->code_rate_LP) {
+ case FEC_2_3: c->operand[14] = 1 << 5; break;
+ case FEC_3_4: c->operand[14] = 2 << 5; break;
+ case FEC_5_6: c->operand[14] = 3 << 5; break;
+ case FEC_7_8: c->operand[14] = 4 << 5; break;
+ case FEC_1_2:
+ default: c->operand[14] = 0x00; break;
+ }
+
+ switch (ofdm->guard_interval) {
+ case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break;
+ case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break;
+ case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break;
+ case GUARD_INTERVAL_1_32:
+ case GUARD_INTERVAL_AUTO:
+ default: break;
+ }
+
+ switch (ofdm->transmission_mode) {
+ case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break;
+ case TRANSMISSION_MODE_2K:
+ case TRANSMISSION_MODE_AUTO:
+ default: break;
+ }
+
+ c->operand[15] = 0x00; /* network_ID[0] */
+ c->operand[16] = 0x00; /* network_ID[1] */
+ /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
+ c->operand[17] = 0x00;
+
+ c->length = 24;
+}
+
+int avc_tuner_dsd(struct firedtv *fdtv,
+ struct dvb_frontend_parameters *params)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+
+ switch (fdtv->type) {
+ case FIREDTV_DVB_S:
+ case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break;
+ case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break;
+ case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break;
+ default:
+ BUG();
+ }
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(500);
+#if 0
+ /* FIXME: */
+ /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */
+ if (status)
+ *status = r->operand[2];
+#endif
+ return 0;
+}
+
+int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+ int pos, k;
+
+ if (pidc > 16 && pidc != 0xff)
+ return -EINVAL;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x00; /* system_specific_multiplex selection_length */
+ c->operand[5] = pidc; /* Nr_of_dsd_sel_specs */
+
+ pos = 6;
+ if (pidc != 0xff)
+ for (k = 0; k < pidc; k++) {
+ c->operand[pos++] = 0x13; /* flowfunction relay */
+ c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
+ c->operand[pos++] = (pid[k] >> 8) & 0x1f;
+ c->operand[pos++] = pid[k] & 0xff;
+ c->operand[pos++] = 0x00; /* tableID */
+ c->operand[pos++] = 0x00; /* filter_length */
+ }
+
+ c->length = ALIGN(3 + pos, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(50);
+ return 0;
+}
+
+int avc_tuner_get_ts(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+ int sl;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_DSIT;
+
+ sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0xff; /* status */
+ c->operand[3] = 0x20; /* system id = DVB */
+ c->operand[4] = 0x00; /* antenna number */
+ c->operand[5] = 0x0; /* system_specific_search_flags */
+ c->operand[6] = sl; /* system_specific_multiplex selection_length */
+ c->operand[7] = 0x00; /* valid_flags [0] */
+ c->operand[8] = 0x00; /* valid_flags [1] */
+ c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */
+
+ c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(250);
+ return 0;
+}
+
+int avc_identify_subunit(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
+
+ c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER;
+ c->operand[1] = 0xff;
+ c->operand[2] = 0x00;
+ c->operand[3] = 0x00; /* length highbyte */
+ c->operand[4] = 0x08; /* length lowbyte */
+ c->operand[5] = 0x00; /* offset highbyte */
+ c->operand[6] = 0x0d; /* offset lowbyte */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if ((r->response != AVC_RESPONSE_STABLE &&
+ r->response != AVC_RESPONSE_ACCEPTED) ||
+ (r->operand[3] << 8) + r->operand[4] != 8) {
+ dev_err(fdtv->device, "cannot read subunit identifier\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+#define SIZEOF_ANTENNA_INPUT_INFO 22
+
+int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int length;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
+
+ c->operand[0] = DESCRIPTOR_TUNER_STATUS;
+ c->operand[1] = 0xff; /* read_result_status */
+ c->operand[2] = 0x00; /* reserved */
+ c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */
+ c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */
+ c->operand[5] = 0x00;
+ c->operand[6] = 0x00;
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_STABLE &&
+ r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device, "cannot read tuner status\n");
+ return -EINVAL;
+ }
+
+ length = r->operand[9];
+ if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) {
+ dev_err(fdtv->device, "got invalid tuner status\n");
+ return -EINVAL;
+ }
+
+ stat->active_system = r->operand[10];
+ stat->searching = r->operand[11] >> 7 & 1;
+ stat->moving = r->operand[11] >> 6 & 1;
+ stat->no_rf = r->operand[11] >> 5 & 1;
+ stat->input = r->operand[12] >> 7 & 1;
+ stat->selected_antenna = r->operand[12] & 0x7f;
+ stat->ber = r->operand[13] << 24 |
+ r->operand[14] << 16 |
+ r->operand[15] << 8 |
+ r->operand[16];
+ stat->signal_strength = r->operand[17];
+ stat->raster_frequency = r->operand[18] >> 6 & 2;
+ stat->rf_frequency = (r->operand[18] & 0x3f) << 16 |
+ r->operand[19] << 8 |
+ r->operand[20];
+ stat->man_dep_info_length = r->operand[21];
+ stat->front_end_error = r->operand[22] >> 4 & 1;
+ stat->antenna_error = r->operand[22] >> 3 & 1;
+ stat->front_end_power_status = r->operand[22] >> 1 & 1;
+ stat->power_supply = r->operand[22] & 1;
+ stat->carrier_noise_ratio = r->operand[23] << 8 |
+ r->operand[24];
+ stat->power_supply_voltage = r->operand[27];
+ stat->antenna_voltage = r->operand[28];
+ stat->firewire_bus_voltage = r->operand[29];
+ stat->ca_mmi = r->operand[30] & 1;
+ stat->ca_pmt_reply = r->operand[31] >> 7 & 1;
+ stat->ca_date_time_request = r->operand[31] >> 6 & 1;
+ stat->ca_application_info = r->operand[31] >> 5 & 1;
+ stat->ca_module_present_status = r->operand[31] >> 4 & 1;
+ stat->ca_dvb_flag = r->operand[31] >> 3 & 1;
+ stat->ca_error_flag = r->operand[31] >> 2 & 1;
+ stat->ca_initialization_status = r->operand[31] >> 1 & 1;
+
+ return 0;
+}
+
+int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
+ char conttone, char nrdiseq,
+ struct dvb_diseqc_master_cmd *diseqcmd)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int i, j, k;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL;
+
+ c->operand[4] = voltage;
+ c->operand[5] = nrdiseq;
+
+ i = 6;
+
+ for (j = 0; j < nrdiseq; j++) {
+ c->operand[i++] = diseqcmd[j].msg_len;
+
+ for (k = 0; k < diseqcmd[j].msg_len; k++)
+ c->operand[i++] = diseqcmd[j].msg[k];
+ }
+
+ c->operand[i++] = burst;
+ c->operand[i++] = conttone;
+
+ c->length = ALIGN(3 + i, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device, "LNB control failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int avc_register_remote_control(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_NOTIFY;
+ c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
+
+ c->length = 8;
+
+ return avc_write(fdtv, c, NULL);
+}
+
+void avc_remote_ctrl_work(struct work_struct *work)
+{
+ struct firedtv *fdtv =
+ container_of(work, struct firedtv, remote_ctrl_work);
+
+ /* Should it be rescheduled in failure cases? */
+ avc_register_remote_control(fdtv);
+}
+
+#if 0 /* FIXME: unused */
+int avc_tuner_host2ca(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+#endif
+
+static int get_ca_object_pos(struct avc_response_frame *r)
+{
+ int length = 1;
+
+ /* Check length of length field */
+ if (r->operand[7] & 0x80)
+ length = (r->operand[7] & 0x7f) + 1;
+ return length + 7;
+}
+
+static int get_ca_object_length(struct avc_response_frame *r)
+{
+#if 0 /* FIXME: unused */
+ int size = 0;
+ int i;
+
+ if (r->operand[7] & 0x80)
+ for (i = 0; i < (r->operand[7] & 0x7f); i++) {
+ size <<= 8;
+ size += r->operand[8 + i];
+ }
+#endif
+ return r->operand[7];
+}
+
+int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int pos;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ pos = get_ca_object_pos(r);
+ app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff;
+ app_info[1] = (EN50221_TAG_APP_INFO >> 8) & 0xff;
+ app_info[2] = (EN50221_TAG_APP_INFO >> 0) & 0xff;
+ app_info[3] = 6 + r->operand[pos + 4];
+ app_info[4] = 0x01;
+ memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]);
+ *len = app_info[3] + 4;
+
+ return 0;
+}
+
+int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int pos;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ pos = get_ca_object_pos(r);
+ app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff;
+ app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff;
+ app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff;
+ app_info[3] = 2;
+ app_info[4] = r->operand[pos + 0];
+ app_info[5] = r->operand[pos + 1];
+ *len = app_info[3] + 4;
+
+ return 0;
+}
+
+int avc_ca_reset(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 1; /* length */
+ c->operand[8] = 0; /* force hardware reset */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+
+int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int list_management;
+ int program_info_length;
+ int pmt_cmd_id;
+ int read_pos;
+ int write_pos;
+ int es_info_length;
+ int crc32_csum;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) {
+ dev_info(fdtv->device, "forcing list_management to ONLY\n");
+ msg[0] = EN50221_LIST_MANAGEMENT_ONLY;
+ }
+ /* We take the cmd_id from the programme level only! */
+ list_management = msg[0];
+ program_info_length = ((msg[4] & 0x0f) << 8) + msg[5];
+ if (program_info_length > 0)
+ program_info_length--; /* Remove pmt_cmd_id */
+ pmt_cmd_id = msg[6];
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */
+ c->operand[8] = list_management;
+ c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */
+
+ /* TS program map table */
+
+ c->operand[10] = 0x02; /* Table id=2 */
+ c->operand[11] = 0x80; /* Section syntax + length */
+ /* c->operand[12] = XXXprogram_info_length + 12; */
+ c->operand[13] = msg[1]; /* Program number */
+ c->operand[14] = msg[2];
+ c->operand[15] = 0x01; /* Version number=0 + current/next=1 */
+ c->operand[16] = 0x00; /* Section number=0 */
+ c->operand[17] = 0x00; /* Last section number=0 */
+ c->operand[18] = 0x1f; /* PCR_PID=1FFF */
+ c->operand[19] = 0xff;
+ c->operand[20] = (program_info_length >> 8); /* Program info length */
+ c->operand[21] = (program_info_length & 0xff);
+
+ /* CA descriptors at programme level */
+ read_pos = 6;
+ write_pos = 22;
+ if (program_info_length > 0) {
+ pmt_cmd_id = msg[read_pos++];
+ if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
+ dev_err(fdtv->device,
+ "invalid pmt_cmd_id %d\n", pmt_cmd_id);
+
+ memcpy(&c->operand[write_pos], &msg[read_pos],
+ program_info_length);
+ read_pos += program_info_length;
+ write_pos += program_info_length;
+ }
+ while (read_pos < length) {
+ c->operand[write_pos++] = msg[read_pos++];
+ c->operand[write_pos++] = msg[read_pos++];
+ c->operand[write_pos++] = msg[read_pos++];
+ es_info_length =
+ ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1];
+ read_pos += 2;
+ if (es_info_length > 0)
+ es_info_length--; /* Remove pmt_cmd_id */
+ c->operand[write_pos++] = es_info_length >> 8;
+ c->operand[write_pos++] = es_info_length & 0xff;
+ if (es_info_length > 0) {
+ pmt_cmd_id = msg[read_pos++];
+ if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
+ dev_err(fdtv->device, "invalid pmt_cmd_id %d "
+ "at stream level\n", pmt_cmd_id);
+
+ memcpy(&c->operand[write_pos], &msg[read_pos],
+ es_info_length);
+ read_pos += es_info_length;
+ write_pos += es_info_length;
+ }
+ }
+
+ /* CRC */
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+
+ c->operand[7] = write_pos - 8;
+ c->operand[12] = write_pos - 13;
+
+ crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1);
+ c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff;
+ c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
+ c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff;
+ c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff;
+
+ c->length = ALIGN(3 + write_pos, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device,
+ "CA PMT failed with response 0x%x\n", r->response);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ *interval = r->operand[get_ca_object_pos(r)];
+
+ return 0;
+}
+
+int avc_ca_enter_menu(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+
+int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_MMI;
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ *len = get_ca_object_length(r);
+ memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len);
+
+ return 0;
+}
+
+#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
+
+static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = fdtv->backend->read(fdtv, addr, buf, len);
+ if (ret < 0)
+ dev_err(fdtv->device, "CMP: read I/O error\n");
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = fdtv->backend->lock(fdtv, addr, data, arg);
+ if (ret < 0)
+ dev_err(fdtv->device, "CMP: lock I/O error\n");
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift)
+{
+ return (be32_to_cpu(opcr) >> shift) & mask;
+}
+
+static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
+{
+ *opcr &= ~cpu_to_be32(mask << shift);
+ *opcr |= cpu_to_be32((value & mask) << shift);
+}
+
+#define get_opcr_online(v) get_opcr((v), 0x1, 31)
+#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24)
+#define get_opcr_channel(v) get_opcr((v), 0x3f, 16)
+
+#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24)
+#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16)
+#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14)
+#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10)
+
+int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
+{
+ __be32 old_opcr, opcr;
+ u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
+ int attempts = 0;
+ int ret;
+
+ ret = cmp_read(fdtv, &opcr, opcr_address, 4);
+ if (ret < 0)
+ return ret;
+
+repeat:
+ if (!get_opcr_online(opcr)) {
+ dev_err(fdtv->device, "CMP: output offline\n");
+ return -EBUSY;
+ }
+
+ old_opcr = opcr;
+
+ if (get_opcr_p2p_connections(opcr)) {
+ if (get_opcr_channel(opcr) != channel) {
+ dev_err(fdtv->device, "CMP: cannot change channel\n");
+ return -EBUSY;
+ }
+ dev_info(fdtv->device, "CMP: overlaying connection\n");
+
+ /* We don't allocate isochronous resources. */
+ } else {
+ set_opcr_channel(&opcr, channel);
+ set_opcr_data_rate(&opcr, 2); /* S400 */
+
+ /* FIXME: this is for the worst case - optimize */
+ set_opcr_overhead_id(&opcr, 0);
+
+ /*
+ * FIXME: allocate isochronous channel and bandwidth at IRM
+ * fdtv->backend->alloc_resources(fdtv, channels_mask, bw);
+ */
+ }
+
+ set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1);
+
+ ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr);
+ if (ret < 0)
+ return ret;
+
+ if (old_opcr != opcr) {
+ /*
+ * FIXME: if old_opcr.P2P_Connections > 0,
+ * deallocate isochronous channel and bandwidth at IRM
+ * if (...)
+ * fdtv->backend->dealloc_resources(fdtv, channel, bw);
+ */
+
+ if (++attempts < 6) /* arbitrary limit */
+ goto repeat;
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
+{
+ __be32 old_opcr, opcr;
+ u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
+ int attempts = 0;
+
+ if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0)
+ return;
+
+repeat:
+ if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) ||
+ get_opcr_channel(opcr) != channel) {
+ dev_err(fdtv->device, "CMP: no connection to break\n");
+ return;
+ }
+
+ old_opcr = opcr;
+ set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1);
+
+ if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0)
+ return;
+
+ if (old_opcr != opcr) {
+ /*
+ * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
+ * owner, deallocate isochronous channel and bandwidth at IRM
+ * if (...)
+ * fdtv->backend->dealloc_resources(fdtv, channel, bw);
+ */
+
+ if (++attempts < 6) /* arbitrary limit */
+ goto repeat;
+ }
+}
diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c
new file mode 100644
index 00000000000..eeb80d0ea3f
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-ci.c
@@ -0,0 +1,260 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/dvb/ca.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+
+#include <dvbdev.h>
+
+#include "firedtv.h"
+
+#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020
+#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030
+#define EN50221_TAG_CA_PMT 0x9f8032
+#define EN50221_TAG_ENTER_MENU 0x9f8022
+
+static int fdtv_ca_ready(struct firedtv_tuner_status *stat)
+{
+ return stat->ca_initialization_status == 1 &&
+ stat->ca_error_flag == 0 &&
+ stat->ca_dvb_flag == 1 &&
+ stat->ca_module_present_status == 1;
+}
+
+static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat)
+{
+ int flags = 0;
+
+ if (stat->ca_module_present_status == 1)
+ flags |= CA_CI_MODULE_PRESENT;
+ if (stat->ca_initialization_status == 1 &&
+ stat->ca_error_flag == 0 &&
+ stat->ca_dvb_flag == 1)
+ flags |= CA_CI_MODULE_READY;
+ return flags;
+}
+
+static int fdtv_ca_reset(struct firedtv *fdtv)
+{
+ return avc_ca_reset(fdtv) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_caps(void *arg)
+{
+ struct ca_caps *cap = arg;
+
+ cap->slot_num = 1;
+ cap->slot_type = CA_CI;
+ cap->descr_num = 1;
+ cap->descr_type = CA_ECD;
+ return 0;
+}
+
+static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg)
+{
+ struct firedtv_tuner_status stat;
+ struct ca_slot_info *slot = arg;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EFAULT;
+
+ if (slot->num != 0)
+ return -EFAULT;
+
+ slot->type = CA_CI;
+ slot->flags = fdtv_get_ca_flags(&stat);
+ return 0;
+}
+
+static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_info(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg)
+{
+ struct firedtv_tuner_status stat;
+ int err;
+
+ switch (fdtv->ca_last_command) {
+ case EN50221_TAG_APP_INFO_ENQUIRY:
+ err = fdtv_ca_app_info(fdtv, arg);
+ break;
+ case EN50221_TAG_CA_INFO_ENQUIRY:
+ err = fdtv_ca_info(fdtv, arg);
+ break;
+ default:
+ if (avc_tuner_status(fdtv, &stat))
+ err = -EFAULT;
+ else if (stat.ca_mmi == 1)
+ err = fdtv_ca_get_mmi(fdtv, arg);
+ else {
+ dev_info(fdtv->device, "unhandled CA message 0x%08x\n",
+ fdtv->ca_last_command);
+ err = -EFAULT;
+ }
+ }
+ fdtv->ca_last_command = 0;
+ return err;
+}
+
+static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *msg = arg;
+ int data_pos;
+ int data_length;
+ int i;
+
+ data_pos = 4;
+ if (msg->msg[3] & 0x80) {
+ data_length = 0;
+ for (i = 0; i < (msg->msg[3] & 0x7f); i++)
+ data_length = (data_length << 8) + msg->msg[data_pos++];
+ } else {
+ data_length = msg->msg[3];
+ }
+
+ return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *msg = arg;
+ int err;
+
+ /* Do we need a semaphore for this? */
+ fdtv->ca_last_command =
+ (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2];
+ switch (fdtv->ca_last_command) {
+ case EN50221_TAG_CA_PMT:
+ err = fdtv_ca_pmt(fdtv, arg);
+ break;
+ case EN50221_TAG_APP_INFO_ENQUIRY:
+ /* handled in ca_get_msg */
+ err = 0;
+ break;
+ case EN50221_TAG_CA_INFO_ENQUIRY:
+ /* handled in ca_get_msg */
+ err = 0;
+ break;
+ case EN50221_TAG_ENTER_MENU:
+ err = avc_ca_enter_menu(fdtv);
+ break;
+ default:
+ dev_err(fdtv->device, "unhandled CA message 0x%08x\n",
+ fdtv->ca_last_command);
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int fdtv_ca_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct firedtv *fdtv = dvbdev->priv;
+ struct firedtv_tuner_status stat;
+ int err;
+
+ switch (cmd) {
+ case CA_RESET:
+ err = fdtv_ca_reset(fdtv);
+ break;
+ case CA_GET_CAP:
+ err = fdtv_ca_get_caps(arg);
+ break;
+ case CA_GET_SLOT_INFO:
+ err = fdtv_ca_get_slot_info(fdtv, arg);
+ break;
+ case CA_GET_MSG:
+ err = fdtv_ca_get_msg(fdtv, arg);
+ break;
+ case CA_SEND_MSG:
+ err = fdtv_ca_send_msg(fdtv, arg);
+ break;
+ default:
+ dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd);
+ err = -EOPNOTSUPP;
+ }
+
+ /* FIXME Is this necessary? */
+ avc_tuner_status(fdtv, &stat);
+
+ return err;
+}
+
+static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait)
+{
+ return POLLIN;
+}
+
+static struct file_operations fdtv_ca_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = dvb_generic_ioctl,
+ .open = dvb_generic_open,
+ .release = dvb_generic_release,
+ .poll = fdtv_ca_io_poll,
+};
+
+static struct dvb_device fdtv_ca = {
+ .users = 1,
+ .readers = 1,
+ .writers = 1,
+ .fops = &fdtv_ca_fops,
+ .kernel_ioctl = fdtv_ca_ioctl,
+};
+
+int fdtv_ca_register(struct firedtv *fdtv)
+{
+ struct firedtv_tuner_status stat;
+ int err;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ if (!fdtv_ca_ready(&stat))
+ return -EFAULT;
+
+ err = dvb_register_device(&fdtv->adapter, &fdtv->cadev,
+ &fdtv_ca, fdtv, DVB_DEVICE_CA);
+
+ if (stat.ca_application_info == 0)
+ dev_err(fdtv->device, "CaApplicationInfo is not set\n");
+ if (stat.ca_date_time_request == 1)
+ avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval);
+
+ return err;
+}
+
+void fdtv_ca_release(struct firedtv *fdtv)
+{
+ if (fdtv->cadev)
+ dvb_unregister_device(fdtv->cadev);
+}
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
new file mode 100644
index 00000000000..9d308dd32a5
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -0,0 +1,364 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <dmxdev.h>
+#include <dvb_demux.h>
+#include <dvbdev.h>
+#include <dvb_frontend.h>
+
+#include "firedtv.h"
+
+static int alloc_channel(struct firedtv *fdtv)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (!__test_and_set_bit(i, &fdtv->channel_active))
+ break;
+ return i;
+}
+
+static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[])
+{
+ int i, n;
+
+ for (i = 0, n = 0; i < 16; i++)
+ if (test_bit(i, &fdtv->channel_active))
+ pid[n++] = fdtv->channel_pid[i];
+ *pidc = n;
+}
+
+static inline void dealloc_channel(struct firedtv *fdtv, int i)
+{
+ __clear_bit(i, &fdtv->channel_active);
+}
+
+int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct firedtv *fdtv = dvbdmxfeed->demux->priv;
+ int pidc, c, ret;
+ u16 pids[16];
+
+ switch (dvbdmxfeed->type) {
+ case DMX_TYPE_TS:
+ case DMX_TYPE_SEC:
+ break;
+ default:
+ dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n",
+ dvbdmxfeed->type);
+ return -EINVAL;
+ }
+
+ if (mutex_lock_interruptible(&fdtv->demux_mutex))
+ return -EINTR;
+
+ if (dvbdmxfeed->type == DMX_TYPE_TS) {
+ switch (dvbdmxfeed->pes_type) {
+ case DMX_TS_PES_VIDEO:
+ case DMX_TS_PES_AUDIO:
+ case DMX_TS_PES_TELETEXT:
+ case DMX_TS_PES_PCR:
+ case DMX_TS_PES_OTHER:
+ c = alloc_channel(fdtv);
+ break;
+ default:
+ dev_err(fdtv->device,
+ "can't start dmx feed: invalid pes type %u\n",
+ dvbdmxfeed->pes_type);
+ ret = -EINVAL;
+ goto out;
+ }
+ } else {
+ c = alloc_channel(fdtv);
+ }
+
+ if (c > 15) {
+ dev_err(fdtv->device, "can't start dmx feed: busy\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c;
+ fdtv->channel_pid[c] = dvbdmxfeed->pid;
+ collect_channels(fdtv, &pidc, pids);
+
+ if (dvbdmxfeed->pid == 8192) {
+ ret = avc_tuner_get_ts(fdtv);
+ if (ret) {
+ dealloc_channel(fdtv, c);
+ dev_err(fdtv->device, "can't get TS\n");
+ goto out;
+ }
+ } else {
+ ret = avc_tuner_set_pids(fdtv, pidc, pids);
+ if (ret) {
+ dealloc_channel(fdtv, c);
+ dev_err(fdtv->device, "can't set PIDs\n");
+ goto out;
+ }
+ }
+out:
+ mutex_unlock(&fdtv->demux_mutex);
+
+ return ret;
+}
+
+int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct dvb_demux *demux = dvbdmxfeed->demux;
+ struct firedtv *fdtv = demux->priv;
+ int pidc, c, ret;
+ u16 pids[16];
+
+ if (dvbdmxfeed->type == DMX_TYPE_TS &&
+ !((dvbdmxfeed->ts_type & TS_PACKET) &&
+ (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
+
+ if (dvbdmxfeed->ts_type & TS_DECODER) {
+ if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
+ !demux->pesfilter[dvbdmxfeed->pes_type])
+ return -EINVAL;
+
+ demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
+ demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
+ }
+
+ if (!(dvbdmxfeed->ts_type & TS_DECODER &&
+ dvbdmxfeed->pes_type < DMX_TS_PES_OTHER))
+ return 0;
+ }
+
+ if (mutex_lock_interruptible(&fdtv->demux_mutex))
+ return -EINTR;
+
+ c = (unsigned long)dvbdmxfeed->priv;
+ dealloc_channel(fdtv, c);
+ collect_channels(fdtv, &pidc, pids);
+
+ ret = avc_tuner_set_pids(fdtv, pidc, pids);
+
+ mutex_unlock(&fdtv->demux_mutex);
+
+ return ret;
+}
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+int fdtv_dvb_register(struct firedtv *fdtv)
+{
+ int err;
+
+ err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type],
+ THIS_MODULE, fdtv->device, adapter_nr);
+ if (err < 0)
+ goto fail_log;
+
+ /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
+ fdtv->demux.dmx.capabilities = 0;
+
+ fdtv->demux.priv = fdtv;
+ fdtv->demux.filternum = 16;
+ fdtv->demux.feednum = 16;
+ fdtv->demux.start_feed = fdtv_start_feed;
+ fdtv->demux.stop_feed = fdtv_stop_feed;
+ fdtv->demux.write_to_decoder = NULL;
+
+ err = dvb_dmx_init(&fdtv->demux);
+ if (err)
+ goto fail_unreg_adapter;
+
+ fdtv->dmxdev.filternum = 16;
+ fdtv->dmxdev.demux = &fdtv->demux.dmx;
+ fdtv->dmxdev.capabilities = 0;
+
+ err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
+ if (err)
+ goto fail_dmx_release;
+
+ fdtv->frontend.source = DMX_FRONTEND_0;
+
+ err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+ if (err)
+ goto fail_dmxdev_release;
+
+ err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
+ &fdtv->frontend);
+ if (err)
+ goto fail_rem_frontend;
+
+ dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
+
+ fdtv_frontend_init(fdtv);
+ err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
+ if (err)
+ goto fail_net_release;
+
+ err = fdtv_ca_register(fdtv);
+ if (err)
+ dev_info(fdtv->device,
+ "Conditional Access Module not enabled\n");
+ return 0;
+
+fail_net_release:
+ dvb_net_release(&fdtv->dvbnet);
+ fdtv->demux.dmx.close(&fdtv->demux.dmx);
+fail_rem_frontend:
+ fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+fail_dmxdev_release:
+ dvb_dmxdev_release(&fdtv->dmxdev);
+fail_dmx_release:
+ dvb_dmx_release(&fdtv->demux);
+fail_unreg_adapter:
+ dvb_unregister_adapter(&fdtv->adapter);
+fail_log:
+ dev_err(fdtv->device, "DVB initialization failed\n");
+ return err;
+}
+
+void fdtv_dvb_unregister(struct firedtv *fdtv)
+{
+ fdtv_ca_release(fdtv);
+ dvb_unregister_frontend(&fdtv->fe);
+ dvb_net_release(&fdtv->dvbnet);
+ fdtv->demux.dmx.close(&fdtv->demux.dmx);
+ fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+ dvb_dmxdev_release(&fdtv->dmxdev);
+ dvb_dmx_release(&fdtv->demux);
+ dvb_unregister_adapter(&fdtv->adapter);
+}
+
+const char *fdtv_model_names[] = {
+ [FIREDTV_UNKNOWN] = "unknown type",
+ [FIREDTV_DVB_S] = "FireDTV S/CI",
+ [FIREDTV_DVB_C] = "FireDTV C/CI",
+ [FIREDTV_DVB_T] = "FireDTV T/CI",
+ [FIREDTV_DVB_S2] = "FireDTV S2 ",
+};
+
+struct firedtv *fdtv_alloc(struct device *dev,
+ const struct firedtv_backend *backend,
+ const char *name, size_t name_len)
+{
+ struct firedtv *fdtv;
+ int i;
+
+ fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
+ if (!fdtv)
+ return NULL;
+
+ dev->driver_data = fdtv;
+ fdtv->device = dev;
+ fdtv->isochannel = -1;
+ fdtv->voltage = 0xff;
+ fdtv->tone = 0xff;
+ fdtv->backend = backend;
+
+ mutex_init(&fdtv->avc_mutex);
+ init_waitqueue_head(&fdtv->avc_wait);
+ fdtv->avc_reply_received = true;
+ mutex_init(&fdtv->demux_mutex);
+ INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
+
+ for (i = ARRAY_SIZE(fdtv_model_names); --i; )
+ if (strlen(fdtv_model_names[i]) <= name_len &&
+ strncmp(name, fdtv_model_names[i], name_len) == 0)
+ break;
+ fdtv->type = i;
+
+ return fdtv;
+}
+
+#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
+ IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
+
+#define DIGITAL_EVERYWHERE_OUI 0x001287
+#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
+#define AVC_SW_VERSION_ENTRY 0x010001
+
+static struct ieee1394_device_id fdtv_id_table[] = {
+ {
+ /* FloppyDTV S/CI and FloppyDTV S2 */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000024,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FloppyDTV T/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000025,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FloppyDTV C/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000026,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV S/CI and FloppyDTV S2 */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000034,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV T/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000035,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV C/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000036,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {}
+};
+MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
+
+static int __init fdtv_init(void)
+{
+ return fdtv_1394_init(fdtv_id_table);
+}
+
+static void __exit fdtv_exit(void)
+{
+ fdtv_1394_exit();
+}
+
+module_init(fdtv_init);
+module_exit(fdtv_exit);
+
+MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
+MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
+MODULE_DESCRIPTION("FireDTV DVB Driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c
new file mode 100644
index 00000000000..7ba43630a25
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-fe.c
@@ -0,0 +1,247 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <dvb_frontend.h>
+
+#include "firedtv.h"
+
+static int fdtv_dvb_init(struct dvb_frontend *fe)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ int err;
+
+ /* FIXME - allocate free channel at IRM */
+ fdtv->isochannel = fdtv->adapter.num;
+
+ err = cmp_establish_pp_connection(fdtv, fdtv->subunit,
+ fdtv->isochannel);
+ if (err) {
+ dev_err(fdtv->device,
+ "could not establish point to point connection\n");
+ return err;
+ }
+
+ return fdtv->backend->start_iso(fdtv);
+}
+
+static int fdtv_sleep(struct dvb_frontend *fe)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->backend->stop_iso(fdtv);
+ cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
+ fdtv->isochannel = -1;
+ return 0;
+}
+
+#define LNBCONTROL_DONTCARE 0xff
+
+static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE,
+ LNBCONTROL_DONTCARE, 1, cmd);
+}
+
+static int fdtv_diseqc_send_burst(struct dvb_frontend *fe,
+ fe_sec_mini_cmd_t minicmd)
+{
+ return 0;
+}
+
+static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->tone = tone;
+ return 0;
+}
+
+static int fdtv_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->voltage = voltage;
+ return 0;
+}
+
+static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ if (stat.no_rf)
+ *status = 0;
+ else
+ *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
+ FE_HAS_CARRIER | FE_HAS_LOCK;
+ return 0;
+}
+
+static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ *ber = stat.ber;
+ return 0;
+}
+
+static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ *strength = stat.signal_strength << 8;
+ return 0;
+}
+
+static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ /* C/N[dB] = -10 * log10(snr / 65535) */
+ *snr = stat.carrier_noise_ratio * 257;
+ return 0;
+}
+
+static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ return -EOPNOTSUPP;
+}
+
+#define ACCEPTED 0x9
+
+static int fdtv_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
+ if (avc_tuner_dsd(fdtv, params) != ACCEPTED)
+ return -EINVAL;
+ else
+ return 0; /* not sure of this... */
+}
+
+static int fdtv_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ return -EOPNOTSUPP;
+}
+
+void fdtv_frontend_init(struct firedtv *fdtv)
+{
+ struct dvb_frontend_ops *ops = &fdtv->fe.ops;
+ struct dvb_frontend_info *fi = &ops->info;
+
+ ops->init = fdtv_dvb_init;
+ ops->sleep = fdtv_sleep;
+
+ ops->set_frontend = fdtv_set_frontend;
+ ops->get_frontend = fdtv_get_frontend;
+
+ ops->read_status = fdtv_read_status;
+ ops->read_ber = fdtv_read_ber;
+ ops->read_signal_strength = fdtv_read_signal_strength;
+ ops->read_snr = fdtv_read_snr;
+ ops->read_ucblocks = fdtv_read_uncorrected_blocks;
+
+ ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd;
+ ops->diseqc_send_burst = fdtv_diseqc_send_burst;
+ ops->set_tone = fdtv_set_tone;
+ ops->set_voltage = fdtv_set_voltage;
+
+ switch (fdtv->type) {
+ case FIREDTV_DVB_S:
+ case FIREDTV_DVB_S2:
+ fi->type = FE_QPSK;
+
+ fi->frequency_min = 950000;
+ fi->frequency_max = 2150000;
+ fi->frequency_stepsize = 125;
+ fi->symbol_rate_min = 1000000;
+ fi->symbol_rate_max = 40000000;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 |
+ FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK;
+ break;
+
+ case FIREDTV_DVB_C:
+ fi->type = FE_QAM;
+
+ fi->frequency_min = 47000000;
+ fi->frequency_max = 866000000;
+ fi->frequency_stepsize = 62500;
+ fi->symbol_rate_min = 870000;
+ fi->symbol_rate_max = 6900000;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_QAM_16 |
+ FE_CAN_QAM_32 |
+ FE_CAN_QAM_64 |
+ FE_CAN_QAM_128 |
+ FE_CAN_QAM_256 |
+ FE_CAN_QAM_AUTO;
+ break;
+
+ case FIREDTV_DVB_T:
+ fi->type = FE_OFDM;
+
+ fi->frequency_min = 49000000;
+ fi->frequency_max = 861000000;
+ fi->frequency_stepsize = 62500;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO;
+ break;
+
+ default:
+ dev_err(fdtv->device, "no frontend for model type %d\n",
+ fdtv->type);
+ }
+ strcpy(fi->name, fdtv_model_names[fdtv->type]);
+
+ fdtv->fe.dvb = &fdtv->adapter;
+ fdtv->fe.sec_priv = fdtv;
+}
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c
new file mode 100644
index 00000000000..46a6324d7b7
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-rc.c
@@ -0,0 +1,190 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "firedtv.h"
+
+/* fixed table with older keycodes, geared towards MythTV */
+const static u16 oldtable[] = {
+
+ /* code from device: 0x4501...0x451f */
+
+ KEY_ESC,
+ KEY_F9,
+ KEY_1,
+ KEY_2,
+ KEY_3,
+ KEY_4,
+ KEY_5,
+ KEY_6,
+ KEY_7,
+ KEY_8,
+ KEY_9,
+ KEY_I,
+ KEY_0,
+ KEY_ENTER,
+ KEY_RED,
+ KEY_UP,
+ KEY_GREEN,
+ KEY_F10,
+ KEY_SPACE,
+ KEY_F11,
+ KEY_YELLOW,
+ KEY_DOWN,
+ KEY_BLUE,
+ KEY_Z,
+ KEY_P,
+ KEY_PAGEDOWN,
+ KEY_LEFT,
+ KEY_W,
+ KEY_RIGHT,
+ KEY_P,
+ KEY_M,
+
+ /* code from device: 0x4540...0x4542 */
+
+ KEY_R,
+ KEY_V,
+ KEY_C,
+};
+
+/* user-modifiable table for a remote as sold in 2008 */
+const static u16 keytable[] = {
+
+ /* code from device: 0x0300...0x031f */
+
+ [0x00] = KEY_POWER,
+ [0x01] = KEY_SLEEP,
+ [0x02] = KEY_STOP,
+ [0x03] = KEY_OK,
+ [0x04] = KEY_RIGHT,
+ [0x05] = KEY_1,
+ [0x06] = KEY_2,
+ [0x07] = KEY_3,
+ [0x08] = KEY_LEFT,
+ [0x09] = KEY_4,
+ [0x0a] = KEY_5,
+ [0x0b] = KEY_6,
+ [0x0c] = KEY_UP,
+ [0x0d] = KEY_7,
+ [0x0e] = KEY_8,
+ [0x0f] = KEY_9,
+ [0x10] = KEY_DOWN,
+ [0x11] = KEY_TITLE, /* "OSD" - fixme */
+ [0x12] = KEY_0,
+ [0x13] = KEY_F20, /* "16:9" - fixme */
+ [0x14] = KEY_SCREEN, /* "FULL" - fixme */
+ [0x15] = KEY_MUTE,
+ [0x16] = KEY_SUBTITLE,
+ [0x17] = KEY_RECORD,
+ [0x18] = KEY_TEXT,
+ [0x19] = KEY_AUDIO,
+ [0x1a] = KEY_RED,
+ [0x1b] = KEY_PREVIOUS,
+ [0x1c] = KEY_REWIND,
+ [0x1d] = KEY_PLAYPAUSE,
+ [0x1e] = KEY_NEXT,
+ [0x1f] = KEY_VOLUMEUP,
+
+ /* code from device: 0x0340...0x0354 */
+
+ [0x20] = KEY_CHANNELUP,
+ [0x21] = KEY_F21, /* "4:3" - fixme */
+ [0x22] = KEY_TV,
+ [0x23] = KEY_DVD,
+ [0x24] = KEY_VCR,
+ [0x25] = KEY_AUX,
+ [0x26] = KEY_GREEN,
+ [0x27] = KEY_YELLOW,
+ [0x28] = KEY_BLUE,
+ [0x29] = KEY_CHANNEL, /* "CH.LIST" */
+ [0x2a] = KEY_VENDOR, /* "CI" - fixme */
+ [0x2b] = KEY_VOLUMEDOWN,
+ [0x2c] = KEY_CHANNELDOWN,
+ [0x2d] = KEY_LAST,
+ [0x2e] = KEY_INFO,
+ [0x2f] = KEY_FORWARD,
+ [0x30] = KEY_LIST,
+ [0x31] = KEY_FAVORITES,
+ [0x32] = KEY_MENU,
+ [0x33] = KEY_EPG,
+ [0x34] = KEY_EXIT,
+};
+
+int fdtv_register_rc(struct firedtv *fdtv, struct device *dev)
+{
+ struct input_dev *idev;
+ int i, err;
+
+ idev = input_allocate_device();
+ if (!idev)
+ return -ENOMEM;
+
+ fdtv->remote_ctrl_dev = idev;
+ idev->name = "FireDTV remote control";
+ idev->dev.parent = dev;
+ idev->evbit[0] = BIT_MASK(EV_KEY);
+ idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
+ if (!idev->keycode) {
+ err = -ENOMEM;
+ goto fail;
+ }
+ idev->keycodesize = sizeof(keytable[0]);
+ idev->keycodemax = ARRAY_SIZE(keytable);
+
+ for (i = 0; i < ARRAY_SIZE(keytable); i++)
+ set_bit(keytable[i], idev->keybit);
+
+ err = input_register_device(idev);
+ if (err)
+ goto fail_free_keymap;
+
+ return 0;
+
+fail_free_keymap:
+ kfree(idev->keycode);
+fail:
+ input_free_device(idev);
+ return err;
+}
+
+void fdtv_unregister_rc(struct firedtv *fdtv)
+{
+ kfree(fdtv->remote_ctrl_dev->keycode);
+ input_unregister_device(fdtv->remote_ctrl_dev);
+}
+
+void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
+{
+ u16 *keycode = fdtv->remote_ctrl_dev->keycode;
+
+ if (code >= 0x0300 && code <= 0x031f)
+ code = keycode[code - 0x0300];
+ else if (code >= 0x0340 && code <= 0x0354)
+ code = keycode[code - 0x0320];
+ else if (code >= 0x4501 && code <= 0x451f)
+ code = oldtable[code - 0x4501];
+ else if (code >= 0x4540 && code <= 0x4542)
+ code = oldtable[code - 0x4521];
+ else {
+ printk(KERN_DEBUG "firedtv: invalid key code 0x%04x "
+ "from remote control\n", code);
+ return;
+ }
+
+ input_report_key(fdtv->remote_ctrl_dev, code, 1);
+ input_report_key(fdtv->remote_ctrl_dev, code, 0);
+}
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h
new file mode 100644
index 00000000000..d48530b81e6
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv.h
@@ -0,0 +1,182 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef _FIREDTV_H
+#define _FIREDTV_H
+
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/frontend.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <demux.h>
+#include <dmxdev.h>
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
+#include <dvb_net.h>
+#include <dvbdev.h>
+
+struct firedtv_tuner_status {
+ unsigned active_system:8;
+ unsigned searching:1;
+ unsigned moving:1;
+ unsigned no_rf:1;
+ unsigned input:1;
+ unsigned selected_antenna:7;
+ unsigned ber:32;
+ unsigned signal_strength:8;
+ unsigned raster_frequency:2;
+ unsigned rf_frequency:22;
+ unsigned man_dep_info_length:8;
+ unsigned front_end_error:1;
+ unsigned antenna_error:1;
+ unsigned front_end_power_status:1;
+ unsigned power_supply:1;
+ unsigned carrier_noise_ratio:16;
+ unsigned power_supply_voltage:8;
+ unsigned antenna_voltage:8;
+ unsigned firewire_bus_voltage:8;
+ unsigned ca_mmi:1;
+ unsigned ca_pmt_reply:1;
+ unsigned ca_date_time_request:1;
+ unsigned ca_application_info:1;
+ unsigned ca_module_present_status:1;
+ unsigned ca_dvb_flag:1;
+ unsigned ca_error_flag:1;
+ unsigned ca_initialization_status:1;
+};
+
+enum model_type {
+ FIREDTV_UNKNOWN = 0,
+ FIREDTV_DVB_S = 1,
+ FIREDTV_DVB_C = 2,
+ FIREDTV_DVB_T = 3,
+ FIREDTV_DVB_S2 = 4,
+};
+
+struct device;
+struct input_dev;
+struct firedtv;
+
+struct firedtv_backend {
+ int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg);
+ int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+ int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+ int (*start_iso)(struct firedtv *fdtv);
+ void (*stop_iso)(struct firedtv *fdtv);
+};
+
+struct firedtv {
+ struct device *device;
+ struct list_head list;
+
+ struct dvb_adapter adapter;
+ struct dmxdev dmxdev;
+ struct dvb_demux demux;
+ struct dmx_frontend frontend;
+ struct dvb_net dvbnet;
+ struct dvb_frontend fe;
+
+ struct dvb_device *cadev;
+ int ca_last_command;
+ int ca_time_interval;
+
+ struct mutex avc_mutex;
+ wait_queue_head_t avc_wait;
+ bool avc_reply_received;
+ struct work_struct remote_ctrl_work;
+ struct input_dev *remote_ctrl_dev;
+
+ enum model_type type;
+ char subunit;
+ char isochannel;
+ fe_sec_voltage_t voltage;
+ fe_sec_tone_mode_t tone;
+
+ const struct firedtv_backend *backend;
+ void *backend_data;
+
+ struct mutex demux_mutex;
+ unsigned long channel_active;
+ u16 channel_pid[16];
+
+ size_t response_length;
+ u8 response[512];
+};
+
+/* firedtv-1394.c */
+#ifdef CONFIG_DVB_FIREDTV_IEEE1394
+int fdtv_1394_init(struct ieee1394_device_id id_table[]);
+void fdtv_1394_exit(void);
+#else
+static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; }
+static inline void fdtv_1394_exit(void) {}
+#endif
+
+/* firedtv-avc.c */
+int avc_recv(struct firedtv *fdtv, void *data, size_t length);
+int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat);
+struct dvb_frontend_parameters;
+int avc_tuner_dsd(struct firedtv *fdtv, struct dvb_frontend_parameters *params);
+int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]);
+int avc_tuner_get_ts(struct firedtv *fdtv);
+int avc_identify_subunit(struct firedtv *fdtv);
+struct dvb_diseqc_master_cmd;
+int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
+ char conttone, char nrdiseq,
+ struct dvb_diseqc_master_cmd *diseqcmd);
+void avc_remote_ctrl_work(struct work_struct *work);
+int avc_register_remote_control(struct firedtv *fdtv);
+int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len);
+int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len);
+int avc_ca_reset(struct firedtv *fdtv);
+int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length);
+int avc_ca_get_time_date(struct firedtv *fdtv, int *interval);
+int avc_ca_enter_menu(struct firedtv *fdtv);
+int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len);
+int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel);
+void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel);
+
+/* firedtv-ci.c */
+int fdtv_ca_register(struct firedtv *fdtv);
+void fdtv_ca_release(struct firedtv *fdtv);
+
+/* firedtv-dvb.c */
+int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed);
+int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
+int fdtv_dvb_register(struct firedtv *fdtv);
+void fdtv_dvb_unregister(struct firedtv *fdtv);
+struct firedtv *fdtv_alloc(struct device *dev,
+ const struct firedtv_backend *backend,
+ const char *name, size_t name_len);
+extern const char *fdtv_model_names[];
+
+/* firedtv-fe.c */
+void fdtv_frontend_init(struct firedtv *fdtv);
+
+/* firedtv-rc.c */
+#ifdef CONFIG_DVB_FIREDTV_INPUT
+int fdtv_register_rc(struct firedtv *fdtv, struct device *dev);
+void fdtv_unregister_rc(struct firedtv *fdtv);
+void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code);
+#else
+static inline int fdtv_register_rc(struct firedtv *fdtv,
+ struct device *dev) { return 0; }
+static inline void fdtv_unregister_rc(struct firedtv *fdtv) {}
+static inline void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) {}
+#endif
+
+#endif /* _FIREDTV_H */
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index ec4e08dbc69..1e81e713df6 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -646,7 +646,7 @@ static int drx_tune(struct drx397xD_state *s,
u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
- int rc, df_tuner;
+ int rc, df_tuner = 0;
int a, b, c, d;
pr_debug("%s %d\n", __func__, s->config.d60);
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index cf4d8936bb8..3e08d985d6e 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -545,9 +545,6 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
s5h1409_enable_modulation(fe, p->u.vsb.modulation);
- /* Allow the demod to settle */
- msleep(100);
-
if (fe->ops.tuner_ops.set_params) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -562,6 +559,10 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
s5h1409_set_qam_interleave_mode(fe);
}
+ /* Issue a reset to the demod so it knows to resync against the
+ newly tuned frequency */
+ s5h1409_softreset(fe);
+
return 0;
}
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
index 83dc7e12d5f..2da55ec2039 100644
--- a/drivers/media/dvb/frontends/stb0899_algo.c
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -31,6 +31,8 @@ inline u32 stb0899_do_div(u64 n, u32 d)
return n;
}
+#if 0
+/* These functions are currently unused */
/*
* stb0899_calc_srate
* Compute symbol rate
@@ -63,6 +65,7 @@ static u32 stb0899_get_srate(struct stb0899_state *state)
return stb0899_calc_srate(internal->master_clk, sfr);
}
+#endif
/*
* stb0899_set_srate
@@ -153,7 +156,7 @@ static void stb0899_first_subrange(struct stb0899_state *state)
}
if (range > 0)
- internal->sub_range = MIN(internal->srch_range, range);
+ internal->sub_range = min(internal->srch_range, range);
else
internal->sub_range = 0;
@@ -182,7 +185,7 @@ static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
timing = stb0899_read_reg(state, STB0899_RTF);
if (lock >= 42) {
- if ((lock > 48) && (ABS(timing) >= 110)) {
+ if ((lock > 48) && (abs(timing) >= 110)) {
internal->status = ANALOGCARRIER;
dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !");
} else {
@@ -219,7 +222,7 @@ static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
index++;
derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */
- if (ABS(derot_freq) > derot_limit)
+ if (abs(derot_freq) > derot_limit)
next_loop--;
if (next_loop) {
@@ -295,7 +298,7 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
last_derot_freq = derot_freq;
derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
- if(ABS(derot_freq) > derot_limit)
+ if(abs(derot_freq) > derot_limit)
next_loop--;
if (next_loop) {
@@ -397,7 +400,7 @@ static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
- if (ABS(derot_freq) > derot_limit)
+ if (abs(derot_freq) > derot_limit)
next_loop--;
if (next_loop) {
@@ -464,7 +467,7 @@ static void next_sub_range(struct stb0899_state *state)
if (internal->sub_dir > 0) {
old_sub_range = internal->sub_range;
- internal->sub_range = MIN((internal->srch_range / 2) -
+ internal->sub_range = min((internal->srch_range / 2) -
(internal->tuner_offst + internal->sub_range / 2),
internal->sub_range);
@@ -768,7 +771,7 @@ static long Log2Int(int number)
int i;
i = 0;
- while ((1 << i) <= ABS(number))
+ while ((1 << i) <= abs(number))
i++;
if (number == 0)
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index 10613acf18f..a04c782fff8 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -794,7 +794,7 @@ static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t
reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
old_state = reg;
/* set to burst mode */
- STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02);
+ STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x03);
STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01);
stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
switch (burst) {
diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h
index 24619e3689d..82395b91281 100644
--- a/drivers/media/dvb/frontends/stb0899_priv.h
+++ b/drivers/media/dvb/frontends/stb0899_priv.h
@@ -59,10 +59,6 @@
#define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
#define MAKEWORD16(a, b) (((a) << 8) | (b))
-#define MIN(x, y) ((x) <= (y) ? (x) : (y))
-#define MAX(x, y) ((x) >= (y) ? (x) : (y))
-#define ABS(x) ((x) >= 0 ? (x) : -(x))
-
#define LSB(x) ((x & 0xff))
#define MSB(y) ((y >> 8) & 0xff)
@@ -168,10 +164,10 @@ struct stb0899_internal {
u32 freq; /* Demod internal Frequency */
u32 srate; /* Demod internal Symbol rate */
enum stb0899_fec fecrate; /* Demod internal FEC rate */
- u32 srch_range; /* Demod internal Search Range */
- u32 sub_range; /* Demod current sub range (Hz) */
- u32 tuner_step; /* Tuner step (Hz) */
- u32 tuner_offst; /* Relative offset to carrier (Hz) */
+ s32 srch_range; /* Demod internal Search Range */
+ s32 sub_range; /* Demod current sub range (Hz) */
+ s32 tuner_step; /* Tuner step (Hz) */
+ s32 tuner_offst; /* Relative offset to carrier (Hz) */
u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */
s32 mclk; /* Masterclock Divider factor (binary) */
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index ff39275ab49..1ed5a7db4c5 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -427,11 +427,11 @@ static int stb6100_init(struct dvb_frontend *fe)
status->refclock = 27000000; /* Hz */
status->iqsense = 1;
status->bandwidth = 36000; /* kHz */
- state->bandwidth = status->bandwidth * 1000; /* MHz */
+ state->bandwidth = status->bandwidth * 1000; /* Hz */
state->reference = status->refclock / 1000; /* kHz */
/* Set default bandwidth. */
- return stb6100_set_bandwidth(fe, status->bandwidth);
+ return stb6100_set_bandwidth(fe, state->bandwidth);
}
static int stb6100_get_state(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index 170720b0281..b150ed30669 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -590,7 +590,7 @@ static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
struct zl10353_state *state = fe->demodulator_priv;
u8 val = 0x0a;
- if (state->config.no_tuner) {
+ if (state->config.disable_i2c_gate_ctrl) {
/* No tuner attached to the internal I2C bus */
/* If set enable I2C bridge, the main I2C bus stopped hardly */
return 0;
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index fdbb88ff75f..2287bac4624 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -38,6 +38,9 @@ struct zl10353_config
/* set if parallel ts output is required */
int parallel_ts;
+
+ /* set if i2c_gate_ctrl disable is required */
+ u8 disable_i2c_gate_ctrl:1;
};
#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 1638e1d9f53..83e9e7750c8 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -470,6 +470,7 @@ static void frontend_init(struct budget *budget)
budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
+ budget->dvb_frontend->tuner_priv = NULL;
break;
}
break;
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 0aa96df80fc..d91e0638448 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1384,7 +1384,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
static int ttusb_dec_init_stb(struct ttusb_dec *dec)
{
int result;
- unsigned int mode, model, version;
+ unsigned int mode = 0, model = 0, version = 0;
dprintk("%s\n", __func__);
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 0747dc8862b..fdfc7bf86b9 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -194,10 +194,10 @@ static int amradio_start(struct amradio_device *radio)
return retval;
}
- mutex_unlock(&radio->lock);
-
radio->muted = 0;
+ mutex_unlock(&radio->lock);
+
return retval;
}
@@ -230,10 +230,10 @@ static int amradio_stop(struct amradio_device *radio)
return retval;
}
- mutex_unlock(&radio->lock);
-
radio->muted = 1;
+ mutex_unlock(&radio->lock);
+
return retval;
}
@@ -284,10 +284,10 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
return retval;
}
- mutex_unlock(&radio->lock);
-
radio->stereo = 0;
+ mutex_unlock(&radio->lock);
+
return retval;
}
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 67cbce82cb9..4dfed6aa2db 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -98,11 +98,16 @@
* - blacklisted KWorld radio in hid-core.c and hid-ids.h
* 2008-12-03 Mark Lord <mlord@pobox.com>
* - add support for DealExtreme USB Radio
+ * 2009-01-31 Bob Ross <pigiron@gmx.com>
+ * - correction of stereo detection/setting
+ * - correction of signal strength indicator scaling
+ * 2009-01-31 Rick Bronson <rick@efn.org>
+ * Tobias Lorenz <tobias.lorenz@gmx.net>
+ * - add LED status output
*
* ToDo:
* - add firmware download/update support
* - RDS support: interrupt mode, instead of polling
- * - add LED status output (check if that's not already done in firmware)
*/
@@ -882,6 +887,30 @@ static int si470x_rds_on(struct si470x_device *radio)
/**************************************************************************
+ * General Driver Functions - LED_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_set_led_state - sets the led state
+ */
+static int si470x_set_led_state(struct si470x_device *radio,
+ unsigned char led_state)
+{
+ unsigned char buf[LED_REPORT_SIZE];
+ int retval;
+
+ buf[0] = LED_REPORT;
+ buf[1] = LED_COMMAND;
+ buf[2] = led_state;
+
+ retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
* RDS Driver Functions
**************************************************************************/
@@ -1385,20 +1414,22 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
};
/* stereo indicator == stereo (instead of mono) */
- if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1)
- tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- else
+ if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0)
tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+ else
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
/* mono/stereo selector */
- if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1)
- tuner->audmode = V4L2_TUNER_MODE_MONO;
- else
+ if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)
tuner->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ tuner->audmode = V4L2_TUNER_MODE_MONO;
/* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
- tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI)
- * 0x0101;
+ /* measured in units of dbµV in 1 db increments (max at ~75 dbµV) */
+ tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
+ /* the ideal factor is 0xffff/75 = 873,8 */
+ tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
/* automatic frequency control: -1: freq to low, 1 freq to high */
/* AFCRL does only indicate that freq. differs, not if too low/high */
@@ -1632,6 +1663,9 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
/* set initial frequency */
si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
+ /* set led to connect state */
+ si470x_set_led_state(radio, BLINK_GREEN_LED);
+
/* rds buffer allocation */
radio->buf_size = rds_buf * 3;
radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
@@ -1715,6 +1749,9 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
cancel_delayed_work_sync(&radio->work);
usb_set_intfdata(intf, NULL);
if (radio->users == 0) {
+ /* set led to disconnect state */
+ si470x_set_led_state(radio, BLINK_ORANGE_LED);
+
video_unregister_device(radio->videodev);
kfree(radio->buffer);
kfree(radio);
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 4d35308fc1f..393623818ad 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -298,7 +298,8 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
strlcpy(v->card, dev->name, sizeof(v->card));
- snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id);
+ snprintf(v->bus_info, sizeof(v->bus_info),
+ "I2C:%s", dev_name(&dev->dev));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 14bebf8a116..87e91072627 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -18,7 +18,6 @@
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 8f1db57bd1d..bfe25841dbf 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1586,7 +1586,8 @@ static int mpeg_open(struct file *file)
lock_kernel();
list_for_each(list, &cx23885_devlist) {
h = list_entry(list, struct cx23885_dev, devlist);
- if (h->v4l_device->minor == minor) {
+ if (h->v4l_device &&
+ h->v4l_device->minor == minor) {
dev = h;
break;
}
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 2d81c4d0434..eaa11893bfe 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -730,12 +730,13 @@ static int video_open(struct file *file)
lock_kernel();
list_for_each(list, &cx23885_devlist) {
h = list_entry(list, struct cx23885_dev, devlist);
- if (h->video_dev->minor == minor) {
+ if (h->video_dev &&
+ h->video_dev->minor == minor) {
dev = h;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
}
if (h->vbi_dev &&
- h->vbi_dev->minor == minor) {
+ h->vbi_dev->minor == minor) {
dev = h;
type = V4L2_BUF_TYPE_VBI_CAPTURE;
}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 88f2fd32bfe..25eb3bec9e5 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1382,6 +1382,14 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
{
+ /* ignore this command */
+ if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
+ return 0;
+
+ /* Old-style drivers rely on initialization on first use, so
+ call the init whenever a command is issued to this driver.
+ New-style drivers using v4l2_subdev should call init explicitly. */
+ cx25840_init(i2c_get_clientdata(client), 0);
return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
}
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 66c755c116d..ce98d955231 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -803,9 +803,10 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
return (-ENOENT);
}
- card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t));
- if (!card)
- return (-ENOMEM);
+ err = snd_card_create(index[devno], id[devno], THIS_MODULE,
+ sizeof(snd_cx88_card_t), &card);
+ if (err < 0)
+ return err;
card->private_free = snd_cx88_dev_free;
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 613dfea4ff3..aef5297534a 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -614,34 +614,41 @@ static struct stv0288_config tevii_tuner_earda_config = {
.set_ts_params = cx24116_set_ts_param,
};
-static int dvb_register(struct cx8802_dev *dev)
+static int cx8802_alloc_frontends(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
- struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
- int mfe_shared = 0; /* bus not shared by default */
+ struct videobuf_dvb_frontend *fe = NULL;
int i;
- if (0 != core->i2c_rc) {
- printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
- goto frontend_detach;
- }
-
- if (!core->board.num_frontends)
- return -EINVAL;
-
mutex_init(&dev->frontends.lock);
INIT_LIST_HEAD(&dev->frontends.felist);
+ if (!core->board.num_frontends)
+ return -ENODEV;
+
printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
core->board.num_frontends);
for (i = 1; i <= core->board.num_frontends; i++) {
- fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i);
- if (!fe0) {
+ fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
+ if (!fe) {
printk(KERN_ERR "%s() failed to alloc\n", __func__);
videobuf_dvb_dealloc_frontends(&dev->frontends);
- goto frontend_detach;
+ return -ENOMEM;
}
}
+ return 0;
+}
+
+static int dvb_register(struct cx8802_dev *dev)
+{
+ struct cx88_core *core = dev->core;
+ struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+ int mfe_shared = 0; /* bus not shared by default */
+
+ if (0 != core->i2c_rc) {
+ printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
+ goto frontend_detach;
+ }
/* Get the first frontend */
fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
@@ -1243,6 +1250,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
struct cx88_core *core = drv->core;
struct cx8802_dev *dev = drv->core->dvbdev;
int err;
+ struct videobuf_dvb_frontend *fe;
+ int i;
dprintk( 1, "%s\n", __func__);
dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1258,39 +1267,34 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
/* If vp3054 isn't enabled, a stub will just return 0 */
err = vp3054_i2c_probe(dev);
if (0 != err)
- goto fail_probe;
+ goto fail_core;
/* dvb stuff */
printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
dev->ts_gen_cntrl = 0x0c;
+ err = cx8802_alloc_frontends(dev);
+ if (err)
+ goto fail_core;
+
err = -ENODEV;
- if (core->board.num_frontends) {
- struct videobuf_dvb_frontend *fe;
- int i;
-
- for (i = 1; i <= core->board.num_frontends; i++) {
- fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
- if (fe == NULL) {
- printk(KERN_ERR "%s() failed to get frontend(%d)\n",
+ for (i = 1; i <= core->board.num_frontends; i++) {
+ fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
+ if (fe == NULL) {
+ printk(KERN_ERR "%s() failed to get frontend(%d)\n",
__func__, i);
- goto fail_probe;
- }
- videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
+ goto fail_probe;
+ }
+ videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_TOP,
sizeof(struct cx88_buffer),
dev);
- /* init struct videobuf_dvb */
- fe->dvb.name = dev->core->name;
- }
- } else {
- /* no frontends allocated */
- printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n",
- core->name);
- goto fail_core;
+ /* init struct videobuf_dvb */
+ fe->dvb.name = dev->core->name;
}
+
err = dvb_register(dev);
if (err)
/* frontends/adapter de-allocated in dvb_register */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 60a8b3187f1..6025fdd2334 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -336,8 +336,8 @@ struct cx88_core {
/* config info -- dvb */
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
- void (*gate_ctrl)(struct cx88_core *core, int open);
#endif
+ void (*gate_ctrl)(struct cx88_core *core, int open);
/* state info */
struct task_struct *kthread;
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 94378ccb750..f132e31f6ed 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -62,9 +62,15 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
dprintk("Stopping isoc\n");
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
- usb_unlink_urb(dev->adev.urb[i]);
+ if (!irqs_disabled())
+ usb_kill_urb(dev->adev.urb[i]);
+ else
+ usb_unlink_urb(dev->adev.urb[i]);
usb_free_urb(dev->adev.urb[i]);
dev->adev.urb[i] = NULL;
+
+ kfree(dev->adev.transfer_buffer[i]);
+ dev->adev.transfer_buffer[i] = NULL;
}
return 0;
@@ -389,11 +395,15 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
*substream)
{
- struct em28xx *dev;
+ unsigned long flags;
+ struct em28xx *dev;
snd_pcm_uframes_t hwptr_done;
+
dev = snd_pcm_substream_chip(substream);
+ spin_lock_irqsave(&dev->adev.slock, flags);
hwptr_done = dev->adev.hwptr_done_capture;
+ spin_unlock_irqrestore(&dev->adev.slock, flags);
return hwptr_done;
}
@@ -438,9 +448,10 @@ static int em28xx_audio_init(struct em28xx *dev)
printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
"Rechberger\n");
- card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
+ err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
+ &card);
+ if (err < 0)
+ return err;
spin_lock_init(&adev->slock);
err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
@@ -453,6 +464,8 @@ static int em28xx_audio_init(struct em28xx *dev)
pcm->info_flags = 0;
pcm->private_data = dev;
strcpy(pcm->name, "Empia 28xx Capture");
+
+ snd_card_set_dev(card, &dev->udev->dev);
strcpy(card->driver, "Empia Em28xx Audio");
strcpy(card->shortname, "Em28xx Audio");
strcpy(card->longname, "Empia Em28xx Audio");
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index ef9bf008a92..3b3ca3f46d5 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -102,6 +102,18 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
/* Board - EM2870 Kworld 355u
Analog - No input analog */
+static struct em28xx_reg_seq kworld_330u_analog[] = {
+ {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
+ {EM2880_R04_GPO, 0x00, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq kworld_330u_digital[] = {
+ {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ {EM2880_R04_GPO, 0x08, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
/* Callback for the most boards */
static struct em28xx_reg_seq default_tuner_gpio[] = {
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
@@ -1177,29 +1189,33 @@ struct em28xx_board em28xx_boards[] = {
.gpio = hauppauge_wintv_hvr_900_analog,
} },
},
- [EM2883_BOARD_KWORLD_HYBRID_A316] = {
+ [EM2883_BOARD_KWORLD_HYBRID_330U] = {
.name = "Kworld PlusTV HD Hybrid 330",
.tuner_type = TUNER_XC2028,
.tuner_gpio = default_tuner_gpio,
.decoder = EM28XX_TVP5150,
.mts_firmware = 1,
.has_dvb = 1,
- .dvb_gpio = default_digital,
+ .dvb_gpio = kworld_330u_digital,
+ .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
.amux = EM28XX_AMUX_VIDEO,
- .gpio = default_analog,
+ .gpio = kworld_330u_analog,
+ .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
}, {
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = TVP5150_COMPOSITE1,
.amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
+ .gpio = kworld_330u_analog,
+ .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
}, {
.type = EM28XX_VMUX_SVIDEO,
.vmux = TVP5150_SVIDEO,
.amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
+ .gpio = kworld_330u_analog,
} },
},
[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
@@ -1249,7 +1265,7 @@ struct usb_device_id em28xx_id_table [] = {
{ USB_DEVICE(0xeb1a, 0xe310),
.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
{ USB_DEVICE(0xeb1a, 0xa316),
- .driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 },
+ .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
{ USB_DEVICE(0xeb1a, 0xe320),
.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
{ USB_DEVICE(0xeb1a, 0xe323),
@@ -1526,6 +1542,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
/* FIXME: Better to specify the needed IF */
ctl->demod = XC3028_FE_DEFAULT;
break;
+ case EM2883_BOARD_KWORLD_HYBRID_330U:
+ ctl->demod = XC3028_FE_CHINA;
+ ctl->fname = XC2028_DEFAULT_FIRMWARE;
+ break;
default:
ctl->demod = XC3028_FE_OREN538;
}
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index eb5fb05fab2..94fb1b639a2 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -438,6 +438,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
int vol;
+ em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200);
+ em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031);
+ em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80);
+
/* LSB: left channel - both channels with the same level */
vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8);
@@ -454,6 +458,15 @@ int em28xx_audio_analog_set(struct em28xx *dev)
em28xx_warn("couldn't setup AC97 register %d\n",
outputs[i].reg);
}
+
+ if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
+ int sel = ac97_return_record_select(dev->ctl_aoutput);
+
+ /* Use the same input for both left and right channels */
+ sel |= (sel << 8);
+
+ em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
+ }
}
return ret;
@@ -847,8 +860,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
urb = dev->isoc_ctl.urb[i];
if (urb) {
- usb_kill_urb(urb);
- usb_unlink_urb(urb);
+ if (!irqs_disabled())
+ usb_kill_urb(urb);
+ else
+ usb_unlink_urb(urb);
+
if (dev->isoc_ctl.transfer_buffer[i]) {
usb_buffer_free(dev->udev,
urb->transfer_buffer_length,
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index d38cb21834d..9ad8527b3fd 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -28,6 +28,7 @@
#include "lgdt330x.h"
#include "zl10353.h"
+#include "s5h1409.h"
#ifdef EM28XX_DRX397XD_SUPPORT
#include "drx397xD.h"
#endif
@@ -232,6 +233,15 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = {
.if2 = 45600,
};
+static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
+ .demod_address = 0x32 >> 1,
+ .output_mode = S5H1409_PARALLEL_OUTPUT,
+ .gpio = S5H1409_GPIO_OFF,
+ .inversion = S5H1409_INVERSION_OFF,
+ .status_mode = S5H1409_DEMODLOCKING,
+ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
+};
+
#ifdef EM28XX_DRX397XD_SUPPORT
/* [TODO] djh - not sure yet what the device config needs to contain */
static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
@@ -412,7 +422,6 @@ static int dvb_init(struct em28xx *dev)
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
- case EM2883_BOARD_KWORLD_HYBRID_A316:
case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
dvb->frontend = dvb_attach(lgdt330x_attach,
&em2880_lgdt3303_dev,
@@ -433,6 +442,15 @@ static int dvb_init(struct em28xx *dev)
goto out_free;
}
break;
+ case EM2883_BOARD_KWORLD_HYBRID_330U:
+ dvb->frontend = dvb_attach(s5h1409_attach,
+ &em28xx_s5h1409_with_xc3028,
+ &dev->i2c_adap);
+ if (attach_xc3028(0x61, dev) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ break;
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
#ifdef EM28XX_DRX397XD_SUPPORT
/* We don't have the config structure properly populated, so
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 416b691c33c..8e61b2ca916 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -886,10 +886,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
if (0 == INPUT(i)->type)
return -EINVAL;
- mutex_lock(&dev->lock);
-
- video_mux(dev, i);
+ dev->ctl_input = i;
+ mutex_lock(&dev->lock);
+ video_mux(dev, dev->ctl_input);
mutex_unlock(&dev->lock);
return 0;
}
@@ -939,6 +939,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
+
+ if (a->index >= MAX_EM28XX_INPUT)
+ return -EINVAL;
+ if (0 == INPUT(a->index)->type)
+ return -EINVAL;
+
mutex_lock(&dev->lock);
dev->ctl_ainput = INPUT(a->index)->amux;
@@ -1950,6 +1956,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
int em28xx_register_analog_devices(struct em28xx *dev)
{
+ u8 val;
int ret;
printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n",
@@ -1957,34 +1964,34 @@ int em28xx_register_analog_devices(struct em28xx *dev)
(EM28XX_VERSION_CODE >> 16) & 0xff,
(EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
+ /* set default norm */
+ dev->norm = em28xx_video_template.current_norm;
+ dev->width = norm_maxw(dev);
+ dev->height = norm_maxh(dev);
+ dev->interlaced = EM28XX_INTERLACED_DEFAULT;
+ dev->hscale = 0;
+ dev->vscale = 0;
+ dev->ctl_input = 0;
+
/* Analog specific initialization */
dev->format = &format[0];
- video_mux(dev, 0);
+ video_mux(dev, dev->ctl_input);
+
+ /* Audio defaults */
+ dev->mute = 1;
+ dev->volume = 0x1f;
/* enable vbi capturing */
/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
-/* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
+ val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
+ em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val));
em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
- dev->mute = 1; /* maybe not the right place... */
- dev->volume = 0x1f;
-
em28xx_set_outfmt(dev);
em28xx_colorlevels_set_default(dev);
em28xx_compression_disable(dev);
- /* set default norm */
- dev->norm = em28xx_video_template.current_norm;
- dev->width = norm_maxw(dev);
- dev->height = norm_maxh(dev);
- dev->interlaced = EM28XX_INTERLACED_DEFAULT;
- dev->hscale = 0;
- dev->vscale = 0;
-
- /* FIXME: This is a very bad hack! Not all devices have TV on input 2 */
- dev->ctl_input = 2;
-
/* allocate and fill video video_device struct */
dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
if (!dev->vdev) {
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 6c6b94aa05b..dd2cd36fb1b 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -94,7 +94,7 @@
#define EM2882_BOARD_KWORLD_VS_DVBT 54
#define EM2882_BOARD_TERRATEC_HYBRID_XS 55
#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56
-#define EM2883_BOARD_KWORLD_HYBRID_A316 57
+#define EM2883_BOARD_KWORLD_HYBRID_330U 57
#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
#define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61
@@ -300,13 +300,32 @@ enum em28xx_amux {
};
enum em28xx_aout {
+ /* AC97 outputs */
EM28XX_AOUT_MASTER = 1 << 0,
EM28XX_AOUT_LINE = 1 << 1,
EM28XX_AOUT_MONO = 1 << 2,
EM28XX_AOUT_LFE = 1 << 3,
EM28XX_AOUT_SURR = 1 << 4,
+
+ /* PCM IN Mixer - used by AC97_RECORD_SELECT register */
+ EM28XX_AOUT_PCM_IN = 1 << 7,
+
+ /* Bits 10-8 are used to indicate the PCM IN record select */
+ EM28XX_AOUT_PCM_MIC_PCM = 0 << 8,
+ EM28XX_AOUT_PCM_CD = 1 << 8,
+ EM28XX_AOUT_PCM_VIDEO = 2 << 8,
+ EM28XX_AOUT_PCM_AUX = 3 << 8,
+ EM28XX_AOUT_PCM_LINE = 4 << 8,
+ EM28XX_AOUT_PCM_STEREO = 5 << 8,
+ EM28XX_AOUT_PCM_MONO = 6 << 8,
+ EM28XX_AOUT_PCM_PHONE = 7 << 8,
};
+static inline int ac97_return_record_select(int a_out)
+{
+ return (a_out & 0x700) >> 8;
+}
+
struct em28xx_reg_seq {
int reg;
unsigned char val, mask;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 5e36b9a4ae3..65e4901f4db 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -422,8 +422,10 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
if (urb == NULL)
break;
+ BUG_ON(!gspca_dev->dev);
gspca_dev->urb[i] = NULL;
- usb_kill_urb(urb);
+ if (!gspca_dev->present)
+ usb_kill_urb(urb);
if (urb->transfer_buffer != NULL)
usb_buffer_free(gspca_dev->dev,
urb->transfer_buffer_length,
@@ -1949,9 +1951,12 @@ void gspca_disconnect(struct usb_interface *intf)
{
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+ mutex_lock(&gspca_dev->usb_lock);
gspca_dev->present = 0;
- gspca_dev->streaming = 0;
+ mutex_unlock(&gspca_dev->usb_lock);
+ destroy_urbs(gspca_dev);
+ gspca_dev->dev = NULL;
usb_set_intfdata(intf, NULL);
/* release the device */
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index e564a61a72d..48892b5715d 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -102,7 +102,11 @@ int s5k4aa_probe(struct sd *sd)
}
/* Test some registers, but we don't know their exact meaning yet */
- if (m5602_read_sensor(sd, 0x00, prod_id, sizeof(prod_id)))
+ if (m5602_read_sensor(sd, 0x00, prod_id, 2))
+ return -ENODEV;
+ if (m5602_read_sensor(sd, 0x02, prod_id+2, 2))
+ return -ENODEV;
+ if (m5602_read_sensor(sd, 0x04, prod_id+4, 2))
return -ENODEV;
if (memcmp(prod_id, expected_prod_id, sizeof(prod_id)))
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index e8e5921cdc3..c46c990987f 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -949,8 +949,10 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
itv->instance = atomic_inc_return(&ivtv_instance) - 1;
retval = v4l2_device_register(&dev->dev, &itv->device);
- if (retval)
+ if (retval) {
+ kfree(itv);
return retval;
+ }
/* "ivtv + PCI ID" is a bit of a mouthful, so use
"ivtv + instance" instead. */
snprintf(itv->device.name, sizeof(itv->device.name),
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index f6b3ef6e691..c13bd2aa0be 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -393,7 +393,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
return 0;
}
- v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
+ v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt);
vbifmt->service_set = ivtv_get_service_set(vbifmt);
return 0;
}
@@ -1748,6 +1748,18 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg)
break;
}
+ case IVTV_IOC_DMA_FRAME:
+ case VIDEO_GET_PTS:
+ case VIDEO_GET_FRAME_COUNT:
+ case VIDEO_GET_EVENT:
+ case VIDEO_PLAY:
+ case VIDEO_STOP:
+ case VIDEO_FREEZE:
+ case VIDEO_CONTINUE:
+ case VIDEO_COMMAND:
+ case VIDEO_TRY_COMMAND:
+ return ivtv_decoder_ioctls(file, cmd, (void *)arg);
+
default:
return -EINVAL;
}
@@ -1790,18 +1802,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
return 0;
- case IVTV_IOC_DMA_FRAME:
- case VIDEO_GET_PTS:
- case VIDEO_GET_FRAME_COUNT:
- case VIDEO_GET_EVENT:
- case VIDEO_PLAY:
- case VIDEO_STOP:
- case VIDEO_FREEZE:
- case VIDEO_CONTINUE:
- case VIDEO_COMMAND:
- case VIDEO_TRY_COMMAND:
- return ivtv_decoder_ioctls(filp, cmd, (void *)arg);
-
default:
break;
}
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 39fbc970f43..0d810189dd8 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -62,7 +62,6 @@
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
-#include <linux/version.h>
#include <asm/io.h>
#include "pwc.h"
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index a1d6008efcb..07c334f25aa 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1155,23 +1155,23 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
- const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL;
- const struct soc_camera_format_xlate *xlate;
+ const struct soc_camera_data_format *cam_fmt = NULL;
+ const struct soc_camera_format_xlate *xlate = NULL;
struct soc_camera_sense sense = {
.master_clock = pcdev->mclk,
.pixel_clock_max = pcdev->ciclk / 4,
};
- int ret, buswidth;
+ int ret;
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
+ if (pixfmt) {
+ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+ if (!xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ return -EINVAL;
+ }
- buswidth = xlate->buswidth;
- host_fmt = xlate->host_fmt;
- cam_fmt = xlate->cam_fmt;
+ cam_fmt = xlate->cam_fmt;
+ }
/* If PCLK is used to latch data from the sensor, check sense */
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
@@ -1201,8 +1201,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
}
if (pixfmt && !ret) {
- icd->buswidth = buswidth;
- icd->current_fmt = host_fmt;
+ icd->buswidth = xlate->buswidth;
+ icd->current_fmt = xlate->host_fmt;
}
return ret;
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index d6848f7a503..05221d47dd4 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -149,7 +149,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = {
{ SAA7127_REG_COPYGEN_0, 0x77 },
{ SAA7127_REG_COPYGEN_1, 0x41 },
{ SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */
- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e },
+ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf },
{ SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 },
{ SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 },
{ SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */
@@ -488,12 +488,18 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
break;
case SAA7127_OUTPUT_TYPE_COMPOSITE:
- state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
+ if (state->ident == V4L2_IDENT_SAA7129)
+ state->reg_2d = 0x20; /* CVBS only */
+ else
+ state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
case SAA7127_OUTPUT_TYPE_SVIDEO:
- state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */
+ if (state->ident == V4L2_IDENT_SAA7129)
+ state->reg_2d = 0x18; /* Y + C */
+ else
+ state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
@@ -508,7 +514,10 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
break;
case SAA7127_OUTPUT_TYPE_BOTH:
- state->reg_2d = 0xbf;
+ if (state->ident == V4L2_IDENT_SAA7129)
+ state->reg_2d = 0x38;
+ else
+ state->reg_2d = 0xbf;
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
@@ -731,24 +740,6 @@ static int saa7127_probe(struct i2c_client *client,
return -ENODEV;
}
- /* Configure Encoder */
-
- v4l2_dbg(1, debug, sd, "Configuring encoder\n");
- saa7127_write_inittab(sd, saa7127_init_config_common);
- saa7127_set_std(sd, V4L2_STD_NTSC);
- saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
- saa7127_set_vps(sd, &vbi);
- saa7127_set_wss(sd, &vbi);
- saa7127_set_cc(sd, &vbi);
- saa7127_set_xds(sd, &vbi);
- if (test_image == 1)
- /* The Encoder has an internal Colorbar generator */
- /* This can be used for debugging */
- saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
- else
- saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
- saa7127_set_video_enable(sd, 1);
-
if (id->driver_data) { /* Chip type is already known */
state->ident = id->driver_data;
} else { /* Needs detection */
@@ -770,6 +761,23 @@ static int saa7127_probe(struct i2c_client *client,
v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
client->addr << 1, client->adapter->name);
+
+ v4l2_dbg(1, debug, sd, "Configuring encoder\n");
+ saa7127_write_inittab(sd, saa7127_init_config_common);
+ saa7127_set_std(sd, V4L2_STD_NTSC);
+ saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
+ saa7127_set_vps(sd, &vbi);
+ saa7127_set_wss(sd, &vbi);
+ saa7127_set_cc(sd, &vbi);
+ saa7127_set_xds(sd, &vbi);
+ if (test_image == 1)
+ /* The Encoder has an internal Colorbar generator */
+ /* This can be used for debugging */
+ saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
+ else
+ saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
+ saa7127_set_video_enable(sd, 1);
+
if (state->ident == V4L2_IDENT_SAA7129)
saa7127_write_inittab(sd, saa7129_init_config_extra);
return 0;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 26194a0ce92..8b0b64a8987 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -990,10 +990,10 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
if (!enable[devnum])
return -ENODEV;
- card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t));
-
- if (card == NULL)
- return -ENOMEM;
+ err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
+ sizeof(snd_card_saa7134_t), &card);
+ if (err < 0)
+ return err;
strcpy(card->driver, "SAA7134");
@@ -1089,7 +1089,11 @@ static int saa7134_alsa_init(void)
list_for_each(list,&saa7134_devlist) {
dev = list_entry(list, struct saa7134_dev, devlist);
- alsa_device_init(dev);
+ if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
+ printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n",
+ dev->name, saa7134_boards[dev->board].name);
+ else
+ alsa_device_init(dev);
}
if (dev == NULL)
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index dfbe08a9ad9..99221d726ed 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -660,6 +660,10 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, 0);
+
+ /* Clear any stale IRQ reports */
+ saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT));
+
mutex_init(&dev->lock);
spin_lock_init(&dev->slock);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 0776ecf56d2..b5370b3e1a3 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -860,6 +860,7 @@ static struct zl10353_config behold_h6_config = {
.demod_address = 0x1e>>1,
.no_tuner = 1,
.parallel_ts = 1,
+ .disable_i2c_gate_ctrl = 1,
};
/* ==================================================================
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 454ad1dd750..88c5e942f75 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -30,7 +30,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 9a2586b07a0..ddcb81d0b81 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -603,21 +603,18 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
const struct soc_camera_format_xlate *xlate;
int ret;
+ if (!pixfmt)
+ return icd->ops->set_fmt(icd, pixfmt, rect);
+
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
- switch (pixfmt) {
- case 0: /* Only geometry change */
- ret = icd->ops->set_fmt(icd, pixfmt, rect);
- break;
- default:
- ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
- }
+ ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
- if (pixfmt && !ret) {
+ if (!ret) {
icd->buswidth = xlate->buswidth;
icd->current_fmt = xlate->host_fmt;
pcdev->camera_fmt = xlate->cam_fmt;
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 56f0c0eb500..00c6cbe06ab 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -242,7 +242,7 @@ static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct tda9875 *t = to_state(sd);
- int chvol=0, volume, balance, left, right;
+ int chvol = 0, volume = 0, balance = 0, left, right;
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 5aeccb301ce..076ed5bf48b 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
/* ---------------------------------------------------------------------- */
/* our structs */
-#define MAXREGS 64
+#define MAXREGS 256
struct CHIPSTATE;
typedef int (*getvalue)(int);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3b0b84c2e45..78277abb733 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -427,6 +427,9 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
memset(tvee, 0, sizeof(*tvee));
+ tvee->tuner_type = TUNER_ABSENT;
+ tvee->tuner2_type = TUNER_ABSENT;
+
done = len = beenhere = 0;
/* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index ac9aa40d09f..8e23aa53c29 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -1401,7 +1401,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
decoder->pdata = client->dev.platform_data;
if (!decoder->pdata) {
- v4l_err(client, "No platform data\n!!");
+ v4l_err(client, "No platform data!!\n");
return -ENODEV;
}
/*
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index 4f16effb530..f4522bb0891 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -21,7 +21,6 @@
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 4b712f69d1b..a5fb74bf240 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -21,7 +21,6 @@
* 02110-1301, USA.
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 9907b9aff2b..6b66ae4f430 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -157,7 +157,7 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
struct i2c_msg *pmsg;
struct usb_usbvision *usbvision;
int i, ret;
- unsigned char addr;
+ unsigned char addr = 0;
usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 2208165aa6f..d2576f6391c 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1,7 +1,7 @@
/*
* uvc_ctrl.c -- USB Video Class driver - Controls
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/uaccess.h>
@@ -29,7 +28,7 @@
#define UVC_CTRL_DATA_BACKUP 1
/* ------------------------------------------------------------------------
- * Control, formats, ...
+ * Controls
*/
static struct uvc_control_info uvc_ctrls[] = {
@@ -635,7 +634,7 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
mask = (1 << bits) - 1;
}
- /* Sign-extend the value if needed */
+ /* Sign-extend the value if needed. */
if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
value |= -(value & (1 << (mapping->size - 1)));
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 89d8bd10a85..b12873265cc 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1,7 +1,7 @@
/*
* uvc_driver.c -- USB Video Class driver
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
@@ -49,7 +48,7 @@ static unsigned int uvc_quirks_param;
unsigned int uvc_trace_param;
/* ------------------------------------------------------------------------
- * Control, formats, ...
+ * Video formats
*/
static struct uvc_format_desc uvc_fmts[] = {
@@ -474,7 +473,7 @@ static int uvc_parse_format(struct uvc_device *dev,
/* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
* completely. Observed behaviours range from setting the
- * value to 1.1x the actual frame size of hardwiring the
+ * value to 1.1x the actual frame size to hardwiring the
* 16 low bits to 0. This results in a higher than necessary
* memory usage as well as a wrong image size information. For
* uncompressed formats this can be fixed by computing the
@@ -487,7 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev,
/* Some bogus devices report dwMinFrameInterval equal to
* dwMaxFrameInterval and have dwFrameIntervalStep set to
* zero. Setting all null intervals to 1 fixes the problem and
- * some other divisions by zero which could happen.
+ * some other divisions by zero that could happen.
*/
for (i = 0; i < n; ++i) {
interval = get_unaligned_le32(&buffer[26+4*i]);
@@ -1200,13 +1199,13 @@ static void uvc_unregister_video(struct uvc_device *dev)
* Scan the UVC descriptors to locate a chain starting at an Output Terminal
* and containing the following units:
*
- * - a USB Streaming Output Terminal
+ * - one Output Terminal (USB Streaming or Display)
* - zero or one Processing Unit
* - zero, one or mode single-input Selector Units
* - zero or one multiple-input Selector Units, provided all inputs are
* connected to input terminals
* - zero, one or mode single-input Extension Units
- * - one Camera Input Terminal, or one or more External terminals.
+ * - one or more Input Terminals (Camera, External or USB Streaming)
*
* A side forward scan is made on each detected entity to check for additional
* extension units.
@@ -1531,10 +1530,6 @@ static int uvc_register_video(struct uvc_device *dev)
/* Set the driver data before calling video_register_device, otherwise
* uvc_v4l2_open might race us.
- *
- * FIXME: usb_set_intfdata hasn't been called so far. Is that a
- * problem ? Does any function which could be called here get
- * a pointer to the usb_interface ?
*/
dev->video.vdev = vdev;
video_set_drvdata(vdev, &dev->video);
@@ -1569,7 +1564,7 @@ void uvc_delete(struct kref *kref)
struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
struct list_head *p, *n;
- /* Unregister the video device */
+ /* Unregister the video device. */
uvc_unregister_video(dev);
usb_put_intf(dev->intf);
usb_put_dev(dev->udev);
@@ -1612,7 +1607,7 @@ static int uvc_probe(struct usb_interface *intf,
uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",
udev->devpath);
- /* Allocate memory for the device and initialize it */
+ /* Allocate memory for the device and initialize it. */
if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
return -ENOMEM;
@@ -1633,14 +1628,14 @@ static int uvc_probe(struct usb_interface *intf,
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
- /* Parse the Video Class control descriptor */
+ /* Parse the Video Class control descriptor. */
if (uvc_parse_control(dev) < 0) {
uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
"descriptors.\n");
goto error;
}
- uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n",
+ uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
dev->uvc_version >> 8, dev->uvc_version & 0xff,
udev->product ? udev->product : "<unnamed>",
le16_to_cpu(udev->descriptor.idVendor),
@@ -1653,18 +1648,18 @@ static int uvc_probe(struct usb_interface *intf,
"linux-uvc-devel mailing list.\n");
}
- /* Initialize controls */
+ /* Initialize controls. */
if (uvc_ctrl_init_device(dev) < 0)
goto error;
- /* Register the video devices */
+ /* Register the video devices. */
if (uvc_register_video(dev) < 0)
goto error;
- /* Save our data pointer in the interface data */
+ /* Save our data pointer in the interface data. */
usb_set_intfdata(intf, dev);
- /* Initialize the interrupt URB */
+ /* Initialize the interrupt URB. */
if ((ret = uvc_status_init(dev)) < 0) {
uvc_printk(KERN_INFO, "Unable to initialize the status "
"endpoint (%d), status interrupt will not be "
@@ -1839,24 +1834,24 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0 },
/* Apple Built-In iSight */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x05ac,
.idProduct = 0x8501,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_MINMAX
| UVC_QUIRK_BUILTIN_ISIGHT },
/* Genesys Logic USB 2.0 PC Camera */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x05e3,
- .idProduct = 0x0505,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .idVendor = 0x05e3,
+ .idProduct = 0x0505,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
index 37bdefdbead..436f462685a 100644
--- a/drivers/media/video/uvc/uvc_isight.c
+++ b/drivers/media/video/uvc/uvc_isight.c
@@ -3,6 +3,8 @@
*
* Copyright (C) 2006-2007
* Ivan N. Zlatev <contact@i-nz.net>
+ * Copyright (C) 2008-2009
+ * Laurent Pinchart <laurent.pinchart@skynet.be>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 42546342e97..0155752e4a5 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -1,7 +1,7 @@
/*
* uvc_queue.c -- USB Video Class driver - Buffers management
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/mm.h>
#include <linux/list.h>
#include <linux/module.h>
@@ -37,22 +36,22 @@
* to user space will return -EBUSY.
*
* Video buffers are managed using two queues. However, unlike most USB video
- * drivers which use an in queue and an out queue, we use a main queue which
- * holds all queued buffers (both 'empty' and 'done' buffers), and an irq
- * queue which holds empty buffers. This design (copied from video-buf)
- * minimizes locking in interrupt, as only one queue is shared between
- * interrupt and user contexts.
+ * drivers that use an in queue and an out queue, we use a main queue to hold
+ * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to
+ * hold empty buffers. This design (copied from video-buf) minimizes locking
+ * in interrupt, as only one queue is shared between interrupt and user
+ * contexts.
*
* Use cases
* ---------
*
- * Unless stated otherwise, all operations which modify the irq buffers queue
+ * Unless stated otherwise, all operations that modify the irq buffers queue
* are protected by the irq spinlock.
*
* 1. The user queues the buffers, starts streaming and dequeues a buffer.
*
* The buffers are added to the main and irq queues. Both operations are
- * protected by the queue lock, and the latert is protected by the irq
+ * protected by the queue lock, and the later is protected by the irq
* spinlock as well.
*
* The completion handler fetches a buffer from the irq queue and fills it
@@ -60,7 +59,7 @@
* returns immediately.
*
* When the buffer is full, the completion handler removes it from the irq
- * queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue.
+ * queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
* At that point, any process waiting on the buffer will be woken up. If a
* process tries to dequeue a buffer after it has been marked ready, the
* dequeing will succeed immediately.
@@ -91,8 +90,8 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
/*
* Allocate the video buffers.
*
- * Pages are reserved to make sure they will not be swaped, as they will be
- * filled in URB completion handler.
+ * Pages are reserved to make sure they will not be swapped, as they will be
+ * filled in the URB completion handler.
*
* Buffers will be individually mapped, so they must all be page aligned.
*/
@@ -210,8 +209,8 @@ int uvc_query_buffer(struct uvc_video_queue *queue,
__uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
done:
- mutex_unlock(&queue->mutex);
- return ret;
+ mutex_unlock(&queue->mutex);
+ return ret;
}
/*
@@ -236,7 +235,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
}
mutex_lock(&queue->mutex);
- if (v4l2_buf->index >= queue->count) {
+ if (v4l2_buf->index >= queue->count) {
uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
ret = -EINVAL;
goto done;
@@ -429,7 +428,7 @@ done:
* Cancel the video buffers queue.
*
* Cancelling the queue marks all buffers on the irq queue as erroneous,
- * wakes them up and remove them from the queue.
+ * wakes them up and removes them from the queue.
*
* If the disconnect parameter is set, further calls to uvc_queue_buffer will
* fail with -ENODEV.
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index 5d60b264d59..c705f248da8 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -1,7 +1,7 @@
/*
* uvc_status.c -- USB Video Class driver - Status endpoint
*
- * Copyright (C) 2007-2008
+ * Copyright (C) 2007-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
@@ -47,8 +46,8 @@ static int uvc_input_init(struct uvc_device *dev)
usb_to_input_id(udev, &input->id);
input->dev.parent = &dev->intf->dev;
- set_bit(EV_KEY, input->evbit);
- set_bit(BTN_0, input->keybit);
+ __set_bit(EV_KEY, input->evbit);
+ __set_bit(KEY_CAMERA, input->keybit);
if ((ret = input_register_device(input)) < 0)
goto error;
@@ -71,8 +70,10 @@ static void uvc_input_cleanup(struct uvc_device *dev)
static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
int value)
{
- if (dev->input)
+ if (dev->input) {
input_report_key(dev->input, code, value);
+ input_sync(dev->input);
+ }
}
#else
@@ -97,7 +98,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len)
return;
uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n",
data[1], data[3] ? "pressed" : "released", len);
- uvc_input_report_key(dev, BTN_0, data[3]);
+ uvc_input_report_key(dev, KEY_CAMERA, data[3]);
} else {
uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
"len %d.\n", data[1], data[2], data[3], len);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index fa150fff2c1..d681519d0c8 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -1,7 +1,7 @@
/*
* uvc_v4l2.c -- USB Video Class driver - V4L2 API
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@
* must be grouped (for instance the Red Balance, Blue Balance and Do White
* Balance V4L2 controls use the White Balance Component UVC control) or
* otherwise translated. The approach we take here is to use a translation
- * table for the controls which can be mapped directly, and handle the others
+ * table for the controls that can be mapped directly, and handle the others
* manually.
*/
static int uvc_v4l2_query_menu(struct uvc_video_device *video,
@@ -189,7 +189,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
probe->dwMaxVideoFrameSize =
video->streaming->ctrl.dwMaxVideoFrameSize;
- /* Probe the device */
+ /* Probe the device. */
if ((ret = uvc_probe_video(video, probe)) < 0)
goto done;
@@ -354,11 +354,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
*
* Each open instance of a UVC device can either be in a privileged or
* unprivileged state. Only a single instance can be in a privileged state at
- * a given time. Trying to perform an operation which requires privileges will
+ * a given time. Trying to perform an operation that requires privileges will
* automatically acquire the required privileges if possible, or return -EBUSY
* otherwise. Privileges are dismissed when closing the instance.
*
- * Operations which require privileges are:
+ * Operations that require privileges are:
*
* - VIDIOC_S_INPUT
* - VIDIOC_S_PARM
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index e7c31995527..9bc4705be78 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -1,7 +1,7 @@
/*
* uvc_video.c -- USB Video Class driver - Video handling
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
@@ -115,7 +114,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
ret = 0;
goto out;
- } else if (query == GET_DEF && probe == 1) {
+ } else if (query == GET_DEF && probe == 1 && ret != size) {
/* Many cameras don't support the GET_DEF request on their
* video probe control. Warn once and return, the caller will
* fall back to GET_CUR.
@@ -160,7 +159,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
}
/* Some broken devices return a null or wrong dwMaxVideoFrameSize.
- * Try to get the value from the format and frame descriptor.
+ * Try to get the value from the format and frame descriptors.
*/
uvc_fixup_buffer_size(video, ctrl);
ret = 0;
@@ -191,9 +190,6 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
*(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality);
*(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize);
*(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay);
- /* Note: Some of the fields below are not required for IN devices (see
- * UVC spec, 4.3.1.1), but we still copy them in case support for OUT
- * devices is added in the future. */
put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]);
put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]);
@@ -400,7 +396,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
*
* Empty buffers (bytesused == 0) don't trigger end of frame detection
* as it doesn't make sense to return an empty buffer. This also
- * avoids detecting and of frame conditions at FID toggling if the
+ * avoids detecting end of frame conditions at FID toggling if the
* previous payload had the EOF bit set.
*/
if (fid != video->last_fid && buf->buf.bytesused != 0) {
@@ -453,6 +449,17 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
}
}
+/* Video payload encoding is handled by uvc_video_encode_header() and
+ * uvc_video_encode_data(). Only bulk transfers are currently supported.
+ *
+ * uvc_video_encode_header is called at the start of a payload. It adds header
+ * data to the transfer buffer and returns the header size. As the only known
+ * UVC output device transfers a whole frame in a single payload, the EOF bit
+ * is always set in the header.
+ *
+ * uvc_video_encode_data is called for every URB and copies the data from the
+ * video buffer to the transfer buffer.
+ */
static int uvc_video_encode_header(struct uvc_video_device *video,
struct uvc_buffer *buf, __u8 *data, int len)
{
@@ -953,7 +960,7 @@ int uvc_video_suspend(struct uvc_video_device *video)
}
/*
- * Reconfigure the video interface and restart streaming if it was enable
+ * Reconfigure the video interface and restart streaming if it was enabled
* before suspend.
*
* If an error occurs, disable the video queue. This will wake all pending
@@ -985,8 +992,8 @@ int uvc_video_resume(struct uvc_video_device *video)
*/
/*
- * Initialize the UVC video device by retrieving the default format and
- * committing it.
+ * Initialize the UVC video device by switching to alternate setting 0 and
+ * retrieve the default format.
*
* Some cameras (namely the Fuji Finepix) set the format and frame
* indexes to zero. The UVC standard doesn't clearly make this a spec
@@ -1014,7 +1021,7 @@ int uvc_video_init(struct uvc_video_device *video)
*/
usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
- /* Some webcams don't suport GET_DEF request on the probe control. We
+ /* Some webcams don't suport GET_DEF requests on the probe control. We
* fall back to GET_CUR if GET_DEF fails.
*/
if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index bcf4361dc1b..027947ea9b6 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -72,149 +72,149 @@ struct uvc_xu_control {
* UVC constants
*/
-#define SC_UNDEFINED 0x00
-#define SC_VIDEOCONTROL 0x01
-#define SC_VIDEOSTREAMING 0x02
-#define SC_VIDEO_INTERFACE_COLLECTION 0x03
+#define SC_UNDEFINED 0x00
+#define SC_VIDEOCONTROL 0x01
+#define SC_VIDEOSTREAMING 0x02
+#define SC_VIDEO_INTERFACE_COLLECTION 0x03
-#define PC_PROTOCOL_UNDEFINED 0x00
+#define PC_PROTOCOL_UNDEFINED 0x00
-#define CS_UNDEFINED 0x20
-#define CS_DEVICE 0x21
-#define CS_CONFIGURATION 0x22
-#define CS_STRING 0x23
-#define CS_INTERFACE 0x24
-#define CS_ENDPOINT 0x25
+#define CS_UNDEFINED 0x20
+#define CS_DEVICE 0x21
+#define CS_CONFIGURATION 0x22
+#define CS_STRING 0x23
+#define CS_INTERFACE 0x24
+#define CS_ENDPOINT 0x25
/* VideoControl class specific interface descriptor */
-#define VC_DESCRIPTOR_UNDEFINED 0x00
-#define VC_HEADER 0x01
-#define VC_INPUT_TERMINAL 0x02
-#define VC_OUTPUT_TERMINAL 0x03
-#define VC_SELECTOR_UNIT 0x04
-#define VC_PROCESSING_UNIT 0x05
-#define VC_EXTENSION_UNIT 0x06
+#define VC_DESCRIPTOR_UNDEFINED 0x00
+#define VC_HEADER 0x01
+#define VC_INPUT_TERMINAL 0x02
+#define VC_OUTPUT_TERMINAL 0x03
+#define VC_SELECTOR_UNIT 0x04
+#define VC_PROCESSING_UNIT 0x05
+#define VC_EXTENSION_UNIT 0x06
/* VideoStreaming class specific interface descriptor */
-#define VS_UNDEFINED 0x00
-#define VS_INPUT_HEADER 0x01
-#define VS_OUTPUT_HEADER 0x02
-#define VS_STILL_IMAGE_FRAME 0x03
-#define VS_FORMAT_UNCOMPRESSED 0x04
-#define VS_FRAME_UNCOMPRESSED 0x05
-#define VS_FORMAT_MJPEG 0x06
-#define VS_FRAME_MJPEG 0x07
-#define VS_FORMAT_MPEG2TS 0x0a
-#define VS_FORMAT_DV 0x0c
-#define VS_COLORFORMAT 0x0d
-#define VS_FORMAT_FRAME_BASED 0x10
-#define VS_FRAME_FRAME_BASED 0x11
-#define VS_FORMAT_STREAM_BASED 0x12
+#define VS_UNDEFINED 0x00
+#define VS_INPUT_HEADER 0x01
+#define VS_OUTPUT_HEADER 0x02
+#define VS_STILL_IMAGE_FRAME 0x03
+#define VS_FORMAT_UNCOMPRESSED 0x04
+#define VS_FRAME_UNCOMPRESSED 0x05
+#define VS_FORMAT_MJPEG 0x06
+#define VS_FRAME_MJPEG 0x07
+#define VS_FORMAT_MPEG2TS 0x0a
+#define VS_FORMAT_DV 0x0c
+#define VS_COLORFORMAT 0x0d
+#define VS_FORMAT_FRAME_BASED 0x10
+#define VS_FRAME_FRAME_BASED 0x11
+#define VS_FORMAT_STREAM_BASED 0x12
/* Endpoint type */
-#define EP_UNDEFINED 0x00
-#define EP_GENERAL 0x01
-#define EP_ENDPOINT 0x02
-#define EP_INTERRUPT 0x03
+#define EP_UNDEFINED 0x00
+#define EP_GENERAL 0x01
+#define EP_ENDPOINT 0x02
+#define EP_INTERRUPT 0x03
/* Request codes */
-#define RC_UNDEFINED 0x00
-#define SET_CUR 0x01
-#define GET_CUR 0x81
-#define GET_MIN 0x82
-#define GET_MAX 0x83
-#define GET_RES 0x84
-#define GET_LEN 0x85
-#define GET_INFO 0x86
-#define GET_DEF 0x87
+#define RC_UNDEFINED 0x00
+#define SET_CUR 0x01
+#define GET_CUR 0x81
+#define GET_MIN 0x82
+#define GET_MAX 0x83
+#define GET_RES 0x84
+#define GET_LEN 0x85
+#define GET_INFO 0x86
+#define GET_DEF 0x87
/* VideoControl interface controls */
-#define VC_CONTROL_UNDEFINED 0x00
-#define VC_VIDEO_POWER_MODE_CONTROL 0x01
-#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
+#define VC_CONTROL_UNDEFINED 0x00
+#define VC_VIDEO_POWER_MODE_CONTROL 0x01
+#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
/* Terminal controls */
-#define TE_CONTROL_UNDEFINED 0x00
+#define TE_CONTROL_UNDEFINED 0x00
/* Selector Unit controls */
-#define SU_CONTROL_UNDEFINED 0x00
-#define SU_INPUT_SELECT_CONTROL 0x01
+#define SU_CONTROL_UNDEFINED 0x00
+#define SU_INPUT_SELECT_CONTROL 0x01
/* Camera Terminal controls */
-#define CT_CONTROL_UNDEFINED 0x00
-#define CT_SCANNING_MODE_CONTROL 0x01
-#define CT_AE_MODE_CONTROL 0x02
-#define CT_AE_PRIORITY_CONTROL 0x03
-#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
-#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
-#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
-#define CT_FOCUS_RELATIVE_CONTROL 0x07
-#define CT_FOCUS_AUTO_CONTROL 0x08
-#define CT_IRIS_ABSOLUTE_CONTROL 0x09
-#define CT_IRIS_RELATIVE_CONTROL 0x0a
-#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
-#define CT_ZOOM_RELATIVE_CONTROL 0x0c
-#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
-#define CT_PANTILT_RELATIVE_CONTROL 0x0e
-#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
-#define CT_ROLL_RELATIVE_CONTROL 0x10
-#define CT_PRIVACY_CONTROL 0x11
+#define CT_CONTROL_UNDEFINED 0x00
+#define CT_SCANNING_MODE_CONTROL 0x01
+#define CT_AE_MODE_CONTROL 0x02
+#define CT_AE_PRIORITY_CONTROL 0x03
+#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
+#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
+#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
+#define CT_FOCUS_RELATIVE_CONTROL 0x07
+#define CT_FOCUS_AUTO_CONTROL 0x08
+#define CT_IRIS_ABSOLUTE_CONTROL 0x09
+#define CT_IRIS_RELATIVE_CONTROL 0x0a
+#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
+#define CT_ZOOM_RELATIVE_CONTROL 0x0c
+#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
+#define CT_PANTILT_RELATIVE_CONTROL 0x0e
+#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
+#define CT_ROLL_RELATIVE_CONTROL 0x10
+#define CT_PRIVACY_CONTROL 0x11
/* Processing Unit controls */
-#define PU_CONTROL_UNDEFINED 0x00
-#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
-#define PU_BRIGHTNESS_CONTROL 0x02
-#define PU_CONTRAST_CONTROL 0x03
-#define PU_GAIN_CONTROL 0x04
-#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
-#define PU_HUE_CONTROL 0x06
-#define PU_SATURATION_CONTROL 0x07
-#define PU_SHARPNESS_CONTROL 0x08
-#define PU_GAMMA_CONTROL 0x09
-#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
-#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
-#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
-#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
-#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
-#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
-#define PU_HUE_AUTO_CONTROL 0x10
-#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
-#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
+#define PU_CONTROL_UNDEFINED 0x00
+#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
+#define PU_BRIGHTNESS_CONTROL 0x02
+#define PU_CONTRAST_CONTROL 0x03
+#define PU_GAIN_CONTROL 0x04
+#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
+#define PU_HUE_CONTROL 0x06
+#define PU_SATURATION_CONTROL 0x07
+#define PU_SHARPNESS_CONTROL 0x08
+#define PU_GAMMA_CONTROL 0x09
+#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
+#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
+#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
+#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
+#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
+#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
+#define PU_HUE_AUTO_CONTROL 0x10
+#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
+#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
#define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01
#define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02
#define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03
/* VideoStreaming interface controls */
-#define VS_CONTROL_UNDEFINED 0x00
-#define VS_PROBE_CONTROL 0x01
-#define VS_COMMIT_CONTROL 0x02
-#define VS_STILL_PROBE_CONTROL 0x03
-#define VS_STILL_COMMIT_CONTROL 0x04
-#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
-#define VS_STREAM_ERROR_CODE_CONTROL 0x06
-#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
-#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
-#define VS_SYNC_DELAY_CONTROL 0x09
-
-#define TT_VENDOR_SPECIFIC 0x0100
-#define TT_STREAMING 0x0101
+#define VS_CONTROL_UNDEFINED 0x00
+#define VS_PROBE_CONTROL 0x01
+#define VS_COMMIT_CONTROL 0x02
+#define VS_STILL_PROBE_CONTROL 0x03
+#define VS_STILL_COMMIT_CONTROL 0x04
+#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
+#define VS_STREAM_ERROR_CODE_CONTROL 0x06
+#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
+#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
+#define VS_SYNC_DELAY_CONTROL 0x09
+
+#define TT_VENDOR_SPECIFIC 0x0100
+#define TT_STREAMING 0x0101
/* Input Terminal types */
-#define ITT_VENDOR_SPECIFIC 0x0200
-#define ITT_CAMERA 0x0201
-#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
+#define ITT_VENDOR_SPECIFIC 0x0200
+#define ITT_CAMERA 0x0201
+#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
/* Output Terminal types */
-#define OTT_VENDOR_SPECIFIC 0x0300
-#define OTT_DISPLAY 0x0301
-#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
+#define OTT_VENDOR_SPECIFIC 0x0300
+#define OTT_DISPLAY 0x0301
+#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
/* External Terminal types */
-#define EXTERNAL_VENDOR_SPECIFIC 0x0400
-#define COMPOSITE_CONNECTOR 0x0401
-#define SVIDEO_CONNECTOR 0x0402
-#define COMPONENT_CONNECTOR 0x0403
+#define EXTERNAL_VENDOR_SPECIFIC 0x0400
+#define COMPOSITE_CONNECTOR 0x0401
+#define SVIDEO_CONNECTOR 0x0402
+#define COMPONENT_CONNECTOR 0x0403
#define UVC_TERM_INPUT 0x0000
#define UVC_TERM_OUTPUT 0x8000
@@ -541,11 +541,11 @@ struct uvc_streaming {
};
enum uvc_buffer_state {
- UVC_BUF_STATE_IDLE = 0,
- UVC_BUF_STATE_QUEUED = 1,
- UVC_BUF_STATE_ACTIVE = 2,
- UVC_BUF_STATE_DONE = 3,
- UVC_BUF_STATE_ERROR = 4,
+ UVC_BUF_STATE_IDLE = 0,
+ UVC_BUF_STATE_QUEUED = 1,
+ UVC_BUF_STATE_ACTIVE = 2,
+ UVC_BUF_STATE_DONE = 3,
+ UVC_BUF_STATE_ERROR = 4,
};
struct uvc_buffer {
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index cf9d4c7f571..8a4b74f3129 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -34,7 +34,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
spin_lock_init(&v4l2_dev->lock);
v4l2_dev->dev = dev;
snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
- dev->driver->name, dev->bus_id);
+ dev->driver->name, dev_name(dev));
dev_set_drvdata(dev, v4l2_dev);
return 0;
}
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index fbe9cc0d433..21208805ea9 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -28,13 +28,13 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
{
switch (cmd) {
case VIDIOC_QUERYCTRL:
- return v4l2_subdev_call(sd, core, querymenu, arg);
+ return v4l2_subdev_call(sd, core, queryctrl, arg);
case VIDIOC_G_CTRL:
return v4l2_subdev_call(sd, core, g_ctrl, arg);
case VIDIOC_S_CTRL:
return v4l2_subdev_call(sd, core, s_ctrl, arg);
case VIDIOC_QUERYMENU:
- return v4l2_subdev_call(sd, core, queryctrl, arg);
+ return v4l2_subdev_call(sd, core, querymenu, arg);
case VIDIOC_LOG_STATUS:
return v4l2_subdev_call(sd, core, log_status);
case VIDIOC_DBG_G_CHIP_IDENT:
diff --git a/drivers/media/video/zoran/Kconfig b/drivers/media/video/zoran/Kconfig
index 4ea5fa71de8..8666e19f31a 100644
--- a/drivers/media/video/zoran/Kconfig
+++ b/drivers/media/video/zoran/Kconfig
@@ -68,6 +68,7 @@ config VIDEO_ZORAN_AVS6EYES
tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1
select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO
help
Support for the AverMedia 6 Eyes video surveillance card.
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index 46b7ad477ce..e873a916250 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -349,7 +349,6 @@ struct card_info {
u16 i2c_decoder, i2c_encoder; /* I2C types */
u16 video_vfe, video_codec; /* videocodec types */
u16 audio_chip; /* audio type */
- u16 vendor_id, device_id; /* subsystem vendor/device ID */
int inputs; /* number of video inputs */
struct input {
@@ -401,7 +400,6 @@ struct zoran {
char name[32]; /* name of this device */
struct pci_dev *pci_dev; /* PCI device */
unsigned char revision; /* revision of zr36057 */
- unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */
unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
spinlock_t spinlock; /* Spinlock */
@@ -490,16 +488,10 @@ struct zoran {
wait_queue_head_t test_q;
};
-/*The following should be done in more portable way. It depends on define
- of _ALPHA_BUZ in the Makefile.*/
-
-#ifdef _ALPHA_BUZ
-#define btwrite(dat,adr) writel((dat), zr->zr36057_adr+(adr))
-#define btread(adr) readl(zr->zr36057_adr+(adr))
-#else
+/* There was something called _ALPHA_BUZ that used the PCI address instead of
+ * the kernel iomapped address for btread/btwrite. */
#define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr))
#define btread(adr) readl(zr->zr36057_mem+(adr))
-#endif
#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 05f39195372..5d2f090aa0f 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -61,17 +61,17 @@
extern const struct zoran_format zoran_formats[];
-static int card[BUZ_MAX] = { -1, -1, -1, -1 };
+static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "The type of card");
+MODULE_PARM_DESC(card, "Card type");
-static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
+static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(encoder, int, NULL, 0444);
-MODULE_PARM_DESC(encoder, "i2c TV encoder");
+MODULE_PARM_DESC(encoder, "Video encoder chip");
-static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
+static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(decoder, int, NULL, 0444);
-MODULE_PARM_DESC(decoder, "i2c TV decoder");
+MODULE_PARM_DESC(decoder, "Video decoder chip");
/*
The video mem address of the video card.
@@ -104,9 +104,9 @@ module_param(default_norm, int, 0444);
MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
/* /dev/videoN, -1 for autodetect */
-static int video_nr[BUZ_MAX] = {-1, -1, -1, -1};
+static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(video_nr, int, NULL, 0444);
-MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
+MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
/*
Number and size of grab buffers for Video 4 Linux
@@ -153,9 +153,21 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
MODULE_AUTHOR("Serguei Miridonov");
MODULE_LICENSE("GPL");
+#define ZR_DEVICE(subven, subdev, data) { \
+ .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
+ .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
+
+static struct pci_device_id zr36067_pci_tbl[] = {
+ ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus),
+ ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus),
+ ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
+ ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
+ ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
+ {0}
+};
+MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
-int zoran_num; /* number of Buzs in use */
-struct zoran *zoran[BUZ_MAX];
+static unsigned int zoran_num; /* number of cards found */
/* videocodec bus functions ZR36060 */
static u32
@@ -472,8 +484,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC10plus,
.name = "DC10plus",
- .vendor_id = PCI_VENDOR_ID_MIRO,
- .device_id = PCI_DEVICE_ID_MIRO_DC10PLUS,
.i2c_decoder = I2C_DRIVERID_SAA7110,
.i2c_encoder = I2C_DRIVERID_ADV7175,
.video_codec = CODEC_TYPE_ZR36060,
@@ -531,8 +541,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC30plus,
.name = "DC30plus",
- .vendor_id = PCI_VENDOR_ID_MIRO,
- .device_id = PCI_DEVICE_ID_MIRO_DC30PLUS,
.i2c_decoder = I2C_DRIVERID_VPX3220,
.i2c_encoder = I2C_DRIVERID_ADV7175,
.video_codec = CODEC_TYPE_ZR36050,
@@ -589,8 +597,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = LML33R10,
.name = "LML33R10",
- .vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH,
- .device_id = PCI_DEVICE_ID_LML_33R10,
.i2c_decoder = I2C_DRIVERID_SAA7114,
.i2c_encoder = I2C_DRIVERID_ADV7170,
.video_codec = CODEC_TYPE_ZR36060,
@@ -618,8 +624,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = BUZ,
.name = "Buz",
- .vendor_id = PCI_VENDOR_ID_IOMEGA,
- .device_id = PCI_DEVICE_ID_IOMEGA_BUZ,
.i2c_decoder = I2C_DRIVERID_SAA7111A,
.i2c_encoder = I2C_DRIVERID_SAA7185B,
.video_codec = CODEC_TYPE_ZR36060,
@@ -649,8 +653,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
.name = "6-Eyes",
/* AverMedia chose not to brand the 6-Eyes. Thus it
can't be autodetected, and requires card=x. */
- .vendor_id = -1,
- .device_id = -1,
.i2c_decoder = I2C_DRIVERID_KS0127,
.i2c_encoder = I2C_DRIVERID_BT866,
.video_codec = CODEC_TYPE_ZR36060,
@@ -1138,7 +1140,8 @@ zr36057_init (struct zoran *zr)
strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
if (err < 0)
- goto exit_unregister;
+ goto exit_free;
+ video_set_drvdata(zr->video_dev, zr);
zoran_init_hardware(zr);
if (zr36067_debug > 2)
@@ -1153,19 +1156,19 @@ zr36057_init (struct zoran *zr)
zr->initialized = 1;
return 0;
-exit_unregister:
- zoran_unregister_i2c(zr);
exit_free:
kfree(zr->stat_com);
kfree(zr->video_dev);
return err;
}
-static void
-zoran_release (struct zoran *zr)
+static void __devexit zoran_remove(struct pci_dev *pdev)
{
+ struct zoran *zr = pci_get_drvdata(pdev);
+
if (!zr->initialized)
goto exit_free;
+
/* unregister videocodec bus */
if (zr->codec) {
struct videocodec_master *master = zr->codec->master_data;
@@ -1194,6 +1197,7 @@ zoran_release (struct zoran *zr)
pci_disable_device(zr->pci_dev);
video_unregister_device(zr->video_dev);
exit_free:
+ pci_set_drvdata(pdev, NULL);
kfree(zr);
}
@@ -1256,338 +1260,329 @@ zoran_setup_videocodec (struct zoran *zr,
* Scan for a Buz card (actually for the PCI controller ZR36057),
* request the irq and map the io memory
*/
-static int __devinit
-find_zr36057 (void)
+static int __devinit zoran_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
unsigned char latency, need_latency;
struct zoran *zr;
- struct pci_dev *dev = NULL;
int result;
struct videocodec_master *master_vfe = NULL;
struct videocodec_master *master_codec = NULL;
int card_num;
char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
+ unsigned int nr;
- zoran_num = 0;
- while (zoran_num < BUZ_MAX &&
- (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
- card_num = card[zoran_num];
- zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
- if (!zr) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - kzalloc failed\n",
- ZORAN_NAME);
- continue;
- }
- zr->pci_dev = dev;
- //zr->zr36057_mem = NULL;
- zr->id = zoran_num;
- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
- spin_lock_init(&zr->spinlock);
- mutex_init(&zr->resource_lock);
- if (pci_enable_device(dev))
- goto zr_free_mem;
- zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
- pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
- &zr->revision);
- if (zr->revision < 2) {
- dprintk(1,
- KERN_INFO
- "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
- ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
- zr->zr36057_adr);
- if (card_num == -1) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
- ZR_DEVNAME(zr));
- goto zr_free_mem;
- }
- } else {
- int i;
- unsigned short ss_vendor, ss_device;
+ nr = zoran_num++;
+ if (nr >= BUZ_MAX) {
+ dprintk(1,
+ KERN_ERR
+ "%s: driver limited to %d card(s) maximum\n",
+ ZORAN_NAME, BUZ_MAX);
+ return -ENOENT;
+ }
- ss_vendor = zr->pci_dev->subsystem_vendor;
- ss_device = zr->pci_dev->subsystem_device;
+ zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
+ if (!zr) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - kzalloc failed\n",
+ ZORAN_NAME);
+ return -ENOMEM;
+ }
+ zr->pci_dev = pdev;
+ zr->id = nr;
+ snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
+ spin_lock_init(&zr->spinlock);
+ mutex_init(&zr->resource_lock);
+ if (pci_enable_device(pdev))
+ goto zr_free_mem;
+ pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
+
+ dprintk(1,
+ KERN_INFO
+ "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
+ ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision,
+ zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
+ if (zr->revision >= 2) {
+ dprintk(1,
+ KERN_INFO
+ "%s: Subsystem vendor=0x%04x id=0x%04x\n",
+ ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor,
+ zr->pci_dev->subsystem_device);
+ }
+
+ /* Use auto-detected card type? */
+ if (card[nr] == -1) {
+ if (zr->revision < 2) {
dprintk(1,
- KERN_INFO
- "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
- ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
- zr->zr36057_adr);
+ KERN_ERR
+ "%s: No card type specified, please use the card=X module parameter\n",
+ ZR_DEVNAME(zr));
dprintk(1,
- KERN_INFO
- "%s: subsystem vendor=0x%04x id=0x%04x\n",
- ZR_DEVNAME(zr), ss_vendor, ss_device);
- if (card_num == -1) {
- dprintk(3,
- KERN_DEBUG
- "%s: find_zr36057() - trying to autodetect card type\n",
- ZR_DEVNAME(zr));
- for (i=0;i<NUM_CARDS;i++) {
- if (ss_vendor == zoran_cards[i].vendor_id &&
- ss_device == zoran_cards[i].device_id) {
- dprintk(3,
- KERN_DEBUG
- "%s: find_zr36057() - card %s detected\n",
- ZR_DEVNAME(zr),
- zoran_cards[i].name);
- card_num = i;
- break;
- }
- }
- if (i == NUM_CARDS) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - unknown card\n",
- ZR_DEVNAME(zr));
- goto zr_free_mem;
- }
- }
- }
-
- if (card_num < 0 || card_num >= NUM_CARDS) {
- dprintk(2,
KERN_ERR
- "%s: find_zr36057() - invalid cardnum %d\n",
- ZR_DEVNAME(zr), card_num);
+ "%s: It is not possible to auto-detect ZR36057 based cards\n",
+ ZR_DEVNAME(zr));
goto zr_free_mem;
}
- /* even though we make this a non pointer and thus
- * theoretically allow for making changes to this struct
- * on a per-individual card basis at runtime, this is
- * strongly discouraged. This structure is intended to
- * keep general card information, no settings or anything */
- zr->card = zoran_cards[card_num];
- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
- "%s[%u]", zr->card.name, zr->id);
-
- zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
- if (!zr->zr36057_mem) {
+ card_num = ent->driver_data;
+ if (card_num >= NUM_CARDS) {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - ioremap failed\n",
+ "%s: Unknown card, try specifying card=X module parameter\n",
ZR_DEVNAME(zr));
goto zr_free_mem;
}
-
- result = request_irq(zr->pci_dev->irq,
- zoran_irq,
- IRQF_SHARED | IRQF_DISABLED,
- ZR_DEVNAME(zr),
- (void *) zr);
- if (result < 0) {
- if (result == -EINVAL) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - bad irq number or handler\n",
- ZR_DEVNAME(zr));
- } else if (result == -EBUSY) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
- ZR_DEVNAME(zr), zr->pci_dev->irq);
- } else {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - can't assign irq, error code %d\n",
- ZR_DEVNAME(zr), result);
- }
- goto zr_unmap;
- }
-
- /* set PCI latency timer */
- pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
- &latency);
- need_latency = zr->revision > 1 ? 32 : 48;
- if (latency != need_latency) {
- dprintk(2,
- KERN_INFO
- "%s: Changing PCI latency from %d to %d.\n",
- ZR_DEVNAME(zr), latency, need_latency);
- pci_write_config_byte(zr->pci_dev,
- PCI_LATENCY_TIMER,
- need_latency);
+ dprintk(3,
+ KERN_DEBUG
+ "%s: %s() - card %s detected\n",
+ ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name);
+ } else {
+ card_num = card[nr];
+ if (card_num >= NUM_CARDS || card_num < 0) {
+ dprintk(1,
+ KERN_ERR
+ "%s: User specified card type %d out of range (0 .. %d)\n",
+ ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
+ goto zr_free_mem;
}
+ }
- zr36057_restart(zr);
- /* i2c */
- dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
- ZR_DEVNAME(zr));
+ /* even though we make this a non pointer and thus
+ * theoretically allow for making changes to this struct
+ * on a per-individual card basis at runtime, this is
+ * strongly discouraged. This structure is intended to
+ * keep general card information, no settings or anything */
+ zr->card = zoran_cards[card_num];
+ snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
+ "%s[%u]", zr->card.name, zr->id);
+
+ zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
+ if (!zr->zr36057_mem) {
+ dprintk(1,
+ KERN_ERR
+ "%s: %s() - ioremap failed\n",
+ ZR_DEVNAME(zr), __func__);
+ goto zr_free_mem;
+ }
- /* i2c decoder */
- if (decoder[zr->id] != -1) {
- i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
- zr->card.i2c_decoder = decoder[zr->id];
- } else if (zr->card.i2c_decoder != 0) {
- i2c_dec_name =
- i2cid_to_modulename(zr->card.i2c_decoder);
+ result = request_irq(zr->pci_dev->irq, zoran_irq,
+ IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
+ if (result < 0) {
+ if (result == -EINVAL) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - bad irq number or handler\n",
+ ZR_DEVNAME(zr));
+ } else if (result == -EBUSY) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
+ ZR_DEVNAME(zr), zr->pci_dev->irq);
} else {
- i2c_dec_name = NULL;
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - can't assign irq, error code %d\n",
+ ZR_DEVNAME(zr), result);
}
+ goto zr_unmap;
+ }
- if (i2c_dec_name) {
- if ((result = request_module(i2c_dec_name)) < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load module %s: %d\n",
- ZR_DEVNAME(zr), i2c_dec_name, result);
- }
- }
+ /* set PCI latency timer */
+ pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+ &latency);
+ need_latency = zr->revision > 1 ? 32 : 48;
+ if (latency != need_latency) {
+ dprintk(2,
+ KERN_INFO
+ "%s: Changing PCI latency from %d to %d\n",
+ ZR_DEVNAME(zr), latency, need_latency);
+ pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+ need_latency);
+ }
- /* i2c encoder */
- if (encoder[zr->id] != -1) {
- i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
- zr->card.i2c_encoder = encoder[zr->id];
- } else if (zr->card.i2c_encoder != 0) {
- i2c_enc_name =
- i2cid_to_modulename(zr->card.i2c_encoder);
- } else {
- i2c_enc_name = NULL;
- }
+ zr36057_restart(zr);
+ /* i2c */
+ dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
+ ZR_DEVNAME(zr));
+
+ /* i2c decoder */
+ if (decoder[zr->id] != -1) {
+ i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
+ zr->card.i2c_decoder = decoder[zr->id];
+ } else if (zr->card.i2c_decoder != 0) {
+ i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
+ } else {
+ i2c_dec_name = NULL;
+ }
- if (i2c_enc_name) {
- if ((result = request_module(i2c_enc_name)) < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load module %s: %d\n",
- ZR_DEVNAME(zr), i2c_enc_name, result);
- }
+ if (i2c_dec_name) {
+ result = request_module(i2c_dec_name);
+ if (result < 0) {
+ dprintk(1,
+ KERN_ERR
+ "%s: failed to load module %s: %d\n",
+ ZR_DEVNAME(zr), i2c_dec_name, result);
}
+ }
+
+ /* i2c encoder */
+ if (encoder[zr->id] != -1) {
+ i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
+ zr->card.i2c_encoder = encoder[zr->id];
+ } else if (zr->card.i2c_encoder != 0) {
+ i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
+ } else {
+ i2c_enc_name = NULL;
+ }
- if (zoran_register_i2c(zr) < 0) {
+ if (i2c_enc_name) {
+ result = request_module(i2c_enc_name);
+ if (result < 0) {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - can't initialize i2c bus\n",
- ZR_DEVNAME(zr));
- goto zr_free_irq;
+ "%s: failed to load module %s: %d\n",
+ ZR_DEVNAME(zr), i2c_enc_name, result);
}
+ }
- dprintk(2,
- KERN_INFO "%s: Initializing videocodec bus...\n",
+ if (zoran_register_i2c(zr) < 0) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - can't initialize i2c bus\n",
ZR_DEVNAME(zr));
+ goto zr_free_irq;
+ }
- if (zr->card.video_codec != 0 &&
- (codec_name =
- codecid_to_modulename(zr->card.video_codec)) != NULL) {
- if ((result = request_module(codec_name)) < 0) {
+ dprintk(2,
+ KERN_INFO "%s: Initializing videocodec bus...\n",
+ ZR_DEVNAME(zr));
+
+ if (zr->card.video_codec) {
+ codec_name = codecid_to_modulename(zr->card.video_codec);
+ if (codec_name) {
+ result = request_module(codec_name);
+ if (result) {
dprintk(1,
KERN_ERR
"%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), codec_name, result);
}
}
- if (zr->card.video_vfe != 0 &&
- (vfe_name =
- codecid_to_modulename(zr->card.video_vfe)) != NULL) {
- if ((result = request_module(vfe_name)) < 0) {
+ }
+ if (zr->card.video_vfe) {
+ vfe_name = codecid_to_modulename(zr->card.video_vfe);
+ if (vfe_name) {
+ result = request_module(vfe_name);
+ if (result < 0) {
dprintk(1,
KERN_ERR
"%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), vfe_name, result);
}
}
+ }
- /* reset JPEG codec */
- jpeg_codec_sleep(zr, 1);
- jpeg_codec_reset(zr);
- /* video bus enabled */
- /* display codec revision */
- if (zr->card.video_codec != 0) {
- master_codec = zoran_setup_videocodec(zr,
- zr->card.video_codec);
- if (!master_codec)
- goto zr_unreg_i2c;
- zr->codec = videocodec_attach(master_codec);
- if (!zr->codec) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no codec found\n",
- ZR_DEVNAME(zr));
- goto zr_free_codec;
- }
- if (zr->codec->type != zr->card.video_codec) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - wrong codec\n",
- ZR_DEVNAME(zr));
- goto zr_detach_codec;
- }
+ /* reset JPEG codec */
+ jpeg_codec_sleep(zr, 1);
+ jpeg_codec_reset(zr);
+ /* video bus enabled */
+ /* display codec revision */
+ if (zr->card.video_codec != 0) {
+ master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
+ if (!master_codec)
+ goto zr_unreg_i2c;
+ zr->codec = videocodec_attach(master_codec);
+ if (!zr->codec) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - no codec found\n",
+ ZR_DEVNAME(zr));
+ goto zr_free_codec;
}
- if (zr->card.video_vfe != 0) {
- master_vfe = zoran_setup_videocodec(zr,
- zr->card.video_vfe);
- if (!master_vfe)
- goto zr_detach_codec;
- zr->vfe = videocodec_attach(master_vfe);
- if (!zr->vfe) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no VFE found\n",
- ZR_DEVNAME(zr));
- goto zr_free_vfe;
- }
- if (zr->vfe->type != zr->card.video_vfe) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() = wrong VFE\n",
- ZR_DEVNAME(zr));
- goto zr_detach_vfe;
- }
+ if (zr->codec->type != zr->card.video_codec) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - wrong codec\n",
+ ZR_DEVNAME(zr));
+ goto zr_detach_codec;
+ }
+ }
+ if (zr->card.video_vfe != 0) {
+ master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
+ if (!master_vfe)
+ goto zr_detach_codec;
+ zr->vfe = videocodec_attach(master_vfe);
+ if (!zr->vfe) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - no VFE found\n",
+ ZR_DEVNAME(zr));
+ goto zr_free_vfe;
+ }
+ if (zr->vfe->type != zr->card.video_vfe) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() = wrong VFE\n",
+ ZR_DEVNAME(zr));
+ goto zr_detach_vfe;
}
- /* Success so keep the pci_dev referenced */
- pci_dev_get(zr->pci_dev);
- zoran[zoran_num++] = zr;
- continue;
-
- // Init errors
- zr_detach_vfe:
- videocodec_detach(zr->vfe);
- zr_free_vfe:
- kfree(master_vfe);
- zr_detach_codec:
- videocodec_detach(zr->codec);
- zr_free_codec:
- kfree(master_codec);
- zr_unreg_i2c:
- zoran_unregister_i2c(zr);
- zr_free_irq:
- btwrite(0, ZR36057_SPGPPCR);
- free_irq(zr->pci_dev->irq, zr);
- zr_unmap:
- iounmap(zr->zr36057_mem);
- zr_free_mem:
- kfree(zr);
- continue;
}
- if (dev) /* Clean up ref count on early exit */
- pci_dev_put(dev);
- if (zoran_num == 0) {
- dprintk(1, KERN_INFO "No known MJPEG cards found.\n");
+ /* take care of Natoma chipset and a revision 1 zr36057 */
+ if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
+ zr->jpg_buffers.need_contiguous = 1;
+ dprintk(1,
+ KERN_INFO
+ "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
+ ZR_DEVNAME(zr));
}
- return zoran_num;
+
+ if (zr36057_init(zr) < 0)
+ goto zr_detach_vfe;
+
+ zoran_proc_init(zr);
+
+ pci_set_drvdata(pdev, zr);
+
+ return 0;
+
+zr_detach_vfe:
+ videocodec_detach(zr->vfe);
+zr_free_vfe:
+ kfree(master_vfe);
+zr_detach_codec:
+ videocodec_detach(zr->codec);
+zr_free_codec:
+ kfree(master_codec);
+zr_unreg_i2c:
+ zoran_unregister_i2c(zr);
+zr_free_irq:
+ btwrite(0, ZR36057_SPGPPCR);
+ free_irq(zr->pci_dev->irq, zr);
+zr_unmap:
+ iounmap(zr->zr36057_mem);
+zr_free_mem:
+ kfree(zr);
+
+ return -ENODEV;
}
-static int __init
-init_dc10_cards (void)
+static struct pci_driver zoran_driver = {
+ .name = "zr36067",
+ .id_table = zr36067_pci_tbl,
+ .probe = zoran_probe,
+ .remove = zoran_remove,
+};
+
+static int __init zoran_init(void)
{
- int i;
+ int res;
- memset(zoran, 0, sizeof(zoran));
printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
- /* Look for cards */
- if (find_zr36057() < 0) {
- return -EIO;
- }
- if (zoran_num == 0)
- return -ENODEV;
- dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME,
- zoran_num);
/* check the parameters we have been given, adjust if necessary */
if (v4l_nbufs < 2)
v4l_nbufs = 2;
@@ -1629,37 +1624,22 @@ init_dc10_cards (void)
ZORAN_NAME);
}
- /* take care of Natoma chipset and a revision 1 zr36057 */
- for (i = 0; i < zoran_num; i++) {
- struct zoran *zr = zoran[i];
-
- if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
- zr->jpg_buffers.need_contiguous = 1;
- dprintk(1,
- KERN_INFO
- "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
- ZR_DEVNAME(zr));
- }
-
- if (zr36057_init(zr) < 0) {
- for (i = 0; i < zoran_num; i++)
- zoran_release(zoran[i]);
- return -EIO;
- }
- zoran_proc_init(zr);
+ res = pci_register_driver(&zoran_driver);
+ if (res) {
+ dprintk(1,
+ KERN_ERR
+ "%s: Unable to register ZR36057 driver\n",
+ ZORAN_NAME);
+ return res;
}
return 0;
}
-static void __exit
-unload_dc10_cards (void)
+static void __exit zoran_exit(void)
{
- int i;
-
- for (i = 0; i < zoran_num; i++)
- zoran_release(zoran[i]);
+ pci_unregister_driver(&zoran_driver);
}
-module_init(init_dc10_cards);
-module_exit(unload_dc10_cards);
+module_init(zoran_init);
+module_exit(zoran_exit);
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h
index e4dc9d29b40..4507bdc5e33 100644
--- a/drivers/media/video/zoran/zoran_card.h
+++ b/drivers/media/video/zoran/zoran_card.h
@@ -40,8 +40,6 @@ extern int zr36067_debug;
/* Anybody who uses more than four? */
#define BUZ_MAX 4
-extern int zoran_num;
-extern struct zoran *zoran[BUZ_MAX];
extern struct video_device zoran_template;
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index b58b9dda715..120ef235e63 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1196,83 +1196,54 @@ zoran_close_end_session (struct file *file)
* Open a zoran card. Right now the flags stuff is just playing
*/
-static int
-zoran_open(struct file *file)
+static int zoran_open(struct file *file)
{
- unsigned int minor = video_devdata(file)->minor;
- struct zoran *zr = NULL;
+ struct zoran *zr = video_drvdata(file);
struct zoran_fh *fh;
- int i, res, first_open = 0, have_module_locks = 0;
+ int res, first_open = 0;
- lock_kernel();
- /* find the device */
- for (i = 0; i < zoran_num; i++) {
- if (zoran[i]->video_dev->minor == minor) {
- zr = zoran[i];
- break;
- }
- }
+ dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
+ ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
- if (!zr) {
- dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME);
- res = -ENODEV;
- goto open_unlock_and_return;
- }
+ lock_kernel();
/* see fs/device.c - the kernel already locks during open(),
* so locking ourselves only causes deadlocks */
/*mutex_lock(&zr->resource_lock);*/
+ if (zr->user >= 2048) {
+ dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
+ ZR_DEVNAME(zr), zr->user);
+ res = -EBUSY;
+ goto fail_unlock;
+ }
+
if (!zr->decoder) {
dprintk(1,
KERN_ERR "%s: no TV decoder loaded for device!\n",
ZR_DEVNAME(zr));
res = -EIO;
- goto open_unlock_and_return;
+ goto fail_unlock;
}
- /* try to grab a module lock */
- if (!try_module_get(THIS_MODULE)) {
- dprintk(1,
- KERN_ERR
- "%s: failed to acquire my own lock! PANIC!\n",
- ZR_DEVNAME(zr));
- res = -ENODEV;
- goto open_unlock_and_return;
- }
if (!try_module_get(zr->decoder->driver->driver.owner)) {
dprintk(1,
KERN_ERR
- "%s: failed to grab ownership of i2c decoder\n",
+ "%s: failed to grab ownership of video decoder\n",
ZR_DEVNAME(zr));
res = -EIO;
- module_put(THIS_MODULE);
- goto open_unlock_and_return;
+ goto fail_unlock;
}
if (zr->encoder &&
!try_module_get(zr->encoder->driver->driver.owner)) {
dprintk(1,
KERN_ERR
- "%s: failed to grab ownership of i2c encoder\n",
+ "%s: failed to grab ownership of video encoder\n",
ZR_DEVNAME(zr));
res = -EIO;
- module_put(zr->decoder->driver->driver.owner);
- module_put(THIS_MODULE);
- goto open_unlock_and_return;
+ goto fail_decoder;
}
- have_module_locks = 1;
-
- if (zr->user >= 2048) {
- dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
- ZR_DEVNAME(zr), zr->user);
- res = -EBUSY;
- goto open_unlock_and_return;
- }
-
- dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
-
/* now, create the open()-specific file_ops struct */
fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
if (!fh) {
@@ -1281,7 +1252,7 @@ zoran_open(struct file *file)
"%s: zoran_open() - allocation of zoran_fh failed\n",
ZR_DEVNAME(zr));
res = -ENOMEM;
- goto open_unlock_and_return;
+ goto fail_encoder;
}
/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
* on norm-change! */
@@ -1292,9 +1263,8 @@ zoran_open(struct file *file)
KERN_ERR
"%s: zoran_open() - allocation of overlay_mask failed\n",
ZR_DEVNAME(zr));
- kfree(fh);
res = -ENOMEM;
- goto open_unlock_and_return;
+ goto fail_fh;
}
if (zr->user++ == 0)
@@ -1319,22 +1289,19 @@ zoran_open(struct file *file)
return 0;
-open_unlock_and_return:
- /* if we grabbed locks, release them accordingly */
- if (have_module_locks) {
- module_put(zr->decoder->driver->driver.owner);
- if (zr->encoder) {
- module_put(zr->encoder->driver->driver.owner);
- }
- module_put(THIS_MODULE);
- }
-
- /* if there's no device found, we didn't obtain the lock either */
- if (zr) {
- /*mutex_unlock(&zr->resource_lock);*/
- }
+fail_fh:
+ kfree(fh);
+fail_encoder:
+ if (zr->encoder)
+ module_put(zr->encoder->driver->driver.owner);
+fail_decoder:
+ module_put(zr->decoder->driver->driver.owner);
+fail_unlock:
unlock_kernel();
+ dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
+ ZR_DEVNAME(zr), res, zr->user);
+
return res;
}
@@ -1344,8 +1311,8 @@ zoran_close(struct file *file)
struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
- dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
+ dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
+ ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
/* kernel locks (fs/device.c), so don't do that ourselves
* (prevents deadlocks) */
@@ -1391,10 +1358,8 @@ zoran_close(struct file *file)
/* release locks on the i2c modules */
module_put(zr->decoder->driver->driver.owner);
- if (zr->encoder) {
- module_put(zr->encoder->driver->driver.owner);
- }
- module_put(THIS_MODULE);
+ if (zr->encoder)
+ module_put(zr->encoder->driver->driver.owner);
/*mutex_unlock(&zr->resource_lock);*/
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
index 10b6ef75872..11c0f461320 100644
--- a/drivers/message/fusion/lsi/mpi.h
+++ b/drivers/message/fusion/lsi/mpi.h
@@ -6,7 +6,7 @@
* Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000
*
- * mpi.h Version: 01.05.13
+ * mpi.h Version: 01.05.16
*
* Version History
* ---------------
@@ -79,6 +79,9 @@
* 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
* 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT.
* 05-24-07 01.05.13 Bumped MPI_HEADER_VERSION_UNIT.
+ * 08-07-07 01.05.14 Bumped MPI_HEADER_VERSION_UNIT.
+ * 01-15-08 01.05.15 Bumped MPI_HEADER_VERSION_UNIT.
+ * 03-28-08 01.05.16 Bumped MPI_HEADER_VERSION_UNIT.
* --------------------------------------------------------------------------
*/
@@ -109,7 +112,7 @@
/* Note: The major versions of 0xe0 through 0xff are reserved */
/* versioning for this MPI header set */
-#define MPI_HEADER_VERSION_UNIT (0x10)
+#define MPI_HEADER_VERSION_UNIT (0x13)
#define MPI_HEADER_VERSION_DEV (0x00)
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
index b2db3330c59..013c7d88194 100644
--- a/drivers/message/fusion/lsi/mpi_cnfg.h
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h
@@ -6,7 +6,7 @@
* Title: MPI Config message, structures, and Pages
* Creation Date: July 27, 2000
*
- * mpi_cnfg.h Version: 01.05.15
+ * mpi_cnfg.h Version: 01.05.18
*
* Version History
* ---------------
@@ -308,6 +308,20 @@
* Expander Page 0 Flags field.
* Fixed define for
* MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED.
+ * 08-07-07 01.05.16 Added MPI_IOCPAGE6_CAP_FLAGS_MULTIPORT_DRIVE_SUPPORT
+ * define.
+ * Added BIOS Page 4 structure.
+ * Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID
+ * Physcial Disk Page 1.
+ * 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of
+ * Manufacturing Page 4.
+ * Added Solid State Drives Supported bit to IOC Page 6
+ * Capabilities Flags.
+ * Added new value for AccessStatus field of SAS Device
+ * Page 0 (_SATA_NEEDS_INITIALIZATION).
+ * 03-28-08 01.05.18 Defined new bits in Manufacturing Page 4 ExtFlags field
+ * to control coercion size and the mixing of SAS and SATA
+ * SSD drives.
* --------------------------------------------------------------------------
*/
@@ -686,6 +700,14 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01)
/* defines for the ExtFlags field */
+#define MPI_MANPAGE4_EXTFLAGS_MASK_COERCION_SIZE (0x0180)
+#define MPI_MANPAGE4_EXTFLAGS_SHIFT_COERCION_SIZE (7)
+#define MPI_MANPAGE4_EXTFLAGS_1GB_COERCION_SIZE (0)
+#define MPI_MANPAGE4_EXTFLAGS_128MB_COERCION_SIZE (1)
+
+#define MPI_MANPAGE4_EXTFLAGS_NO_MIX_SSD_SAS_SATA (0x0040)
+#define MPI_MANPAGE4_EXTFLAGS_MIX_SSD_AND_NON_SSD (0x0020)
+#define MPI_MANPAGE4_EXTFLAGS_DUAL_PORT_SUPPORT (0x0010)
#define MPI_MANPAGE4_EXTFLAGS_HIDE_NON_IR_METADATA (0x0008)
#define MPI_MANPAGE4_EXTFLAGS_SAS_CACHE_DISABLE (0x0004)
#define MPI_MANPAGE4_EXTFLAGS_SATA_CACHE_DISABLE (0x0002)
@@ -1159,6 +1181,8 @@ typedef struct _CONFIG_PAGE_IOC_6
/* IOC Page 6 Capabilities Flags */
+#define MPI_IOCPAGE6_CAP_FLAGS_SSD_SUPPORT (0x00000020)
+#define MPI_IOCPAGE6_CAP_FLAGS_MULTIPORT_DRIVE_SUPPORT (0x00000010)
#define MPI_IOCPAGE6_CAP_FLAGS_DISABLE_SMART_POLLING (0x00000008)
#define MPI_IOCPAGE6_CAP_FLAGS_MASK_METADATA_SIZE (0x00000006)
@@ -1428,6 +1452,15 @@ typedef struct _CONFIG_PAGE_BIOS_2
#define MPI_BIOSPAGE2_FORM_SAS_WWN (0x05)
#define MPI_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06)
+typedef struct _CONFIG_PAGE_BIOS_4
+{
+ CONFIG_PAGE_HEADER Header; /* 00h */
+ U64 ReassignmentBaseWWID; /* 04h */
+} CONFIG_PAGE_BIOS_4, MPI_POINTER PTR_CONFIG_PAGE_BIOS_4,
+ BIOSPage4_t, MPI_POINTER pBIOSPage4_t;
+
+#define MPI_BIOSPAGE4_PAGEVERSION (0x00)
+
/****************************************************************************
* SCSI Port Config Pages
@@ -2419,6 +2452,15 @@ typedef struct _RAID_PHYS_DISK1_PATH
#define MPI_RAID_PHYSDISK1_FLAG_BROKEN (0x0002)
#define MPI_RAID_PHYSDISK1_FLAG_INVALID (0x0001)
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.PageLength or NumPhysDiskPaths at runtime.
+ */
+#ifndef MPI_RAID_PHYS_DISK1_PATH_MAX
+#define MPI_RAID_PHYS_DISK1_PATH_MAX (1)
+#endif
+
typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_1
{
CONFIG_PAGE_HEADER Header; /* 00h */
@@ -2426,7 +2468,7 @@ typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_1
U8 PhysDiskNum; /* 05h */
U16 Reserved2; /* 06h */
U32 Reserved1; /* 08h */
- RAID_PHYS_DISK1_PATH Path[1]; /* 0Ch */
+ RAID_PHYS_DISK1_PATH Path[MPI_RAID_PHYS_DISK1_PATH_MAX];/* 0Ch */
} CONFIG_PAGE_RAID_PHYS_DISK_1, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_1,
RaidPhysDiskPage1_t, MPI_POINTER pRaidPhysDiskPage1_t;
@@ -2844,6 +2886,7 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_0
#define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01)
#define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02)
#define MPI_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT (0x03)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION (0x04)
/* specific values for SATA Init failures */
#define MPI_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN (0x10)
#define MPI_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT (0x11)
diff --git a/drivers/message/fusion/lsi/mpi_fc.h b/drivers/message/fusion/lsi/mpi_fc.h
index 627acfbb862..7d663ce76f8 100644
--- a/drivers/message/fusion/lsi/mpi_fc.h
+++ b/drivers/message/fusion/lsi/mpi_fc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2004 LSI Corporation.
+ * Copyright (c) 2000-2008 LSI Corporation.
*
*
* Name: mpi_fc.h
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
index 3f15fcfe4a2..693e4b51135 100644
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -3,28 +3,28 @@
MPI Header File Change History
==============================
- Copyright (c) 2000-2007 LSI Corporation.
+ Copyright (c) 2000-2008 LSI Corporation.
---------------------------------------
- Header Set Release Version: 01.05.16
- Header Set Release Date: 05-24-07
+ Header Set Release Version: 01.05.19
+ Header Set Release Date: 03-28-08
---------------------------------------
Filename Current version Prior version
---------- --------------- -------------
- mpi.h 01.05.13 01.05.12
- mpi_ioc.h 01.05.14 01.05.13
- mpi_cnfg.h 01.05.15 01.05.14
+ mpi.h 01.05.16 01.05.15
+ mpi_ioc.h 01.05.16 01.05.15
+ mpi_cnfg.h 01.05.18 01.05.17
mpi_init.h 01.05.09 01.05.09
mpi_targ.h 01.05.06 01.05.06
mpi_fc.h 01.05.01 01.05.01
mpi_lan.h 01.05.01 01.05.01
- mpi_raid.h 01.05.03 01.05.03
+ mpi_raid.h 01.05.05 01.05.05
mpi_tool.h 01.05.03 01.05.03
mpi_inb.h 01.05.01 01.05.01
- mpi_sas.h 01.05.04 01.05.04
+ mpi_sas.h 01.05.05 01.05.05
mpi_type.h 01.05.02 01.05.02
- mpi_history.txt 01.05.14 01.05.14
+ mpi_history.txt 01.05.19 01.05.18
* Date Version Description
@@ -96,6 +96,9 @@ mpi.h
* 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
* 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT.
* 05-24-07 01.05.13 Bumped MPI_HEADER_VERSION_UNIT.
+ * 08-07-07 01.05.14 Bumped MPI_HEADER_VERSION_UNIT.
+ * 01-15-08 01.05.15 Bumped MPI_HEADER_VERSION_UNIT.
+ * 03-28-08 01.05.16 Bumped MPI_HEADER_VERSION_UNIT.
* --------------------------------------------------------------------------
mpi_ioc.h
@@ -127,7 +130,7 @@ mpi_ioc.h
* 08-08-01 01.02.01 Original release for v1.2 work.
* New format for FWVersion and ProductId in
* MSG_IOC_FACTS_REPLY and MPI_FW_HEADER.
- * 08-31-01 01.02.02 Added event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and
+ * 08-31-01 01.02.02 Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and
* related structure and defines.
* Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED.
* Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE.
@@ -187,7 +190,7 @@ mpi_ioc.h
* 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED.
* Added MaxInitiators field to PortFacts reply.
* Added SAS Device Status Change ReasonCode for
- * asynchronous notification.
+ * asynchronous notificaiton.
* Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event
* data structure.
* Added new ImageType values for FWDownload and FWUpload
@@ -199,6 +202,16 @@ mpi_ioc.h
* added _MULTI_PORT_DOMAIN.
* 05-24-07 01.05.14 Added Common Boot Block type to FWDownload Request.
* Added Common Boot Block type to FWUpload Request.
+ * 08-07-07 01.05.15 Added MPI_EVENT_SAS_INIT_RC_REMOVED define.
+ * Added MPI_EVENT_IR2_RC_DUAL_PORT_ADDED and
+ * MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED for IR2 event data.
+ * Added SASAddress field to SAS Initiator Device Table
+ * Overflow event data structure.
+ * 03-28-08 01.05.16 Added two new ReasonCode values to SAS Device Status
+ * Change Event data to indicate completion of internally
+ * generated task management.
+ * Added MPI_EVENT_DSCVRY_ERR_DS_SATA_INIT_FAILURE define.
+ * Added MPI_EVENT_SAS_INIT_RC_INACCESSIBLE define.
* --------------------------------------------------------------------------
mpi_cnfg.h
@@ -213,7 +226,7 @@ mpi_cnfg.h
* Added _RESPONSE_ID_MASK definition to SCSI_PORT_1
* page and updated the page version.
* Added Information field and _INFO_PARAMS_NEGOTIATED
- * definition to SCSI_DEVICE_0 page.
+ * definitionto SCSI_DEVICE_0 page.
* 06-22-00 01.00.03 Removed batch controls from LAN_0 page and updated the
* page version.
* Added BucketsRemaining to LAN_1 page, redefined the
@@ -496,6 +509,20 @@ mpi_cnfg.h
* Expander Page 0 Flags field.
* Fixed define for
* MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED.
+ * 08-07-07 01.05.16 Added MPI_IOCPAGE6_CAP_FLAGS_MULTIPORT_DRIVE_SUPPORT
+ * define.
+ * Added BIOS Page 4 structure.
+ * Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID
+ * Physcial Disk Page 1.
+ * 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of
+ * Manufacturing Page 4.
+ * Added Solid State Drives Supported bit to IOC Page 6
+ * Capabilities Flags.
+ * Added new value for AccessStatus field of SAS Device
+ * Page 0 (_SATA_NEEDS_INITIALIZATION).
+ * 03-28-08 01.05.18 Defined new bits in Manufacturing Page 4 ExtFlags field
+ * to control coercion size and the mixing of SAS and SATA
+ * SSD drives.
* --------------------------------------------------------------------------
mpi_init.h
@@ -661,6 +688,9 @@ mpi_raid.h
* _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE.
* 02-28-07 01.05.03 Added new RAID Action, Device FW Update Mode, and
* associated defines.
+ * 08-07-07 01.05.04 Added Disable Full Rebuild bit to the ActionDataWord
+ * for the RAID Action MPI_RAID_ACTION_DISABLE_VOLUME.
+ * 01-15-08 01.05.05 Added define for MPI_RAID_ACTION_SET_VOLUME_NAME.
* --------------------------------------------------------------------------
mpi_tool.h
@@ -694,6 +724,10 @@ mpi_sas.h
* reply.
* 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO
* Unit Control request.
+ * 01-15-08 01.05.05 Added support for MPI_SAS_OP_SET_IOC_PARAMETER,
+ * including adding IOCParameter and IOCParameter value
+ * fields to SAS IO Unit Control Request.
+ * Added MPI_SAS_DEVICE_INFO_PRODUCT_SPECIFIC define.
* --------------------------------------------------------------------------
mpi_type.h
@@ -709,20 +743,20 @@ mpi_type.h
mpi_history.txt Parts list history
-Filename 01.05.15 01.05.15
----------- -------- --------
-mpi.h 01.05.12 01.05.13
-mpi_ioc.h 01.05.13 01.05.14
-mpi_cnfg.h 01.05.14 01.05.15
-mpi_init.h 01.05.09 01.05.09
-mpi_targ.h 01.05.06 01.05.06
-mpi_fc.h 01.05.01 01.05.01
-mpi_lan.h 01.05.01 01.05.01
-mpi_raid.h 01.05.03 01.05.03
-mpi_tool.h 01.05.03 01.05.03
-mpi_inb.h 01.05.01 01.05.01
-mpi_sas.h 01.05.04 01.05.04
-mpi_type.h 01.05.02 01.05.02
+Filename 01.05.19 01.05.18 01.05.17 01.05.16 01.05.15
+---------- -------- -------- -------- -------- --------
+mpi.h 01.05.16 01.05.15 01.05.14 01.05.13 01.05.12
+mpi_ioc.h 01.05.16 01.05.15 01.05.15 01.05.14 01.05.13
+mpi_cnfg.h 01.05.18 01.05.17 01.05.16 01.05.15 01.05.14
+mpi_init.h 01.05.09 01.05.09 01.05.09 01.05.09 01.05.09
+mpi_targ.h 01.05.06 01.05.06 01.05.06 01.05.06 01.05.06
+mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_raid.h 01.05.05 01.05.05 01.05.04 01.05.03 01.05.03
+mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03
+mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_sas.h 01.05.05 01.05.05 01.05.04 01.05.04 01.05.04
+mpi_type.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02
Filename 01.05.14 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09
---------- -------- -------- -------- -------- -------- --------
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
index a9e3693601a..4295d062caa 100644
--- a/drivers/message/fusion/lsi/mpi_init.h
+++ b/drivers/message/fusion/lsi/mpi_init.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2007 LSI Corporation.
+ * Copyright (c) 2000-2008 LSI Corporation.
*
*
* Name: mpi_init.h
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
index 5cbb6bd048e..8faa4fab7b8 100644
--- a/drivers/message/fusion/lsi/mpi_ioc.h
+++ b/drivers/message/fusion/lsi/mpi_ioc.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2007 LSI Corporation.
+ * Copyright (c) 2000-2008 LSI Corporation.
*
*
* Name: mpi_ioc.h
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: August 11, 2000
*
- * mpi_ioc.h Version: 01.05.14
+ * mpi_ioc.h Version: 01.05.16
*
* Version History
* ---------------
@@ -113,6 +113,16 @@
* added _MULTI_PORT_DOMAIN.
* 05-24-07 01.05.14 Added Common Boot Block type to FWDownload Request.
* Added Common Boot Block type to FWUpload Request.
+ * 08-07-07 01.05.15 Added MPI_EVENT_SAS_INIT_RC_REMOVED define.
+ * Added MPI_EVENT_IR2_RC_DUAL_PORT_ADDED and
+ * MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED for IR2 event data.
+ * Added SASAddress field to SAS Initiator Device Table
+ * Overflow event data structure.
+ * 03-28-08 01.05.16 Added two new ReasonCode values to SAS Device Status
+ * Change Event data to indicate completion of internally
+ * generated task management.
+ * Added MPI_EVENT_DSCVRY_ERR_DS_SATA_INIT_FAILURE define.
+ * Added MPI_EVENT_SAS_INIT_RC_INACCESSIBLE define.
* --------------------------------------------------------------------------
*/
@@ -612,6 +622,8 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
#define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B)
#define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C)
#define MPI_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D)
+#define MPI_EVENT_SAS_DEV_STAT_RC_CMPL_INTERNAL_DEV_RESET (0x0E)
+#define MPI_EVENT_SAS_DEV_STAT_RC_CMPL_TASK_ABORT_INTERNAL (0x0F)
/* SCSI Event data for Queue Full event */
@@ -708,6 +720,8 @@ typedef struct _MPI_EVENT_DATA_IR2
#define MPI_EVENT_IR2_RC_PD_REMOVED (0x05)
#define MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED (0x06)
#define MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR (0x07)
+#define MPI_EVENT_IR2_RC_DUAL_PORT_ADDED (0x08)
+#define MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED (0x09)
/* defines for logical disk states */
#define MPI_LD_STATE_OPTIMAL (0x00)
@@ -867,6 +881,7 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR
#define MPI_EVENT_DSCVRY_ERR_DS_UNSUPPORTED_DEVICE (0x00000800)
#define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000)
#define MPI_EVENT_DSCVRY_ERR_DS_MULTI_PORT_DOMAIN (0x00002000)
+#define MPI_EVENT_DSCVRY_ERR_DS_SATA_INIT_FAILURE (0x00004000)
/* SAS SMP Error Event data */
@@ -902,6 +917,8 @@ typedef struct _EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE
/* defines for the ReasonCode field of the SAS Initiator Device Status Change event */
#define MPI_EVENT_SAS_INIT_RC_ADDED (0x01)
+#define MPI_EVENT_SAS_INIT_RC_REMOVED (0x02)
+#define MPI_EVENT_SAS_INIT_RC_INACCESSIBLE (0x03)
/* SAS Initiator Device Table Overflow Event data */
@@ -910,6 +927,7 @@ typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW
U8 MaxInit; /* 00h */
U8 CurrentInit; /* 01h */
U16 Reserved1; /* 02h */
+ U64 SASAddress; /* 04h */
} EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
MPI_POINTER PTR_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
MpiEventDataSasInitTableOverflow_t,
diff --git a/drivers/message/fusion/lsi/mpi_lan.h b/drivers/message/fusion/lsi/mpi_lan.h
index 03253b53b78..f41fcb69b35 100644
--- a/drivers/message/fusion/lsi/mpi_lan.h
+++ b/drivers/message/fusion/lsi/mpi_lan.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2004 LSI Corporation.
+ * Copyright (c) 2000-2008 LSI Corporation.
*
*
* Name: mpi_lan.h
diff --git a/drivers/message/fusion/lsi/mpi_log_fc.h b/drivers/message/fusion/lsi/mpi_log_fc.h
index e4dafcefeec..face6e7acc7 100644
--- a/drivers/message/fusion/lsi/mpi_log_fc.h
+++ b/drivers/message/fusion/lsi/mpi_log_fc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2001 LSI Corporation. All rights reserved.
+ * Copyright (c) 2000-2008 LSI Corporation. All rights reserved.
*
* NAME: fc_log.h
* SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h
index af9da03e95e..691620dbedd 100644
--- a/drivers/message/fusion/lsi/mpi_log_sas.h
+++ b/drivers/message/fusion/lsi/mpi_log_sas.h
@@ -1,6 +1,6 @@
/***************************************************************************
* *
- * Copyright 2003 LSI Corporation. All rights reserved. *
+ * Copyright (c) 2000-2008 LSI Corporation. All rights reserved. *
* *
* Description *
* ------------ *
@@ -73,6 +73,8 @@
#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004)
#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005)
+#define IOP_LOGINFO_CODE_LOG_TIMESTAMP_EVENT (0x00080000)
+
/****************************************************************************/
/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
/****************************************************************************/
@@ -92,7 +94,7 @@
#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_OPEN_TIMEOUT_EXP (0x0000000C)
#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_UNUSED_0D (0x0000000D)
#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_DVTBLE_ACCSS_FAIL (0x0000000E)
-#define PL_LOGINFO_SUB CODE_OPEN_FAIL_BAD_DEST (0x00000011)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_BAD_DEST (0x00000011)
#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RATE_NOT_SUPP (0x00000012)
#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PROT_NOT_SUPP (0x00000013)
#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON0 (0x00000014)
@@ -159,10 +161,11 @@
#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
-#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) /* Bits 0-3 encode Transport Status Register (offset 0x08) */
- /* Bit 0 is Status Bit 0: FrameXferErr */
- /* Bit 1 & 2 are Status Bits 16 and 17: FrameXmitErrStatus */
- /* Bit 3 is Status Bit 18 WriteDataLengthGTDataLengthErr */
+#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)
+/* Bits 0-3 encode Transport Status Register (offset 0x08) */
+/* Bit 0 is Status Bit 0: FrameXferErr */
+/* Bit 1 & 2 are Status Bits 16 and 17: FrameXmitErrStatus */
+/* Bit 3 is Status Bit 18 WriteDataLenghtGTDataLengthErr */
#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500)
#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600)
@@ -177,6 +180,11 @@
#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01)
#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00)
#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
+#define PL_LOGINFO_SUB_CODE_BREAK_ON_SATA_CONNECTION (0x00002000)
+/* not currently used in mainline */
+#define PL_LOGINFO_SUB_CODE_BREAK_ON_STUCK_LINK (0x00003000)
+#define PL_LOGINFO_SUB_CODE_BREAK_ON_STUCK_LINK_AIP (0x00004000)
+#define PL_LOGINFO_SUB_CODE_BREAK_ON_INCOMPLETE_BREAK_RCVD (0x00005000)
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */
@@ -243,6 +251,8 @@
#define IR_LOGINFO_VOLUME_ACTIVATE_VOLUME_FAILED (0x00010014)
/* Activation failed trying to import the volume */
#define IR_LOGINFO_VOLUME_ACTIVATING_IMPORT_VOLUME_FAILED (0x00010015)
+/* Activation failed trying to import the volume */
+#define IR_LOGINFO_VOLUME_ACTIVATING_TOO_MANY_PHYS_DISKS (0x00010016)
/* Phys Disk failed, too many phys disks */
#define IR_LOGINFO_PHYSDISK_CREATE_TOO_MANY_DISKS (0x00010020)
@@ -285,6 +295,21 @@
/* Compatibility Error : IME size limited to < 2TB */
#define IR_LOGINFO_COMPAT_ERROR_IME_VOL_NOT_CURRENTLY_SUPPORTED (0x0001003D)
+/* Device Firmware Update: DFU can only be started once */
+#define IR_LOGINFO_DEV_FW_UPDATE_ERR_DFU_IN_PROGRESS (0x00010050)
+/* Device Firmware Update: Volume must be Optimal/Active/non-Quiesced */
+#define IR_LOGINFO_DEV_FW_UPDATE_ERR_DEVICE_IN_INVALID_STATE (0x00010051)
+/* Device Firmware Update: DFU Timeout cannot be zero */
+#define IR_LOGINFO_DEV_FW_UPDATE_ERR_INVALID_TIMEOUT (0x00010052)
+/* Device Firmware Update: CREATE TIMER FAILED */
+#define IR_LOGINFO_DEV_FW_UPDATE_ERR_NO_TIMERS (0x00010053)
+/* Device Firmware Update: Failed to read SAS_IO_UNIT_PG_1 */
+#define IR_LOGINFO_DEV_FW_UPDATE_ERR_READING_CFG_PAGE (0x00010054)
+/* Device Firmware Update: Invalid SAS_IO_UNIT_PG_1 value(s) */
+#define IR_LOGINFO_DEV_FW_UPDATE_ERR_PORT_IO_TIMEOUTS_REQUIRED (0x00010055)
+/* Device Firmware Update: Unable to allocate memory for page */
+#define IR_LOGINFO_DEV_FW_UPDATE_ERR_ALLOC_CFG_PAGE (0x00010056)
+
/****************************************************************************/
/* Defines for convenience */
diff --git a/drivers/message/fusion/lsi/mpi_raid.h b/drivers/message/fusion/lsi/mpi_raid.h
index 2856108421d..add60cc85be 100644
--- a/drivers/message/fusion/lsi/mpi_raid.h
+++ b/drivers/message/fusion/lsi/mpi_raid.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2001-2007 LSI Corporation.
+ * Copyright (c) 2001-2008 LSI Corporation.
*
*
* Name: mpi_raid.h
* Title: MPI RAID message and structures
* Creation Date: February 27, 2001
*
- * mpi_raid.h Version: 01.05.03
+ * mpi_raid.h Version: 01.05.05
*
* Version History
* ---------------
@@ -34,6 +34,9 @@
* _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE.
* 02-28-07 01.05.03 Added new RAID Action, Device FW Update Mode, and
* associated defines.
+ * 08-07-07 01.05.04 Added Disable Full Rebuild bit to the ActionDataWord
+ * for the RAID Action MPI_RAID_ACTION_DISABLE_VOLUME.
+ * 01-15-08 01.05.05 Added define for MPI_RAID_ACTION_SET_VOLUME_NAME.
* --------------------------------------------------------------------------
*/
@@ -93,6 +96,7 @@ typedef struct _MSG_RAID_ACTION
#define MPI_RAID_ACTION_SET_RESYNC_RATE (0x13)
#define MPI_RAID_ACTION_SET_DATA_SCRUB_RATE (0x14)
#define MPI_RAID_ACTION_DEVICE_FW_UPDATE_MODE (0x15)
+#define MPI_RAID_ACTION_SET_VOLUME_NAME (0x16)
/* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */
#define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC (0x00000001)
@@ -105,6 +109,9 @@ typedef struct _MSG_RAID_ACTION
#define MPI_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000)
#define MPI_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000002)
+/* ActionDataWord defines for use with MPI_RAID_ACTION_DISABLE_VOLUME action */
+#define MPI_RAID_ACTION_ADATA_DISABLE_FULL_REBUILD (0x00000001)
+
/* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */
#define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL (0x00000001)
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h
index 33fca83cefc..ab410036bbf 100644
--- a/drivers/message/fusion/lsi/mpi_sas.h
+++ b/drivers/message/fusion/lsi/mpi_sas.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2004-2006 LSI Corporation.
+ * Copyright (c) 2004-2008 LSI Corporation.
*
*
* Name: mpi_sas.h
* Title: MPI Serial Attached SCSI structures and definitions
* Creation Date: August 19, 2004
*
- * mpi_sas.h Version: 01.05.04
+ * mpi_sas.h Version: 01.05.05
*
* Version History
* ---------------
@@ -23,6 +23,10 @@
* reply.
* 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO
* Unit Control request.
+ * 01-15-08 01.05.05 Added support for MPI_SAS_OP_SET_IOC_PARAMETER,
+ * including adding IOCParameter and IOCParameter value
+ * fields to SAS IO Unit Control Request.
+ * Added MPI_SAS_DEVICE_INFO_PRODUCT_SPECIFIC define.
* --------------------------------------------------------------------------
*/
@@ -60,6 +64,8 @@
* Values for the SAS DeviceInfo field used in SAS Device Status Change Event
* data and SAS IO Unit Configuration pages.
*/
+#define MPI_SAS_DEVICE_INFO_PRODUCT_SPECIFIC (0xF0000000)
+
#define MPI_SAS_DEVICE_INFO_SEP (0x00004000)
#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000)
#define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000)
@@ -216,7 +222,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 DevHandle; /* 04h */
- U8 Reserved3; /* 06h */
+ U8 IOCParameter; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 TargetID; /* 0Ch */
@@ -225,7 +231,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
U8 PrimFlags; /* 0Fh */
U32 Primitive; /* 10h */
U64 SASAddress; /* 14h */
- U32 Reserved4; /* 1Ch */
+ U32 IOCParameterValue; /* 1Ch */
} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,
SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
@@ -241,6 +247,8 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
#define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C)
#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) /* obsolete name */
#define MPI_SAS_OP_REMOVE_DEVICE (0x0D)
+#define MPI_SAS_OP_SET_IOC_PARAMETER (0x0E)
+#define MPI_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80)
/* values for the PrimFlags field */
#define MPI_SAS_PRIMFLAGS_SINGLE (0x08)
@@ -256,7 +264,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U16 DevHandle; /* 04h */
- U8 Reserved3; /* 06h */
+ U8 IOCParameter; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U16 Reserved4; /* 0Ch */
diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h
index ff8c37d3fdc..c3dea7f6909 100644
--- a/drivers/message/fusion/lsi/mpi_targ.h
+++ b/drivers/message/fusion/lsi/mpi_targ.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2004 LSI Corporation.
+ * Copyright (c) 2000-2008 LSI Corporation.
*
*
* Name: mpi_targ.h
diff --git a/drivers/message/fusion/lsi/mpi_tool.h b/drivers/message/fusion/lsi/mpi_tool.h
index 8834ae6ce0f..53cd715aa7e 100644
--- a/drivers/message/fusion/lsi/mpi_tool.h
+++ b/drivers/message/fusion/lsi/mpi_tool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001-2005 LSI Corporation.
+ * Copyright (c) 2001-2008 LSI Corporation.
*
*
* Name: mpi_tool.h
diff --git a/drivers/message/fusion/lsi/mpi_type.h b/drivers/message/fusion/lsi/mpi_type.h
index 08dad9c1e44..888b26dbc41 100644
--- a/drivers/message/fusion/lsi/mpi_type.h
+++ b/drivers/message/fusion/lsi/mpi_type.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2004 LSI Corporation.
+ * Copyright (c) 2000-2008 LSI Corporation.
*
*
* Name: mpi_type.h
* Title: MPI Basic type definitions
* Creation Date: June 6, 2000
*
- * mpi_type.h Version: 01.05.01
+ * mpi_type.h Version: 01.05.02
*
* Version History
* ---------------
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index c4e8b9aa382..ea3aafbbda4 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -79,9 +79,22 @@ MODULE_VERSION(my_VERSION);
/*
* cmd line parameters
*/
-static int mpt_msi_enable = -1;
-module_param(mpt_msi_enable, int, 0);
-MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
+
+static int mpt_msi_enable_spi;
+module_param(mpt_msi_enable_spi, int, 0);
+MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
+ controllers (default=0)");
+
+static int mpt_msi_enable_fc;
+module_param(mpt_msi_enable_fc, int, 0);
+MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
+ controllers (default=0)");
+
+static int mpt_msi_enable_sas;
+module_param(mpt_msi_enable_sas, int, 0);
+MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
+ controllers (default=0)");
+
static int mpt_channel_mapping;
module_param(mpt_channel_mapping, int, 0);
@@ -91,7 +104,17 @@ static int mpt_debug_level;
static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
&mpt_debug_level, 0600);
-MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
+MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
+ - (default=0)");
+
+int mpt_fwfault_debug;
+EXPORT_SYMBOL(mpt_fwfault_debug);
+module_param_call(mpt_fwfault_debug, param_set_int, param_get_int,
+ &mpt_fwfault_debug, 0600);
+MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
+ " and halt Firmware on fault - (default=0)");
+
+
#ifdef MFCNT
static int mfcounter = 0;
@@ -1751,16 +1774,25 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->bus_type = SAS;
}
- if (mpt_msi_enable == -1) {
- /* Enable on SAS, disable on FC and SPI */
- if (ioc->bus_type == SAS)
- ioc->msi_enable = 1;
- else
- ioc->msi_enable = 0;
- } else
- /* follow flag: 0 - disable; 1 - enable */
- ioc->msi_enable = mpt_msi_enable;
+ switch (ioc->bus_type) {
+
+ case SAS:
+ ioc->msi_enable = mpt_msi_enable_sas;
+ break;
+
+ case SPI:
+ ioc->msi_enable = mpt_msi_enable_spi;
+ break;
+
+ case FC:
+ ioc->msi_enable = mpt_msi_enable_fc;
+ break;
+
+ default:
+ ioc->msi_enable = 0;
+ break;
+ }
if (ioc->errata_flag_1064)
pci_disable_io_access(pdev);
@@ -6313,6 +6345,33 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
*size = y;
}
+
+/**
+ * mpt_halt_firmware - Halts the firmware if it is operational and panic
+ * the kernel
+ * @ioc: Pointer to MPT_ADAPTER structure
+ *
+ **/
+void
+mpt_halt_firmware(MPT_ADAPTER *ioc)
+{
+ u32 ioc_raw_state;
+
+ ioc_raw_state = mpt_GetIocState(ioc, 0);
+
+ if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
+ printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
+ ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
+ panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
+ ioc_raw_state & MPI_DOORBELL_DATA_MASK);
+ } else {
+ CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
+ panic("%s: Firmware is halted due to command timeout\n",
+ ioc->name);
+ }
+}
+EXPORT_SYMBOL(mpt_halt_firmware);
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Reset Handling
@@ -6345,6 +6404,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
printk("MF count 0x%x !\n", ioc->mfcnt);
#endif
+ if (mpt_fwfault_debug)
+ mpt_halt_firmware(ioc);
/* Reset the adapter. Prevent more than 1 call to
* mpt_do_ioc_recovery at any instant in time.
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index dff048cfa10..b3e981d2a50 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -922,11 +922,14 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk);
+extern void mpt_halt_firmware(MPT_ADAPTER *ioc);
+
/*
* Public data decl's...
*/
extern struct list_head ioc_list;
+extern int mpt_fwfault_debug;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* } __KERNEL__ */
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index ee090413e59..e62c6bc4ad3 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1846,6 +1846,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
if (hd->timeouts < -1)
hd->timeouts++;
+ if (mpt_fwfault_debug)
+ mpt_halt_firmware(ioc);
+
/* Most important! Set TaskMsgContext to SCpnt's MsgContext!
* (the IO to be ABORT'd)
*
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c
index 1a4d04664d6..aa266e1f69b 100644
--- a/drivers/mfd/htc-egpio.c
+++ b/drivers/mfd/htc-egpio.c
@@ -286,7 +286,7 @@ static int __init egpio_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
goto fail;
- ei->base_addr = ioremap_nocache(res->start, res->end - res->start);
+ ei->base_addr = ioremap_nocache(res->start, resource_size(res));
if (!ei->base_addr)
goto fail;
pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr);
@@ -307,7 +307,7 @@ static int __init egpio_probe(struct platform_device *pdev)
ei->nchips = pdata->num_chips;
ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL);
- if (!ei) {
+ if (!ei->chip) {
ret = -ENOMEM;
goto fail;
}
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 6063dc2b52e..57271cb3b31 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(mcp_host_alloc);
int mcp_host_register(struct mcp *mcp)
{
- strcpy(mcp->attached_device.bus_id, "mcp0");
+ dev_set_name(&mcp->attached_device, "mcp0");
return device_register(&mcp->attached_device);
}
EXPORT_SYMBOL(mcp_host_register);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 24508e28e3f..2e36057659e 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -626,7 +626,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
}
if (client->irq) {
- set_irq_handler(client->irq, handle_level_irq);
ret = request_irq(client->irq, pcf50633_irq,
IRQF_TRIGGER_LOW, "pcf50633", pcf);
@@ -679,6 +678,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
static struct i2c_device_id pcf50633_id_table[] = {
{"pcf50633", 0x73},
+ {/* end of list */}
};
static struct i2c_driver pcf50633_driver = {
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 0e5761f1263..4c7b7962f6b 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1050,7 +1050,7 @@ static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm,
return gpiochip_add(gchip);
}
-static int sm501_register_gpio(struct sm501_devdata *sm)
+static int __devinit sm501_register_gpio(struct sm501_devdata *sm)
{
struct sm501_gpio *gpio = &sm->gpio;
resource_size_t iobase = sm->io_res->start + SM501_GPIO;
@@ -1321,7 +1321,7 @@ static unsigned int sm501_mem_local[] = {
* Common init code for an SM501
*/
-static int sm501_init_dev(struct sm501_devdata *sm)
+static int __devinit sm501_init_dev(struct sm501_devdata *sm)
{
struct sm501_initdata *idata;
struct sm501_platdata *pdata;
@@ -1397,7 +1397,7 @@ static int sm501_init_dev(struct sm501_devdata *sm)
return 0;
}
-static int sm501_plat_probe(struct platform_device *dev)
+static int __devinit sm501_plat_probe(struct platform_device *dev)
{
struct sm501_devdata *sm;
int ret;
@@ -1586,8 +1586,8 @@ static struct sm501_platdata sm501_pci_platdata = {
.gpio_base = -1,
};
-static int sm501_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int __devinit sm501_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
struct sm501_devdata *sm;
int err;
@@ -1693,7 +1693,7 @@ static void sm501_dev_remove(struct sm501_devdata *sm)
sm501_gpio_remove(sm);
}
-static void sm501_pci_remove(struct pci_dev *dev)
+static void __devexit sm501_pci_remove(struct pci_dev *dev)
{
struct sm501_devdata *sm = pci_get_drvdata(dev);
@@ -1727,16 +1727,16 @@ static struct pci_device_id sm501_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, sm501_pci_tbl);
-static struct pci_driver sm501_pci_drv = {
+static struct pci_driver sm501_pci_driver = {
.name = "sm501",
.id_table = sm501_pci_tbl,
.probe = sm501_pci_probe,
- .remove = sm501_pci_remove,
+ .remove = __devexit_p(sm501_pci_remove),
};
MODULE_ALIAS("platform:sm501");
-static struct platform_driver sm501_plat_drv = {
+static struct platform_driver sm501_plat_driver = {
.driver = {
.name = "sm501",
.owner = THIS_MODULE,
@@ -1749,14 +1749,14 @@ static struct platform_driver sm501_plat_drv = {
static int __init sm501_base_init(void)
{
- platform_driver_register(&sm501_plat_drv);
- return pci_register_driver(&sm501_pci_drv);
+ platform_driver_register(&sm501_plat_driver);
+ return pci_register_driver(&sm501_pci_driver);
}
static void __exit sm501_base_exit(void)
{
- platform_driver_unregister(&sm501_plat_drv);
- pci_unregister_driver(&sm501_pci_drv);
+ platform_driver_unregister(&sm501_plat_driver);
+ pci_unregister_driver(&sm501_pci_driver);
}
module_init(sm501_base_init);
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index e7ab0035d30..68826f1e36b 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -38,7 +38,7 @@
#include <linux/i2c.h>
#include <linux/i2c/twl4030.h>
-#ifdef CONFIG_ARM
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
#include <mach/cpu.h>
#endif
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 6860c924f36..fea9085fe52 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -492,7 +492,7 @@ static int ucb1x00_probe(struct mcp *mcp)
ucb->dev.class = &ucb1x00_class;
ucb->dev.parent = &mcp->attached_device;
- strlcpy(ucb->dev.bus_id, "ucb1x00", sizeof(ucb->dev.bus_id));
+ dev_set_name(&ucb->dev, "ucb1x00");
spin_lock_init(&ucb->lock);
spin_lock_init(&ucb->io_lock);
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index f92595c8f16..b457a05b28d 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -1111,7 +1111,7 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
do {
schedule_timeout_interruptible(1);
reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- } while (tries-- && (reg & WM8350_AUXADC_POLL));
+ } while (--tries && (reg & WM8350_AUXADC_POLL));
if (!tries)
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
@@ -1297,14 +1297,29 @@ static void wm8350_client_dev_register(struct wm8350 *wm8350,
int wm8350_device_init(struct wm8350 *wm8350, int irq,
struct wm8350_platform_data *pdata)
{
- int ret = -EINVAL;
+ int ret;
u16 id1, id2, mask_rev;
u16 cust_id, mode, chip_rev;
/* get WM8350 revision and config mode */
- wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1);
- wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2);
- wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), &mask_rev);
+ ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1);
+ if (ret != 0) {
+ dev_err(wm8350->dev, "Failed to read ID: %d\n", ret);
+ goto err;
+ }
+
+ ret = wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2);
+ if (ret != 0) {
+ dev_err(wm8350->dev, "Failed to read ID: %d\n", ret);
+ goto err;
+ }
+
+ ret = wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev),
+ &mask_rev);
+ if (ret != 0) {
+ dev_err(wm8350->dev, "Failed to read revision: %d\n", ret);
+ goto err;
+ }
id1 = be16_to_cpu(id1);
id2 = be16_to_cpu(id2);
@@ -1368,6 +1383,11 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
wm8350->power.rev_g_coeff = 1;
break;
+ case 1:
+ dev_info(wm8350->dev, "WM8351 Rev B\n");
+ wm8350->power.rev_g_coeff = 1;
+ break;
+
default:
dev_err(wm8350->dev, "Unknown WM8351 CHIP_REV\n");
ret = -ENODEV;
@@ -1404,14 +1424,12 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
return ret;
}
- if (pdata && pdata->init) {
- ret = pdata->init(wm8350);
- if (ret != 0) {
- dev_err(wm8350->dev, "Platform init() failed: %d\n",
- ret);
- goto err;
- }
- }
+ wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
mutex_init(&wm8350->auxadc_mutex);
mutex_init(&wm8350->irq_mutex);
@@ -1430,6 +1448,15 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
}
wm8350->chip_irq = irq;
+ if (pdata && pdata->init) {
+ ret = pdata->init(wm8350);
+ if (ret != 0) {
+ dev_err(wm8350->dev, "Platform init() failed: %d\n",
+ ret);
+ goto err;
+ }
+ }
+
wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0);
wm8350_client_dev_register(wm8350, "wm8350-codec",
diff --git a/drivers/mfd/wm8350-regmap.c b/drivers/mfd/wm8350-regmap.c
index 68887b817d1..9a4cc954cb7 100644
--- a/drivers/mfd/wm8350-regmap.c
+++ b/drivers/mfd/wm8350-regmap.c
@@ -3188,7 +3188,7 @@ const struct wm8350_reg_access wm8350_reg_io_map[] = {
{ 0x7CFF, 0x0C00, 0x7FFF }, /* R1 - ID */
{ 0x0000, 0x0000, 0x0000 }, /* R2 */
{ 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */
- { 0xFCF7, 0xFCF7, 0xF800 }, /* R4 - System Control 2 */
+ { 0xFEF7, 0xFEF7, 0xF800 }, /* R4 - System Control 2 */
{ 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */
{ 0xFB0E, 0xFB0E, 0x0000 }, /* R6 - Interface Control */
{ 0x0000, 0x0000, 0x0000 }, /* R7 */
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 419c378bd24..c64e6798878 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -87,14 +87,6 @@ config PHANTOM
If you choose to build module, its name will be phantom. If unsure,
say N here.
-config EEPROM_93CX6
- tristate "EEPROM 93CX6 support"
- ---help---
- This is a driver for the EEPROM chipsets 93c46 and 93c66.
- The driver supports both read as well as write commands.
-
- If unsure, say N.
-
config SGI_IOC4
tristate "SGI IOC4 Base IO support"
depends on PCI
@@ -225,11 +217,13 @@ config DELL_LAPTOP
depends on EXPERIMENTAL
depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL
+ depends on POWER_SUPPLY
default n
---help---
This driver adds support for rfkill and backlight control to Dell
laptops.
source "drivers/misc/c2port/Kconfig"
+source "drivers/misc/eeprom/Kconfig"
endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9cf8ae6e4b3..bc119983055 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -10,14 +10,13 @@ obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
obj-$(CONFIG_ICS932S401) += ics932s401.o
obj-$(CONFIG_LKDTM) += lkdtm.o
obj-$(CONFIG_TIFM_CORE) += tifm_core.o
-obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
obj-$(CONFIG_PHANTOM) += phantom.o
obj-$(CONFIG_SGI_IOC4) += ioc4.o
-obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
obj-$(CONFIG_SGI_XP) += sgi-xp/
obj-$(CONFIG_SGI_GRU) += sgi-gru/
obj-$(CONFIG_HP_ILO) += hpilo.o
obj-$(CONFIG_C2PORT) += c2port/
+obj-y += eeprom/
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index bf5e4d06543..558bf3f2c27 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -35,7 +35,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num)
if (!ssc_valid) {
spin_unlock(&user_lock);
- dev_dbg(&ssc->pdev->dev, "could not find requested device\n");
+ pr_err("ssc: ssc%d platform device is missing\n", ssc_num);
return ERR_PTR(-ENODEV);
}
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
new file mode 100644
index 00000000000..c76df8cda5e
--- /dev/null
+++ b/drivers/misc/eeprom/Kconfig
@@ -0,0 +1,59 @@
+menu "EEPROM support"
+
+config EEPROM_AT24
+ tristate "I2C EEPROMs from most vendors"
+ depends on I2C && SYSFS && EXPERIMENTAL
+ help
+ Enable this driver to get read/write support to most I2C EEPROMs,
+ after you configure the driver to know about each EEPROM on
+ your target board. Use these generic chip names, instead of
+ vendor-specific ones like at24c64 or 24lc02:
+
+ 24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08,
+ 24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024
+
+ Unless you like data loss puzzles, always be sure that any chip
+ you configure as a 24c32 (32 kbit) or larger is NOT really a
+ 24c16 (16 kbit) or smaller, and vice versa. Marking the chip
+ as read-only won't help recover from this. Also, if your chip
+ has any software write-protect mechanism you may want to review the
+ code to make sure this driver won't turn it on by accident.
+
+ If you use this with an SMBus adapter instead of an I2C adapter,
+ full functionality is not available. Only smaller devices are
+ supported (24c16 and below, max 4 kByte).
+
+ This driver can also be built as a module. If so, the module
+ will be called at24.
+
+config EEPROM_AT25
+ tristate "SPI EEPROMs from most vendors"
+ depends on SPI && SYSFS
+ help
+ Enable this driver to get read/write support to most SPI EEPROMs,
+ after you configure the board init code to know about each eeprom
+ on your target board.
+
+ This driver can also be built as a module. If so, the module
+ will be called at25.
+
+config EEPROM_LEGACY
+ tristate "Old I2C EEPROM reader"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get read-only access to the EEPROM data
+ available on modern memory DIMMs and Sony Vaio laptops via I2C. Such
+ EEPROMs could theoretically be available on other devices as well.
+
+ This driver can also be built as a module. If so, the module
+ will be called eeprom.
+
+config EEPROM_93CX6
+ tristate "EEPROM 93CX6 support"
+ help
+ This is a driver for the EEPROM chipsets 93c46 and 93c66.
+ The driver supports both read as well as write commands.
+
+ If unsure, say N.
+
+endmenu
diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile
new file mode 100644
index 00000000000..539dd8f8812
--- /dev/null
+++ b/drivers/misc/eeprom/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_EEPROM_AT24) += at24.o
+obj-$(CONFIG_EEPROM_AT25) += at25.o
+obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
+obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
diff --git a/drivers/i2c/chips/at24.c b/drivers/misc/eeprom/at24.c
index d4775528abc..d4775528abc 100644
--- a/drivers/i2c/chips/at24.c
+++ b/drivers/misc/eeprom/at24.c
diff --git a/drivers/spi/at25.c b/drivers/misc/eeprom/at25.c
index 290dbe99647..290dbe99647 100644
--- a/drivers/spi/at25.c
+++ b/drivers/misc/eeprom/at25.c
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/misc/eeprom/eeprom.c
index 2c27193aeaa..2c27193aeaa 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/misc/eeprom/eeprom.c
diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom/eeprom_93cx6.c
index 15b1780025c..15b1780025c 100644
--- a/drivers/misc/eeprom_93cx6.c
+++ b/drivers/misc/eeprom/eeprom_93cx6.c
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 05e29828923..cf991850f01 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -207,7 +207,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
&device_ccb->recv_ctrl);
/* give iLO some time to process stop request */
- for (retries = 1000; retries > 0; retries--) {
+ for (retries = MAX_WAIT; retries > 0; retries--) {
doorbell_set(driver_ccb);
udelay(1);
if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
@@ -309,7 +309,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
doorbell_clr(driver_ccb);
/* make sure iLO is really handling requests */
- for (i = 1000; i > 0; i--) {
+ for (i = MAX_WAIT; i > 0; i--) {
if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
break;
udelay(1);
@@ -326,7 +326,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
return 0;
free:
- pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
+ ilo_ccb_close(pdev, data);
out:
return error;
}
@@ -710,6 +710,7 @@ out:
static struct pci_device_id ilo_devices[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) },
{ }
};
MODULE_DEVICE_TABLE(pci, ilo_devices);
@@ -758,7 +759,7 @@ static void __exit ilo_exit(void)
class_destroy(ilo_class);
}
-MODULE_VERSION("0.05");
+MODULE_VERSION("1.0");
MODULE_ALIAS(ILO_NAME);
MODULE_DESCRIPTION(ILO_NAME);
MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index a281207696c..b64a20ef07e 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -19,6 +19,8 @@
#define MAX_ILO_DEV 1
/* max number of files */
#define MAX_OPEN (MAX_CCB * MAX_ILO_DEV)
+/* spin counter for open/close delay */
+#define MAX_WAIT 10000
/*
* Per device, used to track global memory allocations.
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index a5bd658c2e8..275b78896a7 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved.
*/
/*
@@ -514,7 +514,8 @@ struct xpc_channel_uv {
/* partition's notify mq */
struct xpc_send_msg_slot_uv *send_msg_slots;
- struct xpc_notify_mq_msg_uv *recv_msg_slots;
+ void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */
+ /* structure plus the user's payload */
struct xpc_fifo_head_uv msg_slot_free_list;
struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index 9cd2ebe2a3b..45fd653dbe3 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -49,9 +49,6 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING))
return;
-
- DBUG_ON(ch->local_msgqueue == NULL);
- DBUG_ON(ch->remote_msgqueue == NULL);
}
if (!(ch->flags & XPC_C_OPENREPLY)) {
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index 82fb9958f22..2e975762c32 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -1106,8 +1106,6 @@ xpc_process_activate_IRQ_rcvd_sn2(void)
int n_IRQs_expected;
int n_IRQs_detected;
- DBUG_ON(xpc_activate_IRQ_rcvd == 0);
-
spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
n_IRQs_expected = xpc_activate_IRQ_rcvd;
xpc_activate_IRQ_rcvd = 0;
@@ -1726,6 +1724,7 @@ xpc_clear_local_msgqueue_flags_sn2(struct xpc_channel *ch)
msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue +
(get % ch->local_nentries) *
ch->entry_size);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
msg->flags = 0;
} while (++get < ch_sn2->remote_GP.get);
}
@@ -1740,11 +1739,18 @@ xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch)
struct xpc_msg_sn2 *msg;
s64 put;
- put = ch_sn2->w_remote_GP.put;
+ /* flags are zeroed when the buffer is allocated */
+ if (ch_sn2->remote_GP.put < ch->remote_nentries)
+ return;
+
+ put = max(ch_sn2->w_remote_GP.put, ch->remote_nentries);
do {
msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
(put % ch->remote_nentries) *
ch->entry_size);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
+ DBUG_ON(!(msg->flags & XPC_M_SN2_DONE));
+ DBUG_ON(msg->number != put - ch->remote_nentries);
msg->flags = 0;
} while (++put < ch_sn2->remote_GP.put);
}
@@ -1836,6 +1842,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
*/
xpc_clear_remote_msgqueue_flags_sn2(ch);
+ smp_wmb(); /* ensure flags have been cleared before bte_copy */
ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put;
dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
@@ -1934,7 +1941,7 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
break;
get = ch_sn2->w_local_GP.get;
- rmb(); /* guarantee that .get loads before .put */
+ smp_rmb(); /* guarantee that .get loads before .put */
if (get == ch_sn2->w_remote_GP.put)
break;
@@ -1956,11 +1963,13 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
msg = xpc_pull_remote_msg_sn2(ch, get);
- DBUG_ON(msg != NULL && msg->number != get);
- DBUG_ON(msg != NULL && (msg->flags & XPC_M_SN2_DONE));
- DBUG_ON(msg != NULL && !(msg->flags & XPC_M_SN2_READY));
+ if (msg != NULL) {
+ DBUG_ON(msg->number != get);
+ DBUG_ON(msg->flags & XPC_M_SN2_DONE);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
- payload = &msg->payload;
+ payload = &msg->payload;
+ }
break;
}
@@ -2053,7 +2062,7 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
while (1) {
put = ch_sn2->w_local_GP.put;
- rmb(); /* guarantee that .put loads before .get */
+ smp_rmb(); /* guarantee that .put loads before .get */
if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) {
/* There are available message entries. We need to try
@@ -2186,7 +2195,7 @@ xpc_send_payload_sn2(struct xpc_channel *ch, u32 flags, void *payload,
* The preceding store of msg->flags must occur before the following
* load of local_GP->put.
*/
- mb();
+ smp_mb();
/* see if the message is next in line to be sent, if so send it */
@@ -2277,8 +2286,9 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n",
(void *)msg, msg_number, ch->partid, ch->number);
- DBUG_ON((((u64)msg - (u64)ch->remote_msgqueue) / ch->entry_size) !=
+ DBUG_ON((((u64)msg - (u64)ch->sn.sn2.remote_msgqueue) / ch->entry_size) !=
msg_number % ch->remote_nentries);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
DBUG_ON(msg->flags & XPC_M_SN2_DONE);
msg->flags |= XPC_M_SN2_DONE;
@@ -2287,7 +2297,7 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
* The preceding store of msg->flags must occur before the following
* load of local_GP->get.
*/
- mb();
+ smp_mb();
/*
* See if this message is next in line to be acknowledged as having
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index 91a55b1b103..29c0502a96b 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved.
*/
/*
@@ -1010,8 +1010,8 @@ xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch)
continue;
for (entry = 0; entry < nentries; entry++) {
- msg_slot = ch_uv->recv_msg_slots + entry *
- ch->entry_size;
+ msg_slot = ch_uv->recv_msg_slots +
+ entry * ch->entry_size;
msg_slot->hdr.msg_slot_number = entry;
}
@@ -1308,9 +1308,8 @@ xpc_handle_notify_mq_msg_uv(struct xpc_partition *part,
/* we're dealing with a normal message sent via the notify_mq */
ch_uv = &ch->sn.uv;
- msg_slot = (struct xpc_notify_mq_msg_uv *)((u64)ch_uv->recv_msg_slots +
- (msg->hdr.msg_slot_number % ch->remote_nentries) *
- ch->entry_size);
+ msg_slot = ch_uv->recv_msg_slots +
+ (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size;
BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number);
BUG_ON(msg_slot->hdr.size != 0);
@@ -1423,7 +1422,7 @@ xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload,
atomic_inc(&ch->n_to_notify);
msg_slot->key = key;
- wmb(); /* a non-NULL func must hit memory after the key */
+ smp_wmb(); /* a non-NULL func must hit memory after the key */
msg_slot->func = func;
if (ch->flags & XPC_C_DISCONNECTING) {
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 7957f525b2f..6faefcffcb5 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1999-2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999-2009 Silicon Graphics, Inc. All rights reserved.
*/
/*
@@ -551,6 +551,7 @@ xpnet_init(void)
netif_carrier_off(xpnet_device);
+ xpnet_device->netdev_ops = &xpnet_netdev_ops;
xpnet_device->mtu = XPNET_DEF_MTU;
/*
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 45b1f430685..513eb09a638 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -584,7 +584,7 @@ static int mmc_blk_probe(struct mmc_card *card)
if (err)
goto out;
- string_get_size(get_capacity(md->disk) << 9, STRING_UNITS_2,
+ string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2,
cap_str, sizeof(cap_str));
printk(KERN_INFO "%s: %s %s %s %s\n",
md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index b92b172074e..b9f1e84897c 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -494,7 +494,7 @@ static int mmc_test_basic_read(struct mmc_test_card *test)
sg_init_one(&sg, test->buffer, 512);
- ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
+ ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0);
if (ret)
return ret;
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 9c50e6f1c23..34ce2703d29 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -248,12 +248,15 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
sg_init_one(&sg, data_buf, len);
- /*
- * The spec states that CSR and CID accesses have a timeout
- * of 64 clock cycles.
- */
- data.timeout_ns = 0;
- data.timeout_clks = 64;
+ if (opcode == MMC_SEND_CSD || opcode == MMC_SEND_CID) {
+ /*
+ * The spec states that CSR and CID accesses have a timeout
+ * of 64 clock cycles.
+ */
+ data.timeout_ns = 0;
+ data.timeout_clks = 64;
+ } else
+ mmc_set_data_timeout(&data, card);
mmc_wait_for_req(host, &mrq);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index dfa585f7fea..99d4b28d52e 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -76,6 +76,16 @@ config MMC_OMAP
If unsure, say N.
+config MMC_OMAP_HS
+ tristate "TI OMAP High Speed Multimedia Card Interface support"
+ depends on ARCH_OMAP2430 || ARCH_OMAP3
+ help
+ This selects the TI OMAP High Speed Multimedia card Interface.
+ If you have an OMAP2430 or OMAP3 board with a Multimedia Card slot,
+ say Y or M here.
+
+ If unsure, say N.
+
config MMC_WBSD
tristate "Winbond W83L51xD SD/MMC Card Interface support"
depends on ISA_DMA_API
@@ -135,6 +145,16 @@ config MMC_IMX
If unsure, say N.
+config MMC_MXC
+ tristate "Freescale i.MX2/3 Multimedia Card Interface support"
+ depends on ARCH_MXC
+ help
+ This selects the Freescale i.MX2/3 Multimedia card Interface.
+ If you have a i.MX platform with a Multimedia Card slot,
+ say Y or M here.
+
+ If unsure, say N.
+
config MMC_TIFM_SD
tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)"
depends on EXPERIMENTAL && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index f4853288bbb..dedec55861d 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -9,12 +9,14 @@ endif
obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
obj-$(CONFIG_MMC_PXA) += pxamci.o
obj-$(CONFIG_MMC_IMX) += imxmmc.o
+obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_OMAP) += omap.o
+obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
obj-$(CONFIG_MMC_AT91) += at91_mci.o
obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o
obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 76bfe16c09b..e94e92001e7 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1548,9 +1548,10 @@ static bool filter(struct dma_chan *chan, void *slave)
{
struct dw_dma_slave *dws = slave;
- if (dws->dma_dev == chan->device->dev)
+ if (dws->dma_dev == chan->device->dev) {
+ chan->private = dws;
return true;
- else
+ } else
return false;
}
#endif
@@ -1602,7 +1603,7 @@ static int __init atmci_probe(struct platform_device *pdev)
tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host);
- ret = request_irq(irq, atmci_interrupt, 0, pdev->dev.bus_id, host);
+ ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host);
if (ret)
goto err_request_irq;
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 1bcbdd6763a..2909bbc8ad0 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -430,6 +430,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
clk = 255;
host->cclk = host->mclk / (2 * (clk + 1));
}
+ if (host->hw_designer == 0x80)
+ clk |= MCI_FCEN; /* Bug fix in ST IP block */
clk |= MCI_CLK_ENABLE;
}
@@ -440,15 +442,27 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_OFF:
break;
case MMC_POWER_UP:
- pwr |= MCI_PWR_UP;
- break;
+ /* The ST version does not have this, fall through to POWER_ON */
+ if (host->hw_designer != 0x80) {
+ pwr |= MCI_PWR_UP;
+ break;
+ }
case MMC_POWER_ON:
pwr |= MCI_PWR_ON;
break;
}
- if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
- pwr |= MCI_ROD;
+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
+ if (host->hw_designer != 0x80)
+ pwr |= MCI_ROD;
+ else {
+ /*
+ * The ST Micro variant use the ROD bit for something
+ * else and only has OD (Open Drain).
+ */
+ pwr |= MCI_OD;
+ }
+ }
writel(clk, host->base + MMCICLOCK);
@@ -500,6 +514,12 @@ static int mmci_probe(struct amba_device *dev, void *id)
}
host = mmc_priv(mmc);
+ /* Bits 12 thru 19 is the designer */
+ host->hw_designer = (dev->periphid >> 12) & 0xff;
+ /* Bits 20 thru 23 is the revison */
+ host->hw_revision = (dev->periphid >> 20) & 0xf;
+ DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
+ DBG(host, "revision = 0x%01x\n", host->hw_revision);
host->clk = clk_get(&dev->dev, NULL);
if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk);
@@ -693,6 +713,15 @@ static struct amba_id mmci_ids[] = {
.id = 0x00041181,
.mask = 0x000fffff,
},
+ /* ST Micro variants */
+ {
+ .id = 0x00180180,
+ .mask = 0x00ffffff,
+ },
+ {
+ .id = 0x00280180,
+ .mask = 0x00ffffff,
+ },
{ 0, 0 },
};
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 0f39c490f02..0441bac1c0e 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -11,13 +11,23 @@
#define MCI_PWR_OFF 0x00
#define MCI_PWR_UP 0x02
#define MCI_PWR_ON 0x03
+#define MCI_DATA2DIREN (1 << 2)
+#define MCI_CMDDIREN (1 << 3)
+#define MCI_DATA0DIREN (1 << 4)
+#define MCI_DATA31DIREN (1 << 5)
#define MCI_OD (1 << 6)
#define MCI_ROD (1 << 7)
+/* The ST Micro version does not have ROD */
+#define MCI_FBCLKEN (1 << 7)
+#define MCI_DATA74DIREN (1 << 8)
#define MMCICLOCK 0x004
#define MCI_CLK_ENABLE (1 << 8)
#define MCI_CLK_PWRSAVE (1 << 9)
#define MCI_CLK_BYPASS (1 << 10)
+#define MCI_WIDE_BUS (1 << 11)
+/* HW flow control on the ST Micro version */
+#define MCI_FCEN (1 << 13)
#define MMCIARGUMENT 0x008
#define MMCICOMMAND 0x00c
@@ -26,6 +36,10 @@
#define MCI_CPSM_INTERRUPT (1 << 8)
#define MCI_CPSM_PENDING (1 << 9)
#define MCI_CPSM_ENABLE (1 << 10)
+#define MCI_SDIO_SUSP (1 << 11)
+#define MCI_ENCMD_COMPL (1 << 12)
+#define MCI_NIEN (1 << 13)
+#define MCI_CE_ATACMD (1 << 14)
#define MMCIRESPCMD 0x010
#define MMCIRESPONSE0 0x014
@@ -39,6 +53,11 @@
#define MCI_DPSM_DIRECTION (1 << 1)
#define MCI_DPSM_MODE (1 << 2)
#define MCI_DPSM_DMAENABLE (1 << 3)
+#define MCI_DPSM_BLOCKSIZE (1 << 4)
+#define MCI_DPSM_RWSTART (1 << 8)
+#define MCI_DPSM_RWSTOP (1 << 9)
+#define MCI_DPSM_RWMOD (1 << 10)
+#define MCI_DPSM_SDIOEN (1 << 11)
#define MMCIDATACNT 0x030
#define MMCISTATUS 0x034
@@ -63,6 +82,8 @@
#define MCI_RXFIFOEMPTY (1 << 19)
#define MCI_TXDATAAVLBL (1 << 20)
#define MCI_RXDATAAVLBL (1 << 21)
+#define MCI_SDIOIT (1 << 22)
+#define MCI_CEATAEND (1 << 23)
#define MMCICLEAR 0x038
#define MCI_CMDCRCFAILCLR (1 << 0)
@@ -75,6 +96,8 @@
#define MCI_CMDSENTCLR (1 << 7)
#define MCI_DATAENDCLR (1 << 8)
#define MCI_DATABLOCKENDCLR (1 << 10)
+#define MCI_SDIOITC (1 << 22)
+#define MCI_CEATAENDC (1 << 23)
#define MMCIMASK0 0x03c
#define MCI_CMDCRCFAILMASK (1 << 0)
@@ -98,6 +121,8 @@
#define MCI_RXFIFOEMPTYMASK (1 << 19)
#define MCI_TXDATAAVLBLMASK (1 << 20)
#define MCI_RXDATAAVLBLMASK (1 << 21)
+#define MCI_SDIOITMASK (1 << 22)
+#define MCI_CEATAENDMASK (1 << 23)
#define MMCIMASK1 0x040
#define MMCIFIFOCNT 0x048
@@ -136,6 +161,9 @@ struct mmci_host {
u32 pwr;
struct mmc_platform_data *plat;
+ u8 hw_designer;
+ u8 hw_revision:4;
+
struct timer_list timer;
unsigned int oldstat;
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
new file mode 100644
index 00000000000..dda0be4e25d
--- /dev/null
+++ b/drivers/mmc/host/mxcmmc.c
@@ -0,0 +1,880 @@
+/*
+ * linux/drivers/mmc/host/mxcmmc.c - Freescale i.MX MMCI driver
+ *
+ * This is a driver for the SDHC controller found in Freescale MX2/MX3
+ * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
+ * Unlike the hardware found on MX1, this hardware just works and does
+ * not need all the quirks found in imxmmc.c, hence the seperate driver.
+ *
+ * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
+ *
+ * derived from pxamci.c by Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/blkdev.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <mach/mmc.h>
+
+#ifdef CONFIG_ARCH_MX2
+#include <mach/dma-mx1-mx2.h>
+#define HAS_DMA
+#endif
+
+#define DRIVER_NAME "imx-mmc"
+
+#define MMC_REG_STR_STP_CLK 0x00
+#define MMC_REG_STATUS 0x04
+#define MMC_REG_CLK_RATE 0x08
+#define MMC_REG_CMD_DAT_CONT 0x0C
+#define MMC_REG_RES_TO 0x10
+#define MMC_REG_READ_TO 0x14
+#define MMC_REG_BLK_LEN 0x18
+#define MMC_REG_NOB 0x1C
+#define MMC_REG_REV_NO 0x20
+#define MMC_REG_INT_CNTR 0x24
+#define MMC_REG_CMD 0x28
+#define MMC_REG_ARG 0x2C
+#define MMC_REG_RES_FIFO 0x34
+#define MMC_REG_BUFFER_ACCESS 0x38
+
+#define STR_STP_CLK_RESET (1 << 3)
+#define STR_STP_CLK_START_CLK (1 << 1)
+#define STR_STP_CLK_STOP_CLK (1 << 0)
+
+#define STATUS_CARD_INSERTION (1 << 31)
+#define STATUS_CARD_REMOVAL (1 << 30)
+#define STATUS_YBUF_EMPTY (1 << 29)
+#define STATUS_XBUF_EMPTY (1 << 28)
+#define STATUS_YBUF_FULL (1 << 27)
+#define STATUS_XBUF_FULL (1 << 26)
+#define STATUS_BUF_UND_RUN (1 << 25)
+#define STATUS_BUF_OVFL (1 << 24)
+#define STATUS_SDIO_INT_ACTIVE (1 << 14)
+#define STATUS_END_CMD_RESP (1 << 13)
+#define STATUS_WRITE_OP_DONE (1 << 12)
+#define STATUS_DATA_TRANS_DONE (1 << 11)
+#define STATUS_READ_OP_DONE (1 << 11)
+#define STATUS_WR_CRC_ERROR_CODE_MASK (3 << 10)
+#define STATUS_CARD_BUS_CLK_RUN (1 << 8)
+#define STATUS_BUF_READ_RDY (1 << 7)
+#define STATUS_BUF_WRITE_RDY (1 << 6)
+#define STATUS_RESP_CRC_ERR (1 << 5)
+#define STATUS_CRC_READ_ERR (1 << 3)
+#define STATUS_CRC_WRITE_ERR (1 << 2)
+#define STATUS_TIME_OUT_RESP (1 << 1)
+#define STATUS_TIME_OUT_READ (1 << 0)
+#define STATUS_ERR_MASK 0x2f
+
+#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1 << 12)
+#define CMD_DAT_CONT_STOP_READWAIT (1 << 11)
+#define CMD_DAT_CONT_START_READWAIT (1 << 10)
+#define CMD_DAT_CONT_BUS_WIDTH_4 (2 << 8)
+#define CMD_DAT_CONT_INIT (1 << 7)
+#define CMD_DAT_CONT_WRITE (1 << 4)
+#define CMD_DAT_CONT_DATA_ENABLE (1 << 3)
+#define CMD_DAT_CONT_RESPONSE_48BIT_CRC (1 << 0)
+#define CMD_DAT_CONT_RESPONSE_136BIT (2 << 0)
+#define CMD_DAT_CONT_RESPONSE_48BIT (3 << 0)
+
+#define INT_SDIO_INT_WKP_EN (1 << 18)
+#define INT_CARD_INSERTION_WKP_EN (1 << 17)
+#define INT_CARD_REMOVAL_WKP_EN (1 << 16)
+#define INT_CARD_INSERTION_EN (1 << 15)
+#define INT_CARD_REMOVAL_EN (1 << 14)
+#define INT_SDIO_IRQ_EN (1 << 13)
+#define INT_DAT0_EN (1 << 12)
+#define INT_BUF_READ_EN (1 << 4)
+#define INT_BUF_WRITE_EN (1 << 3)
+#define INT_END_CMD_RES_EN (1 << 2)
+#define INT_WRITE_OP_DONE_EN (1 << 1)
+#define INT_READ_OP_EN (1 << 0)
+
+struct mxcmci_host {
+ struct mmc_host *mmc;
+ struct resource *res;
+ void __iomem *base;
+ int irq;
+ int detect_irq;
+ int dma;
+ int do_dma;
+ unsigned int power_mode;
+ struct imxmmc_platform_data *pdata;
+
+ struct mmc_request *req;
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+
+ unsigned int dma_nents;
+ unsigned int datasize;
+ unsigned int dma_dir;
+
+ u16 rev_no;
+ unsigned int cmdat;
+
+ struct clk *clk;
+
+ int clock;
+
+ struct work_struct datawork;
+};
+
+static inline int mxcmci_use_dma(struct mxcmci_host *host)
+{
+ return host->do_dma;
+}
+
+static void mxcmci_softreset(struct mxcmci_host *host)
+{
+ int i;
+
+ /* reset sequence */
+ writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
+ writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
+ host->base + MMC_REG_STR_STP_CLK);
+
+ for (i = 0; i < 8; i++)
+ writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
+
+ writew(0xff, host->base + MMC_REG_RES_TO);
+}
+
+static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
+{
+ unsigned int nob = data->blocks;
+ unsigned int blksz = data->blksz;
+ unsigned int datasize = nob * blksz;
+#ifdef HAS_DMA
+ struct scatterlist *sg;
+ int i;
+#endif
+ if (data->flags & MMC_DATA_STREAM)
+ nob = 0xffff;
+
+ host->data = data;
+ data->bytes_xfered = 0;
+
+ writew(nob, host->base + MMC_REG_NOB);
+ writew(blksz, host->base + MMC_REG_BLK_LEN);
+ host->datasize = datasize;
+
+#ifdef HAS_DMA
+ for_each_sg(data->sg, sg, data->sg_len, i) {
+ if (sg->offset & 3 || sg->length & 3) {
+ host->do_dma = 0;
+ return;
+ }
+ }
+
+ if (data->flags & MMC_DATA_READ) {
+ host->dma_dir = DMA_FROM_DEVICE;
+ host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma_dir);
+
+ imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
+ host->res->start + MMC_REG_BUFFER_ACCESS,
+ DMA_MODE_READ);
+ } else {
+ host->dma_dir = DMA_TO_DEVICE;
+ host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma_dir);
+
+ imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
+ host->res->start + MMC_REG_BUFFER_ACCESS,
+ DMA_MODE_WRITE);
+ }
+
+ wmb();
+
+ imx_dma_enable(host->dma);
+#endif /* HAS_DMA */
+}
+
+static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
+ unsigned int cmdat)
+{
+ WARN_ON(host->cmd != NULL);
+ host->cmd = cmd;
+
+ switch (mmc_resp_type(cmd)) {
+ case MMC_RSP_R1: /* short CRC, OPCODE */
+ case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
+ cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
+ break;
+ case MMC_RSP_R2: /* long 136 bit + CRC */
+ cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
+ break;
+ case MMC_RSP_R3: /* short */
+ cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
+ break;
+ case MMC_RSP_NONE:
+ break;
+ default:
+ dev_err(mmc_dev(host->mmc), "unhandled response type 0x%x\n",
+ mmc_resp_type(cmd));
+ cmd->error = -EINVAL;
+ return -EINVAL;
+ }
+
+ if (mxcmci_use_dma(host))
+ writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN |
+ INT_END_CMD_RES_EN,
+ host->base + MMC_REG_INT_CNTR);
+ else
+ writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR);
+
+ writew(cmd->opcode, host->base + MMC_REG_CMD);
+ writel(cmd->arg, host->base + MMC_REG_ARG);
+ writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT);
+
+ return 0;
+}
+
+static void mxcmci_finish_request(struct mxcmci_host *host,
+ struct mmc_request *req)
+{
+ writel(0, host->base + MMC_REG_INT_CNTR);
+
+ host->req = NULL;
+ host->cmd = NULL;
+ host->data = NULL;
+
+ mmc_request_done(host->mmc, req);
+}
+
+static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
+{
+ struct mmc_data *data = host->data;
+ int data_error;
+
+#ifdef HAS_DMA
+ if (mxcmci_use_dma(host)) {
+ imx_dma_disable(host->dma);
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents,
+ host->dma_dir);
+ }
+#endif
+
+ if (stat & STATUS_ERR_MASK) {
+ dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
+ stat);
+ if (stat & STATUS_CRC_READ_ERR) {
+ data->error = -EILSEQ;
+ } else if (stat & STATUS_CRC_WRITE_ERR) {
+ u32 err_code = (stat >> 9) & 0x3;
+ if (err_code == 2) /* No CRC response */
+ data->error = -ETIMEDOUT;
+ else
+ data->error = -EILSEQ;
+ } else if (stat & STATUS_TIME_OUT_READ) {
+ data->error = -ETIMEDOUT;
+ } else {
+ data->error = -EIO;
+ }
+ } else {
+ data->bytes_xfered = host->datasize;
+ }
+
+ data_error = data->error;
+
+ host->data = NULL;
+
+ return data_error;
+}
+
+static void mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
+{
+ struct mmc_command *cmd = host->cmd;
+ int i;
+ u32 a, b, c;
+
+ if (!cmd)
+ return;
+
+ if (stat & STATUS_TIME_OUT_RESP) {
+ dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
+ cmd->error = -ETIMEDOUT;
+ } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
+ dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
+ cmd->error = -EILSEQ;
+ }
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ if (cmd->flags & MMC_RSP_136) {
+ for (i = 0; i < 4; i++) {
+ a = readw(host->base + MMC_REG_RES_FIFO);
+ b = readw(host->base + MMC_REG_RES_FIFO);
+ cmd->resp[i] = a << 16 | b;
+ }
+ } else {
+ a = readw(host->base + MMC_REG_RES_FIFO);
+ b = readw(host->base + MMC_REG_RES_FIFO);
+ c = readw(host->base + MMC_REG_RES_FIFO);
+ cmd->resp[0] = a << 24 | b << 8 | c >> 8;
+ }
+ }
+}
+
+static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
+{
+ u32 stat;
+ unsigned long timeout = jiffies + HZ;
+
+ do {
+ stat = readl(host->base + MMC_REG_STATUS);
+ if (stat & STATUS_ERR_MASK)
+ return stat;
+ if (time_after(jiffies, timeout))
+ return STATUS_TIME_OUT_READ;
+ if (stat & mask)
+ return 0;
+ cpu_relax();
+ } while (1);
+}
+
+static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
+{
+ unsigned int stat;
+ u32 *buf = _buf;
+
+ while (bytes > 3) {
+ stat = mxcmci_poll_status(host,
+ STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+ if (stat)
+ return stat;
+ *buf++ = readl(host->base + MMC_REG_BUFFER_ACCESS);
+ bytes -= 4;
+ }
+
+ if (bytes) {
+ u8 *b = (u8 *)buf;
+ u32 tmp;
+
+ stat = mxcmci_poll_status(host,
+ STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+ if (stat)
+ return stat;
+ tmp = readl(host->base + MMC_REG_BUFFER_ACCESS);
+ memcpy(b, &tmp, bytes);
+ }
+
+ return 0;
+}
+
+static int mxcmci_push(struct mxcmci_host *host, void *_buf, int bytes)
+{
+ unsigned int stat;
+ u32 *buf = _buf;
+
+ while (bytes > 3) {
+ stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+ if (stat)
+ return stat;
+ writel(*buf++, host->base + MMC_REG_BUFFER_ACCESS);
+ bytes -= 4;
+ }
+
+ if (bytes) {
+ u8 *b = (u8 *)buf;
+ u32 tmp;
+
+ stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+ if (stat)
+ return stat;
+
+ memcpy(&tmp, b, bytes);
+ writel(tmp, host->base + MMC_REG_BUFFER_ACCESS);
+ }
+
+ stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+ if (stat)
+ return stat;
+
+ return 0;
+}
+
+static int mxcmci_transfer_data(struct mxcmci_host *host)
+{
+ struct mmc_data *data = host->req->data;
+ struct scatterlist *sg;
+ int stat, i;
+
+ host->datasize = 0;
+
+ host->data = data;
+ host->datasize = 0;
+
+ if (data->flags & MMC_DATA_READ) {
+ for_each_sg(data->sg, sg, data->sg_len, i) {
+ stat = mxcmci_pull(host, sg_virt(sg), sg->length);
+ if (stat)
+ return stat;
+ host->datasize += sg->length;
+ }
+ } else {
+ for_each_sg(data->sg, sg, data->sg_len, i) {
+ stat = mxcmci_push(host, sg_virt(sg), sg->length);
+ if (stat)
+ return stat;
+ host->datasize += sg->length;
+ }
+ stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
+ if (stat)
+ return stat;
+ }
+ return 0;
+}
+
+static void mxcmci_datawork(struct work_struct *work)
+{
+ struct mxcmci_host *host = container_of(work, struct mxcmci_host,
+ datawork);
+ int datastat = mxcmci_transfer_data(host);
+ mxcmci_finish_data(host, datastat);
+
+ if (host->req->stop) {
+ if (mxcmci_start_cmd(host, host->req->stop, 0)) {
+ mxcmci_finish_request(host, host->req);
+ return;
+ }
+ } else {
+ mxcmci_finish_request(host, host->req);
+ }
+}
+
+#ifdef HAS_DMA
+static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
+{
+ struct mmc_data *data = host->data;
+ int data_error;
+
+ if (!data)
+ return;
+
+ data_error = mxcmci_finish_data(host, stat);
+
+ mxcmci_read_response(host, stat);
+ host->cmd = NULL;
+
+ if (host->req->stop) {
+ if (mxcmci_start_cmd(host, host->req->stop, 0)) {
+ mxcmci_finish_request(host, host->req);
+ return;
+ }
+ } else {
+ mxcmci_finish_request(host, host->req);
+ }
+}
+#endif /* HAS_DMA */
+
+static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
+{
+ mxcmci_read_response(host, stat);
+ host->cmd = NULL;
+
+ if (!host->data && host->req) {
+ mxcmci_finish_request(host, host->req);
+ return;
+ }
+
+ /* For the DMA case the DMA engine handles the data transfer
+ * automatically. For non DMA we have to to it ourselves.
+ * Don't do it in interrupt context though.
+ */
+ if (!mxcmci_use_dma(host) && host->data)
+ schedule_work(&host->datawork);
+
+}
+
+static irqreturn_t mxcmci_irq(int irq, void *devid)
+{
+ struct mxcmci_host *host = devid;
+ u32 stat;
+
+ stat = readl(host->base + MMC_REG_STATUS);
+ writel(stat, host->base + MMC_REG_STATUS);
+
+ dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
+
+ if (stat & STATUS_END_CMD_RESP)
+ mxcmci_cmd_done(host, stat);
+#ifdef HAS_DMA
+ if (mxcmci_use_dma(host) &&
+ (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
+ mxcmci_data_done(host, stat);
+#endif
+ return IRQ_HANDLED;
+}
+
+static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+ struct mxcmci_host *host = mmc_priv(mmc);
+ unsigned int cmdat = host->cmdat;
+
+ WARN_ON(host->req != NULL);
+
+ host->req = req;
+ host->cmdat &= ~CMD_DAT_CONT_INIT;
+#ifdef HAS_DMA
+ host->do_dma = 1;
+#endif
+ if (req->data) {
+ mxcmci_setup_data(host, req->data);
+
+ cmdat |= CMD_DAT_CONT_DATA_ENABLE;
+
+ if (req->data->flags & MMC_DATA_WRITE)
+ cmdat |= CMD_DAT_CONT_WRITE;
+ }
+
+ if (mxcmci_start_cmd(host, req->cmd, cmdat))
+ mxcmci_finish_request(host, req);
+}
+
+static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
+{
+ unsigned int divider;
+ int prescaler = 0;
+ unsigned int clk_in = clk_get_rate(host->clk);
+
+ while (prescaler <= 0x800) {
+ for (divider = 1; divider <= 0xF; divider++) {
+ int x;
+
+ x = (clk_in / (divider + 1));
+
+ if (prescaler)
+ x /= (prescaler * 2);
+
+ if (x <= clk_ios)
+ break;
+ }
+ if (divider < 0x10)
+ break;
+
+ if (prescaler == 0)
+ prescaler = 1;
+ else
+ prescaler <<= 1;
+ }
+
+ writew((prescaler << 4) | divider, host->base + MMC_REG_CLK_RATE);
+
+ dev_dbg(mmc_dev(host->mmc), "scaler: %d divider: %d in: %d out: %d\n",
+ prescaler, divider, clk_in, clk_ios);
+}
+
+static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct mxcmci_host *host = mmc_priv(mmc);
+#ifdef HAS_DMA
+ unsigned int blen;
+ /*
+ * use burstlen of 64 in 4 bit mode (--> reg value 0)
+ * use burstlen of 16 in 1 bit mode (--> reg value 16)
+ */
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+ blen = 0;
+ else
+ blen = 16;
+
+ imx_dma_config_burstlen(host->dma, blen);
+#endif
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+ host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
+ else
+ host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
+
+ if (host->power_mode != ios->power_mode) {
+ if (host->pdata && host->pdata->setpower)
+ host->pdata->setpower(mmc_dev(mmc), ios->vdd);
+ host->power_mode = ios->power_mode;
+ if (ios->power_mode == MMC_POWER_ON)
+ host->cmdat |= CMD_DAT_CONT_INIT;
+ }
+
+ if (ios->clock) {
+ mxcmci_set_clk_rate(host, ios->clock);
+ writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
+ } else {
+ writew(STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK);
+ }
+
+ host->clock = ios->clock;
+}
+
+static irqreturn_t mxcmci_detect_irq(int irq, void *data)
+{
+ struct mmc_host *mmc = data;
+
+ dev_dbg(mmc_dev(mmc), "%s\n", __func__);
+
+ mmc_detect_change(mmc, msecs_to_jiffies(250));
+ return IRQ_HANDLED;
+}
+
+static int mxcmci_get_ro(struct mmc_host *mmc)
+{
+ struct mxcmci_host *host = mmc_priv(mmc);
+
+ if (host->pdata && host->pdata->get_ro)
+ return !!host->pdata->get_ro(mmc_dev(mmc));
+ /*
+ * Board doesn't support read only detection; let the mmc core
+ * decide what to do.
+ */
+ return -ENOSYS;
+}
+
+
+static const struct mmc_host_ops mxcmci_ops = {
+ .request = mxcmci_request,
+ .set_ios = mxcmci_set_ios,
+ .get_ro = mxcmci_get_ro,
+};
+
+static int mxcmci_probe(struct platform_device *pdev)
+{
+ struct mmc_host *mmc;
+ struct mxcmci_host *host = NULL;
+ struct resource *r;
+ int ret = 0, irq;
+
+ printk(KERN_INFO "i.MX SDHC driver\n");
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!r || irq < 0)
+ return -EINVAL;
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (!r)
+ return -EBUSY;
+
+ mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto out_release_mem;
+ }
+
+ mmc->ops = &mxcmci_ops;
+ mmc->caps = MMC_CAP_4_BIT_DATA;
+
+ /* MMC core transfer sizes tunable parameters */
+ mmc->max_hw_segs = 64;
+ mmc->max_phys_segs = 64;
+ mmc->max_blk_size = 2048;
+ mmc->max_blk_count = 65535;
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_seg_size;
+
+ host = mmc_priv(mmc);
+ host->base = ioremap(r->start, resource_size(r));
+ if (!host->base) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+
+ host->mmc = mmc;
+ host->pdata = pdev->dev.platform_data;
+
+ if (host->pdata && host->pdata->ocr_avail)
+ mmc->ocr_avail = host->pdata->ocr_avail;
+ else
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ host->res = r;
+ host->irq = irq;
+
+ host->clk = clk_get(&pdev->dev, "sdhc_clk");
+ if (IS_ERR(host->clk)) {
+ ret = PTR_ERR(host->clk);
+ goto out_iounmap;
+ }
+ clk_enable(host->clk);
+
+ mxcmci_softreset(host);
+
+ host->rev_no = readw(host->base + MMC_REG_REV_NO);
+ if (host->rev_no != 0x400) {
+ ret = -ENODEV;
+ dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
+ host->rev_no);
+ goto out_clk_put;
+ }
+
+ mmc->f_min = clk_get_rate(host->clk) >> 7;
+ mmc->f_max = clk_get_rate(host->clk) >> 1;
+
+ /* recommended in data sheet */
+ writew(0x2db4, host->base + MMC_REG_READ_TO);
+
+ writel(0, host->base + MMC_REG_INT_CNTR);
+
+#ifdef HAS_DMA
+ host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
+ if (host->dma < 0) {
+ dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");
+ ret = -EBUSY;
+ goto out_clk_put;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!r) {
+ ret = -EINVAL;
+ goto out_free_dma;
+ }
+
+ ret = imx_dma_config_channel(host->dma,
+ IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO,
+ IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
+ r->start, 0);
+ if (ret) {
+ dev_err(mmc_dev(host->mmc), "failed to config DMA channel\n");
+ goto out_free_dma;
+ }
+#endif
+ INIT_WORK(&host->datawork, mxcmci_datawork);
+
+ ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host);
+ if (ret)
+ goto out_free_dma;
+
+ platform_set_drvdata(pdev, mmc);
+
+ if (host->pdata && host->pdata->init) {
+ ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq,
+ host->mmc);
+ if (ret)
+ goto out_free_irq;
+ }
+
+ mmc_add_host(mmc);
+
+ return 0;
+
+out_free_irq:
+ free_irq(host->irq, host);
+out_free_dma:
+#ifdef HAS_DMA
+ imx_dma_free(host->dma);
+#endif
+out_clk_put:
+ clk_disable(host->clk);
+ clk_put(host->clk);
+out_iounmap:
+ iounmap(host->base);
+out_free:
+ mmc_free_host(mmc);
+out_release_mem:
+ release_mem_region(host->res->start, resource_size(host->res));
+ return ret;
+}
+
+static int mxcmci_remove(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+ struct mxcmci_host *host = mmc_priv(mmc);
+
+ platform_set_drvdata(pdev, NULL);
+
+ mmc_remove_host(mmc);
+
+ if (host->pdata && host->pdata->exit)
+ host->pdata->exit(&pdev->dev, mmc);
+
+ free_irq(host->irq, host);
+ iounmap(host->base);
+#ifdef HAS_DMA
+ imx_dma_free(host->dma);
+#endif
+ clk_disable(host->clk);
+ clk_put(host->clk);
+
+ release_mem_region(host->res->start, resource_size(host->res));
+ release_resource(host->res);
+
+ mmc_free_host(mmc);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mxcmci_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+ int ret = 0;
+
+ if (mmc)
+ ret = mmc_suspend_host(mmc, state);
+
+ return ret;
+}
+
+static int mxcmci_resume(struct platform_device *dev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+ struct mxcmci_host *host;
+ int ret = 0;
+
+ if (mmc) {
+ host = mmc_priv(mmc);
+ ret = mmc_resume_host(mmc);
+ }
+
+ return ret;
+}
+#else
+#define mxcmci_suspend NULL
+#define mxcmci_resume NULL
+#endif /* CONFIG_PM */
+
+static struct platform_driver mxcmci_driver = {
+ .probe = mxcmci_probe,
+ .remove = mxcmci_remove,
+ .suspend = mxcmci_suspend,
+ .resume = mxcmci_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ }
+};
+
+static int __init mxcmci_init(void)
+{
+ return platform_driver_register(&mxcmci_driver);
+}
+
+static void __exit mxcmci_exit(void)
+{
+ platform_driver_unregister(&mxcmci_driver);
+}
+
+module_init(mxcmci_init);
+module_exit(mxcmci_exit);
+
+MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-mmc");
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index fb2921f8099..0c44d560bf1 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -103,7 +103,7 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi)
if (!gpio_is_valid(oms->gpios[i]))
continue;
- ret = gpio_request(oms->gpios[i], dev->bus_id);
+ ret = gpio_request(oms->gpios[i], dev_name(dev));
if (ret < 0) {
oms->gpios[i] = -EINVAL;
continue;
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
new file mode 100644
index 00000000000..a631c81dce1
--- /dev/null
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -0,0 +1,1280 @@
+/*
+ * drivers/mmc/host/omap_hsmmc.c
+ *
+ * Driver for OMAP2430/3430 MMC controller.
+ *
+ * Copyright (C) 2007 Texas Instruments.
+ *
+ * Authors:
+ * Syed Mohammed Khasim <x0khasim@ti.com>
+ * Madhusudhan <madhu.cr@ti.com>
+ * Mohit Jalori <mjalori@ti.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <mach/dma.h>
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/mmc.h>
+#include <mach/cpu.h>
+
+/* OMAP HSMMC Host Controller Registers */
+#define OMAP_HSMMC_SYSCONFIG 0x0010
+#define OMAP_HSMMC_CON 0x002C
+#define OMAP_HSMMC_BLK 0x0104
+#define OMAP_HSMMC_ARG 0x0108
+#define OMAP_HSMMC_CMD 0x010C
+#define OMAP_HSMMC_RSP10 0x0110
+#define OMAP_HSMMC_RSP32 0x0114
+#define OMAP_HSMMC_RSP54 0x0118
+#define OMAP_HSMMC_RSP76 0x011C
+#define OMAP_HSMMC_DATA 0x0120
+#define OMAP_HSMMC_HCTL 0x0128
+#define OMAP_HSMMC_SYSCTL 0x012C
+#define OMAP_HSMMC_STAT 0x0130
+#define OMAP_HSMMC_IE 0x0134
+#define OMAP_HSMMC_ISE 0x0138
+#define OMAP_HSMMC_CAPA 0x0140
+
+#define VS18 (1 << 26)
+#define VS30 (1 << 25)
+#define SDVS18 (0x5 << 9)
+#define SDVS30 (0x6 << 9)
+#define SDVS33 (0x7 << 9)
+#define SDVSCLR 0xFFFFF1FF
+#define SDVSDET 0x00000400
+#define AUTOIDLE 0x1
+#define SDBP (1 << 8)
+#define DTO 0xe
+#define ICE 0x1
+#define ICS 0x2
+#define CEN (1 << 2)
+#define CLKD_MASK 0x0000FFC0
+#define CLKD_SHIFT 6
+#define DTO_MASK 0x000F0000
+#define DTO_SHIFT 16
+#define INT_EN_MASK 0x307F0033
+#define INIT_STREAM (1 << 1)
+#define DP_SELECT (1 << 21)
+#define DDIR (1 << 4)
+#define DMA_EN 0x1
+#define MSBS (1 << 5)
+#define BCE (1 << 1)
+#define FOUR_BIT (1 << 1)
+#define CC 0x1
+#define TC 0x02
+#define OD 0x1
+#define ERR (1 << 15)
+#define CMD_TIMEOUT (1 << 16)
+#define DATA_TIMEOUT (1 << 20)
+#define CMD_CRC (1 << 17)
+#define DATA_CRC (1 << 21)
+#define CARD_ERR (1 << 28)
+#define STAT_CLEAR 0xFFFFFFFF
+#define INIT_STREAM_CMD 0x00000000
+#define DUAL_VOLT_OCR_BIT 7
+#define SRC (1 << 25)
+#define SRD (1 << 26)
+
+/*
+ * FIXME: Most likely all the data using these _DEVID defines should come
+ * from the platform_data, or implemented in controller and slot specific
+ * functions.
+ */
+#define OMAP_MMC1_DEVID 0
+#define OMAP_MMC2_DEVID 1
+
+#define OMAP_MMC_DATADIR_NONE 0
+#define OMAP_MMC_DATADIR_READ 1
+#define OMAP_MMC_DATADIR_WRITE 2
+#define MMC_TIMEOUT_MS 20
+#define OMAP_MMC_MASTER_CLOCK 96000000
+#define DRIVER_NAME "mmci-omap-hs"
+
+/*
+ * One controller can have multiple slots, like on some omap boards using
+ * omap.c controller driver. Luckily this is not currently done on any known
+ * omap_hsmmc.c device.
+ */
+#define mmc_slot(host) (host->pdata->slots[host->slot_id])
+
+/*
+ * MMC Host controller read/write API's
+ */
+#define OMAP_HSMMC_READ(base, reg) \
+ __raw_readl((base) + OMAP_HSMMC_##reg)
+
+#define OMAP_HSMMC_WRITE(base, reg, val) \
+ __raw_writel((val), (base) + OMAP_HSMMC_##reg)
+
+struct mmc_omap_host {
+ struct device *dev;
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+ struct clk *fclk;
+ struct clk *iclk;
+ struct clk *dbclk;
+ struct semaphore sem;
+ struct work_struct mmc_carddetect_work;
+ void __iomem *base;
+ resource_size_t mapbase;
+ unsigned int id;
+ unsigned int dma_len;
+ unsigned int dma_dir;
+ unsigned char bus_mode;
+ unsigned char datadir;
+ u32 *buffer;
+ u32 bytesleft;
+ int suspended;
+ int irq;
+ int carddetect;
+ int use_dma, dma_ch;
+ int initstr;
+ int slot_id;
+ int dbclk_enabled;
+ struct omap_mmc_platform_data *pdata;
+};
+
+/*
+ * Stop clock to the card
+ */
+static void omap_mmc_stop_clock(struct mmc_omap_host *host)
+{
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) & ~CEN);
+ if ((OMAP_HSMMC_READ(host->base, SYSCTL) & CEN) != 0x0)
+ dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n");
+}
+
+/*
+ * Send init stream sequence to card
+ * before sending IDLE command
+ */
+static void send_init_stream(struct mmc_omap_host *host)
+{
+ int reg = 0;
+ unsigned long timeout;
+
+ disable_irq(host->irq);
+ OMAP_HSMMC_WRITE(host->base, CON,
+ OMAP_HSMMC_READ(host->base, CON) | INIT_STREAM);
+ OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD);
+
+ timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+ while ((reg != CC) && time_before(jiffies, timeout))
+ reg = OMAP_HSMMC_READ(host->base, STAT) & CC;
+
+ OMAP_HSMMC_WRITE(host->base, CON,
+ OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM);
+ enable_irq(host->irq);
+}
+
+static inline
+int mmc_omap_cover_is_closed(struct mmc_omap_host *host)
+{
+ int r = 1;
+
+ if (host->pdata->slots[host->slot_id].get_cover_state)
+ r = host->pdata->slots[host->slot_id].get_cover_state(host->dev,
+ host->slot_id);
+ return r;
+}
+
+static ssize_t
+mmc_omap_show_cover_switch(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
+ struct mmc_omap_host *host = mmc_priv(mmc);
+
+ return sprintf(buf, "%s\n", mmc_omap_cover_is_closed(host) ? "closed" :
+ "open");
+}
+
+static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL);
+
+static ssize_t
+mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
+ struct mmc_omap_host *host = mmc_priv(mmc);
+ struct omap_mmc_slot_data slot = host->pdata->slots[host->slot_id];
+
+ return sprintf(buf, "slot:%s\n", slot.name);
+}
+
+static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
+
+/*
+ * Configure the response type and send the cmd.
+ */
+static void
+mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
+ struct mmc_data *data)
+{
+ int cmdreg = 0, resptype = 0, cmdtype = 0;
+
+ dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
+ mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
+ host->cmd = cmd;
+
+ /*
+ * Clear status bits and enable interrupts
+ */
+ OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ if (cmd->flags & MMC_RSP_136)
+ resptype = 1;
+ else
+ resptype = 2;
+ }
+
+ /*
+ * Unlike OMAP1 controller, the cmdtype does not seem to be based on
+ * ac, bc, adtc, bcr. Only commands ending an open ended transfer need
+ * a val of 0x3, rest 0x0.
+ */
+ if (cmd == host->mrq->stop)
+ cmdtype = 0x3;
+
+ cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22);
+
+ if (data) {
+ cmdreg |= DP_SELECT | MSBS | BCE;
+ if (data->flags & MMC_DATA_READ)
+ cmdreg |= DDIR;
+ else
+ cmdreg &= ~(DDIR);
+ }
+
+ if (host->use_dma)
+ cmdreg |= DMA_EN;
+
+ OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg);
+ OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
+}
+
+/*
+ * Notify the transfer complete to MMC core
+ */
+static void
+mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
+{
+ host->data = NULL;
+
+ if (host->use_dma && host->dma_ch != -1)
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
+ host->dma_dir);
+
+ host->datadir = OMAP_MMC_DATADIR_NONE;
+
+ if (!data->error)
+ data->bytes_xfered += data->blocks * (data->blksz);
+ else
+ data->bytes_xfered = 0;
+
+ if (!data->stop) {
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, data->mrq);
+ return;
+ }
+ mmc_omap_start_command(host, data->stop, NULL);
+}
+
+/*
+ * Notify the core about command completion
+ */
+static void
+mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
+{
+ host->cmd = NULL;
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ if (cmd->flags & MMC_RSP_136) {
+ /* response type 2 */
+ cmd->resp[3] = OMAP_HSMMC_READ(host->base, RSP10);
+ cmd->resp[2] = OMAP_HSMMC_READ(host->base, RSP32);
+ cmd->resp[1] = OMAP_HSMMC_READ(host->base, RSP54);
+ cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP76);
+ } else {
+ /* response types 1, 1b, 3, 4, 5, 6 */
+ cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
+ }
+ }
+ if (host->data == NULL || cmd->error) {
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, cmd->mrq);
+ }
+}
+
+/*
+ * DMA clean up for command errors
+ */
+static void mmc_dma_cleanup(struct mmc_omap_host *host)
+{
+ host->data->error = -ETIMEDOUT;
+
+ if (host->use_dma && host->dma_ch != -1) {
+ dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
+ host->dma_dir);
+ omap_free_dma(host->dma_ch);
+ host->dma_ch = -1;
+ up(&host->sem);
+ }
+ host->data = NULL;
+ host->datadir = OMAP_MMC_DATADIR_NONE;
+}
+
+/*
+ * Readable error output
+ */
+#ifdef CONFIG_MMC_DEBUG
+static void mmc_omap_report_irq(struct mmc_omap_host *host, u32 status)
+{
+ /* --- means reserved bit without definition at documentation */
+ static const char *mmc_omap_status_bits[] = {
+ "CC", "TC", "BGE", "---", "BWR", "BRR", "---", "---", "CIRQ",
+ "OBI", "---", "---", "---", "---", "---", "ERRI", "CTO", "CCRC",
+ "CEB", "CIE", "DTO", "DCRC", "DEB", "---", "ACE", "---",
+ "---", "---", "---", "CERR", "CERR", "BADA", "---", "---", "---"
+ };
+ char res[256];
+ char *buf = res;
+ int len, i;
+
+ len = sprintf(buf, "MMC IRQ 0x%x :", status);
+ buf += len;
+
+ for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++)
+ if (status & (1 << i)) {
+ len = sprintf(buf, " %s", mmc_omap_status_bits[i]);
+ buf += len;
+ }
+
+ dev_dbg(mmc_dev(host->mmc), "%s\n", res);
+}
+#endif /* CONFIG_MMC_DEBUG */
+
+/*
+ * MMC controller internal state machines reset
+ *
+ * Used to reset command or data internal state machines, using respectively
+ * SRC or SRD bit of SYSCTL register
+ * Can be called from interrupt context
+ */
+static inline void mmc_omap_reset_controller_fsm(struct mmc_omap_host *host,
+ unsigned long bit)
+{
+ unsigned long i = 0;
+ unsigned long limit = (loops_per_jiffy *
+ msecs_to_jiffies(MMC_TIMEOUT_MS));
+
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
+
+ while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
+ (i++ < limit))
+ cpu_relax();
+
+ if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
+ dev_err(mmc_dev(host->mmc),
+ "Timeout waiting on controller reset in %s\n",
+ __func__);
+}
+
+/*
+ * MMC controller IRQ handler
+ */
+static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
+{
+ struct mmc_omap_host *host = dev_id;
+ struct mmc_data *data;
+ int end_cmd = 0, end_trans = 0, status;
+
+ if (host->cmd == NULL && host->data == NULL) {
+ OMAP_HSMMC_WRITE(host->base, STAT,
+ OMAP_HSMMC_READ(host->base, STAT));
+ return IRQ_HANDLED;
+ }
+
+ data = host->data;
+ status = OMAP_HSMMC_READ(host->base, STAT);
+ dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
+
+ if (status & ERR) {
+#ifdef CONFIG_MMC_DEBUG
+ mmc_omap_report_irq(host, status);
+#endif
+ if ((status & CMD_TIMEOUT) ||
+ (status & CMD_CRC)) {
+ if (host->cmd) {
+ if (status & CMD_TIMEOUT) {
+ mmc_omap_reset_controller_fsm(host, SRC);
+ host->cmd->error = -ETIMEDOUT;
+ } else {
+ host->cmd->error = -EILSEQ;
+ }
+ end_cmd = 1;
+ }
+ if (host->data) {
+ mmc_dma_cleanup(host);
+ mmc_omap_reset_controller_fsm(host, SRD);
+ }
+ }
+ if ((status & DATA_TIMEOUT) ||
+ (status & DATA_CRC)) {
+ if (host->data) {
+ if (status & DATA_TIMEOUT)
+ mmc_dma_cleanup(host);
+ else
+ host->data->error = -EILSEQ;
+ mmc_omap_reset_controller_fsm(host, SRD);
+ end_trans = 1;
+ }
+ }
+ if (status & CARD_ERR) {
+ dev_dbg(mmc_dev(host->mmc),
+ "Ignoring card err CMD%d\n", host->cmd->opcode);
+ if (host->cmd)
+ end_cmd = 1;
+ if (host->data)
+ end_trans = 1;
+ }
+ }
+
+ OMAP_HSMMC_WRITE(host->base, STAT, status);
+
+ if (end_cmd || (status & CC))
+ mmc_omap_cmd_done(host, host->cmd);
+ if (end_trans || (status & TC))
+ mmc_omap_xfer_done(host, data);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Switch MMC interface voltage ... only relevant for MMC1.
+ *
+ * MMC2 and MMC3 use fixed 1.8V levels, and maybe a transceiver.
+ * The MMC2 transceiver controls are used instead of DAT4..DAT7.
+ * Some chips, like eMMC ones, use internal transceivers.
+ */
+static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
+{
+ u32 reg_val = 0;
+ int ret;
+
+ if (host->id != OMAP_MMC1_DEVID)
+ return 0;
+
+ /* Disable the clocks */
+ clk_disable(host->fclk);
+ clk_disable(host->iclk);
+ clk_disable(host->dbclk);
+
+ /* Turn the power off */
+ ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
+ if (ret != 0)
+ goto err;
+
+ /* Turn the power ON with given VDD 1.8 or 3.0v */
+ ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, vdd);
+ if (ret != 0)
+ goto err;
+
+ clk_enable(host->fclk);
+ clk_enable(host->iclk);
+ clk_enable(host->dbclk);
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR);
+ reg_val = OMAP_HSMMC_READ(host->base, HCTL);
+
+ /*
+ * If a MMC dual voltage card is detected, the set_ios fn calls
+ * this fn with VDD bit set for 1.8V. Upon card removal from the
+ * slot, omap_mmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF.
+ *
+ * Cope with a bit of slop in the range ... per data sheets:
+ * - "1.8V" for vdds_mmc1/vdds_mmc1a can be up to 2.45V max,
+ * but recommended values are 1.71V to 1.89V
+ * - "3.0V" for vdds_mmc1/vdds_mmc1a can be up to 3.5V max,
+ * but recommended values are 2.7V to 3.3V
+ *
+ * Board setup code shouldn't permit anything very out-of-range.
+ * TWL4030-family VMMC1 and VSIM regulators are fine (avoiding the
+ * middle range) but VSIM can't power DAT4..DAT7 at more than 3V.
+ */
+ if ((1 << vdd) <= MMC_VDD_23_24)
+ reg_val |= SDVS18;
+ else
+ reg_val |= SDVS30;
+
+ OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+
+ return 0;
+err:
+ dev_dbg(mmc_dev(host->mmc), "Unable to switch operating voltage\n");
+ return ret;
+}
+
+/*
+ * Work Item to notify the core about card insertion/removal
+ */
+static void mmc_omap_detect(struct work_struct *work)
+{
+ struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
+ mmc_carddetect_work);
+ struct omap_mmc_slot_data *slot = &mmc_slot(host);
+
+ host->carddetect = slot->card_detect(slot->card_detect_irq);
+
+ sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
+ if (host->carddetect) {
+ mmc_detect_change(host->mmc, (HZ * 200) / 1000);
+ } else {
+ mmc_omap_reset_controller_fsm(host, SRD);
+ mmc_detect_change(host->mmc, (HZ * 50) / 1000);
+ }
+}
+
+/*
+ * ISR for handling card insertion and removal
+ */
+static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id)
+{
+ struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id;
+
+ schedule_work(&host->mmc_carddetect_work);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * DMA call back function
+ */
+static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
+{
+ struct mmc_omap_host *host = data;
+
+ if (ch_status & OMAP2_DMA_MISALIGNED_ERR_IRQ)
+ dev_dbg(mmc_dev(host->mmc), "MISALIGNED_ADRS_ERR\n");
+
+ if (host->dma_ch < 0)
+ return;
+
+ omap_free_dma(host->dma_ch);
+ host->dma_ch = -1;
+ /*
+ * DMA Callback: run in interrupt context.
+ * mutex_unlock will through a kernel warning if used.
+ */
+ up(&host->sem);
+}
+
+/*
+ * Configure dma src and destination parameters
+ */
+static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,
+ struct mmc_data *data)
+{
+ if (sync_dir == 0) {
+ omap_set_dma_dest_params(host->dma_ch, 0,
+ OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_src_params(host->dma_ch, 0,
+ OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(&data->sg[0]), 0, 0);
+ } else {
+ omap_set_dma_src_params(host->dma_ch, 0,
+ OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_dest_params(host->dma_ch, 0,
+ OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(&data->sg[0]), 0, 0);
+ }
+ return 0;
+}
+/*
+ * Routine to configure and start DMA for the MMC card
+ */
+static int
+mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
+{
+ int sync_dev, sync_dir = 0;
+ int dma_ch = 0, ret = 0, err = 1;
+ struct mmc_data *data = req->data;
+
+ /*
+ * If for some reason the DMA transfer is still active,
+ * we wait for timeout period and free the dma
+ */
+ if (host->dma_ch != -1) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(100);
+ if (down_trylock(&host->sem)) {
+ omap_free_dma(host->dma_ch);
+ host->dma_ch = -1;
+ up(&host->sem);
+ return err;
+ }
+ } else {
+ if (down_trylock(&host->sem))
+ return err;
+ }
+
+ if (!(data->flags & MMC_DATA_WRITE)) {
+ host->dma_dir = DMA_FROM_DEVICE;
+ if (host->id == OMAP_MMC1_DEVID)
+ sync_dev = OMAP24XX_DMA_MMC1_RX;
+ else
+ sync_dev = OMAP24XX_DMA_MMC2_RX;
+ } else {
+ host->dma_dir = DMA_TO_DEVICE;
+ if (host->id == OMAP_MMC1_DEVID)
+ sync_dev = OMAP24XX_DMA_MMC1_TX;
+ else
+ sync_dev = OMAP24XX_DMA_MMC2_TX;
+ }
+
+ ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb,
+ host, &dma_ch);
+ if (ret != 0) {
+ dev_dbg(mmc_dev(host->mmc),
+ "%s: omap_request_dma() failed with %d\n",
+ mmc_hostname(host->mmc), ret);
+ return ret;
+ }
+
+ host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma_dir);
+ host->dma_ch = dma_ch;
+
+ if (!(data->flags & MMC_DATA_WRITE))
+ mmc_omap_config_dma_param(1, host, data);
+ else
+ mmc_omap_config_dma_param(0, host, data);
+
+ if ((data->blksz % 4) == 0)
+ omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
+ (data->blksz / 4), data->blocks, OMAP_DMA_SYNC_FRAME,
+ sync_dev, sync_dir);
+ else
+ /* REVISIT: The MMC buffer increments only when MSB is written.
+ * Return error for blksz which is non multiple of four.
+ */
+ return -EINVAL;
+
+ omap_start_dma(dma_ch);
+ return 0;
+}
+
+static void set_data_timeout(struct mmc_omap_host *host,
+ struct mmc_request *req)
+{
+ unsigned int timeout, cycle_ns;
+ uint32_t reg, clkd, dto = 0;
+
+ reg = OMAP_HSMMC_READ(host->base, SYSCTL);
+ clkd = (reg & CLKD_MASK) >> CLKD_SHIFT;
+ if (clkd == 0)
+ clkd = 1;
+
+ cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd);
+ timeout = req->data->timeout_ns / cycle_ns;
+ timeout += req->data->timeout_clks;
+ if (timeout) {
+ while ((timeout & 0x80000000) == 0) {
+ dto += 1;
+ timeout <<= 1;
+ }
+ dto = 31 - dto;
+ timeout <<= 1;
+ if (timeout && dto)
+ dto += 1;
+ if (dto >= 13)
+ dto -= 13;
+ else
+ dto = 0;
+ if (dto > 14)
+ dto = 14;
+ }
+
+ reg &= ~DTO_MASK;
+ reg |= dto << DTO_SHIFT;
+ OMAP_HSMMC_WRITE(host->base, SYSCTL, reg);
+}
+
+/*
+ * Configure block length for MMC/SD cards and initiate the transfer.
+ */
+static int
+mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
+{
+ int ret;
+ host->data = req->data;
+
+ if (req->data == NULL) {
+ host->datadir = OMAP_MMC_DATADIR_NONE;
+ OMAP_HSMMC_WRITE(host->base, BLK, 0);
+ return 0;
+ }
+
+ OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz)
+ | (req->data->blocks << 16));
+ set_data_timeout(host, req);
+
+ host->datadir = (req->data->flags & MMC_DATA_WRITE) ?
+ OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;
+
+ if (host->use_dma) {
+ ret = mmc_omap_start_dma_transfer(host, req);
+ if (ret != 0) {
+ dev_dbg(mmc_dev(host->mmc), "MMC start dma failure\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Request function. for read/write operation
+ */
+static void omap_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+ struct mmc_omap_host *host = mmc_priv(mmc);
+
+ WARN_ON(host->mrq != NULL);
+ host->mrq = req;
+ mmc_omap_prepare_data(host, req);
+ mmc_omap_start_command(host, req->cmd, req->data);
+}
+
+
+/* Routine to configure clock values. Exposed API to core */
+static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct mmc_omap_host *host = mmc_priv(mmc);
+ u16 dsor = 0;
+ unsigned long regval;
+ unsigned long timeout;
+
+ switch (ios->power_mode) {
+ case MMC_POWER_OFF:
+ mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
+ /*
+ * Reset interface voltage to 3V if it's 1.8V now;
+ * only relevant on MMC-1, the others always use 1.8V.
+ *
+ * REVISIT: If we are able to detect cards after unplugging
+ * a 1.8V card, this code should not be needed.
+ */
+ if (host->id != OMAP_MMC1_DEVID)
+ break;
+ if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
+ int vdd = fls(host->mmc->ocr_avail) - 1;
+ if (omap_mmc_switch_opcond(host, vdd) != 0)
+ host->mmc->ios.vdd = vdd;
+ }
+ break;
+ case MMC_POWER_UP:
+ mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd);
+ break;
+ }
+
+ switch (mmc->ios.bus_width) {
+ case MMC_BUS_WIDTH_4:
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
+ break;
+ case MMC_BUS_WIDTH_1:
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
+ break;
+ }
+
+ if (host->id == OMAP_MMC1_DEVID) {
+ /* Only MMC1 can interface at 3V without some flavor
+ * of external transceiver; but they all handle 1.8V.
+ */
+ if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) &&
+ (ios->vdd == DUAL_VOLT_OCR_BIT)) {
+ /*
+ * The mmc_select_voltage fn of the core does
+ * not seem to set the power_mode to
+ * MMC_POWER_UP upon recalculating the voltage.
+ * vdd 1.8v.
+ */
+ if (omap_mmc_switch_opcond(host, ios->vdd) != 0)
+ dev_dbg(mmc_dev(host->mmc),
+ "Switch operation failed\n");
+ }
+ }
+
+ if (ios->clock) {
+ dsor = OMAP_MMC_MASTER_CLOCK / ios->clock;
+ if (dsor < 1)
+ dsor = 1;
+
+ if (OMAP_MMC_MASTER_CLOCK / dsor > ios->clock)
+ dsor++;
+
+ if (dsor > 250)
+ dsor = 250;
+ }
+ omap_mmc_stop_clock(host);
+ regval = OMAP_HSMMC_READ(host->base, SYSCTL);
+ regval = regval & ~(CLKD_MASK);
+ regval = regval | (dsor << 6) | (DTO << 16);
+ OMAP_HSMMC_WRITE(host->base, SYSCTL, regval);
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
+
+ /* Wait till the ICS bit is set */
+ timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+ while ((OMAP_HSMMC_READ(host->base, SYSCTL) & ICS) != 0x2
+ && time_before(jiffies, timeout))
+ msleep(1);
+
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) | CEN);
+
+ if (ios->power_mode == MMC_POWER_ON)
+ send_init_stream(host);
+
+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+ OMAP_HSMMC_WRITE(host->base, CON,
+ OMAP_HSMMC_READ(host->base, CON) | OD);
+}
+
+static int omap_hsmmc_get_cd(struct mmc_host *mmc)
+{
+ struct mmc_omap_host *host = mmc_priv(mmc);
+ struct omap_mmc_platform_data *pdata = host->pdata;
+
+ if (!pdata->slots[0].card_detect)
+ return -ENOSYS;
+ return pdata->slots[0].card_detect(pdata->slots[0].card_detect_irq);
+}
+
+static int omap_hsmmc_get_ro(struct mmc_host *mmc)
+{
+ struct mmc_omap_host *host = mmc_priv(mmc);
+ struct omap_mmc_platform_data *pdata = host->pdata;
+
+ if (!pdata->slots[0].get_ro)
+ return -ENOSYS;
+ return pdata->slots[0].get_ro(host->dev, 0);
+}
+
+static struct mmc_host_ops mmc_omap_ops = {
+ .request = omap_mmc_request,
+ .set_ios = omap_mmc_set_ios,
+ .get_cd = omap_hsmmc_get_cd,
+ .get_ro = omap_hsmmc_get_ro,
+ /* NYET -- enable_sdio_irq */
+};
+
+static int __init omap_mmc_probe(struct platform_device *pdev)
+{
+ struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
+ struct mmc_host *mmc;
+ struct mmc_omap_host *host = NULL;
+ struct resource *res;
+ int ret = 0, irq;
+ u32 hctl, capa;
+
+ if (pdata == NULL) {
+ dev_err(&pdev->dev, "Platform Data is missing\n");
+ return -ENXIO;
+ }
+
+ if (pdata->nr_slots == 0) {
+ dev_err(&pdev->dev, "No Slots\n");
+ return -ENXIO;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (res == NULL || irq < 0)
+ return -ENXIO;
+
+ res = request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name);
+ if (res == NULL)
+ return -EBUSY;
+
+ mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+ host->pdata = pdata;
+ host->dev = &pdev->dev;
+ host->use_dma = 1;
+ host->dev->dma_mask = &pdata->dma_mask;
+ host->dma_ch = -1;
+ host->irq = irq;
+ host->id = pdev->id;
+ host->slot_id = 0;
+ host->mapbase = res->start;
+ host->base = ioremap(host->mapbase, SZ_4K);
+
+ platform_set_drvdata(pdev, host);
+ INIT_WORK(&host->mmc_carddetect_work, mmc_omap_detect);
+
+ mmc->ops = &mmc_omap_ops;
+ mmc->f_min = 400000;
+ mmc->f_max = 52000000;
+
+ sema_init(&host->sem, 1);
+
+ host->iclk = clk_get(&pdev->dev, "mmchs_ick");
+ if (IS_ERR(host->iclk)) {
+ ret = PTR_ERR(host->iclk);
+ host->iclk = NULL;
+ goto err1;
+ }
+ host->fclk = clk_get(&pdev->dev, "mmchs_fck");
+ if (IS_ERR(host->fclk)) {
+ ret = PTR_ERR(host->fclk);
+ host->fclk = NULL;
+ clk_put(host->iclk);
+ goto err1;
+ }
+
+ if (clk_enable(host->fclk) != 0) {
+ clk_put(host->iclk);
+ clk_put(host->fclk);
+ goto err1;
+ }
+
+ if (clk_enable(host->iclk) != 0) {
+ clk_disable(host->fclk);
+ clk_put(host->iclk);
+ clk_put(host->fclk);
+ goto err1;
+ }
+
+ host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
+ /*
+ * MMC can still work without debounce clock.
+ */
+ if (IS_ERR(host->dbclk))
+ dev_warn(mmc_dev(host->mmc), "Failed to get debounce clock\n");
+ else
+ if (clk_enable(host->dbclk) != 0)
+ dev_dbg(mmc_dev(host->mmc), "Enabling debounce"
+ " clk failed\n");
+ else
+ host->dbclk_enabled = 1;
+
+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+ mmc->max_phys_segs = 1;
+ mmc->max_hw_segs = 1;
+#endif
+ mmc->max_blk_size = 512; /* Block Length at max can be 1024 */
+ mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_req_size;
+
+ mmc->ocr_avail = mmc_slot(host).ocr_mask;
+ mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
+
+ if (pdata->slots[host->slot_id].wires >= 4)
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
+
+ /* Only MMC1 supports 3.0V */
+ if (host->id == OMAP_MMC1_DEVID) {
+ hctl = SDVS30;
+ capa = VS30 | VS18;
+ } else {
+ hctl = SDVS18;
+ capa = VS18;
+ }
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | hctl);
+
+ OMAP_HSMMC_WRITE(host->base, CAPA,
+ OMAP_HSMMC_READ(host->base, CAPA) | capa);
+
+ /* Set the controller to AUTO IDLE mode */
+ OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
+ OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+
+ /* Set SD bus power bit */
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+
+ /* Request IRQ for MMC operations */
+ ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED,
+ mmc_hostname(mmc), host);
+ if (ret) {
+ dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
+ goto err_irq;
+ }
+
+ if (pdata->init != NULL) {
+ if (pdata->init(&pdev->dev) != 0) {
+ dev_dbg(mmc_dev(host->mmc),
+ "Unable to configure MMC IRQs\n");
+ goto err_irq_cd_init;
+ }
+ }
+
+ /* Request IRQ for card detect */
+ if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
+ ret = request_irq(mmc_slot(host).card_detect_irq,
+ omap_mmc_cd_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
+ | IRQF_DISABLED,
+ mmc_hostname(mmc), host);
+ if (ret) {
+ dev_dbg(mmc_dev(host->mmc),
+ "Unable to grab MMC CD IRQ\n");
+ goto err_irq_cd;
+ }
+ }
+
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
+
+ mmc_add_host(mmc);
+
+ if (host->pdata->slots[host->slot_id].name != NULL) {
+ ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name);
+ if (ret < 0)
+ goto err_slot_name;
+ }
+ if (mmc_slot(host).card_detect_irq && mmc_slot(host).card_detect &&
+ host->pdata->slots[host->slot_id].get_cover_state) {
+ ret = device_create_file(&mmc->class_dev,
+ &dev_attr_cover_switch);
+ if (ret < 0)
+ goto err_cover_switch;
+ }
+
+ return 0;
+
+err_cover_switch:
+ device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);
+err_slot_name:
+ mmc_remove_host(mmc);
+err_irq_cd:
+ free_irq(mmc_slot(host).card_detect_irq, host);
+err_irq_cd_init:
+ free_irq(host->irq, host);
+err_irq:
+ clk_disable(host->fclk);
+ clk_disable(host->iclk);
+ clk_put(host->fclk);
+ clk_put(host->iclk);
+ if (host->dbclk_enabled) {
+ clk_disable(host->dbclk);
+ clk_put(host->dbclk);
+ }
+
+err1:
+ iounmap(host->base);
+err:
+ dev_dbg(mmc_dev(host->mmc), "Probe Failed\n");
+ release_mem_region(res->start, res->end - res->start + 1);
+ if (host)
+ mmc_free_host(mmc);
+ return ret;
+}
+
+static int omap_mmc_remove(struct platform_device *pdev)
+{
+ struct mmc_omap_host *host = platform_get_drvdata(pdev);
+ struct resource *res;
+
+ if (host) {
+ mmc_remove_host(host->mmc);
+ if (host->pdata->cleanup)
+ host->pdata->cleanup(&pdev->dev);
+ free_irq(host->irq, host);
+ if (mmc_slot(host).card_detect_irq)
+ free_irq(mmc_slot(host).card_detect_irq, host);
+ flush_scheduled_work();
+
+ clk_disable(host->fclk);
+ clk_disable(host->iclk);
+ clk_put(host->fclk);
+ clk_put(host->iclk);
+ if (host->dbclk_enabled) {
+ clk_disable(host->dbclk);
+ clk_put(host->dbclk);
+ }
+
+ mmc_free_host(host->mmc);
+ iounmap(host->base);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ release_mem_region(res->start, res->end - res->start + 1);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ int ret = 0;
+ struct mmc_omap_host *host = platform_get_drvdata(pdev);
+
+ if (host && host->suspended)
+ return 0;
+
+ if (host) {
+ ret = mmc_suspend_host(host->mmc, state);
+ if (ret == 0) {
+ host->suspended = 1;
+
+ OMAP_HSMMC_WRITE(host->base, ISE, 0);
+ OMAP_HSMMC_WRITE(host->base, IE, 0);
+
+ if (host->pdata->suspend) {
+ ret = host->pdata->suspend(&pdev->dev,
+ host->slot_id);
+ if (ret)
+ dev_dbg(mmc_dev(host->mmc),
+ "Unable to handle MMC board"
+ " level suspend\n");
+ }
+
+ if (host->id == OMAP_MMC1_DEVID
+ && !(OMAP_HSMMC_READ(host->base, HCTL)
+ & SDVSDET)) {
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL)
+ & SDVSCLR);
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL)
+ | SDVS30);
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL)
+ | SDBP);
+ }
+
+ clk_disable(host->fclk);
+ clk_disable(host->iclk);
+ clk_disable(host->dbclk);
+ }
+
+ }
+ return ret;
+}
+
+/* Routine to resume the MMC device */
+static int omap_mmc_resume(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct mmc_omap_host *host = platform_get_drvdata(pdev);
+
+ if (host && !host->suspended)
+ return 0;
+
+ if (host) {
+
+ ret = clk_enable(host->fclk);
+ if (ret)
+ goto clk_en_err;
+
+ ret = clk_enable(host->iclk);
+ if (ret) {
+ clk_disable(host->fclk);
+ clk_put(host->fclk);
+ goto clk_en_err;
+ }
+
+ if (clk_enable(host->dbclk) != 0)
+ dev_dbg(mmc_dev(host->mmc),
+ "Enabling debounce clk failed\n");
+
+ if (host->pdata->resume) {
+ ret = host->pdata->resume(&pdev->dev, host->slot_id);
+ if (ret)
+ dev_dbg(mmc_dev(host->mmc),
+ "Unmask interrupt failed\n");
+ }
+
+ /* Notify the core to resume the host */
+ ret = mmc_resume_host(host->mmc);
+ if (ret == 0)
+ host->suspended = 0;
+ }
+
+ return ret;
+
+clk_en_err:
+ dev_dbg(mmc_dev(host->mmc),
+ "Failed to enable MMC clocks during resume\n");
+ return ret;
+}
+
+#else
+#define omap_mmc_suspend NULL
+#define omap_mmc_resume NULL
+#endif
+
+static struct platform_driver omap_mmc_driver = {
+ .probe = omap_mmc_probe,
+ .remove = omap_mmc_remove,
+ .suspend = omap_mmc_suspend,
+ .resume = omap_mmc_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init omap_mmc_init(void)
+{
+ /* Register the MMC driver */
+ return platform_driver_register(&omap_mmc_driver);
+}
+
+static void __exit omap_mmc_cleanup(void)
+{
+ /* Unregister MMC driver */
+ platform_driver_unregister(&omap_mmc_driver);
+}
+
+module_init(omap_mmc_init);
+module_exit(omap_mmc_cleanup);
+
+MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 3c5483b75da..9702ad3774c 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -180,7 +180,15 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
else
DALGN &= ~(1 << host->dma);
DDADR(host->dma) = host->sg_dma;
- DCSR(host->dma) = DCSR_RUN;
+
+ /*
+ * workaround for erratum #91:
+ * only start DMA now if we are doing a read,
+ * otherwise we wait until CMD/RESP has finished
+ * before starting DMA.
+ */
+ if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ)
+ DCSR(host->dma) = DCSR_RUN;
}
static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat)
@@ -251,23 +259,28 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
if (stat & STAT_TIME_OUT_RESPONSE) {
cmd->error = -ETIMEDOUT;
} else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
-#ifdef CONFIG_PXA27x
/*
* workaround for erratum #42:
* Intel PXA27x Family Processor Specification Update Rev 001
* A bogus CRC error can appear if the msb of a 136 bit
* response is a one.
*/
- if (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000) {
+ if (cpu_is_pxa27x() &&
+ (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000))
pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode);
- } else
-#endif
- cmd->error = -EILSEQ;
+ else
+ cmd->error = -EILSEQ;
}
pxamci_disable_irq(host, END_CMD_RES);
if (host->data && !cmd->error) {
pxamci_enable_irq(host, DATA_TRAN_DONE);
+ /*
+ * workaround for erratum #91, if doing write
+ * enable DMA late
+ */
+ if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE)
+ DCSR(host->dma) = DCSR_RUN;
} else {
pxamci_finish_request(host, host->mrq);
}
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c
index be9e7b32b34..f6279051332 100644
--- a/drivers/mmc/host/ricoh_mmc.c
+++ b/drivers/mmc/host/ricoh_mmc.c
@@ -196,7 +196,7 @@ static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state)
+static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state)
{
struct pci_dev *fw_dev = NULL;
@@ -210,7 +210,7 @@ static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int ricoh_mmc_resume(struct pci_dev *pdev)
+static int ricoh_mmc_resume_early(struct pci_dev *pdev)
{
struct pci_dev *fw_dev = NULL;
@@ -229,8 +229,8 @@ static struct pci_driver ricoh_mmc_driver = {
.id_table = pci_ids,
.probe = ricoh_mmc_probe,
.remove = __devexit_p(ricoh_mmc_remove),
- .suspend = ricoh_mmc_suspend,
- .resume = ricoh_mmc_resume,
+ .suspend_late = ricoh_mmc_suspend_late,
+ .resume_early = ricoh_mmc_resume_early,
};
/*****************************************************************************\
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index fcc98a4cce3..2db166b7096 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -20,7 +20,7 @@
#include <linux/irq.h>
#include <linux/io.h>
-#include <asm/dma.h>
+#include <mach/dma.h>
#include <mach/regs-sdi.h>
#include <mach/regs-gpio.h>
@@ -329,7 +329,7 @@ static void do_pio_write(struct s3cmci_host *host)
to_ptr = host->base + host->sdidata;
- while ((fifo = fifo_free(host))) {
+ while ((fifo = fifo_free(host)) > 3) {
if (!host->pio_bytes) {
res = get_data_buffer(host, &host->pio_bytes,
&host->pio_ptr);
@@ -793,8 +793,7 @@ static void s3cmci_dma_setup(struct s3cmci_host *host,
host->mem->start + host->sdidata);
if (!setup_ok) {
- s3c2410_dma_config(host->dma, 4,
- (S3C2410_DCON_HWTRIG | S3C2410_DCON_CH0_SDI));
+ s3c2410_dma_config(host->dma, 4, 0);
s3c2410_dma_set_buffdone_fn(host->dma,
s3cmci_dma_done_callback);
s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART);
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index f07255cb17e..406da9a8d45 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -107,6 +107,7 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = {
static const struct sdhci_pci_fixes sdhci_cafe = {
.quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+ SDHCI_QUIRK_NO_BUSY_IRQ |
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
};
@@ -144,8 +145,7 @@ static int jmicron_probe(struct sdhci_pci_chip *chip)
SDHCI_QUIRK_32BIT_DMA_SIZE |
SDHCI_QUIRK_32BIT_ADMA_SIZE |
SDHCI_QUIRK_RESET_AFTER_REQUEST |
- SDHCI_QUIRK_BROKEN_SMALL_PIO |
- SDHCI_QUIRK_FORCE_HIGHSPEED;
+ SDHCI_QUIRK_BROKEN_SMALL_PIO;
}
/*
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6b2d1f99af6..accb592764e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1291,8 +1291,11 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
if (host->cmd->data)
DBG("Cannot wait for busy signal when also "
"doing a data transfer");
- else
+ else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
return;
+
+ /* The controller does not support the end-of-busy IRQ,
+ * fall through and take the SDHCI_INT_RESPONSE */
}
if (intmask & SDHCI_INT_RESPONSE)
@@ -1636,8 +1639,7 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->f_max = host->max_clk;
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
- if ((caps & SDHCI_CAN_DO_HISPD) ||
- (host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED))
+ if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED;
mmc->ocr_avail = 0;
@@ -1723,7 +1725,9 @@ int sdhci_add_host(struct sdhci_host *host)
#endif
#ifdef SDHCI_USE_LEDS_CLASS
- host->led.name = mmc_hostname(mmc);
+ snprintf(host->led_name, sizeof(host->led_name),
+ "%s::", mmc_hostname(mmc));
+ host->led.name = host->led_name;
host->led.brightness = LED_OFF;
host->led.default_trigger = mmc_hostname(mmc);
host->led.brightness_set = sdhci_led_control;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 3efba236394..43c37c68d07 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -208,8 +208,8 @@ struct sdhci_host {
#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12)
/* Controller has an issue with buffer bits for small transfers */
#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13)
-/* Controller supports high speed but doesn't have the caps bit set */
-#define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14)
+/* Controller does not provide transfer-complete interrupt when not busy */
+#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<14)
int irq; /* Device IRQ */
void __iomem * ioaddr; /* Mapped address */
@@ -222,6 +222,7 @@ struct sdhci_host {
#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
struct led_classdev led; /* LED control */
+ char led_name[32];
#endif
spinlock_t lock; /* Mutex */
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index 821d0ed6bae..c76d6e5f47e 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -19,6 +19,7 @@ static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
static void maprom_nop (struct mtd_info *);
static struct mtd_info *map_rom_probe(struct map_info *map);
+static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
static struct mtd_chip_driver maprom_chipdrv = {
.probe = map_rom_probe,
@@ -42,6 +43,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
mtd->read = maprom_read;
mtd->write = maprom_write;
mtd->sync = maprom_nop;
+ mtd->erase = maprom_erase;
mtd->flags = MTD_CAP_ROM;
mtd->erasesize = map->size;
mtd->writesize = 1;
@@ -71,6 +73,12 @@ static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *re
return -EIO;
}
+static int maprom_erase (struct mtd_info *mtd, struct erase_info *info)
+{
+ /* We do our best 8) */
+ return -EROFS;
+}
+
static int __init map_rom_init(void)
{
register_mtd_chip_driver(&maprom_chipdrv);
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index bc33200535f..6fde0a2e356 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -120,13 +120,6 @@ config MTD_PHRAM
doesn't have access to, memory beyond the mem=xxx limit, nvram,
memory on the video card, etc...
-config MTD_PS3VRAM
- tristate "PS3 video RAM"
- depends on FB_PS3
- help
- This driver allows you to use excess PS3 video RAM as volatile
- storage or system swap.
-
config MTD_LART
tristate "28F160xx flash driver for LART"
depends on SA1100_LART
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index e51521df4e4..0993d5cf392 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,4 +16,3 @@ obj-$(CONFIG_MTD_LART) += lart.o
obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
obj-$(CONFIG_MTD_M25P80) += m25p80.o
-obj-$(CONFIG_MTD_PS3VRAM) += ps3vram.o
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index d44f741ae22..6d9f810565c 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -821,7 +821,8 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
if (!(info->flags & IS_POW2PS))
return info;
}
- }
+ } else
+ return info;
}
}
diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c
deleted file mode 100644
index d21e9beb7ed..00000000000
--- a/drivers/mtd/devices/ps3vram.c
+++ /dev/null
@@ -1,768 +0,0 @@
-/**
- * ps3vram - Use extra PS3 video ram as MTD block device.
- *
- * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com>
- * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr>
- */
-
-#include <linux/io.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/version.h>
-#include <linux/gfp.h>
-#include <linux/delay.h>
-#include <linux/mtd/mtd.h>
-
-#include <asm/lv1call.h>
-#include <asm/ps3.h>
-
-#define DEVICE_NAME "ps3vram"
-
-#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */
-#define XDR_IOIF 0x0c000000
-
-#define FIFO_BASE XDR_IOIF
-#define FIFO_SIZE (64 * 1024)
-
-#define DMA_PAGE_SIZE (4 * 1024)
-
-#define CACHE_PAGE_SIZE (256 * 1024)
-#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE)
-
-#define CACHE_OFFSET CACHE_PAGE_SIZE
-#define FIFO_OFFSET 0
-
-#define CTRL_PUT 0x10
-#define CTRL_GET 0x11
-#define CTRL_TOP 0x15
-
-#define UPLOAD_SUBCH 1
-#define DOWNLOAD_SUBCH 2
-
-#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c
-#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104
-
-#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
-
-struct mtd_info ps3vram_mtd;
-
-#define CACHE_PAGE_PRESENT 1
-#define CACHE_PAGE_DIRTY 2
-
-struct ps3vram_tag {
- unsigned int address;
- unsigned int flags;
-};
-
-struct ps3vram_cache {
- unsigned int page_count;
- unsigned int page_size;
- struct ps3vram_tag *tags;
-};
-
-struct ps3vram_priv {
- u64 memory_handle;
- u64 context_handle;
- u32 *ctrl;
- u32 *reports;
- u8 __iomem *ddr_base;
- u8 *xdr_buf;
-
- u32 *fifo_base;
- u32 *fifo_ptr;
-
- struct device *dev;
- struct ps3vram_cache cache;
-
- /* Used to serialize cache/DMA operations */
- struct mutex lock;
-};
-
-#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */
-#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */
-#define DMA_NOTIFIER_SIZE 0x40
-#define NOTIFIER 7 /* notifier used for completion report */
-
-/* A trailing '-' means to subtract off ps3fb_videomemory.size */
-char *size = "256M-";
-module_param(size, charp, 0);
-MODULE_PARM_DESC(size, "memory size");
-
-static u32 *ps3vram_get_notifier(u32 *reports, int notifier)
-{
- return (void *) reports +
- DMA_NOTIFIER_OFFSET_BASE +
- DMA_NOTIFIER_SIZE * notifier;
-}
-
-static void ps3vram_notifier_reset(struct mtd_info *mtd)
-{
- int i;
-
- struct ps3vram_priv *priv = mtd->priv;
- u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
- for (i = 0; i < 4; i++)
- notify[i] = 0xffffffff;
-}
-
-static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms)
-{
- struct ps3vram_priv *priv = mtd->priv;
- u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
- unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
-
- do {
- if (!notify[3])
- return 0;
- msleep(1);
- } while (time_before(jiffies, timeout));
-
- return -ETIMEDOUT;
-}
-
-static void ps3vram_init_ring(struct mtd_info *mtd)
-{
- struct ps3vram_priv *priv = mtd->priv;
-
- priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
- priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
-}
-
-static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms)
-{
- struct ps3vram_priv *priv = mtd->priv;
- unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
-
- do {
- if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET])
- return 0;
- msleep(1);
- } while (time_before(jiffies, timeout));
-
- dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__,
- __LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET],
- priv->ctrl[CTRL_TOP]);
-
- return -ETIMEDOUT;
-}
-
-static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data)
-{
- *(priv->fifo_ptr)++ = data;
-}
-
-static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan,
- u32 tag, u32 size)
-{
- ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag);
-}
-
-static void ps3vram_rewind_ring(struct mtd_info *mtd)
-{
- struct ps3vram_priv *priv = mtd->priv;
- u64 status;
-
- ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
-
- priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
-
- /* asking the HV for a blit will kick the fifo */
- status = lv1_gpu_context_attribute(priv->context_handle,
- L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
- 0, 0, 0, 0);
- if (status)
- dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n",
- __func__, __LINE__);
-
- priv->fifo_ptr = priv->fifo_base;
-}
-
-static void ps3vram_fire_ring(struct mtd_info *mtd)
-{
- struct ps3vram_priv *priv = mtd->priv;
- u64 status;
-
- mutex_lock(&ps3_gpu_mutex);
-
- priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET +
- (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
-
- /* asking the HV for a blit will kick the fifo */
- status = lv1_gpu_context_attribute(priv->context_handle,
- L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
- 0, 0, 0, 0);
- if (status)
- dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n",
- __func__, __LINE__);
-
- if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
- FIFO_SIZE - 1024) {
- dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__,
- __LINE__);
- ps3vram_wait_ring(mtd, 200);
- ps3vram_rewind_ring(mtd);
- }
-
- mutex_unlock(&ps3_gpu_mutex);
-}
-
-static void ps3vram_bind(struct mtd_info *mtd)
-{
- struct ps3vram_priv *priv = mtd->priv;
-
- ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
- ps3vram_out_ring(priv, 0x31337303);
- ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3);
- ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
- ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */
- ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */
-
- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1);
- ps3vram_out_ring(priv, 0x3137c0de);
- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3);
- ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
- ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */
- ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */
-
- ps3vram_fire_ring(mtd);
-}
-
-static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset,
- unsigned int dst_offset, int len, int count)
-{
- struct ps3vram_priv *priv = mtd->priv;
-
- ps3vram_begin_ring(priv, UPLOAD_SUBCH,
- NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
- ps3vram_out_ring(priv, XDR_IOIF + src_offset);
- ps3vram_out_ring(priv, dst_offset);
- ps3vram_out_ring(priv, len);
- ps3vram_out_ring(priv, len);
- ps3vram_out_ring(priv, len);
- ps3vram_out_ring(priv, count);
- ps3vram_out_ring(priv, (1 << 8) | 1);
- ps3vram_out_ring(priv, 0);
-
- ps3vram_notifier_reset(mtd);
- ps3vram_begin_ring(priv, UPLOAD_SUBCH,
- NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
- ps3vram_out_ring(priv, 0);
- ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1);
- ps3vram_out_ring(priv, 0);
- ps3vram_fire_ring(mtd);
- if (ps3vram_notifier_wait(mtd, 200) < 0) {
- dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__,
- __LINE__);
- return -1;
- }
-
- return 0;
-}
-
-static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset,
- unsigned int dst_offset, int len, int count)
-{
- struct ps3vram_priv *priv = mtd->priv;
-
- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
- NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
- ps3vram_out_ring(priv, src_offset);
- ps3vram_out_ring(priv, XDR_IOIF + dst_offset);
- ps3vram_out_ring(priv, len);
- ps3vram_out_ring(priv, len);
- ps3vram_out_ring(priv, len);
- ps3vram_out_ring(priv, count);
- ps3vram_out_ring(priv, (1 << 8) | 1);
- ps3vram_out_ring(priv, 0);
-
- ps3vram_notifier_reset(mtd);
- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
- NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
- ps3vram_out_ring(priv, 0);
- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1);
- ps3vram_out_ring(priv, 0);
- ps3vram_fire_ring(mtd);
- if (ps3vram_notifier_wait(mtd, 200) < 0) {
- dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__,
- __LINE__);
- return -1;
- }
-
- return 0;
-}
-
-static void ps3vram_cache_evict(struct mtd_info *mtd, int entry)
-{
- struct ps3vram_priv *priv = mtd->priv;
- struct ps3vram_cache *cache = &priv->cache;
-
- if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) {
- dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__,
- __LINE__, entry, cache->tags[entry].address);
- if (ps3vram_upload(mtd,
- CACHE_OFFSET + entry * cache->page_size,
- cache->tags[entry].address,
- DMA_PAGE_SIZE,
- cache->page_size / DMA_PAGE_SIZE) < 0) {
- dev_dbg(priv->dev, "%s:%d: failed to upload from "
- "0x%x to 0x%x size 0x%x\n", __func__, __LINE__,
- entry * cache->page_size,
- cache->tags[entry].address, cache->page_size);
- }
- cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY;
- }
-}
-
-static void ps3vram_cache_load(struct mtd_info *mtd, int entry,
- unsigned int address)
-{
- struct ps3vram_priv *priv = mtd->priv;
- struct ps3vram_cache *cache = &priv->cache;
-
- dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__,
- entry, address);
- if (ps3vram_download(mtd,
- address,
- CACHE_OFFSET + entry * cache->page_size,
- DMA_PAGE_SIZE,
- cache->page_size / DMA_PAGE_SIZE) < 0) {
- dev_err(priv->dev, "%s:%d: failed to download from "
- "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address,
- entry * cache->page_size, cache->page_size);
- }
-
- cache->tags[entry].address = address;
- cache->tags[entry].flags |= CACHE_PAGE_PRESENT;
-}
-
-
-static void ps3vram_cache_flush(struct mtd_info *mtd)
-{
- struct ps3vram_priv *priv = mtd->priv;
- struct ps3vram_cache *cache = &priv->cache;
- int i;
-
- dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__);
- for (i = 0; i < cache->page_count; i++) {
- ps3vram_cache_evict(mtd, i);
- cache->tags[i].flags = 0;
- }
-}
-
-static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address)
-{
- struct ps3vram_priv *priv = mtd->priv;
- struct ps3vram_cache *cache = &priv->cache;
- unsigned int base;
- unsigned int offset;
- int i;
- static int counter;
-
- offset = (unsigned int) (address & (cache->page_size - 1));
- base = (unsigned int) (address - offset);
-
- /* fully associative check */
- for (i = 0; i < cache->page_count; i++) {
- if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) &&
- cache->tags[i].address == base) {
- dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n",
- __func__, __LINE__, i, cache->tags[i].address);
- return i;
- }
- }
-
- /* choose a random entry */
- i = (jiffies + (counter++)) % cache->page_count;
- dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i);
-
- ps3vram_cache_evict(mtd, i);
- ps3vram_cache_load(mtd, i, base);
-
- return i;
-}
-
-static int ps3vram_cache_init(struct mtd_info *mtd)
-{
- struct ps3vram_priv *priv = mtd->priv;
-
- priv->cache.page_count = CACHE_PAGE_COUNT;
- priv->cache.page_size = CACHE_PAGE_SIZE;
- priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) *
- CACHE_PAGE_COUNT, GFP_KERNEL);
- if (priv->cache.tags == NULL) {
- dev_err(priv->dev, "%s:%d: could not allocate cache tags\n",
- __func__, __LINE__);
- return -ENOMEM;
- }
-
- dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n",
- CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024);
-
- return 0;
-}
-
-static void ps3vram_cache_cleanup(struct mtd_info *mtd)
-{
- struct ps3vram_priv *priv = mtd->priv;
-
- ps3vram_cache_flush(mtd);
- kfree(priv->cache.tags);
-}
-
-static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
- struct ps3vram_priv *priv = mtd->priv;
-
- if (instr->addr + instr->len > mtd->size)
- return -EINVAL;
-
- mutex_lock(&priv->lock);
-
- ps3vram_cache_flush(mtd);
-
- /* Set bytes to 0xFF */
- memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len);
-
- mutex_unlock(&priv->lock);
-
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
- return 0;
-}
-
-static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char *buf)
-{
- struct ps3vram_priv *priv = mtd->priv;
- unsigned int cached, count;
-
- dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__,
- (unsigned int)from, len);
-
- if (from >= mtd->size)
- return -EINVAL;
-
- if (len > mtd->size - from)
- len = mtd->size - from;
-
- /* Copy from vram to buf */
- count = len;
- while (count) {
- unsigned int offset, avail;
- unsigned int entry;
-
- offset = (unsigned int) (from & (priv->cache.page_size - 1));
- avail = priv->cache.page_size - offset;
-
- mutex_lock(&priv->lock);
-
- entry = ps3vram_cache_match(mtd, from);
- cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
-
- dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x "
- "avail=%08x count=%08x\n", __func__, __LINE__,
- (unsigned int)from, cached, offset, avail, count);
-
- if (avail > count)
- avail = count;
- memcpy(buf, priv->xdr_buf + cached, avail);
-
- mutex_unlock(&priv->lock);
-
- buf += avail;
- count -= avail;
- from += avail;
- }
-
- *retlen = len;
- return 0;
-}
-
-static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf)
-{
- struct ps3vram_priv *priv = mtd->priv;
- unsigned int cached, count;
-
- if (to >= mtd->size)
- return -EINVAL;
-
- if (len > mtd->size - to)
- len = mtd->size - to;
-
- /* Copy from buf to vram */
- count = len;
- while (count) {
- unsigned int offset, avail;
- unsigned int entry;
-
- offset = (unsigned int) (to & (priv->cache.page_size - 1));
- avail = priv->cache.page_size - offset;
-
- mutex_lock(&priv->lock);
-
- entry = ps3vram_cache_match(mtd, to);
- cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
-
- dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x "
- "avail=%08x count=%08x\n", __func__, __LINE__,
- (unsigned int)to, cached, offset, avail, count);
-
- if (avail > count)
- avail = count;
- memcpy(priv->xdr_buf + cached, buf, avail);
-
- priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
-
- mutex_unlock(&priv->lock);
-
- buf += avail;
- count -= avail;
- to += avail;
- }
-
- *retlen = len;
- return 0;
-}
-
-static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
-{
- struct ps3vram_priv *priv;
- int status;
- u64 ddr_lpar;
- u64 ctrl_lpar;
- u64 info_lpar;
- u64 reports_lpar;
- u64 ddr_size;
- u64 reports_size;
- int ret = -ENOMEM;
- char *rest;
-
- ret = -EIO;
- ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL);
- if (!ps3vram_mtd.priv)
- goto out;
- priv = ps3vram_mtd.priv;
-
- mutex_init(&priv->lock);
- priv->dev = &dev->core;
-
- /* Allocate XDR buffer (1MiB aligned) */
- priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
- get_order(XDR_BUF_SIZE));
- if (priv->xdr_buf == NULL) {
- dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n",
- __func__, __LINE__);
- ret = -ENOMEM;
- goto out_free_priv;
- }
-
- /* Put FIFO at begginning of XDR buffer */
- priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET);
- priv->fifo_ptr = priv->fifo_base;
-
- /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */
- if (ps3_open_hv_device(dev)) {
- dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
- __func__, __LINE__);
- ret = -EAGAIN;
- goto out_close_gpu;
- }
-
- /* Request memory */
- status = -1;
- ddr_size = memparse(size, &rest);
- if (*rest == '-')
- ddr_size -= ps3fb_videomemory.size;
- ddr_size = ALIGN(ddr_size, 1024*1024);
- if (ddr_size <= 0) {
- dev_err(&dev->core, "%s:%d: specified size is too small\n",
- __func__, __LINE__);
- ret = -EINVAL;
- goto out_close_gpu;
- }
-
- while (ddr_size > 0) {
- status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0,
- &priv->memory_handle,
- &ddr_lpar);
- if (!status)
- break;
- ddr_size -= 1024*1024;
- }
- if (status || ddr_size <= 0) {
- dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n",
- __func__, __LINE__);
- ret = -ENOMEM;
- goto out_free_xdr_buf;
- }
-
- /* Request context */
- status = lv1_gpu_context_allocate(priv->memory_handle,
- 0,
- &priv->context_handle,
- &ctrl_lpar,
- &info_lpar,
- &reports_lpar,
- &reports_size);
- if (status) {
- dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n",
- __func__, __LINE__);
- ret = -ENOMEM;
- goto out_free_memory;
- }
-
- /* Map XDR buffer to RSX */
- status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
- ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
- XDR_BUF_SIZE, 0);
- if (status) {
- dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n",
- __func__, __LINE__);
- ret = -ENOMEM;
- goto out_free_context;
- }
-
- priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
-
- if (!priv->ddr_base) {
- dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
- __LINE__);
- ret = -ENOMEM;
- goto out_free_context;
- }
-
- priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
- if (!priv->ctrl) {
- dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
- __LINE__);
- ret = -ENOMEM;
- goto out_unmap_vram;
- }
-
- priv->reports = ioremap(reports_lpar, reports_size);
- if (!priv->reports) {
- dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
- __LINE__);
- ret = -ENOMEM;
- goto out_unmap_ctrl;
- }
-
- mutex_lock(&ps3_gpu_mutex);
- ps3vram_init_ring(&ps3vram_mtd);
- mutex_unlock(&ps3_gpu_mutex);
-
- ps3vram_mtd.name = "ps3vram";
- ps3vram_mtd.size = ddr_size;
- ps3vram_mtd.flags = MTD_CAP_RAM;
- ps3vram_mtd.erase = ps3vram_erase;
- ps3vram_mtd.point = NULL;
- ps3vram_mtd.unpoint = NULL;
- ps3vram_mtd.read = ps3vram_read;
- ps3vram_mtd.write = ps3vram_write;
- ps3vram_mtd.owner = THIS_MODULE;
- ps3vram_mtd.type = MTD_RAM;
- ps3vram_mtd.erasesize = CACHE_PAGE_SIZE;
- ps3vram_mtd.writesize = 1;
-
- ps3vram_bind(&ps3vram_mtd);
-
- mutex_lock(&ps3_gpu_mutex);
- ret = ps3vram_wait_ring(&ps3vram_mtd, 100);
- mutex_unlock(&ps3_gpu_mutex);
- if (ret < 0) {
- dev_err(&dev->core, "%s:%d: failed to initialize channels\n",
- __func__, __LINE__);
- ret = -ETIMEDOUT;
- goto out_unmap_reports;
- }
-
- ps3vram_cache_init(&ps3vram_mtd);
-
- if (add_mtd_device(&ps3vram_mtd)) {
- dev_err(&dev->core, "%s:%d: add_mtd_device failed\n",
- __func__, __LINE__);
- ret = -EAGAIN;
- goto out_cache_cleanup;
- }
-
- dev_info(&dev->core, "reserved %u MiB of gpu memory\n",
- (unsigned int)(ddr_size / 1024 / 1024));
-
- return 0;
-
-out_cache_cleanup:
- ps3vram_cache_cleanup(&ps3vram_mtd);
-out_unmap_reports:
- iounmap(priv->reports);
-out_unmap_ctrl:
- iounmap(priv->ctrl);
-out_unmap_vram:
- iounmap(priv->ddr_base);
-out_free_context:
- lv1_gpu_context_free(priv->context_handle);
-out_free_memory:
- lv1_gpu_memory_free(priv->memory_handle);
-out_close_gpu:
- ps3_close_hv_device(dev);
-out_free_xdr_buf:
- free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
-out_free_priv:
- kfree(ps3vram_mtd.priv);
- ps3vram_mtd.priv = NULL;
-out:
- return ret;
-}
-
-static int ps3vram_shutdown(struct ps3_system_bus_device *dev)
-{
- struct ps3vram_priv *priv;
-
- priv = ps3vram_mtd.priv;
-
- del_mtd_device(&ps3vram_mtd);
- ps3vram_cache_cleanup(&ps3vram_mtd);
- iounmap(priv->reports);
- iounmap(priv->ctrl);
- iounmap(priv->ddr_base);
- lv1_gpu_context_free(priv->context_handle);
- lv1_gpu_memory_free(priv->memory_handle);
- ps3_close_hv_device(dev);
- free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
- kfree(priv);
- return 0;
-}
-
-static struct ps3_system_bus_driver ps3vram_driver = {
- .match_id = PS3_MATCH_ID_GPU,
- .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK,
- .core.name = DEVICE_NAME,
- .core.owner = THIS_MODULE,
- .probe = ps3vram_probe,
- .remove = ps3vram_shutdown,
- .shutdown = ps3vram_shutdown,
-};
-
-static int __init ps3vram_init(void)
-{
- return ps3_system_bus_driver_register(&ps3vram_driver);
-}
-
-static void __exit ps3vram_exit(void)
-{
- ps3_system_bus_driver_unregister(&ps3vram_driver);
-}
-
-module_init(ps3vram_init);
-module_exit(ps3vram_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jim Paris <jim@jtan.com>");
-MODULE_DESCRIPTION("MTD driver for PS3 video RAM");
-MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK);
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index a425d09f35a..00248e81ecd 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -267,22 +267,28 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
if (*(szlength) != '+') {
devlength = simple_strtoul(szlength, &buffer, 0);
devlength = handle_unit(devlength, buffer) - devstart;
+ if (devlength < devstart)
+ goto err_out;
+
+ devlength -= devstart;
} else {
devlength = simple_strtoul(szlength + 1, &buffer, 0);
devlength = handle_unit(devlength, buffer);
}
T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
devname, devstart, devlength);
- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
- E("slram: Illegal start / length parameter.\n");
- return(-EINVAL);
- }
+ if (devlength % SLRAM_BLK_SZ != 0)
+ goto err_out;
if ((devstart = register_device(devname, devstart, devlength))){
unregister_devices();
return((int)devstart);
}
return(0);
+
+err_out:
+ E("slram: Illegal length parameter.\n");
+ return(-EINVAL);
}
#ifndef MODULE
diff --git a/drivers/mtd/lpddr/Kconfig b/drivers/mtd/lpddr/Kconfig
index acd4ea9b227..5a401d8047a 100644
--- a/drivers/mtd/lpddr/Kconfig
+++ b/drivers/mtd/lpddr/Kconfig
@@ -12,6 +12,7 @@ config MTD_LPDDR
DDR memories, intended for battery-operated systems.
config MTD_QINFO_PROBE
+ depends on MTD_LPDDR
tristate "Detect flash chips by QINFO probe"
help
Device Information for LPDDR chips is offered through the Overlay
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 0225cbbf22d..729f899a5cd 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -491,7 +491,7 @@ config MTD_PCMCIA_ANONYMOUS
config MTD_BFIN_ASYNC
tristate "Blackfin BF533-STAMP Flash Chip Support"
- depends on BFIN533_STAMP && MTD_CFI
+ depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS
select MTD_PARTITIONS
default y
help
@@ -551,5 +551,15 @@ config MTD_PLATRAM
This selection automatically selects the map_ram driver.
-endmenu
+config MTD_VMU
+ tristate "Map driver for Dreamcast VMU"
+ depends on MAPLE
+ help
+ This driver enables access to the Dreamcast Visual Memory Unit (VMU).
+
+ Most Dreamcast users will want to say Y here.
+ To build this as a module select M here, the module will be called
+ vmu-flash.
+
+endmenu
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 6d9ba35caf1..26b28a7a90b 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -61,3 +61,4 @@ obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o
+obj-$(CONFIG_MTD_VMU) += vmu-flash.o
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c
index 6fec86aaed7..576611f605d 100644
--- a/drivers/mtd/maps/bfin-async-flash.c
+++ b/drivers/mtd/maps/bfin-async-flash.c
@@ -152,14 +152,18 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) {
pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin);
+ kfree(state);
return -EBUSY;
}
gpio_direction_output(state->enet_flash_pin, 1);
pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8);
state->mtd = do_map_probe(memory->name, &state->map);
- if (!state->mtd)
+ if (!state->mtd) {
+ gpio_free(state->enet_flash_pin);
+ kfree(state);
return -ENXIO;
+ }
#ifdef CONFIG_MTD_PARTITIONS
ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c
index 5f7a245ed13..424f17d6ffd 100644
--- a/drivers/mtd/maps/ck804xrom.c
+++ b/drivers/mtd/maps/ck804xrom.c
@@ -342,9 +342,9 @@ static struct pci_device_id ck804xrom_pci_tbl[] = {
{ 0, }
};
+#if 0
MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl);
-#if 0
static struct pci_driver ck804xrom_driver = {
.name = MOD_NAME,
.id_table = ck804xrom_pci_tbl,
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 87743661d48..229718222db 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -29,6 +29,7 @@ struct physmap_flash_info {
struct map_info map[MAX_RESOURCES];
#ifdef CONFIG_MTD_PARTITIONS
int nr_parts;
+ struct mtd_partition *parts;
#endif
};
@@ -45,25 +46,29 @@ static int physmap_flash_remove(struct platform_device *dev)
physmap_data = dev->dev.platform_data;
-#ifdef CONFIG_MTD_CONCAT
- if (info->cmtd != info->mtd[0]) {
+ if (info->cmtd) {
+#ifdef CONFIG_MTD_PARTITIONS
+ if (info->nr_parts || physmap_data->nr_parts)
+ del_mtd_partitions(info->cmtd);
+ else
+ del_mtd_device(info->cmtd);
+#else
del_mtd_device(info->cmtd);
- mtd_concat_destroy(info->cmtd);
+#endif
}
+#ifdef CONFIG_MTD_PARTITIONS
+ if (info->nr_parts)
+ kfree(info->parts);
#endif
- for (i = 0; i < MAX_RESOURCES; i++) {
- if (info->mtd[i] != NULL) {
-#ifdef CONFIG_MTD_PARTITIONS
- if (info->nr_parts || physmap_data->nr_parts)
- del_mtd_partitions(info->mtd[i]);
- else
- del_mtd_device(info->mtd[i]);
-#else
- del_mtd_device(info->mtd[i]);
+#ifdef CONFIG_MTD_CONCAT
+ if (info->cmtd != info->mtd[0])
+ mtd_concat_destroy(info->cmtd);
#endif
+
+ for (i = 0; i < MAX_RESOURCES; i++) {
+ if (info->mtd[i] != NULL)
map_destroy(info->mtd[i]);
- }
}
return 0;
}
@@ -86,9 +91,6 @@ static int physmap_flash_probe(struct platform_device *dev)
int err = 0;
int i;
int devices_found = 0;
-#ifdef CONFIG_MTD_PARTITIONS
- struct mtd_partition *parts;
-#endif
physmap_data = dev->dev.platform_data;
if (physmap_data == NULL)
@@ -167,10 +169,11 @@ static int physmap_flash_probe(struct platform_device *dev)
goto err_out;
#ifdef CONFIG_MTD_PARTITIONS
- err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0);
+ err = parse_mtd_partitions(info->cmtd, part_probe_types,
+ &info->parts, 0);
if (err > 0) {
- add_mtd_partitions(info->cmtd, parts, err);
- kfree(parts);
+ add_mtd_partitions(info->cmtd, info->parts, err);
+ info->nr_parts = err;
return 0;
}
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 771139c5bf8..e9026cb1c5b 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info {
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-static int __init pxa2xx_flash_probe(struct device *dev)
+static int __init pxa2xx_flash_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *flash = pdev->dev.platform_data;
struct pxa2xx_flash_info *info;
struct mtd_partition *parts;
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(struct device *dev)
add_mtd_device(info->mtd);
}
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
return 0;
}
-static int __exit pxa2xx_flash_remove(struct device *dev)
+static int __exit pxa2xx_flash_remove(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
#ifdef CONFIG_MTD_PARTITIONS
if (info->nr_parts)
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(struct device *dev)
}
#ifdef CONFIG_PM
-static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
int ret = 0;
if (info->mtd && info->mtd->suspend)
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
return ret;
}
-static int pxa2xx_flash_resume(struct device *dev)
+static int pxa2xx_flash_resume(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
if (info->mtd && info->mtd->resume)
info->mtd->resume(info->mtd);
return 0;
}
-static void pxa2xx_flash_shutdown(struct device *dev)
+static void pxa2xx_flash_shutdown(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
if (info && info->mtd->suspend(info->mtd) == 0)
info->mtd->resume(info->mtd);
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct device *dev)
#define pxa2xx_flash_shutdown NULL
#endif
-static struct device_driver pxa2xx_flash_driver = {
- .name = "pxa2xx-flash",
- .bus = &platform_bus_type,
+static struct platform_driver pxa2xx_flash_driver = {
+ .driver = {
+ .name = "pxa2xx-flash",
+ .owner = THIS_MODULE,
+ },
.probe = pxa2xx_flash_probe,
- .remove = __exit_p(pxa2xx_flash_remove),
+ .remove = __devexit_p(pxa2xx_flash_remove),
.suspend = pxa2xx_flash_suspend,
.resume = pxa2xx_flash_resume,
.shutdown = pxa2xx_flash_shutdown,
@@ -184,12 +185,12 @@ static struct device_driver pxa2xx_flash_driver = {
static int __init init_pxa2xx_flash(void)
{
- return driver_register(&pxa2xx_flash_driver);
+ return platform_driver_register(&pxa2xx_flash_driver);
}
static void __exit cleanup_pxa2xx_flash(void)
{
- driver_unregister(&pxa2xx_flash_driver);
+ platform_driver_unregister(&pxa2xx_flash_driver);
}
module_init(init_pxa2xx_flash);
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 7df6bbf0e4d..6f6a0f6dafd 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -453,7 +453,7 @@ static struct platform_driver sa1100_mtd_driver = {
.resume = sa1100_mtd_resume,
.shutdown = sa1100_mtd_shutdown,
.driver = {
- .name = "flash",
+ .name = "sa1100-mtd",
.owner = THIS_MODULE,
},
};
@@ -474,4 +474,4 @@ module_exit(sa1100_mtd_exit);
MODULE_AUTHOR("Nicolas Pitre");
MODULE_DESCRIPTION("SA1100 CFI map driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:flash");
+MODULE_ALIAS("platform:sa1100-mtd");
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c
new file mode 100644
index 00000000000..1f73297e777
--- /dev/null
+++ b/drivers/mtd/maps/vmu-flash.c
@@ -0,0 +1,832 @@
+/* vmu-flash.c
+ * Driver for SEGA Dreamcast Visual Memory Unit
+ *
+ * Copyright (c) Adrian McMenamin 2002 - 2009
+ * Copyright (c) Paul Mundt 2001
+ *
+ * Licensed under version 2 of the
+ * GNU General Public Licence
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/maple.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+struct vmu_cache {
+ unsigned char *buffer; /* Cache */
+ unsigned int block; /* Which block was cached */
+ unsigned long jiffies_atc; /* When was it cached? */
+ int valid;
+};
+
+struct mdev_part {
+ struct maple_device *mdev;
+ int partition;
+};
+
+struct vmupart {
+ u16 user_blocks;
+ u16 root_block;
+ u16 numblocks;
+ char *name;
+ struct vmu_cache *pcache;
+};
+
+struct memcard {
+ u16 tempA;
+ u16 tempB;
+ u32 partitions;
+ u32 blocklen;
+ u32 writecnt;
+ u32 readcnt;
+ u32 removeable;
+ int partition;
+ int read;
+ unsigned char *blockread;
+ struct vmupart *parts;
+ struct mtd_info *mtd;
+};
+
+struct vmu_block {
+ unsigned int num; /* block number */
+ unsigned int ofs; /* block offset */
+};
+
+static struct vmu_block *ofs_to_block(unsigned long src_ofs,
+ struct mtd_info *mtd, int partition)
+{
+ struct vmu_block *vblock;
+ struct maple_device *mdev;
+ struct memcard *card;
+ struct mdev_part *mpart;
+ int num;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ card = maple_get_drvdata(mdev);
+
+ if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
+ goto failed;
+
+ num = src_ofs / card->blocklen;
+ if (num > card->parts[partition].numblocks)
+ goto failed;
+
+ vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
+ if (!vblock)
+ goto failed;
+
+ vblock->num = num;
+ vblock->ofs = src_ofs % card->blocklen;
+ return vblock;
+
+failed:
+ return NULL;
+}
+
+/* Maple bus callback function for reads */
+static void vmu_blockread(struct mapleq *mq)
+{
+ struct maple_device *mdev;
+ struct memcard *card;
+
+ mdev = mq->dev;
+ card = maple_get_drvdata(mdev);
+ /* copy the read in data */
+
+ if (unlikely(!card->blockread))
+ return;
+
+ memcpy(card->blockread, mq->recvbuf->buf + 12,
+ card->blocklen/card->readcnt);
+
+}
+
+/* Interface with maple bus to read blocks
+ * caching the results so that other parts
+ * of the driver can access block reads */
+static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
+ struct mtd_info *mtd)
+{
+ struct memcard *card;
+ struct mdev_part *mpart;
+ struct maple_device *mdev;
+ int partition, error = 0, x, wait;
+ unsigned char *blockread = NULL;
+ struct vmu_cache *pcache;
+ __be32 sendbuf;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+ pcache = card->parts[partition].pcache;
+ pcache->valid = 0;
+
+ /* prepare the cache for this block */
+ if (!pcache->buffer) {
+ pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
+ if (!pcache->buffer) {
+ dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
+ " to lack of memory\n", mdev->port,
+ mdev->unit);
+ error = -ENOMEM;
+ goto outB;
+ }
+ }
+
+ /*
+ * Reads may be phased - again the hardware spec
+ * supports this - though may not be any devices in
+ * the wild that implement it, but we will here
+ */
+ for (x = 0; x < card->readcnt; x++) {
+ sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);
+
+ if (atomic_read(&mdev->busy) == 1) {
+ wait_event_interruptible_timeout(mdev->maple_wait,
+ atomic_read(&mdev->busy) == 0, HZ);
+ if (atomic_read(&mdev->busy) == 1) {
+ dev_notice(&mdev->dev, "VMU at (%d, %d)"
+ " is busy\n", mdev->port, mdev->unit);
+ error = -EAGAIN;
+ goto outB;
+ }
+ }
+
+ atomic_set(&mdev->busy, 1);
+ blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
+ if (!blockread) {
+ error = -ENOMEM;
+ atomic_set(&mdev->busy, 0);
+ goto outB;
+ }
+ card->blockread = blockread;
+
+ maple_getcond_callback(mdev, vmu_blockread, 0,
+ MAPLE_FUNC_MEMCARD);
+ error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+ MAPLE_COMMAND_BREAD, 2, &sendbuf);
+ /* Very long timeouts seem to be needed when box is stressed */
+ wait = wait_event_interruptible_timeout(mdev->maple_wait,
+ (atomic_read(&mdev->busy) == 0 ||
+ atomic_read(&mdev->busy) == 2), HZ * 3);
+ /*
+ * MTD layer does not handle hotplugging well
+ * so have to return errors when VMU is unplugged
+ * in the middle of a read (busy == 2)
+ */
+ if (error || atomic_read(&mdev->busy) == 2) {
+ if (atomic_read(&mdev->busy) == 2)
+ error = -ENXIO;
+ atomic_set(&mdev->busy, 0);
+ card->blockread = NULL;
+ goto outA;
+ }
+ if (wait == 0 || wait == -ERESTARTSYS) {
+ card->blockread = NULL;
+ atomic_set(&mdev->busy, 0);
+ error = -EIO;
+ list_del_init(&(mdev->mq->list));
+ kfree(mdev->mq->sendbuf);
+ mdev->mq->sendbuf = NULL;
+ if (wait == -ERESTARTSYS) {
+ dev_warn(&mdev->dev, "VMU read on (%d, %d)"
+ " interrupted on block 0x%X\n",
+ mdev->port, mdev->unit, num);
+ } else
+ dev_notice(&mdev->dev, "VMU read on (%d, %d)"
+ " timed out on block 0x%X\n",
+ mdev->port, mdev->unit, num);
+ goto outA;
+ }
+
+ memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
+ card->blocklen/card->readcnt);
+
+ memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
+ card->blockread, card->blocklen/card->readcnt);
+ card->blockread = NULL;
+ pcache->block = num;
+ pcache->jiffies_atc = jiffies;
+ pcache->valid = 1;
+ kfree(blockread);
+ }
+
+ return error;
+
+outA:
+ kfree(blockread);
+outB:
+ return error;
+}
+
+/* communicate with maple bus for phased writing */
+static int maple_vmu_write_block(unsigned int num, const unsigned char *buf,
+ struct mtd_info *mtd)
+{
+ struct memcard *card;
+ struct mdev_part *mpart;
+ struct maple_device *mdev;
+ int partition, error, locking, x, phaselen, wait;
+ __be32 *sendbuf;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+
+ phaselen = card->blocklen/card->writecnt;
+
+ sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
+ if (!sendbuf) {
+ error = -ENOMEM;
+ goto fail_nosendbuf;
+ }
+ for (x = 0; x < card->writecnt; x++) {
+ sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num);
+ memcpy(&sendbuf[1], buf + phaselen * x, phaselen);
+ /* wait until the device is not busy doing something else
+ * or 1 second - which ever is longer */
+ if (atomic_read(&mdev->busy) == 1) {
+ wait_event_interruptible_timeout(mdev->maple_wait,
+ atomic_read(&mdev->busy) == 0, HZ);
+ if (atomic_read(&mdev->busy) == 1) {
+ error = -EBUSY;
+ dev_notice(&mdev->dev, "VMU write at (%d, %d)"
+ "failed - device is busy\n",
+ mdev->port, mdev->unit);
+ goto fail_nolock;
+ }
+ }
+ atomic_set(&mdev->busy, 1);
+
+ locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+ MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf);
+ wait = wait_event_interruptible_timeout(mdev->maple_wait,
+ atomic_read(&mdev->busy) == 0, HZ/10);
+ if (locking) {
+ error = -EIO;
+ atomic_set(&mdev->busy, 0);
+ goto fail_nolock;
+ }
+ if (atomic_read(&mdev->busy) == 2) {
+ atomic_set(&mdev->busy, 0);
+ } else if (wait == 0 || wait == -ERESTARTSYS) {
+ error = -EIO;
+ dev_warn(&mdev->dev, "Write at (%d, %d) of block"
+ " 0x%X at phase %d failed: could not"
+ " communicate with VMU", mdev->port,
+ mdev->unit, num, x);
+ atomic_set(&mdev->busy, 0);
+ kfree(mdev->mq->sendbuf);
+ mdev->mq->sendbuf = NULL;
+ list_del_init(&(mdev->mq->list));
+ goto fail_nolock;
+ }
+ }
+ kfree(sendbuf);
+
+ return card->blocklen;
+
+fail_nolock:
+ kfree(sendbuf);
+fail_nosendbuf:
+ dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
+ mdev->unit);
+ return error;
+}
+
+/* mtd function to simulate reading byte by byte */
+static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval,
+ struct mtd_info *mtd)
+{
+ struct vmu_block *vblock;
+ struct memcard *card;
+ struct mdev_part *mpart;
+ struct maple_device *mdev;
+ unsigned char *buf, ret;
+ int partition, error;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+ *retval = 0;
+
+ buf = kmalloc(card->blocklen, GFP_KERNEL);
+ if (!buf) {
+ *retval = 1;
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ vblock = ofs_to_block(ofs, mtd, partition);
+ if (!vblock) {
+ *retval = 3;
+ ret = -ENOMEM;
+ goto out_buf;
+ }
+
+ error = maple_vmu_read_block(vblock->num, buf, mtd);
+ if (error) {
+ ret = error;
+ *retval = 2;
+ goto out_vblock;
+ }
+
+ ret = buf[vblock->ofs];
+
+out_vblock:
+ kfree(vblock);
+out_buf:
+ kfree(buf);
+finish:
+ return ret;
+}
+
+/* mtd higher order function to read flash */
+static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct maple_device *mdev;
+ struct memcard *card;
+ struct mdev_part *mpart;
+ struct vmu_cache *pcache;
+ struct vmu_block *vblock;
+ int index = 0, retval, partition, leftover, numblocks;
+ unsigned char cx;
+
+ if (len < 1)
+ return -EIO;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+
+ numblocks = card->parts[partition].numblocks;
+ if (from + len > numblocks * card->blocklen)
+ len = numblocks * card->blocklen - from;
+ if (len == 0)
+ return -EIO;
+ /* Have we cached this bit already? */
+ pcache = card->parts[partition].pcache;
+ do {
+ vblock = ofs_to_block(from + index, mtd, partition);
+ if (!vblock)
+ return -ENOMEM;
+ /* Have we cached this and is the cache valid and timely? */
+ if (pcache->valid &&
+ time_before(jiffies, pcache->jiffies_atc + HZ) &&
+ (pcache->block == vblock->num)) {
+ /* we have cached it, so do necessary copying */
+ leftover = card->blocklen - vblock->ofs;
+ if (vblock->ofs + len - index < card->blocklen) {
+ /* only a bit of this block to copy */
+ memcpy(buf + index,
+ pcache->buffer + vblock->ofs,
+ len - index);
+ index = len;
+ } else {
+ /* otherwise copy remainder of whole block */
+ memcpy(buf + index, pcache->buffer +
+ vblock->ofs, leftover);
+ index += leftover;
+ }
+ } else {
+ /*
+ * Not cached so read one byte -
+ * but cache the rest of the block
+ */
+ cx = vmu_flash_read_char(from + index, &retval, mtd);
+ if (retval) {
+ *retlen = index;
+ kfree(vblock);
+ return cx;
+ }
+ memset(buf + index, cx, 1);
+ index++;
+ }
+ kfree(vblock);
+ } while (len > index);
+ *retlen = index;
+
+ return 0;
+}
+
+static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct maple_device *mdev;
+ struct memcard *card;
+ struct mdev_part *mpart;
+ int index = 0, partition, error = 0, numblocks;
+ struct vmu_cache *pcache;
+ struct vmu_block *vblock;
+ unsigned char *buffer;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+
+ /* simple sanity checks */
+ if (len < 1) {
+ error = -EIO;
+ goto failed;
+ }
+ numblocks = card->parts[partition].numblocks;
+ if (to + len > numblocks * card->blocklen)
+ len = numblocks * card->blocklen - to;
+ if (len == 0) {
+ error = -EIO;
+ goto failed;
+ }
+
+ vblock = ofs_to_block(to, mtd, partition);
+ if (!vblock) {
+ error = -ENOMEM;
+ goto failed;
+ }
+
+ buffer = kmalloc(card->blocklen, GFP_KERNEL);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto fail_buffer;
+ }
+
+ do {
+ /* Read in the block we are to write to */
+ error = maple_vmu_read_block(vblock->num, buffer, mtd);
+ if (error)
+ goto fail_io;
+
+ do {
+ buffer[vblock->ofs] = buf[index];
+ vblock->ofs++;
+ index++;
+ if (index >= len)
+ break;
+ } while (vblock->ofs < card->blocklen);
+
+ /* write out new buffer */
+ error = maple_vmu_write_block(vblock->num, buffer, mtd);
+ /* invalidate the cache */
+ pcache = card->parts[partition].pcache;
+ pcache->valid = 0;
+
+ if (error != card->blocklen)
+ goto fail_io;
+
+ vblock->num++;
+ vblock->ofs = 0;
+ } while (len > index);
+
+ kfree(buffer);
+ *retlen = index;
+ kfree(vblock);
+ return 0;
+
+fail_io:
+ kfree(buffer);
+fail_buffer:
+ kfree(vblock);
+failed:
+ dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
+ return error;
+}
+
+static void vmu_flash_sync(struct mtd_info *mtd)
+{
+ /* Do nothing here */
+}
+
+/* Maple bus callback function to recursively query hardware details */
+static void vmu_queryblocks(struct mapleq *mq)
+{
+ struct maple_device *mdev;
+ unsigned short *res;
+ struct memcard *card;
+ __be32 partnum;
+ struct vmu_cache *pcache;
+ struct mdev_part *mpart;
+ struct mtd_info *mtd_cur;
+ struct vmupart *part_cur;
+ int error;
+
+ mdev = mq->dev;
+ card = maple_get_drvdata(mdev);
+ res = (unsigned short *) (mq->recvbuf->buf);
+ card->tempA = res[12];
+ card->tempB = res[6];
+
+ dev_info(&mdev->dev, "VMU device at partition %d has %d user "
+ "blocks with a root block at %d\n", card->partition,
+ card->tempA, card->tempB);
+
+ part_cur = &card->parts[card->partition];
+ part_cur->user_blocks = card->tempA;
+ part_cur->root_block = card->tempB;
+ part_cur->numblocks = card->tempB + 1;
+ part_cur->name = kmalloc(12, GFP_KERNEL);
+ if (!part_cur->name)
+ goto fail_name;
+
+ sprintf(part_cur->name, "vmu%d.%d.%d",
+ mdev->port, mdev->unit, card->partition);
+ mtd_cur = &card->mtd[card->partition];
+ mtd_cur->name = part_cur->name;
+ mtd_cur->type = 8;
+ mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
+ mtd_cur->size = part_cur->numblocks * card->blocklen;
+ mtd_cur->erasesize = card->blocklen;
+ mtd_cur->write = vmu_flash_write;
+ mtd_cur->read = vmu_flash_read;
+ mtd_cur->sync = vmu_flash_sync;
+ mtd_cur->writesize = card->blocklen;
+
+ mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
+ if (!mpart)
+ goto fail_mpart;
+
+ mpart->mdev = mdev;
+ mpart->partition = card->partition;
+ mtd_cur->priv = mpart;
+ mtd_cur->owner = THIS_MODULE;
+
+ pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
+ if (!pcache)
+ goto fail_cache_create;
+ part_cur->pcache = pcache;
+
+ error = add_mtd_device(mtd_cur);
+ if (error)
+ goto fail_mtd_register;
+
+ maple_getcond_callback(mdev, NULL, 0,
+ MAPLE_FUNC_MEMCARD);
+
+ /*
+ * Set up a recursive call to the (probably theoretical)
+ * second or more partition
+ */
+ if (++card->partition < card->partitions) {
+ partnum = cpu_to_be32(card->partition << 24);
+ maple_getcond_callback(mdev, vmu_queryblocks, 0,
+ MAPLE_FUNC_MEMCARD);
+ maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+ MAPLE_COMMAND_GETMINFO, 2, &partnum);
+ }
+ return;
+
+fail_mtd_register:
+ dev_err(&mdev->dev, "Could not register maple device at (%d, %d)"
+ "error is 0x%X\n", mdev->port, mdev->unit, error);
+ for (error = 0; error <= card->partition; error++) {
+ kfree(((card->parts)[error]).pcache);
+ ((card->parts)[error]).pcache = NULL;
+ }
+fail_cache_create:
+fail_mpart:
+ for (error = 0; error <= card->partition; error++) {
+ kfree(((card->mtd)[error]).priv);
+ ((card->mtd)[error]).priv = NULL;
+ }
+ maple_getcond_callback(mdev, NULL, 0,
+ MAPLE_FUNC_MEMCARD);
+ kfree(part_cur->name);
+fail_name:
+ return;
+}
+
+/* Handles very basic info about the flash, queries for details */
+static int __devinit vmu_connect(struct maple_device *mdev)
+{
+ unsigned long test_flash_data, basic_flash_data;
+ int c, error;
+ struct memcard *card;
+ u32 partnum = 0;
+
+ test_flash_data = be32_to_cpu(mdev->devinfo.function);
+ /* Need to count how many bits are set - to find out which
+ * function_data element has details of the memory card:
+ * using Brian Kernighan's/Peter Wegner's method */
+ for (c = 0; test_flash_data; c++)
+ test_flash_data &= test_flash_data - 1;
+
+ basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);
+
+ card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
+ if (!card) {
+ error = ENOMEM;
+ goto fail_nomem;
+ }
+
+ card->partitions = (basic_flash_data >> 24 & 0xFF) + 1;
+ card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5;
+ card->writecnt = basic_flash_data >> 12 & 0xF;
+ card->readcnt = basic_flash_data >> 8 & 0xF;
+ card->removeable = basic_flash_data >> 7 & 1;
+
+ card->partition = 0;
+
+ /*
+ * Not sure there are actually any multi-partition devices in the
+ * real world, but the hardware supports them, so, so will we
+ */
+ card->parts = kmalloc(sizeof(struct vmupart) * card->partitions,
+ GFP_KERNEL);
+ if (!card->parts) {
+ error = -ENOMEM;
+ goto fail_partitions;
+ }
+
+ card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions,
+ GFP_KERNEL);
+ if (!card->mtd) {
+ error = -ENOMEM;
+ goto fail_mtd_info;
+ }
+
+ maple_set_drvdata(mdev, card);
+
+ /*
+ * We want to trap meminfo not get cond
+ * so set interval to zero, but rely on maple bus
+ * driver to pass back the results of the meminfo
+ */
+ maple_getcond_callback(mdev, vmu_queryblocks, 0,
+ MAPLE_FUNC_MEMCARD);
+
+ /* Make sure we are clear to go */
+ if (atomic_read(&mdev->busy) == 1) {
+ wait_event_interruptible_timeout(mdev->maple_wait,
+ atomic_read(&mdev->busy) == 0, HZ);
+ if (atomic_read(&mdev->busy) == 1) {
+ dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n",
+ mdev->port, mdev->unit);
+ error = -EAGAIN;
+ goto fail_device_busy;
+ }
+ }
+
+ atomic_set(&mdev->busy, 1);
+
+ /*
+ * Set up the minfo call: vmu_queryblocks will handle
+ * the information passed back
+ */
+ error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+ MAPLE_COMMAND_GETMINFO, 2, &partnum);
+ if (error) {
+ dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
+ " error is 0x%X\n", mdev->port, mdev->unit, error);
+ goto fail_mtd_info;
+ }
+ return 0;
+
+fail_device_busy:
+ kfree(card->mtd);
+fail_mtd_info:
+ kfree(card->parts);
+fail_partitions:
+ kfree(card);
+fail_nomem:
+ return error;
+}
+
+static void __devexit vmu_disconnect(struct maple_device *mdev)
+{
+ struct memcard *card;
+ struct mdev_part *mpart;
+ int x;
+
+ mdev->callback = NULL;
+ card = maple_get_drvdata(mdev);
+ for (x = 0; x < card->partitions; x++) {
+ mpart = ((card->mtd)[x]).priv;
+ mpart->mdev = NULL;
+ del_mtd_device(&((card->mtd)[x]));
+ kfree(((card->parts)[x]).name);
+ }
+ kfree(card->parts);
+ kfree(card->mtd);
+ kfree(card);
+}
+
+/* Callback to handle eccentricities of both mtd subsystem
+ * and general flakyness of Dreamcast VMUs
+ */
+static int vmu_can_unload(struct maple_device *mdev)
+{
+ struct memcard *card;
+ int x;
+ struct mtd_info *mtd;
+
+ card = maple_get_drvdata(mdev);
+ for (x = 0; x < card->partitions; x++) {
+ mtd = &((card->mtd)[x]);
+ if (mtd->usecount > 0)
+ return 0;
+ }
+ return 1;
+}
+
+#define ERRSTR "VMU at (%d, %d) file error -"
+
+static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
+{
+ enum maple_file_errors error = ((int *)recvbuf)[1];
+
+ switch (error) {
+
+ case MAPLE_FILEERR_INVALID_PARTITION:
+ dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_PHASE_ERROR:
+ dev_notice(&mdev->dev, ERRSTR " phase error\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_INVALID_BLOCK:
+ dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_WRITE_ERROR:
+ dev_notice(&mdev->dev, ERRSTR " write error\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
+ dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_BAD_CRC:
+ dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
+ mdev->port, mdev->unit);
+ break;
+
+ default:
+ dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
+ mdev->port, mdev->unit, error);
+ }
+}
+
+
+static int __devinit probe_maple_vmu(struct device *dev)
+{
+ int error;
+ struct maple_device *mdev = to_maple_dev(dev);
+ struct maple_driver *mdrv = to_maple_driver(dev->driver);
+
+ mdev->can_unload = vmu_can_unload;
+ mdev->fileerr_handler = vmu_file_error;
+ mdev->driver = mdrv;
+
+ error = vmu_connect(mdev);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static int __devexit remove_maple_vmu(struct device *dev)
+{
+ struct maple_device *mdev = to_maple_dev(dev);
+
+ vmu_disconnect(mdev);
+ return 0;
+}
+
+static struct maple_driver vmu_flash_driver = {
+ .function = MAPLE_FUNC_MEMCARD,
+ .drv = {
+ .name = "Dreamcast_visual_memory",
+ .probe = probe_maple_vmu,
+ .remove = __devexit_p(remove_maple_vmu),
+ },
+};
+
+static int __init vmu_flash_map_init(void)
+{
+ return maple_driver_register(&vmu_flash_driver);
+}
+
+static void __exit vmu_flash_map_exit(void)
+{
+ maple_driver_unregister(&vmu_flash_driver);
+}
+
+module_init(vmu_flash_map_init);
+module_exit(vmu_flash_map_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Adrian McMenamin");
+MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index c98c1570a40..47a33cec379 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -139,7 +139,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
struct nand_chip *nand_chip = mtd->priv;
struct atmel_nand_host *host = nand_chip->priv;
- return gpio_get_value(host->board->rdy_pin);
+ return gpio_get_value(host->board->rdy_pin) ^
+ !!host->board->rdy_pin_active_low;
}
/*
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
index ced14b5294d..72446fb48d4 100644
--- a/drivers/mtd/nand/excite_nandflash.c
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -128,11 +128,11 @@ static int excite_nand_devready(struct mtd_info *mtd)
* The binding to the mtd and all allocated
* resources are released.
*/
-static int __exit excite_nand_remove(struct device *dev)
+static int __exit excite_nand_remove(struct platform_device *dev)
{
- struct excite_nand_drvdata * const this = dev_get_drvdata(dev);
+ struct excite_nand_drvdata * const this = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (unlikely(!this)) {
printk(KERN_ERR "%s: called %s without private data!!",
@@ -159,9 +159,8 @@ static int __exit excite_nand_remove(struct device *dev)
* it can allocate all necessary resources then calls the
* nand layer to look for devices.
*/
-static int __init excite_nand_probe(struct device *dev)
+static int __init excite_nand_probe(struct platform_device *pdev)
{
- struct platform_device * const pdev = to_platform_device(dev);
struct excite_nand_drvdata *drvdata; /* private driver data */
struct nand_chip *board_chip; /* private flash chip data */
struct mtd_info *board_mtd; /* mtd info for this board */
@@ -175,7 +174,7 @@ static int __init excite_nand_probe(struct device *dev)
}
/* bind private data into driver */
- dev_set_drvdata(dev, drvdata);
+ platform_set_drvdata(pdev, drvdata);
/* allocate and map the resource */
drvdata->regs =
@@ -219,23 +218,25 @@ static int __init excite_nand_probe(struct device *dev)
return 0;
}
-static struct device_driver excite_nand_driver = {
- .name = "excite_nand",
- .bus = &platform_bus_type,
+static struct platform_driver excite_nand_driver = {
+ .driver = {
+ .name = "excite_nand",
+ .owner = THIS_MODULE,
+ },
.probe = excite_nand_probe,
- .remove = __exit_p(excite_nand_remove)
+ .remove = __devexit_p(excite_nand_remove)
};
static int __init excite_nand_init(void)
{
pr_info("Basler eXcite nand flash driver Version "
EXCITE_NANDFLASH_VERSION "\n");
- return driver_register(&excite_nand_driver);
+ return platform_driver_register(&excite_nand_driver);
}
static void __exit excite_nand_exit(void)
{
- driver_unregister(&excite_nand_driver);
+ platform_driver_unregister(&excite_nand_driver);
}
module_init(excite_nand_init);
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 65929db2944..1f6eb257871 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -676,7 +676,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
dev_dbg(ctrl->dev, "fsl_elbc_init: nand->numchips = %d\n",
chip->numchips);
- dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %ld\n",
+ dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
chip->chipsize);
dev_dbg(ctrl->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
chip->pagemask);
@@ -703,7 +703,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.layout = %p\n",
chip->ecc.layout);
dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags);
- dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %d\n", mtd->size);
+ dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size);
dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->erasesize = %d\n",
mtd->erasesize);
dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->writesize = %d\n",
@@ -932,8 +932,8 @@ static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
#endif
add_mtd_device(&priv->mtd);
- printk(KERN_INFO "eLBC NAND device at 0x%zx, bank %d\n",
- res.start, priv->bank);
+ printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n",
+ (unsigned long long)res.start, priv->bank);
return 0;
err:
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 582cf80f555..89bf85af642 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -187,7 +187,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
return -ENODEV;
ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
- ndfc->ofdev->dev.bus_id, flash_np->name);
+ dev_name(&ndfc->ofdev->dev), flash_np->name);
if (!ndfc->mtd.name) {
ret = -ENOMEM;
goto err;
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index 917cf8d3ae9..c2dfd3ea353 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -149,7 +149,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev)
static struct platform_driver orion_nand_driver = {
.probe = orion_nand_probe,
- .remove = orion_nand_remove,
+ .remove = __devexit_p(orion_nand_remove),
.driver = {
.name = "orion_nand",
.owner = THIS_MODULE,
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c
index 9bd6c9ac844..a8b9376cf32 100644
--- a/drivers/mtd/nand/pasemi_nand.c
+++ b/drivers/mtd/nand/pasemi_nand.c
@@ -107,7 +107,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev,
if (pasemi_nand_mtd)
return -ENODEV;
- pr_debug("pasemi_nand at %lx-%lx\n", res.start, res.end);
+ pr_debug("pasemi_nand at %llx-%llx\n", res.start, res.end);
/* Allocate memory for MTD device structure and private data */
pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) +
@@ -170,7 +170,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev,
goto out_lpc;
}
- printk(KERN_INFO "PA Semi NAND flash at %08lx, control at I/O %x\n",
+ printk(KERN_INFO "PA Semi NAND flash at %08llx, control at I/O %x\n",
res.start, lpcctl);
return 0;
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 5b69e7773c6..3a496c33fb5 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -36,10 +36,9 @@ struct onenand_info {
struct onenand_chip onenand;
};
-static int __devinit generic_onenand_probe(struct device *dev)
+static int __devinit generic_onenand_probe(struct platform_device *pdev)
{
struct onenand_info *info;
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *pdata = pdev->dev.platform_data;
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
@@ -49,7 +48,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
if (!info)
return -ENOMEM;
- if (!request_mem_region(res->start, size, dev->driver->name)) {
+ if (!request_mem_region(res->start, size, pdev->dev.driver->name)) {
err = -EBUSY;
goto out_free_info;
}
@@ -82,7 +81,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
#endif
err = add_mtd_device(&info->mtd);
- dev_set_drvdata(&pdev->dev, info);
+ platform_set_drvdata(pdev, info);
return 0;
@@ -96,14 +95,13 @@ out_free_info:
return err;
}
-static int __devexit generic_onenand_remove(struct device *dev)
+static int __devexit generic_onenand_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct onenand_info *info = dev_get_drvdata(&pdev->dev);
+ struct onenand_info *info = platform_get_drvdata(pdev);
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (info) {
if (info->parts)
@@ -120,9 +118,11 @@ static int __devexit generic_onenand_remove(struct device *dev)
return 0;
}
-static struct device_driver generic_onenand_driver = {
- .name = DRIVER_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver generic_onenand_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
.probe = generic_onenand_probe,
.remove = __devexit_p(generic_onenand_remove),
};
@@ -131,12 +131,12 @@ MODULE_ALIAS(DRIVER_NAME);
static int __init generic_onenand_init(void)
{
- return driver_register(&generic_onenand_driver);
+ return platform_driver_register(&generic_onenand_driver);
}
static void __exit generic_onenand_exit(void)
{
- driver_unregister(&generic_onenand_driver);
+ platform_driver_unregister(&generic_onenand_driver);
}
module_init(generic_onenand_init);
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 96ecc1766fa..77a4f144615 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -629,7 +629,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
}
if (c->gpio_irq) {
- if ((r = omap_request_gpio(c->gpio_irq)) < 0) {
+ if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
dev_err(&pdev->dev, "Failed to request GPIO%d for "
"OneNAND\n", c->gpio_irq);
goto err_iounmap;
@@ -726,7 +726,7 @@ err_release_dma:
free_irq(gpio_to_irq(c->gpio_irq), c);
err_release_gpio:
if (c->gpio_irq)
- omap_free_gpio(c->gpio_irq);
+ gpio_free(c->gpio_irq);
err_iounmap:
iounmap(c->onenand.base);
err_release_mem_region:
@@ -761,7 +761,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
if (c->gpio_irq) {
free_irq(gpio_to_irq(c->gpio_irq), c);
- omap_free_gpio(c->gpio_irq);
+ gpio_free(c->gpio_irq);
}
iounmap(c->onenand.base);
release_mem_region(c->phys_base, ONENAND_IO_SIZE);
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug
index 1e2ee22edef..2246f154e2f 100644
--- a/drivers/mtd/ubi/Kconfig.debug
+++ b/drivers/mtd/ubi/Kconfig.debug
@@ -33,16 +33,6 @@ config MTD_UBI_DEBUG_DISABLE_BGT
This option switches the background thread off by default. The thread
may be also be enabled/disabled via UBI sysfs.
-config MTD_UBI_DEBUG_USERSPACE_IO
- bool "Direct user-space write/erase support"
- default n
- depends on MTD_UBI_DEBUG
- help
- By default, users cannot directly write and erase individual
- eraseblocks of dynamic volumes, and have to use update operation
- instead. This option enables this capability - it is very useful for
- debugging and testing.
-
config MTD_UBI_DEBUG_EMULATE_BITFLIPS
bool "Emulate flash bit-flips"
depends on MTD_UBI_DEBUG
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 9082768cc6c..4048db83aef 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -263,8 +263,12 @@ static ssize_t dev_attribute_show(struct device *dev,
return ret;
}
-/* Fake "release" method for UBI devices */
-static void dev_release(struct device *dev) { }
+static void dev_release(struct device *dev)
+{
+ struct ubi_device *ubi = container_of(dev, struct ubi_device, dev);
+
+ kfree(ubi);
+}
/**
* ubi_sysfs_init - initialize sysfs for an UBI device.
@@ -380,7 +384,7 @@ static void free_user_volumes(struct ubi_device *ubi)
*/
static int uif_init(struct ubi_device *ubi)
{
- int i, err, do_free = 0;
+ int i, err;
dev_t dev;
sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
@@ -427,13 +431,10 @@ static int uif_init(struct ubi_device *ubi)
out_volumes:
kill_volumes(ubi);
- do_free = 0;
out_sysfs:
ubi_sysfs_close(ubi);
cdev_del(&ubi->cdev);
out_unreg:
- if (do_free)
- free_user_volumes(ubi);
unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1);
ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err);
return err;
@@ -947,6 +948,12 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
if (ubi->bgt_thread)
kthread_stop(ubi->bgt_thread);
+ /*
+ * Get a reference to the device in order to prevent 'dev_release()'
+ * from freeing @ubi object.
+ */
+ get_device(&ubi->dev);
+
uif_close(ubi);
ubi_wl_close(ubi);
free_internal_volumes(ubi);
@@ -958,7 +965,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
vfree(ubi->dbg_peb_buf);
#endif
ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
- kfree(ubi);
+ put_device(&ubi->dev);
return 0;
}
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 98cf31ed081..e63c8fc3df3 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -40,9 +40,9 @@
#include <linux/ioctl.h>
#include <linux/capability.h>
#include <linux/uaccess.h>
-#include <linux/smp_lock.h>
+#include <linux/compat.h>
+#include <linux/math64.h>
#include <mtd/ubi-user.h>
-#include <asm/div64.h>
#include "ubi.h"
/**
@@ -195,7 +195,6 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
int err, lnum, off, len, tbuf_size;
size_t count_save = count;
void *tbuf;
- uint64_t tmp;
dbg_gen("read %zd bytes from offset %lld of volume %d",
count, *offp, vol->vol_id);
@@ -225,10 +224,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
return -ENOMEM;
len = count > tbuf_size ? tbuf_size : count;
-
- tmp = *offp;
- off = do_div(tmp, vol->usable_leb_size);
- lnum = tmp;
+ lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
do {
cond_resched();
@@ -263,12 +259,9 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
return err ? err : count_save - count;
}
-#ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO
-
/*
* This function allows to directly write to dynamic UBI volumes, without
- * issuing the volume update operation. Available only as a debugging feature.
- * Very useful for testing UBI.
+ * issuing the volume update operation.
*/
static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
size_t count, loff_t *offp)
@@ -279,7 +272,9 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
int lnum, off, len, tbuf_size, err = 0;
size_t count_save = count;
char *tbuf;
- uint64_t tmp;
+
+ if (!vol->direct_writes)
+ return -EPERM;
dbg_gen("requested: write %zd bytes to offset %lld of volume %u",
count, *offp, vol->vol_id);
@@ -287,10 +282,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
if (vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS;
- tmp = *offp;
- off = do_div(tmp, vol->usable_leb_size);
- lnum = tmp;
-
+ lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
if (off & (ubi->min_io_size - 1)) {
dbg_err("unaligned position");
return -EINVAL;
@@ -347,10 +339,6 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
return err ? err : count_save - count;
}
-#else
-#define vol_cdev_direct_write(file, buf, count, offp) (-EPERM)
-#endif /* CONFIG_MTD_UBI_DEBUG_USERSPACE_IO */
-
static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
size_t count, loff_t *offp)
{
@@ -402,8 +390,8 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
return count;
}
-static int vol_cdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
int err = 0;
struct ubi_volume_desc *desc = file->private_data;
@@ -487,7 +475,6 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file,
break;
}
-#ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO
/* Logical eraseblock erasure command */
case UBI_IOCEBER:
{
@@ -518,13 +505,77 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file,
err = ubi_wl_flush(ubi);
break;
}
-#endif
+
+ /* Logical eraseblock map command */
+ case UBI_IOCEBMAP:
+ {
+ struct ubi_map_req req;
+
+ err = copy_from_user(&req, argp, sizeof(struct ubi_map_req));
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+ err = ubi_leb_map(desc, req.lnum, req.dtype);
+ break;
+ }
+
+ /* Logical eraseblock un-map command */
+ case UBI_IOCEBUNMAP:
+ {
+ int32_t lnum;
+
+ err = get_user(lnum, (__user int32_t *)argp);
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+ err = ubi_leb_unmap(desc, lnum);
+ break;
+ }
+
+ /* Check if logical eraseblock is mapped command */
+ case UBI_IOCEBISMAP:
+ {
+ int32_t lnum;
+
+ err = get_user(lnum, (__user int32_t *)argp);
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+ err = ubi_is_mapped(desc, lnum);
+ break;
+ }
+
+ /* Set volume property command*/
+ case UBI_IOCSETPROP:
+ {
+ struct ubi_set_prop_req req;
+
+ err = copy_from_user(&req, argp,
+ sizeof(struct ubi_set_prop_req));
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+ switch (req.property) {
+ case UBI_PROP_DIRECT_WRITE:
+ mutex_lock(&ubi->volumes_mutex);
+ desc->vol->direct_writes = !!req.value;
+ mutex_unlock(&ubi->volumes_mutex);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ break;
+ }
default:
err = -ENOTTY;
break;
}
-
return err;
}
@@ -762,8 +813,8 @@ out_free:
return err;
}
-static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
int err = 0;
struct ubi_device *ubi;
@@ -773,7 +824,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
if (!capable(CAP_SYS_RESOURCE))
return -EPERM;
- ubi = ubi_get_by_major(imajor(inode));
+ ubi = ubi_get_by_major(imajor(file->f_mapping->host));
if (!ubi)
return -ENODEV;
@@ -843,7 +894,6 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
case UBI_IOCRSVOL:
{
int pebs;
- uint64_t tmp;
struct ubi_rsvol_req req;
dbg_gen("re-size volume");
@@ -863,9 +913,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
break;
}
- tmp = req.bytes;
- pebs = !!do_div(tmp, desc->vol->usable_leb_size);
- pebs += tmp;
+ pebs = div_u64(req.bytes + desc->vol->usable_leb_size - 1,
+ desc->vol->usable_leb_size);
mutex_lock(&ubi->volumes_mutex);
err = ubi_resize_volume(desc, pebs);
@@ -909,8 +958,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
return err;
}
-static int ctrl_cdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
int err = 0;
void __user *argp = (void __user *)arg;
@@ -986,26 +1035,59 @@ static int ctrl_cdev_ioctl(struct inode *inode, struct file *file,
return err;
}
-/* UBI control character device operations */
-struct file_operations ubi_ctrl_cdev_operations = {
- .ioctl = ctrl_cdev_ioctl,
- .owner = THIS_MODULE,
+#ifdef CONFIG_COMPAT
+static long vol_cdev_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned long translated_arg = (unsigned long)compat_ptr(arg);
+
+ return vol_cdev_ioctl(file, cmd, translated_arg);
+}
+
+static long ubi_cdev_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned long translated_arg = (unsigned long)compat_ptr(arg);
+
+ return ubi_cdev_ioctl(file, cmd, translated_arg);
+}
+
+static long ctrl_cdev_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned long translated_arg = (unsigned long)compat_ptr(arg);
+
+ return ctrl_cdev_ioctl(file, cmd, translated_arg);
+}
+#else
+#define vol_cdev_compat_ioctl NULL
+#define ubi_cdev_compat_ioctl NULL
+#define ctrl_cdev_compat_ioctl NULL
+#endif
+
+/* UBI volume character device operations */
+const struct file_operations ubi_vol_cdev_operations = {
+ .owner = THIS_MODULE,
+ .open = vol_cdev_open,
+ .release = vol_cdev_release,
+ .llseek = vol_cdev_llseek,
+ .read = vol_cdev_read,
+ .write = vol_cdev_write,
+ .unlocked_ioctl = vol_cdev_ioctl,
+ .compat_ioctl = vol_cdev_compat_ioctl,
};
/* UBI character device operations */
-struct file_operations ubi_cdev_operations = {
- .owner = THIS_MODULE,
- .ioctl = ubi_cdev_ioctl,
- .llseek = no_llseek,
+const struct file_operations ubi_cdev_operations = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .unlocked_ioctl = ubi_cdev_ioctl,
+ .compat_ioctl = ubi_cdev_compat_ioctl,
};
-/* UBI volume character device operations */
-struct file_operations ubi_vol_cdev_operations = {
- .owner = THIS_MODULE,
- .open = vol_cdev_open,
- .release = vol_cdev_release,
- .llseek = vol_cdev_llseek,
- .read = vol_cdev_read,
- .write = vol_cdev_write,
- .ioctl = vol_cdev_ioctl,
+/* UBI control character device operations */
+const struct file_operations ubi_ctrl_cdev_operations = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = ctrl_cdev_ioctl,
+ .compat_ioctl = ctrl_cdev_compat_ioctl,
};
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c
index 6dd4f5e77f8..49cd55ade9c 100644
--- a/drivers/mtd/ubi/gluebi.c
+++ b/drivers/mtd/ubi/gluebi.c
@@ -28,7 +28,7 @@
* eraseblock size is equivalent to the logical eraseblock size of the volume.
*/
-#include <asm/div64.h>
+#include <linux/math64.h>
#include "ubi.h"
/**
@@ -109,7 +109,6 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
int err = 0, lnum, offs, total_read;
struct ubi_volume *vol;
struct ubi_device *ubi;
- uint64_t tmp = from;
dbg_gen("read %zd bytes from offset %lld", len, from);
@@ -119,9 +118,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
vol = container_of(mtd, struct ubi_volume, gluebi_mtd);
ubi = vol->ubi;
- offs = do_div(tmp, mtd->erasesize);
- lnum = tmp;
-
+ lnum = div_u64_rem(from, mtd->erasesize, &offs);
total_read = len;
while (total_read) {
size_t to_read = mtd->erasesize - offs;
@@ -160,7 +157,6 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
int err = 0, lnum, offs, total_written;
struct ubi_volume *vol;
struct ubi_device *ubi;
- uint64_t tmp = to;
dbg_gen("write %zd bytes to offset %lld", len, to);
@@ -173,8 +169,7 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
if (ubi->ro_mode)
return -EROFS;
- offs = do_div(tmp, mtd->erasesize);
- lnum = tmp;
+ lnum = div_u64_rem(to, mtd->erasesize, &offs);
if (len % mtd->writesize || offs % mtd->writesize)
return -EINVAL;
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index ecde202a5a1..c3d653ba5ca 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -42,7 +42,7 @@
#include <linux/err.h>
#include <linux/crc32.h>
-#include <asm/div64.h>
+#include <linux/math64.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
@@ -904,10 +904,8 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
dbg_msg("scanning is finished");
/* Calculate mean erase counter */
- if (si->ec_count) {
- do_div(si->ec_sum, si->ec_count);
- si->mean_ec = si->ec_sum;
- }
+ if (si->ec_count)
+ si->mean_ec = div_u64(si->ec_sum, si->ec_count);
if (si->is_empty)
ubi_msg("empty MTD device detected");
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 4a8ec485c91..c055511bb1b 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -206,6 +206,7 @@ struct ubi_volume_desc;
* @upd_marker: %1 if the update marker is set for this volume
* @updating: %1 if the volume is being updated
* @changing_leb: %1 if the atomic LEB change ioctl command is in progress
+ * @direct_writes: %1 if direct writes are enabled for this volume
*
* @gluebi_desc: gluebi UBI volume descriptor
* @gluebi_refcount: reference count of the gluebi MTD device
@@ -253,6 +254,7 @@ struct ubi_volume {
unsigned int upd_marker:1;
unsigned int updating:1;
unsigned int changing_leb:1;
+ unsigned int direct_writes:1;
#ifdef CONFIG_MTD_UBI_GLUEBI
/*
@@ -304,7 +306,8 @@ struct ubi_wl_entry;
* @vtbl_size: size of the volume table in bytes
* @vtbl: in-RAM volume table copy
* @volumes_mutex: protects on-flash volume table and serializes volume
- * changes, like creation, deletion, update, re-size and re-name
+ * changes, like creation, deletion, update, re-size,
+ * re-name and set property
*
* @max_ec: current highest erase counter value
* @mean_ec: current mean erase counter value
@@ -449,9 +452,9 @@ struct ubi_device {
};
extern struct kmem_cache *ubi_wl_entry_slab;
-extern struct file_operations ubi_ctrl_cdev_operations;
-extern struct file_operations ubi_cdev_operations;
-extern struct file_operations ubi_vol_cdev_operations;
+extern const struct file_operations ubi_ctrl_cdev_operations;
+extern const struct file_operations ubi_cdev_operations;
+extern const struct file_operations ubi_vol_cdev_operations;
extern struct class *ubi_class;
extern struct mutex ubi_devices_mutex;
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
index 8b89cc18ff0..6b4d1ae891a 100644
--- a/drivers/mtd/ubi/upd.c
+++ b/drivers/mtd/ubi/upd.c
@@ -40,7 +40,7 @@
#include <linux/err.h>
#include <linux/uaccess.h>
-#include <asm/div64.h>
+#include <linux/math64.h>
#include "ubi.h"
/**
@@ -89,7 +89,6 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol,
long long bytes)
{
int err;
- uint64_t tmp;
struct ubi_vtbl_record vtbl_rec;
dbg_gen("clear update marker for volume %d", vol->vol_id);
@@ -101,9 +100,9 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol,
if (vol->vol_type == UBI_STATIC_VOLUME) {
vol->corrupted = 0;
- vol->used_bytes = tmp = bytes;
- vol->last_eb_bytes = do_div(tmp, vol->usable_leb_size);
- vol->used_ebs = tmp;
+ vol->used_bytes = bytes;
+ vol->used_ebs = div_u64_rem(bytes, vol->usable_leb_size,
+ &vol->last_eb_bytes);
if (vol->last_eb_bytes)
vol->used_ebs += 1;
else
@@ -131,7 +130,6 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
long long bytes)
{
int i, err;
- uint64_t tmp;
dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes);
ubi_assert(!vol->updating && !vol->changing_leb);
@@ -161,9 +159,8 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
if (!vol->upd_buf)
return -ENOMEM;
- tmp = bytes;
- vol->upd_ebs = !!do_div(tmp, vol->usable_leb_size);
- vol->upd_ebs += tmp;
+ vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1,
+ vol->usable_leb_size);
vol->upd_bytes = bytes;
vol->upd_received = 0;
return 0;
@@ -282,7 +279,6 @@ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
const void __user *buf, int count)
{
- uint64_t tmp;
int lnum, offs, err = 0, len, to_write = count;
dbg_gen("write %d of %lld bytes, %lld already passed",
@@ -291,10 +287,7 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
if (ubi->ro_mode)
return -EROFS;
- tmp = vol->upd_received;
- offs = do_div(tmp, vol->usable_leb_size);
- lnum = tmp;
-
+ lnum = div_u64_rem(vol->upd_received, vol->usable_leb_size, &offs);
if (vol->upd_received + count > vol->upd_bytes)
to_write = count = vol->upd_bytes - vol->upd_received;
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 22e1d7398fc..df5483562b7 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -24,7 +24,7 @@
*/
#include <linux/err.h>
-#include <asm/div64.h>
+#include <linux/math64.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
@@ -205,7 +205,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
int i, err, vol_id = req->vol_id, do_free = 1;
struct ubi_volume *vol;
struct ubi_vtbl_record vtbl_rec;
- uint64_t bytes;
dev_t dev;
if (ubi->ro_mode)
@@ -255,10 +254,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
/* Calculate how many eraseblocks are requested */
vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment;
- bytes = req->bytes;
- if (do_div(bytes, vol->usable_leb_size))
- vol->reserved_pebs = 1;
- vol->reserved_pebs += bytes;
+ vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1,
+ vol->usable_leb_size);
/* Reserve physical eraseblocks */
if (vol->reserved_pebs > ubi->avail_pebs) {
@@ -301,10 +298,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vol->used_bytes =
(long long)vol->used_ebs * vol->usable_leb_size;
} else {
- bytes = vol->used_bytes;
- vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size);
- vol->used_ebs = bytes;
- if (vol->last_eb_bytes)
+ vol->used_ebs = div_u64_rem(vol->used_bytes,
+ vol->usable_leb_size,
+ &vol->last_eb_bytes);
+ if (vol->last_eb_bytes != 0)
vol->used_ebs += 1;
else
vol->last_eb_bytes = vol->usable_leb_size;
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index 3d1318a3e68..1c5344aa57c 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -197,6 +197,17 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops el_netdev_ops = {
+ .ndo_open = el_open,
+ .ndo_stop = el1_close,
+ .ndo_start_xmit = el_start_xmit,
+ .ndo_tx_timeout = el_timeout,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/**
* el1_probe1:
* @dev: The device structure to use
@@ -305,12 +316,8 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
* The EL1-specific entries in the device structure.
*/
- dev->open = &el_open;
- dev->hard_start_xmit = &el_start_xmit;
- dev->tx_timeout = &el_timeout;
+ dev->netdev_ops = &el_netdev_ops;
dev->watchdog_timeo = HZ;
- dev->stop = &el1_close;
- dev->set_multicast_list = &set_multicast_list;
dev->ethtool_ops = &netdev_ethtool_ops;
return 0;
}
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index 6124605bef0..2de1c9cd7bd 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -493,21 +493,27 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
}
/* read the data */
spin_lock_irqsave(&adapter->lock, flags);
- i = 0;
- do {
- j = 0;
- while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000);
- pcb->data.raw[i++] = inb_command(dev->base_addr);
- if (i > MAX_PCB_DATA)
- INVALID_PCB_MSG(i);
- } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000);
+ for (i = 0; i < MAX_PCB_DATA; i++) {
+ for (j = 0; j < 20000; j++) {
+ stat = get_status(dev->base_addr);
+ if (stat & ACRF)
+ break;
+ }
+ pcb->data.raw[i] = inb_command(dev->base_addr);
+ if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000)
+ break;
+ }
spin_unlock_irqrestore(&adapter->lock, flags);
+ if (i >= MAX_PCB_DATA) {
+ INVALID_PCB_MSG(i);
+ return false;
+ }
if (j >= 20000) {
TIMEOUT_MSG(__LINE__);
return false;
}
- /* woops, the last "data" byte was really the length! */
- total_length = pcb->data.raw[--i];
+ /* the last "data" byte was really the length! */
+ total_length = pcb->data.raw[i];
/* safety check total length vs data length */
if (total_length != (pcb->length + 2)) {
@@ -1348,6 +1354,17 @@ static int __init elp_autodetect(struct net_device *dev)
return 0; /* Because of this, the layer above will return -ENODEV */
}
+static const struct net_device_ops elp_netdev_ops = {
+ .ndo_open = elp_open,
+ .ndo_stop = elp_close,
+ .ndo_get_stats = elp_get_stats,
+ .ndo_start_xmit = elp_start_xmit,
+ .ndo_tx_timeout = elp_timeout,
+ .ndo_set_multicast_list = elp_set_mc_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
/******************************************************
*
@@ -1552,13 +1569,8 @@ static int __init elplus_setup(struct net_device *dev)
printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
}
- dev->open = elp_open; /* local */
- dev->stop = elp_close; /* local */
- dev->get_stats = elp_get_stats; /* local */
- dev->hard_start_xmit = elp_start_xmit; /* local */
- dev->tx_timeout = elp_timeout; /* local */
+ dev->netdev_ops = &elp_netdev_ops;
dev->watchdog_timeo = 10*HZ;
- dev->set_multicast_list = elp_set_mc_list; /* local */
dev->ethtool_ops = &netdev_ethtool_ops; /* local */
dev->mem_start = dev->mem_end = 0;
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index 423e65d0ba7..fbbaf826def 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -352,6 +352,16 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = el16_open,
+ .ndo_stop = el16_close,
+ .ndo_start_xmit = el16_send_packet,
+ .ndo_tx_timeout = el16_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init el16_probe1(struct net_device *dev, int ioaddr)
{
static unsigned char init_ID_done, version_printed;
@@ -449,10 +459,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
goto out1;
}
- dev->open = el16_open;
- dev->stop = el16_close;
- dev->hard_start_xmit = el16_send_packet;
- dev->tx_timeout = el16_tx_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
dev->ethtool_ops = &netdev_ethtool_ops;
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 535c234286e..fbb37192199 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -537,6 +537,21 @@ static struct mca_driver el3_mca_driver = {
static int mca_registered;
#endif /* CONFIG_MCA */
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = el3_poll_controller,
+#endif
+};
+
static int __devinit el3_common_init(struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
@@ -553,16 +568,8 @@ static int __devinit el3_common_init(struct net_device *dev)
}
/* The EL3-specific entries in the device structure. */
- dev->open = &el3_open;
- dev->hard_start_xmit = &el3_start_xmit;
- dev->stop = &el3_close;
- dev->get_stats = &el3_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->tx_timeout = el3_tx_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = el3_poll_controller;
-#endif
SET_ETHTOOL_OPS(dev, &ethtool_ops);
err = register_netdev(dev);
@@ -1475,6 +1482,7 @@ el3_resume(struct device *pdev)
spin_lock_irqsave(&lp->lock, flags);
outw(PowerUp, ioaddr + EL3_CMD);
+ EL3WINDOW(0);
el3_up(dev);
if (netif_running(dev))
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 39ac12233aa..167bf23066e 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -563,6 +563,20 @@ no_pnp:
return NULL;
}
+
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = corkscrew_open,
+ .ndo_stop = corkscrew_close,
+ .ndo_start_xmit = corkscrew_start_xmit,
+ .ndo_tx_timeout = corkscrew_timeout,
+ .ndo_get_stats = corkscrew_get_stats,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+
static int corkscrew_setup(struct net_device *dev, int ioaddr,
struct pnp_dev *idev, int card_number)
{
@@ -681,13 +695,8 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
/* The 3c51x-specific entries in the device structure. */
- dev->open = &corkscrew_open;
- dev->hard_start_xmit = &corkscrew_start_xmit;
- dev->tx_timeout = &corkscrew_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = (400 * HZ) / 1000;
- dev->stop = &corkscrew_close;
- dev->get_stats = &corkscrew_get_stats;
- dev->set_multicast_list = &set_rx_mode;
dev->ethtool_ops = &netdev_ethtool_ops;
return register_netdev(dev);
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index ff41e1ff560..8f734d74b51 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -403,6 +403,20 @@ static int elmc_getinfo(char *buf, int slot, void *d)
return len;
} /* elmc_getinfo() */
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = elmc_open,
+ .ndo_stop = elmc_close,
+ .ndo_get_stats = elmc_get_stats,
+ .ndo_start_xmit = elmc_send_packet,
+ .ndo_tx_timeout = elmc_timeout,
+#ifdef ELMC_MULTICAST
+ .ndo_set_multicast_list = set_multicast_list,
+#endif
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*****************************************************************/
static int __init do_elmc_probe(struct net_device *dev)
@@ -544,17 +558,8 @@ static int __init do_elmc_probe(struct net_device *dev)
printk(KERN_INFO "%s: hardware address %pM\n",
dev->name, dev->dev_addr);
- dev->open = &elmc_open;
- dev->stop = &elmc_close;
- dev->get_stats = &elmc_get_stats;
- dev->hard_start_xmit = &elmc_send_packet;
- dev->tx_timeout = &elmc_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = HZ;
-#ifdef ELMC_MULTICAST
- dev->set_multicast_list = &set_multicast_list;
-#else
- dev->set_multicast_list = NULL;
-#endif
dev->ethtool_ops = &netdev_ethtool_ops;
/* note that we haven't actually requested the IRQ from the kernel.
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index 2df3af3b9b2..b61073c42bf 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -288,6 +288,18 @@ struct net_device *__init mc32_probe(int unit)
return ERR_PTR(-ENODEV);
}
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = mc32_open,
+ .ndo_stop = mc32_close,
+ .ndo_start_xmit = mc32_send_packet,
+ .ndo_get_stats = mc32_get_stats,
+ .ndo_set_multicast_list = mc32_set_multicast_list,
+ .ndo_tx_timeout = mc32_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/**
* mc32_probe1 - Check a given slot for a board and test the card
* @dev: Device structure to fill in
@@ -518,12 +530,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
printk("%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->open = mc32_open;
- dev->stop = mc32_close;
- dev->hard_start_xmit = mc32_send_packet;
- dev->get_stats = mc32_get_stats;
- dev->set_multicast_list = mc32_set_multicast_list;
- dev->tx_timeout = mc32_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = HZ*5; /* Board does all the work */
dev->ethtool_ops = &netdev_ethtool_ops;
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index cdbbb6226fc..c5669840242 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -102,8 +102,8 @@ static int vortex_debug = 1;
#include <linux/delay.h>
-static char version[] __devinitdata =
-DRV_NAME ": Donald Becker and others.\n";
+static const char version[] __devinitconst =
+ DRV_NAME ": Donald Becker and others.\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver ");
@@ -992,6 +992,42 @@ out:
return rc;
}
+static const struct net_device_ops boomrang_netdev_ops = {
+ .ndo_open = vortex_open,
+ .ndo_stop = vortex_close,
+ .ndo_start_xmit = boomerang_start_xmit,
+ .ndo_tx_timeout = vortex_tx_timeout,
+ .ndo_get_stats = vortex_get_stats,
+#ifdef CONFIG_PCI
+ .ndo_do_ioctl = vortex_ioctl,
+#endif
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = poll_vortex,
+#endif
+};
+
+static const struct net_device_ops vortex_netdev_ops = {
+ .ndo_open = vortex_open,
+ .ndo_stop = vortex_close,
+ .ndo_start_xmit = vortex_start_xmit,
+ .ndo_tx_timeout = vortex_tx_timeout,
+ .ndo_get_stats = vortex_get_stats,
+#ifdef CONFIG_PCI
+ .ndo_do_ioctl = vortex_ioctl,
+#endif
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = poll_vortex,
+#endif
+};
+
/*
* Start up the PCI/EISA device which is described by *gendev.
* Return 0 on success.
@@ -1366,18 +1402,16 @@ static int __devinit vortex_probe1(struct device *gendev,
}
/* The 3c59x-specific entries in the device structure. */
- dev->open = vortex_open;
if (vp->full_bus_master_tx) {
- dev->hard_start_xmit = boomerang_start_xmit;
+ dev->netdev_ops = &boomrang_netdev_ops;
/* Actually, it still should work with iommu. */
if (card_idx < MAX_UNITS &&
((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
hw_checksums[card_idx] == 1)) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
}
- } else {
- dev->hard_start_xmit = vortex_start_xmit;
- }
+ } else
+ dev->netdev_ops = &vortex_netdev_ops;
if (print_info) {
printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
@@ -1386,18 +1420,9 @@ static int __devinit vortex_probe1(struct device *gendev,
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
}
- dev->stop = vortex_close;
- dev->get_stats = vortex_get_stats;
-#ifdef CONFIG_PCI
- dev->do_ioctl = vortex_ioctl;
-#endif
dev->ethtool_ops = &vortex_ethtool_ops;
- dev->set_multicast_list = set_rx_mode;
- dev->tx_timeout = vortex_tx_timeout;
dev->watchdog_timeo = (watchdog * HZ) / 1000;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = poll_vortex;
-#endif
+
if (pdev) {
vp->pm_state_valid = 1;
pci_save_state(VORTEX_PCI(vp));
@@ -2883,7 +2908,7 @@ static void vortex_get_drvinfo(struct net_device *dev,
strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
} else {
if (VORTEX_EISA(vp))
- sprintf(info->bus_info, dev_name(vp->gendev));
+ strcpy(info->bus_info, dev_name(vp->gendev));
else
sprintf(info->bus_info, "EISA 0x%lx %d",
dev->base_addr, dev->irq);
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 4e19ae3ce6b..a09e3a7cac4 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -604,7 +604,7 @@ rx_next:
spin_lock_irqsave(&cp->lock, flags);
cpw16_f(IntrMask, cp_intr_mask);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
spin_unlock_irqrestore(&cp->lock, flags);
}
@@ -641,9 +641,9 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
}
if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
- if (netif_rx_schedule_prep(&cp->napi)) {
+ if (napi_schedule_prep(&cp->napi)) {
cpw16_f(IntrMask, cp_norx_intr_mask);
- __netif_rx_schedule(&cp->napi);
+ __napi_schedule(&cp->napi);
}
if (status & (TxOK | TxErr | TxEmpty | SWInt))
@@ -1602,6 +1602,28 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
return rc;
}
+static int cp_set_mac_address(struct net_device *dev, void *p)
+{
+ struct cp_private *cp = 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);
+
+ spin_lock_irq(&cp->lock);
+
+ cpw8_f(Cfg9346, Cfg9346_Unlock);
+ cpw32_f(MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
+ cpw32_f(MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
+ cpw8_f(Cfg9346, Cfg9346_Lock);
+
+ spin_unlock_irq(&cp->lock);
+
+ return 0;
+}
+
/* Serial EEPROM section. */
/* EEPROM_Ctrl bits. */
@@ -1821,7 +1843,7 @@ static const struct net_device_ops cp_netdev_ops = {
.ndo_open = cp_open,
.ndo_stop = cp_close,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = cp_set_mac_address,
.ndo_set_multicast_list = cp_set_rx_mode,
.ndo_get_stats = cp_get_stats,
.ndo_do_ioctl = cp_ioctl,
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index a5b24202d56..29df398b772 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -640,6 +640,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb,
#ifdef CONFIG_NET_POLL_CONTROLLER
static void rtl8139_poll_controller(struct net_device *dev);
#endif
+static int rtl8139_set_mac_address(struct net_device *dev, void *p);
static int rtl8139_poll(struct napi_struct *napi, int budget);
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
static int rtl8139_close (struct net_device *dev);
@@ -917,7 +918,7 @@ static const struct net_device_ops rtl8139_netdev_ops = {
.ndo_stop = rtl8139_close,
.ndo_get_stats = rtl8139_get_stats,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = rtl8139_set_mac_address,
.ndo_start_xmit = rtl8139_start_xmit,
.ndo_set_multicast_list = rtl8139_set_rx_mode,
.ndo_do_ioctl = netdev_ioctl,
@@ -2128,7 +2129,7 @@ static int rtl8139_poll(struct napi_struct *napi, int budget)
*/
spin_lock_irqsave(&tp->lock, flags);
RTL_W16_F(IntrMask, rtl8139_intr_mask);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
spin_unlock_irqrestore(&tp->lock, flags);
}
spin_unlock(&tp->rx_lock);
@@ -2178,9 +2179,9 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
/* Receive packets are processed by poll routine.
If not running start it now. */
if (status & RxAckBits){
- if (netif_rx_schedule_prep(&tp->napi)) {
+ if (napi_schedule_prep(&tp->napi)) {
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
- __netif_rx_schedule(&tp->napi);
+ __napi_schedule(&tp->napi);
}
}
@@ -2215,6 +2216,29 @@ static void rtl8139_poll_controller(struct net_device *dev)
}
#endif
+static int rtl8139_set_mac_address(struct net_device *dev, void *p)
+{
+ struct rtl8139_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ spin_lock_irq(&tp->lock);
+
+ RTL_W8_F(Cfg9346, Cfg9346_Unlock);
+ RTL_W32_F(MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
+ RTL_W32_F(MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+ RTL_W8_F(Cfg9346, Cfg9346_Lock);
+
+ spin_unlock_irq(&tp->lock);
+
+ return 0;
+}
+
static int rtl8139_close (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index b273596368e..cca94b9c08a 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -1122,6 +1122,17 @@ static void print_eth(unsigned char *add, char *str)
static int io = 0x300;
static int irq = 10;
+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_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
struct net_device * __init i82596_probe(int unit)
{
struct net_device *dev;
@@ -1232,11 +1243,7 @@ found:
DEB(DEB_PROBE,printk(KERN_INFO "%s", version));
/* 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;
dev->ml_priv = (void *)(dev->mem_start);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9fe8cb7d43a..e5ffc1c606c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -26,6 +26,15 @@ menuconfig NETDEVICES
# that for each of the symbols.
if NETDEVICES
+config COMPAT_NET_DEV_OPS
+ default y
+ bool "Enable older network device API compatiablity"
+ ---help---
+ This option enables kernel compatiability 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
@@ -1040,6 +1049,17 @@ config NI65
To compile this driver as a module, choose M here. The module
will be called ni65.
+config DNET
+ tristate "Dave ethernet support (DNET)"
+ depends on NET_ETHERNET && HAS_IOMEM
+ select PHYLIB
+ help
+ The Dave ethernet interface (DNET) is found on Qong Board FPGA.
+ Say Y to include support for the DNET chip.
+
+ To compile this driver as a module, choose M here: the module
+ will be called dnet.
+
source "drivers/net/tulip/Kconfig"
config AT1700
@@ -1829,10 +1849,10 @@ config 68360_ENET
config FEC
bool "FEC ethernet controller (of ColdFire CPUs)"
- depends on M523x || M527x || M5272 || M528x || M520x
+ depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27
help
Say Y here if you want to use the built-in 10/100 Fast ethernet
- controller on some Motorola ColdFire processors.
+ controller on some Motorola ColdFire and Freescale i.MX processors.
config FEC2
bool "Second FEC ethernet controller (on some ColdFire CPUs)"
@@ -2019,15 +2039,6 @@ config IGB
To compile this driver as a module, choose M here. The module
will be called igb.
-config IGB_LRO
- bool "Use software LRO"
- depends on IGB && INET
- select INET_LRO
- ---help---
- Say Y here if you want to use large receive offload.
-
- If in doubt, say N.
-
config IGB_DCA
bool "Direct Cache Access (DCA) Support"
default y
@@ -2273,9 +2284,17 @@ config GELIC_WIRELESS_OLD_PSK_INTERFACE
If unsure, say N.
+config FSL_PQ_MDIO
+ tristate "Freescale PQ MDIO"
+ depends on FSL_SOC
+ select PHYLIB
+ help
+ This driver supports the MDIO bus used by the gianfar and UCC drivers.
+
config GIANFAR
tristate "Gianfar Ethernet"
depends on FSL_SOC
+ select FSL_PQ_MDIO
select PHYLIB
select CRC32
help
@@ -2285,6 +2304,7 @@ config GIANFAR
config UCC_GETH
tristate "Freescale QE Gigabit Ethernet"
depends on QUICC_ENGINE
+ select FSL_PQ_MDIO
select PHYLIB
help
This driver supports the Gigabit Ethernet mode of the QUICC Engine,
@@ -2301,6 +2321,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
+ select INET_LRO
select PHYLIB
help
This driver supports the gigabit ethernet MACs in the
@@ -2342,6 +2363,17 @@ config ATL1E
To compile this driver as a module, choose M here. The module
will be called atl1e.
+config ATL1C
+ tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
+ depends on PCI && EXPERIMENTAL
+ select CRC32
+ select MII
+ help
+ This driver supports the Atheros L1C gigabit ethernet adapter.
+
+ To compile this driver as a module, choose M here. The module
+ will be called atl1c.
+
config JME
tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
depends on PCI
@@ -2408,7 +2440,6 @@ config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support"
depends on CHELSIO_T3_DEPENDS
select FW_LOADER
- select INET_LRO
help
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
adapters.
@@ -2444,7 +2475,6 @@ config ENIC
config IXGBE
tristate "Intel(R) 10GbE PCI Express adapters support"
depends on PCI && INET
- select INET_LRO
---help---
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
@@ -2608,6 +2638,8 @@ config QLGE
source "drivers/net/sfc/Kconfig"
+source "drivers/net/benet/Kconfig"
+
endif # NETDEV_10000
source "drivers/net/tokenring/Kconfig"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index a3c5c002f22..758ecdf4c82 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -17,18 +17,21 @@ obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_ATL1) += atlx/
obj-$(CONFIG_ATL2) += atlx/
obj-$(CONFIG_ATL1E) += atl1e/
+obj-$(CONFIG_ATL1C) += atl1c/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
obj-$(CONFIG_TEHUTI) += tehuti.o
obj-$(CONFIG_ENIC) += enic/
obj-$(CONFIG_JME) += jme.o
+obj-$(CONFIG_BE2NET) += benet/
gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \
- gianfar_mii.o \
gianfar_sysfs.o
obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
-ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o ucc_geth_ethtool.o
+ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
+
+obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o
#
# link order important here
@@ -230,6 +233,7 @@ obj-$(CONFIG_ENC28J60) += enc28j60.o
obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
+obj-$(CONFIG_DNET) += dnet.o
obj-$(CONFIG_MACB) += macb.o
obj-$(CONFIG_ARM) += arm/
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 7a60bdd9a24..d0d0c2fee05 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -552,18 +552,13 @@ 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 struct lance_init_block *ib = lp->init_block;
- int entry, skblen, len;
+ int entry, skblen;
int status = 0;
unsigned long flags;
- skblen = skb->len;
- len = skblen;
-
- if (len < ETH_ZLEN) {
- len = ETH_ZLEN;
- if (skb_padto(skb, ETH_ZLEN))
- return 0;
- }
+ if (skb_padto(skb, ETH_ZLEN))
+ return 0;
+ skblen = max_t(unsigned, skb->len, ETH_ZLEN);
local_irq_save(flags);
@@ -586,15 +581,11 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
}
#endif
entry = lp->tx_new & lp->tx_ring_mod_mask;
- ib->btx_ring [entry].length = (-len) | 0xf000;
+ ib->btx_ring [entry].length = (-skblen) | 0xf000;
ib->btx_ring [entry].misc = 0;
skb_copy_from_linear_data(skb, (void *)&ib->tx_buf [entry][0], skblen);
- /* Clear the slack of the packet, do I need this? */
- if (len != skblen)
- memset ((void *) &ib->tx_buf [entry][skblen], 0, len - skblen);
-
/* Now, give the packet to the lance */
ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask;
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 9589d620639..06a9f11669f 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -437,7 +437,7 @@ MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C985/GA620 max number of receive descript
MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)");
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
"acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 7709992bb6b..cb9c95d3ed0 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -831,7 +831,7 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
if (rx_pkt_limit > 0) {
/* Receive descriptor is empty now */
spin_lock_irqsave(&lp->lock, flags);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
writel(VAL0|RINTEN0, mmio + INTEN0);
writel(VAL2 | RDMD0, mmio + CMD0);
spin_unlock_irqrestore(&lp->lock, flags);
@@ -1170,11 +1170,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
/* Check if Receive Interrupt has occurred. */
if (intr0 & RINT0) {
- if (netif_rx_schedule_prep(&lp->napi)) {
+ if (napi_schedule_prep(&lp->napi)) {
/* Disable receive interupts */
writel(RINTEN0, mmio + INTEN0);
/* Schedule a polling routine */
- __netif_rx_schedule(&lp->napi);
+ __napi_schedule(&lp->napi);
} else if (intren0 & RINTEN0) {
printk("************Driver bug! \
interrupt while in poll\n");
diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
index 3ff9affb1a9..646dfc5f50c 100644
--- a/drivers/net/arcnet/arc-rawmode.c
+++ b/drivers/net/arcnet/arc-rawmode.c
@@ -102,7 +102,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -122,7 +122,7 @@ static void rx(struct net_device *dev, int bufnum,
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
- skb->protocol = __constant_htons(ETH_P_ARCNET);
+ skb->protocol = cpu_to_be16(ETH_P_ARCNET);
;
netif_rx(skb);
}
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 6b53e5ed125..d6d4ab3b430 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -95,17 +95,16 @@ EXPORT_SYMBOL(arcnet_unregister_proto);
EXPORT_SYMBOL(arcnet_debug);
EXPORT_SYMBOL(alloc_arcdev);
EXPORT_SYMBOL(arcnet_interrupt);
+EXPORT_SYMBOL(arcnet_open);
+EXPORT_SYMBOL(arcnet_close);
+EXPORT_SYMBOL(arcnet_send_packet);
+EXPORT_SYMBOL(arcnet_timeout);
/* Internal function prototypes */
-static int arcnet_open(struct net_device *dev);
-static int arcnet_close(struct net_device *dev);
-static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev);
-static void arcnet_timeout(struct net_device *dev);
static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *daddr,
const void *saddr, unsigned len);
static int arcnet_rebuild_header(struct sk_buff *skb);
-static struct net_device_stats *arcnet_get_stats(struct net_device *dev);
static int go_tx(struct net_device *dev);
static int debug = ARCNET_DEBUG;
@@ -322,11 +321,18 @@ static const struct header_ops arcnet_header_ops = {
.rebuild = arcnet_rebuild_header,
};
+static const struct net_device_ops arcnet_netdev_ops = {
+ .ndo_open = arcnet_open,
+ .ndo_stop = arcnet_close,
+ .ndo_start_xmit = arcnet_send_packet,
+ .ndo_tx_timeout = arcnet_timeout,
+};
/* Setup a struct device for ARCnet. */
static void arcdev_setup(struct net_device *dev)
{
dev->type = ARPHRD_ARCNET;
+ dev->netdev_ops = &arcnet_netdev_ops;
dev->header_ops = &arcnet_header_ops;
dev->hard_header_len = sizeof(struct archdr);
dev->mtu = choose_mtu();
@@ -339,18 +345,9 @@ static void arcdev_setup(struct net_device *dev)
/* New-style flags. */
dev->flags = IFF_BROADCAST;
- /*
- * Put in this stuff here, so we don't have to export the symbols to
- * the chipset drivers.
- */
- dev->open = arcnet_open;
- dev->stop = arcnet_close;
- dev->hard_start_xmit = arcnet_send_packet;
- dev->tx_timeout = arcnet_timeout;
- dev->get_stats = arcnet_get_stats;
}
-struct net_device *alloc_arcdev(char *name)
+struct net_device *alloc_arcdev(const char *name)
{
struct net_device *dev;
@@ -372,7 +369,7 @@ struct net_device *alloc_arcdev(char *name)
* that "should" only need to be set once at boot, so that there is
* non-reboot way to recover if something goes wrong.
*/
-static int arcnet_open(struct net_device *dev)
+int arcnet_open(struct net_device *dev)
{
struct arcnet_local *lp = netdev_priv(dev);
int count, newmtu, error;
@@ -383,7 +380,6 @@ static int arcnet_open(struct net_device *dev)
return -ENODEV;
BUGLVL(D_PROTO) {
- int count;
BUGMSG(D_PROTO, "protocol map (default is '%c'): ",
arc_proto_default->suffix);
for (count = 0; count < 256; count++)
@@ -472,7 +468,7 @@ static int arcnet_open(struct net_device *dev)
/* The inverse routine to arcnet_open - shuts down the card. */
-static int arcnet_close(struct net_device *dev)
+int arcnet_close(struct net_device *dev)
{
struct arcnet_local *lp = netdev_priv(dev);
@@ -583,8 +579,8 @@ static int arcnet_rebuild_header(struct sk_buff *skb)
} else {
BUGMSG(D_NORMAL,
"I don't understand ethernet protocol %Xh addresses!\n", type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
}
/* if we couldn't resolve the address... give up. */
@@ -601,7 +597,7 @@ static int arcnet_rebuild_header(struct sk_buff *skb)
/* Called by the kernel in order to transmit a packet. */
-static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
+int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
{
struct arcnet_local *lp = netdev_priv(dev);
struct archdr *pkt;
@@ -645,7 +641,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
!proto->ack_tx) {
/* done right away and we don't want to acknowledge
the package later - forget about it now */
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
freeskb = 1;
} else {
/* do it the 'split' way */
@@ -709,7 +705,7 @@ static int go_tx(struct net_device *dev)
/* start sending */
ACOMMAND(TXcmd | (lp->cur_tx << 3));
- lp->stats.tx_packets++;
+ dev->stats.tx_packets++;
lp->lasttrans_dest = lp->lastload_dest;
lp->lastload_dest = 0;
lp->excnak_pending = 0;
@@ -720,7 +716,7 @@ static int go_tx(struct net_device *dev)
/* Called by the kernel when transmit times out */
-static void arcnet_timeout(struct net_device *dev)
+void arcnet_timeout(struct net_device *dev)
{
unsigned long flags;
struct arcnet_local *lp = netdev_priv(dev);
@@ -732,11 +728,11 @@ static void arcnet_timeout(struct net_device *dev)
msg = " - missed IRQ?";
} else {
msg = "";
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
lp->timed_out = 1;
ACOMMAND(NOTXcmd | (lp->cur_tx << 3));
}
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* make sure we didn't miss a TX or a EXC NAK IRQ */
AINTMASK(0);
@@ -865,8 +861,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
"transmit was not acknowledged! "
"(status=%Xh, dest=%02Xh)\n",
status, lp->lasttrans_dest);
- lp->stats.tx_errors++;
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
} else {
BUGMSG(D_DURING,
"broadcast was not acknowledged; that's normal "
@@ -905,7 +901,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
if (txbuf != -1) {
if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
/* that was the last segment */
- lp->stats.tx_bytes += lp->outgoing.skb->len;
+ dev->stats.tx_bytes += lp->outgoing.skb->len;
if(!lp->outgoing.proto->ack_tx)
{
dev_kfree_skb_irq(lp->outgoing.skb);
@@ -930,7 +926,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
}
if (status & lp->intmask & RECONflag) {
ACOMMAND(CFLAGScmd | CONFIGclear);
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
status);
@@ -1038,8 +1034,8 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
"(%d+4 bytes)\n",
bufnum, pkt.hard.source, pkt.hard.dest, length);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += length + ARC_HDR_SIZE;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length + ARC_HDR_SIZE;
/* call the right receiver for the protocol */
if (arc_proto_map[soft->proto]->is_ip) {
@@ -1067,18 +1063,6 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
}
-
-/*
- * Get the current statistics. This may be called with the card open or
- * closed.
- */
-static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
-{
- struct arcnet_local *lp = netdev_priv(dev);
- return &lp->stats;
-}
-
-
static void null_rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index 30580bbe252..083e21094b2 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -119,7 +119,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
@@ -148,7 +148,7 @@ static void rx(struct net_device *dev, int bufnum,
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
- skb->protocol = __constant_htons(ETH_P_ARCNET);
+ skb->protocol = cpu_to_be16(ETH_P_ARCNET);
;
netif_rx(skb);
}
@@ -282,7 +282,7 @@ static int ack_tx(struct net_device *dev, int acked)
BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
*((int*)&ackpkt->soft.cap.cookie[0]));
- ackskb->protocol = __constant_htons(ETH_P_ARCNET);
+ ackskb->protocol = cpu_to_be16(ETH_P_ARCNET);
BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
netif_rx(ackskb);
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index ea53a940272..db08fc24047 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -151,6 +151,8 @@ static int __init com20020_init(void)
if (node && node != 0xff)
dev->dev_addr[0] = node;
+ dev->netdev_ops = &com20020_netdev_ops;
+
lp = netdev_priv(dev);
lp->backplane = backplane;
lp->clockp = clockp & 7;
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index 8b51f632581..dbf4de39754 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -72,6 +72,9 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
dev = alloc_arcdev(device);
if (!dev)
return -ENOMEM;
+
+ dev->netdev_ops = &com20020_netdev_ops;
+
lp = netdev_priv(dev);
pci_set_drvdata(pdev, dev);
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 103688358fb..651275a5f3d 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -149,6 +149,14 @@ int com20020_check(struct net_device *dev)
return 0;
}
+const struct net_device_ops com20020_netdev_ops = {
+ .ndo_open = arcnet_open,
+ .ndo_stop = arcnet_close,
+ .ndo_start_xmit = arcnet_send_packet,
+ .ndo_tx_timeout = arcnet_timeout,
+ .ndo_set_multicast_list = com20020_set_mc_list,
+};
+
/* Set up the struct net_device associated with this card. Called after
* probing succeeds.
*/
@@ -170,8 +178,6 @@ int com20020_found(struct net_device *dev, int shared)
lp->hw.copy_from_card = com20020_copy_from_card;
lp->hw.close = com20020_close;
- dev->set_multicast_list = com20020_set_mc_list;
-
if (!dev->dev_addr[0])
dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8); /* FIXME: do this some other way! */
@@ -342,6 +348,7 @@ static void com20020_set_mc_list(struct net_device *dev)
defined(CONFIG_ARCNET_COM20020_CS_MODULE)
EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found);
+EXPORT_SYMBOL(com20020_netdev_ops);
#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c
index 49d39a9cb69..06f8fa2f8f2 100644
--- a/drivers/net/arcnet/rfc1051.c
+++ b/drivers/net/arcnet/rfc1051.c
@@ -88,7 +88,6 @@ MODULE_LICENSE("GPL");
*/
static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
{
- struct arcnet_local *lp = netdev_priv(dev);
struct archdr *pkt = (struct archdr *) skb->data;
struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
@@ -112,8 +111,8 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
return htons(ETH_P_ARP);
default:
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
return 0;
}
@@ -140,7 +139,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -168,7 +167,6 @@ static void rx(struct net_device *dev, int bufnum,
static int build_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, uint8_t daddr)
{
- struct arcnet_local *lp = netdev_priv(dev);
int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
@@ -184,8 +182,8 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
default:
BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n",
type, type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
return 0;
}
diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c
index 2303d3a1f4b..745530651c4 100644
--- a/drivers/net/arcnet/rfc1201.c
+++ b/drivers/net/arcnet/rfc1201.c
@@ -92,7 +92,6 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct archdr *pkt = (struct archdr *) skb->data;
struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
- struct arcnet_local *lp = netdev_priv(dev);
int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
/* Pull off the arcnet header. */
@@ -121,8 +120,8 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
case ARC_P_NOVELL_EC:
return htons(ETH_P_802_3);
default:
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
return 0;
}
@@ -172,8 +171,8 @@ static void rx(struct net_device *dev, int bufnum,
in->sequence, soft->split_flag, soft->sequence);
lp->rfc1201.aborted_seq = soft->sequence;
dev_kfree_skb_irq(in->skb);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->skb = NULL;
}
in->sequence = soft->sequence;
@@ -181,7 +180,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -213,7 +212,7 @@ static void rx(struct net_device *dev, int bufnum,
BUGMSG(D_EXTRA,
"ARP source address was 00h, set to %02Xh.\n",
saddr);
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
*cptr = saddr;
} else {
BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
@@ -222,8 +221,8 @@ static void rx(struct net_device *dev, int bufnum,
} else {
BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
arp->ar_hln, arp->ar_pln);
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
}
}
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
@@ -257,8 +256,8 @@ static void rx(struct net_device *dev, int bufnum,
soft->split_flag);
dev_kfree_skb_irq(in->skb);
in->skb = NULL;
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->lastpacket = in->numpackets = 0;
}
if (soft->split_flag & 1) { /* first packet in split */
@@ -269,8 +268,8 @@ static void rx(struct net_device *dev, int bufnum,
"(splitflag=%d, seq=%d)\n",
in->sequence, soft->split_flag,
soft->sequence);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
dev_kfree_skb_irq(in->skb);
}
in->sequence = soft->sequence;
@@ -281,8 +280,8 @@ static void rx(struct net_device *dev, int bufnum,
BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
soft->split_flag);
lp->rfc1201.aborted_seq = soft->sequence;
- lp->stats.rx_errors++;
- lp->stats.rx_length_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_length_errors++;
return;
}
in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
@@ -290,7 +289,7 @@ static void rx(struct net_device *dev, int bufnum,
if (skb == NULL) {
BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
lp->rfc1201.aborted_seq = soft->sequence;
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb->dev = dev;
@@ -314,8 +313,8 @@ static void rx(struct net_device *dev, int bufnum,
"first! (splitflag=%d, seq=%d, aborted=%d)\n",
soft->split_flag, soft->sequence,
lp->rfc1201.aborted_seq);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
}
return;
}
@@ -325,8 +324,8 @@ static void rx(struct net_device *dev, int bufnum,
if (packetnum <= in->lastpacket - 1) {
BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n",
soft->split_flag);
- lp->stats.rx_errors++;
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_frame_errors++;
return;
}
/* "bad" duplicate, kill reassembly */
@@ -336,8 +335,8 @@ static void rx(struct net_device *dev, int bufnum,
lp->rfc1201.aborted_seq = soft->sequence;
dev_kfree_skb_irq(in->skb);
in->skb = NULL;
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->lastpacket = in->numpackets = 0;
return;
}
@@ -404,8 +403,8 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
default:
BUGMSG(D_NORMAL, "RFC1201: I don't understand protocol %d (%Xh)\n",
type, type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
return 0;
}
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile
index c69c0cdba4a..811a3ccd14c 100644
--- a/drivers/net/arm/Makefile
+++ b/drivers/net/arm/Makefile
@@ -4,7 +4,7 @@
#
obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
-obj-$(CONFIG_ARM_ETHERH) += etherh.o ../8390.o
+obj-$(CONFIG_ARM_ETHERH) += etherh.o
obj-$(CONFIG_ARM_ETHER3) += ether3.o
obj-$(CONFIG_ARM_ETHER1) += ether1.o
obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 0c628a9e533..c2d012fcc29 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -208,9 +208,9 @@ am79c961_init_for_open(struct net_device *dev)
/*
* Stop the chip.
*/
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP);
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
write_ireg (dev->base_addr, 5, 0x00a0); /* Receive address LED */
write_ireg (dev->base_addr, 6, 0x0081); /* Collision LED */
@@ -332,10 +332,10 @@ am79c961_close(struct net_device *dev)
netif_stop_queue(dev);
netif_carrier_off(dev);
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_STOP);
write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
free_irq (dev->irq, dev);
@@ -391,7 +391,7 @@ static void am79c961_setmulticastlist (struct net_device *dev)
am79c961_mc_hash(dmi, multi_hash);
}
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
@@ -405,9 +405,9 @@ static void am79c961_setmulticastlist (struct net_device *dev)
* Spin waiting for chip to report suspend mode
*/
while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) {
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
nop();
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
}
}
@@ -429,7 +429,7 @@ static void am79c961_setmulticastlist (struct net_device *dev)
write_rreg(dev->base_addr, CTRL1, 0);
}
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
}
static void am79c961_timeout(struct net_device *dev)
@@ -467,10 +467,10 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
priv->txhead = head;
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
dev->trans_start = jiffies;
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
/*
* If the next packet is owned by the ethernet device,
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 3ec20cc18b0..cc7708775da 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -298,7 +298,7 @@ poll_some_more:
int more = 0;
spin_lock_irq(&ep->rx_lock);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
wrl(ep, REG_INTEN, REG_INTEN_TX | REG_INTEN_RX);
if (ep93xx_have_more_rx(ep)) {
wrl(ep, REG_INTEN, REG_INTEN_TX);
@@ -307,7 +307,7 @@ poll_some_more:
}
spin_unlock_irq(&ep->rx_lock);
- if (more && netif_rx_reschedule(napi))
+ if (more && napi_reschedule(napi))
goto poll_some_more;
}
@@ -415,9 +415,9 @@ static irqreturn_t ep93xx_irq(int irq, void *dev_id)
if (status & REG_INTSTS_RX) {
spin_lock(&ep->rx_lock);
- if (likely(netif_rx_schedule_prep(&ep->napi))) {
+ if (likely(napi_schedule_prep(&ep->napi))) {
wrl(ep, REG_INTEN, REG_INTEN_TX);
- __netif_rx_schedule(&ep->napi);
+ __napi_schedule(&ep->napi);
}
spin_unlock(&ep->rx_lock);
}
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index d15d8b79d8e..f52f668c49b 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -641,15 +641,15 @@ static const struct net_device_ops etherh_netdev_ops = {
.ndo_open = etherh_open,
.ndo_stop = etherh_close,
.ndo_set_config = etherh_set_config,
- .ndo_start_xmit = ei_start_xmit,
- .ndo_tx_timeout = ei_tx_timeout,
- .ndo_get_stats = ei_get_stats,
- .ndo_set_multicast_list = ei_set_multicast_list,
+ .ndo_start_xmit = __ei_start_xmit,
+ .ndo_tx_timeout = __ei_tx_timeout,
+ .ndo_get_stats = __ei_get_stats,
+ .ndo_set_multicast_list = __ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_set_mac_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = ei_poll,
+ .ndo_poll_controller = __ei_poll,
#endif
};
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index 5fce1d5c1a1..5fe17d5eaa5 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -473,7 +473,7 @@ static void eth_rx_irq(void *pdev)
printk(KERN_DEBUG "%s: eth_rx_irq\n", dev->name);
#endif
qmgr_disable_irq(port->plat->rxq);
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
}
static int eth_poll(struct napi_struct *napi, int budget)
@@ -498,16 +498,16 @@ static int eth_poll(struct napi_struct *napi, int budget)
if ((n = queue_get_desc(rxq, port, 0)) < 0) {
#if DEBUG_RX
- printk(KERN_DEBUG "%s: eth_poll netif_rx_complete\n",
+ printk(KERN_DEBUG "%s: eth_poll napi_complete\n",
dev->name);
#endif
- netif_rx_complete(napi);
+ napi_complete(napi);
qmgr_enable_irq(rxq);
if (!qmgr_stat_empty(rxq) &&
- netif_rx_reschedule(napi)) {
+ napi_reschedule(napi)) {
#if DEBUG_RX
printk(KERN_DEBUG "%s: eth_poll"
- " netif_rx_reschedule successed\n",
+ " napi_reschedule successed\n",
dev->name);
#endif
qmgr_disable_irq(rxq);
@@ -1036,7 +1036,7 @@ static int eth_open(struct net_device *dev)
}
ports_open++;
/* we may already have RX data, enables IRQ */
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
return 0;
}
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 1cf2f949c0b..35cd264abae 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -560,7 +560,7 @@ ks8695_reset(struct ks8695_priv *ksp)
msleep(1);
}
- if (reset_timeout == 0) {
+ if (reset_timeout < 0) {
dev_crit(ksp->dev,
"Timeout waiting for DMA engines to reset\n");
/* And blithely carry on */
@@ -1059,7 +1059,7 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
{
strlcpy(info->driver, MODULENAME, sizeof(info->driver));
strlcpy(info->version, MODULEVERSION, sizeof(info->version));
- strlcpy(info->bus_info, ndev->dev.parent->bus_id,
+ strlcpy(info->bus_info, dev_name(ndev->dev.parent),
sizeof(info->bus_info));
}
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 72ea6e378f8..ced70799b89 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -828,7 +828,6 @@ set_rx_mode(struct net_device *dev)
struct net_local *lp = netdev_priv(dev);
unsigned char mc_filter[8]; /* Multicast hash filter */
unsigned long flags;
- int i;
if (dev->flags & IFF_PROMISC) {
memset(mc_filter, 0xff, sizeof(mc_filter));
@@ -857,6 +856,7 @@ set_rx_mode(struct net_device *dev)
spin_lock_irqsave (&lp->lock, flags);
if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
+ int i;
int saved_bank = inw(ioaddr + CONFIG_0);
/* Switch to bank 1 and set the multicast table. */
outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
diff --git a/drivers/net/atl1c/Makefile b/drivers/net/atl1c/Makefile
new file mode 100644
index 00000000000..c37d966952e
--- /dev/null
+++ b/drivers/net/atl1c/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ATL1C) += atl1c.o
+atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
new file mode 100644
index 00000000000..e1658ef3fcd
--- /dev/null
+++ b/drivers/net/atl1c/atl1c.h
@@ -0,0 +1,605 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ATL1C_H_
+#define _ATL1C_H_
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/mii.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/tcp.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/workqueue.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+
+#include "atl1c_hw.h"
+
+/* Wake Up Filter Control */
+#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define AT_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
+#define AT_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
+#define AT_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
+#define AT_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
+
+#define AT_VLAN_TO_TAG(_vlan, _tag) \
+ _tag = ((((_vlan) >> 8) & 0xFF) |\
+ (((_vlan) & 0xFF) << 8))
+
+#define AT_TAG_TO_VLAN(_tag, _vlan) \
+ _vlan = ((((_tag) >> 8) & 0xFF) |\
+ (((_tag) & 0xFF) << 8))
+
+#define SPEED_0 0xffff
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+#define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)
+#define MAX_JUMBO_FRAME_SIZE (9*1024)
+#define MAX_TX_OFFLOAD_THRESH (9*1024)
+
+#define AT_MAX_RECEIVE_QUEUE 4
+#define AT_DEF_RECEIVE_QUEUE 1
+#define AT_MAX_TRANSMIT_QUEUE 2
+
+#define AT_DMA_HI_ADDR_MASK 0xffffffff00000000ULL
+#define AT_DMA_LO_ADDR_MASK 0x00000000ffffffffULL
+
+#define AT_TX_WATCHDOG (5 * HZ)
+#define AT_MAX_INT_WORK 5
+#define AT_TWSI_EEPROM_TIMEOUT 100
+#define AT_HW_MAX_IDLE_DELAY 10
+#define AT_SUSPEND_LINK_TIMEOUT 28
+
+#define AT_ASPM_L0S_TIMER 6
+#define AT_ASPM_L1_TIMER 12
+
+#define ATL1C_PCIE_L0S_L1_DISABLE 0x01
+#define ATL1C_PCIE_PHY_RESET 0x02
+
+#define ATL1C_ASPM_L0s_ENABLE 0x0001
+#define ATL1C_ASPM_L1_ENABLE 0x0002
+
+#define AT_REGS_LEN (75 * sizeof(u32))
+#define AT_EEPROM_LEN 512
+
+#define ATL1C_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
+#define ATL1C_RFD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc)
+#define ATL1C_TPD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc)
+#define ATL1C_RRD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status)
+
+/* tpd word 1 bit 0:7 General Checksum task offload */
+#define TPD_L4HDR_OFFSET_MASK 0x00FF
+#define TPD_L4HDR_OFFSET_SHIFT 0
+
+/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */
+#define TPD_TCPHDR_OFFSET_MASK 0x00FF
+#define TPD_TCPHDR_OFFSET_SHIFT 0
+
+/* tpd word 1 bit 0:7 Custom Checksum task offload */
+#define TPD_PLOADOFFSET_MASK 0x00FF
+#define TPD_PLOADOFFSET_SHIFT 0
+
+/* tpd word 1 bit 8:17 */
+#define TPD_CCSUM_EN_MASK 0x0001
+#define TPD_CCSUM_EN_SHIFT 8
+#define TPD_IP_CSUM_MASK 0x0001
+#define TPD_IP_CSUM_SHIFT 9
+#define TPD_TCP_CSUM_MASK 0x0001
+#define TPD_TCP_CSUM_SHIFT 10
+#define TPD_UDP_CSUM_MASK 0x0001
+#define TPD_UDP_CSUM_SHIFT 11
+#define TPD_LSO_EN_MASK 0x0001 /* TCP Large Send Offload */
+#define TPD_LSO_EN_SHIFT 12
+#define TPD_LSO_VER_MASK 0x0001
+#define TPD_LSO_VER_SHIFT 13 /* 0 : ipv4; 1 : ipv4/ipv6 */
+#define TPD_CON_VTAG_MASK 0x0001
+#define TPD_CON_VTAG_SHIFT 14
+#define TPD_INS_VTAG_MASK 0x0001
+#define TPD_INS_VTAG_SHIFT 15
+#define TPD_IPV4_PACKET_MASK 0x0001 /* valid when LSO VER is 1 */
+#define TPD_IPV4_PACKET_SHIFT 16
+#define TPD_ETH_TYPE_MASK 0x0001
+#define TPD_ETH_TYPE_SHIFT 17 /* 0 : 802.3 frame; 1 : Ethernet */
+
+/* tpd word 18:25 Custom Checksum task offload */
+#define TPD_CCSUM_OFFSET_MASK 0x00FF
+#define TPD_CCSUM_OFFSET_SHIFT 18
+#define TPD_CCSUM_EPAD_MASK 0x0001
+#define TPD_CCSUM_EPAD_SHIFT 30
+
+/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */
+#define TPD_MSS_MASK 0x1FFF
+#define TPD_MSS_SHIFT 18
+
+#define TPD_EOP_MASK 0x0001
+#define TPD_EOP_SHIFT 31
+
+struct atl1c_tpd_desc {
+ __le16 buffer_len; /* include 4-byte CRC */
+ __le16 vlan_tag;
+ __le32 word1;
+ __le64 buffer_addr;
+};
+
+struct atl1c_tpd_ext_desc {
+ u32 reservd_0;
+ __le32 word1;
+ __le32 pkt_len;
+ u32 reservd_1;
+};
+/* rrs word 0 bit 0:31 */
+#define RRS_RX_CSUM_MASK 0xFFFF
+#define RRS_RX_CSUM_SHIFT 0
+#define RRS_RX_RFD_CNT_MASK 0x000F
+#define RRS_RX_RFD_CNT_SHIFT 16
+#define RRS_RX_RFD_INDEX_MASK 0x0FFF
+#define RRS_RX_RFD_INDEX_SHIFT 20
+
+/* rrs flag bit 0:16 */
+#define RRS_HEAD_LEN_MASK 0x00FF
+#define RRS_HEAD_LEN_SHIFT 0
+#define RRS_HDS_TYPE_MASK 0x0003
+#define RRS_HDS_TYPE_SHIFT 8
+#define RRS_CPU_NUM_MASK 0x0003
+#define RRS_CPU_NUM_SHIFT 10
+#define RRS_HASH_FLG_MASK 0x000F
+#define RRS_HASH_FLG_SHIFT 12
+
+#define RRS_HDS_TYPE_HEAD 1
+#define RRS_HDS_TYPE_DATA 2
+
+#define RRS_IS_NO_HDS_TYPE(flag) \
+ (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == 0)
+
+#define RRS_IS_HDS_HEAD(flag) \
+ (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \
+ RRS_HDS_TYPE_HEAD)
+
+#define RRS_IS_HDS_DATA(flag) \
+ (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \
+ RRS_HDS_TYPE_DATA)
+
+/* rrs word 3 bit 0:31 */
+#define RRS_PKT_SIZE_MASK 0x3FFF
+#define RRS_PKT_SIZE_SHIFT 0
+#define RRS_ERR_L4_CSUM_MASK 0x0001
+#define RRS_ERR_L4_CSUM_SHIFT 14
+#define RRS_ERR_IP_CSUM_MASK 0x0001
+#define RRS_ERR_IP_CSUM_SHIFT 15
+#define RRS_VLAN_INS_MASK 0x0001
+#define RRS_VLAN_INS_SHIFT 16
+#define RRS_PROT_ID_MASK 0x0007
+#define RRS_PROT_ID_SHIFT 17
+#define RRS_RX_ERR_SUM_MASK 0x0001
+#define RRS_RX_ERR_SUM_SHIFT 20
+#define RRS_RX_ERR_CRC_MASK 0x0001
+#define RRS_RX_ERR_CRC_SHIFT 21
+#define RRS_RX_ERR_FAE_MASK 0x0001
+#define RRS_RX_ERR_FAE_SHIFT 22
+#define RRS_RX_ERR_TRUNC_MASK 0x0001
+#define RRS_RX_ERR_TRUNC_SHIFT 23
+#define RRS_RX_ERR_RUNC_MASK 0x0001
+#define RRS_RX_ERR_RUNC_SHIFT 24
+#define RRS_RX_ERR_ICMP_MASK 0x0001
+#define RRS_RX_ERR_ICMP_SHIFT 25
+#define RRS_PACKET_BCAST_MASK 0x0001
+#define RRS_PACKET_BCAST_SHIFT 26
+#define RRS_PACKET_MCAST_MASK 0x0001
+#define RRS_PACKET_MCAST_SHIFT 27
+#define RRS_PACKET_TYPE_MASK 0x0001
+#define RRS_PACKET_TYPE_SHIFT 28
+#define RRS_FIFO_FULL_MASK 0x0001
+#define RRS_FIFO_FULL_SHIFT 29
+#define RRS_802_3_LEN_ERR_MASK 0x0001
+#define RRS_802_3_LEN_ERR_SHIFT 30
+#define RRS_RXD_UPDATED_MASK 0x0001
+#define RRS_RXD_UPDATED_SHIFT 31
+
+#define RRS_ERR_L4_CSUM 0x00004000
+#define RRS_ERR_IP_CSUM 0x00008000
+#define RRS_VLAN_INS 0x00010000
+#define RRS_RX_ERR_SUM 0x00100000
+#define RRS_RX_ERR_CRC 0x00200000
+#define RRS_802_3_LEN_ERR 0x40000000
+#define RRS_RXD_UPDATED 0x80000000
+
+#define RRS_PACKET_TYPE_802_3 1
+#define RRS_PACKET_TYPE_ETH 0
+#define RRS_PACKET_IS_ETH(word) \
+ (((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK == \
+ RRS_PACKET_TYPE_ETH)
+#define RRS_RXD_IS_VALID(word) \
+ ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
+
+#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \
+ ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1)
+#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \
+ ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6)
+
+struct atl1c_recv_ret_status {
+ __le32 word0;
+ __le32 rss_hash;
+ __le16 vlan_tag;
+ __le16 flag;
+ __le32 word3;
+};
+
+/* RFD desciptor */
+struct atl1c_rx_free_desc {
+ __le64 buffer_addr;
+};
+
+/* DMA Order Settings */
+enum atl1c_dma_order {
+ atl1c_dma_ord_in = 1,
+ atl1c_dma_ord_enh = 2,
+ atl1c_dma_ord_out = 4
+};
+
+enum atl1c_dma_rcb {
+ atl1c_rcb_64 = 0,
+ atl1c_rcb_128 = 1
+};
+
+enum atl1c_mac_speed {
+ atl1c_mac_speed_0 = 0,
+ atl1c_mac_speed_10_100 = 1,
+ atl1c_mac_speed_1000 = 2
+};
+
+enum atl1c_dma_req_block {
+ atl1c_dma_req_128 = 0,
+ atl1c_dma_req_256 = 1,
+ atl1c_dma_req_512 = 2,
+ atl1c_dma_req_1024 = 3,
+ atl1c_dma_req_2048 = 4,
+ atl1c_dma_req_4096 = 5
+};
+
+enum atl1c_rss_mode {
+ atl1c_rss_mode_disable = 0,
+ atl1c_rss_sig_que = 1,
+ atl1c_rss_mul_que_sig_int = 2,
+ atl1c_rss_mul_que_mul_int = 4,
+};
+
+enum atl1c_rss_type {
+ atl1c_rss_disable = 0,
+ atl1c_rss_ipv4 = 1,
+ atl1c_rss_ipv4_tcp = 2,
+ atl1c_rss_ipv6 = 4,
+ atl1c_rss_ipv6_tcp = 8
+};
+
+enum atl1c_nic_type {
+ athr_l1c = 0,
+ athr_l2c = 1,
+};
+
+enum atl1c_trans_queue {
+ atl1c_trans_normal = 0,
+ atl1c_trans_high = 1
+};
+
+struct atl1c_hw_stats {
+ /* rx */
+ unsigned long rx_ok; /* The number of good packet received. */
+ unsigned long rx_bcast; /* The number of good broadcast packet received. */
+ unsigned long rx_mcast; /* The number of good multicast packet received. */
+ unsigned long rx_pause; /* The number of Pause packet received. */
+ unsigned long rx_ctrl; /* The number of Control packet received other than Pause frame. */
+ unsigned long rx_fcs_err; /* The number of packets with bad FCS. */
+ unsigned long rx_len_err; /* The number of packets with mismatch of length field and actual size. */
+ unsigned long rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */
+ unsigned long rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */
+ unsigned long rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */
+ unsigned long rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */
+ unsigned long rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */
+ unsigned long rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */
+ unsigned long rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */
+ unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
+ unsigned long rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
+ unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
+ unsigned long rx_sz_ov; /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
+ unsigned long rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */
+ unsigned long rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */
+ unsigned long rx_align_err; /* Alignment Error */
+ unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
+ unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
+ unsigned long rx_err_addr; /* The number of packets dropped due to address filtering. */
+
+ /* tx */
+ unsigned long tx_ok; /* The number of good packet transmitted. */
+ unsigned long tx_bcast; /* The number of good broadcast packet transmitted. */
+ unsigned long tx_mcast; /* The number of good multicast packet transmitted. */
+ unsigned long tx_pause; /* The number of Pause packet transmitted. */
+ unsigned long tx_exc_defer; /* The number of packets transmitted with excessive deferral. */
+ unsigned long tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */
+ unsigned long tx_defer; /* The number of packets transmitted that is deferred. */
+ unsigned long tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */
+ unsigned long tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */
+ unsigned long tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
+ unsigned long tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
+ unsigned long tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
+ unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
+ unsigned long tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
+ unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
+ unsigned long tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */
+ unsigned long tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
+ unsigned long tx_late_col; /* The number of packets transmitted with late collisions. */
+ unsigned long tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */
+ unsigned long tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
+ unsigned long tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
+ unsigned long tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */
+ unsigned long tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */
+ unsigned long tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */
+ unsigned long tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */
+};
+
+struct atl1c_hw {
+ u8 __iomem *hw_addr; /* inner register address */
+ struct atl1c_adapter *adapter;
+ enum atl1c_nic_type nic_type;
+ enum atl1c_dma_order dma_order;
+ enum atl1c_dma_rcb rcb_value;
+ enum atl1c_dma_req_block dmar_block;
+ enum atl1c_dma_req_block dmaw_block;
+
+ u16 device_id;
+ u16 vendor_id;
+ u16 subsystem_id;
+ u16 subsystem_vendor_id;
+ u8 revision_id;
+
+ u32 intr_mask;
+ u8 dmaw_dly_cnt;
+ u8 dmar_dly_cnt;
+
+ u8 preamble_len;
+ u16 max_frame_size;
+ u16 min_frame_size;
+
+ enum atl1c_mac_speed mac_speed;
+ bool mac_duplex;
+ bool hibernate;
+ u16 media_type;
+#define MEDIA_TYPE_AUTO_SENSOR 0
+#define MEDIA_TYPE_100M_FULL 1
+#define MEDIA_TYPE_100M_HALF 2
+#define MEDIA_TYPE_10M_FULL 3
+#define MEDIA_TYPE_10M_HALF 4
+
+ u16 autoneg_advertised;
+ u16 mii_autoneg_adv_reg;
+ u16 mii_1000t_ctrl_reg;
+
+ u16 tx_imt; /* TX Interrupt Moderator timer ( 2us resolution) */
+ u16 rx_imt; /* RX Interrupt Moderator timer ( 2us resolution) */
+ u16 ict; /* Interrupt Clear timer (2us resolution) */
+ u16 ctrl_flags;
+#define ATL1C_INTR_CLEAR_ON_READ 0x0001
+#define ATL1C_INTR_MODRT_ENABLE 0x0002
+#define ATL1C_CMB_ENABLE 0x0004
+#define ATL1C_SMB_ENABLE 0x0010
+#define ATL1C_TXQ_MODE_ENHANCE 0x0020
+#define ATL1C_RX_IPV6_CHKSUM 0x0040
+#define ATL1C_ASPM_L0S_SUPPORT 0x0080
+#define ATL1C_ASPM_L1_SUPPORT 0x0100
+#define ATL1C_ASPM_CTRL_MON 0x0200
+#define ATL1C_HIB_DISABLE 0x0400
+#define ATL1C_LINK_CAP_1000M 0x0800
+#define ATL1C_FPGA_VERSION 0x8000
+ u16 cmb_tpd;
+ u16 cmb_rrd;
+ u16 cmb_rx_timer; /* 2us resolution */
+ u16 cmb_tx_timer;
+ u32 smb_timer;
+
+ u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
+ interrupt request */
+ u16 tpd_thresh;
+ u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. */
+ u8 rfd_burst;
+ enum atl1c_rss_type rss_type;
+ enum atl1c_rss_mode rss_mode;
+ u8 rss_hash_bits;
+ u32 base_cpu;
+ u32 indirect_tab;
+ u8 mac_addr[ETH_ALEN];
+ u8 perm_mac_addr[ETH_ALEN];
+
+ bool phy_configured;
+ bool re_autoneg;
+ bool emi_ca;
+};
+
+/*
+ * atl1c_ring_header represents a single, contiguous block of DMA space
+ * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
+ * message blocks (cmb, smb) described below
+ */
+struct atl1c_ring_header {
+ void *desc; /* virtual address */
+ dma_addr_t dma; /* physical address*/
+ unsigned int size; /* length in bytes */
+};
+
+/*
+ * atl1c_buffer is wrapper around a pointer to a socket buffer
+ * so a DMA handle can be stored along with the skb
+ */
+struct atl1c_buffer {
+ struct sk_buff *skb; /* socket buffer */
+ u16 length; /* rx buffer length */
+ u16 state; /* state of buffer */
+#define ATL1_BUFFER_FREE 0
+#define ATL1_BUFFER_BUSY 1
+ dma_addr_t dma;
+};
+
+/* transimit packet descriptor (tpd) ring */
+struct atl1c_tpd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use; /* this is protectd by adapter->tx_lock */
+ atomic_t next_to_clean;
+ struct atl1c_buffer *buffer_info;
+};
+
+/* receive free descriptor (rfd) ring */
+struct atl1c_rfd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use;
+ u16 next_to_clean;
+ struct atl1c_buffer *buffer_info;
+};
+
+/* receive return desciptor (rrd) ring */
+struct atl1c_rrd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use;
+ u16 next_to_clean;
+};
+
+struct atl1c_cmb {
+ void *cmb;
+ dma_addr_t dma;
+};
+
+struct atl1c_smb {
+ void *smb;
+ dma_addr_t dma;
+};
+
+/* board specific private data structure */
+struct atl1c_adapter {
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+ struct vlan_group *vlgrp;
+ struct napi_struct napi;
+ struct atl1c_hw hw;
+ struct atl1c_hw_stats hw_stats;
+ struct net_device_stats net_stats;
+ struct mii_if_info mii; /* MII interface info */
+ u16 rx_buffer_len;
+
+ unsigned long flags;
+#define __AT_TESTING 0x0001
+#define __AT_RESETTING 0x0002
+#define __AT_DOWN 0x0003
+ u32 msg_enable;
+
+ bool have_msi;
+ u32 wol;
+ u16 link_speed;
+ u16 link_duplex;
+
+ spinlock_t mdio_lock;
+ spinlock_t tx_lock;
+ atomic_t irq_sem;
+
+ struct work_struct reset_task;
+ struct work_struct link_chg_task;
+ struct timer_list watchdog_timer;
+ struct timer_list phy_config_timer;
+
+ /* All Descriptor memory */
+ struct atl1c_ring_header ring_header;
+ struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE];
+ struct atl1c_rfd_ring rfd_ring[AT_MAX_RECEIVE_QUEUE];
+ struct atl1c_rrd_ring rrd_ring[AT_MAX_RECEIVE_QUEUE];
+ struct atl1c_cmb cmb;
+ struct atl1c_smb smb;
+ int num_rx_queues;
+ u32 bd_number; /* board number;*/
+};
+
+#define AT_WRITE_REG(a, reg, value) ( \
+ writel((value), ((a)->hw_addr + reg)))
+
+#define AT_WRITE_FLUSH(a) (\
+ readl((a)->hw_addr))
+
+#define AT_READ_REG(a, reg, pdata) do { \
+ if (unlikely((a)->hibernate)) { \
+ readl((a)->hw_addr + reg); \
+ *(u32 *)pdata = readl((a)->hw_addr + reg); \
+ } else { \
+ *(u32 *)pdata = readl((a)->hw_addr + reg); \
+ } \
+ } while (0)
+
+#define AT_WRITE_REGB(a, reg, value) (\
+ writeb((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGB(a, reg) (\
+ readb((a)->hw_addr + reg))
+
+#define AT_WRITE_REGW(a, reg, value) (\
+ writew((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGW(a, reg) (\
+ readw((a)->hw_addr + reg))
+
+#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+ writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
+
+#define AT_READ_REG_ARRAY(a, reg, offset) ( \
+ readl(((a)->hw_addr + reg) + ((offset) << 2)))
+
+extern char atl1c_driver_name[];
+extern char atl1c_driver_version[];
+
+extern int atl1c_up(struct atl1c_adapter *adapter);
+extern void atl1c_down(struct atl1c_adapter *adapter);
+extern void atl1c_reinit_locked(struct atl1c_adapter *adapter);
+extern s32 atl1c_reset_hw(struct atl1c_hw *hw);
+extern void atl1c_set_ethtool_ops(struct net_device *netdev);
+#endif /* _ATL1C_H_ */
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
new file mode 100644
index 00000000000..45c5b7332cd
--- /dev/null
+++ b/drivers/net/atl1c/atl1c_ethtool.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+
+#include "atl1c.h"
+
+static int atl1c_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+
+ ecmd->supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_TP);
+ if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M)
+ ecmd->supported |= SUPPORTED_1000baseT_Full;
+
+ ecmd->advertising = ADVERTISED_TP;
+
+ ecmd->advertising |= hw->autoneg_advertised;
+
+ ecmd->port = PORT_TP;
+ ecmd->phy_address = 0;
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ if (adapter->link_speed != SPEED_0) {
+ ecmd->speed = adapter->link_speed;
+ if (adapter->link_duplex == FULL_DUPLEX)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+ } else {
+ ecmd->speed = -1;
+ ecmd->duplex = -1;
+ }
+
+ ecmd->autoneg = AUTONEG_ENABLE;
+ return 0;
+}
+
+static int atl1c_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u16 autoneg_advertised;
+
+ while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+ msleep(1);
+
+ if (ecmd->autoneg == AUTONEG_ENABLE) {
+ autoneg_advertised = ADVERTISED_Autoneg;
+ } else {
+ if (ecmd->speed == SPEED_1000) {
+ if (ecmd->duplex != DUPLEX_FULL) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev,
+ "1000M half is invalid\n");
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return -EINVAL;
+ }
+ autoneg_advertised = ADVERTISED_1000baseT_Full;
+ } else if (ecmd->speed == SPEED_100) {
+ if (ecmd->duplex == DUPLEX_FULL)
+ autoneg_advertised = ADVERTISED_100baseT_Full;
+ else
+ autoneg_advertised = ADVERTISED_100baseT_Half;
+ } else {
+ if (ecmd->duplex == DUPLEX_FULL)
+ autoneg_advertised = ADVERTISED_10baseT_Full;
+ else
+ autoneg_advertised = ADVERTISED_10baseT_Half;
+ }
+ }
+
+ if (hw->autoneg_advertised != autoneg_advertised) {
+ hw->autoneg_advertised = autoneg_advertised;
+ if (atl1c_restart_autoneg(hw) != 0) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev,
+ "ethtool speed/duplex setting failed\n");
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return -EINVAL;
+ }
+ }
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return 0;
+}
+
+static u32 atl1c_get_tx_csum(struct net_device *netdev)
+{
+ return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+static u32 atl1c_get_msglevel(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ return adapter->msg_enable;
+}
+
+static void atl1c_set_msglevel(struct net_device *netdev, u32 data)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ adapter->msg_enable = data;
+}
+
+static int atl1c_get_regs_len(struct net_device *netdev)
+{
+ return AT_REGS_LEN;
+}
+
+static void atl1c_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 *regs_buff = p;
+ u16 phy_data;
+
+ memset(p, 0, AT_REGS_LEN);
+
+ regs->version = 0;
+ AT_READ_REG(hw, REG_VPD_CAP, p++);
+ AT_READ_REG(hw, REG_PM_CTRL, p++);
+ AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL, p++);
+ AT_READ_REG(hw, REG_TWSI_CTRL, p++);
+ AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL, p++);
+ AT_READ_REG(hw, REG_MASTER_CTRL, p++);
+ AT_READ_REG(hw, REG_MANUAL_TIMER_INIT, p++);
+ AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++);
+ AT_READ_REG(hw, REG_GPHY_CTRL, p++);
+ AT_READ_REG(hw, REG_LINK_CTRL, p++);
+ AT_READ_REG(hw, REG_IDLE_STATUS, p++);
+ AT_READ_REG(hw, REG_MDIO_CTRL, p++);
+ AT_READ_REG(hw, REG_SERDES_LOCK, p++);
+ AT_READ_REG(hw, REG_MAC_CTRL, p++);
+ AT_READ_REG(hw, REG_MAC_IPG_IFG, p++);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR, p++);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR+4, p++);
+ AT_READ_REG(hw, REG_RX_HASH_TABLE, p++);
+ AT_READ_REG(hw, REG_RX_HASH_TABLE+4, p++);
+ AT_READ_REG(hw, REG_RXQ_CTRL, p++);
+ AT_READ_REG(hw, REG_TXQ_CTRL, p++);
+ AT_READ_REG(hw, REG_MTU, p++);
+ AT_READ_REG(hw, REG_WOL_CTRL, p++);
+
+ atl1c_read_phy_reg(hw, MII_BMCR, &phy_data);
+ regs_buff[73] = (u32) phy_data;
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ regs_buff[74] = (u32) phy_data;
+}
+
+static int atl1c_get_eeprom_len(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (atl1c_check_eeprom_exist(&adapter->hw))
+ return AT_EEPROM_LEN;
+ else
+ return 0;
+}
+
+static int atl1c_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 *eeprom_buff;
+ int first_dword, last_dword;
+ int ret_val = 0;
+ int i;
+
+ if (eeprom->len == 0)
+ return -EINVAL;
+
+ if (!atl1c_check_eeprom_exist(hw)) /* not exist */
+ return -EINVAL;
+
+ eeprom->magic = adapter->pdev->vendor |
+ (adapter->pdev->device << 16);
+
+ first_dword = eeprom->offset >> 2;
+ last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+
+ eeprom_buff = kmalloc(sizeof(u32) *
+ (last_dword - first_dword + 1), GFP_KERNEL);
+ if (eeprom_buff == NULL)
+ return -ENOMEM;
+
+ for (i = first_dword; i < last_dword; i++) {
+ if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
+ kfree(eeprom_buff);
+ return -EIO;
+ }
+ }
+
+ memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
+ eeprom->len);
+ kfree(eeprom_buff);
+
+ return ret_val;
+ return 0;
+}
+
+static void atl1c_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ strncpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver));
+ strncpy(drvinfo->version, atl1c_driver_version,
+ sizeof(drvinfo->version));
+ strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+ strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ sizeof(drvinfo->bus_info));
+ drvinfo->n_stats = 0;
+ drvinfo->testinfo_len = 0;
+ drvinfo->regdump_len = atl1c_get_regs_len(netdev);
+ drvinfo->eedump_len = atl1c_get_eeprom_len(netdev);
+}
+
+static void atl1c_get_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_MAGIC | WAKE_PHY;
+ wol->wolopts = 0;
+
+ if (adapter->wol & AT_WUFC_EX)
+ wol->wolopts |= WAKE_UCAST;
+ if (adapter->wol & AT_WUFC_MC)
+ wol->wolopts |= WAKE_MCAST;
+ if (adapter->wol & AT_WUFC_BC)
+ wol->wolopts |= WAKE_BCAST;
+ if (adapter->wol & AT_WUFC_MAG)
+ wol->wolopts |= WAKE_MAGIC;
+ if (adapter->wol & AT_WUFC_LNKC)
+ wol->wolopts |= WAKE_PHY;
+
+ return;
+}
+
+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))
+ return -EOPNOTSUPP;
+ /* these settings will always override what we currently have */
+ adapter->wol = 0;
+
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= AT_WUFC_MAG;
+ if (wol->wolopts & WAKE_PHY)
+ adapter->wol |= AT_WUFC_LNKC;
+
+ return 0;
+}
+
+static int atl1c_nway_reset(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ if (netif_running(netdev))
+ atl1c_reinit_locked(adapter);
+ return 0;
+}
+
+static struct ethtool_ops atl1c_ethtool_ops = {
+ .get_settings = atl1c_get_settings,
+ .set_settings = atl1c_set_settings,
+ .get_drvinfo = atl1c_get_drvinfo,
+ .get_regs_len = atl1c_get_regs_len,
+ .get_regs = atl1c_get_regs,
+ .get_wol = atl1c_get_wol,
+ .set_wol = atl1c_set_wol,
+ .get_msglevel = atl1c_get_msglevel,
+ .set_msglevel = atl1c_set_msglevel,
+ .nway_reset = atl1c_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_eeprom_len = atl1c_get_eeprom_len,
+ .get_eeprom = atl1c_get_eeprom,
+ .get_tx_csum = atl1c_get_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+};
+
+void atl1c_set_ethtool_ops(struct net_device *netdev)
+{
+ SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops);
+}
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c
new file mode 100644
index 00000000000..3e69b940b8f
--- /dev/null
+++ b/drivers/net/atl1c/atl1c_hw.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+
+#include "atl1c.h"
+
+/*
+ * check_eeprom_exist
+ * return 1 if eeprom exist
+ */
+int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
+{
+ u32 data;
+
+ AT_READ_REG(hw, REG_TWSI_DEBUG, &data);
+ if (data & TWSI_DEBUG_DEV_EXIST)
+ return 1;
+
+ return 0;
+}
+
+void atl1c_hw_set_mac_addr(struct atl1c_hw *hw)
+{
+ u32 value;
+ /*
+ * 00-0B-6A-F6-00-DC
+ * 0: 6AF600DC 1: 000B
+ * low dword
+ */
+ value = (((u32)hw->mac_addr[2]) << 24) |
+ (((u32)hw->mac_addr[3]) << 16) |
+ (((u32)hw->mac_addr[4]) << 8) |
+ (((u32)hw->mac_addr[5])) ;
+ AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
+ /* hight dword */
+ value = (((u32)hw->mac_addr[0]) << 8) |
+ (((u32)hw->mac_addr[1])) ;
+ AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
+}
+
+/*
+ * atl1c_get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int atl1c_get_permanent_address(struct atl1c_hw *hw)
+{
+ u32 addr[2];
+ u32 i;
+ u32 otp_ctrl_data;
+ u32 twsi_ctrl_data;
+ u8 eth_addr[ETH_ALEN];
+
+ /* init */
+ addr[0] = addr[1] = 0;
+ AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
+ if (atl1c_check_eeprom_exist(hw)) {
+ /* Enable OTP CLK */
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
+ otp_ctrl_data |= OTP_CTRL_CLK_EN;
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(1);
+ }
+
+ AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
+ twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
+ AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
+ for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
+ msleep(10);
+ AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
+ if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
+ break;
+ }
+ if (i >= AT_TWSI_EEPROM_TIMEOUT)
+ return -1;
+ }
+ /* Disable OTP_CLK */
+ if (otp_ctrl_data & OTP_CTRL_CLK_EN) {
+ otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(1);
+ }
+
+ /* maybe MAC-address is from BIOS */
+ AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]);
+ *(u32 *) &eth_addr[2] = swab32(addr[0]);
+ *(u16 *) &eth_addr[0] = swab16(*(u16 *)&addr[1]);
+
+ if (is_valid_ether_addr(eth_addr)) {
+ memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
+ return 0;
+ }
+
+ return -1;
+}
+
+bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
+{
+ int i;
+ int ret = false;
+ u32 otp_ctrl_data;
+ u32 control;
+ u32 data;
+
+ if (offset & 3)
+ return ret; /* address do not align */
+
+ AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
+ AT_WRITE_REG(hw, REG_OTP_CTRL,
+ (otp_ctrl_data | OTP_CTRL_CLK_EN));
+
+ AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0);
+ control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT;
+ AT_WRITE_REG(hw, REG_EEPROM_CTRL, control);
+
+ for (i = 0; i < 10; i++) {
+ udelay(100);
+ AT_READ_REG(hw, REG_EEPROM_CTRL, &control);
+ if (control & EEPROM_CTRL_RW)
+ break;
+ }
+ if (control & EEPROM_CTRL_RW) {
+ AT_READ_REG(hw, REG_EEPROM_CTRL, &data);
+ AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value);
+ data = data & 0xFFFF;
+ *p_value = swab32((data << 16) | (*p_value >> 16));
+ ret = true;
+ }
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+
+ return ret;
+}
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+int atl1c_read_mac_addr(struct atl1c_hw *hw)
+{
+ int err = 0;
+
+ err = atl1c_get_permanent_address(hw);
+ if (err)
+ random_ether_addr(hw->perm_mac_addr);
+
+ memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
+ return 0;
+}
+
+/*
+ * atl1c_hash_mc_addr
+ * purpose
+ * set hash value for a multicast address
+ * hash calcu processing :
+ * 1. calcu 32bit CRC for multicast address
+ * 2. reverse crc with MSB to LSB
+ */
+u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr)
+{
+ u32 crc32;
+ u32 value = 0;
+ int i;
+
+ crc32 = ether_crc_le(6, mc_addr);
+ for (i = 0; i < 32; i++)
+ value |= (((crc32 >> i) & 1) << (31 - i));
+
+ return value;
+}
+
+/*
+ * Sets the bit in the multicast table corresponding to the hash value.
+ * hw - Struct containing variables accessed by shared code
+ * hash_value - Multicast address hash value
+ */
+void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value)
+{
+ u32 hash_bit, hash_reg;
+ u32 mta;
+
+ /*
+ * The HASH Table is a register array of 2 32-bit registers.
+ * It is treated like an array of 64 bits. We want to set
+ * bit BitArray[hash_value]. So we figure out what register
+ * the bit is in, read it, OR in the new bit, then write
+ * back the new value. The register is determined by the
+ * upper bit of the hash value and the bit within that
+ * register are determined by the lower 5 bits of the value.
+ */
+ hash_reg = (hash_value >> 31) & 0x1;
+ hash_bit = (hash_value >> 26) & 0x1F;
+
+ mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
+
+ mta |= (1 << hash_bit);
+
+ AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
+}
+
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+ u32 val;
+ int i;
+
+ val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
+ MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW |
+ MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+ udelay(2);
+ AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ break;
+ }
+ if (!(val & (MDIO_START | MDIO_BUSY))) {
+ *phy_data = (u16)val;
+ return 0;
+ }
+
+ return -1;
+}
+
+/*
+ * Writes a value to a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to write
+ * data - data to write to the PHY
+ */
+int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data)
+{
+ int i;
+ u32 val;
+
+ val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
+ (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
+ MDIO_SUP_PREAMBLE | MDIO_START |
+ MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+ udelay(2);
+ AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ break;
+ }
+
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ return 0;
+
+ return -1;
+}
+
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
+{
+ u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_SPEED_MASK;
+ u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP &
+ ~GIGA_CR_1000T_SPEED_MASK;
+
+ if (hw->autoneg_advertised & ADVERTISED_10baseT_Half)
+ mii_adv_data |= ADVERTISE_10HALF;
+ if (hw->autoneg_advertised & ADVERTISED_10baseT_Full)
+ mii_adv_data |= ADVERTISE_10FULL;
+ if (hw->autoneg_advertised & ADVERTISED_100baseT_Half)
+ mii_adv_data |= ADVERTISE_100HALF;
+ if (hw->autoneg_advertised & ADVERTISED_100baseT_Full)
+ mii_adv_data |= ADVERTISE_100FULL;
+
+ if (hw->autoneg_advertised & ADVERTISED_Autoneg)
+ mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL;
+
+ if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) {
+ if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
+ mii_giga_ctrl_data |= ADVERTISE_1000HALF;
+ if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
+ mii_giga_ctrl_data |= ADVERTISE_1000FULL;
+ if (hw->autoneg_advertised & ADVERTISED_Autoneg)
+ mii_giga_ctrl_data |= ADVERTISE_1000HALF |
+ ADVERTISE_1000FULL;
+ }
+
+ if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 ||
+ atl1c_write_phy_reg(hw, MII_GIGA_CR, mii_giga_ctrl_data) != 0)
+ return -1;
+ return 0;
+}
+
+void atl1c_phy_disable(struct atl1c_hw *hw)
+{
+ AT_WRITE_REGW(hw, REG_GPHY_CTRL,
+ GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
+}
+
+static void atl1c_phy_magic_data(struct atl1c_hw *hw)
+{
+ u16 data;
+
+ data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE |
+ ((1 & ANA_INTERVAL_SEL_TIMER_MASK) <<
+ ANA_INTERVAL_SEL_TIMER_SHIFT);
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_18);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ data = (2 & ANA_SERDES_CDR_BW_MASK) | ANA_MS_PAD_DBG |
+ ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP | ANA_SERDES_EN_PLL |
+ ANA_SERDES_EN_LCKDT;
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_5);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ data = (44 & ANA_LONG_CABLE_TH_100_MASK) |
+ ((33 & ANA_SHORT_CABLE_TH_100_MASK) <<
+ ANA_SHORT_CABLE_TH_100_SHIFT) | ANA_BP_BAD_LINK_ACCUM |
+ ANA_BP_SMALL_BW;
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_54);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ data = (11 & ANA_IECHO_ADJ_MASK) | ((11 & ANA_IECHO_ADJ_MASK) <<
+ ANA_IECHO_ADJ_2_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
+ ANA_IECHO_ADJ_1_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
+ ANA_IECHO_ADJ_0_SHIFT);
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_4);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ data = ANA_RESTART_CAL | ((7 & ANA_MANUL_SWICH_ON_MASK) <<
+ ANA_MANUL_SWICH_ON_SHIFT) | ANA_MAN_ENABLE |
+ ANA_SEL_HSP | ANA_EN_HB | ANA_OEN_125M;
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_0);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ if (hw->ctrl_flags & ATL1C_HIB_DISABLE) {
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_41);
+ if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
+ return;
+ data &= ~ANA_TOP_PS_EN;
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_11);
+ if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
+ return;
+ data &= ~ANA_PS_HIB_EN;
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+ }
+}
+
+int atl1c_phy_reset(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 phy_ctrl_data = GPHY_CTRL_DEFAULT;
+ u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN;
+ int err;
+
+ if (hw->ctrl_flags & ATL1C_HIB_DISABLE)
+ phy_ctrl_data &= ~GPHY_CTRL_HIB_EN;
+
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(40);
+ phy_ctrl_data |= GPHY_CTRL_EXT_RESET;
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(10);
+
+ /*Enable PHY LinkChange Interrupt */
+ err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data);
+ if (err) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Error enable PHY linkChange Interrupt\n");
+ return err;
+ }
+ if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
+ atl1c_phy_magic_data(hw);
+ return 0;
+}
+
+int atl1c_phy_init(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ int ret_val;
+ u16 mii_bmcr_data = BMCR_RESET;
+ u16 phy_id1, phy_id2;
+
+ if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &phy_id1) != 0) ||
+ (atl1c_read_phy_reg(hw, MII_PHYSID2, &phy_id2) != 0)) {
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev, "Error get phy ID\n");
+ return -1;
+ }
+ switch (hw->media_type) {
+ case MEDIA_TYPE_AUTO_SENSOR:
+ ret_val = atl1c_phy_setup_adv(hw);
+ if (ret_val) {
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev,
+ "Error Setting up Auto-Negotiation\n");
+ return ret_val;
+ }
+ mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG;
+ break;
+ case MEDIA_TYPE_100M_FULL:
+ mii_bmcr_data |= BMCR_SPEED_100 | BMCR_FULL_DUPLEX;
+ break;
+ case MEDIA_TYPE_100M_HALF:
+ mii_bmcr_data |= BMCR_SPEED_100;
+ break;
+ case MEDIA_TYPE_10M_FULL:
+ mii_bmcr_data |= BMCR_SPEED_10 | BMCR_FULL_DUPLEX;
+ break;
+ case MEDIA_TYPE_10M_HALF:
+ mii_bmcr_data |= BMCR_SPEED_10;
+ break;
+ default:
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev, "Wrong Media type %d\n",
+ hw->media_type);
+ return -1;
+ break;
+ }
+
+ ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
+ if (ret_val)
+ return ret_val;
+ hw->phy_configured = true;
+
+ return 0;
+}
+
+/*
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ */
+int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
+{
+ int err;
+ u16 phy_data;
+
+ /* Read PHY Specific Status Register (17) */
+ err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data);
+ if (err)
+ return err;
+
+ if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED))
+ return -1;
+
+ switch (phy_data & GIGA_PSSR_SPEED) {
+ case GIGA_PSSR_1000MBS:
+ *speed = SPEED_1000;
+ break;
+ case GIGA_PSSR_100MBS:
+ *speed = SPEED_100;
+ break;
+ case GIGA_PSSR_10MBS:
+ *speed = SPEED_10;
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ if (phy_data & GIGA_PSSR_DPLX)
+ *duplex = FULL_DUPLEX;
+ else
+ *duplex = HALF_DUPLEX;
+
+ return 0;
+}
+
+int atl1c_restart_autoneg(struct atl1c_hw *hw)
+{
+ int err = 0;
+ u16 mii_bmcr_data = BMCR_RESET;
+
+ err = atl1c_phy_setup_adv(hw);
+ if (err)
+ return err;
+ mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG;
+
+ return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
+}
diff --git a/drivers/net/atl1c/atl1c_hw.h b/drivers/net/atl1c/atl1c_hw.h
new file mode 100644
index 00000000000..c2c738df5c6
--- /dev/null
+++ b/drivers/net/atl1c/atl1c_hw.h
@@ -0,0 +1,859 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ATL1C_HW_H_
+#define _ATL1C_HW_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+
+struct atl1c_adapter;
+struct atl1c_hw;
+
+/* function prototype */
+void atl1c_phy_disable(struct atl1c_hw *hw);
+void atl1c_hw_set_mac_addr(struct atl1c_hw *hw);
+int atl1c_phy_reset(struct atl1c_hw *hw);
+int atl1c_read_mac_addr(struct atl1c_hw *hw);
+int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex);
+u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr);
+void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value);
+int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data);
+int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data);
+bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value);
+int atl1c_phy_init(struct atl1c_hw *hw);
+int atl1c_check_eeprom_exist(struct atl1c_hw *hw);
+int atl1c_restart_autoneg(struct atl1c_hw *hw);
+
+/* register definition */
+#define REG_DEVICE_CAP 0x5C
+#define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7
+#define DEVICE_CAP_MAX_PAYLOAD_SHIFT 0
+
+#define REG_DEVICE_CTRL 0x60
+#define DEVICE_CTRL_MAX_PAYLOAD_MASK 0x7
+#define DEVICE_CTRL_MAX_PAYLOAD_SHIFT 5
+#define DEVICE_CTRL_MAX_RREQ_SZ_MASK 0x7
+#define DEVICE_CTRL_MAX_RREQ_SZ_SHIFT 12
+
+#define REG_LINK_CTRL 0x68
+#define LINK_CTRL_L0S_EN 0x01
+#define LINK_CTRL_L1_EN 0x02
+
+#define REG_VPD_CAP 0x6C
+#define VPD_CAP_ID_MASK 0xff
+#define VPD_CAP_ID_SHIFT 0
+#define VPD_CAP_NEXT_PTR_MASK 0xFF
+#define VPD_CAP_NEXT_PTR_SHIFT 8
+#define VPD_CAP_VPD_ADDR_MASK 0x7FFF
+#define VPD_CAP_VPD_ADDR_SHIFT 16
+#define VPD_CAP_VPD_FLAG 0x80000000
+
+#define REG_VPD_DATA 0x70
+
+#define REG_PCIE_UC_SEVERITY 0x10C
+#define PCIE_UC_SERVRITY_TRN 0x00000001
+#define PCIE_UC_SERVRITY_DLP 0x00000010
+#define PCIE_UC_SERVRITY_PSN_TLP 0x00001000
+#define PCIE_UC_SERVRITY_FCP 0x00002000
+#define PCIE_UC_SERVRITY_CPL_TO 0x00004000
+#define PCIE_UC_SERVRITY_CA 0x00008000
+#define PCIE_UC_SERVRITY_UC 0x00010000
+#define PCIE_UC_SERVRITY_ROV 0x00020000
+#define PCIE_UC_SERVRITY_MLFP 0x00040000
+#define PCIE_UC_SERVRITY_ECRC 0x00080000
+#define PCIE_UC_SERVRITY_UR 0x00100000
+
+#define REG_DEV_SERIALNUM_CTRL 0x200
+#define REG_DEV_MAC_SEL_MASK 0x0 /* 0:EUI; 1:MAC */
+#define REG_DEV_MAC_SEL_SHIFT 0
+#define REG_DEV_SERIAL_NUM_EN_MASK 0x1
+#define REG_DEV_SERIAL_NUM_EN_SHIFT 1
+
+#define REG_TWSI_CTRL 0x218
+#define TWSI_CTRL_LD_OFFSET_MASK 0xFF
+#define TWSI_CTRL_LD_OFFSET_SHIFT 0
+#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7
+#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8
+#define TWSI_CTRL_SW_LDSTART 0x800
+#define TWSI_CTRL_HW_LDSTART 0x1000
+#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F
+#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15
+#define TWSI_CTRL_LD_EXIST 0x400000
+#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3
+#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23
+#define TWSI_CTRL_FREQ_SEL_100K 0
+#define TWSI_CTRL_FREQ_SEL_200K 1
+#define TWSI_CTRL_FREQ_SEL_300K 2
+#define TWSI_CTRL_FREQ_SEL_400K 3
+#define TWSI_CTRL_SMB_SLV_ADDR
+#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3
+#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24
+
+
+#define REG_PCIE_DEV_MISC_CTRL 0x21C
+#define PCIE_DEV_MISC_EXT_PIPE 0x2
+#define PCIE_DEV_MISC_RETRY_BUFDIS 0x1
+#define PCIE_DEV_MISC_SPIROM_EXIST 0x4
+#define PCIE_DEV_MISC_SERDES_ENDIAN 0x8
+#define PCIE_DEV_MISC_SERDES_SEL_DIN 0x10
+
+#define REG_PCIE_PHYMISC 0x1000
+#define PCIE_PHYMISC_FORCE_RCV_DET 0x4
+
+#define REG_TWSI_DEBUG 0x1108
+#define TWSI_DEBUG_DEV_EXIST 0x20000000
+
+#define REG_EEPROM_CTRL 0x12C0
+#define EEPROM_CTRL_DATA_HI_MASK 0xFFFF
+#define EEPROM_CTRL_DATA_HI_SHIFT 0
+#define EEPROM_CTRL_ADDR_MASK 0x3FF
+#define EEPROM_CTRL_ADDR_SHIFT 16
+#define EEPROM_CTRL_ACK 0x40000000
+#define EEPROM_CTRL_RW 0x80000000
+
+#define REG_EEPROM_DATA_LO 0x12C4
+
+#define REG_OTP_CTRL 0x12F0
+#define OTP_CTRL_CLK_EN 0x0002
+
+#define REG_PM_CTRL 0x12F8
+#define PM_CTRL_SDES_EN 0x00000001
+#define PM_CTRL_RBER_EN 0x00000002
+#define PM_CTRL_CLK_REQ_EN 0x00000004
+#define PM_CTRL_ASPM_L1_EN 0x00000008
+#define PM_CTRL_SERDES_L1_EN 0x00000010
+#define PM_CTRL_SERDES_PLL_L1_EN 0x00000020
+#define PM_CTRL_SERDES_PD_EX_L1 0x00000040
+#define PM_CTRL_SERDES_BUDS_RX_L1_EN 0x00000080
+#define PM_CTRL_L0S_ENTRY_TIMER_MASK 0xF
+#define PM_CTRL_L0S_ENTRY_TIMER_SHIFT 8
+#define PM_CTRL_ASPM_L0S_EN 0x00001000
+#define PM_CTRL_CLK_SWH_L1 0x00002000
+#define PM_CTRL_CLK_PWM_VER1_1 0x00004000
+#define PM_CTRL_PCIE_RECV 0x00008000
+#define PM_CTRL_L1_ENTRY_TIMER_MASK 0xF
+#define PM_CTRL_L1_ENTRY_TIMER_SHIFT 16
+#define PM_CTRL_PM_REQ_TIMER_MASK 0xF
+#define PM_CTRL_PM_REQ_TIMER_SHIFT 20
+#define PM_CTRL_LCKDET_TIMER_MASK 0x3F
+#define PM_CTRL_LCKDET_TIMER_SHIFT 24
+#define PM_CTRL_MAC_ASPM_CHK 0x40000000
+#define PM_CTRL_HOTRST 0x80000000
+
+/* Selene Master Control Register */
+#define REG_MASTER_CTRL 0x1400
+#define MASTER_CTRL_SOFT_RST 0x1
+#define MASTER_CTRL_TEST_MODE_MASK 0x3
+#define MASTER_CTRL_TEST_MODE_SHIFT 2
+#define MASTER_CTRL_BERT_START 0x10
+#define MASTER_CTRL_MTIMER_EN 0x100
+#define MASTER_CTRL_MANUAL_INT 0x200
+#define MASTER_CTRL_TX_ITIMER_EN 0x400
+#define MASTER_CTRL_RX_ITIMER_EN 0x800
+#define MASTER_CTRL_CLK_SEL_DIS 0x1000
+#define MASTER_CTRL_CLK_SWH_MODE 0x2000
+#define MASTER_CTRL_INT_RDCLR 0x4000
+#define MASTER_CTRL_REV_NUM_SHIFT 16
+#define MASTER_CTRL_REV_NUM_MASK 0xff
+#define MASTER_CTRL_DEV_ID_SHIFT 24
+#define MASTER_CTRL_DEV_ID_MASK 0x7f
+#define MASTER_CTRL_OTP_SEL 0x80000000
+
+/* Timer Initial Value Register */
+#define REG_MANUAL_TIMER_INIT 0x1404
+
+/* IRQ ModeratorTimer Initial Value Register */
+#define REG_IRQ_MODRT_TIMER_INIT 0x1408
+#define IRQ_MODRT_TIMER_MASK 0xffff
+#define IRQ_MODRT_TX_TIMER_SHIFT 0
+#define IRQ_MODRT_RX_TIMER_SHIFT 16
+
+#define REG_GPHY_CTRL 0x140C
+#define GPHY_CTRL_EXT_RESET 0x1
+#define GPHY_CTRL_RTL_MODE 0x2
+#define GPHY_CTRL_LED_MODE 0x4
+#define GPHY_CTRL_ANEG_NOW 0x8
+#define GPHY_CTRL_REV_ANEG 0x10
+#define GPHY_CTRL_GATE_25M_EN 0x20
+#define GPHY_CTRL_LPW_EXIT 0x40
+#define GPHY_CTRL_PHY_IDDQ 0x80
+#define GPHY_CTRL_PHY_IDDQ_DIS 0x100
+#define GPHY_CTRL_GIGA_DIS 0x200
+#define GPHY_CTRL_HIB_EN 0x400
+#define GPHY_CTRL_HIB_PULSE 0x800
+#define GPHY_CTRL_SEL_ANA_RST 0x1000
+#define GPHY_CTRL_PHY_PLL_ON 0x2000
+#define GPHY_CTRL_PWDOWN_HW 0x4000
+#define GPHY_CTRL_PHY_PLL_BYPASS 0x8000
+
+#define GPHY_CTRL_DEFAULT ( \
+ GPHY_CTRL_SEL_ANA_RST |\
+ GPHY_CTRL_HIB_PULSE |\
+ GPHY_CTRL_HIB_EN)
+
+#define GPHY_CTRL_PW_WOL_DIS ( \
+ GPHY_CTRL_SEL_ANA_RST |\
+ GPHY_CTRL_HIB_PULSE |\
+ GPHY_CTRL_HIB_EN |\
+ GPHY_CTRL_PWDOWN_HW |\
+ GPHY_CTRL_PHY_IDDQ)
+
+/* Block IDLE Status Register */
+#define REG_IDLE_STATUS 0x1410
+#define IDLE_STATUS_MASK 0x00FF
+#define IDLE_STATUS_RXMAC_NO_IDLE 0x1
+#define IDLE_STATUS_TXMAC_NO_IDLE 0x2
+#define IDLE_STATUS_RXQ_NO_IDLE 0x4
+#define IDLE_STATUS_TXQ_NO_IDLE 0x8
+#define IDLE_STATUS_DMAR_NO_IDLE 0x10
+#define IDLE_STATUS_DMAW_NO_IDLE 0x20
+#define IDLE_STATUS_SMB_NO_IDLE 0x40
+#define IDLE_STATUS_CMB_NO_IDLE 0x80
+
+/* MDIO Control Register */
+#define REG_MDIO_CTRL 0x1414
+#define MDIO_DATA_MASK 0xffff /* On MDIO write, the 16-bit
+ * control data to write to PHY
+ * MII management register */
+#define MDIO_DATA_SHIFT 0 /* On MDIO read, the 16-bit
+ * status data that was read
+ * from the PHY MII management register */
+#define MDIO_REG_ADDR_MASK 0x1f /* MDIO register address */
+#define MDIO_REG_ADDR_SHIFT 16
+#define MDIO_RW 0x200000 /* 1: read, 0: write */
+#define MDIO_SUP_PREAMBLE 0x400000 /* Suppress preamble */
+#define MDIO_START 0x800000 /* Write 1 to initiate the MDIO
+ * master. And this bit is self
+ * cleared after one cycle */
+#define MDIO_CLK_SEL_SHIFT 24
+#define MDIO_CLK_25_4 0
+#define MDIO_CLK_25_6 2
+#define MDIO_CLK_25_8 3
+#define MDIO_CLK_25_10 4
+#define MDIO_CLK_25_14 5
+#define MDIO_CLK_25_20 6
+#define MDIO_CLK_25_28 7
+#define MDIO_BUSY 0x8000000
+#define MDIO_AP_EN 0x10000000
+#define MDIO_WAIT_TIMES 10
+
+/* MII PHY Status Register */
+#define REG_PHY_STATUS 0x1418
+#define PHY_GENERAL_STATUS_MASK 0xFFFF
+#define PHY_STATUS_RECV_ENABLE 0x0001
+#define PHY_OE_PWSP_STATUS_MASK 0x07FF
+#define PHY_OE_PWSP_STATUS_SHIFT 16
+#define PHY_STATUS_LPW_STATE 0x80000000
+/* BIST Control and Status Register0 (for the Packet Memory) */
+#define REG_BIST0_CTRL 0x141c
+#define BIST0_NOW 0x1
+#define BIST0_SRAM_FAIL 0x2 /* 1: The SRAM failure is
+ * un-repairable because
+ * it has address decoder
+ * failure or more than 1 cell
+ * stuck-to-x failure */
+#define BIST0_FUSE_FLAG 0x4
+
+/* BIST Control and Status Register1(for the retry buffer of PCI Express) */
+#define REG_BIST1_CTRL 0x1420
+#define BIST1_NOW 0x1
+#define BIST1_SRAM_FAIL 0x2
+#define BIST1_FUSE_FLAG 0x4
+
+/* SerDes Lock Detect Control and Status Register */
+#define REG_SERDES_LOCK 0x1424
+#define SERDES_LOCK_DETECT 0x1 /* SerDes lock detected. This signal
+ * comes from Analog SerDes */
+#define SERDES_LOCK_DETECT_EN 0x2 /* 1: Enable SerDes Lock detect function */
+
+/* MAC Control Register */
+#define REG_MAC_CTRL 0x1480
+#define MAC_CTRL_TX_EN 0x1
+#define MAC_CTRL_RX_EN 0x2
+#define MAC_CTRL_TX_FLOW 0x4
+#define MAC_CTRL_RX_FLOW 0x8
+#define MAC_CTRL_LOOPBACK 0x10
+#define MAC_CTRL_DUPLX 0x20
+#define MAC_CTRL_ADD_CRC 0x40
+#define MAC_CTRL_PAD 0x80
+#define MAC_CTRL_LENCHK 0x100
+#define MAC_CTRL_HUGE_EN 0x200
+#define MAC_CTRL_PRMLEN_SHIFT 10
+#define MAC_CTRL_PRMLEN_MASK 0xf
+#define MAC_CTRL_RMV_VLAN 0x4000
+#define MAC_CTRL_PROMIS_EN 0x8000
+#define MAC_CTRL_TX_PAUSE 0x10000
+#define MAC_CTRL_SCNT 0x20000
+#define MAC_CTRL_SRST_TX 0x40000
+#define MAC_CTRL_TX_SIMURST 0x80000
+#define MAC_CTRL_SPEED_SHIFT 20
+#define MAC_CTRL_SPEED_MASK 0x3
+#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000
+#define MAC_CTRL_TX_HUGE 0x800000
+#define MAC_CTRL_RX_CHKSUM_EN 0x1000000
+#define MAC_CTRL_MC_ALL_EN 0x2000000
+#define MAC_CTRL_BC_EN 0x4000000
+#define MAC_CTRL_DBG 0x8000000
+#define MAC_CTRL_SINGLE_PAUSE_EN 0x10000000
+
+/* MAC IPG/IFG Control Register */
+#define REG_MAC_IPG_IFG 0x1484
+#define MAC_IPG_IFG_IPGT_SHIFT 0 /* Desired back to back
+ * inter-packet gap. The
+ * default is 96-bit time */
+#define MAC_IPG_IFG_IPGT_MASK 0x7f
+#define MAC_IPG_IFG_MIFG_SHIFT 8 /* Minimum number of IFG to
+ * enforce in between RX frames */
+#define MAC_IPG_IFG_MIFG_MASK 0xff /* Frame gap below such IFP is dropped */
+#define MAC_IPG_IFG_IPGR1_SHIFT 16 /* 64bit Carrier-Sense window */
+#define MAC_IPG_IFG_IPGR1_MASK 0x7f
+#define MAC_IPG_IFG_IPGR2_SHIFT 24 /* 96-bit IPG window */
+#define MAC_IPG_IFG_IPGR2_MASK 0x7f
+
+/* MAC STATION ADDRESS */
+#define REG_MAC_STA_ADDR 0x1488
+
+/* Hash table for multicast address */
+#define REG_RX_HASH_TABLE 0x1490
+
+/* MAC Half-Duplex Control Register */
+#define REG_MAC_HALF_DUPLX_CTRL 0x1498
+#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 /* Collision Window */
+#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff
+#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12
+#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf
+#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 /* No back-off on backpressure,
+ * immediately start the
+ * transmission after back pressure */
+#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */
+#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 /* Maximum binary exponential number */
+#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 /* IPG to start JAM for collision based flow control in half-duplex */
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf /* mode. In unit of 8-bit time */
+
+/* Maximum Frame Length Control Register */
+#define REG_MTU 0x149c
+
+/* Wake-On-Lan control register */
+#define REG_WOL_CTRL 0x14a0
+#define WOL_PATTERN_EN 0x00000001
+#define WOL_PATTERN_PME_EN 0x00000002
+#define WOL_MAGIC_EN 0x00000004
+#define WOL_MAGIC_PME_EN 0x00000008
+#define WOL_LINK_CHG_EN 0x00000010
+#define WOL_LINK_CHG_PME_EN 0x00000020
+#define WOL_PATTERN_ST 0x00000100
+#define WOL_MAGIC_ST 0x00000200
+#define WOL_LINKCHG_ST 0x00000400
+#define WOL_CLK_SWITCH_EN 0x00008000
+#define WOL_PT0_EN 0x00010000
+#define WOL_PT1_EN 0x00020000
+#define WOL_PT2_EN 0x00040000
+#define WOL_PT3_EN 0x00080000
+#define WOL_PT4_EN 0x00100000
+#define WOL_PT5_EN 0x00200000
+#define WOL_PT6_EN 0x00400000
+
+/* WOL Length ( 2 DWORD ) */
+#define REG_WOL_PATTERN_LEN 0x14a4
+#define WOL_PT_LEN_MASK 0x7f
+#define WOL_PT0_LEN_SHIFT 0
+#define WOL_PT1_LEN_SHIFT 8
+#define WOL_PT2_LEN_SHIFT 16
+#define WOL_PT3_LEN_SHIFT 24
+#define WOL_PT4_LEN_SHIFT 0
+#define WOL_PT5_LEN_SHIFT 8
+#define WOL_PT6_LEN_SHIFT 16
+
+/* Internal SRAM Partition Register */
+#define RFDX_HEAD_ADDR_MASK 0x03FF
+#define RFDX_HARD_ADDR_SHIFT 0
+#define RFDX_TAIL_ADDR_MASK 0x03FF
+#define RFDX_TAIL_ADDR_SHIFT 16
+
+#define REG_SRAM_RFD0_INFO 0x1500
+#define REG_SRAM_RFD1_INFO 0x1504
+#define REG_SRAM_RFD2_INFO 0x1508
+#define REG_SRAM_RFD3_INFO 0x150C
+
+#define REG_RFD_NIC_LEN 0x1510 /* In 8-bytes */
+#define RFD_NIC_LEN_MASK 0x03FF
+
+#define REG_SRAM_TRD_ADDR 0x1518
+#define TPD_HEAD_ADDR_MASK 0x03FF
+#define TPD_HEAD_ADDR_SHIFT 0
+#define TPD_TAIL_ADDR_MASK 0x03FF
+#define TPD_TAIL_ADDR_SHIFT 16
+
+#define REG_SRAM_TRD_LEN 0x151C /* In 8-bytes */
+#define TPD_NIC_LEN_MASK 0x03FF
+
+#define REG_SRAM_RXF_ADDR 0x1520
+#define REG_SRAM_RXF_LEN 0x1524
+#define REG_SRAM_TXF_ADDR 0x1528
+#define REG_SRAM_TXF_LEN 0x152C
+#define REG_SRAM_TCPH_ADDR 0x1530
+#define REG_SRAM_PKTH_ADDR 0x1532
+
+/*
+ * Load Ptr Register
+ * Software sets this bit after the initialization of the head and tail */
+#define REG_LOAD_PTR 0x1534
+
+/*
+ * addresses of all descriptors, as well as the following descriptor
+ * control register, which triggers each function block to load the head
+ * pointer to prepare for the operation. This bit is then self-cleared
+ * after one cycle.
+ */
+#define REG_RX_BASE_ADDR_HI 0x1540
+#define REG_TX_BASE_ADDR_HI 0x1544
+#define REG_SMB_BASE_ADDR_HI 0x1548
+#define REG_SMB_BASE_ADDR_LO 0x154C
+#define REG_RFD0_HEAD_ADDR_LO 0x1550
+#define REG_RFD1_HEAD_ADDR_LO 0x1554
+#define REG_RFD2_HEAD_ADDR_LO 0x1558
+#define REG_RFD3_HEAD_ADDR_LO 0x155C
+#define REG_RFD_RING_SIZE 0x1560
+#define RFD_RING_SIZE_MASK 0x0FFF
+#define REG_RX_BUF_SIZE 0x1564
+#define RX_BUF_SIZE_MASK 0xFFFF
+#define REG_RRD0_HEAD_ADDR_LO 0x1568
+#define REG_RRD1_HEAD_ADDR_LO 0x156C
+#define REG_RRD2_HEAD_ADDR_LO 0x1570
+#define REG_RRD3_HEAD_ADDR_LO 0x1574
+#define REG_RRD_RING_SIZE 0x1578
+#define RRD_RING_SIZE_MASK 0x0FFF
+#define REG_HTPD_HEAD_ADDR_LO 0x157C
+#define REG_NTPD_HEAD_ADDR_LO 0x1580
+#define REG_TPD_RING_SIZE 0x1584
+#define TPD_RING_SIZE_MASK 0xFFFF
+#define REG_CMB_BASE_ADDR_LO 0x1588
+
+/* RSS about */
+#define REG_RSS_KEY0 0x14B0
+#define REG_RSS_KEY1 0x14B4
+#define REG_RSS_KEY2 0x14B8
+#define REG_RSS_KEY3 0x14BC
+#define REG_RSS_KEY4 0x14C0
+#define REG_RSS_KEY5 0x14C4
+#define REG_RSS_KEY6 0x14C8
+#define REG_RSS_KEY7 0x14CC
+#define REG_RSS_KEY8 0x14D0
+#define REG_RSS_KEY9 0x14D4
+#define REG_IDT_TABLE0 0x14E0
+#define REG_IDT_TABLE1 0x14E4
+#define REG_IDT_TABLE2 0x14E8
+#define REG_IDT_TABLE3 0x14EC
+#define REG_IDT_TABLE4 0x14F0
+#define REG_IDT_TABLE5 0x14F4
+#define REG_IDT_TABLE6 0x14F8
+#define REG_IDT_TABLE7 0x14FC
+#define REG_IDT_TABLE REG_IDT_TABLE0
+#define REG_RSS_HASH_VALUE 0x15B0
+#define REG_RSS_HASH_FLAG 0x15B4
+#define REG_BASE_CPU_NUMBER 0x15B8
+
+/* TXQ Control Register */
+#define REG_TXQ_CTRL 0x1590
+#define TXQ_NUM_TPD_BURST_MASK 0xF
+#define TXQ_NUM_TPD_BURST_SHIFT 0
+#define TXQ_CTRL_IP_OPTION_EN 0x10
+#define TXQ_CTRL_EN 0x20
+#define TXQ_CTRL_ENH_MODE 0x40
+#define TXQ_CTRL_LS_8023_EN 0x80
+#define TXQ_TXF_BURST_NUM_SHIFT 16
+#define TXQ_TXF_BURST_NUM_MASK 0xFFFF
+
+/* Jumbo packet Threshold for task offload */
+#define REG_TX_TSO_OFFLOAD_THRESH 0x1594 /* In 8-bytes */
+#define TX_TSO_OFFLOAD_THRESH_MASK 0x07FF
+
+#define REG_TXF_WATER_MARK 0x1598 /* In 8-bytes */
+#define TXF_WATER_MARK_MASK 0x0FFF
+#define TXF_LOW_WATER_MARK_SHIFT 0
+#define TXF_HIGH_WATER_MARK_SHIFT 16
+#define TXQ_CTRL_BURST_MODE_EN 0x80000000
+
+#define REG_THRUPUT_MON_CTRL 0x159C
+#define THRUPUT_MON_RATE_MASK 0x3
+#define THRUPUT_MON_RATE_SHIFT 0
+#define THRUPUT_MON_EN 0x80
+
+/* RXQ Control Register */
+#define REG_RXQ_CTRL 0x15A0
+#define ASPM_THRUPUT_LIMIT_MASK 0x3
+#define ASPM_THRUPUT_LIMIT_SHIFT 0
+#define ASPM_THRUPUT_LIMIT_NO 0x00
+#define ASPM_THRUPUT_LIMIT_1M 0x01
+#define ASPM_THRUPUT_LIMIT_10M 0x02
+#define ASPM_THRUPUT_LIMIT_100M 0x04
+#define RXQ1_CTRL_EN 0x10
+#define RXQ2_CTRL_EN 0x20
+#define RXQ3_CTRL_EN 0x40
+#define IPV6_CHKSUM_CTRL_EN 0x80
+#define RSS_HASH_BITS_MASK 0x00FF
+#define RSS_HASH_BITS_SHIFT 8
+#define RSS_HASH_IPV4 0x10000
+#define RSS_HASH_IPV4_TCP 0x20000
+#define RSS_HASH_IPV6 0x40000
+#define RSS_HASH_IPV6_TCP 0x80000
+#define RXQ_RFD_BURST_NUM_MASK 0x003F
+#define RXQ_RFD_BURST_NUM_SHIFT 20
+#define RSS_MODE_MASK 0x0003
+#define RSS_MODE_SHIFT 26
+#define RSS_NIP_QUEUE_SEL_MASK 0x1
+#define RSS_NIP_QUEUE_SEL_SHIFT 28
+#define RRS_HASH_CTRL_EN 0x20000000
+#define RX_CUT_THRU_EN 0x40000000
+#define RXQ_CTRL_EN 0x80000000
+
+#define REG_RFD_FREE_THRESH 0x15A4
+#define RFD_FREE_THRESH_MASK 0x003F
+#define RFD_FREE_HI_THRESH_SHIFT 0
+#define RFD_FREE_LO_THRESH_SHIFT 6
+
+/* RXF flow control register */
+#define REG_RXQ_RXF_PAUSE_THRESH 0x15A8
+#define RXQ_RXF_PAUSE_TH_HI_SHIFT 0
+#define RXQ_RXF_PAUSE_TH_HI_MASK 0x0FFF
+#define RXQ_RXF_PAUSE_TH_LO_SHIFT 16
+#define RXQ_RXF_PAUSE_TH_LO_MASK 0x0FFF
+
+#define REG_RXD_DMA_CTRL 0x15AC
+#define RXD_DMA_THRESH_MASK 0x0FFF /* In 8-bytes */
+#define RXD_DMA_THRESH_SHIFT 0
+#define RXD_DMA_DOWN_TIMER_MASK 0xFFFF
+#define RXD_DMA_DOWN_TIMER_SHIFT 16
+
+/* DMA Engine Control Register */
+#define REG_DMA_CTRL 0x15C0
+#define DMA_CTRL_DMAR_IN_ORDER 0x1
+#define DMA_CTRL_DMAR_ENH_ORDER 0x2
+#define DMA_CTRL_DMAR_OUT_ORDER 0x4
+#define DMA_CTRL_RCB_VALUE 0x8
+#define DMA_CTRL_DMAR_BURST_LEN_MASK 0x0007
+#define DMA_CTRL_DMAR_BURST_LEN_SHIFT 4
+#define DMA_CTRL_DMAW_BURST_LEN_MASK 0x0007
+#define DMA_CTRL_DMAW_BURST_LEN_SHIFT 7
+#define DMA_CTRL_DMAR_REQ_PRI 0x400
+#define DMA_CTRL_DMAR_DLY_CNT_MASK 0x001F
+#define DMA_CTRL_DMAR_DLY_CNT_SHIFT 11
+#define DMA_CTRL_DMAW_DLY_CNT_MASK 0x000F
+#define DMA_CTRL_DMAW_DLY_CNT_SHIFT 16
+#define DMA_CTRL_CMB_EN 0x100000
+#define DMA_CTRL_SMB_EN 0x200000
+#define DMA_CTRL_CMB_NOW 0x400000
+#define MAC_CTRL_SMB_DIS 0x1000000
+#define DMA_CTRL_SMB_NOW 0x80000000
+
+/* CMB/SMB Control Register */
+#define REG_SMB_STAT_TIMER 0x15C4 /* 2us resolution */
+#define SMB_STAT_TIMER_MASK 0xFFFFFF
+#define REG_CMB_TPD_THRESH 0x15C8
+#define CMB_TPD_THRESH_MASK 0xFFFF
+#define REG_CMB_TX_TIMER 0x15CC /* 2us resolution */
+#define CMB_TX_TIMER_MASK 0xFFFF
+
+/* Mail box */
+#define MB_RFDX_PROD_IDX_MASK 0xFFFF
+#define REG_MB_RFD0_PROD_IDX 0x15E0
+#define REG_MB_RFD1_PROD_IDX 0x15E4
+#define REG_MB_RFD2_PROD_IDX 0x15E8
+#define REG_MB_RFD3_PROD_IDX 0x15EC
+
+#define MB_PRIO_PROD_IDX_MASK 0xFFFF
+#define REG_MB_PRIO_PROD_IDX 0x15F0
+#define MB_HTPD_PROD_IDX_SHIFT 0
+#define MB_NTPD_PROD_IDX_SHIFT 16
+
+#define MB_PRIO_CONS_IDX_MASK 0xFFFF
+#define REG_MB_PRIO_CONS_IDX 0x15F4
+#define MB_HTPD_CONS_IDX_SHIFT 0
+#define MB_NTPD_CONS_IDX_SHIFT 16
+
+#define REG_MB_RFD01_CONS_IDX 0x15F8
+#define MB_RFD0_CONS_IDX_MASK 0x0000FFFF
+#define MB_RFD1_CONS_IDX_MASK 0xFFFF0000
+#define REG_MB_RFD23_CONS_IDX 0x15FC
+#define MB_RFD2_CONS_IDX_MASK 0x0000FFFF
+#define MB_RFD3_CONS_IDX_MASK 0xFFFF0000
+
+/* Interrupt Status Register */
+#define REG_ISR 0x1600
+#define ISR_SMB 0x00000001
+#define ISR_TIMER 0x00000002
+/*
+ * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set
+ * in Table 51 Selene Master Control Register (Offset 0x1400).
+ */
+#define ISR_MANUAL 0x00000004
+#define ISR_HW_RXF_OV 0x00000008 /* RXF overflow interrupt */
+#define ISR_RFD0_UR 0x00000010 /* RFD0 under run */
+#define ISR_RFD1_UR 0x00000020
+#define ISR_RFD2_UR 0x00000040
+#define ISR_RFD3_UR 0x00000080
+#define ISR_TXF_UR 0x00000100
+#define ISR_DMAR_TO_RST 0x00000200
+#define ISR_DMAW_TO_RST 0x00000400
+#define ISR_TX_CREDIT 0x00000800
+#define ISR_GPHY 0x00001000
+/* GPHY low power state interrupt */
+#define ISR_GPHY_LPW 0x00002000
+#define ISR_TXQ_TO_RST 0x00004000
+#define ISR_TX_PKT 0x00008000
+#define ISR_RX_PKT_0 0x00010000
+#define ISR_RX_PKT_1 0x00020000
+#define ISR_RX_PKT_2 0x00040000
+#define ISR_RX_PKT_3 0x00080000
+#define ISR_MAC_RX 0x00100000
+#define ISR_MAC_TX 0x00200000
+#define ISR_UR_DETECTED 0x00400000
+#define ISR_FERR_DETECTED 0x00800000
+#define ISR_NFERR_DETECTED 0x01000000
+#define ISR_CERR_DETECTED 0x02000000
+#define ISR_PHY_LINKDOWN 0x04000000
+#define ISR_DIS_INT 0x80000000
+
+/* Interrupt Mask Register */
+#define REG_IMR 0x1604
+
+#define IMR_NORMAL_MASK (\
+ ISR_MANUAL |\
+ ISR_HW_RXF_OV |\
+ ISR_RFD0_UR |\
+ ISR_TXF_UR |\
+ ISR_DMAR_TO_RST |\
+ ISR_TXQ_TO_RST |\
+ ISR_DMAW_TO_RST |\
+ ISR_GPHY |\
+ ISR_TX_PKT |\
+ ISR_RX_PKT_0 |\
+ ISR_GPHY_LPW |\
+ ISR_PHY_LINKDOWN)
+
+#define ISR_RX_PKT (\
+ ISR_RX_PKT_0 |\
+ ISR_RX_PKT_1 |\
+ ISR_RX_PKT_2 |\
+ ISR_RX_PKT_3)
+
+#define ISR_OVER (\
+ ISR_RFD0_UR |\
+ ISR_RFD1_UR |\
+ ISR_RFD2_UR |\
+ ISR_RFD3_UR |\
+ ISR_HW_RXF_OV |\
+ ISR_TXF_UR)
+
+#define ISR_ERROR (\
+ ISR_DMAR_TO_RST |\
+ ISR_TXQ_TO_RST |\
+ ISR_DMAW_TO_RST |\
+ ISR_PHY_LINKDOWN)
+
+#define REG_INT_RETRIG_TIMER 0x1608
+#define INT_RETRIG_TIMER_MASK 0xFFFF
+
+#define REG_HDS_CTRL 0x160C
+#define HDS_CTRL_EN 0x0001
+#define HDS_CTRL_BACKFILLSIZE_SHIFT 8
+#define HDS_CTRL_BACKFILLSIZE_MASK 0x0FFF
+#define HDS_CTRL_MAX_HDRSIZE_SHIFT 20
+#define HDS_CTRL_MAC_HDRSIZE_MASK 0x0FFF
+
+#define REG_MAC_RX_STATUS_BIN 0x1700
+#define REG_MAC_RX_STATUS_END 0x175c
+#define REG_MAC_TX_STATUS_BIN 0x1760
+#define REG_MAC_TX_STATUS_END 0x17c0
+
+/* DEBUG ADDR */
+#define REG_DEBUG_DATA0 0x1900
+#define REG_DEBUG_DATA1 0x1904
+
+/* PHY Control Register */
+#define MII_BMCR 0x00
+#define BMCR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define BMCR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
+#define BMCR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
+#define BMCR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
+#define BMCR_ISOLATE 0x0400 /* Isolate PHY from MII */
+#define BMCR_POWER_DOWN 0x0800 /* Power down */
+#define BMCR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
+#define BMCR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define BMCR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
+#define BMCR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
+#define BMCR_SPEED_MASK 0x2040
+#define BMCR_SPEED_1000 0x0040
+#define BMCR_SPEED_100 0x2000
+#define BMCR_SPEED_10 0x0000
+
+/* PHY Status Register */
+#define MII_BMSR 0x01
+#define BMMSR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
+#define BMSR_JABBER_DETECT 0x0002 /* Jabber Detected */
+#define BMSR_LINK_STATUS 0x0004 /* Link Status 1 = link */
+#define BMSR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
+#define BMSR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
+#define BMSR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
+#define BMSR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
+#define BMSR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
+#define BMSR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
+#define BMSR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
+#define BMSR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
+#define BMSR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
+#define BMSR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
+#define BMMII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
+#define BMMII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
+
+#define MII_PHYSID1 0x02
+#define MII_PHYSID2 0x03
+
+/* Autoneg Advertisement Register */
+#define MII_ADVERTISE 0x04
+#define ADVERTISE_SPEED_MASK 0x01E0
+#define ADVERTISE_DEFAULT_CAP 0x0DE0
+
+/* 1000BASE-T Control Register */
+#define MII_GIGA_CR 0x09
+#define GIGA_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port 0=DTE device */
+
+#define GIGA_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master 0=Configure PHY as Slave */
+#define GIGA_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
+#define GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
+#define GIGA_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
+#define GIGA_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
+#define GIGA_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
+#define GIGA_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
+#define GIGA_CR_1000T_SPEED_MASK 0x0300
+#define GIGA_CR_1000T_DEFAULT_CAP 0x0300
+
+/* PHY Specific Status Register */
+#define MII_GIGA_PSSR 0x11
+#define GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
+#define GIGA_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
+#define GIGA_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
+#define GIGA_PSSR_10MBS 0x0000 /* 00=10Mbs */
+#define GIGA_PSSR_100MBS 0x4000 /* 01=100Mbs */
+#define GIGA_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
+
+/* PHY Interrupt Enable Register */
+#define MII_IER 0x12
+#define IER_LINK_UP 0x0400
+#define IER_LINK_DOWN 0x0800
+
+/* PHY Interrupt Status Register */
+#define MII_ISR 0x13
+#define ISR_LINK_UP 0x0400
+#define ISR_LINK_DOWN 0x0800
+
+/* Cable-Detect-Test Control Register */
+#define MII_CDTC 0x16
+#define CDTC_EN_OFF 0 /* sc */
+#define CDTC_EN_BITS 1
+#define CDTC_PAIR_OFF 8
+#define CDTC_PAIR_BIT 2
+
+/* Cable-Detect-Test Status Register */
+#define MII_CDTS 0x1C
+#define CDTS_STATUS_OFF 8
+#define CDTS_STATUS_BITS 2
+#define CDTS_STATUS_NORMAL 0
+#define CDTS_STATUS_SHORT 1
+#define CDTS_STATUS_OPEN 2
+#define CDTS_STATUS_INVALID 3
+
+#define MII_DBG_ADDR 0x1D
+#define MII_DBG_DATA 0x1E
+
+#define MII_ANA_CTRL_0 0x0
+#define ANA_RESTART_CAL 0x0001
+#define ANA_MANUL_SWICH_ON_SHIFT 0x1
+#define ANA_MANUL_SWICH_ON_MASK 0xF
+#define ANA_MAN_ENABLE 0x0020
+#define ANA_SEL_HSP 0x0040
+#define ANA_EN_HB 0x0080
+#define ANA_EN_HBIAS 0x0100
+#define ANA_OEN_125M 0x0200
+#define ANA_EN_LCKDT 0x0400
+#define ANA_LCKDT_PHY 0x0800
+#define ANA_AFE_MODE 0x1000
+#define ANA_VCO_SLOW 0x2000
+#define ANA_VCO_FAST 0x4000
+#define ANA_SEL_CLK125M_DSP 0x8000
+
+#define MII_ANA_CTRL_4 0x4
+#define ANA_IECHO_ADJ_MASK 0xF
+#define ANA_IECHO_ADJ_3_SHIFT 0
+#define ANA_IECHO_ADJ_2_SHIFT 4
+#define ANA_IECHO_ADJ_1_SHIFT 8
+#define ANA_IECHO_ADJ_0_SHIFT 12
+
+#define MII_ANA_CTRL_5 0x5
+#define ANA_SERDES_CDR_BW_SHIFT 0
+#define ANA_SERDES_CDR_BW_MASK 0x3
+#define ANA_MS_PAD_DBG 0x0004
+#define ANA_SPEEDUP_DBG 0x0008
+#define ANA_SERDES_TH_LOS_SHIFT 4
+#define ANA_SERDES_TH_LOS_MASK 0x3
+#define ANA_SERDES_EN_DEEM 0x0040
+#define ANA_SERDES_TXELECIDLE 0x0080
+#define ANA_SERDES_BEACON 0x0100
+#define ANA_SERDES_HALFTXDR 0x0200
+#define ANA_SERDES_SEL_HSP 0x0400
+#define ANA_SERDES_EN_PLL 0x0800
+#define ANA_SERDES_EN 0x1000
+#define ANA_SERDES_EN_LCKDT 0x2000
+
+#define MII_ANA_CTRL_11 0xB
+#define ANA_PS_HIB_EN 0x8000
+
+#define MII_ANA_CTRL_18 0x12
+#define ANA_TEST_MODE_10BT_01SHIFT 0
+#define ANA_TEST_MODE_10BT_01MASK 0x3
+#define ANA_LOOP_SEL_10BT 0x0004
+#define ANA_RGMII_MODE_SW 0x0008
+#define ANA_EN_LONGECABLE 0x0010
+#define ANA_TEST_MODE_10BT_2 0x0020
+#define ANA_EN_10BT_IDLE 0x0400
+#define ANA_EN_MASK_TB 0x0800
+#define ANA_TRIGGER_SEL_TIMER_SHIFT 12
+#define ANA_TRIGGER_SEL_TIMER_MASK 0x3
+#define ANA_INTERVAL_SEL_TIMER_SHIFT 14
+#define ANA_INTERVAL_SEL_TIMER_MASK 0x3
+
+#define MII_ANA_CTRL_41 0x29
+#define ANA_TOP_PS_EN 0x8000
+
+#define MII_ANA_CTRL_54 0x36
+#define ANA_LONG_CABLE_TH_100_SHIFT 0
+#define ANA_LONG_CABLE_TH_100_MASK 0x3F
+#define ANA_DESERVED 0x0040
+#define ANA_EN_LIT_CH 0x0080
+#define ANA_SHORT_CABLE_TH_100_SHIFT 8
+#define ANA_SHORT_CABLE_TH_100_MASK 0x3F
+#define ANA_BP_BAD_LINK_ACCUM 0x4000
+#define ANA_BP_SMALL_BW 0x8000
+
+#endif /*_ATL1C_HW_H_*/
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
new file mode 100644
index 00000000000..deb7b53167e
--- /dev/null
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -0,0 +1,2797 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "atl1c.h"
+
+#define ATL1C_DRV_VERSION "1.0.0.1-NAPI"
+char atl1c_driver_name[] = "atl1c";
+char atl1c_driver_version[] = ATL1C_DRV_VERSION;
+#define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062
+#define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063
+/*
+ * atl1c_pci_tbl - PCI Device ID Table
+ *
+ * Wildcard entries (PCI_ANY_ID) should come last
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
+ * Class, Class Mask, private data (not used) }
+ */
+static struct pci_device_id atl1c_pci_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)},
+ /* required last entry */
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl);
+
+MODULE_AUTHOR("Jie Yang <jie.yang@atheros.com>");
+MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATL1C_DRV_VERSION);
+
+static int atl1c_stop_mac(struct atl1c_hw *hw);
+static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw);
+static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw);
+static void atl1c_disable_l0s_l1(struct atl1c_hw *hw);
+static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup);
+static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter);
+static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
+ int *work_done, int work_to_do);
+
+static const u16 atl1c_pay_load_size[] = {
+ 128, 256, 512, 1024, 2048, 4096,
+};
+
+static const u16 atl1c_rfd_prod_idx_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+ REG_MB_RFD0_PROD_IDX,
+ REG_MB_RFD1_PROD_IDX,
+ REG_MB_RFD2_PROD_IDX,
+ REG_MB_RFD3_PROD_IDX
+};
+
+static const u16 atl1c_rfd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+ REG_RFD0_HEAD_ADDR_LO,
+ REG_RFD1_HEAD_ADDR_LO,
+ REG_RFD2_HEAD_ADDR_LO,
+ REG_RFD3_HEAD_ADDR_LO
+};
+
+static const u16 atl1c_rrd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+ REG_RRD0_HEAD_ADDR_LO,
+ REG_RRD1_HEAD_ADDR_LO,
+ REG_RRD2_HEAD_ADDR_LO,
+ REG_RRD3_HEAD_ADDR_LO
+};
+
+static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
+ NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP;
+
+/*
+ * atl1c_init_pcie - init PCIE module
+ */
+static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag)
+{
+ u32 data;
+ u32 pci_cmd;
+ struct pci_dev *pdev = hw->adapter->pdev;
+
+ AT_READ_REG(hw, PCI_COMMAND, &pci_cmd);
+ pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+ pci_cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_IO);
+ AT_WRITE_REG(hw, PCI_COMMAND, pci_cmd);
+
+ /*
+ * Clear any PowerSaveing Settings
+ */
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ /*
+ * Mask some pcie error bits
+ */
+ AT_READ_REG(hw, REG_PCIE_UC_SEVERITY, &data);
+ data &= ~PCIE_UC_SERVRITY_DLP;
+ data &= ~PCIE_UC_SERVRITY_FCP;
+ AT_WRITE_REG(hw, REG_PCIE_UC_SEVERITY, data);
+
+ if (flag & ATL1C_PCIE_L0S_L1_DISABLE)
+ atl1c_disable_l0s_l1(hw);
+ if (flag & ATL1C_PCIE_PHY_RESET)
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
+ else
+ AT_WRITE_REG(hw, REG_GPHY_CTRL,
+ GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET);
+
+ msleep(1);
+}
+
+/*
+ * atl1c_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_enable(struct atl1c_adapter *adapter)
+{
+ if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
+ AT_WRITE_REG(&adapter->hw, REG_ISR, 0x7FFFFFFF);
+ AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
+ AT_WRITE_FLUSH(&adapter->hw);
+ }
+}
+
+/*
+ * atl1c_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_disable(struct atl1c_adapter *adapter)
+{
+ atomic_inc(&adapter->irq_sem);
+ AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
+ AT_WRITE_FLUSH(&adapter->hw);
+ synchronize_irq(adapter->pdev->irq);
+}
+
+/*
+ * atl1c_irq_reset - reset interrupt confiure on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
+{
+ atomic_set(&adapter->irq_sem, 1);
+ atl1c_irq_enable(adapter);
+}
+
+/*
+ * atl1c_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl1c_phy_config(unsigned long data)
+{
+ struct atl1c_adapter *adapter = (struct atl1c_adapter *) data;
+ struct atl1c_hw *hw = &adapter->hw;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ atl1c_restart_autoneg(hw);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+}
+
+void atl1c_reinit_locked(struct atl1c_adapter *adapter)
+{
+
+ WARN_ON(in_interrupt());
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ clear_bit(__AT_RESETTING, &adapter->flags);
+}
+
+static void atl1c_reset_task(struct work_struct *work)
+{
+ struct atl1c_adapter *adapter;
+ struct net_device *netdev;
+
+ adapter = container_of(work, struct atl1c_adapter, reset_task);
+ netdev = adapter->netdev;
+
+ netif_device_detach(netdev);
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ netif_device_attach(netdev);
+}
+
+static void atl1c_check_link_status(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ int err;
+ unsigned long flags;
+ u16 speed, duplex, phy_data;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ /* MII_BMSR must read twise */
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+
+ if ((phy_data & BMSR_LSTATUS) == 0) {
+ /* 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");
+ }
+ netif_carrier_off(netdev);
+ } else {
+ /* Link Up */
+ hw->hibernate = false;
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ err = atl1c_get_speed_and_duplex(hw, &speed, &duplex);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+ if (unlikely(err))
+ return;
+ /* link result is our setting */
+ if (adapter->link_speed != speed ||
+ adapter->link_duplex != duplex) {
+ adapter->link_speed = speed;
+ adapter->link_duplex = duplex;
+ 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",
+ atl1c_driver_name, netdev->name,
+ adapter->link_speed,
+ adapter->link_duplex == FULL_DUPLEX ?
+ "Full Duplex" : "Half Duplex");
+ }
+ if (!netif_carrier_ok(netdev))
+ netif_carrier_on(netdev);
+ }
+}
+
+/*
+ * atl1c_link_chg_task - deal with link change event Out of interrupt context
+ * @netdev: network interface device structure
+ */
+static void atl1c_link_chg_task(struct work_struct *work)
+{
+ struct atl1c_adapter *adapter;
+
+ adapter = container_of(work, struct atl1c_adapter, link_chg_task);
+ atl1c_check_link_status(adapter);
+}
+
+static void atl1c_link_chg_event(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ u16 phy_data;
+ u16 link_up;
+
+ spin_lock(&adapter->mdio_lock);
+ atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+ atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+ spin_unlock(&adapter->mdio_lock);
+ link_up = phy_data & BMSR_LSTATUS;
+ /* notify upper layer link down ASAP */
+ if (!link_up) {
+ if (netif_carrier_ok(netdev)) {
+ /* old link state: Up */
+ netif_carrier_off(netdev);
+ if (netif_msg_link(adapter))
+ dev_info(&pdev->dev,
+ "%s: %s NIC Link is Down\n",
+ atl1c_driver_name, netdev->name);
+ adapter->link_speed = SPEED_0;
+ }
+ }
+ schedule_work(&adapter->link_chg_task);
+}
+
+static void atl1c_del_timer(struct atl1c_adapter *adapter)
+{
+ del_timer_sync(&adapter->phy_config_timer);
+}
+
+static void atl1c_cancel_work(struct atl1c_adapter *adapter)
+{
+ cancel_work_sync(&adapter->reset_task);
+ cancel_work_sync(&adapter->link_chg_task);
+}
+
+/*
+ * atl1c_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl1c_tx_timeout(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ /* Do the reset outside of interrupt context */
+ schedule_work(&adapter->reset_task);
+}
+
+/*
+ * atl1c_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ */
+static void atl1c_set_multi(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ struct dev_mc_list *mc_ptr;
+ u32 mac_ctrl_data;
+ u32 hash_value;
+
+ /* Check for Promiscuous and All Multicast modes */
+ AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data);
+
+ if (netdev->flags & IFF_PROMISC) {
+ mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+ } else if (netdev->flags & IFF_ALLMULTI) {
+ mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+ mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
+ } else {
+ mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+ }
+
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+ /* clear the old settings from the multicast hash table */
+ AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+ AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+ /* comoute mc addresses' hash value ,and put it into hash table */
+ for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+ hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr);
+ atl1c_hash_set(hw, hash_value);
+ }
+}
+
+static void atl1c_vlan_rx_register(struct net_device *netdev,
+ struct vlan_group *grp)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ u32 mac_ctrl_data = 0;
+
+ if (netif_msg_pktdata(adapter))
+ dev_dbg(&pdev->dev, "atl1c_vlan_rx_register\n");
+
+ atl1c_irq_disable(adapter);
+
+ adapter->vlgrp = grp;
+ AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data);
+
+ if (grp) {
+ /* enable VLAN tag insert/strip */
+ mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+ } else {
+ /* disable VLAN tag insert/strip */
+ mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
+ }
+
+ AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
+ atl1c_irq_enable(adapter);
+}
+
+static void atl1c_restore_vlan(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ if (netif_msg_pktdata(adapter))
+ dev_dbg(&pdev->dev, "atl1c_restore_vlan !");
+ atl1c_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+}
+/*
+ * atl1c_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1c_set_mac_addr(struct net_device *netdev, void *p)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (netif_running(netdev))
+ return -EBUSY;
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+ atl1c_hw_set_mac_addr(&adapter->hw);
+
+ return 0;
+}
+
+static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
+ struct net_device *dev)
+{
+ int mtu = dev->mtu;
+
+ adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
+ roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
+}
+/*
+ * atl1c_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ int old_mtu = netdev->mtu;
+ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+ if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+ (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+ return -EINVAL;
+ }
+ /* set MTU */
+ if (old_mtu != new_mtu && netif_running(netdev)) {
+ while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+ msleep(1);
+ netdev->mtu = new_mtu;
+ adapter->hw.max_frame_size = new_mtu;
+ atl1c_set_rxbufsize(adapter, netdev);
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
+ u32 phy_data;
+
+ AT_READ_REG(&adapter->hw, 0x1414, &phy_data);
+ phy_data |= 0x10000000;
+ AT_WRITE_REG(&adapter->hw, 0x1414, phy_data);
+ }
+
+ }
+ return 0;
+}
+
+/*
+ * caller should hold mdio_lock
+ */
+static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ u16 result;
+
+ atl1c_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result);
+ return result;
+}
+
+static void atl1c_mdio_write(struct net_device *netdev, int phy_id,
+ int reg_num, int val)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ atl1c_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val);
+}
+
+/*
+ * atl1c_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1c_mii_ioctl(struct net_device *netdev,
+ struct ifreq *ifr, int cmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ struct mii_ioctl_data *data = if_mii(ifr);
+ unsigned long flags;
+ int retval = 0;
+
+ if (!netif_running(netdev))
+ return -EINVAL;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ data->phy_id = 0;
+ break;
+
+ case SIOCGMIIREG:
+ if (!capable(CAP_NET_ADMIN)) {
+ retval = -EPERM;
+ goto out;
+ }
+ if (atl1c_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+ &data->val_out)) {
+ retval = -EIO;
+ goto out;
+ }
+ break;
+
+ case SIOCSMIIREG:
+ if (!capable(CAP_NET_ADMIN)) {
+ retval = -EPERM;
+ goto out;
+ }
+ if (data->reg_num & ~(0x1F)) {
+ retval = -EFAULT;
+ goto out;
+ }
+
+ dev_dbg(&pdev->dev, "<atl1c_mii_ioctl> write %x %x",
+ data->reg_num, data->val_in);
+ if (atl1c_write_phy_reg(&adapter->hw,
+ data->reg_num, data->val_in)) {
+ retval = -EIO;
+ goto out;
+ }
+ break;
+
+ default:
+ retval = -EOPNOTSUPP;
+ break;
+ }
+out:
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+ return retval;
+}
+
+/*
+ * atl1c_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1c_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ return atl1c_mii_ioctl(netdev, ifr, cmd);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+/*
+ * atl1c_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ */
+static int __devinit atl1c_alloc_queues(struct atl1c_adapter *adapter)
+{
+ return 0;
+}
+
+static void atl1c_set_mac_type(struct atl1c_hw *hw)
+{
+ switch (hw->device_id) {
+ case PCI_DEVICE_ID_ATTANSIC_L2C:
+ hw->nic_type = athr_l2c;
+ break;
+
+ case PCI_DEVICE_ID_ATTANSIC_L1C:
+ hw->nic_type = athr_l1c;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
+{
+ u32 phy_status_data;
+ u32 link_ctrl_data;
+
+ atl1c_set_mac_type(hw);
+ AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data);
+ AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
+
+ hw->ctrl_flags = ATL1C_INTR_CLEAR_ON_READ |
+ ATL1C_INTR_MODRT_ENABLE |
+ ATL1C_RX_IPV6_CHKSUM |
+ ATL1C_TXQ_MODE_ENHANCE;
+ if (link_ctrl_data & LINK_CTRL_L0S_EN)
+ hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT;
+ if (link_ctrl_data & LINK_CTRL_L1_EN)
+ hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT;
+
+ if (hw->nic_type == athr_l1c) {
+ hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON;
+ hw->ctrl_flags |= ATL1C_LINK_CAP_1000M;
+ }
+ return 0;
+}
+/*
+ * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl1c_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ */
+static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+
+ adapter->wol = 0;
+ adapter->link_speed = SPEED_0;
+ adapter->link_duplex = FULL_DUPLEX;
+ adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE;
+ adapter->tpd_ring[0].count = 1024;
+ adapter->rfd_ring[0].count = 512;
+
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_id = pdev->subsystem_device;
+
+ /* before link up, we assume hibernate is true */
+ hw->hibernate = true;
+ hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
+ if (atl1c_setup_mac_funcs(hw) != 0) {
+ dev_err(&pdev->dev, "set mac function pointers failed\n");
+ return -1;
+ }
+ hw->intr_mask = IMR_NORMAL_MASK;
+ hw->phy_configured = false;
+ hw->preamble_len = 7;
+ hw->max_frame_size = adapter->netdev->mtu;
+ if (adapter->num_rx_queues < 2) {
+ hw->rss_type = atl1c_rss_disable;
+ hw->rss_mode = atl1c_rss_mode_disable;
+ } else {
+ hw->rss_type = atl1c_rss_ipv4;
+ hw->rss_mode = atl1c_rss_mul_que_mul_int;
+ hw->rss_hash_bits = 16;
+ }
+ hw->autoneg_advertised = ADVERTISED_Autoneg;
+ hw->indirect_tab = 0xE4E4E4E4;
+ hw->base_cpu = 0;
+
+ hw->ict = 50000; /* 100ms */
+ hw->smb_timer = 200000; /* 400ms */
+ hw->cmb_tpd = 4;
+ hw->cmb_tx_timer = 1; /* 2 us */
+ hw->rx_imt = 200;
+ hw->tx_imt = 1000;
+
+ hw->tpd_burst = 5;
+ hw->rfd_burst = 8;
+ hw->dma_order = atl1c_dma_ord_out;
+ hw->dmar_block = atl1c_dma_req_1024;
+ hw->dmaw_block = atl1c_dma_req_1024;
+ hw->dmar_dly_cnt = 15;
+ hw->dmaw_dly_cnt = 4;
+
+ if (atl1c_alloc_queues(adapter)) {
+ dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+ return -ENOMEM;
+ }
+ /* TODO */
+ atl1c_set_rxbufsize(adapter, adapter->netdev);
+ atomic_set(&adapter->irq_sem, 1);
+ spin_lock_init(&adapter->mdio_lock);
+ spin_lock_init(&adapter->tx_lock);
+ set_bit(__AT_DOWN, &adapter->flags);
+
+ return 0;
+}
+
+/*
+ * atl1c_clean_tx_ring - Free Tx-skb
+ * @adapter: board private structure
+ */
+static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ struct atl1c_buffer *buffer_info;
+ struct pci_dev *pdev = adapter->pdev;
+ u16 index, ring_count;
+
+ ring_count = tpd_ring->count;
+ for (index = 0; index < ring_count; index++) {
+ buffer_info = &tpd_ring->buffer_info[index];
+ if (buffer_info->state == ATL1_BUFFER_FREE)
+ continue;
+ if (buffer_info->dma)
+ pci_unmap_single(pdev, buffer_info->dma,
+ buffer_info->length,
+ PCI_DMA_TODEVICE);
+ if (buffer_info->skb)
+ dev_kfree_skb(buffer_info->skb);
+ buffer_info->dma = 0;
+ buffer_info->skb = NULL;
+ buffer_info->state = ATL1_BUFFER_FREE;
+ }
+
+ /* Zero out Tx-buffers */
+ memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
+ ring_count);
+ atomic_set(&tpd_ring->next_to_clean, 0);
+ tpd_ring->next_to_use = 0;
+}
+
+/*
+ * atl1c_clean_rx_ring - Free rx-reservation skbs
+ * @adapter: board private structure
+ */
+static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
+{
+ struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+ struct atl1c_buffer *buffer_info;
+ struct pci_dev *pdev = adapter->pdev;
+ int i, j;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ for (j = 0; j < rfd_ring[i].count; j++) {
+ buffer_info = &rfd_ring[i].buffer_info[j];
+ if (buffer_info->state == ATL1_BUFFER_FREE)
+ continue;
+ if (buffer_info->dma)
+ pci_unmap_single(pdev, buffer_info->dma,
+ buffer_info->length,
+ PCI_DMA_FROMDEVICE);
+ if (buffer_info->skb)
+ dev_kfree_skb(buffer_info->skb);
+ buffer_info->state = ATL1_BUFFER_FREE;
+ buffer_info->skb = NULL;
+ }
+ /* zero out the descriptor ring */
+ memset(rfd_ring[i].desc, 0, rfd_ring[i].size);
+ rfd_ring[i].next_to_clean = 0;
+ rfd_ring[i].next_to_use = 0;
+ rrd_ring[i].next_to_use = 0;
+ rrd_ring[i].next_to_clean = 0;
+ }
+}
+
+/*
+ * Read / Write Ptr Initialize:
+ */
+static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
+{
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+ struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+ struct atl1c_buffer *buffer_info;
+ int i, j;
+
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].next_to_use = 0;
+ atomic_set(&tpd_ring[i].next_to_clean, 0);
+ buffer_info = tpd_ring[i].buffer_info;
+ for (j = 0; j < tpd_ring->count; j++)
+ buffer_info[i].state = ATL1_BUFFER_FREE;
+ }
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ rfd_ring[i].next_to_use = 0;
+ rfd_ring[i].next_to_clean = 0;
+ rrd_ring[i].next_to_use = 0;
+ rrd_ring[i].next_to_clean = 0;
+ for (j = 0; j < rfd_ring[i].count; j++) {
+ buffer_info = &rfd_ring[i].buffer_info[j];
+ buffer_info->state = ATL1_BUFFER_FREE;
+ }
+ }
+}
+
+/*
+ * atl1c_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl1c_free_ring_resources(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ pci_free_consistent(pdev, adapter->ring_header.size,
+ adapter->ring_header.desc,
+ adapter->ring_header.dma);
+ adapter->ring_header.desc = NULL;
+
+ /* Note: just free tdp_ring.buffer_info,
+ * it contain rfd_ring.buffer_info, do not double free */
+ if (adapter->tpd_ring[0].buffer_info) {
+ kfree(adapter->tpd_ring[0].buffer_info);
+ adapter->tpd_ring[0].buffer_info = NULL;
+ }
+}
+
+/*
+ * atl1c_setup_mem_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+ struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+ struct atl1c_ring_header *ring_header = &adapter->ring_header;
+ int num_rx_queues = adapter->num_rx_queues;
+ int size;
+ int i;
+ int count = 0;
+ int rx_desc_count = 0;
+ u32 offset = 0;
+
+ rrd_ring[0].count = rfd_ring[0].count;
+ for (i = 1; i < AT_MAX_TRANSMIT_QUEUE; i++)
+ tpd_ring[i].count = tpd_ring[0].count;
+
+ for (i = 1; i < adapter->num_rx_queues; i++)
+ rfd_ring[i].count = rrd_ring[i].count = rfd_ring[0].count;
+
+ /* 2 tpd queue, one high priority queue,
+ * another normal priority queue */
+ size = sizeof(struct atl1c_buffer) * (tpd_ring->count * 2 +
+ rfd_ring->count * num_rx_queues);
+ tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
+ if (unlikely(!tpd_ring->buffer_info)) {
+ dev_err(&pdev->dev, "kzalloc failed, size = %d\n",
+ size);
+ goto err_nomem;
+ }
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].buffer_info =
+ (struct atl1c_buffer *) (tpd_ring->buffer_info + count);
+ count += tpd_ring[i].count;
+ }
+
+ for (i = 0; i < num_rx_queues; i++) {
+ rfd_ring[i].buffer_info =
+ (struct atl1c_buffer *) (tpd_ring->buffer_info + count);
+ count += rfd_ring[i].count;
+ rx_desc_count += rfd_ring[i].count;
+ }
+ /*
+ * real ring DMA buffer
+ * each ring/block may need up to 8 bytes for alignment, hence the
+ * additional bytes tacked onto the end.
+ */
+ ring_header->size = size =
+ sizeof(struct atl1c_tpd_desc) * tpd_ring->count * 2 +
+ sizeof(struct atl1c_rx_free_desc) * rx_desc_count +
+ sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
+ sizeof(struct atl1c_hw_stats) +
+ 8 * 4 + 8 * 2 * num_rx_queues;
+
+ ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
+ &ring_header->dma);
+ if (unlikely(!ring_header->desc)) {
+ dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
+ goto err_nomem;
+ }
+ memset(ring_header->desc, 0, ring_header->size);
+ /* init TPD ring */
+
+ tpd_ring[0].dma = roundup(ring_header->dma, 8);
+ offset = tpd_ring[0].dma - ring_header->dma;
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].dma = ring_header->dma + offset;
+ tpd_ring[i].desc = (u8 *) ring_header->desc + offset;
+ tpd_ring[i].size =
+ sizeof(struct atl1c_tpd_desc) * tpd_ring[i].count;
+ offset += roundup(tpd_ring[i].size, 8);
+ }
+ /* init RFD ring */
+ for (i = 0; i < num_rx_queues; i++) {
+ rfd_ring[i].dma = ring_header->dma + offset;
+ rfd_ring[i].desc = (u8 *) ring_header->desc + offset;
+ rfd_ring[i].size = sizeof(struct atl1c_rx_free_desc) *
+ rfd_ring[i].count;
+ offset += roundup(rfd_ring[i].size, 8);
+ }
+
+ /* init RRD ring */
+ for (i = 0; i < num_rx_queues; i++) {
+ rrd_ring[i].dma = ring_header->dma + offset;
+ rrd_ring[i].desc = (u8 *) ring_header->desc + offset;
+ rrd_ring[i].size = sizeof(struct atl1c_recv_ret_status) *
+ rrd_ring[i].count;
+ offset += roundup(rrd_ring[i].size, 8);
+ }
+
+ adapter->smb.dma = ring_header->dma + offset;
+ adapter->smb.smb = (u8 *)ring_header->desc + offset;
+ return 0;
+
+err_nomem:
+ kfree(tpd_ring->buffer_info);
+ return -ENOMEM;
+}
+
+static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct atl1c_rfd_ring *rfd_ring = (struct atl1c_rfd_ring *)
+ adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = (struct atl1c_rrd_ring *)
+ adapter->rrd_ring;
+ struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
+ adapter->tpd_ring;
+ struct atl1c_cmb *cmb = (struct atl1c_cmb *) &adapter->cmb;
+ struct atl1c_smb *smb = (struct atl1c_smb *) &adapter->smb;
+ int i;
+
+ /* TPD */
+ AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI,
+ (u32)((tpd_ring[atl1c_trans_normal].dma &
+ AT_DMA_HI_ADDR_MASK) >> 32));
+ /* just enable normal priority TX queue */
+ AT_WRITE_REG(hw, REG_NTPD_HEAD_ADDR_LO,
+ (u32)(tpd_ring[atl1c_trans_normal].dma &
+ AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_HTPD_HEAD_ADDR_LO,
+ (u32)(tpd_ring[atl1c_trans_high].dma &
+ AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_TPD_RING_SIZE,
+ (u32)(tpd_ring[0].count & TPD_RING_SIZE_MASK));
+
+
+ /* RFD */
+ AT_WRITE_REG(hw, REG_RX_BASE_ADDR_HI,
+ (u32)((rfd_ring[0].dma & AT_DMA_HI_ADDR_MASK) >> 32));
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ AT_WRITE_REG(hw, atl1c_rfd_addr_lo_regs[i],
+ (u32)(rfd_ring[i].dma & AT_DMA_LO_ADDR_MASK));
+
+ AT_WRITE_REG(hw, REG_RFD_RING_SIZE,
+ rfd_ring[0].count & RFD_RING_SIZE_MASK);
+ AT_WRITE_REG(hw, REG_RX_BUF_SIZE,
+ adapter->rx_buffer_len & RX_BUF_SIZE_MASK);
+
+ /* RRD */
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ AT_WRITE_REG(hw, atl1c_rrd_addr_lo_regs[i],
+ (u32)(rrd_ring[i].dma & AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_RRD_RING_SIZE,
+ (rrd_ring[0].count & RRD_RING_SIZE_MASK));
+
+ /* CMB */
+ AT_WRITE_REG(hw, REG_CMB_BASE_ADDR_LO, cmb->dma & AT_DMA_LO_ADDR_MASK);
+
+ /* SMB */
+ AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_HI,
+ (u32)((smb->dma & AT_DMA_HI_ADDR_MASK) >> 32));
+ AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_LO,
+ (u32)(smb->dma & AT_DMA_LO_ADDR_MASK));
+ /* Load all of base address above */
+ AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
+}
+
+static void atl1c_configure_tx(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 dev_ctrl_data;
+ u32 max_pay_load;
+ u16 tx_offload_thresh;
+ u32 txq_ctrl_data;
+ u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */
+
+ extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
+ tx_offload_thresh = MAX_TX_OFFLOAD_THRESH;
+ AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
+ (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
+ AT_READ_REG(hw, REG_DEVICE_CTRL, &dev_ctrl_data);
+ max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) &
+ DEVICE_CTRL_MAX_PAYLOAD_MASK;
+ hw->dmaw_block = min(max_pay_load, hw->dmaw_block);
+ max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) &
+ DEVICE_CTRL_MAX_RREQ_SZ_MASK;
+ hw->dmar_block = min(max_pay_load, hw->dmar_block);
+
+ txq_ctrl_data = (hw->tpd_burst & TXQ_NUM_TPD_BURST_MASK) <<
+ TXQ_NUM_TPD_BURST_SHIFT;
+ if (hw->ctrl_flags & ATL1C_TXQ_MODE_ENHANCE)
+ txq_ctrl_data |= TXQ_CTRL_ENH_MODE;
+ txq_ctrl_data |= (atl1c_pay_load_size[hw->dmar_block] &
+ TXQ_TXF_BURST_NUM_MASK) << TXQ_TXF_BURST_NUM_SHIFT;
+
+ AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data);
+}
+
+static void atl1c_configure_rx(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 rxq_ctrl_data;
+
+ rxq_ctrl_data = (hw->rfd_burst & RXQ_RFD_BURST_NUM_MASK) <<
+ RXQ_RFD_BURST_NUM_SHIFT;
+
+ if (hw->ctrl_flags & ATL1C_RX_IPV6_CHKSUM)
+ rxq_ctrl_data |= IPV6_CHKSUM_CTRL_EN;
+ if (hw->rss_type == atl1c_rss_ipv4)
+ rxq_ctrl_data |= RSS_HASH_IPV4;
+ if (hw->rss_type == atl1c_rss_ipv4_tcp)
+ rxq_ctrl_data |= RSS_HASH_IPV4_TCP;
+ if (hw->rss_type == atl1c_rss_ipv6)
+ rxq_ctrl_data |= RSS_HASH_IPV6;
+ if (hw->rss_type == atl1c_rss_ipv6_tcp)
+ rxq_ctrl_data |= RSS_HASH_IPV6_TCP;
+ if (hw->rss_type != atl1c_rss_disable)
+ rxq_ctrl_data |= RRS_HASH_CTRL_EN;
+
+ rxq_ctrl_data |= (hw->rss_mode & RSS_MODE_MASK) <<
+ RSS_MODE_SHIFT;
+ rxq_ctrl_data |= (hw->rss_hash_bits & RSS_HASH_BITS_MASK) <<
+ RSS_HASH_BITS_SHIFT;
+ if (hw->ctrl_flags & ATL1C_ASPM_CTRL_MON)
+ rxq_ctrl_data |= (ASPM_THRUPUT_LIMIT_100M &
+ ASPM_THRUPUT_LIMIT_MASK) << ASPM_THRUPUT_LIMIT_SHIFT;
+
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
+}
+
+static void atl1c_configure_rss(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+
+ AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab);
+ AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu);
+}
+
+static void atl1c_configure_dma(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 dma_ctrl_data;
+
+ dma_ctrl_data = DMA_CTRL_DMAR_REQ_PRI;
+ if (hw->ctrl_flags & ATL1C_CMB_ENABLE)
+ dma_ctrl_data |= DMA_CTRL_CMB_EN;
+ if (hw->ctrl_flags & ATL1C_SMB_ENABLE)
+ dma_ctrl_data |= DMA_CTRL_SMB_EN;
+ else
+ dma_ctrl_data |= MAC_CTRL_SMB_DIS;
+
+ switch (hw->dma_order) {
+ case atl1c_dma_ord_in:
+ dma_ctrl_data |= DMA_CTRL_DMAR_IN_ORDER;
+ break;
+ case atl1c_dma_ord_enh:
+ dma_ctrl_data |= DMA_CTRL_DMAR_ENH_ORDER;
+ break;
+ case atl1c_dma_ord_out:
+ dma_ctrl_data |= DMA_CTRL_DMAR_OUT_ORDER;
+ break;
+ default:
+ break;
+ }
+
+ dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
+ << DMA_CTRL_DMAR_BURST_LEN_SHIFT;
+ dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
+ << DMA_CTRL_DMAW_BURST_LEN_SHIFT;
+ dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK)
+ << DMA_CTRL_DMAR_DLY_CNT_SHIFT;
+ dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK)
+ << DMA_CTRL_DMAW_DLY_CNT_SHIFT;
+
+ AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
+}
+
+/*
+ * Stop the mac, transmit and receive units
+ * hw - Struct containing variables accessed by shared code
+ * return : 0 or idle status (if error)
+ */
+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 |
+ RXQ3_CTRL_EN | RXQ_CTRL_EN);
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
+
+ AT_READ_REG(hw, REG_TXQ_CTRL, &data);
+ 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);
+ }
+
+ 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;
+}
+
+static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
+{
+ u32 data;
+
+ AT_READ_REG(hw, REG_RXQ_CTRL, &data);
+ switch (hw->adapter->num_rx_queues) {
+ case 4:
+ data |= (RXQ3_CTRL_EN | RXQ2_CTRL_EN | RXQ1_CTRL_EN);
+ break;
+ case 3:
+ data |= (RXQ2_CTRL_EN | RXQ1_CTRL_EN);
+ break;
+ case 2:
+ data |= RXQ1_CTRL_EN;
+ break;
+ default:
+ break;
+ }
+ data |= RXQ_CTRL_EN;
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
+}
+
+static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw)
+{
+ u32 data;
+
+ AT_READ_REG(hw, REG_TXQ_CTRL, &data);
+ data |= TXQ_CTRL_EN;
+ AT_WRITE_REG(hw, REG_TXQ_CTRL, data);
+}
+
+/*
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ * hw - Struct containing variables accessed by shared code
+ * return : 0 or idle status (if error)
+ */
+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);
+ AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT);
+
+ ret = atl1c_stop_mac(hw);
+ if (ret)
+ return ret;
+ /*
+ * Issue Soft Reset to the MAC. This will reset the chip's
+ * transmit, receive, DMA. It will not effect
+ * the current PCI configuration. The global reset bit is self-
+ * clearing, and should clear within a microsecond.
+ */
+ AT_WRITE_REGW(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST);
+ 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) {
+ dev_err(&pdev->dev,
+ "MAC state machine cann't be idle since"
+ " disabled for 10ms second\n");
+ return -1;
+ }
+ return 0;
+}
+
+static void atl1c_disable_l0s_l1(struct atl1c_hw *hw)
+{
+ u32 pm_ctrl_data;
+
+ AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
+ pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
+ PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+ pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+ pm_ctrl_data &= ~PM_CTRL_MAC_ASPM_CHK;
+ 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_PLL_L1_EN;
+ pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
+ AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
+}
+
+/*
+ * Set ASPM state.
+ * Enable/disable L0s/L1 depend on link state.
+ */
+static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
+{
+ u32 pm_ctrl_data;
+
+ 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_L1_ENTRY_TIMER_MASK <<
+ PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+
+ pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK;
+
+ if (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;
+
+ } else {
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+ 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 |= PM_CTRL_ASPM_L1_EN;
+ else
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+ }
+
+ AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
+}
+
+static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ u32 mac_ctrl_data;
+
+ mac_ctrl_data = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN;
+ mac_ctrl_data |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
+
+ if (adapter->link_duplex == FULL_DUPLEX) {
+ hw->mac_duplex = true;
+ mac_ctrl_data |= MAC_CTRL_DUPLX;
+ }
+
+ if (adapter->link_speed == SPEED_1000)
+ hw->mac_speed = atl1c_mac_speed_1000;
+ else
+ hw->mac_speed = atl1c_mac_speed_10_100;
+
+ mac_ctrl_data |= (hw->mac_speed & MAC_CTRL_SPEED_MASK) <<
+ MAC_CTRL_SPEED_SHIFT;
+
+ mac_ctrl_data |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+ mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) <<
+ MAC_CTRL_PRMLEN_SHIFT);
+
+ if (adapter->vlgrp)
+ mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+
+ mac_ctrl_data |= MAC_CTRL_BC_EN;
+ if (netdev->flags & IFF_PROMISC)
+ mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+ if (netdev->flags & IFF_ALLMULTI)
+ mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+
+ mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN;
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+}
+
+/*
+ * atl1c_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static int atl1c_configure(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 master_ctrl_data = 0;
+ u32 intr_modrt_data;
+
+ /* clear interrupt status */
+ AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF);
+ /* Clear any WOL status */
+ AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+ /* set Interrupt Clear Timer
+ * HW will enable self to assert interrupt event to system after
+ * waiting x-time for software to notify it accept interrupt.
+ */
+ AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER,
+ hw->ict & INT_RETRIG_TIMER_MASK);
+
+ atl1c_configure_des_ring(adapter);
+
+ if (hw->ctrl_flags & ATL1C_INTR_MODRT_ENABLE) {
+ intr_modrt_data = (hw->tx_imt & IRQ_MODRT_TIMER_MASK) <<
+ IRQ_MODRT_TX_TIMER_SHIFT;
+ intr_modrt_data |= (hw->rx_imt & IRQ_MODRT_TIMER_MASK) <<
+ IRQ_MODRT_RX_TIMER_SHIFT;
+ AT_WRITE_REG(hw, REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data);
+ master_ctrl_data |=
+ MASTER_CTRL_TX_ITIMER_EN | MASTER_CTRL_RX_ITIMER_EN;
+ }
+
+ if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ)
+ master_ctrl_data |= MASTER_CTRL_INT_RDCLR;
+
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+
+ if (hw->ctrl_flags & ATL1C_CMB_ENABLE) {
+ AT_WRITE_REG(hw, REG_CMB_TPD_THRESH,
+ hw->cmb_tpd & CMB_TPD_THRESH_MASK);
+ AT_WRITE_REG(hw, REG_CMB_TX_TIMER,
+ hw->cmb_tx_timer & CMB_TX_TIMER_MASK);
+ }
+
+ if (hw->ctrl_flags & ATL1C_SMB_ENABLE)
+ AT_WRITE_REG(hw, REG_SMB_STAT_TIMER,
+ hw->smb_timer & SMB_STAT_TIMER_MASK);
+ /* set MTU */
+ AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
+ VLAN_HLEN + ETH_FCS_LEN);
+ /* HDS, disable */
+ AT_WRITE_REG(hw, REG_HDS_CTRL, 0);
+
+ atl1c_configure_tx(adapter);
+ atl1c_configure_rx(adapter);
+ atl1c_configure_rss(adapter);
+ atl1c_configure_dma(adapter);
+
+ return 0;
+}
+
+static void atl1c_update_hw_stats(struct atl1c_adapter *adapter)
+{
+ u16 hw_reg_addr = 0;
+ unsigned long *stats_item = NULL;
+ u32 data;
+
+ /* update rx status */
+ hw_reg_addr = REG_MAC_RX_STATUS_BIN;
+ stats_item = &adapter->hw_stats.rx_ok;
+ while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
+ AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
+ *stats_item += data;
+ stats_item++;
+ hw_reg_addr += 4;
+ }
+/* update tx status */
+ hw_reg_addr = REG_MAC_TX_STATUS_BIN;
+ stats_item = &adapter->hw_stats.tx_ok;
+ while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
+ AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
+ *stats_item += data;
+ stats_item++;
+ hw_reg_addr += 4;
+ }
+}
+
+/*
+ * atl1c_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ */
+static struct net_device_stats *atl1c_get_stats(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw_stats *hw_stats = &adapter->hw_stats;
+ struct net_device_stats *net_stats = &adapter->net_stats;
+
+ atl1c_update_hw_stats(adapter);
+ net_stats->rx_packets = hw_stats->rx_ok;
+ net_stats->tx_packets = hw_stats->tx_ok;
+ net_stats->rx_bytes = hw_stats->rx_byte_cnt;
+ net_stats->tx_bytes = hw_stats->tx_byte_cnt;
+ net_stats->multicast = hw_stats->rx_mcast;
+ net_stats->collisions = hw_stats->tx_1_col +
+ hw_stats->tx_2_col * 2 +
+ hw_stats->tx_late_col + hw_stats->tx_abort_col;
+ net_stats->rx_errors = hw_stats->rx_frag + hw_stats->rx_fcs_err +
+ hw_stats->rx_len_err + hw_stats->rx_sz_ov +
+ hw_stats->rx_rrd_ov + hw_stats->rx_align_err;
+ net_stats->rx_fifo_errors = hw_stats->rx_rxf_ov;
+ net_stats->rx_length_errors = hw_stats->rx_len_err;
+ net_stats->rx_crc_errors = hw_stats->rx_fcs_err;
+ net_stats->rx_frame_errors = hw_stats->rx_align_err;
+ net_stats->rx_over_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+ net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+ net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
+ hw_stats->tx_underrun + hw_stats->tx_trunc;
+ net_stats->tx_fifo_errors = hw_stats->tx_underrun;
+ net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
+ net_stats->tx_window_errors = hw_stats->tx_late_col;
+
+ return &adapter->net_stats;
+}
+
+static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter)
+{
+ u16 phy_data;
+
+ spin_lock(&adapter->mdio_lock);
+ atl1c_read_phy_reg(&adapter->hw, MII_ISR, &phy_data);
+ spin_unlock(&adapter->mdio_lock);
+}
+
+static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
+ &adapter->tpd_ring[type];
+ struct atl1c_buffer *buffer_info;
+ u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+ u16 hw_next_to_clean;
+ u16 shift;
+ u32 data;
+
+ if (type == atl1c_trans_high)
+ shift = MB_HTPD_CONS_IDX_SHIFT;
+ else
+ shift = MB_NTPD_CONS_IDX_SHIFT;
+
+ AT_READ_REG(&adapter->hw, REG_MB_PRIO_CONS_IDX, &data);
+ hw_next_to_clean = (data >> shift) & MB_PRIO_PROD_IDX_MASK;
+
+ while (next_to_clean != hw_next_to_clean) {
+ buffer_info = &tpd_ring->buffer_info[next_to_clean];
+ if (buffer_info->state == ATL1_BUFFER_BUSY) {
+ pci_unmap_page(adapter->pdev, buffer_info->dma,
+ buffer_info->length, PCI_DMA_TODEVICE);
+ buffer_info->dma = 0;
+ if (buffer_info->skb) {
+ dev_kfree_skb_irq(buffer_info->skb);
+ buffer_info->skb = NULL;
+ }
+ buffer_info->state = ATL1_BUFFER_FREE;
+ }
+ if (++next_to_clean == tpd_ring->count)
+ next_to_clean = 0;
+ atomic_set(&tpd_ring->next_to_clean, next_to_clean);
+ }
+
+ if (netif_queue_stopped(adapter->netdev) &&
+ netif_carrier_ok(adapter->netdev)) {
+ netif_wake_queue(adapter->netdev);
+ }
+
+ return true;
+}
+
+/*
+ * atl1c_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
+ */
+static irqreturn_t atl1c_intr(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_hw *hw = &adapter->hw;
+ int max_ints = AT_MAX_INT_WORK;
+ int handled = IRQ_NONE;
+ u32 status;
+ u32 reg_data;
+
+ do {
+ AT_READ_REG(hw, REG_ISR, &reg_data);
+ status = reg_data & hw->intr_mask;
+
+ if (status == 0 || (status & ISR_DIS_INT) != 0) {
+ if (max_ints != AT_MAX_INT_WORK)
+ handled = IRQ_HANDLED;
+ break;
+ }
+ /* link event */
+ if (status & ISR_GPHY)
+ atl1c_clear_phy_int(adapter);
+ /* Ack ISR */
+ AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
+ if (status & ISR_RX_PKT) {
+ if (likely(napi_schedule_prep(&adapter->napi))) {
+ hw->intr_mask &= ~ISR_RX_PKT;
+ AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
+ __napi_schedule(&adapter->napi);
+ }
+ }
+ if (status & ISR_TX_PKT)
+ atl1c_clean_tx_irq(adapter, atl1c_trans_normal);
+
+ handled = IRQ_HANDLED;
+ /* check if PCIE PHY Link down */
+ if (status & ISR_ERROR) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "atl1c hardware error (status = 0x%x)\n",
+ status & ISR_ERROR);
+ /* reset MAC */
+ hw->intr_mask &= ~ISR_ERROR;
+ AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
+ schedule_work(&adapter->reset_task);
+ break;
+ }
+
+ if (status & ISR_OVER)
+ if (netif_msg_intr(adapter))
+ dev_warn(&pdev->dev,
+ "TX/RX over flow (status = 0x%x)\n",
+ status & ISR_OVER);
+
+ /* link event */
+ if (status & (ISR_GPHY | ISR_MANUAL)) {
+ adapter->net_stats.tx_carrier_errors++;
+ atl1c_link_chg_event(adapter);
+ break;
+ }
+
+ } while (--max_ints > 0);
+ /* re-enable Interrupt*/
+ AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+ return handled;
+}
+
+static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
+ struct sk_buff *skb, struct atl1c_recv_ret_status *prrs)
+{
+ /*
+ * The pid field in RRS in not correct sometimes, so we
+ * cannot figure out if the packet is fragmented or not,
+ * so we tell the KERNEL CHECKSUM_NONE
+ */
+ skb->ip_summed = CHECKSUM_NONE;
+}
+
+static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid)
+{
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[ringid];
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_buffer *buffer_info, *next_info;
+ struct sk_buff *skb;
+ void *vir_addr = NULL;
+ u16 num_alloc = 0;
+ u16 rfd_next_to_use, next_next;
+ struct atl1c_rx_free_desc *rfd_desc;
+
+ next_next = rfd_next_to_use = rfd_ring->next_to_use;
+ if (++next_next == rfd_ring->count)
+ next_next = 0;
+ buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+ next_info = &rfd_ring->buffer_info[next_next];
+
+ while (next_info->state == ATL1_BUFFER_FREE) {
+ rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
+
+ skb = dev_alloc_skb(adapter->rx_buffer_len);
+ if (unlikely(!skb)) {
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev, "alloc rx buffer failed\n");
+ break;
+ }
+
+ /*
+ * Make buffer alignment 2 beyond a 16 byte boundary
+ * this will result in a 16 byte aligned IP header after
+ * the 14 byte MAC header is removed
+ */
+ vir_addr = skb->data;
+ buffer_info->state = ATL1_BUFFER_BUSY;
+ buffer_info->skb = skb;
+ buffer_info->length = adapter->rx_buffer_len;
+ buffer_info->dma = pci_map_single(pdev, vir_addr,
+ buffer_info->length,
+ PCI_DMA_FROMDEVICE);
+ rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+ rfd_next_to_use = next_next;
+ if (++next_next == rfd_ring->count)
+ next_next = 0;
+ buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+ next_info = &rfd_ring->buffer_info[next_next];
+ num_alloc++;
+ }
+
+ if (num_alloc) {
+ /* TODO: update mailbox here */
+ wmb();
+ rfd_ring->next_to_use = rfd_next_to_use;
+ AT_WRITE_REG(&adapter->hw, atl1c_rfd_prod_idx_regs[ringid],
+ rfd_ring->next_to_use & MB_RFDX_PROD_IDX_MASK);
+ }
+
+ return num_alloc;
+}
+
+static void atl1c_clean_rrd(struct atl1c_rrd_ring *rrd_ring,
+ struct atl1c_recv_ret_status *rrs, u16 num)
+{
+ u16 i;
+ /* the relationship between rrd and rfd is one map one */
+ for (i = 0; i < num; i++, rrs = ATL1C_RRD_DESC(rrd_ring,
+ rrd_ring->next_to_clean)) {
+ rrs->word3 &= ~RRS_RXD_UPDATED;
+ if (++rrd_ring->next_to_clean == rrd_ring->count)
+ rrd_ring->next_to_clean = 0;
+ }
+}
+
+static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
+ struct atl1c_recv_ret_status *rrs, u16 num)
+{
+ u16 i;
+ u16 rfd_index;
+ struct atl1c_buffer *buffer_info = rfd_ring->buffer_info;
+
+ rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
+ RRS_RX_RFD_INDEX_MASK;
+ for (i = 0; i < num; i++) {
+ buffer_info[rfd_index].skb = NULL;
+ buffer_info[rfd_index].state = ATL1_BUFFER_FREE;
+ if (++rfd_index == rfd_ring->count)
+ rfd_index = 0;
+ }
+ rfd_ring->next_to_clean = rfd_index;
+}
+
+static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
+ int *work_done, int work_to_do)
+{
+ u16 rfd_num, rfd_index;
+ u16 count = 0;
+ u16 length;
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[que];
+ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[que];
+ struct sk_buff *skb;
+ struct atl1c_recv_ret_status *rrs;
+ struct atl1c_buffer *buffer_info;
+
+ while (1) {
+ if (*work_done >= work_to_do)
+ break;
+ rrs = ATL1C_RRD_DESC(rrd_ring, rrd_ring->next_to_clean);
+ if (likely(RRS_RXD_IS_VALID(rrs->word3))) {
+ rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) &
+ RRS_RX_RFD_CNT_MASK;
+ if (unlikely(rfd_num) != 1)
+ /* TODO support mul rfd*/
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "Multi rfd not support yet!\n");
+ goto rrs_checked;
+ } else {
+ break;
+ }
+rrs_checked:
+ atl1c_clean_rrd(rrd_ring, rrs, rfd_num);
+ if (rrs->word3 & (RRS_RX_ERR_SUM | RRS_802_3_LEN_ERR)) {
+ atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "wrong packet! rrs word3 is %x\n",
+ rrs->word3);
+ continue;
+ }
+
+ length = le16_to_cpu((rrs->word3 >> RRS_PKT_SIZE_SHIFT) &
+ RRS_PKT_SIZE_MASK);
+ /* Good Receive */
+ if (likely(rfd_num == 1)) {
+ rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
+ RRS_RX_RFD_INDEX_MASK;
+ buffer_info = &rfd_ring->buffer_info[rfd_index];
+ pci_unmap_single(pdev, buffer_info->dma,
+ buffer_info->length, PCI_DMA_FROMDEVICE);
+ skb = buffer_info->skb;
+ } else {
+ /* TODO */
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "Multi rfd not support yet!\n");
+ break;
+ }
+ atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+ skb_put(skb, length - ETH_FCS_LEN);
+ skb->protocol = eth_type_trans(skb, netdev);
+ skb->dev = netdev;
+ atl1c_rx_checksum(adapter, skb, rrs);
+ if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) {
+ u16 vlan;
+
+ AT_TAG_TO_VLAN(rrs->vlan_tag, vlan);
+ vlan = le16_to_cpu(vlan);
+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan);
+ } else
+ netif_receive_skb(skb);
+
+ netdev->last_rx = jiffies;
+ (*work_done)++;
+ count++;
+ }
+ if (count)
+ atl1c_alloc_rx_buffer(adapter, que);
+}
+
+/*
+ * atl1c_clean - NAPI Rx polling callback
+ * @adapter: board private structure
+ */
+static int atl1c_clean(struct napi_struct *napi, int budget)
+{
+ struct atl1c_adapter *adapter =
+ container_of(napi, struct atl1c_adapter, napi);
+ int work_done = 0;
+
+ /* Keep link state information with original netdev */
+ if (!netif_carrier_ok(adapter->netdev))
+ goto quit_polling;
+ /* just enable one RXQ */
+ atl1c_clean_rx_irq(adapter, 0, &work_done, budget);
+
+ if (work_done < budget) {
+quit_polling:
+ napi_complete(napi);
+ adapter->hw.intr_mask |= ISR_RX_PKT;
+ AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
+ }
+ return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void atl1c_netpoll(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ disable_irq(adapter->pdev->irq);
+ atl1c_intr(adapter->pdev->irq, netdev);
+ enable_irq(adapter->pdev->irq);
+}
+#endif
+
+static inline u16 atl1c_tpd_avail(struct atl1c_adapter *adapter, enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ u16 next_to_use = 0;
+ u16 next_to_clean = 0;
+
+ next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+ next_to_use = tpd_ring->next_to_use;
+
+ return (u16)(next_to_clean > next_to_use) ?
+ (next_to_clean - next_to_use - 1) :
+ (tpd_ring->count + next_to_clean - next_to_use - 1);
+}
+
+/*
+ * get next usable tpd
+ * Note: should call atl1c_tdp_avail to make sure
+ * there is enough tpd to use
+ */
+static struct atl1c_tpd_desc *atl1c_get_tpd(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ struct atl1c_tpd_desc *tpd_desc;
+ u16 next_to_use = 0;
+
+ next_to_use = tpd_ring->next_to_use;
+ if (++tpd_ring->next_to_use == tpd_ring->count)
+ tpd_ring->next_to_use = 0;
+ tpd_desc = ATL1C_TPD_DESC(tpd_ring, next_to_use);
+ memset(tpd_desc, 0, sizeof(struct atl1c_tpd_desc));
+ return tpd_desc;
+}
+
+static struct atl1c_buffer *
+atl1c_get_tx_buffer(struct atl1c_adapter *adapter, struct atl1c_tpd_desc *tpd)
+{
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+
+ return &tpd_ring->buffer_info[tpd -
+ (struct atl1c_tpd_desc *)tpd_ring->desc];
+}
+
+/* Calculate the transmit packet descript needed*/
+static u16 atl1c_cal_tpd_req(const struct sk_buff *skb)
+{
+ u16 tpd_req;
+ u16 proto_hdr_len = 0;
+
+ tpd_req = skb_shinfo(skb)->nr_frags + 1;
+
+ if (skb_is_gso(skb)) {
+ proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ if (proto_hdr_len < skb_headlen(skb))
+ tpd_req++;
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+ tpd_req++;
+ }
+ return tpd_req;
+}
+
+static int atl1c_tso_csum(struct atl1c_adapter *adapter,
+ struct sk_buff *skb,
+ struct atl1c_tpd_desc **tpd,
+ enum atl1c_trans_queue type)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ u8 hdr_len;
+ u32 real_len;
+ unsigned short offload_type;
+ int err;
+
+ if (skb_is_gso(skb)) {
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+ if (unlikely(err))
+ return -1;
+ }
+ offload_type = skb_shinfo(skb)->gso_type;
+
+ if (offload_type & SKB_GSO_TCPV4) {
+ real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
+ + ntohs(ip_hdr(skb)->tot_len));
+
+ if (real_len < skb->len)
+ pskb_trim(skb, real_len);
+
+ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+ if (unlikely(skb->len == hdr_len)) {
+ /* only xsum need */
+ if (netif_msg_tx_queued(adapter))
+ dev_warn(&pdev->dev,
+ "IPV4 tso with zero data??\n");
+ goto check_sum;
+ } else {
+ ip_hdr(skb)->check = 0;
+ tcp_hdr(skb)->check = ~csum_tcpudp_magic(
+ ip_hdr(skb)->saddr,
+ ip_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
+ (*tpd)->word1 |= 1 << TPD_IPV4_PACKET_SHIFT;
+ }
+ }
+
+ if (offload_type & SKB_GSO_TCPV6) {
+ struct atl1c_tpd_ext_desc *etpd =
+ *(struct atl1c_tpd_ext_desc **)(tpd);
+
+ memset(etpd, 0, sizeof(struct atl1c_tpd_ext_desc));
+ *tpd = atl1c_get_tpd(adapter, type);
+ ipv6_hdr(skb)->payload_len = 0;
+ /* check payload == 0 byte ? */
+ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+ if (unlikely(skb->len == hdr_len)) {
+ /* only xsum need */
+ if (netif_msg_tx_queued(adapter))
+ dev_warn(&pdev->dev,
+ "IPV6 tso with zero data??\n");
+ goto check_sum;
+ } else
+ tcp_hdr(skb)->check = ~csum_ipv6_magic(
+ &ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
+ etpd->word1 |= 1 << TPD_LSO_EN_SHIFT;
+ etpd->word1 |= 1 << TPD_LSO_VER_SHIFT;
+ etpd->pkt_len = cpu_to_le32(skb->len);
+ (*tpd)->word1 |= 1 << TPD_LSO_VER_SHIFT;
+ }
+
+ (*tpd)->word1 |= 1 << TPD_LSO_EN_SHIFT;
+ (*tpd)->word1 |= (skb_transport_offset(skb) & TPD_TCPHDR_OFFSET_MASK) <<
+ TPD_TCPHDR_OFFSET_SHIFT;
+ (*tpd)->word1 |= (skb_shinfo(skb)->gso_size & TPD_MSS_MASK) <<
+ TPD_MSS_SHIFT;
+ return 0;
+ }
+
+check_sum:
+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+ u8 css, cso;
+ cso = skb_transport_offset(skb);
+
+ if (unlikely(cso & 0x1)) {
+ if (netif_msg_tx_err(adapter))
+ dev_err(&adapter->pdev->dev,
+ "payload offset should not an event number\n");
+ return -1;
+ } else {
+ css = cso + skb->csum_offset;
+
+ (*tpd)->word1 |= ((cso >> 1) & TPD_PLOADOFFSET_MASK) <<
+ TPD_PLOADOFFSET_SHIFT;
+ (*tpd)->word1 |= ((css >> 1) & TPD_CCSUM_OFFSET_MASK) <<
+ TPD_CCSUM_OFFSET_SHIFT;
+ (*tpd)->word1 |= 1 << TPD_CCSUM_EN_SHIFT;
+ }
+ }
+ return 0;
+}
+
+static void atl1c_tx_map(struct atl1c_adapter *adapter,
+ struct sk_buff *skb, struct atl1c_tpd_desc *tpd,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_desc *use_tpd = NULL;
+ struct atl1c_buffer *buffer_info = NULL;
+ u16 buf_len = skb_headlen(skb);
+ u16 map_len = 0;
+ u16 mapped_len = 0;
+ u16 hdr_len = 0;
+ u16 nr_frags;
+ u16 f;
+ int tso;
+
+ nr_frags = skb_shinfo(skb)->nr_frags;
+ tso = (tpd->word1 >> TPD_LSO_EN_SHIFT) & TPD_LSO_EN_MASK;
+ if (tso) {
+ /* TSO */
+ map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ use_tpd = tpd;
+
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = map_len;
+ buffer_info->dma = pci_map_single(adapter->pdev,
+ skb->data, hdr_len, PCI_DMA_TODEVICE);
+ buffer_info->state = ATL1_BUFFER_BUSY;
+ mapped_len += map_len;
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ if (mapped_len < buf_len) {
+ /* mapped_len == 0, means we should use the first tpd,
+ which is given by caller */
+ if (mapped_len == 0)
+ use_tpd = tpd;
+ else {
+ use_tpd = atl1c_get_tpd(adapter, type);
+ memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+ use_tpd = atl1c_get_tpd(adapter, type);
+ memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+ }
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = buf_len - mapped_len;
+ buffer_info->dma =
+ pci_map_single(adapter->pdev, skb->data + mapped_len,
+ buffer_info->length, PCI_DMA_TODEVICE);
+ buffer_info->state = ATL1_BUFFER_BUSY;
+
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ for (f = 0; f < nr_frags; f++) {
+ struct skb_frag_struct *frag;
+
+ frag = &skb_shinfo(skb)->frags[f];
+
+ use_tpd = atl1c_get_tpd(adapter, type);
+ memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = frag->size;
+ buffer_info->dma =
+ pci_map_page(adapter->pdev, frag->page,
+ frag->page_offset,
+ buffer_info->length,
+ PCI_DMA_TODEVICE);
+ buffer_info->state = ATL1_BUFFER_BUSY;
+
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ /* The last tpd */
+ use_tpd->word1 |= 1 << TPD_EOP_SHIFT;
+ /* The last buffer info contain the skb address,
+ so it will be free after unmap */
+ buffer_info->skb = skb;
+}
+
+static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
+ struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ u32 prod_data;
+
+ AT_READ_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, &prod_data);
+ switch (type) {
+ case atl1c_trans_high:
+ prod_data &= 0xFFFF0000;
+ prod_data |= tpd_ring->next_to_use & 0xFFFF;
+ break;
+ case atl1c_trans_normal:
+ prod_data &= 0x0000FFFF;
+ prod_data |= (tpd_ring->next_to_use & 0xFFFF) << 16;
+ break;
+ default:
+ break;
+ }
+ wmb();
+ AT_WRITE_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, prod_data);
+}
+
+static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ unsigned long flags;
+ u16 tpd_req = 1;
+ struct atl1c_tpd_desc *tpd;
+ enum atl1c_trans_queue type = atl1c_trans_normal;
+
+ if (test_bit(__AT_DOWN, &adapter->flags)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ tpd_req = atl1c_cal_tpd_req(skb);
+ if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
+ if (netif_msg_pktdata(adapter))
+ dev_info(&adapter->pdev->dev, "tx locked\n");
+ return NETDEV_TX_LOCKED;
+ }
+ if (skb->mark == 0x01)
+ type = atl1c_trans_high;
+ else
+ type = atl1c_trans_normal;
+
+ if (atl1c_tpd_avail(adapter, type) < tpd_req) {
+ /* no enough descriptor, just stop queue */
+ netif_stop_queue(netdev);
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+ tpd = atl1c_get_tpd(adapter, type);
+
+ /* do TSO and check sum */
+ if (atl1c_tso_csum(adapter, skb, &tpd, type) != 0) {
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+ u16 vlan = vlan_tx_tag_get(skb);
+ __le16 tag;
+
+ vlan = cpu_to_le16(vlan);
+ AT_VLAN_TO_TAG(vlan, tag);
+ tpd->word1 |= 1 << TPD_INS_VTAG_SHIFT;
+ tpd->vlan_tag = tag;
+ }
+
+ if (skb_network_offset(skb) != ETH_HLEN)
+ tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */
+
+ 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;
+}
+
+static void atl1c_free_irq(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ free_irq(adapter->pdev->irq, netdev);
+
+ if (adapter->have_msi)
+ pci_disable_msi(adapter->pdev);
+}
+
+static int atl1c_request_irq(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
+ int flags = 0;
+ int err = 0;
+
+ adapter->have_msi = true;
+ err = pci_enable_msi(adapter->pdev);
+ if (err) {
+ if (netif_msg_ifup(adapter))
+ dev_err(&pdev->dev,
+ "Unable to allocate MSI interrupt Error: %d\n",
+ err);
+ adapter->have_msi = false;
+ } else
+ netdev->irq = pdev->irq;
+
+ if (!adapter->have_msi)
+ flags |= IRQF_SHARED;
+ err = request_irq(adapter->pdev->irq, &atl1c_intr, flags,
+ netdev->name, netdev);
+ if (err) {
+ if (netif_msg_ifup(adapter))
+ dev_err(&pdev->dev,
+ "Unable to allocate interrupt Error: %d\n",
+ err);
+ if (adapter->have_msi)
+ pci_disable_msi(adapter->pdev);
+ return err;
+ }
+ if (netif_msg_ifup(adapter))
+ dev_dbg(&pdev->dev, "atl1c_request_irq OK\n");
+ return err;
+}
+
+int atl1c_up(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int num;
+ int err;
+ int i;
+
+ netif_carrier_off(netdev);
+ atl1c_init_ring_ptrs(adapter);
+ atl1c_set_multi(netdev);
+ atl1c_restore_vlan(adapter);
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ num = atl1c_alloc_rx_buffer(adapter, i);
+ if (unlikely(num == 0)) {
+ err = -ENOMEM;
+ goto err_alloc_rx;
+ }
+ }
+
+ if (atl1c_configure(adapter)) {
+ err = -EIO;
+ goto err_up;
+ }
+
+ err = atl1c_request_irq(adapter);
+ if (unlikely(err))
+ goto err_up;
+
+ clear_bit(__AT_DOWN, &adapter->flags);
+ napi_enable(&adapter->napi);
+ atl1c_irq_enable(adapter);
+ atl1c_check_link_status(adapter);
+ netif_start_queue(netdev);
+ return err;
+
+err_up:
+err_alloc_rx:
+ atl1c_clean_rx_ring(adapter);
+ return err;
+}
+
+void atl1c_down(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ atl1c_del_timer(adapter);
+ atl1c_cancel_work(adapter);
+
+ /* signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer */
+ set_bit(__AT_DOWN, &adapter->flags);
+ netif_carrier_off(netdev);
+ napi_disable(&adapter->napi);
+ atl1c_irq_disable(adapter);
+ atl1c_free_irq(adapter);
+ AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT);
+ /* reset MAC to disable all RX/TX */
+ atl1c_reset_mac(&adapter->hw);
+ msleep(1);
+
+ adapter->link_speed = SPEED_0;
+ adapter->link_duplex = -1;
+ atl1c_clean_tx_ring(adapter, atl1c_trans_normal);
+ atl1c_clean_tx_ring(adapter, atl1c_trans_high);
+ atl1c_clean_rx_ring(adapter);
+}
+
+/*
+ * atl1c_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP). At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ */
+static int atl1c_open(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ int err;
+
+ /* disallow open during test */
+ if (test_bit(__AT_TESTING, &adapter->flags))
+ return -EBUSY;
+
+ /* allocate rx/tx dma buffer & descriptors */
+ err = atl1c_setup_ring_resources(adapter);
+ if (unlikely(err))
+ return err;
+
+ err = atl1c_up(adapter);
+ if (unlikely(err))
+ goto err_up;
+
+ if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
+ u32 phy_data;
+
+ AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data);
+ phy_data |= MDIO_AP_EN;
+ AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data);
+ }
+ return 0;
+
+err_up:
+ atl1c_free_irq(adapter);
+ atl1c_free_ring_resources(adapter);
+ atl1c_reset_mac(&adapter->hw);
+ return err;
+}
+
+/*
+ * atl1c_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS. The hardware is still under the drivers control, but
+ * needs to be disabled. A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ */
+static int atl1c_close(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+ atl1c_down(adapter);
+ atl1c_free_ring_resources(adapter);
+ return 0;
+}
+
+static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 ctrl;
+ u32 mac_ctrl_data;
+ u32 master_ctrl_data;
+ u32 wol_ctrl_data;
+ u16 mii_bmsr_data;
+ u16 save_autoneg_advertised;
+ u16 mii_intr_status_data;
+ u32 wufc = adapter->wol;
+ u32 i;
+ int retval = 0;
+
+ if (netif_running(netdev)) {
+ WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+ atl1c_down(adapter);
+ }
+ netif_device_detach(netdev);
+ atl1c_disable_l0s_l1(hw);
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
+ if (wufc) {
+ AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
+ master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS;
+
+ /* get link status */
+ atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+ atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+ save_autoneg_advertised = hw->autoneg_advertised;
+ hw->autoneg_advertised = ADVERTISED_10baseT_Half;
+ if (atl1c_restart_autoneg(hw) != 0)
+ if (netif_msg_link(adapter))
+ dev_warn(&pdev->dev, "phy autoneg failed\n");
+ hw->phy_configured = false; /* re-init PHY when resume */
+ hw->autoneg_advertised = save_autoneg_advertised;
+ /* turn on magic packet wol */
+ if (wufc & AT_WUFC_MAG)
+ wol_ctrl_data = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+
+ if (wufc & AT_WUFC_LNKC) {
+ for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
+ msleep(100);
+ atl1c_read_phy_reg(hw, MII_BMSR,
+ (u16 *)&mii_bmsr_data);
+ if (mii_bmsr_data & BMSR_LSTATUS)
+ break;
+ }
+ if ((mii_bmsr_data & BMSR_LSTATUS) == 0)
+ if (netif_msg_link(adapter))
+ dev_warn(&pdev->dev,
+ "%s: Link may change"
+ "when suspend\n",
+ atl1c_driver_name);
+ wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
+ /* only link up can wake up */
+ if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev,
+ "%s: read write phy "
+ "register failed.\n",
+ atl1c_driver_name);
+ goto wol_dis;
+ }
+ }
+ /* clear phy interrupt */
+ atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data);
+ /* Config MAC Ctrl register */
+ mac_ctrl_data = MAC_CTRL_RX_EN;
+ /* set to 10/100M halt duplex */
+ mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT;
+ mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
+ MAC_CTRL_PRMLEN_MASK) <<
+ MAC_CTRL_PRMLEN_SHIFT);
+
+ if (adapter->vlgrp)
+ mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+
+ /* magic packet maybe Broadcast&multicast&Unicast frame */
+ if (wufc & AT_WUFC_MAG)
+ mac_ctrl_data |= MAC_CTRL_BC_EN;
+
+ if (netif_msg_hw(adapter))
+ dev_dbg(&pdev->dev,
+ "%s: suspend MAC=0x%x\n",
+ atl1c_driver_name, mac_ctrl_data);
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+ AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+ /* pcie patch */
+ AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl);
+ ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+ AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+ goto suspend_exit;
+ }
+wol_dis:
+
+ /* WOL disabled */
+ AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+ /* pcie patch */
+ AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl);
+ ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+ AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+
+ atl1c_phy_disable(hw);
+ hw->phy_configured = false; /* re-init PHY when resume */
+
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+suspend_exit:
+
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int atl1c_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
+
+ atl1c_phy_reset(&adapter->hw);
+ atl1c_reset_mac(&adapter->hw);
+ netif_device_attach(netdev);
+ if (netif_running(netdev))
+ atl1c_up(adapter);
+
+ return 0;
+}
+
+static void atl1c_shutdown(struct pci_dev *pdev)
+{
+ atl1c_suspend(pdev, PMSG_SUSPEND);
+}
+
+static const struct net_device_ops atl1c_netdev_ops = {
+ .ndo_open = atl1c_open,
+ .ndo_stop = atl1c_close,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_start_xmit = atl1c_xmit_frame,
+ .ndo_set_mac_address = atl1c_set_mac_addr,
+ .ndo_set_multicast_list = atl1c_set_multi,
+ .ndo_change_mtu = atl1c_change_mtu,
+ .ndo_do_ioctl = atl1c_ioctl,
+ .ndo_tx_timeout = atl1c_tx_timeout,
+ .ndo_get_stats = atl1c_get_stats,
+ .ndo_vlan_rx_register = atl1c_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl1c_netpoll,
+#endif
+};
+
+static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
+{
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ pci_set_drvdata(pdev, netdev);
+
+ netdev->irq = pdev->irq;
+ netdev->netdev_ops = &atl1c_netdev_ops;
+ netdev->watchdog_timeo = AT_TX_WATCHDOG;
+ atl1c_set_ethtool_ops(netdev);
+
+ /* TODO: add when ready */
+ netdev->features = NETIF_F_SG |
+ NETIF_F_HW_CSUM |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_TSO |
+ NETIF_F_TSO6;
+ return 0;
+}
+
+/*
+ * atl1c_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl1c_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl1c_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ */
+static int __devinit atl1c_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct net_device *netdev;
+ struct atl1c_adapter *adapter;
+ static int cards_found;
+
+ int err = 0;
+
+ /* enable device (incl. PCI PM wakeup and hotplug setup) */
+ err = pci_enable_device_mem(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
+ return err;
+ }
+
+ /*
+ * The atl1c chip can DMA to 64-bit addresses, but it uses a single
+ * shared register for the high 32 bits, so only a single, aligned,
+ * 4 GB physical address range can be used at a time.
+ *
+ * Supporting 64-bit DMA on this hardware is more trouble than it's
+ * worth. It is far easier to limit to 32-bit DMA than update
+ * various kernel subsystems to support the mechanics required by a
+ * fixed-high-32-bit system.
+ */
+ if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
+ (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+ dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
+ goto err_dma;
+ }
+
+ err = pci_request_regions(pdev, atl1c_driver_name);
+ if (err) {
+ dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+ goto err_pci_reg;
+ }
+
+ pci_set_master(pdev);
+
+ netdev = alloc_etherdev(sizeof(struct atl1c_adapter));
+ if (netdev == NULL) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "etherdev alloc failed\n");
+ goto err_alloc_etherdev;
+ }
+
+ err = atl1c_init_netdev(netdev, pdev);
+ if (err) {
+ dev_err(&pdev->dev, "init netdevice failed\n");
+ goto err_init_netdev;
+ }
+ adapter = netdev_priv(netdev);
+ adapter->bd_number = cards_found;
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->hw.adapter = adapter;
+ adapter->msg_enable = netif_msg_init(-1, atl1c_default_msg);
+ adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+ if (!adapter->hw.hw_addr) {
+ err = -EIO;
+ dev_err(&pdev->dev, "cannot map device registers\n");
+ goto err_ioremap;
+ }
+ netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
+
+ /* init mii data */
+ adapter->mii.dev = netdev;
+ adapter->mii.mdio_read = atl1c_mdio_read;
+ adapter->mii.mdio_write = atl1c_mdio_write;
+ adapter->mii.phy_id_mask = 0x1f;
+ adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
+ netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64);
+ setup_timer(&adapter->phy_config_timer, atl1c_phy_config,
+ (unsigned long)adapter);
+ /* setup the private structure */
+ err = atl1c_sw_init(adapter);
+ if (err) {
+ dev_err(&pdev->dev, "net device private data init failed\n");
+ goto err_sw_init;
+ }
+ atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
+ ATL1C_PCIE_PHY_RESET);
+
+ /* Init GPHY as early as possible due to power saving issue */
+ atl1c_phy_reset(&adapter->hw);
+
+ err = atl1c_reset_mac(&adapter->hw);
+ if (err) {
+ err = -EIO;
+ goto err_reset;
+ }
+
+ device_init_wakeup(&pdev->dev, 1);
+ /* reset the controller to
+ * put the device in a known good starting state */
+ err = atl1c_phy_init(&adapter->hw);
+ if (err) {
+ err = -EIO;
+ goto err_reset;
+ }
+ if (atl1c_read_mac_addr(&adapter->hw) != 0) {
+ err = -EIO;
+ dev_err(&pdev->dev, "get mac address failed\n");
+ goto err_eeprom;
+ }
+ memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+ memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
+ if (netif_msg_probe(adapter))
+ dev_dbg(&pdev->dev,
+ "mac address : %02x-%02x-%02x-%02x-%02x-%02x\n",
+ adapter->hw.mac_addr[0], adapter->hw.mac_addr[1],
+ adapter->hw.mac_addr[2], adapter->hw.mac_addr[3],
+ adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]);
+
+ atl1c_hw_set_mac_addr(&adapter->hw);
+ INIT_WORK(&adapter->reset_task, atl1c_reset_task);
+ INIT_WORK(&adapter->link_chg_task, atl1c_link_chg_task);
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(&pdev->dev, "register netdevice failed\n");
+ goto err_register;
+ }
+
+ if (netif_msg_probe(adapter))
+ dev_info(&pdev->dev, "version %s\n", ATL1C_DRV_VERSION);
+ cards_found++;
+ return 0;
+
+err_reset:
+err_register:
+err_sw_init:
+err_eeprom:
+ iounmap(adapter->hw.hw_addr);
+err_init_netdev:
+err_ioremap:
+ free_netdev(netdev);
+err_alloc_etherdev:
+ pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+ pci_disable_device(pdev);
+ return err;
+}
+
+/*
+ * atl1c_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl1c_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device. The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ */
+static void __devexit atl1c_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ unregister_netdev(netdev);
+ atl1c_phy_disable(&adapter->hw);
+
+ iounmap(adapter->hw.hw_addr);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ free_netdev(netdev);
+}
+
+/*
+ * atl1c_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev))
+ atl1c_down(adapter);
+
+ pci_disable_device(pdev);
+
+ /* Request a slot slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/*
+ * atl1c_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the e1000_resume routine.
+ */
+static pci_ers_result_t atl1c_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (pci_enable_device(pdev)) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Cannot re-enable PCI device after reset\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ atl1c_reset_mac(&adapter->hw);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/*
+ * atl1c_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the atl1c_resume routine.
+ */
+static void atl1c_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (netif_running(netdev)) {
+ if (atl1c_up(adapter)) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Cannot bring device back up after reset\n");
+ return;
+ }
+ }
+
+ netif_device_attach(netdev);
+}
+
+static struct pci_error_handlers atl1c_err_handler = {
+ .error_detected = atl1c_io_error_detected,
+ .slot_reset = atl1c_io_slot_reset,
+ .resume = atl1c_io_resume,
+};
+
+static struct pci_driver atl1c_driver = {
+ .name = atl1c_driver_name,
+ .id_table = atl1c_pci_tbl,
+ .probe = atl1c_probe,
+ .remove = __devexit_p(atl1c_remove),
+ /* Power Managment Hooks */
+ .suspend = atl1c_suspend,
+ .resume = atl1c_resume,
+ .shutdown = atl1c_shutdown,
+ .err_handler = &atl1c_err_handler
+};
+
+/*
+ * atl1c_init_module - Driver Registration Routine
+ *
+ * atl1c_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ */
+static int __init atl1c_init_module(void)
+{
+ return pci_register_driver(&atl1c_driver);
+}
+
+/*
+ * atl1c_exit_module - Driver Exit Cleanup Routine
+ *
+ * atl1c_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit atl1c_exit_module(void)
+{
+ pci_unregister_driver(&atl1c_driver);
+}
+
+module_init(atl1c_init_module);
+module_exit(atl1c_exit_module);
diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h
index c49550d507a..2bf63b4368e 100644
--- a/drivers/net/atl1e/atl1e.h
+++ b/drivers/net/atl1e/atl1e.h
@@ -448,7 +448,7 @@ struct atl1e_adapter {
/* All Descriptor memory */
dma_addr_t ring_dma;
void *ring_vir_addr;
- int ring_size;
+ u32 ring_size;
struct atl1e_tx_ring tx_ring;
struct atl1e_rx_ring rx_ring;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index bb9094d4cbc..c758884728a 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1326,9 +1326,9 @@ static irqreturn_t atl1e_intr(int irq, void *data)
AT_WRITE_REG(hw, REG_IMR,
IMR_NORMAL_MASK & ~ISR_RX_EVENT);
AT_WRITE_FLUSH(hw);
- if (likely(netif_rx_schedule_prep(
+ if (likely(napi_schedule_prep(
&adapter->napi)))
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
} while (--max_ints > 0);
/* re-enable Interrupt*/
@@ -1514,7 +1514,7 @@ static int atl1e_clean(struct napi_struct *napi, int budget)
/* If no Tx and not enough Rx work done, exit the polling mode */
if (work_done < budget) {
quit_polling:
- netif_rx_complete(napi);
+ napi_complete(napi);
imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
/* test debug */
diff --git a/drivers/net/atl1e/atl1e_param.c b/drivers/net/atl1e/atl1e_param.c
index f72abb34b0c..b3be59fd3fb 100644
--- a/drivers/net/atl1e/atl1e_param.c
+++ b/drivers/net/atl1e/atl1e_param.c
@@ -41,7 +41,7 @@
#define ATL1E_PARAM(x, desc) \
static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
- static int num_##x; \
+ static unsigned int num_##x; \
module_param_array_named(x, x, int, &num_##x, 0); \
MODULE_PARM_DESC(x, desc);
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index c0ceee0d7c8..43fc1b2ca3c 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -105,7 +105,7 @@
* Default Value: 100 (200us)
*/
static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
-static int num_int_mod_timer;
+static unsigned int num_int_mod_timer;
module_param_array_named(int_mod_timer, int_mod_timer, int,
&num_int_mod_timer, 0);
MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index bc394491b63..9fe06c3f409 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -2854,7 +2854,7 @@ static void atl2_force_ps(struct atl2_hw *hw)
#else
#define ATL2_PARAM(X, desc) \
static int __devinitdata X[ATL2_MAX_NIC+1] = ATL2_PARAM_INIT; \
- static int num_##X = 0; \
+ static unsigned int num_##X; \
module_param_array_named(X, X, int, &num_##X, 0); \
MODULE_PARM_DESC(X, desc);
#endif
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 9c875bb3f76..4274e4ac963 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -81,24 +81,6 @@ MODULE_AUTHOR(DRV_AUTHOR);
MODULE_DESCRIPTION(DRV_DESC);
MODULE_LICENSE("GPL");
-// prototypes
-static void hard_stop(struct net_device *);
-static void enable_rx_tx(struct net_device *dev);
-static struct net_device * au1000_probe(int port_num);
-static int au1000_init(struct net_device *);
-static int au1000_open(struct net_device *);
-static int au1000_close(struct net_device *);
-static int au1000_tx(struct sk_buff *, struct net_device *);
-static int au1000_rx(struct net_device *);
-static irqreturn_t au1000_interrupt(int, void *);
-static void au1000_tx_timeout(struct net_device *);
-static void set_rx_mode(struct net_device *);
-static int au1000_ioctl(struct net_device *, struct ifreq *, int);
-static int au1000_mdio_read(struct net_device *, int, int);
-static void au1000_mdio_write(struct net_device *, int, int, u16);
-static void au1000_adjust_link(struct net_device *);
-static void enable_mac(struct net_device *, int);
-
/*
* Theory of operation
*
@@ -188,6 +170,26 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
# error MAC0-associated PHY attached 2nd MACs MII bus not supported yet
#endif
+static void enable_mac(struct net_device *dev, int force_reset)
+{
+ unsigned long flags;
+ struct au1000_private *aup = netdev_priv(dev);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ if(force_reset || (!aup->mac_enabled)) {
+ *aup->enable = MAC_EN_CLOCK_ENABLE;
+ au_sync_delay(2);
+ *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
+ | MAC_EN_CLOCK_ENABLE);
+ au_sync_delay(2);
+
+ aup->mac_enabled = 1;
+ }
+
+ spin_unlock_irqrestore(&aup->lock, flags);
+}
+
/*
* MII operations
*/
@@ -281,6 +283,107 @@ static int au1000_mdiobus_reset(struct mii_bus *bus)
return 0;
}
+static void hard_stop(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+
+ if (au1000_debug > 4)
+ printk(KERN_INFO "%s: hard stop\n", dev->name);
+
+ aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+ au_sync_delay(10);
+}
+
+static void enable_rx_tx(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+
+ if (au1000_debug > 4)
+ printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
+
+ aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+ au_sync_delay(10);
+}
+
+static void
+au1000_adjust_link(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct phy_device *phydev = aup->phy_dev;
+ unsigned long flags;
+
+ int status_change = 0;
+
+ BUG_ON(!aup->phy_dev);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ if (phydev->link && (aup->old_speed != phydev->speed)) {
+ // speed changed
+
+ switch(phydev->speed) {
+ case SPEED_10:
+ case SPEED_100:
+ break;
+ default:
+ printk(KERN_WARNING
+ "%s: Speed (%d) is not 10/100 ???\n",
+ dev->name, phydev->speed);
+ break;
+ }
+
+ aup->old_speed = phydev->speed;
+
+ status_change = 1;
+ }
+
+ if (phydev->link && (aup->old_duplex != phydev->duplex)) {
+ // duplex mode changed
+
+ /* switching duplex mode requires to disable rx and tx! */
+ hard_stop(dev);
+
+ if (DUPLEX_FULL == phydev->duplex)
+ aup->mac->control = ((aup->mac->control
+ | MAC_FULL_DUPLEX)
+ & ~MAC_DISABLE_RX_OWN);
+ else
+ aup->mac->control = ((aup->mac->control
+ & ~MAC_FULL_DUPLEX)
+ | MAC_DISABLE_RX_OWN);
+ au_sync_delay(1);
+
+ enable_rx_tx(dev);
+ aup->old_duplex = phydev->duplex;
+
+ status_change = 1;
+ }
+
+ if(phydev->link != aup->old_link) {
+ // link state changed
+
+ if (!phydev->link) {
+ /* link went down */
+ aup->old_speed = 0;
+ aup->old_duplex = -1;
+ }
+
+ aup->old_link = phydev->link;
+ status_change = 1;
+ }
+
+ spin_unlock_irqrestore(&aup->lock, flags);
+
+ if (status_change) {
+ if (phydev->link)
+ printk(KERN_INFO "%s: link up (%d/%s)\n",
+ dev->name, phydev->speed,
+ DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
+ else
+ printk(KERN_INFO "%s: link down\n", dev->name);
+ }
+}
+
static int mii_probe (struct net_device *dev)
{
struct au1000_private *const aup = netdev_priv(dev);
@@ -355,8 +458,8 @@ static int mii_probe (struct net_device *dev)
/* now we are supposed to have a proper phydev, to attach to... */
BUG_ON(phydev->attached_dev);
- phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &au1000_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
@@ -381,8 +484,8 @@ static int mii_probe (struct net_device *dev)
aup->phy_dev = phydev;
printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
return 0;
}
@@ -412,48 +515,6 @@ void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
aup->pDBfree = pDB;
}
-static void enable_rx_tx(struct net_device *dev)
-{
- struct au1000_private *aup = netdev_priv(dev);
-
- if (au1000_debug > 4)
- printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
-
- aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
- au_sync_delay(10);
-}
-
-static void hard_stop(struct net_device *dev)
-{
- struct au1000_private *aup = netdev_priv(dev);
-
- if (au1000_debug > 4)
- printk(KERN_INFO "%s: hard stop\n", dev->name);
-
- aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
- au_sync_delay(10);
-}
-
-static void enable_mac(struct net_device *dev, int force_reset)
-{
- unsigned long flags;
- struct au1000_private *aup = netdev_priv(dev);
-
- spin_lock_irqsave(&aup->lock, flags);
-
- if(force_reset || (!aup->mac_enabled)) {
- *aup->enable = MAC_EN_CLOCK_ENABLE;
- au_sync_delay(2);
- *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
- | MAC_EN_CLOCK_ENABLE);
- au_sync_delay(2);
-
- aup->mac_enabled = 1;
- }
-
- spin_unlock_irqrestore(&aup->lock, flags);
-}
-
static void reset_mac_unlocked(struct net_device *dev)
{
struct au1000_private *const aup = netdev_priv(dev);
@@ -542,30 +603,6 @@ static struct {
static int num_ifs;
/*
- * Setup the base address and interrupt of the Au1xxx ethernet macs
- * based on cpu type and whether the interface is enabled in sys_pinfunc
- * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
- */
-static int __init au1000_init_module(void)
-{
- int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
- struct net_device *dev;
- int i, found_one = 0;
-
- num_ifs = NUM_ETH_INTERFACES - ni;
-
- for(i = 0; i < num_ifs; i++) {
- dev = au1000_probe(i);
- iflist[i].dev = dev;
- if (dev)
- found_one++;
- }
- if (!found_one)
- return -ENODEV;
- return 0;
-}
-
-/*
* ethtool operations
*/
@@ -611,199 +648,6 @@ static const struct ethtool_ops au1000_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
-static struct net_device * au1000_probe(int port_num)
-{
- static unsigned version_printed = 0;
- struct au1000_private *aup = NULL;
- struct net_device *dev = NULL;
- db_dest_t *pDB, *pDBfree;
- char ethaddr[6];
- int irq, i, err;
- u32 base, macen;
-
- if (port_num >= NUM_ETH_INTERFACES)
- return NULL;
-
- base = CPHYSADDR(iflist[port_num].base_addr );
- macen = CPHYSADDR(iflist[port_num].macen_addr);
- irq = iflist[port_num].irq;
-
- if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
- !request_mem_region(macen, 4, "Au1x00 ENET"))
- return NULL;
-
- if (version_printed++ == 0)
- printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
-
- dev = alloc_etherdev(sizeof(struct au1000_private));
- if (!dev) {
- printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
- return NULL;
- }
-
- if ((err = register_netdev(dev)) != 0) {
- printk(KERN_ERR "%s: Cannot register net device, error %d\n",
- DRV_NAME, err);
- free_netdev(dev);
- return NULL;
- }
-
- printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
- dev->name, base, irq);
-
- aup = netdev_priv(dev);
-
- spin_lock_init(&aup->lock);
-
- /* Allocate the data buffers */
- /* Snooping works fine with eth on all au1xxx */
- aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
- (NUM_TX_BUFFS + NUM_RX_BUFFS),
- &aup->dma_addr, 0);
- if (!aup->vaddr) {
- free_netdev(dev);
- release_mem_region( base, MAC_IOSIZE);
- release_mem_region(macen, 4);
- return NULL;
- }
-
- /* aup->mac is the base address of the MAC's registers */
- aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
-
- /* Setup some variables for quick register address access */
- aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
- aup->mac_id = port_num;
- au_macs[port_num] = aup;
-
- if (port_num == 0) {
- if (prom_get_ethernet_addr(ethaddr) == 0)
- memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
- else {
- printk(KERN_INFO "%s: No MAC address found\n",
- dev->name);
- /* Use the hard coded MAC addresses */
- }
-
- setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
- } else if (port_num == 1)
- setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
-
- /*
- * Assign to the Ethernet ports two consecutive MAC addresses
- * to match those that are printed on their stickers
- */
- memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
- dev->dev_addr[5] += port_num;
-
- *aup->enable = 0;
- aup->mac_enabled = 0;
-
- aup->mii_bus = mdiobus_alloc();
- if (aup->mii_bus == NULL)
- goto err_out;
-
- aup->mii_bus->priv = dev;
- aup->mii_bus->read = au1000_mdiobus_read;
- aup->mii_bus->write = au1000_mdiobus_write;
- aup->mii_bus->reset = au1000_mdiobus_reset;
- aup->mii_bus->name = "au1000_eth_mii";
- snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
- aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
- for(i = 0; i < PHY_MAX_ADDR; ++i)
- aup->mii_bus->irq[i] = PHY_POLL;
-
- /* if known, set corresponding PHY IRQs */
-#if defined(AU1XXX_PHY_STATIC_CONFIG)
-# if defined(AU1XXX_PHY0_IRQ)
- if (AU1XXX_PHY0_BUSID == aup->mac_id)
- aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
-# endif
-# if defined(AU1XXX_PHY1_IRQ)
- if (AU1XXX_PHY1_BUSID == aup->mac_id)
- aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
-# endif
-#endif
- mdiobus_register(aup->mii_bus);
-
- if (mii_probe(dev) != 0) {
- goto err_out;
- }
-
- pDBfree = NULL;
- /* setup the data buffer descriptors and attach a buffer to each one */
- pDB = aup->db;
- for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
- pDB->pnext = pDBfree;
- pDBfree = pDB;
- pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
- pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
- pDB++;
- }
- aup->pDBfree = pDBfree;
-
- for (i = 0; i < NUM_RX_DMA; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) {
- goto err_out;
- }
- aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
- aup->rx_db_inuse[i] = pDB;
- }
- for (i = 0; i < NUM_TX_DMA; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) {
- goto err_out;
- }
- aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
- aup->tx_dma_ring[i]->len = 0;
- aup->tx_db_inuse[i] = pDB;
- }
-
- dev->base_addr = base;
- dev->irq = irq;
- dev->open = au1000_open;
- dev->hard_start_xmit = au1000_tx;
- dev->stop = au1000_close;
- dev->set_multicast_list = &set_rx_mode;
- dev->do_ioctl = &au1000_ioctl;
- SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
- dev->tx_timeout = au1000_tx_timeout;
- dev->watchdog_timeo = ETH_TX_TIMEOUT;
-
- /*
- * The boot code uses the ethernet controller, so reset it to start
- * fresh. au1000_init() expects that the device is in reset state.
- */
- reset_mac(dev);
-
- return dev;
-
-err_out:
- if (aup->mii_bus != NULL) {
- mdiobus_unregister(aup->mii_bus);
- mdiobus_free(aup->mii_bus);
- }
-
- /* here we should have a valid dev plus aup-> register addresses
- * so we can reset the mac properly.*/
- reset_mac(dev);
-
- for (i = 0; i < NUM_RX_DMA; i++) {
- if (aup->rx_db_inuse[i])
- ReleaseDB(aup, aup->rx_db_inuse[i]);
- }
- for (i = 0; i < NUM_TX_DMA; i++) {
- if (aup->tx_db_inuse[i])
- ReleaseDB(aup, aup->tx_db_inuse[i]);
- }
- dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
- (void *)aup->vaddr, aup->dma_addr);
- unregister_netdev(dev);
- free_netdev(dev);
- release_mem_region( base, MAC_IOSIZE);
- release_mem_region(macen, 4);
- return NULL;
-}
/*
* Initialize the interface.
@@ -864,83 +708,170 @@ static int au1000_init(struct net_device *dev)
return 0;
}
-static void
-au1000_adjust_link(struct net_device *dev)
+static inline void update_rx_stats(struct net_device *dev, u32 status)
{
struct au1000_private *aup = netdev_priv(dev);
- struct phy_device *phydev = aup->phy_dev;
- unsigned long flags;
+ struct net_device_stats *ps = &dev->stats;
- int status_change = 0;
+ ps->rx_packets++;
+ if (status & RX_MCAST_FRAME)
+ ps->multicast++;
- BUG_ON(!aup->phy_dev);
+ if (status & RX_ERROR) {
+ ps->rx_errors++;
+ if (status & RX_MISSED_FRAME)
+ ps->rx_missed_errors++;
+ if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
+ ps->rx_length_errors++;
+ if (status & RX_CRC_ERROR)
+ ps->rx_crc_errors++;
+ if (status & RX_COLL)
+ ps->collisions++;
+ }
+ else
+ ps->rx_bytes += status & RX_FRAME_LEN_MASK;
- spin_lock_irqsave(&aup->lock, flags);
+}
- if (phydev->link && (aup->old_speed != phydev->speed)) {
- // speed changed
+/*
+ * Au1000 receive routine.
+ */
+static int au1000_rx(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct sk_buff *skb;
+ volatile rx_dma_t *prxd;
+ u32 buff_stat, status;
+ db_dest_t *pDB;
+ u32 frmlen;
- switch(phydev->speed) {
- case SPEED_10:
- case SPEED_100:
- break;
- default:
- printk(KERN_WARNING
- "%s: Speed (%d) is not 10/100 ???\n",
- dev->name, phydev->speed);
- break;
- }
+ if (au1000_debug > 5)
+ printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
- aup->old_speed = phydev->speed;
+ prxd = aup->rx_dma_ring[aup->rx_head];
+ buff_stat = prxd->buff_stat;
+ while (buff_stat & RX_T_DONE) {
+ status = prxd->status;
+ pDB = aup->rx_db_inuse[aup->rx_head];
+ update_rx_stats(dev, status);
+ if (!(status & RX_ERROR)) {
- status_change = 1;
+ /* good frame */
+ frmlen = (status & RX_FRAME_LEN_MASK);
+ frmlen -= 4; /* Remove FCS */
+ skb = dev_alloc_skb(frmlen + 2);
+ if (skb == NULL) {
+ printk(KERN_ERR
+ "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
+ dev->stats.rx_dropped++;
+ continue;
+ }
+ skb_reserve(skb, 2); /* 16 byte IP header align */
+ skb_copy_to_linear_data(skb,
+ (unsigned char *)pDB->vaddr, frmlen);
+ skb_put(skb, frmlen);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb); /* pass the packet to upper layers */
+ }
+ else {
+ if (au1000_debug > 4) {
+ if (status & RX_MISSED_FRAME)
+ printk("rx miss\n");
+ if (status & RX_WDOG_TIMER)
+ printk("rx wdog\n");
+ if (status & RX_RUNT)
+ printk("rx runt\n");
+ if (status & RX_OVERLEN)
+ printk("rx overlen\n");
+ if (status & RX_COLL)
+ printk("rx coll\n");
+ if (status & RX_MII_ERROR)
+ printk("rx mii error\n");
+ if (status & RX_CRC_ERROR)
+ printk("rx crc error\n");
+ if (status & RX_LEN_ERROR)
+ printk("rx len error\n");
+ if (status & RX_U_CNTRL_FRAME)
+ printk("rx u control frame\n");
+ if (status & RX_MISSED_FRAME)
+ printk("rx miss\n");
+ }
+ }
+ prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
+ aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
+ au_sync();
+
+ /* next descriptor */
+ prxd = aup->rx_dma_ring[aup->rx_head];
+ buff_stat = prxd->buff_stat;
}
+ return 0;
+}
- if (phydev->link && (aup->old_duplex != phydev->duplex)) {
- // duplex mode changed
+static void update_tx_stats(struct net_device *dev, u32 status)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct net_device_stats *ps = &dev->stats;
- /* switching duplex mode requires to disable rx and tx! */
- hard_stop(dev);
+ if (status & TX_FRAME_ABORTED) {
+ if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
+ if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
+ /* any other tx errors are only valid
+ * in half duplex mode */
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
+ }
+ }
+ else {
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
+ if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
+ ps->tx_carrier_errors++;
+ }
+ }
+}
- if (DUPLEX_FULL == phydev->duplex)
- aup->mac->control = ((aup->mac->control
- | MAC_FULL_DUPLEX)
- & ~MAC_DISABLE_RX_OWN);
- else
- aup->mac->control = ((aup->mac->control
- & ~MAC_FULL_DUPLEX)
- | MAC_DISABLE_RX_OWN);
- au_sync_delay(1);
+/*
+ * Called from the interrupt service routine to acknowledge
+ * the TX DONE bits. This is a must if the irq is setup as
+ * edge triggered.
+ */
+static void au1000_tx_ack(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ volatile tx_dma_t *ptxd;
- enable_rx_tx(dev);
- aup->old_duplex = phydev->duplex;
+ ptxd = aup->tx_dma_ring[aup->tx_tail];
- status_change = 1;
- }
+ while (ptxd->buff_stat & TX_T_DONE) {
+ update_tx_stats(dev, ptxd->status);
+ ptxd->buff_stat &= ~TX_T_DONE;
+ ptxd->len = 0;
+ au_sync();
- if(phydev->link != aup->old_link) {
- // link state changed
+ aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
+ ptxd = aup->tx_dma_ring[aup->tx_tail];
- if (!phydev->link) {
- /* link went down */
- aup->old_speed = 0;
- aup->old_duplex = -1;
+ if (aup->tx_full) {
+ aup->tx_full = 0;
+ netif_wake_queue(dev);
}
-
- aup->old_link = phydev->link;
- status_change = 1;
}
+}
- spin_unlock_irqrestore(&aup->lock, flags);
+/*
+ * Au1000 interrupt service routine.
+ */
+static irqreturn_t au1000_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
- if (status_change) {
- if (phydev->link)
- printk(KERN_INFO "%s: link up (%d/%s)\n",
- dev->name, phydev->speed,
- DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
- else
- printk(KERN_INFO "%s: link down\n", dev->name);
- }
+ /* Handle RX interrupts first to minimize chance of overrun */
+
+ au1000_rx(dev);
+ au1000_tx_ack(dev);
+ return IRQ_RETVAL(1);
}
static int au1000_open(struct net_device *dev)
@@ -1003,88 +934,6 @@ static int au1000_close(struct net_device *dev)
return 0;
}
-static void __exit au1000_cleanup_module(void)
-{
- int i, j;
- struct net_device *dev;
- struct au1000_private *aup;
-
- for (i = 0; i < num_ifs; i++) {
- dev = iflist[i].dev;
- if (dev) {
- aup = netdev_priv(dev);
- unregister_netdev(dev);
- mdiobus_unregister(aup->mii_bus);
- mdiobus_free(aup->mii_bus);
- for (j = 0; j < NUM_RX_DMA; j++)
- if (aup->rx_db_inuse[j])
- ReleaseDB(aup, aup->rx_db_inuse[j]);
- for (j = 0; j < NUM_TX_DMA; j++)
- if (aup->tx_db_inuse[j])
- ReleaseDB(aup, aup->tx_db_inuse[j]);
- dma_free_noncoherent(NULL, MAX_BUF_SIZE *
- (NUM_TX_BUFFS + NUM_RX_BUFFS),
- (void *)aup->vaddr, aup->dma_addr);
- release_mem_region(dev->base_addr, MAC_IOSIZE);
- release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
- free_netdev(dev);
- }
- }
-}
-
-static void update_tx_stats(struct net_device *dev, u32 status)
-{
- struct au1000_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &dev->stats;
-
- if (status & TX_FRAME_ABORTED) {
- if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
- if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
- /* any other tx errors are only valid
- * in half duplex mode */
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- }
- }
- else {
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
- ps->tx_carrier_errors++;
- }
- }
-}
-
-
-/*
- * Called from the interrupt service routine to acknowledge
- * the TX DONE bits. This is a must if the irq is setup as
- * edge triggered.
- */
-static void au1000_tx_ack(struct net_device *dev)
-{
- struct au1000_private *aup = netdev_priv(dev);
- volatile tx_dma_t *ptxd;
-
- ptxd = aup->tx_dma_ring[aup->tx_tail];
-
- while (ptxd->buff_stat & TX_T_DONE) {
- update_tx_stats(dev, ptxd->status);
- ptxd->buff_stat &= ~TX_T_DONE;
- ptxd->len = 0;
- au_sync();
-
- aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
- ptxd = aup->tx_dma_ring[aup->tx_tail];
-
- if (aup->tx_full) {
- aup->tx_full = 0;
- netif_wake_queue(dev);
- }
- }
-}
-
-
/*
* Au1000 transmit routine.
*/
@@ -1142,123 +991,6 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-static inline void update_rx_stats(struct net_device *dev, u32 status)
-{
- struct au1000_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &dev->stats;
-
- ps->rx_packets++;
- if (status & RX_MCAST_FRAME)
- ps->multicast++;
-
- if (status & RX_ERROR) {
- ps->rx_errors++;
- if (status & RX_MISSED_FRAME)
- ps->rx_missed_errors++;
- if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
- ps->rx_length_errors++;
- if (status & RX_CRC_ERROR)
- ps->rx_crc_errors++;
- if (status & RX_COLL)
- ps->collisions++;
- }
- else
- ps->rx_bytes += status & RX_FRAME_LEN_MASK;
-
-}
-
-/*
- * Au1000 receive routine.
- */
-static int au1000_rx(struct net_device *dev)
-{
- struct au1000_private *aup = netdev_priv(dev);
- struct sk_buff *skb;
- volatile rx_dma_t *prxd;
- u32 buff_stat, status;
- db_dest_t *pDB;
- u32 frmlen;
-
- if (au1000_debug > 5)
- printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
-
- prxd = aup->rx_dma_ring[aup->rx_head];
- buff_stat = prxd->buff_stat;
- while (buff_stat & RX_T_DONE) {
- status = prxd->status;
- pDB = aup->rx_db_inuse[aup->rx_head];
- update_rx_stats(dev, status);
- if (!(status & RX_ERROR)) {
-
- /* good frame */
- frmlen = (status & RX_FRAME_LEN_MASK);
- frmlen -= 4; /* Remove FCS */
- skb = dev_alloc_skb(frmlen + 2);
- if (skb == NULL) {
- printk(KERN_ERR
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- continue;
- }
- skb_reserve(skb, 2); /* 16 byte IP header align */
- skb_copy_to_linear_data(skb,
- (unsigned char *)pDB->vaddr, frmlen);
- skb_put(skb, frmlen);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb); /* pass the packet to upper layers */
- }
- else {
- if (au1000_debug > 4) {
- if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
- if (status & RX_WDOG_TIMER)
- printk("rx wdog\n");
- if (status & RX_RUNT)
- printk("rx runt\n");
- if (status & RX_OVERLEN)
- printk("rx overlen\n");
- if (status & RX_COLL)
- printk("rx coll\n");
- if (status & RX_MII_ERROR)
- printk("rx mii error\n");
- if (status & RX_CRC_ERROR)
- printk("rx crc error\n");
- if (status & RX_LEN_ERROR)
- printk("rx len error\n");
- if (status & RX_U_CNTRL_FRAME)
- printk("rx u control frame\n");
- if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
- }
- }
- prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
- aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
- au_sync();
-
- /* next descriptor */
- prxd = aup->rx_dma_ring[aup->rx_head];
- buff_stat = prxd->buff_stat;
- }
- return 0;
-}
-
-
-/*
- * Au1000 interrupt service routine.
- */
-static irqreturn_t au1000_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
-
- /* Handle RX interrupts first to minimize chance of overrun */
-
- au1000_rx(dev);
- au1000_tx_ack(dev);
- return IRQ_RETVAL(1);
-}
-
-
/*
* The Tx ring has been full longer than the watchdog timeout
* value. The transmitter must be hung?
@@ -1315,5 +1047,252 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
}
+static struct net_device * au1000_probe(int port_num)
+{
+ static unsigned version_printed = 0;
+ struct au1000_private *aup = NULL;
+ struct net_device *dev = NULL;
+ db_dest_t *pDB, *pDBfree;
+ char ethaddr[6];
+ int irq, i, err;
+ u32 base, macen;
+
+ if (port_num >= NUM_ETH_INTERFACES)
+ return NULL;
+
+ base = CPHYSADDR(iflist[port_num].base_addr );
+ macen = CPHYSADDR(iflist[port_num].macen_addr);
+ irq = iflist[port_num].irq;
+
+ if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
+ !request_mem_region(macen, 4, "Au1x00 ENET"))
+ return NULL;
+
+ if (version_printed++ == 0)
+ printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+
+ dev = alloc_etherdev(sizeof(struct au1000_private));
+ if (!dev) {
+ printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
+ return NULL;
+ }
+
+ if ((err = register_netdev(dev)) != 0) {
+ printk(KERN_ERR "%s: Cannot register net device, error %d\n",
+ DRV_NAME, err);
+ free_netdev(dev);
+ return NULL;
+ }
+
+ printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
+ dev->name, base, irq);
+
+ aup = netdev_priv(dev);
+
+ spin_lock_init(&aup->lock);
+
+ /* Allocate the data buffers */
+ /* Snooping works fine with eth on all au1xxx */
+ aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
+ (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ &aup->dma_addr, 0);
+ if (!aup->vaddr) {
+ free_netdev(dev);
+ release_mem_region( base, MAC_IOSIZE);
+ release_mem_region(macen, 4);
+ return NULL;
+ }
+
+ /* aup->mac is the base address of the MAC's registers */
+ aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
+
+ /* Setup some variables for quick register address access */
+ aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
+ aup->mac_id = port_num;
+ au_macs[port_num] = aup;
+
+ if (port_num == 0) {
+ if (prom_get_ethernet_addr(ethaddr) == 0)
+ memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
+ else {
+ printk(KERN_INFO "%s: No MAC address found\n",
+ dev->name);
+ /* Use the hard coded MAC addresses */
+ }
+
+ setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
+ } else if (port_num == 1)
+ setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
+
+ /*
+ * Assign to the Ethernet ports two consecutive MAC addresses
+ * to match those that are printed on their stickers
+ */
+ memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
+ dev->dev_addr[5] += port_num;
+
+ *aup->enable = 0;
+ aup->mac_enabled = 0;
+
+ aup->mii_bus = mdiobus_alloc();
+ if (aup->mii_bus == NULL)
+ goto err_out;
+
+ aup->mii_bus->priv = dev;
+ aup->mii_bus->read = au1000_mdiobus_read;
+ aup->mii_bus->write = au1000_mdiobus_write;
+ aup->mii_bus->reset = au1000_mdiobus_reset;
+ aup->mii_bus->name = "au1000_eth_mii";
+ snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
+ aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+ for(i = 0; i < PHY_MAX_ADDR; ++i)
+ aup->mii_bus->irq[i] = PHY_POLL;
+
+ /* if known, set corresponding PHY IRQs */
+#if defined(AU1XXX_PHY_STATIC_CONFIG)
+# if defined(AU1XXX_PHY0_IRQ)
+ if (AU1XXX_PHY0_BUSID == aup->mac_id)
+ aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
+# endif
+# if defined(AU1XXX_PHY1_IRQ)
+ if (AU1XXX_PHY1_BUSID == aup->mac_id)
+ aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
+# endif
+#endif
+ mdiobus_register(aup->mii_bus);
+
+ if (mii_probe(dev) != 0) {
+ goto err_out;
+ }
+
+ pDBfree = NULL;
+ /* setup the data buffer descriptors and attach a buffer to each one */
+ pDB = aup->db;
+ for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
+ pDB->pnext = pDBfree;
+ pDBfree = pDB;
+ pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
+ pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+ pDB++;
+ }
+ aup->pDBfree = pDBfree;
+
+ for (i = 0; i < NUM_RX_DMA; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB) {
+ goto err_out;
+ }
+ aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+ aup->rx_db_inuse[i] = pDB;
+ }
+ for (i = 0; i < NUM_TX_DMA; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB) {
+ goto err_out;
+ }
+ aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+ aup->tx_dma_ring[i]->len = 0;
+ aup->tx_db_inuse[i] = pDB;
+ }
+
+ dev->base_addr = base;
+ dev->irq = irq;
+ dev->open = au1000_open;
+ dev->hard_start_xmit = au1000_tx;
+ dev->stop = au1000_close;
+ dev->set_multicast_list = &set_rx_mode;
+ dev->do_ioctl = &au1000_ioctl;
+ SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+ dev->tx_timeout = au1000_tx_timeout;
+ dev->watchdog_timeo = ETH_TX_TIMEOUT;
+
+ /*
+ * The boot code uses the ethernet controller, so reset it to start
+ * fresh. au1000_init() expects that the device is in reset state.
+ */
+ reset_mac(dev);
+
+ return dev;
+
+err_out:
+ if (aup->mii_bus != NULL) {
+ mdiobus_unregister(aup->mii_bus);
+ mdiobus_free(aup->mii_bus);
+ }
+
+ /* here we should have a valid dev plus aup-> register addresses
+ * so we can reset the mac properly.*/
+ reset_mac(dev);
+
+ for (i = 0; i < NUM_RX_DMA; i++) {
+ if (aup->rx_db_inuse[i])
+ ReleaseDB(aup, aup->rx_db_inuse[i]);
+ }
+ for (i = 0; i < NUM_TX_DMA; i++) {
+ if (aup->tx_db_inuse[i])
+ ReleaseDB(aup, aup->tx_db_inuse[i]);
+ }
+ dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr);
+ unregister_netdev(dev);
+ free_netdev(dev);
+ release_mem_region( base, MAC_IOSIZE);
+ release_mem_region(macen, 4);
+ return NULL;
+}
+
+/*
+ * Setup the base address and interrupt of the Au1xxx ethernet macs
+ * based on cpu type and whether the interface is enabled in sys_pinfunc
+ * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
+ */
+static int __init au1000_init_module(void)
+{
+ int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
+ struct net_device *dev;
+ int i, found_one = 0;
+
+ num_ifs = NUM_ETH_INTERFACES - ni;
+
+ for(i = 0; i < num_ifs; i++) {
+ dev = au1000_probe(i);
+ iflist[i].dev = dev;
+ if (dev)
+ found_one++;
+ }
+ if (!found_one)
+ return -ENODEV;
+ return 0;
+}
+
+static void __exit au1000_cleanup_module(void)
+{
+ int i, j;
+ struct net_device *dev;
+ struct au1000_private *aup;
+
+ for (i = 0; i < num_ifs; i++) {
+ dev = iflist[i].dev;
+ if (dev) {
+ aup = netdev_priv(dev);
+ unregister_netdev(dev);
+ mdiobus_unregister(aup->mii_bus);
+ mdiobus_free(aup->mii_bus);
+ for (j = 0; j < NUM_RX_DMA; j++)
+ if (aup->rx_db_inuse[j])
+ ReleaseDB(aup, aup->rx_db_inuse[j]);
+ for (j = 0; j < NUM_TX_DMA; j++)
+ if (aup->tx_db_inuse[j])
+ ReleaseDB(aup, aup->tx_db_inuse[j]);
+ dma_free_noncoherent(NULL, MAX_BUF_SIZE *
+ (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr);
+ release_mem_region(dev->base_addr, MAC_IOSIZE);
+ release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
+ free_netdev(dev);
+ }
+ }
+}
+
module_init(au1000_init_module);
module_exit(au1000_cleanup_module);
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index a4eb6c40678..62d9c9cc567 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -93,6 +93,7 @@ struct ax_device {
unsigned char running;
unsigned char resume_open;
+ unsigned int irqflags;
u32 reg_offsets[0x20];
};
@@ -474,7 +475,8 @@ static int ax_open(struct net_device *dev)
dev_dbg(&ax->dev->dev, "%s: open\n", dev->name);
- ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
+ ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+ dev->name, dev);
if (ret)
return ret;
@@ -731,12 +733,19 @@ static int ax_init_dev(struct net_device *dev, int first_init)
/* load the mac-address from the device if this is the
* first time we've initialised */
- if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
- ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
- ei_local->mem + E8390_CMD); /* 0x61 */
+ if (first_init) {
+ if (ax->plat->flags & AXFLG_MAC_FROMDEV) {
+ ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+ ei_local->mem + E8390_CMD); /* 0x61 */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ dev->dev_addr[i] =
+ ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+ }
- for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
- dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+ if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) &&
+ ax->plat->mac_addr)
+ memcpy(dev->dev_addr, ax->plat->mac_addr,
+ ETHER_ADDR_LEN);
}
ax_reset_8390(dev);
@@ -829,7 +838,7 @@ static int ax_probe(struct platform_device *pdev)
struct ax_device *ax;
struct resource *res;
size_t size;
- int ret;
+ int ret = 0;
dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
if (dev == NULL)
@@ -850,12 +859,14 @@ static int ax_probe(struct platform_device *pdev)
/* find the platform resources */
- ret = platform_get_irq(pdev, 0);
- if (ret < 0) {
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
dev_err(&pdev->dev, "no IRQ specified\n");
goto exit_mem;
}
- dev->irq = ret;
+
+ dev->irq = res->start;
+ ax->irqflags = res->flags & IRQF_TRIGGER_MASK;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index c38512ebcea..5c84541e073 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -874,7 +874,7 @@ static int b44_poll(struct napi_struct *napi, int budget)
}
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
b44_enable_ints(bp);
}
@@ -906,13 +906,13 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id)
goto irq_ack;
}
- if (netif_rx_schedule_prep(&bp->napi)) {
+ if (napi_schedule_prep(&bp->napi)) {
/* NOTE: These writes are posted by the readback of
* the ISTAT register below.
*/
bp->istat = istat;
__b44_disable_ints(bp);
- __netif_rx_schedule(&bp->napi);
+ __napi_schedule(&bp->napi);
} else {
printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
dev->name);
@@ -973,7 +973,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
ssb_dma_unmap_single(bp->sdev, mapping, len,
DMA_TO_DEVICE);
- bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
+ bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb)
goto err_out;
@@ -1264,8 +1264,14 @@ static void b44_clear_stats(struct b44 *bp)
static void b44_chip_reset(struct b44 *bp, int reset_kind)
{
struct ssb_device *sdev = bp->sdev;
+ bool was_enabled;
- if (ssb_device_is_enabled(bp->sdev)) {
+ was_enabled = ssb_device_is_enabled(bp->sdev);
+
+ ssb_device_enable(bp->sdev, 0);
+ ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
+
+ if (was_enabled) {
bw32(bp, B44_RCV_LAZY, 0);
bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1);
@@ -1277,10 +1283,8 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
}
bw32(bp, B44_DMARX_CTRL, 0);
bp->rx_prod = bp->rx_cons = 0;
- } else
- ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
+ }
- ssb_device_enable(bp->sdev, 0);
b44_clear_stats(bp);
/*
@@ -2236,6 +2240,7 @@ static void __devexit b44_remove_one(struct ssb_device *sdev)
struct net_device *dev = ssb_get_drvdata(sdev);
unregister_netdev(dev);
+ ssb_device_disable(sdev, 0);
ssb_bus_may_powerdown(sdev->bus);
free_netdev(dev);
ssb_pcihost_set_power_state(sdev, PCI_D3hot);
diff --git a/drivers/net/benet/Kconfig b/drivers/net/benet/Kconfig
new file mode 100644
index 00000000000..c6934f179c0
--- /dev/null
+++ b/drivers/net/benet/Kconfig
@@ -0,0 +1,7 @@
+config BE2NET
+ tristate "ServerEngines' 10Gbps NIC - BladeEngine 2"
+ depends on PCI && INET
+ select INET_LRO
+ help
+ This driver implements the NIC functionality for ServerEngines'
+ 10Gbps network adapter - BladeEngine 2.
diff --git a/drivers/net/benet/Makefile b/drivers/net/benet/Makefile
new file mode 100644
index 00000000000..a60cd805113
--- /dev/null
+++ b/drivers/net/benet/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile to build the network driver for ServerEngine's BladeEngine.
+#
+
+obj-$(CONFIG_BE2NET) += be2net.o
+
+be2net-y := be_main.o be_cmds.o be_ethtool.o
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
new file mode 100644
index 00000000000..c49ddd08b2a
--- /dev/null
+++ b/drivers/net/benet/be.h
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2005 - 2009 ServerEngines
+ * 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. The full GNU General
+ * Public License is included in this distribution in the file called COPYING.
+ *
+ * Contact Information:
+ * linux-drivers@serverengines.com
+ *
+ * ServerEngines
+ * 209 N. Fair Oaks Ave
+ * Sunnyvale, CA 94085
+ */
+
+#ifndef BE_H
+#define BE_H
+
+#include <linux/pci.h>
+#include <linux/etherdevice.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <net/tcp.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <linux/if_vlan.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/inet_lro.h>
+
+#include "be_hw.h"
+
+#define DRV_VER "2.0.348"
+#define DRV_NAME "be2net"
+#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
+#define DRV_DESC BE_NAME "Driver"
+
+/* Number of bytes of an RX frame that are copied to skb->data */
+#define BE_HDR_LEN 64
+#define BE_MAX_JUMBO_FRAME_SIZE 9018
+#define BE_MIN_MTU 256
+
+#define BE_NUM_VLANS_SUPPORTED 64
+#define BE_MAX_EQD 96
+#define BE_MAX_TX_FRAG_COUNT 30
+
+#define EVNT_Q_LEN 1024
+#define TX_Q_LEN 2048
+#define TX_CQ_LEN 1024
+#define RX_Q_LEN 1024 /* Does not support any other value */
+#define RX_CQ_LEN 1024
+#define MCC_Q_LEN 64 /* total size not to exceed 8 pages */
+#define MCC_CQ_LEN 256
+
+#define BE_NAPI_WEIGHT 64
+#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
+#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
+
+#define BE_MAX_LRO_DESCRIPTORS 16
+#define BE_MAX_FRAGS_PER_FRAME 16
+
+struct be_dma_mem {
+ void *va;
+ dma_addr_t dma;
+ u32 size;
+};
+
+struct be_queue_info {
+ struct be_dma_mem dma_mem;
+ u16 len;
+ u16 entry_size; /* Size of an element in the queue */
+ u16 id;
+ u16 tail, head;
+ bool created;
+ atomic_t used; /* Number of valid elements in the queue */
+};
+
+struct be_ctrl_info {
+ u8 __iomem *csr;
+ u8 __iomem *db; /* Door Bell */
+ u8 __iomem *pcicfg; /* PCI config space */
+ int pci_func;
+
+ /* Mbox used for cmd request/response */
+ spinlock_t cmd_lock; /* For serializing cmds to BE card */
+ struct be_dma_mem mbox_mem;
+ /* Mbox mem is adjusted to align to 16 bytes. The allocated addr
+ * is stored for freeing purpose */
+ struct be_dma_mem mbox_mem_alloced;
+};
+
+#include "be_cmds.h"
+
+struct be_drvr_stats {
+ u32 be_tx_reqs; /* number of TX requests initiated */
+ u32 be_tx_stops; /* number of times TX Q was stopped */
+ u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */
+ u32 be_tx_wrbs; /* number of tx WRBs used */
+ u32 be_tx_events; /* number of tx completion events */
+ u32 be_tx_compl; /* number of tx completion entries processed */
+ ulong be_tx_jiffies;
+ u64 be_tx_bytes;
+ u64 be_tx_bytes_prev;
+ u32 be_tx_rate;
+
+ u32 cache_barrier[16];
+
+ u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */
+ u32 be_polls; /* number of times NAPI called poll function */
+ u32 be_rx_events; /* number of ucast rx completion events */
+ u32 be_rx_compl; /* number of rx completion entries processed */
+ u32 be_lro_hgram_data[8]; /* histogram of LRO data packets */
+ u32 be_lro_hgram_ack[8]; /* histogram of LRO ACKs */
+ ulong be_rx_jiffies;
+ u64 be_rx_bytes;
+ u64 be_rx_bytes_prev;
+ u32 be_rx_rate;
+ /* number of non ether type II frames dropped where
+ * frame len > length field of Mac Hdr */
+ u32 be_802_3_dropped_frames;
+ /* number of non ether type II frames malformed where
+ * in frame len < length field of Mac Hdr */
+ u32 be_802_3_malformed_frames;
+ u32 be_rxcp_err; /* Num rx completion entries w/ err set. */
+ ulong rx_fps_jiffies; /* jiffies at last FPS calc */
+ u32 be_rx_frags;
+ u32 be_prev_rx_frags;
+ u32 be_rx_fps; /* Rx frags per second */
+};
+
+struct be_stats_obj {
+ struct be_drvr_stats drvr_stats;
+ struct net_device_stats net_stats;
+ struct be_dma_mem cmd;
+};
+
+struct be_eq_obj {
+ struct be_queue_info q;
+ char desc[32];
+
+ /* Adaptive interrupt coalescing (AIC) info */
+ bool enable_aic;
+ u16 min_eqd; /* in usecs */
+ u16 max_eqd; /* in usecs */
+ u16 cur_eqd; /* in usecs */
+
+ struct napi_struct napi;
+};
+
+struct be_tx_obj {
+ struct be_queue_info q;
+ struct be_queue_info cq;
+ /* Remember the skbs that were transmitted */
+ struct sk_buff *sent_skb_list[TX_Q_LEN];
+};
+
+/* Struct to remember the pages posted for rx frags */
+struct be_rx_page_info {
+ struct page *page;
+ dma_addr_t bus;
+ u16 page_offset;
+ bool last_page_user;
+};
+
+struct be_rx_obj {
+ struct be_queue_info q;
+ struct be_queue_info cq;
+ struct be_rx_page_info page_info_tbl[RX_Q_LEN];
+ struct net_lro_mgr lro_mgr;
+ struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS];
+};
+
+#define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */
+struct be_adapter {
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+
+ /* Mbox, pci config, csr address information */
+ struct be_ctrl_info ctrl;
+
+ struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS];
+ bool msix_enabled;
+ bool isr_registered;
+
+ /* TX Rings */
+ struct be_eq_obj tx_eq;
+ struct be_tx_obj tx_obj;
+
+ u32 cache_line_break[8];
+
+ /* Rx rings */
+ struct be_eq_obj rx_eq;
+ struct be_rx_obj rx_obj;
+ u32 big_page_size; /* Compounded page size shared by rx wrbs */
+ bool rx_post_starved; /* Zero rx frags have been posted to BE */
+
+ struct vlan_group *vlan_grp;
+ u16 num_vlans;
+ u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
+
+ struct be_stats_obj stats;
+ /* Work queue used to perform periodic tasks like getting statistics */
+ struct delayed_work work;
+
+ /* Ethtool knobs and info */
+ bool rx_csum; /* BE card must perform rx-checksumming */
+ u32 max_rx_coal;
+ char fw_ver[FW_VER_LEN];
+ u32 if_handle; /* Used to configure filtering */
+ u32 pmac_id; /* MAC addr handle used by BE card */
+
+ struct be_link_info link;
+ u32 port_num;
+};
+
+extern struct ethtool_ops be_ethtool_ops;
+
+#define drvr_stats(adapter) (&adapter->stats.drvr_stats)
+
+#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
+
+static inline u32 MODULO(u16 val, u16 limit)
+{
+ BUG_ON(limit & (limit - 1));
+ return val & (limit - 1);
+}
+
+static inline void index_adv(u16 *index, u16 val, u16 limit)
+{
+ *index = MODULO((*index + val), limit);
+}
+
+static inline void index_inc(u16 *index, u16 limit)
+{
+ *index = MODULO((*index + 1), limit);
+}
+
+#define PAGE_SHIFT_4K 12
+#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
+
+/* Returns number of pages spanned by the data starting at the given addr */
+#define PAGES_4K_SPANNED(_address, size) \
+ ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
+ (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
+
+/* Byte offset into the page corresponding to given address */
+#define OFFSET_IN_PAGE(addr) \
+ ((size_t)(addr) & (PAGE_SIZE_4K-1))
+
+/* Returns bit offset within a DWORD of a bitfield */
+#define AMAP_BIT_OFFSET(_struct, field) \
+ (((size_t)&(((_struct *)0)->field))%32)
+
+/* Returns the bit mask of the field that is NOT shifted into location. */
+static inline u32 amap_mask(u32 bitsize)
+{
+ return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1);
+}
+
+static inline void
+amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value)
+{
+ u32 *dw = (u32 *) ptr + dw_offset;
+ *dw &= ~(mask << offset);
+ *dw |= (mask & value) << offset;
+}
+
+#define AMAP_SET_BITS(_struct, field, ptr, val) \
+ amap_set(ptr, \
+ offsetof(_struct, field)/32, \
+ amap_mask(sizeof(((_struct *)0)->field)), \
+ AMAP_BIT_OFFSET(_struct, field), \
+ val)
+
+static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
+{
+ u32 *dw = (u32 *) ptr;
+ return mask & (*(dw + dw_offset) >> offset);
+}
+
+#define AMAP_GET_BITS(_struct, field, ptr) \
+ amap_get(ptr, \
+ offsetof(_struct, field)/32, \
+ amap_mask(sizeof(((_struct *)0)->field)), \
+ AMAP_BIT_OFFSET(_struct, field))
+
+#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len)
+#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len)
+static inline void swap_dws(void *wrb, int len)
+{
+#ifdef __BIG_ENDIAN
+ u32 *dw = wrb;
+ BUG_ON(len % 4);
+ do {
+ *dw = cpu_to_le32(*dw);
+ dw++;
+ len -= 4;
+ } while (len);
+#endif /* __BIG_ENDIAN */
+}
+
+static inline u8 is_tcp_pkt(struct sk_buff *skb)
+{
+ u8 val = 0;
+
+ if (ip_hdr(skb)->version == 4)
+ val = (ip_hdr(skb)->protocol == IPPROTO_TCP);
+ else if (ip_hdr(skb)->version == 6)
+ val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP);
+
+ return val;
+}
+
+static inline u8 is_udp_pkt(struct sk_buff *skb)
+{
+ u8 val = 0;
+
+ if (ip_hdr(skb)->version == 4)
+ val = (ip_hdr(skb)->protocol == IPPROTO_UDP);
+ else if (ip_hdr(skb)->version == 6)
+ val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP);
+
+ return val;
+}
+
+#endif /* BE_H */
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
new file mode 100644
index 00000000000..d444aed962b
--- /dev/null
+++ b/drivers/net/benet/be_cmds.c
@@ -0,0 +1,861 @@
+/*
+ * Copyright (C) 2005 - 2009 ServerEngines
+ * 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. The full GNU General
+ * Public License is included in this distribution in the file called COPYING.
+ *
+ * Contact Information:
+ * linux-drivers@serverengines.com
+ *
+ * ServerEngines
+ * 209 N. Fair Oaks Ave
+ * Sunnyvale, CA 94085
+ */
+
+#include "be.h"
+
+static int be_mbox_db_ready_wait(void __iomem *db)
+{
+ int cnt = 0, wait = 5;
+ u32 ready;
+
+ do {
+ ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
+ if (ready)
+ break;
+
+ if (cnt > 200000) {
+ printk(KERN_WARNING DRV_NAME
+ ": mbox_db poll timed out\n");
+ return -1;
+ }
+
+ if (cnt > 50)
+ wait = 200;
+ cnt += wait;
+ udelay(wait);
+ } while (true);
+
+ return 0;
+}
+
+/*
+ * Insert the mailbox address into the doorbell in two steps
+ */
+static int be_mbox_db_ring(struct be_ctrl_info *ctrl)
+{
+ int status;
+ u16 compl_status, extd_status;
+ u32 val = 0;
+ void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
+ struct be_dma_mem *mbox_mem = &ctrl->mbox_mem;
+ struct be_mcc_mailbox *mbox = mbox_mem->va;
+ struct be_mcc_cq_entry *cqe = &mbox->cqe;
+
+ memset(cqe, 0, sizeof(*cqe));
+
+ val &= ~MPU_MAILBOX_DB_RDY_MASK;
+ val |= MPU_MAILBOX_DB_HI_MASK;
+ /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
+ val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
+ iowrite32(val, db);
+
+ /* wait for ready to be set */
+ status = be_mbox_db_ready_wait(db);
+ if (status != 0)
+ return status;
+
+ val = 0;
+ val &= ~MPU_MAILBOX_DB_RDY_MASK;
+ val &= ~MPU_MAILBOX_DB_HI_MASK;
+ /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
+ val |= (u32)(mbox_mem->dma >> 4) << 2;
+ iowrite32(val, db);
+
+ status = be_mbox_db_ready_wait(db);
+ if (status != 0)
+ return status;
+
+ /* compl entry has been made now */
+ be_dws_le_to_cpu(cqe, sizeof(*cqe));
+ if (!(cqe->flags & CQE_FLAGS_VALID_MASK)) {
+ printk(KERN_WARNING DRV_NAME ": ERROR invalid mbox compl\n");
+ return -1;
+ }
+
+ compl_status = (cqe->status >> CQE_STATUS_COMPL_SHIFT) &
+ CQE_STATUS_COMPL_MASK;
+ if (compl_status != MCC_STATUS_SUCCESS) {
+ extd_status = (cqe->status >> CQE_STATUS_EXTD_SHIFT) &
+ CQE_STATUS_EXTD_MASK;
+ printk(KERN_WARNING DRV_NAME
+ ": ERROR in cmd compl. status(compl/extd)=%d/%d\n",
+ compl_status, extd_status);
+ }
+
+ return compl_status;
+}
+
+static int be_POST_stage_get(struct be_ctrl_info *ctrl, u16 *stage)
+{
+ u32 sem = ioread32(ctrl->csr + MPU_EP_SEMAPHORE_OFFSET);
+
+ *stage = sem & EP_SEMAPHORE_POST_STAGE_MASK;
+ if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK)
+ return -1;
+ else
+ return 0;
+}
+
+static int be_POST_stage_poll(struct be_ctrl_info *ctrl, u16 poll_stage)
+{
+ u16 stage, cnt, error;
+ for (cnt = 0; cnt < 5000; cnt++) {
+ error = be_POST_stage_get(ctrl, &stage);
+ if (error)
+ return -1;
+
+ if (stage == poll_stage)
+ break;
+ udelay(1000);
+ }
+ if (stage != poll_stage)
+ return -1;
+ return 0;
+}
+
+
+int be_cmd_POST(struct be_ctrl_info *ctrl)
+{
+ u16 stage, error;
+
+ error = be_POST_stage_get(ctrl, &stage);
+ if (error)
+ goto err;
+
+ if (stage == POST_STAGE_ARMFW_RDY)
+ return 0;
+
+ if (stage != POST_STAGE_AWAITING_HOST_RDY)
+ goto err;
+
+ /* On awaiting host rdy, reset and again poll on awaiting host rdy */
+ iowrite32(POST_STAGE_BE_RESET, ctrl->csr + MPU_EP_SEMAPHORE_OFFSET);
+ error = be_POST_stage_poll(ctrl, POST_STAGE_AWAITING_HOST_RDY);
+ if (error)
+ goto err;
+
+ /* Now kickoff POST and poll on armfw ready */
+ iowrite32(POST_STAGE_HOST_RDY, ctrl->csr + MPU_EP_SEMAPHORE_OFFSET);
+ error = be_POST_stage_poll(ctrl, POST_STAGE_ARMFW_RDY);
+ if (error)
+ goto err;
+
+ return 0;
+err:
+ printk(KERN_WARNING DRV_NAME ": ERROR, stage=%d\n", stage);
+ return -1;
+}
+
+static inline void *embedded_payload(struct be_mcc_wrb *wrb)
+{
+ return wrb->payload.embedded_payload;
+}
+
+static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
+{
+ return &wrb->payload.sgl[0];
+}
+
+/* Don't touch the hdr after it's prepared */
+static void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
+ bool embedded, u8 sge_cnt)
+{
+ if (embedded)
+ wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
+ else
+ wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) <<
+ MCC_WRB_SGE_CNT_SHIFT;
+ wrb->payload_length = payload_len;
+ be_dws_cpu_to_le(wrb, 20);
+}
+
+/* Don't touch the hdr after it's prepared */
+static void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
+ u8 subsystem, u8 opcode, int cmd_len)
+{
+ req_hdr->opcode = opcode;
+ req_hdr->subsystem = subsystem;
+ req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
+}
+
+static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
+ struct be_dma_mem *mem)
+{
+ int i, buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
+ u64 dma = (u64)mem->dma;
+
+ for (i = 0; i < buf_pages; i++) {
+ pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
+ pages[i].hi = cpu_to_le32(upper_32_bits(dma));
+ dma += PAGE_SIZE_4K;
+ }
+}
+
+/* Converts interrupt delay in microseconds to multiplier value */
+static u32 eq_delay_to_mult(u32 usec_delay)
+{
+#define MAX_INTR_RATE 651042
+ const u32 round = 10;
+ u32 multiplier;
+
+ if (usec_delay == 0)
+ multiplier = 0;
+ else {
+ u32 interrupt_rate = 1000000 / usec_delay;
+ /* Max delay, corresponding to the lowest interrupt rate */
+ if (interrupt_rate == 0)
+ multiplier = 1023;
+ else {
+ multiplier = (MAX_INTR_RATE - interrupt_rate) * round;
+ multiplier /= interrupt_rate;
+ /* Round the multiplier to the closest value.*/
+ multiplier = (multiplier + round/2) / round;
+ multiplier = min(multiplier, (u32)1023);
+ }
+ }
+ return multiplier;
+}
+
+static inline struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
+{
+ return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
+}
+
+int be_cmd_eq_create(struct be_ctrl_info *ctrl,
+ struct be_queue_info *eq, int eq_delay)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_eq_create *req = embedded_payload(wrb);
+ struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
+ struct be_dma_mem *q_mem = &eq->dma_mem;
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_EQ_CREATE, sizeof(*req));
+
+ req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
+
+ AMAP_SET_BITS(struct amap_eq_context, func, req->context,
+ ctrl->pci_func);
+ AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
+ /* 4byte eqe*/
+ AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
+ AMAP_SET_BITS(struct amap_eq_context, count, req->context,
+ __ilog2_u32(eq->len/256));
+ AMAP_SET_BITS(struct amap_eq_context, delaymult, req->context,
+ eq_delay_to_mult(eq_delay));
+ be_dws_cpu_to_le(req->context, sizeof(req->context));
+
+ be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ eq->id = le16_to_cpu(resp->eq_id);
+ eq->created = true;
+ }
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr,
+ u8 type, bool permanent, u32 if_handle)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_mac_query *req = embedded_payload(wrb);
+ struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req));
+
+ req->type = type;
+ if (permanent) {
+ req->permanent = 1;
+ } else {
+ req->if_id = cpu_to_le16((u16)if_handle);
+ req->permanent = 0;
+ }
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status)
+ memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr,
+ u32 if_id, u32 *pmac_id)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_pmac_add *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req));
+
+ req->if_id = cpu_to_le32(if_id);
+ memcpy(req->mac_address, mac_addr, ETH_ALEN);
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb);
+ *pmac_id = le32_to_cpu(resp->pmac_id);
+ }
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_pmac_del *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req));
+
+ req->if_id = cpu_to_le32(if_id);
+ req->pmac_id = cpu_to_le32(pmac_id);
+
+ status = be_mbox_db_ring(ctrl);
+ spin_unlock(&ctrl->cmd_lock);
+
+ return status;
+}
+
+int be_cmd_cq_create(struct be_ctrl_info *ctrl,
+ struct be_queue_info *cq, struct be_queue_info *eq,
+ bool sol_evts, bool no_delay, int coalesce_wm)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_cq_create *req = embedded_payload(wrb);
+ struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
+ struct be_dma_mem *q_mem = &cq->dma_mem;
+ void *ctxt = &req->context;
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_CQ_CREATE, sizeof(*req));
+
+ req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
+
+ AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm);
+ AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
+ AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
+ __ilog2_u32(cq->len/256));
+ AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
+ AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
+ AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
+ AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 0);
+ AMAP_SET_BITS(struct amap_cq_context, func, ctxt, ctrl->pci_func);
+ be_dws_cpu_to_le(ctxt, sizeof(req->context));
+
+ be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ cq->id = le16_to_cpu(resp->cq_id);
+ cq->created = true;
+ }
+ spin_unlock(&ctrl->cmd_lock);
+
+ return status;
+}
+
+int be_cmd_txq_create(struct be_ctrl_info *ctrl,
+ struct be_queue_info *txq,
+ struct be_queue_info *cq)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_eth_tx_create *req = embedded_payload(wrb);
+ struct be_dma_mem *q_mem = &txq->dma_mem;
+ void *ctxt = &req->context;
+ int status;
+ u32 len_encoded;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE,
+ sizeof(*req));
+
+ req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+ req->ulp_num = BE_ULP1_NUM;
+ req->type = BE_ETH_TX_RING_TYPE_STANDARD;
+
+ len_encoded = fls(txq->len); /* log2(len) + 1 */
+ if (len_encoded == 16)
+ len_encoded = 0;
+ AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, len_encoded);
+ AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
+ ctrl->pci_func);
+ AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);
+
+ be_dws_cpu_to_le(ctxt, sizeof(req->context));
+
+ be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb);
+ txq->id = le16_to_cpu(resp->cid);
+ txq->created = true;
+ }
+ spin_unlock(&ctrl->cmd_lock);
+
+ return status;
+}
+
+int be_cmd_rxq_create(struct be_ctrl_info *ctrl,
+ struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
+ u16 max_frame_size, u32 if_id, u32 rss)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_eth_rx_create *req = embedded_payload(wrb);
+ struct be_dma_mem *q_mem = &rxq->dma_mem;
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_RX_CREATE,
+ sizeof(*req));
+
+ req->cq_id = cpu_to_le16(cq_id);
+ req->frag_size = fls(frag_size) - 1;
+ req->num_pages = 2;
+ be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+ req->interface_id = cpu_to_le32(if_id);
+ req->max_frame_size = cpu_to_le16(max_frame_size);
+ req->rss_queue = cpu_to_le32(rss);
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
+ rxq->id = le16_to_cpu(resp->id);
+ rxq->created = true;
+ }
+ spin_unlock(&ctrl->cmd_lock);
+
+ return status;
+}
+
+/* Generic destroyer function for all types of queues */
+int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
+ int queue_type)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
+ u8 subsys = 0, opcode = 0;
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+
+ memset(wrb, 0, sizeof(*wrb));
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ switch (queue_type) {
+ case QTYPE_EQ:
+ subsys = CMD_SUBSYSTEM_COMMON;
+ opcode = OPCODE_COMMON_EQ_DESTROY;
+ break;
+ case QTYPE_CQ:
+ subsys = CMD_SUBSYSTEM_COMMON;
+ opcode = OPCODE_COMMON_CQ_DESTROY;
+ break;
+ case QTYPE_TXQ:
+ subsys = CMD_SUBSYSTEM_ETH;
+ opcode = OPCODE_ETH_TX_DESTROY;
+ break;
+ case QTYPE_RXQ:
+ subsys = CMD_SUBSYSTEM_ETH;
+ opcode = OPCODE_ETH_RX_DESTROY;
+ break;
+ default:
+ printk(KERN_WARNING DRV_NAME ":bad Q type in Q destroy cmd\n");
+ status = -1;
+ goto err;
+ }
+ be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
+ req->id = cpu_to_le16(q->id);
+
+ status = be_mbox_db_ring(ctrl);
+err:
+ spin_unlock(&ctrl->cmd_lock);
+
+ return status;
+}
+
+/* Create an rx filtering policy configuration on an i/f */
+int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 flags, u8 *mac,
+ bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_if_create *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
+
+ req->capability_flags = cpu_to_le32(flags);
+ req->enable_flags = cpu_to_le32(flags);
+ if (!pmac_invalid)
+ memcpy(req->mac_addr, mac, ETH_ALEN);
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_if_create *resp = embedded_payload(wrb);
+ *if_handle = le32_to_cpu(resp->interface_id);
+ if (!pmac_invalid)
+ *pmac_id = le32_to_cpu(resp->pmac_id);
+ }
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 interface_id)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_if_destroy *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req));
+
+ req->interface_id = cpu_to_le32(interface_id);
+ status = be_mbox_db_ring(ctrl);
+
+ spin_unlock(&ctrl->cmd_lock);
+
+ return status;
+}
+
+/* Get stats is a non embedded command: the request is not embedded inside
+ * WRB but is a separate dma memory block
+ */
+int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_get_stats *req = nonemb_cmd->va;
+ struct be_sge *sge = nonembedded_sgl(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ memset(req, 0, sizeof(*req));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
+ OPCODE_ETH_GET_STATISTICS, sizeof(*req));
+ sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+ sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+ sge->len = cpu_to_le32(nonemb_cmd->size);
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_get_stats *resp = nonemb_cmd->va;
+ be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats));
+ }
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_link_status_query(struct be_ctrl_info *ctrl,
+ struct be_link_info *link)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_link_status *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req));
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
+ link->speed = resp->mac_speed;
+ link->duplex = resp->mac_duplex;
+ link->fault = resp->mac_fault;
+ } else {
+ link->speed = PHY_LINK_SPEED_ZERO;
+ }
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_get_fw_version *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_FW_VERSION, sizeof(*req));
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
+ strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
+ }
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+/* set the EQ delay interval of an EQ to specified value */
+int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
+
+ req->num_eq = cpu_to_le32(1);
+ req->delay[0].eq_id = cpu_to_le32(eq_id);
+ req->delay[0].phase = 0;
+ req->delay[0].delay_multiplier = cpu_to_le32(eqd);
+
+ status = be_mbox_db_ring(ctrl);
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, u16 *vtag_array,
+ u32 num, bool untagged, bool promiscuous)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_vlan_config *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req));
+
+ req->interface_id = if_id;
+ req->promiscuous = promiscuous;
+ req->untagged = untagged;
+ req->num_vlan = num;
+ if (!promiscuous) {
+ memcpy(req->normal_vlan, vtag_array,
+ req->num_vlan * sizeof(vtag_array[0]));
+ }
+
+ status = be_mbox_db_ring(ctrl);
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_promiscuous_config *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
+ OPCODE_ETH_PROMISCUOUS, sizeof(*req));
+
+ if (port_num)
+ req->port1_promiscuous = en;
+ else
+ req->port0_promiscuous = en;
+
+ status = be_mbox_db_ring(ctrl);
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table,
+ u32 num, bool promiscuous)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_mcast_mac_config *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
+
+ req->interface_id = if_id;
+ req->promiscuous = promiscuous;
+ if (!promiscuous) {
+ req->num_mac = cpu_to_le16(num);
+ if (num)
+ memcpy(req->mac, mac_table, ETH_ALEN * num);
+ }
+
+ status = be_mbox_db_ring(ctrl);
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_set_flow_control *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req));
+
+ req->tx_flow_control = cpu_to_le16((u16)tx_fc);
+ req->rx_flow_control = cpu_to_le16((u16)rx_fc);
+
+ status = be_mbox_db_ring(ctrl);
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, u32 *tx_fc, u32 *rx_fc)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_get_flow_control *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req));
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_get_flow_control *resp =
+ embedded_payload(wrb);
+ *tx_fc = le16_to_cpu(resp->tx_flow_control);
+ *rx_fc = le16_to_cpu(resp->rx_flow_control);
+ }
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
+
+int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num)
+{
+ struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb);
+ int status;
+
+ spin_lock(&ctrl->cmd_lock);
+
+ memset(wrb, 0, sizeof(*wrb));
+
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
+
+ status = be_mbox_db_ring(ctrl);
+ if (!status) {
+ struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
+ *port_num = le32_to_cpu(resp->phys_port);
+ }
+
+ spin_unlock(&ctrl->cmd_lock);
+ return status;
+}
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
new file mode 100644
index 00000000000..e499e2d5b8c
--- /dev/null
+++ b/drivers/net/benet/be_cmds.h
@@ -0,0 +1,688 @@
+/*
+ * Copyright (C) 2005 - 2009 ServerEngines
+ * 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. The full GNU General
+ * Public License is included in this distribution in the file called COPYING.
+ *
+ * Contact Information:
+ * linux-drivers@serverengines.com
+ *
+ * ServerEngines
+ * 209 N. Fair Oaks Ave
+ * Sunnyvale, CA 94085
+ */
+
+/*
+ * The driver sends configuration and managements command requests to the
+ * firmware in the BE. These requests are communicated to the processor
+ * using Work Request Blocks (WRBs) submitted to the MCC-WRB ring or via one
+ * WRB inside a MAILBOX.
+ * The commands are serviced by the ARM processor in the BladeEngine's MPU.
+ */
+
+struct be_sge {
+ u32 pa_lo;
+ u32 pa_hi;
+ u32 len;
+};
+
+#define MCC_WRB_EMBEDDED_MASK 1 /* bit 0 of dword 0*/
+#define MCC_WRB_SGE_CNT_SHIFT 3 /* bits 3 - 7 of dword 0 */
+#define MCC_WRB_SGE_CNT_MASK 0x1F /* bits 3 - 7 of dword 0 */
+struct be_mcc_wrb {
+ u32 embedded; /* dword 0 */
+ u32 payload_length; /* dword 1 */
+ u32 tag0; /* dword 2 */
+ u32 tag1; /* dword 3 */
+ u32 rsvd; /* dword 4 */
+ union {
+ u8 embedded_payload[236]; /* used by embedded cmds */
+ struct be_sge sgl[19]; /* used by non-embedded cmds */
+ } payload;
+};
+
+#define CQE_FLAGS_VALID_MASK (1 << 31)
+#define CQE_FLAGS_ASYNC_MASK (1 << 30)
+#define CQE_FLAGS_COMPLETED_MASK (1 << 28)
+#define CQE_FLAGS_CONSUMED_MASK (1 << 27)
+
+/* Completion Status */
+enum {
+ MCC_STATUS_SUCCESS = 0x0,
+/* The client does not have sufficient privileges to execute the command */
+ MCC_STATUS_INSUFFICIENT_PRIVILEGES = 0x1,
+/* A parameter in the command was invalid. */
+ MCC_STATUS_INVALID_PARAMETER = 0x2,
+/* There are insufficient chip resources to execute the command */
+ MCC_STATUS_INSUFFICIENT_RESOURCES = 0x3,
+/* The command is completing because the queue was getting flushed */
+ MCC_STATUS_QUEUE_FLUSHING = 0x4,
+/* The command is completing with a DMA error */
+ MCC_STATUS_DMA_FAILED = 0x5
+};
+
+#define CQE_STATUS_COMPL_MASK 0xFFFF
+#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */
+#define CQE_STATUS_EXTD_MASK 0xFFFF
+#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */
+
+struct be_mcc_cq_entry {
+ u32 status; /* dword 0 */
+ u32 tag0; /* dword 1 */
+ u32 tag1; /* dword 2 */
+ u32 flags; /* dword 3 */
+};
+
+struct be_mcc_mailbox {
+ struct be_mcc_wrb wrb;
+ struct be_mcc_cq_entry cqe;
+};
+
+#define CMD_SUBSYSTEM_COMMON 0x1
+#define CMD_SUBSYSTEM_ETH 0x3
+
+#define OPCODE_COMMON_NTWK_MAC_QUERY 1
+#define OPCODE_COMMON_NTWK_MAC_SET 2
+#define OPCODE_COMMON_NTWK_MULTICAST_SET 3
+#define OPCODE_COMMON_NTWK_VLAN_CONFIG 4
+#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY 5
+#define OPCODE_COMMON_CQ_CREATE 12
+#define OPCODE_COMMON_EQ_CREATE 13
+#define OPCODE_COMMON_MCC_CREATE 21
+#define OPCODE_COMMON_NTWK_RX_FILTER 34
+#define OPCODE_COMMON_GET_FW_VERSION 35
+#define OPCODE_COMMON_SET_FLOW_CONTROL 36
+#define OPCODE_COMMON_GET_FLOW_CONTROL 37
+#define OPCODE_COMMON_SET_FRAME_SIZE 39
+#define OPCODE_COMMON_MODIFY_EQ_DELAY 41
+#define OPCODE_COMMON_FIRMWARE_CONFIG 42
+#define OPCODE_COMMON_NTWK_INTERFACE_CREATE 50
+#define OPCODE_COMMON_NTWK_INTERFACE_DESTROY 51
+#define OPCODE_COMMON_CQ_DESTROY 54
+#define OPCODE_COMMON_EQ_DESTROY 55
+#define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58
+#define OPCODE_COMMON_NTWK_PMAC_ADD 59
+#define OPCODE_COMMON_NTWK_PMAC_DEL 60
+
+#define OPCODE_ETH_ACPI_CONFIG 2
+#define OPCODE_ETH_PROMISCUOUS 3
+#define OPCODE_ETH_GET_STATISTICS 4
+#define OPCODE_ETH_TX_CREATE 7
+#define OPCODE_ETH_RX_CREATE 8
+#define OPCODE_ETH_TX_DESTROY 9
+#define OPCODE_ETH_RX_DESTROY 10
+
+struct be_cmd_req_hdr {
+ u8 opcode; /* dword 0 */
+ u8 subsystem; /* dword 0 */
+ u8 port_number; /* dword 0 */
+ u8 domain; /* dword 0 */
+ u32 timeout; /* dword 1 */
+ u32 request_length; /* dword 2 */
+ u32 rsvd; /* dword 3 */
+};
+
+#define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */
+#define RESP_HDR_INFO_SUBSYS_SHIFT 8 /* bits 8 - 15 */
+struct be_cmd_resp_hdr {
+ u32 info; /* dword 0 */
+ u32 status; /* dword 1 */
+ u32 response_length; /* dword 2 */
+ u32 actual_resp_len; /* dword 3 */
+};
+
+struct phys_addr {
+ u32 lo;
+ u32 hi;
+};
+
+/**************************
+ * BE Command definitions *
+ **************************/
+
+/* Pseudo amap definition in which each bit of the actual structure is defined
+ * as a byte: used to calculate offset/shift/mask of each field */
+struct amap_eq_context {
+ u8 cidx[13]; /* dword 0*/
+ u8 rsvd0[3]; /* dword 0*/
+ u8 epidx[13]; /* dword 0*/
+ u8 valid; /* dword 0*/
+ u8 rsvd1; /* dword 0*/
+ u8 size; /* dword 0*/
+ u8 pidx[13]; /* dword 1*/
+ u8 rsvd2[3]; /* dword 1*/
+ u8 pd[10]; /* dword 1*/
+ u8 count[3]; /* dword 1*/
+ u8 solevent; /* dword 1*/
+ u8 stalled; /* dword 1*/
+ u8 armed; /* dword 1*/
+ u8 rsvd3[4]; /* dword 2*/
+ u8 func[8]; /* dword 2*/
+ u8 rsvd4; /* dword 2*/
+ u8 delaymult[10]; /* dword 2*/
+ u8 rsvd5[2]; /* dword 2*/
+ u8 phase[2]; /* dword 2*/
+ u8 nodelay; /* dword 2*/
+ u8 rsvd6[4]; /* dword 2*/
+ u8 rsvd7[32]; /* dword 3*/
+} __packed;
+
+struct be_cmd_req_eq_create {
+ struct be_cmd_req_hdr hdr;
+ u16 num_pages; /* sword */
+ u16 rsvd0; /* sword */
+ u8 context[sizeof(struct amap_eq_context) / 8];
+ struct phys_addr pages[8];
+} __packed;
+
+struct be_cmd_resp_eq_create {
+ struct be_cmd_resp_hdr resp_hdr;
+ u16 eq_id; /* sword */
+ u16 rsvd0; /* sword */
+} __packed;
+
+/******************** Mac query ***************************/
+enum {
+ MAC_ADDRESS_TYPE_STORAGE = 0x0,
+ MAC_ADDRESS_TYPE_NETWORK = 0x1,
+ MAC_ADDRESS_TYPE_PD = 0x2,
+ MAC_ADDRESS_TYPE_MANAGEMENT = 0x3
+};
+
+struct mac_addr {
+ u16 size_of_struct;
+ u8 addr[ETH_ALEN];
+} __packed;
+
+struct be_cmd_req_mac_query {
+ struct be_cmd_req_hdr hdr;
+ u8 type;
+ u8 permanent;
+ u16 if_id;
+} __packed;
+
+struct be_cmd_resp_mac_query {
+ struct be_cmd_resp_hdr hdr;
+ struct mac_addr mac;
+};
+
+/******************** PMac Add ***************************/
+struct be_cmd_req_pmac_add {
+ struct be_cmd_req_hdr hdr;
+ u32 if_id;
+ u8 mac_address[ETH_ALEN];
+ u8 rsvd0[2];
+} __packed;
+
+struct be_cmd_resp_pmac_add {
+ struct be_cmd_resp_hdr hdr;
+ u32 pmac_id;
+};
+
+/******************** PMac Del ***************************/
+struct be_cmd_req_pmac_del {
+ struct be_cmd_req_hdr hdr;
+ u32 if_id;
+ u32 pmac_id;
+};
+
+/******************** Create CQ ***************************/
+/* Pseudo amap definition in which each bit of the actual structure is defined
+ * as a byte: used to calculate offset/shift/mask of each field */
+struct amap_cq_context {
+ u8 cidx[11]; /* dword 0*/
+ u8 rsvd0; /* dword 0*/
+ u8 coalescwm[2]; /* dword 0*/
+ u8 nodelay; /* dword 0*/
+ u8 epidx[11]; /* dword 0*/
+ u8 rsvd1; /* dword 0*/
+ u8 count[2]; /* dword 0*/
+ u8 valid; /* dword 0*/
+ u8 solevent; /* dword 0*/
+ u8 eventable; /* dword 0*/
+ u8 pidx[11]; /* dword 1*/
+ u8 rsvd2; /* dword 1*/
+ u8 pd[10]; /* dword 1*/
+ u8 eqid[8]; /* dword 1*/
+ u8 stalled; /* dword 1*/
+ u8 armed; /* dword 1*/
+ u8 rsvd3[4]; /* dword 2*/
+ u8 func[8]; /* dword 2*/
+ u8 rsvd4[20]; /* dword 2*/
+ u8 rsvd5[32]; /* dword 3*/
+} __packed;
+
+struct be_cmd_req_cq_create {
+ struct be_cmd_req_hdr hdr;
+ u16 num_pages;
+ u16 rsvd0;
+ u8 context[sizeof(struct amap_cq_context) / 8];
+ struct phys_addr pages[8];
+} __packed;
+
+struct be_cmd_resp_cq_create {
+ struct be_cmd_resp_hdr hdr;
+ u16 cq_id;
+ u16 rsvd0;
+} __packed;
+
+/******************** Create TxQ ***************************/
+#define BE_ETH_TX_RING_TYPE_STANDARD 2
+#define BE_ULP1_NUM 1
+
+/* Pseudo amap definition in which each bit of the actual structure is defined
+ * as a byte: used to calculate offset/shift/mask of each field */
+struct amap_tx_context {
+ u8 rsvd0[16]; /* dword 0 */
+ u8 tx_ring_size[4]; /* dword 0 */
+ u8 rsvd1[26]; /* dword 0 */
+ u8 pci_func_id[8]; /* dword 1 */
+ u8 rsvd2[9]; /* dword 1 */
+ u8 ctx_valid; /* dword 1 */
+ u8 cq_id_send[16]; /* dword 2 */
+ u8 rsvd3[16]; /* dword 2 */
+ u8 rsvd4[32]; /* dword 3 */
+ u8 rsvd5[32]; /* dword 4 */
+ u8 rsvd6[32]; /* dword 5 */
+ u8 rsvd7[32]; /* dword 6 */
+ u8 rsvd8[32]; /* dword 7 */
+ u8 rsvd9[32]; /* dword 8 */
+ u8 rsvd10[32]; /* dword 9 */
+ u8 rsvd11[32]; /* dword 10 */
+ u8 rsvd12[32]; /* dword 11 */
+ u8 rsvd13[32]; /* dword 12 */
+ u8 rsvd14[32]; /* dword 13 */
+ u8 rsvd15[32]; /* dword 14 */
+ u8 rsvd16[32]; /* dword 15 */
+} __packed;
+
+struct be_cmd_req_eth_tx_create {
+ struct be_cmd_req_hdr hdr;
+ u8 num_pages;
+ u8 ulp_num;
+ u8 type;
+ u8 bound_port;
+ u8 context[sizeof(struct amap_tx_context) / 8];
+ struct phys_addr pages[8];
+} __packed;
+
+struct be_cmd_resp_eth_tx_create {
+ struct be_cmd_resp_hdr hdr;
+ u16 cid;
+ u16 rsvd0;
+} __packed;
+
+/******************** Create RxQ ***************************/
+struct be_cmd_req_eth_rx_create {
+ struct be_cmd_req_hdr hdr;
+ u16 cq_id;
+ u8 frag_size;
+ u8 num_pages;
+ struct phys_addr pages[2];
+ u32 interface_id;
+ u16 max_frame_size;
+ u16 rsvd0;
+ u32 rss_queue;
+} __packed;
+
+struct be_cmd_resp_eth_rx_create {
+ struct be_cmd_resp_hdr hdr;
+ u16 id;
+ u8 cpu_id;
+ u8 rsvd0;
+} __packed;
+
+/******************** Q Destroy ***************************/
+/* Type of Queue to be destroyed */
+enum {
+ QTYPE_EQ = 1,
+ QTYPE_CQ,
+ QTYPE_TXQ,
+ QTYPE_RXQ
+};
+
+struct be_cmd_req_q_destroy {
+ struct be_cmd_req_hdr hdr;
+ u16 id;
+ u16 bypass_flush; /* valid only for rx q destroy */
+} __packed;
+
+/************ I/f Create (it's actually I/f Config Create)**********/
+
+/* Capability flags for the i/f */
+enum be_if_flags {
+ BE_IF_FLAGS_RSS = 0x4,
+ BE_IF_FLAGS_PROMISCUOUS = 0x8,
+ BE_IF_FLAGS_BROADCAST = 0x10,
+ BE_IF_FLAGS_UNTAGGED = 0x20,
+ BE_IF_FLAGS_ULP = 0x40,
+ BE_IF_FLAGS_VLAN_PROMISCUOUS = 0x80,
+ BE_IF_FLAGS_VLAN = 0x100,
+ BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200,
+ BE_IF_FLAGS_PASS_L2_ERRORS = 0x400,
+ BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800
+};
+
+/* An RX interface is an object with one or more MAC addresses and
+ * filtering capabilities. */
+struct be_cmd_req_if_create {
+ struct be_cmd_req_hdr hdr;
+ u32 version; /* ignore currntly */
+ u32 capability_flags;
+ u32 enable_flags;
+ u8 mac_addr[ETH_ALEN];
+ u8 rsvd0;
+ u8 pmac_invalid; /* if set, don't attach the mac addr to the i/f */
+ u32 vlan_tag; /* not used currently */
+} __packed;
+
+struct be_cmd_resp_if_create {
+ struct be_cmd_resp_hdr hdr;
+ u32 interface_id;
+ u32 pmac_id;
+};
+
+/****** I/f Destroy(it's actually I/f Config Destroy )**********/
+struct be_cmd_req_if_destroy {
+ struct be_cmd_req_hdr hdr;
+ u32 interface_id;
+};
+
+/*************** HW Stats Get **********************************/
+struct be_port_rxf_stats {
+ u32 rx_bytes_lsd; /* dword 0*/
+ u32 rx_bytes_msd; /* dword 1*/
+ u32 rx_total_frames; /* dword 2*/
+ u32 rx_unicast_frames; /* dword 3*/
+ u32 rx_multicast_frames; /* dword 4*/
+ u32 rx_broadcast_frames; /* dword 5*/
+ u32 rx_crc_errors; /* dword 6*/
+ u32 rx_alignment_symbol_errors; /* dword 7*/
+ u32 rx_pause_frames; /* dword 8*/
+ u32 rx_control_frames; /* dword 9*/
+ u32 rx_in_range_errors; /* dword 10*/
+ u32 rx_out_range_errors; /* dword 11*/
+ u32 rx_frame_too_long; /* dword 12*/
+ u32 rx_address_match_errors; /* dword 13*/
+ u32 rx_vlan_mismatch; /* dword 14*/
+ u32 rx_dropped_too_small; /* dword 15*/
+ u32 rx_dropped_too_short; /* dword 16*/
+ u32 rx_dropped_header_too_small; /* dword 17*/
+ u32 rx_dropped_tcp_length; /* dword 18*/
+ u32 rx_dropped_runt; /* dword 19*/
+ u32 rx_64_byte_packets; /* dword 20*/
+ u32 rx_65_127_byte_packets; /* dword 21*/
+ u32 rx_128_256_byte_packets; /* dword 22*/
+ u32 rx_256_511_byte_packets; /* dword 23*/
+ u32 rx_512_1023_byte_packets; /* dword 24*/
+ u32 rx_1024_1518_byte_packets; /* dword 25*/
+ u32 rx_1519_2047_byte_packets; /* dword 26*/
+ u32 rx_2048_4095_byte_packets; /* dword 27*/
+ u32 rx_4096_8191_byte_packets; /* dword 28*/
+ u32 rx_8192_9216_byte_packets; /* dword 29*/
+ u32 rx_ip_checksum_errs; /* dword 30*/
+ u32 rx_tcp_checksum_errs; /* dword 31*/
+ u32 rx_udp_checksum_errs; /* dword 32*/
+ u32 rx_non_rss_packets; /* dword 33*/
+ u32 rx_ipv4_packets; /* dword 34*/
+ u32 rx_ipv6_packets; /* dword 35*/
+ u32 rx_ipv4_bytes_lsd; /* dword 36*/
+ u32 rx_ipv4_bytes_msd; /* dword 37*/
+ u32 rx_ipv6_bytes_lsd; /* dword 38*/
+ u32 rx_ipv6_bytes_msd; /* dword 39*/
+ u32 rx_chute1_packets; /* dword 40*/
+ u32 rx_chute2_packets; /* dword 41*/
+ u32 rx_chute3_packets; /* dword 42*/
+ u32 rx_management_packets; /* dword 43*/
+ u32 rx_switched_unicast_packets; /* dword 44*/
+ u32 rx_switched_multicast_packets; /* dword 45*/
+ u32 rx_switched_broadcast_packets; /* dword 46*/
+ u32 tx_bytes_lsd; /* dword 47*/
+ u32 tx_bytes_msd; /* dword 48*/
+ u32 tx_unicastframes; /* dword 49*/
+ u32 tx_multicastframes; /* dword 50*/
+ u32 tx_broadcastframes; /* dword 51*/
+ u32 tx_pauseframes; /* dword 52*/
+ u32 tx_controlframes; /* dword 53*/
+ u32 tx_64_byte_packets; /* dword 54*/
+ u32 tx_65_127_byte_packets; /* dword 55*/
+ u32 tx_128_256_byte_packets; /* dword 56*/
+ u32 tx_256_511_byte_packets; /* dword 57*/
+ u32 tx_512_1023_byte_packets; /* dword 58*/
+ u32 tx_1024_1518_byte_packets; /* dword 59*/
+ u32 tx_1519_2047_byte_packets; /* dword 60*/
+ u32 tx_2048_4095_byte_packets; /* dword 61*/
+ u32 tx_4096_8191_byte_packets; /* dword 62*/
+ u32 tx_8192_9216_byte_packets; /* dword 63*/
+ u32 rx_fifo_overflow; /* dword 64*/
+ u32 rx_input_fifo_overflow; /* dword 65*/
+};
+
+struct be_rxf_stats {
+ struct be_port_rxf_stats port[2];
+ u32 rx_drops_no_pbuf; /* dword 132*/
+ u32 rx_drops_no_txpb; /* dword 133*/
+ u32 rx_drops_no_erx_descr; /* dword 134*/
+ u32 rx_drops_no_tpre_descr; /* dword 135*/
+ u32 management_rx_port_packets; /* dword 136*/
+ u32 management_rx_port_bytes; /* dword 137*/
+ u32 management_rx_port_pause_frames; /* dword 138*/
+ u32 management_rx_port_errors; /* dword 139*/
+ u32 management_tx_port_packets; /* dword 140*/
+ u32 management_tx_port_bytes; /* dword 141*/
+ u32 management_tx_port_pause; /* dword 142*/
+ u32 management_rx_port_rxfifo_overflow; /* dword 143*/
+ u32 rx_drops_too_many_frags; /* dword 144*/
+ u32 rx_drops_invalid_ring; /* dword 145*/
+ u32 forwarded_packets; /* dword 146*/
+ u32 rx_drops_mtu; /* dword 147*/
+ u32 rsvd0[15];
+};
+
+struct be_erx_stats {
+ u32 rx_drops_no_fragments[44]; /* dwordS 0 to 43*/
+ u32 debug_wdma_sent_hold; /* dword 44*/
+ u32 debug_wdma_pbfree_sent_hold; /* dword 45*/
+ u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/
+ u32 debug_pmem_pbuf_dealloc; /* dword 47*/
+};
+
+struct be_hw_stats {
+ struct be_rxf_stats rxf;
+ u32 rsvd[48];
+ struct be_erx_stats erx;
+};
+
+struct be_cmd_req_get_stats {
+ struct be_cmd_req_hdr hdr;
+ u8 rsvd[sizeof(struct be_hw_stats)];
+};
+
+struct be_cmd_resp_get_stats {
+ struct be_cmd_resp_hdr hdr;
+ struct be_hw_stats hw_stats;
+};
+
+struct be_cmd_req_vlan_config {
+ struct be_cmd_req_hdr hdr;
+ u8 interface_id;
+ u8 promiscuous;
+ u8 untagged;
+ u8 num_vlan;
+ u16 normal_vlan[64];
+} __packed;
+
+struct be_cmd_req_promiscuous_config {
+ struct be_cmd_req_hdr hdr;
+ u8 port0_promiscuous;
+ u8 port1_promiscuous;
+ u16 rsvd0;
+} __packed;
+
+struct macaddr {
+ u8 byte[ETH_ALEN];
+};
+
+struct be_cmd_req_mcast_mac_config {
+ struct be_cmd_req_hdr hdr;
+ u16 num_mac;
+ u8 promiscuous;
+ u8 interface_id;
+ struct macaddr mac[32];
+} __packed;
+
+static inline struct be_hw_stats *
+hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd)
+{
+ return &cmd->hw_stats;
+}
+
+/******************** Link Status Query *******************/
+struct be_cmd_req_link_status {
+ struct be_cmd_req_hdr hdr;
+ u32 rsvd;
+};
+
+struct be_link_info {
+ u8 duplex;
+ u8 speed;
+ u8 fault;
+};
+
+enum {
+ PHY_LINK_DUPLEX_NONE = 0x0,
+ PHY_LINK_DUPLEX_HALF = 0x1,
+ PHY_LINK_DUPLEX_FULL = 0x2
+};
+
+enum {
+ PHY_LINK_SPEED_ZERO = 0x0, /* => No link */
+ PHY_LINK_SPEED_10MBPS = 0x1,
+ PHY_LINK_SPEED_100MBPS = 0x2,
+ PHY_LINK_SPEED_1GBPS = 0x3,
+ PHY_LINK_SPEED_10GBPS = 0x4
+};
+
+struct be_cmd_resp_link_status {
+ struct be_cmd_resp_hdr hdr;
+ u8 physical_port;
+ u8 mac_duplex;
+ u8 mac_speed;
+ u8 mac_fault;
+ u8 mgmt_mac_duplex;
+ u8 mgmt_mac_speed;
+ u16 rsvd0;
+} __packed;
+
+/******************** Get FW Version *******************/
+#define FW_VER_LEN 32
+struct be_cmd_req_get_fw_version {
+ struct be_cmd_req_hdr hdr;
+ u8 rsvd0[FW_VER_LEN];
+ u8 rsvd1[FW_VER_LEN];
+} __packed;
+
+struct be_cmd_resp_get_fw_version {
+ struct be_cmd_resp_hdr hdr;
+ u8 firmware_version_string[FW_VER_LEN];
+ u8 fw_on_flash_version_string[FW_VER_LEN];
+} __packed;
+
+/******************** Set Flow Contrl *******************/
+struct be_cmd_req_set_flow_control {
+ struct be_cmd_req_hdr hdr;
+ u16 tx_flow_control;
+ u16 rx_flow_control;
+} __packed;
+
+/******************** Get Flow Contrl *******************/
+struct be_cmd_req_get_flow_control {
+ struct be_cmd_req_hdr hdr;
+ u32 rsvd;
+};
+
+struct be_cmd_resp_get_flow_control {
+ struct be_cmd_resp_hdr hdr;
+ u16 tx_flow_control;
+ u16 rx_flow_control;
+} __packed;
+
+/******************** Modify EQ Delay *******************/
+struct be_cmd_req_modify_eq_delay {
+ struct be_cmd_req_hdr hdr;
+ u32 num_eq;
+ struct {
+ u32 eq_id;
+ u32 phase;
+ u32 delay_multiplier;
+ } delay[8];
+} __packed;
+
+struct be_cmd_resp_modify_eq_delay {
+ struct be_cmd_resp_hdr hdr;
+ u32 rsvd0;
+} __packed;
+
+/******************** Get FW Config *******************/
+struct be_cmd_req_query_fw_cfg {
+ struct be_cmd_req_hdr hdr;
+ u32 rsvd[30];
+};
+
+struct be_cmd_resp_query_fw_cfg {
+ struct be_cmd_resp_hdr hdr;
+ u32 be_config_number;
+ u32 asic_revision;
+ u32 phys_port;
+ u32 function_mode;
+ u32 rsvd[26];
+};
+
+extern int be_pci_fnum_get(struct be_ctrl_info *ctrl);
+extern int be_cmd_POST(struct be_ctrl_info *ctrl);
+extern int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr,
+ u8 type, bool permanent, u32 if_handle);
+extern int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr,
+ u32 if_id, u32 *pmac_id);
+extern int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id);
+extern int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 if_flags, u8 *mac,
+ bool pmac_invalid, u32 *if_handle, u32 *pmac_id);
+extern int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 if_handle);
+extern int be_cmd_eq_create(struct be_ctrl_info *ctrl,
+ struct be_queue_info *eq, int eq_delay);
+extern int be_cmd_cq_create(struct be_ctrl_info *ctrl,
+ struct be_queue_info *cq, struct be_queue_info *eq,
+ bool sol_evts, bool no_delay,
+ int num_cqe_dma_coalesce);
+extern int be_cmd_txq_create(struct be_ctrl_info *ctrl,
+ struct be_queue_info *txq,
+ struct be_queue_info *cq);
+extern int be_cmd_rxq_create(struct be_ctrl_info *ctrl,
+ struct be_queue_info *rxq, u16 cq_id,
+ u16 frag_size, u16 max_frame_size, u32 if_id,
+ u32 rss);
+extern int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
+ int type);
+extern int be_cmd_link_status_query(struct be_ctrl_info *ctrl,
+ struct be_link_info *link);
+extern int be_cmd_reset(struct be_ctrl_info *ctrl);
+extern int be_cmd_get_stats(struct be_ctrl_info *ctrl,
+ struct be_dma_mem *nonemb_cmd);
+extern int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver);
+
+extern int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd);
+extern int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id,
+ u16 *vtag_array, u32 num, bool untagged,
+ bool promiscuous);
+extern int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl,
+ u8 port_num, bool en);
+extern int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id,
+ u8 *mac_table, u32 num, bool promiscuous);
+extern int be_cmd_set_flow_control(struct be_ctrl_info *ctrl,
+ u32 tx_fc, u32 rx_fc);
+extern int be_cmd_get_flow_control(struct be_ctrl_info *ctrl,
+ u32 *tx_fc, u32 *rx_fc);
+extern int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
new file mode 100644
index 00000000000..04f4b73fa8d
--- /dev/null
+++ b/drivers/net/benet/be_ethtool.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2005 - 2009 ServerEngines
+ * 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. The full GNU General
+ * Public License is included in this distribution in the file called COPYING.
+ *
+ * Contact Information:
+ * linux-drivers@serverengines.com
+ *
+ * ServerEngines
+ * 209 N. Fair Oaks Ave
+ * Sunnyvale, CA 94085
+ */
+
+#include "be.h"
+#include <linux/ethtool.h>
+
+struct be_ethtool_stat {
+ char desc[ETH_GSTRING_LEN];
+ int type;
+ int size;
+ int offset;
+};
+
+enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT, ERXSTAT};
+#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
+ offsetof(_struct, field)
+#define NETSTAT_INFO(field) #field, NETSTAT,\
+ FIELDINFO(struct net_device_stats,\
+ field)
+#define DRVSTAT_INFO(field) #field, DRVSTAT,\
+ FIELDINFO(struct be_drvr_stats, field)
+#define MISCSTAT_INFO(field) #field, MISCSTAT,\
+ FIELDINFO(struct be_rxf_stats, field)
+#define PORTSTAT_INFO(field) #field, PORTSTAT,\
+ FIELDINFO(struct be_port_rxf_stats, \
+ field)
+#define ERXSTAT_INFO(field) #field, ERXSTAT,\
+ FIELDINFO(struct be_erx_stats, field)
+
+static const struct be_ethtool_stat et_stats[] = {
+ {NETSTAT_INFO(rx_packets)},
+ {NETSTAT_INFO(tx_packets)},
+ {NETSTAT_INFO(rx_bytes)},
+ {NETSTAT_INFO(tx_bytes)},
+ {NETSTAT_INFO(rx_errors)},
+ {NETSTAT_INFO(tx_errors)},
+ {NETSTAT_INFO(rx_dropped)},
+ {NETSTAT_INFO(tx_dropped)},
+ {DRVSTAT_INFO(be_tx_reqs)},
+ {DRVSTAT_INFO(be_tx_stops)},
+ {DRVSTAT_INFO(be_fwd_reqs)},
+ {DRVSTAT_INFO(be_tx_wrbs)},
+ {DRVSTAT_INFO(be_polls)},
+ {DRVSTAT_INFO(be_tx_events)},
+ {DRVSTAT_INFO(be_rx_events)},
+ {DRVSTAT_INFO(be_tx_compl)},
+ {DRVSTAT_INFO(be_rx_compl)},
+ {DRVSTAT_INFO(be_ethrx_post_fail)},
+ {DRVSTAT_INFO(be_802_3_dropped_frames)},
+ {DRVSTAT_INFO(be_802_3_malformed_frames)},
+ {DRVSTAT_INFO(be_tx_rate)},
+ {DRVSTAT_INFO(be_rx_rate)},
+ {PORTSTAT_INFO(rx_unicast_frames)},
+ {PORTSTAT_INFO(rx_multicast_frames)},
+ {PORTSTAT_INFO(rx_broadcast_frames)},
+ {PORTSTAT_INFO(rx_crc_errors)},
+ {PORTSTAT_INFO(rx_alignment_symbol_errors)},
+ {PORTSTAT_INFO(rx_pause_frames)},
+ {PORTSTAT_INFO(rx_control_frames)},
+ {PORTSTAT_INFO(rx_in_range_errors)},
+ {PORTSTAT_INFO(rx_out_range_errors)},
+ {PORTSTAT_INFO(rx_frame_too_long)},
+ {PORTSTAT_INFO(rx_address_match_errors)},
+ {PORTSTAT_INFO(rx_vlan_mismatch)},
+ {PORTSTAT_INFO(rx_dropped_too_small)},
+ {PORTSTAT_INFO(rx_dropped_too_short)},
+ {PORTSTAT_INFO(rx_dropped_header_too_small)},
+ {PORTSTAT_INFO(rx_dropped_tcp_length)},
+ {PORTSTAT_INFO(rx_dropped_runt)},
+ {PORTSTAT_INFO(rx_fifo_overflow)},
+ {PORTSTAT_INFO(rx_input_fifo_overflow)},
+ {PORTSTAT_INFO(rx_ip_checksum_errs)},
+ {PORTSTAT_INFO(rx_tcp_checksum_errs)},
+ {PORTSTAT_INFO(rx_udp_checksum_errs)},
+ {PORTSTAT_INFO(rx_non_rss_packets)},
+ {PORTSTAT_INFO(rx_ipv4_packets)},
+ {PORTSTAT_INFO(rx_ipv6_packets)},
+ {PORTSTAT_INFO(tx_unicastframes)},
+ {PORTSTAT_INFO(tx_multicastframes)},
+ {PORTSTAT_INFO(tx_broadcastframes)},
+ {PORTSTAT_INFO(tx_pauseframes)},
+ {PORTSTAT_INFO(tx_controlframes)},
+ {MISCSTAT_INFO(rx_drops_no_pbuf)},
+ {MISCSTAT_INFO(rx_drops_no_txpb)},
+ {MISCSTAT_INFO(rx_drops_no_erx_descr)},
+ {MISCSTAT_INFO(rx_drops_no_tpre_descr)},
+ {MISCSTAT_INFO(rx_drops_too_many_frags)},
+ {MISCSTAT_INFO(rx_drops_invalid_ring)},
+ {MISCSTAT_INFO(forwarded_packets)},
+ {MISCSTAT_INFO(rx_drops_mtu)},
+ {ERXSTAT_INFO(rx_drops_no_fragments)},
+};
+#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
+
+static void
+be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ strcpy(drvinfo->driver, DRV_NAME);
+ strcpy(drvinfo->version, DRV_VER);
+ strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN);
+ strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
+ drvinfo->testinfo_len = 0;
+ drvinfo->regdump_len = 0;
+ drvinfo->eedump_len = 0;
+}
+
+static int
+be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ struct be_eq_obj *tx_eq = &adapter->tx_eq;
+
+ coalesce->rx_max_coalesced_frames = adapter->max_rx_coal;
+
+ coalesce->rx_coalesce_usecs = rx_eq->cur_eqd;
+ coalesce->rx_coalesce_usecs_high = rx_eq->max_eqd;
+ coalesce->rx_coalesce_usecs_low = rx_eq->min_eqd;
+
+ coalesce->tx_coalesce_usecs = tx_eq->cur_eqd;
+ coalesce->tx_coalesce_usecs_high = tx_eq->max_eqd;
+ coalesce->tx_coalesce_usecs_low = tx_eq->min_eqd;
+
+ coalesce->use_adaptive_rx_coalesce = rx_eq->enable_aic;
+ coalesce->use_adaptive_tx_coalesce = tx_eq->enable_aic;
+
+ return 0;
+}
+
+/*
+ * This routine is used to set interrup coalescing delay *as well as*
+ * the number of pkts to coalesce for LRO.
+ */
+static int
+be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+ struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ u32 tx_max, tx_min, tx_cur;
+ u32 rx_max, rx_min, rx_cur;
+ int status = 0;
+
+ if (coalesce->use_adaptive_tx_coalesce == 1)
+ return -EINVAL;
+
+ adapter->max_rx_coal = coalesce->rx_max_coalesced_frames;
+ if (adapter->max_rx_coal > MAX_SKB_FRAGS)
+ adapter->max_rx_coal = MAX_SKB_FRAGS - 1;
+
+ /* if AIC is being turned on now, start with an EQD of 0 */
+ if (rx_eq->enable_aic == 0 &&
+ coalesce->use_adaptive_rx_coalesce == 1) {
+ rx_eq->cur_eqd = 0;
+ }
+ rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce;
+
+ rx_max = coalesce->rx_coalesce_usecs_high;
+ rx_min = coalesce->rx_coalesce_usecs_low;
+ rx_cur = coalesce->rx_coalesce_usecs;
+
+ tx_max = coalesce->tx_coalesce_usecs_high;
+ tx_min = coalesce->tx_coalesce_usecs_low;
+ tx_cur = coalesce->tx_coalesce_usecs;
+
+ if (tx_cur > BE_MAX_EQD)
+ tx_cur = BE_MAX_EQD;
+ if (tx_eq->cur_eqd != tx_cur) {
+ status = be_cmd_modify_eqd(ctrl, tx_eq->q.id, tx_cur);
+ if (!status)
+ tx_eq->cur_eqd = tx_cur;
+ }
+
+ if (rx_eq->enable_aic) {
+ if (rx_max > BE_MAX_EQD)
+ rx_max = BE_MAX_EQD;
+ if (rx_min > rx_max)
+ rx_min = rx_max;
+ rx_eq->max_eqd = rx_max;
+ rx_eq->min_eqd = rx_min;
+ if (rx_eq->cur_eqd > rx_max)
+ rx_eq->cur_eqd = rx_max;
+ if (rx_eq->cur_eqd < rx_min)
+ rx_eq->cur_eqd = rx_min;
+ } else {
+ if (rx_cur > BE_MAX_EQD)
+ rx_cur = BE_MAX_EQD;
+ if (rx_eq->cur_eqd != rx_cur) {
+ status = be_cmd_modify_eqd(ctrl, rx_eq->q.id, rx_cur);
+ if (!status)
+ rx_eq->cur_eqd = rx_cur;
+ }
+ }
+ return 0;
+}
+
+static u32 be_get_rx_csum(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ return adapter->rx_csum;
+}
+
+static int be_set_rx_csum(struct net_device *netdev, uint32_t data)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ if (data)
+ adapter->rx_csum = true;
+ else
+ adapter->rx_csum = false;
+
+ return 0;
+}
+
+static void
+be_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, uint64_t *data)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats;
+ struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va);
+ struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
+ struct be_port_rxf_stats *port_stats =
+ &rxf_stats->port[adapter->port_num];
+ struct net_device_stats *net_stats = &adapter->stats.net_stats;
+ struct be_erx_stats *erx_stats = &hw_stats->erx;
+ void *p = NULL;
+ int i;
+
+ for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
+ switch (et_stats[i].type) {
+ case NETSTAT:
+ p = net_stats;
+ break;
+ case DRVSTAT:
+ p = drvr_stats;
+ break;
+ case PORTSTAT:
+ p = port_stats;
+ break;
+ case MISCSTAT:
+ p = rxf_stats;
+ break;
+ case ERXSTAT: /* Currently only one ERX stat is provided */
+ p = (u32 *)erx_stats + adapter->rx_obj.q.id;
+ break;
+ }
+
+ p = (u8 *)p + et_stats[i].offset;
+ data[i] = (et_stats[i].size == sizeof(u64)) ?
+ *(u64 *)p: *(u32 *)p;
+ }
+
+ return;
+}
+
+static void
+be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
+ uint8_t *data)
+{
+ int i;
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
+ memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN);
+ data += ETH_GSTRING_LEN;
+ }
+ break;
+ }
+}
+
+static int be_get_stats_count(struct net_device *netdev)
+{
+ return ETHTOOL_STATS_NUM;
+}
+
+static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+ ecmd->speed = SPEED_10000;
+ ecmd->duplex = DUPLEX_FULL;
+ ecmd->autoneg = AUTONEG_DISABLE;
+ return 0;
+}
+
+static void
+be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ ring->rx_max_pending = adapter->rx_obj.q.len;
+ ring->tx_max_pending = adapter->tx_obj.q.len;
+
+ ring->rx_pending = atomic_read(&adapter->rx_obj.q.used);
+ ring->tx_pending = atomic_read(&adapter->tx_obj.q.used);
+}
+
+static void
+be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause,
+ &ecmd->rx_pause);
+ ecmd->autoneg = AUTONEG_ENABLE;
+}
+
+static int
+be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ int status;
+
+ if (ecmd->autoneg != AUTONEG_ENABLE)
+ return -EINVAL;
+
+ status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause,
+ ecmd->rx_pause);
+ if (!status)
+ dev_warn(&adapter->pdev->dev, "Pause param set failed.\n");
+
+ return status;
+}
+
+struct ethtool_ops be_ethtool_ops = {
+ .get_settings = be_get_settings,
+ .get_drvinfo = be_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_coalesce = be_get_coalesce,
+ .set_coalesce = be_set_coalesce,
+ .get_ringparam = be_get_ringparam,
+ .get_pauseparam = be_get_pauseparam,
+ .set_pauseparam = be_set_pauseparam,
+ .get_rx_csum = be_get_rx_csum,
+ .set_rx_csum = be_set_rx_csum,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = ethtool_op_set_tso,
+ .get_strings = be_get_stat_strings,
+ .get_stats_count = be_get_stats_count,
+ .get_ethtool_stats = be_get_ethtool_stats,
+};
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
new file mode 100644
index 00000000000..b132aa4893c
--- /dev/null
+++ b/drivers/net/benet/be_hw.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2005 - 2009 ServerEngines
+ * 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. The full GNU General
+ * Public License is included in this distribution in the file called COPYING.
+ *
+ * Contact Information:
+ * linux-drivers@serverengines.com
+ *
+ * ServerEngines
+ * 209 N. Fair Oaks Ave
+ * Sunnyvale, CA 94085
+ */
+
+/********* Mailbox door bell *************/
+/* Used for driver communication with the FW.
+ * The software must write this register twice to post any command. First,
+ * it writes the register with hi=1 and the upper bits of the physical address
+ * for the MAILBOX structure. Software must poll the ready bit until this
+ * is acknowledged. Then, sotware writes the register with hi=0 with the lower
+ * bits in the address. It must poll the ready bit until the command is
+ * complete. Upon completion, the MAILBOX will contain a valid completion
+ * queue entry.
+ */
+#define MPU_MAILBOX_DB_OFFSET 0x160
+#define MPU_MAILBOX_DB_RDY_MASK 0x1 /* bit 0 */
+#define MPU_MAILBOX_DB_HI_MASK 0x2 /* bit 1 */
+
+#define MPU_EP_CONTROL 0
+
+/********** MPU semphore ******************/
+#define MPU_EP_SEMAPHORE_OFFSET 0xac
+#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF
+#define EP_SEMAPHORE_POST_ERR_MASK 0x1
+#define EP_SEMAPHORE_POST_ERR_SHIFT 31
+/* MPU semphore POST stage values */
+#define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */
+#define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */
+#define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */
+#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */
+
+/********* Memory BAR register ************/
+#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
+/* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
+ * Disable" may still globally block interrupts in addition to individual
+ * interrupt masks; a mechanism for the device driver to block all interrupts
+ * atomically without having to arbitrate for the PCI Interrupt Disable bit
+ * with the OS.
+ */
+#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */
+/* PCI physical function number */
+#define MEMBAR_CTRL_INT_CTRL_PFUNC_MASK 0x7 /* bits 26 - 28 */
+#define MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT 26
+
+/********* Event Q door bell *************/
+#define DB_EQ_OFFSET DB_CQ_OFFSET
+#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */
+/* Clear the interrupt for this eq */
+#define DB_EQ_CLR_SHIFT (9) /* bit 9 */
+/* Must be 1 */
+#define DB_EQ_EVNT_SHIFT (10) /* bit 10 */
+/* Number of event entries processed */
+#define DB_EQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
+/* Rearm bit */
+#define DB_EQ_REARM_SHIFT (29) /* bit 29 */
+
+/********* Compl Q door bell *************/
+#define DB_CQ_OFFSET 0x120
+#define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
+/* Number of event entries processed */
+#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
+/* Rearm bit */
+#define DB_CQ_REARM_SHIFT (29) /* bit 29 */
+
+/********** TX ULP door bell *************/
+#define DB_TXULP1_OFFSET 0x60
+#define DB_TXULP_RING_ID_MASK 0x7FF /* bits 0 - 10 */
+/* Number of tx entries posted */
+#define DB_TXULP_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */
+#define DB_TXULP_NUM_POSTED_MASK 0x3FFF /* bits 16 - 29 */
+
+/********** RQ(erx) door bell ************/
+#define DB_RQ_OFFSET 0x100
+#define DB_RQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
+/* Number of rx frags posted */
+#define DB_RQ_NUM_POSTED_SHIFT (24) /* bits 24 - 31 */
+
+/*
+ * BE descriptors: host memory data structures whose formats
+ * are hardwired in BE silicon.
+ */
+/* Event Queue Descriptor */
+#define EQ_ENTRY_VALID_MASK 0x1 /* bit 0 */
+#define EQ_ENTRY_RES_ID_MASK 0xFFFF /* bits 16 - 31 */
+#define EQ_ENTRY_RES_ID_SHIFT 16
+struct be_eq_entry {
+ u32 evt;
+};
+
+/* TX Queue Descriptor */
+#define ETH_WRB_FRAG_LEN_MASK 0xFFFF
+struct be_eth_wrb {
+ u32 frag_pa_hi; /* dword 0 */
+ u32 frag_pa_lo; /* dword 1 */
+ u32 rsvd0; /* dword 2 */
+ u32 frag_len; /* dword 3: bits 0 - 15 */
+} __packed;
+
+/* Pseudo amap definition for eth_hdr_wrb in which each bit of the
+ * actual structure is defined as a byte : used to calculate
+ * offset/shift/mask of each field */
+struct amap_eth_hdr_wrb {
+ u8 rsvd0[32]; /* dword 0 */
+ u8 rsvd1[32]; /* dword 1 */
+ u8 complete; /* dword 2 */
+ u8 event;
+ u8 crc;
+ u8 forward;
+ u8 ipsec;
+ u8 mgmt;
+ u8 ipcs;
+ u8 udpcs;
+ u8 tcpcs;
+ u8 lso;
+ u8 vlan;
+ u8 gso[2];
+ u8 num_wrb[5];
+ u8 lso_mss[14];
+ u8 len[16]; /* dword 3 */
+ u8 vlan_tag[16];
+} __packed;
+
+struct be_eth_hdr_wrb {
+ u32 dw[4];
+};
+
+/* TX Compl Queue Descriptor */
+
+/* Pseudo amap definition for eth_tx_compl in which each bit of the
+ * actual structure is defined as a byte: used to calculate
+ * offset/shift/mask of each field */
+struct amap_eth_tx_compl {
+ u8 wrb_index[16]; /* dword 0 */
+ u8 ct[2]; /* dword 0 */
+ u8 port[2]; /* dword 0 */
+ u8 rsvd0[8]; /* dword 0 */
+ u8 status[4]; /* dword 0 */
+ u8 user_bytes[16]; /* dword 1 */
+ u8 nwh_bytes[8]; /* dword 1 */
+ u8 lso; /* dword 1 */
+ u8 cast_enc[2]; /* dword 1 */
+ u8 rsvd1[5]; /* dword 1 */
+ u8 rsvd2[32]; /* dword 2 */
+ u8 pkts[16]; /* dword 3 */
+ u8 ringid[11]; /* dword 3 */
+ u8 hash_val[4]; /* dword 3 */
+ u8 valid; /* dword 3 */
+} __packed;
+
+struct be_eth_tx_compl {
+ u32 dw[4];
+};
+
+/* RX Queue Descriptor */
+struct be_eth_rx_d {
+ u32 fragpa_hi;
+ u32 fragpa_lo;
+};
+
+/* RX Compl Queue Descriptor */
+
+/* Pseudo amap definition for eth_rx_compl in which each bit of the
+ * actual structure is defined as a byte: used to calculate
+ * offset/shift/mask of each field */
+struct amap_eth_rx_compl {
+ u8 vlan_tag[16]; /* dword 0 */
+ u8 pktsize[14]; /* dword 0 */
+ u8 port; /* dword 0 */
+ u8 ip_opt; /* dword 0 */
+ u8 err; /* dword 1 */
+ u8 rsshp; /* dword 1 */
+ u8 ipf; /* dword 1 */
+ u8 tcpf; /* dword 1 */
+ u8 udpf; /* dword 1 */
+ u8 ipcksm; /* dword 1 */
+ u8 l4_cksm; /* dword 1 */
+ u8 ip_version; /* dword 1 */
+ u8 macdst[6]; /* dword 1 */
+ u8 vtp; /* dword 1 */
+ u8 rsvd0; /* dword 1 */
+ u8 fragndx[10]; /* dword 1 */
+ u8 ct[2]; /* dword 1 */
+ u8 sw; /* dword 1 */
+ u8 numfrags[3]; /* dword 1 */
+ u8 rss_flush; /* dword 2 */
+ u8 cast_enc[2]; /* dword 2 */
+ u8 qnq; /* dword 2 */
+ u8 rss_bank; /* dword 2 */
+ u8 rsvd1[23]; /* dword 2 */
+ u8 lro_pkt; /* dword 2 */
+ u8 rsvd2[2]; /* dword 2 */
+ u8 valid; /* dword 2 */
+ u8 rsshash[32]; /* dword 3 */
+} __packed;
+
+struct be_eth_rx_compl {
+ u32 dw[4];
+};
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
new file mode 100644
index 00000000000..f901fee79a2
--- /dev/null
+++ b/drivers/net/benet/be_main.c
@@ -0,0 +1,1947 @@
+/*
+ * Copyright (C) 2005 - 2009 ServerEngines
+ * 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. The full GNU General
+ * Public License is included in this distribution in the file called COPYING.
+ *
+ * Contact Information:
+ * linux-drivers@serverengines.com
+ *
+ * ServerEngines
+ * 209 N. Fair Oaks Ave
+ * Sunnyvale, CA 94085
+ */
+
+#include "be.h"
+
+MODULE_VERSION(DRV_VER);
+MODULE_DEVICE_TABLE(pci, be_dev_ids);
+MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
+MODULE_AUTHOR("ServerEngines Corporation");
+MODULE_LICENSE("GPL");
+
+static unsigned int rx_frag_size = 2048;
+module_param(rx_frag_size, uint, S_IRUGO);
+MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
+
+#define BE_VENDOR_ID 0x19a2
+#define BE2_DEVICE_ID_1 0x0211
+static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
+ { PCI_DEVICE(BE_VENDOR_ID, BE2_DEVICE_ID_1) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, be_dev_ids);
+
+static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q)
+{
+ struct be_dma_mem *mem = &q->dma_mem;
+ if (mem->va)
+ pci_free_consistent(adapter->pdev, mem->size,
+ mem->va, mem->dma);
+}
+
+static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
+ u16 len, u16 entry_size)
+{
+ struct be_dma_mem *mem = &q->dma_mem;
+
+ memset(q, 0, sizeof(*q));
+ q->len = len;
+ q->entry_size = entry_size;
+ mem->size = len * entry_size;
+ mem->va = pci_alloc_consistent(adapter->pdev, mem->size, &mem->dma);
+ if (!mem->va)
+ return -1;
+ memset(mem->va, 0, mem->size);
+ return 0;
+}
+
+static inline void *queue_head_node(struct be_queue_info *q)
+{
+ return q->dma_mem.va + q->head * q->entry_size;
+}
+
+static inline void *queue_tail_node(struct be_queue_info *q)
+{
+ return q->dma_mem.va + q->tail * q->entry_size;
+}
+
+static inline void queue_head_inc(struct be_queue_info *q)
+{
+ index_inc(&q->head, q->len);
+}
+
+static inline void queue_tail_inc(struct be_queue_info *q)
+{
+ index_inc(&q->tail, q->len);
+}
+
+static void be_intr_set(struct be_ctrl_info *ctrl, bool enable)
+{
+ u8 __iomem *addr = ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET;
+ u32 reg = ioread32(addr);
+ u32 enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
+ if (!enabled && enable) {
+ reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
+ } else if (enabled && !enable) {
+ reg &= ~MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
+ } else {
+ printk(KERN_WARNING DRV_NAME
+ ": bad value in membar_int_ctrl reg=0x%x\n", reg);
+ return;
+ }
+ iowrite32(reg, addr);
+}
+
+static void be_rxq_notify(struct be_ctrl_info *ctrl, u16 qid, u16 posted)
+{
+ u32 val = 0;
+ val |= qid & DB_RQ_RING_ID_MASK;
+ val |= posted << DB_RQ_NUM_POSTED_SHIFT;
+ iowrite32(val, ctrl->db + DB_RQ_OFFSET);
+}
+
+static void be_txq_notify(struct be_ctrl_info *ctrl, u16 qid, u16 posted)
+{
+ u32 val = 0;
+ val |= qid & DB_TXULP_RING_ID_MASK;
+ val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT;
+ iowrite32(val, ctrl->db + DB_TXULP1_OFFSET);
+}
+
+static void be_eq_notify(struct be_ctrl_info *ctrl, u16 qid,
+ bool arm, bool clear_int, u16 num_popped)
+{
+ u32 val = 0;
+ val |= qid & DB_EQ_RING_ID_MASK;
+ if (arm)
+ val |= 1 << DB_EQ_REARM_SHIFT;
+ if (clear_int)
+ val |= 1 << DB_EQ_CLR_SHIFT;
+ val |= 1 << DB_EQ_EVNT_SHIFT;
+ val |= num_popped << DB_EQ_NUM_POPPED_SHIFT;
+ iowrite32(val, ctrl->db + DB_EQ_OFFSET);
+}
+
+static void be_cq_notify(struct be_ctrl_info *ctrl, u16 qid,
+ bool arm, u16 num_popped)
+{
+ u32 val = 0;
+ val |= qid & DB_CQ_RING_ID_MASK;
+ if (arm)
+ val |= 1 << DB_CQ_REARM_SHIFT;
+ val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
+ iowrite32(val, ctrl->db + DB_CQ_OFFSET);
+}
+
+
+static int be_mac_addr_set(struct net_device *netdev, void *p)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+ int status = 0;
+
+ if (netif_running(netdev)) {
+ status = be_cmd_pmac_del(&adapter->ctrl, adapter->if_handle,
+ adapter->pmac_id);
+ if (status)
+ return status;
+
+ status = be_cmd_pmac_add(&adapter->ctrl, (u8 *)addr->sa_data,
+ adapter->if_handle, &adapter->pmac_id);
+ }
+
+ if (!status)
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
+ return status;
+}
+
+static void netdev_stats_update(struct be_adapter *adapter)
+{
+ struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va);
+ struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
+ struct be_port_rxf_stats *port_stats =
+ &rxf_stats->port[adapter->port_num];
+ struct net_device_stats *dev_stats = &adapter->stats.net_stats;
+
+ dev_stats->rx_packets = port_stats->rx_total_frames;
+ dev_stats->tx_packets = port_stats->tx_unicastframes +
+ port_stats->tx_multicastframes + port_stats->tx_broadcastframes;
+ dev_stats->rx_bytes = (u64) port_stats->rx_bytes_msd << 32 |
+ (u64) port_stats->rx_bytes_lsd;
+ dev_stats->tx_bytes = (u64) port_stats->tx_bytes_msd << 32 |
+ (u64) port_stats->tx_bytes_lsd;
+
+ /* bad pkts received */
+ dev_stats->rx_errors = port_stats->rx_crc_errors +
+ port_stats->rx_alignment_symbol_errors +
+ port_stats->rx_in_range_errors +
+ port_stats->rx_out_range_errors + port_stats->rx_frame_too_long;
+
+ /* 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;
+
+ /* detailed rx errors */
+ dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
+ port_stats->rx_out_range_errors + port_stats->rx_frame_too_long;
+ /* receive ring buffer overflow */
+ dev_stats->rx_over_errors = 0;
+ dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
+
+ /* frame alignment errors */
+ 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 +
+ port_stats->rx_input_fifo_overflow +
+ rxf_stats->rx_drops_no_pbuf;
+ /* receiver missed packetd */
+ dev_stats->rx_missed_errors = 0;
+ /* detailed tx_errors */
+ dev_stats->tx_aborted_errors = 0;
+ dev_stats->tx_carrier_errors = 0;
+ dev_stats->tx_fifo_errors = 0;
+ dev_stats->tx_heartbeat_errors = 0;
+ dev_stats->tx_window_errors = 0;
+}
+
+static void be_link_status_update(struct be_adapter *adapter)
+{
+ struct be_link_info *prev = &adapter->link;
+ struct be_link_info now = { 0 };
+ struct net_device *netdev = adapter->netdev;
+
+ be_cmd_link_status_query(&adapter->ctrl, &now);
+
+ /* If link came up or went down */
+ if (now.speed != prev->speed && (now.speed == PHY_LINK_SPEED_ZERO ||
+ prev->speed == PHY_LINK_SPEED_ZERO)) {
+ if (now.speed == PHY_LINK_SPEED_ZERO) {
+ netif_stop_queue(netdev);
+ netif_carrier_off(netdev);
+ printk(KERN_INFO "%s: Link down\n", netdev->name);
+ } else {
+ netif_start_queue(netdev);
+ netif_carrier_on(netdev);
+ printk(KERN_INFO "%s: Link up\n", netdev->name);
+ }
+ }
+ *prev = now;
+}
+
+/* Update the EQ delay n BE based on the RX frags consumed / sec */
+static void be_rx_eqd_update(struct be_adapter *adapter)
+{
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+ struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
+ ulong now = jiffies;
+ u32 eqd;
+
+ if (!rx_eq->enable_aic)
+ return;
+
+ /* Wrapped around */
+ if (time_before(now, stats->rx_fps_jiffies)) {
+ stats->rx_fps_jiffies = now;
+ return;
+ }
+
+ /* Update once a second */
+ if ((now - stats->rx_fps_jiffies) < HZ)
+ return;
+
+ stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) /
+ ((now - stats->rx_fps_jiffies) / HZ);
+
+ stats->rx_fps_jiffies = now;
+ stats->be_prev_rx_frags = stats->be_rx_frags;
+ eqd = stats->be_rx_fps / 110000;
+ eqd = eqd << 3;
+ if (eqd > rx_eq->max_eqd)
+ eqd = rx_eq->max_eqd;
+ if (eqd < rx_eq->min_eqd)
+ eqd = rx_eq->min_eqd;
+ if (eqd < 10)
+ eqd = 0;
+ if (eqd != rx_eq->cur_eqd)
+ be_cmd_modify_eqd(ctrl, rx_eq->q.id, eqd);
+
+ rx_eq->cur_eqd = eqd;
+}
+
+static struct net_device_stats *be_get_stats(struct net_device *dev)
+{
+ struct be_adapter *adapter = netdev_priv(dev);
+
+ return &adapter->stats.net_stats;
+}
+
+static void be_tx_rate_update(struct be_adapter *adapter)
+{
+ struct be_drvr_stats *stats = drvr_stats(adapter);
+ ulong now = jiffies;
+
+ /* Wrapped around? */
+ if (time_before(now, stats->be_tx_jiffies)) {
+ stats->be_tx_jiffies = now;
+ return;
+ }
+
+ /* Update tx rate once in two seconds */
+ if ((now - stats->be_tx_jiffies) > 2 * HZ) {
+ u32 r;
+ r = (stats->be_tx_bytes - stats->be_tx_bytes_prev) /
+ ((now - stats->be_tx_jiffies) / HZ);
+ r = r / 1000000; /* M bytes/s */
+ stats->be_tx_rate = r * 8; /* M bits/s */
+ stats->be_tx_jiffies = now;
+ stats->be_tx_bytes_prev = stats->be_tx_bytes;
+ }
+}
+
+static void be_tx_stats_update(struct be_adapter *adapter,
+ u32 wrb_cnt, u32 copied, bool stopped)
+{
+ struct be_drvr_stats *stats = drvr_stats(adapter);
+ stats->be_tx_reqs++;
+ stats->be_tx_wrbs += wrb_cnt;
+ stats->be_tx_bytes += copied;
+ if (stopped)
+ stats->be_tx_stops++;
+}
+
+/* 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;
+ }
+ /* to account for hdr wrb */
+ cnt++;
+ if (cnt & 1) {
+ /* add a dummy to make it an even num */
+ cnt++;
+ *dummy = true;
+ } else
+ *dummy = false;
+ BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT);
+ return cnt;
+}
+
+static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
+{
+ wrb->frag_pa_hi = upper_32_bits(addr);
+ wrb->frag_pa_lo = addr & 0xFFFFFFFF;
+ wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
+}
+
+static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
+ bool vlan, u32 wrb_cnt, u32 len)
+{
+ memset(hdr, 0, sizeof(*hdr));
+
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
+
+ if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) {
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1);
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss,
+ hdr, skb_shinfo(skb)->gso_size);
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ if (is_tcp_pkt(skb))
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1);
+ else if (is_udp_pkt(skb))
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
+ }
+
+ if (vlan && vlan_tx_tag_present(skb)) {
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag,
+ hdr, vlan_tx_tag_get(skb));
+ }
+
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, complete, hdr, 1);
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, num_wrb, hdr, wrb_cnt);
+ AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len);
+}
+
+
+static int make_tx_wrbs(struct be_adapter *adapter,
+ struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb)
+{
+ u64 busaddr;
+ u32 i, copied = 0;
+ struct pci_dev *pdev = adapter->pdev;
+ struct sk_buff *first_skb = skb;
+ struct be_queue_info *txq = &adapter->tx_obj.q;
+ struct be_eth_wrb *wrb;
+ struct be_eth_hdr_wrb *hdr;
+
+ atomic_add(wrb_cnt, &txq->used);
+ 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;
+ }
+
+ 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;
+ }
+
+ if (dummy_wrb) {
+ wrb = queue_head_node(txq);
+ wrb_fill(wrb, 0, 0);
+ be_dws_cpu_to_le(wrb, sizeof(*wrb));
+ queue_head_inc(txq);
+ }
+
+ wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false,
+ wrb_cnt, copied);
+ be_dws_cpu_to_le(hdr, sizeof(*hdr));
+
+ return copied;
+}
+
+static int be_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct be_tx_obj *tx_obj = &adapter->tx_obj;
+ struct be_queue_info *txq = &tx_obj->q;
+ u32 wrb_cnt = 0, copied = 0;
+ u32 start = txq->head;
+ bool dummy_wrb, stopped = false;
+
+ wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb);
+
+ copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb);
+
+ /* record the sent skb in the sent_skb table */
+ BUG_ON(tx_obj->sent_skb_list[start]);
+ tx_obj->sent_skb_list[start] = skb;
+
+ /* Ensure that txq has space for the next skb; Else stop the queue
+ * *BEFORE* ringing the tx doorbell, so that we serialze the
+ * tx compls of the current transmit which'll wake up the queue
+ */
+ if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >= txq->len) {
+ netif_stop_queue(netdev);
+ stopped = true;
+ }
+
+ 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;
+}
+
+static int be_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ if (new_mtu < BE_MIN_MTU ||
+ new_mtu > BE_MAX_JUMBO_FRAME_SIZE) {
+ dev_info(&adapter->pdev->dev,
+ "MTU must be between %d and %d bytes\n",
+ BE_MIN_MTU, BE_MAX_JUMBO_FRAME_SIZE);
+ return -EINVAL;
+ }
+ dev_info(&adapter->pdev->dev, "MTU changed from %d to %d bytes\n",
+ netdev->mtu, new_mtu);
+ netdev->mtu = new_mtu;
+ return 0;
+}
+
+/*
+ * if there are BE_NUM_VLANS_SUPPORTED or lesser number of VLANS configured,
+ * program them in BE. If more than BE_NUM_VLANS_SUPPORTED are configured,
+ * set the BE in promiscuous VLAN mode.
+ */
+static void be_vid_config(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ u16 vtag[BE_NUM_VLANS_SUPPORTED];
+ u16 ntags = 0, i;
+
+ if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED) {
+ /* Construct VLAN Table to give to HW */
+ for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ if (adapter->vlan_tag[i]) {
+ vtag[ntags] = cpu_to_le16(i);
+ ntags++;
+ }
+ }
+ be_cmd_vlan_config(&adapter->ctrl, adapter->if_handle,
+ vtag, ntags, 1, 0);
+ } else {
+ be_cmd_vlan_config(&adapter->ctrl, adapter->if_handle,
+ NULL, 0, 1, 1);
+ }
+}
+
+static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+
+ be_eq_notify(ctrl, rx_eq->q.id, false, false, 0);
+ be_eq_notify(ctrl, tx_eq->q.id, false, false, 0);
+ adapter->vlan_grp = grp;
+ be_eq_notify(ctrl, rx_eq->q.id, true, false, 0);
+ be_eq_notify(ctrl, tx_eq->q.id, true, false, 0);
+}
+
+static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ adapter->num_vlans++;
+ adapter->vlan_tag[vid] = 1;
+
+ be_vid_config(netdev);
+}
+
+static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ adapter->num_vlans--;
+ adapter->vlan_tag[vid] = 0;
+
+ vlan_group_set_device(adapter->vlan_grp, vid, NULL);
+ be_vid_config(netdev);
+}
+
+static void be_set_multicast_filter(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct dev_mc_list *mc_ptr;
+ u8 mac_addr[32][ETH_ALEN];
+ int i = 0;
+
+ if (netdev->flags & IFF_ALLMULTI) {
+ /* set BE in Multicast promiscuous */
+ be_cmd_mcast_mac_set(&adapter->ctrl,
+ adapter->if_handle, NULL, 0, true);
+ return;
+ }
+
+ for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+ memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN);
+ if (++i >= 32) {
+ be_cmd_mcast_mac_set(&adapter->ctrl,
+ adapter->if_handle, &mac_addr[0][0], i, false);
+ i = 0;
+ }
+
+ }
+
+ if (i) {
+ /* reset the promiscuous mode also. */
+ be_cmd_mcast_mac_set(&adapter->ctrl,
+ adapter->if_handle, &mac_addr[0][0], i, false);
+ }
+}
+
+static void be_set_multicast_list(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ if (netdev->flags & IFF_PROMISC) {
+ be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 1);
+ } else {
+ be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 0);
+ be_set_multicast_filter(netdev);
+ }
+}
+
+static void be_rx_rate_update(struct be_adapter *adapter)
+{
+ struct be_drvr_stats *stats = drvr_stats(adapter);
+ ulong now = jiffies;
+ u32 rate;
+
+ /* Wrapped around */
+ if (time_before(now, stats->be_rx_jiffies)) {
+ stats->be_rx_jiffies = now;
+ return;
+ }
+
+ /* Update the rate once in two seconds */
+ if ((now - stats->be_rx_jiffies) < 2 * HZ)
+ return;
+
+ rate = (stats->be_rx_bytes - stats->be_rx_bytes_prev) /
+ ((now - stats->be_rx_jiffies) / HZ);
+ rate = rate / 1000000; /* MB/Sec */
+ stats->be_rx_rate = rate * 8; /* Mega Bits/Sec */
+ stats->be_rx_jiffies = now;
+ stats->be_rx_bytes_prev = stats->be_rx_bytes;
+}
+
+static void be_rx_stats_update(struct be_adapter *adapter,
+ u32 pktsize, u16 numfrags)
+{
+ struct be_drvr_stats *stats = drvr_stats(adapter);
+
+ stats->be_rx_compl++;
+ stats->be_rx_frags += numfrags;
+ stats->be_rx_bytes += pktsize;
+}
+
+static struct be_rx_page_info *
+get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
+{
+ struct be_rx_page_info *rx_page_info;
+ struct be_queue_info *rxq = &adapter->rx_obj.q;
+
+ rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx];
+ BUG_ON(!rx_page_info->page);
+
+ if (rx_page_info->last_page_user)
+ pci_unmap_page(adapter->pdev, pci_unmap_addr(rx_page_info, bus),
+ adapter->big_page_size, PCI_DMA_FROMDEVICE);
+
+ atomic_dec(&rxq->used);
+ return rx_page_info;
+}
+
+/* Throwaway the data in the Rx completion */
+static void be_rx_compl_discard(struct be_adapter *adapter,
+ struct be_eth_rx_compl *rxcp)
+{
+ struct be_queue_info *rxq = &adapter->rx_obj.q;
+ struct be_rx_page_info *page_info;
+ u16 rxq_idx, i, num_rcvd;
+
+ rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
+ num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+
+ for (i = 0; i < num_rcvd; i++) {
+ page_info = get_rx_page_info(adapter, rxq_idx);
+ put_page(page_info->page);
+ memset(page_info, 0, sizeof(*page_info));
+ index_inc(&rxq_idx, rxq->len);
+ }
+}
+
+/*
+ * skb_fill_rx_data forms a complete skb for an ether frame
+ * indicated by rxcp.
+ */
+static void skb_fill_rx_data(struct be_adapter *adapter,
+ struct sk_buff *skb, struct be_eth_rx_compl *rxcp)
+{
+ struct be_queue_info *rxq = &adapter->rx_obj.q;
+ struct be_rx_page_info *page_info;
+ u16 rxq_idx, i, num_rcvd;
+ u32 pktsize, hdr_len, curr_frag_len;
+ u8 *start;
+
+ rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
+ pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
+ num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+
+ page_info = get_rx_page_info(adapter, rxq_idx);
+
+ start = page_address(page_info->page) + page_info->page_offset;
+ prefetch(start);
+
+ /* Copy data in the first descriptor of this completion */
+ curr_frag_len = min(pktsize, rx_frag_size);
+
+ /* Copy the header portion into skb_data */
+ hdr_len = min((u32)BE_HDR_LEN, curr_frag_len);
+ memcpy(skb->data, start, hdr_len);
+ skb->len = curr_frag_len;
+ if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */
+ /* Complete packet has now been moved to data */
+ put_page(page_info->page);
+ skb->data_len = 0;
+ skb->tail += curr_frag_len;
+ } else {
+ skb_shinfo(skb)->nr_frags = 1;
+ skb_shinfo(skb)->frags[0].page = page_info->page;
+ skb_shinfo(skb)->frags[0].page_offset =
+ page_info->page_offset + hdr_len;
+ skb_shinfo(skb)->frags[0].size = curr_frag_len - hdr_len;
+ skb->data_len = curr_frag_len - hdr_len;
+ skb->tail += hdr_len;
+ }
+ memset(page_info, 0, sizeof(*page_info));
+
+ if (pktsize <= rx_frag_size) {
+ BUG_ON(num_rcvd != 1);
+ return;
+ }
+
+ /* More frags present for this completion */
+ pktsize -= curr_frag_len; /* account for above copied frag */
+ for (i = 1; i < num_rcvd; i++) {
+ index_inc(&rxq_idx, rxq->len);
+ page_info = get_rx_page_info(adapter, rxq_idx);
+
+ curr_frag_len = min(pktsize, rx_frag_size);
+
+ skb_shinfo(skb)->frags[i].page = page_info->page;
+ skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset;
+ skb_shinfo(skb)->frags[i].size = curr_frag_len;
+ skb->len += curr_frag_len;
+ skb->data_len += curr_frag_len;
+ skb_shinfo(skb)->nr_frags++;
+ pktsize -= curr_frag_len;
+
+ memset(page_info, 0, sizeof(*page_info));
+ }
+
+ be_rx_stats_update(adapter, pktsize, num_rcvd);
+ return;
+}
+
+/* Process the RX completion indicated by rxcp when LRO is disabled */
+static void be_rx_compl_process(struct be_adapter *adapter,
+ struct be_eth_rx_compl *rxcp)
+{
+ 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);
+ if (!skb) {
+ if (net_ratelimit())
+ dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
+ be_rx_compl_discard(adapter, rxcp);
+ return;
+ }
+
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ skb_fill_rx_data(adapter, skb, rxcp);
+
+ if (l4_cksm && adapter->rx_csum)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb->ip_summed = CHECKSUM_NONE;
+
+ skb->truesize = skb->len + sizeof(struct sk_buff);
+ skb->protocol = eth_type_trans(skb, adapter->netdev);
+ skb->dev = adapter->netdev;
+
+ if (vtp) {
+ if (!adapter->vlan_grp || adapter->num_vlans == 0) {
+ kfree_skb(skb);
+ return;
+ }
+ vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
+ vid = be16_to_cpu(vid);
+ vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid);
+ } else {
+ netif_receive_skb(skb);
+ }
+
+ adapter->netdev->last_rx = jiffies;
+
+ return;
+}
+
+/* Process the RX completion indicated by rxcp when LRO is enabled */
+static void be_rx_compl_process_lro(struct be_adapter *adapter,
+ struct be_eth_rx_compl *rxcp)
+{
+ struct be_rx_page_info *page_info;
+ struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME];
+ struct be_queue_info *rxq = &adapter->rx_obj.q;
+ u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
+ u16 i, rxq_idx = 0, vid;
+
+ num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+ pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
+ vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+ rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
+
+ remaining = pkt_size;
+ for (i = 0; i < num_rcvd; i++) {
+ page_info = get_rx_page_info(adapter, rxq_idx);
+
+ curr_frag_len = min(remaining, rx_frag_size);
+
+ rx_frags[i].page = page_info->page;
+ rx_frags[i].page_offset = page_info->page_offset;
+ rx_frags[i].size = curr_frag_len;
+ remaining -= curr_frag_len;
+
+ index_inc(&rxq_idx, rxq->len);
+
+ memset(page_info, 0, sizeof(*page_info));
+ }
+
+ if (likely(!vlanf)) {
+ lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size,
+ pkt_size, NULL, 0);
+ } else {
+ vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
+ vid = be16_to_cpu(vid);
+
+ if (!adapter->vlan_grp || adapter->num_vlans == 0)
+ return;
+
+ lro_vlan_hwaccel_receive_frags(&adapter->rx_obj.lro_mgr,
+ rx_frags, pkt_size, pkt_size, adapter->vlan_grp,
+ vid, NULL, 0);
+ }
+
+ be_rx_stats_update(adapter, pkt_size, num_rcvd);
+ return;
+}
+
+static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
+{
+ struct be_eth_rx_compl *rxcp = queue_tail_node(&adapter->rx_obj.cq);
+
+ if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0)
+ return NULL;
+
+ 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;
+}
+
+static inline struct page *be_alloc_pages(u32 size)
+{
+ gfp_t alloc_flags = GFP_ATOMIC;
+ u32 order = get_order(size);
+ if (order > 0)
+ alloc_flags |= __GFP_COMP;
+ return alloc_pages(alloc_flags, order);
+}
+
+/*
+ * Allocate a page, split it to fragments of size rx_frag_size and post as
+ * receive buffers to BE
+ */
+static void be_post_rx_frags(struct be_adapter *adapter)
+{
+ struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl;
+ struct be_rx_page_info *page_info = NULL;
+ struct be_queue_info *rxq = &adapter->rx_obj.q;
+ struct page *pagep = NULL;
+ struct be_eth_rx_d *rxd;
+ u64 page_dmaaddr = 0, frag_dmaaddr;
+ u32 posted, page_offset = 0;
+
+ page_info = &page_info_tbl[rxq->head];
+ for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) {
+ if (!pagep) {
+ pagep = be_alloc_pages(adapter->big_page_size);
+ if (unlikely(!pagep)) {
+ drvr_stats(adapter)->be_ethrx_post_fail++;
+ break;
+ }
+ page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0,
+ adapter->big_page_size,
+ PCI_DMA_FROMDEVICE);
+ page_info->page_offset = 0;
+ } else {
+ get_page(pagep);
+ page_info->page_offset = page_offset + rx_frag_size;
+ }
+ page_offset = page_info->page_offset;
+ page_info->page = pagep;
+ pci_unmap_addr_set(page_info, bus, page_dmaaddr);
+ frag_dmaaddr = page_dmaaddr + page_info->page_offset;
+
+ rxd = queue_head_node(rxq);
+ rxd->fragpa_lo = cpu_to_le32(frag_dmaaddr & 0xFFFFFFFF);
+ rxd->fragpa_hi = cpu_to_le32(upper_32_bits(frag_dmaaddr));
+ queue_head_inc(rxq);
+
+ /* Any space left in the current big page for another frag? */
+ if ((page_offset + rx_frag_size + rx_frag_size) >
+ adapter->big_page_size) {
+ pagep = NULL;
+ page_info->last_page_user = true;
+ }
+ page_info = &page_info_tbl[rxq->head];
+ }
+ if (pagep)
+ page_info->last_page_user = true;
+
+ if (posted) {
+ atomic_add(posted, &rxq->used);
+ be_rxq_notify(&adapter->ctrl, rxq->id, posted);
+ } else if (atomic_read(&rxq->used) == 0) {
+ /* Let be_worker replenish when memory is available */
+ adapter->rx_post_starved = true;
+ }
+
+ return;
+}
+
+static struct be_eth_tx_compl *
+be_tx_compl_get(struct be_adapter *adapter)
+{
+ struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
+ struct be_eth_tx_compl *txcp = queue_tail_node(tx_cq);
+
+ if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0)
+ return NULL;
+
+ be_dws_le_to_cpu(txcp, sizeof(*txcp));
+
+ txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
+
+ queue_tail_inc(tx_cq);
+ return txcp;
+}
+
+static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
+{
+ struct be_queue_info *txq = &adapter->tx_obj.q;
+ struct be_eth_wrb *wrb;
+ struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
+ struct sk_buff *sent_skb;
+ u64 busaddr;
+ u16 cur_index, num_wrbs = 0;
+
+ cur_index = txq->tail;
+ sent_skb = sent_skbs[cur_index];
+ BUG_ON(!sent_skb);
+ sent_skbs[cur_index] = NULL;
+
+ do {
+ cur_index = txq->tail;
+ wrb = queue_tail_node(txq);
+ be_dws_le_to_cpu(wrb, sizeof(*wrb));
+ busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo;
+ if (busaddr != 0) {
+ pci_unmap_single(adapter->pdev, busaddr,
+ wrb->frag_len, PCI_DMA_TODEVICE);
+ }
+ num_wrbs++;
+ queue_tail_inc(txq);
+ } while (cur_index != last_index);
+
+ atomic_sub(num_wrbs, &txq->used);
+
+ kfree_skb(sent_skb);
+}
+
+static void be_rx_q_clean(struct be_adapter *adapter)
+{
+ struct be_rx_page_info *page_info;
+ struct be_queue_info *rxq = &adapter->rx_obj.q;
+ struct be_queue_info *rx_cq = &adapter->rx_obj.cq;
+ struct be_eth_rx_compl *rxcp;
+ u16 tail;
+
+ /* First cleanup pending rx completions */
+ while ((rxcp = be_rx_compl_get(adapter)) != NULL) {
+ be_rx_compl_discard(adapter, rxcp);
+ be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1);
+ }
+
+ /* Then free posted rx buffer that were not used */
+ tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
+ for (; tail != rxq->head; index_inc(&tail, rxq->len)) {
+ page_info = get_rx_page_info(adapter, tail);
+ put_page(page_info->page);
+ memset(page_info, 0, sizeof(*page_info));
+ }
+ BUG_ON(atomic_read(&rxq->used));
+}
+
+static void be_tx_q_clean(struct be_adapter *adapter)
+{
+ struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
+ struct sk_buff *sent_skb;
+ struct be_queue_info *txq = &adapter->tx_obj.q;
+ u16 last_index;
+ bool dummy_wrb;
+
+ while (atomic_read(&txq->used)) {
+ sent_skb = sent_skbs[txq->tail];
+ last_index = txq->tail;
+ index_adv(&last_index,
+ wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len);
+ be_tx_compl_process(adapter, last_index);
+ }
+}
+
+static void be_tx_queues_destroy(struct be_adapter *adapter)
+{
+ struct be_queue_info *q;
+
+ q = &adapter->tx_obj.q;
+ if (q->created)
+ be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ);
+ be_queue_free(adapter, q);
+
+ q = &adapter->tx_obj.cq;
+ if (q->created)
+ 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);
+ be_queue_free(adapter, q);
+}
+
+static int be_tx_queues_create(struct be_adapter *adapter)
+{
+ struct be_queue_info *eq, *q, *cq;
+
+ adapter->tx_eq.max_eqd = 0;
+ adapter->tx_eq.min_eqd = 0;
+ adapter->tx_eq.cur_eqd = 96;
+ adapter->tx_eq.enable_aic = false;
+ /* Alloc Tx Event queue */
+ eq = &adapter->tx_eq.q;
+ if (be_queue_alloc(adapter, eq, EVNT_Q_LEN, sizeof(struct be_eq_entry)))
+ return -1;
+
+ /* Ask BE to create Tx Event queue */
+ if (be_cmd_eq_create(&adapter->ctrl, eq, adapter->tx_eq.cur_eqd))
+ goto tx_eq_free;
+ /* Alloc TX eth compl queue */
+ cq = &adapter->tx_obj.cq;
+ if (be_queue_alloc(adapter, cq, TX_CQ_LEN,
+ sizeof(struct be_eth_tx_compl)))
+ goto tx_eq_destroy;
+
+ /* Ask BE to create Tx eth compl queue */
+ if (be_cmd_cq_create(&adapter->ctrl, cq, eq, false, false, 3))
+ goto tx_cq_free;
+
+ /* Alloc TX eth queue */
+ q = &adapter->tx_obj.q;
+ if (be_queue_alloc(adapter, q, TX_Q_LEN, sizeof(struct be_eth_wrb)))
+ goto tx_cq_destroy;
+
+ /* Ask BE to create Tx eth queue */
+ if (be_cmd_txq_create(&adapter->ctrl, q, cq))
+ goto tx_q_free;
+ return 0;
+
+tx_q_free:
+ be_queue_free(adapter, q);
+tx_cq_destroy:
+ be_cmd_q_destroy(&adapter->ctrl, cq, QTYPE_CQ);
+tx_cq_free:
+ be_queue_free(adapter, cq);
+tx_eq_destroy:
+ be_cmd_q_destroy(&adapter->ctrl, eq, QTYPE_EQ);
+tx_eq_free:
+ be_queue_free(adapter, eq);
+ return -1;
+}
+
+static void be_rx_queues_destroy(struct be_adapter *adapter)
+{
+ struct be_queue_info *q;
+
+ q = &adapter->rx_obj.q;
+ if (q->created) {
+ be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_RXQ);
+ be_rx_q_clean(adapter);
+ }
+ be_queue_free(adapter, q);
+
+ q = &adapter->rx_obj.cq;
+ if (q->created)
+ be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ);
+ be_queue_free(adapter, q);
+
+ q = &adapter->rx_eq.q;
+ if (q->created)
+ be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ);
+ be_queue_free(adapter, q);
+}
+
+static int be_rx_queues_create(struct be_adapter *adapter)
+{
+ struct be_queue_info *eq, *q, *cq;
+ int rc;
+
+ adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME;
+ adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
+ adapter->rx_eq.max_eqd = BE_MAX_EQD;
+ adapter->rx_eq.min_eqd = 0;
+ adapter->rx_eq.cur_eqd = 0;
+ adapter->rx_eq.enable_aic = true;
+
+ /* Alloc Rx Event queue */
+ eq = &adapter->rx_eq.q;
+ rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
+ sizeof(struct be_eq_entry));
+ if (rc)
+ return rc;
+
+ /* Ask BE to create Rx Event queue */
+ rc = be_cmd_eq_create(&adapter->ctrl, eq, adapter->rx_eq.cur_eqd);
+ if (rc)
+ goto rx_eq_free;
+
+ /* Alloc RX eth compl queue */
+ cq = &adapter->rx_obj.cq;
+ rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
+ sizeof(struct be_eth_rx_compl));
+ if (rc)
+ goto rx_eq_destroy;
+
+ /* Ask BE to create Rx eth compl queue */
+ rc = be_cmd_cq_create(&adapter->ctrl, cq, eq, false, false, 3);
+ if (rc)
+ goto rx_cq_free;
+
+ /* Alloc RX eth queue */
+ q = &adapter->rx_obj.q;
+ rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d));
+ if (rc)
+ goto rx_cq_destroy;
+
+ /* Ask BE to create Rx eth queue */
+ rc = be_cmd_rxq_create(&adapter->ctrl, q, cq->id, rx_frag_size,
+ BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false);
+ if (rc)
+ goto rx_q_free;
+
+ return 0;
+rx_q_free:
+ be_queue_free(adapter, q);
+rx_cq_destroy:
+ be_cmd_q_destroy(&adapter->ctrl, cq, QTYPE_CQ);
+rx_cq_free:
+ be_queue_free(adapter, cq);
+rx_eq_destroy:
+ be_cmd_q_destroy(&adapter->ctrl, eq, QTYPE_EQ);
+rx_eq_free:
+ be_queue_free(adapter, eq);
+ return rc;
+}
+static bool event_get(struct be_eq_obj *eq_obj, u16 *rid)
+{
+ struct be_eq_entry *entry = queue_tail_node(&eq_obj->q);
+ u32 evt = entry->evt;
+
+ if (!evt)
+ return false;
+
+ evt = le32_to_cpu(evt);
+ *rid = (evt >> EQ_ENTRY_RES_ID_SHIFT) & EQ_ENTRY_RES_ID_MASK;
+ entry->evt = 0;
+ queue_tail_inc(&eq_obj->q);
+ return true;
+}
+
+static int event_handle(struct be_ctrl_info *ctrl,
+ struct be_eq_obj *eq_obj)
+{
+ u16 rid = 0, num = 0;
+
+ while (event_get(eq_obj, &rid))
+ num++;
+
+ /* We can see an interrupt and no event */
+ be_eq_notify(ctrl, eq_obj->q.id, true, true, num);
+ if (num)
+ napi_schedule(&eq_obj->napi);
+
+ return num;
+}
+
+static irqreturn_t be_intx(int irq, void *dev)
+{
+ struct be_adapter *adapter = dev;
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+ int rx, tx;
+
+ tx = event_handle(ctrl, &adapter->tx_eq);
+ rx = event_handle(ctrl, &adapter->rx_eq);
+
+ if (rx || tx)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static irqreturn_t be_msix_rx(int irq, void *dev)
+{
+ struct be_adapter *adapter = dev;
+
+ event_handle(&adapter->ctrl, &adapter->rx_eq);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t be_msix_tx(int irq, void *dev)
+{
+ struct be_adapter *adapter = dev;
+
+ event_handle(&adapter->ctrl, &adapter->tx_eq);
+
+ return IRQ_HANDLED;
+}
+
+static inline bool do_lro(struct be_adapter *adapter,
+ struct be_eth_rx_compl *rxcp)
+{
+ int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp);
+ int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
+
+ if (err)
+ drvr_stats(adapter)->be_rxcp_err++;
+
+ return (!tcp_frame || err || (adapter->max_rx_coal <= 1)) ?
+ false : true;
+}
+
+int be_poll_rx(struct napi_struct *napi, int budget)
+{
+ struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi);
+ struct be_adapter *adapter =
+ container_of(rx_eq, struct be_adapter, rx_eq);
+ struct be_queue_info *rx_cq = &adapter->rx_obj.cq;
+ struct be_eth_rx_compl *rxcp;
+ u32 work_done;
+
+ for (work_done = 0; work_done < budget; work_done++) {
+ rxcp = be_rx_compl_get(adapter);
+ if (!rxcp)
+ break;
+
+ if (do_lro(adapter, rxcp))
+ be_rx_compl_process_lro(adapter, rxcp);
+ else
+ be_rx_compl_process(adapter, rxcp);
+ }
+
+ lro_flush_all(&adapter->rx_obj.lro_mgr);
+
+ /* Refill the queue */
+ if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM)
+ be_post_rx_frags(adapter);
+
+ /* All consumed */
+ if (work_done < budget) {
+ napi_complete(napi);
+ be_cq_notify(&adapter->ctrl, rx_cq->id, true, work_done);
+ } else {
+ /* More to be consumed; continue with interrupts disabled */
+ be_cq_notify(&adapter->ctrl, rx_cq->id, false, work_done);
+ }
+ return work_done;
+}
+
+/* For TX we don't honour budget; consume everything */
+int be_poll_tx(struct napi_struct *napi, int budget)
+{
+ struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi);
+ struct be_adapter *adapter =
+ container_of(tx_eq, struct be_adapter, tx_eq);
+ struct be_tx_obj *tx_obj = &adapter->tx_obj;
+ struct be_queue_info *tx_cq = &tx_obj->cq;
+ struct be_queue_info *txq = &tx_obj->q;
+ struct be_eth_tx_compl *txcp;
+ u32 num_cmpl = 0;
+ u16 end_idx;
+
+ while ((txcp = be_tx_compl_get(adapter))) {
+ end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
+ wrb_index, txcp);
+ be_tx_compl_process(adapter, end_idx);
+ num_cmpl++;
+ }
+
+ /* As Tx wrbs have been freed up, wake up netdev queue if
+ * it was stopped due to lack of tx wrbs.
+ */
+ if (netif_queue_stopped(adapter->netdev) &&
+ atomic_read(&txq->used) < txq->len / 2) {
+ netif_wake_queue(adapter->netdev);
+ }
+
+ napi_complete(napi);
+
+ be_cq_notify(&adapter->ctrl, tx_cq->id, true, num_cmpl);
+
+ drvr_stats(adapter)->be_tx_events++;
+ drvr_stats(adapter)->be_tx_compl += num_cmpl;
+
+ return 1;
+}
+
+static void be_worker(struct work_struct *work)
+{
+ struct be_adapter *adapter =
+ container_of(work, struct be_adapter, work.work);
+ int status;
+
+ /* Check link */
+ be_link_status_update(adapter);
+
+ /* Get Stats */
+ status = be_cmd_get_stats(&adapter->ctrl, &adapter->stats.cmd);
+ if (!status)
+ netdev_stats_update(adapter);
+
+ /* Set EQ delay */
+ be_rx_eqd_update(adapter);
+
+ be_tx_rate_update(adapter);
+ be_rx_rate_update(adapter);
+
+ if (adapter->rx_post_starved) {
+ adapter->rx_post_starved = false;
+ be_post_rx_frags(adapter);
+ }
+
+ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+}
+
+static void be_msix_enable(struct be_adapter *adapter)
+{
+ int i, status;
+
+ for (i = 0; i < BE_NUM_MSIX_VECTORS; i++)
+ adapter->msix_entries[i].entry = i;
+
+ status = pci_enable_msix(adapter->pdev, adapter->msix_entries,
+ BE_NUM_MSIX_VECTORS);
+ if (status == 0)
+ adapter->msix_enabled = true;
+ return;
+}
+
+static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id)
+{
+ return adapter->msix_entries[eq_id -
+ 8 * adapter->ctrl.pci_func].vector;
+}
+
+static int be_msix_register(struct be_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ int status, vec;
+
+ sprintf(tx_eq->desc, "%s-tx", netdev->name);
+ vec = be_msix_vec_get(adapter, tx_eq->q.id);
+ status = request_irq(vec, be_msix_tx, 0, tx_eq->desc, adapter);
+ if (status)
+ goto err;
+
+ sprintf(rx_eq->desc, "%s-rx", netdev->name);
+ vec = be_msix_vec_get(adapter, rx_eq->q.id);
+ status = request_irq(vec, be_msix_rx, 0, rx_eq->desc, adapter);
+ if (status) { /* Free TX IRQ */
+ vec = be_msix_vec_get(adapter, tx_eq->q.id);
+ free_irq(vec, adapter);
+ goto err;
+ }
+ return 0;
+err:
+ dev_warn(&adapter->pdev->dev,
+ "MSIX Request IRQ failed - err %d\n", status);
+ pci_disable_msix(adapter->pdev);
+ adapter->msix_enabled = false;
+ return status;
+}
+
+static int be_irq_register(struct be_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int status;
+
+ if (adapter->msix_enabled) {
+ status = be_msix_register(adapter);
+ if (status == 0)
+ goto done;
+ }
+
+ /* INTx */
+ netdev->irq = adapter->pdev->irq;
+ status = request_irq(netdev->irq, be_intx, IRQF_SHARED, netdev->name,
+ adapter);
+ if (status) {
+ dev_err(&adapter->pdev->dev,
+ "INTx request IRQ failed - err %d\n", status);
+ return status;
+ }
+done:
+ adapter->isr_registered = true;
+ return 0;
+}
+
+static void be_irq_unregister(struct be_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int vec;
+
+ if (!adapter->isr_registered)
+ return;
+
+ /* INTx */
+ if (!adapter->msix_enabled) {
+ free_irq(netdev->irq, adapter);
+ goto done;
+ }
+
+ /* MSIx */
+ vec = be_msix_vec_get(adapter, adapter->tx_eq.q.id);
+ free_irq(vec, adapter);
+ vec = be_msix_vec_get(adapter, adapter->rx_eq.q.id);
+ free_irq(vec, adapter);
+done:
+ adapter->isr_registered = false;
+ return;
+}
+
+static int be_open(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+ struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ u32 if_flags;
+ int status;
+
+ if_flags = BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PROMISCUOUS |
+ BE_IF_FLAGS_MCAST_PROMISCUOUS | BE_IF_FLAGS_UNTAGGED |
+ BE_IF_FLAGS_PASS_L3L4_ERRORS;
+ status = be_cmd_if_create(ctrl, if_flags, netdev->dev_addr,
+ false/* pmac_invalid */, &adapter->if_handle,
+ &adapter->pmac_id);
+ if (status != 0)
+ goto do_none;
+
+ be_vid_config(netdev);
+
+ status = be_cmd_set_flow_control(ctrl, true, true);
+ if (status != 0)
+ goto if_destroy;
+
+ status = be_tx_queues_create(adapter);
+ if (status != 0)
+ goto if_destroy;
+
+ status = be_rx_queues_create(adapter);
+ if (status != 0)
+ goto tx_qs_destroy;
+
+ /* First time posting */
+ be_post_rx_frags(adapter);
+
+ napi_enable(&rx_eq->napi);
+ napi_enable(&tx_eq->napi);
+
+ be_irq_register(adapter);
+
+ be_intr_set(ctrl, true);
+
+ /* The evt queues are created in the unarmed state; arm them */
+ be_eq_notify(ctrl, rx_eq->q.id, true, false, 0);
+ be_eq_notify(ctrl, tx_eq->q.id, true, false, 0);
+
+ /* The compl queues are created in the unarmed state; arm them */
+ be_cq_notify(ctrl, adapter->rx_obj.cq.id, true, 0);
+ be_cq_notify(ctrl, adapter->tx_obj.cq.id, true, 0);
+
+ be_link_status_update(adapter);
+
+ schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
+ return 0;
+
+tx_qs_destroy:
+ be_tx_queues_destroy(adapter);
+if_destroy:
+ be_cmd_if_destroy(ctrl, adapter->if_handle);
+do_none:
+ return status;
+}
+
+static int be_close(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+ struct be_eq_obj *rx_eq = &adapter->rx_eq;
+ struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ int vec;
+
+ cancel_delayed_work(&adapter->work);
+
+ netif_stop_queue(netdev);
+ netif_carrier_off(netdev);
+ adapter->link.speed = PHY_LINK_SPEED_ZERO;
+
+ be_intr_set(ctrl, false);
+
+ if (adapter->msix_enabled) {
+ vec = be_msix_vec_get(adapter, tx_eq->q.id);
+ synchronize_irq(vec);
+ vec = be_msix_vec_get(adapter, rx_eq->q.id);
+ synchronize_irq(vec);
+ } else {
+ synchronize_irq(netdev->irq);
+ }
+ be_irq_unregister(adapter);
+
+ napi_disable(&rx_eq->napi);
+ napi_disable(&tx_eq->napi);
+
+ be_rx_queues_destroy(adapter);
+ be_tx_queues_destroy(adapter);
+
+ be_cmd_if_destroy(ctrl, adapter->if_handle);
+ return 0;
+}
+
+static int be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
+ void **ip_hdr, void **tcpudp_hdr,
+ u64 *hdr_flags, void *priv)
+{
+ struct ethhdr *eh;
+ struct vlan_ethhdr *veh;
+ struct iphdr *iph;
+ u8 *va = page_address(frag->page) + frag->page_offset;
+ unsigned long ll_hlen;
+
+ prefetch(va);
+ eh = (struct ethhdr *)va;
+ *mac_hdr = eh;
+ ll_hlen = ETH_HLEN;
+ if (eh->h_proto != htons(ETH_P_IP)) {
+ if (eh->h_proto == htons(ETH_P_8021Q)) {
+ veh = (struct vlan_ethhdr *)va;
+ if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
+ return -1;
+
+ ll_hlen += VLAN_HLEN;
+ } else {
+ return -1;
+ }
+ }
+ *hdr_flags = LRO_IPV4;
+ iph = (struct iphdr *)(va + ll_hlen);
+ *ip_hdr = iph;
+ if (iph->protocol != IPPROTO_TCP)
+ return -1;
+ *hdr_flags |= LRO_TCP;
+ *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2);
+
+ return 0;
+}
+
+static void be_lro_init(struct be_adapter *adapter, struct net_device *netdev)
+{
+ struct net_lro_mgr *lro_mgr;
+
+ lro_mgr = &adapter->rx_obj.lro_mgr;
+ lro_mgr->dev = netdev;
+ lro_mgr->features = LRO_F_NAPI;
+ lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
+ lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
+ lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS;
+ lro_mgr->lro_arr = adapter->rx_obj.lro_desc;
+ lro_mgr->get_frag_header = be_get_frag_header;
+ lro_mgr->max_aggr = BE_MAX_FRAGS_PER_FRAME;
+}
+
+static struct net_device_ops be_netdev_ops = {
+ .ndo_open = be_open,
+ .ndo_stop = be_close,
+ .ndo_start_xmit = be_xmit,
+ .ndo_get_stats = be_get_stats,
+ .ndo_set_rx_mode = be_set_multicast_list,
+ .ndo_set_mac_address = be_mac_addr_set,
+ .ndo_change_mtu = be_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_vlan_rx_register = be_vlan_register,
+ .ndo_vlan_rx_add_vid = be_vlan_add_vid,
+ .ndo_vlan_rx_kill_vid = be_vlan_rem_vid,
+};
+
+static void be_netdev_init(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(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;
+
+ netdev->flags |= IFF_MULTICAST;
+
+ BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
+
+ SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
+
+ be_lro_init(adapter, netdev);
+
+ netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx,
+ BE_NAPI_WEIGHT);
+ netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx,
+ BE_NAPI_WEIGHT);
+
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+}
+
+static void be_unmap_pci_bars(struct be_adapter *adapter)
+{
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+ if (ctrl->csr)
+ iounmap(ctrl->csr);
+ if (ctrl->db)
+ iounmap(ctrl->db);
+ if (ctrl->pcicfg)
+ iounmap(ctrl->pcicfg);
+}
+
+static int be_map_pci_bars(struct be_adapter *adapter)
+{
+ u8 __iomem *addr;
+
+ addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
+ pci_resource_len(adapter->pdev, 2));
+ if (addr == NULL)
+ return -ENOMEM;
+ adapter->ctrl.csr = addr;
+
+ addr = ioremap_nocache(pci_resource_start(adapter->pdev, 4),
+ 128 * 1024);
+ if (addr == NULL)
+ goto pci_map_err;
+ adapter->ctrl.db = addr;
+
+ addr = ioremap_nocache(pci_resource_start(adapter->pdev, 1),
+ pci_resource_len(adapter->pdev, 1));
+ if (addr == NULL)
+ goto pci_map_err;
+ adapter->ctrl.pcicfg = addr;
+
+ return 0;
+pci_map_err:
+ be_unmap_pci_bars(adapter);
+ return -ENOMEM;
+}
+
+
+static void be_ctrl_cleanup(struct be_adapter *adapter)
+{
+ struct be_dma_mem *mem = &adapter->ctrl.mbox_mem_alloced;
+
+ be_unmap_pci_bars(adapter);
+
+ if (mem->va)
+ pci_free_consistent(adapter->pdev, mem->size,
+ mem->va, mem->dma);
+}
+
+/* Initialize the mbox required to send cmds to BE */
+static int be_ctrl_init(struct be_adapter *adapter)
+{
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+ struct be_dma_mem *mbox_mem_alloc = &ctrl->mbox_mem_alloced;
+ struct be_dma_mem *mbox_mem_align = &ctrl->mbox_mem;
+ int status;
+ u32 val;
+
+ status = be_map_pci_bars(adapter);
+ if (status)
+ return status;
+
+ mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
+ mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev,
+ mbox_mem_alloc->size, &mbox_mem_alloc->dma);
+ if (!mbox_mem_alloc->va) {
+ be_unmap_pci_bars(adapter);
+ return -1;
+ }
+ mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
+ mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
+ mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
+ memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
+ spin_lock_init(&ctrl->cmd_lock);
+
+ val = ioread32(ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
+ ctrl->pci_func = (val >> MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT) &
+ MEMBAR_CTRL_INT_CTRL_PFUNC_MASK;
+ return 0;
+}
+
+static void be_stats_cleanup(struct be_adapter *adapter)
+{
+ struct be_stats_obj *stats = &adapter->stats;
+ struct be_dma_mem *cmd = &stats->cmd;
+
+ if (cmd->va)
+ pci_free_consistent(adapter->pdev, cmd->size,
+ cmd->va, cmd->dma);
+}
+
+static int be_stats_init(struct be_adapter *adapter)
+{
+ struct be_stats_obj *stats = &adapter->stats;
+ struct be_dma_mem *cmd = &stats->cmd;
+
+ cmd->size = sizeof(struct be_cmd_req_get_stats);
+ cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma);
+ if (cmd->va == NULL)
+ return -1;
+ return 0;
+}
+
+static void __devexit be_remove(struct pci_dev *pdev)
+{
+ struct be_adapter *adapter = pci_get_drvdata(pdev);
+ if (!adapter)
+ return;
+
+ unregister_netdev(adapter->netdev);
+
+ be_stats_cleanup(adapter);
+
+ be_ctrl_cleanup(adapter);
+
+ if (adapter->msix_enabled) {
+ pci_disable_msix(adapter->pdev);
+ adapter->msix_enabled = false;
+ }
+
+ pci_set_drvdata(pdev, NULL);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+
+ free_netdev(adapter->netdev);
+}
+
+static int be_hw_up(struct be_adapter *adapter)
+{
+ struct be_ctrl_info *ctrl = &adapter->ctrl;
+ int status;
+
+ status = be_cmd_POST(ctrl);
+ if (status)
+ return status;
+
+ status = be_cmd_get_fw_ver(ctrl, adapter->fw_ver);
+ if (status)
+ return status;
+
+ status = be_cmd_query_fw_cfg(ctrl, &adapter->port_num);
+ return status;
+}
+
+static int __devinit be_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pdev_id)
+{
+ int status = 0;
+ struct be_adapter *adapter;
+ struct net_device *netdev;
+ struct be_ctrl_info *ctrl;
+ u8 mac[ETH_ALEN];
+
+ status = pci_enable_device(pdev);
+ if (status)
+ goto do_none;
+
+ status = pci_request_regions(pdev, DRV_NAME);
+ if (status)
+ goto disable_dev;
+ pci_set_master(pdev);
+
+ netdev = alloc_etherdev(sizeof(struct be_adapter));
+ if (netdev == NULL) {
+ status = -ENOMEM;
+ goto rel_reg;
+ }
+ adapter = netdev_priv(netdev);
+ adapter->pdev = pdev;
+ pci_set_drvdata(pdev, adapter);
+ adapter->netdev = netdev;
+
+ be_msix_enable(adapter);
+
+ status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ if (!status) {
+ netdev->features |= NETIF_F_HIGHDMA;
+ } else {
+ status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (status) {
+ dev_err(&pdev->dev, "Could not set PCI DMA Mask\n");
+ goto free_netdev;
+ }
+ }
+
+ ctrl = &adapter->ctrl;
+ status = be_ctrl_init(adapter);
+ if (status)
+ goto free_netdev;
+
+ status = be_stats_init(adapter);
+ if (status)
+ goto ctrl_clean;
+
+ status = be_hw_up(adapter);
+ if (status)
+ goto stats_clean;
+
+ status = be_cmd_mac_addr_query(ctrl, mac, MAC_ADDRESS_TYPE_NETWORK,
+ true /* permanent */, 0);
+ if (status)
+ goto stats_clean;
+ memcpy(netdev->dev_addr, mac, ETH_ALEN);
+
+ INIT_DELAYED_WORK(&adapter->work, be_worker);
+ be_netdev_init(netdev);
+ SET_NETDEV_DEV(netdev, &adapter->pdev->dev);
+
+ status = register_netdev(netdev);
+ if (status != 0)
+ goto stats_clean;
+
+ dev_info(&pdev->dev, BE_NAME " port %d\n", adapter->port_num);
+ return 0;
+
+stats_clean:
+ be_stats_cleanup(adapter);
+ctrl_clean:
+ be_ctrl_cleanup(adapter);
+free_netdev:
+ free_netdev(adapter->netdev);
+rel_reg:
+ pci_release_regions(pdev);
+disable_dev:
+ pci_disable_device(pdev);
+do_none:
+ dev_warn(&pdev->dev, BE_NAME " initialization failed\n");
+ return status;
+}
+
+static int be_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct be_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
+
+ netif_device_detach(netdev);
+ if (netif_running(netdev)) {
+ rtnl_lock();
+ be_close(netdev);
+ rtnl_unlock();
+ }
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ return 0;
+}
+
+static int be_resume(struct pci_dev *pdev)
+{
+ int status = 0;
+ struct be_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
+
+ netif_device_detach(netdev);
+
+ status = pci_enable_device(pdev);
+ if (status)
+ return status;
+
+ pci_set_power_state(pdev, 0);
+ pci_restore_state(pdev);
+
+ if (netif_running(netdev)) {
+ rtnl_lock();
+ be_open(netdev);
+ rtnl_unlock();
+ }
+ netif_device_attach(netdev);
+ return 0;
+}
+
+static struct pci_driver be_driver = {
+ .name = DRV_NAME,
+ .id_table = be_dev_ids,
+ .probe = be_probe,
+ .remove = be_remove,
+ .suspend = be_suspend,
+ .resume = be_resume
+};
+
+static int __init be_init_module(void)
+{
+ if (rx_frag_size != 8192 && rx_frag_size != 4096
+ && rx_frag_size != 2048) {
+ printk(KERN_WARNING DRV_NAME
+ " : Module param rx_frag_size must be 2048/4096/8192."
+ " Using 2048\n");
+ rx_frag_size = 2048;
+ }
+ /* Ensure rx_frag_size is aligned to chache line */
+ if (SKB_DATA_ALIGN(rx_frag_size) != rx_frag_size) {
+ printk(KERN_WARNING DRV_NAME
+ " : Bad module param rx_frag_size. Using 2048\n");
+ rx_frag_size = 2048;
+ }
+
+ return pci_register_driver(&be_driver);
+}
+module_init(be_init_module);
+
+static void __exit be_exit_module(void)
+{
+ pci_unregister_driver(&be_driver);
+}
+module_exit(be_exit_module);
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 78e31aa861e..9afe8092dfc 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -415,11 +415,11 @@ static int mii_probe(struct net_device *dev)
}
#if defined(CONFIG_BFIN_MAC_RMII)
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_RMII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+ 0, PHY_INTERFACE_MODE_RMII);
#else
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
#endif
if (IS_ERR(phydev)) {
@@ -447,7 +447,7 @@ static int mii_probe(struct net_device *dev)
printk(KERN_INFO "%s: attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)"
"@sclk=%dMHz)\n",
- DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq,
+ DRV_NAME, phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
MDC_CLK, mdc_div, sclk/1000000);
return 0;
@@ -488,7 +488,7 @@ static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev,
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->fw_version, "N/A");
- strcpy(info->bus_info, dev->dev.bus_id);
+ strcpy(info->bus_info, dev_name(&dev->dev));
}
static struct ethtool_ops bfin_mac_ethtool_ops = {
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 8a546a33d58..44d015f70d1 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1062,7 +1062,6 @@ static int miscintcount;
static irqreturn_t bmac_misc_intr(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
- struct bmac_data *bp = netdev_priv(dev);
unsigned int status = bmread(dev, STATUS);
if (miscintcount++ < 10) {
XXDEBUG(("bmac_misc_intr\n"));
@@ -1240,7 +1239,7 @@ static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *inf
{
struct bmac_data *bp = netdev_priv(dev);
strcpy(info->driver, "bmac");
- strcpy(info->bus_info, bp->mdev->ofdev.dev.bus_id);
+ strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev));
}
static const struct ethtool_ops bmac_ethtool_ops = {
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d4a3dac21dc..ad446db8e18 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1,6 +1,6 @@
/* bnx2.c: Broadcom NX2 network driver.
*
- * Copyright (c) 2004-2008 Broadcom Corporation
+ * Copyright (c) 2004-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
@@ -57,8 +57,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.9.0"
-#define DRV_MODULE_RELDATE "Dec 16, 2008"
+#define DRV_MODULE_VERSION "1.9.3"
+#define DRV_MODULE_RELDATE "March 17, 2009"
#define RUN_AT(x) (jiffies + (x))
@@ -1497,6 +1497,8 @@ static int bnx2_fw_sync(struct bnx2 *, u32, int, int);
static int
bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 speed_arg = 0, pause_adv;
@@ -1554,6 +1556,8 @@ bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
static int
bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 adv, bmcr;
u32 new_adv = 0;
@@ -1866,6 +1870,8 @@ bnx2_set_remote_link(struct bnx2 *bp)
static int
bnx2_setup_copper_phy(struct bnx2 *bp)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 bmcr;
u32 new_bmcr;
@@ -1963,6 +1969,8 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
static int
bnx2_setup_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
if (bp->loopback == MAC_LOOPBACK)
return 0;
@@ -2176,6 +2184,8 @@ bnx2_init_copper_phy(struct bnx2 *bp, int reset_phy)
static int
bnx2_init_phy(struct bnx2 *bp, int reset_phy)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 val;
int rc = 0;
@@ -2910,18 +2920,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
rx_hdr = (struct l2_fhdr *) skb->data;
len = rx_hdr->l2_fhdr_pkt_len;
+ status = rx_hdr->l2_fhdr_status;
- if ((status = rx_hdr->l2_fhdr_status) &
- (L2_FHDR_ERRORS_BAD_CRC |
- L2_FHDR_ERRORS_PHY_DECODE |
- L2_FHDR_ERRORS_ALIGNMENT |
- L2_FHDR_ERRORS_TOO_SHORT |
- L2_FHDR_ERRORS_GIANT_FRAME)) {
-
- bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
- sw_ring_prod);
- goto next_rx;
- }
hdr_len = 0;
if (status & L2_FHDR_STATUS_SPLIT) {
hdr_len = rx_hdr->l2_fhdr_ip_xsum;
@@ -2931,6 +2931,24 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
pg_ring_used = 1;
}
+ if (unlikely(status & (L2_FHDR_ERRORS_BAD_CRC |
+ L2_FHDR_ERRORS_PHY_DECODE |
+ L2_FHDR_ERRORS_ALIGNMENT |
+ L2_FHDR_ERRORS_TOO_SHORT |
+ L2_FHDR_ERRORS_GIANT_FRAME))) {
+
+ bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
+ sw_ring_prod);
+ if (pg_ring_used) {
+ int pages;
+
+ pages = PAGE_ALIGN(len - hdr_len) >> PAGE_SHIFT;
+
+ bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages);
+ }
+ goto next_rx;
+ }
+
len -= 4;
if (len <= bp->rx_copy_thresh) {
@@ -2997,6 +3015,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
+ skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]);
+
#ifdef BCM_VLAN
if (hw_vlan)
vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
@@ -3053,7 +3073,7 @@ bnx2_msi(int irq, void *dev_instance)
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- netif_rx_schedule(&bnapi->napi);
+ napi_schedule(&bnapi->napi);
return IRQ_HANDLED;
}
@@ -3070,7 +3090,7 @@ bnx2_msi_1shot(int irq, void *dev_instance)
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- netif_rx_schedule(&bnapi->napi);
+ napi_schedule(&bnapi->napi);
return IRQ_HANDLED;
}
@@ -3106,9 +3126,9 @@ bnx2_interrupt(int irq, void *dev_instance)
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- if (netif_rx_schedule_prep(&bnapi->napi)) {
+ if (napi_schedule_prep(&bnapi->napi)) {
bnapi->last_status_idx = sblk->status_idx;
- __netif_rx_schedule(&bnapi->napi);
+ __napi_schedule(&bnapi->napi);
}
return IRQ_HANDLED;
@@ -3218,7 +3238,7 @@ static int bnx2_poll_msix(struct napi_struct *napi, int budget)
rmb();
if (likely(!bnx2_has_fast_work(bnapi))) {
- netif_rx_complete(napi);
+ napi_complete(napi);
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
bnapi->last_status_idx);
@@ -3251,7 +3271,7 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
rmb();
if (likely(!bnx2_has_work(bnapi))) {
- netif_rx_complete(napi);
+ napi_complete(napi);
if (likely(bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)) {
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -5835,9 +5855,6 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
msix_ent[i].entry = i;
msix_ent[i].vector = 0;
-
- snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
- bp->irq_tbl[i].handler = bnx2_msi_1shot;
}
rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
@@ -5846,8 +5863,11 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
bp->irq_nvecs = msix_vecs;
bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
- for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
+ for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
bp->irq_tbl[i].vector = msix_ent[i].vector;
+ snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
+ bp->irq_tbl[i].handler = bnx2_msi_1shot;
+ }
}
static void
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 900641ac63e..704cbbcbf97 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1,6 +1,6 @@
/* bnx2.h: Broadcom NX2 network driver.
*
- * Copyright (c) 2004-2007 Broadcom Corporation
+ * Copyright (c) 2004-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
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 24c3cc40c23..6a4f1d695de 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -15,854 +15,849 @@
*/
static u8 bnx2_COM_b06FwText[] = {
- 0xcd, 0x7c, 0x0d, 0x70, 0x5b, 0xd7, 0x95, 0xde, 0xc1, 0x03, 0x40, 0x82,
- 0x10, 0x45, 0x3d, 0x52, 0x30, 0x0d, 0x3b, 0x4c, 0x82, 0x47, 0x3c, 0x92,
- 0xb0, 0xc9, 0x64, 0x9f, 0x64, 0x46, 0x66, 0x12, 0xac, 0x05, 0x03, 0xa4,
- 0x4c, 0x27, 0xea, 0x92, 0xb6, 0x19, 0x47, 0x6d, 0x35, 0x09, 0x17, 0x92,
- 0x12, 0xdb, 0x4d, 0xa7, 0x9a, 0xc6, 0xe9, 0x2a, 0x1b, 0xc7, 0x82, 0x41,
- 0xca, 0x51, 0x52, 0x8a, 0x60, 0x24, 0x4a, 0xf2, 0x74, 0xb3, 0xbb, 0x0c,
- 0x48, 0x4a, 0x8e, 0x03, 0x09, 0x96, 0xec, 0x75, 0xdc, 0xad, 0xb3, 0x62,
- 0x68, 0xad, 0xec, 0x4d, 0xb3, 0xad, 0x9d, 0x49, 0x3a, 0x9a, 0xa9, 0xb7,
- 0x55, 0x95, 0xa4, 0xf9, 0x99, 0xfe, 0xb8, 0x49, 0xa6, 0x75, 0xbb, 0xf1,
- 0xbe, 0x7e, 0xdf, 0x7d, 0xf7, 0x11, 0x20, 0xc5, 0x28, 0xde, 0xec, 0x64,
- 0x66, 0x39, 0x83, 0xb9, 0xef, 0xde, 0x77, 0x7f, 0xce, 0x3d, 0xf7, 0xfc,
- 0x7c, 0xe7, 0xde, 0xfb, 0x78, 0x87, 0x48, 0x54, 0xf4, 0xdf, 0x46, 0xfc,
- 0xfa, 0xff, 0xe9, 0x3f, 0xdb, 0xb3, 0xf5, 0xdd, 0xfd, 0xef, 0x66, 0xde,
- 0x30, 0x42, 0x21, 0xa6, 0x41, 0xfc, 0x62, 0xf8, 0x6d, 0xd5, 0xcf, 0xeb,
- 0xfd, 0x99, 0xf8, 0x6d, 0x0b, 0x88, 0x8c, 0xff, 0x44, 0x24, 0xb0, 0xe6,
- 0x5d, 0x64, 0x9d, 0xfa, 0xae, 0xfb, 0x4b, 0x3a, 0xd2, 0x7f, 0x06, 0x7e,
- 0x89, 0xeb, 0x57, 0x59, 0x19, 0xf7, 0xd7, 0xfd, 0x0b, 0xea, 0xe6, 0x1b,
- 0xf5, 0x4f, 0x22, 0x46, 0x5a, 0x46, 0xb2, 0xb6, 0x44, 0x82, 0xe9, 0x9f,
- 0x8f, 0xec, 0xb1, 0x45, 0x32, 0x95, 0xde, 0x44, 0x4e, 0xde, 0x74, 0x0b,
- 0xb1, 0x90, 0xb0, 0xfc, 0xed, 0xe9, 0x5f, 0x1c, 0xfc, 0xfa, 0xed, 0xd6,
- 0xeb, 0x73, 0x41, 0x89, 0x98, 0xe9, 0x37, 0xc4, 0xec, 0x96, 0x48, 0x07,
- 0xda, 0x7c, 0xa9, 0xe7, 0x49, 0x43, 0x5a, 0xfc, 0xbe, 0xcc, 0xf1, 0x60,
- 0x5a, 0x46, 0xf7, 0x4e, 0x1d, 0x74, 0x0d, 0x5b, 0x0a, 0x37, 0xa7, 0xed,
- 0x44, 0x51, 0x9a, 0x07, 0x26, 0xfb, 0x6f, 0x17, 0xe4, 0x47, 0xf7, 0x56,
- 0x22, 0x92, 0xad, 0x16, 0x9a, 0x0d, 0xdb, 0x46, 0x1a, 0x29, 0xbc, 0x2d,
- 0x2d, 0x91, 0x86, 0xf4, 0x6c, 0xe3, 0x25, 0x9b, 0xe3, 0x0f, 0x60, 0xfc,
- 0xb7, 0x49, 0xc8, 0x76, 0xdd, 0x49, 0x8c, 0xbf, 0xa3, 0xf2, 0xa6, 0xfb,
- 0x58, 0xc8, 0x1b, 0xdb, 0x48, 0x1f, 0x08, 0x32, 0x0d, 0xa4, 0x33, 0x23,
- 0x9d, 0x15, 0x95, 0x6f, 0xf0, 0xf2, 0x83, 0x3a, 0x1f, 0x89, 0x7a, 0xb4,
- 0x4b, 0x13, 0x68, 0x8f, 0x84, 0xd2, 0xe9, 0x26, 0xf4, 0x11, 0x09, 0xa7,
- 0x97, 0x7e, 0x7b, 0x51, 0xd5, 0x3b, 0xac, 0xeb, 0x3d, 0x10, 0xf6, 0xda,
- 0x4d, 0x8e, 0x74, 0x57, 0x98, 0xce, 0x8e, 0x74, 0xa9, 0xf4, 0x4b, 0x23,
- 0x49, 0x95, 0xce, 0xa9, 0x7a, 0x81, 0xf4, 0xc2, 0x88, 0xad, 0xd2, 0xb4,
- 0x2e, 0x1f, 0x1e, 0x49, 0xa8, 0x74, 0xa7, 0x4e, 0x47, 0x75, 0x3a, 0xa6,
- 0xd3, 0x5d, 0x3a, 0xdd, 0xad, 0xd3, 0x71, 0x9d, 0xee, 0xd5, 0xfd, 0x3c,
- 0xa0, 0xf3, 0x9f, 0xd0, 0xe9, 0x7e, 0x9d, 0x3e, 0xac, 0xd3, 0x03, 0x3a,
- 0x7d, 0x44, 0xd3, 0x55, 0xd0, 0xe9, 0x94, 0x2e, 0x9f, 0xd1, 0x74, 0x3e,
- 0x01, 0x7a, 0xfe, 0x71, 0xa3, 0x96, 0x5b, 0xcc, 0x37, 0x21, 0x7b, 0xa6,
- 0x22, 0x52, 0x2c, 0x05, 0x25, 0xa7, 0xd6, 0xf3, 0xe3, 0x61, 0x89, 0x46,
- 0x64, 0xa2, 0x1a, 0x91, 0x2b, 0x4a, 0x5c, 0x7f, 0xe4, 0x7e, 0xbd, 0xc7,
- 0x94, 0xa7, 0xab, 0x31, 0xb9, 0x50, 0x95, 0xc0, 0x68, 0x4f, 0x93, 0x18,
- 0x47, 0x6f, 0x96, 0x8c, 0x19, 0x90, 0xa0, 0xe2, 0x6b, 0x42, 0xb2, 0x53,
- 0xed, 0xc8, 0x5b, 0x71, 0x91, 0xc5, 0xb0, 0xb7, 0x8e, 0x11, 0x09, 0x9e,
- 0xe0, 0xba, 0x3c, 0x37, 0x72, 0x69, 0x36, 0x2e, 0xa1, 0xe9, 0x04, 0xfa,
- 0x6f, 0x96, 0xf0, 0x09, 0xe9, 0x08, 0x4a, 0x57, 0xfc, 0x63, 0xa8, 0x31,
- 0x58, 0x09, 0xc9, 0x50, 0x25, 0x80, 0xb5, 0x8a, 0x40, 0x4e, 0x9a, 0xf1,
- 0x33, 0xf1, 0x8b, 0xe1, 0x17, 0xc7, 0xef, 0xaf, 0xd0, 0x4f, 0x87, 0xe4,
- 0x2a, 0xec, 0x13, 0xe3, 0x96, 0x30, 0x7e, 0xc9, 0x32, 0xc7, 0x85, 0x34,
- 0xc5, 0xe5, 0xeb, 0x3d, 0x1e, 0x4d, 0x17, 0xaa, 0x91, 0x40, 0xf6, 0xa4,
- 0xec, 0xcf, 0x39, 0x92, 0x30, 0xec, 0xa8, 0xe4, 0xcd, 0x40, 0x62, 0x6f,
- 0xaa, 0x4d, 0x0a, 0x63, 0x78, 0x57, 0x92, 0x8c, 0x81, 0xbe, 0xf3, 0xa6,
- 0x8c, 0x7b, 0xef, 0x58, 0xf6, 0x7f, 0xa1, 0xaf, 0x96, 0x49, 0xc1, 0xbd,
- 0x50, 0xfa, 0xd7, 0x78, 0x66, 0x5f, 0x2f, 0x86, 0x3c, 0x9a, 0xdf, 0x40,
- 0x9e, 0xe5, 0xee, 0x26, 0x2f, 0xcf, 0x67, 0xd6, 0xf5, 0xc7, 0xf4, 0xe7,
- 0xca, 0xb1, 0x7b, 0x30, 0x5f, 0x8e, 0xbf, 0x32, 0x5f, 0xd0, 0xd1, 0x1c,
- 0xc8, 0x9d, 0x4c, 0xc8, 0xa1, 0xd2, 0x1d, 0x92, 0x75, 0x5c, 0x77, 0x8f,
- 0x23, 0x31, 0x43, 0xba, 0xcc, 0x1c, 0xde, 0x96, 0x2b, 0x12, 0xc8, 0x96,
- 0x7c, 0x7e, 0xb0, 0xdf, 0x10, 0xca, 0xda, 0x51, 0xbf, 0x25, 0x30, 0x78,
- 0x12, 0xb4, 0xa7, 0xc9, 0x17, 0xc8, 0xac, 0xd3, 0x15, 0xdf, 0x8b, 0xf1,
- 0xe6, 0x2b, 0x5d, 0xce, 0xb2, 0x98, 0xe8, 0xb3, 0x0d, 0x75, 0xc8, 0x23,
- 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x33, 0xda, 0xc6, 0xf0, 0x8e, 0x34, 0xb9,
- 0x6e, 0xd6, 0x31, 0x99, 0x97, 0x39, 0xf0, 0x6d, 0x8e, 0x7c, 0x8b, 0x76,
- 0xc8, 0xa9, 0x0a, 0xc7, 0x58, 0x8f, 0xee, 0x5b, 0xff, 0x9e, 0xd1, 0x1d,
- 0x47, 0xff, 0x31, 0xa4, 0x1b, 0x02, 0xd9, 0x63, 0x2e, 0xc6, 0x8f, 0xe3,
- 0x79, 0xbd, 0x39, 0x5c, 0xd1, 0x32, 0x18, 0x07, 0xed, 0x31, 0x39, 0xa7,
- 0xe4, 0x70, 0x83, 0x04, 0x21, 0x87, 0x5c, 0xe3, 0xd6, 0x13, 0xef, 0x91,
- 0x7c, 0xcc, 0x4a, 0xd0, 0x76, 0x76, 0x6e, 0x6d, 0xc2, 0x1c, 0xb5, 0x15,
- 0x9c, 0x8e, 0x41, 0x0e, 0x97, 0x5b, 0x0d, 0x94, 0x18, 0x62, 0x99, 0xff,
- 0x48, 0x0a, 0x92, 0x5b, 0xf8, 0xbd, 0x80, 0x44, 0x0d, 0xd4, 0xbb, 0x25,
- 0xe0, 0xf1, 0x80, 0xfc, 0xc9, 0x80, 0x3f, 0x01, 0xd1, 0xf6, 0x41, 0x3a,
- 0x2b, 0x7c, 0xdf, 0x9b, 0x30, 0xd4, 0xbb, 0x41, 0xbc, 0x0b, 0x49, 0x72,
- 0xab, 0xff, 0x7e, 0x10, 0xef, 0x6f, 0x96, 0x71, 0x13, 0xb4, 0x94, 0x9e,
- 0x37, 0xb2, 0xa0, 0xf1, 0xce, 0x90, 0x9a, 0x2b, 0xea, 0x8e, 0xd7, 0xf5,
- 0x33, 0x8e, 0x7a, 0xff, 0x0a, 0x63, 0x81, 0xde, 0x52, 0x02, 0xb4, 0xb4,
- 0x83, 0x16, 0xd2, 0x58, 0x30, 0xb2, 0xd5, 0x10, 0xf2, 0x93, 0x46, 0xee,
- 0xf4, 0x61, 0x3c, 0x8b, 0x69, 0xa4, 0x9f, 0x67, 0x8a, 0xf6, 0xbb, 0xeb,
- 0xda, 0xef, 0x46, 0x7b, 0x8e, 0xc1, 0xf6, 0x9e, 0xfc, 0x17, 0x94, 0x2c,
- 0x26, 0xae, 0xc3, 0x8f, 0xe0, 0xaf, 0xc1, 0x8f, 0x7f, 0xa3, 0xf9, 0xf1,
- 0xd7, 0xf2, 0x9b, 0xe7, 0xc7, 0x7f, 0xfa, 0x0d, 0xf1, 0x43, 0x24, 0x7f,
- 0x8c, 0xcf, 0x21, 0x29, 0x28, 0xbb, 0x45, 0xbd, 0xa5, 0xbc, 0xd3, 0x66,
- 0x91, 0x4f, 0x94, 0x63, 0xe8, 0x40, 0x35, 0x84, 0xf4, 0x49, 0xa4, 0x1b,
- 0x02, 0xa3, 0xc7, 0xae, 0x62, 0xfd, 0x5d, 0x31, 0xb7, 0xfa, 0x7e, 0xa3,
- 0x10, 0x37, 0xa5, 0x43, 0xcc, 0x77, 0xc3, 0x69, 0xb7, 0x5b, 0x66, 0x5e,
- 0x7e, 0x80, 0xf7, 0x6f, 0x06, 0x7c, 0xff, 0x9e, 0x9d, 0x6a, 0x7a, 0x23,
- 0xa3, 0x9e, 0xc2, 0xe4, 0x67, 0xc6, 0x48, 0x87, 0x02, 0xb9, 0x52, 0x62,
- 0xdc, 0x48, 0xc7, 0x60, 0xa7, 0x98, 0x1f, 0x08, 0x78, 0x34, 0xf7, 0xa3,
- 0xae, 0x6f, 0xb3, 0x7c, 0xda, 0xfb, 0x41, 0xfb, 0x5a, 0xdb, 0x95, 0x01,
- 0x2d, 0xa4, 0x81, 0x74, 0x15, 0x82, 0x9a, 0xf7, 0xe8, 0xe7, 0x80, 0xea,
- 0x27, 0x98, 0x1e, 0x10, 0xfa, 0xd0, 0xfc, 0x14, 0xf5, 0x80, 0xed, 0xd8,
- 0x97, 0x67, 0x93, 0xf3, 0x15, 0xbf, 0x8f, 0x42, 0x7d, 0x1f, 0xa0, 0x47,
- 0x36, 0x19, 0x76, 0x18, 0x6b, 0xcf, 0xae, 0x0e, 0xe3, 0xdd, 0x97, 0x24,
- 0x7b, 0xfa, 0x76, 0x03, 0x73, 0x40, 0xbf, 0xe4, 0xd1, 0x28, 0x6c, 0x36,
- 0xf5, 0x2c, 0x22, 0xb9, 0x18, 0xcb, 0x3e, 0xa2, 0xc7, 0x0d, 0x49, 0x46,
- 0xe5, 0xbf, 0xd2, 0x52, 0xa3, 0xe3, 0x79, 0x3d, 0x9f, 0x34, 0xe6, 0x43,
- 0x1a, 0xfc, 0xb9, 0xa4, 0xeb, 0xe6, 0xe2, 0xf3, 0x9a, 0xbc, 0x30, 0x61,
- 0xe3, 0x23, 0xda, 0x87, 0xb0, 0xdd, 0x64, 0xdd, 0xda, 0x4d, 0xa2, 0x0d,
- 0x79, 0x8f, 0x3a, 0x6b, 0xfc, 0x0a, 0x7d, 0xca, 0x20, 0xfa, 0x29, 0xce,
- 0x1a, 0x92, 0x73, 0xe0, 0xab, 0x9d, 0xb7, 0x69, 0x79, 0xad, 0xc9, 0x52,
- 0x78, 0x5d, 0x59, 0x3a, 0x68, 0x78, 0xf6, 0x1a, 0xbe, 0x05, 0xfe, 0x67,
- 0x62, 0xd6, 0x4a, 0xf9, 0xb2, 0x54, 0x9c, 0x7a, 0x2b, 0xb2, 0xe4, 0xb7,
- 0x8f, 0x40, 0x76, 0xfd, 0x31, 0xd6, 0xd2, 0xec, 0xd7, 0x01, 0x8d, 0xa5,
- 0xac, 0xc6, 0x28, 0x1c, 0xc7, 0xf3, 0x0d, 0x73, 0xab, 0x7c, 0xc3, 0x61,
- 0xb4, 0x95, 0x40, 0xae, 0xa7, 0x59, 0xf6, 0xcd, 0xfa, 0x7d, 0x1c, 0x56,
- 0x32, 0xbb, 0x77, 0xca, 0x32, 0x87, 0x82, 0x92, 0x19, 0x9a, 0x19, 0x90,
- 0xc1, 0x6a, 0x07, 0xd6, 0xf4, 0x0d, 0x17, 0xbe, 0xf3, 0xdd, 0x61, 0xb1,
- 0x61, 0x17, 0x31, 0xe7, 0x7e, 0xf0, 0xb8, 0x1a, 0x16, 0x23, 0xed, 0x20,
- 0xad, 0xc7, 0x58, 0xa1, 0xd0, 0xd0, 0xaa, 0x7c, 0x03, 0xea, 0xa0, 0xef,
- 0xfe, 0xb5, 0xf5, 0x20, 0x9f, 0xe0, 0x6d, 0xd6, 0x79, 0xd3, 0x85, 0x1f,
- 0xd6, 0x3e, 0x8b, 0xa5, 0xb4, 0x13, 0xbe, 0x8d, 0xf8, 0x10, 0xf4, 0x5b,
- 0xe9, 0x42, 0xc1, 0x48, 0xef, 0x47, 0x1f, 0xa2, 0xe4, 0xb4, 0x58, 0x7d,
- 0xda, 0xd7, 0x7b, 0x55, 0xbe, 0xa3, 0x9f, 0xb2, 0x37, 0x07, 0x4c, 0xc0,
- 0x39, 0x2d, 0x28, 0x5d, 0xcf, 0x99, 0x31, 0x99, 0x2c, 0x29, 0x4c, 0x23,
- 0xc9, 0xca, 0x1f, 0x49, 0xee, 0xb4, 0xc8, 0x37, 0xa7, 0x58, 0xef, 0x05,
- 0x5d, 0xef, 0x79, 0xd4, 0x4b, 0x26, 0x06, 0x03, 0x16, 0xfc, 0x80, 0x05,
- 0x35, 0xe9, 0x4d, 0x20, 0x35, 0x87, 0xf1, 0x1b, 0xa4, 0x93, 0x41, 0x3d,
- 0x0f, 0x03, 0x3d, 0x0f, 0x7e, 0x88, 0xdc, 0x53, 0x6a, 0x84, 0x3d, 0xf9,
- 0x2f, 0xa0, 0x35, 0x26, 0x5f, 0xc0, 0x3c, 0x2e, 0x4d, 0x11, 0x67, 0xbd,
- 0x20, 0x8b, 0x53, 0xc4, 0x5d, 0xcf, 0xcb, 0xe4, 0x54, 0xd2, 0xf9, 0x26,
- 0xf8, 0x7c, 0x4a, 0x38, 0x97, 0x5e, 0x07, 0x29, 0x30, 0xa0, 0x95, 0x78,
- 0x1c, 0xf6, 0xac, 0x67, 0xab, 0xd7, 0x5f, 0x97, 0xee, 0xcf, 0xae, 0x58,
- 0x72, 0xc5, 0xa4, 0x7d, 0xba, 0x56, 0xc7, 0xb3, 0x5a, 0xc7, 0x47, 0x9d,
- 0x0e, 0x31, 0xa0, 0xd7, 0x99, 0xb1, 0x02, 0xbc, 0x1f, 0xf5, 0xfa, 0x7f,
- 0x1b, 0x35, 0xfc, 0x33, 0x00, 0xac, 0x6a, 0x29, 0x7f, 0xf7, 0xb7, 0xd3,
- 0xf1, 0x7a, 0xdd, 0xe6, 0xf8, 0x2d, 0x68, 0x13, 0x42, 0x7a, 0x7d, 0xbd,
- 0x46, 0x1f, 0x75, 0x6d, 0x07, 0xa8, 0x17, 0x68, 0xf3, 0x07, 0xe0, 0x05,
- 0xf9, 0xff, 0x56, 0xf4, 0xb9, 0x37, 0xf8, 0x96, 0xf4, 0x79, 0xec, 0x7a,
- 0xfa, 0x5c, 0xaf, 0xcb, 0x67, 0xc9, 0x0b, 0x8c, 0x2d, 0x33, 0x9e, 0x6c,
- 0x75, 0x81, 0xd7, 0x09, 0xc8, 0x29, 0x68, 0x28, 0xfd, 0x8d, 0x9b, 0x09,
- 0x79, 0x78, 0xce, 0x93, 0x27, 0xd6, 0xf3, 0xeb, 0x78, 0xb6, 0x77, 0xb0,
- 0x7a, 0x45, 0xd9, 0xd9, 0x73, 0xca, 0xce, 0x5a, 0x87, 0x0b, 0x42, 0x79,
- 0xbb, 0x2d, 0x48, 0xbe, 0x3f, 0xed, 0x7c, 0x16, 0x34, 0x5a, 0x89, 0x84,
- 0xd1, 0x55, 0x30, 0x8c, 0xcf, 0xca, 0xfe, 0xf9, 0x87, 0x65, 0x7f, 0x89,
- 0x7d, 0xa4, 0xf1, 0xde, 0x46, 0x59, 0x13, 0x6c, 0x2d, 0x6d, 0xfa, 0x1b,
- 0x01, 0x6f, 0x2c, 0x03, 0xfe, 0x6b, 0x29, 0x70, 0x4f, 0xf5, 0x62, 0x20,
- 0x3b, 0x4f, 0xdd, 0x45, 0x79, 0xb5, 0xde, 0xe6, 0xfb, 0xf6, 0xbe, 0x66,
- 0xff, 0x06, 0x4b, 0x93, 0xc4, 0x80, 0x46, 0xd6, 0xe1, 0x9a, 0x51, 0x37,
- 0x2f, 0x98, 0xde, 0x9c, 0x3f, 0x09, 0x3e, 0x51, 0xaf, 0xc9, 0x37, 0xf8,
- 0xc0, 0x10, 0x75, 0x96, 0xcf, 0xe2, 0x06, 0xd3, 0xd4, 0x3b, 0x09, 0x05,
- 0x41, 0x46, 0x2e, 0xc6, 0x3a, 0x77, 0x80, 0xce, 0xb5, 0x3a, 0xcd, 0x75,
- 0x14, 0x6d, 0x43, 0x58, 0x36, 0x80, 0xe7, 0x4e, 0x19, 0x9f, 0xcf, 0x60,
- 0xcc, 0x3b, 0x75, 0xdf, 0xab, 0x7c, 0x0c, 0xfa, 0x48, 0xe8, 0xf5, 0xd8,
- 0xe0, 0xdb, 0x41, 0x94, 0x39, 0xba, 0xac, 0xa1, 0xae, 0xcc, 0x5f, 0xb7,
- 0x8f, 0x62, 0x7c, 0xfa, 0x8a, 0x61, 0x8d, 0x7f, 0x5c, 0x37, 0xc7, 0xf5,
- 0xee, 0xfb, 0x87, 0x42, 0xdd, 0xb8, 0x50, 0x2a, 0x98, 0x41, 0x25, 0xa3,
- 0x2f, 0xfc, 0x4e, 0x4d, 0x46, 0x81, 0x97, 0x55, 0x2f, 0xe4, 0x31, 0x69,
- 0x69, 0x06, 0x4f, 0x07, 0x41, 0x2b, 0x78, 0xd7, 0x1e, 0x00, 0xff, 0x9a,
- 0x25, 0x5f, 0x4d, 0xeb, 0x77, 0x2c, 0x0f, 0xc9, 0x68, 0xcc, 0xf7, 0x47,
- 0xb7, 0x99, 0x1e, 0xe6, 0x45, 0x9d, 0xd2, 0x8f, 0x83, 0x9e, 0x0e, 0x98,
- 0x92, 0x3f, 0x39, 0x08, 0x59, 0x23, 0x26, 0x6b, 0x80, 0xac, 0xc5, 0x94,
- 0xad, 0x37, 0x6c, 0xd6, 0xc7, 0xbb, 0xd3, 0xbf, 0x17, 0xf4, 0xda, 0xb0,
- 0x9e, 0xdf, 0xc6, 0x1f, 0xbb, 0x6d, 0xa5, 0xed, 0xa8, 0x63, 0x48, 0x50,
- 0x8d, 0x8f, 0xb2, 0xd3, 0xab, 0xc7, 0x37, 0xda, 0xfd, 0xf1, 0x1f, 0xd1,
- 0x7d, 0xb5, 0xd5, 0xf5, 0x15, 0xbb, 0xce, 0xf8, 0x78, 0x77, 0xfa, 0xa3,
- 0x9b, 0xbd, 0x36, 0xb1, 0xba, 0x36, 0xed, 0x6b, 0xda, 0xb0, 0xbe, 0x3f,
- 0x06, 0xde, 0x9d, 0xbe, 0xab, 0xd9, 0x6b, 0xc3, 0x7a, 0x0d, 0xf0, 0x6d,
- 0x7c, 0x47, 0xd9, 0xdf, 0x5f, 0x27, 0xfb, 0xfb, 0x21, 0xfb, 0xbe, 0x4c,
- 0xad, 0xc5, 0xc9, 0x7e, 0xbc, 0xc3, 0x38, 0x87, 0xd8, 0xaa, 0x16, 0xd7,
- 0x84, 0x4e, 0x34, 0x03, 0xb7, 0xb4, 0x30, 0x96, 0xd1, 0xb8, 0x98, 0xb1,
- 0x0d, 0x71, 0xb0, 0xd8, 0x21, 0xe9, 0x82, 0x8d, 0xea, 0x8a, 0xef, 0xa3,
- 0xc2, 0x55, 0x62, 0x0a, 0x2f, 0x67, 0xf4, 0x18, 0x8c, 0x6b, 0xc8, 0x77,
- 0xe6, 0x73, 0x2b, 0x71, 0x4e, 0x07, 0xe2, 0x20, 0xe2, 0x5d, 0xe2, 0x25,
- 0x9f, 0x7e, 0x9f, 0x9e, 0x03, 0x46, 0x4d, 0x27, 0x32, 0xc6, 0x60, 0x75,
- 0xd0, 0xf0, 0x74, 0x82, 0xef, 0x0f, 0x68, 0x9f, 0xb6, 0x96, 0xde, 0xb7,
- 0xaf, 0xa1, 0x97, 0xb8, 0x2a, 0x21, 0x13, 0x90, 0x91, 0xd0, 0x09, 0xda,
- 0xd8, 0xe7, 0x46, 0x16, 0x67, 0x89, 0x1f, 0xfa, 0xc0, 0x17, 0xd2, 0x4b,
- 0xfe, 0x51, 0x97, 0x5b, 0x60, 0x1f, 0xba, 0x52, 0x65, 0xd4, 0x67, 0x7c,
- 0x3d, 0xae, 0xe2, 0xb2, 0x66, 0xa4, 0x08, 0x9e, 0x40, 0xeb, 0x38, 0x68,
- 0x1d, 0xd7, 0x31, 0xd9, 0x3e, 0xd8, 0xef, 0xd0, 0xb4, 0x4f, 0xeb, 0x8d,
- 0x21, 0x7f, 0x6d, 0x56, 0xd3, 0x5e, 0xef, 0x77, 0x3c, 0xfc, 0x75, 0x4f,
- 0x0f, 0x65, 0xc6, 0x2a, 0x10, 0xb3, 0x8d, 0x2b, 0xf9, 0x00, 0xf6, 0x33,
- 0xc4, 0xd3, 0xa5, 0x16, 0xdf, 0xff, 0x72, 0x3e, 0xf4, 0xff, 0xd4, 0x79,
- 0x7f, 0x0e, 0xcd, 0xd2, 0x79, 0x82, 0x73, 0x58, 0xa1, 0x3f, 0xc6, 0xdd,
- 0x8d, 0xfd, 0xb0, 0x9b, 0x79, 0x45, 0xeb, 0x4e, 0xd9, 0x5b, 0x7a, 0xa7,
- 0xa6, 0xbf, 0x19, 0xf4, 0x8f, 0x42, 0xb6, 0x6b, 0x36, 0x23, 0x5f, 0x19,
- 0x43, 0xde, 0xc3, 0x62, 0xe4, 0x71, 0xbe, 0x42, 0xfb, 0xa1, 0xe7, 0x13,
- 0xe5, 0x7c, 0xd6, 0xda, 0x96, 0xf5, 0xf8, 0xfa, 0x8e, 0x35, 0x7c, 0x15,
- 0xcd, 0xd7, 0x88, 0x34, 0x9c, 0x50, 0x71, 0x2d, 0xfa, 0x25, 0xaf, 0xe9,
- 0xbf, 0x9e, 0x1b, 0x99, 0x9c, 0x95, 0xbe, 0xb0, 0x90, 0xbe, 0x38, 0xcb,
- 0xfa, 0x1b, 0xa4, 0xcb, 0xb9, 0x88, 0x79, 0xe7, 0xb1, 0xde, 0xc6, 0xb4,
- 0x27, 0xdf, 0xe4, 0x6f, 0xbe, 0x12, 0x45, 0x2c, 0xcd, 0xb1, 0xc9, 0x33,
- 0xd2, 0x6f, 0x2a, 0x7a, 0x56, 0xf8, 0x0d, 0xfa, 0x3e, 0x56, 0x59, 0xcb,
- 0xdb, 0x7a, 0x3b, 0xe3, 0xc7, 0xec, 0xdf, 0x35, 0x3d, 0xbd, 0x58, 0x2f,
- 0x66, 0x6f, 0x86, 0x7d, 0x0c, 0xd1, 0x36, 0x82, 0xf7, 0xdc, 0x5f, 0x59,
- 0x0a, 0x11, 0x83, 0x5f, 0x28, 0x85, 0x95, 0xcd, 0xcb, 0x3a, 0x2d, 0x5a,
- 0x3f, 0x6e, 0xd3, 0xbe, 0x23, 0xac, 0x6c, 0xb6, 0x18, 0x26, 0x71, 0x09,
- 0xca, 0x90, 0x9f, 0x67, 0xde, 0xa7, 0xe3, 0xde, 0x5d, 0x61, 0xfb, 0x0f,
- 0x43, 0xbe, 0x4d, 0xa8, 0xd1, 0x55, 0x1f, 0x93, 0xbb, 0xc0, 0x72, 0xef,
- 0x84, 0xdc, 0xde, 0x89, 0xb8, 0x3b, 0x21, 0xf9, 0x14, 0xf5, 0x68, 0x40,
- 0xc5, 0x26, 0x86, 0xbd, 0x0f, 0x65, 0x4d, 0x28, 0x83, 0x13, 0x33, 0x31,
- 0x7f, 0xfb, 0x77, 0x65, 0x1c, 0x32, 0x9e, 0x4f, 0xf5, 0x82, 0x0e, 0xda,
- 0x60, 0x60, 0x1c, 0x3b, 0xc5, 0xb8, 0x1d, 0x7f, 0xfd, 0x61, 0x6f, 0x5e,
- 0xbb, 0x90, 0x47, 0x0c, 0x9f, 0xea, 0xd4, 0x75, 0x36, 0x08, 0xf7, 0x7f,
- 0xf2, 0x66, 0x0b, 0xd2, 0xee, 0x35, 0x75, 0xdf, 0x8f, 0xfc, 0x7b, 0x75,
- 0xff, 0x05, 0xbc, 0xdf, 0x86, 0xdf, 0x20, 0xca, 0x6e, 0x47, 0x99, 0x83,
- 0xb2, 0xf7, 0x20, 0xff, 0x7e, 0xbd, 0x1f, 0xe0, 0xb7, 0x69, 0x41, 0xfe,
- 0x31, 0xbc, 0x87, 0xad, 0x30, 0x5f, 0xc6, 0xfb, 0xf7, 0xe2, 0xf7, 0xee,
- 0x35, 0x75, 0xda, 0xd6, 0xe4, 0x3f, 0xb5, 0xc2, 0x83, 0x0b, 0xa5, 0x9f,
- 0x69, 0xbb, 0x46, 0x79, 0x66, 0xfe, 0x94, 0x7e, 0xf7, 0xce, 0xd0, 0xea,
- 0xf2, 0x1d, 0x7e, 0xbe, 0x6e, 0x0d, 0x3b, 0xb1, 0x86, 0x3e, 0xc6, 0x7c,
- 0xbb, 0xf6, 0x5d, 0x6f, 0xf7, 0xe2, 0xf4, 0x92, 0xdf, 0x8e, 0x7e, 0xed,
- 0xce, 0x35, 0x63, 0x3c, 0xdf, 0x50, 0xcb, 0x37, 0x07, 0x86, 0x4e, 0xb2,
- 0xec, 0x72, 0xc3, 0xea, 0x3a, 0x6f, 0xd6, 0xe5, 0x37, 0x06, 0x86, 0x94,
- 0x8f, 0xbb, 0xab, 0x71, 0x75, 0x9d, 0x64, 0x63, 0x6d, 0x1e, 0x35, 0x5b,
- 0x18, 0x4a, 0x2f, 0x53, 0x8e, 0xa1, 0x0b, 0xdf, 0x1a, 0xc9, 0x4e, 0xb9,
- 0xee, 0x84, 0xb3, 0x14, 0x0f, 0x0a, 0x7d, 0x10, 0xb1, 0x2a, 0xcb, 0x5f,
- 0x46, 0x39, 0xb0, 0x4c, 0x75, 0x54, 0x68, 0x93, 0xd6, 0xc7, 0xa4, 0x09,
- 0x8d, 0x49, 0x55, 0x36, 0x94, 0x55, 0x18, 0xf2, 0xf9, 0x11, 0x60, 0x1e,
- 0xfd, 0xfc, 0x02, 0x9e, 0x13, 0xf5, 0xb8, 0x17, 0xfd, 0x2e, 0x8d, 0x64,
- 0x67, 0xe9, 0xf3, 0x2e, 0x8e, 0xec, 0x99, 0xa5, 0xce, 0x5f, 0x82, 0xce,
- 0x07, 0x64, 0x52, 0xf9, 0x3f, 0xd2, 0xc1, 0x76, 0x4b, 0x23, 0x9d, 0x0b,
- 0x4c, 0x97, 0x47, 0xec, 0x85, 0xa0, 0xec, 0x8b, 0x79, 0x6d, 0x99, 0x4f,
- 0x2c, 0xf8, 0x3a, 0x10, 0x95, 0x70, 0x9a, 0x32, 0x69, 0xa5, 0x80, 0xbd,
- 0x31, 0x9f, 0x27, 0x47, 0x26, 0x6d, 0xca, 0xe7, 0x87, 0x1a, 0xa4, 0x25,
- 0x2a, 0x0d, 0xca, 0xde, 0x3c, 0xa5, 0xc7, 0xba, 0x84, 0xb1, 0x36, 0x29,
- 0x7d, 0xca, 0xda, 0xa1, 0x38, 0xc6, 0x39, 0x68, 0xd8, 0xbd, 0x18, 0x8f,
- 0x91, 0x72, 0x87, 0x4c, 0x54, 0xa9, 0x37, 0xdb, 0xc2, 0xb5, 0xf8, 0xf8,
- 0x3c, 0xda, 0xf9, 0x71, 0x19, 0xc7, 0x2b, 0x03, 0x97, 0x41, 0x96, 0xd3,
- 0x96, 0x99, 0x0d, 0xc2, 0xcf, 0xcf, 0xfa, 0x75, 0x48, 0xd3, 0xd9, 0x91,
- 0xe4, 0x42, 0x12, 0x7d, 0x75, 0xd0, 0x86, 0xc1, 0x76, 0x05, 0xf1, 0x63,
- 0xdf, 0x6c, 0x07, 0x5f, 0x34, 0x40, 0x3f, 0x72, 0x1e, 0x7e, 0xa4, 0x43,
- 0x0e, 0x95, 0x54, 0x1f, 0x09, 0xf6, 0x51, 0xd4, 0x6d, 0x3b, 0x17, 0x1a,
- 0x10, 0xdb, 0x24, 0xcd, 0x17, 0xa5, 0xd6, 0x76, 0x48, 0xbc, 0x76, 0x5e,
- 0xdf, 0x3f, 0x77, 0x33, 0xb1, 0x7a, 0xdd, 0x8f, 0x4a, 0x10, 0x74, 0xe4,
- 0xd0, 0x07, 0xc7, 0xaf, 0xf5, 0xed, 0xf7, 0x97, 0x34, 0x97, 0xaf, 0xe9,
- 0x6b, 0x93, 0x8e, 0xb9, 0xac, 0x44, 0xee, 0xd7, 0x1a, 0x5b, 0xc5, 0x00,
- 0x90, 0x07, 0x09, 0xe5, 0x7a, 0x60, 0x17, 0xab, 0x03, 0x5a, 0x46, 0x5e,
- 0x40, 0x59, 0x7d, 0x6c, 0xe3, 0xc9, 0x57, 0x01, 0x98, 0xae, 0x08, 0x3d,
- 0x0f, 0xa6, 0x33, 0xad, 0xde, 0x5e, 0xd3, 0xf5, 0xe2, 0x19, 0xc8, 0x0d,
- 0xfa, 0x2c, 0xae, 0xb4, 0xe5, 0x9c, 0x5e, 0x18, 0xb9, 0x34, 0x15, 0xc7,
- 0x9c, 0x3c, 0xbf, 0xe0, 0xf1, 0x9a, 0x3e, 0x27, 0x20, 0x8b, 0x76, 0x02,
- 0x71, 0x33, 0x7d, 0x7c, 0x42, 0x5e, 0xb2, 0x7d, 0xff, 0x43, 0x5f, 0x84,
- 0xfa, 0x55, 0xd2, 0x46, 0xda, 0xcf, 0x63, 0x6e, 0xae, 0xcc, 0x38, 0x9e,
- 0x0c, 0xf6, 0xc0, 0x8f, 0x7c, 0x23, 0x64, 0x1d, 0x66, 0x7c, 0x75, 0x25,
- 0x54, 0x3f, 0x1f, 0x1f, 0x2b, 0x3c, 0xaf, 0xf7, 0x7e, 0xcf, 0x6b, 0x79,
- 0x59, 0x82, 0xbc, 0xf4, 0x26, 0x4c, 0xe9, 0x06, 0xed, 0xa8, 0xd3, 0xd7,
- 0x85, 0x38, 0x87, 0x31, 0x74, 0x1c, 0xf4, 0x98, 0xb0, 0x1d, 0x9b, 0x34,
- 0x66, 0xff, 0x77, 0x61, 0xfa, 0xb6, 0x56, 0xb5, 0xaf, 0x7c, 0x5e, 0xc9,
- 0xb3, 0x27, 0xdf, 0x41, 0xfd, 0xde, 0x97, 0xa9, 0x20, 0x21, 0x8d, 0xd4,
- 0xf6, 0x4f, 0x59, 0xff, 0x39, 0x5d, 0xff, 0x59, 0xd4, 0x0f, 0x60, 0x4e,
- 0xae, 0xbb, 0x57, 0xd1, 0xfb, 0x1c, 0xf8, 0x1e, 0x94, 0xe2, 0x8a, 0xcc,
- 0x3f, 0x07, 0x99, 0xa7, 0x7c, 0x9f, 0x87, 0xbe, 0x82, 0xf8, 0x7b, 0x29,
- 0xf7, 0x65, 0x19, 0x3c, 0x9d, 0x6b, 0xe0, 0x5e, 0x67, 0xc2, 0x60, 0xec,
- 0x49, 0x99, 0xec, 0x90, 0xc7, 0x4b, 0x49, 0x73, 0xa2, 0x6e, 0x2d, 0x77,
- 0xac, 0x5a, 0x4b, 0xca, 0x80, 0xaa, 0x9f, 0x62, 0xfd, 0x72, 0x9d, 0x0c,
- 0xcc, 0xcf, 0x5e, 0xaf, 0x1d, 0x65, 0x80, 0xed, 0xd6, 0xc3, 0xe9, 0xdc,
- 0x1b, 0x74, 0xdd, 0x45, 0x87, 0xfb, 0xb8, 0x8d, 0x52, 0x50, 0x32, 0x16,
- 0x90, 0xa2, 0x43, 0xbd, 0xca, 0x26, 0x42, 0x62, 0x01, 0x2b, 0x7d, 0x10,
- 0x74, 0x66, 0x52, 0x61, 0xf1, 0xf6, 0x12, 0xc6, 0xb1, 0x06, 0x4b, 0xa6,
- 0xeb, 0x5e, 0xb2, 0x45, 0xca, 0x88, 0x3d, 0x17, 0x91, 0x16, 0x2b, 0xd0,
- 0xd9, 0x68, 0x08, 0x36, 0xc0, 0x97, 0xf1, 0x88, 0xcc, 0xa1, 0xce, 0x3c,
- 0xde, 0x3d, 0x5e, 0xf1, 0x25, 0xc6, 0x75, 0x0d, 0xf0, 0x68, 0x8f, 0xfd,
- 0xff, 0xdc, 0x7c, 0xac, 0xbe, 0xae, 0x8f, 0x89, 0x89, 0x65, 0x89, 0x4d,
- 0x89, 0x29, 0xf9, 0x8e, 0x38, 0xf1, 0x20, 0x68, 0xa1, 0xce, 0xb6, 0x48,
- 0x24, 0x6d, 0xc5, 0x87, 0xc5, 0xf7, 0xfd, 0x97, 0x21, 0x4b, 0x05, 0xb7,
- 0xd1, 0xee, 0x90, 0x67, 0x20, 0x37, 0xe7, 0x57, 0x70, 0x4c, 0x02, 0x72,
- 0x44, 0x3f, 0xea, 0xca, 0x39, 0xc7, 0x4e, 0x7c, 0x0e, 0xe9, 0xb7, 0x9d,
- 0xdf, 0x22, 0xdf, 0x9e, 0x10, 0xe9, 0x43, 0x2c, 0x04, 0xbb, 0x3e, 0xe3,
- 0x63, 0xfb, 0x16, 0xc6, 0x64, 0x5a, 0x96, 0xae, 0xa0, 0x4f, 0xcb, 0x34,
- 0x00, 0x6a, 0xef, 0x42, 0x3d, 0x4f, 0x37, 0xfc, 0xb2, 0x83, 0xa8, 0x4b,
- 0x1a, 0x18, 0x2f, 0x7f, 0x07, 0x3a, 0xeb, 0xba, 0xf7, 0x39, 0x8b, 0x75,
- 0xb6, 0xe6, 0x39, 0xac, 0xbf, 0x92, 0xf3, 0xfe, 0x56, 0xe1, 0xfe, 0xaa,
- 0xf4, 0xb5, 0xa9, 0x78, 0x8e, 0xcf, 0x90, 0xf7, 0x7e, 0x62, 0xa1, 0x84,
- 0xc2, 0x9a, 0xc4, 0x0d, 0xe7, 0xc1, 0xfb, 0x4f, 0x2a, 0x4c, 0x43, 0xfc,
- 0x06, 0xfa, 0x4b, 0xc4, 0x14, 0x1e, 0x96, 0xf6, 0x70, 0x1d, 0xb1, 0x45,
- 0x0a, 0x6b, 0xe3, 0xe3, 0x0b, 0xb6, 0x65, 0x3d, 0xb6, 0xad, 0x5f, 0x3f,
- 0xd6, 0xd9, 0x14, 0xc8, 0x1d, 0xa3, 0x3c, 0xd3, 0x3f, 0xb6, 0xca, 0xbe,
- 0x54, 0x23, 0xf8, 0xde, 0xa6, 0xfd, 0xf8, 0xfb, 0x80, 0xd9, 0x80, 0xbd,
- 0x4d, 0xcb, 0xa9, 0xd9, 0x9e, 0xf7, 0xa0, 0xec, 0x17, 0xe0, 0x3f, 0xcb,
- 0xf6, 0x37, 0x78, 0x7e, 0xf2, 0x61, 0xe8, 0xf2, 0xdc, 0x26, 0x6f, 0xef,
- 0x8a, 0xeb, 0xe0, 0xe3, 0x04, 0x1f, 0xf7, 0x99, 0x1a, 0xef, 0x73, 0x6d,
- 0xbc, 0x7d, 0x2e, 0x43, 0xd5, 0x65, 0xac, 0x55, 0x1f, 0x5b, 0x52, 0x87,
- 0x5d, 0xf7, 0x9c, 0xe3, 0xe3, 0xc8, 0xed, 0xf0, 0xa1, 0x21, 0xcd, 0xeb,
- 0x66, 0xf0, 0x9a, 0x18, 0x25, 0x22, 0x89, 0x36, 0x62, 0x8a, 0x07, 0x1b,
- 0x6a, 0x58, 0xe6, 0x6f, 0xdc, 0xa0, 0xcd, 0x78, 0x8f, 0x38, 0x86, 0xb4,
- 0x6f, 0xd7, 0x78, 0x86, 0xd8, 0xe6, 0x31, 0x8c, 0x11, 0x94, 0x44, 0x3b,
- 0xf3, 0x7f, 0xa9, 0xdb, 0xf0, 0xd9, 0x95, 0xee, 0xad, 0xf5, 0xf2, 0x3c,
- 0x00, 0x3a, 0x39, 0x1f, 0x7f, 0xef, 0xb5, 0x43, 0xd9, 0x93, 0x9a, 0x5c,
- 0xf8, 0x34, 0xf9, 0xe3, 0x92, 0xb6, 0xb8, 0xb4, 0x81, 0xb6, 0x7b, 0xe0,
- 0x53, 0xb6, 0xb6, 0xb1, 0x4f, 0x7f, 0xec, 0x7a, 0x9a, 0xea, 0xf1, 0x55,
- 0x02, 0x63, 0x34, 0xca, 0xd6, 0x76, 0xf2, 0xae, 0x43, 0xf9, 0x96, 0xda,
- 0x7a, 0xd0, 0xf7, 0x73, 0xec, 0xb5, 0xe5, 0xef, 0xad, 0xa3, 0x6b, 0x2d,
- 0xe6, 0xdb, 0x86, 0x77, 0xa4, 0xc9, 0x84, 0x5d, 0x72, 0x65, 0x87, 0xe3,
- 0xe3, 0xbb, 0x7a, 0x3a, 0x88, 0xf1, 0x48, 0x33, 0x69, 0xf0, 0x31, 0x39,
- 0x7f, 0x5c, 0x1b, 0xd2, 0x93, 0xd6, 0xe7, 0x44, 0xfb, 0xf5, 0xbc, 0x6e,
- 0xd3, 0x75, 0x92, 0x68, 0xfb, 0xc7, 0x98, 0x03, 0x9f, 0x39, 0x0f, 0x1f,
- 0x1b, 0x26, 0xbd, 0x7e, 0xa2, 0xeb, 0xc5, 0x00, 0xd4, 0x19, 0x9f, 0x4f,
- 0x6d, 0x7a, 0x8d, 0xb6, 0xaf, 0x19, 0xd7, 0x72, 0x56, 0xdb, 0x91, 0xf7,
- 0xd4, 0xcd, 0xaf, 0x4f, 0x0a, 0xf3, 0x94, 0x8b, 0x77, 0x21, 0xf5, 0x63,
- 0xa3, 0x7e, 0xf8, 0x91, 0x0c, 0x62, 0x21, 0xc6, 0x48, 0xd7, 0xc4, 0x47,
- 0x3c, 0x47, 0x1c, 0xcb, 0x23, 0x5e, 0x56, 0x7e, 0xc4, 0xf3, 0x91, 0xc8,
- 0xc3, 0x9e, 0x54, 0xef, 0xa5, 0x8c, 0x8d, 0x8d, 0x57, 0x9c, 0xb1, 0xbd,
- 0x95, 0xfe, 0x31, 0xc6, 0x11, 0x9e, 0xcc, 0xa1, 0x7e, 0x45, 0xc6, 0x0d,
- 0xb4, 0xcb, 0xaa, 0x76, 0x6a, 0x1f, 0x68, 0x9d, 0x7e, 0x84, 0xfa, 0x38,
- 0xee, 0x8d, 0x15, 0x19, 0xcb, 0xc1, 0x06, 0xcd, 0xcf, 0xc0, 0xc7, 0xd9,
- 0x56, 0x86, 0x72, 0xb9, 0xc7, 0xb1, 0x86, 0x95, 0xec, 0xc5, 0xac, 0x51,
- 0xae, 0x65, 0x79, 0xe6, 0x1d, 0xb0, 0xa1, 0xae, 0xdc, 0x0d, 0x5b, 0xf8,
- 0x10, 0x64, 0x55, 0xce, 0xc0, 0x10, 0x9e, 0x81, 0xf1, 0x3a, 0x13, 0x13,
- 0xe3, 0x78, 0x87, 0x84, 0x8f, 0xc4, 0x25, 0x74, 0x84, 0xb1, 0x58, 0xd2,
- 0xbc, 0x5b, 0x04, 0x3e, 0xf1, 0xc5, 0xdb, 0x0d, 0xb1, 0x06, 0x32, 0x92,
- 0x44, 0x3c, 0xd9, 0x6b, 0x96, 0x91, 0x16, 0x25, 0x99, 0x3a, 0x8d, 0xbe,
- 0xc2, 0x67, 0x50, 0x17, 0xed, 0x9a, 0x16, 0x13, 0xf8, 0xb5, 0x4b, 0x74,
- 0xd1, 0xd3, 0x95, 0xe8, 0xe2, 0xea, 0x3d, 0x94, 0xc1, 0x95, 0x3d, 0x14,
- 0xbe, 0x7f, 0x43, 0xef, 0xfd, 0x3c, 0xab, 0xe3, 0x1a, 0xca, 0x08, 0x7d,
- 0x9b, 0x8a, 0xcd, 0x60, 0xc7, 0x9f, 0x45, 0x2c, 0x6c, 0x4b, 0xae, 0x04,
- 0xcc, 0x9e, 0x76, 0xe5, 0x29, 0xa7, 0xe0, 0x66, 0xfb, 0x5d, 0xb9, 0xec,
- 0xd8, 0x85, 0xbc, 0x58, 0x6f, 0xd0, 0xde, 0xfd, 0x4f, 0xe7, 0xfd, 0xb2,
- 0xab, 0xd5, 0xda, 0x95, 0x09, 0x14, 0xdc, 0x66, 0x3b, 0x2a, 0x37, 0xa5,
- 0x0f, 0xca, 0x9e, 0x2d, 0x4b, 0x66, 0x50, 0x32, 0x37, 0x01, 0x17, 0xc6,
- 0xf3, 0xca, 0x56, 0xbd, 0xa6, 0xe2, 0xeb, 0x07, 0xba, 0x0e, 0xca, 0xc6,
- 0x2d, 0x96, 0x79, 0x35, 0x48, 0xcc, 0x76, 0x10, 0xb1, 0x80, 0x15, 0xcf,
- 0x05, 0x6d, 0x73, 0xa7, 0x58, 0xc3, 0x9f, 0x16, 0x9e, 0xdb, 0xda, 0xd2,
- 0x79, 0xc4, 0x8e, 0x7f, 0x22, 0xd0, 0xbd, 0xff, 0x13, 0x8c, 0xef, 0xce,
- 0x30, 0xef, 0x4a, 0x64, 0x8b, 0x89, 0xe7, 0x98, 0x74, 0x1e, 0x4f, 0x48,
- 0x12, 0x7c, 0xe9, 0x51, 0x3c, 0xe1, 0xf9, 0x51, 0x5c, 0xba, 0x8f, 0x10,
- 0x43, 0x29, 0xde, 0xf4, 0x80, 0x37, 0x29, 0xf0, 0x06, 0x31, 0x55, 0xaf,
- 0x79, 0x15, 0xe9, 0xb2, 0x24, 0x07, 0x7e, 0x00, 0xde, 0xf4, 0x80, 0x37,
- 0xdd, 0x67, 0x12, 0x68, 0x8f, 0x3e, 0x16, 0x3b, 0x91, 0x46, 0xe5, 0x83,
- 0x37, 0xb4, 0xe3, 0xd9, 0x96, 0xe4, 0x91, 0x08, 0xc6, 0x08, 0xc8, 0x8e,
- 0xae, 0x82, 0x0c, 0x6d, 0x41, 0x6c, 0x16, 0x3b, 0x28, 0x17, 0xe1, 0x87,
- 0x4a, 0x88, 0x11, 0x9e, 0x1a, 0xb0, 0x46, 0x97, 0x60, 0x4b, 0xab, 0xf7,
- 0xb8, 0xf2, 0xf2, 0x96, 0xbf, 0x70, 0xe3, 0x37, 0x58, 0xbb, 0x24, 0xd0,
- 0x2f, 0x93, 0x25, 0xe5, 0x1f, 0xe2, 0xd9, 0xa0, 0xc2, 0x65, 0x98, 0x63,
- 0x01, 0x3e, 0x86, 0xe7, 0xd1, 0x36, 0x6c, 0xfd, 0xa7, 0xe5, 0xa1, 0xb9,
- 0x09, 0xfc, 0x10, 0x6f, 0x4e, 0xb1, 0xee, 0x7e, 0xc4, 0x73, 0x0f, 0xcb,
- 0xbe, 0x29, 0x60, 0xc7, 0x34, 0xe8, 0xee, 0xb7, 0x11, 0xcf, 0xcd, 0x37,
- 0x4a, 0x0b, 0xca, 0xc0, 0xdb, 0xd1, 0xea, 0xda, 0x38, 0x6e, 0x09, 0xeb,
- 0x30, 0x20, 0x7f, 0x56, 0xed, 0x97, 0xaf, 0x55, 0xfb, 0xe4, 0x4f, 0xe0,
- 0x5b, 0xce, 0x57, 0x3b, 0xa0, 0x2b, 0x71, 0xac, 0x49, 0x1a, 0xeb, 0xe3,
- 0xc8, 0x73, 0xd5, 0x94, 0x3c, 0x0b, 0x5e, 0x3d, 0x83, 0xdf, 0x50, 0x29,
- 0x25, 0x3b, 0x4a, 0x7d, 0x7a, 0x8d, 0xb8, 0x3e, 0x36, 0xe8, 0xb1, 0x31,
- 0x77, 0xeb, 0xc9, 0x02, 0xf4, 0x6f, 0xbe, 0x6a, 0xbf, 0x5e, 0x96, 0x8f,
- 0x37, 0x72, 0x8f, 0xf7, 0xd4, 0x8a, 0x7f, 0x29, 0xb8, 0xa6, 0x6d, 0x1d,
- 0x1e, 0xc7, 0x3a, 0x94, 0xa1, 0xa7, 0xa3, 0x8a, 0xf7, 0x35, 0xdf, 0x53,
- 0xf6, 0x7c, 0x8f, 0x3f, 0xbf, 0x99, 0xbc, 0x7c, 0x5b, 0xb2, 0x47, 0x27,
- 0x65, 0xcf, 0x31, 0x57, 0x3e, 0xec, 0xb8, 0x90, 0x63, 0xda, 0xe2, 0x7e,
- 0xda, 0xf8, 0xc4, 0x78, 0xd0, 0x50, 0xb1, 0x94, 0x87, 0x5b, 0x7a, 0x37,
- 0x43, 0x67, 0x53, 0x19, 0x63, 0x42, 0x92, 0x47, 0x27, 0xa4, 0xf3, 0x28,
- 0x64, 0xc1, 0x61, 0x5f, 0x4b, 0xa6, 0x71, 0x8d, 0x3c, 0x70, 0x1c, 0x6b,
- 0x20, 0x27, 0xb6, 0xf9, 0xba, 0xa4, 0x30, 0xfe, 0x01, 0xe9, 0x42, 0x1b,
- 0x1b, 0x6d, 0xae, 0xaa, 0xb1, 0x9b, 0x31, 0x76, 0xa3, 0x1c, 0x8a, 0x59,
- 0x90, 0x35, 0xfa, 0xf0, 0xff, 0x25, 0xd9, 0x32, 0xd3, 0x9f, 0x4a, 0xf6,
- 0xd4, 0x47, 0x23, 0x12, 0xe5, 0x33, 0x4c, 0xc3, 0x09, 0x96, 0x77, 0x22,
- 0x65, 0xb9, 0x8d, 0x38, 0xfa, 0xe7, 0x92, 0x3d, 0xcb, 0xb1, 0x5f, 0x47,
- 0xf9, 0xcb, 0x92, 0x9d, 0xfe, 0x05, 0xf2, 0x17, 0x91, 0xbe, 0x81, 0x74,
- 0x54, 0x3a, 0xa7, 0x25, 0x90, 0x3d, 0xfb, 0x2d, 0xe4, 0x43, 0x48, 0x0f,
- 0xa1, 0xde, 0x76, 0xd0, 0xf7, 0xa7, 0xe8, 0x2f, 0x03, 0x9b, 0xf7, 0x3b,
- 0x9a, 0x7e, 0x96, 0xb3, 0x8c, 0xef, 0x0e, 0xc1, 0xa6, 0xfd, 0x67, 0xd8,
- 0x34, 0xfd, 0x3c, 0xcf, 0x3c, 0x6d, 0x1b, 0x9f, 0x27, 0xc0, 0x93, 0x03,
- 0xc8, 0xbb, 0xf2, 0xb0, 0x43, 0x7f, 0xb3, 0x4d, 0xc6, 0xcc, 0x82, 0x1b,
- 0x05, 0xae, 0x68, 0x86, 0x1e, 0x4c, 0x6c, 0x5d, 0x5f, 0x0f, 0x0e, 0x77,
- 0x1f, 0x94, 0xa6, 0x2d, 0xfe, 0xfc, 0xfd, 0xf9, 0xda, 0xe6, 0x4f, 0x14,
- 0x1f, 0xac, 0xc2, 0x27, 0x84, 0xf3, 0xb0, 0xe3, 0x5f, 0x30, 0xba, 0x77,
- 0x3d, 0x04, 0x3d, 0x30, 0xce, 0x32, 0xef, 0xe9, 0x81, 0x71, 0x16, 0xb6,
- 0xe1, 0x04, 0x62, 0xc4, 0x13, 0x1d, 0xd2, 0x38, 0x5d, 0xd3, 0x83, 0x86,
- 0xe9, 0x5f, 0xad, 0x07, 0x8d, 0x67, 0x51, 0xef, 0x2c, 0x79, 0x86, 0x3e,
- 0x4e, 0x91, 0x67, 0xed, 0x48, 0x3f, 0x8d, 0xb9, 0x92, 0xf6, 0x46, 0xd0,
- 0xee, 0xe1, 0xa2, 0xdb, 0x21, 0xef, 0x0f, 0x6c, 0x39, 0xa0, 0xcb, 0xff,
- 0xd2, 0x1d, 0x8e, 0x59, 0x73, 0x12, 0x20, 0x4f, 0x51, 0xb7, 0x4c, 0x1e,
- 0xde, 0xdc, 0x24, 0xd1, 0xfd, 0xd2, 0x49, 0xfe, 0x95, 0x77, 0x22, 0x5f,
- 0x70, 0xc3, 0x76, 0xb3, 0xe6, 0x27, 0x70, 0x52, 0x3f, 0xcb, 0x5f, 0x85,
- 0xcc, 0x10, 0xaf, 0xbe, 0x26, 0x7b, 0xa6, 0x5c, 0x19, 0x73, 0x38, 0xff,
- 0xef, 0x63, 0xfe, 0x99, 0x2d, 0x31, 0x59, 0x4a, 0xc4, 0xc0, 0x93, 0x79,
- 0xd8, 0xf6, 0x8b, 0xe2, 0xf1, 0x81, 0xe7, 0x02, 0x3b, 0xc4, 0x8e, 0x0f,
- 0x89, 0x9d, 0xfa, 0x01, 0xf8, 0x30, 0x04, 0xd9, 0xcf, 0x55, 0x29, 0x3b,
- 0xaf, 0xc8, 0x20, 0x64, 0xe2, 0x7b, 0x8e, 0x95, 0x02, 0x16, 0x82, 0xbd,
- 0xa0, 0x5c, 0x50, 0x26, 0x5a, 0x94, 0x4d, 0x3a, 0xe1, 0x58, 0x4f, 0x94,
- 0xe5, 0x56, 0x39, 0xd1, 0x46, 0xda, 0xf1, 0x6e, 0x5a, 0xf9, 0x8b, 0xd4,
- 0xb8, 0xd1, 0x05, 0x1b, 0x9d, 0x12, 0xb3, 0xbb, 0xd8, 0xe8, 0xdf, 0x21,
- 0xc9, 0x1f, 0x0d, 0xc8, 0x44, 0x37, 0xd7, 0x8a, 0xfd, 0x22, 0x5f, 0x2e,
- 0xb8, 0x21, 0xfb, 0x75, 0xf7, 0x64, 0x7b, 0x42, 0x3e, 0xd9, 0xbd, 0x22,
- 0x97, 0x73, 0x22, 0x9e, 0x5e, 0x0c, 0xaa, 0xf5, 0xf0, 0xe9, 0xf6, 0xe7,
- 0xe2, 0xbf, 0xeb, 0xab, 0x7b, 0xc7, 0xb9, 0x50, 0xd6, 0x57, 0x74, 0x27,
- 0x71, 0x2d, 0xad, 0xaf, 0x41, 0x9e, 0xac, 0x27, 0x8a, 0x72, 0x19, 0xb2,
- 0x07, 0x1e, 0x9e, 0x65, 0x4a, 0x1e, 0x4e, 0x40, 0xee, 0x5f, 0x95, 0x1d,
- 0x47, 0xa9, 0x33, 0xaf, 0x62, 0xae, 0xca, 0x96, 0xc0, 0x46, 0xb0, 0x3f,
- 0x57, 0x26, 0x9d, 0xae, 0xd4, 0x29, 0xb9, 0x35, 0xbe, 0x17, 0x31, 0xe7,
- 0xb8, 0xe9, 0xca, 0xa2, 0x53, 0x90, 0xc5, 0x01, 0xb4, 0x29, 0x7f, 0x1a,
- 0xbf, 0x4f, 0xe9, 0xb9, 0x3d, 0x0a, 0xbe, 0x5b, 0x89, 0x39, 0xe3, 0xf7,
- 0xc1, 0xf7, 0x87, 0x25, 0x39, 0xbd, 0x62, 0x6b, 0x20, 0x77, 0x9e, 0xad,
- 0x49, 0x9e, 0x35, 0xa5, 0x5c, 0xb2, 0xe5, 0x23, 0xb4, 0x21, 0x25, 0xce,
- 0x0b, 0x36, 0x86, 0x67, 0xec, 0x25, 0xd8, 0x99, 0x12, 0x6c, 0x0a, 0x6c,
- 0xc8, 0x9f, 0xa0, 0xfc, 0x59, 0xd4, 0x79, 0x06, 0xf1, 0xd3, 0x79, 0x60,
- 0xbf, 0x73, 0xc0, 0x14, 0x4f, 0x97, 0x32, 0x3a, 0x96, 0x55, 0xf3, 0x85,
- 0xcf, 0x52, 0xb1, 0x8f, 0x94, 0xe7, 0xd4, 0x7d, 0x1e, 0xb5, 0xb6, 0x59,
- 0x67, 0x13, 0x71, 0x16, 0x28, 0x13, 0x99, 0x9b, 0xf3, 0x79, 0x42, 0xdb,
- 0xc7, 0xf3, 0x19, 0xdf, 0x56, 0x36, 0xaf, 0xb1, 0x95, 0x22, 0x2f, 0x56,
- 0x3c, 0x3c, 0x49, 0x7c, 0x5c, 0x9c, 0x4a, 0xac, 0x9c, 0x63, 0x16, 0xe1,
- 0x37, 0x97, 0x11, 0x67, 0x44, 0xd2, 0xdf, 0x94, 0xc8, 0x71, 0xd7, 0xfd,
- 0x21, 0xfc, 0x66, 0x01, 0x6b, 0x62, 0x04, 0x50, 0xbe, 0xc0, 0x77, 0x94,
- 0x7b, 0xca, 0x76, 0x80, 0xe7, 0x19, 0xf2, 0x12, 0xca, 0xca, 0x2a, 0xfe,
- 0xfa, 0x16, 0xe8, 0xd1, 0xf4, 0xa9, 0x32, 0xd6, 0x6b, 0x94, 0xdc, 0x58,
- 0x0a, 0x31, 0x4e, 0xaf, 0xd9, 0x88, 0xf6, 0x73, 0x0b, 0x6c, 0x63, 0x0d,
- 0xf0, 0x3a, 0xd5, 0x4b, 0x0b, 0x2c, 0xef, 0x90, 0x8b, 0x88, 0x45, 0x49,
- 0x43, 0x79, 0x36, 0x2d, 0xde, 0xde, 0x31, 0xed, 0x15, 0x69, 0x45, 0x1e,
- 0xfc, 0xca, 0x96, 0xe8, 0x67, 0x43, 0x52, 0x88, 0x93, 0xd7, 0x71, 0x59,
- 0x9e, 0xfa, 0x4c, 0x13, 0xf7, 0x66, 0xb3, 0x36, 0x9f, 0xfd, 0xbd, 0x0e,
- 0xf3, 0x2d, 0xec, 0x75, 0x70, 0x7f, 0x23, 0x04, 0x5f, 0xa6, 0xf6, 0x3c,
- 0x90, 0x26, 0xea, 0xe2, 0x5f, 0xbe, 0xf7, 0xb0, 0x51, 0x0d, 0x3f, 0x12,
- 0x4f, 0x72, 0xbe, 0x56, 0x61, 0x09, 0xf6, 0xa3, 0x2d, 0x7d, 0x49, 0xee,
- 0x3d, 0xe1, 0xcd, 0xcf, 0x38, 0x25, 0xbc, 0x4b, 0x23, 0x57, 0x67, 0x2d,
- 0xe7, 0x0a, 0x30, 0x45, 0x2e, 0xe6, 0x60, 0xbd, 0x46, 0x9b, 0x60, 0xbf,
- 0x06, 0x32, 0xc6, 0x99, 0x26, 0x0f, 0x9f, 0x85, 0x64, 0x62, 0x8a, 0xe7,
- 0x9e, 0xb0, 0x6d, 0xc0, 0x90, 0xbf, 0x1b, 0xc2, 0x73, 0x85, 0x79, 0xc4,
- 0xa4, 0x5e, 0x3c, 0x8b, 0x67, 0xaf, 0x3f, 0xf2, 0xdc, 0x38, 0xc1, 0xb9,
- 0x07, 0xe4, 0x5e, 0xa0, 0x13, 0x41, 0xff, 0x9d, 0x7a, 0xac, 0xce, 0x53,
- 0x29, 0xee, 0x65, 0x4b, 0x12, 0xf6, 0x22, 0x8b, 0x58, 0x32, 0x17, 0xeb,
- 0xd0, 0xd8, 0x9c, 0xef, 0xd6, 0x62, 0x4f, 0x3f, 0xc6, 0x4b, 0xc9, 0xe7,
- 0x4b, 0x3e, 0xd6, 0x4b, 0xc1, 0xc7, 0x4a, 0x68, 0xb8, 0xc7, 0x95, 0x1f,
- 0x3a, 0xe4, 0x57, 0x1f, 0xf2, 0x8e, 0x1c, 0xae, 0xfe, 0xb2, 0xf3, 0xcd,
- 0xfa, 0xbf, 0x66, 0xd0, 0xc8, 0x1f, 0xe8, 0x03, 0x3e, 0x22, 0xed, 0x06,
- 0xfc, 0x79, 0x11, 0xb8, 0xcb, 0x38, 0xd3, 0xa1, 0xde, 0x19, 0xc0, 0x06,
- 0xe5, 0x29, 0xd8, 0xc6, 0x33, 0x3c, 0xf3, 0x85, 0x6d, 0x3b, 0x13, 0x96,
- 0xe2, 0x0c, 0xe5, 0x52, 0xda, 0x0c, 0xac, 0x17, 0xeb, 0x97, 0xa7, 0x3a,
- 0x90, 0x36, 0x23, 0x4d, 0xa8, 0x7e, 0xca, 0x53, 0xb6, 0x6a, 0x5f, 0x9e,
- 0x4a, 0xa9, 0x76, 0xe5, 0xa9, 0x3e, 0xa4, 0x8e, 0x34, 0x9c, 0x41, 0xe0,
- 0x74, 0xa6, 0x5b, 0x26, 0x4e, 0xc2, 0xbf, 0xf4, 0x1b, 0xea, 0xbe, 0xc4,
- 0x38, 0xfc, 0x4f, 0x08, 0x51, 0xd6, 0x15, 0x73, 0x00, 0x18, 0x6b, 0x1b,
- 0x30, 0xc8, 0x36, 0xb1, 0x8f, 0x73, 0xfe, 0xb4, 0xbd, 0xcb, 0xdc, 0xff,
- 0x8a, 0x3f, 0x28, 0x19, 0xd9, 0x37, 0xd3, 0x08, 0x7d, 0x0d, 0x99, 0x45,
- 0xe9, 0x32, 0x87, 0x90, 0xcf, 0xcf, 0x91, 0x6f, 0xf7, 0xab, 0xd8, 0x2d,
- 0xeb, 0xc4, 0xa2, 0x12, 0x4d, 0x63, 0x8c, 0xb7, 0xd2, 0xbe, 0x07, 0xf2,
- 0x67, 0xeb, 0x3e, 0xd2, 0xa0, 0xa7, 0x9e, 0x1f, 0x3c, 0xeb, 0xcd, 0xfc,
- 0x8a, 0xb3, 0x5e, 0xca, 0x35, 0xf9, 0x7b, 0xbf, 0x2c, 0xdb, 0x69, 0x79,
- 0xc9, 0x4e, 0xc9, 0x45, 0x7b, 0xab, 0xfc, 0x39, 0xfc, 0xf4, 0x25, 0x7b,
- 0xba, 0x89, 0x58, 0xa0, 0xac, 0xce, 0xcf, 0xfc, 0xb5, 0xb2, 0xf5, 0x3e,
- 0xfa, 0x8f, 0x64, 0x71, 0x8a, 0xd8, 0xd9, 0xdd, 0xbe, 0xc7, 0x29, 0xd0,
- 0x6f, 0x81, 0x06, 0x62, 0xb5, 0x02, 0xfc, 0xdf, 0x41, 0x19, 0x72, 0xe8,
- 0xf7, 0x94, 0x8f, 0x8a, 0x0f, 0x79, 0xfa, 0xec, 0xe4, 0x61, 0x57, 0x97,
- 0x67, 0xa0, 0x4f, 0x42, 0xf9, 0xc7, 0xf3, 0x1c, 0xd7, 0xdd, 0x96, 0x2f,
- 0x94, 0x38, 0xcf, 0xe2, 0xe6, 0xa8, 0x04, 0x65, 0x58, 0xe1, 0x85, 0x16,
- 0x79, 0x71, 0x61, 0x83, 0x18, 0xf0, 0x50, 0xc6, 0x2d, 0x61, 0x75, 0xd3,
- 0x84, 0xf1, 0xb7, 0xb4, 0xf2, 0xbe, 0xd8, 0x87, 0xc1, 0x1b, 0xee, 0x05,
- 0x60, 0x6e, 0xad, 0x9c, 0x89, 0x9f, 0xef, 0x83, 0x7e, 0xf1, 0x39, 0x20,
- 0x39, 0x3b, 0x86, 0x67, 0xa6, 0xd4, 0x39, 0xee, 0x93, 0x05, 0xc5, 0xc3,
- 0xdc, 0xe3, 0xea, 0x7d, 0xa3, 0x7d, 0x07, 0x70, 0x1d, 0xe5, 0x15, 0xe9,
- 0xa2, 0x37, 0x6e, 0x0e, 0x38, 0x2e, 0xdf, 0xd7, 0xa4, 0xce, 0xff, 0x0a,
- 0xd0, 0x85, 0x71, 0x55, 0xbf, 0x5f, 0x2e, 0x4d, 0xed, 0x8f, 0x7a, 0xfa,
- 0x31, 0xa0, 0x9f, 0xf9, 0x9e, 0xf1, 0x15, 0xf7, 0x4b, 0x5e, 0x19, 0x99,
- 0xb4, 0xbf, 0xa1, 0xf5, 0x47, 0x02, 0x77, 0xf7, 0x00, 0x87, 0x1e, 0x69,
- 0xc0, 0x5c, 0xac, 0x44, 0x22, 0x60, 0xb4, 0x1b, 0xc0, 0xf1, 0x43, 0xca,
- 0xe7, 0xf6, 0xa8, 0xfd, 0xe8, 0x53, 0xa9, 0x16, 0x29, 0x9b, 0xb6, 0xba,
- 0x17, 0xb7, 0x64, 0x6e, 0x21, 0xd6, 0xc7, 0xaf, 0x09, 0x65, 0x5d, 0x48,
- 0x1b, 0x91, 0xbe, 0x4b, 0x8a, 0xc7, 0xa6, 0xf5, 0x78, 0xe1, 0x35, 0xf9,
- 0x3e, 0x9d, 0x7e, 0x44, 0xc7, 0x53, 0x1c, 0x27, 0x2c, 0xf6, 0x17, 0x9b,
- 0xa5, 0xeb, 0x88, 0x09, 0x6c, 0x1b, 0x07, 0xd6, 0xed, 0x90, 0xd4, 0x91,
- 0x84, 0xdc, 0x72, 0xc4, 0xdf, 0x73, 0xfa, 0x0f, 0x23, 0x49, 0xb5, 0xc7,
- 0xf9, 0xdd, 0x11, 0x7b, 0x8e, 0xe9, 0x6b, 0xfa, 0xfe, 0xde, 0x15, 0x7d,
- 0xaf, 0xef, 0x47, 0x23, 0x3d, 0x2a, 0xfd, 0x6f, 0x23, 0x29, 0x95, 0xbe,
- 0x3e, 0x72, 0x4b, 0xc5, 0x8b, 0x8f, 0x8a, 0xf3, 0x29, 0xf9, 0x5c, 0x89,
- 0xf8, 0xb2, 0x1f, 0xd8, 0xd1, 0x81, 0x9d, 0xe9, 0x83, 0x9d, 0x49, 0xc1,
- 0xce, 0x0c, 0xd0, 0xce, 0xc0, 0x6e, 0xbf, 0x02, 0xbb, 0xed, 0xc8, 0xf7,
- 0x20, 0xaf, 0x4f, 0x3b, 0x8d, 0xc0, 0x85, 0xae, 0xeb, 0xcd, 0xd5, 0x7a,
- 0x62, 0x09, 0xeb, 0x5b, 0x3e, 0x2d, 0x91, 0x56, 0xd8, 0xa0, 0x2d, 0x27,
- 0x1a, 0x64, 0x3e, 0xe6, 0xba, 0x47, 0x1d, 0x5b, 0xae, 0xa2, 0x7e, 0xd6,
- 0xa6, 0x1e, 0xbf, 0x14, 0x65, 0x3c, 0x76, 0x75, 0x6a, 0x2b, 0x6c, 0x12,
- 0xe5, 0x3d, 0x22, 0xe5, 0xb1, 0xb8, 0x2c, 0x20, 0x3e, 0xab, 0xd5, 0x49,
- 0xe1, 0x99, 0xfa, 0xff, 0x5d, 0xd4, 0x4d, 0xc1, 0x3f, 0x98, 0xb2, 0xd8,
- 0x93, 0x90, 0x53, 0x3d, 0xd6, 0x40, 0xc2, 0xa0, 0xed, 0x4a, 0xc8, 0x1c,
- 0x62, 0xfd, 0x72, 0x89, 0xf5, 0x59, 0x0f, 0xfa, 0x59, 0xf2, 0xda, 0x4d,
- 0x96, 0x7c, 0x3b, 0xd1, 0xcf, 0x7d, 0xc8, 0x50, 0xae, 0xc7, 0xf3, 0x01,
- 0x86, 0xd1, 0x08, 0x39, 0x70, 0xc0, 0xff, 0x31, 0x94, 0xf7, 0xf3, 0xbe,
- 0x07, 0xca, 0x88, 0x85, 0x7e, 0x1c, 0x25, 0x46, 0xcc, 0x39, 0x63, 0x28,
- 0x63, 0x1b, 0x2b, 0x9e, 0x44, 0xf9, 0xa8, 0x24, 0xe3, 0x79, 0x75, 0xf7,
- 0xac, 0x1d, 0x65, 0xec, 0x23, 0xa8, 0xf7, 0x63, 0xfe, 0x8f, 0x92, 0xa3,
- 0xa0, 0xed, 0x97, 0xf7, 0xaa, 0xbd, 0x81, 0x8c, 0xe9, 0x40, 0x1f, 0x58,
- 0x96, 0x34, 0xd9, 0x2e, 0xe7, 0x38, 0xca, 0x16, 0xde, 0x57, 0xe1, 0x19,
- 0x5e, 0x44, 0xee, 0xad, 0x34, 0x4b, 0xae, 0xd2, 0x70, 0x1d, 0xfb, 0xef,
- 0xeb, 0xe4, 0x72, 0xdc, 0x14, 0xde, 0x83, 0xf0, 0xf4, 0x3c, 0xb4, 0x95,
- 0x3a, 0x31, 0xc0, 0x73, 0x03, 0xf8, 0x5b, 0xac, 0x05, 0xfc, 0xef, 0x39,
- 0xf8, 0xdf, 0xa7, 0x4b, 0x35, 0xfb, 0xe1, 0xf9, 0x5d, 0xda, 0x80, 0x27,
- 0xb1, 0x66, 0xa3, 0xc0, 0xfd, 0x3b, 0x11, 0x0f, 0x0c, 0x03, 0xfb, 0x0f,
- 0x62, 0xfd, 0xd2, 0x58, 0xbb, 0x31, 0xde, 0x17, 0xc2, 0x3a, 0x0e, 0xa8,
- 0x73, 0xe6, 0x19, 0x75, 0xe7, 0xe2, 0x47, 0xca, 0xf7, 0x3e, 0x5e, 0x32,
- 0xe0, 0x1f, 0x0a, 0xee, 0x66, 0xdb, 0x02, 0xfe, 0x5b, 0xd1, 0xe7, 0x81,
- 0x17, 0x61, 0x57, 0x7e, 0x06, 0xba, 0xce, 0xcf, 0xd0, 0x9f, 0xa3, 0x8e,
- 0x87, 0xb7, 0x1d, 0xee, 0x75, 0x41, 0x9f, 0x0f, 0x2f, 0xcb, 0x12, 0x70,
- 0x47, 0x86, 0x72, 0x8c, 0xf8, 0xc1, 0x7a, 0x7a, 0x4e, 0xba, 0x69, 0x03,
- 0xe7, 0xa8, 0x2b, 0xfd, 0xd3, 0x71, 0x60, 0x3d, 0x20, 0x79, 0x75, 0xae,
- 0x8a, 0xe7, 0xb3, 0x1b, 0xc5, 0x20, 0xde, 0x73, 0x6e, 0x40, 0x19, 0xed,
- 0x86, 0x8f, 0x91, 0x96, 0x06, 0xda, 0x24, 0xb3, 0xa5, 0x4d, 0xd9, 0x0e,
- 0xcb, 0x79, 0x09, 0xe3, 0xee, 0x90, 0x46, 0x60, 0xb8, 0x02, 0xc6, 0x38,
- 0x20, 0xff, 0xd5, 0xe1, 0x1e, 0x95, 0x17, 0xfb, 0x81, 0x96, 0x08, 0x78,
- 0xd6, 0xb4, 0xc7, 0x36, 0x23, 0x3b, 0xaa, 0xec, 0x3f, 0xa2, 0x30, 0x56,
- 0x4e, 0xd8, 0x3f, 0xfc, 0x04, 0xc6, 0x4c, 0x4e, 0x53, 0xf6, 0x7b, 0xb1,
- 0x6e, 0xbf, 0x0d, 0x0c, 0x44, 0xae, 0x7e, 0x75, 0x83, 0xa7, 0x2f, 0xa4,
- 0x7f, 0x89, 0x78, 0x82, 0x67, 0x00, 0x5e, 0x5c, 0xbe, 0x42, 0x5b, 0x3f,
- 0xe8, 0x9d, 0xdd, 0xe0, 0x9f, 0x25, 0x77, 0x4e, 0x7b, 0xfe, 0xba, 0xf3,
- 0x2c, 0x5a, 0x1d, 0x95, 0x76, 0x9e, 0x4a, 0x1b, 0x72, 0x8b, 0xdc, 0x19,
- 0xf2, 0xfa, 0x31, 0x4e, 0x98, 0x90, 0x55, 0xda, 0x81, 0x76, 0xc8, 0x39,
- 0xf3, 0xb4, 0x29, 0xb4, 0x09, 0x94, 0x05, 0x5b, 0x8a, 0x55, 0xd8, 0x84,
- 0x96, 0x0e, 0x99, 0x23, 0xcf, 0x4e, 0xd0, 0x4e, 0xfc, 0x48, 0x26, 0xd7,
- 0xd8, 0xca, 0x41, 0xf1, 0xe3, 0xda, 0x66, 0x09, 0xa7, 0x6d, 0xf3, 0x3e,
- 0x35, 0x47, 0xcf, 0x5e, 0xee, 0x23, 0xfe, 0x9c, 0xc9, 0x58, 0x6d, 0xa2,
- 0xb1, 0xa7, 0xc2, 0x4f, 0xdf, 0xc7, 0x5c, 0xd9, 0x87, 0xe2, 0xd3, 0xc0,
- 0xa0, 0x17, 0x0b, 0xa8, 0x3d, 0x3f, 0xe0, 0xe0, 0xf8, 0xcf, 0x60, 0x6b,
- 0x73, 0xc4, 0x25, 0xe0, 0x73, 0xe7, 0x51, 0xca, 0xd1, 0x66, 0xda, 0x32,
- 0xe0, 0xbc, 0x14, 0xed, 0xb5, 0x2c, 0x4c, 0x03, 0x73, 0x19, 0x77, 0x48,
- 0x9e, 0xf2, 0xca, 0xbb, 0x0a, 0x0b, 0x86, 0x4c, 0xce, 0xb6, 0x48, 0xd7,
- 0x09, 0xee, 0xaf, 0x9e, 0x8a, 0x4a, 0x0b, 0xf7, 0x58, 0xe9, 0x83, 0xfa,
- 0x25, 0x87, 0xf2, 0xce, 0x13, 0x41, 0xb5, 0x1f, 0x36, 0x67, 0x90, 0x47,
- 0x7d, 0xb0, 0x07, 0x56, 0x6a, 0xc9, 0xd8, 0xd6, 0xe4, 0x61, 0x48, 0xc8,
- 0x52, 0x09, 0x32, 0x56, 0x82, 0x8c, 0x95, 0x20, 0x63, 0x25, 0xc8, 0x18,
- 0xb0, 0xdf, 0x79, 0xe8, 0xdf, 0xb9, 0xd2, 0x80, 0xf6, 0xeb, 0xbb, 0x94,
- 0x5f, 0x3f, 0x54, 0x7a, 0xc5, 0x65, 0xfa, 0xac, 0x8a, 0x4d, 0xfb, 0x20,
- 0x83, 0x8c, 0x45, 0xfd, 0x18, 0xf5, 0x15, 0x79, 0x72, 0xe6, 0x55, 0x39,
- 0x35, 0x53, 0xc3, 0x81, 0x13, 0x25, 0x57, 0x5e, 0x72, 0x10, 0x7f, 0xce,
- 0x13, 0x53, 0x65, 0x5a, 0x1b, 0x15, 0xb6, 0x3a, 0x28, 0x79, 0x85, 0x93,
- 0x95, 0x1f, 0x01, 0xbe, 0x52, 0xb8, 0x90, 0xba, 0x29, 0x6d, 0x5b, 0x2e,
- 0xcb, 0x39, 0xf8, 0xf1, 0x85, 0xea, 0x6b, 0xf2, 0x8c, 0xc2, 0xe3, 0xe4,
- 0xc3, 0x3b, 0xe5, 0xa7, 0xa6, 0x77, 0x9e, 0x7f, 0x0a, 0x58, 0x63, 0xa1,
- 0x87, 0xb6, 0x23, 0x04, 0x5f, 0x60, 0x15, 0x3a, 0xa1, 0xd7, 0xfb, 0x8d,
- 0x1b, 0x81, 0x69, 0xf8, 0x7e, 0xa3, 0xbc, 0x38, 0x53, 0xa8, 0x93, 0x09,
- 0xda, 0x07, 0xeb, 0xb0, 0x18, 0xf4, 0x53, 0xf4, 0x9b, 0x9c, 0x2f, 0xfd,
- 0xd4, 0x4f, 0x37, 0xf0, 0x0e, 0x57, 0xf9, 0x58, 0x6c, 0x03, 0xf7, 0x1b,
- 0x63, 0x36, 0x79, 0x7a, 0x59, 0xf6, 0x57, 0x58, 0xf6, 0x2a, 0xd6, 0x87,
- 0xe9, 0x0f, 0xdc, 0x7b, 0x63, 0x1c, 0x8f, 0xfd, 0x02, 0x37, 0xb5, 0x63,
- 0xae, 0xa5, 0x8f, 0x68, 0xcc, 0xdd, 0xa7, 0x70, 0xf4, 0xb5, 0x78, 0x99,
- 0x7c, 0x72, 0xc0, 0xa7, 0xcb, 0x6a, 0x3f, 0x70, 0x9d, 0x7d, 0xe2, 0x27,
- 0xa0, 0x57, 0x85, 0x2b, 0xc2, 0x3d, 0x4b, 0xee, 0xe7, 0x72, 0xaf, 0xb8,
- 0xde, 0x62, 0xa8, 0x7b, 0x03, 0x72, 0x0f, 0xec, 0xcb, 0xbd, 0xb0, 0x2f,
- 0xf7, 0x5d, 0x73, 0x07, 0xda, 0x3f, 0x03, 0xe8, 0x2a, 0x04, 0x8d, 0x0e,
- 0x19, 0xad, 0xd4, 0xb7, 0xe5, 0x3e, 0xee, 0x7a, 0xfb, 0xb6, 0xdc, 0xd3,
- 0x4d, 0xad, 0xd9, 0x0b, 0xa4, 0x6c, 0xb8, 0x72, 0xc9, 0xe1, 0xbe, 0x9b,
- 0x7f, 0x6f, 0x7e, 0x3d, 0xfc, 0x15, 0x68, 0xf6, 0xf7, 0x9c, 0x43, 0xe9,
- 0x2b, 0xc2, 0xfb, 0xf3, 0xc5, 0x29, 0xe2, 0x81, 0x98, 0xba, 0x17, 0x63,
- 0xa8, 0x7d, 0x3e, 0xaf, 0x6d, 0x71, 0x4a, 0x9d, 0x31, 0x15, 0xb8, 0x77,
- 0x6d, 0x6e, 0xb5, 0xcc, 0xd1, 0xa0, 0x77, 0x1f, 0x93, 0xba, 0xec, 0xd9,
- 0x32, 0xc8, 0x62, 0xb5, 0x76, 0xcf, 0x71, 0x50, 0xd9, 0x8b, 0x2b, 0xd0,
- 0x01, 0xae, 0x17, 0xe2, 0x05, 0xe8, 0xc9, 0x04, 0xec, 0x53, 0x5e, 0xf5,
- 0x17, 0xa1, 0x5c, 0x64, 0xb2, 0x41, 0x43, 0xc2, 0xc7, 0x19, 0x0b, 0x79,
- 0x7b, 0x2d, 0xb9, 0xa0, 0xa5, 0xec, 0x37, 0x68, 0x07, 0x3e, 0xa3, 0x7e,
- 0x26, 0xc6, 0x1b, 0xd3, 0x0d, 0xf0, 0xab, 0x58, 0xbf, 0x2a, 0xf7, 0x04,
- 0xa0, 0xbb, 0x8b, 0xdf, 0x91, 0x7d, 0xb3, 0xdd, 0xcd, 0x9e, 0xfc, 0x73,
- 0x1f, 0x99, 0xf3, 0xf3, 0x69, 0x58, 0xdd, 0xb7, 0x71, 0x5c, 0x22, 0x51,
- 0xf8, 0xb4, 0x0f, 0x20, 0xce, 0xd8, 0x01, 0x59, 0x59, 0x8a, 0xb1, 0x5f,
- 0x4f, 0x67, 0x26, 0x4b, 0xec, 0xfb, 0x3b, 0x32, 0x34, 0x5b, 0x6a, 0xa6,
- 0x2f, 0x59, 0x84, 0x1d, 0x58, 0x36, 0xe9, 0x43, 0xc7, 0xe0, 0xe3, 0xda,
- 0xe5, 0xfb, 0xb3, 0xf4, 0x8f, 0x49, 0xf3, 0x94, 0xf4, 0xc6, 0x4f, 0x81,
- 0xa6, 0xcf, 0x3b, 0x21, 0xc6, 0x68, 0xee, 0x20, 0xca, 0xfe, 0x5c, 0x92,
- 0x66, 0x67, 0x80, 0xcf, 0xbd, 0xe6, 0x17, 0x80, 0x61, 0x33, 0x66, 0xd2,
- 0xbc, 0x35, 0x40, 0x39, 0x42, 0xcc, 0xbd, 0x58, 0xa3, 0xf3, 0x07, 0xb3,
- 0x2a, 0x4e, 0x52, 0x76, 0x66, 0xd1, 0xe1, 0x78, 0xa0, 0x5b, 0xd9, 0xac,
- 0x5b, 0x61, 0x4f, 0x22, 0xfa, 0xfc, 0x0d, 0x6d, 0x88, 0x6d, 0x9c, 0x90,
- 0xce, 0x3f, 0x2a, 0xd9, 0x93, 0x31, 0xd8, 0x33, 0xf6, 0xe5, 0xc7, 0x0e,
- 0xf4, 0x91, 0x3e, 0xde, 0xa6, 0xbf, 0xbb, 0x03, 0x7e, 0xef, 0x66, 0x45,
- 0xcf, 0xb0, 0xd3, 0x27, 0x13, 0xc7, 0x38, 0x76, 0x0f, 0x6c, 0x79, 0x5c,
- 0xc9, 0x6d, 0xb1, 0xb4, 0x1c, 0x8f, 0xc0, 0x26, 0x47, 0xb6, 0x90, 0x9f,
- 0xef, 0x93, 0xbb, 0xec, 0x31, 0xb9, 0x1b, 0xb2, 0x33, 0x68, 0x3b, 0x32,
- 0x84, 0xb5, 0xd8, 0x61, 0xc3, 0xef, 0x28, 0x0c, 0xdd, 0x88, 0xb8, 0x8b,
- 0x63, 0xb7, 0xeb, 0xfb, 0x17, 0x1e, 0x7e, 0xfc, 0x4a, 0xd5, 0xe3, 0x51,
- 0x76, 0xf6, 0x49, 0xc5, 0x9b, 0x61, 0x67, 0x9b, 0xf6, 0xb3, 0x2d, 0x92,
- 0x53, 0xf5, 0xb6, 0x29, 0x7f, 0x5c, 0x5c, 0xb8, 0x1f, 0x29, 0x7c, 0xf3,
- 0x02, 0xec, 0x0d, 0x30, 0x77, 0xb1, 0xb2, 0x15, 0x79, 0xf8, 0xd0, 0x85,
- 0x34, 0xd2, 0xf7, 0x21, 0x65, 0xdd, 0x07, 0x9a, 0xbd, 0xbd, 0xdc, 0xb5,
- 0xf7, 0xb8, 0x24, 0xf0, 0x01, 0x85, 0x4b, 0xaf, 0xa8, 0x3b, 0x80, 0x88,
- 0xa1, 0x47, 0xb2, 0xb0, 0x2b, 0xcd, 0xc0, 0x40, 0x53, 0xc7, 0xad, 0xd4,
- 0x50, 0x60, 0xbb, 0x7c, 0x10, 0xb1, 0x7c, 0xd9, 0xe1, 0x5a, 0x6e, 0x95,
- 0x07, 0xdf, 0x4b, 0x19, 0xd9, 0x2e, 0x7b, 0xde, 0x1b, 0x90, 0x3d, 0x7d,
- 0x56, 0x86, 0x74, 0xdf, 0xf2, 0x2e, 0x3f, 0x9e, 0xee, 0x1a, 0x4e, 0x06,
- 0xfa, 0xe5, 0x0b, 0x90, 0xb1, 0x02, 0xe4, 0x6b, 0xa8, 0x4a, 0x9e, 0xd3,
- 0xde, 0xd3, 0xce, 0xa7, 0x80, 0x95, 0x7d, 0xec, 0x67, 0xcb, 0x54, 0xb5,
- 0x41, 0x12, 0x37, 0x70, 0x3f, 0x39, 0xe1, 0x9d, 0x71, 0xdc, 0x40, 0x99,
- 0x40, 0x0c, 0x72, 0x83, 0xa7, 0x9f, 0xea, 0xee, 0xdd, 0x0d, 0x9e, 0x5f,
- 0x41, 0xfc, 0xeb, 0x12, 0xe7, 0x79, 0x77, 0x0d, 0xbe, 0xa1, 0x6d, 0x69,
- 0x68, 0xe3, 0x0a, 0xbe, 0x6b, 0x61, 0xfc, 0xf0, 0x87, 0xcd, 0xb5, 0x6f,
- 0x07, 0xd6, 0xca, 0xa2, 0xbf, 0xef, 0x36, 0x87, 0x39, 0xd3, 0xa7, 0x5b,
- 0x26, 0x6d, 0x61, 0xab, 0xbd, 0x4b, 0xfe, 0x0c, 0xfe, 0xfd, 0x6b, 0x2b,
- 0xfe, 0x7d, 0x37, 0xf8, 0xb1, 0x16, 0x03, 0xd8, 0xe6, 0x3d, 0x98, 0xcb,
- 0x30, 0xd6, 0xf3, 0x6e, 0xfc, 0xee, 0x2a, 0xad, 0xda, 0xc7, 0x9b, 0x29,
- 0x00, 0x4f, 0x36, 0xd8, 0xec, 0x6f, 0xd5, 0x7e, 0x5e, 0x21, 0x2f, 0x2b,
- 0x7b, 0x85, 0x03, 0x57, 0x85, 0x7e, 0xef, 0x75, 0x09, 0x77, 0xdb, 0xaf,
- 0x77, 0x06, 0xec, 0xe7, 0x8d, 0x00, 0xcf, 0xc1, 0x1d, 0x39, 0x5d, 0x25,
- 0x0e, 0xbb, 0x28, 0xc6, 0x59, 0x62, 0xb0, 0x97, 0xd5, 0x1e, 0x54, 0xb9,
- 0xf4, 0x2d, 0xa4, 0xa8, 0x0f, 0xfb, 0x18, 0xf4, 0xf6, 0x29, 0x14, 0x56,
- 0xa1, 0x9d, 0xbd, 0x1b, 0xeb, 0x30, 0x81, 0x5f, 0xe7, 0x96, 0x5b, 0xa1,
- 0xbf, 0x94, 0x53, 0xee, 0x7d, 0x75, 0x9b, 0x5b, 0x02, 0x7c, 0xb7, 0xde,
- 0x3e, 0xd8, 0xb7, 0x25, 0x74, 0x14, 0xbe, 0xce, 0xa0, 0x7d, 0xe0, 0x3c,
- 0xe8, 0x27, 0x4d, 0x99, 0x3f, 0x46, 0x5d, 0x5f, 0xaf, 0xbe, 0x5f, 0xd7,
- 0x9f, 0x8b, 0xf2, 0x1b, 0x99, 0x3c, 0xf7, 0x38, 0x4b, 0x5c, 0x03, 0x07,
- 0x6b, 0xe0, 0xca, 0x71, 0xa7, 0x95, 0x36, 0x5d, 0x82, 0xc7, 0x5d, 0x19,
- 0x54, 0xd8, 0xb5, 0x17, 0x98, 0x6b, 0xa3, 0xc6, 0x0d, 0x31, 0x09, 0x1d,
- 0xef, 0x90, 0x46, 0xe0, 0xea, 0x86, 0x23, 0xf4, 0x91, 0xc9, 0xc4, 0x20,
- 0x84, 0x20, 0xa4, 0xee, 0x93, 0x5a, 0x03, 0xdf, 0x97, 0xde, 0xc4, 0xf7,
- 0x85, 0x78, 0xe9, 0x51, 0xac, 0x9f, 0xe5, 0x5c, 0x5c, 0xa7, 0x7e, 0xb1,
- 0x56, 0x1f, 0x72, 0xc4, 0xbd, 0x35, 0xb6, 0xe1, 0x5e, 0x5b, 0x72, 0xe0,
- 0x7b, 0xdc, 0x63, 0x43, 0xac, 0xd9, 0x70, 0xc6, 0xa3, 0xc1, 0x58, 0x6c,
- 0x93, 0xf2, 0x49, 0xea, 0x28, 0xf7, 0x59, 0x4c, 0x2f, 0x4e, 0x2d, 0x31,
- 0x5e, 0xe5, 0xfb, 0x84, 0x7e, 0xdf, 0xa9, 0xdf, 0x33, 0x1e, 0x2d, 0xb8,
- 0x0d, 0xe0, 0xe9, 0x0e, 0xd8, 0xcf, 0xfb, 0xb7, 0xda, 0x0a, 0x37, 0xdc,
- 0xbf, 0xb2, 0x66, 0x3b, 0xd5, 0xdd, 0xa2, 0x72, 0xe9, 0xa0, 0xd8, 0x5b,
- 0x96, 0x52, 0x21, 0x19, 0xc5, 0x5a, 0x30, 0x9f, 0x21, 0x3d, 0xa9, 0x43,
- 0xb2, 0x5f, 0xad, 0x4d, 0xf9, 0x98, 0x75, 0x38, 0x11, 0x98, 0x10, 0xa3,
- 0xcc, 0xe7, 0x4f, 0x23, 0x3d, 0x04, 0xbc, 0xe3, 0xed, 0x5d, 0x1a, 0xe5,
- 0xd5, 0xbc, 0x04, 0xc6, 0x30, 0x77, 0xac, 0xda, 0xc7, 0xaa, 0xed, 0x71,
- 0xf1, 0xfd, 0xa0, 0x7a, 0x9f, 0x5a, 0xb5, 0xcf, 0x95, 0x33, 0x88, 0x65,
- 0xfc, 0xf7, 0x5c, 0x0b, 0xae, 0x17, 0x7c, 0xf1, 0x31, 0x7f, 0xcf, 0xab,
- 0x45, 0xaf, 0x0b, 0xd7, 0x67, 0x4a, 0xce, 0x99, 0xd6, 0x30, 0xe5, 0xef,
- 0xb6, 0xad, 0x37, 0xc9, 0x78, 0x3b, 0xf7, 0xdb, 0xea, 0x69, 0x58, 0xbb,
- 0x8f, 0x56, 0x3f, 0xfe, 0xda, 0xfd, 0x37, 0x8e, 0xed, 0xed, 0xb1, 0x65,
- 0x57, 0xed, 0xb1, 0xd5, 0x8f, 0xc7, 0xb1, 0x36, 0x22, 0x7e, 0x2a, 0xb8,
- 0x31, 0x9b, 0x6b, 0xd4, 0x95, 0x98, 0x65, 0xfe, 0xcb, 0x06, 0xd6, 0x31,
- 0x06, 0x3f, 0xc2, 0xb5, 0xf4, 0xcf, 0x9e, 0xb9, 0xa6, 0xc9, 0xc4, 0x21,
- 0x6f, 0x3d, 0x07, 0xbc, 0x75, 0xf7, 0xd6, 0xff, 0xe2, 0xca, 0x3a, 0xd2,
- 0x3f, 0x70, 0x1d, 0xdb, 0x45, 0x60, 0x67, 0x8d, 0x23, 0x5c, 0x43, 0xa6,
- 0x5c, 0x43, 0xbe, 0xe3, 0x1a, 0x76, 0xea, 0x77, 0x5c, 0x3f, 0xe0, 0xb4,
- 0x2f, 0x02, 0x63, 0x38, 0x59, 0xf5, 0x1d, 0x54, 0x67, 0xb7, 0xaf, 0x8b,
- 0x29, 0x79, 0x66, 0x3e, 0x2a, 0x66, 0xda, 0x9b, 0xd7, 0xd8, 0xaa, 0xfd,
- 0x76, 0x9e, 0x5f, 0xf5, 0x11, 0x7b, 0xfa, 0xf3, 0x8a, 0x73, 0x5e, 0xfb,
- 0xe5, 0xb2, 0xe4, 0xa7, 0x42, 0x88, 0x01, 0x53, 0xc0, 0x39, 0x7d, 0xb0,
- 0xb7, 0xdc, 0x1f, 0x45, 0x59, 0x85, 0x78, 0x85, 0xbe, 0x2e, 0x05, 0x5d,
- 0xa1, 0x0d, 0x26, 0x1e, 0x79, 0x55, 0x72, 0x73, 0xbe, 0x8d, 0x41, 0xff,
- 0x86, 0xdf, 0x3f, 0xf9, 0x9c, 0xb9, 0x65, 0xb3, 0x2c, 0x25, 0x36, 0x8b,
- 0x95, 0x58, 0x90, 0xda, 0xba, 0x8e, 0xad, 0xcf, 0x77, 0xe7, 0xfe, 0x60,
- 0x4d, 0x36, 0xc6, 0xd6, 0x59, 0xfb, 0xbd, 0xe2, 0xbf, 0xf7, 0xd7, 0x7e,
- 0xdd, 0x75, 0x28, 0xbc, 0x22, 0x5c, 0x0b, 0xf2, 0x80, 0x78, 0x38, 0x2c,
- 0x9f, 0x8a, 0x51, 0x1f, 0x0b, 0xea, 0x7c, 0x33, 0x69, 0x74, 0x2b, 0x9b,
- 0x31, 0xe8, 0x78, 0xf2, 0x5a, 0xc0, 0x38, 0x91, 0xae, 0x7f, 0xe1, 0x0e,
- 0xc6, 0x10, 0xe7, 0x76, 0xd1, 0xbe, 0xf8, 0x3a, 0x1d, 0x55, 0x3a, 0xfd,
- 0x79, 0x27, 0x20, 0x45, 0x3b, 0x20, 0x13, 0xf6, 0x41, 0x85, 0xf1, 0x3f,
- 0x84, 0xbe, 0x1e, 0xd4, 0x7d, 0x4d, 0x48, 0xb7, 0xb6, 0x3f, 0x07, 0x20,
- 0xe7, 0xae, 0xdc, 0xe7, 0x6c, 0x95, 0xdb, 0x5a, 0xa9, 0x03, 0xfe, 0xfc,
- 0x0f, 0x4a, 0xd7, 0xd6, 0xa5, 0x04, 0x22, 0x83, 0x5b, 0xc2, 0x2b, 0x3c,
- 0xa0, 0x9e, 0xf9, 0xf2, 0xed, 0xf1, 0xc1, 0x9b, 0xff, 0xaa, 0xb9, 0xea,
- 0x79, 0x72, 0xce, 0xac, 0xc7, 0xb9, 0x7a, 0x58, 0xbe, 0x36, 0x57, 0xbf,
- 0x7e, 0x33, 0x64, 0xc9, 0x4a, 0x48, 0xa0, 0x9e, 0x37, 0x2b, 0x36, 0x6a,
- 0x98, 0x7b, 0x24, 0x4b, 0xa6, 0x95, 0x4a, 0x04, 0xfc, 0xbd, 0x68, 0x0f,
- 0xeb, 0x76, 0x02, 0x87, 0xdb, 0xdd, 0xdd, 0xa9, 0xbc, 0xda, 0x23, 0x35,
- 0xd4, 0xbc, 0x26, 0x80, 0xc9, 0xe6, 0x9d, 0x57, 0xdc, 0x4f, 0x02, 0xb3,
- 0x8e, 0xcb, 0xc3, 0x12, 0x5c, 0xb5, 0x97, 0x8b, 0xfc, 0x59, 0xee, 0xe7,
- 0x5a, 0x89, 0x0c, 0xd6, 0xf8, 0xc3, 0x88, 0xe1, 0xcb, 0xb0, 0xfb, 0x1f,
- 0xa1, 0x6f, 0x28, 0xc1, 0x5f, 0x00, 0x97, 0x7c, 0xed, 0xba, 0x18, 0x7e,
- 0xbc, 0x6e, 0x2f, 0xd7, 0xc3, 0xa7, 0xe7, 0x14, 0x26, 0x25, 0x6e, 0x3f,
- 0x1c, 0xb8, 0xa7, 0x27, 0x88, 0x38, 0xa3, 0xe0, 0x46, 0x6c, 0xe2, 0xb8,
- 0x83, 0x72, 0x17, 0xd6, 0xe7, 0xf4, 0x7c, 0x21, 0xb0, 0xa3, 0xe4, 0xcb,
- 0x2a, 0xe2, 0xca, 0xaa, 0x95, 0x5a, 0x06, 0x3f, 0x9e, 0xd4, 0x98, 0x8f,
- 0xe7, 0x35, 0x65, 0x1d, 0xb3, 0x70, 0x6f, 0xa8, 0x58, 0x3d, 0x28, 0x93,
- 0x0e, 0xf7, 0x76, 0xba, 0xa4, 0x18, 0xcb, 0xdc, 0xd4, 0xb8, 0xc2, 0x23,
- 0xcb, 0x44, 0xcc, 0x97, 0xa2, 0xfd, 0x2e, 0xeb, 0xf3, 0x8e, 0x27, 0x95,
- 0x7c, 0xf9, 0xfb, 0xc2, 0x8c, 0x8f, 0x78, 0x5e, 0xd5, 0x65, 0x0e, 0xf3,
- 0x79, 0x8e, 0x32, 0xa0, 0x62, 0x26, 0xf0, 0xf2, 0x21, 0xc9, 0x8c, 0x26,
- 0x14, 0x6e, 0x79, 0xbc, 0x44, 0x7d, 0x21, 0xfe, 0xbf, 0x0c, 0xec, 0x1f,
- 0xc2, 0x9a, 0x31, 0x0e, 0xe0, 0xd8, 0xd4, 0x0b, 0x94, 0x55, 0xcc, 0x5f,
- 0xa2, 0x17, 0xdb, 0x37, 0x11, 0x63, 0x5c, 0x28, 0x7d, 0x5c, 0xf1, 0x6f,
- 0x49, 0xfc, 0xbd, 0x73, 0x85, 0x05, 0x0b, 0xd9, 0x60, 0x40, 0x92, 0x47,
- 0x3f, 0x03, 0x19, 0x1a, 0x41, 0x8c, 0xc4, 0x7a, 0xa2, 0xce, 0xaf, 0x06,
- 0x81, 0xb9, 0x0c, 0xfb, 0x46, 0x29, 0x9a, 0x61, 0x29, 0xaa, 0x7b, 0x80,
- 0x3c, 0xcf, 0x0d, 0xaa, 0xbd, 0x9d, 0xa2, 0x49, 0xcc, 0x9f, 0xd9, 0xe4,
- 0xdf, 0x03, 0x2c, 0x9a, 0x6c, 0xc7, 0x3c, 0xcb, 0x27, 0x24, 0x7c, 0xf4,
- 0x80, 0x34, 0x1c, 0x7d, 0x58, 0x1a, 0xa7, 0x89, 0xf1, 0xb8, 0x77, 0x6f,
- 0xdc, 0xd1, 0x28, 0xc4, 0xdc, 0x5f, 0xc5, 0xd8, 0x07, 0xe5, 0x87, 0x8e,
- 0x4f, 0xd3, 0x86, 0x8d, 0xd2, 0xc2, 0x3a, 0x7e, 0xde, 0xc7, 0xe3, 0x77,
- 0x80, 0x1e, 0xce, 0x3f, 0xa1, 0x71, 0xdf, 0x1d, 0x75, 0xb1, 0x6b, 0x83,
- 0x8e, 0x5d, 0xd9, 0xee, 0x32, 0x7c, 0xf6, 0x31, 0x09, 0xdb, 0x7e, 0xfb,
- 0xed, 0xa8, 0x17, 0xaf, 0xbb, 0x03, 0xc1, 0x3a, 0xfa, 0x4e, 0x40, 0x0b,
- 0x71, 0x0f, 0xcf, 0xdb, 0x59, 0xe6, 0x9d, 0xf9, 0x1b, 0xe5, 0x74, 0x70,
- 0xf5, 0xf8, 0xdb, 0xea, 0xea, 0xfa, 0x65, 0x7e, 0x9b, 0xb0, 0x17, 0xf3,
- 0xf7, 0x87, 0xeb, 0xda, 0x7d, 0xd7, 0xf4, 0x52, 0x2f, 0xf6, 0xf0, 0xe2,
- 0x20, 0xce, 0x21, 0x55, 0x87, 0x73, 0x56, 0x7f, 0x2f, 0x9a, 0x43, 0x79,
- 0x7e, 0xd6, 0xbf, 0x3b, 0x64, 0x60, 0x2e, 0x56, 0x81, 0xf1, 0x8b, 0xc9,
- 0x6f, 0x33, 0x67, 0x0b, 0xa0, 0xfb, 0x66, 0x75, 0xef, 0x88, 0x77, 0x37,
- 0x50, 0x2f, 0xe1, 0xe1, 0x4f, 0xe6, 0xe3, 0x58, 0xf3, 0x77, 0x75, 0x18,
- 0xe9, 0xff, 0x7e, 0x53, 0xb6, 0x9f, 0xf8, 0x66, 0x13, 0xcf, 0x21, 0x81,
- 0x9b, 0x29, 0x67, 0xdf, 0x81, 0x9c, 0x35, 0xaa, 0x73, 0x9f, 0x62, 0x89,
- 0xf1, 0x5c, 0x1e, 0xf2, 0xc3, 0xfb, 0x7b, 0x8c, 0xfb, 0xf2, 0x7a, 0x3f,
- 0x96, 0x74, 0x12, 0xd3, 0xfb, 0xf1, 0x01, 0xfb, 0x5c, 0xef, 0x9e, 0xb2,
- 0x1f, 0xb3, 0x51, 0xde, 0xe2, 0x8a, 0xe6, 0xa1, 0x35, 0xf1, 0xca, 0x21,
- 0xd8, 0x82, 0x79, 0xc8, 0xf3, 0x5e, 0xd8, 0xc0, 0xc1, 0x20, 0xf5, 0x33,
- 0xaa, 0x63, 0x59, 0x9b, 0x71, 0x7b, 0x60, 0x14, 0x7d, 0x18, 0xd3, 0xaf,
- 0xc9, 0x04, 0xec, 0xff, 0x64, 0x35, 0xa9, 0xbe, 0xe9, 0xc9, 0xc4, 0x79,
- 0x9f, 0x8c, 0xe5, 0x5f, 0x83, 0xbc, 0xbe, 0x06, 0x3c, 0xbc, 0x01, 0xfc,
- 0x34, 0xf4, 0x5a, 0xfd, 0x96, 0xde, 0x8b, 0x8a, 0x70, 0x2f, 0x1e, 0x76,
- 0xb3, 0xe8, 0x61, 0xcd, 0xd8, 0x24, 0xd2, 0x7f, 0x1e, 0xf5, 0xe4, 0xf5,
- 0xdf, 0x6a, 0x79, 0x6b, 0x42, 0xf9, 0x63, 0x6a, 0x0f, 0xd2, 0x9b, 0x93,
- 0xa5, 0x63, 0x95, 0x30, 0x64, 0x8e, 0xf3, 0xfa, 0x53, 0xd4, 0xa3, 0xac,
- 0xf5, 0xe8, 0xb3, 0xd9, 0xa8, 0xb2, 0x8f, 0x39, 0xc8, 0x52, 0x5e, 0xc5,
- 0x11, 0xc0, 0xf7, 0x0e, 0xdb, 0x3d, 0xb7, 0x89, 0x67, 0x9f, 0x0d, 0xb6,
- 0x8a, 0x2d, 0xda, 0x83, 0xe2, 0x97, 0xdd, 0x89, 0x32, 0xca, 0xd9, 0x8d,
- 0x58, 0x1b, 0x96, 0x65, 0x91, 0xe7, 0x58, 0x37, 0xe9, 0x71, 0x38, 0x46,
- 0x77, 0xf3, 0x6a, 0x9a, 0x38, 0x97, 0xf6, 0x35, 0xdf, 0x35, 0xb0, 0xec,
- 0x46, 0x5d, 0x16, 0xd2, 0xf3, 0x1b, 0xd2, 0xdf, 0xd2, 0x5a, 0x87, 0x33,
- 0x2b, 0xd8, 0x98, 0xf4, 0x45, 0x54, 0xbb, 0x8c, 0xe9, 0xc9, 0xce, 0x21,
- 0xac, 0x47, 0x28, 0x1d, 0xe4, 0x99, 0x2c, 0xf8, 0xeb, 0xeb, 0x44, 0x5c,
- 0xc5, 0x9d, 0x09, 0xc3, 0xbb, 0xbb, 0x74, 0xee, 0x9a, 0xfb, 0xd9, 0xde,
- 0x5d, 0xf7, 0xa1, 0x9e, 0x26, 0x99, 0x9f, 0x89, 0xe8, 0x7b, 0x93, 0x71,
- 0xa5, 0xb3, 0xf9, 0x31, 0xe6, 0xff, 0xc7, 0x26, 0x7e, 0xc7, 0x6c, 0xd8,
- 0x2c, 0x6f, 0xd7, 0xfc, 0xbd, 0x51, 0xdd, 0x33, 0xa2, 0x2e, 0x14, 0xe7,
- 0xde, 0x50, 0xef, 0x4f, 0xcf, 0x36, 0xa8, 0xfa, 0xa7, 0x67, 0xd7, 0xde,
- 0x15, 0x62, 0xd9, 0xdb, 0xb8, 0xbf, 0x21, 0x0b, 0x53, 0x0d, 0xb2, 0x38,
- 0x1b, 0x60, 0xbc, 0x96, 0x6e, 0xac, 0x7d, 0x0b, 0xa3, 0xbf, 0x5b, 0x73,
- 0x65, 0x08, 0xeb, 0x37, 0x3f, 0x30, 0x29, 0xe5, 0x01, 0xc6, 0x23, 0xea,
- 0x3e, 0x20, 0x64, 0xa4, 0x01, 0x58, 0xb4, 0xe0, 0x96, 0x6d, 0xee, 0x03,
- 0xb7, 0x68, 0xbd, 0x7e, 0x45, 0xc7, 0x7c, 0xe4, 0x91, 0x21, 0xb9, 0xbe,
- 0x09, 0x45, 0x57, 0x59, 0xf1, 0xca, 0xff, 0xd6, 0x88, 0xfd, 0xf3, 0x7b,
- 0xa3, 0xa0, 0xc6, 0xb2, 0xfb, 0x35, 0xcf, 0xff, 0x4a, 0xa7, 0x8f, 0xca,
- 0x9e, 0x63, 0xbf, 0x0f, 0x5a, 0x9b, 0xbc, 0x3b, 0x4f, 0x52, 0xff, 0x3d,
- 0x49, 0x48, 0x7d, 0xcf, 0x12, 0xb2, 0x1f, 0x45, 0x19, 0xf7, 0xc1, 0x1e,
- 0x55, 0xf3, 0xe0, 0xbd, 0xba, 0x82, 0xfc, 0xaa, 0xfb, 0x21, 0x7e, 0x2c,
- 0xc6, 0xbb, 0x4b, 0x51, 0xdd, 0xdf, 0x0e, 0xbd, 0x8e, 0x63, 0xb2, 0x07,
- 0xbe, 0x26, 0x0f, 0x4c, 0xca, 0xfb, 0x5e, 0xe3, 0xc1, 0xfa, 0x31, 0x7d,
- 0x59, 0xf6, 0xe2, 0x7c, 0xff, 0xde, 0x41, 0x50, 0xc5, 0x23, 0x2b, 0x7b,
- 0x06, 0xba, 0x7c, 0x4c, 0xf6, 0x95, 0xd4, 0xde, 0x81, 0x3a, 0x2f, 0x9c,
- 0x84, 0x4e, 0x0e, 0x2a, 0x7f, 0x12, 0x09, 0x0c, 0x55, 0xd2, 0x92, 0x3f,
- 0xb9, 0x13, 0xe3, 0x70, 0x1f, 0x2e, 0xa3, 0xcf, 0xe5, 0x76, 0xcb, 0x9e,
- 0xaa, 0x37, 0xf6, 0xde, 0x12, 0xdf, 0x27, 0xe1, 0xa3, 0xf9, 0x3e, 0x17,
- 0x0f, 0xaa, 0x93, 0x85, 0x5b, 0xd1, 0xb6, 0x41, 0xf3, 0x96, 0xf7, 0xfc,
- 0xd9, 0x9e, 0xfa, 0xf7, 0x4f, 0x4c, 0x89, 0xe6, 0xf0, 0x9e, 0x6d, 0xfc,
- 0xfe, 0xf6, 0xc2, 0x67, 0x30, 0x36, 0x7e, 0x44, 0x96, 0xe6, 0x26, 0x65,
- 0x79, 0xce, 0x97, 0x33, 0xde, 0xb9, 0x26, 0xed, 0x77, 0xeb, 0x3b, 0xd7,
- 0x19, 0xac, 0xc3, 0x6a, 0x5e, 0xe5, 0x56, 0x7d, 0x8f, 0xf4, 0x75, 0xd3,
- 0xfb, 0x26, 0x70, 0xbb, 0xba, 0x3f, 0xb5, 0x5a, 0xde, 0xd9, 0xcf, 0x57,
- 0x4c, 0x9e, 0x33, 0x78, 0x77, 0xc0, 0xda, 0xeb, 0xde, 0xc7, 0xf4, 0xbd,
- 0xab, 0xaf, 0xe9, 0xbb, 0xfa, 0xe4, 0xe7, 0xa8, 0xa6, 0xf7, 0x56, 0xe8,
- 0x1e, 0xfb, 0x7c, 0x4c, 0xaf, 0x1b, 0xd2, 0x79, 0x3e, 0xab, 0xbb, 0xa6,
- 0xfa, 0xec, 0xd5, 0xd4, 0x63, 0xd4, 0xdf, 0x7b, 0x6b, 0xa8, 0x1b, 0x97,
- 0xed, 0xe9, 0x1b, 0xfc, 0x3b, 0xe0, 0x2c, 0x3b, 0xa6, 0xef, 0xd7, 0xf9,
- 0x77, 0xbe, 0x59, 0xe6, 0xdf, 0x03, 0x23, 0xbf, 0xb8, 0x9f, 0x88, 0xb4,
- 0x3a, 0xaa, 0x9f, 0x47, 0xeb, 0xbe, 0x1d, 0xf2, 0xfb, 0x0c, 0xa1, 0x8f,
- 0x3b, 0x83, 0xd7, 0xde, 0x11, 0xe7, 0xb7, 0x54, 0x94, 0x45, 0x83, 0xdf,
- 0x78, 0x33, 0x06, 0x03, 0x6e, 0xda, 0x28, 0x7b, 0x15, 0x3d, 0x05, 0x75,
- 0x57, 0x22, 0xeb, 0x34, 0xc9, 0xa0, 0xe9, 0xe5, 0xf7, 0xce, 0xaf, 0x95,
- 0x53, 0x96, 0x6f, 0x8a, 0x48, 0x94, 0xdf, 0x70, 0xf1, 0xfd, 0x7a, 0xdf,
- 0x2e, 0x84, 0xf5, 0xf7, 0x53, 0x0e, 0xda, 0x7c, 0x9e, 0xf2, 0x5e, 0x28,
- 0xac, 0xdc, 0xd1, 0x2c, 0xa8, 0x3d, 0x52, 0x00, 0x73, 0x7d, 0x57, 0x92,
- 0xdf, 0xb0, 0x8b, 0x3c, 0x5d, 0xe1, 0xb7, 0x5c, 0xdb, 0xd5, 0x1d, 0x16,
- 0xef, 0x5c, 0x90, 0x74, 0x75, 0x29, 0x9b, 0x5c, 0xae, 0x14, 0xc9, 0x53,
- 0xed, 0x57, 0xc3, 0xda, 0xaf, 0x92, 0xc7, 0xc3, 0xe0, 0xf1, 0x5f, 0xeb,
- 0x75, 0x61, 0xfb, 0x8c, 0xba, 0x0b, 0x9e, 0x89, 0xf1, 0x6c, 0xea, 0x31,
- 0x35, 0x17, 0xda, 0x68, 0xb4, 0x7d, 0x47, 0x50, 0xe9, 0xae, 0xfa, 0x46,
- 0x1e, 0xf2, 0xc9, 0x6f, 0xde, 0x61, 0x5f, 0x4b, 0xfc, 0xb6, 0x7d, 0x58,
- 0x7d, 0x67, 0x52, 0xae, 0x70, 0x5d, 0xf9, 0x4d, 0xfb, 0x68, 0x9d, 0x3c,
- 0x06, 0xf5, 0x58, 0x9b, 0x5a, 0x25, 0xea, 0xad, 0x3b, 0xbf, 0x51, 0x29,
- 0x57, 0xfc, 0xfb, 0x9d, 0x1b, 0x96, 0xa8, 0x13, 0xa2, 0x62, 0x6c, 0xef,
- 0x3b, 0x9b, 0xb2, 0xfa, 0x6e, 0x25, 0xc1, 0xef, 0x2e, 0xe1, 0x3b, 0x76,
- 0xe1, 0x99, 0x67, 0xba, 0xbb, 0x91, 0xc2, 0xe6, 0x54, 0xc6, 0x91, 0x3e,
- 0x2c, 0x39, 0xb5, 0xe7, 0xd6, 0x8c, 0xfc, 0x5e, 0x35, 0x76, 0xb1, 0xf2,
- 0x80, 0xec, 0x39, 0xf9, 0x10, 0xbf, 0xed, 0x51, 0xdf, 0xe5, 0x67, 0x1d,
- 0xd2, 0x18, 0x93, 0x09, 0x35, 0xef, 0x42, 0xed, 0x9b, 0x11, 0xc5, 0xfb,
- 0x5c, 0x2b, 0xd7, 0xb4, 0x50, 0x69, 0x06, 0x8d, 0x01, 0x7d, 0xc7, 0x93,
- 0x58, 0xdc, 0x9f, 0x7f, 0x94, 0xf7, 0x06, 0x5d, 0x9e, 0xdd, 0xed, 0x29,
- 0xf1, 0x0e, 0x67, 0x52, 0xc7, 0xe8, 0xdc, 0xb7, 0xe3, 0xd9, 0x00, 0x65,
- 0xdc, 0x4a, 0x8d, 0xc3, 0xfa, 0x87, 0x25, 0xce, 0x73, 0x65, 0x3d, 0x97,
- 0xe6, 0xba, 0xb9, 0xf0, 0xde, 0xaa, 0x37, 0x1f, 0x7e, 0x0b, 0x93, 0x2f,
- 0xd5, 0x7f, 0xc7, 0xa3, 0xbe, 0x11, 0x57, 0xdf, 0xcd, 0x8c, 0x57, 0x3e,
- 0x21, 0x1f, 0x2b, 0x6d, 0xd4, 0xdf, 0xf0, 0x44, 0xe4, 0x63, 0x95, 0xd7,
- 0x14, 0x4f, 0xf3, 0xea, 0xfb, 0xa3, 0xb0, 0x5e, 0xb3, 0x98, 0xea, 0xa3,
- 0xf6, 0x1d, 0x92, 0x55, 0xf7, 0x4d, 0x4a, 0x58, 0xc6, 0xe7, 0x7f, 0xd9,
- 0xb7, 0x48, 0x8f, 0x08, 0xbf, 0x47, 0xb9, 0xe4, 0x4c, 0xca, 0xe3, 0x73,
- 0xae, 0x7b, 0x97, 0x43, 0x5c, 0xb7, 0x41, 0x96, 0x63, 0xa3, 0x3b, 0xbe,
- 0x67, 0xb7, 0x05, 0xca, 0x33, 0x8d, 0xb0, 0xd7, 0xc4, 0x12, 0x12, 0x65,
- 0x7e, 0x7e, 0x86, 0x7a, 0x1a, 0xc2, 0x1c, 0x2d, 0xf3, 0xaa, 0x7c, 0xa6,
- 0x95, 0x7b, 0x5e, 0x77, 0x21, 0x8e, 0xfc, 0xb8, 0xe3, 0xd9, 0xe5, 0xcf,
- 0x2d, 0xec, 0x94, 0xcf, 0x55, 0x22, 0x81, 0xf2, 0x14, 0xef, 0xfa, 0x59,
- 0xc3, 0x73, 0x92, 0x44, 0x3d, 0xf6, 0x0f, 0x79, 0x89, 0x6f, 0x96, 0xa7,
- 0x8e, 0xfd, 0xc2, 0xbd, 0x6a, 0xe3, 0x3d, 0x6c, 0xcd, 0xb2, 0xe3, 0xef,
- 0xeb, 0x21, 0x86, 0x3f, 0xc2, 0x7a, 0x9b, 0x21, 0x07, 0xf0, 0xdb, 0xd0,
- 0x39, 0xc6, 0x98, 0x57, 0xb5, 0xdd, 0x32, 0x8e, 0xdc, 0x2c, 0x57, 0x57,
- 0xee, 0x0a, 0x5f, 0x86, 0x6c, 0x27, 0x3c, 0xfe, 0xab, 0x7d, 0xf0, 0x03,
- 0x12, 0xfc, 0x22, 0xfc, 0xc4, 0x17, 0x1b, 0x94, 0x6d, 0xa7, 0x3f, 0x43,
- 0xfc, 0x81, 0x18, 0x23, 0x84, 0x7e, 0x1e, 0x6c, 0xf5, 0x64, 0x76, 0x52,
- 0xe4, 0xcb, 0x4d, 0x92, 0x69, 0x65, 0x0c, 0x2b, 0xbf, 0xc2, 0x7e, 0xd5,
- 0xeb, 0x59, 0x4a, 0xbe, 0x42, 0x1d, 0xaf, 0x72, 0x2e, 0xc9, 0xf8, 0x8f,
- 0xe5, 0x93, 0x32, 0x1e, 0xe7, 0x5c, 0x1e, 0x91, 0xc2, 0xdc, 0x63, 0xf8,
- 0x71, 0x9e, 0xa4, 0xfb, 0x1f, 0xe8, 0x7b, 0x04, 0xa3, 0x52, 0x9c, 0x4a,
- 0xcb, 0xc4, 0xec, 0x5e, 0x7e, 0xa3, 0x3b, 0x7c, 0x97, 0x3a, 0x5f, 0xb3,
- 0xe2, 0xc9, 0x40, 0x6f, 0x62, 0x82, 0xf7, 0x26, 0xd4, 0x7c, 0xf6, 0x62,
- 0x3e, 0xdf, 0x6a, 0xe5, 0xdd, 0xf3, 0xab, 0xb0, 0xbf, 0xc6, 0x71, 0xca,
- 0xa1, 0x65, 0x76, 0x06, 0x98, 0xdf, 0x8d, 0xd8, 0x99, 0x65, 0xbb, 0x25,
- 0x78, 0x64, 0xc5, 0xce, 0xa3, 0x5c, 0x9f, 0xf3, 0xaa, 0xf6, 0xff, 0x11,
- 0x6d, 0x51, 0xef, 0x88, 0xdf, 0xd6, 0xaf, 0xc3, 0xb6, 0x9c, 0xe7, 0x4e,
- 0xc4, 0xec, 0x3e, 0x5d, 0x90, 0xc3, 0x78, 0x3d, 0xbf, 0xa3, 0x6b, 0xf8,
- 0x1d, 0x22, 0xde, 0x04, 0xbf, 0xc8, 0xe3, 0xa0, 0xe6, 0xf1, 0x9b, 0xe8,
- 0xdf, 0x5f, 0x83, 0xbb, 0x50, 0x66, 0xea, 0x6f, 0x03, 0xdf, 0x0a, 0xdf,
- 0xc9, 0x73, 0xd6, 0x7f, 0xb0, 0xd5, 0x93, 0x35, 0xd2, 0xb3, 0x1e, 0xcf,
- 0x3b, 0xdb, 0xbc, 0x75, 0xd9, 0x0d, 0x7e, 0xf1, 0x4e, 0x67, 0xaf, 0xfa,
- 0x4e, 0x20, 0x33, 0xb6, 0x1b, 0xb2, 0xe3, 0xcf, 0xab, 0x17, 0x32, 0xc6,
- 0x33, 0x0b, 0xd6, 0xaf, 0xe7, 0x89, 0xe7, 0xf7, 0x82, 0xdc, 0x77, 0xb0,
- 0x39, 0x57, 0x60, 0xc2, 0x2f, 0xab, 0xef, 0x82, 0x60, 0x27, 0xdf, 0xb6,
- 0xf2, 0x5d, 0xd0, 0xf5, 0xd7, 0x78, 0xa0, 0xcd, 0xf3, 0x51, 0x26, 0x78,
- 0xd2, 0xa2, 0xdb, 0xec, 0x06, 0x3e, 0xe5, 0x5e, 0x6c, 0x32, 0xfe, 0xa0,
- 0xf8, 0xe3, 0xb8, 0xdb, 0x19, 0x73, 0x0e, 0xf6, 0xf7, 0x22, 0xbe, 0x56,
- 0xf7, 0x65, 0xe2, 0xbc, 0x7f, 0x93, 0x0c, 0xec, 0x56, 0x77, 0x27, 0x2e,
- 0xac, 0xfa, 0xb6, 0x2b, 0x25, 0x4f, 0xd5, 0x64, 0x65, 0xf8, 0x27, 0x62,
- 0x49, 0xe2, 0x26, 0xca, 0x0a, 0xfb, 0xdd, 0xcb, 0x79, 0xc6, 0x1f, 0x52,
- 0xf3, 0x34, 0x11, 0xc3, 0xf1, 0x9e, 0x83, 0x19, 0x28, 0xcf, 0x72, 0xdd,
- 0x91, 0x2e, 0xf0, 0xd9, 0x3f, 0x6b, 0x55, 0x76, 0x05, 0xe3, 0xb2, 0x8c,
- 0xb6, 0x91, 0xef, 0xd3, 0xfa, 0x2c, 0xf6, 0xc3, 0x6d, 0xbc, 0x0f, 0x90,
- 0x47, 0xd9, 0xdc, 0xc2, 0xfa, 0xb4, 0x7d, 0x5c, 0xc9, 0xc1, 0x23, 0xe0,
- 0xfb, 0x1f, 0xa3, 0xee, 0x63, 0x48, 0x39, 0xc7, 0xf4, 0xca, 0xba, 0x93,
- 0xdf, 0x1f, 0x90, 0x01, 0xc8, 0x05, 0xf3, 0x8f, 0x48, 0x51, 0xdd, 0x63,
- 0x42, 0x3a, 0xc7, 0x67, 0xda, 0x7a, 0x5b, 0xfb, 0x53, 0xd2, 0xb2, 0x5b,
- 0x7f, 0x4f, 0xe6, 0xcb, 0xd3, 0x2e, 0xdd, 0x6e, 0x6c, 0x85, 0x57, 0x0f,
- 0x5d, 0x83, 0x37, 0xc2, 0x2b, 0x78, 0xc3, 0x1b, 0xeb, 0xf1, 0x36, 0x1f,
- 0x6b, 0x78, 0x73, 0xf0, 0xb0, 0x86, 0x27, 0xe7, 0x7b, 0x25, 0x04, 0x39,
- 0x0e, 0xd6, 0xe4, 0x18, 0xb8, 0xc7, 0xd3, 0x99, 0x09, 0x9e, 0x21, 0x2a,
- 0x3e, 0x53, 0x0e, 0x29, 0xbf, 0x5c, 0xc7, 0xfa, 0xb5, 0x7e, 0xcf, 0x2f,
- 0x59, 0xeb, 0x97, 0xdb, 0x7c, 0xfc, 0xf0, 0x77, 0xd3, 0x83, 0x0b, 0x6d,
- 0x35, 0x3d, 0xb8, 0xf9, 0x37, 0xa4, 0x07, 0x6b, 0xe5, 0xb2, 0x5e, 0xa6,
- 0x4c, 0xc8, 0x13, 0xd7, 0x8b, 0xf2, 0x44, 0x39, 0x22, 0x2f, 0x69, 0x4f,
- 0x1b, 0x19, 0x3b, 0xc5, 0xaf, 0xa8, 0xef, 0x36, 0x26, 0x61, 0x83, 0xda,
- 0x02, 0x73, 0x73, 0x31, 0x29, 0x2e, 0xbc, 0x4f, 0xc9, 0xf4, 0x53, 0x55,
- 0xda, 0xa5, 0xeb, 0xcd, 0x7d, 0xb5, 0xcd, 0xcd, 0xaf, 0xb1, 0xb9, 0xf9,
- 0x15, 0x9b, 0xdb, 0xaa, 0xe3, 0xa5, 0xbf, 0x8b, 0xcd, 0x8d, 0xd5, 0x9d,
- 0xcb, 0xf8, 0x67, 0x32, 0x12, 0xc8, 0xf6, 0x44, 0x65, 0x07, 0xfc, 0xc8,
- 0xf0, 0xd4, 0x4e, 0xf9, 0x97, 0x53, 0x93, 0xea, 0x8e, 0xd2, 0x5f, 0x38,
- 0xc9, 0xf8, 0x03, 0x01, 0x57, 0x3e, 0x80, 0x78, 0x77, 0xbc, 0xa3, 0x41,
- 0x76, 0xbc, 0x4b, 0x9d, 0x35, 0x9a, 0xd9, 0x40, 0xbb, 0x70, 0x17, 0x3c,
- 0xe7, 0x58, 0x4e, 0x22, 0xc0, 0xfb, 0x6a, 0x8d, 0x32, 0x1e, 0x6b, 0x96,
- 0x9d, 0xc0, 0x4e, 0x85, 0x1b, 0x1c, 0xf5, 0x2d, 0x79, 0x46, 0x9d, 0xe5,
- 0xdc, 0xb2, 0xd9, 0x1b, 0x17, 0x7c, 0x68, 0x31, 0xe5, 0xab, 0xd5, 0x5b,
- 0xd4, 0x77, 0xd1, 0x17, 0x4a, 0xd5, 0xd6, 0xd5, 0x79, 0x3e, 0xff, 0x7b,
- 0xd4, 0x89, 0x81, 0x57, 0xf5, 0x77, 0x7f, 0x82, 0x8a, 0x9f, 0xc5, 0xb9,
- 0x31, 0x75, 0xa7, 0xea, 0x4a, 0x90, 0xfc, 0x52, 0x71, 0x53, 0x3c, 0x1b,
- 0x04, 0xc6, 0x99, 0x01, 0x92, 0xb6, 0x19, 0xf3, 0x69, 0xfc, 0x09, 0xfb,
- 0xbf, 0x47, 0x9d, 0xed, 0x2e, 0x81, 0x37, 0xae, 0xda, 0xfb, 0xcd, 0xc7,
- 0x88, 0xeb, 0x6b, 0xf7, 0x87, 0xaf, 0xc5, 0xf7, 0xde, 0xb7, 0x67, 0xfa,
- 0x1c, 0x42, 0xef, 0x15, 0xe9, 0x18, 0x5c, 0x9d, 0xab, 0xad, 0xf7, 0x7f,
- 0x29, 0x88, 0xf5, 0xf8, 0x7f, 0x0f, 0x88, 0xed, 0xac, 0xc3, 0x73, 0xe2,
- 0xa8, 0x38, 0x30, 0x43, 0xfe, 0x96, 0xb1, 0x4e, 0xd3, 0x71, 0xdf, 0x9f,
- 0x07, 0x3a, 0xcf, 0xd6, 0xc7, 0x81, 0xec, 0x23, 0xa2, 0xee, 0x63, 0xd4,
- 0xfe, 0x0f, 0x0e, 0xf7, 0x77, 0x32, 0x81, 0x7b, 0x4a, 0x93, 0x12, 0x3c,
- 0x3a, 0x2a, 0xa1, 0x69, 0xee, 0xa5, 0x67, 0xa4, 0x18, 0x73, 0xe5, 0x63,
- 0xce, 0xea, 0xd8, 0xa4, 0xd3, 0x58, 0x4b, 0xfb, 0x23, 0x32, 0x78, 0xf2,
- 0x31, 0x09, 0x1f, 0xe5, 0xbb, 0x55, 0xe7, 0x28, 0xb0, 0x47, 0x1b, 0x64,
- 0x2e, 0xc6, 0xfd, 0xe4, 0xb0, 0x3a, 0x97, 0x5e, 0x1e, 0x7b, 0x2d, 0x5c,
- 0x04, 0x56, 0xc8, 0x2b, 0xdb, 0x82, 0x74, 0x25, 0x96, 0x38, 0xbc, 0x99,
- 0x3a, 0x85, 0x18, 0x33, 0x30, 0x3e, 0x17, 0x56, 0xf7, 0x83, 0x96, 0x63,
- 0xac, 0x8b, 0xf8, 0xfd, 0x28, 0x71, 0x06, 0x6c, 0xc7, 0xa8, 0x44, 0x99,
- 0x0f, 0x1e, 0xad, 0xe1, 0x0c, 0xda, 0x84, 0x41, 0x27, 0x26, 0xa1, 0x53,
- 0xde, 0xdc, 0xf9, 0x8f, 0x95, 0x8c, 0x13, 0x3b, 0x25, 0x38, 0xcd, 0xe7,
- 0xfa, 0x78, 0x88, 0xd8, 0x1d, 0xbe, 0xe1, 0xec, 0x67, 0xd1, 0x1f, 0xdf,
- 0x65, 0xf4, 0x37, 0xba, 0xc8, 0x97, 0xff, 0xb6, 0xff, 0x43, 0x81, 0xb2,
- 0xff, 0xff, 0x01, 0xe6, 0x8e, 0x9a, 0x21, 0xc0, 0x4e, 0x00, 0x00, 0x00 };
+ 0xcd, 0x7c, 0x0d, 0x70, 0x5c, 0xd7, 0x75, 0xde, 0xd9, 0xb7, 0xbb, 0xc0,
+ 0x12, 0x04, 0xc1, 0x07, 0x68, 0x05, 0xad, 0x24, 0x24, 0xde, 0x87, 0x7d,
+ 0x00, 0x56, 0x22, 0xe4, 0x3c, 0x32, 0x10, 0x0d, 0xb9, 0x5b, 0x72, 0xbd,
+ 0x0b, 0x50, 0x90, 0x43, 0x23, 0x90, 0x84, 0x28, 0x6a, 0x86, 0xe3, 0x41,
+ 0x97, 0xa0, 0x62, 0x69, 0xdc, 0x86, 0x1e, 0x2b, 0x29, 0xe5, 0x2a, 0xe6,
+ 0x6a, 0x01, 0xca, 0x94, 0x02, 0x72, 0x61, 0x12, 0x04, 0xd5, 0x54, 0x6d,
+ 0xd7, 0x0b, 0x80, 0x54, 0xd4, 0x25, 0x97, 0x94, 0xfc, 0xa3, 0x99, 0xd8,
+ 0x21, 0x4a, 0xd1, 0x92, 0xed, 0x71, 0xa7, 0x92, 0xc7, 0x9d, 0xaa, 0x33,
+ 0x9a, 0x94, 0xa5, 0xe4, 0xda, 0xf1, 0x34, 0x8d, 0x6a, 0x7b, 0x1a, 0x25,
+ 0xb1, 0xf3, 0xfa, 0x7d, 0xf7, 0xdd, 0x0b, 0x2c, 0x20, 0x48, 0x56, 0x92,
+ 0xf1, 0x4c, 0x30, 0xb3, 0xbc, 0xef, 0xde, 0x77, 0x7f, 0xcf, 0x39, 0xf7,
+ 0x9c, 0xef, 0x9c, 0x7b, 0x1f, 0x77, 0x89, 0xb4, 0x88, 0xfe, 0xdb, 0x82,
+ 0xdf, 0xc0, 0xbf, 0xf8, 0x9d, 0xfd, 0xdb, 0x3f, 0xb8, 0xf3, 0x83, 0x78,
+ 0xdc, 0x69, 0xd9, 0x4d, 0x11, 0x96, 0x87, 0xf1, 0x8b, 0xe3, 0xb7, 0x43,
+ 0x3f, 0x6f, 0xf4, 0x67, 0xb3, 0x41, 0x48, 0x64, 0xe2, 0x87, 0x22, 0xa1,
+ 0x75, 0xef, 0x62, 0xef, 0xd2, 0xe6, 0xbd, 0xfe, 0xac, 0xf7, 0x59, 0xcf,
+ 0xfe, 0x7b, 0xf4, 0x6d, 0xfe, 0xc2, 0xba, 0xf9, 0x16, 0xfd, 0x93, 0x98,
+ 0x95, 0xb9, 0xfa, 0xb1, 0x9c, 0x2b, 0xb1, 0x70, 0xe6, 0xbb, 0xa3, 0xfb,
+ 0x5d, 0x91, 0x6c, 0x6d, 0x5b, 0x32, 0x2f, 0x3f, 0xf3, 0x8b, 0xf1, 0x88,
+ 0xb0, 0xfc, 0x97, 0x32, 0x3f, 0x3d, 0xfc, 0xb5, 0x0f, 0x39, 0x6f, 0x55,
+ 0xc2, 0x12, 0xb3, 0x33, 0x6f, 0x8b, 0xdd, 0x2b, 0xb1, 0x2e, 0xb4, 0x79,
+ 0xba, 0xef, 0x59, 0x4b, 0xda, 0x4c, 0x5f, 0xf6, 0x44, 0x38, 0x23, 0x63,
+ 0x93, 0x33, 0x87, 0x7d, 0xcb, 0x95, 0xe2, 0x4d, 0x19, 0x37, 0x59, 0x92,
+ 0xd6, 0xc1, 0xe9, 0x81, 0x0f, 0x09, 0xf2, 0x63, 0x93, 0xb5, 0x98, 0xe4,
+ 0xea, 0xc5, 0x56, 0xcb, 0x75, 0x91, 0xc6, 0x8a, 0x37, 0x67, 0x24, 0xd6,
+ 0x94, 0x79, 0xba, 0xf9, 0x25, 0x97, 0xe3, 0x27, 0x46, 0x73, 0xee, 0xcd,
+ 0x12, 0x71, 0x7d, 0x7f, 0x1a, 0xe3, 0xef, 0xa9, 0xfd, 0xcc, 0x7f, 0x2c,
+ 0x12, 0x8c, 0x6d, 0x65, 0x8a, 0x61, 0xa6, 0xa1, 0x4c, 0x72, 0xb4, 0xbb,
+ 0xa6, 0xf2, 0x4d, 0x41, 0xde, 0x35, 0xf9, 0x2d, 0x41, 0x7e, 0x42, 0xe7,
+ 0xed, 0x96, 0x60, 0x2d, 0xb1, 0x4d, 0x58, 0x4b, 0x2c, 0x92, 0x19, 0xda,
+ 0x84, 0x3e, 0x63, 0xd1, 0x8c, 0x9b, 0x59, 0x52, 0xf5, 0x3e, 0xa1, 0xeb,
+ 0x1d, 0x8c, 0x06, 0xed, 0x26, 0x47, 0x7b, 0x6b, 0x4c, 0x1f, 0x1e, 0xed,
+ 0x51, 0xe9, 0xa3, 0xa3, 0x29, 0x95, 0x16, 0x55, 0xbd, 0x50, 0x66, 0x7a,
+ 0xd4, 0x55, 0x69, 0x97, 0x2e, 0x4f, 0x8f, 0x26, 0x55, 0xda, 0xaf, 0x53,
+ 0x4f, 0xa7, 0x03, 0x3a, 0x1d, 0xd4, 0x69, 0x46, 0xa7, 0x59, 0x9d, 0x0e,
+ 0xe9, 0x7e, 0x46, 0x74, 0x7e, 0xaf, 0x4e, 0xc7, 0x74, 0x3a, 0xae, 0xd3,
+ 0xfb, 0x75, 0xba, 0x4f, 0xcf, 0xeb, 0x93, 0x3a, 0x7f, 0x50, 0xcf, 0xef,
+ 0x10, 0xe6, 0xf1, 0x93, 0x26, 0x2d, 0xbf, 0x58, 0x67, 0x52, 0xf6, 0xcf,
+ 0xc4, 0xa4, 0x54, 0x0e, 0x4b, 0x5e, 0xf1, 0xb5, 0x3f, 0x2a, 0x2d, 0x31,
+ 0x99, 0xaa, 0xc7, 0xe4, 0xaa, 0x12, 0xdb, 0x1f, 0xf8, 0x5f, 0xeb, 0xb3,
+ 0xe5, 0x42, 0x3d, 0x2e, 0x97, 0xea, 0x12, 0x1a, 0xeb, 0xdb, 0x24, 0xd6,
+ 0x89, 0x9b, 0x24, 0x6b, 0x87, 0x24, 0xac, 0xe8, 0x9b, 0x94, 0xdc, 0x4c,
+ 0x27, 0xf2, 0x4e, 0x42, 0x64, 0x32, 0x1a, 0xf0, 0x33, 0x26, 0xe1, 0x79,
+ 0xf2, 0x67, 0x7e, 0xf4, 0xa5, 0xb9, 0x84, 0x44, 0x8e, 0x27, 0xd1, 0x7f,
+ 0xab, 0x44, 0xe7, 0xa5, 0x2b, 0x2c, 0x3d, 0x89, 0x07, 0x50, 0x63, 0xa8,
+ 0x16, 0x91, 0xe1, 0x5a, 0x08, 0x3c, 0x8b, 0x41, 0x5e, 0x5a, 0xf1, 0xb3,
+ 0xf1, 0x8b, 0xe3, 0x97, 0xc0, 0xef, 0x09, 0xf4, 0xd3, 0x25, 0xf9, 0x1a,
+ 0xfb, 0xc4, 0xb8, 0x65, 0x8c, 0x5f, 0x76, 0xec, 0x09, 0xe1, 0x9c, 0x12,
+ 0xf2, 0xb5, 0xbe, 0x60, 0x4e, 0x97, 0xea, 0xb1, 0x50, 0xee, 0xb4, 0x1c,
+ 0xcc, 0x7b, 0x92, 0xb4, 0xdc, 0x16, 0x29, 0xd8, 0xa1, 0xe4, 0x64, 0xba,
+ 0x43, 0x8a, 0xe3, 0x78, 0x57, 0x96, 0xac, 0x85, 0xbe, 0x0b, 0xb6, 0x4c,
+ 0x04, 0xef, 0x58, 0xf6, 0x37, 0xd8, 0xb7, 0x8e, 0x4d, 0x01, 0xbe, 0x54,
+ 0xfe, 0x63, 0x3c, 0xb3, 0xaf, 0xff, 0x17, 0x0e, 0xe6, 0xfc, 0xd7, 0xc8,
+ 0xb3, 0xfc, 0xcb, 0x5b, 0x83, 0x3c, 0x9f, 0x59, 0xd7, 0x8c, 0x69, 0xd6,
+ 0xca, 0xb1, 0xfb, 0xb0, 0x5e, 0x8e, 0xbf, 0xb2, 0x5e, 0xcc, 0xa3, 0x35,
+ 0x94, 0x3f, 0x9d, 0x94, 0x23, 0xe5, 0x5d, 0x92, 0xf3, 0x7c, 0x7f, 0xbf,
+ 0x27, 0x71, 0x4b, 0x7a, 0xec, 0x3c, 0xde, 0x56, 0x6b, 0x12, 0xca, 0x95,
+ 0x0d, 0x3d, 0xd8, 0x6f, 0x04, 0x65, 0x9d, 0xa8, 0xdf, 0x16, 0x1a, 0x3a,
+ 0x8d, 0xb9, 0x67, 0x48, 0x17, 0xc8, 0xae, 0xd7, 0x93, 0x98, 0xc4, 0x78,
+ 0x0b, 0xb5, 0x1e, 0xef, 0xb2, 0xd8, 0xe8, 0xb3, 0x03, 0x75, 0x48, 0x23,
+ 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x2b, 0xda, 0xc6, 0xf1, 0x8e, 0x73, 0xf2,
+ 0xfd, 0x9c, 0x67, 0x33, 0x2f, 0x15, 0xd0, 0xad, 0x42, 0xba, 0xb5, 0x74,
+ 0xc9, 0x99, 0x1a, 0xc7, 0xd8, 0x68, 0xde, 0xb7, 0xfe, 0x23, 0x9b, 0x77,
+ 0x02, 0xfd, 0xc7, 0x91, 0x6e, 0x0e, 0xe5, 0x4e, 0xfa, 0x18, 0x3f, 0x81,
+ 0xe7, 0x8d, 0xd6, 0x70, 0x55, 0xcb, 0x60, 0x02, 0x73, 0x8f, 0xcb, 0x45,
+ 0x25, 0x87, 0x9b, 0x25, 0x0c, 0x39, 0x24, 0x8f, 0xdb, 0xe7, 0x6f, 0x97,
+ 0x42, 0xdc, 0x49, 0x52, 0x87, 0x76, 0xef, 0xd8, 0x84, 0x35, 0x6a, 0x6d,
+ 0x78, 0x3c, 0x0e, 0x39, 0xbc, 0xdc, 0x6e, 0xa1, 0xc4, 0x12, 0xc7, 0xfe,
+ 0x2d, 0x29, 0x4a, 0x7e, 0xf1, 0x91, 0x90, 0xb4, 0x58, 0xa8, 0xb7, 0x2d,
+ 0x14, 0xd0, 0x80, 0xf4, 0xc9, 0x82, 0x3e, 0x21, 0x09, 0xf6, 0x73, 0x56,
+ 0xba, 0x6b, 0xea, 0x7d, 0xd2, 0x52, 0xef, 0x86, 0xf0, 0x2e, 0x22, 0xa9,
+ 0x1d, 0xe6, 0xfd, 0x10, 0xde, 0xdf, 0x24, 0x13, 0x36, 0xe6, 0x52, 0x7e,
+ 0xc1, 0xca, 0x61, 0x8e, 0x1f, 0x89, 0xa8, 0xb5, 0xa2, 0xee, 0x44, 0x43,
+ 0x3f, 0x13, 0xa8, 0xf7, 0x34, 0xc6, 0xc2, 0x7c, 0xcb, 0x49, 0xcc, 0xa5,
+ 0x13, 0x73, 0xe1, 0x1c, 0x8b, 0x56, 0xae, 0x1e, 0x41, 0x7e, 0xda, 0xca,
+ 0x9f, 0x3d, 0x8a, 0x67, 0xb1, 0xad, 0xcc, 0x0b, 0x4c, 0xd1, 0x7e, 0x5f,
+ 0x43, 0xfb, 0x7d, 0x68, 0xcf, 0x31, 0xd8, 0x3e, 0x90, 0xff, 0xa2, 0x92,
+ 0xc5, 0xe4, 0x7b, 0xd0, 0x23, 0xfc, 0xf7, 0xa0, 0xc7, 0xd7, 0x34, 0x3d,
+ 0x7e, 0x26, 0xbf, 0x78, 0x7a, 0x5c, 0xfd, 0x05, 0xd1, 0x43, 0xa4, 0x70,
+ 0x92, 0xcf, 0x11, 0x29, 0x2a, 0xbd, 0xc5, 0x7d, 0x4b, 0x79, 0xa7, 0xce,
+ 0x22, 0x9d, 0x28, 0xc7, 0xd8, 0x03, 0xf5, 0x08, 0xd2, 0x67, 0x90, 0x6e,
+ 0x0e, 0x8d, 0x9d, 0x7c, 0x13, 0xfc, 0xf7, 0xc5, 0xde, 0x61, 0xec, 0x47,
+ 0x31, 0x61, 0x4b, 0x97, 0xd8, 0x1f, 0x84, 0xf1, 0xee, 0x74, 0xec, 0x82,
+ 0x7c, 0x9f, 0xef, 0x43, 0xc6, 0xce, 0xe7, 0x66, 0x36, 0xbd, 0x9d, 0x55,
+ 0x4f, 0x51, 0xd2, 0x33, 0x6b, 0x65, 0x22, 0xa1, 0x7c, 0x39, 0x39, 0x61,
+ 0x65, 0xe2, 0xd0, 0x53, 0xcc, 0x0f, 0x86, 0x82, 0x39, 0x0f, 0xa0, 0xae,
+ 0xd1, 0x59, 0x66, 0xee, 0x03, 0x98, 0xfb, 0x7a, 0xdd, 0x95, 0xc5, 0x5c,
+ 0x38, 0x07, 0xce, 0xab, 0xa8, 0x75, 0x10, 0xfb, 0x39, 0xa4, 0xfa, 0x09,
+ 0x67, 0x06, 0x85, 0xb6, 0xb4, 0x30, 0xc3, 0x7d, 0xc0, 0x76, 0xec, 0x2b,
+ 0xd0, 0xc9, 0x85, 0x9a, 0xe9, 0xa3, 0xd8, 0xd8, 0x07, 0xe6, 0x23, 0x5b,
+ 0x2d, 0x37, 0x0a, 0xde, 0xb3, 0xab, 0xa3, 0x78, 0xf7, 0xb4, 0xe4, 0xce,
+ 0xde, 0x61, 0x61, 0x0d, 0xe8, 0x97, 0x34, 0x1a, 0x83, 0xce, 0xe6, 0x3e,
+ 0x8b, 0x49, 0x3e, 0xce, 0xb2, 0x49, 0x3d, 0x6e, 0x44, 0xb2, 0x2a, 0x9f,
+ 0x6b, 0x5b, 0x9d, 0xc7, 0x0b, 0x7a, 0x3d, 0x19, 0xac, 0x87, 0x73, 0x30,
+ 0x6b, 0xc9, 0x34, 0xac, 0xc5, 0xd0, 0x9a, 0xb4, 0xb0, 0xa1, 0xe3, 0x63,
+ 0xda, 0x86, 0xb0, 0xdd, 0x74, 0x03, 0xef, 0xa6, 0xd1, 0x86, 0xb4, 0x47,
+ 0x9d, 0x75, 0x76, 0x85, 0x36, 0x65, 0x08, 0xfd, 0x94, 0xe6, 0x2c, 0xc9,
+ 0x7b, 0xb0, 0xd9, 0xde, 0xcd, 0x5a, 0x5e, 0x57, 0x65, 0x29, 0xba, 0xa1,
+ 0x2c, 0x3d, 0x66, 0x05, 0xfa, 0x1a, 0xb6, 0x05, 0xf6, 0x67, 0x6a, 0xce,
+ 0x49, 0x1b, 0x59, 0x2a, 0xcd, 0xbc, 0x1f, 0x59, 0x32, 0xed, 0x63, 0x90,
+ 0x5d, 0x33, 0xc6, 0xfa, 0x39, 0x9b, 0x3a, 0x98, 0x63, 0x79, 0x48, 0x63,
+ 0x15, 0x8e, 0x13, 0xd8, 0x86, 0xca, 0x1a, 0xdb, 0x70, 0x14, 0x6d, 0x25,
+ 0x94, 0xef, 0x6b, 0x95, 0x03, 0x73, 0xa6, 0x8f, 0xa3, 0x4a, 0x66, 0x27,
+ 0x67, 0x1c, 0x7b, 0x38, 0x2c, 0xd9, 0xe1, 0xd9, 0x41, 0x19, 0xaa, 0x77,
+ 0x81, 0xa7, 0x6f, 0xfb, 0xb0, 0x9d, 0x1f, 0x8c, 0x8a, 0x0b, 0xbd, 0x88,
+ 0x35, 0x0f, 0x80, 0xc6, 0xf5, 0xa8, 0x58, 0x19, 0x0f, 0x69, 0x23, 0xd6,
+ 0x8a, 0x44, 0x86, 0xd7, 0xe4, 0x9b, 0x50, 0x07, 0x7d, 0x0f, 0xac, 0xaf,
+ 0x07, 0xf9, 0x04, 0x6d, 0x73, 0xde, 0xcf, 0x7c, 0xd8, 0x61, 0x6d, 0xb3,
+ 0x58, 0x4a, 0x3d, 0x61, 0x74, 0xc4, 0x6f, 0x60, 0x7f, 0xab, 0xbd, 0x50,
+ 0x04, 0x76, 0x41, 0x1f, 0xa2, 0xe4, 0xb4, 0x54, 0x7f, 0xce, 0xec, 0x7b,
+ 0x55, 0xbe, 0x67, 0x80, 0xb2, 0x57, 0x01, 0x26, 0xe0, 0x9a, 0x16, 0xd5,
+ 0x5e, 0xcf, 0xdb, 0x71, 0x99, 0x2e, 0x73, 0x3d, 0x8b, 0x92, 0xaa, 0xfd,
+ 0x7b, 0xc9, 0x9f, 0x15, 0xf9, 0xd6, 0x0c, 0xeb, 0x7d, 0x55, 0xd7, 0x7b,
+ 0x01, 0xf5, 0x52, 0xc9, 0xa1, 0x90, 0x03, 0x3b, 0xe0, 0x60, 0x9b, 0x6c,
+ 0x4b, 0x22, 0xb5, 0x47, 0xf0, 0x1b, 0xa2, 0x91, 0x41, 0xbd, 0x00, 0xfb,
+ 0xbc, 0x00, 0x7a, 0x88, 0xdc, 0x5d, 0x6e, 0x86, 0x3e, 0xf9, 0x9f, 0x98,
+ 0x6b, 0x5c, 0x9e, 0xc4, 0x3a, 0x5e, 0x9a, 0x21, 0xbe, 0xfa, 0xaa, 0x2c,
+ 0xcd, 0x10, 0x6f, 0xbd, 0x20, 0xd3, 0x33, 0x29, 0xef, 0x5b, 0xa0, 0xf3,
+ 0x19, 0xe1, 0x5a, 0xb6, 0x79, 0x48, 0x81, 0x05, 0x9d, 0xe4, 0xe3, 0xd0,
+ 0x67, 0x7d, 0x3b, 0x82, 0xfe, 0x7a, 0x74, 0x7f, 0x6e, 0xcd, 0x91, 0xab,
+ 0x36, 0xf5, 0xd3, 0x3b, 0xf7, 0x78, 0x4e, 0xef, 0xf1, 0x31, 0xaf, 0x4b,
+ 0x2c, 0xec, 0xeb, 0xec, 0x78, 0x11, 0xd6, 0x8f, 0xfb, 0xfa, 0x6d, 0x6b,
+ 0x15, 0xff, 0x24, 0x80, 0x59, 0x1d, 0x65, 0xef, 0xfe, 0x6e, 0x7b, 0xbc,
+ 0x71, 0x6f, 0x73, 0xfc, 0x36, 0xb4, 0x89, 0x20, 0x7d, 0xef, 0x7d, 0x8d,
+ 0x3e, 0x1a, 0xda, 0x0e, 0x72, 0x5f, 0xa0, 0xcd, 0xbf, 0x05, 0x2d, 0x48,
+ 0xff, 0xf7, 0xb3, 0x9f, 0x6f, 0x0b, 0xbf, 0xaf, 0xfd, 0x3c, 0xfe, 0x5e,
+ 0xfb, 0xb9, 0x71, 0x2f, 0x5f, 0x20, 0x2d, 0x30, 0xb6, 0xcc, 0x06, 0xb2,
+ 0xd5, 0x03, 0x5a, 0x27, 0x21, 0xa7, 0x98, 0x43, 0xf9, 0x6f, 0xfd, 0x6c,
+ 0x24, 0xc0, 0x73, 0x81, 0x3c, 0xb1, 0x9e, 0xa9, 0x13, 0xe8, 0xde, 0xa1,
+ 0xfa, 0x55, 0xa5, 0x67, 0x2f, 0x2a, 0x3d, 0xeb, 0x1c, 0x2d, 0x0a, 0xe5,
+ 0xed, 0xf6, 0x30, 0xe9, 0x7e, 0xc1, 0xfb, 0x7d, 0xcc, 0xd1, 0x49, 0x26,
+ 0xad, 0x9e, 0xa2, 0x65, 0xfd, 0xbe, 0x1c, 0x5c, 0x78, 0x58, 0x0e, 0x96,
+ 0xd9, 0xc7, 0x2e, 0xbc, 0x77, 0x51, 0xb6, 0x09, 0xba, 0x96, 0x3a, 0xfd,
+ 0xed, 0x50, 0x30, 0x96, 0x05, 0xfb, 0xb5, 0x1c, 0xba, 0xbb, 0x7e, 0x25,
+ 0x94, 0x5b, 0xe0, 0xde, 0x45, 0x79, 0xbd, 0x51, 0xe7, 0x1b, 0x7d, 0xff,
+ 0x0a, 0xc6, 0x34, 0x72, 0xee, 0x35, 0xe8, 0xd4, 0x69, 0xe2, 0x41, 0x2b,
+ 0xe7, 0x91, 0x7f, 0xb4, 0x2d, 0x8f, 0xd8, 0xc1, 0xfa, 0x0f, 0x81, 0x66,
+ 0xb4, 0x49, 0xa4, 0x21, 0xec, 0x61, 0x84, 0xfb, 0x97, 0xcf, 0xe2, 0x87,
+ 0x33, 0xdc, 0x83, 0x12, 0x09, 0x67, 0x80, 0x7f, 0xe3, 0xac, 0xb3, 0x0b,
+ 0x73, 0x0e, 0xf6, 0x77, 0x71, 0x65, 0x7f, 0x77, 0xcb, 0xc4, 0x42, 0x16,
+ 0x3a, 0x20, 0xaf, 0xfa, 0x89, 0xba, 0x6b, 0x6c, 0x0b, 0xea, 0x27, 0x35,
+ 0x1f, 0x36, 0x1b, 0xfd, 0x87, 0x32, 0x4f, 0x97, 0x35, 0x35, 0x94, 0x19,
+ 0x7e, 0x15, 0x30, 0x16, 0x6d, 0xc4, 0x88, 0xc6, 0x3d, 0xbe, 0x9f, 0x27,
+ 0x9f, 0xfb, 0xf7, 0x09, 0xf7, 0xc4, 0xa5, 0x72, 0xd1, 0x0e, 0x2b, 0xd9,
+ 0x5c, 0xfc, 0xd8, 0xaa, 0x6c, 0x02, 0x27, 0xab, 0x5e, 0x48, 0x5b, 0xce,
+ 0xa5, 0x15, 0xb4, 0x1c, 0xc2, 0x1a, 0x40, 0xb3, 0xce, 0x10, 0xe8, 0xd6,
+ 0x2a, 0x85, 0xfa, 0x2e, 0xfd, 0x8e, 0xe5, 0x11, 0x19, 0x8b, 0x1b, 0x3b,
+ 0xf4, 0xe7, 0x5b, 0x03, 0xac, 0x8b, 0x3a, 0xe5, 0xff, 0x1d, 0x0e, 0x64,
+ 0xdf, 0x96, 0xc2, 0xe9, 0x21, 0xc8, 0x18, 0xb1, 0xd8, 0x26, 0x2d, 0x63,
+ 0xec, 0x07, 0xe5, 0x67, 0x29, 0xc3, 0xa2, 0xf5, 0xe7, 0x20, 0xd2, 0x1f,
+ 0x87, 0x69, 0xb7, 0xd9, 0x57, 0xe1, 0xb4, 0x69, 0x6f, 0xe6, 0xd1, 0xb1,
+ 0xd2, 0xcf, 0x98, 0x67, 0x49, 0x58, 0xcd, 0x05, 0x65, 0x67, 0xd7, 0xce,
+ 0xc5, 0xea, 0x34, 0x73, 0x79, 0x34, 0x1c, 0xcc, 0xa5, 0xa3, 0xa1, 0xaf,
+ 0x78, 0xc3, 0x5c, 0x9a, 0x30, 0x97, 0xb8, 0xb2, 0x37, 0x9c, 0xcb, 0x05,
+ 0xf0, 0xbe, 0x70, 0xf6, 0xc6, 0xeb, 0x82, 0x36, 0xf1, 0x86, 0x36, 0x9d,
+ 0xeb, 0xda, 0xb0, 0xbe, 0x19, 0x03, 0xef, 0xce, 0x5e, 0xdd, 0x1c, 0xb4,
+ 0x61, 0xbd, 0x26, 0xd8, 0x37, 0xbe, 0x53, 0x7e, 0x5b, 0x83, 0xfc, 0x1f,
+ 0x84, 0xfc, 0x1b, 0xb9, 0x32, 0xb6, 0xd9, 0xf0, 0x75, 0x53, 0x28, 0x7f,
+ 0xf2, 0x03, 0xf4, 0x3d, 0x43, 0x63, 0xe5, 0x25, 0xf8, 0x0f, 0x49, 0x29,
+ 0xa4, 0xe1, 0x9b, 0xd8, 0x83, 0xa2, 0xfc, 0x89, 0x34, 0x7c, 0x16, 0x7b,
+ 0xb3, 0xc2, 0x5b, 0x85, 0x74, 0xbf, 0xb6, 0x59, 0xdf, 0x97, 0x09, 0xc8,
+ 0x70, 0x21, 0x9d, 0xc6, 0x78, 0xd0, 0xd5, 0x6e, 0x2f, 0xda, 0x71, 0xdc,
+ 0xb7, 0x22, 0xb4, 0x23, 0x17, 0xca, 0x1f, 0x47, 0x7e, 0x33, 0xde, 0xff,
+ 0xa9, 0x9e, 0x4f, 0x1b, 0xea, 0x7c, 0x5a, 0xf9, 0x26, 0x17, 0x54, 0x1d,
+ 0xf6, 0x71, 0x19, 0xf9, 0x3b, 0x50, 0x07, 0x9b, 0x1c, 0x12, 0x68, 0xb9,
+ 0x3b, 0xf1, 0xfb, 0x36, 0xca, 0x3e, 0x84, 0xb2, 0x2f, 0xa3, 0xec, 0x76,
+ 0xe4, 0x5f, 0x5c, 0xd7, 0xef, 0x36, 0xe4, 0x1f, 0xc3, 0x7b, 0xac, 0xd3,
+ 0xfe, 0x06, 0xde, 0xdf, 0x81, 0xdf, 0x97, 0xd7, 0xd5, 0xf9, 0x37, 0xeb,
+ 0xf2, 0xc6, 0x2f, 0xf8, 0x63, 0x2d, 0x73, 0xc6, 0x27, 0x08, 0xf4, 0xe8,
+ 0x54, 0xb9, 0x35, 0x34, 0x7c, 0x3a, 0x16, 0xda, 0x73, 0x9a, 0x78, 0x23,
+ 0xa2, 0xfc, 0x80, 0x08, 0xfc, 0x80, 0xe9, 0x39, 0x3a, 0x88, 0x11, 0x94,
+ 0x11, 0xbb, 0xcb, 0x40, 0x93, 0xf4, 0x78, 0x57, 0xb0, 0x4f, 0x0a, 0xb5,
+ 0x2e, 0xe4, 0xb9, 0x7f, 0x20, 0x63, 0xb5, 0x16, 0xc8, 0x75, 0x4f, 0xba,
+ 0x0a, 0x19, 0x3b, 0x00, 0xdf, 0x64, 0x02, 0x36, 0x70, 0xa2, 0xd6, 0x25,
+ 0x0f, 0xd4, 0xae, 0x44, 0x02, 0x39, 0x32, 0x63, 0x3f, 0xbd, 0x6e, 0xec,
+ 0x18, 0xfd, 0x0a, 0xc8, 0xfd, 0xfc, 0xe8, 0xfe, 0x39, 0x8e, 0x6f, 0x75,
+ 0x47, 0xa4, 0x0d, 0x73, 0xa0, 0xff, 0x28, 0xbd, 0x11, 0xe9, 0x49, 0x4e,
+ 0x29, 0x07, 0xb5, 0x28, 0xe1, 0x4c, 0x0f, 0xec, 0x83, 0xca, 0xc3, 0x5f,
+ 0x84, 0xbe, 0xab, 0xad, 0xfa, 0x91, 0xc3, 0x2b, 0x7e, 0x64, 0x17, 0xfc,
+ 0xcc, 0x17, 0x23, 0xc1, 0xde, 0x6f, 0x85, 0x6e, 0xb8, 0x9e, 0x38, 0x47,
+ 0xe9, 0x77, 0xee, 0xf1, 0x9c, 0xd7, 0xae, 0xf3, 0x94, 0x65, 0xe8, 0x0b,
+ 0x2b, 0xaa, 0xf4, 0x95, 0x58, 0x78, 0x37, 0x40, 0xf9, 0x45, 0x7e, 0xa1,
+ 0x71, 0x7f, 0xff, 0x0e, 0xf6, 0x32, 0xdf, 0x1b, 0x39, 0xc3, 0x3f, 0x4a,
+ 0xc6, 0x18, 0xbf, 0xf8, 0x8b, 0x75, 0x6b, 0x3b, 0xb0, 0x6e, 0x6d, 0x91,
+ 0x15, 0xba, 0x72, 0x8d, 0x51, 0xac, 0x71, 0x69, 0x8e, 0xb4, 0xed, 0x87,
+ 0x7c, 0x8a, 0x1b, 0x11, 0xca, 0x31, 0xf5, 0x6a, 0x1b, 0x74, 0x35, 0x69,
+ 0x17, 0x11, 0xc6, 0x3c, 0x26, 0xb0, 0xa6, 0x09, 0xac, 0x69, 0xa2, 0x81,
+ 0x8e, 0x07, 0x56, 0xd6, 0x64, 0xe6, 0x8d, 0x7a, 0x6a, 0xbf, 0xf1, 0x99,
+ 0x3f, 0xe8, 0xa9, 0x36, 0x83, 0x69, 0x38, 0x97, 0xdc, 0xba, 0xb9, 0x90,
+ 0x16, 0x9c, 0xcb, 0xca, 0x3c, 0xe2, 0x8c, 0x1c, 0x1d, 0xac, 0x91, 0xaf,
+ 0x1c, 0x73, 0xaf, 0x4c, 0x96, 0x3f, 0xa0, 0xe7, 0xd1, 0x8a, 0x79, 0x8c,
+ 0x41, 0x6f, 0x70, 0x3c, 0xec, 0xff, 0xda, 0x38, 0x9e, 0xe3, 0xe4, 0xbf,
+ 0x9e, 0x8b, 0xa1, 0x05, 0xfd, 0xb6, 0x84, 0xc6, 0xe2, 0x86, 0x5e, 0xae,
+ 0xc2, 0x0e, 0x97, 0xca, 0xff, 0x6d, 0x6b, 0x30, 0xb7, 0xa4, 0x9e, 0x47,
+ 0x40, 0x63, 0x60, 0x78, 0x60, 0xa9, 0xbc, 0xd6, 0x07, 0x8d, 0x74, 0xbd,
+ 0xbb, 0x49, 0xeb, 0x2b, 0xc8, 0x40, 0x63, 0xf9, 0xa7, 0x9a, 0x56, 0xeb,
+ 0x32, 0x3f, 0xaf, 0xf3, 0x5b, 0x42, 0xc3, 0x27, 0x4d, 0xd9, 0xd5, 0xa6,
+ 0x77, 0xf6, 0xf7, 0xd5, 0x26, 0xa3, 0x3f, 0x2e, 0x95, 0x1b, 0xf7, 0xfb,
+ 0x21, 0x2b, 0xb0, 0x3b, 0x45, 0x29, 0x0d, 0x64, 0xa1, 0xe7, 0x68, 0x7f,
+ 0x86, 0xac, 0xc0, 0xf6, 0xb0, 0xce, 0x21, 0x85, 0x1d, 0x23, 0x99, 0x2a,
+ 0xe5, 0x1e, 0xb4, 0xac, 0x8d, 0xe6, 0x66, 0x7c, 0x7f, 0xca, 0x5b, 0x4e,
+ 0x84, 0x85, 0x7a, 0x99, 0xb8, 0x8d, 0xe5, 0xcf, 0xa0, 0x1c, 0x76, 0xbd,
+ 0x3e, 0x26, 0x6c, 0xb7, 0x31, 0x3e, 0x4b, 0x6a, 0x7c, 0x16, 0x00, 0xbb,
+ 0x9c, 0xc2, 0x53, 0x4f, 0x8d, 0xc2, 0xfe, 0xeb, 0xe7, 0xa7, 0xf1, 0x9c,
+ 0x6c, 0xc4, 0x80, 0xe8, 0xb7, 0x32, 0x9a, 0x9b, 0x53, 0x76, 0x00, 0xfb,
+ 0x81, 0xbc, 0x3a, 0x03, 0x5e, 0x85, 0x64, 0x5a, 0xd9, 0x04, 0xce, 0x83,
+ 0xed, 0x2a, 0xa3, 0xdd, 0x8b, 0x4c, 0xab, 0xa3, 0xee, 0x62, 0x58, 0x0e,
+ 0xc4, 0x83, 0xb6, 0xcc, 0x27, 0x17, 0x8d, 0xdd, 0x6e, 0x91, 0x68, 0x86,
+ 0xba, 0xcd, 0x49, 0x03, 0x87, 0x62, 0x3d, 0x47, 0x47, 0xa7, 0x5d, 0xda,
+ 0xcb, 0xff, 0x03, 0x79, 0x68, 0x91, 0x26, 0x25, 0x27, 0x4f, 0xea, 0xb1,
+ 0xce, 0x60, 0xac, 0xad, 0x98, 0x6b, 0x18, 0x3a, 0x32, 0x92, 0xc0, 0x38,
+ 0x87, 0x2d, 0x77, 0x1b, 0xc6, 0xa3, 0xd7, 0xd8, 0x25, 0x53, 0x75, 0xca,
+ 0xfa, 0xdf, 0x44, 0x56, 0x7d, 0xc5, 0x13, 0x68, 0x67, 0x7c, 0x14, 0x8e,
+ 0x57, 0x05, 0x46, 0x69, 0xc1, 0x3a, 0x1c, 0x3b, 0x17, 0x86, 0xed, 0x9b,
+ 0x33, 0x75, 0x38, 0xa7, 0xe3, 0xa3, 0xa9, 0xc5, 0x14, 0xfa, 0xea, 0xa2,
+ 0xec, 0x41, 0xe6, 0xc2, 0xf8, 0xb1, 0x6f, 0xb6, 0x83, 0x4e, 0x1e, 0x34,
+ 0x76, 0x7c, 0xb5, 0xbd, 0x69, 0xd7, 0xbd, 0x38, 0xa2, 0x65, 0xf7, 0xaf,
+ 0xfc, 0xec, 0x38, 0xdf, 0x37, 0xc6, 0x07, 0x4c, 0x3b, 0x53, 0x27, 0xac,
+ 0xf5, 0xf1, 0x7d, 0xd1, 0xd5, 0x79, 0x3e, 0x35, 0x1a, 0xf8, 0x31, 0x12,
+ 0xc9, 0xf7, 0x0d, 0x6a, 0xbe, 0x3d, 0x8d, 0x32, 0xb6, 0xc7, 0x5e, 0xa8,
+ 0x37, 0x62, 0xf0, 0xa0, 0xdf, 0x22, 0xb0, 0x47, 0xa9, 0xdc, 0x04, 0x5d,
+ 0x93, 0x6d, 0x0f, 0x62, 0x22, 0xef, 0x85, 0xbb, 0xc1, 0x53, 0xf4, 0x53,
+ 0x5a, 0x69, 0xab, 0xe2, 0x93, 0xa3, 0x2f, 0xa1, 0xff, 0x23, 0xe5, 0x60,
+ 0xaf, 0x05, 0x74, 0x20, 0x5e, 0x0a, 0xc9, 0x92, 0x9b, 0x84, 0x7f, 0x47,
+ 0x3b, 0x94, 0x94, 0x97, 0x5d, 0x83, 0x9f, 0x88, 0x9d, 0x50, 0xbf, 0xce,
+ 0xf9, 0x70, 0xdd, 0x27, 0xb0, 0x6e, 0x5f, 0x66, 0xbd, 0x40, 0x3e, 0xfa,
+ 0xb0, 0x37, 0xff, 0x53, 0xc4, 0x39, 0x4a, 0x3f, 0xe0, 0x6a, 0xa4, 0x71,
+ 0x5d, 0xc6, 0x9e, 0x3d, 0xa5, 0x63, 0x93, 0x27, 0x34, 0x2f, 0x2b, 0xe0,
+ 0xe5, 0xb6, 0xa4, 0x2d, 0xbd, 0x98, 0x3b, 0xea, 0xf4, 0xf7, 0x00, 0x8f,
+ 0xd3, 0xd7, 0x4b, 0x60, 0x3e, 0x36, 0x64, 0x7d, 0xab, 0xb6, 0xfb, 0x9f,
+ 0x89, 0x52, 0x5f, 0xb4, 0xab, 0xb8, 0xe7, 0x09, 0x25, 0x6b, 0x81, 0xec,
+ 0x85, 0xf5, 0x7b, 0xc3, 0xef, 0x30, 0xcd, 0xae, 0xac, 0xc6, 0xf9, 0x8c,
+ 0xae, 0x66, 0xfd, 0x39, 0xd4, 0x0f, 0x61, 0x4d, 0xbe, 0x3f, 0xa9, 0xe6,
+ 0x3b, 0x0f, 0x5e, 0x87, 0xa5, 0xb4, 0x22, 0x8f, 0xf3, 0x90, 0xc7, 0x26,
+ 0x91, 0x8e, 0x46, 0xb9, 0xa1, 0xac, 0xbc, 0x1e, 0x65, 0x4c, 0x2e, 0x69,
+ 0x19, 0xde, 0x45, 0x88, 0xdd, 0x90, 0x37, 0xbc, 0xe3, 0xf3, 0x46, 0x18,
+ 0x90, 0x71, 0x27, 0xdf, 0x5f, 0xf2, 0x18, 0x23, 0x6c, 0x96, 0xa2, 0x1d,
+ 0xe0, 0x97, 0x92, 0x47, 0x39, 0xcd, 0x25, 0x23, 0xe2, 0x24, 0x0e, 0xc8,
+ 0x9b, 0xe8, 0x3b, 0x9b, 0x8e, 0x4a, 0xe0, 0xa7, 0x4e, 0x80, 0x6e, 0xcb,
+ 0xb6, 0xef, 0xbf, 0x04, 0xbf, 0xba, 0x0a, 0xbf, 0x66, 0x09, 0x69, 0xa9,
+ 0x86, 0x3d, 0xd0, 0x12, 0xc1, 0x9e, 0x32, 0x7b, 0x25, 0x26, 0x15, 0xd4,
+ 0x59, 0xc0, 0xbb, 0xc7, 0x6b, 0x86, 0xcb, 0xbe, 0x6f, 0x61, 0x5d, 0xfb,
+ 0xdd, 0xbf, 0xf6, 0x0b, 0xf1, 0xc6, 0xba, 0x06, 0x77, 0x11, 0x33, 0x11,
+ 0xf3, 0x10, 0xab, 0xf0, 0x1d, 0xf1, 0xc7, 0x61, 0xcc, 0x85, 0x32, 0xdc,
+ 0x26, 0xb1, 0x8c, 0x93, 0x18, 0x11, 0xa3, 0x8b, 0x5f, 0x03, 0xff, 0x8b,
+ 0x7e, 0xb3, 0xdb, 0x25, 0xcf, 0x83, 0xd7, 0xcf, 0xd5, 0x0d, 0xef, 0x93,
+ 0xe0, 0xbd, 0x53, 0x2c, 0x8a, 0x2f, 0x17, 0x3d, 0x37, 0xf9, 0x39, 0xa4,
+ 0xdf, 0xf1, 0x7e, 0x85, 0xb4, 0x78, 0x0a, 0x26, 0x0f, 0x38, 0x1b, 0x7a,
+ 0x75, 0xd6, 0xe0, 0xc7, 0x36, 0xe2, 0x7d, 0x4d, 0xc7, 0xab, 0xe8, 0xd3,
+ 0xb1, 0x2d, 0x80, 0xa5, 0x3b, 0x51, 0x2f, 0x90, 0x6b, 0x53, 0x76, 0x18,
+ 0x75, 0x39, 0x07, 0xfa, 0x62, 0xdf, 0xc5, 0x5e, 0xf2, 0xfd, 0x7b, 0xbd,
+ 0xc9, 0x86, 0x3d, 0x31, 0x0f, 0x1e, 0x28, 0xd9, 0x1c, 0x68, 0x17, 0xc6,
+ 0xee, 0xa4, 0xbf, 0x43, 0xf9, 0x0a, 0x7c, 0x86, 0x8c, 0x0e, 0xd0, 0x26,
+ 0x24, 0x55, 0xdc, 0x8f, 0xb6, 0xe7, 0x39, 0xd0, 0xfe, 0xd3, 0x35, 0xf2,
+ 0xa1, 0x55, 0xe9, 0xfe, 0xe7, 0xcb, 0xb4, 0xef, 0x01, 0x46, 0x9b, 0x50,
+ 0xb1, 0x5c, 0xda, 0x84, 0x34, 0x78, 0x13, 0xc4, 0xf0, 0x1e, 0x50, 0x6d,
+ 0x59, 0x8f, 0x6d, 0x1b, 0xf9, 0xc7, 0x3a, 0x5b, 0x81, 0xaf, 0x28, 0x83,
+ 0x6d, 0xc0, 0x25, 0xed, 0x72, 0x20, 0xdd, 0x0c, 0xba, 0x77, 0x28, 0x3c,
+ 0x65, 0xb9, 0x1f, 0x86, 0xed, 0x02, 0xa6, 0xb3, 0x1d, 0x6f, 0xd5, 0xf7,
+ 0xb8, 0x1d, 0x65, 0x3f, 0x05, 0xfd, 0x59, 0xb6, 0x49, 0xc7, 0xaf, 0x1f,
+ 0xc6, 0xfe, 0xab, 0x6c, 0x0d, 0xe2, 0x22, 0xe4, 0x83, 0xd1, 0x03, 0xc6,
+ 0xfe, 0xd9, 0x1a, 0x47, 0x92, 0x37, 0x41, 0x0c, 0xc5, 0x52, 0x75, 0x89,
+ 0xe7, 0x1b, 0xfd, 0x16, 0xee, 0x3b, 0xdf, 0xbf, 0xe8, 0x29, 0x7b, 0x0a,
+ 0x1e, 0xec, 0x86, 0x0d, 0x8b, 0x68, 0x5a, 0xb7, 0x82, 0xd6, 0x81, 0x8d,
+ 0x4d, 0x76, 0x40, 0xef, 0xb8, 0x56, 0x53, 0x40, 0x3f, 0x62, 0x85, 0xbf,
+ 0x85, 0x1f, 0x4f, 0xff, 0x81, 0x38, 0x81, 0x73, 0x47, 0xbb, 0x05, 0xd6,
+ 0xa5, 0x2d, 0x7e, 0x0c, 0x63, 0x84, 0x25, 0xd9, 0xc9, 0xfc, 0x03, 0xba,
+ 0x0d, 0x9f, 0x7d, 0xe9, 0xdd, 0xd1, 0x28, 0xcf, 0x83, 0x98, 0x27, 0xd7,
+ 0x63, 0xe2, 0x7a, 0x5d, 0x4a, 0x07, 0xac, 0xca, 0x85, 0x99, 0x93, 0x19,
+ 0x97, 0x73, 0x4b, 0x48, 0x07, 0xe6, 0x76, 0x37, 0x74, 0xf4, 0x8e, 0x0e,
+ 0xf6, 0x69, 0xc6, 0x6e, 0x9c, 0x93, 0xc1, 0x2f, 0x81, 0xdd, 0x8d, 0xba,
+ 0xcd, 0xb2, 0xa3, 0x93, 0xb4, 0xeb, 0x52, 0xba, 0x7a, 0x95, 0x1f, 0xb4,
+ 0xbf, 0x1c, 0x7b, 0x7d, 0xf9, 0x1d, 0x0d, 0xf3, 0x6a, 0x3c, 0x03, 0x20,
+ 0x76, 0xd8, 0x89, 0x77, 0x9c, 0x13, 0x9c, 0xe4, 0xb8, 0x2f, 0x7b, 0x14,
+ 0xdd, 0x38, 0xb7, 0xc6, 0x79, 0x10, 0x43, 0x71, 0xce, 0x9c, 0xc3, 0x7a,
+ 0x6c, 0xc2, 0xf9, 0xfc, 0x57, 0xcd, 0xc3, 0x4d, 0x7a, 0x5d, 0x06, 0xcb,
+ 0xa4, 0xd0, 0xf6, 0x3f, 0x60, 0x0d, 0x7c, 0xe6, 0x3a, 0x8c, 0xcd, 0x4e,
+ 0x05, 0xfd, 0xb4, 0x98, 0x78, 0xb0, 0x89, 0x6b, 0x70, 0x5e, 0xdc, 0x33,
+ 0x86, 0x4e, 0x1d, 0x9a, 0x47, 0xbb, 0xd7, 0x8d, 0xeb, 0x78, 0x6b, 0xf5,
+ 0xc8, 0xed, 0x0d, 0xeb, 0xeb, 0x97, 0xe2, 0x02, 0xe5, 0xe2, 0x36, 0xa4,
+ 0x06, 0x13, 0x0c, 0x40, 0xf7, 0xbf, 0x2b, 0x26, 0xe0, 0x59, 0xd5, 0x78,
+ 0x01, 0x3e, 0x99, 0xd2, 0xfd, 0x6a, 0x2f, 0xc6, 0x90, 0x87, 0x3e, 0xa9,
+ 0xdf, 0x43, 0x19, 0x1b, 0x9f, 0xa8, 0x79, 0xe3, 0x93, 0xb5, 0x81, 0x71,
+ 0xe2, 0xa9, 0x40, 0xe6, 0x50, 0xbf, 0x26, 0x13, 0xf0, 0xb3, 0xc7, 0x73,
+ 0xaa, 0x9d, 0x8a, 0x31, 0x6c, 0xd0, 0x8f, 0x70, 0x3f, 0x4e, 0x04, 0x63,
+ 0xc5, 0xc6, 0xf3, 0xd0, 0x41, 0x0b, 0xb3, 0xb0, 0x4b, 0xae, 0x93, 0xa5,
+ 0x5c, 0xee, 0xf7, 0x9c, 0x11, 0x25, 0x7b, 0x71, 0x67, 0x8c, 0xbc, 0xac,
+ 0xce, 0xfe, 0xb2, 0x2c, 0xcc, 0xf9, 0x72, 0x17, 0x74, 0xe1, 0x43, 0x90,
+ 0x55, 0x39, 0x07, 0x45, 0x78, 0x0e, 0xca, 0xeb, 0x5c, 0x5c, 0xac, 0x53,
+ 0x5d, 0x12, 0x3d, 0x96, 0x90, 0xc8, 0x31, 0x62, 0xcb, 0x94, 0x7d, 0x97,
+ 0x08, 0xec, 0xd8, 0x8b, 0x1f, 0xb2, 0xc4, 0x19, 0xcc, 0x4a, 0x2a, 0xf9,
+ 0x38, 0x6c, 0x6f, 0x15, 0x69, 0x49, 0x52, 0xe9, 0xb3, 0xe8, 0x2b, 0x7a,
+ 0x0e, 0x75, 0xd1, 0x6e, 0xd3, 0x52, 0x12, 0xbf, 0x4e, 0x69, 0x59, 0x0a,
+ 0xf6, 0x4a, 0xcb, 0xd2, 0x5a, 0xff, 0x7c, 0x68, 0xc5, 0x3f, 0xe7, 0xfb,
+ 0xb7, 0x75, 0x5c, 0xe1, 0x8b, 0xfa, 0x8c, 0x81, 0x32, 0x42, 0x7b, 0xa4,
+ 0x7c, 0x63, 0xe8, 0xfd, 0x2f, 0xc2, 0xc7, 0x02, 0x0e, 0x2c, 0xc3, 0x97,
+ 0xca, 0xf8, 0xf2, 0xac, 0x57, 0xf4, 0x73, 0x03, 0xbe, 0xbc, 0xe6, 0xb9,
+ 0xc5, 0x82, 0x38, 0x6f, 0x53, 0xdf, 0xfd, 0x85, 0xf7, 0x4f, 0xe4, 0xfe,
+ 0x76, 0xe7, 0xfe, 0x6c, 0xa8, 0xe8, 0xb7, 0xc2, 0xb7, 0xba, 0x31, 0x73,
+ 0x58, 0xf6, 0x6f, 0x5f, 0x86, 0x0f, 0x9c, 0xbd, 0x11, 0x38, 0x2b, 0x51,
+ 0x50, 0xba, 0xea, 0x75, 0xe5, 0xb7, 0x7d, 0xa2, 0xe7, 0xb0, 0x6c, 0xd9,
+ 0xee, 0xd8, 0xd7, 0xc2, 0xc4, 0x40, 0x87, 0x25, 0x0f, 0xfd, 0x9f, 0x0f,
+ 0xbb, 0xf6, 0x5e, 0x71, 0x46, 0x1e, 0x11, 0x9e, 0x0d, 0xba, 0xd2, 0x7d,
+ 0xcc, 0x4d, 0x7c, 0x32, 0xd4, 0x7b, 0xf0, 0x93, 0xc0, 0xae, 0xdd, 0xe7,
+ 0x98, 0xf7, 0x25, 0xb6, 0xdd, 0xc6, 0x73, 0x5c, 0xba, 0x4f, 0x25, 0x25,
+ 0x05, 0xba, 0xf4, 0x29, 0x9a, 0xf0, 0x6c, 0x22, 0x21, 0xbd, 0xc7, 0x88,
+ 0x49, 0x14, 0x6d, 0xfa, 0x40, 0x9b, 0x34, 0x68, 0x03, 0x9f, 0x66, 0x9b,
+ 0x7d, 0x0d, 0xe9, 0x65, 0x49, 0x0d, 0x7e, 0x0f, 0xb4, 0xe9, 0x03, 0x6d,
+ 0x7a, 0xcf, 0x25, 0xd1, 0x1e, 0x7d, 0x2c, 0x75, 0x23, 0x6d, 0x91, 0x5f,
+ 0xbb, 0xbe, 0x13, 0xcf, 0xae, 0xa4, 0x8e, 0xc5, 0x30, 0x46, 0x48, 0xf6,
+ 0xf4, 0x14, 0x65, 0x78, 0x3b, 0x30, 0x74, 0xfc, 0xb0, 0x5c, 0x81, 0x1d,
+ 0x2a, 0xc3, 0x7f, 0x7b, 0x76, 0xd0, 0x19, 0x5b, 0x86, 0x2e, 0xad, 0xdf,
+ 0xed, 0xcb, 0x37, 0xb6, 0x7f, 0xd3, 0x4f, 0x5c, 0xef, 0xdc, 0x2f, 0xa1,
+ 0x01, 0x99, 0x2e, 0x2b, 0xfb, 0x90, 0xc8, 0x85, 0x15, 0xd6, 0xc1, 0x1a,
+ 0x8b, 0xb0, 0x31, 0x3c, 0xf3, 0x74, 0xa1, 0xeb, 0x1f, 0x91, 0x87, 0x2a,
+ 0x53, 0xf8, 0x01, 0x77, 0xcf, 0xb0, 0xee, 0x41, 0xe0, 0xed, 0x87, 0xe5,
+ 0xc0, 0x0c, 0xb0, 0x58, 0x06, 0xf3, 0x1e, 0x70, 0x81, 0xcb, 0x33, 0xcd,
+ 0xd2, 0x86, 0x32, 0xd0, 0x76, 0xac, 0xbe, 0x1e, 0xd7, 0x2e, 0x83, 0x0f,
+ 0x83, 0xf2, 0x27, 0xf5, 0x01, 0xf9, 0x4a, 0xbd, 0x5f, 0xbe, 0x04, 0xdb,
+ 0xf2, 0x5c, 0xbd, 0x0b, 0x7b, 0x25, 0x01, 0x9e, 0x64, 0xc0, 0x1f, 0x4f,
+ 0xbe, 0x5c, 0x4f, 0xcb, 0x17, 0x41, 0xab, 0xe7, 0xf1, 0x1b, 0x2e, 0xa7,
+ 0x65, 0x4f, 0xb9, 0x5f, 0xf3, 0x88, 0xfc, 0x71, 0x31, 0x1f, 0x17, 0x6b,
+ 0x77, 0x9e, 0x29, 0x62, 0xff, 0x2d, 0xd4, 0xdd, 0xb7, 0xaa, 0x34, 0xb2,
+ 0x6d, 0xb6, 0x9c, 0x59, 0xb1, 0x2f, 0x45, 0xdf, 0x76, 0x9d, 0xa3, 0x13,
+ 0xe0, 0x43, 0x15, 0xfb, 0x74, 0x4c, 0xd1, 0x7e, 0xd5, 0xf6, 0x54, 0x03,
+ 0xdb, 0x63, 0xd6, 0x37, 0x5b, 0x90, 0xef, 0x48, 0xee, 0xc4, 0xb4, 0xec,
+ 0x3f, 0xe9, 0xcb, 0x6f, 0x7a, 0x3e, 0xe4, 0x98, 0xba, 0x78, 0x80, 0x3a,
+ 0x3e, 0x39, 0x11, 0xb6, 0x94, 0x9f, 0x1b, 0x60, 0x8d, 0xef, 0x75, 0x60,
+ 0xcf, 0xa6, 0xb3, 0xd6, 0x94, 0xa4, 0x4e, 0x4c, 0x49, 0xf7, 0x09, 0xc8,
+ 0x82, 0xc7, 0xbe, 0x96, 0x6d, 0xeb, 0x1d, 0xf2, 0xc0, 0x71, 0x9c, 0xc1,
+ 0xbc, 0xb8, 0xf6, 0x5b, 0x92, 0xc6, 0xf8, 0x87, 0xa4, 0x07, 0x6d, 0x5c,
+ 0xb4, 0xb9, 0xa6, 0xc6, 0x6e, 0xc5, 0xd8, 0xcd, 0x72, 0x24, 0xee, 0x40,
+ 0xd6, 0x68, 0xc3, 0xff, 0xaf, 0xe4, 0xaa, 0x4c, 0x7f, 0x24, 0xb9, 0x33,
+ 0x6f, 0x37, 0x4b, 0x0b, 0x9f, 0xa1, 0x1a, 0xe6, 0x59, 0xde, 0x8d, 0x94,
+ 0xe5, 0xae, 0x58, 0xc7, 0x7f, 0x22, 0xb9, 0xf3, 0x1c, 0xfb, 0x2d, 0x94,
+ 0x7f, 0x43, 0x72, 0xc7, 0x7f, 0x8a, 0xfc, 0x15, 0xa4, 0x6f, 0x23, 0x1d,
+ 0x93, 0xee, 0xe3, 0xf0, 0x91, 0xcf, 0x7f, 0x1b, 0x79, 0xf8, 0x74, 0xe7,
+ 0x8f, 0xa0, 0xde, 0x6e, 0xcc, 0xef, 0xde, 0x18, 0xb0, 0x06, 0x74, 0x5e,
+ 0xec, 0xba, 0x60, 0xfe, 0x2c, 0x67, 0x19, 0xdf, 0x1d, 0x81, 0x4e, 0xfb,
+ 0x1f, 0xd0, 0x69, 0xfa, 0x79, 0x81, 0x79, 0xea, 0x36, 0x3e, 0x4f, 0x81,
+ 0x26, 0x87, 0x90, 0xf7, 0xe5, 0x61, 0x8f, 0xf6, 0x66, 0xa7, 0x8c, 0xdb,
+ 0x45, 0xbf, 0x05, 0xb8, 0xa2, 0x15, 0xfb, 0x60, 0x6a, 0xc7, 0xc6, 0xfb,
+ 0xe0, 0x68, 0xef, 0x61, 0xd9, 0xb4, 0xdd, 0xac, 0xdf, 0xac, 0xd7, 0xb5,
+ 0x7f, 0xa8, 0xe8, 0xe0, 0x14, 0x3f, 0x29, 0x5c, 0x87, 0x9b, 0x78, 0xd2,
+ 0xea, 0xbd, 0xff, 0x21, 0xec, 0x03, 0xeb, 0x3c, 0xf3, 0xc1, 0x3e, 0xb0,
+ 0xce, 0x43, 0x37, 0xcc, 0xc3, 0x47, 0x9b, 0xef, 0x92, 0xe6, 0xe3, 0xab,
+ 0xfb, 0xa0, 0xe9, 0xf8, 0xcf, 0xdf, 0x07, 0xcd, 0xe7, 0x51, 0xef, 0x3c,
+ 0x69, 0x86, 0x3e, 0xce, 0x90, 0x66, 0x9d, 0x48, 0x1f, 0xc1, 0x5a, 0x39,
+ 0xf7, 0x66, 0xcc, 0x3d, 0xc0, 0x45, 0x1f, 0x82, 0xbc, 0x7f, 0x62, 0xfb,
+ 0x21, 0x5d, 0xfe, 0x9f, 0xfd, 0x91, 0xb8, 0x53, 0x91, 0x10, 0x69, 0x8a,
+ 0xba, 0x55, 0xd2, 0xf0, 0x79, 0xd0, 0xe6, 0xa0, 0x74, 0x93, 0x7e, 0xd5,
+ 0xbd, 0xc8, 0x17, 0xfd, 0x28, 0x7d, 0x74, 0x45, 0x4f, 0xe0, 0xa4, 0x01,
+ 0x96, 0xbf, 0x0a, 0x99, 0x21, 0xc6, 0x7c, 0x5d, 0xf6, 0xcf, 0xf8, 0x32,
+ 0xee, 0x71, 0xfd, 0x6f, 0x62, 0xfd, 0xd9, 0xed, 0x71, 0x59, 0x4e, 0xc6,
+ 0x41, 0x93, 0x05, 0xe8, 0xf6, 0x2b, 0x12, 0xd0, 0x81, 0x31, 0xe7, 0x3d,
+ 0xe2, 0x26, 0x86, 0xc5, 0x4d, 0x7f, 0x0f, 0x74, 0x18, 0x86, 0xec, 0xe7,
+ 0xeb, 0x94, 0x9d, 0x57, 0x64, 0x08, 0x32, 0xf1, 0x86, 0xe7, 0xa4, 0x81,
+ 0x85, 0xa0, 0x2f, 0x28, 0x17, 0x94, 0x89, 0x36, 0xa5, 0x93, 0xe6, 0x3d,
+ 0xe7, 0xa9, 0xaa, 0xdc, 0x2a, 0xf3, 0x0a, 0x9b, 0xe2, 0xdd, 0x71, 0x65,
+ 0x2f, 0xd2, 0x13, 0x56, 0x0f, 0x74, 0x74, 0x5a, 0xec, 0xde, 0x9b, 0x9b,
+ 0xcd, 0x3d, 0x85, 0xc2, 0x89, 0x90, 0x4c, 0xf5, 0x92, 0x57, 0xec, 0x17,
+ 0xf9, 0x6a, 0xd1, 0x8f, 0xb8, 0x6f, 0xf9, 0xa7, 0x3b, 0x93, 0xf2, 0xe9,
+ 0xde, 0x15, 0xb9, 0xac, 0x88, 0x04, 0xfb, 0x62, 0x48, 0xf1, 0xc3, 0xcc,
+ 0xdb, 0xac, 0xc5, 0xbc, 0xeb, 0x6f, 0x78, 0xc7, 0xb5, 0x50, 0xd6, 0x57,
+ 0xf6, 0x4e, 0xf2, 0x9d, 0x73, 0xfd, 0x5d, 0xd0, 0xcc, 0x79, 0xaa, 0x24,
+ 0xaf, 0x41, 0xf6, 0x40, 0xc3, 0xf3, 0x4c, 0x49, 0xc3, 0x29, 0xc8, 0xfd,
+ 0xab, 0xb2, 0xe7, 0x04, 0xf7, 0xcc, 0xab, 0x58, 0xab, 0xd2, 0x25, 0xd0,
+ 0x11, 0xec, 0xcf, 0x97, 0x69, 0x8f, 0xb1, 0x92, 0x5b, 0x13, 0x93, 0xf0,
+ 0xe1, 0x26, 0x6c, 0x5f, 0x96, 0xbc, 0xa2, 0x2c, 0x0d, 0xa2, 0x4d, 0xf5,
+ 0x11, 0xfc, 0xda, 0xf4, 0xda, 0x3e, 0x0b, 0xba, 0x3b, 0xc9, 0x8a, 0xf5,
+ 0x19, 0xd0, 0xfd, 0x61, 0x49, 0x1d, 0x5f, 0xd1, 0x35, 0x90, 0xbb, 0x40,
+ 0xd7, 0xa4, 0xce, 0xdb, 0x52, 0x2d, 0xbb, 0xf2, 0x71, 0xea, 0x90, 0x32,
+ 0xd7, 0x05, 0x1d, 0xc3, 0xf3, 0xdb, 0x32, 0xf4, 0x4c, 0x19, 0x3a, 0x05,
+ 0x3a, 0xe4, 0x4b, 0x28, 0xff, 0x22, 0xea, 0x3c, 0x0f, 0x9f, 0xe7, 0x39,
+ 0x60, 0xbf, 0x8b, 0xc0, 0x14, 0x17, 0xca, 0x59, 0xed, 0x1b, 0xaa, 0xf5,
+ 0xc2, 0x66, 0x29, 0x7f, 0x45, 0xaa, 0x15, 0xd2, 0xe3, 0x27, 0x8a, 0xb7,
+ 0x39, 0x6f, 0x2b, 0x71, 0x16, 0x66, 0x26, 0x52, 0xa9, 0x18, 0x9a, 0x50,
+ 0xf7, 0x31, 0xf6, 0x6f, 0x74, 0x65, 0xeb, 0x3a, 0x5d, 0x29, 0xf2, 0x62,
+ 0x2d, 0xc0, 0x93, 0xc4, 0xc7, 0xa5, 0x99, 0xe4, 0xca, 0x19, 0x59, 0x09,
+ 0x76, 0xf3, 0x32, 0xfc, 0x92, 0x58, 0xe6, 0x5b, 0x12, 0x3b, 0xe5, 0xfb,
+ 0xdf, 0x87, 0xdd, 0x2c, 0x82, 0x27, 0x56, 0x08, 0xe5, 0x8b, 0x7c, 0x47,
+ 0xb9, 0xa7, 0x6c, 0x87, 0x18, 0x2b, 0x97, 0x97, 0x51, 0x56, 0x55, 0x3e,
+ 0xd3, 0xb7, 0x31, 0x1f, 0x3d, 0x3f, 0x55, 0xc6, 0x7a, 0xcd, 0x92, 0x1f,
+ 0x4f, 0xcb, 0xe3, 0xe5, 0x6d, 0x76, 0x33, 0xda, 0x57, 0x16, 0xd9, 0xc6,
+ 0x19, 0xe4, 0x95, 0x9d, 0x97, 0x17, 0x59, 0xde, 0x25, 0x57, 0x66, 0x32,
+ 0x6a, 0x0e, 0xd5, 0xb9, 0x8c, 0x04, 0x31, 0x49, 0xea, 0x2b, 0xce, 0x15,
+ 0x79, 0xfa, 0x96, 0x65, 0xda, 0xd9, 0x88, 0x14, 0x13, 0xa4, 0x75, 0x42,
+ 0x2e, 0xcf, 0xc4, 0x37, 0x31, 0x86, 0x93, 0x73, 0xf9, 0x6c, 0x62, 0x07,
+ 0xf6, 0xfb, 0x88, 0x1d, 0x30, 0x5e, 0x10, 0x81, 0x2d, 0x53, 0x31, 0x04,
+ 0xa4, 0xc9, 0x06, 0x9f, 0x95, 0xef, 0x03, 0x6c, 0xb4, 0x8a, 0x1f, 0x89,
+ 0x27, 0xb9, 0x5e, 0xa7, 0xb8, 0x0c, 0xfd, 0xd1, 0x91, 0x79, 0x49, 0xee,
+ 0x99, 0x0f, 0xd6, 0x67, 0x9d, 0x11, 0xde, 0xd3, 0x90, 0x6b, 0x73, 0x8e,
+ 0x77, 0x15, 0x98, 0x22, 0x1f, 0xf7, 0xc0, 0xaf, 0x3f, 0x8b, 0x41, 0x7f,
+ 0x0d, 0x66, 0xad, 0x3d, 0x9b, 0x02, 0x7c, 0x16, 0x91, 0xa9, 0x19, 0x9e,
+ 0xa9, 0x41, 0xb7, 0x01, 0x43, 0xfe, 0xf3, 0x08, 0x9e, 0x6b, 0xcc, 0xc3,
+ 0x4f, 0x0b, 0x7c, 0x50, 0x3c, 0x07, 0xfd, 0x91, 0xe6, 0xd6, 0x3c, 0xd7,
+ 0x1e, 0x92, 0x7b, 0x80, 0x4e, 0x04, 0xfd, 0x77, 0xeb, 0xb1, 0xba, 0xcf,
+ 0xa4, 0x19, 0xc3, 0x93, 0x14, 0xf4, 0x45, 0x6e, 0x2e, 0x82, 0xb1, 0xba,
+ 0x34, 0x36, 0xe7, 0xbb, 0xf5, 0xd8, 0xd3, 0xf8, 0x78, 0x69, 0x79, 0xa2,
+ 0x6c, 0xb0, 0x5e, 0x1a, 0x36, 0x56, 0x22, 0x23, 0x7d, 0xbe, 0x7c, 0xdf,
+ 0x23, 0xbd, 0xfa, 0x91, 0xf7, 0xe4, 0x68, 0xfd, 0xdd, 0xce, 0xce, 0x1a,
+ 0xff, 0x5a, 0x31, 0x47, 0xfe, 0x30, 0x3f, 0xe0, 0x23, 0xce, 0xdd, 0x82,
+ 0x3d, 0x2f, 0x01, 0x77, 0x59, 0xe7, 0xba, 0xd4, 0x3b, 0x0b, 0xd8, 0xa0,
+ 0x3a, 0x03, 0xdd, 0x78, 0x8e, 0xe7, 0x89, 0xd0, 0x6d, 0xe7, 0xa2, 0x52,
+ 0x9a, 0xa5, 0x5c, 0x4a, 0x87, 0x05, 0x7e, 0xb1, 0x7e, 0x75, 0xa6, 0x0b,
+ 0x69, 0x2b, 0xd2, 0xa4, 0xea, 0xa7, 0x3a, 0xe3, 0xaa, 0xf6, 0xd5, 0x99,
+ 0xb4, 0x6a, 0x57, 0x9d, 0xe9, 0x47, 0xea, 0x49, 0xd3, 0x39, 0x38, 0x4e,
+ 0xe7, 0x7a, 0x65, 0xea, 0x34, 0xec, 0xcb, 0x80, 0xa5, 0xce, 0xe2, 0x27,
+ 0x60, 0x7f, 0x22, 0xf0, 0xb2, 0xae, 0xda, 0x83, 0xc0, 0x58, 0x3b, 0x81,
+ 0x41, 0x76, 0x8a, 0x7b, 0x8a, 0xeb, 0xa7, 0xee, 0xbd, 0xcc, 0x78, 0x52,
+ 0xe2, 0x41, 0xc9, 0xca, 0x81, 0xd9, 0x66, 0xec, 0xd7, 0x88, 0x5d, 0x92,
+ 0x1e, 0x7b, 0x18, 0xf9, 0x42, 0x85, 0x74, 0xbb, 0x4f, 0xf9, 0x6e, 0x39,
+ 0xef, 0x1c, 0x78, 0x92, 0xc1, 0x18, 0xef, 0xa7, 0x7d, 0x1f, 0xe4, 0xcf,
+ 0xd5, 0x7d, 0x64, 0x30, 0x9f, 0x46, 0x7a, 0xf0, 0x1c, 0x31, 0xfb, 0x73,
+ 0xce, 0x11, 0x29, 0xd7, 0xa4, 0xef, 0x7d, 0x72, 0xd9, 0xcd, 0xc8, 0xcb,
+ 0x6e, 0x5a, 0xae, 0xb8, 0x3b, 0xe4, 0xeb, 0xb0, 0xd3, 0x2f, 0xb9, 0x7d,
+ 0x9b, 0x88, 0x05, 0xaa, 0xea, 0x6c, 0xc6, 0xf0, 0xca, 0xd5, 0xf1, 0xc4,
+ 0x1f, 0xc8, 0xd2, 0x0c, 0xb1, 0xb3, 0xbf, 0x7b, 0xbf, 0x57, 0xa4, 0xdd,
+ 0xc2, 0x1c, 0x88, 0xd5, 0x8a, 0xb0, 0x7f, 0x87, 0x65, 0xd8, 0xa3, 0xdd,
+ 0x53, 0x36, 0x2a, 0x31, 0x1c, 0xec, 0x67, 0xaf, 0x00, 0xbd, 0x7a, 0x79,
+ 0x16, 0xfb, 0x49, 0x28, 0xff, 0x78, 0xae, 0x90, 0xef, 0xae, 0x3c, 0x59,
+ 0xe6, 0x3a, 0x4b, 0xd7, 0xb5, 0x48, 0x58, 0x46, 0x14, 0x5e, 0x68, 0x93,
+ 0x17, 0x17, 0x37, 0x8b, 0x05, 0x0b, 0x65, 0xdd, 0x12, 0x55, 0xb7, 0x18,
+ 0xe8, 0x7f, 0x4b, 0x3b, 0xef, 0x22, 0xbd, 0x05, 0xda, 0x30, 0x16, 0x80,
+ 0xb5, 0xb5, 0x73, 0x25, 0x26, 0xdf, 0x8f, 0xfd, 0xf5, 0x96, 0xda, 0x6b,
+ 0x79, 0x37, 0x8e, 0x67, 0xa6, 0xdc, 0x73, 0x8c, 0x3b, 0x85, 0x75, 0xfc,
+ 0xf7, 0xaf, 0xd4, 0xfb, 0x66, 0x77, 0x17, 0x70, 0x1d, 0xe5, 0x15, 0xe9,
+ 0x52, 0x30, 0x6e, 0x1e, 0x38, 0xae, 0xd0, 0xcf, 0x3b, 0x14, 0x4e, 0xba,
+ 0x88, 0xbd, 0x30, 0xa1, 0xea, 0xef, 0xc4, 0x7e, 0xda, 0xd4, 0x42, 0xfc,
+ 0xb0, 0x07, 0xb2, 0xf8, 0xd2, 0x0c, 0x9f, 0xf9, 0x9e, 0xfe, 0x15, 0xe3,
+ 0x6b, 0x17, 0x46, 0xa7, 0xdd, 0xdf, 0xd2, 0xfb, 0x47, 0x42, 0x77, 0xf5,
+ 0x01, 0x87, 0x1e, 0x6b, 0xc2, 0x5a, 0x9c, 0x64, 0x32, 0x64, 0x75, 0x5a,
+ 0xc0, 0xf1, 0xc3, 0xca, 0xe6, 0xf6, 0x61, 0xfe, 0x69, 0x39, 0x93, 0x6e,
+ 0x93, 0xaa, 0xed, 0xaa, 0x3b, 0x57, 0xcb, 0xf6, 0x76, 0x62, 0x7d, 0xfc,
+ 0x36, 0xa1, 0xac, 0x07, 0x69, 0x33, 0xd2, 0xdb, 0xa4, 0x74, 0xb2, 0xaf,
+ 0x25, 0xe8, 0x2f, 0xba, 0x2e, 0xff, 0x75, 0x3d, 0xce, 0x5f, 0x6a, 0x7f,
+ 0x8a, 0xe3, 0x44, 0xc5, 0xfd, 0x7c, 0xab, 0xf4, 0x1c, 0xb3, 0x81, 0x6d,
+ 0x13, 0xc0, 0xba, 0x5d, 0x92, 0x3e, 0x96, 0x94, 0x5b, 0x8e, 0x99, 0x38,
+ 0xd1, 0x97, 0x47, 0x53, 0x2a, 0x66, 0xf8, 0xa5, 0x51, 0xb7, 0xa2, 0xce,
+ 0x53, 0xf5, 0xdd, 0xb0, 0x65, 0x7d, 0x67, 0xec, 0x1b, 0xa3, 0x7d, 0x2a,
+ 0xfd, 0xf6, 0x68, 0x5a, 0xa5, 0xaf, 0x8c, 0xde, 0x52, 0x0b, 0xfc, 0xa3,
+ 0xd2, 0x42, 0x5a, 0x3e, 0x57, 0x26, 0xbe, 0x1c, 0x00, 0x76, 0xf4, 0xa0,
+ 0x67, 0xfa, 0xa1, 0x67, 0xd2, 0xd0, 0x33, 0x83, 0xd4, 0x33, 0xd0, 0xdb,
+ 0xaf, 0x40, 0x6f, 0x7b, 0xf2, 0x06, 0xe4, 0xf5, 0x82, 0xd7, 0x0c, 0x5c,
+ 0xe8, 0xfb, 0xc1, 0x5a, 0x9d, 0xa7, 0x96, 0xc1, 0xdf, 0xea, 0x59, 0x89,
+ 0xb5, 0x43, 0x07, 0x6d, 0x9f, 0x6f, 0x92, 0x85, 0xb8, 0xef, 0x9f, 0xf0,
+ 0x5c, 0xb9, 0x86, 0xfa, 0x39, 0x97, 0xfb, 0x78, 0xa2, 0x85, 0xfe, 0xd8,
+ 0xb5, 0x99, 0x1d, 0xd0, 0x49, 0x94, 0xf7, 0x98, 0x54, 0xc7, 0x13, 0xb2,
+ 0x08, 0xff, 0x6c, 0xb5, 0x4e, 0x1a, 0xcf, 0xdc, 0xff, 0xff, 0x12, 0x75,
+ 0xd3, 0xb0, 0x0f, 0xb6, 0x2c, 0xf5, 0x25, 0xe5, 0x4c, 0x9f, 0x33, 0x98,
+ 0xb4, 0xa8, 0xbb, 0x92, 0x52, 0x81, 0xaf, 0x5f, 0x2d, 0xb3, 0x3e, 0xeb,
+ 0x61, 0x7f, 0x96, 0x83, 0x76, 0xd3, 0x65, 0xa3, 0x27, 0x20, 0x9f, 0x73,
+ 0x8c, 0x03, 0x06, 0x36, 0xc0, 0xb2, 0x9a, 0x21, 0x07, 0x1e, 0xe8, 0x3f,
+ 0x8e, 0xf2, 0x01, 0xde, 0x25, 0x40, 0x19, 0xb1, 0x50, 0x49, 0xf1, 0x38,
+ 0xef, 0x8d, 0xa3, 0x8c, 0x6d, 0x9c, 0x44, 0x0a, 0xe5, 0x63, 0x92, 0x4a,
+ 0x14, 0xd4, 0xbd, 0xa6, 0x4e, 0x94, 0xb1, 0x8f, 0xb0, 0x8e, 0xc7, 0xcc,
+ 0xb6, 0x50, 0x8e, 0xc2, 0xae, 0x29, 0xdf, 0xa6, 0x62, 0x03, 0x59, 0xdb,
+ 0xc3, 0x7e, 0x60, 0x59, 0xca, 0x66, 0xbb, 0xbc, 0xe7, 0x29, 0x5d, 0x78,
+ 0xaf, 0x3e, 0xb7, 0xb8, 0xa7, 0xd6, 0x2a, 0xf9, 0x5a, 0xd3, 0x7b, 0xe8,
+ 0x7f, 0xb3, 0x27, 0x2f, 0x27, 0x6c, 0xe1, 0x19, 0x7b, 0xb0, 0xcf, 0x23,
+ 0x3b, 0xb8, 0x27, 0x40, 0x77, 0xd8, 0xdf, 0xe7, 0xb1, 0xde, 0xe7, 0x60,
+ 0x7f, 0x2f, 0xc2, 0xfe, 0x5e, 0x28, 0xaf, 0xea, 0x8f, 0xc0, 0xee, 0x52,
+ 0x07, 0x3c, 0x03, 0x9e, 0x8d, 0x01, 0xf7, 0xef, 0x85, 0x3f, 0x30, 0x02,
+ 0xec, 0x3f, 0x04, 0xfe, 0x65, 0xc0, 0xbb, 0x71, 0xde, 0x45, 0x01, 0x1f,
+ 0x07, 0xd5, 0x59, 0xe6, 0xac, 0x3a, 0xcf, 0xff, 0x81, 0xb2, 0xbd, 0x8f,
+ 0x97, 0x2d, 0xd8, 0x87, 0xa2, 0x7f, 0x9d, 0xeb, 0x00, 0xff, 0xad, 0xec,
+ 0xe7, 0xc1, 0x17, 0xa1, 0x57, 0x7e, 0x8c, 0x79, 0x3d, 0x37, 0x4b, 0x7b,
+ 0x8e, 0x3a, 0x01, 0xde, 0xf6, 0x18, 0xeb, 0xc2, 0x7e, 0x3e, 0x7a, 0x59,
+ 0x96, 0x81, 0x3b, 0xb2, 0x94, 0x63, 0xf8, 0x0f, 0xce, 0x85, 0x8a, 0xf4,
+ 0x52, 0x07, 0x02, 0x13, 0x0d, 0xca, 0xc0, 0xf1, 0x04, 0xb0, 0x1e, 0x90,
+ 0xbc, 0x3a, 0xaf, 0xc3, 0xf3, 0xf9, 0x2d, 0x62, 0x11, 0xef, 0x79, 0x3c,
+ 0x9b, 0xa1, 0xde, 0x30, 0x18, 0x69, 0x79, 0xb0, 0x43, 0xb2, 0xdb, 0x3b,
+ 0x94, 0xee, 0x70, 0xbc, 0x97, 0x31, 0xee, 0x1e, 0xb8, 0x20, 0x6f, 0x00,
+ 0x21, 0x58, 0x99, 0x43, 0xf2, 0xbf, 0x3c, 0xc6, 0xa8, 0x02, 0xdf, 0x0f,
+ 0x73, 0x89, 0x81, 0x66, 0x9b, 0xf6, 0xbb, 0x76, 0x6c, 0x4f, 0x9d, 0xfd,
+ 0xc7, 0x14, 0xc6, 0xca, 0x0b, 0xfb, 0x87, 0x9d, 0xc0, 0x98, 0xa9, 0xe3,
+ 0x94, 0xfd, 0x6d, 0xe0, 0xdb, 0x3f, 0x05, 0x06, 0x22, 0x55, 0x87, 0x36,
+ 0x07, 0xfb, 0x85, 0xf3, 0x5f, 0x26, 0x9e, 0x60, 0x4c, 0x3d, 0xf0, 0xcb,
+ 0x57, 0xe6, 0xb6, 0x13, 0xf6, 0xeb, 0xb6, 0xcd, 0x94, 0x81, 0x71, 0x0f,
+ 0x7e, 0xdf, 0xf1, 0xc0, 0x5e, 0x77, 0x9f, 0x47, 0xab, 0x13, 0xd2, 0xc9,
+ 0xd3, 0x4e, 0x4b, 0x6e, 0x91, 0x8f, 0x44, 0x82, 0x7e, 0xac, 0x79, 0x1b,
+ 0xb2, 0x4a, 0x3d, 0xd0, 0x09, 0x39, 0x67, 0x9e, 0x3a, 0x85, 0x3a, 0x81,
+ 0xb2, 0xe0, 0x4a, 0xa9, 0x0e, 0x9d, 0xd0, 0xd6, 0x25, 0x15, 0xd2, 0x6c,
+ 0x9e, 0x7a, 0xe2, 0x07, 0x32, 0xbd, 0x4e, 0x57, 0x0e, 0x89, 0xf1, 0x6b,
+ 0x5b, 0x25, 0x9a, 0x71, 0xed, 0x7b, 0xd5, 0x1a, 0x03, 0x7d, 0x79, 0x80,
+ 0xf8, 0x73, 0x36, 0xeb, 0x74, 0x88, 0xc6, 0x9e, 0x0a, 0x3f, 0xbd, 0x89,
+ 0xb5, 0xb2, 0x0f, 0x45, 0xa7, 0xc1, 0xa1, 0xc0, 0x17, 0x50, 0x31, 0x3f,
+ 0xe0, 0xe0, 0xc4, 0x8f, 0xa1, 0x6b, 0xf3, 0xc4, 0x25, 0xa0, 0x73, 0xf7,
+ 0x09, 0xca, 0xd1, 0x75, 0xea, 0x6c, 0xbc, 0x62, 0xa5, 0xa9, 0xaf, 0x65,
+ 0xf1, 0x38, 0x30, 0x97, 0xb5, 0x4b, 0x0a, 0x94, 0x57, 0x9e, 0x7d, 0x2f,
+ 0x5a, 0x32, 0x3d, 0xd7, 0x26, 0x3d, 0xf3, 0x8c, 0xaf, 0xee, 0x6e, 0x91,
+ 0x36, 0xc6, 0x58, 0x69, 0x83, 0x06, 0x24, 0x8f, 0xf2, 0xee, 0xf9, 0xb0,
+ 0x8a, 0x87, 0x55, 0x2c, 0xd2, 0xa8, 0x1f, 0xfa, 0xc0, 0x49, 0x2f, 0x5b,
+ 0xff, 0x25, 0x16, 0x60, 0x48, 0xc8, 0x52, 0x19, 0x32, 0x56, 0x86, 0x8c,
+ 0x95, 0x21, 0x63, 0x65, 0xc8, 0x18, 0xb0, 0xdf, 0x73, 0xd8, 0x7f, 0x17,
+ 0xcb, 0x83, 0xda, 0xae, 0xdf, 0xaf, 0xec, 0xfa, 0x91, 0x32, 0xcf, 0xf0,
+ 0xe9, 0x83, 0x26, 0x95, 0x0e, 0xb9, 0xa4, 0x7c, 0x51, 0xe3, 0xa3, 0xbe,
+ 0x22, 0xcf, 0xcc, 0xbe, 0x2a, 0x67, 0x66, 0x57, 0x71, 0xe0, 0x54, 0xd9,
+ 0x97, 0x97, 0x3d, 0xf8, 0x9f, 0x0b, 0xc4, 0x54, 0xd9, 0xf6, 0x66, 0x85,
+ 0xad, 0x0e, 0x4b, 0x41, 0xe1, 0x64, 0x65, 0x47, 0x80, 0xaf, 0x14, 0x2e,
+ 0xe4, 0xde, 0x94, 0x8e, 0xed, 0xaf, 0xc9, 0x45, 0xd8, 0xf1, 0xc5, 0xfa,
+ 0xeb, 0xf2, 0xbc, 0xc2, 0xe3, 0xa4, 0xc3, 0x07, 0xe4, 0x47, 0x76, 0x70,
+ 0x4e, 0x7c, 0x06, 0x58, 0x63, 0xb1, 0x8f, 0xba, 0x23, 0x02, 0x5b, 0xe0,
+ 0x14, 0xbb, 0xb1, 0xaf, 0x0f, 0x5a, 0x37, 0x00, 0xd3, 0xf0, 0xfd, 0x16,
+ 0x79, 0x71, 0xb6, 0xd8, 0x20, 0x13, 0xd4, 0x0f, 0xce, 0x51, 0xb1, 0x68,
+ 0xa7, 0x68, 0x37, 0xb9, 0x5e, 0xda, 0xa9, 0x3f, 0xd8, 0xcc, 0xb3, 0xd4,
+ 0xea, 0xc9, 0x73, 0x2d, 0x8c, 0x37, 0xc6, 0x5d, 0xd2, 0xf4, 0x35, 0x39,
+ 0x58, 0x63, 0xd9, 0xab, 0xe0, 0x0f, 0xd3, 0xef, 0xf9, 0xf7, 0xc4, 0x39,
+ 0x1e, 0xfb, 0x05, 0x6e, 0xea, 0xc4, 0x5a, 0xcb, 0x7f, 0xa9, 0x63, 0x5e,
+ 0xfd, 0x0a, 0x47, 0xbf, 0x13, 0x2f, 0x9b, 0x7b, 0x0d, 0xaf, 0xa9, 0x78,
+ 0xe0, 0x06, 0x71, 0xe2, 0xa7, 0xb0, 0xaf, 0x8a, 0x57, 0x85, 0x31, 0x4b,
+ 0xc6, 0x73, 0x19, 0x2b, 0x6e, 0xd4, 0x18, 0xea, 0xbc, 0x54, 0xee, 0x86,
+ 0x7e, 0xb9, 0x07, 0xfa, 0xe5, 0xde, 0x77, 0xdc, 0xaf, 0x35, 0x71, 0xfb,
+ 0x9e, 0x62, 0xd8, 0xea, 0x92, 0xb1, 0x5a, 0x63, 0x5b, 0xc6, 0x71, 0x37,
+ 0x8a, 0xdb, 0x32, 0xa6, 0x9b, 0x5e, 0x17, 0x0b, 0xa4, 0x6c, 0xf8, 0xf2,
+ 0x92, 0xc7, 0xb8, 0x9b, 0xb9, 0x9b, 0xbd, 0x11, 0xfe, 0xfa, 0xc3, 0xcd,
+ 0x26, 0xe6, 0x1c, 0xc9, 0x5c, 0x15, 0xde, 0xd1, 0x2e, 0xcd, 0x10, 0x0f,
+ 0xa8, 0xb3, 0x40, 0x15, 0xbb, 0xce, 0x07, 0xf1, 0x03, 0x94, 0xc3, 0xea,
+ 0xc2, 0xdf, 0x61, 0xec, 0xda, 0xde, 0xe1, 0xd8, 0x63, 0xe1, 0xe0, 0xae,
+ 0x1f, 0xf7, 0x72, 0xa0, 0xcb, 0x20, 0x8b, 0xf5, 0xd5, 0x3b, 0x74, 0x43,
+ 0x4a, 0x5f, 0x5c, 0xc5, 0x1e, 0x20, 0xbf, 0xe0, 0x2f, 0x60, 0x9f, 0x4c,
+ 0x41, 0x3f, 0x15, 0x54, 0x7f, 0x31, 0xca, 0x45, 0x36, 0x17, 0xb6, 0x24,
+ 0x7a, 0x8a, 0xbe, 0x50, 0x10, 0x6b, 0xc9, 0x87, 0x1d, 0xa5, 0xbf, 0x31,
+ 0x77, 0xe0, 0x33, 0xee, 0xcf, 0xe4, 0x44, 0x73, 0xa6, 0x09, 0x76, 0x15,
+ 0xfc, 0xab, 0x33, 0x26, 0x80, 0xbd, 0xbb, 0xf4, 0x5d, 0x39, 0x30, 0x77,
+ 0x69, 0x73, 0x20, 0xff, 0x8c, 0x23, 0x73, 0x7d, 0x66, 0x0e, 0x6b, 0xfb,
+ 0xb6, 0x4e, 0x49, 0xac, 0x05, 0x36, 0xed, 0xa3, 0xa7, 0x88, 0x07, 0x9a,
+ 0x65, 0x39, 0xce, 0x7e, 0x83, 0x3d, 0x33, 0x5d, 0x66, 0xdf, 0xdf, 0x95,
+ 0xe1, 0xb9, 0x74, 0x2b, 0xf5, 0xc8, 0x12, 0xf4, 0xc0, 0x65, 0x9b, 0x36,
+ 0x74, 0x1c, 0x36, 0xae, 0x53, 0xde, 0x9c, 0xa3, 0x7d, 0x4c, 0xd9, 0x67,
+ 0x64, 0x5b, 0xe2, 0x0c, 0xe6, 0xf4, 0x84, 0x17, 0xa1, 0x8f, 0xe6, 0x0f,
+ 0xa1, 0xec, 0xeb, 0x92, 0xb2, 0xbb, 0x43, 0x7c, 0xde, 0x66, 0x3f, 0x29,
+ 0xbc, 0x6f, 0x90, 0xb2, 0x6f, 0x0d, 0x51, 0x8e, 0xe0, 0x73, 0x2f, 0xad,
+ 0xce, 0xf3, 0x7b, 0x73, 0xca, 0x4f, 0x52, 0x7a, 0x66, 0xc9, 0xe3, 0x78,
+ 0x97, 0xb4, 0x6e, 0xbb, 0x15, 0xfa, 0x24, 0xa6, 0xcf, 0xc2, 0xd0, 0x86,
+ 0xd8, 0xc6, 0x8b, 0xe8, 0xfc, 0x67, 0x25, 0x77, 0x3a, 0x0e, 0x7d, 0xc6,
+ 0xbe, 0x8c, 0xef, 0x40, 0x1b, 0x69, 0xf0, 0x36, 0xed, 0xdd, 0x2e, 0xd8,
+ 0xbd, 0x9b, 0xd4, 0x7c, 0x46, 0xbc, 0x7e, 0x99, 0x3a, 0xc9, 0xb1, 0xfb,
+ 0xa0, 0xcb, 0x13, 0x4a, 0x6e, 0x4b, 0xe5, 0xcb, 0x89, 0x18, 0x74, 0x72,
+ 0x6c, 0x3b, 0xe9, 0xf9, 0x61, 0xb9, 0xd3, 0x1d, 0x97, 0xbb, 0x20, 0x3b,
+ 0x43, 0xae, 0x27, 0xc3, 0xe0, 0xc5, 0x1e, 0x17, 0x76, 0x47, 0x61, 0xe8,
+ 0x66, 0xf8, 0x5d, 0x1c, 0x9b, 0xf7, 0xc4, 0xd9, 0x36, 0xc0, 0x8f, 0x7f,
+ 0x54, 0x0f, 0x68, 0x94, 0x9b, 0xfb, 0x88, 0xa2, 0xcd, 0x88, 0xb7, 0x53,
+ 0xdb, 0xd9, 0x36, 0xc9, 0xab, 0x7a, 0x3b, 0x95, 0x3d, 0x2e, 0x2d, 0xde,
+ 0x87, 0x14, 0xb6, 0x79, 0x11, 0xfa, 0x06, 0x98, 0xbb, 0x54, 0xdb, 0x81,
+ 0x3c, 0x6c, 0xe8, 0x62, 0x06, 0xe9, 0x87, 0x91, 0xb2, 0x6e, 0xa8, 0x35,
+ 0x88, 0xe5, 0x1a, 0x3c, 0xba, 0x7a, 0xbf, 0xf0, 0xa3, 0x0a, 0x97, 0x5e,
+ 0x55, 0xf7, 0xcb, 0x2c, 0x60, 0x9d, 0x1c, 0xf4, 0x4a, 0x2b, 0x30, 0xd0,
+ 0xcc, 0x29, 0x27, 0x3d, 0x1c, 0xda, 0x2d, 0xbf, 0x06, 0x5f, 0xbe, 0xea,
+ 0x91, 0x97, 0x3b, 0xe4, 0xc1, 0x3b, 0x28, 0x23, 0xbb, 0x65, 0xff, 0x1d,
+ 0x21, 0xd9, 0xdf, 0xef, 0x64, 0x39, 0xef, 0x5b, 0x6e, 0x33, 0xfe, 0x74,
+ 0xcf, 0x48, 0x2a, 0x34, 0x20, 0x4f, 0x42, 0xc6, 0x8a, 0x90, 0xaf, 0xe1,
+ 0x3a, 0x69, 0x4e, 0x7d, 0x4f, 0x3d, 0x9f, 0x06, 0x56, 0x36, 0xd8, 0xcf,
+ 0x95, 0x99, 0x7a, 0x93, 0x24, 0xaf, 0x67, 0x3c, 0x39, 0x19, 0x9c, 0x71,
+ 0x5c, 0x4f, 0x99, 0x80, 0x0f, 0x72, 0x7d, 0xb0, 0x3f, 0xd5, 0xbd, 0x2e,
+ 0xf5, 0x1c, 0xa7, 0xff, 0xeb, 0x13, 0xe7, 0x15, 0x14, 0x5f, 0x68, 0x23,
+ 0x98, 0xfe, 0xbb, 0xd6, 0x15, 0x7c, 0xd7, 0x46, 0xff, 0x61, 0x67, 0xeb,
+ 0xea, 0xbd, 0xf4, 0xf5, 0xb2, 0x68, 0xe2, 0x6e, 0x15, 0xac, 0x99, 0x36,
+ 0xdd, 0xb1, 0xa9, 0x0b, 0xdb, 0xdd, 0xfb, 0xe5, 0x4f, 0x60, 0xdf, 0xbf,
+ 0xb2, 0x62, 0xdf, 0xf7, 0x81, 0x1e, 0xeb, 0x31, 0x80, 0x6b, 0xdf, 0x8d,
+ 0xb5, 0x8c, 0x80, 0x9f, 0x77, 0xe1, 0x77, 0x67, 0x79, 0x4d, 0x1c, 0x6f,
+ 0xb6, 0x08, 0x3c, 0xd9, 0xe4, 0xb2, 0xbf, 0x35, 0xf1, 0xbc, 0x62, 0x41,
+ 0x56, 0x62, 0x85, 0x83, 0xd7, 0x84, 0x76, 0xef, 0x2d, 0x89, 0xf6, 0xba,
+ 0x6f, 0x75, 0x87, 0xdc, 0x17, 0xac, 0x10, 0xcf, 0x95, 0x3d, 0x39, 0x5b,
+ 0x27, 0x0e, 0xbb, 0x22, 0xd6, 0x79, 0x62, 0xb0, 0x6f, 0xa8, 0x18, 0x54,
+ 0xb5, 0xfc, 0x6d, 0xa4, 0xa8, 0x0f, 0xfd, 0x18, 0x0e, 0xe2, 0x14, 0x0a,
+ 0xab, 0x50, 0xcf, 0xde, 0x05, 0x3e, 0x4c, 0xe1, 0xd7, 0xbd, 0xfd, 0x56,
+ 0xec, 0x5f, 0xca, 0x29, 0x63, 0x5f, 0xbd, 0xf6, 0xf6, 0x10, 0xdf, 0x6d,
+ 0x14, 0x07, 0xfb, 0x8e, 0x44, 0x4e, 0xc0, 0xd6, 0x59, 0xd4, 0x0f, 0x5c,
+ 0x07, 0xed, 0xa4, 0x2d, 0x0b, 0x27, 0xb9, 0xd7, 0x37, 0xaa, 0x6f, 0xea,
+ 0x9a, 0xb5, 0x28, 0xbb, 0x91, 0x2d, 0x30, 0xc6, 0x59, 0x26, 0x0f, 0x3c,
+ 0xf0, 0xc0, 0x97, 0x53, 0x5e, 0x3b, 0xf4, 0x76, 0x5c, 0xc2, 0xa7, 0x7c,
+ 0x19, 0x52, 0xd8, 0x75, 0x1b, 0x30, 0xd7, 0x16, 0x8d, 0x1b, 0xe2, 0x12,
+ 0x39, 0xd5, 0x25, 0xcd, 0xc0, 0xd5, 0x4d, 0xc7, 0x68, 0x23, 0x53, 0xc9,
+ 0x21, 0x08, 0x41, 0x44, 0xdd, 0x55, 0x74, 0x06, 0xdf, 0x94, 0x6d, 0xc9,
+ 0x37, 0x85, 0x78, 0xe9, 0x86, 0x2d, 0xf0, 0x09, 0xbc, 0x2b, 0x1b, 0xd4,
+ 0x2f, 0xad, 0xd6, 0x87, 0x1c, 0x31, 0xb6, 0xc6, 0x36, 0x8c, 0xb5, 0xa5,
+ 0x06, 0xdf, 0x60, 0x8c, 0x0d, 0xbe, 0x66, 0xd3, 0xb9, 0x60, 0x0e, 0xd6,
+ 0x52, 0x87, 0x54, 0x4f, 0x73, 0x8f, 0x32, 0xce, 0x62, 0x07, 0x7e, 0x6a,
+ 0x99, 0xfe, 0x2a, 0xdf, 0x27, 0xf5, 0xfb, 0x6e, 0xfd, 0x9e, 0xfe, 0x68,
+ 0xd1, 0x6f, 0x02, 0x4d, 0xf7, 0x40, 0x7f, 0xde, 0xb7, 0xc3, 0x55, 0xb8,
+ 0xe1, 0xbe, 0x15, 0x9e, 0xed, 0x15, 0xeb, 0x38, 0xfc, 0xd4, 0xf2, 0x61,
+ 0x71, 0xb7, 0x2f, 0xa7, 0x23, 0x32, 0x06, 0x5e, 0x30, 0x9f, 0xe5, 0x7c,
+ 0xd2, 0x47, 0xe4, 0xa0, 0xe2, 0x4d, 0xf5, 0xa4, 0x73, 0x34, 0x19, 0x9a,
+ 0x12, 0xab, 0xca, 0xe7, 0x47, 0x90, 0x1e, 0x01, 0xde, 0x09, 0x62, 0x97,
+ 0x56, 0x75, 0x2d, 0x2d, 0x81, 0x31, 0xec, 0x3d, 0x6b, 0xe2, 0x58, 0xab,
+ 0x31, 0x2e, 0xbe, 0x1f, 0x52, 0xef, 0xd3, 0x6b, 0xe2, 0x5c, 0x79, 0x8b,
+ 0x58, 0xc6, 0xbc, 0x27, 0x2f, 0xc8, 0x2f, 0xd8, 0xe2, 0x93, 0x26, 0xe6,
+ 0xd5, 0xa6, 0xf9, 0x42, 0xfe, 0xcc, 0xc8, 0x45, 0xdb, 0x19, 0xa1, 0xfc,
+ 0xfd, 0xea, 0x8e, 0x1b, 0x65, 0xa2, 0x93, 0xf1, 0xb6, 0xc6, 0x39, 0xac,
+ 0x8f, 0xa3, 0x35, 0x8e, 0xbf, 0x3e, 0xfe, 0xc6, 0xb1, 0x83, 0x18, 0x5b,
+ 0x6e, 0x4d, 0x8c, 0xad, 0x71, 0x3c, 0x8e, 0xb5, 0x05, 0xfe, 0x53, 0xd1,
+ 0x8f, 0xbb, 0xe4, 0x51, 0x4f, 0x72, 0x8e, 0xf9, 0x2f, 0x58, 0xe0, 0x63,
+ 0x1c, 0x76, 0x84, 0xbc, 0x34, 0x67, 0xcf, 0xe4, 0x69, 0x2a, 0x79, 0x24,
+ 0xe0, 0xe7, 0x60, 0xc0, 0xf7, 0x80, 0xff, 0x57, 0x56, 0xf8, 0x48, 0xfb,
+ 0x40, 0x3e, 0x76, 0x8a, 0x40, 0xcf, 0x5a, 0xc7, 0xc8, 0x43, 0xa6, 0xe4,
+ 0x21, 0xdf, 0x91, 0x87, 0xdd, 0xfa, 0x1d, 0xf9, 0x07, 0x9c, 0xf6, 0x79,
+ 0x60, 0x0c, 0x2f, 0xa7, 0xbe, 0xb1, 0xe9, 0xee, 0x35, 0x7b, 0x31, 0x2d,
+ 0xcf, 0x2f, 0xb4, 0x88, 0x9d, 0x09, 0xd6, 0x35, 0xbe, 0x26, 0xde, 0xce,
+ 0xf3, 0xab, 0x7e, 0x62, 0x4f, 0xb3, 0xae, 0x04, 0xd7, 0x75, 0x50, 0x5e,
+ 0x93, 0xc2, 0x4c, 0x04, 0x3e, 0x60, 0x1a, 0x38, 0xa7, 0x1f, 0xfa, 0x96,
+ 0xf1, 0x51, 0x94, 0xd5, 0x88, 0x57, 0x68, 0xeb, 0xd2, 0xd8, 0x2b, 0xd4,
+ 0xc1, 0xc4, 0x23, 0xaf, 0x4a, 0xbe, 0x62, 0x74, 0x0c, 0xfa, 0xb7, 0x4c,
+ 0xff, 0xa4, 0x73, 0xf6, 0x96, 0xeb, 0x64, 0x39, 0x79, 0x9d, 0x38, 0xc9,
+ 0x45, 0x59, 0xe5, 0xeb, 0xf8, 0xc6, 0x74, 0xf7, 0xee, 0x0b, 0xaf, 0xca,
+ 0xc6, 0xf8, 0x06, 0xbc, 0x9f, 0x14, 0xf3, 0xde, 0xf0, 0x7e, 0x43, 0x3e,
+ 0x14, 0x5f, 0x11, 0xf2, 0x82, 0x34, 0x20, 0x1e, 0x8e, 0xca, 0xef, 0xc6,
+ 0xb9, 0x1f, 0x8b, 0xea, 0x7c, 0x33, 0x65, 0xf5, 0x2a, 0x9d, 0x31, 0xe4,
+ 0x05, 0xf2, 0x5a, 0xc4, 0x38, 0xb1, 0x9e, 0xdf, 0xf3, 0x87, 0xe2, 0xf0,
+ 0x73, 0x7b, 0xa8, 0x5f, 0xcc, 0x9e, 0x6e, 0x51, 0x7b, 0xfa, 0x09, 0x2f,
+ 0x24, 0x25, 0x37, 0x24, 0x53, 0xee, 0x61, 0x85, 0xf1, 0x7f, 0x03, 0x7d,
+ 0x3d, 0xa8, 0xfb, 0x9a, 0x92, 0x5e, 0xad, 0x7f, 0x0e, 0x41, 0xce, 0x7d,
+ 0xb9, 0xd7, 0xdb, 0x21, 0xbf, 0xda, 0xce, 0x3d, 0x60, 0xd6, 0x7f, 0x58,
+ 0x7a, 0x76, 0x2c, 0x27, 0xe1, 0x19, 0xdc, 0x12, 0x5d, 0xa1, 0x01, 0xf7,
+ 0x99, 0x91, 0xef, 0x80, 0x0e, 0xc1, 0xfa, 0xd7, 0xac, 0x55, 0xaf, 0x93,
+ 0x6b, 0x66, 0x3d, 0xae, 0x35, 0xc0, 0xf2, 0xab, 0x6b, 0x35, 0xf5, 0x5b,
+ 0x21, 0x4b, 0x4e, 0x52, 0x42, 0x8d, 0xb4, 0x59, 0xd1, 0x51, 0x23, 0x8c,
+ 0x91, 0x2c, 0xdb, 0x4e, 0x3a, 0x19, 0x32, 0xb1, 0xe8, 0x00, 0xeb, 0x76,
+ 0x03, 0x87, 0xbb, 0xbd, 0xbd, 0xe9, 0x82, 0x8a, 0x91, 0x5a, 0x6a, 0x5d,
+ 0x53, 0xc0, 0x64, 0x0b, 0xde, 0x2b, 0xfe, 0xa7, 0x81, 0x59, 0x27, 0xe4,
+ 0x61, 0x09, 0xaf, 0x89, 0xe5, 0x22, 0x7f, 0x9e, 0xf1, 0x5c, 0x27, 0x99,
+ 0x05, 0x8f, 0x7f, 0x13, 0x3e, 0x7c, 0x15, 0x7a, 0xff, 0xe3, 0xb4, 0x0d,
+ 0x65, 0xd8, 0x0b, 0xe0, 0x92, 0xaf, 0xbc, 0x27, 0x86, 0x9f, 0x68, 0x88,
+ 0xe5, 0x06, 0xf8, 0xf4, 0xa2, 0xc2, 0xa4, 0xc4, 0xed, 0x47, 0x43, 0x77,
+ 0xf7, 0x85, 0xe1, 0x67, 0x14, 0xfd, 0x98, 0x4b, 0x1c, 0x77, 0x58, 0xee,
+ 0x04, 0x7f, 0xce, 0x2e, 0x14, 0x43, 0x7b, 0xca, 0x46, 0x56, 0xe1, 0x57,
+ 0xd6, 0x9d, 0xf4, 0x65, 0xd0, 0xe3, 0x19, 0x8d, 0xf9, 0x78, 0x5e, 0x53,
+ 0xd5, 0x3e, 0x0b, 0x63, 0x43, 0xa5, 0xfa, 0x61, 0x99, 0xf6, 0x18, 0xdb,
+ 0xe9, 0x91, 0x52, 0x3c, 0x7b, 0x63, 0xf3, 0x0a, 0x8d, 0x1c, 0x1b, 0x3e,
+ 0x5f, 0x9a, 0xfa, 0xbb, 0xaa, 0xcf, 0x3b, 0x9e, 0x51, 0xf2, 0x65, 0xe2,
+ 0xc2, 0xf4, 0x8f, 0x78, 0x5e, 0xd5, 0x63, 0x8f, 0xf0, 0xb9, 0x42, 0x19,
+ 0x50, 0x3e, 0x13, 0x68, 0xf9, 0x90, 0x64, 0xc7, 0x92, 0x0a, 0xb7, 0x3c,
+ 0x5e, 0xe6, 0x7e, 0x21, 0xfe, 0x7f, 0x0d, 0xd8, 0x3f, 0x02, 0x9e, 0xd1,
+ 0x0f, 0xe0, 0xd8, 0xdc, 0x17, 0x28, 0xab, 0xd9, 0xef, 0xb2, 0x2f, 0x5e,
+ 0x6b, 0x23, 0xc6, 0xb8, 0x54, 0x16, 0x45, 0xbf, 0x65, 0x31, 0xb1, 0x73,
+ 0x85, 0x05, 0x8b, 0xb9, 0x70, 0x48, 0x52, 0x27, 0xfe, 0x35, 0x64, 0xe8,
+ 0xd7, 0xe1, 0x23, 0xa9, 0x7a, 0xea, 0xfc, 0x6a, 0x08, 0x98, 0xcb, 0x72,
+ 0x6f, 0x90, 0x92, 0x1d, 0x95, 0x92, 0xba, 0xa3, 0xc9, 0xf3, 0xdc, 0xb0,
+ 0x8a, 0xed, 0x94, 0x6c, 0x62, 0xfe, 0xff, 0xde, 0x16, 0xd8, 0xfa, 0x0e,
+ 0xe4, 0xd9, 0x8e, 0x79, 0x96, 0x4f, 0x49, 0xf4, 0xc4, 0x21, 0x69, 0x3a,
+ 0xf1, 0xb0, 0x34, 0x1f, 0x27, 0xc6, 0x63, 0xec, 0xde, 0xda, 0xd5, 0x2c,
+ 0xc4, 0xdc, 0x43, 0x18, 0xfb, 0xb0, 0x7c, 0xdf, 0x33, 0x73, 0x5a, 0xc4,
+ 0x1c, 0x59, 0xc7, 0xe4, 0x0d, 0x1e, 0xdf, 0x85, 0xf9, 0x70, 0xfd, 0x49,
+ 0x8d, 0xfb, 0x76, 0x35, 0xf8, 0xae, 0x4d, 0xda, 0x77, 0x65, 0xbb, 0x4f,
+ 0x61, 0xad, 0x27, 0x25, 0xea, 0x9a, 0xf6, 0xbb, 0x51, 0x2f, 0xd1, 0x70,
+ 0x07, 0x82, 0x75, 0xf4, 0x9d, 0x80, 0x36, 0xe2, 0x1e, 0x9e, 0xb7, 0xb3,
+ 0x2c, 0x38, 0xf3, 0xb7, 0xaa, 0xbb, 0xc2, 0x6b, 0xc7, 0xdf, 0xd9, 0x50,
+ 0xd7, 0x94, 0x99, 0x36, 0xd1, 0xc0, 0xe7, 0x1f, 0x88, 0x36, 0xb4, 0x83,
+ 0x71, 0x53, 0x69, 0xe0, 0x7b, 0x04, 0x7e, 0x10, 0xd7, 0x90, 0x6e, 0xc0,
+ 0x39, 0x6b, 0xbf, 0x45, 0xcc, 0xa3, 0xbc, 0x30, 0x67, 0xee, 0x91, 0x59,
+ 0x58, 0x8b, 0x53, 0xa4, 0xff, 0x62, 0xf3, 0x4e, 0xee, 0x5c, 0x11, 0xf3,
+ 0xbe, 0x49, 0xdd, 0x25, 0xe2, 0xdd, 0x0d, 0xd4, 0x4b, 0x06, 0xf8, 0x93,
+ 0xf9, 0x04, 0x78, 0x7e, 0x5b, 0x97, 0x95, 0xf9, 0xf3, 0x1b, 0x73, 0x03,
+ 0xc4, 0x37, 0x5b, 0x79, 0x0e, 0x09, 0xdc, 0x4c, 0x39, 0xfb, 0x2e, 0xe4,
+ 0xac, 0x59, 0x9d, 0xfb, 0x94, 0xca, 0xf4, 0xe7, 0x0a, 0x90, 0x1f, 0xde,
+ 0x87, 0xa3, 0xdf, 0x57, 0xd0, 0xf1, 0x58, 0xce, 0x93, 0x98, 0xde, 0xf8,
+ 0x07, 0xec, 0x73, 0xfd, 0x19, 0x6c, 0xe3, 0xfd, 0x12, 0xca, 0x5b, 0x42,
+ 0xcd, 0x79, 0x78, 0x9d, 0xbf, 0x72, 0x04, 0xba, 0x60, 0x01, 0xf2, 0x3c,
+ 0x09, 0x1d, 0x38, 0x14, 0xe6, 0xfe, 0x6c, 0xd1, 0xbe, 0xac, 0x4b, 0xbf,
+ 0x3d, 0x34, 0x86, 0x3e, 0xac, 0xe3, 0xaf, 0xcb, 0x14, 0xf4, 0xff, 0x74,
+ 0x3d, 0xa5, 0xbe, 0x17, 0xc9, 0x26, 0x78, 0x07, 0x8c, 0xe5, 0x63, 0x18,
+ 0xff, 0x75, 0xe0, 0xe1, 0xcd, 0xa0, 0xa7, 0xa5, 0x79, 0xf5, 0x2b, 0x3a,
+ 0x16, 0x15, 0x63, 0x2c, 0x1e, 0x7a, 0xb3, 0x14, 0x60, 0xcd, 0xf8, 0x34,
+ 0xd2, 0xcd, 0x2d, 0x81, 0xbc, 0x4e, 0x6e, 0xd5, 0x77, 0x2f, 0x50, 0xfe,
+ 0x98, 0x8a, 0x41, 0x06, 0x6b, 0x72, 0xb4, 0xaf, 0x12, 0x85, 0xcc, 0x71,
+ 0x5d, 0xf7, 0xa2, 0x1e, 0x65, 0xad, 0x4f, 0x9f, 0xcd, 0xb6, 0x28, 0xfd,
+ 0x98, 0x87, 0x2c, 0x15, 0x94, 0x1f, 0x01, 0x7c, 0xef, 0xb1, 0xdd, 0xaf,
+ 0x6f, 0xe5, 0xd9, 0x67, 0x93, 0xab, 0x7c, 0x8b, 0xce, 0xb0, 0x98, 0xb2,
+ 0x8f, 0xa0, 0x8c, 0x72, 0x76, 0x03, 0x78, 0xc3, 0xb2, 0x1c, 0xf2, 0x1c,
+ 0xeb, 0x46, 0x3d, 0x0e, 0xc7, 0xb8, 0xb4, 0x79, 0xed, 0x9c, 0xb8, 0x96,
+ 0xce, 0x75, 0x77, 0xe7, 0x59, 0x76, 0x83, 0x2e, 0x8b, 0xe8, 0xf5, 0xfd,
+ 0xa9, 0xfe, 0xb6, 0xc1, 0x39, 0x9a, 0x5d, 0xc1, 0xc6, 0x9c, 0x5f, 0x4c,
+ 0xb5, 0xcb, 0xda, 0x81, 0xec, 0x1c, 0x01, 0x3f, 0x22, 0x99, 0xaf, 0xf1,
+ 0x4c, 0x19, 0xf4, 0x35, 0x7b, 0x22, 0xa1, 0xfc, 0xce, 0xa4, 0x15, 0xdc,
+ 0x5d, 0xba, 0x58, 0x6e, 0xf4, 0x19, 0xcc, 0xfd, 0x6f, 0x57, 0xc6, 0x56,
+ 0x78, 0x45, 0xbe, 0x91, 0x5f, 0xef, 0xc6, 0x2b, 0xf2, 0x91, 0xfc, 0x2a,
+ 0x48, 0x69, 0x96, 0x7c, 0xa2, 0xbc, 0x8c, 0x29, 0x79, 0x29, 0x55, 0x0c,
+ 0x4e, 0xa6, 0x2e, 0xe1, 0x37, 0x0f, 0x1b, 0x9d, 0xd7, 0x9b, 0xbb, 0x61,
+ 0xbf, 0x44, 0xfa, 0x85, 0x86, 0xe1, 0x1e, 0x2d, 0xcc, 0x2a, 0x9d, 0x02,
+ 0xbb, 0x98, 0x50, 0xba, 0xa2, 0x30, 0xce, 0xfc, 0xd2, 0x56, 0x7e, 0x9b,
+ 0x8b, 0x79, 0xa0, 0xbc, 0x53, 0xf3, 0xf5, 0x06, 0x75, 0xbf, 0x89, 0x7b,
+ 0xb0, 0x54, 0xa9, 0xab, 0xf7, 0x67, 0xe7, 0x9a, 0x54, 0xfd, 0xb3, 0x73,
+ 0xeb, 0xef, 0x28, 0xb1, 0xec, 0x66, 0xc6, 0x55, 0x64, 0x71, 0xa6, 0x49,
+ 0x96, 0xe6, 0xfe, 0x90, 0x7e, 0x22, 0x8c, 0xc1, 0xca, 0xf7, 0x1d, 0xfa,
+ 0x5b, 0x2c, 0x5f, 0x86, 0x21, 0x37, 0x0b, 0x83, 0xd3, 0x52, 0x1d, 0xa4,
+ 0x1f, 0xa4, 0xee, 0x0e, 0x62, 0xbd, 0x4d, 0xc0, 0xc0, 0xc0, 0x85, 0x2e,
+ 0xe3, 0xcf, 0x5b, 0xb4, 0x3e, 0x79, 0xb0, 0x75, 0x25, 0x2e, 0x1d, 0x2f,
+ 0xfa, 0x55, 0xd7, 0x7c, 0x33, 0xc3, 0x3e, 0xf9, 0xdd, 0x0c, 0x79, 0x66,
+ 0xa1, 0x3d, 0xef, 0x64, 0x76, 0x33, 0xae, 0xad, 0xf9, 0x1c, 0x46, 0x7d,
+ 0xa6, 0xbf, 0xa7, 0xf3, 0x73, 0x3a, 0xfd, 0xac, 0xec, 0x3f, 0xf9, 0x19,
+ 0xcc, 0x7b, 0x53, 0x70, 0xef, 0x4a, 0x1a, 0xbf, 0x9b, 0x88, 0xe8, 0x6f,
+ 0x34, 0x3e, 0x8b, 0x32, 0xc6, 0xe2, 0x3e, 0xab, 0xd6, 0xc4, 0xbb, 0x7d,
+ 0x45, 0xf9, 0x79, 0x77, 0x54, 0x8c, 0x3f, 0xc8, 0xfb, 0x53, 0x2d, 0xba,
+ 0xbf, 0x3d, 0x5a, 0x96, 0xc6, 0x65, 0x3f, 0xec, 0x5d, 0x01, 0xb8, 0x98,
+ 0x77, 0xce, 0x26, 0xc2, 0x8d, 0x63, 0x9a, 0xfd, 0x14, 0xc4, 0x1a, 0xcc,
+ 0xdd, 0x87, 0xb0, 0xf2, 0x89, 0x56, 0xe2, 0x16, 0xba, 0x7c, 0x5c, 0x0e,
+ 0x94, 0x55, 0xfc, 0x42, 0x9d, 0x59, 0x4e, 0x43, 0x2f, 0x0c, 0x29, 0x9b,
+ 0x16, 0x0b, 0x0d, 0xd7, 0x32, 0x52, 0x38, 0xbd, 0x17, 0xe3, 0x30, 0x16,
+ 0x98, 0xd5, 0x67, 0x83, 0xfb, 0x64, 0x7f, 0x3d, 0x18, 0x7b, 0xb2, 0xcc,
+ 0xf7, 0x29, 0xe0, 0x04, 0xbe, 0xcf, 0x27, 0xc2, 0xea, 0x74, 0xe3, 0x56,
+ 0xb4, 0x6d, 0xd2, 0x74, 0xe6, 0xbd, 0x6b, 0xb6, 0xa7, 0x0e, 0x00, 0xc0,
+ 0x69, 0xc9, 0xe3, 0x3d, 0xdb, 0x98, 0xfe, 0x26, 0x61, 0xb7, 0xe8, 0x9f,
+ 0x3f, 0x2a, 0xcb, 0x95, 0x69, 0xb9, 0x5c, 0x31, 0xb2, 0xce, 0xbb, 0xd7,
+ 0x9c, 0xfb, 0x5d, 0xc1, 0xb7, 0xbf, 0xe5, 0x2c, 0xf8, 0xb3, 0x96, 0x56,
+ 0xf9, 0x35, 0xdf, 0xdb, 0xfc, 0x2b, 0x3b, 0xf8, 0xe6, 0x6d, 0xb7, 0xba,
+ 0xc3, 0xb5, 0x76, 0xcf, 0xb1, 0x9f, 0xfd, 0x36, 0xcf, 0x3a, 0x82, 0x7b,
+ 0x68, 0x9d, 0x0d, 0xef, 0xe3, 0xfa, 0xee, 0xd7, 0xa7, 0xec, 0x80, 0x8f,
+ 0xa4, 0xe7, 0x98, 0x9e, 0xef, 0xad, 0xd8, 0xff, 0xec, 0xf3, 0x31, 0xcd,
+ 0x37, 0xa4, 0x0b, 0x7c, 0xe6, 0xfe, 0x5a, 0xd6, 0xe7, 0xbf, 0xb6, 0x1e,
+ 0xa3, 0xf1, 0xee, 0x5d, 0x53, 0xc3, 0xb8, 0x6c, 0x4f, 0xfb, 0x64, 0xee,
+ 0x80, 0xb3, 0xec, 0xa4, 0xbe, 0xe3, 0x77, 0xb5, 0xa1, 0xcc, 0xdc, 0x45,
+ 0x23, 0xbd, 0x18, 0xd3, 0x44, 0x5a, 0x1f, 0xd3, 0xcf, 0x63, 0x0d, 0xdf,
+ 0xc8, 0x98, 0x3e, 0x23, 0xe8, 0xc3, 0xdc, 0x41, 0x6f, 0xbc, 0x53, 0xcc,
+ 0xef, 0x83, 0x28, 0x8b, 0x16, 0xbf, 0x61, 0xa6, 0x1f, 0x08, 0xec, 0xb6,
+ 0x45, 0x26, 0xd5, 0x7c, 0x8a, 0xea, 0xbe, 0x06, 0xbf, 0x9b, 0x19, 0xb2,
+ 0x83, 0xfc, 0xe4, 0xc2, 0x7a, 0x39, 0x65, 0xf9, 0x33, 0xcd, 0xd2, 0x52,
+ 0xc4, 0x38, 0x7c, 0xbf, 0xd1, 0xf7, 0xf4, 0x51, 0xfd, 0x9d, 0x90, 0x87,
+ 0x36, 0x4f, 0x50, 0xde, 0x8b, 0xc5, 0x95, 0x7b, 0xa2, 0xc5, 0xe0, 0x1b,
+ 0x26, 0xcb, 0xdc, 0xd7, 0xe4, 0x37, 0xda, 0x22, 0x17, 0x6a, 0xfc, 0x3e,
+ 0x69, 0xb7, 0xba, 0x47, 0x13, 0x9c, 0x4d, 0x72, 0x5e, 0x3d, 0xca, 0x2e,
+ 0x54, 0x6b, 0x25, 0xd2, 0x54, 0xdb, 0xf6, 0xa8, 0xb6, 0xed, 0xa4, 0xf1,
+ 0x08, 0x68, 0xfc, 0x25, 0xcd, 0x17, 0xb6, 0xcf, 0xaa, 0xfb, 0xdd, 0xd9,
+ 0x38, 0xcf, 0xc7, 0x1e, 0x53, 0x6b, 0xa1, 0x9d, 0x40, 0xdb, 0x5f, 0x0e,
+ 0xab, 0x78, 0xa7, 0xfa, 0x06, 0x1c, 0xf2, 0xc9, 0x6f, 0xba, 0xa1, 0xe3,
+ 0xcb, 0xfc, 0x76, 0x7b, 0x04, 0x29, 0xbf, 0xd9, 0xde, 0xab, 0xee, 0xff,
+ 0x57, 0xd5, 0x37, 0x01, 0x46, 0x1e, 0xc3, 0x7a, 0xac, 0x6f, 0x62, 0x8c,
+ 0x80, 0xef, 0x85, 0x32, 0xbf, 0xe5, 0x36, 0x77, 0x4c, 0x37, 0x2f, 0x73,
+ 0x4f, 0x88, 0xf2, 0xf3, 0x83, 0x6f, 0xfb, 0xab, 0xea, 0x3b, 0x82, 0x24,
+ 0xbf, 0x2b, 0x84, 0xfd, 0xba, 0x1f, 0xcf, 0x3c, 0x57, 0xde, 0x87, 0x14,
+ 0xfa, 0xa7, 0x36, 0x81, 0xf4, 0x61, 0xc9, 0xab, 0xb8, 0x5f, 0x2b, 0xf2,
+ 0x93, 0x6a, 0xec, 0x52, 0xed, 0x13, 0xb2, 0xff, 0xf4, 0x43, 0xfc, 0x5e,
+ 0x42, 0x7d, 0x77, 0x9e, 0xf3, 0x38, 0xc7, 0xb8, 0x4c, 0xa9, 0x75, 0x17,
+ 0x35, 0xed, 0xcd, 0x59, 0xcc, 0xcf, 0xd4, 0xb7, 0x19, 0xc5, 0x5a, 0x2b,
+ 0xe6, 0x18, 0xd2, 0xf7, 0x4c, 0xe9, 0x0f, 0x98, 0xf5, 0xb7, 0xf0, 0xee,
+ 0xa2, 0xcf, 0xf3, 0xc3, 0xfd, 0x65, 0xde, 0x23, 0x4d, 0xe9, 0x38, 0x01,
+ 0x63, 0x87, 0x3c, 0x9f, 0xa0, 0x8c, 0x3b, 0xe9, 0x09, 0x58, 0xa0, 0xa8,
+ 0x24, 0x78, 0xb6, 0xad, 0xd7, 0xd2, 0xda, 0xb0, 0x16, 0xde, 0x9d, 0x0d,
+ 0xd6, 0xc3, 0xef, 0x21, 0x0a, 0xe5, 0xc6, 0x6f, 0x2a, 0xd4, 0x37, 0xd0,
+ 0xfc, 0x76, 0x46, 0x26, 0x6a, 0x9f, 0x94, 0x07, 0xca, 0x5b, 0xf4, 0xf7,
+ 0x14, 0x31, 0x79, 0xa0, 0xf6, 0xba, 0xa2, 0x69, 0x41, 0x7d, 0xd7, 0x11,
+ 0xd5, 0x3c, 0x33, 0xdf, 0x54, 0x04, 0xfd, 0x1d, 0xa8, 0x39, 0x0d, 0xdf,
+ 0x2f, 0x44, 0x65, 0x62, 0xe1, 0x47, 0x91, 0x8d, 0xbf, 0x61, 0x78, 0x54,
+ 0x72, 0xa7, 0x69, 0xa3, 0xa7, 0xe5, 0xf1, 0x8a, 0xef, 0xdf, 0xe9, 0x11,
+ 0x5b, 0x6e, 0x96, 0xcb, 0xf1, 0xb1, 0x3d, 0x6f, 0xb8, 0x1d, 0xa1, 0xea,
+ 0x6c, 0x33, 0x74, 0x2f, 0xf1, 0x8c, 0xb4, 0x30, 0xbf, 0x30, 0xcb, 0x7d,
+ 0x1a, 0xc1, 0x1a, 0x1d, 0xfb, 0x9a, 0xdc, 0xde, 0xce, 0xb8, 0xdb, 0x9d,
+ 0xf0, 0x65, 0x7f, 0xdb, 0x0b, 0xf4, 0xf5, 0xe7, 0x16, 0xf7, 0xca, 0xe7,
+ 0x6a, 0xb1, 0x50, 0x75, 0x86, 0xf7, 0x0d, 0x9d, 0x91, 0x8a, 0xa4, 0x50,
+ 0x8f, 0xfd, 0x43, 0x5e, 0x12, 0xd7, 0xc9, 0xb3, 0x27, 0x7f, 0xea, 0x5f,
+ 0x73, 0xf1, 0x1e, 0xba, 0xe6, 0xb2, 0x67, 0x62, 0x8b, 0x63, 0xf0, 0x5d,
+ 0x59, 0xef, 0x3a, 0xc8, 0x01, 0xb0, 0x03, 0xf6, 0x1c, 0xfd, 0xdc, 0x6b,
+ 0x5a, 0x6f, 0x59, 0xc7, 0x6e, 0x92, 0x6b, 0x2b, 0xf7, 0x95, 0x5f, 0x83,
+ 0x6c, 0x27, 0x03, 0xfa, 0xab, 0x58, 0xfc, 0x21, 0x09, 0x7f, 0x1e, 0x36,
+ 0xe5, 0xf3, 0x4d, 0x4a, 0xb7, 0xd3, 0xb6, 0xc1, 0x07, 0x82, 0x9f, 0x13,
+ 0x41, 0x3f, 0xa9, 0xf6, 0x40, 0x66, 0xa7, 0x45, 0xbe, 0xb0, 0x49, 0xb2,
+ 0xed, 0xf4, 0xa3, 0xe5, 0xe7, 0xe8, 0xaf, 0xc6, 0x7d, 0x96, 0x96, 0x3f,
+ 0xe2, 0x1e, 0xaf, 0x73, 0x2d, 0xa9, 0xc4, 0x9f, 0xc9, 0xa7, 0x65, 0x22,
+ 0xc1, 0xb5, 0x3c, 0x2a, 0xc5, 0xca, 0x63, 0xf8, 0x71, 0x9d, 0x9c, 0xf7,
+ 0xc7, 0xf4, 0x5d, 0x86, 0x31, 0x29, 0xcd, 0x64, 0x64, 0x6a, 0x6e, 0x92,
+ 0xdf, 0xa0, 0x8e, 0xdc, 0xa9, 0xce, 0xf8, 0x9c, 0x44, 0x2a, 0xb4, 0x2d,
+ 0x39, 0xc5, 0xbb, 0x1b, 0x6a, 0x3d, 0x93, 0x58, 0xcf, 0xe3, 0xed, 0xbc,
+ 0xb3, 0x7e, 0x0d, 0xfa, 0xd7, 0x3a, 0x45, 0x39, 0x74, 0xec, 0xee, 0x10,
+ 0xf3, 0xfb, 0xe0, 0xbf, 0xb3, 0x6c, 0x9f, 0x84, 0x8f, 0xad, 0xe8, 0x79,
+ 0x94, 0xeb, 0xb3, 0x66, 0xd5, 0xfe, 0x14, 0xda, 0xa2, 0xde, 0x31, 0xd3,
+ 0xd6, 0xd4, 0x61, 0x5b, 0xae, 0x73, 0xaf, 0x34, 0x9f, 0x33, 0xf3, 0x82,
+ 0x1c, 0x26, 0x1a, 0xe9, 0xdd, 0xb2, 0x8e, 0xde, 0x11, 0x62, 0x5e, 0xd0,
+ 0x8b, 0x34, 0x0e, 0x6b, 0x1a, 0x7f, 0x05, 0xfd, 0x1b, 0x1e, 0xdc, 0x89,
+ 0x32, 0x5b, 0x7f, 0x93, 0xf4, 0x7e, 0xe8, 0x4e, 0x9a, 0xb3, 0x3e, 0xe9,
+ 0x4e, 0xd9, 0xe2, 0x7c, 0x36, 0xa2, 0xf9, 0xeb, 0x9a, 0x2f, 0xfb, 0x40,
+ 0x2f, 0xde, 0x2b, 0xdd, 0xa6, 0xbe, 0x2f, 0xc8, 0x8e, 0xef, 0x83, 0xec,
+ 0x98, 0x75, 0x6d, 0x83, 0x8c, 0xf1, 0xdc, 0x84, 0xf5, 0x1b, 0x69, 0x12,
+ 0xd8, 0xbd, 0x30, 0x63, 0x1f, 0x2e, 0xd7, 0x0a, 0x5c, 0xfa, 0x05, 0xda,
+ 0x28, 0x7e, 0x63, 0x7d, 0xb3, 0xb6, 0x51, 0x3f, 0x8f, 0xc7, 0x3f, 0x6a,
+ 0x0f, 0x6c, 0x94, 0x0d, 0x9a, 0xb4, 0xe9, 0x36, 0xfb, 0x80, 0x91, 0x19,
+ 0x0f, 0x4e, 0x25, 0x1e, 0x14, 0x33, 0x8e, 0xbf, 0x9b, 0x7e, 0xef, 0xd0,
+ 0xc0, 0x36, 0xa0, 0x16, 0x75, 0x67, 0x27, 0xc1, 0x3b, 0x40, 0xa9, 0xd0,
+ 0x3e, 0x75, 0x7f, 0x63, 0xed, 0xf7, 0x23, 0x69, 0x79, 0x76, 0x55, 0x56,
+ 0x46, 0x7e, 0x28, 0x8e, 0x24, 0x6f, 0xa4, 0xac, 0xb0, 0xdf, 0x49, 0xae,
+ 0x33, 0xf1, 0x90, 0x5a, 0xa7, 0x0d, 0x3f, 0x92, 0x77, 0x2d, 0xec, 0x50,
+ 0x75, 0x8e, 0x7c, 0x47, 0xba, 0xc8, 0x67, 0x73, 0xde, 0xab, 0xf4, 0x0a,
+ 0xc6, 0x65, 0x19, 0x75, 0x23, 0xdf, 0x67, 0xf4, 0x79, 0x70, 0x7b, 0x07,
+ 0xef, 0x24, 0x14, 0x50, 0x56, 0x59, 0xdc, 0x78, 0x6e, 0xbf, 0xad, 0xe4,
+ 0xe0, 0x51, 0xd0, 0xfd, 0x9f, 0xa1, 0xee, 0x63, 0x48, 0xb9, 0xc6, 0xcc,
+ 0x0a, 0xdf, 0x49, 0xef, 0x8f, 0xca, 0x20, 0xe4, 0x82, 0xf9, 0x47, 0x81,
+ 0x37, 0x69, 0x4f, 0x91, 0x56, 0xf8, 0x4c, 0x5d, 0xef, 0x6a, 0x7b, 0xca,
+ 0xb9, 0xec, 0xc3, 0x5c, 0xd4, 0x3a, 0xb5, 0x3c, 0xdd, 0xaf, 0xdb, 0x8d,
+ 0xaf, 0xd0, 0xea, 0xa1, 0x77, 0xe0, 0x8d, 0xe8, 0x0a, 0xde, 0x08, 0xc6,
+ 0xca, 0x76, 0x18, 0xac, 0x11, 0xac, 0x21, 0xc0, 0x1a, 0x81, 0x9c, 0x4f,
+ 0x4a, 0x04, 0x72, 0x1c, 0x5e, 0x95, 0x63, 0xe0, 0x9e, 0x60, 0xcf, 0x4c,
+ 0xf1, 0x1c, 0x53, 0xd1, 0x99, 0x72, 0x48, 0xf9, 0x25, 0x1f, 0x1b, 0x79,
+ 0x7d, 0xfb, 0xbb, 0xf0, 0xba, 0xd4, 0x61, 0xf0, 0xc3, 0x3f, 0x6c, 0x1f,
+ 0x3c, 0xd2, 0xb1, 0xba, 0x0f, 0x6e, 0xfa, 0x05, 0xed, 0x83, 0xf5, 0x72,
+ 0xd9, 0x28, 0x53, 0x36, 0xe4, 0x89, 0xfc, 0xa2, 0x3c, 0x51, 0x8e, 0x48,
+ 0x4b, 0xea, 0xd3, 0x66, 0xfa, 0x6f, 0x89, 0xab, 0xea, 0xdb, 0x91, 0x69,
+ 0xe8, 0xa0, 0x8e, 0x50, 0xa5, 0x12, 0x97, 0xd2, 0xe2, 0x4f, 0x94, 0x4c,
+ 0x3f, 0x5b, 0xa7, 0x5e, 0x7a, 0xaf, 0xb5, 0xaf, 0xd5, 0xb9, 0x85, 0x75,
+ 0x3a, 0xb7, 0xb0, 0xa2, 0x73, 0xdb, 0xb5, 0xcf, 0xf6, 0x0f, 0xd1, 0xb9,
+ 0xf1, 0x86, 0xb3, 0x21, 0x73, 0x2e, 0x24, 0xa1, 0x5c, 0x5f, 0x8b, 0xec,
+ 0x81, 0x1d, 0x19, 0x99, 0xd9, 0x2b, 0x7f, 0x30, 0x33, 0xad, 0xee, 0x49,
+ 0x7d, 0xd3, 0x4b, 0x25, 0x3e, 0x11, 0xf2, 0xe5, 0xa3, 0xf0, 0xb9, 0x27,
+ 0xba, 0x9a, 0x64, 0xcf, 0x6d, 0xea, 0xbc, 0xd3, 0xce, 0x85, 0x3a, 0x85,
+ 0x91, 0xf8, 0xbc, 0xe7, 0x78, 0xc9, 0x10, 0xef, 0xcc, 0x35, 0xcb, 0x44,
+ 0xbc, 0x55, 0xf6, 0x02, 0x3b, 0x15, 0xaf, 0xf7, 0xd4, 0x37, 0xd3, 0x59,
+ 0x75, 0x9e, 0xf4, 0x86, 0xe6, 0x3b, 0xe8, 0xd0, 0x66, 0xcb, 0x7f, 0xac,
+ 0x33, 0xcf, 0xf2, 0x07, 0xd7, 0xe5, 0xf9, 0xfc, 0x04, 0xfc, 0xb9, 0x38,
+ 0x68, 0xd5, 0x78, 0xff, 0x28, 0xac, 0xe8, 0x59, 0xaa, 0x8c, 0xab, 0x7b,
+ 0x5d, 0x57, 0xc3, 0xa4, 0x97, 0xf2, 0xa1, 0x12, 0xb9, 0x30, 0x30, 0xce,
+ 0x2c, 0x90, 0xb4, 0x4b, 0xbf, 0x53, 0xe3, 0x4f, 0xe8, 0xff, 0xfd, 0xea,
+ 0x7c, 0x79, 0x19, 0xb4, 0xf1, 0x55, 0xfc, 0xb9, 0x10, 0x27, 0xae, 0x5f,
+ 0xbd, 0xc3, 0xfc, 0x4e, 0x7c, 0xaf, 0xb0, 0xbd, 0x39, 0x0b, 0xd1, 0xf1,
+ 0x2a, 0x1d, 0x07, 0x50, 0x67, 0x7b, 0x1b, 0xfd, 0xbf, 0x0b, 0xc4, 0x7a,
+ 0xfc, 0xae, 0x9f, 0xd8, 0xce, 0x39, 0x5a, 0x91, 0x1f, 0x2a, 0x5f, 0x34,
+ 0x4b, 0xfa, 0x56, 0xc1, 0xa7, 0xe3, 0x09, 0x63, 0xcf, 0x43, 0xdd, 0xe7,
+ 0x1b, 0x7d, 0x51, 0xf6, 0x11, 0x53, 0x77, 0x42, 0x56, 0xff, 0x9f, 0x17,
+ 0xc6, 0x98, 0xb2, 0xa1, 0xbb, 0xcb, 0xd3, 0x12, 0x3e, 0x31, 0x26, 0x91,
+ 0xe3, 0x8c, 0xe7, 0x67, 0xa5, 0x14, 0xf7, 0xe5, 0x01, 0x6f, 0xad, 0x6f,
+ 0xd2, 0x6d, 0xad, 0x9f, 0xfb, 0xa3, 0x32, 0x74, 0xfa, 0x31, 0x89, 0x9e,
+ 0xe0, 0xbb, 0x35, 0x67, 0x39, 0xd0, 0x47, 0x9b, 0xa5, 0x12, 0x67, 0x4c,
+ 0x3b, 0xaa, 0xce, 0xc6, 0x2f, 0x8f, 0xbf, 0x1e, 0x2d, 0x01, 0x2b, 0x14,
+ 0x94, 0x6e, 0x41, 0xba, 0xe2, 0x4b, 0xe4, 0xae, 0xe3, 0x9e, 0x82, 0xbf,
+ 0x19, 0x9a, 0xa8, 0x44, 0xd5, 0x1d, 0xa5, 0xcb, 0x71, 0xd6, 0x7d, 0x0c,
+ 0x7e, 0x37, 0x71, 0x06, 0x74, 0xc7, 0x98, 0xb4, 0x30, 0x1f, 0x3e, 0xb1,
+ 0x8a, 0x33, 0xa8, 0x13, 0x86, 0xbc, 0xb8, 0x44, 0xce, 0x04, 0x6b, 0xe7,
+ 0x7f, 0x1c, 0x64, 0xcd, 0xef, 0x95, 0xf0, 0x71, 0x3e, 0x37, 0xfa, 0x43,
+ 0xc4, 0xee, 0xb0, 0x0d, 0xe7, 0x7f, 0x1f, 0xfd, 0xf1, 0x5d, 0x56, 0x7f,
+ 0x87, 0x8b, 0x7c, 0xf5, 0xef, 0xfa, 0x7f, 0x04, 0x50, 0xf6, 0xff, 0x3f,
+ 0xc3, 0x8e, 0xbb, 0xb0, 0xa8, 0x4d, 0x00, 0x00, 0x00 };
static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_COM_b06FwRodata[(0x14/4) + 1] = {
- 0x08000e7c, 0x08000ec4, 0x08000ef8, 0x08000f44, 0x08000f78, 0x00000000
+ 0x08000e7c, 0x08000ec4, 0x08000f04, 0x08000f50, 0x08000f84, 0x00000000
};
static struct fw_info bnx2_com_fw_06 = {
- /* Firmware version: 4.4.2 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x2,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
.start_addr = 0x080000f8,
.text_addr = 0x08000000,
- .text_len = 0x4ebc,
+ .text_len = 0x4da4,
.text_index = 0x0,
.gz_text = bnx2_COM_b06FwText,
.gz_text_len = sizeof(bnx2_COM_b06FwText),
@@ -872,15 +867,15 @@ static struct fw_info bnx2_com_fw_06 = {
.data_index = 0x0,
.data = bnx2_COM_b06FwData,
- .sbss_addr = 0x08004f00,
+ .sbss_addr = 0x08004de0,
.sbss_len = 0x38,
.sbss_index = 0x0,
- .bss_addr = 0x08004f38,
+ .bss_addr = 0x08004e18,
.bss_len = 0xbc,
.bss_index = 0x0,
- .rodata_addr = 0x08004ebc,
+ .rodata_addr = 0x08004da4,
.rodata_len = 0x14,
.rodata_index = 0x0,
.rodata = bnx2_COM_b06FwRodata,
@@ -903,1232 +898,1219 @@ static const struct cpu_reg cpu_reg_com = {
};
static u8 bnx2_CP_b06FwText[] = {
- 0x9d, 0xbc, 0x0d, 0x78, 0x1b, 0xe5, 0x95, 0x36, 0x7c, 0xcf, 0x48, 0xb2,
- 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x9c, 0x28, 0x6c, 0x9a, 0x68, 0xf0, 0x28,
- 0x51, 0xb0, 0x69, 0x47, 0x89, 0x03, 0x82, 0x55, 0x89, 0xea, 0x98, 0xc4,
- 0x81, 0x50, 0x9c, 0x12, 0x5a, 0xb3, 0x4b, 0x5b, 0xe1, 0xfc, 0x60, 0x42,
- 0xa0, 0xa1, 0xb0, 0xef, 0x9a, 0xef, 0x65, 0x5f, 0xab, 0xb6, 0x93, 0x38,
- 0x89, 0x2c, 0x39, 0x8e, 0x21, 0x61, 0xbf, 0x5e, 0x8b, 0x89, 0x9d, 0x38,
- 0x80, 0x6c, 0x85, 0x36, 0xdd, 0x0d, 0x7d, 0xd3, 0x8d, 0x36, 0x09, 0x60,
- 0xfe, 0xda, 0x40, 0xbb, 0x2c, 0xed, 0xcb, 0x07, 0xde, 0x14, 0x42, 0xd8,
- 0xb6, 0x40, 0xb7, 0x3f, 0x1b, 0x5a, 0xca, 0xbc, 0xf7, 0x19, 0x49, 0x89,
- 0x13, 0x28, 0xed, 0x7e, 0xbe, 0xae, 0xb9, 0xac, 0x99, 0x79, 0x7e, 0xce,
- 0x73, 0x9e, 0x73, 0xee, 0x73, 0x9f, 0x67, 0x9e, 0x19, 0x3f, 0x50, 0x8a,
- 0xfc, 0x5f, 0x39, 0x8f, 0x4f, 0x37, 0x6c, 0x5c, 0xbd, 0x60, 0xc1, 0xa7,
- 0x1b, 0xe4, 0xdc, 0x39, 0xdd, 0xe9, 0xc4, 0x9f, 0xf9, 0xe7, 0xff, 0x73,
- 0x0b, 0x7e, 0xcc, 0x9f, 0x03, 0xd0, 0x0a, 0xfd, 0xcb, 0x01, 0xb7, 0x1a,
- 0x71, 0xde, 0xdc, 0x68, 0xc0, 0xed, 0x88, 0x4c, 0xb4, 0xad, 0x36, 0x80,
- 0x68, 0xba, 0xce, 0xbf, 0x04, 0x7f, 0xb0, 0xe2, 0x5e, 0x27, 0xe4, 0xfa,
- 0xa7, 0x22, 0x1f, 0x74, 0x7e, 0xef, 0x72, 0xfd, 0xbd, 0x21, 0x07, 0xdc,
- 0x5a, 0x24, 0x0e, 0x6d, 0x2e, 0xdc, 0xb3, 0x58, 0xe7, 0x9b, 0xf3, 0xbe,
- 0xa9, 0xa0, 0xa2, 0xd0, 0xd6, 0x69, 0xeb, 0x7b, 0xf3, 0x7c, 0xb1, 0x92,
- 0x88, 0x86, 0x23, 0x19, 0xb4, 0xd4, 0xf7, 0x75, 0x5a, 0xe5, 0x46, 0x08,
- 0x6e, 0xc3, 0x68, 0xed, 0x53, 0x3c, 0xe1, 0xf5, 0x8b, 0xe0, 0x29, 0x36,
- 0x10, 0xbf, 0x28, 0x82, 0x96, 0x4b, 0xc6, 0x4a, 0xe3, 0xce, 0x88, 0x1b,
- 0xcd, 0x19, 0x77, 0xfc, 0x2f, 0x22, 0x06, 0x96, 0x65, 0x66, 0x95, 0xa2,
- 0xc2, 0x8d, 0x9e, 0xcc, 0xeb, 0x25, 0xb9, 0xf6, 0xea, 0xf3, 0xff, 0x83,
- 0xd3, 0x72, 0xff, 0xa7, 0xc7, 0x9c, 0x11, 0x60, 0x53, 0xc2, 0xb2, 0x8a,
- 0x22, 0x37, 0xdc, 0xa0, 0x46, 0x0c, 0xdf, 0x3e, 0x2c, 0x46, 0x9b, 0x86,
- 0xfb, 0x36, 0x37, 0xfc, 0xa7, 0x72, 0x74, 0x90, 0x0d, 0x8f, 0x3a, 0x10,
- 0xd5, 0x8e, 0xf3, 0xff, 0xec, 0xd9, 0xad, 0x61, 0x03, 0xbb, 0x47, 0xcf,
- 0xf0, 0xba, 0xd3, 0xbe, 0xd6, 0xbd, 0x6b, 0xf6, 0xec, 0x9b, 0xc2, 0xc7,
- 0xf1, 0xe0, 0xa8, 0xfc, 0xbe, 0x15, 0x9d, 0xf5, 0x0a, 0x26, 0x6f, 0x58,
- 0x07, 0x87, 0x61, 0xa0, 0x67, 0x97, 0xe2, 0xec, 0xaa, 0x57, 0x11, 0xf5,
- 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20, 0x56, 0x1c, 0x09, 0x3b, 0xdf,
- 0x4e, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1, 0xd0, 0x0c, 0x38, 0xaa, 0x2c,
- 0xeb, 0x09, 0xd3, 0x03, 0xff, 0x97, 0x9e, 0x42, 0x7c, 0xb8, 0x05, 0xaa,
- 0xf1, 0x14, 0xba, 0x86, 0x9f, 0xc2, 0x43, 0x3b, 0x4b, 0x31, 0x39, 0x8d,
- 0xe3, 0x4d, 0xf9, 0xf0, 0xbd, 0x79, 0xd2, 0xb7, 0xc8, 0x51, 0xcf, 0xc3,
- 0x8d, 0x49, 0xc7, 0x6b, 0xfc, 0x2f, 0x65, 0xce, 0x58, 0x93, 0x33, 0xce,
- 0x95, 0xd9, 0xc4, 0x32, 0x3d, 0x17, 0x94, 0x89, 0x0f, 0x47, 0xf0, 0x5c,
- 0x42, 0xc1, 0xfa, 0x50, 0x05, 0xa2, 0x55, 0x32, 0x5e, 0xcb, 0x1a, 0x35,
- 0x4f, 0x59, 0x93, 0x9a, 0xf4, 0x35, 0x81, 0xe7, 0x79, 0x6f, 0x73, 0xe8,
- 0x0d, 0x2b, 0xeb, 0x95, 0xf6, 0xbe, 0x4e, 0x1b, 0x5a, 0xc9, 0xeb, 0x4e,
- 0xa4, 0x12, 0x88, 0x55, 0x44, 0x6e, 0xe4, 0xb9, 0x6e, 0xbe, 0xa3, 0xb8,
- 0xdd, 0xef, 0x26, 0xdc, 0x5f, 0x2a, 0x37, 0xd4, 0x7b, 0x2a, 0xe1, 0xc4,
- 0x0b, 0x94, 0xf9, 0x90, 0xb9, 0x0e, 0x2e, 0xe3, 0x6e, 0xb1, 0x39, 0x8e,
- 0xeb, 0x47, 0x16, 0x66, 0x14, 0xea, 0x4b, 0xbb, 0x6e, 0x6c, 0x4e, 0x59,
- 0xd6, 0x56, 0x33, 0x7a, 0x45, 0x09, 0x0d, 0xe2, 0x58, 0xa2, 0x05, 0xee,
- 0x48, 0xc0, 0x7f, 0x1a, 0x61, 0x2c, 0xc9, 0x78, 0xf1, 0x64, 0x02, 0xce,
- 0xc6, 0x79, 0x5e, 0x74, 0x65, 0x22, 0xb8, 0x3a, 0x63, 0xa2, 0x29, 0xf3,
- 0xa7, 0x2d, 0xeb, 0xda, 0x94, 0x9f, 0x63, 0xf8, 0x83, 0x95, 0x1b, 0x83,
- 0x8c, 0x2f, 0xf7, 0xbf, 0x27, 0x75, 0x11, 0xb6, 0x71, 0x8e, 0xb6, 0x70,
- 0xfe, 0x96, 0x87, 0xb2, 0xd1, 0x12, 0xe8, 0xe6, 0x69, 0x44, 0xb0, 0x34,
- 0x63, 0x70, 0x4e, 0x23, 0x58, 0x92, 0xaa, 0xd5, 0x86, 0x31, 0x1f, 0x51,
- 0x5f, 0xce, 0xb6, 0xb7, 0x73, 0xbc, 0x6d, 0x81, 0x16, 0x94, 0xd3, 0x46,
- 0xd2, 0x8b, 0xc2, 0x68, 0x64, 0xff, 0x2b, 0xfe, 0x8c, 0xfe, 0xaf, 0x67,
- 0xff, 0xef, 0xb0, 0xff, 0xac, 0xdd, 0x3f, 0x9c, 0xd7, 0xf0, 0xdc, 0x4d,
- 0x7b, 0xdc, 0x96, 0x76, 0x3a, 0x97, 0xa7, 0xbc, 0xd8, 0x9a, 0x36, 0x69,
- 0x73, 0x72, 0xcb, 0x87, 0xcd, 0x83, 0xb3, 0xb0, 0x65, 0x50, 0xf7, 0x3d,
- 0xcd, 0xdf, 0xdd, 0x23, 0x17, 0x61, 0xd3, 0xa0, 0x82, 0x3d, 0xc6, 0x45,
- 0xe8, 0xe2, 0xef, 0xdd, 0x83, 0xb3, 0xf1, 0xe0, 0xa0, 0x03, 0xe1, 0x69,
- 0xe7, 0x8f, 0x63, 0xd2, 0x71, 0x11, 0xe2, 0x23, 0x7e, 0x74, 0x25, 0x9e,
- 0xb7, 0x75, 0x58, 0x1e, 0xf9, 0x5e, 0xc1, 0x9f, 0xe9, 0x3b, 0x7e, 0xac,
- 0x4e, 0x68, 0xe8, 0x4a, 0x89, 0x1f, 0xb8, 0x69, 0x9b, 0xe2, 0x07, 0xbf,
- 0x06, 0x2a, 0x34, 0x74, 0x67, 0x0a, 0xf7, 0x15, 0x38, 0x39, 0x6f, 0x6b,
- 0x34, 0x37, 0xb6, 0xa6, 0xc4, 0x26, 0xa4, 0x4d, 0xb1, 0x0b, 0xf9, 0x5d,
- 0x4d, 0xbb, 0x2b, 0x85, 0x7f, 0x6f, 0x29, 0x82, 0xf7, 0x6b, 0x78, 0xb3,
- 0x41, 0xae, 0xd3, 0xde, 0x43, 0x52, 0xa6, 0x1f, 0xfb, 0xd2, 0xe2, 0xa7,
- 0x7e, 0x34, 0x26, 0x26, 0xd8, 0x7e, 0x03, 0xdb, 0x36, 0xf1, 0xcf, 0x99,
- 0x7a, 0xfc, 0x53, 0x26, 0x88, 0x7f, 0xa4, 0x1e, 0xbf, 0x93, 0xf1, 0xe3,
- 0x60, 0x66, 0x16, 0xbe, 0x9d, 0xf1, 0xe1, 0x5b, 0x9c, 0xbf, 0xc7, 0x33,
- 0x2d, 0xb4, 0x7d, 0x0d, 0x07, 0x32, 0xa2, 0xff, 0x22, 0x8e, 0xb7, 0x14,
- 0xdd, 0x83, 0xb5, 0xc1, 0x63, 0xb4, 0xad, 0x7f, 0x34, 0xaf, 0x41, 0xb6,
- 0xba, 0xc1, 0xb6, 0xc9, 0xad, 0xbc, 0xbe, 0x6d, 0xb0, 0x36, 0x7a, 0x89,
- 0x62, 0x59, 0x6a, 0xa8, 0x2e, 0x7c, 0x54, 0x55, 0x31, 0xe9, 0xd5, 0xfd,
- 0x59, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82, 0xbe, 0x11, 0xaf, 0xd1, 0x87,
- 0xe2, 0xb4, 0x29, 0xaf, 0x31, 0xcc, 0xf1, 0xe8, 0xfe, 0xb8, 0xea, 0xc6,
- 0x96, 0x94, 0xbe, 0x3b, 0xae, 0x7a, 0x10, 0xcf, 0x94, 0xe2, 0x17, 0x83,
- 0x7a, 0x6f, 0x5c, 0xfd, 0x3c, 0xe2, 0xd5, 0x96, 0xf5, 0xad, 0x10, 0x36,
- 0xce, 0x88, 0x20, 0x5a, 0x13, 0x41, 0x6c, 0x76, 0xc4, 0x8b, 0x54, 0x0a,
- 0x78, 0xa7, 0xcf, 0xf0, 0xfd, 0x9b, 0xd2, 0x82, 0xbf, 0x69, 0xd1, 0xfd,
- 0x7e, 0xb5, 0x2e, 0x3e, 0xac, 0x2e, 0xa2, 0x4b, 0xc3, 0xef, 0x8b, 0x2c,
- 0x43, 0x87, 0x7d, 0x4d, 0x81, 0x66, 0x78, 0xd0, 0x9d, 0xba, 0x02, 0x31,
- 0x6f, 0x6d, 0xeb, 0x0e, 0xb5, 0xf6, 0x8c, 0xa9, 0xea, 0x13, 0x2d, 0xaa,
- 0x65, 0xfd, 0x72, 0xe1, 0x3b, 0x96, 0x7f, 0xba, 0x65, 0x2d, 0x58, 0x28,
- 0x7d, 0xfa, 0x51, 0x15, 0x31, 0xb1, 0xd2, 0x9e, 0xc3, 0x52, 0x9c, 0x1a,
- 0xac, 0x66, 0x1f, 0x1a, 0xfe, 0xf5, 0x72, 0x3d, 0xb8, 0x4e, 0x2d, 0xc5,
- 0x9b, 0x23, 0xa5, 0x38, 0xc9, 0xf1, 0xfc, 0xe7, 0xa0, 0x0f, 0xbf, 0x1e,
- 0xb4, 0xac, 0x2f, 0x99, 0x7f, 0x89, 0x81, 0xea, 0x7e, 0xfc, 0xd3, 0xb8,
- 0x17, 0xbf, 0xe0, 0xdc, 0xbc, 0x91, 0x88, 0xde, 0x35, 0x0d, 0x7a, 0x74,
- 0x5c, 0x39, 0xf6, 0xd5, 0x0a, 0xd4, 0xb5, 0x54, 0x28, 0x7a, 0xf3, 0x76,
- 0xe8, 0xbe, 0x4b, 0x14, 0x2f, 0x4e, 0xa7, 0x35, 0xfc, 0x34, 0x5d, 0x1b,
- 0xfe, 0x21, 0xfb, 0xfc, 0xad, 0xf9, 0x84, 0x95, 0x9d, 0x2e, 0x7a, 0x13,
- 0x1d, 0x51, 0xcf, 0x29, 0xea, 0x39, 0x45, 0x3d, 0xa7, 0xa8, 0x67, 0xca,
- 0x70, 0x30, 0x45, 0x3d, 0x53, 0x77, 0xdf, 0xa2, 0x4d, 0x3d, 0xce, 0x79,
- 0x3c, 0x60, 0xcf, 0x63, 0x98, 0xf3, 0xf5, 0x17, 0xf8, 0x5f, 0x36, 0xb6,
- 0x3e, 0x6f, 0xfd, 0xad, 0x57, 0xc6, 0xd4, 0x3d, 0x3d, 0x87, 0x5f, 0x32,
- 0xb6, 0xe7, 0xac, 0x98, 0x26, 0xe3, 0x92, 0xf1, 0xd9, 0xfa, 0xf3, 0x6f,
- 0x54, 0xb6, 0x28, 0x28, 0xb5, 0xac, 0x9d, 0x66, 0xfe, 0xbe, 0xb7, 0x30,
- 0xbe, 0x1b, 0x94, 0x9c, 0x5d, 0xed, 0x74, 0x53, 0xdf, 0xc1, 0xa8, 0xba,
- 0x8c, 0xe7, 0x7a, 0x3c, 0x8a, 0xb9, 0xc5, 0xe7, 0x9f, 0x5f, 0x5b, 0x23,
- 0xf3, 0xe1, 0x3f, 0x7b, 0x4e, 0x7b, 0xb4, 0xfb, 0xbb, 0x8d, 0xe7, 0x32,
- 0x16, 0xb1, 0x45, 0xb1, 0x01, 0x2f, 0xed, 0xe5, 0xf2, 0xfc, 0x3d, 0xc4,
- 0xd5, 0xc8, 0x46, 0xb4, 0x34, 0x3c, 0x6a, 0xf7, 0x51, 0x94, 0x14, 0xbf,
- 0x51, 0xf0, 0xce, 0x15, 0x0a, 0x8e, 0x86, 0x0c, 0xda, 0xcc, 0x10, 0x71,
- 0x01, 0x28, 0x4e, 0xc2, 0xed, 0x89, 0x44, 0x90, 0xe8, 0x83, 0xbb, 0x24,
- 0x12, 0xc6, 0xfc, 0xbe, 0xda, 0xf6, 0x53, 0xd0, 0x83, 0x7d, 0x8a, 0xde,
- 0x02, 0xd4, 0x99, 0x63, 0xd4, 0xe3, 0x25, 0x8a, 0xee, 0x2f, 0x52, 0xe0,
- 0x56, 0x58, 0x2e, 0x90, 0x1e, 0xc2, 0x96, 0x8c, 0xfc, 0x0e, 0xc3, 0x48,
- 0xff, 0xb6, 0xd0, 0x17, 0xed, 0x7e, 0x23, 0xed, 0xfe, 0x14, 0xc7, 0xae,
- 0xfb, 0x89, 0xaf, 0x6e, 0x57, 0xa4, 0x1d, 0x7b, 0x13, 0x70, 0x17, 0x45,
- 0x36, 0xe0, 0xa9, 0x44, 0xf5, 0xf4, 0x42, 0x39, 0x85, 0xe5, 0xfc, 0xe9,
- 0xa9, 0xb2, 0xbc, 0x66, 0x45, 0xbd, 0x39, 0x59, 0x4a, 0x93, 0x43, 0xd8,
- 0x9e, 0x92, 0xba, 0x11, 0xbb, 0xae, 0x93, 0x7d, 0xf4, 0x24, 0x6a, 0x9b,
- 0xaf, 0x55, 0xf4, 0xf0, 0x23, 0xa8, 0x8b, 0xbe, 0xcd, 0x39, 0xec, 0x82,
- 0x7e, 0xa6, 0x1d, 0x39, 0x59, 0xe6, 0xa5, 0x73, 0x72, 0x2c, 0x4e, 0x43,
- 0xb9, 0x29, 0x05, 0x8f, 0xcf, 0x98, 0x96, 0xf7, 0x65, 0x28, 0xd7, 0x71,
- 0xfe, 0x54, 0xc3, 0x8f, 0xeb, 0x68, 0x43, 0x1b, 0x76, 0x5a, 0xe8, 0x0e,
- 0x55, 0xd3, 0x57, 0x5b, 0x50, 0x41, 0xbf, 0xbc, 0x53, 0x43, 0xb4, 0x32,
- 0x12, 0x56, 0xae, 0xcf, 0x0c, 0xe7, 0xf5, 0x7f, 0xb4, 0x9a, 0xf2, 0x29,
- 0x4d, 0xa9, 0x0b, 0xaf, 0x57, 0xe6, 0xe3, 0xde, 0x85, 0xd7, 0x3d, 0x45,
- 0x1f, 0x5f, 0xbe, 0x4e, 0x1b, 0x81, 0xc2, 0x78, 0x53, 0x42, 0xfd, 0xea,
- 0x26, 0xab, 0x05, 0x5d, 0xf6, 0x35, 0x07, 0x86, 0x9c, 0x51, 0x9f, 0x03,
- 0x1f, 0x58, 0xd1, 0x55, 0x72, 0xad, 0x14, 0xb1, 0x96, 0x3a, 0x9f, 0x13,
- 0x75, 0xe1, 0x4d, 0xf4, 0xb7, 0xc9, 0x55, 0x8d, 0xbc, 0x17, 0x30, 0x8f,
- 0xa1, 0xd6, 0xbf, 0x09, 0xf2, 0xfb, 0x7d, 0xda, 0x48, 0xa3, 0xd4, 0x65,
- 0x19, 0xb1, 0x39, 0x5d, 0x3b, 0x06, 0x2f, 0x36, 0xd1, 0xfe, 0x8a, 0x23,
- 0xba, 0xb9, 0xcc, 0xe1, 0xc4, 0x7e, 0xe2, 0xb8, 0xc3, 0xe8, 0x45, 0x31,
- 0xc7, 0xc8, 0xf8, 0x8a, 0x47, 0x12, 0xc0, 0xb3, 0xfd, 0x16, 0x1a, 0x43,
- 0x1e, 0x2c, 0xb1, 0x6d, 0xf3, 0x90, 0x72, 0x75, 0xea, 0x43, 0x6b, 0xc8,
- 0x59, 0x12, 0x55, 0x23, 0x01, 0xdf, 0x49, 0xb2, 0x81, 0xa2, 0x48, 0x9d,
- 0xe6, 0x44, 0x5c, 0x69, 0xce, 0xf4, 0x28, 0xcb, 0x33, 0xbd, 0xca, 0x92,
- 0x8c, 0xb4, 0x7d, 0x48, 0x59, 0x9a, 0xf1, 0x20, 0xdd, 0xaf, 0x60, 0x7b,
- 0x88, 0x72, 0xd5, 0xe4, 0xec, 0x38, 0xd3, 0xaf, 0x12, 0x63, 0xdf, 0x21,
- 0xc6, 0xea, 0x61, 0xb0, 0xef, 0x27, 0x12, 0xd5, 0x38, 0x44, 0x2c, 0xfd,
- 0x71, 0x5a, 0x57, 0x51, 0x7a, 0x11, 0x5e, 0x19, 0xa9, 0xc0, 0xd8, 0xa0,
- 0xc9, 0xdf, 0xf5, 0x78, 0x61, 0xc4, 0xb2, 0x7a, 0x4c, 0xcb, 0xda, 0x6b,
- 0x1e, 0x52, 0x1a, 0xd9, 0x67, 0xd4, 0x19, 0x8f, 0x16, 0x47, 0x02, 0xe6,
- 0x16, 0xf6, 0xe9, 0x88, 0xc4, 0x95, 0x28, 0xfb, 0xbb, 0x9a, 0xfd, 0x2d,
- 0xcd, 0xf7, 0x97, 0xeb, 0x57, 0x64, 0x91, 0x7a, 0x85, 0x3a, 0x61, 0xd6,
- 0x01, 0xf6, 0x25, 0x02, 0xc1, 0x42, 0xbd, 0xa5, 0xac, 0x73, 0xf5, 0xd9,
- 0x3a, 0xc0, 0x70, 0x22, 0xc8, 0x39, 0x15, 0x5b, 0xf7, 0x33, 0x76, 0x7d,
- 0x83, 0x18, 0xdb, 0x80, 0xb6, 0x61, 0xc1, 0xdf, 0x6b, 0xd4, 0xdc, 0x3c,
- 0xe5, 0xb0, 0x56, 0x62, 0x5e, 0x0e, 0x6f, 0x83, 0xe8, 0xa3, 0x5f, 0x77,
- 0xa5, 0xc4, 0xc6, 0xef, 0xf9, 0x72, 0x22, 0xa0, 0xe0, 0xb1, 0x40, 0xb6,
- 0xa5, 0x1c, 0x95, 0x68, 0x0f, 0x89, 0x6d, 0x6e, 0xfc, 0xf2, 0x53, 0x86,
- 0x1e, 0x5e, 0xa1, 0x70, 0xce, 0x02, 0x7a, 0xf3, 0x52, 0x05, 0x08, 0x8c,
- 0x01, 0x6f, 0xa4, 0x2b, 0xb1, 0xda, 0x74, 0x40, 0xad, 0x0a, 0xa2, 0x37,
- 0x33, 0x35, 0x2e, 0x98, 0xc4, 0x78, 0x69, 0x2f, 0x48, 0xbf, 0x2e, 0xc3,
- 0x32, 0x2d, 0x67, 0xd3, 0x6e, 0xb6, 0xed, 0x0e, 0x64, 0x83, 0x2a, 0xe3,
- 0xdd, 0x7e, 0x5e, 0x38, 0x46, 0xfc, 0x6f, 0x34, 0x5c, 0xc4, 0xff, 0x4a,
- 0x34, 0x9a, 0xbf, 0xb3, 0x96, 0xad, 0x92, 0x7b, 0x85, 0x76, 0xe0, 0x2e,
- 0x66, 0xbf, 0x6f, 0x19, 0xba, 0x7f, 0x94, 0x27, 0xd9, 0x74, 0xee, 0x7a,
- 0x9c, 0x31, 0xab, 0x9b, 0xed, 0x6e, 0x66, 0xbb, 0xeb, 0x34, 0x3d, 0x1a,
- 0x3f, 0x5b, 0x2e, 0x1b, 0x74, 0x40, 0xd7, 0xa4, 0x6c, 0x13, 0xdb, 0x5d,
- 0xcd, 0x76, 0x7b, 0x35, 0x91, 0xef, 0x77, 0xd6, 0xba, 0x55, 0x72, 0x2f,
- 0x67, 0x1f, 0xb9, 0x76, 0xef, 0x91, 0x76, 0xcd, 0xd1, 0x7c, 0x5f, 0x47,
- 0x13, 0xe8, 0x77, 0x44, 0x18, 0x63, 0x1b, 0x02, 0xfe, 0x2e, 0xc6, 0xdb,
- 0x26, 0xc6, 0x8e, 0x9c, 0x4d, 0x4c, 0x8d, 0x77, 0x88, 0x9f, 0x2b, 0x23,
- 0xd7, 0xa4, 0x9c, 0xd8, 0xda, 0x24, 0xf5, 0x2c, 0xf1, 0xc5, 0x47, 0xfd,
- 0x0a, 0xb6, 0x38, 0x71, 0x20, 0x41, 0xfc, 0xc7, 0x37, 0x68, 0x77, 0x7e,
- 0xb4, 0x64, 0x6a, 0xb1, 0x66, 0x27, 0xe3, 0xa0, 0x59, 0x45, 0x5b, 0xcf,
- 0xd9, 0xdb, 0x32, 0xb6, 0x3d, 0x69, 0xb7, 0x1d, 0x57, 0x5a, 0x32, 0x75,
- 0x5a, 0x15, 0x63, 0xee, 0x91, 0xb3, 0xd8, 0x39, 0x27, 0x5a, 0x1a, 0x09,
- 0x34, 0xaf, 0xe7, 0x24, 0xb9, 0x19, 0xdf, 0xbe, 0x37, 0xaf, 0x87, 0x76,
- 0xd1, 0x4b, 0x3b, 0xcc, 0xcd, 0x6f, 0x73, 0x66, 0x8f, 0x2a, 0x18, 0x07,
- 0xb5, 0x16, 0xeb, 0x76, 0xca, 0x7f, 0x72, 0x95, 0x86, 0xc7, 0x78, 0xad,
- 0x16, 0xab, 0x87, 0xbf, 0x47, 0x3b, 0xd3, 0x7d, 0x62, 0x87, 0x5d, 0x67,
- 0xe5, 0x12, 0x99, 0x44, 0x36, 0x91, 0xa9, 0x8f, 0xe5, 0x66, 0x51, 0x3f,
- 0x82, 0x8d, 0xd5, 0x94, 0x67, 0x2b, 0xf9, 0xd0, 0x21, 0xe5, 0xf3, 0x94,
- 0x27, 0xeb, 0xf2, 0xe2, 0xa1, 0x94, 0xc8, 0xa3, 0x44, 0x67, 0x46, 0x66,
- 0xe1, 0x4c, 0x2a, 0x10, 0x7f, 0x02, 0x22, 0x5b, 0x8f, 0xd2, 0x2a, 0xf5,
- 0x53, 0xbd, 0xbc, 0x57, 0x90, 0x11, 0x5a, 0xa5, 0x2d, 0x5b, 0x4e, 0xa6,
- 0xeb, 0x39, 0xd7, 0x2e, 0xe3, 0x6f, 0xcb, 0x51, 0xe1, 0xa4, 0xad, 0x49,
- 0xdb, 0xff, 0x61, 0x45, 0xb5, 0x6e, 0x5e, 0xf3, 0x72, 0x9e, 0xdc, 0xe4,
- 0x05, 0x7a, 0xf0, 0x3a, 0x87, 0xd2, 0xe2, 0x91, 0x78, 0x4d, 0xfb, 0x4c,
- 0xa7, 0x9d, 0x38, 0x9e, 0x58, 0xba, 0xb4, 0xcc, 0xf8, 0x34, 0x1e, 0x1b,
- 0xf1, 0x61, 0x84, 0x73, 0xfb, 0x6c, 0x42, 0xe2, 0xeb, 0x2c, 0x3c, 0x9a,
- 0xf6, 0xe0, 0x99, 0x84, 0x1f, 0x8f, 0x30, 0xfe, 0x4c, 0x24, 0x0c, 0xec,
- 0x4f, 0x7b, 0xf1, 0x34, 0xed, 0x79, 0x34, 0xed, 0xa3, 0xbd, 0xd4, 0x63,
- 0x38, 0xdd, 0x66, 0x8f, 0xe1, 0xc9, 0xc4, 0xbf, 0xcb, 0x58, 0x83, 0x32,
- 0xd6, 0xcd, 0xf6, 0x58, 0x0b, 0x71, 0x7e, 0xd6, 0xd9, 0x79, 0x38, 0x91,
- 0xb0, 0x71, 0xa0, 0x77, 0x99, 0x43, 0xe6, 0x81, 0x36, 0x3b, 0x20, 0x58,
- 0xa0, 0xf7, 0xc7, 0x61, 0x61, 0x8f, 0x39, 0x93, 0xfe, 0xdf, 0x4b, 0x79,
- 0xa9, 0x53, 0x8e, 0x1f, 0xae, 0x8a, 0x68, 0x79, 0x24, 0x10, 0xeb, 0xa3,
- 0xde, 0x9d, 0x11, 0xd1, 0x43, 0x4e, 0xef, 0x2b, 0x32, 0x87, 0x14, 0xe1,
- 0x7a, 0x97, 0x0c, 0xc4, 0xad, 0x32, 0x43, 0xf4, 0x1d, 0x20, 0xce, 0x02,
- 0xf3, 0xf7, 0x38, 0x39, 0xbe, 0x9b, 0x38, 0x66, 0x13, 0x45, 0x46, 0x9d,
- 0x56, 0x4d, 0xd9, 0x8f, 0x7c, 0x24, 0x06, 0x8a, 0x8e, 0xfe, 0x36, 0x3f,
- 0x5f, 0xba, 0x83, 0xf2, 0xfa, 0x81, 0xc2, 0xbc, 0x58, 0xd6, 0x0e, 0xb3,
- 0x30, 0x37, 0x35, 0xf0, 0x57, 0xeb, 0xf1, 0x21, 0x5a, 0xc4, 0x48, 0x62,
- 0x1a, 0xe2, 0x9a, 0x9a, 0x6f, 0x3b, 0xaa, 0x14, 0x31, 0xff, 0xc0, 0xb8,
- 0xf8, 0x7e, 0x39, 0xa2, 0x4e, 0xa9, 0x8f, 0x68, 0x51, 0x24, 0x10, 0x9c,
- 0xab, 0x4e, 0xb5, 0x19, 0xc1, 0x01, 0xe9, 0x2b, 0x4e, 0x59, 0xcf, 0xc7,
- 0x82, 0x91, 0x44, 0x01, 0x37, 0xfe, 0x3b, 0xf5, 0x2e, 0xd4, 0xa9, 0xc8,
- 0x29, 0x7a, 0x55, 0x71, 0x74, 0x50, 0xf4, 0xe7, 0xc4, 0x4a, 0x73, 0x7a,
- 0x5e, 0xe6, 0x59, 0x9c, 0x17, 0x62, 0x0e, 0xe7, 0xeb, 0x85, 0x7e, 0x2f,
- 0xe5, 0xb6, 0x90, 0x0e, 0x5d, 0x8c, 0x4d, 0x36, 0xe7, 0x5c, 0x95, 0xcf,
- 0x5b, 0x38, 0x4f, 0xea, 0x76, 0xea, 0xfa, 0xb3, 0x8e, 0xdc, 0x79, 0x9d,
- 0xef, 0xa3, 0xfa, 0xd2, 0xb5, 0x18, 0x0a, 0x3a, 0x03, 0x86, 0xd2, 0x88,
- 0xb9, 0x23, 0xf5, 0x4d, 0xce, 0xbe, 0xb6, 0x0d, 0xf4, 0xef, 0x7b, 0x4f,
- 0x35, 0x7c, 0x16, 0x9b, 0xa9, 0x17, 0xa7, 0x6d, 0x67, 0x51, 0xc5, 0x65,
- 0x2c, 0xb1, 0xfd, 0x49, 0x1d, 0x5f, 0x91, 0xef, 0x23, 0x6a, 0xe7, 0x2c,
- 0x50, 0x5b, 0xf2, 0xe7, 0x77, 0x53, 0xdf, 0x32, 0x0e, 0x15, 0x3f, 0x20,
- 0x97, 0x7d, 0x27, 0xf4, 0x59, 0x64, 0x6d, 0xcc, 0x76, 0xd2, 0xdf, 0xaf,
- 0x62, 0x5d, 0xe2, 0xdf, 0xb8, 0xc4, 0x52, 0xc4, 0x4b, 0xe8, 0xd7, 0x45,
- 0xf4, 0xd5, 0x6b, 0x32, 0xf7, 0xa0, 0x3d, 0x15, 0x08, 0x97, 0x28, 0xf7,
- 0xe0, 0xd6, 0x8c, 0x0b, 0xb1, 0x61, 0x0f, 0xd6, 0x51, 0x27, 0xce, 0xa4,
- 0xf8, 0xb9, 0x86, 0x75, 0xa3, 0x47, 0x67, 0x3a, 0xe9, 0x37, 0xeb, 0x46,
- 0xbd, 0x3c, 0xa6, 0xf3, 0x70, 0x63, 0x35, 0x8f, 0x3d, 0xb4, 0xcb, 0x36,
- 0xc6, 0x86, 0x23, 0x09, 0x13, 0x9d, 0xd4, 0xd5, 0x13, 0x89, 0x06, 0xdc,
- 0x4b, 0xbd, 0x1d, 0x4a, 0x7c, 0x8a, 0x3a, 0x0a, 0xa3, 0x83, 0x73, 0xfc,
- 0x58, 0x42, 0xb5, 0xf3, 0xab, 0xdb, 0x33, 0xff, 0x62, 0x45, 0xa7, 0x8b,
- 0x9c, 0xa2, 0x0b, 0x99, 0xcf, 0x8f, 0xe8, 0x81, 0xfe, 0x3b, 0x55, 0x17,
- 0xf5, 0xd8, 0xb6, 0xcb, 0xc0, 0xf6, 0x5d, 0x75, 0xb4, 0xbb, 0x8c, 0xe5,
- 0xaf, 0x1a, 0xa0, 0x0e, 0xa6, 0xea, 0xe1, 0x08, 0x79, 0x81, 0xe8, 0x41,
- 0xda, 0xbc, 0x8f, 0x63, 0xee, 0xe6, 0x3d, 0x1f, 0x1e, 0x4f, 0x7c, 0x97,
- 0xbf, 0xc3, 0xca, 0x5d, 0x19, 0xf1, 0x79, 0xf1, 0xb7, 0x7f, 0x70, 0xe4,
- 0x62, 0x6f, 0xa1, 0xdc, 0x16, 0x96, 0xb3, 0xac, 0xcd, 0x67, 0xe3, 0x4a,
- 0x51, 0xb4, 0x84, 0x71, 0x65, 0x7f, 0x22, 0x10, 0x7e, 0xc6, 0x8e, 0x7d,
- 0x4e, 0xda, 0x8e, 0xd8, 0x47, 0x8f, 0x6d, 0x1b, 0xcb, 0xce, 0xda, 0xc6,
- 0xe4, 0x59, 0x0e, 0xd5, 0x9f, 0x9a, 0xea, 0x73, 0x39, 0xbb, 0x70, 0x26,
- 0xf5, 0x5e, 0xdb, 0x8e, 0xd3, 0x82, 0x8f, 0x0e, 0x38, 0x06, 0x9c, 0x68,
- 0x33, 0x2f, 0xa5, 0xbe, 0xab, 0x19, 0x6f, 0x8a, 0x78, 0x30, 0x4f, 0x1d,
- 0xfe, 0x0b, 0x94, 0x0e, 0x64, 0xad, 0x12, 0xfe, 0x6e, 0x0e, 0x89, 0xbe,
- 0xaf, 0xc2, 0xad, 0xc3, 0x0e, 0x14, 0x0d, 0x28, 0x78, 0xd2, 0xac, 0xc7,
- 0x90, 0x37, 0x87, 0xbb, 0x6a, 0xf2, 0x52, 0x7b, 0x9e, 0x2e, 0x1e, 0x3f,
- 0xfa, 0x8c, 0xc4, 0x85, 0x7b, 0x47, 0x3d, 0xf0, 0x25, 0x15, 0x78, 0x88,
- 0x2b, 0x65, 0x46, 0x3d, 0xf5, 0xaa, 0xa1, 0x32, 0x69, 0xe2, 0x6b, 0x19,
- 0xd2, 0xa6, 0x07, 0xc2, 0xb8, 0x93, 0xf3, 0x52, 0xfe, 0xc0, 0x95, 0xb8,
- 0x83, 0xe5, 0x36, 0xf0, 0xde, 0x86, 0xd1, 0x6a, 0x1e, 0x5e, 0x1e, 0xd3,
- 0x79, 0x34, 0xe0, 0xf6, 0xe1, 0x5a, 0x44, 0xab, 0xf5, 0xa0, 0x5f, 0x75,
- 0xa0, 0x7a, 0x40, 0xf4, 0xae, 0x62, 0xe5, 0x02, 0x05, 0xe6, 0xa7, 0x8b,
- 0xa1, 0xce, 0xfd, 0x38, 0xdf, 0xfd, 0x53, 0xb2, 0xbe, 0x6c, 0x0d, 0xd9,
- 0x98, 0x2e, 0x3a, 0x16, 0x3b, 0xf9, 0x57, 0xce, 0x85, 0xc8, 0x2b, 0x7d,
- 0x48, 0xac, 0x15, 0x1d, 0x7f, 0x12, 0x36, 0x30, 0xb2, 0x54, 0x74, 0xb1,
- 0xcc, 0x47, 0x7d, 0x01, 0x67, 0xe7, 0x7f, 0x2a, 0x67, 0x95, 0xb8, 0xaf,
- 0x87, 0x87, 0x6c, 0x8e, 0xe3, 0x67, 0xbe, 0xa8, 0xc7, 0x45, 0xe7, 0xe4,
- 0x34, 0x6e, 0xd5, 0x80, 0xbf, 0xc8, 0xb8, 0x19, 0xb7, 0x71, 0x9e, 0xf6,
- 0x26, 0xd4, 0xa5, 0x2e, 0xa8, 0xb3, 0x5c, 0x4c, 0x9c, 0x47, 0x4c, 0x1d,
- 0xed, 0xc3, 0xcc, 0xb5, 0x86, 0xcb, 0xd1, 0xa5, 0x29, 0xee, 0x6d, 0xf5,
- 0x8b, 0x24, 0xa7, 0xf6, 0x57, 0x1a, 0x50, 0xcb, 0x18, 0xff, 0xb7, 0x6b,
- 0x70, 0x16, 0x19, 0x8a, 0x9a, 0xa8, 0x6f, 0x42, 0xbc, 0x0a, 0xce, 0x0a,
- 0x03, 0x0a, 0x73, 0x66, 0xf4, 0x69, 0x10, 0xec, 0x89, 0x16, 0x19, 0xf7,
- 0xe0, 0xb6, 0x14, 0xac, 0xd2, 0x08, 0xf3, 0xa1, 0x88, 0x41, 0x8e, 0x1b,
- 0xf0, 0x15, 0xd1, 0x3f, 0x56, 0x93, 0x57, 0xac, 0x1d, 0x16, 0x39, 0x3c,
- 0xe4, 0x1b, 0x86, 0xbf, 0x0d, 0xcc, 0xe1, 0x5b, 0xf4, 0xe0, 0x24, 0xf3,
- 0xd8, 0xd5, 0xd4, 0xfd, 0x48, 0xe2, 0x1e, 0x34, 0xa6, 0x8e, 0x58, 0x1e,
- 0xf2, 0xc8, 0x22, 0xa3, 0xf6, 0x4c, 0x17, 0x62, 0xf4, 0x0d, 0xe1, 0x47,
- 0x6b, 0xe8, 0x1b, 0x3e, 0x64, 0x12, 0xea, 0x71, 0xb2, 0x0b, 0x74, 0x8c,
- 0xae, 0xc7, 0xd7, 0x46, 0x67, 0x61, 0x3c, 0xb1, 0x01, 0x77, 0x66, 0xc8,
- 0x95, 0xfa, 0xaf, 0xc2, 0x1d, 0xc3, 0x57, 0xe1, 0xf6, 0x9d, 0x46, 0x70,
- 0x03, 0x75, 0xbd, 0x76, 0x98, 0x81, 0x72, 0xba, 0xb4, 0x5b, 0xd0, 0x95,
- 0xf0, 0x45, 0xea, 0x22, 0xaf, 0xa7, 0x2c, 0x0a, 0x1c, 0xe6, 0x5f, 0x2d,
- 0x5e, 0x8a, 0x17, 0x35, 0x28, 0xfe, 0xdd, 0xf5, 0x2f, 0x31, 0xb7, 0x17,
- 0xd9, 0x11, 0x9d, 0x69, 0xfc, 0xc0, 0x7a, 0x50, 0xa3, 0x7f, 0x47, 0x10,
- 0x9f, 0xd3, 0xf0, 0xbc, 0xf5, 0xd0, 0x2a, 0xb9, 0x7e, 0x9b, 0x13, 0xa5,
- 0x2a, 0xaf, 0x49, 0x9b, 0x82, 0x4b, 0x75, 0x44, 0xe2, 0x8f, 0x6b, 0x33,
- 0x6b, 0x25, 0xcf, 0x96, 0x27, 0x2f, 0x24, 0x16, 0x3f, 0x91, 0xf0, 0xa2,
- 0x37, 0x95, 0xe3, 0x56, 0x37, 0x65, 0x84, 0x53, 0xb9, 0x51, 0xda, 0x27,
- 0x71, 0x25, 0x8a, 0xf5, 0xfc, 0x5d, 0xd2, 0xa7, 0xb7, 0xc4, 0x91, 0x60,
- 0x9b, 0x4d, 0x9c, 0x0b, 0xda, 0x6b, 0x9f, 0x03, 0x25, 0x46, 0x73, 0xce,
- 0x56, 0xfb, 0x56, 0xd0, 0x56, 0x35, 0x54, 0xf4, 0xf5, 0x70, 0xac, 0xb4,
- 0x55, 0xd6, 0xbb, 0x83, 0xba, 0xf0, 0xf4, 0xad, 0xa2, 0xbd, 0xce, 0x42,
- 0x59, 0x5f, 0x2b, 0xf1, 0x01, 0x8c, 0xeb, 0x16, 0x8e, 0x9a, 0x95, 0x79,
- 0x7e, 0xda, 0x8c, 0x5b, 0x53, 0x51, 0xb4, 0xa5, 0x6a, 0xa3, 0x27, 0x65,
- 0xad, 0xca, 0x95, 0xc3, 0xb0, 0x68, 0x8d, 0xe8, 0x62, 0x32, 0x8f, 0xa7,
- 0x7a, 0x73, 0x8e, 0xd3, 0xe9, 0x9a, 0x5f, 0x29, 0xc8, 0xde, 0x83, 0x18,
- 0xf3, 0x8f, 0x39, 0x91, 0x16, 0x58, 0x29, 0x91, 0x3b, 0x6e, 0xf9, 0x98,
- 0x53, 0x7a, 0x22, 0xfa, 0xc6, 0xc5, 0x0e, 0xa3, 0xe3, 0x15, 0x25, 0x88,
- 0xeb, 0x29, 0x43, 0x59, 0x5f, 0x27, 0x5e, 0x08, 0xe9, 0xbe, 0xef, 0x2a,
- 0xfa, 0x99, 0x0d, 0x78, 0x05, 0x3f, 0xe3, 0xb5, 0xa2, 0xbe, 0x09, 0x3c,
- 0x94, 0x79, 0x15, 0xa7, 0x28, 0xab, 0xda, 0xf7, 0xa1, 0xb5, 0xcc, 0x78,
- 0x86, 0xe3, 0x77, 0x2b, 0x6f, 0x65, 0xa6, 0xda, 0xe2, 0x55, 0x58, 0xbd,
- 0x53, 0xec, 0x4f, 0x0f, 0xc6, 0x89, 0xbd, 0x6d, 0x66, 0x85, 0x70, 0x79,
- 0x89, 0x4f, 0x94, 0xbf, 0x45, 0xb0, 0x85, 0xfe, 0x41, 0x3b, 0xb0, 0xc7,
- 0xd0, 0x6a, 0x63, 0xb2, 0x33, 0x09, 0x1b, 0x4b, 0x73, 0x7a, 0x8e, 0x28,
- 0x6d, 0xa3, 0xbe, 0x52, 0x94, 0xfa, 0xf2, 0x7e, 0x90, 0x5b, 0xb3, 0x38,
- 0x57, 0xf7, 0x3f, 0xad, 0x11, 0xef, 0xf9, 0x75, 0x2b, 0x98, 0x83, 0x55,
- 0x72, 0x3c, 0xef, 0xf6, 0xc5, 0xad, 0xd2, 0xdc, 0x58, 0x9a, 0x7f, 0xa0,
- 0x88, 0x4d, 0x06, 0xc9, 0xed, 0x3b, 0x71, 0x69, 0x48, 0x6f, 0xfd, 0xae,
- 0x22, 0x65, 0xf5, 0xf0, 0x06, 0xa5, 0xd0, 0xcf, 0xcb, 0x38, 0x39, 0x22,
- 0x7d, 0x48, 0x5f, 0x13, 0xcc, 0xc9, 0x72, 0x63, 0x10, 0x5f, 0x7a, 0xc4,
- 0x9e, 0x4b, 0xf1, 0x27, 0x3f, 0x96, 0x73, 0x4c, 0xae, 0x3e, 0x1f, 0x0f,
- 0x17, 0xed, 0xd5, 0x87, 0xb5, 0x99, 0x15, 0x58, 0xcd, 0xbc, 0x76, 0x75,
- 0xa6, 0x85, 0xba, 0xdf, 0x48, 0x7c, 0x67, 0x46, 0xa0, 0xe5, 0x74, 0x7c,
- 0xce, 0x3e, 0x74, 0xff, 0x24, 0x56, 0xf0, 0xfe, 0xcf, 0x9d, 0xa8, 0x68,
- 0x61, 0x79, 0xfb, 0xbe, 0x29, 0xf8, 0x7d, 0xae, 0xcc, 0x47, 0x78, 0x98,
- 0x1d, 0xe7, 0xf7, 0xda, 0x1c, 0xb1, 0xc5, 0xce, 0xbd, 0xae, 0xb6, 0xe7,
- 0x5c, 0x38, 0x82, 0x85, 0x63, 0x66, 0x31, 0xf3, 0xaf, 0xba, 0xe0, 0xf9,
- 0x9c, 0x50, 0x67, 0x16, 0x5a, 0xc0, 0x03, 0xe9, 0x4b, 0xf4, 0x72, 0xa2,
- 0x26, 0xa7, 0x97, 0x4f, 0x2a, 0x7b, 0x3e, 0x76, 0xec, 0x49, 0x48, 0xdf,
- 0x45, 0x36, 0x2f, 0x6d, 0xcc, 0x94, 0x22, 0xee, 0x15, 0x1d, 0x49, 0x7b,
- 0xba, 0x5f, 0x64, 0x5a, 0xbb, 0x53, 0xec, 0xd8, 0xc2, 0x08, 0x65, 0xe8,
- 0xb6, 0xe7, 0x2d, 0xc7, 0x25, 0x8f, 0x9c, 0x17, 0x9f, 0x65, 0x4c, 0x85,
- 0xbe, 0x6f, 0x73, 0xe5, 0xf8, 0x66, 0x81, 0x2b, 0x58, 0xd6, 0x80, 0x59,
- 0xe0, 0x0a, 0x32, 0xe6, 0xbf, 0x00, 0x63, 0x9d, 0x3d, 0xde, 0x35, 0xf9,
- 0xb6, 0xbb, 0xcc, 0x00, 0xed, 0x5a, 0xb8, 0x54, 0x44, 0x59, 0xb3, 0x2b,
- 0xc3, 0xb9, 0x95, 0xdc, 0x06, 0xb8, 0x93, 0xf7, 0xcb, 0x79, 0xff, 0xc5,
- 0x90, 0x0b, 0x97, 0x4e, 0x97, 0xbe, 0xaf, 0x42, 0xc7, 0xce, 0x28, 0x2a,
- 0x17, 0x06, 0x30, 0x69, 0x73, 0x89, 0x02, 0xef, 0x75, 0xe1, 0x8e, 0x9d,
- 0x1f, 0x5a, 0x15, 0x36, 0x17, 0x33, 0x62, 0xe3, 0x8a, 0x8a, 0xed, 0x8b,
- 0x84, 0xff, 0xba, 0x88, 0xef, 0xe4, 0xa2, 0xc2, 0xad, 0x5d, 0x65, 0xe4,
- 0xb0, 0xc2, 0xe1, 0x02, 0xd9, 0x9b, 0x54, 0x68, 0x5a, 0x44, 0xb8, 0xdc,
- 0x2c, 0x9b, 0xc3, 0x0a, 0x97, 0xfd, 0x56, 0xea, 0xd0, 0x14, 0x2e, 0x7b,
- 0x96, 0x73, 0x30, 0xf7, 0x69, 0x61, 0x7e, 0xef, 0x81, 0x3b, 0xa2, 0xb7,
- 0x6c, 0x52, 0x3a, 0xb1, 0x3c, 0x64, 0x98, 0x92, 0x53, 0x5f, 0xa9, 0xe8,
- 0xc1, 0xd3, 0x08, 0x12, 0x6f, 0x5f, 0xc6, 0xc8, 0x60, 0xdc, 0x25, 0x76,
- 0xb4, 0x29, 0x73, 0x4e, 0x9e, 0x5b, 0x29, 0x8f, 0x3b, 0x27, 0x8f, 0x79,
- 0x1a, 0x2a, 0x9e, 0x6c, 0x70, 0x11, 0xb7, 0xfe, 0x0e, 0x6d, 0x3b, 0x55,
- 0x2c, 0xb1, 0xb9, 0xf9, 0xdf, 0x11, 0x7f, 0x2f, 0x2a, 0xcd, 0x95, 0x07,
- 0x3a, 0xe9, 0xdf, 0xef, 0x2f, 0x2c, 0x41, 0x68, 0x9a, 0x82, 0x2a, 0xa3,
- 0x83, 0xf9, 0xf1, 0x87, 0x56, 0xdc, 0x49, 0x3a, 0x6b, 0x40, 0x2b, 0x89,
- 0x44, 0x29, 0x5b, 0x93, 0x72, 0xcd, 0xf0, 0x20, 0xfb, 0xe9, 0x20, 0xef,
- 0xf7, 0xe0, 0x2e, 0xda, 0xce, 0x5d, 0x8c, 0x65, 0x77, 0x31, 0x96, 0xdd,
- 0x35, 0xfa, 0x2f, 0xbc, 0x3e, 0xdd, 0xfe, 0xbd, 0x29, 0x55, 0xb0, 0x65,
- 0x27, 0xe3, 0x82, 0xe8, 0x77, 0x33, 0x7d, 0x47, 0xe2, 0x02, 0x28, 0x93,
- 0x85, 0x93, 0x9c, 0xc7, 0x25, 0x9a, 0x1e, 0xcc, 0xe2, 0xeb, 0xae, 0x73,
- 0x79, 0x5f, 0x21, 0xb6, 0xc8, 0x3c, 0xba, 0x70, 0x1b, 0x65, 0x0c, 0x86,
- 0xfe, 0xcb, 0x42, 0x95, 0xf8, 0xee, 0x85, 0xf7, 0x73, 0xf3, 0x7a, 0xe4,
- 0x2c, 0x07, 0x54, 0xc4, 0x4e, 0xe9, 0xf3, 0x7b, 0x6c, 0x4e, 0xf1, 0xa2,
- 0xc9, 0xdc, 0x6d, 0xe7, 0xd1, 0xf9, 0x62, 0x2a, 0x6b, 0x47, 0xa3, 0xe8,
- 0xe6, 0xb8, 0x57, 0x0f, 0x3f, 0x96, 0xd7, 0x4b, 0x61, 0xbc, 0x0a, 0xd5,
- 0xe2, 0xa1, 0xff, 0xe4, 0x72, 0x95, 0xb6, 0x51, 0xe1, 0xb6, 0xd5, 0xfc,
- 0x2f, 0xdc, 0xd6, 0xcb, 0xff, 0xc2, 0x73, 0xa7, 0xf3, 0xbf, 0x13, 0xfe,
- 0xe9, 0x62, 0xc7, 0xf5, 0xe8, 0xdd, 0x65, 0x59, 0xc5, 0x81, 0x7a, 0x6c,
- 0x19, 0xfd, 0x48, 0xbc, 0xbc, 0x40, 0x1e, 0x7b, 0x0e, 0xe8, 0x47, 0x2e,
- 0xc1, 0x22, 0xbf, 0x5f, 0x95, 0xbe, 0x2d, 0x6c, 0x34, 0xaf, 0x62, 0x9f,
- 0x8c, 0x80, 0xd5, 0x53, 0xfd, 0xa2, 0xd0, 0x46, 0x41, 0xdf, 0xc5, 0xf4,
- 0x73, 0x68, 0x2e, 0xea, 0x7b, 0x65, 0x46, 0xea, 0x36, 0x29, 0x4b, 0x87,
- 0xa7, 0x96, 0xef, 0x20, 0x1f, 0x3e, 0x4d, 0x5d, 0x17, 0xfc, 0xc8, 0x9b,
- 0xcf, 0x2b, 0x98, 0x4b, 0xa4, 0x44, 0x97, 0x32, 0xbe, 0x5c, 0xae, 0x28,
- 0xb6, 0x74, 0xe4, 0x6c, 0x1f, 0xa2, 0xb7, 0xf8, 0xf4, 0x12, 0x43, 0xec,
- 0x28, 0x48, 0x5c, 0xd1, 0xc3, 0xcd, 0x84, 0xed, 0x53, 0x09, 0xc4, 0x1c,
- 0x91, 0xe6, 0xa6, 0xb5, 0x89, 0xb9, 0xda, 0xf1, 0x7c, 0x2e, 0xba, 0x87,
- 0x38, 0xae, 0x1a, 0xb2, 0x0e, 0x42, 0x5b, 0x19, 0x16, 0xdd, 0x75, 0x28,
- 0xe7, 0xf2, 0xce, 0x28, 0x79, 0x97, 0x6a, 0xcb, 0xe8, 0x8c, 0x88, 0x6c,
- 0x52, 0x87, 0xb2, 0x5f, 0xc0, 0xbf, 0x72, 0xba, 0xa8, 0x80, 0x67, 0x40,
- 0x78, 0x97, 0x8e, 0x0d, 0x8c, 0xf3, 0x65, 0x03, 0x7e, 0xfa, 0x42, 0x35,
- 0x4a, 0x1f, 0x88, 0x60, 0xfd, 0xa8, 0x86, 0x92, 0x07, 0x2c, 0x6b, 0x6e,
- 0xa8, 0x87, 0x5c, 0xf6, 0xb2, 0x22, 0xc9, 0x9d, 0x9c, 0x49, 0x62, 0x16,
- 0xf1, 0xad, 0x3d, 0xa5, 0xe0, 0x6a, 0xc6, 0xd3, 0x28, 0x71, 0xa8, 0xdd,
- 0xc6, 0x39, 0xab, 0x73, 0x4e, 0xc4, 0x45, 0x1b, 0x5a, 0xc5, 0xfb, 0xad,
- 0xc4, 0xc0, 0x56, 0x62, 0x9a, 0x65, 0xbd, 0x7f, 0x39, 0x3a, 0xcb, 0x22,
- 0x37, 0x13, 0x0b, 0x6b, 0xc9, 0x89, 0x25, 0x7e, 0x5f, 0x8e, 0x35, 0x8c,
- 0xfd, 0xc5, 0x49, 0x3b, 0x9f, 0xa2, 0xee, 0x18, 0xa3, 0x32, 0x8c, 0x71,
- 0x94, 0xfd, 0x69, 0x72, 0x5c, 0xe1, 0xbb, 0x95, 0xc9, 0x0d, 0x8c, 0x75,
- 0x1e, 0x54, 0x0c, 0x5c, 0x86, 0x3b, 0x19, 0xcf, 0xef, 0xd8, 0xe9, 0x47,
- 0x7a, 0xd1, 0x55, 0x94, 0xef, 0x1e, 0xac, 0x4f, 0x19, 0x92, 0x43, 0x45,
- 0x83, 0x8b, 0xc8, 0xb7, 0x33, 0x82, 0x3b, 0x92, 0x8f, 0x95, 0x61, 0x49,
- 0x0b, 0x10, 0x4c, 0x16, 0xf0, 0x2d, 0x2a, 0x6b, 0x47, 0x30, 0x92, 0xe7,
- 0x63, 0xdb, 0x39, 0x5e, 0x24, 0xeb, 0x70, 0x2d, 0x98, 0xcf, 0x58, 0x20,
- 0xf6, 0xa5, 0x31, 0xc7, 0x2c, 0x51, 0x0c, 0xdf, 0x1e, 0xfa, 0xa9, 0xe4,
- 0x3d, 0x57, 0x24, 0x0b, 0xb1, 0x4f, 0xcf, 0x2e, 0x76, 0x74, 0x12, 0x47,
- 0xf4, 0x8d, 0xbf, 0x53, 0xf4, 0xf6, 0x13, 0xca, 0x2b, 0xd8, 0x37, 0xf6,
- 0x2a, 0x86, 0xc6, 0xdc, 0xca, 0xe8, 0x98, 0xf4, 0x35, 0x81, 0xbe, 0xcc,
- 0x9f, 0xea, 0x6b, 0xea, 0xfa, 0xcb, 0xa2, 0xf3, 0xd6, 0x6c, 0xae, 0xce,
- 0xe7, 0x89, 0x4b, 0xcf, 0xe3, 0xc7, 0x32, 0x27, 0x62, 0x97, 0x5e, 0xf4,
- 0xa4, 0xce, 0xad, 0x0b, 0xf4, 0x27, 0xb6, 0xd9, 0xfe, 0xd9, 0x92, 0x11,
- 0x7b, 0x55, 0x19, 0x33, 0x2f, 0xce, 0xe7, 0x2c, 0xb5, 0xd4, 0x41, 0x9f,
- 0x7d, 0x6f, 0x9f, 0xf9, 0x29, 0x64, 0xed, 0x6b, 0x8b, 0xe9, 0x9b, 0xd5,
- 0x28, 0x26, 0x26, 0x06, 0x43, 0x3e, 0x14, 0x57, 0xc9, 0x3a, 0xce, 0xb9,
- 0xdc, 0x7f, 0xc3, 0x4e, 0x86, 0x64, 0x1b, 0x73, 0x1a, 0x89, 0x7f, 0xb5,
- 0x9c, 0xef, 0x1c, 0xce, 0xac, 0xa7, 0x0d, 0x5d, 0x27, 0x36, 0xe4, 0xca,
- 0xd9, 0xd0, 0x47, 0xd7, 0x17, 0x54, 0x90, 0xfb, 0x69, 0x15, 0x76, 0xde,
- 0xd7, 0xa4, 0x5c, 0x9f, 0xb7, 0xab, 0xcf, 0x67, 0x1e, 0x2d, 0xca, 0xe7,
- 0x66, 0x17, 0x94, 0xff, 0x38, 0x1d, 0x5c, 0xf6, 0x67, 0xe8, 0x40, 0xe2,
- 0x81, 0xe4, 0x04, 0xa2, 0x83, 0xf3, 0xf3, 0xf2, 0xfe, 0x44, 0x35, 0x71,
- 0xef, 0x42, 0x5d, 0xcc, 0xcc, 0xeb, 0x62, 0x31, 0xb1, 0x4b, 0xfe, 0x5b,
- 0x38, 0x65, 0x7a, 0xf1, 0xa2, 0x26, 0xe3, 0x5e, 0x8c, 0xf5, 0x1c, 0xaf,
- 0x9b, 0xba, 0x58, 0x1e, 0xaa, 0x44, 0xf0, 0xbc, 0x78, 0x50, 0xcb, 0xd8,
- 0xf1, 0x21, 0x79, 0xa6, 0xfc, 0xf6, 0xe3, 0x05, 0xea, 0xe2, 0x8e, 0xe1,
- 0xc5, 0xb8, 0x8b, 0xfe, 0x94, 0xe3, 0x90, 0xb9, 0xd8, 0xb0, 0x76, 0x58,
- 0xda, 0x14, 0x8c, 0xfb, 0xd9, 0xd9, 0x71, 0xfe, 0x71, 0x5e, 0xfe, 0x0a,
- 0xe5, 0x97, 0x67, 0x07, 0xb2, 0x16, 0x2d, 0xcf, 0x11, 0x64, 0x2c, 0xc6,
- 0x14, 0xdc, 0xb1, 0xac, 0x83, 0xe6, 0x3c, 0xc4, 0xaa, 0xf5, 0x7e, 0x89,
- 0x8f, 0xfd, 0xc4, 0x03, 0x07, 0xf3, 0xc8, 0xa2, 0x48, 0x94, 0xfe, 0xac,
- 0x5e, 0xe5, 0x80, 0x5a, 0xef, 0x40, 0x27, 0xde, 0x30, 0x8d, 0xde, 0x75,
- 0xf8, 0x14, 0xba, 0xbc, 0x16, 0xf6, 0xb2, 0x9d, 0xee, 0x54, 0x09, 0xda,
- 0xeb, 0x69, 0x56, 0x2b, 0x3d, 0xd8, 0x91, 0x8a, 0xb7, 0x12, 0x16, 0x18,
- 0x73, 0x1a, 0xfe, 0x2a, 0x11, 0xd0, 0x5b, 0x36, 0x90, 0xb7, 0x2c, 0xef,
- 0x73, 0xc3, 0xaf, 0xe4, 0x72, 0xb4, 0x01, 0x55, 0xd6, 0x09, 0x23, 0x94,
- 0xbd, 0xc7, 0xce, 0xf7, 0xfc, 0xd3, 0xa5, 0x1f, 0x3f, 0xe2, 0x19, 0xa9,
- 0xeb, 0x47, 0xe9, 0x5c, 0x05, 0xcb, 0xe7, 0xea, 0xf1, 0xa8, 0x62, 0x59,
- 0x0b, 0x42, 0x4e, 0xfb, 0xfe, 0xb6, 0x4c, 0x5d, 0xeb, 0x0d, 0xea, 0xab,
- 0x56, 0x6e, 0x6d, 0x52, 0xd7, 0xa2, 0x4c, 0x0a, 0x8e, 0xfc, 0xd1, 0xf5,
- 0xf9, 0x20, 0xe4, 0xb9, 0x89, 0xdb, 0x58, 0x89, 0xfd, 0xf9, 0xf5, 0x39,
- 0x57, 0xe4, 0xbd, 0x2f, 0xef, 0x35, 0x24, 0x6f, 0x11, 0x9d, 0x4b, 0x7f,
- 0x62, 0x0b, 0xd7, 0x15, 0x0b, 0x06, 0x76, 0x65, 0x16, 0xd2, 0x16, 0x7f,
- 0x6b, 0x8d, 0x7a, 0xa7, 0x96, 0xbd, 0x51, 0xcd, 0xad, 0xb7, 0x4b, 0xd9,
- 0x42, 0xb9, 0x8b, 0x89, 0x09, 0x8d, 0x18, 0x3e, 0xaf, 0x4d, 0xc9, 0x75,
- 0x0b, 0x6d, 0xde, 0xc6, 0x72, 0xd2, 0xae, 0xe0, 0xef, 0x7f, 0x59, 0xfb,
- 0xce, 0x6b, 0xaf, 0xd5, 0x95, 0x6b, 0xef, 0xee, 0x62, 0xc9, 0xdd, 0xfb,
- 0x53, 0x45, 0xac, 0xf3, 0x4e, 0x9e, 0x07, 0x16, 0xca, 0x7c, 0xea, 0x82,
- 0x32, 0xc4, 0x79, 0xe3, 0x4d, 0x6b, 0xcf, 0x79, 0x65, 0x96, 0x3b, 0xcf,
- 0x2f, 0xe3, 0xc4, 0x1c, 0xe3, 0x55, 0xeb, 0xc8, 0x79, 0x65, 0xd2, 0x17,
- 0x94, 0xb9, 0x1c, 0x63, 0xf5, 0x8f, 0x58, 0x43, 0xb9, 0xb9, 0xc9, 0xd2,
- 0x7d, 0xdc, 0x33, 0x23, 0xad, 0x7f, 0x75, 0xc5, 0x3c, 0xbd, 0x63, 0xa6,
- 0x43, 0x9e, 0xd9, 0xb8, 0x91, 0xcd, 0xcd, 0x4d, 0x5c, 0xe6, 0xc6, 0xb5,
- 0xa0, 0x30, 0x37, 0xd7, 0xe5, 0xeb, 0x17, 0xda, 0xbd, 0xae, 0xe8, 0xfc,
- 0x76, 0x0b, 0xd7, 0xaf, 0xb8, 0x40, 0xee, 0xef, 0x5c, 0x50, 0xee, 0xb7,
- 0x7f, 0xa4, 0xde, 0x2f, 0x1c, 0xe7, 0x5f, 0x3f, 0xa0, 0x9e, 0x7f, 0xde,
- 0x9c, 0x3f, 0x2f, 0xe8, 0xbf, 0xea, 0x82, 0xf2, 0x35, 0x17, 0x94, 0x7f,
- 0x59, 0xfd, 0xf8, 0x7e, 0xd6, 0x5d, 0x50, 0xcf, 0x5e, 0xab, 0xc6, 0x53,
- 0x67, 0x7d, 0x1e, 0x4d, 0x45, 0x08, 0x98, 0x4e, 0x05, 0x7e, 0xfa, 0xbe,
- 0xff, 0xe9, 0x0b, 0xd6, 0xac, 0x9b, 0xce, 0xfa, 0xfe, 0x79, 0x9c, 0x33,
- 0x56, 0x1c, 0x91, 0x18, 0x56, 0x44, 0xee, 0x2c, 0x3c, 0xb0, 0x4e, 0x3b,
- 0x97, 0x67, 0x15, 0x62, 0x65, 0x45, 0xac, 0x24, 0xd2, 0x00, 0xff, 0xd8,
- 0x2c, 0xff, 0x9b, 0x09, 0x59, 0xb7, 0xfc, 0x80, 0x5c, 0xca, 0xf0, 0xed,
- 0xc7, 0x2c, 0xff, 0x4f, 0xd3, 0x6f, 0x15, 0xa3, 0xc2, 0x83, 0xab, 0x13,
- 0x1f, 0x5f, 0x4f, 0x8d, 0x40, 0x59, 0xd6, 0xe0, 0x63, 0x7e, 0x05, 0xe7,
- 0x35, 0xf3, 0x30, 0xe5, 0xaf, 0x45, 0xf2, 0x3d, 0xf5, 0x58, 0x43, 0x98,
- 0xf1, 0x39, 0xf7, 0xbc, 0x76, 0x49, 0x46, 0xf7, 0x45, 0x95, 0xdc, 0x33,
- 0xd9, 0xf6, 0xd0, 0x1f, 0xc8, 0x77, 0x3a, 0x29, 0x97, 0xc5, 0xbe, 0x80,
- 0x0d, 0x09, 0xcb, 0x7a, 0x8a, 0x79, 0xaa, 0x3c, 0xeb, 0xff, 0x79, 0xfa,
- 0xf7, 0xd6, 0x84, 0xd7, 0x89, 0xb7, 0x8c, 0xa9, 0xed, 0xf9, 0x51, 0x19,
- 0x31, 0x99, 0x2f, 0xd9, 0x27, 0xea, 0x98, 0x51, 0xb7, 0x71, 0x2f, 0xfd,
- 0x6e, 0x7e, 0x40, 0xf7, 0x27, 0xf1, 0xef, 0x96, 0xbf, 0x46, 0x0f, 0x0e,
- 0x29, 0x85, 0x75, 0xe2, 0x0b, 0xd7, 0x83, 0x2b, 0x62, 0x2e, 0x8e, 0x6f,
- 0x8f, 0xcd, 0xf7, 0x8b, 0x88, 0x71, 0x88, 0x39, 0x23, 0xb3, 0xfc, 0x5b,
- 0x12, 0xf6, 0x38, 0xc9, 0x17, 0x15, 0x1c, 0x6b, 0x98, 0xe5, 0xef, 0x4e,
- 0x7b, 0xb1, 0x9d, 0xf1, 0xb8, 0xc4, 0x68, 0xc0, 0x23, 0x69, 0x15, 0xb7,
- 0xdd, 0xef, 0xc5, 0x5a, 0x72, 0xd1, 0x8d, 0x7d, 0xdf, 0x80, 0x71, 0xa9,
- 0x13, 0xb7, 0xd2, 0xfe, 0xd6, 0xf5, 0x15, 0xdb, 0x39, 0xc8, 0xfa, 0x3e,
- 0x27, 0xea, 0x2f, 0xad, 0x40, 0xbc, 0xa6, 0x18, 0xdf, 0x37, 0x1d, 0xcc,
- 0x7b, 0xca, 0x30, 0x64, 0x63, 0xa2, 0xe4, 0xb2, 0x82, 0x73, 0xa2, 0x37,
- 0x87, 0xbd, 0x2e, 0xf9, 0xf1, 0x58, 0xfe, 0x5b, 0x2b, 0x5b, 0xb3, 0xdd,
- 0xc6, 0x5f, 0x47, 0xc4, 0xb4, 0xe3, 0x25, 0x90, 0xe3, 0x69, 0x5d, 0xe7,
- 0x3d, 0x57, 0x6e, 0x51, 0xe6, 0x44, 0x02, 0x13, 0x8b, 0x15, 0x07, 0xc2,
- 0x81, 0x8a, 0x58, 0x65, 0x24, 0x8c, 0x65, 0x99, 0x2e, 0x9f, 0xcf, 0x7e,
- 0x56, 0x1d, 0xc1, 0xe9, 0x45, 0x26, 0x73, 0x60, 0x38, 0x97, 0x51, 0xf7,
- 0x4d, 0xd4, 0xeb, 0x66, 0xf3, 0x0f, 0x56, 0xd6, 0xf6, 0x7b, 0x37, 0x62,
- 0x9a, 0x65, 0xad, 0xa3, 0x7e, 0x1d, 0xd4, 0xe3, 0xcf, 0xf2, 0xfa, 0x15,
- 0x9d, 0x96, 0x8d, 0xfd, 0xde, 0x3a, 0x46, 0xfd, 0xba, 0xd9, 0x9e, 0x9b,
- 0xed, 0x95, 0x8c, 0x9d, 0xaf, 0xe7, 0x62, 0xca, 0xb3, 0xcc, 0x96, 0xa1,
- 0x52, 0x9e, 0xf5, 0xf9, 0xa3, 0x4a, 0x01, 0xb7, 0xff, 0xd4, 0x98, 0x5e,
- 0x99, 0x92, 0x83, 0x88, 0xfe, 0xfd, 0xd4, 0xbf, 0x60, 0xb8, 0xcc, 0x41,
- 0xbd, 0xac, 0xfb, 0xf4, 0x02, 0xa3, 0x4c, 0xd6, 0x15, 0x4c, 0x33, 0x22,
- 0xf8, 0x76, 0x8b, 0x07, 0x6f, 0x26, 0xca, 0xed, 0x71, 0x5f, 0x3a, 0xd7,
- 0xb2, 0x1e, 0x0f, 0xf9, 0xf1, 0x73, 0xa3, 0x2e, 0xbc, 0x40, 0xd5, 0x31,
- 0xa9, 0x79, 0x91, 0x20, 0xce, 0x76, 0xa5, 0x66, 0x73, 0xbe, 0xbc, 0xd8,
- 0x92, 0xc2, 0x46, 0xda, 0x93, 0xdf, 0x11, 0x01, 0xde, 0x48, 0x18, 0xc1,
- 0xcd, 0xec, 0x7f, 0xd8, 0xdb, 0x40, 0xfe, 0xad, 0x36, 0x91, 0xaa, 0xc5,
- 0x4b, 0x22, 0x46, 0x7c, 0x2b, 0xfe, 0xc3, 0x1a, 0x22, 0xce, 0x17, 0x85,
- 0x64, 0x6d, 0x6e, 0x0e, 0x8e, 0x6b, 0x0e, 0x3c, 0x1b, 0x9c, 0x8e, 0x28,
- 0xdd, 0xb1, 0xcc, 0x78, 0xcb, 0xfa, 0xa1, 0x57, 0xfa, 0x91, 0xb1, 0xfc,
- 0x86, 0xe3, 0x50, 0x6c, 0x2c, 0xdc, 0x92, 0x6a, 0xa0, 0xbe, 0x2f, 0xec,
- 0xff, 0xdf, 0xad, 0x49, 0xaf, 0xf4, 0xcf, 0x5c, 0x9e, 0xf1, 0xec, 0xc8,
- 0x1f, 0xc5, 0xee, 0x97, 0xac, 0xe7, 0xec, 0x36, 0x17, 0xb9, 0x73, 0x71,
- 0x50, 0xda, 0xfb, 0x17, 0x8e, 0x4f, 0xda, 0x2c, 0xf4, 0x23, 0x7a, 0xcb,
- 0xba, 0xc5, 0x9f, 0xb7, 0xa4, 0x44, 0x7f, 0x82, 0x57, 0xc7, 0x2c, 0x4c,
- 0x97, 0xf3, 0x87, 0xed, 0xb2, 0x71, 0xea, 0xab, 0x8b, 0x36, 0xc4, 0xd8,
- 0xcb, 0x3c, 0x4e, 0x76, 0x51, 0x68, 0x76, 0x9e, 0xb6, 0x89, 0xdc, 0x7e,
- 0xc8, 0x5b, 0x89, 0x2d, 0x26, 0xed, 0xce, 0x50, 0x2f, 0x76, 0x42, 0x72,
- 0x53, 0x39, 0x77, 0x61, 0xd2, 0xeb, 0xc0, 0x56, 0xd3, 0x89, 0x76, 0x43,
- 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x6b, 0x14, 0x6c, 0x0f,
- 0xab, 0x58, 0x6f, 0x74, 0xf9, 0xe5, 0xfa, 0x92, 0x90, 0x9c, 0x2b, 0x58,
- 0x43, 0x9d, 0xc4, 0x35, 0x05, 0x1b, 0x0c, 0x79, 0xbe, 0x98, 0xe3, 0xbe,
- 0x31, 0x58, 0xd6, 0x76, 0xb3, 0xf1, 0x8a, 0x32, 0x48, 0x9c, 0x17, 0x2e,
- 0xf7, 0xde, 0xcd, 0xf3, 0x03, 0x71, 0x12, 0x31, 0x3d, 0x56, 0x42, 0x3f,
- 0xdd, 0xd2, 0x37, 0x87, 0xf5, 0x14, 0x72, 0x1c, 0xa7, 0x6f, 0x1b, 0x24,
- 0x7e, 0x06, 0xfc, 0x3f, 0x65, 0xf2, 0x34, 0xe4, 0x9d, 0x47, 0xcd, 0x1a,
- 0xfe, 0x93, 0x9c, 0xb7, 0x4a, 0xc3, 0xb9, 0xf1, 0x07, 0xd0, 0xdb, 0x4b,
- 0x94, 0x79, 0xc1, 0x0a, 0xe6, 0x00, 0x71, 0xe2, 0xfb, 0xc8, 0x98, 0x13,
- 0x9b, 0x53, 0x86, 0xb6, 0xcf, 0xe6, 0x6e, 0x4e, 0xea, 0xc2, 0xc9, 0x1c,
- 0x3f, 0xa0, 0x4d, 0x28, 0x85, 0xf3, 0x39, 0x82, 0x0d, 0xe4, 0xe2, 0x82,
- 0x6f, 0x71, 0xeb, 0xc9, 0x06, 0x49, 0xdb, 0xdc, 0xfe, 0x58, 0xda, 0xc3,
- 0x43, 0xe3, 0xe1, 0xf5, 0xaf, 0x4d, 0xfb, 0xfc, 0x6b, 0xd2, 0xf0, 0xb7,
- 0xa5, 0x0b, 0x76, 0x59, 0xf0, 0x6d, 0xc1, 0x36, 0x8b, 0x7c, 0x33, 0x97,
- 0x73, 0x75, 0x49, 0x4e, 0x03, 0x79, 0x3e, 0xf6, 0xde, 0xcd, 0x4f, 0xd1,
- 0xd6, 0x5d, 0xe4, 0xf2, 0x5b, 0x8d, 0x78, 0x54, 0x9e, 0xd7, 0x19, 0x21,
- 0xdd, 0x57, 0xa4, 0xf8, 0xb1, 0xa5, 0xfe, 0x77, 0x9c, 0x4f, 0x72, 0xdc,
- 0xf4, 0xa7, 0x4a, 0x72, 0xf3, 0x21, 0x7e, 0x26, 0x18, 0xe0, 0x67, 0x1e,
- 0xe4, 0xf3, 0x77, 0xb1, 0x9f, 0x4d, 0xe9, 0xa9, 0x3e, 0xa0, 0xe0, 0x1a,
- 0xb6, 0xd5, 0x18, 0x82, 0x73, 0x69, 0xfd, 0x7f, 0x59, 0x59, 0xef, 0xd4,
- 0x7d, 0x11, 0x20, 0x87, 0x80, 0xb3, 0xad, 0x5e, 0xce, 0x15, 0x34, 0x86,
- 0xe5, 0x5c, 0x41, 0x9b, 0x91, 0x93, 0x4f, 0x7c, 0xb7, 0x9b, 0xb8, 0x7d,
- 0xee, 0xfc, 0x42, 0x2c, 0x32, 0x71, 0x7b, 0x0a, 0xb1, 0xa2, 0x88, 0x60,
- 0x91, 0xdb, 0xff, 0x5c, 0xba, 0x9e, 0x5c, 0x5c, 0x9e, 0x7f, 0xbb, 0x39,
- 0xe7, 0x1e, 0xff, 0xb3, 0xe9, 0x2b, 0x71, 0xdb, 0xae, 0x30, 0xda, 0x77,
- 0xc9, 0x86, 0x23, 0xe6, 0x60, 0xa1, 0x80, 0x7f, 0x14, 0x9a, 0xff, 0x38,
- 0x75, 0x72, 0x94, 0x72, 0x1e, 0x3b, 0x4f, 0x4e, 0xd1, 0x21, 0xfc, 0x77,
- 0x24, 0xdc, 0x48, 0x87, 0xde, 0xb7, 0xe2, 0x36, 0xe7, 0xf0, 0xfa, 0xef,
- 0x4c, 0xf8, 0x91, 0xb5, 0xb9, 0xe7, 0xbf, 0xbb, 0x25, 0x47, 0xec, 0x49,
- 0xc5, 0xa3, 0x4c, 0x79, 0xf3, 0xf3, 0xab, 0x87, 0x65, 0x6e, 0xdf, 0x48,
- 0xc8, 0xbd, 0xe8, 0x37, 0x54, 0xe8, 0x7e, 0x95, 0xb1, 0xb4, 0xdf, 0x14,
- 0xfb, 0xb5, 0xec, 0x67, 0xfb, 0xac, 0x18, 0xf7, 0x44, 0x02, 0xad, 0xf5,
- 0xbc, 0xae, 0x2d, 0x40, 0xac, 0x8a, 0x7a, 0x2a, 0x35, 0xbc, 0xfe, 0xba,
- 0x71, 0x9f, 0xdf, 0x1c, 0x87, 0xff, 0x92, 0xf1, 0xa9, 0x22, 0x90, 0xa3,
- 0xab, 0x1f, 0x87, 0x05, 0x5e, 0xff, 0xba, 0xc4, 0x1c, 0xa8, 0x91, 0xb8,
- 0xb5, 0xa4, 0xe1, 0xb4, 0x35, 0x27, 0x62, 0x64, 0x8f, 0x51, 0x86, 0xf7,
- 0x2f, 0xd7, 0xe3, 0x33, 0x1d, 0x47, 0xef, 0xd5, 0xa6, 0xf4, 0xf1, 0x5e,
- 0xe8, 0xff, 0x6f, 0x1f, 0x85, 0x38, 0x47, 0x7b, 0x68, 0x90, 0x31, 0x48,
- 0xbc, 0x2b, 0x62, 0xce, 0x29, 0x63, 0xf9, 0x54, 0xe1, 0xb9, 0x47, 0x7e,
- 0x5c, 0x0a, 0xe7, 0x1a, 0x36, 0x0f, 0xce, 0xc5, 0x30, 0xcb, 0xea, 0x36,
- 0x7c, 0xf9, 0xe7, 0x67, 0x9c, 0xb3, 0xcc, 0xd1, 0x2b, 0x9c, 0x58, 0x4c,
- 0x3f, 0x68, 0xfc, 0x4b, 0x27, 0xa2, 0xbe, 0x62, 0xc6, 0x56, 0x59, 0x17,
- 0x3a, 0x5e, 0x3f, 0x69, 0x4d, 0x18, 0xf5, 0x68, 0xcc, 0xc8, 0xf3, 0x4c,
- 0x07, 0xed, 0xdb, 0xc2, 0x23, 0xa6, 0xdc, 0x17, 0x9c, 0x89, 0xc7, 0x1c,
- 0xb4, 0x15, 0xb7, 0xa1, 0xb7, 0xfe, 0xbd, 0x52, 0x81, 0xd2, 0x88, 0x33,
- 0x38, 0x01, 0x3d, 0xbc, 0x5e, 0xa1, 0x1f, 0x56, 0xcd, 0x33, 0x65, 0x0a,
- 0xde, 0x4e, 0x04, 0xcc, 0x40, 0x3e, 0x2e, 0x9d, 0xe2, 0xdc, 0xbd, 0x93,
- 0x30, 0xda, 0x9f, 0xca, 0x9f, 0xff, 0x22, 0x3d, 0x35, 0xa7, 0x15, 0x7b,
- 0x74, 0xbb, 0x37, 0x25, 0xf0, 0x9e, 0xa3, 0x01, 0xef, 0xed, 0x31, 0x8b,
- 0x98, 0x8b, 0x89, 0x9d, 0xba, 0xdd, 0x5b, 0x12, 0x98, 0x74, 0xf2, 0xda,
- 0x29, 0x73, 0x36, 0x31, 0x4d, 0xe5, 0xb5, 0xb0, 0xd8, 0x59, 0x4c, 0x63,
- 0x7c, 0x2d, 0x8d, 0x78, 0xdd, 0xa5, 0xe3, 0xd0, 0x4a, 0x8c, 0x0a, 0xe6,
- 0xba, 0x68, 0x72, 0x24, 0x75, 0x7f, 0xb3, 0xa3, 0x9e, 0x39, 0xaf, 0x5f,
- 0x71, 0x19, 0xdf, 0x63, 0x5e, 0x2f, 0x6b, 0x61, 0x61, 0xda, 0xa4, 0x93,
- 0x15, 0x76, 0x4c, 0x57, 0x23, 0x0a, 0xb1, 0xb0, 0x02, 0xb7, 0x6b, 0x1b,
- 0x3e, 0xab, 0x46, 0xfa, 0x71, 0x7d, 0x83, 0xbb, 0xa9, 0x72, 0xbc, 0xa0,
- 0x13, 0xc4, 0x3c, 0x11, 0xe6, 0x25, 0x06, 0xd4, 0xf2, 0x88, 0xe8, 0xc6,
- 0xdf, 0x94, 0x1c, 0x13, 0x59, 0x35, 0x77, 0xdf, 0xd8, 0x3b, 0x25, 0x28,
- 0x0d, 0x13, 0xab, 0x7e, 0xe2, 0xfb, 0xef, 0xd5, 0x3b, 0x5a, 0x22, 0x78,
- 0xef, 0x32, 0xe4, 0xbf, 0x6d, 0x5b, 0x6e, 0x77, 0xe4, 0x83, 0x98, 0x3b,
- 0x60, 0x59, 0x8c, 0x93, 0x3e, 0x28, 0xb3, 0x39, 0x1e, 0xfa, 0x1a, 0xe7,
- 0x66, 0x4d, 0xfa, 0x0f, 0xd6, 0xe7, 0x9c, 0x36, 0x07, 0x70, 0x17, 0x47,
- 0x3a, 0x6e, 0x79, 0xcb, 0xf8, 0xc0, 0x7a, 0x33, 0xc1, 0x5c, 0xd9, 0x90,
- 0x67, 0x43, 0x73, 0xb0, 0xcd, 0x74, 0x36, 0x2f, 0x55, 0x14, 0xf4, 0x18,
- 0xf3, 0xb4, 0x12, 0xc6, 0xa9, 0x6e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0xf7,
- 0x80, 0xe5, 0xd2, 0xeb, 0xd6, 0xb9, 0x22, 0x77, 0xde, 0x32, 0xd2, 0x20,
- 0x58, 0x10, 0x6e, 0x7b, 0xca, 0x68, 0x41, 0x4f, 0x66, 0x10, 0xbd, 0x99,
- 0x5c, 0x3f, 0x59, 0xcc, 0xf9, 0x98, 0x7e, 0xd6, 0xad, 0x2b, 0x8e, 0x08,
- 0xf7, 0x3a, 0x73, 0xcb, 0x5e, 0x23, 0x8a, 0xcd, 0x99, 0x3b, 0x6f, 0x39,
- 0xd5, 0xd0, 0xcf, 0xff, 0xb9, 0x3a, 0x43, 0xa8, 0xfc, 0xd8, 0x3a, 0x65,
- 0x11, 0xe9, 0xa3, 0xe3, 0x96, 0xa7, 0x8c, 0x3b, 0x6f, 0x69, 0x5f, 0xf4,
- 0x4d, 0x6c, 0xca, 0xb4, 0xff, 0xc9, 0x7e, 0xca, 0x59, 0xa7, 0x34, 0x72,
- 0xa8, 0xed, 0x9a, 0xc0, 0x9d, 0xb7, 0xa4, 0x17, 0xf5, 0xb2, 0x8f, 0x55,
- 0x8c, 0x2f, 0xb9, 0x3a, 0x51, 0xc6, 0xf6, 0x8f, 0xd3, 0x41, 0x49, 0x64,
- 0xa2, 0x6d, 0x7e, 0xe0, 0x03, 0x6b, 0x5e, 0x5f, 0x91, 0xad, 0x03, 0x17,
- 0x75, 0xf0, 0xa0, 0xe9, 0xcc, 0x06, 0x1c, 0xb6, 0x0e, 0x3a, 0x7c, 0xd4,
- 0x41, 0x92, 0x3a, 0xc8, 0xd6, 0x18, 0xe1, 0x77, 0xa9, 0x83, 0x79, 0x63,
- 0xeb, 0xd6, 0x95, 0x44, 0xe0, 0x74, 0x18, 0xaf, 0x3a, 0x9c, 0x9c, 0x0b,
- 0x97, 0xb1, 0x8e, 0x7a, 0xbb, 0xf3, 0x96, 0x8b, 0x17, 0xd9, 0x3a, 0xff,
- 0xb2, 0x3b, 0xb0, 0xc1, 0xde, 0x3b, 0xd7, 0x9d, 0x59, 0xc3, 0xa3, 0x99,
- 0xc7, 0x7d, 0x3c, 0x7a, 0x98, 0xb3, 0xdc, 0x4c, 0x5d, 0x35, 0x71, 0x1c,
- 0x2b, 0x28, 0xd7, 0x46, 0xfe, 0x6e, 0xe5, 0xef, 0x0e, 0xfe, 0x96, 0xf9,
- 0x51, 0xcf, 0xca, 0x16, 0x3b, 0x2b, 0x9b, 0x83, 0xf2, 0x78, 0x88, 0x57,
- 0x32, 0x26, 0xf7, 0x57, 0xae, 0x09, 0xc4, 0xd8, 0xc6, 0xfd, 0xa5, 0xb2,
- 0x6f, 0xc8, 0x65, 0xc4, 0x7d, 0x4e, 0x88, 0x7c, 0x7a, 0x6b, 0x3b, 0xb2,
- 0xc4, 0xde, 0xdf, 0xe7, 0xb0, 0x97, 0xb2, 0x55, 0x70, 0x7e, 0x5e, 0x58,
- 0x34, 0x34, 0xc3, 0x63, 0xc0, 0xe7, 0x36, 0xe2, 0xcc, 0xf9, 0x13, 0xd4,
- 0x81, 0xd8, 0xc9, 0x3d, 0xd4, 0x5f, 0x27, 0xeb, 0x1c, 0x65, 0x2c, 0xdb,
- 0xcd, 0xfe, 0xed, 0xf5, 0xdb, 0xb0, 0xfd, 0x9c, 0x0c, 0xba, 0x79, 0x9c,
- 0xed, 0xed, 0x35, 0x7e, 0x53, 0x76, 0xb4, 0x5e, 0xf6, 0x53, 0x3a, 0x31,
- 0x6c, 0xcf, 0xbb, 0x42, 0x2e, 0x73, 0x11, 0x79, 0x82, 0x65, 0xfd, 0xd4,
- 0x68, 0x9c, 0xef, 0xb0, 0xed, 0xea, 0x50, 0x9b, 0x3b, 0xe0, 0xc6, 0x90,
- 0xbd, 0x06, 0x6e, 0x59, 0x45, 0xb6, 0x7d, 0x89, 0x2c, 0x75, 0xcd, 0x9b,
- 0x68, 0x78, 0xeb, 0xd2, 0x1f, 0x90, 0x27, 0x8a, 0xfc, 0x73, 0x70, 0x92,
- 0x31, 0x35, 0xaa, 0xc5, 0xdb, 0x45, 0xd6, 0x32, 0xc3, 0x19, 0xbe, 0x16,
- 0xf1, 0x16, 0x27, 0xfb, 0x6b, 0x26, 0xa7, 0x3c, 0x95, 0xc7, 0xee, 0x7d,
- 0x69, 0x3d, 0xb6, 0x5f, 0xc9, 0xf1, 0xd3, 0xde, 0xb1, 0x42, 0xfc, 0x09,
- 0x92, 0xcf, 0x7a, 0xe0, 0x8c, 0xe8, 0xfe, 0x26, 0x47, 0x57, 0xd0, 0x05,
- 0xfa, 0x58, 0xa9, 0xc8, 0x1b, 0xa7, 0xec, 0x82, 0xc7, 0x6e, 0x6d, 0x8d,
- 0x8d, 0xd1, 0xf1, 0xf9, 0x2e, 0x78, 0xb4, 0xb5, 0xe9, 0x42, 0xec, 0xf2,
- 0x68, 0x6d, 0x09, 0xf1, 0x77, 0x59, 0xab, 0x0f, 0xdb, 0xdc, 0xe3, 0x48,
- 0xe6, 0xa5, 0x52, 0xd9, 0x8b, 0x47, 0xdf, 0xaf, 0x70, 0x1a, 0xb9, 0x76,
- 0x35, 0xb6, 0xdb, 0xe2, 0xd0, 0x70, 0xce, 0x77, 0x75, 0xad, 0xc5, 0x21,
- 0xfb, 0x5f, 0x89, 0x4a, 0xe9, 0x7c, 0xbd, 0x1c, 0x7e, 0x2d, 0x76, 0xd9,
- 0xf8, 0xc5, 0x36, 0x4a, 0x81, 0x25, 0x89, 0x0b, 0xfb, 0x97, 0xfe, 0xa4,
- 0xdf, 0xae, 0x2a, 0x15, 0x13, 0xf6, 0xb3, 0x92, 0x83, 0x99, 0x18, 0x06,
- 0x53, 0x53, 0xf7, 0xe8, 0xe9, 0x87, 0xd8, 0xfe, 0x81, 0x38, 0xe7, 0x69,
- 0xb6, 0x21, 0xfb, 0xf7, 0x64, 0xcf, 0xde, 0xd4, 0xfd, 0x7a, 0x22, 0x5b,
- 0x65, 0x19, 0x81, 0x0d, 0x7b, 0x89, 0x7f, 0xd1, 0x16, 0xa9, 0x6f, 0x59,
- 0xaf, 0xcd, 0x0b, 0x22, 0x3b, 0xcd, 0x89, 0xc1, 0xb9, 0xc0, 0x40, 0x52,
- 0xf6, 0x53, 0x9d, 0x89, 0xad, 0x66, 0x1e, 0x19, 0xad, 0xae, 0xd3, 0xba,
- 0x55, 0xd9, 0x0b, 0xf5, 0xc1, 0x97, 0x7b, 0x8c, 0x5a, 0xad, 0x47, 0xcd,
- 0xee, 0x67, 0x7c, 0xd9, 0x0d, 0xcc, 0x2e, 0x13, 0x0c, 0xa8, 0x32, 0xa2,
- 0xbd, 0x55, 0x98, 0x0b, 0x7f, 0xb5, 0x8d, 0xcb, 0xf1, 0x6f, 0xab, 0x46,
- 0x70, 0xa5, 0xf0, 0x4a, 0xf5, 0x7d, 0x6b, 0x88, 0xdc, 0xe4, 0xee, 0xb9,
- 0xff, 0xa7, 0x34, 0xbf, 0xee, 0xd4, 0x3e, 0x9d, 0xf3, 0xf2, 0xf3, 0x05,
- 0xba, 0x3f, 0xad, 0x88, 0x8e, 0x84, 0x4b, 0x25, 0xb0, 0x95, 0x71, 0xf6,
- 0xbf, 0xe6, 0x46, 0xb0, 0x8f, 0xff, 0x7f, 0x76, 0xa5, 0xec, 0x4d, 0xb5,
- 0xac, 0x60, 0x60, 0x5e, 0xb8, 0x8a, 0x63, 0x78, 0x96, 0xf7, 0x7b, 0x33,
- 0x6f, 0x59, 0xa7, 0xa6, 0x1b, 0xfd, 0xcb, 0x18, 0xec, 0x06, 0xc6, 0x75,
- 0x6d, 0x52, 0xfd, 0xef, 0xee, 0x95, 0x83, 0xbb, 0x82, 0x63, 0xf9, 0x7e,
- 0xa0, 0x4e, 0x4b, 0xaa, 0xa5, 0x65, 0xa2, 0xd7, 0x81, 0xf1, 0x57, 0xa6,
- 0x3c, 0x3b, 0x28, 0xf0, 0x59, 0x7b, 0x5d, 0xa5, 0x77, 0x88, 0xbe, 0x3e,
- 0xa4, 0x45, 0xe3, 0xd4, 0xbb, 0x7b, 0x1a, 0xc7, 0x7c, 0xf7, 0xdc, 0x2f,
- 0xd9, 0xe3, 0xac, 0x36, 0x66, 0x72, 0x8c, 0x0a, 0xb4, 0xb9, 0xff, 0x99,
- 0x5f, 0x7f, 0x6d, 0x24, 0xfb, 0x1a, 0xb2, 0x9a, 0xe8, 0x1b, 0x45, 0xac,
- 0x73, 0xb5, 0xf9, 0xf0, 0x8c, 0xae, 0x7a, 0xdd, 0x77, 0x37, 0x6d, 0x34,
- 0x34, 0xf7, 0xd7, 0x16, 0x6d, 0xda, 0xfc, 0x16, 0x47, 0x7d, 0x5b, 0xc2,
- 0x8e, 0x55, 0x9c, 0x57, 0x23, 0x3a, 0x57, 0x79, 0xc7, 0x42, 0x4d, 0x20,
- 0x3c, 0xd7, 0x1e, 0x3f, 0x70, 0x6b, 0x3a, 0x81, 0x6d, 0x29, 0x69, 0x53,
- 0xc1, 0xb2, 0xc0, 0xdb, 0x96, 0x7f, 0x7a, 0x02, 0x5b, 0x32, 0x9f, 0xc4,
- 0x4d, 0x07, 0xc9, 0x8d, 0xf5, 0xd6, 0x38, 0xf4, 0x68, 0xee, 0xd9, 0xd4,
- 0x1c, 0x59, 0xdb, 0x96, 0xbd, 0x45, 0xb7, 0x24, 0x02, 0x70, 0x97, 0x13,
- 0x83, 0xc7, 0x02, 0xf2, 0x2c, 0xd3, 0x8b, 0x6c, 0x8b, 0x94, 0xa9, 0xd5,
- 0xc6, 0x90, 0x25, 0x73, 0x94, 0xb5, 0xd0, 0xfe, 0xb2, 0xdc, 0x3e, 0x09,
- 0x1a, 0x5e, 0x8d, 0xae, 0xbd, 0x41, 0xae, 0xd7, 0x6c, 0x48, 0x1b, 0x0a,
- 0xe6, 0x07, 0xa6, 0xa1, 0x6e, 0xe5, 0xab, 0xaf, 0x17, 0x05, 0x8a, 0x18,
- 0x4f, 0xc4, 0xb7, 0x8c, 0x8d, 0xc7, 0xf0, 0x1b, 0x62, 0x90, 0xec, 0x19,
- 0x4b, 0x4a, 0x3d, 0xb6, 0x35, 0x17, 0x69, 0xf1, 0x53, 0x43, 0xf6, 0x2f,
- 0x5b, 0xd6, 0x35, 0x81, 0x37, 0xad, 0x68, 0x0d, 0xe5, 0x21, 0x5f, 0xcb,
- 0xd5, 0x95, 0x32, 0xf9, 0xbd, 0x40, 0x4a, 0xe3, 0x2d, 0xa2, 0x93, 0x27,
- 0xcd, 0x38, 0xb3, 0x01, 0xc1, 0xfd, 0x0f, 0x62, 0x6f, 0x19, 0x8a, 0xfd,
- 0x8c, 0x71, 0x99, 0x52, 0xc9, 0x38, 0xea, 0xf4, 0x8f, 0xd8, 0xeb, 0x05,
- 0x1d, 0xc4, 0x68, 0xe1, 0x97, 0x92, 0xf3, 0x39, 0xf1, 0x94, 0x51, 0x85,
- 0x27, 0xb5, 0x1c, 0x57, 0x23, 0xd6, 0xe1, 0x07, 0x89, 0x79, 0x59, 0x7a,
- 0x08, 0x39, 0xaf, 0xd1, 0x7e, 0x46, 0xf9, 0x0d, 0xfd, 0x1c, 0x78, 0x21,
- 0xbd, 0x11, 0x0f, 0xca, 0x1a, 0xa2, 0x52, 0xdb, 0x5c, 0xe7, 0x90, 0xfe,
- 0x36, 0x62, 0x6b, 0x46, 0xda, 0xfa, 0x20, 0xb6, 0xd7, 0xd8, 0x9d, 0x97,
- 0x55, 0xb0, 0xfc, 0x83, 0xd8, 0x53, 0xc6, 0xe3, 0xf6, 0xdc, 0xc9, 0x73,
- 0xaf, 0x5e, 0x53, 0x30, 0xaf, 0x14, 0x2a, 0xf3, 0x06, 0x87, 0x71, 0x33,
- 0x1c, 0x55, 0xdf, 0xa4, 0xed, 0xc9, 0xbe, 0x9a, 0xaf, 0xc2, 0x59, 0xe5,
- 0xa2, 0x6f, 0xde, 0x0a, 0x57, 0x95, 0x70, 0xf5, 0x02, 0x8f, 0x8e, 0xf2,
- 0xbe, 0xe8, 0x36, 0xdc, 0x26, 0xba, 0x75, 0x12, 0x87, 0x7a, 0x24, 0xaf,
- 0x33, 0x2a, 0xa9, 0x23, 0xbd, 0x95, 0x9c, 0x1e, 0xe5, 0xc4, 0x4c, 0xc6,
- 0x47, 0x37, 0xf3, 0xb7, 0xb6, 0x77, 0xa9, 0xf7, 0x79, 0x7d, 0x65, 0xe4,
- 0xf0, 0x96, 0xf5, 0x3e, 0x39, 0xfc, 0xfc, 0x40, 0x5d, 0xd6, 0x20, 0x4e,
- 0xe1, 0x06, 0xbd, 0x39, 0x4e, 0xbc, 0x59, 0x6d, 0x9c, 0xb1, 0x62, 0xab,
- 0xa4, 0x8c, 0xee, 0x8b, 0x29, 0x85, 0x3e, 0x16, 0xc0, 0x3f, 0xcd, 0x82,
- 0x2b, 0x22, 0xcf, 0x14, 0x64, 0xbd, 0xb8, 0x51, 0x9e, 0xf5, 0xb5, 0xc8,
- 0xf8, 0x5d, 0xb2, 0xee, 0x86, 0xe8, 0x84, 0x0b, 0x46, 0x76, 0x9f, 0xcc,
- 0xd9, 0x0c, 0x0b, 0x81, 0x85, 0xbf, 0x67, 0x2e, 0x24, 0xf3, 0x53, 0x9b,
- 0xad, 0x57, 0xb2, 0x41, 0x1f, 0x39, 0xfd, 0xa3, 0xd0, 0x5b, 0x12, 0xd4,
- 0x75, 0x53, 0x48, 0x9e, 0xdf, 0x3b, 0x7d, 0x09, 0xd8, 0x3c, 0xde, 0x3c,
- 0x89, 0xcf, 0xa1, 0x9c, 0xb9, 0xeb, 0xdc, 0xb1, 0x15, 0xa8, 0xa8, 0x8a,
- 0xfa, 0x4a, 0x71, 0x19, 0xcf, 0xd7, 0x30, 0x3f, 0xf9, 0x22, 0x2a, 0x56,
- 0xb6, 0x22, 0xc1, 0xb1, 0x97, 0x1b, 0x7f, 0xc5, 0x6b, 0xf7, 0x21, 0x99,
- 0x72, 0x71, 0x1c, 0x3f, 0xb1, 0x2a, 0x6a, 0x44, 0x36, 0xd3, 0x5b, 0x66,
- 0x30, 0x9f, 0xb6, 0x75, 0x41, 0xdc, 0x4e, 0x09, 0x47, 0xaa, 0x8b, 0xae,
- 0x07, 0x73, 0xfb, 0x1a, 0xbd, 0x75, 0x8d, 0xd2, 0x41, 0x9b, 0xed, 0xa1,
- 0xce, 0xa5, 0xac, 0x65, 0x2d, 0x0f, 0x9c, 0xa6, 0x8e, 0x3b, 0x78, 0x6e,
- 0xf8, 0xdf, 0x84, 0x7a, 0x59, 0x31, 0x4e, 0x58, 0x71, 0xcd, 0x47, 0xbb,
- 0x54, 0x57, 0x09, 0x9f, 0x5a, 0x1a, 0x7a, 0x8f, 0xf7, 0xb5, 0xbc, 0x9d,
- 0x9e, 0xb9, 0x25, 0xa7, 0xcb, 0x30, 0x75, 0xf9, 0x6f, 0xf6, 0x75, 0x87,
- 0x7d, 0xbd, 0x23, 0x7f, 0xfd, 0xcc, 0x2d, 0x3d, 0xc6, 0xcb, 0xbc, 0xde,
- 0x4b, 0xdd, 0xab, 0x17, 0x49, 0xfd, 0x75, 0xa6, 0xd4, 0x67, 0x4a, 0x65,
- 0xf4, 0xe4, 0xe7, 0xe3, 0x50, 0x7e, 0x3e, 0x26, 0xf2, 0x6d, 0x38, 0xd9,
- 0x46, 0x3c, 0x5a, 0x0a, 0x13, 0x65, 0x01, 0xc1, 0x79, 0x91, 0x8b, 0x73,
- 0x97, 0x11, 0xb9, 0xd6, 0x30, 0xde, 0x75, 0x3d, 0x53, 0x8a, 0x78, 0xc7,
- 0x4c, 0xdb, 0x0e, 0xcf, 0xdc, 0x22, 0xfb, 0xde, 0xde, 0x52, 0x1a, 0x7d,
- 0xb2, 0x65, 0x23, 0x45, 0x2e, 0x7b, 0xaf, 0xe9, 0x0c, 0xd7, 0x3b, 0xe6,
- 0x65, 0x8b, 0x61, 0xc4, 0xce, 0x28, 0x2e, 0x8f, 0xe0, 0x43, 0x22, 0xdd,
- 0xc8, 0xcc, 0x2b, 0x1e, 0x64, 0xce, 0x14, 0xcc, 0x50, 0xb7, 0x6d, 0x44,
- 0xec, 0x43, 0xf6, 0xde, 0x37, 0xe7, 0xc4, 0x0a, 0x34, 0xea, 0x0e, 0xcc,
- 0x0b, 0xcf, 0x64, 0xe6, 0x45, 0xbb, 0x34, 0x8b, 0x1d, 0xba, 0xff, 0x7a,
- 0x2c, 0xb7, 0xeb, 0xed, 0x4b, 0x67, 0xdb, 0x4b, 0x39, 0xa7, 0x8f, 0x51,
- 0x8e, 0x6d, 0x01, 0x91, 0xe3, 0x9b, 0x79, 0x39, 0x5a, 0x19, 0x4b, 0x4d,
- 0xed, 0xda, 0x40, 0xef, 0x59, 0xbd, 0x3d, 0x63, 0xeb, 0xed, 0x3e, 0x9e,
- 0x17, 0x33, 0xbf, 0x2f, 0xc2, 0xd1, 0x7a, 0x6f, 0x7e, 0x1f, 0x9b, 0xe4,
- 0x6a, 0x82, 0xbf, 0x0d, 0x7f, 0xbd, 0xda, 0xd0, 0xc3, 0x0e, 0x9b, 0xd7,
- 0xbb, 0x11, 0xb7, 0x39, 0xb3, 0x3c, 0xf3, 0xae, 0xc0, 0x23, 0x76, 0x39,
- 0x17, 0x75, 0x52, 0x86, 0x47, 0xf3, 0xfe, 0x22, 0x7b, 0x0e, 0x1e, 0xb3,
- 0x7f, 0xef, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0x85, 0x18, 0x25, 0xeb, 0xed,
- 0xff, 0xc3, 0xf6, 0xfd, 0x21, 0x1c, 0xb7, 0xff, 0x67, 0x73, 0xf9, 0x16,
- 0x7a, 0x4c, 0xd9, 0x3b, 0x53, 0x86, 0x6e, 0x7b, 0x0f, 0xb9, 0xac, 0x01,
- 0x5c, 0x89, 0xcd, 0x9a, 0xac, 0x07, 0x93, 0xfb, 0x68, 0x62, 0x13, 0x9d,
- 0x48, 0x6a, 0xa6, 0x37, 0x53, 0x3f, 0x35, 0x57, 0x32, 0xb1, 0xa7, 0xfe,
- 0x03, 0x2b, 0x6a, 0xe7, 0x4f, 0x27, 0xac, 0xbd, 0xc6, 0xd1, 0x10, 0x3d,
- 0xb8, 0xbd, 0xc8, 0xd6, 0x6f, 0xb8, 0xcd, 0xde, 0xff, 0x47, 0x99, 0x9f,
- 0x49, 0x48, 0x1c, 0x9d, 0x83, 0xb4, 0x69, 0xc7, 0xe2, 0x96, 0xed, 0x9c,
- 0x93, 0x9e, 0x54, 0x20, 0x7a, 0x09, 0xef, 0x4d, 0x30, 0x96, 0x75, 0x53,
- 0x9f, 0xb1, 0x16, 0xe1, 0x67, 0x6b, 0xb0, 0x9b, 0x36, 0x36, 0x6e, 0x5a,
- 0xd6, 0x3e, 0x62, 0x44, 0xe5, 0x3c, 0x15, 0xd9, 0x9a, 0x35, 0x48, 0x31,
- 0x36, 0xed, 0x33, 0x1a, 0x3f, 0x57, 0x84, 0xb8, 0xdf, 0x0d, 0xdd, 0xb7,
- 0x85, 0xa3, 0xb9, 0x97, 0xf3, 0x75, 0xd4, 0x14, 0xde, 0xe8, 0x3c, 0xb3,
- 0x14, 0x46, 0x78, 0xb1, 0xe3, 0x27, 0xd6, 0xa4, 0xfd, 0xec, 0xb8, 0xeb,
- 0x5f, 0x28, 0xc3, 0x46, 0x71, 0xde, 0x4a, 0xce, 0xf1, 0xbb, 0x01, 0x79,
- 0x7e, 0x0d, 0xd4, 0xf5, 0x35, 0xb6, 0x8b, 0x0c, 0x7b, 0x43, 0xce, 0xd8,
- 0x3e, 0x04, 0x5a, 0x36, 0x28, 0xe7, 0x72, 0x83, 0x4b, 0xc6, 0x4c, 0x8c,
- 0xd6, 0x3f, 0x4b, 0x1e, 0x23, 0xf5, 0x8b, 0xf1, 0x84, 0xf9, 0xb4, 0x55,
- 0x3b, 0xe3, 0xfb, 0xd6, 0x7e, 0x43, 0x5d, 0x4f, 0x6d, 0xc7, 0xca, 0xd9,
- 0x56, 0x19, 0xdb, 0xba, 0x3d, 0xa0, 0x9b, 0xdb, 0xd9, 0xd6, 0xf1, 0xc4,
- 0xd1, 0xa0, 0x9b, 0x6d, 0x3d, 0x6a, 0x4a, 0x6e, 0xe0, 0x6c, 0x6e, 0xe6,
- 0xdc, 0x76, 0xa5, 0x02, 0xbe, 0xad, 0x94, 0x4b, 0xf2, 0xb7, 0xaf, 0x26,
- 0xe4, 0x5d, 0x8f, 0x6f, 0x72, 0x3c, 0xd1, 0x8d, 0x2e, 0x34, 0xde, 0x5b,
- 0x41, 0xfb, 0xa9, 0x44, 0xc1, 0xd6, 0x75, 0x1f, 0xf1, 0x0e, 0xb7, 0xb3,
- 0xcc, 0xeb, 0x81, 0x39, 0x78, 0x21, 0xd4, 0xb8, 0x72, 0x0e, 0x9c, 0xe4,
- 0x21, 0x81, 0xe6, 0x0d, 0x4a, 0x5c, 0x13, 0x5b, 0xbc, 0x2d, 0xad, 0x07,
- 0x9b, 0x20, 0xd8, 0xdd, 0x4a, 0x7d, 0xcc, 0xc1, 0xfb, 0x0b, 0x45, 0x2e,
- 0x67, 0x38, 0xe8, 0x08, 0x74, 0x3c, 0xcd, 0xf9, 0xad, 0x98, 0x97, 0xcb,
- 0x53, 0x33, 0xf6, 0x7e, 0xcd, 0x56, 0x24, 0x33, 0x27, 0xde, 0xdd, 0x6b,
- 0xc0, 0x79, 0xa8, 0xfe, 0x41, 0x0b, 0xf6, 0xbb, 0x21, 0x8d, 0x32, 0x0f,
- 0xad, 0x32, 0x0f, 0xa5, 0xf4, 0xa7, 0x6b, 0x28, 0xf7, 0x7a, 0x5b, 0xee,
- 0x39, 0x18, 0x36, 0x65, 0xfd, 0xcb, 0xa9, 0xdd, 0x86, 0x5e, 0x62, 0x67,
- 0xe0, 0x4c, 0x17, 0xfb, 0x79, 0x9d, 0x32, 0xcf, 0xa3, 0xde, 0x27, 0x5b,
- 0x84, 0xb7, 0xde, 0x87, 0xbe, 0x54, 0xe1, 0xdd, 0x11, 0x05, 0xe9, 0x80,
- 0xf4, 0x71, 0x1f, 0x79, 0x5c, 0x97, 0x35, 0x59, 0x23, 0xd7, 0x77, 0x33,
- 0xf7, 0x8f, 0x6a, 0xf4, 0x07, 0xea, 0x1d, 0xfa, 0x1c, 0xe8, 0x13, 0x6f,
- 0x38, 0xa2, 0xf4, 0x01, 0xd3, 0x7b, 0x86, 0xd8, 0x70, 0x08, 0x1d, 0x16,
- 0xaa, 0x6c, 0x7b, 0xf8, 0xd9, 0x88, 0xf1, 0xa1, 0x22, 0xb1, 0x3d, 0x4b,
- 0x1d, 0xa8, 0x9c, 0x13, 0xd1, 0x41, 0x39, 0x7d, 0x76, 0x2c, 0xa0, 0xfb,
- 0x5f, 0xa0, 0x3c, 0xdb, 0x29, 0xcf, 0x8a, 0xdc, 0x1c, 0xfa, 0x36, 0x2b,
- 0xe2, 0xd3, 0x81, 0x96, 0xd5, 0xbc, 0xbe, 0x8d, 0xf2, 0x04, 0xfa, 0x14,
- 0x0c, 0xb5, 0xf4, 0x90, 0x2b, 0x76, 0x50, 0x07, 0xe7, 0xe4, 0x71, 0xdb,
- 0x73, 0xd6, 0x41, 0x2e, 0x50, 0x8c, 0xbd, 0xa6, 0xe0, 0xb7, 0x86, 0x61,
- 0xda, 0xe9, 0x1e, 0xce, 0x48, 0xd4, 0xab, 0xa2, 0xd8, 0x10, 0x0c, 0xa8,
- 0xe1, 0x35, 0x17, 0xe7, 0xa6, 0x12, 0xfb, 0xb5, 0xdd, 0xf6, 0x5e, 0xe5,
- 0x1c, 0xb7, 0xfb, 0x83, 0x35, 0xea, 0x15, 0x7e, 0x26, 0xeb, 0x63, 0xb2,
- 0x86, 0xd4, 0xeb, 0xc9, 0xed, 0xd7, 0x72, 0x51, 0x27, 0xb9, 0xeb, 0xcf,
- 0x68, 0xc2, 0x7d, 0x0b, 0xe5, 0x7f, 0x69, 0x3d, 0x69, 0x97, 0x97, 0x72,
- 0x2e, 0x9b, 0xa3, 0x97, 0xda, 0xe5, 0x7e, 0x69, 0x3d, 0xab, 0x39, 0xa7,
- 0x94, 0x2b, 0x3c, 0x2f, 0x3c, 0xfa, 0x0d, 0x27, 0x31, 0xaf, 0x78, 0xee,
- 0x62, 0x1c, 0x33, 0x4e, 0xd4, 0x9e, 0xac, 0xef, 0x64, 0x1c, 0x9b, 0xba,
- 0x7f, 0xcb, 0xc2, 0xe3, 0x76, 0x1e, 0xde, 0x45, 0x3e, 0x7b, 0x74, 0x47,
- 0x11, 0x84, 0xa3, 0xca, 0xfa, 0x5d, 0x73, 0xd9, 0xb9, 0x5c, 0x56, 0xf6,
- 0x35, 0x5d, 0x66, 0x73, 0xc3, 0xa8, 0x2a, 0xb8, 0xfb, 0x49, 0x7b, 0xf8,
- 0x84, 0xbb, 0x74, 0x62, 0x8f, 0x51, 0xe0, 0x2c, 0x47, 0x1f, 0x54, 0x89,
- 0x93, 0x03, 0xe6, 0x62, 0x89, 0xcd, 0x7e, 0xd6, 0x0f, 0xc6, 0xd4, 0xa9,
- 0xdc, 0xe6, 0x76, 0x0f, 0x2a, 0xba, 0xb6, 0x3a, 0x20, 0xfb, 0x47, 0x65,
- 0x2f, 0xa8, 0xf4, 0x55, 0x92, 0x5f, 0x97, 0xfa, 0x38, 0xae, 0x51, 0xe8,
- 0x4b, 0xf8, 0xc6, 0xfb, 0xa5, 0x85, 0x7d, 0x86, 0x51, 0x5b, 0xce, 0x5f,
- 0x59, 0x2b, 0xb5, 0xec, 0x4c, 0x0d, 0xe7, 0xcb, 0x1e, 0xcd, 0xcb, 0x1e,
- 0xfb, 0xd8, 0x75, 0xb5, 0xa9, 0xfb, 0xee, 0x82, 0xf9, 0xe7, 0x5d, 0xf2,
- 0x0c, 0x46, 0xd6, 0x5c, 0xe5, 0x9e, 0x82, 0x2e, 0xe2, 0x50, 0x54, 0x6b,
- 0x64, 0x9c, 0xd7, 0x7d, 0x6b, 0x39, 0x1f, 0x71, 0xaf, 0xec, 0x51, 0x2f,
- 0xc4, 0xc8, 0x62, 0xe4, 0xd6, 0x3e, 0x65, 0x9f, 0x45, 0x6e, 0xbd, 0x93,
- 0x76, 0x8f, 0xae, 0xf4, 0xef, 0xad, 0xac, 0xd7, 0xc9, 0x58, 0x78, 0x6e,
- 0x7f, 0xf4, 0x10, 0xf5, 0x3a, 0xcc, 0x7b, 0x9b, 0xcf, 0xae, 0xa7, 0xc8,
- 0x9a, 0x92, 0xc4, 0xde, 0xdf, 0x59, 0x6d, 0xe7, 0x95, 0x9d, 0xba, 0x57,
- 0xbc, 0x26, 0x26, 0xcf, 0xdc, 0x46, 0xf3, 0xeb, 0xee, 0x4d, 0x1f, 0x79,
- 0xe6, 0x36, 0x41, 0x5b, 0x42, 0x74, 0x33, 0xb9, 0x5d, 0x1c, 0x3d, 0x18,
- 0x4d, 0xd4, 0x69, 0x5b, 0xa0, 0xc9, 0x7a, 0x33, 0xff, 0x7a, 0xb0, 0x3f,
- 0x81, 0x68, 0xd1, 0xa5, 0x95, 0xe4, 0x5b, 0x88, 0x3a, 0x18, 0xa3, 0x1e,
- 0x4d, 0xd4, 0x35, 0x6f, 0xe3, 0x98, 0xfc, 0x2b, 0x7b, 0x30, 0x9c, 0x68,
- 0xfc, 0x2b, 0xc6, 0x11, 0x7f, 0x99, 0xcd, 0x75, 0xe2, 0x7f, 0xbd, 0x97,
- 0x38, 0xb0, 0x29, 0xbf, 0xe6, 0xd5, 0x96, 0xf8, 0x35, 0xe5, 0xb7, 0x85,
- 0x64, 0xbd, 0x4f, 0x2a, 0x37, 0xc1, 0x3c, 0xff, 0x04, 0xd6, 0xf5, 0x2b,
- 0x78, 0xd2, 0x38, 0x81, 0xb5, 0x43, 0x22, 0xcf, 0x09, 0xac, 0xe9, 0x7f,
- 0x09, 0x7b, 0xfa, 0x67, 0xa0, 0xc9, 0xd6, 0x4d, 0x07, 0x36, 0xec, 0x3c,
- 0x88, 0xed, 0x29, 0x0b, 0xdb, 0x42, 0x1e, 0xac, 0x7f, 0x58, 0xc1, 0xf2,
- 0xc0, 0x61, 0x6c, 0xd9, 0x69, 0xe1, 0xe2, 0x50, 0x27, 0x9a, 0xcd, 0x32,
- 0x14, 0x57, 0xcd, 0x6b, 0x57, 0x59, 0xae, 0x6d, 0xb8, 0x23, 0xbf, 0x2f,
- 0x79, 0x3f, 0xb1, 0x40, 0x85, 0xcf, 0x90, 0x3d, 0xc7, 0x51, 0xe5, 0xa6,
- 0x4c, 0x93, 0xd2, 0x9a, 0x7f, 0x66, 0x79, 0x7d, 0xa6, 0xa8, 0x02, 0xa5,
- 0x71, 0xec, 0x09, 0x9d, 0xc0, 0xd0, 0xd0, 0x07, 0xe5, 0x39, 0x7f, 0x99,
- 0x20, 0x77, 0x90, 0x9c, 0xc3, 0xa4, 0x4d, 0x7d, 0xd2, 0xfb, 0x40, 0x62,
- 0x77, 0x93, 0xf8, 0xe9, 0xe0, 0x49, 0x9c, 0x1c, 0xfc, 0x37, 0x2c, 0xd1,
- 0x24, 0x7f, 0xb4, 0x3a, 0x9d, 0x11, 0xcb, 0xda, 0xd5, 0x10, 0xb7, 0x6a,
- 0x8c, 0x5f, 0xb0, 0xed, 0x0a, 0x4c, 0x8f, 0xbc, 0x88, 0x6d, 0x1a, 0xdb,
- 0x4a, 0xed, 0xc7, 0x0e, 0xc6, 0x75, 0x5f, 0xe4, 0x66, 0xf8, 0x52, 0x59,
- 0xb3, 0x1a, 0xd1, 0x1d, 0xd5, 0xd0, 0x37, 0x56, 0x39, 0x8c, 0x8e, 0x7f,
- 0x55, 0xea, 0x71, 0x7d, 0xe6, 0x24, 0x7e, 0x3e, 0x68, 0xef, 0xa5, 0x6a,
- 0xfd, 0xae, 0x62, 0x75, 0x6e, 0x0b, 0xe9, 0xcd, 0xff, 0x43, 0x89, 0xc6,
- 0x4b, 0x69, 0x53, 0x25, 0xcc, 0x09, 0x6e, 0x18, 0x94, 0x1c, 0xb1, 0x15,
- 0xee, 0x3e, 0x3d, 0xbb, 0x94, 0x3c, 0xfb, 0xee, 0x05, 0xf1, 0x99, 0xd3,
- 0x68, 0x97, 0x0e, 0x45, 0x0f, 0x1a, 0x6a, 0x27, 0x8e, 0x98, 0xfa, 0xc4,
- 0xef, 0x1c, 0xc6, 0xd0, 0x77, 0x50, 0x8f, 0x55, 0x19, 0x7d, 0xe8, 0x32,
- 0xe6, 0x61, 0x5b, 0x92, 0x26, 0x52, 0x49, 0xbd, 0xb5, 0xc3, 0xd1, 0x8b,
- 0x3b, 0x02, 0xb5, 0x1b, 0xdf, 0x25, 0x97, 0xf3, 0x10, 0x53, 0x92, 0xe3,
- 0x23, 0xcc, 0x5f, 0x7b, 0xb1, 0xe1, 0xe1, 0x08, 0xd6, 0xef, 0x32, 0xd1,
- 0x93, 0x1c, 0xa1, 0x6c, 0x3f, 0x2c, 0x97, 0xbd, 0x34, 0x2d, 0xa1, 0xf8,
- 0xb5, 0x2a, 0x02, 0x51, 0xf6, 0xd9, 0xa8, 0x46, 0x02, 0x7e, 0x55, 0x61,
- 0xf4, 0x1f, 0x77, 0xa2, 0x9b, 0x65, 0xfa, 0x52, 0xb4, 0xb9, 0xa4, 0x9b,
- 0xf1, 0x72, 0x16, 0x86, 0xc7, 0x7c, 0xd8, 0x37, 0xe6, 0xc1, 0xd0, 0x98,
- 0xc6, 0xa3, 0x14, 0x0f, 0x0d, 0xc8, 0x9e, 0x14, 0x2f, 0x9e, 0xd8, 0xeb,
- 0xc6, 0xa6, 0x07, 0x3c, 0x98, 0x13, 0x99, 0x8e, 0xbd, 0x7b, 0x4b, 0xb1,
- 0x9b, 0xd7, 0xab, 0x16, 0xfa, 0xf1, 0x38, 0xaf, 0xf7, 0x3f, 0xe0, 0xe2,
- 0x3c, 0x5c, 0x8c, 0x03, 0x34, 0xec, 0xa1, 0xb1, 0x32, 0xa4, 0x06, 0x68,
- 0xf2, 0xe4, 0xac, 0x6f, 0x31, 0xc3, 0x18, 0xdd, 0xcb, 0xd8, 0xf8, 0xb0,
- 0x89, 0x04, 0xfb, 0xd9, 0x4e, 0x5d, 0xf5, 0x10, 0xd7, 0x36, 0x8c, 0x09,
- 0xc6, 0xaf, 0xc2, 0x35, 0x7d, 0x7a, 0x73, 0x93, 0x62, 0x44, 0x17, 0xd9,
- 0xfb, 0xb4, 0xe4, 0xbd, 0xad, 0x55, 0x68, 0x4c, 0xe8, 0x66, 0x13, 0x3a,
- 0x71, 0x8c, 0xe3, 0xfe, 0x7f, 0xe8, 0xb7, 0x8b, 0x1d, 0x7a, 0xef, 0xd5,
- 0xea, 0x41, 0xec, 0xc8, 0x1c, 0x22, 0x57, 0x07, 0xc2, 0x7b, 0x0e, 0x92,
- 0xbf, 0x1d, 0x21, 0xfe, 0xbc, 0x6e, 0xf9, 0x0c, 0x15, 0xd7, 0xdf, 0x6f,
- 0x84, 0xdf, 0x53, 0x02, 0x1b, 0x7f, 0x45, 0x1d, 0x7c, 0x7e, 0xaf, 0x8a,
- 0xeb, 0x76, 0x2c, 0x46, 0x3a, 0x14, 0xc5, 0xf6, 0x45, 0x2a, 0xae, 0x7d,
- 0xf8, 0x20, 0x71, 0x7f, 0xc2, 0xe6, 0xc9, 0xd9, 0xf4, 0x7d, 0x08, 0xf6,
- 0xc9, 0x9a, 0xbc, 0x9b, 0xf1, 0xbb, 0x1c, 0xc7, 0xfb, 0x3b, 0xe9, 0xb7,
- 0xe5, 0x38, 0x3a, 0x74, 0x90, 0xf6, 0x58, 0x8e, 0x23, 0xfd, 0xc6, 0xc4,
- 0x4f, 0x1d, 0xe5, 0x78, 0x82, 0xe7, 0x3b, 0x78, 0xbe, 0x70, 0xc0, 0xe8,
- 0xef, 0x50, 0xcb, 0xb1, 0x60, 0x4f, 0x03, 0xfa, 0x93, 0x62, 0x9b, 0x1a,
- 0x36, 0x8e, 0xd5, 0xe7, 0x75, 0x2f, 0x3a, 0xf7, 0xe2, 0x4e, 0xea, 0xea,
- 0x8e, 0x1d, 0x9d, 0xec, 0xcf, 0x47, 0x9d, 0x1f, 0xc4, 0x43, 0xcc, 0xeb,
- 0xb6, 0x25, 0x7d, 0x38, 0x9d, 0x32, 0xfc, 0x5f, 0x52, 0x0c, 0xb3, 0x44,
- 0x09, 0x68, 0xc7, 0xe1, 0xc3, 0xc9, 0x4c, 0x29, 0xba, 0x07, 0x66, 0xe1,
- 0xa7, 0xb4, 0xcf, 0x07, 0x1f, 0x90, 0xfe, 0x26, 0x18, 0x1f, 0x66, 0xe3,
- 0x89, 0x11, 0x93, 0x6d, 0xcb, 0x3c, 0x49, 0xcc, 0xe9, 0x81, 0x2b, 0x25,
- 0xbe, 0x11, 0xdd, 0x41, 0xb3, 0x20, 0x26, 0x1e, 0x46, 0xa6, 0x5f, 0xef,
- 0xbd, 0x41, 0x15, 0x5e, 0xad, 0x52, 0x97, 0x0e, 0x4c, 0x6a, 0x7a, 0xbc,
- 0x4a, 0x8d, 0xf7, 0x33, 0x7f, 0x8d, 0x57, 0xab, 0x87, 0xf1, 0x44, 0xbf,
- 0x13, 0xf3, 0x16, 0xaa, 0xbc, 0x1e, 0x3f, 0xc3, 0xd8, 0x16, 0x9f, 0xa3,
- 0x9a, 0xd8, 0x6d, 0xcb, 0x8a, 0x78, 0x11, 0xb9, 0x7d, 0xe5, 0xc2, 0x5a,
- 0xc6, 0x2f, 0x87, 0xd8, 0x5e, 0xac, 0x5c, 0x75, 0x52, 0xef, 0x27, 0x31,
- 0x42, 0xbb, 0x7e, 0x94, 0xc7, 0x81, 0x41, 0xab, 0x73, 0x39, 0x39, 0xf7,
- 0xc5, 0x01, 0xab, 0xf3, 0x06, 0xd3, 0xf0, 0x15, 0xa9, 0x81, 0xe8, 0xdd,
- 0x38, 0x89, 0xfd, 0x23, 0x52, 0x06, 0x6e, 0x6f, 0x84, 0x79, 0x75, 0xd2,
- 0xea, 0xdc, 0x61, 0x5e, 0x8c, 0x06, 0x3b, 0x37, 0xfe, 0x55, 0x79, 0x0e,
- 0x33, 0xc5, 0x8f, 0x64, 0x0d, 0x64, 0x12, 0xbf, 0x62, 0x3b, 0xef, 0x0d,
- 0x56, 0x62, 0x5a, 0xb5, 0xf8, 0xc1, 0x09, 0xbc, 0xdd, 0xff, 0x22, 0x4e,
- 0xf7, 0x5b, 0x58, 0x10, 0xb2, 0xe0, 0x0c, 0xd5, 0x99, 0x4d, 0xea, 0x65,
- 0xc4, 0x08, 0x05, 0xd7, 0xcc, 0x7d, 0x09, 0xef, 0xd0, 0xff, 0xaf, 0x9d,
- 0x6b, 0xd9, 0xb2, 0xf4, 0x61, 0xa1, 0xb5, 0xbd, 0x46, 0xfc, 0xc6, 0xb4,
- 0xf7, 0xf5, 0x7c, 0x72, 0x1e, 0x5c, 0xd8, 0xb7, 0x26, 0xb9, 0xf0, 0x49,
- 0x0c, 0x0f, 0x1a, 0xd1, 0x75, 0x05, 0x39, 0xfb, 0x4f, 0x52, 0x07, 0x16,
- 0x76, 0x98, 0x47, 0x1f, 0xae, 0xc2, 0xbc, 0x33, 0xcc, 0x1a, 0xaf, 0x98,
- 0x43, 0xdb, 0x59, 0xb0, 0x30, 0x60, 0x2e, 0x53, 0xdf, 0xa4, 0x9f, 0x9e,
- 0xc4, 0xbe, 0xa1, 0x02, 0x5e, 0xfb, 0xd0, 0x44, 0x3f, 0xcf, 0xed, 0x65,
- 0xf7, 0xa2, 0x31, 0x75, 0xc8, 0x5e, 0x7f, 0x38, 0x40, 0x7c, 0xcc, 0x3d,
- 0xd3, 0xd4, 0x30, 0x92, 0x69, 0x22, 0x36, 0x44, 0xf1, 0xcf, 0x99, 0x08,
- 0xf1, 0x21, 0x4c, 0x7c, 0x68, 0x20, 0x3e, 0x98, 0xc4, 0x87, 0x7a, 0xe2,
- 0x43, 0xd0, 0x7e, 0xd6, 0x2f, 0x6b, 0xe6, 0x43, 0xa3, 0x2f, 0xa2, 0x68,
- 0xe0, 0x04, 0x5c, 0xf4, 0x81, 0xe3, 0xa6, 0x45, 0x7e, 0x52, 0xa7, 0xad,
- 0xc1, 0xc5, 0x4a, 0x54, 0xf3, 0x62, 0x28, 0x73, 0x02, 0x25, 0x03, 0x1a,
- 0xc7, 0x22, 0xfb, 0x33, 0x6a, 0xc3, 0xbd, 0xc4, 0xea, 0x5f, 0x1b, 0x75,
- 0xbd, 0x5e, 0xd4, 0xed, 0xae, 0x81, 0xd1, 0xbf, 0x50, 0x9d, 0xab, 0x44,
- 0xbf, 0xe0, 0xe5, 0x38, 0xab, 0x31, 0xfb, 0x01, 0x0d, 0x73, 0x78, 0xfc,
- 0x53, 0xaa, 0x76, 0xe2, 0x75, 0x07, 0xbc, 0x33, 0x48, 0x77, 0x66, 0x92,
- 0x09, 0x90, 0xd5, 0x7a, 0x7d, 0xb8, 0xe4, 0xc0, 0x49, 0x55, 0x41, 0xf6,
- 0x0b, 0x12, 0xf3, 0xea, 0x82, 0x3d, 0xaa, 0x2a, 0x6b, 0x48, 0xc4, 0x70,
- 0x1e, 0x2a, 0x22, 0x64, 0x11, 0xb3, 0x98, 0x5f, 0x58, 0x6b, 0xcc, 0x12,
- 0x6c, 0xae, 0x57, 0x65, 0x6f, 0xc8, 0x21, 0x89, 0x51, 0x33, 0x18, 0x23,
- 0x4a, 0x93, 0xf1, 0xdb, 0x66, 0xc0, 0x83, 0x92, 0xa4, 0x65, 0x3d, 0x16,
- 0xd2, 0xe0, 0x89, 0x04, 0xa2, 0x1b, 0x98, 0x46, 0x7e, 0x61, 0x5e, 0x18,
- 0xd7, 0x64, 0x0e, 0x60, 0x80, 0xe3, 0x5b, 0x9e, 0x29, 0xbc, 0xe3, 0xf9,
- 0xc9, 0x7f, 0xe7, 0xde, 0x15, 0xbd, 0x64, 0xf7, 0x0c, 0x18, 0xda, 0x5d,
- 0x6a, 0xbc, 0x92, 0x1c, 0xfc, 0x00, 0xe3, 0x9e, 0x32, 0x79, 0xa3, 0x82,
- 0xd6, 0x81, 0x38, 0xa6, 0x85, 0x7e, 0xa0, 0xc4, 0xaa, 0x75, 0xbf, 0x5f,
- 0xa9, 0xc6, 0x8d, 0x0f, 0x50, 0xd7, 0x0b, 0x26, 0x68, 0x2b, 0x3e, 0x7c,
- 0x67, 0x54, 0x74, 0x5b, 0x3b, 0xb4, 0x83, 0xe3, 0x98, 0x98, 0x7b, 0x40,
- 0x70, 0xf2, 0xa0, 0x1b, 0x8e, 0x83, 0xd3, 0x99, 0x9b, 0xd6, 0xcf, 0xbd,
- 0xa4, 0xe3, 0xdf, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0xbd, 0x3f, 0xae, 0x18,
- 0xda, 0x2f, 0x95, 0x03, 0xe4, 0x6c, 0x5e, 0x3c, 0x96, 0x39, 0x4c, 0x5d,
- 0xee, 0xcf, 0xe7, 0x4b, 0xab, 0x90, 0xe8, 0x93, 0x7d, 0x81, 0x27, 0x30,
- 0x7b, 0x40, 0x6f, 0xd9, 0xaa, 0x18, 0xc1, 0x6b, 0x95, 0x13, 0x98, 0x39,
- 0x10, 0xe4, 0x5c, 0x6a, 0x58, 0x96, 0x2c, 0xe0, 0xa7, 0x60, 0xf0, 0x2a,
- 0x62, 0xb0, 0xb5, 0xf8, 0xa7, 0x66, 0x9c, 0x39, 0x8e, 0x6e, 0x3a, 0x15,
- 0xbd, 0x75, 0xae, 0x22, 0xfb, 0x80, 0x8c, 0x33, 0x6d, 0xac, 0xe3, 0x19,
- 0xa8, 0xc7, 0x57, 0x39, 0xe6, 0x66, 0xce, 0xdb, 0x8b, 0x0b, 0x2d, 0x2c,
- 0x5a, 0xa8, 0xef, 0x2e, 0x71, 0x44, 0xef, 0xaa, 0x42, 0xb6, 0xa3, 0x86,
- 0x76, 0x73, 0xc7, 0x02, 0x3d, 0xfc, 0x03, 0xe2, 0x2e, 0x71, 0x1a, 0xdd,
- 0x8c, 0x3b, 0x6b, 0x18, 0x8b, 0x4a, 0x23, 0x7a, 0x2f, 0x73, 0xd4, 0xf7,
- 0x6e, 0x75, 0x44, 0x43, 0xf2, 0x1e, 0xd1, 0xdf, 0x63, 0x31, 0xdc, 0xa1,
- 0x0a, 0xe2, 0xa0, 0x9e, 0x7d, 0x11, 0xfa, 0xee, 0xaf, 0x92, 0x93, 0xfe,
- 0x98, 0xfc, 0xae, 0xe6, 0xd2, 0x43, 0xc4, 0xa8, 0x11, 0x3c, 0x98, 0x39,
- 0x88, 0xdd, 0x99, 0x34, 0x76, 0x66, 0xb6, 0x29, 0x43, 0xf6, 0xb3, 0x45,
- 0x45, 0xde, 0x99, 0x8b, 0x56, 0x28, 0x5f, 0x46, 0x79, 0xe8, 0x5b, 0xd6,
- 0x50, 0x95, 0x8a, 0xca, 0x50, 0x10, 0xd7, 0x24, 0xe3, 0x70, 0x44, 0xde,
- 0xb5, 0xe4, 0x7d, 0xed, 0xf5, 0xe3, 0x06, 0xae, 0x4e, 0x96, 0x22, 0xb6,
- 0xc7, 0xb2, 0x7a, 0x1b, 0x9c, 0x58, 0x3b, 0x5e, 0x8f, 0x65, 0x03, 0x0f,
- 0x59, 0x73, 0x18, 0x73, 0x3e, 0xbc, 0xdc, 0x83, 0x5b, 0xf7, 0x78, 0xd0,
- 0x96, 0x8c, 0xc2, 0x17, 0x29, 0xe3, 0xef, 0x80, 0xb9, 0x04, 0xc6, 0xc4,
- 0x04, 0x8c, 0xde, 0xab, 0x1c, 0x81, 0xfd, 0x61, 0xd5, 0x83, 0xbf, 0x21,
- 0x8e, 0x2f, 0x27, 0xee, 0xc4, 0xc6, 0x2d, 0x54, 0x46, 0xbc, 0xb8, 0x8d,
- 0xf5, 0xaf, 0xe3, 0xdc, 0xbf, 0xb3, 0x68, 0x3f, 0xb1, 0x40, 0xf6, 0x42,
- 0x6a, 0xd8, 0x30, 0xee, 0xa6, 0xae, 0xdc, 0x88, 0xed, 0xab, 0xc6, 0xd5,
- 0x0f, 0xf8, 0x71, 0xeb, 0xb8, 0x07, 0x8d, 0x49, 0x6b, 0xf1, 0x01, 0x33,
- 0xbe, 0x52, 0x83, 0x81, 0xb6, 0x71, 0x2f, 0xbe, 0x92, 0xd4, 0x7d, 0xd7,
- 0x32, 0xe7, 0x1f, 0x31, 0x83, 0xf8, 0x5f, 0xe3, 0x3e, 0xdc, 0x94, 0x3c,
- 0x2a, 0x79, 0xe4, 0x12, 0x27, 0x63, 0xcf, 0xbd, 0xe3, 0xb3, 0xb0, 0x32,
- 0xa9, 0x9f, 0x99, 0x20, 0xb7, 0xeb, 0xdc, 0x67, 0xe2, 0xae, 0x71, 0x15,
- 0xad, 0x6c, 0xe7, 0xc6, 0xe4, 0x6c, 0x74, 0xec, 0x6b, 0xa0, 0x0c, 0x0b,
- 0xb1, 0x7c, 0xc0, 0x09, 0x93, 0x2c, 0x1e, 0x5f, 0x04, 0x5a, 0x06, 0x26,
- 0x98, 0xc7, 0xdd, 0x87, 0xed, 0x7d, 0x26, 0x6e, 0x1f, 0x97, 0xf3, 0x83,
- 0xf6, 0x3b, 0xae, 0xef, 0x3d, 0xbc, 0x10, 0x9f, 0x1f, 0x50, 0x89, 0x03,
- 0xc5, 0x18, 0x5a, 0xa9, 0xe0, 0x2b, 0xbc, 0xbe, 0x35, 0x25, 0x7b, 0x90,
- 0x81, 0xd0, 0x8e, 0xc0, 0xfe, 0x2a, 0x72, 0x86, 0x45, 0x0f, 0xe7, 0xae,
- 0x3f, 0x48, 0x9c, 0x2f, 0x21, 0xce, 0x97, 0x91, 0xc3, 0x5e, 0x35, 0x7c,
- 0x10, 0xf7, 0x13, 0x97, 0x0f, 0x0d, 0x74, 0x32, 0xee, 0x94, 0xe3, 0x71,
- 0xc6, 0x81, 0x24, 0xcf, 0x4f, 0xec, 0x30, 0x3a, 0x4a, 0x88, 0xd3, 0x3f,
- 0x20, 0xfe, 0xf6, 0x12, 0x33, 0xee, 0x48, 0x32, 0xdc, 0xef, 0x60, 0x0e,
- 0x70, 0x69, 0x74, 0xbe, 0x87, 0x39, 0xd6, 0xb5, 0x4a, 0xc0, 0xf7, 0x26,
- 0xca, 0xe1, 0x78, 0xb8, 0x1a, 0x8d, 0x0f, 0x48, 0x19, 0xc1, 0x2f, 0x15,
- 0xea, 0x5e, 0x27, 0x75, 0x7e, 0x18, 0x56, 0xbf, 0x83, 0xe3, 0xad, 0x35,
- 0xc9, 0xc0, 0xf1, 0x9a, 0xa9, 0x6b, 0xff, 0x4c, 0xac, 0x7d, 0x9f, 0x98,
- 0xea, 0x9f, 0xd1, 0x80, 0x26, 0xc3, 0xe4, 0x71, 0x18, 0x27, 0xfb, 0x0d,
- 0x53, 0xf6, 0xe4, 0xbd, 0x4e, 0x9e, 0x37, 0x39, 0x83, 0x31, 0xd3, 0x10,
- 0x3f, 0x1c, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x03, 0xde, 0x7e,
- 0x78, 0x31, 0xc7, 0x25, 0xb1, 0x54, 0xe2, 0xdd, 0x08, 0x65, 0x5d, 0x8c,
- 0x15, 0xd4, 0x47, 0x53, 0x52, 0x45, 0x7a, 0x5f, 0x04, 0xb7, 0xef, 0xca,
- 0xc5, 0xe1, 0x8d, 0xa1, 0xf8, 0x0d, 0x8c, 0xc3, 0xe1, 0x52, 0xc6, 0x61,
- 0x57, 0x44, 0x64, 0x73, 0x62, 0x98, 0x71, 0x7b, 0x73, 0x2a, 0x8c, 0x66,
- 0xce, 0xe1, 0x44, 0x9a, 0xfd, 0x26, 0x67, 0xe1, 0x78, 0xda, 0xc3, 0x98,
- 0xa5, 0xf1, 0x20, 0xaa, 0x8d, 0x4c, 0xe7, 0xe1, 0xe7, 0x71, 0x31, 0x0f,
- 0xc3, 0xbe, 0xb6, 0x26, 0xa9, 0x20, 0xde, 0xa2, 0xd8, 0x7c, 0xfe, 0x78,
- 0x5a, 0xb0, 0x59, 0xd6, 0x32, 0xef, 0xae, 0x94, 0x3d, 0xa8, 0xfd, 0xa9,
- 0x97, 0x50, 0x49, 0x7c, 0xaa, 0xc8, 0xe3, 0xd0, 0xcf, 0x42, 0x82, 0xbb,
- 0xb5, 0xc4, 0x5d, 0xd9, 0x4f, 0x64, 0x59, 0xab, 0x02, 0x53, 0xf1, 0xe8,
- 0xff, 0xfb, 0x30, 0x6a, 0xef, 0xab, 0x15, 0x4c, 0x22, 0xfe, 0xa5, 0x88,
- 0x7f, 0x1c, 0x43, 0xd7, 0x95, 0xc4, 0x40, 0xca, 0xf4, 0x8f, 0x29, 0x62,
- 0x20, 0x71, 0xfa, 0x20, 0x71, 0xfa, 0xdb, 0xc4, 0xe9, 0x6f, 0x11, 0xa7,
- 0x1f, 0x27, 0x26, 0xe4, 0xd6, 0xf4, 0x9a, 0xe5, 0xb9, 0x0a, 0xe7, 0xe3,
- 0x1d, 0x7b, 0x6d, 0xb1, 0x86, 0xba, 0x9a, 0x3d, 0xa0, 0x60, 0x8e, 0xa1,
- 0xef, 0x17, 0xbb, 0xff, 0x31, 0xe7, 0xc9, 0x3f, 0x2d, 0xb7, 0xe7, 0xb7,
- 0x29, 0xd9, 0x03, 0x77, 0xb2, 0x4e, 0xeb, 0x85, 0xfd, 0x0d, 0x01, 0x53,
- 0xb8, 0x68, 0x51, 0x72, 0x0d, 0x1c, 0xc9, 0xba, 0xfd, 0xc7, 0xe4, 0xf9,
- 0xed, 0x74, 0xc9, 0xeb, 0xd7, 0xc8, 0x1e, 0xed, 0xfd, 0xb2, 0x37, 0x6c,
- 0x19, 0xef, 0xb9, 0x92, 0x75, 0xe6, 0x9b, 0xb0, 0xb1, 0xcd, 0x3f, 0x69,
- 0xdf, 0xab, 0x7d, 0xef, 0x7e, 0xea, 0x2b, 0xcb, 0x36, 0xd3, 0x29, 0xd9,
- 0x17, 0x3b, 0x0b, 0x8f, 0x66, 0xe4, 0x77, 0x5d, 0x6b, 0x42, 0xdd, 0x8f,
- 0x58, 0x8d, 0xf0, 0xf1, 0x30, 0xae, 0x4f, 0x7a, 0x68, 0x07, 0x71, 0x54,
- 0xd0, 0xb7, 0xbe, 0x36, 0xde, 0x40, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81,
- 0xd6, 0x71, 0x72, 0x9e, 0xf5, 0xe3, 0x8b, 0xb1, 0x74, 0xc0, 0xb2, 0x3c,
- 0x97, 0x19, 0xe1, 0x0d, 0x8a, 0x1f, 0x2e, 0xfa, 0xa0, 0x83, 0x7e, 0xb5,
- 0x6e, 0x4f, 0x40, 0x7b, 0x93, 0x78, 0xda, 0xde, 0x70, 0x80, 0xf6, 0x61,
- 0x9c, 0x69, 0x26, 0x96, 0x3a, 0x23, 0x01, 0xe6, 0x89, 0x1e, 0xda, 0xbe,
- 0x17, 0x67, 0x12, 0xe2, 0x5f, 0x7a, 0xc7, 0x3f, 0x33, 0x37, 0xe9, 0xa0,
- 0x6f, 0xfc, 0x32, 0x31, 0x8b, 0x3e, 0xe0, 0xc6, 0xdb, 0x09, 0x83, 0xfe,
- 0xe6, 0xc1, 0x3b, 0x89, 0x7a, 0xf6, 0x15, 0x64, 0x19, 0x3f, 0xee, 0x1c,
- 0x0f, 0xd3, 0xcf, 0xae, 0xe4, 0x21, 0xef, 0x53, 0xd7, 0xc6, 0xbf, 0xa3,
- 0xd4, 0xf6, 0xcf, 0x56, 0xab, 0x10, 0xad, 0xd6, 0xf0, 0xf5, 0xf1, 0xcf,
- 0xe2, 0x3f, 0x18, 0xb7, 0xd7, 0x26, 0xc1, 0x39, 0x44, 0x88, 0x3c, 0x70,
- 0x62, 0x9f, 0x3c, 0x4b, 0x44, 0x5d, 0x74, 0xae, 0x43, 0x67, 0x6e, 0xab,
- 0x67, 0x4f, 0x3b, 0x9c, 0xec, 0x93, 0xac, 0x98, 0x65, 0x7f, 0xd9, 0x5f,
- 0x8a, 0xbb, 0xf6, 0x1c, 0xa0, 0x8f, 0x14, 0x61, 0xc1, 0xfd, 0x6e, 0x7c,
- 0x7d, 0xdf, 0x08, 0xb9, 0x83, 0x8a, 0x99, 0xcc, 0x95, 0x86, 0x48, 0x14,
- 0x66, 0x0e, 0x47, 0x70, 0xdb, 0xae, 0x11, 0x0c, 0xe4, 0x79, 0x5e, 0x28,
- 0x14, 0xff, 0x9f, 0x2a, 0x0e, 0x90, 0x47, 0x04, 0xda, 0x3f, 0x43, 0x1b,
- 0xab, 0x88, 0x04, 0xe2, 0x32, 0xee, 0x16, 0xda, 0x58, 0x0f, 0xe7, 0x33,
- 0xcd, 0x71, 0x24, 0x68, 0x63, 0x8f, 0x51, 0xfe, 0xed, 0xb4, 0xb1, 0x38,
- 0x6d, 0x2c, 0x4e, 0x7b, 0x8a, 0xd3, 0xc6, 0xe4, 0x9d, 0xfd, 0x38, 0x6d,
- 0x2c, 0x4e, 0x1b, 0x8b, 0xa7, 0x17, 0x63, 0x94, 0x4c, 0x63, 0xcb, 0x48,
- 0x03, 0x71, 0x4c, 0xb1, 0xa3, 0x52, 0xf6, 0x86, 0xcf, 0x92, 0xb3, 0x5f,
- 0xc5, 0x43, 0x41, 0x33, 0x7d, 0xb2, 0x77, 0x68, 0x84, 0x9c, 0xc7, 0x8d,
- 0xdf, 0x64, 0x84, 0xe3, 0x37, 0x30, 0x8f, 0x3d, 0x4c, 0x9e, 0xaf, 0xe2,
- 0x49, 0x53, 0xf2, 0x60, 0x93, 0xe7, 0x8c, 0x35, 0x29, 0xe1, 0x6b, 0x87,
- 0x71, 0x47, 0x3f, 0x70, 0x2d, 0x79, 0x61, 0x35, 0x79, 0xc9, 0xde, 0x05,
- 0xfc, 0xfd, 0xf0, 0x01, 0xda, 0xbc, 0xf8, 0x63, 0x6e, 0xaf, 0xeb, 0xf1,
- 0xfe, 0x5a, 0xdf, 0xd5, 0xf4, 0xc1, 0x7b, 0x59, 0xd7, 0xf9, 0xb0, 0xd4,
- 0x39, 0xc0, 0xb6, 0xf5, 0xf0, 0x6f, 0x38, 0xff, 0xad, 0xf7, 0x57, 0xe3,
- 0xed, 0x5d, 0x7a, 0xf8, 0x7d, 0x62, 0x5e, 0xb5, 0xc3, 0x5a, 0xfc, 0x99,
- 0x50, 0x60, 0xe3, 0x67, 0xd4, 0x1c, 0xdf, 0x6b, 0xd9, 0xe1, 0xc4, 0xfe,
- 0xd0, 0x62, 0x78, 0x16, 0x14, 0x38, 0x1f, 0x6d, 0xa9, 0x5a, 0x38, 0x96,
- 0x1e, 0x3e, 0x4d, 0xae, 0x92, 0x64, 0xfb, 0xa3, 0xe9, 0x23, 0xc4, 0x90,
- 0xfb, 0xf0, 0x02, 0xf3, 0xf3, 0x91, 0x4f, 0xbf, 0x4e, 0xee, 0xe8, 0xc6,
- 0x18, 0x39, 0xe0, 0x81, 0xfe, 0xe8, 0xe7, 0x9c, 0xc4, 0x7d, 0xcf, 0x82,
- 0x72, 0xa4, 0x87, 0x84, 0x2b, 0x96, 0xe3, 0xd9, 0x7e, 0x43, 0xbb, 0x56,
- 0xc9, 0xf1, 0xc2, 0x2d, 0x3c, 0x7f, 0xb3, 0xdf, 0x38, 0x33, 0x8c, 0xc0,
- 0xc4, 0x69, 0x72, 0xc3, 0xf7, 0x87, 0x24, 0x86, 0x1d, 0xa4, 0x8f, 0xfb,
- 0x11, 0x4e, 0x6a, 0x38, 0x34, 0x66, 0x60, 0x7e, 0xd2, 0x8b, 0x47, 0xc6,
- 0x82, 0xf8, 0x0c, 0x7d, 0x37, 0x43, 0x7e, 0xf8, 0xe9, 0xa4, 0xf8, 0xe2,
- 0x2c, 0x8c, 0x8f, 0xcd, 0xb2, 0xf7, 0x54, 0x7a, 0x8c, 0x5f, 0xc0, 0x53,
- 0x2d, 0x3e, 0x49, 0x6e, 0x9d, 0xd2, 0x7b, 0x63, 0x1c, 0x4f, 0xcc, 0xab,
- 0xef, 0x8f, 0x41, 0x1f, 0x02, 0xae, 0xf8, 0x70, 0xe8, 0x8b, 0x12, 0x1f,
- 0xc5, 0x1f, 0x35, 0x8c, 0x93, 0xef, 0x14, 0x13, 0x53, 0x4b, 0x23, 0xb5,
- 0xef, 0xbd, 0xac, 0xe8, 0xd9, 0xa7, 0x55, 0xcb, 0x7a, 0x69, 0xa1, 0x06,
- 0xdf, 0x3e, 0x8d, 0xdc, 0xc3, 0x64, 0xec, 0x16, 0x3f, 0xd5, 0x30, 0xe3,
- 0x81, 0x6a, 0x4c, 0x7b, 0x20, 0x89, 0xbf, 0xad, 0x8e, 0x7f, 0x6e, 0x3a,
- 0xe3, 0xfc, 0x74, 0xe2, 0x7a, 0x65, 0xf2, 0xd8, 0x0c, 0x37, 0xf9, 0xf2,
- 0x84, 0x5a, 0xd7, 0xba, 0x1f, 0xfa, 0xfe, 0x93, 0x8a, 0xee, 0x7b, 0x8c,
- 0xb1, 0xc1, 0x45, 0x1b, 0x75, 0x8c, 0x6b, 0xf4, 0xdd, 0xba, 0x43, 0xd3,
- 0x60, 0xc4, 0x2f, 0x57, 0x5d, 0x16, 0x6c, 0x79, 0xae, 0xa8, 0xcc, 0xe5,
- 0x45, 0x82, 0x3b, 0x12, 0x17, 0x1c, 0xb2, 0xff, 0x13, 0xed, 0xf4, 0x97,
- 0x15, 0x76, 0x2c, 0x3a, 0x60, 0xef, 0x8f, 0xdb, 0x30, 0x1e, 0xa7, 0x8f,
- 0x2c, 0x46, 0xd9, 0x80, 0x07, 0x5f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x15,
- 0xfd, 0xe5, 0xf6, 0x3d, 0x81, 0xf6, 0xab, 0xe9, 0x2f, 0xb5, 0x97, 0x49,
- 0x0c, 0x63, 0xdc, 0x4e, 0x19, 0xe6, 0x30, 0xb1, 0xe5, 0xa1, 0x06, 0x63,
- 0xe2, 0x75, 0xe4, 0x7c, 0x66, 0x6b, 0x5f, 0x35, 0xfe, 0xe1, 0xfe, 0xfd,
- 0xf6, 0x5a, 0xc8, 0x6d, 0x3c, 0x4f, 0xf6, 0xf9, 0x6c, 0xff, 0x88, 0xf1,
- 0xf7, 0x9d, 0x8c, 0x79, 0x31, 0xfa, 0xd1, 0x96, 0x3e, 0x6b, 0xf1, 0xf7,
- 0x17, 0xc6, 0x57, 0x56, 0x20, 0xc8, 0x98, 0xe4, 0x46, 0x6f, 0x9f, 0xde,
- 0xdf, 0xca, 0x18, 0x74, 0x62, 0xa1, 0x49, 0x59, 0x3c, 0xd8, 0xd1, 0x27,
- 0x98, 0x7a, 0xf4, 0xa6, 0x6a, 0xc4, 0xff, 0xa7, 0xc6, 0xf1, 0x7d, 0xcd,
- 0x7e, 0xf6, 0x37, 0x0b, 0x6b, 0xf7, 0x5d, 0x46, 0x99, 0xeb, 0xe9, 0x83,
- 0xcc, 0xab, 0x99, 0xef, 0xac, 0xde, 0x25, 0x7e, 0x81, 0x46, 0xc9, 0xd3,
- 0x3a, 0xcd, 0x80, 0xf9, 0x06, 0x7d, 0xa8, 0x88, 0x5c, 0xe7, 0x41, 0x62,
- 0x59, 0x31, 0x21, 0xb3, 0xcc, 0x08, 0x63, 0x21, 0x6d, 0x54, 0xde, 0xe1,
- 0x98, 0x46, 0x5e, 0x37, 0x9f, 0xf3, 0x51, 0x92, 0xf1, 0x00, 0xe4, 0x10,
- 0x20, 0x3e, 0x61, 0x94, 0x20, 0x38, 0xea, 0xe7, 0x71, 0x31, 0x0f, 0x2a,
- 0x22, 0xa3, 0xa2, 0x66, 0x94, 0x75, 0x87, 0x47, 0x6c, 0x5b, 0xfc, 0x07,
- 0xce, 0x7b, 0x82, 0xb6, 0x7e, 0x23, 0xb1, 0x7e, 0x62, 0x27, 0xd0, 0xfb,
- 0x70, 0xce, 0xb6, 0x53, 0x6c, 0xbf, 0x85, 0x98, 0xf7, 0x1e, 0x6d, 0xb6,
- 0x87, 0xf3, 0xbd, 0x63, 0xd0, 0x08, 0xd6, 0xa9, 0x01, 0x6d, 0x9c, 0xf3,
- 0xdc, 0x35, 0xa2, 0xa2, 0xaf, 0x7f, 0x31, 0x86, 0x99, 0x07, 0x75, 0x0f,
- 0x89, 0x8f, 0x48, 0x99, 0xc3, 0xe8, 0xa4, 0x8f, 0xfc, 0x6a, 0xa1, 0x82,
- 0xd8, 0x17, 0xe4, 0x1d, 0x51, 0x27, 0xf3, 0xfd, 0xfb, 0xb0, 0x36, 0x71,
- 0xc4, 0x2a, 0x37, 0xf4, 0xde, 0x21, 0x95, 0x79, 0x16, 0x6d, 0xb3, 0x8b,
- 0xf9, 0xc9, 0x12, 0xe6, 0x27, 0xdd, 0x79, 0xbb, 0x3c, 0x4e, 0x3b, 0xec,
- 0x63, 0x1c, 0x7b, 0x7d, 0x28, 0x17, 0xf7, 0x7e, 0xbc, 0xc3, 0x8f, 0xf9,
- 0x97, 0x97, 0xe3, 0x99, 0x87, 0x73, 0xb2, 0xed, 0xa4, 0x4d, 0x3e, 0x4d,
- 0x3d, 0xdf, 0x4a, 0xbd, 0xbe, 0x92, 0x12, 0x8c, 0x0a, 0xe2, 0x59, 0xf2,
- 0xe8, 0xf5, 0xe4, 0x02, 0x2f, 0xa5, 0x72, 0x36, 0xf9, 0xf5, 0xf1, 0x2b,
- 0xab, 0x72, 0xf1, 0xc1, 0x0b, 0xf5, 0x01, 0x79, 0x27, 0xcf, 0xb2, 0x96,
- 0x98, 0xd9, 0x76, 0xf2, 0x1a, 0xb6, 0x1d, 0x21, 0x37, 0x72, 0x62, 0x66,
- 0x32, 0x82, 0xa5, 0xa9, 0xda, 0xe6, 0xb9, 0xb2, 0x89, 0x63, 0x66, 0x8e,
- 0x03, 0xba, 0x92, 0xf2, 0xcd, 0x0f, 0x0d, 0x65, 0xcc, 0x9d, 0xfe, 0x26,
- 0xff, 0x9d, 0x91, 0x1b, 0xff, 0x0c, 0xee, 0xb8, 0x82, 0x32, 0xa5, 0xc8,
- 0x1d, 0x27, 0xf3, 0xdf, 0x19, 0xb9, 0xc1, 0xfe, 0xce, 0x88, 0x1b, 0xd3,
- 0xc6, 0x9d, 0xce, 0x2f, 0xa5, 0x3c, 0x98, 0x31, 0x7e, 0x96, 0x83, 0xba,
- 0x8b, 0x22, 0x4d, 0x78, 0x2a, 0xa1, 0x60, 0xba, 0xf1, 0xbf, 0xf1, 0xb2,
- 0xbd, 0x26, 0x50, 0x8d, 0x99, 0x0f, 0xc8, 0x7a, 0x42, 0x54, 0xde, 0x89,
- 0x69, 0x7e, 0x82, 0xe7, 0x25, 0xc4, 0xd3, 0x8a, 0x07, 0x14, 0x3c, 0x1d,
- 0xf0, 0xa2, 0x98, 0xbf, 0x7d, 0xe4, 0x9a, 0xce, 0x85, 0xcb, 0xad, 0xcd,
- 0xab, 0xc4, 0xbe, 0x39, 0x87, 0xfb, 0xa6, 0x55, 0x0a, 0x06, 0xee, 0x35,
- 0x65, 0xdd, 0xd2, 0x40, 0x4f, 0xa2, 0x9a, 0xfc, 0xba, 0xb6, 0xbd, 0x09,
- 0xb5, 0xe6, 0x2f, 0x1c, 0xd5, 0x28, 0xda, 0x77, 0x63, 0x95, 0xac, 0xd9,
- 0x7f, 0x9b, 0x73, 0xd6, 0x4d, 0xec, 0xea, 0x4a, 0xe5, 0xe2, 0x67, 0x53,
- 0xfa, 0x17, 0x9a, 0xe8, 0xa5, 0x9b, 0xfc, 0x44, 0x4d, 0x9e, 0xb2, 0xcb,
- 0x94, 0x45, 0x0e, 0x11, 0x7f, 0x66, 0xe1, 0x10, 0xf3, 0x1a, 0x89, 0xa5,
- 0x65, 0x3c, 0xca, 0xc9, 0x1b, 0x7f, 0xc9, 0x58, 0x7a, 0x67, 0x28, 0x1b,
- 0x94, 0x2f, 0xd0, 0x54, 0x91, 0x8b, 0xd3, 0x07, 0xb0, 0x2f, 0xa4, 0xb7,
- 0xac, 0x76, 0x44, 0x9f, 0x61, 0x0e, 0x16, 0x5e, 0xcc, 0x9c, 0x7c, 0x79,
- 0x60, 0x04, 0x5b, 0xc9, 0x03, 0xb7, 0x30, 0x17, 0x6f, 0xa5, 0x6d, 0xb6,
- 0xef, 0x62, 0x6c, 0x73, 0x9c, 0xcb, 0xc5, 0xb5, 0x50, 0x7c, 0x35, 0x39,
- 0x40, 0x87, 0x47, 0x15, 0x7b, 0x15, 0xdf, 0x09, 0xb4, 0xbe, 0x41, 0x8c,
- 0xae, 0x63, 0xdc, 0x10, 0x7b, 0xdf, 0x9e, 0xd2, 0xdb, 0xa9, 0x80, 0xaa,
- 0x72, 0xe6, 0x8e, 0x77, 0x8d, 0x35, 0xd0, 0x6f, 0xac, 0x4e, 0x37, 0xed,
- 0xda, 0xb9, 0x68, 0x16, 0x73, 0xce, 0xab, 0xd0, 0xbd, 0x83, 0xf6, 0x4f,
- 0x5f, 0xba, 0xb7, 0x0f, 0xe4, 0x67, 0xea, 0x16, 0xce, 0x5f, 0x76, 0x1f,
- 0x02, 0x67, 0x5a, 0x50, 0xd7, 0x5c, 0xe4, 0x10, 0x19, 0xf4, 0x96, 0xb7,
- 0xc9, 0xd3, 0x3a, 0x98, 0x9f, 0xae, 0x67, 0x2e, 0x1f, 0x63, 0x2e, 0x1f,
- 0x63, 0xbd, 0xd4, 0x0e, 0x79, 0x4e, 0x64, 0xb4, 0x1c, 0x67, 0xfe, 0xf3,
- 0x35, 0xf2, 0x9f, 0x1d, 0xf7, 0x8b, 0x5c, 0xd3, 0x71, 0xd7, 0xde, 0xab,
- 0x90, 0xa4, 0x3d, 0xdd, 0xc9, 0x6b, 0x7d, 0xf7, 0x5f, 0x8c, 0x3b, 0x98,
- 0xc7, 0xc7, 0xc6, 0x16, 0xa3, 0x9f, 0x99, 0xe8, 0xc6, 0xbd, 0x9f, 0x45,
- 0x17, 0xf9, 0xd4, 0x12, 0x62, 0xf4, 0xea, 0x87, 0x47, 0x6c, 0xcc, 0x16,
- 0xcc, 0x7f, 0x2d, 0x0d, 0xbc, 0x49, 0x4e, 0xd6, 0x9f, 0x3a, 0x60, 0xf3,
- 0x34, 0x17, 0xe3, 0x43, 0x31, 0x71, 0x29, 0xbc, 0xcb, 0xe8, 0x58, 0xa6,
- 0x5a, 0x8b, 0x4b, 0x16, 0x06, 0x7a, 0xdf, 0xa6, 0xaf, 0x56, 0xed, 0x53,
- 0x51, 0x3d, 0x20, 0xb9, 0x3a, 0xf9, 0x11, 0x31, 0xfa, 0x05, 0x62, 0x74,
- 0xf9, 0x9e, 0x5c, 0x5e, 0x9e, 0x60, 0xde, 0x55, 0x6d, 0xe4, 0x72, 0xf3,
- 0xed, 0x7d, 0xb2, 0xf7, 0xc6, 0x8d, 0xe7, 0x68, 0xfb, 0x47, 0xf3, 0xb6,
- 0x7f, 0x2c, 0x8f, 0xc1, 0x16, 0x73, 0xf3, 0x37, 0x6d, 0xfc, 0xcd, 0xe5,
- 0xe6, 0xf3, 0x07, 0x8c, 0x8e, 0x30, 0x31, 0xfa, 0x33, 0x7b, 0xa4, 0x7f,
- 0x0d, 0xd5, 0xc4, 0x93, 0x1a, 0x62, 0x49, 0xc5, 0x80, 0xac, 0xcf, 0x04,
- 0xda, 0xc7, 0x55, 0x9f, 0xdd, 0xc7, 0x26, 0xca, 0xd6, 0x9d, 0x92, 0x77,
- 0x6c, 0x0d, 0x6d, 0x83, 0x12, 0x30, 0xaf, 0xa1, 0x3e, 0xf7, 0xa5, 0xaf,
- 0x42, 0x7b, 0xff, 0x2c, 0xec, 0x1f, 0x92, 0xf8, 0x22, 0xed, 0x4b, 0x2e,
- 0xee, 0xc4, 0xfb, 0xbb, 0x66, 0xe3, 0xfd, 0x91, 0x73, 0x79, 0xf8, 0xe6,
- 0x54, 0xf4, 0x5e, 0x86, 0xd7, 0xe5, 0x92, 0x87, 0xbf, 0xc4, 0x3c, 0xfc,
- 0x6d, 0x45, 0xd6, 0x10, 0x55, 0xdc, 0xb8, 0xc0, 0xc1, 0xf8, 0xa2, 0xfb,
- 0x5f, 0x74, 0xc4, 0xe5, 0x39, 0xb2, 0xff, 0x7e, 0xde, 0x7f, 0x9e, 0xf1,
- 0x7c, 0x80, 0x33, 0x11, 0xad, 0x76, 0xe0, 0x99, 0x85, 0xf1, 0xa8, 0x8b,
- 0xd7, 0x7b, 0xc9, 0x53, 0x66, 0x1a, 0x07, 0xe9, 0x9b, 0xb5, 0xe1, 0xf9,
- 0x0e, 0x07, 0xce, 0x98, 0x7a, 0xcb, 0x6e, 0x5e, 0x7b, 0x36, 0x23, 0xbe,
- 0x18, 0x26, 0x7e, 0x2d, 0xca, 0xfb, 0xa2, 0xbc, 0x8f, 0x01, 0xf7, 0x6c,
- 0xda, 0xeb, 0x6b, 0x29, 0xbd, 0xff, 0x59, 0xda, 0x69, 0xf5, 0x59, 0x3b,
- 0x2d, 0xec, 0xd3, 0x82, 0xbb, 0x2a, 0xd2, 0x82, 0x50, 0xb2, 0xb0, 0x5f,
- 0x6b, 0x3f, 0x7a, 0x32, 0xf7, 0x60, 0xe3, 0x4e, 0x7d, 0xa3, 0xac, 0x11,
- 0xbd, 0x10, 0x8a, 0x5b, 0x95, 0x46, 0x27, 0x5c, 0x0b, 0x8c, 0x16, 0xe6,
- 0x2f, 0xb1, 0xef, 0x2a, 0xa5, 0xb4, 0xdf, 0xc3, 0xd8, 0x34, 0xac, 0x07,
- 0xb7, 0x2b, 0x06, 0xe3, 0x86, 0x86, 0xfd, 0x83, 0x45, 0xb8, 0x75, 0x57,
- 0x1b, 0xf6, 0xf5, 0x9b, 0xc4, 0xcf, 0x5a, 0xff, 0x69, 0xbc, 0x87, 0x63,
- 0xa6, 0xbc, 0xaf, 0x54, 0x82, 0x36, 0x4d, 0xf6, 0x29, 0x31, 0xfb, 0x9c,
- 0x7e, 0xde, 0x3b, 0xe0, 0x9e, 0x12, 0xa3, 0xf0, 0x2e, 0xbf, 0xc1, 0x7c,
- 0x71, 0x12, 0x7b, 0x06, 0x65, 0x6d, 0x60, 0x9a, 0x72, 0xa4, 0x7f, 0xae,
- 0xaf, 0x8b, 0xd8, 0x7f, 0xaf, 0x99, 0xc5, 0x99, 0x85, 0xd5, 0xc0, 0x0c,
- 0x05, 0xa1, 0xcf, 0x04, 0xe4, 0x5b, 0x35, 0xfc, 0x7b, 0xd7, 0xf2, 0x7f,
- 0x51, 0xda, 0xa9, 0xa9, 0xc8, 0xad, 0x17, 0xbc, 0x5e, 0x2d, 0xef, 0xf2,
- 0x1d, 0x49, 0xcd, 0xac, 0xcc, 0x3d, 0x77, 0xfe, 0xa4, 0x3e, 0x5e, 0xb3,
- 0xfc, 0x76, 0x1b, 0x85, 0xba, 0xaf, 0x5a, 0x51, 0xaf, 0x94, 0x2f, 0x62,
- 0xdb, 0xe2, 0x9f, 0xd3, 0x94, 0x76, 0xe2, 0xa9, 0x1a, 0x9a, 0xa6, 0xb4,
- 0x0d, 0x5d, 0xd8, 0xee, 0x8b, 0x56, 0xb4, 0x45, 0xce, 0x0b, 0xe5, 0xdc,
- 0xd3, 0x50, 0x2a, 0x65, 0x0b, 0xf7, 0x9f, 0xc9, 0xb7, 0x55, 0x4c, 0xae,
- 0x9a, 0x2b, 0x73, 0x6b, 0xbf, 0xec, 0xad, 0x8a, 0xe2, 0x68, 0xc3, 0xd4,
- 0xf6, 0x0a, 0x7d, 0x7f, 0xef, 0xbc, 0xf6, 0x72, 0x65, 0x67, 0xb1, 0x4d,
- 0x29, 0x9f, 0xc5, 0xff, 0x6b, 0xaf, 0x23, 0xbc, 0x61, 0xef, 0x93, 0xdc,
- 0x6a, 0x36, 0x46, 0x4b, 0xf0, 0x39, 0xa8, 0x97, 0xc6, 0xe7, 0x97, 0xd8,
- 0xfc, 0x36, 0xda, 0x52, 0xc2, 0x1c, 0xd7, 0x6d, 0x44, 0xef, 0x75, 0x23,
- 0x9b, 0x65, 0x5c, 0x6e, 0x3d, 0xa3, 0xec, 0x57, 0x6e, 0x0d, 0xe8, 0x1b,
- 0xdf, 0x25, 0xdf, 0x78, 0x3e, 0x10, 0x27, 0xd6, 0x1b, 0xbe, 0x3e, 0x45,
- 0x37, 0xd7, 0x32, 0xa6, 0x3d, 0xcb, 0x1c, 0x72, 0x4d, 0xa0, 0xd7, 0x7e,
- 0xc6, 0xa8, 0x44, 0x56, 0xe0, 0x12, 0xfb, 0xbb, 0x2c, 0x2d, 0x30, 0xd2,
- 0xcf, 0xcb, 0x9a, 0x17, 0x7f, 0xc7, 0x30, 0xdf, 0xbe, 0xb6, 0x06, 0x41,
- 0xfb, 0xff, 0xaa, 0xfc, 0xb7, 0x5b, 0x5a, 0x51, 0x6b, 0xff, 0xbf, 0x19,
- 0x73, 0xd3, 0x67, 0xd7, 0x86, 0xd1, 0x6d, 0x5a, 0xd6, 0x53, 0xa6, 0x85,
- 0x37, 0xce, 0xed, 0xd1, 0x5e, 0xe1, 0x60, 0xce, 0x41, 0x17, 0x8e, 0xe5,
- 0xbe, 0x5d, 0x75, 0xee, 0xfd, 0x8c, 0xa5, 0xe7, 0xed, 0xd1, 0x96, 0xf7,
- 0xe2, 0xab, 0xed, 0x6f, 0x93, 0xcd, 0x5b, 0xe4, 0xc4, 0x73, 0x89, 0x8a,
- 0x98, 0x87, 0xbf, 0x37, 0x2d, 0x2a, 0xc2, 0xfa, 0x10, 0x39, 0xdf, 0xa5,
- 0xc7, 0x71, 0xda, 0xfe, 0x46, 0x43, 0x3c, 0x24, 0xdf, 0x66, 0x38, 0x9a,
- 0x50, 0x71, 0x6c, 0xb0, 0x27, 0xb4, 0xc7, 0xee, 0xfb, 0x55, 0x74, 0x8f,
- 0xca, 0x73, 0xbf, 0x16, 0xac, 0x4e, 0x4c, 0xda, 0x7b, 0xda, 0x36, 0xa7,
- 0x24, 0xf7, 0xd6, 0xb3, 0x6b, 0x98, 0xaf, 0xaa, 0x8e, 0x20, 0x6e, 0x62,
- 0x7c, 0x79, 0x21, 0x41, 0x3b, 0x5d, 0xa8, 0x77, 0x7c, 0x97, 0x1c, 0xa1,
- 0x22, 0xa2, 0x07, 0xdf, 0x51, 0x5a, 0xc9, 0xc5, 0xdc, 0x98, 0x48, 0x88,
- 0x2d, 0xca, 0xb7, 0x9d, 0x6e, 0xc6, 0x7e, 0x72, 0xd2, 0xe7, 0x13, 0x1a,
- 0x4e, 0x37, 0x78, 0x90, 0x26, 0x47, 0x7d, 0x2e, 0xe1, 0xc6, 0x63, 0xe4,
- 0xa8, 0x8f, 0x0e, 0xca, 0x1a, 0x61, 0x13, 0x1a, 0x13, 0xb2, 0x3e, 0x4c,
- 0xde, 0x35, 0xe2, 0xa5, 0x3d, 0x5a, 0x56, 0x37, 0x6d, 0xb7, 0x4d, 0x9b,
- 0x60, 0x9f, 0xb2, 0xae, 0x18, 0xc5, 0x35, 0xe4, 0x1d, 0x8f, 0x8e, 0xf8,
- 0xf0, 0x7d, 0x72, 0xf3, 0x24, 0xeb, 0xbd, 0x90, 0xf0, 0xa3, 0x2f, 0xed,
- 0xc3, 0xd3, 0xe4, 0xe8, 0x5b, 0x78, 0x2e, 0xdf, 0x09, 0x2b, 0x32, 0x82,
- 0xe4, 0xc1, 0x87, 0x51, 0xd6, 0x77, 0x11, 0xd6, 0xad, 0x3c, 0x08, 0xb5,
- 0xef, 0x10, 0x8f, 0x2b, 0x19, 0xb3, 0xaf, 0x44, 0x6a, 0x30, 0x82, 0xd4,
- 0xc8, 0x8f, 0xd0, 0x3b, 0x28, 0xe3, 0x92, 0xef, 0x3d, 0xc9, 0xbe, 0x27,
- 0x72, 0xbd, 0x3e, 0x2f, 0x86, 0x46, 0xa4, 0x9f, 0x6a, 0xf6, 0xfd, 0xe7,
- 0xb6, 0xff, 0x1f, 0xd6, 0xba, 0x1b, 0xa5, 0xed, 0x83, 0x9f, 0xd0, 0xbe,
- 0xe8, 0xaa, 0xf0, 0x9e, 0xa1, 0xac, 0x75, 0xb8, 0xd9, 0xa6, 0x07, 0x8e,
- 0x48, 0x76, 0x65, 0x39, 0xf4, 0xe8, 0x36, 0xc5, 0x68, 0x2e, 0x53, 0x26,
- 0xb1, 0x2d, 0x23, 0xef, 0x8d, 0x15, 0xe3, 0x69, 0xe2, 0xa3, 0x2b, 0xa4,
- 0x6b, 0xdf, 0xa5, 0xed, 0x2c, 0x21, 0xa6, 0xbc, 0x61, 0x7e, 0x06, 0x71,
- 0x4d, 0xf4, 0x57, 0x8c, 0x1f, 0xf4, 0xbb, 0xf1, 0x4e, 0x28, 0x82, 0xdc,
- 0xb7, 0xbd, 0x3c, 0xf8, 0x71, 0xc2, 0xcb, 0xf9, 0xaa, 0xcb, 0x1a, 0x8e,
- 0xb9, 0xc0, 0xb4, 0xdc, 0xb5, 0xa3, 0x89, 0x35, 0xd8, 0x43, 0x79, 0x5f,
- 0x48, 0x9c, 0xe1, 0xfc, 0xb4, 0x53, 0xff, 0xa2, 0xef, 0x78, 0x5e, 0xd7,
- 0x3d, 0xd4, 0xf5, 0x2c, 0x3c, 0x9b, 0xb8, 0x0f, 0x8f, 0x52, 0xfe, 0x47,
- 0xfa, 0x8d, 0xe8, 0xc5, 0xca, 0x61, 0xe2, 0x65, 0x31, 0x8e, 0xb1, 0xed,
- 0x5b, 0x99, 0x29, 0x4f, 0x4a, 0x5f, 0x29, 0x59, 0x9f, 0x54, 0xf0, 0xce,
- 0xa2, 0xc3, 0x18, 0xe7, 0xbd, 0x1f, 0xf3, 0x77, 0x78, 0x61, 0x25, 0xfb,
- 0x10, 0xfd, 0xf8, 0xed, 0x5c, 0xa0, 0x8b, 0x3c, 0x67, 0x79, 0xc3, 0x61,
- 0x6c, 0x1d, 0x92, 0x6b, 0x6d, 0xe8, 0xed, 0x7f, 0x0f, 0x8e, 0x10, 0x71,
- 0xc8, 0xdb, 0x40, 0x5b, 0xcf, 0x62, 0x5b, 0xfa, 0xc3, 0x69, 0x39, 0x0e,
- 0xfa, 0xca, 0x34, 0xd9, 0x8b, 0x7c, 0x34, 0x51, 0x8c, 0xe7, 0x58, 0x67,
- 0x5d, 0xc8, 0x95, 0x7f, 0x66, 0x72, 0x98, 0xfc, 0xc9, 0x89, 0x34, 0xfb,
- 0x48, 0xd8, 0x6d, 0x4c, 0x53, 0x76, 0xd3, 0x0f, 0x2b, 0x17, 0x4e, 0x53,
- 0x52, 0x43, 0xc2, 0xed, 0x7f, 0x84, 0x27, 0xef, 0xcf, 0xe9, 0x70, 0x8f,
- 0xb9, 0x06, 0x43, 0xe9, 0x1f, 0x17, 0xda, 0x9b, 0xf2, 0x2e, 0x9c, 0xbc,
- 0x9f, 0x53, 0x78, 0x57, 0x27, 0xf7, 0x4c, 0xeb, 0xdb, 0x99, 0x0a, 0xf2,
- 0xe7, 0x52, 0xda, 0x5a, 0x51, 0xcc, 0xcb, 0xb8, 0xba, 0x66, 0x81, 0x86,
- 0x9d, 0x97, 0xd5, 0x4d, 0x43, 0x85, 0xe6, 0xfc, 0x75, 0xc3, 0xf3, 0xec,
- 0xa7, 0x22, 0x56, 0x15, 0xd9, 0x63, 0xef, 0x83, 0x0a, 0x5d, 0x56, 0xc3,
- 0xb8, 0x22, 0xcf, 0x86, 0x63, 0x78, 0x2b, 0x51, 0x1d, 0xab, 0x8e, 0x54,
- 0x12, 0x6f, 0x4f, 0xa3, 0x6f, 0xd8, 0x89, 0x0a, 0xf2, 0xe6, 0xf2, 0x64,
- 0x35, 0xdc, 0xf6, 0x3a, 0xde, 0x45, 0xe4, 0x2b, 0xb3, 0xc9, 0x49, 0x66,
- 0xa1, 0x92, 0xbc, 0xc4, 0x13, 0xb2, 0xac, 0x9f, 0x2d, 0xb4, 0xac, 0x4b,
- 0x78, 0x94, 0xf0, 0x38, 0x15, 0x12, 0x3f, 0x8d, 0xa2, 0xce, 0xf6, 0x57,
- 0x03, 0xf5, 0xf6, 0xff, 0x26, 0xfa, 0x7a, 0x47, 0x68, 0xfe, 0xf8, 0x7d,
- 0xa1, 0xb9, 0xe3, 0x35, 0x50, 0x07, 0xa6, 0xc3, 0xc1, 0xb6, 0xbe, 0x70,
- 0x99, 0x85, 0x26, 0xfa, 0xf0, 0x5a, 0x53, 0x78, 0xd1, 0x1a, 0xf2, 0xa2,
- 0xde, 0x90, 0x31, 0x7e, 0x10, 0x57, 0x33, 0xce, 0xb9, 0x07, 0x7c, 0xec,
- 0x47, 0x72, 0x6c, 0x67, 0x76, 0x0e, 0xf9, 0xf6, 0x67, 0x16, 0x0a, 0x47,
- 0x6a, 0x25, 0x47, 0x3a, 0x84, 0xd6, 0xf1, 0xc3, 0xb8, 0x9e, 0x65, 0x3c,
- 0xe4, 0x2a, 0xc9, 0xcc, 0x8f, 0xd0, 0x97, 0xb1, 0xb0, 0x3d, 0x94, 0xc5,
- 0xb5, 0x6c, 0xbb, 0x74, 0xa0, 0x99, 0xdc, 0x70, 0x05, 0xd6, 0x8d, 0xcb,
- 0xbb, 0x52, 0x13, 0x58, 0x3e, 0x4e, 0xce, 0x39, 0x5e, 0xf0, 0x57, 0xe1,
- 0x4b, 0x2b, 0xc8, 0x97, 0x64, 0x2d, 0x6d, 0x95, 0xbd, 0x96, 0xa6, 0xd2,
- 0x0f, 0x1b, 0x13, 0xf2, 0x9e, 0x50, 0x1c, 0xab, 0xc7, 0x05, 0xab, 0xef,
- 0x41, 0xf7, 0xb8, 0xac, 0xcd, 0x7e, 0x33, 0x74, 0xf1, 0xf8, 0xab, 0x68,
- 0x1c, 0x1f, 0x0a, 0xcd, 0x1b, 0x1f, 0xa1, 0xdc, 0x09, 0xca, 0xd6, 0x1f,
- 0xaa, 0x1d, 0x1f, 0x0c, 0x05, 0xc7, 0x77, 0x87, 0x02, 0xe3, 0x2d, 0xd8,
- 0x32, 0xbe, 0x0a, 0x9b, 0xc7, 0x37, 0x62, 0xd3, 0xb8, 0xe0, 0xfc, 0x24,
- 0x96, 0x8d, 0xbf, 0x81, 0xa5, 0xe3, 0xcf, 0xa3, 0x69, 0xfc, 0x04, 0x96,
- 0x8c, 0xff, 0x08, 0xcd, 0xe3, 0xaf, 0x70, 0x2c, 0xb2, 0xd6, 0x2b, 0xeb,
- 0xbc, 0x85, 0xe7, 0x6a, 0x53, 0xf7, 0x24, 0xcb, 0x5a, 0x86, 0x7c, 0xbf,
- 0x43, 0xe6, 0xd0, 0x85, 0x95, 0xda, 0x6b, 0xe8, 0xd9, 0x25, 0xdf, 0x24,
- 0xac, 0xd3, 0xba, 0xe5, 0xf9, 0xa3, 0xf7, 0x79, 0xd9, 0x63, 0x4f, 0x1b,
- 0x3b, 0xff, 0xbd, 0xbc, 0xc9, 0xb3, 0xcf, 0x18, 0xe5, 0x1b, 0x18, 0xf2,
- 0xec, 0x73, 0x12, 0x5d, 0x99, 0xdf, 0x5a, 0x51, 0x4d, 0xca, 0xca, 0xf7,
- 0x3f, 0xc4, 0x1e, 0x5e, 0xc3, 0x43, 0xbb, 0x26, 0xc9, 0x59, 0xb2, 0xf6,
- 0x5a, 0xcd, 0xbb, 0xf3, 0xe4, 0x9b, 0x56, 0xf2, 0xce, 0xfe, 0x6b, 0x48,
- 0x8d, 0x02, 0xe3, 0x0f, 0x8b, 0x1f, 0xae, 0xa1, 0x1f, 0x66, 0xc5, 0x27,
- 0xe3, 0xc4, 0xe4, 0xaf, 0x78, 0x70, 0x0f, 0x79, 0x49, 0x11, 0xb2, 0x23,
- 0xa5, 0x78, 0x66, 0x30, 0x6e, 0xcd, 0x31, 0x3c, 0x28, 0x8f, 0x18, 0xd9,
- 0x4b, 0x18, 0x67, 0x5f, 0xe1, 0xb5, 0x89, 0x7e, 0xf8, 0x7d, 0x46, 0xc0,
- 0x37, 0x87, 0xe7, 0xc7, 0x86, 0xb2, 0xe4, 0x14, 0x1d, 0x98, 0xe4, 0x7f,
- 0xc9, 0x41, 0x81, 0x6e, 0x0c, 0x0d, 0x89, 0x3e, 0x5b, 0xa8, 0x4f, 0xc1,
- 0x45, 0xbd, 0xa3, 0x89, 0x78, 0x68, 0x29, 0x82, 0x87, 0x2a, 0xca, 0x1e,
- 0xe8, 0xa4, 0xbf, 0xea, 0xb1, 0x9f, 0x30, 0x16, 0xf4, 0x29, 0x3f, 0xc2,
- 0x73, 0xcc, 0x19, 0x4a, 0x1f, 0x20, 0xff, 0x20, 0x56, 0x56, 0x44, 0x14,
- 0x63, 0x79, 0xe0, 0x14, 0x9e, 0x19, 0x71, 0xc2, 0x9d, 0x74, 0x62, 0x82,
- 0x38, 0xe9, 0x48, 0xca, 0xf3, 0x7a, 0x8d, 0xb2, 0xc8, 0xba, 0xd0, 0x09,
- 0x64, 0xed, 0xe7, 0x69, 0xf2, 0x3c, 0xe4, 0x45, 0xbb, 0x1f, 0x27, 0x65,
- 0xef, 0x21, 0x96, 0x76, 0xa5, 0x5e, 0x42, 0xd3, 0x90, 0x07, 0x73, 0x92,
- 0x13, 0xcc, 0x5f, 0x5e, 0x45, 0x6a, 0xd7, 0x2c, 0x7c, 0x95, 0x3c, 0x70,
- 0x66, 0xd2, 0x84, 0x46, 0xbd, 0xdd, 0x34, 0x66, 0x22, 0xba, 0x77, 0x15,
- 0x56, 0xee, 0xfd, 0x22, 0x8f, 0xe9, 0xb8, 0x7e, 0x6f, 0x3b, 0x3e, 0x3f,
- 0x16, 0x47, 0xeb, 0x58, 0x0f, 0x8f, 0x36, 0x5c, 0xb7, 0xa3, 0x12, 0xe9,
- 0x90, 0xc6, 0x9c, 0xba, 0x8d, 0x39, 0xb5, 0xf0, 0xa1, 0xd5, 0x78, 0x86,
- 0xb8, 0x13, 0x0c, 0xad, 0xc6, 0x84, 0xed, 0x8b, 0xb2, 0x97, 0x71, 0x35,
- 0x36, 0x31, 0x5f, 0x1e, 0xc6, 0x6a, 0x74, 0xf1, 0xda, 0x0e, 0x7b, 0x0e,
- 0x0e, 0x63, 0x31, 0xf3, 0xa1, 0xf7, 0x2f, 0x3f, 0x8c, 0x2b, 0xf6, 0x48,
- 0xdf, 0xa7, 0x91, 0xda, 0xb9, 0x86, 0x6d, 0x66, 0xd1, 0x32, 0xf6, 0x43,
- 0x7c, 0x7e, 0x07, 0x6e, 0xab, 0x44, 0x25, 0x9e, 0x0f, 0x05, 0x5a, 0xfb,
- 0x94, 0x1f, 0xda, 0x6d, 0x6f, 0xa2, 0x1f, 0x6f, 0x65, 0xb9, 0x47, 0xd2,
- 0x27, 0xd0, 0x9b, 0x9a, 0x3a, 0xa7, 0xf6, 0x7b, 0xed, 0x8c, 0x07, 0x2f,
- 0x63, 0xdf, 0xc8, 0x24, 0xb1, 0xf7, 0x24, 0x8f, 0x0b, 0x9f, 0x5f, 0x7b,
- 0xed, 0x7c, 0x26, 0x67, 0x37, 0x92, 0xbf, 0xc8, 0x3a, 0x70, 0x0b, 0x7c,
- 0x29, 0xe1, 0x44, 0xd9, 0xad, 0x33, 0xa1, 0x6f, 0x0c, 0xdb, 0x1c, 0xc9,
- 0x88, 0x91, 0x1b, 0xb5, 0x7c, 0x57, 0xf1, 0x90, 0x1b, 0x05, 0xb1, 0x22,
- 0xa3, 0x47, 0xaf, 0xa5, 0xbe, 0x4b, 0xee, 0x7f, 0x19, 0xce, 0xfb, 0x9d,
- 0x28, 0x4e, 0xca, 0xda, 0xc9, 0x04, 0x7a, 0x33, 0xf2, 0xfe, 0x6e, 0x56,
- 0x2f, 0x26, 0xae, 0x16, 0x25, 0xb3, 0x8c, 0xfd, 0xd9, 0xf9, 0x45, 0x90,
- 0x77, 0xf1, 0xaf, 0xc2, 0x9a, 0xfe, 0x28, 0xba, 0x4c, 0x79, 0x57, 0x27,
- 0x37, 0xfe, 0x39, 0x0d, 0x2f, 0xa3, 0x9b, 0xf1, 0xa7, 0x8d, 0x98, 0xf8,
- 0x55, 0xfb, 0x59, 0xe8, 0xcb, 0xe8, 0x19, 0x2c, 0xbc, 0xbb, 0x2e, 0x6d,
- 0x3e, 0x4f, 0xbd, 0xb9, 0xf2, 0xdf, 0xec, 0x91, 0x36, 0x75, 0xd3, 0xaf,
- 0x4e, 0xcb, 0xbd, 0x8b, 0x03, 0xfb, 0x19, 0x36, 0xed, 0xe3, 0x35, 0xf4,
- 0xee, 0x2a, 0x8c, 0x99, 0xb9, 0x41, 0xe0, 0x35, 0xf4, 0x8f, 0xca, 0xd8,
- 0xaf, 0x9f, 0x96, 0x7b, 0xc7, 0x78, 0xaa, 0x3e, 0x0a, 0x75, 0x1d, 0xb4,
- 0xe7, 0xc2, 0xfd, 0x8f, 0xfb, 0x6e, 0xd0, 0xa7, 0xec, 0x6f, 0xf0, 0xe4,
- 0xbe, 0x81, 0x04, 0x3c, 0x99, 0x90, 0x77, 0xfb, 0xd5, 0xc5, 0x2e, 0xa8,
- 0x5e, 0x17, 0x8a, 0x19, 0x2f, 0x6a, 0xd0, 0xed, 0xb5, 0x70, 0x35, 0xc7,
- 0xb2, 0xbf, 0xfe, 0x3a, 0x66, 0x1a, 0xf1, 0x56, 0x97, 0xfd, 0xce, 0xe1,
- 0x8a, 0xbf, 0xfe, 0xe8, 0x3b, 0x87, 0x6f, 0x10, 0x67, 0x15, 0x94, 0x1b,
- 0x37, 0xe1, 0x05, 0x3b, 0xa6, 0x28, 0x28, 0x9b, 0x2b, 0xeb, 0x98, 0x7e,
- 0x3c, 0x6b, 0xd4, 0xf9, 0xab, 0xe4, 0xf9, 0x94, 0x72, 0xca, 0x92, 0x6f,
- 0x06, 0x6c, 0xcb, 0xfc, 0xb1, 0x3d, 0xf1, 0x4f, 0x61, 0xcb, 0xce, 0x30,
- 0xe4, 0xfd, 0x15, 0xa7, 0xa1, 0x79, 0x73, 0xfc, 0x4a, 0x64, 0x93, 0xbd,
- 0xe4, 0xb7, 0x12, 0x9c, 0xde, 0xa0, 0x9f, 0xbe, 0x21, 0x7b, 0xa6, 0xc8,
- 0x99, 0xfe, 0x12, 0xc1, 0xaa, 0xc2, 0x38, 0x65, 0xaf, 0xa9, 0x92, 0x1b,
- 0xab, 0x5d, 0x47, 0xca, 0x4a, 0xbd, 0x37, 0xec, 0x35, 0x5c, 0x97, 0xf1,
- 0x5b, 0xeb, 0x4d, 0x6f, 0x35, 0xcb, 0x1e, 0xce, 0xdf, 0x9f, 0x14, 0x9f,
- 0x33, 0xe5, 0x1b, 0x56, 0x4e, 0xbb, 0x8e, 0xe8, 0xf7, 0x5c, 0x9d, 0xee,
- 0x94, 0x83, 0xb8, 0x79, 0xc2, 0xea, 0xf4, 0xca, 0x18, 0xee, 0xbc, 0xa0,
- 0x8e, 0xac, 0x2b, 0x68, 0xd2, 0x6f, 0x58, 0xc6, 0xdc, 0x95, 0xf9, 0x68,
- 0x9f, 0xb2, 0xde, 0x5b, 0x64, 0x94, 0xe1, 0x54, 0x55, 0x6e, 0x1d, 0xe6,
- 0x9c, 0x8c, 0x3d, 0x35, 0xb2, 0x4f, 0xaf, 0xd8, 0x3e, 0xb7, 0xfb, 0x35,
- 0xcf, 0xd5, 0xfb, 0xbb, 0xfc, 0x78, 0xab, 0xed, 0x77, 0x86, 0x1e, 0xb4,
- 0x79, 0x91, 0x63, 0xca, 0xb8, 0x4b, 0x6a, 0xce, 0xef, 0xe7, 0x2b, 0xf9,
- 0x7e, 0x45, 0x1e, 0xef, 0x94, 0x3e, 0x44, 0xae, 0x87, 0xf3, 0x75, 0xf4,
- 0x70, 0xd4, 0xee, 0x5f, 0x65, 0xbe, 0x55, 0xe8, 0x93, 0xfe, 0xb8, 0xb0,
- 0xd0, 0x46, 0x56, 0xec, 0xb3, 0xb3, 0x98, 0xb1, 0xed, 0x54, 0xc3, 0x3d,
- 0xd8, 0x94, 0x10, 0x3d, 0xcb, 0xb7, 0x60, 0x89, 0xe1, 0x36, 0x57, 0x73,
- 0xd1, 0x5f, 0x2f, 0xc3, 0x90, 0x16, 0xc7, 0x9e, 0x7a, 0x79, 0x47, 0xce,
- 0x45, 0x9f, 0x88, 0xa3, 0xc4, 0x28, 0x96, 0xfd, 0xc7, 0xf6, 0x1e, 0x94,
- 0x7d, 0xa6, 0x1e, 0x7d, 0x52, 0xbe, 0x55, 0x76, 0xa9, 0xbd, 0x5e, 0xd5,
- 0x3c, 0x04, 0xb9, 0x6e, 0xe2, 0xda, 0xf3, 0xf2, 0xfe, 0x12, 0xda, 0x8e,
- 0xbd, 0x27, 0xda, 0x94, 0x77, 0xe8, 0xfa, 0x12, 0xf2, 0x2e, 0x57, 0x5d,
- 0x8c, 0xfc, 0x12, 0x2f, 0xa4, 0x65, 0xbf, 0xc2, 0xef, 0xac, 0x78, 0x8d,
- 0xec, 0x8b, 0x9c, 0x5a, 0xa7, 0x88, 0xb8, 0x16, 0x08, 0x57, 0x28, 0x85,
- 0xf7, 0xb9, 0xce, 0xfd, 0x5d, 0x4f, 0x9b, 0x39, 0x6d, 0xbf, 0x83, 0x27,
- 0x67, 0x11, 0x34, 0xa6, 0xe4, 0x9b, 0xa7, 0xfa, 0xc4, 0x72, 0xd4, 0x65,
- 0x6b, 0x1d, 0xce, 0x3c, 0x7f, 0x09, 0x63, 0x05, 0xed, 0x66, 0x73, 0x20,
- 0x6c, 0xbf, 0x6b, 0xb6, 0x2c, 0x55, 0x1b, 0x7c, 0x04, 0x7a, 0xfb, 0xdb,
- 0x2c, 0x7f, 0x5d, 0xe6, 0xfb, 0xd6, 0x90, 0x57, 0xc6, 0x54, 0xc0, 0x88,
- 0x13, 0xf4, 0x0d, 0xea, 0x31, 0x22, 0xfe, 0xe1, 0x41, 0x55, 0x24, 0x4c,
- 0x3f, 0x96, 0xf8, 0x2f, 0xef, 0xa9, 0xe9, 0xbb, 0xe3, 0x30, 0xd1, 0xc8,
- 0x1c, 0xdd, 0x65, 0xef, 0x73, 0xd6, 0xfd, 0x2b, 0x19, 0x87, 0x8e, 0x9c,
- 0xdd, 0x13, 0x20, 0x7c, 0xe1, 0xc7, 0x35, 0xf9, 0xbd, 0xd0, 0xee, 0x39,
- 0x8c, 0x8f, 0x96, 0xfd, 0x9c, 0x7f, 0x8d, 0x8d, 0x2d, 0x9a, 0xa1, 0xef,
- 0xff, 0x95, 0xa3, 0x13, 0x4f, 0x2c, 0x30, 0x3a, 0x0e, 0xa8, 0xd9, 0x21,
- 0x1f, 0x71, 0xe6, 0x4a, 0x47, 0x74, 0x07, 0xff, 0xfb, 0x5f, 0xb4, 0xbf,
- 0xa1, 0x22, 0x75, 0xf5, 0xe0, 0x2a, 0x55, 0xf6, 0x0f, 0xb5, 0x60, 0xac,
- 0x4f, 0xde, 0x7d, 0xd0, 0x5b, 0xbf, 0xad, 0x74, 0x62, 0x43, 0xc8, 0x68,
- 0xd9, 0xa8, 0xe8, 0xcd, 0x7f, 0xaf, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0x82,
- 0xb2, 0xb6, 0x77, 0x36, 0xf6, 0xba, 0xd8, 0xc7, 0xde, 0x84, 0x1e, 0x9e,
- 0xc6, 0xb2, 0xa7, 0x4c, 0xc3, 0xf7, 0x1e, 0xdb, 0xfc, 0x09, 0x8f, 0x1d,
- 0xf6, 0x3b, 0xec, 0x52, 0x3e, 0x3a, 0xdf, 0x65, 0x7f, 0x8f, 0xb8, 0x95,
- 0x31, 0x45, 0xbe, 0x35, 0x1c, 0x83, 0x96, 0x9c, 0x45, 0x13, 0xd3, 0x7b,
- 0x6f, 0x80, 0xe4, 0xc0, 0x37, 0x4f, 0x47, 0xa9, 0x07, 0xde, 0x48, 0x27,
- 0xe6, 0x2e, 0x30, 0x7c, 0x8b, 0x54, 0xbb, 0x7e, 0x30, 0xaa, 0x4a, 0x7d,
- 0xdd, 0x3f, 0x08, 0x69, 0x23, 0x6b, 0x69, 0x73, 0x2b, 0xed, 0x3a, 0x0b,
- 0xd4, 0xcf, 0xc1, 0xf5, 0xe9, 0x5f, 0xcb, 0x37, 0x8b, 0xb4, 0x6a, 0x43,
- 0xea, 0xc4, 0x77, 0x68, 0xf8, 0x63, 0xf5, 0x04, 0x57, 0x7e, 0x65, 0x61,
- 0xba, 0xd4, 0x93, 0x3d, 0x66, 0x37, 0xe3, 0x76, 0xfb, 0xbb, 0x2b, 0xe2,
- 0x8f, 0x7a, 0xf4, 0x6e, 0x72, 0xd5, 0x52, 0x45, 0x78, 0xaa, 0xc4, 0xa2,
- 0x36, 0xe2, 0x61, 0x27, 0xb4, 0x90, 0xde, 0x7b, 0x91, 0xea, 0x41, 0x71,
- 0x64, 0x54, 0xf6, 0xd9, 0xec, 0x9e, 0xa7, 0xe6, 0xf6, 0xe3, 0xc4, 0xd8,
- 0xee, 0x91, 0x3f, 0xfa, 0xdc, 0x97, 0x7d, 0x95, 0x9a, 0xf2, 0xce, 0x8e,
- 0xfd, 0x9e, 0x48, 0x5b, 0xc2, 0x91, 0xdf, 0x5f, 0x58, 0x98, 0x5b, 0x0d,
- 0x6b, 0x98, 0x17, 0xac, 0x95, 0x6f, 0x63, 0x72, 0xac, 0xeb, 0x12, 0xb2,
- 0x0a, 0xf5, 0x7f, 0x01, 0x28, 0xfc, 0xfc, 0x40, 0x38, 0x5a, 0x00, 0x00,
- 0x00 };
+ 0x9d, 0xbc, 0x0d, 0x7c, 0x1b, 0xe5, 0x95, 0x2e, 0xfe, 0xcc, 0x48, 0xb2,
+ 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x92, 0x28, 0xac, 0x37, 0xd1, 0xc4, 0x23,
+ 0x47, 0xc1, 0xa6, 0x8c, 0x12, 0x27, 0xa8, 0xac, 0x4a, 0x54, 0xc7, 0x24,
+ 0x4e, 0x48, 0xc1, 0x29, 0x69, 0x6b, 0xb8, 0x2d, 0xa8, 0xf9, 0xc2, 0x84,
+ 0x40, 0x43, 0xcb, 0xde, 0x6b, 0xee, 0xed, 0xae, 0x55, 0xdb, 0x49, 0x9c,
+ 0x44, 0x96, 0x6c, 0xc7, 0x24, 0xa1, 0xdb, 0xff, 0xa2, 0xc4, 0xce, 0x07,
+ 0x54, 0xb6, 0xd2, 0x96, 0xee, 0x86, 0xde, 0x74, 0xd1, 0x4d, 0x02, 0x18,
+ 0xca, 0x47, 0xda, 0xe5, 0x76, 0x69, 0x7f, 0xbd, 0xc5, 0x97, 0x42, 0x08,
+ 0x5b, 0x0a, 0xe9, 0xe7, 0x86, 0x7e, 0x30, 0xf7, 0x39, 0x23, 0x29, 0x31,
+ 0x2c, 0xdb, 0x76, 0xff, 0xfa, 0xfd, 0xe6, 0x27, 0xcd, 0xe8, 0xfd, 0x38,
+ 0xef, 0x79, 0xcf, 0x79, 0xce, 0x73, 0xde, 0x79, 0x67, 0xfc, 0x40, 0x39,
+ 0x0a, 0x9f, 0x4a, 0x1e, 0x1f, 0x6a, 0xde, 0xb6, 0x61, 0x69, 0xe8, 0x43,
+ 0x4b, 0xe5, 0xdc, 0xa9, 0x95, 0x38, 0xf1, 0x67, 0x7e, 0xfc, 0x7f, 0x6e,
+ 0xc1, 0xc2, 0x47, 0xe1, 0xd1, 0x58, 0xf8, 0xed, 0x00, 0xb4, 0x62, 0xff,
+ 0x72, 0xc0, 0xad, 0x46, 0xc6, 0x3a, 0x5a, 0x0c, 0xb8, 0x1d, 0x91, 0x6d,
+ 0xb7, 0x6f, 0x30, 0x80, 0x68, 0xa6, 0xd1, 0xbf, 0x1c, 0x7f, 0xb0, 0xe2,
+ 0x5e, 0x27, 0xe4, 0xfa, 0x5f, 0x46, 0x7e, 0xdf, 0xfd, 0xed, 0x6b, 0xf4,
+ 0x0b, 0x69, 0x07, 0xdc, 0x5a, 0x24, 0x0e, 0xad, 0x01, 0xee, 0x3a, 0xd6,
+ 0xf9, 0xca, 0x82, 0xaf, 0x28, 0xa8, 0x2a, 0xb6, 0x75, 0xde, 0xfa, 0xf6,
+ 0x02, 0x5f, 0xac, 0x2c, 0xa2, 0xe1, 0xf1, 0x2c, 0xda, 0x9b, 0x06, 0xba,
+ 0xad, 0x4a, 0x23, 0x04, 0xb7, 0x61, 0x74, 0x0c, 0x28, 0x9e, 0xf0, 0x96,
+ 0x25, 0xf0, 0x94, 0x1a, 0x88, 0x5f, 0x11, 0x41, 0xfb, 0x95, 0xe3, 0xe5,
+ 0x71, 0x67, 0xc4, 0x8d, 0xb6, 0xac, 0x3b, 0xfe, 0x17, 0x11, 0x03, 0x2b,
+ 0xb3, 0x46, 0x19, 0xaa, 0x34, 0xf4, 0x65, 0x5f, 0x77, 0xe7, 0xdb, 0x6b,
+ 0x2e, 0x7c, 0xdf, 0x56, 0x9b, 0xff, 0x9e, 0x15, 0x73, 0x46, 0x80, 0xed,
+ 0x09, 0xcb, 0x2a, 0x89, 0xdc, 0x7c, 0xb3, 0x1a, 0x31, 0x7c, 0x47, 0xb0,
+ 0x0c, 0xeb, 0x35, 0x7c, 0x71, 0x47, 0xf3, 0x2f, 0x94, 0x53, 0x23, 0x4d,
+ 0x88, 0x1f, 0x75, 0x20, 0xaa, 0x3d, 0xcb, 0xef, 0xb9, 0x73, 0x3b, 0xc2,
+ 0x4d, 0x38, 0x70, 0xf4, 0x22, 0xaf, 0x3b, 0xed, 0x6b, 0xbd, 0xfb, 0xe7,
+ 0xce, 0xbd, 0x25, 0xfc, 0x2c, 0x1e, 0x3c, 0x2a, 0xbf, 0xef, 0x40, 0x77,
+ 0x93, 0x82, 0xa9, 0x9b, 0x37, 0xc3, 0x61, 0x34, 0xa1, 0x6f, 0xbf, 0xe2,
+ 0xec, 0x69, 0x52, 0x11, 0xf5, 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20,
+ 0x56, 0x1a, 0x09, 0x3b, 0xdf, 0x48, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1,
+ 0xd0, 0x6c, 0x38, 0x6a, 0x2c, 0xeb, 0x31, 0xd3, 0x03, 0xff, 0xa7, 0x9e,
+ 0x47, 0x7c, 0xb4, 0x1d, 0xaa, 0xf1, 0x3c, 0x7a, 0x46, 0x9f, 0xc7, 0x43,
+ 0x7b, 0xcb, 0x31, 0x35, 0x83, 0xe3, 0x4d, 0xf9, 0xf0, 0xed, 0x05, 0xd2,
+ 0xb7, 0xc8, 0xd1, 0xcc, 0xc3, 0x8d, 0x29, 0xc7, 0x39, 0x7e, 0x4b, 0x99,
+ 0x8b, 0xd6, 0xd4, 0xec, 0xcb, 0x65, 0xb6, 0xb3, 0x4c, 0xdf, 0xfb, 0xca,
+ 0xc4, 0x47, 0x23, 0xf8, 0x4e, 0x42, 0xc1, 0x96, 0x50, 0x15, 0xa2, 0x35,
+ 0x32, 0x5e, 0xcb, 0x3a, 0x6a, 0x9e, 0xb3, 0xa6, 0x34, 0xe9, 0x6b, 0x12,
+ 0xcf, 0xf2, 0xbf, 0x1d, 0xa1, 0x57, 0xad, 0x9c, 0x57, 0xda, 0xfb, 0x3c,
+ 0x6d, 0x68, 0x2d, 0xaf, 0x3b, 0x91, 0x4a, 0x20, 0x56, 0x15, 0xf9, 0x04,
+ 0xcf, 0x75, 0xf3, 0x2d, 0xc5, 0xed, 0x7e, 0x3b, 0xe1, 0xfe, 0x54, 0xa5,
+ 0xa1, 0xde, 0x57, 0x0d, 0x27, 0x9e, 0xa3, 0xcc, 0x27, 0xcc, 0xcd, 0x70,
+ 0x19, 0x5f, 0x10, 0x9b, 0xe3, 0xb8, 0x5e, 0xb4, 0x30, 0xbb, 0x58, 0x5f,
+ 0xda, 0xd5, 0xb0, 0x23, 0x65, 0x59, 0xbb, 0xcc, 0xe8, 0x87, 0xcb, 0x68,
+ 0x10, 0xa7, 0x13, 0xed, 0x70, 0x47, 0x02, 0xfe, 0xf3, 0x08, 0x63, 0x79,
+ 0xd6, 0x8b, 0x27, 0x12, 0x70, 0xb6, 0x2c, 0xa8, 0x43, 0x4f, 0x36, 0x82,
+ 0xeb, 0xb3, 0x26, 0x5a, 0xb3, 0x7f, 0xda, 0xca, 0x6e, 0x48, 0xf9, 0x39,
+ 0x86, 0x3f, 0x58, 0xf9, 0x31, 0xc8, 0xf8, 0xe4, 0x9b, 0xf3, 0x9a, 0xba,
+ 0x02, 0xbb, 0x47, 0x0c, 0xec, 0xe4, 0xfc, 0xad, 0x0a, 0xe5, 0xa2, 0x65,
+ 0xd0, 0xcd, 0xf3, 0x88, 0x60, 0x45, 0xd6, 0xe0, 0x9c, 0x46, 0xb0, 0x3c,
+ 0x55, 0xaf, 0x8d, 0x62, 0x21, 0xa2, 0xbe, 0xbc, 0x6d, 0xef, 0xe1, 0x78,
+ 0xd7, 0x07, 0xda, 0x51, 0x49, 0x1b, 0xc9, 0x2c, 0x09, 0xa3, 0x85, 0xfd,
+ 0xaf, 0xf9, 0x33, 0xfa, 0xbf, 0x89, 0xfd, 0xbf, 0xc5, 0xfe, 0x73, 0x76,
+ 0xff, 0x70, 0xae, 0xe6, 0xb9, 0x9b, 0xf6, 0xb8, 0x3b, 0xe3, 0x74, 0xae,
+ 0x4a, 0x79, 0xb1, 0x2b, 0x63, 0xd2, 0xe6, 0xe4, 0x2f, 0x1f, 0x76, 0x8c,
+ 0xd4, 0x61, 0xe7, 0x88, 0xee, 0x7b, 0x8a, 0xbf, 0x7b, 0xc7, 0xae, 0xc0,
+ 0xf6, 0x11, 0x05, 0x87, 0x8c, 0x2b, 0xd0, 0xc3, 0xdf, 0x07, 0x46, 0xe6,
+ 0xe2, 0xc1, 0x11, 0x07, 0xc2, 0x33, 0xa6, 0x8f, 0x43, 0xbe, 0xaf, 0x40,
+ 0x7c, 0xcc, 0x8f, 0x9e, 0xc4, 0xb3, 0xb6, 0x0e, 0x2b, 0x23, 0xdf, 0x2e,
+ 0xfa, 0x33, 0x7d, 0xc7, 0x8f, 0x0d, 0x09, 0x1f, 0x7a, 0x52, 0xe2, 0x07,
+ 0x6e, 0xda, 0xa6, 0xf8, 0xc1, 0xaf, 0x80, 0x2a, 0xb6, 0x9f, 0x2d, 0xfe,
+ 0xaf, 0xc0, 0xc9, 0x79, 0xdb, 0xc8, 0xff, 0x76, 0xa5, 0xc4, 0x26, 0xa4,
+ 0x4d, 0xb1, 0x0b, 0xf9, 0x5d, 0x4b, 0xbb, 0x2b, 0x87, 0xff, 0x70, 0x39,
+ 0x82, 0x0f, 0x68, 0x78, 0xad, 0x59, 0xae, 0xd3, 0xde, 0x43, 0x52, 0x66,
+ 0x10, 0x47, 0x32, 0xe2, 0xa7, 0x7e, 0xb4, 0x24, 0x26, 0xd9, 0x7e, 0x33,
+ 0xdb, 0x36, 0xf1, 0x4f, 0xd9, 0x26, 0xfc, 0x63, 0x36, 0x88, 0x7f, 0xa0,
+ 0x1e, 0xbf, 0x99, 0xf5, 0xe3, 0xd1, 0x6c, 0x1d, 0xbe, 0x91, 0xf5, 0xe1,
+ 0xeb, 0x9c, 0xbf, 0xaf, 0x65, 0xdb, 0x69, 0xfb, 0x1a, 0x8e, 0x67, 0x45,
+ 0xff, 0x25, 0x1c, 0x6f, 0x39, 0x7a, 0x47, 0xea, 0x83, 0xa7, 0x69, 0x5b,
+ 0xff, 0x60, 0xae, 0x46, 0xae, 0xb6, 0xd9, 0xb6, 0xc9, 0x5d, 0xbc, 0xbe,
+ 0x7b, 0xa4, 0x3e, 0x7a, 0xa5, 0x62, 0x59, 0x6a, 0xa8, 0x31, 0x7c, 0x4a,
+ 0x55, 0x31, 0xe5, 0xd5, 0xfd, 0x39, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82,
+ 0xbe, 0x11, 0x9f, 0xa9, 0xa7, 0xe3, 0xb4, 0x29, 0xaf, 0x31, 0xca, 0xf1,
+ 0xe8, 0xfe, 0xb8, 0xaa, 0x61, 0x67, 0x4a, 0x3f, 0x10, 0x57, 0xbd, 0x88,
+ 0x67, 0xcb, 0xf1, 0xb3, 0x11, 0xbd, 0x3f, 0xae, 0xde, 0x88, 0x78, 0xad,
+ 0x65, 0x7d, 0x3d, 0x84, 0x6d, 0xb3, 0x23, 0x88, 0xce, 0x8c, 0x20, 0x36,
+ 0x37, 0x52, 0x87, 0x54, 0x0a, 0x78, 0x6b, 0xc0, 0xf0, 0xfd, 0x8b, 0xd2,
+ 0x8e, 0xbf, 0x6e, 0xd7, 0xfd, 0x7e, 0xb5, 0x31, 0x3e, 0xaa, 0x2e, 0xa1,
+ 0x4b, 0xc3, 0xef, 0x8b, 0xac, 0x44, 0x97, 0x7d, 0x4d, 0x81, 0x66, 0x78,
+ 0xd1, 0x9b, 0xfa, 0x30, 0x62, 0xde, 0xfa, 0x8e, 0x21, 0xb5, 0xfe, 0xa2,
+ 0xa9, 0xea, 0x93, 0xed, 0xaa, 0x65, 0xfd, 0x7c, 0xf1, 0x5b, 0x96, 0x7f,
+ 0x96, 0x65, 0x2d, 0x5a, 0x2c, 0x7d, 0xfa, 0x51, 0x13, 0x31, 0xb1, 0xd6,
+ 0x9e, 0xc3, 0x72, 0x9c, 0x1b, 0xa9, 0x65, 0x1f, 0x1a, 0xfe, 0xf7, 0x35,
+ 0x7a, 0x70, 0xb3, 0x5a, 0x8e, 0xd7, 0xc6, 0xca, 0xf1, 0x0a, 0xc7, 0xf3,
+ 0x8b, 0x11, 0x1f, 0x7e, 0x35, 0x62, 0x59, 0x9f, 0x32, 0xff, 0x0a, 0xc3,
+ 0xb5, 0x83, 0xf8, 0xc7, 0x09, 0x2f, 0x7e, 0x96, 0xd0, 0xf0, 0x6a, 0x22,
+ 0x7a, 0xef, 0x0c, 0xe8, 0xd1, 0x09, 0xe5, 0xf4, 0xed, 0x55, 0x68, 0x6c,
+ 0xaf, 0x52, 0xf4, 0xb6, 0x3d, 0xd0, 0x7d, 0x57, 0x2a, 0x5e, 0x9c, 0xcf,
+ 0x68, 0xf8, 0x49, 0xa6, 0x3e, 0xfc, 0xcf, 0xec, 0xf3, 0x37, 0xe6, 0x63,
+ 0x56, 0x6e, 0x96, 0xe8, 0x4d, 0x74, 0x44, 0x3d, 0xa7, 0xa8, 0xe7, 0x14,
+ 0xf5, 0x9c, 0xa2, 0x9e, 0x29, 0xc3, 0xa3, 0x29, 0xea, 0x99, 0xba, 0xfb,
+ 0x3a, 0x6d, 0xea, 0x6b, 0x9c, 0xc7, 0xe3, 0xf6, 0x3c, 0x86, 0x39, 0x5f,
+ 0x7f, 0x81, 0xbf, 0xb5, 0xb1, 0xf5, 0x59, 0xeb, 0xbf, 0x79, 0x65, 0x4c,
+ 0x0f, 0xcf, 0xcc, 0xe3, 0x97, 0x8c, 0xed, 0x3b, 0x56, 0x4c, 0x93, 0x71,
+ 0xc9, 0xf8, 0x6c, 0xfd, 0xf9, 0xb7, 0x29, 0x3b, 0x15, 0x94, 0x5b, 0xd6,
+ 0x5e, 0xb3, 0xf0, 0xbf, 0xb7, 0x38, 0xbe, 0x9b, 0x95, 0xbc, 0x5d, 0xfd,
+ 0x5d, 0x29, 0xf5, 0x1d, 0x8c, 0xaa, 0x2b, 0x79, 0xae, 0xc7, 0xa3, 0xf8,
+ 0xa8, 0xe3, 0xbd, 0xe7, 0xf7, 0x7a, 0x65, 0x3e, 0xfc, 0x97, 0xce, 0x69,
+ 0x8f, 0x76, 0x7f, 0x77, 0xf2, 0x5c, 0xc6, 0x22, 0xb6, 0x28, 0x36, 0xe0,
+ 0xa5, 0xbd, 0x5c, 0x53, 0xf8, 0x0f, 0x71, 0x35, 0xb2, 0x0d, 0xed, 0xcd,
+ 0x8f, 0xd8, 0x7d, 0x94, 0x24, 0xc5, 0x6f, 0x14, 0xbc, 0xf5, 0x61, 0x05,
+ 0xa7, 0x42, 0x06, 0x6d, 0xe6, 0x18, 0x71, 0x01, 0x28, 0x4d, 0xc2, 0xed,
+ 0x89, 0x44, 0x90, 0x18, 0x80, 0xbb, 0x2c, 0x12, 0xc6, 0xc2, 0x81, 0xfa,
+ 0xce, 0x73, 0xd0, 0x83, 0x03, 0x8a, 0xde, 0xce, 0x58, 0x62, 0x8e, 0x53,
+ 0x8f, 0x57, 0x2a, 0xba, 0xbf, 0x44, 0x81, 0x5b, 0x61, 0xb9, 0x40, 0xe6,
+ 0x18, 0x76, 0x66, 0xe5, 0x77, 0x18, 0x46, 0xe6, 0x37, 0xc5, 0xbe, 0x24,
+ 0xa6, 0xd0, 0xee, 0xcf, 0x71, 0xec, 0xba, 0x9f, 0xf8, 0xea, 0x76, 0x45,
+ 0x3a, 0x71, 0x38, 0x01, 0x77, 0x49, 0x64, 0x2b, 0x9e, 0x4c, 0x84, 0x67,
+ 0x16, 0xcb, 0x29, 0x2c, 0xe7, 0xcf, 0x4c, 0x97, 0xe5, 0xc7, 0x56, 0xd4,
+ 0x9b, 0x97, 0xa5, 0x3c, 0x79, 0x0c, 0x7b, 0x52, 0x52, 0x37, 0x62, 0xd7,
+ 0x75, 0xb2, 0x8f, 0xbe, 0x44, 0x7d, 0xdb, 0x0d, 0x8a, 0x1e, 0x7e, 0x98,
+ 0xf3, 0xd7, 0x83, 0xc6, 0xe8, 0x1b, 0xd0, 0xb5, 0x4e, 0xe4, 0x65, 0x59,
+ 0x90, 0xc9, 0xcb, 0x31, 0x3f, 0x03, 0xe5, 0xf6, 0x14, 0xac, 0x39, 0x06,
+ 0x3c, 0x3e, 0xc3, 0xf0, 0xbf, 0xe3, 0xa8, 0xc5, 0x01, 0xce, 0x4f, 0x1f,
+ 0x7d, 0x45, 0xf0, 0xec, 0xee, 0xbd, 0x7e, 0x78, 0x0c, 0x0b, 0x47, 0x42,
+ 0xb5, 0x78, 0x96, 0x58, 0x5b, 0x45, 0xdf, 0x7c, 0x5e, 0x43, 0x74, 0x4e,
+ 0x24, 0xac, 0xdc, 0x92, 0x1d, 0x2d, 0xcc, 0xc1, 0x8b, 0x35, 0x05, 0x19,
+ 0xdf, 0x77, 0xbd, 0x5a, 0xf9, 0xe0, 0xeb, 0x50, 0x3a, 0x52, 0x7a, 0x30,
+ 0x0e, 0x0b, 0xd5, 0x8b, 0x75, 0xff, 0x94, 0xf2, 0x96, 0x8a, 0x2a, 0x62,
+ 0x75, 0xf6, 0xfd, 0xe5, 0x1a, 0xb5, 0x31, 0xc6, 0x65, 0x07, 0x43, 0x5f,
+ 0x54, 0xd3, 0x4d, 0x36, 0x13, 0x74, 0xd9, 0xd7, 0x1c, 0x48, 0x3b, 0xa3,
+ 0x3e, 0x07, 0x7e, 0x6f, 0x45, 0xd7, 0xc9, 0xb5, 0x72, 0xc4, 0xda, 0x1b,
+ 0x7d, 0x4e, 0x34, 0x86, 0xb7, 0xd3, 0x07, 0xa7, 0xd6, 0xb5, 0xf0, 0xbf,
+ 0x80, 0x79, 0x1a, 0xf5, 0xfe, 0xed, 0x90, 0xdf, 0xef, 0xd0, 0x6e, 0x5a,
+ 0xa4, 0x2e, 0xcb, 0x88, 0x1d, 0xea, 0x9a, 0xf8, 0x78, 0x9f, 0x69, 0x59,
+ 0x87, 0xcd, 0x13, 0x4a, 0x4b, 0xea, 0x5d, 0x2b, 0xea, 0x8c, 0x47, 0x4b,
+ 0x23, 0x01, 0x73, 0x27, 0xc1, 0xd8, 0x11, 0x89, 0x2b, 0xd1, 0x6c, 0x9f,
+ 0x72, 0x7d, 0xb6, 0x5f, 0x59, 0x91, 0x95, 0xf2, 0x27, 0x94, 0xe5, 0x59,
+ 0x29, 0x5f, 0x2c, 0x1b, 0x66, 0x59, 0xe0, 0x48, 0x22, 0x10, 0x2c, 0x96,
+ 0x5f, 0xc1, 0xb2, 0xd7, 0x5f, 0x2a, 0x1b, 0xa6, 0xad, 0x9a, 0x9c, 0x97,
+ 0x0a, 0x6c, 0xd6, 0xf4, 0x68, 0x9c, 0x3a, 0x2f, 0x8d, 0xf8, 0x6e, 0x7d,
+ 0xdd, 0xc8, 0x05, 0x1d, 0x9c, 0x83, 0xa3, 0x1c, 0x59, 0x2b, 0x71, 0x6e,
+ 0x83, 0xe1, 0x42, 0xbf, 0x56, 0x8d, 0x0d, 0xe6, 0x6f, 0xad, 0xcd, 0xeb,
+ 0xe4, 0xbf, 0xbc, 0x6c, 0xb0, 0xcb, 0xd7, 0xb1, 0xbc, 0x6e, 0x1e, 0x2d,
+ 0x60, 0xeb, 0xa9, 0x04, 0x06, 0x1d, 0x11, 0x62, 0x7e, 0x73, 0xc0, 0xdf,
+ 0x03, 0x99, 0x1b, 0x3f, 0xae, 0xa7, 0x2c, 0x69, 0xe7, 0x74, 0xfc, 0x45,
+ 0xfc, 0x72, 0x19, 0xb9, 0x26, 0xe5, 0xa6, 0x68, 0xdf, 0x82, 0x75, 0x96,
+ 0x35, 0x64, 0x8a, 0x9d, 0xfb, 0x68, 0xe7, 0x33, 0xe1, 0xaf, 0xd5, 0xe3,
+ 0x69, 0x56, 0x38, 0x9c, 0x98, 0x81, 0xb4, 0xa6, 0x12, 0x73, 0xef, 0xf2,
+ 0xa0, 0x2a, 0xaa, 0x94, 0x90, 0xdb, 0x60, 0x42, 0xc6, 0x59, 0x89, 0xa8,
+ 0x53, 0x0f, 0xca, 0xdc, 0x95, 0x30, 0xe6, 0x35, 0xa8, 0xac, 0x77, 0xc9,
+ 0x97, 0x65, 0xcc, 0x7e, 0xfa, 0x72, 0xdc, 0xd6, 0x51, 0xeb, 0xa5, 0x71,
+ 0x4b, 0x7b, 0x45, 0x1d, 0xfd, 0x67, 0xea, 0x59, 0xd6, 0x8e, 0x4b, 0xba,
+ 0x2d, 0x89, 0x96, 0x51, 0xb7, 0xc7, 0x12, 0x81, 0xf0, 0xd3, 0x88, 0x2b,
+ 0x6d, 0x59, 0x27, 0xc6, 0x12, 0x52, 0xaf, 0x8f, 0xe5, 0xfb, 0x95, 0x95,
+ 0x97, 0xea, 0x4c, 0x15, 0xfc, 0x56, 0xc6, 0x23, 0xe3, 0xbb, 0x0e, 0x1b,
+ 0xf6, 0xea, 0xf1, 0x38, 0xc4, 0xae, 0xa2, 0x58, 0x6f, 0xea, 0x7e, 0xda,
+ 0x1f, 0xed, 0x06, 0xa8, 0x49, 0xc6, 0xdc, 0x79, 0x0c, 0x00, 0xee, 0xd8,
+ 0xdb, 0xce, 0xb1, 0x5a, 0x78, 0xcd, 0xac, 0xc5, 0x18, 0xbd, 0xb4, 0x3a,
+ 0x29, 0xd7, 0xa7, 0xcb, 0x18, 0x51, 0xd6, 0x1f, 0xf5, 0x97, 0xa1, 0x5c,
+ 0xe4, 0xfc, 0x1b, 0x35, 0x6f, 0xbf, 0x1f, 0x54, 0xff, 0x17, 0xd6, 0x98,
+ 0x37, 0x7f, 0xad, 0x3a, 0x29, 0x9c, 0xaf, 0x1d, 0x5a, 0xd2, 0xc3, 0x78,
+ 0x17, 0xb7, 0x2a, 0x0c, 0xbd, 0xfd, 0x82, 0xd2, 0x8d, 0x1b, 0x43, 0x7a,
+ 0xec, 0x87, 0x8a, 0x1e, 0x1d, 0x50, 0x0c, 0xfa, 0x61, 0x10, 0xab, 0xb2,
+ 0xef, 0xef, 0xeb, 0xfb, 0x50, 0x0f, 0x4b, 0x3f, 0xd2, 0xdf, 0x59, 0xf4,
+ 0xdb, 0x63, 0x2a, 0x8e, 0x47, 0xc6, 0xa6, 0x60, 0xb3, 0x3d, 0xa6, 0x15,
+ 0xb6, 0x7f, 0x7c, 0xd7, 0x74, 0x61, 0xe3, 0xde, 0x53, 0x0b, 0xc5, 0x40,
+ 0x36, 0x1d, 0x8d, 0xa2, 0xb7, 0xd9, 0x85, 0x0d, 0xa3, 0x37, 0xa9, 0x22,
+ 0x1b, 0xd4, 0xf9, 0x65, 0xf9, 0x6f, 0x85, 0xbc, 0xc5, 0x83, 0xf5, 0x59,
+ 0xce, 0x1d, 0x31, 0x74, 0xfd, 0x51, 0x99, 0xdb, 0x5a, 0x7e, 0xcb, 0xdc,
+ 0x7a, 0xf9, 0x2d, 0xf3, 0x3c, 0x8b, 0xdf, 0xd5, 0xf0, 0xcf, 0x12, 0x59,
+ 0x9a, 0x91, 0xd8, 0x0f, 0x77, 0x45, 0xa4, 0x0b, 0x77, 0x0d, 0x58, 0x56,
+ 0x7f, 0xc0, 0xb2, 0xca, 0x42, 0xe4, 0x59, 0x81, 0xc6, 0xf0, 0x95, 0x4a,
+ 0x09, 0xa6, 0xb4, 0x66, 0xf4, 0x1f, 0x2d, 0x89, 0x55, 0x47, 0x66, 0xd1,
+ 0xf7, 0x35, 0xfc, 0x6c, 0x49, 0x3b, 0x26, 0xc6, 0xa7, 0x8f, 0x21, 0x6f,
+ 0x67, 0xdf, 0x5e, 0x50, 0xb4, 0x33, 0x91, 0x5f, 0x64, 0xd7, 0xfb, 0xd3,
+ 0xf4, 0xcb, 0xb8, 0x86, 0x18, 0xfd, 0x83, 0x32, 0xd5, 0xa2, 0xe7, 0x12,
+ 0xa7, 0xfe, 0xa0, 0xfa, 0x17, 0x1b, 0x3b, 0x13, 0xef, 0x5a, 0x0c, 0xa7,
+ 0xfc, 0xe4, 0x1a, 0xef, 0xcd, 0xbc, 0xd7, 0x6e, 0xca, 0x6c, 0xbb, 0x91,
+ 0xb2, 0x17, 0x1b, 0xef, 0xcc, 0xac, 0xb0, 0xc7, 0x9c, 0x66, 0xe1, 0x4d,
+ 0x7b, 0x45, 0xa7, 0xa2, 0x03, 0x0b, 0xc7, 0xcd, 0xeb, 0x88, 0x15, 0xaf,
+ 0x5b, 0x8e, 0x59, 0xd2, 0x46, 0x97, 0xd2, 0x4a, 0x7b, 0x8a, 0x3b, 0x4b,
+ 0x41, 0x4e, 0xad, 0x95, 0x44, 0xa2, 0xca, 0x5a, 0x5b, 0xff, 0xad, 0xca,
+ 0xca, 0xd1, 0xe9, 0x6d, 0x77, 0xd1, 0x77, 0x1f, 0x57, 0xf3, 0xf3, 0x7d,
+ 0xde, 0x1e, 0x43, 0x5e, 0x7e, 0x3f, 0xda, 0x53, 0xd2, 0x8e, 0xe8, 0x35,
+ 0xef, 0x6f, 0xed, 0x12, 0x23, 0x2e, 0xc9, 0x9c, 0xe7, 0x1e, 0x97, 0x31,
+ 0x61, 0xc9, 0x7b, 0xf0, 0xe3, 0x7a, 0xe2, 0x47, 0xf4, 0x3f, 0xc4, 0x8f,
+ 0xa5, 0x7f, 0xa2, 0xec, 0x59, 0xca, 0x21, 0x3c, 0x45, 0xe2, 0x9e, 0xf0,
+ 0x16, 0xe1, 0x2b, 0x41, 0xca, 0x25, 0xfc, 0xa5, 0x68, 0x1b, 0x96, 0xf5,
+ 0x4d, 0x73, 0x01, 0x62, 0xb5, 0xfa, 0x20, 0x50, 0x87, 0x41, 0xca, 0xea,
+ 0x48, 0x22, 0xce, 0x71, 0x52, 0xd7, 0xea, 0x75, 0x0e, 0xa8, 0x4d, 0x0e,
+ 0x74, 0xe3, 0x55, 0xd3, 0xe8, 0xdf, 0x8c, 0xbf, 0x44, 0x8f, 0xd7, 0xc2,
+ 0x61, 0x33, 0x48, 0x5c, 0x2a, 0x47, 0x67, 0x13, 0x27, 0x62, 0xad, 0x17,
+ 0x43, 0xa9, 0x78, 0x07, 0x61, 0x83, 0x31, 0xec, 0xd9, 0x4f, 0x26, 0x02,
+ 0x7a, 0xfb, 0x56, 0xa6, 0x40, 0xab, 0x06, 0xdc, 0xf0, 0x4b, 0x2a, 0xc4,
+ 0x98, 0xf1, 0x75, 0xc6, 0xf9, 0x4d, 0xe6, 0x15, 0xd4, 0x6d, 0x1f, 0x6d,
+ 0x48, 0xa5, 0xbd, 0x48, 0x3f, 0x41, 0xf2, 0x19, 0xa9, 0xcb, 0xb8, 0xd0,
+ 0xa0, 0xe0, 0x86, 0x06, 0xda, 0x27, 0x79, 0xd1, 0xe7, 0x43, 0x4e, 0xfb,
+ 0xff, 0x44, 0xb6, 0x31, 0x7a, 0xb3, 0xfa, 0x23, 0x0b, 0x33, 0xed, 0x36,
+ 0xb4, 0xa8, 0x4a, 0xb9, 0xff, 0x28, 0x27, 0x30, 0x21, 0x5c, 0xad, 0xd2,
+ 0xf8, 0x0d, 0xc6, 0xbd, 0x52, 0xa7, 0x0a, 0x15, 0xc3, 0xf1, 0x59, 0xe5,
+ 0xb4, 0xe1, 0xd2, 0x88, 0x8e, 0xbb, 0x46, 0x2b, 0xe1, 0x18, 0xd6, 0x2f,
+ 0xae, 0x74, 0x20, 0x56, 0x22, 0xfc, 0x70, 0xb4, 0x16, 0x35, 0xfb, 0xac,
+ 0x6e, 0x77, 0xc4, 0xb2, 0x3c, 0x4b, 0x22, 0xb8, 0xf7, 0xa8, 0x06, 0x75,
+ 0x9f, 0x0b, 0x15, 0xcc, 0x43, 0xd6, 0x99, 0x7d, 0xb8, 0x8f, 0xfc, 0x6e,
+ 0x4e, 0x32, 0x88, 0xd5, 0xc4, 0xa2, 0x8b, 0xa9, 0xb6, 0xd6, 0x17, 0x12,
+ 0x0d, 0xdb, 0xe6, 0x38, 0x84, 0xfb, 0xaf, 0xc1, 0xe6, 0xec, 0x1a, 0xdc,
+ 0xc9, 0xd8, 0xf9, 0x9c, 0x81, 0xee, 0x39, 0xf4, 0xd7, 0x3b, 0xc9, 0xff,
+ 0x36, 0xa6, 0xd6, 0x61, 0x63, 0x76, 0x1b, 0xff, 0xeb, 0xc0, 0xdd, 0x3c,
+ 0x36, 0xa5, 0xc4, 0xbf, 0x3f, 0x8d, 0x4d, 0xd9, 0x7a, 0xc4, 0x46, 0x37,
+ 0x62, 0x2b, 0x39, 0xc1, 0x5d, 0xa3, 0x5e, 0xea, 0xb6, 0x0d, 0x1b, 0xb2,
+ 0x6d, 0xb8, 0x97, 0x63, 0xb9, 0x97, 0xf3, 0xa1, 0x26, 0xb7, 0xd2, 0xc7,
+ 0x3c, 0xf0, 0x0e, 0x2f, 0xc5, 0x7d, 0xa3, 0xd7, 0x61, 0x0b, 0xe3, 0xe4,
+ 0xed, 0x4b, 0xae, 0x43, 0xf7, 0xe8, 0x7d, 0xe8, 0x4a, 0x19, 0x5d, 0x73,
+ 0x98, 0x6a, 0xbd, 0xb5, 0xe4, 0x3e, 0xdc, 0x43, 0x39, 0xb6, 0xed, 0xb5,
+ 0x50, 0xb6, 0x68, 0xb1, 0x6a, 0xd4, 0xc4, 0x2d, 0x9f, 0x21, 0xb1, 0xf9,
+ 0xc0, 0xad, 0x7d, 0xc6, 0xee, 0x02, 0xb6, 0x38, 0x51, 0x62, 0x28, 0x62,
+ 0xa3, 0xf9, 0xeb, 0x89, 0xbf, 0xc1, 0xe6, 0x51, 0x17, 0xee, 0x18, 0xed,
+ 0x52, 0x56, 0x8b, 0xad, 0xb8, 0x54, 0xce, 0x67, 0x94, 0xd8, 0xd7, 0xaa,
+ 0xb4, 0x8c, 0xda, 0xf3, 0xac, 0x79, 0x23, 0x5d, 0xca, 0xba, 0xec, 0x9d,
+ 0x0e, 0x94, 0xcb, 0x5c, 0x5c, 0x83, 0xf1, 0xa6, 0xaf, 0x58, 0xe9, 0xfc,
+ 0x7c, 0xa6, 0xe9, 0x3e, 0x6e, 0x5f, 0xe4, 0x57, 0x9f, 0xf4, 0x2d, 0xd0,
+ 0xbb, 0x0e, 0xa8, 0xc2, 0x2b, 0xdd, 0xc8, 0xd9, 0xf3, 0x59, 0xc2, 0x7e,
+ 0x6a, 0x70, 0xc4, 0x9b, 0xe7, 0x12, 0xf3, 0xd8, 0x97, 0x95, 0x72, 0x71,
+ 0xac, 0x94, 0x9b, 0xe3, 0x99, 0x93, 0xf4, 0xe1, 0x7e, 0xea, 0xa7, 0x8b,
+ 0x73, 0xd4, 0x45, 0xbd, 0x7c, 0x2e, 0x75, 0x8a, 0x31, 0x62, 0x1b, 0x3e,
+ 0x57, 0xe8, 0xa7, 0x2f, 0x5b, 0x8a, 0x72, 0xa3, 0x0f, 0x8f, 0x68, 0x25,
+ 0xf4, 0x31, 0xe1, 0x19, 0x07, 0x6e, 0x3d, 0x6c, 0xac, 0xe3, 0x18, 0xbe,
+ 0xc4, 0x36, 0x44, 0xae, 0x46, 0xad, 0x06, 0xf9, 0xb2, 0x3d, 0xc4, 0xec,
+ 0x72, 0xe3, 0x37, 0xd6, 0x23, 0xde, 0x76, 0xbb, 0x6c, 0x15, 0xcb, 0x3e,
+ 0x3f, 0xe0, 0xc7, 0x8d, 0xb4, 0xef, 0xb2, 0x64, 0x94, 0x7a, 0x77, 0x93,
+ 0x53, 0xb5, 0x52, 0xe7, 0x9c, 0x63, 0xea, 0xf5, 0x0e, 0xda, 0xb3, 0x33,
+ 0xb9, 0x86, 0xf3, 0xa0, 0xa1, 0x32, 0xd9, 0xc7, 0x79, 0xf0, 0xc2, 0x9d,
+ 0x6c, 0x47, 0x27, 0xe5, 0x72, 0x25, 0xd7, 0x71, 0x2e, 0xea, 0xe0, 0x49,
+ 0x76, 0x70, 0x2e, 0x80, 0xbb, 0xa8, 0xcb, 0xfb, 0x42, 0xbf, 0x56, 0x7a,
+ 0x6b, 0x65, 0x18, 0x6d, 0x9c, 0xbf, 0x28, 0x36, 0xa7, 0xea, 0xc3, 0x3b,
+ 0x24, 0xee, 0x3b, 0x99, 0x90, 0x19, 0x3f, 0x26, 0x17, 0xa6, 0xf5, 0x1b,
+ 0x3d, 0xfc, 0x5d, 0x94, 0xb3, 0x88, 0xe3, 0x22, 0xa7, 0xc4, 0xd7, 0xa2,
+ 0x9c, 0x2e, 0x94, 0x19, 0xcf, 0x5a, 0x0f, 0x7b, 0xe1, 0x77, 0xb1, 0x6c,
+ 0x39, 0xcb, 0xae, 0xa6, 0x9c, 0xab, 0x29, 0xff, 0xbc, 0xe4, 0xa7, 0xd1,
+ 0x4d, 0x39, 0xe7, 0x0c, 0xbb, 0xc9, 0x51, 0x75, 0xdc, 0x4f, 0xdd, 0x1f,
+ 0x48, 0x95, 0xa1, 0x9a, 0xf3, 0xfc, 0x39, 0xfe, 0xde, 0x41, 0x3f, 0x7a,
+ 0x7e, 0xd0, 0xc2, 0x99, 0x90, 0x86, 0x41, 0xad, 0x0c, 0xbd, 0xc1, 0xad,
+ 0xe4, 0xe5, 0x32, 0x57, 0xcc, 0xa7, 0x8c, 0x0a, 0xc6, 0x75, 0xc4, 0x5d,
+ 0xcd, 0x3a, 0xb6, 0x07, 0xdd, 0x48, 0x7b, 0x11, 0x75, 0x19, 0x51, 0xda,
+ 0xb8, 0x0b, 0x03, 0x9a, 0x02, 0x17, 0xf1, 0xb0, 0x94, 0xfe, 0xb4, 0x93,
+ 0x71, 0xd7, 0x15, 0x91, 0xff, 0x68, 0x27, 0xe4, 0x60, 0xd5, 0x11, 0x23,
+ 0xfe, 0x82, 0x12, 0x68, 0x73, 0xa9, 0xf7, 0x51, 0x47, 0x15, 0x38, 0x33,
+ 0xf8, 0x25, 0x6c, 0x64, 0x5f, 0x7d, 0x29, 0x0f, 0x73, 0x93, 0xbf, 0x53,
+ 0x72, 0x36, 0x7e, 0x7a, 0x90, 0x1c, 0x79, 0xdc, 0x9a, 0x67, 0x88, 0xdd,
+ 0x44, 0x70, 0xcf, 0xd1, 0x2a, 0x0c, 0x0e, 0x5e, 0x87, 0x6d, 0x2c, 0xb7,
+ 0x2b, 0x55, 0x0d, 0x63, 0x68, 0x99, 0x5d, 0x67, 0x84, 0xfe, 0x35, 0x90,
+ 0xbc, 0x0f, 0x2b, 0x53, 0xf5, 0xc1, 0xa3, 0x4a, 0x8c, 0x3a, 0xf4, 0xa2,
+ 0x3f, 0xb9, 0xd1, 0xd6, 0x69, 0x62, 0x5f, 0x27, 0xb6, 0x1e, 0xbd, 0x02,
+ 0x7b, 0xf6, 0x6d, 0xc1, 0x5d, 0x47, 0x99, 0xbf, 0xda, 0xb6, 0xac, 0xa2,
+ 0x77, 0xdf, 0x75, 0xca, 0x06, 0xb6, 0xb7, 0x7b, 0x98, 0xf6, 0x4c, 0x9b,
+ 0xbe, 0x7f, 0xaf, 0x91, 0x5b, 0xe6, 0xd8, 0xa2, 0xf8, 0x6b, 0xaf, 0x43,
+ 0x97, 0x6d, 0x7b, 0x79, 0xbd, 0xed, 0xc8, 0xce, 0x67, 0x9e, 0xf3, 0xb7,
+ 0xd6, 0xa3, 0xde, 0x52, 0x7b, 0x7e, 0x55, 0xea, 0xad, 0x25, 0xc1, 0xdc,
+ 0xbf, 0x96, 0xb9, 0x57, 0xc1, 0x5e, 0x7a, 0xb3, 0x8b, 0xc9, 0x1b, 0xbd,
+ 0xc8, 0x68, 0x41, 0xea, 0xa3, 0x38, 0x0f, 0x0d, 0x05, 0x7b, 0x79, 0x8b,
+ 0x65, 0x6c, 0x5b, 0x7e, 0x9f, 0x2f, 0xc8, 0xfc, 0xb6, 0xa3, 0x86, 0xf1,
+ 0x75, 0x43, 0x68, 0x9d, 0x72, 0xaf, 0x76, 0x69, 0xce, 0x7c, 0xc5, 0x39,
+ 0x93, 0x3c, 0xd1, 0x6e, 0x2b, 0xf1, 0x25, 0xdb, 0x76, 0xaf, 0xcf, 0x36,
+ 0xa3, 0x73, 0x74, 0x7a, 0xfb, 0xc5, 0x3a, 0x65, 0x9c, 0x8b, 0xe2, 0x3c,
+ 0xeb, 0xfd, 0x82, 0x65, 0x81, 0x45, 0x45, 0x2c, 0xbb, 0xb3, 0xd0, 0xff,
+ 0x41, 0x8b, 0x31, 0xc9, 0xe9, 0x32, 0x1c, 0x18, 0x09, 0xfe, 0x57, 0x25,
+ 0x5e, 0xeb, 0xa4, 0xcc, 0x0a, 0xb1, 0xe4, 0xef, 0xac, 0x3d, 0xeb, 0x64,
+ 0x5e, 0x3e, 0x42, 0x43, 0x86, 0xe2, 0xba, 0xe4, 0xb3, 0x6b, 0xb0, 0x3e,
+ 0x25, 0xb2, 0xb6, 0x63, 0x43, 0xca, 0x96, 0xcb, 0x5f, 0x94, 0xab, 0x8f,
+ 0x36, 0xa3, 0x25, 0x77, 0xdb, 0x32, 0xb5, 0xd3, 0xae, 0xee, 0xd9, 0xab,
+ 0xe2, 0xe9, 0xd0, 0x26, 0xc5, 0x3f, 0x53, 0xe2, 0x70, 0x3d, 0xba, 0xf6,
+ 0xca, 0xb7, 0x9f, 0x7c, 0x37, 0xa6, 0x4c, 0xcd, 0x1c, 0x60, 0xb9, 0x65,
+ 0x58, 0xbf, 0xb7, 0x16, 0x73, 0x38, 0xd6, 0xdb, 0xcd, 0xff, 0xa2, 0xbc,
+ 0x33, 0x43, 0xc6, 0xb3, 0xa2, 0x10, 0xcb, 0xeb, 0x71, 0xdf, 0x5e, 0xf1,
+ 0x21, 0xf9, 0xdd, 0x82, 0xde, 0xa5, 0xf5, 0x85, 0x38, 0xff, 0x37, 0x9c,
+ 0x97, 0x2e, 0xe5, 0x06, 0xe2, 0x42, 0x8c, 0xb8, 0x40, 0x9b, 0x52, 0xda,
+ 0x89, 0x0b, 0xd7, 0x17, 0x70, 0xc1, 0x43, 0x5c, 0x58, 0x93, 0x7d, 0x9b,
+ 0xf2, 0x88, 0x2f, 0xbe, 0x57, 0x9e, 0xbb, 0x29, 0xcf, 0xb1, 0xd0, 0x1c,
+ 0xc0, 0x96, 0x67, 0x19, 0x79, 0x4c, 0x2d, 0xe7, 0xd0, 0x62, 0x7c, 0x50,
+ 0x94, 0x11, 0x5b, 0xcf, 0xcb, 0x28, 0xb3, 0xd8, 0x94, 0x45, 0xb9, 0x7f,
+ 0x8f, 0x06, 0x7b, 0x7d, 0xe0, 0xb2, 0x3c, 0xeb, 0xf7, 0xbe, 0xcb, 0x1c,
+ 0x41, 0x7e, 0x13, 0x2f, 0x9a, 0xeb, 0x89, 0x73, 0xcb, 0x88, 0x7b, 0x2e,
+ 0x8e, 0x4b, 0xb0, 0x4e, 0x64, 0x73, 0xd1, 0x2f, 0xa4, 0x6d, 0xd1, 0xc9,
+ 0x52, 0x47, 0x7e, 0x1e, 0x8a, 0xf3, 0xec, 0xa4, 0x1f, 0xbb, 0x51, 0x1d,
+ 0xd1, 0xa3, 0x37, 0x39, 0x64, 0xce, 0x88, 0xf2, 0x43, 0xed, 0x85, 0xbe,
+ 0xfe, 0xbb, 0xd2, 0x50, 0xd3, 0x4f, 0x39, 0x4f, 0x28, 0xb7, 0x70, 0x5c,
+ 0xfe, 0xd2, 0xaa, 0xa8, 0x27, 0x12, 0xe8, 0x48, 0xbc, 0x2f, 0x36, 0xde,
+ 0x90, 0xcd, 0xf3, 0x4b, 0x75, 0x28, 0x6e, 0x95, 0xd3, 0xf6, 0x9d, 0x46,
+ 0xe0, 0xe2, 0x6a, 0xf6, 0x30, 0xef, 0xa0, 0xf0, 0x19, 0x93, 0x6d, 0x15,
+ 0xfb, 0xaa, 0x23, 0x96, 0x84, 0x0a, 0x76, 0xb0, 0x46, 0x61, 0xde, 0xd0,
+ 0x16, 0xb5, 0xed, 0x61, 0x17, 0xf5, 0x75, 0x42, 0xf9, 0x98, 0x70, 0x66,
+ 0x9b, 0x63, 0xc4, 0x95, 0x55, 0xc4, 0x95, 0xea, 0xa4, 0x12, 0xf5, 0x46,
+ 0x1a, 0xb7, 0xd5, 0x20, 0xd0, 0xf6, 0x28, 0xfb, 0xac, 0x21, 0xcf, 0xbc,
+ 0x89, 0xb1, 0x36, 0xc9, 0x3e, 0x57, 0xb1, 0xcf, 0xb5, 0xd9, 0x2d, 0x6c,
+ 0x57, 0xb0, 0x55, 0xc5, 0x9c, 0x7d, 0x70, 0x7b, 0x69, 0x07, 0x23, 0x0d,
+ 0x4e, 0x84, 0x17, 0xff, 0x02, 0x98, 0x81, 0x98, 0xca, 0xfc, 0x7d, 0x5e,
+ 0x52, 0x72, 0xa9, 0x03, 0xb7, 0x2e, 0xcb, 0x08, 0x96, 0x6a, 0xf0, 0x0c,
+ 0x7b, 0x25, 0x1e, 0xa1, 0x2f, 0x54, 0xa7, 0xec, 0xb1, 0xf1, 0x56, 0x45,
+ 0xd9, 0x3e, 0x05, 0x57, 0x85, 0xbe, 0xae, 0xa4, 0x67, 0xe6, 0x31, 0x5f,
+ 0xa5, 0x3e, 0x7a, 0x26, 0x04, 0x1b, 0xd3, 0xc4, 0xc6, 0x63, 0x4a, 0x7e,
+ 0x3d, 0x86, 0x7e, 0x9f, 0x42, 0xbc, 0x2a, 0x22, 0x6b, 0x20, 0x81, 0xce,
+ 0x0f, 0x29, 0xf7, 0x11, 0x0b, 0x5d, 0x8c, 0x43, 0x1e, 0x62, 0xa3, 0xc4,
+ 0xe9, 0xf4, 0xad, 0x89, 0x81, 0x3a, 0xf4, 0xd3, 0xb7, 0x37, 0x1e, 0x3d,
+ 0x75, 0x8b, 0x07, 0xb5, 0xfc, 0xf6, 0xf2, 0x98, 0xc5, 0xc3, 0x4d, 0x5f,
+ 0x76, 0xc3, 0x31, 0x20, 0x7c, 0xaf, 0x89, 0xb1, 0xca, 0x83, 0xf2, 0x01,
+ 0x13, 0x5b, 0x28, 0x4f, 0xe9, 0x50, 0x33, 0xe3, 0x09, 0xfd, 0x3c, 0x55,
+ 0x83, 0xeb, 0x07, 0x97, 0x60, 0x93, 0x8d, 0x5f, 0xb5, 0x38, 0x3b, 0xb8,
+ 0xd4, 0xc6, 0x8d, 0x87, 0x52, 0x33, 0xf0, 0xce, 0xde, 0x6b, 0x6c, 0x8c,
+ 0x1b, 0x64, 0x6c, 0xf6, 0xed, 0x0b, 0xa3, 0x8b, 0x6d, 0x7a, 0xf7, 0x5d,
+ 0x8b, 0xfb, 0x8e, 0xfa, 0xa8, 0x23, 0x83, 0x71, 0x40, 0x7d, 0xd7, 0xff,
+ 0x49, 0xb1, 0xf3, 0xe9, 0xd8, 0x2f, 0x73, 0x2d, 0x75, 0x32, 0x34, 0x56,
+ 0xf9, 0xed, 0xb4, 0xb9, 0x70, 0x5e, 0x47, 0x79, 0x9d, 0x5c, 0x4d, 0x9d,
+ 0xdc, 0x94, 0xa5, 0x39, 0x0c, 0x3b, 0x39, 0xd7, 0xe4, 0x10, 0x35, 0xb5,
+ 0xf4, 0xcb, 0x12, 0x1e, 0xb4, 0xff, 0xd1, 0xbf, 0x60, 0x6c, 0xcf, 0x71,
+ 0x3e, 0xf9, 0xdb, 0x94, 0xf9, 0x94, 0xf8, 0xe9, 0x20, 0xe6, 0x2a, 0xd4,
+ 0xef, 0xff, 0x02, 0x66, 0xe7, 0x73, 0x9b, 0xa2, 0xae, 0x54, 0x8e, 0xbf,
+ 0x25, 0x91, 0xb3, 0x39, 0x3d, 0x33, 0x22, 0x5d, 0xe5, 0x7f, 0x1b, 0x8f,
+ 0x92, 0x73, 0x27, 0xc5, 0x67, 0xbd, 0xb4, 0xe7, 0x26, 0xea, 0x4b, 0x63,
+ 0xec, 0x30, 0x89, 0x73, 0xb3, 0xe0, 0xe2, 0x38, 0x36, 0x51, 0x3f, 0x1e,
+ 0x8e, 0x63, 0x2b, 0xcb, 0xdd, 0xc5, 0xff, 0xee, 0x3a, 0x5a, 0xcb, 0xc3,
+ 0xcb, 0x63, 0x16, 0x8f, 0x9f, 0x12, 0xb3, 0x9a, 0x69, 0xc7, 0x0e, 0x94,
+ 0x0c, 0xab, 0x78, 0xca, 0x54, 0x70, 0xa1, 0x89, 0xfd, 0x35, 0x5c, 0xc6,
+ 0x3a, 0x89, 0x65, 0xde, 0xe4, 0x97, 0x88, 0x73, 0x7e, 0xac, 0x23, 0x27,
+ 0xe8, 0xdc, 0xab, 0xc1, 0x15, 0xca, 0x30, 0x67, 0x12, 0x19, 0x4e, 0x14,
+ 0x38, 0xe6, 0x3c, 0xe6, 0x3a, 0x8d, 0x61, 0xda, 0x90, 0xb6, 0xd9, 0xb6,
+ 0xa1, 0x38, 0xe3, 0x73, 0x90, 0xb9, 0x7e, 0xde, 0x76, 0x5b, 0xde, 0x63,
+ 0x47, 0xf4, 0x31, 0x8e, 0x67, 0x4e, 0x44, 0xf7, 0xdf, 0x42, 0x5f, 0x10,
+ 0xce, 0x57, 0x9a, 0x04, 0x0e, 0x0c, 0xb6, 0xa3, 0x9a, 0x36, 0xe3, 0x5d,
+ 0x7c, 0x14, 0xa9, 0xda, 0x7e, 0xdb, 0x56, 0xf3, 0x6d, 0x97, 0x45, 0x2b,
+ 0x23, 0x8d, 0x31, 0x69, 0x7b, 0xbc, 0xd0, 0xf6, 0x0a, 0xb6, 0x9d, 0x60,
+ 0xdb, 0x2b, 0xff, 0x5d, 0xdb, 0xd3, 0xe3, 0x5d, 0x4f, 0x21, 0x2e, 0x4b,
+ 0xde, 0x5c, 0xc4, 0xed, 0x22, 0xc7, 0xf8, 0x8d, 0xf7, 0x32, 0x4e, 0xee,
+ 0x90, 0xb9, 0xf3, 0xe5, 0x7d, 0xf6, 0xbd, 0xd8, 0x7c, 0xb9, 0xad, 0x3d,
+ 0xc5, 0x18, 0x6f, 0xd6, 0x4c, 0x6b, 0x6b, 0x0e, 0xff, 0xff, 0x70, 0x4a,
+ 0xb8, 0x44, 0x3b, 0x2c, 0xca, 0xfa, 0xac, 0xa1, 0x77, 0x2d, 0x73, 0x18,
+ 0xdb, 0x2e, 0x32, 0xd7, 0xb9, 0xf1, 0x52, 0x5f, 0xb2, 0x36, 0xd2, 0x8e,
+ 0x85, 0x03, 0x7a, 0xe7, 0x2e, 0xf2, 0xd1, 0xc3, 0x21, 0x3d, 0xfa, 0x2d,
+ 0xe8, 0xf1, 0x52, 0xe5, 0x25, 0x94, 0x4c, 0x9c, 0xc5, 0x60, 0xf6, 0x47,
+ 0x92, 0x6f, 0xb2, 0x4d, 0xb7, 0xe2, 0x99, 0xe8, 0x43, 0x8c, 0xf5, 0xdc,
+ 0xac, 0xe7, 0x1e, 0x80, 0xbb, 0x92, 0xf5, 0xc6, 0x07, 0xe2, 0x96, 0x8b,
+ 0x5c, 0x50, 0x8d, 0xe8, 0x1d, 0x95, 0x8a, 0x11, 0xdb, 0xc4, 0xb6, 0xd7,
+ 0x30, 0x96, 0x95, 0x27, 0xbb, 0xc9, 0x03, 0x74, 0xdf, 0x97, 0x55, 0xbd,
+ 0x6b, 0x3d, 0x5e, 0xc2, 0xbf, 0x92, 0x3c, 0xce, 0x4b, 0x9e, 0x45, 0x8a,
+ 0xed, 0x59, 0xe3, 0x1a, 0xf9, 0xcc, 0xbb, 0x56, 0x78, 0x41, 0x85, 0x53,
+ 0xda, 0xbd, 0x38, 0xbe, 0xe0, 0xdd, 0xc4, 0x65, 0x3c, 0xd7, 0x5c, 0x46,
+ 0xe3, 0xfb, 0xf0, 0xa9, 0xa9, 0x75, 0x45, 0x62, 0xfd, 0x56, 0x57, 0x64,
+ 0xdb, 0xfd, 0xc7, 0x9b, 0xf3, 0x76, 0xeb, 0xcf, 0xb8, 0x71, 0xd6, 0x2b,
+ 0xbe, 0xc4, 0xfc, 0x67, 0x7f, 0x13, 0x76, 0xef, 0x67, 0x5e, 0xa9, 0x36,
+ 0x86, 0xcb, 0x95, 0x1a, 0xe6, 0x44, 0xc3, 0x36, 0x1f, 0x76, 0x1a, 0xbb,
+ 0xec, 0x9c, 0x59, 0xe2, 0x83, 0xd4, 0x99, 0x9f, 0x91, 0xf8, 0x27, 0xeb,
+ 0x39, 0x07, 0x6e, 0xdd, 0x90, 0xa0, 0xdf, 0x6a, 0xbd, 0x2c, 0xb3, 0xae,
+ 0xb0, 0x4e, 0x2f, 0x6b, 0x18, 0xbd, 0xd3, 0x38, 0xc9, 0xba, 0x69, 0xb1,
+ 0xaa, 0xd1, 0x5f, 0x73, 0x29, 0x8e, 0x74, 0x14, 0xca, 0x33, 0xd9, 0xb3,
+ 0x65, 0x73, 0x4f, 0xc3, 0xb3, 0x1d, 0xbc, 0x96, 0xf7, 0x85, 0xcb, 0xf1,
+ 0x6e, 0x67, 0x61, 0x6e, 0x0e, 0xb9, 0xf2, 0xb8, 0xff, 0x69, 0x77, 0x71,
+ 0xbd, 0x28, 0x5f, 0xe6, 0xda, 0x12, 0x94, 0xef, 0xb9, 0x14, 0x5b, 0xe2,
+ 0xc4, 0xf2, 0x6d, 0x7b, 0xf3, 0xeb, 0x93, 0x95, 0x4b, 0x05, 0xb7, 0xeb,
+ 0x71, 0xb7, 0xed, 0xf7, 0x5f, 0x75, 0xe5, 0xed, 0xc0, 0x59, 0x18, 0x97,
+ 0x49, 0x1b, 0xbc, 0x52, 0xd6, 0xfc, 0x0b, 0xf8, 0x39, 0x9b, 0xff, 0xf7,
+ 0x42, 0xe6, 0xc2, 0x45, 0xff, 0x7c, 0xdc, 0x74, 0x60, 0x6a, 0x46, 0x9e,
+ 0xaf, 0xab, 0xfb, 0x9a, 0xd0, 0x33, 0x46, 0xbc, 0xa1, 0x0f, 0xb5, 0x85,
+ 0xd6, 0x5a, 0xa8, 0x91, 0x75, 0x83, 0x5a, 0x54, 0xec, 0x13, 0xde, 0x4c,
+ 0x9e, 0x31, 0x76, 0xca, 0x1e, 0x4b, 0x6f, 0x26, 0xbf, 0x2e, 0xb2, 0x33,
+ 0xd5, 0xf7, 0xee, 0x1d, 0x9a, 0xe0, 0x85, 0xd8, 0x46, 0xdd, 0xad, 0x0b,
+ 0x03, 0x39, 0xbf, 0x03, 0xba, 0xb9, 0x4b, 0x56, 0x92, 0x12, 0xb7, 0x61,
+ 0x7b, 0xad, 0x82, 0x2e, 0xa3, 0x1a, 0x8e, 0xc5, 0xbf, 0xb5, 0xee, 0x58,
+ 0x27, 0xff, 0xbd, 0x5b, 0xc0, 0x97, 0x0f, 0xb2, 0x6f, 0x19, 0xb7, 0x70,
+ 0x3a, 0x37, 0x2a, 0xe8, 0x53, 0x37, 0x38, 0x84, 0x73, 0x2a, 0x8c, 0x9d,
+ 0xf6, 0x5c, 0xa0, 0x37, 0xad, 0x60, 0x77, 0x5a, 0x30, 0xd3, 0x49, 0x1c,
+ 0xf4, 0x61, 0x67, 0x5a, 0x70, 0xd0, 0x45, 0x1c, 0x9c, 0x83, 0xed, 0x69,
+ 0xc1, 0xc1, 0x12, 0xbc, 0x3c, 0x78, 0x05, 0x1e, 0xe2, 0xef, 0x07, 0x53,
+ 0xa5, 0x08, 0xef, 0xfd, 0x0b, 0x1c, 0x48, 0x0b, 0x7f, 0x72, 0x23, 0x35,
+ 0x5c, 0x87, 0x54, 0x3a, 0xcf, 0x25, 0xaa, 0x86, 0xff, 0x12, 0x49, 0xfe,
+ 0x1e, 0x20, 0xef, 0xcb, 0x0c, 0xcd, 0x45, 0x82, 0xbf, 0x65, 0xbd, 0xcd,
+ 0x43, 0xf9, 0x13, 0x81, 0x0a, 0x6c, 0x18, 0x92, 0x1c, 0xda, 0x77, 0xeb,
+ 0x5d, 0x81, 0x79, 0xec, 0xb3, 0x0e, 0xbb, 0xc9, 0xd9, 0xda, 0x86, 0xfc,
+ 0xe8, 0xe7, 0xef, 0x9d, 0xa9, 0x4a, 0xbc, 0x36, 0xa8, 0xdb, 0xfd, 0xf5,
+ 0xa4, 0x56, 0xac, 0x70, 0x19, 0x55, 0x58, 0x31, 0x38, 0x1f, 0x3b, 0xd2,
+ 0x82, 0xbd, 0xd5, 0xc4, 0xde, 0x7a, 0x3c, 0x98, 0x16, 0x7e, 0xa9, 0xc1,
+ 0xbb, 0xd7, 0xc0, 0x48, 0x5a, 0xd6, 0x84, 0x6b, 0x70, 0x61, 0x28, 0x80,
+ 0x41, 0xbb, 0x7f, 0x13, 0xc9, 0x54, 0x98, 0xf2, 0x79, 0x51, 0xb9, 0x2f,
+ 0xe7, 0xab, 0x82, 0x82, 0xc9, 0x40, 0x10, 0x03, 0x63, 0xb3, 0x50, 0xbe,
+ 0x4f, 0x37, 0xb7, 0x42, 0xbf, 0x78, 0x17, 0xae, 0xc4, 0xee, 0x31, 0x1f,
+ 0x4a, 0xf7, 0x55, 0xc3, 0x1d, 0x6a, 0xc2, 0xce, 0xb1, 0x0f, 0x61, 0xfb,
+ 0x58, 0x1d, 0xb1, 0x13, 0x78, 0x3a, 0x63, 0xa2, 0x9f, 0x18, 0x3c, 0x87,
+ 0x31, 0xe6, 0x95, 0xac, 0xcc, 0xa3, 0xcc, 0x8f, 0x02, 0x4f, 0xa0, 0x9a,
+ 0x31, 0x4a, 0x7e, 0xcb, 0xb5, 0xb0, 0x8d, 0xed, 0xf9, 0x75, 0x2a, 0x3d,
+ 0xbe, 0x13, 0xb6, 0xbe, 0x91, 0xcb, 0x88, 0xee, 0x65, 0x4d, 0x68, 0xba,
+ 0x3d, 0xed, 0xb4, 0xd7, 0xe8, 0x2f, 0xdb, 0xe5, 0x5f, 0x15, 0xec, 0xd2,
+ 0x5e, 0x53, 0xc3, 0x93, 0x97, 0xf2, 0x5c, 0xb4, 0x96, 0x20, 0x60, 0x3a,
+ 0x15, 0xf8, 0x99, 0xef, 0xfa, 0x9f, 0x7a, 0xdf, 0xda, 0xda, 0xe5, 0xf5,
+ 0x9f, 0xe9, 0x6b, 0xb0, 0x72, 0x6f, 0x49, 0x65, 0x3c, 0x2f, 0x41, 0x5c,
+ 0x93, 0x35, 0xaa, 0x46, 0x8d, 0x5a, 0x79, 0x5f, 0xde, 0x5d, 0x15, 0x2b,
+ 0x8b, 0x34, 0xc3, 0x3f, 0x5e, 0xe7, 0x7f, 0x2d, 0x21, 0x3a, 0xfd, 0xbd,
+ 0xe5, 0x36, 0x0c, 0xdf, 0x31, 0xd4, 0xf9, 0x7f, 0x92, 0x79, 0xbb, 0x04,
+ 0x55, 0x1e, 0x5c, 0x9f, 0xf8, 0xe0, 0x7a, 0x6a, 0x04, 0xca, 0xca, 0x66,
+ 0x1f, 0x79, 0x3f, 0x9c, 0xab, 0x17, 0x60, 0xda, 0x87, 0x7c, 0x24, 0x02,
+ 0xf5, 0x74, 0x73, 0x98, 0xb9, 0x7e, 0xfe, 0x7e, 0xce, 0xf2, 0xac, 0xee,
+ 0x8b, 0x2a, 0xf9, 0x7b, 0x36, 0x9d, 0xa1, 0x3f, 0xd0, 0xae, 0xbb, 0x85,
+ 0xb3, 0xb0, 0x2f, 0x60, 0x6b, 0xc2, 0xb2, 0x9e, 0xa4, 0x0e, 0xe4, 0x5e,
+ 0xe0, 0x9b, 0x99, 0xdf, 0x59, 0x93, 0x5e, 0x27, 0x5e, 0x37, 0xa6, 0xb7,
+ 0x47, 0xae, 0x17, 0x31, 0x19, 0xfb, 0xec, 0x13, 0x75, 0xdc, 0x68, 0xdc,
+ 0x76, 0x98, 0x79, 0xf2, 0xc2, 0x80, 0xee, 0x4f, 0xe2, 0xff, 0x5a, 0xc2,
+ 0x0b, 0xd3, 0x4a, 0x71, 0xdd, 0xee, 0xfd, 0x6b, 0x27, 0x55, 0x31, 0x17,
+ 0xc7, 0x77, 0x28, 0xa1, 0xf7, 0xc7, 0x99, 0xb7, 0x45, 0xbd, 0x88, 0x39,
+ 0x23, 0x75, 0xfe, 0x9d, 0x09, 0x7b, 0x9c, 0xe6, 0x79, 0xce, 0xdd, 0xe9,
+ 0xe6, 0x3a, 0x7f, 0x6f, 0x46, 0x6c, 0x50, 0xe1, 0x58, 0x9a, 0xf1, 0x70,
+ 0x46, 0xc5, 0x9d, 0x0f, 0x78, 0xb1, 0x69, 0xc0, 0x83, 0x6d, 0x03, 0x5f,
+ 0x82, 0x71, 0x95, 0x13, 0x77, 0x30, 0xf7, 0xdb, 0x3c, 0x50, 0x4a, 0x3d,
+ 0x6a, 0xd8, 0x32, 0xe0, 0x44, 0xd3, 0x55, 0x55, 0x88, 0xcf, 0x2c, 0xc5,
+ 0xf3, 0xf4, 0xdd, 0xab, 0x42, 0x15, 0x48, 0xdb, 0x9c, 0x43, 0xb0, 0x41,
+ 0x78, 0x9b, 0xe8, 0x8d, 0x71, 0xd0, 0x10, 0x0c, 0xf9, 0xa0, 0xf5, 0x99,
+ 0xdf, 0x58, 0xb9, 0x99, 0x7b, 0x6c, 0x3e, 0xe9, 0x88, 0x88, 0x6e, 0xa4,
+ 0xae, 0xac, 0x35, 0x79, 0x19, 0x23, 0xdf, 0xa3, 0x47, 0x65, 0x5e, 0x24,
+ 0x30, 0xb9, 0x4c, 0x71, 0x20, 0x1c, 0xa8, 0x8a, 0x55, 0x47, 0xc2, 0x58,
+ 0x99, 0xed, 0xf1, 0xf9, 0xec, 0x7b, 0x59, 0x11, 0x9c, 0x5f, 0x62, 0xe2,
+ 0x96, 0x2c, 0x9c, 0x2b, 0xa9, 0xfb, 0x56, 0xea, 0x75, 0x87, 0xf9, 0x07,
+ 0x2b, 0x9f, 0xd7, 0xb8, 0x89, 0x97, 0x96, 0xb5, 0x99, 0xfa, 0x65, 0x4e,
+ 0x81, 0x9f, 0x16, 0xf4, 0x2b, 0x3a, 0xad, 0x18, 0xff, 0x9d, 0x75, 0x9a,
+ 0xfa, 0x75, 0xb3, 0x3d, 0x37, 0xdb, 0x2b, 0x1b, 0x7f, 0xaf, 0x9e, 0x4b,
+ 0x29, 0xcf, 0x4a, 0x5b, 0x86, 0xd9, 0x72, 0x2f, 0xc0, 0x1f, 0x55, 0x8a,
+ 0x3c, 0xf4, 0x4f, 0x8d, 0xe9, 0x25, 0x7b, 0xbd, 0xed, 0xeb, 0x59, 0xcb,
+ 0x1a, 0x36, 0x45, 0xff, 0x7e, 0xea, 0x5f, 0xd6, 0x5d, 0x64, 0x0e, 0x9a,
+ 0x10, 0xad, 0xd5, 0xfb, 0x01, 0x49, 0x7c, 0x15, 0xcc, 0x60, 0xae, 0xf5,
+ 0x8d, 0x76, 0x0f, 0x5e, 0x4b, 0x54, 0xda, 0xe3, 0xbe, 0xaa, 0xc1, 0xb2,
+ 0xbe, 0x16, 0xf2, 0xe3, 0x4d, 0xa3, 0x31, 0xbc, 0x48, 0xd5, 0x19, 0x13,
+ 0x64, 0xed, 0x83, 0xba, 0x48, 0xcd, 0xe5, 0x7c, 0x89, 0xcf, 0x63, 0x1b,
+ 0xed, 0xc9, 0xef, 0x88, 0x00, 0xaf, 0x26, 0x8c, 0xe0, 0x0e, 0xf6, 0x3f,
+ 0xea, 0x8d, 0x60, 0x7b, 0x4a, 0x6d, 0x75, 0x92, 0x7c, 0x96, 0x31, 0xd7,
+ 0xdb, 0x85, 0x7f, 0xb5, 0xd2, 0x5e, 0x0b, 0x25, 0x21, 0x89, 0x25, 0xf3,
+ 0x70, 0x46, 0x73, 0xe0, 0x99, 0xe0, 0x2c, 0x44, 0x6b, 0x1c, 0xe4, 0x33,
+ 0xaf, 0x5b, 0xff, 0xec, 0x95, 0x7e, 0x64, 0x2c, 0x7f, 0xe0, 0x38, 0x14,
+ 0x1b, 0xef, 0x76, 0xa6, 0x22, 0xd4, 0xf7, 0xfb, 0xfb, 0xff, 0xbf, 0xd6,
+ 0x94, 0x57, 0xfa, 0xd7, 0x35, 0x3f, 0xf9, 0xf9, 0xe3, 0x1f, 0xb8, 0xce,
+ 0x12, 0xe4, 0x78, 0xbf, 0x67, 0x7d, 0xc7, 0x6e, 0xf3, 0x23, 0xa5, 0x79,
+ 0x5e, 0x2f, 0xed, 0x3d, 0xcd, 0xf1, 0x49, 0x9b, 0xc5, 0x7e, 0x44, 0x6f,
+ 0x93, 0xa5, 0x82, 0xd7, 0x3b, 0x53, 0xa2, 0x3f, 0xc9, 0x97, 0x4e, 0x5b,
+ 0x98, 0x25, 0xe7, 0x0f, 0xdb, 0x65, 0xe3, 0xd4, 0x57, 0x0f, 0x6d, 0x88,
+ 0xb1, 0x81, 0xf1, 0x42, 0xee, 0xb2, 0x6a, 0xc4, 0x5c, 0x0b, 0xdb, 0x19,
+ 0xb2, 0xd2, 0xde, 0x6a, 0xec, 0x34, 0x69, 0x77, 0x86, 0x3a, 0xdf, 0x09,
+ 0x0b, 0xa7, 0x4d, 0x39, 0x77, 0x61, 0xca, 0xeb, 0xc0, 0x2e, 0xd3, 0x89,
+ 0x4e, 0x43, 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x67, 0x2a,
+ 0xd8, 0x13, 0x56, 0xb1, 0xc5, 0xe8, 0xf1, 0xcb, 0xf5, 0xe5, 0x21, 0x39,
+ 0x57, 0xb0, 0x91, 0x3a, 0x89, 0x33, 0x57, 0xde, 0xca, 0x76, 0x7b, 0x43,
+ 0xf9, 0x75, 0xf1, 0x18, 0x2c, 0x6b, 0x8f, 0xd9, 0xf2, 0xe1, 0x0a, 0x96,
+ 0x3b, 0x67, 0x4a, 0xec, 0x38, 0x70, 0xcb, 0xc2, 0x40, 0x3c, 0x5a, 0x02,
+ 0x3d, 0x56, 0x46, 0x3f, 0xdd, 0x39, 0x30, 0x8f, 0xf5, 0x04, 0xfb, 0x9d,
+ 0xbe, 0xdd, 0x90, 0xf5, 0xae, 0x80, 0xff, 0x27, 0xe4, 0xde, 0x69, 0xef,
+ 0x02, 0x6a, 0xd6, 0xf0, 0xbf, 0xc2, 0x79, 0xab, 0x36, 0x9c, 0xdb, 0x5e,
+ 0x80, 0xde, 0x59, 0xa6, 0x2c, 0x08, 0x56, 0xc1, 0x85, 0x38, 0xf9, 0xf9,
+ 0xd8, 0x38, 0xf3, 0xeb, 0x94, 0xa1, 0x1d, 0xb1, 0xd7, 0xcc, 0x3d, 0xd4,
+ 0x85, 0x87, 0xf1, 0x22, 0xa0, 0x4d, 0x2a, 0xc5, 0xf3, 0x79, 0x82, 0x0d,
+ 0x31, 0x47, 0x44, 0xf0, 0x2d, 0x6e, 0x3d, 0xd1, 0x4c, 0xd5, 0x19, 0x6e,
+ 0x7f, 0x2c, 0xe3, 0xe1, 0xa1, 0xf1, 0xf0, 0xfa, 0x37, 0x65, 0x7c, 0xfe,
+ 0x8d, 0x19, 0xf8, 0xd7, 0x67, 0x8a, 0x76, 0x59, 0xf4, 0x6d, 0xc1, 0x36,
+ 0xcb, 0x92, 0x7b, 0xc9, 0x8f, 0x67, 0xa5, 0xad, 0x7c, 0x1c, 0x2b, 0xa1,
+ 0xec, 0x4f, 0xd2, 0xd6, 0x5d, 0x8c, 0x55, 0xbb, 0x8c, 0x38, 0xa1, 0xd2,
+ 0xb2, 0x0c, 0xf2, 0x99, 0x12, 0xc5, 0x8f, 0x9d, 0x4d, 0xbf, 0xe5, 0x7c,
+ 0x02, 0x9b, 0x32, 0x01, 0x77, 0x7e, 0x3e, 0xc4, 0xcf, 0x04, 0x03, 0xfc,
+ 0x8c, 0xbf, 0x3e, 0x7f, 0x0f, 0xfb, 0xd9, 0x9e, 0x99, 0xee, 0x03, 0x0a,
+ 0x56, 0xb3, 0xad, 0x96, 0x10, 0x9c, 0x2b, 0x9a, 0xfe, 0xcd, 0xca, 0x79,
+ 0xa7, 0xdf, 0x37, 0x75, 0x33, 0xe6, 0xc2, 0xb9, 0xbe, 0x49, 0xce, 0x15,
+ 0xb4, 0x84, 0xe5, 0x5c, 0xc1, 0x7a, 0x43, 0xce, 0x89, 0xd9, 0x59, 0x39,
+ 0xb7, 0xac, 0xcb, 0xe7, 0xef, 0xc7, 0x22, 0x13, 0x77, 0xa5, 0x64, 0xed,
+ 0x4d, 0xb0, 0xc8, 0xed, 0xff, 0x4e, 0xa6, 0x09, 0x5b, 0x52, 0x72, 0x7f,
+ 0x8c, 0xb9, 0x86, 0xe1, 0xf1, 0x3f, 0x93, 0xb9, 0x16, 0x77, 0xee, 0x0f,
+ 0xa3, 0x73, 0x3f, 0x9a, 0xca, 0x38, 0x86, 0xd2, 0x50, 0xc0, 0x7f, 0x14,
+ 0x9a, 0xff, 0x0c, 0x75, 0x72, 0x8a, 0x72, 0x9e, 0x7e, 0x8f, 0x9c, 0xa2,
+ 0x43, 0xf8, 0xef, 0x4e, 0xb8, 0x91, 0x09, 0xbd, 0x63, 0xc5, 0xed, 0x5c,
+ 0xc8, 0xeb, 0xbf, 0x27, 0xe1, 0x47, 0xce, 0xce, 0xc9, 0xde, 0x28, 0x15,
+ 0xec, 0xee, 0x4b, 0xc5, 0xa3, 0x2a, 0x8a, 0xf3, 0xab, 0x87, 0x65, 0x6e,
+ 0x5f, 0x4d, 0xc8, 0x7f, 0xd1, 0x2f, 0xa9, 0x8c, 0x4b, 0x2a, 0x73, 0xf9,
+ 0x41, 0x59, 0xdf, 0x57, 0x4b, 0x45, 0x3f, 0x72, 0x8f, 0x22, 0x2e, 0x39,
+ 0x63, 0x13, 0xaf, 0x6b, 0x8b, 0x10, 0xab, 0xa1, 0x9e, 0xca, 0x0d, 0xaf,
+ 0xbf, 0x71, 0xc2, 0xe7, 0x37, 0x27, 0xe0, 0xbf, 0x72, 0x62, 0xba, 0x08,
+ 0xe4, 0x0a, 0xea, 0x07, 0x61, 0x81, 0xd7, 0xbf, 0x39, 0x31, 0x8f, 0x3c,
+ 0x33, 0x6e, 0x2d, 0x6f, 0x3e, 0x6f, 0xcd, 0x8b, 0x18, 0xb9, 0xd3, 0x94,
+ 0xe1, 0x9d, 0x6b, 0xf4, 0xf8, 0x1c, 0xc7, 0xa9, 0xfb, 0xb5, 0x69, 0x7d,
+ 0x5c, 0x08, 0xfd, 0xff, 0xed, 0xa3, 0x18, 0xe7, 0x68, 0x0f, 0xcd, 0x32,
+ 0x06, 0x89, 0x77, 0xcc, 0x85, 0x6a, 0x65, 0x2c, 0x81, 0x02, 0x6f, 0x2b,
+ 0x8e, 0x4b, 0xe1, 0x5c, 0xbb, 0xa9, 0x8b, 0x62, 0x0c, 0xb3, 0xac, 0x5e,
+ 0xc3, 0x57, 0x58, 0x03, 0xe7, 0x9c, 0x65, 0x4f, 0x7d, 0xd8, 0xc9, 0x9c,
+ 0xfd, 0x9c, 0xd9, 0xf2, 0x57, 0x4e, 0x44, 0x7d, 0xa5, 0x8c, 0xad, 0xb2,
+ 0xf6, 0x74, 0xa6, 0x69, 0xca, 0x9a, 0x64, 0x1e, 0xd4, 0x92, 0x95, 0xfb,
+ 0x4b, 0x0e, 0xda, 0xb7, 0x85, 0x87, 0x4d, 0xf9, 0x5f, 0x70, 0x26, 0x1e,
+ 0x73, 0xd0, 0x56, 0xdc, 0x86, 0xde, 0xf1, 0x65, 0xa5, 0x8a, 0xae, 0xec,
+ 0x0c, 0x4e, 0x42, 0x0f, 0x6f, 0x51, 0xe8, 0x87, 0x35, 0x0b, 0x4c, 0x99,
+ 0x82, 0x37, 0x12, 0x01, 0x33, 0x50, 0x88, 0x4b, 0xe7, 0x38, 0x77, 0x6f,
+ 0x25, 0x8c, 0xce, 0x27, 0x0b, 0xe7, 0x3f, 0xcb, 0x4c, 0x5f, 0x1f, 0x17,
+ 0x7b, 0x74, 0xbb, 0xb7, 0x27, 0x70, 0xc1, 0xd1, 0x8c, 0x0b, 0x87, 0xcc,
+ 0x12, 0x2c, 0x6f, 0x17, 0x3b, 0x75, 0xbb, 0x77, 0x26, 0x30, 0xe5, 0xe4,
+ 0xb5, 0x73, 0xe6, 0x5c, 0x62, 0x9a, 0xbd, 0x7e, 0x29, 0x31, 0x22, 0xa6,
+ 0x31, 0xbe, 0x96, 0x47, 0xbc, 0xee, 0xf2, 0x09, 0x68, 0x65, 0xe4, 0x40,
+ 0xee, 0x08, 0x5a, 0x1d, 0x49, 0xdd, 0xdf, 0xe6, 0x68, 0xc2, 0xaa, 0xac,
+ 0x9f, 0x3c, 0xfa, 0x05, 0xf2, 0x4e, 0xfb, 0x3e, 0x1f, 0x6d, 0xd2, 0xc9,
+ 0x0a, 0x43, 0xb3, 0xd4, 0x88, 0xe4, 0x76, 0x55, 0xb8, 0x4b, 0xdb, 0xfa,
+ 0x11, 0x35, 0x32, 0x88, 0x9b, 0x9a, 0xdd, 0xad, 0xd5, 0x13, 0x45, 0x9d,
+ 0x20, 0xe6, 0x89, 0x40, 0xab, 0x32, 0xa0, 0x56, 0x46, 0x44, 0x37, 0xfe,
+ 0xd6, 0xe4, 0xb8, 0xc8, 0xaa, 0xb9, 0x07, 0xc6, 0x7f, 0xe3, 0x46, 0x79,
+ 0x94, 0x58, 0xf5, 0x43, 0xdf, 0x7f, 0xae, 0xde, 0x33, 0x6e, 0xc1, 0x7b,
+ 0x97, 0x21, 0xdf, 0xb6, 0x6d, 0x31, 0x1f, 0x19, 0xfb, 0x8c, 0x3b, 0x60,
+ 0x59, 0x8c, 0x93, 0x3e, 0x28, 0x73, 0x39, 0x1e, 0xfa, 0x1a, 0xe3, 0xd2,
+ 0xc6, 0xcc, 0x1f, 0xac, 0x8f, 0x3a, 0x6d, 0x0e, 0x40, 0xde, 0xe4, 0xbf,
+ 0xed, 0x75, 0xe3, 0xf7, 0x96, 0xf0, 0x11, 0x27, 0x7d, 0xba, 0x84, 0x78,
+ 0xbe, 0xdb, 0x74, 0xb6, 0xad, 0x50, 0x14, 0xf4, 0x19, 0x0b, 0xb4, 0x32,
+ 0xc6, 0xa9, 0x5e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0x0f, 0x81, 0xe5, 0x32,
+ 0x9b, 0x37, 0xbb, 0x22, 0xf7, 0x7c, 0x76, 0xac, 0x59, 0xb0, 0x60, 0xea,
+ 0xb6, 0x27, 0x8d, 0x0e, 0xf2, 0xaf, 0xaf, 0x90, 0xa7, 0xe5, 0xfb, 0xc9,
+ 0x61, 0xde, 0x07, 0xf4, 0xb3, 0x79, 0x73, 0x69, 0x44, 0x78, 0x58, 0xfa,
+ 0xb6, 0xc3, 0x46, 0x1b, 0x73, 0xb0, 0x7b, 0x3e, 0x7b, 0xae, 0xf9, 0x00,
+ 0xbf, 0xf3, 0x75, 0xd2, 0xa8, 0xfe, 0xc0, 0x3a, 0x15, 0x11, 0xe9, 0xc3,
+ 0xcf, 0x3e, 0xee, 0xf9, 0x6c, 0xe7, 0x92, 0x31, 0x6c, 0xcf, 0x6e, 0xfb,
+ 0x93, 0xfd, 0x54, 0x46, 0x64, 0x3d, 0x34, 0x76, 0xfb, 0xea, 0xc0, 0x3d,
+ 0x9f, 0xcd, 0x2c, 0x19, 0x64, 0x1f, 0x9f, 0x66, 0x7c, 0xc9, 0xd7, 0x89,
+ 0x2a, 0x8e, 0x0f, 0xd4, 0x41, 0x59, 0x64, 0xdb, 0xed, 0x0b, 0x03, 0xbf,
+ 0xb7, 0x16, 0x0c, 0x94, 0xd8, 0x3a, 0x70, 0x51, 0x07, 0x0f, 0x9a, 0xce,
+ 0x5c, 0xc0, 0x61, 0xeb, 0xa0, 0xcb, 0x47, 0x1d, 0x24, 0xa9, 0x83, 0xdc,
+ 0x4c, 0x23, 0xfc, 0x36, 0x75, 0xb0, 0x60, 0x7c, 0xf3, 0xe6, 0xb2, 0x08,
+ 0x9c, 0x0e, 0xe3, 0x47, 0x0e, 0xe6, 0x45, 0xaa, 0xcb, 0xd8, 0x4c, 0xbd,
+ 0xdd, 0xf3, 0xd9, 0xf9, 0x4b, 0x6c, 0x9d, 0xdf, 0xea, 0x0e, 0xdc, 0x47,
+ 0xbb, 0x69, 0xa5, 0xad, 0x6f, 0xe5, 0xd1, 0xce, 0xa3, 0x8f, 0x47, 0x02,
+ 0xbb, 0xb3, 0x1b, 0xa9, 0xab, 0x35, 0x1c, 0xc7, 0x3a, 0xca, 0xd5, 0xc5,
+ 0xdf, 0x31, 0xfe, 0x8e, 0xf3, 0xb7, 0xcc, 0x8f, 0x7a, 0x49, 0xb6, 0xd8,
+ 0x25, 0xd9, 0x1c, 0x94, 0xc7, 0x63, 0xaf, 0x55, 0x96, 0x47, 0x8e, 0xdf,
+ 0xba, 0x3a, 0xd0, 0xc9, 0x36, 0xfe, 0xbf, 0x32, 0xd9, 0x57, 0xe0, 0x32,
+ 0xe2, 0x3e, 0x27, 0x44, 0x3e, 0xbd, 0xa3, 0x13, 0x39, 0x62, 0xef, 0xef,
+ 0xf2, 0xd8, 0x4b, 0xd9, 0xaa, 0x38, 0x3f, 0xcf, 0x2d, 0x49, 0xcf, 0xf6,
+ 0x18, 0xf0, 0xb9, 0x8d, 0x7e, 0x0c, 0x64, 0x47, 0xa8, 0x03, 0xb1, 0x93,
+ 0x2f, 0x52, 0x7f, 0xdd, 0xac, 0x73, 0x8a, 0xb1, 0x4c, 0x8f, 0xd2, 0x67,
+ 0x69, 0xb3, 0x7a, 0x98, 0x07, 0xed, 0xe5, 0x51, 0xb6, 0x9b, 0xa6, 0x4c,
+ 0x25, 0xb4, 0x5f, 0x05, 0x72, 0x0f, 0xf7, 0x0c, 0xdb, 0x3f, 0x6c, 0xfc,
+ 0xba, 0xe2, 0x14, 0xc7, 0x1e, 0xf5, 0x6e, 0xc6, 0x68, 0x93, 0xe8, 0x2a,
+ 0x46, 0x5d, 0xe9, 0x3e, 0xff, 0x34, 0x5d, 0x5e, 0x96, 0xf7, 0x0a, 0xf2,
+ 0x09, 0xcb, 0xfa, 0x89, 0xd1, 0xb2, 0x90, 0x49, 0x21, 0xd2, 0x76, 0xae,
+ 0x64, 0x59, 0x25, 0xf6, 0xfe, 0xb3, 0xd8, 0xed, 0x1b, 0x0c, 0x91, 0xb7,
+ 0xb1, 0x7d, 0x3b, 0x8d, 0x73, 0x73, 0x86, 0xfe, 0x1c, 0xf8, 0x9d, 0x15,
+ 0x9d, 0x29, 0xf5, 0xe6, 0xe1, 0x15, 0xc6, 0xde, 0xa8, 0x16, 0xef, 0x74,
+ 0x0b, 0xbf, 0x37, 0x9c, 0xe1, 0x35, 0x88, 0x33, 0xa1, 0xd4, 0x83, 0x77,
+ 0x92, 0x7b, 0x9e, 0x33, 0xf2, 0x7e, 0x7c, 0x24, 0xa3, 0x47, 0x1f, 0xe6,
+ 0x39, 0x39, 0x30, 0xb9, 0x54, 0x31, 0x4e, 0x05, 0xc9, 0x7b, 0x3d, 0x70,
+ 0x32, 0x87, 0x6a, 0x75, 0xf4, 0x04, 0x5d, 0xa0, 0x2f, 0x96, 0xcb, 0xb8,
+ 0xe2, 0x1c, 0xa3, 0xe0, 0xb6, 0x5b, 0xdb, 0x68, 0x63, 0x79, 0x7c, 0xa1,
+ 0x0b, 0x1e, 0x6d, 0x53, 0xa6, 0x18, 0xe3, 0x3c, 0xda, 0xfa, 0x84, 0xe0,
+ 0x82, 0xdc, 0x77, 0x0d, 0x53, 0xcf, 0x82, 0x0f, 0xaf, 0xda, 0x7b, 0xd5,
+ 0x88, 0x11, 0x55, 0x4e, 0x23, 0xdf, 0xae, 0xc6, 0x76, 0xdb, 0x1d, 0x1a,
+ 0x2e, 0xfb, 0xb8, 0xae, 0xb5, 0x3b, 0x64, 0x1f, 0x1d, 0xd1, 0x2b, 0x53,
+ 0xa8, 0x97, 0xc7, 0xb9, 0x65, 0x2e, 0x1b, 0xe7, 0xd8, 0x06, 0xf3, 0x8e,
+ 0xe5, 0x89, 0xf7, 0xf7, 0x2f, 0xfd, 0x49, 0xbf, 0x3d, 0x35, 0x2a, 0x64,
+ 0x9f, 0x8f, 0xdc, 0x13, 0xeb, 0x64, 0xbe, 0x36, 0x7d, 0xaf, 0x8f, 0x7e,
+ 0x82, 0xed, 0x1f, 0x8f, 0x73, 0x3e, 0xe7, 0x1a, 0xb2, 0x0f, 0x48, 0xee,
+ 0xa1, 0x4d, 0xdf, 0xf7, 0x63, 0xdf, 0x9f, 0x2c, 0x17, 0x2e, 0x73, 0x98,
+ 0x38, 0x19, 0x6d, 0x97, 0xfa, 0x96, 0xf5, 0xe3, 0x05, 0x41, 0xe4, 0x66,
+ 0x38, 0x31, 0xd2, 0x00, 0x0c, 0x27, 0x45, 0xd7, 0xe9, 0xcf, 0x6c, 0x30,
+ 0xfe, 0xcd, 0x8a, 0xd6, 0x36, 0x6a, 0xbd, 0xaa, 0xac, 0x67, 0x8c, 0xdd,
+ 0xda, 0x67, 0xd4, 0x6b, 0x7d, 0x6a, 0xee, 0x18, 0xe3, 0xd0, 0x01, 0xe6,
+ 0xe8, 0xe5, 0x82, 0x15, 0x35, 0x46, 0xb4, 0xbf, 0x06, 0x0d, 0xf0, 0xdb,
+ 0xf7, 0x24, 0xf4, 0xf8, 0x37, 0x54, 0x23, 0xb8, 0x56, 0xf8, 0xa7, 0xfa,
+ 0x8e, 0x95, 0xa6, 0x0d, 0x7c, 0xa1, 0xe1, 0x67, 0x65, 0x79, 0x6c, 0x8f,
+ 0x76, 0xce, 0xe2, 0xbc, 0xbc, 0xb9, 0x48, 0xf7, 0x67, 0x14, 0xd1, 0x91,
+ 0x70, 0xae, 0x11, 0xec, 0x62, 0x3c, 0xfe, 0xb7, 0x86, 0x08, 0x8e, 0xf0,
+ 0xfb, 0xa7, 0xd7, 0xca, 0x1e, 0x37, 0xcb, 0x0a, 0x06, 0x16, 0x84, 0x6b,
+ 0x38, 0x86, 0x67, 0xf8, 0x7f, 0x7f, 0xf6, 0x75, 0xeb, 0xdc, 0x2c, 0x63,
+ 0x70, 0x25, 0x83, 0xe2, 0xf0, 0x84, 0xae, 0x4d, 0xa9, 0xff, 0xd9, 0x3d,
+ 0x37, 0xf6, 0x3a, 0xe3, 0x67, 0x9e, 0x0f, 0x34, 0x6a, 0x49, 0xb5, 0xae,
+ 0x5c, 0xf4, 0x3a, 0x3c, 0xf1, 0x52, 0x21, 0xce, 0xe7, 0xef, 0x75, 0x3e,
+ 0x7e, 0x49, 0x3f, 0x72, 0xdf, 0x76, 0x1e, 0x6d, 0x2e, 0x1a, 0xa7, 0xde,
+ 0xdd, 0x33, 0x38, 0xe6, 0x2f, 0x34, 0xdc, 0x69, 0x8f, 0xb3, 0xd6, 0x98,
+ 0xc3, 0x31, 0x2a, 0xd0, 0x1a, 0x9c, 0xe5, 0x79, 0xfe, 0xd8, 0x42, 0x96,
+ 0x96, 0xb6, 0x5a, 0xe9, 0x43, 0x25, 0xac, 0x73, 0xbd, 0x79, 0x70, 0x76,
+ 0x4f, 0x93, 0xee, 0xfb, 0x02, 0x6d, 0x35, 0xd4, 0xf0, 0x2b, 0x2b, 0xaa,
+ 0x39, 0xcd, 0xaf, 0x73, 0xd4, 0x77, 0x26, 0xa4, 0xac, 0xcc, 0xab, 0x11,
+ 0x6d, 0x50, 0xde, 0xb2, 0x30, 0x33, 0x10, 0x6e, 0xb0, 0xc7, 0x0f, 0xdc,
+ 0x91, 0x19, 0x61, 0xae, 0x2c, 0x6d, 0x2a, 0x58, 0x19, 0x78, 0xc3, 0xf2,
+ 0xcf, 0x1a, 0xc1, 0xce, 0xec, 0x1f, 0xe3, 0xb0, 0x5f, 0x21, 0x87, 0xd6,
+ 0x3b, 0xe2, 0x79, 0xbf, 0x6b, 0x03, 0xfb, 0x2d, 0x37, 0xec, 0x3c, 0xfc,
+ 0xb6, 0x44, 0x40, 0xd6, 0x8c, 0xc6, 0x3e, 0x33, 0x1e, 0x90, 0xbd, 0x19,
+ 0x5e, 0xe4, 0xda, 0xa5, 0x4c, 0xbd, 0x36, 0x8e, 0x1c, 0x19, 0xa6, 0xec,
+ 0x23, 0x39, 0x54, 0x9e, 0x5f, 0x47, 0x70, 0xc8, 0x3a, 0xb8, 0xf6, 0x2a,
+ 0x39, 0x61, 0x9b, 0x21, 0x6d, 0x28, 0x58, 0x18, 0x98, 0x81, 0xc6, 0xb5,
+ 0x3f, 0x7a, 0xb9, 0x24, 0x90, 0xf7, 0xdb, 0x3e, 0xc3, 0xd8, 0x76, 0x1a,
+ 0xbf, 0x26, 0x56, 0xc9, 0x3e, 0x93, 0xb4, 0xd4, 0x63, 0x5b, 0x0d, 0xc8,
+ 0x68, 0x4e, 0x8c, 0x1a, 0xb2, 0x0f, 0xd2, 0xb2, 0x56, 0x07, 0x5e, 0xa3,
+ 0xdf, 0x51, 0x9e, 0xac, 0xb3, 0x50, 0x57, 0xca, 0x14, 0xf6, 0x70, 0x28,
+ 0x2d, 0x9f, 0x15, 0x9d, 0x3c, 0x61, 0xc6, 0x99, 0x35, 0x48, 0x7c, 0x18,
+ 0xfb, 0xcc, 0xeb, 0x86, 0x70, 0x78, 0xdd, 0x5c, 0xa9, 0x54, 0x33, 0xde,
+ 0x3a, 0xfd, 0x63, 0xf6, 0x7a, 0x86, 0x9f, 0x58, 0x2e, 0x3c, 0x54, 0x72,
+ 0x43, 0x27, 0x9e, 0x34, 0x6a, 0xf0, 0x84, 0x96, 0xe7, 0x74, 0xc4, 0x44,
+ 0xbc, 0x90, 0x58, 0x90, 0xa3, 0x87, 0x90, 0x1b, 0x1b, 0x9d, 0x17, 0x95,
+ 0x5f, 0x33, 0x6f, 0x04, 0x9e, 0xcb, 0x74, 0xe1, 0x41, 0xb9, 0x8f, 0xa5,
+ 0xd4, 0xb7, 0x35, 0x3a, 0xa4, 0xbf, 0x2e, 0xec, 0xb2, 0xd7, 0x65, 0xc7,
+ 0x3e, 0x73, 0xd8, 0x78, 0xa4, 0x20, 0xab, 0x60, 0xfe, 0xd8, 0x67, 0x9e,
+ 0x34, 0x4e, 0xdb, 0x73, 0x27, 0x7b, 0x16, 0xfa, 0x4d, 0xc1, 0xc6, 0x72,
+ 0xa8, 0xcc, 0x2f, 0x1c, 0xc6, 0xa7, 0xe1, 0xa8, 0x19, 0xa3, 0xed, 0xc9,
+ 0x7a, 0xcf, 0xed, 0x70, 0xd6, 0xb8, 0xe8, 0x9b, 0x77, 0xc0, 0x55, 0x23,
+ 0x9c, 0xbe, 0xc8, 0xb7, 0xdb, 0xf8, 0xbf, 0xe8, 0x76, 0xca, 0xd6, 0xad,
+ 0x93, 0xd8, 0xd3, 0x27, 0xf9, 0x9f, 0x51, 0x4d, 0x1d, 0xe9, 0x1d, 0xb2,
+ 0xae, 0x5d, 0x49, 0x6c, 0x65, 0x1c, 0x75, 0x57, 0xb3, 0xcc, 0xdb, 0xd4,
+ 0xfb, 0x82, 0x81, 0x0a, 0x72, 0x7d, 0xcb, 0x7a, 0x87, 0x5c, 0x7f, 0x61,
+ 0xa0, 0x31, 0x67, 0x30, 0xfe, 0xe1, 0x66, 0xbd, 0x4d, 0xee, 0x11, 0x6f,
+ 0x30, 0x2e, 0x5a, 0xb1, 0x75, 0x52, 0x46, 0xf7, 0xc5, 0x94, 0x62, 0x1f,
+ 0x8b, 0xe0, 0x9f, 0x61, 0xc1, 0x15, 0xb1, 0x88, 0x5d, 0xba, 0x19, 0x45,
+ 0x8b, 0xec, 0xf5, 0x69, 0x97, 0xf1, 0xbb, 0xe4, 0x7e, 0x03, 0xa2, 0x93,
+ 0x2e, 0x18, 0xb9, 0x23, 0x32, 0x67, 0xb3, 0x2d, 0x04, 0x16, 0xff, 0x8e,
+ 0x39, 0x93, 0xcc, 0x4f, 0x7d, 0xae, 0x49, 0xc9, 0x05, 0x7d, 0xe4, 0xfe,
+ 0x8f, 0x40, 0x6f, 0x4f, 0x50, 0xd7, 0xad, 0x21, 0x1b, 0xf3, 0x7c, 0x09,
+ 0xd8, 0x7c, 0xdf, 0x7c, 0x05, 0x1f, 0x45, 0x25, 0x73, 0xdc, 0x86, 0xf1,
+ 0x35, 0xa8, 0xaa, 0x89, 0xfa, 0xca, 0xb1, 0x94, 0xe7, 0x5b, 0x99, 0xc7,
+ 0x7c, 0x12, 0x55, 0x6b, 0x63, 0x48, 0x70, 0xec, 0x95, 0xc6, 0xad, 0xbc,
+ 0xd6, 0x87, 0x64, 0xca, 0xc5, 0x71, 0xfc, 0xd0, 0xaa, 0x9a, 0x29, 0xb2,
+ 0x99, 0xde, 0x0a, 0x83, 0x79, 0xb7, 0xad, 0x0b, 0x62, 0x79, 0x4a, 0xb8,
+ 0x54, 0x63, 0x74, 0x0b, 0xfe, 0x40, 0xdb, 0xd5, 0x3b, 0x36, 0x2a, 0x71,
+ 0xda, 0x6c, 0x82, 0x3a, 0x97, 0xb2, 0x96, 0xb5, 0x2a, 0xf0, 0x5b, 0xea,
+ 0x38, 0xce, 0x73, 0xc3, 0xff, 0x1a, 0xd4, 0xa5, 0xa5, 0x38, 0x6b, 0xc5,
+ 0x35, 0x1f, 0xed, 0x52, 0x5d, 0x27, 0xbc, 0x6b, 0x45, 0x48, 0xad, 0x40,
+ 0xb9, 0x56, 0xb0, 0xd3, 0x74, 0x41, 0x97, 0x53, 0xb7, 0xf5, 0x19, 0x6f,
+ 0x94, 0xcb, 0x75, 0x87, 0x7d, 0xdd, 0x5f, 0xb8, 0x9e, 0xe6, 0xf5, 0xf3,
+ 0xbc, 0x3e, 0x48, 0xdd, 0xab, 0x57, 0x48, 0xfd, 0xcd, 0xa6, 0xd4, 0x27,
+ 0x1d, 0x31, 0x12, 0x85, 0xf9, 0x88, 0xdd, 0x9e, 0x2f, 0xbb, 0xed, 0xf6,
+ 0x7c, 0x1b, 0x4e, 0xb6, 0x11, 0x8f, 0x96, 0xc3, 0x44, 0x45, 0x40, 0x70,
+ 0x5e, 0xe4, 0xe2, 0xdc, 0x65, 0x45, 0xae, 0xad, 0x8c, 0x8b, 0x3d, 0x4f,
+ 0x97, 0x23, 0xde, 0x35, 0xc7, 0xb6, 0xc3, 0x34, 0x79, 0x8a, 0xee, 0x7f,
+ 0x5d, 0x69, 0xf1, 0xc9, 0xb2, 0x4e, 0x8a, 0x9c, 0xf7, 0x7e, 0xd3, 0x19,
+ 0x6e, 0x72, 0x2c, 0xc8, 0x95, 0xc2, 0x88, 0x5d, 0x54, 0x66, 0x57, 0x08,
+ 0x3e, 0x24, 0x32, 0x2d, 0xcc, 0xd0, 0xe2, 0x41, 0xe6, 0x56, 0xc1, 0x2c,
+ 0x75, 0xbb, 0x9e, 0x88, 0x7d, 0xc2, 0xde, 0xb3, 0xe4, 0x9c, 0x5c, 0x83,
+ 0x16, 0xdd, 0x81, 0x05, 0xe1, 0x39, 0xcc, 0xd0, 0x68, 0x97, 0x66, 0xa9,
+ 0x43, 0xf7, 0xdf, 0x84, 0xff, 0x62, 0xd7, 0x3b, 0x92, 0xc9, 0x75, 0x96,
+ 0x73, 0x4e, 0xbf, 0x4a, 0x39, 0x76, 0x07, 0x44, 0x8e, 0xb1, 0x82, 0x1c,
+ 0x31, 0xc6, 0x5c, 0x53, 0xbb, 0x21, 0x30, 0x78, 0x49, 0x6f, 0x4f, 0xdb,
+ 0x7a, 0xeb, 0xe3, 0x79, 0x29, 0x76, 0x90, 0x3f, 0x9e, 0x6a, 0xf2, 0x16,
+ 0xd6, 0xf6, 0x25, 0xa7, 0x13, 0xfc, 0x3d, 0xfb, 0xa9, 0x0d, 0x86, 0x1e,
+ 0x76, 0xd8, 0xfc, 0xdf, 0x8d, 0xb8, 0xcd, 0xad, 0x1d, 0x10, 0xee, 0xf8,
+ 0xb0, 0x5d, 0xce, 0x45, 0x9d, 0x54, 0xe0, 0x91, 0x82, 0xbf, 0x54, 0x30,
+ 0xbe, 0x7d, 0xd5, 0xfe, 0x9d, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0xc5, 0x18,
+ 0x25, 0xeb, 0x83, 0xfd, 0xb6, 0xef, 0xa7, 0xf1, 0x7d, 0xfb, 0x3b, 0x97,
+ 0xcf, 0xcb, 0xd0, 0x47, 0x9f, 0x70, 0xb0, 0x8d, 0x5e, 0x7b, 0x2f, 0xaa,
+ 0xac, 0x15, 0x5c, 0x8b, 0x1d, 0x1c, 0x95, 0xdb, 0xe8, 0x44, 0xbf, 0x26,
+ 0x36, 0xd1, 0x8d, 0xa4, 0x66, 0x7a, 0xb3, 0x4d, 0xd3, 0x73, 0x2a, 0x13,
+ 0x87, 0x9a, 0x7e, 0xcf, 0x58, 0x2e, 0xd7, 0xce, 0x5a, 0x87, 0x8d, 0x53,
+ 0x21, 0x7a, 0x70, 0x67, 0x89, 0xad, 0xdf, 0xa9, 0xdb, 0xec, 0x7d, 0x5b,
+ 0x94, 0xf9, 0xe9, 0x84, 0xc4, 0xd1, 0x79, 0xc8, 0x98, 0x22, 0x9b, 0xb3,
+ 0x7d, 0x0f, 0xe7, 0xa4, 0x2f, 0x15, 0x88, 0x5e, 0xc9, 0xff, 0x26, 0x19,
+ 0xcb, 0x7a, 0xa9, 0xcf, 0x58, 0xbb, 0xf0, 0xb8, 0xad, 0x38, 0x40, 0x1b,
+ 0x9b, 0x30, 0x2d, 0xeb, 0x08, 0x31, 0xa2, 0x7a, 0x81, 0x8a, 0xdc, 0xcc,
+ 0xad, 0x48, 0x31, 0x36, 0x1d, 0x31, 0x5a, 0x3e, 0x5a, 0x82, 0xb8, 0x9f,
+ 0x31, 0xdc, 0xb7, 0x93, 0xa3, 0xb9, 0x9f, 0xf3, 0x75, 0xca, 0x14, 0x7e,
+ 0xe9, 0xbc, 0xb8, 0x02, 0x46, 0x78, 0x99, 0xe3, 0x87, 0xd6, 0x94, 0xc8,
+ 0x9e, 0xea, 0xf9, 0x5f, 0x94, 0x61, 0x9b, 0x38, 0x6f, 0x35, 0xe7, 0xf8,
+ 0xed, 0x80, 0xde, 0xf6, 0x02, 0xfb, 0x69, 0x1c, 0x68, 0xe9, 0x14, 0x19,
+ 0x0e, 0x87, 0x9c, 0xb1, 0x23, 0x08, 0xb4, 0x6f, 0x55, 0x8a, 0x39, 0x04,
+ 0x70, 0xe5, 0xb8, 0x89, 0xa3, 0x4d, 0xcf, 0x90, 0xef, 0x48, 0xfd, 0x52,
+ 0x3c, 0x66, 0x3e, 0x65, 0xd5, 0xcf, 0x7e, 0xde, 0x3a, 0x66, 0xa8, 0x5b,
+ 0xa8, 0xed, 0x58, 0x25, 0x64, 0x4d, 0x33, 0x7d, 0xdb, 0x5d, 0x01, 0xdd,
+ 0xdc, 0xc3, 0xb6, 0xce, 0x24, 0x4e, 0x05, 0xdd, 0x6c, 0xeb, 0x11, 0x53,
+ 0x72, 0x08, 0x67, 0x5b, 0x1b, 0xe7, 0xb6, 0x27, 0x15, 0xf0, 0xc9, 0xba,
+ 0xad, 0xe4, 0x79, 0xb7, 0x27, 0x64, 0xcf, 0xf8, 0x18, 0xc7, 0x13, 0xdd,
+ 0xe6, 0x42, 0xcb, 0xfd, 0x55, 0xb4, 0x9f, 0x6a, 0x14, 0x6d, 0x5d, 0xf7,
+ 0x11, 0xef, 0x70, 0x17, 0xcb, 0xbc, 0x1c, 0x98, 0x87, 0xe7, 0x42, 0x2d,
+ 0x6b, 0xe7, 0xc1, 0x19, 0x3b, 0xa6, 0x04, 0xda, 0xb6, 0x2a, 0x71, 0x4d,
+ 0x6c, 0xf1, 0xce, 0x8c, 0x1e, 0x6c, 0x85, 0x60, 0x77, 0x8c, 0xfa, 0x98,
+ 0x87, 0x77, 0x16, 0x8b, 0x5c, 0xce, 0x70, 0xd0, 0x11, 0xe8, 0x7a, 0x8a,
+ 0xf3, 0x5b, 0xb5, 0x40, 0x64, 0x07, 0xb2, 0x19, 0x91, 0x3f, 0x86, 0x64,
+ 0xf6, 0xec, 0xdb, 0x87, 0x0d, 0x38, 0x4f, 0x34, 0x3d, 0x68, 0xc1, 0xde,
+ 0x63, 0xde, 0x22, 0xf3, 0xd0, 0x21, 0xf3, 0x50, 0x4e, 0x7f, 0x5a, 0x4d,
+ 0xb9, 0xb7, 0xd8, 0x72, 0xcf, 0xc3, 0xa8, 0x29, 0xeb, 0x64, 0x4e, 0xed,
+ 0x4e, 0x0c, 0x12, 0x3b, 0x03, 0x17, 0x7b, 0xd8, 0xcf, 0xcb, 0x94, 0x79,
+ 0x01, 0xf5, 0x3e, 0xd5, 0x2e, 0xfc, 0xb6, 0x0f, 0x03, 0xa9, 0xe2, 0x1e,
+ 0x74, 0x05, 0x92, 0x7a, 0x4f, 0x39, 0xfa, 0xc8, 0xf7, 0x7a, 0xac, 0xa9,
+ 0x99, 0x72, 0x3d, 0x8d, 0x1d, 0xa9, 0xa8, 0x46, 0x7f, 0xa0, 0xde, 0xa1,
+ 0xcf, 0x83, 0x3e, 0xf9, 0xaa, 0x23, 0x4a, 0x1f, 0x30, 0xbd, 0x17, 0x89,
+ 0x0d, 0x27, 0xd0, 0x65, 0xa1, 0xc6, 0xb6, 0x87, 0x9f, 0x8e, 0x19, 0x0e,
+ 0x59, 0x6b, 0x0f, 0xe6, 0xa8, 0x03, 0x95, 0x73, 0x22, 0x3a, 0xa8, 0xa4,
+ 0xcf, 0x8e, 0x07, 0x74, 0xff, 0x73, 0x94, 0x67, 0x0f, 0xe5, 0x59, 0x93,
+ 0x9f, 0x43, 0xdf, 0x0e, 0x45, 0x7c, 0x3a, 0xd0, 0xbe, 0x81, 0xd7, 0x77,
+ 0x53, 0x9e, 0xc0, 0x80, 0x82, 0x34, 0xd1, 0xac, 0x8f, 0x7c, 0xf6, 0xc0,
+ 0x34, 0x79, 0xdc, 0xf6, 0x9c, 0xc5, 0xc9, 0x05, 0x4a, 0x71, 0xd8, 0x14,
+ 0xfc, 0xd6, 0x30, 0x4a, 0x3b, 0x3d, 0xc4, 0x19, 0x89, 0x7a, 0x55, 0x94,
+ 0x1a, 0x82, 0x01, 0x33, 0x79, 0xcd, 0xc5, 0xb9, 0xa9, 0xc6, 0x31, 0x2d,
+ 0xcd, 0x38, 0x59, 0xe4, 0x76, 0x7f, 0xb0, 0x8e, 0x7a, 0x85, 0x9f, 0xc9,
+ 0x3a, 0x9a, 0xac, 0x35, 0x7d, 0xb9, 0x22, 0xbf, 0xbf, 0x52, 0xf6, 0x3f,
+ 0xe4, 0xaf, 0x3f, 0xad, 0x09, 0x47, 0x2e, 0x96, 0xff, 0xb9, 0xf5, 0x84,
+ 0x5d, 0x5e, 0xca, 0xb9, 0x6c, 0x2e, 0x5f, 0x6e, 0x97, 0xfb, 0xb9, 0xf5,
+ 0x8c, 0xe6, 0x9c, 0x56, 0xae, 0xb8, 0x07, 0xef, 0xd4, 0x97, 0x5c, 0xc4,
+ 0x3c, 0x47, 0xc3, 0x32, 0x3c, 0x61, 0x9c, 0xad, 0x5f, 0xdf, 0xd4, 0xcd,
+ 0x38, 0x56, 0xe4, 0x5a, 0x75, 0xf4, 0x2b, 0x0b, 0x43, 0xe6, 0xa9, 0xa1,
+ 0x12, 0xf4, 0x90, 0x3b, 0x0a, 0x17, 0x10, 0x8e, 0x2a, 0xeb, 0x7c, 0xb7,
+ 0x96, 0x5f, 0xce, 0x79, 0xf5, 0xa0, 0x5f, 0x6d, 0xb3, 0xb9, 0x61, 0x54,
+ 0x15, 0xdc, 0xad, 0xb3, 0xc7, 0x7e, 0x39, 0xfe, 0x4b, 0xac, 0x98, 0xbe,
+ 0x6e, 0xd7, 0x8d, 0x43, 0x46, 0x91, 0xb3, 0x9c, 0x7a, 0x50, 0x25, 0x4e,
+ 0x0e, 0x9b, 0xcb, 0x24, 0x36, 0xfb, 0x59, 0x3f, 0x18, 0x53, 0xa7, 0x73,
+ 0x9b, 0xbf, 0xa9, 0x40, 0x55, 0xcf, 0x2e, 0x07, 0x64, 0xff, 0xaf, 0xec,
+ 0xd9, 0x96, 0xbe, 0xca, 0x0a, 0xeb, 0x57, 0x1f, 0xc4, 0x35, 0x8a, 0x7d,
+ 0x09, 0xdf, 0xa8, 0x28, 0xca, 0x18, 0x8c, 0xda, 0x72, 0xfe, 0xd2, 0x5a,
+ 0xab, 0xe5, 0xe6, 0x68, 0x78, 0xaf, 0xec, 0xd1, 0x82, 0xec, 0xb1, 0x0f,
+ 0x5c, 0x7f, 0x93, 0x7e, 0xa6, 0xb7, 0x59, 0xdc, 0x7b, 0x2a, 0x6b, 0xb3,
+ 0xf2, 0x9f, 0x82, 0x1e, 0xe2, 0x50, 0x54, 0x6b, 0x61, 0x9c, 0xd7, 0x7d,
+ 0x9b, 0x38, 0x1f, 0x71, 0xaf, 0xec, 0x6b, 0x2d, 0xc6, 0xc8, 0x52, 0xe4,
+ 0xd7, 0x48, 0x81, 0x43, 0x85, 0x75, 0x51, 0xda, 0x3d, 0x7a, 0x32, 0xbf,
+ 0xb3, 0x72, 0x5e, 0x27, 0x63, 0xe1, 0xe5, 0xfd, 0xf7, 0x69, 0xea, 0x75,
+ 0x94, 0xff, 0xed, 0xb8, 0xb4, 0xee, 0x22, 0x6b, 0x4f, 0x12, 0x7b, 0x7f,
+ 0x6b, 0xad, 0x7f, 0x4f, 0xd9, 0xe9, 0x7b, 0x5f, 0x67, 0xc6, 0x64, 0x3f,
+ 0xda, 0xd1, 0xc2, 0xfa, 0x7c, 0xeb, 0xbf, 0xdf, 0x8f, 0x46, 0x5b, 0x42,
+ 0x74, 0x07, 0xb9, 0x5d, 0x1c, 0x7d, 0x38, 0x9a, 0x68, 0xd4, 0x76, 0x42,
+ 0x93, 0x75, 0x69, 0x7e, 0xfa, 0x70, 0x2c, 0x81, 0x68, 0xc9, 0x55, 0xd5,
+ 0xe4, 0x5b, 0x88, 0x3a, 0x64, 0x8f, 0x50, 0xa2, 0xb1, 0x6d, 0x37, 0xc7,
+ 0xe4, 0x5f, 0xdb, 0x87, 0xd1, 0x44, 0xcb, 0xad, 0x8c, 0x23, 0xfe, 0x8a,
+ 0x3c, 0xd7, 0xe9, 0x38, 0x4c, 0x1c, 0xd8, 0x5e, 0x58, 0x1b, 0x5b, 0x9f,
+ 0xf8, 0x15, 0xe5, 0xb7, 0x85, 0x64, 0xbd, 0x3f, 0x56, 0xee, 0x2c, 0x7a,
+ 0x53, 0x67, 0xb1, 0x79, 0x50, 0x11, 0xfb, 0xc2, 0xa6, 0xb4, 0xc8, 0x73,
+ 0x16, 0x1b, 0x07, 0xbf, 0x87, 0x43, 0x83, 0xb3, 0xd1, 0x6a, 0xeb, 0xa6,
+ 0x0b, 0x5b, 0xf7, 0x9e, 0xc4, 0x9e, 0x94, 0x85, 0xdd, 0x21, 0x0f, 0xb6,
+ 0x1c, 0x54, 0xb0, 0x2a, 0x70, 0x06, 0x3b, 0xf7, 0x5a, 0x98, 0x1f, 0xea,
+ 0x46, 0x9b, 0x59, 0x81, 0xd2, 0x9a, 0x05, 0x9d, 0x2a, 0xcb, 0xad, 0x1f,
+ 0xed, 0x52, 0x6e, 0xe4, 0xb8, 0x73, 0xae, 0xe3, 0xc4, 0x02, 0x15, 0x3e,
+ 0x03, 0x5a, 0x75, 0x24, 0xaa, 0xdc, 0x92, 0x6d, 0x55, 0x3a, 0x46, 0x6d,
+ 0x3e, 0xa5, 0xdc, 0x94, 0xf5, 0x55, 0x4a, 0x4c, 0x3f, 0x14, 0x3a, 0x8b,
+ 0x74, 0xba, 0xaa, 0x32, 0xef, 0x2f, 0x67, 0xc9, 0x1d, 0x24, 0xe7, 0x30,
+ 0x69, 0x53, 0x7f, 0xec, 0xb9, 0x02, 0xb1, 0xbb, 0x29, 0xfc, 0x64, 0xe4,
+ 0x15, 0xbc, 0x32, 0xf2, 0x2f, 0x58, 0xae, 0x49, 0x9e, 0x69, 0x75, 0x3b,
+ 0x23, 0x96, 0xb5, 0xbf, 0x39, 0x6e, 0xcd, 0x34, 0x2c, 0xb6, 0x57, 0x85,
+ 0x59, 0x91, 0xef, 0x62, 0xb7, 0xc6, 0xb6, 0x52, 0xc7, 0xed, 0x7b, 0xb7,
+ 0xbe, 0xc8, 0xa7, 0xe1, 0x4b, 0xe5, 0xcc, 0x5a, 0x44, 0x87, 0x6a, 0xa1,
+ 0x6f, 0xab, 0x71, 0x18, 0x5d, 0xff, 0x5b, 0x69, 0xc2, 0x4d, 0xd9, 0x57,
+ 0xf0, 0xe6, 0x48, 0x37, 0x31, 0x53, 0xef, 0xf8, 0x96, 0x62, 0x75, 0xef,
+ 0x0e, 0xe9, 0x6d, 0xff, 0x55, 0x89, 0xc6, 0xcb, 0x69, 0x53, 0x65, 0xcc,
+ 0x09, 0x6e, 0x1e, 0x91, 0x7c, 0xb9, 0x03, 0xee, 0x01, 0x3d, 0xb7, 0x82,
+ 0x3c, 0xfb, 0x0b, 0x8b, 0xe2, 0x73, 0x66, 0xd0, 0x2e, 0x1d, 0x8a, 0x1e,
+ 0x34, 0xd4, 0x6e, 0x3c, 0x6e, 0xea, 0x93, 0xbf, 0x75, 0x18, 0xe9, 0x6f,
+ 0xa2, 0x09, 0xeb, 0xb2, 0x7a, 0x7a, 0x29, 0xf3, 0xb0, 0x9d, 0x49, 0x13,
+ 0xa9, 0xa4, 0xde, 0xd1, 0xe5, 0xe8, 0xc7, 0xdd, 0x81, 0xfa, 0x6d, 0x6f,
+ 0x93, 0xcb, 0x79, 0x88, 0x29, 0xc9, 0x89, 0x0c, 0xf3, 0xdc, 0x7e, 0x6c,
+ 0x3d, 0x18, 0xc1, 0x96, 0xfd, 0x26, 0xfa, 0x92, 0x19, 0xca, 0xf6, 0x1a,
+ 0x6d, 0xdb, 0xb2, 0xda, 0x43, 0xf1, 0x1b, 0x54, 0x04, 0xa2, 0xec, 0xb3,
+ 0x45, 0x8d, 0x04, 0xfc, 0xaa, 0xc2, 0xe8, 0x3f, 0xe1, 0x44, 0x2f, 0xcb,
+ 0x0c, 0xa4, 0x68, 0x73, 0x49, 0x37, 0xe3, 0x65, 0x1d, 0x46, 0xc7, 0x7d,
+ 0x38, 0x32, 0xee, 0x41, 0x7a, 0x5c, 0xe3, 0x51, 0x8e, 0x87, 0x86, 0x2d,
+ 0x62, 0xb9, 0x17, 0x8f, 0x1d, 0x76, 0x63, 0xfb, 0x3e, 0x0f, 0xe6, 0x45,
+ 0x66, 0xe1, 0xf0, 0xe1, 0x72, 0x1c, 0xe0, 0xf5, 0x9a, 0xc5, 0x7e, 0x7c,
+ 0x8d, 0xd7, 0x07, 0xf7, 0xb9, 0x38, 0x0f, 0xf3, 0x71, 0x9c, 0x86, 0x9d,
+ 0x1e, 0xaf, 0x40, 0x6a, 0x98, 0x26, 0x4f, 0xce, 0xfa, 0x3a, 0x33, 0x8c,
+ 0xa3, 0x87, 0x19, 0x1b, 0x0f, 0x9a, 0x48, 0xb0, 0x9f, 0x3d, 0xd4, 0x55,
+ 0x1f, 0x71, 0x6d, 0xeb, 0xb8, 0x60, 0xfc, 0x3a, 0xac, 0x1e, 0xd0, 0xdb,
+ 0x5a, 0x15, 0x23, 0xba, 0x44, 0x09, 0xca, 0x73, 0x2b, 0x6e, 0x95, 0xd7,
+ 0x5a, 0x12, 0xba, 0xd9, 0x8a, 0x6e, 0x9c, 0xe6, 0xb8, 0xff, 0x3b, 0xfd,
+ 0x76, 0x99, 0x43, 0xef, 0xbf, 0x5e, 0x3d, 0x89, 0xa1, 0x6c, 0x8e, 0x5c,
+ 0x1d, 0x08, 0x1f, 0x3a, 0x49, 0xfe, 0xf6, 0x38, 0xf1, 0xe7, 0x65, 0xcb,
+ 0x67, 0xa8, 0xb8, 0xe9, 0x01, 0x23, 0x7c, 0x41, 0x09, 0x6c, 0xfb, 0x25,
+ 0x75, 0x70, 0xe3, 0x61, 0x15, 0x1f, 0x1b, 0x5a, 0x86, 0x4c, 0x28, 0x8a,
+ 0x3d, 0x4b, 0x54, 0xdc, 0x70, 0xf0, 0x24, 0x71, 0xff, 0xac, 0xcd, 0x93,
+ 0x73, 0x99, 0x2f, 0x22, 0x38, 0x20, 0x6b, 0xf7, 0x6e, 0xc6, 0xef, 0x4a,
+ 0x9c, 0x19, 0xec, 0xa6, 0xdf, 0x56, 0xe2, 0x54, 0xfa, 0x24, 0xed, 0xb1,
+ 0x12, 0x8f, 0x0f, 0x1a, 0x93, 0x3f, 0x71, 0x54, 0xe2, 0x31, 0x9e, 0x0f,
+ 0xf1, 0x7c, 0xf1, 0xb0, 0x31, 0xd8, 0xa5, 0x56, 0x62, 0xd1, 0xa1, 0x66,
+ 0x0c, 0x26, 0xc5, 0x36, 0x35, 0x6c, 0x1b, 0x6f, 0x2a, 0xe8, 0x5e, 0x74,
+ 0xee, 0xc5, 0x3d, 0xd4, 0xd5, 0xdd, 0x43, 0xdd, 0xec, 0xcf, 0x47, 0x9d,
+ 0x9f, 0xc4, 0x43, 0xcc, 0xeb, 0x76, 0x27, 0x7d, 0x38, 0x9f, 0x32, 0xfc,
+ 0x9f, 0x52, 0x0c, 0xb3, 0x4c, 0x09, 0x68, 0x67, 0xe0, 0xc3, 0x2b, 0xd9,
+ 0x72, 0xf4, 0x0e, 0xd7, 0xe1, 0x27, 0xb4, 0xcf, 0x07, 0xf7, 0x9d, 0xb4,
+ 0xed, 0xff, 0x40, 0x6a, 0x2e, 0x1e, 0x1b, 0x33, 0xd9, 0xb6, 0xcc, 0x93,
+ 0xc3, 0xde, 0xdb, 0xe4, 0x4a, 0x89, 0x6f, 0x44, 0x87, 0x68, 0x16, 0xc4,
+ 0xc4, 0x93, 0xc8, 0x0e, 0xea, 0xfd, 0x37, 0xab, 0xc2, 0xab, 0x55, 0xea,
+ 0xd2, 0x81, 0x29, 0x4d, 0x8f, 0xd7, 0xa8, 0xf1, 0x41, 0xe6, 0xaf, 0xf1,
+ 0x5a, 0xea, 0xe4, 0xb1, 0x41, 0x27, 0x16, 0x2c, 0x56, 0x79, 0x3d, 0x7e,
+ 0x91, 0xb1, 0x2d, 0x3e, 0x4f, 0x35, 0x71, 0xc0, 0x96, 0x15, 0xf1, 0x12,
+ 0x72, 0xfb, 0xea, 0xc5, 0xf5, 0x8c, 0x5f, 0x0e, 0xb1, 0xbd, 0x58, 0xa5,
+ 0xea, 0xa4, 0xde, 0x5f, 0xc1, 0x18, 0xed, 0xfa, 0x11, 0x1e, 0xc7, 0x47,
+ 0xac, 0xee, 0x55, 0xe4, 0xdc, 0xf3, 0x03, 0x56, 0xf7, 0xcd, 0xa6, 0xe1,
+ 0x2b, 0x51, 0x03, 0xd1, 0x2f, 0xe0, 0x15, 0x1c, 0x1b, 0x93, 0x32, 0xb2,
+ 0x0f, 0x24, 0x86, 0x91, 0xa4, 0xd5, 0x3d, 0x64, 0xce, 0x47, 0xb3, 0x9d,
+ 0x1b, 0xbb, 0x2a, 0xf3, 0x98, 0x29, 0x7e, 0x24, 0x6b, 0x25, 0x53, 0xf8,
+ 0x25, 0xdb, 0xb9, 0x30, 0x52, 0x8d, 0x19, 0xb5, 0xe2, 0x07, 0x67, 0xf1,
+ 0xc6, 0xe0, 0x77, 0x71, 0x7e, 0xd0, 0xc2, 0xa2, 0x90, 0x05, 0x67, 0xa8,
+ 0xd1, 0x6c, 0x55, 0x97, 0x12, 0x23, 0x14, 0xac, 0x6e, 0xf8, 0x1e, 0xde,
+ 0x1a, 0x94, 0xfd, 0xa6, 0x96, 0x2d, 0xcb, 0x00, 0x16, 0x5b, 0x7b, 0x66,
+ 0x8a, 0xdf, 0x48, 0xbd, 0x3f, 0x95, 0x07, 0xeb, 0x8c, 0x86, 0xc5, 0x5c,
+ 0xf8, 0x15, 0x8c, 0x8e, 0x18, 0xd1, 0xcd, 0x45, 0x39, 0x07, 0x5f, 0xa1,
+ 0x0e, 0xec, 0xf8, 0x74, 0xb0, 0x06, 0x0b, 0x2e, 0x32, 0x6b, 0xfc, 0xf0,
+ 0x3c, 0xda, 0xce, 0xa2, 0xc5, 0x01, 0x73, 0xa5, 0xfa, 0x6f, 0xf4, 0xd3,
+ 0x57, 0x70, 0x24, 0x5d, 0xc4, 0x6b, 0x1f, 0x5a, 0xe9, 0xe7, 0xf9, 0x7d,
+ 0xfe, 0x5e, 0xb4, 0xa4, 0x4e, 0xd8, 0xeb, 0x0f, 0xc7, 0x89, 0x8f, 0x83,
+ 0x29, 0x29, 0xa3, 0x61, 0x2c, 0xdb, 0x4a, 0x6c, 0x88, 0xe2, 0x9f, 0xb2,
+ 0x11, 0xe2, 0x43, 0x98, 0xf8, 0xd0, 0x4c, 0x7c, 0x30, 0x89, 0x0f, 0x4d,
+ 0xc4, 0x87, 0x20, 0xf1, 0xc1, 0xb0, 0xd7, 0xd6, 0xd3, 0x47, 0xbf, 0x8b,
+ 0x92, 0xe1, 0xb3, 0x70, 0xd1, 0x07, 0xce, 0x98, 0x16, 0xf9, 0x49, 0xa3,
+ 0xb6, 0x11, 0xf3, 0x95, 0xa8, 0xe6, 0x45, 0x9a, 0xed, 0x95, 0x0d, 0x6b,
+ 0x1c, 0x8b, 0x85, 0x60, 0xa8, 0x3e, 0xdc, 0x4f, 0xac, 0xfe, 0x95, 0xd1,
+ 0xd8, 0xef, 0x45, 0xe3, 0x81, 0x99, 0x30, 0x06, 0x17, 0xab, 0x0d, 0x4a,
+ 0xf4, 0xe3, 0x5e, 0x8e, 0xb3, 0x16, 0x73, 0xf7, 0x69, 0x98, 0xc7, 0xe3,
+ 0x1f, 0x53, 0xf5, 0x93, 0x2f, 0x3b, 0xe0, 0x9d, 0x4d, 0xba, 0x33, 0x87,
+ 0x4c, 0x80, 0xac, 0xd6, 0xeb, 0xc3, 0x95, 0xc7, 0x5f, 0x51, 0x15, 0xe4,
+ 0x3e, 0x2e, 0x31, 0xaf, 0x31, 0xd8, 0xa7, 0xaa, 0xb2, 0x96, 0x44, 0x0c,
+ 0xe7, 0xa1, 0x22, 0x42, 0x16, 0x51, 0xc7, 0xfc, 0xc2, 0xda, 0x68, 0x96,
+ 0x61, 0x47, 0x13, 0x39, 0xa7, 0x57, 0x3f, 0x21, 0x31, 0x6a, 0x36, 0x63,
+ 0x44, 0x79, 0x32, 0x7e, 0xe7, 0x6c, 0x78, 0x50, 0x96, 0xb4, 0xac, 0xaf,
+ 0x86, 0x34, 0x78, 0x22, 0x81, 0xe8, 0x56, 0xa6, 0x91, 0x1f, 0x5f, 0x10,
+ 0xc6, 0xea, 0xec, 0x09, 0x0c, 0x73, 0x7c, 0xab, 0xb2, 0xc5, 0x67, 0xc5,
+ 0xfe, 0xf8, 0xe7, 0xf2, 0x33, 0x67, 0x57, 0x1e, 0x98, 0x0d, 0x43, 0xbb,
+ 0x57, 0x1d, 0xae, 0x22, 0x07, 0x3f, 0xce, 0xb8, 0xa7, 0x4c, 0x7d, 0x42,
+ 0x41, 0xc7, 0x70, 0x1c, 0x33, 0x42, 0x2f, 0x28, 0xb1, 0x5a, 0xdd, 0xef,
+ 0x57, 0x6a, 0xf1, 0x89, 0x7d, 0xd4, 0xf5, 0xa2, 0x1f, 0x7a, 0xe4, 0xb9,
+ 0xb0, 0x6f, 0x1e, 0x15, 0xdd, 0xd6, 0xa7, 0x87, 0x38, 0x8e, 0xc9, 0x86,
+ 0x13, 0x82, 0x93, 0x8f, 0xba, 0xe1, 0x78, 0x74, 0x16, 0xa2, 0x68, 0x6a,
+ 0xb8, 0xb2, 0xeb, 0x5f, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0x7d, 0x30, 0xae,
+ 0x18, 0xda, 0xcf, 0x95, 0x13, 0xf6, 0x7d, 0xb8, 0xaf, 0x66, 0x4f, 0x52,
+ 0x97, 0xc7, 0x0b, 0xf9, 0xd2, 0x3a, 0x24, 0x06, 0x64, 0x5f, 0xfe, 0x59,
+ 0xcc, 0x1d, 0xd6, 0xdb, 0x77, 0x29, 0x46, 0xf0, 0x06, 0xe5, 0x2c, 0xe6,
+ 0x0c, 0x07, 0x39, 0x97, 0x1a, 0x56, 0x26, 0x8b, 0xf8, 0x29, 0x18, 0xbc,
+ 0x8e, 0x18, 0x6c, 0x2d, 0xfb, 0x89, 0x19, 0xd7, 0x65, 0x4f, 0x82, 0x53,
+ 0xd1, 0x3b, 0x1a, 0x94, 0x38, 0x63, 0xa8, 0x71, 0x71, 0x3d, 0xeb, 0x78,
+ 0x86, 0x9b, 0x70, 0x3b, 0xc7, 0xdc, 0xc6, 0x79, 0xfb, 0xee, 0x62, 0x0b,
+ 0x4b, 0x16, 0xeb, 0x07, 0xca, 0x1c, 0xd1, 0x7b, 0x6b, 0x90, 0xeb, 0x9a,
+ 0x49, 0xbb, 0xb9, 0x7b, 0x91, 0x1e, 0x7e, 0x81, 0xb8, 0x4b, 0x9c, 0x46,
+ 0x2f, 0xe3, 0xce, 0x46, 0xc6, 0xa2, 0xf2, 0x88, 0xde, 0xcf, 0x1c, 0xf5,
+ 0xc2, 0x1d, 0x8e, 0x68, 0x48, 0x9e, 0xff, 0xf8, 0x32, 0x96, 0xc1, 0x1d,
+ 0xaa, 0x22, 0x0e, 0xea, 0xb9, 0xef, 0x42, 0x3f, 0x70, 0x3b, 0xfa, 0xf1,
+ 0x03, 0xf2, 0xbb, 0x99, 0x57, 0xe5, 0x88, 0x51, 0x19, 0x3c, 0x98, 0x3d,
+ 0x89, 0x03, 0xd9, 0x47, 0xb1, 0x37, 0xbb, 0x5b, 0x49, 0xdb, 0xf7, 0x20,
+ 0x15, 0x79, 0xee, 0x26, 0x5a, 0xa5, 0x7c, 0x06, 0x95, 0xa1, 0xaf, 0x5b,
+ 0xe9, 0x1a, 0x15, 0xd5, 0xa1, 0x20, 0x56, 0x27, 0xe3, 0x70, 0x44, 0xde,
+ 0xb6, 0xe4, 0xb9, 0xcf, 0x2d, 0x13, 0x06, 0xae, 0x4f, 0x96, 0x23, 0x76,
+ 0xc8, 0xb2, 0xfa, 0x9b, 0x9d, 0xd8, 0x34, 0xd1, 0x84, 0x95, 0xc3, 0x0f,
+ 0x59, 0xf3, 0x18, 0x73, 0xde, 0xbd, 0xc6, 0x83, 0x3b, 0x0e, 0x79, 0xb0,
+ 0x3e, 0x19, 0x85, 0x2f, 0x52, 0xc1, 0xdf, 0x01, 0x73, 0x39, 0x8c, 0xc9,
+ 0x49, 0x18, 0xfd, 0xd7, 0x39, 0x02, 0xc7, 0xc2, 0xaa, 0x07, 0x7f, 0x4d,
+ 0x1c, 0x5f, 0x45, 0xdc, 0x89, 0x4d, 0x58, 0xa8, 0x8e, 0x78, 0x71, 0x27,
+ 0xeb, 0x7f, 0x8c, 0x73, 0xff, 0xd6, 0x92, 0xe3, 0xc4, 0x02, 0x23, 0x36,
+ 0xa1, 0x68, 0xd8, 0x3a, 0xe1, 0xa6, 0xae, 0xdc, 0x88, 0x1d, 0xa9, 0xc5,
+ 0xf5, 0xfb, 0xfc, 0xb8, 0x63, 0xc2, 0x83, 0x96, 0xa4, 0xb5, 0xec, 0xb8,
+ 0x19, 0x5f, 0xab, 0xc1, 0xc0, 0xfa, 0x09, 0x2f, 0x6e, 0x4b, 0xea, 0xbe,
+ 0x1b, 0x98, 0xf3, 0x8f, 0x99, 0x41, 0xfc, 0xed, 0x84, 0x0f, 0xb7, 0x24,
+ 0x4f, 0x49, 0x1e, 0xb9, 0xdc, 0xc9, 0xd8, 0x73, 0xff, 0x44, 0x1d, 0xd6,
+ 0x26, 0xf5, 0x8b, 0x93, 0xe4, 0x76, 0xdd, 0x47, 0x4c, 0xdc, 0x3b, 0xa1,
+ 0xa2, 0x83, 0xed, 0x7c, 0x22, 0x39, 0x17, 0x5d, 0x47, 0x9a, 0x29, 0xc3,
+ 0x62, 0xac, 0x1a, 0x76, 0xc2, 0x24, 0x8b, 0xc7, 0x27, 0x81, 0x76, 0xfa,
+ 0x47, 0x22, 0xf5, 0x45, 0xec, 0x19, 0x30, 0x71, 0xd7, 0x84, 0x9c, 0x9f,
+ 0xb4, 0x9f, 0x95, 0xbb, 0x70, 0x70, 0x31, 0x6e, 0x1c, 0x56, 0x89, 0x03,
+ 0xa5, 0x48, 0xaf, 0x55, 0x70, 0x1b, 0xaf, 0xef, 0x4a, 0xd9, 0x7b, 0xab,
+ 0x11, 0x1a, 0x0a, 0x1c, 0xab, 0x21, 0x67, 0x58, 0x72, 0x30, 0x7f, 0xfd,
+ 0x41, 0xe2, 0x7c, 0x19, 0x71, 0xbe, 0x82, 0x1c, 0xf6, 0xba, 0xd1, 0x93,
+ 0x78, 0x80, 0xb8, 0x7c, 0x62, 0xb8, 0x9b, 0x71, 0xa7, 0x12, 0x5f, 0x63,
+ 0x1c, 0x48, 0xf2, 0xfc, 0xec, 0x90, 0xd1, 0x55, 0x46, 0x9c, 0x7e, 0x81,
+ 0xf8, 0xdb, 0x4f, 0xcc, 0xb8, 0x3b, 0x49, 0xb7, 0x1f, 0x62, 0x0e, 0x70,
+ 0x55, 0x74, 0xa1, 0x87, 0x39, 0xd6, 0x0d, 0x4a, 0xc0, 0xf7, 0x1a, 0x2a,
+ 0xe1, 0x38, 0x58, 0x8b, 0x96, 0x7d, 0x52, 0x46, 0xf0, 0x4b, 0x85, 0x7a,
+ 0xd8, 0x49, 0x9d, 0x9f, 0x84, 0x35, 0xe8, 0xe0, 0x78, 0xeb, 0x4d, 0x32,
+ 0x70, 0xfc, 0xd8, 0xd4, 0xb5, 0x7f, 0x22, 0xd6, 0xbe, 0x43, 0x4c, 0xf5,
+ 0xcf, 0x6e, 0x46, 0xab, 0x61, 0xf2, 0x38, 0x89, 0x57, 0x06, 0x0d, 0xf3,
+ 0x10, 0x9c, 0x78, 0x99, 0x3c, 0x6f, 0x6a, 0x36, 0x63, 0xa6, 0x21, 0x7e,
+ 0x98, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x07, 0xde, 0x38, 0xb8,
+ 0x8c, 0xe3, 0x92, 0x58, 0x2a, 0xf1, 0x2e, 0x43, 0x59, 0x97, 0x61, 0x0d,
+ 0xf5, 0xd1, 0x9a, 0x54, 0x91, 0x39, 0x12, 0xc1, 0x5d, 0xfb, 0xf3, 0x71,
+ 0x78, 0x5b, 0x28, 0x7e, 0x33, 0xe3, 0x70, 0xb8, 0x9c, 0x71, 0xd8, 0x15,
+ 0x11, 0xd9, 0x9c, 0x18, 0x65, 0xdc, 0xde, 0x91, 0x0a, 0xa3, 0x8d, 0x73,
+ 0x38, 0x99, 0x61, 0xbf, 0xc9, 0x3a, 0x9c, 0xc9, 0x78, 0x18, 0xb3, 0x34,
+ 0x1e, 0x44, 0xb5, 0xb1, 0x59, 0x3c, 0xfc, 0x3c, 0xe6, 0xf3, 0x30, 0xec,
+ 0x6b, 0x1b, 0x93, 0x0a, 0xe2, 0xed, 0x8a, 0xcd, 0xe7, 0xcf, 0x64, 0x04,
+ 0x9b, 0x65, 0x2d, 0x73, 0x7b, 0x95, 0x3c, 0x8b, 0x32, 0x98, 0xfa, 0x1e,
+ 0xaa, 0xa9, 0xff, 0xaa, 0x02, 0x0e, 0xfd, 0x34, 0x24, 0xb8, 0x5b, 0x4f,
+ 0xdc, 0x95, 0xe7, 0x04, 0x2c, 0x6b, 0x5d, 0x60, 0x3a, 0x1e, 0xfd, 0x9f,
+ 0x77, 0xa3, 0xf6, 0x33, 0x17, 0x82, 0x49, 0xc4, 0xbf, 0x14, 0xf1, 0x8f,
+ 0x63, 0xe8, 0xb9, 0x96, 0x18, 0x48, 0x99, 0xfe, 0x21, 0x45, 0x0c, 0x24,
+ 0x4e, 0x3f, 0x4a, 0x9c, 0xfe, 0x06, 0x71, 0xfa, 0xeb, 0xc4, 0xe9, 0xaf,
+ 0x11, 0x13, 0xf2, 0x6b, 0x7a, 0x6d, 0x72, 0xff, 0x85, 0xf3, 0xf1, 0x96,
+ 0xbd, 0xb6, 0x38, 0x93, 0xba, 0x9a, 0x3b, 0xac, 0x60, 0x9e, 0xa1, 0x1f,
+ 0x13, 0xbb, 0xff, 0x01, 0xe7, 0xc9, 0x3f, 0xa3, 0xce, 0x7e, 0x26, 0xa6,
+ 0x35, 0xd9, 0x07, 0x77, 0xb2, 0x51, 0xeb, 0x87, 0xfd, 0x2c, 0xb2, 0x29,
+ 0x5c, 0xb4, 0x24, 0xb9, 0x11, 0x8e, 0x64, 0xe3, 0xb1, 0xd3, 0x72, 0x9f,
+ 0x77, 0x96, 0xe4, 0xf5, 0x1b, 0xe1, 0x4c, 0xea, 0xc7, 0xe2, 0x94, 0x65,
+ 0x25, 0xff, 0x73, 0x25, 0x1b, 0xcd, 0xd7, 0x60, 0x63, 0x9b, 0x7f, 0xca,
+ 0xfe, 0xaf, 0xfe, 0xc2, 0x03, 0xd4, 0x57, 0x8e, 0x6d, 0x66, 0xa8, 0xfb,
+ 0x72, 0xf2, 0x95, 0x47, 0xb2, 0xf2, 0xbb, 0xb1, 0x23, 0xa1, 0x1e, 0x43,
+ 0x6c, 0xa6, 0xf0, 0xf1, 0x30, 0x6e, 0x4a, 0x7a, 0x68, 0x07, 0x71, 0x54,
+ 0xd1, 0xb7, 0x3e, 0x37, 0xd1, 0x4c, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81,
+ 0x8e, 0x09, 0x72, 0x9e, 0x2d, 0x13, 0xcb, 0xb0, 0x62, 0xd8, 0xb2, 0x3c,
+ 0x4b, 0x8d, 0xf0, 0x56, 0xc5, 0x0f, 0x17, 0x7d, 0xd0, 0x41, 0xbf, 0xda,
+ 0x7c, 0x28, 0xa0, 0xbd, 0x46, 0x3c, 0xed, 0x6c, 0x3e, 0x41, 0xfb, 0x30,
+ 0x2e, 0xb6, 0x11, 0x4b, 0x9d, 0x91, 0x00, 0xf3, 0x44, 0x0f, 0x6d, 0xdf,
+ 0x8b, 0x8b, 0x09, 0xf1, 0x2f, 0xbd, 0xeb, 0x9f, 0x98, 0x9b, 0x74, 0xd1,
+ 0x37, 0x7e, 0x9e, 0xa8, 0xa3, 0x0f, 0xb8, 0xf1, 0x46, 0xc2, 0xa0, 0xbf,
+ 0x79, 0xf0, 0x56, 0xa2, 0x89, 0x7d, 0x05, 0x59, 0xc6, 0x8f, 0x7b, 0x26,
+ 0xc2, 0xf4, 0xb3, 0x6b, 0x79, 0xc8, 0x73, 0x99, 0xf5, 0xf1, 0x6f, 0x2a,
+ 0xf5, 0x83, 0x73, 0xd5, 0x1a, 0x44, 0x6b, 0x35, 0x7c, 0x7e, 0xe2, 0x23,
+ 0xf8, 0x57, 0xc6, 0xed, 0x4d, 0x49, 0x70, 0x0e, 0x11, 0x22, 0x0f, 0x9c,
+ 0x3c, 0x22, 0xf7, 0x1c, 0xd1, 0x18, 0x6d, 0x70, 0xe8, 0xcc, 0x6d, 0xf5,
+ 0xdc, 0x79, 0x87, 0x93, 0x7d, 0x92, 0x15, 0xb3, 0xec, 0xcf, 0x07, 0xcb,
+ 0x71, 0xef, 0xa1, 0x13, 0xf4, 0x91, 0x12, 0x2c, 0x7a, 0xc0, 0x8d, 0xcf,
+ 0x1f, 0xc9, 0x90, 0x3b, 0xa8, 0x90, 0xfd, 0xbc, 0x69, 0x12, 0x85, 0x39,
+ 0xa3, 0x11, 0xdc, 0xb9, 0x3f, 0x83, 0xe1, 0x02, 0xcf, 0x0b, 0x85, 0xe2,
+ 0xff, 0x43, 0xc5, 0x09, 0xf2, 0x88, 0x40, 0xe7, 0xd5, 0xb4, 0xb1, 0xaa,
+ 0x48, 0x20, 0x2e, 0xe3, 0x6e, 0xa7, 0x8d, 0xf5, 0x71, 0x3e, 0x33, 0x1c,
+ 0x47, 0x82, 0x36, 0xf6, 0x55, 0xca, 0xbf, 0x87, 0x36, 0x16, 0xa7, 0x8d,
+ 0xc5, 0x69, 0x4f, 0x71, 0xda, 0x98, 0x3c, 0xfb, 0x1b, 0xa7, 0x8d, 0xc5,
+ 0x69, 0x63, 0xf1, 0xcc, 0x32, 0x1c, 0x25, 0xd3, 0xd8, 0x39, 0xd6, 0x4c,
+ 0x1c, 0x53, 0xec, 0xa8, 0x94, 0xbb, 0xf9, 0x23, 0xe4, 0xec, 0xd7, 0xf1,
+ 0x50, 0xd0, 0x46, 0x9f, 0xec, 0x4f, 0x67, 0xc8, 0x79, 0xdc, 0xf8, 0x75,
+ 0x56, 0x38, 0x7e, 0x33, 0xf3, 0xd8, 0x93, 0xe4, 0xf9, 0x2a, 0x9e, 0x30,
+ 0x25, 0x0f, 0x36, 0x79, 0xce, 0x58, 0x93, 0x12, 0xbe, 0x76, 0x12, 0x77,
+ 0x0f, 0x02, 0x37, 0x90, 0x17, 0xd6, 0x92, 0x97, 0x1c, 0x5e, 0xc4, 0xdf,
+ 0x07, 0x4f, 0xd0, 0xe6, 0x4f, 0xda, 0x7b, 0xbb, 0x54, 0xb6, 0x75, 0x66,
+ 0xb0, 0xde, 0x77, 0x3d, 0x7d, 0xf0, 0x7e, 0xd6, 0x75, 0x1e, 0x94, 0x3a,
+ 0x27, 0xd8, 0xb6, 0x1e, 0xfe, 0x35, 0xe7, 0xbf, 0xe3, 0x81, 0x5a, 0xbc,
+ 0xb1, 0x5f, 0x0f, 0xbf, 0x43, 0xcc, 0xab, 0x75, 0x58, 0xcb, 0xae, 0x0e,
+ 0x05, 0xb6, 0x5d, 0xad, 0xe6, 0xf9, 0x5e, 0xfb, 0x90, 0x13, 0xc7, 0x42,
+ 0xcb, 0xe0, 0x59, 0x54, 0xe4, 0x7c, 0xb4, 0xa5, 0x5a, 0xe1, 0x58, 0x7a,
+ 0xf8, 0x3c, 0xb9, 0x4a, 0x92, 0xed, 0x1f, 0xcd, 0x3c, 0x4e, 0x0c, 0xf9,
+ 0x22, 0x9e, 0x63, 0x7e, 0x3e, 0xf6, 0xa1, 0x97, 0xc9, 0x1d, 0xdd, 0x18,
+ 0x27, 0x07, 0x3c, 0x3e, 0x18, 0xfd, 0xa8, 0x93, 0xb8, 0xef, 0x59, 0x54,
+ 0x89, 0x4c, 0x5a, 0xb8, 0x62, 0x25, 0x9e, 0x19, 0x34, 0xb4, 0x1b, 0x94,
+ 0x3c, 0x2f, 0xcc, 0xef, 0xfd, 0x32, 0x2e, 0x8e, 0x22, 0x30, 0x79, 0x9e,
+ 0xdc, 0xf0, 0x9d, 0xb4, 0xc4, 0xb0, 0x93, 0xf4, 0x71, 0x3f, 0xc2, 0x49,
+ 0x0d, 0x27, 0xc6, 0x0d, 0x2c, 0x4c, 0x7a, 0xf1, 0xf0, 0x78, 0x10, 0x57,
+ 0xd3, 0x77, 0xb3, 0xe4, 0x87, 0x1f, 0x4a, 0x8a, 0x2f, 0xd6, 0x61, 0x62,
+ 0xbc, 0x8e, 0x3e, 0x22, 0xbc, 0xfc, 0x67, 0xf0, 0xd4, 0x9e, 0xb5, 0xf7,
+ 0x36, 0x8f, 0xa6, 0xf4, 0xfe, 0x18, 0xc7, 0x13, 0xf3, 0xea, 0xc7, 0x62,
+ 0xd0, 0xd3, 0xc0, 0x87, 0xdf, 0x4d, 0x7f, 0x52, 0xe2, 0xa3, 0xf8, 0xa3,
+ 0x86, 0x09, 0xf2, 0x9d, 0x52, 0x62, 0x6a, 0x79, 0xa4, 0xfe, 0xc2, 0xf7,
+ 0x15, 0x3d, 0xf7, 0x94, 0x6a, 0x59, 0xdf, 0x5b, 0xac, 0xc1, 0x77, 0x44,
+ 0x23, 0xf7, 0x30, 0xed, 0xe7, 0x62, 0xe4, 0x79, 0xf3, 0xd9, 0xfb, 0x6a,
+ 0x31, 0x63, 0x5f, 0x12, 0xff, 0xad, 0x36, 0xfe, 0xd1, 0x59, 0x8c, 0xf3,
+ 0xb3, 0x64, 0x7f, 0x76, 0xf2, 0xf4, 0x6c, 0xb9, 0x57, 0x34, 0xa9, 0x36,
+ 0x76, 0x1c, 0x83, 0x7e, 0xec, 0x15, 0x45, 0xf7, 0x7d, 0x95, 0xb1, 0xc1,
+ 0x45, 0x1b, 0x75, 0x4c, 0x68, 0xf4, 0xdd, 0xc6, 0x13, 0x33, 0x60, 0xc4,
+ 0xaf, 0x51, 0x5d, 0x16, 0x6c, 0x79, 0x6e, 0xa8, 0xca, 0xe7, 0x45, 0x82,
+ 0x3b, 0x12, 0x17, 0xc8, 0x17, 0x89, 0xc1, 0x9d, 0xf4, 0x97, 0x35, 0x76,
+ 0x2c, 0x3a, 0x61, 0xef, 0xfd, 0xde, 0x3a, 0x11, 0xa7, 0x8f, 0x2c, 0x43,
+ 0xc5, 0xb0, 0x07, 0x9f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x0d, 0xfd, 0xe5,
+ 0xae, 0x43, 0x81, 0xce, 0xeb, 0xe9, 0x2f, 0xf5, 0x4b, 0x25, 0x86, 0x31,
+ 0x6e, 0xa7, 0x0c, 0x73, 0x94, 0xd8, 0xf2, 0x50, 0xb3, 0x31, 0xf9, 0x32,
+ 0xf2, 0x3e, 0xb3, 0x6b, 0xa0, 0x16, 0x7f, 0xff, 0xc0, 0x71, 0x7b, 0x2d,
+ 0xe4, 0x4e, 0x9e, 0x27, 0x07, 0x7c, 0xb6, 0x7f, 0xc4, 0xf8, 0xfb, 0x1e,
+ 0xc6, 0xbc, 0x18, 0xfd, 0x68, 0xe7, 0x80, 0xb5, 0xec, 0xf9, 0xc5, 0xf1,
+ 0xb5, 0x55, 0x08, 0x32, 0x26, 0xb9, 0xd1, 0x3f, 0xa0, 0x0f, 0x76, 0x30,
+ 0x06, 0x9d, 0x5d, 0x6c, 0x52, 0x16, 0x0f, 0x86, 0x06, 0x04, 0x53, 0x4f,
+ 0xdd, 0x52, 0x8b, 0xf8, 0xff, 0xd0, 0x38, 0xbe, 0xcf, 0xd9, 0xf7, 0x08,
+ 0xeb, 0xb0, 0xe9, 0xc8, 0x52, 0xca, 0xdc, 0x44, 0x1f, 0x64, 0x5e, 0xcd,
+ 0x7c, 0x67, 0xc3, 0x7e, 0xf1, 0x0b, 0xb4, 0x48, 0x9e, 0xd6, 0x6d, 0x06,
+ 0xcc, 0x57, 0xe9, 0x43, 0x25, 0xe4, 0x3a, 0x0f, 0xa6, 0xec, 0xe7, 0x73,
+ 0x72, 0x15, 0x46, 0x18, 0x8b, 0x69, 0xa3, 0x25, 0x86, 0x0f, 0x33, 0xc8,
+ 0xeb, 0x16, 0x72, 0x3e, 0xca, 0xb2, 0x1e, 0x80, 0x1c, 0x02, 0xc4, 0x27,
+ 0x1c, 0x25, 0x08, 0x1e, 0xf5, 0xf3, 0x98, 0xcf, 0x83, 0x8a, 0xc8, 0xaa,
+ 0x98, 0x79, 0x94, 0x75, 0x47, 0x33, 0xb6, 0x2d, 0xfe, 0x3d, 0xe7, 0x3d,
+ 0x41, 0x5b, 0xff, 0x04, 0xb1, 0x7e, 0x72, 0x2f, 0xd0, 0x7f, 0x30, 0x6f,
+ 0xdb, 0x29, 0xb6, 0xdf, 0x4e, 0xcc, 0xbb, 0x40, 0x9b, 0xed, 0xe3, 0x7c,
+ 0x0f, 0x8d, 0x18, 0xc1, 0x46, 0x35, 0xa0, 0x4d, 0x70, 0x9e, 0x7b, 0xc6,
+ 0x54, 0x0c, 0x0c, 0x2e, 0xc3, 0x28, 0xf3, 0xa0, 0xde, 0xb4, 0xf8, 0x88,
+ 0x94, 0x39, 0x89, 0x6e, 0xfa, 0xc8, 0x2f, 0x17, 0x2b, 0x88, 0x7d, 0x5c,
+ 0xf6, 0xbe, 0x3b, 0x99, 0xef, 0x7f, 0x11, 0x9b, 0x12, 0x8f, 0x5b, 0x95,
+ 0x86, 0xde, 0x9f, 0x56, 0x99, 0x67, 0xd1, 0x36, 0x7b, 0x98, 0x9f, 0x2c,
+ 0x67, 0x7e, 0xd2, 0x5b, 0xb0, 0xcb, 0x33, 0xb4, 0xc3, 0x01, 0xc6, 0xb1,
+ 0x97, 0xd3, 0xf9, 0xb8, 0xf7, 0x83, 0x21, 0x3f, 0x16, 0x5e, 0x53, 0x89,
+ 0xa7, 0x0f, 0xe6, 0x65, 0xdb, 0x4b, 0x9b, 0x7c, 0x8a, 0x7a, 0xbe, 0x83,
+ 0x7a, 0x7d, 0x29, 0x25, 0x18, 0x15, 0xc4, 0x33, 0xe4, 0xd1, 0x5b, 0xc8,
+ 0x05, 0xbe, 0x97, 0xca, 0xdb, 0xe4, 0xe7, 0x27, 0xd6, 0x68, 0xf9, 0xf8,
+ 0xe0, 0x85, 0xba, 0x4f, 0xf6, 0x00, 0x5a, 0xd6, 0x72, 0x33, 0xd7, 0x49,
+ 0x5e, 0xc3, 0xb6, 0x23, 0xe4, 0x46, 0x4e, 0xcc, 0x49, 0x46, 0xb0, 0x22,
+ 0x55, 0xdf, 0xd6, 0x20, 0x9b, 0x3d, 0xe6, 0xe4, 0x39, 0xa0, 0x2b, 0x29,
+ 0xef, 0x0e, 0xd0, 0x50, 0xc1, 0xdc, 0xe9, 0xaf, 0x0b, 0xef, 0x2b, 0xf8,
+ 0xc4, 0x9f, 0xc1, 0x1d, 0xd7, 0x50, 0xa6, 0x14, 0xb9, 0xe3, 0x54, 0xe1,
+ 0x7d, 0x05, 0x37, 0xdb, 0xef, 0x2b, 0x70, 0x63, 0xc6, 0x84, 0xd3, 0xf9,
+ 0xa9, 0x94, 0x07, 0xb3, 0x27, 0x2e, 0x71, 0x50, 0x77, 0x49, 0xa4, 0x15,
+ 0x4f, 0x26, 0x14, 0xcc, 0x32, 0xfe, 0x27, 0xbe, 0x6f, 0xaf, 0x09, 0xd4,
+ 0xda, 0x7b, 0xf6, 0x5d, 0x91, 0x28, 0x0e, 0x27, 0xf4, 0xb6, 0xc7, 0x78,
+ 0x5e, 0x46, 0x3c, 0xad, 0xda, 0xa7, 0xe0, 0xa9, 0x80, 0x17, 0xa5, 0x47,
+ 0x64, 0xaf, 0xbb, 0x65, 0x39, 0x17, 0xaf, 0xb2, 0x76, 0xac, 0x13, 0xfb,
+ 0xe6, 0x1c, 0x1e, 0x09, 0x54, 0x09, 0x06, 0x1e, 0x36, 0x65, 0xdd, 0xd2,
+ 0x40, 0x5f, 0xa2, 0x96, 0xfc, 0xba, 0xbe, 0xb3, 0x15, 0xf5, 0xe6, 0xcf,
+ 0x1c, 0xb5, 0x28, 0x39, 0x72, 0x87, 0x26, 0x6b, 0xf6, 0xdf, 0xe0, 0x9c,
+ 0xf5, 0x12, 0xbb, 0x7a, 0x52, 0xf9, 0xf8, 0xd9, 0x9a, 0xb1, 0xaa, 0x45,
+ 0x2f, 0xbd, 0xe4, 0x27, 0x6a, 0xf2, 0xa2, 0x5d, 0xa6, 0x22, 0x92, 0x23,
+ 0xfe, 0xd4, 0xe1, 0x04, 0xf9, 0x82, 0xc4, 0xd2, 0x0a, 0x1e, 0x95, 0xe4,
+ 0x8d, 0x3f, 0x67, 0x2c, 0xbd, 0x27, 0x94, 0x0b, 0xca, 0x9b, 0x2c, 0x6a,
+ 0xc8, 0xc5, 0xe9, 0x03, 0x38, 0x12, 0xd2, 0xdb, 0x37, 0x38, 0xa2, 0x4f,
+ 0x33, 0x07, 0x0b, 0x2f, 0x63, 0x4e, 0xbe, 0x2a, 0x90, 0xc1, 0x2e, 0xf2,
+ 0xc0, 0x9d, 0xcc, 0xc5, 0x3b, 0x68, 0x9b, 0x9d, 0xfb, 0x19, 0xdb, 0x1c,
+ 0x97, 0x73, 0x71, 0x2d, 0x14, 0xdf, 0x40, 0x0e, 0xd0, 0xe5, 0x51, 0xc5,
+ 0x5e, 0xc5, 0x77, 0x02, 0x1d, 0xaf, 0x12, 0xa3, 0x1b, 0x19, 0x37, 0xc4,
+ 0xde, 0xf7, 0xa4, 0xf4, 0x4e, 0x2a, 0xa0, 0xa6, 0x92, 0xb9, 0xe3, 0xbd,
+ 0xe3, 0xcd, 0xf4, 0x9b, 0xfc, 0x33, 0x73, 0xce, 0x25, 0x75, 0xcc, 0x39,
+ 0xaf, 0x43, 0xef, 0x10, 0xed, 0x9f, 0xbe, 0x74, 0xff, 0x00, 0xc8, 0xcf,
+ 0xd4, 0x9d, 0x9c, 0xbf, 0xdc, 0x11, 0x04, 0x2e, 0xb6, 0xa3, 0xb1, 0xad,
+ 0xc4, 0x21, 0x32, 0xe8, 0xed, 0x6f, 0x90, 0xa7, 0x75, 0x31, 0x3f, 0xdd,
+ 0xc2, 0x5c, 0x3e, 0xc6, 0x5c, 0x3e, 0xc6, 0x7a, 0xa9, 0x21, 0xb9, 0x4f,
+ 0x64, 0xb4, 0x9f, 0x61, 0xfe, 0xf3, 0x39, 0xf2, 0x9f, 0xa1, 0x07, 0x44,
+ 0xae, 0x59, 0xb8, 0xf7, 0xf0, 0x75, 0x48, 0xd2, 0x9e, 0xee, 0xe1, 0xb5,
+ 0x81, 0x07, 0xe6, 0xe3, 0x6e, 0xe6, 0xf1, 0xb1, 0xf1, 0x65, 0x18, 0x64,
+ 0x26, 0xba, 0xed, 0xf0, 0x47, 0xd0, 0x43, 0x3e, 0xb5, 0x9c, 0x18, 0xbd,
+ 0xe1, 0x60, 0xc6, 0xc6, 0x6c, 0xc1, 0xfc, 0x1f, 0x67, 0x80, 0xd7, 0xc8,
+ 0xc9, 0x06, 0x53, 0x27, 0x6c, 0x9e, 0xe6, 0x62, 0x7c, 0x28, 0x25, 0x2e,
+ 0x85, 0xf7, 0x1b, 0x5d, 0x2b, 0x55, 0x6b, 0x59, 0xd9, 0xe2, 0x40, 0xff,
+ 0x1b, 0xf4, 0xd5, 0x9a, 0x23, 0x2a, 0x6a, 0x87, 0x25, 0x57, 0x27, 0x3f,
+ 0x22, 0x46, 0x3f, 0x47, 0x8c, 0xae, 0x3c, 0x94, 0xcf, 0xcb, 0x13, 0xcc,
+ 0xbb, 0x6a, 0x8d, 0x7c, 0x6e, 0xbe, 0x67, 0x40, 0xf6, 0xe8, 0xb8, 0xf1,
+ 0x1d, 0xda, 0xfe, 0xa9, 0x82, 0xed, 0x9f, 0x2e, 0x60, 0xb0, 0xc5, 0xdc,
+ 0xfc, 0x35, 0x1b, 0x7f, 0xf3, 0xb9, 0xf9, 0xc2, 0x61, 0xa3, 0x2b, 0x4c,
+ 0x8c, 0xbe, 0xfa, 0x90, 0xf4, 0xaf, 0xa1, 0x96, 0x78, 0x32, 0x93, 0x58,
+ 0x52, 0x35, 0x2c, 0xeb, 0x33, 0x81, 0xce, 0x09, 0xd5, 0x67, 0xf7, 0xb1,
+ 0x9d, 0xb2, 0xf5, 0xd2, 0x07, 0xbe, 0x9a, 0x30, 0xb4, 0xad, 0x4a, 0xc0,
+ 0x5c, 0x4d, 0x7d, 0x1e, 0xc9, 0x5c, 0x87, 0xce, 0xc1, 0x3a, 0x1c, 0x4b,
+ 0x4b, 0x7c, 0x91, 0xf6, 0x25, 0x17, 0x77, 0xe2, 0x9d, 0xfd, 0x73, 0xf1,
+ 0xce, 0xd8, 0xe5, 0x3c, 0x7c, 0x47, 0x2a, 0x7a, 0x3f, 0xc3, 0xeb, 0x2a,
+ 0xc9, 0xc3, 0xbf, 0xc7, 0x3c, 0xfc, 0x0d, 0x45, 0xd6, 0x10, 0x55, 0x7c,
+ 0x62, 0x91, 0x83, 0xf1, 0x45, 0xf7, 0x7f, 0xd7, 0x11, 0x97, 0xfb, 0xc8,
+ 0xfe, 0x07, 0xf8, 0xff, 0xb3, 0x8c, 0xe7, 0xc3, 0x9c, 0x89, 0x68, 0xad,
+ 0x03, 0x4f, 0x2f, 0x8e, 0x47, 0x65, 0x9d, 0xb4, 0x9f, 0x3c, 0x65, 0x0e,
+ 0xe3, 0xe1, 0xdf, 0xa7, 0xea, 0xc3, 0x0b, 0x1d, 0x0e, 0x5c, 0x34, 0xf5,
+ 0xf6, 0x03, 0xbc, 0xf6, 0x4c, 0x56, 0x7c, 0x31, 0x4c, 0xfc, 0x5a, 0x59,
+ 0xf0, 0xc5, 0x5a, 0x94, 0xd3, 0xce, 0xe7, 0xd2, 0x5e, 0x7f, 0x9c, 0xd2,
+ 0x07, 0x9f, 0xa1, 0x9d, 0xd6, 0x5e, 0xb2, 0x53, 0x59, 0xa3, 0x95, 0xbc,
+ 0xa6, 0x9d, 0x79, 0xcd, 0xf4, 0xe7, 0xa5, 0x8f, 0xa3, 0x2f, 0x7b, 0x1f,
+ 0xee, 0xdd, 0xab, 0x77, 0x39, 0x1d, 0x71, 0x4b, 0x33, 0xba, 0x99, 0xa3,
+ 0x75, 0x23, 0xb0, 0xc8, 0xe8, 0xb8, 0xa0, 0xe8, 0x9d, 0x3f, 0x54, 0xca,
+ 0x99, 0xf3, 0x9d, 0xc1, 0xf6, 0x51, 0x3d, 0x98, 0x51, 0x0c, 0xdc, 0x40,
+ 0x8c, 0x7b, 0x78, 0xa4, 0x84, 0x76, 0xb8, 0x1e, 0x47, 0x06, 0xf5, 0x70,
+ 0x1c, 0x26, 0x31, 0xb4, 0xde, 0x5f, 0xa6, 0x5c, 0xc0, 0x69, 0xf3, 0x2c,
+ 0xb6, 0x67, 0xe7, 0x60, 0xbd, 0x26, 0x7b, 0x9a, 0xd6, 0x63, 0x62, 0xf0,
+ 0x02, 0x71, 0xa8, 0x9d, 0xdc, 0x4a, 0xf2, 0x06, 0x0b, 0x7b, 0x42, 0x57,
+ 0x63, 0x8b, 0xed, 0xbf, 0xa5, 0xf2, 0x4e, 0x0b, 0xcf, 0x3c, 0xc3, 0x20,
+ 0x4e, 0x48, 0x6e, 0xee, 0x9b, 0xb6, 0x3f, 0x57, 0xd6, 0x75, 0x1b, 0xab,
+ 0xf2, 0xf7, 0x95, 0xff, 0x58, 0x99, 0x29, 0x1c, 0x1a, 0x91, 0xf5, 0x85,
+ 0x19, 0xca, 0xe3, 0x83, 0x0d, 0xbe, 0x1e, 0xc6, 0x8f, 0xfb, 0xcd, 0x1c,
+ 0x5e, 0x5f, 0x5c, 0x86, 0x29, 0xaf, 0x82, 0xd0, 0xd5, 0x61, 0xe9, 0x83,
+ 0x9f, 0x73, 0x96, 0xff, 0x93, 0xd2, 0xce, 0x82, 0xc2, 0x9a, 0xc3, 0x3b,
+ 0x35, 0x8c, 0x55, 0x3c, 0x97, 0xe7, 0x03, 0xe5, 0xbc, 0x78, 0xfd, 0x47,
+ 0x56, 0xd4, 0x2b, 0xd7, 0x89, 0xd9, 0xb3, 0xc4, 0x7f, 0x67, 0x28, 0x77,
+ 0x12, 0x6f, 0xe7, 0x87, 0x66, 0x28, 0xeb, 0xd3, 0xc5, 0x3a, 0x2f, 0x22,
+ 0x3b, 0xf2, 0x22, 0xe7, 0x53, 0x0f, 0x4e, 0xc1, 0x55, 0x78, 0x56, 0x5e,
+ 0xf6, 0x81, 0xb9, 0xc8, 0x43, 0x65, 0x2d, 0xfe, 0x1c, 0x86, 0xf6, 0x0b,
+ 0x6f, 0xb4, 0xac, 0x40, 0xc3, 0x39, 0x6c, 0x3f, 0x7a, 0x42, 0xe9, 0x48,
+ 0xbd, 0x6b, 0xa1, 0x74, 0x46, 0x6c, 0x8e, 0xbd, 0xdf, 0x59, 0xda, 0xe8,
+ 0x53, 0xda, 0xb3, 0x81, 0xf0, 0xfd, 0x0c, 0xbe, 0x5a, 0x44, 0x9e, 0x63,
+ 0x97, 0xb1, 0x9d, 0xe0, 0x35, 0xc3, 0x7e, 0x66, 0xe8, 0xb8, 0x3d, 0xce,
+ 0xf7, 0xeb, 0xe1, 0x9b, 0x56, 0xb4, 0x5d, 0xea, 0x16, 0xe5, 0x9a, 0xcf,
+ 0x89, 0x16, 0xd9, 0x8a, 0xff, 0x8f, 0x17, 0x64, 0x2f, 0x25, 0x77, 0xce,
+ 0x97, 0xe9, 0xa4, 0xec, 0x25, 0xa1, 0x28, 0x4e, 0x35, 0x4f, 0x97, 0xbf,
+ 0x38, 0xd6, 0x83, 0xef, 0x69, 0x2f, 0x5f, 0xf6, 0xe3, 0xb5, 0xb2, 0x4f,
+ 0xea, 0x54, 0xf3, 0x24, 0xfe, 0xce, 0x5e, 0xd7, 0x78, 0xd3, 0xde, 0xdf,
+ 0xb9, 0xcb, 0x6c, 0x89, 0x96, 0xe1, 0xa3, 0x50, 0xaf, 0x8a, 0x2f, 0x2c,
+ 0xb3, 0xf9, 0x76, 0xb4, 0xbd, 0x8c, 0x39, 0xb7, 0xdb, 0x88, 0xde, 0xef,
+ 0x46, 0x2e, 0x47, 0x9e, 0xd0, 0x71, 0x51, 0x39, 0xa6, 0xdc, 0x11, 0xd0,
+ 0xb7, 0xbd, 0x4d, 0xfe, 0xf3, 0x6c, 0x20, 0xce, 0x39, 0x37, 0x7c, 0x03,
+ 0x8a, 0x6e, 0x6e, 0x62, 0x8c, 0x7d, 0x86, 0x39, 0xed, 0xc6, 0x40, 0xbf,
+ 0x7d, 0xcf, 0x53, 0x89, 0xac, 0xc1, 0x95, 0xf6, 0xfb, 0x26, 0xda, 0x61,
+ 0x64, 0x5e, 0x94, 0x35, 0x38, 0xfe, 0x8e, 0x61, 0xa1, 0x7d, 0x6d, 0x23,
+ 0x82, 0xf6, 0xf7, 0xba, 0xc2, 0x3b, 0x29, 0x3a, 0x50, 0x6f, 0x7f, 0x7f,
+ 0x1a, 0x0d, 0x99, 0x4b, 0x6b, 0xd5, 0xe8, 0x35, 0x2d, 0xeb, 0x49, 0x53,
+ 0x9e, 0x57, 0xbb, 0xb4, 0xb7, 0x7c, 0x8d, 0x83, 0x39, 0x10, 0x21, 0x25,
+ 0x96, 0x7f, 0x27, 0xcf, 0xe5, 0xe7, 0xc5, 0x56, 0xbc, 0x67, 0x6f, 0xb9,
+ 0xfd, 0xac, 0x93, 0xfd, 0xce, 0xa5, 0x05, 0x4b, 0x9c, 0xf8, 0x4e, 0xa2,
+ 0x2a, 0xe6, 0xe1, 0xef, 0xed, 0x4b, 0x4a, 0xb0, 0x25, 0x44, 0x0e, 0x7a,
+ 0xd5, 0x19, 0x9c, 0xcf, 0x38, 0x71, 0x26, 0x11, 0x0f, 0x8d, 0xb1, 0xbf,
+ 0x53, 0x09, 0x15, 0xa7, 0x47, 0xfa, 0x42, 0x87, 0xec, 0xbe, 0x5f, 0x45,
+ 0xef, 0x51, 0xb9, 0x0f, 0xd9, 0x8e, 0x0d, 0x89, 0xf3, 0x8c, 0xbb, 0xd2,
+ 0x96, 0xac, 0x05, 0xe8, 0xb9, 0x8d, 0xcc, 0x9f, 0x55, 0x47, 0x10, 0xb7,
+ 0x30, 0xde, 0x3d, 0x97, 0xe8, 0x86, 0x6b, 0xb1, 0xde, 0xf5, 0x2d, 0x72,
+ 0x96, 0xaa, 0x88, 0x1e, 0x7c, 0x4b, 0xe9, 0x20, 0x37, 0x74, 0x63, 0x32,
+ 0x21, 0x7e, 0x21, 0xef, 0xac, 0xf9, 0x34, 0x8e, 0x91, 0x23, 0x3f, 0x9b,
+ 0xd0, 0x70, 0xbe, 0xd9, 0x83, 0x0c, 0x39, 0xf3, 0x77, 0x12, 0x6e, 0x7c,
+ 0x95, 0x9c, 0xf9, 0x91, 0x11, 0x59, 0xb3, 0x6c, 0x45, 0x4b, 0x42, 0xd6,
+ 0xab, 0xc9, 0x03, 0xc7, 0xbc, 0xb4, 0x6d, 0xcb, 0xea, 0x35, 0x67, 0xd3,
+ 0x9f, 0xce, 0xb2, 0x4f, 0x59, 0xe7, 0x8c, 0x62, 0x35, 0x79, 0xd0, 0x23,
+ 0x63, 0x3e, 0x3c, 0xcf, 0x5c, 0x21, 0xc9, 0x7a, 0xcf, 0x25, 0xfc, 0x18,
+ 0xc8, 0xf8, 0xf0, 0x14, 0x73, 0x86, 0x9d, 0x3c, 0x97, 0xf7, 0x1f, 0x95,
+ 0x18, 0x41, 0xf2, 0xf2, 0x93, 0xa8, 0x18, 0xb8, 0x02, 0x9b, 0xd7, 0x3e,
+ 0x0a, 0x75, 0xe0, 0x04, 0x8f, 0x6b, 0xc9, 0x21, 0xae, 0x45, 0x6a, 0x24,
+ 0x82, 0xd4, 0xd8, 0x8b, 0xe8, 0x1f, 0x91, 0x71, 0xc9, 0x7b, 0x6c, 0x64,
+ 0x0f, 0x12, 0xb9, 0xe7, 0x80, 0x17, 0xe9, 0x31, 0xe9, 0xa7, 0x96, 0x7d,
+ 0xff, 0xb9, 0xed, 0xff, 0xab, 0xb5, 0xf9, 0x13, 0xd2, 0xf6, 0xa3, 0x7f,
+ 0xa4, 0x7d, 0xd1, 0x95, 0xac, 0xbd, 0xb4, 0x17, 0xd6, 0x5e, 0xdc, 0x6c,
+ 0xd3, 0x03, 0x47, 0x24, 0xb7, 0xb6, 0x12, 0x7a, 0x74, 0xb7, 0x62, 0xb4,
+ 0x55, 0x28, 0xe7, 0xb1, 0x3b, 0x2b, 0xef, 0x45, 0x28, 0xc5, 0x53, 0xc4,
+ 0x6b, 0x57, 0x48, 0xd7, 0xbe, 0x45, 0xdb, 0x59, 0x4e, 0x8c, 0x7b, 0xd5,
+ 0xbc, 0x1a, 0x71, 0x4d, 0xf4, 0x57, 0x8a, 0x17, 0x06, 0xdd, 0xc4, 0xa6,
+ 0x08, 0xf2, 0xcf, 0xc8, 0x79, 0xf0, 0x83, 0x84, 0x97, 0xf3, 0xd5, 0x98,
+ 0x33, 0x1c, 0x0d, 0xf2, 0x0c, 0x9e, 0x7d, 0xed, 0x54, 0x62, 0x23, 0x0e,
+ 0x51, 0xde, 0xe7, 0x12, 0x17, 0x39, 0x3f, 0x9d, 0xd4, 0xbf, 0xe8, 0x3b,
+ 0x5e, 0xd0, 0x75, 0x1f, 0x75, 0x5d, 0x87, 0x67, 0x12, 0x5f, 0xc4, 0x23,
+ 0x94, 0xff, 0xe1, 0x41, 0x23, 0x3a, 0x5f, 0x39, 0x49, 0xfc, 0x2e, 0xc5,
+ 0x69, 0xb6, 0x7d, 0x07, 0x33, 0xf7, 0x29, 0xe9, 0x2b, 0x25, 0xeb, 0xa5,
+ 0x0a, 0xde, 0x5a, 0x72, 0x12, 0x13, 0xfc, 0xef, 0x07, 0x83, 0xf2, 0x1c,
+ 0x5a, 0x35, 0xfb, 0x10, 0xfd, 0xf8, 0xed, 0xdc, 0xa4, 0x87, 0xbc, 0x6b,
+ 0x55, 0xf3, 0x49, 0xec, 0x4a, 0xcb, 0xb5, 0xf5, 0xe8, 0x1f, 0xbc, 0x00,
+ 0x47, 0xa8, 0x04, 0x77, 0x78, 0x9b, 0x69, 0xeb, 0x39, 0xec, 0xce, 0x34,
+ 0xcf, 0xc8, 0x73, 0xe2, 0xaa, 0x19, 0xf2, 0x4c, 0xd6, 0xa9, 0x44, 0x29,
+ 0xbe, 0xc3, 0x3a, 0x9b, 0x89, 0x15, 0xf9, 0x7b, 0x38, 0xe4, 0xfe, 0xc4,
+ 0xfa, 0x0c, 0xfb, 0x48, 0xd8, 0x6d, 0xcc, 0x50, 0x0e, 0xd0, 0x0f, 0xab,
+ 0x17, 0xcf, 0x50, 0x52, 0x69, 0xc9, 0x35, 0x5e, 0xc4, 0x13, 0x0f, 0xe4,
+ 0x75, 0x78, 0xc8, 0xdc, 0x88, 0x74, 0xa6, 0xba, 0xd0, 0xde, 0x4b, 0x85,
+ 0x7b, 0x6d, 0xf2, 0x3c, 0x88, 0x51, 0x78, 0x17, 0xc0, 0xe5, 0x7b, 0x6c,
+ 0xdf, 0xc8, 0x56, 0x91, 0xcf, 0x97, 0xd3, 0xd6, 0x4a, 0x62, 0x5e, 0xc6,
+ 0xf9, 0x8d, 0x8b, 0x34, 0xec, 0x5d, 0xfa, 0xd9, 0x5a, 0x54, 0x69, 0xce,
+ 0x5f, 0x35, 0xbf, 0xc8, 0x7e, 0xaa, 0x62, 0x35, 0x91, 0x47, 0xec, 0x7d,
+ 0x59, 0xa1, 0xa5, 0x33, 0x19, 0xe7, 0xe4, 0x5e, 0x75, 0x0c, 0xaf, 0x27,
+ 0x6a, 0x63, 0xb5, 0x91, 0x6a, 0xe6, 0xf6, 0x17, 0x30, 0x30, 0xea, 0x44,
+ 0x15, 0x79, 0x7c, 0x65, 0xb2, 0x16, 0x6e, 0x7b, 0x5d, 0xf1, 0x0a, 0xf2,
+ 0xa7, 0xb9, 0xe4, 0x48, 0x75, 0xa8, 0x26, 0x4f, 0xf2, 0x84, 0x2c, 0xeb,
+ 0xa7, 0x8b, 0x2d, 0xeb, 0x4a, 0x1e, 0x65, 0x3c, 0xce, 0x85, 0xc4, 0x4f,
+ 0xa3, 0x68, 0xb4, 0xfd, 0xd5, 0x40, 0x93, 0xfd, 0xdd, 0x4a, 0x5f, 0xef,
+ 0x0a, 0x2d, 0x9c, 0xf8, 0x62, 0xa8, 0x61, 0x62, 0x26, 0xd4, 0xe1, 0x59,
+ 0x70, 0xb0, 0xad, 0x8f, 0x2f, 0xb5, 0xd0, 0x6a, 0xca, 0xfb, 0x04, 0x84,
+ 0xa7, 0x6d, 0x24, 0x4f, 0xeb, 0x0f, 0x19, 0x13, 0x8f, 0xe2, 0x7a, 0xc6,
+ 0x5d, 0xf7, 0xb0, 0x8f, 0xfd, 0x48, 0xce, 0xef, 0xcc, 0xcd, 0x23, 0xff,
+ 0xbf, 0x7a, 0xb1, 0x70, 0xb6, 0x0e, 0x79, 0x97, 0x08, 0x3a, 0x26, 0x4e,
+ 0xe2, 0x26, 0x96, 0xf1, 0x0c, 0xbf, 0x84, 0x64, 0xf6, 0x47, 0x18, 0xc8,
+ 0x4a, 0x3c, 0xc9, 0xe1, 0x06, 0xb6, 0x5d, 0x3e, 0xdc, 0x46, 0xae, 0xba,
+ 0x06, 0x9b, 0x27, 0x2c, 0xac, 0x0a, 0x4d, 0x62, 0xd5, 0x04, 0x39, 0xf0,
+ 0x44, 0xd1, 0x5f, 0x85, 0xbf, 0xad, 0x81, 0x3c, 0x7f, 0xe6, 0x26, 0xb6,
+ 0xc8, 0xda, 0x9e, 0x4a, 0x3f, 0x6c, 0xa1, 0x7d, 0x3f, 0x9e, 0x8a, 0x63,
+ 0xc3, 0x84, 0x60, 0xee, 0x7d, 0xe8, 0x9d, 0x90, 0xb5, 0xe2, 0xaf, 0x84,
+ 0xe6, 0x4f, 0xfc, 0x08, 0x2d, 0x13, 0xe9, 0xd0, 0x82, 0x89, 0x31, 0xca,
+ 0x9d, 0xa0, 0x6c, 0x83, 0xa1, 0xfa, 0x89, 0x91, 0x50, 0x70, 0xe2, 0x40,
+ 0x28, 0x30, 0xd1, 0x8e, 0x9d, 0x13, 0xeb, 0xb0, 0x63, 0x62, 0x1b, 0xb6,
+ 0x4f, 0x08, 0x6e, 0x4f, 0x61, 0xe5, 0xc4, 0xab, 0x58, 0x31, 0xf1, 0x2c,
+ 0x5a, 0x27, 0xce, 0x62, 0xf9, 0xc4, 0x8b, 0x68, 0x9b, 0x78, 0x89, 0x63,
+ 0x91, 0xb5, 0x67, 0x59, 0x77, 0x2e, 0xde, 0xe7, 0x9b, 0xbe, 0x97, 0x5a,
+ 0xd6, 0x56, 0xe4, 0x59, 0x30, 0x99, 0x43, 0x17, 0xd6, 0x6a, 0xe7, 0xd0,
+ 0xb7, 0x5f, 0xde, 0xb5, 0xd6, 0xa8, 0xf5, 0x42, 0xee, 0xe1, 0xbe, 0x28,
+ 0xcf, 0x06, 0xd0, 0xc6, 0xa6, 0xef, 0x1b, 0xd6, 0xb5, 0xa9, 0x4b, 0xf7,
+ 0x3c, 0xe5, 0x99, 0x2c, 0x89, 0x3d, 0xe7, 0xd1, 0x93, 0xfd, 0x8d, 0x15,
+ 0xd5, 0xa4, 0xac, 0x3c, 0x2b, 0x26, 0xf6, 0x70, 0x0e, 0x0f, 0xed, 0x3f,
+ 0x4f, 0x0e, 0x35, 0x69, 0xaf, 0x1d, 0xbd, 0xbd, 0x40, 0xde, 0xd3, 0xe3,
+ 0x27, 0x36, 0x9d, 0x43, 0xea, 0x28, 0x30, 0x71, 0x50, 0xfc, 0x70, 0x23,
+ 0xfd, 0x70, 0x52, 0x7c, 0x32, 0x4e, 0x4c, 0xbe, 0xcd, 0x83, 0xfb, 0xc8,
+ 0x93, 0x4a, 0x90, 0x1b, 0x2b, 0xc7, 0xd3, 0x23, 0x71, 0x6b, 0x9e, 0x21,
+ 0xef, 0x2e, 0x31, 0x72, 0x57, 0x32, 0xee, 0xbf, 0xc4, 0x6b, 0x93, 0x83,
+ 0xf0, 0xfb, 0x8c, 0x80, 0x6f, 0x1e, 0xcf, 0x4f, 0xa7, 0x27, 0xc9, 0x71,
+ 0xba, 0x30, 0xc5, 0x6f, 0xc9, 0x89, 0x81, 0x5e, 0xa4, 0xd3, 0xa2, 0xcf,
+ 0x76, 0xea, 0x53, 0x70, 0x51, 0xef, 0x6a, 0x25, 0x1e, 0x5a, 0x8a, 0xe0,
+ 0xa1, 0x8a, 0x8a, 0x7d, 0xc2, 0x25, 0xec, 0x77, 0x9f, 0x98, 0x03, 0xca,
+ 0x8b, 0xf8, 0x0e, 0x73, 0x98, 0xf2, 0x7d, 0xe4, 0x43, 0xc4, 0xca, 0xaa,
+ 0x88, 0x62, 0xac, 0x0a, 0x9c, 0xc3, 0xd3, 0x63, 0x4e, 0xb8, 0x93, 0x4e,
+ 0x4c, 0x12, 0x27, 0x1d, 0x49, 0xd9, 0x3f, 0xa0, 0x51, 0x16, 0x59, 0xa7,
+ 0x3a, 0x8b, 0x9c, 0x7d, 0x7f, 0x4f, 0xee, 0xcf, 0x7c, 0xd7, 0xee, 0xc7,
+ 0x49, 0xd9, 0xfb, 0x88, 0xa5, 0x3d, 0xa9, 0xef, 0xa1, 0x35, 0xed, 0xb1,
+ 0x9f, 0xf3, 0xdb, 0x9d, 0x7a, 0x15, 0xa9, 0xfd, 0x75, 0xb8, 0xdd, 0x7e,
+ 0xd6, 0xcf, 0x84, 0x46, 0xbd, 0xdd, 0x32, 0x6e, 0x22, 0x7a, 0x78, 0x1d,
+ 0xd6, 0x1e, 0xfe, 0x24, 0x8f, 0x59, 0xb8, 0xe9, 0x70, 0x27, 0x6e, 0x1c,
+ 0x8f, 0xa3, 0x63, 0xbc, 0x8f, 0xc7, 0x7a, 0x7c, 0x6c, 0xa8, 0x1a, 0x99,
+ 0x90, 0xc6, 0x1c, 0x7f, 0x3d, 0x73, 0x7c, 0xe1, 0x67, 0x1b, 0xf0, 0x34,
+ 0x71, 0x27, 0x18, 0xda, 0x80, 0x49, 0xdb, 0x17, 0x65, 0x8f, 0xe5, 0x06,
+ 0x6c, 0x67, 0xfe, 0x3e, 0x8a, 0x0d, 0xe8, 0xe1, 0xb5, 0x21, 0x7b, 0x0e,
+ 0x4e, 0x62, 0x19, 0xf3, 0xb3, 0x77, 0xae, 0x39, 0x89, 0x0f, 0x1f, 0x92,
+ 0xbe, 0x2f, 0x20, 0xb5, 0x77, 0x23, 0xdb, 0xcc, 0xa1, 0x7d, 0xfc, 0x9f,
+ 0x71, 0xe3, 0x10, 0xee, 0xac, 0x46, 0x35, 0x9e, 0x0d, 0x05, 0x3a, 0x06,
+ 0x94, 0x7f, 0xb6, 0xdb, 0xde, 0x9e, 0xfa, 0x11, 0x76, 0xa5, 0xce, 0xe3,
+ 0xe1, 0xcc, 0x4b, 0xe8, 0x4f, 0x4d, 0x9f, 0x53, 0x99, 0xcb, 0x37, 0x19,
+ 0x0f, 0xbe, 0x8f, 0x23, 0x63, 0x53, 0xc4, 0xde, 0x57, 0x78, 0xbc, 0xff,
+ 0x7e, 0x7a, 0xfe, 0x39, 0xdc, 0xbc, 0xdd, 0x48, 0x3e, 0x55, 0xe4, 0x6f,
+ 0x71, 0xab, 0xda, 0xc8, 0xed, 0x9a, 0x03, 0x7d, 0x5b, 0x58, 0x95, 0xfb,
+ 0x81, 0x46, 0xec, 0x05, 0x45, 0x6f, 0xff, 0x96, 0xe2, 0x61, 0xae, 0x21,
+ 0xcf, 0x45, 0xea, 0xd1, 0x1b, 0xa8, 0xef, 0xb2, 0x07, 0xbe, 0x0f, 0xe7,
+ 0x03, 0x4e, 0x94, 0x26, 0x65, 0x2d, 0x47, 0xde, 0x2b, 0x23, 0xef, 0x30,
+ 0xc9, 0xe9, 0xa5, 0xf2, 0xae, 0x89, 0xe4, 0x24, 0x63, 0x7f, 0x6e, 0x61,
+ 0x09, 0xe4, 0x39, 0xec, 0xeb, 0xb0, 0x71, 0x30, 0x8a, 0x1e, 0x53, 0x9e,
+ 0x31, 0xca, 0x8f, 0x7f, 0x5e, 0xf3, 0xf7, 0xd1, 0xcb, 0xf8, 0xb3, 0x9e,
+ 0x98, 0x78, 0xbb, 0x7d, 0x6f, 0xf6, 0xfb, 0xe8, 0x1b, 0xf9, 0x47, 0xb7,
+ 0xf0, 0x9d, 0x3e, 0x53, 0x9e, 0xe3, 0xd6, 0xcd, 0xf7, 0xbe, 0xc3, 0x66,
+ 0xbe, 0xec, 0x69, 0xa3, 0x4d, 0xe4, 0x16, 0xba, 0xb0, 0xbd, 0x36, 0xff,
+ 0x1e, 0x95, 0x0f, 0x7a, 0xe7, 0xd0, 0x5f, 0xda, 0xef, 0x1c, 0x92, 0xfb,
+ 0xfa, 0xf2, 0xbe, 0xaa, 0x27, 0x12, 0xf2, 0x1e, 0x09, 0x75, 0x99, 0x0b,
+ 0xaa, 0xd7, 0x45, 0x5e, 0xf8, 0xaa, 0x39, 0x13, 0xbd, 0x5e, 0x0b, 0xd7,
+ 0x53, 0x96, 0x63, 0x4d, 0x1f, 0x63, 0xe6, 0x12, 0xef, 0x70, 0xd9, 0xef,
+ 0x26, 0x39, 0xff, 0xa9, 0x7f, 0xff, 0x6e, 0x92, 0x37, 0x89, 0x93, 0x0a,
+ 0x2a, 0x8d, 0x5b, 0xf0, 0x9c, 0x1d, 0x13, 0x14, 0x54, 0x34, 0xc8, 0xba,
+ 0xa8, 0x1f, 0xcf, 0x18, 0x8d, 0xfe, 0x1a, 0xb9, 0xdf, 0xa5, 0x9c, 0xb3,
+ 0xe2, 0xde, 0x3a, 0xc6, 0x97, 0xff, 0x68, 0x2f, 0xfe, 0xf3, 0xd8, 0xb9,
+ 0x37, 0x4c, 0xce, 0xe8, 0x95, 0x67, 0x23, 0x67, 0x14, 0x9f, 0xc5, 0xdc,
+ 0x91, 0x92, 0x3d, 0xec, 0x0c, 0x8a, 0xe5, 0x6f, 0xd2, 0xcf, 0xde, 0x94,
+ 0x3d, 0x58, 0xe4, 0x3c, 0x7f, 0x85, 0x60, 0xcd, 0x8c, 0xfc, 0x73, 0x52,
+ 0xf6, 0x5e, 0x5f, 0x59, 0x0f, 0xd8, 0x5e, 0x78, 0xef, 0xa2, 0x94, 0x95,
+ 0x7a, 0x6f, 0xda, 0x6b, 0xc2, 0x2e, 0xe3, 0x37, 0xd6, 0x6b, 0xde, 0x5a,
+ 0x96, 0xfd, 0x45, 0xe1, 0xff, 0xf3, 0xe2, 0x33, 0x66, 0x14, 0x72, 0x4d,
+ 0xea, 0x88, 0xae, 0x2e, 0xd7, 0xe9, 0x4d, 0x39, 0x88, 0x7b, 0x67, 0xad,
+ 0x6e, 0xaf, 0x8c, 0x61, 0xec, 0x7d, 0x75, 0x54, 0xfb, 0x1d, 0x84, 0x79,
+ 0xfd, 0x8a, 0x3c, 0xff, 0xbe, 0x4f, 0x59, 0x3f, 0x2e, 0x31, 0x2a, 0x70,
+ 0xae, 0x26, 0xbf, 0xae, 0x73, 0x59, 0xc6, 0x47, 0xbc, 0xb2, 0xef, 0xaf,
+ 0xd4, 0x3e, 0xb7, 0xfb, 0x35, 0x2f, 0xd7, 0xfb, 0x46, 0x61, 0xbc, 0xb5,
+ 0xf6, 0xb3, 0x4a, 0x0f, 0xda, 0xbc, 0xc6, 0x31, 0x6d, 0xdc, 0xcb, 0xbc,
+ 0xef, 0xed, 0x67, 0xa4, 0xd0, 0xaf, 0x6a, 0x3f, 0xef, 0x75, 0xb9, 0x0f,
+ 0x91, 0xeb, 0xa9, 0x42, 0x1d, 0x3d, 0x1c, 0xb5, 0xfb, 0x57, 0x99, 0xbf,
+ 0x15, 0xfb, 0xa4, 0x3f, 0x2d, 0x2e, 0xb6, 0x31, 0x29, 0xf6, 0xd5, 0x5d,
+ 0xca, 0xd8, 0x74, 0xae, 0xf9, 0x3e, 0x6c, 0x4f, 0x88, 0x9e, 0xe5, 0x1d,
+ 0x95, 0xc4, 0x60, 0x9b, 0x6b, 0xb9, 0xe8, 0x6f, 0x4b, 0x91, 0xd6, 0xe2,
+ 0x38, 0xd4, 0x24, 0xcf, 0xe6, 0xb9, 0x68, 0xd3, 0x71, 0x94, 0x91, 0xdb,
+ 0x46, 0x79, 0x4d, 0xf6, 0xb4, 0x1c, 0x31, 0xf5, 0xe8, 0x13, 0xf8, 0x12,
+ 0x1c, 0x57, 0xd9, 0xeb, 0x5f, 0x6d, 0x69, 0xc8, 0x75, 0x93, 0xb9, 0xc9,
+ 0xf4, 0x15, 0x83, 0x32, 0xda, 0x8e, 0xbd, 0x17, 0xdb, 0x94, 0x67, 0xf7,
+ 0x06, 0x12, 0xf2, 0x0c, 0x59, 0x63, 0x8c, 0xfc, 0x10, 0xcf, 0x65, 0x64,
+ 0xff, 0xc3, 0x6f, 0xad, 0xf8, 0x4c, 0xd9, 0x67, 0x39, 0xbd, 0x4e, 0x09,
+ 0x71, 0x29, 0x10, 0xae, 0x52, 0x8a, 0xcf, 0x91, 0x5d, 0xfe, 0xdc, 0x44,
+ 0x9b, 0x39, 0x6f, 0x3f, 0xfb, 0x27, 0x67, 0x11, 0xb4, 0xa4, 0xe4, 0x5d,
+ 0x8c, 0xfa, 0xe4, 0x2a, 0x34, 0xe6, 0xea, 0x1d, 0xce, 0x02, 0xff, 0x08,
+ 0x63, 0x0d, 0xed, 0x66, 0x47, 0x20, 0x6c, 0x3f, 0xe3, 0x26, 0xef, 0xdc,
+ 0x78, 0x18, 0x7a, 0xe7, 0x1b, 0x2c, 0xff, 0xb1, 0xec, 0xf3, 0x56, 0xda,
+ 0x2b, 0x63, 0x2a, 0xfa, 0xb8, 0xbc, 0xdb, 0x87, 0x7a, 0x8c, 0x88, 0x7f,
+ 0x78, 0x50, 0x13, 0x09, 0xd3, 0x0f, 0x25, 0x7e, 0xcb, 0xf3, 0x71, 0xfa,
+ 0x01, 0xc9, 0xab, 0x5a, 0xb2, 0xf2, 0xfc, 0xb7, 0xec, 0x9b, 0xd6, 0xfd,
+ 0x6b, 0x1d, 0xc1, 0xc2, 0xfe, 0xe5, 0x62, 0xbc, 0xb7, 0xbc, 0x85, 0xbd,
+ 0xd5, 0xee, 0x79, 0x8c, 0x6f, 0x96, 0xbd, 0x6f, 0x60, 0xa3, 0x8d, 0x0d,
+ 0x9a, 0xa1, 0x1f, 0xfb, 0xa5, 0xa3, 0x1b, 0x8f, 0x2d, 0x32, 0xba, 0x8e,
+ 0xab, 0xb9, 0xb4, 0x8f, 0x38, 0x71, 0xad, 0x23, 0x3a, 0xc4, 0x6f, 0xff,
+ 0x77, 0x89, 0xcd, 0x37, 0xd9, 0x75, 0xf5, 0xe0, 0x3a, 0xb5, 0xf8, 0x6c,
+ 0xb5, 0x3c, 0x73, 0xa1, 0x77, 0x7c, 0x43, 0xe9, 0xc6, 0xd6, 0x90, 0xd1,
+ 0xbe, 0x4d, 0xd1, 0xdb, 0xbe, 0xac, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0xec,
+ 0x77, 0xe8, 0x5c, 0x8a, 0x9d, 0x2e, 0xf6, 0x71, 0x38, 0xa1, 0x87, 0x67,
+ 0xb0, 0xec, 0x39, 0xd3, 0xf0, 0x5d, 0x60, 0x9b, 0x3f, 0xe4, 0x31, 0x84,
+ 0x20, 0x96, 0xdb, 0xed, 0x46, 0x17, 0xba, 0xec, 0xf7, 0xa4, 0x76, 0x30,
+ 0x26, 0xc8, 0xfb, 0xb0, 0x62, 0xd0, 0x92, 0x75, 0x34, 0x31, 0xbd, 0xff,
+ 0x66, 0x48, 0x4e, 0xdd, 0xc3, 0x80, 0xed, 0x81, 0x37, 0xd2, 0x8d, 0x86,
+ 0x45, 0x86, 0x6f, 0x89, 0x6a, 0xd7, 0x0f, 0xca, 0xfb, 0x81, 0x96, 0x73,
+ 0x9c, 0x23, 0x90, 0x36, 0x72, 0x96, 0xd6, 0x50, 0x6d, 0xd7, 0x59, 0xa4,
+ 0x7e, 0x14, 0xae, 0x0f, 0xfd, 0xca, 0x4a, 0x6b, 0xd0, 0x6a, 0x0d, 0xa9,
+ 0x13, 0x1f, 0xd2, 0xf0, 0x1f, 0xd5, 0x13, 0x5c, 0xf9, 0xa5, 0x85, 0x59,
+ 0x52, 0x4f, 0xf6, 0xac, 0x7d, 0x1a, 0x77, 0x0d, 0xc8, 0x7b, 0x22, 0xc4,
+ 0x1f, 0xf5, 0xe8, 0x17, 0xc8, 0x35, 0xcb, 0xed, 0xf7, 0x6f, 0x49, 0x2c,
+ 0x59, 0x4f, 0x3c, 0xeb, 0x86, 0x16, 0xd2, 0xfb, 0xaf, 0x50, 0xe5, 0x1d,
+ 0x43, 0x8f, 0xc9, 0xbe, 0x9d, 0x03, 0x0b, 0xd4, 0xfc, 0xfe, 0x9e, 0xd8,
+ 0x1f, 0x7d, 0x5f, 0x11, 0xfb, 0x2a, 0x97, 0xf7, 0x15, 0xd5, 0xd9, 0xcf,
+ 0xa7, 0xac, 0x4f, 0x38, 0x0a, 0xfb, 0x15, 0x2f, 0xbf, 0xc7, 0x73, 0x23,
+ 0x79, 0xfd, 0x26, 0x79, 0x67, 0x1f, 0xc7, 0xba, 0x39, 0x21, 0x4b, 0x5a,
+ 0xff, 0x0f, 0xdd, 0x0f, 0x6b, 0xf2, 0xd0, 0x56, 0x00, 0x00, 0x00 };
static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = {
0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
@@ -2137,50 +2119,51 @@ static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = {
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000000 };
-static const u32 bnx2_CP_b06FwRodata[(0x130/4) + 1] = {
- 0x08001e8c, 0x08001d18, 0x08001e68, 0x08001e44, 0x08001e20, 0x08001dfc,
- 0x08001dd4, 0x08001dac, 0x08001d80, 0x08001f84, 0x08001f74, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001eb4, 0x08001eb4, 0x08001d34, 0x08001d34,
- 0x08001f64, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001f54,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001f44, 0x08001d34, 0x08001d34, 0x08001f34,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001f1c,
- 0x08001d34, 0x08001d34, 0x08001f0c, 0x08001efc, 0x08003208, 0x08003210,
- 0x080031d8, 0x080031e4, 0x080031f0, 0x080031fc, 0x08005694, 0x08005654,
- 0x08005620, 0x080055f4, 0x080055d0, 0x0800558c, 0x00000000 };
+static const u32 bnx2_CP_b06FwRodata[(0x134/4) + 1] = {
+ 0x08000f30, 0x08000d88, 0x08000fc4, 0x0800106c, 0x08000f58, 0x08000f98,
+ 0x080011a4, 0x08000da4, 0x080011c8, 0x08000df4, 0x08001498, 0x08001440,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08001254, 0x08001254, 0x08000da4,
+ 0x08000da4, 0x080016e0, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x080013d4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08000fb8, 0x08000da4, 0x08000da4,
+ 0x08001690, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x080015bc, 0x08000da4, 0x08000da4, 0x08001348, 0x080012b8, 0x08002e50,
+ 0x08002e58, 0x08002e20, 0x08002e2c, 0x08002e38, 0x08002e44, 0x0800532c,
+ 0x080052ec, 0x080052b8, 0x0800528c, 0x08005268, 0x08005224, 0x00000000
+};
static struct fw_info bnx2_cp_fw_06 = {
- /* Firmware version: 4.4.22 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x16,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
.start_addr = 0x08000080,
.text_addr = 0x08000000,
- .text_len = 0x5a34,
+ .text_len = 0x56cc,
.text_index = 0x0,
.gz_text = bnx2_CP_b06FwText,
.gz_text_len = sizeof(bnx2_CP_b06FwText),
- .data_addr = 0x08005b80,
+ .data_addr = 0x08005820,
.data_len = 0x84,
.data_index = 0x0,
.data = bnx2_CP_b06FwData,
- .sbss_addr = 0x08005c04,
- .sbss_len = 0xe9,
+ .sbss_addr = 0x080058a4,
+ .sbss_len = 0xf1,
.sbss_index = 0x0,
- .bss_addr = 0x08005cf0,
+ .bss_addr = 0x08005998,
.bss_len = 0x5d8,
.bss_index = 0x0,
- .rodata_addr = 0x08005a34,
- .rodata_len = 0x130,
+ .rodata_addr = 0x080056cc,
+ .rodata_len = 0x134,
.rodata_index = 0x0,
.rodata = bnx2_CP_b06FwRodata,
};
@@ -2202,761 +2185,747 @@ static const struct cpu_reg cpu_reg_cp = {
};
static u8 bnx2_RXP_b06FwText[] = {
- 0xec, 0x5b, 0x5f, 0x6c, 0x5b, 0xd7, 0x79, 0xff, 0xee, 0x21, 0x25, 0x51,
- 0xb2, 0xfe, 0x5c, 0xc9, 0x8c, 0x43, 0x27, 0x4a, 0x43, 0x4a, 0x57, 0x12,
- 0x13, 0x69, 0xe9, 0x95, 0xc6, 0x26, 0x2a, 0x46, 0x34, 0x2c, 0x29, 0xdb,
- 0x4a, 0xe3, 0x07, 0xc5, 0xf5, 0xda, 0xac, 0xeb, 0x30, 0x81, 0xb2, 0xb1,
- 0xec, 0x61, 0x83, 0x67, 0xac, 0x41, 0xb6, 0xb9, 0x30, 0x41, 0x29, 0x8e,
- 0x92, 0xd2, 0x22, 0x67, 0x2b, 0x73, 0xb1, 0x65, 0x80, 0x42, 0x49, 0x76,
- 0xb6, 0xd1, 0x62, 0xda, 0xbd, 0x74, 0x45, 0x1c, 0x0b, 0x8a, 0xe7, 0xe5,
- 0xa1, 0x0f, 0x69, 0x17, 0x60, 0xed, 0xd0, 0x61, 0x86, 0xe2, 0xda, 0x79,
- 0x28, 0xb6, 0x6c, 0x40, 0x96, 0x6c, 0x71, 0x73, 0xf7, 0xfb, 0x9d, 0x7b,
- 0xaf, 0x4c, 0x2b, 0x1a, 0x9a, 0x87, 0x3d, 0xde, 0x03, 0x08, 0xe7, 0x9e,
- 0x73, 0xbe, 0xf3, 0x9d, 0xef, 0xfb, 0xce, 0xf7, 0xf7, 0xd0, 0xfe, 0xc3,
- 0x76, 0x69, 0x13, 0xaf, 0x75, 0xe0, 0x2f, 0x75, 0xec, 0x99, 0xe3, 0x63,
- 0x0f, 0xa5, 0x1e, 0xe2, 0x38, 0xa4, 0xc2, 0x61, 0xf6, 0x86, 0x04, 0x2d,
- 0x68, 0x41, 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68,
- 0x41, 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41,
- 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b,
- 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, 0x5a,
- 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, 0x5a, 0xd0,
- 0x82, 0x16, 0xb4, 0xa0, 0x05, 0xed, 0xff, 0xb3, 0x85, 0x44, 0x4c, 0xf6,
- 0x1d, 0xde, 0x9f, 0x44, 0x54, 0x3a, 0x7e, 0x3c, 0x6b, 0x49, 0x24, 0x94,
- 0xbe, 0xf2, 0xf4, 0x8c, 0x25, 0x92, 0xa9, 0x0d, 0xc7, 0x73, 0xf2, 0x0b,
- 0xa7, 0x10, 0x0d, 0x0b, 0xe7, 0xef, 0x4b, 0xdf, 0x3a, 0x79, 0xe9, 0x91,
- 0xc4, 0x7b, 0x4b, 0x21, 0x89, 0x98, 0xe9, 0xb7, 0x46, 0xcd, 0x41, 0x89,
- 0xf4, 0x62, 0xcf, 0x4b, 0x43, 0x97, 0xbb, 0xa4, 0xd3, 0xc7, 0x25, 0x52,
- 0x2d, 0x25, 0xec, 0xfd, 0x32, 0x6c, 0x6e, 0x48, 0x58, 0x32, 0x38, 0xe3,
- 0x7c, 0x4d, 0xa4, 0x58, 0x32, 0x88, 0x43, 0x8a, 0xb5, 0x88, 0x5c, 0x0b,
- 0x11, 0xea, 0x7b, 0x46, 0xb6, 0xfc, 0xb1, 0x93, 0x09, 0xe3, 0x5c, 0x0b,
- 0xdf, 0x75, 0x7f, 0x3e, 0x22, 0x2a, 0x9d, 0x48, 0x66, 0x43, 0x93, 0x52,
- 0x5d, 0x74, 0x9c, 0x39, 0xfb, 0x5e, 0xe0, 0xe8, 0x91, 0x39, 0xcb, 0x1d,
- 0x67, 0xed, 0x07, 0xcd, 0x09, 0xb9, 0x1b, 0x73, 0x21, 0x51, 0xd6, 0x3d,
- 0xf8, 0x8b, 0x1b, 0xb9, 0xb3, 0xdf, 0x32, 0xb2, 0xcb, 0xed, 0x52, 0x2c,
- 0x3b, 0x32, 0x63, 0x4b, 0x26, 0x6b, 0xb7, 0x62, 0xfd, 0x63, 0x67, 0x66,
- 0x6b, 0xcf, 0xb0, 0x99, 0x93, 0x26, 0xc9, 0x44, 0x63, 0x80, 0x59, 0x34,
- 0x72, 0x17, 0xfe, 0xae, 0x5d, 0xda, 0x40, 0x4f, 0x8a, 0xe3, 0x8f, 0x9d,
- 0x90, 0x65, 0x61, 0x9d, 0xe7, 0x63, 0x5c, 0x27, 0x5e, 0x7e, 0x13, 0xe7,
- 0x35, 0xe7, 0xd2, 0x50, 0x4c, 0xbe, 0x5b, 0x8f, 0xca, 0x77, 0xea, 0xa6,
- 0xbc, 0x5a, 0xef, 0x95, 0xcb, 0x75, 0xc7, 0xf9, 0x8e, 0xed, 0x38, 0x6f,
- 0xe1, 0xef, 0x3f, 0xed, 0x2d, 0x1e, 0xd0, 0x0a, 0xc6, 0x44, 0xfd, 0x2f,
- 0xda, 0xa5, 0x33, 0x11, 0x17, 0xd5, 0x2e, 0xb3, 0xe5, 0x98, 0xcc, 0x95,
- 0x4b, 0xc6, 0x13, 0x17, 0x16, 0x8c, 0xa9, 0x0b, 0x15, 0x9c, 0x19, 0xc6,
- 0x9c, 0x14, 0x8a, 0xf6, 0x2b, 0x46, 0xae, 0x3e, 0x6f, 0x1c, 0xba, 0xd0,
- 0x09, 0x1a, 0x79, 0xfe, 0x1e, 0x23, 0x7b, 0xf6, 0x96, 0x64, 0x6d, 0xca,
- 0x38, 0x61, 0x7e, 0x0d, 0x62, 0xcf, 0x96, 0x48, 0x73, 0xb3, 0x47, 0xaf,
- 0xe3, 0xa8, 0xb4, 0x73, 0x32, 0x9b, 0xb2, 0xcc, 0xa2, 0x90, 0x3e, 0x3d,
- 0x77, 0xd9, 0xa5, 0xf9, 0xbc, 0x91, 0xbd, 0xd0, 0x6e, 0xe4, 0xce, 0x85,
- 0x41, 0x87, 0xf4, 0x86, 0x84, 0xfb, 0x06, 0x62, 0x79, 0xa9, 0xe1, 0x0c,
- 0x31, 0x55, 0x9a, 0x72, 0x05, 0xcd, 0xa0, 0xe5, 0xbb, 0x65, 0xf0, 0x50,
- 0x06, 0x0f, 0x65, 0xf2, 0x16, 0x97, 0x4b, 0x43, 0x3e, 0x6f, 0x8e, 0xf3,
- 0x23, 0x9b, 0xb4, 0x27, 0xe2, 0x19, 0xe5, 0xf3, 0xe9, 0x38, 0xff, 0x61,
- 0x93, 0x57, 0xf2, 0xe3, 0x38, 0xaf, 0xda, 0x31, 0xd0, 0xee, 0x5c, 0x56,
- 0x56, 0x09, 0xbc, 0x58, 0xc0, 0x4f, 0x59, 0x2f, 0x80, 0x87, 0x79, 0xf0,
- 0x77, 0x1e, 0xbc, 0x55, 0x40, 0xc7, 0x2f, 0x3b, 0xaf, 0x60, 0xe4, 0x86,
- 0xb6, 0xe4, 0x15, 0xa7, 0x8c, 0xf3, 0x2b, 0x0a, 0xb2, 0xde, 0x25, 0xf9,
- 0x25, 0x53, 0xa6, 0x57, 0xfc, 0xfd, 0xbe, 0x1e, 0x1c, 0x93, 0x83, 0xe5,
- 0x1e, 0xc8, 0x86, 0xb2, 0x4c, 0xd8, 0x22, 0x0e, 0x64, 0x54, 0x4c, 0x2a,
- 0x11, 0x23, 0x6f, 0x9f, 0xd4, 0xf7, 0xbf, 0x62, 0x49, 0x26, 0x6f, 0x53,
- 0x8e, 0x12, 0xcf, 0xdb, 0x85, 0x58, 0x18, 0xfa, 0xb6, 0x62, 0x15, 0xcc,
- 0xb0, 0x50, 0x8e, 0x89, 0xd8, 0x1f, 0x43, 0x96, 0x47, 0x4b, 0x92, 0xf9,
- 0x52, 0xc9, 0x97, 0xb1, 0x2b, 0xdf, 0xc7, 0x4b, 0x5f, 0xec, 0x90, 0x36,
- 0xf5, 0x99, 0x26, 0xf9, 0x3d, 0xec, 0x25, 0xee, 0x3b, 0xf6, 0x62, 0x9f,
- 0x0b, 0xe7, 0xee, 0x4d, 0x3c, 0x29, 0x42, 0xd8, 0x62, 0x7f, 0x93, 0xb6,
- 0x11, 0x31, 0xb2, 0x56, 0x21, 0x16, 0x02, 0x5c, 0x5e, 0x8a, 0xa3, 0xde,
- 0x5c, 0x53, 0xd6, 0xba, 0x15, 0x9a, 0xb3, 0x13, 0xf1, 0xa2, 0xdc, 0x0a,
- 0x5d, 0xb5, 0xf5, 0x5c, 0x6b, 0xd6, 0x72, 0x64, 0x15, 0xd8, 0x9f, 0x83,
- 0x3d, 0x6c, 0x80, 0xa3, 0xdf, 0x2d, 0xe9, 0xf9, 0x0e, 0xec, 0x4f, 0x36,
- 0x01, 0x67, 0x9b, 0x24, 0x92, 0x55, 0xcc, 0x5f, 0x75, 0xe7, 0xbb, 0x5d,
- 0xbc, 0xc5, 0xfe, 0x36, 0x8d, 0x5b, 0xe4, 0x15, 0x77, 0xfe, 0x2e, 0x17,
- 0x77, 0xf1, 0x01, 0xcc, 0x03, 0xff, 0xe0, 0xe4, 0x90, 0xa1, 0xe7, 0xf7,
- 0xd2, 0x9e, 0x7e, 0xa7, 0x74, 0x2b, 0xb4, 0x6a, 0x3b, 0x92, 0x1b, 0x1d,
- 0x9c, 0x1c, 0x34, 0x5c, 0x7c, 0xa7, 0xdc, 0x7d, 0xf7, 0xb9, 0xf8, 0x06,
- 0x27, 0x93, 0x86, 0x8b, 0x6f, 0xa5, 0xa4, 0xf7, 0x4a, 0xbe, 0x44, 0xd8,
- 0xc1, 0x49, 0xcb, 0xb8, 0x4f, 0xa6, 0xbb, 0x07, 0x27, 0xfb, 0x0c, 0xf5,
- 0x99, 0x5d, 0x2e, 0x1f, 0x09, 0x9f, 0x86, 0x5d, 0x9a, 0x06, 0x9e, 0xab,
- 0xe7, 0x07, 0xb2, 0x56, 0xf1, 0x81, 0x5d, 0xfa, 0x7c, 0x9e, 0xa9, 0xe7,
- 0x1e, 0x20, 0x5d, 0x3c, 0x7b, 0x66, 0xf4, 0x8e, 0x73, 0x7f, 0xe5, 0xb6,
- 0x7c, 0x76, 0x3a, 0x93, 0xe7, 0x49, 0x24, 0x9c, 0x0e, 0x8f, 0xce, 0x95,
- 0x8e, 0x49, 0xb6, 0x1c, 0x97, 0xd9, 0x91, 0x56, 0x99, 0x36, 0xfb, 0xa7,
- 0x0f, 0x0a, 0x7d, 0x4f, 0x64, 0x74, 0xc6, 0xbb, 0xc3, 0x9c, 0x18, 0x32,
- 0x0b, 0x1e, 0x0f, 0xd6, 0x24, 0x62, 0x00, 0xbe, 0xbf, 0x16, 0x96, 0xe7,
- 0xeb, 0x86, 0x34, 0x6b, 0xfb, 0x4c, 0x98, 0xeb, 0xd0, 0xc3, 0x67, 0xcb,
- 0xd4, 0x63, 0xea, 0xac, 0x64, 0xaa, 0x5a, 0x67, 0x7d, 0x7b, 0x6d, 0xe3,
- 0xdd, 0x16, 0x0a, 0x02, 0x73, 0x4c, 0x5b, 0x66, 0x55, 0x5a, 0x24, 0x33,
- 0x25, 0x85, 0xaa, 0xbd, 0x65, 0x3f, 0xb1, 0x65, 0xd9, 0x80, 0x1e, 0x88,
- 0x99, 0x4d, 0x71, 0x9e, 0xf0, 0x0d, 0xb0, 0xa6, 0x6b, 0x7b, 0x21, 0xd8,
- 0xde, 0x4c, 0x8a, 0xb0, 0x52, 0xd0, 0xfe, 0xa2, 0x0e, 0x7d, 0xac, 0xdf,
- 0xd7, 0xe1, 0xfa, 0xbb, 0x08, 0x6c, 0xb4, 0x1d, 0x76, 0xfe, 0x19, 0xd8,
- 0x60, 0xaf, 0x91, 0x3d, 0xe7, 0x38, 0xf0, 0x3f, 0x51, 0x25, 0xb4, 0x41,
- 0xd8, 0x7b, 0x9d, 0x6b, 0xed, 0x98, 0x17, 0x73, 0xd6, 0xee, 0x06, 0x8f,
- 0x8e, 0x33, 0x69, 0xc7, 0xa5, 0x68, 0x77, 0x61, 0x5f, 0x93, 0xf4, 0x58,
- 0xd4, 0x79, 0xda, 0xf5, 0x2e, 0x9c, 0x67, 0x70, 0xdc, 0x89, 0xf3, 0x3a,
- 0x30, 0x17, 0x9b, 0xa5, 0x2d, 0xa7, 0xe8, 0xb7, 0x5c, 0x1f, 0x2a, 0x72,
- 0x1d, 0xb4, 0x72, 0x8f, 0x86, 0x8b, 0xb4, 0xa4, 0x53, 0x72, 0xb3, 0xb4,
- 0x57, 0xae, 0x45, 0x29, 0x03, 0xe0, 0x2c, 0xc3, 0x27, 0x46, 0x0d, 0xd0,
- 0x4f, 0xba, 0xe9, 0x03, 0x77, 0x7b, 0x63, 0xe3, 0x7e, 0xf7, 0x0c, 0x31,
- 0x43, 0xe9, 0x4e, 0xc9, 0xe9, 0x39, 0x51, 0x6a, 0x74, 0x97, 0xb7, 0xde,
- 0x69, 0xec, 0x3f, 0xa7, 0xe4, 0xc0, 0xc3, 0xf0, 0x5b, 0x38, 0xeb, 0xaa,
- 0xe5, 0x38, 0x57, 0xed, 0xf7, 0x61, 0xf7, 0x4a, 0x9a, 0xac, 0x6b, 0x9d,
- 0xd2, 0x46, 0x7b, 0x36, 0x1a, 0x64, 0x18, 0x93, 0x53, 0x65, 0xee, 0x29,
- 0x48, 0xd8, 0x22, 0x0c, 0xe1, 0xff, 0x05, 0x70, 0x21, 0x69, 0x81, 0x3d,
- 0x6e, 0xd8, 0x51, 0xd2, 0xdb, 0xe5, 0xc2, 0x77, 0xe3, 0x0c, 0xd2, 0x4e,
- 0xfb, 0x73, 0xb4, 0xfd, 0x65, 0x43, 0x2a, 0x33, 0xb1, 0x08, 0x6b, 0x1a,
- 0xa1, 0xbc, 0xb3, 0xdd, 0x70, 0xff, 0x32, 0x3b, 0x54, 0x30, 0x95, 0xbe,
- 0x6f, 0x91, 0x5c, 0xe9, 0x7e, 0x99, 0xb3, 0x71, 0x9e, 0x15, 0x06, 0xcd,
- 0xf4, 0x35, 0x03, 0x85, 0x90, 0x82, 0x95, 0xf5, 0x50, 0x56, 0x3e, 0xad,
- 0xff, 0x8c, 0xf3, 0x0a, 0x46, 0xd8, 0xe2, 0x19, 0xbf, 0xe5, 0xc9, 0x87,
- 0xba, 0x67, 0x4b, 0xb6, 0xd4, 0xce, 0x31, 0xe8, 0x68, 0xd3, 0x74, 0x84,
- 0xd2, 0xfa, 0xee, 0x0c, 0x95, 0xf6, 0x63, 0x00, 0x41, 0xef, 0xc0, 0x03,
- 0x3e, 0xb8, 0xd7, 0xc2, 0xde, 0x08, 0x68, 0xec, 0x68, 0xa0, 0xbf, 0x8d,
- 0xf0, 0x90, 0x55, 0xc4, 0x3b, 0x43, 0xf3, 0x6d, 0xb8, 0x7c, 0xfb, 0xb2,
- 0x7a, 0x1d, 0xb2, 0xfa, 0xc8, 0x39, 0x30, 0x46, 0x1c, 0x29, 0xe0, 0x80,
- 0xdc, 0x4d, 0xfa, 0x2c, 0xfa, 0x29, 0x73, 0x0b, 0x17, 0x6c, 0x41, 0x85,
- 0xd2, 0xed, 0x92, 0x33, 0x75, 0x1c, 0x00, 0xec, 0xb8, 0x68, 0x3f, 0x6f,
- 0x91, 0x47, 0x6f, 0x6c, 0x25, 0xb4, 0xde, 0xe4, 0x2b, 0x8c, 0x05, 0x45,
- 0xd0, 0xb6, 0x9e, 0x50, 0x9a, 0xb5, 0x76, 0xc8, 0x5c, 0x22, 0x4d, 0xe9,
- 0xb7, 0x64, 0xb5, 0xa4, 0xf6, 0x34, 0x4b, 0x97, 0x4c, 0x41, 0x46, 0xd5,
- 0x71, 0xc4, 0xb0, 0x91, 0x76, 0x09, 0x3d, 0xc4, 0x58, 0x10, 0x03, 0xad,
- 0xeb, 0x09, 0x53, 0x6e, 0x39, 0x6a, 0x10, 0xfb, 0x47, 0x70, 0x0f, 0x87,
- 0x79, 0xa7, 0xca, 0x83, 0x23, 0x4c, 0x88, 0x32, 0xef, 0x69, 0x16, 0xe2,
- 0xe6, 0xda, 0x70, 0xcc, 0x14, 0xce, 0x23, 0x5e, 0x4e, 0x71, 0x2f, 0xf9,
- 0x73, 0xf7, 0x7c, 0x92, 0x3f, 0x7f, 0x9d, 0x32, 0xa3, 0xec, 0xa0, 0x63,
- 0xa0, 0xa9, 0x1b, 0x72, 0x1b, 0x5d, 0x80, 0x4f, 0xb4, 0x1f, 0xd7, 0x3a,
- 0xdc, 0x37, 0x76, 0xaf, 0x5c, 0x83, 0xdd, 0xc5, 0x95, 0x18, 0x55, 0x7b,
- 0xaf, 0x9e, 0x53, 0x96, 0x2f, 0x4f, 0xca, 0x60, 0xf7, 0x36, 0x19, 0x10,
- 0xe7, 0xce, 0x72, 0x38, 0x52, 0x21, 0x0d, 0x2e, 0x2d, 0x73, 0xd6, 0x7a,
- 0x22, 0x2c, 0x8d, 0xf4, 0x7c, 0xec, 0x28, 0xcb, 0x2a, 0xf4, 0x29, 0xe2,
- 0x6f, 0x16, 0xb5, 0x27, 0x2c, 0x4f, 0x8c, 0x19, 0x12, 0x3f, 0xa4, 0xe4,
- 0xd0, 0xc3, 0xc4, 0xf9, 0x13, 0xf2, 0x38, 0x9e, 0xe1, 0xfa, 0x18, 0x75,
- 0x21, 0x8c, 0x5e, 0xf3, 0x87, 0xb9, 0x46, 0x5d, 0x7f, 0xdd, 0xd3, 0xf5,
- 0x8f, 0x9c, 0x43, 0x63, 0x61, 0x0f, 0x36, 0xd2, 0x00, 0x2b, 0xb8, 0xef,
- 0x9d, 0x60, 0x09, 0xd3, 0xa8, 0x17, 0x84, 0x2d, 0xec, 0x00, 0x8b, 0xe0,
- 0xf4, 0x15, 0xda, 0x50, 0xb7, 0xe7, 0x33, 0x7c, 0x9b, 0xe2, 0x39, 0xec,
- 0x77, 0xb2, 0x3f, 0xee, 0xe3, 0x7e, 0xc2, 0x6f, 0x8f, 0xa7, 0xb8, 0x06,
- 0xd9, 0x31, 0xa6, 0xa2, 0x4d, 0xe2, 0x5b, 0xc1, 0xff, 0x34, 0xc6, 0x56,
- 0xce, 0x99, 0x18, 0x4f, 0xa0, 0xb7, 0x24, 0x5f, 0xa3, 0x1d, 0x71, 0x3f,
- 0x63, 0xed, 0xbb, 0x9e, 0xef, 0x6c, 0x9f, 0x0e, 0xa7, 0xa3, 0xf0, 0x9d,
- 0x32, 0x55, 0x2c, 0x9d, 0x44, 0x3e, 0x24, 0x85, 0x7b, 0xd2, 0xd4, 0x8b,
- 0xf6, 0x71, 0xf8, 0xc6, 0xa9, 0x62, 0x8d, 0x39, 0x11, 0xdc, 0x17, 0xf6,
- 0x21, 0x3e, 0x47, 0xd4, 0x42, 0xa4, 0x70, 0x6f, 0x9a, 0x3e, 0x39, 0x2e,
- 0xf1, 0xda, 0x7b, 0xc8, 0x39, 0x4c, 0xc9, 0x6a, 0x1d, 0xfb, 0xf6, 0x5e,
- 0xd2, 0x5c, 0x44, 0xfe, 0x10, 0x4e, 0x4b, 0x58, 0xa5, 0x9b, 0x23, 0xb3,
- 0xa9, 0x76, 0xe4, 0x59, 0x93, 0x7b, 0xd5, 0xda, 0xc1, 0xbd, 0xa1, 0xb5,
- 0x3d, 0xd3, 0x4d, 0xe9, 0xc2, 0x5e, 0xb5, 0x20, 0xb2, 0x5c, 0x12, 0x85,
- 0x9c, 0x26, 0x76, 0x44, 0x30, 0x5e, 0xfb, 0xf2, 0x97, 0x55, 0x3a, 0x24,
- 0xf9, 0xa8, 0x9c, 0x58, 0x49, 0x85, 0x99, 0x3f, 0xc6, 0xa7, 0xe4, 0x04,
- 0x72, 0xc6, 0x67, 0x64, 0xb6, 0x04, 0xba, 0x34, 0xdf, 0x31, 0xf0, 0xdb,
- 0x0b, 0xdc, 0xa4, 0x3d, 0x0a, 0xdf, 0xea, 0xd2, 0x0e, 0x9a, 0x33, 0x39,
- 0xe6, 0x48, 0x29, 0xc6, 0x94, 0xf7, 0xa0, 0x27, 0xb4, 0x93, 0x9f, 0xcb,
- 0xaa, 0xd5, 0x2a, 0x79, 0xd7, 0x2f, 0x68, 0x3d, 0x0d, 0xa7, 0xdf, 0xf5,
- 0xd6, 0xae, 0x63, 0x8d, 0xfa, 0xba, 0xab, 0xe1, 0xee, 0xbe, 0xa5, 0xf3,
- 0x9c, 0xab, 0x36, 0xbf, 0x09, 0xfb, 0x83, 0x51, 0x17, 0xf6, 0xcd, 0xd1,
- 0x55, 0xeb, 0x2b, 0x5d, 0xd2, 0x86, 0x73, 0xca, 0x3c, 0x27, 0x4a, 0xdf,
- 0x8a, 0xf5, 0x6b, 0x1e, 0xae, 0x9f, 0x02, 0x57, 0x3b, 0xe9, 0x46, 0x0b,
- 0x63, 0x1d, 0xf4, 0x21, 0xdf, 0xc9, 0x6f, 0xf9, 0x18, 0xc2, 0xbe, 0xe6,
- 0xe1, 0xfa, 0x5e, 0x03, 0x2e, 0xae, 0xb1, 0xe7, 0x99, 0x38, 0xbb, 0x8d,
- 0xbc, 0x91, 0x1f, 0xde, 0x01, 0xef, 0x23, 0x69, 0x4c, 0xc1, 0xa7, 0x4f,
- 0xd5, 0x75, 0x5e, 0x67, 0xe4, 0xca, 0xc8, 0xb7, 0xea, 0x2f, 0x82, 0x46,
- 0xe4, 0x61, 0xf5, 0x01, 0x2f, 0xd7, 0xa6, 0xad, 0xac, 0x6b, 0x9f, 0x45,
- 0x7f, 0x53, 0xd4, 0xf6, 0x74, 0x05, 0x63, 0x9d, 0x67, 0xe3, 0x6e, 0xae,
- 0x48, 0x5f, 0xad, 0xdc, 0xe5, 0xfe, 0xbf, 0x6d, 0x53, 0x42, 0xfa, 0x3e,
- 0x19, 0xd7, 0xa8, 0x67, 0x77, 0xc3, 0x9f, 0x3b, 0x1f, 0x30, 0xbe, 0x4c,
- 0x31, 0xf6, 0x4c, 0x31, 0x66, 0x18, 0x9e, 0x1f, 0x8c, 0x37, 0xe0, 0x88,
- 0x03, 0xc7, 0x79, 0x4f, 0x6f, 0x4f, 0x7b, 0xb8, 0xfc, 0xdc, 0xd3, 0xf7,
- 0xa5, 0x2f, 0xdd, 0x73, 0xe7, 0xba, 0x61, 0xba, 0xe3, 0x66, 0xed, 0x87,
- 0x61, 0xf7, 0xa0, 0x3f, 0x3e, 0xad, 0xa0, 0x5f, 0xb9, 0x9a, 0x7b, 0x1f,
- 0xb0, 0x71, 0xe8, 0x1e, 0x3f, 0xfd, 0xbb, 0x75, 0x73, 0x6f, 0x57, 0x06,
- 0xbc, 0xd3, 0x0c, 0xf9, 0xce, 0x84, 0x49, 0x4b, 0x7d, 0x12, 0xfb, 0xe5,
- 0x18, 0x63, 0x62, 0x1e, 0x7c, 0x1c, 0x31, 0x87, 0xcd, 0x59, 0xe2, 0x8e,
- 0x0a, 0x70, 0x22, 0x8f, 0x4c, 0xb7, 0x78, 0xf7, 0xfc, 0x7d, 0x9e, 0x0f,
- 0xdc, 0xbb, 0x38, 0x46, 0xff, 0x7d, 0x8f, 0x9e, 0x1b, 0x9d, 0x2e, 0x3d,
- 0xfe, 0xfa, 0x80, 0x79, 0xe7, 0x78, 0x75, 0xaf, 0x27, 0x4f, 0x7c, 0x3f,
- 0xe3, 0xd1, 0xc5, 0xbb, 0x69, 0xa4, 0x89, 0xf7, 0xf2, 0x5f, 0xc0, 0xa3,
- 0xf3, 0x8c, 0x82, 0x4a, 0x23, 0x6f, 0x49, 0x31, 0x56, 0xc1, 0xe6, 0xc5,
- 0xc2, 0x9d, 0x24, 0xec, 0x69, 0xec, 0x7a, 0xb7, 0xc4, 0x7b, 0xbe, 0x05,
- 0x1f, 0xcd, 0x7b, 0xff, 0x50, 0xe6, 0x4a, 0xfd, 0x76, 0xb3, 0x41, 0x7b,
- 0x4d, 0x24, 0xcf, 0xcb, 0xb0, 0x7d, 0x5e, 0xe7, 0x4f, 0x89, 0xf8, 0x29,
- 0xa1, 0x6c, 0x6f, 0xc9, 0x80, 0xce, 0x6b, 0x3e, 0x14, 0x0b, 0x72, 0x99,
- 0x2a, 0xc3, 0xc6, 0xc6, 0xfe, 0xcd, 0xd1, 0xf9, 0x28, 0xf2, 0xa5, 0x1b,
- 0x3b, 0xe0, 0x7a, 0x53, 0xe3, 0x21, 0xbe, 0x46, 0x5c, 0x86, 0xb4, 0x8c,
- 0xf9, 0xf8, 0x2c, 0x99, 0xaf, 0xfb, 0x38, 0xc3, 0xf0, 0xc3, 0xf0, 0x01,
- 0x63, 0xbf, 0xe1, 0xe9, 0x0b, 0xbf, 0x7f, 0xe8, 0x30, 0x07, 0x52, 0xe9,
- 0x3f, 0xf7, 0xe6, 0xae, 0x50, 0x06, 0x18, 0xfb, 0x72, 0x7f, 0xd1, 0xf3,
- 0x39, 0x05, 0x23, 0x53, 0xa7, 0x0c, 0xa8, 0x2b, 0xb8, 0x7f, 0xad, 0x9f,
- 0xb0, 0x99, 0xf2, 0x17, 0x10, 0x1f, 0xbb, 0xdd, 0xbc, 0x01, 0xb5, 0x55,
- 0xa6, 0xce, 0xb9, 0xf5, 0x96, 0xac, 0xdd, 0xe4, 0xd9, 0xd2, 0x41, 0xcc,
- 0x4d, 0xe1, 0x8f, 0xb2, 0x23, 0xcc, 0x61, 0x7c, 0x67, 0x3c, 0x38, 0x19,
- 0xcf, 0x22, 0x66, 0x65, 0x0e, 0x4f, 0x60, 0x6c, 0x78, 0x35, 0x96, 0x96,
- 0x7b, 0x05, 0x39, 0x0a, 0xe4, 0x39, 0x00, 0x7e, 0xe2, 0x32, 0x51, 0xc7,
- 0x9d, 0x6f, 0xf9, 0xb3, 0x2d, 0x98, 0xc2, 0x6d, 0x18, 0xd7, 0xf7, 0x4d,
- 0xd4, 0x7f, 0xec, 0xd0, 0x1f, 0xfc, 0xad, 0xb6, 0x97, 0x78, 0x43, 0xde,
- 0x97, 0x31, 0x9e, 0x28, 0x4f, 0x1a, 0x87, 0xca, 0xdc, 0xa3, 0x5e, 0xea,
- 0x11, 0x2b, 0x9e, 0x55, 0xc8, 0x51, 0xc7, 0x3a, 0x71, 0xe6, 0x29, 0xe8,
- 0x46, 0xc1, 0x98, 0x1a, 0xea, 0x92, 0x7c, 0xb2, 0x07, 0x34, 0x3f, 0x82,
- 0x1e, 0xb1, 0xc3, 0xfa, 0x35, 0xcc, 0x43, 0x8f, 0x92, 0xb4, 0x8f, 0x56,
- 0x5d, 0x57, 0x4e, 0xeb, 0xb8, 0x35, 0xe0, 0xe9, 0xd6, 0x3f, 0x99, 0xae,
- 0x2e, 0x3d, 0x8d, 0xf1, 0x2e, 0xcc, 0xff, 0x26, 0x7a, 0xc4, 0xac, 0x31,
- 0x7f, 0x9e, 0x36, 0x38, 0x8e, 0xf9, 0xcf, 0x01, 0xc7, 0x9f, 0xe0, 0xfb,
- 0x7e, 0x7c, 0xff, 0xd1, 0xb6, 0xbd, 0xdf, 0xe0, 0xd9, 0x98, 0xcf, 0x6e,
- 0x9b, 0xf7, 0xfd, 0xb7, 0x8e, 0x93, 0xd2, 0xbd, 0x06, 0xc6, 0xd7, 0x22,
- 0xb2, 0xfb, 0x7c, 0x9b, 0xa8, 0xaa, 0xeb, 0xc3, 0x55, 0xd5, 0x94, 0x9e,
- 0xf3, 0xf4, 0xdf, 0x3f, 0xc2, 0x1e, 0x4b, 0xd4, 0x1a, 0x2e, 0x8d, 0x77,
- 0xab, 0x6d, 0xf4, 0x99, 0xe3, 0x7d, 0x4b, 0xec, 0x0b, 0xc7, 0x47, 0x6b,
- 0x84, 0xe1, 0xf7, 0x89, 0xe3, 0x7d, 0xb5, 0x9f, 0x00, 0x16, 0x72, 0x29,
- 0xfb, 0xf8, 0x09, 0xff, 0xda, 0xb6, 0x33, 0xb5, 0x6c, 0x71, 0x26, 0xed,
- 0xfe, 0x99, 0xe3, 0xd9, 0x0a, 0xf3, 0x83, 0x44, 0x4c, 0x74, 0x1e, 0x5e,
- 0x38, 0x3e, 0x53, 0x0a, 0x4b, 0x48, 0xd3, 0xe2, 0xaf, 0x73, 0x8d, 0xf7,
- 0xb0, 0x13, 0x6d, 0xa4, 0xab, 0x11, 0x0f, 0xe3, 0x0c, 0xf1, 0x9c, 0x00,
- 0x9e, 0x24, 0xf0, 0x30, 0xde, 0xb8, 0xf4, 0xc6, 0x97, 0x76, 0xa2, 0x8d,
- 0xb8, 0x78, 0x96, 0x8f, 0xaf, 0x47, 0xd4, 0xf9, 0xb7, 0x49, 0xaf, 0xc9,
- 0x9c, 0xd6, 0xf5, 0x35, 0x4d, 0x92, 0x3f, 0x8b, 0xdc, 0xc6, 0x1e, 0xf3,
- 0xc6, 0x77, 0x9b, 0xac, 0xb7, 0xe3, 0x8a, 0xf3, 0xec, 0xb1, 0x96, 0x8a,
- 0x63, 0x0e, 0xe3, 0x65, 0x1f, 0x56, 0x79, 0xb0, 0x1d, 0x0d, 0x7c, 0x37,
- 0x79, 0xb2, 0xe6, 0x99, 0x7e, 0xdd, 0xd9, 0x48, 0x0b, 0x40, 0x71, 0x0f,
- 0xdd, 0x5b, 0xf7, 0xe0, 0xf3, 0x89, 0x85, 0x35, 0xd2, 0x96, 0x04, 0xaf,
- 0x3e, 0x6d, 0x9f, 0xf6, 0xfe, 0xb8, 0x37, 0x89, 0x3f, 0xff, 0x3c, 0x5f,
- 0x06, 0xa4, 0x8b, 0x3d, 0x74, 0xf9, 0x13, 0x75, 0x73, 0x12, 0x76, 0xc7,
- 0x37, 0x10, 0xc7, 0x59, 0xb5, 0x29, 0xfb, 0x16, 0xdc, 0xbb, 0xf6, 0xb1,
- 0xa8, 0x21, 0x14, 0x73, 0xb9, 0x38, 0xeb, 0xd5, 0xa3, 0xb2, 0x09, 0x5c,
- 0x19, 0xd4, 0x94, 0x6e, 0x5d, 0x34, 0x0d, 0xff, 0xb8, 0x0e, 0xfd, 0xbc,
- 0x6a, 0xf1, 0x2d, 0x26, 0xcc, 0x78, 0x27, 0xc5, 0xda, 0xcf, 0x01, 0xc3,
- 0x3c, 0xea, 0xf6, 0x3b, 0xcb, 0x12, 0x60, 0x96, 0xb1, 0x76, 0xca, 0xf5,
- 0xcb, 0xf4, 0xed, 0xc8, 0xa9, 0x50, 0xc3, 0x58, 0xff, 0xe3, 0xe4, 0xa3,
- 0x8d, 0xb0, 0x3b, 0xbd, 0x83, 0x20, 0xe6, 0x2c, 0x26, 0xe6, 0x97, 0xe0,
- 0xc3, 0x2b, 0x96, 0xda, 0xad, 0xb4, 0x46, 0x26, 0x2a, 0xf0, 0x49, 0xa8,
- 0x78, 0x13, 0xf1, 0x25, 0x79, 0x5f, 0xdf, 0x43, 0x93, 0x35, 0x6c, 0xf6,
- 0xa8, 0xaf, 0x52, 0xaf, 0x34, 0xe5, 0xa1, 0x33, 0x88, 0xcb, 0x23, 0x4f,
- 0x20, 0xe6, 0x40, 0x5e, 0x67, 0x0a, 0xa8, 0xe2, 0xa9, 0x23, 0x3f, 0xf8,
- 0x83, 0x19, 0xcb, 0xcd, 0xff, 0x75, 0x3c, 0x13, 0x97, 0xc7, 0xd0, 0x99,
- 0x76, 0xed, 0x67, 0xf2, 0xda, 0xdf, 0xf4, 0x9b, 0x53, 0xaa, 0x0d, 0x39,
- 0x06, 0x12, 0x4f, 0x64, 0x38, 0xe6, 0xa0, 0x48, 0x1f, 0xf3, 0x4e, 0xf8,
- 0xe1, 0xbe, 0x35, 0x78, 0xb7, 0x33, 0x84, 0x57, 0x12, 0x3e, 0x13, 0x92,
- 0xa6, 0x33, 0x7c, 0x0b, 0x91, 0x3d, 0xa8, 0xc3, 0x88, 0xb3, 0x2f, 0x8c,
- 0x7e, 0x02, 0x7f, 0xfb, 0x90, 0x5f, 0x99, 0xc8, 0x8d, 0x77, 0x80, 0x07,
- 0x2c, 0xf7, 0xec, 0x04, 0xdf, 0xd5, 0x2d, 0x6d, 0x11, 0xec, 0x21, 0x3c,
- 0xf2, 0x43, 0x6b, 0x0f, 0xe8, 0x71, 0xcf, 0x27, 0x8e, 0xf0, 0x19, 0x91,
- 0xfe, 0x05, 0xe9, 0x51, 0x7a, 0x4f, 0x58, 0x66, 0x52, 0x5c, 0x6b, 0x07,
- 0x3c, 0xf7, 0x61, 0x4d, 0xef, 0x73, 0xdf, 0x94, 0xf2, 0xb7, 0xe9, 0xc6,
- 0x9c, 0x81, 0x6f, 0xe4, 0x53, 0x29, 0x53, 0xfa, 0xab, 0x2e, 0x6c, 0xdf,
- 0xda, 0x53, 0xdd, 0x7c, 0x97, 0x52, 0x96, 0x4b, 0x9b, 0x42, 0xee, 0x9b,
- 0x87, 0x54, 0xc3, 0x83, 0x7c, 0x9b, 0x21, 0x0c, 0xeb, 0xd9, 0x2e, 0x0d,
- 0x63, 0x0e, 0x52, 0x7e, 0xee, 0x9c, 0x52, 0xff, 0xd7, 0x9b, 0x4b, 0x63,
- 0x4e, 0xa1, 0x6d, 0x05, 0xfb, 0xbf, 0xa9, 0x6d, 0x45, 0x54, 0xdc, 0xb3,
- 0x15, 0x8c, 0x97, 0x39, 0xf6, 0x63, 0xf1, 0xf1, 0x7b, 0x5c, 0x7f, 0xef,
- 0xc8, 0xac, 0xcd, 0xf7, 0x0b, 0x47, 0xae, 0xda, 0x05, 0xe3, 0xc0, 0x1d,
- 0x79, 0x66, 0x52, 0xc7, 0xe7, 0x19, 0xc8, 0x7e, 0xb3, 0xa6, 0x6b, 0x35,
- 0xb9, 0x56, 0x8b, 0xc8, 0x3b, 0x2b, 0x6d, 0xb2, 0xb9, 0xe4, 0xea, 0xfc,
- 0xe6, 0x12, 0xf5, 0xdc, 0x94, 0x9f, 0xad, 0x58, 0x58, 0x4b, 0xe2, 0xaf,
- 0x47, 0x6e, 0xac, 0xdc, 0x99, 0x77, 0x5e, 0xae, 0x3f, 0x0a, 0x5a, 0x7a,
- 0x24, 0x64, 0x39, 0xba, 0xee, 0xca, 0x21, 0xf6, 0x15, 0x64, 0x42, 0xf2,
- 0xe5, 0x7e, 0xd4, 0x7e, 0x08, 0xce, 0x61, 0xc6, 0x20, 0xdc, 0x7f, 0xf9,
- 0xf3, 0xc8, 0x4d, 0x12, 0x30, 0x9e, 0x7e, 0xfd, 0xa6, 0xf8, 0xc5, 0x70,
- 0x8f, 0x34, 0x5b, 0xdf, 0xec, 0x76, 0x63, 0x95, 0xe9, 0xd6, 0xa7, 0x96,
- 0x1f, 0xaf, 0xdf, 0x04, 0xee, 0x11, 0xe8, 0x29, 0x75, 0xd3, 0x86, 0xce,
- 0x9a, 0xb2, 0x3a, 0x94, 0xa8, 0x14, 0x84, 0xfe, 0x21, 0xc5, 0x7c, 0x11,
- 0xfb, 0x92, 0x90, 0x47, 0xab, 0xce, 0x85, 0x32, 0x0a, 0x77, 0xbb, 0x30,
- 0x27, 0xf9, 0xfa, 0xef, 0x63, 0x3e, 0x23, 0xd3, 0xf5, 0x71, 0x9c, 0x75,
- 0x1a, 0x7a, 0xfb, 0x60, 0x8f, 0xb4, 0xf1, 0x9c, 0x14, 0x68, 0x7c, 0x44,
- 0x66, 0xce, 0xce, 0xc9, 0x91, 0x32, 0xe9, 0xe4, 0x1b, 0x63, 0x22, 0x99,
- 0x93, 0xe1, 0xf8, 0x0a, 0x72, 0x27, 0xd7, 0x1e, 0xd3, 0x32, 0x73, 0x0e,
- 0x38, 0xca, 0xac, 0xff, 0xfb, 0xa1, 0x37, 0xc3, 0xba, 0x7e, 0x99, 0xd6,
- 0x7e, 0x87, 0xf3, 0x6f, 0xe3, 0x9e, 0xfa, 0x0b, 0xfb, 0x00, 0x97, 0x47,
- 0xad, 0x33, 0x85, 0x7c, 0x79, 0xb9, 0x8c, 0x3a, 0xcf, 0x0e, 0x31, 0xf7,
- 0x52, 0xea, 0xa1, 0x5e, 0xa9, 0x96, 0x87, 0x4d, 0xa5, 0x98, 0x53, 0xf1,
- 0x2e, 0xb8, 0x46, 0xfb, 0x8e, 0xa9, 0xb0, 0xd5, 0x2b, 0x2b, 0xe5, 0x02,
- 0xea, 0x65, 0xe5, 0xbd, 0x67, 0x14, 0xc4, 0xb4, 0x5c, 0xbf, 0xa7, 0x6b,
- 0x1b, 0xe6, 0x9f, 0xf5, 0x2f, 0x80, 0xc6, 0x0c, 0x2e, 0xf3, 0x24, 0xe8,
- 0xc3, 0xf7, 0x32, 0x74, 0x7c, 0x81, 0x39, 0x5c, 0x06, 0x6b, 0x69, 0x39,
- 0x76, 0x61, 0x0a, 0x34, 0x74, 0x4a, 0xff, 0x9f, 0xd1, 0xc6, 0x9e, 0xc4,
- 0x1c, 0xc7, 0x09, 0xe8, 0xeb, 0xd7, 0xf1, 0x4d, 0xd8, 0x18, 0x7a, 0xca,
- 0xa1, 0x17, 0xbd, 0x09, 0x5a, 0x58, 0x07, 0x43, 0xfe, 0x87, 0xe3, 0x52,
- 0x3d, 0xfb, 0xb0, 0x4c, 0x2f, 0x3f, 0x0c, 0xfc, 0xff, 0x8a, 0xba, 0x00,
- 0xf1, 0x6d, 0x99, 0x67, 0x31, 0xff, 0xe3, 0x39, 0x10, 0x10, 0x6d, 0x63,
- 0x81, 0xf3, 0xec, 0x0f, 0x62, 0x3f, 0x6a, 0x8c, 0x72, 0x46, 0x66, 0xca,
- 0x3c, 0x0b, 0x77, 0x87, 0x7c, 0x2a, 0x7f, 0x76, 0xca, 0xbb, 0xe3, 0x1e,
- 0xc9, 0x45, 0x0b, 0xac, 0x2f, 0x10, 0x27, 0x96, 0x46, 0xb3, 0xa5, 0x84,
- 0x99, 0x55, 0xc4, 0x95, 0x14, 0xc6, 0x06, 0x77, 0x2e, 0x22, 0xd6, 0x02,
- 0x6a, 0xda, 0x34, 0xd7, 0x4e, 0x7a, 0x6f, 0x06, 0xc4, 0xf5, 0x63, 0x99,
- 0x80, 0x8e, 0xf5, 0x2f, 0x8c, 0x20, 0x17, 0xfe, 0x29, 0x72, 0xc9, 0xb8,
- 0x27, 0x83, 0x71, 0x4f, 0x37, 0xda, 0x1a, 0x74, 0x02, 0xf7, 0x5c, 0xc6,
- 0xdd, 0x97, 0xa1, 0x07, 0xf0, 0xd5, 0xaf, 0x6e, 0xe9, 0xc7, 0x78, 0x43,
- 0x8e, 0xd9, 0x21, 0xff, 0x50, 0x49, 0x24, 0xd7, 0xa1, 0x3f, 0x37, 0x50,
- 0x0b, 0xac, 0xa3, 0x3e, 0xdc, 0xb4, 0x23, 0xa8, 0x4b, 0x0e, 0x83, 0x7e,
- 0xe6, 0x94, 0x1c, 0xc7, 0x74, 0xae, 0xd3, 0x62, 0x3d, 0x7f, 0x8f, 0x7e,
- 0xd7, 0x95, 0xaf, 0xf6, 0xb0, 0xa6, 0x64, 0x3d, 0xce, 0x37, 0xe9, 0x77,
- 0x70, 0x8f, 0xeb, 0x26, 0xd7, 0xfd, 0x7d, 0xac, 0x05, 0x7c, 0xfd, 0x21,
- 0x2d, 0xd4, 0x1f, 0xee, 0x21, 0x4c, 0x8f, 0xb6, 0x93, 0xbc, 0xc6, 0x47,
- 0x9d, 0xfd, 0x9b, 0x6e, 0xd7, 0xce, 0x74, 0x9e, 0x65, 0x5e, 0x13, 0x5f,
- 0x7f, 0x3f, 0x74, 0x58, 0xd7, 0x65, 0x87, 0xe0, 0xbb, 0xeb, 0x8e, 0xbc,
- 0x60, 0xdf, 0x69, 0x77, 0xfb, 0xcb, 0xbe, 0x9c, 0x28, 0xc7, 0xc3, 0x72,
- 0xaa, 0x9e, 0x80, 0x4d, 0x50, 0x86, 0x56, 0x83, 0x0c, 0x45, 0xfe, 0xaa,
- 0x2c, 0xf2, 0x4a, 0x99, 0x6b, 0x5a, 0x86, 0xb1, 0x6c, 0xa8, 0x8d, 0xef,
- 0xea, 0xd0, 0xcb, 0xb7, 0xe5, 0xc8, 0xa2, 0xc8, 0x05, 0xac, 0xaf, 0x96,
- 0x69, 0xab, 0x23, 0xc8, 0x5f, 0x77, 0x49, 0x75, 0x09, 0x35, 0x59, 0x59,
- 0xa6, 0xb3, 0x9f, 0x63, 0xbc, 0x89, 0xc8, 0xa6, 0x7e, 0x8f, 0x15, 0x19,
- 0xbc, 0x18, 0x96, 0xf0, 0x45, 0x14, 0x7f, 0x90, 0xfd, 0xa5, 0x21, 0xff,
- 0x7d, 0xd6, 0xb5, 0xf9, 0x62, 0x09, 0x7b, 0xcb, 0xfd, 0xda, 0x4f, 0x16,
- 0x6b, 0x33, 0x92, 0xaf, 0xf0, 0x2c, 0xf4, 0x4b, 0x71, 0xac, 0xa5, 0x64,
- 0xf6, 0xec, 0x88, 0x3c, 0x8b, 0x33, 0x50, 0xff, 0xe1, 0x8c, 0x09, 0x29,
- 0x5c, 0xc0, 0x7c, 0xed, 0xba, 0x2c, 0xad, 0xcc, 0x48, 0xb5, 0x72, 0xb9,
- 0xe1, 0xdd, 0x1d, 0xe3, 0xa5, 0xc6, 0x5a, 0xf6, 0x30, 0xeb, 0x19, 0xd4,
- 0xaa, 0x16, 0xc6, 0x90, 0x59, 0x6d, 0x76, 0xfa, 0xce, 0xf7, 0xe2, 0xc6,
- 0x1a, 0x76, 0x52, 0xe6, 0xcb, 0x29, 0x29, 0x9e, 0x1d, 0xd1, 0x6f, 0x0a,
- 0x2d, 0xe9, 0xca, 0xd3, 0x37, 0x11, 0x2b, 0x26, 0xf5, 0x7b, 0xf1, 0x2d,
- 0x79, 0xcc, 0x9e, 0x97, 0xa3, 0xd6, 0x41, 0x39, 0x85, 0xfc, 0xfa, 0x4b,
- 0x76, 0xab, 0xc4, 0xbb, 0x79, 0x8f, 0xa0, 0xd7, 0x62, 0x0d, 0xea, 0xc8,
- 0x84, 0xfd, 0xa0, 0xf9, 0x3c, 0x24, 0xfb, 0x4e, 0x8d, 0x71, 0xf2, 0xbf,
- 0x9d, 0x0c, 0xe2, 0xde, 0x4d, 0xd4, 0x8e, 0x19, 0x0d, 0x67, 0xb8, 0x70,
- 0x15, 0xc2, 0x0d, 0x9b, 0x2f, 0x10, 0x6e, 0xc9, 0xf0, 0xe0, 0x0c, 0xc0,
- 0x85, 0x64, 0xc3, 0x0e, 0x43, 0x47, 0x26, 0xc1, 0x27, 0x7c, 0xfc, 0x68,
- 0x87, 0x97, 0x07, 0xb7, 0x22, 0xb6, 0xde, 0xde, 0xff, 0x86, 0xb7, 0xff,
- 0x59, 0x6f, 0xff, 0xd5, 0xad, 0xfd, 0x7e, 0x7c, 0xfd, 0x85, 0x23, 0x0d,
- 0x74, 0xbd, 0x51, 0x72, 0xe1, 0xe7, 0x3d, 0xba, 0xae, 0x6e, 0xd1, 0xe5,
- 0xc3, 0x43, 0x9e, 0x9a, 0x67, 0xfa, 0x66, 0xfa, 0xe8, 0x7e, 0xc8, 0xd1,
- 0x91, 0x9c, 0x0d, 0xdb, 0x28, 0x27, 0xc6, 0x0b, 0xfa, 0x2d, 0x4d, 0xc9,
- 0x7a, 0x74, 0x5e, 0x26, 0xad, 0xc4, 0xf8, 0xac, 0x84, 0xa0, 0xcb, 0xf4,
- 0x2d, 0x21, 0xa9, 0xd2, 0xe7, 0xa0, 0xcf, 0xdb, 0x3b, 0xd3, 0xfa, 0x4e,
- 0x03, 0xad, 0xa1, 0x97, 0x49, 0xa3, 0x4b, 0x6b, 0x64, 0xe0, 0x36, 0xad,
- 0x2e, 0xbc, 0x4b, 0xeb, 0x3b, 0xa5, 0x06, 0xf8, 0x8b, 0x61, 0x0f, 0x3e,
- 0xdc, 0x00, 0x4f, 0x7d, 0x66, 0x5e, 0x41, 0x7d, 0x26, 0x6d, 0x9f, 0x85,
- 0x6d, 0x48, 0xa4, 0x35, 0x5d, 0x39, 0xfe, 0xc0, 0x80, 0x23, 0x11, 0xe4,
- 0x1b, 0xcd, 0x58, 0xdb, 0xac, 0x30, 0x17, 0x51, 0x7d, 0xcd, 0x32, 0x08,
- 0x9d, 0xe5, 0xdd, 0xb9, 0x6f, 0x82, 0x8f, 0xe9, 0x9c, 0xc0, 0x91, 0xa3,
- 0x36, 0x69, 0x79, 0xdf, 0x79, 0x25, 0x3a, 0x68, 0x17, 0x65, 0xc8, 0x6c,
- 0xc6, 0xf9, 0xd5, 0xba, 0xc6, 0x99, 0x24, 0x2d, 0xe7, 0x87, 0xfa, 0xcd,
- 0xbf, 0x07, 0x9f, 0x13, 0x15, 0x43, 0xaa, 0x56, 0x22, 0x76, 0x09, 0x38,
- 0xf6, 0xe1, 0x6e, 0xaa, 0x23, 0xa4, 0x47, 0xe4, 0x08, 0xf4, 0xbb, 0xaa,
- 0xe3, 0x22, 0xf5, 0x38, 0x31, 0x59, 0x40, 0xae, 0xf3, 0xd7, 0x3a, 0xb6,
- 0x39, 0xce, 0x4d, 0xc4, 0xb7, 0xc9, 0x6d, 0xba, 0xa7, 0x2e, 0xba, 0xba,
- 0xa7, 0x2e, 0xa2, 0x06, 0x3e, 0x1d, 0x91, 0x96, 0x55, 0xd8, 0xcf, 0xcb,
- 0x7b, 0xdc, 0x7c, 0xee, 0x65, 0xfe, 0xe6, 0x04, 0x7f, 0x77, 0x3a, 0x2c,
- 0xd6, 0x69, 0x1d, 0x0f, 0x20, 0xef, 0x09, 0x99, 0x3d, 0x47, 0x9f, 0x6a,
- 0xc9, 0xc0, 0x69, 0xde, 0x07, 0xf3, 0x9a, 0xa5, 0xd1, 0x19, 0xd8, 0xc8,
- 0x1c, 0xfc, 0x82, 0x5a, 0x7d, 0x57, 0x66, 0x2c, 0xca, 0xa1, 0x53, 0xda,
- 0x56, 0x51, 0x8f, 0xaf, 0xc2, 0x37, 0xac, 0xc6, 0xa4, 0x09, 0xb6, 0xa5,
- 0x2e, 0x46, 0x8d, 0xe2, 0xe2, 0x07, 0xb0, 0x07, 0xfe, 0x7e, 0x83, 0xdc,
- 0xf2, 0x62, 0xcc, 0xa0, 0x6d, 0xa9, 0x8b, 0xd4, 0x73, 0xa4, 0x53, 0x17,
- 0xa9, 0xe7, 0xa4, 0xc3, 0xb7, 0x17, 0x7c, 0x5f, 0x1c, 0xd1, 0xef, 0xd3,
- 0x37, 0x6d, 0xf2, 0xf2, 0x8f, 0x92, 0xad, 0x30, 0x47, 0x24, 0x3f, 0xd2,
- 0x8d, 0x5c, 0xa6, 0x2b, 0x6b, 0x0f, 0x8c, 0x6f, 0xca, 0xa7, 0xe5, 0xeb,
- 0xee, 0x4f, 0xc1, 0x17, 0xf9, 0x68, 0xe4, 0x8b, 0x3c, 0x75, 0x4a, 0x93,
- 0xe6, 0xcb, 0xe7, 0x07, 0x82, 0x06, 0x3f, 0x7d, 0xa7, 0x63, 0xc0, 0xff,
- 0x75, 0xf8, 0x80, 0x5e, 0xf4, 0x4f, 0xa2, 0x47, 0x48, 0xbb, 0x48, 0xde,
- 0xc9, 0xeb, 0x0d, 0xe4, 0x8d, 0x3e, 0x9f, 0xd3, 0xf8, 0x7e, 0x5d, 0x66,
- 0x17, 0x9d, 0x93, 0x88, 0xab, 0x7c, 0x3b, 0xef, 0x71, 0xdf, 0x81, 0xb7,
- 0xf3, 0xfe, 0xba, 0xb8, 0xf2, 0x49, 0x98, 0x55, 0xc1, 0xf7, 0xca, 0x76,
- 0x59, 0x34, 0xfa, 0x8e, 0x98, 0xce, 0xc3, 0x8f, 0xd4, 0xe8, 0x27, 0x28,
- 0xa3, 0x1b, 0x92, 0x5d, 0xe4, 0xfb, 0x97, 0x8b, 0x6f, 0xba, 0xe6, 0xfb,
- 0x8d, 0xc6, 0x3d, 0x36, 0xe0, 0x7a, 0x01, 0x47, 0xba, 0xd6, 0x29, 0x3f,
- 0xf8, 0x9c, 0xbd, 0x0d, 0xbe, 0xa6, 0x71, 0xdf, 0xb8, 0x3c, 0x87, 0x3c,
- 0xe0, 0x0d, 0xfb, 0x0e, 0xb9, 0x4e, 0x33, 0x17, 0xaa, 0xd6, 0xa6, 0x60,
- 0x93, 0x4d, 0xf0, 0x65, 0xa6, 0x6c, 0x96, 0x9a, 0xa5, 0x8a, 0x7c, 0x67,
- 0x79, 0x85, 0xbe, 0x90, 0xb4, 0xb7, 0x61, 0xde, 0xf5, 0x5f, 0xf4, 0xb5,
- 0x9b, 0x25, 0xc4, 0x59, 0xd8, 0xf6, 0x66, 0x29, 0x8a, 0xbe, 0x17, 0xbd,
- 0x85, 0x3e, 0x8e, 0x3e, 0x89, 0x7e, 0x04, 0xfd, 0x08, 0x7a, 0x0b, 0x7b,
- 0x63, 0xe8, 0xfd, 0x9a, 0x81, 0xb8, 0x6e, 0xf3, 0x5d, 0xd4, 0xe7, 0x21,
- 0x57, 0xb4, 0x18, 0xd3, 0xc2, 0x76, 0x0e, 0x75, 0x44, 0x76, 0x84, 0xb9,
- 0x1e, 0x73, 0xbe, 0x8f, 0x1d, 0xd3, 0x62, 0x5d, 0x5e, 0x30, 0xf6, 0x0d,
- 0x31, 0x2e, 0x54, 0x10, 0x17, 0x3e, 0xd8, 0x8d, 0xfa, 0xd1, 0xdc, 0xaf,
- 0xdf, 0x8e, 0x16, 0x31, 0xe6, 0x37, 0x6a, 0xde, 0xe8, 0x1c, 0xe2, 0x14,
- 0xfd, 0xa7, 0x83, 0x3d, 0x79, 0xf8, 0xf1, 0x2e, 0xd8, 0x5f, 0x06, 0x7e,
- 0x1b, 0xdf, 0x4b, 0x6f, 0xec, 0x76, 0x63, 0x2a, 0xf2, 0x77, 0xb5, 0xfd,
- 0xbd, 0xc6, 0xc6, 0x9e, 0x9d, 0x6a, 0x83, 0x0e, 0xe0, 0x48, 0x54, 0x96,
- 0x60, 0x83, 0x3f, 0xb4, 0x4f, 0xea, 0xdc, 0x8e, 0x77, 0xf1, 0x2c, 0x72,
- 0xd4, 0xdc, 0x02, 0x73, 0x98, 0x13, 0xa8, 0x4b, 0x50, 0x9f, 0x45, 0x59,
- 0x93, 0x33, 0x16, 0xe8, 0x5c, 0x34, 0x2a, 0x6d, 0x8c, 0x03, 0x37, 0x70,
- 0x1e, 0xf8, 0x5a, 0x76, 0x20, 0xb3, 0x03, 0xc8, 0x09, 0x1d, 0x27, 0x6c,
- 0xed, 0x93, 0xf8, 0x21, 0xfa, 0x1c, 0xc1, 0x7e, 0x53, 0xdc, 0xf7, 0x74,
- 0xf8, 0xdd, 0x29, 0xfd, 0x5b, 0x31, 0x94, 0xeb, 0xb3, 0xd8, 0x7b, 0x17,
- 0x70, 0x71, 0x9e, 0x6f, 0xd9, 0x22, 0xfb, 0x16, 0xdc, 0x9c, 0x56, 0x59,
- 0x8d, 0xf8, 0x7e, 0xd5, 0xc3, 0xc7, 0x75, 0xe5, 0xfd, 0xa6, 0xb1, 0xc7,
- 0x7d, 0x1b, 0xc6, 0x1d, 0x9f, 0x42, 0xfe, 0xbc, 0x81, 0x7b, 0x79, 0x03,
- 0x77, 0x72, 0xa5, 0x44, 0x5d, 0x1f, 0x86, 0xde, 0x43, 0x86, 0x53, 0xc4,
- 0x35, 0xa2, 0xcf, 0xde, 0x28, 0xc1, 0x77, 0xd2, 0xff, 0x29, 0x64, 0x77,
- 0x6d, 0x6e, 0x4c, 0x77, 0xf1, 0xf4, 0xba, 0x70, 0xe2, 0xaf, 0xed, 0xd6,
- 0xf4, 0x54, 0xf5, 0x3b, 0x18, 0xe5, 0x04, 0x1d, 0xe4, 0x6f, 0x03, 0x1a,
- 0xe6, 0x6b, 0x51, 0xfd, 0xfe, 0xae, 0x38, 0x47, 0x3e, 0x46, 0x24, 0xbb,
- 0xe0, 0xef, 0xeb, 0xc6, 0xbe, 0xd6, 0x06, 0x5c, 0x77, 0x6f, 0xe3, 0x41,
- 0x79, 0x3c, 0x70, 0xfd, 0x93, 0x6f, 0xc3, 0x85, 0xad, 0xb7, 0x61, 0xc6,
- 0x5f, 0xde, 0x4d, 0x0a, 0xfb, 0xfd, 0xfb, 0xe9, 0xf5, 0x6a, 0x81, 0xc4,
- 0x7c, 0x41, 0x98, 0xab, 0xf0, 0x8e, 0xc6, 0x61, 0xd7, 0x5d, 0xc0, 0x6f,
- 0x4b, 0xa5, 0xd4, 0x22, 0xaa, 0x87, 0xb5, 0x31, 0x73, 0xe5, 0xc6, 0x33,
- 0x7f, 0xdb, 0x3b, 0x13, 0xf5, 0xf4, 0x19, 0xe6, 0xcd, 0x3a, 0xce, 0x00,
- 0xa6, 0x7d, 0x1b, 0x6d, 0xbf, 0xee, 0xc1, 0x71, 0x3d, 0x29, 0x05, 0xe4,
- 0xa1, 0xb9, 0x05, 0x64, 0xf4, 0xf0, 0xdf, 0x2a, 0xcd, 0xdf, 0xb3, 0xf8,
- 0x86, 0x37, 0x1c, 0x9f, 0x05, 0x8d, 0x05, 0x33, 0xc3, 0x77, 0x33, 0xe0,
- 0xd8, 0xbb, 0x0d, 0xc7, 0x84, 0x87, 0x63, 0x42, 0x8a, 0xe7, 0x26, 0x61,
- 0x6b, 0x19, 0xc4, 0xf7, 0x7e, 0xf3, 0x80, 0x7c, 0x1e, 0xc5, 0x35, 0xe6,
- 0x2e, 0x8c, 0xe0, 0x9e, 0x1c, 0x67, 0x9f, 0x7d, 0x18, 0x74, 0xbf, 0x86,
- 0xd8, 0xea, 0xe7, 0x3c, 0xc5, 0x58, 0x08, 0x31, 0xec, 0x98, 0xfe, 0x0d,
- 0xb6, 0x60, 0x9a, 0xd0, 0x57, 0x65, 0x0c, 0x27, 0x51, 0xde, 0x23, 0xbe,
- 0xcd, 0x23, 0x56, 0x91, 0xcf, 0x0e, 0x29, 0x9a, 0xc6, 0xa3, 0x21, 0xe4,
- 0x35, 0xd9, 0x05, 0xda, 0x91, 0x0c, 0x84, 0xd2, 0xcd, 0xc8, 0x49, 0x1d,
- 0xf9, 0x99, 0xcd, 0x7f, 0xa3, 0x30, 0x2f, 0x1b, 0x35, 0x13, 0xfd, 0x3a,
- 0xee, 0xe1, 0xdb, 0xf8, 0xbe, 0xde, 0x83, 0xbc, 0x0f, 0x2b, 0x19, 0xe8,
- 0x6e, 0x52, 0xe7, 0x33, 0xcc, 0x23, 0xaa, 0x88, 0xb7, 0x0a, 0xb1, 0x06,
- 0x79, 0xd5, 0x38, 0x73, 0xd7, 0xe7, 0x96, 0xaf, 0xcb, 0x95, 0x45, 0xfe,
- 0x06, 0xca, 0xb8, 0x7c, 0x90, 0xfe, 0xc0, 0x9c, 0x4b, 0x61, 0x6e, 0x85,
- 0xbe, 0x0c, 0xe3, 0x3a, 0x0c, 0xa8, 0x07, 0x39, 0x02, 0x72, 0xed, 0x4d,
- 0x2b, 0x09, 0x3e, 0xaf, 0xcb, 0xc6, 0x62, 0x58, 0x96, 0x2d, 0xe6, 0x45,
- 0x12, 0xcf, 0x02, 0x76, 0x63, 0xe5, 0x9a, 0xab, 0x13, 0x84, 0x47, 0xcd,
- 0x53, 0x40, 0x5e, 0x77, 0x40, 0xef, 0xfd, 0x65, 0xf7, 0x4c, 0x9a, 0x1a,
- 0xeb, 0xbc, 0x19, 0xd9, 0xa0, 0x3d, 0xd9, 0x7c, 0x93, 0x62, 0x6e, 0x70,
- 0x02, 0x3a, 0xcb, 0xdc, 0x9d, 0xf5, 0x00, 0xbe, 0x6b, 0x5c, 0x27, 0xef,
- 0xe8, 0x97, 0xfa, 0x21, 0x1b, 0xda, 0x3d, 0xdf, 0xc4, 0x10, 0x47, 0x15,
- 0x6d, 0xbd, 0xa8, 0x7d, 0x41, 0xb1, 0x3c, 0x83, 0x98, 0x02, 0x1f, 0xc0,
- 0xdf, 0x70, 0xa6, 0xa6, 0x70, 0x97, 0xe3, 0x80, 0xdb, 0x16, 0x4b, 0xd6,
- 0x8a, 0x3a, 0x2f, 0x53, 0xe7, 0x6f, 0xbf, 0xdf, 0xe4, 0x61, 0x3f, 0x6a,
- 0x0d, 0xba, 0x05, 0x1b, 0x52, 0x6b, 0x51, 0xf4, 0xf0, 0xc7, 0x6b, 0xa8,
- 0x2f, 0x4a, 0x7c, 0x1f, 0x42, 0x6d, 0x50, 0xe2, 0xdb, 0x49, 0x12, 0xfd,
- 0x08, 0xdf, 0x8b, 0x3c, 0xbf, 0x46, 0xfc, 0xa4, 0xc3, 0xf7, 0x2f, 0xcc,
- 0x25, 0xe9, 0x5f, 0xfc, 0x7c, 0xd2, 0xd5, 0x85, 0x53, 0x65, 0xfa, 0x10,
- 0xea, 0x75, 0x3f, 0xfc, 0x16, 0x75, 0xc1, 0xcd, 0x25, 0x57, 0x2a, 0xae,
- 0xcc, 0x66, 0xeb, 0x97, 0x75, 0x8c, 0xd8, 0x2f, 0x16, 0x74, 0x8c, 0xb2,
- 0xc3, 0x9a, 0x8e, 0x01, 0x97, 0x24, 0xa3, 0x7b, 0xca, 0xec, 0x75, 0xc9,
- 0xac, 0x8c, 0xc8, 0x0b, 0xda, 0x6f, 0xf9, 0x3e, 0x8b, 0x39, 0x64, 0x0c,
- 0xf2, 0x4b, 0xca, 0xf3, 0x67, 0xaf, 0x4b, 0xf6, 0x45, 0xfa, 0xad, 0xe1,
- 0x58, 0xab, 0x41, 0x5f, 0xe5, 0x48, 0x0d, 0xb1, 0xe9, 0x80, 0xcd, 0x7f,
- 0x07, 0x10, 0x42, 0x4d, 0xe7, 0x48, 0xf3, 0x68, 0xc2, 0x8e, 0x1b, 0xfd,
- 0x4f, 0xb6, 0x1a, 0x8c, 0x8d, 0xc3, 0xe6, 0x53, 0xe2, 0xbf, 0x47, 0xb5,
- 0xc8, 0x53, 0xfa, 0xad, 0x02, 0x66, 0xbb, 0xf0, 0x91, 0xfe, 0x1d, 0xe5,
- 0x66, 0x8a, 0xb2, 0xc6, 0x78, 0x8d, 0xf3, 0x85, 0xc8, 0xcd, 0x54, 0x93,
- 0x14, 0xef, 0x72, 0x9c, 0xa3, 0xa3, 0xa9, 0xdd, 0xee, 0xbf, 0x15, 0xf9,
- 0xc6, 0x5d, 0xae, 0x2f, 0x38, 0xea, 0x8d, 0x5f, 0x41, 0x4f, 0xdd, 0x66,
- 0xbc, 0x65, 0x7c, 0xe4, 0xbd, 0xa1, 0x5f, 0xe1, 0x37, 0x63, 0xef, 0x3c,
- 0x62, 0x2f, 0xe3, 0x65, 0x97, 0xe4, 0x0e, 0x6b, 0x9f, 0xc1, 0xf9, 0x82,
- 0x9b, 0x4b, 0x7b, 0x70, 0x95, 0x69, 0x99, 0xad, 0x30, 0x87, 0xda, 0x40,
- 0x2c, 0x1b, 0x82, 0xae, 0x32, 0xa6, 0x9d, 0x44, 0x3c, 0xe7, 0xef, 0xd2,
- 0x58, 0x5b, 0xe2, 0xbe, 0x44, 0x32, 0xae, 0xc0, 0xf3, 0x96, 0x4e, 0xdd,
- 0x8c, 0xf2, 0x3d, 0xea, 0xd2, 0x10, 0xee, 0xfd, 0x4f, 0x59, 0x5b, 0x0c,
- 0x68, 0x1d, 0xc9, 0xbe, 0x4c, 0xd9, 0xbb, 0xbf, 0x5b, 0x4b, 0xb7, 0x6b,
- 0x03, 0xcc, 0x03, 0x1e, 0x87, 0x5c, 0xf6, 0xdb, 0xd7, 0x19, 0xbb, 0xff,
- 0x5d, 0x59, 0xc3, 0xc9, 0xa7, 0x0c, 0xda, 0x36, 0xc6, 0x2b, 0x21, 0x59,
- 0x8a, 0x92, 0x7f, 0xc8, 0xcb, 0xa0, 0xed, 0xec, 0x24, 0x87, 0xed, 0x32,
- 0xf8, 0x4b, 0xc8, 0x80, 0xb2, 0xf4, 0x65, 0xc0, 0xef, 0x49, 0xdc, 0x17,
- 0x6b, 0x86, 0x7e, 0x5d, 0x47, 0x16, 0xeb, 0xee, 0xd9, 0xc5, 0x72, 0x23,
- 0xcd, 0xa4, 0x97, 0x77, 0x7a, 0x49, 0x72, 0xfa, 0x7e, 0xe7, 0x25, 0x57,
- 0xb9, 0x24, 0xfb, 0x2a, 0xf3, 0xf2, 0x98, 0xf5, 0x28, 0xf8, 0xbd, 0xe6,
- 0xcc, 0x58, 0xba, 0x56, 0x19, 0xcf, 0xff, 0x6f, 0xe7, 0x56, 0x1b, 0xdb,
- 0x56, 0x75, 0x86, 0x5f, 0x5f, 0xdb, 0x69, 0x1a, 0x9a, 0x70, 0xeb, 0x3a,
- 0x89, 0x9b, 0x66, 0xad, 0x1d, 0xdf, 0x7e, 0x88, 0xa4, 0xe8, 0x36, 0x64,
- 0x34, 0xea, 0x82, 0x62, 0x9c, 0x50, 0xc2, 0xe8, 0x44, 0xda, 0x75, 0x55,
- 0xb5, 0x31, 0x64, 0x39, 0xe9, 0x07, 0xd3, 0x06, 0xa3, 0xb0, 0x82, 0x18,
- 0x52, 0x8d, 0xdb, 0x6a, 0x9d, 0x96, 0xc6, 0xe9, 0x07, 0x6b, 0x37, 0x69,
- 0x9a, 0xe5, 0xa4, 0x2d, 0x48, 0x11, 0x2e, 0x88, 0x6e, 0xfb, 0xb1, 0x8d,
- 0x2a, 0x65, 0xec, 0xff, 0xf6, 0x67, 0xda, 0xd0, 0x16, 0x15, 0x18, 0xfc,
- 0xd8, 0xa4, 0xfe, 0xe0, 0x47, 0x25, 0xe8, 0xbc, 0xe7, 0x79, 0xcf, 0xbd,
- 0x8e, 0x6d, 0x82, 0x26, 0x2d, 0x52, 0xe4, 0x7b, 0xce, 0x3d, 0xf7, 0x9c,
- 0x73, 0xcf, 0xfb, 0xfd, 0xbe, 0xcf, 0xc5, 0xda, 0x13, 0x7d, 0x6b, 0xe5,
- 0x63, 0xf8, 0x1d, 0x27, 0x67, 0x6d, 0xc9, 0xd8, 0x83, 0xf2, 0x63, 0xcd,
- 0xe5, 0x33, 0x3e, 0x09, 0xc0, 0x27, 0x35, 0xb8, 0x02, 0x69, 0x77, 0x62,
- 0x37, 0x85, 0x3e, 0x65, 0x18, 0xb4, 0x8e, 0x1b, 0xbf, 0xd9, 0x36, 0xf7,
- 0x37, 0x9d, 0x81, 0xef, 0xee, 0x0e, 0xb4, 0xfb, 0x39, 0x5f, 0xe3, 0xdf,
- 0xfe, 0xc5, 0xab, 0xa1, 0x0d, 0xca, 0x0c, 0xf6, 0xf3, 0x96, 0xea, 0x59,
- 0x07, 0xbc, 0xc4, 0xdc, 0x74, 0x4c, 0xf3, 0x0f, 0xe1, 0x69, 0xea, 0xa8,
- 0xab, 0xd0, 0x51, 0x43, 0xd4, 0x5d, 0xc3, 0xb3, 0x2e, 0xf3, 0x03, 0x51,
- 0xf9, 0xf3, 0x14, 0xf5, 0x70, 0x5c, 0xfe, 0x34, 0xf5, 0x02, 0xf6, 0x93,
- 0x28, 0x32, 0x47, 0x79, 0x63, 0x26, 0x47, 0x3f, 0x49, 0xfd, 0xf9, 0xb4,
- 0xfb, 0xac, 0xda, 0x81, 0xb8, 0x95, 0x5f, 0x13, 0x56, 0x7d, 0xf3, 0xb4,
- 0xd6, 0x74, 0xe3, 0x56, 0xb7, 0xdc, 0x38, 0x6f, 0x74, 0x6c, 0x78, 0x3a,
- 0x1a, 0x18, 0x99, 0xa3, 0x5d, 0x4a, 0xc6, 0xb2, 0xd6, 0x0a, 0x39, 0x10,
- 0x65, 0xee, 0x39, 0x45, 0xfd, 0x0c, 0x5b, 0xd8, 0x6b, 0x67, 0xad, 0x66,
- 0xcf, 0xfe, 0xc4, 0x1a, 0xf4, 0xec, 0xd3, 0x9e, 0x9e, 0xe5, 0xbd, 0x14,
- 0x68, 0x4a, 0x5b, 0x94, 0x98, 0x19, 0xb5, 0x92, 0xb0, 0x79, 0xb8, 0x9e,
- 0xe7, 0xfc, 0x71, 0x39, 0x32, 0x7f, 0x18, 0xfe, 0x77, 0xaf, 0xbd, 0x87,
- 0x76, 0xd5, 0x1e, 0x22, 0x16, 0x07, 0xeb, 0x7f, 0xa9, 0x61, 0xae, 0xc7,
- 0xbd, 0xb9, 0x78, 0x1f, 0x72, 0x3e, 0xed, 0xc8, 0x04, 0x6c, 0xc9, 0x88,
- 0x6d, 0xf6, 0x5a, 0x3f, 0x76, 0x77, 0x75, 0xdd, 0x13, 0x05, 0xc7, 0xc3,
- 0x85, 0xe1, 0x17, 0xbe, 0xd0, 0xd7, 0x23, 0x5c, 0x93, 0xeb, 0xb5, 0x49,
- 0x7a, 0x1f, 0xf4, 0xcb, 0x34, 0xff, 0x73, 0x5e, 0xed, 0x0a, 0xf1, 0x4a,
- 0xb4, 0x6b, 0x19, 0xdb, 0xf4, 0x80, 0x37, 0xdf, 0xb6, 0x0e, 0x69, 0x89,
- 0xd6, 0x8c, 0x67, 0x6e, 0x85, 0xed, 0xb8, 0xe4, 0xe6, 0xf9, 0x5b, 0xa9,
- 0x44, 0x9c, 0x26, 0xd9, 0x63, 0xaf, 0x6b, 0x98, 0x63, 0x2b, 0xfa, 0x8c,
- 0x4f, 0x10, 0x9c, 0x0e, 0x78, 0xbe, 0xc5, 0x06, 0xfa, 0x4d, 0xde, 0x75,
- 0xb3, 0xe6, 0x64, 0xe2, 0x56, 0x57, 0xc3, 0x7b, 0x6c, 0xa8, 0xda, 0xe1,
- 0xb8, 0x45, 0xdd, 0xd9, 0x14, 0x95, 0x36, 0xf2, 0x50, 0x45, 0xfd, 0xf8,
- 0x90, 0x63, 0xb0, 0x16, 0x51, 0xe7, 0x60, 0x07, 0x73, 0xf6, 0x6f, 0xeb,
- 0xb9, 0xb5, 0xd2, 0x27, 0xc0, 0x35, 0xf8, 0xe4, 0x73, 0xf9, 0x5e, 0xe6,
- 0x7a, 0x31, 0x7f, 0x0b, 0xe7, 0x77, 0xbd, 0x73, 0x4e, 0xb8, 0x39, 0xeb,
- 0x7e, 0xc9, 0x9e, 0x37, 0xfc, 0x97, 0x76, 0xc0, 0x7b, 0x6d, 0x68, 0xcf,
- 0xd1, 0x26, 0x7c, 0xd1, 0x3c, 0xbe, 0x6d, 0xd8, 0xa2, 0xb6, 0xe1, 0x78,
- 0x81, 0xfc, 0x49, 0xbe, 0xf4, 0xf9, 0xd1, 0xd7, 0x79, 0xe4, 0x51, 0xea,
- 0xd9, 0x41, 0x39, 0x53, 0xe0, 0xd9, 0xa4, 0xb4, 0xa6, 0xb5, 0xf1, 0xec,
- 0x84, 0xe2, 0xb1, 0x7a, 0xa6, 0x13, 0x17, 0x73, 0x32, 0x2c, 0x57, 0x5d,
- 0x9e, 0x59, 0xa2, 0x98, 0x09, 0xb6, 0xd6, 0xbc, 0xff, 0x3e, 0x3d, 0xb3,
- 0xb0, 0xfa, 0x8c, 0x31, 0x8c, 0x7d, 0xc9, 0xa3, 0x77, 0x9b, 0x9e, 0x6d,
- 0xa6, 0x8e, 0x3e, 0x8f, 0xea, 0x39, 0x85, 0xa1, 0x13, 0x59, 0xc7, 0x0f,
- 0x47, 0xf8, 0x0c, 0xd7, 0xa5, 0xcf, 0xc7, 0xb5, 0xc8, 0x7b, 0x3d, 0xb0,
- 0xd8, 0xfd, 0x12, 0xdc, 0x01, 0xd1, 0xdf, 0xc1, 0x3a, 0x72, 0x00, 0xb2,
- 0xba, 0xd1, 0x60, 0x5f, 0xc6, 0x8d, 0xaf, 0x91, 0xb1, 0xde, 0xc2, 0x39,
- 0x22, 0x56, 0x81, 0x1f, 0x7d, 0xfc, 0xa7, 0x77, 0x30, 0x5f, 0xc6, 0xf3,
- 0xd7, 0x07, 0x30, 0x3f, 0xcf, 0x82, 0x32, 0x36, 0xb5, 0x8d, 0xbc, 0x3a,
- 0xaa, 0xf5, 0x41, 0x3e, 0x43, 0x39, 0xe6, 0x99, 0x91, 0x2e, 0x7f, 0xc3,
- 0xf3, 0x6c, 0x6f, 0x6d, 0xa0, 0x63, 0xd2, 0xdb, 0x9f, 0x7f, 0x3f, 0x2c,
- 0xe1, 0x0e, 0xea, 0xb8, 0xa8, 0x24, 0xa7, 0x19, 0xb3, 0xc0, 0x76, 0x8d,
- 0x73, 0xae, 0xff, 0xad, 0x8b, 0x33, 0xff, 0xa7, 0x2e, 0xce, 0x58, 0x1f,
- 0x29, 0xef, 0x84, 0x35, 0x8f, 0xf5, 0xc5, 0x74, 0x2d, 0xd6, 0xd1, 0xd5,
- 0xaf, 0xdd, 0x47, 0xab, 0x74, 0xfc, 0x51, 0x81, 0xf6, 0x2a, 0xa5, 0x39,
- 0xe5, 0x7f, 0x4e, 0xf1, 0x6c, 0xb9, 0xc7, 0xab, 0xdc, 0xe3, 0xf0, 0x82,
- 0x62, 0x20, 0xbf, 0xa6, 0x32, 0x7c, 0xb2, 0x40, 0x1d, 0xd3, 0x2a, 0xb3,
- 0x33, 0xbe, 0x9e, 0x19, 0xf3, 0x7c, 0xdc, 0xfc, 0x9a, 0x26, 0xd5, 0x33,
- 0xf0, 0x6e, 0x9c, 0x11, 0xcf, 0xbe, 0x74, 0x4b, 0xe9, 0x3c, 0xed, 0x6e,
- 0x12, 0x7d, 0xd1, 0x40, 0x69, 0x8e, 0xb5, 0x49, 0x62, 0x50, 0x86, 0x85,
- 0x75, 0xff, 0x11, 0xfb, 0x38, 0xe4, 0x2d, 0x26, 0xef, 0x4f, 0xd1, 0xa7,
- 0x6f, 0x82, 0x6f, 0xdc, 0xd6, 0x70, 0xbe, 0xdb, 0xab, 0x3e, 0x61, 0x3d,
- 0xdd, 0x37, 0x74, 0x4a, 0x0b, 0xf9, 0xdc, 0xb1, 0x6f, 0x08, 0x7d, 0x30,
- 0x5e, 0x67, 0x11, 0x0b, 0x30, 0xf6, 0x88, 0x6b, 0xec, 0x51, 0x2a, 0xb2,
- 0xaf, 0xd5, 0xcb, 0x2b, 0xb5, 0x2a, 0xaf, 0x90, 0xdf, 0x32, 0xea, 0x7f,
- 0x0f, 0xa9, 0xce, 0xca, 0x4f, 0xf5, 0x1a, 0xfc, 0x8a, 0x1d, 0x53, 0xde,
- 0x93, 0x3a, 0xde, 0x8b, 0x79, 0x6b, 0x3f, 0xdc, 0x69, 0x7c, 0x2b, 0x5b,
- 0xf5, 0x4d, 0x58, 0xc7, 0xd1, 0xae, 0x70, 0x7e, 0xf2, 0x06, 0x79, 0x84,
- 0x3a, 0xcf, 0x1f, 0xe7, 0xd3, 0xc3, 0x6f, 0x73, 0x3c, 0xf9, 0xbf, 0x16,
- 0x8b, 0xe0, 0xcb, 0xaa, 0xdf, 0xe7, 0xcb, 0x1d, 0xef, 0xd5, 0xda, 0x04,
- 0xca, 0x5d, 0x6d, 0x7d, 0xd2, 0x96, 0xc8, 0xf4, 0x12, 0x5d, 0xd2, 0xfd,
- 0xdc, 0xff, 0x4b, 0xcc, 0xed, 0x42, 0xde, 0x96, 0xa3, 0xcd, 0x51, 0xa5,
- 0x4d, 0x06, 0xb4, 0x89, 0x28, 0x6d, 0x18, 0xef, 0x3d, 0xe3, 0xf1, 0x5b,
- 0x2b, 0xce, 0x8b, 0xb9, 0x5a, 0xe8, 0xba, 0xbd, 0xd4, 0xf9, 0xcf, 0x77,
- 0x6a, 0x7d, 0xd0, 0xa1, 0xee, 0x5b, 0x05, 0x7d, 0xc6, 0xf6, 0x66, 0xf5,
- 0x47, 0x4c, 0xbc, 0x15, 0xd7, 0x3c, 0x68, 0x10, 0xfa, 0xb9, 0x34, 0x05,
- 0x5f, 0x8d, 0x78, 0xb7, 0x3a, 0x5a, 0x7d, 0xc7, 0x3b, 0xaf, 0x92, 0xd2,
- 0x86, 0x32, 0x40, 0xbd, 0xb9, 0x1a, 0xf3, 0xed, 0x8e, 0xf6, 0x81, 0xbf,
- 0x7e, 0x81, 0xfe, 0x8d, 0x1a, 0x4f, 0x04, 0x21, 0xf3, 0x37, 0xa7, 0x3a,
- 0xbc, 0x18, 0xce, 0x41, 0x1b, 0x71, 0xeb, 0x54, 0x84, 0x31, 0x05, 0xda,
- 0x5b, 0xa4, 0x69, 0x1a, 0xf1, 0x2b, 0xf4, 0xf8, 0x82, 0xda, 0xa3, 0x3e,
- 0xdc, 0xbf, 0x8b, 0x18, 0x3f, 0x5c, 0x1f, 0xc6, 0x73, 0xbd, 0x06, 0x8b,
- 0x10, 0xdd, 0xa4, 0x67, 0x5a, 0x9a, 0x4a, 0xc4, 0x0e, 0x8a, 0xd7, 0x37,
- 0xee, 0xaa, 0x3e, 0x58, 0xda, 0xd7, 0x43, 0xb2, 0xbb, 0x6a, 0x2f, 0x18,
- 0x47, 0xc3, 0x87, 0x9f, 0x31, 0xf6, 0x20, 0x5f, 0xec, 0x53, 0x5c, 0x54,
- 0x70, 0x68, 0x1e, 0x67, 0x49, 0x9f, 0x74, 0x11, 0x7e, 0xb8, 0x8b, 0x33,
- 0xa4, 0xdf, 0x5d, 0x39, 0x76, 0xc2, 0x4d, 0xb1, 0x3e, 0x06, 0x7d, 0x70,
- 0x4c, 0x46, 0x10, 0x17, 0x8c, 0x04, 0xdb, 0x98, 0x57, 0x86, 0x6f, 0x98,
- 0xf3, 0x72, 0x8f, 0x7d, 0xcc, 0x99, 0xca, 0xd9, 0x39, 0xee, 0x9d, 0xb2,
- 0x6d, 0x62, 0xef, 0xd2, 0x14, 0xf7, 0x6b, 0xf2, 0x10, 0x6c, 0x5b, 0xd3,
- 0x2e, 0x7e, 0x79, 0x16, 0x03, 0xf8, 0x1d, 0x84, 0x3c, 0x70, 0x2c, 0x7e,
- 0xe7, 0x16, 0xe5, 0xdd, 0xf3, 0xbe, 0x6d, 0x0f, 0xc8, 0x3b, 0x4e, 0xe5,
- 0xd8, 0x71, 0x77, 0x0d, 0xcf, 0xc0, 0xcd, 0xb1, 0x66, 0xed, 0x38, 0x6e,
- 0x5e, 0x2a, 0x95, 0x05, 0x77, 0x61, 0x8d, 0xa5, 0xb4, 0xa4, 0xfc, 0xff,
- 0x03, 0x67, 0x78, 0xfd, 0x3e, 0x4b, 0x0c, 0xfd, 0x48, 0x9b, 0xcf, 0xd7,
- 0xfe, 0x6a, 0x6d, 0x81, 0xaf, 0xff, 0xc8, 0x8f, 0xe4, 0xcb, 0x45, 0xd9,
- 0xa9, 0xfa, 0x7f, 0xb9, 0xe7, 0x6a, 0x75, 0xbf, 0xef, 0xdf, 0x52, 0xbf,
- 0x93, 0x17, 0x63, 0x1a, 0x1f, 0x6c, 0x9a, 0x6e, 0xd4, 0x09, 0x4f, 0x78,
- 0x75, 0x85, 0xe5, 0x78, 0x6f, 0xbf, 0xa7, 0x17, 0x52, 0xea, 0x3b, 0xa7,
- 0x6c, 0xea, 0x07, 0xee, 0xa7, 0x45, 0x26, 0x2e, 0xdc, 0x01, 0x4d, 0x7c,
- 0x1d, 0xcc, 0xb8, 0xcf, 0xd7, 0x1d, 0x6d, 0x9e, 0x2f, 0x6c, 0x49, 0xcf,
- 0x59, 0xfa, 0x4e, 0x0e, 0xf4, 0x68, 0xbb, 0x64, 0xc6, 0x83, 0x92, 0x3c,
- 0x1b, 0x8b, 0x19, 0x5f, 0x97, 0xfc, 0x07, 0x79, 0xd3, 0x3e, 0xad, 0x45,
- 0xa1, 0xff, 0x6e, 0xe1, 0xda, 0x86, 0x9f, 0x21, 0xcf, 0x7b, 0xfd, 0x7b,
- 0x76, 0x03, 0x8f, 0xee, 0xf0, 0x78, 0x94, 0xf7, 0x2d, 0x53, 0xff, 0xc0,
- 0xd8, 0x9e, 0xb3, 0xdc, 0xa3, 0x79, 0xae, 0xe7, 0xac, 0x89, 0xd7, 0xeb,
- 0x9f, 0xeb, 0xab, 0x3e, 0x87, 0xfb, 0xf0, 0x7d, 0xcd, 0xdc, 0x3b, 0x07,
- 0xe1, 0xd3, 0xf5, 0xd1, 0xe6, 0xd0, 0x7e, 0x6f, 0x74, 0x77, 0x0a, 0xf9,
- 0x3d, 0xe1, 0xf1, 0x1c, 0xf5, 0x4d, 0xc4, 0xd3, 0x37, 0x4b, 0xf6, 0x65,
- 0xc4, 0xe0, 0x4f, 0x98, 0x13, 0xa9, 0xb1, 0x2f, 0x4f, 0x98, 0x77, 0xab,
- 0xb3, 0x2f, 0x77, 0x7b, 0xf3, 0xf8, 0xf7, 0x7c, 0xbd, 0xe2, 0xb7, 0x7d,
- 0xbd, 0xd2, 0xe8, 0xd3, 0xfa, 0xb4, 0xaf, 0xed, 0xaf, 0x8f, 0xf9, 0xf2,
- 0xcb, 0xe6, 0x5d, 0xb2, 0x88, 0xd9, 0xe8, 0x53, 0x26, 0x72, 0x06, 0x2f,
- 0x6d, 0x9d, 0xb1, 0x88, 0xfb, 0x70, 0x7e, 0x22, 0xe9, 0xc8, 0x1d, 0x8d,
- 0xad, 0x4f, 0x5e, 0x18, 0xd3, 0x3c, 0x4f, 0xc9, 0xf5, 0xf4, 0x4e, 0x74,
- 0x17, 0xe4, 0xea, 0x4a, 0x64, 0x09, 0x53, 0x34, 0x73, 0x34, 0x0d, 0x3b,
- 0x94, 0xd2, 0x7a, 0xd9, 0xf7, 0xb0, 0xdf, 0x41, 0xc5, 0x73, 0xad, 0x74,
- 0x5e, 0x94, 0x47, 0xec, 0x8a, 0xd6, 0x6e, 0x9a, 0x87, 0x8a, 0x47, 0x9b,
- 0x4f, 0xfb, 0x7c, 0x4f, 0x7e, 0x9a, 0x39, 0x3a, 0x31, 0x53, 0x19, 0x0e,
- 0x6d, 0xeb, 0xb5, 0xf3, 0x42, 0xbc, 0xfe, 0xb0, 0x1c, 0x52, 0xdc, 0xf0,
- 0xab, 0xb8, 0xbf, 0x97, 0xf1, 0x65, 0x22, 0xa4, 0x78, 0xe0, 0x44, 0x6c,
- 0x12, 0xb2, 0x98, 0x75, 0x89, 0xef, 0x5f, 0xa5, 0x38, 0xff, 0x92, 0xd0,
- 0xcf, 0x22, 0xa6, 0xe0, 0x05, 0x39, 0xe8, 0x6e, 0x74, 0x17, 0xc4, 0xf8,
- 0xbf, 0x59, 0xad, 0x09, 0xad, 0x90, 0x49, 0x37, 0xd4, 0x9c, 0x2e, 0x1b,
- 0x19, 0x18, 0x0d, 0xa6, 0x56, 0x9e, 0x70, 0xa2, 0xcd, 0x3b, 0xcb, 0x90,
- 0xf1, 0x32, 0xf4, 0x7f, 0x39, 0x16, 0x18, 0x51, 0x6c, 0xda, 0x57, 0x24,
- 0xdd, 0x41, 0x3f, 0x9f, 0xfa, 0xe4, 0x01, 0xb9, 0x69, 0x6f, 0x96, 0x9b,
- 0x5b, 0x88, 0xc3, 0xec, 0x47, 0x9b, 0xba, 0x64, 0x10, 0x7d, 0x49, 0xf4,
- 0x35, 0x2b, 0x3f, 0x6a, 0x7c, 0x06, 0x9d, 0x75, 0xd3, 0xa6, 0xae, 0x5a,
- 0xcf, 0x5f, 0xbc, 0xeb, 0x22, 0x68, 0x42, 0x6c, 0xc7, 0x56, 0xb4, 0xa9,
- 0xe3, 0xec, 0x86, 0xfe, 0x2e, 0xb4, 0xef, 0xc3, 0x1c, 0x4d, 0xfa, 0x7e,
- 0x96, 0xb3, 0xcd, 0xd4, 0x39, 0xeb, 0xc6, 0xac, 0x6e, 0x68, 0xff, 0xb1,
- 0xdd, 0xe0, 0x13, 0x3e, 0x25, 0xbd, 0x73, 0x29, 0xd9, 0xd5, 0x59, 0xdf,
- 0xfe, 0x77, 0x43, 0xbb, 0x4d, 0x56, 0xb6, 0x93, 0x0c, 0x4f, 0x75, 0xd4,
- 0xf7, 0xfb, 0xfc, 0xe4, 0xb7, 0x3b, 0xf1, 0xbe, 0x09, 0x18, 0xbc, 0xa4,
- 0xc6, 0x52, 0x37, 0xa3, 0x5c, 0xeb, 0x83, 0x86, 0x67, 0x78, 0xcd, 0x67,
- 0xf8, 0x2c, 0xf3, 0x7a, 0x9f, 0xb1, 0x1f, 0xcf, 0x30, 0x27, 0xc0, 0xbc,
- 0x06, 0x79, 0x76, 0xb9, 0x38, 0x8b, 0x63, 0x3e, 0x9f, 0x6f, 0xc8, 0x54,
- 0x79, 0xcf, 0xd7, 0x2b, 0xb1, 0x2a, 0x56, 0x6d, 0x67, 0xc1, 0xcf, 0x09,
- 0x93, 0x76, 0x5a, 0x93, 0x8a, 0xdd, 0x00, 0x9d, 0x0f, 0x80, 0xce, 0x0f,
- 0x05, 0x19, 0x17, 0xb6, 0x78, 0xb4, 0x76, 0x64, 0xa4, 0xfc, 0x5b, 0xc8,
- 0x38, 0x79, 0x14, 0x3e, 0x45, 0xd9, 0xf2, 0xf0, 0x19, 0x03, 0xb0, 0x69,
- 0xae, 0x04, 0x35, 0xef, 0x80, 0xf8, 0x7e, 0xf6, 0xba, 0x8c, 0x4c, 0x31,
- 0x27, 0x40, 0x7e, 0x66, 0x5c, 0x9f, 0xc2, 0xbd, 0x5b, 0x18, 0xeb, 0x42,
- 0x86, 0xc7, 0xc0, 0xaf, 0x21, 0x71, 0xa6, 0xb7, 0x4a, 0x6e, 0x7c, 0x4c,
- 0x7d, 0x80, 0x1e, 0xd8, 0xa8, 0xe3, 0xee, 0xa8, 0x9c, 0xb8, 0xb2, 0x01,
- 0xb2, 0xca, 0xb8, 0x5f, 0x73, 0x1a, 0x95, 0xb0, 0xfa, 0xe6, 0xf4, 0x39,
- 0x98, 0x87, 0x33, 0x35, 0x66, 0x23, 0xb7, 0x93, 0x31, 0x69, 0x1b, 0x95,
- 0x99, 0x0b, 0xb6, 0xe2, 0x5d, 0x52, 0x72, 0xa7, 0x42, 0xda, 0x65, 0xf7,
- 0xc6, 0xa1, 0xab, 0xe8, 0xcb, 0x9f, 0x8c, 0x98, 0xb3, 0x7c, 0x74, 0x2d,
- 0x63, 0xe2, 0xe4, 0x74, 0xed, 0x1c, 0x8a, 0x91, 0xc1, 0xbd, 0xd7, 0xda,
- 0x8d, 0xcc, 0x30, 0x3e, 0xfe, 0xa0, 0x92, 0x8a, 0x72, 0x4d, 0x8e, 0x65,
- 0xed, 0x96, 0x3c, 0xc2, 0xbd, 0x7d, 0xea, 0xf1, 0xf2, 0xcf, 0x30, 0x5f,
- 0x5c, 0x7a, 0x5e, 0x1f, 0xd3, 0xb8, 0xfe, 0x78, 0x5d, 0x0c, 0x6b, 0xf2,
- 0x05, 0x26, 0x8e, 0xbd, 0x2e, 0x93, 0xf3, 0xa4, 0x0f, 0x6d, 0x7c, 0x40,
- 0x5e, 0x73, 0x7a, 0xed, 0x27, 0xb5, 0xd6, 0x98, 0x48, 0xb1, 0x3e, 0xd3,
- 0xe2, 0x24, 0xed, 0x59, 0x09, 0x0d, 0x7e, 0x15, 0xd7, 0x8c, 0x6b, 0xf3,
- 0x6e, 0xaf, 0xfb, 0xa4, 0xf8, 0x38, 0x90, 0x8d, 0xa9, 0x15, 0x81, 0xdb,
- 0x95, 0xeb, 0x7b, 0x39, 0xc6, 0xe0, 0x40, 0x24, 0x40, 0x5a, 0xbd, 0xb7,
- 0x9e, 0xf8, 0x99, 0xfa, 0xfc, 0xdf, 0x83, 0x4f, 0xef, 0x19, 0x48, 0x9c,
- 0x62, 0x0c, 0x1b, 0x76, 0xbe, 0xb5, 0xd6, 0xbc, 0x6b, 0x2e, 0xb7, 0x5a,
- 0xb4, 0x7e, 0x76, 0xe4, 0x23, 0x87, 0x78, 0x88, 0x44, 0x6c, 0x85, 0xc5,
- 0x3c, 0x38, 0x75, 0x1c, 0x6b, 0x2a, 0xcc, 0xb9, 0x11, 0xc7, 0xdf, 0x2c,
- 0x97, 0xfb, 0x2c, 0x79, 0x30, 0x94, 0x8a, 0x5b, 0xb2, 0x29, 0x7e, 0x56,
- 0xb0, 0x26, 0xeb, 0x2b, 0xf3, 0x89, 0x1c, 0xc7, 0x87, 0xa6, 0x39, 0x5f,
- 0x5c, 0xe3, 0x95, 0xe4, 0xa6, 0x4a, 0xe5, 0x19, 0x57, 0x02, 0xc9, 0x7b,
- 0x3f, 0xac, 0xb0, 0x16, 0x6e, 0xbd, 0xfe, 0x45, 0x38, 0x05, 0xea, 0x8a,
- 0x55, 0x93, 0x06, 0x73, 0x78, 0xe2, 0x48, 0xcf, 0x3c, 0xdb, 0xdf, 0x7d,
- 0xc4, 0xb4, 0x4f, 0xa1, 0xdd, 0xe4, 0x61, 0x9d, 0xa6, 0x8e, 0xf4, 0x14,
- 0x9f, 0x5a, 0x6b, 0xe2, 0xef, 0x45, 0xc5, 0x7f, 0xbd, 0x5d, 0x17, 0xd3,
- 0xa4, 0x02, 0xe3, 0x85, 0xb1, 0xc0, 0x58, 0xc1, 0xea, 0x6b, 0x06, 0xad,
- 0xe6, 0x5c, 0xe6, 0x6a, 0xfc, 0x9c, 0x15, 0xf3, 0xfd, 0x22, 0xdf, 0x57,
- 0x8c, 0x14, 0x6b, 0x8a, 0x96, 0xfa, 0x42, 0x07, 0xe6, 0x98, 0xe3, 0x8f,
- 0xa8, 0x3e, 0x38, 0x38, 0xdf, 0x26, 0x79, 0x7b, 0x8d, 0xe4, 0x55, 0xc6,
- 0xa3, 0xaa, 0x03, 0x2c, 0xe7, 0x5e, 0xf4, 0x71, 0xdf, 0x4f, 0x28, 0x2e,
- 0xe2, 0xcd, 0x42, 0x17, 0xda, 0xcc, 0x35, 0x6f, 0x6f, 0xe8, 0xaf, 0xad,
- 0xcb, 0x26, 0x6c, 0xcb, 0x6a, 0xac, 0xc9, 0xb2, 0xaf, 0xb1, 0x16, 0x7b,
- 0x52, 0xae, 0x93, 0x6f, 0xca, 0x7e, 0xce, 0xdd, 0xf5, 0x72, 0xee, 0xdf,
- 0xee, 0x32, 0x18, 0x61, 0xc9, 0x84, 0x86, 0x9a, 0xfb, 0x8e, 0x4f, 0x05,
- 0x6f, 0x2d, 0xe5, 0x4f, 0xd1, 0x9e, 0xaf, 0xd6, 0xca, 0x71, 0xef, 0x39,
- 0x62, 0xc5, 0xe1, 0x57, 0xe4, 0xbc, 0xef, 0x0e, 0x78, 0xbf, 0xfa, 0xfc,
- 0xff, 0xd8, 0x53, 0x8b, 0xd6, 0xd9, 0xad, 0xba, 0x3a, 0xfb, 0xe3, 0x78,
- 0x96, 0x35, 0xf6, 0x5c, 0xa5, 0x09, 0xbc, 0xdb, 0x44, 0x9c, 0x48, 0x75,
- 0x3c, 0x75, 0xbc, 0xea, 0x72, 0x9d, 0x6b, 0xa7, 0x37, 0x57, 0x10, 0x7a,
- 0x7e, 0x62, 0xca, 0x1f, 0x73, 0x4c, 0x56, 0xf4, 0x27, 0x62, 0x41, 0x8b,
- 0x63, 0x8c, 0xbe, 0x4f, 0xbb, 0xc7, 0xa0, 0xc7, 0xa9, 0xf3, 0xf9, 0xde,
- 0x0e, 0x7c, 0x3d, 0xea, 0x02, 0xea, 0x73, 0xb5, 0x01, 0xf1, 0x3c, 0x74,
- 0xfd, 0x48, 0x59, 0x73, 0xf9, 0xb1, 0x87, 0x83, 0x89, 0x99, 0xac, 0xea,
- 0x06, 0xf8, 0x7b, 0xe5, 0x6b, 0xcc, 0x07, 0x9d, 0x92, 0x40, 0x6d, 0x9d,
- 0x86, 0xb1, 0x19, 0x6b, 0x1a, 0xad, 0xd0, 0x0d, 0x22, 0x57, 0xc1, 0x1b,
- 0x6f, 0xcc, 0x91, 0x5f, 0x83, 0x1d, 0x26, 0xbe, 0x5a, 0xd8, 0x6e, 0x49,
- 0x87, 0xd6, 0x3e, 0xf3, 0x4e, 0x84, 0xfe, 0xc9, 0x70, 0xb2, 0x1f, 0x7e,
- 0xb6, 0x62, 0x0f, 0x98, 0xaf, 0x9c, 0x40, 0x3c, 0x56, 0x9b, 0x63, 0x81,
- 0x7c, 0x8d, 0xb3, 0x3f, 0x0b, 0xbf, 0x72, 0xa9, 0xee, 0x91, 0x2f, 0x9e,
- 0xd0, 0xdc, 0x66, 0x69, 0xae, 0x55, 0x75, 0x6c, 0xa9, 0xf8, 0x30, 0xce,
- 0x45, 0x36, 0x5b, 0x43, 0x79, 0xaf, 0x3f, 0x2c, 0xc5, 0x22, 0xdb, 0xd2,
- 0xdd, 0xa4, 0xe7, 0xee, 0xd7, 0x76, 0x6c, 0x99, 0x85, 0xaf, 0x58, 0x9c,
- 0x77, 0xf0, 0xbf, 0x05, 0xff, 0x7d, 0xf8, 0xdf, 0x25, 0xe9, 0x69, 0xfa,
- 0xaf, 0xac, 0xe5, 0xb4, 0x36, 0xac, 0x1f, 0xf6, 0x70, 0xe0, 0xf4, 0x6b,
- 0x4d, 0x9c, 0x93, 0x2f, 0x36, 0xca, 0x09, 0xf3, 0xa4, 0xbe, 0x8e, 0x60,
- 0xbe, 0xd4, 0xaf, 0xf5, 0xd5, 0xd6, 0xb0, 0x2c, 0xaf, 0xee, 0x45, 0x9e,
- 0x6e, 0x91, 0x83, 0x45, 0xbf, 0x76, 0x15, 0x93, 0x43, 0xd5, 0xda, 0x95,
- 0x64, 0x82, 0x43, 0xb7, 0x1f, 0xcb, 0x4e, 0x29, 0x9e, 0xc0, 0xb2, 0x86,
- 0xae, 0x3f, 0x36, 0x39, 0xff, 0xce, 0x63, 0x4b, 0x98, 0x70, 0xdc, 0x9b,
- 0x5f, 0x0e, 0x33, 0x44, 0x2c, 0x1d, 0xbf, 0x93, 0x53, 0xdf, 0x0d, 0xfb,
- 0xf6, 0x63, 0x1e, 0xe2, 0xec, 0xe2, 0xf6, 0x12, 0x7e, 0xd9, 0x8f, 0x47,
- 0x89, 0x23, 0xe5, 0x73, 0xb5, 0xd8, 0x8f, 0x10, 0xce, 0x5f, 0x02, 0x96,
- 0x93, 0xc3, 0x3e, 0x2e, 0x76, 0x19, 0x3f, 0x90, 0x38, 0xd3, 0x44, 0x0d,
- 0xf6, 0xc8, 0xc7, 0x9a, 0x5e, 0xc4, 0x5c, 0x19, 0xf9, 0x7d, 0xf9, 0x71,
- 0xf9, 0x75, 0x79, 0x0c, 0xf2, 0x3d, 0x89, 0x39, 0xf7, 0xcb, 0xaf, 0xca,
- 0x7b, 0xe5, 0x5a, 0x79, 0x5c, 0xde, 0x2a, 0xef, 0x42, 0x4c, 0x35, 0x4a,
- 0xac, 0xa7, 0x87, 0x95, 0x1e, 0x96, 0x89, 0x73, 0x8a, 0x01, 0xbc, 0x45,
- 0xbf, 0xe7, 0x88, 0xfa, 0xd9, 0x01, 0xf2, 0xf4, 0x6f, 0x18, 0xcf, 0x13,
- 0x9b, 0x59, 0x2c, 0xfb, 0x18, 0x8e, 0x43, 0xdd, 0x58, 0xdb, 0xe6, 0x37,
- 0x29, 0x23, 0xe7, 0x22, 0x81, 0xd1, 0x73, 0xa1, 0xc0, 0x43, 0xfa, 0x7d,
- 0x0b, 0xeb, 0x9d, 0x15, 0x39, 0xe1, 0x3a, 0xe4, 0xcd, 0xc1, 0x11, 0xc8,
- 0xc2, 0x28, 0x54, 0xfd, 0x23, 0xce, 0x1a, 0x01, 0x49, 0x53, 0x1f, 0xc3,
- 0xcf, 0x4c, 0x9e, 0x76, 0x25, 0x5b, 0x98, 0x0d, 0x18, 0x3c, 0x9a, 0x8d,
- 0x76, 0x1f, 0xda, 0xbf, 0xf4, 0xda, 0x3b, 0x24, 0x7b, 0x41, 0x52, 0xef,
- 0xab, 0x3f, 0xfc, 0x73, 0xaf, 0x6f, 0x10, 0x7d, 0xe0, 0xcc, 0x57, 0xd8,
- 0xf7, 0x8a, 0xd7, 0xc7, 0x33, 0x61, 0xad, 0x3e, 0xae, 0x7c, 0x95, 0xb5,
- 0xc7, 0x85, 0xdf, 0x2f, 0x18, 0x4c, 0xe8, 0xfb, 0x5d, 0x46, 0xb7, 0x11,
- 0x13, 0xf8, 0xaf, 0x2e, 0xc6, 0x60, 0x45, 0xc8, 0xd7, 0x7a, 0xe8, 0xc4,
- 0xbf, 0x6f, 0x5e, 0x6a, 0x5b, 0x43, 0x9f, 0xd4, 0x60, 0xb4, 0x3f, 0x91,
- 0x9e, 0xf9, 0xdb, 0x1e, 0x9e, 0xf7, 0x30, 0xde, 0x0d, 0x67, 0x55, 0x20,
- 0x6e, 0x3c, 0x0e, 0xd9, 0x6e, 0x95, 0x35, 0x67, 0x48, 0xaf, 0x5e, 0xe8,
- 0xea, 0x14, 0xe4, 0xd6, 0x95, 0xb9, 0x72, 0x28, 0x30, 0x52, 0x48, 0x89,
- 0xc1, 0x53, 0x5b, 0x92, 0x89, 0xa6, 0xe4, 0xe4, 0x40, 0x62, 0x0b, 0xf3,
- 0x90, 0xd9, 0x7e, 0x57, 0x2e, 0x95, 0x69, 0x8f, 0x73, 0x72, 0x79, 0x20,
- 0xe1, 0x16, 0x85, 0xb8, 0x18, 0x57, 0x2e, 0x43, 0x36, 0xff, 0x70, 0x6e,
- 0x97, 0x1c, 0x2a, 0xa8, 0x1f, 0xdc, 0x1b, 0x96, 0x97, 0xe5, 0xd2, 0xc0,
- 0xcb, 0xb7, 0x2e, 0xb9, 0x93, 0x38, 0x53, 0xf2, 0xe1, 0x81, 0x6e, 0xb3,
- 0x6f, 0xc5, 0x21, 0x09, 0xf3, 0x21, 0x5a, 0x53, 0x73, 0x56, 0x48, 0x7a,
- 0x5f, 0xc4, 0x8b, 0xcb, 0xe1, 0x73, 0x07, 0xee, 0x33, 0xf5, 0x94, 0x80,
- 0xbf, 0xcf, 0x30, 0xfc, 0x18, 0x3e, 0xe7, 0xd3, 0xc6, 0x9f, 0xa7, 0x2b,
- 0x90, 0xbe, 0xd0, 0x26, 0xa1, 0x57, 0xbe, 0x0c, 0xba, 0x86, 0xe4, 0x40,
- 0x7f, 0xa5, 0xf2, 0x0d, 0x37, 0x14, 0x9f, 0x44, 0x8c, 0x82, 0xfd, 0xcb,
- 0xea, 0xd3, 0xed, 0xa0, 0x49, 0xb3, 0x44, 0x4f, 0xfb, 0xeb, 0xad, 0xf0,
- 0xb0, 0x0c, 0xe7, 0x57, 0x1b, 0x5b, 0xe6, 0x63, 0x1b, 0xfc, 0xf9, 0x0c,
- 0xa6, 0xac, 0xc7, 0xea, 0x0f, 0x78, 0xdf, 0x49, 0x78, 0xed, 0x7b, 0x03,
- 0x0f, 0x86, 0x3a, 0x24, 0xe4, 0xfc, 0x70, 0x1d, 0xb1, 0x91, 0x0b, 0x05,
- 0xbf, 0x1f, 0x7e, 0x62, 0xc8, 0xf7, 0x87, 0x65, 0xdb, 0xd2, 0x59, 0xcb,
- 0xb6, 0x9e, 0xf9, 0x6f, 0x7a, 0x73, 0xa6, 0xbc, 0xb1, 0x88, 0x39, 0x62,
- 0xab, 0xd4, 0x3e, 0x99, 0xb1, 0x9f, 0xc9, 0xb3, 0xfd, 0x89, 0x57, 0x15,
- 0x27, 0x5b, 0x7d, 0x86, 0xf7, 0x11, 0x43, 0x96, 0xf5, 0x99, 0xd8, 0x6e,
- 0xd0, 0x37, 0x13, 0xbb, 0xc7, 0x9e, 0xb5, 0x82, 0x01, 0xe3, 0x8f, 0x34,
- 0xc9, 0x0f, 0xa2, 0xb0, 0xdb, 0x88, 0xf1, 0xb2, 0xcc, 0x7f, 0xb9, 0x77,
- 0x3c, 0x3f, 0x85, 0x7d, 0x89, 0x53, 0x49, 0x6b, 0x02, 0xfb, 0xe3, 0x19,
- 0x10, 0x03, 0x6a, 0x81, 0x4e, 0x5d, 0x78, 0x3f, 0xc4, 0x4f, 0xfd, 0xfe,
- 0xfb, 0xaf, 0x86, 0x0e, 0xe3, 0xfe, 0x0d, 0x2e, 0x4c, 0x2c, 0xe6, 0x42,
- 0x86, 0x3d, 0x0c, 0x6c, 0xad, 0xdc, 0xfa, 0xd8, 0x58, 0x1f, 0x4f, 0x47,
- 0x8c, 0x52, 0x0c, 0x7e, 0x20, 0x65, 0x82, 0xbc, 0xd9, 0x89, 0xfe, 0x95,
- 0xb7, 0x53, 0xfa, 0xea, 0x7e, 0xdf, 0x87, 0x55, 0x6c, 0xf7, 0x64, 0x61,
- 0xaf, 0xc1, 0xe6, 0x59, 0x8b, 0x92, 0xea, 0x4e, 0xda, 0x27, 0xb0, 0xdf,
- 0x74, 0x28, 0x51, 0xcc, 0x49, 0x4c, 0x66, 0xa1, 0x2f, 0xde, 0x80, 0xec,
- 0x5f, 0x2b, 0xc7, 0x03, 0x69, 0xec, 0xe9, 0x60, 0x61, 0x48, 0x26, 0x2f,
- 0xe8, 0x37, 0x5f, 0xd0, 0xfb, 0x43, 0x52, 0x2a, 0x24, 0xb6, 0xcc, 0x82,
- 0xff, 0x66, 0x0b, 0xc4, 0x17, 0xf5, 0xc6, 0x47, 0x31, 0xe3, 0x42, 0x61,
- 0x23, 0xec, 0x83, 0xa4, 0x2e, 0xc1, 0xff, 0xb9, 0x54, 0xde, 0x02, 0x3e,
- 0xc3, 0xfd, 0xb2, 0x83, 0x5f, 0xe8, 0xcc, 0xf2, 0x00, 0xe4, 0x9c, 0x7b,
- 0xb1, 0x65, 0x6e, 0x33, 0xce, 0x8e, 0x38, 0x22, 0xc5, 0x8f, 0xff, 0x07,
- 0xe7, 0xeb, 0xbf, 0xf7, 0x76, 0xb5, 0xd3, 0xb3, 0xba, 0x2f, 0xd8, 0x65,
- 0xc4, 0x00, 0xd9, 0x7e, 0x63, 0xb7, 0xd3, 0x91, 0x76, 0x49, 0xdf, 0x43,
- 0x3b, 0xde, 0xa1, 0x31, 0xa2, 0xf2, 0x62, 0x84, 0xf7, 0xdf, 0x59, 0x67,
- 0xe8, 0x17, 0x6e, 0x68, 0xbf, 0x8d, 0xdf, 0x36, 0xe9, 0x74, 0xf8, 0x6b,
- 0xe3, 0xf7, 0xc6, 0x3a, 0xd6, 0x77, 0x3b, 0x9d, 0x24, 0xd6, 0xfa, 0x9d,
- 0x97, 0x2f, 0xc0, 0xf5, 0x2c, 0x9f, 0x59, 0xeb, 0xad, 0xcb, 0x79, 0xdb,
- 0x30, 0x4f, 0xab, 0xb7, 0x56, 0x9b, 0xe6, 0x27, 0xcd, 0x5a, 0x88, 0x71,
- 0x0b, 0xef, 0xad, 0xd3, 0xef, 0x8c, 0x61, 0x2f, 0xea, 0xdb, 0x7f, 0x5d,
- 0x47, 0xdc, 0x5c, 0xa7, 0xd3, 0xa6, 0x18, 0xcf, 0x9b, 0x1d, 0x1d, 0xb8,
- 0xe6, 0x9a, 0x1c, 0x63, 0xf2, 0xe1, 0xa5, 0x32, 0xe7, 0x67, 0x3b, 0x25,
- 0x47, 0x35, 0x9f, 0x61, 0xb0, 0x7c, 0xa5, 0xc2, 0xfd, 0x32, 0x79, 0x4e,
- 0xf1, 0x75, 0x33, 0x79, 0x8b, 0xdf, 0xbd, 0xf0, 0x3b, 0x39, 0xfa, 0x12,
- 0x63, 0x32, 0x81, 0xf3, 0xbb, 0x0c, 0x9f, 0x6a, 0xc1, 0x7c, 0x13, 0x8b,
- 0xbf, 0xfd, 0x38, 0x97, 0x10, 0x64, 0x8c, 0x32, 0x4a, 0x99, 0xc2, 0xf9,
- 0x8d, 0xdb, 0xf2, 0xee, 0x00, 0xe5, 0x79, 0x40, 0xae, 0x54, 0xe5, 0x39,
- 0x07, 0x79, 0xa6, 0x2c, 0xe7, 0x20, 0xd3, 0x86, 0xaf, 0xf7, 0xf1, 0x1b,
- 0x6b, 0x84, 0xeb, 0x25, 0xf5, 0x21, 0x2e, 0x82, 0xaf, 0x6d, 0x13, 0x97,
- 0x2b, 0x2e, 0xfe, 0x30, 0xf4, 0x5a, 0x93, 0xf7, 0x1d, 0x00, 0xae, 0xaf,
- 0xbc, 0x28, 0xe9, 0x0b, 0x2d, 0xd8, 0x77, 0xbc, 0x9b, 0x67, 0x96, 0xbd,
- 0xc2, 0x7f, 0x9f, 0x17, 0x89, 0x37, 0xa5, 0x3f, 0xcb, 0x6b, 0xc6, 0x79,
- 0xeb, 0x31, 0x66, 0x10, 0x74, 0x6e, 0xc1, 0xfc, 0xdc, 0xe3, 0x72, 0xe3,
- 0x78, 0x3f, 0x54, 0x83, 0x4f, 0xf5, 0xe9, 0xbd, 0x4a, 0xd7, 0xcc, 0xea,
- 0x37, 0x5a, 0x46, 0x06, 0x27, 0x0a, 0xe4, 0xfb, 0x18, 0xf8, 0x96, 0x3e,
- 0x31, 0xf9, 0x25, 0xa5, 0xe7, 0x50, 0x2a, 0x90, 0x7f, 0x43, 0x9a, 0xc3,
- 0xc8, 0xc2, 0xb6, 0xec, 0xd1, 0xf1, 0xb1, 0x25, 0xf9, 0xee, 0x0e, 0x68,
- 0xdc, 0x9d, 0x2d, 0xac, 0x94, 0x1e, 0xd5, 0x41, 0xdd, 0x1e, 0x6f, 0xc3,
- 0x5e, 0x28, 0x96, 0x7b, 0xbf, 0x1c, 0x29, 0x0f, 0x82, 0x0e, 0x31, 0x79,
- 0x06, 0x7e, 0xf3, 0x73, 0xe5, 0xbb, 0x64, 0x31, 0x82, 0x7d, 0x55, 0x65,
- 0x6c, 0x58, 0x9e, 0x9f, 0x8d, 0x7b, 0xd7, 0x09, 0x77, 0xd1, 0xda, 0x8e,
- 0x3d, 0x50, 0x9e, 0x28, 0x57, 0x1c, 0x17, 0x44, 0x2c, 0xc2, 0x79, 0x8f,
- 0x18, 0xdd, 0x86, 0x79, 0x8b, 0x11, 0xca, 0x2f, 0xf7, 0x16, 0xf2, 0x64,
- 0x96, 0x71, 0x15, 0xdf, 0xd9, 0xd8, 0xa4, 0x4c, 0xdd, 0x59, 0x24, 0x14,
- 0x07, 0xba, 0x74, 0x06, 0xfe, 0x3c, 0xbe, 0x5c, 0xfa, 0xdf, 0x51, 0x50,
- 0x8f, 0xc2, 0x56, 0x16, 0x60, 0x2b, 0x0b, 0xb0, 0x91, 0x90, 0x85, 0x6b,
- 0x05, 0xd8, 0xc8, 0x02, 0x6c, 0x24, 0xf4, 0xd9, 0x9b, 0x88, 0xed, 0xde,
- 0x00, 0x0f, 0x19, 0x5f, 0xfb, 0x30, 0x7d, 0x6d, 0xfc, 0xfd, 0x17, 0xea,
- 0x52, 0x61, 0x78, 0xd0, 0x71, 0x00, 0x00, 0x00 };
+ 0xec, 0x5b, 0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x24, 0x57,
+ 0x14, 0x45, 0x8e, 0xa8, 0x15, 0xb5, 0xb2, 0x99, 0x64, 0x97, 0x1c, 0x89,
+ 0x1b, 0x93, 0x50, 0x86, 0xec, 0x5a, 0x66, 0x92, 0x45, 0xbc, 0x59, 0x52,
+ 0x16, 0x53, 0x08, 0xf0, 0xda, 0x56, 0x5c, 0xa3, 0x31, 0x90, 0xc5, 0x92,
+ 0x76, 0xd2, 0x37, 0xc9, 0xa9, 0x5d, 0x21, 0xb1, 0xab, 0xf5, 0x92, 0x91,
+ 0x15, 0x75, 0xc5, 0x61, 0x24, 0x26, 0x72, 0x1b, 0xb7, 0xa0, 0xf9, 0x23,
+ 0xaa, 0xc1, 0x4a, 0xe3, 0x9f, 0xd8, 0xf5, 0x43, 0x64, 0x31, 0xb2, 0xad,
+ 0xfa, 0xa5, 0x80, 0xd3, 0x1f, 0xc0, 0x28, 0x8c, 0x56, 0x90, 0x6b, 0xd9,
+ 0x68, 0x81, 0x42, 0x6d, 0x51, 0xd4, 0x6d, 0x64, 0x4d, 0xbf, 0xef, 0xce,
+ 0x0c, 0xb9, 0x22, 0x94, 0xc6, 0x2f, 0x7d, 0x9b, 0x0b, 0x2c, 0xee, 0xdc,
+ 0x3b, 0xe7, 0x9e, 0x7b, 0xce, 0xb9, 0xe7, 0xf7, 0x0e, 0xf9, 0x44, 0x9b,
+ 0xb4, 0x4a, 0xd0, 0x36, 0xe1, 0x97, 0x3d, 0x70, 0xe8, 0xb1, 0xc1, 0x5d,
+ 0xbb, 0x77, 0xe1, 0x71, 0x77, 0xcc, 0x6c, 0x36, 0x38, 0xaf, 0x49, 0xd4,
+ 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2,
+ 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16,
+ 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5,
+ 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8,
+ 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45,
+ 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xfe, 0x3f, 0x5a, 0x4c, 0xc4, 0x64,
+ 0xbf, 0x29, 0xf8, 0x49, 0x5c, 0xcf, 0xa5, 0x0e, 0x16, 0x2c, 0x89, 0xc7,
+ 0x72, 0x6f, 0x3f, 0x3e, 0x6e, 0x89, 0xe4, 0xeb, 0xfd, 0xa9, 0x11, 0xf9,
+ 0xc4, 0xab, 0x24, 0x0c, 0xe1, 0xfc, 0x67, 0x72, 0xd7, 0x0f, 0x9f, 0xbf,
+ 0x2b, 0x7d, 0x6d, 0x2e, 0x26, 0x71, 0x33, 0xf7, 0xee, 0xa0, 0xb9, 0x53,
+ 0xe2, 0xdd, 0x58, 0xf3, 0x5c, 0xdf, 0xc4, 0x66, 0x69, 0x0f, 0x71, 0x79,
+ 0xde, 0x92, 0xed, 0xc9, 0x25, 0xbb, 0xa2, 0x8d, 0xf4, 0xbd, 0xa6, 0x15,
+ 0x9c, 0x1b, 0x5e, 0xde, 0xd0, 0x45, 0x07, 0xbe, 0x89, 0x7a, 0x5c, 0x1e,
+ 0x59, 0x6c, 0x95, 0x47, 0xe7, 0x36, 0x4a, 0x79, 0x4e, 0x4c, 0x3d, 0x97,
+ 0x94, 0x6f, 0x61, 0xee, 0x72, 0x0c, 0x70, 0xae, 0x94, 0x62, 0xb9, 0x8f,
+ 0xef, 0x2d, 0xd7, 0x08, 0x2f, 0xba, 0x9e, 0x5b, 0xb9, 0x77, 0xa2, 0xfe,
+ 0xe6, 0xbd, 0xe5, 0x3a, 0xe1, 0x08, 0x83, 0x77, 0xf5, 0x8f, 0xbc, 0xf3,
+ 0x7d, 0x09, 0xb9, 0xe0, 0x9a, 0xf2, 0x82, 0xfb, 0x32, 0xf6, 0x4c, 0x57,
+ 0x2a, 0xd2, 0x24, 0xe5, 0x93, 0x37, 0xbc, 0x98, 0x95, 0x4e, 0x61, 0x13,
+ 0x73, 0x44, 0xf0, 0xde, 0xc1, 0x7b, 0x07, 0xf3, 0x0b, 0x3f, 0xdf, 0x2c,
+ 0xad, 0x49, 0x39, 0xdf, 0xc7, 0x75, 0x5c, 0xc3, 0xb5, 0x8b, 0xed, 0xfe,
+ 0x3a, 0xc1, 0xba, 0xa2, 0xc4, 0x2c, 0x4f, 0x0a, 0xb6, 0x21, 0x23, 0x09,
+ 0xd1, 0x74, 0xab, 0x02, 0x3a, 0x7e, 0xd1, 0x26, 0xad, 0xc4, 0x55, 0xd1,
+ 0xf2, 0x2e, 0xfb, 0x10, 0xdf, 0x53, 0x1d, 0x3e, 0xae, 0x67, 0x81, 0xab,
+ 0x24, 0xaf, 0xbb, 0x0f, 0xcb, 0x5f, 0xb8, 0x63, 0xf2, 0x92, 0x3b, 0x01,
+ 0x9c, 0x0f, 0xc9, 0xab, 0xee, 0x7e, 0x79, 0xc5, 0x2d, 0xca, 0xcf, 0xdc,
+ 0x7d, 0xf2, 0xb2, 0x3b, 0x2a, 0x2f, 0xba, 0x79, 0xec, 0x97, 0xd1, 0x8a,
+ 0xce, 0xdd, 0x32, 0x7e, 0x92, 0x34, 0xa6, 0xaf, 0x41, 0x36, 0xf2, 0x98,
+ 0xdd, 0x67, 0xea, 0xa2, 0x61, 0xcf, 0xf4, 0x6b, 0x22, 0x8f, 0x4a, 0x3e,
+ 0x31, 0x2c, 0x73, 0x6e, 0x97, 0x56, 0x38, 0xd9, 0xa9, 0x8d, 0x9c, 0x24,
+ 0x2d, 0x9e, 0x8c, 0xdb, 0xe9, 0x54, 0x21, 0x96, 0x36, 0x47, 0x62, 0x92,
+ 0xdf, 0x03, 0xb9, 0x55, 0x9d, 0xa4, 0xe4, 0x4d, 0xc9, 0x1f, 0xb5, 0x0c,
+ 0xc8, 0x53, 0x93, 0x58, 0x8e, 0x7c, 0x6e, 0xe1, 0x1c, 0x5a, 0x9b, 0x2c,
+ 0xd4, 0x6c, 0x29, 0x3b, 0xf3, 0x5a, 0x39, 0xa1, 0x51, 0x04, 0x18, 0x0f,
+ 0x60, 0xfc, 0x67, 0xc1, 0xf8, 0x4b, 0x52, 0x3e, 0x25, 0xf9, 0xc9, 0x59,
+ 0xcf, 0x2b, 0xd8, 0x7f, 0x1c, 0xcc, 0x0d, 0x63, 0x4e, 0x97, 0xd8, 0x8f,
+ 0x38, 0x37, 0x1b, 0xcc, 0x51, 0x1e, 0x9e, 0x8c, 0xd8, 0x14, 0x23, 0xe8,
+ 0x35, 0x8b, 0xe8, 0x9b, 0xd1, 0x73, 0x8f, 0x8d, 0x9b, 0xfc, 0xff, 0x03,
+ 0xe2, 0xf9, 0x26, 0xf0, 0x6c, 0x83, 0x66, 0x89, 0x7f, 0x36, 0x77, 0xf4,
+ 0xe0, 0x3f, 0xf4, 0xad, 0x8d, 0xf5, 0xdc, 0x7b, 0x52, 0xa8, 0x69, 0x4a,
+ 0x57, 0x34, 0x3c, 0xf7, 0xd4, 0x9f, 0xea, 0xf4, 0xf5, 0xc2, 0x69, 0x97,
+ 0x56, 0xc8, 0xc9, 0x21, 0xfd, 0x29, 0xd0, 0xbf, 0x49, 0xb6, 0xfc, 0x90,
+ 0x3c, 0xf4, 0xa7, 0x74, 0xc9, 0xa7, 0x0d, 0xb1, 0x65, 0xd1, 0x35, 0xb4,
+ 0x11, 0x27, 0x2f, 0x7a, 0xce, 0x4a, 0x96, 0x45, 0x97, 0x52, 0x22, 0x2f,
+ 0xcf, 0x64, 0xd3, 0xc3, 0x15, 0x49, 0x49, 0x79, 0xc8, 0x96, 0x65, 0x17,
+ 0x90, 0x89, 0x8a, 0x5c, 0xcd, 0xa6, 0xed, 0xcb, 0xb2, 0x51, 0x56, 0x4c,
+ 0x5b, 0x4e, 0xbb, 0x71, 0x79, 0xeb, 0xe4, 0x3e, 0xf9, 0x96, 0xc3, 0x73,
+ 0x92, 0xfe, 0x26, 0x79, 0x5a, 0x96, 0xb2, 0x4f, 0x5f, 0x5b, 0xb2, 0x8f,
+ 0xb7, 0x49, 0x3b, 0x75, 0xb0, 0xd6, 0xee, 0xd3, 0xfd, 0x15, 0xf0, 0x96,
+ 0x87, 0x6c, 0xdb, 0x21, 0x33, 0x43, 0xf1, 0x55, 0x78, 0xb0, 0x13, 0x3d,
+ 0xd7, 0xfd, 0xfd, 0x16, 0xe8, 0x83, 0x2d, 0x5a, 0x48, 0x63, 0x93, 0x14,
+ 0xba, 0xb8, 0xe6, 0x25, 0xe0, 0xc0, 0xfb, 0x55, 0xda, 0x6f, 0xd3, 0x0a,
+ 0xa7, 0xda, 0xc5, 0xf8, 0xd1, 0x9d, 0x38, 0x4f, 0x43, 0x1e, 0x19, 0xf2,
+ 0xbc, 0xaf, 0xdb, 0x46, 0x6a, 0x42, 0x72, 0xa4, 0x5d, 0x36, 0x1f, 0xdf,
+ 0x2a, 0x73, 0x66, 0x5c, 0x12, 0xc7, 0xc3, 0xbd, 0x5a, 0x82, 0xf3, 0xf9,
+ 0x32, 0xf1, 0xa7, 0x52, 0xfa, 0xa6, 0x60, 0x1c, 0xd2, 0x34, 0x8a, 0x33,
+ 0xea, 0x35, 0x7b, 0xf4, 0x21, 0x2d, 0xaf, 0xfe, 0x8f, 0x6a, 0x2c, 0x18,
+ 0xef, 0xd2, 0xbe, 0x6a, 0x74, 0x89, 0x61, 0xcd, 0x43, 0xae, 0x86, 0x5c,
+ 0x74, 0xc2, 0xf9, 0xb8, 0xf8, 0x70, 0x94, 0xb3, 0x0c, 0xae, 0xc9, 0x59,
+ 0x06, 0x7b, 0xea, 0x4f, 0x07, 0x38, 0xf3, 0x01, 0xec, 0x06, 0xc9, 0x27,
+ 0xdb, 0x78, 0xa6, 0x01, 0xec, 0x75, 0xf9, 0xce, 0x50, 0xfa, 0x0c, 0xff,
+ 0x57, 0x6b, 0x6d, 0x0d, 0xdf, 0xdb, 0x32, 0xef, 0xaa, 0x35, 0xc9, 0xfb,
+ 0x70, 0xb6, 0xa5, 0xe4, 0x1d, 0xe6, 0x82, 0x1e, 0xd3, 0xf2, 0x09, 0xe2,
+ 0x6a, 0x96, 0xc7, 0x13, 0xbd, 0x18, 0x6b, 0x52, 0xfe, 0x12, 0xf5, 0xf5,
+ 0x13, 0xf1, 0xe7, 0x39, 0x97, 0x3e, 0xda, 0xab, 0x1f, 0x03, 0x7d, 0x94,
+ 0x41, 0x3a, 0x29, 0x10, 0x7e, 0x79, 0xe8, 0x36, 0xf0, 0x67, 0xa2, 0x0f,
+ 0xf9, 0xdf, 0x2c, 0xf9, 0x22, 0xe9, 0x57, 0x76, 0x0a, 0x39, 0x27, 0xb1,
+ 0xdf, 0xdd, 0xb0, 0xc9, 0xf5, 0xf6, 0x0a, 0x1b, 0x6d, 0xa7, 0xad, 0x7e,
+ 0x11, 0x3c, 0xa7, 0x33, 0x22, 0x16, 0xe4, 0x95, 0x94, 0x66, 0x6b, 0x1a,
+ 0x3c, 0x51, 0x2f, 0xb7, 0x61, 0x7e, 0xc3, 0xc7, 0x79, 0xc5, 0x7a, 0x38,
+ 0xf7, 0x41, 0x20, 0xcb, 0x7d, 0x32, 0xe1, 0xec, 0x57, 0x3c, 0x57, 0xf5,
+ 0xcb, 0x92, 0xef, 0xee, 0x35, 0xa7, 0x40, 0x6f, 0xc1, 0x48, 0xcf, 0x55,
+ 0x24, 0x29, 0x0b, 0xf0, 0x13, 0x2f, 0xc2, 0xe6, 0x5f, 0x71, 0x53, 0xb0,
+ 0xaf, 0xbc, 0x3c, 0xea, 0xe4, 0x64, 0xe2, 0x14, 0x6d, 0x2c, 0x9d, 0x29,
+ 0xc4, 0x72, 0x32, 0xef, 0xa4, 0x33, 0x0b, 0xd0, 0xbd, 0x05, 0xc7, 0xf3,
+ 0xa6, 0xec, 0xfe, 0xd4, 0x28, 0x30, 0x5e, 0x74, 0x76, 0x24, 0x27, 0x20,
+ 0xc8, 0x25, 0x2b, 0x25, 0x4b, 0x6e, 0x06, 0x3a, 0x86, 0xf7, 0xae, 0x85,
+ 0x7e, 0x00, 0x3a, 0x9e, 0x85, 0x7d, 0x93, 0x16, 0x53, 0x16, 0xfb, 0x20,
+ 0x3b, 0x47, 0x07, 0x2e, 0x4d, 0xf2, 0xfb, 0x6f, 0x40, 0xbe, 0x21, 0xdf,
+ 0x77, 0x81, 0xb6, 0x04, 0x70, 0x92, 0xae, 0xdb, 0xa4, 0xda, 0x05, 0xf9,
+ 0x0d, 0x25, 0x94, 0x5d, 0x16, 0x3a, 0xb7, 0x4a, 0xe1, 0x8e, 0x66, 0xbc,
+ 0xef, 0xc2, 0x98, 0xf2, 0x6f, 0xc1, 0x1c, 0xdf, 0xff, 0x4b, 0x60, 0x5f,
+ 0x4d, 0xeb, 0xc6, 0x57, 0xd1, 0xb7, 0xcb, 0x36, 0x8b, 0xbd, 0x89, 0xfe,
+ 0x9f, 0xd1, 0x77, 0xa2, 0xef, 0xc5, 0x5e, 0xe7, 0x21, 0x43, 0xca, 0x0f,
+ 0xcf, 0x0b, 0x5c, 0xb3, 0x3d, 0xd8, 0x97, 0x78, 0xdb, 0x81, 0x67, 0x53,
+ 0xb0, 0x57, 0x3b, 0xc6, 0xad, 0xc1, 0x5e, 0x16, 0x68, 0x8e, 0x29, 0x19,
+ 0x16, 0xac, 0xf8, 0xba, 0xb1, 0x86, 0x3e, 0x0e, 0xdc, 0x84, 0xd7, 0xe5,
+ 0x4a, 0x57, 0x17, 0x9e, 0xb9, 0x27, 0x61, 0xf8, 0x1e, 0xbd, 0x4b, 0xfc,
+ 0x1c, 0xe7, 0xe5, 0x09, 0x07, 0xfe, 0x89, 0xfa, 0xe6, 0x52, 0x8e, 0xbb,
+ 0x65, 0x02, 0xbc, 0x8f, 0x3b, 0xe9, 0x99, 0xaa, 0xee, 0x79, 0x7a, 0xd6,
+ 0x30, 0xab, 0x92, 0x86, 0x1d, 0x8f, 0xc9, 0x38, 0xe4, 0x77, 0xda, 0x89,
+ 0xcb, 0x45, 0x65, 0x7b, 0xe4, 0xe9, 0x21, 0xc8, 0x05, 0xf1, 0xa4, 0x8b,
+ 0xf6, 0x49, 0x9b, 0x82, 0xfc, 0x8a, 0xa6, 0x5c, 0xca, 0xd2, 0x96, 0xb3,
+ 0xb2, 0xbc, 0x6a, 0xcb, 0x15, 0xd8, 0x32, 0xed, 0xb8, 0x02, 0x7b, 0xf6,
+ 0xf5, 0xfa, 0x41, 0xd9, 0x06, 0xbd, 0x4e, 0x62, 0x3f, 0xea, 0xf5, 0xb3,
+ 0xd0, 0x6b, 0xc8, 0xd4, 0x86, 0xae, 0x9b, 0xd4, 0x89, 0x6f, 0xc3, 0xa7,
+ 0x81, 0xdf, 0x44, 0xf0, 0xbc, 0xfc, 0x5d, 0x29, 0x9c, 0x6a, 0x05, 0xdd,
+ 0x7b, 0xdb, 0x29, 0xb3, 0xf2, 0x32, 0x7f, 0xa1, 0x2e, 0x3e, 0x05, 0xf9,
+ 0xc1, 0x8f, 0x2a, 0x1d, 0x04, 0x6f, 0xd9, 0x3d, 0x80, 0x19, 0xc6, 0x39,
+ 0xb7, 0x02, 0x3f, 0x69, 0xbc, 0x15, 0x1c, 0xdf, 0x83, 0xee, 0x2c, 0xf5,
+ 0x15, 0xf3, 0x0b, 0xe1, 0x79, 0xb7, 0xa9, 0x3d, 0xcb, 0x43, 0xad, 0x01,
+ 0x7f, 0x94, 0x03, 0xf5, 0x3e, 0x09, 0xbd, 0xd5, 0x64, 0x5c, 0xe9, 0x6e,
+ 0x5e, 0xc9, 0x61, 0xde, 0xa1, 0xfe, 0x02, 0x87, 0x4d, 0x19, 0x98, 0x72,
+ 0xbf, 0x82, 0x4f, 0xae, 0xd9, 0x77, 0x37, 0x69, 0xe7, 0x78, 0x83, 0xf4,
+ 0x28, 0x1f, 0xd4, 0x1d, 0xe8, 0x76, 0x13, 0x6c, 0x9f, 0xef, 0x1e, 0x92,
+ 0xc7, 0xdc, 0x61, 0x9c, 0x43, 0x52, 0x0e, 0xba, 0xdd, 0xf2, 0xfb, 0xee,
+ 0x46, 0xb9, 0xdc, 0x09, 0xba, 0x56, 0x6d, 0xec, 0x6e, 0xf9, 0x03, 0xc6,
+ 0x3c, 0xf5, 0x0c, 0x3f, 0xa9, 0xdf, 0x05, 0x1a, 0x68, 0x4f, 0xb4, 0x2b,
+ 0xc2, 0xc5, 0xa4, 0xa4, 0xf6, 0xfc, 0x89, 0xef, 0xdb, 0x80, 0x77, 0xae,
+ 0x93, 0xf6, 0x4b, 0xda, 0x8c, 0xc0, 0x66, 0xd3, 0x66, 0x49, 0xc8, 0x33,
+ 0x69, 0xe5, 0x73, 0xa3, 0x2c, 0xd8, 0x37, 0xca, 0x20, 0xc4, 0x13, 0xda,
+ 0xe5, 0xa8, 0xe4, 0x5d, 0xf6, 0xf4, 0x97, 0x88, 0x91, 0x0e, 0x62, 0xa4,
+ 0x83, 0xd8, 0x08, 0x5b, 0x78, 0xc5, 0x41, 0x6c, 0x74, 0x10, 0x1b, 0xe1,
+ 0xcf, 0x5e, 0x72, 0x10, 0x1f, 0xa1, 0x43, 0x2f, 0x38, 0x8c, 0xeb, 0xdf,
+ 0x46, 0x4c, 0x35, 0xe4, 0x99, 0x9a, 0xc8, 0x91, 0x5a, 0x1a, 0xd4, 0xa5,
+ 0x87, 0x3f, 0x90, 0xfe, 0xcc, 0x07, 0x92, 0xb6, 0x2f, 0xe2, 0xf7, 0x96,
+ 0xe0, 0x9d, 0xca, 0x11, 0xf0, 0xbe, 0x1e, 0xe6, 0x13, 0x38, 0x7f, 0x8b,
+ 0x39, 0x83, 0x3f, 0x0f, 0x97, 0x88, 0xb8, 0x41, 0x9b, 0x1e, 0x93, 0xf9,
+ 0x59, 0xda, 0xf2, 0xed, 0x38, 0x8b, 0x4e, 0x99, 0xb2, 0xfc, 0x71, 0xc1,
+ 0xbe, 0xc3, 0x1c, 0xa5, 0xee, 0x98, 0x31, 0xd0, 0x76, 0x1b, 0x7e, 0x29,
+ 0xc4, 0xda, 0x3f, 0xd2, 0x0a, 0x0b, 0x71, 0xc4, 0x56, 0xc6, 0x5b, 0xc9,
+ 0xfb, 0x7a, 0x74, 0xc3, 0x1b, 0x5f, 0x5d, 0xd3, 0x0f, 0xfd, 0x86, 0xdc,
+ 0x13, 0x09, 0xc0, 0xcc, 0x6a, 0x23, 0xcb, 0x6f, 0xfb, 0x76, 0x92, 0xe5,
+ 0xf8, 0x46, 0x60, 0x7b, 0xdc, 0x1f, 0x63, 0x97, 0x78, 0xf9, 0x4c, 0x9c,
+ 0x97, 0x91, 0x1f, 0x24, 0x91, 0x17, 0x24, 0xe0, 0x7b, 0x98, 0x73, 0x74,
+ 0x23, 0x3f, 0xf0, 0xbc, 0x17, 0x6d, 0xcf, 0x7b, 0x07, 0xbf, 0x7f, 0xb7,
+ 0x57, 0x79, 0x40, 0xab, 0x68, 0xa3, 0x6e, 0x4a, 0x46, 0xdd, 0x9f, 0xb6,
+ 0xfb, 0x72, 0x8c, 0xcb, 0xa4, 0x93, 0x90, 0x29, 0xa7, 0xa6, 0xdd, 0xb7,
+ 0x3c, 0xad, 0x15, 0x97, 0x67, 0xb0, 0xaf, 0x81, 0x39, 0xa9, 0x54, 0xed,
+ 0x33, 0xda, 0x88, 0x7b, 0x54, 0xbb, 0x7f, 0xb9, 0x5d, 0xd9, 0x79, 0xd5,
+ 0x61, 0xce, 0x70, 0x5d, 0xe5, 0x2e, 0x05, 0x2b, 0x6d, 0xfe, 0x2e, 0x14,
+ 0xaf, 0x50, 0x23, 0xdd, 0xcd, 0x01, 0xcd, 0xb0, 0xc3, 0x9c, 0x77, 0xb8,
+ 0x90, 0xb5, 0x60, 0x8b, 0xa4, 0x51, 0xcd, 0x5d, 0xf0, 0xe9, 0x3e, 0xad,
+ 0x15, 0x96, 0xdb, 0xb4, 0x91, 0x53, 0x8c, 0xc7, 0xd2, 0x1d, 0x13, 0xae,
+ 0xdb, 0x01, 0x7b, 0xad, 0x63, 0x0f, 0xe6, 0x5b, 0x94, 0x2d, 0xe8, 0x86,
+ 0x0e, 0xbf, 0x04, 0x7a, 0x5e, 0x54, 0xf9, 0x0f, 0xf9, 0x4b, 0xe1, 0xac,
+ 0x42, 0xfe, 0x3c, 0xef, 0xaf, 0xed, 0x90, 0xfe, 0x74, 0x2a, 0xaf, 0x87,
+ 0xfc, 0x7a, 0xde, 0xbf, 0xd9, 0xe4, 0x99, 0x3c, 0x79, 0xde, 0x0b, 0x76,
+ 0x02, 0xf4, 0x7b, 0x17, 0x74, 0xab, 0x06, 0x7e, 0x18, 0xdb, 0x29, 0xf3,
+ 0x69, 0xf0, 0x71, 0x14, 0x3c, 0x9e, 0x06, 0x7f, 0x33, 0xa0, 0xe5, 0x37,
+ 0xed, 0xd9, 0x98, 0x4b, 0x4a, 0x8a, 0xb2, 0x2e, 0x2f, 0x32, 0xa7, 0x64,
+ 0x1e, 0x69, 0x4a, 0x69, 0x31, 0x5c, 0x1f, 0xea, 0xc3, 0x01, 0xd9, 0xeb,
+ 0x74, 0x42, 0x3e, 0x94, 0xe7, 0x35, 0xd0, 0x4b, 0x9f, 0x5f, 0xcd, 0xe8,
+ 0x08, 0x80, 0x65, 0x1b, 0xb1, 0x5e, 0x46, 0x94, 0x2e, 0x2c, 0x5a, 0x92,
+ 0x2f, 0xdb, 0x26, 0xed, 0x36, 0x55, 0xb6, 0x2b, 0xc8, 0x0c, 0x7c, 0x39,
+ 0x8e, 0xd4, 0x0c, 0xbc, 0xe3, 0x58, 0x60, 0xf3, 0xa1, 0x6c, 0x0d, 0xd8,
+ 0x5d, 0x28, 0xf3, 0x70, 0xee, 0xc1, 0x0e, 0xfa, 0xcc, 0x79, 0xf7, 0x0b,
+ 0xc0, 0x41, 0xbc, 0xbf, 0x09, 0x47, 0x1c, 0x31, 0x84, 0x78, 0xe2, 0x72,
+ 0xc6, 0x21, 0x3c, 0xf3, 0x8b, 0xb8, 0xb4, 0x22, 0x26, 0x6f, 0xc8, 0x89,
+ 0xf6, 0xf9, 0x1d, 0x69, 0x73, 0x31, 0x16, 0x93, 0x63, 0x09, 0xb9, 0xc3,
+ 0x60, 0x00, 0xd8, 0xec, 0x67, 0xea, 0x85, 0x19, 0x0d, 0xba, 0xdc, 0x26,
+ 0x93, 0x03, 0x69, 0x73, 0x1e, 0x7b, 0xe8, 0xd8, 0xe3, 0x6b, 0x9c, 0xaf,
+ 0xfd, 0x87, 0x57, 0x4a, 0xec, 0x84, 0x9d, 0x48, 0xdc, 0xc8, 0x19, 0x83,
+ 0x53, 0xb5, 0x03, 0xc2, 0xfc, 0x6a, 0x72, 0x60, 0x03, 0xec, 0xbc, 0x77,
+ 0x78, 0xaf, 0x30, 0x97, 0x8f, 0x0f, 0x8e, 0x5b, 0x3e, 0x5d, 0x23, 0xb0,
+ 0xeb, 0x49, 0xe4, 0x79, 0x7b, 0xeb, 0xcc, 0x01, 0x8c, 0xc1, 0xde, 0xba,
+ 0x21, 0x47, 0x60, 0xaf, 0xcd, 0xd0, 0x9f, 0x15, 0xa5, 0xcb, 0x26, 0x64,
+ 0x4d, 0xdf, 0x3a, 0x0c, 0xdc, 0xef, 0x40, 0x6e, 0x16, 0x62, 0x67, 0x37,
+ 0xf2, 0xd9, 0x0c, 0xce, 0x33, 0x85, 0xd8, 0xd7, 0xa8, 0xd7, 0x12, 0xdf,
+ 0x0a, 0xb8, 0x57, 0x76, 0x32, 0x2f, 0xf3, 0xbc, 0x07, 0xac, 0xf4, 0xb3,
+ 0xe4, 0x65, 0xca, 0x91, 0x7c, 0xd5, 0x56, 0xbe, 0x10, 0x3a, 0x9b, 0x62,
+ 0x3e, 0x07, 0xfd, 0x83, 0x4e, 0x16, 0x39, 0x5e, 0xd5, 0xc1, 0xe4, 0xa4,
+ 0xcc, 0x43, 0x76, 0x62, 0x16, 0xb2, 0x84, 0x0d, 0xe1, 0x5a, 0x02, 0xdd,
+ 0xf6, 0xbc, 0x18, 0x74, 0x77, 0x3c, 0x4b, 0x38, 0xa9, 0x28, 0x9b, 0x83,
+ 0xcc, 0x26, 0xdd, 0x5d, 0x1d, 0x7e, 0x3e, 0x09, 0x5f, 0x99, 0xe0, 0x5e,
+ 0x9f, 0x85, 0x0e, 0x77, 0x23, 0x86, 0x78, 0x1e, 0x6c, 0x38, 0xa1, 0x0b,
+ 0x75, 0x18, 0xf6, 0xe2, 0xf2, 0x5d, 0x1b, 0xe6, 0xc5, 0x9c, 0x84, 0x4f,
+ 0x2b, 0x99, 0x9e, 0x77, 0x0f, 0x68, 0xa9, 0xda, 0x1d, 0x58, 0xd7, 0x24,
+ 0x08, 0x7b, 0xa6, 0xbf, 0xdf, 0x46, 0x15, 0x3b, 0x30, 0x6e, 0xc7, 0x7e,
+ 0x9b, 0x98, 0x7b, 0x4e, 0xd2, 0x16, 0xb2, 0xb4, 0x7d, 0x23, 0xf0, 0xe7,
+ 0x6f, 0x82, 0x4e, 0xae, 0x51, 0x70, 0xf1, 0xa6, 0x5c, 0x56, 0x96, 0x6a,
+ 0xdb, 0x65, 0x6e, 0x3f, 0xf7, 0xe8, 0xa6, 0x1d, 0x22, 0xfe, 0xf3, 0x99,
+ 0x74, 0xd3, 0x8f, 0x74, 0x06, 0x63, 0xed, 0x73, 0xfe, 0x1e, 0x62, 0x32,
+ 0xdf, 0x1d, 0x51, 0xf4, 0x8a, 0x7e, 0xd1, 0xde, 0xe8, 0xc7, 0xa8, 0x5c,
+ 0xbb, 0x76, 0x0f, 0x72, 0xf0, 0xbd, 0xbb, 0xa9, 0x03, 0x86, 0x5c, 0xb2,
+ 0x3c, 0xef, 0x92, 0xdd, 0x04, 0xfe, 0x74, 0x69, 0xb2, 0x8e, 0x9b, 0xd2,
+ 0x0a, 0x99, 0x3b, 0x5a, 0x20, 0x97, 0x36, 0x25, 0x97, 0x49, 0x15, 0xf7,
+ 0xde, 0xc5, 0xd9, 0x70, 0x6d, 0x45, 0xc5, 0x97, 0x82, 0x5a, 0xc7, 0x35,
+ 0x3c, 0xd3, 0x77, 0x91, 0x73, 0x1f, 0xc3, 0xda, 0x98, 0xb4, 0x28, 0xdd,
+ 0x66, 0xfc, 0x27, 0xaf, 0xd2, 0xe1, 0xe3, 0x61, 0xac, 0xa5, 0x0e, 0x87,
+ 0xfc, 0x8f, 0x06, 0x3c, 0x12, 0xaf, 0x0d, 0xbc, 0x6d, 0xaa, 0xce, 0x28,
+ 0xfb, 0xe7, 0xd7, 0x11, 0x53, 0xf2, 0x40, 0x5d, 0x94, 0x0b, 0x7d, 0x21,
+ 0x41, 0x43, 0xba, 0x9f, 0xc1, 0x3e, 0xa4, 0x61, 0x13, 0xf2, 0x5e, 0xd1,
+ 0xaa, 0xe4, 0xcb, 0x0c, 0xf7, 0x11, 0x3d, 0x96, 0x6b, 0x91, 0x11, 0x68,
+ 0x5d, 0xd5, 0xb1, 0xcc, 0x07, 0xa0, 0x7b, 0x5f, 0x07, 0x8f, 0x85, 0x19,
+ 0xfa, 0xaa, 0x2f, 0x61, 0xdd, 0x4a, 0x5a, 0xf7, 0xb7, 0x95, 0x23, 0x0e,
+ 0x65, 0xfa, 0x0e, 0x64, 0xaa, 0x77, 0x35, 0x4b, 0x87, 0x14, 0x91, 0x4f,
+ 0xcd, 0x0f, 0x83, 0xaf, 0x81, 0x36, 0x89, 0xed, 0xa2, 0xaf, 0x42, 0xed,
+ 0x93, 0x58, 0x41, 0x60, 0xb8, 0xee, 0xe9, 0x3b, 0xb1, 0x7e, 0x20, 0x01,
+ 0xf9, 0x52, 0x66, 0x7a, 0x00, 0x47, 0x18, 0x14, 0x4a, 0x66, 0xa1, 0xb3,
+ 0x59, 0x88, 0x9b, 0xef, 0xfa, 0x93, 0xa6, 0x70, 0x1e, 0x3e, 0xbd, 0xc8,
+ 0xb5, 0xa4, 0xd9, 0x5f, 0xd3, 0x64, 0x85, 0xb2, 0xfe, 0x2b, 0xf8, 0xa7,
+ 0x5f, 0x79, 0x7b, 0x87, 0xc2, 0xf7, 0xe4, 0x87, 0x7c, 0xe1, 0x0c, 0x41,
+ 0xd3, 0xe6, 0x9c, 0x25, 0x83, 0xd3, 0xa2, 0x15, 0x90, 0x7b, 0x50, 0x47,
+ 0x7a, 0x86, 0xd2, 0x95, 0x94, 0xbe, 0x0d, 0xbc, 0x1a, 0xb2, 0x7f, 0x88,
+ 0xfc, 0x6e, 0x0d, 0xf2, 0x8e, 0x46, 0x9e, 0x3b, 0x02, 0x9e, 0xd5, 0x7e,
+ 0xc3, 0x79, 0x7d, 0x8d, 0xf7, 0xd1, 0x99, 0x70, 0x5f, 0x03, 0xb6, 0xbc,
+ 0x82, 0x9a, 0x87, 0xfb, 0x93, 0x9e, 0x1b, 0x9e, 0x6e, 0x59, 0x95, 0x1e,
+ 0xfd, 0x57, 0xde, 0xfd, 0x43, 0x9a, 0xca, 0xd3, 0x74, 0xe4, 0x8c, 0xfa,
+ 0x10, 0x78, 0x1d, 0xe2, 0x79, 0xe9, 0x72, 0xff, 0x6e, 0xe2, 0x3b, 0x42,
+ 0xde, 0x80, 0xb3, 0xd5, 0xaf, 0x61, 0x86, 0xc2, 0x3d, 0x1a, 0xf5, 0x27,
+ 0xc4, 0x49, 0x5c, 0x84, 0xe1, 0x99, 0xd0, 0xdf, 0x4a, 0xbc, 0x60, 0xc7,
+ 0x83, 0xb3, 0x0e, 0xd7, 0x89, 0x66, 0x58, 0xeb, 0xd7, 0xc1, 0x68, 0x1f,
+ 0xa4, 0xde, 0xf5, 0x04, 0x76, 0x16, 0xea, 0x21, 0xf7, 0x64, 0x7f, 0x2b,
+ 0x9d, 0xe5, 0x3a, 0xae, 0x27, 0x3c, 0x61, 0xe0, 0x33, 0xe0, 0x83, 0x7e,
+ 0x06, 0xdb, 0x78, 0xf9, 0x26, 0x5f, 0xce, 0xd8, 0x4e, 0x1f, 0x63, 0xaf,
+ 0xf7, 0xe7, 0xac, 0x7d, 0xf0, 0xac, 0xc3, 0x7e, 0x1b, 0xfd, 0x3a, 0xe7,
+ 0x50, 0x4f, 0x2c, 0x8e, 0xa2, 0xb7, 0x64, 0xed, 0x1e, 0x80, 0x7e, 0x3e,
+ 0xac, 0xe7, 0xdb, 0x4a, 0x46, 0x8e, 0x35, 0xbd, 0x14, 0xab, 0xb5, 0xc3,
+ 0x88, 0xc9, 0x52, 0xb9, 0x4d, 0xd5, 0xc6, 0x6d, 0xc3, 0x85, 0x2c, 0xe6,
+ 0xea, 0x8c, 0xcb, 0x30, 0x7f, 0xac, 0x43, 0x6c, 0x88, 0xeb, 0xd3, 0xf1,
+ 0xca, 0xed, 0x39, 0xda, 0x49, 0x4a, 0x52, 0xf5, 0x6b, 0x88, 0x79, 0xc8,
+ 0x1f, 0x95, 0x0e, 0x7d, 0xf1, 0x76, 0xd2, 0x5f, 0x45, 0xec, 0x32, 0x72,
+ 0x62, 0xe8, 0xb9, 0xe6, 0xf8, 0x64, 0xb6, 0x0d, 0xb1, 0x7e, 0x6c, 0xbb,
+ 0x7e, 0x6e, 0xdf, 0xf6, 0xd8, 0xb9, 0xae, 0x52, 0x53, 0xae, 0xb2, 0x5d,
+ 0x9f, 0x86, 0x2f, 0xaf, 0x89, 0x8e, 0x98, 0x8a, 0x1a, 0x01, 0xe3, 0x73,
+ 0x0f, 0x3c, 0xa0, 0xe7, 0x62, 0x52, 0x4e, 0xc8, 0x93, 0x8b, 0x59, 0xf8,
+ 0xf5, 0x5a, 0x3a, 0x55, 0x94, 0x27, 0xa5, 0x5a, 0x3b, 0x24, 0x93, 0xb5,
+ 0xf0, 0xde, 0x80, 0x77, 0x06, 0x49, 0xe5, 0xbf, 0xe8, 0x5f, 0x27, 0x03,
+ 0xda, 0x41, 0x73, 0x7e, 0x84, 0x31, 0x3a, 0x4b, 0xdf, 0x7d, 0x0d, 0x3a,
+ 0xd1, 0x12, 0xd4, 0xda, 0xbe, 0xfe, 0x19, 0xb9, 0x8f, 0x30, 0x47, 0xfd,
+ 0xdb, 0xb0, 0x7a, 0x6e, 0x7b, 0x4e, 0xfd, 0x89, 0x8a, 0xa9, 0x4b, 0x36,
+ 0x9f, 0x09, 0xf3, 0xf6, 0xe0, 0x94, 0x75, 0xdd, 0x64, 0x6d, 0x70, 0xc1,
+ 0x21, 0x3e, 0x53, 0x9d, 0xb5, 0x91, 0xbb, 0x8c, 0xb5, 0xad, 0xa4, 0x0b,
+ 0xcd, 0xc0, 0x3c, 0xf6, 0x77, 0x9a, 0x83, 0x71, 0xb8, 0xf6, 0xb5, 0x86,
+ 0xb5, 0x9c, 0x63, 0x4f, 0xdc, 0xd8, 0xa3, 0xe1, 0xce, 0xe4, 0x82, 0x9b,
+ 0x51, 0x35, 0x7b, 0xc1, 0x55, 0xb9, 0x02, 0x6a, 0x74, 0xe8, 0x93, 0xba,
+ 0x43, 0x81, 0x3f, 0x72, 0xff, 0xce, 0xf4, 0xcf, 0x9d, 0xfe, 0x63, 0x45,
+ 0x18, 0xdf, 0xa8, 0x6f, 0x53, 0xca, 0x4f, 0xbd, 0xd9, 0x70, 0x17, 0xf0,
+ 0x26, 0xfc, 0xd2, 0x9d, 0x9b, 0xfd, 0x9a, 0xc6, 0x0c, 0x7c, 0x5a, 0xab,
+ 0xca, 0x53, 0x7c, 0x9f, 0x96, 0x6a, 0x80, 0x4d, 0xf1, 0xde, 0xa0, 0xc3,
+ 0xaf, 0xbd, 0x7f, 0x2b, 0x58, 0xc3, 0xfc, 0xc1, 0x32, 0x99, 0x3b, 0xf8,
+ 0xb2, 0xf0, 0x9e, 0x59, 0x1d, 0x27, 0x4a, 0x01, 0xbe, 0xa6, 0xe0, 0xdd,
+ 0x5b, 0x6d, 0x3e, 0x4d, 0xe1, 0xda, 0x3f, 0x0d, 0xee, 0xa6, 0x94, 0x2f,
+ 0xcc, 0x03, 0x16, 0x3c, 0xa4, 0x4a, 0x3a, 0xf4, 0x66, 0xa4, 0xee, 0xcb,
+ 0x1b, 0xf1, 0x8e, 0xf7, 0x4f, 0x8a, 0xb6, 0x0b, 0x2a, 0xe7, 0x68, 0xe4,
+ 0x3f, 0x4f, 0xbe, 0xf3, 0x06, 0x69, 0x74, 0xc7, 0xb0, 0x56, 0x0e, 0xf8,
+ 0x77, 0x14, 0xa6, 0x4c, 0x98, 0xfd, 0xe6, 0x24, 0xf1, 0x26, 0x04, 0xf8,
+ 0x90, 0x97, 0xe4, 0xc2, 0x33, 0xfc, 0x26, 0xf7, 0x06, 0xde, 0x8d, 0x1c,
+ 0xa3, 0xff, 0x66, 0x40, 0xcb, 0x8f, 0x03, 0x79, 0x85, 0xef, 0x7f, 0xb1,
+ 0xf9, 0xe6, 0xf1, 0x3d, 0xb7, 0x07, 0xf2, 0xc4, 0xf3, 0xa1, 0x5f, 0x43,
+ 0x13, 0xf5, 0xfd, 0x34, 0xf0, 0xa8, 0x18, 0x5c, 0xd1, 0x73, 0x88, 0xf9,
+ 0x59, 0x64, 0x34, 0x35, 0xd8, 0xb4, 0x20, 0xf6, 0xbb, 0x69, 0xbb, 0x84,
+ 0x55, 0x1f, 0xd5, 0xe8, 0x57, 0xaf, 0xc3, 0xaf, 0xf2, 0xac, 0x3f, 0x96,
+ 0xa9, 0x5a, 0xaf, 0xdd, 0xac, 0xa9, 0xfc, 0x3a, 0x73, 0x5a, 0xfa, 0xed,
+ 0xd3, 0xc8, 0x3d, 0x50, 0xa3, 0xa5, 0x8e, 0x08, 0x65, 0x7e, 0x5d, 0x76,
+ 0xa8, 0x9c, 0xe0, 0x63, 0xb1, 0x20, 0x93, 0x22, 0xea, 0x04, 0x7d, 0xe8,
+ 0x5f, 0x3d, 0x95, 0xd3, 0x68, 0xa8, 0x42, 0x6f, 0x81, 0xeb, 0x6d, 0x85,
+ 0x87, 0xf8, 0x1a, 0x71, 0x69, 0xd2, 0x32, 0x14, 0xe2, 0x4b, 0xc9, 0x51,
+ 0x37, 0xc4, 0x69, 0xc8, 0x65, 0x64, 0x2d, 0xfa, 0x90, 0x17, 0xf0, 0xcf,
+ 0xe7, 0x5f, 0x7a, 0xcc, 0x09, 0xf4, 0xdc, 0xdd, 0x81, 0x0c, 0x7e, 0x8f,
+ 0x32, 0xc0, 0x18, 0x3a, 0xef, 0x7c, 0xc5, 0xaf, 0x45, 0x54, 0x2d, 0x37,
+ 0x86, 0x9a, 0x82, 0x73, 0x2b, 0x2d, 0x05, 0x3b, 0x3c, 0xe3, 0x7d, 0x98,
+ 0x2b, 0xe2, 0x47, 0xb9, 0x10, 0x66, 0x3f, 0x9e, 0xf3, 0x01, 0x9c, 0x0c,
+ 0xfb, 0x35, 0x79, 0x58, 0x8b, 0x84, 0x39, 0xa1, 0xcc, 0xe8, 0x39, 0xe6,
+ 0xef, 0x3b, 0x40, 0x2b, 0x73, 0x56, 0x9c, 0xe7, 0xaa, 0xff, 0x59, 0x85,
+ 0xa9, 0xac, 0xc1, 0xf8, 0xb9, 0xe7, 0xa8, 0x1b, 0xe6, 0xbb, 0xcc, 0x69,
+ 0xc3, 0xdc, 0x27, 0xaf, 0x15, 0x9d, 0x31, 0xed, 0x3e, 0x87, 0xf0, 0xfa,
+ 0xec, 0x66, 0xb1, 0x52, 0x3d, 0xba, 0x27, 0x23, 0x43, 0xac, 0x9d, 0x8f,
+ 0xe1, 0xcc, 0x3b, 0xa4, 0x9c, 0x41, 0x1e, 0x60, 0xde, 0x85, 0xbe, 0x19,
+ 0x73, 0x5f, 0xc6, 0x1c, 0x74, 0x23, 0xc3, 0xfc, 0x66, 0x83, 0xaa, 0x41,
+ 0x4a, 0x2a, 0x76, 0xec, 0x08, 0xf4, 0xe5, 0x89, 0x4e, 0x5f, 0x3f, 0xbe,
+ 0x87, 0xf1, 0x46, 0xcc, 0x7f, 0x03, 0xbd, 0xe7, 0xf5, 0x0c, 0x85, 0xf3,
+ 0xd4, 0xfb, 0x61, 0xcc, 0xdf, 0x09, 0x1c, 0x15, 0x3c, 0x7f, 0x0e, 0xcf,
+ 0x7f, 0xb8, 0x6e, 0xed, 0x77, 0x31, 0xae, 0x60, 0xbe, 0xb0, 0x6e, 0x3e,
+ 0xf4, 0xb3, 0xdc, 0xaf, 0xa2, 0x15, 0xdd, 0x29, 0x2d, 0xaf, 0xea, 0x88,
+ 0x63, 0xa8, 0x55, 0xe8, 0x6b, 0x59, 0xb3, 0xcc, 0x20, 0x17, 0xa7, 0x9f,
+ 0x3d, 0x88, 0x35, 0x8b, 0xd0, 0xbb, 0x56, 0x95, 0x65, 0xea, 0xca, 0x1e,
+ 0x0f, 0x1d, 0xec, 0x99, 0x63, 0x5f, 0x39, 0x68, 0xd7, 0x09, 0xc3, 0xe7,
+ 0x27, 0x0f, 0xf6, 0xd4, 0x0f, 0x01, 0x96, 0xf9, 0x7a, 0xe3, 0x1d, 0xef,
+ 0x37, 0xd6, 0xed, 0xe9, 0xd7, 0x38, 0x45, 0x75, 0x37, 0x78, 0xe8, 0x60,
+ 0x61, 0x86, 0x71, 0x9a, 0xf5, 0x26, 0xf3, 0xd2, 0xca, 0xc1, 0xf1, 0xda,
+ 0x54, 0x50, 0xd3, 0x84, 0xef, 0xf9, 0x8e, 0xf2, 0xbf, 0x15, 0x6d, 0xa4,
+ 0xab, 0x11, 0x8f, 0xca, 0x6b, 0x80, 0xe7, 0x49, 0xe0, 0x61, 0x6d, 0xa4,
+ 0xee, 0x90, 0x15, 0xbd, 0xa9, 0xb9, 0x5b, 0xd1, 0x46, 0x5c, 0xdc, 0x2b,
+ 0xc4, 0x77, 0x02, 0x75, 0xc7, 0x77, 0x48, 0x2f, 0xf0, 0x7c, 0x26, 0xc8,
+ 0x6d, 0x78, 0x37, 0x65, 0xf8, 0x77, 0x38, 0x6a, 0x1c, 0xd6, 0xbe, 0x4d,
+ 0xeb, 0x6a, 0xdf, 0xa6, 0xe0, 0x1e, 0x8b, 0xb0, 0x7a, 0x00, 0xab, 0xee,
+ 0xd0, 0x31, 0x97, 0x0a, 0xee, 0x94, 0xe3, 0xbc, 0x53, 0x6e, 0x90, 0x45,
+ 0x53, 0x20, 0x7f, 0xd2, 0x11, 0xd6, 0x2b, 0x8d, 0xf4, 0xf1, 0xbe, 0x79,
+ 0x0a, 0xef, 0xc3, 0xb3, 0x09, 0x79, 0x5f, 0xc4, 0x3c, 0xe9, 0x3d, 0x03,
+ 0xf8, 0x90, 0xde, 0x4f, 0x7b, 0xa6, 0x5c, 0x7b, 0x06, 0xbf, 0x70, 0xbf,
+ 0x50, 0x2e, 0xa4, 0xf5, 0xd7, 0xd5, 0x5a, 0xa1, 0xdf, 0x5b, 0x0c, 0x62,
+ 0x3a, 0xe9, 0xa2, 0x0f, 0xa2, 0x3f, 0x0e, 0xef, 0xc0, 0x59, 0x63, 0x33,
+ 0x56, 0xf0, 0xbc, 0x5a, 0xa0, 0x2b, 0x84, 0xd3, 0x90, 0x5f, 0xeb, 0xcc,
+ 0xc3, 0x52, 0xa8, 0x35, 0x92, 0x8f, 0xc8, 0x0f, 0xb0, 0x57, 0x3e, 0xd3,
+ 0xa4, 0xec, 0x88, 0xf7, 0x08, 0xcd, 0xb2, 0x02, 0x9d, 0xbe, 0x84, 0xfa,
+ 0x63, 0x1e, 0xb5, 0xd1, 0x12, 0xef, 0xb5, 0xeb, 0x27, 0x3b, 0x79, 0x1f,
+ 0x32, 0x65, 0xad, 0xd5, 0xf1, 0x73, 0x80, 0x59, 0xb0, 0x58, 0xeb, 0x4b,
+ 0xd0, 0x10, 0x23, 0x91, 0x67, 0x8c, 0x5b, 0xff, 0xe3, 0x95, 0x13, 0x8d,
+ 0xb0, 0xb7, 0xaa, 0xb3, 0xdb, 0xa4, 0x3a, 0x9b, 0x3e, 0x3a, 0x87, 0x7a,
+ 0x77, 0xc6, 0xd2, 0xb7, 0xe8, 0x7e, 0xad, 0x34, 0x03, 0xdf, 0xa4, 0x6a,
+ 0xad, 0x39, 0x79, 0xae, 0x93, 0x67, 0xd7, 0x64, 0xf5, 0x9b, 0x9d, 0xfa,
+ 0xef, 0x50, 0x17, 0x15, 0xe5, 0xb1, 0x13, 0x1b, 0xa4, 0x3c, 0x70, 0x1f,
+ 0x72, 0x2d, 0xc8, 0xf3, 0x44, 0x05, 0x95, 0x21, 0xf5, 0xea, 0xbd, 0x03,
+ 0xe3, 0x16, 0x6b, 0x26, 0xf1, 0xe3, 0x9a, 0xf8, 0x3c, 0xc6, 0x4e, 0xb4,
+ 0x29, 0x9f, 0xe4, 0xdf, 0x99, 0xf7, 0x9a, 0x45, 0xe4, 0x63, 0x85, 0x01,
+ 0x24, 0x8d, 0xc8, 0x5e, 0xcc, 0x9d, 0x22, 0x3d, 0xcc, 0x19, 0xe1, 0x8f,
+ 0x7b, 0xce, 0xc1, 0xcb, 0x9d, 0x20, 0xbc, 0x2e, 0xc6, 0x89, 0x98, 0x34,
+ 0x9d, 0x60, 0x9d, 0x2d, 0x5d, 0xa8, 0x51, 0x88, 0xb3, 0xc7, 0x40, 0x3f,
+ 0x8a, 0xdf, 0x1e, 0xe4, 0x51, 0x26, 0xf2, 0xda, 0x5b, 0xc0, 0x03, 0x96,
+ 0x6b, 0x6e, 0x05, 0xff, 0x6a, 0x27, 0xeb, 0xce, 0x9e, 0x73, 0x84, 0xe7,
+ 0x7d, 0x76, 0x17, 0xe8, 0xf1, 0xf7, 0x27, 0x0e, 0xe3, 0x84, 0x48, 0xef,
+ 0xb4, 0x74, 0xea, 0x6a, 0x8d, 0x21, 0xe3, 0x59, 0xbe, 0x6b, 0x03, 0xfc,
+ 0xab, 0xca, 0x3e, 0x7b, 0xd5, 0x3a, 0xff, 0xce, 0xa2, 0xbc, 0x46, 0x37,
+ 0xe6, 0x34, 0x3c, 0x23, 0x57, 0xca, 0x9a, 0xd2, 0x3b, 0xef, 0xc3, 0xf6,
+ 0x9c, 0xeb, 0xd8, 0xe2, 0xdf, 0xed, 0xf8, 0xb4, 0xf1, 0x6e, 0xb0, 0x0c,
+ 0xa9, 0x1a, 0x3b, 0x59, 0xf3, 0x13, 0x86, 0xdf, 0x52, 0xd8, 0x73, 0x2d,
+ 0xe5, 0xe7, 0xcf, 0xe9, 0xfa, 0xff, 0xa5, 0x5f, 0xeb, 0xbf, 0xe1, 0x84,
+ 0x77, 0x4b, 0xa9, 0x86, 0xbb, 0xa5, 0x74, 0xc3, 0xb7, 0x97, 0x9f, 0xb4,
+ 0x05, 0x7a, 0x27, 0x93, 0xb6, 0x27, 0xe1, 0xf7, 0xa5, 0xbd, 0x37, 0xe5,
+ 0x90, 0x19, 0x15, 0xa7, 0xc7, 0x21, 0xfb, 0x2b, 0x75, 0xd2, 0x8b, 0x98,
+ 0x53, 0x8f, 0xcb, 0xfb, 0x8b, 0xad, 0x72, 0x65, 0xce, 0xcf, 0x29, 0xaf,
+ 0xa8, 0x6f, 0x4e, 0xa6, 0x7c, 0x80, 0xc2, 0xff, 0x72, 0x3d, 0x83, 0x5f,
+ 0xa7, 0x5c, 0x5d, 0xbc, 0x39, 0xa7, 0xbc, 0xe0, 0xde, 0x0d, 0x5a, 0x3a,
+ 0x03, 0x1b, 0x46, 0xdd, 0x86, 0x18, 0x58, 0x09, 0xee, 0xea, 0x55, 0xce,
+ 0x62, 0xd0, 0x16, 0x78, 0x27, 0x1f, 0xde, 0x57, 0xf7, 0x9a, 0x17, 0x21,
+ 0xe3, 0xaf, 0x1a, 0x9d, 0xa8, 0xa3, 0x79, 0xd7, 0x16, 0xc6, 0xec, 0x30,
+ 0xf6, 0x90, 0xee, 0xb7, 0x81, 0x7b, 0x00, 0x7a, 0x4a, 0xdd, 0xb4, 0xa1,
+ 0xb3, 0xa6, 0x2c, 0xf5, 0xa5, 0x67, 0x2a, 0xc2, 0xef, 0x02, 0x59, 0xec,
+ 0xb9, 0x0c, 0xbd, 0xcc, 0x40, 0x1e, 0xcc, 0xf5, 0x28, 0x57, 0x9c, 0xed,
+ 0xf4, 0x94, 0x94, 0xdd, 0xad, 0xc0, 0x97, 0x97, 0x92, 0x3b, 0x8c, 0xbd,
+ 0x8e, 0x43, 0x6f, 0x7f, 0xb9, 0x85, 0x77, 0x99, 0xcd, 0x56, 0x16, 0x34,
+ 0xde, 0x25, 0xe3, 0x27, 0xa7, 0x64, 0xc2, 0x59, 0xfd, 0x66, 0x94, 0xe1,
+ 0xf7, 0x94, 0x45, 0xd4, 0xb4, 0xbe, 0x3d, 0xe6, 0x64, 0xfc, 0x14, 0x70,
+ 0x38, 0xac, 0x8d, 0x7b, 0xa1, 0x37, 0xfd, 0xaa, 0x36, 0x2e, 0x29, 0x9f,
+ 0xc4, 0xf9, 0xef, 0x01, 0x57, 0x6f, 0x65, 0x0f, 0xe0, 0xca, 0xa8, 0x9f,
+ 0x8b, 0xc8, 0x85, 0x17, 0x1c, 0x43, 0xca, 0x36, 0x7c, 0x6b, 0x31, 0xa9,
+ 0xeb, 0xbb, 0xba, 0x65, 0xde, 0xe9, 0x37, 0x75, 0xde, 0x3d, 0x26, 0x7c,
+ 0xdf, 0x57, 0x56, 0xf6, 0x9d, 0xd4, 0x0d, 0xab, 0x5b, 0x16, 0x9d, 0x8a,
+ 0x54, 0x07, 0x38, 0xe6, 0xf9, 0x55, 0xc4, 0xb4, 0x7c, 0x5f, 0x99, 0xd7,
+ 0x35, 0x75, 0xb7, 0x5d, 0x76, 0xd5, 0xfd, 0x68, 0xca, 0x94, 0xc3, 0xa0,
+ 0x0f, 0xcf, 0x0b, 0xd0, 0xf1, 0x69, 0xe6, 0x78, 0xfe, 0x9d, 0xf1, 0x81,
+ 0xe5, 0x22, 0x68, 0x68, 0x97, 0xde, 0x1f, 0xd3, 0xc6, 0x1e, 0xc2, 0x1c,
+ 0xc7, 0x69, 0xe8, 0xeb, 0xc3, 0x78, 0x26, 0x6c, 0x12, 0x3d, 0xe5, 0xd0,
+ 0x8d, 0xde, 0x04, 0x2d, 0xd0, 0x4b, 0xd6, 0xa5, 0xfb, 0x53, 0x32, 0x7f,
+ 0x72, 0xb7, 0x94, 0x16, 0x76, 0x03, 0xff, 0x3f, 0x22, 0xe7, 0xbf, 0x33,
+ 0xb8, 0x8b, 0x65, 0xde, 0xcf, 0x7d, 0x5e, 0xdc, 0xa2, 0x6c, 0x63, 0x9a,
+ 0xf3, 0xec, 0xf7, 0x61, 0x3d, 0xea, 0x07, 0x47, 0xdd, 0x4f, 0x03, 0x06,
+ 0x67, 0xe7, 0x36, 0x7e, 0xfb, 0xeb, 0x84, 0x9f, 0xae, 0xb0, 0x76, 0x40,
+ 0x6c, 0x99, 0x1b, 0x2c, 0xd4, 0xd2, 0x66, 0x41, 0x7d, 0x97, 0xc8, 0x88,
+ 0x1f, 0x6f, 0x38, 0x17, 0x17, 0x6b, 0x1a, 0xf5, 0x68, 0x8e, 0xef, 0x0e,
+ 0xab, 0xfb, 0x1f, 0xf5, 0x7d, 0x4e, 0xde, 0x95, 0x51, 0xe8, 0x58, 0xef,
+ 0x74, 0x06, 0x39, 0xf1, 0x7b, 0xc8, 0x27, 0x7f, 0x1e, 0xc8, 0x60, 0x38,
+ 0xd0, 0x8d, 0xd6, 0x06, 0x9d, 0xc0, 0x39, 0x3b, 0x38, 0x7b, 0x07, 0x7a,
+ 0xe0, 0xe0, 0xac, 0x57, 0xf5, 0x63, 0xb8, 0xc1, 0xe7, 0x6e, 0x92, 0xbf,
+ 0x9c, 0x49, 0x67, 0x56, 0xa0, 0x3f, 0x57, 0xc1, 0xeb, 0x0a, 0xea, 0xbc,
+ 0x2b, 0x88, 0x23, 0x0b, 0x35, 0x7e, 0x4b, 0xe0, 0xb7, 0x38, 0x8e, 0xb7,
+ 0xe1, 0x3c, 0x42, 0x7f, 0xfc, 0x52, 0x60, 0x17, 0x9b, 0xd4, 0x7d, 0xe7,
+ 0xfb, 0x38, 0xc3, 0x15, 0xd3, 0xcf, 0x17, 0xfd, 0x35, 0x9b, 0x24, 0xfc,
+ 0xde, 0xe7, 0xeb, 0x0f, 0x69, 0xa1, 0xfe, 0x7c, 0xb2, 0xc5, 0xcf, 0xfb,
+ 0xf9, 0x0d, 0x8c, 0xf5, 0x0b, 0x9f, 0xef, 0xdf, 0xe2, 0xe3, 0x6a, 0xd4,
+ 0xdb, 0x8f, 0x3d, 0xd6, 0x6a, 0x85, 0x3e, 0xf8, 0x6c, 0xd7, 0x93, 0x63,
+ 0xf6, 0xcd, 0xf6, 0x76, 0x8f, 0x13, 0xca, 0x87, 0xf2, 0x2b, 0xca, 0x11,
+ 0x37, 0x0d, 0x5b, 0xa0, 0xec, 0xac, 0x06, 0xd9, 0x89, 0xfc, 0xb9, 0x23,
+ 0xbc, 0xef, 0xc2, 0x3b, 0x25, 0xbb, 0x64, 0x21, 0xd6, 0xca, 0xfb, 0x5a,
+ 0xe8, 0xe3, 0xdf, 0xca, 0xc4, 0xac, 0xc8, 0x32, 0xde, 0x2f, 0x39, 0xb4,
+ 0xd1, 0x0c, 0xf2, 0xd7, 0x8d, 0x32, 0x3f, 0x87, 0x3a, 0xcb, 0x91, 0x52,
+ 0xe1, 0x4e, 0xc6, 0x99, 0xb8, 0x5c, 0x51, 0xf7, 0x7b, 0x22, 0x3b, 0xcf,
+ 0x1a, 0x62, 0x9c, 0x45, 0x41, 0x07, 0x99, 0x9f, 0xef, 0x0b, 0xef, 0xfb,
+ 0x7c, 0x5b, 0xaf, 0xd6, 0xb0, 0xd6, 0xe9, 0x55, 0xfe, 0xb1, 0x5a, 0x1f,
+ 0x97, 0xf2, 0x0c, 0xf7, 0x42, 0x3f, 0x97, 0xc2, 0x3b, 0x5b, 0x26, 0x4f,
+ 0x66, 0xe4, 0xfb, 0xfc, 0x5e, 0x93, 0x1d, 0xc5, 0x1e, 0x05, 0xa9, 0x2c,
+ 0x63, 0xbe, 0xfe, 0x4f, 0x32, 0xb7, 0x38, 0x2e, 0xf3, 0x33, 0x17, 0x1a,
+ 0xee, 0x73, 0x31, 0x9e, 0x6b, 0xac, 0x4f, 0x8b, 0xac, 0xa9, 0x50, 0x7f,
+ 0x5a, 0x18, 0xc3, 0x06, 0xea, 0x93, 0xa5, 0x9b, 0xef, 0x1f, 0x1b, 0xeb,
+ 0xd2, 0x51, 0x39, 0x8a, 0x33, 0xae, 0x9e, 0xcc, 0xa8, 0xba, 0xa6, 0x25,
+ 0x37, 0xfb, 0xf8, 0x87, 0x88, 0x11, 0x63, 0x42, 0x3d, 0xbb, 0x2e, 0x5f,
+ 0xb3, 0x8f, 0xca, 0x23, 0x88, 0x1d, 0x47, 0x90, 0x5f, 0xff, 0x36, 0xea,
+ 0xba, 0xd4, 0x66, 0x9e, 0x21, 0xe8, 0xb5, 0x58, 0x57, 0x7a, 0x32, 0x6a,
+ 0xdf, 0x61, 0xfe, 0x00, 0x92, 0x7d, 0xbf, 0xce, 0xf8, 0xf8, 0xdf, 0x5e,
+ 0x1e, 0xf1, 0xee, 0x43, 0x0b, 0x3e, 0x41, 0xc1, 0x69, 0x3e, 0xdc, 0x0c,
+ 0xe1, 0xfa, 0xcd, 0x63, 0x84, 0x9b, 0xd3, 0x02, 0x38, 0x0d, 0x70, 0x31,
+ 0xb9, 0x68, 0x1b, 0xd0, 0x8d, 0x51, 0xf0, 0x09, 0xdf, 0x3e, 0x18, 0x7e,
+ 0x6f, 0xdc, 0x80, 0x98, 0xba, 0xb6, 0xfe, 0x8d, 0x60, 0xfd, 0xf7, 0x83,
+ 0xf5, 0x97, 0x56, 0xd7, 0x87, 0x71, 0xf5, 0x13, 0x4f, 0x1a, 0xe8, 0x7a,
+ 0xa3, 0xe6, 0xc3, 0x1f, 0x0d, 0xe8, 0xba, 0xb4, 0x4a, 0x57, 0x08, 0x0f,
+ 0x79, 0x2a, 0x9e, 0xe9, 0x93, 0xe9, 0x9b, 0x7b, 0x21, 0x47, 0x7e, 0x47,
+ 0x86, 0x4d, 0x38, 0xfc, 0x7e, 0x4b, 0x3b, 0xd1, 0x65, 0x25, 0x71, 0x54,
+ 0xc6, 0xac, 0xf4, 0xf0, 0xa4, 0xc4, 0xa0, 0xc3, 0xf4, 0x29, 0x31, 0x99,
+ 0xa7, 0xaf, 0x41, 0x5f, 0xb6, 0x6f, 0x4d, 0xeb, 0xfb, 0x0d, 0xb4, 0xc6,
+ 0x9e, 0x27, 0x8d, 0x3e, 0xad, 0xf1, 0x1d, 0x6b, 0xb4, 0xfa, 0xf0, 0x3e,
+ 0xad, 0xef, 0xd7, 0x1a, 0xe0, 0xcf, 0x1a, 0x01, 0xbc, 0xd1, 0x00, 0x4f,
+ 0x7d, 0x66, 0x3e, 0x41, 0x7d, 0x26, 0x6d, 0x5f, 0x50, 0xf7, 0x66, 0x1b,
+ 0x72, 0xb3, 0x07, 0x3f, 0xbf, 0xc3, 0x93, 0x38, 0xf2, 0x8c, 0x66, 0xbc,
+ 0xbb, 0x32, 0xc3, 0x1c, 0x44, 0xef, 0x69, 0x96, 0x9d, 0xd0, 0x59, 0x9e,
+ 0x5d, 0xe3, 0x9d, 0xab, 0x27, 0x8f, 0xd8, 0xa4, 0xe5, 0x3f, 0xbd, 0x33,
+ 0x89, 0x9d, 0x76, 0x55, 0xfa, 0xcc, 0x66, 0xe1, 0x9d, 0xae, 0xc2, 0x99,
+ 0x21, 0x2d, 0xa7, 0xfb, 0x7a, 0xcd, 0xb7, 0xc0, 0xe7, 0xe8, 0x8c, 0x26,
+ 0xf3, 0x56, 0x3a, 0x79, 0x1e, 0x38, 0xf6, 0xe0, 0x6c, 0xe6, 0x07, 0x48,
+ 0x8f, 0xc8, 0x04, 0xf4, 0x7b, 0x5e, 0xc5, 0x43, 0xea, 0x71, 0x7a, 0xac,
+ 0x82, 0x1c, 0xe7, 0xa7, 0x2a, 0xa6, 0x79, 0xde, 0x87, 0x88, 0x6b, 0x63,
+ 0xeb, 0x74, 0x4f, 0x3f, 0xeb, 0xeb, 0x9e, 0x7e, 0x16, 0xb5, 0xf1, 0xf1,
+ 0xb8, 0xb4, 0x2c, 0xc1, 0x7e, 0x9e, 0xef, 0x52, 0xfa, 0xa7, 0x3f, 0xcf,
+ 0x6f, 0x19, 0xf0, 0x73, 0xc7, 0x0d, 0xb1, 0x8e, 0xab, 0x38, 0x00, 0x79,
+ 0x17, 0x64, 0xf2, 0x14, 0x7d, 0xa9, 0x25, 0x3b, 0x8e, 0xf3, 0x3c, 0x98,
+ 0xcf, 0xcc, 0x0d, 0x8e, 0xc3, 0x46, 0xa6, 0xf8, 0x7d, 0x70, 0xe9, 0x23,
+ 0x19, 0xb7, 0x28, 0x07, 0x94, 0xfa, 0x4b, 0xa6, 0xc4, 0x96, 0xe0, 0x13,
+ 0x96, 0x92, 0xd2, 0x04, 0xdb, 0xd2, 0xcf, 0x26, 0xb4, 0xea, 0xec, 0x7f,
+ 0xc1, 0x1e, 0xf8, 0x4d, 0x20, 0x83, 0x71, 0x52, 0xab, 0xd6, 0x06, 0xd0,
+ 0x53, 0xcf, 0x91, 0x46, 0x9d, 0xa5, 0x9e, 0x93, 0x8e, 0xd0, 0x5e, 0xf0,
+ 0x7c, 0x36, 0xa3, 0xee, 0x6c, 0x3f, 0xb4, 0xc9, 0xcb, 0xdf, 0x48, 0x61,
+ 0x26, 0xfc, 0x1b, 0x10, 0xd9, 0x8c, 0x1c, 0xa6, 0xa3, 0x60, 0xef, 0x18,
+ 0xbe, 0x22, 0x9f, 0x96, 0xaf, 0x6d, 0x9f, 0x82, 0x2f, 0xf2, 0xd1, 0xc8,
+ 0x17, 0x79, 0x6a, 0x97, 0x26, 0xc5, 0x57, 0xc8, 0x0f, 0x04, 0x0d, 0x7e,
+ 0x7a, 0x8e, 0x27, 0x81, 0xff, 0x61, 0xf8, 0x80, 0x6e, 0xf4, 0x0f, 0xa1,
+ 0x47, 0x28, 0x3b, 0x4b, 0xde, 0xc9, 0xeb, 0x55, 0xe4, 0x8b, 0x21, 0x9f,
+ 0x25, 0x3c, 0xbf, 0x2e, 0x93, 0xb3, 0xde, 0x61, 0xc4, 0x53, 0xde, 0x27,
+ 0x77, 0xea, 0x4a, 0x77, 0xd7, 0xf3, 0xfe, 0xba, 0xf8, 0xf2, 0xe1, 0x5d,
+ 0x3c, 0x9e, 0x17, 0xd7, 0xcb, 0xa2, 0xd1, 0x77, 0x24, 0x83, 0xbf, 0x7b,
+ 0xa1, 0x9f, 0xa0, 0x8c, 0xae, 0x4a, 0x61, 0x96, 0x77, 0x5a, 0x3e, 0xbe,
+ 0xd2, 0xea, 0xdf, 0xbe, 0x34, 0xae, 0x19, 0x00, 0x5c, 0x37, 0xe0, 0x48,
+ 0xd7, 0x0a, 0xe5, 0x07, 0x9f, 0xb3, 0xbd, 0xc1, 0xd7, 0x34, 0xae, 0xcb,
+ 0xca, 0x33, 0x88, 0xff, 0x6f, 0xd8, 0x37, 0xc9, 0xb5, 0xc4, 0x1c, 0x68,
+ 0xbe, 0xbe, 0x0f, 0x36, 0xd9, 0x04, 0x5f, 0x66, 0xca, 0x95, 0x5a, 0xb3,
+ 0xcc, 0x23, 0xcf, 0x59, 0x58, 0xa4, 0x2f, 0x24, 0xed, 0xad, 0x98, 0xf7,
+ 0xfd, 0x17, 0x7d, 0xed, 0x95, 0x1a, 0xe2, 0x2b, 0x6c, 0xfb, 0x4a, 0x2d,
+ 0x81, 0xbe, 0x1b, 0xbd, 0x85, 0x3e, 0x85, 0x3e, 0x83, 0x7e, 0x00, 0xfd,
+ 0x00, 0x7a, 0x0b, 0x6b, 0x93, 0xe8, 0xc3, 0x5a, 0x82, 0xb8, 0xd6, 0xf8,
+ 0xae, 0xaa, 0xfd, 0xf8, 0xdd, 0x90, 0xb1, 0xcc, 0xb0, 0x47, 0x50, 0x63,
+ 0x17, 0x06, 0xc2, 0xbf, 0xb9, 0xb9, 0xe1, 0x99, 0x16, 0x6b, 0xf7, 0x8a,
+ 0xb6, 0x47, 0x7d, 0x5f, 0x98, 0x41, 0x5c, 0x78, 0x6e, 0xab, 0xb4, 0x5a,
+ 0xe6, 0x3d, 0xea, 0xee, 0x68, 0x16, 0x63, 0x3e, 0xa3, 0x3e, 0x4e, 0x4c,
+ 0x21, 0x3e, 0xd1, 0x7f, 0xfe, 0x6f, 0xe7, 0xd6, 0x1b, 0xdb, 0xc6, 0x59,
+ 0xc6, 0x1f, 0x9f, 0x9d, 0x34, 0xe9, 0x9a, 0xf6, 0x92, 0x38, 0xa9, 0x93,
+ 0x85, 0xcd, 0x8e, 0x2f, 0xad, 0x45, 0xd2, 0x71, 0xed, 0x2c, 0x16, 0xa6,
+ 0x8c, 0x78, 0x76, 0x92, 0x76, 0x30, 0xa6, 0xb4, 0x74, 0xd3, 0x84, 0x10,
+ 0x58, 0xc9, 0xba, 0x75, 0x13, 0xd2, 0x28, 0x30, 0x34, 0x89, 0xa2, 0x18,
+ 0x27, 0x61, 0x19, 0x18, 0xc7, 0x0b, 0x81, 0x4e, 0xf0, 0xc5, 0x38, 0xd1,
+ 0x06, 0x22, 0x4a, 0x3a, 0x8d, 0x0f, 0x08, 0x6d, 0x74, 0xb8, 0x83, 0xef,
+ 0xfc, 0x11, 0x62, 0x12, 0x1f, 0xaa, 0xa8, 0x63, 0x20, 0x21, 0xe0, 0x23,
+ 0xd2, 0x98, 0x8e, 0xdf, 0xef, 0x79, 0xef, 0x12, 0xc7, 0x64, 0x54, 0xf0,
+ 0xc1, 0x3a, 0xbf, 0x77, 0xf7, 0xbe, 0xf7, 0xde, 0xfb, 0x3c, 0xef, 0xef,
+ 0xf9, 0x3d, 0x7f, 0xce, 0x43, 0x9f, 0x19, 0xe0, 0xf8, 0x11, 0x61, 0x0c,
+ 0x36, 0x9b, 0xc6, 0xff, 0xea, 0xc5, 0x1e, 0x63, 0x4b, 0xc1, 0xdb, 0x77,
+ 0xb8, 0x61, 0x60, 0xab, 0x46, 0xd0, 0x67, 0x3f, 0x9f, 0x00, 0x36, 0xb0,
+ 0x92, 0xa8, 0x54, 0xb1, 0x07, 0x7f, 0xed, 0xce, 0x29, 0xa7, 0xa3, 0x2c,
+ 0x16, 0xc1, 0x4d, 0x73, 0x65, 0x72, 0x97, 0xcb, 0xf0, 0x47, 0xe0, 0xcb,
+ 0x45, 0xe9, 0xbb, 0xd3, 0x16, 0x90, 0x83, 0xfe, 0x12, 0x73, 0xa3, 0x1d,
+ 0xf8, 0x26, 0x9e, 0x87, 0xf7, 0x5a, 0xf3, 0xb0, 0x66, 0xa7, 0xc1, 0x05,
+ 0x3d, 0x2f, 0xe2, 0x4c, 0x4a, 0xfc, 0x1c, 0x31, 0x47, 0xd0, 0xdf, 0xc4,
+ 0xb2, 0xc8, 0xab, 0x32, 0xd3, 0x9a, 0x83, 0x84, 0x72, 0xfd, 0x0e, 0x7d,
+ 0x7b, 0xc4, 0xc4, 0xa7, 0x18, 0x7f, 0x16, 0x99, 0x2c, 0x1b, 0x2e, 0x0b,
+ 0xbf, 0xac, 0x61, 0xbc, 0xbb, 0xfd, 0xf1, 0x78, 0xdd, 0xd2, 0x71, 0x6a,
+ 0xd2, 0x6b, 0x62, 0xbb, 0x63, 0x23, 0xb0, 0x11, 0x51, 0xa9, 0x43, 0x2e,
+ 0xd7, 0x21, 0x93, 0x37, 0x4b, 0xd4, 0xf5, 0x61, 0xe8, 0x7d, 0x0b, 0xf3,
+ 0xb3, 0x18, 0x6b, 0x44, 0x9f, 0x5d, 0x2f, 0x01, 0x3b, 0x6d, 0xf5, 0x4f,
+ 0x7b, 0xc9, 0x0b, 0x69, 0x07, 0xcd, 0x38, 0x03, 0xe6, 0x3e, 0x09, 0xae,
+ 0x75, 0xeb, 0x7c, 0x6a, 0x1a, 0x03, 0xe3, 0x3a, 0x41, 0x07, 0x4b, 0xdd,
+ 0xfe, 0x3d, 0x5e, 0x8f, 0xa9, 0x77, 0xe2, 0x39, 0xbe, 0xc7, 0x88, 0x64,
+ 0xcb, 0x41, 0xbf, 0x4e, 0xf4, 0x6b, 0x6f, 0x18, 0xeb, 0x68, 0xd3, 0x3b,
+ 0x58, 0xfe, 0x3b, 0xf0, 0x7a, 0x33, 0xdf, 0x4f, 0xd8, 0x05, 0x09, 0x38,
+ 0x3f, 0xed, 0x2f, 0x65, 0x93, 0xd6, 0xfc, 0xb6, 0x91, 0xcf, 0x80, 0xef,
+ 0x03, 0x24, 0x96, 0x0a, 0x02, 0xbe, 0x18, 0xa5, 0x8c, 0xd2, 0xd8, 0xd7,
+ 0x3f, 0x89, 0xca, 0x61, 0x57, 0x2a, 0xa5, 0x03, 0x62, 0x75, 0xb5, 0x68,
+ 0x8d, 0x4e, 0xdc, 0x6a, 0x7c, 0xe6, 0x67, 0xfd, 0x67, 0xc2, 0xf7, 0x5e,
+ 0x69, 0xd7, 0xb8, 0x34, 0xec, 0x0c, 0xee, 0x39, 0xd4, 0x34, 0xb7, 0x87,
+ 0xfd, 0xfb, 0x78, 0xdd, 0x91, 0x02, 0xf8, 0x67, 0xae, 0x0c, 0x26, 0x0f,
+ 0xfc, 0xb6, 0xc6, 0x98, 0xe3, 0x61, 0x0c, 0x6f, 0x38, 0x3e, 0x8f, 0x39,
+ 0x16, 0xec, 0x31, 0xc6, 0xcd, 0x30, 0x46, 0x5f, 0xd3, 0x18, 0x13, 0xfe,
+ 0x18, 0x59, 0x29, 0x5e, 0x99, 0xc0, 0x5e, 0x1b, 0x83, 0x7d, 0x4f, 0xda,
+ 0xa7, 0xe5, 0x23, 0x22, 0x9d, 0x38, 0xf7, 0x72, 0x0a, 0x72, 0xf2, 0xbc,
+ 0x49, 0x77, 0x1a, 0xf3, 0x7e, 0x0d, 0xb6, 0x35, 0xe0, 0x3c, 0xc5, 0x58,
+ 0x18, 0x36, 0xec, 0xf3, 0x2e, 0xe3, 0x62, 0x05, 0x30, 0xb2, 0x84, 0x6d,
+ 0x85, 0x86, 0x53, 0x35, 0xf0, 0xba, 0x2a, 0x2c, 0x69, 0xd1, 0xe1, 0x7b,
+ 0x76, 0x48, 0xd1, 0x0e, 0x8d, 0x87, 0xc1, 0x6b, 0xb2, 0x65, 0xee, 0x23,
+ 0x19, 0x0a, 0x8f, 0xb5, 0x82, 0x8b, 0x7a, 0xf2, 0x36, 0xa0, 0xa6, 0x58,
+ 0x5a, 0x92, 0xfa, 0x86, 0x8d, 0xe3, 0x05, 0xc8, 0xe1, 0x45, 0xfc, 0x7f,
+ 0x3e, 0xaa, 0x75, 0x4a, 0xe0, 0xeb, 0x8b, 0x78, 0x1f, 0xf2, 0x19, 0xf2,
+ 0x88, 0x1a, 0xec, 0xad, 0x05, 0x5b, 0x03, 0x5e, 0x35, 0x4a, 0xde, 0xf5,
+ 0xdc, 0xda, 0x4d, 0x79, 0x73, 0x35, 0x81, 0x67, 0xd1, 0x2e, 0x9f, 0x21,
+ 0x1e, 0xd8, 0x0b, 0x69, 0x9c, 0x5b, 0x37, 0xdc, 0xb7, 0xb8, 0x85, 0x0d,
+ 0xd4, 0x05, 0x8e, 0x00, 0x8e, 0xbd, 0x0d, 0x0c, 0x2c, 0xe2, 0xfe, 0xfa,
+ 0x6a, 0x44, 0xd6, 0x1c, 0xf2, 0x22, 0x89, 0x67, 0x71, 0x6f, 0x7d, 0x7d,
+ 0xb1, 0xd7, 0xe4, 0x51, 0xd8, 0x7f, 0x42, 0x0a, 0xe0, 0x75, 0xa7, 0xb5,
+ 0xef, 0xad, 0xe4, 0xcc, 0x39, 0x35, 0xfa, 0x77, 0xb3, 0x52, 0xe7, 0x7e,
+ 0xd2, 0xdc, 0x03, 0xb9, 0xc1, 0x65, 0xe8, 0x2c, 0x39, 0x3b, 0xfd, 0x00,
+ 0xfc, 0xdf, 0xe0, 0x75, 0xbe, 0x3b, 0x8e, 0xd5, 0x24, 0xd6, 0x86, 0xfb,
+ 0xbe, 0x10, 0x9a, 0x3e, 0x0e, 0x3b, 0x6a, 0x71, 0xaf, 0x17, 0x15, 0x0b,
+ 0x8a, 0xcb, 0xb3, 0xb0, 0x29, 0xac, 0xb5, 0xe8, 0x83, 0x2e, 0x3e, 0x08,
+ 0x59, 0xa6, 0x71, 0x5f, 0x93, 0x2d, 0xd9, 0x2c, 0x2a, 0x2f, 0xb3, 0x5e,
+ 0x32, 0xb8, 0x66, 0xd5, 0xc0, 0xd1, 0xb0, 0x7f, 0xac, 0x4d, 0xe8, 0x16,
+ 0xf6, 0x90, 0xb5, 0x19, 0xc5, 0x11, 0x78, 0xbc, 0x09, 0xbf, 0x02, 0xf8,
+ 0x66, 0x6d, 0xc2, 0x27, 0x00, 0xbe, 0x59, 0x9b, 0x29, 0x1c, 0x81, 0xf1,
+ 0x9b, 0x01, 0xae, 0x71, 0xfc, 0x94, 0xe6, 0xe1, 0x0d, 0xbe, 0x90, 0x4b,
+ 0x12, 0x5f, 0x02, 0x3e, 0x69, 0x74, 0xe1, 0xeb, 0xcb, 0xc4, 0x10, 0xea,
+ 0x75, 0x12, 0xb8, 0x45, 0x5d, 0x30, 0x5c, 0x72, 0xbd, 0x62, 0xd6, 0x6c,
+ 0x7e, 0xeb, 0x9a, 0xda, 0x88, 0x29, 0x71, 0xa0, 0x63, 0x5c, 0x3b, 0x5c,
+ 0x53, 0x1b, 0xf0, 0xba, 0x64, 0xf4, 0xc8, 0x35, 0xfb, 0xb9, 0x64, 0xd6,
+ 0x53, 0xf2, 0x0d, 0xc5, 0xad, 0x00, 0xb3, 0xc8, 0x21, 0x63, 0x58, 0x3f,
+ 0x47, 0x9e, 0xff, 0xf6, 0x4d, 0xc9, 0x7e, 0x87, 0xb8, 0x35, 0x1c, 0x6b,
+ 0x0f, 0x11, 0xab, 0x3c, 0xd9, 0x80, 0x6d, 0x3a, 0xed, 0x26, 0x1e, 0x65,
+ 0xfd, 0x66, 0x1e, 0xba, 0xd2, 0x7a, 0x32, 0xe1, 0xc6, 0x43, 0xc9, 0x47,
+ 0xdb, 0x43, 0xb4, 0x8d, 0xc3, 0xf6, 0x45, 0x39, 0xe5, 0xc7, 0xa3, 0x0e,
+ 0xc8, 0x45, 0xe5, 0xfe, 0x2c, 0xcf, 0x78, 0x57, 0x73, 0x23, 0xef, 0xa4,
+ 0xb9, 0xd6, 0x68, 0x6f, 0x6a, 0xdc, 0xa8, 0xed, 0x9d, 0x74, 0x8b, 0x14,
+ 0x7b, 0x3c, 0xef, 0xc2, 0xc9, 0xb7, 0xa2, 0x26, 0xce, 0xd5, 0x7f, 0xd4,
+ 0x60, 0x01, 0x00, 0x4c, 0xdb, 0x9f, 0xc0, 0x91, 0xba, 0x4d, 0x7b, 0x4b,
+ 0xfb, 0x48, 0xb9, 0xe1, 0xb8, 0xce, 0xff, 0xb4, 0xbd, 0x4b, 0xb0, 0xbd,
+ 0xb4, 0x97, 0x47, 0x24, 0xc7, 0x9c, 0x9c, 0xa5, 0xe7, 0x0b, 0x86, 0x4b,
+ 0xfb, 0xf7, 0x55, 0xf2, 0x32, 0x5f, 0x21, 0x87, 0xaa, 0xc3, 0x96, 0xb1,
+ 0xf6, 0x91, 0x36, 0x6d, 0x0e, 0xf6, 0x9c, 0xb9, 0x5a, 0x5c, 0xab, 0xb2,
+ 0x5f, 0x22, 0x15, 0xb7, 0xf0, 0xce, 0x3b, 0x3a, 0x55, 0x82, 0xfe, 0x51,
+ 0x9f, 0x20, 0xf7, 0x17, 0xe8, 0x5b, 0x0c, 0xa9, 0x8e, 0x64, 0x7f, 0xc0,
+ 0xb5, 0xf7, 0xbc, 0x33, 0x2e, 0xd4, 0xb0, 0xd3, 0xec, 0x01, 0xf2, 0x80,
+ 0x8f, 0x63, 0x5d, 0xa6, 0xdc, 0x9b, 0xb4, 0xdd, 0x7f, 0xb7, 0x9c, 0xe1,
+ 0xd4, 0xc5, 0x10, 0xf7, 0x36, 0xda, 0xeb, 0x61, 0xa9, 0x46, 0xf9, 0xfe,
+ 0x58, 0xaf, 0x10, 0xf7, 0xce, 0x7e, 0xeb, 0xd0, 0xbc, 0x06, 0x59, 0xac,
+ 0x01, 0xd7, 0x32, 0x58, 0x03, 0xfe, 0x9f, 0x80, 0xbc, 0xe8, 0x33, 0x10,
+ 0x87, 0xf1, 0x7f, 0xcb, 0x3c, 0x9b, 0x75, 0x99, 0xbb, 0x73, 0xe6, 0x7c,
+ 0x29, 0xd3, 0xd7, 0x25, 0xa7, 0xf2, 0x5d, 0x92, 0x5c, 0xe5, 0x75, 0x99,
+ 0xac, 0x2c, 0xc9, 0x03, 0xce, 0x38, 0xde, 0xf7, 0x86, 0x37, 0xeb, 0xa8,
+ 0xaf, 0x32, 0x3a, 0x83, 0x67, 0xcf, 0x8e, 0xf4, 0xc9, 0x9f, 0x5d, 0x47,
+ 0x16, 0xd7, 0x6c, 0xc9, 0xdb, 0x69, 0x79, 0x5e, 0x63, 0xf9, 0xf4, 0x4f,
+ 0x42, 0xe0, 0xa4, 0xcc, 0xc9, 0xb7, 0x89, 0xf4, 0x38, 0xb1, 0x6d, 0x21,
+ 0xa7, 0x6c, 0x81, 0xac, 0xe3, 0x86, 0x37, 0xdb, 0xe6, 0xfa, 0xb1, 0x17,
+ 0xc0, 0xdd, 0xdd, 0xb7, 0x7a, 0x83, 0xf8, 0xb0, 0xe1, 0xb7, 0x7f, 0xf0,
+ 0xf3, 0x62, 0x69, 0xa9, 0x30, 0x07, 0xa7, 0x38, 0xeb, 0x40, 0x97, 0x98,
+ 0xc3, 0x8f, 0x69, 0xdc, 0xa1, 0xa5, 0x4c, 0x8c, 0xba, 0x0a, 0x8c, 0x1a,
+ 0x25, 0x76, 0x8d, 0xaf, 0xb9, 0x8c, 0x0b, 0x44, 0xe5, 0xb7, 0x25, 0xe2,
+ 0x70, 0x5c, 0x7e, 0x53, 0x7a, 0x16, 0xf3, 0x49, 0x54, 0x19, 0xcf, 0xbc,
+ 0x5e, 0x29, 0x90, 0x27, 0x29, 0x9f, 0xcf, 0xba, 0x5f, 0x54, 0x3b, 0x10,
+ 0xb7, 0x8a, 0xdd, 0x2d, 0x8a, 0x37, 0x4f, 0x6b, 0x1e, 0x36, 0x6e, 0x0d,
+ 0xc8, 0xf5, 0x55, 0xbe, 0x6f, 0x0a, 0x63, 0x47, 0x43, 0xb9, 0x75, 0xda,
+ 0xa5, 0x64, 0x6c, 0xc6, 0x3a, 0x20, 0x17, 0xa2, 0x8c, 0x53, 0x8f, 0x11,
+ 0x9f, 0x61, 0x0b, 0x87, 0xed, 0x19, 0xd6, 0x38, 0xa9, 0xfd, 0x89, 0x35,
+ 0xe1, 0xec, 0xd3, 0x3e, 0xce, 0xf2, 0xda, 0x18, 0x64, 0x4a, 0x5b, 0x94,
+ 0xa8, 0x4c, 0x58, 0x49, 0xd8, 0x3c, 0xfc, 0xdf, 0xe0, 0xf8, 0x71, 0xf9,
+ 0xc2, 0xc6, 0x45, 0xf0, 0xef, 0x61, 0xfb, 0x1c, 0xed, 0xaa, 0x3d, 0x8a,
+ 0x7b, 0xf9, 0xfc, 0x0f, 0x34, 0x8d, 0xf5, 0x69, 0x7f, 0x2c, 0x5e, 0xc7,
+ 0x3e, 0x2f, 0x3b, 0x32, 0x5b, 0x62, 0x2e, 0xda, 0xcc, 0x75, 0xef, 0xbd,
+ 0x67, 0x77, 0x9e, 0xbb, 0xb0, 0x4c, 0x7e, 0x63, 0xea, 0xdc, 0x8a, 0xe0,
+ 0x42, 0x9f, 0xec, 0xe2, 0x33, 0xf9, 0xbc, 0xc3, 0x92, 0x7d, 0x04, 0xf8,
+ 0x52, 0xe6, 0xaf, 0xe0, 0xd7, 0xde, 0xc2, 0x5f, 0x89, 0xf6, 0xef, 0x63,
+ 0x9b, 0xee, 0xf3, 0xc7, 0xfb, 0x3d, 0x74, 0x28, 0xda, 0x70, 0x3f, 0x63,
+ 0x2a, 0x6c, 0xc7, 0xa5, 0xb0, 0xc1, 0xa3, 0xe7, 0x75, 0x39, 0xad, 0x72,
+ 0xce, 0xbe, 0xbd, 0x69, 0x8c, 0x13, 0x38, 0x67, 0x38, 0x41, 0xb8, 0x1c,
+ 0xf2, 0xb9, 0xc5, 0x9d, 0xe4, 0x4d, 0xfe, 0xff, 0x36, 0x8d, 0xc5, 0xc4,
+ 0xad, 0xfe, 0xa6, 0xf7, 0xb8, 0x73, 0xc7, 0x0e, 0xc7, 0x2d, 0x62, 0xe7,
+ 0x8f, 0x71, 0x8d, 0x3a, 0xe4, 0x29, 0x8f, 0x8f, 0x80, 0xe7, 0xe7, 0x80,
+ 0x05, 0x51, 0xe7, 0xb6, 0x18, 0x8b, 0x4d, 0xae, 0x2d, 0x9b, 0x7a, 0x54,
+ 0x72, 0xe0, 0x6b, 0xfb, 0xe6, 0x6a, 0x53, 0xd0, 0x65, 0x8c, 0x7f, 0x90,
+ 0xe3, 0x8f, 0xf8, 0xeb, 0x9c, 0x70, 0x0b, 0xd6, 0x87, 0x65, 0x66, 0xd5,
+ 0xe8, 0x5f, 0xd6, 0x81, 0xee, 0x1d, 0x46, 0x7b, 0x9d, 0x36, 0xe1, 0xfd,
+ 0xc6, 0x09, 0x6c, 0x43, 0x4a, 0x6d, 0xc3, 0xfc, 0x32, 0xf5, 0x93, 0x7a,
+ 0x19, 0xe8, 0x63, 0x80, 0x79, 0xd4, 0x51, 0xe2, 0x6c, 0x5a, 0x5e, 0x58,
+ 0xe6, 0xda, 0x64, 0x34, 0xa7, 0x35, 0xb4, 0x32, 0xab, 0xf5, 0x3d, 0x83,
+ 0xe5, 0xc4, 0x8b, 0x05, 0x19, 0x97, 0xab, 0x2e, 0xd7, 0x2c, 0x51, 0xcd,
+ 0x87, 0x3b, 0x1a, 0xde, 0xff, 0x9c, 0xbf, 0x66, 0x29, 0xd5, 0xab, 0xc1,
+ 0xf2, 0xe5, 0x1d, 0x79, 0xe7, 0xad, 0xc3, 0x4d, 0xeb, 0x14, 0x70, 0xb8,
+ 0xb8, 0x90, 0x3f, 0x44, 0xba, 0xd8, 0x87, 0xcf, 0x25, 0xe7, 0xe3, 0xb3,
+ 0x68, 0x5b, 0xef, 0x60, 0x3d, 0x83, 0xd0, 0x8f, 0x8b, 0x3c, 0x62, 0xb8,
+ 0x45, 0xde, 0x7a, 0x18, 0xeb, 0x76, 0x50, 0xeb, 0x28, 0xe7, 0xbf, 0xfb,
+ 0x1e, 0xfa, 0xe7, 0x7d, 0x7e, 0x9e, 0xc6, 0x78, 0x7c, 0x77, 0xee, 0xa9,
+ 0xd2, 0x49, 0xea, 0xe6, 0xa4, 0xe6, 0x03, 0xd9, 0x87, 0xfb, 0x96, 0x6b,
+ 0x44, 0x39, 0x5c, 0x8e, 0x19, 0x7b, 0x7a, 0xa2, 0x69, 0x3e, 0x49, 0x7f,
+ 0x3e, 0xc1, 0xf5, 0x16, 0x89, 0xf4, 0xa6, 0xb4, 0x96, 0x24, 0x59, 0xa6,
+ 0x8f, 0x02, 0x5b, 0x35, 0xcd, 0xb1, 0x6e, 0x8d, 0xbd, 0xf9, 0xff, 0x13,
+ 0x7b, 0xf3, 0x56, 0x49, 0xe7, 0xd8, 0xe2, 0xfc, 0x2f, 0x72, 0x6c, 0xac,
+ 0xa7, 0x37, 0x72, 0x7b, 0x6e, 0x99, 0xf6, 0x29, 0xa3, 0xb1, 0xe3, 0x3f,
+ 0x95, 0xb8, 0x96, 0x9c, 0xe3, 0x55, 0xce, 0x71, 0xbc, 0xae, 0xb5, 0x74,
+ 0x0f, 0xe9, 0x9e, 0x5d, 0x5c, 0x26, 0xa6, 0x74, 0xc8, 0x5a, 0x25, 0xc0,
+ 0x95, 0x07, 0x7c, 0x4e, 0x5b, 0xec, 0x6e, 0xc5, 0x3e, 0x39, 0xe3, 0x5a,
+ 0x5a, 0x47, 0x68, 0x3d, 0xcc, 0x73, 0x03, 0x52, 0x5b, 0xa5, 0x9d, 0x4d,
+ 0xc2, 0xaf, 0x88, 0x86, 0x6a, 0xeb, 0xcc, 0x45, 0xb2, 0x4e, 0x64, 0x5c,
+ 0x98, 0xbb, 0xcf, 0xd9, 0xf3, 0xd8, 0x5f, 0x31, 0xf8, 0xfd, 0xe4, 0xf0,
+ 0x8c, 0x8f, 0x35, 0xcb, 0x7b, 0x74, 0x87, 0x03, 0xee, 0x95, 0xf3, 0x2f,
+ 0xb0, 0xde, 0xd4, 0x6b, 0xc7, 0xbe, 0x0e, 0x3b, 0x99, 0x8b, 0xf2, 0xff,
+ 0x0c, 0xb8, 0x3f, 0x7d, 0x8d, 0xb8, 0xfa, 0x1a, 0xb5, 0x6a, 0x46, 0x96,
+ 0x54, 0xf7, 0x3b, 0xfc, 0x58, 0x52, 0x87, 0xea, 0x07, 0x75, 0x2c, 0xaf,
+ 0x9c, 0x7b, 0x54, 0x71, 0xaa, 0x58, 0x1a, 0x36, 0x75, 0x26, 0x76, 0xcc,
+ 0xaf, 0x27, 0x6f, 0x7c, 0x7e, 0xcc, 0x7f, 0xfe, 0x5f, 0x7c, 0xf9, 0xda,
+ 0x8a, 0x31, 0xba, 0xd6, 0x56, 0x52, 0x7d, 0xcb, 0xf9, 0x65, 0xea, 0x07,
+ 0xf5, 0x84, 0x38, 0x17, 0xdc, 0x17, 0xc8, 0x24, 0x68, 0xf3, 0x7e, 0xea,
+ 0x7c, 0x63, 0x4d, 0x41, 0xb0, 0x3f, 0x83, 0x73, 0x81, 0x8c, 0x78, 0xad,
+ 0xd1, 0x0e, 0x70, 0xaf, 0xc5, 0x21, 0xa7, 0xdd, 0xfd, 0xd6, 0x55, 0xde,
+ 0x95, 0x4d, 0xf6, 0x14, 0xe7, 0x7f, 0x99, 0x71, 0x5c, 0xec, 0xb1, 0xfd,
+ 0xe4, 0xf3, 0x65, 0x95, 0x4f, 0x1e, 0xf2, 0xe9, 0x52, 0xdc, 0xa7, 0x8f,
+ 0x77, 0xc9, 0xd7, 0xb9, 0x0e, 0xac, 0x19, 0xe3, 0xb2, 0xc0, 0xb7, 0xf3,
+ 0xc4, 0xf9, 0xbe, 0x3e, 0xe2, 0x0b, 0x63, 0x8a, 0x99, 0xe9, 0x43, 0xc0,
+ 0x30, 0xb6, 0x8f, 0x2b, 0x07, 0x31, 0x3e, 0x56, 0x5c, 0x63, 0x8b, 0x61,
+ 0x60, 0x72, 0xad, 0x04, 0x7e, 0xc6, 0xba, 0xaf, 0x3d, 0xf2, 0x7a, 0xca,
+ 0x5f, 0xaf, 0x89, 0x3e, 0xca, 0x87, 0xfb, 0x80, 0x58, 0xd9, 0x89, 0xf1,
+ 0xce, 0x46, 0x53, 0xd0, 0xb1, 0x71, 0x9c, 0x1f, 0x52, 0x1f, 0x22, 0x8c,
+ 0x7d, 0xbe, 0x5d, 0xea, 0xf5, 0xfd, 0x36, 0x07, 0x6d, 0xf8, 0xaa, 0xa5,
+ 0x2e, 0xfa, 0x11, 0x1a, 0x47, 0x6c, 0x2d, 0xc3, 0x67, 0x05, 0x76, 0xd7,
+ 0xd5, 0x06, 0x8d, 0xe0, 0xfa, 0x6d, 0xac, 0x89, 0xd3, 0xda, 0xe0, 0x6d,
+ 0x95, 0x19, 0x7d, 0xcd, 0x63, 0xba, 0xa6, 0xb5, 0x52, 0x22, 0xf6, 0xb8,
+ 0xf8, 0xe7, 0xa6, 0xf9, 0xdc, 0xc1, 0x86, 0x79, 0x4d, 0xca, 0xd9, 0x1d,
+ 0x1b, 0x41, 0xdf, 0x19, 0xbc, 0xbd, 0x62, 0x6c, 0x40, 0xb1, 0x9a, 0xd2,
+ 0xfa, 0xa5, 0xf0, 0xd8, 0x06, 0xd6, 0x92, 0x3c, 0xf4, 0x06, 0xb8, 0xf7,
+ 0x08, 0xd6, 0x90, 0x5c, 0xdb, 0x9b, 0x5b, 0x70, 0x33, 0xcc, 0x85, 0xc1,
+ 0x86, 0xcd, 0x49, 0x0e, 0xbe, 0x40, 0x2e, 0x7c, 0x98, 0x31, 0x64, 0xf0,
+ 0xc1, 0x82, 0x1f, 0x6f, 0x1c, 0x61, 0x9c, 0x54, 0x56, 0xd6, 0x39, 0x77,
+ 0xee, 0x6f, 0xe3, 0x6f, 0xd7, 0x4a, 0x9c, 0xaf, 0x89, 0x3d, 0xb0, 0x6d,
+ 0x95, 0x5d, 0x1c, 0xb9, 0x16, 0x69, 0x1c, 0xef, 0xc5, 0x9e, 0xe0, 0xbd,
+ 0x38, 0xae, 0xdf, 0x90, 0x5f, 0xad, 0x06, 0xf6, 0x3c, 0x24, 0x6f, 0x3a,
+ 0xde, 0xdc, 0xbc, 0xdb, 0xcd, 0x35, 0x70, 0x0b, 0xcc, 0x65, 0x3b, 0x8e,
+ 0x5b, 0x14, 0xcf, 0xab, 0xbb, 0xf5, 0x6e, 0x4b, 0x65, 0x49, 0x0c, 0xf8,
+ 0x1a, 0xd6, 0xf0, 0x8d, 0xbb, 0x2d, 0x31, 0xf2, 0xa3, 0x6c, 0xae, 0xfd,
+ 0x57, 0xfc, 0x0f, 0x30, 0x90, 0xfa, 0x48, 0xbd, 0xbc, 0x21, 0x53, 0x8a,
+ 0xf9, 0xfb, 0xf5, 0x6b, 0xc4, 0x89, 0x80, 0xd3, 0x12, 0xd3, 0xa9, 0x8b,
+ 0x31, 0xf5, 0x09, 0x8e, 0x95, 0x9b, 0x71, 0xe1, 0x33, 0x7e, 0x0e, 0x61,
+ 0x3f, 0xdd, 0x7b, 0xd4, 0xc7, 0x86, 0x31, 0xe5, 0xcb, 0x19, 0x9b, 0x18,
+ 0xc1, 0xf9, 0x1c, 0x94, 0xd9, 0x2b, 0x8d, 0x38, 0x4c, 0x5f, 0xcf, 0xe0,
+ 0x87, 0x7e, 0xe3, 0xa1, 0xfc, 0xd7, 0x92, 0xc1, 0x15, 0xf2, 0x25, 0x07,
+ 0x58, 0xda, 0x23, 0xf9, 0xe9, 0xb0, 0x24, 0x57, 0x7e, 0xd6, 0x67, 0xf8,
+ 0x2d, 0xf5, 0x0f, 0xfb, 0x4d, 0xcf, 0xb1, 0x5d, 0xc7, 0xf9, 0x23, 0xc2,
+ 0x67, 0x1b, 0x7d, 0xc6, 0x7e, 0x3e, 0x1f, 0x5c, 0xb3, 0x9b, 0x74, 0xf4,
+ 0x5e, 0x5f, 0x47, 0x79, 0xdd, 0x32, 0xb9, 0x0e, 0xdc, 0x3b, 0xb8, 0xc2,
+ 0x39, 0x9a, 0x7e, 0x83, 0x2b, 0xc6, 0x47, 0xdf, 0xdb, 0x6f, 0x64, 0xa7,
+ 0x1f, 0xae, 0x83, 0xef, 0x9a, 0xb1, 0xa7, 0x46, 0xc1, 0xe3, 0x46, 0x58,
+ 0x83, 0x44, 0x9b, 0x3d, 0xe4, 0x4e, 0x09, 0xf5, 0x3d, 0xe1, 0xeb, 0x1c,
+ 0xf1, 0xa6, 0xcb, 0xc7, 0x9b, 0x5d, 0x1b, 0x93, 0x33, 0x35, 0x27, 0x8c,
+ 0x83, 0x34, 0xd8, 0x18, 0xe9, 0xff, 0x4f, 0x1b, 0x73, 0xc4, 0x1f, 0x27,
+ 0xb8, 0x16, 0xe0, 0x4a, 0xd0, 0x0e, 0x70, 0xa5, 0x99, 0xc7, 0x06, 0xb2,
+ 0x6f, 0x3c, 0xdf, 0xe8, 0xe7, 0x65, 0x7c, 0x7f, 0xde, 0xd2, 0xfd, 0xf3,
+ 0xca, 0x8e, 0x1f, 0x4f, 0x19, 0x27, 0xa0, 0x7a, 0x25, 0xec, 0xed, 0xf7,
+ 0xd4, 0x6f, 0x5e, 0xbc, 0x32, 0xa1, 0xb1, 0x9c, 0x9a, 0xca, 0xfa, 0xab,
+ 0x58, 0x9f, 0x33, 0xd8, 0x47, 0x0f, 0x46, 0x77, 0xeb, 0x86, 0x56, 0x9f,
+ 0xc9, 0xfa, 0xbc, 0x25, 0x23, 0x5d, 0x98, 0x5f, 0x5a, 0xeb, 0xb0, 0xda,
+ 0x9d, 0xaf, 0xc8, 0x03, 0x66, 0xee, 0x6d, 0x6d, 0x63, 0xeb, 0xcf, 0xb4,
+ 0x7d, 0x2b, 0xd0, 0x73, 0xea, 0xcf, 0xea, 0x33, 0xb3, 0x15, 0x6f, 0x3c,
+ 0x72, 0x72, 0xd8, 0x2e, 0x0a, 0x6b, 0xbd, 0xc7, 0xe5, 0x09, 0x97, 0xd7,
+ 0x7f, 0x88, 0xeb, 0xd3, 0xf4, 0x21, 0x13, 0x11, 0xfd, 0xfe, 0x20, 0x11,
+ 0x7b, 0x0c, 0x7b, 0x6f, 0x46, 0xbf, 0xf7, 0x38, 0xa4, 0x35, 0xe2, 0x35,
+ 0x21, 0x97, 0x62, 0x8d, 0xc1, 0xb3, 0xf2, 0xb8, 0x3b, 0xe4, 0xd6, 0xc5,
+ 0x70, 0xdc, 0x19, 0xcd, 0xf7, 0x1c, 0x90, 0xc7, 0xdc, 0x48, 0x5b, 0x76,
+ 0xcb, 0xe8, 0xfc, 0x44, 0x38, 0xd3, 0xbe, 0xe0, 0x44, 0xdb, 0xa6, 0xb6,
+ 0xb0, 0xa7, 0xb7, 0x80, 0xf7, 0x5b, 0xb1, 0x50, 0x6e, 0x83, 0xef, 0x1e,
+ 0x36, 0x35, 0x1d, 0xea, 0x5f, 0x11, 0x43, 0xee, 0x93, 0x6d, 0xfb, 0xb8,
+ 0x6c, 0xa7, 0xf8, 0x4d, 0xd6, 0x29, 0xb4, 0x07, 0x35, 0xe7, 0xb2, 0x0d,
+ 0xbc, 0xd9, 0x4e, 0xb5, 0xa9, 0x0e, 0xaa, 0x1f, 0x06, 0x9c, 0xda, 0xb6,
+ 0x89, 0x4f, 0x77, 0xf0, 0x88, 0x77, 0x9e, 0x83, 0x1c, 0x58, 0xef, 0x71,
+ 0x02, 0x6d, 0xe2, 0x9a, 0xdd, 0x74, 0xbe, 0x1f, 0xed, 0xbb, 0x31, 0x46,
+ 0xab, 0xbe, 0xa3, 0xe5, 0x9c, 0x34, 0x79, 0xcc, 0x3d, 0xf7, 0x74, 0x36,
+ 0xb5, 0x3f, 0x77, 0xd4, 0x7c, 0x6f, 0xf4, 0x3d, 0xca, 0xb8, 0x90, 0x91,
+ 0xbf, 0xc5, 0xf6, 0xb6, 0x97, 0xfb, 0xf6, 0xb6, 0x0f, 0x4b, 0x7b, 0x0f,
+ 0x45, 0xd1, 0xdd, 0x74, 0x5f, 0xa0, 0x43, 0x41, 0xfb, 0x28, 0x71, 0x85,
+ 0x76, 0x4b, 0x7d, 0xa6, 0xed, 0x28, 0x9f, 0xb5, 0xd8, 0xd4, 0x87, 0xff,
+ 0xd9, 0x87, 0x7d, 0x19, 0xbf, 0xfb, 0xbe, 0xd1, 0x33, 0x8b, 0xbe, 0x3f,
+ 0xe3, 0x17, 0xd4, 0xd3, 0xfd, 0xfc, 0xa9, 0x84, 0x7e, 0x1f, 0xb4, 0xbf,
+ 0xae, 0x05, 0x38, 0x12, 0xf3, 0x63, 0x0a, 0x26, 0xef, 0x64, 0xe2, 0xbe,
+ 0x94, 0x9d, 0xe6, 0x9d, 0x62, 0xd7, 0x21, 0xe7, 0x0b, 0x90, 0xf3, 0x64,
+ 0x98, 0xbe, 0x1f, 0xf3, 0x4b, 0x8e, 0xe4, 0xb6, 0x28, 0x6f, 0xda, 0x75,
+ 0xea, 0x26, 0x78, 0xc4, 0x16, 0x31, 0xc5, 0x02, 0x07, 0xca, 0x60, 0x8e,
+ 0xaf, 0xe1, 0xbc, 0xe5, 0xd7, 0x6f, 0xa4, 0x61, 0xd3, 0x5c, 0xfc, 0x28,
+ 0x77, 0xf8, 0xf4, 0x6b, 0x94, 0x31, 0xeb, 0xd9, 0x18, 0x0b, 0xe0, 0xfc,
+ 0x98, 0x63, 0x77, 0xa1, 0xd3, 0x13, 0xd0, 0xdd, 0x88, 0x38, 0xe5, 0x13,
+ 0x52, 0x98, 0x9e, 0x50, 0xfb, 0x3f, 0x08, 0xfb, 0x34, 0xef, 0x66, 0x65,
+ 0xe1, 0xe5, 0x3b, 0xb1, 0x4f, 0xe9, 0xe7, 0x6b, 0x0c, 0xc3, 0x6b, 0x51,
+ 0x9d, 0x26, 0xe7, 0x60, 0xdc, 0xcd, 0xe4, 0x92, 0xfd, 0xef, 0xaa, 0xfa,
+ 0xe5, 0x70, 0x56, 0x2a, 0x57, 0x6c, 0xad, 0x85, 0xc9, 0xc8, 0x7b, 0x1e,
+ 0x65, 0x38, 0x73, 0x3e, 0x0e, 0x9c, 0x22, 0x77, 0xff, 0x60, 0xd4, 0xac,
+ 0xe9, 0x5f, 0xfb, 0xe9, 0x03, 0x27, 0xcb, 0x8d, 0x63, 0x68, 0xfd, 0x0c,
+ 0xae, 0x3d, 0x74, 0xd4, 0xec, 0x1f, 0xfa, 0xc3, 0x37, 0xbd, 0x4c, 0x94,
+ 0xcf, 0xe4, 0xbd, 0xcc, 0xd1, 0x52, 0x57, 0x38, 0xb7, 0x77, 0x7d, 0xbd,
+ 0xfe, 0x28, 0xc6, 0x8b, 0xcb, 0xe0, 0xe6, 0x84, 0xfa, 0xf1, 0xf3, 0x7b,
+ 0x7c, 0x56, 0x13, 0x1f, 0x30, 0x7e, 0xeb, 0x1b, 0xf2, 0xd8, 0x06, 0xe5,
+ 0x44, 0xfb, 0x1e, 0x92, 0x1f, 0x39, 0xc3, 0xf6, 0x93, 0x5a, 0x77, 0x9c,
+ 0xc8, 0x30, 0x1f, 0x73, 0xd0, 0x49, 0xda, 0x6b, 0x12, 0x19, 0xfd, 0x98,
+ 0xf0, 0x9b, 0x16, 0xd6, 0x7a, 0x0c, 0xbb, 0x4f, 0x4a, 0x50, 0xef, 0x31,
+ 0x94, 0x39, 0x10, 0xfa, 0xa7, 0xf7, 0xc6, 0x79, 0xde, 0x63, 0xea, 0x3d,
+ 0x24, 0x44, 0xb9, 0xfd, 0xf1, 0x0e, 0x7e, 0xe3, 0xb9, 0x37, 0xde, 0x77,
+ 0xff, 0xd3, 0xe7, 0xd2, 0x89, 0x25, 0xfa, 0xac, 0x2d, 0xce, 0xbf, 0xfa,
+ 0xcd, 0xbb, 0x16, 0x0a, 0x9d, 0xa2, 0xf9, 0xb2, 0x4b, 0xef, 0x38, 0xac,
+ 0x7b, 0x48, 0xc4, 0x0e, 0x58, 0x8c, 0x7b, 0x13, 0xdf, 0x98, 0x43, 0x61,
+ 0x8c, 0x0d, 0x6d, 0x70, 0x86, 0x97, 0x46, 0x2c, 0xb9, 0x3f, 0x92, 0x89,
+ 0x5b, 0x72, 0x2c, 0xbe, 0x22, 0x78, 0x26, 0xf3, 0x29, 0x1b, 0x89, 0x02,
+ 0xef, 0x8f, 0x94, 0x39, 0x5e, 0x5c, 0xfd, 0x93, 0xe4, 0x31, 0xcf, 0xbb,
+ 0xe4, 0x4a, 0x28, 0x79, 0xd7, 0xdb, 0x1e, 0x73, 0xde, 0xd6, 0xe6, 0xfb,
+ 0xd5, 0x23, 0x10, 0x37, 0x16, 0x9e, 0x32, 0xb5, 0x87, 0x4b, 0x97, 0x06,
+ 0x37, 0xf4, 0x9b, 0xb9, 0x69, 0xd3, 0x2e, 0xa1, 0xdd, 0xea, 0xd7, 0x41,
+ 0x55, 0x2e, 0x0d, 0x56, 0x8f, 0xdc, 0x6e, 0xfc, 0x6d, 0xf2, 0xab, 0xc0,
+ 0x87, 0x89, 0xef, 0xa9, 0x0b, 0x3b, 0xbb, 0x7c, 0x26, 0x74, 0x66, 0xd9,
+ 0x5a, 0x6d, 0x63, 0x0e, 0xec, 0x94, 0x27, 0xdd, 0x27, 0x83, 0x38, 0x15,
+ 0xe3, 0x5a, 0x22, 0x9d, 0x9b, 0x13, 0x26, 0xe7, 0xb1, 0x69, 0x29, 0x17,
+ 0xea, 0x7a, 0x89, 0xb1, 0xaa, 0xa8, 0x62, 0x43, 0xf7, 0x26, 0xeb, 0xc1,
+ 0x7a, 0x64, 0x46, 0x31, 0xa3, 0x47, 0xf1, 0xc0, 0xe8, 0x5d, 0x97, 0xc6,
+ 0x61, 0xc9, 0x97, 0xae, 0x2d, 0xbb, 0x03, 0xac, 0xe1, 0x79, 0x75, 0xf9,
+ 0x09, 0xb4, 0x89, 0x33, 0xf7, 0x34, 0x9d, 0x6f, 0xcc, 0xc9, 0x26, 0xec,
+ 0x41, 0xab, 0x39, 0x1f, 0xcb, 0x73, 0xcd, 0x79, 0xd8, 0x57, 0x25, 0xdf,
+ 0xcb, 0xdc, 0x6b, 0x10, 0x6f, 0x77, 0xfd, 0x78, 0xfb, 0x87, 0x06, 0xa8,
+ 0x83, 0xf0, 0x6f, 0xf2, 0x91, 0xb1, 0xb6, 0x91, 0xf9, 0x52, 0xf8, 0x1f,
+ 0xbb, 0xb1, 0x53, 0xb4, 0x37, 0x76, 0xf2, 0xe3, 0xb8, 0xf6, 0x25, 0x70,
+ 0x92, 0x22, 0xf8, 0x45, 0xc1, 0xaf, 0xc3, 0xe7, 0xf5, 0x9d, 0xfe, 0xb7,
+ 0x98, 0xd3, 0x41, 0xcd, 0xad, 0x0f, 0xee, 0xc9, 0xad, 0xdf, 0x35, 0xc0,
+ 0xda, 0xe3, 0xe2, 0xd6, 0x6e, 0xdf, 0x88, 0xdf, 0x77, 0xe2, 0x96, 0xef,
+ 0x63, 0xf6, 0x4c, 0x51, 0xf7, 0xcc, 0x65, 0x8d, 0x11, 0xcf, 0x6f, 0x2d,
+ 0xc9, 0x8c, 0xd3, 0x25, 0xb9, 0xd5, 0xc0, 0x4e, 0x78, 0xe3, 0xb3, 0x6e,
+ 0xa1, 0x2f, 0x2c, 0xec, 0xcf, 0xe7, 0x29, 0x47, 0x8b, 0xe5, 0xc2, 0x1c,
+ 0xff, 0x90, 0x44, 0xc6, 0x68, 0x3b, 0x68, 0x13, 0x3e, 0x05, 0x2c, 0x03,
+ 0x4f, 0xdf, 0x6a, 0xcc, 0x7d, 0xbf, 0x9f, 0x1c, 0x29, 0xc3, 0xe0, 0x9d,
+ 0x0b, 0x5e, 0x2b, 0xf6, 0xdf, 0x31, 0xd6, 0xb4, 0xec, 0xcc, 0x95, 0x36,
+ 0x4b, 0x6d, 0x93, 0xbe, 0xc7, 0x94, 0xff, 0x1e, 0x61, 0xcc, 0x67, 0xb6,
+ 0x14, 0xdc, 0x33, 0x27, 0xc7, 0x4f, 0x25, 0x62, 0x49, 0x4b, 0xe7, 0xa5,
+ 0xf6, 0x2b, 0xeb, 0xce, 0xc1, 0x2e, 0xd1, 0x86, 0x29, 0xae, 0x81, 0xab,
+ 0x12, 0xd7, 0x68, 0x9f, 0xd4, 0xa6, 0xc5, 0x8b, 0x98, 0x67, 0x6e, 0x4b,
+ 0xf3, 0x0f, 0xb1, 0xd3, 0xe1, 0x44, 0x65, 0x46, 0xb1, 0x0e, 0x7c, 0x55,
+ 0xe7, 0x0e, 0x7b, 0x1c, 0x6a, 0xcc, 0x2d, 0xd1, 0xbf, 0x64, 0x1e, 0xa6,
+ 0x43, 0xb2, 0x15, 0x91, 0x57, 0xa0, 0xdf, 0x57, 0xd7, 0xb9, 0xe7, 0xc2,
+ 0xbd, 0xc6, 0x47, 0xac, 0xdf, 0x63, 0x49, 0xaf, 0xe6, 0x6b, 0x8b, 0x58,
+ 0x2f, 0xf0, 0xab, 0xf1, 0xf0, 0x29, 0xf8, 0x09, 0x5a, 0x27, 0xc1, 0x18,
+ 0xeb, 0x2c, 0x7c, 0xca, 0xc6, 0xb8, 0x10, 0x30, 0x62, 0x9a, 0xe7, 0x67,
+ 0xc0, 0x8b, 0x77, 0x73, 0x35, 0xc5, 0xea, 0x82, 0xc6, 0x63, 0x6b, 0xeb,
+ 0x1d, 0x6a, 0x2f, 0x6a, 0xd5, 0x3e, 0xac, 0x8b, 0x1c, 0xb7, 0xc6, 0x8a,
+ 0xfe, 0xf9, 0x16, 0xa9, 0x56, 0xd9, 0x96, 0x81, 0x56, 0xd5, 0x97, 0x20,
+ 0x1f, 0x65, 0xcb, 0x1a, 0xb8, 0x6e, 0x75, 0xc3, 0xc1, 0x2f, 0x85, 0xdf,
+ 0x08, 0x7e, 0x0f, 0x4a, 0xb6, 0x4c, 0xfe, 0xcd, 0xfc, 0x53, 0x47, 0xd3,
+ 0xf3, 0x5b, 0xf4, 0xfb, 0x11, 0xd6, 0xb4, 0x15, 0x7d, 0x3f, 0xad, 0x58,
+ 0xdd, 0x8f, 0x9b, 0x32, 0xbe, 0x9b, 0xf2, 0xb1, 0xee, 0xa7, 0x7e, 0x6d,
+ 0xed, 0xbf, 0x01, 0x17, 0x24, 0x5e, 0x9d, 0xe0, 0x70, 0x00, 0x00, 0x00 };
static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = {
- 0x0800458c, 0x0800458c, 0x08004504, 0x0800453c, 0x08004570, 0x08004594,
- 0x08004594, 0x08004594, 0x08004474, 0x00000000 };
+ 0x08004c28, 0x08004c28, 0x08004ba0, 0x08004bd8, 0x08004c0c, 0x08004c30,
+ 0x08004c30, 0x08004c30, 0x08004b10, 0x00000000 };
static struct fw_info bnx2_rxp_fw_06 = {
- /* Firmware version: 4.4.2 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x2,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
- .start_addr = 0x080031d0,
+ .start_addr = 0x080031d8,
.text_addr = 0x08000000,
- .text_len = 0x71cc,
+ .text_len = 0x70dc,
.text_index = 0x0,
.gz_text = bnx2_RXP_b06FwText,
.gz_text_len = sizeof(bnx2_RXP_b06FwText),
@@ -2966,15 +2935,15 @@ static struct fw_info bnx2_rxp_fw_06 = {
.data_index = 0x0,
.data = bnx2_RXP_b06FwData,
- .sbss_addr = 0x08007220,
- .sbss_len = 0x58,
+ .sbss_addr = 0x08007120,
+ .sbss_len = 0x54,
.sbss_index = 0x0,
- .bss_addr = 0x08007278,
- .bss_len = 0x44c,
+ .bss_addr = 0x08007178,
+ .bss_len = 0x450,
.bss_index = 0x0,
- .rodata_addr = 0x080071cc,
+ .rodata_addr = 0x080070dc,
.rodata_len = 0x24,
.rodata_index = 0x0,
.rodata = bnx2_RXP_b06FwRodata,
@@ -2997,639 +2966,571 @@ static const struct cpu_reg cpu_reg_rxp = {
};
static u8 bnx2_rv2p_proc1[] = {
- /* Date: 05/13/2008 13:50 */
- 0xa5, 0x56, 0x4f, 0x48, 0x14, 0x61, 0x14, 0x7f, 0x3b, 0xfb, 0x67, 0xd6,
- 0xdd, 0xd9, 0x9d, 0x25, 0xff, 0x6d, 0x66, 0xb8, 0x49, 0x97, 0xd5, 0x15,
- 0xb5, 0x22, 0x3a, 0x18, 0x86, 0x17, 0x21, 0x3b, 0x84, 0x20, 0x45, 0x04,
- 0xd9, 0x12, 0xde, 0x82, 0x0e, 0xd1, 0x29, 0x68, 0xd1, 0x34, 0x8a, 0x0a,
- 0x16, 0x52, 0x30, 0xa2, 0xa4, 0x43, 0x85, 0x04, 0xed, 0x74, 0x0a, 0x12,
- 0x82, 0x8a, 0x88, 0xea, 0x12, 0x78, 0xa8, 0x4b, 0x16, 0x61, 0xd0, 0xa1,
- 0x83, 0x9d, 0xba, 0xe4, 0xf4, 0xbd, 0xef, 0xbd, 0xcf, 0x9d, 0xf9, 0x9c,
- 0x55, 0x21, 0x41, 0x7f, 0xbc, 0x6f, 0xde, 0x7b, 0xdf, 0x9b, 0xdf, 0x7b,
- 0xef, 0x37, 0x66, 0x00, 0xc0, 0x80, 0x92, 0xd3, 0x26, 0x10, 0x52, 0x46,
- 0x28, 0x2e, 0x20, 0x04, 0xf0, 0x18, 0xe8, 0x27, 0x6a, 0x49, 0xbb, 0xd4,
- 0xcd, 0x76, 0x27, 0x41, 0xa9, 0x33, 0x23, 0xfe, 0x9e, 0x85, 0xfe, 0x1c,
- 0x62, 0x18, 0xfa, 0x77, 0x21, 0x1e, 0x84, 0x17, 0xb9, 0xac, 0xc0, 0xbf,
- 0x2e, 0x94, 0xd0, 0x6e, 0xa8, 0x3c, 0x73, 0x92, 0x32, 0xff, 0x12, 0xc7,
- 0x7f, 0x0a, 0x13, 0x1e, 0x28, 0xc4, 0x29, 0x0f, 0x23, 0x74, 0x65, 0x24,
- 0x2c, 0x96, 0xd1, 0x1e, 0x19, 0x81, 0x18, 0xe6, 0x99, 0x12, 0x0e, 0x68,
- 0xb7, 0x86, 0x4a, 0x5d, 0x5c, 0x97, 0x41, 0x7e, 0x5f, 0xca, 0x36, 0x9e,
- 0xc3, 0xd7, 0x01, 0xb4, 0xb7, 0x27, 0x2e, 0x97, 0x11, 0xb3, 0x30, 0x16,
- 0xb7, 0xe8, 0x7d, 0xda, 0x28, 0xed, 0x52, 0x07, 0xc6, 0x09, 0xdf, 0x0e,
- 0xce, 0x1b, 0xc5, 0xbc, 0x3f, 0x5d, 0xca, 0x8b, 0xf9, 0xbc, 0x79, 0x5a,
- 0x45, 0x1e, 0x3c, 0x8f, 0x71, 0x5d, 0x31, 0xad, 0xae, 0x98, 0xa8, 0x83,
- 0x79, 0x00, 0x55, 0x07, 0x62, 0xa3, 0xb8, 0x17, 0xf3, 0xae, 0xf0, 0x7b,
- 0x03, 0x9c, 0xca, 0x71, 0x7e, 0x07, 0xb1, 0xc2, 0xf9, 0xc4, 0x2f, 0xbf,
- 0xc7, 0xfa, 0x3c, 0x8a, 0x27, 0x7f, 0xfd, 0x66, 0x41, 0x3d, 0x57, 0xfd,
- 0xc0, 0x7b, 0x3e, 0x8a, 0x7b, 0xbc, 0xfe, 0xb0, 0x89, 0xff, 0x7b, 0xe1,
- 0xef, 0xcf, 0x4b, 0xe7, 0x6f, 0xab, 0xe7, 0xf9, 0x20, 0xde, 0xa2, 0x1a,
- 0x6f, 0x2f, 0x99, 0xb7, 0x41, 0xd8, 0x6d, 0x64, 0xa5, 0x5f, 0x04, 0x10,
- 0x77, 0x88, 0x02, 0x10, 0x77, 0x32, 0x1e, 0x63, 0xbc, 0xc9, 0x78, 0x83,
- 0xb1, 0x91, 0xb1, 0x81, 0xb1, 0x9e, 0x71, 0x1b, 0xe3, 0x3b, 0xc6, 0x0c,
- 0xa3, 0xcd, 0x98, 0x66, 0x7c, 0xc3, 0x68, 0x31, 0x26, 0xb5, 0x7c, 0x2d,
- 0x8c, 0x71, 0xc6, 0xbb, 0x8c, 0xfb, 0xb5, 0xf8, 0xdf, 0x8c, 0x0b, 0x8c,
- 0xcd, 0x21, 0xc2, 0x43, 0x6c, 0x23, 0xa1, 0x3c, 0xf7, 0x3e, 0xbe, 0xee,
- 0xaf, 0xf5, 0x77, 0xb1, 0xcc, 0xcf, 0xf3, 0xca, 0x2f, 0x2e, 0xf9, 0x83,
- 0x0e, 0xaf, 0xff, 0x9d, 0x0d, 0xfc, 0xc9, 0x6d, 0x20, 0x1f, 0x14, 0x37,
- 0xed, 0x52, 0x1d, 0xb7, 0x38, 0xbe, 0xbe, 0xb2, 0x50, 0x63, 0x8f, 0xfa,
- 0x0a, 0xfa, 0x7c, 0x05, 0xed, 0xd1, 0x4e, 0xde, 0xa3, 0xa3, 0xeb, 0xe6,
- 0x97, 0xe6, 0xd4, 0xbb, 0x87, 0x32, 0x4f, 0x8d, 0x39, 0x7f, 0x1a, 0x2a,
- 0x16, 0xb2, 0x34, 0x17, 0xa5, 0x8d, 0xee, 0xc5, 0x78, 0x9e, 0xcb, 0xbc,
- 0x9a, 0x4f, 0xff, 0x5c, 0xd2, 0x7c, 0xc5, 0xb4, 0xf9, 0xba, 0xb0, 0x09,
- 0xbf, 0x49, 0x8d, 0xa7, 0x73, 0xae, 0xea, 0x97, 0xc1, 0xc7, 0xe3, 0xb1,
- 0x8c, 0xcc, 0x7b, 0xcd, 0x91, 0x66, 0x83, 0x35, 0x85, 0x76, 0x04, 0xae,
- 0x3b, 0x2a, 0x8e, 0xf7, 0xb2, 0x43, 0xdd, 0x43, 0xf1, 0x29, 0x20, 0x9e,
- 0xe7, 0x34, 0x9e, 0x73, 0x5b, 0xd2, 0xa9, 0x15, 0xb7, 0xaa, 0x53, 0xf4,
- 0xbc, 0x0d, 0xbc, 0x3a, 0x15, 0x87, 0xd1, 0x41, 0x5b, 0xde, 0x9b, 0x8e,
- 0x51, 0x9a, 0xe3, 0x36, 0xe1, 0x99, 0x04, 0xe1, 0x72, 0xa2, 0x4e, 0xfc,
- 0x75, 0xdd, 0xb1, 0x24, 0xd9, 0xa7, 0x53, 0x6a, 0x3f, 0x54, 0xbc, 0xaa,
- 0x6b, 0xa3, 0x7a, 0xf0, 0x7e, 0x75, 0x8f, 0xaa, 0x43, 0xdd, 0xe7, 0xe7,
- 0xbf, 0xf6, 0xbd, 0x84, 0x45, 0xc3, 0xcf, 0xc3, 0xed, 0x1e, 0xc2, 0x48,
- 0xaf, 0x84, 0xec, 0x8c, 0x45, 0x71, 0xb3, 0x56, 0x04, 0xed, 0x7d, 0xb3,
- 0x1f, 0x30, 0xbf, 0xb1, 0x67, 0xc6, 0xe1, 0xfa, 0x6c, 0xd5, 0x3f, 0x79,
- 0x0e, 0xed, 0x40, 0xf6, 0x30, 0xcf, 0xc3, 0xb0, 0x9c, 0x7b, 0xb1, 0xd7,
- 0x06, 0x62, 0x0b, 0x94, 0xa4, 0xae, 0x1b, 0x89, 0xd7, 0x32, 0x3e, 0xcc,
- 0xe7, 0xa2, 0x4f, 0xed, 0xfe, 0x7d, 0x59, 0xa2, 0xfe, 0xc7, 0xfd, 0x73,
- 0xd3, 0xed, 0x06, 0xcf, 0x63, 0xa2, 0x32, 0x57, 0x0e, 0xea, 0xd7, 0x73,
- 0xd6, 0xbd, 0x2c, 0x14, 0x7b, 0x6b, 0xe9, 0xb1, 0xfa, 0x0e, 0x2a, 0x3d,
- 0x92, 0xc7, 0x95, 0x52, 0xd8, 0xc7, 0xcb, 0x21, 0x28, 0x04, 0xe5, 0x7f,
- 0xa2, 0xbe, 0x2f, 0x01, 0x7b, 0xb4, 0xd9, 0xbd, 0xbe, 0xfc, 0x69, 0x28,
- 0x04, 0xed, 0x81, 0xa9, 0xed, 0x8d, 0xcd, 0x7b, 0xd3, 0xbc, 0x6e, 0x7e,
- 0x95, 0x4e, 0xe4, 0x36, 0xd4, 0x89, 0xff, 0xd5, 0x05, 0x03, 0x48, 0x17,
- 0x50, 0x8f, 0xfd, 0xf7, 0x9b, 0xaa, 0x7e, 0x6d, 0xff, 0xa9, 0xee, 0x3f,
- 0xab, 0x5b, 0xd3, 0x11, 0xef, 0xfb, 0x07, 0xe9, 0x48, 0x42, 0xd3, 0x85,
- 0x5f, 0xab, 0x55, 0x1d, 0xc1, 0xe7, 0xf3, 0xf3, 0xd4, 0x97, 0x8b, 0xee,
- 0x9a, 0xae, 0xfb, 0xf8, 0xac, 0x63, 0x3e, 0x85, 0x9f, 0x8c, 0x5f, 0xd6,
- 0xe2, 0x55, 0x5f, 0xcf, 0x33, 0xcf, 0x46, 0x1f, 0xcd, 0x95, 0x59, 0xfc,
- 0xa1, 0xf1, 0xdd, 0x5b, 0xc0, 0xbd, 0xb8, 0x04, 0x0e, 0xf3, 0xf6, 0xd9,
- 0xc7, 0x5f, 0x8a, 0xf5, 0xc1, 0x84, 0x47, 0x8e, 0xe2, 0x59, 0xf5, 0x87,
- 0xf0, 0xa1, 0xf4, 0xcf, 0x6c, 0xc2, 0x77, 0x06, 0x1e, 0x38, 0x6a, 0xbf,
- 0x6d, 0x99, 0xaf, 0x87, 0xf5, 0x64, 0x94, 0xf7, 0xfa, 0x5b, 0x82, 0x74,
- 0xa3, 0x38, 0x24, 0xf7, 0x14, 0x9a, 0x78, 0xbf, 0x8b, 0x29, 0xb2, 0x5b,
- 0x52, 0xf4, 0x7f, 0x5b, 0x8f, 0x69, 0x49, 0xbf, 0x96, 0x14, 0x61, 0x53,
- 0x12, 0xe3, 0xb2, 0xf0, 0xfd, 0x88, 0x74, 0x2f, 0x54, 0xf7, 0x5b, 0xdf,
- 0x6b, 0x7e, 0xdf, 0xbd, 0x78, 0xde, 0x24, 0xf6, 0xd4, 0xdb, 0x0f, 0x6b,
- 0x4d, 0x5f, 0xef, 0x71, 0xf5, 0x39, 0xdb, 0xcb, 0xb7, 0x9a, 0xdb, 0x67,
- 0x35, 0xfa, 0x34, 0xe8, 0x2a, 0xdd, 0x6b, 0x1f, 0xc4, 0x7a, 0x6d, 0x48,
- 0x9b, 0x34, 0x1f, 0x84, 0x22, 0x8f, 0x61, 0x62, 0x58, 0xeb, 0x24, 0xeb,
- 0xc4, 0xe4, 0xb8, 0x4c, 0x73, 0x64, 0x52, 0x9d, 0x0f, 0xc8, 0xc1, 0x1f,
- 0x9e, 0x7f, 0x25, 0xcf, 0xd3, 0x4e, 0x98, 0xce, 0xcd, 0x21, 0xc5, 0x97,
- 0x2d, 0xdf, 0x7f, 0x86, 0xf8, 0x3a, 0x39, 0x4d, 0x78, 0x02, 0x0e, 0x4b,
- 0x4c, 0x54, 0xf5, 0x2d, 0x2e, 0x11, 0x52, 0x5e, 0x7d, 0x8b, 0x8a, 0xf2,
- 0xd0, 0xae, 0xf3, 0xf4, 0x51, 0xff, 0x6e, 0x6c, 0xb5, 0x9f, 0x5e, 0x9d,
- 0xc4, 0x7e, 0xea, 0x7a, 0x27, 0xe7, 0x46, 0x9b, 0xcf, 0x72, 0x8d, 0xf9,
- 0xcc, 0xd5, 0x98, 0x6f, 0x5d, 0x2f, 0xae, 0xf2, 0xde, 0x45, 0x20, 0x1a,
- 0x96, 0x1f, 0x24, 0x2b, 0x32, 0x21, 0xfb, 0x6b, 0x4c, 0xd2, 0x87, 0xd4,
- 0x8a, 0x4e, 0x85, 0x24, 0x6f, 0xd6, 0x14, 0xf9, 0x45, 0xe8, 0x3c, 0xab,
- 0xf0, 0xca, 0x84, 0xfa, 0xee, 0xfe, 0x03, 0x65, 0x6c, 0x9a, 0x59, 0x40,
- 0x0c, 0x00, 0x00, 0x00 };
+ /* Date: 02/03/2009 14:20 */
+ 0xa5, 0x56, 0x4f, 0x68, 0x14, 0x67, 0x14, 0x7f, 0x33, 0xbb, 0xb3, 0xb3,
+ 0x99, 0x9d, 0xd9, 0xdd, 0x92, 0x18, 0x96, 0x18, 0xcc, 0x1a, 0x84, 0x92,
+ 0x75, 0xb7, 0x6e, 0x6c, 0x0f, 0x42, 0x03, 0x29, 0xb9, 0x08, 0x35, 0x87,
+ 0x12, 0x11, 0x8a, 0x2d, 0x68, 0xb7, 0x22, 0x14, 0x0a, 0xa5, 0x07, 0x8f,
+ 0xa5, 0x83, 0x71, 0x53, 0x5a, 0xbc, 0xe4, 0xd0, 0x80, 0x42, 0x35, 0x27,
+ 0x5b, 0x62, 0x0e, 0x3b, 0xe0, 0xa1, 0x88, 0xe0, 0x41, 0x8f, 0x7a, 0xaa,
+ 0x7f, 0x5a, 0x28, 0x46, 0x29, 0xb5, 0x87, 0x82, 0xc7, 0xde, 0x9a, 0xe9,
+ 0xf7, 0xfe, 0x7c, 0xbb, 0x33, 0x5f, 0x66, 0x13, 0xa1, 0x42, 0xfc, 0xf1,
+ 0xbd, 0x79, 0xef, 0xfb, 0xde, 0x9f, 0xdf, 0x7b, 0x6f, 0xab, 0x00, 0x60,
+ 0x43, 0x18, 0x4d, 0x29, 0x04, 0x2b, 0x67, 0x15, 0x11, 0x00, 0x36, 0x81,
+ 0xff, 0x39, 0x3e, 0x9d, 0xc3, 0x23, 0x72, 0x3e, 0xcc, 0x10, 0x1e, 0xae,
+ 0xaa, 0xff, 0x3f, 0x85, 0xf9, 0x3a, 0x62, 0x0e, 0xe6, 0x0f, 0x22, 0x1e,
+ 0x85, 0xbb, 0xf5, 0x9a, 0xc2, 0x7f, 0x63, 0x08, 0xf1, 0x1c, 0xf4, 0x7e,
+ 0x8e, 0x4a, 0x74, 0xff, 0x96, 0xd8, 0xff, 0x9a, 0x63, 0x3c, 0xd6, 0xac,
+ 0x12, 0x3e, 0x5a, 0xc5, 0xf7, 0x4e, 0x9d, 0x82, 0x02, 0xda, 0x5d, 0x50,
+ 0x17, 0x23, 0x96, 0xd4, 0x83, 0x45, 0xb2, 0x03, 0xbb, 0xa2, 0x70, 0x12,
+ 0x9e, 0x2f, 0xa0, 0xfe, 0x1b, 0xde, 0xa5, 0x55, 0xc4, 0x12, 0x74, 0x9a,
+ 0xa8, 0x77, 0x00, 0xb2, 0xf5, 0x6a, 0x4a, 0x0f, 0xe5, 0x11, 0x84, 0x4d,
+ 0xc4, 0x11, 0x80, 0x56, 0xf2, 0x3d, 0xd7, 0x0a, 0x5b, 0x68, 0xff, 0x85,
+ 0xbc, 0xb7, 0x4f, 0xee, 0x51, 0x71, 0x47, 0x88, 0x3d, 0xb1, 0x53, 0x7f,
+ 0x2d, 0x96, 0xb3, 0xfe, 0x67, 0x4a, 0x4f, 0xc7, 0xe3, 0x73, 0xde, 0xa6,
+ 0x38, 0x1e, 0x57, 0xe2, 0x79, 0xb6, 0xaa, 0xf3, 0x86, 0xfa, 0xbf, 0xc7,
+ 0x69, 0x7d, 0xd8, 0x43, 0xff, 0x89, 0xd2, 0x4f, 0xdf, 0xcb, 0xf2, 0x5f,
+ 0x06, 0xf2, 0x99, 0xf4, 0xf7, 0xad, 0x06, 0xfa, 0xe7, 0x00, 0x34, 0x24,
+ 0x8f, 0xa4, 0xff, 0x30, 0xe6, 0x78, 0xe6, 0xe0, 0x90, 0x5d, 0x23, 0xbd,
+ 0x3c, 0xd4, 0x28, 0x3f, 0x1c, 0xef, 0x01, 0xc1, 0x25, 0xc1, 0x6b, 0x82,
+ 0x3f, 0x08, 0xc2, 0xff, 0xc4, 0xad, 0x21, 0xf2, 0x7d, 0x82, 0xfb, 0x0d,
+ 0xf9, 0x2d, 0xc1, 0xb7, 0x0c, 0x7b, 0xcf, 0x62, 0x7c, 0xac, 0xbf, 0xcb,
+ 0xf9, 0x5d, 0xc3, 0xfe, 0x4b, 0xe0, 0xfc, 0x58, 0x46, 0xde, 0x36, 0x85,
+ 0x87, 0x58, 0x77, 0xf9, 0x3e, 0xa3, 0xf5, 0x84, 0x37, 0x8d, 0xa4, 0xfe,
+ 0x8d, 0x5d, 0xf4, 0x59, 0x6d, 0x61, 0x26, 0xcb, 0xee, 0x7a, 0x2c, 0x79,
+ 0x14, 0x7b, 0xaf, 0x77, 0x67, 0x08, 0xef, 0xe7, 0x32, 0x79, 0x3f, 0x2e,
+ 0x71, 0xa8, 0xa6, 0x23, 0xfb, 0xdb, 0x16, 0xf3, 0xdb, 0x11, 0x5e, 0xee,
+ 0xc6, 0x63, 0xe1, 0xd5, 0x8c, 0xe6, 0x57, 0x9a, 0x57, 0xcc, 0x8f, 0x82,
+ 0xc1, 0x8f, 0x6f, 0xf7, 0xc8, 0x4b, 0xc9, 0x88, 0x6f, 0x39, 0xd6, 0xf9,
+ 0xb6, 0x45, 0x7c, 0xb1, 0x50, 0xa5, 0x7b, 0xbf, 0x8b, 0xe8, 0x38, 0xe6,
+ 0xaf, 0xe0, 0x39, 0x0f, 0x97, 0x23, 0x6d, 0x27, 0xfd, 0xd4, 0xd0, 0xef,
+ 0xb0, 0x7d, 0x20, 0x9f, 0x6d, 0x47, 0xfb, 0xc9, 0x72, 0x0f, 0xf0, 0x3c,
+ 0xda, 0x5b, 0x37, 0xf2, 0x56, 0xa7, 0xb8, 0x41, 0xe2, 0x07, 0x23, 0x7e,
+ 0x9d, 0xbf, 0x57, 0xc2, 0xf7, 0x49, 0x95, 0x0f, 0xfe, 0x3e, 0x05, 0xfa,
+ 0x7e, 0x9c, 0x0b, 0x45, 0x38, 0x7b, 0xbc, 0x42, 0xfe, 0x94, 0x0b, 0x7c,
+ 0xcd, 0x87, 0x15, 0xc6, 0x73, 0x1e, 0xe3, 0x9f, 0x9e, 0xca, 0x2d, 0xc4,
+ 0xf1, 0xf9, 0x12, 0x9f, 0x3f, 0x09, 0xf0, 0xde, 0x51, 0xf5, 0xb0, 0xb6,
+ 0xd7, 0x7e, 0xed, 0xe6, 0x0f, 0xbe, 0xaf, 0xdf, 0xd1, 0x7e, 0xe8, 0xf7,
+ 0xd2, 0x75, 0x19, 0xfe, 0x2e, 0x63, 0xc7, 0x4e, 0xe7, 0x21, 0x3f, 0xcb,
+ 0x78, 0xb5, 0x4d, 0x50, 0x5b, 0xf3, 0xd9, 0xee, 0x8a, 0x9f, 0xc7, 0xf3,
+ 0x3b, 0x57, 0x1e, 0xe0, 0xfd, 0xf6, 0xd1, 0xb5, 0x48, 0xfc, 0xab, 0xe8,
+ 0xba, 0x92, 0x1c, 0xa6, 0x81, 0xcf, 0x4b, 0xc2, 0x93, 0x25, 0xe2, 0x71,
+ 0x59, 0x7d, 0x42, 0x9c, 0x80, 0xd0, 0x26, 0x3d, 0xef, 0x3e, 0xd9, 0xe7,
+ 0x44, 0xae, 0xea, 0x37, 0x9d, 0xe6, 0xff, 0x16, 0xf3, 0xa2, 0x98, 0xe6,
+ 0xd3, 0x7c, 0x62, 0xce, 0x25, 0xf3, 0x61, 0xf5, 0x79, 0xb4, 0xb3, 0x8e,
+ 0xe9, 0x7a, 0x3d, 0x5a, 0xd5, 0xf9, 0x61, 0xbe, 0xb2, 0x9e, 0x2a, 0x56,
+ 0x8b, 0xd5, 0xc3, 0xb6, 0x24, 0x72, 0x56, 0xbe, 0xb7, 0x4c, 0xde, 0x66,
+ 0xf1, 0xbe, 0x6a, 0xf0, 0xb8, 0x21, 0xbc, 0x1f, 0xe9, 0xad, 0xbf, 0xd6,
+ 0x7e, 0xb8, 0x29, 0xbc, 0xaf, 0x0e, 0xf6, 0xc3, 0x26, 0xed, 0x27, 0x75,
+ 0x26, 0xf5, 0x5e, 0x98, 0x4b, 0xd5, 0xe9, 0x3d, 0xc8, 0xec, 0xef, 0xab,
+ 0x72, 0x4f, 0x5b, 0xfa, 0xbc, 0x90, 0xd8, 0x23, 0xa4, 0x5e, 0x06, 0xf2,
+ 0xc3, 0x35, 0xfa, 0x74, 0x2c, 0x96, 0x77, 0x54, 0xbf, 0x65, 0xc5, 0xeb,
+ 0xc2, 0x5f, 0xc2, 0x83, 0x0e, 0xf5, 0x93, 0x33, 0xf6, 0xf9, 0xed, 0x54,
+ 0x9d, 0x00, 0x0e, 0xea, 0xfd, 0x90, 0xf4, 0x2b, 0xb9, 0xdf, 0xf0, 0xbe,
+ 0x1a, 0x74, 0x66, 0x93, 0x7b, 0xee, 0x72, 0xbf, 0xdf, 0x03, 0xea, 0xa3,
+ 0xf2, 0x8e, 0xbe, 0xd4, 0xf3, 0xac, 0xde, 0x4c, 0xf6, 0xf7, 0x98, 0xcc,
+ 0x2f, 0x5b, 0xf6, 0x73, 0xc9, 0x8c, 0x53, 0xed, 0xbd, 0xec, 0x7a, 0x71,
+ 0xbc, 0xff, 0x6c, 0xbf, 0xde, 0xbc, 0xdb, 0xab, 0xee, 0x9e, 0x51, 0xf7,
+ 0xbf, 0xb7, 0x75, 0x1e, 0x6d, 0x27, 0x6b, 0xbf, 0x7f, 0xa0, 0xee, 0x15,
+ 0x7d, 0x99, 0x1b, 0x67, 0xea, 0x59, 0x7c, 0x2d, 0xee, 0xd0, 0x4b, 0xcf,
+ 0x2f, 0xed, 0xe7, 0xc6, 0x06, 0xd7, 0xfd, 0xa3, 0xb8, 0xbf, 0x97, 0x52,
+ 0xf3, 0x75, 0x44, 0xea, 0xac, 0xf4, 0xc8, 0xbf, 0xa7, 0xdb, 0x83, 0x79,
+ 0x9c, 0xe4, 0xcd, 0x49, 0xe1, 0xab, 0x3d, 0xb7, 0x4e, 0xfd, 0xe1, 0x76,
+ 0x5e, 0x1a, 0x75, 0x98, 0x6d, 0x62, 0xfd, 0xbf, 0x86, 0x48, 0xfc, 0xfc,
+ 0x2d, 0xe5, 0x6f, 0x20, 0xfd, 0x55, 0x80, 0x9f, 0x22, 0x1d, 0x97, 0xae,
+ 0x1b, 0xe3, 0x8f, 0x4d, 0xe9, 0x93, 0x7e, 0x7c, 0xf8, 0xee, 0xa2, 0xbc,
+ 0x5b, 0x85, 0x1b, 0x91, 0x9e, 0x63, 0x38, 0xd7, 0x5c, 0x68, 0xcb, 0xdc,
+ 0x3c, 0x2b, 0xf3, 0xeb, 0x85, 0xc7, 0xf3, 0xb1, 0x73, 0x82, 0x78, 0x08,
+ 0xe3, 0x32, 0xc7, 0x3a, 0x01, 0x9f, 0x27, 0x02, 0xfe, 0x7d, 0xd8, 0x76,
+ 0x7d, 0xd2, 0x9b, 0x08, 0x18, 0xc7, 0x4b, 0x68, 0x57, 0x83, 0x3f, 0x16,
+ 0x49, 0xbd, 0x39, 0x98, 0x63, 0xe6, 0xfc, 0x92, 0x38, 0xdf, 0x46, 0xb9,
+ 0xda, 0x93, 0xd3, 0x7c, 0xe6, 0x3a, 0xfb, 0x7d, 0x5e, 0x5f, 0x97, 0xaa,
+ 0xd4, 0x2b, 0xc9, 0x3c, 0xeb, 0x3e, 0xba, 0x69, 0xe4, 0x57, 0xd7, 0xe7,
+ 0xcd, 0x58, 0xcf, 0xf7, 0xe9, 0xe3, 0xe8, 0x6f, 0x05, 0xca, 0x2e, 0xf3,
+ 0x82, 0x51, 0xdd, 0x63, 0xbb, 0x68, 0x36, 0xd9, 0x95, 0x79, 0xd8, 0xbd,
+ 0x48, 0xd7, 0x2c, 0x76, 0xb5, 0x7c, 0x81, 0x1a, 0x61, 0x69, 0xe3, 0x1e,
+ 0xc9, 0xcb, 0x51, 0x8e, 0xe5, 0xee, 0x09, 0x9d, 0xaf, 0x0a, 0xc5, 0xbf,
+ 0xc6, 0xf9, 0xfa, 0xf8, 0x7b, 0xc6, 0xd3, 0xf0, 0x3e, 0xa1, 0x37, 0x98,
+ 0xe3, 0x45, 0x42, 0x08, 0x92, 0x73, 0xdc, 0x51, 0xee, 0x55, 0xc9, 0x9f,
+ 0x41, 0xfd, 0xcc, 0xfd, 0xb8, 0x5b, 0x1d, 0x47, 0x13, 0xfc, 0xd3, 0x75,
+ 0x34, 0xe7, 0x39, 0xf1, 0xc4, 0xe0, 0x63, 0x77, 0x08, 0x1f, 0xad, 0x21,
+ 0x7c, 0x36, 0xe7, 0xd6, 0x57, 0xd2, 0xc7, 0x79, 0x70, 0x72, 0xb4, 0x70,
+ 0xfd, 0xfc, 0x32, 0xd5, 0xd5, 0xee, 0xf2, 0x0f, 0x08, 0xdf, 0x59, 0xb1,
+ 0x28, 0x5f, 0xfe, 0x0a, 0xeb, 0xe5, 0x59, 0x5e, 0xd3, 0xf8, 0xcd, 0xb2,
+ 0xfe, 0xbd, 0xf1, 0x1f, 0xb6, 0x34, 0x9b, 0xb9, 0xa0, 0x0c, 0x00, 0x00,
+ 0x00 };
static u8 bnx2_rv2p_proc2[] = {
- /* Date: 05/13/2008 13:50 */
- 0xad, 0x58, 0x4d, 0x6c, 0x54, 0x55, 0x14, 0xbe, 0x7d, 0xf3, 0xdb, 0x99,
- 0x37, 0x3f, 0xb4, 0xb5, 0xbf, 0x68, 0xa1, 0x95, 0xd2, 0x92, 0x29, 0x94,
- 0x69, 0x01, 0x95, 0x44, 0x49, 0x31, 0x05, 0x94, 0x84, 0x52, 0x5d, 0x10,
- 0x37, 0xd0, 0x22, 0xa5, 0x83, 0x2d, 0x69, 0x28, 0x61, 0xc1, 0xc6, 0x09,
- 0xc5, 0xe2, 0x62, 0x12, 0x2d, 0xb1, 0x14, 0x8c, 0xc1, 0x46, 0x37, 0xc4,
- 0xb8, 0x19, 0x83, 0x52, 0xd4, 0xc4, 0x84, 0x60, 0x43, 0x70, 0x01, 0x26,
- 0x9a, 0xe0, 0x42, 0x13, 0xa2, 0x50, 0x0b, 0x36, 0x58, 0x7e, 0x46, 0x17,
- 0xca, 0x78, 0xef, 0xf9, 0xce, 0x7d, 0x7d, 0x6f, 0x3a, 0xb5, 0x2c, 0xe8,
- 0xe6, 0xeb, 0xbd, 0xef, 0xdc, 0x73, 0xcf, 0xcf, 0x77, 0xcf, 0x39, 0x6d,
- 0x54, 0x08, 0xe1, 0x16, 0xc9, 0x74, 0xb5, 0x44, 0x11, 0x32, 0x0a, 0xfc,
- 0x12, 0xb2, 0x42, 0x78, 0xca, 0xd5, 0x5a, 0x18, 0x82, 0x7f, 0x56, 0x44,
- 0x09, 0x7e, 0x48, 0xab, 0xef, 0x3e, 0xf1, 0xaa, 0x81, 0xef, 0x6e, 0xa1,
- 0x30, 0x22, 0x44, 0x52, 0x61, 0x94, 0x71, 0x3d, 0x63, 0x86, 0x31, 0x58,
- 0x00, 0x6c, 0x66, 0x7c, 0xc0, 0xfb, 0x77, 0x78, 0x7d, 0x93, 0xf1, 0x6f,
- 0xde, 0x37, 0x19, 0x6f, 0xf3, 0xfe, 0xf3, 0x06, 0x30, 0xc1, 0xfb, 0x3f,
- 0x4b, 0xd4, 0x76, 0xa9, 0xf5, 0x74, 0x56, 0x24, 0xe5, 0x19, 0x21, 0xc5,
- 0x1b, 0xf4, 0xbe, 0x49, 0x90, 0x6c, 0x80, 0xdd, 0xaf, 0x2c, 0x51, 0x72,
- 0xbf, 0xe7, 0x91, 0x53, 0xfb, 0x37, 0xb2, 0xd0, 0x3b, 0xeb, 0xaf, 0xe1,
- 0x51, 0xe7, 0x96, 0xb6, 0x9c, 0x18, 0xc6, 0xf9, 0x9d, 0x4b, 0xb0, 0xff,
- 0x54, 0x4c, 0xf9, 0xef, 0x15, 0x49, 0x46, 0xd1, 0xa8, 0xd0, 0x28, 0x48,
- 0x36, 0xea, 0x40, 0x41, 0xfe, 0x97, 0x61, 0xac, 0x3a, 0x43, 0xd0, 0x1b,
- 0x70, 0xe8, 0x2d, 0x9d, 0xa3, 0xf7, 0x5a, 0xa1, 0x5d, 0xff, 0x67, 0xac,
- 0x3f, 0xb0, 0xa0, 0xfe, 0xae, 0x10, 0xb0, 0x38, 0x96, 0xef, 0x9e, 0xc2,
- 0x05, 0xec, 0xdf, 0xb7, 0xa0, 0xfe, 0xc3, 0x96, 0xfd, 0x3a, 0x6e, 0xfa,
- 0x3b, 0xb0, 0x1a, 0x62, 0x9f, 0x24, 0x57, 0xe9, 0x78, 0x6a, 0xbf, 0xd9,
- 0x3e, 0x17, 0x70, 0x43, 0x8c, 0x20, 0xb5, 0x9b, 0x03, 0xdc, 0x56, 0xa7,
- 0xee, 0x2d, 0x12, 0x6e, 0x43, 0xe9, 0x59, 0xee, 0xf7, 0x9e, 0xc7, 0xfe,
- 0x8e, 0x08, 0xf0, 0x75, 0x76, 0xe4, 0x46, 0x40, 0x05, 0x26, 0x9b, 0xed,
- 0x0e, 0xb2, 0x7e, 0xa4, 0x55, 0x24, 0x83, 0x38, 0x3f, 0x61, 0x2a, 0xfb,
- 0x2e, 0xcb, 0xfc, 0xa9, 0xb5, 0x4b, 0x24, 0x23, 0x4e, 0x3f, 0x3e, 0x14,
- 0x90, 0x5b, 0xb4, 0x1c, 0xbb, 0xef, 0x76, 0x63, 0x5d, 0xf5, 0x71, 0x94,
- 0xe4, 0x4f, 0xa6, 0xb5, 0x1f, 0x6a, 0x5f, 0xbe, 0x83, 0x08, 0xf4, 0x88,
- 0x1a, 0x3f, 0x5d, 0x86, 0x38, 0xc9, 0x4b, 0x1b, 0xb5, 0x3e, 0xfc, 0x9c,
- 0x58, 0xa6, 0xf9, 0x85, 0x75, 0xb7, 0x97, 0xa0, 0xbc, 0x73, 0x48, 0xd9,
- 0x1b, 0x11, 0xbb, 0x0c, 0x65, 0x88, 0xc1, 0xfe, 0xb9, 0xfc, 0xe6, 0x17,
- 0x90, 0xff, 0xa6, 0xda, 0x24, 0xdb, 0xba, 0x9b, 0x71, 0xae, 0x24, 0x0e,
- 0x1c, 0x89, 0x7b, 0x14, 0xc4, 0xba, 0x07, 0x68, 0xb9, 0xf2, 0xd7, 0xd5,
- 0x7e, 0x92, 0x4b, 0x36, 0x6a, 0xfe, 0xea, 0xb8, 0x2b, 0x7f, 0xdf, 0xc9,
- 0x5a, 0xfc, 0xaf, 0x45, 0x7c, 0x6e, 0x2e, 0x53, 0xf2, 0x32, 0x48, 0x35,
- 0xb8, 0xa7, 0x23, 0x91, 0x8f, 0xff, 0x6f, 0xdb, 0xf8, 0xff, 0x68, 0x79,
- 0xdc, 0x40, 0xfe, 0x6f, 0xe0, 0x38, 0x2c, 0x61, 0xbe, 0x2c, 0xce, 0xc3,
- 0x97, 0x08, 0xfd, 0x7e, 0xab, 0x35, 0x4a, 0x71, 0xdc, 0x86, 0xfd, 0xe3,
- 0x6d, 0xe7, 0x10, 0xef, 0x2d, 0x14, 0x07, 0x11, 0x38, 0xfa, 0x39, 0x4e,
- 0x75, 0x86, 0xd4, 0xfa, 0xb5, 0x96, 0xee, 0x2f, 0xb1, 0xee, 0x72, 0xa9,
- 0xf5, 0x0e, 0x73, 0xf7, 0x38, 0xe4, 0x3d, 0x83, 0x51, 0x8a, 0xdf, 0x36,
- 0xbe, 0x65, 0x8b, 0xab, 0x40, 0x41, 0xca, 0x3b, 0x48, 0x4b, 0x73, 0x82,
- 0xbe, 0x47, 0xc5, 0xb1, 0x34, 0xbe, 0xef, 0x0f, 0x52, 0x7d, 0x90, 0xfe,
- 0x91, 0x5c, 0x49, 0xc2, 0x8b, 0xf3, 0xa9, 0x61, 0x3f, 0xf9, 0x3b, 0x75,
- 0x56, 0xad, 0xb7, 0xc6, 0xa6, 0x20, 0x1f, 0x4b, 0x0c, 0xb1, 0x62, 0x03,
- 0xf1, 0xbb, 0x65, 0x40, 0x9e, 0xe9, 0x15, 0x70, 0x53, 0xfe, 0x0a, 0x84,
- 0xd9, 0x06, 0x7c, 0x8b, 0xbe, 0xff, 0x53, 0x90, 0xa2, 0x78, 0x6d, 0x0c,
- 0xbb, 0xcf, 0xe9, 0xf8, 0x30, 0x46, 0xb4, 0x5f, 0xc0, 0x47, 0xe5, 0xef,
- 0x90, 0xa9, 0x79, 0xcb, 0x79, 0x6b, 0x98, 0x8f, 0xb7, 0xc0, 0xb6, 0x3a,
- 0xa0, 0xb7, 0x56, 0xc9, 0x79, 0xf2, 0xf0, 0xd7, 0x99, 0x17, 0xce, 0xab,
- 0x8d, 0x67, 0x04, 0x92, 0x5f, 0x0e, 0xbe, 0x49, 0x3e, 0x53, 0x5d, 0x92,
- 0xf1, 0xd4, 0xbc, 0x51, 0x8a, 0x7c, 0xe2, 0x0d, 0xd6, 0x97, 0x60, 0xbf,
- 0x7a, 0xd9, 0xaf, 0xe9, 0x80, 0x8e, 0xbb, 0xf6, 0x07, 0x78, 0xcc, 0x04,
- 0xbf, 0x3a, 0x12, 0xda, 0x2f, 0x27, 0x7f, 0xd9, 0x9e, 0xd4, 0xb7, 0x35,
- 0xf8, 0xa5, 0xaa, 0x16, 0x68, 0xf9, 0x59, 0x47, 0xef, 0x25, 0x5c, 0x36,
- 0xae, 0xed, 0x50, 0x79, 0xfd, 0x4b, 0xe6, 0x15, 0xf9, 0x39, 0x99, 0xb6,
- 0xbf, 0xd3, 0xca, 0x3c, 0xef, 0xd4, 0xf9, 0x6e, 0xb4, 0xff, 0xfb, 0x43,
- 0x54, 0x88, 0x5a, 0xae, 0x4c, 0x3a, 0xdf, 0x05, 0xf8, 0xef, 0xb3, 0x78,
- 0x54, 0xb2, 0x96, 0xe3, 0xc4, 0x58, 0xba, 0x4e, 0xe9, 0x6b, 0x67, 0xfd,
- 0x4d, 0xac, 0xdf, 0xb4, 0xbd, 0x4b, 0x65, 0xdf, 0x93, 0xd6, 0x7b, 0xd4,
- 0xf9, 0x99, 0x7d, 0x97, 0x3a, 0x4e, 0x74, 0x7f, 0xec, 0xca, 0xa4, 0x3a,
- 0x5f, 0xb5, 0xc0, 0x3b, 0x2d, 0xb6, 0xf4, 0xfd, 0x68, 0xbd, 0x47, 0xf5,
- 0x3d, 0x28, 0x5e, 0xe0, 0xa5, 0xb3, 0xde, 0xfc, 0x29, 0xeb, 0x0d, 0xf9,
- 0xe1, 0x37, 0xcf, 0x71, 0x7d, 0x19, 0x50, 0xf7, 0x94, 0xb3, 0xdd, 0xe5,
- 0xba, 0xce, 0x4b, 0xbb, 0xb9, 0x0e, 0xed, 0xb4, 0xd7, 0x13, 0x8f, 0xad,
- 0x2e, 0xa8, 0xb5, 0x2b, 0x4f, 0x9f, 0x74, 0xc4, 0x33, 0x29, 0x22, 0x98,
- 0x03, 0x92, 0x11, 0x25, 0x7f, 0x4f, 0xcc, 0xad, 0x2b, 0xb9, 0xf6, 0x23,
- 0x1e, 0x9d, 0x46, 0x88, 0xe4, 0xae, 0xf7, 0xab, 0x73, 0xd7, 0xac, 0x3e,
- 0x8e, 0x3a, 0x73, 0x91, 0xed, 0x5d, 0xcc, 0xf6, 0x4a, 0x7d, 0x8d, 0xc4,
- 0x53, 0xff, 0xf5, 0x7e, 0xbb, 0xbd, 0x77, 0x1e, 0xce, 0x7f, 0x9f, 0x33,
- 0xef, 0xfd, 0xdc, 0x6f, 0xb8, 0x4f, 0xfa, 0x77, 0x7f, 0xa5, 0xed, 0xe1,
- 0x7b, 0x23, 0xfa, 0x7e, 0x93, 0xf2, 0x32, 0x39, 0xa0, 0xce, 0x87, 0x05,
- 0xd3, 0x44, 0xf4, 0xd5, 0xa3, 0xae, 0x4d, 0xef, 0x81, 0xfd, 0x7d, 0x75,
- 0xea, 0xfe, 0x16, 0x81, 0x7e, 0xe3, 0x96, 0x21, 0x45, 0x7d, 0xbf, 0x38,
- 0x9c, 0x2f, 0x8f, 0x5f, 0xb3, 0xdc, 0x38, 0xfb, 0x15, 0x65, 0xbf, 0x36,
- 0x4b, 0xbf, 0x28, 0xee, 0xfc, 0x3d, 0x9f, 0xdf, 0x6c, 0xa7, 0xd0, 0xfd,
- 0x9b, 0xcf, 0x91, 0x5c, 0x0f, 0xcb, 0xb9, 0xe7, 0xed, 0xdb, 0x99, 0xe5,
- 0x54, 0x87, 0x4f, 0x1f, 0xa6, 0x7a, 0x1a, 0xb2, 0xf8, 0xe6, 0xb4, 0x6f,
- 0xe2, 0x31, 0xc4, 0x51, 0xc9, 0x2d, 0x12, 0x7b, 0xc3, 0xf3, 0xc5, 0xcb,
- 0xad, 0xb6, 0xc7, 0x66, 0xc6, 0x75, 0xbc, 0x4d, 0xf2, 0x73, 0x72, 0x80,
- 0xe6, 0xc2, 0x9c, 0x38, 0x1a, 0xb6, 0x38, 0x42, 0x1e, 0xf3, 0x4a, 0xbe,
- 0xf8, 0xe5, 0xeb, 0x8b, 0x9f, 0x3e, 0xd4, 0x7c, 0x3a, 0xe2, 0xd5, 0xf6,
- 0x2b, 0x5c, 0x65, 0xe5, 0xf3, 0x00, 0xcf, 0x23, 0x19, 0x93, 0x7e, 0x89,
- 0x4f, 0xa7, 0x68, 0x69, 0x56, 0x9c, 0x51, 0x72, 0x2b, 0xe2, 0x07, 0xd8,
- 0xce, 0xcb, 0x2e, 0xf8, 0xd1, 0xb3, 0x07, 0xeb, 0x2b, 0x5c, 0xdf, 0xee,
- 0x72, 0x9d, 0xda, 0xee, 0x07, 0x4e, 0xd7, 0x93, 0x7f, 0xf1, 0x03, 0xe7,
- 0xb5, 0x7e, 0xd2, 0x6b, 0x66, 0x38, 0x3e, 0x2f, 0xba, 0xd8, 0xee, 0x1a,
- 0xca, 0x47, 0xfc, 0x0e, 0xbd, 0x4f, 0xb7, 0x68, 0x5d, 0xaa, 0xb0, 0x42,
- 0xc6, 0x81, 0xed, 0x59, 0x0f, 0xec, 0xf0, 0x71, 0x5c, 0x1b, 0x72, 0xf3,
- 0x85, 0x6d, 0x6f, 0x0d, 0x9f, 0xef, 0xc4, 0xda, 0xc7, 0xf5, 0x65, 0x94,
- 0xed, 0x7a, 0xaf, 0x1e, 0x18, 0x6e, 0x40, 0x7f, 0x9c, 0x34, 0x15, 0x46,
- 0xe2, 0x03, 0xe3, 0xf0, 0xa7, 0x77, 0x23, 0xfc, 0xbd, 0xc7, 0x71, 0x60,
- 0x0c, 0x9f, 0x1a, 0xa4, 0xbe, 0x19, 0x1e, 0x42, 0x7f, 0x0d, 0x7b, 0x07,
- 0xe1, 0x47, 0x6f, 0x06, 0xeb, 0x7b, 0xcf, 0x02, 0x1f, 0x3c, 0x87, 0x73,
- 0x07, 0x0f, 0x73, 0x7c, 0x36, 0xe6, 0x3f, 0xd7, 0x73, 0x1f, 0x72, 0x7d,
- 0xf5, 0xd4, 0xe7, 0xc7, 0xb8, 0xef, 0x8a, 0x04, 0xf7, 0xf9, 0x0c, 0xaf,
- 0xf7, 0x71, 0x1f, 0xb9, 0xcd, 0x7d, 0xb2, 0x37, 0xa7, 0x4f, 0x4e, 0xa1,
- 0x6e, 0x8e, 0x65, 0x52, 0x6a, 0x43, 0xd6, 0xaf, 0x42, 0xdd, 0x1f, 0x15,
- 0x06, 0xe2, 0x65, 0x9c, 0xaf, 0x92, 0x35, 0xc0, 0x91, 0x35, 0xe8, 0x6b,
- 0xbd, 0x87, 0x38, 0x2e, 0x2d, 0x94, 0x9f, 0x95, 0x33, 0xe3, 0x9a, 0x0f,
- 0x34, 0x3f, 0x3d, 0xd4, 0xbc, 0x43, 0xfd, 0xca, 0x58, 0xf5, 0x76, 0x8a,
- 0xec, 0xab, 0x1a, 0xcb, 0x90, 0x7c, 0xa5, 0x28, 0x26, 0x7e, 0x55, 0x84,
- 0x67, 0x60, 0x6f, 0x7c, 0x94, 0xfd, 0xec, 0x7f, 0x06, 0x78, 0x88, 0xf3,
- 0xac, 0xf3, 0x77, 0x75, 0x9d, 0x49, 0xe7, 0x26, 0x07, 0x60, 0xb7, 0xe6,
- 0x7d, 0xee, 0x9c, 0xa7, 0xf3, 0x5e, 0xd1, 0x4c, 0x6b, 0xd1, 0x73, 0x50,
- 0xdd, 0x13, 0x92, 0xf9, 0x52, 0x76, 0xc9, 0x58, 0x70, 0x7f, 0x74, 0xf2,
- 0x41, 0xf1, 0x45, 0xf3, 0xd2, 0xce, 0x23, 0x3b, 0x4f, 0x9c, 0xfc, 0x08,
- 0x53, 0x3d, 0x97, 0x8f, 0x97, 0xfa, 0xa7, 0x37, 0x3e, 0x3a, 0xfc, 0xff,
- 0xf1, 0x3a, 0x85, 0x78, 0xc5, 0xd9, 0x6e, 0x33, 0x41, 0x73, 0xd6, 0x13,
- 0x62, 0x88, 0xf3, 0x35, 0x55, 0xcf, 0xef, 0xb5, 0x06, 0xf9, 0xea, 0x7f,
- 0x1a, 0xf6, 0xf4, 0xf3, 0x3b, 0xf9, 0x83, 0xfb, 0x39, 0xf2, 0xec, 0x33,
- 0xbb, 0xc7, 0x39, 0xaf, 0xcc, 0xb7, 0x7d, 0x1c, 0x87, 0xdb, 0x88, 0x83,
- 0xa9, 0xe3, 0x90, 0xb0, 0xe2, 0xa0, 0xeb, 0x83, 0x5d, 0x4f, 0x91, 0xe4,
- 0x0b, 0xd5, 0x19, 0xf3, 0x2a, 0xcd, 0x27, 0x1e, 0xf6, 0x5b, 0xca, 0x35,
- 0x2b, 0xff, 0xc2, 0xec, 0x5f, 0x48, 0xec, 0x5d, 0x69, 0x3f, 0x17, 0xe4,
- 0x73, 0x01, 0x79, 0x0e, 0xfb, 0x78, 0x8f, 0xe6, 0x3c, 0xf1, 0x55, 0x71,
- 0xd4, 0x7a, 0x73, 0xdf, 0x9d, 0x3d, 0x9e, 0x54, 0x51, 0xe9, 0x07, 0x75,
- 0x46, 0xe6, 0x8d, 0xea, 0x91, 0x69, 0xd5, 0x99, 0xbb, 0x54, 0x7f, 0x03,
- 0xa7, 0xfb, 0x50, 0x17, 0x4e, 0xf7, 0x9d, 0xe1, 0xfe, 0xc7, 0x71, 0x69,
- 0xa7, 0xb9, 0x58, 0xc6, 0xae, 0xc6, 0x59, 0x67, 0x9c, 0x76, 0x54, 0xd9,
- 0xec, 0xd0, 0xf7, 0xce, 0xd7, 0x97, 0x31, 0xaf, 0x6d, 0xa2, 0xbe, 0xec,
- 0xb7, 0xe6, 0x49, 0x67, 0xbd, 0xf7, 0x3f, 0x72, 0xbd, 0xdf, 0xde, 0x6c,
- 0xd7, 0x5f, 0x2b, 0x26, 0xd2, 0xd0, 0xdf, 0xce, 0xfd, 0x72, 0x17, 0xbf,
- 0xdb, 0xeb, 0x81, 0x08, 0xdd, 0xd7, 0xf5, 0x32, 0xf9, 0x27, 0x4a, 0x83,
- 0xf0, 0xa7, 0x6b, 0x2b, 0xbe, 0x77, 0x85, 0xb0, 0x5f, 0x19, 0xc2, 0xdf,
- 0x5b, 0xed, 0x3e, 0x93, 0xe4, 0x2b, 0x43, 0xc0, 0x52, 0x7e, 0xef, 0x13,
- 0xd6, 0x5c, 0x0c, 0x3c, 0xe9, 0xb5, 0xcf, 0x8f, 0x6e, 0x71, 0xc1, 0x8b,
- 0xf7, 0x2f, 0x1a, 0x30, 0x07, 0xb6, 0xd6, 0x99, 0xf4, 0xbd, 0xa3, 0x01,
- 0xfd, 0x12, 0xf5, 0x75, 0xf6, 0xef, 0x33, 0x9e, 0x2b, 0x2b, 0x67, 0xe7,
- 0x67, 0xfb, 0x7c, 0x5d, 0x18, 0x1f, 0xb5, 0xe6, 0x5c, 0x7d, 0x9f, 0xfd,
- 0xfd, 0x28, 0xbd, 0xb4, 0x94, 0x73, 0xaa, 0x7d, 0xbe, 0x76, 0xe9, 0x79,
- 0x87, 0xe7, 0xd1, 0x62, 0x71, 0x29, 0x0d, 0xbf, 0x26, 0xd2, 0xf9, 0xde,
- 0xa1, 0xba, 0x4f, 0xeb, 0x83, 0xdd, 0xda, 0x8f, 0x59, 0xfd, 0xb8, 0x7f,
- 0x0f, 0xdb, 0xf9, 0x1b, 0xfd, 0x5d, 0x5c, 0xca, 0xfe, 0x28, 0xbd, 0xd8,
- 0xdf, 0xcc, 0xf3, 0x7e, 0xd2, 0x5a, 0x3b, 0xe7, 0xf4, 0x76, 0xb2, 0xab,
- 0x88, 0xfb, 0x69, 0xa9, 0xad, 0xdf, 0x43, 0xbe, 0xa4, 0x09, 0x38, 0xd2,
- 0xa4, 0xf3, 0xa0, 0xf3, 0xa5, 0xf3, 0x83, 0x3c, 0x96, 0xae, 0x26, 0xb1,
- 0x96, 0xae, 0xd5, 0xf4, 0x60, 0x9b, 0xba, 0x66, 0x9c, 0xff, 0x3f, 0xd8,
- 0x1e, 0x53, 0xf2, 0x6f, 0x8a, 0xef, 0x63, 0x68, 0x80, 0x3f, 0x31, 0xce,
- 0xce, 0xc5, 0x9c, 0x00, 0x6b, 0x1e, 0xc1, 0x7d, 0x17, 0x3c, 0xbc, 0xdd,
- 0xac, 0xe7, 0x46, 0x67, 0xff, 0xfe, 0x90, 0xea, 0xf2, 0xd9, 0x7f, 0x73,
- 0xe7, 0xce, 0xd9, 0xf9, 0x51, 0xfb, 0xa9, 0xe4, 0x1b, 0x99, 0x8f, 0x7e,
- 0xd1, 0xba, 0x09, 0x7f, 0x6f, 0x87, 0x7d, 0xe0, 0x7d, 0xd8, 0x67, 0xcf,
- 0x97, 0xe4, 0x45, 0x21, 0x3d, 0xf0, 0xc5, 0x45, 0x85, 0xe4, 0xcf, 0xf1,
- 0xcb, 0xdf, 0xd1, 0xe7, 0x8f, 0x46, 0x83, 0xd8, 0x2f, 0x6b, 0x85, 0x7a,
- 0x37, 0xf1, 0xd6, 0x25, 0x8e, 0x82, 0xd7, 0x1f, 0x8c, 0x00, 0xdf, 0x17,
- 0x2f, 0x41, 0x4f, 0xd1, 0x11, 0xea, 0x73, 0xfe, 0x32, 0x84, 0x35, 0x35,
- 0xca, 0x7c, 0x2d, 0x37, 0xe8, 0xff, 0x65, 0x59, 0x11, 0xe2, 0xff, 0xab,
- 0xf0, 0xbb, 0x03, 0x4f, 0xdd, 0xb6, 0x7c, 0x2f, 0xc4, 0x5b, 0xaa, 0x1f,
- 0x92, 0x97, 0x38, 0xce, 0xfc, 0xf5, 0xe7, 0xf2, 0x57, 0xc7, 0xa5, 0xdc,
- 0xc8, 0xcb, 0xd7, 0xb5, 0x4e, 0xbe, 0x7a, 0x99, 0xaf, 0xf7, 0xad, 0xfe,
- 0x36, 0x57, 0x2f, 0xfe, 0xae, 0xb8, 0xf4, 0xd8, 0xf8, 0x0b, 0xdc, 0x5c,
- 0xab, 0xee, 0x2f, 0x9b, 0x33, 0x77, 0x56, 0x0b, 0x7b, 0x3d, 0x3a, 0x24,
- 0xf3, 0xfd, 0x1f, 0xfe, 0xac, 0x5e, 0x92, 0x80, 0x14, 0x00, 0x00, 0x00 };
+ /* Date: 02/03/2009 14:20 */
+ 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0x3e, 0xf3, 0xe6, 0xef, 0xcd,
+ 0xcc, 0x9b, 0xcc, 0x34, 0x8d, 0x93, 0x31, 0x29, 0x26, 0x4d, 0x68, 0xea,
+ 0xc8, 0x44, 0xf3, 0x47, 0x05, 0x5d, 0x18, 0x46, 0x48, 0x7f, 0x2c, 0x34,
+ 0x8d, 0x2e, 0x8a, 0x9b, 0x36, 0x53, 0x3b, 0x3a, 0x6d, 0xed, 0xc2, 0xec,
+ 0xdc, 0xf8, 0xb0, 0x35, 0x41, 0x98, 0x45, 0x53, 0x4c, 0x13, 0x44, 0xa8,
+ 0xe8, 0xce, 0xdd, 0x88, 0x9a, 0xd6, 0x8d, 0x50, 0x68, 0x28, 0x76, 0x51,
+ 0x04, 0x05, 0xed, 0x42, 0x10, 0xad, 0xa1, 0x15, 0x41, 0x51, 0xb3, 0x92,
+ 0x8c, 0xf7, 0x9e, 0xef, 0xdc, 0x37, 0xef, 0x4d, 0xa6, 0xa4, 0x0b, 0x67,
+ 0xf3, 0xe5, 0xdc, 0x77, 0xee, 0xb9, 0xe7, 0xe7, 0x3b, 0xe7, 0xde, 0x64,
+ 0x89, 0x28, 0x42, 0x6e, 0xbd, 0x4f, 0x21, 0x85, 0xc2, 0x21, 0x5b, 0x41,
+ 0x83, 0x28, 0x9a, 0xd7, 0x32, 0x59, 0x24, 0xbf, 0x27, 0xb2, 0x0c, 0xdf,
+ 0xd6, 0x1d, 0xad, 0x46, 0x6e, 0x41, 0xeb, 0xd9, 0xf4, 0x92, 0x05, 0xbd,
+ 0x08, 0x69, 0x54, 0x3a, 0xae, 0xc6, 0x1d, 0x82, 0xcf, 0x08, 0x46, 0x42,
+ 0xc0, 0xb0, 0xa0, 0xd5, 0x82, 0x24, 0x7a, 0x5d, 0x22, 0x6f, 0x8a, 0xec,
+ 0x08, 0xe6, 0x65, 0xfd, 0xb4, 0xe0, 0xab, 0xb2, 0x7e, 0x47, 0x70, 0x5d,
+ 0xa1, 0xf1, 0x53, 0xcb, 0xbf, 0x35, 0x9a, 0xb2, 0x03, 0xf3, 0x05, 0xf8,
+ 0xff, 0x62, 0x3f, 0xeb, 0x37, 0x82, 0xfa, 0x77, 0x1b, 0xc6, 0x0f, 0x13,
+ 0xaf, 0x15, 0xd5, 0xfa, 0xbb, 0x27, 0x2e, 0x2f, 0x62, 0xdf, 0xf1, 0x7e,
+ 0xac, 0x3f, 0x56, 0xd4, 0x71, 0xc7, 0xc8, 0x15, 0xa4, 0x61, 0x9b, 0xe3,
+ 0x70, 0x87, 0x4d, 0xa2, 0xa0, 0xff, 0xe3, 0x22, 0xa4, 0xd9, 0x34, 0xec,
+ 0x26, 0x03, 0x76, 0x73, 0x5b, 0xec, 0x7e, 0x9f, 0xf0, 0xdb, 0xff, 0x54,
+ 0xec, 0x27, 0xb7, 0xb5, 0x5f, 0x4e, 0x03, 0x77, 0x16, 0xdb, 0x9d, 0x93,
+ 0xd8, 0xc6, 0xff, 0xd3, 0xdb, 0xda, 0x7f, 0xd3, 0xf3, 0xdf, 0xac, 0x03,
+ 0xfb, 0xf0, 0xf9, 0x13, 0xf7, 0x29, 0x93, 0x47, 0x13, 0xaf, 0xf8, 0x15,
+ 0x06, 0x4e, 0x16, 0x19, 0x6a, 0x27, 0x25, 0xb1, 0x53, 0x43, 0xfa, 0xbc,
+ 0x4e, 0x8a, 0x58, 0xda, 0xce, 0x5e, 0x3b, 0x76, 0x0d, 0xeb, 0xc7, 0x32,
+ 0xc0, 0x57, 0x24, 0x80, 0xbb, 0x49, 0x9d, 0x90, 0x46, 0xa3, 0x92, 0x12,
+ 0xfb, 0x28, 0x23, 0xb9, 0x29, 0xec, 0x5f, 0x73, 0xb4, 0x5f, 0xb7, 0x54,
+ 0xdd, 0xb4, 0x1c, 0x26, 0x37, 0x13, 0xf4, 0xff, 0x0a, 0x41, 0x6f, 0xc7,
+ 0x5e, 0xac, 0x5e, 0xac, 0x40, 0xee, 0xfd, 0x38, 0xcb, 0xfa, 0x2b, 0x75,
+ 0x13, 0x87, 0x5e, 0x57, 0xfc, 0xcf, 0xc0, 0x0e, 0x0d, 0xd8, 0x7c, 0x18,
+ 0xf2, 0xa3, 0x0e, 0x1d, 0x36, 0xf6, 0xf0, 0xbb, 0xbc, 0xc7, 0xf0, 0x09,
+ 0x72, 0x25, 0xc6, 0x90, 0x9f, 0x9d, 0xd7, 0xfe, 0x66, 0xe8, 0x84, 0xa5,
+ 0x1d, 0xb1, 0x24, 0xbe, 0xb0, 0xed, 0x7c, 0x01, 0xfd, 0xaf, 0xfa, 0x1c,
+ 0xf6, 0xad, 0x32, 0x8e, 0x7d, 0x5d, 0x63, 0xc0, 0xa5, 0xb1, 0xa8, 0x86,
+ 0x62, 0x65, 0x8e, 0xc5, 0x27, 0x7f, 0x1e, 0xb5, 0x59, 0xcf, 0x1d, 0x36,
+ 0x7c, 0x35, 0x79, 0xd7, 0xf1, 0x5e, 0x6c, 0xf2, 0x76, 0x10, 0xf9, 0xf9,
+ 0x75, 0x8f, 0xd6, 0x57, 0x49, 0x1a, 0xc0, 0x39, 0x33, 0xd5, 0x76, 0x7c,
+ 0x7f, 0x57, 0xed, 0x7b, 0xb8, 0xfa, 0x4d, 0x72, 0xdc, 0x93, 0x12, 0x7f,
+ 0xbf, 0xf0, 0x63, 0x57, 0x1b, 0x7e, 0x64, 0xf8, 0xef, 0xfb, 0xa5, 0x2c,
+ 0xe7, 0xef, 0x08, 0xd6, 0x2f, 0x4d, 0xad, 0x22, 0xcf, 0x07, 0x39, 0x7e,
+ 0x4a, 0x5e, 0xf8, 0x1c, 0xbb, 0x66, 0xd3, 0x5a, 0x7e, 0x79, 0xa2, 0xf2,
+ 0x25, 0xe4, 0x72, 0x58, 0xcb, 0xc7, 0x9c, 0x93, 0x57, 0xa1, 0x1f, 0x3d,
+ 0x9f, 0xe5, 0xbc, 0x1d, 0x91, 0x53, 0x0e, 0xaa, 0x51, 0xa1, 0x7e, 0xb5,
+ 0xd8, 0x79, 0x16, 0x9d, 0x35, 0xfe, 0x9e, 0xa5, 0x85, 0x3a, 0xbe, 0x9f,
+ 0x4b, 0xe9, 0xb8, 0xce, 0xa8, 0xb8, 0x58, 0xaf, 0xab, 0x1a, 0xc3, 0xfe,
+ 0xda, 0xa2, 0xb6, 0x17, 0xa2, 0x7b, 0x9f, 0x69, 0xf9, 0x70, 0xf1, 0x1e,
+ 0xf4, 0x8b, 0xd5, 0x79, 0x31, 0x6c, 0x21, 0x6f, 0xf7, 0x2d, 0xe8, 0x0b,
+ 0xad, 0x92, 0x11, 0xae, 0x5b, 0x88, 0x9c, 0x29, 0xe0, 0x3b, 0xfc, 0xfd,
+ 0xdf, 0x50, 0x8d, 0xf3, 0xf5, 0x7c, 0x47, 0x64, 0xd5, 0xe4, 0x47, 0x30,
+ 0x63, 0xe2, 0x02, 0x3e, 0x2c, 0x6f, 0xe7, 0x1d, 0xc3, 0x57, 0xa9, 0x57,
+ 0xe1, 0x41, 0x7c, 0x05, 0x4e, 0x0d, 0x01, 0x63, 0x83, 0x5a, 0x2f, 0xda,
+ 0x86, 0xb7, 0xc1, 0xba, 0x48, 0x5d, 0x7d, 0xfc, 0x62, 0x50, 0xbc, 0x0a,
+ 0xf0, 0x4c, 0xf1, 0x98, 0xe7, 0x90, 0xca, 0xa7, 0xe1, 0x8b, 0x36, 0x14,
+ 0xa7, 0x33, 0x62, 0xaf, 0x2a, 0x71, 0x9d, 0x95, 0xb8, 0x7e, 0x4f, 0x9a,
+ 0xbc, 0x9b, 0x78, 0x80, 0x0b, 0x5e, 0x3c, 0x86, 0x6f, 0xb8, 0x1f, 0x66,
+ 0xaa, 0x01, 0x7f, 0x6a, 0x37, 0x06, 0xf0, 0x47, 0xef, 0x20, 0xd0, 0x8b,
+ 0x73, 0x88, 0xfb, 0xa4, 0xa3, 0xfb, 0xaa, 0xf1, 0x43, 0xd7, 0x75, 0x43,
+ 0xf8, 0x6a, 0xa9, 0x78, 0xfd, 0xfd, 0xd9, 0xd3, 0xa6, 0x3f, 0x83, 0xfd,
+ 0x62, 0xe2, 0x3f, 0x97, 0xe6, 0x01, 0x34, 0x71, 0x7b, 0x3d, 0xd8, 0x0f,
+ 0xe0, 0x7f, 0xdc, 0xe3, 0x51, 0xd7, 0x3e, 0xc9, 0x93, 0x60, 0xee, 0x69,
+ 0x6d, 0x6f, 0x5a, 0xec, 0x8f, 0x88, 0x7d, 0xc7, 0xd7, 0x8f, 0xda, 0xbf,
+ 0x3e, 0xaf, 0x0f, 0x4d, 0x7d, 0x9a, 0xfd, 0x68, 0xf2, 0xc4, 0xe7, 0x17,
+ 0x6f, 0xaf, 0xeb, 0xfd, 0xbd, 0xdb, 0xf4, 0xe7, 0x23, 0x9e, 0xbd, 0xef,
+ 0xbc, 0x7e, 0xd4, 0xdf, 0x53, 0xf4, 0x9c, 0x88, 0xc1, 0x39, 0xf3, 0x87,
+ 0x9a, 0x33, 0x1c, 0x87, 0xed, 0xac, 0xca, 0x5c, 0x99, 0xd3, 0xe7, 0xe4,
+ 0xc5, 0xef, 0xbc, 0x99, 0xeb, 0xca, 0x6f, 0x99, 0x3f, 0xc7, 0xfd, 0x73,
+ 0x24, 0xde, 0xe6, 0x3c, 0xc0, 0x64, 0xb1, 0x35, 0x5f, 0xc8, 0x3b, 0xec,
+ 0xaa, 0xfc, 0x9b, 0x39, 0x30, 0x6e, 0xec, 0x43, 0x74, 0x47, 0xfd, 0xfa,
+ 0xad, 0xf5, 0x89, 0x3c, 0x60, 0x9e, 0x6d, 0x6c, 0xe2, 0xde, 0xfd, 0x67,
+ 0xb3, 0x79, 0x1f, 0x07, 0xea, 0xe8, 0x12, 0xd7, 0x3d, 0xae, 0xea, 0xcf,
+ 0xef, 0x03, 0xef, 0x9e, 0xb7, 0xa2, 0x7a, 0x5d, 0xe5, 0x42, 0x78, 0xf5,
+ 0xfa, 0xe3, 0xb2, 0xbf, 0x80, 0xb9, 0xf4, 0xda, 0x29, 0xce, 0xff, 0x7b,
+ 0x67, 0x37, 0x78, 0x3e, 0x7d, 0xf8, 0xc6, 0x35, 0x1d, 0xd7, 0xa3, 0xb4,
+ 0x3e, 0xe7, 0xb0, 0x3f, 0xa5, 0xdd, 0x50, 0xdf, 0x78, 0xb6, 0xb5, 0x1e,
+ 0x78, 0xd7, 0xa0, 0x5e, 0x4a, 0x6f, 0x36, 0x78, 0xaf, 0x36, 0xfd, 0x43,
+ 0xbf, 0xec, 0xcf, 0x40, 0xdf, 0xf4, 0x73, 0xb0, 0xae, 0x77, 0x36, 0x9b,
+ 0x73, 0xd7, 0xe4, 0x3b, 0xc8, 0xd3, 0xa3, 0xe3, 0x7e, 0xbb, 0x83, 0xb4,
+ 0x56, 0x87, 0xdd, 0x69, 0xe9, 0xc3, 0x13, 0x72, 0xf0, 0x4f, 0xc9, 0x0c,
+ 0x9f, 0x53, 0x7e, 0x81, 0x79, 0x46, 0xb9, 0x14, 0xe2, 0x2c, 0x1f, 0xc6,
+ 0xf7, 0x72, 0x1a, 0xeb, 0x3d, 0x69, 0xdc, 0x6f, 0xd3, 0x71, 0x87, 0xf5,
+ 0x7b, 0xd2, 0xc0, 0x9c, 0xf4, 0xeb, 0x9a, 0x37, 0x8f, 0x80, 0x2b, 0x31,
+ 0x7f, 0xff, 0x46, 0xe8, 0x7a, 0x4c, 0x2b, 0xa8, 0xcb, 0xba, 0x80, 0xfe,
+ 0x2b, 0x0d, 0x39, 0xfc, 0x7d, 0xa6, 0x80, 0xb9, 0x4a, 0x03, 0xc1, 0xfb,
+ 0x50, 0xfa, 0xb9, 0xa7, 0x39, 0xb7, 0xfc, 0x73, 0x2d, 0x31, 0xb6, 0x5c,
+ 0x0f, 0xde, 0x97, 0x2b, 0x31, 0xff, 0x9c, 0xd0, 0x76, 0x59, 0x54, 0xf3,
+ 0xc1, 0x3f, 0xd7, 0xc2, 0x52, 0xef, 0xbf, 0x64, 0x0e, 0xec, 0xa4, 0x9b,
+ 0x75, 0xc4, 0xb5, 0x56, 0x6f, 0xcd, 0xb3, 0x39, 0xcf, 0xd8, 0x83, 0xdf,
+ 0x26, 0x8e, 0xa6, 0x7d, 0x9c, 0x7f, 0x4a, 0xfc, 0xfc, 0x85, 0xdf, 0x21,
+ 0x39, 0x89, 0x47, 0xdb, 0xc5, 0xfa, 0x01, 0x99, 0xb3, 0xae, 0x27, 0x07,
+ 0xe7, 0xe3, 0x34, 0xfb, 0xd5, 0x49, 0x78, 0x77, 0xe4, 0xbc, 0xbe, 0x36,
+ 0xf1, 0x75, 0x8d, 0x00, 0x97, 0x46, 0x4c, 0x1d, 0x4c, 0xbd, 0x4c, 0x7d,
+ 0x50, 0xc7, 0xdc, 0x28, 0xab, 0x4d, 0x94, 0x47, 0x99, 0xa7, 0x23, 0xe5,
+ 0x3f, 0x83, 0xef, 0xb4, 0xa3, 0x45, 0xad, 0xff, 0x16, 0x7d, 0xc3, 0x7d,
+ 0x44, 0xf4, 0x83, 0x60, 0x73, 0x1e, 0x49, 0x01, 0x02, 0xef, 0xb2, 0x30,
+ 0x5d, 0x8f, 0xca, 0xf2, 0xb8, 0xe9, 0x9b, 0x60, 0xdf, 0x5d, 0xe1, 0x77,
+ 0xfa, 0xc2, 0xe6, 0xd6, 0xfe, 0x37, 0xf1, 0x69, 0xbd, 0x61, 0xe1, 0xa1,
+ 0x4d, 0xa5, 0xfd, 0x78, 0xd7, 0x74, 0xc4, 0xc1, 0xf3, 0x8e, 0xb8, 0xbf,
+ 0x4e, 0x8a, 0x0f, 0x89, 0xb8, 0x16, 0x77, 0x75, 0x26, 0x38, 0x8e, 0x4b,
+ 0x5f, 0xdf, 0xe2, 0xcf, 0x1f, 0x2d, 0xa7, 0xb0, 0xde, 0x5d, 0x82, 0xf9,
+ 0x08, 0xf3, 0x35, 0x4c, 0x17, 0xc0, 0xe7, 0x0f, 0x96, 0x80, 0xef, 0xd3,
+ 0x21, 0xd8, 0xe9, 0x7c, 0x9b, 0xef, 0x71, 0xbb, 0x1b, 0xe9, 0xac, 0x2d,
+ 0x0b, 0x4f, 0xf3, 0x16, 0xff, 0x3f, 0xd2, 0xa0, 0xb4, 0xbc, 0x5b, 0xa5,
+ 0xcf, 0xc0, 0xcf, 0x88, 0xaf, 0xce, 0xdb, 0xf1, 0x55, 0xa3, 0xa3, 0xf8,
+ 0x88, 0xed, 0xc2, 0x5b, 0xbb, 0x95, 0xb7, 0xa6, 0x8e, 0x79, 0xab, 0x2d,
+ 0x4f, 0xf7, 0x05, 0x79, 0x1a, 0x13, 0x9e, 0xfe, 0xed, 0xcd, 0xd3, 0xad,
+ 0x76, 0x31, 0xc7, 0x6f, 0xfe, 0x6f, 0xbc, 0x05, 0x1e, 0x18, 0xd4, 0xe7,
+ 0x77, 0xfb, 0xf8, 0x67, 0xfc, 0xf2, 0xcf, 0x9f, 0x43, 0x6a, 0xae, 0xfe,
+ 0x07, 0x92, 0xe2, 0x88, 0x7c, 0xe0, 0x0d, 0x00, 0x00, 0x00 };
static u8 bnx2_TPAT_b06FwText[] = {
- 0xbd, 0x59, 0x6d, 0x70, 0x5b, 0x55, 0x7a, 0x7e, 0xae, 0x74, 0x25, 0x5d,
- 0xdb, 0xb2, 0x75, 0x8d, 0x95, 0x20, 0xb7, 0x2e, 0xd6, 0x8d, 0xaf, 0x6c,
- 0x11, 0xb9, 0xe1, 0x2a, 0x36, 0x45, 0x19, 0xee, 0x94, 0x1b, 0x7f, 0x21,
- 0x92, 0x10, 0x94, 0x42, 0x5b, 0x67, 0x96, 0x19, 0x4c, 0xe2, 0x4d, 0x4c,
- 0x08, 0x6c, 0xba, 0xcb, 0x4c, 0xdd, 0xd9, 0x4c, 0x23, 0xfc, 0x15, 0x93,
- 0xc8, 0x16, 0x6b, 0x20, 0x26, 0x3b, 0x3b, 0x43, 0xc6, 0xf9, 0x70, 0x0a,
- 0x72, 0x14, 0xda, 0x3f, 0x3b, 0xd3, 0x65, 0xf0, 0x6c, 0x12, 0x12, 0x58,
- 0xd8, 0xb4, 0xd3, 0x3f, 0xc9, 0xf4, 0xc7, 0x7a, 0x21, 0xa1, 0x81, 0x42,
- 0x36, 0xed, 0x0c, 0x9d, 0x50, 0x68, 0x4e, 0x9f, 0x73, 0x25, 0x07, 0x13,
- 0xb2, 0xfd, 0xd9, 0xcc, 0x08, 0x4b, 0xe7, 0xde, 0x73, 0xce, 0x7b, 0xce,
- 0xfb, 0x3c, 0xcf, 0xfb, 0x9c, 0xc3, 0x0a, 0x05, 0x95, 0x28, 0xff, 0xab,
- 0xe6, 0xa7, 0xfd, 0xc9, 0x5d, 0xcf, 0xad, 0x5e, 0xd5, 0xbe, 0x8a, 0x5f,
- 0x57, 0x2b, 0xcb, 0x55, 0x15, 0xff, 0x8f, 0xff, 0xbc, 0x80, 0xbe, 0x18,
- 0x87, 0xfc, 0x40, 0xf3, 0xd8, 0xf3, 0x77, 0x75, 0x98, 0xd0, 0xbc, 0xf6,
- 0x63, 0x4d, 0x5b, 0x4d, 0xc0, 0x29, 0x24, 0xa2, 0x9d, 0xf8, 0x1f, 0x91,
- 0x0d, 0xab, 0x90, 0xed, 0x7f, 0x64, 0x7f, 0x7d, 0xcf, 0x5b, 0xf7, 0x19,
- 0xd7, 0x0e, 0x79, 0xa1, 0xe9, 0xf6, 0xb8, 0xaa, 0x37, 0x43, 0x6b, 0x60,
- 0x9f, 0x9f, 0xb5, 0xf4, 0xfb, 0x50, 0xb3, 0x38, 0x16, 0x70, 0x38, 0x67,
- 0x58, 0xdb, 0x90, 0xd0, 0x4f, 0x41, 0x85, 0xc3, 0x39, 0x8e, 0x15, 0x80,
- 0xbd, 0x39, 0x05, 0x97, 0x39, 0xe6, 0x68, 0x41, 0xc3, 0x82, 0xd7, 0x9d,
- 0xae, 0xaf, 0xc2, 0x46, 0xc6, 0x9c, 0xd8, 0x23, 0x02, 0x26, 0xb2, 0x7f,
- 0x60, 0x9b, 0xf1, 0xbd, 0x08, 0xa6, 0x66, 0xda, 0x91, 0x59, 0x31, 0xa7,
- 0x61, 0x73, 0xbe, 0xa1, 0x4f, 0xb3, 0xc1, 0x77, 0x14, 0xa4, 0xee, 0xd3,
- 0xd0, 0x5b, 0x8c, 0x23, 0x5b, 0xcc, 0xc2, 0x29, 0x8e, 0xf0, 0xa3, 0x21,
- 0x30, 0xa1, 0x69, 0xf7, 0x4c, 0x2c, 0x97, 0xef, 0x20, 0x38, 0x71, 0x4d,
- 0x5c, 0x4d, 0xea, 0x78, 0x6f, 0x8d, 0x10, 0xd5, 0x36, 0xb2, 0x55, 0xed,
- 0x59, 0x78, 0x6d, 0xc3, 0x5a, 0xef, 0x55, 0xd0, 0xf5, 0xc7, 0x66, 0x7c,
- 0x42, 0x79, 0xf4, 0x51, 0x8f, 0x0d, 0x4d, 0xb1, 0xa3, 0x6a, 0x53, 0xa1,
- 0x01, 0x63, 0x45, 0x1d, 0x7b, 0x8b, 0x61, 0x8c, 0x14, 0xb1, 0xdb, 0x7b,
- 0xaf, 0x1f, 0x33, 0x3a, 0x9c, 0xef, 0xb5, 0xec, 0xc6, 0x8e, 0xdc, 0x20,
- 0xb6, 0xe6, 0x52, 0xd8, 0x57, 0x94, 0x31, 0x46, 0x31, 0x5c, 0x54, 0xe1,
- 0x9f, 0x30, 0x22, 0xef, 0xe2, 0x76, 0xcf, 0x84, 0x18, 0xb1, 0x02, 0x18,
- 0xb2, 0xe2, 0x18, 0xcd, 0x7b, 0xb8, 0xce, 0x00, 0x86, 0xcd, 0xeb, 0xa2,
- 0xdf, 0x32, 0xac, 0x51, 0x88, 0xc6, 0xd3, 0x96, 0x11, 0xe9, 0xf2, 0xc2,
- 0xf9, 0xb1, 0x19, 0xc1, 0x28, 0x63, 0x1f, 0x71, 0xfb, 0x8d, 0xa0, 0xeb,
- 0x66, 0x3f, 0x87, 0xfd, 0x74, 0x8c, 0x7d, 0xbb, 0x6f, 0x74, 0x14, 0x89,
- 0xc8, 0x18, 0x3c, 0xe8, 0x0b, 0xb7, 0xb2, 0x5f, 0x53, 0x74, 0x0c, 0x46,
- 0x9c, 0xe3, 0x64, 0xfd, 0xed, 0x0e, 0xc7, 0xc8, 0xb2, 0xbf, 0x11, 0x3d,
- 0x06, 0x39, 0x56, 0x03, 0x7f, 0xb7, 0xb3, 0xbf, 0x02, 0x8f, 0x1d, 0x8b,
- 0x0e, 0xb1, 0xcf, 0x29, 0x4b, 0xc5, 0x19, 0x7e, 0xfa, 0x74, 0x43, 0x66,
- 0x56, 0x09, 0xb0, 0x7d, 0x2f, 0xf8, 0xdc, 0xac, 0xc2, 0xa1, 0x8c, 0x85,
- 0x21, 0xae, 0x5b, 0x63, 0xdb, 0x38, 0xdb, 0x7c, 0xa6, 0xc5, 0xf1, 0xa1,
- 0x77, 0x15, 0x97, 0x62, 0x62, 0x31, 0x37, 0xbf, 0xaf, 0x9d, 0x63, 0xe4,
- 0x4b, 0x39, 0x95, 0xef, 0x74, 0xe6, 0x6f, 0x88, 0x27, 0xd5, 0xa5, 0xcf,
- 0x07, 0x95, 0x0e, 0xb6, 0x39, 0x6a, 0x03, 0xf6, 0xe6, 0xa1, 0xf9, 0x4d,
- 0x8d, 0xf3, 0x68, 0xf8, 0x28, 0x37, 0xa8, 0xf4, 0x14, 0x1d, 0xa5, 0x7b,
- 0xb6, 0x43, 0x71, 0x66, 0x55, 0xa5, 0x6b, 0x5a, 0xc6, 0x2d, 0xc4, 0x0b,
- 0x96, 0xc2, 0x98, 0x7f, 0x22, 0xe3, 0x75, 0xa2, 0xca, 0x0d, 0xb1, 0x32,
- 0xe6, 0x41, 0x95, 0xd9, 0xa3, 0xac, 0x9f, 0x15, 0x22, 0x9d, 0x4c, 0x2b,
- 0xeb, 0x66, 0xa1, 0x05, 0x6d, 0x5b, 0xcd, 0x4d, 0xec, 0x43, 0x76, 0x99,
- 0x89, 0x83, 0xf9, 0x28, 0x3e, 0xb0, 0x3c, 0x38, 0xb4, 0xac, 0x02, 0xaa,
- 0xa9, 0xf0, 0x83, 0xe0, 0x79, 0x0b, 0x6a, 0x0d, 0xbf, 0x5f, 0xdd, 0xa4,
- 0x62, 0xa4, 0x7d, 0x9d, 0xd2, 0xc5, 0x3e, 0x3e, 0xe6, 0xf9, 0x68, 0x2e,
- 0x8d, 0x20, 0xb1, 0x53, 0x65, 0xc7, 0x22, 0x05, 0xee, 0xcd, 0x7b, 0x56,
- 0x2c, 0xfe, 0xb4, 0xc4, 0x63, 0xad, 0x11, 0x91, 0x7b, 0x53, 0x6d, 0xc7,
- 0xe2, 0x73, 0xdc, 0x07, 0xaf, 0xa9, 0xe2, 0xd7, 0x96, 0x0f, 0xf3, 0x9b,
- 0x2c, 0xe6, 0x54, 0x87, 0x9f, 0xed, 0xc7, 0xdc, 0x76, 0xf9, 0x1b, 0x7a,
- 0xf7, 0xb7, 0xf6, 0xa1, 0xb4, 0x07, 0xc3, 0xf9, 0x26, 0xc6, 0x5c, 0xda,
- 0x83, 0x47, 0xb8, 0xde, 0xdf, 0xfa, 0xe4, 0xd7, 0xbb, 0x6e, 0xb6, 0x6d,
- 0x66, 0x9c, 0x1e, 0xdb, 0x9c, 0x5f, 0xe1, 0xad, 0x07, 0xea, 0xda, 0xb1,
- 0x8f, 0x39, 0xee, 0x4a, 0x2e, 0x47, 0xd6, 0x7d, 0x1e, 0xd6, 0xd7, 0x4f,
- 0xd7, 0xa1, 0x6f, 0x99, 0xbb, 0x6f, 0xfa, 0xc6, 0x69, 0x21, 0xce, 0x24,
- 0xfd, 0x98, 0x33, 0x87, 0x22, 0xd5, 0xc8, 0x5a, 0x5e, 0xe6, 0xfb, 0x2c,
- 0xe7, 0x2f, 0x24, 0xbd, 0x38, 0x9c, 0x3c, 0x84, 0x6c, 0x2d, 0x30, 0x93,
- 0x93, 0xbc, 0x32, 0xe6, 0xcf, 0xf2, 0xbf, 0x9e, 0xa2, 0x5c, 0x9f, 0xc5,
- 0xf5, 0x29, 0x38, 0x66, 0x4a, 0x4c, 0x5b, 0x6a, 0x33, 0xf9, 0xb5, 0x83,
- 0xfb, 0x59, 0xdf, 0x1e, 0x24, 0x3e, 0x81, 0x0f, 0x73, 0xfd, 0xd8, 0x5c,
- 0x8a, 0x05, 0xd7, 0x73, 0x50, 0x7c, 0x6d, 0x69, 0x1c, 0x2a, 0xfd, 0x26,
- 0xc7, 0xd3, 0x6a, 0x47, 0xce, 0xc8, 0xa4, 0x91, 0x38, 0xd7, 0xa1, 0xc8,
- 0xfe, 0x69, 0x75, 0x65, 0xc1, 0x8f, 0x68, 0x5d, 0xe9, 0x79, 0x95, 0xbd,
- 0x41, 0x7d, 0x7a, 0x42, 0xc1, 0xf6, 0x98, 0x7c, 0xb6, 0x41, 0x6d, 0x29,
- 0x40, 0xab, 0xb6, 0x77, 0xa9, 0x73, 0x13, 0x46, 0xdf, 0x71, 0x25, 0x11,
- 0x9d, 0x70, 0xfb, 0xec, 0x52, 0x5b, 0x0b, 0x01, 0xae, 0x27, 0xce, 0x9c,
- 0x40, 0xab, 0xb1, 0x9f, 0x53, 0x7f, 0xcd, 0x07, 0xe7, 0xdc, 0x3e, 0xcf,
- 0xa9, 0xf1, 0x82, 0x6c, 0x37, 0xac, 0xa8, 0x12, 0xc0, 0xdd, 0x49, 0x0d,
- 0x2b, 0x5b, 0x44, 0x63, 0x77, 0xd2, 0x98, 0xef, 0xf6, 0x46, 0x70, 0x90,
- 0x5c, 0x20, 0xee, 0x9c, 0x3f, 0x6c, 0x19, 0x41, 0x77, 0xd1, 0x8b, 0x68,
- 0xad, 0x83, 0xfd, 0xf9, 0x00, 0x7e, 0x49, 0xfc, 0xf7, 0x58, 0x3a, 0x46,
- 0xf2, 0x46, 0xfc, 0x57, 0x48, 0xa4, 0x8e, 0x30, 0x67, 0x0b, 0xe4, 0xc0,
- 0xfe, 0x62, 0x53, 0xfc, 0x08, 0x8c, 0x81, 0x6e, 0x72, 0x40, 0x6b, 0x97,
- 0x31, 0x40, 0x57, 0x6d, 0x72, 0xa7, 0xd8, 0x80, 0x1c, 0xf9, 0xd0, 0xed,
- 0xf2, 0x6a, 0x50, 0xe9, 0x2a, 0xbe, 0x4f, 0x6d, 0xed, 0x21, 0xbe, 0x10,
- 0x8a, 0x98, 0x7e, 0xa4, 0xea, 0xa2, 0x38, 0x4d, 0xac, 0x64, 0xc3, 0x15,
- 0xcc, 0xa5, 0xcc, 0xe7, 0x45, 0x3e, 0x5f, 0xa7, 0x74, 0xce, 0x46, 0xf1,
- 0x4b, 0xeb, 0x6b, 0xe1, 0x84, 0xab, 0xd9, 0xe6, 0x5b, 0xd2, 0xae, 0xe1,
- 0xf2, 0xcb, 0x95, 0xf8, 0xf4, 0xe5, 0x20, 0xbe, 0x7c, 0x99, 0xfc, 0xce,
- 0xa3, 0xbd, 0x12, 0x42, 0xa4, 0xda, 0x84, 0x28, 0x5a, 0xad, 0xf8, 0xa8,
- 0x36, 0x16, 0xbd, 0x00, 0xa9, 0x8d, 0x8e, 0xba, 0x35, 0x67, 0xec, 0x1a,
- 0x40, 0xc2, 0x39, 0xe5, 0xee, 0x85, 0xa3, 0xae, 0x2a, 0x9c, 0x16, 0xd8,
- 0x54, 0xda, 0x0b, 0xbf, 0xdd, 0xa5, 0xbe, 0xc3, 0xdc, 0x9c, 0x77, 0x73,
- 0xd3, 0xa5, 0xde, 0x53, 0xb8, 0xdf, 0x83, 0xca, 0xd2, 0x33, 0xd5, 0xce,
- 0xa8, 0x23, 0x39, 0xa3, 0x77, 0x9c, 0xeb, 0xeb, 0x77, 0xfb, 0x66, 0xd4,
- 0x04, 0xf7, 0x7e, 0xa1, 0x9c, 0x9b, 0x6a, 0xfb, 0x31, 0xee, 0x33, 0x73,
- 0xef, 0xee, 0xe3, 0x63, 0xdc, 0x63, 0x39, 0xdf, 0xe0, 0x2d, 0xf3, 0x0d,
- 0x72, 0xbe, 0xe3, 0x4b, 0xe6, 0xdb, 0xbd, 0x64, 0xbe, 0xdd, 0x4b, 0xe6,
- 0x4b, 0x91, 0xab, 0xff, 0x22, 0x86, 0xc2, 0xa5, 0xb1, 0x55, 0x7b, 0xe0,
- 0x96, 0xb9, 0x07, 0x38, 0xf7, 0x01, 0xb1, 0x90, 0x29, 0x8d, 0x53, 0x6d,
- 0xef, 0x5c, 0x32, 0xf7, 0x4e, 0xce, 0xbd, 0x38, 0x8e, 0x4e, 0x2d, 0x12,
- 0x62, 0xa3, 0x25, 0x84, 0x6a, 0x9b, 0x7a, 0x17, 0x9a, 0x33, 0x5d, 0xc4,
- 0x4e, 0x25, 0x12, 0xf3, 0x1e, 0x98, 0x83, 0xf5, 0x5e, 0x1f, 0x16, 0x6a,
- 0x17, 0xb9, 0x51, 0x5d, 0xfe, 0xfb, 0x9a, 0x02, 0x6a, 0xfd, 0x1b, 0xb9,
- 0x10, 0xc7, 0x88, 0xe9, 0xfd, 0x8a, 0x10, 0xa7, 0xd6, 0x24, 0x06, 0xbc,
- 0x48, 0xf4, 0xd5, 0xc0, 0x24, 0x86, 0x7c, 0x65, 0x2e, 0x2c, 0xed, 0x73,
- 0xdc, 0xed, 0x53, 0x74, 0xfb, 0x08, 0xf1, 0xe1, 0xbd, 0x57, 0xc4, 0x5b,
- 0x2d, 0x61, 0xbc, 0x4d, 0x4e, 0x9e, 0x2c, 0x2e, 0xea, 0x8a, 0xd4, 0x0d,
- 0x78, 0x4e, 0x59, 0x7e, 0xc6, 0x34, 0xb4, 0xc3, 0xff, 0xad, 0xfe, 0x04,
- 0x8c, 0x29, 0xdb, 0xbc, 0x78, 0x3d, 0x89, 0x27, 0x2b, 0x61, 0xf4, 0xee,
- 0x53, 0xb2, 0xe9, 0x2a, 0x18, 0xce, 0x4a, 0x25, 0x9b, 0xd2, 0x20, 0x79,
- 0xa3, 0x36, 0x1e, 0x35, 0x8d, 0xec, 0x65, 0xbe, 0xac, 0x4e, 0xde, 0x2e,
- 0x06, 0x95, 0x63, 0x04, 0xf1, 0x6c, 0xfe, 0x7d, 0xcc, 0xfb, 0xa4, 0x86,
- 0x49, 0xed, 0xe4, 0xc0, 0x27, 0xa4, 0x86, 0x05, 0x48, 0x44, 0x15, 0x7b,
- 0xf2, 0x9e, 0xd3, 0x8d, 0x10, 0xf0, 0xb7, 0xf9, 0x70, 0xd1, 0x1c, 0xb6,
- 0xea, 0xb1, 0x16, 0xe7, 0x5b, 0xb9, 0x07, 0xcb, 0x54, 0x44, 0x66, 0x96,
- 0x8e, 0x15, 0xe1, 0x58, 0x11, 0x7c, 0x92, 0x13, 0xa2, 0xd2, 0x36, 0xe2,
- 0x0b, 0x30, 0x19, 0x47, 0x04, 0x57, 0x0a, 0x5b, 0xfc, 0xa8, 0x09, 0x43,
- 0x6d, 0x56, 0xb1, 0x3d, 0xaf, 0x29, 0xdd, 0x79, 0xe8, 0x5e, 0xdb, 0x8c,
- 0x1e, 0xc6, 0x51, 0xc6, 0xc3, 0xba, 0x76, 0x4c, 0x55, 0x36, 0x4e, 0x07,
- 0x50, 0x3d, 0xf5, 0x99, 0x78, 0x9f, 0x7a, 0xf8, 0xc6, 0xbd, 0xac, 0x17,
- 0xc9, 0x00, 0xaa, 0xdc, 0xb9, 0x85, 0xf8, 0xb8, 0xad, 0x0e, 0x17, 0x39,
- 0x5f, 0xf4, 0x2f, 0x03, 0xf0, 0x4e, 0x05, 0xe0, 0x9b, 0x52, 0x30, 0xd3,
- 0x1e, 0x80, 0x67, 0x46, 0xfe, 0x56, 0x10, 0x30, 0xa7, 0xb1, 0x5d, 0x6f,
- 0xc0, 0x78, 0x9e, 0x45, 0xda, 0xfc, 0x19, 0x06, 0xdc, 0xef, 0x2a, 0x9e,
- 0xca, 0x6b, 0x08, 0x1d, 0x10, 0xa2, 0xd1, 0x16, 0x22, 0x96, 0xf4, 0x60,
- 0xd6, 0x1c, 0x8e, 0x06, 0xb8, 0x8e, 0x61, 0x4b, 0x6a, 0x8e, 0x0f, 0xea,
- 0x8c, 0x91, 0x39, 0xc7, 0xa8, 0x37, 0x4f, 0xa8, 0x4a, 0xef, 0xf4, 0x1e,
- 0xc1, 0x98, 0xfa, 0x1e, 0xf0, 0x0a, 0x51, 0xd3, 0xd6, 0x34, 0x70, 0x9e,
- 0xda, 0x3c, 0x13, 0x8b, 0xf5, 0x0e, 0x29, 0xc0, 0xfa, 0x39, 0x1f, 0xfc,
- 0x53, 0xff, 0xc5, 0x3a, 0x2b, 0x44, 0xe1, 0x5e, 0x81, 0x77, 0xad, 0x6c,
- 0xbc, 0x02, 0x46, 0xea, 0x24, 0xc2, 0xb8, 0xf4, 0xa2, 0x10, 0xdb, 0xdb,
- 0x43, 0x78, 0xcd, 0x32, 0x76, 0x7d, 0xec, 0x15, 0xb8, 0x98, 0xcc, 0x0e,
- 0xd6, 0x53, 0xb7, 0xae, 0x29, 0x51, 0x54, 0xe5, 0x8d, 0xcc, 0x15, 0x85,
- 0x4b, 0x9f, 0x31, 0xf5, 0x9d, 0x4a, 0x10, 0x55, 0x27, 0x82, 0xe8, 0x98,
- 0xf3, 0xa3, 0x62, 0x2a, 0x08, 0xef, 0xa4, 0x79, 0xfd, 0x41, 0xb8, 0xe3,
- 0x58, 0x27, 0xd1, 0x8c, 0x8b, 0x2f, 0x1b, 0xf3, 0xc7, 0x89, 0x93, 0xed,
- 0x88, 0xe2, 0x37, 0x05, 0x13, 0x17, 0x0b, 0x41, 0xa8, 0x27, 0x74, 0xd4,
- 0xbb, 0xf5, 0x4e, 0x47, 0xb5, 0xe9, 0x61, 0x5e, 0x1c, 0xe5, 0x61, 0xb7,
- 0x9e, 0x74, 0xf1, 0xd3, 0xa3, 0x74, 0xb0, 0xae, 0x6c, 0x98, 0x26, 0x95,
- 0xf9, 0xec, 0x9c, 0x75, 0x43, 0xec, 0x8f, 0xa5, 0x59, 0x47, 0x2a, 0xe0,
- 0xb3, 0xd7, 0xb1, 0x8e, 0xb0, 0x38, 0xb9, 0xba, 0x5f, 0xa1, 0xf8, 0xec,
- 0xef, 0x6a, 0x7e, 0x88, 0x9a, 0x5f, 0xfc, 0x3f, 0x35, 0x5f, 0x85, 0x3a,
- 0xe5, 0xc1, 0x98, 0x19, 0xc0, 0x6f, 0xac, 0xa6, 0x73, 0x8d, 0x08, 0x20,
- 0xd5, 0xa6, 0x23, 0x72, 0xc2, 0xc2, 0x8b, 0xdc, 0x5b, 0xdc, 0x71, 0x6b,
- 0x3d, 0x04, 0x76, 0x92, 0x53, 0x15, 0xd4, 0x86, 0xbb, 0x27, 0x82, 0xd4,
- 0x29, 0x55, 0x59, 0x4f, 0x9d, 0xdf, 0x91, 0xbc, 0x21, 0xd2, 0x31, 0x23,
- 0x1e, 0x57, 0x12, 0xa9, 0xbf, 0x43, 0x49, 0x3b, 0x62, 0xd4, 0xd1, 0x05,
- 0x7d, 0x91, 0x83, 0x5d, 0x2e, 0x07, 0x67, 0x62, 0x25, 0xed, 0x58, 0x51,
- 0x28, 0xf1, 0xef, 0x01, 0xea, 0xe7, 0xf5, 0xb6, 0x92, 0x76, 0xbe, 0x4a,
- 0xff, 0xd3, 0xcb, 0xf1, 0x1e, 0x99, 0x36, 0xb2, 0xbd, 0xcc, 0xcf, 0x25,
- 0x62, 0x63, 0x92, 0x19, 0x9c, 0xaf, 0xa5, 0xa6, 0x36, 0x07, 0x18, 0xe3,
- 0x75, 0x71, 0x9a, 0xde, 0x62, 0x98, 0xfd, 0x46, 0xf3, 0x46, 0x74, 0x98,
- 0x7c, 0x1f, 0x2d, 0x6b, 0xe9, 0x30, 0xfd, 0xc4, 0x28, 0xf3, 0xf4, 0x36,
- 0x9f, 0x9d, 0xcc, 0x1b, 0xe9, 0x2e, 0x57, 0x53, 0xa5, 0xaf, 0x90, 0x31,
- 0x49, 0x6f, 0x11, 0xc1, 0x5b, 0x2d, 0x52, 0x5f, 0x1b, 0xa8, 0xaf, 0x8b,
- 0xba, 0x2a, 0xf1, 0x70, 0x4d, 0x84, 0x5a, 0x42, 0x5e, 0xc9, 0xcb, 0x4b,
- 0x49, 0x21, 0xaa, 0xec, 0x20, 0x2a, 0x27, 0xcc, 0xf4, 0x7a, 0x25, 0x16,
- 0x31, 0x95, 0xbb, 0xd8, 0xce, 0x1c, 0xce, 0x6d, 0xf2, 0xba, 0xde, 0xf6,
- 0x84, 0x10, 0x21, 0x5b, 0x47, 0xcd, 0x84, 0x49, 0xdc, 0xc4, 0xfa, 0x8e,
- 0xb8, 0xcf, 0x75, 0x04, 0xe7, 0x16, 0xc8, 0xe7, 0x08, 0xf9, 0x1c, 0xc6,
- 0x9b, 0xb7, 0x70, 0x9a, 0x5a, 0xeb, 0xe9, 0x27, 0xa7, 0xb3, 0xe1, 0xa1,
- 0x2d, 0xde, 0x6f, 0xf1, 0x71, 0xbf, 0xe4, 0x34, 0xdb, 0xbc, 0x78, 0x21,
- 0x89, 0xcd, 0xc4, 0x47, 0xe6, 0x29, 0x25, 0xeb, 0x90, 0xdb, 0xa9, 0x0a,
- 0x25, 0x4b, 0x17, 0xf5, 0x0d, 0xa7, 0xcf, 0xf0, 0x6d, 0x2f, 0x39, 0xdd,
- 0x17, 0xbe, 0x95, 0xd3, 0x2c, 0xbe, 0xcc, 0xf7, 0x33, 0xf9, 0x83, 0x98,
- 0xf1, 0xf9, 0x11, 0x99, 0xf2, 0x21, 0x30, 0xa5, 0x92, 0x5f, 0x0a, 0xfd,
- 0x41, 0x36, 0x1e, 0x80, 0x91, 0x3e, 0x89, 0x08, 0x12, 0x13, 0x1a, 0xfe,
- 0xaa, 0xc5, 0x87, 0x63, 0x31, 0x23, 0xb3, 0x93, 0x3c, 0x5d, 0x39, 0x37,
- 0xc4, 0x88, 0x8c, 0x68, 0xd4, 0x53, 0xe2, 0xab, 0xaf, 0xd9, 0x0f, 0x6d,
- 0xca, 0xe5, 0xe0, 0x1e, 0x8f, 0x9d, 0x8d, 0x6a, 0x30, 0x76, 0xfd, 0x84,
- 0xb8, 0xb8, 0x30, 0x21, 0x44, 0x67, 0xbb, 0x79, 0xee, 0x23, 0xaf, 0x41,
- 0x2d, 0x54, 0x71, 0x7e, 0xae, 0x34, 0x7e, 0xd5, 0x94, 0x06, 0xff, 0x01,
- 0x77, 0xfc, 0xeb, 0x6f, 0x32, 0x8a, 0xcf, 0xf3, 0x12, 0x9f, 0x42, 0x04,
- 0x6c, 0x33, 0x32, 0x4b, 0x3d, 0xdc, 0x97, 0x34, 0xb8, 0x7f, 0x4d, 0x4e,
- 0x33, 0xbf, 0x7b, 0x92, 0xb1, 0xe8, 0x16, 0xbe, 0x73, 0xa9, 0x58, 0xe2,
- 0x70, 0xbd, 0xb9, 0x15, 0x7f, 0xa3, 0x7b, 0x51, 0x63, 0xfe, 0x10, 0xcf,
- 0xba, 0x1a, 0x45, 0xec, 0x4f, 0x56, 0xa2, 0x91, 0x98, 0x7f, 0x82, 0x98,
- 0xdf, 0x3c, 0x4b, 0xad, 0x99, 0x6a, 0x67, 0x7e, 0x25, 0xdf, 0xbb, 0x94,
- 0xde, 0xd9, 0x1e, 0xd7, 0x57, 0x3d, 0x32, 0xed, 0xc1, 0x9b, 0xd6, 0x5a,
- 0x7a, 0x98, 0xb4, 0xf2, 0xc8, 0xac, 0xc4, 0xfb, 0x3a, 0xe5, 0x41, 0x62,
- 0x3f, 0x7a, 0x87, 0x8a, 0x19, 0x6b, 0xad, 0xe2, 0x77, 0xb1, 0xef, 0x83,
- 0x93, 0x29, 0xe1, 0xde, 0x6b, 0xc7, 0xac, 0x53, 0x4b, 0x70, 0xdf, 0x73,
- 0x1b, 0xaf, 0x23, 0xb5, 0x03, 0x25, 0x7d, 0xd7, 0xbb, 0x98, 0xaf, 0xe7,
- 0xcb, 0xf8, 0x7e, 0x96, 0xed, 0xbe, 0x29, 0x68, 0x95, 0xc4, 0xf0, 0x3a,
- 0x62, 0x7c, 0x92, 0x38, 0x79, 0x78, 0x5a, 0xe0, 0x0d, 0xd6, 0x89, 0x42,
- 0xd2, 0xb0, 0x76, 0x2a, 0x46, 0xba, 0x47, 0x49, 0x64, 0x57, 0x96, 0x6b,
- 0xe4, 0xdd, 0xac, 0x73, 0xb8, 0x43, 0xe0, 0xe7, 0x16, 0xb4, 0x00, 0xb1,
- 0xfd, 0x6f, 0xac, 0x59, 0xff, 0x51, 0xae, 0x91, 0xc9, 0x42, 0x25, 0x42,
- 0x2d, 0xd4, 0x7c, 0x62, 0xb9, 0x9b, 0x58, 0x3e, 0x44, 0x3e, 0x8c, 0xd0,
- 0x13, 0x6c, 0x26, 0x96, 0x57, 0xb4, 0x19, 0xd9, 0x2e, 0xfa, 0x69, 0xcf,
- 0xea, 0x08, 0x71, 0x1a, 0xa7, 0x87, 0x1d, 0x41, 0x07, 0xe7, 0x4a, 0x4f,
- 0x1b, 0x91, 0x0e, 0xe2, 0x5f, 0x65, 0x9f, 0xd7, 0xd8, 0x67, 0xa1, 0x4e,
- 0x7a, 0xed, 0x00, 0x5e, 0x60, 0x1f, 0x33, 0xe9, 0xb8, 0x3a, 0x21, 0xf1,
- 0x3f, 0x86, 0x44, 0x46, 0xe2, 0xdf, 0x59, 0xd6, 0x4a, 0xdf, 0x2f, 0xf1,
- 0x4f, 0x0c, 0xe6, 0x89, 0xc1, 0x12, 0x07, 0x06, 0x24, 0x07, 0x6a, 0xe8,
- 0x2b, 0x4e, 0xd0, 0x57, 0x54, 0xd9, 0x51, 0xe2, 0x5f, 0xf2, 0xa1, 0xe4,
- 0x2d, 0xba, 0xca, 0x1c, 0x58, 0xef, 0xce, 0x27, 0x35, 0x20, 0x88, 0xa6,
- 0x49, 0x43, 0x57, 0x95, 0xff, 0x14, 0x4f, 0x98, 0xe6, 0xfc, 0x76, 0xfa,
- 0x83, 0x2f, 0xdb, 0x62, 0xcc, 0x7b, 0x10, 0xf7, 0x9c, 0x08, 0xa9, 0x12,
- 0xe7, 0xf5, 0x93, 0x41, 0x84, 0x26, 0x25, 0x0f, 0xb2, 0xe3, 0x11, 0x62,
- 0xc4, 0xf2, 0xfc, 0x96, 0xf8, 0x8f, 0x12, 0x17, 0xaa, 0xd2, 0xcd, 0x31,
- 0x6a, 0xa6, 0x74, 0xb4, 0x4e, 0x1a, 0x03, 0x27, 0x70, 0x55, 0xbc, 0x11,
- 0x33, 0x33, 0x7b, 0x99, 0xff, 0x6d, 0xc9, 0x18, 0xf7, 0x4a, 0xc7, 0xdd,
- 0x37, 0xc7, 0x70, 0x39, 0xe1, 0x6c, 0xb1, 0x82, 0x65, 0xaf, 0xad, 0x61,
- 0x4b, 0x1e, 0xd8, 0x96, 0xa7, 0xd9, 0x35, 0x3d, 0xab, 0xfc, 0xb8, 0x86,
- 0xc3, 0x44, 0x7f, 0xbf, 0xee, 0x30, 0xff, 0x01, 0xea, 0x7d, 0xe9, 0x9d,
- 0x92, 0x07, 0xff, 0x79, 0xf9, 0x8c, 0xf9, 0x2b, 0x4f, 0xe9, 0xef, 0xdb,
- 0xde, 0xc5, 0x33, 0xe7, 0x16, 0x62, 0xb0, 0x93, 0x18, 0xec, 0x61, 0x8e,
- 0xb6, 0x5b, 0xe4, 0x36, 0xf3, 0x99, 0x55, 0x03, 0xf4, 0xd4, 0x4d, 0x7d,
- 0xd5, 0xd4, 0xb4, 0x7d, 0xd4, 0xa7, 0x77, 0xcd, 0x4a, 0x7a, 0x70, 0x87,
- 0xda, 0xd9, 0x41, 0xdd, 0xec, 0x52, 0x1e, 0x72, 0xb1, 0x95, 0x26, 0x8e,
- 0x34, 0x25, 0x4d, 0x5f, 0xeb, 0x63, 0xed, 0x38, 0x14, 0x5e, 0xf4, 0xdf,
- 0x32, 0x4e, 0xe9, 0xb9, 0x8d, 0xb8, 0x2c, 0xbf, 0xcf, 0xba, 0x3a, 0xb4,
- 0x16, 0xaa, 0xbd, 0x56, 0x51, 0x6d, 0x79, 0xc6, 0x50, 0xf1, 0x03, 0xea,
- 0xec, 0xc2, 0x26, 0x79, 0xd6, 0xe0, 0xba, 0xd8, 0x16, 0x31, 0x63, 0xd1,
- 0x83, 0xc4, 0xd5, 0xab, 0xdf, 0x39, 0x7b, 0x94, 0xf0, 0x36, 0x9c, 0x57,
- 0x6f, 0xfa, 0x68, 0xa9, 0x0f, 0x6b, 0x6f, 0xe2, 0x4d, 0xc3, 0x33, 0x2d,
- 0x51, 0xe2, 0x51, 0x62, 0x4d, 0x43, 0xe1, 0x95, 0x4a, 0xbc, 0xf1, 0x4a,
- 0x10, 0xaf, 0xbf, 0x22, 0xc4, 0x68, 0x12, 0x3c, 0xe1, 0x08, 0xf1, 0x50,
- 0x72, 0x0d, 0x8e, 0xeb, 0xb1, 0xe8, 0x0b, 0xae, 0x8f, 0x75, 0xe8, 0x63,
- 0x8d, 0x81, 0xb3, 0xb8, 0x21, 0x0a, 0x2e, 0xa7, 0x13, 0xe4, 0x5b, 0x09,
- 0x8b, 0xae, 0xdf, 0xad, 0xd5, 0x70, 0x81, 0xf8, 0x0b, 0x11, 0x7f, 0xbf,
- 0xa3, 0xe6, 0x5e, 0x2d, 0x6b, 0xee, 0xaa, 0x02, 0xf9, 0xd8, 0x16, 0x40,
- 0x8f, 0x5c, 0x0b, 0x71, 0x38, 0x7c, 0x13, 0x87, 0xac, 0xbd, 0xdc, 0xf3,
- 0xb3, 0x96, 0x11, 0xef, 0x24, 0x1e, 0x67, 0x2c, 0xc3, 0xe9, 0xa0, 0x9f,
- 0x1d, 0x76, 0x31, 0x49, 0xed, 0x8d, 0x49, 0x5c, 0x12, 0x87, 0xcc, 0xc9,
- 0x3e, 0xf6, 0x39, 0xcd, 0x3e, 0x63, 0x65, 0x3f, 0xfb, 0x1e, 0x12, 0x69,
- 0xe9, 0x67, 0xa3, 0xc4, 0xe0, 0x3e, 0xd7, 0xcf, 0x4a, 0xff, 0x2a, 0xbd,
- 0xab, 0x8c, 0xb3, 0xdd, 0x8d, 0xb3, 0xfb, 0x26, 0x0e, 0xa9, 0x61, 0xb5,
- 0x12, 0x7f, 0x0f, 0x60, 0xec, 0xa5, 0x1a, 0x84, 0xcc, 0x3b, 0x71, 0x3e,
- 0xf3, 0x80, 0x1a, 0x31, 0xa1, 0xd7, 0xdb, 0x25, 0x3c, 0x6e, 0x2e, 0xa6,
- 0x90, 0xcf, 0xbf, 0x23, 0xf2, 0x61, 0xc3, 0x39, 0xeb, 0x7a, 0xd2, 0x01,
- 0x7a, 0xc4, 0x1b, 0xc2, 0x13, 0x33, 0xce, 0x6d, 0xa1, 0x2f, 0x6b, 0xf2,
- 0x96, 0xfc, 0xdd, 0x9a, 0xc2, 0xfb, 0x02, 0x75, 0xa5, 0x75, 0xaa, 0xf4,
- 0x74, 0x23, 0xe4, 0xdc, 0xa8, 0x59, 0xf2, 0x77, 0xb1, 0xc2, 0xa7, 0xaa,
- 0xd4, 0x73, 0x4f, 0x9b, 0x1c, 0x37, 0x4d, 0x0d, 0x59, 0x1c, 0xfb, 0x1b,
- 0x5d, 0x1e, 0x21, 0x06, 0x87, 0xa5, 0xd7, 0xa2, 0x2f, 0xe1, 0x59, 0x7d,
- 0x89, 0xa6, 0xee, 0xf6, 0xc2, 0x94, 0x6d, 0x8e, 0xf2, 0x10, 0xd7, 0xa0,
- 0x99, 0x83, 0x4a, 0x9a, 0xb5, 0x79, 0x2f, 0xf1, 0xd5, 0xc3, 0x1a, 0x7c,
- 0xd9, 0x6a, 0x26, 0x87, 0x05, 0xeb, 0xd0, 0x0d, 0xb1, 0xcf, 0x5c, 0x3c,
- 0xd3, 0xc9, 0xf3, 0x5c, 0x9c, 0x71, 0x57, 0xb3, 0x76, 0xaf, 0x63, 0xbd,
- 0xe6, 0x69, 0x91, 0x39, 0xfd, 0x32, 0x26, 0x1a, 0x57, 0xb5, 0x19, 0x03,
- 0x1b, 0xbd, 0x01, 0xe4, 0x88, 0xf7, 0x57, 0x59, 0x83, 0xf2, 0xdc, 0xd3,
- 0xc9, 0xa2, 0x91, 0xca, 0x62, 0x04, 0x1b, 0xb9, 0xa7, 0x3c, 0x03, 0x39,
- 0xff, 0x18, 0x2b, 0x9d, 0x91, 0xb7, 0xb3, 0xb6, 0x8d, 0x97, 0xb9, 0x7d,
- 0x05, 0x09, 0x4b, 0x72, 0x7b, 0x9e, 0xb5, 0x6d, 0xdc, 0xe5, 0xb6, 0x91,
- 0x92, 0x7c, 0xae, 0x28, 0xd7, 0xb4, 0x4f, 0x20, 0x39, 0x7c, 0x6b, 0x3d,
- 0x93, 0x78, 0x5e, 0xeb, 0x93, 0xde, 0x36, 0x9f, 0x97, 0x35, 0x49, 0xd6,
- 0xa2, 0xc5, 0xba, 0xa4, 0xc9, 0xfb, 0x84, 0x4c, 0xe3, 0xc4, 0x1e, 0xe1,
- 0x29, 0xdd, 0x49, 0x9c, 0xfb, 0xd0, 0x1b, 0x4c, 0xa5, 0xee, 0x43, 0x26,
- 0x32, 0xa7, 0x61, 0x53, 0xbe, 0xa1, 0x2f, 0x60, 0x83, 0xef, 0x28, 0xb0,
- 0xfe, 0x44, 0x43, 0xe6, 0x96, 0x3b, 0x89, 0x8f, 0x73, 0x9a, 0x16, 0x9a,
- 0x58, 0x2e, 0xdf, 0xc1, 0x67, 0xb9, 0xdb, 0xde, 0x49, 0xa4, 0x7f, 0xdf,
- 0x9d, 0xc4, 0x0b, 0xe4, 0xc7, 0x58, 0xe9, 0x4e, 0xc2, 0xf9, 0x5e, 0x8b,
- 0x17, 0x33, 0x61, 0xec, 0xfe, 0xa8, 0x5d, 0xc5, 0xe5, 0x9c, 0x11, 0x39,
- 0x8e, 0xdd, 0xe8, 0x77, 0xef, 0x1f, 0x90, 0xf5, 0xdb, 0xbb, 0xf0, 0x4f,
- 0xed, 0xf2, 0xfe, 0x21, 0x25, 0xd7, 0x38, 0xce, 0xe5, 0x43, 0xa3, 0xde,
- 0xac, 0x67, 0x2d, 0xd8, 0xb1, 0x46, 0xc1, 0x43, 0xc9, 0x3b, 0x5d, 0x6c,
- 0x8f, 0x17, 0x8d, 0x74, 0x94, 0xcf, 0xee, 0x99, 0x90, 0x35, 0xf2, 0x71,
- 0x9e, 0x17, 0xa1, 0x35, 0xda, 0xbd, 0xaa, 0xc8, 0x37, 0x45, 0xae, 0x28,
- 0x86, 0x73, 0x18, 0xf2, 0x8e, 0x20, 0x71, 0xce, 0xab, 0x18, 0xf3, 0x1f,
- 0x7a, 0x8d, 0x54, 0xbd, 0x8b, 0x99, 0xc7, 0x79, 0x76, 0x93, 0x7f, 0x7b,
- 0xe5, 0xb9, 0x0f, 0x1b, 0x39, 0xe6, 0x07, 0x6b, 0xe4, 0x59, 0xf4, 0x73,
- 0x91, 0x5d, 0x66, 0x38, 0x0b, 0x8a, 0xc6, 0xdc, 0x80, 0xfa, 0x24, 0x35,
- 0xfc, 0x71, 0x6a, 0xb8, 0xf4, 0x2c, 0xbd, 0xf4, 0x2c, 0x4d, 0xf3, 0x71,
- 0xaf, 0x91, 0xb9, 0x4e, 0xbd, 0xe3, 0x98, 0x7d, 0xbd, 0x8a, 0xd1, 0x7b,
- 0x82, 0xfa, 0xbf, 0x53, 0x29, 0x8d, 0xb9, 0xb2, 0x3c, 0xe6, 0xdd, 0x05,
- 0x4d, 0xe9, 0xcc, 0x83, 0xba, 0x83, 0xe8, 0x36, 0x8b, 0xda, 0x51, 0xac,
- 0x24, 0xc7, 0x4c, 0xb9, 0x66, 0xc6, 0xd6, 0xca, 0xd8, 0x14, 0x5c, 0x69,
- 0x91, 0xef, 0xb6, 0xca, 0x38, 0x9c, 0x2a, 0x3b, 0x45, 0xed, 0x7d, 0xc5,
- 0x57, 0xd6, 0x2f, 0xcf, 0x16, 0x6b, 0x19, 0x9c, 0x30, 0x42, 0x3e, 0xb3,
- 0x0e, 0xa3, 0xb4, 0x81, 0x41, 0xb3, 0x19, 0x39, 0xdd, 0x8f, 0x2d, 0xd6,
- 0x17, 0x82, 0x3a, 0xc9, 0xf7, 0x81, 0xa7, 0x5e, 0xe2, 0x19, 0xde, 0xbc,
- 0x86, 0x58, 0xf2, 0x39, 0x1c, 0xd3, 0x77, 0xd1, 0x0f, 0x6e, 0xc5, 0xeb,
- 0xae, 0x9e, 0xd8, 0xc4, 0xb3, 0x42, 0x0c, 0xd9, 0xb2, 0xd6, 0xdd, 0x32,
- 0xb6, 0xbc, 0x93, 0xb8, 0x24, 0xb2, 0xa5, 0x31, 0x9c, 0x6d, 0x56, 0x86,
- 0x71, 0x7d, 0xa3, 0xbb, 0x3b, 0xa8, 0xbb, 0x15, 0xa6, 0xe7, 0xae, 0x4a,
- 0xea, 0xee, 0x56, 0xeb, 0xcf, 0xf1, 0x14, 0x39, 0x5e, 0x65, 0x7e, 0x26,
- 0x9e, 0x0e, 0xcb, 0x31, 0xa9, 0xaf, 0x35, 0x4b, 0xc7, 0xff, 0x90, 0x63,
- 0xca, 0x39, 0x64, 0x3d, 0x3c, 0x2f, 0x0e, 0xd5, 0xca, 0x31, 0x07, 0x95,
- 0x8d, 0xe4, 0xd4, 0x3c, 0x4b, 0xef, 0x0f, 0xc8, 0xa7, 0x05, 0xe6, 0xa7,
- 0xf1, 0x36, 0x7c, 0x6a, 0x24, 0x9f, 0x9e, 0x58, 0xc2, 0xa7, 0x83, 0x79,
- 0xe9, 0xbd, 0x14, 0xb4, 0xb4, 0xfd, 0x29, 0x75, 0x45, 0x08, 0x7f, 0xdb,
- 0x0d, 0x71, 0xc6, 0xf5, 0xbe, 0xd2, 0xef, 0xa6, 0x95, 0xee, 0x59, 0xa9,
- 0x4f, 0xd5, 0x08, 0x92, 0x4f, 0x1b, 0xc8, 0xa7, 0x7e, 0xf2, 0xe9, 0x69,
- 0x53, 0x34, 0xee, 0x48, 0x1a, 0xa9, 0x79, 0xfa, 0x9a, 0x75, 0xe4, 0xd4,
- 0x3b, 0xe4, 0xd4, 0x48, 0xb1, 0xa4, 0x53, 0xfb, 0xb8, 0xee, 0xfb, 0xa9,
- 0x53, 0xeb, 0x8a, 0x52, 0xdb, 0x1c, 0xe2, 0x3f, 0x80, 0xcf, 0xc9, 0xa9,
- 0xd9, 0xa4, 0xab, 0x53, 0xd6, 0xef, 0x90, 0xd8, 0x75, 0x5a, 0xf2, 0x89,
- 0x3a, 0x95, 0x2f, 0x36, 0x59, 0xa7, 0xb9, 0xa6, 0xf1, 0xbc, 0x71, 0xbd,
- 0x87, 0x9c, 0xf2, 0xb5, 0x1b, 0xe7, 0x2e, 0x13, 0xbb, 0x81, 0x18, 0xf4,
- 0x88, 0x2d, 0xd7, 0xc4, 0x1a, 0xcb, 0x3a, 0x79, 0x90, 0xf8, 0xef, 0xa1,
- 0x66, 0xf4, 0x16, 0x6d, 0xec, 0x2d, 0x2e, 0xdd, 0x53, 0xd6, 0xa1, 0xdb,
- 0xee, 0xcb, 0xb8, 0xff, 0xf6, 0xed, 0xac, 0x57, 0xb7, 0x6d, 0x97, 0x7c,
- 0x5d, 0xe6, 0x97, 0x7c, 0x1d, 0xce, 0xbf, 0xa6, 0xde, 0xfe, 0x1d, 0x79,
- 0xa7, 0x26, 0xc4, 0x51, 0x4b, 0xde, 0x49, 0x48, 0xdf, 0xa3, 0x60, 0xc8,
- 0x92, 0xf7, 0x6a, 0x1d, 0x51, 0x15, 0x46, 0xe4, 0xfb, 0xf8, 0x4a, 0x64,
- 0xc3, 0x4e, 0xdc, 0xe7, 0xd6, 0x48, 0x43, 0xef, 0x63, 0xad, 0x9b, 0x2f,
- 0x9f, 0xfd, 0x66, 0x78, 0x3e, 0x7b, 0x87, 0x75, 0xea, 0x28, 0xcf, 0x79,
- 0x43, 0x85, 0xaf, 0xc4, 0x7c, 0x58, 0xc5, 0x88, 0x79, 0xf3, 0x8e, 0xd2,
- 0xd5, 0xb1, 0xc3, 0x7c, 0x36, 0x56, 0x58, 0xac, 0x51, 0xd4, 0x4c, 0x53,
- 0x88, 0xad, 0xe6, 0x7f, 0x8b, 0x2d, 0xdf, 0x7a, 0x57, 0x88, 0x49, 0xc6,
- 0x70, 0xc1, 0xc2, 0x6e, 0x1f, 0x62, 0x7d, 0xd7, 0x59, 0xd7, 0x3f, 0x58,
- 0x63, 0x64, 0x0a, 0x4a, 0xa2, 0x77, 0x83, 0x22, 0xbd, 0x9e, 0xa7, 0xab,
- 0x82, 0xef, 0xb4, 0xd0, 0x1b, 0x5d, 0x61, 0x06, 0xfd, 0xfc, 0x7e, 0xc6,
- 0x32, 0x22, 0x47, 0xf8, 0x77, 0x4b, 0x4a, 0x8e, 0x21, 0x44, 0x87, 0x25,
- 0xef, 0xbb, 0x46, 0xd4, 0xdc, 0x44, 0x56, 0x54, 0x99, 0x17, 0xa8, 0x4d,
- 0x46, 0x66, 0x44, 0x91, 0x3e, 0x3b, 0x0a, 0x57, 0x67, 0xf9, 0x4c, 0x9b,
- 0x88, 0xe0, 0xef, 0x5d, 0xff, 0x1c, 0xa5, 0x66, 0x35, 0xe0, 0x1f, 0x5c,
- 0xdd, 0x52, 0xb1, 0xed, 0x25, 0x23, 0xa5, 0x2a, 0x7b, 0x70, 0xc9, 0x32,
- 0xf4, 0x9f, 0x32, 0x6e, 0x6a, 0xcd, 0x8b, 0x9d, 0x3c, 0x3f, 0x71, 0x8e,
- 0x6c, 0x9f, 0xb7, 0x56, 0xd1, 0x58, 0x3b, 0x7e, 0xdc, 0x22, 0x6b, 0xf7,
- 0x2e, 0xf4, 0x34, 0xef, 0xe4, 0x47, 0x45, 0xdd, 0x94, 0xaa, 0x6c, 0xa2,
- 0x27, 0x09, 0x4d, 0x85, 0xb0, 0x7d, 0xb5, 0x10, 0xab, 0x56, 0x3b, 0xf8,
- 0x3c, 0xd9, 0x14, 0x3f, 0xcb, 0x1a, 0x74, 0xa8, 0xd6, 0x48, 0x03, 0xbf,
- 0xc0, 0x66, 0x7a, 0xd9, 0x54, 0x5b, 0x0e, 0xb8, 0x53, 0xae, 0xf1, 0x17,
- 0xe8, 0x94, 0x1e, 0xd8, 0x0a, 0x49, 0xbf, 0xe5, 0xe2, 0xb7, 0x74, 0xaf,
- 0xc4, 0xd4, 0x1d, 0xc8, 0x8a, 0x4a, 0xd3, 0xe8, 0x9b, 0x65, 0xbd, 0xfd,
- 0x20, 0xb6, 0x5c, 0x7f, 0x78, 0x56, 0x7a, 0x60, 0x33, 0xba, 0x5e, 0x11,
- 0xcc, 0xc5, 0xf3, 0xcc, 0x45, 0xcc, 0x09, 0xd2, 0x32, 0xf0, 0xac, 0xe5,
- 0x84, 0x94, 0x41, 0xe5, 0x51, 0xf2, 0xa1, 0xcf, 0x5f, 0x49, 0x0f, 0xe1,
- 0xd0, 0x3f, 0x78, 0x50, 0x7d, 0x40, 0x7a, 0x8a, 0x00, 0xb5, 0xa6, 0xa9,
- 0x37, 0xc8, 0xfc, 0xec, 0x48, 0x4a, 0xff, 0x41, 0xac, 0x1f, 0xb8, 0x21,
- 0x3a, 0xe9, 0x71, 0x3b, 0xcb, 0x1e, 0xf7, 0x89, 0xe9, 0x34, 0x3d, 0xb0,
- 0xa6, 0xc8, 0x3b, 0xb6, 0x54, 0x1b, 0x0f, 0xa4, 0x8f, 0x4a, 0x1f, 0x22,
- 0xd7, 0xa0, 0xe3, 0x6a, 0x52, 0x62, 0x57, 0xc7, 0x70, 0xbb, 0x11, 0xc9,
- 0x42, 0xde, 0xe9, 0xdc, 0xea, 0x2f, 0xa0, 0xa7, 0xbf, 0xe3, 0x39, 0xa0,
- 0x6f, 0x62, 0x2c, 0x86, 0x5f, 0x88, 0xba, 0xa4, 0x17, 0x7d, 0xee, 0x59,
- 0x2e, 0xa2, 0xa7, 0xc9, 0xfb, 0x73, 0xf4, 0x09, 0x5e, 0x9e, 0x99, 0xf7,
- 0x10, 0x4b, 0x5f, 0xb6, 0x0c, 0xbd, 0x5a, 0x8f, 0xec, 0x78, 0x1d, 0xcf,
- 0xa8, 0xf7, 0x53, 0x57, 0x2f, 0xe4, 0x1e, 0x65, 0x3d, 0xf7, 0xb4, 0x47,
- 0x78, 0x06, 0x68, 0x9c, 0xca, 0x8a, 0x7a, 0xfa, 0x41, 0x9e, 0x97, 0x51,
- 0xdb, 0x16, 0xa7, 0xdf, 0x5e, 0xdc, 0x2b, 0x0f, 0x7e, 0x68, 0x99, 0x70,
- 0xdc, 0xdf, 0x41, 0xbd, 0x7b, 0x9a, 0xe7, 0x68, 0x73, 0xb9, 0xde, 0x51,
- 0x8a, 0x4b, 0xad, 0xb0, 0x2d, 0xb4, 0xdc, 0x0b, 0xfd, 0xc1, 0xdb, 0xc4,
- 0xb4, 0x4e, 0x7a, 0x1f, 0x5f, 0xa9, 0xdf, 0x9f, 0x4d, 0x37, 0xe8, 0x8f,
- 0xb0, 0xde, 0xcd, 0x13, 0x2b, 0x4f, 0xac, 0xb6, 0x64, 0x2c, 0xf3, 0x32,
- 0x16, 0xfa, 0x4b, 0xe7, 0x7e, 0x0f, 0x7d, 0x49, 0x12, 0x08, 0xcd, 0xfd,
- 0x35, 0x79, 0xe5, 0x69, 0x0d, 0x21, 0xbb, 0x8b, 0x31, 0xbe, 0xfa, 0xaf,
- 0xdc, 0x9a, 0xfe, 0x49, 0xf4, 0x7b, 0xd8, 0x67, 0xc2, 0x02, 0x9e, 0x39,
- 0x01, 0x3c, 0x3d, 0x19, 0xa3, 0x2f, 0xa7, 0x8f, 0x3c, 0xa1, 0xe1, 0xfb,
- 0xd3, 0x95, 0xf8, 0xd1, 0x74, 0x10, 0x3b, 0xa6, 0xdd, 0xbb, 0xae, 0x0d,
- 0x75, 0x7c, 0xaf, 0x83, 0x67, 0xbb, 0x59, 0x6b, 0x35, 0x3e, 0xa2, 0x87,
- 0x5a, 0xa1, 0x78, 0x10, 0x39, 0x00, 0x5d, 0x27, 0x6e, 0x6a, 0x5b, 0x7e,
- 0x44, 0x2e, 0x0b, 0x61, 0xae, 0x96, 0x3a, 0xf9, 0xbc, 0xfb, 0x7d, 0x84,
- 0xfe, 0x31, 0x23, 0x31, 0x98, 0x27, 0x06, 0xf3, 0xc4, 0xe4, 0x4d, 0x4f,
- 0x2d, 0xb1, 0x1c, 0xa7, 0x8f, 0x7e, 0x4e, 0x94, 0xb0, 0xf1, 0xb5, 0x38,
- 0x6a, 0x9e, 0x24, 0x7f, 0x55, 0x6a, 0x28, 0xf0, 0xcf, 0xb9, 0x88, 0xbe,
- 0xa9, 0x28, 0xf3, 0xff, 0xb7, 0xe5, 0xfc, 0x9f, 0xf1, 0x97, 0xf4, 0xc2,
- 0x70, 0x66, 0xd1, 0x80, 0xc9, 0x7c, 0x83, 0xbe, 0x21, 0x3f, 0x34, 0xa8,
- 0x21, 0x1b, 0x0d, 0xc1, 0x18, 0x98, 0x84, 0xa7, 0x35, 0x08, 0xb9, 0x76,
- 0xa0, 0xe0, 0xae, 0x51, 0x88, 0x31, 0xea, 0x9b, 0xcc, 0xc1, 0xbf, 0xe7,
- 0xd0, 0xea, 0x61, 0x3e, 0x1c, 0xc8, 0xb3, 0x35, 0xf0, 0x69, 0x41, 0xde,
- 0x7d, 0xc6, 0xd2, 0xdd, 0xf8, 0xc2, 0x1d, 0xf3, 0x93, 0x42, 0x0a, 0xfb,
- 0xf3, 0x1f, 0x88, 0xfd, 0xe1, 0x92, 0xc6, 0xa7, 0x79, 0x3e, 0x0a, 0x1d,
- 0x28, 0x7b, 0x21, 0x72, 0xb8, 0x9a, 0xeb, 0xbd, 0x9a, 0x74, 0xbd, 0x3f,
- 0x6b, 0xe4, 0x80, 0x7a, 0xd4, 0x64, 0xb1, 0xab, 0xb9, 0x21, 0xc6, 0x62,
- 0x89, 0x40, 0x29, 0xa6, 0x84, 0x7e, 0x04, 0x15, 0xc4, 0xae, 0x3c, 0x23,
- 0x49, 0xfd, 0x90, 0xbf, 0x79, 0x3e, 0x51, 0x9d, 0x88, 0x97, 0xeb, 0x72,
- 0x1e, 0x93, 0x6d, 0x81, 0xb2, 0x5f, 0x5d, 0xf4, 0x22, 0x1d, 0x7c, 0x26,
- 0xbd, 0xc8, 0x57, 0xa2, 0x2f, 0xdc, 0x71, 0x53, 0x73, 0xb2, 0x7c, 0x63,
- 0x34, 0x2f, 0xef, 0xb4, 0x5a, 0xe8, 0x88, 0x15, 0x9c, 0x62, 0xe4, 0x47,
- 0x5a, 0x63, 0xfa, 0x30, 0xc7, 0x73, 0x74, 0x9d, 0x5c, 0xde, 0x43, 0xbf,
- 0xcc, 0x77, 0x8a, 0x2d, 0xec, 0x23, 0xb5, 0xec, 0x2f, 0xb8, 0xd6, 0x2f,
- 0x9a, 0x25, 0xb6, 0x87, 0xf3, 0x6f, 0x79, 0x54, 0x53, 0xae, 0x33, 0x91,
- 0x1a, 0x66, 0x3c, 0x0b, 0xba, 0xf4, 0xd6, 0x0e, 0xb5, 0x2d, 0xe1, 0xf6,
- 0xcf, 0xaa, 0x32, 0x0e, 0x37, 0x1e, 0xb6, 0x49, 0xcd, 0x32, 0x32, 0xa7,
- 0x90, 0x70, 0xfa, 0xa5, 0x39, 0x58, 0x26, 0x63, 0x68, 0x8a, 0xf4, 0x33,
- 0x9e, 0x43, 0x61, 0x57, 0x0f, 0xf9, 0x8c, 0xf3, 0xe5, 0x3d, 0x1b, 0x2a,
- 0x21, 0xb0, 0x22, 0xe9, 0x9e, 0xf9, 0xcb, 0xff, 0x5f, 0x43, 0xa5, 0x0f,
- 0x91, 0x58, 0xfc, 0x5f, 0x69, 0xd7, 0x8a, 0xc0, 0xa8, 0x1a, 0x00, 0x00,
- 0x00 };
+ 0xbd, 0x58, 0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xce, 0xbd, 0x77, 0xb5,
+ 0xd7, 0xd2, 0x4a, 0xba, 0xb2, 0xd6, 0x66, 0x5d, 0xdc, 0xfa, 0x1e, 0x74,
+ 0x57, 0x52, 0x58, 0x01, 0x77, 0x6d, 0x01, 0xeb, 0xe6, 0xb6, 0xbe, 0xc8,
+ 0xb2, 0xbc, 0xfe, 0x00, 0xe4, 0xc0, 0x4c, 0xe4, 0x96, 0x8e, 0x37, 0xc6,
+ 0x18, 0xd9, 0x90, 0xa9, 0x28, 0xfc, 0x58, 0x37, 0x4c, 0xbd, 0x95, 0x65,
+ 0x63, 0xc3, 0x4a, 0x6b, 0x0c, 0xb1, 0x4c, 0xda, 0x99, 0x78, 0x84, 0xb1,
+ 0x4c, 0x22, 0x7b, 0x0d, 0xe4, 0x07, 0x49, 0xc3, 0xa0, 0xc1, 0x0e, 0x08,
+ 0x06, 0xf3, 0x31, 0x6d, 0x67, 0x98, 0xe9, 0xa4, 0xf5, 0x18, 0xf3, 0x11,
+ 0x92, 0x18, 0x87, 0x4e, 0x3a, 0xa2, 0x10, 0x9f, 0x3e, 0x67, 0x77, 0xc5,
+ 0x57, 0x32, 0xd3, 0xfe, 0xaa, 0x66, 0x56, 0x7b, 0xf7, 0xec, 0xf9, 0x78,
+ 0xcf, 0xfb, 0x3e, 0xef, 0xf3, 0x3e, 0xef, 0x5e, 0x21, 0x50, 0x8f, 0xda,
+ 0x5f, 0x23, 0x5f, 0xdd, 0xdf, 0x1a, 0xba, 0x2f, 0x7d, 0xf5, 0x75, 0x57,
+ 0xf3, 0xf1, 0x3a, 0xe1, 0xd4, 0x59, 0xf8, 0x7f, 0xfc, 0x33, 0x01, 0x67,
+ 0xce, 0x0e, 0xfd, 0x82, 0x6d, 0x04, 0x85, 0xcb, 0x7b, 0x3c, 0xd8, 0x66,
+ 0x10, 0x77, 0x6f, 0xf7, 0x80, 0x70, 0x2a, 0xe5, 0xae, 0xc4, 0xef, 0x54,
+ 0x21, 0x6e, 0x41, 0x8f, 0xff, 0x71, 0xf0, 0xe9, 0x35, 0xcf, 0x5d, 0x2f,
+ 0x2f, 0x1e, 0x36, 0x61, 0x3b, 0xc1, 0x5e, 0xcb, 0x69, 0x87, 0xbd, 0x98,
+ 0x6b, 0xfe, 0xb1, 0xe3, 0x2f, 0x04, 0x9a, 0xe6, 0xf6, 0x52, 0x6a, 0xc4,
+ 0x8f, 0x62, 0xd8, 0x4f, 0x60, 0x77, 0xc9, 0x40, 0xe8, 0x44, 0xb1, 0xcb,
+ 0x9b, 0x55, 0x5b, 0x7c, 0xe9, 0xef, 0x86, 0x5a, 0x72, 0xda, 0x97, 0x89,
+ 0x5e, 0x13, 0xe1, 0x77, 0xbc, 0xc5, 0xd8, 0x5d, 0x4e, 0x60, 0xa4, 0x6c,
+ 0xe3, 0xac, 0x39, 0x82, 0xde, 0xf2, 0xdc, 0x3a, 0x97, 0xeb, 0x3a, 0xb1,
+ 0xe7, 0xcb, 0x6b, 0xdd, 0xdd, 0x48, 0x25, 0xf6, 0xc0, 0x40, 0x2e, 0xee,
+ 0x71, 0x5d, 0x9b, 0xbb, 0x07, 0xb2, 0x93, 0xfb, 0x14, 0xea, 0xba, 0x5d,
+ 0xee, 0x51, 0xe0, 0x7a, 0xe9, 0x1e, 0x85, 0xde, 0x2b, 0xc3, 0xcf, 0x6f,
+ 0xa9, 0xe7, 0x3a, 0x16, 0xe3, 0x19, 0xee, 0xff, 0x74, 0xd9, 0xc1, 0xc9,
+ 0xb2, 0x87, 0xe7, 0xcb, 0x2e, 0x7e, 0x54, 0x8e, 0xe3, 0xa9, 0xb2, 0x9d,
+ 0xb3, 0x03, 0xf4, 0xc7, 0x47, 0x77, 0xaa, 0x84, 0x87, 0xc2, 0x1f, 0x05,
+ 0xde, 0xa1, 0x43, 0x46, 0x2c, 0xf3, 0x37, 0xd7, 0xa1, 0x7f, 0xfe, 0x71,
+ 0x1b, 0x1b, 0x4a, 0x8b, 0x73, 0xd1, 0x00, 0x9c, 0x23, 0xe0, 0x5f, 0x67,
+ 0xa3, 0x9f, 0x7b, 0x14, 0xb8, 0x7f, 0x58, 0x1e, 0xe1, 0xcb, 0xc6, 0xbb,
+ 0x45, 0xdb, 0x6e, 0x1e, 0x5d, 0xa8, 0xe7, 0xe0, 0x57, 0xc5, 0x8b, 0xea,
+ 0x42, 0xda, 0xc1, 0x2b, 0xcb, 0x95, 0x6a, 0x0c, 0x50, 0x68, 0xe8, 0x2e,
+ 0xc0, 0x0c, 0x64, 0x76, 0x9d, 0x29, 0xd0, 0x7b, 0x95, 0xd7, 0x39, 0x2a,
+ 0x6e, 0xb9, 0xc5, 0x08, 0x60, 0x8b, 0xc0, 0xb5, 0xda, 0xa6, 0x32, 0xd8,
+ 0x57, 0xe6, 0xbd, 0x68, 0xcf, 0x48, 0x19, 0xe1, 0x5f, 0x76, 0x98, 0x98,
+ 0x88, 0xe3, 0xfe, 0xb7, 0xbb, 0x2d, 0x7c, 0x5c, 0x94, 0x89, 0x4e, 0xf3,
+ 0x7e, 0xec, 0x2c, 0xe6, 0x71, 0x47, 0x11, 0x05, 0x23, 0x18, 0xc2, 0x37,
+ 0xba, 0x03, 0xde, 0x33, 0xc4, 0xf7, 0xcb, 0xb0, 0x5b, 0x83, 0xd3, 0x97,
+ 0xdf, 0xdb, 0x2e, 0x0f, 0x87, 0x06, 0x90, 0x1d, 0x03, 0xfa, 0x4a, 0x02,
+ 0xa7, 0x32, 0x02, 0x5b, 0xfc, 0xcb, 0x50, 0x70, 0xba, 0xb1, 0xb7, 0x2c,
+ 0xb3, 0x05, 0x7e, 0x77, 0xd5, 0x28, 0xec, 0x45, 0xc1, 0x6d, 0xd6, 0xf2,
+ 0x12, 0xec, 0x96, 0x60, 0xc0, 0x4a, 0x8f, 0xb5, 0xcd, 0x1e, 0x13, 0x32,
+ 0xbf, 0xc2, 0x94, 0x21, 0x20, 0x33, 0x9d, 0x46, 0xaa, 0xa0, 0x84, 0x1c,
+ 0xba, 0x08, 0x6d, 0xd3, 0x6d, 0xd6, 0x35, 0x53, 0xfa, 0x7d, 0xc0, 0xba,
+ 0x7a, 0x0a, 0x58, 0xcf, 0x3d, 0x1f, 0x5a, 0x2e, 0xb0, 0x3d, 0xfd, 0x6b,
+ 0x15, 0x2e, 0x90, 0xe1, 0x61, 0xd1, 0x8d, 0xd1, 0x32, 0x70, 0xd3, 0x18,
+ 0xec, 0x18, 0xe7, 0x16, 0xb9, 0x77, 0x3d, 0xe7, 0xae, 0x1d, 0x6d, 0x1b,
+ 0x9c, 0x11, 0x92, 0x77, 0x93, 0x03, 0x40, 0xca, 0x3f, 0x0e, 0xe9, 0xae,
+ 0x13, 0xd2, 0xd9, 0x53, 0xdb, 0x33, 0x59, 0xdb, 0xf3, 0x8a, 0x29, 0x5b,
+ 0xac, 0x2a, 0x41, 0xf4, 0x96, 0xe0, 0x3e, 0xe9, 0x83, 0x77, 0x89, 0xf1,
+ 0xde, 0xf5, 0x70, 0x5b, 0xa4, 0x7f, 0x98, 0x73, 0xa3, 0x41, 0x97, 0xf5,
+ 0x5e, 0x51, 0xe0, 0x43, 0x4f, 0xcf, 0xef, 0xd2, 0xb6, 0x84, 0x4e, 0x90,
+ 0x11, 0xfd, 0xe5, 0xfd, 0x73, 0x39, 0x62, 0x9c, 0xf4, 0xe3, 0xc0, 0x42,
+ 0x34, 0xb7, 0x78, 0xf3, 0xf1, 0xb0, 0x83, 0xc6, 0xa8, 0xb7, 0xcc, 0x78,
+ 0xc0, 0xa9, 0xc3, 0x49, 0xff, 0xb7, 0x0a, 0xdf, 0xd0, 0xf3, 0x81, 0x6f,
+ 0x3f, 0xe2, 0x20, 0xe6, 0x5d, 0xc4, 0xd1, 0xf4, 0x36, 0xe3, 0x55, 0x67,
+ 0x08, 0x4d, 0xde, 0xcf, 0x8d, 0xd7, 0x9c, 0x38, 0x1e, 0xe2, 0x7d, 0xee,
+ 0x4c, 0xc6, 0xf1, 0x40, 0xf9, 0xab, 0xfb, 0x5a, 0x22, 0x3b, 0xfe, 0x8e,
+ 0x42, 0x4b, 0x65, 0x7d, 0xf8, 0xac, 0x3f, 0x01, 0x5c, 0xa6, 0xc7, 0xf3,
+ 0x62, 0x63, 0xe9, 0x92, 0x72, 0xa3, 0x19, 0x3c, 0x50, 0xb2, 0x31, 0x8f,
+ 0x76, 0x45, 0x3c, 0x1b, 0x6f, 0x17, 0xf3, 0x62, 0x55, 0x39, 0x14, 0x6b,
+ 0x26, 0x7b, 0x44, 0x38, 0x69, 0x89, 0x9e, 0x71, 0x10, 0x9b, 0x4a, 0xad,
+ 0xf1, 0x05, 0xfe, 0xc3, 0xff, 0x57, 0xe3, 0x6c, 0xab, 0x0c, 0x5d, 0x71,
+ 0x49, 0x79, 0x49, 0x03, 0xf5, 0x5e, 0x9f, 0x58, 0x3b, 0xa9, 0xd4, 0x5e,
+ 0x3f, 0x2b, 0x7a, 0x27, 0x61, 0x37, 0x04, 0x81, 0x75, 0xd7, 0xe8, 0x69,
+ 0x23, 0xb7, 0x20, 0x86, 0x52, 0xc9, 0xc5, 0x29, 0x5f, 0xe3, 0x77, 0x1e,
+ 0x2c, 0x4f, 0xf0, 0x85, 0xd8, 0x19, 0x1f, 0x56, 0x8c, 0xcf, 0x53, 0x1b,
+ 0x2c, 0x8c, 0x74, 0xaf, 0xad, 0xac, 0x89, 0x10, 0x2b, 0x4f, 0x14, 0xb3,
+ 0x30, 0x88, 0xbf, 0x45, 0x41, 0x72, 0x76, 0x82, 0x98, 0x7f, 0xcb, 0x4f,
+ 0x76, 0x7e, 0x6c, 0x92, 0x1c, 0x5a, 0x65, 0x82, 0x86, 0x0a, 0x2b, 0x48,
+ 0x76, 0x1e, 0x81, 0x80, 0xe9, 0x59, 0x78, 0xc5, 0x8f, 0x20, 0xdc, 0x60,
+ 0x63, 0x17, 0x71, 0x55, 0xc7, 0xf1, 0xa3, 0x95, 0x71, 0xfd, 0x19, 0xce,
+ 0xaa, 0xf2, 0x57, 0x73, 0x9e, 0xe3, 0xa5, 0x36, 0xe4, 0x2a, 0x79, 0x0f,
+ 0x67, 0x1d, 0xef, 0xfb, 0xad, 0x88, 0x7e, 0xfc, 0x93, 0xcf, 0xc6, 0x6e,
+ 0xa4, 0x9d, 0x66, 0xe0, 0xe5, 0x1e, 0x17, 0x8b, 0x50, 0x68, 0x01, 0xed,
+ 0x36, 0x70, 0x21, 0xbd, 0x10, 0xd3, 0x2d, 0xfa, 0xeb, 0xb8, 0xd3, 0x3f,
+ 0xde, 0xaa, 0x63, 0xa2, 0xf7, 0x72, 0x56, 0x8d, 0x2b, 0xf5, 0xbc, 0x5f,
+ 0x87, 0xd9, 0x8e, 0xe1, 0x19, 0x66, 0x89, 0xbf, 0x88, 0x39, 0xf9, 0x12,
+ 0xcf, 0x6f, 0x59, 0x66, 0xc2, 0x5c, 0xe6, 0x9a, 0xee, 0x7c, 0x60, 0xa2,
+ 0xa8, 0x39, 0x41, 0xce, 0xbe, 0xc4, 0xff, 0xe7, 0xca, 0x1a, 0x9f, 0x3e,
+ 0xf1, 0x29, 0xd0, 0xde, 0xa1, 0xe3, 0xee, 0x5b, 0xed, 0xc4, 0xde, 0x76,
+ 0xfa, 0x33, 0xc2, 0x3c, 0x78, 0x90, 0xf6, 0x9e, 0x2b, 0x7e, 0xcf, 0x58,
+ 0xe5, 0x48, 0x57, 0x9f, 0xf0, 0x4e, 0x11, 0xe2, 0x79, 0xff, 0xef, 0xb4,
+ 0x8f, 0x5d, 0x6e, 0x4b, 0xcc, 0xdc, 0x47, 0xcc, 0x68, 0xee, 0x59, 0x6f,
+ 0x39, 0x63, 0x72, 0xe0, 0x7d, 0x1a, 0x91, 0x08, 0x86, 0xac, 0x44, 0x29,
+ 0xb5, 0x77, 0x90, 0xdf, 0xdb, 0x41, 0xd6, 0xb2, 0x47, 0x65, 0x9e, 0xe7,
+ 0xe5, 0x2c, 0x43, 0x26, 0x9a, 0xcd, 0xd4, 0xd0, 0x88, 0x90, 0x83, 0xcd,
+ 0x42, 0xf6, 0xdf, 0x03, 0xe9, 0x9c, 0x10, 0xfa, 0xcc, 0xf5, 0x56, 0x57,
+ 0x05, 0xa3, 0x59, 0x62, 0x54, 0xbf, 0xdf, 0x67, 0xa5, 0x2a, 0xef, 0x43,
+ 0xd6, 0x95, 0x53, 0x09, 0x8c, 0x96, 0xa4, 0xef, 0x8a, 0x28, 0xbe, 0x96,
+ 0xb6, 0x71, 0x22, 0xa9, 0x96, 0xbc, 0x90, 0x96, 0xb9, 0x1e, 0x73, 0x31,
+ 0x73, 0x21, 0x81, 0x61, 0x62, 0xe9, 0x1f, 0x92, 0x23, 0xe8, 0x29, 0x9b,
+ 0xc4, 0xb1, 0x8b, 0xfd, 0xa5, 0x28, 0x66, 0xc8, 0x4f, 0x75, 0xe9, 0x4e,
+ 0x8c, 0x94, 0x64, 0xe7, 0x1b, 0x48, 0xe5, 0x8f, 0x30, 0x5e, 0x67, 0x17,
+ 0x78, 0xd8, 0x5f, 0x6e, 0x63, 0x8c, 0xa4, 0xbb, 0x8a, 0x1c, 0x65, 0x76,
+ 0x4b, 0x67, 0x17, 0x7d, 0x5b, 0x17, 0x90, 0xdb, 0xca, 0x19, 0xee, 0x53,
+ 0xc0, 0xaa, 0x72, 0x5e, 0xf4, 0x95, 0xe7, 0x70, 0xfa, 0x73, 0x62, 0x53,
+ 0x63, 0xd5, 0xc6, 0xe6, 0x12, 0x70, 0x67, 0xc9, 0x47, 0x8b, 0x67, 0xbc,
+ 0x18, 0xc5, 0x45, 0xfa, 0x71, 0x02, 0xf7, 0x38, 0x21, 0x16, 0x79, 0xeb,
+ 0xd4, 0x8e, 0xb8, 0x9e, 0x9f, 0x17, 0x6b, 0x19, 0xb7, 0x30, 0x02, 0x63,
+ 0xd2, 0x37, 0x71, 0x36, 0x3e, 0x3c, 0x3f, 0x52, 0xe1, 0x5d, 0xfd, 0x6e,
+ 0xa2, 0xdf, 0xc7, 0x1a, 0x07, 0x72, 0xc8, 0x17, 0x85, 0xc1, 0x26, 0xfa,
+ 0xe1, 0xa4, 0x28, 0x0c, 0xc4, 0x20, 0x0b, 0xf7, 0x0a, 0x3a, 0x6b, 0x8c,
+ 0x24, 0xb1, 0x60, 0x8e, 0xa7, 0x2d, 0xfc, 0x75, 0xe9, 0x29, 0xe3, 0x5c,
+ 0xa4, 0x0e, 0xe6, 0x81, 0x08, 0xa2, 0x07, 0x2c, 0x34, 0x1f, 0x10, 0xc4,
+ 0x5d, 0xa1, 0x33, 0xaa, 0xd7, 0x21, 0x81, 0x7d, 0xa3, 0x36, 0xee, 0xe9,
+ 0x88, 0xe0, 0x42, 0x52, 0x0e, 0x5e, 0x21, 0x86, 0xfd, 0x26, 0x8e, 0x8d,
+ 0x1e, 0x97, 0xae, 0x6b, 0x14, 0x22, 0x68, 0x8a, 0x23, 0xd2, 0x5e, 0x87,
+ 0x06, 0xae, 0xdb, 0x59, 0x52, 0x3b, 0xed, 0xa0, 0xe0, 0x36, 0x40, 0xfa,
+ 0x0f, 0x73, 0xdf, 0x53, 0x45, 0xa5, 0xea, 0xaf, 0xf5, 0x66, 0x3e, 0x30,
+ 0xe5, 0xf4, 0x0e, 0x7e, 0x7e, 0x6b, 0xaa, 0xba, 0xff, 0xbc, 0x03, 0x36,
+ 0x1a, 0x0f, 0x56, 0xf6, 0x9f, 0x7d, 0x8a, 0x16, 0x7c, 0x58, 0xd2, 0xf9,
+ 0xa4, 0x54, 0x34, 0xf0, 0xfa, 0xdf, 0x13, 0x4a, 0xdd, 0xe4, 0xcb, 0xdc,
+ 0xcb, 0xa2, 0x6d, 0x60, 0x94, 0xcf, 0x83, 0xe9, 0xa4, 0x9b, 0xa5, 0xcd,
+ 0xe7, 0xcb, 0x51, 0xda, 0xc7, 0x5c, 0xf0, 0xb6, 0x19, 0x3b, 0x1c, 0x13,
+ 0x75, 0xde, 0x0e, 0x63, 0x6b, 0x05, 0xab, 0x0e, 0x16, 0x8d, 0xd5, 0x63,
+ 0x89, 0x17, 0x8a, 0x4d, 0xcc, 0xcd, 0x8d, 0x93, 0x16, 0xe7, 0xe9, 0xdc,
+ 0x14, 0x88, 0x7a, 0xbd, 0x62, 0xe5, 0x64, 0x5f, 0x25, 0x5f, 0x07, 0xc6,
+ 0x0d, 0xbc, 0xe9, 0xdf, 0x80, 0x48, 0x90, 0x15, 0x03, 0x93, 0x3a, 0x7f,
+ 0xd6, 0x8a, 0xd5, 0x93, 0x8c, 0xdf, 0x7c, 0x9d, 0x3b, 0x37, 0x88, 0x48,
+ 0xa0, 0xf3, 0xe5, 0xf3, 0x1c, 0xb2, 0x99, 0x43, 0xc7, 0xfe, 0x97, 0x1c,
+ 0x7a, 0xa8, 0x64, 0x21, 0xd7, 0x52, 0xcd, 0x97, 0x5e, 0xc6, 0xe2, 0xef,
+ 0x6b, 0x75, 0x7b, 0x3b, 0xc7, 0xa3, 0x07, 0x74, 0x0e, 0xf7, 0x32, 0x87,
+ 0x35, 0x9e, 0x2d, 0xb1, 0x69, 0x1c, 0x76, 0x73, 0x10, 0x5a, 0x1f, 0x8e,
+ 0x2a, 0xbc, 0xed, 0x2b, 0xf5, 0xf1, 0x32, 0xed, 0x13, 0x39, 0xf8, 0x2c,
+ 0xf1, 0x08, 0x12, 0xd2, 0xbb, 0x9e, 0x52, 0x33, 0x7e, 0x2a, 0xfb, 0x2c,
+ 0x79, 0xf9, 0x9c, 0xd0, 0xf7, 0x8f, 0xc2, 0x49, 0x6b, 0x3c, 0xf6, 0x5a,
+ 0x57, 0x55, 0x70, 0x19, 0x12, 0xaf, 0xac, 0xd5, 0xf3, 0x35, 0x36, 0xa3,
+ 0x68, 0x48, 0xce, 0xd2, 0x37, 0x72, 0xa8, 0x51, 0xa8, 0x25, 0xaf, 0xa6,
+ 0xab, 0xb8, 0x2c, 0xb2, 0x36, 0xad, 0xe7, 0x59, 0xbd, 0xe3, 0xb2, 0xb0,
+ 0xde, 0xac, 0xd6, 0xd1, 0xbd, 0xc4, 0x86, 0xe6, 0xb8, 0xcb, 0xdb, 0xa3,
+ 0xd8, 0x47, 0x8c, 0x7a, 0x69, 0x17, 0xc3, 0xac, 0xab, 0xbb, 0x4b, 0xd2,
+ 0x1d, 0x26, 0x4e, 0x77, 0xd7, 0x70, 0x3a, 0xcc, 0x5a, 0xba, 0x1b, 0x72,
+ 0xaf, 0xae, 0xa5, 0x11, 0xe2, 0x94, 0x34, 0x56, 0xc1, 0xe9, 0x48, 0x0d,
+ 0xa7, 0xbd, 0x15, 0x9c, 0xee, 0x36, 0x34, 0x3e, 0x35, 0xf6, 0x36, 0xf1,
+ 0xbe, 0x67, 0xa3, 0x30, 0x7e, 0xc0, 0xfd, 0xc3, 0x05, 0xc3, 0x3d, 0x35,
+ 0xec, 0xf5, 0x68, 0xec, 0x19, 0x69, 0xdc, 0x63, 0xf0, 0x6e, 0x2f, 0x88,
+ 0x42, 0xae, 0x11, 0x32, 0x3b, 0x2c, 0x0a, 0x9d, 0xf3, 0x88, 0xbd, 0x67,
+ 0x38, 0xa3, 0x81, 0xd8, 0xab, 0xfa, 0x4c, 0xcf, 0x8f, 0x11, 0x7b, 0xff,
+ 0x29, 0xce, 0x46, 0x34, 0xd7, 0xea, 0xd8, 0x02, 0x8b, 0x4e, 0x68, 0xae,
+ 0x8d, 0x92, 0x30, 0x2c, 0xe4, 0x4b, 0xc6, 0xe2, 0x04, 0x14, 0xb6, 0x92,
+ 0xdb, 0xde, 0xf4, 0x76, 0xf9, 0x2d, 0xb8, 0x01, 0xa7, 0xbb, 0x0c, 0x68,
+ 0x1d, 0x62, 0x4e, 0x54, 0xb1, 0x7b, 0x17, 0x39, 0xa3, 0x29, 0x90, 0x9d,
+ 0x67, 0xa9, 0x37, 0xb6, 0xa4, 0x1b, 0x50, 0xf2, 0x86, 0xc3, 0x66, 0x56,
+ 0x43, 0x9b, 0xe7, 0xae, 0x86, 0xae, 0x85, 0x71, 0x58, 0xed, 0x36, 0x1a,
+ 0x8e, 0x7a, 0xb9, 0x13, 0x42, 0xe3, 0x15, 0xe8, 0x3a, 0x6e, 0xd3, 0x7e,
+ 0x38, 0xf5, 0x81, 0x97, 0xf9, 0xc0, 0x7c, 0x5c, 0x9c, 0x75, 0xaa, 0xf5,
+ 0xa0, 0x6f, 0x5c, 0x63, 0xec, 0x57, 0xea, 0x4d, 0xcf, 0xc0, 0x1d, 0xdd,
+ 0x4a, 0x79, 0x4b, 0xa3, 0x88, 0x4c, 0xd8, 0xa8, 0x3b, 0xd8, 0x8a, 0x97,
+ 0xba, 0x22, 0x38, 0x7b, 0xab, 0xfe, 0x3e, 0x8a, 0x7a, 0xe2, 0x70, 0xd3,
+ 0xb5, 0x51, 0x2c, 0x99, 0xa8, 0x62, 0xb2, 0xc1, 0xfb, 0x89, 0xb8, 0x8b,
+ 0x98, 0x9c, 0xe7, 0x9d, 0x11, 0xdb, 0x9c, 0x0c, 0xf6, 0xd2, 0xa6, 0xd7,
+ 0xc9, 0xf1, 0xe7, 0x93, 0xbb, 0x66, 0x2c, 0xda, 0xbf, 0x62, 0x59, 0xa1,
+ 0x73, 0x09, 0x22, 0x58, 0x34, 0x21, 0x07, 0x8e, 0xe9, 0x0a, 0x33, 0x6a,
+ 0x89, 0x0d, 0xc4, 0xbb, 0xe6, 0x57, 0x93, 0x71, 0xba, 0x62, 0x69, 0xdb,
+ 0xd0, 0xcd, 0xb8, 0xa4, 0xce, 0x24, 0x93, 0xd9, 0x51, 0x62, 0x7d, 0xdb,
+ 0xf1, 0x08, 0xea, 0x0e, 0xfc, 0x97, 0x32, 0x02, 0xe6, 0x42, 0xb7, 0x22,
+ 0x3e, 0x0b, 0x99, 0x7a, 0x72, 0xc8, 0x45, 0xc4, 0xf1, 0xd8, 0xfe, 0x9d,
+ 0x6a, 0x09, 0xc7, 0xdf, 0xbb, 0xbe, 0x19, 0x6d, 0xcb, 0x64, 0x7e, 0x2b,
+ 0xf7, 0x9f, 0x4d, 0x17, 0x3a, 0x13, 0x8c, 0xdd, 0x49, 0xb8, 0xb8, 0x6a,
+ 0x4c, 0xe6, 0x8e, 0xa1, 0x0e, 0xcd, 0x13, 0x5e, 0xf6, 0x84, 0x88, 0xa1,
+ 0xf1, 0x44, 0x0c, 0xfb, 0x8e, 0xeb, 0xfc, 0x8c, 0xc1, 0x1a, 0xf3, 0x66,
+ 0x3b, 0x44, 0xa1, 0x9f, 0xf9, 0x39, 0xd3, 0x2f, 0xda, 0xd1, 0x3e, 0x2e,
+ 0xa7, 0xb3, 0xc2, 0x0b, 0x1f, 0x80, 0x87, 0x76, 0xd6, 0x65, 0xfb, 0x84,
+ 0x8b, 0x15, 0xba, 0x7e, 0x94, 0x75, 0xfe, 0xe8, 0x7a, 0x6a, 0xf0, 0x4e,
+ 0xa1, 0x58, 0x5f, 0xa9, 0x79, 0xbd, 0x7c, 0xf5, 0xb1, 0xfe, 0x59, 0x62,
+ 0xdd, 0xb8, 0xce, 0x2d, 0x03, 0x33, 0xfe, 0x25, 0xb5, 0x3d, 0x99, 0x65,
+ 0xad, 0x9b, 0xc7, 0xbc, 0xaa, 0xe6, 0x13, 0x5a, 0x74, 0x6e, 0xcd, 0xab,
+ 0xe5, 0x93, 0x85, 0x33, 0x8c, 0xdd, 0xe1, 0xff, 0x73, 0x5d, 0xb2, 0x90,
+ 0x38, 0x60, 0xa0, 0xa5, 0x23, 0x8a, 0x6b, 0x96, 0xb6, 0x39, 0xcd, 0x88,
+ 0xe2, 0x26, 0xdf, 0x41, 0x13, 0x31, 0xb1, 0x9f, 0x39, 0x85, 0xf9, 0xd5,
+ 0x5c, 0x5b, 0xa9, 0xeb, 0x55, 0x2d, 0xd7, 0xf2, 0xa5, 0x04, 0x6b, 0x93,
+ 0xae, 0x05, 0xbd, 0xac, 0x05, 0x16, 0x0e, 0x95, 0xb5, 0x6f, 0x1d, 0xbc,
+ 0x4b, 0xce, 0x7e, 0xc5, 0xd7, 0xbe, 0x5d, 0x8c, 0x12, 0x73, 0xe3, 0x41,
+ 0xe6, 0xc6, 0xda, 0xf2, 0x25, 0xb5, 0xc6, 0xd3, 0xf5, 0x38, 0x64, 0x3d,
+ 0xb6, 0xc4, 0x4d, 0xe3, 0x72, 0xd0, 0x15, 0xa7, 0xee, 0x24, 0x36, 0x3b,
+ 0x1b, 0x0d, 0xa5, 0x5e, 0x4e, 0xa7, 0x42, 0xea, 0x98, 0xcc, 0xdd, 0x42,
+ 0xba, 0xef, 0x93, 0x9b, 0xd6, 0x9a, 0x51, 0x2c, 0xaf, 0xe5, 0x60, 0xb2,
+ 0x96, 0x83, 0x1e, 0x73, 0xd0, 0x6d, 0x45, 0xf8, 0x09, 0x6d, 0x6c, 0x63,
+ 0x0e, 0x6e, 0xa3, 0x4e, 0xfd, 0x7e, 0xa9, 0xc2, 0xfb, 0x99, 0x15, 0x22,
+ 0x35, 0x73, 0x9e, 0xf9, 0xe4, 0x5e, 0xe6, 0x51, 0xaf, 0xb5, 0x65, 0xce,
+ 0x33, 0x66, 0xab, 0x6b, 0xf9, 0xb4, 0xbb, 0xc6, 0xfb, 0x0f, 0xd4, 0xf2,
+ 0x69, 0xf5, 0x97, 0xf2, 0x49, 0xf3, 0xd3, 0x0b, 0xbf, 0x43, 0xab, 0xd6,
+ 0x22, 0x79, 0xa1, 0xef, 0x97, 0xb3, 0x10, 0xfe, 0xd8, 0xd7, 0x67, 0xd9,
+ 0xb0, 0x82, 0xc6, 0x0a, 0xdf, 0x58, 0x41, 0x28, 0x7a, 0x59, 0x3b, 0x6d,
+ 0x2f, 0x2f, 0xb2, 0xf4, 0x9d, 0x5e, 0xb7, 0x96, 0xb1, 0xd8, 0x99, 0xfe,
+ 0x05, 0xce, 0xb6, 0x2a, 0xd5, 0x97, 0xbe, 0xa4, 0xde, 0x60, 0x5c, 0x62,
+ 0xd4, 0x1f, 0xeb, 0x27, 0xb3, 0xa2, 0x7f, 0x52, 0xfb, 0xa6, 0x11, 0x11,
+ 0x6f, 0xad, 0x58, 0x35, 0x09, 0xdc, 0x43, 0x3d, 0x73, 0x8e, 0x7e, 0x59,
+ 0xe3, 0xcb, 0xa1, 0x35, 0xbc, 0xdb, 0x19, 0xdf, 0xc2, 0xc3, 0xe5, 0xaa,
+ 0x7f, 0xf6, 0x95, 0x65, 0x66, 0x1a, 0x23, 0x58, 0xc3, 0x9a, 0x76, 0x98,
+ 0x7c, 0xf1, 0x6f, 0xc9, 0x28, 0x5e, 0x24, 0x5f, 0xbc, 0xc4, 0xfb, 0x1d,
+ 0xaa, 0xde, 0xcf, 0x9f, 0x45, 0x2a, 0x73, 0x5a, 0xf3, 0x05, 0xb5, 0xf7,
+ 0xa1, 0x72, 0x9b, 0x7f, 0x9a, 0x78, 0x7c, 0xb0, 0x24, 0x07, 0xfa, 0x78,
+ 0x47, 0xbb, 0x5b, 0xce, 0x0e, 0x0a, 0x81, 0x8d, 0x49, 0x38, 0x66, 0xa0,
+ 0xef, 0xe1, 0x52, 0xe3, 0x66, 0xe8, 0x87, 0x02, 0xfa, 0x78, 0xd7, 0x95,
+ 0xac, 0x71, 0x8f, 0x95, 0xbf, 0xa4, 0xeb, 0xb0, 0xad, 0xa4, 0xb9, 0x4a,
+ 0xa9, 0x8e, 0xb4, 0xd6, 0x4a, 0x79, 0x71, 0xb3, 0xe6, 0x94, 0x48, 0x14,
+ 0xca, 0x6f, 0x4b, 0x2c, 0x61, 0xec, 0xf3, 0xc4, 0xd7, 0xbb, 0x5e, 0x3d,
+ 0x79, 0x21, 0x24, 0xaf, 0xf7, 0x90, 0xb7, 0x7b, 0x45, 0x5f, 0x85, 0xcf,
+ 0xb3, 0x22, 0x3b, 0x69, 0x8b, 0x1e, 0x6a, 0x94, 0x0d, 0xcc, 0x33, 0x77,
+ 0xe1, 0x3c, 0x62, 0x4a, 0xe3, 0xca, 0xc0, 0x0f, 0xfc, 0xb5, 0xe4, 0xfc,
+ 0x1b, 0xe8, 0x2b, 0xf2, 0x52, 0x05, 0x8b, 0x37, 0x50, 0x27, 0x55, 0xb1,
+ 0xf8, 0x43, 0x62, 0x31, 0x57, 0xc3, 0x62, 0x24, 0x48, 0x92, 0xef, 0x3e,
+ 0xc7, 0x62, 0xef, 0x1f, 0xe0, 0xf7, 0x2f, 0x62, 0x6e, 0xbd, 0xe6, 0xf7,
+ 0xc8, 0x1c, 0xe6, 0x58, 0x9f, 0x3b, 0x02, 0xf2, 0xb0, 0xc6, 0x9b, 0x8d,
+ 0xbe, 0x47, 0xeb, 0xb1, 0xe1, 0xd1, 0x18, 0x6e, 0x7e, 0x54, 0xa9, 0xd7,
+ 0x7c, 0x78, 0x2d, 0xe4, 0xa2, 0x5f, 0xa4, 0x27, 0x70, 0xa6, 0x25, 0xe9,
+ 0xee, 0x83, 0xee, 0xa3, 0x7a, 0xad, 0xdb, 0x8b, 0x5a, 0xa3, 0x84, 0xd4,
+ 0x28, 0xb2, 0xff, 0x7d, 0xe6, 0xfa, 0xa6, 0xa4, 0xcc, 0xef, 0xac, 0x70,
+ 0x7f, 0xca, 0xa7, 0x16, 0xdf, 0x6b, 0x98, 0x32, 0xdb, 0x6e, 0x54, 0xb1,
+ 0x76, 0x4d, 0x0d, 0x6b, 0x5f, 0x9b, 0xb2, 0xf1, 0x4b, 0xd6, 0x85, 0xcd,
+ 0xe9, 0x28, 0x56, 0xeb, 0x1a, 0xef, 0xe8, 0x5e, 0x2a, 0x8a, 0x7e, 0xc6,
+ 0xc5, 0x58, 0xaa, 0xa8, 0x37, 0xa8, 0x3b, 0x18, 0xcb, 0x55, 0xec, 0xa7,
+ 0xce, 0x50, 0x9f, 0xdc, 0x68, 0x56, 0x7b, 0xa9, 0xd1, 0x9a, 0x3e, 0xb9,
+ 0xb1, 0xac, 0xf3, 0xd1, 0x25, 0x06, 0xa2, 0x38, 0xcd, 0x35, 0x7b, 0xfc,
+ 0xaa, 0x3e, 0x79, 0x1d, 0xa9, 0xac, 0xd6, 0x27, 0x2e, 0x79, 0xbf, 0x54,
+ 0xd1, 0x27, 0x5a, 0x8f, 0x68, 0x2d, 0xa2, 0xfb, 0x85, 0x6e, 0xf6, 0x0b,
+ 0x72, 0x5a, 0xeb, 0x15, 0xa3, 0x5b, 0xfa, 0x86, 0x19, 0x61, 0x8d, 0xcc,
+ 0x30, 0x96, 0x97, 0x61, 0xd7, 0x23, 0x4d, 0x8c, 0x45, 0x23, 0x76, 0x38,
+ 0x2b, 0xac, 0x25, 0x9e, 0xe6, 0x4f, 0x6a, 0x90, 0xdf, 0xd3, 0x2e, 0x47,
+ 0x35, 0xc7, 0x32, 0xfe, 0x73, 0xe3, 0xff, 0x5e, 0x1b, 0xd7, 0xf3, 0xb3,
+ 0xac, 0xd1, 0x7a, 0xcd, 0x8f, 0xac, 0x2a, 0xee, 0xd1, 0xdc, 0xe4, 0xfd,
+ 0x19, 0x2e, 0xd0, 0xc6, 0x37, 0xbf, 0x14, 0x47, 0x9b, 0x79, 0xa1, 0xe3,
+ 0xf8, 0x09, 0xd7, 0xea, 0x78, 0xdb, 0x78, 0x87, 0x3e, 0x3e, 0x47, 0x1f,
+ 0xff, 0xf2, 0xd1, 0x80, 0xdc, 0x84, 0x4f, 0x0d, 0xfa, 0x78, 0x3b, 0x71,
+ 0xf3, 0x63, 0xff, 0x7a, 0xb4, 0xb7, 0x26, 0xdd, 0x0f, 0xcc, 0xb9, 0x7a,
+ 0x0b, 0x7b, 0x09, 0x7d, 0xa7, 0xe8, 0x67, 0xdd, 0xeb, 0x1c, 0xa3, 0x7f,
+ 0x99, 0xcb, 0x15, 0x0d, 0xd2, 0x6e, 0x56, 0xfd, 0xdb, 0x51, 0xf3, 0x6f,
+ 0x66, 0x6a, 0x1b, 0xcf, 0xd1, 0xf5, 0x54, 0xeb, 0xd1, 0xfb, 0x2b, 0xfd,
+ 0x92, 0x19, 0xdc, 0x5a, 0x89, 0x55, 0x5d, 0x90, 0xb7, 0x5e, 0x2c, 0xea,
+ 0x9a, 0xdd, 0xcf, 0x9a, 0xcd, 0x9e, 0xc9, 0x94, 0x83, 0x83, 0x48, 0x4d,
+ 0x73, 0xaf, 0xbd, 0xa7, 0x91, 0x0a, 0xd9, 0x4f, 0x0d, 0x9d, 0x67, 0xef,
+ 0x93, 0x31, 0x64, 0x6e, 0xa6, 0xa2, 0x27, 0x6f, 0xad, 0xd5, 0xe9, 0xfe,
+ 0x9a, 0xae, 0xbc, 0xbf, 0x76, 0x4e, 0x9e, 0xba, 0x72, 0xee, 0x1c, 0x7d,
+ 0x97, 0xcb, 0x2d, 0xfd, 0xac, 0xfb, 0x80, 0x37, 0xfc, 0x9f, 0x29, 0x2c,
+ 0x6c, 0xac, 0xe8, 0x8e, 0xcf, 0xef, 0x6c, 0x89, 0x8d, 0xe3, 0x17, 0x55,
+ 0xa6, 0xe3, 0x2e, 0x13, 0xf5, 0x4a, 0x59, 0xcb, 0x42, 0x14, 0x4b, 0x33,
+ 0xaa, 0x18, 0x97, 0x05, 0x0d, 0xca, 0x96, 0xe0, 0x6e, 0xc6, 0x07, 0xb6,
+ 0x15, 0x0c, 0x5a, 0x23, 0x45, 0x39, 0xc4, 0x5e, 0x2e, 0xcf, 0x3e, 0x2c,
+ 0xdc, 0x0f, 0xad, 0x6f, 0xf5, 0x79, 0x77, 0xeb, 0x3e, 0x8e, 0xef, 0x83,
+ 0xb4, 0x67, 0xee, 0xdc, 0x10, 0x8f, 0x95, 0xfe, 0x4a, 0x3d, 0x16, 0x97,
+ 0x39, 0xbd, 0x47, 0x84, 0x73, 0x9e, 0xa8, 0xe8, 0xe7, 0x41, 0xad, 0x9f,
+ 0x5d, 0x8d, 0xc7, 0x31, 0x4f, 0xce, 0x9e, 0x40, 0x6a, 0xe0, 0x82, 0x29,
+ 0xfb, 0x63, 0xd4, 0xcc, 0xeb, 0x6a, 0x7b, 0xad, 0xa8, 0xed, 0xd5, 0x36,
+ 0xf5, 0x10, 0xed, 0xd6, 0x78, 0xac, 0xd6, 0x37, 0x23, 0x88, 0xa1, 0x69,
+ 0xd4, 0x63, 0x8d, 0x4f, 0xe6, 0x8e, 0xb0, 0xce, 0xc4, 0x8e, 0xef, 0xa8,
+ 0xd8, 0xfb, 0xba, 0xff, 0xa4, 0x59, 0xc9, 0xef, 0x13, 0xba, 0x4e, 0x58,
+ 0xb0, 0x58, 0x77, 0xae, 0x1c, 0x93, 0xe1, 0x16, 0xf1, 0x91, 0x5a, 0x92,
+ 0xf4, 0x12, 0xab, 0x85, 0xd6, 0x3e, 0x49, 0x6a, 0x9f, 0x18, 0x32, 0x27,
+ 0xfe, 0x85, 0xf6, 0x69, 0xfd, 0xa6, 0x6b, 0xa1, 0x83, 0x96, 0x51, 0xaf,
+ 0xb3, 0xcd, 0x48, 0x52, 0x3b, 0x3b, 0x68, 0xfe, 0x6c, 0x3f, 0x4b, 0xac,
+ 0xe2, 0x3e, 0x75, 0x07, 0x1c, 0x5c, 0x33, 0x26, 0x9d, 0xa3, 0xb8, 0x40,
+ 0x0e, 0xf7, 0x06, 0xb5, 0x4e, 0xbc, 0x3a, 0x9d, 0x64, 0x4d, 0x77, 0xd0,
+ 0xf5, 0xd9, 0x3e, 0x31, 0xd4, 0x8d, 0xe9, 0xb3, 0x0b, 0xd3, 0x26, 0xe3,
+ 0xe4, 0x98, 0x47, 0x39, 0xee, 0xa2, 0xfd, 0x44, 0x23, 0xfb, 0x2d, 0xa5,
+ 0xfa, 0x59, 0x0f, 0x2c, 0xd6, 0xdc, 0x5e, 0xb4, 0x0f, 0x8e, 0x88, 0xd4,
+ 0x40, 0x23, 0x52, 0xfd, 0x31, 0x78, 0xce, 0x3a, 0xa1, 0x7f, 0x63, 0x98,
+ 0xd3, 0x24, 0xc0, 0xe3, 0xc5, 0x3f, 0xe7, 0xba, 0xa4, 0xb3, 0x85, 0x18,
+ 0x6b, 0xf9, 0xd3, 0x54, 0xbe, 0x05, 0xa9, 0x21, 0x07, 0x9e, 0xfb, 0x3a,
+ 0xe7, 0x15, 0xbe, 0x30, 0xef, 0xd9, 0xca, 0x3c, 0xfa, 0xe2, 0x7a, 0xad,
+ 0xb5, 0x94, 0x7a, 0x82, 0x7a, 0xab, 0xe0, 0x68, 0xce, 0x11, 0x18, 0xf6,
+ 0xf5, 0x9e, 0x3d, 0xae, 0x05, 0x99, 0xb8, 0x03, 0x9f, 0xa8, 0x42, 0x3c,
+ 0xec, 0x8c, 0x54, 0x7e, 0x97, 0x90, 0x4e, 0x8e, 0xdc, 0x36, 0x5d, 0xed,
+ 0xb3, 0xd8, 0x17, 0x29, 0xf5, 0x22, 0xb9, 0xe9, 0x09, 0x6a, 0x9f, 0xe1,
+ 0xa9, 0x4f, 0xd4, 0x34, 0xb5, 0xcd, 0x88, 0xa7, 0xe7, 0x55, 0x39, 0xe8,
+ 0xb0, 0xa3, 0xd4, 0xe3, 0xfc, 0x6e, 0xcf, 0xd4, 0x1c, 0x2f, 0xf1, 0x3c,
+ 0x72, 0xc2, 0xed, 0xde, 0x7f, 0xab, 0xcd, 0x5f, 0x9a, 0xab, 0xd4, 0x18,
+ 0x6d, 0x78, 0xcb, 0xc7, 0xfd, 0x11, 0x24, 0x73, 0xb3, 0xf4, 0xcf, 0x99,
+ 0xe5, 0xb2, 0x7f, 0x8a, 0xf7, 0x5c, 0x2f, 0x64, 0x96, 0x77, 0xec, 0x9d,
+ 0x07, 0xcd, 0xb5, 0x92, 0xf9, 0x60, 0x78, 0x75, 0x7c, 0xfe, 0x99, 0x2f,
+ 0x13, 0x47, 0xf8, 0xbe, 0x39, 0xa3, 0xf7, 0x50, 0xaa, 0xc7, 0xd7, 0x3d,
+ 0xfe, 0x08, 0x7b, 0xfc, 0x82, 0x6a, 0xf0, 0xde, 0x50, 0xcf, 0x75, 0xc8,
+ 0xfe, 0x11, 0xe1, 0x71, 0xad, 0xcb, 0xba, 0xa0, 0xfb, 0xaa, 0x11, 0xf6,
+ 0x55, 0x2e, 0x9e, 0x26, 0xc7, 0x9c, 0x2c, 0x77, 0xe2, 0xf9, 0xb2, 0x87,
+ 0x67, 0x58, 0x3f, 0x9e, 0x2a, 0x5b, 0xd8, 0xfa, 0x88, 0xcc, 0x58, 0x62,
+ 0x27, 0xce, 0xfb, 0xd2, 0xf9, 0x1e, 0xed, 0x36, 0x03, 0xb9, 0x7f, 0x25,
+ 0x79, 0x85, 0x67, 0x14, 0x72, 0x66, 0x8b, 0xb0, 0x03, 0x1b, 0xdf, 0xe9,
+ 0x30, 0x70, 0x38, 0x3e, 0x84, 0xbe, 0xf6, 0xbb, 0xf9, 0xb2, 0xd0, 0x7a,
+ 0x40, 0xd7, 0x6a, 0xdd, 0x6f, 0x34, 0xe3, 0x4e, 0xf2, 0xd9, 0xd5, 0x4b,
+ 0x43, 0xfc, 0x3a, 0xdd, 0xd6, 0xf9, 0x92, 0xa0, 0x66, 0x68, 0x91, 0x59,
+ 0xe0, 0xa7, 0xd8, 0xc8, 0x7e, 0x21, 0xb3, 0x6c, 0x7f, 0xad, 0x37, 0xff,
+ 0x29, 0x56, 0xea, 0x3e, 0xc3, 0x6f, 0x66, 0xbd, 0xab, 0xc6, 0xe1, 0x70,
+ 0xc5, 0x8f, 0x06, 0x9a, 0x0e, 0x16, 0x54, 0xbd, 0x27, 0x73, 0x93, 0x15,
+ 0x1d, 0xb5, 0xd0, 0xb9, 0x91, 0x7d, 0x40, 0xc3, 0x01, 0xcf, 0x5d, 0x27,
+ 0x14, 0x63, 0xb1, 0x9b, 0xb1, 0x48, 0x86, 0x31, 0xb6, 0xdb, 0xcd, 0x41,
+ 0x32, 0x6c, 0x16, 0x79, 0x71, 0x8b, 0xae, 0xb1, 0x75, 0xf5, 0xec, 0xbf,
+ 0x59, 0x53, 0x27, 0x0d, 0xf6, 0x23, 0xba, 0x1f, 0x8f, 0x62, 0x2a, 0xdd,
+ 0xc6, 0x3e, 0x29, 0x8a, 0xed, 0xe9, 0x1e, 0xea, 0x1a, 0x03, 0xc6, 0xc1,
+ 0x4b, 0x6a, 0xe5, 0x17, 0xfa, 0x88, 0x4d, 0xe3, 0x9a, 0xc3, 0x6c, 0xb1,
+ 0x91, 0xf9, 0x9b, 0x59, 0x46, 0xb1, 0x76, 0x8b, 0xee, 0xe1, 0xf5, 0x1d,
+ 0x1c, 0xf6, 0xc7, 0x06, 0xa6, 0x17, 0x38, 0xd8, 0xd5, 0x2d, 0x13, 0x05,
+ 0xe8, 0x5c, 0xfe, 0x6a, 0x4d, 0x81, 0x93, 0xfd, 0xbd, 0x3a, 0x03, 0x67,
+ 0x03, 0x6d, 0x91, 0x75, 0x4a, 0xb5, 0xa6, 0x4d, 0xe4, 0x2a, 0xf5, 0x26,
+ 0xe1, 0x64, 0xd9, 0xff, 0xcd, 0x4c, 0xb1, 0x27, 0x3b, 0xa8, 0xd4, 0x4e,
+ 0x62, 0xe9, 0xe3, 0x8e, 0xe1, 0x43, 0xec, 0xc4, 0xf7, 0xb6, 0xb2, 0xb7,
+ 0xfa, 0x3a, 0xdb, 0xb7, 0xb7, 0x8a, 0xdf, 0x24, 0x7f, 0x1b, 0xdd, 0x09,
+ 0xe8, 0x7e, 0xa7, 0xa0, 0x22, 0x9e, 0x37, 0xfb, 0x38, 0xb5, 0xe0, 0x6f,
+ 0x96, 0x75, 0xc1, 0x9d, 0x5f, 0xf5, 0xd5, 0x6a, 0x6a, 0xa9, 0x8f, 0xc8,
+ 0xf9, 0x61, 0xe5, 0x73, 0xcc, 0x59, 0x37, 0x7e, 0x49, 0x6d, 0xa6, 0x6f,
+ 0x7a, 0xaa, 0x76, 0x59, 0xf5, 0x01, 0x9b, 0xc4, 0x6b, 0xe1, 0xac, 0xf9,
+ 0x03, 0x36, 0x7d, 0x5e, 0xef, 0x62, 0xce, 0x9a, 0xf1, 0xc5, 0xb4, 0x51,
+ 0xba, 0xd3, 0x15, 0xfc, 0xf8, 0xf8, 0xc8, 0x1b, 0x4e, 0xcc, 0x47, 0xa1,
+ 0x93, 0x39, 0x36, 0xfb, 0x4f, 0x1c, 0x6b, 0x5f, 0x0a, 0xfc, 0xa6, 0xfc,
+ 0x5d, 0xf2, 0xbe, 0xd1, 0xd5, 0x82, 0xc2, 0x0c, 0x6d, 0x3c, 0xf4, 0x75,
+ 0x62, 0x32, 0x3f, 0x86, 0xfb, 0xd8, 0x46, 0xe0, 0x59, 0xd6, 0xdb, 0x63,
+ 0xe4, 0x8c, 0xe6, 0xb4, 0x83, 0x32, 0x9f, 0x8f, 0x94, 0x92, 0x83, 0xa7,
+ 0x99, 0xb7, 0xc7, 0xf9, 0x7c, 0x94, 0xf7, 0xdc, 0x4a, 0x7d, 0x77, 0xef,
+ 0x78, 0x3d, 0xbe, 0x3d, 0x1e, 0xc3, 0xd6, 0xf1, 0x80, 0x9a, 0x02, 0xb7,
+ 0x35, 0x72, 0xdf, 0x57, 0x89, 0xe7, 0xcd, 0x4b, 0xaf, 0xc3, 0x5a, 0x27,
+ 0xe9, 0xde, 0xcd, 0xdc, 0xab, 0x3b, 0x08, 0xc7, 0x21, 0x8e, 0xfe, 0xd9,
+ 0x5b, 0x2e, 0xd0, 0x44, 0xbd, 0xbf, 0xd4, 0x12, 0xeb, 0xc7, 0x57, 0x57,
+ 0x9e, 0x47, 0xd2, 0x79, 0x6a, 0x0b, 0x62, 0xb2, 0x44, 0x4c, 0x32, 0x36,
+ 0x4f, 0x97, 0x88, 0x4b, 0x6a, 0xc3, 0x93, 0x25, 0x8d, 0x6d, 0x1f, 0xcf,
+ 0x75, 0x0c, 0xa9, 0x2a, 0x56, 0x3e, 0x55, 0x4f, 0x78, 0xaf, 0x45, 0x50,
+ 0x6f, 0xe9, 0xdf, 0x76, 0xf0, 0x66, 0x31, 0xe1, 0x6c, 0x28, 0x6b, 0x3c,
+ 0xfc, 0x6d, 0x0d, 0x0f, 0x6f, 0x47, 0xaa, 0xfa, 0x44, 0xce, 0x4c, 0x42,
+ 0x73, 0xdd, 0x62, 0xe7, 0xa6, 0xd2, 0xf0, 0x34, 0x7d, 0x9f, 0xa7, 0xc6,
+ 0x76, 0xdf, 0x67, 0xc8, 0xc7, 0xa6, 0x8c, 0x2e, 0xf6, 0xd4, 0xf4, 0x87,
+ 0xbe, 0x33, 0xf3, 0x37, 0x2d, 0x3b, 0x75, 0x4c, 0x8e, 0x17, 0x71, 0x2b,
+ 0xfb, 0x1e, 0x3f, 0x44, 0xf5, 0x6e, 0x53, 0xbc, 0xf3, 0x43, 0xbc, 0xf3,
+ 0x0f, 0xf9, 0x3c, 0x51, 0x4a, 0x66, 0x7b, 0x78, 0xe7, 0x27, 0xf9, 0x3c,
+ 0x59, 0x6a, 0xad, 0xd3, 0x67, 0x4c, 0x4e, 0x85, 0xac, 0x03, 0x2f, 0xab,
+ 0x52, 0xbc, 0x12, 0x0e, 0xf6, 0xc0, 0x06, 0x1a, 0x0e, 0xce, 0xf1, 0xb3,
+ 0xfe, 0x6d, 0x49, 0xd7, 0x38, 0xcd, 0xf9, 0x83, 0xba, 0x26, 0x67, 0xae,
+ 0x14, 0x97, 0xd4, 0x47, 0x9e, 0x0c, 0x9f, 0xc6, 0x29, 0x35, 0x1f, 0xa9,
+ 0x99, 0xf9, 0x42, 0x4e, 0xaf, 0x30, 0xa4, 0xbb, 0xc8, 0xac, 0x72, 0x75,
+ 0x67, 0x8d, 0xab, 0xbd, 0xa9, 0x1b, 0xeb, 0xaa, 0x77, 0x48, 0x39, 0x47,
+ 0x30, 0x8f, 0xd8, 0xd7, 0x35, 0x55, 0xf3, 0x8f, 0xfe, 0x4c, 0x7d, 0x67,
+ 0x85, 0x09, 0x93, 0x7e, 0x08, 0x6f, 0xd5, 0x63, 0xd1, 0xda, 0x6f, 0x3e,
+ 0x29, 0x5f, 0xf7, 0x82, 0xd3, 0xf1, 0x1e, 0x7e, 0xa7, 0x7b, 0xc1, 0x4f,
+ 0x54, 0x2e, 0xde, 0xf3, 0x19, 0x67, 0x15, 0xd0, 0x45, 0xed, 0xf1, 0x3e,
+ 0x39, 0xa1, 0x83, 0x2a, 0x4a, 0xe0, 0x14, 0xfb, 0xb0, 0x23, 0x5d, 0x49,
+ 0x67, 0x17, 0xf7, 0x0b, 0x1d, 0x87, 0x5c, 0xb0, 0x93, 0x3a, 0x93, 0x73,
+ 0xca, 0x1d, 0x5c, 0xa3, 0xb9, 0xf0, 0x3e, 0xfa, 0xe6, 0xb7, 0xed, 0x96,
+ 0xe7, 0x63, 0x57, 0xe9, 0x39, 0xc3, 0xf2, 0xb4, 0x5f, 0x52, 0x99, 0x5d,
+ 0xb4, 0xe7, 0x2c, 0xed, 0x89, 0x78, 0x21, 0xb9, 0x31, 0x55, 0x59, 0x5f,
+ 0xb0, 0xb4, 0x1d, 0x15, 0x7b, 0x38, 0xa6, 0x39, 0x4f, 0xf6, 0x9f, 0x62,
+ 0x8d, 0xdd, 0x02, 0xfd, 0x3b, 0x85, 0xb6, 0xa1, 0x2d, 0xb1, 0x85, 0xf6,
+ 0x1c, 0x8e, 0x57, 0xf8, 0x94, 0xdf, 0xf1, 0xbc, 0x92, 0xb1, 0xbe, 0x9e,
+ 0x78, 0xbf, 0x22, 0x9d, 0x60, 0x6c, 0xbb, 0xa8, 0xef, 0xab, 0x71, 0xde,
+ 0x57, 0xc1, 0xf2, 0xff, 0x00, 0xb0, 0x60, 0x72, 0xf9, 0x60, 0x17, 0x00,
+ 0x00, 0x00 };
static const u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
static struct fw_info bnx2_tpat_fw_06 = {
- /* Firmware version: 4.4.22 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x16,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
.start_addr = 0x08000488,
.text_addr = 0x08000400,
- .text_len = 0x1aa4,
+ .text_len = 0x175c,
.text_index = 0x0,
.gz_text = bnx2_TPAT_b06FwText,
.gz_text_len = sizeof(bnx2_TPAT_b06FwText),
@@ -3639,11 +3540,11 @@ static struct fw_info bnx2_tpat_fw_06 = {
.data_index = 0x0,
.data = bnx2_TPAT_b06FwData,
- .sbss_addr = 0x08001ec0,
+ .sbss_addr = 0x08001b80,
.sbss_len = 0x44,
.sbss_index = 0x0,
- .bss_addr = 0x08001f04,
+ .bss_addr = 0x08001bc4,
.bss_len = 0x450,
.bss_index = 0x0,
@@ -3670,862 +3571,858 @@ static const struct cpu_reg cpu_reg_tpat = {
};
static u8 bnx2_TXP_b06FwText[] = {
- 0xad, 0x7b, 0x0d, 0x70, 0x94, 0xf7, 0x79, 0xe7, 0xef, 0xbf, 0x1f, 0xd2,
- 0xae, 0xb4, 0x5a, 0xad, 0xf0, 0x82, 0x57, 0x89, 0x52, 0xf6, 0xf5, 0xbe,
- 0x2b, 0x2d, 0x96, 0x80, 0x77, 0x41, 0x04, 0x11, 0x6d, 0xcd, 0x56, 0x08,
- 0x21, 0x40, 0xd8, 0x32, 0x56, 0x92, 0x25, 0xc7, 0xd4, 0x2a, 0xc8, 0x20,
- 0xdb, 0x18, 0x8b, 0x86, 0xe6, 0xe4, 0xd6, 0xad, 0xd6, 0x92, 0xc0, 0x60,
- 0x56, 0xbc, 0x22, 0x82, 0x08, 0x77, 0xee, 0x26, 0xb2, 0x25, 0x2c, 0xec,
- 0xac, 0x58, 0x3b, 0xbd, 0xeb, 0xc5, 0x33, 0xc9, 0x58, 0x67, 0x6c, 0x4c,
- 0x72, 0xfe, 0xc8, 0x75, 0x3a, 0x3d, 0xf7, 0xe6, 0xee, 0xca, 0xf8, 0x83,
- 0xd8, 0x6e, 0x8c, 0xdd, 0x4c, 0x3a, 0x27, 0x52, 0xdb, 0xef, 0xfd, 0x9e,
- 0xf7, 0xdd, 0x05, 0xe2, 0xba, 0xd3, 0x99, 0xce, 0x69, 0x66, 0x67, 0xa5,
- 0xf7, 0xe3, 0xf9, 0x3f, 0xdf, 0xcf, 0xef, 0x79, 0xfe, 0x7f, 0xd5, 0x03,
- 0x15, 0x28, 0xfe, 0x54, 0xf1, 0xd3, 0x3c, 0x30, 0x78, 0x70, 0xd5, 0x8a,
- 0xe6, 0x15, 0xf6, 0x05, 0x97, 0xc7, 0x23, 0x37, 0xbf, 0xaa, 0x80, 0xde,
- 0x0f, 0xf0, 0x6f, 0xfa, 0xf9, 0xca, 0xbf, 0xed, 0x35, 0xfb, 0xc7, 0x0d,
- 0x84, 0x4a, 0x7c, 0xc9, 0x07, 0x3e, 0x57, 0xea, 0xd2, 0xd7, 0xda, 0x74,
- 0xf8, 0xdc, 0xa9, 0x93, 0xa9, 0xdd, 0x3a, 0x90, 0xce, 0x37, 0x46, 0x37,
- 0xe0, 0x53, 0x2b, 0x1b, 0xf6, 0x40, 0xae, 0x7f, 0x25, 0xf5, 0xc9, 0xd0,
- 0x4f, 0xd6, 0x6a, 0x1f, 0x4f, 0xb9, 0xe1, 0x0b, 0xa5, 0x4e, 0x23, 0x54,
- 0x0f, 0x5f, 0x1d, 0xdf, 0xf9, 0x0f, 0x0d, 0xd5, 0x6e, 0x04, 0x4b, 0xb4,
- 0x5a, 0x30, 0x62, 0x22, 0xeb, 0x4b, 0x0d, 0xa0, 0x7c, 0x0d, 0xf0, 0x6e,
- 0x2e, 0x6e, 0x8c, 0x00, 0xe3, 0xae, 0x54, 0x3c, 0xfa, 0x22, 0x0c, 0x1c,
- 0x2a, 0x44, 0xd1, 0xce, 0xcf, 0x66, 0xf3, 0x33, 0x2b, 0xea, 0x45, 0xd6,
- 0xcd, 0xe7, 0x76, 0x35, 0x03, 0x1b, 0x73, 0x06, 0x0e, 0x9b, 0xf0, 0xd5,
- 0xa6, 0x1e, 0xc6, 0x3a, 0x7e, 0x07, 0x53, 0x83, 0x78, 0x7d, 0x2c, 0x16,
- 0x7d, 0x0a, 0x5a, 0x46, 0x77, 0x6b, 0x83, 0x40, 0x63, 0x7f, 0x9f, 0xd2,
- 0x7a, 0xdf, 0x50, 0x5a, 0xf7, 0x98, 0x82, 0x4f, 0xf1, 0xb9, 0xc6, 0xbc,
- 0x7c, 0x0f, 0xe2, 0xd6, 0xbc, 0x0f, 0x97, 0xdc, 0xb2, 0xfe, 0xef, 0x52,
- 0xdf, 0x0a, 0x1e, 0xbd, 0x05, 0xa3, 0xe4, 0xc1, 0x9b, 0x52, 0x78, 0xb2,
- 0x39, 0x1e, 0x19, 0x86, 0xdc, 0x8f, 0x62, 0x43, 0x41, 0xbe, 0x35, 0x4a,
- 0x6d, 0x59, 0xa3, 0x86, 0x65, 0x9d, 0x31, 0xca, 0x91, 0x0d, 0x69, 0x11,
- 0x40, 0x61, 0xd8, 0x70, 0x21, 0x1d, 0x6a, 0x8b, 0x7a, 0xa0, 0x45, 0xee,
- 0xc1, 0x3f, 0x51, 0xe6, 0x74, 0xc2, 0x0b, 0xe7, 0xf9, 0x5e, 0x94, 0x63,
- 0x3e, 0xe4, 0x68, 0xed, 0xc9, 0x9c, 0x65, 0x5d, 0xd0, 0x3d, 0x38, 0x43,
- 0xfd, 0x0c, 0xe7, 0xff, 0xc9, 0x9a, 0xa7, 0x6e, 0x46, 0xf5, 0xd2, 0xfa,
- 0x3e, 0x4c, 0x85, 0x2c, 0x6b, 0x9a, 0xf7, 0x0e, 0xe7, 0x4b, 0x7a, 0xb6,
- 0x2c, 0x97, 0x6e, 0x59, 0xbb, 0xf5, 0xdf, 0x58, 0xbb, 0x7e, 0xeb, 0x59,
- 0xcb, 0x7a, 0xcc, 0xb8, 0x09, 0x67, 0x27, 0xda, 0xd5, 0x96, 0xd9, 0x25,
- 0xc1, 0xcd, 0x93, 0x16, 0x2e, 0x18, 0x08, 0xb9, 0x52, 0x1d, 0x6a, 0xf3,
- 0x6c, 0xa7, 0xda, 0x58, 0xd8, 0xae, 0x3a, 0xa6, 0xbf, 0xa5, 0x3a, 0x67,
- 0x7b, 0xd5, 0xa6, 0x42, 0x04, 0x33, 0x66, 0x18, 0xd3, 0x66, 0x46, 0xb5,
- 0xcf, 0xf6, 0x28, 0x47, 0x8e, 0x41, 0xd5, 0x56, 0x28, 0xd1, 0xba, 0xae,
- 0xc7, 0xcd, 0xb9, 0x14, 0x8e, 0x98, 0xe5, 0x5c, 0x67, 0xc1, 0xfa, 0x49,
- 0xc3, 0x02, 0xe5, 0x34, 0x70, 0xb4, 0xf0, 0x18, 0xb6, 0x4d, 0x5a, 0x56,
- 0x3e, 0x09, 0xe4, 0x0b, 0xc0, 0x0f, 0xcc, 0x58, 0x77, 0xbf, 0xb2, 0xac,
- 0x4d, 0x71, 0x6b, 0xe9, 0x65, 0xa3, 0x31, 0xf1, 0x12, 0xfe, 0xaf, 0x35,
- 0x15, 0x46, 0x36, 0x40, 0x1a, 0xc7, 0x68, 0xb3, 0xfb, 0xc6, 0xe0, 0x2b,
- 0x4f, 0x8d, 0xe2, 0x17, 0x39, 0xf8, 0xca, 0x52, 0x59, 0x5c, 0xc8, 0x0d,
- 0x87, 0x7c, 0x88, 0x45, 0x36, 0xab, 0xec, 0xa0, 0x0b, 0xda, 0xc0, 0xdb,
- 0xd0, 0xa2, 0xb4, 0xc7, 0xc5, 0xf3, 0x4a, 0x9b, 0x7f, 0x09, 0x5a, 0xfa,
- 0x37, 0x4a, 0xeb, 0xac, 0x75, 0x23, 0xed, 0x8a, 0xfb, 0xf0, 0x93, 0x06,
- 0xb1, 0xc9, 0x28, 0x56, 0xd8, 0xb6, 0xc9, 0x62, 0xd9, 0x35, 0xdb, 0xa4,
- 0x30, 0x4c, 0xbe, 0x0e, 0x93, 0xaf, 0x97, 0x0d, 0x2d, 0xf2, 0x24, 0xac,
- 0xa5, 0x7d, 0x86, 0xdc, 0x4b, 0x61, 0xb4, 0x60, 0x45, 0x83, 0xa9, 0x4b,
- 0xe4, 0x17, 0xd9, 0x2f, 0xa5, 0x7c, 0xd9, 0xea, 0xd4, 0xa7, 0xd6, 0x6b,
- 0x6b, 0x22, 0x78, 0xa1, 0x10, 0xc6, 0x73, 0x85, 0x10, 0x9e, 0x2d, 0xb4,
- 0xc3, 0x2c, 0x20, 0xb8, 0xad, 0xf0, 0x45, 0x7e, 0x6c, 0x21, 0xc0, 0xe7,
- 0xc9, 0x77, 0x70, 0x6b, 0xc1, 0xd3, 0x5b, 0x96, 0x42, 0xf7, 0x4f, 0x73,
- 0x43, 0x56, 0x85, 0x8e, 0xde, 0x9a, 0x94, 0x9e, 0xbe, 0x55, 0x05, 0x5a,
- 0xe8, 0x87, 0xdd, 0xaf, 0xe4, 0x5b, 0x3c, 0xfa, 0x71, 0x3f, 0xbc, 0xd4,
- 0xff, 0xc6, 0x82, 0x65, 0x8d, 0x18, 0x07, 0x56, 0xee, 0x6a, 0xf9, 0x8b,
- 0xf9, 0x6e, 0xbd, 0x0b, 0xd9, 0x42, 0x1f, 0x10, 0x4c, 0xf1, 0x9b, 0xa1,
- 0xb8, 0xbd, 0xa9, 0x3d, 0x7a, 0xee, 0x01, 0x8f, 0xe3, 0xcf, 0xe4, 0x81,
- 0x7a, 0x7f, 0xce, 0x24, 0x0f, 0xe6, 0xe1, 0x20, 0x2a, 0xa2, 0x94, 0xef,
- 0xe7, 0xe4, 0x33, 0x81, 0x1f, 0x16, 0x74, 0xf2, 0xd6, 0x44, 0x1e, 0xa3,
- 0xe4, 0xcf, 0x87, 0x5d, 0x13, 0xda, 0x78, 0x16, 0xda, 0x91, 0x29, 0x2c,
- 0x47, 0x3a, 0x1c, 0xa2, 0x0f, 0xfe, 0x39, 0x1c, 0x1a, 0x5d, 0x38, 0x6e,
- 0x62, 0x55, 0x28, 0x45, 0xfb, 0x26, 0xf1, 0x70, 0x19, 0xe2, 0xbd, 0x1f,
- 0x2b, 0x85, 0xd7, 0xe2, 0x5d, 0x18, 0xa3, 0x3c, 0x5d, 0x79, 0x3f, 0xee,
- 0x9f, 0xa8, 0xc0, 0xbd, 0x13, 0x16, 0xee, 0x4b, 0x22, 0x55, 0x41, 0x79,
- 0x12, 0xc9, 0x78, 0xf4, 0x3d, 0x78, 0xd0, 0x9e, 0xef, 0x62, 0x2c, 0x6d,
- 0x40, 0xba, 0xcc, 0x87, 0x0d, 0xf9, 0x00, 0xe3, 0x31, 0x8d, 0xd3, 0x93,
- 0x3e, 0x78, 0x57, 0xbb, 0x30, 0x15, 0x2e, 0x43, 0xa2, 0xde, 0xc5, 0x4f,
- 0x38, 0xd8, 0x36, 0x59, 0x17, 0xdc, 0x68, 0x7a, 0xb0, 0xd7, 0x74, 0x61,
- 0x68, 0xc2, 0xb2, 0xda, 0x0d, 0x0b, 0x57, 0x57, 0x87, 0xf0, 0x3c, 0xf5,
- 0x77, 0xc0, 0x8c, 0xe0, 0x6c, 0xe1, 0x51, 0xf2, 0x12, 0x76, 0xf8, 0x35,
- 0xc9, 0xbb, 0x49, 0xde, 0x4d, 0xf2, 0x6d, 0x0a, 0x9f, 0xe7, 0x19, 0x33,
- 0x06, 0xe5, 0xf2, 0x93, 0x87, 0x4a, 0xf4, 0x93, 0x8f, 0x58, 0xd2, 0x82,
- 0x2b, 0xa9, 0x65, 0x77, 0x31, 0x79, 0x2d, 0xad, 0xb7, 0xac, 0x8f, 0x57,
- 0x8b, 0x2c, 0xb4, 0xb9, 0xab, 0x4b, 0x62, 0xf4, 0xf7, 0xaa, 0x18, 0x57,
- 0x7f, 0x4b, 0xbd, 0x3d, 0x5e, 0xf0, 0x63, 0x70, 0xc2, 0xf6, 0xdb, 0x83,
- 0x65, 0xe4, 0x5b, 0xf8, 0x2a, 0xe8, 0x71, 0xc6, 0x68, 0x3c, 0xc3, 0x18,
- 0xc5, 0x56, 0xf2, 0x7c, 0x9f, 0x19, 0x6f, 0xd9, 0xae, 0x3c, 0xd8, 0x94,
- 0x0f, 0x07, 0xdb, 0x6f, 0xe0, 0x93, 0xf2, 0x4a, 0x0c, 0x52, 0xd6, 0x10,
- 0xf9, 0x0b, 0x63, 0x37, 0xf9, 0x7c, 0xae, 0xc8, 0xe7, 0x74, 0x41, 0xd6,
- 0xfa, 0x3c, 0xaf, 0x25, 0x3e, 0x91, 0x5d, 0x94, 0x0a, 0x2b, 0x54, 0x04,
- 0xb0, 0x3d, 0xff, 0x26, 0x6d, 0x51, 0x87, 0xbf, 0xa0, 0x0d, 0x5e, 0x60,
- 0x8c, 0xfc, 0xf0, 0x9a, 0xbf, 0x88, 0x3d, 0x1e, 0xa1, 0x1d, 0xb4, 0xd3,
- 0x59, 0x04, 0xd0, 0x5b, 0x48, 0xe3, 0xd0, 0x24, 0xd2, 0x33, 0xc6, 0x31,
- 0xc6, 0xfb, 0x12, 0xb8, 0xf5, 0xf2, 0x74, 0x48, 0xaf, 0xc0, 0xee, 0xe9,
- 0x30, 0x06, 0x0a, 0x6d, 0x30, 0x27, 0xc2, 0xd8, 0x47, 0xdf, 0xbc, 0x92,
- 0x4c, 0xdf, 0x17, 0x84, 0xf0, 0x1e, 0xc6, 0xfd, 0x7c, 0xe7, 0xb1, 0xc9,
- 0x30, 0xfa, 0xa9, 0xa3, 0xcd, 0xc9, 0x78, 0x8b, 0x9f, 0xd7, 0xf6, 0xf2,
- 0xda, 0x61, 0xea, 0xff, 0xbc, 0x31, 0x86, 0xde, 0x6e, 0x2d, 0x01, 0x84,
- 0xb1, 0xc7, 0x44, 0x88, 0x2e, 0xfc, 0x08, 0xf3, 0x5b, 0xe2, 0x3c, 0xff,
- 0xbe, 0xa7, 0x50, 0x41, 0x39, 0x83, 0x88, 0xe8, 0x9f, 0x58, 0xde, 0x66,
- 0xcb, 0xfa, 0xbe, 0x11, 0xbf, 0xf8, 0x96, 0xdb, 0x83, 0x87, 0x0a, 0x2e,
- 0x0c, 0x4e, 0x57, 0xe0, 0x0f, 0x27, 0x3c, 0xb8, 0xb3, 0xbe, 0x02, 0x07,
- 0xa6, 0xd3, 0x18, 0x99, 0xac, 0x40, 0xdf, 0x04, 0x96, 0xee, 0x31, 0x46,
- 0x6a, 0xca, 0xa0, 0x2d, 0xb4, 0x23, 0x81, 0xab, 0xb4, 0xc3, 0x43, 0xd3,
- 0x81, 0x60, 0x66, 0x32, 0x84, 0xc1, 0x59, 0x3f, 0x9f, 0x77, 0xf1, 0xf9,
- 0x72, 0x18, 0xab, 0x62, 0x83, 0x21, 0x08, 0x8f, 0x95, 0xd8, 0x3f, 0xed,
- 0xc7, 0x03, 0x13, 0x21, 0xec, 0x9b, 0x6c, 0xc6, 0xb8, 0x99, 0xc6, 0x51,
- 0xe6, 0x8e, 0x1f, 0x24, 0xb5, 0xee, 0x7d, 0x4a, 0x4b, 0x6f, 0x54, 0x69,
- 0x34, 0x24, 0xbd, 0xb8, 0xc4, 0x3c, 0xe4, 0x4d, 0x36, 0xb6, 0x3c, 0xcb,
- 0xdc, 0x50, 0x96, 0x0a, 0xf3, 0x6f, 0xed, 0x08, 0x63, 0x36, 0xed, 0x75,
- 0xad, 0x06, 0x16, 0x4b, 0xfc, 0x86, 0x83, 0x5b, 0xcc, 0x50, 0x70, 0x4b,
- 0xa1, 0x2e, 0xb8, 0xd9, 0x8c, 0x04, 0x37, 0x33, 0xbe, 0x36, 0x8a, 0x3f,
- 0x9a, 0x3e, 0x1c, 0x4b, 0x7e, 0x6a, 0xf5, 0xd6, 0xd8, 0xf9, 0x2c, 0xb8,
- 0x6d, 0x52, 0xcb, 0x4e, 0x41, 0x33, 0x58, 0x0d, 0x30, 0x36, 0xeb, 0xa1,
- 0xfd, 0x14, 0x6a, 0xf4, 0x66, 0xe6, 0xf1, 0x10, 0xf6, 0x33, 0xa7, 0xfc,
- 0x15, 0x73, 0x4a, 0xdf, 0xf1, 0x58, 0x68, 0x1c, 0x7e, 0xea, 0x1b, 0xd8,
- 0x75, 0x2e, 0x4c, 0x9b, 0x77, 0xe2, 0x51, 0xf2, 0xb5, 0x79, 0x4d, 0x18,
- 0xf7, 0x16, 0x42, 0xc1, 0x4e, 0xda, 0xef, 0xbd, 0x7c, 0x24, 0xb8, 0x81,
- 0xb6, 0x7c, 0x3b, 0xaf, 0x45, 0xe7, 0xf1, 0x8f, 0xe2, 0x4f, 0x09, 0xb8,
- 0x80, 0x3d, 0xc7, 0xbd, 0x98, 0x0f, 0xcb, 0x5a, 0xd4, 0xb9, 0xf9, 0x82,
- 0x15, 0xd0, 0xf5, 0xd3, 0xfb, 0xa8, 0xeb, 0x6f, 0x17, 0x02, 0x78, 0xc0,
- 0xd4, 0x12, 0x3f, 0x54, 0x01, 0xea, 0xd4, 0x47, 0x3d, 0x30, 0xc1, 0x2c,
- 0x91, 0xe7, 0x92, 0x88, 0x2e, 0x71, 0x72, 0xed, 0x81, 0x69, 0xf1, 0x13,
- 0xda, 0xde, 0xa4, 0x0f, 0xd0, 0x7f, 0x7e, 0x78, 0x2d, 0x56, 0xb5, 0x50,
- 0xd6, 0xce, 0xdd, 0x09, 0xfa, 0x8b, 0xa3, 0xa3, 0x13, 0x93, 0xa2, 0x07,
- 0x6d, 0x1c, 0xae, 0x34, 0x56, 0xae, 0xfa, 0x2b, 0xeb, 0xd2, 0x62, 0xd1,
- 0x47, 0x08, 0x43, 0xd4, 0xe1, 0x69, 0xd3, 0xb2, 0xae, 0xae, 0xfe, 0xd0,
- 0x6a, 0xb9, 0x59, 0xf4, 0x22, 0xb2, 0x3e, 0xaf, 0xa4, 0x8e, 0xd4, 0xe8,
- 0xc1, 0xff, 0x0f, 0xbe, 0xf2, 0x1d, 0xab, 0xd7, 0x96, 0x4f, 0xfc, 0xc5,
- 0x43, 0x5f, 0x7c, 0x94, 0xb4, 0x5d, 0xe8, 0x25, 0xbd, 0x07, 0x4d, 0xeb,
- 0xa3, 0xda, 0xd4, 0x67, 0x56, 0xcb, 0x5a, 0x7d, 0x60, 0x41, 0xfd, 0x0f,
- 0x5e, 0x0f, 0x63, 0x7f, 0xa1, 0x85, 0xba, 0x6b, 0xc7, 0x63, 0xd4, 0xe1,
- 0x61, 0x53, 0x72, 0x62, 0x84, 0xfe, 0x5c, 0x47, 0xff, 0xf6, 0xa8, 0x8d,
- 0x66, 0x1e, 0x9b, 0xc7, 0xb2, 0xd8, 0x44, 0x7f, 0xbf, 0x98, 0x8b, 0xb5,
- 0x3c, 0x0d, 0x2d, 0x4b, 0x19, 0x82, 0x9d, 0xd4, 0x71, 0xbb, 0xa9, 0x75,
- 0x8a, 0x4d, 0xdb, 0x99, 0x97, 0x5e, 0xcc, 0x45, 0x82, 0x6d, 0x05, 0xd1,
- 0x77, 0x5d, 0x70, 0x43, 0xe1, 0xab, 0xb4, 0xbd, 0xc2, 0xba, 0xe5, 0x3e,
- 0xe6, 0x99, 0x3b, 0xe1, 0xd8, 0xd5, 0xb1, 0xdd, 0x6b, 0xc9, 0xc6, 0xde,
- 0x0f, 0x99, 0x9f, 0xb2, 0x8b, 0x9d, 0x6b, 0x83, 0xbc, 0x56, 0xbd, 0x1a,
- 0xc1, 0x3b, 0xe8, 0x07, 0x77, 0xd3, 0x0f, 0xae, 0xae, 0xfe, 0xd4, 0x8a,
- 0xde, 0xe4, 0xf8, 0x41, 0xdb, 0xa4, 0x27, 0xd8, 0x41, 0x3d, 0x6d, 0x34,
- 0x14, 0xa6, 0x8d, 0x1c, 0x7a, 0xaf, 0x61, 0x87, 0xf4, 0xd4, 0x59, 0x23,
- 0xcd, 0x3c, 0xf2, 0xbb, 0xf0, 0xd4, 0x60, 0xea, 0x69, 0xe3, 0x51, 0x44,
- 0x1d, 0xdf, 0xc1, 0xbe, 0x09, 0x3f, 0xb2, 0x77, 0x86, 0x30, 0xd3, 0x10,
- 0xc2, 0x83, 0xa4, 0x7d, 0x25, 0xd9, 0xd8, 0xff, 0x3a, 0x75, 0x30, 0x55,
- 0x23, 0xd7, 0xd2, 0xf8, 0x91, 0xf1, 0x30, 0x70, 0x93, 0xb3, 0xf6, 0xac,
- 0xc4, 0xe8, 0x6c, 0x33, 0x0e, 0x17, 0x32, 0xca, 0xc9, 0x9b, 0x5a, 0x67,
- 0x1a, 0x3f, 0xb7, 0x24, 0x97, 0xce, 0x9a, 0xcc, 0x71, 0xd4, 0xc7, 0x28,
- 0xfd, 0x68, 0x38, 0x5f, 0x17, 0xdc, 0x44, 0x3f, 0x7a, 0x34, 0x2f, 0x32,
- 0xc5, 0x0d, 0xc3, 0x5d, 0xcb, 0xda, 0x4c, 0xfd, 0x98, 0x76, 0xcd, 0xaf,
- 0x0e, 0xe9, 0x47, 0x31, 0x6e, 0xf3, 0x36, 0xa8, 0x32, 0xc4, 0x18, 0x0c,
- 0x99, 0xea, 0x72, 0xfd, 0x00, 0x1e, 0xb5, 0xaf, 0x85, 0x83, 0x3b, 0x26,
- 0xd3, 0x2e, 0x97, 0x8e, 0x50, 0x65, 0xaa, 0x5d, 0xed, 0x60, 0xdd, 0xed,
- 0x98, 0xec, 0x50, 0x1d, 0xb3, 0x12, 0x03, 0x9d, 0x6a, 0x33, 0x6b, 0x6e,
- 0x9a, 0x35, 0x37, 0xcd, 0x9a, 0x9b, 0x26, 0x1f, 0x69, 0xd6, 0xda, 0xb6,
- 0xc2, 0xa0, 0xda, 0x2a, 0xfa, 0xa7, 0x7f, 0x3d, 0x6b, 0x3a, 0x38, 0x82,
- 0x39, 0x28, 0xb8, 0xa9, 0xb0, 0xc2, 0xe5, 0x60, 0xbb, 0x41, 0x55, 0xc4,
- 0x32, 0xbe, 0x0a, 0x9d, 0xb5, 0xcc, 0x1c, 0x54, 0x5b, 0x58, 0x6f, 0x33,
- 0xb6, 0x2e, 0x63, 0x03, 0xef, 0xb0, 0xce, 0xbe, 0xc6, 0x3a, 0x9b, 0x4f,
- 0x32, 0xae, 0x96, 0x5f, 0xb5, 0x7a, 0x17, 0x3b, 0x35, 0x61, 0x84, 0xfc,
- 0x7e, 0x9f, 0x36, 0x9b, 0x67, 0x2d, 0x6d, 0x77, 0x2b, 0xec, 0xd1, 0x51,
- 0x5d, 0xcb, 0x9c, 0x7a, 0xb8, 0xc0, 0x3a, 0x60, 0xc4, 0x5a, 0xde, 0xa7,
- 0x62, 0x0f, 0xeb, 0x5e, 0x5c, 0xbd, 0x89, 0x60, 0x47, 0x6f, 0xc3, 0xb1,
- 0x89, 0x72, 0xf4, 0x27, 0xd3, 0x8b, 0x7c, 0xc4, 0x2a, 0x9d, 0xcd, 0x78,
- 0x98, 0x4b, 0xab, 0x48, 0x2a, 0x4e, 0xbf, 0x41, 0xfa, 0x38, 0xeb, 0xc4,
- 0x98, 0xf9, 0x55, 0xe4, 0x59, 0x4f, 0x67, 0x0c, 0x0f, 0x5e, 0xcb, 0xaf,
- 0x60, 0x9e, 0x8b, 0x1b, 0x01, 0x55, 0xc1, 0xf8, 0x4d, 0x21, 0x67, 0x4a,
- 0x7e, 0xb2, 0xac, 0x19, 0xe1, 0x21, 0x1e, 0x4f, 0x0f, 0x43, 0x72, 0x96,
- 0xb5, 0xf4, 0x9e, 0x64, 0x19, 0xd6, 0xc5, 0x83, 0x58, 0xaa, 0xf7, 0xaa,
- 0xce, 0x42, 0xdc, 0x38, 0x8f, 0x6f, 0xa9, 0xbb, 0x67, 0x53, 0x8c, 0xed,
- 0x0c, 0x75, 0x53, 0x81, 0x4b, 0x61, 0xe1, 0x11, 0xd5, 0x5e, 0xdd, 0x85,
- 0x77, 0xef, 0x52, 0x08, 0xe9, 0x69, 0x5c, 0x68, 0x0e, 0xd1, 0xaf, 0x3a,
- 0x89, 0x31, 0xa2, 0x70, 0xcf, 0x45, 0x82, 0x5b, 0x69, 0x8b, 0xca, 0xb9,
- 0x3a, 0xda, 0x87, 0xbe, 0x47, 0x1d, 0xb6, 0x51, 0x87, 0x5b, 0xa6, 0x11,
- 0xaa, 0x48, 0xf5, 0xa8, 0x8e, 0x42, 0xbb, 0x6a, 0x2f, 0x68, 0xd4, 0x93,
- 0xe8, 0xe4, 0x3b, 0xc4, 0x4a, 0xe2, 0x2b, 0x25, 0x5b, 0x8a, 0xbf, 0xde,
- 0x68, 0xcf, 0x8c, 0x4b, 0x62, 0x6e, 0xdd, 0xf2, 0x14, 0xe3, 0xd1, 0x45,
- 0xbe, 0x84, 0x07, 0x1f, 0xaa, 0x1b, 0xac, 0xa5, 0x57, 0x92, 0x4c, 0x9e,
- 0x15, 0x29, 0x1c, 0x2f, 0x74, 0xd1, 0x2e, 0xab, 0x8b, 0xfe, 0x15, 0x0a,
- 0x6e, 0x9c, 0x6c, 0x57, 0x1b, 0x67, 0x17, 0x05, 0xbb, 0x69, 0xc3, 0xee,
- 0xd9, 0x88, 0xd0, 0xe5, 0xfa, 0x62, 0xdb, 0x34, 0x5c, 0xfa, 0xbf, 0x64,
- 0xcb, 0x6f, 0x93, 0x96, 0xd8, 0xd3, 0x5f, 0xf2, 0xd3, 0xe0, 0xdd, 0x93,
- 0x69, 0xbc, 0xbb, 0xda, 0xcb, 0x9a, 0x5a, 0xc2, 0x14, 0x55, 0xc5, 0xef,
- 0xd3, 0x2e, 0xe8, 0x83, 0xaa, 0x53, 0xfc, 0xc8, 0xeb, 0xac, 0x79, 0xc7,
- 0x24, 0xbc, 0x84, 0x0a, 0x51, 0x37, 0x31, 0xdd, 0x87, 0xc9, 0x78, 0xef,
- 0x39, 0xd5, 0xa5, 0xba, 0x0a, 0x52, 0x83, 0x1d, 0x9f, 0x6a, 0xa3, 0x4f,
- 0xb5, 0x93, 0x9f, 0x76, 0xfa, 0xd4, 0x16, 0xf2, 0xb3, 0xc5, 0xf6, 0x29,
- 0xf1, 0xcd, 0xdf, 0xe6, 0x65, 0x43, 0xe1, 0x6e, 0x5b, 0x2f, 0x5b, 0xf9,
- 0x6e, 0x27, 0xe5, 0xe8, 0xe4, 0x7b, 0x77, 0xf3, 0xbd, 0xbb, 0x67, 0xff,
- 0x97, 0xf0, 0x47, 0x59, 0x9c, 0xd8, 0xbf, 0x5e, 0xd3, 0x24, 0x07, 0xfc,
- 0xac, 0x88, 0x29, 0x90, 0x75, 0xa5, 0x24, 0x47, 0x0c, 0xa0, 0xbb, 0x19,
- 0xbe, 0x45, 0xa9, 0x67, 0x5b, 0xb7, 0xd7, 0x33, 0x9f, 0x31, 0x9f, 0xfa,
- 0x8e, 0x13, 0x4b, 0x33, 0x47, 0xcf, 0xb4, 0x28, 0x8c, 0x18, 0x37, 0x33,
- 0x4e, 0x0d, 0x1c, 0x29, 0x68, 0x9d, 0x51, 0xde, 0x6b, 0x1a, 0x13, 0x8c,
- 0xbf, 0x0f, 0x6d, 0xc4, 0x75, 0x91, 0x54, 0x3f, 0x22, 0x66, 0x2c, 0x72,
- 0x44, 0x69, 0xfd, 0x1b, 0xa0, 0x5d, 0x64, 0x6d, 0x18, 0x9c, 0x56, 0xda,
- 0x40, 0xad, 0x5b, 0x4b, 0xbf, 0x61, 0xe3, 0xeb, 0x7d, 0x58, 0x6e, 0x63,
- 0xb8, 0x7e, 0x24, 0x88, 0x65, 0xb7, 0x92, 0xe6, 0xde, 0x75, 0x0a, 0x97,
- 0x8d, 0x0f, 0x69, 0x47, 0x2d, 0x9d, 0x55, 0x06, 0x72, 0xcc, 0x13, 0x91,
- 0xe3, 0x82, 0xd5, 0xf7, 0x11, 0xab, 0xc3, 0x17, 0xe0, 0xb3, 0xb9, 0xb1,
- 0xd8, 0xa0, 0xcf, 0xad, 0x25, 0x88, 0xd3, 0xd3, 0xa4, 0x69, 0x14, 0x88,
- 0xdf, 0xb9, 0x46, 0x74, 0x4f, 0x91, 0x66, 0xbc, 0x48, 0x53, 0xcf, 0x83,
- 0x71, 0x73, 0x04, 0x9b, 0xe2, 0xac, 0x15, 0xcc, 0x79, 0x47, 0xa5, 0x27,
- 0x20, 0xbd, 0xf2, 0xe3, 0x06, 0xff, 0x1e, 0x54, 0x3b, 0x24, 0xa6, 0xca,
- 0x1d, 0x2b, 0x54, 0x73, 0x8d, 0xaa, 0xd4, 0x41, 0xcc, 0xd9, 0x6b, 0x0c,
- 0xc8, 0x1a, 0x03, 0xbf, 0x50, 0x5a, 0xe2, 0x9c, 0x92, 0x5c, 0xdd, 0x98,
- 0x39, 0xc7, 0x18, 0x3a, 0xac, 0xb4, 0x96, 0x63, 0x14, 0xdf, 0xaf, 0x0b,
- 0xfd, 0x83, 0xc5, 0x75, 0x06, 0xd0, 0x90, 0x67, 0x7c, 0x16, 0x7c, 0x6a,
- 0xc3, 0x44, 0x1b, 0x46, 0xa6, 0xdb, 0x30, 0x3c, 0xa1, 0x70, 0xb7, 0xb1,
- 0x18, 0x97, 0x6e, 0xb6, 0xfb, 0x94, 0xaa, 0xa5, 0x7a, 0x2d, 0x86, 0x42,
- 0xa8, 0x76, 0xe9, 0x5f, 0xc1, 0xae, 0x22, 0xc6, 0xdf, 0x74, 0xa2, 0x9b,
- 0x79, 0xdf, 0xc2, 0xfb, 0x8c, 0xa5, 0x58, 0x0d, 0xd2, 0xde, 0x54, 0x0b,
- 0xf1, 0x78, 0x9d, 0xdb, 0x89, 0xf7, 0x0f, 0x7d, 0x8e, 0x0d, 0x44, 0xff,
- 0x9f, 0xbf, 0xd7, 0x86, 0xc7, 0x27, 0xca, 0xd0, 0xb2, 0x1a, 0x77, 0x46,
- 0x50, 0xe5, 0x62, 0x8d, 0x7b, 0x73, 0xbb, 0x1a, 0xe4, 0x3d, 0xfb, 0x59,
- 0xdf, 0x97, 0x53, 0x46, 0xea, 0x4f, 0x1a, 0xe4, 0xba, 0x9d, 0x37, 0x6e,
- 0xb8, 0xde, 0xfd, 0x05, 0xd7, 0x15, 0x9e, 0x61, 0x22, 0xfb, 0x01, 0x6b,
- 0x4a, 0x3e, 0x67, 0xc1, 0x9d, 0xf2, 0xa0, 0x7f, 0x2c, 0x8a, 0x7d, 0x73,
- 0x61, 0xcc, 0xe5, 0xb4, 0xde, 0x4b, 0xec, 0x1f, 0x76, 0x35, 0xeb, 0x78,
- 0x60, 0x2e, 0x82, 0xd9, 0x1c, 0x2c, 0x7f, 0x4a, 0x9f, 0xf7, 0xab, 0x04,
- 0xf6, 0xce, 0xd5, 0xe1, 0x5c, 0x4e, 0xbf, 0x38, 0xac, 0xe2, 0x83, 0xb5,
- 0xc4, 0x1d, 0x0f, 0xce, 0x35, 0x61, 0xff, 0x9c, 0x8f, 0xef, 0x58, 0xd8,
- 0x92, 0xac, 0xe3, 0xf3, 0x2e, 0x3c, 0x7d, 0xd2, 0xb2, 0x04, 0x77, 0xf5,
- 0xcf, 0x01, 0xb3, 0xe3, 0xac, 0x45, 0x67, 0x58, 0x97, 0x9e, 0x00, 0xf6,
- 0x3e, 0xe1, 0xc2, 0xf4, 0xb8, 0x85, 0x5d, 0xc6, 0x70, 0xad, 0x8b, 0x0e,
- 0xdf, 0xcb, 0xba, 0xe1, 0x65, 0x0d, 0xbc, 0x27, 0xe4, 0xe4, 0xf3, 0x4b,
- 0xcc, 0x53, 0xf7, 0x3d, 0x91, 0xc0, 0x9b, 0xb9, 0x2c, 0xb6, 0x10, 0x9f,
- 0x0f, 0x92, 0x97, 0x37, 0x72, 0xac, 0x63, 0x73, 0x06, 0x5e, 0xcf, 0xf9,
- 0xb8, 0x4e, 0x13, 0x5e, 0xca, 0xc9, 0x33, 0xf2, 0x6c, 0x00, 0x7d, 0xe4,
- 0xe5, 0xb5, 0x5c, 0x84, 0x6b, 0x86, 0xf1, 0x53, 0x3e, 0x77, 0xef, 0x9c,
- 0xce, 0xba, 0xe5, 0xe3, 0xba, 0x51, 0xbc, 0x92, 0x0b, 0x90, 0xd7, 0x30,
- 0x6b, 0x55, 0x1f, 0x46, 0x72, 0x8d, 0x17, 0x37, 0x30, 0x51, 0x3b, 0xb5,
- 0x46, 0xae, 0xbd, 0x63, 0x75, 0xd9, 0xb1, 0x28, 0xeb, 0x94, 0xd6, 0xed,
- 0xc3, 0x70, 0xee, 0x75, 0x77, 0xa9, 0x9f, 0x7e, 0x66, 0x7c, 0xc1, 0xc6,
- 0x7e, 0x4f, 0x9b, 0xfc, 0x7d, 0x1a, 0x38, 0x67, 0x66, 0xad, 0xea, 0x14,
- 0xb1, 0x2e, 0x6b, 0xd4, 0x5b, 0x6b, 0x9a, 0xb8, 0xae, 0xde, 0xfb, 0xa2,
- 0x92, 0x7e, 0xc7, 0x83, 0xe8, 0x13, 0xa2, 0x2f, 0x62, 0xe6, 0x59, 0xe0,
- 0x47, 0xc4, 0x9f, 0x0d, 0x63, 0x9a, 0xf8, 0x7d, 0x86, 0xb8, 0xa6, 0x7b,
- 0x1e, 0xf5, 0x89, 0x07, 0x30, 0x64, 0x95, 0x11, 0x9f, 0x57, 0x13, 0xd7,
- 0xce, 0x35, 0xb1, 0x4e, 0xad, 0xb1, 0xac, 0xbf, 0x6d, 0x86, 0xe5, 0x4a,
- 0xe9, 0x46, 0xad, 0x7b, 0xfe, 0x2b, 0x55, 0xd0, 0x2f, 0x06, 0x95, 0x3e,
- 0xff, 0x16, 0xe2, 0x03, 0xe7, 0x21, 0x7a, 0x05, 0x56, 0xcc, 0x79, 0xb0,
- 0x92, 0xf2, 0x6c, 0x1c, 0xe3, 0xda, 0xc4, 0x27, 0x71, 0xca, 0xb4, 0x6d,
- 0x8c, 0x98, 0x4b, 0x0f, 0x60, 0x39, 0x75, 0xdc, 0x7f, 0xca, 0xb2, 0xca,
- 0xa9, 0xe3, 0x06, 0xda, 0x67, 0xcf, 0x09, 0x0b, 0x2f, 0x1a, 0x2f, 0x52,
- 0xa7, 0x8a, 0xb8, 0xb1, 0x99, 0xef, 0x84, 0xf9, 0xbc, 0x0f, 0x7b, 0xc7,
- 0xa4, 0x5f, 0xaa, 0xe3, 0x33, 0xaf, 0xe2, 0x58, 0x2e, 0x81, 0x26, 0xea,
- 0x2f, 0x4a, 0x9a, 0x8d, 0x7c, 0x27, 0x4a, 0x7a, 0xd1, 0xb9, 0xaf, 0x61,
- 0xf3, 0x29, 0x05, 0x3d, 0x2e, 0x3a, 0xf8, 0x1a, 0xda, 0xcf, 0x7c, 0x51,
- 0x4e, 0x60, 0x96, 0x1a, 0xd7, 0x8e, 0xcc, 0x13, 0x7f, 0x57, 0xa5, 0x86,
- 0xc0, 0xfa, 0x8d, 0x37, 0xa6, 0x14, 0x8e, 0x8f, 0xb3, 0xdf, 0x5b, 0x03,
- 0xab, 0x82, 0x32, 0xbd, 0x3e, 0xf5, 0x3b, 0x78, 0xea, 0x24, 0xf5, 0xf0,
- 0x64, 0x18, 0x3f, 0xc8, 0x79, 0xb0, 0xec, 0xb8, 0x60, 0x3a, 0x3d, 0xb1,
- 0x4f, 0x49, 0x7f, 0x24, 0x7d, 0x4b, 0x3c, 0xea, 0x55, 0x2e, 0xd4, 0x3f,
- 0xe5, 0x81, 0x7e, 0x2e, 0x0a, 0x6f, 0xbd, 0x0f, 0x7a, 0xfd, 0x1f, 0x32,
- 0xd7, 0xb8, 0x50, 0xc6, 0x5e, 0x76, 0xd3, 0x77, 0x13, 0xbc, 0x16, 0xe6,
- 0x35, 0xfc, 0x4e, 0x39, 0xdc, 0x4b, 0xdc, 0xac, 0xe1, 0x65, 0x3a, 0xf1,
- 0x98, 0xc7, 0xb2, 0xdc, 0xac, 0x0d, 0x3b, 0xbe, 0x67, 0x59, 0xb1, 0xd5,
- 0xf2, 0x7c, 0x08, 0xb1, 0x73, 0x3a, 0x9f, 0x73, 0xea, 0xe5, 0x75, 0x3c,
- 0xe6, 0xa6, 0x1f, 0x49, 0xac, 0xb2, 0xde, 0xdb, 0x3d, 0x94, 0x83, 0xdb,
- 0x9f, 0x2b, 0x08, 0xb6, 0x89, 0xda, 0x32, 0x9c, 0x1d, 0x57, 0xcc, 0xd9,
- 0x29, 0x3e, 0xbb, 0x1e, 0xee, 0xa4, 0x76, 0x24, 0x4b, 0x3f, 0xd8, 0x15,
- 0x6a, 0xc1, 0x33, 0xa6, 0x17, 0x95, 0xfa, 0x12, 0xdc, 0xdf, 0x1d, 0xc2,
- 0x33, 0xec, 0x0b, 0x68, 0xb3, 0xc4, 0x3c, 0xd8, 0x48, 0x07, 0x49, 0xcf,
- 0xf5, 0x63, 0xe8, 0xdf, 0x75, 0x31, 0xcf, 0xb9, 0xed, 0x3c, 0x57, 0x56,
- 0x0f, 0xcc, 0xe7, 0x3d, 0xb8, 0xa0, 0x3b, 0x98, 0xf0, 0x39, 0xbb, 0x66,
- 0x6b, 0xa1, 0xf9, 0x6b, 0x58, 0x50, 0x6b, 0x49, 0x2b, 0x32, 0x13, 0x14,
- 0xdd, 0x65, 0x3c, 0x8e, 0x2f, 0xfd, 0x8d, 0x5b, 0x7a, 0x8e, 0xeb, 0x7f,
- 0x57, 0xc0, 0x95, 0xd2, 0x22, 0x6d, 0x6e, 0xf8, 0x3c, 0xa9, 0xce, 0xd6,
- 0x51, 0xfd, 0x4b, 0x37, 0xf0, 0xde, 0x84, 0x91, 0xc2, 0xf5, 0x5e, 0xbb,
- 0x33, 0x67, 0xfb, 0x50, 0xa7, 0xe8, 0xfe, 0x31, 0x43, 0xf2, 0xec, 0xa0,
- 0x6a, 0x67, 0xde, 0xca, 0x7a, 0x90, 0xad, 0xe2, 0x33, 0xd4, 0x3f, 0x0e,
- 0x8f, 0x09, 0x9d, 0x83, 0x18, 0xcd, 0xc9, 0x6c, 0x63, 0x00, 0xeb, 0xcc,
- 0x58, 0xe2, 0x22, 0x7b, 0xe8, 0x43, 0x90, 0x39, 0x44, 0xe3, 0xfc, 0xcb,
- 0x4a, 0x1b, 0xbc, 0xc5, 0xad, 0xf5, 0x2f, 0x28, 0x27, 0x6f, 0xad, 0x28,
- 0xe6, 0xad, 0xe5, 0xf9, 0x25, 0xc1, 0x2e, 0xd6, 0x83, 0xae, 0xd9, 0x52,
- 0x7d, 0xe8, 0x52, 0x9b, 0xec, 0xda, 0x9a, 0x51, 0x5b, 0x67, 0x7d, 0xaa,
- 0x63, 0xc2, 0x87, 0x97, 0x89, 0xc5, 0xa6, 0x7a, 0x10, 0x5a, 0xb6, 0x06,
- 0xfe, 0xad, 0x13, 0xdd, 0x28, 0xd7, 0xa5, 0x87, 0x2c, 0xc7, 0x26, 0xbb,
- 0xae, 0xd5, 0x05, 0xbb, 0x58, 0x7f, 0xba, 0x0a, 0x3d, 0xcc, 0x7f, 0x08,
- 0xf9, 0x53, 0xce, 0xcc, 0x40, 0x72, 0xe1, 0xed, 0x7c, 0xf7, 0x62, 0x72,
- 0x11, 0xe0, 0xd4, 0x3f, 0x95, 0x61, 0x2f, 0x51, 0xbd, 0x5a, 0xe1, 0xd2,
- 0x9d, 0x3e, 0x90, 0x16, 0x7b, 0xfe, 0x7c, 0xeb, 0x85, 0xf1, 0x6e, 0xd5,
- 0x31, 0x3d, 0xe3, 0xdf, 0x68, 0xca, 0x2c, 0x62, 0xca, 0xdf, 0x4e, 0x1e,
- 0xda, 0x67, 0x9f, 0xf4, 0x6f, 0x20, 0x4f, 0x1b, 0x66, 0x3f, 0x4f, 0x53,
- 0xea, 0x4a, 0x7f, 0x6b, 0x1b, 0x63, 0x7b, 0x87, 0xf1, 0x91, 0x15, 0xfd,
- 0xa6, 0xd0, 0x99, 0x2b, 0xea, 0x33, 0x4d, 0xbe, 0xc2, 0xbe, 0x4d, 0x85,
- 0x90, 0x2f, 0x5d, 0x68, 0xf7, 0xb7, 0x99, 0xdd, 0xfe, 0x0d, 0x66, 0x8f,
- 0xbf, 0xdd, 0xdc, 0x49, 0xda, 0x5d, 0xfe, 0x0e, 0x93, 0x71, 0x5d, 0xe8,
- 0xa1, 0x5e, 0xbb, 0x31, 0x5a, 0xd8, 0x49, 0xec, 0x21, 0x34, 0x7b, 0x89,
- 0x83, 0xfc, 0x94, 0x71, 0x88, 0x32, 0xce, 0x47, 0xbc, 0x48, 0x6b, 0x5e,
- 0xea, 0x6b, 0xc4, 0xb6, 0xe3, 0x11, 0x7b, 0x16, 0x55, 0x91, 0x7a, 0xa0,
- 0x75, 0xcb, 0x09, 0xe6, 0xfb, 0xd4, 0x9e, 0xd6, 0x65, 0xa7, 0x50, 0xe3,
- 0x4d, 0x49, 0xef, 0xcc, 0x7e, 0x38, 0x1e, 0x37, 0xde, 0x43, 0x3c, 0xf2,
- 0x32, 0x9f, 0x1d, 0xa6, 0xef, 0x8e, 0xd8, 0xf3, 0x07, 0x1a, 0x24, 0xdf,
- 0x84, 0x2d, 0xa6, 0xcf, 0xbf, 0x8d, 0xbd, 0x59, 0x30, 0xa5, 0xb5, 0xdc,
- 0xee, 0x96, 0x79, 0xc8, 0xfc, 0xef, 0x05, 0xd0, 0x84, 0xce, 0x82, 0x8f,
- 0x72, 0x7d, 0x09, 0x7f, 0x7f, 0x92, 0x75, 0x0d, 0xe2, 0x87, 0x96, 0x75,
- 0x2f, 0xfb, 0x9a, 0xa3, 0xf9, 0x3a, 0x5c, 0xb6, 0x6d, 0xec, 0xc1, 0xe1,
- 0x7c, 0x14, 0xef, 0x50, 0x3e, 0xcf, 0x5c, 0x2d, 0xde, 0x1e, 0x77, 0x63,
- 0xb7, 0x71, 0x5b, 0xb1, 0x5e, 0xb8, 0x70, 0x4f, 0xe2, 0x00, 0xb1, 0x83,
- 0x0b, 0xd5, 0xc4, 0x6f, 0x0f, 0xda, 0xd7, 0xdc, 0xec, 0xff, 0xbe, 0x8e,
- 0x41, 0xa7, 0x9e, 0x90, 0xc7, 0x9d, 0xe4, 0xb1, 0xd9, 0xbf, 0x61, 0x42,
- 0xf3, 0xdf, 0x31, 0x01, 0x9f, 0x37, 0xb5, 0xab, 0xf5, 0xcc, 0x49, 0x0b,
- 0x7d, 0xc6, 0xad, 0xb8, 0x72, 0x72, 0xb8, 0xdf, 0x43, 0xff, 0xf9, 0x65,
- 0x32, 0x03, 0x73, 0x12, 0x17, 0x88, 0x3c, 0x5e, 0x0d, 0x30, 0xb7, 0x37,
- 0x24, 0xe3, 0x21, 0xd6, 0x62, 0x63, 0x96, 0xb1, 0xd9, 0x01, 0xad, 0x9f,
- 0x35, 0x39, 0xed, 0x4e, 0xc5, 0x7b, 0x47, 0x08, 0x1e, 0xab, 0xc8, 0x8f,
- 0x9f, 0xb9, 0x3b, 0x30, 0x17, 0xf5, 0xef, 0x60, 0xbd, 0x89, 0xb0, 0xbf,
- 0xf3, 0xc7, 0x71, 0x5b, 0x2d, 0xe2, 0x89, 0x05, 0xca, 0xed, 0x9d, 0x6b,
- 0xf2, 0xdf, 0xce, 0xfa, 0x71, 0x39, 0x6e, 0x0d, 0xbd, 0x68, 0x04, 0x10,
- 0x9c, 0x33, 0xa8, 0xef, 0x0c, 0x86, 0x67, 0xd9, 0x72, 0xc5, 0xd9, 0xf3,
- 0xcf, 0xb5, 0xf8, 0xb7, 0x31, 0x36, 0xab, 0x68, 0xa2, 0xc6, 0xb9, 0xb4,
- 0x5f, 0x7a, 0xbe, 0xa6, 0xb9, 0xb5, 0xe4, 0x4f, 0x7c, 0x74, 0x5f, 0xeb,
- 0x3a, 0xfa, 0x43, 0x74, 0x0e, 0x9b, 0x98, 0xe6, 0x5e, 0x22, 0xcd, 0x4c,
- 0x84, 0x18, 0x76, 0xef, 0x9a, 0x00, 0xf3, 0x94, 0xe8, 0x92, 0x7a, 0x2c,
- 0x94, 0x64, 0x92, 0xba, 0xbc, 0xa7, 0x75, 0xee, 0x94, 0xd4, 0xe5, 0x4c,
- 0x6b, 0xee, 0x94, 0x8e, 0x77, 0x58, 0x5b, 0x56, 0x24, 0x35, 0xe3, 0x9c,
- 0x8a, 0x45, 0x5e, 0xa5, 0x2c, 0x1e, 0xfc, 0xca, 0xda, 0xa5, 0xc7, 0xe7,
- 0x6f, 0x61, 0x3c, 0x55, 0x33, 0x37, 0x46, 0x98, 0xf3, 0xab, 0xe7, 0xa8,
- 0x98, 0x39, 0xb7, 0x17, 0x15, 0x11, 0xf8, 0xe2, 0x3a, 0xde, 0x3d, 0x99,
- 0xa0, 0x1e, 0xae, 0xd1, 0xdc, 0x47, 0xa8, 0xd5, 0xc7, 0x52, 0xf8, 0xc8,
- 0x53, 0xf4, 0xc5, 0x51, 0xae, 0x5b, 0x36, 0x27, 0x3c, 0xcb, 0xf3, 0x61,
- 0x3e, 0x7f, 0x7d, 0xed, 0x6a, 0xae, 0xfd, 0xd1, 0x29, 0xf1, 0xd7, 0x4c,
- 0xeb, 0x85, 0x93, 0xce, 0xda, 0xf1, 0x64, 0x02, 0x1f, 0x9e, 0xd4, 0x06,
- 0xde, 0x55, 0xb1, 0xde, 0x0b, 0x4a, 0xd6, 0x47, 0x5d, 0x15, 0xae, 0x58,
- 0xc3, 0xf1, 0xf8, 0xe0, 0x2e, 0xd2, 0x6c, 0x59, 0x4b, 0xfd, 0xdb, 0x7c,
- 0xd0, 0xe7, 0x99, 0x67, 0xbd, 0xe4, 0xc7, 0xe1, 0xa5, 0x8e, 0xb4, 0x4f,
- 0x16, 0x7b, 0x35, 0xf6, 0xa9, 0xd7, 0xf9, 0x09, 0x53, 0x0f, 0xbe, 0x1d,
- 0xcd, 0x01, 0xd4, 0xda, 0xcf, 0x85, 0xf8, 0x9c, 0xe8, 0xe1, 0xd7, 0xca,
- 0xa5, 0xbf, 0xc7, 0x3c, 0x26, 0xb9, 0x24, 0xcc, 0x1c, 0xb6, 0x53, 0x7a,
- 0xda, 0x6c, 0x96, 0xfe, 0xee, 0xa5, 0xbf, 0x6f, 0x14, 0x9f, 0x36, 0xe9,
- 0xd3, 0x26, 0x7d, 0xda, 0xd4, 0x22, 0x03, 0x88, 0x85, 0xfa, 0x68, 0xb7,
- 0x74, 0x44, 0x7c, 0xbd, 0x07, 0xbb, 0xf9, 0xd9, 0xc3, 0xfb, 0x87, 0xd9,
- 0xe7, 0x62, 0x91, 0xac, 0x79, 0x10, 0xed, 0xe6, 0x23, 0xe8, 0x9f, 0xc0,
- 0x6f, 0xfc, 0xcd, 0xe5, 0x28, 0x5f, 0x2e, 0x3d, 0xbc, 0x16, 0x3a, 0x8a,
- 0x47, 0xd8, 0x47, 0xfd, 0x5a, 0x55, 0xea, 0x9e, 0xee, 0x63, 0x4a, 0x0b,
- 0xb5, 0xb3, 0x1f, 0xde, 0x55, 0xd8, 0x49, 0xfb, 0xc6, 0xfa, 0x5f, 0x56,
- 0xec, 0xa5, 0x6a, 0xb9, 0x36, 0x63, 0xe9, 0x0e, 0xae, 0x63, 0x0a, 0x1f,
- 0x76, 0xbe, 0xfd, 0x7d, 0x88, 0x6e, 0x7f, 0xd2, 0xd0, 0xc7, 0xf5, 0x1d,
- 0x3e, 0x86, 0xd9, 0x53, 0xf6, 0x31, 0xc6, 0x76, 0xdb, 0xf1, 0xd5, 0x43,
- 0x1a, 0xd7, 0xf3, 0xd8, 0x86, 0x9c, 0xd4, 0x52, 0x0b, 0x8f, 0x1a, 0x16,
- 0x9e, 0xe6, 0xe7, 0x22, 0x73, 0xd9, 0xc8, 0x0d, 0xb9, 0xcc, 0xc5, 0xe7,
- 0x76, 0xf0, 0xb9, 0x16, 0xa6, 0xce, 0xd9, 0x69, 0x99, 0x0d, 0x1e, 0x94,
- 0xd9, 0x20, 0xf2, 0xa6, 0xe8, 0x7e, 0x00, 0x17, 0x72, 0xb1, 0x41, 0xb7,
- 0xdb, 0x1a, 0x62, 0x5c, 0x5d, 0xfc, 0x88, 0xbe, 0xfb, 0xda, 0x1a, 0xad,
- 0x9b, 0x3a, 0x4c, 0x8c, 0x29, 0x2d, 0xf2, 0x33, 0xcc, 0x6f, 0xf2, 0xa1,
- 0x31, 0xba, 0xd2, 0x1d, 0x0f, 0x9d, 0x85, 0x36, 0xdf, 0x47, 0x49, 0x9f,
- 0x2c, 0x38, 0xb9, 0x6e, 0x5d, 0x31, 0xd7, 0xb5, 0xe4, 0x2b, 0xd4, 0x1d,
- 0x13, 0xac, 0xcf, 0xd3, 0x56, 0x36, 0xc8, 0x7a, 0x55, 0x98, 0x16, 0xda,
- 0x43, 0x68, 0x4c, 0x0a, 0x2d, 0xbd, 0x73, 0x4c, 0xe1, 0x1b, 0x95, 0x88,
- 0xb3, 0x56, 0xc1, 0x28, 0xd7, 0xb3, 0x16, 0x6b, 0x52, 0xc8, 0x9b, 0x92,
- 0xda, 0xd9, 0xc5, 0xbe, 0xa5, 0x87, 0x79, 0x51, 0x30, 0xb5, 0xcc, 0x4b,
- 0x9d, 0x7c, 0xb4, 0xb1, 0x20, 0x76, 0x11, 0x9b, 0x88, 0x6d, 0x0e, 0xe2,
- 0x1e, 0x53, 0x7a, 0x7f, 0x0b, 0xe3, 0x46, 0x3c, 0xfa, 0x14, 0xc4, 0x4e,
- 0x07, 0xa9, 0x0b, 0x2f, 0x76, 0x33, 0x0f, 0xee, 0x6a, 0xa6, 0xae, 0x82,
- 0x5e, 0xec, 0xb2, 0x67, 0x09, 0x25, 0xfd, 0x79, 0x69, 0x43, 0xc5, 0x1a,
- 0x37, 0xeb, 0x75, 0xf4, 0xe8, 0xcc, 0x26, 0xdd, 0x29, 0xa1, 0x57, 0x9a,
- 0x4b, 0x3a, 0xba, 0xdb, 0x94, 0x13, 0xba, 0x16, 0xce, 0x1a, 0x0e, 0x6e,
- 0x2d, 0xe9, 0x2c, 0x42, 0xb9, 0x6a, 0xd6, 0x02, 0x2b, 0x6f, 0xc0, 0xae,
- 0x15, 0xbc, 0xb6, 0xe5, 0x3a, 0x76, 0xcd, 0x08, 0x3e, 0x26, 0x76, 0xed,
- 0xdc, 0x4a, 0xec, 0x5a, 0xaf, 0x4a, 0xb8, 0x55, 0xe6, 0x12, 0x25, 0xec,
- 0x5a, 0x5d, 0xcc, 0xd1, 0x07, 0xb1, 0x8b, 0xb8, 0xa6, 0xb6, 0x7e, 0x08,
- 0xbe, 0x55, 0xae, 0xcf, 0x5c, 0x18, 0x62, 0xbf, 0x52, 0x06, 0x2c, 0xb6,
- 0x70, 0xcb, 0xea, 0xac, 0x55, 0xae, 0xd7, 0x47, 0xcb, 0x5d, 0x32, 0x77,
- 0x8e, 0x67, 0x47, 0x98, 0x4b, 0x5c, 0xab, 0xb4, 0x6c, 0x1a, 0xbe, 0x50,
- 0x8d, 0xbe, 0xb3, 0xd8, 0x2f, 0x44, 0x7c, 0x9b, 0x89, 0x7b, 0xe2, 0xc9,
- 0x4f, 0xad, 0xa9, 0xb0, 0xd0, 0x98, 0x9f, 0xf7, 0x21, 0xfd, 0x90, 0x8f,
- 0x75, 0x68, 0x41, 0x1d, 0xc1, 0x6b, 0xf1, 0x88, 0x6f, 0x5b, 0x21, 0xeb,
- 0xdf, 0xd2, 0x70, 0x0b, 0xba, 0x4e, 0x49, 0xcd, 0x89, 0x62, 0xeb, 0xa9,
- 0x76, 0xd6, 0x19, 0x1d, 0x1d, 0x63, 0x9d, 0xec, 0xe3, 0xba, 0x55, 0xf7,
- 0xb4, 0xe8, 0x49, 0xf4, 0xac, 0x85, 0xa2, 0xae, 0x1b, 0xe7, 0xa2, 0xa5,
- 0x9e, 0xf8, 0x3d, 0xdb, 0x87, 0x46, 0x8d, 0x10, 0xf5, 0xf3, 0x2b, 0x2f,
- 0x82, 0x16, 0xce, 0x18, 0xe2, 0x7b, 0xfc, 0xdb, 0x4c, 0x63, 0x63, 0xf3,
- 0xb8, 0xe5, 0xd1, 0x65, 0xbe, 0x1d, 0xb1, 0xed, 0xb6, 0x81, 0xb5, 0xac,
- 0x7d, 0xba, 0x87, 0xb6, 0x2a, 0xcd, 0xb2, 0x6f, 0xb4, 0xd9, 0x7a, 0xff,
- 0x46, 0xe6, 0x35, 0xf6, 0xe9, 0x3e, 0x1f, 0x73, 0xa5, 0xef, 0x94, 0x85,
- 0x69, 0xe3, 0x4d, 0xeb, 0x51, 0xdd, 0x43, 0xbb, 0x7c, 0x95, 0x79, 0x57,
- 0x70, 0x49, 0xca, 0x7f, 0xfb, 0xa4, 0xc7, 0x55, 0x95, 0x42, 0x73, 0x19,
- 0x7d, 0xee, 0xd5, 0xa4, 0x33, 0x73, 0x3c, 0x96, 0xbf, 0xcd, 0xbf, 0x65,
- 0x82, 0xbd, 0x04, 0x7b, 0x5d, 0xa7, 0xbf, 0xfb, 0xaa, 0xff, 0xee, 0x09,
- 0xb7, 0xaa, 0x4d, 0xc1, 0xdd, 0xb2, 0xd6, 0xc2, 0xc7, 0xab, 0xe3, 0x83,
- 0x11, 0x17, 0x73, 0x24, 0x69, 0x99, 0xf9, 0x66, 0x7f, 0x86, 0x39, 0x79,
- 0xdb, 0x04, 0xd2, 0x32, 0x9f, 0x0d, 0xae, 0x1e, 0xee, 0x0d, 0x42, 0x66,
- 0x69, 0xf8, 0x06, 0xa3, 0x32, 0x4c, 0x9f, 0x8b, 0xb4, 0xa9, 0xf8, 0x42,
- 0x3f, 0xe2, 0x17, 0x3f, 0x76, 0xbf, 0x69, 0x3d, 0x9e, 0x5f, 0xcb, 0xe7,
- 0x3b, 0x99, 0x2f, 0xd3, 0xcc, 0x9f, 0xc3, 0x83, 0x5e, 0xc8, 0x3b, 0x5a,
- 0xe6, 0x0d, 0x15, 0xa3, 0xaf, 0xe3, 0x9b, 0x7c, 0x3e, 0xd4, 0xc1, 0x5c,
- 0x39, 0x6d, 0xc4, 0xd3, 0x1b, 0x90, 0xed, 0xac, 0x86, 0x66, 0x34, 0x28,
- 0x99, 0x7d, 0x89, 0x1d, 0x12, 0xf8, 0x39, 0xd7, 0xf4, 0xe8, 0xa2, 0xc7,
- 0xf5, 0xe8, 0x9b, 0x66, 0xfd, 0xbf, 0xe6, 0x6f, 0xa2, 0x03, 0xd1, 0xcb,
- 0x37, 0xcb, 0x50, 0xb1, 0x88, 0xb2, 0xfd, 0xdc, 0xce, 0x2b, 0x7e, 0x5d,
- 0xc7, 0x7f, 0x26, 0x3e, 0xfa, 0x4f, 0x05, 0x99, 0x71, 0x96, 0x30, 0x9f,
- 0xdd, 0x47, 0xb5, 0x2e, 0x9b, 0x4a, 0x14, 0x67, 0x9e, 0x3e, 0x7f, 0xe7,
- 0xa4, 0x85, 0x93, 0x46, 0x10, 0xd2, 0xe3, 0x97, 0x27, 0xe7, 0x89, 0x00,
- 0x9a, 0xd0, 0xc1, 0xeb, 0xed, 0x93, 0x95, 0xaa, 0x7d, 0xc2, 0xc2, 0x5f,
- 0x18, 0x5a, 0xb6, 0xcd, 0xcd, 0x98, 0x36, 0xb4, 0xb3, 0xc0, 0x3b, 0xc4,
- 0x4a, 0xe2, 0x63, 0x1e, 0x04, 0x74, 0x87, 0x56, 0xd3, 0xd4, 0x6d, 0xc4,
- 0x0f, 0x12, 0x63, 0xee, 0x15, 0x15, 0x48, 0xaa, 0x29, 0x8f, 0xe8, 0xad,
- 0x13, 0xe9, 0x42, 0xa5, 0xda, 0x4e, 0x5d, 0xde, 0xb1, 0xaa, 0x0c, 0x97,
- 0x6c, 0x5d, 0xde, 0x46, 0x5d, 0xe2, 0xf5, 0xa5, 0x70, 0x5f, 0xa8, 0x45,
- 0xa7, 0x82, 0xdd, 0x9f, 0x55, 0xb2, 0x4e, 0xa7, 0x89, 0x6f, 0x89, 0x07,
- 0x43, 0x3d, 0xf8, 0x2e, 0xf3, 0xcd, 0xa3, 0xf4, 0xd5, 0x5f, 0xe9, 0x4d,
- 0xa8, 0xf8, 0x5e, 0x33, 0xed, 0xb8, 0xd6, 0xbf, 0x79, 0x22, 0x83, 0xc7,
- 0x66, 0x2d, 0x3c, 0xc5, 0x38, 0x69, 0x48, 0x66, 0x43, 0xe5, 0xec, 0xd7,
- 0x58, 0xd3, 0x16, 0x4e, 0xd8, 0x7e, 0xbe, 0xab, 0x75, 0xfd, 0x4c, 0x04,
- 0xee, 0xef, 0xca, 0xef, 0x3b, 0x5b, 0xa3, 0x33, 0xf2, 0x9d, 0xe1, 0xb7,
- 0x85, 0x01, 0x43, 0x4b, 0x7f, 0xec, 0xae, 0x40, 0x65, 0xdc, 0xb2, 0x06,
- 0x92, 0x72, 0xbd, 0xaf, 0x35, 0x61, 0xdf, 0xdf, 0xc3, 0xef, 0xd2, 0x4c,
- 0xfa, 0x6f, 0x04, 0x0b, 0x46, 0xd3, 0x94, 0x79, 0x2b, 0xeb, 0x7b, 0x86,
- 0xf5, 0xbd, 0x36, 0xa5, 0xa5, 0x77, 0xb8, 0x65, 0xfe, 0x32, 0x7f, 0xa0,
- 0x9a, 0xd7, 0x6f, 0x2f, 0xd6, 0xf7, 0xaa, 0x53, 0x32, 0xd3, 0x23, 0x06,
- 0x84, 0xb3, 0x17, 0xd2, 0xc5, 0xfa, 0x5e, 0x31, 0xe6, 0xc1, 0x16, 0xd6,
- 0x76, 0x2f, 0xb1, 0xf8, 0xc6, 0x7c, 0x2d, 0xfc, 0x27, 0xdc, 0x88, 0x25,
- 0x7f, 0x82, 0x03, 0xf4, 0xb1, 0x03, 0x09, 0xb7, 0x8a, 0x2e, 0x71, 0x51,
- 0x4f, 0xff, 0x88, 0x7d, 0x21, 0x37, 0xaa, 0xf4, 0x9f, 0xe1, 0x81, 0x2f,
- 0xa8, 0xe9, 0x99, 0x09, 0x89, 0xed, 0x5d, 0xad, 0x5b, 0x4e, 0x39, 0x35,
- 0x3d, 0x70, 0x6a, 0x78, 0x41, 0x6a, 0x7a, 0xed, 0xea, 0x0c, 0x4e, 0x4f,
- 0xe2, 0x3b, 0x4b, 0x09, 0x1e, 0x6b, 0xb9, 0x66, 0x7d, 0x32, 0xce, 0xde,
- 0x5a, 0xeb, 0xef, 0x50, 0xf1, 0x23, 0x55, 0xcc, 0x01, 0xa7, 0x59, 0xd3,
- 0x7d, 0xa9, 0x78, 0x28, 0xe1, 0x42, 0x97, 0x97, 0xf6, 0x78, 0x9f, 0x7d,
- 0xf6, 0x5b, 0xf9, 0x28, 0x69, 0x96, 0xc1, 0xc3, 0x9a, 0xfe, 0xbe, 0x8e,
- 0xcf, 0xdc, 0xf4, 0xbd, 0x77, 0xdc, 0x3e, 0x5c, 0xcd, 0x3b, 0x35, 0xbd,
- 0xba, 0xc1, 0x1a, 0xba, 0x9c, 0x0c, 0xe0, 0x4a, 0xde, 0xa0, 0x0f, 0x66,
- 0x70, 0x98, 0x35, 0xfd, 0xb2, 0x1e, 0xc2, 0x87, 0xf9, 0x16, 0xfa, 0x65,
- 0x18, 0xbf, 0x24, 0xfe, 0x5d, 0xc5, 0x9a, 0x7e, 0x27, 0x7d, 0x2a, 0xc9,
- 0x9a, 0xde, 0x66, 0xe3, 0x8d, 0x7d, 0xad, 0x67, 0xc6, 0xed, 0x9a, 0xde,
- 0xe0, 0x62, 0x3d, 0xf4, 0x22, 0xbe, 0xc0, 0x3c, 0x61, 0xfd, 0x6a, 0x6d,
- 0x80, 0xcf, 0x52, 0x6f, 0x85, 0xd5, 0x98, 0xb2, 0x6b, 0xd0, 0x7a, 0xff,
- 0x76, 0xae, 0xbd, 0xd8, 0x8e, 0x33, 0x0b, 0x5b, 0x57, 0xbd, 0x86, 0x3f,
- 0xaa, 0x71, 0xd1, 0x0f, 0x53, 0xfe, 0x3b, 0x18, 0x6b, 0xc1, 0x54, 0x69,
- 0xe6, 0x91, 0xe0, 0x3a, 0xb7, 0xf9, 0xef, 0xa4, 0x6f, 0xdc, 0xb2, 0x8a,
- 0x99, 0x24, 0xe4, 0xc4, 0x59, 0x3b, 0xe3, 0x2c, 0xc2, 0x38, 0x5b, 0xca,
- 0x38, 0x7b, 0xdc, 0x88, 0x27, 0xd6, 0x13, 0x77, 0xbd, 0x9c, 0x97, 0x58,
- 0x6b, 0x26, 0x5d, 0x8d, 0x72, 0x0d, 0xf7, 0x4a, 0xcc, 0x6c, 0x5d, 0x35,
- 0x7c, 0xb6, 0x12, 0xa2, 0x2b, 0x7c, 0xb6, 0x98, 0x18, 0x83, 0x99, 0xe9,
- 0xe2, 0x82, 0x3b, 0x3e, 0x78, 0xab, 0x3b, 0x3e, 0xf0, 0x9e, 0x7a, 0xd3,
- 0x7a, 0x9d, 0x71, 0xb6, 0x8d, 0x71, 0xb6, 0x9d, 0x71, 0xd6, 0x66, 0x5a,
- 0x78, 0x2e, 0xa9, 0x65, 0x9a, 0x5c, 0x31, 0xa3, 0xcd, 0x85, 0xa5, 0x95,
- 0x2c, 0x0d, 0x7e, 0xc4, 0x3b, 0xff, 0x88, 0xfc, 0x5f, 0x34, 0xe2, 0xdd,
- 0x09, 0x25, 0xb1, 0x15, 0xc5, 0x07, 0x94, 0xbb, 0xbc, 0x18, 0x5b, 0x7b,
- 0xa7, 0xcf, 0x17, 0x7d, 0xa3, 0x24, 0xbb, 0x1b, 0xcf, 0x1a, 0xcc, 0xa5,
- 0x8b, 0xb4, 0x68, 0xd6, 0xd5, 0x83, 0x23, 0xd4, 0xa3, 0x3f, 0xde, 0x83,
- 0xa3, 0xac, 0x87, 0xf7, 0xb2, 0x0e, 0xdf, 0x67, 0xc6, 0x5a, 0x36, 0xb3,
- 0xff, 0xb9, 0x14, 0xd1, 0xa2, 0x51, 0xd5, 0x83, 0x3e, 0xfa, 0x70, 0x1f,
- 0xeb, 0x46, 0x9b, 0xf9, 0x6b, 0xd5, 0x41, 0xac, 0xb0, 0xa7, 0x20, 0xef,
- 0x69, 0x89, 0x5e, 0x57, 0x3f, 0x7a, 0x67, 0x25, 0xb7, 0x21, 0x74, 0x53,
- 0xaa, 0x07, 0xc7, 0xcd, 0x32, 0xf4, 0x34, 0x77, 0xa9, 0xdb, 0x0b, 0x32,
- 0x7f, 0x63, 0x3c, 0x9a, 0x8c, 0x57, 0x9b, 0x5f, 0x85, 0x7c, 0xbc, 0x0b,
- 0x39, 0x89, 0x4f, 0x73, 0xbb, 0xba, 0x73, 0x5a, 0x62, 0xbc, 0x47, 0xf5,
- 0x48, 0x0c, 0x9b, 0x83, 0xea, 0x2e, 0x89, 0x69, 0x7b, 0x66, 0x2d, 0x71,
- 0x2f, 0x7b, 0x1a, 0xb7, 0x11, 0xc7, 0x81, 0x31, 0xe5, 0xfe, 0x5e, 0x84,
- 0x71, 0xd7, 0x56, 0xe6, 0xa2, 0x9f, 0xc6, 0x68, 0x3b, 0x17, 0xda, 0x8d,
- 0xdf, 0xb1, 0xb2, 0xa1, 0x5e, 0xc6, 0x54, 0x0f, 0x0e, 0x9b, 0x5f, 0xb6,
- 0x2e, 0xdb, 0xf8, 0xa4, 0x94, 0xd7, 0xd7, 0xe3, 0x9e, 0x89, 0x25, 0xf0,
- 0xe9, 0x52, 0xb7, 0x03, 0x48, 0xd4, 0xf8, 0x50, 0xa1, 0x4b, 0xbd, 0xd9,
- 0xd7, 0x3a, 0x77, 0x42, 0x49, 0xff, 0x51, 0x8c, 0xef, 0xf5, 0xb8, 0x9f,
- 0x79, 0x60, 0x77, 0xf2, 0x1e, 0xdc, 0x17, 0xaa, 0x40, 0x90, 0x7a, 0xda,
- 0x1f, 0x0a, 0x30, 0xbf, 0xfe, 0x7e, 0x91, 0xce, 0xb3, 0x65, 0xc5, 0xbe,
- 0xfa, 0x1a, 0xb6, 0xaa, 0x65, 0x8c, 0xad, 0x9b, 0x94, 0x39, 0x51, 0xa6,
- 0x35, 0x32, 0xa9, 0x23, 0xc8, 0x7e, 0x76, 0x7d, 0x52, 0x1b, 0x5c, 0xef,
- 0x8e, 0x49, 0xaf, 0x92, 0x0b, 0x12, 0xd7, 0xe5, 0xe3, 0xf1, 0xee, 0x26,
- 0xd1, 0xb1, 0x1e, 0xc1, 0x26, 0xea, 0x69, 0x4b, 0x3e, 0xcc, 0x18, 0x5a,
- 0x28, 0x13, 0x8c, 0x94, 0xce, 0x5f, 0xa7, 0x15, 0x21, 0xad, 0xc8, 0xa4,
- 0xe0, 0xb5, 0x0c, 0xf1, 0x9a, 0xce, 0x38, 0xb4, 0xac, 0x75, 0xc4, 0x69,
- 0x81, 0x53, 0x32, 0x6f, 0x8a, 0x1d, 0x21, 0xb6, 0x6d, 0x22, 0xee, 0xed,
- 0xa1, 0x57, 0x5b, 0xb7, 0xd4, 0xc7, 0x8d, 0x36, 0x85, 0x47, 0x66, 0x9a,
- 0xe1, 0x73, 0x93, 0xe6, 0x3b, 0xf9, 0x10, 0x2e, 0xe7, 0x23, 0x78, 0x9b,
- 0xb4, 0x2f, 0xd9, 0xb4, 0xeb, 0xf0, 0x8b, 0x62, 0xde, 0x4a, 0x32, 0x6f,
- 0x6d, 0x98, 0x50, 0xf4, 0xd7, 0x28, 0x86, 0x8c, 0xbf, 0xfe, 0xec, 0xd2,
- 0xcd, 0x3e, 0xea, 0x4d, 0x64, 0xf1, 0xf0, 0x7b, 0x14, 0xfb, 0xed, 0x3c,
- 0xfd, 0xda, 0x67, 0x53, 0x35, 0xb4, 0x15, 0x75, 0x5f, 0x5d, 0x7c, 0x6f,
- 0xe5, 0x54, 0xa1, 0x28, 0xaf, 0x0e, 0xd7, 0xa9, 0x04, 0xca, 0x4e, 0x5d,
- 0xe3, 0x55, 0x97, 0xf8, 0x60, 0x65, 0x7d, 0xe4, 0xfb, 0x5c, 0xff, 0x21,
- 0x62, 0x3e, 0x8b, 0xeb, 0x5f, 0xb5, 0xd7, 0x0d, 0x73, 0x5d, 0x75, 0x0d,
- 0x1f, 0x46, 0xae, 0xbd, 0x13, 0xa2, 0xec, 0x78, 0x38, 0x42, 0xdd, 0x5d,
- 0x59, 0x23, 0xcf, 0x05, 0x70, 0x7b, 0x7e, 0x55, 0xb9, 0xe4, 0x71, 0x3f,
- 0xfb, 0x01, 0xc7, 0x97, 0x88, 0xf7, 0xcc, 0xe7, 0x79, 0x4f, 0xf0, 0xd7,
- 0x7a, 0x62, 0x8d, 0xcf, 0xeb, 0x3d, 0x4c, 0x5b, 0x94, 0xd1, 0x78, 0x72,
- 0xef, 0x8b, 0xea, 0xe8, 0x9f, 0x61, 0x90, 0xbd, 0xd0, 0x43, 0x13, 0x59,
- 0xec, 0x9f, 0xf8, 0x63, 0x7b, 0x8f, 0x6e, 0xe5, 0x6a, 0xec, 0xe1, 0x9a,
- 0xfb, 0xaa, 0x19, 0x47, 0xff, 0x2d, 0x19, 0x17, 0x8c, 0xb4, 0xbd, 0x12,
- 0x52, 0x6b, 0xe3, 0x2d, 0xb7, 0x2a, 0x0b, 0x65, 0x49, 0x0c, 0xb4, 0x37,
- 0xc7, 0x13, 0x97, 0xf1, 0x88, 0x25, 0xf3, 0x6e, 0x77, 0xb1, 0xee, 0x12,
- 0x97, 0xaa, 0x76, 0xd6, 0xde, 0xb6, 0x22, 0x56, 0xda, 0x50, 0x78, 0xf3,
- 0x73, 0x33, 0x05, 0xe9, 0xc7, 0xa5, 0xde, 0xf8, 0x55, 0x1b, 0xd7, 0x39,
- 0xcc, 0x9c, 0xfd, 0xac, 0xf1, 0x62, 0x84, 0xd5, 0x18, 0x9e, 0x55, 0x0a,
- 0x07, 0x0c, 0x2f, 0xb2, 0x61, 0x0b, 0xdb, 0xf9, 0xbd, 0x97, 0xf8, 0xe9,
- 0x5d, 0xa3, 0x0a, 0x53, 0xa1, 0x10, 0x31, 0x23, 0x73, 0xb0, 0xeb, 0xff,
- 0x78, 0x65, 0x5f, 0x27, 0xea, 0x92, 0x3d, 0xf8, 0x7f, 0x6d, 0x5f, 0x66,
- 0x15, 0xf1, 0x8b, 0xc8, 0xee, 0x57, 0xcc, 0xa1, 0x09, 0x10, 0xd3, 0xec,
- 0x32, 0xe6, 0xa3, 0x2e, 0xa4, 0xaf, 0xba, 0xa0, 0x9d, 0x7e, 0x87, 0x7d,
- 0xde, 0x43, 0xf5, 0xda, 0xe9, 0x56, 0xb7, 0x8e, 0xc1, 0xe3, 0x3e, 0x3c,
- 0x78, 0xbc, 0x03, 0xd5, 0xf6, 0x7c, 0x68, 0x94, 0x3a, 0x75, 0xb1, 0xbf,
- 0x1a, 0xfe, 0xd4, 0xc3, 0x3e, 0xeb, 0xea, 0xea, 0x87, 0xd1, 0x62, 0x5f,
- 0x1f, 0xc1, 0x9e, 0x09, 0xbf, 0xda, 0x32, 0xe1, 0x41, 0xc7, 0x9d, 0x0f,
- 0xc3, 0xbb, 0xaa, 0x97, 0x7c, 0xc9, 0x75, 0xf9, 0xfd, 0x2e, 0xf6, 0x67,
- 0xc2, 0x5f, 0x19, 0xa2, 0x4b, 0xc8, 0xdb, 0x2a, 0x1d, 0x43, 0xc7, 0x3d,
- 0x6a, 0x87, 0xf9, 0x37, 0xd6, 0x55, 0x7b, 0xcf, 0x47, 0xae, 0x55, 0xc8,
- 0x59, 0x00, 0x3e, 0x23, 0x39, 0xa7, 0x0f, 0x13, 0x8c, 0xed, 0xbb, 0xec,
- 0xf7, 0x8f, 0x97, 0x39, 0x32, 0xa5, 0xd9, 0xb7, 0xb6, 0xd3, 0x7e, 0xf2,
- 0x4c, 0x6b, 0xf1, 0xda, 0x7a, 0x9f, 0x73, 0xde, 0x40, 0x7c, 0xa1, 0x0f,
- 0xcb, 0x68, 0x84, 0xfa, 0xb8, 0x5d, 0xa7, 0x50, 0x9f, 0x67, 0x42, 0x5d,
- 0xe2, 0xf0, 0xfb, 0x80, 0x39, 0xcf, 0x9e, 0x53, 0x67, 0xde, 0xa4, 0xee,
- 0x16, 0xcb, 0xfb, 0x55, 0xbe, 0xdf, 0x7e, 0x5f, 0xf2, 0x2d, 0xb1, 0x66,
- 0x50, 0x30, 0xe7, 0x17, 0xdd, 0xff, 0x5d, 0xc8, 0x3d, 0x8f, 0xfe, 0xa7,
- 0x8c, 0xe3, 0x78, 0x77, 0xa5, 0x4b, 0xfc, 0xe7, 0x4f, 0x71, 0xdf, 0xf4,
- 0x30, 0xef, 0x0b, 0xfd, 0x83, 0xec, 0x25, 0x3c, 0xaa, 0x93, 0xf9, 0x67,
- 0xef, 0x71, 0xd7, 0xed, 0x65, 0xf8, 0x4b, 0xab, 0x7c, 0xf1, 0x10, 0xea,
- 0x93, 0x23, 0x7c, 0x5e, 0xa1, 0x9d, 0xb8, 0xf1, 0x31, 0x63, 0x03, 0x3a,
- 0x6a, 0x24, 0x07, 0x3c, 0x6b, 0xf5, 0xf5, 0x88, 0x0e, 0x15, 0x36, 0xf2,
- 0xfa, 0x73, 0xb4, 0xef, 0x93, 0x86, 0x07, 0xf5, 0x8b, 0x64, 0xd6, 0xa7,
- 0x8d, 0xa7, 0xf1, 0x75, 0x9f, 0xb3, 0xf7, 0x95, 0xb5, 0xaa, 0x75, 0x7d,
- 0xe0, 0x0e, 0x57, 0xfd, 0xf8, 0x1b, 0xf4, 0xa7, 0xb6, 0x55, 0x37, 0xde,
- 0x2b, 0xe9, 0xc4, 0x40, 0x64, 0xd5, 0x33, 0x16, 0x6e, 0x1a, 0x46, 0x68,
- 0xd5, 0x8d, 0xf6, 0x2f, 0xf1, 0x7d, 0x90, 0x31, 0x88, 0x6c, 0x75, 0x4a,
- 0xe6, 0x3f, 0x71, 0xd2, 0x39, 0x88, 0x3f, 0x2c, 0x8c, 0xe0, 0xc0, 0x44,
- 0x11, 0x5b, 0xd3, 0xb7, 0xf5, 0x55, 0xd7, 0x65, 0x7b, 0x60, 0x22, 0xde,
- 0x5b, 0x55, 0x94, 0x6d, 0x1f, 0xfb, 0x8c, 0x4a, 0xe6, 0xd8, 0xfb, 0xa9,
- 0xd3, 0x01, 0x5b, 0xa7, 0x3d, 0x30, 0xf2, 0xd7, 0xe9, 0xf6, 0x93, 0xae,
- 0x3f, 0x25, 0x7a, 0x93, 0xfd, 0xb6, 0x83, 0xd8, 0x4b, 0xba, 0xbb, 0x6f,
- 0xa0, 0xdb, 0x67, 0x5c, 0xa7, 0xbb, 0x6b, 0x22, 0x7e, 0xda, 0x55, 0xa4,
- 0xfb, 0xed, 0xe9, 0x12, 0x8d, 0x2c, 0xb6, 0xad, 0xca, 0x22, 0xbf, 0x6e,
- 0x9f, 0xb5, 0xcf, 0xd6, 0xc7, 0x59, 0xfb, 0xfa, 0xc6, 0x7a, 0x89, 0x07,
- 0xfe, 0x9a, 0xd2, 0xed, 0xbd, 0x7d, 0x07, 0x7b, 0xdd, 0x18, 0x1f, 0xda,
- 0x9b, 0x5b, 0xdc, 0x69, 0xc6, 0x76, 0xd8, 0xb7, 0xf9, 0x73, 0x33, 0x8d,
- 0x0e, 0xf6, 0x61, 0x9b, 0xcc, 0x2e, 0x7f, 0xa7, 0xe9, 0x23, 0xee, 0xaa,
- 0x54, 0x1b, 0x27, 0x64, 0xb6, 0x21, 0xb1, 0x5c, 0xc4, 0xc2, 0x05, 0xe9,
- 0xf7, 0x76, 0xb2, 0x4f, 0x58, 0x46, 0xfb, 0xf6, 0xe2, 0x48, 0xa1, 0x57,
- 0xa5, 0xc3, 0x5c, 0xc7, 0x94, 0xba, 0x02, 0xd6, 0xbc, 0x6e, 0x54, 0xd2,
- 0x97, 0xc2, 0xa9, 0x81, 0xd4, 0xc9, 0x7a, 0x0b, 0xc4, 0x28, 0xbe, 0x45,
- 0xa9, 0x6c, 0x6a, 0x7b, 0xbd, 0x1b, 0xc7, 0x6c, 0xfc, 0xa5, 0x4d, 0xf1,
- 0x33, 0x2e, 0x31, 0x73, 0xc7, 0x84, 0xd4, 0x31, 0x42, 0x48, 0x7d, 0x08,
- 0xff, 0x90, 0x9c, 0x1f, 0xa8, 0x41, 0xfa, 0xde, 0x1a, 0x48, 0x5f, 0x71,
- 0x04, 0x3f, 0xd2, 0x23, 0xbe, 0x4c, 0xc1, 0xa3, 0xb6, 0x98, 0x33, 0xfe,
- 0xad, 0x66, 0x10, 0x01, 0xf6, 0x65, 0x5d, 0xee, 0x18, 0xfb, 0x0c, 0xd1,
- 0x63, 0x67, 0xeb, 0xb2, 0x7c, 0xc6, 0xdf, 0x6e, 0x3a, 0xb9, 0xf0, 0x96,
- 0x29, 0x9f, 0xbf, 0x63, 0x32, 0x16, 0x39, 0x62, 0x63, 0xb1, 0xae, 0xd6,
- 0x58, 0xde, 0xb2, 0x5e, 0x31, 0xe6, 0xaf, 0x96, 0x3b, 0x3d, 0x48, 0x6b,
- 0x22, 0xdf, 0x84, 0xbb, 0x89, 0x9f, 0xda, 0x26, 0x9b, 0x60, 0x4c, 0x02,
- 0x27, 0x8e, 0x47, 0xb0, 0x72, 0x42, 0x3b, 0x3d, 0xe8, 0xce, 0x60, 0x7c,
- 0xb6, 0x13, 0x13, 0x05, 0xff, 0x42, 0xd4, 0x45, 0x5c, 0x9d, 0x74, 0xe1,
- 0x76, 0x63, 0xb5, 0x9a, 0xb7, 0x63, 0x5a, 0xe1, 0x2e, 0x63, 0xbb, 0xea,
- 0xb5, 0x31, 0xc5, 0x0c, 0xb1, 0x88, 0xc2, 0x4d, 0xce, 0x5c, 0xbe, 0x35,
- 0x49, 0xcc, 0x7d, 0xfb, 0x84, 0xd4, 0x77, 0x0b, 0xaf, 0x26, 0xa9, 0x97,
- 0x64, 0x36, 0xe3, 0x65, 0x0f, 0xb4, 0x4f, 0x69, 0xdd, 0x86, 0x72, 0x30,
- 0xde, 0xad, 0x33, 0x0e, 0x2e, 0x5c, 0x36, 0xd3, 0xec, 0x97, 0x1c, 0xd4,
- 0x6e, 0x68, 0x11, 0x8f, 0x2b, 0x84, 0x01, 0x9b, 0x46, 0x6f, 0xab, 0x31,
- 0x53, 0x86, 0xa5, 0x7a, 0x0f, 0x4e, 0xdb, 0x32, 0xf4, 0xb7, 0xae, 0x27,
- 0xbe, 0x7e, 0xdc, 0xcc, 0xb0, 0x07, 0x96, 0xfd, 0xd0, 0x58, 0xa2, 0xc5,
- 0xdd, 0x46, 0x0c, 0x1b, 0x8b, 0x2e, 0xa8, 0xb4, 0xca, 0x7a, 0x1a, 0xd3,
- 0x33, 0x60, 0x45, 0xa9, 0x71, 0xea, 0x9b, 0xc8, 0x18, 0x27, 0xce, 0x6a,
- 0x3b, 0xee, 0x5f, 0x48, 0xc3, 0x99, 0xdf, 0x6c, 0x32, 0xfe, 0x37, 0x2e,
- 0x85, 0xb5, 0x23, 0x69, 0xf2, 0xdd, 0xc1, 0xbc, 0x3b, 0xdf, 0xe3, 0xe1,
- 0x7d, 0x99, 0xdb, 0x75, 0xb7, 0x8e, 0xe6, 0x30, 0xef, 0x4e, 0x49, 0x5f,
- 0x85, 0x60, 0x77, 0x01, 0x32, 0x43, 0x62, 0x6f, 0xf1, 0xa9, 0x55, 0xda,
- 0x3b, 0xea, 0x9a, 0x74, 0xf6, 0xc5, 0x72, 0xb3, 0x9e, 0xe0, 0x56, 0xb3,
- 0x19, 0xc7, 0x0a, 0x9e, 0x1b, 0x68, 0xc7, 0x8f, 0xdc, 0xe2, 0x72, 0x21,
- 0xbe, 0xea, 0x2e, 0x55, 0xdc, 0x5b, 0x62, 0x9e, 0xc8, 0xd8, 0x35, 0xb1,
- 0x8c, 0x72, 0x5e, 0x38, 0x29, 0x6b, 0x7c, 0xab, 0x75, 0xf4, 0xa4, 0xd4,
- 0xc8, 0xee, 0xd6, 0x88, 0xa9, 0x75, 0x4b, 0x1f, 0x58, 0x4d, 0x3d, 0x7d,
- 0x34, 0x26, 0x35, 0x78, 0x3f, 0x6b, 0xb0, 0xb6, 0xd0, 0xae, 0xa4, 0x8e,
- 0x69, 0x09, 0xbf, 0xdb, 0x85, 0x2b, 0x0d, 0x5a, 0xe6, 0x79, 0x68, 0xbd,
- 0xce, 0xbc, 0x70, 0x67, 0x6b, 0x63, 0x11, 0x0f, 0xdf, 0x3a, 0xd3, 0x27,
- 0xe7, 0x49, 0x6c, 0x1d, 0x37, 0xe5, 0x05, 0x1b, 0x5b, 0xd6, 0x4b, 0xc9,
- 0x2e, 0xe2, 0x06, 0xc1, 0xc6, 0x72, 0xfd, 0x81, 0xd6, 0x86, 0x29, 0x1f,
- 0x79, 0x53, 0x78, 0x8f, 0x75, 0xe9, 0x48, 0xa1, 0xc4, 0xa3, 0x83, 0x9b,
- 0x37, 0x13, 0x37, 0xbb, 0x53, 0x5a, 0xcb, 0x06, 0xe2, 0x66, 0x9d, 0x3d,
- 0x84, 0x07, 0x3d, 0x78, 0xcc, 0x74, 0xfa, 0x08, 0xc1, 0xce, 0xd6, 0x49,
- 0x2d, 0x2d, 0xb8, 0xf9, 0xea, 0x6a, 0x60, 0x07, 0x71, 0xf3, 0x42, 0xce,
- 0x83, 0x0c, 0x71, 0xf3, 0x47, 0x39, 0x1f, 0xee, 0x20, 0x6e, 0xbe, 0x42,
- 0x8c, 0x75, 0x3e, 0xf9, 0x4b, 0x7c, 0xbb, 0x38, 0x13, 0xdb, 0x95, 0xf0,
- 0xd1, 0xb7, 0x05, 0x3b, 0xff, 0xa6, 0x88, 0x9d, 0xff, 0xcb, 0x3f, 0xc3,
- 0xce, 0x77, 0x13, 0x13, 0x76, 0x4d, 0xc8, 0xfe, 0xd1, 0xae, 0xd6, 0xd7,
- 0x4f, 0xc9, 0x99, 0x95, 0x5b, 0xf1, 0xee, 0xc9, 0xe1, 0x7e, 0x62, 0x65,
- 0x8c, 0x24, 0x33, 0xc8, 0x4d, 0x62, 0x09, 0x71, 0xc1, 0x4b, 0x6e, 0xae,
- 0xbb, 0x32, 0xa9, 0x19, 0x6f, 0xa8, 0x78, 0x67, 0x06, 0x71, 0xf6, 0xca,
- 0xda, 0x02, 0x4d, 0x98, 0xf6, 0xa4, 0x88, 0x8d, 0x59, 0x03, 0x97, 0x12,
- 0x3b, 0x57, 0xcd, 0x01, 0xb5, 0x73, 0x0e, 0x76, 0x96, 0x79, 0x58, 0x55,
- 0x1c, 0x7f, 0x46, 0xec, 0xcc, 0xfe, 0x96, 0xa1, 0x36, 0xd7, 0xc4, 0x18,
- 0x55, 0x38, 0x1c, 0x0f, 0xa0, 0xeb, 0x38, 0x71, 0x8f, 0x3d, 0x0f, 0xb3,
- 0x86, 0x7e, 0x6a, 0x64, 0x70, 0x74, 0xd6, 0x99, 0x87, 0x6d, 0x22, 0x7e,
- 0xf3, 0xc4, 0xc3, 0x28, 0x9f, 0xf3, 0xe0, 0x19, 0xe2, 0xe7, 0x8d, 0xb4,
- 0xf3, 0x19, 0xe2, 0xe7, 0xbb, 0x6f, 0x98, 0x89, 0x4d, 0xcd, 0xe1, 0x15,
- 0x62, 0xf9, 0xba, 0x5a, 0xc4, 0x65, 0xde, 0x61, 0x5d, 0x59, 0x13, 0xc0,
- 0x39, 0x1b, 0x3f, 0xfb, 0x17, 0xb2, 0xca, 0x91, 0xad, 0x8c, 0xb6, 0x10,
- 0xbb, 0xba, 0x68, 0xd7, 0xb6, 0x93, 0x5a, 0xe7, 0x8b, 0xd4, 0x45, 0x63,
- 0xfc, 0xbc, 0x6d, 0x8f, 0xbe, 0xa4, 0xcc, 0x4e, 0x3a, 0x5b, 0xe5, 0x5c,
- 0x55, 0x05, 0xed, 0xbd, 0x65, 0x2c, 0x96, 0xfe, 0x00, 0x4e, 0x4c, 0x26,
- 0xf2, 0x65, 0xc5, 0x7a, 0x28, 0xf7, 0xfa, 0x79, 0x2f, 0x8d, 0xce, 0x35,
- 0x8e, 0x7f, 0x27, 0xf2, 0xc7, 0x88, 0x5d, 0x65, 0xcf, 0x34, 0x14, 0xdc,
- 0x64, 0x76, 0x62, 0xdc, 0x8c, 0xa2, 0xfc, 0x5c, 0x71, 0xef, 0xf5, 0x9c,
- 0x9c, 0xc5, 0xdb, 0xd9, 0x1a, 0xfa, 0x5e, 0x09, 0x13, 0xa6, 0x89, 0xef,
- 0xc2, 0xbe, 0xdb, 0x0b, 0x82, 0x17, 0xbb, 0x71, 0xd4, 0xd4, 0x22, 0x3f,
- 0x67, 0x4c, 0xdc, 0x2b, 0xfb, 0xee, 0x37, 0xcc, 0x9e, 0x1e, 0xe4, 0x3d,
- 0xf3, 0x73, 0xb3, 0xa7, 0xc1, 0x09, 0xfc, 0xc6, 0xdd, 0x5c, 0x0e, 0xd7,
- 0x4a, 0x2f, 0x31, 0xbd, 0x16, 0x19, 0xc1, 0x23, 0xc4, 0x1c, 0xbf, 0x56,
- 0x01, 0xdd, 0xd3, 0xdf, 0xe4, 0xd6, 0x22, 0x33, 0x2a, 0xc0, 0x77, 0x77,
- 0x32, 0xbf, 0xed, 0xa4, 0x6f, 0xc4, 0x16, 0x2a, 0x94, 0x1b, 0x97, 0xbe,
- 0x6c, 0xe3, 0x51, 0x7f, 0x37, 0xaf, 0x8d, 0x17, 0x4a, 0xb8, 0xa6, 0x47,
- 0x78, 0xc5, 0xa6, 0xe3, 0x4e, 0x0e, 0xd1, 0xf3, 0xfe, 0x85, 0x4b, 0x70,
- 0x64, 0xab, 0xa4, 0xac, 0xf7, 0x8f, 0x85, 0xac, 0xde, 0xc5, 0x12, 0xc3,
- 0x3a, 0xb6, 0x99, 0xe2, 0x5f, 0x7d, 0xe4, 0xb3, 0x07, 0x87, 0xcc, 0xa5,
- 0xec, 0xdd, 0x64, 0x0e, 0xda, 0x44, 0x6c, 0xdd, 0xcd, 0x1a, 0x6c, 0x59,
- 0x83, 0x46, 0xd6, 0x6a, 0x5a, 0xab, 0x1b, 0x79, 0x35, 0x5f, 0x13, 0x21,
- 0xbe, 0x59, 0xc5, 0xda, 0xdd, 0x56, 0x68, 0xc2, 0x1b, 0x67, 0x74, 0xfa,
- 0x66, 0x3b, 0xf1, 0x7b, 0x37, 0xee, 0xa1, 0x3c, 0xdf, 0x2e, 0x7c, 0x07,
- 0xe9, 0x6f, 0x78, 0x70, 0xe4, 0x78, 0x1a, 0xeb, 0x57, 0x0d, 0xe1, 0xd2,
- 0x37, 0x7d, 0xcc, 0x55, 0x01, 0x3c, 0x7e, 0x5c, 0xf2, 0x6b, 0x09, 0x6f,
- 0xdf, 0x88, 0x45, 0x7c, 0x88, 0xda, 0x38, 0xe4, 0x8b, 0xef, 0x39, 0x18,
- 0xc5, 0xcf, 0xfe, 0xb7, 0xf4, 0x3e, 0xf3, 0xd0, 0xaa, 0x7f, 0x86, 0x67,
- 0x88, 0x5b, 0x88, 0x05, 0x2a, 0x12, 0xf6, 0xb9, 0xb7, 0x12, 0xde, 0xf5,
- 0xd0, 0x07, 0x24, 0xa6, 0x97, 0x32, 0xd6, 0x2d, 0x62, 0xe7, 0x85, 0xe2,
- 0x5c, 0xf2, 0xed, 0x93, 0xda, 0xc5, 0x43, 0x88, 0x11, 0x43, 0xa3, 0x4f,
- 0xb0, 0x9b, 0x9b, 0x78, 0xf7, 0x4a, 0x3c, 0x6e, 0x9c, 0x23, 0xde, 0x1d,
- 0xa6, 0xad, 0x3d, 0xba, 0xf8, 0x66, 0x08, 0x65, 0x73, 0x11, 0xfa, 0xa4,
- 0xcc, 0x25, 0x5f, 0xf1, 0x3b, 0x73, 0x49, 0x99, 0x85, 0xcb, 0xb9, 0x10,
- 0x74, 0x94, 0xb1, 0x77, 0x2b, 0x57, 0x59, 0xe6, 0xe4, 0x29, 0xff, 0x0e,
- 0xe6, 0xf7, 0x8c, 0x19, 0x0e, 0xee, 0x28, 0x84, 0xf8, 0xa9, 0x0b, 0x66,
- 0x0a, 0xbf, 0xc7, 0xe7, 0x23, 0xfc, 0x8e, 0x62, 0x22, 0x5f, 0x5b, 0x21,
- 0xcd, 0xc0, 0x44, 0xde, 0xc9, 0x79, 0xd1, 0xfc, 0x5e, 0xbf, 0x60, 0xcd,
- 0xb6, 0xe3, 0xce, 0xdf, 0xfa, 0x0d, 0x7f, 0x7f, 0x1e, 0xf3, 0x7b, 0xc9,
- 0xf7, 0x99, 0x93, 0x3a, 0x3e, 0x3a, 0x69, 0x63, 0xfe, 0x79, 0x62, 0xfe,
- 0x01, 0xaf, 0x5b, 0xb0, 0xe6, 0xaf, 0xac, 0xf3, 0xf1, 0x78, 0xef, 0x34,
- 0xfd, 0xa0, 0x8b, 0x74, 0x5d, 0x7a, 0xd8, 0xe6, 0xd7, 0xe1, 0xd3, 0x99,
- 0xe5, 0x5e, 0x3e, 0x99, 0xc0, 0x3b, 0xd7, 0x67, 0xa7, 0x9f, 0x94, 0xd9,
- 0x33, 0x60, 0x3c, 0xf2, 0xee, 0x5a, 0xf8, 0x5a, 0xd8, 0x6f, 0x7a, 0xf9,
- 0x7c, 0xc4, 0x7e, 0x5e, 0x66, 0xb9, 0x9f, 0x7c, 0x56, 0xc2, 0xd3, 0x1f,
- 0x5d, 0x7f, 0xe7, 0x20, 0x3b, 0x35, 0xdf, 0x79, 0xc6, 0x96, 0xdb, 0x7e,
- 0x4e, 0xe6, 0xad, 0xfe, 0x05, 0xd8, 0xf1, 0xf5, 0xfb, 0x94, 0x49, 0xec,
- 0x7b, 0xc0, 0x72, 0xfc, 0x36, 0x1c, 0xdc, 0xc6, 0x78, 0xf8, 0x2e, 0xed,
- 0xb3, 0xed, 0x5c, 0x5d, 0xf0, 0x2e, 0xb3, 0xd3, 0x96, 0xf9, 0xae, 0x73,
- 0x52, 0x93, 0xe4, 0xfe, 0x1f, 0x54, 0x08, 0x1e, 0x7f, 0x9c, 0x35, 0x6b,
- 0xd8, 0x94, 0xd9, 0x3e, 0x94, 0x27, 0x75, 0x08, 0x9b, 0xc6, 0xa3, 0x78,
- 0xdb, 0xf0, 0x17, 0xcf, 0xb0, 0x48, 0x4c, 0x0e, 0x30, 0x26, 0xc3, 0x18,
- 0x31, 0x63, 0xd1, 0xb7, 0x89, 0x4f, 0xb3, 0x64, 0xf8, 0xe8, 0x84, 0x1b,
- 0x6f, 0x13, 0x33, 0x42, 0x39, 0x67, 0x40, 0x9d, 0x77, 0x4b, 0xbf, 0x57,
- 0x22, 0x5a, 0x13, 0x6b, 0xd9, 0x8b, 0x3a, 0xe4, 0x98, 0xf3, 0xfd, 0xfa,
- 0x8f, 0x71, 0xec, 0x84, 0x0b, 0xf7, 0xb1, 0xef, 0x4b, 0xdf, 0x69, 0xf0,
- 0xef, 0xc6, 0xfe, 0xf7, 0xf1, 0x0f, 0xd6, 0x94, 0x9c, 0xb3, 0x52, 0x72,
- 0x96, 0xe3, 0x13, 0xab, 0x56, 0xd7, 0xe7, 0x9f, 0x87, 0x3e, 0x78, 0x15,
- 0x8d, 0x03, 0x0b, 0xf8, 0xc0, 0x9a, 0xe7, 0xbd, 0xf7, 0x18, 0x3f, 0x2f,
- 0x1a, 0xb1, 0x88, 0x8b, 0xc2, 0xcc, 0x87, 0xdd, 0xb8, 0xd7, 0x90, 0x7d,
- 0x26, 0x6d, 0xe0, 0x69, 0x68, 0xfd, 0x17, 0x94, 0x9c, 0xcd, 0xb9, 0x64,
- 0x65, 0x6b, 0x64, 0x5d, 0x85, 0x95, 0xcb, 0x1b, 0x3b, 0xcb, 0xa0, 0xb5,
- 0x78, 0x95, 0x6e, 0xbc, 0xaf, 0xfe, 0xa7, 0x35, 0x1f, 0xfe, 0xc4, 0x7a,
- 0x47, 0x2f, 0xd1, 0xd5, 0xa2, 0x3e, 0x77, 0x89, 0xb7, 0x3a, 0x1c, 0x33,
- 0x65, 0x7f, 0xee, 0xc7, 0xb8, 0xef, 0x84, 0x07, 0xed, 0xc9, 0x5f, 0x5a,
- 0xd9, 0xb0, 0xd0, 0x0c, 0x56, 0xa2, 0x42, 0xe8, 0x3b, 0x33, 0xeb, 0x17,
- 0x0a, 0x50, 0x1d, 0xa6, 0xe0, 0x65, 0xf1, 0xd3, 0x71, 0x58, 0xa6, 0xcc,
- 0x11, 0x2d, 0xdc, 0x91, 0x1c, 0xc2, 0x7b, 0xc9, 0xf4, 0x1f, 0xf8, 0xa0,
- 0x5d, 0xbc, 0xec, 0xd6, 0xe6, 0x9b, 0xdc, 0x51, 0xe5, 0x6f, 0xd0, 0x07,
- 0x1a, 0xec, 0x7a, 0x93, 0x67, 0xef, 0x14, 0x60, 0x6e, 0x91, 0x1e, 0x73,
- 0x1c, 0x73, 0x63, 0x59, 0x78, 0x88, 0xed, 0x86, 0x9b, 0xb5, 0xcc, 0x53,
- 0x4a, 0x8b, 0xec, 0x53, 0x51, 0x75, 0x8f, 0x3e, 0x88, 0x67, 0x8c, 0x78,
- 0xba, 0x4d, 0xd5, 0xf9, 0x3a, 0x0b, 0x25, 0xda, 0xed, 0xc4, 0x2a, 0xda,
- 0xfc, 0x65, 0x77, 0x39, 0x6a, 0x57, 0xeb, 0x9d, 0xe5, 0x6e, 0x6d, 0xf0,
- 0x6b, 0x8c, 0xaf, 0xcd, 0x85, 0x79, 0xff, 0xfb, 0x71, 0x17, 0x56, 0xd8,
- 0xfb, 0x08, 0xb9, 0xe2, 0x8c, 0x74, 0x1c, 0x5b, 0xc6, 0xac, 0xf5, 0xaf,
- 0x26, 0xb5, 0xc8, 0x53, 0x2a, 0xbb, 0x23, 0x40, 0x4c, 0x73, 0x3f, 0xf4,
- 0xe8, 0x2c, 0xeb, 0x54, 0x7b, 0xc1, 0x85, 0x5b, 0x4e, 0x09, 0xcd, 0x1c,
- 0x69, 0x1e, 0x42, 0xf9, 0x09, 0x6b, 0xfd, 0x0e, 0x43, 0x1b, 0xbc, 0xec,
- 0xce, 0xfe, 0xd7, 0x5a, 0xea, 0xad, 0x43, 0xc9, 0x3e, 0xda, 0x10, 0x71,
- 0xc5, 0x90, 0x9c, 0x87, 0x4b, 0xfc, 0x39, 0x31, 0xc5, 0x1f, 0xd3, 0x57,
- 0xdd, 0xa9, 0x20, 0xf9, 0xd4, 0x12, 0xd3, 0x90, 0xf9, 0x79, 0x14, 0x97,
- 0x8d, 0xac, 0x7f, 0x53, 0x43, 0x82, 0xd8, 0x2c, 0xc2, 0x3a, 0x18, 0xc5,
- 0x51, 0x62, 0xbc, 0x43, 0x6c, 0x09, 0xe7, 0x43, 0x3a, 0xb1, 0x59, 0x37,
- 0x5c, 0x63, 0x01, 0x35, 0x93, 0x8b, 0x19, 0xed, 0xf8, 0xf7, 0x98, 0x8f,
- 0x88, 0x8b, 0x1c, 0x42, 0xe0, 0xc4, 0xdf, 0x59, 0x55, 0xba, 0xde, 0x32,
- 0xa6, 0xb8, 0xee, 0x13, 0x11, 0xea, 0x98, 0xef, 0xc9, 0xb9, 0x15, 0xb3,
- 0x0b, 0xf7, 0x8c, 0x85, 0xf9, 0x7e, 0x15, 0x56, 0x9e, 0x88, 0xe2, 0x4a,
- 0xf2, 0x66, 0xcc, 0xd7, 0x38, 0x18, 0xc8, 0xaf, 0xd3, 0x8f, 0xd8, 0x67,
- 0x65, 0x0b, 0xba, 0xbd, 0x77, 0x74, 0xc8, 0x94, 0xfe, 0xdc, 0xc3, 0xbf,
- 0x03, 0xfc, 0x88, 0x3e, 0xbf, 0x55, 0xc4, 0x3a, 0xfb, 0x5b, 0xa3, 0x33,
- 0x6f, 0x55, 0xd8, 0x7b, 0x9a, 0x88, 0xf2, 0xb9, 0x90, 0x3d, 0x17, 0x1c,
- 0x26, 0xcd, 0xb3, 0xe3, 0xd2, 0xb7, 0xb5, 0xad, 0xf3, 0x15, 0xf7, 0xdf,
- 0xdf, 0x32, 0x5c, 0x58, 0xcf, 0xde, 0x3e, 0xa2, 0x4b, 0xbd, 0x1c, 0xd6,
- 0x6a, 0xb1, 0x0e, 0xa7, 0x43, 0x6c, 0xc2, 0xf5, 0x7f, 0x87, 0x23, 0xa1,
- 0x04, 0x73, 0xbe, 0x8e, 0x77, 0x73, 0x5f, 0x66, 0xbf, 0x53, 0x27, 0x67,
- 0x77, 0x70, 0xcb, 0x09, 0x2f, 0xd7, 0x5c, 0x4f, 0x5c, 0xb3, 0x09, 0x3f,
- 0x0b, 0x39, 0xbd, 0xc6, 0x61, 0x5e, 0x1f, 0x9d, 0x0e, 0x10, 0x8b, 0xfa,
- 0xf8, 0xb9, 0x91, 0xb7, 0x2f, 0xe2, 0x49, 0x64, 0xf9, 0xd7, 0x78, 0xf2,
- 0x11, 0x0f, 0xe8, 0xb8, 0x9a, 0x7b, 0x09, 0x57, 0x48, 0x3b, 0x3b, 0xed,
- 0xd0, 0x3c, 0x5e, 0x10, 0xba, 0xb2, 0x5e, 0x6c, 0xb0, 0xd6, 0x2d, 0xf4,
- 0x03, 0x72, 0x8e, 0xf7, 0xdf, 0xb8, 0x06, 0x91, 0xdd, 0x09, 0xf6, 0xc7,
- 0x46, 0x03, 0xda, 0x43, 0xb4, 0x97, 0x29, 0x6b, 0x68, 0xec, 0x45, 0xe5,
- 0xdd, 0x08, 0x56, 0x8c, 0x59, 0x43, 0x91, 0x94, 0x5c, 0xb7, 0xac, 0xea,
- 0xb5, 0x7a, 0xe4, 0x0d, 0xe5, 0x61, 0xad, 0xf3, 0x50, 0x07, 0xa3, 0x38,
- 0x9b, 0x6b, 0xbc, 0xf8, 0x1e, 0xb1, 0x53, 0x94, 0xbd, 0xde, 0x25, 0xf7,
- 0x28, 0x66, 0x72, 0xff, 0xb1, 0x52, 0x66, 0x04, 0xa3, 0x85, 0x80, 0x9a,
- 0xce, 0xfd, 0x49, 0xa5, 0xe4, 0xa2, 0x11, 0xfa, 0x42, 0xd3, 0x98, 0xf0,
- 0x6a, 0x0d, 0x55, 0x91, 0xce, 0x51, 0xd2, 0x99, 0x5e, 0xa3, 0x67, 0x46,
- 0x94, 0xe8, 0x2c, 0x40, 0x5c, 0xf7, 0xaa, 0xcc, 0xcf, 0xa8, 0xb7, 0xa7,
- 0xf9, 0xbc, 0xe8, 0x2d, 0x8c, 0x9f, 0x15, 0xe9, 0x3c, 0x56, 0xb8, 0x88,
- 0xe9, 0xdc, 0x25, 0xfb, 0xf7, 0x91, 0x42, 0x82, 0xb5, 0xaf, 0x0f, 0x79,
- 0xe6, 0x93, 0xb1, 0x5c, 0x63, 0x66, 0x8c, 0x7c, 0x38, 0x67, 0xee, 0xfa,
- 0xf0, 0x64, 0xf1, 0x99, 0x61, 0xbe, 0x3b, 0x7c, 0xed, 0x77, 0xd1, 0x91,
- 0xb3, 0xaf, 0xef, 0xec, 0x2b, 0x94, 0xd3, 0x76, 0x4e, 0x1f, 0x7e, 0xd8,
- 0xf4, 0xca, 0x0c, 0x1c, 0x2f, 0x8d, 0xaf, 0xc7, 0x88, 0xf1, 0x97, 0xd8,
- 0x45, 0xb9, 0x47, 0xa9, 0xcf, 0x13, 0xa6, 0xbd, 0x7f, 0x2f, 0xe7, 0xba,
- 0x98, 0xab, 0xbb, 0x5a, 0xcf, 0x10, 0x8b, 0x1d, 0x63, 0xcc, 0xec, 0x49,
- 0x36, 0x76, 0xbf, 0x4c, 0xbf, 0x4b, 0x7f, 0x5d, 0xf6, 0xc8, 0x81, 0xb1,
- 0x89, 0x6f, 0x63, 0xaa, 0xa6, 0x71, 0xe1, 0x59, 0xe6, 0x84, 0xd3, 0xcc,
- 0x53, 0x1e, 0xe6, 0x84, 0xea, 0x09, 0x62, 0x48, 0xe6, 0xa9, 0x79, 0xe6,
- 0x29, 0x8f, 0xde, 0x78, 0x71, 0x06, 0xff, 0x9d, 0x7a, 0x11, 0xfe, 0x62,
- 0x89, 0x19, 0xc8, 0xb3, 0xce, 0xfc, 0x55, 0x9f, 0xe9, 0xc7, 0xa5, 0x9b,
- 0x9d, 0x19, 0x9a, 0x9b, 0x35, 0x7b, 0x77, 0xae, 0x31, 0x34, 0x22, 0xb4,
- 0x7b, 0xb4, 0x48, 0x96, 0xb6, 0x3a, 0x62, 0x63, 0xef, 0x6e, 0xf6, 0x0b,
- 0x72, 0x8e, 0xab, 0x0a, 0x1e, 0xfa, 0xfe, 0x88, 0x21, 0xe7, 0x1b, 0x22,
- 0xc1, 0xcd, 0xb4, 0xe1, 0x88, 0xd9, 0xd8, 0x12, 0x53, 0x3b, 0x70, 0xa9,
- 0x98, 0x63, 0x1d, 0x2c, 0xad, 0x65, 0x8e, 0xa2, 0xb1, 0xfb, 0x7e, 0x7c,
- 0x03, 0xe9, 0x9a, 0xc6, 0xde, 0x71, 0xc4, 0x8c, 0x7b, 0x21, 0xe7, 0x41,
- 0x1d, 0x5a, 0xf5, 0x79, 0x37, 0xf1, 0xc8, 0x27, 0xd6, 0x52, 0xfd, 0x31,
- 0x8c, 0x13, 0x33, 0x36, 0xac, 0xd2, 0x2f, 0x7e, 0xbf, 0x78, 0xcf, 0xd9,
- 0x2b, 0x12, 0x7f, 0xf1, 0x51, 0x07, 0xe5, 0xf0, 0x2c, 0xaa, 0xe3, 0x1a,
- 0xd4, 0x85, 0x7d, 0x56, 0xf8, 0x55, 0x1c, 0xa0, 0xbf, 0x8d, 0x17, 0x14,
- 0x8c, 0xfa, 0x57, 0x31, 0x20, 0xb5, 0x89, 0xef, 0xb4, 0xe5, 0x02, 0xc4,
- 0x29, 0x11, 0x94, 0xeb, 0xb1, 0xe8, 0x30, 0xe5, 0x6b, 0x63, 0x2e, 0x1f,
- 0x65, 0x0e, 0xc9, 0x86, 0x02, 0xf6, 0xf9, 0xd5, 0x72, 0x3d, 0x62, 0xff,
- 0xcf, 0x81, 0xf4, 0x41, 0x0d, 0x53, 0xb2, 0x4f, 0x7d, 0x08, 0xaf, 0x8e,
- 0xcf, 0xe3, 0x58, 0x32, 0x8d, 0xbd, 0x35, 0x21, 0x8c, 0x99, 0x8b, 0xed,
- 0xb9, 0x81, 0xf4, 0x5b, 0x5b, 0x26, 0x0e, 0xda, 0xb3, 0xc8, 0x8d, 0x49,
- 0x57, 0xbd, 0x9c, 0xe3, 0x98, 0x66, 0xdf, 0x35, 0x6e, 0x0c, 0xe1, 0x80,
- 0xf1, 0xc7, 0x30, 0x16, 0x49, 0xee, 0x1c, 0xc1, 0xf9, 0x29, 0xa9, 0x61,
- 0xfd, 0xad, 0xcb, 0xc6, 0x44, 0x3f, 0x2e, 0x62, 0x5e, 0x1f, 0x9a, 0x6c,
- 0x0c, 0x37, 0xd7, 0xba, 0x7c, 0xca, 0xc1, 0x72, 0x4d, 0x79, 0x39, 0x73,
- 0x5d, 0x85, 0x20, 0xf5, 0x75, 0x21, 0xe9, 0x65, 0xce, 0x11, 0x7d, 0xca,
- 0x19, 0x3f, 0x47, 0xce, 0x44, 0x5e, 0x61, 0xa4, 0xf9, 0xc6, 0xfd, 0x15,
- 0xf9, 0xff, 0x83, 0x6b, 0xe7, 0x0e, 0x8b, 0xb3, 0xf1, 0x3f, 0xb7, 0x2e,
- 0xdd, 0x24, 0x72, 0x27, 0x03, 0xcc, 0xe9, 0xd1, 0xa9, 0x6b, 0xfa, 0x15,
- 0x9d, 0x9e, 0x93, 0x9a, 0x61, 0xeb, 0xdc, 0x99, 0xb7, 0x69, 0x03, 0xef,
- 0xa8, 0x46, 0xd6, 0x13, 0xfa, 0x55, 0x0d, 0xfd, 0xad, 0x09, 0xbd, 0x4b,
- 0x53, 0x9e, 0x9e, 0xab, 0xe6, 0x7a, 0xb4, 0xac, 0x7e, 0xd7, 0xc2, 0xcd,
- 0x6d, 0x70, 0xeb, 0x72, 0x7d, 0xca, 0x4a, 0x87, 0xe4, 0x77, 0x33, 0x20,
- 0xb5, 0xfc, 0x05, 0x73, 0xde, 0x5a, 0xbe, 0xd8, 0xc1, 0x86, 0x7f, 0x97,
- 0x93, 0xbd, 0xaf, 0xac, 0xc5, 0x5e, 0xfb, 0xe2, 0xdb, 0xee, 0x83, 0xf8,
- 0xdb, 0xfc, 0x21, 0xbc, 0x39, 0xee, 0x21, 0xce, 0x14, 0x59, 0xd6, 0xa3,
- 0x7a, 0x75, 0x3c, 0xfd, 0x2e, 0xf3, 0xe2, 0xc5, 0xa9, 0x92, 0x5f, 0xcc,
- 0xb5, 0xae, 0x98, 0x52, 0xa4, 0x55, 0x85, 0x32, 0xca, 0xf9, 0x53, 0xc3,
- 0x8d, 0x68, 0x11, 0xdb, 0xba, 0xc9, 0xe7, 0xee, 0x9c, 0x83, 0x79, 0x63,
- 0xf9, 0xc3, 0x01, 0x67, 0xfe, 0x15, 0x60, 0x1e, 0x1d, 0xc5, 0x91, 0x5c,
- 0x63, 0xe2, 0x3d, 0x39, 0xa7, 0xc3, 0x5e, 0xec, 0x12, 0x46, 0x71, 0x22,
- 0x57, 0xca, 0xa1, 0x11, 0x39, 0xdf, 0x9a, 0x88, 0xba, 0x9c, 0x1c, 0x19,
- 0x75, 0x69, 0xd9, 0xa8, 0xeb, 0xe6, 0x80, 0x60, 0x83, 0xe1, 0x42, 0x2c,
- 0x52, 0x0e, 0x37, 0xf6, 0x18, 0x8e, 0x7f, 0xd4, 0xcf, 0x78, 0x11, 0x5d,
- 0x24, 0x75, 0x59, 0x6a, 0xb2, 0x87, 0x35, 0x79, 0x31, 0xd2, 0x8b, 0x3d,
- 0x78, 0x4d, 0x17, 0x7d, 0xec, 0x2f, 0xe9, 0xc3, 0x38, 0x87, 0xfd, 0xd6,
- 0x7c, 0xb7, 0xf8, 0x92, 0x17, 0x87, 0x9a, 0xa6, 0xad, 0xa9, 0xb0, 0xc8,
- 0xee, 0xc6, 0x69, 0xe6, 0x57, 0xdc, 0x1c, 0x8b, 0x9c, 0x66, 0xcd, 0x1e,
- 0xd1, 0x4b, 0x3e, 0x7e, 0x57, 0x91, 0x4f, 0x3d, 0x33, 0x8b, 0x3f, 0xe1,
- 0xef, 0xf5, 0x91, 0xbd, 0xca, 0x59, 0x6f, 0xf9, 0xcc, 0xdb, 0x81, 0xd2,
- 0xec, 0x54, 0x9e, 0x8d, 0xe6, 0x09, 0x3a, 0x2b, 0x84, 0x56, 0x80, 0xfe,
- 0x59, 0x8e, 0xde, 0xb0, 0x9c, 0xf3, 0x10, 0xbd, 0xc8, 0x9e, 0x22, 0xa8,
- 0x0f, 0x0b, 0x2f, 0x51, 0x1f, 0x87, 0xae, 0x9d, 0xa9, 0x72, 0xf2, 0x57,
- 0x05, 0xaf, 0x6f, 0x4e, 0xbe, 0xb8, 0xce, 0x8f, 0xdf, 0x58, 0x97, 0xc2,
- 0x11, 0xe6, 0x04, 0xb1, 0x69, 0xc6, 0xc6, 0x91, 0x6e, 0xe2, 0x93, 0xdd,
- 0xf6, 0xf9, 0x11, 0xc6, 0x81, 0x79, 0x4d, 0x8e, 0xf9, 0x3e, 0xe2, 0xec,
- 0xb9, 0x9c, 0x7d, 0x66, 0xaf, 0xf7, 0x0d, 0x15, 0x63, 0xae, 0xf9, 0x12,
- 0x7a, 0x6b, 0x85, 0x5e, 0x28, 0xb8, 0x6d, 0x32, 0x41, 0x1d, 0xd4, 0x09,
- 0x5d, 0xeb, 0x29, 0x76, 0x73, 0x87, 0xc6, 0x84, 0x3e, 0x30, 0x32, 0x16,
- 0xeb, 0xff, 0x29, 0xb0, 0xae, 0x0a, 0xda, 0xe0, 0x6c, 0xf1, 0xff, 0x38,
- 0x7e, 0xa1, 0x84, 0x96, 0xd0, 0xf1, 0xc0, 0x64, 0x8e, 0x3b, 0x3e, 0x57,
- 0x41, 0xdd, 0x69, 0xdd, 0x3f, 0x50, 0x15, 0x78, 0xec, 0x89, 0x04, 0x79,
- 0x5f, 0x14, 0xdc, 0x3c, 0xe9, 0x83, 0xff, 0x4c, 0x15, 0x6b, 0xae, 0x0f,
- 0x97, 0x9b, 0x69, 0xd7, 0x27, 0x4a, 0xbc, 0xdb, 0x7b, 0xa3, 0x78, 0x74,
- 0x22, 0x0a, 0x93, 0x3e, 0x3b, 0x67, 0xca, 0x3e, 0xb0, 0xcf, 0xce, 0x9f,
- 0x17, 0xd7, 0xd4, 0xd9, 0x7b, 0x54, 0xcf, 0x16, 0xf4, 0xc8, 0x59, 0x55,
- 0x85, 0x0f, 0x4e, 0xcc, 0xdf, 0x5c, 0x0e, 0xeb, 0x85, 0xa5, 0xa9, 0x78,
- 0x66, 0x17, 0x7d, 0x7e, 0xc5, 0xf2, 0x30, 0x7b, 0x19, 0xf6, 0x94, 0x6b,
- 0xa5, 0xff, 0x1d, 0x60, 0xff, 0x5b, 0xda, 0xd3, 0xd7, 0xfb, 0x1f, 0x52,
- 0xd9, 0x4d, 0x41, 0x58, 0x1f, 0x95, 0xa7, 0xac, 0x8f, 0xbd, 0xa9, 0x38,
- 0xdf, 0x97, 0x3d, 0x3d, 0xcb, 0x7a, 0xab, 0xd9, 0xb2, 0xf2, 0xcd, 0xb1,
- 0x4c, 0xc8, 0x1d, 0xc2, 0x99, 0x06, 0xd9, 0x07, 0x74, 0xe1, 0x83, 0xb8,
- 0x1e, 0xd9, 0x05, 0xd9, 0x7b, 0x67, 0x8e, 0x5f, 0x2c, 0xe7, 0x0e, 0xeb,
- 0x82, 0x9d, 0xe6, 0x22, 0x3c, 0x33, 0xbb, 0x16, 0xbd, 0x5e, 0xd8, 0xe7,
- 0x62, 0x2c, 0x03, 0x6f, 0x2c, 0x85, 0xd4, 0xed, 0x78, 0xcb, 0x43, 0x08,
- 0x63, 0xb6, 0x70, 0x08, 0x0f, 0x9e, 0x90, 0xfd, 0xc5, 0x07, 0x5a, 0x7d,
- 0x27, 0xac, 0xbf, 0x8b, 0xa4, 0xe6, 0x99, 0x17, 0x2d, 0xab, 0x62, 0x6d,
- 0x63, 0x84, 0xe5, 0x88, 0x18, 0xa3, 0x57, 0xb0, 0x7b, 0xff, 0x07, 0xa8,
- 0xc1, 0xd9, 0xe9, 0xf4, 0xcd, 0xec, 0x25, 0x3b, 0x9f, 0x54, 0x21, 0x3c,
- 0x4f, 0x19, 0x9f, 0x2e, 0x08, 0x4e, 0x79, 0xb0, 0x75, 0xcb, 0x89, 0x25,
- 0x78, 0x61, 0x36, 0x8c, 0xb3, 0xa6, 0x4e, 0x9c, 0x04, 0x55, 0x99, 0xb2,
- 0xaa, 0xab, 0xc9, 0x6b, 0xa5, 0xdb, 0x8d, 0x4d, 0x49, 0xe9, 0x0f, 0xf5,
- 0xfe, 0x80, 0xc2, 0x92, 0x72, 0xe8, 0x0b, 0xfb, 0x81, 0x01, 0x3f, 0xfb,
- 0xd5, 0x27, 0x55, 0x3c, 0xf3, 0xbe, 0x3b, 0x8c, 0xe7, 0x99, 0x7f, 0x7e,
- 0x50, 0x90, 0x33, 0x53, 0xcc, 0x31, 0xd3, 0x51, 0xda, 0xca, 0x07, 0x57,
- 0x7d, 0x15, 0x0e, 0x33, 0x5e, 0x5e, 0x32, 0xca, 0x98, 0xa3, 0xe4, 0x0c,
- 0x95, 0xe4, 0xf7, 0x9d, 0x72, 0x56, 0xc4, 0x7a, 0x56, 0x77, 0xfa, 0x7d,
- 0x63, 0xe6, 0xc6, 0x73, 0xc8, 0x21, 0xe6, 0xf5, 0xc6, 0xee, 0x88, 0x7a,
- 0xc5, 0x4a, 0x7f, 0x5d, 0x51, 0xce, 0xdd, 0x55, 0xa8, 0xb0, 0x65, 0xc5,
- 0xf0, 0x44, 0xa9, 0xa6, 0x54, 0x4b, 0x2f, 0xd7, 0x9d, 0x2d, 0xfa, 0x60,
- 0x25, 0x63, 0xfd, 0x28, 0x6b, 0x74, 0xf9, 0x09, 0xa9, 0x25, 0xec, 0x5f,
- 0xd4, 0x7a, 0x62, 0x61, 0xc1, 0x0d, 0x3e, 0xdc, 0x1f, 0xd2, 0x5a, 0xe4,
- 0x2c, 0xf6, 0xd3, 0x85, 0x0e, 0x8f, 0x9c, 0x89, 0x7a, 0xa6, 0x20, 0xb5,
- 0x5c, 0x72, 0x41, 0x69, 0xbd, 0x08, 0x6a, 0xc7, 0xc4, 0x46, 0xdd, 0xad,
- 0x1f, 0x8d, 0x05, 0xe4, 0xdc, 0xfc, 0x90, 0x8b, 0xbd, 0xb6, 0x6f, 0xcc,
- 0xb2, 0xee, 0x6e, 0xd6, 0xfb, 0xd7, 0xbb, 0x65, 0x3f, 0x39, 0xd6, 0x7b,
- 0x4e, 0x69, 0x2d, 0x47, 0xd4, 0x8d, 0x74, 0x9e, 0xab, 0x92, 0x18, 0xc9,
- 0x52, 0xce, 0x47, 0x6d, 0x99, 0xf6, 0x53, 0xa6, 0xd2, 0x99, 0xa1, 0x2a,
- 0x5c, 0x1e, 0x87, 0xce, 0xa8, 0xc5, 0x79, 0x83, 0xc9, 0x29, 0x14, 0x4f,
- 0xb7, 0x43, 0xfc, 0x5f, 0xeb, 0x15, 0x0c, 0x55, 0xc9, 0x9c, 0x3c, 0x3d,
- 0x2e, 0x35, 0x46, 0x09, 0x3e, 0xc9, 0x56, 0xa7, 0x06, 0x70, 0x65, 0x0d,
- 0xf0, 0xca, 0x98, 0xb3, 0xdf, 0x5e, 0x3c, 0xe3, 0x6d, 0x9f, 0x65, 0x78,
- 0xc8, 0x3e, 0xa3, 0x20, 0xf4, 0x0f, 0xe2, 0x4c, 0x4e, 0x30, 0xe5, 0x00,
- 0x31, 0x65, 0x6c, 0x90, 0x78, 0xb3, 0xa5, 0xe0, 0x9c, 0xb7, 0x32, 0x3e,
- 0xa2, 0xcf, 0x3f, 0x49, 0xac, 0x7a, 0x18, 0xce, 0x7e, 0x7b, 0x43, 0xf1,
- 0x0c, 0x42, 0x2c, 0xdf, 0xa9, 0xb6, 0x16, 0xec, 0x33, 0x5a, 0x8c, 0xb1,
- 0x76, 0xb5, 0x79, 0xb6, 0x43, 0x6d, 0x99, 0xed, 0x52, 0x3b, 0x0a, 0xd2,
- 0xb3, 0x3e, 0xd0, 0x7a, 0xff, 0x89, 0xed, 0x6a, 0xeb, 0x74, 0x8f, 0x22,
- 0xa6, 0x0d, 0xf9, 0x52, 0x19, 0xd5, 0x35, 0xeb, 0xcc, 0xcf, 0x3b, 0xd9,
- 0x77, 0x6d, 0x35, 0x4b, 0xfd, 0xbc, 0xfc, 0x1f, 0x57, 0x58, 0xfe, 0x67,
- 0xa2, 0x77, 0xa3, 0xb2, 0xac, 0x5b, 0x93, 0x7f, 0x2d, 0xf6, 0xb0, 0x9e,
- 0x4e, 0xb2, 0x36, 0x9a, 0x55, 0xe8, 0x63, 0xdf, 0x31, 0x6c, 0x2c, 0x2b,
- 0xee, 0x97, 0x89, 0x4c, 0x72, 0x4e, 0x42, 0xfc, 0x15, 0x59, 0xf6, 0x20,
- 0xf8, 0x7b, 0xf2, 0xbf, 0xb7, 0x28, 0x57, 0x97, 0x9c, 0x23, 0xf0, 0x5e,
- 0x3f, 0x47, 0x76, 0x6c, 0xec, 0xba, 0x5c, 0x1e, 0x5e, 0x1b, 0x25, 0x3e,
- 0xdd, 0xab, 0xb4, 0xc1, 0xa7, 0x1c, 0xb9, 0x2e, 0x5e, 0x66, 0x0c, 0x0f,
- 0xdb, 0x31, 0xec, 0xc8, 0xb5, 0xb2, 0x28, 0xd7, 0x8a, 0x7c, 0xa7, 0x7d,
- 0x3e, 0x8b, 0x74, 0x5a, 0xe7, 0xc6, 0xe4, 0x1c, 0x99, 0xcc, 0x2e, 0x45,
- 0x36, 0x91, 0xe3, 0x84, 0x55, 0xa1, 0x77, 0xa9, 0x6d, 0xf6, 0xb9, 0x32,
- 0x39, 0xd3, 0x25, 0xfb, 0xfb, 0x25, 0xb9, 0xa4, 0x8e, 0x2f, 0x0a, 0x76,
- 0x4c, 0xca, 0x39, 0x6b, 0xcb, 0xfa, 0x99, 0x51, 0x11, 0x14, 0x59, 0xce,
- 0x1a, 0x22, 0x8b, 0x9c, 0x17, 0x29, 0xc9, 0xf3, 0xb5, 0xa2, 0x3c, 0x62,
- 0xab, 0xeb, 0x76, 0x2a, 0xfd, 0xff, 0xdf, 0xdb, 0x39, 0xe7, 0x2c, 0x49,
- 0x49, 0x9e, 0x60, 0x4a, 0xf8, 0xcf, 0xb7, 0x8e, 0x8e, 0x0f, 0xe0, 0x15,
- 0xde, 0xff, 0x65, 0xae, 0x24, 0x97, 0x1b, 0x33, 0xd3, 0xa5, 0x33, 0x72,
- 0x6c, 0x29, 0xcd, 0x98, 0x31, 0x42, 0x3f, 0x72, 0xe4, 0x93, 0x33, 0x72,
- 0x8d, 0xf3, 0x97, 0xed, 0xb9, 0x57, 0x3c, 0xcd, 0x7e, 0x19, 0x67, 0x0b,
- 0xbf, 0x6d, 0xbf, 0xa6, 0x7c, 0x05, 0x7b, 0x64, 0xa1, 0x3d, 0x47, 0xda,
- 0x72, 0x96, 0x44, 0xe1, 0xa9, 0x69, 0x60, 0xda, 0xe4, 0xb2, 0xa9, 0x21,
- 0x3c, 0x6e, 0x58, 0xd6, 0x93, 0xcd, 0xba, 0x9c, 0x01, 0xba, 0x50, 0x6b,
- 0xcf, 0x85, 0x60, 0x54, 0xe9, 0xb2, 0x77, 0x27, 0xe7, 0x48, 0x7a, 0xa8,
- 0x03, 0x91, 0x5d, 0x7c, 0xa0, 0x64, 0x7b, 0x39, 0xdf, 0x96, 0xa5, 0x7e,
- 0x44, 0x37, 0xa5, 0x73, 0x6e, 0x32, 0x73, 0xb9, 0x51, 0x27, 0xb7, 0xd9,
- 0x3a, 0x79, 0xda, 0x10, 0x7f, 0x65, 0xf6, 0xa1, 0xaf, 0xce, 0x10, 0x3f,
- 0x8c, 0x18, 0x5e, 0x1b, 0xab, 0x1d, 0x26, 0x3e, 0x39, 0xc2, 0xd8, 0x79,
- 0xd4, 0xbc, 0x88, 0x8b, 0xf9, 0x97, 0xf0, 0xca, 0xb5, 0xff, 0x85, 0x13,
- 0x7f, 0xf1, 0xb5, 0x6c, 0xb1, 0xcf, 0x32, 0xfd, 0x75, 0xcb, 0xb2, 0xb8,
- 0xe4, 0xa1, 0x93, 0x4d, 0x72, 0xb6, 0xa9, 0x3c, 0xf5, 0xde, 0x3a, 0xd9,
- 0xdf, 0x2a, 0x4b, 0x0d, 0x7e, 0xf5, 0x82, 0x2e, 0xba, 0xf9, 0x64, 0xf5,
- 0x19, 0x5d, 0xe4, 0xd2, 0x8d, 0x51, 0xfb, 0x7f, 0x33, 0x43, 0x6b, 0x77,
- 0xeb, 0x12, 0x3b, 0xef, 0x34, 0xb7, 0xd9, 0x39, 0x61, 0x30, 0x75, 0xab,
- 0xad, 0x83, 0x83, 0xa9, 0x65, 0x8e, 0x2e, 0x52, 0x09, 0xfb, 0xfb, 0xe1,
- 0x94, 0xa3, 0x9b, 0x5c, 0xaa, 0xde, 0xfe, 0x1e, 0x4d, 0x39, 0x67, 0xa2,
- 0xb3, 0x29, 0xdd, 0xfe, 0x1e, 0x4f, 0xc5, 0xec, 0xef, 0x23, 0xa9, 0x5b,
- 0xae, 0xf3, 0xc5, 0x9f, 0xff, 0x07, 0xd8, 0xc4, 0xd3, 0xb4, 0xb4, 0x3a,
+ 0xad, 0x7b, 0x0f, 0x70, 0x54, 0xe7, 0x75, 0xef, 0xef, 0xee, 0x1f, 0x69,
+ 0x57, 0x5a, 0xad, 0x2e, 0x78, 0xc1, 0xab, 0x54, 0x29, 0x7b, 0xd9, 0xbb,
+ 0xd2, 0x1a, 0x09, 0xb8, 0x0b, 0xc2, 0x88, 0xe8, 0xd6, 0x6c, 0x85, 0x00,
+ 0x21, 0x64, 0x2c, 0x63, 0x25, 0x15, 0x7d, 0x9e, 0x5a, 0x0f, 0x64, 0x23,
+ 0xdb, 0xd8, 0x16, 0x35, 0x6d, 0xe5, 0xd4, 0xad, 0xd6, 0x92, 0xc0, 0xc2,
+ 0xac, 0xb8, 0x22, 0x0b, 0x11, 0xee, 0xf4, 0xbd, 0xc8, 0x96, 0xb0, 0xb0,
+ 0xb3, 0x62, 0xed, 0xa4, 0xaf, 0xd3, 0xcc, 0x34, 0xe3, 0x7d, 0xfe, 0x83,
+ 0x49, 0x1e, 0xb6, 0xd3, 0x4e, 0xe7, 0x3d, 0xa7, 0xf3, 0xde, 0x84, 0x17,
+ 0x63, 0x62, 0xa7, 0x89, 0xed, 0xe6, 0xa5, 0xf3, 0x44, 0xea, 0xf8, 0xbe,
+ 0xdf, 0xb9, 0x77, 0x17, 0x88, 0x9b, 0x4e, 0x67, 0x3a, 0x4f, 0x33, 0x9a,
+ 0xd5, 0xde, 0x3f, 0xdf, 0x77, 0xce, 0xf9, 0xce, 0xf9, 0x9d, 0xdf, 0x39,
+ 0xdf, 0xa7, 0x06, 0xa0, 0x0a, 0xa5, 0x9f, 0x1a, 0xfe, 0xb6, 0x0c, 0x0d,
+ 0x1f, 0x4a, 0xad, 0xb9, 0x75, 0x0d, 0xff, 0xbc, 0x15, 0x6a, 0x85, 0x4f,
+ 0x6e, 0xde, 0xaa, 0x00, 0xfd, 0x3f, 0xc6, 0xbf, 0xeb, 0xe7, 0xf3, 0xff,
+ 0xbe, 0xd7, 0x9c, 0x1f, 0x2f, 0xa0, 0x96, 0xe5, 0x92, 0x5f, 0x04, 0x3c,
+ 0xe6, 0xcc, 0x17, 0xda, 0x75, 0x04, 0xbc, 0x66, 0xaf, 0xb9, 0x4f, 0x07,
+ 0xd2, 0xf9, 0xa6, 0xd8, 0x16, 0xfc, 0xd2, 0xce, 0x44, 0x7c, 0x90, 0xeb,
+ 0x9f, 0x37, 0x3f, 0x19, 0xf9, 0xf6, 0x46, 0xed, 0xe3, 0x19, 0x2f, 0x02,
+ 0xaa, 0x79, 0x1a, 0x6a, 0x03, 0x02, 0xf5, 0x7c, 0xe7, 0xcf, 0x1b, 0xfd,
+ 0x5e, 0x84, 0xcb, 0x63, 0xb5, 0x62, 0xcc, 0x42, 0x26, 0x60, 0x0e, 0xa1,
+ 0x72, 0x03, 0xf0, 0x5e, 0x36, 0x61, 0x8c, 0x01, 0x53, 0x1e, 0x33, 0x11,
+ 0x7b, 0x05, 0x06, 0x0e, 0x17, 0x62, 0xe8, 0xe0, 0xef, 0x0e, 0xeb, 0x53,
+ 0x3b, 0xe6, 0x47, 0xc6, 0xcb, 0xe7, 0xf6, 0xb6, 0x00, 0x5b, 0xb3, 0x06,
+ 0x8e, 0x58, 0x08, 0xd4, 0x99, 0x8f, 0x63, 0x13, 0x3f, 0xc3, 0xe6, 0x30,
+ 0xde, 0x9a, 0x8c, 0xc7, 0x9e, 0x83, 0xd6, 0xa7, 0x7b, 0xb5, 0x61, 0xa0,
+ 0x69, 0x70, 0x40, 0xd1, 0xfa, 0xdf, 0x56, 0xb4, 0x9e, 0x49, 0x05, 0x01,
+ 0x85, 0xcf, 0x35, 0xe5, 0xe5, 0x73, 0x18, 0xab, 0xf2, 0x01, 0x5c, 0xf2,
+ 0xca, 0xfc, 0xbf, 0x45, 0x7b, 0x2b, 0xf0, 0xe9, 0xad, 0x18, 0xa7, 0x0c,
+ 0x7e, 0x53, 0xc1, 0xb3, 0x2d, 0x89, 0xe8, 0x28, 0xe4, 0x7e, 0x0c, 0x5b,
+ 0x0a, 0xf2, 0xa9, 0x51, 0x6b, 0xdb, 0x1e, 0x37, 0x6c, 0xfb, 0x8c, 0x51,
+ 0x89, 0x8c, 0xaa, 0x45, 0x01, 0x05, 0xa3, 0x86, 0x07, 0x69, 0xb5, 0x3d,
+ 0xe6, 0x83, 0x16, 0xbd, 0x17, 0xff, 0x4c, 0x9d, 0xd3, 0x49, 0x3f, 0xdc,
+ 0xe7, 0xfb, 0x51, 0x89, 0xa2, 0xea, 0x5a, 0xed, 0xd9, 0xac, 0x6d, 0x9f,
+ 0xd7, 0x7d, 0x38, 0x43, 0xfb, 0x8c, 0xe6, 0xff, 0xd9, 0x2e, 0xd2, 0x36,
+ 0xe3, 0x7a, 0x79, 0xfe, 0x00, 0x66, 0x54, 0xdb, 0x9e, 0xe5, 0xbd, 0x23,
+ 0xf9, 0xb2, 0x9d, 0x6d, 0xdb, 0xa3, 0xdb, 0xf6, 0x3e, 0xfd, 0x17, 0xf6,
+ 0xde, 0x5f, 0x79, 0xd6, 0xb6, 0x9f, 0x32, 0x6e, 0xc2, 0xd9, 0x5c, 0x87,
+ 0xd2, 0x35, 0xbf, 0x3c, 0xbc, 0x63, 0xda, 0xc6, 0x79, 0x03, 0xaa, 0xc7,
+ 0xdc, 0xa6, 0xec, 0x98, 0xef, 0x54, 0xb6, 0x16, 0x76, 0x2b, 0xdb, 0x66,
+ 0x7f, 0x57, 0xe9, 0x9c, 0xef, 0x57, 0xb6, 0x17, 0xa2, 0x98, 0xb3, 0x22,
+ 0x98, 0xb5, 0xfa, 0x94, 0x8e, 0xf9, 0x5e, 0xc5, 0xd5, 0x63, 0x58, 0x69,
+ 0x2f, 0x94, 0xc7, 0xba, 0x6e, 0xc7, 0x1d, 0x59, 0x13, 0x13, 0x56, 0x25,
+ 0xe7, 0x59, 0xb4, 0xbf, 0xdd, 0xb8, 0x48, 0x3d, 0x0d, 0x1c, 0x2d, 0x3c,
+ 0x85, 0xdb, 0xa7, 0x6d, 0x3b, 0x9f, 0x02, 0xf2, 0x05, 0xe0, 0xeb, 0x56,
+ 0xbc, 0x67, 0x50, 0xb1, 0xed, 0xed, 0x09, 0x7b, 0xc5, 0x15, 0xa3, 0x29,
+ 0xf9, 0x1a, 0xfe, 0xaf, 0x3d, 0x13, 0x41, 0x26, 0xc4, 0x31, 0x8e, 0x71,
+ 0xcd, 0x1e, 0x98, 0x44, 0xa0, 0xd2, 0x1c, 0xc7, 0x8f, 0xb2, 0x08, 0x54,
+ 0x98, 0x19, 0x9c, 0xcf, 0x8e, 0xaa, 0x01, 0xc4, 0xa3, 0x3b, 0x94, 0xcc,
+ 0xb0, 0x07, 0xda, 0xd0, 0xbb, 0xd0, 0x62, 0x5c, 0x8f, 0x0b, 0xaf, 0x2a,
+ 0x5a, 0xf1, 0x35, 0x68, 0xe9, 0x5f, 0x28, 0x5a, 0x67, 0x9d, 0x17, 0x69,
+ 0x4f, 0x22, 0x80, 0x6f, 0x37, 0xca, 0x9a, 0x8c, 0x63, 0x8d, 0xb3, 0x36,
+ 0x19, 0xdc, 0x72, 0x6d, 0x6d, 0x4c, 0x8c, 0x52, 0xae, 0x23, 0x94, 0xeb,
+ 0x75, 0x43, 0x8b, 0x3e, 0x0b, 0x7b, 0xc5, 0x80, 0x21, 0xf7, 0x4c, 0x8c,
+ 0x17, 0xec, 0x58, 0xd8, 0xbc, 0x44, 0x79, 0x91, 0xf9, 0x9c, 0x19, 0xc8,
+ 0xd4, 0x9a, 0xbf, 0xb4, 0xdf, 0xdc, 0x10, 0xc5, 0xcb, 0x85, 0x08, 0x5e,
+ 0x2a, 0xa8, 0x78, 0xb1, 0xd0, 0x01, 0xab, 0x80, 0xf0, 0xed, 0x85, 0x5f,
+ 0xe7, 0xc7, 0x36, 0x42, 0x7c, 0x9e, 0x72, 0x87, 0x77, 0x16, 0x7c, 0xfd,
+ 0x15, 0x26, 0x7a, 0xbe, 0x93, 0x1d, 0xb1, 0xab, 0x74, 0xf4, 0x2f, 0x31,
+ 0xf5, 0xf4, 0x2a, 0x25, 0xd4, 0x4a, 0x3f, 0xec, 0x79, 0x23, 0xdf, 0xea,
+ 0xd3, 0x8f, 0x07, 0xe1, 0xa7, 0xfd, 0xb7, 0x16, 0x6c, 0x7b, 0xcc, 0x38,
+ 0xb8, 0x76, 0x6f, 0xeb, 0x37, 0x8b, 0x3d, 0x7a, 0x37, 0x32, 0x85, 0x01,
+ 0x20, 0x6c, 0xf2, 0x93, 0xa1, 0xb8, 0xbb, 0xb9, 0x23, 0x76, 0xae, 0xdf,
+ 0xe7, 0xfa, 0x33, 0x65, 0xa0, 0xdd, 0x5f, 0xb2, 0x28, 0x83, 0xf5, 0x47,
+ 0x61, 0x54, 0xc5, 0xa8, 0xdf, 0xf7, 0x28, 0x67, 0x12, 0xdf, 0x28, 0xe8,
+ 0x94, 0xad, 0x99, 0x32, 0xc6, 0x28, 0x5f, 0x00, 0x7b, 0x73, 0xda, 0x54,
+ 0x06, 0xda, 0xc4, 0x0c, 0x56, 0x23, 0x1d, 0x51, 0xe9, 0x83, 0x7f, 0x06,
+ 0x77, 0x8c, 0x6e, 0x1c, 0xb7, 0xb0, 0x4e, 0x35, 0xb9, 0xbe, 0x29, 0x3c,
+ 0x5e, 0x81, 0x44, 0xff, 0xc7, 0x8a, 0x82, 0x37, 0x13, 0xdd, 0x98, 0xa4,
+ 0x3e, 0xdd, 0xf9, 0x20, 0x1e, 0xcc, 0x55, 0xe1, 0xfe, 0x9c, 0x8d, 0x07,
+ 0x52, 0x30, 0xab, 0xa8, 0x4f, 0x32, 0x95, 0x88, 0xbd, 0x0f, 0x1f, 0x3a,
+ 0xf2, 0xdd, 0x8c, 0xa5, 0x2d, 0x48, 0x57, 0x04, 0xb0, 0x25, 0x1f, 0x62,
+ 0x3c, 0xa6, 0x71, 0x7a, 0x3a, 0x00, 0xff, 0x7a, 0x0f, 0x66, 0x22, 0x15,
+ 0x48, 0x36, 0x78, 0xf8, 0x1b, 0x09, 0xb7, 0x4f, 0xd7, 0x87, 0xb7, 0x5a,
+ 0x3e, 0xec, 0xb7, 0x3c, 0x18, 0xc9, 0xd9, 0x76, 0x87, 0x61, 0xe3, 0xea,
+ 0x7a, 0x15, 0xdf, 0xa2, 0xfd, 0x0e, 0x5a, 0x51, 0x9c, 0x2d, 0x3c, 0x49,
+ 0x59, 0x22, 0xae, 0xbc, 0x16, 0x65, 0xb7, 0x28, 0xbb, 0x45, 0xb9, 0x2d,
+ 0x91, 0xf3, 0x55, 0xc6, 0x8c, 0x41, 0xbd, 0x82, 0x94, 0xa1, 0x1a, 0x83,
+ 0x94, 0x23, 0x9e, 0xb2, 0xe1, 0x49, 0x69, 0x99, 0xbd, 0x04, 0xaf, 0x15,
+ 0x0d, 0xb6, 0xfd, 0xf1, 0x7a, 0xd1, 0x85, 0x6b, 0xee, 0xe9, 0x96, 0x18,
+ 0xfd, 0xed, 0x1a, 0xc6, 0xd5, 0xf7, 0x69, 0xb7, 0xa7, 0x0b, 0x41, 0x0c,
+ 0xe7, 0x1c, 0xbf, 0x3d, 0x54, 0x41, 0xb9, 0x45, 0xae, 0x82, 0x9e, 0x60,
+ 0x8c, 0x26, 0xfa, 0x18, 0xa3, 0xd8, 0x49, 0x99, 0x1f, 0xb0, 0x22, 0xe1,
+ 0x8e, 0xe9, 0x44, 0xeb, 0x6e, 0xc5, 0x87, 0xed, 0xf9, 0xeb, 0x72, 0x52,
+ 0x5f, 0x89, 0x41, 0xea, 0xaa, 0x52, 0xbe, 0x08, 0xf6, 0x51, 0xce, 0x97,
+ 0x4a, 0x72, 0xce, 0x16, 0x64, 0xae, 0xcf, 0xca, 0x5a, 0x96, 0x13, 0x99,
+ 0xa5, 0x66, 0x44, 0x41, 0x55, 0x08, 0xbb, 0xf3, 0xef, 0x70, 0x2d, 0xea,
+ 0xf1, 0x4d, 0xae, 0xc1, 0xcb, 0x8c, 0x91, 0x6f, 0x5c, 0xf3, 0x17, 0x59,
+ 0x8f, 0x27, 0xb8, 0x0e, 0xda, 0xe9, 0x0c, 0x42, 0xe8, 0x2f, 0xa4, 0x71,
+ 0x78, 0x1a, 0xe9, 0x39, 0xe3, 0x18, 0xe3, 0x7d, 0x39, 0xbc, 0x7a, 0x65,
+ 0x5a, 0xd5, 0xab, 0xb0, 0x6f, 0x36, 0x82, 0xa1, 0x42, 0x3b, 0xac, 0x5c,
+ 0x04, 0x07, 0xe8, 0x9b, 0x1f, 0xa6, 0xd2, 0x0f, 0x84, 0x21, 0xb2, 0x47,
+ 0xf0, 0x20, 0xdf, 0x79, 0x6a, 0x3a, 0x82, 0x41, 0xda, 0x68, 0x47, 0x2a,
+ 0xd1, 0x1a, 0xe4, 0xb5, 0xfd, 0xbc, 0x76, 0x84, 0xf6, 0x7f, 0xd5, 0x98,
+ 0x44, 0x7f, 0x8f, 0x96, 0x04, 0x22, 0xb8, 0xcf, 0x82, 0x4a, 0x17, 0x7e,
+ 0x82, 0xf8, 0x96, 0x7c, 0x95, 0xdf, 0xef, 0x2d, 0x54, 0x51, 0xdf, 0x30,
+ 0xa2, 0xfa, 0x27, 0xb6, 0xbf, 0xc5, 0xb6, 0xbf, 0x66, 0x24, 0x2e, 0xfc,
+ 0xd0, 0xeb, 0xc3, 0x63, 0x05, 0x0f, 0x86, 0x67, 0xab, 0xf0, 0xfb, 0x39,
+ 0x1f, 0xee, 0x6c, 0xa8, 0xc2, 0xc1, 0xd9, 0x34, 0xc6, 0xa6, 0xab, 0x30,
+ 0x90, 0xc3, 0x8a, 0xfb, 0x8c, 0xb1, 0x25, 0x15, 0xd0, 0x16, 0x3b, 0x90,
+ 0xc4, 0x55, 0xae, 0xc3, 0x63, 0xb3, 0xa1, 0x70, 0xdf, 0xb4, 0x8a, 0xe1,
+ 0xf9, 0x20, 0x9f, 0xf7, 0xf0, 0xf9, 0x4a, 0x18, 0xeb, 0xe2, 0xc3, 0x2a,
+ 0x44, 0xc6, 0x6a, 0x3c, 0x3c, 0x1b, 0xc4, 0x43, 0x39, 0x15, 0x07, 0xa6,
+ 0x5b, 0x30, 0x65, 0xa5, 0x71, 0x94, 0xd8, 0xf1, 0xf5, 0x94, 0xd6, 0x73,
+ 0x40, 0xd1, 0xd2, 0x5b, 0x95, 0x34, 0x1a, 0x53, 0x7e, 0x5c, 0x22, 0x0e,
+ 0xf9, 0x53, 0x4d, 0xad, 0x2f, 0x12, 0x1b, 0x2a, 0xcc, 0x08, 0xbf, 0x6b,
+ 0x13, 0x8c, 0xd9, 0xb4, 0xdf, 0xb3, 0x1e, 0x58, 0x26, 0xf1, 0x1b, 0x09,
+ 0x77, 0x59, 0x6a, 0xb8, 0xab, 0x50, 0x1f, 0xde, 0x61, 0x45, 0xc3, 0x3b,
+ 0x18, 0x5f, 0x5b, 0xc5, 0x1f, 0xad, 0x00, 0x8e, 0xa5, 0x7e, 0x69, 0xf7,
+ 0x2f, 0x71, 0xf0, 0x2c, 0x7c, 0xfb, 0xb4, 0x96, 0x99, 0x81, 0x66, 0x30,
+ 0x1b, 0x60, 0x72, 0xde, 0xc7, 0xf5, 0x53, 0xb0, 0x44, 0x6f, 0x21, 0x8e,
+ 0xab, 0x78, 0x98, 0x98, 0xf2, 0xb7, 0xc4, 0x94, 0x81, 0xe3, 0x71, 0x75,
+ 0x0a, 0x41, 0xda, 0x1b, 0xd8, 0x7b, 0x2e, 0xc2, 0x35, 0xef, 0xc4, 0x93,
+ 0x94, 0x6b, 0xc7, 0x86, 0x08, 0xee, 0x2f, 0xa8, 0xe1, 0x4e, 0xae, 0xdf,
+ 0xfb, 0xf9, 0x68, 0x78, 0x0b, 0xd7, 0xf2, 0xdd, 0xbc, 0x16, 0x2b, 0xe2,
+ 0x9f, 0xc4, 0x9f, 0x92, 0xf0, 0x00, 0xf7, 0x1d, 0xf7, 0xa3, 0x18, 0x91,
+ 0xb9, 0x68, 0x73, 0xeb, 0x65, 0x3b, 0xa4, 0xeb, 0xa7, 0x0f, 0xd0, 0xd6,
+ 0x8f, 0x16, 0x42, 0x78, 0xc8, 0xd2, 0x92, 0xdf, 0x50, 0x42, 0xb4, 0x69,
+ 0x80, 0x76, 0x20, 0xc0, 0x2c, 0x97, 0xe7, 0x52, 0x88, 0x2d, 0x77, 0xb1,
+ 0xf6, 0xe0, 0xac, 0xf8, 0x09, 0xd7, 0xde, 0xa2, 0x0f, 0xd0, 0x7f, 0xbe,
+ 0x71, 0x2d, 0x56, 0x35, 0x35, 0xe3, 0x60, 0x77, 0x92, 0xfe, 0xe2, 0xda,
+ 0xe8, 0xc4, 0xb4, 0xd8, 0x41, 0x9b, 0x82, 0x27, 0x8d, 0xb5, 0xeb, 0xfe,
+ 0xd6, 0xbe, 0xb4, 0x4c, 0xec, 0xa1, 0x62, 0x84, 0x36, 0x3c, 0x6d, 0xd9,
+ 0xf6, 0xd5, 0xf5, 0x3f, 0xb5, 0x5b, 0x6f, 0x16, 0xbb, 0x88, 0xae, 0xdf,
+ 0x52, 0x24, 0x8f, 0x2c, 0xd1, 0xc3, 0xff, 0x1f, 0x7c, 0xe5, 0x0f, 0xed,
+ 0x7e, 0x47, 0x3f, 0xf1, 0x17, 0x1f, 0x7d, 0xf1, 0x49, 0x8e, 0xed, 0x41,
+ 0x3f, 0xc7, 0x7b, 0xc4, 0xb2, 0x3f, 0xaa, 0x33, 0x3f, 0xb5, 0x5b, 0x37,
+ 0xea, 0x43, 0x8b, 0xca, 0xff, 0xe0, 0xf5, 0x08, 0x1e, 0x2e, 0xb4, 0xd2,
+ 0x76, 0x1d, 0x78, 0xca, 0x12, 0x3c, 0xec, 0x64, 0xbc, 0x45, 0xe9, 0xcf,
+ 0xf5, 0xf4, 0x6f, 0x9f, 0xb2, 0xd5, 0xca, 0x63, 0xc7, 0x64, 0x06, 0xdb,
+ 0xe9, 0xef, 0x17, 0xb2, 0xf1, 0xd6, 0xe7, 0xa1, 0x65, 0xa8, 0x43, 0xb8,
+ 0x93, 0x36, 0xee, 0xb0, 0xb4, 0x4e, 0x59, 0xd3, 0x0e, 0xe2, 0xd2, 0x2b,
+ 0xd9, 0x68, 0xb8, 0xbd, 0x20, 0xf6, 0xae, 0x0f, 0x6f, 0x29, 0xdc, 0xca,
+ 0xb5, 0x57, 0xb0, 0x69, 0x75, 0x80, 0x38, 0x73, 0x07, 0xdc, 0x75, 0x75,
+ 0xd7, 0xee, 0xcd, 0x54, 0x53, 0xff, 0x4f, 0xd1, 0x85, 0xcc, 0x32, 0xf7,
+ 0xda, 0x30, 0xaf, 0xd5, 0xae, 0x47, 0xf8, 0x0e, 0xfa, 0xc1, 0x3d, 0xf4,
+ 0x83, 0xab, 0xeb, 0x7f, 0x69, 0xc7, 0x6e, 0x72, 0xfd, 0xa0, 0x7d, 0xda,
+ 0x17, 0xde, 0x46, 0x3b, 0x6d, 0x35, 0x14, 0xcc, 0x1a, 0x4f, 0xa1, 0xff,
+ 0x1a, 0x77, 0x48, 0xcf, 0x9c, 0x35, 0xd2, 0xc4, 0x91, 0x36, 0xf8, 0x96,
+ 0x60, 0xe6, 0x79, 0xe3, 0x30, 0x62, 0xae, 0xef, 0xe0, 0x40, 0x2e, 0x88,
+ 0xcc, 0x9d, 0x2a, 0xe6, 0x1a, 0x55, 0x3c, 0xc2, 0xb1, 0x3f, 0x4c, 0x35,
+ 0x0d, 0xbe, 0x45, 0x1b, 0xcc, 0x2c, 0x91, 0x6b, 0x69, 0xfc, 0x95, 0xf1,
+ 0x65, 0xe0, 0x26, 0x77, 0xee, 0x79, 0x89, 0xd1, 0xf9, 0x16, 0x1c, 0x29,
+ 0xf4, 0x29, 0x2e, 0x6e, 0x6a, 0x9d, 0x69, 0x7c, 0xcf, 0x16, 0x2c, 0x9d,
+ 0x27, 0x86, 0xb4, 0xd3, 0xa7, 0xc6, 0xe9, 0x47, 0xa3, 0xc4, 0x90, 0xed,
+ 0xf4, 0xa3, 0x27, 0xf3, 0xa2, 0x53, 0xc2, 0x30, 0xbc, 0x37, 0x33, 0x37,
+ 0xd3, 0x3e, 0x96, 0x93, 0xf3, 0x6b, 0x55, 0xfd, 0x30, 0xa6, 0x1c, 0xd9,
+ 0x86, 0x95, 0x3b, 0xc8, 0x31, 0x2e, 0xf9, 0x51, 0x1b, 0xd5, 0x1f, 0xc1,
+ 0x69, 0xe7, 0x5a, 0x84, 0xef, 0xa6, 0x3d, 0x1e, 0x1d, 0xaa, 0x6a, 0x76,
+ 0x30, 0xaf, 0x8a, 0xef, 0x77, 0x2a, 0x3b, 0x98, 0x6b, 0xd3, 0xcc, 0xb5,
+ 0x69, 0xe6, 0xda, 0x34, 0xe7, 0x4f, 0x33, 0xc7, 0xb6, 0x17, 0x86, 0x95,
+ 0x1e, 0xb1, 0xbb, 0xd8, 0xdf, 0x72, 0xf9, 0x03, 0xb1, 0x27, 0xbc, 0xbd,
+ 0xb0, 0xc6, 0xe3, 0x72, 0xba, 0x61, 0xa5, 0xc4, 0x61, 0x02, 0x55, 0x3a,
+ 0x73, 0x98, 0x35, 0xac, 0x74, 0x31, 0xcf, 0xf6, 0x39, 0x36, 0x8c, 0x0f,
+ 0x5d, 0x66, 0x7e, 0x7d, 0x93, 0xf9, 0x35, 0x9f, 0x62, 0x3c, 0xad, 0xbe,
+ 0x6a, 0xf7, 0x2f, 0x73, 0x73, 0xc1, 0x18, 0xe5, 0xfc, 0x1a, 0xd7, 0xaa,
+ 0xc8, 0x1c, 0xda, 0xe1, 0x55, 0x70, 0x9f, 0x8e, 0xda, 0x3a, 0x62, 0xe9,
+ 0x91, 0x02, 0xf1, 0xdf, 0x88, 0xb7, 0x7e, 0x40, 0x83, 0x1e, 0xd1, 0xfd,
+ 0xb8, 0x7a, 0x13, 0x49, 0x8e, 0xde, 0x8e, 0x63, 0xb9, 0x4a, 0x0c, 0xa6,
+ 0xd2, 0x4b, 0x03, 0xe4, 0x28, 0x9d, 0x2d, 0x78, 0x9c, 0x53, 0x2b, 0x51,
+ 0x33, 0x41, 0x7f, 0x41, 0xfa, 0x38, 0xf3, 0xc3, 0xa4, 0x75, 0x2b, 0xf2,
+ 0xcc, 0xa3, 0x73, 0x86, 0x0f, 0x6f, 0xe6, 0xd7, 0x10, 0xdf, 0x12, 0x46,
+ 0x48, 0xa9, 0x62, 0xdc, 0x9a, 0xc8, 0x5a, 0x82, 0x4b, 0xb6, 0x3d, 0x27,
+ 0x32, 0x24, 0x12, 0xe9, 0x51, 0x08, 0x56, 0xd9, 0x2b, 0xee, 0x4d, 0x55,
+ 0x60, 0x53, 0x22, 0x8c, 0x15, 0x7a, 0xbf, 0xd2, 0x59, 0x48, 0x18, 0xaf,
+ 0xe2, 0x77, 0x95, 0x7b, 0xe6, 0x4d, 0xc6, 0x74, 0x9f, 0xb2, 0x67, 0xbe,
+ 0x0a, 0x97, 0x22, 0x22, 0x23, 0x6a, 0xfd, 0xba, 0x07, 0xef, 0xdd, 0xa5,
+ 0x40, 0xd5, 0xd3, 0x38, 0xdf, 0xa2, 0xd2, 0x9f, 0x3a, 0xc9, 0x2d, 0x62,
+ 0xf0, 0x2e, 0x44, 0xc3, 0x3b, 0xb9, 0x06, 0xd5, 0x0b, 0xb2, 0x2e, 0x1d,
+ 0xb4, 0x55, 0x3d, 0xfd, 0xaf, 0x53, 0xe9, 0xa0, 0x1d, 0xbb, 0x66, 0xa1,
+ 0x56, 0x99, 0xbd, 0xca, 0xb6, 0x82, 0x46, 0x3b, 0x89, 0x4d, 0x86, 0xc9,
+ 0x91, 0xc4, 0x47, 0xca, 0x6b, 0x28, 0x7e, 0x7a, 0xe3, 0x3a, 0xf6, 0x79,
+ 0x24, 0xd6, 0x36, 0xad, 0x36, 0x19, 0x87, 0x1e, 0xca, 0x25, 0x32, 0x04,
+ 0x50, 0xdb, 0x68, 0xaf, 0xf8, 0x30, 0xb5, 0xc0, 0x7b, 0x26, 0x8e, 0x17,
+ 0xba, 0xb9, 0x2e, 0xcd, 0x25, 0xbf, 0x52, 0xe9, 0x87, 0x1d, 0x1c, 0x5f,
+ 0xfc, 0x3b, 0x0d, 0x77, 0x2d, 0x3b, 0xc9, 0x89, 0xfe, 0xb5, 0x35, 0x3c,
+ 0xc8, 0x31, 0x64, 0x1d, 0x2b, 0xca, 0x7e, 0x19, 0xbe, 0x67, 0x3a, 0x8d,
+ 0xf7, 0x9c, 0x1c, 0x5a, 0xf6, 0xe1, 0x61, 0xa5, 0x93, 0x6b, 0x09, 0xbf,
+ 0x3b, 0xfe, 0xae, 0x69, 0xf8, 0x6b, 0x4c, 0xc4, 0xbc, 0xe4, 0x6d, 0x17,
+ 0x53, 0x09, 0x75, 0x52, 0xe9, 0xe6, 0x58, 0x8c, 0x2d, 0x62, 0x7d, 0x35,
+ 0xfd, 0xa6, 0x83, 0xfa, 0x76, 0x51, 0xdf, 0x2e, 0x67, 0x4e, 0xf1, 0xbb,
+ 0x5f, 0x9d, 0x77, 0x4b, 0xe1, 0x1e, 0x47, 0xf7, 0x9d, 0x7c, 0x67, 0x0f,
+ 0x65, 0xdd, 0xc3, 0xe7, 0xb7, 0x58, 0xdf, 0xe7, 0x35, 0x91, 0x57, 0xe2,
+ 0xfa, 0xc6, 0x5c, 0x25, 0xb1, 0xfd, 0xdd, 0x12, 0x57, 0x40, 0xc6, 0x63,
+ 0x4a, 0xec, 0x0f, 0xa1, 0xa7, 0x05, 0x81, 0xa5, 0xe6, 0x50, 0xdb, 0xee,
+ 0x06, 0xe2, 0x14, 0x71, 0x32, 0x70, 0x9c, 0x1c, 0x99, 0xd8, 0x3b, 0xd7,
+ 0xaa, 0x60, 0xcc, 0xb8, 0x99, 0xf1, 0x67, 0x60, 0xa2, 0xa0, 0x75, 0xc6,
+ 0x78, 0xaf, 0x79, 0x52, 0xb8, 0xfb, 0x01, 0xb4, 0x93, 0xaf, 0x45, 0xcd,
+ 0x41, 0x44, 0xad, 0x78, 0x74, 0x42, 0xd1, 0x06, 0xb7, 0x40, 0xbb, 0x40,
+ 0xcc, 0x1f, 0x9e, 0x55, 0xb4, 0xa1, 0x3a, 0xaf, 0x96, 0x7e, 0xdb, 0xe1,
+ 0xcd, 0x07, 0xb0, 0xda, 0xe1, 0x66, 0x83, 0x48, 0x92, 0xa3, 0xee, 0xe4,
+ 0x98, 0xfb, 0x37, 0x29, 0xb8, 0x62, 0xfc, 0x94, 0xeb, 0xa4, 0xa5, 0x33,
+ 0x8a, 0x81, 0x2c, 0xe3, 0x3f, 0x7a, 0x5c, 0x38, 0xf8, 0x01, 0x72, 0x70,
+ 0x04, 0x42, 0x7c, 0x36, 0x3b, 0x19, 0x1f, 0x0e, 0x78, 0xb5, 0x24, 0xf9,
+ 0x77, 0x9a, 0x63, 0x1a, 0x05, 0xf2, 0x72, 0xce, 0x11, 0xbb, 0xaf, 0x34,
+ 0x66, 0xa2, 0x34, 0xa6, 0x9e, 0x07, 0xe3, 0x62, 0x02, 0xdb, 0x13, 0xcc,
+ 0x01, 0xc4, 0xb2, 0xa3, 0xc2, 0xf5, 0x39, 0x5e, 0xe5, 0x71, 0x83, 0xdf,
+ 0x87, 0x95, 0x3d, 0x12, 0x33, 0x95, 0x2e, 0x73, 0xab, 0xe5, 0x1c, 0x35,
+ 0xe6, 0x21, 0x2c, 0x38, 0x73, 0x0c, 0xc9, 0x1c, 0x43, 0x3f, 0x52, 0xb4,
+ 0xe4, 0x39, 0x45, 0x30, 0xb8, 0xa9, 0xef, 0x1c, 0x63, 0xe4, 0x88, 0xa2,
+ 0xb5, 0x1e, 0xa3, 0xfa, 0x41, 0x5d, 0xc6, 0x3f, 0x54, 0x9a, 0x67, 0x08,
+ 0x8d, 0x79, 0xc6, 0x5f, 0x21, 0xa0, 0x6c, 0xc9, 0xb5, 0x63, 0x6c, 0xb6,
+ 0x1d, 0xa3, 0x39, 0x05, 0xf7, 0x18, 0xcb, 0x70, 0xe9, 0x66, 0xa7, 0xfe,
+ 0xa8, 0x59, 0xa1, 0xd7, 0x61, 0x44, 0x45, 0xad, 0x47, 0xff, 0x3c, 0xf6,
+ 0x96, 0xb8, 0xfb, 0xf6, 0x13, 0x3d, 0xc4, 0x73, 0x1b, 0x1f, 0x30, 0x56,
+ 0xe2, 0x4b, 0x90, 0xf6, 0x9b, 0xad, 0xe4, 0xd9, 0x4b, 0xbd, 0x6e, 0x3c,
+ 0xff, 0x7d, 0xc0, 0x5d, 0x03, 0xb1, 0xff, 0x67, 0xef, 0xb5, 0xe3, 0xe9,
+ 0x5c, 0x05, 0x5a, 0xd7, 0xe3, 0xce, 0x28, 0x6a, 0x3c, 0xcc, 0x5d, 0xef,
+ 0xec, 0x56, 0x1e, 0xe6, 0x3d, 0xe7, 0xd9, 0xc0, 0x6f, 0x98, 0x1f, 0xb7,
+ 0xfd, 0x71, 0xa3, 0x5c, 0x97, 0x67, 0x6f, 0xbc, 0xae, 0x9a, 0xff, 0xf2,
+ 0xba, 0x82, 0x17, 0x08, 0x50, 0x5f, 0x67, 0xae, 0xc8, 0x67, 0x6d, 0x78,
+ 0x4d, 0x1f, 0x06, 0x27, 0x63, 0x38, 0xb0, 0x10, 0xc1, 0x42, 0x56, 0xeb,
+ 0xbf, 0xc4, 0xba, 0x60, 0x6f, 0x8b, 0x8e, 0x87, 0x16, 0xa2, 0x98, 0xcf,
+ 0xc2, 0x0e, 0x9a, 0x7a, 0x31, 0xa8, 0x24, 0xb1, 0x7f, 0xa1, 0x1e, 0xe7,
+ 0xb2, 0xfa, 0x85, 0x51, 0x25, 0x31, 0x5c, 0x47, 0x3e, 0xf1, 0xc8, 0x42,
+ 0x33, 0x1e, 0x5e, 0x08, 0xf0, 0x1d, 0x1b, 0x5d, 0xa9, 0x7a, 0x3e, 0xef,
+ 0xc1, 0xf3, 0x27, 0x6d, 0x5b, 0xf8, 0xd4, 0xe0, 0x02, 0x30, 0x3f, 0xc5,
+ 0x1c, 0x73, 0x86, 0xf9, 0xe6, 0x19, 0x60, 0xff, 0x33, 0x1e, 0xcc, 0x4e,
+ 0xd9, 0xd8, 0x6b, 0x8c, 0xd6, 0x79, 0xe8, 0xe4, 0xfd, 0xcc, 0x07, 0x7e,
+ 0xe6, 0xb6, 0x7b, 0x55, 0x17, 0xa7, 0x2f, 0x11, 0x87, 0x1e, 0x78, 0x26,
+ 0x89, 0x77, 0xb2, 0x19, 0x74, 0x91, 0x77, 0x0f, 0x53, 0x96, 0xb7, 0xb3,
+ 0xcc, 0x4f, 0x0b, 0x06, 0xde, 0xca, 0x06, 0x38, 0x4f, 0x33, 0x5e, 0xcb,
+ 0xca, 0x33, 0xf2, 0x6c, 0x08, 0x03, 0x94, 0xe5, 0xcd, 0x6c, 0x94, 0x73,
+ 0x46, 0xf0, 0x1d, 0x3e, 0x77, 0xff, 0x82, 0xce, 0x7c, 0x14, 0xe0, 0xbc,
+ 0x31, 0xbc, 0x91, 0x0d, 0x51, 0xd6, 0x08, 0x73, 0xd0, 0x00, 0xc6, 0xb2,
+ 0x4d, 0x17, 0xb6, 0x90, 0xb3, 0xb8, 0x39, 0x44, 0xae, 0x5d, 0xb6, 0xbb,
+ 0x9d, 0x98, 0x93, 0x79, 0xca, 0xf3, 0x0e, 0x60, 0x34, 0xfb, 0x9a, 0xb7,
+ 0x5c, 0x27, 0xbf, 0x30, 0xb5, 0xe8, 0x70, 0xba, 0xe7, 0x2d, 0xfe, 0x3d,
+ 0x0b, 0x9c, 0xb3, 0x32, 0x76, 0xad, 0x49, 0x0e, 0xcb, 0xdc, 0xf3, 0xc3,
+ 0x0d, 0xcd, 0x9c, 0x57, 0xef, 0x7f, 0x45, 0x91, 0x3a, 0xc6, 0x87, 0xd8,
+ 0x33, 0x62, 0x2f, 0xc6, 0xf1, 0x3c, 0xf0, 0x57, 0xe4, 0x95, 0x8d, 0x93,
+ 0x9a, 0xf8, 0x7d, 0x1f, 0xf9, 0x4a, 0x4f, 0x11, 0x0d, 0xc9, 0x87, 0x30,
+ 0x62, 0x57, 0x90, 0x77, 0xd7, 0x92, 0xaf, 0x2e, 0x34, 0x33, 0xff, 0x6c,
+ 0xb0, 0xed, 0xef, 0xb7, 0xc0, 0xf6, 0x98, 0xba, 0x51, 0xe7, 0x2d, 0x7e,
+ 0xbe, 0x06, 0xfa, 0x85, 0xb0, 0xa2, 0x17, 0x7f, 0x88, 0xc4, 0xd0, 0xab,
+ 0x10, 0xbb, 0x02, 0x6b, 0x16, 0x7c, 0x58, 0x4b, 0x7d, 0xb6, 0x4e, 0x72,
+ 0x6e, 0xf2, 0x8e, 0x04, 0x75, 0xba, 0x7d, 0x92, 0x5c, 0x4a, 0x0f, 0x61,
+ 0x35, 0x6d, 0x3c, 0x78, 0xca, 0xb6, 0x2b, 0x69, 0xe3, 0x46, 0xae, 0xcf,
+ 0x7d, 0x27, 0x6c, 0xbc, 0x62, 0xbc, 0x42, 0x9b, 0x2a, 0xe4, 0x83, 0x2d,
+ 0x7c, 0x27, 0xc2, 0xe7, 0x03, 0xd8, 0x3f, 0x29, 0x75, 0x50, 0x3d, 0x9f,
+ 0xb9, 0x88, 0x63, 0xd9, 0x24, 0x9a, 0x69, 0xbf, 0x18, 0xc7, 0x6c, 0xe2,
+ 0x3b, 0xb1, 0x05, 0x37, 0x97, 0xc4, 0x16, 0x7e, 0x1d, 0x0e, 0x00, 0xa7,
+ 0xa7, 0xb4, 0x89, 0x22, 0xb9, 0x74, 0x8d, 0x39, 0x02, 0xe6, 0x62, 0xbc,
+ 0x3d, 0xa3, 0xe0, 0xf8, 0x14, 0x6b, 0xb7, 0x0d, 0xb0, 0xab, 0xa8, 0xc7,
+ 0x5b, 0x33, 0xbf, 0x89, 0xe7, 0x4e, 0x52, 0xf7, 0x67, 0x23, 0xf8, 0x7a,
+ 0xd6, 0x87, 0x5b, 0x8e, 0x0b, 0x3f, 0xd3, 0x93, 0x07, 0x14, 0xa9, 0x75,
+ 0xa4, 0x06, 0x49, 0xc4, 0xfc, 0x8a, 0x07, 0x0d, 0xcf, 0xf9, 0xa0, 0x9f,
+ 0x8b, 0xc1, 0xdf, 0x10, 0x80, 0xde, 0xf0, 0xfb, 0xc4, 0x17, 0x0f, 0x2a,
+ 0x58, 0x97, 0x6e, 0xff, 0x4a, 0x92, 0xd7, 0x22, 0xbc, 0x86, 0xdf, 0xac,
+ 0x84, 0x77, 0xb9, 0x97, 0xf9, 0xb8, 0x42, 0x27, 0xb7, 0xf2, 0xd9, 0xb6,
+ 0x97, 0x78, 0xbf, 0xe7, 0xab, 0xb6, 0x1d, 0x5f, 0x2f, 0xcf, 0xab, 0x88,
+ 0x9f, 0xd3, 0xf9, 0x9c, 0x9b, 0x03, 0xaf, 0x73, 0x2b, 0x2f, 0x7d, 0x47,
+ 0xe2, 0xf3, 0x71, 0xb8, 0xf5, 0x90, 0xcb, 0xc1, 0x5f, 0x2a, 0x08, 0x4f,
+ 0x89, 0x39, 0x3a, 0x9c, 0x9d, 0x52, 0x88, 0x73, 0x26, 0x9f, 0xdd, 0x0c,
+ 0x6f, 0x4a, 0x9b, 0xc8, 0x70, 0xed, 0xf7, 0xaa, 0xad, 0x78, 0xc1, 0xf2,
+ 0xa3, 0x5a, 0x5f, 0x8e, 0x07, 0x7b, 0x54, 0xbc, 0x40, 0x8e, 0xcf, 0x75,
+ 0x4a, 0x16, 0x51, 0xc9, 0x5a, 0x8b, 0xe3, 0x79, 0xfe, 0x1a, 0xfa, 0x57,
+ 0x3c, 0xc4, 0x36, 0xaf, 0x83, 0x6d, 0x15, 0x0d, 0x40, 0x31, 0xef, 0xc3,
+ 0x79, 0xdd, 0xe5, 0x77, 0x2f, 0x39, 0x79, 0x58, 0x53, 0x8b, 0xd7, 0x78,
+ 0x9d, 0xd6, 0x9a, 0x56, 0x0e, 0x7b, 0x45, 0xce, 0x17, 0x0b, 0x3b, 0x7d,
+ 0xae, 0xff, 0x5c, 0xf4, 0x4a, 0xfd, 0x70, 0xfd, 0x7b, 0x15, 0x3c, 0xa6,
+ 0x16, 0x6d, 0xf7, 0x22, 0xe0, 0x33, 0x03, 0x6d, 0xe3, 0xfa, 0xe7, 0x6e,
+ 0x90, 0xbd, 0x19, 0x63, 0x85, 0xeb, 0x75, 0x73, 0x67, 0xd6, 0xf1, 0x9b,
+ 0x4e, 0xb1, 0xfd, 0x53, 0x86, 0x60, 0xeb, 0xb0, 0xd2, 0x41, 0xac, 0xca,
+ 0xf8, 0xdc, 0xba, 0xf8, 0x08, 0xeb, 0xe2, 0xd7, 0xb3, 0xd2, 0x1b, 0x39,
+ 0x84, 0x7d, 0x0e, 0xce, 0x0e, 0x09, 0xce, 0xc6, 0xce, 0x42, 0x1b, 0x1c,
+ 0x28, 0xe1, 0xec, 0x9c, 0x8b, 0xb3, 0xfd, 0x2e, 0xce, 0x1e, 0x2a, 0xe1,
+ 0xec, 0x10, 0x9a, 0xf3, 0x11, 0x72, 0xe0, 0x0e, 0xe6, 0xda, 0x6e, 0x72,
+ 0x0e, 0xc9, 0x91, 0x7d, 0xca, 0xce, 0xf9, 0x80, 0xb2, 0x2d, 0x17, 0xc0,
+ 0xeb, 0xe4, 0x53, 0x33, 0xbd, 0x50, 0x6f, 0xd9, 0x80, 0xe0, 0xce, 0x5c,
+ 0x0f, 0x2a, 0x75, 0xa9, 0x03, 0x2b, 0xb1, 0xdd, 0xc9, 0x55, 0x52, 0x2f,
+ 0x49, 0x2f, 0xa0, 0x97, 0x58, 0x07, 0x35, 0x68, 0xba, 0x75, 0xbf, 0xe0,
+ 0xde, 0xed, 0x7c, 0xf7, 0x2c, 0xfd, 0x10, 0x6e, 0x4e, 0x53, 0xee, 0x60,
+ 0x3d, 0xf0, 0x61, 0x4a, 0x41, 0xf1, 0xce, 0x00, 0x38, 0x16, 0xf5, 0x3d,
+ 0xd0, 0x36, 0x3e, 0xd5, 0xa3, 0x74, 0xcc, 0xce, 0x05, 0x99, 0xb7, 0x99,
+ 0x93, 0x66, 0x82, 0x6e, 0xae, 0xfe, 0xec, 0x58, 0xd2, 0x73, 0x49, 0xb6,
+ 0x6d, 0x22, 0xc7, 0x69, 0x5d, 0xff, 0x8f, 0x36, 0x7e, 0x47, 0xde, 0xff,
+ 0xcf, 0x25, 0xfb, 0xa5, 0x29, 0x4f, 0x24, 0xb0, 0xbd, 0xa0, 0x06, 0xd2,
+ 0x85, 0x0e, 0xbe, 0xdf, 0xc3, 0xb1, 0x7a, 0x83, 0x1d, 0xd6, 0xdd, 0xc1,
+ 0xad, 0x56, 0x77, 0x70, 0x9b, 0xc5, 0xd8, 0x2d, 0xf4, 0xd2, 0x8e, 0x3d,
+ 0xac, 0xe1, 0xef, 0x26, 0x7f, 0x90, 0x31, 0xfb, 0xc9, 0x65, 0x82, 0xd4,
+ 0x6d, 0x84, 0xba, 0x15, 0xa3, 0x7e, 0xa4, 0x35, 0x3f, 0x34, 0x75, 0xcc,
+ 0x59, 0xb7, 0x09, 0xa7, 0x8f, 0x54, 0x65, 0xae, 0x6e, 0xeb, 0x3a, 0x41,
+ 0x4c, 0x37, 0x1b, 0xda, 0x6e, 0x39, 0x85, 0x25, 0x7e, 0x53, 0xea, 0x5e,
+ 0xd6, 0xb2, 0x89, 0x84, 0xf1, 0x3e, 0x12, 0xd1, 0xd7, 0xf9, 0xec, 0x28,
+ 0x7d, 0x75, 0xcc, 0xe9, 0x1d, 0x70, 0x01, 0xf2, 0xcd, 0xe8, 0xb2, 0x02,
+ 0xc1, 0xdb, 0x59, 0x57, 0x85, 0x4d, 0xad, 0x75, 0x97, 0x57, 0x7a, 0x19,
+ 0xc5, 0xdf, 0x0e, 0xa1, 0x19, 0x9d, 0x85, 0x40, 0x70, 0xcb, 0xf4, 0xe7,
+ 0xf0, 0x0f, 0x27, 0x99, 0xbb, 0x20, 0x7e, 0x67, 0xdb, 0xf7, 0xb3, 0x26,
+ 0x39, 0x9a, 0xaf, 0xc7, 0x15, 0x67, 0x4d, 0x7d, 0x38, 0x92, 0x8f, 0xe1,
+ 0x32, 0xf1, 0xc9, 0xb7, 0x50, 0x87, 0x77, 0xa7, 0xbc, 0xd8, 0x67, 0xdc,
+ 0x56, 0xca, 0x09, 0x1e, 0xdc, 0x9b, 0x3c, 0x48, 0x1e, 0xe0, 0x41, 0x2d,
+ 0x39, 0xd8, 0x23, 0xce, 0x35, 0x2f, 0x6b, 0xb7, 0x2f, 0x62, 0xd8, 0xcd,
+ 0x19, 0x94, 0xb1, 0x9e, 0x32, 0xb6, 0x04, 0xb7, 0xe4, 0xb4, 0xe0, 0x1d,
+ 0x39, 0x04, 0xfc, 0xe6, 0xca, 0xb6, 0x33, 0x27, 0x6d, 0x0c, 0x18, 0xab,
+ 0xf0, 0xe1, 0xc9, 0xd1, 0x41, 0x1f, 0xfd, 0xe5, 0x27, 0xa9, 0x3e, 0x58,
+ 0xd3, 0x38, 0x4f, 0x26, 0x71, 0x31, 0x44, 0xfc, 0x6e, 0x24, 0x67, 0xa0,
+ 0x1f, 0x18, 0xf3, 0x8c, 0xc5, 0x6d, 0xf4, 0x0f, 0xfa, 0x43, 0xda, 0x6b,
+ 0x26, 0xfa, 0xc7, 0x48, 0x00, 0x6b, 0x28, 0x4f, 0x90, 0xf8, 0x1c, 0x5a,
+ 0x88, 0x05, 0xf7, 0x30, 0xa7, 0x44, 0x59, 0x9b, 0x05, 0x13, 0xb8, 0xad,
+ 0x0e, 0x89, 0xe4, 0x22, 0xf5, 0xf6, 0x2f, 0x34, 0x07, 0x77, 0x31, 0x47,
+ 0x5c, 0x49, 0xd8, 0x23, 0xaf, 0x18, 0x21, 0x84, 0x17, 0x0c, 0xda, 0xbb,
+ 0x0f, 0xa3, 0xf3, 0x2c, 0x97, 0x12, 0xac, 0xd7, 0x17, 0x5a, 0x83, 0xb7,
+ 0x33, 0x16, 0x6b, 0x88, 0x53, 0x4d, 0x0b, 0xe9, 0xa0, 0xd4, 0x6b, 0xcd,
+ 0x0b, 0x1b, 0x29, 0x9f, 0xac, 0x63, 0x73, 0xdb, 0x26, 0xfa, 0x41, 0x6c,
+ 0x01, 0xdb, 0x09, 0x65, 0xaf, 0x71, 0xcc, 0xbe, 0x28, 0x79, 0xe8, 0xfe,
+ 0x0d, 0x21, 0x62, 0x91, 0xd8, 0x92, 0x76, 0x2c, 0x94, 0x75, 0x92, 0xdc,
+ 0xdb, 0xd0, 0xb6, 0x70, 0x4a, 0x72, 0x6f, 0xb4, 0x2d, 0x7b, 0x4a, 0xc7,
+ 0x65, 0xe6, 0x8f, 0x35, 0x29, 0xcd, 0x38, 0xa7, 0xc4, 0xa3, 0x17, 0xa9,
+ 0x8b, 0x0f, 0x3f, 0xb3, 0xf7, 0xea, 0x89, 0xe2, 0x4a, 0xc6, 0x4f, 0x2d,
+ 0xf1, 0x2f, 0x4a, 0x5c, 0xaf, 0x5d, 0xa0, 0x61, 0x16, 0x7e, 0x46, 0xff,
+ 0x88, 0x22, 0x90, 0xd0, 0xf1, 0xde, 0xc9, 0x24, 0xed, 0x70, 0x6d, 0xcc,
+ 0x03, 0xa4, 0x50, 0x03, 0x4c, 0x77, 0x4f, 0x3c, 0x47, 0x1f, 0x1c, 0xe7,
+ 0xbc, 0x15, 0x0b, 0x22, 0xb3, 0x3c, 0x1f, 0xe1, 0xf3, 0xd7, 0xe7, 0xae,
+ 0xe5, 0xdc, 0x1f, 0x9d, 0x92, 0xfe, 0x52, 0xb4, 0xed, 0xfc, 0x49, 0x77,
+ 0xee, 0x44, 0x2a, 0x89, 0x9f, 0x9e, 0xd4, 0x86, 0xde, 0x53, 0xe2, 0xfd,
+ 0xe7, 0x15, 0x99, 0x1f, 0xf5, 0x35, 0xf8, 0xd0, 0x1e, 0x4d, 0x24, 0x86,
+ 0xf7, 0x72, 0xcc, 0xd6, 0x8d, 0xb4, 0xbf, 0x23, 0x07, 0x13, 0x3b, 0xb1,
+ 0xd4, 0x4f, 0x79, 0x5c, 0x59, 0xea, 0x39, 0xf6, 0xc9, 0x52, 0x9d, 0xc5,
+ 0x1a, 0xf3, 0xba, 0x3c, 0x11, 0xda, 0x21, 0xb0, 0xa7, 0x25, 0x84, 0x3a,
+ 0xe7, 0x39, 0x95, 0xcf, 0x89, 0x1d, 0x7e, 0xae, 0x78, 0xf4, 0xf7, 0x89,
+ 0x5b, 0x82, 0x1d, 0x11, 0x62, 0xd6, 0xdd, 0x52, 0x8f, 0x66, 0x32, 0xf4,
+ 0x77, 0x3f, 0xfd, 0x7d, 0xab, 0xf8, 0xb4, 0x45, 0x9f, 0xb6, 0xe8, 0xd3,
+ 0x96, 0x16, 0x1d, 0x42, 0x5c, 0x1d, 0xe0, 0xba, 0xa5, 0xa3, 0xe2, 0xeb,
+ 0xbd, 0xd8, 0xc7, 0xdf, 0xfb, 0x78, 0xff, 0x08, 0x6b, 0x54, 0x2c, 0x95,
+ 0x39, 0x0f, 0xa1, 0xc3, 0x7a, 0x02, 0x83, 0x39, 0xfc, 0x22, 0xd8, 0x52,
+ 0x89, 0xca, 0xd5, 0x52, 0x7f, 0x6b, 0xea, 0x51, 0x3c, 0xc1, 0x1a, 0xe8,
+ 0xe7, 0x4a, 0xb5, 0xee, 0xeb, 0x39, 0xa6, 0x68, 0x6a, 0x07, 0x6b, 0xd9,
+ 0xbd, 0x85, 0xbb, 0xb9, 0xbe, 0xf1, 0xc1, 0xd7, 0x15, 0xd6, 0x41, 0x75,
+ 0x9c, 0x9b, 0xb1, 0x74, 0x07, 0xe7, 0xb1, 0x44, 0x0e, 0x07, 0x5f, 0x7f,
+ 0x0f, 0x62, 0xdb, 0x6f, 0x37, 0x0e, 0x70, 0x7e, 0x57, 0x8e, 0x51, 0xd6,
+ 0x83, 0x03, 0x8c, 0xb1, 0x7d, 0x4e, 0x7c, 0xf5, 0x72, 0x8c, 0xeb, 0xb8,
+ 0xb5, 0x25, 0x2b, 0xf9, 0xd2, 0xc6, 0x93, 0x86, 0x8d, 0xe7, 0xf9, 0x7b,
+ 0x81, 0xd8, 0x35, 0x76, 0x03, 0x76, 0x79, 0xf8, 0xdc, 0x1e, 0x3e, 0xd7,
+ 0x4a, 0xdc, 0x9e, 0x9f, 0x95, 0xbe, 0xde, 0x21, 0xe9, 0xeb, 0x21, 0x6f,
+ 0x89, 0xed, 0x87, 0x70, 0x3e, 0x1b, 0x1f, 0xf6, 0x7a, 0xed, 0x11, 0xc6,
+ 0xd5, 0x85, 0x8f, 0xe8, 0xbb, 0x6f, 0x6e, 0xd0, 0x7a, 0x68, 0xc3, 0xe4,
+ 0xa4, 0xa2, 0x45, 0xbf, 0x8b, 0xe2, 0xf6, 0x00, 0x9a, 0x62, 0x6b, 0xbd,
+ 0x09, 0x95, 0x38, 0x57, 0x1c, 0xa0, 0xa6, 0xcf, 0x16, 0x5c, 0x6c, 0xdb,
+ 0x54, 0xc2, 0xb6, 0xd6, 0x7c, 0x15, 0xb1, 0x87, 0x39, 0x78, 0xd6, 0xce,
+ 0x84, 0x99, 0x9f, 0x0a, 0xb3, 0x32, 0xf6, 0x08, 0x9a, 0x52, 0x32, 0x96,
+ 0xde, 0x39, 0xa9, 0xe0, 0x4b, 0xd5, 0x48, 0x30, 0x37, 0xc1, 0xa8, 0xd4,
+ 0x33, 0x36, 0x73, 0x90, 0xea, 0x37, 0x25, 0x3f, 0x76, 0x13, 0x0f, 0x7b,
+ 0x89, 0x87, 0xc2, 0x99, 0xa5, 0xd7, 0xe9, 0xe2, 0xd1, 0xd6, 0x82, 0xac,
+ 0x8b, 0xac, 0x89, 0xac, 0xcd, 0x21, 0xdc, 0x6b, 0x49, 0xdd, 0x6e, 0x63,
+ 0xca, 0x48, 0xc4, 0x9e, 0x83, 0xac, 0xd3, 0x21, 0xda, 0xc2, 0x8f, 0x7d,
+ 0xc4, 0xbf, 0xbd, 0x2d, 0xb4, 0x55, 0xd8, 0x8f, 0xbd, 0x4e, 0x1f, 0xa0,
+ 0x6c, 0x3f, 0x3f, 0xd7, 0x50, 0x61, 0x4e, 0xfb, 0xaa, 0xdf, 0xb5, 0xa3,
+ 0xdb, 0x57, 0xf4, 0x9a, 0x32, 0x5e, 0xb9, 0xa7, 0xe8, 0xda, 0x6e, 0x7b,
+ 0x56, 0xc6, 0xb5, 0x71, 0xd6, 0x70, 0xb9, 0x69, 0xd9, 0x66, 0x82, 0xed,
+ 0x4b, 0x36, 0x02, 0x6b, 0x6f, 0xe0, 0xa7, 0x55, 0xbc, 0xd6, 0x75, 0x9d,
+ 0x9f, 0xf6, 0x09, 0x07, 0x26, 0x3f, 0xed, 0xdc, 0x49, 0x7e, 0xda, 0xa0,
+ 0x94, 0xb9, 0xa9, 0xf4, 0x14, 0xca, 0xfc, 0xb4, 0xb6, 0x84, 0xcd, 0x87,
+ 0xb0, 0x97, 0xdc, 0xa5, 0xae, 0x61, 0x04, 0x81, 0x75, 0x9e, 0x4f, 0x3d,
+ 0x18, 0x61, 0xed, 0x51, 0x01, 0x2c, 0xb3, 0xb1, 0x72, 0x7d, 0xc6, 0xae,
+ 0xd4, 0x1b, 0x62, 0x95, 0x1e, 0xe9, 0x19, 0x27, 0x32, 0x63, 0xc4, 0x12,
+ 0xcf, 0x3a, 0x2d, 0x93, 0x46, 0x40, 0x5d, 0xa2, 0xdf, 0x5d, 0xaa, 0x09,
+ 0xa2, 0x81, 0x1d, 0xe4, 0x36, 0x89, 0xd4, 0x2f, 0xed, 0x99, 0xc8, 0x08,
+ 0xa2, 0xeb, 0x8a, 0xc3, 0x51, 0xa4, 0x0f, 0x46, 0x1d, 0x5c, 0x99, 0x40,
+ 0x3e, 0x11, 0x0d, 0x74, 0x17, 0x32, 0xc1, 0xae, 0xc6, 0x18, 0x76, 0x4e,
+ 0x76, 0xb0, 0xe6, 0xd0, 0xb1, 0x6d, 0xb2, 0x93, 0xf5, 0x51, 0x8f, 0xd2,
+ 0x33, 0x2b, 0xf6, 0x11, 0xfb, 0x6a, 0x6a, 0xcc, 0x73, 0x63, 0x2f, 0xb3,
+ 0x5c, 0xcf, 0xbe, 0xef, 0xf8, 0xce, 0xb8, 0xa1, 0xd2, 0x2e, 0xff, 0xdb,
+ 0x8f, 0xb0, 0x8d, 0x33, 0x86, 0xf8, 0x1c, 0xbf, 0xb3, 0xb6, 0xda, 0xda,
+ 0x32, 0x65, 0xfb, 0x74, 0xe9, 0x49, 0x47, 0x9d, 0xf5, 0x92, 0x1a, 0xab,
+ 0x63, 0xb6, 0x97, 0x6b, 0x54, 0xee, 0x3f, 0xdf, 0xb8, 0x56, 0x9b, 0x83,
+ 0x5b, 0x89, 0x67, 0xac, 0xc7, 0x02, 0x01, 0x62, 0x64, 0xe0, 0x94, 0x8d,
+ 0x59, 0xe3, 0x1d, 0xfb, 0x49, 0xdd, 0xc7, 0xf5, 0xb8, 0x95, 0x78, 0x2b,
+ 0xfc, 0xc3, 0x0c, 0xee, 0x9a, 0xf6, 0x79, 0x58, 0x5b, 0xb5, 0x54, 0xc0,
+ 0xa9, 0xad, 0x9c, 0x3e, 0xe1, 0xb1, 0xfc, 0x6d, 0xc1, 0xae, 0x1c, 0xeb,
+ 0x04, 0xd6, 0xa9, 0x6e, 0x8d, 0x76, 0x6b, 0xf0, 0x9e, 0x9c, 0x57, 0xa9,
+ 0x33, 0xe1, 0x6d, 0xdd, 0x68, 0xe3, 0xe3, 0xf5, 0x89, 0xe1, 0xa8, 0x87,
+ 0xd8, 0xc8, 0xb1, 0xac, 0x7c, 0x4b, 0xb0, 0x8f, 0x58, 0x7c, 0x7b, 0x0e,
+ 0x69, 0xe9, 0xa9, 0x86, 0xd7, 0x8f, 0xf6, 0x87, 0x21, 0xfd, 0x2f, 0x7c,
+ 0x89, 0xd1, 0x18, 0xa1, 0xaf, 0x45, 0xdb, 0x95, 0xc4, 0xe2, 0x20, 0x12,
+ 0x17, 0x3e, 0xf6, 0xbe, 0x63, 0x3f, 0x9d, 0xdf, 0xc8, 0xe7, 0x3b, 0x89,
+ 0x93, 0x69, 0xe2, 0xe6, 0xe8, 0xb0, 0x1f, 0xf2, 0x8e, 0xd6, 0xf7, 0xb6,
+ 0x12, 0xa7, 0x8f, 0xe3, 0x77, 0xf8, 0xbc, 0xba, 0x8d, 0x18, 0x39, 0x6b,
+ 0x24, 0xd2, 0x5b, 0x90, 0xe9, 0xac, 0x85, 0x66, 0x34, 0x2a, 0xd2, 0xaf,
+ 0x12, 0xfb, 0x27, 0xf1, 0x3d, 0xce, 0xe9, 0xd3, 0xc5, 0x8e, 0x9b, 0x31,
+ 0x30, 0xab, 0xa9, 0xd7, 0xfd, 0x4c, 0x6c, 0x20, 0x76, 0xe9, 0xa8, 0x40,
+ 0xd5, 0x52, 0xea, 0xf6, 0x3d, 0x07, 0x4f, 0x82, 0xba, 0x8e, 0xff, 0x42,
+ 0x1e, 0xf4, 0x17, 0x05, 0xe9, 0x4b, 0x96, 0xb9, 0x9d, 0xf8, 0x44, 0x73,
+ 0xdb, 0x2d, 0x33, 0xc9, 0x52, 0x9f, 0x32, 0x10, 0xec, 0x9c, 0xb6, 0x71,
+ 0xd2, 0x08, 0x43, 0xea, 0xf3, 0xca, 0x54, 0x91, 0x19, 0xbf, 0x19, 0xdb,
+ 0x78, 0xbd, 0x63, 0xba, 0x5a, 0xe9, 0xc8, 0xd9, 0xf8, 0xa6, 0xa1, 0x65,
+ 0xda, 0xbd, 0x8c, 0x65, 0x43, 0x3b, 0x0b, 0x5c, 0x26, 0x27, 0x12, 0xdf,
+ 0xf2, 0x21, 0xa4, 0xbb, 0x63, 0x35, 0xcf, 0xdc, 0x46, 0xbe, 0x20, 0xb1,
+ 0xe5, 0x5d, 0x53, 0x85, 0x94, 0x32, 0xe3, 0x13, 0xbb, 0x75, 0x22, 0x5d,
+ 0xa8, 0x56, 0x76, 0xd3, 0x96, 0x77, 0xac, 0xab, 0xc0, 0x25, 0xc7, 0x96,
+ 0xb7, 0xd1, 0x96, 0x78, 0x6b, 0x05, 0xbc, 0xe7, 0xeb, 0xd0, 0xa9, 0xc0,
+ 0xa9, 0xbd, 0xaa, 0x99, 0x9f, 0xd3, 0xe4, 0xae, 0xe4, 0x7d, 0x6a, 0x2f,
+ 0xbe, 0x42, 0x9c, 0x79, 0x92, 0x3e, 0xfa, 0x33, 0xbd, 0x19, 0x55, 0x5f,
+ 0x6d, 0xe1, 0x3a, 0x6e, 0x0c, 0xee, 0xc8, 0xf5, 0xe1, 0xa9, 0x79, 0x1b,
+ 0xcf, 0x31, 0x3e, 0x1a, 0x53, 0x19, 0xb5, 0x92, 0xb5, 0x18, 0x73, 0xd9,
+ 0xe2, 0x09, 0xc7, 0xbf, 0x57, 0xb6, 0x6d, 0x9e, 0x8b, 0xc2, 0xfb, 0x15,
+ 0xf9, 0xbb, 0xbe, 0x2d, 0x36, 0x27, 0x9f, 0x51, 0x7e, 0xda, 0x18, 0x32,
+ 0xb4, 0xf4, 0xc7, 0xde, 0x2a, 0x54, 0x27, 0x6c, 0x7b, 0x28, 0x25, 0xd7,
+ 0xf5, 0xb6, 0xa4, 0x73, 0xbf, 0x81, 0x9f, 0xe5, 0x3e, 0xf2, 0xeb, 0xc2,
+ 0xf9, 0x62, 0x69, 0xea, 0xbc, 0x93, 0x79, 0xbd, 0x8f, 0x79, 0xbd, 0xce,
+ 0xd4, 0xd2, 0x7b, 0xbc, 0xd2, 0x3b, 0x29, 0x1e, 0xac, 0xe5, 0xf5, 0x5d,
+ 0xa5, 0xbc, 0x5e, 0x73, 0x4a, 0xfa, 0x70, 0xe4, 0x7a, 0x70, 0xf7, 0x2f,
+ 0xba, 0x99, 0xd7, 0xab, 0x26, 0x7d, 0xe8, 0x62, 0x4e, 0xf7, 0x93, 0x67,
+ 0x6f, 0xcd, 0xd7, 0x21, 0x78, 0xc2, 0x8b, 0x78, 0xea, 0xdb, 0x38, 0x48,
+ 0x1f, 0x3b, 0x98, 0xf4, 0x2a, 0xb1, 0xe5, 0x1e, 0xda, 0xe9, 0x9f, 0x70,
+ 0x40, 0xf5, 0xa2, 0x46, 0xff, 0x2e, 0x1e, 0xfa, 0x35, 0xb9, 0xbc, 0x2f,
+ 0x27, 0x31, 0xbd, 0xb2, 0xad, 0xeb, 0x94, 0x9b, 0xcb, 0x43, 0xa7, 0x46,
+ 0x17, 0x25, 0x97, 0xd7, 0xad, 0xef, 0xc3, 0xe9, 0x69, 0xfc, 0xe1, 0x0a,
+ 0x92, 0xc4, 0x3a, 0xce, 0xd9, 0x90, 0x4a, 0xb0, 0x6e, 0xd6, 0x06, 0xb7,
+ 0x29, 0x89, 0x89, 0x1a, 0xc6, 0xfe, 0x69, 0xe6, 0xf2, 0x80, 0x99, 0x50,
+ 0x93, 0x1e, 0x74, 0xfb, 0xb9, 0x1e, 0x1f, 0xb0, 0x86, 0xfe, 0x61, 0x3e,
+ 0xc6, 0x31, 0x2b, 0xe0, 0x63, 0x2e, 0xff, 0x40, 0xc7, 0xa7, 0x5e, 0xfa,
+ 0xde, 0x65, 0x6f, 0x00, 0x57, 0xf3, 0x6e, 0x2e, 0xaf, 0x6d, 0xb4, 0x47,
+ 0xae, 0xa4, 0x42, 0xf8, 0x30, 0x6f, 0xd0, 0x07, 0xfb, 0x70, 0x84, 0xb9,
+ 0xfc, 0x8a, 0xae, 0xe2, 0xa7, 0xf9, 0x56, 0xfa, 0x65, 0x04, 0x3f, 0x21,
+ 0xcf, 0x5d, 0xc7, 0x5c, 0x7e, 0x27, 0x7d, 0x2a, 0xc5, 0x5c, 0xde, 0xee,
+ 0xf0, 0x8c, 0xe6, 0xb6, 0x33, 0x53, 0x4e, 0x2e, 0x6f, 0x64, 0x89, 0x5f,
+ 0xef, 0x47, 0x62, 0x91, 0xf8, 0x60, 0xff, 0x6c, 0x63, 0x88, 0xcf, 0xd2,
+ 0x6e, 0x85, 0xf5, 0x98, 0x71, 0x72, 0xcf, 0xe6, 0xe0, 0x6e, 0xce, 0xbd,
+ 0xcc, 0x89, 0x33, 0x1b, 0x3b, 0xd7, 0xbd, 0x89, 0x3f, 0x58, 0xe2, 0xa1,
+ 0x1f, 0x9a, 0xc1, 0x3b, 0x18, 0x6b, 0x61, 0xfa, 0xd7, 0x4f, 0x53, 0x89,
+ 0xfe, 0x73, 0xac, 0x21, 0x7f, 0xc2, 0x38, 0xbb, 0x93, 0xbe, 0xb1, 0x72,
+ 0x5d, 0x80, 0xeb, 0xee, 0xc6, 0x59, 0x07, 0xe3, 0x2c, 0xca, 0x38, 0x5b,
+ 0xc1, 0x38, 0x7b, 0xda, 0x48, 0x24, 0x37, 0x93, 0x6f, 0xbd, 0x9e, 0x97,
+ 0x58, 0x6b, 0xe1, 0xb8, 0x1a, 0xf5, 0x1a, 0xed, 0x97, 0x98, 0xd9, 0xb9,
+ 0x6e, 0xf4, 0x6c, 0x35, 0xc4, 0x56, 0xf8, 0x74, 0x19, 0xb9, 0x05, 0x11,
+ 0xe9, 0xc2, 0xa2, 0x37, 0x31, 0xbc, 0xca, 0x9b, 0x18, 0x7a, 0x5f, 0x79,
+ 0xc7, 0x7e, 0x8b, 0x71, 0x76, 0x3b, 0xe3, 0x6c, 0x37, 0xe3, 0xac, 0xdd,
+ 0xb2, 0xf1, 0x52, 0x4a, 0xeb, 0x6b, 0xf6, 0xc4, 0x8d, 0x76, 0x0f, 0x56,
+ 0x54, 0x33, 0x25, 0x04, 0x91, 0xe8, 0xfc, 0x03, 0xca, 0x7f, 0xc1, 0x48,
+ 0xf4, 0x24, 0x15, 0x89, 0xad, 0x18, 0x7e, 0x4c, 0xbd, 0x2b, 0x4b, 0xb1,
+ 0xb5, 0x7f, 0xf6, 0xd5, 0x92, 0x6f, 0x94, 0x75, 0xf7, 0xe2, 0x45, 0x83,
+ 0x18, 0xba, 0x54, 0x8b, 0x65, 0x3c, 0xbd, 0x98, 0xa0, 0x1d, 0x83, 0x89,
+ 0x5e, 0x1c, 0x65, 0x1e, 0xbc, 0x9f, 0xf9, 0xf7, 0x01, 0x2b, 0xde, 0xba,
+ 0x83, 0x75, 0xce, 0xa5, 0xa8, 0x16, 0x8b, 0x29, 0xbd, 0x18, 0xa0, 0x0f,
+ 0x0f, 0x30, 0x5f, 0xb4, 0x5b, 0x3f, 0x57, 0xb6, 0x91, 0x23, 0xdc, 0x57,
+ 0x90, 0xf7, 0xb4, 0x64, 0xbf, 0x67, 0x10, 0xfd, 0xf3, 0x82, 0x6d, 0x50,
+ 0x6f, 0x32, 0x7b, 0x71, 0xdc, 0xaa, 0x40, 0x6f, 0x4b, 0xb7, 0xb2, 0xab,
+ 0x20, 0xbd, 0x33, 0xc6, 0xa3, 0xc5, 0x78, 0x75, 0xe4, 0x55, 0x88, 0xa5,
+ 0xdd, 0xc8, 0x4a, 0x7c, 0x5a, 0xbb, 0x95, 0x3b, 0x67, 0x25, 0xc6, 0x7b,
+ 0x95, 0x5e, 0x89, 0x61, 0x6b, 0x58, 0xb9, 0x4b, 0x62, 0xda, 0xe9, 0x33,
+ 0x4b, 0xdc, 0xcb, 0x3e, 0xc4, 0x6d, 0xe4, 0x6f, 0x60, 0x4c, 0x79, 0xbf,
+ 0x1a, 0x65, 0xdc, 0xb5, 0x57, 0x78, 0xe8, 0xa7, 0x71, 0xae, 0x9d, 0x07,
+ 0x1d, 0xc6, 0x6f, 0xda, 0x19, 0xb5, 0x9f, 0x31, 0xd5, 0x8b, 0x23, 0xd6,
+ 0x6f, 0xd8, 0x57, 0x1c, 0x5e, 0x52, 0xc6, 0xf3, 0xcd, 0xb8, 0x37, 0xb7,
+ 0x1c, 0x01, 0x5d, 0xf2, 0x75, 0x08, 0xc9, 0x25, 0x01, 0x54, 0xe9, 0x92,
+ 0x67, 0x9a, 0xdb, 0x16, 0x4e, 0x50, 0x86, 0x0d, 0xe5, 0xf8, 0xde, 0x8c,
+ 0x07, 0x89, 0x03, 0xfb, 0x52, 0xf7, 0xe2, 0x01, 0xb5, 0x0a, 0x61, 0xda,
+ 0xe9, 0x61, 0x35, 0x44, 0x7c, 0xfd, 0xbd, 0xd2, 0x38, 0xff, 0xa9, 0xa2,
+ 0x54, 0x33, 0x5f, 0xe3, 0x54, 0x75, 0x8c, 0xb1, 0x4d, 0xd3, 0x52, 0x9b,
+ 0x44, 0xdb, 0xa2, 0xd3, 0x3a, 0xc2, 0xac, 0x55, 0x37, 0xa7, 0xb4, 0xe1,
+ 0xcd, 0xde, 0xf8, 0xe0, 0xa2, 0x82, 0x6c, 0x98, 0x7c, 0x2e, 0x9f, 0x48,
+ 0xf4, 0x34, 0x8b, 0x8d, 0xf5, 0x28, 0xb6, 0xd3, 0x4e, 0x5d, 0xf9, 0x08,
+ 0x63, 0xe8, 0xbd, 0x0a, 0xe1, 0x46, 0xe9, 0xfc, 0xf5, 0xb1, 0xa2, 0x1c,
+ 0x2b, 0x3a, 0x2d, 0x3c, 0x2d, 0x4a, 0x9e, 0xa6, 0x33, 0x0e, 0x6d, 0x7b,
+ 0x13, 0xf9, 0x59, 0xe8, 0x94, 0xd4, 0x38, 0xf1, 0x09, 0x72, 0xda, 0x66,
+ 0xf2, 0xdd, 0x5e, 0x7a, 0xb5, 0xbd, 0xb2, 0x21, 0x61, 0xb4, 0x2b, 0x78,
+ 0x62, 0xae, 0x85, 0xf5, 0x11, 0xc7, 0xbc, 0x9c, 0x57, 0x71, 0x25, 0x1f,
+ 0xc5, 0xbb, 0x1c, 0xfb, 0x92, 0x33, 0x76, 0x3d, 0x7e, 0x54, 0xc2, 0xad,
+ 0x14, 0x71, 0x6b, 0x4b, 0x4e, 0xa1, 0xbf, 0xc6, 0x30, 0x62, 0xfc, 0xdd,
+ 0xa7, 0x97, 0x6e, 0x0e, 0xd0, 0x6e, 0xa2, 0x8b, 0x8f, 0x9f, 0xe3, 0x78,
+ 0xd8, 0xc1, 0xe9, 0x37, 0x3f, 0x9d, 0x59, 0xc2, 0xb5, 0xa2, 0xed, 0x6b,
+ 0x4b, 0xef, 0xad, 0x9d, 0xf9, 0xf3, 0x92, 0xbe, 0x3a, 0x3c, 0xa7, 0x92,
+ 0xa8, 0x38, 0x75, 0x4d, 0x56, 0x5d, 0xe2, 0x83, 0x19, 0xf5, 0x89, 0xaf,
+ 0x71, 0xfe, 0xc7, 0xc8, 0xf5, 0x6c, 0xce, 0x7f, 0xd5, 0x99, 0x37, 0xc2,
+ 0x79, 0x95, 0x6b, 0xbc, 0x30, 0x7a, 0xed, 0x1d, 0x95, 0xba, 0xe3, 0xf1,
+ 0x28, 0x6d, 0xf7, 0xe1, 0x06, 0x79, 0x2e, 0x84, 0x5d, 0xf9, 0x15, 0x95,
+ 0x82, 0xe3, 0x41, 0xd6, 0x01, 0xae, 0x2f, 0x91, 0xe7, 0x59, 0xcf, 0xf1,
+ 0x9e, 0xf0, 0xae, 0xcd, 0xe4, 0x18, 0x9f, 0xb5, 0x7b, 0x84, 0x6b, 0xf1,
+ 0x7f, 0xf8, 0x8e, 0xdc, 0xfb, 0x75, 0x79, 0xf4, 0x4f, 0x31, 0xcc, 0x1a,
+ 0xe8, 0xb1, 0x5c, 0x06, 0x0f, 0xe7, 0xbe, 0xec, 0xec, 0xab, 0xad, 0x5d,
+ 0x8f, 0xfb, 0x38, 0xe7, 0x81, 0x5a, 0xc6, 0xd1, 0x7f, 0x4b, 0x25, 0x84,
+ 0x1b, 0xed, 0xae, 0x86, 0xe4, 0xda, 0x44, 0xeb, 0x2a, 0xc5, 0x46, 0x45,
+ 0x0a, 0x43, 0x1d, 0x2d, 0x89, 0xe4, 0x15, 0x3c, 0x61, 0x4b, 0x5f, 0xd3,
+ 0x5b, 0xca, 0xbb, 0x52, 0xff, 0x49, 0x6f, 0xb5, 0xbd, 0xc4, 0x91, 0xb6,
+ 0x14, 0xde, 0xf9, 0x4c, 0xef, 0x40, 0xea, 0x6e, 0xc9, 0x37, 0x41, 0xa5,
+ 0x9d, 0xf3, 0x1c, 0x21, 0x66, 0xbf, 0x68, 0xbc, 0x12, 0x65, 0x36, 0x86,
+ 0x6f, 0x9d, 0x82, 0x83, 0x86, 0x1f, 0x99, 0x88, 0x8d, 0xdd, 0xfc, 0xdc,
+ 0x4f, 0xde, 0xf4, 0x9e, 0x51, 0x83, 0x19, 0x55, 0x25, 0x57, 0x24, 0x06,
+ 0x7b, 0xde, 0xf4, 0xcb, 0x5e, 0x4c, 0xcc, 0x23, 0xfb, 0xe6, 0xff, 0xd6,
+ 0x5e, 0xca, 0x3a, 0xf2, 0x16, 0xd1, 0x3d, 0xa8, 0x10, 0x43, 0x93, 0x20,
+ 0x97, 0xd9, 0x6b, 0x14, 0x63, 0x1e, 0xa4, 0xaf, 0x7a, 0xa0, 0x9d, 0xbe,
+ 0xcc, 0xfa, 0xee, 0xb1, 0x06, 0xed, 0x74, 0x9b, 0x57, 0xc7, 0xf0, 0xf1,
+ 0x00, 0x1e, 0x39, 0xbe, 0x0d, 0xb5, 0x4e, 0xef, 0x67, 0x9c, 0x36, 0xf5,
+ 0xb0, 0xae, 0x1a, 0xfd, 0xa5, 0x8f, 0xf5, 0xd5, 0xd5, 0xf5, 0x8f, 0xa3,
+ 0xd5, 0xb9, 0x3e, 0x86, 0xfb, 0x72, 0x41, 0xa5, 0x2b, 0xe7, 0xc3, 0xb6,
+ 0x3b, 0x1f, 0x87, 0x7f, 0x5d, 0x3f, 0xe5, 0x92, 0xeb, 0xf2, 0xf7, 0x5d,
+ 0xac, 0xcb, 0x44, 0xbe, 0x0a, 0xc4, 0x96, 0x53, 0xb6, 0x75, 0x3a, 0x46,
+ 0x8e, 0xfb, 0x94, 0x3d, 0xd6, 0x7f, 0xb7, 0xaf, 0x3a, 0xfb, 0x34, 0x72,
+ 0xad, 0x4a, 0xf6, 0xef, 0xf9, 0x8c, 0x60, 0xce, 0x00, 0x72, 0x8c, 0xed,
+ 0xbb, 0x9c, 0xf7, 0xff, 0xb8, 0xc2, 0xd5, 0x29, 0xcd, 0x7a, 0xb5, 0x83,
+ 0xeb, 0x27, 0xcf, 0x24, 0x4b, 0xd7, 0x9a, 0x03, 0xee, 0x19, 0x01, 0xf1,
+ 0x85, 0x01, 0xdc, 0xc2, 0x45, 0x68, 0x48, 0x88, 0x8f, 0x0d, 0xa0, 0x21,
+ 0x4f, 0x40, 0x5d, 0xee, 0xca, 0xfb, 0x90, 0x55, 0x64, 0xad, 0xa9, 0x13,
+ 0x37, 0x69, 0xbb, 0x65, 0xf2, 0xfe, 0x2f, 0x2a, 0x7f, 0xf5, 0x7d, 0xc1,
+ 0x5b, 0x72, 0xcc, 0xb0, 0x70, 0xcd, 0x5f, 0x77, 0xff, 0xb7, 0x20, 0xf7,
+ 0x7c, 0xfa, 0x9f, 0x30, 0x8e, 0x13, 0x3d, 0xd5, 0x1e, 0xf1, 0x9f, 0x3f,
+ 0xc1, 0x03, 0xb3, 0x8f, 0xf0, 0xbe, 0x8c, 0x7f, 0x88, 0x35, 0x84, 0x4f,
+ 0xe9, 0x24, 0xfe, 0xec, 0x3f, 0xee, 0xd9, 0x55, 0x81, 0xbf, 0xb4, 0x2b,
+ 0x97, 0x8d, 0xa0, 0x21, 0x35, 0xc6, 0xe7, 0x15, 0x74, 0x90, 0x2f, 0x3e,
+ 0x65, 0x6c, 0xc1, 0xb6, 0x25, 0x82, 0x01, 0x2f, 0xda, 0x03, 0xbd, 0x62,
+ 0x43, 0x05, 0x5b, 0x79, 0xfd, 0x25, 0xae, 0xef, 0xb3, 0x86, 0x0f, 0x0d,
+ 0x4b, 0xa5, 0x8f, 0xa7, 0x4d, 0xa5, 0xd1, 0x1e, 0x70, 0xf7, 0xab, 0x32,
+ 0x76, 0xad, 0xae, 0x0f, 0xdd, 0xe1, 0x69, 0x98, 0x7a, 0x9b, 0xfe, 0xd4,
+ 0xbe, 0xee, 0xc6, 0x7b, 0x65, 0x9b, 0x18, 0xe4, 0x90, 0x2f, 0xd8, 0xb8,
+ 0x69, 0x14, 0xea, 0xba, 0x1b, 0xd7, 0xbf, 0x2c, 0xf7, 0x21, 0xc6, 0x20,
+ 0x32, 0xb5, 0xa6, 0xf4, 0x79, 0x12, 0x1c, 0xe7, 0x10, 0x7e, 0xbf, 0x30,
+ 0x86, 0x83, 0xb9, 0x12, 0xa7, 0xa6, 0x6f, 0xeb, 0xeb, 0xae, 0xeb, 0xf6,
+ 0x50, 0x2e, 0xd1, 0x5f, 0x53, 0xd2, 0xed, 0x00, 0xeb, 0x8b, 0x6a, 0x62,
+ 0xec, 0x83, 0xb4, 0xe9, 0x90, 0x63, 0xd3, 0x5e, 0x18, 0xf9, 0xeb, 0xe3,
+ 0x0e, 0x72, 0xdc, 0xa0, 0x29, 0x76, 0x93, 0x3d, 0xb2, 0x43, 0xd8, 0xcf,
+ 0x71, 0xf7, 0xdd, 0x30, 0xee, 0x80, 0x71, 0x7d, 0xdc, 0xbd, 0xb9, 0xc4,
+ 0x69, 0x4f, 0x69, 0xdc, 0x47, 0x67, 0xcb, 0x63, 0x64, 0x70, 0xfb, 0xba,
+ 0x0c, 0xf2, 0x9b, 0x0e, 0xd8, 0x07, 0x1c, 0x7b, 0x9c, 0x72, 0xae, 0x6f,
+ 0x6d, 0x10, 0xee, 0xc5, 0x3f, 0x4d, 0xd9, 0x8f, 0x4f, 0x92, 0x7b, 0xe9,
+ 0xce, 0x9e, 0xf0, 0x37, 0x0a, 0xe5, 0xbe, 0x94, 0xf6, 0x4e, 0x97, 0x37,
+ 0xcd, 0xd8, 0x8e, 0x04, 0x76, 0x7c, 0xa6, 0x97, 0xb1, 0x8d, 0xf5, 0xd7,
+ 0x76, 0xab, 0x3b, 0xd8, 0x69, 0x05, 0xc8, 0xbb, 0xaa, 0x95, 0xad, 0x39,
+ 0xe9, 0x69, 0x48, 0x2c, 0x97, 0xb8, 0x70, 0x41, 0xea, 0xbc, 0xbb, 0x59,
+ 0x1f, 0x2c, 0x0f, 0x20, 0xdc, 0x8f, 0x89, 0xc2, 0xef, 0x2a, 0xe9, 0x88,
+ 0xec, 0x4d, 0x4b, 0x5e, 0x01, 0x73, 0x5e, 0x0f, 0xaa, 0xe9, 0x4b, 0x11,
+ 0xd3, 0x30, 0x4f, 0x36, 0xd8, 0x20, 0x47, 0x09, 0x2c, 0x35, 0xd3, 0xe6,
+ 0xee, 0x06, 0x2f, 0x8e, 0x39, 0xfc, 0x4b, 0x9b, 0xe1, 0xef, 0x94, 0xc4,
+ 0xcc, 0x1d, 0x39, 0xc9, 0x63, 0xa4, 0x90, 0xfa, 0x08, 0xfe, 0x31, 0x55,
+ 0x1c, 0x5a, 0x82, 0xf4, 0xfd, 0x4b, 0x20, 0xf5, 0xc4, 0x04, 0xfe, 0x4a,
+ 0x8f, 0x06, 0xfa, 0x0a, 0x3e, 0xa5, 0xcb, 0x9a, 0x0b, 0xee, 0xb4, 0xc2,
+ 0x08, 0xb1, 0x1e, 0xeb, 0xf6, 0xc6, 0x59, 0x5f, 0x88, 0x1d, 0x03, 0x6d,
+ 0xb7, 0xe4, 0xfb, 0x82, 0x1d, 0x96, 0x8b, 0x85, 0x2b, 0x67, 0x02, 0xc1,
+ 0x6d, 0xd3, 0xf1, 0xe8, 0x84, 0xc3, 0xc5, 0x42, 0x6d, 0xf1, 0xbc, 0x6d,
+ 0xbf, 0x61, 0x14, 0xaf, 0x56, 0x3a, 0xdf, 0x8d, 0xb6, 0x64, 0xbe, 0x19,
+ 0xf7, 0x90, 0x3f, 0xb5, 0x4f, 0x37, 0xc3, 0x98, 0x06, 0x4e, 0x1c, 0x8f,
+ 0x62, 0x6d, 0x4e, 0x3b, 0x3d, 0xec, 0xed, 0xc3, 0xd4, 0x7c, 0x27, 0x72,
+ 0x85, 0xe0, 0x62, 0xcc, 0x43, 0x5e, 0x9d, 0xf2, 0x60, 0x97, 0x71, 0x5c,
+ 0x29, 0x2e, 0x53, 0x70, 0x17, 0x11, 0xbc, 0xdf, 0xe1, 0x13, 0x73, 0xac,
+ 0x47, 0x15, 0xdc, 0xe4, 0xe0, 0x6e, 0x4b, 0xdb, 0x5a, 0xf2, 0xed, 0x3b,
+ 0xc9, 0x07, 0x77, 0x11, 0x57, 0x12, 0xeb, 0x6c, 0xbc, 0x99, 0xca, 0xf4,
+ 0xd7, 0x40, 0xeb, 0x39, 0xcc, 0x1a, 0xa8, 0x47, 0x71, 0xf9, 0x5d, 0xd3,
+ 0x9c, 0xcb, 0x09, 0x57, 0xcd, 0xb5, 0x90, 0x37, 0xb2, 0xae, 0x49, 0x69,
+ 0x31, 0x8f, 0x47, 0xc5, 0x94, 0x33, 0x46, 0xac, 0xcd, 0x98, 0xab, 0x60,
+ 0xbe, 0xeb, 0xc5, 0xd3, 0x8e, 0xfc, 0x49, 0xca, 0x77, 0x37, 0xbe, 0x66,
+ 0xf5, 0x05, 0xfb, 0x2c, 0xd9, 0xbf, 0x8c, 0x27, 0xaf, 0x7a, 0x4d, 0xf2,
+ 0xd7, 0x78, 0xac, 0xce, 0xfb, 0x05, 0x25, 0xe3, 0x6b, 0x6a, 0x9d, 0x83,
+ 0xa9, 0x5c, 0x2a, 0x71, 0x36, 0xd1, 0x2f, 0x41, 0x8e, 0xd5, 0x7e, 0x3c,
+ 0xb8, 0x98, 0x86, 0xdb, 0xb3, 0xd9, 0x66, 0xfc, 0x2f, 0x14, 0x23, 0xda,
+ 0x44, 0x9a, 0x18, 0xb0, 0x85, 0x98, 0xdb, 0xdf, 0xeb, 0xe3, 0x7d, 0xe9,
+ 0x79, 0xa9, 0x6d, 0xe3, 0x59, 0x14, 0x83, 0x66, 0x22, 0x73, 0x94, 0x9e,
+ 0xd3, 0x53, 0x90, 0xfd, 0x8d, 0x00, 0x1e, 0x60, 0xed, 0x94, 0x2e, 0xed,
+ 0xfd, 0x6c, 0x9d, 0x76, 0xf7, 0xb3, 0x0e, 0xcf, 0xfb, 0xc2, 0xdd, 0x56,
+ 0x0b, 0xf3, 0xbd, 0xef, 0x86, 0xb1, 0x13, 0x13, 0x2b, 0x3d, 0x1e, 0xac,
+ 0x5e, 0xb7, 0x47, 0x99, 0x59, 0x56, 0xce, 0xad, 0x51, 0x27, 0x1f, 0x56,
+ 0x50, 0xcf, 0xf3, 0x27, 0x65, 0x8e, 0xcf, 0xb5, 0x8d, 0x9f, 0x94, 0x5c,
+ 0xab, 0xb6, 0x6d, 0xb2, 0xb4, 0x3e, 0xa9, 0xfd, 0xa2, 0xb4, 0x53, 0x94,
+ 0xba, 0xad, 0x30, 0xd7, 0xb4, 0xd9, 0xd3, 0x5a, 0x74, 0x40, 0x49, 0x93,
+ 0xf7, 0x69, 0xc9, 0x5b, 0xbc, 0x1e, 0x3c, 0xa2, 0x6b, 0x83, 0xd2, 0x13,
+ 0x7c, 0x19, 0x2e, 0x07, 0x6e, 0x9a, 0x1b, 0x60, 0x5e, 0x73, 0x6d, 0xeb,
+ 0xf6, 0x07, 0xeb, 0xdb, 0x9a, 0x1d, 0x5e, 0x6c, 0xdb, 0x97, 0x53, 0xdd,
+ 0xe4, 0x0c, 0xc2, 0x8b, 0xe5, 0xfa, 0xea, 0xb6, 0xc6, 0x99, 0x00, 0x65,
+ 0x53, 0xf0, 0x3e, 0x73, 0xd2, 0x44, 0xa1, 0x2c, 0xa3, 0xcb, 0x99, 0x77,
+ 0x90, 0x33, 0x57, 0x99, 0x5a, 0x6b, 0x17, 0x39, 0xb3, 0x9e, 0x2a, 0xd6,
+ 0xf9, 0xd0, 0x8b, 0xa7, 0xac, 0x66, 0x39, 0xe3, 0xe4, 0xf0, 0xe6, 0x2b,
+ 0x27, 0xb5, 0xb4, 0x70, 0xe6, 0x1f, 0x18, 0xc0, 0x3d, 0xe4, 0xcc, 0x57,
+ 0xb3, 0x3e, 0xec, 0x21, 0x67, 0x5e, 0xcc, 0x06, 0xd0, 0x47, 0xce, 0xfc,
+ 0x11, 0xf9, 0xd5, 0xbb, 0xa9, 0x2b, 0x78, 0xb4, 0xd4, 0x07, 0xdb, 0x9b,
+ 0xf4, 0xd0, 0xaf, 0x85, 0x37, 0xff, 0xbc, 0xc4, 0x9b, 0xe7, 0xff, 0x05,
+ 0x6f, 0xde, 0x4a, 0x3e, 0xd8, 0x9d, 0x13, 0x4e, 0xb0, 0x92, 0x9c, 0xc0,
+ 0xc6, 0xcb, 0xa5, 0x1e, 0xd8, 0x0a, 0xe6, 0xb3, 0xa7, 0x53, 0x7d, 0xc8,
+ 0x4e, 0x63, 0x79, 0x8d, 0xd3, 0x77, 0x12, 0x99, 0x34, 0xe3, 0xb2, 0x92,
+ 0xe8, 0xec, 0x43, 0x82, 0xf5, 0xb1, 0x96, 0xbc, 0xe8, 0xf6, 0xc0, 0x16,
+ 0xdf, 0x85, 0xf4, 0x88, 0x7c, 0xa8, 0x59, 0x00, 0x56, 0xdc, 0xd0, 0x03,
+ 0xab, 0x49, 0xe0, 0x4f, 0xeb, 0x20, 0xfb, 0x9a, 0x0c, 0xb3, 0x85, 0x66,
+ 0xc6, 0xa7, 0x82, 0x23, 0x89, 0x10, 0xba, 0x8f, 0x93, 0xf3, 0x38, 0x3d,
+ 0x30, 0x7b, 0xe4, 0x3b, 0x46, 0x1f, 0x8e, 0xce, 0xbb, 0x3d, 0xb0, 0xed,
+ 0xe4, 0x6e, 0xbe, 0x44, 0x04, 0x95, 0x0b, 0x3e, 0xbc, 0x40, 0xee, 0xbc,
+ 0x95, 0xeb, 0x7c, 0xa6, 0xd4, 0x07, 0x5b, 0xc1, 0x18, 0xb1, 0x73, 0x2a,
+ 0x66, 0x16, 0xf0, 0x86, 0x17, 0xb8, 0xb8, 0xc2, 0xe9, 0xed, 0x4b, 0xff,
+ 0x3f, 0x84, 0x73, 0x0e, 0x77, 0x0e, 0x2e, 0x66, 0x14, 0x57, 0xb7, 0x0a,
+ 0xae, 0x89, 0xac, 0xab, 0x87, 0xeb, 0xda, 0x7e, 0x52, 0xeb, 0x7c, 0x85,
+ 0xb6, 0x68, 0x4a, 0xbc, 0xea, 0xac, 0xc7, 0x40, 0x4a, 0x6a, 0xd9, 0x40,
+ 0x5b, 0xc0, 0x39, 0x0f, 0xa5, 0xb6, 0xfd, 0x28, 0x1b, 0xef, 0xa9, 0x2c,
+ 0xc5, 0xe3, 0xaa, 0x7c, 0x05, 0xd2, 0x25, 0x1f, 0x09, 0xd0, 0xa7, 0x03,
+ 0x93, 0x69, 0x54, 0x6d, 0x70, 0xfd, 0x7b, 0x55, 0x7e, 0x9c, 0xbc, 0xb5,
+ 0x53, 0xea, 0xe8, 0xf0, 0x76, 0xab, 0x13, 0x53, 0x56, 0x0c, 0x95, 0xe7,
+ 0x4a, 0x7b, 0xa6, 0xe7, 0xe4, 0xec, 0x5c, 0x7d, 0x9b, 0xfa, 0xd5, 0x32,
+ 0x1f, 0x4c, 0x93, 0xe3, 0x44, 0x02, 0x77, 0x14, 0x84, 0x2b, 0xf6, 0xe0,
+ 0xa8, 0xa5, 0x45, 0xbf, 0x87, 0xf8, 0xd0, 0xfd, 0xb4, 0x51, 0xb1, 0xee,
+ 0x7a, 0xbf, 0x69, 0x40, 0xfa, 0x51, 0x9f, 0xe9, 0x37, 0x0d, 0xe7, 0xf0,
+ 0x8b, 0xba, 0x96, 0x4a, 0x78, 0xd6, 0xfa, 0xc9, 0xe7, 0xb5, 0xe8, 0xd3,
+ 0x78, 0x02, 0x23, 0xb9, 0x9f, 0x2b, 0x21, 0xdd, 0x37, 0xf8, 0x13, 0xaf,
+ 0x16, 0x9d, 0x53, 0x42, 0x7c, 0xf7, 0xee, 0x60, 0x97, 0x75, 0x37, 0x71,
+ 0x27, 0x9e, 0xec, 0x54, 0xbc, 0x98, 0x89, 0x3a, 0x5c, 0x34, 0xd8, 0xc3,
+ 0x6b, 0x53, 0x85, 0x32, 0xa7, 0x71, 0x6b, 0xfe, 0xed, 0xc7, 0x5d, 0xfc,
+ 0x88, 0xe7, 0x83, 0x8b, 0x97, 0xe0, 0xea, 0x56, 0x4d, 0x5d, 0x1f, 0x9c,
+ 0x54, 0xed, 0xfe, 0x65, 0x12, 0xc3, 0x3a, 0xf6, 0xd0, 0xf7, 0xee, 0x99,
+ 0x1e, 0xa0, 0x9c, 0xc2, 0xa5, 0x57, 0x10, 0xa7, 0xfa, 0x30, 0x4e, 0x9c,
+ 0xb1, 0x28, 0x5f, 0x8e, 0x35, 0xe4, 0xe2, 0xfa, 0x8c, 0x3d, 0xb9, 0x41,
+ 0x37, 0x56, 0x7b, 0x8b, 0x4b, 0xa2, 0xe4, 0x36, 0xeb, 0x98, 0xb7, 0xdb,
+ 0x0b, 0xcd, 0xb8, 0x7c, 0x46, 0x67, 0x7d, 0xdb, 0x41, 0xee, 0xde, 0x83,
+ 0x87, 0xa9, 0xcf, 0xa3, 0x85, 0xc7, 0x91, 0xfe, 0x92, 0x0f, 0x87, 0x8f,
+ 0xa7, 0xb1, 0x6a, 0x5d, 0x0a, 0xe9, 0x2f, 0x06, 0x88, 0x53, 0x21, 0x4c,
+ 0x30, 0x16, 0xa1, 0xb8, 0x7e, 0x2e, 0xe7, 0x7f, 0xfe, 0x82, 0x36, 0xfb,
+ 0x26, 0xed, 0xf7, 0x8d, 0x6b, 0x7b, 0x00, 0x65, 0xfe, 0x7d, 0x9d, 0xab,
+ 0x7a, 0xb9, 0x86, 0xfb, 0x9c, 0xd8, 0x8c, 0x32, 0x36, 0x75, 0x5c, 0x2d,
+ 0xf5, 0x12, 0x17, 0x4f, 0x6a, 0x8b, 0xf7, 0x22, 0x3e, 0x7c, 0xd9, 0x8b,
+ 0x81, 0x3a, 0xfa, 0x5d, 0x94, 0x5c, 0xf5, 0xc3, 0x44, 0xc2, 0x38, 0x47,
+ 0xae, 0x3a, 0xba, 0xc1, 0xe5, 0xaa, 0x9e, 0x05, 0x15, 0x15, 0x0b, 0xac,
+ 0x65, 0x9d, 0x5e, 0xe2, 0x37, 0x83, 0x6e, 0x2f, 0x51, 0xf8, 0x4d, 0xab,
+ 0x9c, 0x75, 0xba, 0x8d, 0xb5, 0x5c, 0xfa, 0x0a, 0x32, 0xe8, 0x2c, 0xcc,
+ 0x04, 0xef, 0x21, 0x36, 0xf7, 0x49, 0x6f, 0xa4, 0x10, 0x09, 0xdf, 0x43,
+ 0xde, 0xf5, 0x2d, 0xae, 0xaf, 0xec, 0xed, 0xf6, 0x15, 0x56, 0xf3, 0xbd,
+ 0x28, 0x3f, 0x05, 0x57, 0x45, 0xf6, 0x1b, 0xf5, 0xe8, 0xa9, 0x92, 0xbd,
+ 0x86, 0x97, 0xa9, 0x43, 0xff, 0xdc, 0x4a, 0x3c, 0x3a, 0xe7, 0xaf, 0x12,
+ 0xc2, 0xff, 0x68, 0xde, 0xc5, 0xb6, 0x58, 0xfe, 0xae, 0xa0, 0xf0, 0xc9,
+ 0xf6, 0xe3, 0xee, 0x77, 0xfd, 0x86, 0xef, 0x65, 0xfd, 0x56, 0x50, 0x3f,
+ 0x7b, 0x5a, 0xea, 0xa2, 0x68, 0xdb, 0x19, 0xea, 0xb7, 0x78, 0xd2, 0x89,
+ 0x2f, 0xd6, 0x98, 0xf1, 0xe1, 0x84, 0x57, 0xf4, 0xfa, 0x99, 0xe8, 0x45,
+ 0xae, 0xc2, 0x78, 0xe1, 0xb8, 0x1e, 0x3d, 0xe2, 0xe8, 0xe5, 0xea, 0xe3,
+ 0xf6, 0x69, 0xaf, 0x9c, 0x4c, 0xde, 0xd8, 0x17, 0xd5, 0xc9, 0x97, 0x3f,
+ 0x61, 0x6c, 0x3c, 0x71, 0x98, 0x9c, 0xf9, 0x2a, 0x6b, 0x4a, 0x3f, 0x9f,
+ 0xaf, 0x73, 0x9e, 0x97, 0x3e, 0xad, 0xe7, 0x1a, 0x67, 0x5e, 0xbc, 0xfe,
+ 0x4e, 0x89, 0x2f, 0x4b, 0x4f, 0x5a, 0x9e, 0x53, 0x1d, 0x3b, 0xed, 0x76,
+ 0x78, 0xa0, 0x70, 0x2b, 0x1b, 0x1d, 0xeb, 0xfe, 0xad, 0x35, 0x0b, 0x2e,
+ 0xce, 0x38, 0x6e, 0xd5, 0x55, 0x25, 0x7b, 0xe1, 0xab, 0xd6, 0x3d, 0x68,
+ 0xbb, 0xfe, 0x1c, 0x09, 0xef, 0x62, 0x9c, 0x7c, 0x85, 0xef, 0xec, 0x3a,
+ 0x57, 0x1f, 0xbe, 0xcb, 0x6a, 0x71, 0x6c, 0x74, 0xd7, 0xb9, 0x28, 0x46,
+ 0x2d, 0xe9, 0xeb, 0x43, 0xf1, 0x99, 0x87, 0xb1, 0x7d, 0x2a, 0x86, 0x77,
+ 0x8d, 0x60, 0xe9, 0xec, 0x89, 0xc4, 0xa4, 0xc1, 0x98, 0x8c, 0xd0, 0x77,
+ 0xe3, 0xb1, 0x77, 0xc9, 0x51, 0x33, 0x3e, 0xe0, 0x68, 0x8e, 0xb8, 0x46,
+ 0xde, 0x08, 0xc5, 0x3d, 0xbb, 0xe9, 0xbe, 0x5b, 0xfe, 0xbb, 0x1a, 0xb1,
+ 0x25, 0xf1, 0xd6, 0xfd, 0xa8, 0x47, 0x96, 0xd8, 0x1f, 0xd4, 0xff, 0x1a,
+ 0xc7, 0x4e, 0x78, 0x98, 0x1f, 0x08, 0x4e, 0x77, 0x1a, 0xfc, 0xde, 0x34,
+ 0xf8, 0x01, 0xfe, 0xd1, 0x9e, 0x91, 0xf3, 0x51, 0x8a, 0x9c, 0xc5, 0xf8,
+ 0xc4, 0xae, 0xd3, 0xf5, 0xe2, 0xb7, 0xa0, 0x0f, 0x5f, 0x45, 0xd3, 0xd0,
+ 0x22, 0x7e, 0x6c, 0x17, 0x79, 0xef, 0x7d, 0xc6, 0xd1, 0x2b, 0x46, 0x3c,
+ 0xea, 0xa1, 0xf0, 0xc5, 0x88, 0x17, 0xf7, 0x1b, 0xb2, 0xa7, 0xa4, 0x0d,
+ 0x3d, 0x0f, 0x6d, 0xf0, 0xbc, 0x22, 0x67, 0x6a, 0x2e, 0xd9, 0x99, 0x25,
+ 0x32, 0xaf, 0x82, 0xb5, 0xab, 0x9b, 0x3a, 0x2b, 0xa0, 0xb5, 0xfa, 0x15,
+ 0xdd, 0xf8, 0x40, 0xf9, 0x7b, 0xbb, 0x18, 0xf9, 0xc4, 0xbe, 0xac, 0x97,
+ 0xc7, 0xd5, 0x62, 0x01, 0x6f, 0x59, 0xb6, 0x7a, 0x1c, 0xb3, 0x64, 0x2f,
+ 0xee, 0xaf, 0xf1, 0xc0, 0x09, 0x1f, 0x3a, 0x52, 0x3f, 0xb1, 0x33, 0x11,
+ 0x19, 0xf3, 0x13, 0xda, 0x42, 0xc6, 0x77, 0xfb, 0xd5, 0x2f, 0x17, 0xa0,
+ 0x6c, 0xb3, 0x84, 0x33, 0x8b, 0x5f, 0x4c, 0xc1, 0xb6, 0xa4, 0x87, 0x68,
+ 0xe3, 0x8e, 0xd4, 0x08, 0xde, 0x4f, 0xa5, 0xff, 0x63, 0x00, 0xda, 0x85,
+ 0x2b, 0x5e, 0xad, 0xd8, 0xec, 0x8d, 0x29, 0xc1, 0x46, 0x7d, 0xa8, 0xd1,
+ 0xdd, 0x9f, 0x67, 0xfd, 0x14, 0x0a, 0xec, 0x2a, 0x48, 0x9d, 0x39, 0x85,
+ 0x85, 0xc9, 0x0c, 0x7c, 0xe4, 0x77, 0xa3, 0x2d, 0x5a, 0xdf, 0x73, 0x8a,
+ 0x16, 0x3d, 0xa0, 0xc4, 0x94, 0x7b, 0xf5, 0x61, 0xbc, 0x60, 0x24, 0xd2,
+ 0xed, 0x4a, 0x7d, 0xa0, 0xb3, 0x50, 0x1e, 0xbb, 0x83, 0xb8, 0xa1, 0x15,
+ 0xaf, 0x78, 0x2b, 0x51, 0xb7, 0x5e, 0xef, 0xac, 0xf4, 0x6a, 0xc3, 0x5f,
+ 0x60, 0x1d, 0xb0, 0xa3, 0x50, 0x0c, 0x7e, 0x90, 0xf0, 0x60, 0x8d, 0xb3,
+ 0x87, 0x90, 0x2d, 0xf5, 0x47, 0xa7, 0xd0, 0x35, 0x69, 0x6f, 0xbe, 0x98,
+ 0xd2, 0xa2, 0xcf, 0x29, 0x99, 0x3d, 0x21, 0xf2, 0x9a, 0x07, 0xa1, 0xc7,
+ 0xe6, 0x19, 0xc7, 0x1d, 0x05, 0x0f, 0x56, 0x3a, 0x7e, 0x9c, 0xe5, 0x98,
+ 0x87, 0x51, 0x79, 0xc2, 0xde, 0xbc, 0xc7, 0xd0, 0x86, 0xaf, 0x78, 0x33,
+ 0xff, 0xb5, 0x8e, 0x76, 0xdb, 0xa6, 0x68, 0xac, 0x4f, 0x47, 0x70, 0x91,
+ 0x3a, 0x7c, 0x3d, 0xa5, 0x25, 0xff, 0x4c, 0xd1, 0x7a, 0xbe, 0x4c, 0x5f,
+ 0xf6, 0x9a, 0x61, 0xca, 0xa9, 0x25, 0x67, 0x21, 0xbd, 0xf3, 0x18, 0xae,
+ 0x18, 0x99, 0xe0, 0xf6, 0xc6, 0x24, 0xf9, 0x59, 0x94, 0xf9, 0x30, 0x86,
+ 0xa3, 0xe4, 0x77, 0x87, 0x0b, 0x15, 0x28, 0xaa, 0x3a, 0xf9, 0x59, 0x0f,
+ 0x3c, 0x93, 0x21, 0x65, 0x2e, 0x1b, 0x37, 0x3a, 0xf0, 0x47, 0x28, 0x3a,
+ 0x38, 0x77, 0x18, 0xa1, 0x13, 0x3f, 0xb0, 0x6b, 0x74, 0xbd, 0x75, 0x52,
+ 0xe1, 0xbc, 0xcf, 0x44, 0x69, 0x63, 0xbe, 0x27, 0xe7, 0x4e, 0xac, 0x6e,
+ 0xdc, 0x3b, 0x19, 0xe1, 0xfb, 0x35, 0x58, 0x7b, 0x22, 0x86, 0x0f, 0x53,
+ 0x37, 0xa3, 0xe8, 0x70, 0x04, 0x85, 0x7e, 0x40, 0x3f, 0x62, 0xad, 0x95,
+ 0x21, 0x8f, 0x94, 0x7d, 0xa3, 0xc3, 0x96, 0xd4, 0xe8, 0x3e, 0x7e, 0x0f,
+ 0xf1, 0x57, 0xec, 0xf9, 0x39, 0x72, 0x1d, 0xf9, 0x5c, 0xd3, 0x16, 0x9b,
+ 0xfb, 0x5e, 0x95, 0xb3, 0x7f, 0x89, 0x18, 0x9f, 0x53, 0x9d, 0xde, 0xe0,
+ 0x28, 0xc7, 0x3c, 0x3b, 0x25, 0xb5, 0x5b, 0xfb, 0xa6, 0x40, 0x69, 0x7f,
+ 0xfd, 0x87, 0x86, 0x07, 0x9b, 0x59, 0xdf, 0x47, 0x75, 0x39, 0x9b, 0x39,
+ 0xaa, 0xd5, 0x61, 0x13, 0x4e, 0xab, 0x2c, 0xc4, 0xf5, 0xff, 0x80, 0x09,
+ 0x35, 0x49, 0xac, 0xd1, 0xf1, 0x5e, 0xf6, 0x37, 0x58, 0xf3, 0xd4, 0xcb,
+ 0xd9, 0x1b, 0xac, 0x3c, 0xe1, 0xe7, 0x9c, 0x9b, 0xc9, 0x75, 0xb6, 0xe3,
+ 0xbb, 0xaa, 0x5b, 0x6f, 0x10, 0x8f, 0x30, 0x3e, 0x1b, 0x22, 0x1f, 0x0d,
+ 0xf0, 0xf7, 0x46, 0xd9, 0x7e, 0x9d, 0x4c, 0xa2, 0xcb, 0xbf, 0x25, 0x53,
+ 0x80, 0x7c, 0x80, 0x78, 0x99, 0x7d, 0x0d, 0x1f, 0x72, 0xec, 0xcc, 0xac,
+ 0x3b, 0xe6, 0xf1, 0x82, 0x8c, 0x2b, 0xf3, 0xc5, 0x99, 0x37, 0x65, 0xfc,
+ 0x90, 0x9c, 0xbf, 0xfd, 0x77, 0xce, 0x41, 0x86, 0x77, 0x82, 0x35, 0xb2,
+ 0xd1, 0x88, 0x0e, 0x95, 0xeb, 0x65, 0xc9, 0x1c, 0x1a, 0xeb, 0x51, 0x79,
+ 0x37, 0x8a, 0x35, 0x93, 0xf6, 0x48, 0xd4, 0x94, 0xeb, 0xb6, 0x5d, 0xbb,
+ 0x51, 0x8f, 0xbe, 0xad, 0xf8, 0x98, 0xf3, 0x7c, 0xb4, 0xc1, 0x38, 0xce,
+ 0x66, 0x9b, 0x2e, 0xbc, 0x4f, 0x0e, 0x15, 0x63, 0xbd, 0x77, 0xc9, 0x3b,
+ 0x8e, 0xb9, 0xec, 0xb1, 0x6a, 0xe9, 0x13, 0x30, 0x0f, 0x2a, 0xb3, 0xd9,
+ 0xfb, 0xab, 0x05, 0xab, 0xc6, 0xe8, 0x0b, 0xcd, 0x93, 0x22, 0xab, 0x3d,
+ 0x52, 0xc3, 0x71, 0x8e, 0x72, 0x9c, 0xd9, 0x0d, 0x7a, 0xdf, 0x98, 0x22,
+ 0x36, 0x0b, 0xe1, 0x58, 0xe1, 0xa2, 0xf4, 0xd0, 0x68, 0xb7, 0x69, 0x3e,
+ 0x2f, 0x76, 0x8b, 0xe0, 0xbb, 0xa5, 0x71, 0x9e, 0x2a, 0x5c, 0xc0, 0x6c,
+ 0xf6, 0x2d, 0xe7, 0xef, 0x31, 0xd6, 0x0d, 0xe3, 0xac, 0x21, 0xf3, 0xc4,
+ 0x93, 0xc9, 0x6c, 0x53, 0xdf, 0x24, 0xe5, 0x70, 0xcf, 0xca, 0x0d, 0xe0,
+ 0xd9, 0xd2, 0x33, 0xa3, 0x7c, 0x77, 0xf4, 0xda, 0xdf, 0x62, 0x23, 0x77,
+ 0x0f, 0xdf, 0xdd, 0x53, 0xa8, 0xe4, 0xda, 0xb9, 0xb5, 0xf8, 0x11, 0xcb,
+ 0x2f, 0x7d, 0x70, 0xbc, 0x36, 0xb5, 0x19, 0x63, 0xc6, 0x5f, 0x62, 0x2f,
+ 0xf5, 0x1e, 0xa7, 0x3d, 0x4f, 0x58, 0xce, 0x5e, 0xbd, 0x9c, 0xcb, 0x22,
+ 0x96, 0x87, 0xda, 0xce, 0x90, 0x93, 0x1d, 0x63, 0xcc, 0xdc, 0x97, 0x6a,
+ 0xea, 0x79, 0x9d, 0x7e, 0x97, 0xfe, 0xa2, 0xec, 0x87, 0x03, 0x93, 0xb9,
+ 0x47, 0x31, 0xb3, 0xa4, 0x69, 0xf1, 0x45, 0x62, 0xc2, 0x69, 0xe2, 0x94,
+ 0x8f, 0x98, 0x50, 0x9b, 0xf3, 0x94, 0xf6, 0x77, 0x0d, 0x7e, 0x6f, 0xba,
+ 0x30, 0x87, 0xbf, 0xa1, 0x5d, 0x44, 0xbe, 0x78, 0x72, 0x0e, 0xf2, 0xac,
+ 0xdb, 0x83, 0xd5, 0xe7, 0x06, 0x71, 0xe9, 0x66, 0xb7, 0x8f, 0xe6, 0x65,
+ 0xee, 0xde, 0x97, 0x6d, 0x52, 0xc7, 0x64, 0xec, 0x5e, 0x2d, 0x9a, 0xe1,
+ 0x5a, 0x4d, 0x38, 0x1c, 0x5c, 0x65, 0x8e, 0x97, 0x73, 0x58, 0x35, 0xf0,
+ 0xd1, 0xf7, 0xc7, 0x0c, 0x39, 0xbf, 0x10, 0x0d, 0xef, 0xe0, 0x1a, 0x8e,
+ 0x59, 0x4d, 0xad, 0x71, 0x65, 0x0f, 0xca, 0xfc, 0xdb, 0xe5, 0xd4, 0x5a,
+ 0xdf, 0x51, 0x34, 0xf5, 0x3c, 0x88, 0x2f, 0x21, 0xbd, 0xa4, 0xa9, 0x7f,
+ 0x0a, 0x71, 0xe3, 0x7e, 0xc8, 0x39, 0x4e, 0x77, 0xac, 0x86, 0x3c, 0x33,
+ 0xc9, 0xd2, 0x4f, 0xec, 0x15, 0xfa, 0x53, 0x98, 0x22, 0x77, 0x6c, 0x5c,
+ 0xa7, 0x5f, 0xf8, 0x5a, 0xe9, 0x9e, 0xbb, 0x4f, 0x24, 0xfe, 0x12, 0xa0,
+ 0x0d, 0x2a, 0xe1, 0x5b, 0x5a, 0xcf, 0x39, 0x68, 0x0b, 0xe7, 0x8c, 0xef,
+ 0x45, 0x1c, 0xa4, 0xbf, 0x4d, 0x15, 0x14, 0x18, 0x0d, 0x17, 0x31, 0x24,
+ 0xb9, 0x8b, 0xef, 0xb4, 0x67, 0x43, 0xe4, 0xb2, 0x51, 0x54, 0xea, 0xf1,
+ 0xd8, 0x28, 0xf5, 0x6b, 0x27, 0x96, 0x8f, 0x13, 0x43, 0x32, 0x6a, 0xc8,
+ 0x39, 0x77, 0x5a, 0xa9, 0x47, 0x9d, 0xff, 0x15, 0x90, 0x5a, 0xa8, 0x71,
+ 0x46, 0xf6, 0xa8, 0x0f, 0xe3, 0xe2, 0x54, 0x11, 0xc7, 0x52, 0x69, 0xec,
+ 0x5f, 0xa2, 0x62, 0xd2, 0x5a, 0xe6, 0xf4, 0x0e, 0xa4, 0xe6, 0xea, 0xca,
+ 0x1d, 0x72, 0xfa, 0x91, 0x5b, 0x53, 0x9e, 0x06, 0x39, 0xa7, 0x31, 0xcb,
+ 0xda, 0x6b, 0xca, 0x18, 0xc1, 0x41, 0xe3, 0xcb, 0x30, 0x96, 0x0a, 0x76,
+ 0x8e, 0xe1, 0xd5, 0x19, 0xc9, 0x71, 0xc9, 0xb6, 0x5b, 0x26, 0xc5, 0x3e,
+ 0x1e, 0x72, 0xdf, 0x00, 0x9a, 0x1d, 0x2e, 0xf7, 0x50, 0xdb, 0xea, 0x19,
+ 0x97, 0xd3, 0x35, 0xe7, 0xe5, 0xac, 0x74, 0x0d, 0xc2, 0xb4, 0xd7, 0xf9,
+ 0x94, 0x9f, 0x98, 0x23, 0xf6, 0x94, 0x33, 0x7a, 0xae, 0x9e, 0xc9, 0xbc,
+ 0x82, 0xb1, 0x96, 0x1b, 0xf7, 0x58, 0xe4, 0xff, 0x06, 0xae, 0x9d, 0x1b,
+ 0x2c, 0xf5, 0xc7, 0xff, 0xcc, 0xbe, 0x74, 0x93, 0xe8, 0xbd, 0x22, 0x44,
+ 0x4c, 0x8f, 0xcd, 0x5c, 0xb3, 0xaf, 0xd8, 0xf4, 0x9c, 0xe4, 0x0c, 0xc7,
+ 0xe6, 0x6e, 0xcf, 0x4d, 0x1b, 0xba, 0xac, 0x34, 0x31, 0x9f, 0xd0, 0xaf,
+ 0x96, 0xd0, 0xdf, 0x9a, 0xd1, 0xbf, 0xc2, 0xf4, 0xf5, 0x5e, 0xb5, 0x36,
+ 0xa3, 0x75, 0xfd, 0x7b, 0x36, 0x6e, 0x6e, 0x87, 0x57, 0x97, 0xeb, 0x33,
+ 0x76, 0x5a, 0x95, 0xbf, 0xff, 0x24, 0x24, 0xb9, 0xfe, 0x65, 0xab, 0x68,
+ 0xaf, 0x5e, 0xe6, 0x72, 0xc4, 0x1f, 0x64, 0x65, 0xdf, 0x2b, 0x63, 0xb3,
+ 0xde, 0xbe, 0xf0, 0xae, 0xf7, 0x10, 0xbe, 0x9f, 0x3f, 0x8c, 0x77, 0xa6,
+ 0x7c, 0x08, 0xeb, 0xa2, 0xcb, 0x66, 0xd4, 0xae, 0x4f, 0xa4, 0xdf, 0x23,
+ 0x2e, 0x5e, 0x98, 0x29, 0xfb, 0xc5, 0x43, 0x6d, 0x6b, 0x66, 0x14, 0x8e,
+ 0x55, 0x83, 0x0a, 0xea, 0xf9, 0x1d, 0xc3, 0x8b, 0x58, 0x89, 0xe3, 0x7a,
+ 0x29, 0xa7, 0x9c, 0x7b, 0x10, 0xee, 0x1b, 0xcf, 0x1f, 0x0a, 0xb9, 0x3d,
+ 0xb0, 0x10, 0x71, 0x74, 0x1c, 0x13, 0xd9, 0xa6, 0xe4, 0xfb, 0x72, 0x0e,
+ 0x87, 0x35, 0xd9, 0x25, 0x8c, 0xe3, 0x44, 0xb6, 0x8c, 0xa1, 0x51, 0x39,
+ 0x97, 0x9a, 0x8c, 0x79, 0x5c, 0x8c, 0x8c, 0x79, 0xb4, 0x4c, 0xcc, 0xe3,
+ 0x0f, 0x09, 0x77, 0x18, 0x2d, 0xc4, 0xa3, 0x95, 0xf0, 0xe2, 0x3e, 0xc3,
+ 0xf5, 0x8f, 0x86, 0x39, 0x3f, 0x62, 0x4b, 0x25, 0x2f, 0x4b, 0x4e, 0xf6,
+ 0x31, 0x27, 0x2f, 0x23, 0xbf, 0xf6, 0xe1, 0x4d, 0x5d, 0xec, 0xb1, 0xa6,
+ 0x6c, 0x0f, 0xe3, 0x1c, 0x1e, 0xb6, 0x8b, 0x3d, 0xe2, 0x4b, 0x7e, 0x1c,
+ 0x6e, 0x9e, 0xb5, 0x67, 0x22, 0xa2, 0xbb, 0x17, 0xa7, 0x89, 0xaf, 0xb8,
+ 0x39, 0x1e, 0x3d, 0xcd, 0x9c, 0x3d, 0xa6, 0x97, 0x7d, 0xfc, 0xb7, 0x4b,
+ 0x72, 0xea, 0x7d, 0xf3, 0xb8, 0x9f, 0x7f, 0x37, 0x44, 0xf7, 0x2b, 0xee,
+ 0x7c, 0xab, 0xe7, 0xfe, 0x26, 0x54, 0xee, 0x9f, 0xca, 0xb3, 0xb1, 0xfc,
+ 0xe3, 0xfc, 0x2e, 0x63, 0x85, 0xe8, 0x9f, 0x95, 0xe8, 0x8f, 0xc8, 0xff,
+ 0x89, 0x88, 0x5d, 0x64, 0x3f, 0x11, 0xb4, 0x87, 0x8d, 0xd7, 0x68, 0x8f,
+ 0xc3, 0xd7, 0xce, 0x4c, 0xb9, 0xf8, 0x55, 0xc5, 0xeb, 0x3b, 0x52, 0xaf,
+ 0x6c, 0x0a, 0xe2, 0x17, 0xf6, 0xa5, 0x48, 0x94, 0x98, 0x50, 0xe6, 0xa1,
+ 0x62, 0x33, 0xc3, 0xb1, 0x99, 0x5b, 0x2b, 0x5e, 0xd3, 0xa3, 0x38, 0x40,
+ 0xbe, 0xbd, 0x90, 0x2d, 0x9f, 0x15, 0x89, 0x13, 0x6b, 0x3e, 0x8f, 0xfe,
+ 0x3a, 0x19, 0xaf, 0x9e, 0xfe, 0x95, 0xa4, 0x0d, 0xd4, 0xf0, 0xce, 0x69,
+ 0xa9, 0xb5, 0xc9, 0x8f, 0x27, 0xe3, 0xc6, 0x43, 0xe4, 0x91, 0x13, 0x93,
+ 0xb6, 0xfd, 0x96, 0x81, 0x3b, 0xc3, 0xcc, 0xef, 0x2f, 0x90, 0x4f, 0x90,
+ 0x6f, 0xc4, 0x2a, 0x95, 0xa6, 0xe8, 0x2a, 0xe6, 0xfa, 0x31, 0xd6, 0x0a,
+ 0x4f, 0x13, 0xe3, 0x4e, 0x2f, 0x54, 0xc1, 0x3a, 0x21, 0xfb, 0x82, 0x55,
+ 0x98, 0x7c, 0x26, 0x49, 0xd9, 0x97, 0x72, 0x9c, 0x00, 0xaa, 0xcf, 0xb4,
+ 0xa2, 0xea, 0x94, 0x82, 0x1d, 0x89, 0x56, 0x04, 0xcf, 0xd4, 0x30, 0xff,
+ 0x06, 0x70, 0xa5, 0x85, 0x6b, 0xfc, 0x4c, 0x59, 0x0f, 0x67, 0x8f, 0x14,
+ 0x4f, 0xe6, 0x62, 0xe4, 0xf1, 0x11, 0x2c, 0x58, 0xb2, 0x1f, 0x1c, 0x70,
+ 0xb0, 0xf4, 0xc2, 0x86, 0x7a, 0x67, 0xcf, 0xea, 0xc5, 0x82, 0x1e, 0x3d,
+ 0xab, 0xd4, 0xe0, 0xc7, 0x27, 0x8a, 0x37, 0x57, 0xc2, 0x7e, 0x79, 0x85,
+ 0x99, 0xe8, 0xdb, 0x4b, 0xff, 0x5f, 0xb3, 0x3a, 0xc2, 0xfa, 0xc6, 0xb6,
+ 0xaf, 0x6e, 0x94, 0x3a, 0xd8, 0x70, 0xea, 0x60, 0x77, 0x6f, 0x5f, 0x1f,
+ 0x7c, 0x4c, 0xc9, 0x6c, 0x0f, 0xc3, 0xfe, 0xa8, 0xd2, 0xb4, 0x3f, 0xf6,
+ 0x9b, 0x09, 0xbe, 0x2f, 0x7b, 0x7c, 0xb6, 0xfd, 0xc3, 0x16, 0xdb, 0xce,
+ 0xb7, 0xc4, 0xfb, 0x54, 0xaf, 0x8a, 0x33, 0x8d, 0xb2, 0x2f, 0xe8, 0xc1,
+ 0x8f, 0x13, 0x7a, 0x74, 0x2f, 0x64, 0x0f, 0x9e, 0x78, 0xbf, 0x4c, 0xce,
+ 0x18, 0xd6, 0x87, 0x3b, 0xad, 0xa5, 0x78, 0x61, 0x7e, 0x23, 0xfa, 0xfd,
+ 0x70, 0xce, 0xc5, 0xd8, 0x06, 0xde, 0x5e, 0x01, 0xc9, 0xe1, 0x89, 0xd6,
+ 0xc7, 0x10, 0xc1, 0x7c, 0xe1, 0x30, 0x1e, 0x39, 0x21, 0xf5, 0xd7, 0xea,
+ 0xb6, 0xc0, 0x09, 0xfb, 0x07, 0x51, 0xb3, 0x48, 0x8c, 0xb4, 0xed, 0xaa,
+ 0x8d, 0x4d, 0x51, 0xa6, 0x26, 0xf2, 0x8d, 0x18, 0x79, 0xb3, 0x3e, 0xf8,
+ 0x63, 0x2c, 0xc1, 0xd9, 0xd9, 0xf4, 0xcd, 0xe4, 0xf2, 0x9d, 0xcf, 0x2a,
+ 0xc2, 0xdb, 0x23, 0x78, 0xbe, 0x20, 0x9c, 0x65, 0x6d, 0x5b, 0xd7, 0x89,
+ 0xe5, 0x78, 0x79, 0x3e, 0x82, 0xb3, 0x96, 0x4e, 0xce, 0x04, 0xa5, 0xda,
+ 0xb4, 0x6b, 0x6b, 0x29, 0x6b, 0xb5, 0xd7, 0x8b, 0xed, 0x29, 0xa9, 0x19,
+ 0xf5, 0xc1, 0x90, 0x82, 0xe5, 0x95, 0xd0, 0x17, 0x1f, 0x06, 0x86, 0x82,
+ 0x66, 0xe2, 0xc2, 0xb3, 0x4a, 0xa2, 0xef, 0x03, 0x6f, 0x04, 0xdf, 0x22,
+ 0x16, 0x7d, 0xbd, 0x20, 0x67, 0xa5, 0x88, 0x37, 0xb3, 0x31, 0xae, 0x5b,
+ 0x00, 0x9e, 0x86, 0x1a, 0x1c, 0x61, 0xec, 0xbc, 0x66, 0x54, 0x10, 0xaf,
+ 0xe4, 0xec, 0x94, 0x60, 0x7d, 0xbd, 0x9c, 0x19, 0xb1, 0x5f, 0xd4, 0xdd,
+ 0x7a, 0xdf, 0x98, 0xbb, 0xf1, 0x4c, 0xb1, 0x4a, 0x8c, 0x6f, 0xea, 0x89,
+ 0x2a, 0x6f, 0xd8, 0xe9, 0x2f, 0x2a, 0xd4, 0xb3, 0xb7, 0x06, 0x55, 0x8e,
+ 0xae, 0x18, 0xcd, 0x95, 0xf3, 0x4b, 0xad, 0xd4, 0x77, 0x3d, 0x99, 0x92,
+ 0x3f, 0x56, 0x33, 0xee, 0x8f, 0x32, 0x5f, 0x57, 0x9e, 0x90, 0xbc, 0x42,
+ 0xfe, 0xad, 0x6c, 0x26, 0x2f, 0x16, 0x0e, 0x11, 0xc0, 0x83, 0xaa, 0xf8,
+ 0x86, 0x4a, 0xfd, 0x36, 0xf9, 0xe4, 0x2c, 0xd4, 0x0b, 0x05, 0xc9, 0xeb,
+ 0x82, 0x0b, 0xe5, 0xf9, 0xa2, 0xa8, 0x9b, 0x94, 0x35, 0x52, 0xdb, 0x3e,
+ 0x9a, 0x0c, 0xc9, 0xd9, 0xf7, 0x11, 0x0f, 0xeb, 0xef, 0x00, 0xfd, 0xeb,
+ 0x9e, 0x16, 0x7d, 0x70, 0xb3, 0x57, 0x63, 0x0d, 0x1e, 0x67, 0x2d, 0xa1,
+ 0xb5, 0x4e, 0x28, 0x37, 0x8e, 0xf3, 0x6c, 0x8d, 0xc4, 0x4b, 0x86, 0x7a,
+ 0x3e, 0xe9, 0xe8, 0xb4, 0x86, 0x3a, 0x09, 0x5e, 0x27, 0x89, 0xd7, 0x35,
+ 0xb8, 0x32, 0x05, 0x9d, 0x11, 0x8c, 0x57, 0x0d, 0x02, 0x95, 0x9a, 0x48,
+ 0x77, 0x40, 0x62, 0x41, 0xeb, 0x17, 0x3e, 0x55, 0x4d, 0x7c, 0x9e, 0x9d,
+ 0x92, 0x7c, 0xa3, 0x08, 0x57, 0xc9, 0xd4, 0x9a, 0x43, 0xf8, 0x70, 0x03,
+ 0xf0, 0xc6, 0xa4, 0xbb, 0xef, 0xde, 0x27, 0x67, 0x6f, 0x2b, 0xdd, 0x33,
+ 0x0d, 0x8f, 0x39, 0x67, 0x15, 0x64, 0xfc, 0x43, 0x38, 0x93, 0x15, 0x7e,
+ 0x39, 0x44, 0x7e, 0x19, 0x1f, 0x26, 0xf7, 0x6c, 0x2d, 0x40, 0x62, 0xb2,
+ 0xc9, 0xf8, 0x88, 0xbe, 0xff, 0x2c, 0x79, 0xeb, 0x11, 0xb8, 0xfb, 0xee,
+ 0x8d, 0xa5, 0xb3, 0x08, 0xf1, 0x7c, 0xa7, 0xb2, 0xd3, 0x39, 0xcf, 0x64,
+ 0x30, 0xde, 0x3a, 0x94, 0x1d, 0xf3, 0xdb, 0x94, 0xae, 0xf9, 0x6e, 0x65,
+ 0x4f, 0x41, 0xea, 0xd8, 0xd5, 0x6d, 0x0f, 0x9e, 0xd8, 0xad, 0xec, 0x9c,
+ 0xed, 0x55, 0xc8, 0x6f, 0xd5, 0x80, 0xd9, 0xa7, 0x74, 0xcf, 0xbb, 0xfd,
+ 0xf4, 0x4e, 0xd6, 0x70, 0x3b, 0x2d, 0xf1, 0x07, 0xb5, 0xad, 0x6b, 0x52,
+ 0xfe, 0x17, 0x2b, 0x22, 0xff, 0xf7, 0xd0, 0xbf, 0x55, 0xb1, 0xed, 0x55,
+ 0xa9, 0xd7, 0x65, 0x3d, 0xec, 0xe7, 0x53, 0xcc, 0x93, 0x56, 0x0d, 0x06,
+ 0x58, 0x83, 0x8c, 0x1a, 0xb7, 0x94, 0xf6, 0xcf, 0x44, 0x27, 0x39, 0x2f,
+ 0x21, 0xfe, 0x8a, 0x4c, 0x25, 0x65, 0xf8, 0x07, 0xca, 0xbf, 0xbf, 0xa4,
+ 0x57, 0xb7, 0x9c, 0x27, 0xf0, 0x23, 0x23, 0x3a, 0xe4, 0xa9, 0xef, 0xb1,
+ 0xc9, 0xeb, 0x7a, 0xf9, 0x78, 0x6d, 0x9c, 0x5c, 0x75, 0xbf, 0xa2, 0x0d,
+ 0x3f, 0xe7, 0xea, 0x75, 0xe1, 0x8a, 0xa2, 0x15, 0x47, 0x21, 0xb8, 0xe0,
+ 0xea, 0xb5, 0xb6, 0xa4, 0xd7, 0x9a, 0x7c, 0xa7, 0x73, 0x4e, 0xab, 0x86,
+ 0x7a, 0x2d, 0x4c, 0x76, 0x28, 0x9d, 0xf3, 0xd2, 0xcb, 0x14, 0xdd, 0x44,
+ 0x8f, 0x13, 0x76, 0x95, 0xde, 0xad, 0xdc, 0xee, 0x9c, 0x2b, 0x93, 0xb3,
+ 0x5d, 0xb2, 0xdf, 0x5f, 0xd6, 0x4b, 0x72, 0xfa, 0xd2, 0xf0, 0xb6, 0x69,
+ 0x35, 0xbc, 0x75, 0xda, 0xb6, 0xbf, 0x6b, 0xfc, 0xb3, 0xa3, 0xcb, 0x59,
+ 0x43, 0x74, 0x91, 0x73, 0x23, 0x65, 0x7d, 0xbe, 0x50, 0xd2, 0x47, 0xd6,
+ 0xea, 0xfa, 0x3a, 0x95, 0xff, 0x87, 0xef, 0xdd, 0xac, 0x7b, 0xa6, 0xa4,
+ 0xac, 0x4f, 0xd8, 0x2c, 0x9f, 0x2f, 0x1b, 0xc2, 0x1b, 0xbc, 0xff, 0x93,
+ 0x6c, 0x59, 0x2f, 0x2f, 0xe6, 0x66, 0xc5, 0xfe, 0x43, 0xf2, 0x3f, 0x7c,
+ 0xc4, 0x91, 0xb8, 0x31, 0x46, 0x3f, 0x72, 0xf5, 0xd3, 0x86, 0x57, 0x7a,
+ 0x9b, 0x8a, 0x57, 0xa0, 0xf5, 0x2f, 0x2a, 0x89, 0x34, 0x6b, 0x70, 0x9c,
+ 0x2d, 0xfc, 0xea, 0xfa, 0x35, 0xe7, 0xab, 0x94, 0x6d, 0x39, 0x19, 0xfb,
+ 0x21, 0x8e, 0x2d, 0x67, 0x4a, 0x14, 0x3c, 0x37, 0x0b, 0xcc, 0x5a, 0x9c,
+ 0xd6, 0x1c, 0xc1, 0xd3, 0x86, 0x6d, 0x3f, 0xdb, 0xa2, 0xcb, 0x59, 0xa0,
+ 0xf3, 0x6e, 0xaf, 0x08, 0x46, 0x8d, 0x2e, 0x7b, 0x79, 0x72, 0x9e, 0xa4,
+ 0x97, 0x36, 0x10, 0xdd, 0xc5, 0x07, 0xca, 0x6b, 0x2f, 0xe7, 0xdc, 0x32,
+ 0xb4, 0x8f, 0xd8, 0xa6, 0x7c, 0xde, 0x4d, 0xfa, 0x30, 0x37, 0xda, 0x64,
+ 0x6d, 0xd8, 0x59, 0x5f, 0x43, 0xfc, 0x95, 0xe8, 0x43, 0x5f, 0x9d, 0x23,
+ 0x97, 0x18, 0x33, 0xfc, 0x0e, 0x6f, 0x3b, 0x42, 0xae, 0x32, 0xc1, 0xd8,
+ 0x79, 0xd2, 0xba, 0x80, 0x0b, 0xf9, 0xd7, 0xf0, 0xc6, 0xb5, 0xff, 0x67,
+ 0x13, 0x7f, 0xb9, 0xb8, 0xb1, 0xcb, 0x39, 0xd3, 0x74, 0xba, 0xf5, 0x96,
+ 0x84, 0xe0, 0x50, 0x77, 0xb3, 0x9c, 0x71, 0xaa, 0x34, 0xf3, 0x9b, 0x64,
+ 0xbf, 0xab, 0xc2, 0x34, 0x6f, 0x3d, 0xaf, 0x8b, 0x6d, 0xfe, 0x62, 0xfd,
+ 0x19, 0x5d, 0xf4, 0xfa, 0x9f, 0x6b, 0xc7, 0x9d, 0xff, 0xaf, 0xfc, 0xbb,
+ 0x5b, 0xf7, 0xe9, 0x12, 0x3b, 0x67, 0x5b, 0xda, 0x1d, 0x4c, 0x68, 0x35,
+ 0x57, 0x39, 0x36, 0x68, 0x31, 0x6f, 0x71, 0x3e, 0x0d, 0x33, 0xe9, 0x7c,
+ 0x9a, 0xa6, 0x6b, 0x9b, 0x6e, 0xb3, 0xc1, 0xf9, 0xec, 0x30, 0xdd, 0xf3,
+ 0xcf, 0x69, 0x53, 0x77, 0x3e, 0x7b, 0xcc, 0xb8, 0xf3, 0xd9, 0x69, 0xae,
+ 0xbc, 0x2e, 0x17, 0x7f, 0xfe, 0x1f, 0x9b, 0x97, 0x53, 0xd9, 0x78, 0x3a,
0x00, 0x00, 0x00 };
static const u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
static struct fw_info bnx2_txp_fw_06 = {
- /* Firmware version: 4.4.2 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x2,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
.start_addr = 0x08000098,
.text_addr = 0x08000000,
- .text_len = 0x3ab0,
+ .text_len = 0x3a74,
.text_index = 0x0,
.gz_text = bnx2_TXP_b06FwText,
.gz_text_len = sizeof(bnx2_TXP_b06FwText),
@@ -4535,11 +4432,11 @@ static struct fw_info bnx2_txp_fw_06 = {
.data_index = 0x0,
.data = bnx2_TXP_b06FwData,
- .sbss_addr = 0x08003ae0,
+ .sbss_addr = 0x08003aa0,
.sbss_len = 0x68,
.sbss_index = 0x0,
- .bss_addr = 0x08003b48,
+ .bss_addr = 0x08003b08,
.bss_len = 0x14c,
.bss_index = 0x0,
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
index fe753b6bcb4..c54e4886b8b 100644
--- a/drivers/net/bnx2_fw2.h
+++ b/drivers/net/bnx2_fw2.h
@@ -15,848 +15,847 @@
*/
static u8 bnx2_COM_b09FwText[] = {
- 0xcd, 0x7c, 0x7f, 0x6c, 0x5c, 0xd7, 0x75, 0xe6, 0x79, 0x6f, 0xde, 0x90,
- 0x43, 0x8a, 0xa2, 0x1e, 0x99, 0x31, 0x33, 0x8e, 0xd8, 0x7a, 0x86, 0xf3,
- 0x48, 0xd1, 0x21, 0xe3, 0x3e, 0x33, 0x63, 0x99, 0x76, 0xa6, 0xd6, 0x64,
- 0x66, 0x28, 0x2b, 0x0e, 0x69, 0xd0, 0x8e, 0x82, 0x4d, 0x01, 0x03, 0xe5,
- 0x0e, 0xa9, 0x54, 0xd9, 0xf5, 0x22, 0xda, 0x34, 0x45, 0x8a, 0xa2, 0x88,
- 0x26, 0x24, 0xe5, 0x2a, 0xcd, 0x88, 0x1c, 0xcb, 0x34, 0x1b, 0x14, 0x5e,
- 0x64, 0x3c, 0xa4, 0x14, 0xb7, 0x1d, 0x89, 0x72, 0xe2, 0x2d, 0xbc, 0x58,
- 0x07, 0x66, 0xa9, 0x1f, 0x4e, 0x83, 0x14, 0xf0, 0x2e, 0xbc, 0x68, 0x60,
- 0xa4, 0x80, 0x20, 0xbb, 0x8d, 0xb3, 0xc8, 0x62, 0x83, 0xdd, 0x00, 0x71,
- 0x02, 0x27, 0x6f, 0xbf, 0xef, 0xde, 0xfb, 0xc8, 0xd1, 0x88, 0x76, 0xd2,
- 0xfc, 0xb5, 0x04, 0x06, 0xf7, 0xfd, 0xb8, 0x3f, 0xce, 0x3d, 0xf7, 0xdc,
- 0x73, 0xbe, 0x73, 0xee, 0x79, 0x7c, 0x40, 0xa4, 0x53, 0xcc, 0xdf, 0x5e,
- 0xfc, 0x32, 0xff, 0xe1, 0xb3, 0xb3, 0x63, 0x77, 0x65, 0xee, 0xc2, 0xe5,
- 0x87, 0xed, 0xf7, 0x3b, 0x0e, 0x9f, 0x47, 0xf0, 0x8b, 0xe3, 0x37, 0x66,
- 0xae, 0x77, 0xfb, 0x73, 0xf1, 0x3b, 0x68, 0x89, 0xcc, 0xfc, 0x4f, 0x11,
- 0xab, 0xe5, 0x5d, 0xec, 0x5d, 0xda, 0xbc, 0xd7, 0x9f, 0xfd, 0x1b, 0xb4,
- 0xf9, 0xd7, 0xfe, 0x45, 0x34, 0xd9, 0x6a, 0xde, 0xfc, 0x49, 0xcc, 0xce,
- 0xce, 0x4c, 0xe6, 0x3d, 0x89, 0x45, 0xb2, 0x47, 0xa7, 0x66, 0x3d, 0x91,
- 0x5c, 0x63, 0x24, 0x59, 0x90, 0x5f, 0x04, 0xe5, 0xb8, 0x23, 0x7c, 0xfe,
- 0x5b, 0xd9, 0x77, 0xbe, 0xf6, 0xad, 0x7b, 0x53, 0x3f, 0xae, 0x45, 0x24,
- 0xe6, 0x66, 0xdf, 0x16, 0x77, 0x48, 0x62, 0xfd, 0x68, 0xf3, 0xcc, 0x81,
- 0x57, 0x6d, 0xe9, 0x0e, 0xfb, 0x72, 0x67, 0x22, 0x59, 0x99, 0x3e, 0x56,
- 0x39, 0x19, 0xd8, 0x9e, 0x94, 0x9d, 0xac, 0x37, 0x5c, 0x97, 0xae, 0xf1,
- 0x73, 0x99, 0x7b, 0x05, 0xf7, 0xd3, 0xc7, 0x1a, 0x31, 0x99, 0x6f, 0x94,
- 0xbb, 0x6c, 0xcf, 0x43, 0x29, 0xb1, 0xb6, 0xec, 0x62, 0xec, 0x9a, 0xc7,
- 0xb1, 0xbf, 0x8a, 0xb1, 0xf7, 0x4b, 0xd4, 0x0b, 0x82, 0x73, 0x18, 0xfb,
- 0x70, 0xe3, 0x17, 0xc1, 0xb3, 0x8e, 0x1e, 0xd7, 0xce, 0x9e, 0x88, 0xb0,
- 0xb4, 0xb2, 0xb5, 0xc9, 0x81, 0x06, 0xef, 0x8b, 0xed, 0x9a, 0x4e, 0xbf,
- 0x13, 0x74, 0xc6, 0x9c, 0xec, 0x89, 0xce, 0x45, 0x94, 0xd1, 0x6c, 0x7c,
- 0xec, 0x9c, 0xaa, 0xb7, 0x6e, 0xea, 0x3d, 0x1e, 0xd5, 0xed, 0xde, 0x9a,
- 0x1c, 0x6a, 0xb0, 0xfc, 0xc9, 0xe4, 0xa0, 0x2a, 0xdf, 0x99, 0x4c, 0xab,
- 0x52, 0xa6, 0x06, 0x54, 0xe9, 0x4c, 0x79, 0xaa, 0x7c, 0xc6, 0x3c, 0x7f,
- 0x6e, 0x32, 0xa9, 0xca, 0x86, 0x29, 0x2f, 0x99, 0xf2, 0x05, 0x53, 0xbe,
- 0x68, 0xca, 0x97, 0x4c, 0xb9, 0x69, 0xca, 0x2b, 0x93, 0xba, 0x9f, 0x6f,
- 0x9b, 0xfb, 0xef, 0x9a, 0xf2, 0x55, 0x53, 0xbe, 0x66, 0xca, 0xef, 0x99,
- 0xf2, 0xfb, 0x86, 0xae, 0xeb, 0xa6, 0x7c, 0xd3, 0x94, 0x3f, 0x32, 0xef,
- 0x7f, 0x6c, 0xe8, 0x7d, 0x1b, 0x74, 0xfd, 0x49, 0xd4, 0xc8, 0x2a, 0xe6,
- 0x9d, 0x94, 0xd9, 0x8a, 0x23, 0xf3, 0xcb, 0x11, 0x29, 0xa8, 0x35, 0xfc,
- 0xca, 0x5e, 0xe9, 0x74, 0x64, 0x61, 0x23, 0x26, 0xd7, 0x95, 0x88, 0xbe,
- 0x15, 0x7c, 0xeb, 0x80, 0x94, 0xed, 0xac, 0x2b, 0x97, 0x36, 0xe2, 0xf2,
- 0xf2, 0x86, 0x58, 0xd3, 0x99, 0x0e, 0xb1, 0xcf, 0x7e, 0x40, 0x72, 0xae,
- 0x25, 0x11, 0xc5, 0xd3, 0xa4, 0xe4, 0x2b, 0x7d, 0xb8, 0x4f, 0x25, 0x44,
- 0xae, 0xee, 0xd5, 0xeb, 0x17, 0x93, 0xc8, 0x2a, 0xd7, 0xe4, 0xfe, 0xa9,
- 0x6b, 0x2b, 0x09, 0x71, 0x96, 0x46, 0x31, 0x46, 0x97, 0x44, 0x57, 0xa5,
- 0x3f, 0x22, 0x83, 0x89, 0x4f, 0xa3, 0x46, 0xb1, 0xe1, 0xc8, 0x44, 0xc3,
- 0x12, 0xc7, 0x8b, 0x41, 0x3e, 0xba, 0xf0, 0x73, 0xf1, 0x8b, 0xe3, 0x97,
- 0xc0, 0xef, 0x47, 0xe8, 0xa7, 0x5f, 0x0a, 0x0d, 0xf6, 0x89, 0x71, 0x97,
- 0x31, 0xfe, 0x72, 0xca, 0x9d, 0x11, 0xd2, 0x95, 0x90, 0x6f, 0x1d, 0x20,
- 0x5d, 0x2e, 0xe9, 0x01, 0x6d, 0x31, 0x2b, 0xbf, 0x22, 0x27, 0x0a, 0xbe,
- 0x24, 0x6d, 0xaf, 0x53, 0x4a, 0xae, 0x95, 0x9c, 0x1b, 0xee, 0x95, 0xf2,
- 0x51, 0xbc, 0x5f, 0x96, 0x9c, 0x8d, 0xfe, 0x4b, 0xae, 0xcc, 0xe8, 0x77,
- 0x7c, 0xf6, 0x36, 0xf6, 0x6a, 0xca, 0xa5, 0xd0, 0xbe, 0xbc, 0xfc, 0xb7,
- 0xb8, 0x66, 0x7f, 0x3f, 0x77, 0x34, 0xdd, 0x3f, 0xc5, 0x3d, 0x9f, 0x0f,
- 0x99, 0x79, 0xf0, 0x9a, 0x75, 0xc3, 0x71, 0xc3, 0xf9, 0x72, 0xfc, 0x61,
- 0xcc, 0x99, 0x34, 0x84, 0x73, 0x96, 0x72, 0x14, 0xb4, 0xd4, 0x57, 0xba,
- 0xac, 0xb5, 0x95, 0x51, 0x79, 0x62, 0xf9, 0x01, 0xc9, 0xfb, 0x41, 0x30,
- 0xeb, 0x4b, 0xdc, 0x96, 0x41, 0xb7, 0x80, 0x0a, 0x5b, 0x0d, 0xb1, 0xea,
- 0x15, 0x89, 0xb5, 0x83, 0x2f, 0x3f, 0x58, 0x61, 0xdf, 0x0e, 0x9e, 0xf5,
- 0xa1, 0x7e, 0xb7, 0xb5, 0xbe, 0x02, 0xfa, 0xb3, 0xe4, 0x4f, 0x10, 0x2c,
- 0xfa, 0x83, 0x89, 0x39, 0x8c, 0x79, 0xb9, 0x31, 0x38, 0x7e, 0x43, 0x5c,
- 0xf4, 0xd9, 0x8b, 0x3a, 0xe4, 0x15, 0xfb, 0x62, 0x9f, 0xec, 0xaf, 0x0b,
- 0x6d, 0xe3, 0x78, 0x47, 0xba, 0x82, 0x20, 0xef, 0xbb, 0xbc, 0x97, 0x4d,
- 0xf0, 0x6f, 0x93, 0xfc, 0xeb, 0xec, 0x97, 0x57, 0x1a, 0x1c, 0x63, 0x37,
- 0xda, 0x47, 0xfe, 0x3f, 0xa4, 0x3d, 0x81, 0xfe, 0xe3, 0x28, 0xf7, 0x58,
- 0xf5, 0x6a, 0x80, 0xf1, 0x13, 0xb8, 0xde, 0x6d, 0x1e, 0xd7, 0xd5, 0xda,
- 0x5f, 0xc2, 0xda, 0xbb, 0xd9, 0xb8, 0x3c, 0xbf, 0xd1, 0x8f, 0x79, 0x24,
- 0xe4, 0x1b, 0x90, 0xcd, 0x9e, 0x83, 0x7b, 0x24, 0x0d, 0xd9, 0xe4, 0x9a,
- 0x8f, 0xad, 0xce, 0x49, 0x29, 0x9e, 0x1a, 0xa6, 0x1e, 0xcd, 0x8f, 0xed,
- 0xc3, 0x7c, 0xb5, 0xb6, 0x1a, 0x58, 0xca, 0xed, 0xb7, 0xe5, 0x90, 0xd8,
- 0x59, 0x8c, 0x9b, 0x19, 0x01, 0x2d, 0x11, 0xbc, 0x8b, 0x8b, 0xb7, 0x9a,
- 0xc3, 0xb3, 0x54, 0xa2, 0x04, 0x1a, 0xe7, 0x41, 0x63, 0x49, 0xca, 0x62,
- 0x5f, 0x7c, 0xce, 0x0a, 0xf7, 0x8a, 0xe6, 0xdd, 0xb0, 0xe9, 0x67, 0x5b,
- 0xce, 0x2d, 0x7b, 0xb5, 0xcb, 0x8a, 0xac, 0x8e, 0xca, 0xa9, 0x5d, 0x78,
- 0x56, 0x07, 0xcf, 0xec, 0xa5, 0x70, 0x1f, 0x38, 0xb8, 0xef, 0x43, 0xdd,
- 0x6e, 0xcb, 0x59, 0xbd, 0x95, 0x5f, 0x6b, 0x8d, 0x41, 0x7f, 0x0b, 0xfc,
- 0xb2, 0x57, 0x7b, 0x51, 0xe7, 0x56, 0x7e, 0xd5, 0xc1, 0x2f, 0x7b, 0x55,
- 0xf3, 0xaa, 0x0e, 0x5e, 0xd9, 0x4b, 0x71, 0x94, 0x7b, 0x2c, 0xfb, 0xac,
- 0xe6, 0x55, 0xdd, 0xec, 0x99, 0xf3, 0x4a, 0x5f, 0xe5, 0x40, 0xab, 0x25,
- 0x5a, 0x67, 0xe5, 0x84, 0xba, 0x29, 0x92, 0x2d, 0x62, 0xaf, 0xdb, 0xe0,
- 0x85, 0x23, 0xc5, 0x31, 0x4b, 0x66, 0xd5, 0xbb, 0xa2, 0xa4, 0x1b, 0x1f,
- 0x00, 0x23, 0x47, 0x86, 0x61, 0x29, 0xca, 0x6d, 0xd9, 0x17, 0xed, 0xad,
- 0x4a, 0x4c, 0x0a, 0x4e, 0x52, 0xbc, 0x25, 0xa5, 0xc7, 0x9b, 0xfa, 0x99,
- 0x41, 0x3f, 0xdf, 0x01, 0x3f, 0x2c, 0xe8, 0x56, 0xbe, 0x7b, 0x4c, 0xed,
- 0xfb, 0xf4, 0xaa, 0x23, 0x83, 0x4b, 0xac, 0x53, 0xb6, 0xaf, 0x34, 0xde,
- 0x09, 0x74, 0xbf, 0x8f, 0x71, 0x4c, 0xd7, 0xce, 0x2e, 0xda, 0x97, 0xd7,
- 0x4f, 0xdb, 0x57, 0x1b, 0xe8, 0xb7, 0xc1, 0xb5, 0xc0, 0x5a, 0x2d, 0x63,
- 0xad, 0x96, 0xb1, 0x6e, 0x66, 0x4f, 0xd7, 0xd4, 0xde, 0x4a, 0x9a, 0x75,
- 0x25, 0x0d, 0x5c, 0xdb, 0x04, 0xd6, 0x94, 0x6b, 0x2b, 0xd6, 0xab, 0x99,
- 0x3d, 0x12, 0x39, 0x1b, 0x51, 0x6b, 0xda, 0xb3, 0xfa, 0x91, 0xed, 0x35,
- 0x1d, 0x68, 0x5a, 0x53, 0xfb, 0x5d, 0xd6, 0xd4, 0xd9, 0x65, 0x4d, 0xb7,
- 0x1a, 0x3f, 0x31, 0x6b, 0xfa, 0x73, 0x31, 0xb2, 0xff, 0x9e, 0xfc, 0x1a,
- 0x00, 0xbf, 0xbc, 0x5f, 0x83, 0x5f, 0xce, 0xae, 0xfc, 0xea, 0xb3, 0x5b,
- 0xf9, 0x15, 0x01, 0xbf, 0xa2, 0xbf, 0x36, 0xbf, 0xc0, 0x87, 0x5d, 0x79,
- 0x15, 0x83, 0xde, 0x2b, 0x4b, 0x3e, 0x23, 0x92, 0xaf, 0x6a, 0x5d, 0x5d,
- 0x56, 0x3a, 0x9b, 0xba, 0x2a, 0xd4, 0xd9, 0xd4, 0xd7, 0x6a, 0x9f, 0x58,
- 0x85, 0x4a, 0x12, 0xba, 0xd4, 0x41, 0xf9, 0x1c, 0xca, 0x3d, 0xd6, 0x74,
- 0xb5, 0x1f, 0x76, 0x36, 0x10, 0x77, 0x2c, 0xb4, 0x97, 0xe5, 0x84, 0x8b,
- 0xb5, 0x71, 0xef, 0x8a, 0x8a, 0xf4, 0xa5, 0xc0, 0xa7, 0x14, 0xde, 0xa7,
- 0x12, 0x39, 0xc9, 0xda, 0x21, 0xae, 0xc9, 0x57, 0x3a, 0xde, 0xce, 0xa9,
- 0x2b, 0x3e, 0x67, 0xbb, 0x0c, 0x9e, 0x45, 0x65, 0x06, 0x76, 0xa0, 0xe8,
- 0x71, 0x3c, 0xf6, 0x9f, 0x9c, 0xe1, 0xb8, 0x85, 0x46, 0xa8, 0xb3, 0x25,
- 0x07, 0x1b, 0x8e, 0x77, 0xdc, 0xb7, 0xe3, 0x56, 0x41, 0xd9, 0xa0, 0x8c,
- 0x78, 0x8d, 0x66, 0xfb, 0xb2, 0x4d, 0x27, 0xf6, 0x73, 0x0e, 0x72, 0x4d,
- 0xda, 0x92, 0xd8, 0x7b, 0xc7, 0x22, 0xe1, 0xfa, 0x38, 0xd9, 0x71, 0x81,
- 0x5d, 0x96, 0xf9, 0x0a, 0xfb, 0xfb, 0x63, 0x2b, 0x72, 0x31, 0xec, 0x9f,
- 0x7c, 0x64, 0xdf, 0xba, 0xbf, 0xf9, 0xc6, 0x5b, 0x46, 0x37, 0x28, 0x5b,
- 0x85, 0xfe, 0xca, 0x4d, 0xfd, 0x95, 0xad, 0xc8, 0x92, 0xec, 0x53, 0xf6,
- 0xe0, 0x28, 0xf9, 0x77, 0x1a, 0xef, 0xae, 0x4b, 0x84, 0x32, 0xa3, 0xf6,
- 0x18, 0xf7, 0xfb, 0x97, 0x38, 0xdf, 0x26, 0xde, 0x4e, 0xc3, 0xc6, 0x71,
- 0x7f, 0x61, 0x8d, 0xe3, 0x7c, 0x7e, 0xc8, 0xd0, 0xe4, 0x48, 0x4e, 0xdd,
- 0x7f, 0x63, 0x4f, 0xa8, 0x3f, 0xb1, 0x9f, 0x41, 0xdb, 0x8b, 0x6a, 0x8e,
- 0x76, 0x36, 0x0b, 0xde, 0x34, 0xd3, 0xc8, 0x79, 0x67, 0xb1, 0xc6, 0xa1,
- 0x0e, 0x0b, 0xd7, 0x8a, 0xb8, 0xc6, 0xb1, 0x16, 0x2a, 0x5d, 0xb0, 0x8f,
- 0x31, 0x63, 0x83, 0xd9, 0x7e, 0x11, 0xed, 0xf9, 0x9c, 0x6d, 0xbb, 0x60,
- 0x8f, 0xd9, 0x7e, 0xd1, 0xb4, 0xdf, 0xb1, 0xcb, 0xdc, 0x2b, 0xb4, 0xc9,
- 0x57, 0x32, 0xc0, 0x42, 0x2b, 0xb6, 0x14, 0x7c, 0xe0, 0x1c, 0xbf, 0xdf,
- 0xec, 0x0b, 0x2d, 0x9b, 0x1f, 0x75, 0x2c, 0x69, 0xf7, 0x76, 0x93, 0xcd,
- 0x7f, 0xb0, 0xb5, 0xad, 0xdb, 0x91, 0xcd, 0x05, 0xe8, 0xa8, 0x53, 0x90,
- 0x95, 0xc5, 0xed, 0x7a, 0x94, 0x4b, 0x25, 0xa3, 0x90, 0xcd, 0xd4, 0x38,
- 0xa7, 0x79, 0xa5, 0xd1, 0x2c, 0xa3, 0x61, 0x1f, 0x31, 0x25, 0x07, 0x7a,
- 0x9c, 0xc5, 0xa6, 0x71, 0x16, 0x9b, 0xc6, 0x59, 0x32, 0xd8, 0x8e, 0xfd,
- 0x68, 0xbb, 0x7a, 0xfd, 0x26, 0x7b, 0xce, 0x35, 0xfb, 0x24, 0xf6, 0xa4,
- 0x96, 0x05, 0x60, 0x35, 0xbd, 0x06, 0x15, 0x57, 0xe6, 0x37, 0x2e, 0x84,
- 0x7b, 0xb5, 0xdc, 0x8e, 0xe7, 0x3f, 0xc4, 0xf3, 0xe1, 0x33, 0x2e, 0xec,
- 0x14, 0xb1, 0xda, 0x4b, 0x72, 0xae, 0x42, 0x19, 0x79, 0x11, 0x74, 0xa7,
- 0xfd, 0x36, 0x8b, 0x7c, 0x4d, 0x0d, 0x9f, 0x97, 0x54, 0x72, 0x5e, 0x46,
- 0x7c, 0x96, 0x4f, 0x88, 0xc2, 0x58, 0xa2, 0x31, 0xd0, 0x8b, 0x90, 0x3f,
- 0x91, 0x1f, 0x57, 0xda, 0xc5, 0x1e, 0xfb, 0x61, 0x40, 0x3b, 0x78, 0x7a,
- 0xa3, 0xb5, 0x1f, 0x91, 0xa1, 0x33, 0xaa, 0x1f, 0xf4, 0x91, 0xf6, 0xbf,
- 0xad, 0xfa, 0x0b, 0xfb, 0xc2, 0x3c, 0xc7, 0x5a, 0xfb, 0x73, 0xe4, 0xba,
- 0x6b, 0xa3, 0xbf, 0xb4, 0x99, 0x23, 0xaf, 0x21, 0x23, 0xae, 0x83, 0xf2,
- 0x61, 0x3b, 0x94, 0x19, 0x7b, 0xec, 0x3b, 0x41, 0x6e, 0x9a, 0x73, 0x2b,
- 0x99, 0x67, 0xff, 0xc3, 0xc8, 0x9b, 0x54, 0xed, 0x2c, 0x78, 0x96, 0x19,
- 0xc4, 0x78, 0xbc, 0x4f, 0x02, 0x1f, 0x49, 0x99, 0xf8, 0xac, 0x54, 0xf9,
- 0x65, 0x90, 0x73, 0x34, 0xa6, 0xd2, 0x6b, 0xcf, 0xf7, 0x96, 0x14, 0x50,
- 0x77, 0xc1, 0xe8, 0x83, 0x62, 0xe3, 0xba, 0xe2, 0xdf, 0xf3, 0x6a, 0x1f,
- 0xa5, 0x4e, 0x97, 0xa9, 0x37, 0x36, 0xdc, 0x08, 0xf7, 0xf8, 0x25, 0xff,
- 0xa5, 0x60, 0x61, 0x39, 0x95, 0x4c, 0xda, 0x83, 0x52, 0xaa, 0x0e, 0x96,
- 0x6d, 0x94, 0x27, 0x6a, 0x09, 0x39, 0x51, 0x61, 0x3f, 0xfb, 0x51, 0x07,
- 0x8a, 0xc8, 0xc6, 0x26, 0xef, 0xa3, 0xae, 0xe1, 0x98, 0x6f, 0x5b, 0x7a,
- 0x4c, 0xcc, 0xc1, 0xdb, 0xb4, 0xfe, 0x63, 0xe3, 0x8a, 0x55, 0xaa, 0x71,
- 0xfd, 0xf1, 0xbc, 0xd1, 0xac, 0x8f, 0x42, 0x5d, 0xb4, 0x83, 0xc5, 0x22,
- 0xd9, 0x45, 0xab, 0xb4, 0x22, 0x76, 0xde, 0x8f, 0x12, 0x0f, 0x26, 0x45,
- 0xee, 0x75, 0xf5, 0x3c, 0x3f, 0x19, 0xa1, 0x1e, 0x74, 0xbc, 0xd3, 0xe8,
- 0xbb, 0x53, 0x72, 0x0e, 0xd7, 0x9f, 0xd7, 0x12, 0x44, 0xb2, 0x1e, 0x6d,
- 0xa5, 0x13, 0xc9, 0x3a, 0xd8, 0x63, 0xac, 0xf3, 0x52, 0xc0, 0xbd, 0x90,
- 0xaf, 0x6a, 0x19, 0x29, 0xef, 0x60, 0x2f, 0xd0, 0x9b, 0x83, 0x8e, 0x11,
- 0x1b, 0x7b, 0xcc, 0x8d, 0x64, 0xf9, 0x7c, 0x1c, 0xd7, 0x9b, 0xa8, 0x4f,
- 0x1d, 0x0b, 0x4c, 0x5a, 0x53, 0xbc, 0xc3, 0x58, 0x39, 0xab, 0x58, 0x09,
- 0x79, 0xf2, 0x52, 0xf0, 0xe4, 0x72, 0x88, 0x11, 0x94, 0x6c, 0xc9, 0xc0,
- 0xd9, 0xa4, 0xd9, 0xd7, 0x5d, 0xdc, 0x73, 0xe4, 0x3f, 0x9e, 0xf9, 0xe6,
- 0x59, 0x7b, 0xd3, 0xb3, 0x70, 0xff, 0x7f, 0x09, 0xb4, 0xf5, 0x2b, 0xfe,
- 0xd8, 0xd9, 0x23, 0x56, 0x5e, 0xe1, 0x93, 0x20, 0x28, 0x78, 0x51, 0x29,
- 0x8d, 0xfe, 0x09, 0xe6, 0xca, 0x77, 0x65, 0x30, 0x9c, 0x76, 0x63, 0x78,
- 0x72, 0xd6, 0x4b, 0x29, 0xfb, 0x9f, 0xc7, 0xfe, 0xd3, 0x3a, 0x53, 0xca,
- 0x3d, 0xa0, 0xdd, 0x5b, 0xe2, 0x9a, 0xbc, 0x14, 0x9c, 0x05, 0x16, 0x9e,
- 0x5e, 0x2a, 0x5a, 0x03, 0xd8, 0x12, 0x76, 0x9f, 0x05, 0x3e, 0x77, 0x49,
- 0xfe, 0x22, 0xd7, 0x82, 0x75, 0xf8, 0xbc, 0x4d, 0xa6, 0xe3, 0xad, 0xb6,
- 0xf2, 0xdc, 0x3e, 0xe9, 0x24, 0xbf, 0x51, 0x77, 0xe9, 0xff, 0x46, 0xb4,
- 0x5e, 0x76, 0x65, 0x60, 0x95, 0x7c, 0x2f, 0x5a, 0xb3, 0x15, 0xea, 0xb1,
- 0x0e, 0xd8, 0x47, 0x3e, 0x67, 0x9f, 0x78, 0x77, 0xbe, 0xb5, 0x8f, 0xdf,
- 0x8b, 0xe8, 0x3e, 0xd8, 0x2e, 0xec, 0xa3, 0x99, 0x1f, 0x7b, 0x94, 0x9e,
- 0xeb, 0xcd, 0xf6, 0xb6, 0xf4, 0x9b, 0x68, 0xea, 0x17, 0xef, 0xce, 0x7f,
- 0x37, 0x42, 0x5c, 0xf6, 0xf2, 0x32, 0xf8, 0xac, 0xe6, 0xc4, 0x77, 0x6c,
- 0x53, 0xb4, 0x0a, 0x4b, 0x41, 0x30, 0xed, 0xdb, 0x12, 0xe9, 0x0b, 0xeb,
- 0xea, 0x79, 0x15, 0x31, 0xaf, 0x3c, 0xe6, 0x65, 0xf7, 0xb5, 0xd2, 0xf4,
- 0xfb, 0x86, 0xa6, 0xde, 0x26, 0x9a, 0xe2, 0xef, 0x31, 0xaf, 0xf8, 0x2e,
- 0xf3, 0x7a, 0xa9, 0x57, 0xf7, 0x11, 0x6f, 0xea, 0xa3, 0xaf, 0xa5, 0x0f,
- 0xe8, 0xfd, 0x38, 0xdb, 0xf7, 0xed, 0xd2, 0xfe, 0x87, 0x1d, 0xba, 0x3d,
- 0xdb, 0xb4, 0x41, 0xb7, 0xf7, 0x1b, 0xbd, 0x78, 0xa2, 0x49, 0x97, 0x9d,
- 0x80, 0x2e, 0x6b, 0x6e, 0xd3, 0x2c, 0xff, 0xa1, 0x8f, 0x44, 0xff, 0x28,
- 0xc4, 0x8a, 0x1f, 0x50, 0x18, 0x64, 0x07, 0x63, 0xc7, 0x80, 0x47, 0xba,
- 0x60, 0xff, 0xbb, 0xe9, 0x07, 0x19, 0x4c, 0x48, 0xbf, 0x88, 0x38, 0x50,
- 0x3c, 0xa0, 0x28, 0xe8, 0x96, 0xc1, 0xc4, 0x31, 0x11, 0xe5, 0x07, 0x11,
- 0x5f, 0xd3, 0x27, 0xe2, 0x38, 0xf4, 0x89, 0xb8, 0xee, 0xbc, 0x2f, 0x6c,
- 0xfb, 0x48, 0xfd, 0xd8, 0xf7, 0xc4, 0xc7, 0xdc, 0x33, 0xa1, 0xad, 0x69,
- 0xd6, 0xa7, 0xbb, 0xd1, 0xd4, 0xdf, 0x42, 0x13, 0x74, 0x12, 0x7c, 0xb3,
- 0x05, 0xc8, 0x23, 0x30, 0x29, 0x74, 0xe0, 0xfd, 0x53, 0xe7, 0x56, 0x44,
- 0x4a, 0x0d, 0xda, 0xc7, 0x51, 0x81, 0x5f, 0x05, 0xba, 0xd8, 0xb7, 0xb2,
- 0x91, 0xd0, 0x4d, 0xdd, 0x39, 0x3b, 0x3b, 0x08, 0x3f, 0xdc, 0x91, 0x39,
- 0x43, 0xdb, 0x8c, 0xf2, 0xe1, 0xba, 0x50, 0x26, 0x94, 0x5c, 0xcd, 0x80,
- 0x3e, 0x5e, 0xcf, 0x18, 0xec, 0x7e, 0xac, 0xd1, 0x4a, 0xdb, 0xf7, 0x40,
- 0x9b, 0x07, 0x1a, 0x92, 0xf2, 0x02, 0xb0, 0xfb, 0x37, 0xd5, 0xbe, 0x0c,
- 0x75, 0x17, 0x65, 0x29, 0x55, 0x2d, 0xcb, 0x66, 0xb0, 0xb2, 0xcc, 0x7d,
- 0x4b, 0x1b, 0xde, 0x25, 0x65, 0xac, 0xd7, 0xc0, 0x52, 0x2a, 0x99, 0xb3,
- 0xc5, 0x7a, 0xdf, 0x41, 0xca, 0xd3, 0xe3, 0x32, 0x70, 0x51, 0x2c, 0x67,
- 0x09, 0x7b, 0xbd, 0x3b, 0xc4, 0x57, 0x9c, 0xdf, 0x6f, 0x63, 0x7e, 0xe8,
- 0x7b, 0x39, 0x9c, 0x5f, 0x97, 0x94, 0x56, 0x39, 0xbf, 0xed, 0xb9, 0xc5,
- 0x19, 0x11, 0xf9, 0x1c, 0xf4, 0x35, 0xe6, 0x08, 0x1a, 0xc7, 0x81, 0x73,
- 0xef, 0x30, 0x73, 0xea, 0xc2, 0x9c, 0x60, 0xa3, 0x97, 0xd8, 0x1e, 0x74,
- 0x81, 0xe6, 0x12, 0xea, 0xcd, 0x2f, 0x71, 0xcd, 0x41, 0x2b, 0xd6, 0xbd,
- 0xd4, 0xe0, 0xda, 0x73, 0x6e, 0xda, 0xae, 0x3b, 0x1e, 0xe7, 0xc7, 0x79,
- 0x0e, 0x63, 0x5e, 0xac, 0xc3, 0x76, 0xad, 0x32, 0x32, 0xfc, 0x1e, 0xeb,
- 0xf1, 0xdb, 0x2d, 0xeb, 0x21, 0x66, 0x3d, 0x62, 0xd2, 0xb6, 0xaa, 0xfc,
- 0x65, 0x45, 0x03, 0x7d, 0x08, 0x07, 0xf4, 0x2f, 0xae, 0xc8, 0x68, 0x54,
- 0x48, 0x7b, 0x82, 0xcf, 0x32, 0x6d, 0x32, 0xe8, 0x5f, 0x81, 0x5c, 0x95,
- 0x20, 0x0b, 0xf4, 0x07, 0x5e, 0x5e, 0xd6, 0x6b, 0x51, 0x6a, 0x74, 0xc2,
- 0x47, 0xe7, 0xf8, 0xe4, 0x37, 0xe7, 0xe6, 0xaa, 0x75, 0x68, 0x5e, 0x97,
- 0x4f, 0xdf, 0xb2, 0x2e, 0xd4, 0xbb, 0xd4, 0x03, 0xc4, 0x3d, 0xd4, 0x05,
- 0x61, 0x4c, 0xa0, 0xe6, 0xea, 0xfd, 0x14, 0xda, 0x9f, 0xeb, 0xdb, 0xf8,
- 0x52, 0xaf, 0x59, 0xc2, 0xc4, 0x05, 0xba, 0xc4, 0x5e, 0xbd, 0x83, 0x7a,
- 0x1f, 0xf6, 0x27, 0x9c, 0xdf, 0xef, 0xe0, 0x3e, 0x71, 0xd3, 0x7a, 0xd8,
- 0x98, 0x93, 0xa3, 0xe6, 0xa8, 0xd6, 0x62, 0x5b, 0xe6, 0xe6, 0x1a, 0x7a,
- 0x5e, 0xce, 0xd2, 0x1e, 0xb3, 0x1e, 0x31, 0x3c, 0xe3, 0xbc, 0x42, 0x9b,
- 0xc3, 0x79, 0x91, 0x5e, 0xd7, 0xc8, 0x1c, 0xe7, 0xc3, 0xfd, 0xd7, 0x2c,
- 0x6b, 0x2f, 0x05, 0xd5, 0xe5, 0xa8, 0x9a, 0x7b, 0xde, 0xef, 0x26, 0x46,
- 0xa3, 0x8e, 0x34, 0xfa, 0x89, 0xcf, 0x69, 0x07, 0xf1, 0x2e, 0x43, 0x19,
- 0xc2, 0x7d, 0x9d, 0xf7, 0xcd, 0x36, 0xed, 0x79, 0x47, 0xeb, 0x01, 0xc6,
- 0x9f, 0xde, 0xdb, 0xd6, 0x45, 0xb3, 0x62, 0xad, 0x57, 0xe8, 0x33, 0x07,
- 0xc0, 0x5d, 0x77, 0x40, 0xaf, 0x1c, 0x92, 0x92, 0x0b, 0x7b, 0x3d, 0x7c,
- 0x3b, 0xe6, 0x3c, 0x2e, 0x2a, 0xde, 0x30, 0xbc, 0x17, 0xd7, 0x7b, 0x94,
- 0xef, 0x52, 0x1a, 0xfe, 0x90, 0xe4, 0xa6, 0x69, 0xd3, 0x7e, 0x5f, 0x66,
- 0x60, 0x5b, 0x4b, 0xc3, 0x77, 0x82, 0x3e, 0xde, 0x43, 0x27, 0x7a, 0x43,
- 0x8c, 0x51, 0xe0, 0xef, 0x71, 0x13, 0x9b, 0x39, 0x80, 0xfb, 0x3d, 0xa8,
- 0xf3, 0x49, 0x53, 0xa7, 0x1b, 0x75, 0x06, 0x5b, 0xea, 0x70, 0xbc, 0xfb,
- 0x50, 0x07, 0xf6, 0x14, 0x56, 0xd2, 0xf6, 0x0e, 0xe2, 0x37, 0x81, 0x67,
- 0xf7, 0xe2, 0xd9, 0x3d, 0x78, 0x76, 0x0f, 0xee, 0x7f, 0xd7, 0xc4, 0x3c,
- 0xc2, 0x36, 0xdd, 0xb8, 0xff, 0x12, 0xde, 0x43, 0xc7, 0xb9, 0xdf, 0xc6,
- 0xfb, 0xfb, 0xf0, 0x1b, 0x6b, 0xa9, 0xe3, 0xb6, 0xdc, 0x9f, 0x76, 0x74,
- 0x8c, 0x84, 0xcf, 0x82, 0xc8, 0xce, 0xf5, 0x7f, 0x35, 0xcf, 0xbd, 0xa6,
- 0xf7, 0x1f, 0x37, 0xd7, 0xad, 0xb2, 0x94, 0x86, 0x2c, 0xf1, 0xfd, 0x57,
- 0xf6, 0xe9, 0xb5, 0xb8, 0x43, 0xc7, 0x1f, 0x6e, 0xc2, 0x1b, 0x4a, 0xfc,
- 0x71, 0xbd, 0x09, 0x9c, 0x41, 0xec, 0xd1, 0x8c, 0x3b, 0x48, 0x8b, 0xab,
- 0xe4, 0xf5, 0xe5, 0xe5, 0xd7, 0xba, 0xf5, 0x18, 0x62, 0xd5, 0x21, 0x73,
- 0x13, 0x2a, 0x16, 0xf1, 0x33, 0xf3, 0xcc, 0xdb, 0xb7, 0xf3, 0x6e, 0xaf,
- 0x4c, 0x54, 0xff, 0x68, 0xdf, 0x0e, 0x6d, 0x93, 0x4d, 0xd7, 0x3b, 0x98,
- 0x02, 0xfe, 0x84, 0xbd, 0x83, 0x77, 0x72, 0xf6, 0x5c, 0xa3, 0x68, 0xeb,
- 0x71, 0x59, 0x07, 0xef, 0x1a, 0x9b, 0x3d, 0x8e, 0x92, 0xfd, 0x9c, 0x4d,
- 0x5f, 0xa3, 0xbc, 0xc6, 0xeb, 0xdb, 0x51, 0x36, 0xb7, 0xed, 0x87, 0x1e,
- 0xcf, 0xd9, 0x9a, 0xee, 0xd6, 0xf6, 0xe1, 0xbe, 0xf1, 0x65, 0xa1, 0x0a,
- 0x99, 0xf3, 0x52, 0xc3, 0x65, 0xac, 0xdd, 0xac, 0x9f, 0x9a, 0xa6, 0x4c,
- 0xc2, 0x9f, 0xfd, 0x94, 0xc8, 0xa4, 0xcc, 0x57, 0x1f, 0x06, 0xfe, 0x0e,
- 0xe4, 0x21, 0xe0, 0x8a, 0x7f, 0x0f, 0x5c, 0x52, 0x83, 0xac, 0xd7, 0x1a,
- 0x1e, 0x7e, 0xfd, 0xf2, 0x57, 0x95, 0x84, 0x3c, 0x07, 0x7f, 0x02, 0xb2,
- 0x06, 0x3d, 0x9c, 0x76, 0x1f, 0x12, 0xe9, 0xb1, 0xe5, 0xf2, 0xbd, 0xb6,
- 0x8c, 0x24, 0x07, 0xac, 0x74, 0x02, 0x3f, 0xb7, 0x0d, 0xbf, 0x22, 0x7c,
- 0xb8, 0xb5, 0x06, 0x63, 0x01, 0x71, 0xf9, 0xeb, 0xf5, 0x24, 0x7e, 0x7d,
- 0xf2, 0x37, 0xeb, 0x1c, 0x7f, 0xc0, 0x94, 0x6a, 0x1f, 0xc3, 0xe7, 0x28,
- 0xcb, 0x62, 0x26, 0x21, 0x0b, 0x95, 0xe0, 0xa4, 0xf6, 0x99, 0x3d, 0xf8,
- 0xc8, 0xdc, 0xb3, 0x2f, 0x60, 0xcf, 0xe2, 0xb9, 0xc2, 0x9e, 0xa1, 0xdd,
- 0x7b, 0x01, 0x76, 0x2f, 0x5c, 0x23, 0xce, 0xb3, 0x75, 0x7d, 0xd8, 0x2f,
- 0xd7, 0x88, 0x7a, 0x9d, 0xba, 0x3c, 0x06, 0xfc, 0x10, 0xea, 0x76, 0xea,
- 0x08, 0x6f, 0xdb, 0x0f, 0x7d, 0xe4, 0x60, 0x17, 0xb0, 0x86, 0xc4, 0xe2,
- 0xd9, 0x9f, 0xca, 0xca, 0x59, 0xee, 0x1b, 0xda, 0xe3, 0xbb, 0x21, 0x6f,
- 0xa9, 0xaf, 0x96, 0x89, 0x99, 0xbd, 0x0c, 0xf8, 0x51, 0x96, 0xe9, 0x83,
- 0xab, 0xbd, 0x5a, 0x4e, 0x26, 0xc5, 0x39, 0xfb, 0x85, 0xa8, 0x74, 0x9f,
- 0x94, 0x45, 0x1f, 0x7e, 0xa9, 0x5d, 0x0e, 0x22, 0x9e, 0x97, 0x28, 0x28,
- 0xbf, 0x69, 0x05, 0x74, 0xc6, 0x64, 0xe2, 0x2c, 0xeb, 0x9c, 0x84, 0x8c,
- 0xb5, 0x81, 0xe6, 0x76, 0x39, 0x15, 0x4f, 0x95, 0x0b, 0xf0, 0xf7, 0x6d,
- 0xaf, 0x47, 0x06, 0xea, 0x2c, 0x89, 0x41, 0xfe, 0x37, 0xe4, 0x87, 0xd7,
- 0xf0, 0x03, 0x57, 0xf9, 0x7c, 0x00, 0x25, 0x9f, 0x7b, 0xd0, 0x2f, 0xe4,
- 0x07, 0x70, 0xc3, 0xc5, 0xb2, 0x9c, 0xca, 0x4c, 0x4a, 0xbd, 0x2a, 0xd6,
- 0x42, 0x06, 0x7b, 0xa0, 0x96, 0x95, 0x3a, 0x78, 0x51, 0x6a, 0x1c, 0x87,
- 0xdf, 0xf9, 0x26, 0xca, 0x39, 0x94, 0xd7, 0x51, 0x3e, 0x8e, 0xf2, 0x2d,
- 0x94, 0xa4, 0xfd, 0xb8, 0xd4, 0x6b, 0x7b, 0xda, 0xa4, 0x93, 0x7d, 0x6c,
- 0x18, 0x9a, 0xe1, 0x3b, 0x1e, 0x3c, 0x0e, 0x2c, 0x1a, 0x3e, 0x3f, 0x2e,
- 0x52, 0xff, 0x0c, 0x7e, 0x0f, 0xaa, 0x7b, 0xfa, 0x96, 0x0b, 0x99, 0x71,
- 0xe0, 0x7a, 0xb1, 0x4e, 0x65, 0x1e, 0x37, 0xfd, 0x7c, 0x06, 0xe3, 0x5d,
- 0xc5, 0xd8, 0x31, 0xc8, 0x48, 0x20, 0x8f, 0xf8, 0x27, 0xe5, 0x73, 0xfe,
- 0x7e, 0x19, 0xeb, 0x8d, 0x95, 0x63, 0x59, 0xce, 0x9f, 0x7a, 0x6a, 0xb7,
- 0xf9, 0x87, 0xf3, 0xe6, 0x9c, 0xa1, 0x5b, 0x97, 0xf6, 0x6a, 0xdc, 0x6d,
- 0x7f, 0x39, 0xaa, 0x69, 0xb1, 0x64, 0x60, 0x88, 0xfd, 0x65, 0x25, 0x72,
- 0x76, 0xc8, 0xcd, 0xd8, 0x23, 0xf0, 0x52, 0xd2, 0xf8, 0x9d, 0x84, 0xfc,
- 0x79, 0xa7, 0x07, 0xec, 0xdb, 0x40, 0x13, 0xde, 0xd5, 0x39, 0x0e, 0xec,
- 0xe9, 0x3d, 0xaf, 0x62, 0x6e, 0x65, 0x69, 0xbf, 0x27, 0x2b, 0x37, 0x1a,
- 0xbc, 0x86, 0x3d, 0xba, 0x30, 0x29, 0xff, 0x5c, 0xbd, 0x2a, 0x4f, 0x54,
- 0x27, 0xe5, 0x0d, 0x94, 0x8b, 0xd5, 0x32, 0xf8, 0xc8, 0x58, 0x3c, 0xfb,
- 0x08, 0xb0, 0x2e, 0x83, 0xf0, 0x8d, 0x3e, 0x98, 0x98, 0xc3, 0xfa, 0xcd,
- 0xb8, 0x81, 0x9c, 0xf3, 0xcb, 0x72, 0x6e, 0x1c, 0x6d, 0x6a, 0x1d, 0x12,
- 0x7d, 0x96, 0xf3, 0xed, 0x96, 0x02, 0x2c, 0x7a, 0x31, 0x43, 0x9d, 0xd9,
- 0x29, 0x85, 0x5a, 0xab, 0xdc, 0x51, 0xde, 0xde, 0xb6, 0xea, 0xdb, 0x3a,
- 0x60, 0xd3, 0xfa, 0x66, 0x83, 0x36, 0x78, 0x37, 0x7b, 0xaa, 0xe5, 0xae,
- 0x5e, 0xa3, 0x4d, 0xdd, 0x91, 0xbd, 0x3a, 0xfc, 0xb9, 0x7a, 0xf5, 0xba,
- 0x91, 0x3f, 0x25, 0xb7, 0x58, 0x17, 0x62, 0xf1, 0x9f, 0x08, 0xb0, 0x1f,
- 0x78, 0x14, 0xc6, 0x09, 0xb5, 0x7f, 0x54, 0x03, 0xad, 0x85, 0x38, 0x71,
- 0x06, 0xac, 0x5b, 0xed, 0x0b, 0x8a, 0x57, 0xde, 0xd9, 0x7e, 0xa9, 0x2e,
- 0x93, 0xbf, 0x29, 0xd7, 0xb6, 0x95, 0x4f, 0x02, 0xbe, 0x7a, 0x58, 0x9f,
- 0xf0, 0x7d, 0x0a, 0x7e, 0xd2, 0x49, 0x71, 0xc7, 0x3a, 0x31, 0x27, 0x5e,
- 0x8b, 0x4c, 0x5f, 0x6c, 0xc5, 0x91, 0xa1, 0x9d, 0x68, 0x83, 0x3f, 0x1e,
- 0xc5, 0x5a, 0x76, 0xc1, 0x9f, 0x86, 0x9f, 0x0a, 0x39, 0xfa, 0x33, 0x60,
- 0xaf, 0xd3, 0xca, 0xb7, 0xe6, 0x9e, 0xea, 0x9e, 0x1a, 0x58, 0x67, 0xb9,
- 0x77, 0x2a, 0x5d, 0x63, 0x19, 0x9f, 0xd2, 0xbe, 0x64, 0x62, 0x4a, 0xc7,
- 0xed, 0x93, 0x53, 0x07, 0x54, 0xe9, 0x4d, 0x0d, 0xab, 0x72, 0x78, 0x6a,
- 0x27, 0x66, 0x42, 0x9e, 0x8a, 0x95, 0xcf, 0x64, 0xa4, 0x58, 0x21, 0x8d,
- 0xe2, 0x1c, 0x83, 0x3c, 0xcd, 0x01, 0xcb, 0xe4, 0x2b, 0xbe, 0x9c, 0xda,
- 0xc8, 0x82, 0x66, 0xe8, 0x99, 0xac, 0x8f, 0x52, 0xcc, 0x5f, 0xd8, 0xb6,
- 0x8d, 0x31, 0x32, 0xae, 0x99, 0xf1, 0x33, 0x7d, 0xfa, 0x99, 0xcd, 0x7f,
- 0xec, 0x0f, 0xb2, 0x49, 0xfb, 0xf9, 0x0b, 0xf8, 0xc6, 0xe2, 0x94, 0x32,
- 0x6c, 0xeb, 0xc3, 0x07, 0x17, 0xd9, 0x5a, 0x91, 0x58, 0x2c, 0xfb, 0x1d,
- 0x89, 0x3d, 0x1d, 0x04, 0x3f, 0xf0, 0x53, 0x47, 0xca, 0x02, 0x5e, 0x59,
- 0x78, 0xbe, 0xce, 0x77, 0xd4, 0x4d, 0x23, 0xee, 0x0d, 0xc8, 0x5c, 0xee,
- 0xa8, 0xc8, 0x2b, 0x78, 0x56, 0x5f, 0xe1, 0x1a, 0x7c, 0x17, 0x6b, 0x60,
- 0xd6, 0x44, 0x3d, 0x63, 0x3d, 0xf8, 0x58, 0x71, 0xce, 0x63, 0xc4, 0x6d,
- 0x47, 0xfb, 0xda, 0x3a, 0xdb, 0xa4, 0xc6, 0x79, 0xe4, 0xf5, 0xca, 0xba,
- 0x9e, 0xdf, 0xe1, 0xcc, 0xb0, 0x5c, 0xae, 0xa8, 0x3e, 0x20, 0xeb, 0xbf,
- 0x44, 0x9b, 0x4d, 0xc8, 0x2d, 0x63, 0x53, 0x59, 0x99, 0x07, 0x4e, 0x9b,
- 0xaf, 0xa4, 0x21, 0x3b, 0x8e, 0xcc, 0x24, 0x48, 0xb6, 0x27, 0x5b, 0x95,
- 0x37, 0xdb, 0x88, 0x85, 0xf3, 0x1e, 0xaf, 0xc7, 0x51, 0x67, 0x5a, 0x88,
- 0xb7, 0xf2, 0x19, 0xce, 0xa9, 0x99, 0x17, 0xfa, 0xaf, 0x84, 0xb5, 0x30,
- 0x73, 0x54, 0x7f, 0x7a, 0x1c, 0xb4, 0x37, 0xe3, 0x14, 0x01, 0x53, 0xe0,
- 0x6b, 0x4a, 0xfa, 0x82, 0xe3, 0xe4, 0x2b, 0x8e, 0x0c, 0x5c, 0xc0, 0xb6,
- 0xca, 0x1a, 0x5e, 0x34, 0x42, 0x59, 0x0b, 0x31, 0x10, 0x65, 0x8b, 0x3c,
- 0x48, 0x95, 0x37, 0xc1, 0xec, 0xde, 0xec, 0x35, 0x79, 0x74, 0x55, 0xcf,
- 0xd9, 0x3e, 0x2f, 0x3c, 0x0b, 0x91, 0x1b, 0x2b, 0x29, 0xff, 0x3a, 0xf4,
- 0x7d, 0x21, 0xee, 0x43, 0x56, 0xfe, 0x4b, 0x1b, 0xf6, 0xf4, 0x78, 0xce,
- 0xde, 0xdf, 0xae, 0x6d, 0xac, 0x83, 0x3d, 0x01, 0xac, 0x59, 0xc9, 0xa1,
- 0x4d, 0xbb, 0xfc, 0x5b, 0x07, 0xd7, 0xc4, 0x9e, 0x78, 0x66, 0xec, 0x22,
- 0xae, 0x75, 0x7f, 0xf3, 0x98, 0x87, 0x8e, 0x03, 0x5b, 0xf2, 0x28, 0x2c,
- 0x88, 0xa0, 0xff, 0x01, 0x33, 0xd6, 0xc0, 0xf9, 0x50, 0x36, 0x40, 0xf7,
- 0x6a, 0x16, 0xf8, 0xdd, 0x31, 0x7e, 0x2b, 0x75, 0x8c, 0xec, 0xe2, 0xf7,
- 0x34, 0xc7, 0x5e, 0x63, 0x2a, 0x4e, 0x47, 0x2c, 0x47, 0xd9, 0x3a, 0x62,
- 0x64, 0xeb, 0x33, 0x90, 0xad, 0xe3, 0x4a, 0xb6, 0x02, 0xf9, 0x81, 0xef,
- 0xcb, 0x97, 0x77, 0x95, 0xaf, 0xd6, 0xbf, 0x2e, 0xd0, 0xcb, 0x5f, 0x9f,
- 0x2c, 0xfc, 0x05, 0xc6, 0xbd, 0xe0, 0xe2, 0x3a, 0x95, 0x9b, 0x11, 0xf2,
- 0x31, 0x81, 0xeb, 0x18, 0xca, 0x7e, 0x55, 0x67, 0xe0, 0x02, 0xec, 0x1a,
- 0xe4, 0x8d, 0xfc, 0x9d, 0x87, 0x8d, 0x1b, 0xb8, 0x10, 0x85, 0x2d, 0xe4,
- 0x9e, 0x95, 0x5e, 0x1b, 0xba, 0x81, 0xf5, 0xeb, 0xd8, 0x3b, 0x03, 0x17,
- 0xba, 0x50, 0x26, 0x55, 0x5f, 0xf5, 0x8a, 0xa7, 0xda, 0xd7, 0x2b, 0xc3,
- 0xaa, 0x5d, 0xbd, 0x32, 0x8a, 0x12, 0xfa, 0x3d, 0xe3, 0xcb, 0xd0, 0x85,
- 0x8c, 0x24, 0x2f, 0x58, 0x52, 0x9a, 0x0e, 0x82, 0x18, 0x68, 0x1f, 0xbe,
- 0xd0, 0x23, 0xd7, 0xa7, 0x39, 0x37, 0xea, 0x62, 0xb1, 0x16, 0x33, 0xd3,
- 0xd8, 0x9b, 0xe4, 0x1f, 0xb0, 0xfe, 0x85, 0x22, 0x6c, 0x6e, 0x51, 0x4e,
- 0xad, 0x90, 0x3f, 0x8c, 0xb5, 0x6f, 0x25, 0x22, 0x92, 0x82, 0x2e, 0x3b,
- 0x2a, 0x73, 0xd5, 0x76, 0xe8, 0x32, 0xc7, 0xad, 0xcb, 0x13, 0x58, 0xa3,
- 0x41, 0xca, 0x03, 0xf8, 0x92, 0x45, 0xdf, 0x45, 0x29, 0xa0, 0x4d, 0x71,
- 0x65, 0xa7, 0x7e, 0x49, 0xda, 0xb1, 0xa7, 0x8e, 0xca, 0xb1, 0x2a, 0xfb,
- 0x71, 0xdc, 0x79, 0x39, 0x00, 0x19, 0xf2, 0xdc, 0x09, 0xf4, 0x03, 0x1b,
- 0xd9, 0xf4, 0xc7, 0xfd, 0x97, 0x7b, 0x0f, 0x99, 0x0c, 0xf7, 0x5d, 0xac,
- 0xdc, 0x96, 0x9d, 0xb6, 0xb6, 0x32, 0xe2, 0xcc, 0x66, 0x1e, 0xb2, 0x5e,
- 0xc9, 0x64, 0xac, 0x2b, 0x99, 0x9c, 0x75, 0x35, 0x53, 0xb4, 0xae, 0xc1,
- 0x36, 0xd5, 0x37, 0xde, 0x81, 0xfc, 0x00, 0x4f, 0x10, 0x7b, 0x6f, 0xaf,
- 0x61, 0xdc, 0xf8, 0x39, 0x6f, 0xc9, 0xb9, 0x0a, 0xed, 0x74, 0x70, 0x68,
- 0xd6, 0x2f, 0xdf, 0x0e, 0xfa, 0x40, 0x07, 0xe3, 0x11, 0x3b, 0xb6, 0x23,
- 0x9a, 0x1d, 0x06, 0x4e, 0xa0, 0xed, 0xe8, 0xa2, 0xed, 0xf0, 0x0b, 0xb2,
- 0x57, 0xb6, 0xaa, 0x3a, 0x2e, 0x97, 0x07, 0x6e, 0xda, 0xaa, 0xc5, 0xe5,
- 0xcb, 0xcb, 0xa1, 0x2c, 0x71, 0xbe, 0xf3, 0xef, 0xeb, 0x90, 0x88, 0x1c,
- 0x51, 0xf6, 0xba, 0x5b, 0x2e, 0xaf, 0x03, 0xd3, 0x02, 0x81, 0xd8, 0x77,
- 0x32, 0xce, 0x63, 0xab, 0xf8, 0x85, 0xf4, 0xf0, 0x3c, 0xf0, 0x1f, 0xc0,
- 0x2b, 0x9e, 0xd9, 0x61, 0x9e, 0x3d, 0x9c, 0x51, 0x78, 0x3f, 0x8a, 0x3d,
- 0xc9, 0x6b, 0x4b, 0x0a, 0xc0, 0xed, 0x5b, 0x15, 0x96, 0x09, 0x94, 0x26,
- 0x56, 0x0f, 0x5d, 0x10, 0xc9, 0xfe, 0xa3, 0x7a, 0xdf, 0xee, 0x89, 0x35,
- 0x0b, 0x3b, 0x5c, 0x5a, 0xa1, 0x4c, 0xa3, 0x5c, 0xd7, 0x63, 0x17, 0x7c,
- 0x60, 0xe6, 0xd1, 0x0e, 0xda, 0x37, 0xe0, 0x27, 0xec, 0x7b, 0x85, 0xed,
- 0x33, 0xd8, 0x73, 0x3f, 0x68, 0xa7, 0x6d, 0x3f, 0xec, 0x8f, 0xcb, 0xb5,
- 0x0a, 0xaf, 0xf9, 0x3e, 0xe5, 0x8b, 0x8a, 0x1b, 0xc7, 0xa6, 0x16, 0x3d,
- 0xdf, 0xec, 0x31, 0x15, 0xd3, 0xb1, 0x3e, 0x06, 0xcc, 0x38, 0x70, 0xa6,
- 0x4d, 0xd2, 0x4f, 0xdb, 0x7d, 0xfa, 0x7c, 0xe5, 0x90, 0x14, 0xfd, 0x03,
- 0x98, 0xc3, 0x3e, 0x99, 0x87, 0x2f, 0xb6, 0xb0, 0x31, 0x2c, 0xf3, 0xc3,
- 0xf0, 0xb9, 0xdd, 0xbb, 0x89, 0xd5, 0xf0, 0xeb, 0xc0, 0xf3, 0x41, 0x94,
- 0xed, 0x28, 0x6f, 0x97, 0xf9, 0xa7, 0xba, 0x63, 0xba, 0xbf, 0x68, 0xcb,
- 0xfd, 0xb3, 0x1c, 0x3b, 0x99, 0xb4, 0x7e, 0x15, 0x2e, 0x6c, 0xc6, 0x84,
- 0xa4, 0x23, 0x2a, 0xde, 0x93, 0x5d, 0x32, 0x78, 0xc6, 0x95, 0xa1, 0x33,
- 0x09, 0x39, 0x70, 0xa6, 0x5f, 0x86, 0xcf, 0x24, 0xe5, 0xce, 0x33, 0x21,
- 0xfe, 0xea, 0x9e, 0x4a, 0x1b, 0x5b, 0xe1, 0xfd, 0x9a, 0xb6, 0xe2, 0xce,
- 0x86, 0xc6, 0xa8, 0xf3, 0x6b, 0xc4, 0x74, 0xaf, 0x62, 0xef, 0x6e, 0xaa,
- 0xf3, 0xca, 0x4b, 0x1b, 0x41, 0x70, 0xc9, 0x6f, 0x77, 0xa7, 0x85, 0xfc,
- 0xce, 0x00, 0x9f, 0xf9, 0xd0, 0x61, 0xa3, 0xd0, 0x61, 0xe3, 0xca, 0x36,
- 0xd6, 0xbf, 0x2e, 0xd6, 0xb1, 0xcc, 0x03, 0xb2, 0x06, 0xd9, 0x7e, 0xd0,
- 0x4f, 0x7d, 0x75, 0x53, 0xf1, 0x47, 0x62, 0x3d, 0xd0, 0x67, 0x77, 0xaf,
- 0xb6, 0xcb, 0x1b, 0xf1, 0x20, 0x38, 0x0b, 0x1d, 0x50, 0xaf, 0x68, 0xf9,
- 0xcd, 0x7b, 0xd4, 0x05, 0x0f, 0x61, 0xfe, 0xa3, 0x78, 0x96, 0x33, 0xba,
- 0xbd, 0x43, 0x6e, 0xc4, 0x13, 0xb2, 0x7e, 0x60, 0xbc, 0xa5, 0x5e, 0x06,
- 0xf7, 0xc0, 0x3d, 0x8d, 0xdf, 0x23, 0xbf, 0xf0, 0xdc, 0x95, 0x73, 0xf0,
- 0x99, 0xcf, 0x1f, 0x48, 0x8d, 0x27, 0x6d, 0xea, 0xc3, 0xa4, 0xd4, 0xbe,
- 0x9e, 0x90, 0xb5, 0x65, 0x6d, 0x97, 0x66, 0xbd, 0x71, 0x29, 0x00, 0xfb,
- 0xae, 0x2d, 0x67, 0x51, 0xb2, 0x7e, 0xa8, 0x73, 0xb4, 0x5c, 0x16, 0x33,
- 0x79, 0xec, 0x63, 0xee, 0x0f, 0x6d, 0x77, 0x6c, 0xbb, 0x1d, 0x72, 0xc4,
- 0x3d, 0xf1, 0x30, 0x9e, 0xe7, 0xb1, 0xaf, 0x69, 0xc7, 0xd3, 0x90, 0xaf,
- 0xcf, 0xc6, 0x28, 0x1f, 0x05, 0x9f, 0xf8, 0x9a, 0x6d, 0x52, 0x89, 0x34,
- 0x9e, 0x4f, 0x4b, 0x5a, 0x9d, 0x0b, 0xcd, 0xfa, 0x61, 0x7f, 0x59, 0xa3,
- 0x17, 0x22, 0x8c, 0x81, 0xe1, 0xef, 0x64, 0x8c, 0xf2, 0x18, 0xf1, 0xc2,
- 0xe7, 0x23, 0xb0, 0x3d, 0x51, 0x35, 0xc6, 0xfc, 0x32, 0x9f, 0xa5, 0x5d,
- 0xb6, 0x2f, 0xf8, 0xbc, 0x17, 0xf9, 0x44, 0x83, 0xf1, 0x9a, 0x98, 0x3c,
- 0xda, 0xe8, 0x02, 0xbd, 0x6d, 0xbf, 0xc2, 0xf6, 0xec, 0xec, 0x73, 0x3b,
- 0xbb, 0x95, 0x70, 0x95, 0x6e, 0xa1, 0x1e, 0xa1, 0x0e, 0x69, 0x17, 0x67,
- 0x8c, 0xfb, 0x0c, 0x6b, 0xb2, 0x8c, 0x35, 0x5a, 0xc6, 0x1a, 0x2d, 0x63,
- 0x8d, 0x96, 0xb1, 0x7e, 0xcb, 0xd4, 0x2d, 0x83, 0xd8, 0xcf, 0x39, 0x73,
- 0x86, 0x40, 0xfd, 0xf2, 0x1c, 0xd6, 0x76, 0x5a, 0xfe, 0x76, 0x63, 0x52,
- 0xfe, 0xf3, 0xc6, 0x11, 0xe0, 0xee, 0x22, 0xd6, 0x35, 0x87, 0x75, 0xcd,
- 0x62, 0x5d, 0x8f, 0x62, 0x5d, 0xc7, 0x55, 0xcc, 0xb3, 0x5a, 0x49, 0x5d,
- 0x2a, 0x2b, 0x8c, 0xff, 0x16, 0xe4, 0x61, 0x4c, 0x9c, 0xd5, 0x7e, 0xe8,
- 0x8b, 0x72, 0x10, 0xf7, 0x82, 0x43, 0xc0, 0xd6, 0x18, 0xbb, 0x9c, 0x72,
- 0x94, 0xee, 0xf3, 0xdc, 0xcf, 0x63, 0xaf, 0xbc, 0x2f, 0x9b, 0xaa, 0x52,
- 0x75, 0x9d, 0xab, 0x0e, 0x4b, 0xe9, 0x22, 0xea, 0x9f, 0xed, 0x02, 0xad,
- 0xc4, 0x7c, 0xa9, 0xd3, 0x25, 0xd9, 0x84, 0xbe, 0xcb, 0x81, 0xc6, 0x0f,
- 0xc9, 0x7c, 0x3c, 0xf5, 0x9c, 0xc8, 0xb8, 0xdc, 0x03, 0x3f, 0x9d, 0xf1,
- 0xcc, 0x9c, 0x8a, 0xb1, 0xe1, 0xfa, 0x62, 0x16, 0xfe, 0x36, 0x6d, 0xec,
- 0x3e, 0xe3, 0x87, 0x6b, 0x1c, 0x5b, 0x13, 0x8e, 0xcb, 0xf1, 0xfe, 0x58,
- 0xe6, 0x80, 0x15, 0xe1, 0xeb, 0x03, 0x8b, 0x78, 0x09, 0x8c, 0x19, 0x9b,
- 0xbd, 0xe8, 0xc6, 0xe6, 0x2e, 0xb2, 0x9f, 0x98, 0x44, 0x96, 0xa8, 0xb3,
- 0xd8, 0x0f, 0x74, 0x3b, 0xfa, 0x4e, 0xab, 0x33, 0xb3, 0x11, 0xb4, 0xfb,
- 0x5d, 0xe0, 0x4c, 0xcd, 0xc7, 0xfc, 0x59, 0x6d, 0xf7, 0xf2, 0xf5, 0x66,
- 0xac, 0x07, 0xdd, 0x02, 0xbb, 0x98, 0xab, 0x6b, 0xdc, 0x56, 0x54, 0xb8,
- 0x4e, 0x63, 0xba, 0xa3, 0x72, 0xa8, 0x43, 0x3a, 0x3d, 0x35, 0x9f, 0xc8,
- 0xd9, 0x4d, 0xe2, 0x58, 0x8c, 0xc1, 0x36, 0xd1, 0x26, 0xba, 0x33, 0xb0,
- 0xa7, 0xb7, 0x77, 0x50, 0x66, 0x3e, 0x09, 0xdc, 0x38, 0xb0, 0xa4, 0xcf,
- 0x98, 0x06, 0x2e, 0xfa, 0x98, 0x8f, 0xf4, 0x31, 0xb2, 0x69, 0x63, 0x0e,
- 0x1f, 0x55, 0x76, 0x79, 0x0c, 0xb6, 0xd8, 0x85, 0xac, 0x53, 0xe7, 0xf4,
- 0x61, 0xff, 0xf0, 0x9e, 0xba, 0x87, 0x7a, 0x8c, 0x32, 0x13, 0x07, 0x6e,
- 0x82, 0xfe, 0xe9, 0xee, 0x97, 0xda, 0x06, 0xdf, 0xf5, 0x2b, 0x1d, 0xed,
- 0x60, 0x0d, 0x16, 0x2b, 0xc1, 0xa1, 0xbc, 0x5f, 0x86, 0x16, 0x25, 0xcf,
- 0xc9, 0x0f, 0xf2, 0x7d, 0x14, 0xb4, 0x91, 0xc7, 0xdd, 0x65, 0x7d, 0x6e,
- 0xb9, 0x57, 0x4a, 0x55, 0xea, 0x69, 0x94, 0xb5, 0xbd, 0xf0, 0x9d, 0x5c,
- 0x85, 0x65, 0x73, 0xd3, 0x9c, 0x7b, 0xac, 0xec, 0x42, 0x6e, 0xdd, 0x83,
- 0x93, 0x2a, 0xa6, 0x72, 0x79, 0x29, 0xe5, 0xd7, 0x6c, 0x8c, 0x09, 0x9d,
- 0x69, 0x9f, 0x1f, 0x93, 0xb9, 0x95, 0x6e, 0x19, 0x5c, 0xe5, 0xf9, 0xf2,
- 0x50, 0x4c, 0xba, 0x83, 0xe0, 0x9c, 0x9f, 0x57, 0xb1, 0xc7, 0x81, 0x55,
- 0x60, 0x82, 0xa3, 0x9a, 0x77, 0x9c, 0x2f, 0x74, 0xc4, 0xbf, 0x82, 0x8f,
- 0xef, 0x8e, 0x8f, 0x8b, 0xbb, 0xe0, 0xe3, 0x57, 0x2f, 0x42, 0xfe, 0x96,
- 0x21, 0x9b, 0xcb, 0x90, 0xcd, 0x65, 0xc8, 0xe6, 0x32, 0x64, 0x73, 0x19,
- 0xb2, 0x89, 0xfd, 0xf3, 0xfc, 0xf2, 0xb8, 0xc1, 0x1f, 0x9f, 0x82, 0x2c,
- 0x7f, 0xdb, 0xe0, 0x8f, 0x51, 0xc8, 0x70, 0x12, 0xb2, 0xeb, 0x43, 0x6e,
- 0x87, 0x21, 0xcb, 0x1e, 0x64, 0xb9, 0x1f, 0x72, 0x9c, 0x50, 0xfe, 0xe3,
- 0x04, 0xb0, 0xe8, 0x83, 0xf0, 0x41, 0xce, 0x57, 0xfb, 0x65, 0x51, 0xd1,
- 0x12, 0xc8, 0x96, 0xbf, 0x49, 0x1e, 0x62, 0x5f, 0xd0, 0x3f, 0x77, 0xe5,
- 0xfc, 0x5a, 0x48, 0xdb, 0xab, 0xf2, 0xcd, 0xca, 0x6b, 0xf2, 0x42, 0x85,
- 0x34, 0xe6, 0x64, 0x11, 0xef, 0xd6, 0x9e, 0xa2, 0x1f, 0xa9, 0xe8, 0x83,
- 0xcc, 0x9d, 0x94, 0xff, 0x03, 0x5e, 0xae, 0x6f, 0x7c, 0x58, 0x3e, 0xe7,
- 0x52, 0x86, 0xe3, 0xd0, 0x35, 0xb8, 0x3f, 0x40, 0xbd, 0x04, 0x3f, 0xb4,
- 0x92, 0x2a, 0x97, 0xa0, 0x27, 0xaa, 0xf6, 0x08, 0x30, 0x58, 0x39, 0xe8,
- 0xa1, 0x0e, 0xab, 0x7a, 0xee, 0x80, 0x4d, 0xde, 0xec, 0x87, 0xbc, 0xa4,
- 0xbe, 0x0a, 0xe1, 0xc5, 0x33, 0xda, 0x73, 0x94, 0x35, 0xe8, 0xcf, 0xa7,
- 0xc8, 0x47, 0xfa, 0xb5, 0xb8, 0x56, 0xba, 0xf7, 0x27, 0x2a, 0x7e, 0x5c,
- 0x9a, 0x86, 0x2f, 0xbf, 0x46, 0x3e, 0x41, 0x56, 0x9e, 0x22, 0x1f, 0x49,
- 0x9f, 0xe6, 0xe3, 0x23, 0x12, 0xf2, 0x90, 0xef, 0x5a, 0x79, 0x08, 0x27,
- 0xaa, 0x33, 0x8e, 0xb9, 0x7f, 0x2d, 0x66, 0x62, 0xc8, 0xc6, 0x26, 0xbf,
- 0x2a, 0xd3, 0x0d, 0xce, 0xc7, 0x92, 0xdb, 0xbc, 0xab, 0xf0, 0xa9, 0x38,
- 0xf6, 0xab, 0xc1, 0xa3, 0x71, 0xce, 0x81, 0xeb, 0xba, 0x47, 0xea, 0x7d,
- 0xbe, 0x89, 0xaf, 0xfc, 0x2a, 0x5b, 0xc4, 0x7a, 0xe0, 0x3b, 0xf4, 0xcb,
- 0x0b, 0xcb, 0xe0, 0x37, 0xfc, 0xae, 0x6f, 0xc0, 0xef, 0x62, 0x9c, 0x53,
- 0xaf, 0xcf, 0xb8, 0x89, 0xd9, 0xb6, 0xc6, 0x6a, 0x93, 0x58, 0x23, 0xfa,
- 0xed, 0xa9, 0xf2, 0x75, 0xe8, 0xc1, 0xe7, 0x7d, 0xc6, 0xf8, 0x02, 0xf9,
- 0xef, 0x7e, 0xb3, 0xa6, 0x53, 0xf1, 0x6d, 0x79, 0x04, 0xba, 0xf1, 0x51,
- 0xe8, 0xc6, 0x4f, 0xdc, 0x92, 0xe7, 0x43, 0x79, 0xbb, 0x7f, 0x6a, 0x76,
- 0x65, 0xb0, 0x1c, 0xb1, 0xfb, 0x31, 0xa7, 0xe6, 0xb6, 0x8c, 0xf1, 0x25,
- 0x4d, 0x2c, 0xb6, 0x19, 0xb3, 0x86, 0xf1, 0x56, 0xca, 0x74, 0x20, 0xd7,
- 0xfc, 0x72, 0x57, 0x44, 0x9d, 0x3f, 0x7b, 0xb4, 0x13, 0xbb, 0xfc, 0xbd,
- 0xd8, 0xa1, 0xed, 0xf3, 0x5b, 0x46, 0xc6, 0x76, 0x72, 0x99, 0x26, 0x32,
- 0xe1, 0x99, 0x73, 0x37, 0x6c, 0x1e, 0xf7, 0x6d, 0x2a, 0x99, 0xc3, 0xde,
- 0x9e, 0xdf, 0xa0, 0x5d, 0x20, 0x9e, 0x6c, 0x63, 0x4c, 0x6f, 0xa6, 0x3d,
- 0xcb, 0xd8, 0x41, 0x37, 0xfc, 0x97, 0xd7, 0xe5, 0xdc, 0xca, 0x3f, 0x75,
- 0xe8, 0xfd, 0xa4, 0x73, 0xcf, 0xec, 0x8b, 0xad, 0x71, 0x54, 0xbd, 0x46,
- 0x85, 0x4c, 0x37, 0x30, 0x0c, 0xfd, 0xa5, 0x6b, 0xca, 0x5f, 0x3a, 0xec,
- 0x3b, 0xb2, 0x19, 0x67, 0x9f, 0xaf, 0xcb, 0xb1, 0x95, 0xe1, 0x4e, 0xc6,
- 0x2b, 0x17, 0x97, 0x0f, 0xc8, 0x96, 0xd2, 0x65, 0x0f, 0xa3, 0x6e, 0x16,
- 0x7b, 0x36, 0x08, 0x26, 0xfc, 0xb4, 0x7b, 0x5e, 0x46, 0x12, 0xe7, 0xc1,
- 0xd3, 0x3f, 0x43, 0x1b, 0xf8, 0xd4, 0x41, 0x11, 0xcf, 0xae, 0xc2, 0x6f,
- 0xbf, 0x21, 0xbc, 0x1e, 0x71, 0x4f, 0x43, 0x18, 0x72, 0x6e, 0xda, 0x7d,
- 0x4b, 0x42, 0xdb, 0x45, 0x3b, 0xc5, 0x33, 0xeb, 0x3e, 0x29, 0xac, 0x6b,
- 0x5a, 0xe7, 0x41, 0xeb, 0xa9, 0x15, 0x8e, 0xc1, 0x79, 0x91, 0xde, 0x7f,
- 0xe2, 0x19, 0x07, 0xe6, 0xf2, 0x41, 0x60, 0x59, 0xe2, 0x28, 0x1d, 0x8b,
- 0x28, 0xa0, 0x8d, 0xc2, 0x5a, 0x3e, 0xcf, 0x2b, 0xc9, 0xc7, 0x2f, 0xc2,
- 0x6f, 0x88, 0x43, 0x8e, 0xf1, 0x7c, 0xbd, 0x39, 0xe6, 0xcb, 0xfa, 0xfa,
- 0x1c, 0xed, 0x92, 0xf2, 0x11, 0xf2, 0xc0, 0x85, 0x93, 0xa8, 0xcb, 0x78,
- 0x67, 0x10, 0x1c, 0xf7, 0xe1, 0xc7, 0x3f, 0x45, 0xd9, 0xbb, 0x53, 0x4a,
- 0xca, 0xe7, 0x20, 0x86, 0x65, 0xfe, 0xc6, 0x96, 0x1b, 0xc3, 0xfe, 0x9c,
- 0x86, 0x6d, 0xcb, 0xc3, 0xb6, 0x45, 0xee, 0x3e, 0x02, 0x3c, 0xab, 0xce,
- 0xd9, 0x60, 0x3f, 0x39, 0xee, 0xc3, 0xd6, 0xdf, 0x67, 0x46, 0x81, 0x6f,
- 0x1f, 0x00, 0xbe, 0x65, 0x1e, 0x59, 0x1e, 0x18, 0x97, 0xf8, 0xd6, 0x95,
- 0xbf, 0xda, 0xc8, 0x43, 0xb7, 0x4d, 0x74, 0x52, 0x17, 0x1f, 0xd9, 0xb6,
- 0xd3, 0x45, 0x63, 0xc7, 0xf7, 0x49, 0x41, 0x9d, 0xbb, 0x15, 0x95, 0xbd,
- 0x9f, 0x5f, 0x27, 0xae, 0x87, 0xed, 0x5f, 0x87, 0xef, 0x57, 0xa1, 0x8f,
- 0x96, 0xc3, 0xfd, 0x03, 0xb8, 0x7f, 0x08, 0xe5, 0x11, 0x94, 0xda, 0xf7,
- 0xb9, 0xb4, 0x1c, 0xe9, 0xd4, 0x31, 0xde, 0x44, 0x93, 0xff, 0x43, 0x39,
- 0x8c, 0x4f, 0xcd, 0x56, 0xc3, 0x38, 0xfd, 0x21, 0x39, 0xee, 0xeb, 0xb3,
- 0xf5, 0x09, 0xf8, 0xeb, 0x9d, 0xc0, 0x60, 0x0f, 0x3d, 0x0d, 0x9b, 0x71,
- 0xdf, 0x21, 0xb1, 0xef, 0xb3, 0x64, 0x76, 0x14, 0x74, 0x8f, 0x0e, 0x42,
- 0x3f, 0xf7, 0xc3, 0xdf, 0x56, 0x7e, 0xb0, 0xc1, 0x9c, 0xd4, 0xfb, 0x71,
- 0xf9, 0xf3, 0x8d, 0x10, 0x7b, 0xb6, 0x01, 0xa7, 0x32, 0x56, 0x98, 0x54,
- 0xb8, 0xd9, 0xbe, 0x8d, 0xeb, 0xdf, 0x25, 0xf9, 0xdb, 0xc8, 0x53, 0x3e,
- 0x03, 0xa6, 0x51, 0xd7, 0x71, 0x49, 0x9f, 0xe1, 0xba, 0xb5, 0x9b, 0x18,
- 0x2f, 0x6d, 0x06, 0xcb, 0xbf, 0xec, 0xdc, 0xc6, 0x96, 0x8c, 0x01, 0x59,
- 0xe3, 0x9d, 0x3b, 0x79, 0x69, 0xa1, 0xdc, 0x87, 0xf9, 0x04, 0x94, 0xff,
- 0x4b, 0xa0, 0x9f, 0xf6, 0x9e, 0xb6, 0xc1, 0xb5, 0xa2, 0x07, 0x89, 0x05,
- 0x22, 0xd2, 0xe6, 0x71, 0x9f, 0xd2, 0x4e, 0x1d, 0xc1, 0x9c, 0x88, 0x0d,
- 0x3e, 0xdf, 0x2d, 0xdd, 0xc4, 0x07, 0x49, 0x3c, 0xbb, 0x8e, 0x7a, 0xbc,
- 0x67, 0x3d, 0xf8, 0x52, 0xcb, 0x62, 0x45, 0x0e, 0xce, 0x41, 0xae, 0x3d,
- 0x5c, 0x1f, 0x47, 0x39, 0x8c, 0xf2, 0x71, 0x94, 0xd4, 0x4f, 0x57, 0x65,
- 0x56, 0xc7, 0x7f, 0x14, 0x0e, 0xa1, 0xed, 0x9c, 0xf6, 0xa9, 0x53, 0x4f,
- 0x8a, 0x3d, 0xf6, 0x41, 0x3c, 0xa3, 0x1f, 0x8f, 0x91, 0xee, 0xff, 0x82,
- 0x89, 0x3f, 0x6d, 0xc7, 0xac, 0x8c, 0x4e, 0x5e, 0x51, 0x31, 0xfc, 0xf5,
- 0xa7, 0xe8, 0x23, 0xff, 0x54, 0x1e, 0xbd, 0x29, 0xb6, 0xb7, 0x1d, 0xcb,
- 0x1a, 0x2f, 0x28, 0x5d, 0x4c, 0x7e, 0x40, 0x0f, 0xbb, 0x19, 0xf9, 0xfa,
- 0x46, 0x0f, 0xf4, 0x5b, 0x5c, 0xde, 0x58, 0x09, 0x80, 0xd5, 0xb9, 0x37,
- 0x47, 0x60, 0x33, 0x5d, 0x83, 0x03, 0xe2, 0xf2, 0x2f, 0x90, 0xf3, 0x7f,
- 0xae, 0x24, 0xe4, 0xcd, 0x4a, 0x10, 0x5c, 0xf3, 0xd3, 0xfe, 0x61, 0x91,
- 0xbb, 0xdb, 0x74, 0x0e, 0x00, 0x6a, 0xe8, 0x73, 0xfb, 0x79, 0x75, 0x76,
- 0x8f, 0x7a, 0xd0, 0x3b, 0x6f, 0x36, 0x7e, 0x01, 0xbe, 0xea, 0x3e, 0x5b,
- 0xdb, 0x6e, 0xe9, 0xb6, 0x3c, 0xfb, 0x4f, 0x6c, 0x4a, 0xda, 0xe4, 0x10,
- 0xa4, 0xd1, 0x36, 0x3d, 0xbc, 0xb6, 0xdd, 0x9e, 0x6d, 0x33, 0xca, 0x5e,
- 0x94, 0xd6, 0x7b, 0xa5, 0xfe, 0x17, 0xdc, 0x2b, 0xf0, 0x63, 0xd5, 0x99,
- 0x11, 0x4b, 0x9e, 0x55, 0xb0, 0x4e, 0xd2, 0xbc, 0x1f, 0x30, 0xef, 0x3d,
- 0x85, 0x5f, 0x9d, 0xed, 0x18, 0x20, 0x7c, 0xdb, 0xe5, 0xd4, 0x69, 0x65,
- 0x47, 0x18, 0xb7, 0x5d, 0xa6, 0x7f, 0x4f, 0x5d, 0x3e, 0x69, 0xec, 0x09,
- 0x7c, 0x8f, 0xda, 0x71, 0x99, 0x51, 0xd7, 0x9f, 0x90, 0x47, 0x5c, 0xf2,
- 0xee, 0xa4, 0xf8, 0x63, 0x1a, 0x4b, 0x89, 0x89, 0x09, 0x76, 0x78, 0x27,
- 0xe1, 0x9b, 0x29, 0x7b, 0xec, 0x7e, 0x4c, 0xc8, 0xe3, 0x36, 0xda, 0x8f,
- 0x9c, 0x6d, 0x01, 0x83, 0x3d, 0x99, 0x91, 0xe7, 0x36, 0x50, 0x17, 0xeb,
- 0xf5, 0x31, 0xc1, 0xfd, 0xb3, 0xb8, 0x67, 0x1c, 0xed, 0xe9, 0xb8, 0x44,
- 0x9e, 0xee, 0x97, 0xf6, 0x33, 0xc4, 0x29, 0xe4, 0x69, 0x42, 0xda, 0xce,
- 0x10, 0x2f, 0x33, 0xb6, 0x9c, 0x1a, 0xbf, 0x21, 0x8c, 0xe5, 0xa4, 0xfc,
- 0x2b, 0xf8, 0x6d, 0x61, 0xde, 0xed, 0xf0, 0xc3, 0xdb, 0x2e, 0xe8, 0x76,
- 0xf6, 0xb9, 0x3e, 0x00, 0xc3, 0x98, 0xd8, 0xf0, 0x59, 0xec, 0x0b, 0x2c,
- 0xbb, 0x50, 0xf2, 0x1d, 0x48, 0x3a, 0x37, 0x60, 0xde, 0x41, 0x37, 0x5e,
- 0xe0, 0xf8, 0xb0, 0x8f, 0xbe, 0xce, 0x17, 0x1d, 0x18, 0xf2, 0xe5, 0xd2,
- 0x1a, 0x65, 0x93, 0x71, 0x74, 0x62, 0x97, 0x57, 0xc5, 0x5e, 0xca, 0x48,
- 0xe4, 0x4c, 0x06, 0x72, 0xe8, 0xc3, 0xee, 0x12, 0xf3, 0xd1, 0xd6, 0xe1,
- 0x39, 0xf0, 0x56, 0xfd, 0x29, 0xce, 0xe9, 0xaa, 0xd8, 0xf5, 0x5f, 0x65,
- 0xc3, 0xc2, 0x7d, 0xc1, 0x31, 0x4e, 0xc2, 0xfe, 0x46, 0xe5, 0x73, 0x71,
- 0xca, 0x8a, 0x96, 0xbd, 0xb4, 0x3d, 0xa4, 0x64, 0xb5, 0x48, 0xbb, 0xfc,
- 0xd4, 0xed, 0x7b, 0xe0, 0xa7, 0x9d, 0x2e, 0x6f, 0xcb, 0x18, 0xf3, 0x42,
- 0x03, 0xa9, 0x02, 0xef, 0xcc, 0x7b, 0x96, 0x2c, 0x78, 0x27, 0x15, 0x1e,
- 0x7c, 0x14, 0xed, 0x4f, 0x98, 0xf6, 0x0b, 0x32, 0x64, 0x64, 0x5d, 0xc5,
- 0x11, 0xa0, 0xc7, 0xb8, 0x66, 0xbc, 0xff, 0x2d, 0xf1, 0x7b, 0xb9, 0x9e,
- 0x27, 0x65, 0x60, 0x4c, 0xe3, 0x90, 0x92, 0x4d, 0x1c, 0xf2, 0xae, 0x71,
- 0x5a, 0x95, 0xcb, 0x57, 0xa8, 0xd0, 0xce, 0xec, 0x85, 0xfc, 0xc2, 0x27,
- 0xda, 0x08, 0x63, 0xb5, 0x6a, 0x5f, 0x25, 0x06, 0x6c, 0x4b, 0xbc, 0xa1,
- 0xa1, 0xe1, 0x12, 0xf0, 0xc9, 0x3c, 0x7c, 0x5e, 0xd2, 0xb1, 0x00, 0x3b,
- 0xb7, 0xe6, 0xff, 0x4b, 0x70, 0x22, 0x9e, 0x3a, 0x3d, 0xf3, 0xae, 0xf1,
- 0xfb, 0x30, 0x6e, 0xdf, 0x7c, 0x9e, 0xb2, 0x69, 0xfd, 0x61, 0xe3, 0x88,
- 0xd2, 0x91, 0x37, 0xe3, 0xae, 0x30, 0x7e, 0x3f, 0x7d, 0x53, 0x1c, 0xb5,
- 0xd4, 0x08, 0x73, 0xf0, 0x42, 0x3d, 0x7f, 0x1a, 0xba, 0x3a, 0x22, 0x37,
- 0x80, 0x41, 0x27, 0xc0, 0xbb, 0x73, 0x6b, 0x65, 0xeb, 0x4a, 0x45, 0xd4,
- 0x7d, 0xc1, 0x67, 0x4e, 0xde, 0x47, 0xc0, 0x3b, 0xd8, 0x98, 0x0d, 0xc7,
- 0x9c, 0x29, 0x39, 0x78, 0x66, 0x2b, 0x9f, 0xb9, 0xa4, 0x74, 0xf3, 0xe1,
- 0x2e, 0x9e, 0xb9, 0x5c, 0x5a, 0xfe, 0x28, 0xee, 0x79, 0xf6, 0x71, 0xa4,
- 0xe5, 0xf9, 0x66, 0x4f, 0x54, 0x63, 0x37, 0xf0, 0x5d, 0xf3, 0xcd, 0x01,
- 0xbf, 0x8b, 0x8c, 0xe7, 0x35, 0x88, 0x83, 0x3b, 0x0d, 0x0e, 0x26, 0xce,
- 0xc2, 0x7a, 0x6d, 0x30, 0x0e, 0x43, 0xac, 0x15, 0x57, 0x7e, 0xa1, 0xc2,
- 0x5e, 0xfe, 0x31, 0x93, 0x7f, 0x71, 0xab, 0x5c, 0xcd, 0x56, 0x42, 0x3c,
- 0xd7, 0x2c, 0x57, 0xee, 0x6f, 0x20, 0x57, 0x13, 0x5d, 0x3a, 0xdf, 0x81,
- 0x36, 0xcd, 0x92, 0x37, 0xaa, 0x7b, 0x64, 0xab, 0xfa, 0x20, 0x70, 0xb4,
- 0xca, 0xfb, 0x90, 0x2d, 0xac, 0xc5, 0x83, 0x95, 0x49, 0x99, 0xa8, 0xc6,
- 0xe4, 0x5a, 0xd5, 0x7e, 0xa0, 0x5d, 0x18, 0x07, 0x27, 0x36, 0xf9, 0x1b,
- 0xa5, 0xdf, 0x7e, 0xe0, 0xef, 0xb4, 0xe7, 0xb9, 0xca, 0x0d, 0xb4, 0x9f,
- 0xad, 0xde, 0x2b, 0x25, 0xd5, 0xbe, 0x7e, 0xcb, 0x18, 0x51, 0x33, 0x46,
- 0xbd, 0x7a, 0x97, 0x89, 0xdf, 0x95, 0xe5, 0x12, 0xb0, 0xaf, 0x7d, 0x96,
- 0xf3, 0xbd, 0xc3, 0xe4, 0x77, 0xc5, 0x9a, 0xfc, 0x91, 0xa8, 0xf1, 0x47,
- 0x7e, 0x06, 0x3d, 0xfe, 0x94, 0x44, 0xbd, 0xb0, 0x2f, 0xe6, 0x6a, 0x27,
- 0x4c, 0x6e, 0xc7, 0x5e, 0xf4, 0x75, 0x10, 0xef, 0xee, 0xc3, 0xef, 0x49,
- 0xd4, 0xa3, 0xbd, 0xe2, 0xd9, 0x28, 0x31, 0x02, 0xcf, 0xeb, 0x7a, 0x51,
- 0xaf, 0x03, 0x58, 0x72, 0xbf, 0x79, 0x16, 0xf6, 0x11, 0xd6, 0x0d, 0xef,
- 0x9b, 0xcf, 0x53, 0x59, 0x2f, 0xd9, 0x74, 0x9e, 0x0a, 0x45, 0xa5, 0xda,
- 0x86, 0xb6, 0x36, 0xb4, 0x51, 0xc9, 0x26, 0x1b, 0xf5, 0x56, 0x53, 0x9e,
- 0xa7, 0xc6, 0x61, 0x57, 0x33, 0x9c, 0x6b, 0x5f, 0x53, 0x0e, 0x4a, 0xaa,
- 0x4c, 0xfb, 0xc8, 0x78, 0xdf, 0x7a, 0x25, 0xb4, 0x1f, 0xb9, 0x1e, 0x9e,
- 0x5b, 0x2c, 0xfa, 0x2a, 0x16, 0x97, 0x8c, 0x64, 0x69, 0x7f, 0xfc, 0xd8,
- 0x16, 0x70, 0x65, 0x5d, 0x9d, 0xeb, 0x47, 0xf0, 0x83, 0x5d, 0x76, 0x2c,
- 0x71, 0x3d, 0x3e, 0x2b, 0x1b, 0xbd, 0x03, 0x5d, 0x6e, 0xab, 0x3a, 0xc9,
- 0xbc, 0xdf, 0x67, 0xee, 0x13, 0xb2, 0x56, 0xf9, 0x50, 0xbf, 0x9d, 0xfd,
- 0x5f, 0xb7, 0xe7, 0x33, 0x3d, 0x3c, 0x7f, 0xc2, 0x33, 0xe2, 0xf5, 0xd7,
- 0x54, 0x4e, 0xa3, 0xc6, 0x46, 0x0e, 0xcf, 0x2f, 0x81, 0x73, 0x7e, 0x04,
- 0x9e, 0x84, 0xb8, 0xfb, 0x75, 0x99, 0x50, 0x98, 0xaa, 0x0d, 0xb6, 0xd2,
- 0x60, 0xaa, 0xee, 0x14, 0x30, 0x15, 0xdb, 0xb7, 0xe2, 0x40, 0xbd, 0x97,
- 0x22, 0x59, 0x1d, 0x57, 0x6d, 0x89, 0x15, 0x5b, 0x8f, 0x64, 0xc4, 0x3a,
- 0x81, 0x1f, 0x65, 0xd4, 0x5e, 0x7a, 0x4d, 0xbc, 0xa5, 0x54, 0x95, 0xf9,
- 0xb1, 0x0b, 0x1b, 0x3c, 0xc7, 0x03, 0x16, 0x4b, 0x50, 0x96, 0xf9, 0x6e,
- 0x1a, 0x63, 0xbc, 0x06, 0xff, 0x73, 0x0f, 0xf8, 0x6d, 0x1b, 0x1e, 0xf9,
- 0x26, 0x46, 0x11, 0x63, 0x2c, 0x18, 0x7b, 0x71, 0x5e, 0x61, 0x89, 0x52,
- 0x7c, 0x11, 0xe5, 0x0f, 0x0d, 0x76, 0x78, 0xbd, 0x2b, 0x3c, 0xb7, 0x2f,
- 0xc5, 0xbf, 0x84, 0xe7, 0xaf, 0xc3, 0x1f, 0x8c, 0x4a, 0x9b, 0x5a, 0xb3,
- 0x10, 0x3b, 0xff, 0x3d, 0xea, 0x90, 0xfe, 0x3b, 0x4d, 0x7e, 0x0d, 0xf3,
- 0x06, 0xd8, 0x1f, 0xec, 0x96, 0xca, 0xe1, 0xca, 0xa1, 0x64, 0x3b, 0xb6,
- 0x79, 0x05, 0x75, 0x73, 0x98, 0x37, 0x9f, 0x4b, 0x5f, 0x44, 0x9a, 0x9f,
- 0x7f, 0x14, 0xcf, 0x29, 0x87, 0xef, 0x37, 0x72, 0x18, 0xbe, 0xcb, 0x1b,
- 0x3e, 0xdd, 0x8e, 0x31, 0xc8, 0xab, 0x66, 0xba, 0x38, 0x9f, 0x70, 0xcd,
- 0xdb, 0x4c, 0xae, 0x01, 0x9f, 0xbd, 0xdf, 0x3c, 0x73, 0xcc, 0x1c, 0x3f,
- 0xde, 0x65, 0xb0, 0x04, 0x76, 0x7b, 0xb8, 0x1f, 0x49, 0x67, 0xac, 0x09,
- 0xb3, 0xfe, 0x61, 0xef, 0x4e, 0x1e, 0x26, 0x65, 0xce, 0x53, 0xb1, 0x23,
- 0xe6, 0x8f, 0xe5, 0x6c, 0x9d, 0xb3, 0xf1, 0x8d, 0x9b, 0xe2, 0xdd, 0x4a,
- 0xd7, 0xf2, 0x0c, 0xa4, 0x6a, 0x67, 0xdb, 0x7f, 0xed, 0xbc, 0xbb, 0x48,
- 0x36, 0x6c, 0x07, 0x9c, 0xa6, 0xda, 0x24, 0x65, 0xae, 0xf1, 0x6e, 0x39,
- 0x7a, 0xca, 0xbf, 0x30, 0x79, 0x10, 0xfb, 0x55, 0x1e, 0x04, 0xf5, 0xe2,
- 0x5a, 0x35, 0x02, 0x5e, 0xf7, 0x31, 0x37, 0x0a, 0x7e, 0x4c, 0x0c, 0x73,
- 0x45, 0x5f, 0xf1, 0xf7, 0xab, 0x5c, 0xa9, 0x88, 0x17, 0xe6, 0xf5, 0x72,
- 0x1f, 0xde, 0xa1, 0xde, 0x7f, 0x7d, 0xa5, 0x9d, 0xf9, 0xaa, 0x28, 0xb9,
- 0x47, 0x7f, 0x09, 0xfd, 0x18, 0x95, 0x42, 0xd5, 0x03, 0xfe, 0x89, 0x52,
- 0x2e, 0xf1, 0x7c, 0x3f, 0xfc, 0x61, 0xc1, 0x3e, 0x69, 0x83, 0x6f, 0xa2,
- 0x7c, 0x1d, 0xcc, 0x68, 0x87, 0x0e, 0x62, 0x70, 0x9d, 0x1f, 0x1a, 0x40,
- 0x87, 0xcf, 0xcb, 0xda, 0xf8, 0xa2, 0xd4, 0xc7, 0x9b, 0x31, 0x2c, 0x30,
- 0xaa, 0x5b, 0x0e, 0xea, 0x9e, 0x8a, 0x65, 0x1a, 0xdd, 0x72, 0xc2, 0xe0,
- 0x4e, 0xae, 0x83, 0x2d, 0x85, 0xd1, 0x05, 0x25, 0x5f, 0x75, 0xb5, 0x1e,
- 0x8e, 0x75, 0x59, 0xe5, 0xf9, 0x72, 0x0c, 0xe6, 0xfa, 0x46, 0x0c, 0x0e,
- 0x3b, 0x65, 0xd6, 0xd5, 0xd9, 0x1b, 0xe6, 0xcc, 0x47, 0xb3, 0x87, 0x99,
- 0xdb, 0x01, 0x6c, 0x3d, 0x3d, 0x35, 0x5b, 0xa1, 0x2d, 0x0c, 0x82, 0xba,
- 0xbf, 0x89, 0x1e, 0x7f, 0xac, 0x30, 0xe4, 0x96, 0x68, 0xdd, 0xbe, 0xa0,
- 0x72, 0x66, 0x27, 0xa7, 0xf2, 0x2a, 0x5e, 0xd8, 0x7c, 0x76, 0xf3, 0x5e,
- 0xe7, 0x36, 0x31, 0xf8, 0xfe, 0x1d, 0x66, 0xfd, 0x63, 0x4e, 0xa9, 0xd2,
- 0xe5, 0xcc, 0xaa, 0xb3, 0xb5, 0xac, 0xf9, 0x16, 0x27, 0x37, 0x95, 0x6e,
- 0x7c, 0x76, 0x2f, 0xb1, 0x3e, 0xcf, 0x31, 0x0a, 0x15, 0x9e, 0xe3, 0xe8,
- 0xf7, 0x69, 0xf3, 0x7e, 0xa0, 0xa1, 0xde, 0xa9, 0x78, 0x23, 0x63, 0x8c,
- 0xed, 0x28, 0x6f, 0x54, 0xa8, 0x6b, 0xd0, 0x7f, 0x5c, 0xcf, 0x21, 0x92,
- 0x2d, 0xc2, 0x3f, 0x25, 0x7d, 0x47, 0xa6, 0xf2, 0x2b, 0xcc, 0xdb, 0x7a,
- 0x68, 0xea, 0x1a, 0xfc, 0xa5, 0x73, 0x9e, 0xce, 0x2b, 0x5f, 0x67, 0x1c,
- 0x8c, 0xed, 0x54, 0x9f, 0x45, 0x13, 0xab, 0x3d, 0x3c, 0x35, 0xb8, 0x1e,
- 0x91, 0x27, 0x4c, 0x1f, 0xbc, 0x4f, 0x6e, 0xfb, 0x52, 0x4a, 0xff, 0xc1,
- 0x3f, 0x18, 0x85, 0x7f, 0xd0, 0x09, 0x5d, 0x4f, 0x3f, 0x83, 0xf8, 0xbb,
- 0x13, 0x7b, 0x85, 0xe3, 0xdc, 0xa5, 0xc6, 0x89, 0x60, 0x9c, 0x59, 0xf8,
- 0x38, 0x8c, 0x47, 0xe6, 0x3d, 0x07, 0x58, 0x02, 0xb6, 0xde, 0x63, 0xbc,
- 0xdc, 0xc6, 0x9c, 0x87, 0xa1, 0x27, 0x98, 0xa3, 0x32, 0x11, 0xe6, 0x0d,
- 0xa1, 0x9d, 0x6f, 0xda, 0x1d, 0x44, 0x3b, 0xfa, 0x07, 0x6c, 0x2b, 0xb7,
- 0xd9, 0x32, 0xa8, 0xb0, 0x81, 0xf6, 0x6b, 0x48, 0x43, 0x0d, 0x73, 0xa5,
- 0x5d, 0xc5, 0x9e, 0x53, 0xf3, 0x3a, 0xa8, 0xda, 0x59, 0xd9, 0x31, 0xd0,
- 0x4e, 0xfc, 0x87, 0xbe, 0x97, 0x75, 0xbc, 0xb3, 0xa0, 0xe4, 0x08, 0x72,
- 0x32, 0x1e, 0xe6, 0xbd, 0xe8, 0x76, 0x61, 0xfd, 0x81, 0xf5, 0x86, 0x19,
- 0xff, 0xe7, 0x41, 0xee, 0x68, 0xa7, 0xf2, 0xad, 0x5f, 0xbe, 0x29, 0x07,
- 0x8d, 0x6d, 0xc2, 0x3a, 0x91, 0x30, 0x2f, 0xb9, 0x89, 0xe6, 0xac, 0x59,
- 0x73, 0xb6, 0x63, 0x6c, 0x58, 0xe5, 0xe2, 0xf3, 0x99, 0x33, 0x97, 0x61,
- 0x1f, 0xcd, 0x67, 0x4d, 0xa3, 0xc0, 0x19, 0xda, 0x86, 0x94, 0x37, 0x3c,
- 0xd8, 0xeb, 0x36, 0xac, 0x1d, 0x6d, 0xc2, 0xa0, 0xf1, 0x2d, 0xde, 0x2b,
- 0xce, 0xca, 0x73, 0xcc, 0x51, 0xf8, 0xf5, 0x61, 0x7b, 0xae, 0x63, 0x6e,
- 0xea, 0x5a, 0xc5, 0x93, 0x53, 0xcb, 0x3a, 0x3f, 0x4c, 0xf3, 0x81, 0x3a,
- 0x9b, 0x6b, 0x9b, 0x94, 0x59, 0x8f, 0xb1, 0x9c, 0xa4, 0xbc, 0xe2, 0x35,
- 0xe7, 0x39, 0xa1, 0xfe, 0xc6, 0xa8, 0xc9, 0xc7, 0x3e, 0x88, 0xf9, 0x13,
- 0x37, 0x6a, 0x59, 0x3a, 0x00, 0x3b, 0xf4, 0x77, 0x0e, 0x70, 0x21, 0xf6,
- 0xd3, 0x75, 0xa7, 0x79, 0x7e, 0xdb, 0xf9, 0xdf, 0x4a, 0x2e, 0x1d, 0xc8,
- 0xc8, 0xe2, 0x36, 0xdf, 0xe1, 0xb7, 0xdf, 0x35, 0x04, 0x7d, 0x6f, 0x49,
- 0x71, 0xd4, 0x4b, 0x2c, 0xf0, 0x5c, 0xc3, 0x1d, 0x01, 0xca, 0xa7, 0x1f,
- 0x9d, 0x04, 0xbd, 0xbc, 0x1e, 0x04, 0x3e, 0x62, 0x4e, 0x22, 0xee, 0x99,
- 0x13, 0x18, 0xf7, 0x40, 0xaf, 0xab, 0xce, 0x2b, 0xb4, 0xce, 0xfe, 0xfe,
- 0x5e, 0xe6, 0xc0, 0xf5, 0x78, 0xe1, 0xda, 0xab, 0xef, 0xda, 0xd0, 0x77,
- 0xc4, 0xbc, 0x9f, 0xd8, 0xe6, 0xbf, 0xf4, 0xb1, 0xdc, 0xce, 0x35, 0x33,
- 0xb1, 0x17, 0xd6, 0x1f, 0x57, 0xb4, 0xcc, 0x42, 0x57, 0xcf, 0xa9, 0xf9,
- 0xdc, 0x0f, 0x59, 0x88, 0xc8, 0xfc, 0xb6, 0xfc, 0xde, 0x0f, 0xf9, 0xdd,
- 0xc3, 0x14, 0xcf, 0x5d, 0x64, 0x2d, 0x94, 0x31, 0xca, 0x17, 0x65, 0xeb,
- 0xe3, 0xdd, 0xdc, 0x73, 0xe5, 0xed, 0x75, 0x77, 0x94, 0xcd, 0x4d, 0xda,
- 0xe1, 0xba, 0xf3, 0x7a, 0xb7, 0xdc, 0xaa, 0x70, 0x7f, 0x64, 0x7e, 0x83,
- 0xb5, 0xf5, 0xcd, 0xda, 0x66, 0x9a, 0xbe, 0x83, 0x08, 0xfb, 0x63, 0x0c,
- 0x94, 0x36, 0x88, 0xe7, 0x50, 0xed, 0x52, 0x56, 0x32, 0x68, 0x29, 0x6c,
- 0x9d, 0x73, 0xf3, 0x49, 0xc6, 0xbc, 0x8f, 0xc9, 0xbf, 0x03, 0xcd, 0xb9,
- 0xe1, 0xa8, 0xe8, 0xb6, 0x33, 0xe0, 0xf7, 0xa6, 0x0b, 0x7f, 0x90, 0x67,
- 0xd6, 0x15, 0x47, 0xce, 0xa9, 0x73, 0x57, 0xec, 0xd1, 0x4e, 0x47, 0x16,
- 0xbd, 0xed, 0x73, 0x78, 0xa9, 0xa1, 0xce, 0x1a, 0xde, 0x3d, 0xb1, 0x4d,
- 0x1b, 0xfd, 0x09, 0xf8, 0x52, 0xde, 0xcf, 0x83, 0x52, 0xfc, 0xa6, 0xba,
- 0x46, 0xaf, 0x33, 0x4e, 0xc3, 0xf3, 0x01, 0x57, 0x0a, 0xf0, 0x0b, 0x0b,
- 0xf0, 0x09, 0x0b, 0x4a, 0x2f, 0x30, 0x6e, 0xc3, 0x18, 0x5b, 0x19, 0x3e,
- 0x48, 0x39, 0x68, 0xf7, 0x4e, 0xaa, 0x18, 0xe2, 0xa5, 0x8d, 0x54, 0xb9,
- 0x2c, 0x5e, 0xf2, 0xc1, 0xed, 0x7c, 0xba, 0xee, 0x72, 0x2c, 0xdb, 0x1c,
- 0x87, 0x4b, 0xaa, 0x5c, 0xb4, 0x0e, 0x60, 0xe4, 0xe3, 0xd0, 0xd5, 0xcf,
- 0xfb, 0x8c, 0xbf, 0xdd, 0x49, 0x7e, 0x7f, 0x95, 0x93, 0xb4, 0x87, 0x46,
- 0xc5, 0xbb, 0xe0, 0x0d, 0x3f, 0x28, 0xf4, 0x3f, 0x52, 0xc9, 0x23, 0xe4,
- 0xdb, 0xf6, 0x37, 0x0d, 0xa1, 0x7d, 0x1d, 0x95, 0xc1, 0x0b, 0xaf, 0xab,
- 0x33, 0x8e, 0x4f, 0xf8, 0xad, 0xb2, 0xa1, 0xe2, 0x77, 0xa3, 0x3d, 0x32,
- 0x08, 0xdf, 0x57, 0x60, 0xa1, 0xf8, 0x8d, 0x83, 0x05, 0xdf, 0x43, 0xdd,
- 0xcb, 0x74, 0x23, 0x69, 0xf2, 0x54, 0x69, 0x5f, 0x19, 0xdf, 0xd3, 0x79,
- 0x7a, 0xcc, 0x4d, 0x65, 0xfe, 0x64, 0x51, 0xe5, 0xeb, 0x31, 0xd6, 0xc7,
- 0x58, 0x1e, 0xe3, 0x7d, 0x8c, 0xdb, 0xe9, 0x5c, 0xbd, 0x89, 0xc6, 0x6e,
- 0xb1, 0xbd, 0x30, 0x5f, 0x52, 0xdb, 0xad, 0xad, 0xcc, 0x3e, 0xd8, 0x3a,
- 0x57, 0xc5, 0x4e, 0x4a, 0x6e, 0x8f, 0x1c, 0x1b, 0x6e, 0x07, 0xcf, 0x7b,
- 0x55, 0x3e, 0x9d, 0xed, 0xdd, 0x0f, 0x1c, 0xcb, 0xf8, 0x1c, 0xb1, 0x69,
- 0xc8, 0xe7, 0x7b, 0xf0, 0xec, 0x1d, 0xf0, 0x9e, 0xcf, 0x80, 0x5b, 0x95,
- 0x1d, 0xfa, 0xbc, 0x6c, 0x55, 0x98, 0x03, 0x5f, 0xdb, 0x97, 0x57, 0xeb,
- 0x41, 0xdf, 0x3c, 0xd4, 0x4d, 0x61, 0xfe, 0x28, 0x7d, 0x2a, 0xd7, 0x9c,
- 0x93, 0xd3, 0x37, 0xef, 0x85, 0xbf, 0x4e, 0xfd, 0x63, 0xa9, 0xb1, 0xae,
- 0x47, 0x3e, 0x20, 0xe5, 0xda, 0x6e, 0x67, 0xfe, 0x41, 0xf0, 0x0d, 0x5f,
- 0xe5, 0xac, 0xc2, 0x9f, 0xd4, 0x6b, 0xac, 0xbf, 0x8f, 0x74, 0x76, 0xf2,
- 0xcb, 0xe3, 0xda, 0x67, 0xcc, 0xf5, 0x02, 0xb3, 0x78, 0xa7, 0xbb, 0x77,
- 0xb0, 0xf3, 0x2f, 0x0d, 0xae, 0x25, 0x6e, 0xee, 0x55, 0xd8, 0xc0, 0xae,
- 0x87, 0x72, 0xc2, 0x7c, 0x1f, 0x62, 0xea, 0x03, 0x92, 0xab, 0x41, 0x6f,
- 0xf6, 0xf1, 0xfe, 0x47, 0xa6, 0x2d, 0xaf, 0x03, 0x39, 0x3c, 0xd6, 0x7a,
- 0x96, 0x3f, 0xae, 0x71, 0x7d, 0x67, 0x78, 0x9e, 0x1f, 0xe6, 0xbc, 0xdf,
- 0x94, 0x5b, 0x0b, 0x79, 0x0a, 0x69, 0xd0, 0x63, 0x4d, 0x80, 0xde, 0x7a,
- 0x35, 0x21, 0xbd, 0x1e, 0xf3, 0x84, 0x22, 0x32, 0xd6, 0x9b, 0x82, 0x13,
- 0xaf, 0xe9, 0xa9, 0xd7, 0x60, 0xf3, 0xab, 0x21, 0x9d, 0x1a, 0xe3, 0xd7,
- 0x6b, 0x7c, 0x9f, 0xc4, 0x58, 0xed, 0x32, 0xd6, 0x47, 0x3e, 0xb7, 0xd2,
- 0x91, 0x34, 0xf9, 0xdc, 0xad, 0xcf, 0xef, 0x6b, 0xa2, 0xef, 0xd6, 0xef,
- 0x4a, 0xf3, 0x8c, 0x8b, 0xad, 0xd0, 0x3f, 0x21, 0x8d, 0xbd, 0xd0, 0x73,
- 0x98, 0xa3, 0x1f, 0xfa, 0x1a, 0x21, 0x5f, 0x42, 0x1f, 0x25, 0xaa, 0xe4,
- 0x62, 0x36, 0xc3, 0xb9, 0x44, 0x8d, 0xcf, 0x42, 0xba, 0x14, 0x6d, 0x11,
- 0x9e, 0x25, 0x46, 0xbd, 0xcf, 0xec, 0xd3, 0xeb, 0xff, 0xa4, 0x99, 0xaf,
- 0x6b, 0xea, 0xb0, 0xaf, 0xfd, 0x68, 0xff, 0xb5, 0x00, 0x63, 0x31, 0x08,
- 0x87, 0xfd, 0x1f, 0x62, 0xf7, 0xfd, 0xba, 0xaf, 0xce, 0x10, 0xbf, 0x87,
- 0xdf, 0xa1, 0x91, 0x4e, 0xee, 0xaf, 0x90, 0x87, 0xec, 0xa3, 0xd7, 0xc4,
- 0x5c, 0x49, 0x43, 0x47, 0x0b, 0x0d, 0x29, 0xff, 0x66, 0x1d, 0x77, 0x4f,
- 0xd3, 0xdc, 0x29, 0x6b, 0xdd, 0xb2, 0x50, 0xed, 0x94, 0xf9, 0xaa, 0xf2,
- 0x75, 0x86, 0x45, 0x88, 0xed, 0xb8, 0x2f, 0x55, 0x2e, 0xb3, 0xc9, 0x99,
- 0x0c, 0xf7, 0x67, 0x37, 0xea, 0xd1, 0x86, 0xa0, 0xac, 0x69, 0xfd, 0x54,
- 0x93, 0x5b, 0xbf, 0xd3, 0x98, 0x6b, 0xb4, 0xe6, 0xe3, 0x5d, 0x6f, 0xca,
- 0xc7, 0x6b, 0xce, 0x7f, 0x2a, 0xcb, 0x23, 0x07, 0x3b, 0x64, 0xe0, 0x6c,
- 0xa7, 0x91, 0xd1, 0xfb, 0xcd, 0x38, 0x18, 0x6f, 0x69, 0x5c, 0x06, 0x96,
- 0xbe, 0x28, 0xa5, 0x69, 0x95, 0xff, 0xde, 0xf4, 0xfd, 0xc3, 0xa0, 0xf9,
- 0xfe, 0x29, 0x67, 0x31, 0x17, 0xa6, 0xb0, 0x84, 0xf5, 0x3a, 0x98, 0x1a,
- 0x4e, 0xda, 0xfc, 0x46, 0xf7, 0x31, 0x19, 0x58, 0x1d, 0x97, 0xf4, 0x12,
- 0x31, 0x03, 0xb3, 0x01, 0x52, 0x2a, 0x2e, 0x9a, 0xbe, 0xa8, 0xfb, 0xf3,
- 0x96, 0xf8, 0x3e, 0x0d, 0xbc, 0xca, 0xf7, 0x85, 0x44, 0x44, 0x65, 0x0c,
- 0x7c, 0x10, 0xf2, 0xd4, 0x66, 0xf0, 0x80, 0x23, 0xf9, 0x25, 0xb6, 0x27,
- 0xf6, 0xf8, 0x47, 0xac, 0x59, 0x21, 0x69, 0x0b, 0xdb, 0xa8, 0xfe, 0x70,
- 0x1d, 0xc6, 0xd3, 0xc9, 0xeb, 0x51, 0x59, 0x6f, 0x78, 0xd8, 0x13, 0xfa,
- 0x9b, 0x89, 0x52, 0x2d, 0xcc, 0x27, 0x7d, 0xc4, 0xc4, 0x00, 0x34, 0x8d,
- 0xc5, 0x4a, 0xab, 0xec, 0x3d, 0x63, 0xbe, 0x9d, 0xe8, 0x50, 0x67, 0x68,
- 0x4d, 0xfa, 0xcf, 0xd4, 0xbf, 0xdd, 0x65, 0xde, 0x80, 0x08, 0xdf, 0x37,
- 0xf9, 0x24, 0xf1, 0xb8, 0xda, 0x07, 0x03, 0xf5, 0xb0, 0xde, 0xa8, 0xab,
- 0x7d, 0x60, 0xf2, 0x29, 0x6b, 0x68, 0x1e, 0x83, 0xcf, 0xc3, 0x67, 0x07,
- 0xd0, 0x96, 0xeb, 0x84, 0xb2, 0x7e, 0x40, 0xe5, 0x39, 0x46, 0xb2, 0x47,
- 0xcc, 0x59, 0x5a, 0x9f, 0x1a, 0xcb, 0xcd, 0xb2, 0xff, 0x50, 0x37, 0x74,
- 0x34, 0x8d, 0xdf, 0x4a, 0x2f, 0x7d, 0xf8, 0x9f, 0x19, 0x79, 0xe1, 0x7b,
- 0xde, 0xb7, 0xd6, 0xf9, 0xa3, 0x7d, 0xe1, 0x7b, 0x67, 0xfb, 0x1b, 0x0c,
- 0xf2, 0x92, 0x67, 0x80, 0x28, 0x2f, 0x32, 0x97, 0x9d, 0xd7, 0x28, 0xcd,
- 0xb7, 0x25, 0xce, 0x12, 0x7f, 0xad, 0xfd, 0x38, 0xe8, 0x3b, 0xdc, 0xb3,
- 0xbb, 0xe5, 0x06, 0x51, 0x17, 0x9f, 0xb6, 0xb6, 0x2a, 0x8c, 0x5d, 0x94,
- 0xe5, 0x58, 0xa6, 0x5b, 0x66, 0xab, 0x36, 0xbf, 0x4d, 0x65, 0x2c, 0x96,
- 0x67, 0x95, 0x32, 0xa7, 0x74, 0xdc, 0x90, 0xe8, 0xef, 0x76, 0x3b, 0xa4,
- 0xe8, 0x52, 0x9e, 0x87, 0x64, 0xbd, 0x36, 0xdd, 0x94, 0x03, 0xdc, 0x66,
- 0xe4, 0xec, 0xef, 0xa2, 0xd2, 0xc9, 0x38, 0x52, 0xb8, 0xa7, 0x87, 0xa4,
- 0x58, 0x6b, 0x3e, 0x67, 0x60, 0x9e, 0x11, 0xe5, 0xb6, 0xbf, 0x69, 0xef,
- 0x31, 0x57, 0x0f, 0xb8, 0x2a, 0x4e, 0x9f, 0x95, 0xf5, 0xf6, 0x1a, 0x7b,
- 0xfb, 0x15, 0xac, 0xc7, 0xfb, 0x2d, 0xf1, 0x48, 0x1b, 0x6c, 0x84, 0xc9,
- 0x35, 0x3e, 0x1c, 0x2f, 0xc3, 0x3f, 0x1b, 0x32, 0xe3, 0xde, 0x81, 0x7b,
- 0xd6, 0xdd, 0x67, 0xde, 0xef, 0x37, 0xf7, 0x9d, 0xe6, 0x3e, 0x82, 0x7b,
- 0xe6, 0x8d, 0xb3, 0x4f, 0x96, 0xfc, 0x9e, 0x88, 0xdf, 0xeb, 0x64, 0x25,
- 0x7a, 0x11, 0xe8, 0xa9, 0xd1, 0x29, 0x9f, 0xae, 0x29, 0xfe, 0x5a, 0xde,
- 0x12, 0x01, 0xc1, 0x7e, 0x73, 0x7d, 0xeb, 0x1e, 0xfc, 0xdc, 0x4d, 0xdf,
- 0x4a, 0x55, 0x8c, 0xac, 0x34, 0xd3, 0x9b, 0x03, 0xad, 0xef, 0x96, 0x83,
- 0x45, 0x1b, 0xa5, 0xfd, 0xc6, 0x62, 0x45, 0xe7, 0x1a, 0x1d, 0x83, 0xdf,
- 0x78, 0xb8, 0xfa, 0xa8, 0xab, 0xf3, 0x62, 0xc2, 0x5c, 0xca, 0x4e, 0xcc,
- 0x6b, 0xc8, 0x9c, 0x5b, 0xb3, 0x2d, 0x73, 0x3a, 0xc3, 0xf3, 0x99, 0x66,
- 0xac, 0x4a, 0x5b, 0x44, 0x3b, 0xc3, 0xef, 0x9a, 0x7c, 0xd4, 0x5d, 0xa4,
- 0xae, 0x69, 0xca, 0xcd, 0xff, 0x52, 0x4b, 0x6e, 0x3e, 0xbf, 0xfb, 0x16,
- 0xf9, 0x6f, 0x0d, 0xc6, 0x95, 0x3a, 0x24, 0x72, 0x36, 0xcc, 0xc1, 0xe2,
- 0x1a, 0x13, 0x87, 0xf1, 0x7b, 0xef, 0xa9, 0x5d, 0x62, 0x4e, 0xa1, 0x9c,
- 0x7f, 0xc7, 0x65, 0x7e, 0xab, 0x9b, 0x0d, 0xe3, 0x54, 0xcc, 0xeb, 0x21,
- 0xe6, 0x3a, 0x60, 0x62, 0x0a, 0x7c, 0x57, 0x96, 0x9e, 0x83, 0x53, 0xdc,
- 0x1b, 0xbf, 0x1d, 0xd9, 0xce, 0xfd, 0x57, 0xe3, 0xc4, 0x35, 0x86, 0xe4,
- 0x77, 0xe3, 0x3e, 0xf6, 0xd5, 0x9e, 0xcd, 0xf0, 0x9b, 0x8c, 0xcb, 0x8d,
- 0x8c, 0xfa, 0xf6, 0x83, 0x67, 0x1e, 0x5b, 0x0d, 0xee, 0x3b, 0x7e, 0x23,
- 0x9e, 0x55, 0x39, 0x01, 0x5b, 0xe6, 0x9b, 0xe7, 0xab, 0x0d, 0xfd, 0x1d,
- 0xcb, 0xe2, 0xb2, 0xca, 0xcb, 0x07, 0x56, 0x4b, 0xe2, 0x3d, 0x73, 0xe8,
- 0xfa, 0x55, 0x2e, 0xc1, 0x7c, 0xe3, 0x53, 0x28, 0x3f, 0x2f, 0x6b, 0x15,
- 0x1d, 0x7f, 0x9d, 0x6f, 0x30, 0xa7, 0xc0, 0x55, 0x67, 0x44, 0x03, 0x4b,
- 0x45, 0x8c, 0x17, 0x7e, 0xb3, 0x1d, 0xc7, 0x33, 0xd2, 0x57, 0x36, 0x7b,
- 0x34, 0xcc, 0x05, 0xe9, 0xea, 0xa1, 0x4d, 0x28, 0x37, 0xba, 0x54, 0x1e,
- 0x82, 0xc6, 0x23, 0xc4, 0x7a, 0x31, 0xd4, 0xe5, 0x5c, 0x3b, 0x69, 0xaf,
- 0x02, 0xea, 0xa4, 0x34, 0xc6, 0xa9, 0xab, 0xdc, 0x44, 0xf2, 0xd9, 0x73,
- 0x4b, 0xf4, 0xd7, 0x94, 0x8e, 0x4f, 0x0d, 0xcf, 0x48, 0xc1, 0x8d, 0xc2,
- 0x17, 0x9b, 0x57, 0x7e, 0xce, 0xfd, 0xc0, 0xd0, 0x5d, 0x9b, 0x91, 0x2c,
- 0xe7, 0xc6, 0xb1, 0xe9, 0x87, 0xe8, 0xf9, 0xe8, 0x33, 0x02, 0xb1, 0xe6,
- 0xd5, 0xf7, 0x8f, 0x7c, 0xce, 0x78, 0x6f, 0xf8, 0xcd, 0x90, 0xfe, 0x26,
- 0x64, 0xa6, 0x71, 0x44, 0x4e, 0x55, 0xf6, 0xf2, 0x5b, 0x09, 0x7f, 0x0b,
- 0x7c, 0x3b, 0xd6, 0xe8, 0x52, 0xdf, 0xa5, 0xcc, 0x34, 0x98, 0x3f, 0x17,
- 0xda, 0x1e, 0xae, 0x55, 0xdc, 0x7c, 0x37, 0x91, 0x30, 0xdf, 0x4d, 0xf0,
- 0xdb, 0x8f, 0x1f, 0xed, 0x0d, 0xf7, 0xfb, 0xad, 0x38, 0x9c, 0x32, 0xf8,
- 0xa7, 0xf0, 0x0d, 0xc3, 0x3c, 0x4c, 0xe6, 0x8b, 0x06, 0xc1, 0x31, 0x9f,
- 0xf1, 0xdb, 0xe9, 0xc3, 0x6b, 0x98, 0xe3, 0x95, 0x1a, 0x78, 0x78, 0x94,
- 0xcf, 0x98, 0x37, 0xd6, 0x2e, 0xf9, 0xd1, 0x76, 0xea, 0xf2, 0xce, 0x35,
- 0x6f, 0xaf, 0x5c, 0xae, 0xc6, 0x55, 0x0e, 0x5c, 0x09, 0x38, 0xbf, 0x2e,
- 0x1f, 0xeb, 0xe1, 0xd9, 0xdd, 0x84, 0x6a, 0x1f, 0xee, 0x77, 0x1d, 0x37,
- 0x98, 0x58, 0xd7, 0xfa, 0xe4, 0x78, 0x06, 0xb8, 0xe5, 0x82, 0x58, 0x7f,
- 0x90, 0xe9, 0x87, 0xef, 0xcd, 0xb1, 0xd2, 0x68, 0x07, 0xd9, 0x49, 0x70,
- 0xaf, 0xbf, 0x13, 0xd4, 0x41, 0xef, 0x8d, 0x06, 0xf1, 0x3a, 0x30, 0xd4,
- 0x34, 0xdb, 0x64, 0xc5, 0x3e, 0xc3, 0x3a, 0xbd, 0x90, 0xbf, 0x28, 0xe6,
- 0xe3, 0xc0, 0x17, 0xd8, 0x27, 0x75, 0x97, 0xef, 0x1c, 0x7d, 0xa6, 0x12,
- 0x0f, 0xfd, 0x94, 0xef, 0x81, 0x7f, 0x49, 0xa5, 0x93, 0xc2, 0xf3, 0x4e,
- 0xe6, 0xb3, 0xce, 0x56, 0x27, 0xb1, 0x87, 0x1c, 0x83, 0xcd, 0x1c, 0xf4,
- 0xf1, 0xe1, 0x1e, 0x8d, 0x15, 0x78, 0x1e, 0xaa, 0xb1, 0x88, 0xb6, 0x31,
- 0x3c, 0xdf, 0x71, 0xe0, 0x0b, 0x84, 0xfb, 0xf2, 0x99, 0x7d, 0x37, 0x7f,
- 0x0b, 0x43, 0x1c, 0x93, 0x4e, 0x9c, 0xe7, 0x79, 0xdc, 0xc6, 0xc3, 0x32,
- 0x03, 0x9a, 0x4f, 0x9b, 0x79, 0x3e, 0x98, 0xf1, 0xe4, 0x7a, 0x8d, 0xe7,
- 0x95, 0x07, 0x50, 0x32, 0xd7, 0x91, 0x34, 0x8f, 0x98, 0x7c, 0xce, 0x2c,
- 0xe6, 0xfa, 0x98, 0xbc, 0x01, 0x7c, 0xfd, 0x66, 0x25, 0xed, 0x4f, 0xa8,
- 0x3c, 0xa4, 0x54, 0xe2, 0xb2, 0x8c, 0x24, 0xe9, 0x03, 0x96, 0xdd, 0x54,
- 0xe2, 0x3a, 0xe4, 0xe1, 0x46, 0xe5, 0x99, 0x1e, 0xfe, 0xaf, 0x8a, 0x3a,
- 0xec, 0xe1, 0x0d, 0x95, 0x83, 0x94, 0x62, 0xcc, 0x04, 0xf7, 0xfd, 0x26,
- 0x0f, 0x8a, 0xe3, 0xf0, 0x5d, 0xbf, 0xbc, 0x51, 0xd9, 0xb6, 0xbf, 0x1c,
- 0xc7, 0x7c, 0x03, 0xcf, 0xb1, 0x2e, 0xf4, 0x50, 0x0f, 0x71, 0x3c, 0xdd,
- 0x47, 0x58, 0x87, 0x7c, 0x0d, 0xe3, 0x9a, 0xea, 0x5b, 0xcb, 0xa4, 0x58,
- 0x96, 0xb4, 0x79, 0x9c, 0xfb, 0x54, 0x8f, 0xc6, 0x40, 0x6c, 0x97, 0x76,
- 0x0f, 0xab, 0xfe, 0x78, 0xb6, 0xc7, 0xf3, 0xaf, 0xb0, 0x1f, 0xe6, 0x43,
- 0x31, 0xe7, 0x8a, 0xba, 0xaf, 0x99, 0x06, 0x6d, 0xff, 0xdf, 0x50, 0xb1,
- 0xf4, 0x71, 0xd4, 0xa7, 0x8d, 0x86, 0xbc, 0xd4, 0x12, 0xdb, 0xdf, 0x7c,
- 0x68, 0x5e, 0xf2, 0xfa, 0x99, 0xed, 0x6f, 0x32, 0xec, 0xbb, 0x5d, 0xf3,
- 0x3e, 0xc4, 0xa5, 0xfd, 0xd8, 0xaf, 0x8f, 0x49, 0x7d, 0x25, 0x9d, 0xf8,
- 0xb4, 0x84, 0xfd, 0x06, 0x87, 0x78, 0xde, 0x51, 0xcc, 0x8c, 0xb8, 0x0b,
- 0x8a, 0x9e, 0x54, 0x82, 0x39, 0xc8, 0x97, 0x31, 0x5e, 0xbd, 0xd1, 0x1a,
- 0x7b, 0x48, 0xe5, 0x36, 0x25, 0xed, 0xeb, 0xb5, 0x19, 0x92, 0x4d, 0xac,
- 0xcd, 0x9f, 0x9b, 0xb5, 0xf9, 0x18, 0xfa, 0xf6, 0xce, 0x8c, 0x4a, 0xfa,
- 0x4c, 0x3a, 0x79, 0x5a, 0x78, 0x96, 0xb8, 0x8f, 0x31, 0x2c, 0xeb, 0xc1,
- 0x4c, 0x12, 0xf3, 0x4d, 0x61, 0xbe, 0x28, 0x1b, 0xbc, 0x1e, 0x81, 0x6f,
- 0xbe, 0x87, 0x7b, 0xfb, 0x10, 0x75, 0x26, 0x79, 0x51, 0x54, 0xef, 0x80,
- 0x4f, 0x9e, 0x26, 0x4d, 0x00, 0xca, 0x9d, 0x29, 0x15, 0x07, 0xbc, 0xde,
- 0xe0, 0xf9, 0xa2, 0xa6, 0xaf, 0x00, 0xfa, 0xe6, 0x34, 0x7d, 0xc9, 0x99,
- 0x6d, 0xec, 0x9a, 0x4a, 0x9c, 0x12, 0xe2, 0x25, 0xe2, 0x17, 0xe2, 0xfa,
- 0x47, 0x7a, 0xc3, 0x6f, 0x5a, 0xf2, 0x77, 0xe7, 0xb6, 0xe7, 0xde, 0x86,
- 0xba, 0x57, 0x32, 0x2a, 0xbf, 0xd9, 0x3d, 0x22, 0x1f, 0x91, 0xdc, 0xa7,
- 0x52, 0xc9, 0x9c, 0xe5, 0x19, 0x0c, 0x88, 0xb2, 0xc6, 0x6b, 0xea, 0x5c,
- 0xcf, 0x60, 0x0b, 0xae, 0x4d, 0x06, 0x63, 0x29, 0xde, 0xc2, 0x67, 0xea,
- 0x87, 0xcc, 0x53, 0xd6, 0x7e, 0x07, 0x7b, 0x48, 0xff, 0x9f, 0x8e, 0xcb,
- 0xe0, 0xe3, 0x3c, 0xf8, 0x78, 0xfc, 0x16, 0x0c, 0x16, 0xdd, 0xc6, 0x60,
- 0x5b, 0x6a, 0xbc, 0x7b, 0x41, 0x53, 0xc1, 0x25, 0xfe, 0x9a, 0xdf, 0x96,
- 0x15, 0xd2, 0x34, 0xca, 0xff, 0xb5, 0x23, 0x57, 0x33, 0x5c, 0x0f, 0x60,
- 0x30, 0xf4, 0xb7, 0xb6, 0x23, 0x4b, 0x98, 0xbf, 0x92, 0x5f, 0xc8, 0x6e,
- 0xca, 0x75, 0x2c, 0xae, 0x05, 0xfb, 0x13, 0xeb, 0x1a, 0x68, 0xd9, 0x52,
- 0x72, 0xa0, 0x65, 0x60, 0xab, 0xd6, 0xf9, 0x1e, 0x32, 0xc0, 0x79, 0x52,
- 0xfe, 0x42, 0xd9, 0xdb, 0xc9, 0xa7, 0xe8, 0x00, 0x4f, 0x3e, 0x78, 0x4f,
- 0x56, 0xf2, 0x67, 0x78, 0x16, 0x26, 0xd6, 0xc8, 0x3d, 0x94, 0x49, 0xe2,
- 0x04, 0x60, 0xc8, 0x04, 0x79, 0xac, 0xf1, 0xe0, 0xcc, 0xb3, 0x7b, 0xf1,
- 0x7b, 0xb3, 0x87, 0x39, 0x33, 0xf9, 0x73, 0xd4, 0x57, 0x62, 0xdd, 0x79,
- 0x8f, 0xf6, 0x0f, 0x6f, 0xc4, 0xc1, 0x73, 0xbc, 0x1f, 0x78, 0xb2, 0x0d,
- 0xfa, 0xca, 0x31, 0xf3, 0xe6, 0x3d, 0xf9, 0x8a, 0xf2, 0xd9, 0x29, 0xa3,
- 0x03, 0xa8, 0x47, 0xc4, 0xec, 0x8b, 0xb2, 0xcc, 0x31, 0x46, 0x9f, 0xe9,
- 0x94, 0x09, 0xe8, 0xb5, 0x23, 0x95, 0x71, 0xf9, 0x72, 0xa5, 0x4b, 0xe1,
- 0x86, 0xbf, 0xf6, 0xd3, 0x89, 0x61, 0x2b, 0x90, 0x07, 0x81, 0x7f, 0x66,
- 0xfa, 0xdb, 0xe4, 0xcd, 0x51, 0x9d, 0xfb, 0x7b, 0x83, 0xc9, 0x8d, 0x2e,
- 0xf3, 0x55, 0x39, 0x1f, 0xe8, 0x7d, 0x0b, 0xbe, 0x80, 0xd5, 0x2e, 0x33,
- 0xf1, 0x2e, 0xf9, 0xb8, 0x8f, 0xf2, 0x36, 0x5f, 0x7d, 0x63, 0x9c, 0x8b,
- 0x37, 0xeb, 0x91, 0x37, 0xcd, 0xd8, 0x5f, 0x34, 0xe5, 0xbf, 0xe9, 0x6d,
- 0xa2, 0xc5, 0x9a, 0xcb, 0x44, 0xd4, 0xfc, 0xe6, 0x6b, 0xd4, 0x6f, 0x6c,
- 0x03, 0x7d, 0xd2, 0xe0, 0x39, 0x51, 0x59, 0xd6, 0xa0, 0x5f, 0x4a, 0x55,
- 0xb1, 0xce, 0x65, 0x80, 0xa8, 0x3d, 0x8d, 0x3f, 0x4b, 0x90, 0xaf, 0xd9,
- 0xaa, 0x8a, 0x59, 0xaa, 0xbc, 0xed, 0x59, 0x60, 0x5d, 0xf8, 0xc4, 0xc0,
- 0x10, 0x26, 0x7f, 0xa5, 0x93, 0xf1, 0x90, 0x66, 0x1d, 0x16, 0xfe, 0x2f,
- 0x9d, 0xff, 0xd4, 0x2b, 0xdd, 0x65, 0xac, 0x4b, 0x88, 0xb9, 0xc1, 0x53,
- 0x8c, 0x99, 0x57, 0xeb, 0x14, 0xae, 0x09, 0x75, 0x4f, 0x73, 0xbe, 0x78,
- 0x88, 0x39, 0xb8, 0x67, 0x69, 0x2f, 0xa4, 0x1c, 0x03, 0xa6, 0xed, 0x38,
- 0x03, 0xdb, 0x5d, 0xcd, 0x42, 0x56, 0xc6, 0x55, 0xde, 0xe7, 0x3c, 0xb0,
- 0xdb, 0x1f, 0xf8, 0x7f, 0x2a, 0xf6, 0xd3, 0x07, 0x64, 0xad, 0xda, 0x01,
- 0x7e, 0xd0, 0x2e, 0x44, 0x95, 0x7f, 0x7d, 0xe3, 0x28, 0xed, 0x1d, 0x6d,
- 0x89, 0x5e, 0x8b, 0xad, 0xda, 0xf7, 0x7a, 0xf5, 0xb7, 0x33, 0x7b, 0x65,
- 0xb3, 0x16, 0xda, 0x42, 0xf8, 0x87, 0xd5, 0xa8, 0xb1, 0xcb, 0x9d, 0xd0,
- 0xdd, 0xdf, 0x8f, 0xd6, 0x95, 0xaf, 0xce, 0xf9, 0xd3, 0x06, 0x45, 0x99,
- 0x17, 0xd7, 0x59, 0xf7, 0x38, 0xf7, 0x66, 0x1b, 0xa4, 0x71, 0x87, 0x7b,
- 0x90, 0xe3, 0x31, 0x87, 0x82, 0x73, 0x8c, 0x4b, 0xf4, 0xfc, 0x63, 0x62,
- 0xc3, 0x6f, 0x89, 0x2c, 0x11, 0xeb, 0xdd, 0xec, 0xbb, 0x44, 0x2e, 0xba,
- 0xe6, 0x5b, 0xec, 0x41, 0x8d, 0x65, 0x32, 0x28, 0xeb, 0xe1, 0xf7, 0xd9,
- 0xfc, 0x35, 0xdb, 0xcd, 0xd0, 0xb7, 0xd8, 0xd5, 0x96, 0xe2, 0xef, 0xff,
- 0x01, 0x37, 0x64, 0x26, 0x2b, 0x1c, 0x4c, 0x00, 0x00, 0x00 };
+ 0xcd, 0x7c, 0x7b, 0x6c, 0x5c, 0xd7, 0x99, 0xdf, 0x77, 0xef, 0xcc, 0x90,
+ 0x43, 0x6a, 0x44, 0x5d, 0x32, 0x13, 0x66, 0x1c, 0x33, 0xcd, 0x3c, 0x2e,
+ 0x29, 0xda, 0x64, 0x92, 0x31, 0x77, 0xa4, 0xd0, 0xc9, 0xad, 0x3d, 0x99,
+ 0x19, 0xc9, 0x4c, 0xa8, 0x0d, 0xe8, 0x44, 0x2e, 0x52, 0x54, 0x28, 0xd8,
+ 0x21, 0xe5, 0x28, 0x8b, 0xec, 0xae, 0xf2, 0x28, 0x9a, 0x2e, 0xd2, 0xd5,
+ 0x64, 0x48, 0x29, 0xca, 0x62, 0xc4, 0x19, 0xd3, 0x34, 0x93, 0xa2, 0x01,
+ 0x32, 0x19, 0x92, 0x72, 0x76, 0x31, 0x12, 0x15, 0xdb, 0xcd, 0x1a, 0x41,
+ 0xe2, 0xb0, 0xd4, 0x23, 0xde, 0x20, 0x2d, 0xb4, 0x1b, 0x17, 0x4d, 0xd3,
+ 0x45, 0x21, 0xc8, 0x4e, 0x6c, 0x6c, 0xb3, 0x6d, 0x50, 0x2c, 0x10, 0x77,
+ 0x91, 0x64, 0xfa, 0xfb, 0x9d, 0x73, 0xee, 0x70, 0x44, 0x31, 0x4e, 0xba,
+ 0x7f, 0x95, 0xc0, 0xe0, 0xdc, 0x7b, 0x9e, 0xdf, 0xf9, 0xce, 0xf7, 0x3e,
+ 0xdf, 0xe5, 0x43, 0x22, 0xbd, 0x62, 0xfe, 0xf6, 0xe3, 0x97, 0xf9, 0xfd,
+ 0x3f, 0x9c, 0x7b, 0xe0, 0x9d, 0x87, 0xdf, 0x89, 0xc7, 0x43, 0xf6, 0x81,
+ 0xae, 0x20, 0xeb, 0x03, 0xf8, 0x45, 0xf1, 0x9b, 0x30, 0xcf, 0x7b, 0xfd,
+ 0x39, 0xf8, 0x1d, 0xb6, 0x44, 0x66, 0xff, 0x46, 0xc4, 0xda, 0xd5, 0x16,
+ 0xfe, 0x35, 0x63, 0xde, 0xe8, 0xcf, 0xfe, 0x2d, 0xfb, 0x39, 0xff, 0x80,
+ 0xb9, 0xfd, 0xbf, 0x80, 0x19, 0xbe, 0xdf, 0xfc, 0x24, 0x6c, 0x7b, 0xb7,
+ 0x3e, 0x90, 0x73, 0x25, 0x1c, 0xf0, 0x7e, 0x38, 0x3d, 0xe7, 0x8a, 0x64,
+ 0x9b, 0x63, 0xf1, 0xbc, 0xfc, 0xb2, 0x55, 0x8a, 0x06, 0x85, 0xf5, 0x6f,
+ 0xf3, 0x7e, 0xf1, 0x95, 0x6f, 0xbf, 0x3b, 0xf1, 0xb3, 0x7a, 0x40, 0xc2,
+ 0x8e, 0xf7, 0xba, 0x38, 0x23, 0x12, 0x1e, 0xc2, 0x98, 0x2f, 0x1f, 0x9c,
+ 0xb5, 0xa5, 0xcf, 0x9f, 0xeb, 0xb5, 0xd6, 0xb7, 0x0f, 0x4a, 0xc9, 0xf6,
+ 0x1c, 0xb9, 0xb2, 0x19, 0x95, 0xef, 0x6c, 0x8a, 0x35, 0x93, 0xe9, 0x11,
+ 0x7b, 0xf9, 0xad, 0x92, 0x75, 0x2c, 0x09, 0xb8, 0x5c, 0x27, 0x2e, 0xb9,
+ 0xca, 0x20, 0xde, 0x13, 0x31, 0x91, 0x7f, 0xbe, 0x5f, 0x8f, 0x0d, 0x4b,
+ 0x60, 0x55, 0xc2, 0x5d, 0xde, 0x0b, 0xd3, 0x37, 0x56, 0x62, 0x12, 0x5c,
+ 0x1a, 0x97, 0x72, 0x35, 0x22, 0xa1, 0x55, 0x19, 0x0a, 0xc8, 0x70, 0xec,
+ 0x71, 0xf4, 0x28, 0x34, 0x83, 0x72, 0xa4, 0x69, 0x49, 0xd0, 0x0d, 0x03,
+ 0xb6, 0x08, 0x7e, 0x0e, 0x7e, 0x51, 0xfc, 0x62, 0xf8, 0x9d, 0xc5, 0x3c,
+ 0x43, 0x92, 0x6f, 0x72, 0x4e, 0xac, 0x5b, 0xc5, 0xfa, 0xd5, 0x84, 0x33,
+ 0x8b, 0x79, 0x6f, 0x05, 0x62, 0xf2, 0xed, 0x83, 0x84, 0xcb, 0x21, 0x3c,
+ 0x80, 0x2d, 0x6c, 0xe5, 0x56, 0xe4, 0x74, 0x3e, 0x2d, 0x71, 0xdb, 0xed,
+ 0x95, 0xa2, 0x63, 0xc5, 0xe7, 0x47, 0x07, 0xa4, 0x74, 0x1c, 0xed, 0x55,
+ 0xc9, 0xda, 0x98, 0xbf, 0xe8, 0xc8, 0xac, 0x6e, 0x63, 0xdd, 0x17, 0x41,
+ 0x27, 0x09, 0x87, 0x08, 0xfb, 0x4e, 0xf5, 0x31, 0x3c, 0x73, 0xbe, 0x78,
+ 0x50, 0xc3, 0xbd, 0x8a, 0x77, 0xd6, 0xff, 0x41, 0x44, 0xbf, 0xf3, 0x99,
+ 0x7d, 0xfd, 0x75, 0xfd, 0xfd, 0x72, 0xfd, 0x51, 0xec, 0x99, 0x30, 0xf8,
+ 0x7b, 0x96, 0x52, 0x08, 0xb0, 0x34, 0x56, 0x22, 0xd6, 0xda, 0xca, 0xb8,
+ 0x9c, 0xab, 0x3e, 0x24, 0xb9, 0x74, 0xab, 0x35, 0x97, 0x96, 0xa8, 0x2d,
+ 0xc3, 0x4e, 0x1e, 0x1d, 0xb6, 0x9b, 0x62, 0x35, 0x2a, 0x12, 0xee, 0x06,
+ 0x5e, 0x5e, 0x5d, 0xe1, 0xdc, 0x41, 0xd4, 0x0d, 0xa2, 0x7f, 0x9f, 0xb5,
+ 0xbe, 0x02, 0xf8, 0x3d, 0xe2, 0xa7, 0xd5, 0x5a, 0x4c, 0x0f, 0xc7, 0xe6,
+ 0xb1, 0xe6, 0xd5, 0xe6, 0xf0, 0xe4, 0x6d, 0x71, 0x30, 0xe7, 0x00, 0xfa,
+ 0x10, 0x57, 0x9c, 0x8b, 0x73, 0x72, 0xbe, 0x08, 0xc6, 0x46, 0xd1, 0x46,
+ 0xb8, 0x5a, 0xad, 0x5c, 0xda, 0xe1, 0xbb, 0x6c, 0x01, 0x7f, 0x5b, 0xc4,
+ 0x5f, 0xef, 0x90, 0x7c, 0xb7, 0xc9, 0x35, 0xda, 0xb0, 0x97, 0xba, 0xbc,
+ 0xe7, 0xed, 0xed, 0x0a, 0xcf, 0x2d, 0x2c, 0xef, 0x0b, 0x26, 0x46, 0x4b,
+ 0x8a, 0x4e, 0x66, 0xb1, 0x1f, 0x4b, 0xd1, 0x84, 0x85, 0xe7, 0x64, 0x93,
+ 0xfd, 0x89, 0xeb, 0xb8, 0x2c, 0xe0, 0x5c, 0xcb, 0x2b, 0x25, 0xfb, 0x6a,
+ 0xf3, 0x17, 0xad, 0x9c, 0xbb, 0x68, 0x6f, 0xaf, 0xb3, 0xff, 0x09, 0xf4,
+ 0x0f, 0xca, 0x62, 0xa5, 0x4f, 0x08, 0x93, 0x1e, 0x77, 0x02, 0xe3, 0xc4,
+ 0xb1, 0xbd, 0x73, 0xf6, 0xd5, 0xf5, 0xf3, 0xf6, 0x35, 0x75, 0x6e, 0x58,
+ 0xab, 0x3d, 0x57, 0x27, 0xde, 0xc6, 0xfe, 0x3f, 0xc4, 0x5b, 0x0c, 0xf3,
+ 0x47, 0x51, 0xee, 0xb3, 0x1a, 0xb5, 0x16, 0xd6, 0x8f, 0xe1, 0x79, 0x2f,
+ 0x1c, 0xde, 0x52, 0x74, 0x77, 0x05, 0x74, 0xe7, 0x78, 0x31, 0x79, 0x66,
+ 0x73, 0x08, 0xfb, 0x88, 0xca, 0xd7, 0xc1, 0x17, 0x03, 0x87, 0xf7, 0x49,
+ 0x1e, 0x7c, 0x41, 0x7a, 0x7b, 0x74, 0xf5, 0x9f, 0x49, 0x31, 0x9a, 0x18,
+ 0xa5, 0xfc, 0x48, 0x4e, 0x80, 0x9e, 0x0d, 0x6b, 0xe7, 0x96, 0xb2, 0x29,
+ 0x5b, 0x1e, 0x16, 0xdb, 0xc3, 0xba, 0x99, 0x31, 0xa7, 0x20, 0x41, 0xb4,
+ 0x65, 0x25, 0xe0, 0x45, 0x25, 0xb7, 0xfa, 0x5e, 0x0b, 0x74, 0x19, 0x5f,
+ 0xc0, 0xa0, 0xc0, 0x92, 0x58, 0xb6, 0xdb, 0x25, 0xc5, 0xe3, 0xac, 0x0f,
+ 0x83, 0xc6, 0xc1, 0xb3, 0x2b, 0x07, 0x00, 0x97, 0x0c, 0xdb, 0xc2, 0xba,
+ 0x61, 0xa7, 0x2c, 0x25, 0xb1, 0x2f, 0xff, 0xa1, 0x65, 0x64, 0x9e, 0xc1,
+ 0xef, 0xa8, 0x59, 0xab, 0xcd, 0x87, 0x96, 0xbd, 0x1a, 0xb1, 0x02, 0xab,
+ 0xe3, 0x72, 0x76, 0x0f, 0xbc, 0x36, 0x80, 0x57, 0x7b, 0xc9, 0xe7, 0xd3,
+ 0x20, 0xde, 0x07, 0xd1, 0xb7, 0xcf, 0x0a, 0xae, 0xde, 0x8d, 0xd3, 0xb5,
+ 0xe6, 0x70, 0x7a, 0x1b, 0x38, 0xb5, 0x57, 0x07, 0xd0, 0xe7, 0x6e, 0x9c,
+ 0x36, 0x80, 0x53, 0x7b, 0x55, 0xe3, 0xb3, 0x01, 0x7c, 0xda, 0x4b, 0x51,
+ 0x94, 0xfb, 0x2c, 0x7b, 0x59, 0xe3, 0xb3, 0x61, 0x78, 0xfa, 0x62, 0x93,
+ 0xb0, 0x66, 0x3b, 0x68, 0x2e, 0x4b, 0xda, 0x81, 0x9c, 0x2a, 0xc8, 0x5c,
+ 0xc5, 0x06, 0xbe, 0x82, 0xe2, 0x4e, 0x58, 0x32, 0xa7, 0xda, 0x0a, 0x92,
+ 0x02, 0x0d, 0x95, 0x9c, 0xb1, 0x51, 0x5b, 0x12, 0xf1, 0xac, 0x0d, 0x7c,
+ 0x57, 0x81, 0xf7, 0x2a, 0x70, 0xae, 0x64, 0xc2, 0x8b, 0xe0, 0xd7, 0x38,
+ 0xce, 0x65, 0x77, 0x7d, 0xc2, 0xa9, 0x2b, 0x9e, 0x8d, 0x9b, 0x33, 0x23,
+ 0xed, 0xf3, 0x9c, 0x62, 0x38, 0x2f, 0x75, 0x7e, 0xd6, 0x5f, 0x66, 0xf6,
+ 0x49, 0x6a, 0x39, 0xa0, 0xce, 0x2b, 0xbd, 0xfa, 0xae, 0xf6, 0x79, 0xd9,
+ 0x13, 0x94, 0x65, 0x3c, 0x23, 0x91, 0xd4, 0x12, 0xcf, 0x29, 0x9b, 0x0a,
+ 0x08, 0xcf, 0x2a, 0x24, 0xd9, 0x19, 0x9e, 0x4b, 0x54, 0x92, 0xab, 0x3c,
+ 0xb3, 0x0d, 0x73, 0x5e, 0xfa, 0x9c, 0x92, 0x7b, 0x9c, 0x53, 0xd2, 0x9c,
+ 0xd3, 0x76, 0xf3, 0x8a, 0x39, 0xa7, 0x7f, 0x2b, 0x86, 0xe6, 0xdf, 0x10,
+ 0x07, 0x36, 0x70, 0x10, 0xbc, 0x03, 0x07, 0xdd, 0x6d, 0x1c, 0xc4, 0x6d,
+ 0xec, 0xe1, 0xae, 0xfd, 0x77, 0xd6, 0x75, 0xee, 0x5d, 0x4a, 0x41, 0x4f,
+ 0xac, 0x85, 0x0a, 0xe1, 0x0e, 0x48, 0x71, 0x86, 0x30, 0x52, 0xae, 0x6b,
+ 0x58, 0xf3, 0x2b, 0x94, 0x6d, 0x07, 0x04, 0x34, 0xf1, 0xb6, 0x80, 0x1a,
+ 0x53, 0x92, 0x85, 0x26, 0xdb, 0x4a, 0x92, 0xcb, 0x80, 0x5e, 0x6b, 0xac,
+ 0x03, 0x83, 0x6e, 0x6a, 0x3e, 0xde, 0xd1, 0x07, 0xd1, 0x36, 0x1e, 0xf3,
+ 0x95, 0x38, 0xe4, 0x74, 0x10, 0xe5, 0xd7, 0x50, 0xee, 0xb3, 0x66, 0x6a,
+ 0x7f, 0x65, 0x49, 0x5f, 0x4b, 0x9c, 0x09, 0xee, 0x31, 0x36, 0x9d, 0x73,
+ 0x4b, 0x31, 0x47, 0xde, 0x26, 0xce, 0x3b, 0x43, 0x22, 0x83, 0x09, 0xa7,
+ 0x28, 0xff, 0x05, 0xed, 0x89, 0x58, 0x56, 0xfe, 0xb7, 0x4f, 0xbb, 0xc0,
+ 0x43, 0xcf, 0xeb, 0x59, 0xf5, 0xc4, 0x7a, 0x8e, 0xcb, 0xa0, 0x2e, 0x24,
+ 0xb3, 0xd0, 0x31, 0x05, 0x97, 0xeb, 0x71, 0xfe, 0xf8, 0x2c, 0xd7, 0xcd,
+ 0x37, 0x7d, 0x7d, 0x20, 0xd9, 0x80, 0xc7, 0x36, 0xf2, 0xe5, 0xa4, 0x95,
+ 0x6f, 0x12, 0x57, 0x19, 0x71, 0x9b, 0x1a, 0x66, 0x0d, 0x6b, 0x1b, 0x4e,
+ 0xf0, 0x6b, 0x16, 0x34, 0x49, 0xd8, 0xe2, 0xe0, 0x9b, 0x73, 0x01, 0xff,
+ 0x1c, 0x82, 0xde, 0xa4, 0x2c, 0x42, 0x3f, 0x96, 0x2b, 0x9c, 0xef, 0x33,
+ 0x56, 0xe0, 0xb2, 0x3f, 0x3f, 0xcf, 0x86, 0x73, 0xeb, 0xf9, 0xca, 0xcd,
+ 0xd7, 0x0c, 0xef, 0x2b, 0x3d, 0x88, 0xf9, 0x4a, 0x1d, 0xf3, 0x95, 0xc8,
+ 0xb3, 0x07, 0x94, 0xae, 0x39, 0x4e, 0xfc, 0x9d, 0x47, 0xdb, 0x2d, 0xd0,
+ 0x08, 0xf9, 0x81, 0xfc, 0x41, 0x5e, 0x7d, 0xb7, 0x8d, 0xfd, 0x76, 0xe0,
+ 0x76, 0x06, 0x72, 0x98, 0xbc, 0x11, 0x96, 0x7c, 0x94, 0xf5, 0x8f, 0x1b,
+ 0x98, 0x20, 0x13, 0xd4, 0xfb, 0xf1, 0x1e, 0x5f, 0x3e, 0x82, 0x16, 0x01,
+ 0xdb, 0xf3, 0x6a, 0x8f, 0xb6, 0xe7, 0x01, 0x37, 0x9d, 0x30, 0x72, 0xdf,
+ 0x9e, 0x91, 0xdb, 0x3e, 0xbc, 0x3c, 0x2b, 0xca, 0x55, 0xb1, 0xd6, 0x33,
+ 0x61, 0xc8, 0x70, 0x5b, 0xf2, 0x69, 0xd0, 0x66, 0x3a, 0x60, 0xe4, 0xc3,
+ 0x8b, 0xc6, 0x56, 0xd2, 0x38, 0x0e, 0x2a, 0x3d, 0xbe, 0x88, 0x79, 0x4f,
+ 0x00, 0x46, 0xce, 0x19, 0xb4, 0xd6, 0x2a, 0x11, 0xe8, 0x6c, 0xc0, 0xe6,
+ 0x24, 0xe2, 0x80, 0x09, 0xef, 0x7e, 0x9f, 0x88, 0x2c, 0x6c, 0xfa, 0xeb,
+ 0x2e, 0xb6, 0xf5, 0x45, 0x49, 0xe1, 0xdb, 0x99, 0x0d, 0xec, 0xd0, 0xc6,
+ 0xcc, 0xc9, 0xca, 0x99, 0x96, 0xed, 0x92, 0x06, 0xdd, 0xd1, 0x86, 0x44,
+ 0x26, 0x37, 0x32, 0xef, 0x06, 0xbf, 0xa1, 0x1e, 0x63, 0xca, 0xcd, 0x52,
+ 0xc4, 0x76, 0x5d, 0x94, 0x94, 0x3f, 0x27, 0xba, 0x6f, 0xb8, 0x3e, 0xbd,
+ 0x0c, 0x49, 0xc8, 0x6d, 0xb5, 0x36, 0x70, 0x26, 0x47, 0x9b, 0xbf, 0x6c,
+ 0x7d, 0x35, 0xa8, 0xed, 0x15, 0xdb, 0xfb, 0xa9, 0xa5, 0xd7, 0x8c, 0x4f,
+ 0x27, 0x15, 0x1e, 0x62, 0x5d, 0xfa, 0xdd, 0x35, 0xef, 0xd7, 0x22, 0x46,
+ 0x87, 0x99, 0xf7, 0xf9, 0xa0, 0xb6, 0x7f, 0xc2, 0x3d, 0xe4, 0xa3, 0xa0,
+ 0xe7, 0xf4, 0xe0, 0x9c, 0xc3, 0x21, 0x6f, 0x6a, 0x7c, 0x43, 0xf5, 0x2b,
+ 0x99, 0x7e, 0xd1, 0x6e, 0x3d, 0xee, 0xd4, 0xf4, 0x88, 0xa2, 0xa1, 0x4f,
+ 0x4f, 0x0f, 0xab, 0xf2, 0xb3, 0xd3, 0x29, 0x55, 0x2e, 0x4e, 0xbb, 0xaa,
+ 0x3c, 0xaf, 0xfa, 0x5b, 0xde, 0x90, 0xa9, 0x1f, 0x9d, 0x8e, 0xab, 0x72,
+ 0xdc, 0x94, 0x69, 0x53, 0x66, 0x4c, 0x39, 0x69, 0x4a, 0xcf, 0x94, 0x59,
+ 0x53, 0x16, 0xcc, 0x7c, 0x53, 0xe6, 0xfd, 0x98, 0x29, 0x67, 0x4c, 0x79,
+ 0xdc, 0x94, 0x1f, 0x31, 0xe5, 0x09, 0x03, 0xd7, 0xbc, 0x29, 0x3f, 0x6e,
+ 0xea, 0x4f, 0x1b, 0x38, 0x3f, 0x03, 0x78, 0x1e, 0x09, 0xed, 0xd0, 0xca,
+ 0x69, 0x4d, 0x5f, 0x15, 0x47, 0xca, 0x9b, 0xdc, 0x7f, 0x1c, 0x32, 0x25,
+ 0x88, 0xb3, 0x04, 0xbf, 0x3b, 0xa4, 0x09, 0x17, 0x72, 0x38, 0x88, 0x33,
+ 0xe4, 0xf3, 0x69, 0xf9, 0x53, 0xf4, 0x1d, 0xbd, 0xe0, 0xc8, 0x62, 0x95,
+ 0xfa, 0xf5, 0x5b, 0xf2, 0x6a, 0x85, 0xe7, 0xf1, 0xbc, 0xdc, 0xa8, 0xa4,
+ 0xe2, 0x41, 0x8b, 0x74, 0x94, 0x98, 0x7c, 0x45, 0x12, 0x90, 0xfd, 0x63,
+ 0x71, 0x96, 0xd7, 0xa8, 0x54, 0xd0, 0xef, 0xa0, 0x5a, 0xfb, 0x79, 0x01,
+ 0x4c, 0x72, 0xa5, 0xd2, 0x0d, 0x99, 0xf5, 0x4a, 0x8b, 0x7a, 0xfd, 0xfc,
+ 0xa6, 0xc8, 0xc8, 0x05, 0xe2, 0xf9, 0x5b, 0xb2, 0x51, 0x21, 0xde, 0x9f,
+ 0x87, 0xad, 0x90, 0x4a, 0xbf, 0x28, 0x89, 0xd1, 0x8b, 0xc2, 0xf9, 0xc6,
+ 0xd2, 0x28, 0xe3, 0x65, 0xfc, 0xce, 0x41, 0xde, 0x76, 0x4f, 0xe8, 0xf9,
+ 0x86, 0xcd, 0x7c, 0x2e, 0xec, 0xc2, 0x5b, 0x0e, 0x65, 0xe0, 0x7f, 0xb5,
+ 0xf4, 0x9e, 0xb4, 0x3c, 0xcc, 0x3a, 0x41, 0x96, 0xb6, 0xcf, 0x23, 0xf6,
+ 0xc4, 0xf5, 0x16, 0xe4, 0x31, 0xf9, 0xdf, 0xd4, 0x6d, 0x1b, 0xfe, 0x92,
+ 0x9a, 0xed, 0x81, 0x3e, 0x33, 0xc3, 0x58, 0x83, 0xef, 0x71, 0xd8, 0x9a,
+ 0x52, 0x22, 0x1e, 0x8a, 0x95, 0x5f, 0xb5, 0xb2, 0x41, 0x6d, 0x9f, 0x6a,
+ 0x19, 0xc1, 0x76, 0x4b, 0xf2, 0xe8, 0xbb, 0x60, 0x64, 0x66, 0xa1, 0x79,
+ 0x4b, 0xc9, 0x8d, 0xaf, 0x2b, 0x1a, 0x4e, 0x9c, 0x2f, 0x09, 0x75, 0x86,
+ 0x1d, 0xa0, 0x4c, 0xbb, 0x92, 0xae, 0xb7, 0x16, 0xaa, 0x94, 0xc1, 0xc3,
+ 0x52, 0xac, 0x0d, 0x97, 0x6c, 0x94, 0xa7, 0xeb, 0x31, 0x39, 0x5d, 0xe1,
+ 0x3c, 0xfb, 0xd1, 0xc7, 0x45, 0x1d, 0x18, 0x6b, 0x90, 0xf2, 0x98, 0x6b,
+ 0xbe, 0x6e, 0xe9, 0x35, 0xb1, 0x07, 0x77, 0xcb, 0xfa, 0x44, 0xf3, 0x9a,
+ 0x55, 0xac, 0xd3, 0x4e, 0x42, 0x7d, 0xb3, 0x53, 0x66, 0xfb, 0xf2, 0xfa,
+ 0x79, 0xac, 0x5d, 0xc0, 0x7a, 0x59, 0x25, 0xb3, 0xba, 0x21, 0xf7, 0x7e,
+ 0x52, 0xf9, 0x72, 0xab, 0x5c, 0x1d, 0x95, 0x8b, 0x9b, 0x71, 0x39, 0x52,
+ 0x19, 0x97, 0x8d, 0x4d, 0x4f, 0x0a, 0x95, 0xb4, 0xac, 0xa3, 0x4f, 0xbe,
+ 0x92, 0x91, 0xb5, 0xcd, 0x63, 0xea, 0xac, 0x2f, 0x42, 0x2e, 0x6d, 0xa0,
+ 0x4f, 0x63, 0x73, 0x12, 0x3f, 0xdf, 0x1e, 0x88, 0xa1, 0xdf, 0x10, 0xfa,
+ 0x88, 0xf5, 0xb3, 0xca, 0x3d, 0xc0, 0x21, 0xe6, 0xae, 0xfa, 0xb6, 0xc1,
+ 0xb8, 0x2c, 0x54, 0x79, 0x4e, 0x2f, 0x4c, 0x6f, 0xac, 0xc4, 0xb2, 0xd4,
+ 0x77, 0xa7, 0x9b, 0xc3, 0xe0, 0x53, 0xe8, 0xef, 0x2a, 0x65, 0x42, 0x50,
+ 0x8a, 0x90, 0xb5, 0x0d, 0xc0, 0x46, 0x58, 0x1b, 0xb0, 0xdf, 0x8b, 0xcd,
+ 0x21, 0x94, 0x0e, 0x4a, 0xac, 0x03, 0xd8, 0x8b, 0x4d, 0x17, 0x65, 0x0c,
+ 0xa5, 0xd6, 0xed, 0x27, 0x9b, 0x9c, 0x3f, 0xab, 0x74, 0x90, 0xc6, 0xf1,
+ 0xd4, 0x1d, 0xb6, 0x7a, 0xc0, 0x5b, 0xb4, 0x8a, 0x2b, 0x62, 0xe7, 0xd2,
+ 0x21, 0xfa, 0x0b, 0x90, 0x2b, 0x37, 0x0f, 0x68, 0x58, 0x3e, 0x1b, 0xa0,
+ 0xdc, 0x09, 0xba, 0xe7, 0x81, 0xaf, 0x5e, 0xc9, 0x06, 0x69, 0x73, 0xf1,
+ 0x59, 0x5a, 0x01, 0xcf, 0xa5, 0xad, 0x12, 0x0c, 0x50, 0x5f, 0x45, 0xd9,
+ 0xa7, 0xde, 0xa2, 0x5c, 0xca, 0xd5, 0xb4, 0x6d, 0x5e, 0x6a, 0xdb, 0xe6,
+ 0xeb, 0xa8, 0xb7, 0x20, 0x3b, 0xe0, 0x9b, 0xd4, 0x79, 0x1e, 0x03, 0x98,
+ 0x33, 0x6b, 0x15, 0x2a, 0xfe, 0x79, 0xd6, 0x5b, 0x4f, 0x54, 0x69, 0xaf,
+ 0xd1, 0x6e, 0x53, 0xf2, 0x49, 0x92, 0xcb, 0x71, 0x23, 0x83, 0x23, 0x8a,
+ 0x37, 0x88, 0x83, 0xe4, 0x72, 0xda, 0xd4, 0x75, 0x77, 0xd4, 0xf9, 0xb2,
+ 0xfa, 0x73, 0x80, 0x61, 0x48, 0x9d, 0xad, 0xed, 0x4d, 0x59, 0x39, 0x65,
+ 0x2b, 0xb6, 0x5a, 0x79, 0x37, 0x24, 0xc5, 0xf1, 0x3f, 0xc2, 0x9e, 0xd8,
+ 0x56, 0x72, 0x40, 0x5a, 0xe0, 0xbb, 0xca, 0x07, 0xe6, 0xdc, 0x84, 0xb2,
+ 0xb3, 0x72, 0x15, 0xf8, 0x38, 0x5a, 0xd5, 0x95, 0xfa, 0xa1, 0x87, 0xdc,
+ 0x25, 0xd2, 0x53, 0xbd, 0xb5, 0x0c, 0x9c, 0xce, 0x2c, 0x15, 0xac, 0xe4,
+ 0x12, 0xe8, 0x63, 0x10, 0xb6, 0x87, 0x1b, 0x91, 0xdc, 0x65, 0xd2, 0x11,
+ 0xfb, 0xb0, 0xbe, 0x4b, 0x66, 0xa2, 0xbb, 0x6d, 0x9b, 0x87, 0x0e, 0x68,
+ 0x9d, 0x8f, 0xbe, 0x4b, 0x70, 0xe6, 0x7a, 0xb5, 0x9f, 0x92, 0x5c, 0xa5,
+ 0x9c, 0x2d, 0x40, 0xd7, 0x53, 0xe7, 0xf4, 0xc0, 0x9e, 0x61, 0x3d, 0xe7,
+ 0x44, 0xdb, 0xc5, 0xac, 0x05, 0xfd, 0x66, 0x97, 0x95, 0x8d, 0x3e, 0x89,
+ 0xf2, 0xde, 0x20, 0x6d, 0x5b, 0xea, 0x90, 0xe4, 0xaa, 0x3f, 0x47, 0x27,
+ 0x3e, 0xf6, 0x29, 0x9d, 0x34, 0xe0, 0x0d, 0xa8, 0x79, 0x61, 0x97, 0x58,
+ 0x73, 0x6a, 0xde, 0x58, 0xc7, 0xbc, 0x68, 0xbb, 0xf8, 0xb7, 0x01, 0x3d,
+ 0x0f, 0xf0, 0xac, 0xf6, 0xc4, 0x36, 0x8e, 0x29, 0x58, 0x79, 0xd8, 0x4e,
+ 0x33, 0x69, 0x5b, 0x02, 0x83, 0x7e, 0x5f, 0xbd, 0xaf, 0x02, 0xf6, 0x95,
+ 0xc3, 0xbe, 0xec, 0xc1, 0xdd, 0xfb, 0x2a, 0x05, 0xf4, 0xbe, 0x06, 0x3a,
+ 0x60, 0x8a, 0xee, 0x5a, 0xbf, 0x73, 0x5f, 0x68, 0xbb, 0xb8, 0x7b, 0x8e,
+ 0xc7, 0x06, 0xf4, 0x1c, 0xd1, 0x8e, 0x39, 0x06, 0x77, 0xcd, 0x01, 0x7a,
+ 0x8e, 0x72, 0xfc, 0xe0, 0x1e, 0xe3, 0x5f, 0xef, 0xd5, 0xe3, 0x39, 0xa6,
+ 0x0b, 0x7a, 0x58, 0x9d, 0x75, 0x58, 0xc9, 0xd4, 0xb6, 0xad, 0x76, 0x1a,
+ 0x3a, 0xaf, 0x73, 0xcc, 0x9d, 0x76, 0xa6, 0xad, 0xec, 0xcc, 0x3b, 0xe8,
+ 0xcc, 0x7a, 0x14, 0x3e, 0x73, 0x6a, 0x19, 0xbe, 0x73, 0xe5, 0xed, 0x58,
+ 0xf7, 0xcf, 0xe0, 0x87, 0x42, 0x16, 0x8d, 0xd2, 0x2f, 0x98, 0x14, 0xe5,
+ 0x97, 0x8e, 0xc2, 0xff, 0x75, 0xf6, 0x29, 0x5b, 0xb4, 0x38, 0x3a, 0xee,
+ 0xfb, 0x0b, 0xd6, 0x2c, 0xe4, 0x46, 0x71, 0x14, 0x36, 0x7d, 0x14, 0xf8,
+ 0x72, 0x47, 0x30, 0x8e, 0xf0, 0xbc, 0x3b, 0x44, 0x9f, 0xf5, 0x99, 0xea,
+ 0x2c, 0xde, 0xf7, 0xa1, 0xfd, 0xe7, 0x06, 0xce, 0x3e, 0xf4, 0xf9, 0x57,
+ 0xa8, 0x63, 0x1b, 0xfb, 0x70, 0x8a, 0x1f, 0xe0, 0xfd, 0x41, 0xf4, 0x01,
+ 0x4f, 0x81, 0x53, 0x6c, 0xf7, 0x30, 0x7e, 0x2f, 0xa3, 0xee, 0xdd, 0xa8,
+ 0xbb, 0x8e, 0xba, 0x43, 0x78, 0xff, 0xe1, 0xae, 0x79, 0xdf, 0x81, 0xf7,
+ 0xcf, 0xa1, 0x1d, 0xfb, 0x77, 0x5e, 0x44, 0xfb, 0x83, 0xf8, 0xfd, 0xc5,
+ 0xae, 0x3e, 0x8d, 0x5d, 0xef, 0xbe, 0xbc, 0x79, 0xc9, 0xf0, 0xc0, 0x8e,
+ 0x6f, 0x07, 0xfe, 0xb1, 0xa8, 0x8f, 0x0a, 0x15, 0xca, 0x9b, 0xb0, 0x3c,
+ 0xb2, 0xe2, 0xcb, 0x1c, 0x91, 0x79, 0xc8, 0xfa, 0x42, 0x45, 0xbc, 0x6e,
+ 0x19, 0x9e, 0xfc, 0x31, 0x64, 0xfa, 0x3c, 0xf0, 0x5a, 0x80, 0x7d, 0x71,
+ 0x74, 0x25, 0x8c, 0xe7, 0x21, 0xc8, 0x3b, 0xc9, 0x74, 0x09, 0x79, 0x3e,
+ 0x02, 0xd9, 0xd2, 0x0b, 0x9e, 0x57, 0x3e, 0x88, 0x3c, 0x0e, 0xb9, 0x34,
+ 0x8b, 0xbe, 0xb3, 0xe8, 0xf3, 0xd1, 0xe6, 0xff, 0x31, 0xb4, 0xec, 0xc3,
+ 0xf0, 0xec, 0x2e, 0x18, 0xc2, 0xe2, 0xae, 0x92, 0x1f, 0x5f, 0x98, 0x9e,
+ 0x5b, 0x89, 0xc8, 0xf0, 0xaa, 0x9d, 0xa4, 0xb3, 0x3f, 0xb2, 0xca, 0x98,
+ 0x84, 0x8c, 0x04, 0x85, 0xb2, 0x5f, 0xc6, 0x43, 0xb0, 0xd1, 0x02, 0xde,
+ 0x30, 0x74, 0x94, 0x7a, 0x97, 0x2c, 0x60, 0xcb, 0x36, 0x77, 0x62, 0x13,
+ 0x47, 0xda, 0xb1, 0x89, 0x21, 0xe8, 0x88, 0xd7, 0x83, 0x5a, 0x5e, 0x45,
+ 0x40, 0x27, 0x6f, 0x01, 0xfe, 0x29, 0x5b, 0x42, 0xe0, 0x1f, 0x07, 0xbc,
+ 0xf3, 0x26, 0xda, 0x6f, 0xd4, 0x5b, 0xa0, 0x77, 0xc8, 0x38, 0x9b, 0xf5,
+ 0x2c, 0xd1, 0x96, 0x21, 0x0f, 0xe0, 0xbd, 0xd1, 0xc9, 0x6b, 0xe7, 0xb4,
+ 0x8d, 0x75, 0x97, 0x6f, 0xf3, 0xa0, 0xa3, 0x69, 0x91, 0xf6, 0xfa, 0xe1,
+ 0xd0, 0x9d, 0x7b, 0xfc, 0xa3, 0x5d, 0x7b, 0x0c, 0x4a, 0x72, 0x89, 0xf8,
+ 0x8d, 0xa8, 0xbd, 0xfa, 0xf8, 0x2d, 0x2a, 0x5b, 0x7e, 0x1c, 0x3e, 0x89,
+ 0x40, 0x9a, 0x2b, 0x5b, 0x14, 0x3a, 0xb1, 0x0f, 0xb2, 0x9e, 0x72, 0x9e,
+ 0xf8, 0x0e, 0x03, 0x87, 0x11, 0xfc, 0x1c, 0xfc, 0x76, 0x70, 0x7a, 0xb2,
+ 0xbd, 0x3f, 0x7f, 0x0f, 0xeb, 0x90, 0x55, 0x2c, 0x09, 0x3f, 0xf0, 0x71,
+ 0x91, 0xcf, 0x90, 0xaf, 0x7d, 0x94, 0xb7, 0x3e, 0x4c, 0x8f, 0xed, 0x82,
+ 0x89, 0xb8, 0x21, 0x4c, 0xf5, 0x16, 0x6c, 0x8b, 0x28, 0xa3, 0x60, 0xa7,
+ 0x9b, 0xd4, 0x29, 0x5c, 0x73, 0x92, 0xf6, 0xb6, 0x81, 0x93, 0x7a, 0xc5,
+ 0x93, 0x73, 0x95, 0xb7, 0x1b, 0xb8, 0x78, 0xbe, 0xb0, 0xf9, 0x96, 0xb8,
+ 0x7e, 0x54, 0xe9, 0x1e, 0x0d, 0xd3, 0x6e, 0xfc, 0xd0, 0x3f, 0x27, 0x7e,
+ 0xa8, 0x0f, 0x88, 0x4b, 0xda, 0xd4, 0xc4, 0xe7, 0xef, 0x00, 0x9f, 0xec,
+ 0xeb, 0x1a, 0xdd, 0xf2, 0x2e, 0x03, 0xd7, 0xdd, 0xfa, 0xf8, 0xf4, 0x1d,
+ 0xfa, 0xd8, 0xc7, 0xf1, 0x5e, 0x67, 0xf1, 0xfb, 0x7d, 0xbe, 0xcc, 0x1d,
+ 0x5e, 0xdd, 0xab, 0x7d, 0xd9, 0xb4, 0xb3, 0xad, 0xb3, 0xfe, 0xdb, 0x7d,
+ 0xfe, 0x19, 0x0e, 0x2f, 0xef, 0x6e, 0xeb, 0x3b, 0xb0, 0x33, 0x66, 0xf7,
+ 0x7c, 0x3f, 0xee, 0xdb, 0xdb, 0xaf, 0xdd, 0xf1, 0xeb, 0xe0, 0xab, 0xd8,
+ 0x3b, 0x7b, 0xc9, 0xda, 0xf3, 0xcd, 0x82, 0xad, 0xf7, 0xc2, 0x3e, 0x68,
+ 0x6b, 0x6e, 0xf5, 0x07, 0x95, 0x6e, 0xcc, 0xda, 0xf4, 0x63, 0x4a, 0x6b,
+ 0x7c, 0xbe, 0x07, 0x65, 0xe7, 0xd8, 0x21, 0xf0, 0x40, 0x16, 0x7d, 0x39,
+ 0xc7, 0xee, 0xf1, 0xbe, 0x8d, 0x94, 0x96, 0x85, 0x5a, 0x08, 0xed, 0x89,
+ 0x6c, 0x49, 0x1e, 0x86, 0xaf, 0x98, 0x98, 0xa2, 0xdf, 0x00, 0x7f, 0x79,
+ 0x46, 0xe4, 0x98, 0x94, 0x6b, 0x1f, 0x94, 0x85, 0x95, 0x96, 0xbc, 0x1f,
+ 0x7a, 0xf0, 0xf7, 0xa0, 0x47, 0xe5, 0x12, 0x84, 0xd7, 0x25, 0x1c, 0xc6,
+ 0xa5, 0xa8, 0xd8, 0x4f, 0xc1, 0x96, 0xbf, 0x10, 0x93, 0xe0, 0x05, 0xd2,
+ 0x5e, 0xca, 0x79, 0xbf, 0x48, 0xbf, 0x2d, 0x57, 0xe1, 0x08, 0x25, 0x26,
+ 0xb3, 0x92, 0x82, 0xfd, 0x37, 0xe6, 0x34, 0x50, 0x96, 0x25, 0x35, 0xfa,
+ 0xb4, 0xa0, 0xef, 0x25, 0xf4, 0xc5, 0xb8, 0x9e, 0x8d, 0x38, 0x7e, 0x83,
+ 0xd2, 0xbb, 0x41, 0x18, 0x92, 0xa6, 0x24, 0x2c, 0x3f, 0x6c, 0xd1, 0xd7,
+ 0x7d, 0x66, 0x33, 0x0c, 0xdd, 0x14, 0x97, 0xe7, 0x20, 0x67, 0x9f, 0x55,
+ 0xf1, 0x17, 0xb7, 0xed, 0x8f, 0x3e, 0x7a, 0x18, 0x74, 0xb7, 0x2c, 0xe1,
+ 0xa8, 0xf7, 0x73, 0x59, 0x59, 0x6e, 0xc1, 0xef, 0xa1, 0xac, 0x7f, 0x00,
+ 0xf2, 0x2a, 0xf1, 0xa5, 0x12, 0x6d, 0x49, 0x37, 0x03, 0xd8, 0x4b, 0x32,
+ 0x73, 0xf8, 0x5d, 0x03, 0x9a, 0x3e, 0x8e, 0x49, 0x70, 0xb9, 0x00, 0xfb,
+ 0xf9, 0x8c, 0x2c, 0xa6, 0xe1, 0x9f, 0xda, 0xa5, 0x56, 0xc0, 0x75, 0x63,
+ 0xd0, 0xdb, 0xd0, 0xa7, 0x2b, 0xf4, 0x87, 0xe5, 0xc8, 0x32, 0xfb, 0x9c,
+ 0x01, 0x6d, 0x75, 0x01, 0x77, 0xdd, 0x72, 0x36, 0x9a, 0x28, 0xe5, 0xc1,
+ 0x4f, 0xb6, 0xdb, 0x0f, 0x5e, 0x66, 0x49, 0xfd, 0xf6, 0x34, 0xe8, 0x87,
+ 0xcf, 0x38, 0xce, 0x55, 0xd6, 0x27, 0x51, 0xb2, 0xde, 0x15, 0x7b, 0x29,
+ 0x8c, 0xb9, 0xa0, 0x93, 0x2e, 0x97, 0xe4, 0x6c, 0xe6, 0x98, 0x34, 0x6a,
+ 0xf0, 0xc9, 0x33, 0xb0, 0xa3, 0xea, 0x9e, 0x34, 0x2a, 0xb4, 0x9f, 0x4e,
+ 0x81, 0x1f, 0x5e, 0x41, 0x39, 0x8f, 0xf2, 0x16, 0xca, 0x8f, 0xa3, 0x7c,
+ 0x0d, 0x25, 0x61, 0x3f, 0x25, 0x8d, 0xfa, 0x55, 0xcc, 0xcd, 0x39, 0xa6,
+ 0x0c, 0xcc, 0xf0, 0x21, 0x0f, 0x9f, 0x82, 0x9d, 0xe3, 0xd7, 0x9f, 0x12,
+ 0x69, 0x7c, 0x0c, 0xbf, 0x96, 0x7a, 0xa7, 0x8f, 0xb9, 0x90, 0x99, 0x84,
+ 0xbd, 0x2b, 0xd6, 0xd9, 0xcc, 0xc7, 0xcd, 0x3c, 0x1f, 0xc3, 0x7a, 0xd7,
+ 0xb1, 0x76, 0x18, 0xe7, 0xd9, 0x92, 0x47, 0xd3, 0x67, 0xe4, 0x93, 0xe9,
+ 0x7b, 0x65, 0x62, 0x20, 0x5c, 0x0a, 0x7b, 0xdc, 0x3f, 0xed, 0xda, 0xbd,
+ 0xf6, 0xef, 0xef, 0x9b, 0x7b, 0x8e, 0x60, 0x2f, 0xfb, 0xb5, 0xed, 0x66,
+ 0xff, 0x13, 0xe3, 0x73, 0x58, 0x92, 0x1c, 0xe1, 0x7c, 0x9e, 0x04, 0x96,
+ 0x47, 0x9c, 0x8c, 0x3d, 0x06, 0xeb, 0x3d, 0x85, 0xdf, 0x19, 0xd0, 0x8a,
+ 0x7b, 0x3e, 0x69, 0xff, 0x47, 0xc0, 0x84, 0xb6, 0x06, 0xd7, 0x11, 0x2b,
+ 0x78, 0xe8, 0x26, 0xf6, 0x56, 0x92, 0xee, 0x43, 0x9e, 0xdc, 0x6e, 0xf2,
+ 0x19, 0x92, 0xf2, 0xd2, 0x31, 0xf9, 0x71, 0xed, 0xba, 0x9c, 0xab, 0x1d,
+ 0x93, 0x97, 0x51, 0x2e, 0xd6, 0x4a, 0xc0, 0x23, 0x7d, 0x46, 0xce, 0xd1,
+ 0xc2, 0xb9, 0x50, 0x2e, 0xdf, 0x1f, 0x9b, 0xc7, 0xf9, 0xcd, 0x3a, 0x2d,
+ 0xd9, 0x48, 0x97, 0x64, 0x63, 0x12, 0x63, 0xea, 0x3d, 0x12, 0xfa, 0x2a,
+ 0xf7, 0xdb, 0x27, 0xf9, 0x5a, 0x49, 0x0a, 0x19, 0xfa, 0x34, 0xbd, 0x92,
+ 0x87, 0x4d, 0x0e, 0x3b, 0xe8, 0x8c, 0x8e, 0xb3, 0xb9, 0xb1, 0x22, 0x6c,
+ 0xf8, 0x85, 0xe6, 0xeb, 0x56, 0xa3, 0x6d, 0xff, 0x6f, 0x59, 0xcf, 0xc2,
+ 0x76, 0xfd, 0x0e, 0xe4, 0xc6, 0x73, 0xb0, 0x09, 0x9f, 0xbd, 0x83, 0xc7,
+ 0x48, 0x23, 0xd7, 0xac, 0x46, 0x7d, 0x94, 0x7c, 0x66, 0xf8, 0x01, 0x63,
+ 0xe1, 0xe7, 0x34, 0x6a, 0xb7, 0x0c, 0xfd, 0x29, 0x5b, 0x00, 0xe7, 0x42,
+ 0xbd, 0xf2, 0x77, 0xf0, 0xaf, 0x28, 0x77, 0x7c, 0xbd, 0xaf, 0xfd, 0x86,
+ 0x3a, 0x60, 0xcd, 0x47, 0x13, 0x80, 0x4a, 0xa4, 0x5e, 0x2f, 0x28, 0x5c,
+ 0xb9, 0xcb, 0x43, 0x52, 0xab, 0x12, 0xbf, 0x09, 0xc7, 0xb6, 0x95, 0x5d,
+ 0x0b, 0xbc, 0xba, 0x38, 0x1f, 0xbf, 0x3d, 0x01, 0xff, 0xe1, 0x8c, 0x38,
+ 0x13, 0xbd, 0xd8, 0x13, 0x9f, 0x45, 0x66, 0x2e, 0xff, 0x3a, 0x19, 0xd0,
+ 0x05, 0xbf, 0x3e, 0x84, 0xb3, 0x8c, 0xc8, 0x59, 0xd8, 0xff, 0xe7, 0x40,
+ 0x47, 0x9f, 0xaf, 0x0c, 0xc9, 0xf9, 0x4a, 0x1c, 0xfe, 0x16, 0xed, 0x94,
+ 0xe5, 0xe9, 0xe4, 0x3a, 0xcb, 0x27, 0xa6, 0x53, 0x75, 0x96, 0x5f, 0x32,
+ 0xfe, 0xe2, 0x97, 0x8d, 0x1f, 0xb9, 0x3e, 0xad, 0x7d, 0xb8, 0xaf, 0x4d,
+ 0x8f, 0xaa, 0xb2, 0x39, 0xbd, 0x13, 0x3b, 0x09, 0x1b, 0xbd, 0x9d, 0xa1,
+ 0x7e, 0x06, 0x8c, 0x12, 0x3c, 0x09, 0x7a, 0x9a, 0x87, 0xdc, 0xce, 0xc1,
+ 0xf7, 0x38, 0x0b, 0x1f, 0xa4, 0xd8, 0x84, 0x4c, 0xf0, 0xd2, 0x28, 0xc5,
+ 0xfc, 0xf9, 0x63, 0xbb, 0x18, 0xdf, 0xe4, 0x99, 0x19, 0xff, 0x2b, 0x4d,
+ 0xff, 0xab, 0xf3, 0x8f, 0xf3, 0x81, 0x36, 0xa9, 0x2b, 0x7f, 0x09, 0x9f,
+ 0x51, 0x82, 0xc5, 0x0c, 0xc7, 0xa6, 0xe9, 0xaf, 0xca, 0x36, 0xec, 0x83,
+ 0xb0, 0xf7, 0x3d, 0x09, 0x3f, 0xd5, 0x6a, 0xbd, 0x0a, 0x59, 0x53, 0x82,
+ 0xcf, 0x68, 0x5b, 0xa8, 0x5f, 0x67, 0x1b, 0xe5, 0xc8, 0x98, 0x73, 0x1b,
+ 0x34, 0x97, 0x3d, 0x2e, 0xf2, 0x5d, 0xd4, 0x35, 0x56, 0x78, 0x06, 0xdf,
+ 0xc7, 0x19, 0x98, 0x33, 0x51, 0x75, 0xec, 0x07, 0xfb, 0x3d, 0xca, 0x7d,
+ 0x8c, 0x39, 0xdd, 0x18, 0x5f, 0x5f, 0xe7, 0x98, 0xc4, 0x24, 0xaf, 0x74,
+ 0xbe, 0xbb, 0xae, 0xf7, 0x77, 0x34, 0x33, 0x2a, 0x57, 0x2b, 0x6a, 0x0e,
+ 0xd0, 0xfa, 0xaf, 0x30, 0x66, 0x0b, 0x74, 0xcb, 0x18, 0x95, 0x27, 0x65,
+ 0xe8, 0xa4, 0x72, 0x25, 0x05, 0xda, 0x09, 0xca, 0x6c, 0x8c, 0x60, 0xbb,
+ 0xb2, 0x5d, 0xf9, 0x72, 0x97, 0x8e, 0x8f, 0xf0, 0x19, 0x3a, 0xac, 0x39,
+ 0x23, 0xbc, 0x1b, 0x81, 0x7d, 0x83, 0x3d, 0x75, 0xe2, 0x42, 0xff, 0x15,
+ 0x71, 0x16, 0x66, 0x8f, 0xea, 0x4f, 0xaf, 0x83, 0xf1, 0x66, 0x9d, 0x02,
+ 0x14, 0x77, 0x1e, 0xeb, 0xa7, 0x2e, 0x05, 0x83, 0x8c, 0xa9, 0x27, 0x2f,
+ 0x81, 0xad, 0x3c, 0x83, 0x8b, 0xa6, 0x4f, 0x6b, 0xbe, 0x2f, 0x4a, 0xda,
+ 0x22, 0x0e, 0x12, 0xa5, 0x2d, 0x20, 0x7b, 0xc0, 0xbb, 0x21, 0x1f, 0x5a,
+ 0xd5, 0x7b, 0xb6, 0x2f, 0x0a, 0xef, 0x5b, 0xe4, 0xf6, 0x4a, 0x22, 0x7d,
+ 0x0b, 0xb2, 0x39, 0x1f, 0x4d, 0x83, 0x56, 0x3e, 0xd1, 0x05, 0x9e, 0x9e,
+ 0xcc, 0xda, 0x3f, 0xe8, 0xd2, 0xb6, 0x20, 0x7c, 0x7e, 0xc6, 0x01, 0x2a,
+ 0x59, 0x8c, 0xe9, 0x96, 0x7f, 0x11, 0xc4, 0x73, 0x93, 0xef, 0xb0, 0x73,
+ 0x82, 0x1a, 0xbe, 0xb2, 0xc1, 0x21, 0xfc, 0x04, 0xd1, 0xb1, 0x5c, 0x4b,
+ 0x3e, 0x04, 0x29, 0x2f, 0x98, 0x3f, 0x69, 0xd6, 0x4a, 0x5e, 0x0c, 0xb7,
+ 0x6d, 0xba, 0xd4, 0xaa, 0x07, 0xdb, 0x22, 0x68, 0x7c, 0x22, 0xca, 0x18,
+ 0xd9, 0xc3, 0xa6, 0xee, 0xb4, 0x8f, 0xc3, 0x2a, 0x5e, 0xc7, 0x7b, 0x24,
+ 0xd2, 0xd6, 0x94, 0xa1, 0xad, 0x8f, 0x81, 0xb6, 0x4e, 0x29, 0xda, 0x6a,
+ 0xc9, 0xab, 0xe9, 0xb4, 0x7c, 0x61, 0x4f, 0xfa, 0xda, 0xfd, 0x17, 0x01,
+ 0xbc, 0xfc, 0x0d, 0xca, 0xc2, 0x17, 0xb1, 0x2e, 0xf4, 0x4e, 0xb9, 0x92,
+ 0xc8, 0xce, 0xd2, 0x16, 0x82, 0x1e, 0x29, 0xc3, 0xe7, 0x4a, 0x5e, 0x1a,
+ 0x52, 0x7d, 0x92, 0xd0, 0x29, 0x0d, 0xd0, 0x1b, 0xf1, 0x5b, 0xae, 0x40,
+ 0x0e, 0x5f, 0x0a, 0x41, 0x6f, 0x91, 0x67, 0x65, 0xc0, 0x86, 0x6c, 0x60,
+ 0xff, 0x06, 0x78, 0x27, 0x79, 0x29, 0x82, 0x32, 0xae, 0xe6, 0x6a, 0x54,
+ 0x5c, 0x35, 0xbe, 0x51, 0x19, 0x55, 0xe3, 0x1a, 0xb0, 0x5f, 0x93, 0x97,
+ 0x20, 0xdf, 0x33, 0x69, 0x19, 0xb9, 0x94, 0x91, 0xf8, 0x25, 0x4b, 0x8a,
+ 0x33, 0xad, 0x56, 0x18, 0xb0, 0x8f, 0x5e, 0xea, 0x97, 0x5b, 0x2a, 0xb6,
+ 0x1a, 0x56, 0xf1, 0xd6, 0xc5, 0xcc, 0x0c, 0x78, 0x93, 0xf8, 0xf3, 0x30,
+ 0xa6, 0x00, 0xfd, 0x58, 0x90, 0xb3, 0x2b, 0xc4, 0x0f, 0xe3, 0xe5, 0xdb,
+ 0xb1, 0x80, 0x24, 0x20, 0xcb, 0x8e, 0xcb, 0x7c, 0xad, 0x1b, 0xb2, 0x2c,
+ 0x08, 0x1d, 0xf8, 0x50, 0xb7, 0xf4, 0x0e, 0x93, 0x1e, 0x80, 0x17, 0x0f,
+ 0x73, 0x17, 0x24, 0x8f, 0x31, 0x85, 0x95, 0x9d, 0xfe, 0x45, 0xe9, 0x06,
+ 0x4f, 0x1d, 0x97, 0x93, 0x35, 0xce, 0x13, 0x74, 0xca, 0x72, 0x10, 0x34,
+ 0xe4, 0x3a, 0x47, 0x30, 0x0f, 0xf4, 0x76, 0xc7, 0x1f, 0xf9, 0x2f, 0xfb,
+ 0x06, 0x34, 0xe9, 0xf3, 0x5d, 0xb8, 0xd4, 0xe5, 0xcd, 0x58, 0xdb, 0x19,
+ 0x09, 0xce, 0x65, 0x3e, 0x60, 0x7d, 0x37, 0x93, 0xb1, 0xae, 0x65, 0xb2,
+ 0xd6, 0xf5, 0x4c, 0xc1, 0xba, 0x01, 0xdd, 0xd4, 0xd8, 0x7c, 0x0e, 0xf4,
+ 0x03, 0xdd, 0xcf, 0x98, 0x79, 0xfb, 0x0c, 0xa3, 0x26, 0x66, 0xf0, 0x9a,
+ 0x6c, 0x54, 0x68, 0x3b, 0xb4, 0x1e, 0x9e, 0x4b, 0x97, 0xee, 0x01, 0x7c,
+ 0x80, 0x83, 0xbe, 0xee, 0x8e, 0xee, 0x08, 0x79, 0xa3, 0xb2, 0xa6, 0x74,
+ 0x47, 0x84, 0xba, 0x23, 0x9d, 0x97, 0xfd, 0xb2, 0x5d, 0x03, 0xff, 0x89,
+ 0xb2, 0x83, 0x65, 0xbb, 0x1e, 0x95, 0x2f, 0x54, 0x7d, 0x5a, 0xe2, 0x7e,
+ 0xcb, 0x6f, 0xea, 0x91, 0x80, 0x4c, 0x29, 0x7d, 0xdd, 0x27, 0x57, 0xd7,
+ 0xe1, 0x0f, 0xc1, 0x5a, 0xb0, 0xef, 0x63, 0xac, 0xc0, 0x56, 0xbe, 0xb1,
+ 0xf4, 0xf3, 0xee, 0xea, 0x2c, 0x70, 0xc5, 0xfb, 0x25, 0xec, 0xb3, 0x9f,
+ 0x3b, 0xf2, 0xdf, 0xc7, 0xc1, 0x93, 0x7c, 0xb6, 0x24, 0x0f, 0xbb, 0x91,
+ 0xf7, 0x5c, 0x79, 0xd8, 0x3d, 0xdb, 0x95, 0x31, 0xc0, 0x15, 0x80, 0x4d,
+ 0x1e, 0x06, 0x1c, 0x55, 0xd5, 0xde, 0xed, 0x8a, 0x35, 0x07, 0x3d, 0x5c,
+ 0x54, 0xf7, 0x57, 0x28, 0xd7, 0xf5, 0xda, 0x79, 0xf8, 0xab, 0xc5, 0xf1,
+ 0x1e, 0xea, 0xb7, 0xd1, 0x12, 0xf9, 0x5e, 0xd9, 0xf1, 0x19, 0xf0, 0xdc,
+ 0x57, 0xba, 0xa9, 0xdb, 0x8f, 0xa6, 0x27, 0xe5, 0x46, 0x85, 0xcf, 0x6c,
+ 0x4f, 0xa4, 0x45, 0xc5, 0x8f, 0x2b, 0xd3, 0x8b, 0xee, 0x6b, 0x86, 0xc7,
+ 0x6a, 0xa0, 0xf1, 0x53, 0xf2, 0x8d, 0xcd, 0x79, 0xf9, 0xf7, 0x9b, 0xb3,
+ 0xb0, 0x4f, 0x4e, 0xc0, 0x3e, 0xf9, 0x08, 0x78, 0xf8, 0x38, 0x78, 0xf8,
+ 0xe3, 0xa0, 0xfb, 0x19, 0x15, 0x77, 0xa8, 0x55, 0x12, 0x57, 0x4a, 0x2a,
+ 0xce, 0xfd, 0x1a, 0x68, 0x7e, 0x42, 0x82, 0xab, 0x43, 0xc0, 0x6b, 0xa9,
+ 0x15, 0x75, 0x5b, 0x0f, 0xc3, 0x06, 0xc1, 0x59, 0x97, 0x12, 0x41, 0x45,
+ 0x23, 0xae, 0xf3, 0x69, 0xe0, 0xf2, 0x4d, 0x5e, 0xa2, 0xc6, 0x23, 0xde,
+ 0xa8, 0x8d, 0x4a, 0xf1, 0x32, 0xfa, 0x2f, 0x47, 0x80, 0x37, 0xea, 0xc6,
+ 0xc4, 0xf9, 0xa2, 0x6c, 0x81, 0x2e, 0xb2, 0xc0, 0xcf, 0x3b, 0xa4, 0x1c,
+ 0x4d, 0x7c, 0x4d, 0x64, 0x52, 0x0e, 0x2d, 0x81, 0xa6, 0x97, 0x6c, 0xec,
+ 0x99, 0xb8, 0xc4, 0xf3, 0x65, 0x4f, 0xec, 0x65, 0xca, 0xa2, 0x03, 0xc6,
+ 0x37, 0xd1, 0xfa, 0xbe, 0x2e, 0x5c, 0x97, 0xeb, 0x7d, 0x46, 0xe6, 0xa1,
+ 0x53, 0x61, 0x7f, 0x43, 0x66, 0xbb, 0x31, 0xac, 0x19, 0x9e, 0xbb, 0xec,
+ 0x84, 0xe7, 0x2f, 0x73, 0x9e, 0xb0, 0x04, 0x96, 0x78, 0xb6, 0x9c, 0x07,
+ 0x3c, 0x80, 0xb9, 0x53, 0x4b, 0xc4, 0xdb, 0x18, 0xc6, 0xfd, 0x63, 0xe8,
+ 0x63, 0x4d, 0x57, 0xb9, 0x65, 0x2d, 0x1f, 0x72, 0x8d, 0x4e, 0x9d, 0x88,
+ 0x33, 0x80, 0xfc, 0xc8, 0x36, 0xb4, 0x7e, 0x2b, 0x28, 0xfd, 0xa7, 0x75,
+ 0xdf, 0x71, 0x81, 0x51, 0xd7, 0xeb, 0xaa, 0xfd, 0x04, 0x96, 0xb7, 0xa8,
+ 0xef, 0xb1, 0x06, 0xc7, 0x84, 0x3a, 0xe0, 0xce, 0x40, 0xee, 0xdc, 0x1b,
+ 0x26, 0xee, 0x1f, 0x83, 0x7e, 0x4d, 0x2e, 0xe9, 0x98, 0x7c, 0xf2, 0x72,
+ 0x1a, 0xfb, 0x91, 0x41, 0x46, 0x17, 0x6c, 0xec, 0xe1, 0x7d, 0x4a, 0x7e,
+ 0x4d, 0x40, 0x66, 0x39, 0xb2, 0x7e, 0x90, 0x67, 0x33, 0x28, 0x8d, 0xa7,
+ 0xf9, 0xce, 0x33, 0xe2, 0x79, 0x93, 0x17, 0xa3, 0xd0, 0x2f, 0x38, 0xa7,
+ 0xbe, 0x21, 0xa9, 0x6f, 0xb2, 0x6d, 0x48, 0xd1, 0x72, 0x10, 0x67, 0xb0,
+ 0x58, 0x69, 0x3d, 0x9c, 0x4b, 0x97, 0x40, 0x6d, 0xc4, 0x39, 0xf1, 0x41,
+ 0xbc, 0x8f, 0x03, 0x36, 0xe2, 0xb8, 0x8f, 0xba, 0x18, 0x75, 0xfb, 0xa5,
+ 0x58, 0x23, 0x3d, 0xa3, 0xac, 0xef, 0x37, 0xbe, 0xde, 0x67, 0x78, 0x27,
+ 0x84, 0xbd, 0x6b, 0x3a, 0x2e, 0x80, 0xa6, 0xca, 0xf0, 0xbb, 0xae, 0x2e,
+ 0x49, 0xf8, 0x4d, 0x90, 0xcf, 0x9f, 0xa2, 0x0c, 0x05, 0x7d, 0x95, 0xd7,
+ 0x27, 0x40, 0x6b, 0x7d, 0x90, 0x97, 0xad, 0xd6, 0x71, 0xd8, 0xc9, 0xa7,
+ 0xd3, 0xc4, 0xd1, 0x4d, 0xe0, 0xa8, 0x3b, 0x76, 0x1a, 0xe7, 0xb5, 0xf6,
+ 0xf4, 0x43, 0x4a, 0x5e, 0xc0, 0xd6, 0x51, 0x7a, 0x4b, 0xc7, 0x38, 0xd2,
+ 0xb4, 0x8d, 0x14, 0x0f, 0xe7, 0x5c, 0xca, 0xc3, 0x3c, 0xf0, 0x30, 0xae,
+ 0xe4, 0xb7, 0x96, 0x2d, 0x3d, 0x52, 0x3c, 0x9e, 0xc5, 0x7e, 0x27, 0x77,
+ 0xf5, 0xcb, 0xe0, 0x1d, 0xb6, 0x5f, 0xf3, 0x43, 0x61, 0xc6, 0x43, 0x03,
+ 0xde, 0xa4, 0x6c, 0x1c, 0x9c, 0x92, 0x8b, 0x07, 0x13, 0x93, 0xb3, 0x36,
+ 0x75, 0xc2, 0x94, 0xd4, 0x9f, 0xce, 0xca, 0x5a, 0x55, 0xeb, 0xe6, 0x39,
+ 0x77, 0x52, 0xf2, 0xcd, 0x02, 0xde, 0x3d, 0x94, 0xec, 0xef, 0xcb, 0x5d,
+ 0x7f, 0x4f, 0x39, 0xee, 0x09, 0x32, 0x42, 0xeb, 0x5e, 0xdb, 0xee, 0xc6,
+ 0xf9, 0x50, 0x2e, 0x7c, 0x10, 0xf5, 0x39, 0xc8, 0x36, 0x9e, 0x67, 0x0a,
+ 0x67, 0x77, 0x4a, 0x9d, 0x53, 0x3e, 0x4d, 0x7f, 0x80, 0x63, 0x12, 0xb1,
+ 0x39, 0xd4, 0xcf, 0x08, 0x75, 0x28, 0xf7, 0xe6, 0xcf, 0xe7, 0x19, 0xf8,
+ 0x03, 0x8c, 0x31, 0xe1, 0xef, 0x33, 0x61, 0xf2, 0x64, 0xc0, 0xf5, 0xeb,
+ 0xc7, 0xa0, 0x7f, 0x43, 0x6a, 0x8d, 0x72, 0x95, 0x75, 0x29, 0x87, 0xe3,
+ 0xf3, 0x69, 0xbe, 0x8b, 0x3c, 0x66, 0xfc, 0xf2, 0xe3, 0xf0, 0x5b, 0xf3,
+ 0xcd, 0xae, 0xdf, 0xa0, 0x7f, 0x77, 0x64, 0x9d, 0x96, 0xcb, 0xdb, 0x31,
+ 0xc7, 0xc8, 0xde, 0x93, 0x35, 0xc6, 0xac, 0x2d, 0xe9, 0x82, 0x2c, 0x3d,
+ 0x2a, 0xc3, 0x46, 0x8e, 0x72, 0x3f, 0x7d, 0x4a, 0xd7, 0xe5, 0x67, 0x62,
+ 0x72, 0x6e, 0xed, 0xff, 0x85, 0xae, 0x7f, 0xbd, 0x5d, 0x57, 0xd8, 0xc3,
+ 0xae, 0xbb, 0x79, 0x19, 0xf2, 0xa0, 0x0a, 0x59, 0x51, 0x85, 0xac, 0xa8,
+ 0x42, 0x56, 0x54, 0x21, 0x2b, 0xaa, 0x90, 0x15, 0x55, 0xc8, 0x8a, 0xea,
+ 0x8c, 0xd1, 0x9b, 0xa7, 0x21, 0x73, 0xe9, 0xf3, 0xd0, 0xcf, 0xe9, 0xb4,
+ 0x05, 0xe2, 0x90, 0x25, 0xf4, 0x67, 0x12, 0xa5, 0x5b, 0xc0, 0xcd, 0xd7,
+ 0xd3, 0xf4, 0xb9, 0x5b, 0xf2, 0x57, 0xe9, 0xce, 0xdd, 0xab, 0xf8, 0x86,
+ 0x3c, 0x0a, 0x7c, 0x7d, 0x08, 0xf8, 0xfa, 0xf0, 0x5d, 0x39, 0x16, 0x7e,
+ 0x4c, 0x64, 0xb8, 0x14, 0x80, 0xff, 0x39, 0x73, 0x07, 0xee, 0xe8, 0x7b,
+ 0x63, 0x8d, 0xbb, 0x6c, 0x63, 0xfa, 0xdc, 0xa3, 0xea, 0xde, 0x7c, 0x03,
+ 0x76, 0xf9, 0x8d, 0x74, 0x29, 0x12, 0x50, 0xf7, 0x73, 0x2e, 0x69, 0x67,
+ 0x8f, 0xbf, 0x6f, 0x84, 0xb5, 0x5c, 0xd4, 0x67, 0x9f, 0xcf, 0xf4, 0x81,
+ 0x0f, 0x68, 0xdf, 0xdd, 0x50, 0xf6, 0xdd, 0xd1, 0x74, 0x50, 0xb6, 0xa2,
+ 0xd4, 0xa9, 0x3f, 0x92, 0x93, 0x2b, 0x91, 0x1e, 0xfa, 0xdf, 0x8b, 0xd5,
+ 0x83, 0xb2, 0xad, 0x64, 0xca, 0x07, 0xd1, 0xd7, 0x93, 0x79, 0xd0, 0xc4,
+ 0x11, 0xf8, 0x8e, 0x17, 0x65, 0x2c, 0x76, 0x11, 0x7b, 0xfd, 0x3c, 0xc6,
+ 0xc0, 0x07, 0x68, 0x15, 0x50, 0x77, 0x1d, 0x7e, 0xc6, 0x6d, 0xe1, 0xf3,
+ 0x98, 0x73, 0x1e, 0x88, 0xce, 0x3a, 0x29, 0xe7, 0x35, 0xf1, 0xe9, 0x8c,
+ 0x34, 0xc5, 0xbb, 0xb6, 0x41, 0xc9, 0xaf, 0xd3, 0x2f, 0xeb, 0x03, 0x1f,
+ 0xfe, 0x08, 0x7a, 0x98, 0x6b, 0x50, 0x2e, 0x70, 0x0f, 0xff, 0x0d, 0xf0,
+ 0xc5, 0x67, 0xbb, 0xbd, 0xfb, 0xa1, 0x7b, 0x29, 0xf7, 0xb5, 0xef, 0x94,
+ 0xc7, 0x18, 0xa5, 0x1b, 0xd2, 0xbc, 0x77, 0xe0, 0xfe, 0xfe, 0x18, 0x76,
+ 0x4e, 0x14, 0x74, 0x80, 0xfa, 0x75, 0xdf, 0xce, 0xf5, 0xed, 0x19, 0x1d,
+ 0xeb, 0xbb, 0xa2, 0x6c, 0x9a, 0x1c, 0xf4, 0xd8, 0x31, 0xf4, 0x65, 0xac,
+ 0xbd, 0xd5, 0x3a, 0x95, 0x86, 0xdf, 0xf1, 0x24, 0x65, 0xd9, 0x7d, 0xe0,
+ 0x69, 0xda, 0x45, 0xd4, 0xb9, 0x62, 0xdd, 0xcc, 0x6c, 0x3b, 0x61, 0xe8,
+ 0xcb, 0x19, 0xd0, 0x5c, 0x0e, 0x74, 0x18, 0x78, 0x60, 0x0a, 0xfa, 0x57,
+ 0xc5, 0x9c, 0x41, 0xeb, 0x5c, 0xf7, 0x83, 0xd6, 0x5f, 0x64, 0xc6, 0xa1,
+ 0x8f, 0x1f, 0x82, 0x3e, 0xe6, 0x7d, 0x74, 0x0e, 0x3a, 0x99, 0xfa, 0xd8,
+ 0x91, 0x3f, 0xdd, 0xcc, 0x41, 0x76, 0xdd, 0xd7, 0x43, 0x5e, 0x9b, 0x6a,
+ 0xf3, 0x54, 0xc1, 0xf0, 0xdc, 0x01, 0x13, 0xfb, 0x28, 0x28, 0xde, 0x2c,
+ 0xaf, 0xd3, 0x0e, 0x01, 0x9f, 0xae, 0x53, 0x46, 0xd0, 0xa6, 0xa4, 0xec,
+ 0x80, 0xac, 0x59, 0xff, 0x00, 0xca, 0x29, 0x94, 0xda, 0x56, 0xbb, 0x52,
+ 0x7d, 0x35, 0xec, 0xdf, 0x23, 0xef, 0xd8, 0x6b, 0x75, 0xec, 0xef, 0x18,
+ 0x73, 0x1b, 0x4a, 0xfd, 0xde, 0x47, 0xb0, 0xc7, 0xe3, 0xa0, 0xc1, 0x19,
+ 0xd0, 0xe0, 0x14, 0xf6, 0x7a, 0xde, 0x1a, 0x39, 0x1c, 0x80, 0x3e, 0x3f,
+ 0x23, 0x85, 0x34, 0x64, 0xee, 0x5a, 0xc9, 0x9a, 0x58, 0x12, 0xf5, 0x9e,
+ 0x4f, 0xf3, 0x4e, 0xfd, 0xbd, 0x2a, 0x3e, 0xb8, 0xbc, 0x19, 0x34, 0x71,
+ 0xc4, 0x20, 0xea, 0xa8, 0xc3, 0x21, 0xb3, 0x1c, 0xcc, 0x55, 0xfd, 0x59,
+ 0xaf, 0xf4, 0x62, 0xbe, 0xea, 0x34, 0xde, 0x19, 0x5b, 0x38, 0x66, 0xdd,
+ 0x59, 0xcf, 0xd8, 0x45, 0xc2, 0xc9, 0xc1, 0x17, 0x0d, 0xba, 0x8c, 0x5f,
+ 0xb8, 0x38, 0x9f, 0xac, 0xe4, 0x47, 0x60, 0x93, 0x29, 0x99, 0xdc, 0x6b,
+ 0x64, 0x32, 0xe4, 0x5d, 0xcd, 0x93, 0xb5, 0x4d, 0xda, 0x4e, 0x9e, 0xf2,
+ 0xa7, 0x29, 0xc7, 0x8a, 0x35, 0xd8, 0x3f, 0xe9, 0xdf, 0xb3, 0xb2, 0x6a,
+ 0xce, 0xb0, 0xca, 0xd5, 0x28, 0xad, 0x89, 0xe5, 0x1c, 0xbe, 0x09, 0xff,
+ 0x35, 0x03, 0x1e, 0xf6, 0x20, 0x37, 0x1d, 0xc8, 0x45, 0xea, 0xb5, 0xaf,
+ 0x76, 0x4b, 0x1f, 0xea, 0x2f, 0xc3, 0xe6, 0x79, 0x92, 0x7c, 0x7b, 0x5d,
+ 0xec, 0xc6, 0x1b, 0xc5, 0x47, 0x18, 0x1b, 0x19, 0x32, 0x77, 0xb3, 0xff,
+ 0x0b, 0xf0, 0xea, 0x35, 0x42, 0xb0, 0xeb, 0xaf, 0xd6, 0xf6, 0xc1, 0x47,
+ 0x3c, 0x66, 0xe5, 0xa3, 0xac, 0x2b, 0xc9, 0x7a, 0x86, 0x76, 0x28, 0x63,
+ 0x24, 0x61, 0xd4, 0xef, 0xf6, 0x49, 0xa9, 0xff, 0x9f, 0x53, 0x77, 0x34,
+ 0x0b, 0x4a, 0xee, 0xfa, 0xf1, 0xe5, 0xe7, 0x24, 0xd9, 0xf4, 0xe3, 0x54,
+ 0x5c, 0x7f, 0xcb, 0x2a, 0x36, 0xff, 0x1c, 0xeb, 0x10, 0x06, 0xee, 0x45,
+ 0xaf, 0x63, 0x2f, 0x4f, 0x98, 0x75, 0x1c, 0x2b, 0x74, 0x38, 0x86, 0xfd,
+ 0xec, 0xef, 0x93, 0xbe, 0x00, 0xe4, 0xd9, 0x28, 0x9e, 0x6f, 0xa1, 0x6e,
+ 0xe7, 0xbd, 0x51, 0x15, 0x2b, 0x70, 0x18, 0xde, 0x33, 0xf4, 0x77, 0x03,
+ 0x32, 0xc7, 0x86, 0xfe, 0x6c, 0x54, 0x3f, 0x8e, 0x12, 0xe3, 0x9e, 0xbc,
+ 0x2e, 0x73, 0xda, 0xdf, 0x86, 0x4d, 0x39, 0xac, 0x74, 0xf0, 0x4c, 0x9a,
+ 0xb1, 0x90, 0x33, 0x90, 0x8f, 0xf7, 0xa3, 0x8e, 0x7e, 0x53, 0x49, 0x9c,
+ 0xf7, 0x14, 0x8c, 0xbf, 0xaf, 0xcf, 0x25, 0xa0, 0xf4, 0xf5, 0x0a, 0xce,
+ 0x83, 0x73, 0x50, 0xdf, 0xfd, 0x5c, 0x3e, 0xd5, 0x11, 0x47, 0xc9, 0xd9,
+ 0xed, 0xb8, 0x41, 0x36, 0x0f, 0x1d, 0xbd, 0x56, 0x25, 0x0f, 0x66, 0x70,
+ 0xde, 0x59, 0xf9, 0xda, 0xe6, 0x3d, 0xc0, 0x75, 0x54, 0x02, 0x4f, 0xb5,
+ 0x40, 0x3f, 0xd4, 0x0d, 0x63, 0x90, 0xc9, 0x8e, 0xb1, 0x25, 0xa2, 0x12,
+ 0x7c, 0x6a, 0x48, 0xba, 0x2f, 0xc4, 0xa4, 0xeb, 0x02, 0xf3, 0x4f, 0x52,
+ 0x71, 0xd8, 0xc5, 0xb4, 0x87, 0x78, 0x0f, 0xc9, 0xfb, 0xc3, 0xb8, 0xbe,
+ 0x8f, 0xe4, 0x5d, 0x24, 0xfa, 0xc1, 0x76, 0xef, 0xba, 0xe4, 0x00, 0x3f,
+ 0x7a, 0xce, 0xdd, 0x63, 0xcb, 0x7a, 0x2c, 0xef, 0x31, 0x63, 0x25, 0x49,
+ 0x99, 0x7b, 0xcc, 0x14, 0xc6, 0xa6, 0x26, 0x5f, 0x6e, 0x8f, 0xe7, 0x58,
+ 0xea, 0xc4, 0x28, 0xf8, 0xfb, 0xad, 0xd2, 0xf8, 0x22, 0xf9, 0xdc, 0xbf,
+ 0xeb, 0x1a, 0x32, 0x77, 0x5f, 0xec, 0x13, 0x37, 0xed, 0x49, 0xd3, 0xee,
+ 0x2a, 0x3d, 0x19, 0x6c, 0xc7, 0x5b, 0x78, 0x2f, 0x96, 0x38, 0xcf, 0xe4,
+ 0x11, 0x7d, 0x47, 0x46, 0x5f, 0x0a, 0xbe, 0xc5, 0x93, 0xb0, 0x31, 0xeb,
+ 0x2c, 0x7b, 0xa4, 0x5c, 0x3f, 0x25, 0xb3, 0xea, 0xf9, 0x43, 0xf2, 0xa8,
+ 0x43, 0xdc, 0x9d, 0x91, 0xf4, 0x84, 0xb6, 0xc7, 0xc4, 0xd6, 0xb8, 0xed,
+ 0x76, 0xcf, 0xc8, 0xd1, 0xb4, 0xd2, 0x21, 0xce, 0x23, 0xc0, 0x71, 0xb1,
+ 0xd9, 0x45, 0x7a, 0x07, 0xec, 0x1e, 0x78, 0x2c, 0x2b, 0x17, 0x37, 0xd1,
+ 0x17, 0x67, 0xf5, 0x08, 0xdf, 0xeb, 0xc0, 0x27, 0x63, 0x16, 0x4f, 0x11,
+ 0x9f, 0xdc, 0x3b, 0x75, 0x28, 0x71, 0x4a, 0x1c, 0x50, 0x2f, 0x33, 0xe6,
+ 0x96, 0x98, 0xbc, 0x2d, 0xf4, 0x9b, 0x89, 0x33, 0xce, 0xe3, 0xef, 0x5b,
+ 0x8f, 0xb3, 0x37, 0x06, 0x85, 0xe6, 0x98, 0x7d, 0xc1, 0x11, 0xfb, 0x12,
+ 0xcb, 0x08, 0x4a, 0xb6, 0x01, 0xa4, 0x8d, 0xa4, 0x69, 0x73, 0x51, 0x07,
+ 0x3b, 0xf2, 0x09, 0xf2, 0x96, 0xce, 0xff, 0x4b, 0x8e, 0x4c, 0xca, 0x95,
+ 0xb5, 0xbb, 0xf9, 0x2b, 0x70, 0x41, 0xdb, 0x25, 0x77, 0xf2, 0xd7, 0xe4,
+ 0x3f, 0x80, 0xbf, 0xb8, 0xc6, 0x19, 0x95, 0xbb, 0xf0, 0xa9, 0x68, 0x22,
+ 0x9e, 0xd5, 0xfe, 0x85, 0x93, 0xb2, 0x47, 0xe2, 0xb4, 0x47, 0x1b, 0x4f,
+ 0x8e, 0xe3, 0xdc, 0x5b, 0xf2, 0x44, 0xda, 0xa7, 0x2f, 0xe6, 0xf8, 0xb5,
+ 0xa4, 0x06, 0xfd, 0x5c, 0x76, 0x2d, 0x59, 0x70, 0xcf, 0x28, 0x7b, 0xf2,
+ 0xc3, 0xd1, 0x96, 0x9c, 0x4e, 0xeb, 0xb1, 0x0b, 0x32, 0x62, 0x68, 0x5c,
+ 0xf9, 0x6b, 0x90, 0xbf, 0x3c, 0x2f, 0xbe, 0xdf, 0x23, 0xe9, 0x81, 0x33,
+ 0x92, 0x9c, 0xd8, 0x22, 0xbe, 0x70, 0x0e, 0x94, 0x3b, 0xbf, 0x36, 0x16,
+ 0xa6, 0x72, 0x9e, 0xf2, 0x15, 0xc2, 0xb4, 0x0f, 0x74, 0x9b, 0x85, 0xbf,
+ 0xb4, 0x13, 0x0f, 0x4b, 0x8d, 0x94, 0x5a, 0x21, 0xac, 0x5d, 0x84, 0x3f,
+ 0xf1, 0xe1, 0xa8, 0x1b, 0x1f, 0xb6, 0x47, 0x62, 0x67, 0xa5, 0xa6, 0x60,
+ 0xfd, 0x44, 0x5a, 0xd3, 0xcb, 0x62, 0x66, 0xaf, 0x18, 0x55, 0x67, 0x8c,
+ 0x9a, 0x73, 0x6d, 0x59, 0x9f, 0x6c, 0xea, 0x78, 0xd4, 0x4e, 0x9c, 0x7a,
+ 0x47, 0xe6, 0x04, 0x8d, 0x2c, 0x28, 0xd7, 0xde, 0x25, 0xbe, 0xcc, 0xa9,
+ 0x65, 0x70, 0x56, 0xcb, 0x3c, 0xa3, 0xb8, 0xb9, 0x47, 0x0a, 0x77, 0xd8,
+ 0xca, 0x21, 0xe6, 0xfd, 0xc5, 0xb3, 0xf6, 0x32, 0x64, 0xc3, 0x93, 0x12,
+ 0x72, 0xfd, 0xb9, 0x98, 0xd3, 0x19, 0x33, 0xf7, 0x11, 0xfb, 0x19, 0xb7,
+ 0x42, 0x9f, 0x07, 0xd1, 0x7e, 0x3f, 0xfa, 0x51, 0x57, 0xf2, 0x1e, 0x80,
+ 0x7a, 0x93, 0xb1, 0xf6, 0x01, 0xf4, 0xeb, 0x91, 0x7c, 0x7d, 0xbf, 0xa9,
+ 0xf3, 0xe7, 0x38, 0xdc, 0xd1, 0xdf, 0xaf, 0xd3, 0xf7, 0x07, 0x59, 0x1b,
+ 0x32, 0x7e, 0x99, 0x7d, 0xe3, 0xed, 0x3b, 0x10, 0xbb, 0xf1, 0xa0, 0xa3,
+ 0xc7, 0xb3, 0x1f, 0x65, 0x3e, 0x74, 0x4b, 0x15, 0xfa, 0xa6, 0x3a, 0xc5,
+ 0xbb, 0x40, 0x63, 0x57, 0xcc, 0x9a, 0x7c, 0x16, 0xda, 0x17, 0xaf, 0x19,
+ 0x7d, 0xbb, 0x93, 0x8b, 0x7a, 0x24, 0xe3, 0xe7, 0xf5, 0x30, 0x17, 0x91,
+ 0xeb, 0xf2, 0x3c, 0x40, 0x53, 0x9b, 0xda, 0x96, 0xb6, 0x33, 0x5d, 0xbc,
+ 0x6b, 0x83, 0x7e, 0xd7, 0xfa, 0xbf, 0x01, 0xfd, 0xbf, 0xb1, 0x02, 0x9d,
+ 0xdf, 0x47, 0xdd, 0xaf, 0xf3, 0x4f, 0xec, 0x76, 0xbe, 0x8f, 0x7f, 0x8f,
+ 0xbc, 0xa5, 0xee, 0xf1, 0x7a, 0x3c, 0xca, 0xf4, 0x8c, 0xfc, 0x39, 0x6c,
+ 0xad, 0x67, 0x36, 0x27, 0xb1, 0x5e, 0x1a, 0x7e, 0xdd, 0x38, 0xfc, 0xba,
+ 0x51, 0xf8, 0x75, 0x2e, 0x74, 0xe1, 0x90, 0xca, 0x27, 0xa3, 0xde, 0x9f,
+ 0x38, 0x24, 0xd6, 0xd7, 0x32, 0x62, 0x1d, 0xbc, 0x00, 0x1b, 0x61, 0xe9,
+ 0x25, 0xd0, 0x7f, 0xe2, 0x79, 0x11, 0xf2, 0x04, 0xf9, 0xef, 0x31, 0xc9,
+ 0xc6, 0x86, 0xe4, 0xf3, 0x9b, 0x6c, 0x23, 0x3d, 0x65, 0xe5, 0x15, 0xf7,
+ 0x25, 0xc5, 0x67, 0x17, 0x6b, 0xd7, 0x25, 0xf4, 0x84, 0x96, 0xb5, 0x3f,
+ 0x80, 0x3d, 0xd5, 0x48, 0x6b, 0xda, 0xbb, 0x2d, 0xa4, 0x3d, 0xe8, 0xa7,
+ 0x35, 0xca, 0xd8, 0x9b, 0x12, 0xbd, 0xf0, 0x92, 0xbc, 0xf9, 0x82, 0xab,
+ 0xe2, 0x12, 0x6b, 0x4f, 0x2a, 0xdd, 0x07, 0xb9, 0x16, 0x95, 0xf5, 0xcd,
+ 0xdf, 0x91, 0x4f, 0x39, 0x89, 0x2b, 0x94, 0x99, 0x94, 0x5d, 0x5a, 0xa7,
+ 0x41, 0xc6, 0x56, 0x12, 0xa5, 0x32, 0x6c, 0xef, 0x2b, 0xf6, 0x98, 0x64,
+ 0x83, 0xa5, 0x56, 0x3f, 0xfd, 0x82, 0x9a, 0xeb, 0x24, 0x6d, 0x9e, 0xef,
+ 0xbd, 0xb0, 0xad, 0x13, 0x75, 0x25, 0xa3, 0xa8, 0x27, 0x33, 0xd4, 0x9b,
+ 0xd4, 0x7d, 0xd4, 0x3f, 0x8c, 0x97, 0xe3, 0x79, 0x8d, 0xba, 0xe9, 0xef,
+ 0xd4, 0x9d, 0x67, 0x71, 0xc6, 0x91, 0xfa, 0x1a, 0xe5, 0x13, 0xf4, 0xfc,
+ 0x93, 0xb4, 0x73, 0x45, 0xd1, 0x3f, 0xed, 0xdc, 0x47, 0xc5, 0xb7, 0x71,
+ 0xd9, 0xb6, 0xdb, 0xc6, 0xfd, 0x83, 0x7d, 0xd2, 0x1b, 0x05, 0x7e, 0xc8,
+ 0xff, 0x3b, 0x36, 0x60, 0x2e, 0x73, 0x13, 0xb6, 0x26, 0xf7, 0x61, 0xc9,
+ 0xa0, 0x7b, 0x1d, 0x74, 0xc4, 0xb5, 0x6f, 0xb6, 0x3e, 0x1c, 0xe5, 0x1e,
+ 0x2c, 0x65, 0x23, 0x6c, 0x0f, 0xfe, 0xa6, 0x3b, 0x0a, 0xca, 0x88, 0x7d,
+ 0xb0, 0xcd, 0x6d, 0x43, 0xb3, 0x9f, 0x34, 0xbe, 0x04, 0xf8, 0x79, 0x95,
+ 0x7b, 0x28, 0xf3, 0x4e, 0x04, 0x36, 0xd7, 0x22, 0x63, 0x52, 0x6a, 0xdd,
+ 0xf7, 0x67, 0x22, 0x92, 0xbc, 0xd0, 0x25, 0xa9, 0xa7, 0xec, 0x41, 0x9d,
+ 0xb7, 0xf8, 0x30, 0x74, 0xcf, 0x41, 0xb4, 0x1f, 0x90, 0xb2, 0x13, 0x85,
+ 0x3f, 0x33, 0x2a, 0xe5, 0xd1, 0x30, 0x78, 0xe6, 0x01, 0xde, 0x75, 0x28,
+ 0x38, 0xca, 0xce, 0x30, 0xca, 0x6e, 0x94, 0xf7, 0x48, 0xf9, 0xc9, 0x4b,
+ 0xfb, 0xb4, 0x2d, 0xbb, 0xfb, 0xfd, 0x9f, 0x76, 0xab, 0xd8, 0xb9, 0xf5,
+ 0x8e, 0x88, 0xb9, 0x47, 0xff, 0x2d, 0x60, 0xf7, 0xfb, 0x12, 0x9e, 0x90,
+ 0xb8, 0x4f, 0x44, 0x64, 0x18, 0xb2, 0x77, 0x04, 0x7a, 0xeb, 0xe0, 0x85,
+ 0x21, 0x19, 0xbd, 0x10, 0x97, 0xfb, 0x2e, 0xf8, 0xf6, 0xc0, 0xf2, 0x74,
+ 0xca, 0xc4, 0x71, 0xdd, 0xdf, 0x32, 0x8e, 0x7b, 0x9f, 0x9a, 0x1f, 0x30,
+ 0xae, 0x41, 0x1e, 0x46, 0x3f, 0xa7, 0xec, 0x06, 0x8d, 0xfb, 0x1f, 0xc9,
+ 0x91, 0x95, 0x90, 0x1c, 0x55, 0xbc, 0xe8, 0xdb, 0xf0, 0xff, 0x13, 0xfb,
+ 0x48, 0x80, 0x47, 0x4e, 0x18, 0xbf, 0xb3, 0x17, 0x78, 0x25, 0x0e, 0xa1,
+ 0xeb, 0xe0, 0x8b, 0x32, 0x3f, 0xb5, 0x98, 0xee, 0x1c, 0xcf, 0xb1, 0x3f,
+ 0xc5, 0x98, 0x2c, 0x6c, 0x0b, 0xb6, 0xcb, 0x60, 0x40, 0xf6, 0x6a, 0x7f,
+ 0x1f, 0xda, 0x29, 0x73, 0x8e, 0x42, 0xe6, 0xec, 0x6e, 0xcf, 0xa1, 0x8d,
+ 0xeb, 0xdf, 0x83, 0x75, 0xc9, 0x8f, 0x5c, 0xd7, 0xc7, 0x09, 0xcf, 0x75,
+ 0x10, 0xfe, 0x07, 0xcf, 0xb5, 0x4b, 0x0a, 0x0e, 0x73, 0x37, 0x59, 0xf7,
+ 0x16, 0x73, 0xd6, 0x13, 0xe6, 0xac, 0x05, 0xb6, 0x31, 0xed, 0x2d, 0x9d,
+ 0xaf, 0x50, 0x88, 0x26, 0x4a, 0x22, 0x71, 0x15, 0xbf, 0x5b, 0xaf, 0xf8,
+ 0xf6, 0x49, 0xb6, 0x9f, 0xf7, 0x10, 0x8b, 0x69, 0x15, 0x5b, 0x8b, 0x07,
+ 0x3c, 0xda, 0x37, 0xe9, 0x30, 0xf3, 0x92, 0x1b, 0x2b, 0xbc, 0x93, 0x0c,
+ 0xe0, 0x07, 0x3c, 0x07, 0x2d, 0x71, 0x5c, 0xd6, 0x95, 0xb4, 0x6e, 0x9b,
+ 0x01, 0xff, 0xda, 0xaa, 0x4f, 0x3c, 0x97, 0x1e, 0x34, 0xef, 0x31, 0x59,
+ 0xab, 0xbc, 0x63, 0xc8, 0xf6, 0xfe, 0xf6, 0x9e, 0x5c, 0xa6, 0x9f, 0xf7,
+ 0x49, 0xa8, 0x23, 0x9f, 0xbc, 0xa4, 0x72, 0x15, 0xb5, 0xef, 0x10, 0xe4,
+ 0x3d, 0x24, 0xf6, 0xf9, 0x53, 0xd0, 0xf5, 0xee, 0x3d, 0x77, 0x99, 0x3d,
+ 0x73, 0xbf, 0xc4, 0x37, 0xc7, 0xfb, 0x7a, 0x8e, 0x38, 0x0f, 0x77, 0xf8,
+ 0x1b, 0x91, 0x81, 0x9d, 0xfb, 0x73, 0xca, 0x42, 0xca, 0xbf, 0x49, 0x95,
+ 0xef, 0x72, 0xcb, 0x86, 0x1c, 0xaa, 0x42, 0x2e, 0x55, 0x21, 0x8b, 0xaa,
+ 0x90, 0x45, 0xb0, 0x41, 0x9e, 0x85, 0x5c, 0x7d, 0x06, 0xbe, 0xda, 0xd7,
+ 0xab, 0xbe, 0xfd, 0x9e, 0x85, 0x1c, 0x53, 0x36, 0x1d, 0xed, 0x9f, 0x9a,
+ 0xed, 0x75, 0xff, 0xd6, 0xf9, 0x50, 0x01, 0xcf, 0x1f, 0xd7, 0x2d, 0x45,
+ 0x35, 0x26, 0x2e, 0xf3, 0xcd, 0xbd, 0xfa, 0x72, 0x7f, 0xa1, 0x8e, 0xfd,
+ 0x9a, 0xbb, 0x7e, 0x15, 0x8b, 0xa0, 0x0c, 0xfe, 0x4d, 0x3c, 0xd0, 0x99,
+ 0xa7, 0xc9, 0x33, 0x56, 0x39, 0x42, 0x38, 0x53, 0xe2, 0x9d, 0x76, 0x61,
+ 0x59, 0x16, 0x26, 0x17, 0xa5, 0x3c, 0x69, 0xc9, 0xdc, 0x38, 0xce, 0x68,
+ 0x7c, 0x18, 0x3a, 0x32, 0x0d, 0x5d, 0xbb, 0x80, 0x79, 0xc8, 0x7f, 0x0f,
+ 0xe2, 0x5c, 0x1c, 0x73, 0x27, 0xfe, 0xa5, 0xe9, 0x5c, 0x4d, 0xac, 0x6b,
+ 0x2a, 0x47, 0x7c, 0x79, 0xfa, 0xd5, 0x95, 0x87, 0x61, 0x3f, 0x4d, 0xc8,
+ 0xd5, 0xc9, 0x87, 0x65, 0xfb, 0x8e, 0xf1, 0x38, 0x07, 0xc8, 0xe1, 0xcf,
+ 0x6f, 0xf2, 0x1e, 0xb4, 0x4b, 0x66, 0xa3, 0x8c, 0x81, 0xc1, 0xc6, 0x71,
+ 0xfb, 0x65, 0x5b, 0xf9, 0xa1, 0x07, 0xe4, 0xb6, 0xa2, 0x2d, 0xd6, 0x85,
+ 0x50, 0xa7, 0xed, 0xd1, 0xb5, 0x8a, 0x6f, 0x5b, 0x28, 0x1c, 0x99, 0x98,
+ 0x1f, 0xf5, 0x0d, 0xe3, 0x49, 0x8c, 0x2f, 0xad, 0x45, 0x76, 0x64, 0x01,
+ 0x4b, 0xff, 0x5c, 0x3b, 0xfd, 0xe3, 0xbf, 0x8e, 0xe8, 0x6f, 0x0b, 0xba,
+ 0xa4, 0x1c, 0x2d, 0xb5, 0xca, 0x6e, 0xd0, 0xba, 0xda, 0xce, 0x69, 0xf5,
+ 0xdb, 0x48, 0xcb, 0x36, 0x60, 0x25, 0x1d, 0x24, 0x55, 0xee, 0xce, 0x77,
+ 0xaa, 0x03, 0xfb, 0xf4, 0x37, 0x0a, 0x01, 0x8c, 0xe3, 0xfb, 0x89, 0x88,
+ 0x7e, 0xf7, 0xef, 0xdd, 0xdf, 0x86, 0xbe, 0x31, 0x25, 0xaf, 0xd6, 0x6a,
+ 0x01, 0xf0, 0xf0, 0x20, 0x9e, 0x5f, 0x44, 0x9f, 0x30, 0xce, 0x86, 0xb1,
+ 0xa4, 0xb7, 0xa8, 0xfc, 0x9b, 0x80, 0xeb, 0xe7, 0xf5, 0x52, 0x77, 0xff,
+ 0x67, 0xd5, 0xfe, 0xf4, 0x4a, 0x37, 0xf3, 0x55, 0x51, 0x52, 0xaf, 0xff,
+ 0x0a, 0xbe, 0x56, 0x48, 0xf2, 0x35, 0x17, 0xb6, 0x78, 0x88, 0xf4, 0x8b,
+ 0xfa, 0x7b, 0xa1, 0xa3, 0x04, 0xfc, 0xd4, 0x05, 0xbd, 0xa9, 0x70, 0x0d,
+ 0x4a, 0xa2, 0x4f, 0xef, 0xe7, 0x99, 0x6a, 0x38, 0x42, 0xde, 0xf7, 0x98,
+ 0x6f, 0x10, 0x0e, 0x78, 0x2f, 0x4d, 0xcf, 0x55, 0x68, 0x2b, 0xb5, 0x5a,
+ 0xd0, 0x65, 0xd8, 0xc9, 0xcf, 0x94, 0x5f, 0xb1, 0x2d, 0xda, 0x57, 0x5b,
+ 0x50, 0xf9, 0x96, 0x37, 0xa7, 0x35, 0x8d, 0x74, 0xde, 0x9f, 0xbc, 0xd1,
+ 0xdd, 0x49, 0x58, 0xb6, 0xd3, 0x3d, 0x86, 0x2f, 0xc2, 0xc1, 0x62, 0x25,
+ 0x12, 0x9c, 0x53, 0xf7, 0x5b, 0x5b, 0x26, 0x1f, 0xf3, 0xda, 0x74, 0xaa,
+ 0x19, 0x56, 0xb9, 0x00, 0xbc, 0x4b, 0xc8, 0x57, 0x78, 0x97, 0xa2, 0xdb,
+ 0x53, 0xa6, 0x3d, 0xd9, 0x54, 0x6d, 0x2a, 0xde, 0xc5, 0x18, 0x57, 0x37,
+ 0xca, 0xdb, 0x15, 0xca, 0x07, 0xcc, 0xaf, 0x65, 0x09, 0x60, 0x7f, 0x71,
+ 0x7a, 0x6e, 0x85, 0xf0, 0x7d, 0x7f, 0x3a, 0xb7, 0xc2, 0x1c, 0xc8, 0xff,
+ 0x34, 0x7d, 0x63, 0xc5, 0x92, 0x0d, 0x37, 0xa1, 0xe2, 0x57, 0xeb, 0x8c,
+ 0xb1, 0x72, 0x9c, 0x9a, 0xf3, 0x45, 0x23, 0x93, 0xbf, 0x37, 0x3d, 0xbc,
+ 0x1e, 0x90, 0x73, 0x66, 0x0e, 0xbe, 0xc7, 0xd7, 0xef, 0xa0, 0x6b, 0xd0,
+ 0xca, 0x15, 0xd0, 0x4a, 0x2f, 0x6c, 0x09, 0xd2, 0x37, 0x7d, 0xb2, 0x5e,
+ 0xc8, 0x01, 0xae, 0xf3, 0x8c, 0x5a, 0x27, 0x80, 0x75, 0xe6, 0x54, 0xce,
+ 0x78, 0x80, 0x79, 0xb7, 0xb0, 0x35, 0x61, 0x13, 0xba, 0x8c, 0x59, 0xdb,
+ 0xd8, 0xf3, 0x28, 0xf4, 0x12, 0xf3, 0x3f, 0xfe, 0x7b, 0x64, 0x27, 0x6f,
+ 0xfc, 0x39, 0x33, 0xee, 0x9b, 0x18, 0xc7, 0x33, 0x51, 0xf9, 0xe6, 0x6f,
+ 0xb6, 0x65, 0x58, 0xd9, 0x90, 0x3a, 0x07, 0x89, 0x30, 0xd4, 0xb1, 0x57,
+ 0xea, 0xe2, 0x2e, 0xc9, 0xab, 0x7d, 0x7d, 0x53, 0x8d, 0xb3, 0xbc, 0x6f,
+ 0x00, 0x76, 0xda, 0x25, 0x98, 0xbb, 0xaa, 0xe3, 0x6d, 0x79, 0xc5, 0xd3,
+ 0xe0, 0x91, 0x49, 0x3f, 0x57, 0x4f, 0x8f, 0xf3, 0xfb, 0x27, 0xd7, 0x8f,
+ 0x98, 0x9c, 0x8e, 0xbf, 0x6f, 0x65, 0x8f, 0xf7, 0x2a, 0x1b, 0x6c, 0xe7,
+ 0x9b, 0x08, 0x7f, 0x8c, 0xdf, 0xc7, 0xcf, 0x31, 0x7e, 0x74, 0xff, 0x0e,
+ 0xcc, 0x5b, 0xe6, 0xcc, 0x39, 0x8e, 0xb1, 0x49, 0x95, 0xaf, 0xcb, 0xba,
+ 0xe0, 0x7c, 0x86, 0x73, 0x74, 0xde, 0xf7, 0x8c, 0x83, 0x47, 0xb5, 0xcd,
+ 0x57, 0x82, 0x9d, 0x55, 0x06, 0xbf, 0x04, 0x3c, 0xca, 0xf1, 0x61, 0x13,
+ 0x57, 0x7b, 0xa3, 0x38, 0x1f, 0xef, 0x12, 0xc7, 0x21, 0x7b, 0xfc, 0xf1,
+ 0x3c, 0xc7, 0x6b, 0xd3, 0x37, 0x2a, 0xae, 0x9c, 0xad, 0xea, 0x7c, 0x47,
+ 0x8d, 0x07, 0xc6, 0x6e, 0x78, 0xb6, 0x71, 0x99, 0x73, 0xa9, 0x67, 0xe3,
+ 0xf2, 0x5d, 0xd7, 0x8f, 0xad, 0xf1, 0x7e, 0x0a, 0xfd, 0x61, 0xeb, 0x2d,
+ 0x6c, 0x72, 0xff, 0xdf, 0xc4, 0xfe, 0xe9, 0x53, 0x68, 0x5a, 0x3a, 0x08,
+ 0xb9, 0xf5, 0x1f, 0x82, 0xf0, 0x19, 0xa0, 0xbb, 0x6f, 0x05, 0x3b, 0xf7,
+ 0xe7, 0xeb, 0x6b, 0x4d, 0x97, 0x41, 0xd0, 0xc8, 0x62, 0x1b, 0xef, 0x96,
+ 0x04, 0xde, 0x39, 0x02, 0x1d, 0x64, 0x49, 0x61, 0xdc, 0x8d, 0x2d, 0xf0,
+ 0x6e, 0xc1, 0x19, 0x73, 0x1c, 0x95, 0xc7, 0x16, 0x07, 0xbc, 0x7c, 0xe6,
+ 0xb7, 0x02, 0xcc, 0x39, 0x8b, 0xab, 0x5c, 0xdd, 0x6c, 0xd4, 0x05, 0xbc,
+ 0x8e, 0xb2, 0x4f, 0xb4, 0x5e, 0xfe, 0x97, 0xfb, 0x29, 0x6b, 0xfa, 0x5d,
+ 0xff, 0xec, 0x39, 0xf7, 0x8b, 0x98, 0x3b, 0x60, 0xda, 0x7d, 0x1a, 0x09,
+ 0x30, 0xe5, 0x4d, 0x76, 0xbe, 0x01, 0xf1, 0xe3, 0x7c, 0xec, 0xff, 0x2d,
+ 0x05, 0xcb, 0x1c, 0xf4, 0xd0, 0xbc, 0xda, 0xcf, 0x0b, 0xa0, 0x05, 0xca,
+ 0x15, 0x9f, 0x7e, 0x5f, 0x00, 0xfd, 0xee, 0x63, 0x0a, 0xdf, 0x1e, 0xb4,
+ 0xe6, 0xd3, 0x18, 0xe9, 0x8b, 0xb4, 0xf5, 0x8a, 0xe2, 0xb9, 0x52, 0xfb,
+ 0xdc, 0x29, 0xb3, 0x12, 0x4e, 0xdc, 0xf6, 0xcf, 0x9d, 0xcf, 0x7b, 0xe5,
+ 0xb8, 0xfa, 0xfc, 0x91, 0xf9, 0x07, 0x9c, 0x6d, 0xda, 0x9c, 0x6d, 0xa6,
+ 0xe3, 0x9b, 0x04, 0x7f, 0x3e, 0xfa, 0xfb, 0xd4, 0xaf, 0xbc, 0x0b, 0xe2,
+ 0xf7, 0x12, 0xca, 0x44, 0x90, 0x72, 0x9a, 0x7c, 0x94, 0x8b, 0xf3, 0x3e,
+ 0xe5, 0xa4, 0x04, 0xfa, 0x60, 0xb7, 0x8c, 0x86, 0xc4, 0xff, 0x2e, 0xa9,
+ 0x4b, 0xb6, 0x9c, 0x56, 0xeb, 0x06, 0xef, 0x8d, 0x2b, 0x41, 0xd9, 0x50,
+ 0x77, 0x9f, 0xe0, 0xd1, 0xde, 0xa0, 0x2c, 0xba, 0x6d, 0x3d, 0x27, 0x75,
+ 0xf4, 0x59, 0x43, 0xdb, 0xb9, 0x36, 0x6c, 0xd4, 0x07, 0xb0, 0x21, 0xdd,
+ 0xbf, 0x6f, 0x15, 0xa3, 0x77, 0xf4, 0x35, 0x32, 0x96, 0xb1, 0x47, 0xc6,
+ 0xa7, 0x1d, 0xc9, 0xaf, 0x0f, 0xe0, 0x07, 0x19, 0xaf, 0xe4, 0x02, 0x63,
+ 0x91, 0x8c, 0xe7, 0x96, 0xe0, 0x9f, 0x6a, 0x3f, 0x9f, 0xf6, 0xf6, 0x95,
+ 0xcd, 0x44, 0xa9, 0x24, 0x6e, 0xfc, 0x91, 0xf6, 0x77, 0x3c, 0x7d, 0xa5,
+ 0xb0, 0xd7, 0x19, 0xf3, 0x8d, 0xab, 0xfc, 0xd9, 0x1e, 0x2f, 0x11, 0x3b,
+ 0x05, 0xdf, 0xf5, 0xeb, 0x69, 0xc6, 0x7a, 0xef, 0x23, 0xbe, 0xbf, 0xc4,
+ 0x4d, 0xda, 0x23, 0xe3, 0xe2, 0x5e, 0x72, 0x47, 0x1f, 0x11, 0xfa, 0xa7,
+ 0x89, 0xf8, 0x14, 0xf1, 0xd6, 0xfe, 0xbe, 0x20, 0x68, 0xec, 0xa5, 0x71,
+ 0x19, 0xbe, 0xf4, 0x23, 0x15, 0x63, 0xff, 0x70, 0x7a, 0x37, 0x6d, 0xa8,
+ 0x58, 0xf1, 0x78, 0xbf, 0x0c, 0x8f, 0xae, 0x89, 0x40, 0x5b, 0xf0, 0x7b,
+ 0x03, 0x0b, 0x3e, 0xaa, 0x7a, 0x87, 0xbd, 0x1e, 0x57, 0xdf, 0x5c, 0x65,
+ 0x55, 0xde, 0x23, 0x63, 0xc9, 0x3c, 0xd3, 0x88, 0xca, 0x85, 0x7b, 0x16,
+ 0x67, 0x5b, 0x68, 0xf2, 0x7c, 0x19, 0x57, 0x66, 0xdc, 0x98, 0xb1, 0x65,
+ 0xc6, 0x88, 0xf5, 0xf7, 0x53, 0x47, 0x9a, 0x7b, 0xc5, 0x91, 0x89, 0x8b,
+ 0x51, 0xf3, 0x4d, 0x9a, 0x58, 0xdb, 0xd0, 0xbb, 0xf9, 0x9a, 0xa3, 0xee,
+ 0xfd, 0x8a, 0x4e, 0xbf, 0x9c, 0x1c, 0xed, 0x06, 0xce, 0x07, 0x54, 0x3e,
+ 0xa4, 0xed, 0xbe, 0x07, 0x7e, 0x25, 0xfd, 0x38, 0xea, 0x5b, 0x1f, 0xcf,
+ 0x87, 0x50, 0xf7, 0x0b, 0xe0, 0x9e, 0x75, 0xf0, 0x39, 0x95, 0xee, 0xfd,
+ 0xb4, 0x6c, 0x57, 0x98, 0x9f, 0x5d, 0x3f, 0x90, 0x53, 0xe7, 0xc1, 0x98,
+ 0x8d, 0x2f, 0x9b, 0xfc, 0x5c, 0x35, 0xfa, 0xcc, 0x8e, 0xb9, 0xab, 0x66,
+ 0xcc, 0x66, 0x40, 0x8a, 0xeb, 0x94, 0x3f, 0x96, 0x5a, 0xeb, 0x56, 0xe0,
+ 0xad, 0x52, 0xaa, 0xef, 0x75, 0xef, 0xde, 0x6a, 0x3d, 0x93, 0x56, 0xbe,
+ 0xec, 0xf9, 0x92, 0x39, 0x63, 0xfd, 0x1d, 0x64, 0x70, 0x27, 0x7f, 0x38,
+ 0xaa, 0xe3, 0x09, 0xd9, 0x81, 0x5e, 0xfa, 0x0f, 0x7d, 0x1a, 0xbf, 0xf4,
+ 0x7b, 0x7f, 0x65, 0x6c, 0x51, 0xfa, 0xbc, 0x03, 0x4a, 0x4f, 0xdb, 0x0d,
+ 0x9f, 0x4e, 0x98, 0x73, 0x43, 0x7f, 0xf8, 0xa0, 0x64, 0xeb, 0x90, 0x9b,
+ 0x83, 0x7c, 0x3f, 0x6b, 0xc6, 0xf2, 0xb9, 0x25, 0x47, 0x27, 0x76, 0xdf,
+ 0xa7, 0x4f, 0x6a, 0x3f, 0xbb, 0xd7, 0xbf, 0x53, 0xf7, 0x73, 0x4d, 0x7d,
+ 0x78, 0x15, 0x9c, 0xa0, 0x27, 0x1f, 0x06, 0xbd, 0xd6, 0x11, 0xc0, 0xcb,
+ 0x18, 0xe4, 0x80, 0xcb, 0x5c, 0x9d, 0x80, 0x4c, 0x0c, 0x24, 0x98, 0xc3,
+ 0xa7, 0xe0, 0x69, 0xd4, 0x43, 0x68, 0xf3, 0xe1, 0xd4, 0xfe, 0x79, 0xa3,
+ 0xce, 0xf6, 0x38, 0xd6, 0xea, 0x96, 0x89, 0x41, 0xe2, 0x79, 0x37, 0x1c,
+ 0x03, 0x81, 0xbd, 0x73, 0xd4, 0x1e, 0xec, 0x80, 0xef, 0xee, 0xef, 0x47,
+ 0x73, 0xf0, 0xc3, 0x72, 0x2b, 0x8c, 0x15, 0x10, 0xc6, 0x01, 0xc8, 0x39,
+ 0xec, 0x31, 0xed, 0xe7, 0x0e, 0xfb, 0x78, 0xf1, 0x63, 0x0c, 0x21, 0x45,
+ 0x17, 0x73, 0x19, 0xee, 0x25, 0x64, 0x62, 0x0e, 0x84, 0x2b, 0x61, 0xf2,
+ 0x0f, 0x09, 0x9f, 0x7d, 0x40, 0x9f, 0xff, 0xfd, 0x66, 0xbf, 0x7e, 0xce,
+ 0x22, 0xe7, 0xba, 0x17, 0xe3, 0xbf, 0xd2, 0xc2, 0x5a, 0x34, 0xe8, 0xc0,
+ 0xff, 0xbe, 0xaf, 0x7f, 0xaf, 0x9e, 0xab, 0xd7, 0xff, 0xa6, 0x2f, 0x66,
+ 0xbe, 0xe3, 0x23, 0x9c, 0xe4, 0x2f, 0x1f, 0x87, 0x9c, 0x63, 0xc0, 0xdc,
+ 0x23, 0x10, 0x86, 0x9e, 0x5d, 0x30, 0x24, 0xd2, 0x77, 0xca, 0xb8, 0x43,
+ 0x1d, 0x7b, 0x27, 0xad, 0xf5, 0xc9, 0x42, 0xad, 0x57, 0xca, 0x35, 0xe6,
+ 0x53, 0xf3, 0xfb, 0x32, 0xda, 0x59, 0xe4, 0x4b, 0x95, 0x37, 0x69, 0xf2,
+ 0x15, 0x7d, 0xfe, 0xec, 0x43, 0x3f, 0xea, 0x10, 0x94, 0x75, 0x2d, 0x9f,
+ 0xea, 0x72, 0x77, 0xce, 0xe2, 0x7c, 0x3b, 0x67, 0x51, 0xe7, 0x25, 0x15,
+ 0xdb, 0x79, 0x22, 0xcc, 0x89, 0xeb, 0xcc, 0x41, 0x2a, 0xc9, 0xa3, 0x87,
+ 0x7b, 0x24, 0xb9, 0xdc, 0x6b, 0x68, 0xf4, 0x3d, 0x66, 0x1d, 0xac, 0xb7,
+ 0x34, 0x29, 0xc9, 0xa5, 0x3f, 0x86, 0x6f, 0xaf, 0xf2, 0x22, 0x3b, 0xf2,
+ 0xdb, 0x87, 0xcd, 0xb7, 0x48, 0x59, 0x8b, 0xf9, 0x28, 0xf9, 0x25, 0x9c,
+ 0xd7, 0xe1, 0xc4, 0x68, 0xdc, 0xe6, 0xb7, 0xb8, 0x27, 0x24, 0xb9, 0x3a,
+ 0xa9, 0xbf, 0x89, 0x4b, 0xf3, 0x46, 0x3e, 0xa1, 0xec, 0xe9, 0xd4, 0x65,
+ 0x3d, 0x9f, 0xbb, 0xc4, 0xf6, 0x14, 0x6c, 0x47, 0xb6, 0xe7, 0x63, 0x01,
+ 0x75, 0x6b, 0x7f, 0x3f, 0xe8, 0xa9, 0xcb, 0xd8, 0x03, 0xcc, 0xe9, 0xe4,
+ 0x78, 0xda, 0x1e, 0xa7, 0x71, 0x66, 0xf9, 0xb8, 0x2d, 0x1c, 0xa3, 0xe6,
+ 0xc3, 0xb3, 0x7f, 0x47, 0x44, 0x5c, 0x8f, 0xcb, 0x7a, 0xd3, 0x05, 0x4f,
+ 0xe8, 0x9c, 0xf8, 0x62, 0xdd, 0xcf, 0xe5, 0x7c, 0xb4, 0x9d, 0xcb, 0x49,
+ 0x18, 0x0b, 0x95, 0xdd, 0xb4, 0x77, 0xc8, 0xe4, 0x54, 0xf6, 0xa8, 0xfb,
+ 0xd9, 0x0e, 0xf9, 0x67, 0xfa, 0x3f, 0x73, 0x80, 0x77, 0xf7, 0x22, 0x6c,
+ 0x1f, 0x34, 0xed, 0xb0, 0x8f, 0xa2, 0x51, 0xc5, 0x07, 0xc9, 0x86, 0xdf,
+ 0xef, 0xfa, 0x01, 0x9d, 0x0b, 0x4a, 0x3c, 0x79, 0x06, 0xe6, 0x09, 0xf8,
+ 0xb1, 0xac, 0x3b, 0x88, 0xb1, 0x3c, 0x27, 0x94, 0x8d, 0x83, 0x2a, 0xd7,
+ 0x30, 0xe0, 0x4d, 0x99, 0x7b, 0xc1, 0x41, 0xb5, 0x96, 0xe3, 0x71, 0x7e,
+ 0x5f, 0x36, 0xf4, 0x74, 0xac, 0xbf, 0x1b, 0x5e, 0xc6, 0xe0, 0xfc, 0xdc,
+ 0x51, 0xb6, 0xf3, 0x7d, 0x77, 0x1f, 0x3f, 0x4f, 0x34, 0x6b, 0x05, 0xdb,
+ 0x39, 0xf6, 0xc4, 0x25, 0xef, 0x96, 0x51, 0x5e, 0xf6, 0x00, 0x23, 0x9f,
+ 0x51, 0x9a, 0x6f, 0x07, 0x82, 0x4b, 0xfc, 0xed, 0x9e, 0x27, 0x88, 0xb9,
+ 0x7d, 0x9e, 0xdd, 0x3b, 0xa7, 0xb4, 0xcb, 0x3b, 0x6f, 0x6d, 0x57, 0x98,
+ 0x27, 0x51, 0x92, 0x93, 0x99, 0x3e, 0x99, 0xab, 0xd9, 0xfc, 0xc6, 0x93,
+ 0x31, 0x7a, 0xde, 0x83, 0xcb, 0xbc, 0x92, 0x71, 0x23, 0xc6, 0xe7, 0xee,
+ 0x81, 0x6f, 0x4e, 0x7a, 0x1e, 0x91, 0xf5, 0xfa, 0x4c, 0x47, 0xfe, 0x6d,
+ 0x97, 0xa1, 0xb3, 0x7f, 0x1d, 0x92, 0xde, 0x12, 0x7c, 0x32, 0x9f, 0xa7,
+ 0x47, 0xa4, 0x50, 0xef, 0xbc, 0x3b, 0x63, 0xae, 0x4f, 0xe7, 0x37, 0xb4,
+ 0x4a, 0x0f, 0xd6, 0x4a, 0xb4, 0xab, 0xa2, 0x8c, 0x4b, 0xb0, 0xdf, 0x7e,
+ 0xa3, 0x6f, 0xe1, 0x08, 0xf5, 0xbe, 0xc5, 0x12, 0x97, 0xb0, 0x41, 0x47,
+ 0xa8, 0x75, 0x52, 0x72, 0x34, 0x5a, 0x82, 0x8f, 0x3a, 0x62, 0xd6, 0x7d,
+ 0x3b, 0xde, 0xd9, 0xf7, 0x80, 0x69, 0xbf, 0xd7, 0xbc, 0xf7, 0x9a, 0xf7,
+ 0x00, 0xde, 0xeb, 0xad, 0x5a, 0x95, 0x73, 0xb2, 0xe4, 0xf7, 0x22, 0xbc,
+ 0xdb, 0xf2, 0x24, 0x74, 0x59, 0xa0, 0xa7, 0x7a, 0xe5, 0xf1, 0xba, 0xc2,
+ 0xaf, 0xe5, 0x2e, 0xd1, 0x20, 0xd8, 0x6f, 0x9e, 0xef, 0xe6, 0xc1, 0x4f,
+ 0xde, 0x91, 0x37, 0x3c, 0xec, 0x98, 0xdc, 0xec, 0x0e, 0x78, 0xb3, 0x80,
+ 0xf5, 0xd7, 0xe5, 0x41, 0x51, 0x47, 0x69, 0x5f, 0xb9, 0x50, 0xd1, 0xf9,
+ 0x3e, 0x27, 0x2b, 0x80, 0xb5, 0xf6, 0x3f, 0x0e, 0xe8, 0xdc, 0x14, 0x3f,
+ 0x9f, 0x91, 0xf9, 0xee, 0x23, 0x26, 0x27, 0x82, 0x63, 0x99, 0x57, 0xe9,
+ 0xdf, 0x39, 0x76, 0xda, 0xaa, 0xd4, 0x45, 0xd4, 0x33, 0xfc, 0x6e, 0x25,
+ 0x8d, 0xbe, 0x8b, 0x94, 0x35, 0xd0, 0x53, 0xbe, 0x2d, 0xf1, 0x39, 0xe5,
+ 0x1f, 0x76, 0x7e, 0xf7, 0x73, 0x0e, 0xb0, 0xfe, 0x65, 0x93, 0x71, 0xe1,
+ 0x1e, 0x09, 0x2c, 0xfb, 0x79, 0x50, 0x3c, 0x63, 0xda, 0x61, 0xfc, 0xb6,
+ 0xfa, 0x77, 0x77, 0xc5, 0x8c, 0x7d, 0x5b, 0x81, 0x74, 0x3e, 0xe7, 0x30,
+ 0xc7, 0xd4, 0xf1, 0xfc, 0x38, 0x33, 0x73, 0x6b, 0x68, 0x73, 0x1d, 0x14,
+ 0x5b, 0xc5, 0x8d, 0xd8, 0x56, 0x92, 0xfe, 0xc3, 0xbf, 0x4b, 0xde, 0xf8,
+ 0x47, 0xfc, 0x16, 0x46, 0xe7, 0x79, 0xab, 0x75, 0xa2, 0xda, 0x86, 0xe4,
+ 0x37, 0xda, 0x69, 0xf0, 0xd5, 0xbe, 0x2d, 0x9d, 0xf3, 0x1d, 0xc1, 0x7b,
+ 0x06, 0x74, 0x0c, 0x99, 0x2a, 0xfc, 0x1e, 0x9b, 0x7c, 0xc7, 0xef, 0xb1,
+ 0x3d, 0x95, 0x6f, 0xb2, 0x6d, 0xbe, 0x2f, 0xba, 0xde, 0x0c, 0x8a, 0xbd,
+ 0x34, 0xce, 0x6f, 0xd5, 0xf8, 0x6d, 0x23, 0x6c, 0xb5, 0x38, 0xda, 0x99,
+ 0xc7, 0x36, 0xa4, 0xf2, 0x54, 0xca, 0xcd, 0x8f, 0xa0, 0xfc, 0x34, 0xfc,
+ 0x75, 0x1d, 0x9f, 0x2f, 0x37, 0x99, 0xaf, 0xe2, 0xa8, 0x7b, 0xcf, 0xe4,
+ 0x52, 0x01, 0xeb, 0xf9, 0xdf, 0x3e, 0x47, 0x51, 0x47, 0xf8, 0x4a, 0x86,
+ 0x47, 0xfd, 0x5c, 0x84, 0x0d, 0x87, 0x3a, 0xa1, 0xd4, 0x8c, 0xa8, 0x1c,
+ 0x17, 0x6d, 0x8f, 0xd0, 0xd6, 0x0b, 0xa3, 0x2f, 0xf7, 0xda, 0x4b, 0x7d,
+ 0xd5, 0xa2, 0x4c, 0x4a, 0x61, 0x9d, 0x86, 0xca, 0x0f, 0x24, 0x9e, 0x5d,
+ 0xa7, 0x48, 0x7f, 0x4d, 0xc9, 0xf8, 0xc4, 0xe8, 0xac, 0xe4, 0x9d, 0x10,
+ 0x7c, 0xb1, 0xb2, 0xf2, 0x73, 0x5e, 0x80, 0x0d, 0x1d, 0xd9, 0x0a, 0x78,
+ 0xdc, 0x1b, 0xd7, 0xa6, 0x1f, 0xa2, 0xf7, 0xa3, 0xef, 0x8e, 0xc4, 0x2a,
+ 0xab, 0xef, 0xf5, 0x58, 0xcf, 0x7b, 0x01, 0xff, 0x7b, 0x6c, 0xe6, 0xef,
+ 0xc3, 0x4f, 0x68, 0x4e, 0xc9, 0xd9, 0xca, 0x7e, 0xe6, 0xc6, 0xa7, 0xb7,
+ 0x81, 0xb7, 0x93, 0xed, 0x7c, 0x7d, 0xe6, 0xb0, 0xf9, 0xba, 0x87, 0x67,
+ 0xc5, 0x5c, 0x79, 0xd2, 0x19, 0xf3, 0xe5, 0x69, 0x87, 0x0d, 0xc9, 0xe3,
+ 0x4d, 0x3f, 0x47, 0x7e, 0x2f, 0x3b, 0x9c, 0x34, 0xf8, 0x59, 0xf8, 0x86,
+ 0x7e, 0x2e, 0x24, 0x73, 0x36, 0x5b, 0xad, 0x93, 0x69, 0xde, 0xc7, 0xce,
+ 0x1c, 0x5d, 0xc3, 0x1e, 0xaf, 0xd5, 0x81, 0xc3, 0xe3, 0xac, 0x63, 0xee,
+ 0x56, 0xb7, 0xe4, 0xc6, 0x55, 0xbc, 0xaf, 0x77, 0xcd, 0xdd, 0x2f, 0x57,
+ 0x6b, 0x51, 0x95, 0x87, 0x56, 0x84, 0x9d, 0xdf, 0x90, 0xdb, 0x0e, 0xef,
+ 0xa3, 0x8f, 0xa8, 0xf1, 0x3e, 0xbf, 0x73, 0x9d, 0xa8, 0x1c, 0x59, 0xd7,
+ 0xf2, 0xe4, 0x54, 0x06, 0x76, 0xcb, 0x25, 0xb1, 0x3e, 0x9a, 0x19, 0x82,
+ 0xef, 0xcd, 0xb5, 0x52, 0x18, 0x07, 0xda, 0x89, 0x91, 0xd7, 0x7f, 0xd1,
+ 0x6a, 0x00, 0xde, 0xdb, 0x4d, 0xda, 0xeb, 0xb0, 0xa1, 0x66, 0x38, 0xc6,
+ 0x13, 0xfb, 0x02, 0xfb, 0x0c, 0x80, 0xfe, 0x42, 0xfa, 0x7b, 0xb4, 0xca,
+ 0x01, 0x69, 0x38, 0x6c, 0xe3, 0x73, 0x4c, 0x1a, 0x51, 0xdf, 0x4f, 0xf9,
+ 0x21, 0xf0, 0x17, 0x57, 0x32, 0xc9, 0xbf, 0xc3, 0x67, 0x4e, 0xe9, 0x5c,
+ 0xed, 0x18, 0x78, 0x28, 0x68, 0x6c, 0xb3, 0x20, 0xe6, 0xf8, 0xbe, 0xa3,
+ 0x6d, 0x05, 0xde, 0xf1, 0x6b, 0x5b, 0x44, 0xeb, 0x18, 0xde, 0xfb, 0x05,
+ 0xe1, 0x0b, 0xf8, 0x7c, 0x79, 0xc8, 0xd8, 0x14, 0x9d, 0xbe, 0x7c, 0x2a,
+ 0x76, 0x91, 0xff, 0x0f, 0x62, 0xf3, 0x83, 0x32, 0x0b, 0x98, 0xcf, 0x9b,
+ 0x7d, 0x3e, 0x92, 0x71, 0xe5, 0x56, 0x9d, 0x77, 0xf0, 0x07, 0x51, 0x32,
+ 0xdf, 0x90, 0x30, 0x8f, 0x99, 0x9c, 0x4a, 0x0f, 0x7b, 0x3d, 0x21, 0x2f,
+ 0xc3, 0xbe, 0x7e, 0xa5, 0x92, 0x4a, 0x1f, 0x51, 0x71, 0xe7, 0x44, 0xec,
+ 0xaa, 0x8c, 0xc5, 0xe9, 0x03, 0x96, 0x9c, 0x44, 0xec, 0x16, 0xe8, 0xe1,
+ 0x76, 0xe5, 0x50, 0x3f, 0xff, 0x27, 0x45, 0x03, 0xfa, 0xf0, 0xb6, 0xca,
+ 0x81, 0x49, 0x30, 0x66, 0x82, 0xf7, 0x21, 0x93, 0x87, 0xc3, 0x75, 0xd8,
+ 0x36, 0x24, 0x2f, 0x57, 0xda, 0xfa, 0x97, 0xeb, 0xe8, 0xdc, 0x36, 0xa5,
+ 0x5f, 0x8f, 0xf6, 0x53, 0x0e, 0x71, 0x3d, 0x3d, 0x87, 0xdf, 0x87, 0x78,
+ 0xf5, 0x63, 0x91, 0x8e, 0xfe, 0xbe, 0xc1, 0x62, 0xde, 0x0b, 0xf7, 0xfe,
+ 0x13, 0x47, 0xdb, 0x40, 0x1c, 0x97, 0x72, 0x8e, 0xaa, 0xf9, 0x78, 0xdf,
+ 0x3b, 0x24, 0x3f, 0x6e, 0xfa, 0xf3, 0x30, 0x1f, 0x87, 0x39, 0x3f, 0x94,
+ 0x7d, 0x9d, 0x30, 0x68, 0xfd, 0xff, 0xb2, 0x8a, 0xeb, 0x4d, 0xa2, 0x3f,
+ 0x75, 0x34, 0xe8, 0xa5, 0x1e, 0xd3, 0xff, 0xdf, 0xa1, 0x2d, 0xe3, 0xf8,
+ 0x4c, 0x7c, 0x72, 0x1d, 0xd8, 0xf8, 0x0f, 0x38, 0xa6, 0xdd, 0xb7, 0x4b,
+ 0x87, 0xc0, 0xaf, 0x27, 0xa4, 0xb1, 0x92, 0x8a, 0x3d, 0x2e, 0xfe, 0xbc,
+ 0xad, 0x87, 0x79, 0x2f, 0x56, 0xc8, 0x8c, 0x39, 0x0b, 0x0a, 0x1e, 0xde,
+ 0xdd, 0x26, 0x9c, 0xab, 0x58, 0xaf, 0xd1, 0xdc, 0x1d, 0x7b, 0x48, 0x64,
+ 0xb7, 0x24, 0x95, 0xd6, 0x67, 0x33, 0x22, 0x5b, 0x38, 0x9b, 0x3f, 0x31,
+ 0x67, 0xf3, 0x7e, 0xcc, 0xed, 0x5e, 0x18, 0x97, 0xd4, 0x85, 0x54, 0xfc,
+ 0xbc, 0xf0, 0x8e, 0xf9, 0x00, 0xef, 0x98, 0xad, 0x47, 0x32, 0x71, 0xec,
+ 0x37, 0x81, 0xfd, 0xa2, 0x6c, 0xf2, 0x99, 0xdf, 0xf7, 0xef, 0x23, 0x6f,
+ 0x3f, 0x4c, 0x99, 0x49, 0x5c, 0x14, 0x54, 0x1b, 0xec, 0x93, 0xa7, 0x08,
+ 0xd3, 0xbf, 0xe3, 0xf9, 0xa8, 0x58, 0xe8, 0xad, 0x26, 0xbf, 0x5b, 0xd5,
+ 0xf0, 0xe5, 0x01, 0xdf, 0xbc, 0x86, 0x2f, 0x3e, 0xdb, 0xb6, 0x5d, 0x13,
+ 0xb1, 0xb3, 0x42, 0x7b, 0x89, 0xf6, 0x0b, 0xed, 0xfa, 0xbf, 0xe9, 0xd7,
+ 0xb1, 0x3d, 0xf8, 0xb1, 0x0f, 0x64, 0xdb, 0x7b, 0xef, 0x42, 0xdf, 0x6b,
+ 0x19, 0x95, 0x63, 0xec, 0x4c, 0xc9, 0x7b, 0x25, 0xfb, 0x91, 0x44, 0x3c,
+ 0x6b, 0xb9, 0xc6, 0x06, 0x44, 0x59, 0xe7, 0x33, 0x65, 0xae, 0x6b, 0x6c,
+ 0x0b, 0x9e, 0x4d, 0x06, 0x6b, 0x29, 0xdc, 0xc2, 0x67, 0x1a, 0x02, 0xcd,
+ 0x93, 0xd6, 0xde, 0x05, 0x1e, 0xd2, 0xff, 0x13, 0xe3, 0x2a, 0xf0, 0x58,
+ 0x06, 0x1e, 0x4f, 0xdd, 0x65, 0x83, 0x85, 0xda, 0x36, 0xd8, 0xb6, 0x5a,
+ 0xef, 0x26, 0x60, 0xca, 0x3b, 0xb4, 0xbf, 0xca, 0x6d, 0x5a, 0x21, 0x4c,
+ 0xe3, 0xfc, 0x2e, 0x5b, 0xae, 0x67, 0x78, 0x1e, 0xb0, 0xc1, 0x30, 0xdf,
+ 0xda, 0x0e, 0x2d, 0x61, 0xff, 0x8a, 0x7e, 0x41, 0xbb, 0x09, 0x27, 0x68,
+ 0xf1, 0x2c, 0x38, 0x9f, 0x58, 0x37, 0x00, 0xcb, 0xb6, 0xa2, 0x03, 0x4d,
+ 0x03, 0xdb, 0xf5, 0xde, 0x37, 0xa0, 0x01, 0xee, 0x93, 0xf4, 0xe7, 0xd3,
+ 0x5e, 0xfb, 0xbb, 0x75, 0xf8, 0xb7, 0x25, 0xb9, 0xff, 0x90, 0x27, 0xb9,
+ 0x0b, 0x2d, 0x59, 0x48, 0x8b, 0x35, 0x76, 0x88, 0x34, 0x49, 0x3b, 0x01,
+ 0x36, 0x64, 0x8c, 0x38, 0xd6, 0xf6, 0xe0, 0xec, 0x57, 0xf7, 0xe3, 0xf7,
+ 0x6f, 0xfa, 0x79, 0xbf, 0x94, 0xdb, 0xa0, 0xbc, 0x12, 0xeb, 0xbe, 0x43,
+ 0xda, 0x3f, 0xbc, 0x1d, 0x05, 0xce, 0xd1, 0x9e, 0x7c, 0xa2, 0xcb, 0xc4,
+ 0x51, 0xb5, 0x5e, 0x4e, 0x3e, 0x41, 0xbc, 0xa2, 0xfc, 0xea, 0x4f, 0x1c,
+ 0x3f, 0x27, 0x49, 0xc7, 0x04, 0xc9, 0x17, 0x25, 0x99, 0xcf, 0x30, 0x27,
+ 0xb4, 0x57, 0x8e, 0x40, 0xae, 0x4d, 0x55, 0x26, 0xe5, 0x0b, 0x95, 0x88,
+ 0xb2, 0x1b, 0xfe, 0x2c, 0x9d, 0x8a, 0x8d, 0x5a, 0x2d, 0x79, 0x04, 0xf6,
+ 0xcf, 0xec, 0x50, 0x97, 0xbc, 0x32, 0xae, 0xf3, 0x6f, 0x6f, 0x33, 0xb9,
+ 0xce, 0x61, 0xce, 0x28, 0xf7, 0x03, 0xb9, 0x6f, 0xc1, 0x17, 0xb0, 0xba,
+ 0x65, 0x36, 0x1a, 0x91, 0xe9, 0x34, 0xca, 0x37, 0xa7, 0xd5, 0x37, 0xa4,
+ 0xd9, 0x68, 0xa7, 0x1c, 0x21, 0xcc, 0x2c, 0xdf, 0x62, 0xca, 0x9f, 0xf5,
+ 0x77, 0xc0, 0x62, 0xcd, 0x67, 0x02, 0x6a, 0x7f, 0xe5, 0x3a, 0xe5, 0x1b,
+ 0xc7, 0x40, 0x9e, 0x34, 0x79, 0x0f, 0x59, 0x92, 0x35, 0xc8, 0x97, 0x62,
+ 0x4d, 0xac, 0x8d, 0x0c, 0x2c, 0x6a, 0x57, 0xdb, 0x9f, 0x45, 0xd0, 0xd7,
+ 0x5c, 0x8d, 0xf2, 0x6f, 0x4a, 0xe5, 0x4e, 0xcf, 0xc1, 0xd6, 0x85, 0x4f,
+ 0x3c, 0xdb, 0xed, 0x99, 0x7b, 0xce, 0x5e, 0xc6, 0x43, 0x3a, 0x65, 0x98,
+ 0xff, 0x3f, 0x73, 0x0e, 0x0f, 0x48, 0x5f, 0x09, 0xe7, 0xe2, 0xdb, 0xdc,
+ 0xc0, 0x29, 0xd6, 0xcc, 0xa9, 0x73, 0xf2, 0xcf, 0x84, 0xb2, 0xa7, 0x33,
+ 0x67, 0xdb, 0xb7, 0x39, 0xc8, 0xb3, 0xd4, 0x17, 0x52, 0x0a, 0xc3, 0xa6,
+ 0xed, 0xb9, 0x00, 0xdd, 0x5d, 0xf3, 0x40, 0x2b, 0x93, 0xd0, 0x87, 0x93,
+ 0x52, 0x86, 0xed, 0xf6, 0xd1, 0xf4, 0x67, 0xc5, 0x7e, 0xea, 0xa0, 0xac,
+ 0xd5, 0x7a, 0x80, 0x0f, 0xea, 0x85, 0x90, 0xf2, 0xaf, 0x6f, 0x1f, 0xa7,
+ 0xbe, 0xa3, 0x2e, 0xd1, 0x67, 0xb1, 0x5d, 0xff, 0xc4, 0x80, 0xfe, 0x7e,
+ 0x65, 0xbf, 0x6c, 0xd5, 0x7d, 0x5d, 0x08, 0xff, 0xb0, 0x16, 0x32, 0x7a,
+ 0xb9, 0x17, 0xb2, 0xfb, 0xaf, 0x43, 0x0d, 0xe5, 0xab, 0x73, 0xff, 0xd4,
+ 0x41, 0xea, 0xff, 0x70, 0xf4, 0x36, 0x5c, 0xee, 0xbd, 0x53, 0x07, 0x69,
+ 0xbb, 0xc3, 0x39, 0xcc, 0xf5, 0x78, 0x1f, 0xc7, 0x3d, 0x46, 0x25, 0x74,
+ 0xf1, 0x84, 0xd8, 0xf0, 0x5b, 0x02, 0x4b, 0xb4, 0xf5, 0xee, 0xf4, 0x5d,
+ 0x02, 0x97, 0x6d, 0xf3, 0xad, 0xed, 0xb0, 0xb6, 0x65, 0x32, 0x28, 0x1b,
+ 0xfe, 0xf7, 0xb7, 0xfc, 0xdd, 0xe1, 0xdb, 0x1d, 0x78, 0x03, 0x5d, 0x8a,
+ 0xbf, 0xff, 0x0b, 0xc4, 0xbf, 0x6d, 0x24, 0x80, 0x4a, 0x00, 0x00, 0x00 };
static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_COM_b09FwRodata[(0x30/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000e20, 0x08000e78,
- 0x08000ebc, 0x08000f50, 0x08000f94, 0x80080100, 0x80080080, 0x80080000,
+ 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000ea4, 0x08000efc,
+ 0x08000f40, 0x08000fd4, 0x08001018, 0x80080100, 0x80080080, 0x80080000,
0x00000000 };
static struct fw_info bnx2_com_fw_09 = {
- /* Firmware version: 4.4.23 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
.start_addr = 0x080000f8,
.text_addr = 0x08000000,
- .text_len = 0x4c18,
+ .text_len = 0x4a7c,
.text_index = 0x0,
.gz_text = bnx2_COM_b09FwText,
.gz_text_len = sizeof(bnx2_COM_b09FwText),
@@ -866,1210 +865,1189 @@ static struct fw_info bnx2_com_fw_09 = {
.data_index = 0x0,
.data = bnx2_COM_b09FwData,
- .sbss_addr = 0x08004c60,
+ .sbss_addr = 0x08004ae0,
.sbss_len = 0x38,
.sbss_index = 0x0,
- .bss_addr = 0x08004c98,
- .bss_len = 0xbc,
+ .bss_addr = 0x08004b18,
+ .bss_len = 0xc0,
.bss_index = 0x0,
- .rodata_addr = 0x08004c18,
+ .rodata_addr = 0x08004a7c,
.rodata_len = 0x30,
.rodata_index = 0x0,
.rodata = bnx2_COM_b09FwRodata,
};
static u8 bnx2_CP_b09FwText[] = {
- 0xad, 0xbc, 0x0b, 0x74, 0x1c, 0xd5, 0x95, 0x2e, 0xfc, 0x55, 0x75, 0xb7,
- 0xd4, 0x92, 0xda, 0x52, 0x4b, 0x6e, 0xcb, 0x6d, 0xd0, 0xe0, 0x6a, 0xab,
- 0xda, 0x6a, 0x2c, 0x01, 0xd5, 0xb2, 0x0c, 0x4d, 0xa6, 0xc0, 0x1d, 0x5b,
- 0x80, 0x0c, 0x26, 0x11, 0xc6, 0xb9, 0x23, 0xe6, 0x7a, 0xfe, 0xf4, 0x18,
- 0x03, 0x86, 0x90, 0x5c, 0x33, 0x93, 0x9b, 0x71, 0xb8, 0x9e, 0xeb, 0x8a,
- 0xe4, 0x87, 0xc0, 0xa5, 0xee, 0x96, 0x90, 0x1f, 0xac, 0x35, 0xeb, 0xa7,
- 0x2d, 0xcb, 0x92, 0x21, 0xad, 0x16, 0x49, 0x98, 0x19, 0xe7, 0xe6, 0x81,
- 0xc6, 0xd8, 0x60, 0x93, 0xf0, 0xc8, 0x6b, 0xfd, 0x4c, 0xfe, 0xb9, 0x7f,
- 0x3c, 0xb6, 0x79, 0x83, 0xe3, 0x3c, 0x47, 0x9e, 0xc1, 0xa9, 0xff, 0xdb,
- 0xd5, 0xdd, 0xb6, 0xec, 0x40, 0x1e, 0xeb, 0x8e, 0xd6, 0xaa, 0xa5, 0xee,
- 0xaa, 0x73, 0xf6, 0x39, 0x67, 0x9f, 0xbd, 0xbf, 0xfd, 0xed, 0x73, 0x4e,
- 0xb5, 0x06, 0x54, 0xa3, 0xf4, 0x37, 0x8b, 0xd7, 0xd5, 0x1d, 0x1b, 0xee,
- 0x5e, 0xdc, 0x7e, 0x75, 0x87, 0x7c, 0xf7, 0xce, 0xf5, 0x7a, 0xf1, 0x61,
- 0x7f, 0x26, 0x12, 0x97, 0xde, 0xd2, 0x3e, 0xb4, 0xe0, 0x47, 0xfc, 0x25,
- 0x10, 0x91, 0x7f, 0xad, 0xa5, 0xaf, 0x1e, 0x20, 0x58, 0x6e, 0x5f, 0x2e,
- 0xf8, 0x55, 0xb3, 0xf3, 0xbf, 0x2e, 0xd3, 0xe1, 0xf7, 0x98, 0x9f, 0xff,
- 0x8b, 0xbb, 0x75, 0x20, 0x99, 0x6f, 0xd5, 0x96, 0xe3, 0x9c, 0x63, 0x85,
- 0xbc, 0x90, 0xfb, 0x7f, 0x62, 0x7e, 0xf0, 0xc4, 0xb7, 0xae, 0x8b, 0x9c,
- 0xc9, 0x79, 0xe0, 0x0f, 0x9a, 0x16, 0x82, 0x0b, 0xe1, 0x6f, 0x62, 0x9d,
- 0xbf, 0x6b, 0xd9, 0xa6, 0xa2, 0xb6, 0x2c, 0x2b, 0x12, 0xce, 0x21, 0x12,
- 0xb4, 0x10, 0x89, 0x59, 0x40, 0xca, 0x6b, 0x22, 0x55, 0x69, 0xfa, 0x51,
- 0xa1, 0x57, 0x20, 0x15, 0xdc, 0xa8, 0x6d, 0xe1, 0x18, 0x97, 0xd9, 0x7e,
- 0xed, 0x44, 0x1e, 0xb8, 0xdb, 0xf6, 0xe3, 0xb8, 0x27, 0xa0, 0x9d, 0xcc,
- 0xef, 0xab, 0x2b, 0xea, 0x23, 0x09, 0x8f, 0x8e, 0x94, 0x6a, 0xca, 0x7d,
- 0x68, 0xcb, 0xf3, 0x48, 0xf9, 0xcc, 0xcf, 0x6b, 0xe3, 0x36, 0xd0, 0x9b,
- 0x69, 0x36, 0x4e, 0xa0, 0x35, 0x7c, 0x18, 0x95, 0x48, 0x85, 0x22, 0x31,
- 0xe0, 0x83, 0x73, 0x8f, 0x66, 0x14, 0xf8, 0xf4, 0xd9, 0xe8, 0xdc, 0x0b,
- 0x3c, 0x92, 0x89, 0x24, 0x75, 0x05, 0xe8, 0x9f, 0x94, 0xba, 0x91, 0x60,
- 0x8e, 0xcf, 0xb7, 0x64, 0x80, 0xad, 0x99, 0xd9, 0xd8, 0x96, 0x75, 0xf0,
- 0x9c, 0xd1, 0x1c, 0xdc, 0xc7, 0x16, 0x7a, 0xdd, 0xe7, 0xb3, 0x61, 0xe5,
- 0xe4, 0xf9, 0x5b, 0xce, 0xb7, 0x5a, 0x82, 0x78, 0x7a, 0x32, 0x84, 0x67,
- 0x27, 0xeb, 0xf1, 0x48, 0xb6, 0x1e, 0xdb, 0xb3, 0x31, 0xa8, 0xba, 0x83,
- 0x58, 0x3c, 0x86, 0x8a, 0xeb, 0x1d, 0x9c, 0x34, 0xda, 0xb0, 0x95, 0x82,
- 0x5f, 0x6d, 0x6b, 0xc4, 0xda, 0x60, 0x13, 0xb6, 0xe8, 0xd7, 0xa1, 0x38,
- 0xd6, 0x0f, 0xce, 0x65, 0x32, 0xd2, 0x3f, 0xaf, 0xaa, 0xea, 0x37, 0xe2,
- 0xf4, 0x4e, 0x13, 0xef, 0xef, 0xc4, 0x9a, 0x5a, 0x38, 0x4e, 0x3e, 0x1e,
- 0xed, 0x7e, 0x50, 0x09, 0x6a, 0x4f, 0xe5, 0xd9, 0xa1, 0x55, 0x5e, 0xca,
- 0x83, 0x36, 0x92, 0x9f, 0x39, 0x15, 0x6c, 0x2f, 0xc3, 0x76, 0x33, 0xd2,
- 0x97, 0x30, 0xbe, 0xd5, 0xf2, 0xdf, 0x68, 0x0f, 0xc5, 0x31, 0x6d, 0xcd,
- 0xbc, 0xc6, 0x3e, 0x69, 0xec, 0x4f, 0x13, 0xbe, 0x36, 0x19, 0xc6, 0x57,
- 0xd9, 0xb7, 0xaf, 0x4c, 0x4a, 0x1f, 0x23, 0x7b, 0x2c, 0xd4, 0x63, 0x34,
- 0xdb, 0x84, 0xa7, 0xf5, 0x36, 0x7c, 0x85, 0x7d, 0xec, 0x33, 0x62, 0x58,
- 0x9b, 0xb8, 0x8b, 0xfd, 0x51, 0xb0, 0xaa, 0xed, 0x2f, 0x4b, 0xfd, 0x8a,
- 0x68, 0x50, 0x55, 0x24, 0x1b, 0x22, 0x31, 0x4d, 0x15, 0x99, 0x17, 0xfa,
- 0x3b, 0x90, 0x81, 0xe5, 0x37, 0xa5, 0xcf, 0x37, 0x22, 0xcf, 0xfe, 0x7e,
- 0x79, 0x67, 0xd4, 0x58, 0xaf, 0x62, 0x65, 0x80, 0x7d, 0x7e, 0x20, 0x1e,
- 0x4d, 0x2c, 0x62, 0x9f, 0xc7, 0xf3, 0x2a, 0xc7, 0x13, 0xd2, 0xc6, 0xd8,
- 0xf7, 0xe4, 0x2a, 0x95, 0x7d, 0x67, 0x5f, 0x32, 0xec, 0x4b, 0x86, 0x7d,
- 0xc9, 0xb0, 0x2f, 0x6e, 0xbf, 0x63, 0xec, 0x73, 0x71, 0x8e, 0x46, 0xf2,
- 0xc7, 0xd9, 0xdf, 0x99, 0xfd, 0x6c, 0x62, 0xdf, 0x91, 0xaa, 0xe7, 0xbc,
- 0x35, 0xa7, 0x65, 0xde, 0x1c, 0xe7, 0x55, 0xc3, 0x71, 0x7e, 0x6e, 0x04,
- 0xa8, 0xbf, 0x0c, 0xed, 0xa0, 0xdc, 0x9f, 0xf9, 0x56, 0x85, 0x89, 0x4e,
- 0x9a, 0xa0, 0x73, 0xa4, 0x23, 0x9a, 0x68, 0x50, 0x54, 0x78, 0xf5, 0xa0,
- 0xd6, 0x52, 0x88, 0x18, 0xd4, 0x8f, 0x16, 0x2d, 0x40, 0xd3, 0x0b, 0x94,
- 0x75, 0x51, 0xbb, 0x91, 0xe0, 0x14, 0xa4, 0x5d, 0x8d, 0xed, 0x1f, 0x2f,
- 0xcd, 0x9d, 0xc8, 0x0f, 0xb3, 0x4d, 0x69, 0x5f, 0x64, 0x3b, 0xce, 0xcf,
- 0x0c, 0xe8, 0x41, 0x44, 0xad, 0x41, 0xda, 0x9f, 0xc7, 0x0c, 0x6a, 0x1b,
- 0xf2, 0x7c, 0x7e, 0x5e, 0x46, 0x71, 0x3e, 0xd6, 0xe6, 0xb5, 0xd2, 0x18,
- 0x22, 0xec, 0x82, 0xd8, 0x41, 0x38, 0x15, 0x30, 0x83, 0xd2, 0xf7, 0xee,
- 0x3d, 0x03, 0x9b, 0x9d, 0x79, 0xba, 0xe8, 0x4a, 0xdf, 0x38, 0xcf, 0x13,
- 0x48, 0x9c, 0x5e, 0xf2, 0x90, 0x35, 0xab, 0x23, 0x8e, 0x6a, 0x1d, 0x81,
- 0x2a, 0x1d, 0xdd, 0xe9, 0x89, 0x6a, 0xab, 0xc6, 0xfc, 0xe6, 0x9d, 0x03,
- 0x13, 0x7e, 0x54, 0x4f, 0xe8, 0xa8, 0x9a, 0x78, 0xdc, 0x8b, 0x5a, 0x03,
- 0x3b, 0x26, 0xff, 0xcc, 0x5b, 0x1c, 0xdb, 0xcd, 0xa5, 0x31, 0xba, 0xb6,
- 0xef, 0x7f, 0xdd, 0x3e, 0xe3, 0x54, 0xe8, 0x55, 0x7f, 0xe6, 0x31, 0x75,
- 0x6d, 0x0c, 0x38, 0xb3, 0xb6, 0x63, 0x39, 0x7a, 0x83, 0x0a, 0xe6, 0xeb,
- 0x7f, 0x32, 0x0b, 0xb5, 0x26, 0xac, 0xc9, 0xc6, 0x54, 0x85, 0x19, 0x4a,
- 0x71, 0x6e, 0xf0, 0x82, 0x9d, 0x83, 0x6f, 0xc0, 0x71, 0xa4, 0xec, 0x49,
- 0xdc, 0x79, 0xa7, 0x6a, 0x1e, 0xba, 0xc6, 0x87, 0x4e, 0x96, 0xc7, 0xa6,
- 0xa3, 0x1d, 0x3f, 0x57, 0xd4, 0x9d, 0xdd, 0xb0, 0xc6, 0x3d, 0x48, 0x06,
- 0x53, 0xfc, 0x7f, 0xc5, 0x15, 0x2b, 0x13, 0xdd, 0xb0, 0xc7, 0xa7, 0x79,
- 0xdf, 0xcb, 0x7b, 0x26, 0xd2, 0x99, 0x2b, 0xae, 0xb8, 0x3d, 0x91, 0xc2,
- 0xc0, 0xb8, 0x7c, 0xf6, 0x62, 0xaa, 0x3e, 0x85, 0xed, 0xbb, 0x35, 0xd4,
- 0xe9, 0xdd, 0xc8, 0x8c, 0xcb, 0x67, 0xc7, 0x39, 0x65, 0x7c, 0x09, 0x7b,
- 0xda, 0xe8, 0xff, 0x73, 0xbb, 0xb1, 0x6d, 0xb7, 0x85, 0x4a, 0xdd, 0xa2,
- 0xee, 0x15, 0xef, 0x3f, 0xb7, 0x29, 0xd0, 0xee, 0x84, 0xb7, 0x42, 0x17,
- 0xbd, 0x25, 0xbc, 0xf7, 0xd8, 0x66, 0x70, 0xbe, 0xee, 0x38, 0x23, 0xc6,
- 0x22, 0x7c, 0xba, 0x7b, 0x2d, 0xac, 0x7d, 0x01, 0x58, 0xab, 0xe5, 0x7f,
- 0x37, 0x75, 0xb8, 0x16, 0xbd, 0xfb, 0xd6, 0xa2, 0xff, 0x31, 0x3a, 0x6e,
- 0x7d, 0xd0, 0x9d, 0xa7, 0x6f, 0xb5, 0x48, 0x9f, 0xa4, 0x7f, 0x3d, 0xbc,
- 0x44, 0xb7, 0x5f, 0xe0, 0x7f, 0x29, 0x33, 0xed, 0x60, 0xce, 0x85, 0x32,
- 0xdb, 0x59, 0x66, 0xdb, 0x45, 0x65, 0x4c, 0x3c, 0x31, 0x29, 0xba, 0x10,
- 0x95, 0xfd, 0x3e, 0x5d, 0x7c, 0xdb, 0xe9, 0x0d, 0x89, 0x2e, 0xac, 0x1e,
- 0x1f, 0x22, 0xdd, 0xf7, 0x2a, 0x5e, 0xac, 0x18, 0x00, 0xeb, 0xd0, 0x09,
- 0xaa, 0x23, 0xc9, 0x85, 0x8a, 0x89, 0xea, 0x01, 0x05, 0x2b, 0xe2, 0x55,
- 0xd0, 0xea, 0x45, 0xde, 0x8f, 0x1c, 0x2b, 0x28, 0xfd, 0x3d, 0x8a, 0x1a,
- 0xde, 0x5f, 0x17, 0xff, 0x01, 0xf1, 0x4c, 0xfa, 0x14, 0x67, 0xf9, 0x3b,
- 0x78, 0xff, 0x95, 0x19, 0xdf, 0xa5, 0x9c, 0xe3, 0xf4, 0x19, 0x06, 0xfa,
- 0x33, 0x6d, 0xd8, 0x9e, 0x49, 0x46, 0xa8, 0x25, 0xcb, 0x67, 0xf2, 0xbe,
- 0x19, 0xed, 0xea, 0x85, 0xb4, 0x03, 0xa5, 0xda, 0x84, 0x37, 0xdf, 0x71,
- 0xdc, 0xff, 0x92, 0xad, 0xf7, 0x3c, 0xa5, 0xf8, 0x68, 0xec, 0xd2, 0xce,
- 0x71, 0xff, 0x2b, 0xb6, 0x82, 0x37, 0xf5, 0xe8, 0x86, 0x77, 0x94, 0xe3,
- 0xfe, 0x97, 0xf3, 0x41, 0xcc, 0x1b, 0x88, 0xf4, 0x58, 0x4a, 0x02, 0x5f,
- 0xcf, 0x87, 0x10, 0x1e, 0x30, 0x71, 0x30, 0x6f, 0xe0, 0xc9, 0x8b, 0x70,
- 0xe0, 0x43, 0xff, 0x2c, 0x0f, 0xc7, 0xbe, 0xce, 0xd6, 0xd0, 0x6b, 0x9c,
- 0x73, 0x92, 0x41, 0xa4, 0xea, 0xcc, 0xe3, 0xfe, 0xf7, 0x07, 0xa0, 0xd4,
- 0x9a, 0x7a, 0xb8, 0xa0, 0xfc, 0xab, 0x93, 0x0a, 0x49, 0x31, 0xf6, 0xcf,
- 0xc5, 0xb2, 0x24, 0xed, 0xce, 0x20, 0xce, 0x9d, 0x71, 0x6a, 0x68, 0xb3,
- 0x15, 0xe6, 0x65, 0x18, 0x1f, 0xd6, 0xf1, 0xa4, 0xed, 0x38, 0xef, 0x19,
- 0x53, 0x89, 0x00, 0xf4, 0xee, 0x77, 0x11, 0x49, 0x2e, 0xa2, 0x5e, 0x8e,
- 0xe6, 0x75, 0x8c, 0xda, 0x26, 0x9e, 0xb3, 0x9b, 0x83, 0x7d, 0x58, 0x8c,
- 0x64, 0xb8, 0x18, 0x43, 0x26, 0xd8, 0xef, 0x91, 0x68, 0x37, 0xea, 0xcc,
- 0x04, 0x0e, 0xb1, 0xdf, 0xa7, 0x97, 0x88, 0x1c, 0x03, 0x2f, 0xff, 0x01,
- 0x7d, 0x25, 0xbe, 0xe3, 0x71, 0xf6, 0x35, 0xb1, 0xf8, 0x9c, 0x83, 0xd9,
- 0x7e, 0x9c, 0x30, 0xe6, 0xd2, 0x0e, 0x61, 0x55, 0x99, 0x7e, 0x6f, 0xbf,
- 0x1d, 0xc4, 0x81, 0x7c, 0xc0, 0xdb, 0x67, 0x87, 0xb0, 0x8f, 0xfe, 0x36,
- 0x8f, 0xa6, 0x1e, 0xa6, 0xdc, 0x79, 0xc4, 0xb5, 0xc2, 0x70, 0x13, 0x26,
- 0x87, 0x23, 0xc6, 0x2b, 0x4a, 0x18, 0x63, 0xa3, 0x97, 0x61, 0x62, 0x58,
- 0xc1, 0x78, 0x94, 0x7d, 0xe7, 0xe7, 0x2f, 0x0f, 0x5f, 0x81, 0xfc, 0xb0,
- 0x07, 0x3b, 0x5c, 0xbd, 0xba, 0x38, 0x53, 0xfa, 0x7f, 0x19, 0x72, 0xa3,
- 0xf0, 0x2e, 0x1a, 0x08, 0xe2, 0xa9, 0xbc, 0xd7, 0xab, 0x0f, 0x84, 0x30,
- 0x9a, 0xff, 0x36, 0xe7, 0x4d, 0x64, 0x6b, 0x18, 0xb1, 0xc7, 0xdc, 0x39,
- 0xac, 0x33, 0x29, 0xac, 0x18, 0x5f, 0x19, 0xcb, 0x34, 0xc6, 0x99, 0x04,
- 0x71, 0x48, 0x7c, 0xdc, 0x4f, 0x0c, 0x12, 0x1f, 0x7f, 0x4d, 0x41, 0x6d,
- 0x02, 0x7d, 0x93, 0xe5, 0xe7, 0x0a, 0xed, 0xdf, 0x8b, 0x75, 0x41, 0x03,
- 0x76, 0x46, 0xec, 0xb4, 0x8c, 0xcb, 0xf2, 0x59, 0xe6, 0xbf, 0x1a, 0xd6,
- 0xfe, 0x6a, 0xec, 0xa0, 0x8f, 0x3d, 0xba, 0x53, 0xee, 0x3b, 0xce, 0x7d,
- 0xf1, 0x3a, 0xda, 0x18, 0x6e, 0xaa, 0x42, 0xd4, 0x78, 0xcb, 0xed, 0x9b,
- 0x85, 0xb1, 0xbc, 0xc4, 0x50, 0x8d, 0xf1, 0xed, 0x28, 0xdb, 0xea, 0x60,
- 0x3b, 0x06, 0xbe, 0x3d, 0xd9, 0x86, 0x7f, 0x9c, 0x8c, 0xe1, 0x1f, 0x26,
- 0x75, 0xfc, 0xfd, 0xa4, 0x86, 0x67, 0x2e, 0xc2, 0xf5, 0x3b, 0xa9, 0x2b,
- 0xc1, 0x30, 0x03, 0x5b, 0x32, 0x15, 0xd8, 0x36, 0x5c, 0x8d, 0xbe, 0xe1,
- 0xe6, 0xd8, 0x73, 0xc4, 0xe3, 0x7f, 0x30, 0x6e, 0xc7, 0x54, 0x43, 0x87,
- 0xeb, 0x33, 0x8f, 0xf0, 0xfe, 0xa3, 0xc3, 0xcd, 0x9c, 0x43, 0xc7, 0x51,
- 0xe3, 0xad, 0x89, 0x43, 0xc4, 0xf7, 0xe3, 0xa1, 0x88, 0x36, 0xa5, 0x46,
- 0xb4, 0x24, 0x7c, 0xb0, 0xdb, 0x54, 0x58, 0x73, 0x22, 0x39, 0x7a, 0x31,
- 0x42, 0xfa, 0x7d, 0x1c, 0x5b, 0x44, 0xb3, 0x54, 0x83, 0xf6, 0xcb, 0x98,
- 0xa1, 0x76, 0x10, 0x5f, 0xaa, 0xf1, 0xfe, 0x70, 0xa4, 0xdf, 0x52, 0xef,
- 0x80, 0xd5, 0xe0, 0x38, 0x5f, 0x8d, 0x63, 0xc3, 0x5c, 0x13, 0xc9, 0x39,
- 0x8c, 0x05, 0x57, 0x98, 0x49, 0x30, 0x8e, 0xe1, 0xf4, 0x80, 0x1e, 0xfe,
- 0x7f, 0x94, 0x3b, 0xf1, 0xdf, 0xbb, 0x23, 0x9a, 0xa6, 0xb6, 0x5a, 0xfb,
- 0x54, 0x92, 0x8d, 0x46, 0x68, 0x61, 0xf3, 0x56, 0x6c, 0x74, 0x79, 0x82,
- 0x82, 0xa0, 0xde, 0x81, 0xbe, 0x0c, 0x2b, 0x85, 0x9a, 0x7b, 0x06, 0xd5,
- 0xe6, 0x69, 0x43, 0x8d, 0x1c, 0xed, 0x56, 0x89, 0xb7, 0x8b, 0x4f, 0x3b,
- 0x5a, 0xa3, 0xe3, 0xb4, 0x2f, 0x96, 0x36, 0x35, 0x34, 0x70, 0x9e, 0xeb,
- 0x39, 0xcf, 0xed, 0x85, 0x6a, 0xbc, 0x33, 0x0c, 0x6b, 0xae, 0x19, 0xe9,
- 0x7a, 0x40, 0xad, 0xc6, 0xdb, 0xa3, 0xd5, 0x38, 0x39, 0xec, 0xc5, 0x5b,
- 0xc3, 0x8e, 0x73, 0x8f, 0x51, 0x87, 0x8a, 0x38, 0xe6, 0x54, 0x20, 0x7a,
- 0x66, 0x04, 0x16, 0x7e, 0xc3, 0xb2, 0xbf, 0x1c, 0x0e, 0xe3, 0x57, 0xc3,
- 0x1f, 0xc3, 0x33, 0x0d, 0xc9, 0x63, 0xb3, 0x19, 0x23, 0xa7, 0x69, 0x3f,
- 0xa7, 0xed, 0x48, 0xcf, 0x3c, 0x4f, 0x64, 0x23, 0x79, 0xcb, 0xfa, 0x2f,
- 0x2a, 0x91, 0xd4, 0x2b, 0x4a, 0x44, 0x1b, 0x50, 0x42, 0x78, 0x97, 0x76,
- 0x7a, 0x2a, 0xdf, 0x9c, 0xf8, 0x01, 0xdb, 0xff, 0xb5, 0xf1, 0x0f, 0xce,
- 0x54, 0xa3, 0xe8, 0x50, 0xf4, 0x45, 0x9d, 0xd3, 0x77, 0xff, 0x91, 0x31,
- 0xea, 0x1f, 0x32, 0xd4, 0x39, 0xfb, 0xf3, 0xcc, 0x6f, 0xc5, 0x2f, 0x99,
- 0xaf, 0x04, 0xe7, 0xf1, 0x72, 0xfc, 0x4f, 0x77, 0x6c, 0xc7, 0x9c, 0xbf,
- 0x09, 0xc9, 0xf8, 0x3a, 0x1b, 0x8b, 0x18, 0x24, 0xe3, 0x3c, 0xea, 0xa4,
- 0x82, 0x32, 0x46, 0x19, 0xab, 0xab, 0x4b, 0x6d, 0x83, 0xf2, 0x90, 0x8a,
- 0x6a, 0xc7, 0x79, 0xcc, 0x28, 0x3d, 0x0f, 0x95, 0xc7, 0xfa, 0x31, 0xde,
- 0x97, 0xf1, 0xbe, 0xe3, 0x11, 0xdd, 0x6b, 0xea, 0xd5, 0xfc, 0x1e, 0xb1,
- 0x92, 0xb8, 0x33, 0xc0, 0xef, 0xb1, 0xe4, 0xf9, 0xef, 0xde, 0xba, 0x8b,
- 0x9f, 0xd3, 0x4e, 0xdd, 0xf6, 0xee, 0xe4, 0x77, 0x19, 0xcb, 0xab, 0xb4,
- 0x9b, 0x0f, 0xb3, 0x13, 0xb1, 0x91, 0x18, 0xed, 0xe9, 0x94, 0xc4, 0x15,
- 0x2b, 0x64, 0xfa, 0x2d, 0xd5, 0x84, 0x46, 0x9c, 0xf0, 0x2b, 0xe6, 0x06,
- 0x68, 0x79, 0x0b, 0x9f, 0xea, 0xf0, 0xe0, 0xaf, 0x3a, 0x14, 0xcc, 0xd6,
- 0x37, 0x20, 0x7b, 0xad, 0xe5, 0xd4, 0xeb, 0x7b, 0x55, 0xf1, 0x81, 0x8a,
- 0x34, 0x2c, 0xfa, 0x1d, 0x12, 0xe4, 0x4a, 0x75, 0x7f, 0xaa, 0xe0, 0x44,
- 0x3c, 0x4a, 0x9b, 0xdb, 0x82, 0x6d, 0x9c, 0xf3, 0x59, 0x69, 0xf8, 0x03,
- 0xa6, 0x09, 0x7b, 0x00, 0xfe, 0x2a, 0xfa, 0xfe, 0x95, 0x03, 0xcd, 0x1b,
- 0xc6, 0x94, 0x48, 0x22, 0xad, 0x44, 0xba, 0xa9, 0x6f, 0xe3, 0xb4, 0x8b,
- 0x1b, 0x11, 0xad, 0x42, 0x91, 0x76, 0x4c, 0xb4, 0xe4, 0xb7, 0x60, 0x60,
- 0x52, 0x3e, 0x27, 0xa0, 0xe7, 0x7f, 0x5c, 0xea, 0x3b, 0xfc, 0x3e, 0xf6,
- 0x61, 0xbf, 0xfd, 0xba, 0x93, 0x0b, 0x46, 0xb4, 0x9c, 0xfb, 0x7d, 0x3d,
- 0xbf, 0xc3, 0x5f, 0x61, 0x3e, 0x88, 0xe7, 0xed, 0x37, 0xe7, 0x94, 0xcb,
- 0x15, 0xfb, 0x7a, 0x69, 0x7f, 0xfe, 0xb7, 0x93, 0x0c, 0xb9, 0xfd, 0xf1,
- 0xd7, 0xb0, 0x8d, 0xcf, 0x0c, 0xb0, 0x8d, 0x4c, 0xb9, 0x3f, 0x40, 0x20,
- 0x2d, 0x71, 0x38, 0xa2, 0x2d, 0x50, 0x9a, 0x8d, 0x01, 0x25, 0x12, 0xbb,
- 0x57, 0x69, 0x4d, 0x8c, 0x91, 0x5f, 0x6e, 0x47, 0xb1, 0x4f, 0xd1, 0x7c,
- 0xb1, 0x3f, 0x0b, 0xf2, 0x50, 0x3c, 0x03, 0x08, 0xcc, 0xd7, 0x17, 0x62,
- 0xb3, 0x3b, 0xa7, 0x50, 0xc2, 0x03, 0x1a, 0x6a, 0xc9, 0x5f, 0xc2, 0x13,
- 0xc0, 0xe4, 0x10, 0xb9, 0x5c, 0xbc, 0x19, 0x9f, 0x63, 0x2c, 0x98, 0xc7,
- 0x32, 0x5f, 0x0c, 0x9e, 0xc7, 0x2f, 0xa5, 0xdf, 0x26, 0xc0, 0xcc, 0x29,
- 0xf2, 0xb2, 0xd4, 0x7f, 0x41, 0x52, 0xee, 0x3d, 0x6e, 0x43, 0xc9, 0xd8,
- 0x91, 0x3d, 0x80, 0x3e, 0x15, 0xf7, 0x24, 0xef, 0x0f, 0x63, 0x33, 0x4e,
- 0xc7, 0xa3, 0xa9, 0x82, 0x12, 0x35, 0x86, 0x14, 0xc3, 0xbf, 0x8d, 0xed,
- 0xed, 0x60, 0x99, 0xed, 0xbc, 0x1e, 0x88, 0xea, 0x5d, 0x77, 0x28, 0xc9,
- 0x2b, 0xab, 0x58, 0xe6, 0xa4, 0x11, 0x25, 0xcf, 0x8c, 0x4e, 0xaf, 0x82,
- 0xe1, 0x7f, 0x22, 0x2f, 0xb2, 0x12, 0xca, 0x96, 0xc2, 0xe3, 0x6a, 0x11,
- 0x8f, 0x7e, 0x5d, 0xd2, 0xd9, 0x49, 0xf9, 0xee, 0xb6, 0xed, 0x1d, 0x68,
- 0xaa, 0xf9, 0xed, 0x7b, 0xda, 0x9c, 0x8b, 0xef, 0xb5, 0x06, 0x47, 0xe9,
- 0x7f, 0x1e, 0xbd, 0x8a, 0x73, 0x27, 0xfc, 0x28, 0x19, 0xf3, 0x41, 0xee,
- 0x79, 0x90, 0xf3, 0x26, 0xc3, 0x1e, 0x7c, 0xe0, 0x24, 0x57, 0xcb, 0xbd,
- 0x6a, 0xa4, 0xba, 0x5b, 0xc3, 0x5e, 0xb4, 0x26, 0xb6, 0x12, 0x0b, 0x8e,
- 0xaf, 0x5e, 0xc6, 0x67, 0x51, 0xe3, 0x39, 0x34, 0x6b, 0x5b, 0x21, 0x9f,
- 0xcf, 0xd2, 0x66, 0x97, 0x49, 0x5d, 0x96, 0x29, 0x72, 0x1f, 0xc1, 0x9a,
- 0x2d, 0x86, 0x83, 0xe7, 0x0d, 0x58, 0x95, 0xe6, 0x41, 0xe5, 0x84, 0xfd,
- 0x1b, 0x27, 0xe9, 0xc5, 0x4a, 0xfa, 0xa5, 0x41, 0xda, 0xab, 0xf9, 0xcd,
- 0xa8, 0x76, 0x94, 0x99, 0x82, 0xc7, 0xb4, 0x94, 0xe3, 0xf9, 0x2d, 0xca,
- 0xeb, 0xf9, 0x7e, 0xe5, 0x54, 0x5e, 0xea, 0x1e, 0x54, 0x4e, 0xe6, 0x25,
- 0x1e, 0x36, 0x69, 0x47, 0xc8, 0x6f, 0xc8, 0xa9, 0xd4, 0x3e, 0x03, 0xca,
- 0x36, 0xa3, 0x96, 0x3c, 0x5f, 0x8f, 0x8d, 0xb0, 0xbf, 0xfb, 0x3b, 0x60,
- 0x6c, 0x37, 0x7c, 0x38, 0x1e, 0x44, 0xa0, 0xcf, 0xf0, 0xca, 0x77, 0xe6,
- 0x03, 0x52, 0xb7, 0x49, 0xdb, 0x9a, 0x3f, 0x47, 0xff, 0x2a, 0x7e, 0xdf,
- 0xdf, 0x51, 0xbe, 0xf7, 0x0b, 0x67, 0x6a, 0xb5, 0xca, 0xef, 0x7f, 0xea,
- 0xe1, 0x50, 0x58, 0x77, 0x26, 0x3f, 0x17, 0x2e, 0xa5, 0x92, 0x3f, 0xd6,
- 0xc3, 0x0a, 0x46, 0xac, 0x1c, 0x73, 0x85, 0xbe, 0x4c, 0x3b, 0xfd, 0x2d,
- 0xcc, 0x58, 0x99, 0x24, 0xbe, 0x93, 0xf7, 0xb2, 0xcd, 0x0a, 0x3d, 0x80,
- 0x9b, 0xec, 0x66, 0x4f, 0x51, 0x7f, 0x2a, 0x31, 0xcc, 0xc3, 0x98, 0x2e,
- 0x1c, 0xef, 0x52, 0xce, 0xdd, 0xa4, 0xbd, 0xc5, 0x7e, 0x57, 0xe9, 0x7a,
- 0xac, 0x4a, 0x69, 0xd2, 0x5e, 0xcf, 0x27, 0xe9, 0xe3, 0x3d, 0x6c, 0x37,
- 0x80, 0xd7, 0xed, 0x5a, 0xe6, 0x20, 0x91, 0xa4, 0x45, 0x81, 0x37, 0x77,
- 0x84, 0x41, 0xce, 0x37, 0xe3, 0xaf, 0x1b, 0x8c, 0xff, 0x12, 0xa3, 0xd5,
- 0x5b, 0x96, 0x24, 0xb0, 0x3e, 0x0f, 0xef, 0xba, 0x0e, 0x13, 0xf7, 0x30,
- 0xb6, 0xdf, 0xc7, 0x78, 0xf9, 0x20, 0x63, 0xe1, 0x8e, 0x38, 0xc7, 0x56,
- 0xef, 0x38, 0x95, 0xfa, 0x66, 0xc9, 0x67, 0x30, 0xc0, 0x58, 0x7c, 0x37,
- 0xe3, 0xcb, 0x16, 0x7e, 0x7e, 0x29, 0xff, 0x1f, 0xce, 0x7d, 0xcc, 0xa7,
- 0x9e, 0xbf, 0x48, 0x26, 0xd4, 0x51, 0xbd, 0x35, 0xb6, 0x95, 0xb1, 0x98,
- 0x72, 0xad, 0x5a, 0xd3, 0x71, 0xae, 0x8c, 0x46, 0x92, 0x3e, 0xc5, 0xc0,
- 0x73, 0x13, 0xc7, 0x1d, 0x6d, 0x8e, 0xe4, 0x52, 0xe5, 0x38, 0x28, 0x63,
- 0x95, 0x1c, 0x41, 0xf0, 0x41, 0xf2, 0x84, 0x99, 0x18, 0xa1, 0xe2, 0xe6,
- 0x61, 0xc9, 0x13, 0xc2, 0x58, 0x65, 0x7f, 0x09, 0xcf, 0xb5, 0x79, 0xd1,
- 0xc5, 0x1c, 0xeb, 0x16, 0x3b, 0x80, 0x3b, 0x88, 0xa5, 0x2b, 0x6c, 0xe6,
- 0x4e, 0xc1, 0x10, 0x6e, 0xb5, 0xbd, 0x38, 0xdc, 0xc6, 0x1c, 0x28, 0x54,
- 0x89, 0x77, 0x0d, 0x0f, 0x8e, 0x18, 0x41, 0xe4, 0x5c, 0x7f, 0xd8, 0x41,
- 0x0c, 0xa4, 0x1e, 0x55, 0xc9, 0x1d, 0x44, 0x87, 0x1e, 0xea, 0x53, 0x45,
- 0xea, 0xbc, 0x0e, 0x3f, 0x2c, 0x17, 0x90, 0x7e, 0x49, 0x3e, 0xf0, 0x33,
- 0x27, 0x35, 0x47, 0xea, 0xc3, 0x0a, 0x98, 0x32, 0x0e, 0xe1, 0xb7, 0x06,
- 0xfa, 0x26, 0x3a, 0xc8, 0xed, 0x66, 0x0e, 0xf5, 0x0c, 0xb9, 0x75, 0x1d,
- 0x5e, 0xd3, 0x85, 0x5b, 0xbf, 0x8a, 0x20, 0x7d, 0xb7, 0x7f, 0x22, 0xba,
- 0xe1, 0x8c, 0xe2, 0xc1, 0x4b, 0x7a, 0x2d, 0x79, 0x9f, 0x89, 0xed, 0x13,
- 0xf0, 0x6e, 0x5d, 0x62, 0x20, 0x3d, 0xd1, 0x9b, 0x98, 0xc5, 0xb4, 0xd7,
- 0xbb, 0xa4, 0xc8, 0x89, 0x3e, 0x43, 0xdd, 0xae, 0x8d, 0xbb, 0x9c, 0xa8,
- 0xc8, 0x07, 0x82, 0x8e, 0x73, 0x52, 0x17, 0x3d, 0x03, 0x07, 0x4a, 0x3a,
- 0xde, 0xcf, 0xcf, 0xfd, 0x25, 0x1d, 0x6f, 0xa1, 0x3c, 0xfa, 0x1f, 0xb6,
- 0x5d, 0xc4, 0x63, 0x34, 0x54, 0x9a, 0xc2, 0x6f, 0x88, 0xc3, 0xc4, 0x93,
- 0x24, 0x75, 0xfc, 0x42, 0x7e, 0xbd, 0xe0, 0x36, 0xa7, 0xbb, 0xdd, 0xc5,
- 0xef, 0xa4, 0x7a, 0x80, 0x76, 0x20, 0x7a, 0x78, 0xad, 0x94, 0xdb, 0x38,
- 0xce, 0x90, 0x21, 0x3a, 0x2e, 0xe7, 0x65, 0xa2, 0xeb, 0x36, 0xc9, 0xb1,
- 0xfa, 0x81, 0xdf, 0xb0, 0xac, 0x87, 0xb8, 0x6b, 0xe2, 0x6b, 0xdd, 0x62,
- 0x3b, 0xb3, 0xdc, 0x58, 0x79, 0xd5, 0x42, 0xc7, 0xf9, 0x4a, 0x5c, 0xc3,
- 0x7b, 0x7a, 0x6b, 0xa2, 0x5d, 0x8d, 0xb0, 0xaf, 0x49, 0xd8, 0x93, 0x1d,
- 0x9c, 0xbb, 0x2b, 0x90, 0x0c, 0x89, 0xad, 0x61, 0x43, 0x45, 0x11, 0xc3,
- 0x71, 0xca, 0xd6, 0x63, 0xdb, 0x38, 0x67, 0xfb, 0x42, 0x5d, 0xe4, 0x71,
- 0x6a, 0x27, 0xd3, 0x7f, 0xf2, 0x27, 0xdd, 0x7a, 0x04, 0xef, 0x38, 0xb9,
- 0x90, 0xc3, 0x38, 0x29, 0xb9, 0xd1, 0x7c, 0x1c, 0x0e, 0x7a, 0xf0, 0x62,
- 0xac, 0x11, 0xc9, 0x7a, 0x05, 0x35, 0xfa, 0x9b, 0xce, 0x77, 0x42, 0xd2,
- 0x0e, 0x73, 0x3c, 0xf5, 0x56, 0x8f, 0xe4, 0x80, 0x5e, 0x5d, 0xe4, 0x76,
- 0x31, 0xc7, 0xbd, 0xb4, 0xfd, 0x7f, 0x75, 0x8e, 0x87, 0xa4, 0xfd, 0x48,
- 0x50, 0x53, 0x7f, 0xd7, 0x1c, 0x7e, 0xdf, 0xf9, 0x81, 0x2b, 0x33, 0xe3,
- 0xea, 0x01, 0xaa, 0xc8, 0x23, 0x54, 0x54, 0x8b, 0xcc, 0x72, 0x3b, 0xe2,
- 0x67, 0x73, 0x79, 0x4f, 0x9e, 0x89, 0x8d, 0x6c, 0x61, 0xbb, 0xcf, 0x39,
- 0x68, 0x94, 0xef, 0xd3, 0x1e, 0x29, 0x6b, 0x4d, 0x1e, 0x5a, 0xe1, 0xc5,
- 0x52, 0xb4, 0xc4, 0x97, 0x2d, 0x97, 0xb1, 0xa8, 0x66, 0x52, 0xf3, 0xc3,
- 0x6a, 0xf4, 0x10, 0x8b, 0xdf, 0x68, 0x6b, 0xc3, 0x72, 0xe6, 0x8c, 0xef,
- 0x10, 0x5c, 0x7a, 0x75, 0x0f, 0xa6, 0x38, 0xbe, 0x27, 0x0d, 0x59, 0x2f,
- 0x70, 0x70, 0x4b, 0xdc, 0x4a, 0xd1, 0x63, 0xad, 0x59, 0xb4, 0x9d, 0x6a,
- 0x5d, 0xe2, 0x7c, 0x2d, 0x6a, 0x4c, 0x6f, 0xec, 0x1d, 0x44, 0x8c, 0x1d,
- 0xe4, 0x39, 0x5a, 0x7d, 0x4b, 0xc2, 0x47, 0xed, 0xbe, 0x6c, 0x47, 0x13,
- 0x47, 0x94, 0xa2, 0x3f, 0xbc, 0xc0, 0xb9, 0x7d, 0xcd, 0xd6, 0x37, 0x56,
- 0x7a, 0x8a, 0xdf, 0x5f, 0x71, 0xf3, 0xd1, 0xb2, 0x3f, 0x84, 0x4b, 0xb8,
- 0xe1, 0xf7, 0x9f, 0xb2, 0x71, 0x86, 0x54, 0x88, 0x79, 0x29, 0xce, 0xf4,
- 0x19, 0x53, 0x8a, 0x4f, 0xaf, 0x25, 0xae, 0x0a, 0x96, 0x56, 0x90, 0x13,
- 0x4a, 0xec, 0xf7, 0xfb, 0xdf, 0x61, 0x19, 0x72, 0xba, 0xe3, 0xb1, 0xeb,
- 0x5b, 0x13, 0x7e, 0x24, 0xad, 0x4a, 0xfa, 0xe5, 0x2c, 0x33, 0xe4, 0xbf,
- 0xaa, 0x60, 0x35, 0x06, 0x68, 0xd7, 0x35, 0xcc, 0x57, 0x5b, 0xd2, 0x13,
- 0x8c, 0xe1, 0x6d, 0x78, 0x70, 0x82, 0x23, 0x6b, 0x18, 0x6c, 0x54, 0x4d,
- 0x59, 0x83, 0x08, 0xc2, 0xd7, 0xf0, 0xe0, 0x0d, 0xaa, 0x79, 0x1c, 0x3d,
- 0x1d, 0xfe, 0xce, 0x44, 0x01, 0xfe, 0x7a, 0x73, 0x13, 0xe2, 0x69, 0xc9,
- 0x3b, 0x05, 0x23, 0x93, 0x5b, 0x89, 0x5a, 0x8d, 0x75, 0xd7, 0x96, 0xf5,
- 0x0d, 0xb5, 0xd6, 0x94, 0xfc, 0x53, 0xeb, 0x7c, 0xc5, 0xc5, 0xd2, 0x20,
- 0xf3, 0x85, 0x1f, 0x87, 0xff, 0xcf, 0xea, 0x27, 0x38, 0x27, 0xd2, 0x17,
- 0xf9, 0x2f, 0x79, 0x3f, 0xbc, 0x2a, 0xb1, 0xb0, 0x77, 0xdc, 0xcb, 0xfc,
- 0x4a, 0xe6, 0x4c, 0xe2, 0xf1, 0x6b, 0xff, 0xf5, 0x79, 0xfa, 0x8b, 0x8f,
- 0xba, 0x7f, 0x44, 0xb7, 0x08, 0xf3, 0x8e, 0xa3, 0xc7, 0x23, 0xe1, 0x0a,
- 0x45, 0xc3, 0xf6, 0xb6, 0x7f, 0xa7, 0x8d, 0x80, 0x38, 0x06, 0x12, 0xeb,
- 0x5a, 0x6c, 0x19, 0xaf, 0x98, 0x51, 0xaf, 0x67, 0x4d, 0xb9, 0xde, 0x80,
- 0x6e, 0xa5, 0xa4, 0xde, 0x68, 0x3c, 0xd2, 0xb3, 0x8d, 0xf5, 0x1e, 0x65,
- 0xbd, 0x24, 0x63, 0xe7, 0x3d, 0x13, 0x41, 0x37, 0x9f, 0xb3, 0xc6, 0xab,
- 0x67, 0xb6, 0x77, 0xbe, 0xde, 0xe3, 0xba, 0x35, 0xe5, 0xb6, 0xb7, 0x38,
- 0xb2, 0xb1, 0xc2, 0xe3, 0x45, 0x9a, 0xf5, 0xa6, 0x58, 0xef, 0xf5, 0x09,
- 0x59, 0x8f, 0xc0, 0x0d, 0xe3, 0x76, 0xe6, 0xb8, 0x47, 0xd7, 0x83, 0x27,
- 0x91, 0x24, 0xe6, 0xba, 0x73, 0x79, 0xc3, 0x58, 0x7e, 0x33, 0xb6, 0xeb,
- 0x87, 0xe2, 0x95, 0xac, 0x77, 0x44, 0x3f, 0x14, 0xf6, 0xd1, 0xaf, 0xd6,
- 0x51, 0x5e, 0x2f, 0xf3, 0x1a, 0x95, 0xfe, 0xb2, 0x65, 0x5c, 0x62, 0xbf,
- 0x41, 0x5e, 0x12, 0xa2, 0xcd, 0xc9, 0x98, 0xa5, 0x5d, 0x99, 0x53, 0x19,
- 0x5f, 0x24, 0x36, 0xee, 0x8e, 0x4f, 0x99, 0x7b, 0x40, 0x72, 0xdd, 0x7a,
- 0x0b, 0x7d, 0x6d, 0x12, 0xff, 0x14, 0x62, 0x6f, 0x03, 0xf3, 0x4f, 0x69,
- 0x23, 0x84, 0x6d, 0xf4, 0xed, 0xfd, 0x86, 0xe3, 0x3c, 0x6f, 0xcc, 0xc7,
- 0x01, 0x23, 0x92, 0x12, 0x3b, 0x7c, 0xd3, 0x58, 0x76, 0xa5, 0xe4, 0x96,
- 0xc0, 0x9f, 0x60, 0x8a, 0xb6, 0x51, 0xa5, 0x8b, 0xbf, 0x29, 0x08, 0x47,
- 0xbd, 0x5a, 0x8d, 0xe2, 0xc0, 0xbf, 0x78, 0xe1, 0xc6, 0x85, 0x1c, 0x7b,
- 0xed, 0xf5, 0x0a, 0xde, 0xbf, 0x4a, 0xc1, 0xa1, 0xab, 0xa2, 0xe1, 0x11,
- 0x65, 0x16, 0xb1, 0x35, 0xda, 0xdd, 0xa9, 0x58, 0x47, 0x59, 0x37, 0xd9,
- 0xe6, 0x89, 0x84, 0xa1, 0xd4, 0xd1, 0xef, 0x5b, 0x34, 0x09, 0xfd, 0xde,
- 0x81, 0x68, 0xf8, 0x51, 0xfe, 0xf7, 0x4c, 0x28, 0x98, 0xd0, 0x23, 0x49,
- 0xb8, 0xf2, 0xd9, 0x36, 0xd3, 0xce, 0xab, 0xa3, 0x8e, 0x73, 0x2c, 0xde,
- 0x1a, 0x3c, 0x86, 0x37, 0x89, 0x6d, 0xd2, 0x4e, 0x19, 0xeb, 0xc1, 0x5c,
- 0x56, 0x4f, 0x76, 0x2a, 0x8e, 0x57, 0xf8, 0xc3, 0xfa, 0xbc, 0xc4, 0xc3,
- 0x72, 0x7f, 0xcb, 0x71, 0xd1, 0x71, 0xde, 0x34, 0x8a, 0xb2, 0x82, 0x1d,
- 0x91, 0x14, 0x30, 0x1f, 0x93, 0x7a, 0xa4, 0x6b, 0x8a, 0x3a, 0x08, 0xd3,
- 0xdf, 0xe6, 0xe9, 0x8d, 0x38, 0xee, 0x8b, 0x04, 0x8f, 0x2b, 0xcb, 0xcf,
- 0xaa, 0x58, 0xb4, 0xfe, 0x09, 0xa5, 0x75, 0x43, 0x15, 0xf4, 0x64, 0x41,
- 0x99, 0x2b, 0x3a, 0x09, 0x07, 0xc8, 0xa5, 0xd6, 0xc1, 0x8d, 0xd1, 0xb8,
- 0xcd, 0xf6, 0x26, 0xa7, 0xd1, 0x4c, 0xdb, 0xd7, 0x7b, 0xee, 0x23, 0x0f,
- 0x04, 0x3e, 0xce, 0x24, 0x41, 0xfa, 0xda, 0x88, 0xd4, 0xa7, 0x1c, 0xe7,
- 0x7e, 0xf6, 0x75, 0x07, 0xfb, 0xfa, 0x60, 0xfc, 0x3d, 0xe7, 0x5f, 0x5d,
- 0x99, 0x37, 0x62, 0x44, 0xbf, 0x54, 0xee, 0xbb, 0xcc, 0xf5, 0x45, 0xae,
- 0x0f, 0x37, 0xcf, 0x61, 0xbe, 0xd2, 0x21, 0xb8, 0x71, 0xd2, 0x4b, 0xdc,
- 0xa0, 0x3c, 0xc6, 0x10, 0xf5, 0xd2, 0x38, 0xec, 0x01, 0xe3, 0x5b, 0x38,
- 0xa5, 0xa8, 0x24, 0x42, 0x41, 0xf8, 0x75, 0x07, 0x0f, 0x90, 0x33, 0x24,
- 0xe7, 0xd4, 0xe1, 0x73, 0x86, 0x1f, 0xb3, 0xa2, 0xea, 0x65, 0x1e, 0xce,
- 0xc9, 0x81, 0xb8, 0x7c, 0xf7, 0x61, 0x6a, 0x8e, 0x07, 0x9b, 0xc9, 0x25,
- 0x82, 0x51, 0x75, 0x9e, 0xdc, 0xf7, 0xb7, 0xcb, 0x77, 0xf6, 0x7f, 0xae,
- 0x82, 0xfb, 0x69, 0x15, 0x6a, 0xb4, 0x37, 0x2c, 0xf7, 0xbb, 0x0c, 0xf9,
- 0xae, 0xa0, 0x39, 0xee, 0xe5, 0xbc, 0x38, 0xf0, 0x48, 0x7a, 0x1f, 0xe5,
- 0xfd, 0xb8, 0x7c, 0x4e, 0xde, 0xcf, 0x71, 0x27, 0xf7, 0x29, 0x82, 0x33,
- 0x3f, 0x72, 0x5e, 0x64, 0x1c, 0x09, 0xf2, 0xf9, 0xe7, 0xd8, 0xf6, 0xd1,
- 0xf8, 0xf3, 0xce, 0x3c, 0xe2, 0xeb, 0xb1, 0x84, 0x86, 0xf9, 0x57, 0x35,
- 0xe1, 0xf8, 0x9d, 0x32, 0x66, 0x05, 0xb3, 0xf4, 0x2f, 0xf8, 0x24, 0xcf,
- 0xac, 0xd5, 0xe7, 0xe2, 0xe6, 0x3b, 0x8a, 0xf7, 0xaa, 0xa2, 0xb2, 0x4e,
- 0xa8, 0xa1, 0xea, 0xaa, 0x06, 0x68, 0xa5, 0x7b, 0xcb, 0xa3, 0xde, 0xee,
- 0x59, 0x8a, 0x1e, 0xbc, 0x4d, 0x91, 0xe7, 0xbf, 0x24, 0xb7, 0x75, 0x9c,
- 0x07, 0x38, 0x5f, 0x2d, 0xf1, 0x00, 0x4e, 0xb3, 0x9d, 0x5e, 0xea, 0x6f,
- 0xe5, 0xf9, 0xf9, 0x2a, 0xd7, 0xff, 0xb9, 0xa3, 0x7d, 0x4a, 0xea, 0x8a,
- 0x8c, 0x85, 0x5d, 0x37, 0x2b, 0x1c, 0x50, 0xb5, 0xe8, 0xd9, 0xd5, 0x19,
- 0xcb, 0xf6, 0xba, 0xdf, 0x83, 0x1d, 0xaf, 0x9d, 0x5f, 0xf3, 0x3a, 0xe3,
- 0xc6, 0xa3, 0x65, 0xd7, 0x07, 0x71, 0xdc, 0xa9, 0x6f, 0xb7, 0x82, 0x95,
- 0x90, 0xb8, 0xd4, 0x1c, 0xfb, 0x0a, 0xe5, 0xfe, 0xc0, 0x28, 0xc6, 0xac,
- 0xfd, 0x46, 0x24, 0x6b, 0xd1, 0x1f, 0x52, 0xcc, 0x13, 0x3b, 0x25, 0x76,
- 0x4f, 0xd6, 0xfa, 0x50, 0x3b, 0x1f, 0x95, 0xed, 0x91, 0xfe, 0x05, 0xcc,
- 0x9b, 0x3c, 0x1d, 0x12, 0xeb, 0x64, 0x7e, 0xdc, 0x32, 0x6c, 0xab, 0x0a,
- 0xcb, 0xd9, 0xc7, 0x78, 0xfb, 0xef, 0x8b, 0x13, 0x22, 0x47, 0xac, 0x33,
- 0xd2, 0x9f, 0xc4, 0xef, 0x2b, 0x0b, 0x46, 0x65, 0x59, 0x4f, 0xf2, 0xdf,
- 0x90, 0xca, 0xab, 0xe4, 0x19, 0x15, 0xc1, 0xde, 0x8e, 0x46, 0x5e, 0xf2,
- 0xdc, 0x7b, 0xc3, 0xda, 0xfc, 0xf9, 0x75, 0x3c, 0x64, 0x8d, 0x0a, 0xa8,
- 0x57, 0x0b, 0x66, 0x13, 0x7d, 0x83, 0x32, 0x3e, 0x8b, 0x56, 0x2e, 0x39,
- 0x7a, 0xe7, 0x5d, 0x77, 0xd3, 0x9f, 0x9f, 0x63, 0x8b, 0xa3, 0xe4, 0x33,
- 0x96, 0xeb, 0x19, 0xe2, 0xeb, 0x33, 0xd7, 0xf5, 0x24, 0x86, 0x94, 0xd7,
- 0x06, 0x1b, 0x30, 0xb8, 0xfb, 0x0e, 0x68, 0x8d, 0x45, 0x1c, 0x52, 0xcd,
- 0xc5, 0x58, 0x96, 0x7d, 0xdb, 0x57, 0xe4, 0xe0, 0xb5, 0x18, 0xd8, 0x1d,
- 0x47, 0x6e, 0x8e, 0x3c, 0x93, 0x7b, 0x7e, 0x08, 0x4e, 0x6e, 0xdf, 0x7d,
- 0x99, 0xe4, 0xd4, 0x61, 0x91, 0x9b, 0xa2, 0xef, 0xa8, 0xfa, 0xdb, 0x8e,
- 0x15, 0x14, 0xf9, 0x87, 0xae, 0xf4, 0x52, 0x87, 0x37, 0xa1, 0xb5, 0x67,
- 0x0c, 0xa7, 0xc8, 0xeb, 0xdc, 0x35, 0x54, 0xad, 0xd2, 0x9c, 0xba, 0xdf,
- 0x87, 0x68, 0x6a, 0x9c, 0x38, 0x10, 0x98, 0xf0, 0x93, 0x9f, 0xcc, 0x77,
- 0xd7, 0x8e, 0x96, 0x91, 0x7f, 0xa4, 0xc8, 0x6d, 0x3f, 0xee, 0xf5, 0xe2,
- 0x6e, 0x62, 0xc6, 0x7e, 0xbd, 0x75, 0xc3, 0x18, 0x7e, 0x45, 0xac, 0x93,
- 0xf2, 0x3f, 0x60, 0x7b, 0x22, 0xd3, 0xcb, 0xf6, 0xe0, 0xf7, 0x12, 0x8f,
- 0xc9, 0x09, 0xbd, 0x3e, 0x3d, 0xed, 0x93, 0xf8, 0x2d, 0xdc, 0x75, 0xc7,
- 0x6e, 0x05, 0x9d, 0x94, 0xf3, 0x28, 0x6d, 0xe6, 0xfe, 0x28, 0xbc, 0x5d,
- 0x57, 0x91, 0xa3, 0x90, 0xf3, 0x61, 0x4e, 0x00, 0x8f, 0x8c, 0x23, 0x91,
- 0xd7, 0xa7, 0xe6, 0x05, 0xf0, 0x26, 0xe5, 0x08, 0xae, 0x57, 0x94, 0xe4,
- 0xf4, 0xac, 0xb9, 0x58, 0x4e, 0x2d, 0x1e, 0x2f, 0xc9, 0xd9, 0x43, 0x39,
- 0xd7, 0xb4, 0xc0, 0x5b, 0x7b, 0x8d, 0xcc, 0x55, 0x1b, 0xfd, 0xa7, 0x16,
- 0x19, 0x17, 0xdb, 0xc9, 0xe9, 0x3e, 0x06, 0x45, 0x5f, 0x28, 0xfc, 0xff,
- 0x1b, 0x6e, 0xbd, 0x9b, 0xda, 0xa6, 0xa6, 0xeb, 0x09, 0x9e, 0x67, 0x5a,
- 0xa6, 0xe8, 0xa8, 0x65, 0xdd, 0x34, 0x62, 0xeb, 0xee, 0xea, 0x72, 0x7f,
- 0xd9, 0x4e, 0xb9, 0x8d, 0x06, 0xde, 0x0b, 0xe1, 0x11, 0xe6, 0x71, 0x37,
- 0xb1, 0x9d, 0x03, 0x86, 0x70, 0xb1, 0x56, 0xa3, 0x4a, 0x91, 0xbc, 0x36,
- 0xcc, 0xb8, 0xde, 0x80, 0x3e, 0x37, 0x16, 0x84, 0x59, 0x7f, 0x77, 0x5d,
- 0x91, 0x4f, 0xc0, 0x77, 0x2b, 0xcb, 0x76, 0xc6, 0x8b, 0xed, 0xf9, 0x74,
- 0xc9, 0x15, 0xdb, 0xb1, 0x7f, 0xf8, 0xfc, 0xf3, 0xc8, 0x4d, 0xfa, 0xcc,
- 0xf9, 0x9a, 0x8a, 0x10, 0x4b, 0x2b, 0x50, 0x5d, 0x21, 0x58, 0x7f, 0xd1,
- 0xd8, 0xb7, 0x8c, 0xff, 0x29, 0xef, 0x57, 0x63, 0xeb, 0xb8, 0x83, 0x2d,
- 0x6e, 0x9e, 0x50, 0x81, 0xde, 0x36, 0xc1, 0x43, 0xb1, 0xa5, 0x39, 0x92,
- 0x27, 0x25, 0x72, 0x90, 0x18, 0x27, 0xf6, 0xb3, 0xc6, 0xb5, 0x1f, 0x8f,
- 0x32, 0xd3, 0x7e, 0x36, 0xe3, 0xbb, 0xfa, 0xa1, 0x3b, 0x2a, 0x71, 0xe8,
- 0x2e, 0x59, 0xff, 0xde, 0x10, 0xc7, 0xe1, 0x5b, 0xe8, 0x9b, 0xaf, 0x13,
- 0x5b, 0xb6, 0xb4, 0x30, 0x86, 0xb8, 0x98, 0xa5, 0xa0, 0x92, 0xb1, 0x7d,
- 0xdb, 0x6e, 0xe6, 0xc0, 0x6a, 0x90, 0x6d, 0x5e, 0x8a, 0x5d, 0xd2, 0x7f,
- 0x83, 0xb9, 0xee, 0xa1, 0x2f, 0x56, 0x22, 0x20, 0x39, 0xc7, 0x4f, 0x4e,
- 0x51, 0xc6, 0x4d, 0x46, 0x59, 0x57, 0xa2, 0xa7, 0xb2, 0x9c, 0x06, 0xa4,
- 0x77, 0x97, 0xeb, 0x2b, 0x78, 0x29, 0x1a, 0x2e, 0xad, 0x3f, 0x37, 0x60,
- 0x60, 0xfc, 0xd0, 0x31, 0x72, 0x0d, 0x27, 0xd1, 0x72, 0x68, 0x63, 0x98,
- 0x7d, 0x39, 0x13, 0x2f, 0xcf, 0xa9, 0xf8, 0xe6, 0x4c, 0x19, 0x62, 0xbb,
- 0x50, 0x6a, 0x17, 0x62, 0x4b, 0x2d, 0x6d, 0x34, 0x1f, 0x45, 0xaa, 0xc6,
- 0xac, 0x85, 0x3d, 0x4e, 0xdf, 0x9a, 0xa8, 0x80, 0xf7, 0x5a, 0x89, 0x7d,
- 0xc2, 0x77, 0xbc, 0x37, 0x9c, 0xb0, 0x2b, 0xf0, 0x69, 0xe3, 0x9c, 0x23,
- 0xb8, 0x78, 0x4c, 0xc7, 0xe5, 0x15, 0xc4, 0xc4, 0x85, 0xf1, 0x68, 0x72,
- 0x1d, 0xf3, 0xc2, 0x23, 0x6d, 0xde, 0x1b, 0xde, 0xca, 0xff, 0x9a, 0xdc,
- 0xf2, 0xd2, 0xf1, 0x88, 0x3e, 0x70, 0x74, 0x45, 0x54, 0xda, 0x94, 0xf6,
- 0xca, 0x36, 0x2a, 0xed, 0x3b, 0x4e, 0x34, 0x1e, 0x70, 0xe7, 0xbc, 0x3c,
- 0x86, 0x37, 0xf4, 0xf2, 0x18, 0x02, 0x8c, 0xa7, 0x49, 0x72, 0x57, 0xe1,
- 0xd5, 0x7e, 0xe6, 0x91, 0x5e, 0xf2, 0xf1, 0x6e, 0x08, 0xdf, 0x3b, 0x4a,
- 0x7e, 0xf2, 0xa4, 0x0d, 0xbc, 0x93, 0x75, 0xb0, 0x2c, 0x3e, 0x8b, 0xf8,
- 0xd2, 0x4f, 0xd9, 0xb2, 0xa6, 0x76, 0x50, 0x19, 0x67, 0xae, 0x79, 0xdc,
- 0x5b, 0x95, 0x54, 0x99, 0x5b, 0x1e, 0xc8, 0x47, 0xc3, 0x87, 0x98, 0x67,
- 0xfa, 0x99, 0xeb, 0x72, 0x06, 0x94, 0x27, 0x99, 0x67, 0xee, 0x2b, 0xe5,
- 0x99, 0x07, 0xf2, 0x01, 0xe4, 0xb3, 0xc4, 0xc6, 0x38, 0xf3, 0x5b, 0x37,
- 0x4f, 0x0f, 0x60, 0x32, 0xab, 0x32, 0x1f, 0x7f, 0xdf, 0x99, 0xaa, 0x77,
- 0xf7, 0x0b, 0xf0, 0x75, 0xbb, 0x01, 0x07, 0x87, 0x9b, 0x70, 0x36, 0x3f,
- 0x45, 0xbb, 0xb8, 0x0c, 0xd3, 0xa3, 0xb5, 0x98, 0x18, 0x7e, 0x95, 0x9f,
- 0xdb, 0xf0, 0xfe, 0xa8, 0x9b, 0xe3, 0x12, 0x0f, 0xa5, 0x7f, 0x07, 0x95,
- 0x43, 0x6e, 0x8e, 0x6b, 0x25, 0x99, 0xdb, 0x26, 0xfa, 0x4b, 0xb9, 0xed,
- 0x14, 0x73, 0xdb, 0x23, 0x6c, 0xf3, 0x85, 0x52, 0x9b, 0xcf, 0xb9, 0xff,
- 0xa5, 0x2f, 0x52, 0x77, 0x66, 0xbd, 0x44, 0x52, 0xd6, 0xa6, 0xc7, 0xed,
- 0x68, 0xac, 0x5c, 0xf7, 0x05, 0xd6, 0x3b, 0x72, 0xbe, 0xde, 0x6a, 0x0c,
- 0x64, 0xd6, 0x90, 0xe7, 0xcb, 0xda, 0xca, 0x7b, 0x6b, 0x6c, 0xea, 0xf2,
- 0xcb, 0xd1, 0xa9, 0xee, 0x59, 0xa8, 0xc3, 0xfa, 0xb8, 0x70, 0xa2, 0xb7,
- 0xc8, 0x89, 0x22, 0x89, 0x95, 0x8c, 0x0f, 0x9e, 0x68, 0x84, 0x58, 0x0f,
- 0x44, 0x27, 0x98, 0x03, 0xe4, 0xeb, 0x70, 0x37, 0x73, 0x31, 0xb5, 0x7e,
- 0x75, 0x69, 0x0f, 0xab, 0x94, 0xe3, 0x78, 0xd6, 0xa0, 0x6f, 0x52, 0xe4,
- 0xad, 0x26, 0xbf, 0xae, 0xc1, 0x2d, 0xc5, 0x75, 0x0b, 0xbf, 0x9f, 0xb2,
- 0xfd, 0xd1, 0xa9, 0x18, 0x5d, 0xc6, 0x38, 0xc0, 0x1b, 0xcf, 0xd9, 0x0a,
- 0x96, 0xe9, 0x3e, 0xac, 0x0b, 0xd6, 0x61, 0x99, 0xf1, 0xef, 0xce, 0x2d,
- 0xab, 0xe5, 0xd9, 0x79, 0x1e, 0xe1, 0xaf, 0x64, 0xbb, 0x6f, 0x92, 0x53,
- 0x8f, 0xf3, 0xcb, 0x54, 0xbe, 0x78, 0xdf, 0xca, 0x53, 0x36, 0xe5, 0x6e,
- 0xa3, 0xdc, 0x7b, 0x83, 0x6e, 0xbe, 0x5b, 0x2a, 0x37, 0x15, 0xf3, 0x10,
- 0xd7, 0xa5, 0x6c, 0x27, 0xe5, 0xde, 0x4d, 0xb9, 0xfd, 0x41, 0xe9, 0xdf,
- 0xbf, 0x3b, 0xf7, 0xae, 0x96, 0x67, 0xe5, 0x7d, 0x13, 0x29, 0xff, 0x9e,
- 0xc8, 0x35, 0xc6, 0x4b, 0x6d, 0x1d, 0xb2, 0x91, 0x95, 0xdc, 0x6f, 0x6d,
- 0x47, 0x54, 0xeb, 0x75, 0xd7, 0xb2, 0x35, 0xac, 0xcb, 0x6b, 0xb8, 0x87,
- 0xba, 0xcb, 0x79, 0xcb, 0x63, 0x72, 0xfb, 0x64, 0x09, 0x77, 0x5e, 0xce,
- 0x72, 0x7d, 0x25, 0xdc, 0xee, 0xcc, 0x8b, 0x0d, 0xcd, 0xdc, 0x4f, 0x6a,
- 0x2a, 0xf9, 0xb3, 0x17, 0x4f, 0xdb, 0x1f, 0x9c, 0x1b, 0xcc, 0x48, 0x3c,
- 0x93, 0xf5, 0x10, 0x0d, 0xd9, 0xfc, 0xe5, 0x68, 0x1e, 0x0a, 0x62, 0xad,
- 0x31, 0x9b, 0xbe, 0xfe, 0xa5, 0xf3, 0x36, 0x75, 0x80, 0xed, 0xc0, 0xe7,
- 0x8a, 0x57, 0x9e, 0xce, 0xb7, 0x06, 0x1b, 0x70, 0xe9, 0x1e, 0xd2, 0xfc,
- 0x64, 0x8d, 0x19, 0xed, 0xfe, 0x0e, 0xe7, 0xae, 0xca, 0xe5, 0xd0, 0x5b,
- 0x94, 0x1c, 0xe7, 0xef, 0xa9, 0xd2, 0xfc, 0x3d, 0x99, 0xbf, 0xae, 0xb2,
- 0x88, 0x45, 0x97, 0xa3, 0x65, 0x48, 0xfe, 0x07, 0xf1, 0x46, 0xc7, 0xc7,
- 0x79, 0xef, 0x72, 0x2c, 0x1c, 0xf9, 0x54, 0x25, 0xb9, 0xb5, 0x51, 0xcc,
- 0xc1, 0x2f, 0xcd, 0x33, 0x22, 0xfd, 0x16, 0x16, 0xb0, 0x5c, 0x13, 0x75,
- 0x26, 0x18, 0x28, 0xfd, 0x7a, 0xe4, 0x7c, 0xbf, 0xbe, 0xcc, 0x7e, 0xa5,
- 0x7c, 0xb2, 0xd6, 0x2a, 0xfd, 0x52, 0x92, 0xb5, 0x66, 0x13, 0xde, 0x1f,
- 0x40, 0x30, 0x68, 0x46, 0x53, 0x2f, 0xd3, 0xde, 0x27, 0xd8, 0xd7, 0x7a,
- 0xf4, 0x2b, 0x79, 0x77, 0xaf, 0xea, 0x20, 0xcb, 0xcc, 0x8c, 0xa3, 0xd2,
- 0x4f, 0xaf, 0xe4, 0x59, 0x3e, 0xd9, 0x67, 0xf2, 0xe9, 0x22, 0xff, 0x6d,
- 0x72, 0xc5, 0x3e, 0xca, 0x4f, 0x72, 0xfe, 0xfc, 0x6c, 0x03, 0x56, 0xb5,
- 0xd9, 0xed, 0x72, 0x55, 0x2f, 0xfd, 0x6e, 0x19, 0x6d, 0xea, 0xc9, 0x9c,
- 0x82, 0x51, 0x2a, 0xfd, 0x68, 0x56, 0xd6, 0x89, 0xc3, 0x38, 0x90, 0xf3,
- 0xe1, 0x85, 0xec, 0x3c, 0x8c, 0xe7, 0x2a, 0xf0, 0x5c, 0xf6, 0x32, 0xec,
- 0xcb, 0x11, 0xfd, 0xb2, 0x97, 0x63, 0x24, 0xe7, 0xc7, 0x4f, 0xb2, 0xd4,
- 0x53, 0xae, 0x0a, 0xff, 0x9c, 0xfd, 0x13, 0x7c, 0x3d, 0x57, 0x8d, 0xd7,
- 0xb2, 0x57, 0xe0, 0x60, 0xae, 0x06, 0xaf, 0x64, 0xc9, 0x27, 0x73, 0x01,
- 0xbc, 0x9c, 0xd5, 0x50, 0xc8, 0xcd, 0xc2, 0x4b, 0xd9, 0x08, 0x26, 0x72,
- 0xb5, 0xf8, 0x6e, 0x76, 0x01, 0xf2, 0xb9, 0x3a, 0x7c, 0x27, 0xdb, 0x8c,
- 0x2f, 0xe7, 0x82, 0x78, 0x31, 0xab, 0xe3, 0xa9, 0x5c, 0x3d, 0x8e, 0x65,
- 0xa3, 0x6c, 0x37, 0x84, 0xa3, 0xc3, 0x31, 0x1c, 0x18, 0x6d, 0xc4, 0x0b,
- 0xc3, 0x8b, 0x30, 0x3e, 0x1a, 0xc6, 0x73, 0xc3, 0x6d, 0xd8, 0x37, 0xfa,
- 0x6f, 0x15, 0xa2, 0x9f, 0x23, 0xf6, 0xff, 0x38, 0xaf, 0xc7, 0x6d, 0x1f,
- 0x31, 0xdf, 0xaf, 0xda, 0xa2, 0x37, 0xbf, 0x55, 0xcf, 0x39, 0x7a, 0x3a,
- 0xef, 0xce, 0x3b, 0xf4, 0x21, 0x77, 0x7f, 0x06, 0x7d, 0xc6, 0x65, 0xcc,
- 0xd9, 0xfa, 0x25, 0x7e, 0xd0, 0x16, 0x0e, 0x2a, 0xdb, 0x5d, 0x1c, 0xa9,
- 0x4d, 0xce, 0xa2, 0x2e, 0x39, 0xec, 0x60, 0x0d, 0x7d, 0x32, 0x4b, 0x7f,
- 0xb6, 0x38, 0xaf, 0x76, 0xfe, 0xa0, 0xb2, 0x83, 0x39, 0xe2, 0x95, 0x43,
- 0x96, 0x53, 0xed, 0xe2, 0x69, 0x34, 0xb9, 0x88, 0x3e, 0x17, 0x1b, 0x11,
- 0x7d, 0xde, 0x59, 0x21, 0xfa, 0xac, 0xd0, 0x3f, 0xcc, 0x4e, 0xca, 0x7a,
- 0x0f, 0x94, 0xec, 0xe1, 0xfb, 0x95, 0xc5, 0xbc, 0xaa, 0x3c, 0xef, 0x8e,
- 0x33, 0x68, 0x94, 0xe7, 0x9e, 0xfc, 0xaf, 0x41, 0xd6, 0xa4, 0xc0, 0x58,
- 0x50, 0x8f, 0x5c, 0x48, 0xf2, 0xf5, 0x99, 0x98, 0x81, 0x64, 0xa5, 0x19,
- 0xd5, 0x5a, 0xd4, 0x99, 0x7c, 0x45, 0xb0, 0x43, 0xe4, 0x5b, 0x2e, 0xee,
- 0x1c, 0x3e, 0x8f, 0x1f, 0x67, 0x2b, 0x85, 0xa7, 0xec, 0xb7, 0xa5, 0x6f,
- 0x50, 0x2b, 0xa4, 0xcf, 0x28, 0xde, 0x43, 0xa1, 0xac, 0xaf, 0x99, 0x76,
- 0xa7, 0x52, 0xb7, 0x62, 0x7b, 0x5e, 0xfa, 0xc2, 0x72, 0x89, 0x7b, 0xec,
- 0x47, 0x13, 0x5e, 0xb0, 0x8b, 0x7b, 0x33, 0xe3, 0x79, 0xd1, 0xb7, 0x86,
- 0xad, 0xe4, 0x5e, 0x87, 0x87, 0x15, 0xea, 0xee, 0x2f, 0x51, 0xdc, 0x3f,
- 0xf2, 0xd2, 0x57, 0xd7, 0xb2, 0x3c, 0x63, 0x7c, 0x61, 0xda, 0xdd, 0x1b,
- 0xae, 0x73, 0xf3, 0xee, 0x30, 0x0a, 0x03, 0x1f, 0x9c, 0xdb, 0x96, 0xf9,
- 0xe5, 0xb9, 0x3d, 0x99, 0x68, 0x4a, 0xf6, 0x67, 0xf2, 0x13, 0x3e, 0xe4,
- 0xf6, 0x06, 0xf0, 0xd4, 0x84, 0x1f, 0x35, 0x69, 0xc9, 0xf3, 0x83, 0x78,
- 0x6a, 0xff, 0xa1, 0x15, 0x35, 0x68, 0xe0, 0xff, 0x10, 0xaf, 0x46, 0x5e,
- 0x01, 0x1c, 0x1b, 0xf5, 0xe3, 0x2d, 0x5b, 0x7c, 0x58, 0xfc, 0xa3, 0x8d,
- 0xd8, 0x1f, 0x60, 0xbc, 0x55, 0x19, 0x47, 0x9a, 0x70, 0x38, 0x1f, 0xc4,
- 0xf2, 0x6c, 0x3d, 0x9e, 0xcb, 0x25, 0xf1, 0x44, 0xa6, 0x1e, 0x67, 0x1f,
- 0xf3, 0x63, 0xde, 0x3e, 0xf1, 0x87, 0x06, 0x9c, 0x1e, 0xfc, 0x04, 0x0a,
- 0x7b, 0x93, 0xb0, 0x33, 0xb3, 0xb1, 0x63, 0xb0, 0x01, 0xdf, 0x61, 0x99,
- 0x7e, 0xea, 0xa9, 0x7a, 0xa7, 0x89, 0x17, 0x69, 0x43, 0x55, 0x3b, 0x6f,
- 0xa4, 0xec, 0x30, 0x7c, 0x03, 0x21, 0x1c, 0xc9, 0x7b, 0x85, 0xd7, 0x71,
- 0x1e, 0x7f, 0x5a, 0x9c, 0x17, 0x08, 0x6f, 0xbd, 0x98, 0x07, 0x1e, 0x3f,
- 0xcf, 0x03, 0x81, 0x5c, 0x5e, 0xd6, 0x18, 0xdb, 0x3a, 0xfb, 0xec, 0x89,
- 0xff, 0xcf, 0x6f, 0xfe, 0xf4, 0xdb, 0x15, 0x4b, 0x0c, 0x62, 0x9d, 0x8c,
- 0x7f, 0xed, 0x83, 0xd5, 0xe6, 0x86, 0x2f, 0xae, 0x58, 0x52, 0x89, 0xfb,
- 0xdd, 0xf9, 0xea, 0x81, 0xbd, 0xbb, 0x9b, 0xf1, 0xb5, 0xb5, 0x67, 0x40,
- 0xb9, 0x02, 0xa9, 0xfa, 0x21, 0xde, 0x53, 0x4b, 0x3e, 0x07, 0x55, 0x6c,
- 0xad, 0x8e, 0xfa, 0x54, 0x0b, 0x1a, 0x4e, 0xd0, 0xc8, 0x6a, 0xd3, 0x11,
- 0x4c, 0xd5, 0xcb, 0x38, 0x63, 0xcc, 0xb3, 0x3c, 0xb2, 0x77, 0x8d, 0x4f,
- 0x33, 0xc6, 0x9d, 0x5d, 0xac, 0x20, 0xf1, 0x67, 0xe2, 0x83, 0xb7, 0x96,
- 0xf6, 0x80, 0x65, 0x3f, 0x4c, 0xe6, 0xad, 0xac, 0xff, 0xbd, 0xb2, 0xee,
- 0xc9, 0x3f, 0xc1, 0x0a, 0x2f, 0x0e, 0xdb, 0x39, 0xe6, 0x08, 0x32, 0x07,
- 0x32, 0xa6, 0xed, 0xac, 0x27, 0xe3, 0x92, 0xe7, 0xad, 0x89, 0xfa, 0x8f,
- 0x1c, 0x97, 0x8c, 0x67, 0xad, 0x1f, 0xd5, 0x32, 0x86, 0xb2, 0x2e, 0xfa,
- 0x58, 0xf7, 0x51, 0xde, 0x93, 0x7a, 0x8e, 0xb3, 0xfd, 0xa2, 0x98, 0x55,
- 0x91, 0xac, 0x66, 0xdf, 0x9f, 0xb4, 0xa3, 0xc9, 0x77, 0x88, 0x8b, 0xc7,
- 0xa8, 0xc3, 0x51, 0x5b, 0xec, 0x6f, 0x0b, 0xed, 0xae, 0x5f, 0x39, 0x7a,
- 0xde, 0xf6, 0x80, 0x83, 0xb6, 0xcc, 0xaf, 0xf0, 0x29, 0x19, 0xaf, 0x86,
- 0xe9, 0x89, 0xa0, 0xcb, 0xc7, 0xdf, 0xb6, 0xc5, 0x26, 0x62, 0xcc, 0xcf,
- 0xa6, 0xcf, 0xf5, 0x66, 0x0c, 0x1c, 0xe3, 0xdc, 0x9e, 0xb6, 0xab, 0x88,
- 0x37, 0x1d, 0x90, 0xbd, 0xce, 0xf7, 0xed, 0x04, 0x5e, 0x22, 0x66, 0xbd,
- 0x47, 0x5b, 0xfb, 0x2e, 0x31, 0xec, 0x5d, 0x5b, 0xc7, 0x77, 0x68, 0x7b,
- 0xef, 0xd8, 0x31, 0xbc, 0x98, 0xaf, 0xc7, 0x51, 0xe2, 0xd0, 0x49, 0x7e,
- 0x5e, 0x9e, 0xf7, 0xc1, 0x0a, 0xc9, 0xbe, 0xda, 0x1e, 0x3f, 0x6a, 0x7b,
- 0xd9, 0xe7, 0x48, 0x97, 0x1c, 0x44, 0x79, 0x96, 0xe3, 0xd3, 0x94, 0x32,
- 0x0f, 0x29, 0xe7, 0x04, 0x49, 0x64, 0x33, 0x33, 0xb1, 0x21, 0xd2, 0x9f,
- 0xa3, 0xdd, 0xfa, 0xd2, 0xe5, 0x38, 0xc0, 0xd8, 0x59, 0x10, 0xdb, 0xf6,
- 0xc0, 0x33, 0x24, 0xf6, 0x7f, 0x0d, 0x75, 0x3d, 0x7d, 0x4e, 0xf6, 0xd2,
- 0x54, 0x7d, 0x8a, 0xfe, 0x5e, 0x85, 0xde, 0xdc, 0xe5, 0xa8, 0x19, 0x5a,
- 0x8a, 0xfb, 0xe3, 0xe2, 0xf7, 0x7e, 0xf4, 0xe7, 0x3c, 0xa8, 0x1c, 0x22,
- 0x77, 0x61, 0xd9, 0xa9, 0x50, 0x31, 0x1e, 0xa9, 0x69, 0xc3, 0xf5, 0x83,
- 0x05, 0x85, 0x0f, 0xce, 0xd9, 0x99, 0x43, 0xf3, 0x54, 0x4c, 0x9f, 0x4b,
- 0x67, 0x02, 0xe8, 0xa3, 0x4d, 0xab, 0x69, 0x05, 0x75, 0x7a, 0x88, 0xf9,
- 0x5f, 0x1b, 0x7a, 0xa9, 0x8b, 0xf9, 0xe9, 0x26, 0x3c, 0x31, 0xd1, 0x88,
- 0x79, 0xbb, 0x4c, 0x3c, 0x4e, 0xdb, 0x0f, 0xef, 0xba, 0x11, 0x7b, 0x58,
- 0xee, 0x15, 0x3e, 0x7b, 0x65, 0x7f, 0x03, 0xaf, 0x10, 0xaf, 0x46, 0x5e,
- 0xf5, 0x18, 0xd8, 0xab, 0x97, 0xce, 0x61, 0x78, 0xd0, 0x30, 0x24, 0xf8,
- 0xa2, 0xe2, 0x8e, 0x76, 0x05, 0xc6, 0xd5, 0x6c, 0x73, 0xe1, 0x87, 0x61,
- 0x4d, 0xc3, 0x1f, 0xd0, 0xef, 0x1f, 0x38, 0x53, 0xe7, 0xed, 0xc7, 0x0f,
- 0x6f, 0xfa, 0xfb, 0xae, 0xfd, 0x2c, 0x28, 0x48, 0x3b, 0xef, 0x12, 0x33,
- 0xc4, 0x86, 0x7e, 0x17, 0x9e, 0x95, 0xf5, 0xfe, 0xdb, 0x67, 0x2b, 0x70,
- 0xde, 0xbe, 0x2e, 0x5a, 0x77, 0x47, 0x9e, 0x36, 0xb1, 0xc3, 0x3d, 0x3b,
- 0x22, 0xb9, 0x4e, 0xa4, 0x2b, 0x47, 0xfd, 0xf4, 0x33, 0x87, 0xb9, 0x87,
- 0x38, 0xb1, 0x3d, 0x13, 0xb1, 0x2c, 0xb6, 0xe5, 0x23, 0x36, 0x3c, 0x30,
- 0xe8, 0x97, 0xf5, 0x6e, 0xcd, 0xa7, 0xcf, 0xc3, 0x3b, 0x39, 0xb1, 0xf9,
- 0x2a, 0x1c, 0xce, 0x86, 0x71, 0xca, 0xfd, 0x5c, 0xcd, 0x58, 0xe3, 0xa0,
- 0xd3, 0x98, 0x85, 0xbe, 0x60, 0x15, 0x06, 0x62, 0x37, 0x22, 0x77, 0x07,
- 0x73, 0x6c, 0xfa, 0x58, 0xad, 0xee, 0x47, 0x3a, 0x28, 0xf9, 0x8b, 0x07,
- 0x99, 0xd8, 0xed, 0x38, 0x5e, 0xef, 0xc5, 0x3c, 0x59, 0x6f, 0xe1, 0xb3,
- 0x3d, 0x41, 0x28, 0xf4, 0xbd, 0xa4, 0x8f, 0xb8, 0x34, 0x6b, 0x00, 0x4e,
- 0xad, 0xa9, 0xcb, 0x1e, 0x4c, 0xcf, 0x56, 0xe2, 0x52, 0xcd, 0x44, 0x0d,
- 0xe3, 0x4e, 0x0b, 0xaa, 0xf7, 0xca, 0x5e, 0x40, 0x00, 0xeb, 0x86, 0xaf,
- 0x95, 0xbd, 0x81, 0x98, 0xa6, 0x04, 0x70, 0xef, 0xb0, 0xc4, 0x8f, 0x35,
- 0xa8, 0xd8, 0x5f, 0x8b, 0x2f, 0x66, 0xbd, 0xc4, 0x78, 0xe2, 0x0d, 0xcb,
- 0xed, 0xc9, 0xd4, 0xa1, 0xee, 0xb1, 0x67, 0x9d, 0x30, 0x75, 0x5c, 0xb7,
- 0x57, 0xb0, 0x88, 0xb6, 0x9b, 0xf9, 0x3c, 0x0a, 0x76, 0x33, 0xe5, 0xf6,
- 0x70, 0x7c, 0x21, 0xbc, 0x4b, 0xec, 0xaa, 0x99, 0x08, 0xe3, 0x9d, 0xdd,
- 0x92, 0xab, 0x24, 0xe1, 0x9d, 0xb8, 0x0c, 0x6f, 0xf2, 0xf3, 0x09, 0xa3,
- 0x13, 0xea, 0x44, 0x13, 0x4e, 0x66, 0xba, 0xe0, 0x99, 0xa8, 0x2d, 0x62,
- 0xd8, 0x5e, 0x3f, 0xea, 0x06, 0xf5, 0xd8, 0x34, 0xe7, 0xc8, 0xb7, 0x97,
- 0x04, 0xa7, 0x51, 0xda, 0x3f, 0x6f, 0xdb, 0xc6, 0x85, 0x7d, 0x87, 0xf2,
- 0xd9, 0x15, 0xb1, 0xef, 0xef, 0x3a, 0x4f, 0x04, 0xd9, 0xbf, 0x8e, 0x08,
- 0xfa, 0x62, 0xc7, 0x64, 0x3f, 0x9f, 0xe3, 0x4b, 0x72, 0xee, 0x9f, 0x77,
- 0xe4, 0x5c, 0x88, 0xcf, 0x94, 0x33, 0x19, 0xcf, 0x39, 0xdb, 0x57, 0xcb,
- 0xfd, 0xdb, 0xab, 0x50, 0xcd, 0xc4, 0xc9, 0x14, 0x99, 0x3b, 0x64, 0x6e,
- 0x19, 0x75, 0x3e, 0x4c, 0xe6, 0x3f, 0x3a, 0x8f, 0x9f, 0x2f, 0x8f, 0xa0,
- 0xcf, 0x5d, 0x13, 0xbf, 0xe0, 0xcb, 0x35, 0x9c, 0xbb, 0xf5, 0x25, 0x5f,
- 0x7e, 0xc7, 0x96, 0xf9, 0x93, 0xf3, 0x4b, 0x01, 0x72, 0x30, 0x03, 0xd5,
- 0x9c, 0xbb, 0xf7, 0x6d, 0x28, 0xb7, 0x76, 0x74, 0x63, 0xd6, 0x44, 0x80,
- 0xbe, 0x1e, 0x59, 0x6f, 0xc1, 0x66, 0x5b, 0x1d, 0xa8, 0x62, 0x9d, 0x93,
- 0xb6, 0x87, 0x7e, 0x9e, 0xe0, 0x98, 0x83, 0x70, 0x5c, 0x5e, 0xbf, 0x1a,
- 0xf3, 0xa9, 0xa7, 0xb3, 0xb6, 0x89, 0x79, 0xd4, 0xd3, 0xb4, 0xed, 0x25,
- 0x4e, 0x34, 0x11, 0x0f, 0x34, 0xd4, 0x12, 0x1b, 0x2b, 0x06, 0x1d, 0x1c,
- 0x32, 0xea, 0xc8, 0xf5, 0xc5, 0x4e, 0x3b, 0x10, 0x1e, 0x30, 0x30, 0x6f,
- 0xa0, 0x79, 0xe3, 0x3c, 0x8f, 0x07, 0xc7, 0x7d, 0xc5, 0xd8, 0x93, 0x9b,
- 0x23, 0xfa, 0x91, 0x31, 0xb9, 0xb9, 0xfc, 0x87, 0x60, 0xc0, 0x6a, 0x80,
- 0xb2, 0x0a, 0xc4, 0x8c, 0xcf, 0xb1, 0xad, 0x37, 0xec, 0x57, 0x71, 0xf3,
- 0x84, 0xe0, 0xcb, 0x0f, 0xb1, 0x92, 0xfd, 0x78, 0x97, 0xb8, 0x76, 0x5f,
- 0xf4, 0x1b, 0x1c, 0x6b, 0x13, 0x6e, 0x99, 0x98, 0x3e, 0xd7, 0xe7, 0x8e,
- 0xb3, 0x9c, 0xff, 0xf9, 0x71, 0x5f, 0xb6, 0x7c, 0x06, 0x2d, 0x49, 0x9f,
- 0x91, 0x38, 0xe1, 0x87, 0xf8, 0x4d, 0xb7, 0xbd, 0x0d, 0xc5, 0x78, 0x2e,
- 0x57, 0x59, 0x8f, 0x3b, 0xbd, 0x92, 0x97, 0x17, 0x7d, 0x43, 0xfa, 0xf3,
- 0xbb, 0xca, 0x14, 0x7d, 0x43, 0xfc, 0xe2, 0xcb, 0xae, 0x7e, 0x85, 0x77,
- 0x69, 0xb8, 0x6d, 0xe2, 0x97, 0xc4, 0xc7, 0x48, 0x32, 0x47, 0xcc, 0x7e,
- 0x9d, 0xfa, 0xdd, 0x4e, 0xfd, 0x32, 0x07, 0x60, 0xbc, 0x4a, 0x50, 0x9f,
- 0x3e, 0x72, 0x15, 0x2f, 0x31, 0xd3, 0xa4, 0x2e, 0x41, 0x0c, 0x64, 0xee,
- 0x1e, 0x2c, 0x8e, 0x37, 0x77, 0x7e, 0xfe, 0xd8, 0x96, 0x92, 0xc0, 0x09,
- 0xfb, 0x87, 0x55, 0x72, 0x26, 0xe8, 0xa4, 0xed, 0x3e, 0x97, 0x35, 0xcd,
- 0x19, 0x65, 0x2e, 0xb4, 0xbd, 0xcf, 0x16, 0xfe, 0x5c, 0x49, 0xbb, 0xd6,
- 0x28, 0xaf, 0xa6, 0x84, 0xa9, 0x52, 0x57, 0xf6, 0x60, 0xa5, 0xfd, 0x6e,
- 0xe1, 0x20, 0x78, 0x83, 0x3e, 0x77, 0xc4, 0xa8, 0xc0, 0xa8, 0x3b, 0x17,
- 0x62, 0x8f, 0xc5, 0x76, 0x2f, 0xd8, 0x4d, 0xba, 0xae, 0x74, 0x1e, 0xab,
- 0xba, 0xc8, 0xc9, 0x2e, 0x6d, 0xa3, 0xe2, 0x3f, 0xb1, 0x8d, 0x44, 0xa9,
- 0x8d, 0x8f, 0x3a, 0xe3, 0x06, 0x3c, 0x65, 0x4b, 0xec, 0x97, 0xfd, 0x0f,
- 0x0d, 0x8b, 0x26, 0x04, 0x5f, 0xe8, 0xbb, 0x03, 0xd3, 0x2e, 0xf7, 0xcf,
- 0x41, 0xf6, 0xb6, 0x42, 0xf0, 0x45, 0x35, 0x9c, 0xd2, 0x63, 0x58, 0x58,
- 0x90, 0xfd, 0xa9, 0x7d, 0x75, 0xc2, 0xe1, 0xce, 0xe8, 0xc2, 0x3b, 0x64,
- 0xbe, 0xca, 0xf7, 0xfc, 0xd8, 0xaf, 0x17, 0xfb, 0x9a, 0x54, 0x8b, 0xdc,
- 0xd1, 0x43, 0xee, 0xd8, 0x6b, 0xf8, 0x69, 0x97, 0xad, 0xc1, 0xd9, 0xbf,
- 0x73, 0x2f, 0xab, 0xdc, 0xdf, 0xdf, 0x57, 0xee, 0xc2, 0x7a, 0x5c, 0xf6,
- 0xa2, 0xfd, 0x21, 0x19, 0xd3, 0x5c, 0xa0, 0x41, 0xe2, 0x55, 0x91, 0xa3,
- 0x6e, 0x3d, 0x9f, 0xff, 0x58, 0xca, 0x60, 0xfe, 0x31, 0xd4, 0xeb, 0x0b,
- 0x50, 0xdf, 0x50, 0xc3, 0xb8, 0x1c, 0xed, 0xa2, 0x7b, 0x4b, 0x2c, 0xb3,
- 0x82, 0xa6, 0xe4, 0xbf, 0xc2, 0x5b, 0xa5, 0xcd, 0x7e, 0xa5, 0xaa, 0x20,
- 0xed, 0x1e, 0x54, 0xfc, 0x85, 0x0f, 0x6b, 0x5b, 0xce, 0xfb, 0x4d, 0x9f,
- 0x1b, 0xca, 0x74, 0xbb, 0x7b, 0x8c, 0xcb, 0x86, 0x1c, 0xdc, 0x69, 0x34,
- 0xe1, 0xee, 0x06, 0x69, 0xa3, 0x98, 0xc3, 0x68, 0xea, 0x34, 0x39, 0xdc,
- 0x6f, 0x1c, 0x55, 0x97, 0xcf, 0x3e, 0x78, 0x1e, 0xd3, 0xa7, 0xd7, 0x42,
- 0xc5, 0xd9, 0xeb, 0x24, 0x9f, 0xf1, 0x91, 0x7f, 0x6d, 0xaa, 0x2e, 0xee,
- 0x2f, 0x8b, 0x1d, 0x4b, 0x3f, 0xfc, 0xf4, 0xb3, 0x0b, 0xfd, 0xd8, 0xf6,
- 0x07, 0xf5, 0xc3, 0x8f, 0x9b, 0x86, 0x92, 0x18, 0x35, 0x4e, 0x38, 0x56,
- 0x68, 0x66, 0xdb, 0x3e, 0xac, 0x1c, 0xfa, 0x8d, 0x33, 0xcb, 0x6d, 0x5b,
- 0x27, 0xa7, 0x52, 0xf1, 0xc0, 0x12, 0x1f, 0x6e, 0x1d, 0x89, 0x62, 0xc5,
- 0x90, 0x8a, 0xd8, 0x12, 0xe9, 0x43, 0x14, 0x5d, 0x23, 0xbb, 0xbd, 0xc5,
- 0xf2, 0xc0, 0x2d, 0x1c, 0xc3, 0x1b, 0x46, 0x0d, 0x7e, 0x40, 0x0c, 0xac,
- 0x75, 0xb9, 0xfd, 0x46, 0x25, 0x23, 0xdc, 0xde, 0xa7, 0x62, 0xb6, 0x8e,
- 0x60, 0x83, 0x99, 0xa4, 0xee, 0x3a, 0x95, 0xc7, 0x72, 0x1b, 0x95, 0xa1,
- 0x7c, 0xb9, 0xef, 0x01, 0x7c, 0xa2, 0x10, 0xc4, 0x27, 0xc6, 0x1a, 0x78,
- 0x85, 0x78, 0x35, 0xf2, 0x7a, 0xf1, 0xfc, 0xb8, 0xca, 0x67, 0x3c, 0x9f,
- 0x65, 0x4e, 0xb1, 0xcd, 0xf5, 0x4b, 0x89, 0x0b, 0x9a, 0x9c, 0xd5, 0xc1,
- 0x5b, 0x59, 0xc9, 0x27, 0xb6, 0xd1, 0x86, 0x65, 0x4d, 0xb8, 0x92, 0x39,
- 0x45, 0x24, 0x36, 0x85, 0xbf, 0xaa, 0x2e, 0xce, 0x7d, 0xd1, 0x86, 0x71,
- 0xde, 0x86, 0x7d, 0x78, 0x3b, 0xab, 0xa2, 0x25, 0xfe, 0x6f, 0xce, 0xf1,
- 0xa0, 0xe0, 0xc9, 0xa5, 0xcf, 0xcb, 0x9c, 0x65, 0xfa, 0x5c, 0x36, 0xd3,
- 0x34, 0x63, 0x5f, 0x56, 0x41, 0xc5, 0x90, 0xf0, 0xf3, 0xeb, 0x5c, 0xbe,
- 0xf7, 0x7d, 0xc3, 0x07, 0xef, 0xd0, 0xa1, 0x2b, 0xe5, 0x68, 0x93, 0x6f,
- 0x8c, 0x71, 0xab, 0x83, 0xf3, 0x32, 0xf2, 0xf1, 0x92, 0xce, 0xca, 0xba,
- 0x50, 0xdc, 0x35, 0x49, 0xd5, 0x8d, 0xe9, 0x41, 0xa8, 0x63, 0xc2, 0x43,
- 0xc9, 0x0d, 0xc6, 0x24, 0x1f, 0x08, 0xf1, 0xbf, 0xe4, 0x06, 0x8d, 0xfc,
- 0xcf, 0xc4, 0xa2, 0x51, 0xe2, 0x78, 0x0f, 0xfa, 0x19, 0x9f, 0x2a, 0xa3,
- 0x3d, 0xd8, 0x3e, 0xfe, 0x61, 0x31, 0xbf, 0x98, 0x63, 0x3d, 0x7b, 0xde,
- 0xcf, 0xdc, 0x39, 0x62, 0x9f, 0xa6, 0xcf, 0x89, 0xcf, 0xc8, 0x5c, 0xed,
- 0xcb, 0x4a, 0x1f, 0x1c, 0x6c, 0x30, 0x6e, 0x64, 0xdb, 0x3e, 0xa8, 0x0d,
- 0x33, 0xb9, 0xe7, 0x79, 0x3e, 0x4d, 0xdd, 0x6d, 0x54, 0x46, 0x39, 0x27,
- 0x96, 0xb7, 0x52, 0xd6, 0x87, 0x82, 0x15, 0x9c, 0x93, 0xaf, 0xe4, 0x45,
- 0x46, 0xa7, 0x32, 0x9e, 0x9b, 0x59, 0x67, 0xa3, 0x32, 0x96, 0xff, 0x55,
- 0xb5, 0xac, 0x99, 0x5f, 0xd0, 0x4d, 0xb9, 0x0f, 0x62, 0x63, 0x1a, 0xea,
- 0xd3, 0xa2, 0x67, 0x19, 0xb3, 0x06, 0x2f, 0x79, 0x5c, 0x7d, 0xe1, 0x43,
- 0xdb, 0x6c, 0xac, 0x72, 0xcf, 0x62, 0xc6, 0x18, 0x8b, 0x02, 0x56, 0x25,
- 0x39, 0x1f, 0x6d, 0x34, 0xe5, 0x33, 0xbb, 0x3a, 0xf7, 0xd9, 0x0b, 0x83,
- 0x87, 0x4b, 0x6b, 0x11, 0x6b, 0x21, 0xbc, 0x54, 0x71, 0x71, 0xd6, 0xa3,
- 0x47, 0xb1, 0x9c, 0xb9, 0xee, 0x4d, 0xb9, 0x62, 0x7f, 0xc7, 0xd8, 0xdf,
- 0x29, 0xd7, 0xf7, 0x92, 0xca, 0x68, 0x5e, 0x75, 0xfb, 0xed, 0x35, 0xa5,
- 0xbf, 0x52, 0x97, 0xe3, 0xc9, 0xbf, 0x56, 0xca, 0xa9, 0x92, 0x18, 0xcc,
- 0xcc, 0xf4, 0x61, 0xe9, 0x73, 0x2d, 0xda, 0x86, 0x3e, 0xa0, 0x9f, 0xc9,
- 0xbc, 0x0a, 0xfe, 0xcc, 0xc3, 0xca, 0x91, 0x59, 0x68, 0x1d, 0x0a, 0xe3,
- 0xb6, 0x91, 0x06, 0x2c, 0xda, 0xb5, 0x06, 0xd5, 0x63, 0x41, 0x5c, 0xb9,
- 0x4b, 0xd6, 0xf8, 0x57, 0xa3, 0xb2, 0x70, 0x5b, 0x8d, 0xe4, 0xb8, 0x7a,
- 0x3a, 0xc1, 0xf9, 0x4b, 0xa0, 0x22, 0x1d, 0x49, 0x24, 0x21, 0x6b, 0xa4,
- 0x26, 0x2a, 0x0a, 0x26, 0xf9, 0xa4, 0xb3, 0x79, 0xbe, 0xe9, 0x73, 0xcf,
- 0x9b, 0x2d, 0x2b, 0xd0, 0xe6, 0x39, 0x6e, 0x1f, 0x2f, 0x4f, 0xda, 0x71,
- 0xce, 0x5e, 0x87, 0xcd, 0x35, 0x66, 0x13, 0x3c, 0x85, 0xcb, 0x91, 0x1c,
- 0x69, 0xc3, 0xbc, 0x42, 0x03, 0x3a, 0x47, 0x42, 0x88, 0xa5, 0xc5, 0xc7,
- 0x23, 0x5a, 0x4a, 0xed, 0x80, 0xbf, 0xc0, 0x78, 0x9a, 0xfe, 0x8d, 0xf3,
- 0x16, 0xed, 0xa0, 0x87, 0xfa, 0xba, 0x26, 0xdd, 0x85, 0xba, 0x42, 0x00,
- 0x57, 0x0f, 0x7d, 0x02, 0xb5, 0x23, 0x7e, 0xcc, 0x1a, 0xd2, 0x90, 0x5f,
- 0xe2, 0x47, 0x60, 0x24, 0x8c, 0xea, 0xb4, 0xde, 0x75, 0x9b, 0x82, 0xe4,
- 0xc2, 0x25, 0x61, 0xb6, 0x4d, 0x7b, 0xa3, 0x7f, 0x8d, 0x90, 0x7f, 0x2d,
- 0xef, 0x06, 0x36, 0xa7, 0x05, 0x1b, 0x45, 0x27, 0x9f, 0x72, 0xcf, 0x9f,
- 0xac, 0x4b, 0x7f, 0x18, 0xce, 0x95, 0xed, 0x5b, 0xfc, 0xdc, 0x72, 0xcf,
- 0xc4, 0x32, 0x07, 0x52, 0xa6, 0x5b, 0xf4, 0xec, 0x3c, 0xde, 0xfb, 0x39,
- 0xe3, 0xf3, 0x43, 0xe9, 0x80, 0x55, 0x6b, 0x6e, 0xc6, 0x55, 0xed, 0x11,
- 0xab, 0xa0, 0xbc, 0xca, 0xf1, 0xff, 0x90, 0x41, 0xbb, 0x89, 0xfd, 0xfc,
- 0x63, 0xe5, 0x5f, 0xba, 0xce, 0xb6, 0xe4, 0xa2, 0xf5, 0xb9, 0x23, 0xcc,
- 0xe7, 0xa7, 0x2e, 0x5a, 0x9f, 0x13, 0xbc, 0x2f, 0x9f, 0x83, 0x90, 0xb9,
- 0xd2, 0x66, 0xd8, 0xb7, 0xac, 0x17, 0x09, 0x36, 0xca, 0x7c, 0x95, 0xd7,
- 0x8b, 0x7c, 0x58, 0x3e, 0x24, 0xb9, 0x92, 0xca, 0x3c, 0xa1, 0x05, 0xc9,
- 0xd0, 0xa3, 0x9c, 0x03, 0x77, 0x4d, 0x89, 0xf7, 0x06, 0xf8, 0x59, 0xd6,
- 0x7b, 0x34, 0xe2, 0x8f, 0x56, 0xca, 0x0b, 0xaa, 0x70, 0xeb, 0x50, 0x83,
- 0xbb, 0x1f, 0xb5, 0x22, 0x7e, 0x39, 0x62, 0xf5, 0x5f, 0x62, 0x99, 0x0b,
- 0x6b, 0x43, 0x57, 0x31, 0xdf, 0xa8, 0x71, 0xcf, 0x4a, 0x2c, 0xa3, 0xbe,
- 0x2f, 0x47, 0xdb, 0x48, 0x11, 0xcf, 0x6e, 0x1b, 0x29, 0xe2, 0x56, 0x5a,
- 0x6c, 0xce, 0x57, 0xb4, 0xb9, 0x2c, 0x6d, 0x2e, 0xa8, 0x77, 0x2a, 0xd9,
- 0xdc, 0x47, 0xc5, 0x13, 0x04, 0xeb, 0xcc, 0xf2, 0x99, 0x6a, 0x62, 0x5e,
- 0xfe, 0x48, 0xcd, 0x1f, 0x16, 0x7f, 0x2e, 0xd5, 0xd9, 0xb5, 0x7f, 0xa4,
- 0xce, 0xca, 0x31, 0xeb, 0x82, 0xce, 0x06, 0x2f, 0xd1, 0xd9, 0x02, 0xea,
- 0xa0, 0x41, 0x2f, 0xea, 0x6d, 0xb9, 0x71, 0x19, 0x52, 0xae, 0xde, 0xaa,
- 0x64, 0x6d, 0x8c, 0xf7, 0x04, 0xaf, 0xe7, 0xe0, 0xfb, 0xc1, 0x2f, 0xb9,
- 0xf7, 0x16, 0x51, 0x27, 0x45, 0x7d, 0x05, 0xa9, 0xaf, 0x0b, 0xb1, 0x00,
- 0xea, 0x07, 0xcc, 0xa7, 0x8a, 0xb1, 0x40, 0x74, 0xf7, 0xda, 0xa0, 0x86,
- 0xba, 0xeb, 0x2e, 0xc7, 0x2b, 0x7b, 0xab, 0xd0, 0x3e, 0xe2, 0xa3, 0x7f,
- 0x49, 0x7c, 0x28, 0xc6, 0xa4, 0xd6, 0x11, 0x77, 0x3f, 0x8a, 0xf8, 0xda,
- 0x10, 0xf8, 0xc3, 0x63, 0xb0, 0x8c, 0x47, 0xce, 0xe5, 0xc9, 0xb9, 0x39,
- 0x19, 0x97, 0x3e, 0xc3, 0x16, 0x1c, 0xe7, 0x19, 0xce, 0x77, 0xaa, 0x21,
- 0x92, 0x95, 0xf5, 0xa6, 0x2c, 0x39, 0x99, 0x27, 0x2d, 0x3a, 0x13, 0xbe,
- 0xad, 0xde, 0xe8, 0x81, 0xda, 0xe6, 0xc1, 0x66, 0x9c, 0x32, 0xf4, 0xfe,
- 0x7b, 0xf1, 0x27, 0xe8, 0x0d, 0x39, 0xd8, 0x6f, 0xac, 0x64, 0x3e, 0x51,
- 0x8d, 0xf5, 0x6d, 0x34, 0xcf, 0x3b, 0x3a, 0x88, 0x09, 0x56, 0x8f, 0x07,
- 0xb2, 0x9e, 0xbb, 0xf1, 0x2e, 0x3b, 0x1a, 0xe9, 0x7e, 0x50, 0x01, 0x56,
- 0x0c, 0xf8, 0xa1, 0x29, 0x2e, 0xdf, 0x89, 0x0d, 0xa9, 0xb2, 0xb6, 0xfc,
- 0x2f, 0x15, 0xc5, 0xb3, 0x10, 0x2a, 0xb4, 0x46, 0x69, 0x67, 0x25, 0xac,
- 0xc9, 0x0e, 0x17, 0x4f, 0x6a, 0x16, 0x2a, 0xb8, 0x75, 0x61, 0xc4, 0x4a,
- 0x29, 0x8e, 0xb3, 0x2a, 0xee, 0x75, 0x9f, 0xef, 0x98, 0x6c, 0x4d, 0xdd,
- 0xa9, 0xfe, 0x8b, 0x63, 0xb9, 0xeb, 0xd9, 0x91, 0x60, 0x52, 0x65, 0x9f,
- 0x3f, 0xf2, 0xac, 0xa2, 0x8c, 0x93, 0x5c, 0x9c, 0xbc, 0xfb, 0xc9, 0xd2,
- 0xfa, 0xaf, 0xcf, 0x5c, 0xff, 0x17, 0xfb, 0x75, 0xc9, 0xf7, 0xbe, 0xe4,
- 0x9e, 0xfb, 0xc8, 0x66, 0x64, 0xfd, 0xf0, 0xe1, 0x00, 0xaa, 0x57, 0xa2,
- 0x77, 0xf2, 0x3a, 0x4c, 0xb4, 0xfd, 0xab, 0x93, 0x2b, 0xf6, 0x5d, 0xcc,
- 0xd0, 0x3f, 0xcf, 0xcc, 0xdd, 0x75, 0x7d, 0x4b, 0x84, 0x1c, 0x5c, 0xce,
- 0x7a, 0x92, 0x0b, 0x2b, 0x45, 0x1e, 0x3e, 0x5f, 0xbf, 0x09, 0xcf, 0x5e,
- 0x24, 0x53, 0xd6, 0x12, 0xca, 0x32, 0x77, 0x51, 0x9e, 0xc8, 0x65, 0x3c,
- 0xd0, 0xff, 0xcd, 0x19, 0x09, 0xcd, 0x2c, 0x17, 0xab, 0x2a, 0xc6, 0x2a,
- 0x29, 0x57, 0x6e, 0xb7, 0x82, 0xf5, 0xde, 0x77, 0x46, 0x2f, 0x2a, 0xf7,
- 0xd3, 0x52, 0xb9, 0x67, 0x02, 0x72, 0x66, 0x24, 0x9b, 0x11, 0xce, 0x7a,
- 0xca, 0x19, 0xbb, 0xa8, 0x4c, 0x4b, 0xf5, 0xc5, 0x65, 0x9a, 0x89, 0xd1,
- 0xff, 0xaf, 0x33, 0x7e, 0x51, 0x99, 0xe4, 0x25, 0x65, 0x16, 0x10, 0x13,
- 0xbf, 0xef, 0xec, 0xbb, 0xa8, 0x4c, 0xed, 0x25, 0x65, 0x16, 0xd3, 0x1e,
- 0x9f, 0x71, 0x0e, 0x5c, 0x54, 0x66, 0xcc, 0x7f, 0x71, 0x19, 0xd9, 0xe3,
- 0x58, 0xff, 0x17, 0x5b, 0xf4, 0x75, 0x25, 0x9f, 0xbb, 0x70, 0xbf, 0x58,
- 0xfe, 0xf1, 0x4b, 0xfa, 0x1f, 0xb1, 0x64, 0xbe, 0x7d, 0xed, 0xe5, 0xf9,
- 0x7e, 0xb8, 0x74, 0xff, 0x7b, 0x35, 0x17, 0x97, 0xbb, 0x22, 0x70, 0x69,
- 0x3b, 0x45, 0x79, 0x47, 0x2f, 0x69, 0xff, 0xe6, 0xca, 0x8b, 0xbf, 0xbf,
- 0x5d, 0x51, 0xfc, 0x5e, 0xd6, 0xe9, 0xa1, 0x4b, 0x9e, 0xff, 0x7d, 0xc5,
- 0xc5, 0xdf, 0x37, 0x54, 0x7e, 0x78, 0x3b, 0xb5, 0x97, 0xb4, 0xa3, 0xf4,
- 0xca, 0xbb, 0x38, 0x1e, 0x53, 0xad, 0xed, 0xed, 0x58, 0x7f, 0x43, 0x2a,
- 0xbf, 0x89, 0xf6, 0x29, 0xb6, 0xf5, 0xe0, 0x0d, 0x6b, 0xf3, 0x6f, 0xcd,
- 0xe0, 0xb1, 0xcb, 0xc2, 0x41, 0x7c, 0x1c, 0x6b, 0xdd, 0xbd, 0x34, 0x95,
- 0x38, 0x69, 0xb9, 0xb6, 0x40, 0x8e, 0xe9, 0x57, 0xcc, 0x14, 0x0c, 0xf7,
- 0xbc, 0xe5, 0x3a, 0x34, 0xe7, 0xdd, 0x3d, 0xbb, 0x58, 0x0a, 0xcf, 0xaa,
- 0x5d, 0xba, 0x55, 0x3a, 0x47, 0x67, 0x5d, 0x1f, 0x44, 0x72, 0x66, 0x7e,
- 0xaa, 0x8d, 0x23, 0x12, 0xde, 0x86, 0x75, 0xee, 0x59, 0x6b, 0xc5, 0xec,
- 0x29, 0x9d, 0xd7, 0x5c, 0x03, 0x3d, 0x5f, 0xe6, 0x4d, 0xb2, 0x9e, 0x2b,
- 0xe7, 0x19, 0x1c, 0xfa, 0xa0, 0xc4, 0xf9, 0x83, 0x8a, 0x3a, 0xe0, 0xae,
- 0x99, 0xae, 0xf6, 0x20, 0x9a, 0xe8, 0x54, 0x90, 0xaa, 0x32, 0xa3, 0xda,
- 0xdb, 0x25, 0x4c, 0xf3, 0x4d, 0x6c, 0x51, 0x2a, 0x26, 0xfa, 0x15, 0xef,
- 0x44, 0x11, 0xd3, 0x3c, 0x13, 0xb2, 0xb6, 0xd0, 0xc0, 0x32, 0x41, 0xb4,
- 0x2c, 0xf1, 0xe2, 0x3b, 0x76, 0xad, 0xfb, 0x1e, 0xc7, 0xd6, 0x25, 0x15,
- 0x78, 0x20, 0xae, 0xa0, 0xeb, 0xaa, 0xc3, 0x78, 0x2b, 0x2f, 0xeb, 0x6c,
- 0x56, 0x7c, 0x94, 0x6d, 0x1e, 0xb2, 0x65, 0xbd, 0x74, 0x4b, 0x7c, 0xc4,
- 0x6d, 0xff, 0xf3, 0xe8, 0x73, 0xf7, 0xad, 0xba, 0x9d, 0xed, 0x99, 0x1e,
- 0x67, 0x1b, 0x73, 0x8d, 0x82, 0xdd, 0x90, 0xaa, 0x63, 0xfd, 0xb7, 0x96,
- 0xac, 0xc7, 0x69, 0x96, 0x99, 0xb0, 0x1f, 0xc4, 0xfb, 0xf9, 0x20, 0xf2,
- 0xf6, 0x4a, 0x7c, 0x37, 0x1f, 0x60, 0xce, 0xd7, 0x85, 0xef, 0xe4, 0x57,
- 0xe3, 0xc5, 0x61, 0xf7, 0x7d, 0x29, 0x2c, 0xb3, 0x15, 0xac, 0x88, 0xae,
- 0xc6, 0xb1, 0xd1, 0xd5, 0x38, 0x3c, 0x2c, 0xef, 0x0e, 0xcc, 0x25, 0x8f,
- 0x2c, 0xda, 0x9b, 0x4a, 0x8c, 0x59, 0x66, 0xaf, 0xc2, 0xa1, 0xd1, 0x30,
- 0x73, 0x29, 0x03, 0x27, 0xf3, 0x21, 0x8c, 0xd8, 0x6d, 0x38, 0x91, 0x0f,
- 0xe3, 0xeb, 0x76, 0x02, 0x67, 0xf9, 0xfd, 0xa0, 0x2d, 0x9c, 0xa5, 0x03,
- 0xd3, 0xf9, 0x6f, 0x32, 0xcf, 0x99, 0x87, 0x23, 0xdd, 0xcf, 0x30, 0x1c,
- 0x1d, 0xe4, 0xd5, 0x85, 0x13, 0xa3, 0x5d, 0x38, 0x35, 0x7c, 0x2b, 0x4e,
- 0x8d, 0xfe, 0x18, 0x6f, 0x0d, 0x4b, 0x7f, 0xe5, 0xfc, 0xb7, 0xc8, 0xd5,
- 0x29, 0x77, 0x35, 0xa6, 0x46, 0xff, 0x18, 0xd9, 0xef, 0x3a, 0x47, 0x56,
- 0x8b, 0xdc, 0x67, 0x7e, 0x87, 0x6c, 0xd1, 0xa5, 0x60, 0xbf, 0x1f, 0xc7,
- 0x6c, 0x3f, 0x8e, 0xda, 0x53, 0x57, 0x56, 0x61, 0xea, 0x7a, 0x22, 0x1d,
- 0xb6, 0xe7, 0x2b, 0xf1, 0x5c, 0x56, 0xd6, 0xd8, 0x3e, 0x86, 0x64, 0x70,
- 0x23, 0xb6, 0x4e, 0x56, 0xe2, 0x3b, 0x59, 0x3f, 0x75, 0x7c, 0x3d, 0x92,
- 0xf5, 0xab, 0xa9, 0xbf, 0x00, 0x5e, 0xb2, 0x43, 0x78, 0xd9, 0x6e, 0x4d,
- 0x15, 0x94, 0x76, 0x58, 0x2e, 0xfe, 0x07, 0xa8, 0xef, 0x0d, 0x6e, 0x9f,
- 0xbe, 0x63, 0x77, 0x3b, 0x5b, 0xa9, 0xe3, 0xfe, 0xcc, 0xe7, 0xdd, 0xb3,
- 0xdb, 0x2f, 0xda, 0xd3, 0x8e, 0xbc, 0x93, 0xf1, 0x14, 0x75, 0x7a, 0xcc,
- 0x4e, 0x91, 0xdb, 0x35, 0x71, 0x8e, 0xa6, 0x30, 0x4a, 0xbb, 0x3c, 0x99,
- 0xd5, 0x8f, 0xae, 0xc5, 0x26, 0x9c, 0xcd, 0x55, 0xe2, 0x35, 0xb6, 0x51,
- 0xb7, 0xd8, 0x8b, 0xe3, 0xae, 0xbc, 0x4d, 0x78, 0x3f, 0xab, 0x30, 0xde,
- 0x6e, 0xc2, 0x7b, 0x7c, 0xf6, 0x0a, 0x3f, 0x9f, 0x8e, 0xb3, 0x87, 0xa5,
- 0x67, 0xa7, 0xc8, 0xcf, 0x65, 0xcd, 0xa8, 0xb7, 0x63, 0x13, 0x4e, 0xe4,
- 0xde, 0x23, 0xa7, 0x75, 0xf0, 0x45, 0x63, 0x36, 0x12, 0xb3, 0xc9, 0x9b,
- 0xf4, 0x4a, 0x1c, 0xe3, 0xf3, 0x85, 0xc4, 0xdf, 0xe2, 0xfa, 0xd9, 0x26,
- 0xbc, 0xcb, 0xf1, 0x3c, 0x40, 0x59, 0xef, 0xe4, 0xfe, 0x96, 0x72, 0x97,
- 0x22, 0x1f, 0xff, 0x5b, 0xca, 0xfd, 0x31, 0xc6, 0x4b, 0xfa, 0x38, 0x61,
- 0xc8, 0xb8, 0xbe, 0x31, 0x0b, 0xd5, 0x21, 0x8e, 0xe3, 0x9b, 0xfc, 0xbf,
- 0x01, 0xc7, 0xf3, 0xff, 0x9b, 0xff, 0xbf, 0x8b, 0x03, 0x79, 0x59, 0xaf,
- 0x9e, 0x19, 0x4b, 0xc5, 0x7f, 0xca, 0x1c, 0x64, 0x0e, 0x32, 0x83, 0xb5,
- 0xa9, 0xd9, 0xb4, 0xa3, 0xbf, 0xbe, 0xb6, 0x0e, 0xef, 0xc6, 0x2d, 0xec,
- 0xd8, 0xe7, 0x45, 0x86, 0xb8, 0xbb, 0x63, 0xa0, 0x01, 0x4f, 0xec, 0x0c,
- 0xe2, 0xf1, 0x9d, 0x97, 0x61, 0xcb, 0xce, 0x2b, 0xb0, 0x67, 0x67, 0x13,
- 0xd2, 0x3b, 0x1d, 0xe7, 0xfd, 0xc5, 0x8e, 0xb3, 0x88, 0xd7, 0x23, 0xf4,
- 0x05, 0x3f, 0xff, 0xbf, 0x10, 0x17, 0x3f, 0xd1, 0x71, 0x95, 0xeb, 0x2f,
- 0x9d, 0xb8, 0xd2, 0xfd, 0x9f, 0xc4, 0xa2, 0xfc, 0xc6, 0xf8, 0xfa, 0xc2,
- 0xa6, 0xf8, 0x7d, 0x85, 0x39, 0xd8, 0x3a, 0xd8, 0x88, 0xc1, 0x9d, 0x0d,
- 0xa9, 0x06, 0xb6, 0xb3, 0xea, 0x5a, 0xe1, 0x76, 0x8e, 0x63, 0xb4, 0xf7,
- 0xc7, 0xd7, 0x16, 0x9e, 0x41, 0x77, 0x21, 0x84, 0xbe, 0xc1, 0x30, 0xdb,
- 0x92, 0xbd, 0x5c, 0xef, 0xd1, 0x7b, 0xe1, 0x38, 0xd3, 0x8b, 0x0f, 0xe2,
- 0xae, 0xc2, 0x37, 0xc9, 0x1b, 0x43, 0x48, 0x0f, 0xae, 0x47, 0x66, 0xb2,
- 0x22, 0xe5, 0x37, 0x1d, 0xbc, 0x14, 0x9f, 0xc2, 0xed, 0x94, 0xf7, 0xe8,
- 0x60, 0x2d, 0xfb, 0x54, 0x9d, 0xaa, 0x34, 0x25, 0x86, 0x3f, 0xc8, 0x18,
- 0x25, 0xfc, 0xe2, 0x28, 0x56, 0x30, 0xbf, 0xaa, 0x5f, 0xa2, 0xcf, 0x42,
- 0x6d, 0xd0, 0x7b, 0xa6, 0x43, 0xec, 0x2f, 0x45, 0xfb, 0x93, 0x7d, 0xf5,
- 0x75, 0xb8, 0xdb, 0x3d, 0xe7, 0xdd, 0x83, 0xe7, 0x6d, 0xc1, 0x9d, 0x35,
- 0xd8, 0x6f, 0xaf, 0x63, 0xce, 0x25, 0xf1, 0x7a, 0x25, 0x9a, 0x0b, 0x7f,
- 0x17, 0xbf, 0xa7, 0xb0, 0x9a, 0x7c, 0xf6, 0x5f, 0x70, 0x53, 0x21, 0xc7,
- 0x7e, 0x8d, 0xc6, 0xef, 0x2e, 0xec, 0x89, 0xdf, 0x5b, 0xe8, 0xc2, 0x02,
- 0x37, 0xa7, 0x64, 0xfe, 0x55, 0x90, 0x38, 0x77, 0x9c, 0x5c, 0xf8, 0x14,
- 0x96, 0x17, 0x5e, 0xc3, 0xcd, 0x05, 0xc1, 0x0d, 0x89, 0x7f, 0x2f, 0x7a,
- 0x51, 0x2d, 0x71, 0xef, 0x0b, 0xd8, 0xba, 0x3b, 0x85, 0xbe, 0xdd, 0x65,
- 0x8c, 0x6a, 0x0d, 0xee, 0x13, 0x7c, 0x99, 0xf4, 0x95, 0x62, 0xd4, 0xa7,
- 0x68, 0x8f, 0x2a, 0x63, 0xa3, 0xac, 0xd3, 0xaf, 0xa3, 0x2f, 0x6f, 0x24,
- 0x66, 0xca, 0x7a, 0xfc, 0x27, 0x4b, 0xf7, 0x25, 0xd6, 0xcb, 0x5a, 0xbc,
- 0x86, 0x43, 0x79, 0x77, 0x4f, 0x5b, 0xf3, 0xeb, 0xb7, 0xf3, 0x99, 0xd4,
- 0xff, 0x02, 0xd2, 0xbb, 0x57, 0x3b, 0x8f, 0x66, 0x8a, 0xfb, 0x66, 0x47,
- 0xa2, 0x6c, 0x6b, 0x9c, 0xb1, 0x7d, 0x2f, 0xfc, 0xb3, 0x38, 0xb6, 0x89,
- 0x01, 0x58, 0x1e, 0xbd, 0xdb, 0xd9, 0x92, 0xc1, 0xbd, 0xb3, 0x10, 0xc6,
- 0xca, 0x89, 0x0a, 0x24, 0xf7, 0x57, 0xe3, 0xb6, 0x9d, 0x3d, 0xb4, 0x65,
- 0x8b, 0xf6, 0xab, 0x1b, 0x77, 0x2b, 0xd5, 0xb8, 0x99, 0xf7, 0x3e, 0x3d,
- 0x28, 0x6b, 0x58, 0xd1, 0xa3, 0x27, 0x3c, 0xd5, 0xb8, 0x6b, 0xaf, 0x1f,
- 0xb9, 0xdc, 0x4a, 0x24, 0xf7, 0x1e, 0x81, 0x95, 0xa3, 0x4d, 0xee, 0x22,
- 0xce, 0x30, 0xcd, 0x51, 0xcd, 0x1f, 0x63, 0xcf, 0xa8, 0x8a, 0xba, 0x5d,
- 0xb2, 0xfe, 0xa8, 0xe8, 0xa7, 0xa3, 0x05, 0xa4, 0x47, 0xbd, 0x98, 0x95,
- 0xee, 0xc4, 0x04, 0xb1, 0x26, 0x90, 0x4e, 0x22, 0x9f, 0xef, 0x46, 0x8e,
- 0x58, 0x92, 0x1b, 0x0d, 0xa0, 0x26, 0x6d, 0x20, 0xa0, 0xc7, 0xb0, 0x83,
- 0xfe, 0x52, 0x91, 0xd6, 0xb1, 0x2d, 0x7f, 0x23, 0xac, 0xd1, 0x4f, 0x60,
- 0xfb, 0x68, 0x37, 0x2f, 0x13, 0x7d, 0xa3, 0x9f, 0xc7, 0xb2, 0x89, 0xa3,
- 0xe8, 0xcf, 0xa7, 0x68, 0x8f, 0xef, 0x61, 0x7b, 0xee, 0x30, 0x9e, 0xc8,
- 0x6e, 0xc6, 0xd9, 0xc5, 0x87, 0xf1, 0x38, 0x3f, 0x67, 0xb3, 0xfa, 0xc6,
- 0xb0, 0x7a, 0x18, 0x99, 0xdc, 0x26, 0x7c, 0x62, 0x50, 0xc1, 0x4b, 0xb4,
- 0xf5, 0xdb, 0xf7, 0xd2, 0x16, 0x1f, 0xdb, 0x80, 0xae, 0x89, 0xef, 0xc2,
- 0xce, 0x3f, 0x8f, 0x1d, 0xb9, 0x07, 0xd1, 0x9f, 0x59, 0xcf, 0xfc, 0xff,
- 0x19, 0xca, 0x39, 0x48, 0x3f, 0xdf, 0xc8, 0x31, 0x3e, 0xcc, 0xeb, 0xc2,
- 0x1a, 0xe3, 0x85, 0x35, 0x39, 0xfa, 0x7d, 0x46, 0x72, 0xcf, 0x75, 0xc4,
- 0x89, 0x27, 0x6b, 0x65, 0x5d, 0xb2, 0x4a, 0x9f, 0xb9, 0x56, 0x2f, 0xb6,
- 0x1f, 0x76, 0x73, 0xed, 0xaa, 0xb4, 0xe4, 0x75, 0x53, 0x91, 0x2a, 0x72,
- 0x0c, 0x7f, 0x5a, 0x74, 0xd8, 0xe3, 0xf4, 0x66, 0x04, 0x4b, 0x64, 0x3e,
- 0x34, 0xbc, 0x90, 0xff, 0x31, 0xb6, 0x0e, 0xcf, 0xc6, 0xf2, 0x6c, 0x1b,
- 0x39, 0xa5, 0xe3, 0x7c, 0x85, 0xbe, 0x66, 0x93, 0xeb, 0xec, 0x18, 0x4c,
- 0x12, 0x53, 0x66, 0x23, 0x39, 0xa7, 0xc8, 0x4f, 0xc2, 0x69, 0x69, 0xcb,
- 0x57, 0xda, 0xab, 0x9b, 0xba, 0x32, 0xcc, 0x7b, 0x75, 0x69, 0x99, 0xb7,
- 0x88, 0xa1, 0xb9, 0xfb, 0x69, 0x8e, 0xf3, 0x52, 0xb4, 0xcc, 0x95, 0xa6,
- 0xae, 0xac, 0xc3, 0x6c, 0x59, 0x77, 0x4d, 0xc8, 0x39, 0xdf, 0x6f, 0xb5,
- 0x2c, 0xa7, 0xaf, 0x7e, 0x01, 0x03, 0xe3, 0xe5, 0x77, 0x23, 0xff, 0xb3,
- 0xe4, 0xdd, 0xf5, 0x9f, 0x2c, 0xaf, 0xbc, 0x07, 0x2a, 0xe7, 0x8c, 0xcb,
- 0xef, 0x50, 0x8a, 0x2e, 0xaf, 0x90, 0xfd, 0x03, 0xab, 0xb8, 0x4f, 0x0a,
- 0x1c, 0xb1, 0x2b, 0x18, 0x87, 0xd5, 0xa5, 0x64, 0x63, 0x21, 0x1f, 0x2a,
- 0x19, 0x2f, 0x1b, 0xd1, 0x47, 0xbe, 0x7a, 0x93, 0x51, 0x81, 0x03, 0x6d,
- 0x49, 0x39, 0xcf, 0xd7, 0xe3, 0x73, 0x79, 0xea, 0xa6, 0x3f, 0xff, 0x6d,
- 0x9e, 0xba, 0x09, 0xe9, 0x8c, 0x9c, 0x63, 0xeb, 0xc6, 0x4b, 0xf5, 0xf2,
- 0x5e, 0xe7, 0x26, 0xf7, 0x9c, 0x70, 0xd5, 0x42, 0x62, 0x46, 0x5c, 0xc3,
- 0x51, 0xbd, 0x55, 0x6b, 0x50, 0x23, 0x06, 0x94, 0xd7, 0x1d, 0x2b, 0x94,
- 0x44, 0xff, 0xa4, 0x9c, 0xd5, 0xfb, 0xa8, 0x3d, 0x84, 0xb5, 0xd8, 0xfe,
- 0x58, 0x07, 0x8e, 0xaf, 0x96, 0xb5, 0xbc, 0x9f, 0x95, 0xde, 0xdb, 0x93,
- 0x3e, 0x46, 0xea, 0xe4, 0x0c, 0xaa, 0xc8, 0xde, 0x9e, 0x51, 0x19, 0x7b,
- 0xe2, 0x78, 0x3d, 0xe8, 0x8e, 0x37, 0x56, 0x3e, 0x97, 0x59, 0xa9, 0x2f,
- 0x2f, 0x95, 0x5f, 0x50, 0x27, 0xbc, 0x64, 0x5b, 0x66, 0x13, 0xb9, 0xb6,
- 0xf4, 0xe7, 0xd7, 0xce, 0xda, 0x50, 0x03, 0xcb, 0x8e, 0x95, 0x9e, 0x8b,
- 0xad, 0x45, 0x8c, 0x24, 0xe4, 0x9e, 0xd4, 0x11, 0x9d, 0xcd, 0xac, 0xe3,
- 0x41, 0xbd, 0x7e, 0x25, 0x1e, 0xa2, 0x8f, 0xcf, 0xd7, 0x5f, 0x76, 0x36,
- 0xcb, 0x39, 0xcd, 0x85, 0xc1, 0x19, 0x6d, 0x2d, 0x75, 0xfb, 0x52, 0xc9,
- 0xbe, 0x0c, 0x66, 0xe4, 0xbd, 0x81, 0xb3, 0xce, 0xc2, 0x46, 0x79, 0x7e,
- 0x5b, 0x6d, 0x51, 0x7e, 0xb3, 0x7b, 0x0e, 0x7b, 0x4f, 0xa6, 0xdc, 0x6f,
- 0x39, 0xe3, 0x1e, 0x2a, 0xb7, 0x15, 0xbb, 0x30, 0x1e, 0xe9, 0xdb, 0xd7,
- 0x6a, 0x2f, 0xee, 0xf3, 0x9d, 0xb3, 0xca, 0xef, 0x17, 0xcc, 0x73, 0xeb,
- 0x94, 0xdb, 0x94, 0x3e, 0x6e, 0xc2, 0xe3, 0x93, 0x97, 0x8e, 0xf1, 0xee,
- 0x19, 0x63, 0x92, 0x3a, 0x32, 0xae, 0x60, 0xc9, 0x0e, 0x36, 0xb2, 0x8c,
- 0xd4, 0x91, 0x75, 0x82, 0xa0, 0x9b, 0x3f, 0xd4, 0xed, 0x16, 0x79, 0x22,
- 0xc3, 0x71, 0xde, 0x70, 0x63, 0xf2, 0x02, 0xb7, 0xcc, 0xe0, 0xe4, 0x6a,
- 0xfa, 0x91, 0xb3, 0x99, 0xf8, 0xec, 0xbc, 0xd1, 0x11, 0xc6, 0x56, 0x5b,
- 0x74, 0xad, 0x87, 0xc7, 0x88, 0x4d, 0x7d, 0x2e, 0x9f, 0xf1, 0xa1, 0x37,
- 0x57, 0x3e, 0xeb, 0x52, 0x29, 0x7b, 0x21, 0x61, 0xd1, 0x79, 0xaf, 0x41,
- 0x1e, 0x17, 0x5c, 0xa6, 0x79, 0xc9, 0xc5, 0xee, 0xc1, 0x7f, 0xc8, 0xfc,
- 0xc6, 0x7c, 0xa5, 0x75, 0x93, 0x14, 0xed, 0xa8, 0x18, 0x0f, 0x41, 0xfe,
- 0x40, 0x1e, 0x56, 0x3a, 0x43, 0xdf, 0x9b, 0xff, 0x0f, 0x67, 0xca, 0x3d,
- 0x43, 0x7f, 0xe1, 0x2c, 0x4a, 0x2e, 0xe8, 0x38, 0xfb, 0xf8, 0xec, 0xc2,
- 0x79, 0x7a, 0x72, 0x06, 0x5d, 0xce, 0xdd, 0xff, 0x3b, 0xe7, 0x6e, 0x66,
- 0xd9, 0xa9, 0xfa, 0xe2, 0xfb, 0x25, 0x49, 0x75, 0x99, 0x5e, 0xc6, 0x6d,
- 0xd9, 0x27, 0x12, 0xdc, 0x3e, 0x58, 0x57, 0x5c, 0x3f, 0x8e, 0x74, 0x75,
- 0x43, 0xf6, 0xe4, 0xcb, 0x38, 0xa3, 0x1b, 0x8b, 0x94, 0xcd, 0x68, 0x89,
- 0x57, 0xcb, 0xf9, 0xba, 0x88, 0xd7, 0x8c, 0x04, 0xdf, 0x42, 0x34, 0x76,
- 0xd8, 0x3d, 0x43, 0x22, 0xd8, 0xa3, 0xe3, 0x9e, 0xbc, 0x4e, 0x9b, 0x95,
- 0xf7, 0xd2, 0xe5, 0x73, 0xf1, 0xdd, 0xc7, 0x64, 0x5e, 0xb0, 0xba, 0x87,
- 0x58, 0x6d, 0xfd, 0xa5, 0xcf, 0x95, 0x17, 0xe9, 0x19, 0x55, 0x22, 0x5d,
- 0x0f, 0x2a, 0x65, 0x79, 0x81, 0x0f, 0x91, 0x17, 0x63, 0x7d, 0xad, 0xf4,
- 0x2e, 0xb8, 0x4e, 0x19, 0x97, 0x9e, 0x0d, 0x9a, 0x93, 0x92, 0x3c, 0xfa,
- 0x40, 0x89, 0x73, 0x1e, 0xfe, 0xad, 0x3c, 0xfa, 0x43, 0xdb, 0x4c, 0xb2,
- 0xcd, 0xae, 0x6a, 0x25, 0x19, 0x97, 0xf7, 0x80, 0x2a, 0xe3, 0xd1, 0xd8,
- 0x0b, 0x74, 0x72, 0xaf, 0x19, 0x0d, 0x8f, 0xba, 0x67, 0x5d, 0x0c, 0xff,
- 0xf2, 0x7c, 0xd1, 0x7f, 0xac, 0xc9, 0xdf, 0xad, 0x93, 0x1a, 0x5d, 0xef,
- 0x6e, 0x55, 0x92, 0xd7, 0x57, 0x53, 0x4e, 0x2c, 0x0e, 0xad, 0xc2, 0x2c,
- 0xeb, 0x28, 0x1a, 0x7b, 0x8b, 0xf3, 0x79, 0xa8, 0x23, 0x1a, 0x1e, 0x71,
- 0x73, 0x74, 0xd1, 0x8b, 0xe1, 0x2f, 0xce, 0xbd, 0x2e, 0x7c, 0xde, 0xf2,
- 0x31, 0x36, 0x8f, 0xdb, 0x7e, 0x8e, 0xa5, 0x35, 0xb8, 0x1d, 0xf5, 0xb4,
- 0x71, 0x24, 0xfb, 0xda, 0x18, 0x1f, 0x6c, 0x24, 0x3d, 0x57, 0xd5, 0x21,
- 0x45, 0x82, 0xee, 0xd1, 0x53, 0xe4, 0x5c, 0xad, 0xb1, 0x47, 0x68, 0xbf,
- 0xb9, 0x50, 0x24, 0x6c, 0x21, 0x85, 0xe7, 0xec, 0x65, 0x7f, 0xee, 0x81,
- 0x65, 0xd4, 0x70, 0xa2, 0xab, 0xcd, 0xa9, 0x3f, 0xbf, 0x35, 0x1a, 0xd1,
- 0x5e, 0x2c, 0x9d, 0xd5, 0xe9, 0xb5, 0x7f, 0xe1, 0xee, 0x51, 0x79, 0xf4,
- 0xdf, 0x55, 0x46, 0xda, 0xf6, 0x63, 0x2c, 0x9b, 0xc5, 0x96, 0xc7, 0xd8,
- 0x47, 0xdd, 0xc1, 0x32, 0x63, 0x33, 0x96, 0x1b, 0x01, 0xac, 0x0b, 0xb6,
- 0x24, 0xe4, 0x2c, 0xd2, 0x48, 0xae, 0xb8, 0x36, 0x52, 0x5c, 0x0b, 0xef,
- 0xc7, 0xa3, 0x19, 0x37, 0x3e, 0x07, 0xfd, 0x66, 0x52, 0x79, 0x34, 0xdf,
- 0xa9, 0x3c, 0x52, 0x5a, 0x8f, 0xeb, 0xcf, 0xdf, 0x10, 0x44, 0xb5, 0x85,
- 0x13, 0x86, 0xbc, 0x47, 0x29, 0x72, 0x2d, 0x8c, 0x76, 0xfc, 0x21, 0xef,
- 0x53, 0x8a, 0x4e, 0x37, 0xa2, 0x6f, 0xf8, 0x61, 0xf4, 0x0e, 0xbf, 0xe4,
- 0x9e, 0x65, 0xf5, 0xe9, 0x7e, 0xeb, 0x0a, 0x33, 0x72, 0xd0, 0xc2, 0xbc,
- 0x7a, 0x59, 0x13, 0x6e, 0x34, 0x8f, 0xe2, 0xd1, 0xa0, 0xbc, 0x27, 0xd8,
- 0x4f, 0x9e, 0x22, 0xef, 0x9c, 0xad, 0xc1, 0x67, 0x06, 0x64, 0x0e, 0x6b,
- 0xad, 0x4a, 0x33, 0x92, 0x5c, 0xe7, 0xce, 0x61, 0x1b, 0x8e, 0x15, 0x1e,
- 0xc6, 0x1b, 0xbb, 0x36, 0x43, 0x8d, 0x47, 0xc2, 0xb7, 0xc0, 0xd9, 0x7c,
- 0xc4, 0x48, 0x5a, 0x3e, 0x44, 0x0e, 0x78, 0x54, 0xe0, 0xd9, 0x5d, 0x92,
- 0x4f, 0xf7, 0xe0, 0x7a, 0x72, 0x80, 0x3a, 0xdd, 0x59, 0xfa, 0xab, 0xc5,
- 0x91, 0x7e, 0xdd, 0x63, 0xfd, 0xd3, 0x1c, 0x44, 0xb2, 0x09, 0x55, 0xef,
- 0xf9, 0xa4, 0x0a, 0x25, 0x60, 0xca, 0x6f, 0x00, 0x6c, 0xc6, 0x27, 0xda,
- 0x03, 0xd6, 0x2c, 0x33, 0x92, 0x7d, 0x49, 0x89, 0xc4, 0x2c, 0xf5, 0x1b,
- 0x9c, 0xe7, 0x18, 0x5e, 0x24, 0xc7, 0xe9, 0x62, 0x6c, 0x5f, 0x21, 0x31,
- 0xdd, 0xc5, 0xbe, 0xe6, 0x44, 0x95, 0x12, 0xc4, 0x2d, 0x05, 0xe0, 0x50,
- 0x6e, 0x0d, 0x4e, 0xee, 0x32, 0xd0, 0xc9, 0x67, 0x83, 0x19, 0x02, 0x16,
- 0x31, 0x60, 0x83, 0x61, 0xb5, 0xaa, 0xe4, 0x16, 0x3e, 0x15, 0xcb, 0xe6,
- 0x9b, 0xd1, 0xa9, 0xa5, 0x1e, 0x2f, 0x12, 0x05, 0x2f, 0xee, 0x60, 0x99,
- 0xed, 0x8c, 0x0b, 0x9f, 0x4c, 0xfb, 0xc9, 0x6f, 0x9b, 0xf0, 0x33, 0xf2,
- 0xec, 0x9f, 0x92, 0x4f, 0x1f, 0x27, 0x5f, 0x38, 0x9e, 0xaf, 0x46, 0xf7,
- 0x90, 0x4f, 0xce, 0x1f, 0x4d, 0xf9, 0x38, 0x17, 0xb5, 0xed, 0x21, 0x9c,
- 0x1e, 0xf5, 0xe3, 0xf6, 0x5d, 0x91, 0x3d, 0xc7, 0xd5, 0x46, 0xbc, 0x3f,
- 0x5a, 0x8d, 0x95, 0x43, 0x7e, 0xf6, 0xcd, 0xc1, 0x0e, 0xe2, 0xff, 0xbb,
- 0x7c, 0xd6, 0xb9, 0x0b, 0x4a, 0x7e, 0xc9, 0x02, 0xe6, 0x04, 0x3a, 0xeb,
- 0xd7, 0xe0, 0xd6, 0x21, 0xe1, 0x81, 0x2a, 0xde, 0x1e, 0x55, 0xf0, 0x56,
- 0xce, 0xc0, 0x32, 0xb6, 0xd7, 0x97, 0x79, 0xd6, 0xf1, 0xd3, 0xcf, 0xd7,
- 0xe6, 0x0d, 0xdc, 0x9b, 0xd3, 0x19, 0x53, 0x7e, 0xe2, 0x78, 0xf4, 0x76,
- 0xfc, 0x64, 0xa7, 0x7e, 0xf4, 0x75, 0x4f, 0x74, 0x6a, 0x89, 0xa7, 0x1d,
- 0xaf, 0xed, 0x6f, 0xc7, 0xf7, 0x06, 0x97, 0xe2, 0x9a, 0xf6, 0x24, 0xce,
- 0x2c, 0x69, 0xc7, 0xab, 0x7b, 0x75, 0x3c, 0x92, 0xe9, 0x80, 0x36, 0x31,
- 0x45, 0xfe, 0x9b, 0x40, 0xeb, 0x84, 0x09, 0x7d, 0xd0, 0xd9, 0x5c, 0x63,
- 0x6e, 0xc6, 0xa3, 0x86, 0x89, 0x45, 0x7b, 0x45, 0x0f, 0x8e, 0xb3, 0x6e,
- 0x89, 0x89, 0x17, 0xb2, 0x3a, 0xfd, 0xd4, 0xa4, 0x1e, 0x74, 0x3c, 0x9e,
- 0x31, 0x11, 0x7d, 0x4c, 0x9f, 0xde, 0xc7, 0xef, 0x4b, 0xf7, 0x75, 0xa0,
- 0x87, 0xed, 0xdb, 0xc4, 0xeb, 0x3d, 0x13, 0x6d, 0x1c, 0xb3, 0xc1, 0xf1,
- 0x37, 0x5b, 0x3f, 0x53, 0x3a, 0x91, 0x9d, 0xe8, 0x22, 0x9f, 0xdd, 0x4c,
- 0x1e, 0xdb, 0xe5, 0xee, 0xb9, 0x6f, 0xcd, 0x18, 0xb8, 0x35, 0xdd, 0x85,
- 0x27, 0x6d, 0x39, 0x3b, 0xaf, 0x27, 0xae, 0x55, 0xe4, 0x1d, 0xdd, 0x2e,
- 0x8c, 0x51, 0x27, 0xcb, 0x86, 0x56, 0xba, 0xe7, 0x9d, 0x96, 0xef, 0xd2,
- 0xf1, 0x44, 0xe6, 0x13, 0x38, 0x39, 0x6e, 0xa0, 0x3b, 0x2d, 0xfa, 0x96,
- 0xf3, 0x9b, 0x29, 0x1c, 0x61, 0x6c, 0xf9, 0xd9, 0x50, 0xf2, 0x9f, 0x38,
- 0xcd, 0xc7, 0x54, 0xc8, 0x7a, 0x89, 0x8a, 0xab, 0xdb, 0xe5, 0x0c, 0xae,
- 0x87, 0xa8, 0x16, 0xb1, 0xea, 0x54, 0x4b, 0xe3, 0x7d, 0xcb, 0xab, 0x6e,
- 0xc2, 0x67, 0x87, 0xbc, 0xcc, 0x19, 0x54, 0xe6, 0x3a, 0xd6, 0x06, 0xda,
- 0x86, 0x55, 0xab, 0x16, 0xe7, 0xcd, 0xdd, 0x63, 0xd0, 0x3d, 0xd8, 0x61,
- 0x34, 0x77, 0xd7, 0xb0, 0xde, 0x8a, 0x78, 0x24, 0x59, 0xa5, 0x76, 0x30,
- 0x0f, 0x7d, 0x18, 0xeb, 0x76, 0x3d, 0x8c, 0xb5, 0xbc, 0x36, 0xec, 0x72,
- 0x36, 0xdf, 0x6c, 0x28, 0x78, 0x4e, 0x77, 0x36, 0x6f, 0x36, 0x74, 0xce,
- 0xad, 0xcc, 0xeb, 0xc3, 0xd8, 0x38, 0xf6, 0x30, 0x1e, 0xa2, 0x7d, 0x35,
- 0xd0, 0x8f, 0x57, 0xa5, 0x9d, 0xcd, 0xd7, 0xb4, 0xc7, 0xf0, 0x73, 0x37,
- 0xbf, 0x11, 0x7b, 0x3d, 0xe3, 0xe6, 0xdc, 0x39, 0xd5, 0xb5, 0xdd, 0xa0,
- 0x7c, 0xb6, 0xd4, 0x25, 0xc1, 0x72, 0x6c, 0xf9, 0x05, 0xe5, 0xfe, 0x72,
- 0x57, 0x1d, 0x1e, 0x6b, 0x90, 0xf8, 0xe1, 0xb7, 0xaa, 0x4c, 0x28, 0xfa,
- 0x12, 0xe6, 0x71, 0x8f, 0x1d, 0xc1, 0x76, 0xf2, 0xc2, 0x50, 0x5c, 0x72,
- 0xec, 0x56, 0x63, 0x8b, 0x7a, 0x23, 0xb1, 0x5d, 0xc1, 0xa3, 0x0b, 0xb3,
- 0x18, 0xa0, 0xaf, 0xee, 0x58, 0x18, 0x49, 0x0d, 0xc0, 0x74, 0x76, 0xcc,
- 0xe9, 0xff, 0x23, 0xde, 0xa1, 0x2d, 0xef, 0x4b, 0xca, 0x7b, 0xb4, 0x0f,
- 0x63, 0xf3, 0x2e, 0x99, 0xff, 0x87, 0xf1, 0x45, 0xf6, 0x7f, 0xe3, 0xd0,
- 0xc3, 0xf8, 0x1c, 0x6d, 0xa7, 0x7e, 0xf1, 0xa1, 0x2f, 0xd6, 0xa3, 0x25,
- 0x5b, 0x87, 0xa9, 0xfb, 0x1b, 0xe4, 0xbc, 0x2d, 0x31, 0x71, 0x40, 0x79,
- 0x18, 0xf7, 0x8c, 0xd4, 0xd2, 0x17, 0xdd, 0x31, 0x10, 0x8b, 0xcb, 0xf1,
- 0x2a, 0x8c, 0x75, 0xf9, 0xa6, 0x12, 0xae, 0x87, 0xb0, 0xd6, 0x3e, 0xe0,
- 0xfa, 0x7e, 0x85, 0xb9, 0x9a, 0x7e, 0xdf, 0x4d, 0xbf, 0x5f, 0x49, 0xbf,
- 0xef, 0xa2, 0xdf, 0x77, 0xd2, 0xef, 0x93, 0xf4, 0x7b, 0x93, 0x7e, 0x9f,
- 0xa0, 0xdf, 0x77, 0xd0, 0xef, 0x0d, 0xd9, 0x3b, 0x54, 0x8e, 0x76, 0x1c,
- 0x81, 0x6f, 0xd0, 0x4f, 0x1b, 0x2a, 0xbe, 0xd3, 0xb8, 0x9f, 0xf8, 0x73,
- 0xc2, 0x58, 0x14, 0xbe, 0x89, 0xaa, 0x1a, 0x25, 0x46, 0xe4, 0xc6, 0xff,
- 0xce, 0x7d, 0xff, 0x2d, 0x47, 0xdc, 0x7f, 0x91, 0xfa, 0x58, 0x11, 0x6f,
- 0x36, 0x9e, 0x64, 0x0c, 0xfb, 0xa1, 0xde, 0xda, 0x1f, 0x62, 0x99, 0xaf,
- 0x65, 0x5a, 0xb3, 0xb3, 0xa1, 0x5b, 0xed, 0xea, 0x56, 0x60, 0x55, 0x88,
- 0x63, 0x96, 0x73, 0xdd, 0xab, 0xf0, 0xc5, 0xe1, 0x6e, 0xfc, 0xcf, 0xe1,
- 0x20, 0x75, 0xd1, 0x3c, 0x75, 0xa3, 0x07, 0xdf, 0x0c, 0xc3, 0x13, 0x9a,
- 0x0b, 0x7c, 0xd0, 0x88, 0x45, 0x07, 0xe4, 0x5d, 0xec, 0x5c, 0xa3, 0xa7,
- 0x6d, 0x3e, 0xc4, 0x46, 0x40, 0xa4, 0xf6, 0x30, 0xd3, 0x5c, 0xe4, 0xbe,
- 0xaf, 0x99, 0x5c, 0x2d, 0x98, 0x5e, 0x85, 0xad, 0x31, 0x17, 0x67, 0x9f,
- 0x96, 0xf3, 0xe9, 0x8d, 0xc4, 0xa3, 0x80, 0xd9, 0x85, 0x6d, 0x03, 0xd6,
- 0x5d, 0x8d, 0x58, 0x89, 0xfe, 0x81, 0xa2, 0x0e, 0xee, 0x8f, 0x13, 0xf2,
- 0xcc, 0xa8, 0xb6, 0x48, 0x81, 0x77, 0x43, 0x47, 0x02, 0xf7, 0xe6, 0x6d,
- 0x64, 0x39, 0xc6, 0xf5, 0xf4, 0xb3, 0x75, 0xbf, 0xff, 0x3d, 0x7c, 0x7c,
- 0xce, 0xd6, 0x68, 0xff, 0xe7, 0x9c, 0x5c, 0xfd, 0xa2, 0x6c, 0x23, 0xf4,
- 0x8d, 0x77, 0xa8, 0xd7, 0x32, 0x67, 0x8e, 0x1c, 0xe4, 0x23, 0x6b, 0x8e,
- 0x7b, 0x8e, 0xce, 0x8f, 0x05, 0x43, 0x50, 0x46, 0xd3, 0xf2, 0xce, 0xda,
- 0x66, 0xfc, 0x5f, 0xc6, 0x37, 0x5c, 0x5b, 0x9a, 0xf2, 0xc8, 0x99, 0x16,
- 0xb9, 0xef, 0x2c, 0x3d, 0xbb, 0x38, 0x12, 0xd3, 0x3c, 0x3f, 0xa8, 0x93,
- 0xfd, 0x8b, 0xaf, 0x33, 0xce, 0x86, 0x87, 0x96, 0x42, 0x5d, 0xec, 0xc7,
- 0x9d, 0x6d, 0xb3, 0x90, 0x5a, 0x25, 0x3c, 0xd4, 0xdd, 0x5f, 0xa1, 0x3e,
- 0xff, 0x02, 0xf7, 0x19, 0x5f, 0xc1, 0xf1, 0x90, 0x8d, 0x21, 0xe2, 0xd7,
- 0x3a, 0xe3, 0x76, 0xc5, 0xe2, 0x67, 0xe6, 0x44, 0x58, 0x6f, 0x30, 0xd7,
- 0xfa, 0x54, 0x03, 0x1a, 0x76, 0x49, 0x79, 0x91, 0x7b, 0xc6, 0x95, 0xb7,
- 0x3f, 0x23, 0x9f, 0x8b, 0x36, 0x3b, 0xe5, 0xf9, 0x24, 0xd0, 0x20, 0xe7,
- 0x84, 0x15, 0xbc, 0xbd, 0xd0, 0xc6, 0x63, 0x19, 0x7c, 0xb3, 0x0a, 0xcd,
- 0xb9, 0x41, 0xd5, 0xf3, 0xcd, 0xb9, 0x58, 0x64, 0xfc, 0x5a, 0x95, 0xf9,
- 0x48, 0xe2, 0xbe, 0x85, 0x72, 0x1e, 0x4d, 0x3f, 0xf3, 0x3d, 0xfa, 0xd6,
- 0x71, 0xd8, 0xd8, 0x3e, 0xf9, 0x92, 0x33, 0x35, 0x37, 0x84, 0xa7, 0x26,
- 0xa5, 0x6e, 0x37, 0x4e, 0x70, 0x4e, 0xbe, 0xec, 0xee, 0xe7, 0x45, 0x92,
- 0x27, 0x54, 0x79, 0xe7, 0xb0, 0x1b, 0x6f, 0x8d, 0x1a, 0xd8, 0xc7, 0x1c,
- 0xea, 0x57, 0xc3, 0xab, 0xf0, 0xeb, 0xe1, 0x66, 0xed, 0x6f, 0x14, 0x39,
- 0x03, 0xff, 0x71, 0xfc, 0xa8, 0x21, 0x88, 0x83, 0xb4, 0xa1, 0x69, 0xbb,
- 0x0b, 0x6f, 0xdb, 0x56, 0x64, 0x2e, 0x22, 0x7b, 0xbc, 0x9e, 0xc8, 0x01,
- 0x79, 0xcf, 0x79, 0x9d, 0x1a, 0x39, 0xb8, 0x44, 0x89, 0x58, 0x6f, 0xa8,
- 0x2b, 0xf1, 0x8b, 0x7c, 0x17, 0xce, 0xe4, 0x67, 0xda, 0xc2, 0x66, 0x07,
- 0x8d, 0x62, 0x07, 0x62, 0x0f, 0xb4, 0x45, 0xe6, 0x8a, 0xdf, 0x26, 0x8f,
- 0xee, 0xfd, 0x18, 0xed, 0x31, 0x43, 0x7b, 0xcc, 0xd0, 0x1e, 0x89, 0x49,
- 0xcf, 0x10, 0xab, 0xbe, 0x96, 0xa1, 0x3d, 0xd2, 0x7f, 0xbe, 0x42, 0xff,
- 0x29, 0x72, 0xe5, 0x1e, 0x77, 0x4d, 0xff, 0x15, 0xc6, 0x44, 0xfb, 0x31,
- 0x79, 0x7f, 0xb8, 0x79, 0x7d, 0x01, 0x91, 0x9e, 0x01, 0x65, 0x5d, 0xbd,
- 0xbc, 0xcf, 0xf1, 0xf9, 0xa8, 0xf8, 0x80, 0xbc, 0x7b, 0x46, 0xbf, 0x1a,
- 0x3f, 0x55, 0x27, 0xef, 0xb2, 0xee, 0xdf, 0xfd, 0x51, 0x3a, 0xfb, 0x7b,
- 0xf6, 0x43, 0xf4, 0xf5, 0xc7, 0x8e, 0x5d, 0x74, 0xf9, 0x4f, 0xce, 0x8f,
- 0x1a, 0x65, 0xfc, 0xab, 0xf1, 0xf3, 0xe1, 0x4e, 0x9c, 0x65, 0xfc, 0xfd,
- 0x74, 0xfb, 0x94, 0x45, 0x9b, 0xdd, 0x68, 0x78, 0x4c, 0x4c, 0xe6, 0x3b,
- 0x71, 0xda, 0x36, 0x91, 0xb7, 0x9b, 0xd7, 0x7f, 0x57, 0x79, 0x53, 0xcd,
- 0xcd, 0x2b, 0xf2, 0xf9, 0xdf, 0x90, 0x5f, 0x1e, 0x6a, 0x91, 0xf7, 0x5d,
- 0x13, 0x18, 0xc9, 0x8b, 0x9d, 0x06, 0x71, 0xd3, 0x12, 0x43, 0xde, 0x11,
- 0xfb, 0xbd, 0x7f, 0xf7, 0xd9, 0xb2, 0x97, 0x72, 0xce, 0x99, 0x0a, 0xfa,
- 0xad, 0x20, 0x7d, 0xd8, 0xb3, 0x4b, 0x7e, 0x07, 0x40, 0xfc, 0x59, 0xc1,
- 0x67, 0x8c, 0x29, 0xad, 0x06, 0x91, 0xa7, 0x77, 0x33, 0x81, 0x7a, 0x2d,
- 0x2d, 0x67, 0x88, 0x3b, 0xf1, 0x26, 0xcb, 0x57, 0xd1, 0x2f, 0x5e, 0xcb,
- 0x7b, 0xbd, 0x3f, 0x4a, 0xcb, 0x7b, 0xec, 0x2b, 0xf1, 0xa3, 0xfc, 0xcb,
- 0xea, 0x2f, 0x82, 0x06, 0xde, 0x2e, 0xac, 0xc2, 0xfc, 0x5d, 0xb2, 0xbe,
- 0x90, 0xc4, 0x7e, 0x3b, 0x72, 0xf4, 0x59, 0xac, 0xc2, 0xbc, 0xb1, 0xd5,
- 0xcc, 0xa3, 0x15, 0xbc, 0x17, 0x5d, 0x8d, 0x00, 0x3f, 0xd7, 0xee, 0x72,
- 0x9c, 0xc3, 0xf1, 0x3a, 0x67, 0xfb, 0x6a, 0x99, 0x3b, 0xc1, 0x93, 0x65,
- 0xf5, 0xa8, 0x5d, 0x0d, 0x8c, 0x09, 0x57, 0xd1, 0x71, 0xeb, 0xc0, 0x2a,
- 0x5c, 0xb1, 0xab, 0x39, 0x76, 0x2b, 0x9a, 0xb3, 0x47, 0x3c, 0xab, 0xd0,
- 0x30, 0x76, 0x2f, 0xe7, 0x40, 0xca, 0x6a, 0xb4, 0x3f, 0x0b, 0x95, 0xe4,
- 0x84, 0x9d, 0xe9, 0x9f, 0x3a, 0xf3, 0x4d, 0x77, 0x1f, 0x0e, 0xeb, 0x0a,
- 0x3a, 0xe3, 0x5d, 0x35, 0x52, 0x23, 0x4f, 0x38, 0x75, 0xa6, 0x17, 0x6b,
- 0x0b, 0x6d, 0xb8, 0x69, 0xc8, 0x71, 0x4e, 0x2f, 0x49, 0x22, 0x60, 0x06,
- 0x88, 0x61, 0x01, 0x3c, 0x94, 0xae, 0xe1, 0x7f, 0x07, 0x15, 0x8c, 0xc9,
- 0x2d, 0xaa, 0xbe, 0x7e, 0x9e, 0x47, 0xef, 0x29, 0x28, 0x12, 0xf7, 0x03,
- 0x78, 0x80, 0xf1, 0x79, 0x45, 0x3a, 0x8c, 0x54, 0xc1, 0x71, 0x5e, 0xed,
- 0x08, 0xe1, 0x7e, 0xd6, 0xef, 0x4a, 0xf7, 0xa3, 0x97, 0x76, 0x91, 0x1a,
- 0xd3, 0xb5, 0x20, 0xe3, 0xfd, 0xba, 0x82, 0x9f, 0x31, 0xac, 0x01, 0xb7,
- 0xec, 0xd2, 0xf0, 0x50, 0x21, 0xc0, 0xf8, 0xe6, 0x2c, 0x3d, 0x69, 0x58,
- 0x57, 0x7a, 0xa0, 0x63, 0x63, 0x21, 0x84, 0x95, 0xe9, 0xc8, 0xb4, 0xbc,
- 0x47, 0x7d, 0xd6, 0x88, 0xe1, 0xc1, 0x42, 0x18, 0xb7, 0xa5, 0x0f, 0x3d,
- 0x34, 0x1f, 0xd6, 0xff, 0x98, 0x87, 0x36, 0x7c, 0xa6, 0xd0, 0x44, 0xf9,
- 0x91, 0xf5, 0xaf, 0x28, 0x4d, 0xf8, 0xec, 0x98, 0x41, 0xf9, 0x2a, 0x6e,
- 0xa5, 0x9c, 0x9b, 0xd3, 0x57, 0xe0, 0x81, 0xb1, 0x0e, 0xdc, 0x5b, 0x58,
- 0x8c, 0xe5, 0x8c, 0x4f, 0x1b, 0x98, 0x1b, 0xe2, 0xbf, 0x00, 0xb7, 0x0d,
- 0x89, 0xee, 0xa1, 0xbc, 0xda, 0x31, 0xc5, 0x7c, 0xdc, 0x00, 0x0d, 0x91,
- 0xf7, 0x74, 0x72, 0x30, 0x03, 0xb7, 0xed, 0x5d, 0xec, 0xee, 0xc9, 0x37,
- 0xc7, 0x2b, 0x91, 0xea, 0x56, 0xd0, 0x39, 0x24, 0x71, 0x56, 0xb8, 0x8d,
- 0xc1, 0xb8, 0x1a, 0x65, 0x1b, 0x06, 0xe3, 0x6a, 0xf1, 0x7e, 0x6f, 0x46,
- 0xd6, 0x2e, 0x7e, 0x42, 0xbe, 0x14, 0x47, 0xa7, 0x1b, 0xa3, 0xfd, 0xe4,
- 0xd7, 0x16, 0xbc, 0x8c, 0xdd, 0x71, 0xda, 0xf8, 0xd2, 0x76, 0x89, 0xd5,
- 0x3a, 0x06, 0xe8, 0x0f, 0x93, 0x83, 0xfa, 0x86, 0x69, 0xc5, 0x44, 0x61,
- 0xaf, 0xc4, 0xc4, 0x10, 0x1e, 0x4c, 0x9b, 0x38, 0x29, 0xe7, 0xf8, 0xaf,
- 0x4a, 0xae, 0xa8, 0x81, 0x6e, 0x3c, 0x80, 0xa8, 0x75, 0x8c, 0xb1, 0xfd,
- 0x4c, 0xae, 0x01, 0x37, 0xed, 0x92, 0x32, 0xed, 0x78, 0x7d, 0xd4, 0x8b,
- 0x9b, 0xd2, 0x9b, 0xf0, 0x44, 0xd6, 0x83, 0x11, 0xa3, 0xb9, 0x5f, 0x65,
- 0xfc, 0xbc, 0xbe, 0x3d, 0x12, 0xfc, 0x3a, 0xb9, 0xea, 0xf4, 0x62, 0x46,
- 0xe5, 0xb9, 0x1d, 0xe8, 0x64, 0xbf, 0x3a, 0x75, 0xf1, 0x49, 0x0b, 0xf7,
- 0x76, 0x6c, 0xc2, 0xb1, 0xac, 0x6e, 0x3d, 0x29, 0xeb, 0x0c, 0xed, 0x7c,
- 0x3e, 0xc7, 0x8b, 0x3e, 0x5d, 0x38, 0xad, 0x4e, 0xdf, 0x22, 0xeb, 0xd4,
- 0x3b, 0x70, 0x92, 0xf6, 0xda, 0x9f, 0x5b, 0xca, 0xd8, 0x2f, 0x31, 0xdf,
- 0x6f, 0x85, 0x59, 0xaf, 0xee, 0x3a, 0x05, 0x27, 0xf6, 0x09, 0xc7, 0x5a,
- 0x8a, 0xbb, 0xa8, 0xa7, 0xce, 0xb4, 0x8a, 0xeb, 0xc7, 0xd6, 0xe0, 0xf4,
- 0xce, 0x22, 0xe7, 0x7a, 0x35, 0x6e, 0x7d, 0x86, 0x9c, 0xab, 0x67, 0x16,
- 0x39, 0x17, 0xb9, 0x5c, 0xec, 0x41, 0xc5, 0x8b, 0x68, 0x21, 0x41, 0x5e,
- 0x21, 0xfc, 0x22, 0x8c, 0xa7, 0xf2, 0x1d, 0xb8, 0x25, 0xdd, 0x84, 0x71,
- 0xf2, 0xad, 0x1c, 0xf1, 0x22, 0x97, 0x67, 0x5c, 0x19, 0x6d, 0xe4, 0xa5,
- 0xf1, 0x5a, 0xc0, 0x4b, 0x77, 0xef, 0xad, 0xa5, 0x2d, 0x27, 0xbb, 0x25,
- 0x4f, 0x23, 0xff, 0xcd, 0x4b, 0xac, 0x56, 0x98, 0xb7, 0xfe, 0xaf, 0x7a,
- 0xc9, 0x4d, 0x83, 0xba, 0x82, 0xaf, 0x65, 0x35, 0xfc, 0x55, 0xfb, 0x76,
- 0x25, 0xd9, 0xe0, 0xbe, 0x83, 0x4a, 0xdf, 0xb6, 0x70, 0x92, 0x63, 0xba,
- 0x37, 0x2b, 0x76, 0x49, 0x19, 0xcc, 0xd1, 0x8f, 0x19, 0xf5, 0xd0, 0xea,
- 0x35, 0x39, 0xd7, 0xc4, 0xd8, 0xc1, 0xf8, 0x6b, 0xa7, 0xc8, 0xa3, 0x5a,
- 0xbb, 0x5b, 0x55, 0x8f, 0xbc, 0x9f, 0x67, 0x68, 0xaa, 0xf8, 0x58, 0x0a,
- 0x15, 0x69, 0xbf, 0x55, 0x27, 0xf5, 0x97, 0x6c, 0x60, 0x3c, 0x68, 0x5d,
- 0xff, 0xb2, 0xf0, 0xfb, 0x39, 0x11, 0x6d, 0x0a, 0x1b, 0xb0, 0xce, 0xd6,
- 0x19, 0x03, 0xd7, 0x38, 0xbd, 0x9c, 0x87, 0x51, 0x7b, 0x03, 0xee, 0xb2,
- 0x5b, 0xa7, 0x1e, 0xa7, 0x6d, 0xe1, 0xce, 0x0d, 0xe8, 0xe4, 0xb3, 0x91,
- 0x4c, 0xf3, 0x74, 0x2f, 0x75, 0x7d, 0x7c, 0x76, 0xcc, 0x5d, 0xf7, 0x97,
- 0x33, 0xe4, 0xa3, 0xe4, 0xd7, 0x5f, 0xcd, 0xb4, 0x26, 0x87, 0xd4, 0x1e,
- 0x05, 0x73, 0x24, 0x97, 0x4c, 0x90, 0x53, 0x05, 0xf0, 0x99, 0xb4, 0x45,
- 0x1f, 0x00, 0x6d, 0xae, 0x83, 0x79, 0xc5, 0x13, 0x4e, 0xbd, 0x19, 0x35,
- 0x44, 0x3f, 0xeb, 0x0b, 0x4b, 0xf1, 0x14, 0x63, 0x6f, 0xf3, 0xb5, 0x7a,
- 0xf0, 0x39, 0x68, 0xf0, 0x99, 0x3f, 0x75, 0x1a, 0xcc, 0x1a, 0x3c, 0x30,
- 0x12, 0x4d, 0xdc, 0xc4, 0x38, 0xdb, 0x79, 0xad, 0x7e, 0xf4, 0x14, 0x63,
- 0xe0, 0x7c, 0xd3, 0x96, 0xf3, 0x26, 0xe4, 0x3b, 0x01, 0xd7, 0xce, 0x4f,
- 0xdb, 0xe2, 0x27, 0x3a, 0x71, 0x33, 0x84, 0xcf, 0xd1, 0xce, 0xdf, 0xb7,
- 0x63, 0x98, 0x24, 0xdf, 0xf8, 0x2c, 0xfd, 0xe3, 0x8c, 0x1d, 0x49, 0x5d,
- 0xa3, 0xea, 0xd8, 0x40, 0xff, 0x78, 0xd7, 0x4e, 0xd0, 0x77, 0x3e, 0xc6,
- 0xab, 0x8d, 0xfe, 0x10, 0x63, 0x1d, 0x8d, 0x7e, 0x10, 0x72, 0xcf, 0x95,
- 0x8e, 0x65, 0x9a, 0xbb, 0x1f, 0x42, 0x73, 0xec, 0x66, 0xa5, 0x8e, 0x79,
- 0x6a, 0x10, 0xf7, 0x14, 0x6e, 0xc0, 0x89, 0x6c, 0x64, 0x9a, 0x39, 0xf9,
- 0xc6, 0xa5, 0x0a, 0xee, 0x20, 0x67, 0x5b, 0x5f, 0xad, 0xb4, 0x4e, 0x3d,
- 0xa5, 0x44, 0x68, 0x93, 0x8c, 0x97, 0xf4, 0xcf, 0xcf, 0xb2, 0xcc, 0x99,
- 0x6c, 0x35, 0x36, 0x8c, 0xd8, 0xe8, 0xcf, 0x54, 0xa0, 0x6a, 0xa7, 0x1f,
- 0xf7, 0x8f, 0xe9, 0xc8, 0x64, 0x64, 0x1d, 0xd9, 0x6f, 0xd5, 0x12, 0x37,
- 0x46, 0x89, 0x0d, 0x2f, 0x2d, 0x01, 0xa6, 0xf7, 0xae, 0xc1, 0x81, 0x9d,
- 0x3a, 0xe3, 0x5d, 0xd1, 0x3e, 0x82, 0x71, 0x97, 0x93, 0xa7, 0x84, 0x93,
- 0x57, 0x99, 0x12, 0xfb, 0xa2, 0x3d, 0x8f, 0x50, 0x07, 0xb7, 0x15, 0xc4,
- 0xee, 0x12, 0x9c, 0xa3, 0x30, 0x06, 0x69, 0x23, 0xfb, 0xec, 0x26, 0xe6,
- 0xe6, 0x01, 0x58, 0xb4, 0x11, 0x4b, 0xde, 0x53, 0xa5, 0x8d, 0x58, 0xb4,
- 0x11, 0x8b, 0x36, 0x62, 0xd1, 0x46, 0xac, 0xfc, 0x52, 0xe6, 0x4c, 0x3a,
- 0xc6, 0xd9, 0xe6, 0xb6, 0x51, 0x72, 0xf7, 0xa0, 0xd8, 0x4a, 0x0c, 0x5f,
- 0xcf, 0xf4, 0x2b, 0xda, 0x9d, 0x37, 0x60, 0x24, 0x7b, 0x23, 0x2f, 0x05,
- 0xb7, 0xd2, 0x56, 0x1e, 0xcd, 0x89, 0xed, 0xe9, 0xee, 0xef, 0xd3, 0x3c,
- 0x9b, 0xdf, 0x33, 0x1b, 0xd5, 0xe2, 0x03, 0x8c, 0x45, 0xee, 0x7d, 0x39,
- 0x73, 0xec, 0xc7, 0x68, 0xfe, 0x82, 0x5f, 0x7c, 0x4f, 0xce, 0xab, 0xb4,
- 0xcb, 0x6f, 0xc5, 0x74, 0x30, 0x0f, 0x90, 0x73, 0xee, 0x32, 0x4e, 0x19,
- 0x57, 0x71, 0x4c, 0x55, 0x83, 0x9b, 0xf0, 0xf5, 0x41, 0x9d, 0xb1, 0xca,
- 0xc0, 0x93, 0x39, 0x89, 0xe5, 0xe2, 0xdf, 0x32, 0x0f, 0xe2, 0xeb, 0x1e,
- 0xd4, 0xb4, 0x7b, 0x11, 0x70, 0xfd, 0xbc, 0x39, 0xbc, 0x43, 0xb1, 0xe9,
- 0x3b, 0xba, 0x9c, 0x03, 0x9d, 0x0a, 0xeb, 0x0d, 0x38, 0xbd, 0xbb, 0x1d,
- 0xff, 0x6d, 0xa7, 0x87, 0x3c, 0xc0, 0x59, 0xfa, 0x52, 0x5c, 0x4f, 0x4e,
- 0x2b, 0xd1, 0xd8, 0x2c, 0xa5, 0x1d, 0xf7, 0x90, 0xfb, 0x6f, 0x18, 0x8c,
- 0x74, 0x33, 0x66, 0x1b, 0xb7, 0x28, 0x4b, 0x51, 0xc5, 0x1c, 0xa0, 0x8d,
- 0x39, 0xc0, 0x83, 0xc4, 0x80, 0xaf, 0x66, 0xbc, 0x68, 0x59, 0x2c, 0xbf,
- 0x4d, 0xa6, 0xbb, 0x6b, 0x3b, 0x2f, 0x90, 0xa3, 0xce, 0x37, 0x3b, 0xe4,
- 0x2c, 0x8e, 0x72, 0xf6, 0xba, 0x29, 0x24, 0x28, 0x7f, 0xcc, 0xcd, 0x2f,
- 0x12, 0x38, 0x98, 0x27, 0x6e, 0x70, 0xdc, 0xaf, 0xb4, 0xfd, 0x84, 0xf9,
- 0xb0, 0x70, 0x7b, 0x13, 0x13, 0x39, 0x97, 0xff, 0x47, 0xea, 0x88, 0x19,
- 0xd9, 0x41, 0xbd, 0xcb, 0xaf, 0x9a, 0x78, 0x64, 0xaf, 0xf8, 0xb0, 0x89,
- 0xf6, 0x21, 0x3d, 0x7c, 0x9b, 0x1a, 0x0d, 0xae, 0xe3, 0xb3, 0x05, 0x9c,
- 0xcf, 0xc7, 0x33, 0x32, 0x8f, 0x1a, 0x5a, 0x18, 0x9b, 0xdf, 0x9c, 0xd0,
- 0xb1, 0x88, 0x71, 0xfa, 0x9d, 0x89, 0x18, 0x96, 0x32, 0x66, 0x3b, 0xcc,
- 0x1f, 0x12, 0x19, 0xf1, 0x45, 0xf2, 0x81, 0x09, 0x8d, 0x71, 0x56, 0xd6,
- 0x87, 0x9e, 0xc0, 0xd8, 0x6a, 0x0d, 0xfb, 0xdc, 0xf3, 0x7c, 0x7e, 0xab,
- 0x81, 0x58, 0xd9, 0x39, 0xe0, 0xc7, 0xa7, 0x87, 0x36, 0xe3, 0xf5, 0xc5,
- 0xc2, 0x95, 0xd6, 0x38, 0xa2, 0x9f, 0xc7, 0x29, 0x73, 0x8c, 0xbc, 0x78,
- 0x94, 0x79, 0xd7, 0xc2, 0x7d, 0x6b, 0xf0, 0xc9, 0x5d, 0x17, 0xf2, 0xb4,
- 0x33, 0x71, 0xeb, 0x6e, 0xda, 0xc4, 0xfa, 0x00, 0x6d, 0xa2, 0x96, 0x36,
- 0x61, 0x67, 0xa2, 0xc9, 0x02, 0x6d, 0x22, 0x46, 0xdc, 0xc8, 0x0e, 0x48,
- 0x39, 0xf7, 0x9d, 0x99, 0xbb, 0xe4, 0xdd, 0x65, 0x83, 0xbe, 0xb3, 0x75,
- 0xc0, 0xd9, 0xec, 0x65, 0xbc, 0x79, 0xa4, 0xa3, 0x89, 0xd8, 0x72, 0x23,
- 0xf6, 0x0c, 0x36, 0xa1, 0x85, 0x31, 0x63, 0x61, 0x1a, 0x77, 0x84, 0xa1,
- 0xce, 0x0f, 0x23, 0xb2, 0xe1, 0x1d, 0x44, 0xa7, 0xef, 0x56, 0x5a, 0x8f,
- 0xbe, 0xa8, 0x44, 0x36, 0xfe, 0x84, 0x36, 0x7c, 0x56, 0x91, 0xb6, 0x9b,
- 0x70, 0x35, 0xfd, 0xe4, 0x2a, 0xfa, 0x84, 0xc6, 0x5c, 0x52, 0x63, 0xdd,
- 0xfe, 0x41, 0x1f, 0xe6, 0x33, 0xd7, 0x93, 0xb3, 0xca, 0xb1, 0x31, 0x2f,
- 0xb2, 0x3b, 0xf5, 0xa9, 0x47, 0xd0, 0x08, 0x63, 0xec, 0x46, 0x6c, 0x1d,
- 0xd4, 0x10, 0xe5, 0xbd, 0xbe, 0x9d, 0x0b, 0xd0, 0x4c, 0xfb, 0xd6, 0xe8,
- 0xa7, 0xbd, 0x83, 0x2a, 0x16, 0x8c, 0xdd, 0x80, 0x1d, 0x83, 0x0a, 0xee,
- 0x8b, 0x2a, 0x68, 0x19, 0x91, 0x1c, 0x2c, 0x86, 0xa7, 0x32, 0xc2, 0x15,
- 0xa1, 0xb4, 0x5c, 0x4b, 0x8e, 0x4c, 0xee, 0xf9, 0x93, 0x9c, 0xcc, 0xb9,
- 0xe8, 0x53, 0x7e, 0x53, 0xa6, 0x1d, 0x9f, 0xdb, 0xd9, 0x80, 0xab, 0x76,
- 0xeb, 0xd6, 0x69, 0xc5, 0x59, 0x7a, 0x80, 0x7c, 0xde, 0xaf, 0x16, 0xe7,
- 0xfc, 0xc1, 0xc1, 0x67, 0x19, 0x2f, 0x7e, 0xe2, 0x04, 0xf5, 0xa5, 0xe8,
- 0x8b, 0x27, 0xb1, 0xb6, 0xa3, 0x1d, 0x6b, 0xf7, 0x8a, 0xbe, 0x1c, 0xe6,
- 0x87, 0xcc, 0xfd, 0x26, 0xa7, 0xf0, 0x0e, 0xfd, 0x77, 0x11, 0x39, 0xed,
- 0x52, 0xc6, 0x89, 0x37, 0x16, 0x9b, 0xd4, 0x9f, 0xee, 0x9e, 0xf5, 0x9b,
- 0x67, 0x9a, 0xa8, 0x1d, 0xd4, 0x19, 0x67, 0x4c, 0xcc, 0xda, 0x2b, 0xed,
- 0x99, 0xb8, 0x67, 0x50, 0x4f, 0x3d, 0xcd, 0xb9, 0x14, 0xbb, 0x11, 0xcc,
- 0xae, 0x61, 0xec, 0x3f, 0x39, 0x29, 0x38, 0xd5, 0x89, 0x13, 0xcc, 0x03,
- 0xde, 0x7c, 0x2c, 0xda, 0xfd, 0x33, 0xe6, 0x74, 0xef, 0x50, 0x46, 0x96,
- 0xfd, 0x1b, 0xe0, 0xbc, 0x56, 0xa4, 0xf5, 0x8d, 0xff, 0x8c, 0x28, 0xfd,
- 0xbb, 0x0b, 0xb5, 0xd4, 0xc9, 0x81, 0xc1, 0x95, 0xf0, 0xd3, 0x16, 0x1e,
- 0xc9, 0x88, 0xdd, 0x10, 0xbf, 0x77, 0x7e, 0x02, 0x5b, 0xf7, 0x17, 0xf3,
- 0xbc, 0x7b, 0x06, 0x36, 0xd1, 0xc6, 0x85, 0xb3, 0xc7, 0x68, 0xef, 0x98,
- 0xe7, 0x43, 0xb2, 0x9e, 0x18, 0x91, 0x58, 0x4e, 0xcc, 0x7c, 0xd4, 0x20,
- 0xae, 0xd6, 0x47, 0xc2, 0x2d, 0xaa, 0x95, 0x60, 0x5e, 0x17, 0xbe, 0x0f,
- 0xd2, 0xbe, 0x85, 0x75, 0x4b, 0x36, 0x61, 0x4f, 0xd6, 0x8b, 0xaa, 0xc5,
- 0x1e, 0xe2, 0xb1, 0x60, 0x94, 0x15, 0x94, 0xe7, 0x6b, 0x21, 0x7e, 0x22,
- 0xf3, 0xeb, 0xc1, 0x99, 0x78, 0xf3, 0x86, 0xac, 0xfc, 0x96, 0x05, 0x73,
- 0xbe, 0xcf, 0xa2, 0x83, 0x73, 0x2f, 0xfe, 0x98, 0xc0, 0x3d, 0x63, 0xc2,
- 0xd5, 0xc8, 0xe7, 0x6c, 0x3f, 0xfe, 0x3a, 0x2b, 0x9c, 0x6e, 0x33, 0xee,
- 0x69, 0x2f, 0xe7, 0x6e, 0x62, 0x77, 0xad, 0xd3, 0x1e, 0x34, 0x93, 0x93,
- 0xe9, 0xb9, 0xac, 0x1a, 0xb1, 0x52, 0x88, 0xf4, 0xa7, 0x20, 0x71, 0xa2,
- 0xd5, 0xe2, 0x0c, 0x53, 0x36, 0xb9, 0xa5, 0xed, 0x41, 0x1d, 0x7d, 0x5c,
- 0x7e, 0x44, 0xae, 0x9d, 0xf6, 0xf3, 0xac, 0x5d, 0x0d, 0xcd, 0xb5, 0x75,
- 0x2f, 0x96, 0x16, 0x2c, 0xe2, 0xed, 0x52, 0xb4, 0x3d, 0x16, 0xc0, 0x35,
- 0xe4, 0x26, 0x57, 0xa7, 0x9f, 0x70, 0x66, 0x11, 0x7b, 0xdb, 0x46, 0xa2,
- 0xc1, 0x23, 0xe4, 0x81, 0x07, 0x96, 0xfc, 0xd4, 0xf1, 0x98, 0xae, 0x5f,
- 0x68, 0xf4, 0x00, 0xe7, 0x33, 0x1d, 0xfa, 0xd4, 0x0e, 0x04, 0x90, 0x20,
- 0x7e, 0x5e, 0x99, 0x69, 0x40, 0xfb, 0xee, 0x7e, 0xce, 0x7f, 0x10, 0x57,
- 0xf2, 0xfb, 0x62, 0xc6, 0x37, 0x8d, 0xd8, 0xaa, 0xc9, 0xe7, 0x82, 0xd8,
- 0x4b, 0x98, 0x7e, 0xe4, 0x2c, 0xbd, 0xb3, 0xdd, 0xba, 0x63, 0x36, 0xf5,
- 0xd5, 0x42, 0x5c, 0x5e, 0x9a, 0x89, 0x6c, 0xbc, 0x59, 0x51, 0xb0, 0xb2,
- 0xdd, 0x60, 0xdb, 0x01, 0xc4, 0x32, 0xb2, 0x36, 0x70, 0xe8, 0xa1, 0x3a,
- 0x58, 0xad, 0x01, 0xda, 0xe9, 0x11, 0x45, 0xd6, 0x35, 0x44, 0x6f, 0x4d,
- 0xb8, 0x8a, 0x7c, 0x44, 0x23, 0x66, 0xc7, 0x0a, 0xa2, 0x43, 0x60, 0x6d,
- 0x6e, 0x0d, 0xf6, 0x0c, 0x8b, 0x7f, 0x0a, 0x76, 0x3a, 0x4e, 0xe5, 0xe2,
- 0xa8, 0xf1, 0x36, 0x75, 0xf8, 0xc6, 0x84, 0x60, 0x90, 0x82, 0x79, 0xb4,
- 0x63, 0x55, 0x97, 0x58, 0x2b, 0xb8, 0x15, 0xa6, 0xdf, 0x76, 0xe0, 0xd3,
- 0x8c, 0x6d, 0xd5, 0x9c, 0x83, 0x55, 0x4b, 0x9a, 0xe8, 0xbf, 0xc4, 0xc9,
- 0x89, 0x20, 0xaf, 0x10, 0x8e, 0xef, 0x6f, 0xe4, 0xa5, 0xf1, 0x5a, 0xc0,
- 0x4b, 0xe7, 0x3d, 0x15, 0x67, 0xf6, 0x93, 0x33, 0xed, 0x15, 0x0e, 0x22,
- 0x3e, 0xe8, 0xc7, 0xd3, 0x13, 0x20, 0x8f, 0x31, 0xc8, 0x43, 0x04, 0xff,
- 0x64, 0x9e, 0x98, 0xc7, 0x0c, 0xc6, 0x11, 0x1d, 0x29, 0x72, 0x8e, 0x93,
- 0xc3, 0x7a, 0xcf, 0x5a, 0x44, 0xb5, 0xbf, 0x26, 0x7e, 0x9d, 0x1a, 0x6d,
- 0xc7, 0x74, 0x96, 0xb8, 0xb5, 0xb8, 0x1d, 0x6f, 0xe7, 0x36, 0xd1, 0xff,
- 0x55, 0x9c, 0x25, 0x66, 0x69, 0x73, 0x05, 0xd7, 0x05, 0x43, 0xfd, 0xb4,
- 0xd7, 0x0e, 0x59, 0x03, 0x55, 0xe2, 0xc4, 0xac, 0x6b, 0xd2, 0xcf, 0x3a,
- 0xb5, 0x3a, 0x73, 0x2a, 0x35, 0x81, 0x0c, 0x31, 0xcb, 0xce, 0xca, 0x7c,
- 0x6d, 0xc6, 0x56, 0xe2, 0xd5, 0xd6, 0x9c, 0xd8, 0x37, 0x6d, 0x7a, 0x50,
- 0x0f, 0x16, 0x68, 0xdb, 0xea, 0x5e, 0x91, 0x61, 0xa2, 0x8f, 0xb1, 0xfd,
- 0x33, 0x1d, 0x26, 0x76, 0xe4, 0x24, 0x0e, 0x0a, 0x07, 0xd3, 0x98, 0x97,
- 0x24, 0xd1, 0x43, 0x9c, 0x7a, 0xdb, 0xee, 0xc4, 0x0a, 0xe2, 0xd4, 0x2f,
- 0x98, 0xa7, 0xdc, 0x49, 0x9c, 0x7a, 0xc3, 0x2e, 0xe2, 0xd4, 0xcd, 0x13,
- 0x62, 0x0b, 0x45, 0x5e, 0x7e, 0xc2, 0x6e, 0x6b, 0x90, 0xdf, 0x39, 0xab,
- 0x36, 0x7f, 0x57, 0x5c, 0x58, 0x85, 0x97, 0x86, 0xcb, 0x7b, 0xc5, 0x91,
- 0xe4, 0xed, 0xe4, 0xcc, 0x47, 0x47, 0xcb, 0x9c, 0xf7, 0xb8, 0x9b, 0x5b,
- 0xcf, 0x32, 0xcb, 0xfb, 0x96, 0xe5, 0xfd, 0x06, 0x0b, 0x5f, 0x5d, 0x22,
- 0x3c, 0x53, 0xd6, 0x81, 0x2a, 0xc8, 0x27, 0xbb, 0x31, 0xbe, 0xf3, 0x3d,
- 0x3c, 0x32, 0xa8, 0xde, 0x5c, 0xc3, 0xd8, 0x7a, 0x8b, 0xb2, 0x19, 0x9e,
- 0xb8, 0xbc, 0x47, 0x2a, 0x6b, 0xe5, 0xcc, 0x5d, 0x26, 0xb3, 0xe8, 0xdb,
- 0x57, 0x83, 0x43, 0x41, 0xc7, 0x79, 0xda, 0x98, 0x27, 0x3f, 0x13, 0x20,
- 0xb8, 0x19, 0xa8, 0xa0, 0x2f, 0xdc, 0xfc, 0x5b, 0xbf, 0xdd, 0x58, 0xde,
- 0x3b, 0xd8, 0x88, 0xbb, 0x76, 0x3d, 0x8c, 0x9e, 0x5d, 0x7f, 0x8b, 0x4f,
- 0x0e, 0x2d, 0xec, 0x9f, 0xe7, 0x71, 0x9c, 0xab, 0xdb, 0xa7, 0x70, 0x2a,
- 0xce, 0xd8, 0x18, 0x52, 0xf0, 0xbd, 0xab, 0x16, 0x8a, 0x1c, 0xfe, 0xbd,
- 0xef, 0x68, 0xae, 0xbc, 0x5b, 0x4b, 0x3e, 0x92, 0x98, 0xc3, 0xf1, 0x53,
- 0xf6, 0x8a, 0xfa, 0xd2, 0xbb, 0xc2, 0x7f, 0x40, 0x5b, 0x3f, 0x16, 0x19,
- 0xfc, 0x2b, 0xcb, 0x78, 0xcd, 0x49, 0xae, 0x96, 0x7a, 0x15, 0xa5, 0x36,
- 0xfe, 0x96, 0x9c, 0x90, 0xbc, 0xd0, 0xe0, 0xff, 0x91, 0xeb, 0x44, 0x3e,
- 0x9f, 0x95, 0xe5, 0xbf, 0xe4, 0x24, 0xbb, 0xe5, 0xbb, 0x94, 0x59, 0xc7,
- 0x67, 0x52, 0xae, 0xfc, 0xec, 0xf9, 0x92, 0x9c, 0x4a, 0x68, 0x0d, 0x45,
- 0x39, 0x9f, 0xa6, 0x9c, 0x33, 0x8b, 0x93, 0x50, 0xaf, 0x9d, 0x29, 0xab,
- 0xdc, 0xee, 0xff, 0x3a, 0x2f, 0xab, 0x58, 0xee, 0x6f, 0xe6, 0xc8, 0xbe,
- 0x80, 0x7a, 0xed, 0xcc, 0x75, 0xf2, 0x0a, 0xfa, 0x6f, 0x34, 0xb8, 0xd5,
- 0x5d, 0x9f, 0x36, 0xb0, 0xf6, 0xe2, 0x1c, 0x4b, 0xb0, 0x03, 0xe3, 0x76,
- 0xb0, 0x94, 0x53, 0xc9, 0x2d, 0x13, 0x5f, 0x66, 0xce, 0xf6, 0x94, 0x1d,
- 0xe9, 0x5a, 0xa7, 0xb4, 0x26, 0x17, 0x31, 0xce, 0xa0, 0x5e, 0xd6, 0xb0,
- 0x13, 0xee, 0xef, 0xf9, 0xe5, 0xa3, 0x09, 0xe4, 0x69, 0x8f, 0xaf, 0xd8,
- 0x91, 0x0d, 0xa7, 0xdc, 0xfd, 0x3b, 0x13, 0x2f, 0xe7, 0x5f, 0x2d, 0xed,
- 0x33, 0x95, 0x7f, 0x4f, 0x6c, 0xe6, 0x1a, 0xaa, 0xcc, 0xbf, 0x9c, 0xb1,
- 0x6e, 0x90, 0xb5, 0x0a, 0xcb, 0xa2, 0x9f, 0xf7, 0x66, 0xac, 0xb0, 0x8a,
- 0xeb, 0x90, 0x0a, 0xc9, 0xbe, 0xc4, 0xd6, 0xd2, 0x6f, 0x52, 0xb1, 0xde,
- 0xef, 0x58, 0x13, 0x02, 0x8c, 0xd2, 0x39, 0xb6, 0x18, 0xac, 0xc9, 0x2b,
- 0xc8, 0xc5, 0x64, 0xbd, 0x01, 0xd6, 0x6c, 0x53, 0x43, 0x48, 0x3f, 0xcc,
- 0x71, 0xfb, 0x30, 0x87, 0xf9, 0x54, 0x7c, 0x61, 0x6b, 0x77, 0xbb, 0x3a,
- 0x57, 0x70, 0x36, 0x98, 0x54, 0x63, 0x12, 0x07, 0x50, 0x99, 0x96, 0xb3,
- 0x26, 0x56, 0x97, 0x9f, 0x98, 0xba, 0x98, 0xd8, 0x52, 0x11, 0x85, 0xf7,
- 0xbe, 0xbc, 0x17, 0xc1, 0x85, 0xbf, 0x70, 0x7e, 0x18, 0x8a, 0x61, 0xdb,
- 0x64, 0xb9, 0x0f, 0x06, 0xfe, 0x7b, 0xe1, 0xd2, 0x8c, 0xb3, 0x2c, 0xf3,
- 0x3d, 0x27, 0x39, 0x47, 0xda, 0x2e, 0xca, 0xfd, 0xe8, 0xbe, 0x4a, 0x1f,
- 0xa5, 0xaf, 0xcd, 0x1a, 0x51, 0x15, 0x5b, 0x8d, 0x89, 0x39, 0xf2, 0x9b,
- 0x3f, 0xf7, 0xb8, 0x67, 0xd3, 0x65, 0x0e, 0xe4, 0xfd, 0xf1, 0x04, 0xee,
- 0x93, 0xf7, 0x30, 0x19, 0xb3, 0xee, 0xcd, 0xbb, 0xef, 0x77, 0x42, 0x7e,
- 0x17, 0xf1, 0xde, 0x7c, 0x51, 0x7f, 0x0f, 0xe5, 0x03, 0xe4, 0xdd, 0x01,
- 0xcb, 0x6b, 0x6e, 0x80, 0x4f, 0x97, 0x33, 0x67, 0x65, 0x5d, 0xfe, 0xdf,
- 0x73, 0x24, 0x97, 0xff, 0x2a, 0xfd, 0xc9, 0xbb, 0x50, 0x3e, 0x5b, 0xf2,
- 0xae, 0xa2, 0x52, 0xfc, 0x7c, 0xc6, 0x7d, 0xef, 0x5d, 0x35, 0xd7, 0xd1,
- 0x2f, 0x67, 0xbb, 0xef, 0xeb, 0x89, 0x7e, 0x42, 0xa6, 0xe5, 0xcc, 0xd6,
- 0x03, 0xb4, 0x91, 0xde, 0x39, 0xa5, 0x77, 0x0f, 0xba, 0xee, 0x20, 0x8e,
- 0x2c, 0x22, 0xb7, 0x5a, 0xac, 0x44, 0xb4, 0x55, 0x4a, 0x37, 0xeb, 0x51,
- 0x4f, 0x05, 0x91, 0xa1, 0xb8, 0xbf, 0xbd, 0xeb, 0xa3, 0x8c, 0xfd, 0x76,
- 0xab, 0xe6, 0x53, 0x7f, 0x5e, 0x3a, 0x7b, 0x2d, 0x7b, 0xf1, 0x29, 0x3c,
- 0x6f, 0xcf, 0xc1, 0xd4, 0x6f, 0xc9, 0x3d, 0xbf, 0x66, 0xfd, 0x4f, 0x41,
- 0x62, 0x88, 0x4f, 0x8f, 0x6c, 0x8c, 0x7b, 0x22, 0xeb, 0xa7, 0xe9, 0xd3,
- 0x85, 0xb8, 0x9e, 0xfa, 0x1a, 0xdb, 0xf8, 0x3e, 0xb9, 0x85, 0x3d, 0x43,
- 0x7e, 0x51, 0x56, 0x6b, 0x4f, 0x85, 0x7a, 0xc6, 0x29, 0xbe, 0x77, 0x2d,
- 0xbf, 0xfb, 0xbb, 0x06, 0xc1, 0xb4, 0xe5, 0x84, 0x28, 0x73, 0xbe, 0x19,
- 0xd9, 0x53, 0xaf, 0xea, 0xd9, 0xcf, 0xab, 0x9b, 0xb1, 0x56, 0x8e, 0x7c,
- 0x98, 0x11, 0xed, 0xd3, 0xb4, 0x8f, 0x76, 0x57, 0x46, 0x32, 0x56, 0x81,
- 0x8f, 0x3a, 0xd3, 0xc6, 0xf1, 0x41, 0xd6, 0x28, 0x59, 0xce, 0xdd, 0xe3,
- 0x97, 0xf7, 0x77, 0x98, 0x63, 0xdb, 0xf2, 0xbb, 0xa6, 0x6e, 0x33, 0xa5,
- 0x7d, 0x24, 0xe6, 0xc8, 0x8c, 0x97, 0xf7, 0xc8, 0x6f, 0xc8, 0x55, 0x07,
- 0x70, 0xaf, 0x2d, 0xeb, 0x0e, 0xff, 0x3f, 0x45, 0x18, 0xff, 0x64, 0x3c,
- 0x59, 0x00, 0x00, 0x00 };
+ 0xa5, 0xbc, 0x0d, 0x74, 0x1c, 0xe5, 0x95, 0x26, 0xfc, 0x54, 0x75, 0xb7,
+ 0xd4, 0x92, 0x5a, 0x52, 0x49, 0x6e, 0x8b, 0x36, 0x68, 0x70, 0xb5, 0x55,
+ 0x2d, 0x0b, 0x4b, 0x40, 0xb5, 0x24, 0x3b, 0xed, 0x6c, 0x83, 0x3b, 0xb6,
+ 0x6c, 0x64, 0x63, 0x40, 0x36, 0x06, 0xc4, 0xb7, 0xfe, 0x3e, 0x7a, 0xfc,
+ 0x03, 0x86, 0x38, 0x19, 0x91, 0xcd, 0xce, 0x0a, 0xd6, 0x59, 0x55, 0xe4,
+ 0x3f, 0xd9, 0x6e, 0x75, 0x4b, 0x42, 0xfe, 0xe1, 0xec, 0x9c, 0xa5, 0x2d,
+ 0xcb, 0x96, 0x21, 0xad, 0x16, 0x24, 0x6c, 0xc6, 0x39, 0x27, 0x09, 0x1a,
+ 0x63, 0x83, 0x0d, 0x18, 0xc8, 0x24, 0xf9, 0x86, 0xc9, 0xd9, 0x5d, 0x34,
+ 0xc6, 0xfc, 0x19, 0x70, 0x1c, 0x92, 0xc9, 0x9a, 0x19, 0x4c, 0xed, 0x73,
+ 0xab, 0xd5, 0xb6, 0xec, 0x30, 0xc9, 0xcc, 0x59, 0x9d, 0xd3, 0xa7, 0xab,
+ 0xab, 0xde, 0x9f, 0xfb, 0xde, 0xf7, 0xde, 0xe7, 0x3e, 0xf7, 0x7d, 0xdf,
+ 0x92, 0x0e, 0x14, 0x63, 0xf2, 0xaf, 0x94, 0x9f, 0x9b, 0x9a, 0x3b, 0xd6,
+ 0xce, 0x0d, 0xdf, 0x34, 0x4f, 0x7e, 0xbb, 0xcb, 0x0b, 0xdc, 0xf8, 0xb2,
+ 0xbf, 0x28, 0x22, 0x57, 0xdf, 0xd2, 0xbf, 0xb4, 0xe0, 0xbf, 0xf0, 0x17,
+ 0x41, 0x50, 0xe1, 0x57, 0xfd, 0xe4, 0x4f, 0x17, 0xa0, 0xe5, 0xfb, 0x97,
+ 0x0f, 0xbc, 0x6a, 0xd4, 0xb8, 0x77, 0xa1, 0x01, 0xaf, 0x2b, 0xba, 0xaa,
+ 0x7d, 0xad, 0x01, 0xc4, 0x32, 0xf5, 0xfa, 0x22, 0x5c, 0xb4, 0x2d, 0xbf,
+ 0x1b, 0x72, 0xff, 0xcf, 0xa2, 0x9f, 0x3f, 0xf5, 0x93, 0xaf, 0x04, 0xcf,
+ 0xa7, 0x5d, 0xf0, 0x6a, 0x51, 0x0b, 0x5a, 0x2d, 0xbc, 0xd5, 0xac, 0xf3,
+ 0x57, 0xb3, 0xb7, 0xa9, 0x28, 0xcb, 0xb7, 0x15, 0x0c, 0xa4, 0x11, 0xd4,
+ 0x2c, 0x04, 0xeb, 0x2c, 0x20, 0xee, 0x8e, 0x22, 0x5e, 0x18, 0xf5, 0xa2,
+ 0xc0, 0x28, 0x40, 0x5c, 0xeb, 0xd4, 0xb7, 0x34, 0x03, 0x0b, 0x13, 0x5e,
+ 0xfd, 0x74, 0x06, 0x58, 0x9b, 0xf0, 0x62, 0xc2, 0xe5, 0xd3, 0xdf, 0xc9,
+ 0x44, 0xca, 0x72, 0xfa, 0x88, 0xc1, 0x65, 0x20, 0xae, 0x46, 0xe5, 0x3e,
+ 0xf4, 0x45, 0x19, 0xa9, 0x0b, 0x6c, 0x4b, 0x7d, 0x5b, 0x7f, 0x37, 0x11,
+ 0xd4, 0xb6, 0xa1, 0x3e, 0x30, 0x84, 0x42, 0xc4, 0xfd, 0xc1, 0x3a, 0xe0,
+ 0xf3, 0x8b, 0x3b, 0x53, 0x0a, 0x3c, 0xc6, 0x34, 0xb4, 0xec, 0x07, 0x76,
+ 0xa4, 0x82, 0x31, 0x83, 0xc3, 0xeb, 0x19, 0x93, 0xba, 0x41, 0x2d, 0xcd,
+ 0xe7, 0x5b, 0x52, 0xc0, 0xd6, 0xd4, 0x34, 0x6c, 0xeb, 0xb3, 0xf1, 0xa2,
+ 0x59, 0xa3, 0x1d, 0x60, 0x0f, 0xdd, 0xce, 0xf3, 0x69, 0xb0, 0xd2, 0xf2,
+ 0xfc, 0x03, 0xfb, 0x27, 0xb3, 0x35, 0x3c, 0x3b, 0xe6, 0xc7, 0x0b, 0x63,
+ 0x15, 0xd8, 0xd1, 0x57, 0x81, 0xed, 0x7d, 0x75, 0x50, 0x0d, 0x1b, 0x75,
+ 0xe1, 0x3a, 0x14, 0xcc, 0xb7, 0xf1, 0x8e, 0xd9, 0x80, 0xad, 0x6c, 0xf8,
+ 0xcd, 0x86, 0x2a, 0xac, 0xd1, 0xaa, 0xb1, 0xc5, 0xf8, 0x0a, 0x72, 0x63,
+ 0xfd, 0xfc, 0x62, 0x2a, 0x85, 0xb8, 0x27, 0xea, 0x56, 0x55, 0xe3, 0x56,
+ 0x9c, 0xdb, 0x1d, 0xc5, 0x27, 0xbb, 0xb1, 0xba, 0x0c, 0xb6, 0x9d, 0x09,
+ 0x87, 0xda, 0x36, 0x2a, 0x9a, 0xfe, 0x4c, 0x86, 0x02, 0xad, 0x74, 0xb3,
+ 0x3d, 0xe8, 0x43, 0x99, 0xa9, 0x53, 0xc1, 0xfe, 0x52, 0xec, 0x37, 0x25,
+ 0xb2, 0x04, 0xf0, 0x93, 0xd9, 0x7f, 0x41, 0x7b, 0xc8, 0x8d, 0x69, 0x6b,
+ 0xea, 0x2d, 0xca, 0xa4, 0x53, 0x9e, 0x6a, 0xfc, 0x60, 0x2c, 0x80, 0xef,
+ 0x53, 0xb6, 0xe7, 0xc6, 0x44, 0xc6, 0xe0, 0x3e, 0x0b, 0x15, 0x18, 0xee,
+ 0xab, 0xc6, 0xb3, 0x46, 0x03, 0x9e, 0xa3, 0x8c, 0x9b, 0xcd, 0x3a, 0xac,
+ 0x89, 0xdc, 0x4f, 0x79, 0x14, 0xac, 0x6c, 0xf8, 0xf3, 0x49, 0xb9, 0x82,
+ 0x3a, 0x54, 0x15, 0xb1, 0xca, 0x60, 0x9d, 0xae, 0x4a, 0x9b, 0x97, 0xe5,
+ 0xed, 0x4d, 0xc1, 0xf2, 0x46, 0x45, 0xe6, 0x5b, 0x91, 0xa1, 0xbc, 0xdf,
+ 0xdb, 0x1d, 0x32, 0x37, 0xa8, 0x58, 0xee, 0xa3, 0xcc, 0x8f, 0x84, 0x43,
+ 0x91, 0x39, 0x94, 0x79, 0x24, 0xa3, 0x72, 0x3c, 0x7e, 0xfd, 0x10, 0x65,
+ 0x8f, 0xad, 0x54, 0x29, 0x3b, 0x65, 0x49, 0x51, 0x96, 0x14, 0x65, 0x49,
+ 0x51, 0x16, 0x47, 0xee, 0x3a, 0xca, 0x9c, 0x9b, 0xa3, 0xa1, 0xcc, 0x04,
+ 0xe5, 0x9d, 0x2a, 0x67, 0x35, 0x65, 0x47, 0xbc, 0x22, 0xfa, 0x6d, 0xbd,
+ 0x26, 0x49, 0x7d, 0xa7, 0x6c, 0xfb, 0x4d, 0xd3, 0xb6, 0x3f, 0x35, 0x7d,
+ 0xd4, 0x5f, 0x8a, 0x76, 0x90, 0x97, 0x67, 0xa6, 0x55, 0x10, 0x45, 0x0b,
+ 0x4d, 0xd0, 0x3e, 0xde, 0x1c, 0x8a, 0x54, 0x2a, 0x2a, 0xdc, 0x86, 0xa6,
+ 0xcf, 0xce, 0x06, 0x4d, 0xea, 0x47, 0x0f, 0x65, 0xa1, 0x1b, 0x59, 0xb6,
+ 0x75, 0x45, 0xbf, 0x41, 0x6d, 0x1c, 0xd2, 0xaf, 0xce, 0xfe, 0x27, 0x26,
+ 0xe7, 0x4e, 0xda, 0x0f, 0xb0, 0x4f, 0xe9, 0x5f, 0xda, 0xb6, 0xed, 0xdf,
+ 0x98, 0x30, 0x34, 0x84, 0xac, 0x7e, 0xda, 0x9f, 0x2b, 0xaa, 0xe9, 0x1d,
+ 0x19, 0x3e, 0xbf, 0xd4, 0x46, 0x6e, 0x3e, 0xd6, 0x64, 0xf4, 0xc9, 0x31,
+ 0x04, 0x29, 0x82, 0xd8, 0x41, 0x20, 0xee, 0x8b, 0x6a, 0x22, 0x7b, 0xdb,
+ 0xbe, 0xde, 0x2e, 0x7b, 0x86, 0x21, 0xba, 0x32, 0x3a, 0x67, 0xb8, 0x7c,
+ 0x91, 0x73, 0x73, 0x1f, 0xb5, 0x4a, 0x9b, 0xc3, 0x28, 0x36, 0xe0, 0x2b,
+ 0x32, 0xd0, 0x96, 0x1c, 0x2d, 0xb6, 0x4a, 0xa2, 0x3f, 0xbe, 0xbb, 0x77,
+ 0xd4, 0x8b, 0xe2, 0x51, 0x03, 0x45, 0xa3, 0x4f, 0xbb, 0x51, 0xd6, 0x80,
+ 0x5d, 0x63, 0x0f, 0xb9, 0x73, 0x63, 0x5b, 0x32, 0x39, 0x46, 0xc7, 0xf6,
+ 0xbd, 0xef, 0x26, 0xce, 0xdb, 0x05, 0x46, 0xd1, 0x7d, 0xae, 0xa8, 0xa1,
+ 0x1f, 0x02, 0xce, 0xaf, 0x69, 0x5e, 0x84, 0x6e, 0x4d, 0xc1, 0x4c, 0xe3,
+ 0x95, 0x12, 0x94, 0x45, 0x60, 0x8d, 0x55, 0xc5, 0x0b, 0xa2, 0xfe, 0x38,
+ 0xe7, 0x06, 0x2f, 0x27, 0xd2, 0xf0, 0xf4, 0xda, 0xb6, 0x94, 0x7d, 0x07,
+ 0x77, 0xdf, 0xad, 0x46, 0x8f, 0xde, 0xec, 0x41, 0x0b, 0xcb, 0x63, 0xd3,
+ 0x89, 0xe6, 0x4f, 0x15, 0x75, 0x77, 0x1b, 0xac, 0x11, 0x17, 0x62, 0x5a,
+ 0x9c, 0xdf, 0xd7, 0x5f, 0xbf, 0x3c, 0xd2, 0x86, 0xc4, 0xc8, 0x05, 0xde,
+ 0x77, 0xf3, 0x5e, 0x04, 0xc9, 0xd4, 0xf5, 0xd7, 0xdf, 0x11, 0x89, 0xa3,
+ 0x77, 0x44, 0xae, 0xdd, 0x18, 0xaf, 0x88, 0x63, 0xfb, 0x5e, 0x1d, 0xe5,
+ 0x46, 0x1b, 0x52, 0x23, 0x72, 0x6d, 0xdb, 0x67, 0xcc, 0xef, 0x62, 0x5f,
+ 0x03, 0xfd, 0xff, 0x9a, 0x36, 0x6c, 0xdb, 0x6b, 0xa1, 0xd0, 0xb0, 0xa8,
+ 0x7b, 0xc5, 0xfd, 0xf7, 0x0d, 0x0a, 0xf4, 0xbb, 0xe1, 0x2e, 0x30, 0x44,
+ 0x6f, 0x11, 0xf7, 0xfa, 0x44, 0x54, 0x9b, 0x69, 0xd8, 0xf6, 0x90, 0x39,
+ 0x07, 0x0f, 0xb4, 0xad, 0x81, 0x75, 0xc0, 0x07, 0x6b, 0x95, 0x7c, 0xb7,
+ 0x51, 0x87, 0x6b, 0xd0, 0x7d, 0x60, 0x0d, 0x7a, 0x9e, 0xa0, 0xe3, 0x56,
+ 0x68, 0xce, 0x3c, 0xfd, 0x64, 0xb6, 0xc8, 0x24, 0xf2, 0xb5, 0xf3, 0x23,
+ 0xba, 0xfd, 0x4b, 0x7e, 0x4b, 0x99, 0x0b, 0x36, 0xa6, 0x5f, 0x2e, 0xb3,
+ 0x9d, 0x65, 0xb6, 0x5d, 0x51, 0x26, 0x82, 0xa7, 0xc6, 0x44, 0x17, 0xa2,
+ 0xb2, 0x3f, 0xa5, 0x8b, 0x9f, 0xda, 0xdd, 0x7e, 0xd1, 0x85, 0xd5, 0xee,
+ 0x41, 0xb0, 0xed, 0x41, 0xc5, 0x8d, 0xa5, 0xbd, 0x60, 0x1d, 0x3a, 0x41,
+ 0x71, 0x30, 0x56, 0xab, 0x44, 0x51, 0xdc, 0xab, 0x60, 0x69, 0xb8, 0x08,
+ 0x7a, 0x85, 0xb4, 0xf7, 0x4b, 0xdb, 0xd2, 0x44, 0xde, 0x13, 0x28, 0xe1,
+ 0xfd, 0x75, 0xe1, 0x9f, 0x13, 0xcf, 0x44, 0xa6, 0x30, 0xcb, 0xaf, 0xe0,
+ 0xfd, 0x37, 0xa6, 0xfc, 0x96, 0x72, 0xb6, 0xbd, 0x99, 0x3e, 0xdf, 0x43,
+ 0x1b, 0xdf, 0x9e, 0x8a, 0x05, 0xa9, 0x25, 0xcb, 0x13, 0xe5, 0xfd, 0x68,
+ 0xa8, 0xb5, 0x1b, 0xd2, 0x0f, 0x94, 0xe2, 0x28, 0xdc, 0x99, 0xe6, 0x09,
+ 0xef, 0xa9, 0x84, 0xd1, 0xfe, 0x8c, 0xe2, 0xa1, 0xb1, 0x4b, 0x3f, 0x13,
+ 0xde, 0x37, 0x12, 0x0a, 0xde, 0x37, 0x42, 0x1d, 0x67, 0x95, 0x09, 0xef,
+ 0xeb, 0x19, 0x0d, 0x33, 0x7a, 0x83, 0xed, 0x96, 0x12, 0xc1, 0x8f, 0x32,
+ 0x7e, 0x04, 0x7a, 0xa3, 0x38, 0x92, 0x31, 0xf1, 0xf4, 0x15, 0x38, 0xf0,
+ 0xa5, 0x7f, 0x96, 0x8b, 0x63, 0x5f, 0x97, 0xd0, 0xd1, 0x6d, 0x5e, 0xb4,
+ 0x63, 0x1a, 0xe2, 0xe5, 0xd1, 0x09, 0xef, 0x27, 0xbd, 0x50, 0xca, 0xa2,
+ 0x46, 0x20, 0xab, 0xfc, 0x83, 0x1d, 0xf7, 0x4b, 0x31, 0xca, 0xe7, 0x60,
+ 0x59, 0x94, 0x76, 0x47, 0x8c, 0x4a, 0x9d, 0xb7, 0x4b, 0x68, 0xb3, 0x05,
+ 0xd1, 0x6b, 0x31, 0x32, 0x68, 0xe0, 0xe9, 0x84, 0x6d, 0x7f, 0x6c, 0x8e,
+ 0x47, 0x7c, 0x30, 0xda, 0x3e, 0x42, 0x30, 0x36, 0x87, 0x7a, 0x39, 0x91,
+ 0x31, 0x30, 0x9c, 0x88, 0xe2, 0xc5, 0x44, 0x8d, 0xb6, 0x19, 0x4d, 0x88,
+ 0x05, 0x72, 0x31, 0x64, 0x94, 0x72, 0x0f, 0x85, 0xda, 0x50, 0x1e, 0x8d,
+ 0xe0, 0x28, 0xe5, 0x3e, 0x37, 0x57, 0xda, 0x31, 0xf1, 0xfa, 0xbf, 0x42,
+ 0x56, 0xe2, 0x3b, 0x9e, 0xa4, 0xac, 0x91, 0xa6, 0x8b, 0x36, 0xa6, 0x79,
+ 0x71, 0xda, 0xbc, 0x86, 0x76, 0x08, 0xab, 0x28, 0xea, 0x75, 0xf7, 0x24,
+ 0x34, 0x1c, 0xce, 0xf8, 0xdc, 0x9b, 0x13, 0x7e, 0x1c, 0xa0, 0xbf, 0xcd,
+ 0x88, 0xc2, 0x0a, 0xb0, 0xdd, 0x19, 0xc4, 0xb5, 0xec, 0x60, 0x35, 0xc6,
+ 0x06, 0x83, 0xe6, 0x1b, 0x4a, 0x00, 0x87, 0x86, 0xaf, 0xc5, 0xe8, 0xa0,
+ 0x82, 0x91, 0x10, 0x65, 0xe7, 0xf5, 0xf7, 0x06, 0xaf, 0x47, 0x66, 0xd0,
+ 0x85, 0x5d, 0x8e, 0x5e, 0x1d, 0x9c, 0x99, 0xfc, 0xbe, 0x16, 0xe9, 0x61,
+ 0xb8, 0xe7, 0xf4, 0x6a, 0x78, 0x26, 0xe3, 0x76, 0x1b, 0xbd, 0x7e, 0x0c,
+ 0x67, 0x7e, 0xca, 0x79, 0x93, 0xb6, 0x75, 0x0c, 0x25, 0x0e, 0x39, 0x73,
+ 0x58, 0x1e, 0x65, 0x63, 0xb9, 0xf8, 0xca, 0x58, 0xa6, 0x33, 0xce, 0x34,
+ 0x13, 0x87, 0xc4, 0xc7, 0xbd, 0xc4, 0x20, 0xf1, 0xf1, 0xb7, 0x14, 0x94,
+ 0x35, 0x63, 0xf3, 0x58, 0xfe, 0xb9, 0x42, 0xfb, 0x77, 0x63, 0x9d, 0xd6,
+ 0x80, 0x44, 0x4a, 0xec, 0x34, 0x8f, 0xcb, 0x72, 0x2d, 0xf3, 0x5f, 0x0c,
+ 0xeb, 0x60, 0x31, 0x76, 0xd1, 0xc7, 0x76, 0xee, 0x96, 0xfb, 0xb6, 0xfd,
+ 0x50, 0xb8, 0x9c, 0x36, 0x86, 0xc5, 0x45, 0x08, 0x99, 0x1f, 0x38, 0xb2,
+ 0x59, 0x38, 0x94, 0x91, 0x18, 0xaa, 0x33, 0xbe, 0x9d, 0x60, 0x5f, 0xcd,
+ 0xec, 0xc7, 0xc4, 0x4f, 0x39, 0x37, 0x7f, 0x3d, 0x56, 0x87, 0x1f, 0x8e,
+ 0x19, 0xf8, 0xef, 0x63, 0x3a, 0x9e, 0xbf, 0x02, 0xd7, 0xef, 0xa6, 0xae,
+ 0x04, 0xc3, 0x1a, 0xb0, 0x25, 0x55, 0x80, 0x6d, 0x83, 0xc5, 0xd8, 0x3c,
+ 0x58, 0x53, 0xf7, 0x22, 0xf1, 0xf8, 0x87, 0xe6, 0x1d, 0x18, 0xaf, 0x6c,
+ 0x76, 0x7c, 0x66, 0x07, 0xef, 0xef, 0x1c, 0xac, 0xe1, 0x1c, 0xda, 0xb6,
+ 0x1a, 0xae, 0x8f, 0x1c, 0x25, 0xbe, 0x4f, 0xf8, 0x83, 0xfa, 0xb8, 0x1a,
+ 0xd4, 0x63, 0xf0, 0x20, 0xd1, 0xa0, 0xc2, 0x9a, 0x1e, 0x4c, 0xd3, 0x8b,
+ 0xe1, 0x37, 0x1e, 0xe2, 0xd8, 0x82, 0xba, 0xa5, 0x36, 0xd0, 0x7e, 0x19,
+ 0x33, 0x54, 0x93, 0xf8, 0x52, 0x8c, 0x4f, 0x06, 0x83, 0x3d, 0x96, 0xba,
+ 0x02, 0x56, 0xa5, 0x6d, 0x7f, 0x3f, 0x8c, 0x8e, 0x6b, 0xa2, 0x88, 0x4d,
+ 0x67, 0x2c, 0xb8, 0x3e, 0x1a, 0x05, 0xe3, 0x18, 0xce, 0xf5, 0x1a, 0x81,
+ 0xbf, 0x53, 0xee, 0xc6, 0x7f, 0x6c, 0x0b, 0xea, 0xba, 0x5a, 0x6f, 0x1d,
+ 0x50, 0x49, 0x36, 0xaa, 0xa0, 0x07, 0xa2, 0xcb, 0xd0, 0xe9, 0xf0, 0x04,
+ 0x05, 0x9a, 0x61, 0x62, 0x73, 0x8a, 0x95, 0xfc, 0x35, 0xed, 0xfd, 0x6a,
+ 0xcd, 0x05, 0x53, 0x0d, 0x9e, 0x68, 0x53, 0x89, 0xb7, 0x4d, 0xe7, 0x6c,
+ 0xbd, 0xca, 0xb6, 0x1b, 0x9b, 0xa4, 0x4f, 0x1d, 0x95, 0x9c, 0xe7, 0x0a,
+ 0xce, 0x73, 0x63, 0xb6, 0x18, 0x67, 0x07, 0x61, 0x5d, 0x13, 0x0d, 0xb6,
+ 0x3e, 0xa2, 0x16, 0xe3, 0xc3, 0xe1, 0x62, 0xbc, 0x33, 0xe8, 0xc6, 0x07,
+ 0x83, 0xb6, 0xbd, 0xde, 0x2c, 0x47, 0x41, 0x18, 0xd3, 0x0b, 0x10, 0x3a,
+ 0x3f, 0x04, 0x0b, 0x5f, 0xb0, 0xec, 0xef, 0x06, 0x03, 0xf8, 0xc7, 0xc1,
+ 0xaf, 0xe2, 0xf9, 0xca, 0xd8, 0xc9, 0x69, 0x8c, 0x91, 0x17, 0x68, 0x3f,
+ 0xe7, 0x12, 0xc1, 0xf6, 0x19, 0xae, 0x60, 0x27, 0x79, 0xcb, 0x86, 0xc7,
+ 0x94, 0x60, 0xfc, 0x0d, 0x25, 0xa8, 0xf7, 0x2a, 0x7e, 0x7c, 0x44, 0x3b,
+ 0x3d, 0x93, 0xa9, 0x89, 0xfc, 0x9c, 0xfd, 0xff, 0xde, 0xfc, 0xa1, 0x3d,
+ 0x5e, 0x25, 0x3a, 0x14, 0x7d, 0x51, 0xe7, 0x29, 0xea, 0x9c, 0xfe, 0xfb,
+ 0xc3, 0x14, 0x75, 0x4e, 0x79, 0x9e, 0xff, 0x83, 0xf8, 0x25, 0xf3, 0x15,
+ 0xe1, 0x3c, 0x5e, 0x87, 0xff, 0xe2, 0x8c, 0xed, 0xa4, 0xfd, 0x9f, 0xfc,
+ 0x32, 0xbe, 0xcf, 0xfd, 0x39, 0x0c, 0x92, 0x71, 0x9e, 0xb0, 0xe3, 0x9a,
+ 0x8c, 0x51, 0xc6, 0xea, 0xe8, 0x52, 0xef, 0x50, 0x1e, 0x55, 0x51, 0x6c,
+ 0xdb, 0x4f, 0x98, 0x93, 0xcf, 0xfd, 0xf9, 0xb1, 0x7e, 0x95, 0xf7, 0x65,
+ 0xbc, 0x67, 0x5d, 0xa2, 0x7b, 0x5d, 0xbd, 0x89, 0xbf, 0x83, 0x56, 0x0c,
+ 0xa7, 0x0b, 0xf9, 0xbb, 0x2e, 0x76, 0xe9, 0xf7, 0x93, 0xa5, 0x57, 0x3e,
+ 0xa7, 0x9d, 0x3a, 0xfd, 0xdd, 0xcd, 0xdf, 0x32, 0x96, 0x37, 0x69, 0x37,
+ 0x5f, 0x66, 0x27, 0x62, 0x23, 0x75, 0xb4, 0xa7, 0x33, 0x12, 0x57, 0x2c,
+ 0x7f, 0xd4, 0x6b, 0xa9, 0x51, 0xe8, 0x74, 0x7d, 0xaf, 0x12, 0xed, 0x80,
+ 0x9e, 0xb1, 0x70, 0x4f, 0xb3, 0x0b, 0xdf, 0x6a, 0x56, 0x30, 0xcd, 0xe8,
+ 0x40, 0xdf, 0x3c, 0xcb, 0xae, 0x30, 0xf6, 0xab, 0xe2, 0x03, 0x05, 0x49,
+ 0x58, 0xf4, 0x3b, 0x44, 0xc8, 0x95, 0xca, 0xff, 0x9d, 0x82, 0xd3, 0xe1,
+ 0x10, 0x6d, 0x6e, 0x0b, 0x39, 0x15, 0x50, 0x98, 0x84, 0xb7, 0x94, 0xf3,
+ 0x3f, 0xda, 0x0b, 0x6f, 0x31, 0x7d, 0x7f, 0x59, 0x6f, 0x4d, 0xc7, 0x7b,
+ 0xc4, 0x8a, 0xac, 0x12, 0x6c, 0xa7, 0xbe, 0xcd, 0x32, 0x25, 0xd8, 0x7a,
+ 0x3b, 0xf5, 0x5d, 0xab, 0x48, 0x3f, 0x51, 0xd4, 0x65, 0xb6, 0x10, 0x73,
+ 0xe4, 0x3a, 0x02, 0x23, 0xf3, 0xab, 0x49, 0xd9, 0xe1, 0xf5, 0x50, 0x86,
+ 0x83, 0x89, 0x77, 0xed, 0xb4, 0x16, 0xd4, 0xd3, 0xce, 0xef, 0x0d, 0xfc,
+ 0x0d, 0x6f, 0x41, 0x74, 0x23, 0x5e, 0x4a, 0x3c, 0xe5, 0xcf, 0x97, 0xcb,
+ 0xc9, 0x7a, 0xb5, 0x3c, 0xff, 0xd3, 0x8e, 0xf9, 0x73, 0xf2, 0xf8, 0x92,
+ 0x5b, 0x40, 0x8e, 0xe2, 0x2d, 0x64, 0x5f, 0xef, 0x3b, 0xf5, 0x23, 0xac,
+ 0x5f, 0xd3, 0xde, 0xab, 0x04, 0xeb, 0x3e, 0x42, 0xbd, 0xfe, 0x3d, 0x04,
+ 0x5b, 0x8f, 0x92, 0x5b, 0x1a, 0x93, 0xf2, 0x84, 0x32, 0x0e, 0x9f, 0x71,
+ 0xe4, 0x99, 0x95, 0x81, 0xe2, 0xea, 0x85, 0x6f, 0xa6, 0x51, 0x8b, 0x2e,
+ 0x67, 0x4e, 0xa1, 0x04, 0x7a, 0x75, 0x94, 0x91, 0xbf, 0x04, 0x46, 0x81,
+ 0xb1, 0x01, 0x72, 0xb9, 0x70, 0x0d, 0xbe, 0xc9, 0x58, 0x30, 0x83, 0x65,
+ 0x1e, 0xd3, 0x2e, 0xe1, 0x97, 0xd2, 0x93, 0x20, 0xc0, 0x4c, 0xcf, 0xf1,
+ 0xb2, 0xf8, 0xbd, 0x88, 0xc9, 0xbd, 0x27, 0x13, 0x50, 0x52, 0x89, 0xe0,
+ 0x3e, 0xc0, 0x18, 0x0f, 0xbb, 0x62, 0x0f, 0x07, 0xd0, 0x85, 0x73, 0xe1,
+ 0x50, 0x3c, 0xab, 0x84, 0xda, 0x07, 0x14, 0xd3, 0xbb, 0x8b, 0xfd, 0x6d,
+ 0x67, 0x99, 0x1d, 0xfc, 0x9c, 0x35, 0x0c, 0x73, 0x85, 0x12, 0xbb, 0xa1,
+ 0x80, 0x65, 0x6a, 0xc2, 0x21, 0xf2, 0xcc, 0xd0, 0x85, 0x95, 0x30, 0xbd,
+ 0x4f, 0x65, 0xa4, 0xad, 0x88, 0xb2, 0x25, 0xfb, 0xa4, 0x9a, 0xc3, 0xa3,
+ 0xdf, 0x4f, 0xea, 0xec, 0x1d, 0xf9, 0xed, 0xf4, 0xed, 0xee, 0xfd, 0xaf,
+ 0x85, 0x7f, 0x78, 0xef, 0xaf, 0xa7, 0x5d, 0x79, 0xaf, 0x5e, 0x1b, 0xa6,
+ 0xff, 0xb9, 0x8c, 0x22, 0xce, 0x9d, 0xf0, 0xa3, 0x58, 0x9d, 0x07, 0x72,
+ 0xcf, 0x85, 0xb4, 0x3b, 0x16, 0x70, 0xe1, 0x73, 0x3b, 0xb6, 0x4a, 0xee,
+ 0x15, 0x23, 0xde, 0x56, 0x1f, 0x70, 0xa3, 0x3e, 0xb2, 0x95, 0x58, 0x30,
+ 0xb1, 0x6a, 0x21, 0x9f, 0x85, 0xcc, 0x17, 0x51, 0xa3, 0x6f, 0x85, 0x5c,
+ 0x7f, 0x46, 0x9b, 0x5d, 0x28, 0x75, 0x59, 0x26, 0xc7, 0x7d, 0x04, 0x6b,
+ 0xb6, 0x98, 0x36, 0x5e, 0x22, 0x4c, 0x14, 0x46, 0x8f, 0x28, 0xa7, 0x13,
+ 0x5f, 0xd8, 0x31, 0x37, 0x96, 0xd3, 0x2f, 0x4d, 0xea, 0x59, 0xf7, 0x46,
+ 0x43, 0xfa, 0x09, 0x66, 0x0a, 0xae, 0xa8, 0xa5, 0x4c, 0x64, 0xb6, 0x28,
+ 0xef, 0x66, 0x7a, 0x94, 0x33, 0x19, 0xa9, 0x7b, 0x44, 0x79, 0x27, 0x23,
+ 0xf1, 0xb0, 0x5a, 0x3f, 0x4e, 0x7e, 0x43, 0x4e, 0xa5, 0x6e, 0x36, 0xa1,
+ 0x6c, 0x33, 0xcb, 0xc8, 0xf3, 0x8d, 0xba, 0x21, 0xca, 0x7b, 0xb0, 0x19,
+ 0xe6, 0x76, 0xd3, 0x83, 0x09, 0x0d, 0xbe, 0xcd, 0xa6, 0x5b, 0x7e, 0x33,
+ 0x1f, 0x90, 0xba, 0xd5, 0xfa, 0xd6, 0xcc, 0x45, 0xfa, 0x57, 0xee, 0xf7,
+ 0xc1, 0xe6, 0xfc, 0xbd, 0xdf, 0xda, 0xe3, 0xab, 0x54, 0xfe, 0xfe, 0x77,
+ 0x2e, 0x0e, 0x85, 0x75, 0xa7, 0xf2, 0x73, 0xe1, 0x52, 0x2a, 0xf9, 0x63,
+ 0x05, 0x2c, 0x2d, 0x68, 0xa5, 0x99, 0x0e, 0x6d, 0x4e, 0x35, 0xd2, 0xdf,
+ 0x02, 0x8c, 0x95, 0x51, 0xe2, 0x3b, 0x79, 0x2f, 0xfb, 0x2c, 0x30, 0x7c,
+ 0x58, 0x9c, 0xa8, 0x71, 0xe5, 0xf4, 0xa7, 0x12, 0xc3, 0x5c, 0x8c, 0xe9,
+ 0xc2, 0xf1, 0xae, 0xe6, 0xdc, 0xd5, 0xfa, 0x07, 0x94, 0xbb, 0xc8, 0x30,
+ 0xea, 0x8a, 0x94, 0x6a, 0xfd, 0xdd, 0x4c, 0x94, 0x3e, 0xde, 0xce, 0x7e,
+ 0x7d, 0x78, 0x37, 0x51, 0xc6, 0x1c, 0x24, 0x18, 0xb3, 0xd8, 0xe0, 0x92,
+ 0xe6, 0x00, 0xc8, 0xf9, 0xa6, 0xfc, 0xb5, 0x81, 0xf1, 0x5f, 0x62, 0xb4,
+ 0x7a, 0xdb, 0xdc, 0x08, 0x36, 0x64, 0xe0, 0x5e, 0xd7, 0x1c, 0xc5, 0x7a,
+ 0xc6, 0xf6, 0x87, 0x18, 0x2f, 0x37, 0x32, 0x16, 0xee, 0x0a, 0x73, 0x6c,
+ 0x15, 0xb6, 0x5d, 0x68, 0x74, 0x49, 0x3e, 0x83, 0x5e, 0xc6, 0xe2, 0xb5,
+ 0x8c, 0x2f, 0x5b, 0x78, 0x7d, 0x2a, 0xf3, 0xcf, 0xf6, 0x43, 0xcc, 0xa7,
+ 0x5e, 0xba, 0xa2, 0x4d, 0xa8, 0xc3, 0x46, 0x7d, 0xdd, 0x56, 0xc6, 0x62,
+ 0xb6, 0x6b, 0x95, 0x45, 0x6d, 0xfb, 0x86, 0x50, 0x30, 0xe6, 0x51, 0x4c,
+ 0xbc, 0x38, 0x3a, 0x61, 0xeb, 0xd3, 0x25, 0x97, 0xca, 0xc7, 0x41, 0x19,
+ 0xab, 0xe4, 0x08, 0x82, 0x0f, 0x92, 0x27, 0x4c, 0xc5, 0x08, 0x15, 0x4b,
+ 0x06, 0x25, 0x4f, 0x08, 0x60, 0x65, 0xe2, 0xbb, 0x78, 0xb1, 0xc1, 0x8d,
+ 0x56, 0xe6, 0x58, 0xb7, 0x25, 0x7c, 0x58, 0x41, 0x2c, 0x5d, 0x9a, 0x60,
+ 0xee, 0xa4, 0xf9, 0xb1, 0x2c, 0xe1, 0xc6, 0xb1, 0x06, 0xe6, 0x40, 0xfe,
+ 0x42, 0x7c, 0x64, 0xba, 0x70, 0xdc, 0xd4, 0x90, 0x76, 0xfc, 0x61, 0x17,
+ 0x31, 0x90, 0x7a, 0x54, 0x25, 0x77, 0x10, 0x1d, 0xba, 0xa8, 0x4f, 0x15,
+ 0xf1, 0x4b, 0x3a, 0xfc, 0xb2, 0x5c, 0x40, 0xe4, 0x92, 0x7c, 0xe0, 0x37,
+ 0x76, 0x7c, 0xba, 0xd4, 0x87, 0xe5, 0x8b, 0xca, 0x38, 0x84, 0xdf, 0x12,
+ 0x27, 0x47, 0x4d, 0x72, 0xbb, 0xa9, 0x43, 0x3d, 0x4f, 0x6e, 0x5d, 0x8e,
+ 0xb7, 0x0c, 0xe1, 0xd6, 0x6f, 0x42, 0xa3, 0xef, 0xf6, 0x8c, 0x86, 0x3a,
+ 0xce, 0x2b, 0x2e, 0x9c, 0x32, 0xca, 0xc8, 0xfb, 0x38, 0x0f, 0xa3, 0x70,
+ 0x6f, 0x9d, 0x6b, 0x22, 0x39, 0xda, 0x1d, 0x29, 0xe5, 0x78, 0xdd, 0x73,
+ 0x73, 0x9c, 0xe8, 0xeb, 0xd4, 0xed, 0x9a, 0xb0, 0xc3, 0x89, 0x72, 0x7c,
+ 0x40, 0xb3, 0xed, 0x77, 0x0c, 0xd1, 0x33, 0x70, 0x78, 0x52, 0xc7, 0x07,
+ 0x79, 0xdd, 0x33, 0xa9, 0xe3, 0x2d, 0x6c, 0x8f, 0xfe, 0x87, 0x6d, 0x57,
+ 0xf0, 0x18, 0x1d, 0xcc, 0x29, 0xc9, 0x6f, 0x88, 0xc3, 0xc4, 0x95, 0x18,
+ 0x75, 0xfc, 0x72, 0x66, 0x83, 0xe0, 0x36, 0xa7, 0xbb, 0xd1, 0xc1, 0xef,
+ 0x98, 0x7a, 0x98, 0x76, 0x20, 0x7a, 0x78, 0x6b, 0x32, 0xb7, 0xb1, 0xed,
+ 0x01, 0x53, 0x74, 0x9c, 0xcf, 0xcb, 0x44, 0xd7, 0x37, 0x4a, 0x8e, 0xd5,
+ 0x03, 0x7c, 0xc1, 0xb2, 0x2e, 0xe2, 0xee, 0x42, 0xfc, 0xa0, 0x4d, 0x6c,
+ 0xa7, 0xd4, 0x89, 0x95, 0xf3, 0x6b, 0x6d, 0x3b, 0xdc, 0xa4, 0xe3, 0x82,
+ 0x51, 0x1f, 0x69, 0x54, 0x67, 0x51, 0xd6, 0x28, 0xf6, 0x91, 0x0f, 0x74,
+ 0xa7, 0x66, 0x22, 0xe6, 0x17, 0x5b, 0x43, 0x47, 0x41, 0x0e, 0xc3, 0x71,
+ 0x26, 0x61, 0xd4, 0x6d, 0xc3, 0x0c, 0x1c, 0xf0, 0xb7, 0x90, 0xc7, 0xa9,
+ 0x2d, 0x4c, 0xff, 0xc9, 0x9f, 0x0c, 0x6b, 0x07, 0xce, 0xda, 0x69, 0xbf,
+ 0xcd, 0x38, 0x49, 0x18, 0xa0, 0x2e, 0x5f, 0xd1, 0x5c, 0x78, 0xb5, 0xee,
+ 0x9a, 0x49, 0xbe, 0x29, 0x9c, 0xe5, 0x3d, 0xfb, 0x98, 0x5f, 0xfa, 0x62,
+ 0x9e, 0xa7, 0x2e, 0x73, 0x49, 0x1e, 0xe8, 0x36, 0xa4, 0x6d, 0xe6, 0x0b,
+ 0x63, 0x57, 0xcb, 0x30, 0x61, 0x4f, 0xf8, 0x45, 0x86, 0xa0, 0xa6, 0xab,
+ 0x7f, 0x6c, 0x1e, 0xaf, 0xc3, 0xcf, 0x35, 0x37, 0x7c, 0xe4, 0xc5, 0xaf,
+ 0xf9, 0x73, 0x6d, 0xf4, 0x9a, 0xe3, 0x33, 0x4a, 0x1d, 0xac, 0x3c, 0xa2,
+ 0x24, 0x89, 0x0f, 0xe3, 0x1e, 0x68, 0xe5, 0x51, 0xb7, 0xae, 0x11, 0x13,
+ 0x36, 0x13, 0x13, 0x2c, 0x62, 0x42, 0x5f, 0xe6, 0x88, 0x92, 0xca, 0x7c,
+ 0x46, 0x5d, 0x48, 0x1d, 0xb1, 0x9d, 0x2d, 0x94, 0xe5, 0x27, 0x36, 0xaa,
+ 0x44, 0x9e, 0x0b, 0xbc, 0xdf, 0x42, 0x1e, 0x92, 0x97, 0x53, 0x7c, 0x95,
+ 0x10, 0x54, 0x2c, 0xcf, 0x52, 0xb9, 0xdf, 0xaa, 0x5c, 0xcf, 0x70, 0x4b,
+ 0xb9, 0xee, 0xb1, 0xa3, 0x4b, 0xdd, 0x58, 0x80, 0xd9, 0xe1, 0x85, 0x8b,
+ 0x44, 0x17, 0x6a, 0x34, 0xa6, 0x7b, 0x61, 0x55, 0xb9, 0x88, 0xe5, 0xef,
+ 0x35, 0x34, 0x60, 0x11, 0x73, 0xce, 0xb3, 0x04, 0xa7, 0x6e, 0xc3, 0x85,
+ 0x71, 0xea, 0xe7, 0x69, 0x53, 0xd6, 0x1b, 0x6c, 0xdc, 0x16, 0xb6, 0xe2,
+ 0xf4, 0x78, 0xab, 0x94, 0xb6, 0x57, 0x6c, 0x08, 0x4f, 0x28, 0x43, 0x49,
+ 0xd4, 0x5d, 0x77, 0x16, 0x41, 0x73, 0x17, 0x79, 0x92, 0x5e, 0x31, 0x3b,
+ 0xe2, 0xa1, 0xe6, 0x5e, 0x4f, 0x84, 0x22, 0xc7, 0x95, 0x9c, 0x3f, 0xbd,
+ 0x4c, 0xdb, 0x78, 0x2b, 0x61, 0x74, 0x16, 0xba, 0x72, 0xbf, 0xdf, 0x70,
+ 0xf2, 0xd9, 0xbc, 0x3f, 0x05, 0x26, 0x71, 0xc7, 0xeb, 0x3d, 0x93, 0xc0,
+ 0x79, 0xb5, 0x59, 0xf2, 0x5a, 0x9c, 0xdf, 0x6c, 0x8e, 0x2b, 0x1e, 0xa3,
+ 0x8c, 0xfa, 0x10, 0x2c, 0x2e, 0x20, 0xa7, 0x14, 0xee, 0xe0, 0xf5, 0x9e,
+ 0x65, 0x19, 0x72, 0xc2, 0x89, 0xba, 0xf9, 0xf5, 0x11, 0x2f, 0x62, 0x56,
+ 0x21, 0xfd, 0xba, 0x34, 0xea, 0xf7, 0xde, 0x98, 0xb5, 0xaa, 0x7c, 0xf4,
+ 0x8b, 0x12, 0xe6, 0xbb, 0xb3, 0x93, 0x0b, 0xcb, 0x24, 0x57, 0xdc, 0x38,
+ 0xca, 0x91, 0x55, 0xf6, 0x57, 0xa9, 0x51, 0x59, 0xc3, 0xd0, 0xe0, 0xa9,
+ 0xdc, 0x78, 0x8b, 0x1a, 0x9d, 0x40, 0x7b, 0xb3, 0xb7, 0x25, 0x92, 0x85,
+ 0xb7, 0x22, 0xba, 0x09, 0xe1, 0xa4, 0xe4, 0xad, 0x82, 0xb1, 0xb1, 0xad,
+ 0x44, 0xbd, 0xaa, 0xf2, 0x79, 0xf9, 0xb9, 0x82, 0x5a, 0x16, 0x95, 0xfc,
+ 0x55, 0x6f, 0x79, 0xc3, 0xc1, 0x62, 0x8d, 0xf9, 0xc6, 0xaf, 0x02, 0xff,
+ 0x77, 0xf5, 0x5b, 0xdd, 0x32, 0x77, 0x1e, 0x43, 0xbe, 0x65, 0xdd, 0x00,
+ 0x6e, 0x95, 0x58, 0xda, 0x3d, 0xe2, 0x66, 0x7e, 0x26, 0xf3, 0x25, 0xf1,
+ 0xf8, 0xc8, 0xbd, 0x2f, 0xd1, 0xdf, 0x3c, 0xd4, 0xfd, 0x0e, 0xc3, 0x62,
+ 0x98, 0xb0, 0x6d, 0x23, 0x1c, 0x0c, 0x14, 0x28, 0x3a, 0xb6, 0x37, 0xfc,
+ 0x13, 0xed, 0x0b, 0xc4, 0x41, 0x90, 0x98, 0x97, 0x61, 0xcb, 0x48, 0xc1,
+ 0x94, 0x7a, 0x91, 0xfb, 0xf2, 0xf5, 0x7a, 0x0d, 0x2b, 0x2e, 0xf5, 0x86,
+ 0xc3, 0xc1, 0xf6, 0x6d, 0xac, 0xb7, 0x93, 0xf5, 0x62, 0x8c, 0xbd, 0xeb,
+ 0x47, 0x35, 0x27, 0x1f, 0xb4, 0x46, 0x8a, 0xa7, 0xf6, 0x77, 0xa9, 0xde,
+ 0x93, 0x86, 0x35, 0xee, 0xf4, 0xd7, 0x14, 0xec, 0x2c, 0x70, 0xb9, 0x91,
+ 0x64, 0xbd, 0x71, 0xd6, 0x7b, 0x77, 0x54, 0xd6, 0x33, 0x70, 0xcb, 0x48,
+ 0x22, 0x35, 0xe1, 0x32, 0x0c, 0xed, 0x1d, 0xc4, 0x88, 0xd9, 0xce, 0x5c,
+ 0xde, 0x72, 0x28, 0xd3, 0x85, 0xed, 0xc6, 0xd1, 0x70, 0x21, 0xeb, 0x1d,
+ 0x37, 0x8e, 0x06, 0x3c, 0xf4, 0x99, 0x75, 0x6c, 0xaf, 0x9b, 0x79, 0x91,
+ 0x4a, 0x8c, 0xdc, 0x32, 0x22, 0xdc, 0xc1, 0xc4, 0x6c, 0xe6, 0x67, 0x8e,
+ 0x6d, 0xca, 0xda, 0x09, 0x64, 0x4e, 0x65, 0x7c, 0xc1, 0xba, 0x11, 0x67,
+ 0x7c, 0xca, 0x35, 0x87, 0x25, 0x57, 0xae, 0xb0, 0xb0, 0xb9, 0x41, 0xe2,
+ 0xa7, 0x42, 0xec, 0x0e, 0xd6, 0x8d, 0x33, 0x9e, 0x6c, 0x1b, 0xfb, 0x33,
+ 0x8c, 0x6b, 0x95, 0xcc, 0x65, 0x6d, 0xfb, 0x15, 0x63, 0x61, 0x05, 0x43,
+ 0xbc, 0xd7, 0x4b, 0x99, 0xbd, 0xa1, 0x62, 0x89, 0xd3, 0x4e, 0x5b, 0x31,
+ 0x08, 0x3e, 0x29, 0x48, 0x1a, 0xd6, 0x06, 0x91, 0xff, 0x58, 0x38, 0x18,
+ 0x3f, 0xac, 0xd4, 0xb7, 0x6f, 0xc3, 0x3f, 0x11, 0x2f, 0x41, 0xac, 0x9b,
+ 0x89, 0x21, 0x93, 0xd6, 0xd2, 0x66, 0x31, 0x42, 0x4a, 0x8c, 0x77, 0x9f,
+ 0x58, 0xc4, 0x08, 0xe7, 0x46, 0xb0, 0xb3, 0x95, 0xe5, 0x23, 0xb9, 0x75,
+ 0x16, 0x5c, 0x18, 0x0d, 0x32, 0x0e, 0x8b, 0x2e, 0x80, 0xad, 0x99, 0x7c,
+ 0x2c, 0xb0, 0xed, 0x83, 0xa6, 0x6d, 0xbf, 0x64, 0xce, 0xc4, 0x61, 0x33,
+ 0x18, 0x17, 0x1f, 0x78, 0xdf, 0x5c, 0x78, 0x83, 0xe4, 0xc5, 0x80, 0xc8,
+ 0xa6, 0x30, 0x76, 0x29, 0x28, 0xe1, 0x27, 0x10, 0x72, 0xeb, 0x25, 0x8a,
+ 0x0d, 0x6f, 0x53, 0x6d, 0x67, 0x2d, 0xf5, 0x5e, 0x36, 0x5f, 0xc1, 0x27,
+ 0x37, 0x2a, 0x38, 0x7a, 0x63, 0x28, 0x30, 0xa4, 0x94, 0x32, 0x2e, 0x84,
+ 0xda, 0x5a, 0x14, 0xeb, 0x04, 0xeb, 0xc6, 0x1a, 0x5c, 0xc1, 0x00, 0x94,
+ 0x72, 0x62, 0xd6, 0x6c, 0x5d, 0x68, 0x8b, 0xbb, 0x37, 0x14, 0xd8, 0xc9,
+ 0x6f, 0xd7, 0xa8, 0x82, 0x51, 0x23, 0x18, 0x83, 0xd3, 0x3e, 0xfb, 0x66,
+ 0xca, 0x7c, 0x53, 0xc8, 0xb6, 0x4f, 0x86, 0xeb, 0xb5, 0x93, 0x78, 0x9f,
+ 0xb8, 0x2c, 0xfd, 0xe4, 0x65, 0x03, 0xf3, 0x70, 0x23, 0xd6, 0xa2, 0xdc,
+ 0x24, 0xb4, 0x84, 0x71, 0x52, 0x62, 0x79, 0x5e, 0xde, 0x7c, 0x4c, 0xb7,
+ 0xed, 0xf7, 0xcd, 0x5c, 0x5b, 0x5a, 0x73, 0x30, 0x0e, 0xcc, 0xc4, 0x98,
+ 0x11, 0x6c, 0x1d, 0xa7, 0x1e, 0x02, 0xf4, 0xf5, 0x19, 0x46, 0x15, 0x26,
+ 0x3c, 0x41, 0x6d, 0x42, 0x59, 0xf4, 0x99, 0x8a, 0x39, 0x1b, 0x9e, 0x52,
+ 0xea, 0x3b, 0x8a, 0x60, 0x90, 0x9f, 0x5e, 0x23, 0xf3, 0x11, 0xf0, 0x91,
+ 0x0b, 0xae, 0x83, 0xc3, 0x2f, 0x70, 0x7b, 0xc2, 0x1d, 0xbb, 0x80, 0x1a,
+ 0xfa, 0x9d, 0xd1, 0xfe, 0x90, 0x12, 0x64, 0xf2, 0xf2, 0x35, 0x26, 0x38,
+ 0x22, 0x6b, 0x15, 0xe2, 0xf7, 0xd8, 0xf6, 0xc3, 0x94, 0x75, 0x17, 0x65,
+ 0xdd, 0x18, 0xfe, 0xd8, 0xfe, 0x07, 0xa7, 0xcd, 0x5b, 0x31, 0x64, 0x5c,
+ 0xdd, 0xee, 0x47, 0x36, 0xa6, 0x4b, 0xbb, 0x1e, 0x2c, 0x99, 0xce, 0x5c,
+ 0xab, 0x59, 0xf0, 0xaa, 0xd2, 0x43, 0x7c, 0x62, 0x7b, 0x8c, 0x7f, 0xea,
+ 0xd5, 0x1c, 0xc2, 0x05, 0xc6, 0xe6, 0x40, 0x5c, 0x51, 0xab, 0x4b, 0xa0,
+ 0xc1, 0x6b, 0xd8, 0x78, 0x84, 0x7c, 0x27, 0x36, 0xbd, 0x1c, 0xdf, 0xe4,
+ 0x9c, 0x96, 0x86, 0xd4, 0x6b, 0x5d, 0x9c, 0x93, 0xc3, 0x61, 0xf9, 0xed,
+ 0xc1, 0xf8, 0x74, 0x17, 0xba, 0x38, 0xcb, 0x5a, 0x48, 0x9d, 0x21, 0xf7,
+ 0xbd, 0x8d, 0xf2, 0x9b, 0xf2, 0x5f, 0xa3, 0xe0, 0x61, 0x5a, 0xa4, 0x1a,
+ 0xea, 0x0e, 0xc8, 0xfd, 0x56, 0x53, 0x7e, 0x2b, 0xe4, 0x92, 0x6e, 0xce,
+ 0x8b, 0x0d, 0x97, 0x2c, 0x4d, 0x84, 0x78, 0x3f, 0x2c, 0xd7, 0xb1, 0x87,
+ 0x39, 0xee, 0xd8, 0x01, 0x45, 0x30, 0xee, 0x97, 0xf6, 0x2b, 0x8c, 0x81,
+ 0x1a, 0x9f, 0x7f, 0x93, 0x7d, 0x9f, 0x08, 0xbf, 0x64, 0xcf, 0xa8, 0x50,
+ 0x70, 0x32, 0xa2, 0x63, 0xe6, 0x8d, 0xd5, 0x98, 0xb8, 0x5b, 0xc6, 0xac,
+ 0xa0, 0xd4, 0x38, 0xe8, 0x91, 0x1c, 0xb9, 0xcc, 0xb8, 0x06, 0x4b, 0x56,
+ 0xe4, 0xee, 0x15, 0x85, 0x64, 0x8d, 0x53, 0x47, 0xd1, 0x8d, 0x95, 0xd0,
+ 0x27, 0xef, 0x2d, 0x0a, 0xb9, 0xdb, 0x4a, 0x15, 0x43, 0xbb, 0x5d, 0x91,
+ 0xe7, 0xbf, 0x23, 0x2f, 0xb7, 0xed, 0x47, 0x38, 0x5f, 0xb3, 0xc3, 0x3e,
+ 0x9c, 0x63, 0x3f, 0xdd, 0xd4, 0xdf, 0xf2, 0x4b, 0xf3, 0x95, 0xaf, 0xff,
+ 0xa9, 0xad, 0xdf, 0x23, 0x75, 0xa5, 0x8d, 0xda, 0xd6, 0x25, 0xca, 0x03,
+ 0x1e, 0xc9, 0x91, 0x36, 0x86, 0x1d, 0x9d, 0xb1, 0xec, 0x73, 0xce, 0x6f,
+ 0xad, 0xf9, 0xad, 0x4b, 0xeb, 0x75, 0xe7, 0x9d, 0x58, 0xba, 0x70, 0xbe,
+ 0x86, 0x09, 0xbb, 0xa2, 0xd1, 0xd2, 0x0a, 0x21, 0x31, 0xb5, 0xa6, 0xee,
+ 0x39, 0xb6, 0xfb, 0x73, 0x33, 0x17, 0x6f, 0x0f, 0x9a, 0xc1, 0x3e, 0x8b,
+ 0xfe, 0x13, 0x67, 0x8e, 0xdb, 0x22, 0xbc, 0x63, 0xec, 0x16, 0xce, 0xc3,
+ 0x4c, 0x14, 0x36, 0x06, 0x7b, 0x66, 0x31, 0xe7, 0x73, 0x35, 0x4b, 0x9c,
+ 0x96, 0xf9, 0x71, 0xca, 0xb0, 0xaf, 0x22, 0x2c, 0xa2, 0x8c, 0xe1, 0xc6,
+ 0x3f, 0x15, 0xdf, 0xa4, 0x1d, 0xb1, 0xce, 0x60, 0x4f, 0x0c, 0x7f, 0xaa,
+ 0x2c, 0xc8, 0x28, 0x64, 0x2d, 0xcc, 0x7b, 0x4b, 0x3c, 0xa3, 0x92, 0x23,
+ 0x15, 0x68, 0xdd, 0xcd, 0x55, 0xfc, 0xc8, 0x73, 0xf7, 0x2d, 0x6b, 0x32,
+ 0x97, 0xd6, 0x20, 0xd1, 0x67, 0x16, 0x40, 0xbd, 0x49, 0xe2, 0x05, 0x7d,
+ 0x59, 0x93, 0xf1, 0x59, 0xb4, 0x72, 0x59, 0x5f, 0x30, 0x56, 0xad, 0x25,
+ 0x5e, 0xbc, 0xc8, 0x1e, 0x87, 0xc9, 0xc5, 0x2c, 0xc7, 0x33, 0x9c, 0xf8,
+ 0x37, 0x65, 0x4d, 0x52, 0xe2, 0x57, 0x7e, 0x5d, 0xb3, 0x12, 0xfd, 0x7b,
+ 0x57, 0x40, 0xaf, 0xca, 0x61, 0xa0, 0x1a, 0x6d, 0xc2, 0xc2, 0xbe, 0x40,
+ 0x41, 0x2e, 0x7f, 0x28, 0x43, 0xef, 0xde, 0x30, 0xd2, 0xd3, 0x9d, 0xfa,
+ 0xbc, 0xe7, 0x85, 0x60, 0xf4, 0xf6, 0xbd, 0xd7, 0xca, 0x7a, 0x40, 0x40,
+ 0xda, 0x8d, 0xd3, 0x77, 0x54, 0xe3, 0x43, 0xdb, 0xd2, 0xa4, 0xfd, 0xa3,
+ 0x37, 0x10, 0x47, 0xcc, 0xc5, 0xa8, 0x6f, 0x3f, 0x84, 0x33, 0xe4, 0xa4,
+ 0x4e, 0xbe, 0xa4, 0x17, 0x46, 0xc7, 0x1f, 0xf6, 0x20, 0x14, 0x1f, 0x21,
+ 0x0e, 0xf8, 0x46, 0xbd, 0xe4, 0x56, 0x33, 0x9d, 0x75, 0xaf, 0x85, 0xc4,
+ 0x96, 0x38, 0x79, 0xf9, 0xd7, 0xdc, 0x6e, 0xac, 0x25, 0x66, 0x1c, 0x34,
+ 0xea, 0x3b, 0x0e, 0xe1, 0x1f, 0x89, 0xb3, 0x52, 0x5e, 0x65, 0x7f, 0xd2,
+ 0xa6, 0x9b, 0xfd, 0xc1, 0x4b, 0x2e, 0x70, 0x2f, 0xf9, 0xac, 0xdb, 0x63,
+ 0xfc, 0xc4, 0x23, 0xbc, 0x43, 0x78, 0xf7, 0xae, 0xbd, 0x0a, 0x5a, 0xd8,
+ 0xce, 0x4e, 0xda, 0xcc, 0xc3, 0x21, 0xb8, 0x5b, 0x6f, 0x24, 0xbf, 0x02,
+ 0x5d, 0x70, 0xba, 0x0f, 0x3b, 0x46, 0x10, 0xc9, 0x18, 0xe3, 0x33, 0x7c,
+ 0xa8, 0x62, 0x3b, 0x12, 0x53, 0x0a, 0x26, 0xdb, 0x89, 0xdc, 0x77, 0x65,
+ 0x3b, 0x65, 0x78, 0x72, 0xb2, 0x9d, 0x7d, 0x6c, 0xe7, 0xe6, 0xd9, 0x70,
+ 0x97, 0xdd, 0x2c, 0x73, 0xd5, 0x40, 0xff, 0x29, 0x43, 0xca, 0x89, 0x2b,
+ 0xe4, 0xa3, 0x5f, 0x85, 0x62, 0xd4, 0x4a, 0xee, 0x72, 0xd6, 0xa9, 0xb7,
+ 0xb8, 0x61, 0xfc, 0x02, 0x69, 0x91, 0x72, 0x7e, 0xf6, 0x38, 0x1d, 0x35,
+ 0xaf, 0x9b, 0x2a, 0x6c, 0xdd, 0x5b, 0x9c, 0x97, 0x97, 0xfd, 0xe4, 0xfb,
+ 0xa8, 0xe4, 0x3d, 0x3f, 0x76, 0x30, 0x07, 0x5d, 0xcc, 0x7e, 0x0e, 0x9b,
+ 0xc2, 0x23, 0xeb, 0xcd, 0x22, 0x45, 0x72, 0xf2, 0x00, 0x39, 0x45, 0x25,
+ 0x36, 0x3b, 0x71, 0x28, 0xc0, 0xfa, 0x0d, 0x65, 0x39, 0x7e, 0x02, 0xcf,
+ 0x32, 0x96, 0x6d, 0x09, 0xe7, 0xfa, 0x23, 0x0e, 0x33, 0xcf, 0x6d, 0xc4,
+ 0xc1, 0xc1, 0x4b, 0xcf, 0x83, 0x8b, 0x8d, 0xa9, 0xf3, 0x35, 0x1e, 0xf4,
+ 0xa0, 0x8d, 0xdf, 0x05, 0x12, 0x67, 0xae, 0x18, 0xfb, 0x96, 0x91, 0x47,
+ 0xf8, 0x5d, 0x8c, 0xad, 0x23, 0x36, 0xb6, 0x38, 0x39, 0x4e, 0x01, 0xba,
+ 0x1b, 0x04, 0x0f, 0xc5, 0x96, 0xa6, 0x4b, 0xec, 0x88, 0xa4, 0x21, 0xf1,
+ 0x55, 0xec, 0x27, 0xea, 0xd8, 0x8f, 0x4b, 0x99, 0x6a, 0x3f, 0x5d, 0x78,
+ 0xcd, 0x38, 0xba, 0xa2, 0x10, 0x47, 0xef, 0x97, 0xb5, 0xfb, 0x8e, 0x30,
+ 0x8e, 0xdd, 0x46, 0xdf, 0x7c, 0x97, 0xd8, 0xb2, 0x65, 0x36, 0xe3, 0x97,
+ 0x83, 0x59, 0x0a, 0x0a, 0xc9, 0x2b, 0xb6, 0xed, 0x0d, 0xea, 0x05, 0xaa,
+ 0xc6, 0x3e, 0xaf, 0xc6, 0x2e, 0x91, 0xdf, 0x64, 0x9e, 0x7e, 0xf4, 0xb1,
+ 0x42, 0xf8, 0x24, 0x5f, 0x7a, 0xfb, 0x0c, 0xdb, 0x58, 0x6c, 0xe6, 0x75,
+ 0xe5, 0xe8, 0x69, 0xb2, 0x9d, 0x4a, 0x24, 0xf7, 0xe6, 0xeb, 0x2b, 0x38,
+ 0x15, 0x0a, 0x4c, 0xae, 0x9d, 0x57, 0xa2, 0x77, 0xe4, 0xe8, 0x49, 0xf2,
+ 0x1c, 0xc6, 0xa9, 0xa3, 0x9d, 0x01, 0xca, 0x72, 0x3e, 0x9c, 0x9f, 0x53,
+ 0xf1, 0xcd, 0xa9, 0x6d, 0x88, 0xed, 0x42, 0x29, 0xab, 0xc5, 0x96, 0x32,
+ 0xda, 0x68, 0x26, 0x84, 0x78, 0x49, 0xb4, 0x0c, 0x89, 0x11, 0xfa, 0xd6,
+ 0x68, 0x01, 0xdc, 0xf3, 0x24, 0xee, 0x0a, 0xd7, 0x72, 0xdf, 0x72, 0x3a,
+ 0x51, 0x80, 0x07, 0xcc, 0x8b, 0xb6, 0xe0, 0xe2, 0x49, 0x03, 0xd7, 0x15,
+ 0x10, 0x13, 0x6b, 0xc3, 0xa1, 0xd8, 0x3a, 0xe6, 0xb4, 0xc7, 0x1b, 0xdc,
+ 0xb7, 0x7c, 0x90, 0xf9, 0x3d, 0x79, 0xf1, 0xd5, 0xe3, 0x11, 0x7d, 0xe0,
+ 0xc4, 0xd2, 0x90, 0xf4, 0x29, 0xfd, 0xe5, 0x6d, 0x54, 0xfa, 0xb7, 0xed,
+ 0x50, 0xd8, 0xe7, 0xcc, 0x79, 0x7e, 0x0c, 0xef, 0x19, 0xf9, 0x31, 0xf8,
+ 0x9c, 0xf8, 0xcd, 0x1c, 0x98, 0x98, 0x23, 0x79, 0xc1, 0x11, 0xe5, 0xa8,
+ 0x93, 0x03, 0x5b, 0x31, 0xe6, 0xbe, 0x91, 0x9e, 0xc9, 0xdc, 0x77, 0x9c,
+ 0x3c, 0xf7, 0x38, 0x79, 0xee, 0xcb, 0x93, 0xb9, 0xef, 0x8b, 0x19, 0xa9,
+ 0x33, 0xb5, 0x7c, 0x24, 0x26, 0x6b, 0xd6, 0x23, 0x89, 0x50, 0x5d, 0xbe,
+ 0xce, 0xcb, 0x2c, 0x7f, 0xfc, 0x52, 0xf9, 0xd5, 0xcc, 0x57, 0x57, 0x61,
+ 0x5b, 0xaa, 0x04, 0x0f, 0x6a, 0x4e, 0x6e, 0xe9, 0x2d, 0x8c, 0x9e, 0xb8,
+ 0xef, 0x7d, 0x63, 0xbc, 0xce, 0x45, 0x1c, 0x1a, 0xe1, 0xe0, 0x5b, 0x12,
+ 0x0a, 0xfd, 0xce, 0x83, 0x1e, 0xad, 0x1c, 0x6b, 0xcd, 0x7f, 0xb2, 0x1f,
+ 0x5c, 0x25, 0xcf, 0xf2, 0x7b, 0x14, 0x52, 0xfe, 0x35, 0x96, 0x0f, 0x9a,
+ 0x23, 0x93, 0xb9, 0xe0, 0xd1, 0x04, 0xfa, 0x24, 0xcf, 0x5a, 0xd3, 0x1c,
+ 0xd2, 0xbb, 0x9d, 0x75, 0x63, 0x1d, 0xeb, 0x32, 0x3a, 0xd6, 0x53, 0x9e,
+ 0xb4, 0x7b, 0x32, 0x47, 0xca, 0xc5, 0x62, 0x4b, 0x78, 0xe6, 0x22, 0x96,
+ 0xdb, 0x3c, 0x89, 0x33, 0x2d, 0x97, 0x78, 0xae, 0x6d, 0xf7, 0x9b, 0x79,
+ 0xae, 0xcb, 0x58, 0x50, 0x29, 0xb9, 0x35, 0x68, 0x17, 0x15, 0x48, 0xfb,
+ 0x65, 0x4f, 0x66, 0xea, 0x18, 0x11, 0x2b, 0x8c, 0x86, 0xf4, 0xd9, 0xea,
+ 0x54, 0xec, 0x92, 0xb1, 0x0a, 0x6e, 0x59, 0x8e, 0x7e, 0x8e, 0x5d, 0x1a,
+ 0x6f, 0x7d, 0xa1, 0x60, 0xd6, 0xc1, 0x44, 0x77, 0x01, 0x6d, 0x4b, 0x2d,
+ 0x10, 0x7b, 0x40, 0xee, 0x1e, 0xb2, 0xb6, 0xbd, 0xfd, 0x0a, 0xdd, 0x15,
+ 0xc4, 0x98, 0x0a, 0xe0, 0xe9, 0x44, 0x28, 0x76, 0x16, 0x96, 0x72, 0x32,
+ 0xe3, 0xa6, 0xad, 0x4b, 0xbb, 0x5b, 0xd8, 0x5e, 0x8f, 0x72, 0xe2, 0x52,
+ 0x9b, 0x17, 0x2e, 0x6e, 0x76, 0xd6, 0x71, 0xf3, 0xbe, 0xe2, 0xc5, 0x43,
+ 0x7d, 0xf9, 0xbd, 0xc6, 0x18, 0xde, 0x33, 0x05, 0x17, 0xbd, 0xe4, 0x3d,
+ 0xcc, 0xd2, 0x13, 0xdb, 0x90, 0xf3, 0x4b, 0xf9, 0xe4, 0xe7, 0xfd, 0xa0,
+ 0x5b, 0x30, 0xec, 0x27, 0xb3, 0x63, 0x93, 0x6b, 0x2e, 0x7f, 0xac, 0x4c,
+ 0x1e, 0xdb, 0x2f, 0x5c, 0xec, 0x4b, 0x55, 0x4f, 0xc9, 0xb3, 0x69, 0x5f,
+ 0x03, 0xc1, 0x1e, 0x0b, 0x95, 0x6c, 0xc3, 0x8d, 0xbf, 0x65, 0xfc, 0x76,
+ 0x0f, 0x1c, 0xbd, 0x41, 0x52, 0x32, 0xcf, 0xa1, 0x18, 0x36, 0x37, 0x7b,
+ 0xe0, 0x1a, 0xaa, 0x2e, 0xcc, 0xad, 0xf3, 0x91, 0x3c, 0x3b, 0xdf, 0x8a,
+ 0x83, 0xd3, 0x6a, 0x56, 0xf2, 0x6a, 0xd2, 0x88, 0x43, 0xa2, 0xd7, 0x4a,
+ 0x7e, 0x8b, 0x5e, 0xfc, 0xfc, 0x16, 0x1d, 0x55, 0xf1, 0xbb, 0x1c, 0xb1,
+ 0x2a, 0xd9, 0xf3, 0x6a, 0x47, 0x82, 0x98, 0x55, 0x12, 0xed, 0xc4, 0xd7,
+ 0x7b, 0x6d, 0xbb, 0x87, 0x7e, 0x59, 0xc4, 0x18, 0xff, 0x48, 0xa8, 0x3e,
+ 0x32, 0x47, 0x29, 0x20, 0xdf, 0x69, 0x47, 0xcf, 0x48, 0x41, 0xbc, 0x3c,
+ 0x5a, 0xc5, 0x98, 0xae, 0xe1, 0x93, 0xb9, 0x6d, 0xc8, 0x8e, 0x5e, 0xbd,
+ 0x57, 0x36, 0x75, 0x9f, 0x2c, 0xbf, 0x3f, 0x26, 0xe3, 0x11, 0xb9, 0x45,
+ 0xfe, 0x0b, 0x17, 0xb7, 0xa6, 0x44, 0x36, 0x0f, 0x0e, 0xf4, 0x89, 0xbc,
+ 0x36, 0x3a, 0xcc, 0x5b, 0x29, 0x27, 0x91, 0xbe, 0x72, 0xea, 0xfc, 0xe6,
+ 0xdb, 0x91, 0x75, 0xf0, 0x4e, 0x65, 0x98, 0xf3, 0x65, 0xb9, 0x0b, 0xc5,
+ 0xbf, 0x34, 0xe6, 0x15, 0xca, 0x73, 0x19, 0x69, 0xa3, 0x45, 0x19, 0x49,
+ 0x4f, 0xad, 0xd3, 0xa9, 0x1c, 0xca, 0x3c, 0x5c, 0x28, 0x9c, 0xe3, 0xb2,
+ 0x1e, 0xf3, 0x32, 0x90, 0xdc, 0xd2, 0x5e, 0x2a, 0x92, 0xa2, 0x7f, 0xd1,
+ 0x8f, 0x0e, 0x77, 0x96, 0xbf, 0xb3, 0x5f, 0xd6, 0xe7, 0xd5, 0x3e, 0x36,
+ 0xf7, 0x0a, 0x9f, 0x3c, 0x4e, 0x9f, 0x1c, 0xff, 0xa3, 0x3e, 0x39, 0xef,
+ 0x4f, 0x94, 0xcf, 0xaf, 0xb7, 0xda, 0xf6, 0x6e, 0x53, 0xd6, 0xe8, 0x65,
+ 0xdd, 0xb5, 0xe1, 0x4b, 0xf6, 0x5e, 0x65, 0x3d, 0x7e, 0x36, 0xd2, 0x95,
+ 0xc1, 0xb4, 0xac, 0xbf, 0x0c, 0xa4, 0x80, 0x45, 0x49, 0xe9, 0x27, 0x46,
+ 0x7d, 0xa9, 0xb7, 0x32, 0x1a, 0x31, 0x43, 0xe8, 0xc2, 0x19, 0xd3, 0xd8,
+ 0xf7, 0x20, 0x79, 0x77, 0x37, 0x73, 0xd2, 0x83, 0xe6, 0x72, 0xfa, 0x7b,
+ 0x31, 0x36, 0x34, 0xd0, 0x18, 0x57, 0x98, 0xf4, 0x7b, 0xab, 0x9d, 0xae,
+ 0xe8, 0xf5, 0x45, 0xdb, 0x57, 0x25, 0x42, 0xc1, 0xb6, 0x8d, 0xc4, 0xf3,
+ 0xa5, 0xbd, 0x5e, 0xe8, 0x8a, 0xc3, 0x07, 0x5a, 0x7f, 0xa1, 0x0a, 0x46,
+ 0x9d, 0x29, 0xc8, 0xe5, 0xcd, 0xb2, 0xe6, 0x22, 0xfd, 0x2c, 0x67, 0x5e,
+ 0x22, 0x75, 0x75, 0xb4, 0xd7, 0x2a, 0x48, 0xd5, 0x06, 0xfb, 0xe0, 0xb2,
+ 0xed, 0xdf, 0x91, 0x17, 0x8e, 0x3b, 0xb9, 0x7c, 0x7d, 0xdd, 0x6e, 0xf5,
+ 0x7f, 0x10, 0x0b, 0x9d, 0x36, 0x34, 0x59, 0xf3, 0x7f, 0xe1, 0x4f, 0xae,
+ 0x7b, 0x9b, 0x90, 0xbd, 0x89, 0x42, 0x63, 0x89, 0x32, 0xe2, 0xcf, 0x71,
+ 0x8a, 0xdb, 0x06, 0x3e, 0xbf, 0xf8, 0x64, 0x4a, 0xec, 0x1c, 0x55, 0x01,
+ 0x63, 0x06, 0x66, 0x1f, 0x28, 0xc5, 0xb2, 0x01, 0xe1, 0x0a, 0x3e, 0xab,
+ 0x30, 0x1a, 0xc0, 0x9c, 0x03, 0x95, 0x68, 0xd9, 0x23, 0xfb, 0x50, 0x76,
+ 0x57, 0x45, 0x74, 0x35, 0xdc, 0x87, 0x34, 0x3c, 0xb0, 0xc7, 0xb6, 0x67,
+ 0xcd, 0x23, 0xb5, 0x63, 0x4c, 0x7c, 0xb7, 0x69, 0x15, 0x3c, 0xd9, 0x6a,
+ 0x2c, 0x49, 0xd6, 0x39, 0x6b, 0xad, 0x1f, 0x26, 0x5a, 0x5b, 0xce, 0xf5,
+ 0xd6, 0x6e, 0xa8, 0x55, 0x82, 0xe6, 0x29, 0x25, 0x82, 0x82, 0x6c, 0x04,
+ 0xae, 0xa4, 0x82, 0x57, 0x0d, 0x74, 0x95, 0x45, 0xa3, 0x70, 0x65, 0xa3,
+ 0xf0, 0x25, 0xdd, 0x68, 0xa0, 0xbe, 0x4b, 0x38, 0xf7, 0xd3, 0x92, 0xd5,
+ 0x98, 0x96, 0xbd, 0x0e, 0xfa, 0x81, 0x06, 0xfa, 0x48, 0x25, 0xfb, 0xf3,
+ 0xa3, 0x25, 0xd9, 0x86, 0x69, 0x46, 0x33, 0x6d, 0xa3, 0x19, 0x33, 0x93,
+ 0x7e, 0x2c, 0xe0, 0x7c, 0x2c, 0x4e, 0xb6, 0xb2, 0x1f, 0x1f, 0xda, 0x07,
+ 0xee, 0x44, 0x60, 0xc8, 0x8b, 0xf2, 0x01, 0x1d, 0x1f, 0xce, 0xf5, 0xa2,
+ 0x68, 0x28, 0x80, 0xd2, 0xa4, 0xec, 0x8d, 0x21, 0xb6, 0xb1, 0x39, 0x00,
+ 0x5f, 0x16, 0x28, 0x19, 0xb0, 0xf1, 0xad, 0xf0, 0xa8, 0x7a, 0x77, 0xa5,
+ 0x65, 0x4f, 0x73, 0x62, 0x41, 0x6b, 0xfb, 0x16, 0xe3, 0xce, 0x49, 0xbf,
+ 0x77, 0x33, 0xcf, 0x52, 0xc8, 0xd7, 0x25, 0x06, 0xb6, 0xb6, 0x1f, 0x4c,
+ 0xc8, 0xda, 0x46, 0x88, 0x7e, 0xeb, 0x81, 0x77, 0xa8, 0x53, 0xe9, 0xa3,
+ 0xed, 0xa0, 0x40, 0xf4, 0xaf, 0xd2, 0xbf, 0xa0, 0x95, 0xd2, 0xce, 0xb7,
+ 0x66, 0x5a, 0x94, 0x64, 0xba, 0x53, 0xe9, 0xcd, 0x94, 0x78, 0x51, 0x2c,
+ 0xf3, 0xf2, 0x15, 0x8c, 0x36, 0x3c, 0x69, 0xa7, 0x2b, 0x9c, 0xb9, 0xb5,
+ 0x3c, 0x90, 0x9c, 0xdb, 0x5a, 0x15, 0xae, 0x0d, 0x76, 0x56, 0xa8, 0xb2,
+ 0x9f, 0x42, 0x1c, 0x52, 0x72, 0x7d, 0x69, 0x46, 0x12, 0xcf, 0xfa, 0x65,
+ 0x7d, 0x55, 0xe6, 0xbf, 0xb5, 0x3d, 0xd1, 0x7b, 0xe1, 0xa2, 0xcc, 0xe9,
+ 0xc7, 0xb4, 0xc3, 0xdb, 0x93, 0x9f, 0x5f, 0xdc, 0x97, 0x6a, 0x63, 0x9e,
+ 0x66, 0xe2, 0x55, 0xfe, 0x5e, 0xc4, 0x71, 0xbf, 0x98, 0xf1, 0x61, 0x61,
+ 0xb2, 0xd9, 0xd9, 0x8b, 0x5b, 0x96, 0x8c, 0xe0, 0x15, 0x7e, 0xb7, 0x24,
+ 0x57, 0xe1, 0x18, 0xf3, 0xd4, 0x07, 0x92, 0x51, 0xbc, 0x9d, 0x09, 0xe0,
+ 0x7e, 0xea, 0x6f, 0x06, 0xed, 0xf4, 0xae, 0xa4, 0x8e, 0x37, 0x32, 0xc0,
+ 0xcf, 0xfa, 0x6c, 0x84, 0x1a, 0xbf, 0xa3, 0x3e, 0xed, 0xac, 0x8d, 0x35,
+ 0xe3, 0x67, 0x09, 0x13, 0x6f, 0x24, 0x6a, 0xcc, 0x9b, 0xd5, 0xdf, 0x62,
+ 0xdc, 0x9d, 0xa0, 0x4d, 0x9d, 0x47, 0xbc, 0x52, 0xd6, 0xf1, 0x72, 0xf2,
+ 0x77, 0x8f, 0x79, 0x98, 0x63, 0x6d, 0xc0, 0x11, 0xbf, 0xb3, 0x2e, 0x71,
+ 0x85, 0x5c, 0xb2, 0x36, 0xb1, 0x88, 0x72, 0x3d, 0x95, 0x22, 0x57, 0x34,
+ 0xaa, 0x29, 0x8f, 0x17, 0x0b, 0x07, 0xbc, 0xa8, 0xa4, 0x6d, 0x9c, 0x3e,
+ 0x10, 0xc5, 0xce, 0x54, 0x11, 0x5a, 0xfa, 0x03, 0x38, 0xc3, 0xeb, 0xad,
+ 0xb4, 0xf1, 0x1f, 0xb1, 0x6f, 0xa3, 0x49, 0xc3, 0x80, 0x56, 0x84, 0x9e,
+ 0xba, 0x1f, 0x93, 0xef, 0xa9, 0xcc, 0x39, 0x98, 0x1b, 0x18, 0x25, 0xd8,
+ 0xc1, 0xb4, 0xbe, 0xb0, 0x39, 0x88, 0xfe, 0x3a, 0xda, 0x7a, 0x15, 0xe3,
+ 0x87, 0x11, 0x43, 0x39, 0x31, 0x26, 0xc5, 0x5c, 0xb1, 0x30, 0x6a, 0x51,
+ 0x06, 0x15, 0xfb, 0x34, 0x55, 0xd6, 0xe4, 0xf8, 0x2c, 0x80, 0x63, 0x09,
+ 0xd8, 0xc5, 0x51, 0xe3, 0xc2, 0x4e, 0x84, 0x4e, 0xbc, 0xcf, 0xb8, 0xfe,
+ 0xf7, 0x99, 0x12, 0x7c, 0xbf, 0x6f, 0x36, 0xfe, 0x36, 0x2d, 0xeb, 0xbd,
+ 0x3e, 0xac, 0x1f, 0x0c, 0xab, 0xb9, 0xb5, 0x4a, 0x1f, 0x1e, 0x1a, 0x84,
+ 0x35, 0x93, 0xf6, 0xf8, 0xf2, 0x70, 0x19, 0xd6, 0xf4, 0xbd, 0x60, 0x33,
+ 0x77, 0xa6, 0x5d, 0x7b, 0x71, 0x34, 0x2d, 0x32, 0x96, 0x53, 0xc6, 0x22,
+ 0x1c, 0xe3, 0x75, 0x0f, 0x6d, 0xbf, 0xb2, 0xf7, 0xdb, 0xf8, 0x2c, 0x55,
+ 0x53, 0x77, 0xbf, 0xda, 0x8e, 0xe3, 0xce, 0x7e, 0x6c, 0x03, 0xde, 0xa2,
+ 0x1e, 0xcb, 0x77, 0xdb, 0xf6, 0x6f, 0xc2, 0x31, 0xfc, 0x2c, 0x73, 0x2d,
+ 0x8a, 0x78, 0x6d, 0x86, 0x5b, 0xf0, 0x66, 0xa6, 0x1a, 0x65, 0xbd, 0xad,
+ 0x78, 0x9d, 0x9c, 0xbf, 0x74, 0x77, 0x27, 0x4e, 0xb1, 0x7d, 0x5f, 0xbf,
+ 0x17, 0xaf, 0xa5, 0xbd, 0x78, 0xb5, 0xcf, 0xd0, 0xd6, 0x2a, 0x7f, 0xa7,
+ 0xc4, 0x2b, 0x73, 0xfd, 0x0c, 0xa4, 0x72, 0xfa, 0xdc, 0x3e, 0x56, 0x00,
+ 0xc1, 0xf2, 0x43, 0x7e, 0x59, 0xbf, 0x95, 0xf3, 0x31, 0xad, 0xed, 0x5a,
+ 0xf2, 0x77, 0x17, 0x13, 0xd4, 0xe7, 0x9b, 0xa3, 0x01, 0xdc, 0x91, 0x14,
+ 0xdd, 0x7e, 0x7e, 0x71, 0x17, 0xb1, 0xa3, 0x77, 0x34, 0x82, 0x13, 0x09,
+ 0x8f, 0xb3, 0xe7, 0xd8, 0x33, 0x2a, 0xfb, 0xb1, 0xdf, 0xe5, 0xdc, 0x00,
+ 0x6b, 0x47, 0x73, 0x6d, 0x6d, 0x19, 0x2b, 0xa4, 0xee, 0x6e, 0xc7, 0xd3,
+ 0x5a, 0x81, 0xc4, 0xdf, 0x9c, 0x8d, 0x1a, 0x41, 0xda, 0xee, 0x77, 0x9d,
+ 0xf5, 0xbd, 0x81, 0x54, 0xbd, 0x36, 0x0d, 0xf9, 0x79, 0xac, 0xc1, 0x4c,
+ 0xe3, 0xf7, 0xf6, 0x0b, 0x7e, 0x59, 0x77, 0x15, 0xbe, 0xd8, 0xda, 0xbe,
+ 0x36, 0x21, 0xfd, 0xe8, 0xd8, 0x3c, 0x7a, 0xe1, 0x62, 0x3f, 0xf9, 0xfa,
+ 0x12, 0xda, 0xc8, 0xba, 0x90, 0x1f, 0x8b, 0x6b, 0xeb, 0x50, 0x9b, 0x95,
+ 0x35, 0xdd, 0x08, 0x39, 0xab, 0x89, 0x8e, 0x50, 0xd4, 0xd9, 0xd7, 0x82,
+ 0x9a, 0xbf, 0xe7, 0xc5, 0xbb, 0x7f, 0xe0, 0x2b, 0xc0, 0xac, 0x81, 0x36,
+ 0xf6, 0x6b, 0x63, 0x99, 0xf9, 0x0f, 0x76, 0xcb, 0x3d, 0xd2, 0x7f, 0x4d,
+ 0x59, 0xee, 0x19, 0x27, 0xbc, 0x58, 0x7e, 0x37, 0xd1, 0x97, 0x1a, 0x71,
+ 0xd8, 0x2f, 0x3c, 0x43, 0xfc, 0xa0, 0xb5, 0x3d, 0x4c, 0xfb, 0xd9, 0x41,
+ 0x19, 0x56, 0xd0, 0x76, 0x96, 0x11, 0x17, 0xca, 0x8d, 0x0b, 0x17, 0x7b,
+ 0x53, 0x26, 0xe6, 0x8c, 0xfa, 0x68, 0xcb, 0x45, 0xec, 0xaf, 0x19, 0xc6,
+ 0x28, 0x71, 0x84, 0xf6, 0xbd, 0x60, 0xd4, 0x4f, 0x7b, 0xd6, 0x31, 0x7f,
+ 0x54, 0x7c, 0xdc, 0x40, 0x88, 0xb1, 0xac, 0x9d, 0x75, 0x22, 0xa3, 0x15,
+ 0xb8, 0x79, 0xbf, 0x1b, 0x77, 0x26, 0xc3, 0xd4, 0x4f, 0x1d, 0x63, 0xdc,
+ 0x65, 0x7d, 0x6f, 0x1b, 0x9b, 0x85, 0x0a, 0xe3, 0x88, 0xfd, 0x9c, 0x83,
+ 0x61, 0x85, 0x8e, 0x9e, 0x02, 0xec, 0x37, 0x90, 0x82, 0x55, 0xce, 0xf8,
+ 0x72, 0x61, 0xf4, 0xb9, 0x2f, 0xe2, 0xf7, 0x8a, 0x2e, 0xa7, 0x8e, 0x47,
+ 0x30, 0xe5, 0x02, 0xb1, 0x0e, 0x68, 0x7c, 0xc2, 0xc6, 0xe2, 0xc6, 0x8d,
+ 0xca, 0x0f, 0x1c, 0x5b, 0x92, 0x76, 0x85, 0x3b, 0xe4, 0xf5, 0x9f, 0xd7,
+ 0xf9, 0x6f, 0x0a, 0x72, 0x3a, 0xcf, 0x8f, 0x33, 0xb8, 0x4f, 0x70, 0x7a,
+ 0x7d, 0x63, 0x1e, 0xa7, 0xa5, 0xbc, 0xdc, 0x5f, 0x61, 0xf7, 0x6a, 0x70,
+ 0x17, 0x1a, 0x2e, 0x6c, 0xaf, 0x7b, 0x46, 0x99, 0xd0, 0xc4, 0xe7, 0x15,
+ 0x62, 0xc7, 0xed, 0x36, 0xdd, 0x96, 0x76, 0xfd, 0x12, 0xcb, 0x41, 0x29,
+ 0xbc, 0x34, 0x97, 0xc2, 0x3f, 0xba, 0x27, 0xe7, 0x52, 0x78, 0x6f, 0x7e,
+ 0x4c, 0x79, 0x59, 0x23, 0xe4, 0x76, 0x22, 0xaf, 0xd8, 0x86, 0x94, 0x79,
+ 0xb0, 0xc8, 0x59, 0x8f, 0x46, 0xf7, 0x14, 0x7b, 0xc8, 0x73, 0x18, 0xa7,
+ 0x0d, 0x0d, 0x97, 0xec, 0xc1, 0x8d, 0xb6, 0xa4, 0xcc, 0x3b, 0xac, 0x62,
+ 0xea, 0xa1, 0x6d, 0xd4, 0xc3, 0xf9, 0x13, 0x2e, 0xae, 0x62, 0x89, 0xb9,
+ 0x5d, 0x19, 0xf7, 0xef, 0x64, 0x1b, 0x9f, 0x5f, 0x64, 0x1d, 0xde, 0xeb,
+ 0xe5, 0xf5, 0x75, 0xb8, 0x9d, 0x38, 0xba, 0x36, 0x6c, 0x29, 0xb9, 0x73,
+ 0x05, 0x45, 0xb8, 0x71, 0xa0, 0x12, 0x3e, 0x43, 0xd6, 0x2d, 0xfe, 0xb3,
+ 0xe2, 0xab, 0x90, 0xf1, 0x3b, 0x9c, 0x81, 0x76, 0x72, 0x1d, 0x16, 0x0f,
+ 0x30, 0x64, 0x3b, 0x7b, 0x04, 0x0b, 0xf1, 0x74, 0xf3, 0x75, 0x58, 0xea,
+ 0x70, 0x9d, 0x10, 0x6e, 0x1a, 0x12, 0x0c, 0xed, 0x54, 0xfa, 0x89, 0x9d,
+ 0x4c, 0x38, 0xe8, 0xd7, 0x31, 0xa5, 0x8f, 0x98, 0xb9, 0xcf, 0xf1, 0x11,
+ 0x59, 0x2f, 0xee, 0x54, 0x52, 0x99, 0x0a, 0x8e, 0x43, 0x6c, 0xf7, 0xb2,
+ 0x8c, 0x33, 0x29, 0xe3, 0x79, 0x62, 0xd1, 0xfc, 0x49, 0x19, 0x67, 0x37,
+ 0x49, 0x2e, 0x2b, 0x32, 0x16, 0xa1, 0x96, 0x72, 0x54, 0x52, 0x8e, 0x63,
+ 0x66, 0x85, 0x32, 0xa0, 0xe5, 0x64, 0xab, 0x61, 0xff, 0x8c, 0x39, 0x58,
+ 0x63, 0xfa, 0x94, 0x65, 0xce, 0xbd, 0xbc, 0x6c, 0x9f, 0x5f, 0xec, 0x49,
+ 0x7d, 0x61, 0xfb, 0x8c, 0x9c, 0x9c, 0x65, 0xfd, 0x3a, 0x4e, 0xcd, 0xbd,
+ 0x0e, 0xa5, 0xfb, 0x8b, 0xd0, 0x48, 0x5c, 0xaf, 0x1f, 0x30, 0xfa, 0x36,
+ 0x2a, 0x22, 0xab, 0x87, 0xbf, 0x9d, 0x75, 0x03, 0xea, 0xf3, 0xff, 0x2f,
+ 0xbc, 0xd2, 0x8e, 0xdd, 0x58, 0x91, 0xcc, 0xd9, 0xb0, 0xe3, 0xbf, 0xb5,
+ 0x62, 0xbf, 0xb2, 0x46, 0x48, 0x7b, 0xce, 0xb8, 0xb0, 0x84, 0x7d, 0x1f,
+ 0x33, 0x1f, 0x56, 0x2c, 0xed, 0xc2, 0x45, 0xd9, 0xaf, 0x57, 0x29, 0x63,
+ 0x77, 0xfa, 0x3a, 0xdc, 0x31, 0x30, 0x6e, 0x7b, 0x8d, 0x05, 0xc8, 0x84,
+ 0x43, 0xed, 0x3d, 0x8a, 0x17, 0xbb, 0xd2, 0x2e, 0x2c, 0x1a, 0x20, 0x5f,
+ 0x33, 0xe3, 0x4a, 0x6c, 0x7a, 0x8e, 0x87, 0x2f, 0x4c, 0x32, 0x1f, 0xcd,
+ 0x4a, 0x7e, 0xd8, 0xd6, 0xbe, 0x30, 0xf1, 0x80, 0x12, 0xd3, 0x3e, 0xbf,
+ 0x98, 0x4c, 0x1d, 0xfd, 0xae, 0xea, 0xf0, 0x30, 0x1f, 0xde, 0x3c, 0xe8,
+ 0xa3, 0x2f, 0x28, 0xf4, 0x13, 0x3f, 0x7d, 0xbf, 0x01, 0x6f, 0xd3, 0x37,
+ 0xee, 0x67, 0x5c, 0xfc, 0xfb, 0xd1, 0x2a, 0xdc, 0xb6, 0x27, 0x8a, 0x97,
+ 0x0f, 0xfa, 0xd1, 0xbe, 0xe7, 0x56, 0xbc, 0xc5, 0x72, 0x63, 0x8c, 0x07,
+ 0x63, 0xc3, 0x95, 0xfc, 0xf8, 0xf9, 0xa9, 0xe2, 0x67, 0x2d, 0xf1, 0xa8,
+ 0x02, 0x27, 0xf7, 0xbb, 0xd0, 0x32, 0xa0, 0x62, 0xc0, 0x54, 0x70, 0xf7,
+ 0x4d, 0x32, 0x1e, 0x2f, 0xd6, 0xd4, 0x5e, 0xb6, 0x8b, 0x25, 0x49, 0xe1,
+ 0x70, 0x5e, 0xce, 0x93, 0x8e, 0x43, 0xf4, 0xcb, 0xdb, 0xc8, 0xc1, 0x76,
+ 0xf4, 0xb5, 0xd1, 0x8f, 0x6c, 0xcc, 0x0a, 0xff, 0x18, 0x2b, 0xb4, 0x1e,
+ 0xc9, 0x6b, 0x9d, 0x75, 0xfe, 0x14, 0xe7, 0x71, 0xc2, 0x53, 0x6f, 0x4d,
+ 0x43, 0x51, 0x2c, 0x10, 0x0d, 0x69, 0x47, 0xb0, 0x1c, 0x7d, 0x63, 0xd0,
+ 0x64, 0xcd, 0x7f, 0x1b, 0x79, 0xd4, 0x76, 0xf2, 0xa8, 0xee, 0xcc, 0x11,
+ 0xce, 0xb1, 0xcf, 0x2b, 0x7b, 0xdf, 0xdb, 0xa8, 0xbb, 0xc5, 0x0e, 0x27,
+ 0xf2, 0x5a, 0x45, 0x6c, 0xff, 0x38, 0x63, 0xd2, 0x82, 0xfe, 0x1c, 0x6e,
+ 0x7c, 0xd6, 0xf4, 0x3c, 0x8c, 0x69, 0x3d, 0xf4, 0xf9, 0x5c, 0xdb, 0x3b,
+ 0x85, 0x9b, 0x79, 0xca, 0x62, 0x65, 0xd1, 0xd0, 0x86, 0xd7, 0xa9, 0x7c,
+ 0x2f, 0xdb, 0xdc, 0x3a, 0xb9, 0x8f, 0xd0, 0xcb, 0x36, 0x7b, 0x58, 0xb7,
+ 0xbe, 0xdf, 0xe2, 0x5c, 0xba, 0x59, 0x3f, 0x14, 0xd8, 0xa8, 0x98, 0xac,
+ 0xeb, 0xe4, 0x11, 0xa8, 0xd9, 0x7f, 0x79, 0xae, 0xda, 0x88, 0x31, 0xfd,
+ 0x93, 0xfe, 0x7e, 0x7e, 0xf4, 0x3a, 0x84, 0x68, 0x24, 0x4f, 0x9b, 0x9b,
+ 0xa0, 0xd3, 0x66, 0x5d, 0x93, 0x7d, 0x6d, 0x97, 0x71, 0xb8, 0x67, 0xc6,
+ 0x66, 0xb2, 0x8f, 0xbe, 0x4c, 0x48, 0xeb, 0x42, 0xfd, 0x89, 0x69, 0x90,
+ 0x71, 0x48, 0x7f, 0xcb, 0xf1, 0xe4, 0xd8, 0xd5, 0xe3, 0xa8, 0x26, 0x3e,
+ 0x5d, 0x2c, 0x98, 0x3c, 0x33, 0xe7, 0xe4, 0xe2, 0x31, 0xc7, 0xc7, 0x76,
+ 0x38, 0xf2, 0x7b, 0xd8, 0x66, 0x36, 0xb7, 0x07, 0x22, 0x69, 0x95, 0x32,
+ 0xc2, 0x58, 0xd1, 0x96, 0x54, 0x62, 0x15, 0xd1, 0xfa, 0xce, 0x69, 0x08,
+ 0x45, 0x7e, 0xc6, 0xb6, 0xa7, 0xb1, 0xed, 0x67, 0xd9, 0x76, 0x8a, 0x6d,
+ 0x8f, 0xb0, 0xed, 0x1f, 0x5c, 0x6a, 0x5b, 0xc5, 0xfd, 0x7b, 0xf2, 0xb6,
+ 0xe5, 0x46, 0xa4, 0x89, 0x59, 0xdf, 0x34, 0xd9, 0x03, 0xad, 0xe6, 0xdc,
+ 0x8b, 0xee, 0x74, 0xc6, 0xf6, 0x9c, 0xbd, 0x2d, 0x60, 0xec, 0xb9, 0x6b,
+ 0x8f, 0x82, 0xf7, 0xc3, 0xef, 0x63, 0xc2, 0x9f, 0xe3, 0x11, 0x79, 0x1b,
+ 0xd2, 0x68, 0x43, 0x5a, 0xf2, 0x7f, 0xd2, 0xf4, 0xa5, 0x8e, 0xd8, 0x8f,
+ 0xec, 0x3f, 0x90, 0x3f, 0x27, 0x44, 0x1f, 0xbf, 0x23, 0xee, 0x86, 0x4e,
+ 0xbc, 0xc7, 0xd8, 0xf9, 0xa3, 0x8c, 0x07, 0xe9, 0xb4, 0x0f, 0xcf, 0x66,
+ 0x04, 0x1b, 0xdb, 0x88, 0x8d, 0x82, 0xf7, 0xe4, 0x81, 0xc3, 0x47, 0x1f,
+ 0x0b, 0xb0, 0xf2, 0xb3, 0xb4, 0x9f, 0x67, 0x69, 0x3f, 0xcf, 0x0e, 0xfb,
+ 0x70, 0xf3, 0x21, 0x2f, 0xce, 0x11, 0x6b, 0x7a, 0x59, 0x26, 0x91, 0x6a,
+ 0xc0, 0x4d, 0xe4, 0x59, 0x87, 0x7b, 0x19, 0x97, 0x19, 0xff, 0xeb, 0xb2,
+ 0x1a, 0x76, 0xf5, 0x57, 0xa0, 0x7e, 0x48, 0x62, 0x70, 0x05, 0x1e, 0xe9,
+ 0xf3, 0x62, 0xce, 0x7e, 0xd9, 0x87, 0x24, 0x2f, 0xec, 0xbb, 0x13, 0xc3,
+ 0x8e, 0x8f, 0x4f, 0xa3, 0x7f, 0x54, 0xa2, 0x76, 0x48, 0xae, 0xc9, 0x53,
+ 0x68, 0xb3, 0x0b, 0x0e, 0x55, 0x71, 0xbc, 0xb7, 0x62, 0xfe, 0xa1, 0x00,
+ 0xf1, 0xdc, 0x8f, 0x48, 0x76, 0xf9, 0x45, 0xc1, 0xe4, 0xed, 0x63, 0x53,
+ 0x63, 0x9a, 0xf8, 0xa1, 0x83, 0x61, 0x91, 0x3c, 0x86, 0x5d, 0x7e, 0x3e,
+ 0x15, 0x27, 0x7f, 0xcb, 0x67, 0x52, 0x26, 0x1f, 0x7b, 0xa6, 0xe2, 0xe2,
+ 0x65, 0x7c, 0x6a, 0x1c, 0x90, 0x6f, 0x0d, 0xed, 0xf3, 0xc4, 0xd7, 0xaf,
+ 0x43, 0xc4, 0x91, 0xe7, 0xfe, 0x62, 0x96, 0x0b, 0xe4, 0xfc, 0x7d, 0x2a,
+ 0x9e, 0xfb, 0x26, 0xfd, 0xd4, 0x85, 0x58, 0x45, 0x8e, 0x0b, 0xdf, 0xbe,
+ 0xa7, 0x01, 0xbb, 0xa8, 0x8f, 0x56, 0xfa, 0x91, 0x2f, 0x1c, 0xb5, 0xad,
+ 0x0a, 0xc9, 0x5b, 0x2b, 0x71, 0xe7, 0x1e, 0x3f, 0x63, 0xf8, 0xb5, 0x48,
+ 0x0e, 0xcf, 0x66, 0x5b, 0xd5, 0xe8, 0x9d, 0xcc, 0xe7, 0xb7, 0xa7, 0x96,
+ 0xd9, 0x0f, 0x39, 0x7b, 0xf2, 0xb2, 0xf6, 0xff, 0xda, 0x7d, 0xde, 0xd0,
+ 0xb8, 0xce, 0x7c, 0xde, 0x64, 0xce, 0x41, 0x0e, 0x76, 0x02, 0xa1, 0x4a,
+ 0xe6, 0xe7, 0x46, 0x39, 0x16, 0x31, 0x9f, 0x7f, 0xc8, 0x2f, 0xcf, 0x6e,
+ 0x15, 0x59, 0x9c, 0xf2, 0x97, 0xc7, 0xb8, 0x6b, 0xca, 0x18, 0xeb, 0x23,
+ 0xd3, 0x90, 0xe7, 0x63, 0x5f, 0xd8, 0x7f, 0x6f, 0x40, 0xe9, 0x0f, 0xd1,
+ 0x6a, 0x1b, 0x83, 0x7d, 0x0f, 0x29, 0x86, 0xd6, 0xa4, 0x12, 0xba, 0x46,
+ 0xdf, 0xc4, 0x92, 0xec, 0x2f, 0x10, 0xcb, 0xae, 0xf6, 0x8a, 0x2c, 0xf7,
+ 0x67, 0x57, 0x61, 0x9c, 0x73, 0x5c, 0xc4, 0x3a, 0x37, 0xf4, 0xfa, 0x68,
+ 0xa3, 0x50, 0x0e, 0x37, 0xd7, 0xe1, 0x43, 0xf2, 0x9c, 0xb6, 0xe4, 0x9b,
+ 0xd0, 0x18, 0x5f, 0xef, 0x4c, 0xfe, 0x02, 0x65, 0xc4, 0x94, 0x3b, 0x92,
+ 0x5f, 0xd8, 0x23, 0xa1, 0x7d, 0x4e, 0xbd, 0xc2, 0xd1, 0x03, 0x17, 0xfb,
+ 0x2e, 0xc7, 0x27, 0xad, 0xd0, 0x78, 0xe5, 0x2a, 0x3c, 0x6c, 0x68, 0xd9,
+ 0x9c, 0x18, 0xfd, 0x5f, 0x9e, 0xe8, 0xaf, 0x7f, 0xfa, 0xfd, 0xe6, 0x9c,
+ 0x5d, 0xea, 0x99, 0xbb, 0xf0, 0x2d, 0x07, 0x77, 0xd7, 0x6c, 0x74, 0x47,
+ 0x3b, 0x1e, 0x93, 0xb5, 0xd0, 0x35, 0xce, 0x3a, 0x41, 0x3b, 0x76, 0xee,
+ 0x6d, 0xc3, 0xe6, 0xbd, 0x82, 0xad, 0xf5, 0xad, 0x8b, 0x94, 0x19, 0xf4,
+ 0xc3, 0x01, 0x27, 0x97, 0x71, 0x1b, 0x9f, 0xca, 0x9a, 0xab, 0xea, 0x71,
+ 0xf6, 0xc0, 0x74, 0xac, 0x19, 0xcd, 0xb5, 0x35, 0x2b, 0x53, 0x4a, 0xff,
+ 0x8a, 0x22, 0xc9, 0x9c, 0xc5, 0xc7, 0xd8, 0xc9, 0x79, 0xc1, 0xa9, 0x7e,
+ 0x89, 0x3b, 0x0a, 0x7c, 0xf7, 0xc8, 0x5e, 0xe6, 0x32, 0xe4, 0xf9, 0x7a,
+ 0x4c, 0xdb, 0xcc, 0xdf, 0x3b, 0x8a, 0x73, 0x72, 0x6d, 0xbe, 0x8a, 0x17,
+ 0xe5, 0xed, 0x41, 0x74, 0x97, 0xb7, 0xa1, 0x4f, 0x39, 0x06, 0xe6, 0xd8,
+ 0xe4, 0x83, 0x97, 0xfd, 0xf9, 0x8b, 0x22, 0x67, 0x5d, 0x30, 0x3b, 0x35,
+ 0xbe, 0x6f, 0x9f, 0xd4, 0xfd, 0x75, 0xc5, 0xf9, 0xd8, 0x94, 0x93, 0xd7,
+ 0x24, 0x16, 0x5e, 0x83, 0x98, 0x3f, 0xef, 0xff, 0xdf, 0xe4, 0xf3, 0xcd,
+ 0x82, 0x01, 0x93, 0x75, 0xef, 0x2e, 0x41, 0xf1, 0x76, 0x87, 0xc3, 0x5d,
+ 0x6e, 0x9f, 0x64, 0xf8, 0x8a, 0xf6, 0xa7, 0xda, 0xaf, 0xb4, 0x2f, 0x71,
+ 0x5a, 0x74, 0xda, 0xc8, 0xba, 0xa2, 0x3f, 0x07, 0xa3, 0x65, 0x4d, 0x96,
+ 0xdc, 0xad, 0xcd, 0xd9, 0xa7, 0x29, 0x26, 0x6f, 0xee, 0x66, 0x0e, 0x55,
+ 0xb2, 0x9f, 0xd7, 0xe4, 0x3e, 0x4b, 0x07, 0x02, 0x28, 0xda, 0xef, 0x21,
+ 0xae, 0xcf, 0x80, 0x7b, 0x7f, 0x01, 0xed, 0x55, 0x38, 0xc2, 0x6b, 0xf7,
+ 0x6d, 0x31, 0xae, 0x85, 0x6b, 0x7f, 0x21, 0x79, 0xb9, 0x70, 0xbe, 0x13,
+ 0xf7, 0xad, 0x65, 0x1c, 0x57, 0xf7, 0x7b, 0x19, 0x9f, 0xab, 0xe1, 0x61,
+ 0xcc, 0x5b, 0x32, 0xf0, 0x67, 0x28, 0xd8, 0x5f, 0x8c, 0x07, 0x06, 0xae,
+ 0xc7, 0xcc, 0xfd, 0x25, 0xb8, 0x7f, 0x60, 0x26, 0x66, 0xec, 0x97, 0xdc,
+ 0x49, 0x47, 0x60, 0x7f, 0x29, 0x56, 0x0c, 0x04, 0x51, 0xb1, 0xbf, 0x0c,
+ 0x6d, 0x03, 0xb3, 0xa0, 0xed, 0x2f, 0xc7, 0x5d, 0x03, 0x35, 0x28, 0xdf,
+ 0xaf, 0xe1, 0xce, 0x01, 0x03, 0x65, 0xfb, 0x2b, 0x18, 0xd3, 0x42, 0x8c,
+ 0x9d, 0x7e, 0x2c, 0xdf, 0xc3, 0xb9, 0x39, 0x58, 0x45, 0xbf, 0x58, 0x45,
+ 0x4e, 0xbd, 0x1a, 0xfb, 0x52, 0x73, 0x50, 0x72, 0x30, 0x80, 0xa5, 0x7b,
+ 0xc6, 0x35, 0x52, 0x1a, 0x2c, 0x0e, 0x35, 0xa0, 0xe8, 0xa0, 0xe4, 0x7e,
+ 0xc1, 0x13, 0x2d, 0x08, 0x5e, 0x58, 0x84, 0x72, 0xe6, 0xbe, 0xc0, 0x7b,
+ 0x63, 0xc0, 0xec, 0x31, 0x17, 0x8e, 0x68, 0xab, 0xb0, 0x75, 0xec, 0x9b,
+ 0x93, 0x36, 0x2f, 0xfb, 0x47, 0xe5, 0x9c, 0x5f, 0xb9, 0x96, 0x7b, 0xab,
+ 0xd1, 0x33, 0x96, 0x5f, 0x07, 0x0b, 0xf6, 0x6d, 0xa7, 0x06, 0xc7, 0x33,
+ 0xf2, 0x4c, 0x7c, 0x04, 0xb4, 0x6f, 0xa5, 0x5b, 0xce, 0x8f, 0xbb, 0xa2,
+ 0x6a, 0x59, 0x77, 0xf3, 0x86, 0x5b, 0xe2, 0x99, 0x4d, 0xcc, 0xbb, 0x24,
+ 0x87, 0xdd, 0x78, 0xcb, 0x9a, 0xcc, 0x07, 0x97, 0xf6, 0x13, 0xfa, 0xcc,
+ 0x85, 0x01, 0x0d, 0x5f, 0xc3, 0x1a, 0x67, 0x0d, 0x55, 0xe5, 0x9c, 0xc9,
+ 0x79, 0x56, 0xe7, 0x2c, 0x39, 0xed, 0x2c, 0x0e, 0xd3, 0xc1, 0xd4, 0x75,
+ 0xa8, 0xc9, 0x38, 0x6b, 0xb5, 0x75, 0x71, 0xbc, 0xa0, 0xb6, 0x1a, 0xd6,
+ 0xe4, 0xd9, 0x0f, 0x6b, 0xbe, 0x86, 0x98, 0xa9, 0x5d, 0x3a, 0x1f, 0x12,
+ 0xd4, 0x47, 0x10, 0x0c, 0x6c, 0xc3, 0x3a, 0xe7, 0x7c, 0xa0, 0x12, 0x6d,
+ 0x97, 0x73, 0x46, 0xfc, 0x5e, 0x0d, 0x23, 0x93, 0x5f, 0x6b, 0x94, 0xb3,
+ 0xd7, 0xb2, 0x8f, 0x65, 0x33, 0xe7, 0x97, 0x3c, 0xf9, 0x88, 0xa2, 0xf6,
+ 0x3a, 0xeb, 0x63, 0xab, 0x5c, 0x8c, 0x01, 0x2d, 0x0a, 0xe2, 0x45, 0xd1,
+ 0x90, 0xfe, 0xe1, 0xe4, 0xba, 0x83, 0x67, 0x74, 0x8b, 0x52, 0x30, 0xda,
+ 0xa3, 0xb8, 0x47, 0x73, 0xeb, 0x0e, 0x2e, 0xf2, 0xd8, 0x6d, 0xa9, 0x4a,
+ 0x96, 0xd1, 0x30, 0x7b, 0xae, 0x1b, 0xaf, 0x26, 0xca, 0x9c, 0xb3, 0xc7,
+ 0x5b, 0xe7, 0x16, 0xe0, 0x11, 0xda, 0x7e, 0xeb, 0x8d, 0xc7, 0xf0, 0x41,
+ 0x86, 0x5c, 0x23, 0x61, 0x85, 0x87, 0xd9, 0xe7, 0xd1, 0x84, 0x8a, 0x17,
+ 0x07, 0xb7, 0x84, 0x87, 0x9c, 0xfe, 0xbf, 0x8d, 0xcd, 0x23, 0x92, 0x77,
+ 0xb5, 0xd9, 0xdb, 0x53, 0xed, 0xb6, 0xc4, 0xdd, 0x6c, 0xa2, 0x92, 0xb9,
+ 0xb9, 0x86, 0x0f, 0xe6, 0x6e, 0xc0, 0x39, 0x96, 0x19, 0x4d, 0x6c, 0xc4,
+ 0x27, 0xe4, 0x08, 0x99, 0xc4, 0x72, 0xbc, 0xc6, 0x5c, 0xf2, 0x7b, 0x89,
+ 0x56, 0xe6, 0x96, 0xab, 0xf0, 0xca, 0xa0, 0xf0, 0x8f, 0x16, 0x2c, 0x4c,
+ 0x28, 0x58, 0x1a, 0x5a, 0x85, 0x93, 0xc3, 0xcc, 0x29, 0x07, 0xe5, 0xbc,
+ 0xeb, 0x35, 0x58, 0x93, 0x3b, 0x0f, 0xc5, 0xe7, 0x31, 0x3e, 0x5f, 0x89,
+ 0xa3, 0xc3, 0x01, 0x1c, 0x60, 0x0e, 0xf9, 0x0e, 0x31, 0x64, 0x28, 0xd1,
+ 0x80, 0xd3, 0xcc, 0x95, 0x7e, 0x94, 0x88, 0xe0, 0x33, 0xfe, 0x3e, 0x92,
+ 0x90, 0xf5, 0xef, 0x66, 0x5c, 0xc8, 0xfc, 0x18, 0x05, 0xbd, 0x33, 0x70,
+ 0xbc, 0xed, 0x79, 0x52, 0xc9, 0x23, 0xfc, 0xb4, 0xe2, 0xf4, 0x70, 0x2b,
+ 0xce, 0x0c, 0x2e, 0xc3, 0x99, 0xe1, 0x5f, 0xe1, 0x83, 0x41, 0x91, 0x57,
+ 0xce, 0x2c, 0x3a, 0xef, 0x16, 0xb0, 0x5d, 0xe2, 0xd4, 0xf0, 0xbf, 0xa5,
+ 0xed, 0x8f, 0xec, 0xe3, 0xab, 0xa4, 0xdd, 0xe7, 0xff, 0x48, 0xdb, 0xa2,
+ 0x4b, 0x89, 0xf5, 0x5e, 0x9c, 0x4c, 0x78, 0x99, 0x57, 0x8d, 0xdf, 0x50,
+ 0x84, 0xf1, 0xf9, 0xcc, 0x36, 0xb1, 0x3d, 0x53, 0x88, 0x17, 0xfb, 0xdc,
+ 0xe4, 0x8a, 0x5f, 0x25, 0x7e, 0x74, 0xd2, 0x0e, 0x0b, 0x99, 0xbf, 0x79,
+ 0xa9, 0xe3, 0xf9, 0xc4, 0xfb, 0x55, 0xd4, 0x9f, 0x0f, 0xa7, 0x12, 0x7e,
+ 0xbc, 0x9e, 0xa8, 0x8f, 0x67, 0x95, 0x46, 0x58, 0x15, 0xb9, 0xbc, 0xf2,
+ 0x68, 0xa2, 0xc3, 0x91, 0xe9, 0xd5, 0x44, 0x9b, 0xbd, 0x95, 0x3a, 0xee,
+ 0x49, 0x7d, 0xdb, 0x39, 0x6f, 0xf8, 0x4a, 0xe2, 0x82, 0x2d, 0xe7, 0x88,
+ 0x9f, 0xa1, 0x4e, 0x4f, 0x26, 0xe2, 0x28, 0x62, 0x9e, 0x72, 0x2c, 0x31,
+ 0x8e, 0x61, 0xda, 0xe5, 0x3b, 0x7d, 0xc6, 0x89, 0x35, 0xd8, 0x84, 0xcf,
+ 0xd2, 0x85, 0x78, 0x8b, 0x7d, 0x94, 0x37, 0xb9, 0x31, 0xe1, 0xb4, 0xb7,
+ 0x09, 0x9f, 0xf4, 0x29, 0xc8, 0xcc, 0xdd, 0x84, 0x8f, 0xf9, 0xec, 0x0d,
+ 0x5e, 0x9f, 0x0b, 0x53, 0xc2, 0xc9, 0x67, 0x67, 0xfa, 0x54, 0x27, 0x07,
+ 0xee, 0x6e, 0xde, 0x84, 0xd3, 0xe9, 0x8f, 0x71, 0x80, 0xb9, 0xf4, 0x63,
+ 0xe6, 0x34, 0x44, 0xa6, 0x11, 0x70, 0x8d, 0x42, 0x9c, 0xe4, 0xf3, 0x5a,
+ 0x59, 0xef, 0xd1, 0x72, 0xe5, 0x3f, 0xe2, 0x78, 0x1e, 0x61, 0x5b, 0x67,
+ 0xd3, 0xdf, 0x61, 0xbb, 0xc2, 0x39, 0xbf, 0xc3, 0x76, 0x7f, 0x85, 0x91,
+ 0x49, 0x7d, 0x9c, 0x36, 0x65, 0x5c, 0x1b, 0x7c, 0x28, 0xf6, 0x73, 0x1c,
+ 0x0f, 0xf3, 0xbb, 0x03, 0x13, 0x99, 0x9d, 0xfc, 0x7e, 0x0d, 0x87, 0x33,
+ 0x12, 0xdb, 0xf3, 0x67, 0x87, 0x64, 0x7d, 0x4b, 0xfc, 0x47, 0x9f, 0x5c,
+ 0x97, 0x9b, 0x8e, 0x54, 0x7f, 0x59, 0x7c, 0x1a, 0xed, 0xe8, 0x3f, 0xcc,
+ 0x2b, 0xc7, 0x47, 0x61, 0x0b, 0xbb, 0x0e, 0xb8, 0x91, 0xea, 0x25, 0x9f,
+ 0xed, 0xad, 0xc4, 0x53, 0xbb, 0x35, 0x3c, 0xb9, 0xfb, 0x5a, 0x6c, 0xd9,
+ 0x7d, 0x3d, 0xf6, 0xed, 0xae, 0x46, 0x92, 0xb9, 0xf2, 0x27, 0x4d, 0xb6,
+ 0x3d, 0x87, 0x9f, 0x1d, 0xf4, 0x05, 0x2f, 0xbf, 0x5f, 0x0e, 0x8b, 0x9f,
+ 0x18, 0xb8, 0xd1, 0xf1, 0x97, 0x16, 0xdc, 0xe0, 0x7c, 0xc7, 0x30, 0x27,
+ 0xd3, 0x19, 0xde, 0x90, 0xdd, 0x14, 0x7e, 0x28, 0x3b, 0x1d, 0x5b, 0xfb,
+ 0xab, 0xd0, 0xbf, 0xbb, 0x32, 0x5e, 0xc9, 0x7e, 0x56, 0xce, 0xb3, 0x31,
+ 0xc4, 0xba, 0x66, 0x63, 0x4f, 0x78, 0x4d, 0xf6, 0x79, 0xb4, 0x65, 0xfd,
+ 0xd8, 0xdc, 0x1f, 0x60, 0x5f, 0xb2, 0x86, 0xef, 0x3e, 0xf1, 0x20, 0x6c,
+ 0xfb, 0x42, 0xd3, 0x11, 0xc6, 0xb7, 0x1f, 0xa3, 0x9d, 0xcf, 0x92, 0xfd,
+ 0x1b, 0xc8, 0xa9, 0x0a, 0xe2, 0xde, 0xa8, 0x8d, 0x53, 0xe1, 0x71, 0xdc,
+ 0xc1, 0xf6, 0x76, 0xf6, 0x97, 0x51, 0xa6, 0xe2, 0x78, 0x21, 0xef, 0x2d,
+ 0x0d, 0x6f, 0xc4, 0xae, 0x31, 0x59, 0x03, 0x3c, 0x81, 0xa5, 0xe4, 0x2c,
+ 0x15, 0x73, 0x7f, 0x56, 0x82, 0x32, 0xcd, 0x7d, 0xbe, 0x59, 0xec, 0x2f,
+ 0x4e, 0xfb, 0x13, 0xac, 0x5c, 0x87, 0xb5, 0xce, 0xd9, 0xc2, 0x76, 0xbc,
+ 0x94, 0x10, 0x9c, 0x5e, 0x8d, 0x83, 0x89, 0x75, 0xd8, 0x92, 0x92, 0x7d,
+ 0xc0, 0xe5, 0xa8, 0xc9, 0xfe, 0x55, 0x78, 0x3d, 0xe3, 0xa9, 0x2b, 0xfb,
+ 0x3f, 0xb0, 0x38, 0x9b, 0xa6, 0x5c, 0xc3, 0xe1, 0xb5, 0xd9, 0x7d, 0xe1,
+ 0x07, 0xb3, 0xad, 0x98, 0x95, 0x95, 0xf5, 0xb4, 0x36, 0xe2, 0xbb, 0xac,
+ 0xa7, 0x4d, 0x60, 0x61, 0xf6, 0x0c, 0x16, 0x65, 0xdf, 0x62, 0x2c, 0x16,
+ 0xdc, 0x90, 0x75, 0xb6, 0x5f, 0x31, 0x39, 0x91, 0x7d, 0xc3, 0xbf, 0xc4,
+ 0xd6, 0xbd, 0x71, 0xc6, 0xc2, 0x3c, 0x46, 0xd5, 0x6b, 0x07, 0x04, 0x5f,
+ 0xc6, 0x3c, 0x4e, 0x2c, 0xe8, 0x4b, 0xdd, 0x43, 0x7b, 0x54, 0xc9, 0xf3,
+ 0x25, 0xce, 0xac, 0xa3, 0x2f, 0x77, 0x92, 0x9f, 0x4b, 0xfc, 0xbb, 0x6b,
+ 0xf2, 0xbe, 0xf0, 0x3a, 0x89, 0x7d, 0x3a, 0x8e, 0x66, 0x9c, 0xbd, 0x0c,
+ 0xdd, 0x6b, 0xdc, 0xc1, 0x67, 0x52, 0xff, 0x2f, 0x91, 0xdc, 0xbb, 0xca,
+ 0xde, 0xe9, 0xac, 0x19, 0x29, 0x38, 0x1e, 0x62, 0x5f, 0xa4, 0x91, 0x4b,
+ 0xf7, 0xcb, 0x59, 0xce, 0x75, 0x72, 0x96, 0xd3, 0x72, 0x19, 0x6d, 0xf6,
+ 0x96, 0x14, 0x1e, 0x2c, 0x45, 0x00, 0xcb, 0x47, 0x0b, 0x10, 0x3b, 0x58,
+ 0x8c, 0xdb, 0x77, 0xb7, 0xd3, 0x96, 0x2d, 0xda, 0xaf, 0x61, 0xae, 0x55,
+ 0x8a, 0xb1, 0x84, 0xf7, 0x1e, 0xe8, 0x0f, 0xb6, 0x02, 0xa1, 0x13, 0xa7,
+ 0x5d, 0xc5, 0xb8, 0x9f, 0xb1, 0x23, 0x9d, 0x5e, 0x8e, 0xd8, 0xfe, 0xe3,
+ 0xb0, 0xd2, 0xb4, 0xc9, 0x3d, 0xc4, 0x99, 0xbd, 0x6e, 0xa8, 0xd1, 0x5f,
+ 0x61, 0xdf, 0xb0, 0x8a, 0xf2, 0x3d, 0x2f, 0xd8, 0x01, 0x43, 0x31, 0xce,
+ 0x85, 0xb2, 0xe4, 0x40, 0x6e, 0x94, 0x26, 0x5b, 0x30, 0x4a, 0xac, 0xf1,
+ 0x25, 0x63, 0xc8, 0x64, 0xda, 0x90, 0x26, 0x96, 0xa4, 0xc9, 0x9b, 0x4a,
+ 0x92, 0x26, 0x63, 0x79, 0x1d, 0x76, 0xd1, 0x5f, 0x0a, 0x98, 0xcb, 0x6f,
+ 0xcb, 0xdc, 0x0a, 0x6b, 0xf8, 0x4e, 0x6c, 0x1f, 0x6e, 0xe3, 0x87, 0xfc,
+ 0x71, 0xf8, 0xdb, 0x58, 0x38, 0x7a, 0x02, 0x3d, 0x99, 0x38, 0xed, 0xf1,
+ 0x63, 0x6c, 0x4f, 0x1f, 0xc3, 0x53, 0x7d, 0x5d, 0xcc, 0x11, 0x8e, 0xe1,
+ 0x49, 0x5e, 0xf7, 0xf5, 0x19, 0x9d, 0x01, 0xf5, 0x18, 0x52, 0xe9, 0x4d,
+ 0xb8, 0xb3, 0x5f, 0x61, 0x0e, 0xb7, 0x09, 0x77, 0xec, 0xa7, 0x2d, 0x3e,
+ 0xd1, 0x81, 0xd6, 0xd1, 0xd7, 0x90, 0xc8, 0xbc, 0xc4, 0xfc, 0x6a, 0x23,
+ 0x7a, 0x52, 0x1b, 0xc8, 0xbd, 0x9e, 0x67, 0x3b, 0x47, 0xe8, 0xe7, 0x9d,
+ 0x1c, 0xe3, 0xe3, 0xfc, 0x5c, 0xc2, 0x70, 0x4d, 0x57, 0xf2, 0x58, 0x4d,
+ 0xbf, 0x4f, 0x49, 0xee, 0xb0, 0x8e, 0x38, 0x71, 0x6f, 0x29, 0x8a, 0x45,
+ 0xbf, 0xf9, 0x35, 0x69, 0x99, 0x0b, 0xb1, 0x7d, 0x59, 0x9b, 0x76, 0xa3,
+ 0x28, 0x29, 0xeb, 0xd1, 0xe3, 0xc1, 0x22, 0x72, 0x00, 0x6f, 0x52, 0x74,
+ 0xd8, 0x6e, 0x77, 0xa7, 0x04, 0x4b, 0x72, 0xdc, 0xfc, 0xe5, 0xcc, 0xaf,
+ 0xb0, 0x75, 0x70, 0x1a, 0x16, 0xf5, 0x55, 0x23, 0xee, 0xb7, 0xed, 0xe7,
+ 0xe8, 0x6b, 0x09, 0xe6, 0x58, 0xbb, 0xfa, 0x63, 0xc4, 0x94, 0x12, 0xe4,
+ 0x72, 0x3d, 0xd1, 0x4d, 0xd0, 0xd4, 0xaf, 0xd8, 0x23, 0x99, 0xc5, 0x79,
+ 0x13, 0xee, 0x3a, 0x7e, 0x43, 0x29, 0xce, 0x97, 0xe4, 0xd6, 0xc5, 0xff,
+ 0xfc, 0x12, 0xb7, 0xf9, 0xd7, 0x95, 0xbf, 0xff, 0xdf, 0x58, 0x7e, 0x62,
+ 0xca, 0xd9, 0xb5, 0xfc, 0x7b, 0x39, 0x32, 0xd6, 0xeb, 0xe5, 0xdc, 0x9a,
+ 0x25, 0x7c, 0x49, 0xce, 0xdc, 0x1e, 0x4f, 0x14, 0x30, 0x4e, 0xaa, 0x0b,
+ 0x3c, 0x50, 0xfd, 0x1e, 0x14, 0x32, 0x9e, 0x55, 0x61, 0xb3, 0xdf, 0xc6,
+ 0x62, 0xb3, 0x00, 0x87, 0x1b, 0x62, 0x72, 0xce, 0xa2, 0xdd, 0xe3, 0xf0,
+ 0xd1, 0xd5, 0xf7, 0xfc, 0xe1, 0xba, 0xf5, 0x26, 0x72, 0x37, 0x39, 0x5f,
+ 0xd0, 0x86, 0x53, 0x15, 0xf2, 0xae, 0xd0, 0x26, 0xe7, 0xdc, 0x59, 0x51,
+ 0xad, 0xac, 0xa3, 0xe9, 0x38, 0x61, 0xd4, 0xeb, 0x95, 0x2a, 0xe3, 0xb9,
+ 0xf2, 0xae, 0x6d, 0xf9, 0xa3, 0x8c, 0xf5, 0x72, 0x86, 0xe2, 0x5f, 0xda,
+ 0xa7, 0x58, 0x83, 0xed, 0x4f, 0x34, 0x63, 0x62, 0x95, 0xc4, 0xff, 0xff,
+ 0xe6, 0xcb, 0x73, 0xba, 0x6d, 0xa9, 0x1f, 0x96, 0xca, 0xb9, 0x24, 0x69,
+ 0x7b, 0x3b, 0xf3, 0x27, 0x8f, 0x11, 0xc6, 0xbb, 0xc2, 0xd2, 0x9c, 0xfd,
+ 0xa4, 0x1c, 0xa7, 0x28, 0x34, 0xce, 0x4f, 0xbe, 0x3b, 0xf2, 0xd7, 0xa5,
+ 0xc2, 0x0f, 0xb7, 0xa5, 0x36, 0x91, 0x9b, 0x8b, 0x3c, 0xbf, 0xb7, 0xd7,
+ 0xf8, 0x2b, 0x59, 0xf6, 0xee, 0xc9, 0xf6, 0xc4, 0x16, 0xe4, 0x4c, 0x8e,
+ 0xdc, 0x93, 0x3a, 0xa2, 0xb3, 0xa9, 0x75, 0x5c, 0xcc, 0x85, 0x6f, 0xc0,
+ 0xa3, 0xf4, 0xc1, 0x99, 0xc6, 0xeb, 0x76, 0x97, 0x9c, 0x9f, 0xa9, 0xd5,
+ 0xa6, 0xf4, 0xf5, 0x0b, 0x47, 0x96, 0x42, 0xca, 0xd2, 0x9f, 0x92, 0xb3,
+ 0xa8, 0x9f, 0xd9, 0xb5, 0x55, 0xf2, 0xfc, 0xc2, 0x64, 0xfb, 0x35, 0xce,
+ 0xd9, 0xbe, 0x7d, 0xa9, 0xbc, 0xdc, 0xb2, 0xde, 0xea, 0xcf, 0xf7, 0x55,
+ 0x77, 0x79, 0x3c, 0x22, 0x5b, 0xbc, 0xf4, 0x4a, 0x99, 0xe1, 0xcb, 0x9f,
+ 0x59, 0x9d, 0xe1, 0xd4, 0xc9, 0xf7, 0x29, 0x32, 0x6e, 0x62, 0x9e, 0x7a,
+ 0xf5, 0x18, 0xb5, 0x29, 0x63, 0x92, 0x3a, 0x32, 0x2e, 0x6d, 0xd2, 0x0e,
+ 0x4a, 0xcb, 0x50, 0x2c, 0x75, 0x84, 0xbb, 0x6a, 0x0e, 0x07, 0x2f, 0x17,
+ 0x5e, 0x2e, 0xb6, 0x51, 0x66, 0xdb, 0xef, 0x39, 0x31, 0x53, 0xda, 0xe1,
+ 0x38, 0xc6, 0x56, 0xd1, 0xce, 0xed, 0x2e, 0xe2, 0xa7, 0xfd, 0x5e, 0x73,
+ 0x00, 0x5b, 0x13, 0xa2, 0x6b, 0x23, 0x70, 0x88, 0xd8, 0xb1, 0xd9, 0xe1,
+ 0x1b, 0x1e, 0x74, 0xa7, 0xf3, 0xfb, 0xa3, 0x85, 0x72, 0xf6, 0x36, 0x20,
+ 0x3a, 0xef, 0x36, 0xc9, 0xb3, 0xb4, 0x85, 0xba, 0x9b, 0x5c, 0x69, 0x3d,
+ 0xfe, 0x99, 0xf3, 0x2b, 0xe7, 0x8f, 0x73, 0x7b, 0x95, 0x71, 0xda, 0x51,
+ 0x2e, 0x5e, 0x81, 0xf1, 0x9d, 0x3c, 0x69, 0xf2, 0x5c, 0x66, 0x77, 0xe6,
+ 0x9f, 0xed, 0x71, 0xe7, 0x5c, 0xe6, 0xe5, 0x77, 0x3a, 0xd2, 0x9a, 0x6d,
+ 0x1f, 0xe0, 0xb3, 0xcb, 0x67, 0x34, 0x19, 0xd3, 0x0d, 0x39, 0xcb, 0xf9,
+ 0x4f, 0x9c, 0xbb, 0xa9, 0x65, 0xc7, 0x2b, 0x72, 0x67, 0x96, 0x63, 0xea,
+ 0x42, 0x23, 0x8f, 0xab, 0x41, 0xcb, 0x72, 0x70, 0xf5, 0x0e, 0x67, 0x0f,
+ 0x3e, 0x8d, 0x60, 0x6b, 0x1b, 0x2c, 0xbb, 0xd8, 0xc8, 0xe3, 0x80, 0x61,
+ 0xce, 0x51, 0xba, 0x30, 0x3b, 0x5c, 0x2c, 0x1c, 0x3b, 0xe8, 0x8e, 0x06,
+ 0xb5, 0x0f, 0x10, 0xaa, 0x3b, 0xe6, 0xec, 0x95, 0x0a, 0x36, 0x18, 0x58,
+ 0x9f, 0x21, 0xdf, 0x1e, 0x93, 0x77, 0x1d, 0xe5, 0xda, 0x69, 0x9f, 0xd7,
+ 0x82, 0xa5, 0xed, 0xc4, 0x52, 0xeb, 0xcf, 0x3d, 0x4e, 0x7b, 0xc1, 0xf6,
+ 0x61, 0x25, 0xd8, 0xba, 0x51, 0xc9, 0xb7, 0xe7, 0xfb, 0x92, 0xf6, 0xea,
+ 0x58, 0xbf, 0x7a, 0xf2, 0xfd, 0x42, 0x83, 0x6d, 0x5c, 0xbd, 0x9f, 0x3c,
+ 0x3d, 0x2e, 0x7b, 0x51, 0x87, 0x27, 0x39, 0xe1, 0xb1, 0x3f, 0xd8, 0x8b,
+ 0xfa, 0xd2, 0x3e, 0x63, 0xec, 0xb3, 0xb5, 0x58, 0x89, 0x91, 0x31, 0x74,
+ 0xa1, 0x30, 0x1c, 0xaa, 0x7b, 0x19, 0xd0, 0xdd, 0xd1, 0x50, 0x60, 0xd8,
+ 0xd9, 0xd3, 0x35, 0xbd, 0x8b, 0x9c, 0xfa, 0xd5, 0xe4, 0xc5, 0x7f, 0x5c,
+ 0x27, 0x25, 0x86, 0xd1, 0x56, 0xaf, 0xc4, 0xe6, 0x17, 0xb3, 0x9d, 0xba,
+ 0x30, 0xf4, 0x82, 0x68, 0x5e, 0x47, 0xa1, 0xba, 0x0f, 0x38, 0x9f, 0x47,
+ 0x9b, 0x43, 0x81, 0x21, 0xe7, 0x8c, 0xa7, 0xe8, 0xc5, 0xf4, 0xe6, 0xe6,
+ 0x5e, 0x17, 0xbe, 0xcd, 0x7c, 0x32, 0x8e, 0x91, 0x84, 0x97, 0x63, 0xa9,
+ 0xd7, 0xb6, 0xa3, 0x82, 0x36, 0x8e, 0xd8, 0xe6, 0x06, 0xe2, 0x77, 0x02,
+ 0x31, 0xd7, 0x8d, 0xe5, 0x88, 0x93, 0x40, 0xbb, 0x8c, 0x38, 0x39, 0x51,
+ 0x7d, 0xdd, 0x0e, 0xda, 0x6f, 0xda, 0x1f, 0x0c, 0x58, 0x88, 0xe3, 0xc5,
+ 0xc4, 0xc2, 0xff, 0xc7, 0x05, 0xcb, 0x2c, 0x81, 0xbc, 0x5f, 0x90, 0xbe,
+ 0x67, 0x59, 0x28, 0xa8, 0xbf, 0x32, 0xb9, 0x27, 0xdd, 0x9d, 0xf8, 0xad,
+ 0xbc, 0xc7, 0xc4, 0x7a, 0x7f, 0xac, 0x8c, 0xf4, 0xed, 0xc5, 0xa1, 0xbe,
+ 0x3e, 0x6c, 0x79, 0x82, 0x32, 0x1a, 0x36, 0x16, 0x9a, 0x5d, 0xcc, 0xa5,
+ 0x7d, 0x58, 0xa7, 0xcd, 0x8e, 0xa8, 0x2c, 0x37, 0x94, 0xce, 0xad, 0x3b,
+ 0x6e, 0x75, 0xf6, 0xbc, 0x7b, 0x98, 0xa3, 0x38, 0xf1, 0x53, 0xf3, 0x46,
+ 0x63, 0xca, 0xce, 0x4c, 0x8b, 0xb2, 0x23, 0x2d, 0x6d, 0x75, 0x2a, 0x3d,
+ 0x99, 0xbf, 0xa5, 0x4f, 0x58, 0x38, 0x6d, 0xca, 0xbb, 0x39, 0xd2, 0xae,
+ 0x85, 0xe1, 0xe6, 0x7f, 0xcd, 0x3b, 0x3a, 0xa2, 0xd3, 0x4e, 0x6c, 0x1e,
+ 0x7c, 0x1c, 0xdd, 0x83, 0xa7, 0x9c, 0x33, 0x46, 0x1e, 0xc3, 0x6b, 0x5d,
+ 0x1f, 0x0d, 0x1e, 0xb1, 0x90, 0x2d, 0x97, 0xf3, 0xf9, 0x55, 0xd1, 0x13,
+ 0xd8, 0xa9, 0xc9, 0xbb, 0x27, 0x3d, 0xe4, 0x11, 0xb2, 0x6f, 0xbb, 0x1a,
+ 0x5f, 0xef, 0x95, 0x39, 0x2c, 0xb3, 0x0a, 0xa3, 0xc1, 0xd8, 0x3a, 0x67,
+ 0x0e, 0x1b, 0x70, 0x32, 0xfb, 0x38, 0xde, 0xdb, 0xd3, 0x05, 0x35, 0x1c,
+ 0x0c, 0xdc, 0x06, 0xbb, 0xeb, 0xb8, 0x19, 0xb3, 0x3c, 0x08, 0x1e, 0x76,
+ 0xa9, 0xc0, 0x0b, 0x7b, 0xe0, 0x9d, 0xc1, 0xf9, 0x9f, 0xcf, 0x18, 0x5d,
+ 0x6e, 0xd8, 0x0b, 0xfe, 0xb1, 0x29, 0xd8, 0x63, 0xb8, 0xac, 0xbf, 0x99,
+ 0x8e, 0x60, 0x5f, 0x44, 0x35, 0xda, 0xef, 0x52, 0xa1, 0xf8, 0xa2, 0xf2,
+ 0x5e, 0x69, 0x17, 0xee, 0x6c, 0xf4, 0x59, 0xa5, 0xd1, 0x60, 0xdf, 0x29,
+ 0x25, 0x58, 0x67, 0xa9, 0x6d, 0x9c, 0xe7, 0x3a, 0xbc, 0x42, 0x0e, 0xd2,
+ 0xca, 0xd8, 0xbb, 0x34, 0xa9, 0x3b, 0xeb, 0x4c, 0xaa, 0x51, 0x13, 0x29,
+ 0x52, 0x34, 0xdc, 0x96, 0x05, 0x8e, 0xa6, 0x57, 0xe3, 0x9d, 0x3d, 0x26,
+ 0xf3, 0x54, 0x9d, 0xb8, 0xf5, 0xbd, 0x32, 0xc1, 0x80, 0x0e, 0xd3, 0xaa,
+ 0x57, 0x19, 0xfb, 0x3d, 0x2a, 0x16, 0xce, 0x8c, 0x86, 0xc6, 0x17, 0xb8,
+ 0xdc, 0x88, 0x64, 0x65, 0xfd, 0x53, 0x97, 0xb3, 0xc9, 0xb8, 0x2b, 0xe9,
+ 0x25, 0xff, 0xac, 0xc6, 0x6f, 0xc8, 0x83, 0x7f, 0x4d, 0xbe, 0x3b, 0xc1,
+ 0x78, 0x3e, 0x91, 0x29, 0x66, 0xbe, 0xe8, 0x91, 0x1c, 0x78, 0xdc, 0xc3,
+ 0xb9, 0x28, 0x6b, 0xf4, 0xe3, 0xdc, 0xb0, 0x17, 0x77, 0xec, 0x09, 0xee,
+ 0x9b, 0x50, 0xab, 0xf0, 0xc9, 0x70, 0x31, 0x96, 0x0f, 0x78, 0x29, 0x9b,
+ 0x8d, 0x5d, 0xc4, 0xff, 0x8f, 0xf8, 0xac, 0x65, 0x0f, 0x94, 0xcc, 0xdc,
+ 0x59, 0xe4, 0xec, 0x06, 0xeb, 0x97, 0x60, 0xd9, 0x80, 0xf0, 0x34, 0x15,
+ 0x1f, 0x0e, 0x2b, 0xf8, 0x20, 0x6d, 0x62, 0x21, 0xfb, 0xdb, 0x9c, 0x7a,
+ 0xc1, 0xf6, 0xd2, 0xcf, 0xd7, 0x64, 0x4c, 0x3c, 0x98, 0xd6, 0x19, 0x53,
+ 0xde, 0xb6, 0x5d, 0x46, 0x23, 0xde, 0xde, 0x6d, 0x9c, 0x78, 0xd7, 0x15,
+ 0x1a, 0x9f, 0xeb, 0x6a, 0xc4, 0x5b, 0x07, 0x1b, 0xf1, 0xb3, 0xfe, 0x05,
+ 0xb8, 0xb9, 0x31, 0x86, 0xf3, 0x73, 0x1b, 0xf1, 0xe6, 0x7e, 0x1d, 0x3b,
+ 0x52, 0xcd, 0xd0, 0x47, 0xc7, 0xc9, 0x4f, 0x23, 0xa8, 0x67, 0x4e, 0x65,
+ 0xf4, 0xdb, 0x5d, 0x25, 0xd1, 0x2e, 0xec, 0x34, 0xa3, 0x98, 0xb3, 0x5f,
+ 0xf4, 0x60, 0xdb, 0xeb, 0xe6, 0x46, 0xf1, 0x72, 0x9f, 0x41, 0x3f, 0x8d,
+ 0x52, 0x0f, 0x3a, 0x9e, 0x24, 0x36, 0x87, 0x9e, 0x30, 0x2e, 0x1c, 0xe0,
+ 0xef, 0x05, 0x07, 0x9a, 0xd1, 0xce, 0xfe, 0x13, 0xa9, 0x18, 0xf6, 0x8d,
+ 0x36, 0x70, 0xcc, 0x26, 0xc7, 0x5f, 0x63, 0xfd, 0x46, 0x69, 0x41, 0xdf,
+ 0x68, 0x2b, 0xf9, 0x66, 0x17, 0x79, 0x66, 0x2b, 0x7a, 0xd9, 0xd6, 0xd6,
+ 0x94, 0x89, 0x65, 0xc9, 0x56, 0x3c, 0x9d, 0x90, 0x33, 0x8d, 0x46, 0x64,
+ 0x9e, 0x22, 0xef, 0x7d, 0xb5, 0xe2, 0x10, 0x75, 0xb2, 0x70, 0x60, 0x39,
+ 0xed, 0xd0, 0x8b, 0x45, 0x7b, 0x74, 0x3c, 0x95, 0xba, 0x13, 0xef, 0x8c,
+ 0x98, 0x68, 0x4b, 0x8a, 0xbe, 0xe5, 0x5c, 0x4d, 0x1c, 0xc7, 0x19, 0x5b,
+ 0x7e, 0x33, 0x10, 0xfb, 0x1b, 0x4e, 0xf3, 0x49, 0x15, 0xc1, 0xce, 0x19,
+ 0x9c, 0xf0, 0x9b, 0x1a, 0xe5, 0x6c, 0x94, 0x8b, 0xa8, 0x16, 0xb4, 0xca,
+ 0x55, 0x4b, 0xe7, 0x7d, 0xcb, 0xad, 0x6e, 0xc2, 0x37, 0x06, 0xdc, 0xe4,
+ 0xf4, 0x2a, 0x73, 0x11, 0xab, 0x83, 0xb6, 0x61, 0x95, 0xa9, 0xb9, 0x79,
+ 0xdb, 0x2e, 0xef, 0xa1, 0x19, 0x2e, 0xec, 0x32, 0x6b, 0xda, 0x4a, 0x58,
+ 0x6f, 0x69, 0x38, 0x18, 0x2b, 0x52, 0x9b, 0x99, 0x27, 0x3e, 0x8e, 0x75,
+ 0x7b, 0x1e, 0xc7, 0x1a, 0x7e, 0x3a, 0xf6, 0xd8, 0x5d, 0x4b, 0x4c, 0x05,
+ 0x2f, 0x1a, 0x76, 0x57, 0x97, 0x69, 0x70, 0x6e, 0x65, 0x5e, 0x1f, 0x47,
+ 0xe7, 0xa1, 0xc7, 0xf1, 0x28, 0xed, 0xab, 0x92, 0x7e, 0xbc, 0x32, 0x69,
+ 0x77, 0xdd, 0xdc, 0x58, 0x87, 0x4f, 0x9d, 0xfc, 0x43, 0xec, 0x75, 0xab,
+ 0x93, 0x13, 0xa7, 0x55, 0xb9, 0xde, 0xed, 0x5c, 0x5b, 0xea, 0x2b, 0x65,
+ 0xf9, 0xd8, 0xf2, 0x5b, 0xb6, 0xfb, 0xbb, 0x3d, 0xe5, 0x78, 0xa2, 0x52,
+ 0xe2, 0x87, 0xac, 0xed, 0x42, 0x31, 0xe6, 0x32, 0xcf, 0x7a, 0xe2, 0x38,
+ 0xb6, 0x93, 0xb7, 0xf9, 0xc3, 0x92, 0x03, 0xd7, 0x9b, 0x5b, 0xd4, 0x5b,
+ 0x89, 0xed, 0x0a, 0x76, 0xd6, 0xf6, 0xa1, 0x97, 0xbe, 0xba, 0xab, 0x36,
+ 0x18, 0xef, 0x45, 0xd4, 0xde, 0x35, 0xbd, 0xe7, 0xdf, 0xf0, 0x5e, 0x96,
+ 0xbc, 0xb7, 0x9d, 0x7f, 0x37, 0xeb, 0x71, 0x74, 0xed, 0x91, 0xf9, 0x7f,
+ 0x1c, 0x8f, 0x51, 0xfe, 0xce, 0x81, 0xc7, 0xf1, 0x4d, 0xda, 0x4e, 0x45,
+ 0xd3, 0xd1, 0xc7, 0x2a, 0x30, 0xbb, 0xaf, 0x1c, 0xe3, 0x0f, 0x57, 0xca,
+ 0x39, 0x28, 0x62, 0x62, 0xaf, 0xf2, 0x38, 0xd6, 0x0f, 0x1d, 0xa0, 0x2f,
+ 0x3a, 0xfe, 0x47, 0x2c, 0xce, 0xc7, 0xab, 0x00, 0xd6, 0x11, 0x93, 0x73,
+ 0xb8, 0xee, 0xc7, 0x9a, 0xc4, 0x61, 0xc7, 0xf7, 0x0b, 0xa2, 0xab, 0xe8,
+ 0xf7, 0x6d, 0xf4, 0xfb, 0xe5, 0xf4, 0xfb, 0x56, 0xfa, 0x7d, 0x0b, 0xfd,
+ 0x3e, 0x46, 0xbf, 0x8f, 0xd2, 0xef, 0x23, 0xf4, 0xfb, 0x66, 0xfa, 0xbd,
+ 0x49, 0xbf, 0x87, 0x72, 0xa2, 0xf9, 0x38, 0x3c, 0xfd, 0x5e, 0xda, 0x50,
+ 0xee, 0x3d, 0x99, 0x83, 0xc4, 0x9f, 0xd3, 0xe6, 0x9c, 0xc0, 0x62, 0xc6,
+ 0xd5, 0x61, 0x62, 0x44, 0x7a, 0xe4, 0xaf, 0x9c, 0x77, 0x2a, 0xd2, 0xc4,
+ 0xfd, 0x57, 0xa8, 0x8f, 0xa5, 0xe1, 0x1a, 0xf3, 0x69, 0xc6, 0xb0, 0x5f,
+ 0x18, 0xf5, 0x3d, 0x7e, 0x96, 0xf9, 0x41, 0xaa, 0xbe, 0x6f, 0x1a, 0x0c,
+ 0xab, 0x51, 0xdd, 0x0a, 0xac, 0xf4, 0x73, 0xcc, 0x72, 0xde, 0x6e, 0x25,
+ 0x1e, 0x1b, 0x6c, 0xc3, 0x7f, 0x19, 0xd4, 0xa8, 0x8b, 0x9a, 0xf1, 0x5b,
+ 0x5d, 0xf8, 0x71, 0x00, 0x2e, 0xff, 0x35, 0xc0, 0xe7, 0x55, 0x98, 0x73,
+ 0x58, 0xde, 0xef, 0x4b, 0x57, 0xb9, 0x1a, 0x66, 0x42, 0x6c, 0x04, 0x44,
+ 0x6a, 0x17, 0x33, 0xc1, 0x39, 0xce, 0x3b, 0x40, 0xb1, 0x55, 0x82, 0xe9,
+ 0x45, 0xd8, 0x5a, 0xe7, 0xe0, 0xec, 0xb3, 0x72, 0x6e, 0xb0, 0x8a, 0x78,
+ 0xe4, 0x8b, 0xb6, 0x62, 0x5b, 0xaf, 0x75, 0x7f, 0x15, 0x96, 0xa3, 0xa7,
+ 0x37, 0xa7, 0x83, 0x87, 0xc3, 0x1a, 0xa9, 0x42, 0x48, 0x9f, 0xa3, 0xc0,
+ 0xdd, 0xd1, 0x1c, 0xc1, 0x83, 0x99, 0x04, 0xfa, 0x38, 0xc6, 0x0d, 0xf4,
+ 0xb3, 0x75, 0x7f, 0xfa, 0xdd, 0x4e, 0x7c, 0x33, 0xa1, 0xd3, 0xfe, 0x2f,
+ 0xda, 0xe9, 0x8a, 0x39, 0x7d, 0x55, 0x30, 0x3a, 0x57, 0xa8, 0xf3, 0x98,
+ 0xd3, 0x06, 0x8f, 0xc8, 0xc2, 0xf7, 0xf4, 0xa8, 0xd7, 0xaa, 0x20, 0x36,
+ 0xcf, 0x1a, 0x80, 0x32, 0x9c, 0x94, 0xf7, 0x20, 0xba, 0xf0, 0xff, 0x99,
+ 0x6d, 0x8e, 0xfd, 0x8c, 0xbb, 0x34, 0xcc, 0x4c, 0xca, 0x7d, 0x7b, 0xc1,
+ 0x67, 0x4d, 0xc1, 0x3a, 0xdd, 0xb5, 0x81, 0xf7, 0xab, 0xf1, 0x23, 0xc6,
+ 0xd9, 0xc0, 0xc0, 0x02, 0xa8, 0x4d, 0x5e, 0xdc, 0xdd, 0x50, 0x8a, 0xf8,
+ 0x4a, 0xe1, 0xa1, 0x92, 0xef, 0xbb, 0xa9, 0xcf, 0xff, 0x17, 0x0f, 0x99,
+ 0xcf, 0x61, 0xc2, 0x9f, 0x70, 0xf6, 0xdd, 0xd7, 0x99, 0x77, 0x28, 0x16,
+ 0xaf, 0xb7, 0xa5, 0x2c, 0x6c, 0x30, 0x99, 0x0b, 0xdd, 0x53, 0xc9, 0x9c,
+ 0x44, 0xca, 0x4b, 0xbb, 0x5b, 0x9d, 0xf6, 0x0e, 0xa6, 0xe4, 0x7a, 0xf7,
+ 0x64, 0x9f, 0x77, 0x01, 0x95, 0x5e, 0xe2, 0xad, 0x82, 0x33, 0xb5, 0x09,
+ 0xfa, 0x34, 0x7e, 0xec, 0x46, 0x4d, 0xba, 0x5f, 0x75, 0xfd, 0xf8, 0x1a,
+ 0xcc, 0x31, 0x7f, 0xaf, 0xca, 0x7c, 0xc4, 0xf0, 0x54, 0x48, 0x41, 0xa5,
+ 0x61, 0x9c, 0xff, 0x19, 0x7d, 0x6b, 0xc2, 0x95, 0xc0, 0x53, 0x63, 0xa7,
+ 0xec, 0xf1, 0x6b, 0xfc, 0x9c, 0x73, 0xa9, 0xdb, 0x86, 0x0f, 0x06, 0x65,
+ 0xce, 0x64, 0x9d, 0x9f, 0xb1, 0x5d, 0xd5, 0x51, 0xca, 0x7b, 0xa7, 0x87,
+ 0x4d, 0xe6, 0x3a, 0x6d, 0xf8, 0xc7, 0xc1, 0x95, 0xf8, 0xfd, 0x60, 0x4d,
+ 0xdb, 0x7f, 0x52, 0x6d, 0x7b, 0x69, 0xf8, 0x6b, 0xf8, 0x65, 0xa5, 0x86,
+ 0xa7, 0x69, 0x43, 0xbf, 0x4f, 0x58, 0x4b, 0xaf, 0x21, 0x16, 0xfc, 0xef,
+ 0x44, 0xf0, 0xc2, 0x49, 0x67, 0x5f, 0xa9, 0xde, 0xfc, 0xd0, 0x15, 0x8c,
+ 0x9f, 0x51, 0x83, 0xd6, 0x36, 0x65, 0x39, 0xec, 0x4c, 0x2b, 0xce, 0x67,
+ 0xa6, 0xda, 0x42, 0x97, 0x8d, 0x2a, 0xb1, 0x03, 0xb1, 0x07, 0xda, 0x22,
+ 0x73, 0xb9, 0x9f, 0x92, 0x47, 0x77, 0x7f, 0x95, 0xf6, 0x98, 0xa2, 0x3d,
+ 0xa6, 0x68, 0x8f, 0xc4, 0xa4, 0xe7, 0x89, 0x55, 0x3f, 0x48, 0xd1, 0x1e,
+ 0xe9, 0x3f, 0xcf, 0xd1, 0x7f, 0x72, 0x5c, 0xb9, 0xdd, 0x39, 0xb7, 0xf6,
+ 0x06, 0x63, 0x62, 0xe2, 0x09, 0x79, 0x27, 0xad, 0x66, 0x43, 0x16, 0xc1,
+ 0xf6, 0x5e, 0xe5, 0xb3, 0x72, 0x39, 0x67, 0xfb, 0xed, 0x90, 0xf8, 0x40,
+ 0x6e, 0x3f, 0xe0, 0xc8, 0xc8, 0x63, 0x65, 0xf2, 0x7e, 0xd4, 0xc1, 0xbd,
+ 0xff, 0x92, 0xce, 0xfe, 0x3b, 0xe5, 0x10, 0x7d, 0xfd, 0x5b, 0xc7, 0x2e,
+ 0xba, 0xfc, 0x1b, 0xfb, 0x97, 0x55, 0x32, 0xfe, 0x55, 0xf8, 0x62, 0xb0,
+ 0x05, 0xe7, 0x19, 0x7f, 0xdf, 0x6a, 0x1a, 0xef, 0x0c, 0x20, 0xd8, 0x51,
+ 0xae, 0x46, 0x91, 0xcd, 0xb4, 0xe0, 0xb3, 0x44, 0x14, 0x07, 0x12, 0x35,
+ 0xed, 0x35, 0xae, 0xb3, 0x6a, 0x7c, 0x86, 0x58, 0x54, 0x0c, 0x9f, 0x92,
+ 0x5f, 0x2e, 0xac, 0x8d, 0x60, 0x88, 0x6d, 0x7a, 0xa2, 0x1a, 0x46, 0x9a,
+ 0xc5, 0x56, 0x73, 0xef, 0x4e, 0xfd, 0xa9, 0xbf, 0x2e, 0xda, 0xe3, 0x7b,
+ 0x4d, 0x17, 0xed, 0x71, 0xcd, 0x6b, 0x69, 0xf4, 0xe1, 0xd2, 0x3d, 0xf2,
+ 0x6e, 0xa9, 0xf8, 0xb3, 0x82, 0x1f, 0x84, 0xc7, 0xdb, 0xa6, 0x21, 0xf8,
+ 0xec, 0x7d, 0xb4, 0xf5, 0x93, 0x49, 0x59, 0x53, 0x6c, 0xc1, 0xfb, 0x2c,
+ 0xef, 0xa6, 0x5f, 0x9c, 0xcc, 0xb8, 0xdd, 0xbf, 0x4c, 0x2a, 0xcc, 0x4b,
+ 0x97, 0xe3, 0x97, 0x99, 0x37, 0xd5, 0x8f, 0x35, 0x13, 0x67, 0xb2, 0x2b,
+ 0x69, 0x4f, 0x92, 0xff, 0xc7, 0x98, 0xff, 0x07, 0x3b, 0x8f, 0x60, 0x25,
+ 0xca, 0x0f, 0xad, 0x42, 0xd9, 0x1e, 0xe2, 0x67, 0x88, 0xf9, 0x3f, 0xaf,
+ 0x67, 0xec, 0x91, 0xf7, 0x0d, 0xca, 0xed, 0xed, 0xab, 0x44, 0x2f, 0x82,
+ 0x27, 0x7f, 0x57, 0x8e, 0xb2, 0x55, 0xc0, 0x21, 0xa9, 0x67, 0xb0, 0xde,
+ 0x4a, 0x54, 0xee, 0xa9, 0x89, 0x2c, 0x46, 0xcd, 0xf9, 0xdb, 0xd4, 0x95,
+ 0xb8, 0xfe, 0xd0, 0x3f, 0x73, 0x0e, 0xa4, 0x6c, 0x35, 0x9e, 0xa0, 0xdd,
+ 0x16, 0x92, 0x13, 0xb6, 0x24, 0x7f, 0x6d, 0xcf, 0xa4, 0x2f, 0x7e, 0xf6,
+ 0x15, 0x60, 0x5d, 0xd6, 0x60, 0xbc, 0x2b, 0x46, 0x7c, 0xe8, 0x29, 0xbb,
+ 0x3c, 0xea, 0xc6, 0x9a, 0x6c, 0x03, 0x16, 0x0f, 0xd8, 0xf6, 0xb9, 0xb9,
+ 0x31, 0xf8, 0xa2, 0x3e, 0x62, 0x98, 0x0f, 0x8f, 0x26, 0x4b, 0xf8, 0x2d,
+ 0xc7, 0x4f, 0x42, 0xe3, 0xb3, 0x55, 0x63, 0xc3, 0x0c, 0x97, 0xd1, 0x9e,
+ 0x55, 0x24, 0xee, 0xfb, 0xf0, 0x08, 0xe3, 0xf3, 0xd2, 0x64, 0x00, 0xf1,
+ 0xac, 0x6d, 0xbf, 0xd9, 0xec, 0xc7, 0xc3, 0xac, 0xdf, 0x9a, 0xec, 0x41,
+ 0x37, 0xed, 0x22, 0x7e, 0xc8, 0xd0, 0x35, 0xc6, 0xfb, 0x75, 0x59, 0x2f,
+ 0x63, 0x58, 0x25, 0x6e, 0x63, 0x2c, 0x7a, 0x54, 0xce, 0xca, 0xd0, 0x07,
+ 0xdf, 0x31, 0xad, 0x1b, 0x5c, 0x30, 0xd0, 0x99, 0xf5, 0x63, 0x79, 0x32,
+ 0x78, 0x41, 0xde, 0xcd, 0xfb, 0xcc, 0xac, 0xc3, 0xc6, 0x6c, 0x00, 0xb7,
+ 0x27, 0x8f, 0x3e, 0x3a, 0x13, 0xd6, 0x7f, 0x9e, 0x81, 0x06, 0x7c, 0x3d,
+ 0x5b, 0xcd, 0xf6, 0x83, 0x1b, 0xde, 0x50, 0xaa, 0xf1, 0x8d, 0x43, 0x26,
+ 0xdb, 0x57, 0xb1, 0x8c, 0xed, 0x2c, 0x49, 0x5e, 0x8f, 0x47, 0x0e, 0x35,
+ 0xe3, 0xc1, 0x6c, 0x13, 0x16, 0x31, 0x3e, 0x75, 0x30, 0x37, 0xc4, 0xbd,
+ 0xc0, 0xed, 0x03, 0xa2, 0x7b, 0x28, 0x6f, 0x36, 0x8f, 0x33, 0x5f, 0x36,
+ 0x41, 0x43, 0x74, 0xf6, 0x92, 0x77, 0xd2, 0x56, 0x6f, 0xdf, 0xdf, 0x84,
+ 0xa5, 0x03, 0x2a, 0x6a, 0xc2, 0x85, 0x88, 0xb7, 0x29, 0x68, 0x19, 0x90,
+ 0x38, 0x2b, 0xdc, 0xc6, 0x64, 0x5c, 0x0d, 0xb1, 0x0f, 0x93, 0x71, 0x35,
+ 0x77, 0xbf, 0x3b, 0x25, 0x6b, 0x0b, 0x6f, 0x93, 0x2f, 0x85, 0xd1, 0xe2,
+ 0xc4, 0x68, 0x59, 0x13, 0xb7, 0xe0, 0x66, 0xec, 0x0e, 0xd3, 0xc6, 0x17,
+ 0x34, 0x4a, 0xac, 0xd6, 0x9d, 0xbd, 0xa9, 0xb1, 0x7e, 0xa3, 0xe3, 0x82,
+ 0x42, 0xfb, 0xda, 0x2f, 0x31, 0xd1, 0x8f, 0x8d, 0xc9, 0x28, 0xde, 0xe9,
+ 0x63, 0xbc, 0xb9, 0x31, 0xb6, 0xb4, 0x04, 0x86, 0xf9, 0x08, 0x42, 0xd6,
+ 0x49, 0xc6, 0xf6, 0xf3, 0xe9, 0x4a, 0x2c, 0xde, 0x23, 0x65, 0x1a, 0xf1,
+ 0xee, 0xb0, 0xec, 0x4d, 0x6e, 0xc2, 0x53, 0x7d, 0x2e, 0x0c, 0x99, 0x35,
+ 0x3d, 0x2a, 0xe3, 0xe7, 0xfc, 0xc6, 0xa0, 0xf6, 0x23, 0x72, 0xd5, 0x0b,
+ 0x4d, 0x8c, 0xca, 0xd7, 0x34, 0xa3, 0x85, 0x72, 0xb5, 0x18, 0xe2, 0x93,
+ 0x16, 0x1e, 0x6c, 0xde, 0x84, 0x93, 0x7d, 0x86, 0xf5, 0xb4, 0xac, 0x03,
+ 0x34, 0xf2, 0xf9, 0x74, 0x37, 0x36, 0x1b, 0xc2, 0x69, 0x75, 0xfa, 0x16,
+ 0x59, 0xa7, 0xd1, 0x8c, 0x77, 0x68, 0xaf, 0x3d, 0xe9, 0x05, 0x8c, 0xfd,
+ 0x12, 0xf3, 0xbd, 0x56, 0x80, 0xf5, 0xca, 0xbf, 0xa2, 0xe0, 0xf4, 0x01,
+ 0xe1, 0x58, 0x0b, 0x70, 0xff, 0x80, 0xec, 0x0b, 0xa8, 0x98, 0x7f, 0x68,
+ 0x35, 0xce, 0xed, 0xce, 0x71, 0xae, 0x37, 0xc3, 0xd6, 0xd7, 0xc9, 0xb9,
+ 0xda, 0x4b, 0xc9, 0xb9, 0xc8, 0xe5, 0xea, 0x36, 0x2a, 0x6e, 0x84, 0xb2,
+ 0x11, 0xf2, 0x0a, 0xe1, 0x17, 0x01, 0x3c, 0x93, 0x69, 0xc6, 0x6d, 0xc9,
+ 0x6a, 0x8c, 0x90, 0x6f, 0xa5, 0x89, 0x17, 0xe9, 0x0c, 0xe3, 0xca, 0x70,
+ 0x15, 0x3f, 0x3a, 0x3f, 0xb3, 0xf8, 0x31, 0x9c, 0x7b, 0x6b, 0x68, 0xcb,
+ 0xb1, 0x36, 0xc5, 0xd9, 0xdb, 0x18, 0xca, 0x48, 0xac, 0x56, 0x98, 0xb7,
+ 0xde, 0xa5, 0x49, 0x6e, 0x2a, 0xe7, 0x0e, 0x7e, 0xde, 0xa7, 0xe3, 0x5b,
+ 0x8d, 0x3b, 0x95, 0x58, 0xa5, 0xf3, 0x5e, 0x92, 0x55, 0x4c, 0xd9, 0x6e,
+ 0x9b, 0x2b, 0x6b, 0x94, 0x62, 0x97, 0x6c, 0x83, 0x39, 0xfa, 0xc3, 0x66,
+ 0x05, 0xf4, 0x0a, 0x5d, 0xce, 0x50, 0xd2, 0xdf, 0xfd, 0x78, 0x35, 0x11,
+ 0x47, 0x26, 0x51, 0xdf, 0xb3, 0x51, 0x71, 0xc9, 0xd9, 0xf3, 0xba, 0xb8,
+ 0x22, 0x3e, 0x16, 0x87, 0x27, 0xe9, 0xb5, 0xca, 0x59, 0xff, 0x9d, 0xb9,
+ 0x1d, 0x8c, 0x07, 0xf5, 0x9c, 0x62, 0xd5, 0x39, 0x7f, 0x9e, 0x46, 0x07,
+ 0xd6, 0x25, 0x0c, 0xc6, 0xc0, 0xd5, 0x76, 0x37, 0xe7, 0xe1, 0x58, 0xa2,
+ 0x03, 0xf7, 0x27, 0xea, 0xc7, 0x9f, 0xa4, 0x6d, 0xe1, 0xee, 0x0e, 0xb4,
+ 0xf0, 0xd9, 0x50, 0xaa, 0xe6, 0x42, 0x37, 0x75, 0x3d, 0x31, 0xad, 0xce,
+ 0x59, 0x97, 0x77, 0x1b, 0x3a, 0xcb, 0xeb, 0xc4, 0xb3, 0xfa, 0xd8, 0x80,
+ 0xfa, 0xef, 0x15, 0x4c, 0x97, 0x5c, 0x32, 0x82, 0xe3, 0x09, 0x1f, 0xbe,
+ 0x9e, 0xb4, 0xe8, 0x03, 0xc0, 0xfa, 0x6c, 0x33, 0xf3, 0x88, 0xa7, 0xec,
+ 0x0a, 0x87, 0xeb, 0xba, 0x69, 0x83, 0x0b, 0x70, 0x82, 0xb1, 0xb7, 0x66,
+ 0x9e, 0xa1, 0x2d, 0x52, 0xe4, 0x7d, 0xeb, 0x5f, 0xdb, 0xee, 0x68, 0x09,
+ 0x36, 0x0c, 0x85, 0x22, 0x2b, 0x19, 0x67, 0x9f, 0x6a, 0x36, 0xc6, 0x6d,
+ 0xc6, 0xc0, 0x19, 0xd1, 0x04, 0xe7, 0x3a, 0x24, 0xff, 0xaf, 0x03, 0x7f,
+ 0x41, 0x3b, 0xff, 0x24, 0x21, 0x7e, 0x62, 0x10, 0x37, 0xfd, 0xf8, 0x06,
+ 0xed, 0xfc, 0x7c, 0xa2, 0x0e, 0x59, 0xfa, 0x65, 0x07, 0xfd, 0xe3, 0xdd,
+ 0x44, 0x30, 0x7e, 0x93, 0xca, 0x7c, 0x8f, 0xfe, 0xf1, 0x51, 0x22, 0x42,
+ 0xdf, 0xf9, 0x2a, 0x3f, 0x0d, 0xf4, 0x87, 0x3a, 0xd6, 0xd1, 0xe9, 0x07,
+ 0x7e, 0x9c, 0x65, 0xf9, 0x03, 0xa9, 0x9a, 0xd6, 0x15, 0x4a, 0x8d, 0x59,
+ 0xa3, 0x54, 0x30, 0x9f, 0xd5, 0x68, 0xff, 0xb7, 0xe0, 0x43, 0x59, 0x4f,
+ 0x4e, 0x12, 0x8b, 0x92, 0xe8, 0x2f, 0x22, 0x97, 0x5b, 0xe9, 0x9c, 0xe5,
+ 0xaf, 0x3f, 0xf1, 0xa9, 0x12, 0x1c, 0x3f, 0xe3, 0x0a, 0x76, 0xcc, 0x20,
+ 0x8f, 0xfe, 0x0b, 0xfa, 0xc1, 0x37, 0x59, 0xf6, 0x93, 0xbe, 0x62, 0x7c,
+ 0x63, 0x88, 0x31, 0x37, 0x55, 0x80, 0x82, 0x3d, 0x5e, 0x3c, 0x78, 0x48,
+ 0xc7, 0x3e, 0x27, 0x57, 0x17, 0x9d, 0x52, 0x77, 0xc4, 0x88, 0x73, 0x73,
+ 0x81, 0x19, 0x07, 0x56, 0xe3, 0xd4, 0x6e, 0x9d, 0x71, 0x2f, 0x67, 0x27,
+ 0xcf, 0x86, 0x1d, 0x6e, 0x1e, 0x17, 0x6e, 0x5e, 0xc0, 0x71, 0x6d, 0x4d,
+ 0x85, 0xda, 0xb7, 0x51, 0x17, 0xb7, 0x67, 0xc5, 0xfe, 0x22, 0x78, 0x8e,
+ 0x63, 0xeb, 0xa7, 0xad, 0x1c, 0x48, 0x54, 0x33, 0x47, 0xf7, 0xc1, 0xa2,
+ 0xad, 0x58, 0xf2, 0x0e, 0x13, 0x6d, 0xc5, 0xa2, 0xad, 0x58, 0xb4, 0x15,
+ 0x8b, 0xb6, 0x62, 0x65, 0x16, 0xe0, 0x99, 0x3e, 0x03, 0x23, 0xec, 0x73,
+ 0xe7, 0x30, 0x39, 0xbc, 0xf3, 0x3e, 0x50, 0x9d, 0xe4, 0x29, 0xca, 0xc4,
+ 0xdd, 0xb7, 0x60, 0xa8, 0xef, 0x56, 0x7e, 0x14, 0xb4, 0xd2, 0x66, 0x7a,
+ 0xd2, 0x62, 0x83, 0x22, 0x93, 0x17, 0xc3, 0x99, 0x9b, 0x2b, 0x51, 0x2c,
+ 0xf1, 0x5d, 0xc1, 0x0e, 0xe7, 0x7e, 0xde, 0xd6, 0xe4, 0x9e, 0x85, 0x9a,
+ 0x79, 0x9b, 0xf0, 0x48, 0x9f, 0x8a, 0xdb, 0xc2, 0xf2, 0x7f, 0x08, 0x9a,
+ 0x99, 0x0f, 0xc8, 0xfe, 0x7c, 0x82, 0xfe, 0x99, 0xb3, 0x15, 0x19, 0x53,
+ 0xa6, 0x7f, 0x13, 0x4e, 0xf4, 0x1b, 0x8c, 0x59, 0x26, 0x32, 0xe9, 0x04,
+ 0x7d, 0x42, 0xfc, 0xdc, 0xc0, 0x33, 0x6c, 0x6b, 0xf6, 0x80, 0x0b, 0x95,
+ 0x8d, 0x6e, 0x94, 0xd0, 0xdf, 0x6f, 0x4b, 0xd7, 0x04, 0xbe, 0xa5, 0x24,
+ 0x9c, 0xf5, 0xd7, 0x5d, 0x29, 0x8c, 0xcf, 0x34, 0x2a, 0xb1, 0x6f, 0xb0,
+ 0x11, 0x8f, 0xed, 0x76, 0xd1, 0x46, 0xed, 0x05, 0xe5, 0x4d, 0x46, 0xc7,
+ 0x02, 0x97, 0xe0, 0x45, 0x23, 0xbe, 0xc1, 0x1c, 0x60, 0x7d, 0x7f, 0xd0,
+ 0x7c, 0x05, 0x41, 0xf3, 0x24, 0x16, 0xe0, 0x59, 0x93, 0xb8, 0x39, 0xaf,
+ 0x11, 0x1b, 0xf7, 0x1b, 0xb4, 0x29, 0x37, 0xf3, 0x63, 0xf9, 0xbf, 0x37,
+ 0xba, 0xb3, 0xc6, 0xf3, 0x32, 0xe4, 0x9c, 0x43, 0xb3, 0xfc, 0x4f, 0x06,
+ 0xa5, 0x87, 0xf8, 0x34, 0xa3, 0xd7, 0xe0, 0xb8, 0x5f, 0xb0, 0x4b, 0x0d,
+ 0xf9, 0x7f, 0x1c, 0xc4, 0x11, 0x8e, 0xfb, 0xc2, 0xcd, 0x6f, 0xdb, 0x95,
+ 0x86, 0xc4, 0x50, 0xe2, 0x49, 0x5a, 0xfa, 0x8f, 0xed, 0x08, 0x10, 0x3b,
+ 0x3a, 0xfa, 0x8d, 0x78, 0x29, 0x63, 0xd8, 0x46, 0x07, 0x63, 0x04, 0x5f,
+ 0x8c, 0xb6, 0x6f, 0x21, 0xa4, 0xad, 0x20, 0xee, 0x9c, 0xe6, 0x58, 0x7a,
+ 0x52, 0x82, 0x51, 0x3a, 0x8a, 0x7a, 0x63, 0xb8, 0x81, 0x39, 0x63, 0x41,
+ 0x6f, 0x0b, 0x6a, 0x99, 0x3f, 0xba, 0x7b, 0x5b, 0x61, 0x30, 0x97, 0x9c,
+ 0xd9, 0xbb, 0x1c, 0x0b, 0xc6, 0xf2, 0x1c, 0x5a, 0xc7, 0x11, 0x67, 0xdd,
+ 0xea, 0x29, 0x78, 0xee, 0xd3, 0x69, 0x53, 0x72, 0xe6, 0xc5, 0x6b, 0x55,
+ 0x12, 0x37, 0xcf, 0x50, 0xd7, 0xed, 0x03, 0xab, 0xed, 0x81, 0x94, 0xf0,
+ 0xa6, 0x2e, 0x78, 0x9a, 0x24, 0xf7, 0xd1, 0x31, 0x46, 0x8e, 0x3c, 0xcc,
+ 0x1c, 0xec, 0x8d, 0xfd, 0xab, 0x71, 0xff, 0x9e, 0xcb, 0x39, 0x9b, 0xd9,
+ 0x64, 0xfd, 0x7b, 0xda, 0xc5, 0x86, 0x12, 0xda, 0x85, 0x97, 0x76, 0xb1,
+ 0x2b, 0x15, 0x32, 0x0f, 0xd3, 0x2e, 0x6a, 0x89, 0x21, 0x1d, 0xbd, 0x92,
+ 0xef, 0x38, 0xef, 0xed, 0x55, 0x78, 0x10, 0xc0, 0x9b, 0xb4, 0x8f, 0x8d,
+ 0xbd, 0x76, 0x97, 0x9b, 0xb1, 0xa7, 0xa7, 0xb9, 0x1a, 0xaf, 0x65, 0x6e,
+ 0xc5, 0xa3, 0xfd, 0xd5, 0x78, 0x85, 0xb6, 0xf3, 0x76, 0x02, 0xf3, 0x2b,
+ 0xa0, 0xce, 0xac, 0x60, 0xac, 0xbe, 0x4d, 0x09, 0xb5, 0x2e, 0x42, 0xfd,
+ 0xf8, 0xcb, 0x4a, 0xb0, 0x93, 0x9c, 0xe5, 0xc4, 0x05, 0x62, 0xff, 0xeb,
+ 0x19, 0x39, 0x77, 0xe7, 0xc3, 0x38, 0xed, 0x6a, 0x9c, 0xf5, 0xbe, 0xd1,
+ 0x5f, 0xc7, 0x79, 0xf3, 0xa0, 0xd0, 0xf0, 0xe3, 0x14, 0xb1, 0xb4, 0x63,
+ 0x37, 0xc6, 0x03, 0x86, 0x71, 0xa2, 0x55, 0xa9, 0xc2, 0x9b, 0xc3, 0xb7,
+ 0x62, 0x63, 0x7f, 0x50, 0x8f, 0xd1, 0x37, 0x5f, 0xe3, 0xb3, 0xf5, 0xbb,
+ 0x67, 0xe1, 0x38, 0x6d, 0x6f, 0x9c, 0xb6, 0xb7, 0xb6, 0x5f, 0xc5, 0x8b,
+ 0xc3, 0xb7, 0xb0, 0x5f, 0x05, 0xb3, 0x6a, 0x15, 0x27, 0xff, 0xda, 0x91,
+ 0x72, 0xfe, 0x77, 0x81, 0xf3, 0x8e, 0xde, 0x9c, 0x51, 0x13, 0xb3, 0xf7,
+ 0xcb, 0xf8, 0xc8, 0xc3, 0x9c, 0xb5, 0xe9, 0x46, 0xdc, 0xbc, 0xa7, 0x12,
+ 0xe7, 0xf6, 0x1a, 0x56, 0xb9, 0xcb, 0x5e, 0x70, 0x2a, 0x1c, 0xe2, 0x3c,
+ 0x34, 0xa2, 0xe1, 0x50, 0x23, 0x42, 0x03, 0xb9, 0x18, 0xa1, 0x19, 0x0b,
+ 0xf0, 0x3d, 0xce, 0xfb, 0x5a, 0xe6, 0x80, 0x35, 0x43, 0x82, 0xbd, 0x36,
+ 0x73, 0xc5, 0x66, 0x4c, 0x8c, 0x8d, 0x73, 0x6c, 0x11, 0x9c, 0x25, 0xbf,
+ 0x7d, 0x9f, 0x31, 0xe3, 0x43, 0xe6, 0x80, 0x1f, 0x3a, 0x31, 0x43, 0xde,
+ 0xa5, 0xbd, 0x32, 0x6e, 0xec, 0xe2, 0x9c, 0x6e, 0xec, 0x37, 0xea, 0xfa,
+ 0xf8, 0x7b, 0xbd, 0x33, 0xc7, 0x31, 0xe2, 0xb9, 0x60, 0x85, 0xe0, 0x7f,
+ 0x0b, 0x73, 0xde, 0x56, 0x9c, 0xed, 0x0b, 0x99, 0x0b, 0x95, 0x56, 0xbc,
+ 0x47, 0x99, 0xfb, 0x28, 0x5f, 0x92, 0xbc, 0x6c, 0x66, 0xd2, 0x18, 0xff,
+ 0xd0, 0x25, 0x18, 0xd3, 0x8a, 0xf2, 0xec, 0xad, 0x38, 0xd5, 0xbf, 0x1c,
+ 0xa5, 0x43, 0xc2, 0x35, 0xa5, 0x4d, 0x37, 0xb6, 0xee, 0xbe, 0x13, 0xeb,
+ 0x0f, 0xe6, 0x72, 0xbe, 0xf5, 0x89, 0x4d, 0xcc, 0x75, 0x85, 0xbf, 0xd7,
+ 0xe1, 0x50, 0x2a, 0x26, 0x47, 0x42, 0x77, 0x30, 0x9f, 0x8b, 0xac, 0x20,
+ 0x7e, 0x2e, 0x0d, 0x13, 0x63, 0x2b, 0x82, 0x81, 0x97, 0x61, 0xe9, 0xbc,
+ 0x17, 0x58, 0x07, 0xd1, 0x89, 0x85, 0x65, 0x8c, 0x3b, 0xb7, 0xf5, 0xbb,
+ 0x29, 0xbb, 0x3c, 0xaf, 0xc3, 0x8f, 0x52, 0x56, 0x5c, 0x9e, 0x6f, 0x84,
+ 0xf8, 0x8a, 0xe8, 0xc9, 0x05, 0xb3, 0xa9, 0x26, 0xd6, 0x41, 0x8c, 0x2e,
+ 0x0d, 0x07, 0xcd, 0x6f, 0xa0, 0x99, 0x73, 0x2f, 0x32, 0x47, 0xb0, 0xfe,
+ 0x10, 0x9c, 0x7d, 0x7f, 0x79, 0x47, 0xe4, 0x3f, 0xf4, 0xed, 0x76, 0xec,
+ 0x69, 0x7d, 0xe3, 0x65, 0x1b, 0x3c, 0x90, 0xaa, 0xef, 0x74, 0xa1, 0xc6,
+ 0x2a, 0x87, 0x91, 0xee, 0x23, 0x2f, 0x8d, 0x23, 0xd8, 0x13, 0x87, 0xc4,
+ 0x8c, 0x7a, 0x4b, 0x43, 0x35, 0xdb, 0x8e, 0xe0, 0xad, 0x84, 0x4b, 0xb0,
+ 0x09, 0xf2, 0x4f, 0x8a, 0x22, 0xc4, 0xe1, 0x37, 0x12, 0xc5, 0xd0, 0x87,
+ 0x12, 0xce, 0xff, 0x11, 0xba, 0x39, 0x6b, 0x91, 0xaf, 0x2d, 0xc0, 0xab,
+ 0xfd, 0x3e, 0xcc, 0x27, 0x4f, 0xa9, 0x4b, 0x3e, 0x65, 0x97, 0x12, 0x87,
+ 0xeb, 0x87, 0x42, 0x9a, 0x47, 0xb1, 0xed, 0x03, 0x73, 0x7f, 0x6d, 0x4f,
+ 0x8b, 0x4a, 0x59, 0x23, 0xb2, 0x48, 0xfe, 0x9f, 0xd4, 0x3c, 0xa3, 0xf5,
+ 0x2c, 0x7c, 0xb8, 0x81, 0x58, 0x7a, 0xac, 0xb7, 0x12, 0x6f, 0xed, 0xee,
+ 0x91, 0x35, 0x4b, 0x18, 0xfc, 0xfd, 0x5a, 0x6f, 0x00, 0x3a, 0xb1, 0x4c,
+ 0xe7, 0x75, 0x03, 0x31, 0x5a, 0x27, 0x3e, 0xbf, 0xdd, 0x6b, 0x2f, 0xf0,
+ 0x35, 0x59, 0x6c, 0xbd, 0x0e, 0x0b, 0x88, 0xd1, 0x6f, 0xf4, 0x06, 0x4f,
+ 0x2c, 0x51, 0x15, 0x94, 0x34, 0x99, 0xec, 0xdb, 0x87, 0x17, 0x69, 0xdf,
+ 0x4f, 0xa4, 0x8e, 0x7e, 0x6d, 0x06, 0xac, 0xfa, 0x12, 0x04, 0x37, 0x78,
+ 0x14, 0x59, 0xe3, 0x90, 0xd8, 0x56, 0x8d, 0x1b, 0xc9, 0x4d, 0x74, 0xe2,
+ 0x77, 0x4d, 0x56, 0xe2, 0x1c, 0xb0, 0x66, 0x68, 0x35, 0x3e, 0x1c, 0x14,
+ 0x1f, 0xc5, 0x42, 0xb1, 0xff, 0x05, 0xe1, 0x90, 0x79, 0x86, 0xb8, 0x5c,
+ 0x3b, 0x96, 0x20, 0xfe, 0xca, 0xb9, 0x3c, 0x8c, 0xab, 0xc4, 0x81, 0xca,
+ 0x94, 0x60, 0x57, 0x00, 0x8d, 0xcc, 0xf7, 0xca, 0x53, 0xe2, 0x93, 0x96,
+ 0x9c, 0x1b, 0xc1, 0xcd, 0x63, 0x3e, 0xe8, 0x63, 0x1a, 0x3f, 0x7e, 0xe8,
+ 0x23, 0x55, 0xfc, 0x50, 0xd6, 0x91, 0x59, 0xfc, 0x50, 0x56, 0xc6, 0x31,
+ 0x73, 0x44, 0xc1, 0x4d, 0x8e, 0x6d, 0x89, 0x0f, 0x7a, 0xf1, 0xec, 0x28,
+ 0xb0, 0xa1, 0xdf, 0xc4, 0xe1, 0xfd, 0x39, 0x9c, 0xdb, 0xcc, 0x3e, 0x42,
+ 0x03, 0x61, 0xac, 0x4f, 0x8b, 0x7d, 0x36, 0xe2, 0xb7, 0x7b, 0x8d, 0xb6,
+ 0x35, 0x6a, 0x28, 0xb2, 0x9c, 0x18, 0xf6, 0xfe, 0x48, 0x23, 0x3e, 0x7c,
+ 0x62, 0x01, 0x8c, 0x70, 0x23, 0xce, 0x1c, 0xd8, 0x84, 0xf2, 0x27, 0x54,
+ 0xe2, 0x8f, 0x8a, 0xf1, 0xe9, 0x82, 0xed, 0x82, 0xa3, 0x5e, 0xab, 0x8c,
+ 0xb8, 0xb5, 0x8d, 0xb8, 0xf5, 0xb3, 0xb9, 0xe3, 0x98, 0x9f, 0x94, 0x73,
+ 0xad, 0xcc, 0xaf, 0xd4, 0x08, 0x9e, 0x24, 0x6e, 0xed, 0xea, 0x93, 0xf9,
+ 0xe2, 0xdc, 0x12, 0xb3, 0xb6, 0xa6, 0x73, 0x9c, 0xe8, 0x70, 0xbf, 0xa1,
+ 0xb9, 0x68, 0xcb, 0x43, 0x93, 0x78, 0xf5, 0x5b, 0xc6, 0xff, 0x47, 0xe6,
+ 0x45, 0x71, 0x36, 0x2d, 0x7e, 0x25, 0x71, 0x45, 0xc7, 0x87, 0xb4, 0xf1,
+ 0xa5, 0xd4, 0xf5, 0x19, 0xe6, 0x16, 0x2d, 0x8c, 0x73, 0x1f, 0xd3, 0x9e,
+ 0x97, 0x93, 0x3f, 0xbe, 0x97, 0x12, 0x1b, 0x59, 0x8e, 0x25, 0x59, 0xb1,
+ 0x05, 0x67, 0x9d, 0x95, 0xdf, 0x31, 0x9c, 0x4e, 0xfc, 0xb1, 0xb8, 0xb0,
+ 0x12, 0xaf, 0x0e, 0xca, 0x79, 0x17, 0x03, 0xde, 0xde, 0xa0, 0x56, 0xa2,
+ 0xc8, 0x9e, 0x6e, 0x9e, 0xfb, 0x4e, 0x38, 0x39, 0x76, 0x69, 0x34, 0xbf,
+ 0xbf, 0x98, 0xdf, 0x77, 0xb0, 0xf0, 0xfd, 0xb9, 0x01, 0xf2, 0x4f, 0x28,
+ 0x87, 0xe7, 0x16, 0xe0, 0xf6, 0x3d, 0x6d, 0x18, 0xd9, 0xfd, 0x31, 0x8a,
+ 0xfa, 0xd5, 0x7b, 0x7d, 0xa8, 0xa9, 0x7b, 0x48, 0xe9, 0xc2, 0xa2, 0xb0,
+ 0xbc, 0xe7, 0x23, 0x6b, 0xe6, 0x7d, 0xd8, 0x7c, 0x80, 0x79, 0xcc, 0xd8,
+ 0x75, 0x38, 0xaa, 0x31, 0x1e, 0x9a, 0x1f, 0xa3, 0xa0, 0xdf, 0xe3, 0x9c,
+ 0x05, 0x3c, 0x6a, 0x36, 0x61, 0xe5, 0xe4, 0x59, 0x40, 0x54, 0x5d, 0xbd,
+ 0x97, 0x00, 0x5f, 0xe9, 0xe4, 0xff, 0x1f, 0xc8, 0xbd, 0xdb, 0x63, 0xa0,
+ 0x77, 0xf4, 0x7f, 0x95, 0xe7, 0xce, 0x06, 0xfd, 0x6b, 0xca, 0x76, 0xa2,
+ 0x7d, 0xcf, 0xe3, 0x58, 0xb1, 0xe7, 0x3b, 0xb8, 0x73, 0xa0, 0xb6, 0x33,
+ 0xc2, 0x5c, 0xe7, 0x83, 0xf0, 0x38, 0x8e, 0x85, 0x8b, 0x60, 0xf9, 0xc9,
+ 0xb1, 0x6e, 0xfc, 0x8a, 0xbc, 0x4e, 0xca, 0xbf, 0xd3, 0xb6, 0x7e, 0xaf,
+ 0xb4, 0xf7, 0xf6, 0xa4, 0x7f, 0xfd, 0x7c, 0x9a, 0x9c, 0xa7, 0x79, 0x21,
+ 0xf5, 0x2b, 0x5b, 0x77, 0x9e, 0xe7, 0xef, 0xbf, 0x65, 0xc7, 0xfc, 0x72,
+ 0x7f, 0xd6, 0x64, 0xbd, 0xef, 0xe0, 0x01, 0xe6, 0xbf, 0xa7, 0x9b, 0xbe,
+ 0x83, 0x85, 0x43, 0x97, 0xea, 0xa0, 0x68, 0xf7, 0x3a, 0x07, 0xbb, 0xe9,
+ 0x61, 0xe4, 0x48, 0xb2, 0x57, 0x25, 0xfb, 0x27, 0x7f, 0x89, 0xcd, 0x7b,
+ 0x65, 0x6d, 0xd3, 0xb6, 0xd7, 0x1b, 0xb2, 0xc7, 0x97, 0x3f, 0x37, 0x27,
+ 0xed, 0x58, 0x8a, 0x95, 0x91, 0xba, 0x5b, 0x94, 0xbe, 0xcc, 0xd4, 0x31,
+ 0x4d, 0x93, 0xff, 0x97, 0xa7, 0x95, 0x44, 0xa7, 0x8e, 0xad, 0x47, 0xd9,
+ 0x9e, 0x39, 0xa2, 0xec, 0xca, 0x5c, 0xad, 0x8f, 0xe7, 0xec, 0x58, 0x9b,
+ 0xb4, 0x21, 0x32, 0xc1, 0x8f, 0x62, 0x91, 0x2b, 0xff, 0xec, 0x99, 0x49,
+ 0xb9, 0x0b, 0xa1, 0x57, 0xe6, 0xe4, 0xbe, 0x9f, 0x72, 0x9b, 0x4d, 0x31,
+ 0xa8, 0xf3, 0xa6, 0xca, 0x9e, 0x1f, 0xe7, 0x7f, 0xbb, 0xd4, 0x56, 0xae,
+ 0xdc, 0xcd, 0x7e, 0xb1, 0x21, 0x75, 0xde, 0xd4, 0x35, 0xfb, 0x02, 0xe2,
+ 0x47, 0x48, 0xdb, 0x8a, 0x5c, 0xbe, 0xb7, 0xe6, 0xca, 0x7c, 0x4f, 0xb0,
+ 0x0b, 0x23, 0x09, 0x0d, 0xef, 0x99, 0x92, 0xdf, 0xc9, 0xad, 0x28, 0xbe,
+ 0xc7, 0xfc, 0xf1, 0x99, 0x44, 0xb0, 0x75, 0x9d, 0x52, 0x1f, 0x9b, 0xc3,
+ 0x38, 0x87, 0x0a, 0x59, 0x4f, 0x8f, 0x38, 0xff, 0xaf, 0x2a, 0x13, 0x8a,
+ 0x20, 0x43, 0x7f, 0x78, 0x23, 0x11, 0xec, 0x38, 0xa3, 0xe4, 0xfe, 0x0f,
+ 0xd6, 0xeb, 0xce, 0xfb, 0x1c, 0x79, 0xbb, 0x13, 0xce, 0x39, 0x75, 0x3d,
+ 0x57, 0x6c, 0x30, 0xd8, 0x97, 0x46, 0xa5, 0xac, 0x9b, 0x58, 0x16, 0xf3,
+ 0xa1, 0xee, 0x94, 0x15, 0x50, 0xf1, 0x15, 0xc4, 0xfd, 0xb2, 0x47, 0x72,
+ 0xcb, 0xe4, 0xff, 0xa9, 0x11, 0x7e, 0xf4, 0x2f, 0xaf, 0x4f, 0xc9, 0xff,
+ 0x06, 0xca, 0xdb, 0x8b, 0x35, 0x76, 0x3d, 0xd2, 0x9a, 0xac, 0x7d, 0xc0,
+ 0x9a, 0x46, 0x5d, 0xfb, 0x8d, 0x4d, 0x1c, 0xb7, 0x07, 0xd3, 0x99, 0xdb,
+ 0x85, 0x6b, 0xeb, 0xdb, 0x1a, 0xd5, 0x6b, 0x10, 0xab, 0x08, 0x6a, 0x31,
+ 0x72, 0xcd, 0x1e, 0xe7, 0xff, 0xed, 0xc8, 0xb9, 0x14, 0xab, 0xd5, 0x4b,
+ 0x4c, 0x6f, 0x52, 0x14, 0x14, 0x84, 0xe0, 0x7e, 0x28, 0xe3, 0x86, 0x56,
+ 0xfb, 0x5b, 0xfb, 0x17, 0x7e, 0x03, 0xdb, 0xc6, 0x6e, 0xb9, 0xf4, 0xff,
+ 0x87, 0xfe, 0x63, 0xf6, 0xea, 0xec, 0x37, 0xdf, 0xe6, 0xc7, 0x76, 0x6c,
+ 0xba, 0xf4, 0x2d, 0xed, 0xfe, 0x31, 0x59, 0xf3, 0xef, 0x7a, 0xd4, 0xe8,
+ 0x2e, 0x94, 0x63, 0xab, 0xb9, 0xde, 0x2f, 0x67, 0xe5, 0xd6, 0x43, 0xf6,
+ 0xff, 0x65, 0x0e, 0xe4, 0x1d, 0xc3, 0x08, 0xf3, 0x6e, 0xd1, 0x4b, 0x14,
+ 0x0f, 0x66, 0xe4, 0x9d, 0xa0, 0x59, 0x90, 0xff, 0xfb, 0xf5, 0x60, 0x26,
+ 0xa7, 0xbf, 0x47, 0x33, 0x3e, 0xe6, 0x00, 0x3e, 0xda, 0x60, 0x07, 0xf9,
+ 0x0b, 0xf9, 0xd3, 0x25, 0x5d, 0xde, 0xeb, 0x97, 0x75, 0x85, 0xef, 0xd3,
+ 0xa7, 0xdd, 0xb5, 0x72, 0x6d, 0xc9, 0xb9, 0x51, 0x25, 0x77, 0x7d, 0xde,
+ 0x79, 0x37, 0x52, 0x8d, 0xae, 0xc3, 0xc2, 0xc4, 0x34, 0x39, 0x3f, 0x29,
+ 0x6b, 0x36, 0x96, 0x3f, 0x2a, 0xef, 0x61, 0xf8, 0x88, 0xb1, 0x5f, 0xf5,
+ 0x4f, 0xbe, 0x73, 0xd5, 0xba, 0x82, 0x38, 0x36, 0x27, 0x6c, 0xc4, 0x9a,
+ 0x94, 0xa0, 0xbe, 0x52, 0x69, 0x63, 0xbd, 0x3a, 0xf4, 0x64, 0xa5, 0x0d,
+ 0xc5, 0xf9, 0xdf, 0x92, 0x1e, 0xb6, 0x71, 0x30, 0x51, 0xaf, 0x7b, 0xd4,
+ 0x4f, 0x6d, 0xcb, 0x39, 0x03, 0x29, 0xfb, 0xf6, 0x71, 0xbc, 0x94, 0x98,
+ 0x4e, 0x94, 0xba, 0xba, 0xdd, 0x4b, 0xeb, 0xe7, 0x7f, 0xa3, 0x21, 0xc6,
+ 0xb6, 0x82, 0x9d, 0x61, 0x57, 0x70, 0xc3, 0x05, 0xe2, 0x4a, 0x36, 0x6c,
+ 0xc4, 0x7f, 0xc0, 0x3e, 0xfe, 0x56, 0xa9, 0x43, 0x62, 0x4a, 0xfb, 0xb9,
+ 0xb6, 0xea, 0xdb, 0x0b, 0xd4, 0xf3, 0xce, 0xbb, 0xf8, 0xd2, 0xbe, 0x16,
+ 0x5d, 0x0d, 0x2d, 0x69, 0xd9, 0x7e, 0xb6, 0x39, 0x33, 0x1a, 0xdc, 0x57,
+ 0x41, 0x30, 0xfa, 0xb6, 0xda, 0x85, 0x35, 0x72, 0x3c, 0x24, 0x1a, 0xd4,
+ 0x1f, 0xa0, 0x7d, 0x34, 0x3a, 0x6d, 0xc4, 0xea, 0x0a, 0x20, 0x9c, 0xf2,
+ 0x4b, 0xed, 0x84, 0x39, 0x81, 0x70, 0x31, 0x96, 0x73, 0xce, 0x03, 0xc8,
+ 0xb9, 0x49, 0xe6, 0x0d, 0x09, 0xf9, 0xbf, 0x7d, 0x4e, 0x37, 0x93, 0x7b,
+ 0x5a, 0xcc, 0xd7, 0x19, 0xaf, 0xd7, 0xcb, 0xff, 0x48, 0x2a, 0xf6, 0xe1,
+ 0xc1, 0x84, 0xac, 0x81, 0xfc, 0x1f, 0x05, 0x3f, 0x96, 0xb4, 0x1c, 0x54,
+ 0x00, 0x00, 0x00 };
static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
@@ -2079,1076 +2057,1088 @@ static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000000 };
static const u32 bnx2_CP_b09FwRodata[(0x16c/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x08001744, 0x08001744, 0x0800177c,
- 0x0800177c, 0x08001790, 0x08001760, 0x080019b8, 0x08001984, 0x08001a10,
- 0x08001a10, 0x08001a98, 0x080019c8, 0x80080240, 0x08003260, 0x080031cc,
- 0x08003288, 0x080032b0, 0x080032d8, 0x080032fc, 0x08003344, 0x08003320,
- 0x08003368, 0x08003234, 0x0800345c, 0x0800344c, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080033bc, 0x080033bc, 0x080031e8, 0x080031e8, 0x0800343c,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x0800342c, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x0800341c, 0x080031e8, 0x080031e8, 0x0800340c, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080033f4, 0x080031e8,
- 0x080031e8, 0x080033e4, 0x080033d4, 0x08003d6c, 0x08003d40, 0x08003d0c,
- 0x08003ce0, 0x08003cc0, 0x08003c74, 0x80080100, 0x80080080, 0x80080000,
+ 0x80080100, 0x80080080, 0x80080000, 0x08001800, 0x08001800, 0x08001838,
+ 0x08001838, 0x0800184c, 0x0800181c, 0x08001a74, 0x08001a40, 0x08001acc,
+ 0x08001acc, 0x08001b54, 0x08001a84, 0x80080240, 0x080021c4, 0x08002010,
+ 0x080021ec, 0x08002284, 0x080023d4, 0x08002420, 0x08002544, 0x0800244c,
+ 0x080024d0, 0x08002080, 0x080029f8, 0x0800299c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x080025b8, 0x080025b8, 0x0800202c, 0x0800202c, 0x08002874,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x080028d4, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x08002440, 0x0800202c, 0x0800202c, 0x08002944, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x08002798, 0x0800202c,
+ 0x0800202c, 0x08002700, 0x0800265c, 0x080037c0, 0x08003794, 0x08003760,
+ 0x08003734, 0x08003714, 0x080036c8, 0x80080100, 0x80080080, 0x80080000,
0x80080080, 0x00000000 };
static struct fw_info bnx2_cp_fw_09 = {
- /* Firmware version: 4.4.23 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
.start_addr = 0x08000080,
.text_addr = 0x08000000,
- .text_len = 0x5938,
+ .text_len = 0x5418,
.text_index = 0x0,
.gz_text = bnx2_CP_b09FwText,
.gz_text_len = sizeof(bnx2_CP_b09FwText),
- .data_addr = 0x08005ac0,
+ .data_addr = 0x080055a0,
.data_len = 0x84,
.data_index = 0x0,
.data = bnx2_CP_b09FwData,
- .sbss_addr = 0x08005b44,
+ .sbss_addr = 0x08005624,
.sbss_len = 0x91,
.sbss_index = 0x0,
- .bss_addr = 0x08005bd8,
+ .bss_addr = 0x080056b8,
.bss_len = 0x19c,
.bss_index = 0x0,
- .rodata_addr = 0x08005938,
+ .rodata_addr = 0x08005418,
.rodata_len = 0x16c,
.rodata_index = 0x0,
.rodata = bnx2_CP_b09FwRodata,
};
static u8 bnx2_RXP_b09FwText[] = {
- 0xec, 0x5c, 0x7f, 0x70, 0x1c, 0xd5, 0x7d, 0xff, 0xbc, 0xbd, 0xbd, 0xbb,
- 0x95, 0x74, 0x3e, 0xed, 0x9d, 0x4e, 0xb2, 0x04, 0x06, 0xef, 0xa2, 0x95,
- 0x74, 0x58, 0xc6, 0xec, 0x9d, 0x4e, 0xb6, 0x48, 0xb7, 0xc9, 0xd5, 0x36,
- 0x20, 0x17, 0x52, 0x84, 0xa1, 0xc1, 0xcc, 0x30, 0x9d, 0x1b, 0x63, 0x8c,
- 0xb0, 0x1d, 0xa2, 0x00, 0x33, 0xc8, 0x29, 0x13, 0x16, 0xfc, 0xb3, 0xf8,
- 0xa4, 0x93, 0x8d, 0x8c, 0xc9, 0xf4, 0xd7, 0x21, 0xcb, 0x8a, 0x81, 0x93,
- 0xce, 0x04, 0xda, 0x98, 0x69, 0xa8, 0x15, 0x6c, 0x53, 0x87, 0x5f, 0x21,
- 0x19, 0x68, 0x4d, 0x9b, 0x99, 0xa8, 0x06, 0x1c, 0xd3, 0xa6, 0xd4, 0xb4,
- 0x0e, 0xb5, 0x8b, 0xeb, 0xd7, 0xef, 0x77, 0x4f, 0x97, 0x50, 0x42, 0xcb,
- 0x64, 0xa6, 0x7f, 0xee, 0x77, 0xe6, 0xe6, 0xf6, 0xde, 0xfb, 0xbe, 0xef,
- 0x7b, 0xdf, 0xdf, 0x9f, 0xb7, 0x1a, 0xfb, 0xbe, 0x08, 0x6a, 0x31, 0x4b,
- 0x73, 0xe8, 0x93, 0x19, 0x18, 0xbc, 0x27, 0xbd, 0x28, 0xb3, 0x88, 0x1e,
- 0xbb, 0x02, 0x73, 0x55, 0x95, 0xc7, 0x05, 0x7c, 0xf2, 0xc9, 0x27, 0x9f,
- 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2,
- 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27,
- 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c,
- 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9,
- 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xfa, 0xff, 0xa4, 0x00,
- 0xa0, 0xf3, 0xf7, 0x9c, 0xd9, 0x0f, 0x34, 0xc5, 0x71, 0x37, 0x2e, 0xb5,
- 0xa0, 0x05, 0x9c, 0x33, 0x1b, 0x6f, 0xb7, 0x80, 0x6c, 0xa9, 0xd3, 0x58,
- 0x86, 0xff, 0x92, 0x6e, 0x42, 0x05, 0x8f, 0x5f, 0xe2, 0x9c, 0xff, 0xf3,
- 0x17, 0x96, 0x98, 0xa7, 0x8b, 0x01, 0x68, 0xba, 0xf3, 0x46, 0x4a, 0x6f,
- 0x87, 0x36, 0x8f, 0xd6, 0xfc, 0x49, 0xc7, 0x95, 0x71, 0x44, 0xab, 0xb2,
- 0xe0, 0x2a, 0x8e, 0x94, 0xfb, 0x6c, 0x89, 0x97, 0x6c, 0x57, 0xf4, 0x66,
- 0xe0, 0x06, 0x9c, 0x83, 0xe2, 0xae, 0xfc, 0x05, 0x69, 0x04, 0x2b, 0x3b,
- 0xab, 0x93, 0x1a, 0x82, 0xfb, 0xa0, 0xab, 0x8e, 0x82, 0xa0, 0x55, 0x8b,
- 0xd0, 0x13, 0x75, 0x08, 0x3e, 0xd1, 0x8c, 0xf0, 0xe4, 0x01, 0x91, 0x2b,
- 0x6a, 0x98, 0x09, 0x1c, 0x14, 0x6b, 0x4a, 0xc8, 0x05, 0x9d, 0xb3, 0x37,
- 0x8c, 0xd1, 0xba, 0xac, 0xf7, 0xef, 0x4b, 0xa6, 0x6f, 0x18, 0x2f, 0x41,
- 0x0f, 0x38, 0x50, 0x54, 0xe7, 0x08, 0x3d, 0x33, 0xdf, 0xd9, 0x1b, 0xf6,
- 0x96, 0x4e, 0xc9, 0x17, 0x3a, 0x12, 0x38, 0x54, 0xd6, 0x71, 0xa0, 0xfc,
- 0x10, 0x9d, 0xc3, 0x74, 0x5d, 0x68, 0xae, 0xea, 0xb8, 0xd8, 0x92, 0x09,
- 0x62, 0x62, 0xe4, 0x82, 0x0c, 0x58, 0xa6, 0x01, 0xc5, 0xd2, 0x0f, 0x83,
- 0xf8, 0x0a, 0xc4, 0x57, 0x08, 0x62, 0xac, 0xb8, 0x23, 0x8e, 0xda, 0x66,
- 0xbc, 0xd0, 0xc1, 0xeb, 0x79, 0x2d, 0xcb, 0xf8, 0x38, 0x5a, 0x5d, 0x1f,
- 0xa2, 0xf5, 0x47, 0x33, 0xc0, 0xf8, 0x48, 0x1f, 0x2d, 0x95, 0xd8, 0x64,
- 0x87, 0xb1, 0x5a, 0x87, 0x5b, 0xe3, 0xb0, 0xac, 0xaa, 0x1c, 0x57, 0x18,
- 0x93, 0xff, 0x5c, 0x5f, 0x91, 0x03, 0xa1, 0x59, 0x70, 0xc3, 0x9f, 0x9a,
- 0x3f, 0x55, 0xaa, 0xce, 0x6f, 0xa7, 0x7d, 0x34, 0x9a, 0xef, 0xc7, 0x5f,
- 0x96, 0xd7, 0xe0, 0x2f, 0xca, 0xb7, 0xe1, 0xd9, 0x72, 0x1f, 0xed, 0x7b,
- 0x1f, 0xed, 0x3b, 0x80, 0xbf, 0x2e, 0x6f, 0xc0, 0x77, 0xcb, 0x39, 0x3c,
- 0x57, 0x5e, 0x85, 0xef, 0x94, 0x6f, 0xc6, 0x33, 0x65, 0x78, 0x67, 0x38,
- 0x95, 0x49, 0x8a, 0x1f, 0xe5, 0x6b, 0xa0, 0xee, 0xdc, 0x8c, 0xe9, 0x52,
- 0x10, 0xc1, 0x9d, 0x12, 0x23, 0xb6, 0xf9, 0x38, 0xd0, 0xa1, 0x07, 0x21,
- 0xb0, 0xcc, 0x36, 0xf7, 0x03, 0x5f, 0x40, 0x2e, 0x61, 0x1e, 0x00, 0x9a,
- 0xc4, 0x8f, 0x47, 0x9b, 0xc4, 0x6b, 0xa3, 0xaa, 0x78, 0x3d, 0x2f, 0x50,
- 0xef, 0x20, 0xf2, 0x72, 0x46, 0xca, 0xeb, 0xd2, 0x52, 0x96, 0x52, 0x56,
- 0xef, 0x0f, 0x85, 0x69, 0x3f, 0x22, 0x2e, 0x85, 0xd1, 0x68, 0x66, 0xd7,
- 0x09, 0xcd, 0xad, 0x25, 0xf9, 0x2b, 0xba, 0x01, 0x6b, 0xa7, 0x41, 0x7e,
- 0x60, 0x1d, 0x37, 0xe1, 0x0e, 0x2f, 0x26, 0xfa, 0xd0, 0x60, 0x2d, 0xc5,
- 0xbd, 0x7d, 0x36, 0x8a, 0x65, 0x68, 0x31, 0xe7, 0x0c, 0x52, 0xc3, 0x02,
- 0x36, 0xf9, 0x5b, 0xd0, 0xb3, 0x5d, 0x5a, 0xdf, 0x50, 0xf1, 0x37, 0x9d,
- 0xbd, 0x40, 0x67, 0x2f, 0xd0, 0xd9, 0x0b, 0xa4, 0x57, 0x81, 0xf4, 0x2a,
- 0x90, 0x0e, 0x05, 0xd2, 0xad, 0x40, 0x7a, 0x14, 0x48, 0x8f, 0x02, 0xe9,
- 0x58, 0x60, 0x5f, 0x0d, 0x92, 0x0d, 0x22, 0xf8, 0xbb, 0xfc, 0x3c, 0x9c,
- 0xe1, 0xcf, 0x4a, 0x1d, 0xc7, 0xe9, 0x8c, 0x8a, 0xf5, 0x9b, 0xca, 0xf8,
- 0x6e, 0x84, 0x7c, 0x64, 0xfc, 0xe6, 0x7b, 0x2f, 0xc4, 0xc9, 0xfc, 0xbb,
- 0x32, 0x34, 0x97, 0xf7, 0xfc, 0x22, 0xe4, 0x28, 0x70, 0xe9, 0x6e, 0x29,
- 0xcf, 0x75, 0xcd, 0xc8, 0xb7, 0x6f, 0x61, 0x59, 0x0e, 0x4e, 0x8c, 0x2a,
- 0x08, 0xd0, 0xd8, 0xb5, 0xf6, 0xdf, 0xcb, 0x3b, 0x13, 0xcc, 0xf7, 0x51,
- 0x04, 0xb5, 0x6c, 0x27, 0x68, 0x0d, 0xce, 0xbb, 0x1b, 0xef, 0x6d, 0x87,
- 0x1b, 0x75, 0x54, 0xf1, 0xe6, 0x90, 0x81, 0xb9, 0x4e, 0x16, 0x73, 0x1c,
- 0x6b, 0x64, 0x8f, 0xd2, 0x39, 0x18, 0x47, 0xf6, 0xf2, 0x7a, 0xd8, 0xd8,
- 0x57, 0x56, 0xc5, 0xab, 0x43, 0x73, 0x10, 0xdf, 0x69, 0xad, 0x1a, 0x12,
- 0x0a, 0x72, 0x8d, 0x59, 0x8c, 0x67, 0x4c, 0xa3, 0x08, 0x03, 0xab, 0xd2,
- 0x0a, 0x30, 0xd7, 0xc5, 0xd6, 0x8c, 0x69, 0xbb, 0x78, 0x08, 0xd3, 0x09,
- 0x1b, 0x13, 0x65, 0x8d, 0x72, 0xc3, 0xc5, 0x9d, 0x19, 0x0d, 0x72, 0x24,
- 0x8b, 0x93, 0x5d, 0x21, 0x4c, 0xf7, 0x71, 0x8c, 0xa8, 0xb4, 0xf7, 0x56,
- 0x28, 0xf1, 0x38, 0xf9, 0xe5, 0xb0, 0x0c, 0xc6, 0x79, 0x0c, 0xe2, 0x5f,
- 0x32, 0xbc, 0xff, 0x45, 0xe2, 0xd5, 0xdd, 0x51, 0xd4, 0xee, 0xd6, 0xf0,
- 0xf4, 0x4e, 0x15, 0x2b, 0xc8, 0xb7, 0x7b, 0x52, 0xaa, 0xb1, 0x4e, 0x38,
- 0x18, 0x2f, 0xab, 0x48, 0x0c, 0xb5, 0xc0, 0x88, 0x69, 0xb8, 0x74, 0xc8,
- 0xc5, 0x3b, 0x24, 0x77, 0x90, 0xe4, 0xd6, 0x77, 0xe9, 0x98, 0x69, 0xac,
- 0xf8, 0xf5, 0xeb, 0xf9, 0x56, 0x77, 0xa7, 0x12, 0x02, 0x42, 0x70, 0x35,
- 0x27, 0x83, 0xfb, 0xf3, 0xad, 0xa4, 0xc3, 0xad, 0x58, 0x1a, 0xd2, 0xb0,
- 0x7a, 0x98, 0xc7, 0x96, 0x03, 0x93, 0x73, 0xe7, 0xa0, 0x96, 0xf5, 0xe7,
- 0x7c, 0x5e, 0x4a, 0xcf, 0x1c, 0x07, 0xbf, 0x9d, 0x60, 0xbb, 0xbb, 0xca,
- 0x7f, 0xc8, 0x6c, 0x82, 0xf9, 0x2a, 0x39, 0x72, 0x38, 0x93, 0xc1, 0xc6,
- 0x7c, 0x6b, 0xf6, 0x5b, 0x4a, 0x03, 0x10, 0x34, 0x0d, 0x43, 0x81, 0x96,
- 0x70, 0x90, 0x1a, 0xa5, 0x78, 0x79, 0xd4, 0x8b, 0x17, 0xa4, 0xba, 0x4a,
- 0x9c, 0x97, 0x9a, 0xab, 0x13, 0xff, 0xfc, 0xc5, 0x6d, 0xf8, 0xe8, 0x51,
- 0xe6, 0x53, 0xf1, 0x03, 0x7a, 0x7e, 0x7f, 0xef, 0x8e, 0xd9, 0xda, 0xf1,
- 0xa7, 0x9e, 0x5f, 0x0d, 0xa5, 0xba, 0xb7, 0x8d, 0x3b, 0xf3, 0xad, 0x67,
- 0xb7, 0x29, 0xe4, 0xbf, 0x8b, 0x23, 0xa8, 0xa1, 0xfa, 0x13, 0x24, 0x59,
- 0xfb, 0xf2, 0xe7, 0xb1, 0x32, 0x6d, 0x1e, 0xe4, 0x7f, 0x6f, 0x36, 0x66,
- 0x55, 0xe4, 0x5f, 0x56, 0xb2, 0xf1, 0x64, 0xd9, 0xc6, 0xed, 0x74, 0x8e,
- 0xfb, 0xf0, 0x8f, 0x40, 0xcb, 0x02, 0xe3, 0x94, 0x72, 0x42, 0xba, 0x37,
- 0xb3, 0xbc, 0x79, 0x38, 0x15, 0x6f, 0xcd, 0x9d, 0x52, 0xcc, 0xe2, 0x76,
- 0x85, 0x6d, 0xa5, 0xe0, 0xcb, 0xe9, 0x0c, 0x8a, 0x31, 0x1d, 0xb7, 0xa6,
- 0x35, 0xf7, 0x52, 0x3a, 0xd3, 0x1b, 0x4b, 0x34, 0x34, 0xed, 0xca, 0xe2,
- 0xad, 0xf4, 0x9b, 0x28, 0xae, 0x64, 0x3b, 0xf0, 0x3a, 0x3e, 0x73, 0x33,
- 0xe2, 0x56, 0x0d, 0xe2, 0x63, 0x41, 0xd4, 0xef, 0xba, 0x20, 0x9b, 0x2d,
- 0x1e, 0xb7, 0x06, 0xce, 0x0a, 0x3e, 0x73, 0x10, 0xd1, 0xb1, 0xab, 0xa0,
- 0x5a, 0x66, 0x92, 0x1c, 0x9b, 0x60, 0xde, 0x90, 0x55, 0x3d, 0xbb, 0xc0,
- 0x75, 0x5f, 0x10, 0x58, 0x97, 0xfa, 0xbe, 0xcc, 0x36, 0xf2, 0x9a, 0x67,
- 0x68, 0x9c, 0xcf, 0x50, 0x73, 0x36, 0x8b, 0x26, 0x5a, 0x53, 0xe5, 0x8b,
- 0xa0, 0x7f, 0x57, 0xe5, 0x0c, 0x6f, 0x2f, 0xc1, 0xb3, 0x1a, 0x7a, 0xd0,
- 0x51, 0x78, 0x08, 0x6f, 0x2d, 0xf6, 0xf6, 0x3f, 0xbd, 0x2f, 0xbd, 0x83,
- 0x6c, 0xc2, 0x75, 0xf4, 0xd3, 0x7e, 0xe1, 0xf9, 0xff, 0x64, 0x7f, 0x24,
- 0x21, 0x9a, 0x69, 0x8c, 0xe3, 0x77, 0xa7, 0x34, 0x6e, 0xaa, 0xf8, 0x25,
- 0x4c, 0xf2, 0xde, 0xcf, 0xf4, 0xa0, 0x75, 0x48, 0x85, 0xcc, 0xb7, 0xda,
- 0x3f, 0x0d, 0x3c, 0x22, 0xa7, 0x6f, 0xe3, 0xb9, 0x56, 0xfd, 0x70, 0x40,
- 0x60, 0xa9, 0x6a, 0x9e, 0xce, 0xa1, 0x19, 0xfb, 0xa9, 0xc6, 0xb4, 0x38,
- 0x3a, 0xd5, 0x9c, 0x04, 0xd5, 0x1e, 0x43, 0x74, 0xec, 0xb1, 0xb1, 0x60,
- 0xe8, 0x36, 0x7c, 0x69, 0xb7, 0x83, 0x83, 0x05, 0x1b, 0x4f, 0x17, 0xa4,
- 0x3c, 0x69, 0x4b, 0xf9, 0xaf, 0x5d, 0x66, 0xff, 0x31, 0x6a, 0x07, 0x8b,
- 0x96, 0x74, 0xe6, 0xea, 0x03, 0x2a, 0xd9, 0xa7, 0xcd, 0xd8, 0x20, 0xcc,
- 0xe6, 0x29, 0x61, 0x53, 0xcc, 0xf5, 0x92, 0xed, 0x0d, 0xec, 0x2d, 0x27,
- 0xf1, 0x54, 0xd9, 0xa2, 0xcf, 0x42, 0x8a, 0x95, 0x0c, 0xd5, 0x33, 0xd6,
- 0x55, 0xc7, 0x78, 0x07, 0xe5, 0x45, 0x41, 0xc1, 0x7e, 0x9b, 0xe2, 0x3f,
- 0x46, 0xbc, 0x85, 0x0b, 0xe4, 0x3f, 0x0d, 0xc9, 0x9d, 0x59, 0xd4, 0xa4,
- 0x1a, 0x60, 0xdc, 0x68, 0x61, 0xbc, 0xa0, 0xb9, 0x41, 0x8a, 0xf9, 0xb1,
- 0xfc, 0x38, 0xfe, 0x40, 0x4f, 0xa0, 0x96, 0xec, 0xb7, 0x2a, 0x1d, 0x01,
- 0x6e, 0xe2, 0xb9, 0x08, 0x5a, 0xac, 0xef, 0xa3, 0x25, 0x3e, 0x07, 0xa1,
- 0x05, 0x7f, 0x85, 0x69, 0x3d, 0x8a, 0x30, 0xf5, 0x8c, 0xf9, 0xc4, 0x33,
- 0x9f, 0x7c, 0xd5, 0x68, 0x59, 0x24, 0x53, 0xc0, 0x6a, 0x23, 0x5e, 0xca,
- 0xa7, 0x66, 0xd2, 0x3d, 0xb8, 0x24, 0x81, 0x32, 0x9d, 0x7f, 0x2a, 0x2f,
- 0x65, 0x24, 0x63, 0xf6, 0x17, 0x28, 0x37, 0x27, 0x4b, 0x3d, 0x98, 0x2a,
- 0xff, 0x1e, 0xd5, 0x73, 0x1b, 0x7b, 0xf3, 0x0e, 0xc6, 0x0a, 0xea, 0xaa,
- 0x3c, 0xcc, 0xbe, 0xf5, 0xc8, 0xe0, 0x29, 0x8a, 0x9f, 0x89, 0x82, 0x69,
- 0xbc, 0x18, 0xd0, 0x70, 0xcc, 0xae, 0xa3, 0x73, 0x52, 0xde, 0x92, 0x4e,
- 0xcf, 0xe7, 0x47, 0x60, 0x35, 0xb0, 0xfd, 0xd9, 0x4f, 0x19, 0x7c, 0xbb,
- 0xe0, 0xc5, 0xf7, 0x75, 0x1a, 0x5c, 0xd8, 0xdd, 0xec, 0x1b, 0xf7, 0x74,
- 0x30, 0x5d, 0xa9, 0xa3, 0x7d, 0xdd, 0x36, 0xc2, 0xc3, 0x3d, 0x24, 0xb7,
- 0xd5, 0x3e, 0x81, 0x3b, 0x30, 0xdd, 0xec, 0x62, 0x11, 0xc5, 0xbf, 0xea,
- 0x3c, 0x9e, 0xda, 0x9c, 0x77, 0x65, 0xbd, 0x65, 0xf5, 0xff, 0x50, 0x3c,
- 0x88, 0x57, 0x53, 0x5c, 0xd7, 0x55, 0xca, 0x7b, 0x1d, 0x3b, 0xec, 0x11,
- 0xbc, 0x56, 0xfa, 0x2d, 0xe4, 0x62, 0x66, 0x72, 0x93, 0x58, 0x8f, 0x83,
- 0x23, 0x57, 0x01, 0xb7, 0x70, 0x9e, 0x90, 0x6e, 0xd6, 0x7a, 0x1c, 0x2a,
- 0x7e, 0x03, 0x47, 0x47, 0x6b, 0xf1, 0xbc, 0x15, 0x47, 0xcb, 0x44, 0x65,
- 0x9f, 0xab, 0xbb, 0x35, 0x8c, 0x51, 0x4e, 0x5f, 0x6b, 0xab, 0x98, 0x49,
- 0x70, 0xfd, 0xa0, 0x58, 0x4b, 0x6f, 0xa0, 0x5a, 0xe3, 0xb5, 0x5e, 0xac,
- 0xc9, 0x18, 0xc8, 0xe7, 0xb3, 0x54, 0xff, 0x6a, 0xb0, 0x2b, 0x06, 0x71,
- 0x3b, 0xf5, 0xb0, 0xbb, 0xf3, 0xad, 0xfd, 0xc3, 0x4a, 0x1c, 0xc5, 0x96,
- 0x2c, 0xf9, 0x42, 0xa0, 0xc9, 0x32, 0xb0, 0xa5, 0x44, 0x15, 0xb4, 0xa4,
- 0xe2, 0x9b, 0xa5, 0x2b, 0x50, 0x6c, 0xe2, 0xb5, 0x1d, 0x98, 0xf6, 0xbe,
- 0x83, 0x98, 0x89, 0x9b, 0xcd, 0x20, 0x9b, 0x8d, 0x17, 0x54, 0xec, 0xb6,
- 0xf7, 0x5c, 0x28, 0xae, 0x34, 0xf5, 0x1c, 0xe5, 0x5b, 0xc0, 0x8b, 0x5b,
- 0x7e, 0x06, 0xbe, 0x96, 0xff, 0x50, 0x9e, 0xf1, 0xf6, 0x54, 0x39, 0xff,
- 0xa7, 0xdf, 0x0e, 0xbc, 0x2f, 0x45, 0x98, 0xe5, 0xdf, 0x1f, 0xad, 0xfc,
- 0x5b, 0xd1, 0x67, 0x99, 0x37, 0x0b, 0x70, 0x1c, 0xcc, 0xfd, 0x44, 0xcc,
- 0x57, 0xea, 0x80, 0xbe, 0x98, 0xcf, 0x51, 0xcd, 0xb3, 0x38, 0x9a, 0x26,
- 0xda, 0x50, 0xb3, 0x8b, 0x7f, 0xf3, 0xb8, 0xc0, 0x65, 0xdd, 0x9c, 0x63,
- 0x6d, 0x50, 0xc6, 0x56, 0x47, 0x2b, 0x35, 0xb8, 0x5a, 0x1f, 0xfe, 0x70,
- 0x56, 0xbe, 0xd7, 0xeb, 0xe9, 0x77, 0xa5, 0x86, 0x7e, 0x33, 0xc3, 0xcf,
- 0xbc, 0xa6, 0x06, 0x6f, 0xed, 0x35, 0xed, 0xa2, 0xb2, 0x84, 0xf7, 0xac,
- 0xe4, 0x08, 0x36, 0xce, 0xae, 0xa1, 0x98, 0x2f, 0x4c, 0x49, 0xdc, 0xca,
- 0xf2, 0xaa, 0xeb, 0xdb, 0x10, 0xfa, 0xe5, 0xbe, 0x2a, 0x5e, 0xcc, 0x7c,
- 0x7a, 0xdf, 0xdb, 0x64, 0xed, 0xca, 0x38, 0xc5, 0x59, 0x23, 0xd4, 0x05,
- 0xd4, 0xe0, 0xf5, 0x26, 0xd4, 0x51, 0xde, 0x06, 0xac, 0x5b, 0x64, 0xe0,
- 0x2b, 0x1c, 0xa7, 0x9a, 0x1b, 0x71, 0x2e, 0xc6, 0xf0, 0xce, 0x17, 0xc8,
- 0xc7, 0x51, 0x8e, 0x47, 0xf2, 0xf3, 0xc5, 0x18, 0x7a, 0xe2, 0x92, 0x28,
- 0xeb, 0xbb, 0x2a, 0x0d, 0x77, 0x3e, 0xd5, 0xec, 0xf7, 0xf6, 0xdc, 0x2d,
- 0x8b, 0x7d, 0x3a, 0x5e, 0xca, 0xfc, 0x0e, 0x8d, 0x73, 0x3c, 0xd9, 0x78,
- 0x2e, 0xaf, 0xe1, 0xfe, 0xe1, 0x66, 0x3a, 0x27, 0xd7, 0xca, 0x9a, 0xb3,
- 0x33, 0x8a, 0x8d, 0x67, 0x29, 0x16, 0x9f, 0x29, 0xb0, 0xad, 0x54, 0x5c,
- 0x96, 0x5e, 0x21, 0xc3, 0x4d, 0x1c, 0xdf, 0x49, 0x5a, 0xa3, 0x93, 0xec,
- 0x28, 0x74, 0x6b, 0x99, 0x3c, 0xb0, 0x92, 0x9f, 0x3b, 0x68, 0xac, 0x89,
- 0xbe, 0xbb, 0x65, 0xdd, 0xaf, 0x9d, 0x43, 0xff, 0xac, 0x73, 0x50, 0xdc,
- 0x9b, 0xf6, 0x5a, 0x74, 0x12, 0x0e, 0x52, 0x91, 0xa5, 0x3e, 0x3f, 0x41,
- 0x31, 0xb0, 0x8d, 0x7a, 0xf0, 0x7b, 0x84, 0xf5, 0xb6, 0x78, 0x78, 0xca,
- 0x83, 0x67, 0x1e, 0x5e, 0x5b, 0x5d, 0xc1, 0x5d, 0x9a, 0x6a, 0x31, 0x16,
- 0xab, 0xce, 0x71, 0x9e, 0xf6, 0x62, 0x6c, 0x54, 0xca, 0xcd, 0x76, 0x0b,
- 0xc9, 0x88, 0x63, 0xb3, 0x45, 0x39, 0x3d, 0xca, 0x6b, 0xa4, 0x4c, 0xa6,
- 0x16, 0xf4, 0xa8, 0xa2, 0x01, 0x33, 0xba, 0x2b, 0xd6, 0x66, 0x0c, 0xf1,
- 0xd5, 0x51, 0x15, 0xf9, 0xc2, 0x45, 0x64, 0x2f, 0x29, 0x9f, 0x4a, 0x21,
- 0xbb, 0x29, 0x55, 0x87, 0x57, 0x8a, 0x3a, 0x72, 0xfa, 0x05, 0xb9, 0xbc,
- 0xad, 0x17, 0x65, 0x92, 0xf3, 0x41, 0xaa, 0x33, 0x79, 0x44, 0x44, 0x50,
- 0x4c, 0x44, 0xf0, 0x78, 0x21, 0x81, 0x23, 0xe3, 0x11, 0x6c, 0xa5, 0x18,
- 0x7d, 0x31, 0xc3, 0x7b, 0x46, 0xf0, 0x70, 0x99, 0x31, 0x55, 0x80, 0x6c,
- 0xe4, 0x8a, 0x13, 0xde, 0x58, 0x1d, 0x96, 0x17, 0x99, 0xf7, 0x82, 0x6c,
- 0xb1, 0x2c, 0xbd, 0x25, 0x50, 0xe5, 0x3b, 0x4e, 0xf8, 0xca, 0xa0, 0x5a,
- 0x36, 0x8f, 0x70, 0x55, 0x33, 0x61, 0xa8, 0x04, 0x61, 0x28, 0x6b, 0x16,
- 0x17, 0x9a, 0x94, 0x8d, 0x52, 0x3e, 0x4b, 0xb5, 0xec, 0xc7, 0xf4, 0x39,
- 0x43, 0xf5, 0x34, 0x46, 0x3a, 0x5e, 0x36, 0xcc, 0x3a, 0xba, 0xc2, 0xa6,
- 0x7a, 0x9b, 0x55, 0x94, 0x7a, 0xee, 0x43, 0x81, 0x29, 0xde, 0x5f, 0xc5,
- 0x96, 0x02, 0xb0, 0xa9, 0x00, 0xf7, 0x08, 0xe5, 0x7e, 0xc3, 0x44, 0x14,
- 0xf1, 0x09, 0x1d, 0xc1, 0x89, 0x24, 0xcd, 0x6b, 0x48, 0xd0, 0x6f, 0x97,
- 0xb0, 0x60, 0xbd, 0xd3, 0x24, 0x16, 0x3e, 0x76, 0x5e, 0xee, 0x48, 0xa9,
- 0x58, 0xd7, 0x66, 0xf6, 0xde, 0x28, 0x90, 0x4d, 0x0e, 0x49, 0x19, 0x4e,
- 0x85, 0x29, 0x37, 0xe5, 0xa1, 0x04, 0xe9, 0x1d, 0x75, 0xe4, 0x83, 0xaf,
- 0x75, 0x5b, 0xf6, 0x6b, 0x20, 0xb9, 0x65, 0x5e, 0xc3, 0xe3, 0xae, 0xf8,
- 0xb0, 0xdb, 0x7a, 0xfc, 0x4d, 0xb4, 0xa3, 0x6b, 0x42, 0x15, 0xff, 0x36,
- 0xb4, 0x10, 0xe9, 0x29, 0xe8, 0x21, 0xe7, 0x80, 0x98, 0x79, 0xe2, 0xa0,
- 0x38, 0x39, 0x49, 0xe7, 0x2e, 0x90, 0x2e, 0x05, 0xd2, 0xa5, 0x40, 0xba,
- 0x90, 0x5d, 0x9e, 0xf1, 0xf0, 0x24, 0xeb, 0x9a, 0x24, 0x2c, 0x73, 0xdc,
- 0xc3, 0xbc, 0x8c, 0x11, 0x63, 0x8e, 0x99, 0x75, 0xc1, 0x7a, 0xb3, 0x9e,
- 0x52, 0xbe, 0x69, 0x57, 0xf4, 0x71, 0xa9, 0xdc, 0x6a, 0x53, 0x55, 0x5b,
- 0x48, 0xf9, 0xef, 0x36, 0xdb, 0x82, 0x75, 0x94, 0xf2, 0x3b, 0xa4, 0xd3,
- 0x16, 0xd2, 0x71, 0x53, 0x41, 0x1e, 0x0a, 0x59, 0x96, 0x31, 0x41, 0x67,
- 0x8b, 0x93, 0x4e, 0x89, 0x09, 0x8d, 0x74, 0x6d, 0x87, 0x4a, 0xba, 0x06,
- 0x26, 0xa0, 0x2b, 0x74, 0x1e, 0x63, 0x8c, 0xec, 0x34, 0xf5, 0x79, 0xe7,
- 0x61, 0xcc, 0xef, 0x8a, 0xab, 0x09, 0x9f, 0xa8, 0x64, 0xd7, 0x4d, 0x14,
- 0x3b, 0x39, 0x15, 0x46, 0xd8, 0x52, 0xa8, 0x27, 0x6a, 0xf8, 0xf6, 0x78,
- 0x1d, 0x26, 0xc8, 0xef, 0xc5, 0x71, 0xe8, 0x41, 0x92, 0xe9, 0x16, 0x0f,
- 0x8a, 0x4f, 0xc6, 0x5b, 0xd0, 0x19, 0x20, 0x9c, 0x04, 0x3c, 0x92, 0x8f,
- 0x8b, 0x89, 0x11, 0x15, 0x9b, 0x0b, 0xa7, 0x49, 0x3f, 0x89, 0xc3, 0xf6,
- 0xc3, 0xcd, 0xc4, 0x22, 0x1e, 0xb6, 0xcd, 0x1e, 0xe0, 0x2a, 0x8a, 0xb7,
- 0x00, 0xd6, 0x5a, 0xc8, 0x6e, 0xb3, 0xaf, 0xc2, 0x4c, 0x1f, 0x8c, 0xed,
- 0xb6, 0xab, 0x87, 0x60, 0x1e, 0xbb, 0x9a, 0x7a, 0xd3, 0x95, 0xa4, 0xcf,
- 0xa0, 0xe5, 0x0e, 0x50, 0xe1, 0x42, 0xb9, 0x6c, 0xf6, 0x1f, 0x25, 0x5f,
- 0x94, 0xa8, 0xff, 0x95, 0xca, 0x4d, 0xe2, 0xe9, 0xd1, 0xf3, 0xf2, 0xae,
- 0x94, 0x99, 0x6d, 0xa3, 0xb1, 0xe0, 0x90, 0x46, 0x38, 0x4d, 0xa3, 0x9c,
- 0x32, 0x6d, 0x80, 0x6b, 0x03, 0xb4, 0x30, 0xd5, 0xe2, 0x9f, 0x59, 0x47,
- 0x08, 0xa7, 0x6b, 0x20, 0x0c, 0x8f, 0xa5, 0x23, 0x02, 0xfb, 0x28, 0xc7,
- 0x27, 0x17, 0x9a, 0xc7, 0x56, 0xc3, 0x9d, 0x6e, 0x81, 0x39, 0x18, 0x0e,
- 0x9c, 0xc6, 0x07, 0x43, 0x21, 0xc2, 0x0d, 0xed, 0xf6, 0xeb, 0x30, 0xf5,
- 0x7d, 0x81, 0x5f, 0xc8, 0xfd, 0x09, 0x5c, 0x14, 0xc4, 0x19, 0x69, 0xfc,
- 0x3e, 0xaf, 0x61, 0xdd, 0x07, 0xb0, 0x2d, 0xc3, 0x38, 0x45, 0x25, 0x9c,
- 0x02, 0xbc, 0x93, 0x37, 0xb0, 0x7f, 0x61, 0x0d, 0xf5, 0x93, 0xd6, 0x9e,
- 0x75, 0x70, 0x57, 0xd1, 0xf5, 0x47, 0x8b, 0xd0, 0x5e, 0x79, 0x8a, 0x95,
- 0x0d, 0x42, 0xe0, 0x29, 0xeb, 0xac, 0xdd, 0x31, 0xc9, 0x18, 0x46, 0x4d,
- 0x2d, 0xa0, 0x5c, 0xdc, 0x5a, 0x16, 0xd4, 0xdb, 0x4c, 0x7d, 0x06, 0x6c,
- 0x1b, 0x9d, 0xec, 0x7a, 0x5e, 0x22, 0xc6, 0xba, 0xbb, 0x39, 0xd2, 0x73,
- 0xd5, 0x16, 0x3a, 0xff, 0x1a, 0xd2, 0xe9, 0x2e, 0xcb, 0xed, 0x21, 0xa9,
- 0xd4, 0xa3, 0xcc, 0xe6, 0xf7, 0x48, 0xf7, 0xb5, 0x54, 0x47, 0x8a, 0xe5,
- 0xe7, 0xea, 0xb9, 0x66, 0x4c, 0x94, 0xf9, 0x1e, 0xd7, 0x83, 0xa5, 0xf9,
- 0x6a, 0x3e, 0xb0, 0xff, 0xd9, 0xf7, 0x1c, 0x0b, 0x1c, 0x33, 0x1c, 0x27,
- 0x8c, 0xd1, 0x7a, 0x30, 0xda, 0xae, 0x20, 0x9b, 0x90, 0x72, 0xa5, 0x65,
- 0x8e, 0x70, 0x1d, 0xa7, 0x98, 0xcf, 0xee, 0xb5, 0xeb, 0x29, 0x3f, 0xe1,
- 0x3e, 0x69, 0x1b, 0x08, 0x39, 0x1c, 0x1b, 0x75, 0x14, 0xeb, 0x11, 0x6c,
- 0xa3, 0x58, 0xd1, 0x2c, 0x2b, 0x49, 0x97, 0x0d, 0xfd, 0x9d, 0x0c, 0xf1,
- 0x96, 0x61, 0x94, 0xed, 0x5a, 0xc2, 0x95, 0x2a, 0x62, 0xce, 0x21, 0xd9,
- 0x60, 0x35, 0xea, 0xd4, 0xb8, 0xf5, 0x7b, 0xb1, 0x9a, 0xee, 0x17, 0x06,
- 0xea, 0x1c, 0x9e, 0x3f, 0x27, 0x67, 0x62, 0x11, 0x8a, 0x33, 0xe6, 0xb1,
- 0xdc, 0x67, 0xf0, 0x91, 0x44, 0x9c, 0x79, 0xb3, 0x58, 0x9d, 0x81, 0x38,
- 0x48, 0x7b, 0xa1, 0x81, 0x73, 0xd7, 0xc0, 0x7c, 0xc7, 0x3a, 0x76, 0x88,
- 0x7a, 0x8f, 0xd1, 0x00, 0xaa, 0xb9, 0x2a, 0x02, 0x8e, 0xa5, 0xef, 0xc5,
- 0x51, 0xaf, 0x4e, 0x11, 0x52, 0x17, 0x2b, 0x76, 0xcf, 0x13, 0xbd, 0x84,
- 0xcd, 0xdb, 0x53, 0x70, 0x34, 0xb4, 0x19, 0x7f, 0x43, 0xa3, 0x9b, 0x29,
- 0xfe, 0xe7, 0x38, 0x11, 0x51, 0xda, 0x0d, 0xfd, 0x69, 0x5b, 0xa3, 0x3e,
- 0x2a, 0xe5, 0xd6, 0x94, 0x81, 0x29, 0x9b, 0x70, 0x74, 0x63, 0x10, 0x31,
- 0x0b, 0xba, 0xee, 0x58, 0x83, 0x07, 0x30, 0xc0, 0xf8, 0x37, 0x3a, 0x9f,
- 0x7a, 0x25, 0x8d, 0x89, 0x31, 0xbb, 0x06, 0xd9, 0x9b, 0x05, 0x22, 0x4e,
- 0x82, 0xce, 0x16, 0x42, 0xce, 0x7b, 0x66, 0x1d, 0x91, 0x7d, 0xd7, 0xde,
- 0x43, 0xfa, 0x8a, 0xf9, 0xb5, 0x0e, 0x8f, 0x59, 0x76, 0x09, 0x77, 0x11,
- 0x56, 0xa7, 0x21, 0x9a, 0xdf, 0x4c, 0xf3, 0x8f, 0x92, 0xec, 0x5c, 0xdc,
- 0xbb, 0x87, 0xd6, 0xb7, 0x38, 0xd6, 0xf4, 0xf3, 0xd8, 0x4e, 0x3a, 0x70,
- 0x8d, 0xe7, 0x31, 0x3e, 0xf3, 0x42, 0x3e, 0x33, 0xf5, 0x78, 0x8e, 0x2b,
- 0x1b, 0x3f, 0xcb, 0xd3, 0xde, 0x09, 0x64, 0xb7, 0xdb, 0x10, 0x13, 0xf6,
- 0x6e, 0xc2, 0x2f, 0xa8, 0x8f, 0x3a, 0x56, 0xff, 0x14, 0xa0, 0x44, 0x9c,
- 0x9d, 0x28, 0xc5, 0x80, 0x47, 0x0b, 0x96, 0x7b, 0x8f, 0x62, 0x0e, 0x26,
- 0x08, 0x13, 0x9f, 0x21, 0x4c, 0xbf, 0xab, 0x7d, 0xda, 0x8c, 0x83, 0xb1,
- 0x7e, 0x54, 0xbc, 0xb4, 0x5b, 0x41, 0xc7, 0x62, 0xea, 0x4b, 0x54, 0x4b,
- 0xae, 0xb1, 0xf9, 0xbe, 0x7c, 0x79, 0x7d, 0x05, 0x2f, 0xff, 0x6f, 0x39,
- 0x69, 0x92, 0xc5, 0xaa, 0x79, 0x69, 0xf5, 0x3d, 0x8d, 0x3f, 0x93, 0xd9,
- 0x18, 0xfb, 0x22, 0x42, 0xb5, 0xf8, 0x97, 0xf5, 0x28, 0x39, 0x49, 0xf2,
- 0x37, 0x75, 0x07, 0x75, 0x8e, 0x19, 0xf2, 0x65, 0xf6, 0x8d, 0x3c, 0x44,
- 0x7d, 0x9a, 0xf2, 0x2a, 0xc6, 0x7e, 0xe1, 0xfb, 0x3d, 0x19, 0x6f, 0x38,
- 0x41, 0xba, 0xa9, 0xe8, 0x4a, 0xa3, 0x5e, 0x71, 0xac, 0xb3, 0x63, 0x74,
- 0xe6, 0x16, 0xa7, 0x1e, 0xe7, 0x1a, 0xb8, 0x36, 0x46, 0xc5, 0x0f, 0x46,
- 0xcd, 0x1e, 0xc2, 0xc3, 0xab, 0xee, 0x21, 0x1c, 0x75, 0x9f, 0x50, 0xd1,
- 0x4b, 0x67, 0xb7, 0xda, 0xc8, 0x07, 0x84, 0x4d, 0x12, 0x6d, 0xd3, 0x66,
- 0x02, 0xd5, 0xf3, 0x5e, 0x90, 0x71, 0xcb, 0x72, 0xe3, 0xca, 0xc7, 0x32,
- 0x95, 0xe6, 0x18, 0xdf, 0x80, 0x70, 0x5c, 0x20, 0x94, 0x1e, 0xf2, 0x6c,
- 0x4b, 0x77, 0x2a, 0xd4, 0xa7, 0x1f, 0x62, 0x1f, 0x11, 0x7e, 0x7b, 0x59,
- 0xe6, 0xbe, 0xc2, 0xba, 0x6d, 0x9f, 0xd5, 0x73, 0x2d, 0xc7, 0x15, 0xfd,
- 0x96, 0x73, 0xd8, 0xde, 0x87, 0xa8, 0x8e, 0x77, 0x2d, 0xe9, 0xdc, 0x3e,
- 0xa8, 0x0c, 0x49, 0x63, 0x25, 0xfb, 0x93, 0x2e, 0x37, 0xb5, 0x9e, 0xaf,
- 0xb5, 0xa8, 0x73, 0x1c, 0xaf, 0x0f, 0x45, 0x45, 0xfd, 0x63, 0xae, 0xd7,
- 0x53, 0x5f, 0xa3, 0xb3, 0x9c, 0x4c, 0xf1, 0x19, 0x38, 0xc7, 0x8e, 0xe3,
- 0x8a, 0xd2, 0xed, 0xc4, 0x1b, 0xa0, 0xfd, 0xa1, 0x51, 0xbc, 0x41, 0x52,
- 0x9f, 0x39, 0xd7, 0x35, 0x25, 0x8d, 0x06, 0x96, 0x4f, 0xb6, 0x1e, 0x65,
- 0x5b, 0xf3, 0xdd, 0xb2, 0x6a, 0x6f, 0xe6, 0xe7, 0xf5, 0x74, 0xe9, 0x8e,
- 0xb1, 0xff, 0x50, 0x5f, 0xe7, 0xb0, 0x4d, 0x21, 0x6a, 0x9c, 0x4e, 0x63,
- 0x81, 0xd8, 0x21, 0xdd, 0x44, 0xb5, 0x86, 0x45, 0xc5, 0x84, 0xb7, 0x9e,
- 0xf7, 0xfe, 0xf4, 0xfa, 0x26, 0xf1, 0xce, 0x9e, 0xdf, 0xa5, 0x67, 0x2f,
- 0x46, 0x7a, 0x9f, 0xa2, 0x1c, 0xd2, 0x9c, 0x7e, 0x99, 0x6c, 0xe4, 0x18,
- 0x83, 0xf2, 0x8a, 0xbd, 0x56, 0xe6, 0x1a, 0x39, 0xd6, 0xe0, 0x26, 0x48,
- 0xce, 0xae, 0xc7, 0x7e, 0x75, 0x8e, 0xab, 0xdb, 0xa5, 0x9c, 0xb0, 0xd7,
- 0x90, 0x2d, 0x58, 0x4e, 0xd5, 0x16, 0x7b, 0x66, 0x6d, 0xd3, 0x5e, 0xf1,
- 0x5f, 0xc1, 0x3b, 0x83, 0x16, 0x72, 0xde, 0xc0, 0x4b, 0x79, 0xa5, 0x89,
- 0x6e, 0x2b, 0xe8, 0xb3, 0x05, 0x7e, 0xda, 0x43, 0xfa, 0x5d, 0x49, 0x58,
- 0x65, 0x91, 0x35, 0xdd, 0x1a, 0x58, 0x2f, 0x31, 0x77, 0x9a, 0x82, 0xe3,
- 0xbc, 0xd4, 0xda, 0x55, 0x84, 0xaf, 0xe0, 0x1e, 0xc5, 0xb6, 0x57, 0xf0,
- 0x32, 0xf1, 0xad, 0xb8, 0xc2, 0x32, 0x5a, 0x05, 0xf5, 0xb5, 0xbe, 0xa5,
- 0xe9, 0xe0, 0x2f, 0x63, 0x8f, 0xcf, 0x90, 0xf3, 0x74, 0xe0, 0x18, 0xec,
- 0x22, 0xdf, 0xe5, 0x56, 0x2a, 0x48, 0x2d, 0x06, 0x61, 0x8d, 0xa8, 0xd8,
- 0xba, 0x9b, 0xfd, 0xff, 0x3d, 0x9a, 0x67, 0xbe, 0xce, 0x66, 0x1d, 0xd6,
- 0xaa, 0xc3, 0x74, 0xb1, 0x24, 0x2c, 0x4a, 0xf6, 0xe0, 0xbd, 0xaa, 0x72,
- 0xaa, 0x32, 0xa2, 0x62, 0x72, 0x94, 0x79, 0x59, 0x17, 0xaa, 0xcd, 0x1c,
- 0x2b, 0x29, 0x8e, 0x8f, 0x8f, 0x65, 0x47, 0x3a, 0x1a, 0x43, 0x2d, 0xaf,
- 0x89, 0x0a, 0x7d, 0x0f, 0xcb, 0x85, 0x60, 0x3b, 0xc6, 0x48, 0xff, 0xf6,
- 0xf4, 0xe5, 0xb3, 0xfa, 0xff, 0xb1, 0x5e, 0xc1, 0x71, 0x51, 0x71, 0xd4,
- 0xdb, 0xbb, 0x62, 0xa3, 0x49, 0xb2, 0xf5, 0x44, 0xaa, 0xca, 0xf3, 0x38,
- 0xf1, 0x70, 0x9c, 0x7d, 0x66, 0x4f, 0x22, 0xea, 0x15, 0x8f, 0xe4, 0xe9,
- 0x92, 0x6a, 0x29, 0xd7, 0xd7, 0x52, 0x9e, 0x3c, 0x49, 0xbd, 0x69, 0x7f,
- 0xb1, 0x57, 0x6c, 0xcb, 0xeb, 0xd4, 0xa7, 0x96, 0x8b, 0xad, 0x79, 0x8b,
- 0x71, 0xd1, 0x6c, 0x9f, 0xaa, 0xbc, 0x8b, 0xda, 0x52, 0xfa, 0xe4, 0x3b,
- 0xa2, 0x48, 0x4e, 0x77, 0xd0, 0x37, 0x7f, 0xf8, 0x41, 0xa9, 0x58, 0xfc,
- 0x3e, 0xc8, 0x3a, 0x76, 0x22, 0x10, 0xe9, 0xe9, 0x59, 0x12, 0x40, 0xbd,
- 0x85, 0xbe, 0x66, 0xc2, 0x07, 0x57, 0x7a, 0x35, 0xdd, 0x80, 0x51, 0x6a,
- 0x6f, 0xac, 0xf8, 0x89, 0xf3, 0x0e, 0x6a, 0xad, 0x83, 0x5c, 0x0d, 0xd5,
- 0x91, 0x6b, 0xba, 0x43, 0xda, 0xd1, 0xee, 0xde, 0x96, 0xf6, 0xc9, 0xa6,
- 0x5c, 0xad, 0x73, 0x7d, 0x4b, 0xdb, 0xa4, 0xdb, 0xb2, 0x70, 0x08, 0xf8,
- 0xf2, 0x90, 0x0e, 0xcd, 0xb9, 0xd1, 0x0d, 0x74, 0x23, 0xa7, 0x52, 0x5c,
- 0xec, 0xe8, 0xb6, 0x7a, 0xa6, 0xc4, 0x4d, 0x37, 0x91, 0x1e, 0x2d, 0x9d,
- 0x93, 0x86, 0xb1, 0x39, 0xf3, 0xc0, 0x4d, 0x81, 0x29, 0xee, 0x2f, 0x1b,
- 0x06, 0xf7, 0xf1, 0x7b, 0x33, 0xba, 0x9b, 0x9e, 0xd0, 0xf1, 0xc0, 0xb2,
- 0xee, 0x41, 0x0c, 0xe4, 0x1f, 0x40, 0x7f, 0x9e, 0xdf, 0x3b, 0x69, 0x18,
- 0xe1, 0x1a, 0x5f, 0xe0, 0x77, 0x4e, 0x0f, 0x35, 0x30, 0x6e, 0xdc, 0x5e,
- 0x56, 0x71, 0xed, 0x10, 0xcf, 0x99, 0xcd, 0xef, 0xa3, 0xca, 0xfb, 0x59,
- 0x7c, 0x9f, 0xd4, 0x93, 0x6b, 0x1e, 0xb2, 0x81, 0x61, 0x29, 0x95, 0x0c,
- 0xdf, 0x63, 0x4e, 0x13, 0xd6, 0xe3, 0xbd, 0x7f, 0x4e, 0xbd, 0x71, 0x2e,
- 0xbf, 0x0b, 0x63, 0xca, 0x86, 0x87, 0x79, 0xee, 0xd4, 0xec, 0xdc, 0xbb,
- 0x34, 0x07, 0x71, 0x92, 0xea, 0xfa, 0x74, 0x25, 0x2f, 0xb2, 0xb5, 0xc3,
- 0x1a, 0xfe, 0xa8, 0xc0, 0x3c, 0x33, 0xb3, 0x3c, 0x3f, 0x21, 0x9e, 0x04,
- 0x56, 0xc4, 0xb8, 0x76, 0x53, 0xce, 0xec, 0xae, 0xbe, 0x2b, 0x93, 0xf2,
- 0x25, 0xfb, 0xc3, 0x68, 0xe5, 0x5d, 0x59, 0x54, 0x68, 0x8f, 0xd1, 0x33,
- 0x61, 0x95, 0x50, 0x2a, 0x2a, 0x42, 0x8f, 0xf1, 0xfa, 0x57, 0x53, 0x95,
- 0xf5, 0xc7, 0x52, 0xbc, 0xfe, 0xd7, 0xd7, 0xa8, 0xd9, 0xc8, 0x30, 0xdd,
- 0xa9, 0x0a, 0xff, 0x24, 0x77, 0x34, 0x56, 0x64, 0x57, 0xd6, 0x7d, 0x6f,
- 0x76, 0xdd, 0x41, 0x5a, 0xb7, 0x8f, 0x62, 0x8c, 0xd7, 0xb2, 0x9e, 0x1c,
- 0xa3, 0xd5, 0xf7, 0x86, 0x49, 0x71, 0x80, 0x7a, 0xf5, 0x81, 0x92, 0x2a,
- 0xf6, 0x52, 0x1d, 0x1c, 0xcf, 0x13, 0x36, 0xf2, 0xde, 0x05, 0x52, 0xcd,
- 0x2f, 0x7f, 0x23, 0x56, 0xf1, 0x21, 0xf7, 0xd5, 0x69, 0xea, 0xab, 0xed,
- 0x54, 0xdf, 0x55, 0x4f, 0xa7, 0xb0, 0x73, 0x84, 0xea, 0xbb, 0xc0, 0x49,
- 0xaf, 0xbe, 0x1c, 0x41, 0x7b, 0x89, 0xfb, 0x80, 0x25, 0xce, 0x15, 0x8c,
- 0x5c, 0x33, 0xc9, 0x6e, 0x29, 0x57, 0x6a, 0x03, 0xf5, 0x82, 0x2c, 0xf5,
- 0x64, 0xf1, 0x62, 0x89, 0x7f, 0x52, 0xf1, 0x8c, 0xf3, 0x19, 0xb2, 0x62,
- 0x4e, 0xbb, 0x8b, 0xfa, 0x76, 0x97, 0x71, 0xec, 0xc0, 0xf3, 0xc2, 0x9a,
- 0x3e, 0x27, 0xb2, 0xb7, 0x36, 0xe3, 0x41, 0xfc, 0x3c, 0x95, 0x5d, 0x11,
- 0xa5, 0x6f, 0xc2, 0xcc, 0x86, 0xc6, 0xef, 0x48, 0xbb, 0xdb, 0x7a, 0x36,
- 0x88, 0x36, 0xaa, 0x37, 0x6d, 0xee, 0x16, 0xb4, 0x51, 0xcf, 0xb7, 0xb5,
- 0xc3, 0x25, 0x5b, 0x7b, 0xa3, 0x54, 0xb5, 0x03, 0xc7, 0x29, 0xdb, 0x80,
- 0x42, 0xdf, 0xb1, 0xb2, 0x0b, 0x04, 0xf5, 0x55, 0xea, 0xbb, 0xc3, 0xd4,
- 0xb3, 0x2b, 0xf7, 0xce, 0x30, 0xe1, 0x16, 0xde, 0x7b, 0xdd, 0xec, 0xbb,
- 0x96, 0x7f, 0x90, 0x95, 0x1e, 0xf5, 0x0a, 0xd9, 0x83, 0xcf, 0xfc, 0xa3,
- 0x48, 0x65, 0xfc, 0x4c, 0x6c, 0xf6, 0xff, 0xf9, 0x21, 0x9c, 0x42, 0xf7,
- 0xc8, 0x21, 0x81, 0x1d, 0x6d, 0x95, 0x58, 0xee, 0xe4, 0xf7, 0x98, 0xde,
- 0x7b, 0xb7, 0x2a, 0x4f, 0xc5, 0x86, 0x0a, 0xe1, 0x99, 0x43, 0xe5, 0xac,
- 0xb8, 0x26, 0x8f, 0x01, 0xea, 0x89, 0xd9, 0x20, 0xf1, 0x5e, 0x53, 0xea,
- 0x15, 0xcb, 0xf3, 0x96, 0xb1, 0x89, 0x74, 0xdd, 0xa2, 0x77, 0xea, 0xe3,
- 0x84, 0x21, 0x68, 0x3f, 0x23, 0x4c, 0xf1, 0xaf, 0x39, 0x73, 0xb1, 0x7d,
- 0x36, 0x76, 0x28, 0x1f, 0x28, 0x7f, 0x06, 0xc5, 0x82, 0x49, 0xfe, 0xa9,
- 0x7b, 0xb1, 0x5b, 0xd1, 0xe3, 0x9c, 0xdc, 0x76, 0x33, 0xcf, 0x5f, 0x31,
- 0x6b, 0xfb, 0xa6, 0x38, 0xed, 0x49, 0xbf, 0x47, 0x66, 0xcf, 0xff, 0x7f,
- 0xad, 0xbd, 0xf6, 0x92, 0xff, 0xb9, 0x66, 0x86, 0xce, 0xc9, 0x18, 0x08,
- 0x6e, 0xdc, 0x61, 0xfc, 0x33, 0x6f, 0xd6, 0xe7, 0xd4, 0x15, 0xa3, 0x03,
- 0xb8, 0x71, 0x31, 0xdd, 0x7c, 0xe9, 0x0e, 0xb6, 0x8d, 0x7c, 0x95, 0x1c,
- 0x66, 0xbd, 0xcf, 0x93, 0xde, 0xd0, 0x6a, 0x9c, 0xb3, 0xb8, 0x7c, 0xa8,
- 0xb5, 0x3f, 0x2c, 0xcc, 0xe4, 0x90, 0x30, 0xfb, 0xa8, 0xbe, 0xd9, 0x93,
- 0x30, 0x9b, 0x17, 0x08, 0xd3, 0x58, 0x0b, 0xb6, 0xc9, 0x79, 0xb4, 0x95,
- 0xf8, 0xfb, 0x2c, 0x2c, 0xf2, 0x6b, 0xdf, 0x70, 0x00, 0x4a, 0xfa, 0x03,
- 0xb2, 0x2b, 0xe1, 0x35, 0xd1, 0x4c, 0xb9, 0xc4, 0xb1, 0x77, 0x1e, 0x9b,
- 0xf3, 0xd0, 0x5a, 0x88, 0xe7, 0x2a, 0xaa, 0xd1, 0xad, 0xc3, 0xe6, 0x59,
- 0xc2, 0x9c, 0x83, 0x5f, 0x0a, 0xb4, 0x26, 0xfb, 0x61, 0x0e, 0x6c, 0x41,
- 0xe7, 0xf4, 0x51, 0x61, 0x66, 0xcf, 0x12, 0x16, 0x0c, 0xa7, 0x2b, 0x32,
- 0x17, 0xcd, 0xca, 0x4c, 0x32, 0x3e, 0xf6, 0x72, 0x88, 0x30, 0x74, 0xfa,
- 0x6f, 0xe5, 0xb4, 0x67, 0xb3, 0xe0, 0xac, 0xfe, 0x4b, 0xe2, 0x15, 0x1f,
- 0x3c, 0x37, 0x6b, 0x1f, 0x42, 0x24, 0xb5, 0xcc, 0xc7, 0xf7, 0x30, 0x88,
- 0x35, 0xf9, 0x2f, 0xe2, 0x61, 0xc2, 0x43, 0x59, 0x6f, 0x7d, 0x2f, 0x72,
- 0x25, 0x88, 0xb5, 0xf9, 0xe9, 0xf0, 0x51, 0x3b, 0x88, 0xa2, 0x27, 0xe7,
- 0x7a, 0x1a, 0xeb, 0xa3, 0x0f, 0xdb, 0x8c, 0xef, 0xe4, 0x37, 0xd3, 0x73,
- 0xd6, 0xe3, 0xeb, 0xcf, 0xa3, 0x27, 0x9c, 0x22, 0xdc, 0xe6, 0xf1, 0x79,
- 0xf7, 0x75, 0xe2, 0x59, 0xce, 0x73, 0x23, 0xfc, 0xae, 0x61, 0x75, 0xa6,
- 0xcd, 0x78, 0xd8, 0xbb, 0x23, 0x1a, 0x58, 0x53, 0x32, 0x70, 0x07, 0xd5,
- 0xd5, 0xa2, 0x57, 0x57, 0x7f, 0x85, 0xe7, 0x15, 0xe2, 0x5b, 0x46, 0x7c,
- 0x9b, 0xbc, 0x31, 0x03, 0xcb, 0x4b, 0xc7, 0xbd, 0x58, 0x51, 0x1d, 0xf6,
- 0x03, 0xdb, 0x9e, 0xf1, 0x68, 0xf5, 0xae, 0xc6, 0x3e, 0xc9, 0x8a, 0x47,
- 0xf3, 0xbd, 0x62, 0x67, 0x3e, 0x4a, 0xfb, 0xb9, 0x62, 0x24, 0xa3, 0x8c,
- 0xc6, 0x20, 0xb1, 0x2c, 0x7d, 0x35, 0xd5, 0x19, 0x2b, 0x69, 0xd1, 0xb5,
- 0x65, 0x6d, 0x72, 0x2e, 0x61, 0xa7, 0x25, 0x58, 0x97, 0x0c, 0x51, 0xff,
- 0xfe, 0x16, 0xee, 0xd4, 0xc3, 0xe8, 0x4f, 0xde, 0x0b, 0xdc, 0x58, 0x43,
- 0xfd, 0xf6, 0x61, 0x0f, 0xb3, 0x86, 0x68, 0xdf, 0x1a, 0xaa, 0x0d, 0x77,
- 0x79, 0x7a, 0x4f, 0xb1, 0xae, 0x74, 0xce, 0xe5, 0x62, 0x84, 0xea, 0x7d,
- 0xa2, 0x82, 0x01, 0x36, 0x66, 0x8a, 0xfc, 0x3d, 0xb3, 0xb1, 0xcb, 0xb3,
- 0xf3, 0x4f, 0x36, 0xda, 0xa5, 0x5f, 0xc4, 0x2b, 0x3d, 0x75, 0x29, 0xb2,
- 0x8d, 0xdd, 0x58, 0x9f, 0xec, 0xc1, 0x1c, 0x6b, 0x39, 0xbe, 0xaa, 0xbb,
- 0x88, 0x5a, 0x63, 0xb8, 0xdb, 0x93, 0xc1, 0xf2, 0xbc, 0xbf, 0x6d, 0x10,
- 0x4d, 0x13, 0xc8, 0xf9, 0xbc, 0xfb, 0x50, 0xe5, 0xdd, 0x42, 0x4e, 0x09,
- 0x62, 0xd3, 0x2e, 0xfe, 0x56, 0x71, 0x77, 0xa6, 0xf2, 0xce, 0x70, 0x78,
- 0x2c, 0x88, 0xa1, 0x5d, 0xd4, 0xfb, 0x52, 0x21, 0xb8, 0x8d, 0x9f, 0x96,
- 0xdd, 0x4f, 0xb2, 0x2b, 0xf7, 0xef, 0xaf, 0x91, 0x5d, 0x67, 0x82, 0x41,
- 0x34, 0x13, 0x0c, 0x4b, 0x10, 0x4f, 0xc3, 0x54, 0x1d, 0x9a, 0xc7, 0xf8,
- 0xef, 0x23, 0x07, 0xc5, 0x7d, 0xa5, 0x0a, 0xcf, 0x46, 0xfe, 0x9b, 0x4a,
- 0x58, 0xc1, 0x7c, 0x8b, 0xd5, 0x55, 0x89, 0x47, 0xa3, 0x7b, 0x5c, 0x2d,
- 0xe6, 0x8f, 0xd5, 0xd1, 0x47, 0x47, 0x6c, 0x82, 0x26, 0xa6, 0x96, 0x8b,
- 0xaf, 0xe7, 0x93, 0x88, 0xd1, 0xfd, 0x32, 0xee, 0x54, 0xd6, 0xdf, 0x53,
- 0xfa, 0xbc, 0xf3, 0x07, 0xff, 0xbb, 0xb2, 0x6f, 0x01, 0x8e, 0xea, 0xbc,
- 0xd2, 0xfc, 0x6e, 0x3f, 0xa4, 0xd6, 0x93, 0xab, 0x27, 0x2d, 0x1e, 0xa6,
- 0x9b, 0xbe, 0x2d, 0xb5, 0xad, 0x4e, 0xb8, 0x0d, 0xa2, 0x90, 0x3d, 0xbd,
- 0xa5, 0x06, 0x0b, 0x5b, 0x04, 0x63, 0xcb, 0xb6, 0x32, 0x83, 0x67, 0x53,
- 0x63, 0x05, 0x03, 0xc6, 0xd8, 0x33, 0x91, 0x09, 0x35, 0x25, 0xef, 0xce,
- 0x44, 0x77, 0x25, 0x10, 0x02, 0xf5, 0x4b, 0x12, 0x04, 0x98, 0xaa, 0x2d,
- 0x37, 0x92, 0x40, 0xd8, 0x69, 0x49, 0x78, 0x92, 0xec, 0x90, 0x4c, 0xd5,
- 0x58, 0x01, 0x61, 0x20, 0x04, 0xe3, 0xec, 0x4e, 0x6d, 0x91, 0x5d, 0xcf,
- 0x98, 0xc2, 0x06, 0x9c, 0x18, 0x3f, 0x33, 0x59, 0x8b, 0x78, 0xe2, 0xbb,
- 0xdf, 0xb9, 0xdd, 0x0d, 0x82, 0x21, 0x99, 0x1a, 0x57, 0x75, 0x89, 0xee,
- 0x7b, 0xff, 0xff, 0x9e, 0xff, 0xfc, 0xe7, 0x7c, 0xe7, 0x3b, 0xe7, 0xfc,
- 0xb7, 0x4c, 0x2e, 0x2d, 0xfb, 0xb5, 0x08, 0xc5, 0xda, 0x94, 0xf9, 0x42,
- 0x96, 0xe3, 0x48, 0x1c, 0xed, 0xbe, 0xd9, 0x8f, 0x11, 0x99, 0x84, 0xcb,
- 0x41, 0xad, 0x08, 0x4b, 0x9e, 0xc7, 0x1f, 0xad, 0x3c, 0x51, 0x64, 0x90,
- 0xb9, 0x0b, 0x91, 0x3f, 0x2c, 0x73, 0x17, 0x21, 0xef, 0xa6, 0x2c, 0xf2,
- 0x1c, 0xa6, 0x5c, 0x13, 0x12, 0x5b, 0xe5, 0x79, 0xc7, 0x95, 0xa1, 0xb4,
- 0xc8, 0x90, 0x7b, 0xee, 0x59, 0x73, 0xa3, 0x5a, 0xc4, 0x18, 0x3e, 0x62,
- 0x6e, 0x62, 0x5e, 0xe2, 0x5f, 0xfa, 0x86, 0x99, 0x6a, 0x93, 0xb5, 0xba,
- 0xcd, 0xbd, 0x09, 0x27, 0xfa, 0xa9, 0xb7, 0xad, 0xa1, 0xa3, 0xc2, 0x67,
- 0xb3, 0xff, 0xe5, 0xf4, 0xf6, 0x97, 0xd4, 0xdb, 0xa9, 0xec, 0x3e, 0x1e,
- 0x57, 0x4e, 0xde, 0x8c, 0xf5, 0x22, 0xa3, 0xc8, 0xa5, 0xa0, 0x42, 0x13,
- 0xb9, 0x6c, 0x28, 0x67, 0xdc, 0xac, 0xa0, 0x7e, 0xca, 0x2d, 0x99, 0x9a,
- 0x95, 0x9f, 0x47, 0xa1, 0xce, 0x21, 0x17, 0x2c, 0x9b, 0xc8, 0xc8, 0x35,
- 0x45, 0xfd, 0x5c, 0xb8, 0x69, 0x13, 0xb3, 0xf5, 0x2c, 0x74, 0x46, 0x7c,
- 0xfa, 0xe2, 0x4b, 0x3b, 0x92, 0x32, 0xaf, 0x5d, 0xf2, 0x04, 0x2b, 0xdf,
- 0xb3, 0xd1, 0x9e, 0x56, 0x45, 0x33, 0x3a, 0xb0, 0x59, 0x7b, 0x20, 0x3e,
- 0x20, 0xeb, 0xcf, 0xad, 0xbd, 0x59, 0x79, 0x3a, 0x2a, 0xe3, 0x35, 0x2c,
- 0xb2, 0xc6, 0x59, 0xfb, 0xce, 0x71, 0x6f, 0x73, 0x5c, 0x80, 0x63, 0x32,
- 0xb6, 0xe9, 0x49, 0x7d, 0x26, 0x7e, 0xcd, 0x7d, 0x3a, 0xae, 0x74, 0xf2,
- 0x99, 0xb0, 0xf6, 0xf6, 0xfd, 0xac, 0xaf, 0x1f, 0xa7, 0x6f, 0xf2, 0x37,
- 0xa7, 0x8d, 0xf6, 0x5e, 0x04, 0xc7, 0xb0, 0xcb, 0xaa, 0x49, 0xc8, 0xdc,
- 0xcf, 0x45, 0xcb, 0x51, 0x70, 0x24, 0x37, 0x36, 0x13, 0xc3, 0x33, 0xbd,
- 0xac, 0x9c, 0x3f, 0x0a, 0x3e, 0x0a, 0x76, 0x1b, 0x4a, 0xe4, 0x66, 0x3f,
- 0x4a, 0x6a, 0x38, 0xd2, 0xa7, 0xcb, 0xa7, 0x3c, 0x52, 0xef, 0x53, 0x88,
- 0x19, 0xcc, 0x07, 0xd5, 0x55, 0x1e, 0x07, 0x71, 0x6e, 0x13, 0xbe, 0x20,
- 0xb7, 0x8d, 0x04, 0x9c, 0x96, 0x0f, 0x4b, 0xcd, 0x2f, 0x1f, 0x19, 0x0c,
- 0x02, 0x86, 0xa3, 0x8c, 0xbb, 0x5c, 0x2b, 0x63, 0x3d, 0xba, 0xd3, 0x5f,
- 0x98, 0x53, 0x95, 0xcc, 0xd9, 0xb5, 0x9b, 0x35, 0x22, 0xfa, 0x9d, 0x69,
- 0x8e, 0xf0, 0x5a, 0x6f, 0x3a, 0xb7, 0x4f, 0xe4, 0x10, 0xe4, 0x68, 0xcf,
- 0x68, 0xbf, 0x35, 0x37, 0xdc, 0x76, 0x6f, 0x0e, 0x9b, 0x73, 0x79, 0xa9,
- 0x60, 0x73, 0x31, 0x7a, 0xf7, 0x7a, 0x93, 0x29, 0x54, 0x22, 0xa9, 0xd9,
- 0xe6, 0xd3, 0x4b, 0x98, 0xf5, 0x7b, 0xfb, 0x9a, 0x61, 0xe5, 0xeb, 0x9e,
- 0x14, 0xfa, 0x2b, 0xc4, 0x8f, 0x9c, 0x5a, 0xbd, 0xa7, 0xcc, 0x56, 0x2e,
- 0xb2, 0x5b, 0x52, 0xd9, 0x07, 0x0b, 0xb0, 0x89, 0xb9, 0x76, 0xaa, 0x95,
- 0x98, 0x35, 0x68, 0xb4, 0x70, 0x7a, 0x57, 0x61, 0x38, 0xd5, 0xf9, 0x35,
- 0xbf, 0x97, 0xf1, 0x10, 0xc8, 0x67, 0xde, 0x7f, 0x09, 0x59, 0x4c, 0x1b,
- 0xf4, 0x1a, 0x36, 0x9b, 0x8c, 0xff, 0xcc, 0x34, 0xda, 0x64, 0xac, 0xcc,
- 0xc1, 0x67, 0xff, 0x1b, 0x5f, 0xf0, 0x50, 0x4f, 0x87, 0x2b, 0xa4, 0x7e,
- 0xa6, 0xd6, 0x92, 0xab, 0x0f, 0x16, 0xa3, 0x88, 0xb9, 0x6b, 0x7f, 0x95,
- 0xaf, 0x43, 0xb7, 0x15, 0xe2, 0xfc, 0x57, 0xfe, 0x13, 0x52, 0x55, 0x79,
- 0x70, 0xd5, 0x02, 0x0f, 0xc6, 0x6d, 0xb0, 0xd5, 0x12, 0x7b, 0x1b, 0x80,
- 0xe6, 0x09, 0xee, 0xdb, 0xa0, 0x82, 0xa7, 0x92, 0x36, 0x3c, 0x9a, 0xb4,
- 0x63, 0x6d, 0x12, 0xdf, 0x59, 0x04, 0x4c, 0xd7, 0xc0, 0xdf, 0x3e, 0xa3,
- 0x60, 0x6b, 0x29, 0xfc, 0xad, 0x31, 0xc5, 0xdf, 0xb2, 0x96, 0x39, 0xd3,
- 0x9a, 0x09, 0xe2, 0x19, 0xef, 0x75, 0x0e, 0x70, 0x5f, 0x07, 0xec, 0xa8,
- 0x19, 0xc0, 0x3d, 0xf9, 0x40, 0x83, 0x13, 0xfe, 0x19, 0xc6, 0x99, 0x72,
- 0x07, 0xfc, 0x53, 0x97, 0xed, 0xfe, 0xce, 0x1a, 0x3b, 0x37, 0xb7, 0x56,
- 0x64, 0x71, 0xe1, 0x31, 0xda, 0xf3, 0xa2, 0x41, 0xde, 0xcf, 0xfc, 0x5d,
- 0x65, 0x9e, 0xf3, 0xc9, 0x9f, 0x48, 0xfd, 0x52, 0xae, 0x49, 0xef, 0x52,
- 0x41, 0xe9, 0xa0, 0x9d, 0x18, 0x76, 0xce, 0x3c, 0x5f, 0x25, 0xf8, 0x0d,
- 0x3c, 0x45, 0xd9, 0xdc, 0xfc, 0x4d, 0xad, 0x25, 0x37, 0x5d, 0xa1, 0x62,
- 0xfd, 0xb0, 0xdc, 0x0b, 0x6b, 0x1e, 0x27, 0x7d, 0x2a, 0x8f, 0x3e, 0x7e,
- 0xc4, 0xea, 0x77, 0xd9, 0xb8, 0x46, 0x3b, 0x8a, 0x06, 0x81, 0x35, 0x71,
- 0x3c, 0x51, 0x0c, 0x7f, 0x44, 0x64, 0xac, 0x5b, 0xee, 0xe0, 0xd8, 0x62,
- 0xb4, 0x4c, 0x64, 0xc6, 0x3d, 0x3c, 0xf1, 0xa3, 0x8a, 0x4c, 0x2d, 0xf7,
- 0xf7, 0xf7, 0x5e, 0x7b, 0x1a, 0xfc, 0xd8, 0x94, 0xa4, 0xcd, 0xd9, 0x3c,
- 0x18, 0xce, 0xd6, 0x54, 0x37, 0xa4, 0xbc, 0xb3, 0x7a, 0xa3, 0xff, 0xbd,
- 0x38, 0xdb, 0x37, 0xa5, 0x2f, 0xcc, 0x70, 0x1e, 0x43, 0xd9, 0x40, 0xdd,
- 0x0d, 0x4f, 0x9a, 0x88, 0xea, 0x26, 0xc6, 0xf9, 0x79, 0x53, 0x87, 0x51,
- 0x44, 0x5f, 0xd8, 0x18, 0xfb, 0xd2, 0x34, 0xb2, 0xfe, 0xfc, 0x4a, 0x22,
- 0xa0, 0x6c, 0x21, 0x57, 0x7e, 0x95, 0xf1, 0x74, 0x8c, 0x9f, 0x51, 0xe6,
- 0x70, 0x4e, 0xca, 0x6d, 0xa3, 0x5f, 0xef, 0x4c, 0x01, 0x23, 0xcc, 0xd1,
- 0x0f, 0x2e, 0x17, 0xfe, 0x5e, 0xc4, 0xe7, 0xd1, 0x6b, 0x78, 0x4f, 0x9a,
- 0x9f, 0x23, 0xfc, 0x4c, 0x72, 0x4f, 0xf9, 0x3c, 0x04, 0xc6, 0x1d, 0x88,
- 0x8c, 0x13, 0x68, 0xc7, 0x03, 0x98, 0x62, 0x0c, 0xbc, 0x31, 0xaa, 0xa2,
- 0x64, 0xac, 0x1c, 0x1f, 0x1d, 0x26, 0x3e, 0x1e, 0xca, 0x70, 0xfe, 0x4d,
- 0xe3, 0xd2, 0xdf, 0x92, 0xf5, 0x49, 0x1f, 0x58, 0xfc, 0xa9, 0x00, 0x63,
- 0xa4, 0x1f, 0xd2, 0x0b, 0x7e, 0x57, 0xe7, 0xdc, 0xaa, 0xf4, 0xf1, 0x5a,
- 0x71, 0x34, 0xea, 0xf3, 0xf4, 0xd1, 0xe6, 0x0d, 0x87, 0xf8, 0x58, 0x03,
- 0x5e, 0x8d, 0xe6, 0x7a, 0x42, 0xbe, 0x96, 0x9f, 0x4a, 0x3d, 0x83, 0x21,
- 0x3b, 0x4f, 0x93, 0x6b, 0xb9, 0x58, 0x2a, 0x6b, 0x96, 0xba, 0x74, 0x8e,
- 0xb7, 0xcc, 0xfe, 0xfd, 0x8c, 0x29, 0x7d, 0xca, 0xd7, 0x26, 0xbd, 0x7d,
- 0x29, 0xe8, 0x56, 0xac, 0x3c, 0x5c, 0xe7, 0x4d, 0x1a, 0x90, 0xfd, 0x6d,
- 0xa0, 0x0c, 0xdf, 0xa5, 0xed, 0x07, 0x44, 0xd7, 0x8c, 0xed, 0x52, 0xef,
- 0x2d, 0x43, 0xff, 0x40, 0x39, 0xf6, 0x0c, 0x18, 0xe8, 0x5d, 0xde, 0x86,
- 0x33, 0x51, 0x13, 0x9b, 0x42, 0x26, 0xd6, 0x84, 0xbc, 0x81, 0x57, 0x50,
- 0xdf, 0x78, 0x14, 0x8f, 0x91, 0x43, 0xa8, 0xd4, 0xc9, 0x37, 0xf0, 0xce,
- 0x5e, 0x07, 0x36, 0xeb, 0x7f, 0x4c, 0x1f, 0x36, 0xcd, 0xf7, 0x96, 0x2d,
- 0xc0, 0x70, 0xa2, 0x5e, 0xed, 0xa6, 0x7c, 0x91, 0x36, 0xee, 0x55, 0xd0,
- 0x81, 0x67, 0xf5, 0xef, 0xf0, 0x5e, 0xb7, 0xcd, 0xa1, 0xc9, 0x77, 0x1b,
- 0xe3, 0xa9, 0xec, 0xa5, 0x41, 0xfb, 0xca, 0xc4, 0xb2, 0x48, 0xb6, 0xce,
- 0xbe, 0xb9, 0x41, 0x30, 0xbf, 0x18, 0xa7, 0xa9, 0xb7, 0x13, 0xc9, 0x08,
- 0xc3, 0x2e, 0x94, 0x67, 0x1b, 0xba, 0xf0, 0x34, 0xf9, 0xc6, 0x3b, 0x24,
- 0x02, 0xf7, 0xc7, 0x15, 0x34, 0xd6, 0xe9, 0xb8, 0x98, 0xfe, 0x06, 0xde,
- 0x1a, 0x0d, 0xe3, 0x4d, 0xc6, 0xf4, 0x25, 0xdf, 0xf5, 0x92, 0x83, 0x7a,
- 0x70, 0x3e, 0x1d, 0xc6, 0xb9, 0xa8, 0xb7, 0xf5, 0x05, 0x65, 0x01, 0x7e,
- 0x9a, 0x76, 0xe0, 0xde, 0x38, 0xf0, 0x4b, 0xce, 0xe3, 0x8f, 0x3b, 0x70,
- 0x25, 0xad, 0xe2, 0x28, 0xf7, 0xc7, 0x11, 0x5a, 0x02, 0xa3, 0xcd, 0x83,
- 0x23, 0x43, 0x8f, 0x62, 0x2a, 0xf5, 0x28, 0x4e, 0x25, 0xdf, 0x31, 0x5d,
- 0x9a, 0xf4, 0x75, 0x5c, 0xb8, 0xc2, 0x7c, 0x6c, 0x9a, 0xda, 0x28, 0x5e,
- 0xd1, 0xca, 0x38, 0xaf, 0x19, 0xa2, 0xf7, 0xb7, 0xf8, 0xdb, 0xfd, 0xf1,
- 0x46, 0x1c, 0x1c, 0xa7, 0x4a, 0x13, 0x3a, 0x12, 0x31, 0x79, 0x56, 0x03,
- 0x62, 0xe4, 0x85, 0xfd, 0x4c, 0xdb, 0xb7, 0x86, 0xee, 0x95, 0x5c, 0x43,
- 0x69, 0xa9, 0xed, 0xcf, 0xae, 0xa3, 0x71, 0x56, 0xcf, 0x4e, 0x72, 0x28,
- 0xea, 0x95, 0xe3, 0xfe, 0x36, 0x11, 0xb4, 0x62, 0xd3, 0xb1, 0x9b, 0xfb,
- 0xd1, 0xc8, 0xfd, 0xf8, 0x06, 0x2e, 0xee, 0x6d, 0xc3, 0x5b, 0xc4, 0xbb,
- 0xd2, 0x65, 0xbe, 0x4e, 0xa7, 0xad, 0x9e, 0x73, 0xa7, 0xcd, 0x54, 0x95,
- 0xe8, 0xb4, 0x0d, 0xbf, 0x88, 0x8a, 0x4e, 0xd3, 0xc4, 0x3f, 0x9f, 0xc7,
- 0x6f, 0xff, 0xcb, 0x4a, 0xda, 0xb3, 0xad, 0x3b, 0x98, 0xe9, 0x41, 0x15,
- 0xaf, 0x70, 0xe1, 0xaa, 0x25, 0x9b, 0xc8, 0xfa, 0x87, 0xe4, 0xfb, 0x85,
- 0xb9, 0xa6, 0x4a, 0xe4, 0x33, 0xcc, 0x3c, 0x4d, 0x0b, 0xe4, 0x29, 0x12,
- 0x67, 0x03, 0x56, 0x3d, 0xbe, 0x2e, 0xde, 0x05, 0x7b, 0xa8, 0x98, 0x79,
- 0x98, 0x77, 0xa6, 0x03, 0x6f, 0xe1, 0xda, 0xa4, 0x0b, 0x8b, 0xe3, 0x1a,
- 0x5e, 0x9e, 0x7c, 0x8d, 0xcf, 0xfa, 0x47, 0x5c, 0xe6, 0x77, 0x5f, 0x3c,
- 0xe3, 0x6f, 0xdd, 0x0d, 0x6d, 0x78, 0x30, 0x2d, 0xeb, 0xcb, 0xe3, 0x83,
- 0x74, 0x44, 0xd2, 0xb2, 0xce, 0x18, 0x7d, 0x43, 0xd6, 0x59, 0xfe, 0xef,
- 0xac, 0xf3, 0xbf, 0x72, 0xbe, 0x05, 0xf4, 0xa5, 0x5c, 0xec, 0x28, 0xc1,
- 0x91, 0xa4, 0x8a, 0xd3, 0x7a, 0x31, 0x2e, 0xa9, 0x52, 0x5f, 0x76, 0x31,
- 0x86, 0x38, 0xd0, 0xcc, 0x9c, 0x71, 0x84, 0x9f, 0x8d, 0xcc, 0x7f, 0xce,
- 0xea, 0x0e, 0x9c, 0xd2, 0x17, 0x10, 0xeb, 0xef, 0xb4, 0x61, 0xb9, 0x46,
- 0xb2, 0x5f, 0x56, 0x8e, 0x73, 0x52, 0xff, 0xb3, 0xae, 0xbb, 0xa4, 0x2f,
- 0x89, 0x31, 0xea, 0x2b, 0x2f, 0xf6, 0x1b, 0xf3, 0xaa, 0x85, 0x35, 0x77,
- 0xca, 0x77, 0xe7, 0x3c, 0x12, 0x82, 0x7f, 0x69, 0x6e, 0xad, 0xca, 0xc6,
- 0x2e, 0xe5, 0x4f, 0x2b, 0x33, 0x78, 0x21, 0x71, 0xec, 0xef, 0x72, 0xd8,
- 0x21, 0xf9, 0x64, 0x1b, 0xe3, 0x10, 0xe3, 0xf2, 0xf1, 0x6d, 0x92, 0xe7,
- 0xd9, 0xc2, 0xef, 0xb5, 0xad, 0xd2, 0xf2, 0x60, 0xb7, 0xf8, 0xde, 0x7b,
- 0x2f, 0x65, 0x38, 0xfa, 0xfb, 0x2f, 0x69, 0xd6, 0xdf, 0xeb, 0x2f, 0x2d,
- 0xb6, 0xfe, 0x7e, 0xf2, 0x92, 0x2f, 0x75, 0x2b, 0x5e, 0x65, 0x38, 0xb0,
- 0x75, 0x6e, 0x05, 0x7d, 0xba, 0xa1, 0x3c, 0xdc, 0x20, 0x5c, 0x72, 0x36,
- 0x8f, 0x08, 0x28, 0x67, 0xa3, 0x92, 0xa7, 0x15, 0x1a, 0xcc, 0xe3, 0x95,
- 0x46, 0xbf, 0x46, 0x3c, 0xee, 0x42, 0xc9, 0x32, 0x0d, 0x17, 0xa8, 0x73,
- 0xc2, 0x28, 0xed, 0xf8, 0xff, 0x20, 0xba, 0x17, 0xed, 0x85, 0x16, 0xf6,
- 0x98, 0x66, 0x7f, 0x48, 0x6a, 0x0c, 0x32, 0xaf, 0x03, 0x1f, 0x70, 0x2f,
- 0x7f, 0x35, 0x5a, 0x84, 0xf7, 0x53, 0x1a, 0x2e, 0xa5, 0xdb, 0xb0, 0x7b,
- 0x32, 0xc3, 0x33, 0x4e, 0x59, 0xfc, 0x5b, 0x63, 0x8e, 0xe9, 0xc0, 0xc1,
- 0xa8, 0x86, 0x58, 0xe2, 0x75, 0xb3, 0x40, 0xf3, 0x4d, 0xf9, 0xed, 0x0e,
- 0x1c, 0x48, 0x4f, 0x63, 0x72, 0xe0, 0x63, 0xd3, 0xae, 0x75, 0xe1, 0xa3,
- 0xd0, 0x34, 0x26, 0x0e, 0x49, 0x5f, 0x4f, 0x47, 0xff, 0x90, 0x86, 0xde,
- 0x84, 0x0d, 0x7b, 0x96, 0xb7, 0xa0, 0x7f, 0xb2, 0x19, 0xc6, 0x98, 0x07,
- 0x7b, 0xd2, 0x69, 0x4c, 0x8d, 0x4e, 0xe3, 0x4c, 0x52, 0x6b, 0x2c, 0x50,
- 0xa6, 0x71, 0x9a, 0xcf, 0xd9, 0x91, 0x78, 0x1b, 0x06, 0xe7, 0xd8, 0x99,
- 0x94, 0x9a, 0xa4, 0x3c, 0x67, 0x1a, 0xdd, 0xa9, 0xbb, 0xd5, 0x44, 0x28,
- 0x4f, 0xa2, 0xa7, 0x3d, 0x53, 0xab, 0x27, 0xbe, 0xa6, 0x35, 0xa5, 0x8f,
- 0xfb, 0x74, 0x34, 0x9d, 0xab, 0xdb, 0xdf, 0x59, 0x0b, 0xd1, 0xd1, 0x37,
- 0xd4, 0xc2, 0x31, 0x1a, 0xba, 0x13, 0xd2, 0x1b, 0xf5, 0xf1, 0x99, 0x26,
- 0x7e, 0xa9, 0x7b, 0xdd, 0x8b, 0xf9, 0xf7, 0xb0, 0xde, 0x89, 0x2d, 0x9c,
- 0x6b, 0x8a, 0x79, 0x90, 0xa6, 0x78, 0x1b, 0x0d, 0xd8, 0xf1, 0x9e, 0x4e,
- 0xce, 0x53, 0x69, 0xc7, 0xab, 0x7a, 0x09, 0x22, 0x65, 0x76, 0xd4, 0x87,
- 0x18, 0xa7, 0xb3, 0x71, 0xfb, 0xc3, 0xa4, 0x82, 0x47, 0x89, 0xa9, 0x27,
- 0x42, 0xf5, 0xed, 0xab, 0x85, 0xd1, 0x1d, 0x52, 0x70, 0x4d, 0xbb, 0x61,
- 0x1a, 0x8c, 0x5d, 0x2e, 0x7f, 0x6e, 0x8f, 0x7e, 0x6d, 0x66, 0xfa, 0x9b,
- 0x5f, 0x98, 0xb9, 0x71, 0x33, 0x94, 0xf1, 0x29, 0x8e, 0x5b, 0xbc, 0xac,
- 0xbe, 0x53, 0xc6, 0xb9, 0x89, 0xe9, 0x32, 0x4e, 0xea, 0xd1, 0xb7, 0xc6,
- 0xe9, 0xd8, 0x39, 0x14, 0xb1, 0xe4, 0xdd, 0x95, 0xc0, 0x52, 0x07, 0xc4,
- 0x9f, 0xea, 0xd5, 0x2b, 0x40, 0xd7, 0xb4, 0x3e, 0x87, 0x5c, 0xc7, 0x1f,
- 0xd8, 0x08, 0xd1, 0x95, 0xe4, 0x92, 0x6f, 0x63, 0x4f, 0x74, 0x14, 0xcc,
- 0x27, 0x89, 0x73, 0xfe, 0xf5, 0x23, 0x48, 0xe1, 0xf9, 0x74, 0x0a, 0x2f,
- 0x50, 0x47, 0x86, 0x75, 0x6e, 0x29, 0x8d, 0x3f, 0x8f, 0xbe, 0x8d, 0x98,
- 0xb5, 0x67, 0x47, 0xb1, 0x21, 0xfa, 0xf7, 0x55, 0xc2, 0x11, 0x77, 0x24,
- 0x56, 0x72, 0x7e, 0xd1, 0xab, 0xb7, 0xd5, 0xc0, 0x97, 0x9c, 0x7f, 0x25,
- 0x7a, 0x46, 0x4c, 0xf3, 0x7b, 0x8c, 0x5f, 0x3f, 0x23, 0xbf, 0xba, 0x96,
- 0x3d, 0x03, 0x55, 0x40, 0x7d, 0x6b, 0x56, 0x1c, 0x6b, 0xe3, 0x3e, 0x57,
- 0x0b, 0xaf, 0x47, 0xc9, 0xb8, 0xa6, 0x2c, 0x8e, 0xc9, 0xbe, 0x93, 0x37,
- 0x8e, 0x7b, 0xf0, 0x14, 0x39, 0x4a, 0xfe, 0xe1, 0x1f, 0x28, 0x12, 0xcb,
- 0x6a, 0x0e, 0x91, 0xef, 0x1f, 0xf2, 0x28, 0x4b, 0xf6, 0xb9, 0xf0, 0x68,
- 0x4c, 0xea, 0x37, 0xcd, 0xe8, 0xd9, 0xaf, 0xf1, 0x1e, 0xaf, 0x7e, 0x81,
- 0x39, 0xe9, 0x69, 0xf8, 0x3c, 0x23, 0xe4, 0x55, 0x6e, 0x62, 0xb1, 0xe3,
- 0x70, 0x29, 0x8a, 0x0e, 0xab, 0xb0, 0x1d, 0x2e, 0x47, 0xf1, 0x61, 0x37,
- 0x6a, 0x18, 0xdb, 0xdc, 0xe3, 0x17, 0x31, 0xb9, 0x0f, 0x6a, 0x51, 0xf8,
- 0x73, 0x33, 0x5f, 0x93, 0x3e, 0x5b, 0x00, 0xa5, 0xe3, 0xdb, 0x91, 0x8e,
- 0x05, 0x51, 0x3c, 0x4e, 0x2a, 0x35, 0x7e, 0x5c, 0xa9, 0xe7, 0x33, 0x1f,
- 0x8a, 0x69, 0x9c, 0x2b, 0xc3, 0x75, 0x56, 0x73, 0x5c, 0x5f, 0xc2, 0xbb,
- 0x5e, 0x7a, 0x65, 0xd7, 0xf4, 0x37, 0x50, 0x30, 0x70, 0xeb, 0x2c, 0x97,
- 0x16, 0xc2, 0x3c, 0x72, 0x91, 0xd6, 0x67, 0x91, 0x39, 0xd7, 0xf5, 0x70,
- 0x76, 0x4d, 0x41, 0x59, 0x93, 0xb3, 0x8d, 0xb6, 0x30, 0x57, 0xea, 0x5f,
- 0xb8, 0x4c, 0xfb, 0xb9, 0x9f, 0xf2, 0xde, 0x60, 0x6e, 0xd8, 0x19, 0x13,
- 0xbb, 0xff, 0x81, 0x42, 0xbf, 0xc1, 0x4c, 0xaa, 0x08, 0x1f, 0xa7, 0x3c,
- 0x8a, 0x8f, 0xeb, 0xf9, 0x0b, 0x5e, 0xff, 0x73, 0xae, 0x67, 0xc7, 0x7e,
- 0x6f, 0xeb, 0x49, 0xc5, 0xdb, 0xbe, 0x4e, 0xf1, 0xa9, 0x3b, 0x94, 0x62,
- 0x5c, 0x1e, 0x2d, 0xc5, 0x15, 0xc6, 0xe2, 0x1b, 0xa3, 0xe5, 0xb8, 0x3a,
- 0x5a, 0x49, 0x5f, 0xd1, 0x38, 0x87, 0x69, 0x96, 0x68, 0x6e, 0xcc, 0xa4,
- 0x5f, 0xc0, 0x9c, 0xd8, 0x02, 0x7c, 0x9c, 0xde, 0x82, 0xd2, 0x98, 0x70,
- 0x76, 0x0f, 0x3e, 0xe2, 0xf5, 0x0f, 0xd3, 0x13, 0x28, 0xdc, 0xf7, 0x39,
- 0xef, 0x31, 0xcd, 0x87, 0xb8, 0xc6, 0xab, 0xe9, 0x0e, 0x14, 0xef, 0xdb,
- 0x06, 0xc7, 0x3e, 0xb3, 0xab, 0x27, 0x84, 0x9f, 0xda, 0xb9, 0x96, 0x6e,
- 0xdd, 0x3b, 0xb5, 0xd8, 0x1e, 0xe4, 0x1c, 0x3a, 0xe7, 0x3c, 0xae, 0x2c,
- 0x19, 0xdf, 0x86, 0xd2, 0x7d, 0x1e, 0x6c, 0xa5, 0x2e, 0x27, 0xa0, 0x05,
- 0xd6, 0x29, 0xdb, 0x90, 0x77, 0x38, 0xa3, 0x83, 0x4d, 0xe3, 0x19, 0x1f,
- 0x79, 0xa8, 0x41, 0xea, 0x43, 0xc7, 0x95, 0x11, 0xcb, 0x47, 0xdc, 0x72,
- 0xfe, 0x04, 0xd3, 0xe9, 0x22, 0x9c, 0x4d, 0x89, 0x8e, 0xe4, 0xec, 0xda,
- 0x04, 0xf2, 0xf7, 0x11, 0x23, 0x47, 0x75, 0x8b, 0x43, 0x88, 0x6f, 0x8c,
- 0xa6, 0xef, 0xe6, 0x5f, 0x41, 0xec, 0x49, 0xd4, 0xd0, 0xb7, 0x16, 0x60,
- 0xcd, 0x3e, 0xe9, 0x91, 0x4e, 0xdd, 0xef, 0xa2, 0x35, 0x8d, 0xa5, 0xef,
- 0xe6, 0x5b, 0x0d, 0xb4, 0x53, 0x6f, 0x8b, 0x01, 0x39, 0xab, 0x61, 0x62,
- 0x5a, 0x3f, 0xae, 0xd8, 0x62, 0x92, 0x6f, 0xb5, 0xd1, 0xe7, 0x5b, 0xd1,
- 0x33, 0x84, 0xf6, 0x83, 0x0d, 0xd2, 0xb7, 0x75, 0x62, 0x84, 0xf9, 0xd3,
- 0x65, 0xe6, 0x1c, 0xd4, 0xb9, 0x9a, 0x17, 0xce, 0xc3, 0xf0, 0xa8, 0x0b,
- 0x3f, 0x1a, 0xf5, 0xa0, 0x31, 0xf6, 0x39, 0x31, 0xa3, 0x10, 0xc7, 0xa9,
- 0xef, 0x49, 0xf2, 0x9f, 0x8f, 0xa2, 0x2a, 0x26, 0x18, 0x6b, 0x3f, 0x8c,
- 0x56, 0x62, 0x9c, 0xb9, 0xd6, 0x75, 0xe2, 0x4c, 0x9a, 0x7b, 0xf3, 0x01,
- 0xf3, 0x8e, 0xef, 0xa5, 0x83, 0xf8, 0x55, 0x34, 0x88, 0x57, 0xa9, 0xc7,
- 0xba, 0x98, 0x9b, 0x32, 0x1d, 0x53, 0x70, 0xe8, 0xb8, 0x92, 0x47, 0xbb,
- 0xf0, 0xc7, 0x34, 0xcf, 0x48, 0xd6, 0x2e, 0xb4, 0xf1, 0x56, 0xfa, 0x91,
- 0xf4, 0xff, 0x25, 0x3e, 0x38, 0xf4, 0x11, 0x90, 0xd3, 0x05, 0x73, 0x75,
- 0x42, 0xaf, 0x7b, 0x0a, 0x15, 0xf4, 0xa5, 0x2f, 0x4d, 0x55, 0x93, 0x9a,
- 0x58, 0x32, 0x74, 0x2d, 0xaa, 0xa9, 0x57, 0xad, 0x35, 0x18, 0x8a, 0x73,
- 0x39, 0x39, 0x46, 0xe5, 0x0e, 0xae, 0x5f, 0x23, 0x66, 0x38, 0xe8, 0x32,
- 0x26, 0xef, 0xbb, 0x8e, 0xfb, 0x0e, 0xfd, 0x69, 0x75, 0x86, 0x03, 0xd1,
- 0x9f, 0x6d, 0x77, 0xd6, 0xb1, 0xa4, 0x96, 0xbd, 0x37, 0xf4, 0x46, 0x34,
- 0x56, 0x2d, 0x3d, 0xa5, 0x93, 0x08, 0x52, 0x2f, 0x77, 0xcb, 0x15, 0x4c,
- 0xbc, 0x45, 0x4c, 0xb9, 0x9a, 0x14, 0xbe, 0x24, 0x3c, 0xa9, 0x8b, 0x31,
- 0xa9, 0x84, 0x3c, 0x41, 0xc3, 0x4e, 0x72, 0x79, 0x5f, 0x7c, 0x8a, 0xb9,
- 0xca, 0x57, 0xc9, 0xd5, 0x4a, 0x39, 0x8d, 0xc1, 0xe7, 0xb5, 0x62, 0x0f,
- 0x7d, 0xb3, 0x40, 0x5b, 0x8c, 0x35, 0xe4, 0x41, 0x0e, 0x8d, 0xa1, 0xe4,
- 0x09, 0x89, 0x27, 0x40, 0x6d, 0x5c, 0x95, 0x7e, 0xcf, 0xfa, 0x9f, 0xe1,
- 0x7e, 0xb4, 0x57, 0xb9, 0x20, 0x3d, 0x9a, 0x37, 0xd1, 0x84, 0xd4, 0xd7,
- 0xad, 0xde, 0x30, 0xdc, 0x61, 0xcd, 0xb8, 0x88, 0x45, 0x16, 0x23, 0x2f,
- 0x0c, 0x8b, 0x3c, 0x95, 0xd4, 0xbf, 0x8a, 0x77, 0xa9, 0xd7, 0x2b, 0x51,
- 0xdf, 0xcc, 0x83, 0xa8, 0x3f, 0x73, 0xc5, 0x2e, 0xfd, 0x2b, 0xb9, 0x3f,
- 0x08, 0x8d, 0xf3, 0x7d, 0x1a, 0x0d, 0x61, 0x40, 0x95, 0xef, 0xc2, 0x1b,
- 0x5b, 0xd1, 0x3d, 0x22, 0x32, 0x98, 0x66, 0x39, 0xf1, 0xf1, 0x09, 0xeb,
- 0xf9, 0xf2, 0xec, 0x3b, 0xf3, 0x0e, 0xaf, 0x6a, 0x20, 0x97, 0x7b, 0x4c,
- 0xe3, 0x68, 0xd2, 0x03, 0xc7, 0xf2, 0xff, 0x41, 0x3d, 0x4c, 0x63, 0x34,
- 0xa5, 0x91, 0x53, 0x16, 0xc1, 0x53, 0x15, 0x44, 0x3f, 0xe3, 0x78, 0x8c,
- 0xf7, 0xa7, 0x63, 0x45, 0x30, 0xaa, 0x32, 0xcf, 0xfc, 0x6a, 0xfc, 0xba,
- 0x39, 0xf5, 0xb8, 0xcc, 0x29, 0xdf, 0x7f, 0xce, 0x31, 0x73, 0xe5, 0xd8,
- 0x23, 0x36, 0xc7, 0xae, 0x9a, 0x53, 0xad, 0xb3, 0x7f, 0x2f, 0xb3, 0xce,
- 0x10, 0x45, 0x6c, 0x55, 0x52, 0x6f, 0xb1, 0xf4, 0xd2, 0x4d, 0xbd, 0xcc,
- 0xd1, 0xde, 0x36, 0x1f, 0xb3, 0xe4, 0x9a, 0xaa, 0x16, 0x9e, 0x5f, 0x1b,
- 0xff, 0xbc, 0x5a, 0xea, 0xa5, 0x12, 0xc3, 0x5c, 0x61, 0xad, 0xf1, 0x0c,
- 0xfe, 0xd1, 0xbc, 0x74, 0xdb, 0x3c, 0x15, 0xbc, 0x26, 0xf1, 0xe8, 0x52,
- 0xb6, 0x1f, 0xed, 0xce, 0xe6, 0x02, 0xd3, 0x38, 0x99, 0x94, 0x58, 0xe0,
- 0xc1, 0x06, 0xa9, 0x43, 0xa9, 0xde, 0x3e, 0x03, 0x53, 0xe4, 0x7e, 0xef,
- 0x50, 0xf7, 0x4c, 0x80, 0xfc, 0x53, 0xe4, 0x7f, 0xb3, 0xe3, 0x55, 0x04,
- 0xa9, 0x4a, 0xe9, 0x29, 0x08, 0x9e, 0x4e, 0x63, 0x57, 0xf2, 0x75, 0xe2,
- 0xda, 0xc7, 0xe4, 0x43, 0x5d, 0xe4, 0xda, 0xd3, 0xe8, 0x49, 0x35, 0xe3,
- 0xe5, 0xfd, 0x2d, 0xc4, 0x18, 0xc1, 0x4a, 0xdf, 0x99, 0xcb, 0xf6, 0x66,
- 0x1c, 0x1c, 0x4b, 0x23, 0x75, 0x58, 0x62, 0xa4, 0x9c, 0xc7, 0x92, 0xf8,
- 0xa8, 0x21, 0x9a, 0x38, 0x0d, 0x83, 0x7f, 0xf7, 0x24, 0xb6, 0x21, 0x72,
- 0xf8, 0x6d, 0x72, 0xfc, 0x69, 0xac, 0x1e, 0xd0, 0xd6, 0x1f, 0xc1, 0x34,
- 0xd6, 0x32, 0x7e, 0x26, 0x13, 0x2d, 0x9c, 0xbf, 0x19, 0xbd, 0xfb, 0xbd,
- 0x01, 0x87, 0x6d, 0x0e, 0x63, 0x94, 0x07, 0x3b, 0x27, 0x23, 0x30, 0x46,
- 0xe4, 0x8c, 0x81, 0x0b, 0xc1, 0xb8, 0x47, 0xf9, 0x90, 0x3c, 0xb9, 0x3e,
- 0xee, 0x65, 0x7e, 0xe6, 0x35, 0xd6, 0x2a, 0x3e, 0x4f, 0x9e, 0x4d, 0xfa,
- 0x59, 0x73, 0x70, 0x46, 0x57, 0x50, 0x70, 0xbf, 0x82, 0x10, 0x63, 0x97,
- 0xa7, 0x9a, 0x31, 0x65, 0x44, 0x47, 0xef, 0x10, 0xd7, 0x7b, 0x73, 0xdf,
- 0x64, 0xbf, 0x1e, 0xe1, 0x7c, 0xb2, 0x77, 0x2d, 0xe8, 0x9d, 0xf4, 0x75,
- 0x9c, 0x81, 0xdb, 0xe2, 0x5c, 0xbd, 0x43, 0xb9, 0x7b, 0x50, 0xfc, 0x71,
- 0x83, 0x37, 0x30, 0x47, 0x91, 0x7b, 0x77, 0x10, 0xbf, 0x66, 0xdf, 0x6f,
- 0x28, 0xc9, 0xe5, 0xe4, 0xa5, 0x36, 0xf1, 0x8b, 0x6e, 0xcb, 0x5f, 0x44,
- 0x17, 0xbd, 0xc9, 0x08, 0x6d, 0xfa, 0xc7, 0x66, 0xaa, 0xb5, 0x95, 0x72,
- 0x36, 0x48, 0xaf, 0xc7, 0xe2, 0x26, 0xe7, 0xa5, 0xee, 0xe6, 0x94, 0xd8,
- 0xdd, 0xdd, 0xee, 0xa2, 0x3d, 0xe5, 0x13, 0x9f, 0x0a, 0x26, 0x5c, 0x70,
- 0x1d, 0x29, 0x42, 0xfe, 0xb0, 0xf0, 0x34, 0xa8, 0xa5, 0xcc, 0xfb, 0xe5,
- 0x3c, 0xc3, 0x30, 0x6d, 0xd4, 0x36, 0x41, 0x1f, 0x8b, 0xba, 0xb1, 0x68,
- 0xc2, 0x8d, 0x1f, 0x11, 0x03, 0x6a, 0x26, 0x34, 0x1c, 0x27, 0x06, 0xb8,
- 0x27, 0x02, 0x98, 0x24, 0x06, 0xcc, 0xc9, 0xd6, 0x3e, 0xde, 0x4c, 0xcf,
- 0x9f, 0x8b, 0x42, 0x79, 0x96, 0xe8, 0x31, 0xb7, 0xaf, 0xb2, 0xa7, 0x2d,
- 0xc4, 0x3d, 0xd9, 0xdf, 0x00, 0x76, 0x0f, 0xa5, 0xb1, 0x6a, 0x9f, 0x89,
- 0x9f, 0xeb, 0xf5, 0xee, 0x02, 0x45, 0xf2, 0x04, 0x13, 0x69, 0x5d, 0xce,
- 0x4d, 0x7a, 0xd7, 0xcb, 0xb9, 0xe2, 0xf6, 0x4a, 0x13, 0x79, 0x21, 0xaf,
- 0x4e, 0xb4, 0x5f, 0x5f, 0xa0, 0x48, 0xdc, 0xaa, 0xf7, 0x6c, 0xc1, 0x7c,
- 0x64, 0x7a, 0x65, 0x0f, 0x62, 0x8b, 0xaa, 0xd0, 0x1f, 0x5b, 0xb0, 0xa7,
- 0xcc, 0x70, 0x5d, 0x6b, 0x30, 0xcd, 0x4d, 0xa1, 0xdf, 0x56, 0x59, 0xb5,
- 0x65, 0xdb, 0x1f, 0x71, 0xed, 0x6d, 0x5c, 0xb7, 0xac, 0xbd, 0x03, 0xb1,
- 0xbd, 0x0a, 0xd2, 0xfe, 0x0e, 0x44, 0x47, 0x3b, 0xd0, 0xbf, 0x57, 0x30,
- 0xa1, 0x8f, 0x98, 0x60, 0x76, 0x3d, 0x1b, 0x7a, 0x0c, 0x57, 0x2d, 0x16,
- 0x20, 0x63, 0xbc, 0x01, 0x8f, 0x6d, 0xf6, 0x3e, 0xe4, 0x53, 0xfe, 0x8c,
- 0xef, 0x34, 0x0f, 0x08, 0xa7, 0xf6, 0xf7, 0xf5, 0x72, 0xff, 0x1f, 0x3f,
- 0x24, 0xf1, 0xc6, 0x34, 0xfb, 0xc8, 0x59, 0x51, 0x26, 0x6b, 0xd0, 0xa4,
- 0x3e, 0xfe, 0x71, 0x8d, 0xe6, 0x9b, 0xe9, 0x67, 0x6c, 0xbf, 0xb8, 0xaf,
- 0x7e, 0xcb, 0x16, 0xe1, 0x31, 0xcb, 0x84, 0xdb, 0xa5, 0x71, 0xe1, 0xf0,
- 0x7d, 0x48, 0x3d, 0xce, 0xf5, 0x70, 0xaf, 0x9c, 0xf1, 0x2f, 0x4c, 0xe1,
- 0x72, 0x76, 0x4d, 0x53, 0x8f, 0x12, 0xfb, 0x6c, 0x13, 0x7e, 0xf4, 0x94,
- 0xc1, 0xb8, 0xd6, 0x20, 0xcf, 0xbf, 0x29, 0x3f, 0xd7, 0xdb, 0x8c, 0xfe,
- 0xfd, 0xc2, 0x35, 0x84, 0x97, 0xf9, 0x8c, 0x0f, 0xd0, 0x82, 0xe4, 0x64,
- 0xe6, 0x59, 0xd1, 0xc4, 0x9d, 0xb6, 0x22, 0xfb, 0x7e, 0x1a, 0xbb, 0x69,
- 0x97, 0x2e, 0xce, 0xcf, 0xf8, 0xc2, 0xf9, 0xb4, 0x40, 0x81, 0x3c, 0x6f,
- 0xe2, 0xc7, 0xe6, 0x9e, 0x2a, 0xd1, 0x8d, 0xcc, 0x7f, 0xba, 0x4a, 0x30,
- 0x63, 0x53, 0xe8, 0x0f, 0xad, 0xf5, 0x75, 0xfe, 0xf5, 0xb6, 0x64, 0xf4,
- 0x21, 0xf7, 0x9e, 0xfe, 0x3d, 0xf2, 0x5c, 0xe0, 0x7d, 0x22, 0x53, 0x07,
- 0x76, 0xef, 0x85, 0x51, 0xa8, 0x49, 0xaf, 0xa0, 0x03, 0x7d, 0xd4, 0xef,
- 0xce, 0x64, 0x07, 0x0e, 0xd2, 0x67, 0x87, 0xf5, 0x13, 0x35, 0x36, 0xd4,
- 0xcd, 0xd8, 0x31, 0xf5, 0x93, 0x45, 0xc4, 0xd3, 0x25, 0xcb, 0xfc, 0xf4,
- 0xaf, 0x0e, 0xc4, 0x53, 0x63, 0x73, 0xad, 0x3e, 0x9f, 0x4d, 0xe2, 0x9f,
- 0xe8, 0xa2, 0x13, 0x85, 0x03, 0xa7, 0xe1, 0x1c, 0xe8, 0x44, 0x81, 0xbf,
- 0x09, 0x0f, 0x87, 0x2e, 0x99, 0x57, 0x35, 0x87, 0xfb, 0x24, 0xf5, 0x73,
- 0x22, 0x58, 0xc3, 0x7c, 0x92, 0x39, 0xcc, 0xc8, 0x3c, 0xfa, 0x7e, 0x03,
- 0xf9, 0xae, 0xf4, 0xf4, 0x6d, 0x58, 0xbb, 0x5c, 0x72, 0x75, 0x85, 0xb6,
- 0x5d, 0xcd, 0x5c, 0x53, 0x53, 0x9f, 0xb7, 0xce, 0x5f, 0x90, 0x87, 0x55,
- 0x7a, 0xf0, 0x8c, 0x75, 0xee, 0x40, 0xae, 0x6f, 0x67, 0x8e, 0xb0, 0x1d,
- 0x35, 0x31, 0xc3, 0x14, 0x7d, 0x9f, 0x44, 0xe4, 0x25, 0x1b, 0xe5, 0x68,
- 0x5c, 0xe6, 0xdf, 0x32, 0xa3, 0x88, 0x4d, 0xfb, 0xdb, 0x27, 0x14, 0xdd,
- 0xf5, 0xc8, 0xb8, 0x82, 0xc0, 0x00, 0xe7, 0x0a, 0xfd, 0xf5, 0xdc, 0x4c,
- 0x7d, 0x2c, 0xc7, 0xf9, 0xb6, 0x93, 0x27, 0x6c, 0x47, 0x09, 0xc7, 0xbb,
- 0x35, 0xc1, 0x86, 0xc8, 0x4a, 0xe9, 0xa5, 0xa4, 0x43, 0xfe, 0xd6, 0x62,
- 0x45, 0xf8, 0x90, 0xbf, 0x71, 0xad, 0x22, 0xdc, 0x45, 0xc6, 0xe9, 0xae,
- 0xba, 0xf1, 0x8b, 0xd9, 0x9e, 0x57, 0x03, 0xf1, 0xc1, 0x63, 0x9d, 0x85,
- 0x7c, 0xed, 0xe6, 0x79, 0x89, 0x4c, 0xbd, 0xda, 0x19, 0x97, 0xbc, 0xe2,
- 0x58, 0x68, 0x55, 0xb4, 0x91, 0x58, 0x67, 0x36, 0x8d, 0xd1, 0xee, 0x2f,
- 0xa3, 0x12, 0xff, 0x33, 0x2a, 0xb8, 0xe6, 0xc1, 0xff, 0x8a, 0xe6, 0x4b,
- 0xbe, 0x9c, 0x92, 0x7a, 0xe4, 0xb9, 0xa4, 0x61, 0x52, 0xaf, 0x2d, 0x6b,
- 0x69, 0x4b, 0x81, 0x50, 0x31, 0x50, 0xd5, 0xfd, 0x8c, 0xd3, 0xca, 0xdf,
- 0x4b, 0x50, 0xc6, 0x18, 0x30, 0x30, 0xf2, 0xfb, 0x6a, 0xaf, 0xc4, 0xe1,
- 0x42, 0xa9, 0x81, 0xda, 0xb1, 0x33, 0xf4, 0x2f, 0x66, 0x2a, 0x7b, 0x76,
- 0xf5, 0xc2, 0x5e, 0xb1, 0xd3, 0x00, 0xf2, 0xe3, 0x17, 0x69, 0x93, 0x2a,
- 0xce, 0x47, 0x7d, 0xfa, 0x3a, 0xdb, 0x37, 0x68, 0xff, 0x8b, 0x6e, 0xc3,
- 0xee, 0x45, 0xda, 0xa3, 0x78, 0xda, 0xc2, 0xee, 0x30, 0x7a, 0x18, 0x1b,
- 0xc8, 0xe3, 0x0e, 0x3c, 0x63, 0x53, 0x51, 0x10, 0xf3, 0xa9, 0x3e, 0xe6,
- 0xdb, 0x3d, 0x7c, 0x86, 0x70, 0xcc, 0x0a, 0x72, 0xc0, 0x67, 0xa3, 0xf5,
- 0x9e, 0x5f, 0x63, 0x03, 0xfd, 0x51, 0x9e, 0x21, 0x6b, 0xd2, 0x50, 0xcc,
- 0xbc, 0xf2, 0x14, 0xd7, 0xb1, 0xb3, 0x2c, 0xf3, 0xdc, 0xd2, 0xec, 0xdc,
- 0xf1, 0x11, 0xe1, 0x5f, 0x2b, 0xb0, 0xce, 0x9a, 0x3b, 0x68, 0xf9, 0xe6,
- 0x01, 0x39, 0x5b, 0x5e, 0xa7, 0x21, 0x91, 0x6e, 0xc6, 0xb6, 0xf2, 0x05,
- 0x38, 0x98, 0xd8, 0x8e, 0xa5, 0xe4, 0xc1, 0x4f, 0x96, 0x1b, 0x8c, 0x8d,
- 0xc4, 0xa1, 0xb8, 0xa6, 0xde, 0xa7, 0x3c, 0x90, 0xed, 0x3f, 0x54, 0xc2,
- 0x11, 0x97, 0x98, 0x97, 0x87, 0x41, 0x75, 0x3e, 0x8a, 0xac, 0x33, 0x7f,
- 0x99, 0xb9, 0xfb, 0x47, 0xbc, 0xd9, 0x38, 0x48, 0xd4, 0x88, 0x5b, 0xe7,
- 0x2d, 0x02, 0x2f, 0x90, 0x4b, 0xa4, 0x18, 0x01, 0xf3, 0xc2, 0x5a, 0x6a,
- 0x33, 0x0a, 0x60, 0x54, 0x0b, 0x26, 0xca, 0x98, 0x79, 0x77, 0xc8, 0x54,
- 0x9e, 0x95, 0x29, 0x77, 0x3d, 0xc5, 0x6b, 0x62, 0x5b, 0xc2, 0x2f, 0xe4,
- 0xf7, 0x42, 0xb4, 0xd2, 0x9e, 0x2a, 0x29, 0x73, 0xc2, 0x3a, 0xb7, 0xe9,
- 0xd5, 0x0d, 0x5b, 0x03, 0x3e, 0xdb, 0x97, 0xb1, 0xc1, 0xf5, 0xb5, 0xdc,
- 0xff, 0xd2, 0x06, 0xcc, 0x1c, 0x96, 0x78, 0xf6, 0xfb, 0xcf, 0x52, 0x18,
- 0x37, 0xcf, 0x52, 0x88, 0x5e, 0xbd, 0x67, 0xde, 0x45, 0xfd, 0xd4, 0x53,
- 0xb6, 0xa3, 0x26, 0x2a, 0x44, 0xc7, 0x9b, 0xdd, 0x92, 0x87, 0xda, 0xc8,
- 0x23, 0x8c, 0x74, 0xd2, 0x2d, 0xb1, 0xd2, 0x11, 0x07, 0x16, 0xc5, 0x0d,
- 0xe4, 0x87, 0xb5, 0x03, 0xd7, 0xec, 0x37, 0xcc, 0xf6, 0xea, 0x79, 0xcc,
- 0x03, 0x6f, 0xad, 0xb9, 0x8f, 0xb2, 0xdb, 0xb5, 0x1f, 0x9b, 0x0f, 0x56,
- 0x8a, 0x8c, 0x3f, 0x72, 0x67, 0xea, 0xcc, 0x0b, 0xa9, 0x97, 0x9c, 0x4e,
- 0x4c, 0xda, 0xcf, 0xdf, 0x98, 0x5f, 0xbb, 0xed, 0xba, 0xf0, 0x19, 0xb1,
- 0xd3, 0xd9, 0x67, 0xdb, 0xc4, 0x66, 0x3d, 0xb4, 0xd3, 0x69, 0x8c, 0x25,
- 0x1b, 0x30, 0x90, 0x10, 0x1d, 0x47, 0x70, 0x99, 0xfc, 0xb0, 0x76, 0x70,
- 0x1a, 0xc3, 0xe4, 0x87, 0xbe, 0xb8, 0xf7, 0x00, 0x35, 0x89, 0x6d, 0x6a,
- 0x93, 0xc5, 0x93, 0x5c, 0x5a, 0x4e, 0x86, 0xaf, 0x5a, 0x7a, 0x97, 0x18,
- 0xb3, 0x87, 0xeb, 0xbd, 0x97, 0x3c, 0xa9, 0x39, 0x96, 0x0f, 0xad, 0xac,
- 0x14, 0xc5, 0x9a, 0xf4, 0x2b, 0x32, 0xf7, 0x45, 0x29, 0x4b, 0x91, 0xe6,
- 0xc3, 0x5a, 0xeb, 0x5e, 0x8f, 0x75, 0xae, 0xc1, 0x51, 0x2e, 0x31, 0x58,
- 0xe2, 0x2e, 0xf9, 0xf7, 0x72, 0x89, 0xbb, 0x61, 0xca, 0xb6, 0x98, 0x7b,
- 0xb6, 0x14, 0xee, 0x07, 0x3c, 0xa8, 0x79, 0x80, 0x31, 0x72, 0x89, 0x82,
- 0xf2, 0x25, 0x7e, 0x63, 0xa9, 0xad, 0x19, 0xa8, 0xd6, 0x88, 0x3f, 0x6e,
- 0xb3, 0x27, 0xf1, 0x3b, 0xce, 0xd1, 0x01, 0x73, 0x6f, 0x21, 0x36, 0xec,
- 0x9d, 0x43, 0x5b, 0xf5, 0x48, 0x7d, 0xdd, 0xe5, 0x0a, 0x47, 0x43, 0xae,
- 0x58, 0xbd, 0xee, 0x54, 0x16, 0x33, 0x1e, 0xcb, 0xfe, 0xc9, 0xf3, 0xbf,
- 0x72, 0x1b, 0x5f, 0xaa, 0x60, 0x7c, 0x7b, 0xd2, 0x92, 0x41, 0x6a, 0xc0,
- 0x32, 0xee, 0xdf, 0xee, 0xd3, 0xd4, 0xcd, 0x7d, 0xba, 0x0f, 0x8e, 0x27,
- 0x2a, 0xc9, 0xbf, 0xee, 0x1e, 0x43, 0x0a, 0x18, 0x43, 0xee, 0x8d, 0x99,
- 0x5d, 0x5b, 0x43, 0x45, 0x52, 0x17, 0xb2, 0x62, 0x48, 0xbb, 0x8d, 0x38,
- 0x5a, 0x2a, 0x76, 0xe1, 0xab, 0x21, 0xc6, 0xe9, 0x99, 0xdf, 0xc4, 0x3e,
- 0xac, 0x3a, 0x5e, 0xf6, 0xb7, 0x0e, 0xec, 0x22, 0x66, 0xca, 0xd9, 0x6e,
- 0xa7, 0xa6, 0xd1, 0xff, 0x3b, 0xd0, 0xc3, 0x39, 0x5f, 0x26, 0x6e, 0x0e,
- 0x10, 0x37, 0x6f, 0x2c, 0x3b, 0xf1, 0x93, 0x1a, 0xd4, 0xd1, 0x08, 0xa6,
- 0xfe, 0x5b, 0xb9, 0xe0, 0xe6, 0x52, 0x7f, 0xc7, 0x27, 0x16, 0x6e, 0xca,
- 0xdc, 0x32, 0xdf, 0xec, 0xb9, 0x17, 0xf2, 0xdf, 0x85, 0x52, 0x4b, 0x34,
- 0x9d, 0xda, 0xff, 0x36, 0x77, 0x56, 0x8a, 0xac, 0x77, 0x93, 0x43, 0xb0,
- 0x76, 0x76, 0x4f, 0x7e, 0x9a, 0x98, 0x6b, 0xe5, 0x08, 0x8c, 0xb9, 0x11,
- 0xac, 0x59, 0xae, 0xe2, 0x6a, 0x74, 0x1a, 0x05, 0x87, 0x72, 0xf8, 0x64,
- 0x36, 0x9d, 0x22, 0x36, 0x0d, 0x43, 0xf0, 0xa8, 0x91, 0xfb, 0x62, 0xd0,
- 0x4f, 0x4a, 0x30, 0x91, 0xd4, 0x88, 0x99, 0x26, 0xfa, 0x43, 0x2e, 0x72,
- 0xdb, 0xee, 0x93, 0x79, 0x56, 0x9c, 0x28, 0x21, 0x86, 0xe7, 0x78, 0xb7,
- 0x70, 0x6e, 0xc1, 0x1f, 0xe6, 0x18, 0x23, 0x76, 0xe4, 0x2d, 0x93, 0xbc,
- 0xe2, 0x73, 0xf3, 0x42, 0x9b, 0xdc, 0xb7, 0x00, 0xc3, 0x7b, 0xc5, 0xfe,
- 0x7c, 0xa8, 0xd1, 0x2e, 0x32, 0xcf, 0x00, 0xde, 0x8f, 0xda, 0xee, 0x71,
- 0x91, 0x1b, 0x77, 0xe9, 0xcb, 0x71, 0xa3, 0xa2, 0x87, 0x3e, 0xef, 0xe6,
- 0x6f, 0x53, 0x38, 0x12, 0x75, 0x21, 0xcf, 0xd2, 0x69, 0x29, 0xd7, 0x90,
- 0xb1, 0xa1, 0x9d, 0xb4, 0xa1, 0x7c, 0xe6, 0x6f, 0x0f, 0x5b, 0xbe, 0x2a,
- 0xf3, 0x4c, 0xe3, 0x15, 0x72, 0x5a, 0x6d, 0xb9, 0xf0, 0xd9, 0x20, 0xe3,
- 0x62, 0x09, 0xe2, 0x03, 0x5d, 0x38, 0x1f, 0x2a, 0x41, 0xec, 0x90, 0xf8,
- 0xd8, 0x02, 0xc1, 0x52, 0x3e, 0xb7, 0x91, 0x3a, 0x51, 0x89, 0x35, 0xf5,
- 0x9d, 0x76, 0x7b, 0x09, 0x2e, 0x95, 0x31, 0xaf, 0xb5, 0xde, 0xe3, 0x69,
- 0xc5, 0xc1, 0xac, 0x5d, 0xa8, 0xb4, 0x8b, 0xd6, 0x9b, 0x3c, 0x3a, 0xb7,
- 0x96, 0x9c, 0xcf, 0x66, 0xfa, 0xe1, 0xbd, 0xe4, 0x36, 0x2f, 0x4b, 0xfd,
- 0xc8, 0xe6, 0x63, 0x2c, 0x61, 0xce, 0x34, 0x29, 0xfa, 0xfd, 0xeb, 0xb9,
- 0x19, 0xac, 0x78, 0xa5, 0x26, 0x73, 0x76, 0x25, 0xa7, 0xf7, 0xdc, 0x77,
- 0x6d, 0x7d, 0xa1, 0xf2, 0x0b, 0x73, 0x6b, 0x95, 0xc8, 0x77, 0x9d, 0x79,
- 0xda, 0x77, 0xf9, 0xfb, 0x2a, 0xf4, 0x8e, 0xcc, 0x8e, 0x15, 0xe2, 0x87,
- 0x9e, 0xdb, 0xce, 0xd5, 0x95, 0xc5, 0xe5, 0xdd, 0xa9, 0x63, 0xa1, 0x67,
- 0xb8, 0x0f, 0xfe, 0xa5, 0xf5, 0x56, 0xdd, 0x85, 0xdc, 0x97, 0x79, 0x89,
- 0x60, 0xac, 0xc1, 0x18, 0x5f, 0x82, 0x9f, 0x26, 0x25, 0xe6, 0x9a, 0xc8,
- 0xa7, 0xfd, 0x5d, 0xaa, 0xec, 0x7e, 0xbe, 0xcc, 0xe2, 0xd2, 0x25, 0x28,
- 0xa7, 0xbd, 0x0f, 0x8e, 0xdc, 0xcd, 0xb6, 0x6f, 0xc5, 0x85, 0x74, 0x48,
- 0x21, 0x4e, 0xfc, 0x8b, 0xd9, 0xff, 0xf5, 0xcc, 0x98, 0x0b, 0x49, 0x17,
- 0x3e, 0x0a, 0xb5, 0x63, 0xaa, 0x2c, 0x8c, 0xa1, 0x44, 0x01, 0xda, 0xab,
- 0xeb, 0xac, 0x77, 0x0a, 0x6a, 0xe2, 0x1e, 0x5c, 0x8c, 0x3a, 0xd1, 0x38,
- 0xd7, 0x63, 0xd5, 0xd3, 0x6c, 0xf4, 0x85, 0x77, 0xa2, 0x11, 0xcb, 0xe7,
- 0x66, 0xc7, 0x8c, 0x3c, 0x6d, 0x19, 0x1e, 0xca, 0xe2, 0xfa, 0xc1, 0xc4,
- 0xe7, 0xc4, 0x9d, 0x52, 0xa3, 0x22, 0x5c, 0x82, 0x7b, 0x87, 0x0c, 0xc1,
- 0x64, 0xa3, 0x24, 0xac, 0xcd, 0xdc, 0xa7, 0x94, 0xa0, 0x69, 0x44, 0x30,
- 0x5e, 0x7c, 0x35, 0x4d, 0x5f, 0x6d, 0xe3, 0x1e, 0x75, 0xa2, 0x6e, 0xbf,
- 0xa5, 0x57, 0xd5, 0xae, 0x98, 0x5d, 0x57, 0xf4, 0x88, 0xce, 0x18, 0xd7,
- 0xf9, 0x10, 0xed, 0x7e, 0x26, 0xe4, 0x6d, 0xaf, 0xb0, 0x6b, 0x1d, 0xef,
- 0x29, 0x41, 0x4c, 0x8c, 0x03, 0x03, 0x87, 0x03, 0xf8, 0x20, 0x21, 0x9c,
- 0x3f, 0x80, 0x5f, 0x4d, 0x06, 0xf1, 0x2e, 0x63, 0x53, 0x41, 0xdc, 0x1b,
- 0x79, 0x8e, 0x39, 0xdd, 0xfb, 0xfc, 0x9e, 0x1f, 0xd7, 0x71, 0x8d, 0xfa,
- 0x73, 0xc6, 0x1b, 0x70, 0x65, 0xf2, 0x01, 0x5c, 0xdd, 0xaf, 0xe0, 0x84,
- 0xf6, 0x00, 0x2e, 0x8f, 0x75, 0x62, 0xd9, 0x7e, 0x39, 0x87, 0x76, 0x2c,
- 0xa4, 0x32, 0x36, 0x3c, 0x53, 0x6b, 0x76, 0xbd, 0xa8, 0xd7, 0x41, 0x2f,
- 0xf7, 0xea, 0xed, 0xcc, 0x99, 0x04, 0xd3, 0x23, 0x36, 0xd9, 0x33, 0xd9,
- 0xbb, 0x4e, 0x5c, 0xb5, 0x70, 0xfc, 0xee, 0xd8, 0x70, 0x0b, 0xc3, 0xe5,
- 0x39, 0x82, 0x27, 0x0b, 0xf1, 0x7d, 0x26, 0xab, 0x3d, 0xbc, 0xcf, 0x45,
- 0xec, 0x7b, 0x36, 0x5a, 0x80, 0xfc, 0xaa, 0x52, 0x2b, 0x97, 0x29, 0x8c,
- 0x07, 0x70, 0x96, 0xba, 0x5b, 0x53, 0xe5, 0xe5, 0x77, 0x89, 0xbb, 0x41,
- 0xe6, 0x2d, 0x15, 0xf8, 0xe0, 0xb6, 0x78, 0xfb, 0x7d, 0xf3, 0x49, 0x0b,
- 0x9f, 0xeb, 0xe7, 0x09, 0xff, 0x7a, 0x3d, 0xf1, 0xeb, 0x1a, 0xc1, 0x69,
- 0xa9, 0x21, 0x96, 0x6a, 0xda, 0x96, 0xbf, 0x80, 0xbc, 0x6f, 0x75, 0xe2,
- 0x3f, 0x17, 0x93, 0x17, 0xbf, 0x18, 0xaa, 0x33, 0xca, 0xa0, 0xf1, 0xbe,
- 0xa9, 0x65, 0x2a, 0x56, 0xf1, 0xaf, 0x9f, 0xf7, 0x05, 0x29, 0xc7, 0x75,
- 0x33, 0xa5, 0xfa, 0xf8, 0xef, 0x05, 0x8c, 0xef, 0xdb, 0x71, 0x3e, 0x56,
- 0xdf, 0x7e, 0x58, 0xb9, 0x66, 0x1a, 0x55, 0xb5, 0xfc, 0xad, 0x12, 0x17,
- 0xa2, 0xde, 0xa9, 0x31, 0xd4, 0x7b, 0x66, 0x94, 0x83, 0xa6, 0xa1, 0xca,
- 0xfe, 0xc8, 0x7a, 0x65, 0xfc, 0x62, 0x5e, 0xbf, 0x34, 0xcb, 0x0e, 0x6f,
- 0xe5, 0x5d, 0xce, 0x9b, 0xf6, 0x27, 0xbc, 0xc4, 0x6c, 0x1a, 0xd5, 0xeb,
- 0xd5, 0x1e, 0x62, 0x41, 0x44, 0xbd, 0x9b, 0xfd, 0x15, 0xd0, 0xfe, 0xc2,
- 0xcc, 0x23, 0x4b, 0xa0, 0x5a, 0xf1, 0xa9, 0x15, 0xc9, 0x91, 0xd9, 0xdc,
- 0x52, 0xec, 0x2e, 0xc3, 0x53, 0xdb, 0xcb, 0xba, 0x4f, 0x3a, 0x89, 0x45,
- 0x09, 0xe2, 0x78, 0x9c, 0x38, 0x9e, 0x4f, 0x1c, 0xbf, 0xbe, 0xaf, 0x10,
- 0xe7, 0xf7, 0x35, 0x22, 0x5d, 0x26, 0x63, 0xec, 0x70, 0x72, 0x75, 0xa9,
- 0xec, 0x79, 0x85, 0x9a, 0xc1, 0x95, 0x72, 0x8e, 0x13, 0x82, 0x5f, 0x79,
- 0x71, 0xe6, 0x59, 0xad, 0x76, 0x38, 0xac, 0x33, 0xf6, 0x73, 0x6e, 0xb3,
- 0x3f, 0x97, 0x96, 0x8f, 0x96, 0x4a, 0xc1, 0x87, 0xd7, 0xe7, 0x49, 0x1c,
- 0x7d, 0x9d, 0xb2, 0x9c, 0xa4, 0x4d, 0x6f, 0xd4, 0x57, 0x48, 0x5f, 0x8f,
- 0xf7, 0xcb, 0x38, 0xc9, 0x6d, 0x4c, 0xec, 0xa6, 0x85, 0xd5, 0x55, 0x99,
- 0x48, 0xe8, 0x61, 0xc6, 0xac, 0x10, 0x22, 0x65, 0x41, 0xc6, 0x2a, 0xf9,
- 0xae, 0xe2, 0x0a, 0xf3, 0xb2, 0xf1, 0xa0, 0x82, 0x8f, 0xbe, 0x22, 0x5c,
- 0xc0, 0xaf, 0x9f, 0x57, 0x84, 0x0b, 0xc8, 0x78, 0xc1, 0x88, 0x52, 0x0b,
- 0x23, 0xf2, 0x2d, 0x5e, 0x34, 0xd7, 0xc2, 0x16, 0x79, 0x47, 0xa9, 0x86,
- 0x71, 0xe7, 0xfe, 0x44, 0xfd, 0x94, 0xcf, 0x4e, 0x8e, 0xf6, 0x27, 0x5f,
- 0x21, 0x37, 0xb3, 0x38, 0x02, 0xf1, 0x3e, 0x87, 0x0d, 0x72, 0xee, 0x76,
- 0xb6, 0x3e, 0x72, 0xe7, 0x72, 0x3d, 0x19, 0xac, 0x2c, 0x15, 0x2e, 0xf7,
- 0xff, 0xcc, 0xd6, 0xdb, 0xe4, 0xcf, 0xe1, 0xc8, 0x3f, 0xf0, 0xbb, 0x8c,
- 0x17, 0xbf, 0xa3, 0x5d, 0xc4, 0x7f, 0x62, 0x3e, 0x6d, 0xf1, 0xb9, 0x97,
- 0xe7, 0xc9, 0xf9, 0x43, 0xc7, 0xe0, 0xd0, 0x3c, 0x39, 0x6f, 0x65, 0x9b,
- 0xc5, 0x0b, 0x32, 0xb1, 0xf6, 0x5d, 0x73, 0xad, 0x25, 0xeb, 0x91, 0xec,
- 0x7d, 0x92, 0x43, 0x8b, 0x2c, 0x0a, 0x5e, 0xd1, 0xea, 0xd5, 0xb3, 0x28,
- 0x16, 0x3c, 0x89, 0x48, 0x0f, 0xb3, 0x50, 0xf3, 0xb9, 0x8f, 0xf0, 0x6f,
- 0x3f, 0xaf, 0xbf, 0xa1, 0x39, 0x1a, 0xb7, 0x42, 0xfa, 0xb6, 0x36, 0xee,
- 0x55, 0xbd, 0xfb, 0x2c, 0xfc, 0x91, 0x7c, 0x65, 0xc6, 0x6c, 0xaf, 0x94,
- 0x7b, 0x32, 0xfd, 0x5b, 0x28, 0x17, 0xad, 0xfa, 0x49, 0xc6, 0x66, 0x16,
- 0xd0, 0x66, 0x04, 0xbb, 0x84, 0x8b, 0x2c, 0xe1, 0xda, 0x55, 0x8c, 0x4c,
- 0x02, 0x79, 0x83, 0x2e, 0x8b, 0x1b, 0xa9, 0xb5, 0xb5, 0x9e, 0xcd, 0xf8,
- 0xe7, 0x79, 0xf2, 0xee, 0xd1, 0x0e, 0x1d, 0xf7, 0xd8, 0xf0, 0xf6, 0x3d,
- 0xb6, 0xf0, 0xca, 0x6f, 0x3d, 0xd4, 0x90, 0x37, 0x5f, 0xde, 0xff, 0x20,
- 0xc3, 0x93, 0xfa, 0xad, 0x5b, 0x7a, 0x8d, 0xab, 0x19, 0xc3, 0x86, 0x99,
- 0xe3, 0xaf, 0x0e, 0xfe, 0xd6, 0xfc, 0xa6, 0x23, 0xe2, 0xb1, 0xa3, 0xd6,
- 0xd3, 0x8b, 0x1b, 0x66, 0xaa, 0x52, 0xae, 0xcb, 0x1c, 0xf2, 0x6e, 0xa1,
- 0xf4, 0x4b, 0x4c, 0xf3, 0xde, 0x5a, 0x93, 0xf9, 0xb3, 0x6d, 0x95, 0x9d,
- 0x7e, 0x91, 0xaf, 0x5d, 0x36, 0xeb, 0xaa, 0x6b, 0xdd, 0x36, 0xa5, 0x8e,
- 0xd6, 0x51, 0x89, 0x57, 0x69, 0xbf, 0xaf, 0x4e, 0x4a, 0xcc, 0x53, 0x71,
- 0x94, 0x7e, 0x3a, 0x56, 0xe7, 0xeb, 0xbc, 0xca, 0x5c, 0xf2, 0x43, 0x72,
- 0xfc, 0x37, 0x35, 0x6f, 0xfb, 0x19, 0xa9, 0x3b, 0x86, 0x1c, 0x38, 0x17,
- 0xbc, 0x61, 0xd5, 0x82, 0x63, 0x87, 0x54, 0x0c, 0x27, 0x32, 0xfe, 0xfe,
- 0x1a, 0xfd, 0xf8, 0xd6, 0xd9, 0x05, 0x1d, 0x3d, 0x43, 0xe2, 0x1f, 0x0d,
- 0x96, 0x1f, 0xdd, 0xaa, 0x15, 0x09, 0x5e, 0x8b, 0x5f, 0x6c, 0x90, 0xde,
- 0x9d, 0x91, 0x02, 0xb9, 0xcc, 0xe0, 0x6a, 0x72, 0x60, 0x89, 0xb1, 0x01,
- 0xe6, 0xbb, 0x0e, 0xfa, 0xcf, 0x19, 0xe6, 0x1e, 0x94, 0x2d, 0x6c, 0x9a,
- 0xef, 0x32, 0x17, 0x1b, 0x41, 0xbd, 0x7a, 0x0a, 0xeb, 0xc8, 0x63, 0xc9,
- 0x71, 0x26, 0x9b, 0xb1, 0xc7, 0xca, 0xa5, 0x7c, 0xea, 0xc3, 0xca, 0x52,
- 0xae, 0xbf, 0x19, 0xdd, 0x63, 0x0b, 0x70, 0x80, 0xeb, 0x7a, 0x44, 0xff,
- 0x2b, 0x94, 0x0f, 0x75, 0x77, 0x96, 0x53, 0x1f, 0x9f, 0x86, 0x8c, 0x0e,
- 0x62, 0xfa, 0x96, 0x53, 0x4a, 0xfd, 0xfa, 0x98, 0xf2, 0x4d, 0xee, 0x87,
- 0xd4, 0x47, 0x3c, 0xcc, 0xd3, 0x1f, 0x61, 0x3c, 0xfb, 0x33, 0xec, 0x56,
- 0x95, 0x26, 0x5b, 0x58, 0x38, 0x22, 0xfc, 0xaa, 0x75, 0x76, 0xf0, 0xbf,
- 0x40, 0x9f, 0xdb, 0xc0, 0x6b, 0x12, 0xd7, 0xe5, 0x5e, 0x39, 0x37, 0xde,
- 0x89, 0x93, 0x69, 0xda, 0x75, 0xb4, 0x0f, 0xa7, 0xd2, 0xf2, 0x4c, 0xe1,
- 0x58, 0x01, 0xc4, 0x86, 0xec, 0x98, 0xd0, 0x7d, 0x91, 0x52, 0xea, 0xa5,
- 0x30, 0xe4, 0x8d, 0xac, 0x53, 0x02, 0xe4, 0x72, 0x69, 0x9c, 0xdb, 0xeb,
- 0x6d, 0xaf, 0x63, 0xde, 0x18, 0x9d, 0x84, 0xfa, 0xdc, 0xf2, 0x34, 0xce,
- 0x8e, 0x3e, 0x0e, 0x4f, 0xb5, 0xd7, 0xb3, 0x5a, 0x69, 0xc1, 0x8e, 0xc9,
- 0x7f, 0xaf, 0xc6, 0xe4, 0xe1, 0xb3, 0x5b, 0x60, 0x50, 0xf7, 0xbb, 0xf0,
- 0xad, 0xf9, 0xe2, 0xf3, 0xbd, 0x93, 0xc5, 0x58, 0xc4, 0x78, 0xf4, 0xb2,
- 0x15, 0x67, 0x33, 0x7e, 0x54, 0xa3, 0x7d, 0x64, 0x3e, 0x95, 0x8d, 0xe1,
- 0x7f, 0x58, 0x5f, 0x3f, 0x34, 0x23, 0xaa, 0xe8, 0x4b, 0xc6, 0xd5, 0xa0,
- 0x80, 0xf3, 0xec, 0xce, 0xc6, 0xeb, 0x32, 0xed, 0x9f, 0xcc, 0xc7, 0xad,
- 0x39, 0x56, 0xce, 0x97, 0x44, 0x61, 0xa7, 0x95, 0xe7, 0xcb, 0xba, 0x75,
- 0x7c, 0x16, 0x95, 0x5a, 0x87, 0x8a, 0x53, 0xba, 0xe0, 0x48, 0x0b, 0x7d,
- 0xd5, 0x89, 0x2d, 0x41, 0xba, 0xa3, 0x55, 0xf7, 0x9f, 0xc6, 0x9e, 0xe4,
- 0xbf, 0x9a, 0xcf, 0xd3, 0x8e, 0xd6, 0x90, 0xc3, 0x78, 0x88, 0x03, 0x1b,
- 0x43, 0x8f, 0x90, 0x87, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2,
- 0x91, 0xfe, 0x1f, 0x5a, 0x82, 0x29, 0xeb, 0xfe, 0x4f, 0xe7, 0x65, 0x6a,
- 0x8b, 0x67, 0xe6, 0x67, 0x72, 0x43, 0xd1, 0xff, 0x7f, 0x44, 0x7f, 0xaf,
- 0x99, 0x9e, 0x72, 0xd1, 0x9f, 0x03, 0x6e, 0xc6, 0xad, 0x03, 0xbc, 0xe7,
- 0xc2, 0x5e, 0x07, 0x06, 0xb5, 0x16, 0x0c, 0x4e, 0xc2, 0xf3, 0x29, 0xef,
- 0xf9, 0xf9, 0x68, 0xc7, 0xfc, 0x0c, 0x57, 0x78, 0x1b, 0xdd, 0xd1, 0x17,
- 0xcc, 0x55, 0xe5, 0xb2, 0x5e, 0x39, 0xaf, 0xd3, 0xca, 0xfb, 0x73, 0x75,
- 0xbe, 0xcd, 0xe6, 0x13, 0x56, 0x9c, 0x78, 0x71, 0xbe, 0xf4, 0xd7, 0x5e,
- 0x4f, 0x98, 0xb8, 0xa2, 0xf7, 0x58, 0xb9, 0xb9, 0x60, 0x43, 0x6f, 0x42,
- 0xf6, 0x56, 0x64, 0xfb, 0x66, 0x56, 0x1f, 0x13, 0x55, 0xb7, 0xcb, 0xbd,
- 0x2a, 0x6b, 0xcb, 0xd2, 0xdf, 0xce, 0xf1, 0x7e, 0xb1, 0x65, 0xb1, 0x63,
- 0xeb, 0xbd, 0x96, 0xa4, 0xbc, 0xd3, 0xb9, 0x41, 0xfd, 0x1d, 0x9f, 0x21,
- 0x75, 0x96, 0x16, 0xce, 0x61, 0x9a, 0x9b, 0xf5, 0x7a, 0xcf, 0x29, 0xfc,
- 0x31, 0x6d, 0x5b, 0xc7, 0xae, 0x21, 0xa9, 0xc3, 0x7a, 0x14, 0xc7, 0xbe,
- 0x75, 0xb8, 0xc2, 0xf8, 0xbf, 0xc7, 0xb2, 0x43, 0xc1, 0x15, 0x91, 0x43,
- 0xb0, 0xa5, 0x8d, 0x71, 0x5c, 0x6a, 0xdd, 0x46, 0xa4, 0x26, 0xdc, 0xa9,
- 0x7c, 0x58, 0xd7, 0x89, 0x63, 0x21, 0xc3, 0x2c, 0xd5, 0xfc, 0xeb, 0x6b,
- 0x6c, 0x28, 0x98, 0x6c, 0xc8, 0xc7, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2,
- 0x69, 0xaf, 0x31, 0xc7, 0xae, 0xba, 0xbe, 0x97, 0xce, 0x62, 0xa5, 0xad,
- 0x7e, 0xbe, 0xe4, 0x50, 0x49, 0x0b, 0x47, 0xbe, 0x8a, 0x07, 0xad, 0xbd,
- 0x55, 0x19, 0x43, 0xa5, 0x0e, 0x7c, 0x2c, 0x74, 0x2d, 0x2a, 0x98, 0x62,
- 0x36, 0x35, 0x87, 0xea, 0xd5, 0x5d, 0xb8, 0x87, 0xd8, 0xd5, 0x84, 0x73,
- 0xba, 0xf4, 0x3f, 0x8c, 0x6f, 0x3a, 0xac, 0xb3, 0x34, 0x47, 0x43, 0x3b,
- 0xa2, 0x2b, 0x71, 0x60, 0xc8, 0x50, 0x9c, 0x61, 0x6f, 0x24, 0x46, 0x2e,
- 0xc4, 0x1c, 0xdd, 0xaa, 0x03, 0x4a, 0x8d, 0x61, 0xb8, 0xa1, 0x13, 0xbb,
- 0xf4, 0x7c, 0xf4, 0xea, 0x91, 0x82, 0x9e, 0xe5, 0x5d, 0x38, 0xa8, 0x17,
- 0x1b, 0x8b, 0xc2, 0x06, 0x31, 0x5d, 0xdb, 0x92, 0x84, 0xbf, 0xe5, 0x32,
- 0x39, 0xc7, 0x49, 0x78, 0x3b, 0x9a, 0xec, 0xc4, 0xdc, 0x15, 0x0e, 0x57,
- 0x6c, 0xbc, 0x11, 0x89, 0xc9, 0x4a, 0xd7, 0xee, 0xf1, 0x20, 0xe2, 0x93,
- 0xdc, 0x6f, 0xe6, 0xba, 0x8e, 0xf1, 0x95, 0xe4, 0xa0, 0xa2, 0x47, 0x3b,
- 0x6d, 0xb1, 0x0e, 0xcf, 0xb5, 0x5e, 0x32, 0x9f, 0xf1, 0x0b, 0x7e, 0x2e,
- 0xc0, 0x56, 0xd5, 0x67, 0x71, 0xca, 0x88, 0xed, 0x0f, 0xf9, 0x87, 0x9d,
- 0x36, 0xf7, 0x7d, 0xd3, 0xf3, 0x75, 0xd1, 0x9b, 0x63, 0x01, 0x0a, 0x1f,
- 0x21, 0x7e, 0xca, 0xbf, 0x45, 0x77, 0xa2, 0x43, 0x13, 0x9b, 0x74, 0xa9,
- 0xf1, 0x35, 0xd0, 0x67, 0xdc, 0x78, 0x47, 0xbd, 0xb5, 0x0f, 0xcf, 0xea,
- 0x3e, 0x7d, 0x0c, 0x52, 0xdb, 0x5b, 0xc1, 0x71, 0x52, 0x83, 0x69, 0xc4,
- 0x4b, 0xd9, 0x9c, 0xc3, 0x63, 0x2b, 0x22, 0xee, 0xe6, 0xe2, 0x88, 0x5c,
- 0xf7, 0x26, 0x23, 0xb4, 0xd3, 0x6d, 0xc1, 0x19, 0x33, 0x52, 0x6e, 0x74,
- 0xca, 0xf9, 0x15, 0x77, 0x78, 0xba, 0xd3, 0x5d, 0xe7, 0xed, 0x98, 0x51,
- 0x80, 0x73, 0x31, 0xc6, 0x61, 0xeb, 0x7f, 0xb1, 0x28, 0x73, 0x3b, 0x31,
- 0x12, 0x5c, 0x88, 0xf6, 0x36, 0x79, 0x56, 0x33, 0xfa, 0xf6, 0x9b, 0x66,
- 0x71, 0xc8, 0xa7, 0xa6, 0xe1, 0xc4, 0xc3, 0x41, 0x3b, 0x2e, 0xa9, 0x26,
- 0x1c, 0xa1, 0x7f, 0x35, 0xc7, 0x19, 0x1f, 0x47, 0xe9, 0x27, 0xbb, 0x69,
- 0x63, 0xf2, 0xbe, 0x8f, 0x9f, 0x7e, 0x12, 0xa7, 0x9f, 0x9c, 0x0b, 0xdd,
- 0x97, 0x7d, 0x5f, 0x50, 0x23, 0xaf, 0x98, 0x46, 0xd3, 0x90, 0x8a, 0x4f,
- 0x57, 0x4c, 0x23, 0x34, 0x92, 0x93, 0x5d, 0xfc, 0x32, 0x27, 0xbf, 0xf4,
- 0x11, 0x45, 0x76, 0x91, 0x51, 0xd6, 0x22, 0xff, 0xce, 0x5d, 0xcb, 0xfd,
- 0x26, 0x71, 0xd6, 0x89, 0x56, 0x6b, 0x6d, 0x7f, 0x56, 0x93, 0xc1, 0x8c,
- 0xdc, 0x9a, 0x2e, 0xb9, 0x6f, 0xff, 0x7e, 0xe2, 0x8e, 0xeb, 0x2b, 0xee,
- 0xb8, 0xbe, 0x71, 0xde, 0xed, 0xdf, 0x73, 0x3e, 0x71, 0x4b, 0xaf, 0x1d,
- 0xba, 0x6f, 0xea, 0x18, 0xd7, 0x3a, 0x67, 0xc9, 0x98, 0x79, 0xa9, 0x4c,
- 0x64, 0x91, 0x3c, 0x36, 0x23, 0xeb, 0xaa, 0xf1, 0xd9, 0xb2, 0xbe, 0x95,
- 0xed, 0x19, 0x58, 0x67, 0x7c, 0xe9, 0x37, 0x1a, 0x7e, 0x78, 0xdb, 0xb9,
- 0x43, 0xb1, 0xb5, 0x80, 0xd2, 0x17, 0x93, 0xf7, 0x33, 0x0b, 0xad, 0x77,
- 0xac, 0x55, 0xbf, 0x81, 0x22, 0xbf, 0xb6, 0x65, 0x8e, 0xad, 0x0b, 0xce,
- 0xa5, 0x5a, 0xc7, 0xb7, 0x94, 0x24, 0xe2, 0xe3, 0xde, 0xc0, 0x18, 0x75,
- 0x15, 0x1b, 0xbf, 0xce, 0x5c, 0xbb, 0x0b, 0xcf, 0x85, 0x1c, 0x46, 0x61,
- 0x58, 0xce, 0x82, 0xae, 0xc2, 0xae, 0x91, 0xbf, 0xc2, 0xe6, 0xa4, 0x70,
- 0xfc, 0x05, 0xe8, 0x99, 0xb4, 0xe1, 0x04, 0xed, 0xbb, 0x8f, 0xcf, 0x21,
- 0xfe, 0xb9, 0x53, 0x90, 0xf7, 0x6b, 0x1a, 0x98, 0x37, 0xeb, 0xd6, 0x67,
- 0xc7, 0xc8, 0xcf, 0xb0, 0x39, 0x6a, 0xe2, 0x53, 0x9d, 0xb1, 0x47, 0x13,
- 0xf9, 0x1c, 0xd0, 0xca, 0x5b, 0x2d, 0x2c, 0x7d, 0x32, 0xce, 0xfd, 0xac,
- 0x16, 0x5f, 0x5d, 0x49, 0x9f, 0x55, 0xf0, 0x99, 0xf4, 0x27, 0xcb, 0x29,
- 0x33, 0xb9, 0xe1, 0xf1, 0xe8, 0x76, 0x8c, 0x5a, 0xfd, 0x67, 0xad, 0xaf,
- 0xc6, 0x1e, 0x79, 0xb1, 0x8c, 0x3c, 0x3b, 0xa1, 0xfb, 0xdb, 0x2f, 0x28,
- 0xf0, 0x94, 0x84, 0xfd, 0x8c, 0x33, 0x5f, 0xe2, 0x37, 0xba, 0xd4, 0xd8,
- 0x74, 0xd7, 0x5a, 0xda, 0xfb, 0xbe, 0x91, 0x80, 0x55, 0x33, 0xf8, 0xe1,
- 0x5d, 0x6b, 0x1a, 0x99, 0x77, 0xab, 0x33, 0xf5, 0xc7, 0x9f, 0xe1, 0x48,
- 0xda, 0x85, 0xa7, 0xe2, 0x1e, 0x65, 0xd1, 0x3e, 0x15, 0x0f, 0xc5, 0xbd,
- 0x53, 0x4d, 0x76, 0xf2, 0x8f, 0x65, 0x73, 0x38, 0x9f, 0x82, 0x1f, 0x2c,
- 0x95, 0x58, 0xf0, 0x47, 0x30, 0xaa, 0x23, 0x9c, 0x13, 0xc5, 0x79, 0xcb,
- 0xbd, 0xea, 0x11, 0x9b, 0xcf, 0xfd, 0x1b, 0xec, 0x80, 0x7d, 0xfc, 0x11,
- 0x74, 0x53, 0xfe, 0x35, 0x71, 0xe9, 0x69, 0xd5, 0x03, 0x65, 0xcd, 0xd8,
- 0x3d, 0x26, 0xbe, 0x09, 0xa3, 0x2a, 0x0c, 0x4f, 0x65, 0xd8, 0xbf, 0x10,
- 0x85, 0x5f, 0x92, 0x6b, 0x4f, 0x4b, 0xfe, 0xb9, 0xa5, 0xd4, 0x66, 0x32,
- 0x7f, 0xb9, 0x2f, 0xdb, 0xab, 0x58, 0x89, 0x1d, 0x43, 0x52, 0x87, 0x27,
- 0x6e, 0xeb, 0xcc, 0x83, 0xca, 0xb4, 0xc0, 0x46, 0x9b, 0xf4, 0x87, 0xb6,
- 0xc3, 0x17, 0xdb, 0x8e, 0x40, 0x4c, 0x7c, 0x56, 0x53, 0x3b, 0x10, 0x39,
- 0x2b, 0xb5, 0xbf, 0x45, 0x21, 0x3f, 0xe5, 0xf2, 0xf7, 0x55, 0xda, 0x75,
- 0xd7, 0x6b, 0x13, 0x2a, 0xa6, 0xd4, 0x4c, 0x1e, 0x39, 0x96, 0xd4, 0xd6,
- 0xe7, 0xdb, 0xe4, 0x0c, 0xc5, 0x55, 0xeb, 0x3d, 0xeb, 0x88, 0xed, 0x9f,
- 0x89, 0x47, 0xcd, 0x18, 0xd8, 0xff, 0x3e, 0x63, 0x90, 0x3c, 0xe3, 0x77,
- 0xcc, 0xaf, 0x9d, 0x58, 0xdd, 0xe6, 0xc1, 0x83, 0x71, 0xa9, 0x9d, 0xae,
- 0xaf, 0xca, 0x9c, 0x01, 0x91, 0xef, 0x0e, 0x74, 0xe8, 0x04, 0xd9, 0xea,
- 0x2f, 0xcc, 0x4a, 0x2b, 0x2f, 0xfd, 0xbf, 0x19, 0x9b, 0x49, 0xe4, 0x2d,
- 0x14, 0x1f, 0xef, 0x9d, 0x64, 0x02, 0x69, 0xd9, 0x5d, 0x15, 0xbf, 0xcb,
- 0x5c, 0xda, 0x81, 0xed, 0xd8, 0x56, 0x25, 0x7c, 0xe6, 0xc9, 0x89, 0xd9,
- 0xf7, 0xe7, 0xea, 0x32, 0x95, 0x59, 0x4e, 0x95, 0xb3, 0x37, 0xe9, 0x05,
- 0x46, 0x94, 0x27, 0xa2, 0x2d, 0xca, 0xda, 0xa8, 0xf4, 0x03, 0x6d, 0xd1,
- 0x22, 0x72, 0x18, 0xdf, 0x52, 0x13, 0xdf, 0x0e, 0x1d, 0x57, 0x76, 0x5a,
- 0xe7, 0x66, 0xe5, 0xac, 0x2b, 0x50, 0x3e, 0xd1, 0xac, 0xec, 0x8a, 0x7e,
- 0x62, 0x6e, 0xb4, 0x7a, 0xf0, 0x79, 0xd6, 0x79, 0x9c, 0xfc, 0x09, 0x17,
- 0xca, 0x8e, 0xc8, 0xf9, 0x41, 0x0d, 0x15, 0x13, 0x8f, 0x91, 0xb7, 0x0a,
- 0xd7, 0x31, 0x5a, 0x1c, 0xd6, 0xb9, 0xb6, 0xe6, 0x97, 0x72, 0xe7, 0xda,
- 0x1c, 0x31, 0x79, 0x1b, 0xd9, 0xfa, 0x8f, 0xb9, 0xd2, 0x51, 0xe6, 0x4a,
- 0x66, 0xd3, 0xb7, 0x43, 0xc6, 0xee, 0x0a, 0x78, 0x03, 0xe5, 0x36, 0xc3,
- 0x94, 0x7a, 0xce, 0x6b, 0x24, 0x8c, 0xeb, 0x6a, 0x0d, 0x3c, 0x5c, 0x2b,
- 0xef, 0x1f, 0xca, 0xbb, 0xc7, 0x5d, 0x38, 0x1a, 0xea, 0xc2, 0x2f, 0xf5,
- 0x2e, 0xec, 0xd1, 0xe5, 0x4c, 0x43, 0x31, 0x65, 0xd5, 0xa6, 0xa2, 0xd0,
- 0xf4, 0xb4, 0xa2, 0x9d, 0xb9, 0x0e, 0xef, 0x01, 0x9f, 0xe2, 0x35, 0x56,
- 0x29, 0x1a, 0xae, 0x8e, 0x7b, 0x67, 0x4a, 0xe9, 0x03, 0x37, 0xc6, 0x03,
- 0x98, 0x21, 0xae, 0x26, 0x27, 0xe5, 0xfc, 0xc9, 0x02, 0x0c, 0x4d, 0x7e,
- 0x4d, 0xb8, 0x81, 0x41, 0x4c, 0xb2, 0xce, 0x48, 0x3e, 0x2f, 0xbd, 0x4e,
- 0x67, 0x30, 0xcb, 0x61, 0x0c, 0x65, 0x53, 0x43, 0x09, 0x6e, 0x30, 0x3a,
- 0xfd, 0x6d, 0xba, 0x93, 0xf9, 0x1c, 0xde, 0xa8, 0x81, 0xfd, 0x3b, 0x6e,
- 0xd4, 0x25, 0xe7, 0xe0, 0x44, 0x5d, 0x39, 0xf2, 0x70, 0x6c, 0xf4, 0x45,
- 0x72, 0xfc, 0xee, 0xf6, 0x52, 0xe6, 0xa7, 0x13, 0xa3, 0x4e, 0xa4, 0x52,
- 0x52, 0x73, 0xb0, 0x7a, 0x96, 0xd3, 0x0e, 0xfa, 0x52, 0x7f, 0x02, 0x75,
- 0x35, 0x61, 0x7f, 0xb2, 0xc6, 0xae, 0x72, 0x8e, 0x4a, 0xa4, 0xd2, 0x1a,
- 0x3f, 0x01, 0x7e, 0x82, 0xfc, 0x34, 0xe2, 0xdb, 0xf4, 0xd9, 0x32, 0xe2,
- 0xed, 0xf7, 0xd3, 0x25, 0xf8, 0x24, 0xa9, 0x05, 0x74, 0xda, 0xc1, 0x28,
- 0x73, 0x04, 0xc3, 0xd2, 0x53, 0x09, 0xae, 0xd3, 0x4f, 0x5f, 0x0e, 0x95,
- 0xc0, 0x4c, 0xdd, 0x2d, 0x27, 0x94, 0xdc, 0x16, 0x6a, 0x61, 0x58, 0xf8,
- 0xe2, 0x31, 0x25, 0x95, 0x3d, 0xf3, 0xf5, 0xea, 0x38, 0xda, 0xcb, 0xc3,
- 0xae, 0xe0, 0xea, 0xb8, 0xfd, 0x13, 0x79, 0x9f, 0x75, 0x43, 0x83, 0xbc,
- 0xf3, 0xe4, 0x0a, 0x3e, 0x3d, 0xe1, 0x0a, 0xae, 0x8f, 0x1f, 0x53, 0x28,
- 0xcf, 0x81, 0x1a, 0xbb, 0x2b, 0xf8, 0xe4, 0xc4, 0xb1, 0x85, 0x99, 0xbc,
- 0x0f, 0xca, 0xd3, 0xb5, 0x06, 0x6d, 0x8c, 0x79, 0xef, 0x32, 0xe9, 0xcb,
- 0x68, 0x9d, 0x57, 0xec, 0x85, 0x46, 0x4d, 0xd8, 0xeb, 0xa9, 0xb1, 0xcb,
- 0xd9, 0x90, 0x69, 0xc4, 0x93, 0xf2, 0xae, 0x97, 0xd8, 0xfe, 0x3f, 0x99,
- 0x46, 0x99, 0x9c, 0xf5, 0xe8, 0x44, 0x5c, 0x2b, 0x67, 0xee, 0x24, 0x67,
- 0xcd, 0x8f, 0x86, 0xa2, 0xb1, 0x62, 0x79, 0x77, 0xb6, 0xe9, 0x7b, 0x21,
- 0x6f, 0xcb, 0xa0, 0x62, 0x3c, 0x5e, 0x04, 0xd9, 0xd7, 0x2e, 0xe2, 0xb7,
- 0xa6, 0x3a, 0x15, 0x6f, 0x63, 0x0f, 0x02, 0x38, 0x91, 0x16, 0x5d, 0x07,
- 0xe5, 0x8c, 0xba, 0xa5, 0xeb, 0x5b, 0x67, 0xae, 0x33, 0xb6, 0xb3, 0x2d,
- 0xea, 0xe0, 0x5f, 0xb1, 0x17, 0x1b, 0x63, 0x0a, 0xe3, 0x8a, 0x65, 0x33,
- 0xb7, 0x64, 0x5c, 0x57, 0xdb, 0x85, 0xc9, 0x50, 0xa1, 0xbc, 0x77, 0xcd,
- 0xb8, 0xee, 0x0d, 0x7c, 0xa2, 0x58, 0xf1, 0xdc, 0x28, 0x62, 0x9c, 0x7d,
- 0x61, 0xfc, 0xef, 0xcc, 0xf6, 0x6a, 0xc1, 0x2b, 0x3b, 0xc7, 0x5e, 0xc7,
- 0x6b, 0xa9, 0x5b, 0xe3, 0x5a, 0x38, 0xae, 0x90, 0xe3, 0x8a, 0xc2, 0x92,
- 0x3b, 0x7a, 0xf5, 0xb5, 0x8a, 0xe6, 0x29, 0x50, 0xa4, 0x57, 0xa6, 0xe1,
- 0xbd, 0xf4, 0xe4, 0x42, 0xc9, 0x79, 0x7b, 0x27, 0xcb, 0xb1, 0x6e, 0xaf,
- 0xd9, 0xb4, 0x68, 0xa9, 0xd9, 0x94, 0x0e, 0x45, 0xcd, 0x97, 0xab, 0x64,
- 0x4f, 0xa5, 0xff, 0x27, 0x63, 0x34, 0xd5, 0xc7, 0x5c, 0xf3, 0x6b, 0x7a,
- 0x6f, 0xf6, 0xcc, 0x2e, 0xed, 0x9a, 0xcf, 0x38, 0x9d, 0x12, 0x3b, 0xd9,
- 0xd1, 0xee, 0x62, 0x3e, 0x2a, 0xef, 0x87, 0x1e, 0xe5, 0xfe, 0x1f, 0x49,
- 0xfd, 0xcd, 0x42, 0x39, 0xc3, 0x2e, 0x67, 0x08, 0x80, 0xff, 0x0f, 0x1d,
- 0xab, 0x22, 0x97, 0x70, 0x78, 0x00, 0x00, 0x00 };
+ 0xec, 0x5c, 0x7d, 0x70, 0x1c, 0xe5, 0x79, 0xff, 0xbd, 0x7b, 0x7b, 0xd2,
+ 0x4a, 0x3a, 0x9d, 0x56, 0xa7, 0x93, 0x7c, 0x22, 0x04, 0xef, 0xa2, 0x3d,
+ 0xf9, 0xb0, 0x0c, 0xec, 0x9d, 0x4f, 0xb6, 0xa0, 0xdb, 0xb2, 0x83, 0x0d,
+ 0x11, 0x21, 0x13, 0x84, 0x4d, 0x52, 0x33, 0x49, 0x27, 0x37, 0xc6, 0x18,
+ 0x81, 0x4d, 0x70, 0x0d, 0x6d, 0x55, 0x86, 0x19, 0x6f, 0x2c, 0x7f, 0x01,
+ 0x27, 0x9d, 0x62, 0x64, 0x63, 0xd2, 0x0e, 0x68, 0x6c, 0x59, 0x08, 0x7c,
+ 0xd2, 0x61, 0x20, 0xad, 0xe8, 0x84, 0xfa, 0x26, 0xd8, 0xe0, 0x94, 0xcf,
+ 0x21, 0x0c, 0xc3, 0x1f, 0xcd, 0xa0, 0x62, 0x3e, 0xcc, 0x94, 0xa1, 0x26,
+ 0x38, 0xa9, 0xdd, 0xb8, 0x7e, 0xfb, 0x3c, 0x7b, 0x3a, 0x9b, 0x90, 0x26,
+ 0x9d, 0xfc, 0xd1, 0xff, 0xf6, 0x99, 0xb9, 0xb9, 0xbd, 0x77, 0xdf, 0xf7,
+ 0xf9, 0xfe, 0x7c, 0x3d, 0xf2, 0x5f, 0x47, 0x50, 0x8f, 0x39, 0x68, 0xa4,
+ 0x4f, 0x76, 0xc3, 0xc0, 0xc6, 0xf4, 0x65, 0x4b, 0x2e, 0xa3, 0xc7, 0xee,
+ 0x50, 0x53, 0x8d, 0xca, 0xeb, 0x02, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01,
+ 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10,
+ 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00,
+ 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04,
+ 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40,
+ 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0xfc, 0x7f, 0x40, 0x08, 0xd0,
+ 0xf9, 0xbb, 0x71, 0xee, 0x03, 0x4d, 0x71, 0xdc, 0x7b, 0xaf, 0xb6, 0xa0,
+ 0x85, 0x9c, 0x99, 0x7b, 0x6f, 0xb1, 0x00, 0xb7, 0xd8, 0x65, 0x2c, 0xc3,
+ 0x7f, 0x4b, 0x2f, 0xae, 0x82, 0xd7, 0xbf, 0xea, 0x9c, 0x79, 0xec, 0xf9,
+ 0xa5, 0xe6, 0x89, 0xb1, 0x10, 0x34, 0xdd, 0x79, 0x27, 0xad, 0x77, 0x42,
+ 0xbb, 0x90, 0xce, 0xfc, 0xfd, 0x82, 0x95, 0x31, 0x44, 0xab, 0xb8, 0xe0,
+ 0x29, 0x8e, 0x94, 0xfb, 0x6d, 0x89, 0x17, 0x6d, 0x4f, 0x2c, 0xcb, 0xc2,
+ 0xd3, 0x9c, 0x19, 0x51, 0x37, 0x74, 0x56, 0x1a, 0xe1, 0x0a, 0xe5, 0x35,
+ 0x45, 0x05, 0xaa, 0xa5, 0xe1, 0xd6, 0xf1, 0x7a, 0xac, 0x1d, 0x6b, 0xc0,
+ 0x9a, 0xb1, 0x04, 0x6e, 0x2b, 0x42, 0x0f, 0x39, 0x1a, 0x66, 0x43, 0x33,
+ 0x22, 0x34, 0x85, 0x5c, 0xd8, 0x39, 0x75, 0xc3, 0xde, 0xfc, 0x59, 0xe9,
+ 0xfa, 0x7f, 0x63, 0x52, 0xbe, 0x61, 0xdc, 0x7f, 0x0f, 0x45, 0x75, 0x0e,
+ 0xd3, 0x33, 0xef, 0x3b, 0x75, 0xc3, 0xbe, 0xe2, 0x71, 0xf9, 0xfc, 0x82,
+ 0x38, 0x0e, 0x95, 0x74, 0x3c, 0x55, 0xda, 0x4f, 0x3c, 0x98, 0x9e, 0x07,
+ 0xcd, 0x53, 0x1d, 0x0f, 0x5b, 0xb3, 0x61, 0x4c, 0x8c, 0x9c, 0x95, 0x21,
+ 0xcb, 0x34, 0xa0, 0x58, 0xfa, 0x0b, 0xa0, 0x7d, 0x05, 0xda, 0x57, 0x08,
+ 0x63, 0xef, 0x58, 0x29, 0x86, 0xfa, 0x04, 0x9e, 0x5f, 0xc0, 0xe7, 0xf9,
+ 0x2c, 0xe3, 0x78, 0x3b, 0x5a, 0x3d, 0x5f, 0x43, 0xe7, 0x8f, 0x64, 0x81,
+ 0xf1, 0x91, 0x3e, 0x3a, 0x2a, 0x31, 0x68, 0xd7, 0x62, 0xb5, 0x0e, 0xaf,
+ 0xce, 0x61, 0x5c, 0x55, 0x3c, 0x9e, 0x30, 0xa6, 0x8e, 0x34, 0x55, 0xf0,
+ 0x40, 0x68, 0x16, 0xbc, 0xda, 0x2f, 0xbd, 0x3f, 0x5e, 0xac, 0xbe, 0xdf,
+ 0x41, 0x74, 0x34, 0xd2, 0xc3, 0x06, 0xfc, 0x73, 0xa9, 0x1f, 0xff, 0x50,
+ 0xca, 0xe1, 0xd9, 0x52, 0x1f, 0xd1, 0xbd, 0x87, 0xe8, 0xae, 0xc7, 0x3f,
+ 0x96, 0xd6, 0xe0, 0xc7, 0xa5, 0xef, 0xe2, 0x99, 0xd2, 0x2a, 0x3c, 0x5d,
+ 0xba, 0x09, 0x07, 0x4b, 0x1e, 0xc2, 0xdd, 0x8c, 0x2f, 0x25, 0x3e, 0xcb,
+ 0xd7, 0x11, 0x1f, 0x5b, 0x30, 0x5b, 0x64, 0x79, 0x24, 0x46, 0x6c, 0x73,
+ 0x0c, 0x58, 0x90, 0xa8, 0x81, 0xc0, 0x6a, 0xdb, 0x7c, 0x0a, 0xb8, 0x0d,
+ 0x6e, 0xdc, 0x3c, 0xc1, 0x5a, 0x7a, 0x62, 0xc4, 0x40, 0x98, 0xf8, 0xb5,
+ 0xd2, 0x6d, 0xd8, 0xaa, 0xf7, 0xa1, 0xde, 0x1a, 0xc2, 0x03, 0xbe, 0x8d,
+ 0xa1, 0x45, 0x9c, 0x7f, 0x45, 0x7e, 0x48, 0xe0, 0xc1, 0x24, 0x34, 0x41,
+ 0xcf, 0x5d, 0xc5, 0xbf, 0x6b, 0xa9, 0xd8, 0x8c, 0x78, 0x28, 0x10, 0x5f,
+ 0x05, 0xe2, 0xa3, 0x40, 0xbc, 0x15, 0x88, 0x97, 0x02, 0xf1, 0x57, 0x20,
+ 0x7e, 0x0a, 0xc4, 0x4f, 0x81, 0xf8, 0x29, 0x10, 0xaf, 0x05, 0xd6, 0xf9,
+ 0x00, 0xc9, 0x52, 0xb1, 0x71, 0xab, 0x63, 0x63, 0xac, 0xd4, 0x26, 0xf6,
+ 0xee, 0x56, 0xc5, 0x73, 0xc3, 0x06, 0xe6, 0x3b, 0x88, 0x3c, 0xbd, 0xc4,
+ 0x2a, 0x5f, 0x15, 0xea, 0x9a, 0x49, 0xc0, 0x4d, 0xcf, 0x83, 0x8d, 0x89,
+ 0x92, 0x2a, 0xa6, 0x87, 0xa5, 0x5c, 0x69, 0xbb, 0x68, 0x72, 0xcc, 0x9e,
+ 0x8d, 0x8a, 0xd5, 0xff, 0xba, 0x68, 0xc4, 0x2f, 0x47, 0x7a, 0x31, 0xd6,
+ 0xec, 0xe2, 0x70, 0xd6, 0xc0, 0xb2, 0x8c, 0x82, 0x5c, 0xdc, 0xc3, 0xb6,
+ 0xac, 0x69, 0x7b, 0x18, 0x45, 0x39, 0xce, 0xe7, 0x34, 0xd2, 0xb5, 0x87,
+ 0x64, 0xb7, 0x86, 0xc9, 0x11, 0x17, 0x35, 0xe9, 0x1a, 0x94, 0xfb, 0x58,
+ 0x7f, 0x2a, 0xc9, 0xb4, 0x0f, 0xf5, 0xb1, 0x18, 0x1a, 0xac, 0x4b, 0xd0,
+ 0x10, 0xe3, 0x35, 0x88, 0x56, 0xd2, 0xd5, 0x3c, 0xe7, 0x02, 0xf1, 0xf9,
+ 0xee, 0x28, 0x3e, 0x1d, 0xd5, 0x50, 0xda, 0xa9, 0xe2, 0x1b, 0x19, 0x29,
+ 0xff, 0x2a, 0xa3, 0xf6, 0x7f, 0x2a, 0x1c, 0x4c, 0x95, 0x54, 0x7c, 0x9e,
+ 0x4f, 0xc3, 0x6b, 0xd6, 0xf0, 0x9f, 0x79, 0x0f, 0x21, 0xc2, 0x3b, 0x40,
+ 0x78, 0x6b, 0x17, 0xa7, 0x30, 0x1b, 0x67, 0x71, 0xfa, 0xb0, 0x31, 0xdf,
+ 0xb1, 0x63, 0xa3, 0x52, 0x03, 0xa3, 0x06, 0x64, 0xff, 0x2c, 0x36, 0xe5,
+ 0x3b, 0x8e, 0x6e, 0x52, 0xb6, 0xe0, 0xe2, 0x5a, 0x0d, 0x9b, 0x87, 0x79,
+ 0x6d, 0x39, 0xca, 0x45, 0x41, 0xfe, 0xf0, 0xc7, 0xea, 0x6b, 0x26, 0x42,
+ 0x7e, 0x65, 0xfc, 0xf1, 0x7a, 0x4e, 0x34, 0xa2, 0xde, 0x34, 0xca, 0x58,
+ 0x1f, 0xe7, 0xf3, 0x39, 0xe5, 0x5d, 0xe9, 0xc6, 0x99, 0x0f, 0xcd, 0x0b,
+ 0x91, 0x6e, 0x6e, 0xc9, 0x66, 0xb1, 0x26, 0xdf, 0xa1, 0xaf, 0x51, 0x48,
+ 0xdb, 0x6a, 0xc5, 0xc6, 0x71, 0x07, 0xe9, 0xd1, 0x61, 0x81, 0x91, 0x4e,
+ 0xb6, 0x31, 0xd2, 0x76, 0xd1, 0x8f, 0x09, 0xc3, 0x50, 0x2a, 0x31, 0xf1,
+ 0x58, 0x36, 0x89, 0xb3, 0x0f, 0xf1, 0x6f, 0x15, 0x3f, 0x5b, 0x9a, 0xc4,
+ 0xc7, 0xfb, 0x4a, 0x73, 0x71, 0xfb, 0x68, 0xa4, 0xb2, 0xef, 0x1a, 0xa2,
+ 0xc9, 0x32, 0x32, 0xae, 0xc9, 0x7b, 0x47, 0x3b, 0x6b, 0xe9, 0x77, 0xc5,
+ 0xd6, 0xfd, 0xf9, 0x0e, 0xbb, 0x5f, 0xd1, 0x50, 0x4e, 0x44, 0x48, 0xf7,
+ 0xd0, 0xea, 0x08, 0xff, 0x25, 0x43, 0x67, 0xb0, 0x22, 0x63, 0x4e, 0xf2,
+ 0xdf, 0x80, 0x25, 0x93, 0x15, 0x9a, 0xc9, 0xa2, 0x8d, 0x03, 0x25, 0x1b,
+ 0x77, 0xe4, 0x3b, 0xdc, 0x95, 0x62, 0x16, 0x68, 0x5f, 0x98, 0x9b, 0x54,
+ 0x7e, 0x21, 0xbd, 0x56, 0xa6, 0xb3, 0x10, 0x93, 0xb1, 0x8e, 0x81, 0x49,
+ 0xc5, 0xdc, 0xd3, 0xaf, 0x48, 0xf9, 0xab, 0xb4, 0x82, 0xaf, 0x65, 0xb2,
+ 0x98, 0xd5, 0x75, 0xdc, 0x9c, 0xd1, 0xbc, 0x16, 0xe2, 0x71, 0xc3, 0x12,
+ 0x0d, 0x17, 0xed, 0x74, 0xf1, 0xf6, 0xe2, 0x9f, 0xa3, 0xbc, 0x82, 0x75,
+ 0xcf, 0x7c, 0xb1, 0x1c, 0x09, 0xc4, 0xac, 0x3a, 0xc4, 0xf6, 0x86, 0x31,
+ 0x6f, 0xe7, 0x59, 0x99, 0xb0, 0x78, 0xdd, 0x9a, 0x3c, 0xa5, 0xb0, 0x0c,
+ 0x61, 0xb4, 0xee, 0xbd, 0x82, 0x72, 0x8a, 0x99, 0x02, 0xbe, 0x16, 0xe7,
+ 0xbd, 0x35, 0x56, 0x55, 0x96, 0x08, 0x76, 0xef, 0xac, 0xc8, 0xff, 0x68,
+ 0xb6, 0x07, 0x2f, 0x15, 0xb0, 0xaf, 0x0d, 0x3f, 0xc0, 0xc8, 0x12, 0xce,
+ 0x4f, 0x8c, 0x63, 0x88, 0x64, 0xff, 0xc1, 0x89, 0x70, 0xa6, 0x6a, 0xe3,
+ 0xea, 0x39, 0x81, 0x6f, 0x5e, 0x29, 0xf0, 0x6a, 0x7a, 0x5a, 0x8e, 0xb5,
+ 0x32, 0xbf, 0x0f, 0x37, 0x56, 0xfe, 0x16, 0xae, 0xee, 0x94, 0x8b, 0x36,
+ 0xa2, 0x55, 0xdd, 0xc7, 0x38, 0x2e, 0x69, 0x25, 0xfd, 0xa5, 0x66, 0xf1,
+ 0x5f, 0x11, 0xd4, 0xb3, 0x9d, 0xef, 0x96, 0x46, 0x4b, 0x85, 0xe6, 0xfd,
+ 0x44, 0xb3, 0x63, 0x48, 0xc5, 0xe6, 0x7c, 0xc7, 0xa9, 0xf7, 0x94, 0xef,
+ 0xcb, 0xd9, 0xf9, 0x4c, 0xa7, 0xc3, 0x3e, 0xa6, 0x08, 0xfc, 0x54, 0x35,
+ 0x67, 0x72, 0x48, 0x60, 0xb2, 0x04, 0xaf, 0xdd, 0xd1, 0x29, 0xfe, 0xe3,
+ 0x94, 0x07, 0x0c, 0xd1, 0xf9, 0xb0, 0x8d, 0x85, 0x43, 0xdf, 0x85, 0xb5,
+ 0xcb, 0xc1, 0x4c, 0xc1, 0xc6, 0x54, 0x41, 0xca, 0xed, 0xb6, 0x94, 0xef,
+ 0xda, 0xe6, 0x86, 0xe3, 0x21, 0xb8, 0x97, 0x2f, 0xed, 0x4a, 0xd5, 0x86,
+ 0x54, 0xd6, 0x4d, 0xee, 0x75, 0x91, 0x5c, 0xb5, 0x5f, 0xf4, 0xe2, 0x89,
+ 0x92, 0x81, 0x62, 0x29, 0x85, 0x27, 0x4b, 0xac, 0x7f, 0x8b, 0xbe, 0x17,
+ 0x51, 0x7c, 0x66, 0x29, 0xb7, 0x30, 0xbf, 0x3a, 0xc6, 0x17, 0xd8, 0x98,
+ 0x2c, 0x28, 0x08, 0x91, 0xce, 0x73, 0x3a, 0xed, 0x2f, 0x9c, 0x25, 0xdb,
+ 0x69, 0xe8, 0xf8, 0xa1, 0x8b, 0xdb, 0xed, 0x16, 0x18, 0x37, 0x5a, 0x18,
+ 0x2f, 0x68, 0x94, 0xbb, 0x55, 0xf4, 0xe6, 0xc7, 0x31, 0xaf, 0x39, 0x4e,
+ 0xb1, 0x26, 0xb0, 0x2a, 0x13, 0x01, 0x56, 0xf2, 0xbb, 0x08, 0xda, 0xad,
+ 0x32, 0xda, 0x63, 0x8d, 0x98, 0xbf, 0xf0, 0x9f, 0x30, 0xdb, 0x12, 0x25,
+ 0x1d, 0xd7, 0x93, 0x1e, 0x04, 0x54, 0xb2, 0x53, 0x9b, 0x65, 0x11, 0x4e,
+ 0x01, 0x2b, 0x49, 0x7b, 0x29, 0x7e, 0x13, 0x24, 0x7b, 0x78, 0x69, 0x1c,
+ 0x8f, 0x13, 0xff, 0xa5, 0xbc, 0x94, 0x91, 0xac, 0xb9, 0x61, 0x3b, 0xe5,
+ 0x84, 0xe9, 0x62, 0x0f, 0x4a, 0xa5, 0x6f, 0x62, 0x6a, 0x84, 0xf8, 0xcc,
+ 0x3b, 0xc4, 0x93, 0xaa, 0x17, 0x85, 0xd9, 0xb7, 0x5a, 0x64, 0xf1, 0x24,
+ 0xf9, 0xce, 0x44, 0xc1, 0x34, 0x8e, 0x93, 0x9f, 0xbd, 0x60, 0x37, 0x10,
+ 0x9f, 0x2e, 0xe1, 0x32, 0xf0, 0x5c, 0xbe, 0x00, 0xab, 0x85, 0xed, 0x15,
+ 0xc1, 0xfd, 0x3b, 0xb3, 0x84, 0x13, 0x83, 0x75, 0xf0, 0xa0, 0x2e, 0xf1,
+ 0x4e, 0x6c, 0xb5, 0x87, 0x22, 0x55, 0x1f, 0xaf, 0x27, 0x9a, 0x7d, 0xdd,
+ 0x36, 0x42, 0xc3, 0x3d, 0x84, 0x97, 0xfc, 0x15, 0xb7, 0x92, 0xbf, 0x7a,
+ 0xb8, 0x9c, 0xe2, 0x21, 0xea, 0xec, 0x49, 0xbf, 0x36, 0xe4, 0xc9, 0x5a,
+ 0xcb, 0xea, 0xff, 0x48, 0x6c, 0xc2, 0x27, 0x69, 0xb6, 0x83, 0x4a, 0xf2,
+ 0xea, 0x78, 0x39, 0x3d, 0x82, 0x57, 0x8b, 0x7f, 0x82, 0x5c, 0xb3, 0x99,
+ 0xda, 0x2c, 0xd6, 0x61, 0x66, 0xe4, 0x0a, 0xe0, 0xcf, 0xd9, 0x7e, 0x02,
+ 0xf3, 0xad, 0x75, 0x38, 0x34, 0x76, 0x2f, 0x8e, 0x8c, 0xd6, 0xe3, 0x39,
+ 0x2b, 0x86, 0xf6, 0x89, 0x0a, 0x9d, 0x6b, 0xe6, 0x72, 0x93, 0x9e, 0xa6,
+ 0xe0, 0x6b, 0xe3, 0x98, 0x14, 0xb8, 0x3e, 0xb3, 0x0e, 0x39, 0xdf, 0xcf,
+ 0x3d, 0xac, 0xa1, 0xdc, 0x96, 0xcf, 0xbb, 0x14, 0xd7, 0x75, 0xd8, 0xd9,
+ 0x0c, 0x71, 0x0b, 0xd5, 0x93, 0x3b, 0x29, 0x5e, 0xef, 0x54, 0x62, 0x70,
+ 0x13, 0x2e, 0xd9, 0x55, 0xe0, 0x22, 0xcb, 0xc0, 0x9e, 0x22, 0x70, 0x77,
+ 0x51, 0xc5, 0xdf, 0x14, 0x2f, 0x45, 0xb9, 0x8d, 0xcf, 0x2e, 0x40, 0x79,
+ 0x1e, 0x7f, 0x87, 0x31, 0x16, 0x33, 0x13, 0x20, 0x9d, 0xed, 0x2f, 0xa8,
+ 0xf8, 0xb1, 0xbd, 0xeb, 0xec, 0xd8, 0x0a, 0x53, 0xcf, 0x51, 0xac, 0x85,
+ 0xac, 0xd3, 0xe4, 0x67, 0xfc, 0x0c, 0x7c, 0x3f, 0xff, 0x99, 0xfc, 0xb9,
+ 0x4f, 0x53, 0xc5, 0x6d, 0xf9, 0x8e, 0x81, 0x8f, 0x94, 0x8f, 0xe5, 0xbf,
+ 0x85, 0x19, 0xff, 0x77, 0xa2, 0x15, 0x7f, 0xdd, 0xc3, 0x79, 0xc4, 0xad,
+ 0xf8, 0xed, 0xbc, 0x2f, 0xf8, 0x6d, 0xc5, 0x3f, 0x47, 0xb2, 0xcc, 0x47,
+ 0x35, 0xc6, 0x62, 0xb8, 0x68, 0x22, 0x89, 0xba, 0x9d, 0xfc, 0x9b, 0xd7,
+ 0x05, 0x2e, 0xee, 0xe6, 0xf8, 0x4a, 0x42, 0xd9, 0x7b, 0x2d, 0xe1, 0x63,
+ 0xd9, 0xab, 0xb9, 0xe2, 0x7b, 0x73, 0xf8, 0xcf, 0xe7, 0x98, 0x76, 0xc2,
+ 0xb7, 0x74, 0x29, 0x3f, 0xf3, 0x99, 0x3a, 0xfc, 0x7a, 0xaf, 0x69, 0x97,
+ 0x95, 0xa5, 0x44, 0x93, 0x63, 0x92, 0x63, 0xf3, 0x2f, 0xe6, 0xce, 0x24,
+ 0xc8, 0xce, 0xd3, 0xb2, 0xbc, 0x8a, 0xf1, 0x55, 0xcf, 0x27, 0x11, 0x3a,
+ 0x47, 0x57, 0xc5, 0xea, 0xec, 0x97, 0xe9, 0xda, 0x94, 0xf7, 0x5b, 0xd1,
+ 0xb0, 0xd0, 0x22, 0x3b, 0xb5, 0xa1, 0x91, 0xe2, 0x3a, 0x62, 0xad, 0x92,
+ 0x91, 0x6f, 0xb3, 0x8f, 0x6a, 0x5e, 0xd8, 0xf9, 0x0a, 0x4a, 0x23, 0xcf,
+ 0x93, 0x7d, 0xa3, 0xec, 0x8b, 0x1b, 0x3e, 0x12, 0x5f, 0xc1, 0xf4, 0x98,
+ 0x88, 0xb2, 0xac, 0xab, 0x28, 0xb6, 0xe7, 0x53, 0x7d, 0xf8, 0xe0, 0xe1,
+ 0xbb, 0xe4, 0x58, 0x9f, 0x8e, 0x17, 0xb3, 0x49, 0x5a, 0x67, 0x5f, 0xb2,
+ 0xf1, 0x4c, 0x5e, 0xc3, 0xee, 0xe1, 0x84, 0xef, 0xc7, 0xf7, 0x74, 0xd6,
+ 0x9d, 0x2a, 0x2b, 0x36, 0x9e, 0x25, 0x3f, 0x3c, 0x58, 0x60, 0x1d, 0xab,
+ 0xb8, 0x38, 0xf3, 0x75, 0x59, 0xd3, 0xc6, 0xbe, 0x1d, 0xa1, 0x33, 0x3a,
+ 0xe1, 0x8e, 0x42, 0xb7, 0x96, 0xcb, 0x37, 0x56, 0xf0, 0x73, 0x03, 0xad,
+ 0xb5, 0xd1, 0xf7, 0x12, 0xd9, 0xf8, 0x3b, 0x7c, 0xe8, 0xff, 0x1b, 0x1f,
+ 0xf4, 0x1d, 0xa3, 0x75, 0x90, 0xbf, 0xcc, 0x88, 0xd5, 0x95, 0xfe, 0x46,
+ 0x53, 0xad, 0x19, 0xb1, 0xc6, 0xef, 0x69, 0xfc, 0x34, 0x4e, 0x38, 0x7a,
+ 0xb1, 0x77, 0x54, 0xca, 0x2d, 0x76, 0x3b, 0x5c, 0x3d, 0x86, 0x2d, 0x16,
+ 0xc5, 0xeb, 0x28, 0x9f, 0x91, 0x32, 0x95, 0x5e, 0xd8, 0xa3, 0x8a, 0x16,
+ 0xca, 0x99, 0x9e, 0x58, 0x9b, 0x35, 0xc4, 0x9d, 0xa3, 0x2a, 0xf2, 0x85,
+ 0x0b, 0x28, 0x27, 0x4b, 0xf9, 0x64, 0x1a, 0xee, 0x60, 0xba, 0x01, 0x2f,
+ 0x8f, 0xe9, 0x14, 0x3b, 0x67, 0xe5, 0xf2, 0x64, 0x2f, 0x4a, 0x84, 0xe7,
+ 0xd3, 0x74, 0x57, 0xea, 0xb0, 0x88, 0x60, 0x2c, 0x1e, 0xc1, 0x9e, 0x42,
+ 0x1c, 0x87, 0xc7, 0x23, 0xd8, 0x46, 0xfe, 0xf7, 0xd3, 0x2c, 0xd3, 0x8c,
+ 0x60, 0x73, 0x89, 0x7b, 0x8d, 0x10, 0xe9, 0xc0, 0x13, 0xef, 0xf9, 0x6b,
+ 0x0d, 0x58, 0x3e, 0xc6, 0x7b, 0xcf, 0xca, 0x76, 0xcb, 0xd2, 0xdb, 0x43,
+ 0xd5, 0x7d, 0xef, 0x50, 0x1f, 0x63, 0x50, 0xef, 0x72, 0x21, 0xe5, 0xaa,
+ 0x04, 0xf5, 0x2a, 0x71, 0xea, 0x55, 0xac, 0xb9, 0xfe, 0xcb, 0xa4, 0x48,
+ 0x93, 0xf2, 0x19, 0xca, 0x53, 0x6f, 0xd2, 0xe7, 0xa4, 0x4d, 0xe5, 0x96,
+ 0x64, 0xbc, 0x78, 0x98, 0x65, 0xf4, 0x84, 0xbd, 0x84, 0x3a, 0xce, 0x69,
+ 0xd3, 0x70, 0x95, 0x5f, 0x50, 0x9f, 0x65, 0xa0, 0x63, 0x9a, 0x79, 0x50,
+ 0xb1, 0xb5, 0x00, 0x0c, 0x16, 0xe0, 0x1d, 0xa6, 0xd8, 0x6e, 0x99, 0x88,
+ 0x22, 0x36, 0xa1, 0x23, 0x3c, 0x91, 0xa2, 0xbd, 0x1a, 0xe2, 0xf4, 0xdb,
+ 0xa3, 0xbe, 0xab, 0xc9, 0x69, 0x13, 0x8b, 0x76, 0x9f, 0x91, 0x0f, 0x52,
+ 0xac, 0xdd, 0x91, 0x34, 0x7b, 0x6f, 0x14, 0x70, 0x53, 0x43, 0x52, 0xd6,
+ 0xa6, 0x6b, 0xa9, 0x7e, 0xcb, 0x43, 0x71, 0x92, 0x3d, 0xea, 0xc8, 0x4d,
+ 0xaf, 0x76, 0x5b, 0xf6, 0xab, 0x20, 0xbc, 0x25, 0x3e, 0xc3, 0xeb, 0x9e,
+ 0xf8, 0xac, 0xdb, 0xda, 0xf3, 0x16, 0x3a, 0xb1, 0x78, 0x42, 0x15, 0xbf,
+ 0x1c, 0x5a, 0x84, 0xcc, 0x34, 0xf4, 0x1a, 0xe2, 0xeb, 0xc3, 0x29, 0xe2,
+ 0xbb, 0x40, 0xb2, 0x14, 0x48, 0x96, 0x02, 0xc9, 0x42, 0x7a, 0x39, 0xe8,
+ 0xf7, 0x6d, 0x2c, 0x6b, 0x8a, 0xea, 0xef, 0x3b, 0x7e, 0x6f, 0x79, 0xb0,
+ 0xc4, 0x72, 0x98, 0xae, 0x07, 0x96, 0x9b, 0xe5, 0x94, 0xf2, 0x2d, 0x9b,
+ 0xe5, 0x31, 0x0d, 0x4f, 0x21, 0x6b, 0x4d, 0x1b, 0x48, 0x4d, 0x57, 0xf5,
+ 0x21, 0xe5, 0xe7, 0x36, 0xeb, 0x83, 0x65, 0x94, 0xf2, 0x69, 0x92, 0x69,
+ 0x2b, 0xc9, 0x38, 0x58, 0x90, 0x87, 0x6a, 0x2c, 0xcb, 0x98, 0x20, 0xde,
+ 0x62, 0x24, 0x53, 0x7c, 0x42, 0x23, 0x59, 0x3b, 0xa1, 0x92, 0xac, 0xa1,
+ 0x09, 0xe8, 0x0a, 0xeb, 0x69, 0xfa, 0xff, 0xe2, 0x87, 0xfb, 0x6a, 0x4f,
+ 0x5c, 0x43, 0xfd, 0xb4, 0x4a, 0xfb, 0x07, 0xc9, 0x77, 0x72, 0x2a, 0x8c,
+ 0x5a, 0x4b, 0xa1, 0x3c, 0xac, 0xe1, 0xf1, 0xf1, 0x06, 0x4c, 0x90, 0xdd,
+ 0xc7, 0xc6, 0xa1, 0x87, 0xe9, 0xfd, 0xd6, 0x73, 0xfe, 0x04, 0xf2, 0xa7,
+ 0x0d, 0x18, 0xa7, 0xfc, 0xf3, 0x40, 0x3e, 0x26, 0x26, 0x46, 0x54, 0x6c,
+ 0x29, 0x9c, 0x20, 0xd9, 0x24, 0xe5, 0xd8, 0xcd, 0x09, 0xda, 0x22, 0x36,
+ 0xdb, 0x66, 0x0f, 0x70, 0x05, 0xf9, 0x5a, 0x08, 0x6b, 0x2d, 0xb8, 0xdb,
+ 0xed, 0x2b, 0x30, 0xdb, 0x07, 0x63, 0x87, 0xed, 0xe9, 0x35, 0x30, 0x8f,
+ 0x5e, 0x43, 0xa3, 0xc0, 0xe5, 0x24, 0xc7, 0x80, 0xe5, 0x6d, 0xa0, 0x84,
+ 0x44, 0xf9, 0xdb, 0xec, 0x3f, 0x42, 0x36, 0x28, 0x52, 0x5d, 0x2b, 0x52,
+ 0x0f, 0x78, 0x60, 0xf4, 0x8c, 0xbc, 0x3d, 0x6d, 0xba, 0x49, 0x5a, 0x0b,
+ 0x0f, 0x69, 0xd8, 0x5f, 0xd2, 0x28, 0x5e, 0x4c, 0x1b, 0xe0, 0x98, 0x87,
+ 0x56, 0x4b, 0x3d, 0xda, 0x47, 0xd6, 0xa3, 0xd4, 0x0b, 0x6b, 0xa0, 0x3e,
+ 0x19, 0x57, 0x8f, 0x08, 0xec, 0xa7, 0xf8, 0x9d, 0x5a, 0x64, 0x1e, 0x5d,
+ 0x0d, 0xaf, 0xdc, 0x0e, 0x73, 0xa0, 0x96, 0x18, 0xf9, 0x74, 0xa8, 0x86,
+ 0xfa, 0xc2, 0x4e, 0xfb, 0x35, 0x98, 0xfa, 0xfe, 0xd0, 0xaf, 0xe4, 0x64,
+ 0x1c, 0x17, 0x84, 0x71, 0x52, 0x1a, 0xdf, 0xe2, 0x33, 0x2c, 0xf7, 0x06,
+ 0x6c, 0xcf, 0x42, 0x0b, 0x3b, 0x6a, 0x7a, 0x7f, 0x1e, 0x38, 0x96, 0x37,
+ 0x30, 0xb9, 0xa8, 0x0e, 0x68, 0xee, 0xe8, 0xb9, 0x03, 0xde, 0xaa, 0xb0,
+ 0xdf, 0xe7, 0x6a, 0xe9, 0x3c, 0xf9, 0xc8, 0x7a, 0x21, 0xf0, 0x24, 0xd1,
+ 0x5a, 0x30, 0xc5, 0x7d, 0x89, 0x9a, 0x5e, 0x48, 0x79, 0x76, 0x5b, 0x49,
+ 0xa0, 0xd6, 0x32, 0xf5, 0x59, 0xb0, 0x6e, 0x74, 0xd2, 0xe9, 0x19, 0x89,
+ 0x66, 0x96, 0xdd, 0xcb, 0x91, 0x9c, 0xab, 0xb6, 0x12, 0xff, 0x6b, 0x48,
+ 0xa6, 0xdb, 0x2d, 0xaf, 0x87, 0xb0, 0x52, 0xed, 0x31, 0x13, 0x1f, 0x90,
+ 0xec, 0x6b, 0x29, 0x47, 0x8c, 0x95, 0x86, 0x9b, 0x38, 0x1f, 0x4c, 0x94,
+ 0x78, 0x4e, 0xea, 0xc1, 0xd5, 0xf9, 0x6a, 0x2c, 0xb0, 0xdd, 0xd9, 0xe6,
+ 0x17, 0xfa, 0xf5, 0xfb, 0xa0, 0xef, 0x23, 0xdc, 0x3f, 0xf5, 0x60, 0xb4,
+ 0x53, 0xa1, 0xde, 0x5c, 0xca, 0x15, 0x96, 0x39, 0xc2, 0xf9, 0x99, 0x7c,
+ 0xdd, 0xdd, 0x67, 0x37, 0x51, 0x6c, 0xc2, 0x7b, 0xc2, 0x36, 0x50, 0xe3,
+ 0xb0, 0x4f, 0x34, 0x90, 0x8f, 0x47, 0xb0, 0x9d, 0x7c, 0x44, 0xb3, 0xac,
+ 0x14, 0x35, 0x53, 0xfa, 0xb1, 0x2c, 0xed, 0x2d, 0xc1, 0x28, 0xd9, 0xf5,
+ 0x98, 0x6d, 0x55, 0xd1, 0xec, 0x1c, 0x92, 0x2d, 0xd6, 0x7f, 0x10, 0x7d,
+ 0x4b, 0xbf, 0x1b, 0xab, 0x61, 0xb4, 0x1a, 0x68, 0x70, 0xf8, 0xfd, 0x69,
+ 0x39, 0xdb, 0x1c, 0x21, 0xff, 0xe2, 0x3d, 0x96, 0x77, 0x10, 0xbf, 0x96,
+ 0x88, 0xf1, 0x5e, 0x97, 0xf2, 0x27, 0xc4, 0x0c, 0xd1, 0x42, 0x0b, 0xc7,
+ 0x2d, 0xf7, 0xe7, 0xd6, 0xd1, 0x43, 0x54, 0x53, 0x8c, 0x16, 0x50, 0x2e,
+ 0x55, 0x11, 0x72, 0x2c, 0x7d, 0x1f, 0x8e, 0x92, 0xcd, 0xd9, 0x45, 0x2e,
+ 0x12, 0xd7, 0xed, 0xba, 0x50, 0xf4, 0xee, 0x92, 0xb2, 0x33, 0x0d, 0x9a,
+ 0xc2, 0x92, 0xc6, 0x4b, 0xb4, 0xba, 0x85, 0x7c, 0xbf, 0xd1, 0x89, 0x88,
+ 0xe2, 0x2e, 0xe8, 0x07, 0x6c, 0x8d, 0xf2, 0xae, 0x94, 0xdb, 0xd2, 0x06,
+ 0xa6, 0x6d, 0xea, 0xc7, 0x5b, 0xc3, 0x68, 0xb6, 0xa0, 0xeb, 0x8e, 0x35,
+ 0xf0, 0x14, 0xee, 0x26, 0x3e, 0x11, 0x99, 0x4f, 0x35, 0x90, 0xd6, 0xc4,
+ 0x5e, 0xbb, 0x0e, 0xee, 0x4d, 0x02, 0x11, 0x27, 0x4e, 0xbc, 0xd5, 0x20,
+ 0xe7, 0x3f, 0xb3, 0x8c, 0x70, 0xdf, 0xb7, 0x7f, 0x44, 0xf2, 0x8a, 0xf9,
+ 0xf5, 0x0e, 0xaf, 0x59, 0x76, 0x11, 0xeb, 0xa9, 0xe7, 0xa7, 0x25, 0x7a,
+ 0xbf, 0x85, 0xde, 0x3f, 0x44, 0xb8, 0x73, 0x31, 0x7f, 0xd6, 0x6b, 0x6a,
+ 0x77, 0xac, 0xf2, 0x73, 0x78, 0x90, 0x64, 0xe0, 0xfc, 0xcd, 0x6b, 0xcc,
+ 0xf3, 0x22, 0xe6, 0x99, 0x6a, 0x37, 0xfb, 0x95, 0x8d, 0x8f, 0xf2, 0x77,
+ 0x73, 0x0f, 0xef, 0xee, 0xb0, 0x21, 0x26, 0xec, 0x3d, 0x28, 0xeb, 0x68,
+ 0x8a, 0x3a, 0x56, 0xff, 0x34, 0xa0, 0x44, 0x9c, 0x51, 0x14, 0x9b, 0x81,
+ 0x87, 0x0a, 0x96, 0xb7, 0x51, 0x31, 0x07, 0xe2, 0xd4, 0xf7, 0x9e, 0xfc,
+ 0xa1, 0x8a, 0x9d, 0x9d, 0x65, 0x33, 0x46, 0x46, 0x8f, 0x3a, 0x51, 0xf1,
+ 0xe2, 0x2e, 0x05, 0x0b, 0x96, 0xa8, 0x78, 0x8b, 0x72, 0xc8, 0x36, 0x9a,
+ 0x45, 0xc2, 0x96, 0xda, 0x54, 0xe9, 0x89, 0x7f, 0x5f, 0x3c, 0x9a, 0xa4,
+ 0xb1, 0x6a, 0x4c, 0x5a, 0x7d, 0x07, 0xf0, 0xa8, 0x74, 0x9b, 0xd9, 0x16,
+ 0x11, 0xca, 0xc3, 0xe7, 0xf2, 0x50, 0x6a, 0x8a, 0xf0, 0x0f, 0x76, 0xbf,
+ 0xeb, 0xfb, 0x0c, 0xd9, 0xd2, 0x7d, 0x23, 0x0f, 0xd1, 0x94, 0x71, 0x30,
+ 0xdb, 0xcc, 0x76, 0xe1, 0xf9, 0x99, 0x94, 0x37, 0x4c, 0xc3, 0x47, 0x8b,
+ 0x8a, 0xc5, 0x19, 0x34, 0x29, 0x8e, 0x75, 0x6a, 0x2f, 0xf1, 0xdc, 0xee,
+ 0x34, 0xe1, 0x74, 0x0b, 0xe7, 0xc4, 0xa8, 0xf8, 0xd9, 0xa8, 0xd9, 0x43,
+ 0x3d, 0xee, 0xaa, 0x8d, 0x30, 0xfb, 0xee, 0x11, 0xd4, 0x97, 0x11, 0xef,
+ 0x56, 0x92, 0xf8, 0xb4, 0x55, 0xc4, 0x93, 0x65, 0x33, 0x8e, 0x2a, 0xbf,
+ 0x67, 0x65, 0xcc, 0xb2, 0xbc, 0x98, 0xf2, 0x1b, 0x99, 0xce, 0xb0, 0x8f,
+ 0xdf, 0x85, 0xda, 0x98, 0x40, 0x4d, 0x66, 0xc4, 0xd7, 0x6d, 0x94, 0xec,
+ 0xdd, 0x94, 0x51, 0x89, 0xb6, 0x4a, 0x39, 0x9d, 0x68, 0x2f, 0x1e, 0xa0,
+ 0x9e, 0x85, 0x75, 0xfa, 0x92, 0xcc, 0x7d, 0x9b, 0xe5, 0xbc, 0x65, 0x4e,
+ 0x66, 0xd2, 0x6c, 0x3d, 0xff, 0x96, 0x0d, 0xac, 0xfb, 0x43, 0x94, 0xcf,
+ 0x17, 0x2f, 0xed, 0xda, 0x31, 0xa0, 0x3c, 0x20, 0x8d, 0x15, 0x6c, 0xdb,
+ 0x46, 0x7a, 0xef, 0xdb, 0x9d, 0xfa, 0xa9, 0x77, 0xf0, 0xda, 0x50, 0x54,
+ 0x34, 0xed, 0xf6, 0xfc, 0xda, 0xf9, 0x2a, 0xf1, 0xf5, 0x61, 0x9a, 0xf9,
+ 0xe1, 0x78, 0x7b, 0x07, 0x97, 0x16, 0xff, 0x94, 0xf6, 0x86, 0x88, 0x17,
+ 0x68, 0x31, 0x92, 0x75, 0x05, 0xcd, 0x25, 0x57, 0x67, 0x0e, 0x48, 0x57,
+ 0x67, 0xfc, 0xa4, 0xf7, 0x51, 0xd6, 0x3b, 0xcf, 0x45, 0x55, 0xdd, 0xf3,
+ 0x7e, 0x3e, 0x3f, 0x4c, 0x31, 0xc9, 0xb6, 0x44, 0x53, 0x83, 0xc3, 0xfa,
+ 0x85, 0xa8, 0x73, 0xba, 0x8c, 0x85, 0x62, 0x87, 0xf4, 0xe2, 0xd5, 0x7c,
+ 0x16, 0x15, 0x13, 0xfe, 0x79, 0xa6, 0xfd, 0xe5, 0xf3, 0x6d, 0xe2, 0xd8,
+ 0xc3, 0x54, 0x7c, 0xeb, 0x7d, 0x7f, 0xe9, 0x7d, 0x92, 0xe2, 0x49, 0x73,
+ 0x6e, 0x95, 0xa9, 0x56, 0xf6, 0x37, 0x28, 0x2f, 0xdb, 0xb7, 0xc8, 0x5c,
+ 0x2b, 0xfb, 0x1d, 0xbc, 0x38, 0xe1, 0xd9, 0xb9, 0xfb, 0x3c, 0x1f, 0xd7,
+ 0x74, 0x4a, 0x39, 0x61, 0x5f, 0x45, 0xba, 0x60, 0x3c, 0x55, 0x5d, 0xfc,
+ 0xe5, 0x9c, 0x6e, 0xa8, 0x89, 0xae, 0xaf, 0xd4, 0x2b, 0xce, 0x69, 0x35,
+ 0xce, 0x1b, 0x78, 0x31, 0xaf, 0xb4, 0x85, 0xd1, 0x84, 0x3e, 0x5b, 0xe0,
+ 0xdd, 0x1e, 0x81, 0xd3, 0x97, 0x47, 0x10, 0xba, 0xcc, 0x2a, 0x77, 0x84,
+ 0xfa, 0x25, 0xe6, 0x95, 0xc9, 0x51, 0xce, 0x48, 0xad, 0x53, 0x45, 0xed,
+ 0xa5, 0x5c, 0xa7, 0xd8, 0x0e, 0x0a, 0xfe, 0x85, 0xf6, 0x5d, 0x77, 0xa9,
+ 0x65, 0x74, 0x50, 0x4b, 0xe0, 0xf5, 0x5d, 0x9d, 0x09, 0x9f, 0xf3, 0x43,
+ 0xe6, 0xe1, 0x4a, 0x5f, 0x06, 0xf6, 0xc7, 0xc5, 0x64, 0xc7, 0xdc, 0x0a,
+ 0x05, 0xe9, 0x25, 0xf0, 0x22, 0xf4, 0x7e, 0xdb, 0x2e, 0xf6, 0x85, 0x47,
+ 0x74, 0x9e, 0x09, 0x81, 0xae, 0x84, 0x0e, 0x6b, 0xd5, 0x0b, 0x44, 0x9b,
+ 0xfa, 0x4d, 0xd2, 0x07, 0xd3, 0xaa, 0xe2, 0xa9, 0xe2, 0x88, 0x8a, 0xd3,
+ 0x0f, 0xf3, 0x19, 0x08, 0xd6, 0x51, 0x7a, 0x01, 0xc5, 0x76, 0x46, 0x9d,
+ 0x93, 0x6d, 0x40, 0xaf, 0xf4, 0x61, 0x51, 0x31, 0x35, 0xca, 0xf8, 0x7c,
+ 0x3f, 0x42, 0x91, 0x7d, 0x2b, 0xcd, 0x7b, 0x7e, 0x23, 0x17, 0x64, 0xfe,
+ 0x9d, 0xf6, 0x30, 0xde, 0xa8, 0x38, 0xe2, 0xd3, 0xae, 0xe8, 0x68, 0x8a,
+ 0x74, 0x3d, 0x91, 0xae, 0xe2, 0xd9, 0x48, 0x7b, 0xd8, 0xe7, 0x98, 0x87,
+ 0x5e, 0xf1, 0x78, 0x9e, 0xf2, 0x0a, 0xd5, 0xdc, 0x89, 0xac, 0x62, 0xd5,
+ 0x42, 0x62, 0xb3, 0xad, 0x63, 0x99, 0x5e, 0xa9, 0x57, 0xf7, 0xe7, 0xab,
+ 0xf7, 0x3f, 0xbd, 0xa2, 0x90, 0x57, 0xa8, 0x7f, 0x83, 0x5e, 0xef, 0x28,
+ 0xf7, 0x34, 0x51, 0x2c, 0xbd, 0x46, 0xb5, 0xeb, 0xd5, 0xb1, 0x5e, 0x91,
+ 0xcf, 0xeb, 0x78, 0x65, 0x7c, 0xb9, 0x78, 0x30, 0x6f, 0xe1, 0xe5, 0x62,
+ 0xe5, 0x2e, 0xe8, 0x81, 0xa2, 0x2b, 0xc6, 0xf3, 0xdc, 0xfb, 0x98, 0xa9,
+ 0x32, 0x66, 0xc4, 0x5a, 0xc2, 0x53, 0x56, 0x2f, 0xf4, 0xeb, 0xc8, 0x78,
+ 0xb1, 0x01, 0x93, 0x63, 0x95, 0x7a, 0x77, 0xeb, 0xb9, 0x7a, 0xf7, 0xc5,
+ 0x3b, 0x9d, 0x48, 0x4e, 0x77, 0xd0, 0xd7, 0x38, 0xbc, 0x49, 0x46, 0xad,
+ 0x10, 0xd5, 0x49, 0x2b, 0x37, 0x2d, 0x22, 0x3d, 0x3b, 0xba, 0x99, 0x5f,
+ 0xf4, 0x69, 0xd4, 0x63, 0x4c, 0x14, 0xd9, 0x5f, 0x0d, 0x18, 0xc5, 0x6f,
+ 0xb5, 0x56, 0xec, 0xdc, 0x96, 0xd3, 0x1c, 0xa0, 0x9e, 0xfa, 0x8b, 0x06,
+ 0x9a, 0x0d, 0xea, 0x9c, 0x1b, 0xbd, 0x8e, 0x6e, 0xe4, 0x54, 0xc7, 0xea,
+ 0xb9, 0x5e, 0xac, 0x5c, 0xa9, 0x38, 0xf7, 0xad, 0x0c, 0x4d, 0x1b, 0xc6,
+ 0x16, 0xbf, 0x0e, 0x9d, 0x1c, 0xd8, 0x4f, 0x33, 0x50, 0x0d, 0xcd, 0xa5,
+ 0xef, 0xe9, 0xb8, 0x2f, 0xd4, 0x7d, 0x1f, 0x36, 0xe5, 0x07, 0xf0, 0xb7,
+ 0x79, 0xce, 0x13, 0x3a, 0x1e, 0x63, 0x1e, 0x0a, 0x7c, 0xff, 0x73, 0xb0,
+ 0x85, 0x6b, 0xdf, 0x23, 0x25, 0x8a, 0xc3, 0x21, 0xe4, 0x12, 0x8e, 0x9f,
+ 0x47, 0x12, 0xa7, 0xc4, 0xf9, 0xfd, 0xbf, 0xbb, 0x97, 0xf5, 0x46, 0xfd,
+ 0x1c, 0xcd, 0x4e, 0x4a, 0xf6, 0x4a, 0xbe, 0x7f, 0xf2, 0x03, 0x74, 0x3b,
+ 0xe5, 0x91, 0x0f, 0x6c, 0x13, 0x63, 0x7a, 0xc5, 0x7e, 0xdb, 0x47, 0xb9,
+ 0x1e, 0x7d, 0x42, 0xf5, 0x28, 0x2a, 0xb6, 0xd2, 0x73, 0xa3, 0xf3, 0x4a,
+ 0x7a, 0x8a, 0x78, 0x3f, 0x46, 0x39, 0x26, 0xe1, 0x1c, 0x47, 0xa2, 0xc0,
+ 0xb3, 0xfa, 0x51, 0x9a, 0xd5, 0xcd, 0xdc, 0x32, 0x8a, 0xe7, 0x03, 0x76,
+ 0xd7, 0xc0, 0xa0, 0x30, 0x8f, 0x52, 0x6d, 0x4e, 0x1c, 0xa0, 0xb9, 0x8b,
+ 0xbe, 0x37, 0xb4, 0x87, 0xba, 0xec, 0x75, 0x30, 0xdd, 0x85, 0xc2, 0x34,
+ 0x5e, 0x17, 0xa6, 0x5e, 0x23, 0x58, 0x27, 0x9f, 0x60, 0x91, 0xaf, 0x9b,
+ 0xe3, 0xb0, 0xfc, 0xef, 0x57, 0xd2, 0x1d, 0xfe, 0xf7, 0xd1, 0xf4, 0xc5,
+ 0xe7, 0x7b, 0x0b, 0x77, 0x07, 0xd5, 0xc6, 0x7c, 0x21, 0x83, 0x48, 0x33,
+ 0xd7, 0x8a, 0xa8, 0x38, 0xb0, 0x0b, 0x5a, 0xbd, 0xf3, 0x3e, 0xbe, 0x3e,
+ 0x04, 0x4d, 0x73, 0xa8, 0xd2, 0x12, 0x2f, 0xd4, 0x1b, 0xa4, 0xae, 0x13,
+ 0xdc, 0x0f, 0x74, 0xe5, 0x9e, 0x80, 0xd9, 0x53, 0x43, 0x34, 0x3e, 0x01,
+ 0xe3, 0x7a, 0x1f, 0x49, 0x1f, 0xe7, 0x2c, 0xce, 0xe3, 0x8c, 0x8a, 0xc1,
+ 0xd1, 0xa8, 0xd8, 0x4c, 0xb2, 0xb4, 0x3b, 0x27, 0x71, 0x85, 0xcf, 0xff,
+ 0x2b, 0xc4, 0x3f, 0xe7, 0x9c, 0x13, 0x94, 0x73, 0x18, 0xef, 0xd1, 0x34,
+ 0xe3, 0x1d, 0xa0, 0x3e, 0xf3, 0x7a, 0xdb, 0x4c, 0xf5, 0x84, 0xcc, 0x44,
+ 0x97, 0x30, 0x29, 0xa9, 0xb1, 0x3c, 0x5d, 0xfd, 0x33, 0xe0, 0xb9, 0xd8,
+ 0x97, 0xa9, 0xa7, 0x9e, 0x64, 0x1a, 0x22, 0x7a, 0x1f, 0xfa, 0xf4, 0x4e,
+ 0xce, 0xd1, 0x3b, 0xf1, 0x07, 0x64, 0x52, 0xdd, 0xfb, 0xc9, 0x1e, 0xdb,
+ 0x0a, 0xaf, 0xc8, 0xce, 0xd6, 0x8a, 0x4c, 0x83, 0x3e, 0x2f, 0x3f, 0x49,
+ 0x33, 0x2f, 0x51, 0x67, 0x86, 0xe6, 0x48, 0xa6, 0x6d, 0xae, 0x22, 0xba,
+ 0x44, 0xb3, 0xcb, 0x18, 0x10, 0x66, 0x3f, 0xe9, 0xad, 0x6f, 0xdc, 0xd7,
+ 0xdb, 0x4f, 0xd2, 0x5d, 0x3e, 0xce, 0x19, 0xea, 0x39, 0xbe, 0xe8, 0x93,
+ 0xec, 0x73, 0xd5, 0xbb, 0xca, 0x94, 0x78, 0x8a, 0x7a, 0x97, 0xa7, 0x8a,
+ 0xaa, 0xd8, 0x47, 0xf6, 0x1c, 0xa7, 0xb8, 0x19, 0xf4, 0xef, 0x1f, 0xa9,
+ 0x06, 0x96, 0xbe, 0xd7, 0x3c, 0x97, 0x6f, 0xc8, 0xae, 0x65, 0xb2, 0x6b,
+ 0x27, 0x65, 0x65, 0xee, 0xd9, 0xb8, 0xde, 0x1d, 0xa6, 0x7a, 0x27, 0xf0,
+ 0xa1, 0x9f, 0x63, 0x0f, 0xa3, 0xb3, 0xc8, 0x3d, 0xa1, 0x25, 0x96, 0xe7,
+ 0x8d, 0xdc, 0x7c, 0xc2, 0xfd, 0x7e, 0xa9, 0x92, 0x1f, 0xa9, 0x36, 0xba,
+ 0x21, 0xa7, 0x47, 0xbc, 0x50, 0xe4, 0x9f, 0x54, 0x4c, 0x62, 0xec, 0x5b,
+ 0xae, 0x68, 0xea, 0xf4, 0xd0, 0xde, 0xe9, 0x49, 0xd5, 0xb2, 0xca, 0xef,
+ 0x0b, 0xeb, 0x94, 0x15, 0x72, 0x6f, 0x9f, 0x8f, 0x4d, 0xb8, 0x6c, 0xb1,
+ 0x7b, 0x73, 0x02, 0xfe, 0x4c, 0x6c, 0x50, 0x4c, 0xa2, 0xb7, 0x3b, 0xd9,
+ 0x33, 0x2d, 0x92, 0xd4, 0x43, 0x25, 0xbd, 0x94, 0x48, 0xa6, 0x8e, 0xc3,
+ 0xd6, 0x8e, 0x14, 0x6d, 0xed, 0x8d, 0x62, 0xf5, 0x6e, 0x93, 0xe5, 0x62,
+ 0x5f, 0xe5, 0xf8, 0xb0, 0xdc, 0xfb, 0x29, 0x0f, 0xc1, 0xef, 0x43, 0xe4,
+ 0xa1, 0x46, 0x8a, 0xb1, 0x3b, 0x51, 0x4b, 0x4d, 0xb3, 0xdc, 0xde, 0x44,
+ 0xf3, 0xcf, 0x5d, 0x44, 0xbf, 0xdc, 0x9a, 0x03, 0xd7, 0x93, 0x47, 0xf8,
+ 0xc2, 0xb9, 0x85, 0x79, 0x7a, 0x33, 0x52, 0x91, 0x91, 0xca, 0x70, 0xe5,
+ 0xff, 0x17, 0xd2, 0x1a, 0x28, 0x06, 0xd7, 0x0d, 0x09, 0xea, 0xef, 0x2b,
+ 0xf1, 0xb8, 0x90, 0xef, 0x4e, 0xfd, 0x7b, 0xb3, 0x57, 0x64, 0xa5, 0xde,
+ 0x7f, 0xdc, 0xcc, 0x77, 0x51, 0x8a, 0x33, 0x1c, 0xfb, 0xed, 0xb3, 0x15,
+ 0xdd, 0xf2, 0x1c, 0x7f, 0xa8, 0xe4, 0x8a, 0x6b, 0xf3, 0xd8, 0x40, 0xbd,
+ 0x83, 0x1b, 0x26, 0x1c, 0xd7, 0x16, 0x7b, 0x49, 0x37, 0x96, 0x31, 0x48,
+ 0x44, 0xb7, 0xea, 0x5d, 0xfa, 0x38, 0xf5, 0x5a, 0x84, 0xcb, 0xa0, 0x7e,
+ 0x94, 0x62, 0x7c, 0x1e, 0x76, 0xcc, 0xc5, 0x54, 0xbd, 0xc3, 0x77, 0xbb,
+ 0x03, 0x62, 0xe1, 0x54, 0x25, 0xcd, 0x1f, 0x3a, 0x27, 0xdf, 0x69, 0xb9,
+ 0xfd, 0x26, 0x7e, 0x5f, 0x3f, 0x67, 0x93, 0x2b, 0x99, 0x26, 0xfd, 0x7e,
+ 0x76, 0x8e, 0x87, 0x3f, 0x74, 0xf6, 0x8e, 0xaf, 0xfe, 0xf6, 0x99, 0x59,
+ 0xe2, 0x93, 0x7b, 0x45, 0x78, 0x31, 0x87, 0xfb, 0xc4, 0x0b, 0xe7, 0x7c,
+ 0xe1, 0x52, 0xc2, 0xbd, 0x01, 0x37, 0xd2, 0x7c, 0xd4, 0x49, 0x73, 0x28,
+ 0xcd, 0x2e, 0x48, 0x0d, 0xb3, 0x3e, 0xce, 0x90, 0x3e, 0xd8, 0xe6, 0xa7,
+ 0xc8, 0xe6, 0x1d, 0x39, 0x8a, 0x99, 0xd4, 0x7a, 0x61, 0xf6, 0x92, 0xbf,
+ 0x51, 0xed, 0x32, 0x13, 0x1f, 0xc3, 0x34, 0xd6, 0xfa, 0x3e, 0x7d, 0x66,
+ 0xce, 0xa7, 0x4f, 0xb1, 0x4f, 0xa3, 0x6f, 0x38, 0x04, 0x25, 0xf3, 0x29,
+ 0xe9, 0x8c, 0xe2, 0x4d, 0x30, 0x4e, 0xce, 0x53, 0x67, 0x40, 0xfd, 0xb2,
+ 0x36, 0x9f, 0xf6, 0xc8, 0x42, 0x47, 0xe2, 0x28, 0xf5, 0xdb, 0xfb, 0xc0,
+ 0x25, 0xa3, 0xeb, 0xe8, 0x31, 0x61, 0x96, 0xdf, 0x0b, 0x71, 0x0e, 0x10,
+ 0x68, 0xcc, 0x54, 0xf0, 0x5d, 0x5e, 0x4c, 0x60, 0x47, 0xa9, 0x82, 0xf3,
+ 0x32, 0xf2, 0xe1, 0x31, 0xff, 0x7e, 0x41, 0x81, 0x96, 0x79, 0x9b, 0x6b,
+ 0x33, 0xc1, 0x25, 0x73, 0xf2, 0x7f, 0x67, 0xce, 0x06, 0x6f, 0xce, 0xe9,
+ 0x67, 0x4b, 0x8c, 0x6b, 0x8f, 0x96, 0xe1, 0x7c, 0x0d, 0xb1, 0x26, 0xff,
+ 0x67, 0x54, 0x03, 0x34, 0xea, 0x81, 0xfd, 0xbc, 0x8f, 0x5c, 0x11, 0x94,
+ 0xbf, 0xcb, 0xb5, 0x47, 0xec, 0xf0, 0x5c, 0xfe, 0xfa, 0x06, 0xad, 0xf5,
+ 0xd1, 0x87, 0x75, 0xc6, 0x77, 0x12, 0x37, 0xd1, 0xb3, 0xeb, 0xef, 0xeb,
+ 0xcf, 0xa3, 0xa7, 0x36, 0x4d, 0xfd, 0xad, 0xbf, 0xcf, 0xbf, 0xaf, 0xa0,
+ 0x3d, 0xcb, 0xf9, 0xdd, 0x08, 0xdf, 0xb5, 0xac, 0xce, 0x26, 0x8d, 0xcd,
+ 0x60, 0x3a, 0x06, 0xd6, 0x14, 0x0d, 0xdc, 0x4a, 0x75, 0x61, 0xcc, 0xbf,
+ 0x07, 0x3d, 0x3f, 0xf7, 0x28, 0xb4, 0x6f, 0x19, 0xed, 0x1b, 0xf4, 0xd7,
+ 0x0c, 0x2c, 0x2f, 0x9e, 0x9f, 0xe9, 0x54, 0x3a, 0x77, 0xe8, 0xdc, 0x1c,
+ 0xcb, 0x76, 0x70, 0xc5, 0xce, 0x7c, 0xaf, 0x18, 0xc9, 0x47, 0x89, 0x96,
+ 0x42, 0x19, 0x40, 0xa2, 0x23, 0x73, 0x33, 0xe5, 0x5d, 0x2b, 0xa5, 0x2a,
+ 0x4d, 0x58, 0x9b, 0x22, 0x3f, 0xd6, 0x97, 0xe2, 0x8e, 0x54, 0x0d, 0xf5,
+ 0x34, 0xc3, 0xb8, 0x4d, 0xaf, 0x45, 0x7f, 0xea, 0x52, 0xe0, 0xc6, 0x3a,
+ 0xea, 0x41, 0x06, 0xfc, 0x9e, 0xbe, 0x86, 0xe8, 0xd5, 0x59, 0x4f, 0xe1,
+ 0xf6, 0x73, 0xff, 0xae, 0x42, 0x34, 0x7e, 0xef, 0x3c, 0x77, 0x33, 0xdc,
+ 0xe6, 0x1e, 0xaa, 0x83, 0xdd, 0x58, 0x97, 0x0a, 0x53, 0x6f, 0xcd, 0xf9,
+ 0x61, 0x3e, 0x22, 0xd6, 0x67, 0x72, 0xfd, 0xb9, 0x3e, 0x67, 0x46, 0xcc,
+ 0x90, 0x5c, 0xa8, 0xf5, 0xc4, 0x73, 0x34, 0xbf, 0x65, 0x4a, 0x7c, 0x1f,
+ 0xa5, 0x20, 0x66, 0xf1, 0xcc, 0x48, 0xc3, 0x1f, 0xcd, 0x59, 0xe9, 0xc7,
+ 0xeb, 0x71, 0xd5, 0xbe, 0x06, 0x64, 0xf6, 0xe9, 0xb0, 0x1f, 0xb7, 0x68,
+ 0x2d, 0x45, 0x9f, 0x19, 0xb1, 0xb7, 0xf8, 0x87, 0x68, 0x77, 0x60, 0x8d,
+ 0xfe, 0x3f, 0x95, 0x7d, 0x0b, 0x70, 0x54, 0xe7, 0x95, 0xe6, 0x77, 0xfb,
+ 0x21, 0xb5, 0x9e, 0x5c, 0x09, 0x09, 0x5a, 0x20, 0x9b, 0x6e, 0xf7, 0x6d,
+ 0xa9, 0x8d, 0x3a, 0xe1, 0x36, 0x88, 0xb5, 0x9c, 0xed, 0x2d, 0x1a, 0x2c,
+ 0x8c, 0x08, 0x60, 0xcb, 0xb6, 0x3c, 0x83, 0x77, 0x32, 0x6b, 0xc5, 0x36,
+ 0x18, 0x3f, 0x92, 0x91, 0x09, 0x5b, 0x25, 0x53, 0x53, 0xd1, 0x1d, 0x01,
+ 0x42, 0x40, 0xbf, 0x24, 0xc1, 0x00, 0x33, 0x53, 0xe3, 0x46, 0x0f, 0x20,
+ 0xb8, 0x5b, 0xc2, 0x71, 0x66, 0x4a, 0xc9, 0xd4, 0x56, 0x34, 0x20, 0x0c,
+ 0x04, 0x63, 0x3c, 0x93, 0x99, 0x29, 0xb2, 0xeb, 0x2d, 0x13, 0x1c, 0xc0,
+ 0x0f, 0xfc, 0x4c, 0xb2, 0x16, 0xf1, 0xc4, 0x77, 0xbf, 0x73, 0xbb, 0x1b,
+ 0x04, 0x45, 0x3c, 0x35, 0x54, 0x75, 0xb5, 0x6e, 0xdf, 0xff, 0xfe, 0x8f,
+ 0xf3, 0x9f, 0xf3, 0x9d, 0xef, 0x9c, 0xf3, 0xdf, 0xa2, 0x84, 0xfe, 0xfb,
+ 0xdf, 0xcc, 0x75, 0x8c, 0x4f, 0xdc, 0x0b, 0x69, 0x66, 0xb3, 0x65, 0xbc,
+ 0x0b, 0x5f, 0x0e, 0x24, 0x9c, 0xe8, 0xea, 0x77, 0xe0, 0xda, 0xa2, 0x73,
+ 0xa6, 0x67, 0xf6, 0x8d, 0xfc, 0x4e, 0xc4, 0xe6, 0xc4, 0x33, 0xfd, 0xf2,
+ 0xed, 0x40, 0x60, 0x71, 0x36, 0xe7, 0xba, 0x61, 0xd0, 0x89, 0xa7, 0xd9,
+ 0xf6, 0xa2, 0x6e, 0xcb, 0xed, 0xb1, 0x55, 0x1b, 0xc0, 0x73, 0xfd, 0x8c,
+ 0x6d, 0x34, 0x13, 0xcf, 0x86, 0x8a, 0x71, 0x7f, 0x75, 0x76, 0x1d, 0xc3,
+ 0x5c, 0x87, 0xe1, 0x30, 0x94, 0x4c, 0xa3, 0x13, 0xe5, 0x9c, 0x3f, 0xb9,
+ 0x18, 0x7e, 0x98, 0x29, 0xc1, 0xe8, 0x81, 0x71, 0x25, 0x9d, 0xce, 0xb6,
+ 0x19, 0xb2, 0x62, 0x5a, 0x43, 0x19, 0x6b, 0xb4, 0x61, 0x26, 0xfd, 0xfb,
+ 0x85, 0x8c, 0x03, 0x9f, 0x65, 0x5c, 0xf8, 0x74, 0xa4, 0x18, 0xbf, 0x3e,
+ 0x50, 0xc2, 0x8f, 0x8a, 0x4f, 0x46, 0x34, 0xfe, 0xde, 0xac, 0xbc, 0x12,
+ 0x95, 0xd8, 0x23, 0x80, 0x4f, 0x33, 0xe3, 0xca, 0xd1, 0xaf, 0x5c, 0x6b,
+ 0xc6, 0xfc, 0x8e, 0x6a, 0x70, 0xcc, 0xbf, 0x36, 0xbf, 0x3b, 0x4d, 0xae,
+ 0xd3, 0xc7, 0xaa, 0xd4, 0x4a, 0xf0, 0xd9, 0x01, 0x19, 0x47, 0xfa, 0x6f,
+ 0x56, 0x5e, 0x8d, 0x8a, 0x7c, 0x2b, 0xf1, 0xeb, 0x11, 0x91, 0xe3, 0x27,
+ 0xd4, 0x69, 0xe9, 0x7f, 0x5c, 0x39, 0x9e, 0x7b, 0xe6, 0xe7, 0xdc, 0x8b,
+ 0x8d, 0xa3, 0x0e, 0x90, 0x4c, 0xf0, 0x59, 0x17, 0x5e, 0x38, 0x68, 0x23,
+ 0x27, 0x2e, 0xc6, 0xc6, 0xc1, 0x12, 0xbc, 0x30, 0xa8, 0xa2, 0xe3, 0x60,
+ 0xb3, 0x42, 0xbe, 0xaf, 0xce, 0x20, 0xef, 0xed, 0x18, 0x0d, 0xb0, 0xdd,
+ 0xb8, 0x72, 0x2e, 0xdd, 0x30, 0x33, 0xdb, 0x4f, 0x36, 0xf7, 0x93, 0xe5,
+ 0x31, 0x86, 0xc2, 0x38, 0x8d, 0x5c, 0x72, 0xdf, 0xe6, 0xd7, 0x18, 0x21,
+ 0x3e, 0x9c, 0xb6, 0x53, 0xc7, 0x24, 0x1e, 0x15, 0xbb, 0x4f, 0x6d, 0xbe,
+ 0x12, 0x95, 0xb9, 0x1a, 0xca, 0x91, 0x46, 0x9b, 0xc5, 0xb1, 0x5f, 0x67,
+ 0x5c, 0xb8, 0x82, 0xb6, 0xf2, 0x10, 0xe5, 0xb1, 0x9a, 0xf2, 0x68, 0xa6,
+ 0x3c, 0x5a, 0x39, 0xdf, 0x97, 0xa3, 0x82, 0x93, 0xde, 0x40, 0x44, 0xd1,
+ 0xb0, 0x2a, 0x23, 0x7d, 0x58, 0xe3, 0xb8, 0x1c, 0xe1, 0xbf, 0xd9, 0xbc,
+ 0x35, 0x7a, 0xab, 0x5c, 0xa0, 0x96, 0x87, 0xc5, 0xaf, 0x89, 0x6c, 0x02,
+ 0xe4, 0x50, 0xe3, 0xca, 0xa8, 0x15, 0x23, 0xef, 0xdb, 0xec, 0x49, 0xe5,
+ 0x6d, 0xa7, 0x44, 0xec, 0x53, 0xf2, 0xe1, 0xca, 0x3e, 0x72, 0xb5, 0x1a,
+ 0x2d, 0x7b, 0xff, 0xde, 0x94, 0x7c, 0xa7, 0x36, 0x2f, 0xb4, 0xf0, 0xe6,
+ 0x6f, 0x36, 0x37, 0x5d, 0x5f, 0xd3, 0xb8, 0xf2, 0x36, 0xd7, 0x73, 0x81,
+ 0x7a, 0x7a, 0x92, 0x73, 0x2d, 0x92, 0xbd, 0x4b, 0x73, 0xef, 0x38, 0xd7,
+ 0x4f, 0x87, 0x8b, 0xf1, 0x5e, 0xaa, 0x84, 0x1f, 0xca, 0x76, 0x98, 0x7b,
+ 0x97, 0x6e, 0x56, 0x4e, 0x59, 0xf2, 0x0d, 0xe0, 0x5d, 0x8e, 0x7d, 0xec,
+ 0x7a, 0x1f, 0x59, 0xde, 0x96, 0xad, 0xc3, 0xe5, 0xed, 0x57, 0xf0, 0x54,
+ 0xd6, 0x66, 0x28, 0x91, 0xeb, 0xb5, 0x34, 0xc9, 0x8b, 0x49, 0x7d, 0x91,
+ 0x3e, 0x46, 0x95, 0xfc, 0xa8, 0x42, 0x8c, 0xa1, 0xfe, 0xa9, 0xcb, 0x3c,
+ 0x0e, 0xe2, 0xe2, 0x3a, 0x7c, 0xc1, 0x38, 0x21, 0x42, 0x8b, 0x92, 0xb5,
+ 0x48, 0x8e, 0xb4, 0x50, 0x62, 0x42, 0xeb, 0xdf, 0x20, 0xb9, 0xd4, 0x6b,
+ 0xe4, 0xb9, 0x54, 0x21, 0x74, 0xa7, 0xbf, 0x30, 0x27, 0xaa, 0xe8, 0x57,
+ 0xb5, 0xeb, 0x79, 0x37, 0xae, 0xd9, 0x34, 0x87, 0x78, 0xaf, 0x27, 0x8d,
+ 0xdc, 0x3f, 0x72, 0x2f, 0xf2, 0xdd, 0x27, 0xb5, 0xdf, 0x99, 0x4f, 0xdc,
+ 0xd4, 0x36, 0x8f, 0xe5, 0xf9, 0x78, 0x5f, 0xb0, 0xbc, 0x14, 0x3d, 0xbb,
+ 0xbd, 0xc9, 0x14, 0xaa, 0x90, 0xd4, 0x6c, 0x73, 0x0b, 0x38, 0x3b, 0x3b,
+ 0xbc, 0xbd, 0xcd, 0xb0, 0xf2, 0x20, 0x9e, 0x14, 0xfe, 0x61, 0xa6, 0xd8,
+ 0x8c, 0x53, 0x6b, 0xf0, 0x54, 0xd8, 0x2a, 0x65, 0xee, 0xd6, 0xac, 0xec,
+ 0xfd, 0x45, 0x58, 0x17, 0x2c, 0x42, 0xaa, 0x95, 0x18, 0xd7, 0x6f, 0xb4,
+ 0xb0, 0x7b, 0xf2, 0xa7, 0xc0, 0x8b, 0xdf, 0xf4, 0x0b, 0x1f, 0x03, 0x0a,
+ 0x63, 0x1c, 0x13, 0x39, 0x0c, 0xec, 0xf7, 0x1a, 0x36, 0x9b, 0x3c, 0xff,
+ 0x99, 0x69, 0xb4, 0xc9, 0xb3, 0xd2, 0x47, 0xad, 0xc5, 0x1b, 0x6f, 0xd6,
+ 0x7b, 0x0f, 0xe5, 0xf4, 0xaf, 0x33, 0x25, 0xe7, 0xa8, 0xd6, 0x31, 0xee,
+ 0xe9, 0x97, 0x9a, 0x4d, 0x04, 0xbb, 0xaa, 0x7d, 0x1d, 0xba, 0xad, 0x18,
+ 0x67, 0xbf, 0xf6, 0xdf, 0x88, 0xe9, 0x05, 0x70, 0xd5, 0x01, 0xf7, 0xc5,
+ 0x6d, 0xb0, 0xd5, 0x11, 0xab, 0xa9, 0xd3, 0xcd, 0xa3, 0x36, 0xcc, 0xeb,
+ 0x57, 0xf0, 0x58, 0xd2, 0x86, 0x07, 0x92, 0x76, 0xac, 0x4a, 0xe2, 0xfb,
+ 0xf3, 0x80, 0xc9, 0x1a, 0xf8, 0xdb, 0xa7, 0xe8, 0x9a, 0xcb, 0xe1, 0x6f,
+ 0x8d, 0x91, 0x17, 0xac, 0x62, 0x2c, 0xba, 0x72, 0x94, 0x38, 0xc8, 0xb6,
+ 0xce, 0x3e, 0xea, 0x66, 0x9f, 0x1d, 0x35, 0x7d, 0xb8, 0xb3, 0x10, 0xa0,
+ 0x75, 0xfb, 0xa7, 0xe8, 0x97, 0x2a, 0x1d, 0xf0, 0xd3, 0xaf, 0xf8, 0x3b,
+ 0x6b, 0xec, 0x0c, 0xc4, 0xea, 0xfe, 0xd5, 0xe2, 0xb4, 0x0f, 0xd2, 0x5e,
+ 0xe6, 0xf5, 0xb3, 0x7d, 0x9d, 0x0d, 0x2a, 0xf5, 0xf9, 0x93, 0x3f, 0x96,
+ 0x7c, 0xaf, 0xdc, 0x93, 0xba, 0xab, 0x82, 0xf2, 0x7e, 0x3b, 0xf1, 0xf0,
+ 0x8c, 0x79, 0xb6, 0xda, 0xaa, 0x41, 0xe1, 0x31, 0xce, 0xcd, 0xcd, 0xdf,
+ 0xd4, 0x3a, 0x17, 0x16, 0xdc, 0xa3, 0x62, 0xed, 0xa0, 0xb4, 0x85, 0xd5,
+ 0x8f, 0x93, 0xb8, 0x53, 0xa0, 0x4d, 0x98, 0x07, 0xab, 0xa4, 0xad, 0x8d,
+ 0x6b, 0xb4, 0xa3, 0xa4, 0x1f, 0x58, 0x19, 0xc7, 0xc3, 0xa5, 0xf0, 0x47,
+ 0x64, 0x8e, 0xf5, 0x8b, 0x1d, 0x7c, 0xb6, 0x14, 0x2d, 0xa3, 0xd9, 0xe7,
+ 0x56, 0x8c, 0xbe, 0x37, 0x33, 0x9b, 0xfb, 0xfe, 0xc3, 0x75, 0xe3, 0x2d,
+ 0x8d, 0x7e, 0xac, 0x4b, 0x52, 0xe7, 0x6c, 0x1e, 0x0c, 0xe6, 0x72, 0xd0,
+ 0x4f, 0xa4, 0xbc, 0xd3, 0xea, 0xba, 0x7f, 0x5b, 0x9a, 0xab, 0xf9, 0xd2,
+ 0x8e, 0xa7, 0xd8, 0x8f, 0x65, 0xc3, 0x18, 0x1c, 0x33, 0x11, 0xd5, 0x4d,
+ 0x64, 0xf8, 0x79, 0x43, 0x87, 0x51, 0x42, 0x1b, 0x7f, 0x2a, 0x26, 0x98,
+ 0x97, 0xd5, 0xa4, 0x1f, 0x24, 0x02, 0xca, 0x86, 0x18, 0x70, 0x84, 0xf1,
+ 0xe3, 0x21, 0x7e, 0x86, 0x13, 0x5c, 0x03, 0xe7, 0x6d, 0x23, 0x6e, 0x6c,
+ 0x4b, 0x01, 0x43, 0x09, 0x44, 0xf6, 0x2f, 0x96, 0x58, 0xa6, 0x84, 0xe3,
+ 0x01, 0xe3, 0x6c, 0x93, 0xe6, 0xe7, 0x20, 0x3f, 0x63, 0xdc, 0x53, 0x8e,
+ 0x87, 0x00, 0xf1, 0x30, 0x92, 0xd1, 0x60, 0x64, 0x02, 0x98, 0xa0, 0x6d,
+ 0x5d, 0x1b, 0x56, 0x51, 0x76, 0xa8, 0x12, 0x1f, 0x8d, 0x64, 0x63, 0xa5,
+ 0x75, 0x19, 0xa9, 0x5d, 0xcb, 0xda, 0xa4, 0x7e, 0x2d, 0xb6, 0x54, 0x84,
+ 0x43, 0xc9, 0x4a, 0xab, 0x86, 0xfd, 0x8e, 0xce, 0x7e, 0x55, 0xa9, 0xb1,
+ 0xb6, 0xe2, 0x70, 0xd4, 0xe7, 0xe9, 0xa5, 0xbe, 0x1b, 0x0e, 0xb1, 0xaf,
+ 0x46, 0x1c, 0x89, 0xe6, 0x6b, 0x67, 0xbe, 0x96, 0x9f, 0x49, 0x8e, 0xc8,
+ 0x59, 0x49, 0xd9, 0xca, 0xbd, 0xbc, 0xdf, 0x95, 0xf5, 0x4a, 0x0e, 0x3f,
+ 0xcf, 0x71, 0xa6, 0xff, 0x7e, 0x8a, 0xe3, 0x05, 0x69, 0x07, 0xde, 0xde,
+ 0x14, 0x74, 0xcb, 0x97, 0x8e, 0xd4, 0x7b, 0x93, 0x06, 0x64, 0x6f, 0x1b,
+ 0x39, 0x87, 0xd7, 0xa8, 0xf7, 0x01, 0xca, 0xf9, 0x2f, 0xe8, 0x23, 0x5c,
+ 0x8c, 0x65, 0x2b, 0xb0, 0xab, 0xaf, 0x12, 0x3b, 0xfb, 0x0c, 0xf4, 0x2c,
+ 0x6e, 0xc3, 0xa9, 0xa8, 0x89, 0x75, 0x21, 0x13, 0x2b, 0x19, 0x23, 0xfc,
+ 0x00, 0x0d, 0x4d, 0x87, 0xf1, 0x20, 0x63, 0x65, 0x95, 0xf2, 0xf8, 0x16,
+ 0xde, 0xde, 0xed, 0xc0, 0x7a, 0xfd, 0x8f, 0x68, 0xbf, 0xa6, 0xf9, 0xab,
+ 0x45, 0xb5, 0x18, 0x4c, 0x34, 0xa8, 0xdd, 0x9c, 0x5f, 0xa4, 0x8d, 0xfb,
+ 0x14, 0x74, 0xe0, 0x69, 0xfd, 0xfb, 0x6c, 0xeb, 0xb6, 0x39, 0x34, 0xb9,
+ 0x96, 0xba, 0x96, 0xec, 0xa3, 0x41, 0xdd, 0xca, 0xfb, 0xac, 0x6c, 0xad,
+ 0x74, 0x7d, 0xa3, 0xe4, 0x44, 0x4a, 0x71, 0x92, 0x32, 0x3b, 0x96, 0x8c,
+ 0xd0, 0x55, 0x43, 0x79, 0xba, 0xb1, 0x0b, 0x8f, 0x93, 0x9b, 0xbc, 0x4d,
+ 0xd2, 0x70, 0x6f, 0x5c, 0x41, 0x53, 0xbd, 0x8e, 0xf3, 0xe9, 0x6f, 0xe1,
+ 0xcd, 0xe1, 0x30, 0xde, 0x20, 0x07, 0x58, 0xf0, 0x97, 0xc2, 0xe9, 0x3d,
+ 0x38, 0x9b, 0x0e, 0xe3, 0x4c, 0xd4, 0xdb, 0xfa, 0xbc, 0x52, 0x8b, 0x9f,
+ 0x11, 0xd3, 0xee, 0x8e, 0x03, 0xef, 0xb1, 0x1f, 0x7f, 0xdc, 0x81, 0x4b,
+ 0x69, 0x15, 0x87, 0xb9, 0x37, 0x8e, 0xd0, 0x02, 0x18, 0x6d, 0x1e, 0x1c,
+ 0x1c, 0x78, 0x00, 0x13, 0xa9, 0x07, 0x70, 0x22, 0xf9, 0xb6, 0xe9, 0xd2,
+ 0xa4, 0x06, 0xe6, 0xc2, 0x25, 0x62, 0xea, 0x24, 0xa5, 0x51, 0x7a, 0x4f,
+ 0x2b, 0x71, 0x51, 0x33, 0x44, 0xee, 0x6f, 0xf2, 0xb7, 0x7b, 0xe3, 0x4d,
+ 0xd8, 0x9f, 0xa1, 0x48, 0x13, 0x3a, 0x12, 0x31, 0x19, 0xab, 0x11, 0x31,
+ 0x72, 0xc8, 0x5d, 0x7d, 0xe2, 0x37, 0xef, 0xc6, 0xca, 0x0a, 0x28, 0x2d,
+ 0x75, 0x63, 0xb9, 0x75, 0x34, 0x4d, 0xab, 0x6d, 0x4a, 0xbc, 0x49, 0xb9,
+ 0xf2, 0xb9, 0x1f, 0x26, 0x28, 0xf7, 0x04, 0x65, 0x7b, 0x7d, 0x3f, 0x9a,
+ 0xb8, 0x1f, 0xdf, 0xc2, 0xf9, 0xdd, 0x6d, 0x78, 0x93, 0x58, 0x57, 0xbe,
+ 0xc8, 0xd7, 0xe9, 0xb4, 0x35, 0xb0, 0xef, 0xb4, 0x99, 0xaa, 0x16, 0x99,
+ 0xb6, 0xe1, 0x17, 0x51, 0x91, 0x69, 0x9a, 0xd8, 0xe7, 0xf3, 0xf8, 0xed,
+ 0x23, 0x55, 0xd4, 0x65, 0x5b, 0x77, 0x30, 0x5b, 0xaf, 0x2b, 0xbd, 0xc7,
+ 0x85, 0xcb, 0xd6, 0xdc, 0x64, 0xae, 0x5f, 0x35, 0xbf, 0x5f, 0x98, 0x2b,
+ 0xab, 0x65, 0x7e, 0x86, 0xc9, 0x98, 0x3a, 0xc0, 0x78, 0x91, 0xb6, 0x13,
+ 0x80, 0xe4, 0x9c, 0xeb, 0xe3, 0x5d, 0xb0, 0x87, 0x4a, 0x0d, 0x35, 0xec,
+ 0x9d, 0xea, 0xc0, 0x9b, 0xb8, 0x42, 0x8e, 0x72, 0x57, 0x5c, 0x63, 0x7c,
+ 0x7b, 0x81, 0x63, 0xfd, 0x0b, 0x2e, 0xf2, 0xda, 0x17, 0xcf, 0xda, 0x5a,
+ 0x77, 0x63, 0x1b, 0xee, 0x4b, 0xcb, 0xfa, 0xfe, 0x0b, 0x07, 0xd2, 0x11,
+ 0x49, 0xcb, 0x3a, 0x63, 0xb4, 0x0b, 0x59, 0x67, 0xe5, 0x7f, 0xb0, 0xce,
+ 0x23, 0xec, 0xaf, 0x96, 0x76, 0x94, 0xf7, 0x1b, 0x65, 0x38, 0x98, 0x54,
+ 0x71, 0x52, 0x2f, 0xc5, 0x05, 0x55, 0xf2, 0xf5, 0xd9, 0x5a, 0x66, 0x33,
+ 0xe3, 0xd3, 0x21, 0x7e, 0x9e, 0x62, 0x0c, 0x75, 0x5a, 0x77, 0xe0, 0x84,
+ 0x5e, 0x4b, 0x9c, 0xbf, 0x55, 0x87, 0xe5, 0x1e, 0x03, 0x83, 0x8a, 0x4a,
+ 0x9c, 0x91, 0x9c, 0xaa, 0x75, 0x5f, 0xce, 0x16, 0xb8, 0x20, 0x39, 0x8d,
+ 0x82, 0xd8, 0x6f, 0xcd, 0xcb, 0x16, 0xce, 0xdc, 0x3a, 0xbf, 0x5b, 0xfb,
+ 0x21, 0x55, 0xd0, 0xde, 0x33, 0x9f, 0xad, 0xce, 0xf9, 0x2d, 0x65, 0x47,
+ 0x55, 0x16, 0x2b, 0xc4, 0x87, 0x8d, 0xe7, 0x71, 0x83, 0x7c, 0x7c, 0xdf,
+ 0xa3, 0xf4, 0x41, 0xf4, 0xcf, 0xcd, 0xdf, 0xdb, 0xaa, 0x49, 0x9c, 0x97,
+ 0x7a, 0x74, 0x99, 0x56, 0x00, 0xbb, 0xe5, 0x67, 0x0f, 0x6f, 0xce, 0xf2,
+ 0xf9, 0xf4, 0xe6, 0x6c, 0x8c, 0x7a, 0x74, 0xf3, 0x5d, 0xd6, 0xf7, 0x8f,
+ 0x36, 0xfb, 0x52, 0x37, 0x7c, 0x55, 0x96, 0x2f, 0x5b, 0x67, 0x6d, 0xd0,
+ 0xab, 0x1b, 0xca, 0x8a, 0x46, 0xf1, 0xd7, 0x79, 0x8e, 0x22, 0x6d, 0x02,
+ 0xca, 0x89, 0xa8, 0x61, 0xba, 0xb5, 0x62, 0xfa, 0x7a, 0x28, 0x63, 0x8c,
+ 0xc5, 0xa6, 0xac, 0xba, 0xa7, 0x86, 0x37, 0xd2, 0x12, 0x13, 0x83, 0xfa,
+ 0xfb, 0xbf, 0xb1, 0x6b, 0x37, 0xda, 0x8b, 0x16, 0x93, 0xb3, 0xd3, 0xcf,
+ 0x3d, 0x1b, 0x72, 0xe0, 0xfd, 0x74, 0x76, 0x3d, 0xef, 0x0d, 0x97, 0xe0,
+ 0xdd, 0x94, 0xf8, 0x6b, 0xa8, 0x85, 0xec, 0xf7, 0x64, 0x5a, 0x63, 0x6c,
+ 0x2a, 0xe3, 0xb6, 0x61, 0xdb, 0x98, 0x03, 0xfb, 0xa3, 0x1a, 0x62, 0x89,
+ 0x9f, 0x9a, 0x45, 0x9a, 0x6f, 0xc2, 0x6f, 0x77, 0x60, 0x5f, 0x7a, 0x12,
+ 0x63, 0x7d, 0x1f, 0x9b, 0x76, 0xad, 0x0b, 0x1f, 0x85, 0x26, 0xc9, 0xeb,
+ 0xa4, 0xfe, 0xa9, 0x63, 0xd7, 0x80, 0xc6, 0x58, 0xda, 0x86, 0x9d, 0x8b,
+ 0x5b, 0xb0, 0x6b, 0xac, 0x19, 0xc6, 0x21, 0x0f, 0x76, 0x92, 0xf0, 0x4d,
+ 0x0c, 0x4f, 0xe2, 0x54, 0x52, 0x6b, 0x2a, 0x52, 0x26, 0x71, 0x92, 0xe3,
+ 0x6c, 0x4d, 0xbc, 0x05, 0x83, 0x7d, 0x6c, 0x4b, 0x4a, 0x8e, 0x57, 0xc6,
+ 0x99, 0x44, 0x77, 0xea, 0x76, 0x35, 0x8f, 0x36, 0xec, 0x48, 0x6c, 0x69,
+ 0xcf, 0xd6, 0x3d, 0x88, 0xab, 0x69, 0x4d, 0xe9, 0xe5, 0x1e, 0x1d, 0x4e,
+ 0xe7, 0x6b, 0x20, 0x82, 0xa1, 0x59, 0x3c, 0xdc, 0x96, 0xd6, 0xd1, 0x3b,
+ 0xd0, 0xc2, 0xf6, 0x1a, 0xba, 0x13, 0x52, 0x3f, 0xf6, 0x71, 0x3c, 0x13,
+ 0xef, 0xe9, 0x5e, 0xf7, 0x5d, 0xfc, 0x1e, 0xd1, 0x3b, 0xb1, 0x81, 0xfd,
+ 0x08, 0xe7, 0xd2, 0x14, 0x6f, 0x93, 0x01, 0x3b, 0x7e, 0xa5, 0xdb, 0x61,
+ 0x54, 0xd9, 0x71, 0x44, 0x2f, 0x23, 0x3f, 0xb7, 0xa3, 0x21, 0x44, 0xdf,
+ 0x9c, 0xf3, 0xd5, 0x1f, 0x26, 0x15, 0x3c, 0x40, 0x2c, 0x3d, 0x16, 0x6a,
+ 0x68, 0x5f, 0x2e, 0x6c, 0xf7, 0x80, 0x82, 0x2b, 0xda, 0x35, 0xd3, 0xa0,
+ 0xbf, 0x72, 0xf9, 0xf3, 0x7b, 0xf3, 0x6b, 0x33, 0x5b, 0x03, 0xfe, 0xc2,
+ 0xcc, 0x3f, 0x37, 0xc5, 0xf9, 0x3d, 0xc6, 0xe7, 0xee, 0x5a, 0xd4, 0xd0,
+ 0x29, 0xcf, 0xb9, 0x89, 0xe3, 0xf2, 0x9c, 0xe4, 0xf6, 0x6f, 0x3c, 0xa7,
+ 0x63, 0xdb, 0x40, 0xc4, 0x9a, 0xef, 0xf6, 0x04, 0x16, 0x3a, 0x20, 0x76,
+ 0xd4, 0xa0, 0x5e, 0x02, 0xba, 0x26, 0xf5, 0x19, 0xe4, 0x37, 0xfe, 0xc0,
+ 0x53, 0x10, 0x39, 0x49, 0xbc, 0xf9, 0x16, 0x76, 0x46, 0x87, 0xc1, 0x98,
+ 0x93, 0xf8, 0xe6, 0x5f, 0x3b, 0x84, 0x14, 0x9e, 0x4b, 0xa7, 0xf0, 0xbc,
+ 0x70, 0x6c, 0x2b, 0xc7, 0x96, 0xc6, 0x77, 0xa2, 0x6f, 0x21, 0x66, 0xc5,
+ 0x55, 0x87, 0xf1, 0x44, 0xf4, 0xdd, 0x6a, 0xc9, 0x65, 0x6e, 0x4d, 0x2c,
+ 0x65, 0xff, 0x22, 0x53, 0x6f, 0xab, 0x81, 0x2f, 0xd9, 0xff, 0x52, 0x6c,
+ 0x19, 0x92, 0x9c, 0x90, 0x89, 0xd7, 0xc9, 0xa9, 0xae, 0x50, 0x8f, 0x5a,
+ 0x1a, 0xa5, 0xff, 0x71, 0x45, 0xb3, 0x7c, 0x57, 0x1b, 0xf7, 0x78, 0x16,
+ 0xdc, 0x94, 0x73, 0x59, 0x46, 0x53, 0xee, 0x8a, 0xc9, 0x9e, 0x3b, 0x60,
+ 0xcb, 0x78, 0xf0, 0x18, 0x79, 0x49, 0xe1, 0xc8, 0x8f, 0x14, 0xf1, 0x5f,
+ 0x35, 0xe4, 0xa2, 0xee, 0x03, 0x1e, 0x65, 0xc1, 0x1e, 0x17, 0x1e, 0x88,
+ 0x91, 0xa3, 0xc6, 0x9a, 0xb1, 0x65, 0xaf, 0xc6, 0x36, 0x5e, 0xfd, 0x1c,
+ 0xe3, 0xd6, 0x93, 0xf0, 0x79, 0x86, 0xc8, 0xa5, 0xdc, 0xc4, 0x60, 0xc7,
+ 0x48, 0x39, 0x4a, 0xc8, 0xb3, 0xa5, 0xdc, 0x5c, 0x3a, 0xe2, 0x46, 0x0d,
+ 0xfd, 0x99, 0x3b, 0x73, 0x1e, 0x63, 0x7b, 0xa0, 0x96, 0x84, 0x3f, 0x37,
+ 0x0b, 0x35, 0xa9, 0x57, 0x06, 0x50, 0x9e, 0xd9, 0x84, 0x74, 0x2c, 0x88,
+ 0x52, 0xf2, 0xfb, 0x06, 0x8e, 0x77, 0x7f, 0x4c, 0x63, 0x3f, 0x59, 0x6e,
+ 0xb3, 0x9c, 0xcf, 0xf4, 0x26, 0xbc, 0x6b, 0xa5, 0xde, 0x78, 0x45, 0x7f,
+ 0x0d, 0x45, 0x7d, 0x37, 0xce, 0x9c, 0x69, 0x21, 0xcc, 0x21, 0xf7, 0x68,
+ 0x7d, 0x1a, 0xd9, 0xf3, 0x67, 0x2b, 0x72, 0xeb, 0x09, 0xca, 0x7a, 0x9c,
+ 0x6d, 0xd4, 0x83, 0xd9, 0x98, 0xc1, 0xf5, 0x5c, 0xa4, 0xde, 0xdc, 0xcb,
+ 0xb9, 0x5e, 0x63, 0xec, 0xd0, 0xc9, 0xb5, 0xbc, 0x3f, 0xfc, 0x23, 0xa5,
+ 0x86, 0x6b, 0x99, 0x22, 0x57, 0xfd, 0x38, 0xe5, 0x51, 0x7c, 0x5c, 0xcb,
+ 0x77, 0x79, 0xff, 0x3b, 0x5c, 0xcb, 0xd6, 0xbd, 0xde, 0xd6, 0xe3, 0x8a,
+ 0xb7, 0x7d, 0x8d, 0xe2, 0x53, 0xb7, 0x2a, 0xa5, 0xb8, 0x38, 0x5c, 0x8e,
+ 0x4b, 0xf4, 0xbd, 0xd7, 0x86, 0x2b, 0x71, 0x79, 0xb8, 0x8a, 0x36, 0xa2,
+ 0xb1, 0x0f, 0xd3, 0x2c, 0xd3, 0xdc, 0x98, 0x4a, 0x3f, 0x8f, 0x19, 0xb1,
+ 0x5a, 0x7c, 0x9c, 0xde, 0x80, 0xf2, 0x98, 0xc4, 0x00, 0x1e, 0x7c, 0xc4,
+ 0xfb, 0x1f, 0xa6, 0x47, 0x51, 0xbc, 0xe7, 0x73, 0xb6, 0x31, 0xcd, 0xfb,
+ 0xb9, 0xbe, 0xcb, 0xe9, 0x0e, 0x94, 0xee, 0xd9, 0x08, 0xc7, 0x1e, 0xb3,
+ 0x6b, 0x4b, 0x08, 0x3f, 0xb3, 0x73, 0x2d, 0xdd, 0xba, 0x77, 0xe2, 0x2e,
+ 0x7b, 0x90, 0x7d, 0x8c, 0x2b, 0x0b, 0x32, 0x1b, 0x51, 0xbe, 0xc7, 0x83,
+ 0x67, 0x29, 0xc3, 0x51, 0x68, 0x81, 0x35, 0xca, 0x46, 0x14, 0x8c, 0x64,
+ 0xd7, 0xbf, 0x2e, 0x93, 0xb5, 0x8b, 0xfb, 0x1b, 0xa7, 0xc7, 0x32, 0x6e,
+ 0x8b, 0x77, 0x4f, 0xa6, 0x4b, 0x70, 0x3a, 0x25, 0xf2, 0x81, 0xea, 0x08,
+ 0x8f, 0xa2, 0x70, 0x0f, 0x31, 0x71, 0x58, 0xb7, 0xf8, 0x82, 0xd8, 0xc4,
+ 0x70, 0xfa, 0x76, 0x36, 0x15, 0xc4, 0xce, 0x44, 0x0d, 0xed, 0xa9, 0x16,
+ 0x2b, 0xf7, 0x48, 0x8d, 0x79, 0xe2, 0x5e, 0x17, 0xb5, 0xe8, 0x50, 0xfa,
+ 0x56, 0x7b, 0x6a, 0xa4, 0x6e, 0x0a, 0xb6, 0x9a, 0x98, 0xd4, 0xb3, 0x78,
+ 0x73, 0xcc, 0xaa, 0x61, 0x8b, 0x4d, 0xb6, 0x62, 0xcb, 0x00, 0xda, 0xf7,
+ 0x37, 0x8a, 0x4d, 0x3a, 0x31, 0x44, 0xbe, 0x7f, 0x91, 0xb1, 0xc3, 0x0c,
+ 0xed, 0x73, 0x62, 0x42, 0x01, 0x06, 0x87, 0x5d, 0xf8, 0xf1, 0xb0, 0x07,
+ 0xee, 0x58, 0x31, 0xc6, 0x29, 0xe3, 0x31, 0x72, 0x9c, 0x8f, 0x18, 0x65,
+ 0x8f, 0xd2, 0xa7, 0x7e, 0x18, 0xad, 0x42, 0x26, 0x5d, 0x8b, 0xab, 0xc4,
+ 0x94, 0x34, 0xf7, 0xe3, 0x83, 0x68, 0x00, 0x2f, 0xa7, 0x83, 0x78, 0x3f,
+ 0x2a, 0xd8, 0x13, 0xc4, 0x11, 0xca, 0xaf, 0x28, 0xe6, 0x66, 0xbf, 0x82,
+ 0x43, 0x1e, 0x38, 0x63, 0x9a, 0x67, 0x28, 0xa7, 0x0b, 0x8e, 0x4c, 0x2b,
+ 0xed, 0x46, 0xce, 0x44, 0x88, 0x1f, 0x70, 0xe8, 0x43, 0x8c, 0xb9, 0x07,
+ 0x83, 0xf9, 0xfc, 0xaf, 0xd7, 0x3d, 0x81, 0x99, 0xb4, 0x9d, 0x2f, 0x4d,
+ 0x55, 0x93, 0x98, 0x2a, 0x19, 0xba, 0x12, 0xd5, 0x24, 0x17, 0x48, 0x6c,
+ 0x37, 0x14, 0xe7, 0x62, 0x72, 0x89, 0xaa, 0xad, 0x92, 0x17, 0xe6, 0xfc,
+ 0xe5, 0x6c, 0x99, 0xc9, 0x76, 0x57, 0x31, 0xff, 0xc0, 0xd6, 0x59, 0xb9,
+ 0x1c, 0x93, 0x7a, 0x83, 0xf7, 0xe5, 0x31, 0x5e, 0xe2, 0xb5, 0xdd, 0xa1,
+ 0xd7, 0xa2, 0x7f, 0x3f, 0x4b, 0xea, 0x71, 0xc7, 0x11, 0xa4, 0x4c, 0x6e,
+ 0x17, 0x0f, 0x98, 0x78, 0x93, 0x18, 0x72, 0x39, 0x29, 0xbc, 0x48, 0xf8,
+ 0x50, 0x17, 0x7d, 0x4f, 0x19, 0xf9, 0x80, 0x86, 0x6d, 0xe4, 0xeb, 0xbe,
+ 0xf8, 0x04, 0xe3, 0x91, 0xaf, 0x93, 0x93, 0x95, 0xb3, 0x9b, 0x1f, 0x70,
+ 0xbc, 0x56, 0xec, 0xa4, 0x2d, 0x16, 0x69, 0x77, 0x61, 0x25, 0xf9, 0x8e,
+ 0x43, 0xa3, 0xcb, 0x78, 0x58, 0xfc, 0x86, 0xe4, 0x70, 0x54, 0xa9, 0x95,
+ 0xad, 0x7d, 0x1d, 0xf7, 0xa2, 0xbd, 0xda, 0x05, 0xa9, 0x6f, 0xbd, 0x81,
+ 0x25, 0x48, 0x3d, 0x2a, 0xbe, 0x93, 0x1c, 0x39, 0xac, 0x19, 0xe7, 0x31,
+ 0xcf, 0x62, 0xdd, 0xc5, 0x61, 0x99, 0x4f, 0x15, 0x65, 0xaf, 0xe2, 0x1d,
+ 0xca, 0xf5, 0x52, 0xd4, 0x37, 0x75, 0x1f, 0x1a, 0x4e, 0x5d, 0xb2, 0x4b,
+ 0xed, 0x4f, 0xda, 0x07, 0xa1, 0xb1, 0xbf, 0x4f, 0xa3, 0x21, 0xf4, 0xa9,
+ 0x72, 0x2d, 0xfc, 0xb0, 0x15, 0xdd, 0x43, 0x32, 0x07, 0xd3, 0xac, 0x24,
+ 0x1e, 0x3e, 0x6c, 0x8d, 0x2f, 0x63, 0xdf, 0x1a, 0x5b, 0x78, 0x19, 0x49,
+ 0xe7, 0xe3, 0x8b, 0x49, 0x1c, 0x4e, 0x52, 0xfe, 0x8b, 0xdf, 0xa6, 0x1c,
+ 0x26, 0x31, 0x9c, 0xd2, 0xc8, 0x1d, 0x4b, 0xe0, 0xa9, 0x0e, 0x62, 0x17,
+ 0xfd, 0x75, 0x8c, 0xed, 0xd3, 0xb1, 0x12, 0x18, 0xd5, 0xd9, 0x31, 0xbf,
+ 0x1e, 0xbf, 0x6a, 0x4e, 0x3c, 0x64, 0xc5, 0xa9, 0xbc, 0xfe, 0x1d, 0x9f,
+ 0x99, 0x2d, 0xc7, 0x32, 0xb1, 0x3e, 0x76, 0xd9, 0x9c, 0x68, 0x9d, 0xfe,
+ 0x7b, 0x85, 0x75, 0xa6, 0x2a, 0x62, 0xab, 0xe6, 0x77, 0x56, 0x2e, 0xdd,
+ 0x94, 0xcb, 0x0c, 0xed, 0x2d, 0xf3, 0x41, 0x6b, 0x5e, 0xef, 0xcd, 0x12,
+ 0x2e, 0x5f, 0x17, 0xf7, 0xcc, 0x46, 0x71, 0x15, 0xdb, 0x10, 0x43, 0xc3,
+ 0x5a, 0xd3, 0x29, 0xfc, 0x8b, 0x79, 0xe1, 0xa6, 0x7e, 0x66, 0xf2, 0x9e,
+ 0xf8, 0x9e, 0x0b, 0xb9, 0x9c, 0x8f, 0x3b, 0xc7, 0xf7, 0x27, 0x71, 0x3c,
+ 0x29, 0xd8, 0xef, 0xc1, 0x13, 0x92, 0x9b, 0x52, 0xbd, 0xbd, 0x06, 0x26,
+ 0xc8, 0xf1, 0xde, 0xa6, 0xec, 0x25, 0xff, 0x38, 0x41, 0x9e, 0x37, 0xdd,
+ 0x37, 0x45, 0x90, 0xaa, 0x92, 0x1a, 0x8c, 0xe0, 0xe7, 0x24, 0xb6, 0x27,
+ 0x7f, 0x4a, 0x1c, 0xfb, 0x98, 0xbc, 0xa7, 0x8b, 0x9c, 0x7a, 0x12, 0x5b,
+ 0x52, 0xcd, 0x78, 0x69, 0x6f, 0x0b, 0x71, 0x45, 0xb0, 0xd1, 0x77, 0xea,
+ 0xa2, 0xbd, 0x19, 0xfb, 0x0f, 0xa5, 0x91, 0x1a, 0x11, 0x7f, 0x28, 0x3e,
+ 0x57, 0x7c, 0xa1, 0x86, 0x68, 0xe2, 0x24, 0x0c, 0x7e, 0xef, 0x4c, 0x6c,
+ 0x44, 0x64, 0xe4, 0x2d, 0xf2, 0xf8, 0x49, 0x2c, 0xef, 0xd3, 0xd6, 0x1e,
+ 0xc4, 0x24, 0x56, 0xd1, 0x57, 0x26, 0x13, 0x2d, 0xec, 0xbf, 0x19, 0x3d,
+ 0x7b, 0xbd, 0x56, 0xbe, 0x49, 0x62, 0xf8, 0x6d, 0x63, 0x11, 0x18, 0x43,
+ 0x72, 0x36, 0xc3, 0x85, 0x60, 0xdc, 0xa3, 0x7c, 0x48, 0x3e, 0xdc, 0x10,
+ 0xf7, 0x32, 0x06, 0xf3, 0x1a, 0xab, 0x14, 0x9f, 0xa7, 0xc0, 0x26, 0xb5,
+ 0xc0, 0x19, 0x38, 0xa5, 0x2b, 0x28, 0xba, 0x57, 0x41, 0x88, 0xbe, 0xca,
+ 0x33, 0x8b, 0x3e, 0x64, 0x48, 0x47, 0xcf, 0x00, 0xd7, 0x7b, 0x7d, 0xdf,
+ 0x64, 0xbf, 0x56, 0xb3, 0x3f, 0xd9, 0xbb, 0x16, 0xf4, 0x8c, 0xf9, 0x3a,
+ 0x4e, 0xc1, 0x6d, 0x71, 0xab, 0x9e, 0x81, 0xeb, 0x79, 0x81, 0xd2, 0x8f,
+ 0x1b, 0xbd, 0x81, 0x19, 0x8a, 0xb4, 0xdd, 0x4a, 0xcc, 0x9a, 0xde, 0xde,
+ 0x50, 0x92, 0x8b, 0xc9, 0x3f, 0x6d, 0x62, 0x17, 0xdd, 0x96, 0xbd, 0x88,
+ 0x2c, 0x7a, 0x92, 0x11, 0xea, 0xf4, 0x4f, 0xcc, 0x54, 0x6b, 0x2b, 0xe7,
+ 0xd9, 0x28, 0xb5, 0x31, 0x0b, 0x13, 0xce, 0x4a, 0x2e, 0xce, 0x29, 0x98,
+ 0xd0, 0xdd, 0xee, 0xa2, 0x3e, 0x15, 0x12, 0x97, 0x8a, 0x46, 0x5d, 0x70,
+ 0x1d, 0x2c, 0x41, 0xe1, 0xa0, 0xf0, 0x31, 0xc9, 0x41, 0xa8, 0xb0, 0x8f,
+ 0x96, 0xd2, 0x06, 0xb8, 0x87, 0xa3, 0xb4, 0xb1, 0xa8, 0x1b, 0xf3, 0x46,
+ 0xdd, 0xf8, 0x31, 0x31, 0xa0, 0x66, 0x54, 0xc3, 0x38, 0x31, 0xc0, 0x3d,
+ 0x1a, 0xc0, 0x58, 0x34, 0x88, 0x19, 0xa3, 0xe3, 0xca, 0x1b, 0xe9, 0x66,
+ 0xee, 0xb7, 0x8c, 0x23, 0x32, 0xcc, 0xef, 0xa9, 0xec, 0x67, 0x0b, 0xb1,
+ 0x4e, 0xf6, 0x36, 0x80, 0x1d, 0x03, 0x69, 0x2c, 0xdb, 0x63, 0xe2, 0x9f,
+ 0xf4, 0x06, 0x77, 0x91, 0x22, 0xb1, 0x80, 0x89, 0x34, 0xfd, 0xda, 0x0a,
+ 0xdd, 0xbb, 0x56, 0xce, 0x3b, 0xb7, 0x57, 0x99, 0x28, 0x08, 0x79, 0x75,
+ 0xa2, 0xfb, 0xda, 0x22, 0x45, 0x7c, 0x54, 0x83, 0x67, 0x03, 0xe6, 0x22,
+ 0x5b, 0x57, 0xbc, 0x0f, 0x1b, 0x54, 0x85, 0xb6, 0xd8, 0x82, 0x9d, 0x15,
+ 0x86, 0xeb, 0x4a, 0xa3, 0x69, 0xae, 0x0b, 0xd5, 0xcd, 0xb2, 0x72, 0xd0,
+ 0xb6, 0xf5, 0xfc, 0x6e, 0xe3, 0x9a, 0x65, 0xdd, 0x1d, 0x88, 0xed, 0x56,
+ 0x90, 0xf6, 0x77, 0x20, 0x3a, 0xdc, 0x21, 0xfc, 0x89, 0x78, 0xd0, 0x4b,
+ 0x3c, 0x30, 0xbb, 0x9e, 0x0e, 0x3d, 0x88, 0xcb, 0x96, 0xc7, 0x97, 0x67,
+ 0xbc, 0x01, 0x8f, 0x6d, 0xfa, 0x1e, 0xe8, 0xb3, 0x25, 0xcf, 0x21, 0x76,
+ 0xd3, 0xdc, 0x27, 0xbc, 0xd9, 0xdf, 0xdb, 0xc3, 0xbd, 0x7f, 0xe8, 0x80,
+ 0xf8, 0x17, 0xd3, 0xec, 0x25, 0x2f, 0x45, 0x85, 0xac, 0x41, 0x43, 0x3c,
+ 0x61, 0x7e, 0x5c, 0xa3, 0xf9, 0xa6, 0x76, 0xd1, 0x8f, 0x9f, 0xdf, 0xd3,
+ 0xb0, 0x61, 0x83, 0x70, 0x96, 0x45, 0x1a, 0x63, 0xe9, 0x34, 0xce, 0x8d,
+ 0xcc, 0x47, 0xea, 0x21, 0xae, 0x87, 0xfb, 0xe4, 0x8c, 0x7f, 0xc1, 0x38,
+ 0x43, 0xb0, 0x4f, 0x53, 0x0f, 0x13, 0xf7, 0x6c, 0xa3, 0x7e, 0x6c, 0xa9,
+ 0x80, 0x71, 0xa5, 0x51, 0xc6, 0xbf, 0x3e, 0x7f, 0xae, 0xb7, 0x19, 0xbb,
+ 0xf6, 0x0a, 0xaf, 0x10, 0xfe, 0xe5, 0x33, 0x3e, 0x40, 0x0b, 0x92, 0x63,
+ 0xd9, 0xb1, 0xa2, 0x89, 0x5b, 0xf5, 0x44, 0xf6, 0xfc, 0x24, 0x76, 0x50,
+ 0x27, 0x5d, 0xec, 0x9f, 0x3e, 0x85, 0xfd, 0x69, 0x81, 0x22, 0x19, 0x6f,
+ 0xf4, 0x27, 0xe6, 0xce, 0x6a, 0x91, 0x8d, 0xf4, 0xff, 0x9b, 0x6a, 0xc1,
+ 0x8b, 0x75, 0xa1, 0xaf, 0x5a, 0xeb, 0x15, 0x7e, 0x4b, 0xce, 0x3a, 0x3f,
+ 0x1f, 0x79, 0xe6, 0x76, 0xf3, 0xf9, 0x9c, 0xed, 0x64, 0x4e, 0x1d, 0xd8,
+ 0xb1, 0x1b, 0x46, 0xb1, 0xa6, 0x45, 0xe6, 0x2b, 0x1d, 0xe8, 0xa5, 0x7c,
+ 0xb7, 0x25, 0x3b, 0xb0, 0x9f, 0xf6, 0x3a, 0xa8, 0x1f, 0xab, 0xb1, 0xa1,
+ 0x7e, 0xca, 0x8e, 0x89, 0x7f, 0x94, 0x9a, 0xc5, 0x82, 0x45, 0x7e, 0xda,
+ 0x56, 0x07, 0xe2, 0xa9, 0x73, 0xb3, 0xad, 0x9a, 0xa8, 0x4d, 0x7c, 0x9e,
+ 0xc8, 0xa2, 0x13, 0xc5, 0x7d, 0x27, 0xe1, 0xec, 0xeb, 0x44, 0x91, 0x7f,
+ 0x09, 0x56, 0x84, 0x2e, 0x98, 0x97, 0x35, 0x87, 0xfb, 0x38, 0xe5, 0x73,
+ 0x2c, 0x58, 0xc3, 0x98, 0x91, 0x71, 0xca, 0xd0, 0x1c, 0xda, 0x7d, 0x23,
+ 0x76, 0x8c, 0xc9, 0x59, 0x08, 0x1b, 0x56, 0x2d, 0x96, 0x58, 0x5c, 0xa1,
+ 0x5e, 0xcf, 0x62, 0x3c, 0xa9, 0xa9, 0xcf, 0x59, 0xe7, 0x56, 0xc8, 0xb9,
+ 0xaa, 0x3c, 0x78, 0xd2, 0x3a, 0xaf, 0x21, 0xf7, 0x37, 0x31, 0x0e, 0xd8,
+ 0x84, 0x9a, 0x98, 0x61, 0x8a, 0xbc, 0x8f, 0x23, 0xf2, 0xa2, 0x8d, 0xf3,
+ 0x68, 0x5a, 0xe4, 0xdf, 0x30, 0xa5, 0x88, 0x3e, 0xfb, 0xdb, 0x47, 0x15,
+ 0xdd, 0xb5, 0x3a, 0xa3, 0x20, 0xd0, 0xc7, 0xbe, 0x42, 0x23, 0xb3, 0xb3,
+ 0xb9, 0xf1, 0x3c, 0xbf, 0xdb, 0x44, 0x5e, 0xb0, 0x09, 0x65, 0x31, 0xe1,
+ 0xe4, 0x82, 0x0b, 0x91, 0xa5, 0xe5, 0x7c, 0x3e, 0x1d, 0xf2, 0xb7, 0x96,
+ 0x2a, 0xc2, 0x7d, 0xfc, 0x4d, 0xab, 0x14, 0xe1, 0x2a, 0xf2, 0x9c, 0xee,
+ 0xaa, 0xcf, 0x9c, 0xcf, 0xd5, 0x31, 0x1b, 0x89, 0x0d, 0x72, 0xce, 0x24,
+ 0x7f, 0xd6, 0xea, 0x46, 0xce, 0xda, 0x19, 0x97, 0xd8, 0xe1, 0x68, 0x68,
+ 0x59, 0xb4, 0x89, 0x38, 0x67, 0x2e, 0x39, 0x44, 0xbd, 0xbf, 0x88, 0x2a,
+ 0xfc, 0x73, 0x54, 0x30, 0xcd, 0x83, 0x9f, 0x47, 0x0b, 0x25, 0x26, 0x4e,
+ 0x49, 0x5e, 0xf6, 0x4c, 0xd2, 0x30, 0x29, 0xd7, 0x96, 0x55, 0xd4, 0xa5,
+ 0x40, 0xa8, 0x14, 0xa8, 0xee, 0x7e, 0xd2, 0x69, 0xc5, 0xe8, 0x65, 0xa8,
+ 0x20, 0xfe, 0xf7, 0x0d, 0xfd, 0xa1, 0xf3, 0x0e, 0xc4, 0xe0, 0x62, 0xc9,
+ 0x15, 0xda, 0xb1, 0x2d, 0xf4, 0x1b, 0x33, 0xd5, 0x26, 0xcf, 0xd4, 0xe2,
+ 0xdc, 0x6e, 0xd1, 0xd3, 0x00, 0x0a, 0xe3, 0xe7, 0xa9, 0x93, 0x2a, 0xce,
+ 0x46, 0x7d, 0xfa, 0x1a, 0xdb, 0xb7, 0xa8, 0xff, 0xf3, 0x6e, 0xc2, 0xed,
+ 0x79, 0xda, 0x03, 0x78, 0xdc, 0xc2, 0xed, 0x30, 0xb6, 0xd0, 0x2f, 0x90,
+ 0xb7, 0xed, 0x7b, 0xd2, 0xa6, 0xd2, 0x9f, 0xfb, 0x54, 0x1f, 0x63, 0xea,
+ 0x2d, 0x1c, 0x43, 0xf8, 0xe4, 0x4c, 0xf2, 0xbd, 0xa7, 0xa3, 0x0d, 0x9e,
+ 0x5f, 0xe3, 0x09, 0xda, 0xa3, 0x8c, 0x21, 0x6b, 0xd2, 0x50, 0xca, 0xd8,
+ 0xf1, 0x04, 0xd7, 0xb1, 0xad, 0x22, 0x3b, 0x6e, 0x79, 0xae, 0xef, 0xf8,
+ 0x90, 0xf0, 0xad, 0x7b, 0xb0, 0xc6, 0xea, 0x3b, 0x68, 0xd9, 0xe6, 0xbe,
+ 0xa8, 0x82, 0x19, 0xf5, 0x1a, 0x12, 0xe9, 0x66, 0x6c, 0xac, 0xac, 0xc5,
+ 0xfe, 0xc4, 0x26, 0x2c, 0x24, 0xe7, 0x7d, 0xa4, 0xd2, 0xa0, 0x5f, 0x24,
+ 0x06, 0xc5, 0x35, 0x75, 0xbe, 0xf2, 0x8d, 0x5c, 0xae, 0xba, 0x0a, 0x8e,
+ 0xb8, 0xf8, 0xbb, 0x02, 0xf4, 0xab, 0x73, 0x51, 0x62, 0x9d, 0x81, 0xcc,
+ 0xf6, 0xbd, 0x6b, 0xc8, 0x9b, 0xf3, 0x81, 0x44, 0x8d, 0xb8, 0x75, 0x4e,
+ 0x25, 0xf0, 0x3c, 0x79, 0x44, 0x8a, 0xde, 0xaf, 0x20, 0xac, 0xa5, 0xd6,
+ 0xa3, 0x08, 0xc6, 0x2c, 0xc1, 0x43, 0x79, 0x66, 0xce, 0x2d, 0x73, 0xaa,
+ 0xcc, 0xcd, 0x29, 0x7f, 0xff, 0x34, 0xef, 0x89, 0x6e, 0x09, 0xb7, 0x90,
+ 0xdf, 0x8b, 0xd1, 0x4a, 0x7d, 0xaa, 0xe2, 0x9c, 0x13, 0x09, 0xb9, 0xef,
+ 0xd5, 0x0d, 0x5b, 0x23, 0x3e, 0xdb, 0x93, 0xd5, 0xc1, 0xb5, 0x75, 0xdc,
+ 0xff, 0xf2, 0x46, 0x4c, 0x8d, 0x88, 0x2f, 0xfb, 0xc3, 0x67, 0x50, 0x8c,
+ 0xeb, 0x67, 0x50, 0x44, 0xae, 0xde, 0x53, 0xef, 0xa0, 0x61, 0xe2, 0x31,
+ 0xdb, 0x61, 0x13, 0x33, 0x45, 0xc6, 0x71, 0xb7, 0xc4, 0x9a, 0x36, 0x72,
+ 0x08, 0x23, 0x3d, 0xee, 0x16, 0x3f, 0xe9, 0x88, 0x03, 0xf3, 0xe2, 0x06,
+ 0x0a, 0xc3, 0xda, 0xbe, 0x2b, 0xf6, 0x6b, 0x66, 0xfb, 0xac, 0x39, 0x8c,
+ 0xf9, 0x6e, 0xac, 0xb9, 0x97, 0x73, 0xb7, 0x6b, 0x3f, 0x31, 0xef, 0xab,
+ 0x92, 0x39, 0xfe, 0xd2, 0x9d, 0x3d, 0xfb, 0x70, 0x07, 0xe5, 0x92, 0x97,
+ 0x89, 0x49, 0xfd, 0xf9, 0x2b, 0xf3, 0x9b, 0x37, 0xdd, 0x17, 0x2e, 0x23,
+ 0x7a, 0x3a, 0xfd, 0x3c, 0xa0, 0xe8, 0xac, 0xd4, 0x56, 0x26, 0x71, 0x28,
+ 0x29, 0xba, 0x2b, 0x32, 0x8e, 0xe0, 0x22, 0x79, 0x61, 0x41, 0xff, 0x24,
+ 0x06, 0xc9, 0x0b, 0xed, 0x71, 0xef, 0x3e, 0x4a, 0x12, 0x1b, 0xd5, 0x25,
+ 0xc4, 0xea, 0x32, 0xce, 0x23, 0x3f, 0x87, 0x3a, 0x4b, 0xee, 0xe2, 0x5f,
+ 0x76, 0x72, 0xbd, 0x45, 0xe4, 0x48, 0xcd, 0xb1, 0x42, 0x68, 0x15, 0xe5,
+ 0x28, 0xd5, 0xe4, 0x0c, 0x7c, 0xb6, 0x5d, 0x94, 0x73, 0x29, 0xd1, 0xe6,
+ 0x62, 0x95, 0xd5, 0xd6, 0x63, 0x9d, 0x01, 0xd1, 0x2a, 0xc5, 0xff, 0x8a,
+ 0xcf, 0x25, 0xdf, 0x5e, 0x2c, 0x3e, 0x37, 0xcc, 0xb9, 0xcd, 0xc9, 0xd5,
+ 0x99, 0x56, 0x59, 0xf7, 0xf7, 0x25, 0x2e, 0x7c, 0xd9, 0x9f, 0xf8, 0x3d,
+ 0x9f, 0xe9, 0x80, 0xba, 0xb7, 0x18, 0x0f, 0xfd, 0x65, 0x09, 0xf4, 0xca,
+ 0x6c, 0xae, 0x7c, 0x5e, 0x38, 0x1a, 0x32, 0x13, 0xc2, 0x93, 0xee, 0x84,
+ 0x67, 0xb6, 0x8c, 0x25, 0x18, 0x20, 0x7b, 0x21, 0x7b, 0x27, 0x39, 0xdc,
+ 0xdb, 0xd5, 0x18, 0xbc, 0xea, 0xc4, 0xf5, 0x7d, 0x98, 0x0f, 0xed, 0xe1,
+ 0x2a, 0xae, 0x2d, 0xeb, 0x23, 0x76, 0xd0, 0x47, 0x04, 0xfc, 0x59, 0x0c,
+ 0x93, 0x1a, 0xbd, 0x93, 0x3e, 0x62, 0x84, 0x3e, 0xe2, 0xa2, 0x5e, 0x8e,
+ 0xe5, 0x39, 0x1f, 0xd1, 0x6e, 0xd3, 0xad, 0xfe, 0x9d, 0xda, 0x7d, 0x35,
+ 0xc4, 0x30, 0x8e, 0xf1, 0xb5, 0x9b, 0xb8, 0xd8, 0x4c, 0xed, 0x97, 0xe6,
+ 0x23, 0x55, 0xb2, 0xc6, 0xe6, 0x9a, 0x6c, 0x8e, 0xbc, 0x03, 0xfb, 0x88,
+ 0x8f, 0x35, 0x9a, 0x3c, 0xa3, 0x25, 0x6b, 0xec, 0x1d, 0xe8, 0x67, 0xff,
+ 0x7d, 0xc4, 0xc8, 0x18, 0x31, 0x52, 0x5f, 0x78, 0xec, 0x45, 0x15, 0xf5,
+ 0x1d, 0x64, 0x0f, 0xdf, 0x16, 0x6c, 0x79, 0x99, 0xd8, 0xf2, 0x3c, 0x31,
+ 0x72, 0x67, 0x4a, 0xc6, 0x91, 0xf1, 0xf2, 0xe3, 0x48, 0x9f, 0xff, 0x66,
+ 0xae, 0xaf, 0x92, 0xb9, 0xde, 0x6e, 0x1e, 0xf2, 0xdb, 0x9f, 0xf2, 0xef,
+ 0x62, 0x8b, 0x43, 0xf5, 0x26, 0xa6, 0x9f, 0xa9, 0x98, 0x24, 0xbe, 0x5a,
+ 0x71, 0x00, 0xfd, 0x6b, 0x04, 0x2b, 0x17, 0xab, 0xb8, 0x1c, 0x9d, 0x44,
+ 0xd1, 0x81, 0x3c, 0x16, 0x99, 0x4b, 0x4e, 0x10, 0x87, 0x06, 0x21, 0xd8,
+ 0xd3, 0xc4, 0x3d, 0x30, 0x68, 0x13, 0x65, 0x18, 0x4d, 0xca, 0xd9, 0x0b,
+ 0x13, 0xbb, 0x42, 0x2e, 0x72, 0xd8, 0xee, 0xe3, 0x05, 0x96, 0x4f, 0x28,
+ 0x23, 0x5e, 0xe7, 0xf9, 0xb5, 0x70, 0x6b, 0xc1, 0x1a, 0xc6, 0x11, 0x43,
+ 0x76, 0x14, 0x2c, 0xca, 0xc6, 0x0e, 0xe7, 0xda, 0xa4, 0x5d, 0x2d, 0x06,
+ 0x77, 0x8b, 0xae, 0xf9, 0x50, 0xa3, 0x9d, 0x67, 0x2c, 0x01, 0xbc, 0x1b,
+ 0xb5, 0xdd, 0xe9, 0x22, 0x07, 0xee, 0xd2, 0x17, 0xe3, 0xda, 0xcc, 0x2d,
+ 0xb4, 0x6f, 0x37, 0x7f, 0x9b, 0xc0, 0xc1, 0xa8, 0x0b, 0x05, 0x56, 0x8d,
+ 0xb2, 0x9c, 0xeb, 0xc9, 0xea, 0xcb, 0x36, 0xea, 0x4b, 0x21, 0x63, 0xb3,
+ 0x15, 0x96, 0x5d, 0x4a, 0x3f, 0x93, 0xd6, 0xbb, 0x32, 0xda, 0x62, 0xe1,
+ 0xad, 0x41, 0xfa, 0xc0, 0x32, 0xc4, 0xfb, 0xba, 0x70, 0x36, 0x54, 0x86,
+ 0xd8, 0x01, 0xb1, 0xa7, 0x5a, 0xc1, 0x4d, 0x8e, 0xdb, 0x44, 0xf9, 0xa8,
+ 0xc4, 0x95, 0x86, 0x4e, 0xbb, 0xbd, 0x0c, 0x17, 0x2a, 0x18, 0xaf, 0x5a,
+ 0xef, 0x13, 0xb5, 0x62, 0x7f, 0x6e, 0x8f, 0x54, 0xf2, 0x9b, 0xd6, 0xeb,
+ 0x7c, 0x39, 0xbf, 0x96, 0xbc, 0x7d, 0x66, 0x6b, 0xe4, 0x3d, 0xe4, 0x30,
+ 0x2f, 0x49, 0x3e, 0xc8, 0xe6, 0xa3, 0xdf, 0x60, 0x5c, 0x34, 0x26, 0xb2,
+ 0xce, 0xeb, 0xd6, 0xeb, 0x35, 0xd9, 0x33, 0x3d, 0xf9, 0x3d, 0xc8, 0x5f,
+ 0x6b, 0x6b, 0x8b, 0x95, 0x5f, 0x98, 0xcf, 0x56, 0xcb, 0xfc, 0xae, 0x32,
+ 0x0e, 0xfb, 0x31, 0x7f, 0x5f, 0x86, 0x9e, 0xa1, 0xe9, 0x7e, 0x41, 0x6c,
+ 0xce, 0x73, 0xd3, 0xd9, 0xc3, 0x8a, 0xb8, 0xbc, 0xbf, 0x75, 0x34, 0xf4,
+ 0x24, 0xf7, 0xc1, 0xbf, 0xb0, 0xc1, 0xca, 0xa5, 0x90, 0xe3, 0x32, 0xfe,
+ 0x10, 0x3c, 0x35, 0xe8, 0xcf, 0xcb, 0xf0, 0xb3, 0xa4, 0xf8, 0x57, 0x13,
+ 0x85, 0xa1, 0x12, 0xfa, 0xbb, 0xee, 0xe7, 0x2a, 0x2c, 0xce, 0x5c, 0x86,
+ 0x4a, 0xea, 0x5e, 0xff, 0xd0, 0xed, 0xf4, 0xfc, 0x86, 0x0f, 0x48, 0x87,
+ 0x14, 0x62, 0xc2, 0x6f, 0xcc, 0x5d, 0x8f, 0x66, 0x9f, 0x39, 0x97, 0x74,
+ 0xe1, 0xa3, 0x50, 0x3b, 0x26, 0x2a, 0xc2, 0x18, 0x48, 0x14, 0xa1, 0x7d,
+ 0x56, 0xbd, 0xf5, 0xce, 0x45, 0x4d, 0xdc, 0x83, 0xf3, 0x51, 0x27, 0x9a,
+ 0x66, 0x7b, 0xac, 0x7c, 0x92, 0x8d, 0x76, 0xf1, 0x76, 0x34, 0x42, 0x5f,
+ 0xe0, 0xb9, 0xc9, 0x3f, 0x14, 0x68, 0x8b, 0x70, 0x7f, 0x0e, 0xc3, 0xf7,
+ 0x27, 0x3e, 0x27, 0xc6, 0x94, 0x1b, 0x33, 0xc3, 0x65, 0xb8, 0x7b, 0x40,
+ 0xce, 0x29, 0x48, 0x9d, 0x4a, 0x9b, 0x9a, 0xaf, 0x94, 0x61, 0xc9, 0x90,
+ 0xe0, 0xb9, 0x9c, 0xfd, 0x48, 0x87, 0x5c, 0xb1, 0x36, 0xee, 0x51, 0x27,
+ 0xea, 0xf7, 0x5a, 0x72, 0x55, 0xed, 0x8a, 0xd9, 0x75, 0x49, 0x8f, 0xe8,
+ 0xf4, 0x67, 0x9d, 0xf7, 0x53, 0xef, 0xa7, 0x42, 0xde, 0xf6, 0x99, 0x76,
+ 0xad, 0xe3, 0x57, 0x4a, 0x10, 0xa3, 0x19, 0xa0, 0x6f, 0x24, 0x80, 0x0f,
+ 0x12, 0xc2, 0xed, 0x03, 0x78, 0x7f, 0x2c, 0x88, 0x77, 0xe8, 0x87, 0x8a,
+ 0xe2, 0xde, 0xc8, 0x33, 0x8c, 0xdd, 0xde, 0xe5, 0x75, 0x61, 0x5c, 0xc7,
+ 0x15, 0xca, 0xcf, 0x19, 0x6f, 0xc4, 0xa5, 0xb1, 0x6f, 0xe0, 0xf2, 0x5e,
+ 0x05, 0xc7, 0xb4, 0x6f, 0xe0, 0xe2, 0xa1, 0x4e, 0x2c, 0xda, 0x2b, 0x67,
+ 0xf5, 0x8e, 0x86, 0x54, 0xfa, 0x81, 0x27, 0xeb, 0xcc, 0xae, 0x17, 0xf4,
+ 0x7a, 0x62, 0x86, 0x57, 0x6f, 0x67, 0x6c, 0x24, 0xf8, 0x1d, 0xb1, 0xc9,
+ 0x9e, 0xc9, 0xde, 0x75, 0xe2, 0xb2, 0x85, 0xd9, 0xb7, 0xc7, 0x89, 0x1b,
+ 0x78, 0x2d, 0xe3, 0x88, 0x6d, 0xdf, 0x81, 0x57, 0x19, 0x94, 0x6e, 0x61,
+ 0x3b, 0x17, 0x71, 0xee, 0xe9, 0x68, 0x11, 0x0a, 0xab, 0xcb, 0x2d, 0x7b,
+ 0x2b, 0x8e, 0x07, 0x70, 0x9a, 0xb2, 0x5b, 0x59, 0xed, 0xe5, 0xb5, 0xf8,
+ 0xd8, 0x20, 0xe3, 0x93, 0x99, 0xf8, 0xe0, 0x26, 0xdf, 0xfa, 0xaa, 0x85,
+ 0x0d, 0x0e, 0xed, 0x81, 0x39, 0x59, 0x6c, 0x20, 0xa0, 0x13, 0x93, 0x25,
+ 0x27, 0x58, 0xae, 0x69, 0x1b, 0xbe, 0x4b, 0x1b, 0x4f, 0x87, 0x8e, 0xfd,
+ 0x49, 0x29, 0x39, 0xf0, 0x0b, 0xa1, 0x7a, 0xa3, 0x02, 0x2b, 0x78, 0x7f,
+ 0x62, 0x91, 0x8a, 0x75, 0xfc, 0xf6, 0xb3, 0x5d, 0x90, 0xf3, 0xb8, 0x6a,
+ 0xa6, 0x54, 0x1f, 0xff, 0xae, 0xa5, 0x2f, 0xdf, 0x84, 0xb3, 0xb1, 0x86,
+ 0xf6, 0x11, 0xe5, 0x8a, 0x69, 0x54, 0xd7, 0xf1, 0xb7, 0x2a, 0x9c, 0x8b,
+ 0x7a, 0x27, 0x0e, 0xa1, 0xc1, 0x33, 0xa5, 0xec, 0x37, 0x0d, 0x55, 0xf6,
+ 0x47, 0xd6, 0x2b, 0xcf, 0xdf, 0xc5, 0xfb, 0x17, 0xa6, 0xe9, 0xe1, 0x8d,
+ 0xf8, 0xca, 0x79, 0x5d, 0xff, 0x84, 0x83, 0x98, 0x4b, 0x86, 0xf5, 0x06,
+ 0x75, 0x0b, 0xb1, 0x20, 0xa2, 0xde, 0x4e, 0xff, 0x8a, 0xa8, 0x7f, 0x61,
+ 0xc6, 0x8b, 0x65, 0x50, 0x2d, 0x5f, 0xd4, 0x8a, 0xe4, 0xd0, 0x74, 0x1e,
+ 0x29, 0x7a, 0x97, 0xe5, 0xa4, 0xed, 0x15, 0xdd, 0xc7, 0x9d, 0xf4, 0x87,
+ 0x09, 0x62, 0x78, 0x9c, 0x18, 0x5e, 0x48, 0x0c, 0xbf, 0xba, 0xa7, 0x18,
+ 0x67, 0xf7, 0x34, 0x21, 0x5d, 0x21, 0xcf, 0xd8, 0xe1, 0xe4, 0xea, 0x52,
+ 0x96, 0x6f, 0xb7, 0xa1, 0xa6, 0x7f, 0xa9, 0x9c, 0x75, 0x85, 0xf8, 0xd0,
+ 0x82, 0x38, 0x11, 0xb1, 0xd5, 0x0e, 0x87, 0xf5, 0x7e, 0xc1, 0x8c, 0x9b,
+ 0xf4, 0xcf, 0xa5, 0x15, 0xa2, 0xa5, 0x4a, 0xf0, 0xe1, 0xe2, 0x1c, 0xf1,
+ 0x99, 0x3f, 0xe5, 0x5c, 0x8e, 0x53, 0xa7, 0x9f, 0xd2, 0xef, 0x91, 0x1a,
+ 0x1d, 0xdb, 0xcb, 0x73, 0x12, 0xc3, 0x98, 0xd8, 0x41, 0x0d, 0xab, 0xaf,
+ 0x36, 0x91, 0xd0, 0xc3, 0xf4, 0x4f, 0x21, 0x44, 0x2a, 0x82, 0xf4, 0x4b,
+ 0x72, 0xad, 0xe2, 0x12, 0xe3, 0xaf, 0x4c, 0x50, 0xc1, 0x47, 0x5f, 0x13,
+ 0xbf, 0xef, 0xd7, 0xcf, 0x2a, 0xa7, 0x67, 0x65, 0xdf, 0x6b, 0x10, 0x8c,
+ 0x28, 0xb7, 0x30, 0xa2, 0xd0, 0xe2, 0x40, 0xb3, 0x2d, 0x6c, 0xf1, 0xd8,
+ 0xe4, 0x4c, 0x51, 0x34, 0x74, 0x6f, 0xa2, 0x61, 0xc2, 0x67, 0x27, 0x1f,
+ 0xfb, 0xe3, 0xaf, 0x91, 0x87, 0x59, 0x7c, 0x60, 0xba, 0xdf, 0x69, 0x02,
+ 0xa6, 0xcb, 0x23, 0x7f, 0x76, 0xd9, 0x93, 0xc5, 0xca, 0x72, 0xe1, 0x6d,
+ 0xff, 0xcf, 0x6c, 0xbd, 0x69, 0xfe, 0x79, 0x1c, 0xf9, 0x25, 0xaf, 0xe5,
+ 0x79, 0xb1, 0x3b, 0xea, 0x45, 0xfc, 0x1f, 0xcd, 0xc7, 0x2d, 0xee, 0x76,
+ 0x6c, 0x8e, 0x9c, 0xcb, 0x74, 0xf4, 0xff, 0xfd, 0x1c, 0x79, 0x9f, 0xc1,
+ 0x36, 0x8d, 0x03, 0x64, 0xfd, 0xea, 0x3b, 0xe6, 0x2a, 0x6b, 0xae, 0xa7,
+ 0x73, 0xed, 0x24, 0x56, 0x96, 0xb9, 0x28, 0xf8, 0x81, 0xd6, 0xa0, 0x9e,
+ 0x46, 0xa9, 0xe0, 0x49, 0x44, 0xea, 0x91, 0xc5, 0x9a, 0xcf, 0x7d, 0x90,
+ 0xdf, 0xbb, 0x78, 0xff, 0x35, 0xcd, 0xd1, 0xf4, 0x2c, 0xa4, 0x06, 0x6b,
+ 0xe3, 0x5e, 0x35, 0xb8, 0x4f, 0xc3, 0x1f, 0x29, 0x54, 0xa6, 0xcc, 0xf6,
+ 0x2a, 0x69, 0x93, 0xad, 0xc5, 0x42, 0x39, 0x6f, 0xe5, 0x49, 0xb2, 0x3a,
+ 0x53, 0x4b, 0x9d, 0x11, 0xec, 0x12, 0xde, 0xb1, 0x80, 0x6b, 0x57, 0x31,
+ 0x34, 0x26, 0x1c, 0xc1, 0x65, 0xf1, 0x20, 0xb5, 0xae, 0xce, 0xb3, 0x1e,
+ 0xca, 0x5c, 0x62, 0x2c, 0xb6, 0xea, 0xb8, 0xd3, 0x86, 0xb7, 0xee, 0xb4,
+ 0x85, 0x97, 0xfe, 0xd9, 0xfd, 0x8d, 0x77, 0xcf, 0x95, 0x77, 0x5f, 0xc8,
+ 0xe6, 0x24, 0x2f, 0xeb, 0x96, 0xba, 0xe1, 0x72, 0xf2, 0xaa, 0x41, 0xc6,
+ 0xf2, 0xcb, 0x83, 0xbf, 0x33, 0xbf, 0xed, 0x88, 0x78, 0xec, 0xa8, 0xf3,
+ 0xf4, 0xe0, 0x9a, 0x99, 0xaa, 0xb2, 0xee, 0xcf, 0x95, 0xf7, 0x0d, 0x9c,
+ 0xd2, 0x3f, 0xb9, 0xc8, 0xdd, 0x75, 0x26, 0xe3, 0x64, 0xdb, 0x32, 0x3b,
+ 0xed, 0x82, 0x32, 0x33, 0xeb, 0x67, 0xd5, 0xb9, 0x6d, 0x4a, 0x3d, 0xb5,
+ 0xa3, 0x0a, 0x47, 0xa8, 0xbf, 0x47, 0xc6, 0xc4, 0xff, 0xa9, 0x38, 0x4c,
+ 0x3b, 0x3d, 0x54, 0xef, 0xeb, 0xbc, 0xcc, 0xb8, 0xf1, 0x43, 0xf2, 0xf9,
+ 0x37, 0x34, 0x6f, 0xfb, 0x29, 0xc9, 0x29, 0x86, 0x1c, 0x38, 0x13, 0xbc,
+ 0x66, 0xe5, 0x78, 0x63, 0x07, 0x54, 0x0c, 0x26, 0xb2, 0xf6, 0xfe, 0x0a,
+ 0xed, 0xf8, 0xc6, 0x99, 0x03, 0x1d, 0x5b, 0x06, 0xc4, 0x3e, 0x1a, 0x2d,
+ 0x3b, 0xba, 0x91, 0x13, 0x12, 0xbc, 0x16, 0xbb, 0x78, 0x42, 0x6a, 0x71,
+ 0x46, 0x0a, 0x0e, 0xca, 0x77, 0x39, 0xf9, 0xae, 0xf8, 0xd8, 0x00, 0x63,
+ 0x5b, 0x07, 0xed, 0xe7, 0x14, 0xe3, 0x0c, 0xce, 0x2d, 0x6c, 0x9a, 0xef,
+ 0x30, 0xee, 0x1a, 0x42, 0x83, 0x7a, 0x02, 0x6b, 0xc8, 0x59, 0xc9, 0x67,
+ 0xc6, 0x9a, 0xb1, 0xd3, 0x8a, 0x9b, 0x7c, 0xea, 0x0a, 0x65, 0x21, 0xd7,
+ 0xdf, 0x8c, 0xee, 0x43, 0xb5, 0xe4, 0x35, 0xa6, 0xb9, 0x5a, 0xff, 0x73,
+ 0x54, 0x0e, 0x74, 0x77, 0x56, 0x52, 0x1e, 0x9f, 0x86, 0x8c, 0x0e, 0x62,
+ 0xfa, 0x86, 0x13, 0x4a, 0xc3, 0xda, 0x98, 0xf2, 0x6d, 0xee, 0x87, 0xe4,
+ 0x41, 0x3c, 0x8c, 0xc7, 0x57, 0xd3, 0x9f, 0xfd, 0x0f, 0xec, 0x50, 0x95,
+ 0x25, 0xb6, 0xb0, 0xf0, 0x41, 0xf8, 0xd5, 0xb0, 0x76, 0xea, 0xa2, 0x7d,
+ 0x33, 0xbd, 0x4f, 0x23, 0xef, 0x89, 0x5f, 0x97, 0xb6, 0x72, 0xb6, 0xbe,
+ 0x13, 0xc7, 0xd3, 0xd4, 0xeb, 0x68, 0x2f, 0x4e, 0xa4, 0x65, 0x4c, 0xe1,
+ 0x53, 0x01, 0xc4, 0x06, 0xec, 0x18, 0xd5, 0x7d, 0x91, 0x72, 0xca, 0xa5,
+ 0x38, 0xe4, 0x8d, 0xac, 0x51, 0x02, 0xe4, 0x6d, 0x69, 0x9c, 0xd9, 0xed,
+ 0x6d, 0xaf, 0x67, 0x8c, 0x18, 0x1d, 0x83, 0xfa, 0xcc, 0xe2, 0x34, 0x4e,
+ 0x0f, 0x3f, 0x04, 0xcf, 0x2c, 0xaf, 0x67, 0xb9, 0xd2, 0x82, 0xad, 0x63,
+ 0xff, 0x51, 0x2e, 0xc9, 0xc3, 0xb1, 0x5b, 0x60, 0x50, 0xf6, 0xdb, 0xd1,
+ 0x3f, 0x57, 0x6c, 0xbe, 0x67, 0xac, 0x14, 0xf3, 0xe8, 0x8f, 0x5e, 0xb2,
+ 0xfc, 0x6c, 0xd6, 0x8e, 0x6a, 0xb4, 0x8f, 0xcc, 0xc7, 0x72, 0x3e, 0xfc,
+ 0xab, 0xe5, 0xf5, 0x77, 0x66, 0x44, 0x15, 0x79, 0xc9, 0x73, 0x35, 0x28,
+ 0x62, 0x3f, 0x3b, 0x72, 0xfe, 0xba, 0x42, 0xfb, 0xbf, 0xe6, 0x43, 0x56,
+ 0x1f, 0x4f, 0xcd, 0x95, 0xa0, 0x60, 0x9b, 0x15, 0xd3, 0xcb, 0xba, 0x75,
+ 0x7c, 0x16, 0x95, 0x9c, 0x86, 0x8a, 0x13, 0xba, 0xe0, 0x48, 0x0b, 0x6d,
+ 0xd5, 0x89, 0x0d, 0x41, 0x9a, 0xa3, 0x95, 0xcf, 0x9f, 0xc4, 0xce, 0xe4,
+ 0xbf, 0x9b, 0xcf, 0x51, 0x8f, 0x56, 0x92, 0xc3, 0x78, 0x88, 0x03, 0x4f,
+ 0x85, 0x56, 0x93, 0x73, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2,
+ 0x89, 0xf6, 0x1f, 0x5a, 0x80, 0x09, 0xab, 0x7d, 0xd5, 0xdc, 0x6c, 0x0e,
+ 0xf1, 0x83, 0xb9, 0xd9, 0x38, 0x50, 0xe4, 0xff, 0x9f, 0x91, 0xdf, 0x2b,
+ 0xa6, 0xa7, 0x52, 0xe4, 0xe7, 0x80, 0x9b, 0x7e, 0x6b, 0x1f, 0xdb, 0x9c,
+ 0xdb, 0xed, 0x40, 0xbf, 0xd6, 0x82, 0xfe, 0x31, 0x78, 0x3e, 0x65, 0x9b,
+ 0x7f, 0x1a, 0x1e, 0x98, 0x9b, 0xe5, 0x0a, 0x6f, 0xa1, 0x3b, 0xfa, 0xbc,
+ 0xb9, 0xac, 0x52, 0xd6, 0xeb, 0x84, 0x9b, 0xeb, 0xdd, 0x77, 0x3d, 0x9f,
+ 0xb7, 0xde, 0x7c, 0xd8, 0xf2, 0x13, 0xbb, 0xe7, 0x4a, 0xbd, 0xec, 0xa7,
+ 0x09, 0x13, 0x97, 0xf4, 0xa3, 0x56, 0x1c, 0x2e, 0xd8, 0xd0, 0x93, 0x90,
+ 0xbd, 0x95, 0xb9, 0x6d, 0xcd, 0xc9, 0xe3, 0xff, 0x54, 0xdf, 0x3c, 0xef,
+ 0x65, 0x39, 0x5d, 0x96, 0x5a, 0x75, 0x9e, 0xe3, 0x8b, 0x2e, 0x8b, 0x1e,
+ 0x5b, 0xef, 0xfd, 0x24, 0xe5, 0xfd, 0xd9, 0x27, 0xd4, 0xdf, 0x73, 0x0c,
+ 0xc9, 0xa9, 0xb4, 0xb0, 0x0f, 0xd3, 0x5c, 0xaf, 0x37, 0x78, 0x4e, 0xe0,
+ 0x8f, 0xa8, 0xdb, 0x3a, 0xb6, 0x0f, 0x48, 0xbe, 0xd5, 0xa3, 0x38, 0xf6,
+ 0xac, 0xc1, 0x25, 0xfa, 0xff, 0x9d, 0x96, 0x1e, 0x0a, 0xae, 0xc8, 0x3c,
+ 0x04, 0x5b, 0xda, 0xe8, 0xc7, 0xad, 0xb3, 0x2e, 0x91, 0x9a, 0x70, 0xa7,
+ 0xf2, 0x61, 0x7d, 0x27, 0x8e, 0x86, 0x0c, 0xb3, 0x5c, 0xf3, 0xaf, 0x65,
+ 0xd0, 0x5f, 0x34, 0xd6, 0x58, 0x88, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2,
+ 0x69, 0xaf, 0x31, 0xc3, 0xae, 0xba, 0x5e, 0x4e, 0xe7, 0xb0, 0xd2, 0xf6,
+ 0xc0, 0x5c, 0x89, 0x97, 0x92, 0x16, 0x8e, 0x7c, 0x1d, 0xf7, 0x59, 0x7b,
+ 0xab, 0xd2, 0x87, 0x4a, 0xbe, 0xf7, 0x68, 0xe8, 0x4a, 0x54, 0x30, 0xc5,
+ 0x5c, 0xd2, 0x1c, 0x6a, 0x50, 0xb7, 0xe3, 0x4e, 0x62, 0xd7, 0x12, 0x9c,
+ 0xd1, 0xa5, 0xae, 0x61, 0x7c, 0xdb, 0x01, 0xa9, 0xc1, 0x1d, 0x0e, 0x6d,
+ 0x8d, 0x2e, 0xc5, 0xbe, 0x01, 0x43, 0x71, 0x86, 0xbd, 0x91, 0x18, 0xb9,
+ 0x10, 0xe3, 0x71, 0x2b, 0xdf, 0x27, 0xf9, 0x84, 0xc1, 0xc6, 0x4e, 0x6c,
+ 0xd7, 0x0b, 0xd1, 0xa3, 0x47, 0x8a, 0xb6, 0x2c, 0xee, 0xc2, 0x7e, 0xbd,
+ 0xd4, 0x98, 0x17, 0x36, 0x88, 0xe9, 0xda, 0x86, 0x24, 0xfc, 0x2d, 0x17,
+ 0xc9, 0x39, 0x8e, 0xc3, 0xdb, 0xb1, 0xc4, 0x4e, 0xcc, 0xbd, 0xc7, 0xe1,
+ 0x8a, 0x65, 0x9a, 0x90, 0x18, 0xab, 0x72, 0xed, 0xc8, 0x04, 0x11, 0x1f,
+ 0xe3, 0x7e, 0x33, 0xae, 0x75, 0x64, 0x96, 0x92, 0x83, 0x8a, 0x1c, 0xed,
+ 0xd4, 0xc5, 0x7a, 0x3c, 0xd3, 0x7a, 0xc1, 0x7c, 0xd2, 0x2f, 0xf8, 0x59,
+ 0x8b, 0x67, 0x55, 0x9f, 0xc5, 0x29, 0x23, 0xb6, 0xaf, 0xb2, 0x0f, 0x3b,
+ 0x75, 0xee, 0x55, 0xd3, 0xf3, 0xa8, 0xc8, 0x8d, 0xc1, 0x56, 0xf1, 0x6a,
+ 0xe2, 0xa7, 0xfc, 0x2d, 0xb2, 0x13, 0x19, 0x9a, 0x58, 0xa7, 0x4b, 0x2e,
+ 0xaf, 0x91, 0x36, 0xe3, 0xc6, 0xdb, 0xea, 0x8d, 0x7d, 0x78, 0x5a, 0xf7,
+ 0xe9, 0x87, 0x20, 0x39, 0xbc, 0xff, 0xce, 0xe7, 0x24, 0xdf, 0xd2, 0x84,
+ 0x17, 0x2b, 0xb2, 0xf1, 0x87, 0xc7, 0x56, 0x42, 0xdc, 0xcd, 0xfb, 0x11,
+ 0xb9, 0xef, 0x4d, 0x46, 0xa8, 0xa7, 0x1b, 0x83, 0x53, 0x66, 0xa4, 0xd2,
+ 0xe8, 0x94, 0xb3, 0x28, 0xee, 0xf0, 0xea, 0x17, 0xdd, 0xf5, 0xde, 0x8e,
+ 0x29, 0x05, 0x38, 0x13, 0xa3, 0x1f, 0xb6, 0xfe, 0xbb, 0x47, 0xe9, 0xdb,
+ 0x89, 0xa1, 0xe0, 0x1d, 0x68, 0x6f, 0x93, 0xb1, 0x9a, 0xd1, 0xbb, 0xd7,
+ 0x34, 0x4b, 0x43, 0x3e, 0x35, 0x0d, 0x27, 0x56, 0x04, 0xed, 0xb8, 0xa0,
+ 0x9a, 0x70, 0x84, 0xfe, 0xdd, 0xcc, 0xd0, 0x3f, 0x0e, 0xd3, 0x4e, 0x76,
+ 0x50, 0xc7, 0xe4, 0x5d, 0x28, 0x3f, 0xed, 0x24, 0x4e, 0x3b, 0x39, 0x13,
+ 0x9a, 0x9f, 0x7b, 0x57, 0x52, 0x23, 0xaf, 0x98, 0xc4, 0x92, 0x01, 0x15,
+ 0x9f, 0xde, 0x33, 0x89, 0xd0, 0x50, 0x7e, 0xee, 0x62, 0x97, 0xf9, 0xf9,
+ 0x4b, 0x6d, 0x50, 0xe6, 0x2e, 0x73, 0x94, 0xb5, 0xc8, 0xdf, 0xf9, 0x7b,
+ 0xf9, 0xdf, 0xc4, 0xcf, 0x3a, 0xd1, 0x6a, 0xad, 0xed, 0x2f, 0x6a, 0xb2,
+ 0x98, 0x91, 0x5f, 0x93, 0xeb, 0x96, 0xeb, 0x4b, 0xb7, 0x5c, 0x3f, 0xee,
+ 0xbe, 0xf9, 0x7a, 0xfb, 0x9c, 0x9b, 0xaf, 0xf3, 0x36, 0x71, 0x43, 0xae,
+ 0x1d, 0xba, 0x6f, 0xe2, 0x28, 0xd7, 0x3a, 0x63, 0xc1, 0x21, 0xf3, 0x42,
+ 0x85, 0xcc, 0x45, 0x62, 0xd6, 0xec, 0x5c, 0x97, 0x65, 0xa6, 0xcf, 0xf5,
+ 0xcd, 0x5c, 0x6d, 0xc0, 0x3a, 0xf7, 0x4b, 0xbb, 0xd1, 0xe4, 0x1d, 0xdf,
+ 0xdc, 0x3b, 0x74, 0xd9, 0xb3, 0x88, 0xa5, 0xe1, 0x80, 0xd2, 0x1b, 0x33,
+ 0xcc, 0x19, 0x5a, 0xb1, 0x21, 0xef, 0x4a, 0xa9, 0x7e, 0x03, 0x25, 0x7e,
+ 0x6d, 0xc3, 0x0c, 0x5b, 0x17, 0x9c, 0x0b, 0xb5, 0x8e, 0x3f, 0x53, 0x92,
+ 0x88, 0x67, 0xbc, 0x81, 0x43, 0x94, 0x55, 0x2c, 0x73, 0x95, 0x71, 0x75,
+ 0x17, 0x9e, 0x09, 0x39, 0x8c, 0xe2, 0xb0, 0xd7, 0x3d, 0x5f, 0x59, 0x86,
+ 0xed, 0x43, 0x7f, 0x8e, 0xf5, 0x49, 0xe1, 0xf8, 0xb5, 0xd8, 0x32, 0x66,
+ 0xc3, 0x31, 0xea, 0x77, 0x2f, 0xc7, 0x21, 0xfe, 0xb9, 0x53, 0x90, 0xb3,
+ 0x79, 0x8d, 0x8c, 0x91, 0x75, 0xeb, 0xb3, 0x75, 0xe8, 0x75, 0xac, 0x8f,
+ 0x9a, 0xf8, 0x54, 0xa7, 0xef, 0xd1, 0x64, 0x7e, 0x12, 0x3b, 0xb7, 0x5a,
+ 0x58, 0xfa, 0x48, 0x9c, 0xfb, 0x39, 0x4b, 0x6c, 0x75, 0x29, 0x6d, 0x56,
+ 0xc1, 0x67, 0x52, 0x77, 0xac, 0xe4, 0x9c, 0xc9, 0x0d, 0xc7, 0xa3, 0x9b,
+ 0x30, 0x1c, 0x35, 0xe4, 0x7d, 0xc0, 0xde, 0x1a, 0x7b, 0xe4, 0x85, 0x0a,
+ 0xf2, 0xec, 0x84, 0xee, 0x6f, 0x3f, 0xa7, 0xc0, 0x53, 0x16, 0xf6, 0xd3,
+ 0xcf, 0x7c, 0x89, 0xdf, 0xea, 0x92, 0x4f, 0xd3, 0x5d, 0xab, 0xa8, 0xef,
+ 0x7b, 0x86, 0x02, 0x56, 0x7e, 0xe0, 0xef, 0x6e, 0x9b, 0xbf, 0x90, 0x1a,
+ 0xb3, 0x9e, 0xcb, 0x35, 0xbe, 0x8e, 0x83, 0x69, 0x17, 0x1e, 0x8b, 0x7b,
+ 0x94, 0x79, 0x7b, 0x54, 0xdc, 0x1f, 0xf7, 0x4e, 0x2c, 0xb1, 0x93, 0x7f,
+ 0x2c, 0x9a, 0xc1, 0xfe, 0x14, 0xfc, 0x68, 0xa1, 0xf8, 0x82, 0xff, 0x0a,
+ 0x63, 0x56, 0x84, 0x7d, 0xa2, 0xb4, 0x60, 0xb1, 0x57, 0x3d, 0x68, 0xf3,
+ 0xb9, 0x7f, 0x8b, 0xad, 0xb0, 0x67, 0x56, 0xa3, 0x9b, 0xf3, 0x5f, 0x19,
+ 0x97, 0x9a, 0x55, 0x03, 0x50, 0xd1, 0x8c, 0x1d, 0x87, 0xc4, 0x36, 0xe5,
+ 0x9d, 0x75, 0x78, 0xaa, 0xc2, 0x2d, 0x77, 0xa0, 0xf8, 0x4b, 0x72, 0xed,
+ 0x49, 0x89, 0x3f, 0x37, 0x94, 0xdb, 0x4c, 0xc6, 0x2f, 0xf3, 0x73, 0x35,
+ 0x89, 0xa5, 0xd8, 0x3a, 0x20, 0xf9, 0x76, 0xe2, 0xb6, 0xce, 0x38, 0xa8,
+ 0x42, 0x0b, 0x3c, 0x65, 0x93, 0x3a, 0xd0, 0x26, 0xf8, 0x62, 0x9b, 0x10,
+ 0x88, 0x89, 0xcd, 0x6a, 0x6a, 0x07, 0x22, 0xa7, 0x25, 0xcf, 0x37, 0x2f,
+ 0xe4, 0xe7, 0xbc, 0xfc, 0xbd, 0x55, 0x76, 0xdd, 0xf5, 0xca, 0xa8, 0x8a,
+ 0x09, 0x35, 0x1b, 0x47, 0x1e, 0x4a, 0x6a, 0x6b, 0x0b, 0x6d, 0x72, 0x26,
+ 0xe2, 0xb2, 0x19, 0xb1, 0xfa, 0x55, 0x6a, 0x51, 0xde, 0x8c, 0xbe, 0xbd,
+ 0xef, 0xd2, 0x07, 0xc9, 0x18, 0xbf, 0x37, 0x9d, 0xd4, 0xcb, 0xe5, 0x6d,
+ 0x1e, 0xdc, 0x17, 0x97, 0x3c, 0x69, 0x4f, 0x75, 0xf6, 0x4c, 0x87, 0x5c,
+ 0x3b, 0xd0, 0xa1, 0x13, 0x64, 0x67, 0x7d, 0x61, 0x56, 0x59, 0x71, 0xe9,
+ 0x97, 0x59, 0x9d, 0x49, 0xdc, 0x7d, 0x87, 0xd8, 0x78, 0xcf, 0x58, 0x83,
+ 0x3b, 0xab, 0x77, 0x4d, 0xbc, 0x96, 0xbe, 0xb4, 0x7d, 0x9b, 0xe4, 0x34,
+ 0x2e, 0xf9, 0xcc, 0x23, 0xa3, 0xd3, 0xdb, 0xe7, 0x73, 0x30, 0x55, 0x39,
+ 0x4e, 0x95, 0xd7, 0x37, 0xa9, 0xf5, 0x45, 0x94, 0x87, 0xa3, 0x2d, 0xca,
+ 0xaa, 0xa8, 0xd4, 0xfb, 0x6c, 0xd1, 0x12, 0xeb, 0x5c, 0xab, 0x89, 0xef,
+ 0x85, 0xc6, 0x95, 0x6d, 0xd6, 0x99, 0x59, 0x43, 0x49, 0x36, 0x02, 0x95,
+ 0xa3, 0xcd, 0xca, 0xf6, 0xe8, 0x27, 0xe6, 0x53, 0x56, 0x5d, 0x7d, 0xa6,
+ 0x75, 0xbe, 0xa6, 0x70, 0xd4, 0x85, 0x8a, 0x83, 0x25, 0x28, 0x18, 0xd4,
+ 0x30, 0x73, 0xf4, 0x41, 0xf2, 0x56, 0xe1, 0x3a, 0x46, 0x8b, 0xc3, 0x3a,
+ 0xa3, 0xf6, 0xfa, 0xf5, 0x33, 0x6a, 0x0e, 0xe2, 0x82, 0x01, 0xeb, 0x1f,
+ 0x63, 0xa5, 0xc3, 0x8c, 0x95, 0xcc, 0x25, 0xdf, 0x0b, 0x19, 0x3b, 0x66,
+ 0xc2, 0x1b, 0xa8, 0xb4, 0x19, 0xa6, 0xe4, 0x6e, 0x5e, 0x21, 0x61, 0x5c,
+ 0x53, 0x67, 0x60, 0x45, 0x9d, 0xbc, 0x9b, 0xe9, 0x30, 0xec, 0xe1, 0x2e,
+ 0x1c, 0x0e, 0x75, 0xe1, 0x3d, 0xbd, 0x0b, 0x3b, 0xf5, 0x62, 0xa3, 0x3c,
+ 0x5c, 0x2a, 0x67, 0xd9, 0x27, 0xa2, 0xd0, 0xf4, 0xb4, 0xa2, 0x9d, 0xba,
+ 0x0a, 0xef, 0x3e, 0x9f, 0xe2, 0x35, 0x96, 0x29, 0x1a, 0x2e, 0x67, 0xbc,
+ 0x53, 0xe5, 0xb4, 0x81, 0x6b, 0x99, 0x00, 0xa6, 0x88, 0xab, 0xc9, 0x31,
+ 0x39, 0x4f, 0x52, 0x8b, 0x81, 0xb1, 0xff, 0x29, 0xdc, 0xc0, 0x20, 0x26,
+ 0x59, 0x67, 0x2a, 0x9f, 0x93, 0x5a, 0xa6, 0x33, 0x98, 0xe3, 0x30, 0x86,
+ 0xb2, 0xae, 0xb1, 0x0c, 0xd7, 0xe8, 0x9d, 0x7e, 0x98, 0xee, 0x64, 0x3c,
+ 0x87, 0xd7, 0x6a, 0x60, 0xff, 0xbe, 0x1b, 0xf5, 0xc9, 0x19, 0x38, 0x56,
+ 0x5f, 0x89, 0x02, 0x1c, 0x1d, 0xee, 0x20, 0xc7, 0xef, 0x6e, 0x2f, 0x67,
+ 0x7c, 0x3a, 0x3a, 0xec, 0x44, 0x2a, 0x25, 0x39, 0x07, 0xab, 0x36, 0x39,
+ 0xe9, 0xa0, 0x2d, 0xed, 0x4a, 0xa0, 0xbe, 0x26, 0xec, 0x4f, 0xd6, 0xd8,
+ 0x55, 0xf6, 0x51, 0x85, 0x54, 0x5a, 0xe3, 0x27, 0xc0, 0x4f, 0x90, 0x9f,
+ 0x26, 0x7c, 0x8f, 0x36, 0x5b, 0x41, 0xbc, 0x7d, 0x35, 0x5d, 0x86, 0x4f,
+ 0x92, 0x5a, 0x40, 0xa7, 0x1e, 0x0c, 0x33, 0x46, 0x30, 0x2c, 0x39, 0x95,
+ 0xe1, 0x2a, 0xed, 0xf4, 0xa5, 0x50, 0x19, 0xcc, 0xd4, 0xed, 0x62, 0x42,
+ 0x79, 0xff, 0x25, 0x7f, 0x0e, 0x33, 0x5b, 0x5f, 0x3d, 0x92, 0x81, 0xf2,
+ 0x78, 0x9d, 0x41, 0x7d, 0x61, 0x0c, 0xbb, 0x48, 0x6a, 0x29, 0x5a, 0xe7,
+ 0x25, 0x7b, 0xb1, 0x51, 0x13, 0xf6, 0x7a, 0x6a, 0xec, 0x1a, 0xce, 0xa5,
+ 0x27, 0x11, 0x4f, 0xca, 0xbb, 0x6d, 0xa2, 0xc7, 0xef, 0x9b, 0x46, 0x85,
+ 0x9c, 0xc9, 0xe8, 0x44, 0x5c, 0xab, 0x64, 0x1c, 0x24, 0xef, 0x3e, 0x1e,
+ 0x0e, 0x45, 0x63, 0xa5, 0xf2, 0x9e, 0xf0, 0x92, 0x97, 0x43, 0xde, 0x96,
+ 0x7e, 0xc5, 0x78, 0xa8, 0xc4, 0x7a, 0xaf, 0xa3, 0x8b, 0x58, 0xac, 0xa9,
+ 0x4e, 0xc5, 0xdb, 0xb4, 0x05, 0x01, 0x1c, 0x4b, 0x8b, 0xdc, 0x28, 0xa7,
+ 0xb1, 0xac, 0xdc, 0x6e, 0x9c, 0x9d, 0xce, 0xea, 0xc1, 0xc6, 0xa8, 0x83,
+ 0xdf, 0xb2, 0xf7, 0x72, 0xae, 0x95, 0x3e, 0xc2, 0xda, 0xff, 0x9f, 0xdf,
+ 0x91, 0x3b, 0xbf, 0xda, 0x5e, 0x19, 0x76, 0x05, 0x97, 0xc7, 0xed, 0x9f,
+ 0xc8, 0xfb, 0xc8, 0x4f, 0x34, 0xca, 0x7b, 0x6b, 0xae, 0xe0, 0xe3, 0xa3,
+ 0xae, 0xe0, 0xda, 0xf8, 0x51, 0x85, 0xf2, 0xda, 0x57, 0x63, 0x77, 0x05,
+ 0x1f, 0xb9, 0xd1, 0x9e, 0xfb, 0xde, 0x85, 0xb1, 0x50, 0xb1, 0xa1, 0x86,
+ 0xc5, 0xa7, 0x7b, 0x03, 0x9f, 0x28, 0x96, 0x2f, 0x37, 0x4a, 0xe8, 0x63,
+ 0x9f, 0xcf, 0x8c, 0x9b, 0xed, 0xb3, 0x04, 0xab, 0xec, 0x1c, 0xeb, 0x2a,
+ 0x5e, 0x49, 0xdd, 0x78, 0xae, 0x85, 0xcf, 0x15, 0xf3, 0xb9, 0x92, 0xb0,
+ 0xc4, 0x8d, 0x5e, 0x7d, 0x95, 0xa2, 0x79, 0x8a, 0x14, 0xa9, 0x87, 0x69,
+ 0xf8, 0x55, 0xfa, 0x9f, 0xef, 0x90, 0x78, 0xb7, 0x67, 0xac, 0x12, 0x6b,
+ 0x76, 0x9b, 0x4b, 0xe6, 0x2d, 0x34, 0x97, 0xa4, 0x43, 0x31, 0xf3, 0xa5,
+ 0x6a, 0xd9, 0x4f, 0xa9, 0xf1, 0xc9, 0x33, 0x9a, 0xea, 0x63, 0x9c, 0xf9,
+ 0x4d, 0x7d, 0xbb, 0xbc, 0xa3, 0x07, 0x79, 0x7f, 0xa9, 0x90, 0x63, 0x9c,
+ 0x4c, 0x89, 0x8e, 0x6c, 0x6d, 0x77, 0x31, 0x16, 0x95, 0x77, 0x67, 0x0f,
+ 0x73, 0xef, 0x0f, 0xa6, 0xfe, 0xd7, 0x1d, 0x72, 0x76, 0x5d, 0xce, 0x06,
+ 0x00, 0xff, 0x1f, 0x17, 0x23, 0xca, 0x76, 0xf8, 0x78, 0x00, 0x00, 0x00 };
static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_RXP_b09FwRodata[(0xf0/4) + 1] = {
+static const u32 bnx2_RXP_b09FwRodata[(0x124/4) + 1] = {
0x5f865437, 0xe4ac62cc, 0x50103a45, 0x36621985, 0xbf14c0e8, 0x1bc27a1e,
0x84f4b556, 0x094ea6fe, 0x7dda01e7, 0xc04d7481, 0x80080100, 0x80080080,
- 0x80080000, 0x08004efc, 0x08004efc, 0x08004fd8, 0x08004fac, 0x08004f90,
- 0x08004ecc, 0x08004ecc, 0x08004ecc, 0x08004f04, 0x08007220, 0x0800726c,
- 0x0800722c, 0x08007150, 0x0800722c, 0x0800725c, 0x0800722c, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x0800724c, 0x0800723c, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x0800723c,
- 0x080077f4, 0x080076bc, 0x080077bc, 0x08007718, 0x080076e8, 0x080075a4,
- 0x00000000 };
+ 0x80080000, 0x08004fbc, 0x08004fbc, 0x08005098, 0x0800506c, 0x08005050,
+ 0x08004f8c, 0x08004f8c, 0x08004f8c, 0x08004fc4, 0x080072ac, 0x080072f8,
+ 0x080072b8, 0x080071dc, 0x080072b8, 0x080072e8, 0x080072b8, 0x080071dc,
+ 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc,
+ 0x080071dc, 0x080071dc, 0x080071dc, 0x080072d8, 0x080072c8, 0x080071dc,
+ 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc,
+ 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080072c8,
+ 0x0800787c, 0x08007748, 0x08007844, 0x08007748, 0x08007814, 0x08007630,
+ 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748,
+ 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748,
+ 0x08007770, 0x00000000 };
static struct fw_info bnx2_rxp_fw_09 = {
- /* Firmware version: 4.4.23 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
- .start_addr = 0x080031d0,
+ .start_addr = 0x080031d8,
.text_addr = 0x08000000,
- .text_len = 0x786c,
+ .text_len = 0x78f4,
.text_index = 0x0,
.gz_text = bnx2_RXP_b09FwText,
.gz_text_len = sizeof(bnx2_RXP_b09FwText),
@@ -3158,548 +3148,492 @@ static struct fw_info bnx2_rxp_fw_09 = {
.data_index = 0x0,
.data = bnx2_RXP_b09FwData,
- .sbss_addr = 0x08007980,
+ .sbss_addr = 0x08007a40,
.sbss_len = 0x58,
.sbss_index = 0x0,
- .bss_addr = 0x080079d8,
- .bss_len = 0x1c,
+ .bss_addr = 0x08007a98,
+ .bss_len = 0x20,
.bss_index = 0x0,
- .rodata_addr = 0x0800786c,
- .rodata_len = 0xf0,
+ .rodata_addr = 0x080078f4,
+ .rodata_len = 0x124,
.rodata_index = 0x0,
.rodata = bnx2_RXP_b09FwRodata,
};
static u8 bnx2_xi_rv2p_proc1[] = {
- /* Date: 06/17/2008 16:52 */
- 0xbd, 0x56, 0xcf, 0x6b, 0x1c, 0x75, 0x14, 0x7f, 0x3b, 0xbb, 0x33, 0x3b,
- 0x99, 0x9d, 0xdd, 0x99, 0xda, 0x34, 0x4c, 0xb7, 0x2b, 0xd9, 0x86, 0x5e,
- 0x36, 0x99, 0x62, 0xa2, 0x11, 0x0a, 0x46, 0x5b, 0x72, 0x09, 0xd8, 0x9e,
- 0x02, 0x95, 0x22, 0x82, 0x71, 0xa9, 0x3d, 0xd8, 0x96, 0xe2, 0x5f, 0xe0,
- 0x90, 0x9a, 0x08, 0x45, 0x0f, 0x0b, 0x36, 0x90, 0x20, 0x1a, 0x7b, 0x50,
- 0x09, 0x0a, 0x3b, 0x07, 0x41, 0x44, 0x2d, 0xa8, 0x88, 0x60, 0x3d, 0x08,
- 0x85, 0xda, 0x8b, 0x51, 0x8b, 0x8a, 0x07, 0x0f, 0x01, 0x8f, 0x9a, 0xf1,
- 0xfb, 0x7e, 0x7c, 0x37, 0x33, 0x93, 0xdd, 0x24, 0x27, 0x03, 0xed, 0x87,
- 0xf7, 0x9d, 0xf7, 0x7d, 0xdf, 0xf7, 0xde, 0xf7, 0xf3, 0x3e, 0xdf, 0xf5,
- 0x01, 0xc0, 0x80, 0x28, 0x1e, 0x55, 0x08, 0x87, 0x8c, 0xa2, 0xad, 0xa0,
- 0x00, 0xf0, 0x21, 0xf0, 0x9f, 0xe9, 0x92, 0x1d, 0x3d, 0x22, 0xf6, 0x04,
- 0x43, 0x34, 0xe1, 0xab, 0xff, 0xaf, 0xc2, 0xe9, 0x26, 0x62, 0x11, 0x4e,
- 0x1f, 0x47, 0x7c, 0x12, 0x6e, 0x37, 0x03, 0x85, 0xff, 0x26, 0x10, 0xa1,
- 0x3d, 0xdc, 0xfd, 0x24, 0xae, 0x50, 0xfc, 0x4d, 0xd9, 0xff, 0x63, 0x91,
- 0xf1, 0x54, 0x68, 0x73, 0x1c, 0x41, 0x38, 0xe9, 0x13, 0xdc, 0xed, 0xa0,
- 0x7d, 0xfe, 0x3c, 0x58, 0x18, 0xe7, 0x6d, 0xe5, 0x80, 0x76, 0xa3, 0x10,
- 0x9d, 0x94, 0xbc, 0x0c, 0xf6, 0xfb, 0xa9, 0xe3, 0xe1, 0x3a, 0xfc, 0x3c,
- 0x8b, 0xf6, 0x51, 0xe7, 0xd5, 0x0e, 0x62, 0x00, 0x97, 0x6c, 0x97, 0xeb,
- 0x19, 0xe5, 0xb0, 0x9b, 0xe3, 0xb8, 0x4f, 0xf9, 0x8e, 0x4b, 0x5c, 0x13,
- 0xe3, 0xfe, 0x99, 0x70, 0x5c, 0x8c, 0x97, 0x8e, 0xd3, 0x50, 0x71, 0x70,
- 0xdd, 0x92, 0xbc, 0xac, 0x5c, 0x5e, 0x96, 0xca, 0x43, 0xfa, 0x00, 0x3a,
- 0x0f, 0xc4, 0x23, 0xea, 0x5c, 0x8c, 0xbb, 0x25, 0x75, 0x03, 0x3c, 0xdf,
- 0x94, 0xf8, 0x31, 0xa2, 0x5b, 0xe0, 0x78, 0xea, 0x9f, 0xd4, 0xb1, 0x3b,
- 0x8e, 0xee, 0x53, 0x36, 0xff, 0x72, 0xa8, 0xbf, 0xeb, 0xfb, 0xc0, 0x73,
- 0x7e, 0x50, 0xe7, 0xa4, 0xfd, 0x61, 0x1f, 0xff, 0xef, 0x94, 0x7f, 0x36,
- 0x2e, 0xaf, 0x7f, 0xbb, 0xb3, 0xde, 0xea, 0xd7, 0x37, 0x33, 0xd7, 0xb7,
- 0x2f, 0xa5, 0x6f, 0x73, 0x70, 0xc2, 0x08, 0xc8, 0xaf, 0x04, 0x88, 0xc7,
- 0x54, 0x02, 0x88, 0x0f, 0x0b, 0x5e, 0x13, 0xbc, 0x25, 0xf8, 0xae, 0xe0,
- 0x11, 0xc1, 0x61, 0xc1, 0xc3, 0x82, 0x0f, 0x09, 0x6e, 0x09, 0xfa, 0x82,
- 0x9e, 0x60, 0x4d, 0xf0, 0x2f, 0x41, 0x57, 0xb0, 0x92, 0x8b, 0x57, 0x17,
- 0xb4, 0x05, 0x3f, 0x17, 0x7c, 0x22, 0xb7, 0xff, 0x68, 0x81, 0xf1, 0x81,
- 0xd8, 0x4f, 0x89, 0x7d, 0x41, 0x6c, 0x6c, 0xa8, 0xf0, 0x3e, 0xd3, 0xaf,
- 0x5b, 0xbd, 0xfb, 0xbd, 0xdb, 0x91, 0xef, 0x2d, 0xed, 0x67, 0x53, 0xff,
- 0x60, 0x3c, 0xed, 0xff, 0xd6, 0x1e, 0xfe, 0xec, 0x36, 0xdb, 0xea, 0xb7,
- 0xef, 0x66, 0xc2, 0x79, 0xbc, 0x29, 0xfb, 0x83, 0xee, 0x67, 0x03, 0xe6,
- 0x68, 0x26, 0xcc, 0xf3, 0xab, 0xdf, 0x1c, 0x3d, 0x2e, 0x73, 0x34, 0xbd,
- 0x8b, 0xbf, 0xcc, 0xd3, 0x33, 0xb2, 0x7f, 0x46, 0xf8, 0xd9, 0x18, 0xe0,
- 0x17, 0xa5, 0xe6, 0x95, 0xce, 0x1b, 0x30, 0x0f, 0x1f, 0x15, 0xda, 0x61,
- 0xc0, 0xfc, 0x89, 0xf6, 0xca, 0x0f, 0xf7, 0x0b, 0x7f, 0x5b, 0x9a, 0xc7,
- 0x59, 0xfe, 0x32, 0x0f, 0xad, 0x1c, 0x0f, 0x5f, 0xde, 0xe7, 0x1e, 0x2a,
- 0xb9, 0x7e, 0x5e, 0x56, 0xfe, 0x6c, 0x1a, 0x06, 0xe3, 0x1a, 0x63, 0xe8,
- 0x5a, 0x25, 0xc4, 0x69, 0xf7, 0x1b, 0x8e, 0x37, 0x4a, 0x75, 0xb8, 0xc1,
- 0x0a, 0xcd, 0x6d, 0x09, 0x56, 0xac, 0x21, 0x85, 0xff, 0x24, 0x6f, 0xb0,
- 0x5f, 0xdd, 0xfc, 0x9e, 0x30, 0x58, 0xbb, 0xc3, 0xfe, 0xf7, 0x9a, 0x9c,
- 0xf7, 0x33, 0x13, 0x90, 0xfb, 0xd3, 0xdf, 0x65, 0xde, 0x3d, 0xb4, 0xff,
- 0x2e, 0x44, 0xb1, 0x3e, 0x47, 0xf6, 0x5d, 0xd6, 0x73, 0xc4, 0x7f, 0x8b,
- 0x96, 0x4f, 0xf5, 0xde, 0x88, 0xc9, 0x1c, 0x76, 0x97, 0x7d, 0xfa, 0xfa,
- 0x7a, 0xac, 0xeb, 0x11, 0x5d, 0x19, 0xd7, 0xf5, 0xf3, 0xfe, 0x2a, 0x9d,
- 0x77, 0xb8, 0xbb, 0x9e, 0xe3, 0x49, 0xf3, 0x40, 0x3a, 0xbb, 0x95, 0xec,
- 0xe8, 0x6c, 0xba, 0x0f, 0x5a, 0x67, 0x6d, 0x58, 0x98, 0xf3, 0xe8, 0xdc,
- 0x9a, 0xc5, 0x61, 0x2e, 0x78, 0x8c, 0x17, 0x1d, 0xc6, 0xdf, 0x1c, 0xec,
- 0x53, 0x92, 0x5c, 0xaa, 0xb0, 0xfd, 0x42, 0x55, 0xcf, 0xb7, 0xde, 0xaf,
- 0xf3, 0xda, 0x2b, 0x1f, 0x3c, 0x5f, 0x9f, 0xa3, 0xf3, 0xd0, 0xe7, 0x65,
- 0x79, 0x31, 0xf8, 0x5c, 0xc6, 0xb6, 0x91, 0xed, 0xc3, 0xda, 0x24, 0x63,
- 0x69, 0x0a, 0xf3, 0xba, 0x9d, 0xf4, 0xe6, 0xbb, 0xe5, 0x93, 0xdf, 0x18,
- 0xb0, 0x3d, 0x2f, 0x3c, 0x9c, 0xa7, 0xb9, 0x54, 0xba, 0x63, 0x20, 0xd6,
- 0x21, 0xa2, 0x77, 0xc7, 0x70, 0xbe, 0x26, 0x5e, 0x14, 0x65, 0x5d, 0xdd,
- 0xc3, 0x58, 0x76, 0x9e, 0x37, 0x99, 0x77, 0x76, 0x96, 0xaf, 0xc7, 0x84,
- 0xaf, 0x4e, 0x77, 0xbd, 0xb3, 0xdf, 0x3c, 0x48, 0xc1, 0xbd, 0xfe, 0x6b,
- 0x3d, 0xd4, 0xef, 0xb2, 0xd6, 0x3d, 0xfa, 0xdc, 0x8d, 0x8a, 0x99, 0x3a,
- 0xcf, 0x40, 0xd8, 0xef, 0x7e, 0x3f, 0x16, 0x3d, 0x99, 0x16, 0x7d, 0x53,
- 0x97, 0x18, 0x65, 0xf6, 0xd5, 0x80, 0xf2, 0x29, 0xe7, 0xe6, 0xac, 0xd4,
- 0x9b, 0x9b, 0x45, 0x6b, 0x80, 0xde, 0x99, 0xfc, 0x7e, 0x2e, 0xcc, 0xe1,
- 0xb9, 0x76, 0xe3, 0x06, 0xcd, 0x7f, 0x19, 0xfe, 0x70, 0xf9, 0x5e, 0xda,
- 0x26, 0xda, 0xe6, 0xf0, 0x95, 0x4f, 0x33, 0xfd, 0x01, 0x38, 0xae, 0xdf,
- 0x97, 0xf4, 0x1c, 0x07, 0xd0, 0x9e, 0x3a, 0xe8, 0x7b, 0x99, 0xe6, 0x7d,
- 0x6d, 0x17, 0xef, 0xb5, 0x3e, 0x36, 0xc3, 0xf4, 0x9c, 0xe0, 0x3b, 0xc1,
- 0xf7, 0xcd, 0xfa, 0x54, 0xc9, 0xf7, 0x41, 0xbd, 0x9f, 0xba, 0xbe, 0x7e,
- 0xef, 0xe8, 0xaf, 0xdb, 0x07, 0xd3, 0xb3, 0x74, 0x9f, 0xfa, 0xe9, 0x99,
- 0x93, 0xd3, 0xa7, 0x7b, 0xdb, 0x3d, 0x7d, 0x32, 0xfb, 0xd5, 0xff, 0x7f,
- 0xe8, 0x36, 0xf7, 0xd3, 0x81, 0x74, 0x3d, 0x1b, 0x1b, 0xcc, 0x9f, 0xab,
- 0xa9, 0x79, 0x49, 0xdf, 0xff, 0x90, 0xf0, 0x45, 0xf9, 0x51, 0x1d, 0x5f,
- 0x6c, 0xef, 0xe8, 0x72, 0x9a, 0x7f, 0x2f, 0x0a, 0xff, 0x8d, 0x99, 0x75,
- 0xe6, 0x47, 0xfb, 0xf7, 0xdc, 0x7d, 0x4d, 0x85, 0xc8, 0x97, 0x57, 0x20,
- 0x96, 0x3c, 0xef, 0x67, 0xf2, 0xad, 0x8a, 0x2e, 0x95, 0xe1, 0x83, 0x58,
- 0xd7, 0xc5, 0x9f, 0x9b, 0x21, 0xe3, 0xfb, 0xe4, 0xef, 0xef, 0xf3, 0x2e,
- 0xf9, 0xf0, 0x5e, 0x4f, 0x7f, 0x3d, 0x8a, 0x37, 0x29, 0x3a, 0xb6, 0x20,
- 0x7a, 0xf2, 0x8b, 0xc3, 0x7a, 0xd5, 0x3e, 0x4b, 0xfc, 0x85, 0x11, 0xd1,
- 0x95, 0x76, 0x95, 0xed, 0x7a, 0x95, 0x7f, 0xef, 0x4e, 0x96, 0x5d, 0xf2,
- 0xab, 0x57, 0x19, 0x47, 0x2a, 0xb8, 0x2f, 0x80, 0x07, 0xe7, 0xc8, 0x3d,
- 0x5c, 0x75, 0xf9, 0x5d, 0x59, 0xbd, 0x23, 0x7a, 0xe7, 0xe9, 0xfe, 0x49,
- 0xbd, 0x8f, 0xe1, 0xfa, 0x88, 0xd2, 0x0f, 0xb6, 0x99, 0x17, 0x6e, 0x6f,
- 0x1e, 0xde, 0x91, 0xec, 0x9b, 0x5e, 0xba, 0xdf, 0x7a, 0x2e, 0x3b, 0xb9,
- 0x3e, 0xeb, 0x7b, 0x3a, 0x95, 0x68, 0xbd, 0x1d, 0x9b, 0xc3, 0x7c, 0x3d,
- 0xa8, 0x95, 0x99, 0x47, 0x8c, 0x2a, 0x8e, 0x51, 0xc6, 0x6d, 0x8d, 0x25,
- 0xd1, 0xaf, 0xa5, 0x45, 0x0a, 0x73, 0x6e, 0x49, 0xaf, 0xcf, 0xd2, 0xe0,
- 0xcc, 0x6f, 0x7c, 0x45, 0xeb, 0xb5, 0xb8, 0xc8, 0xeb, 0xe5, 0xb3, 0xba,
- 0x5f, 0x1e, 0xd5, 0xbf, 0xc2, 0xfd, 0x7a, 0xee, 0x26, 0xe3, 0xb3, 0xf0,
- 0x34, 0xa1, 0xb3, 0x22, 0x73, 0xbf, 0xea, 0xda, 0x84, 0x40, 0xfd, 0x32,
- 0x1e, 0xe5, 0xf7, 0xd4, 0x94, 0x77, 0x70, 0x28, 0x75, 0x8f, 0xf9, 0xf7,
- 0xea, 0xa0, 0xf7, 0x99, 0xd6, 0x6f, 0xfd, 0x9e, 0x16, 0x72, 0xbf, 0x5f,
- 0xab, 0x39, 0x7e, 0xbe, 0x34, 0x80, 0x9f, 0x87, 0x06, 0xf0, 0x3b, 0xaf,
- 0x87, 0x6d, 0x99, 0xff, 0x12, 0x98, 0x45, 0x7a, 0x08, 0xdd, 0xd2, 0x75,
- 0xba, 0x5f, 0x63, 0x89, 0x7f, 0x4f, 0xb8, 0xe6, 0x72, 0x81, 0xfa, 0xe6,
- 0x2e, 0xb3, 0x5f, 0x89, 0xd7, 0x03, 0x8d, 0xaf, 0x5d, 0xe7, 0x39, 0x33,
- 0xe0, 0x3f, 0xdd, 0xd1, 0x99, 0x07, 0x78, 0x0d, 0x00, 0x00, 0x00 };
+ /* Date: 01/27/2009 19:01 */
+#define XI_RV2P_PROC1_POST_WAIT_TIMEOUT_MSK 0xffff
+ 0xa5, 0x56, 0xdd, 0x6b, 0x1c, 0x55, 0x14, 0x3f, 0x33, 0xbb, 0x33, 0xb3,
+ 0xd9, 0x9d, 0xd9, 0x5d, 0x9a, 0x34, 0x8e, 0xb1, 0x34, 0xdb, 0x20, 0xca,
+ 0xa6, 0x13, 0xdd, 0x68, 0x1f, 0x04, 0x03, 0x2d, 0x01, 0x29, 0x98, 0xe2,
+ 0x43, 0xa0, 0x52, 0x8a, 0x60, 0x5c, 0xb4, 0x08, 0xf6, 0x2f, 0x10, 0xc1,
+ 0x21, 0x31, 0x11, 0xc4, 0xaf, 0x7d, 0xe8, 0x42, 0x02, 0x6a, 0x40, 0x50,
+ 0x09, 0x11, 0x77, 0xdf, 0x24, 0x16, 0x7c, 0x68, 0xf1, 0x41, 0xda, 0xa7,
+ 0x16, 0xd4, 0x97, 0x46, 0x11, 0xbf, 0x5e, 0x04, 0xd1, 0xc7, 0x9a, 0xf1,
+ 0x9e, 0x8f, 0xbb, 0x3b, 0x73, 0xb3, 0x9b, 0x14, 0x5c, 0x48, 0x7e, 0x9c,
+ 0x7b, 0xcf, 0x39, 0xf7, 0x7c, 0x9f, 0xa9, 0x02, 0x80, 0x0d, 0x71, 0x77,
+ 0x52, 0x21, 0x58, 0xb9, 0x5c, 0x01, 0x01, 0x60, 0x1b, 0xf8, 0xe7, 0xf8,
+ 0x44, 0xc7, 0x8f, 0x0a, 0x7d, 0x92, 0x21, 0x3e, 0x59, 0x55, 0xff, 0x2f,
+ 0xc3, 0xe9, 0x1a, 0x62, 0x0e, 0x4e, 0x9f, 0x40, 0x7c, 0x12, 0xbe, 0xae,
+ 0x85, 0x0a, 0xff, 0x4d, 0x20, 0x46, 0xfa, 0x68, 0xe7, 0xcb, 0x6e, 0x89,
+ 0xf4, 0xef, 0x8a, 0xfc, 0xf7, 0x39, 0xc6, 0x27, 0xa2, 0x02, 0xeb, 0x11,
+ 0x84, 0x99, 0x2a, 0xc1, 0xed, 0x16, 0xd2, 0xe7, 0xcf, 0x83, 0x8b, 0x7a,
+ 0xde, 0x53, 0x0c, 0x48, 0x1f, 0xb3, 0xe2, 0x19, 0xb1, 0xcb, 0x66, 0xbe,
+ 0x3b, 0xad, 0x0a, 0x9e, 0xc3, 0x8f, 0xf3, 0x48, 0xdf, 0x57, 0x7c, 0xa3,
+ 0x85, 0x38, 0x0e, 0x97, 0x0a, 0x3e, 0xfb, 0x53, 0x17, 0x9c, 0x64, 0xf5,
+ 0xbb, 0xd3, 0x28, 0xaf, 0x64, 0xa6, 0x45, 0xbf, 0x83, 0xfa, 0x7f, 0x4f,
+ 0x58, 0x3f, 0xea, 0x4d, 0xeb, 0xbb, 0x5f, 0xe9, 0xc3, 0x73, 0x57, 0xec,
+ 0x73, 0x0d, 0xfb, 0x5c, 0x65, 0x0f, 0xca, 0xaf, 0x00, 0xfb, 0x39, 0xaa,
+ 0xde, 0x45, 0xfa, 0xaf, 0xbe, 0xbe, 0x2e, 0xa2, 0x6f, 0xb1, 0xbc, 0xfa,
+ 0x13, 0xfb, 0x59, 0xee, 0x35, 0x25, 0xa7, 0xe3, 0x92, 0xb5, 0xd3, 0x8b,
+ 0xb4, 0x7f, 0x3a, 0xfe, 0xc8, 0x7f, 0x2b, 0xc9, 0xf2, 0xc3, 0x21, 0xfc,
+ 0x37, 0x15, 0x7f, 0x56, 0x2f, 0x9f, 0x7f, 0xdb, 0x3f, 0x1f, 0x18, 0x1f,
+ 0xc7, 0x88, 0xcf, 0x75, 0xf1, 0xe7, 0x29, 0x78, 0xd0, 0x0e, 0x89, 0x2f,
+ 0x0f, 0x21, 0xc5, 0x09, 0x62, 0xc4, 0xe3, 0x82, 0x2f, 0x09, 0x7e, 0x2e,
+ 0xb8, 0x2d, 0x08, 0xff, 0x13, 0xff, 0x1e, 0x72, 0x7e, 0x54, 0xf0, 0x01,
+ 0xe3, 0xfc, 0x9a, 0xe0, 0x23, 0x86, 0xfc, 0x71, 0x8b, 0xf1, 0x0f, 0xa1,
+ 0xe7, 0x85, 0x7e, 0xc6, 0x90, 0x8f, 0x81, 0xe3, 0x63, 0x19, 0x71, 0xfb,
+ 0x58, 0xea, 0x19, 0xf3, 0x2f, 0xf7, 0x75, 0xcd, 0x57, 0xa0, 0x38, 0xc2,
+ 0x74, 0x9a, 0xff, 0x83, 0x03, 0xf8, 0x99, 0x6d, 0xbe, 0x3e, 0x48, 0xae,
+ 0x9d, 0xb0, 0x1d, 0x57, 0x44, 0xbe, 0xd8, 0xb9, 0x3a, 0xa4, 0x7f, 0xe6,
+ 0xa2, 0x41, 0xfd, 0x52, 0x17, 0x3f, 0xbe, 0x92, 0xba, 0xdc, 0xb1, 0x9a,
+ 0x51, 0xc8, 0x79, 0xa5, 0x3c, 0x06, 0x52, 0x8f, 0x23, 0x46, 0x3d, 0x7b,
+ 0xaa, 0x9e, 0xa5, 0xae, 0xea, 0xba, 0xbe, 0xb2, 0x75, 0xc5, 0xf5, 0xe1,
+ 0x1a, 0xf5, 0x11, 0x1f, 0x12, 0x97, 0x92, 0xe1, 0xdf, 0xab, 0x09, 0x86,
+ 0x18, 0x7f, 0xb6, 0xcd, 0xb8, 0xc1, 0x18, 0xf9, 0x6e, 0x1e, 0xf1, 0x94,
+ 0xff, 0x0d, 0xeb, 0x9b, 0x04, 0x44, 0x3f, 0x6c, 0x53, 0x1f, 0xe5, 0xa1,
+ 0xed, 0x2a, 0x9b, 0xe1, 0x6e, 0xf2, 0x0e, 0xf3, 0x4d, 0x38, 0x37, 0x09,
+ 0xc3, 0x8d, 0x1b, 0xcc, 0xff, 0x5d, 0x8d, 0xed, 0x7e, 0x56, 0xe6, 0x53,
+ 0xff, 0xa7, 0xef, 0xa5, 0xff, 0x2a, 0x48, 0xff, 0x63, 0xc5, 0x5d, 0xfd,
+ 0x8e, 0xc8, 0xbd, 0xa2, 0xeb, 0x9b, 0x7f, 0xcb, 0x6e, 0x95, 0xfc, 0x7d,
+ 0xab, 0x4b, 0xe4, 0x98, 0xbf, 0x56, 0xa5, 0xdb, 0xb7, 0xbb, 0xda, 0x1f,
+ 0xe9, 0xf3, 0x69, 0xed, 0x3f, 0xcb, 0x07, 0x72, 0x6d, 0x3b, 0x3a, 0x7e,
+ 0x7c, 0x5e, 0x24, 0x3b, 0x46, 0x3b, 0x9b, 0x46, 0x3e, 0x6b, 0xf7, 0x34,
+ 0x07, 0xff, 0x4c, 0xfa, 0x73, 0x30, 0x1d, 0x1f, 0x3d, 0x07, 0x0b, 0xb0,
+ 0x74, 0xb6, 0x42, 0xf6, 0x94, 0x5d, 0x56, 0x73, 0xa1, 0xc2, 0xf8, 0x62,
+ 0x91, 0xf1, 0x97, 0x22, 0xc6, 0x2f, 0x49, 0x2e, 0x95, 0x98, 0x7e, 0x21,
+ 0x40, 0xbd, 0xa3, 0xea, 0x61, 0x2d, 0xaf, 0xed, 0x3a, 0xc8, 0x1e, 0x7c,
+ 0x5f, 0xbf, 0xa3, 0xed, 0xd0, 0xef, 0x65, 0xeb, 0x65, 0xf8, 0xbb, 0x8c,
+ 0x4d, 0x3b, 0x1b, 0x87, 0xfc, 0x2c, 0xe3, 0x46, 0x03, 0xed, 0xba, 0x9a,
+ 0xf4, 0xfa, 0xb0, 0x5e, 0x25, 0xbe, 0x29, 0x60, 0x7a, 0x51, 0xea, 0x73,
+ 0x91, 0xfa, 0xa7, 0xac, 0xae, 0x10, 0x27, 0x20, 0xa6, 0xbd, 0x60, 0x17,
+ 0xaf, 0x53, 0xbd, 0xe4, 0xe4, 0x5c, 0xe5, 0x67, 0x2a, 0xdb, 0x77, 0xbb,
+ 0x5c, 0x8f, 0x85, 0x6c, 0x1d, 0x3f, 0x9c, 0x9a, 0xaf, 0x69, 0x7f, 0xad,
+ 0x5e, 0xfd, 0xee, 0xcf, 0x53, 0x36, 0x1f, 0xb7, 0x5b, 0xda, 0x7f, 0x73,
+ 0x6f, 0x30, 0x7b, 0xdc, 0x90, 0x40, 0xcd, 0xca, 0xfd, 0x8c, 0xd9, 0x2f,
+ 0x83, 0xfa, 0xad, 0x6a, 0xf4, 0xcf, 0x11, 0xe9, 0xb7, 0x91, 0xce, 0x66,
+ 0xeb, 0xb0, 0x7e, 0x46, 0xfe, 0x2f, 0x64, 0x9e, 0x54, 0xa1, 0xb7, 0x97,
+ 0xb6, 0x91, 0x2e, 0x81, 0xf4, 0x61, 0x27, 0xce, 0x65, 0xf2, 0x70, 0x06,
+ 0x06, 0xce, 0x95, 0x0f, 0x45, 0x4f, 0x43, 0xe6, 0x8b, 0x9b, 0xda, 0x5f,
+ 0xc4, 0x5e, 0x06, 0xb2, 0xc3, 0x33, 0xe6, 0xc3, 0xdd, 0x3d, 0xdd, 0xef,
+ 0xcb, 0xee, 0x20, 0x7f, 0x3d, 0xf8, 0xcd, 0xe7, 0xfa, 0x68, 0x52, 0xbf,
+ 0x38, 0x63, 0x97, 0x77, 0x32, 0x79, 0x02, 0x38, 0xa1, 0xf7, 0x52, 0xda,
+ 0xae, 0xf4, 0x5e, 0x45, 0x7d, 0x21, 0x34, 0x67, 0xd3, 0xfb, 0xf5, 0xfd,
+ 0x44, 0xcf, 0xf5, 0x80, 0xfa, 0xa4, 0xbc, 0xaf, 0xef, 0xf4, 0x1c, 0xad,
+ 0x45, 0xe9, 0xfe, 0x1d, 0x93, 0xb9, 0x69, 0x03, 0xcf, 0xcd, 0x92, 0xe9,
+ 0xa7, 0xda, 0xb7, 0x83, 0xf3, 0xc5, 0xfe, 0xde, 0xd9, 0xbb, 0xb7, 0x39,
+ 0x7b, 0x58, 0xde, 0x8b, 0x46, 0xde, 0x6f, 0xf5, 0xe2, 0x68, 0x3b, 0x83,
+ 0xbe, 0x2b, 0x4e, 0x29, 0xbd, 0xc2, 0x2f, 0x73, 0xe1, 0x79, 0x9a, 0x77,
+ 0x67, 0x84, 0x6f, 0x2e, 0x55, 0xaf, 0x83, 0xf8, 0x62, 0xa3, 0xae, 0x0b,
+ 0xfb, 0xf8, 0xb2, 0x73, 0x4c, 0xfb, 0xb3, 0xb5, 0xc5, 0xf5, 0x71, 0x31,
+ 0xd5, 0xaf, 0xe9, 0xf9, 0x3f, 0x22, 0xf5, 0xa0, 0xf8, 0xc8, 0x8f, 0x9d,
+ 0xbd, 0xfe, 0xbe, 0x48, 0xd7, 0xd7, 0xa2, 0xd4, 0xb5, 0x3d, 0xb7, 0x49,
+ 0x7d, 0xe4, 0x35, 0x7f, 0x35, 0xf2, 0x35, 0x1b, 0x61, 0x9d, 0xbc, 0x0e,
+ 0x5d, 0xb1, 0xf3, 0x87, 0x8c, 0xbd, 0x81, 0xf4, 0xa1, 0x0b, 0x9f, 0x75,
+ 0xb5, 0x5f, 0x7c, 0x5d, 0x8b, 0x18, 0x3f, 0x8d, 0xa4, 0x9f, 0x7a, 0xfe,
+ 0xe1, 0xbb, 0x0b, 0xf2, 0x6e, 0x15, 0x3e, 0xe9, 0xed, 0x03, 0x9c, 0x6f,
+ 0x1e, 0x34, 0x64, 0x7e, 0x2e, 0xc9, 0x1c, 0xfb, 0xa9, 0xc8, 0x73, 0xb2,
+ 0xb9, 0x40, 0xf5, 0x0a, 0xe3, 0x32, 0xcf, 0x9a, 0x01, 0xd3, 0x13, 0x01,
+ 0x7f, 0x07, 0x37, 0x3c, 0x9f, 0xf8, 0x26, 0x02, 0xc6, 0xf1, 0x12, 0xca,
+ 0x85, 0xf0, 0xf3, 0x39, 0x62, 0x8f, 0xd6, 0x7d, 0xde, 0x73, 0xeb, 0x37,
+ 0x64, 0x9e, 0x54, 0x74, 0xdc, 0xc4, 0xcf, 0xc7, 0xf1, 0x7c, 0x5c, 0xcd,
+ 0x2d, 0xa6, 0xb9, 0x1e, 0xfc, 0x5e, 0xfd, 0x7f, 0x24, 0x59, 0xa9, 0x55,
+ 0xd2, 0x71, 0xd6, 0xfd, 0xf6, 0xae, 0x11, 0x5f, 0x9d, 0x9f, 0x87, 0x12,
+ 0x3d, 0xe7, 0xa7, 0xce, 0xa2, 0xbd, 0x15, 0x28, 0x7b, 0x5c, 0x3f, 0x8c,
+ 0x4a, 0x8f, 0xed, 0xa1, 0xd8, 0xb1, 0x55, 0x99, 0x9b, 0xab, 0xcb, 0xa4,
+ 0xe6, 0xdc, 0xaa, 0x3e, 0x9f, 0xa7, 0x86, 0x59, 0xdc, 0xba, 0x46, 0xe7,
+ 0xe5, 0x6e, 0x8e, 0xcf, 0xbd, 0x05, 0x1d, 0xaf, 0x0a, 0xf9, 0xdf, 0xe6,
+ 0x78, 0x3d, 0x77, 0x85, 0xf1, 0x22, 0x3c, 0x4d, 0x58, 0x6c, 0x4b, 0x9f,
+ 0xaf, 0xfb, 0x05, 0x42, 0xa0, 0x78, 0xd9, 0x8f, 0xf1, 0x7e, 0x77, 0x64,
+ 0x2f, 0x17, 0x52, 0xf9, 0x33, 0xf7, 0xe4, 0x41, 0x79, 0x3c, 0x62, 0xec,
+ 0x0b, 0xbd, 0xd7, 0x2d, 0xe3, 0xfb, 0x36, 0x30, 0xea, 0xf1, 0xe5, 0x21,
+ 0xf5, 0x08, 0x43, 0xea, 0xd9, 0x9c, 0x6f, 0x4b, 0xd2, 0xef, 0x79, 0x70,
+ 0x72, 0xb4, 0x78, 0xfd, 0xfc, 0x0a, 0xe5, 0xd5, 0x5e, 0xe5, 0xef, 0x1a,
+ 0xdf, 0x59, 0xb3, 0x28, 0x5e, 0xfe, 0x1a, 0xf3, 0xe5, 0xf9, 0x3c, 0xd4,
+ 0xf8, 0xe6, 0x0a, 0xf7, 0x95, 0x0d, 0xff, 0x01, 0xd7, 0x0e, 0x41, 0x60,
+ 0x88, 0x0d, 0x00, 0x00, 0x00 };
static u8 bnx2_xi_rv2p_proc2[] = {
- /* Date: 06/17/2008 16:52 */
+ /* Date: 01/27/2009 19:01 */
#define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5
#define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff
#define XI_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
- 0xad, 0x58, 0x4d, 0x4c, 0x54, 0x57, 0x14, 0xbe, 0xf3, 0xc3, 0xcc, 0x30,
- 0xbc, 0x99, 0x41, 0x98, 0x0e, 0x7f, 0xa6, 0x22, 0x28, 0x82, 0x1d, 0x14,
- 0x06, 0xd4, 0xb6, 0x36, 0xa9, 0xc1, 0x06, 0xb5, 0xb5, 0x11, 0x69, 0x63,
- 0xba, 0x68, 0x8a, 0x60, 0x45, 0x06, 0xc1, 0x10, 0x31, 0x2e, 0xdc, 0x74,
- 0x02, 0x16, 0xbb, 0x98, 0x85, 0x98, 0xe2, 0x60, 0xd3, 0x18, 0x52, 0x37,
- 0xa6, 0x3b, 0x92, 0xb6, 0x62, 0xbb, 0x30, 0x31, 0x2d, 0xb1, 0xb6, 0x89,
- 0x36, 0xb1, 0x7f, 0x9b, 0xa6, 0xa6, 0x5a, 0x8a, 0x4a, 0x2d, 0xda, 0xb2,
- 0xaa, 0xd0, 0x77, 0xcf, 0x77, 0xee, 0x9b, 0x37, 0x33, 0x6f, 0x44, 0x53,
- 0xd9, 0x1c, 0xee, 0x7d, 0xe7, 0x9e, 0x7b, 0xce, 0x77, 0x7e, 0xef, 0xe4,
- 0x0b, 0x21, 0x9c, 0x22, 0x36, 0xbe, 0x4c, 0xa7, 0x62, 0x89, 0xdd, 0xe1,
- 0xd1, 0xc9, 0x82, 0x10, 0x39, 0xc5, 0x72, 0x2d, 0xec, 0x82, 0xff, 0x56,
- 0xe7, 0x13, 0xb9, 0x36, 0x2e, 0xbf, 0xbb, 0xc5, 0xeb, 0x76, 0x7c, 0x77,
- 0x0a, 0x49, 0x03, 0x42, 0xc4, 0x24, 0xcd, 0x67, 0xba, 0x9d, 0xe9, 0x4a,
- 0x1b, 0xe8, 0x46, 0xa6, 0x51, 0xa6, 0x2b, 0x98, 0xd6, 0xdb, 0x41, 0x57,
- 0x31, 0xad, 0xe6, 0x7d, 0x8d, 0xcf, 0xd7, 0xf2, 0xfe, 0x7b, 0x4c, 0x8f,
- 0xf2, 0xbe, 0xa6, 0xf3, 0x29, 0xbd, 0xe4, 0x7a, 0x66, 0x41, 0xc4, 0xf4,
- 0x33, 0x42, 0xdf, 0xae, 0x51, 0xfb, 0x1a, 0x91, 0x58, 0x0d, 0xf4, 0x7e,
- 0xad, 0x5c, 0xf2, 0xfd, 0x61, 0xc1, 0x27, 0xf7, 0x6f, 0x2e, 0x28, 0x79,
- 0x03, 0x0e, 0xb9, 0xfe, 0x55, 0x5f, 0xdb, 0xe4, 0x32, 0x18, 0x82, 0x98,
- 0x60, 0x71, 0x5c, 0xca, 0x71, 0x88, 0xd1, 0x61, 0x0f, 0xa1, 0x72, 0x52,
- 0xc3, 0x3a, 0x46, 0x78, 0xd8, 0xf4, 0x35, 0xcb, 0x63, 0x5a, 0xe2, 0xc3,
- 0xbd, 0xbb, 0xca, 0x71, 0xdf, 0x8f, 0xcf, 0x80, 0x2f, 0x16, 0x50, 0x80,
- 0xe2, 0xfb, 0x32, 0xc1, 0xdf, 0xf7, 0xcb, 0xf5, 0xac, 0xad, 0xd0, 0x06,
- 0x5c, 0xdd, 0xcc, 0x65, 0xcf, 0x91, 0xfb, 0xcb, 0x1b, 0x4f, 0x0e, 0x83,
- 0xbf, 0xad, 0x1c, 0xfb, 0x4f, 0x87, 0xa5, 0x3c, 0x97, 0x88, 0x31, 0x15,
- 0xb5, 0xa4, 0x97, 0x2d, 0x56, 0x9b, 0x2a, 0xff, 0x97, 0x61, 0xac, 0xda,
- 0x7d, 0x90, 0xeb, 0x4d, 0x91, 0x1b, 0xca, 0x90, 0xfb, 0x53, 0xae, 0x59,
- 0xbe, 0xdf, 0x06, 0xf9, 0xde, 0x45, 0xe5, 0x77, 0xf8, 0x40, 0x0b, 0xc3,
- 0x56, 0xf7, 0xe4, 0x2e, 0xa2, 0x7f, 0xf7, 0xa2, 0xf2, 0x8f, 0x18, 0xfa,
- 0x2b, 0xff, 0xa9, 0xef, 0xe9, 0x38, 0xd2, 0xf2, 0xe3, 0xd8, 0x5a, 0x16,
- 0xb3, 0x5a, 0xd9, 0xcf, 0x7a, 0x3a, 0x40, 0x37, 0x85, 0x89, 0xc4, 0xf7,
- 0x70, 0x80, 0x37, 0x57, 0xc9, 0xfb, 0x0b, 0x84, 0xd3, 0x2e, 0xe5, 0xd5,
- 0x79, 0x5c, 0xe7, 0xb1, 0xff, 0x06, 0xfb, 0xeb, 0x6d, 0x36, 0xe8, 0xa6,
- 0x57, 0x02, 0xb4, 0xb0, 0xd0, 0x99, 0xc7, 0xf2, 0xd9, 0xdf, 0xb1, 0x3c,
- 0x9c, 0x9f, 0xd4, 0xa4, 0x9e, 0x5f, 0xeb, 0xf1, 0x63, 0xe5, 0x7f, 0xc7,
- 0x43, 0xfc, 0x8f, 0xf3, 0x4b, 0x56, 0xe1, 0xeb, 0xf1, 0x4e, 0xac, 0xcb,
- 0xce, 0xe4, 0x13, 0x4e, 0xa3, 0xe3, 0x56, 0xf1, 0x92, 0x2e, 0x5f, 0xcf,
- 0xe3, 0x00, 0xee, 0x11, 0x15, 0x1e, 0x52, 0x0e, 0xf8, 0xea, 0x3c, 0xb5,
- 0x96, 0x38, 0x89, 0x93, 0x2b, 0xe5, 0xbe, 0x5d, 0xb4, 0x3a, 0x34, 0xba,
- 0xa7, 0x35, 0xaa, 0xf2, 0x06, 0xdf, 0x3b, 0x5d, 0x44, 0x8a, 0xdb, 0x87,
- 0xa4, 0xdd, 0x01, 0xb1, 0xdb, 0x1e, 0x20, 0x7e, 0xe0, 0xe4, 0xf0, 0x68,
- 0x9f, 0x81, 0xff, 0xc2, 0x32, 0x8d, 0x6c, 0xea, 0x6c, 0xc0, 0xb9, 0x60,
- 0x04, 0x74, 0x24, 0x92, 0x23, 0x49, 0xb8, 0xb3, 0x9f, 0x96, 0x6b, 0x7e,
- 0xab, 0xf7, 0x10, 0x5f, 0xac, 0x56, 0xe5, 0xa5, 0xf2, 0xa3, 0xc4, 0xed,
- 0x90, 0x91, 0x87, 0xa2, 0x12, 0x38, 0xff, 0xbe, 0x52, 0xf2, 0xeb, 0x60,
- 0x57, 0xe0, 0x9e, 0xa4, 0x7e, 0xe6, 0xbc, 0xee, 0x35, 0xe5, 0xf5, 0xe3,
- 0xc5, 0xc5, 0x26, 0xc2, 0x67, 0x13, 0xe3, 0x54, 0xce, 0x71, 0xb8, 0xd4,
- 0x22, 0x0e, 0x03, 0xf4, 0xff, 0xad, 0xa6, 0x7c, 0xc2, 0x79, 0x07, 0xf6,
- 0x4f, 0x34, 0x9f, 0x83, 0x9f, 0xb6, 0x11, 0x1e, 0xc2, 0x7b, 0xf4, 0x53,
- 0x9c, 0x6a, 0xa7, 0xfc, 0xef, 0x6d, 0xec, 0xfc, 0x1c, 0xeb, 0x0e, 0x87,
- 0x5c, 0xef, 0xd7, 0xf6, 0x4c, 0x80, 0x3f, 0x67, 0x10, 0xb8, 0xef, 0xe0,
- 0x5b, 0xb6, 0x39, 0xa8, 0xde, 0xc4, 0x5d, 0x83, 0xb4, 0xd4, 0x26, 0xe9,
- 0x7b, 0xbe, 0x38, 0x36, 0x8e, 0xef, 0x07, 0xf2, 0xa4, 0x9d, 0xaf, 0x1a,
- 0x75, 0x29, 0xea, 0xc2, 0xf9, 0xf8, 0x30, 0xea, 0xca, 0xf4, 0x27, 0x72,
- 0xdd, 0x16, 0x9e, 0x06, 0x7f, 0x38, 0x3a, 0xc4, 0x82, 0xed, 0xc0, 0xf1,
- 0x96, 0x1d, 0xfc, 0x1c, 0xae, 0x5e, 0x27, 0xf9, 0xd1, 0x26, 0xb4, 0x66,
- 0xd0, 0x77, 0xe9, 0xfb, 0xbf, 0xb6, 0x38, 0xe1, 0xb6, 0xcb, 0xef, 0x3c,
- 0xa7, 0xf0, 0x61, 0x1a, 0x50, 0x76, 0x81, 0x3e, 0x6a, 0x3e, 0x0c, 0x69,
- 0xd9, 0xf2, 0x80, 0xfd, 0x59, 0xb3, 0x58, 0x1e, 0x80, 0x36, 0x57, 0x81,
- 0xba, 0x2a, 0xa9, 0x9e, 0x3c, 0x46, 0x3e, 0xb0, 0x5e, 0x19, 0xf9, 0x86,
- 0xdd, 0x64, 0x9c, 0x12, 0xd1, 0xe3, 0x33, 0x25, 0x5e, 0x39, 0x3f, 0x96,
- 0xeb, 0x7e, 0x50, 0x71, 0x27, 0x05, 0xba, 0xc5, 0x7e, 0x96, 0x1b, 0x65,
- 0x3c, 0x7a, 0x18, 0x8f, 0x19, 0xa6, 0x07, 0xf2, 0x14, 0x0e, 0xa0, 0xc7,
- 0x34, 0xdc, 0xdb, 0x1a, 0x95, 0x7e, 0x0c, 0x5a, 0xf4, 0x17, 0xd5, 0x47,
- 0xe0, 0xa7, 0x51, 0xf6, 0xeb, 0x29, 0xa3, 0x9f, 0x28, 0x7c, 0xb3, 0xf5,
- 0x95, 0xd4, 0x7c, 0x4a, 0xb3, 0x33, 0xfe, 0x55, 0x05, 0x8e, 0x17, 0x54,
- 0x82, 0x1a, 0xf8, 0x56, 0x51, 0x1e, 0xfb, 0x8b, 0x26, 0x94, 0x7d, 0x52,
- 0xbf, 0x3b, 0x2a, 0x0f, 0xfd, 0x89, 0x01, 0xa2, 0xde, 0x82, 0x33, 0xf2,
- 0x9e, 0x52, 0x8b, 0xba, 0x92, 0x9a, 0xcf, 0xe9, 0xf8, 0x1e, 0xf0, 0x51,
- 0xc1, 0x6d, 0xbc, 0x32, 0x95, 0x9a, 0xb7, 0xc8, 0x4f, 0xb7, 0x11, 0xdf,
- 0xc1, 0xf5, 0xec, 0x07, 0xa6, 0xa1, 0x0d, 0x52, 0x6e, 0x0b, 0xdf, 0x53,
- 0xc7, 0xf7, 0x68, 0xa6, 0xba, 0x21, 0xf5, 0xfc, 0x73, 0x5e, 0xd5, 0x0b,
- 0x15, 0x1f, 0xc9, 0xba, 0xa1, 0xfc, 0x40, 0xf7, 0x87, 0xaf, 0x4c, 0xc9,
- 0xf3, 0x65, 0x8b, 0xd4, 0x91, 0x1b, 0x86, 0xbc, 0xef, 0x8d, 0x3a, 0x21,
- 0xbf, 0xe7, 0x89, 0x17, 0x79, 0x99, 0x5a, 0x0f, 0xff, 0xd2, 0xeb, 0x21,
- 0xd9, 0xe1, 0xd1, 0xce, 0x71, 0xfd, 0xeb, 0x97, 0xf7, 0x14, 0xb3, 0xde,
- 0xc5, 0xaa, 0xaf, 0xe9, 0x7a, 0x73, 0x9d, 0x6c, 0x33, 0xd7, 0xbb, 0x1f,
- 0xe6, 0x93, 0x75, 0x4b, 0xae, 0xaf, 0xcd, 0x67, 0xce, 0x27, 0x96, 0xb8,
- 0xc6, 0x44, 0x00, 0x73, 0x58, 0x2c, 0x20, 0xcf, 0xe5, 0xd8, 0x32, 0xeb,
- 0x5f, 0xba, 0x1d, 0xc0, 0xa5, 0xdd, 0xee, 0x23, 0xbe, 0xeb, 0x7d, 0xf2,
- 0xdc, 0xb4, 0x50, 0xf6, 0xa2, 0x0e, 0x96, 0x73, 0xbf, 0x5f, 0xca, 0x7a,
- 0xeb, 0xf2, 0x6a, 0x29, 0x1f, 0x3c, 0xd7, 0xfb, 0xcc, 0x7a, 0x5f, 0x98,
- 0xcf, 0x7e, 0x9f, 0x75, 0x1c, 0xf4, 0x71, 0x9f, 0xe5, 0x39, 0xc1, 0xb3,
- 0xe7, 0x0b, 0xa5, 0x17, 0xdf, 0x1f, 0x50, 0x7a, 0x68, 0xe4, 0xa7, 0xa9,
- 0x7e, 0x29, 0xa7, 0x50, 0x70, 0xd8, 0x88, 0xde, 0x6a, 0xd4, 0xdf, 0x99,
- 0xbd, 0xb0, 0xa3, 0xb7, 0x4a, 0xea, 0xa1, 0x7b, 0x25, 0x86, 0x3c, 0x17,
- 0xdc, 0x8f, 0xbe, 0x1c, 0xb6, 0xf2, 0xeb, 0xb7, 0xcc, 0x17, 0x64, 0xfb,
- 0xf2, 0xd9, 0xbe, 0xb0, 0x48, 0xaf, 0xf3, 0x6d, 0xe5, 0xd4, 0x0f, 0x98,
- 0xef, 0x05, 0xd5, 0x0f, 0x74, 0x3e, 0xc2, 0x99, 0xe5, 0x58, 0xe1, 0x64,
- 0x25, 0x67, 0x82, 0xe3, 0xa0, 0x8b, 0xf9, 0x9c, 0x59, 0xe7, 0x9b, 0xb9,
- 0x55, 0xd4, 0x57, 0x4e, 0x1f, 0xa1, 0xfe, 0xe0, 0x33, 0xe2, 0x34, 0xd5,
- 0x8e, 0xe3, 0x4f, 0x10, 0x77, 0x9a, 0xff, 0xc4, 0x3e, 0x7f, 0x36, 0x7c,
- 0x9d, 0x72, 0x7b, 0x6c, 0x76, 0x42, 0xf9, 0x47, 0x23, 0x7b, 0xa7, 0xfa,
- 0xd5, 0x9c, 0x6f, 0xc6, 0xdd, 0x6e, 0xc2, 0x1d, 0xfc, 0x98, 0xef, 0xfe,
- 0x0f, 0xde, 0x56, 0xf3, 0x41, 0x9f, 0x91, 0x9f, 0x03, 0x2e, 0xab, 0xfa,
- 0xbf, 0xd6, 0x88, 0x97, 0x83, 0x3c, 0xe7, 0xcd, 0x69, 0xf4, 0x4f, 0x64,
- 0x26, 0x4e, 0x4b, 0xad, 0xe4, 0xac, 0xe4, 0x5b, 0x1d, 0x39, 0xc8, 0x76,
- 0x5d, 0x76, 0xc0, 0xee, 0xae, 0xbd, 0x58, 0x5f, 0xe1, 0x7a, 0x7d, 0x8f,
- 0xeb, 0xe3, 0x4e, 0x0f, 0xe8, 0x4c, 0x35, 0xe1, 0x11, 0x39, 0x78, 0x5e,
- 0xc9, 0x27, 0xb9, 0xda, 0x1c, 0xe3, 0xf9, 0x92, 0x83, 0xed, 0xac, 0x20,
- 0x3f, 0x46, 0xee, 0x52, 0x3d, 0x70, 0x8a, 0xa6, 0xe5, 0x92, 0x96, 0xe8,
- 0xb8, 0xb1, 0x3e, 0x1b, 0x41, 0x5b, 0xd5, 0x80, 0x5f, 0x93, 0xee, 0x67,
- 0x6c, 0xbb, 0x2a, 0xf8, 0x7c, 0x3b, 0xd6, 0x6e, 0xae, 0x67, 0x09, 0xd6,
- 0xeb, 0xfd, 0x6a, 0x50, 0x7f, 0x0d, 0xe6, 0x84, 0x29, 0xea, 0x0b, 0x81,
- 0x48, 0xff, 0x04, 0xec, 0xe9, 0xd9, 0x0c, 0x7b, 0xef, 0x33, 0x0e, 0x4c,
- 0xfd, 0xa7, 0x06, 0xa9, 0xef, 0xf8, 0x87, 0x30, 0x67, 0xf8, 0x5d, 0x83,
- 0xb0, 0xa3, 0x67, 0x0e, 0xeb, 0xfb, 0xcf, 0x81, 0xfe, 0xf3, 0x3c, 0xce,
- 0x1d, 0x3a, 0xc2, 0xf8, 0x6c, 0xb6, 0x3e, 0xd7, 0xf5, 0x37, 0xf8, 0x7a,
- 0xab, 0xe5, 0xfd, 0x6f, 0x8d, 0xf1, 0xfc, 0x21, 0xa2, 0x34, 0xef, 0xbc,
- 0xa9, 0xcd, 0xf1, 0xba, 0x9b, 0xfb, 0xe2, 0x6d, 0x9e, 0x17, 0x7a, 0xd2,
- 0xe6, 0x85, 0x69, 0xd4, 0xe9, 0xb1, 0xb9, 0xb8, 0xdc, 0xd0, 0xeb, 0x65,
- 0xae, 0x95, 0x7f, 0x7d, 0x91, 0x22, 0xf6, 0x5b, 0x70, 0x1d, 0xe8, 0xc8,
- 0x3a, 0xf4, 0xeb, 0x9e, 0xc3, 0x8c, 0x4f, 0x23, 0xf9, 0x69, 0xcd, 0xec,
- 0x44, 0xfa, 0x79, 0x19, 0x3f, 0xed, 0xf3, 0x78, 0x3f, 0x6e, 0xd6, 0xa9,
- 0xba, 0x0f, 0xe7, 0x3a, 0xe8, 0x7d, 0x71, 0xcf, 0x98, 0x3f, 0xa7, 0x49,
- 0xff, 0xb2, 0xb1, 0x39, 0x92, 0x53, 0x2a, 0x0a, 0x29, 0x0e, 0x4b, 0xfc,
- 0xb3, 0xb0, 0x27, 0x92, 0x60, 0x1c, 0xfa, 0x9e, 0x05, 0x3d, 0xcc, 0x71,
- 0xa0, 0xfc, 0x7b, 0x75, 0x83, 0x46, 0xe7, 0xa6, 0xfa, 0x71, 0x8f, 0xca,
- 0xa3, 0xf4, 0xb9, 0x58, 0xc5, 0x45, 0x49, 0x03, 0xad, 0x45, 0xd7, 0x21,
- 0xb2, 0x53, 0xf7, 0xa7, 0x8c, 0x27, 0x1d, 0x2b, 0xee, 0xdb, 0xa9, 0xf1,
- 0x22, 0xe3, 0x49, 0xc5, 0xad, 0x39, 0xce, 0xcc, 0x71, 0x94, 0x1a, 0x3f,
- 0x7e, 0xea, 0x2f, 0x7a, 0x31, 0xa0, 0x77, 0x89, 0x2b, 0x92, 0x18, 0x7e,
- 0x38, 0x8e, 0xa7, 0x80, 0x63, 0x84, 0xf5, 0xd6, 0xa2, 0x34, 0x8f, 0x3e,
- 0x25, 0x86, 0xd8, 0x9f, 0xd3, 0xd5, 0x9c, 0xff, 0x15, 0xf0, 0x67, 0xdf,
- 0x0a, 0xe8, 0xd3, 0xc7, 0x79, 0x74, 0x87, 0xe7, 0x0c, 0xc4, 0x81, 0x5b,
- 0xeb, 0x9c, 0x60, 0xbf, 0x73, 0x3c, 0x76, 0x33, 0x0e, 0xb7, 0x81, 0x83,
- 0xa6, 0x70, 0x88, 0x1a, 0x38, 0xa8, 0x7a, 0x63, 0x96, 0x53, 0xa0, 0xc7,
- 0x93, 0xa4, 0x4b, 0xb4, 0xab, 0x34, 0x8f, 0xe5, 0xb0, 0xdd, 0x3a, 0x5f,
- 0x83, 0xb4, 0xcf, 0xcf, 0xf6, 0xf9, 0xc4, 0xbe, 0x35, 0xe6, 0x73, 0x79,
- 0x7c, 0xce, 0xab, 0x9f, 0xc3, 0x3e, 0xf2, 0x55, 0xcb, 0x82, 0xaf, 0xc4,
- 0x51, 0xc9, 0x4d, 0xcf, 0x4b, 0x33, 0x9e, 0x54, 0xa9, 0xe9, 0x0f, 0xf5,
- 0x48, 0xf7, 0x1b, 0xd5, 0x2d, 0xcd, 0xa8, 0x43, 0xf7, 0xa8, 0xae, 0x7b,
- 0x4f, 0xf7, 0xa2, 0x6e, 0x9c, 0xee, 0x3d, 0xcb, 0x7d, 0x98, 0x71, 0x69,
- 0xa1, 0xf7, 0x83, 0x8e, 0x5d, 0x45, 0x6a, 0x1d, 0x4a, 0xd5, 0xa3, 0xcc,
- 0xa4, 0x87, 0xba, 0x77, 0xb1, 0x39, 0x01, 0x73, 0xea, 0x16, 0x9a, 0x13,
- 0x3c, 0xc6, 0xbc, 0x9d, 0xda, 0x4f, 0x26, 0x1f, 0x3c, 0x6e, 0x3f, 0xd9,
- 0xd9, 0x60, 0xbe, 0xaf, 0x46, 0x4c, 0x8e, 0xe3, 0x9e, 0x16, 0xee, 0xdf,
- 0xbb, 0x39, 0xcf, 0xaf, 0x7b, 0x03, 0x74, 0x6f, 0xc7, 0x2b, 0x64, 0xaf,
- 0x08, 0xe5, 0xc1, 0xbe, 0x8e, 0xed, 0xf8, 0xde, 0xe1, 0xc3, 0x7e, 0xa9,
- 0x0f, 0xbf, 0xa3, 0xb4, 0xb8, 0x35, 0xe2, 0x2f, 0xf5, 0x81, 0x86, 0xb8,
- 0x3e, 0x4c, 0x1a, 0xef, 0x09, 0xd0, 0x51, 0x57, 0xb6, 0xf7, 0x04, 0xde,
- 0x65, 0x17, 0x5d, 0xa8, 0x1f, 0xa2, 0x06, 0x73, 0x74, 0x53, 0x95, 0x46,
- 0xdf, 0x5b, 0x6b, 0xd0, 0xa7, 0x51, 0x9f, 0x33, 0xed, 0x2a, 0x43, 0xbc,
- 0x96, 0x26, 0xdf, 0x1d, 0xe6, 0xf7, 0x89, 0x16, 0x49, 0x18, 0xf3, 0x7f,
- 0xaa, 0x1e, 0xc8, 0x33, 0x29, 0x9f, 0x96, 0xfa, 0x9c, 0xfd, 0x28, 0xef,
- 0x12, 0x07, 0xcf, 0x6d, 0x77, 0xf9, 0x77, 0x82, 0x42, 0x71, 0x69, 0x1c,
- 0x38, 0x4c, 0x8e, 0x5b, 0xe5, 0xb1, 0xd4, 0x43, 0xdd, 0x03, 0xbb, 0x94,
- 0x9d, 0xc9, 0x7b, 0xa1, 0xd7, 0x5e, 0xd6, 0xff, 0x06, 0xfd, 0x9e, 0x11,
- 0x62, 0x7b, 0xa5, 0x5c, 0xec, 0x6f, 0xa5, 0xf7, 0x53, 0x8e, 0x88, 0x19,
- 0xeb, 0xd4, 0x77, 0x4d, 0x0b, 0xe9, 0x55, 0xc0, 0xfd, 0x3d, 0x64, 0x9a,
- 0x43, 0xc0, 0x1f, 0xac, 0x03, 0x1d, 0xa9, 0x53, 0x7e, 0x53, 0xfe, 0x55,
- 0xfe, 0x84, 0xdf, 0x43, 0xf5, 0xc4, 0xd6, 0xd8, 0x51, 0x4f, 0x09, 0x5f,
- 0xd7, 0x31, 0xab, 0xfa, 0x3d, 0xce, 0xef, 0x0c, 0x4b, 0xfe, 0x77, 0xc4,
- 0x77, 0x61, 0x34, 0xd8, 0x9f, 0x99, 0x26, 0xe7, 0x7c, 0xc1, 0x7f, 0xe6,
- 0xf7, 0x82, 0x43, 0x5c, 0xcc, 0xe1, 0xed, 0x06, 0x35, 0xff, 0x66, 0x7b,
- 0xf7, 0x48, 0x3b, 0xba, 0x1f, 0xa4, 0xcf, 0xd3, 0xc9, 0x79, 0x58, 0xd9,
- 0x2b, 0xcf, 0xd5, 0x71, 0x1c, 0x7b, 0x44, 0xd3, 0x16, 0xfc, 0xce, 0xe1,
- 0x77, 0x23, 0x6f, 0xfc, 0x6e, 0xab, 0xf7, 0xa9, 0x1e, 0x47, 0xb9, 0x54,
- 0x30, 0x96, 0x16, 0xe4, 0x92, 0x7d, 0x27, 0x2e, 0x7f, 0x43, 0x6c, 0x1f,
- 0x25, 0xf2, 0xb0, 0x5f, 0xd4, 0x84, 0x6b, 0x9c, 0x14, 0xf7, 0x0e, 0x71,
- 0x14, 0x79, 0xf1, 0xe1, 0x08, 0xe8, 0x07, 0xe2, 0x65, 0xc8, 0x29, 0x18,
- 0xa0, 0xbe, 0xea, 0x29, 0x02, 0xcc, 0xf1, 0x04, 0xc7, 0x7b, 0xb1, 0x9d,
- 0x7e, 0x87, 0x5d, 0x10, 0x3e, 0xfe, 0x9d, 0x8c, 0xf3, 0x17, 0x71, 0xed,
- 0x34, 0xf9, 0xff, 0x51, 0xe3, 0x1c, 0xfd, 0x33, 0xc1, 0x7e, 0xe7, 0x78,
- 0xf7, 0xa4, 0xc7, 0xbb, 0xc2, 0xa9, 0xd8, 0x6e, 0x19, 0xdf, 0xeb, 0x33,
- 0xe3, 0x5b, 0xe9, 0x97, 0xda, 0x3f, 0x33, 0xe5, 0xe3, 0x1d, 0x75, 0xe9,
- 0x89, 0xc5, 0x37, 0xe8, 0xd6, 0x4a, 0x79, 0x7f, 0x51, 0xc6, 0xbc, 0x9c,
- 0x9e, 0x7f, 0xa8, 0x77, 0xd5, 0x7a, 0x3c, 0xfc, 0x07, 0xd7, 0x0d, 0x36,
- 0x4f, 0xf0, 0x16, 0x00, 0x00, 0x00 };
+ 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0xbe, 0x33, 0x6f, 0x7e, 0xde,
+ 0xcc, 0xbc, 0xc9, 0x4c, 0x93, 0x38, 0x99, 0x26, 0xc5, 0xa4, 0x09, 0x8d,
+ 0x4e, 0x9d, 0x69, 0x27, 0x3f, 0x44, 0xb0, 0x42, 0x43, 0x90, 0xb4, 0xb5,
+ 0x4a, 0xd3, 0x28, 0xc5, 0x5d, 0x92, 0xa9, 0x1d, 0x8c, 0x69, 0x23, 0x18,
+ 0x70, 0xe1, 0xc6, 0x47, 0x5a, 0xd3, 0xcd, 0x2c, 0x4c, 0x31, 0x3f, 0x8a,
+ 0xa0, 0xd8, 0x9d, 0xb8, 0x19, 0x50, 0xdb, 0x8a, 0x22, 0x14, 0x0c, 0x52,
+ 0x17, 0x45, 0xb0, 0x58, 0x37, 0x8a, 0x58, 0x1b, 0x1a, 0x11, 0x8d, 0x8b,
+ 0xae, 0x24, 0xe3, 0xbd, 0xe7, 0x3b, 0xf7, 0xcd, 0xbc, 0xc9, 0x8b, 0x89,
+ 0x62, 0x36, 0x27, 0xe7, 0xbe, 0x73, 0xcf, 0x39, 0xf7, 0x9c, 0xef, 0x7c,
+ 0xf7, 0x4e, 0x52, 0x08, 0x11, 0x10, 0x76, 0xb9, 0x5d, 0x4a, 0xe1, 0x33,
+ 0x0c, 0x53, 0x8a, 0x8a, 0x10, 0xc1, 0xb4, 0xd2, 0x85, 0x5f, 0xf0, 0xdf,
+ 0xfe, 0x24, 0x89, 0x6f, 0xcb, 0x96, 0x32, 0x13, 0x76, 0x46, 0xd9, 0x45,
+ 0xc4, 0xb3, 0xfe, 0x88, 0x94, 0x87, 0xc5, 0x68, 0x06, 0xf6, 0x01, 0xa1,
+ 0xa4, 0xb4, 0xb5, 0x95, 0xdc, 0xc5, 0xf2, 0x38, 0xcb, 0xc7, 0x7d, 0x90,
+ 0x87, 0x58, 0x3e, 0x56, 0x27, 0x05, 0xdb, 0x3d, 0xcd, 0xfa, 0x00, 0x4b,
+ 0x8b, 0xd7, 0x47, 0x59, 0xff, 0x90, 0xa5, 0xcd, 0xeb, 0x61, 0xd6, 0x1f,
+ 0xf0, 0xa9, 0x25, 0xe4, 0xab, 0xf4, 0xb5, 0x4a, 0x55, 0xb7, 0xe0, 0x3e,
+ 0x83, 0x73, 0x3c, 0xd3, 0xa1, 0xbe, 0xdf, 0xad, 0xb8, 0xed, 0xef, 0x38,
+ 0xfa, 0xac, 0xa1, 0xf4, 0x1f, 0xa5, 0xee, 0x53, 0x6a, 0x73, 0x0a, 0xdb,
+ 0x9b, 0xd3, 0x25, 0xb5, 0xdf, 0x10, 0xcb, 0xf3, 0x26, 0x55, 0x67, 0xd1,
+ 0x82, 0x6e, 0x97, 0x4d, 0xaa, 0xcb, 0xa2, 0xc5, 0xfe, 0x58, 0xee, 0x8e,
+ 0x23, 0xde, 0xa9, 0x0e, 0xd4, 0xed, 0xbb, 0x47, 0x60, 0x67, 0x27, 0x74,
+ 0x61, 0xf1, 0xbd, 0x5d, 0xf0, 0xf7, 0x29, 0xa5, 0xaf, 0xfb, 0x9a, 0x7c,
+ 0xa8, 0x47, 0x98, 0xad, 0xfc, 0x41, 0xb5, 0xbe, 0xb7, 0x7f, 0x71, 0x1e,
+ 0xf6, 0x63, 0x1d, 0x58, 0x7f, 0x30, 0xab, 0xfc, 0x85, 0x84, 0xcd, 0x52,
+ 0xe4, 0x28, 0x2f, 0x9f, 0x9d, 0x73, 0xfb, 0xff, 0x61, 0x1e, 0xda, 0x44,
+ 0x1c, 0x7e, 0xa3, 0x2e, 0xbf, 0xa9, 0x4d, 0x7e, 0x6f, 0x47, 0x6a, 0xfd,
+ 0x37, 0xf8, 0xe0, 0x3f, 0xba, 0xad, 0xff, 0x42, 0x1c, 0xb2, 0x29, 0xeb,
+ 0x15, 0x27, 0xb2, 0x4d, 0xfe, 0x2f, 0x6e, 0xeb, 0xff, 0x55, 0x27, 0x7f,
+ 0xbd, 0x5e, 0x5f, 0x3f, 0x52, 0x3f, 0xb0, 0x0f, 0xf2, 0xf6, 0xfd, 0xfa,
+ 0xdc, 0x9c, 0x9f, 0x01, 0x39, 0x98, 0x25, 0x51, 0x3a, 0xcd, 0x00, 0x1f,
+ 0xee, 0x56, 0x71, 0x1b, 0x45, 0xc0, 0xaf, 0xfc, 0x1d, 0x30, 0x43, 0xd7,
+ 0xb0, 0xfe, 0x1c, 0xf7, 0xe9, 0x79, 0x3e, 0xc8, 0x2f, 0x51, 0x55, 0x98,
+ 0x4a, 0xa5, 0x18, 0x63, 0xff, 0xdc, 0x67, 0x3b, 0x86, 0xfd, 0x2b, 0x96,
+ 0xca, 0xef, 0x86, 0xc4, 0x8d, 0x57, 0xdf, 0x8d, 0x7f, 0xe8, 0x3b, 0xf6,
+ 0xef, 0x7a, 0x08, 0x5f, 0xdf, 0x28, 0x42, 0x6f, 0xbb, 0x9c, 0xa4, 0xfa,
+ 0x2c, 0x97, 0xbd, 0x70, 0x52, 0xef, 0x5f, 0xce, 0x71, 0x02, 0x71, 0x44,
+ 0xa7, 0x49, 0xc9, 0xa1, 0xae, 0xd2, 0x26, 0xe7, 0x59, 0x27, 0xb1, 0xb8,
+ 0x4f, 0xcf, 0x05, 0xf4, 0x62, 0x88, 0x44, 0x7a, 0x62, 0x4e, 0x9d, 0x33,
+ 0x21, 0xc6, 0xfd, 0x2a, 0x61, 0x3f, 0xd7, 0xc5, 0x30, 0xad, 0x4f, 0x60,
+ 0xff, 0x45, 0xbb, 0x45, 0x67, 0x28, 0xf6, 0x61, 0x5f, 0x73, 0x2f, 0xe4,
+ 0x42, 0x6f, 0x50, 0x89, 0x6c, 0x71, 0x86, 0xd4, 0x03, 0x3f, 0xf7, 0x98,
+ 0x64, 0x67, 0xe7, 0xf4, 0xdc, 0xe9, 0xbe, 0xa9, 0x3a, 0xbd, 0x52, 0x9d,
+ 0xbf, 0x2e, 0xd4, 0xf5, 0xee, 0x3e, 0x65, 0x2f, 0x8b, 0xdb, 0x89, 0x38,
+ 0xa3, 0x93, 0x5e, 0x73, 0xfb, 0x92, 0x53, 0xdf, 0x9d, 0xf6, 0x7f, 0x90,
+ 0xea, 0x30, 0xc8, 0xf5, 0xe8, 0x60, 0x9c, 0xed, 0xf1, 0xc0, 0x59, 0x82,
+ 0xfe, 0x5f, 0x1b, 0x4a, 0x52, 0x3d, 0x4f, 0x60, 0xfd, 0xd2, 0xf0, 0x15,
+ 0xf4, 0xe3, 0x18, 0xd5, 0x41, 0x44, 0x2f, 0x7c, 0x8c, 0x5d, 0x13, 0x34,
+ 0xdf, 0xe7, 0xfa, 0x8b, 0x9f, 0x42, 0x2f, 0x18, 0x4a, 0x9f, 0xb2, 0x4e,
+ 0x5f, 0x85, 0x7d, 0xf0, 0x7c, 0x92, 0xea, 0x77, 0x82, 0xa3, 0x1c, 0x33,
+ 0x88, 0x4f, 0x4a, 0xa1, 0xf3, 0xa4, 0x5a, 0x2b, 0xf4, 0x3d, 0x29, 0x2e,
+ 0x96, 0xf1, 0x7d, 0x3a, 0xa6, 0xce, 0x37, 0xe2, 0xf0, 0xce, 0x64, 0x08,
+ 0xfb, 0x4b, 0xf3, 0xe0, 0x8d, 0x7b, 0x1f, 0x29, 0x7d, 0x2c, 0x7b, 0x0f,
+ 0xf6, 0xd9, 0xc9, 0x39, 0x76, 0xec, 0x47, 0xfd, 0xd6, 0xfc, 0xb0, 0x67,
+ 0x58, 0x46, 0x03, 0xd4, 0x3f, 0x9f, 0xb0, 0x86, 0x21, 0x5f, 0xa7, 0xef,
+ 0x7f, 0xf9, 0x4a, 0x54, 0xb7, 0x53, 0x0d, 0x81, 0x2b, 0xba, 0x3e, 0x2c,
+ 0x13, 0xfa, 0x5c, 0x90, 0x3b, 0xc5, 0xfd, 0x9c, 0xb5, 0x15, 0xde, 0xb9,
+ 0x8f, 0x99, 0xed, 0xf0, 0x0e, 0x39, 0xdc, 0x0d, 0x19, 0xea, 0x22, 0xbe,
+ 0xf8, 0x17, 0xb8, 0xe7, 0xbc, 0x36, 0xcd, 0x15, 0x56, 0xab, 0xf8, 0x24,
+ 0x21, 0x71, 0xe9, 0xc2, 0xa9, 0x9c, 0x03, 0xe2, 0x57, 0xd9, 0x07, 0x8d,
+ 0x37, 0xe5, 0x30, 0x2c, 0xa6, 0xd8, 0xef, 0x24, 0xd7, 0xe3, 0x2c, 0xd7,
+ 0xe3, 0x37, 0x96, 0xd3, 0x31, 0x5d, 0x07, 0xc8, 0x8b, 0x34, 0xff, 0x69,
+ 0x8f, 0x7b, 0x43, 0xdf, 0x0f, 0xe8, 0xcf, 0x32, 0xf7, 0xf3, 0x2d, 0xe7,
+ 0x9e, 0xd0, 0x75, 0xdd, 0xea, 0xbe, 0xd0, 0xf8, 0xc7, 0xfa, 0xe8, 0xa4,
+ 0xe7, 0x39, 0x4b, 0x5f, 0x76, 0xc2, 0x4d, 0x63, 0x17, 0xa4, 0x53, 0xdf,
+ 0x6e, 0x9a, 0xdf, 0x86, 0x96, 0xab, 0xfa, 0x7c, 0x2a, 0xcf, 0x5f, 0xf5,
+ 0xfc, 0x35, 0x2c, 0xcd, 0x92, 0x8c, 0x36, 0x5e, 0x56, 0xf1, 0x5a, 0x3d,
+ 0xf8, 0xc3, 0x3d, 0xc7, 0xf5, 0xf5, 0x9d, 0x8e, 0x13, 0xb1, 0xf6, 0xdf,
+ 0x5c, 0x75, 0xcf, 0x2b, 0xe6, 0x33, 0xec, 0xe0, 0xbb, 0x79, 0x80, 0xfb,
+ 0xc0, 0x32, 0xf5, 0xa8, 0xf2, 0x3b, 0xc2, 0x71, 0xf2, 0x1c, 0xc7, 0xaa,
+ 0xe1, 0x0b, 0x95, 0xe7, 0xfa, 0x86, 0xe6, 0x09, 0x8d, 0x8f, 0x2a, 0x5f,
+ 0xe8, 0x3e, 0x50, 0xfc, 0xec, 0xcd, 0x55, 0xb5, 0xbf, 0x6d, 0x1b, 0xfe,
+ 0x58, 0x75, 0xfc, 0xdd, 0x72, 0x78, 0x22, 0x49, 0x71, 0x0f, 0xb3, 0xea,
+ 0xe6, 0xc1, 0x3f, 0x24, 0x0f, 0xaa, 0xef, 0xa6, 0x69, 0x39, 0xf3, 0xc2,
+ 0xfc, 0x37, 0xa3, 0xe2, 0xa5, 0x39, 0xff, 0xb4, 0xbe, 0xbf, 0x64, 0xfe,
+ 0xcc, 0x93, 0x63, 0xb5, 0x7c, 0x77, 0xdb, 0x23, 0xee, 0x7f, 0xf5, 0xc7,
+ 0xf3, 0x95, 0x65, 0xbe, 0xcf, 0x51, 0x9e, 0x95, 0xf1, 0x3c, 0xe3, 0x25,
+ 0x57, 0xdf, 0x07, 0xf4, 0x15, 0xf6, 0xb2, 0xbf, 0x9a, 0xf7, 0xfa, 0xb4,
+ 0x7f, 0xa8, 0x76, 0x4f, 0xad, 0x7d, 0x7d, 0xff, 0x03, 0x5b, 0xf0, 0xf8,
+ 0xe7, 0x1b, 0x78, 0x7f, 0x7d, 0xb6, 0x51, 0x7d, 0x4f, 0x79, 0xe2, 0xc4,
+ 0x16, 0x74, 0x3f, 0x85, 0x25, 0x9e, 0xe9, 0xbd, 0x26, 0xb4, 0xbd, 0x3f,
+ 0x88, 0xf7, 0xa4, 0x60, 0xfc, 0x9e, 0x7b, 0x98, 0xfd, 0x64, 0xc0, 0xc7,
+ 0x2f, 0x9c, 0xa1, 0xfe, 0xbe, 0x79, 0xf6, 0x3e, 0xf1, 0xf2, 0x7b, 0x2f,
+ 0x5f, 0x53, 0x7e, 0x77, 0x8b, 0xd5, 0x19, 0x8b, 0xf2, 0x1a, 0xda, 0x0b,
+ 0xf3, 0xfb, 0x87, 0xea, 0xfb, 0xad, 0xfc, 0x9a, 0x8c, 0x07, 0x69, 0x37,
+ 0xe1, 0x7e, 0x97, 0x6c, 0xce, 0x13, 0x73, 0x7f, 0x24, 0x81, 0x7d, 0x9a,
+ 0xbf, 0xdc, 0xf8, 0x79, 0x77, 0xa3, 0x7a, 0xff, 0xc0, 0xcd, 0xad, 0x83,
+ 0xde, 0x73, 0x71, 0xb2, 0xaf, 0x36, 0x4e, 0x46, 0xac, 0x94, 0xe1, 0x7f,
+ 0x84, 0x79, 0x65, 0x9c, 0x13, 0xf9, 0x29, 0x9a, 0xa0, 0x78, 0x85, 0xe3,
+ 0x84, 0x6b, 0x91, 0x8a, 0xe1, 0xdc, 0x85, 0xa7, 0xf0, 0xbd, 0x10, 0xc7,
+ 0x7a, 0x6b, 0x1c, 0xef, 0xcd, 0x91, 0xb0, 0x45, 0xf6, 0xad, 0x71, 0xc8,
+ 0x14, 0xf3, 0xcf, 0x8a, 0xc3, 0xcb, 0x90, 0xcb, 0xa1, 0xad, 0x78, 0x19,
+ 0xf7, 0xdb, 0xf5, 0x90, 0x5a, 0x97, 0x8f, 0xa0, 0x0c, 0x78, 0x69, 0xa8,
+ 0xdb, 0xa2, 0xef, 0xa3, 0x19, 0xe0, 0x48, 0x74, 0x7a, 0x9f, 0xab, 0x0d,
+ 0xfc, 0xd2, 0x5a, 0xe5, 0xef, 0x5a, 0x9e, 0xb7, 0x7a, 0x97, 0x1c, 0x1e,
+ 0x75, 0xe7, 0x01, 0xfe, 0x52, 0xfe, 0x49, 0x95, 0x7c, 0xb5, 0x13, 0x7e,
+ 0x37, 0x18, 0x2f, 0xbf, 0xf3, 0xbd, 0xdf, 0x24, 0xbe, 0x2a, 0xa3, 0x0e,
+ 0x2b, 0xe5, 0xfa, 0xfe, 0xe8, 0x3c, 0x74, 0x1c, 0x9c, 0x4b, 0x9f, 0xb3,
+ 0x1a, 0x17, 0x79, 0x9d, 0xe1, 0xfc, 0xef, 0xd0, 0xfb, 0x2f, 0xc5, 0xe7,
+ 0x55, 0x7e, 0xb1, 0x7e, 0x94, 0xee, 0xa1, 0xa0, 0x7c, 0xdf, 0x6b, 0xdd,
+ 0x7d, 0x3f, 0x8c, 0x50, 0x5e, 0x8d, 0x72, 0x41, 0xef, 0x77, 0x9f, 0xbb,
+ 0x39, 0x0f, 0xb9, 0x90, 0xd7, 0x7d, 0xd3, 0xfd, 0xd5, 0xfd, 0x44, 0xdf,
+ 0x53, 0x3d, 0x64, 0xd6, 0x5f, 0xe8, 0x21, 0x9c, 0xe7, 0x0b, 0xeb, 0xee,
+ 0x77, 0xf2, 0xc9, 0xac, 0xb2, 0x7f, 0x4d, 0x7c, 0x43, 0xf3, 0x28, 0xc4,
+ 0xf7, 0x2c, 0xab, 0x7c, 0x29, 0xf8, 0xaf, 0x96, 0x77, 0x0d, 0x71, 0x3d,
+ 0xc8, 0xcb, 0x7d, 0x7a, 0xee, 0xdc, 0xf3, 0x5b, 0xad, 0xbb, 0x3a, 0xc7,
+ 0x13, 0x1e, 0xfc, 0xa4, 0xcf, 0xa9, 0xec, 0xf3, 0x8c, 0x5f, 0x53, 0x0c,
+ 0x1d, 0xc1, 0xfb, 0xb0, 0x21, 0x8c, 0x39, 0x69, 0x08, 0x7b, 0xdd, 0xef,
+ 0x12, 0x3f, 0x11, 0xfa, 0x05, 0xb3, 0xa7, 0x31, 0x42, 0xe7, 0xba, 0x74,
+ 0xe3, 0x6b, 0x32, 0x7b, 0x7f, 0x29, 0x86, 0xf5, 0x96, 0x21, 0x84, 0x09,
+ 0x10, 0xde, 0x0d, 0x71, 0x01, 0xf3, 0xf0, 0xce, 0x02, 0xe4, 0xdb, 0xe2,
+ 0x49, 0xf8, 0x69, 0x9c, 0xa5, 0xfb, 0xd4, 0x6c, 0x41, 0x79, 0x4b, 0x4b,
+ 0x8c, 0xf3, 0xb4, 0x9f, 0x7e, 0xaf, 0x56, 0x44, 0x9c, 0x7f, 0x47, 0xf0,
+ 0xbc, 0x02, 0xcf, 0x81, 0x9a, 0xbe, 0xef, 0x14, 0xdf, 0x4a, 0x8f, 0x4b,
+ 0xfc, 0xc2, 0x0d, 0xe3, 0xdc, 0xac, 0xc7, 0xb9, 0xee, 0x6f, 0xda, 0xef,
+ 0x89, 0xeb, 0x81, 0xcd, 0xb8, 0xd6, 0xf9, 0xa9, 0x3a, 0xff, 0xe9, 0xbc,
+ 0x7b, 0x37, 0xfb, 0x57, 0xfb, 0x62, 0x12, 0xdf, 0xff, 0x17, 0xae, 0x21,
+ 0x8f, 0x76, 0xa9, 0xf8, 0x2d, 0x35, 0xf8, 0xf4, 0x9e, 0x3b, 0xf0, 0x9b,
+ 0x21, 0x79, 0xfc, 0x6f, 0x6a, 0x8c, 0x09, 0xd0, 0x18, 0x10, 0x00, 0x00,
+ 0x00 };
static u8 bnx2_TPAT_b09FwText[] = {
- 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0x7a,
- 0x6d, 0x39, 0xf1, 0xb8, 0x99, 0x96, 0x4d, 0x63, 0xd4, 0x99, 0x78, 0xfc,
- 0x43, 0x6d, 0x95, 0x69, 0x59, 0x15, 0x17, 0x56, 0x68, 0xba, 0xbb, 0x71,
- 0xad, 0xaa, 0xaa, 0x5c, 0x29, 0x88, 0x4a, 0x8d, 0x90, 0x59, 0x37, 0x6d,
- 0x79, 0x4b, 0x11, 0x0f, 0x48, 0x45, 0xca, 0xb2, 0x76, 0xd2, 0x08, 0x2d,
- 0x99, 0xd6, 0x85, 0x44, 0x42, 0x7d, 0x88, 0x9c, 0x3a, 0xee, 0xc3, 0xca,
- 0x9b, 0x8a, 0x07, 0x24, 0xa4, 0xa8, 0x55, 0x80, 0xc0, 0x1b, 0x7d, 0xa8,
- 0xf8, 0x79, 0x22, 0x12, 0x0f, 0x54, 0x08, 0x90, 0x85, 0x04, 0x2a, 0xa5,
- 0xe4, 0xf2, 0x7d, 0x77, 0x67, 0x92, 0xc5, 0x4d, 0x41, 0xe5, 0x81, 0x95,
- 0x56, 0x77, 0xe6, 0xde, 0x73, 0xce, 0x3d, 0xf7, 0xfc, 0x7c, 0xe7, 0xdc,
- 0x39, 0xec, 0xc8, 0x88, 0x64, 0xbf, 0x7d, 0xf8, 0x57, 0xbe, 0x72, 0xe2,
- 0xeb, 0x0f, 0xdc, 0x57, 0xb9, 0x0f, 0x8f, 0x0f, 0x3a, 0x77, 0x6b, 0x2d,
- 0xff, 0xc7, 0x9f, 0x2b, 0xe2, 0xe5, 0x7a, 0xf0, 0x2f, 0x25, 0x55, 0x4d,
- 0x0e, 0xd6, 0x22, 0x29, 0xb9, 0xd5, 0xea, 0xfc, 0x6a, 0x24, 0x92, 0x74,
- 0xe7, 0x82, 0xba, 0xfc, 0xd3, 0xb4, 0x7c, 0x2d, 0x9c, 0xff, 0x64, 0xf5,
- 0x83, 0x4f, 0x5f, 0xf9, 0x6c, 0xb8, 0x7b, 0xc1, 0x95, 0x92, 0x57, 0x3d,
- 0xa3, 0xbd, 0x69, 0x29, 0x4d, 0x80, 0xe7, 0xd5, 0x99, 0x6f, 0x17, 0x64,
- 0x7f, 0x2e, 0xab, 0x65, 0x54, 0x74, 0xdd, 0x5c, 0x99, 0x89, 0xbc, 0x36,
- 0x36, 0xb8, 0xdc, 0x0b, 0xa4, 0xd6, 0x2b, 0xcb, 0x9b, 0x3d, 0x5f, 0xde,
- 0xe8, 0x69, 0x39, 0xfe, 0xca, 0x49, 0x59, 0x8f, 0xc3, 0x72, 0xc3, 0x2d,
- 0x89, 0xaa, 0x86, 0xe5, 0xa6, 0x04, 0xb2, 0x15, 0x87, 0xad, 0x15, 0x77,
- 0xdc, 0x29, 0x55, 0x4b, 0xf2, 0xc2, 0x8c, 0x92, 0x0b, 0xfe, 0x31, 0x79,
- 0x26, 0x7a, 0x12, 0x7f, 0x2d, 0x6a, 0x43, 0x3b, 0xf5, 0xf3, 0x5a, 0xf4,
- 0xc6, 0x98, 0x3c, 0x12, 0x1b, 0xb3, 0x1a, 0x27, 0xe0, 0x9f, 0x9c, 0x7d,
- 0x56, 0x86, 0xa5, 0xe5, 0x85, 0x4b, 0x22, 0x05, 0xd2, 0x48, 0x2d, 0x2e,
- 0x48, 0xe2, 0xf5, 0xcf, 0x75, 0xc1, 0x8e, 0x1f, 0x98, 0x2d, 0xf0, 0x0f,
- 0x47, 0xf9, 0xfa, 0x1d, 0xd9, 0xba, 0x97, 0xad, 0x2b, 0x51, 0xe7, 0xc2,
- 0x60, 0x5b, 0xa6, 0x12, 0xed, 0xdc, 0x30, 0xb5, 0xe8, 0x2e, 0xaf, 0xb6,
- 0xad, 0xc5, 0xdd, 0xa0, 0xfe, 0x91, 0x57, 0x17, 0x03, 0x1e, 0x97, 0x3c,
- 0x5a, 0x55, 0xbf, 0x06, 0xbf, 0x4d, 0x25, 0xca, 0x11, 0xb9, 0xda, 0x29,
- 0x7b, 0xb5, 0xde, 0x37, 0x9c, 0x5a, 0x7a, 0xc3, 0x24, 0x7a, 0x44, 0x54,
- 0x94, 0x38, 0xb5, 0x6d, 0xca, 0x1a, 0x16, 0x1d, 0x0d, 0x81, 0x67, 0xd2,
- 0x53, 0xc2, 0xb1, 0x96, 0xcd, 0x53, 0x76, 0x03, 0xcf, 0x8b, 0x4e, 0xb2,
- 0xad, 0x9d, 0xda, 0xf9, 0x25, 0x3c, 0x97, 0xc0, 0x0f, 0xbb, 0xc4, 0x8e,
- 0x24, 0xcb, 0x0e, 0xf8, 0x78, 0x4e, 0x0f, 0xef, 0x4a, 0x12, 0xdf, 0x93,
- 0xb5, 0x4a, 0x58, 0x6e, 0xc9, 0xa3, 0x4e, 0x7d, 0xfb, 0x43, 0x4e, 0xf3,
- 0x96, 0x7a, 0x1f, 0x9e, 0xa3, 0x2e, 0x0f, 0x6b, 0x63, 0xd4, 0xfd, 0x43,
- 0xd9, 0x19, 0x29, 0x2f, 0xe9, 0xeb, 0xef, 0xf3, 0x1d, 0x3a, 0xa7, 0xd0,
- 0xbd, 0x5b, 0x84, 0x3e, 0xc6, 0x70, 0x9f, 0x5a, 0x54, 0x87, 0x9e, 0x09,
- 0xfe, 0xe1, 0x99, 0x26, 0x42, 0xe1, 0xf0, 0xb9, 0x7d, 0x12, 0x8c, 0x1b,
- 0xd3, 0x88, 0x43, 0x6f, 0x5b, 0x26, 0x64, 0x2d, 0x9d, 0xf0, 0x8e, 0xa4,
- 0x6d, 0xac, 0xb7, 0x48, 0x03, 0x7b, 0x88, 0x1c, 0xe9, 0x1a, 0x73, 0x29,
- 0x3e, 0x50, 0x94, 0xfd, 0x6a, 0xbe, 0x20, 0x61, 0x90, 0x60, 0xee, 0xf0,
- 0xa5, 0xbd, 0x36, 0xbb, 0x27, 0xd3, 0x81, 0x76, 0xc7, 0x3e, 0xf1, 0xa1,
- 0xec, 0x7d, 0xd4, 0xab, 0x9d, 0xcf, 0xed, 0x6c, 0xf5, 0x86, 0x5d, 0x63,
- 0xa9, 0x55, 0xa0, 0xff, 0x47, 0x9e, 0x29, 0xe7, 0xa3, 0x2e, 0xd4, 0x1b,
- 0xf4, 0xd1, 0x2d, 0x9d, 0x9e, 0xfa, 0x90, 0x4e, 0xd4, 0x47, 0x89, 0x3e,
- 0x57, 0x92, 0xf5, 0xe8, 0x71, 0x25, 0xfb, 0x8d, 0x59, 0x8f, 0xb5, 0xd3,
- 0x38, 0x7f, 0x2c, 0x7b, 0x46, 0x1c, 0xa6, 0x88, 0xc3, 0x14, 0x71, 0x99,
- 0x8a, 0xa7, 0xaa, 0x81, 0x5c, 0x99, 0x29, 0xc9, 0x75, 0x17, 0xfe, 0xec,
- 0xcd, 0x79, 0xaf, 0x21, 0xa6, 0x12, 0xcf, 0x11, 0x37, 0x4a, 0x66, 0x0b,
- 0xc2, 0x77, 0xc4, 0x92, 0x4e, 0xca, 0x2e, 0x62, 0x29, 0x39, 0xca, 0xb9,
- 0x21, 0x59, 0xb1, 0x67, 0x99, 0xf3, 0x4e, 0x09, 0x7d, 0x55, 0xc3, 0xda,
- 0x64, 0x70, 0x4a, 0x76, 0x11, 0x1f, 0x35, 0xac, 0x53, 0x56, 0xe8, 0xb5,
- 0x40, 0xd1, 0x4e, 0xdf, 0x45, 0x0e, 0xf8, 0x88, 0xfb, 0x99, 0xb2, 0x12,
- 0x47, 0x56, 0xe7, 0x61, 0x8b, 0xf9, 0x29, 0xd8, 0x88, 0x39, 0xc1, 0xb8,
- 0xfa, 0xeb, 0xb4, 0x8e, 0x4e, 0x22, 0x7e, 0x40, 0x8b, 0xf3, 0x9f, 0x4a,
- 0x67, 0xc0, 0x1f, 0x15, 0xa9, 0xe7, 0x56, 0xac, 0x65, 0x3d, 0xbd, 0xa2,
- 0x0a, 0xd1, 0xef, 0x1d, 0xd9, 0x1f, 0xb6, 0x12, 0x09, 0x5b, 0x4a, 0x29,
- 0x9f, 0x5b, 0xbf, 0x84, 0x3c, 0x7a, 0xd3, 0xea, 0xaf, 0xc1, 0x57, 0xce,
- 0xf4, 0xa7, 0xdd, 0x45, 0x36, 0x3b, 0x61, 0xbc, 0x08, 0xdd, 0xae, 0xc2,
- 0xff, 0xb4, 0xf9, 0xa5, 0x2e, 0x64, 0x77, 0x1c, 0xe6, 0xae, 0xb4, 0xbb,
- 0xa4, 0xb3, 0x69, 0xbe, 0xa2, 0xab, 0xb2, 0xdc, 0xee, 0x9c, 0x34, 0x6e,
- 0x24, 0x2b, 0x85, 0x2a, 0xfd, 0x36, 0xba, 0x00, 0x3f, 0x2c, 0xb7, 0xbb,
- 0x13, 0x8f, 0x6d, 0x76, 0xa4, 0x75, 0x77, 0x55, 0x5a, 0x6e, 0x45, 0xdd,
- 0xa5, 0x64, 0x0c, 0x72, 0xab, 0xd8, 0x87, 0x71, 0x15, 0x06, 0x75, 0x77,
- 0xe2, 0xb1, 0x8b, 0x9d, 0x7b, 0x90, 0xb7, 0xf2, 0x41, 0xad, 0x12, 0x21,
- 0x77, 0xaf, 0x1e, 0x74, 0x25, 0x92, 0xb5, 0x5e, 0x49, 0x6a, 0xe9, 0x84,
- 0xac, 0xf7, 0x24, 0x79, 0x6a, 0x06, 0xfb, 0x55, 0xf0, 0xde, 0x9b, 0x97,
- 0x56, 0x6f, 0x62, 0x45, 0x55, 0x5b, 0x92, 0xf4, 0xd6, 0xf1, 0x2f, 0x49,
- 0xa3, 0x53, 0x2a, 0x5d, 0xec, 0xb4, 0xc8, 0x5f, 0x72, 0xaa, 0x81, 0x3e,
- 0xdc, 0xdd, 0x65, 0xdc, 0x40, 0xce, 0xf0, 0x97, 0x54, 0x55, 0x4b, 0xd3,
- 0xf7, 0x21, 0xc3, 0x81, 0x4d, 0xa8, 0xeb, 0x2c, 0xf6, 0xed, 0x8f, 0xad,
- 0x1e, 0x7d, 0x37, 0x24, 0xed, 0x78, 0x1e, 0x76, 0x62, 0xd4, 0x0e, 0xc9,
- 0x5a, 0xf4, 0x9e, 0x79, 0x1a, 0xb1, 0xfa, 0x9a, 0x98, 0x7b, 0x6a, 0xc0,
- 0x93, 0x1a, 0x4c, 0xfa, 0x42, 0x54, 0x96, 0x53, 0xd8, 0xb7, 0xcf, 0xb7,
- 0x0e, 0x1d, 0xc8, 0x37, 0x06, 0xbe, 0x06, 0xf8, 0x7c, 0x39, 0x6d, 0x79,
- 0xc7, 0xc0, 0xbb, 0x9b, 0xf1, 0xce, 0x95, 0x17, 0x25, 0x06, 0xcf, 0x64,
- 0xb0, 0x08, 0x7f, 0xae, 0xf8, 0x0d, 0xf0, 0x36, 0xa0, 0x03, 0xc6, 0x54,
- 0x5a, 0xba, 0x42, 0xb9, 0x61, 0xf9, 0x69, 0xe6, 0x83, 0x95, 0xd9, 0x82,
- 0x4c, 0xe8, 0x95, 0x96, 0x20, 0x67, 0x01, 0xe3, 0x3b, 0xa6, 0x9d, 0x02,
- 0x77, 0x7c, 0x3e, 0xbf, 0x69, 0x54, 0x15, 0x31, 0x5a, 0x89, 0x82, 0xb6,
- 0xf0, 0xbd, 0x28, 0x75, 0xe4, 0x99, 0x8a, 0xc6, 0xa4, 0xe9, 0x39, 0x8e,
- 0xaa, 0xba, 0xd2, 0x44, 0x84, 0x26, 0xcb, 0xda, 0xce, 0xad, 0x20, 0xce,
- 0x54, 0xf5, 0x7b, 0xaa, 0x5f, 0x0f, 0x0a, 0xa0, 0x41, 0x6e, 0x46, 0xa3,
- 0xb0, 0xc1, 0x38, 0x68, 0xcf, 0x62, 0x7e, 0x0a, 0xf8, 0x39, 0x0e, 0x1a,
- 0x8e, 0xcc, 0x11, 0xda, 0x85, 0xf4, 0x15, 0xe8, 0x98, 0xcf, 0x55, 0x60,
- 0x9b, 0xc1, 0xb4, 0xc9, 0x7d, 0x0c, 0x9a, 0x54, 0x67, 0x79, 0x37, 0x98,
- 0x4b, 0xf9, 0x7a, 0x80, 0xf5, 0xab, 0x9f, 0x52, 0xb2, 0x6b, 0x2e, 0x46,
- 0x8c, 0x61, 0x79, 0xaf, 0x11, 0x25, 0xe3, 0xae, 0xcd, 0xf3, 0x3c, 0xdf,
- 0x39, 0xb2, 0x16, 0x9c, 0x39, 0xb8, 0x1a, 0x39, 0xee, 0xfa, 0xfc, 0x01,
- 0x69, 0xf9, 0x61, 0x5c, 0x87, 0xbf, 0xd7, 0x53, 0xe6, 0xc6, 0x18, 0xce,
- 0x1d, 0x22, 0xea, 0x26, 0xf1, 0x9c, 0x1c, 0x04, 0x0f, 0xfc, 0xd8, 0x82,
- 0x2c, 0x8e, 0x88, 0x99, 0x34, 0x84, 0x8e, 0xb0, 0x47, 0x34, 0xe7, 0x1d,
- 0x61, 0x3c, 0xfa, 0x5c, 0x63, 0x8d, 0x79, 0xf5, 0x50, 0x2d, 0x0a, 0xe3,
- 0x66, 0x96, 0x2b, 0x6f, 0xc1, 0xb6, 0xed, 0x94, 0xf5, 0x22, 0xaf, 0x11,
- 0xcc, 0x0f, 0xc6, 0x4a, 0x8e, 0xb1, 0xe0, 0x89, 0x98, 0x9f, 0xa5, 0x0c,
- 0x6b, 0x6b, 0x19, 0x8e, 0x2e, 0x40, 0x0f, 0x63, 0x9e, 0x00, 0x86, 0xb6,
- 0x63, 0x1b, 0x9f, 0xad, 0x40, 0xdd, 0x30, 0x93, 0xd3, 0xb4, 0xb9, 0x31,
- 0x27, 0xe2, 0x45, 0xd0, 0xfe, 0x16, 0xf6, 0x5a, 0x02, 0x8e, 0x12, 0x7b,
- 0xb9, 0x77, 0x55, 0xd7, 0x3a, 0xfb, 0xa0, 0x4b, 0x00, 0x7c, 0x83, 0x0d,
- 0x2c, 0xde, 0x0e, 0x23, 0xdf, 0x99, 0xf3, 0x61, 0xb0, 0x22, 0x9c, 0x97,
- 0x61, 0x85, 0xf7, 0x26, 0xfc, 0xb4, 0x5e, 0x79, 0xd4, 0x69, 0x6c, 0xbf,
- 0x9f, 0xf9, 0x48, 0xc6, 0x14, 0x6a, 0x49, 0xd3, 0x27, 0x5f, 0x11, 0x7c,
- 0xfb, 0xc0, 0xf3, 0x77, 0xac, 0x15, 0x30, 0x0e, 0xca, 0xb1, 0xb8, 0x8d,
- 0xbd, 0x02, 0xec, 0xb5, 0x24, 0xba, 0xfa, 0x3c, 0xb0, 0x67, 0x2a, 0x68,
- 0xc8, 0xf7, 0x55, 0xbf, 0x46, 0xd2, 0x37, 0x5f, 0x18, 0xf0, 0x4d, 0x20,
- 0xae, 0xcd, 0xc1, 0x87, 0xb2, 0x98, 0x22, 0x66, 0x3e, 0x98, 0xad, 0xfb,
- 0xc0, 0xbe, 0xcf, 0x64, 0x18, 0x5e, 0x22, 0x0e, 0xca, 0x19, 0x8b, 0x83,
- 0x45, 0xe2, 0x20, 0x70, 0xa5, 0xb5, 0x00, 0x7b, 0xc7, 0xef, 0x02, 0x5f,
- 0xea, 0xf0, 0xc4, 0x4f, 0x3a, 0x1a, 0x71, 0xe5, 0x82, 0x9f, 0x75, 0xf8,
- 0xf3, 0xae, 0x8c, 0x84, 0xde, 0xbb, 0xc0, 0x9b, 0xe4, 0x28, 0xf3, 0xc0,
- 0x18, 0xe4, 0x3a, 0xb0, 0x6a, 0xba, 0x7c, 0x0a, 0x71, 0xef, 0x02, 0x27,
- 0xb4, 0x70, 0xdf, 0xbc, 0x6e, 0xe6, 0xf5, 0x9b, 0xbf, 0xb7, 0x1d, 0xb8,
- 0x19, 0xb5, 0xee, 0x73, 0x90, 0x31, 0x15, 0x1c, 0x81, 0x1f, 0xd7, 0x16,
- 0xfe, 0x1b, 0xcf, 0x6f, 0x32, 0x1e, 0xd4, 0x90, 0x0a, 0xf7, 0x15, 0x69,
- 0x74, 0x69, 0x87, 0x18, 0x76, 0xb0, 0x18, 0x84, 0x9c, 0x8f, 0x91, 0xf3,
- 0x22, 0x4d, 0x62, 0x05, 0x30, 0x8c, 0xb8, 0xb7, 0x06, 0x7a, 0x55, 0x19,
- 0x82, 0x5d, 0x11, 0x4b, 0x4a, 0x4a, 0xba, 0x7a, 0x54, 0xaf, 0x83, 0xb6,
- 0x50, 0x5d, 0xd6, 0x5b, 0xd1, 0x31, 0x37, 0xef, 0x97, 0xda, 0x1d, 0x71,
- 0x6a, 0x7d, 0x3f, 0x67, 0x74, 0x8f, 0x65, 0x74, 0x4b, 0x83, 0x74, 0x98,
- 0x6f, 0x64, 0xf3, 0x09, 0xe6, 0x3f, 0x91, 0xd9, 0x9c, 0xb5, 0xa0, 0x84,
- 0x3a, 0xcb, 0x3a, 0x10, 0x06, 0x81, 0xfa, 0x4f, 0x75, 0x60, 0x61, 0x00,
- 0xbb, 0x45, 0xd9, 0xbe, 0xc2, 0x67, 0x4c, 0x0e, 0x9e, 0x75, 0x58, 0x49,
- 0x74, 0x33, 0x3e, 0xf1, 0xdb, 0xcc, 0xf6, 0x21, 0x2d, 0xf1, 0x7a, 0x90,
- 0x16, 0x69, 0x04, 0xbb, 0xa8, 0xb3, 0xb7, 0xb3, 0xd9, 0x01, 0xac, 0x21,
- 0xe7, 0x53, 0x57, 0x1e, 0xd6, 0xcc, 0xef, 0x7b, 0xb5, 0x3d, 0xc7, 0x0e,
- 0xe8, 0x77, 0x26, 0x2c, 0xce, 0x2c, 0x75, 0x86, 0x20, 0x7e, 0x54, 0x8e,
- 0x23, 0x9f, 0x9f, 0x86, 0xef, 0x2f, 0xc6, 0x0a, 0xdd, 0x02, 0x6b, 0x8e,
- 0x41, 0x1c, 0x86, 0xd6, 0x17, 0xb5, 0x68, 0x0d, 0x91, 0xfc, 0x2d, 0xb9,
- 0x3a, 0x3f, 0x22, 0x85, 0x4b, 0xd4, 0x01, 0xfd, 0xd2, 0xe6, 0xe0, 0x3e,
- 0x73, 0xd8, 0x67, 0x02, 0x18, 0x78, 0x3f, 0xea, 0x8b, 0x2f, 0x7a, 0x1a,
- 0x58, 0x9b, 0x96, 0x9c, 0x3a, 0xe4, 0xab, 0x4b, 0x3c, 0x3f, 0x31, 0xb8,
- 0x94, 0xd5, 0x36, 0xe6, 0xd6, 0x10, 0x6a, 0xfa, 0x1f, 0x91, 0xbb, 0x4a,
- 0x56, 0x2b, 0xc6, 0x1c, 0x89, 0x7f, 0x00, 0xfb, 0x62, 0x6e, 0x93, 0x6b,
- 0xbb, 0x98, 0xe7, 0x1c, 0x65, 0x30, 0x16, 0x0f, 0xa0, 0xae, 0x61, 0xcf,
- 0xa3, 0xe4, 0x19, 0x42, 0xcd, 0x27, 0xfe, 0x63, 0xdc, 0xe4, 0x3b, 0xcf,
- 0x44, 0x6c, 0x73, 0x31, 0x8e, 0x60, 0xe4, 0x99, 0x7e, 0x91, 0xf9, 0x8a,
- 0xcf, 0xc6, 0xe8, 0xea, 0xa8, 0xd4, 0x3b, 0x11, 0x30, 0x76, 0xaa, 0x7c,
- 0x5c, 0xb8, 0x86, 0xf7, 0x2e, 0xe7, 0xbd, 0x81, 0x79, 0x3c, 0x77, 0xad,
- 0xce, 0xa8, 0xed, 0x79, 0xff, 0xb2, 0x06, 0xc3, 0xa2, 0xc7, 0xd8, 0x64,
- 0xaf, 0xc2, 0xfa, 0x67, 0x71, 0x6b, 0x96, 0x7d, 0xca, 0xeb, 0x1d, 0xd6,
- 0x42, 0xcd, 0xbc, 0x44, 0x00, 0x1c, 0x92, 0xba, 0x9f, 0x9f, 0x0b, 0x71,
- 0x1c, 0x53, 0x36, 0x65, 0x4c, 0xc2, 0x76, 0xec, 0x47, 0xa2, 0xb2, 0x76,
- 0xa6, 0x92, 0x26, 0xf9, 0xba, 0x05, 0x29, 0x6c, 0xcc, 0x8b, 0x7b, 0xd6,
- 0xc8, 0x66, 0x5f, 0x9e, 0xb7, 0x2c, 0xbe, 0xd4, 0x5e, 0xa2, 0x1e, 0x98,
- 0xdf, 0x61, 0x3d, 0x0c, 0x81, 0x67, 0xc5, 0x6c, 0xdf, 0xb2, 0x34, 0x3b,
- 0x91, 0xd7, 0x10, 0x8c, 0xdd, 0x3b, 0xe0, 0xbb, 0x22, 0xce, 0xac, 0xe5,
- 0x62, 0xa7, 0xbf, 0x17, 0x73, 0xee, 0xb9, 0xb8, 0xbf, 0x57, 0x43, 0x7e,
- 0x89, 0xbd, 0xc4, 0x57, 0xc2, 0x3e, 0x12, 0x7d, 0xe3, 0x39, 0x8d, 0xfd,
- 0x68, 0xa3, 0x02, 0x7a, 0xdb, 0xd9, 0xec, 0x3c, 0x21, 0xe8, 0x34, 0x6c,
- 0x4e, 0x5b, 0x73, 0x0f, 0xc6, 0xe2, 0x3f, 0x0c, 0xf1, 0x05, 0x75, 0x05,
- 0xfa, 0xe2, 0xbd, 0xc7, 0x3d, 0x26, 0xe4, 0xc5, 0xd4, 0x62, 0xad, 0x77,
- 0x02, 0x98, 0xd5, 0xe8, 0xfc, 0x2d, 0xaf, 0x3d, 0x49, 0x1b, 0xf8, 0xfb,
- 0xac, 0x8c, 0x8a, 0xde, 0x19, 0x95, 0xe7, 0xd0, 0xef, 0x15, 0x36, 0x50,
- 0xe7, 0x61, 0x63, 0x75, 0xb6, 0x35, 0xcb, 0x9e, 0xed, 0x32, 0x72, 0x79,
- 0xb5, 0x12, 0xc5, 0xae, 0x33, 0x2d, 0x67, 0xbe, 0x1b, 0xce, 0x6e, 0xdb,
- 0x7c, 0xc6, 0xfa, 0x4e, 0x20, 0xa7, 0xbb, 0x91, 0x9c, 0xe9, 0x7a, 0xd0,
- 0xcb, 0xbb, 0xd5, 0xd7, 0x46, 0xc4, 0xdb, 0x06, 0xfe, 0xc4, 0x53, 0x9e,
- 0x0b, 0x3e, 0xa8, 0xd2, 0x6e, 0xec, 0x63, 0xe9, 0x5f, 0xe2, 0xdb, 0xa3,
- 0x78, 0x1e, 0x11, 0xf7, 0x1c, 0xfb, 0x4e, 0xc6, 0x24, 0xfd, 0x33, 0xd8,
- 0x0b, 0x13, 0xfb, 0x20, 0x73, 0x87, 0xb9, 0x9f, 0xe7, 0x66, 0x9e, 0xab,
- 0xc4, 0x01, 0xed, 0x2c, 0xc2, 0x5e, 0xd7, 0x62, 0xe6, 0xeb, 0x0d, 0x73,
- 0xcd, 0xf6, 0x6e, 0x1e, 0xfb, 0xe2, 0x81, 0xde, 0x2d, 0xef, 0x7b, 0x18,
- 0xaf, 0xe5, 0x81, 0x7c, 0xbd, 0x6e, 0x73, 0xf5, 0x0d, 0xe4, 0xed, 0xcb,
- 0x69, 0xd9, 0xe6, 0xec, 0xe1, 0x07, 0x6e, 0x97, 0xb3, 0x97, 0x3f, 0x46,
- 0xce, 0xfe, 0x30, 0xcb, 0xd9, 0xa2, 0x8d, 0x6b, 0xb5, 0x31, 0xb8, 0xf6,
- 0x23, 0xac, 0x0d, 0x65, 0x77, 0x0a, 0x6d, 0x3b, 0xe8, 0xc3, 0x0f, 0xd2,
- 0x47, 0xb9, 0x7f, 0xfa, 0x71, 0x5a, 0xd7, 0xa4, 0x81, 0x0f, 0x37, 0x46,
- 0x11, 0x4f, 0xcc, 0xe9, 0x3c, 0x9e, 0x02, 0xc4, 0x72, 0xce, 0x8f, 0x7e,
- 0xf3, 0x28, 0x63, 0xa1, 0x60, 0xf3, 0xc6, 0xad, 0xe6, 0x34, 0x65, 0x59,
- 0x44, 0x2f, 0xf7, 0x63, 0x8e, 0xdd, 0x7e, 0xac, 0x14, 0x37, 0x4a, 0xf2,
- 0xfc, 0x0c, 0xb1, 0x2b, 0x8c, 0xaf, 0x42, 0xe7, 0x6b, 0x91, 0x2f, 0x85,
- 0x69, 0xe6, 0x33, 0xab, 0x51, 0x11, 0x31, 0x84, 0xbb, 0x55, 0x6a, 0x4e,
- 0xa2, 0xdf, 0x0a, 0x34, 0xfc, 0xfc, 0x32, 0xe2, 0x88, 0xd8, 0x8a, 0x98,
- 0x98, 0xdd, 0x44, 0x4c, 0x1c, 0xe7, 0xbb, 0xdd, 0xb7, 0x60, 0x69, 0x5d,
- 0xbb, 0xbf, 0x0f, 0xfd, 0x4b, 0x32, 0x74, 0xce, 0xe0, 0x4e, 0x75, 0x8b,
- 0xef, 0xb4, 0x8d, 0x5f, 0x60, 0x09, 0xe6, 0x57, 0x6d, 0xfc, 0xd2, 0xa7,
- 0x8c, 0x7b, 0x63, 0x7e, 0x67, 0xf3, 0xe6, 0xd7, 0x16, 0x03, 0xae, 0xc5,
- 0x36, 0x9e, 0x63, 0xf6, 0x9b, 0xa7, 0xbb, 0x3f, 0xd7, 0x16, 0x23, 0x36,
- 0x8c, 0x9c, 0x8a, 0x6d, 0xac, 0xcd, 0xbe, 0x81, 0x63, 0xbf, 0xd6, 0xcf,
- 0x85, 0x01, 0x39, 0x93, 0xde, 0x23, 0x90, 0x83, 0x9a, 0x17, 0xac, 0xb1,
- 0x3f, 0x88, 0xa7, 0xd0, 0x2f, 0x81, 0xae, 0xbb, 0x17, 0x2f, 0xc6, 0x31,
- 0xd2, 0xde, 0x7f, 0x80, 0x5c, 0x0f, 0x36, 0xa4, 0x1c, 0xea, 0x4d, 0xbd,
- 0x46, 0x25, 0x3a, 0x9b, 0xeb, 0xf4, 0x17, 0xab, 0xcb, 0xbf, 0xcb, 0xc3,
- 0xfa, 0xce, 0xed, 0xf8, 0xbc, 0x01, 0xbe, 0x3f, 0xdf, 0x86, 0x0f, 0xeb,
- 0x3b, 0xe4, 0x19, 0xb9, 0xd9, 0x6b, 0xd4, 0x6f, 0xc6, 0x75, 0x82, 0xb8,
- 0x27, 0xef, 0xde, 0xbb, 0xdc, 0x60, 0x0e, 0xe4, 0x35, 0x9e, 0x71, 0xce,
- 0x3d, 0xf3, 0x58, 0xcf, 0x63, 0x3c, 0x8f, 0xf9, 0x3c, 0xd6, 0xc3, 0xf8,
- 0x19, 0xe9, 0xfb, 0x57, 0x6f, 0x84, 0xd8, 0x7f, 0xe4, 0x7f, 0xb8, 0xb7,
- 0x10, 0x23, 0x24, 0xb9, 0x75, 0xd7, 0xfb, 0x69, 0xd6, 0xaf, 0x94, 0x98,
- 0x6b, 0xf8, 0xb3, 0x8f, 0xdf, 0x45, 0x7f, 0x10, 0x67, 0xb6, 0x4d, 0xb2,
- 0xb1, 0x4f, 0xd3, 0xef, 0x07, 0xbf, 0x9a, 0x61, 0xf2, 0x17, 0xfb, 0xf5,
- 0x47, 0xf2, 0x9c, 0x62, 0x0e, 0xd9, 0x9c, 0xe2, 0x79, 0x70, 0x0f, 0x37,
- 0x66, 0x19, 0x7e, 0x7c, 0x3e, 0xce, 0xf3, 0x08, 0xf1, 0xf4, 0x40, 0x9e,
- 0xe3, 0xb0, 0x53, 0x74, 0xc3, 0xe8, 0xe9, 0x04, 0x36, 0xe3, 0xdd, 0xb7,
- 0x81, 0xde, 0x89, 0x76, 0x5a, 0x72, 0x9e, 0xb8, 0x79, 0xdf, 0xdd, 0xdb,
- 0x27, 0xd1, 0x6e, 0xb4, 0xeb, 0xa0, 0xdd, 0xc2, 0x78, 0x5c, 0x11, 0x03,
- 0x6e, 0x87, 0x13, 0x79, 0x3d, 0x07, 0x06, 0x4d, 0xe7, 0x76, 0xfa, 0xd8,
- 0x35, 0x3d, 0xe9, 0x7f, 0x2b, 0xd8, 0x8b, 0x0f, 0xdb, 0xee, 0x00, 0x3e,
- 0xdc, 0xa6, 0xe7, 0xa4, 0x0c, 0xda, 0x00, 0xf5, 0xcd, 0xf6, 0x21, 0xec,
- 0x31, 0x6f, 0x18, 0xd7, 0xf6, 0x9b, 0xc4, 0x46, 0xf6, 0x99, 0xdf, 0x2c,
- 0xc8, 0xc8, 0x3e, 0xfb, 0x9e, 0x6c, 0x73, 0x64, 0x4c, 0x48, 0xbf, 0x6e,
- 0x59, 0xfd, 0x1f, 0xcf, 0xf4, 0xef, 0xeb, 0x2c, 0xea, 0xa3, 0x30, 0x8d,
- 0xba, 0x7a, 0xd0, 0x35, 0xcc, 0xed, 0xd2, 0x52, 0xd5, 0x13, 0xd2, 0xa8,
- 0xb0, 0x5f, 0x12, 0xdc, 0xb5, 0xa0, 0xc3, 0x02, 0xf5, 0x28, 0x43, 0x8f,
- 0x51, 0xdc, 0x4d, 0xc2, 0xa5, 0x96, 0x84, 0xc9, 0x0a, 0x08, 0x67, 0xbe,
- 0x43, 0xbb, 0x1d, 0xd3, 0x5b, 0x1d, 0xda, 0xed, 0x49, 0xbd, 0xde, 0x99,
- 0x44, 0x7f, 0x18, 0xc2, 0xdb, 0xe1, 0xec, 0x25, 0x61, 0x8c, 0xcd, 0xc5,
- 0x1c, 0x4f, 0x0b, 0xfb, 0xb1, 0x63, 0x7a, 0xaa, 0xcb, 0xf1, 0x49, 0x1d,
- 0x75, 0x07, 0xe5, 0xfe, 0xc9, 0x00, 0x13, 0x93, 0xeb, 0xc8, 0xa3, 0x17,
- 0x7b, 0xfd, 0xbd, 0x71, 0x3f, 0xcc, 0xe4, 0x62, 0x2e, 0xcd, 0x65, 0x0b,
- 0x71, 0x8a, 0xb2, 0x21, 0x77, 0x32, 0xfe, 0x99, 0xdd, 0x83, 0xf7, 0xa3,
- 0x8f, 0xda, 0xe3, 0xae, 0xfc, 0xfb, 0x04, 0x72, 0xa7, 0x60, 0xb1, 0x67,
- 0x2d, 0xc5, 0x9d, 0xda, 0x37, 0xa6, 0x19, 0xbd, 0x0d, 0xdb, 0xa1, 0x47,
- 0x98, 0xf7, 0xf0, 0x07, 0xae, 0x2e, 0x73, 0x0d, 0x7d, 0x38, 0xee, 0x82,
- 0xbc, 0xcf, 0xad, 0xa5, 0x5c, 0x63, 0x8c, 0xa3, 0x57, 0x9c, 0xff, 0x15,
- 0x68, 0xdf, 0x31, 0xad, 0x9e, 0xb2, 0xf7, 0x75, 0x15, 0xe1, 0x1e, 0xd6,
- 0x63, 0x3f, 0x23, 0x4e, 0x23, 0x95, 0xa0, 0x19, 0x2f, 0xd8, 0xfb, 0x5a,
- 0xe2, 0x05, 0xbc, 0x93, 0xa2, 0x07, 0x9d, 0x1f, 0xe8, 0x41, 0xe7, 0xd1,
- 0x83, 0x8e, 0x15, 0x11, 0xe7, 0x09, 0xee, 0xa1, 0xaa, 0xd9, 0xcf, 0x9b,
- 0x31, 0xde, 0x39, 0xdb, 0xbe, 0xec, 0x43, 0x77, 0x05, 0xdd, 0x22, 0xec,
- 0xcf, 0xf5, 0x3b, 0xb3, 0xef, 0x5a, 0xa3, 0xa0, 0x4f, 0x6c, 0x3f, 0xd6,
- 0xf6, 0x8b, 0xd2, 0x8c, 0x49, 0x73, 0x28, 0xa3, 0xf9, 0xf2, 0x1e, 0x9a,
- 0x3b, 0x79, 0x46, 0xca, 0x96, 0xe6, 0x2b, 0xcc, 0x3b, 0xd6, 0xd2, 0x62,
- 0x96, 0x6f, 0x27, 0xf0, 0x3c, 0x94, 0x3d, 0xe7, 0xf4, 0xf7, 0xee, 0xe1,
- 0x7f, 0xc8, 0xe9, 0xbf, 0xf3, 0x99, 0x3a, 0x27, 0xec, 0x93, 0x21, 0x6f,
- 0xc1, 0xe9, 0x7f, 0x27, 0xc1, 0x85, 0x73, 0x84, 0x3e, 0xe9, 0xf7, 0x17,
- 0xc0, 0x60, 0x74, 0x5f, 0x53, 0xb0, 0xbb, 0x31, 0xed, 0x05, 0xe2, 0xda,
- 0xdc, 0xec, 0x11, 0x8b, 0x6f, 0x6a, 0x42, 0x49, 0x8e, 0xb9, 0x83, 0xcf,
- 0x18, 0x17, 0xec, 0x37, 0x03, 0xbc, 0xf7, 0x65, 0x6c, 0xe1, 0xfe, 0x2c,
- 0xc8, 0xe1, 0x96, 0xd5, 0xcb, 0xe9, 0xdf, 0x8b, 0xbc, 0x1a, 0xeb, 0x01,
- 0xea, 0xc6, 0x0c, 0xf5, 0xba, 0xf9, 0x6d, 0x63, 0x05, 0xb5, 0xe6, 0x2d,
- 0xc4, 0x3e, 0xf2, 0xd3, 0xf6, 0x58, 0x5b, 0xf6, 0xdb, 0x02, 0xea, 0xd0,
- 0x08, 0xee, 0x4b, 0xd1, 0xcd, 0x6f, 0x0c, 0x72, 0x01, 0x34, 0x17, 0xb1,
- 0x76, 0xba, 0x9b, 0xf7, 0xbc, 0xe8, 0xf3, 0x81, 0x7b, 0xab, 0xd1, 0xfb,
- 0xa6, 0xe9, 0x0f, 0xd2, 0xf2, 0xf7, 0x2f, 0x97, 0xa2, 0x15, 0x3a, 0x18,
- 0x15, 0x00, 0x00, 0x00 };
+ 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0xee,
+ 0x78, 0xb1, 0xe3, 0x71, 0x3b, 0xa4, 0xdb, 0x62, 0xc8, 0x8c, 0x7d, 0xfd,
+ 0x03, 0xb6, 0xc2, 0x94, 0x6e, 0xdb, 0xad, 0x18, 0x45, 0xc3, 0xec, 0xda,
+ 0xb1, 0xa2, 0x3c, 0xb8, 0x52, 0xa4, 0x46, 0x6a, 0x04, 0x66, 0x1d, 0x93,
+ 0x3e, 0xa6, 0x88, 0x07, 0xa4, 0x3e, 0x64, 0x59, 0x3b, 0xa9, 0x1f, 0x96,
+ 0x2c, 0xb8, 0xc8, 0x7e, 0x41, 0x28, 0x72, 0x6a, 0xbb, 0x48, 0x8b, 0x37,
+ 0x11, 0x48, 0x3c, 0x45, 0x8d, 0x1c, 0x14, 0x55, 0xea, 0x0b, 0x0f, 0xfc,
+ 0x3d, 0x46, 0x6a, 0x45, 0xfb, 0x50, 0x90, 0x55, 0xa9, 0xa8, 0x82, 0xe0,
+ 0xcb, 0x77, 0x66, 0x67, 0x9c, 0x4d, 0xec, 0x08, 0x9e, 0xb0, 0xb4, 0xba,
+ 0x33, 0x73, 0xef, 0x39, 0xf7, 0xdc, 0x73, 0xbe, 0xef, 0x9c, 0x73, 0x3d,
+ 0x64, 0x50, 0x9e, 0x92, 0xbf, 0x3e, 0xfc, 0x8a, 0xdf, 0xbd, 0xf8, 0x83,
+ 0x67, 0x8f, 0xbf, 0x70, 0x1c, 0x8f, 0xcf, 0x1b, 0xfd, 0x59, 0x49, 0xff,
+ 0xc7, 0x3f, 0x93, 0xc8, 0x4e, 0xed, 0xe0, 0x1f, 0x59, 0x22, 0xb8, 0xfd,
+ 0x54, 0xa4, 0xc8, 0x32, 0x83, 0xdf, 0x7c, 0x6d, 0x5e, 0x11, 0x85, 0xad,
+ 0x09, 0xb7, 0x4c, 0xff, 0xd6, 0x35, 0x47, 0x12, 0x7f, 0xff, 0x72, 0x70,
+ 0xff, 0xeb, 0xb7, 0x5e, 0xf4, 0x76, 0xaf, 0x99, 0x64, 0xd9, 0xc1, 0xb2,
+ 0xb4, 0x47, 0xc9, 0x1a, 0x84, 0xcc, 0xcf, 0xc7, 0xbe, 0x2d, 0xe8, 0x48,
+ 0xaa, 0xab, 0xa6, 0x85, 0xba, 0xa7, 0x6f, 0x8d, 0x29, 0xbb, 0x8e, 0x0d,
+ 0x6e, 0xb4, 0x5d, 0x8a, 0xda, 0x05, 0x7a, 0xb7, 0xed, 0xd0, 0xcd, 0xb6,
+ 0xa4, 0x85, 0xb7, 0x2e, 0xd1, 0x92, 0xef, 0x15, 0x2a, 0xa6, 0x45, 0x22,
+ 0xf0, 0x0a, 0x55, 0x72, 0x69, 0xc3, 0xf7, 0x6a, 0x73, 0xe6, 0x80, 0x61,
+ 0x05, 0x16, 0xbd, 0x31, 0x26, 0xe8, 0x9a, 0x73, 0x8e, 0xbe, 0xa7, 0xce,
+ 0xe2, 0x27, 0x49, 0xac, 0x48, 0xa3, 0xbc, 0x26, 0x49, 0xae, 0xf4, 0xd3,
+ 0x49, 0x5f, 0xeb, 0x79, 0x3f, 0x84, 0xfc, 0xf0, 0xf8, 0x05, 0xea, 0xa1,
+ 0x9a, 0xed, 0xcd, 0x10, 0x65, 0x78, 0x0d, 0x45, 0x7e, 0x86, 0x42, 0xbb,
+ 0x73, 0xae, 0x6b, 0xf1, 0x78, 0x5f, 0x6f, 0x40, 0xbe, 0x47, 0xa5, 0xf3,
+ 0x4f, 0x24, 0xf3, 0x76, 0x32, 0x2f, 0x48, 0xac, 0x7a, 0xee, 0x16, 0x8d,
+ 0x84, 0xd2, 0xd8, 0xd3, 0x91, 0x3a, 0x6a, 0x47, 0x5b, 0x92, 0xcc, 0x15,
+ 0xb6, 0x5f, 0xd9, 0x65, 0xd2, 0x90, 0x31, 0x59, 0x46, 0x8a, 0xe0, 0xfb,
+ 0x88, 0xdb, 0x48, 0x28, 0x0c, 0xa2, 0x9d, 0x46, 0xc1, 0x8e, 0xda, 0x3f,
+ 0x34, 0xa2, 0xe6, 0x9e, 0x0e, 0x65, 0x9e, 0x84, 0x0a, 0x8d, 0x68, 0x8b,
+ 0x75, 0xf5, 0x90, 0x54, 0x39, 0xc8, 0x0c, 0xdb, 0x82, 0x78, 0x8c, 0x92,
+ 0xef, 0xac, 0xbb, 0x82, 0xe7, 0x69, 0x23, 0xdc, 0x92, 0x46, 0xb4, 0x36,
+ 0x83, 0x67, 0x0b, 0xf2, 0xf0, 0x8b, 0x6f, 0x50, 0x38, 0x6b, 0x40, 0x8e,
+ 0xcf, 0x69, 0xe3, 0x5d, 0x50, 0xe8, 0xd8, 0xb4, 0x58, 0xf4, 0x0a, 0x35,
+ 0x3a, 0x65, 0x94, 0xb7, 0x0e, 0x04, 0xcd, 0x9e, 0x69, 0x1f, 0xfc, 0xc6,
+ 0xb6, 0x7c, 0x4b, 0x6a, 0x2d, 0x9e, 0xcd, 0x25, 0x67, 0x64, 0x7d, 0x61,
+ 0xc7, 0x7e, 0x87, 0xdf, 0x61, 0x73, 0x13, 0xb6, 0xb7, 0xb2, 0xb0, 0x47,
+ 0x6b, 0xde, 0x27, 0x52, 0x65, 0xd8, 0x19, 0xe2, 0xe7, 0x2d, 0x57, 0x01,
+ 0x85, 0xa1, 0xd5, 0x3e, 0x72, 0x07, 0xb4, 0xae, 0xf8, 0x9e, 0xbd, 0x45,
+ 0x01, 0x2d, 0x36, 0x07, 0xed, 0xa9, 0x66, 0x1d, 0xf3, 0x35, 0x5e, 0x03,
+ 0x7f, 0x10, 0x4d, 0xb5, 0xb4, 0xde, 0xf4, 0x7f, 0x9b, 0xa1, 0x23, 0x62,
+ 0x32, 0x43, 0x9e, 0x1b, 0xe2, 0xdb, 0xd0, 0xe6, 0xa3, 0x3e, 0x3b, 0x96,
+ 0xd8, 0xc0, 0x7e, 0xc7, 0x3e, 0xfe, 0x97, 0x92, 0xf7, 0x5e, 0x3b, 0x5a,
+ 0x4b, 0xfd, 0x1c, 0xdb, 0x0d, 0xbf, 0xfa, 0x14, 0x15, 0x61, 0xff, 0x63,
+ 0xcf, 0x94, 0xca, 0xb1, 0x2d, 0x6c, 0x37, 0xd6, 0xab, 0x07, 0x36, 0xbd,
+ 0x7a, 0xc0, 0x26, 0xb6, 0x47, 0x90, 0x5c, 0xb5, 0x68, 0x49, 0x7d, 0x64,
+ 0xd0, 0x11, 0xad, 0x97, 0x7c, 0x69, 0x54, 0xd6, 0x3e, 0x4b, 0x9e, 0x81,
+ 0xc3, 0x26, 0x70, 0xd8, 0x04, 0x2e, 0x9b, 0x64, 0x8b, 0xc0, 0xa5, 0x5b,
+ 0x63, 0x16, 0xdd, 0x33, 0x11, 0xcf, 0x36, 0xcf, 0xe7, 0xa8, 0xee, 0x2b,
+ 0xba, 0xdc, 0x64, 0xcf, 0xe4, 0x68, 0x51, 0x7d, 0xae, 0xcf, 0xc3, 0x1f,
+ 0x6f, 0x93, 0x3e, 0x16, 0x01, 0xb3, 0x11, 0xdc, 0xf9, 0x86, 0x1a, 0xa7,
+ 0xcb, 0x6d, 0x45, 0xf5, 0x36, 0xcb, 0x2d, 0x51, 0x47, 0xae, 0x1f, 0x72,
+ 0x93, 0x90, 0x2b, 0xd2, 0x95, 0x58, 0xb6, 0x1f, 0xb2, 0xbb, 0x89, 0xec,
+ 0x44, 0x61, 0x9a, 0x7c, 0xc8, 0x0c, 0xbb, 0xd3, 0xc0, 0xdc, 0x9c, 0x33,
+ 0x09, 0xd9, 0x49, 0x5a, 0xc2, 0xaf, 0xde, 0xa4, 0x9a, 0x2c, 0xb2, 0x5e,
+ 0xaf, 0x70, 0x9e, 0x7d, 0x1e, 0xeb, 0xac, 0x41, 0xa7, 0x83, 0x39, 0x0b,
+ 0x7a, 0x24, 0xc6, 0x0f, 0x75, 0xbd, 0x09, 0x6c, 0x3b, 0xfc, 0xfc, 0xae,
+ 0x16, 0x01, 0xfc, 0x50, 0x54, 0x6e, 0x9d, 0xf8, 0x3d, 0x4b, 0x65, 0xc4,
+ 0x52, 0xa8, 0x7e, 0xaa, 0xda, 0x86, 0x21, 0x02, 0x93, 0xaa, 0xf0, 0x42,
+ 0x38, 0x2b, 0xe3, 0x6f, 0x73, 0xb6, 0x01, 0x8e, 0x1d, 0x17, 0x9d, 0x9c,
+ 0x93, 0xc1, 0x1a, 0xc4, 0x5f, 0xf5, 0x52, 0xd5, 0x19, 0xc0, 0x5a, 0x10,
+ 0x2d, 0x3f, 0x02, 0x8e, 0x0e, 0x60, 0x0d, 0x8f, 0x1c, 0x07, 0xac, 0x57,
+ 0xbc, 0xbe, 0x17, 0x36, 0xa6, 0xdf, 0x7a, 0xa9, 0xf6, 0x50, 0x7c, 0xd8,
+ 0xc6, 0x38, 0x2e, 0xd8, 0x5f, 0x26, 0xb1, 0xed, 0x8e, 0x57, 0x3a, 0x6f,
+ 0x63, 0x7e, 0xe7, 0xab, 0x82, 0x76, 0xf5, 0x75, 0x15, 0x15, 0xf0, 0xe9,
+ 0xf3, 0x8a, 0x0a, 0x07, 0xcc, 0x18, 0x4b, 0x29, 0xa6, 0x78, 0xe4, 0x7c,
+ 0x43, 0x85, 0x79, 0x65, 0x98, 0x4b, 0x93, 0x4f, 0x52, 0xcd, 0xf1, 0xfc,
+ 0x32, 0x15, 0x68, 0xa9, 0x39, 0x01, 0xdf, 0xf5, 0xe3, 0xdc, 0x9e, 0x4f,
+ 0x34, 0x8c, 0xe7, 0xf0, 0x69, 0xc8, 0x20, 0x5f, 0xd4, 0xa0, 0x8b, 0xc7,
+ 0x41, 0xe8, 0xf7, 0x60, 0x23, 0xfc, 0xa1, 0x26, 0xec, 0x29, 0xf8, 0x23,
+ 0x74, 0x78, 0x8e, 0xf3, 0x98, 0xf3, 0x4c, 0xa4, 0x3c, 0xbf, 0x1a, 0xdb,
+ 0xe2, 0xd9, 0xb7, 0x89, 0xf3, 0x51, 0x9a, 0x83, 0x38, 0x27, 0x59, 0x73,
+ 0x32, 0xa0, 0xd9, 0x7a, 0xe3, 0x92, 0x36, 0x15, 0xcd, 0x65, 0x03, 0xc6,
+ 0x6e, 0x6f, 0x09, 0x58, 0x9c, 0xad, 0xb7, 0x06, 0x4f, 0xef, 0x34, 0xa8,
+ 0xf6, 0x4c, 0x20, 0x8e, 0x0a, 0xec, 0x1f, 0xf9, 0xcc, 0x29, 0xec, 0xd5,
+ 0x1e, 0x3c, 0x7d, 0xa7, 0x71, 0x0c, 0xbe, 0xa2, 0xfb, 0xf0, 0x3f, 0xf6,
+ 0xdf, 0x79, 0xda, 0x84, 0x9d, 0x1c, 0x33, 0x70, 0x2b, 0x7c, 0x75, 0xcc,
+ 0x00, 0x96, 0xf1, 0x0c, 0x6c, 0xd4, 0xda, 0x83, 0x73, 0x22, 0xa8, 0x51,
+ 0xd8, 0x5e, 0xc2, 0xcf, 0xa2, 0xa9, 0x86, 0x65, 0xdd, 0x81, 0x4e, 0x51,
+ 0xf4, 0xdc, 0xc8, 0xdc, 0x65, 0xae, 0xf0, 0x39, 0x58, 0x97, 0x65, 0x04,
+ 0xae, 0x1c, 0x6a, 0xf5, 0xbc, 0x22, 0x82, 0x00, 0x98, 0x90, 0x88, 0x4d,
+ 0x11, 0x58, 0xe1, 0x38, 0x5c, 0x45, 0x1c, 0x80, 0x03, 0xd8, 0x0c, 0xff,
+ 0xd7, 0x44, 0x70, 0x91, 0x2a, 0x45, 0xa2, 0xc5, 0x06, 0x61, 0x3f, 0xec,
+ 0x55, 0xc2, 0x0f, 0x78, 0x0e, 0xed, 0x12, 0x6c, 0xf0, 0xc2, 0x1a, 0x79,
+ 0xfe, 0x1c, 0xbc, 0x9e, 0xfb, 0x31, 0x59, 0x99, 0xe0, 0x9c, 0xdc, 0x68,
+ 0x90, 0x25, 0x83, 0xb3, 0x72, 0xa9, 0x31, 0xec, 0xff, 0x15, 0xbe, 0x26,
+ 0xf2, 0xc6, 0x37, 0x69, 0xc2, 0xdf, 0x04, 0x6f, 0xeb, 0xf8, 0x5d, 0x21,
+ 0xde, 0xfb, 0x9c, 0x1c, 0x69, 0xf1, 0x78, 0x56, 0xaa, 0x56, 0xb7, 0xde,
+ 0xbf, 0x69, 0xf6, 0xfb, 0x3d, 0x2a, 0xd1, 0x9b, 0xc9, 0xde, 0xf0, 0x0d,
+ 0x9d, 0x6c, 0x94, 0x80, 0xef, 0x03, 0xfa, 0x4b, 0xa9, 0xfe, 0xad, 0x58,
+ 0x37, 0x63, 0x77, 0xc2, 0xdf, 0x3a, 0x74, 0x8f, 0xa3, 0x69, 0x7e, 0x42,
+ 0x1e, 0xec, 0xe4, 0xeb, 0xc5, 0x66, 0x0e, 0x9c, 0xd0, 0xba, 0xaa, 0x7e,
+ 0x8f, 0xf3, 0xe6, 0x81, 0x5f, 0x1b, 0x3f, 0xc4, 0x72, 0x96, 0xe7, 0x0c,
+ 0xaa, 0xa2, 0x0e, 0xd5, 0xdb, 0xfc, 0xcc, 0x73, 0x9c, 0xcf, 0x72, 0x18,
+ 0xff, 0x8c, 0xb5, 0x1f, 0xea, 0x5a, 0x9b, 0xb9, 0xc6, 0xbe, 0x02, 0x47,
+ 0xda, 0x96, 0x51, 0x6e, 0x92, 0x51, 0x69, 0x92, 0x5b, 0xf5, 0x65, 0x1c,
+ 0x97, 0xd0, 0xb6, 0xe1, 0x53, 0xc6, 0xc3, 0xa4, 0x8c, 0x1a, 0x46, 0x5c,
+ 0xc3, 0x0c, 0x3c, 0x0f, 0xb5, 0x7e, 0x9d, 0x01, 0x27, 0x42, 0xf8, 0x5f,
+ 0x2c, 0x20, 0x47, 0x5e, 0x73, 0xa8, 0x5f, 0xa8, 0x39, 0x51, 0x77, 0xa8,
+ 0x4f, 0x28, 0xb6, 0xed, 0x3d, 0x01, 0xdb, 0x78, 0x3e, 0xac, 0xfa, 0xbf,
+ 0xc2, 0x9e, 0x41, 0xcc, 0xc7, 0x4a, 0x23, 0xcd, 0xfb, 0xd0, 0xa9, 0x38,
+ 0x67, 0x58, 0x49, 0xfe, 0x8f, 0x92, 0xdc, 0x2e, 0x81, 0x5b, 0xad, 0x5f,
+ 0x46, 0x5e, 0xaf, 0xc7, 0xb8, 0xf1, 0x6a, 0xae, 0xd8, 0xd3, 0xc3, 0xa3,
+ 0xcc, 0x51, 0xad, 0x2f, 0xfa, 0xd3, 0x58, 0x2b, 0x4d, 0xca, 0xcf, 0x20,
+ 0xb7, 0x73, 0x3d, 0x60, 0xdb, 0x02, 0xd8, 0xd6, 0xd7, 0xc9, 0xfb, 0xa8,
+ 0x09, 0xf5, 0xb8, 0x06, 0xf4, 0x90, 0xa9, 0x0c, 0xfc, 0x3c, 0x77, 0x8e,
+ 0xf8, 0x3b, 0xf5, 0x08, 0xbc, 0x57, 0xc1, 0xeb, 0xa5, 0xe2, 0x29, 0xa3,
+ 0xb2, 0x75, 0xcc, 0x4c, 0xfa, 0x08, 0xd8, 0x0d, 0x5e, 0x3b, 0x2c, 0x97,
+ 0x85, 0x5c, 0x1f, 0x64, 0xbe, 0x82, 0xb9, 0x0c, 0xc6, 0x6e, 0x3d, 0x71,
+ 0x2d, 0xc1, 0x5e, 0x2e, 0xf6, 0x9a, 0x21, 0x19, 0xe4, 0x51, 0xaf, 0x47,
+ 0xdc, 0x0a, 0x3d, 0x97, 0xd4, 0x6d, 0xe6, 0xf2, 0x89, 0x2e, 0x2e, 0xbb,
+ 0x64, 0xc6, 0x9c, 0x78, 0x29, 0xc9, 0x41, 0x9c, 0xc7, 0x5f, 0x48, 0xe6,
+ 0x1d, 0xe4, 0xe3, 0xe7, 0x92, 0xba, 0x62, 0xe1, 0x39, 0xa0, 0xe5, 0x38,
+ 0x37, 0x67, 0x39, 0x37, 0x17, 0x90, 0x9b, 0x4b, 0xe0, 0xa7, 0xff, 0x31,
+ 0x19, 0xc8, 0x4d, 0x44, 0xbf, 0x6b, 0x48, 0xe4, 0x21, 0x13, 0xf2, 0xdc,
+ 0x1b, 0xcc, 0xc1, 0x36, 0xcf, 0xfe, 0x18, 0x67, 0x0a, 0xcf, 0x70, 0xde,
+ 0xd4, 0x3a, 0x13, 0x28, 0xf7, 0x32, 0x8d, 0x16, 0x2e, 0x23, 0x4f, 0x9a,
+ 0x34, 0x81, 0xdd, 0x78, 0xdf, 0xb4, 0x96, 0xa7, 0x3d, 0x05, 0xff, 0xbd,
+ 0x6f, 0x90, 0xe2, 0xfa, 0xfb, 0x1d, 0xe8, 0x18, 0x71, 0xa7, 0xc0, 0xfb,
+ 0xc5, 0xd2, 0x7f, 0x93, 0xf9, 0x43, 0x22, 0x83, 0xba, 0x56, 0xe4, 0x7d,
+ 0x89, 0x2a, 0x2d, 0xf6, 0x83, 0xdf, 0x85, 0x07, 0x1f, 0x78, 0x20, 0xaa,
+ 0x36, 0xc1, 0x3f, 0xc4, 0x38, 0xc6, 0x1a, 0xd6, 0x8b, 0x22, 0x72, 0xaa,
+ 0xc3, 0xb8, 0x66, 0xbc, 0x9f, 0x49, 0xf0, 0x3e, 0x0b, 0xbc, 0x7b, 0xe3,
+ 0x37, 0xc0, 0xa3, 0x1b, 0x0f, 0xf1, 0xe8, 0x4c, 0x82, 0xf1, 0x59, 0x60,
+ 0xfc, 0x97, 0xc0, 0x96, 0x85, 0x9a, 0x0e, 0xdc, 0x36, 0xc8, 0x88, 0x50,
+ 0x1b, 0x80, 0x83, 0x44, 0xcf, 0xe9, 0x44, 0xcf, 0xcc, 0x63, 0xf4, 0x9c,
+ 0x4e, 0xf4, 0xcc, 0x74, 0xeb, 0x81, 0x5c, 0x25, 0x91, 0x0b, 0x1f, 0x23,
+ 0x57, 0x49, 0xe4, 0xc2, 0x2e, 0x39, 0x0b, 0x67, 0xe2, 0x73, 0x71, 0x1e,
+ 0xdb, 0x45, 0x2c, 0x7c, 0x8a, 0xb1, 0x62, 0x87, 0x18, 0xef, 0x61, 0x04,
+ 0x66, 0x9a, 0x37, 0xb1, 0x96, 0xfd, 0x90, 0x61, 0x0e, 0x3c, 0xe2, 0xbb,
+ 0x3d, 0xf8, 0x6e, 0x1f, 0xef, 0xf8, 0xfb, 0x66, 0x82, 0x15, 0xae, 0x45,
+ 0x5e, 0x2d, 0x7c, 0x68, 0x6d, 0x46, 0xb0, 0x9f, 0xc5, 0xd5, 0xc3, 0x62,
+ 0x60, 0x61, 0x0e, 0x35, 0xa7, 0x69, 0x52, 0x59, 0x32, 0x57, 0x5f, 0x91,
+ 0x31, 0x76, 0xb7, 0xb1, 0x7e, 0xbb, 0xc3, 0xab, 0x99, 0x46, 0x8e, 0x68,
+ 0xbd, 0x97, 0x16, 0x50, 0x4f, 0xce, 0x03, 0x4b, 0xd7, 0x7d, 0xb0, 0x90,
+ 0x86, 0x81, 0x0b, 0x0d, 0x5c, 0x7b, 0x71, 0x6c, 0x23, 0xb5, 0x08, 0x66,
+ 0xfc, 0x88, 0x76, 0x26, 0xf3, 0x94, 0xd9, 0xec, 0xd4, 0x43, 0xb9, 0xde,
+ 0xbd, 0x8f, 0x8b, 0x7d, 0x02, 0xd4, 0xe0, 0x3f, 0xa2, 0x17, 0x70, 0x48,
+ 0x8e, 0x22, 0x97, 0x36, 0x39, 0x27, 0x80, 0xa3, 0x9b, 0x5c, 0xeb, 0x39,
+ 0xe7, 0x5a, 0xc0, 0x62, 0x9a, 0x7f, 0x72, 0xe8, 0x5b, 0x3e, 0x41, 0xed,
+ 0x10, 0x34, 0x5f, 0xd4, 0x7a, 0xca, 0xff, 0x04, 0xb8, 0xc2, 0xb7, 0x75,
+ 0x9e, 0xdb, 0xc5, 0x77, 0xfe, 0x66, 0x51, 0x76, 0xf5, 0x49, 0xec, 0x89,
+ 0xfd, 0xce, 0xf0, 0xfa, 0x1c, 0x7a, 0x1a, 0xce, 0xf3, 0x18, 0xd7, 0xf9,
+ 0xdd, 0x48, 0x7c, 0x6a, 0x62, 0xfc, 0x02, 0x46, 0x3e, 0x4f, 0x0f, 0xce,
+ 0xa7, 0xf5, 0x5d, 0x9f, 0x9f, 0xb5, 0x96, 0x41, 0x2f, 0x95, 0x1b, 0x0a,
+ 0xf5, 0x7d, 0xa4, 0xb0, 0x00, 0x9e, 0x95, 0x5b, 0xe9, 0x3c, 0xcf, 0xd9,
+ 0x5d, 0x73, 0x78, 0x6e, 0xf1, 0x77, 0x41, 0x3b, 0x6a, 0x11, 0x75, 0x11,
+ 0xfd, 0xd3, 0x3a, 0xf7, 0x61, 0xdc, 0x53, 0xc5, 0xf5, 0x72, 0x9c, 0x7b,
+ 0xb0, 0x77, 0x90, 0xff, 0xd7, 0xc1, 0x29, 0xf0, 0xfb, 0x29, 0x41, 0x4f,
+ 0x50, 0xd9, 0x49, 0xcf, 0xa3, 0x35, 0x38, 0x5b, 0x30, 0x0d, 0xe6, 0xe2,
+ 0xb0, 0x3d, 0x4d, 0xdc, 0x6b, 0x8d, 0x84, 0x55, 0x96, 0x69, 0x21, 0x1f,
+ 0xac, 0x68, 0xaa, 0x76, 0xf4, 0xd8, 0xb3, 0xc8, 0xd1, 0xd1, 0x4f, 0xb8,
+ 0xb6, 0xb1, 0x6f, 0x4f, 0xc0, 0x1e, 0xf4, 0x05, 0xeb, 0x92, 0xde, 0x6e,
+ 0xb0, 0x9e, 0x3c, 0x99, 0xe8, 0x11, 0x97, 0xfd, 0x54, 0xcf, 0x9f, 0xa0,
+ 0x87, 0x1c, 0x41, 0xdc, 0xff, 0x4a, 0xe8, 0x62, 0x1f, 0x64, 0xd0, 0x8f,
+ 0x8f, 0xd3, 0xbc, 0x5a, 0x8c, 0x6b, 0xf1, 0x79, 0xd4, 0xde, 0xa8, 0x98,
+ 0x85, 0xef, 0x72, 0xb1, 0x9e, 0x7a, 0xf3, 0x5f, 0x9a, 0xf3, 0x0f, 0xea,
+ 0x24, 0xf4, 0xe3, 0xbd, 0x8d, 0xb9, 0x95, 0x80, 0xde, 0x6c, 0xc6, 0xb5,
+ 0xdb, 0xbe, 0x88, 0x9e, 0xbf, 0xd2, 0xf8, 0x47, 0xda, 0xcb, 0x84, 0xc0,
+ 0x71, 0xe1, 0x02, 0x7c, 0x23, 0xb7, 0x7b, 0xe9, 0x35, 0xf4, 0xa8, 0x99,
+ 0x15, 0xd4, 0x65, 0xf8, 0x4d, 0x5c, 0xad, 0x8d, 0x73, 0x9f, 0x79, 0x03,
+ 0x5c, 0x9f, 0x2f, 0x2a, 0xdf, 0x34, 0x46, 0x69, 0xf9, 0x67, 0x5c, 0x67,
+ 0xe2, 0x7a, 0x0d, 0xfc, 0xb8, 0x74, 0xa5, 0xa5, 0x68, 0xb9, 0x65, 0xc3,
+ 0x2e, 0xfb, 0x41, 0x2f, 0xae, 0x38, 0x1f, 0x57, 0xf0, 0x8b, 0xf3, 0x2d,
+ 0xce, 0x04, 0x3e, 0x04, 0xec, 0x0f, 0xee, 0xbd, 0x39, 0x66, 0x9c, 0xff,
+ 0x4e, 0xe1, 0x99, 0xcf, 0xca, 0xbd, 0x32, 0xfb, 0x81, 0x7b, 0xe2, 0xee,
+ 0xfe, 0x9d, 0x73, 0x23, 0x74, 0x6e, 0x33, 0x87, 0xb8, 0x47, 0xa9, 0xc8,
+ 0xf9, 0x86, 0x1d, 0xf3, 0xaa, 0xde, 0xee, 0xf8, 0x3b, 0xf2, 0x59, 0xa7,
+ 0x57, 0x0a, 0xe9, 0xce, 0x8b, 0x22, 0xee, 0x3b, 0x42, 0xe4, 0x15, 0x3e,
+ 0xcb, 0x04, 0xee, 0x27, 0x1e, 0x7c, 0xe7, 0xa1, 0x2f, 0xe9, 0xf0, 0x73,
+ 0x38, 0xe1, 0xe7, 0x50, 0xeb, 0x44, 0x26, 0xed, 0xc7, 0x0e, 0x72, 0xee,
+ 0x17, 0xe2, 0x7f, 0xe7, 0xdc, 0x46, 0xc2, 0xb9, 0x6c, 0x8c, 0x4d, 0xb1,
+ 0xd2, 0x3d, 0xf7, 0x0e, 0xe6, 0x72, 0x5d, 0xf7, 0xa2, 0xc3, 0x62, 0x12,
+ 0xf3, 0x03, 0x9c, 0xe4, 0x75, 0x88, 0xff, 0x4a, 0x2f, 0x99, 0x57, 0x99,
+ 0x97, 0x29, 0x46, 0x5c, 0xe0, 0x31, 0xd5, 0xd1, 0x83, 0x3d, 0x70, 0xd7,
+ 0x59, 0xcd, 0xc4, 0xf8, 0x37, 0x83, 0x74, 0x4d, 0x81, 0xa6, 0x1b, 0x9e,
+ 0x7f, 0x87, 0xc7, 0x16, 0xcf, 0x4b, 0xca, 0xae, 0x58, 0xf4, 0xfa, 0x98,
+ 0xe7, 0xba, 0xc2, 0xf3, 0x77, 0x60, 0xf7, 0x5d, 0xe5, 0x50, 0x66, 0x94,
+ 0x39, 0xc9, 0x15, 0x2a, 0x0b, 0xdc, 0xe0, 0x0e, 0xd8, 0xd4, 0x97, 0xd0,
+ 0x1f, 0xb9, 0x12, 0xb1, 0xfd, 0x29, 0x6c, 0xe1, 0x7c, 0x0b, 0xbb, 0xc6,
+ 0xd7, 0x81, 0x83, 0x05, 0x7e, 0xdf, 0xc7, 0x18, 0xdf, 0x2d, 0x78, 0x7f,
+ 0x07, 0x67, 0xb0, 0x28, 0xb7, 0xaa, 0x71, 0xf7, 0x7b, 0x20, 0x77, 0x25,
+ 0xc1, 0x6b, 0x06, 0xdf, 0xe7, 0x63, 0xbc, 0x72, 0x1c, 0xd9, 0xe7, 0x5a,
+ 0x7f, 0x80, 0x38, 0x96, 0xe9, 0x2f, 0x31, 0x8f, 0xef, 0xfa, 0x31, 0x7e,
+ 0x61, 0x0f, 0x64, 0x5a, 0x9f, 0xca, 0x98, 0xe7, 0xe0, 0xc3, 0x65, 0x3f,
+ 0xc6, 0xd7, 0xf8, 0x4d, 0x1c, 0xbb, 0x83, 0xfd, 0x6e, 0x3d, 0xc3, 0xf6,
+ 0x49, 0x8a, 0x39, 0xe5, 0x2e, 0x72, 0x8f, 0xe9, 0x8f, 0x20, 0xdf, 0x62,
+ 0x5d, 0x2b, 0xe5, 0x7d, 0x16, 0x7c, 0x67, 0x5f, 0x33, 0xf7, 0x07, 0x92,
+ 0xe7, 0x2f, 0x22, 0xb6, 0x36, 0xfc, 0xd8, 0xe9, 0x05, 0xcc, 0x15, 0xb6,
+ 0xad, 0x97, 0xd4, 0xd5, 0xd4, 0xae, 0x4f, 0x63, 0x7b, 0x1e, 0xd6, 0x89,
+ 0xf9, 0xed, 0xc3, 0xe4, 0xec, 0x2e, 0xb9, 0xbf, 0x1f, 0x22, 0x87, 0xf9,
+ 0x6d, 0x96, 0xc9, 0xef, 0xf7, 0x20, 0xe5, 0x7d, 0x3c, 0x87, 0xc0, 0x3b,
+ 0xcb, 0x3e, 0x7a, 0xef, 0xec, 0xc6, 0x7e, 0x5a, 0xfb, 0x19, 0xdf, 0xbc,
+ 0xa7, 0xe7, 0x72, 0xef, 0xde, 0xc1, 0x76, 0x1e, 0x79, 0x2f, 0xf6, 0x03,
+ 0x72, 0xa6, 0x37, 0x3e, 0x47, 0x29, 0xfe, 0x1f, 0x60, 0x7c, 0x01, 0x76,
+ 0x55, 0x68, 0xa2, 0xc4, 0xe3, 0xc9, 0x03, 0x18, 0xe7, 0xfb, 0x3a, 0xd7,
+ 0xa6, 0x3c, 0xee, 0x61, 0x5c, 0xe7, 0xf9, 0x2e, 0xd6, 0xc9, 0x53, 0x95,
+ 0x35, 0x7e, 0xff, 0x2c, 0x79, 0xe7, 0xbc, 0xcc, 0x7d, 0xd4, 0x0d, 0x9c,
+ 0x9f, 0xeb, 0xd1, 0x18, 0xd5, 0x1d, 0xf8, 0xd5, 0x67, 0x1b, 0x2e, 0xd0,
+ 0x83, 0x1e, 0xec, 0xb0, 0xba, 0xb2, 0x6a, 0x76, 0x71, 0xe5, 0xb0, 0x7e,
+ 0x8c, 0xef, 0x27, 0x46, 0x79, 0xcd, 0x48, 0x7a, 0x78, 0xee, 0xbf, 0xf6,
+ 0xb4, 0x19, 0xf7, 0x62, 0x9c, 0x17, 0xb8, 0x07, 0x7b, 0x0d, 0xfb, 0xf6,
+ 0xc5, 0xef, 0xe1, 0x16, 0x8f, 0xec, 0x17, 0x8a, 0x79, 0xd1, 0xe1, 0x79,
+ 0x6a, 0x77, 0x84, 0x75, 0xf0, 0x8f, 0x88, 0x52, 0x9b, 0xa8, 0xfa, 0x16,
+ 0xd7, 0x54, 0x3b, 0xc9, 0xff, 0x17, 0x31, 0x3e, 0x9f, 0x60, 0x20, 0x3d,
+ 0x4b, 0xec, 0x57, 0xec, 0xaf, 0xf5, 0x2c, 0x30, 0xf5, 0xba, 0x9f, 0xda,
+ 0x0a, 0x6c, 0x7f, 0x23, 0xcd, 0x31, 0x88, 0x97, 0xda, 0xd3, 0x72, 0x34,
+ 0x84, 0x2d, 0xfc, 0xff, 0x82, 0x0a, 0x7a, 0x3b, 0xb6, 0x65, 0xc6, 0x78,
+ 0x79, 0xff, 0x7f, 0x04, 0x8f, 0xf6, 0x71, 0x1c, 0x3f, 0x8e, 0xef, 0x7e,
+ 0xfc, 0xac, 0x1c, 0x7c, 0xff, 0x51, 0xc3, 0xb3, 0x07, 0x04, 0xe7, 0x23,
+ 0xb2, 0xb2, 0x88, 0xc1, 0x5d, 0xc4, 0x28, 0x24, 0xaf, 0xf4, 0x41, 0xdc,
+ 0x9b, 0x13, 0x38, 0x37, 0x11, 0xe2, 0x19, 0x1c, 0xc0, 0xd9, 0x46, 0x3d,
+ 0xff, 0x3d, 0xe2, 0x38, 0x58, 0xb8, 0x6b, 0x74, 0x62, 0x37, 0x96, 0xc4,
+ 0x6e, 0xb4, 0xf5, 0xf0, 0x99, 0x5d, 0xf1, 0x52, 0xf2, 0xce, 0x67, 0xe2,
+ 0x5e, 0xc1, 0xe5, 0x1e, 0x09, 0x3e, 0x28, 0x19, 0x9d, 0x7b, 0x7b, 0x93,
+ 0xef, 0x97, 0x35, 0xce, 0xe5, 0xdc, 0xcf, 0x81, 0x6b, 0xa8, 0x96, 0x23,
+ 0xb8, 0x6b, 0x68, 0x5d, 0x2f, 0x31, 0x76, 0x27, 0xc6, 0xa7, 0x62, 0x0c,
+ 0x8b, 0x41, 0x41, 0x29, 0xb7, 0xba, 0x9f, 0x31, 0x96, 0xf8, 0x9e, 0xc6,
+ 0xef, 0x1d, 0x1d, 0x1b, 0xc0, 0x1d, 0x6e, 0x32, 0xb8, 0x1d, 0xb2, 0x7e,
+ 0xa3, 0xd3, 0x13, 0xdb, 0x11, 0xf3, 0x1e, 0xb8, 0x7b, 0x1f, 0x76, 0x85,
+ 0xe0, 0x6d, 0xe7, 0x6e, 0x37, 0x87, 0x9c, 0x72, 0x1b, 0xb1, 0xbd, 0xab,
+ 0x3a, 0x75, 0x71, 0x83, 0xfb, 0xae, 0x16, 0xf2, 0x4d, 0x1e, 0xbd, 0xb2,
+ 0x4a, 0xef, 0xa2, 0x16, 0x5d, 0xc3, 0x9a, 0xeb, 0x98, 0xbb, 0xd2, 0x4a,
+ 0x71, 0x84, 0x1e, 0x0f, 0xd8, 0x9c, 0x57, 0xff, 0xd4, 0x55, 0xa7, 0x7b,
+ 0x2d, 0xff, 0xfd, 0x07, 0x5d, 0xe7, 0x92, 0xbb, 0xa8, 0x13, 0x00, 0x00,
+ 0x00 };
static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = {
0x00000001, 0x00000000 };
static struct fw_info bnx2_tpat_fw_09 = {
- /* Firmware version: 4.4.26 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x1a,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
.start_addr = 0x08000488,
.text_addr = 0x08000400,
- .text_len = 0x1514,
+ .text_len = 0x13a4,
.text_index = 0x0,
.gz_text = bnx2_TPAT_b09FwText,
.gz_text_len = sizeof(bnx2_TPAT_b09FwText),
@@ -3709,871 +3643,868 @@ static struct fw_info bnx2_tpat_fw_09 = {
.data_index = 0x0,
.data = bnx2_TPAT_b09FwData,
- .sbss_addr = 0x08001940,
- .sbss_len = 0x48,
+ .sbss_addr = 0x080017c0,
+ .sbss_len = 0x40,
.sbss_index = 0x0,
- .bss_addr = 0x08001988,
+ .bss_addr = 0x08001800,
.bss_len = 0x12b4,
.bss_index = 0x0,
- .rodata_addr = 0x08001914,
+ .rodata_addr = 0x080017a4,
.rodata_len = 0x4,
.rodata_index = 0x0,
.rodata = bnx2_TPAT_b09FwRodata,
};
static u8 bnx2_TXP_b09FwText[] = {
- 0xc5, 0x7b, 0x7b, 0x74, 0x1c, 0x55, 0x9a, 0xdf, 0xef, 0x56, 0x3f, 0x54,
- 0xdd, 0x6a, 0xb5, 0x4a, 0x72, 0xdb, 0x6e, 0xed, 0x68, 0xc6, 0x5d, 0xee,
- 0x6a, 0xb9, 0xb1, 0x84, 0x5d, 0x2d, 0xb5, 0xec, 0x66, 0x5d, 0xb1, 0x7b,
- 0x8c, 0xb0, 0x65, 0x10, 0x3b, 0xc2, 0xeb, 0x9d, 0x88, 0x09, 0x27, 0xf4,
- 0x18, 0x19, 0x64, 0x63, 0x40, 0x30, 0x64, 0xa3, 0xd9, 0x25, 0xeb, 0x1a,
- 0xf9, 0x81, 0x1f, 0xad, 0xee, 0xd6, 0xc3, 0xc8, 0xec, 0xd9, 0x13, 0x64,
- 0x49, 0xb6, 0xcc, 0xd0, 0x0f, 0x33, 0xc0, 0xcc, 0x30, 0x27, 0x13, 0x77,
- 0x8c, 0x01, 0x03, 0x63, 0x98, 0xdd, 0x6c, 0x92, 0x99, 0x3d, 0x49, 0xd6,
- 0x07, 0xf3, 0xb0, 0xc1, 0x60, 0x32, 0x43, 0x12, 0xb1, 0xcb, 0x4c, 0xe5,
- 0xfb, 0xaa, 0x25, 0x63, 0x58, 0xb2, 0x9b, 0x6c, 0xfe, 0x88, 0xce, 0xd1,
- 0xe9, 0xee, 0xaa, 0x5b, 0xf7, 0x7e, 0xef, 0xef, 0xf7, 0x7d, 0xf7, 0x56,
- 0x04, 0xf0, 0x62, 0xee, 0xaf, 0x86, 0xfe, 0xe3, 0xfd, 0x03, 0x0f, 0xb7,
- 0xae, 0x88, 0xaf, 0xa0, 0xaf, 0x6d, 0x58, 0xec, 0x74, 0xf2, 0xcd, 0x55,
- 0x02, 0x48, 0xbd, 0x87, 0x7f, 0xd4, 0xdf, 0x57, 0xff, 0x71, 0x8f, 0xc1,
- 0x01, 0x28, 0xf3, 0x34, 0xf1, 0x3f, 0x64, 0xc9, 0x30, 0xd7, 0xac, 0xd7,
- 0x20, 0x3b, 0x8c, 0xc4, 0xda, 0xbb, 0x34, 0x20, 0x99, 0x6f, 0x0e, 0xdd,
- 0x88, 0xdf, 0x58, 0x66, 0xc0, 0x09, 0xbe, 0xfe, 0x55, 0xe3, 0xd3, 0x5d,
- 0x3f, 0x5d, 0xad, 0x7e, 0x34, 0xe1, 0x80, 0xac, 0x18, 0x63, 0x50, 0x9a,
- 0x20, 0x37, 0xd2, 0x33, 0x7f, 0xb6, 0xec, 0x79, 0x27, 0xfc, 0xf3, 0x73,
- 0xc1, 0x74, 0x19, 0x3a, 0x76, 0x67, 0xfb, 0x31, 0x13, 0x07, 0x2e, 0xa6,
- 0x23, 0xfa, 0x6e, 0x20, 0x27, 0x19, 0x91, 0xd0, 0x69, 0x84, 0x30, 0x9d,
- 0x87, 0x59, 0x65, 0x68, 0xd8, 0x5f, 0x0a, 0xe1, 0x52, 0xfa, 0xb7, 0x56,
- 0xc8, 0xd5, 0x8f, 0xb7, 0xe2, 0x90, 0x83, 0xc6, 0x23, 0x08, 0x66, 0x21,
- 0xd7, 0x18, 0x03, 0x28, 0x0c, 0x01, 0x7b, 0xd3, 0x6a, 0x3f, 0xa0, 0xf6,
- 0x14, 0x45, 0xf8, 0xec, 0x09, 0xa8, 0xdd, 0x0d, 0x8e, 0xe6, 0xd4, 0xed,
- 0x42, 0x4d, 0xee, 0x14, 0x90, 0x05, 0x8d, 0x5d, 0x9e, 0xe7, 0xcf, 0x01,
- 0x44, 0xf3, 0x32, 0xce, 0x3b, 0x78, 0x59, 0x83, 0xe4, 0x2c, 0xe0, 0xd4,
- 0x74, 0xec, 0xcd, 0xc2, 0x74, 0x1a, 0x02, 0xbb, 0xe3, 0x11, 0x65, 0x0a,
- 0x7c, 0x3f, 0x84, 0x41, 0x7b, 0x9c, 0x4a, 0x1c, 0x5b, 0xd6, 0x1e, 0xdd,
- 0xb2, 0x8e, 0xe9, 0x55, 0x30, 0x15, 0x35, 0x08, 0x08, 0x0c, 0xea, 0x12,
- 0x92, 0xca, 0xfa, 0x90, 0x13, 0x6a, 0x70, 0x1b, 0xfe, 0x96, 0xf8, 0x4d,
- 0x46, 0x5d, 0xa8, 0x8c, 0x4f, 0xa1, 0x0a, 0x65, 0xa5, 0x22, 0xb1, 0xc9,
- 0xb4, 0x65, 0xbd, 0xa4, 0x39, 0x71, 0x8c, 0x64, 0x33, 0x98, 0xff, 0x5b,
- 0xab, 0x4c, 0x72, 0xd9, 0xa3, 0xcd, 0xaf, 0x2f, 0x63, 0x42, 0xb1, 0xac,
- 0x29, 0xba, 0xb7, 0x2f, 0x3f, 0x2f, 0x63, 0xcb, 0x92, 0x34, 0xcb, 0xba,
- 0x4b, 0xfb, 0x1b, 0x6b, 0xeb, 0xe7, 0xc6, 0xc6, 0xf0, 0xfd, 0x9c, 0x82,
- 0xa7, 0xb2, 0x49, 0xe4, 0xd3, 0x16, 0x1c, 0x86, 0x13, 0x7d, 0x43, 0x21,
- 0xec, 0x2c, 0x74, 0xa0, 0x90, 0x56, 0x53, 0xe7, 0xe9, 0xb9, 0xad, 0x71,
- 0x0d, 0xf7, 0x15, 0x3a, 0x31, 0x93, 0x86, 0xe5, 0x31, 0xb4, 0xb2, 0x47,
- 0x44, 0x71, 0x4f, 0xa1, 0x0b, 0xc5, 0xb4, 0x76, 0x76, 0x50, 0x44, 0x06,
- 0x1a, 0x1c, 0x4e, 0x3c, 0x50, 0x68, 0xc1, 0xfd, 0x85, 0x04, 0x3d, 0x63,
- 0xe1, 0xe6, 0x58, 0x23, 0x8d, 0x6f, 0xc5, 0x93, 0x63, 0x96, 0x15, 0x8d,
- 0x29, 0xe8, 0x2b, 0xe8, 0x98, 0xc9, 0x49, 0x48, 0x1d, 0x73, 0x22, 0x75,
- 0x14, 0xb8, 0xe7, 0x68, 0x2b, 0xa6, 0x72, 0x16, 0xb6, 0xea, 0x83, 0x0d,
- 0x12, 0x5c, 0x48, 0x29, 0x02, 0x2e, 0xcd, 0x8f, 0x6d, 0x4a, 0x85, 0xf6,
- 0xf3, 0x0e, 0x81, 0x1d, 0x47, 0xa3, 0xf8, 0x45, 0xda, 0xc4, 0xcd, 0xed,
- 0x41, 0x0c, 0x14, 0x02, 0x78, 0x23, 0x1d, 0xa0, 0x35, 0x74, 0xbc, 0x9e,
- 0x96, 0x69, 0x9d, 0x16, 0x9c, 0x49, 0xf3, 0x18, 0x1e, 0xeb, 0x43, 0x6f,
- 0xa1, 0x11, 0xe7, 0xd2, 0x41, 0x5a, 0x33, 0x80, 0x57, 0x68, 0xdc, 0xf6,
- 0x82, 0x86, 0xb3, 0x34, 0xae, 0xaf, 0x10, 0xc2, 0xcb, 0x69, 0x1f, 0xd1,
- 0x1a, 0xc0, 0xe9, 0x74, 0x3f, 0x76, 0xa7, 0x9b, 0xcf, 0xde, 0x48, 0x32,
- 0x0c, 0x2d, 0xe0, 0x75, 0xf8, 0xda, 0x5b, 0x56, 0x57, 0xc0, 0x36, 0x13,
- 0x5a, 0x67, 0x7e, 0xdd, 0x7e, 0x0c, 0xa6, 0xcf, 0xcc, 0xf9, 0x89, 0x8e,
- 0x03, 0xb9, 0x59, 0xeb, 0xa7, 0xcb, 0x1a, 0x71, 0x22, 0x0b, 0x3c, 0x39,
- 0x05, 0x4c, 0x65, 0x4d, 0xab, 0xc6, 0xb0, 0xac, 0xc9, 0xf6, 0x16, 0x92,
- 0x97, 0xd6, 0xb3, 0x95, 0x46, 0x3d, 0x55, 0x72, 0x02, 0x47, 0xd5, 0x9e,
- 0x32, 0x24, 0x4c, 0xcc, 0x38, 0xe1, 0x1e, 0x52, 0x3b, 0x27, 0xa0, 0x9e,
- 0xbd, 0x87, 0x3c, 0xe9, 0x58, 0x56, 0xed, 0x36, 0xb1, 0xcb, 0x0a, 0x1a,
- 0x4d, 0xa1, 0x16, 0x87, 0x05, 0x3f, 0xd9, 0x42, 0xba, 0xc5, 0xb2, 0x6a,
- 0x57, 0x5b, 0xd6, 0xb9, 0x76, 0x58, 0x92, 0xa1, 0x9d, 0x2d, 0x41, 0x2b,
- 0x7f, 0x00, 0x6d, 0xe0, 0x34, 0xca, 0x5f, 0xf5, 0x21, 0xd2, 0x17, 0x76,
- 0x44, 0xfa, 0x67, 0xe9, 0xd9, 0x9a, 0x02, 0x99, 0x32, 0xf1, 0xa2, 0x91,
- 0x0d, 0x16, 0x4a, 0x32, 0x9c, 0xc4, 0x4f, 0xcb, 0x90, 0x65, 0x39, 0x35,
- 0x1f, 0x7c, 0x24, 0xdf, 0x8d, 0x87, 0x2d, 0xeb, 0x1d, 0x5d, 0x81, 0x9b,
- 0x74, 0x73, 0xd3, 0xb0, 0x85, 0x49, 0xfd, 0x34, 0xc9, 0x53, 0x20, 0xd5,
- 0x1d, 0xa7, 0x67, 0x02, 0x34, 0x3e, 0x81, 0x8d, 0x43, 0x41, 0x7c, 0x3f,
- 0x2b, 0xe3, 0xa7, 0xcb, 0xa2, 0xa8, 0xa6, 0xb9, 0xbc, 0x24, 0xab, 0x2a,
- 0x92, 0x1f, 0x0a, 0x64, 0x6e, 0x85, 0x8a, 0x3d, 0xa2, 0x70, 0x9e, 0x78,
- 0x0c, 0xe2, 0x07, 0xa5, 0x00, 0x9e, 0x2e, 0x29, 0x38, 0x59, 0x6a, 0xc4,
- 0xa9, 0x92, 0x8e, 0x6c, 0x4e, 0xdd, 0x5f, 0x86, 0x85, 0x1a, 0x32, 0xe7,
- 0x37, 0x26, 0x62, 0xc8, 0xe4, 0x2c, 0x2b, 0x4f, 0x34, 0x7b, 0x89, 0x87,
- 0xd7, 0x27, 0xbe, 0x86, 0xe3, 0x63, 0x4e, 0x84, 0x26, 0x03, 0x78, 0x2a,
- 0xed, 0xc4, 0x75, 0x19, 0xd5, 0x9c, 0x80, 0x16, 0xdd, 0x29, 0xb4, 0xe4,
- 0x72, 0xa1, 0xe6, 0x4c, 0x44, 0x42, 0x2e, 0x21, 0xa1, 0xe9, 0xb8, 0x13,
- 0x5a, 0x31, 0x04, 0x57, 0x93, 0x0c, 0xad, 0x89, 0xdc, 0xc8, 0x2f, 0xc1,
- 0x4d, 0x7e, 0xb1, 0x71, 0x24, 0x4a, 0xd7, 0x02, 0x74, 0x0d, 0x5f, 0xab,
- 0x82, 0x63, 0x91, 0x03, 0x24, 0x37, 0xcd, 0x81, 0xa4, 0xd3, 0xb2, 0x1c,
- 0x5a, 0x2b, 0x7a, 0x1e, 0xa3, 0xcf, 0x36, 0x1e, 0xaf, 0x20, 0x5c, 0x24,
- 0x19, 0x34, 0x11, 0x4d, 0x59, 0xa2, 0x31, 0x4b, 0x34, 0x66, 0x89, 0xc6,
- 0xac, 0x83, 0x6c, 0x46, 0xd5, 0x81, 0x3f, 0x22, 0x5d, 0x85, 0x88, 0xbf,
- 0x5f, 0xd8, 0x7a, 0x7a, 0xba, 0x14, 0x24, 0xfa, 0x43, 0x36, 0xfd, 0x4f,
- 0xe6, 0x04, 0x24, 0x4d, 0xed, 0x3e, 0x8f, 0x75, 0x08, 0xc7, 0xd4, 0xe4,
- 0x04, 0x92, 0xf4, 0x9c, 0xba, 0xdf, 0x84, 0xda, 0x59, 0x26, 0xfd, 0x6f,
- 0x55, 0x12, 0x98, 0xc9, 0xba, 0x50, 0xad, 0xa9, 0x21, 0xd2, 0x57, 0xb4,
- 0x8c, 0x05, 0xb8, 0x57, 0xa1, 0x39, 0x25, 0xb7, 0xa8, 0xc4, 0x90, 0x47,
- 0x10, 0x19, 0x91, 0x30, 0xad, 0x3b, 0xc8, 0x3f, 0x75, 0x38, 0x9a, 0x68,
- 0xb9, 0x62, 0x9c, 0x3e, 0x69, 0xfe, 0x2c, 0xad, 0x45, 0xf4, 0xd0, 0x7c,
- 0xe4, 0x97, 0x2c, 0xc7, 0x28, 0xd1, 0xb0, 0xd7, 0xa6, 0xf7, 0x64, 0xa9,
- 0x4b, 0x54, 0xec, 0xc7, 0x20, 0x7b, 0x51, 0x43, 0x10, 0x6a, 0x34, 0x24,
- 0x54, 0x3d, 0x29, 0x14, 0x4c, 0x95, 0x7e, 0x46, 0x63, 0x02, 0xd7, 0x8c,
- 0xe9, 0xc6, 0x60, 0x56, 0xe0, 0x46, 0xcd, 0xc2, 0x7a, 0xbd, 0x1b, 0xbb,
- 0x4b, 0xf3, 0x7e, 0xc9, 0xb1, 0x4b, 0xf1, 0x4f, 0xa5, 0x3b, 0xb0, 0x27,
- 0x1b, 0xc2, 0xee, 0x7c, 0xd0, 0x3f, 0x99, 0xe6, 0x7b, 0x1a, 0xf9, 0x3b,
- 0xdf, 0x0b, 0x5c, 0x73, 0xaf, 0xf1, 0x9a, 0x7b, 0x09, 0x0c, 0x8e, 0x7e,
- 0x85, 0x62, 0x48, 0x2d, 0x76, 0x6b, 0x1f, 0x91, 0xad, 0x68, 0x89, 0x5e,
- 0x34, 0xe0, 0xbc, 0xd2, 0x82, 0x43, 0xe3, 0x5d, 0xd8, 0x33, 0xbe, 0x02,
- 0x07, 0x46, 0x1b, 0x53, 0x5e, 0x63, 0x88, 0xd6, 0x0f, 0x27, 0x7b, 0x85,
- 0xda, 0xef, 0x10, 0xe1, 0x68, 0x2f, 0xd9, 0x6e, 0x53, 0x9d, 0x65, 0x9d,
- 0x8e, 0x91, 0x6d, 0xeb, 0xcd, 0xfa, 0x46, 0x12, 0x40, 0xb9, 0x5b, 0xed,
- 0x7c, 0x0b, 0x3e, 0xdc, 0x4a, 0x36, 0x37, 0x15, 0x43, 0xaf, 0x03, 0x8e,
- 0x16, 0x1f, 0x7e, 0x6d, 0x1d, 0x75, 0xb2, 0xdc, 0xad, 0x5d, 0x77, 0xe9,
- 0x7b, 0x05, 0xc7, 0x39, 0xf7, 0xd5, 0x58, 0xc2, 0xf3, 0xf3, 0x33, 0x96,
- 0x15, 0xa6, 0x79, 0xfa, 0x62, 0xcd, 0x89, 0x3e, 0xcc, 0x5a, 0xe7, 0xb7,
- 0x74, 0x61, 0xf7, 0xcc, 0x0a, 0x1c, 0x1c, 0x75, 0x21, 0x59, 0x27, 0x50,
- 0xab, 0x85, 0xcb, 0xf7, 0x62, 0x05, 0xcc, 0x29, 0x7e, 0xae, 0x0b, 0x47,
- 0x66, 0x2a, 0xbf, 0xb3, 0x57, 0x7f, 0xcf, 0xcf, 0x77, 0x91, 0x74, 0xca,
- 0xf2, 0xe4, 0x38, 0x49, 0x2a, 0x30, 0x9a, 0x71, 0x62, 0x34, 0x40, 0xba,
- 0xed, 0x10, 0xce, 0xe3, 0x8b, 0xfc, 0xde, 0xc7, 0x2c, 0xbc, 0xa4, 0x93,
- 0x9e, 0xb3, 0x1b, 0x84, 0xf7, 0x78, 0xa7, 0x70, 0x15, 0x37, 0x0b, 0xf7,
- 0xe4, 0xb7, 0x84, 0x7c, 0x3c, 0x25, 0xaa, 0x8a, 0x2d, 0x24, 0xfb, 0x1e,
- 0xe1, 0x39, 0xae, 0x86, 0x42, 0xe2, 0xbb, 0xa4, 0xcf, 0x2d, 0xc2, 0x51,
- 0x84, 0x22, 0x19, 0x03, 0x42, 0x2a, 0xd2, 0x1c, 0xb6, 0x0d, 0xf1, 0x3a,
- 0x41, 0xd2, 0x1b, 0x4c, 0x87, 0xd1, 0x8f, 0xad, 0x94, 0x23, 0x6e, 0x49,
- 0x1b, 0x38, 0x98, 0xad, 0xa2, 0xf8, 0xc8, 0x7e, 0x3f, 0x4b, 0xeb, 0x6a,
- 0x38, 0x54, 0x82, 0xe9, 0x31, 0x0e, 0x62, 0x05, 0xf9, 0xdb, 0xb9, 0x18,
- 0xfb, 0x22, 0x90, 0xcf, 0x86, 0x93, 0x07, 0x85, 0x65, 0x55, 0x45, 0xac,
- 0x25, 0xef, 0xe8, 0xcd, 0xd1, 0x33, 0xf8, 0x9f, 0xd6, 0x44, 0xa0, 0x1f,
- 0xd1, 0x76, 0xc8, 0x55, 0xc6, 0x1e, 0xbc, 0x9b, 0x86, 0xec, 0x36, 0x4c,
- 0xbc, 0x94, 0x06, 0x7c, 0x43, 0x83, 0x8a, 0x17, 0x64, 0x07, 0x08, 0x07,
- 0x0f, 0x09, 0xb5, 0xfb, 0x02, 0xa5, 0xb3, 0x44, 0xbb, 0x39, 0x20, 0x81,
- 0xe2, 0x91, 0x50, 0x7b, 0xce, 0x90, 0x3d, 0x7e, 0x57, 0xa8, 0xca, 0xac,
- 0x60, 0x3f, 0xe5, 0x5c, 0xb2, 0x67, 0x2e, 0xa7, 0x98, 0xb8, 0xee, 0x9a,
- 0x9c, 0x32, 0x48, 0x74, 0xed, 0x23, 0xba, 0x5e, 0xd4, 0xd5, 0xe0, 0x24,
- 0xac, 0x25, 0xbd, 0x3a, 0xdf, 0x33, 0xb0, 0xa7, 0x64, 0x85, 0x1c, 0x06,
- 0xcb, 0x0a, 0xa9, 0x2a, 0x03, 0xa6, 0x6c, 0x28, 0xe4, 0x1b, 0xbf, 0xb1,
- 0x7a, 0xe3, 0xb2, 0xfe, 0x76, 0x5e, 0x21, 0x79, 0xc1, 0xef, 0x2c, 0x7c,
- 0x59, 0xde, 0xb5, 0x20, 0x19, 0xbf, 0xb1, 0xee, 0x8c, 0xc3, 0xbf, 0xa4,
- 0xe0, 0x4c, 0x55, 0x1b, 0xe8, 0x1e, 0x18, 0xda, 0x65, 0x35, 0x68, 0x12,
- 0xc5, 0x29, 0x8d, 0xe2, 0xba, 0x2f, 0x71, 0xb9, 0xdd, 0x23, 0xce, 0xb5,
- 0x07, 0xbb, 0x3e, 0xc8, 0x7b, 0x48, 0xcf, 0xe8, 0xde, 0x59, 0x48, 0x38,
- 0xdf, 0x23, 0x5b, 0x73, 0x53, 0x4c, 0x45, 0xa1, 0xb1, 0xeb, 0x12, 0xe5,
- 0xa1, 0x9b, 0x62, 0x9e, 0x7f, 0xea, 0x36, 0xa4, 0xaf, 0x79, 0xf0, 0xe0,
- 0xca, 0xe9, 0x44, 0x2d, 0xc5, 0x75, 0x05, 0x67, 0xe3, 0x9d, 0x18, 0x2c,
- 0x55, 0x91, 0x1d, 0x3e, 0x53, 0xde, 0xab, 0x35, 0x76, 0xbd, 0x9f, 0x5e,
- 0xc2, 0x71, 0xe4, 0xd3, 0x7c, 0xbb, 0xd6, 0xbd, 0x53, 0x9c, 0xde, 0xe4,
- 0x45, 0x1c, 0x07, 0x4a, 0xb2, 0xfc, 0x49, 0x1a, 0x1f, 0x2d, 0xd1, 0xb4,
- 0xf2, 0x3a, 0x47, 0x53, 0xbf, 0xec, 0x68, 0x1a, 0x70, 0x53, 0x0c, 0xbe,
- 0x78, 0xbd, 0xc0, 0x4b, 0xd7, 0x47, 0x12, 0x6e, 0xe1, 0xc1, 0xf9, 0xee,
- 0x04, 0xd9, 0x49, 0x63, 0xca, 0x63, 0x50, 0xfc, 0x20, 0x93, 0x75, 0x68,
- 0x09, 0xec, 0x9e, 0xc2, 0x23, 0x83, 0x7a, 0x17, 0xcc, 0x19, 0xb6, 0xa1,
- 0x16, 0x0c, 0xce, 0x74, 0xc3, 0x2c, 0x39, 0x30, 0x11, 0x20, 0xe6, 0x4b,
- 0x48, 0xb9, 0x8c, 0x96, 0x8e, 0x89, 0x7c, 0xaf, 0xab, 0xe2, 0xc3, 0xc4,
- 0x7f, 0xf6, 0xa8, 0x1f, 0x5e, 0xd6, 0xf3, 0x59, 0x92, 0x51, 0x0b, 0x9e,
- 0x29, 0x45, 0x29, 0xd6, 0xe9, 0x24, 0x17, 0x8d, 0xe2, 0x45, 0x88, 0xec,
- 0x4b, 0xc6, 0xd6, 0x51, 0xf5, 0x08, 0xc5, 0x85, 0xdc, 0x04, 0xda, 0x91,
- 0x0c, 0x28, 0x94, 0xbb, 0x5f, 0x9a, 0x8b, 0x01, 0xdb, 0xe8, 0x53, 0x35,
- 0x93, 0xc0, 0x19, 0x09, 0x68, 0x6d, 0x30, 0x22, 0xfb, 0x1b, 0x48, 0x1f,
- 0x75, 0x45, 0x0f, 0x1e, 0x18, 0xad, 0xc7, 0xfd, 0xe3, 0x5e, 0xec, 0x18,
- 0xb5, 0x70, 0x39, 0xc6, 0xb6, 0xa1, 0xf6, 0x10, 0x89, 0x1d, 0xd5, 0x24,
- 0xd7, 0x4d, 0xb1, 0x48, 0xc2, 0x23, 0x9c, 0xa8, 0x2a, 0x76, 0x13, 0x06,
- 0x48, 0xb2, 0x5f, 0xe8, 0x34, 0x47, 0x68, 0xb7, 0x7e, 0x2b, 0x52, 0x01,
- 0x19, 0xae, 0xa2, 0x8f, 0x62, 0x09, 0xfb, 0x31, 0xdf, 0xfb, 0x06, 0xb6,
- 0xba, 0x7d, 0x70, 0x64, 0x64, 0xe4, 0x28, 0xff, 0x63, 0x91, 0x1b, 0x9d,
- 0x4d, 0x12, 0xfd, 0x07, 0xfc, 0xd3, 0x63, 0x8d, 0xfe, 0x63, 0x14, 0x5f,
- 0xef, 0xc9, 0x4a, 0xbc, 0x0e, 0xe3, 0x05, 0x9a, 0x5b, 0xc1, 0x93, 0x14,
- 0xab, 0x1f, 0xa2, 0xf8, 0x73, 0xa2, 0x94, 0x17, 0x1c, 0x4f, 0x6c, 0x7e,
- 0xb2, 0xc4, 0x5b, 0x96, 0x78, 0xcb, 0x12, 0x5f, 0x14, 0x17, 0x4e, 0x66,
- 0x99, 0x8f, 0x2b, 0xe4, 0xa3, 0x09, 0xe2, 0xdd, 0x83, 0x6d, 0x44, 0xef,
- 0x83, 0xe3, 0xd5, 0xb8, 0x8f, 0xe8, 0x2d, 0xea, 0x6a, 0xcf, 0x9f, 0x0b,
- 0x0b, 0xf9, 0x98, 0x6a, 0xee, 0x14, 0x5e, 0x48, 0x4d, 0x96, 0xd5, 0xad,
- 0x33, 0xcf, 0x64, 0xa7, 0x92, 0xcd, 0xf3, 0xfe, 0x24, 0x3c, 0xe8, 0xa3,
- 0x67, 0x7a, 0xc7, 0xf1, 0xa9, 0x44, 0x3c, 0x79, 0x88, 0xc7, 0x83, 0xba,
- 0x9a, 0x58, 0x4e, 0x71, 0xfd, 0x82, 0x16, 0x29, 0x5f, 0x70, 0xe0, 0xeb,
- 0x24, 0x0f, 0x9d, 0xe5, 0xd1, 0x44, 0xfc, 0x3c, 0x40, 0x58, 0xc7, 0x6f,
- 0x30, 0x9f, 0x91, 0xe8, 0xaf, 0x89, 0xf7, 0x48, 0x31, 0xe0, 0x3f, 0x77,
- 0xb8, 0xd1, 0xff, 0xe2, 0x50, 0x85, 0xfe, 0x9d, 0x44, 0xff, 0x74, 0xcc,
- 0xc2, 0x21, 0xa2, 0xff, 0x29, 0xa2, 0xbf, 0x8f, 0xe3, 0xf9, 0x1c, 0xfd,
- 0x27, 0x4a, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x3d, 0xb6, 0x8e,
- 0xcf, 0xcb, 0xcb, 0xb2, 0xee, 0xd4, 0x9f, 0xb5, 0xbe, 0x4d, 0x32, 0x5b,
- 0x52, 0x64, 0xb9, 0x31, 0x8e, 0x8b, 0x1c, 0xb9, 0x07, 0x7d, 0x12, 0xbc,
- 0x3e, 0x2c, 0x28, 0x72, 0x2e, 0x08, 0xe1, 0x59, 0xd2, 0xef, 0x29, 0xca,
- 0x65, 0xcf, 0x94, 0xae, 0xcd, 0x6d, 0xac, 0xeb, 0x31, 0xd2, 0xb1, 0x3a,
- 0x61, 0x52, 0x6c, 0x4b, 0x95, 0x92, 0xd8, 0x3b, 0x8e, 0xe4, 0xb4, 0xfe,
- 0xaf, 0x29, 0xc0, 0x2c, 0x22, 0xfb, 0xaa, 0x4a, 0x2a, 0x9a, 0x17, 0x77,
- 0x4d, 0x05, 0xd0, 0x5f, 0x5a, 0x8f, 0x2c, 0xc5, 0x9b, 0x9d, 0x14, 0x9f,
- 0x3f, 0x8c, 0x25, 0x77, 0xf8, 0x11, 0x21, 0xfd, 0x06, 0x70, 0x2f, 0x3d,
- 0x73, 0x70, 0x9c, 0xe9, 0x57, 0xe6, 0xf4, 0x1c, 0xc0, 0x3d, 0x74, 0x6d,
- 0xdf, 0xb8, 0x8c, 0x17, 0xf4, 0x27, 0x08, 0xcf, 0x54, 0xf0, 0xc5, 0xdd,
- 0x59, 0x28, 0xe4, 0x9e, 0x84, 0xff, 0x22, 0xd1, 0x17, 0xe8, 0xf7, 0xb6,
- 0x92, 0xd7, 0x3f, 0x38, 0x86, 0xef, 0x2d, 0x31, 0xfc, 0x58, 0x40, 0x58,
- 0xec, 0x76, 0x3d, 0x42, 0x76, 0xef, 0xc4, 0x40, 0x49, 0xc2, 0x77, 0xa6,
- 0xbc, 0x78, 0x68, 0xf4, 0x53, 0xcb, 0x1d, 0x77, 0xe2, 0xb6, 0x26, 0x2f,
- 0x1e, 0x9c, 0x4a, 0x62, 0xff, 0x38, 0x42, 0x55, 0xb1, 0x61, 0x8a, 0xdd,
- 0x95, 0x7c, 0x50, 0x4d, 0xbc, 0x1f, 0x18, 0xf7, 0xf9, 0xfb, 0x0e, 0xb3,
- 0x0c, 0xd6, 0x07, 0x3d, 0x40, 0xb9, 0x2a, 0xe6, 0xc0, 0x36, 0xdd, 0xb1,
- 0xa0, 0x8a, 0x0c, 0xfd, 0x09, 0x9a, 0x6f, 0x12, 0x8e, 0x57, 0x97, 0x20,
- 0x72, 0xa4, 0xc1, 0x51, 0xce, 0x2d, 0x40, 0x3d, 0x1e, 0x9a, 0x49, 0x62,
- 0x98, 0x6c, 0xf4, 0x81, 0xd1, 0xc1, 0xef, 0xd5, 0x51, 0x0c, 0xf1, 0xb7,
- 0xaa, 0x7d, 0x6f, 0x08, 0x03, 0xf9, 0x88, 0x07, 0x3b, 0xa7, 0x7c, 0xfe,
- 0x1d, 0x87, 0xad, 0x75, 0x6c, 0x4f, 0xdb, 0x67, 0xea, 0x71, 0xdf, 0x38,
- 0x5d, 0x1b, 0x65, 0x1b, 0x26, 0x5b, 0x8b, 0x54, 0x11, 0x6f, 0xe1, 0xa4,
- 0x87, 0xf0, 0x92, 0x23, 0x56, 0x4d, 0xf2, 0xf0, 0xe0, 0x1e, 0xdb, 0x16,
- 0x14, 0x6c, 0x1b, 0xb7, 0xf0, 0xa6, 0x1e, 0x45, 0x8e, 0xec, 0xfa, 0xc8,
- 0xb8, 0x3a, 0xdb, 0x41, 0x58, 0xe7, 0x6d, 0x87, 0x7a, 0xa4, 0xc9, 0x91,
- 0x44, 0x7d, 0x1b, 0xc5, 0xf8, 0x7a, 0xcb, 0xba, 0xbb, 0xb5, 0xb9, 0xff,
- 0xe7, 0x44, 0x73, 0x9d, 0xb1, 0x08, 0xe5, 0x3a, 0x35, 0x07, 0x34, 0x0f,
- 0xb8, 0xa5, 0xeb, 0x71, 0x7e, 0x21, 0xc7, 0x41, 0x8e, 0xe5, 0x01, 0x7f,
- 0x7d, 0xa6, 0x92, 0xe3, 0xea, 0x8b, 0x8d, 0xfe, 0xba, 0x4c, 0xd0, 0x5f,
- 0x57, 0x84, 0xdf, 0x5d, 0x04, 0x7e, 0x4c, 0xf1, 0x65, 0x41, 0xdb, 0x6f,
- 0xac, 0x54, 0xbd, 0x8d, 0x07, 0xfd, 0xcf, 0x8f, 0xa9, 0x66, 0x19, 0xea,
- 0x7e, 0x0a, 0x9b, 0x78, 0x7c, 0xc6, 0xe9, 0x3f, 0x4e, 0xd8, 0xaf, 0x5e,
- 0x8b, 0x62, 0x1f, 0xe9, 0x73, 0x17, 0xd9, 0xc2, 0xaf, 0xdb, 0x80, 0x03,
- 0x99, 0x70, 0x48, 0x17, 0x3d, 0x34, 0x31, 0xb0, 0xa7, 0x48, 0x31, 0x5f,
- 0x4a, 0x52, 0x10, 0x53, 0xa3, 0x94, 0xd6, 0x90, 0xce, 0xb8, 0x60, 0x2e,
- 0xac, 0xe8, 0xe4, 0xbe, 0xec, 0x29, 0xcb, 0xaf, 0x69, 0x13, 0x45, 0xd2,
- 0xd9, 0xc3, 0x25, 0x1f, 0x06, 0x08, 0x0f, 0x2c, 0x20, 0x0c, 0xf9, 0x20,
- 0xd9, 0xc5, 0x03, 0xa3, 0x0e, 0xa2, 0x8f, 0xc7, 0x25, 0x91, 0x5c, 0x54,
- 0xc1, 0xa2, 0x0f, 0x4d, 0xb1, 0x5d, 0x92, 0x1d, 0x91, 0x2d, 0x3e, 0x4b,
- 0x39, 0xff, 0x99, 0xcf, 0x61, 0x10, 0x55, 0x31, 0xaf, 0xe6, 0xfe, 0x8a,
- 0x3c, 0x06, 0xc7, 0x99, 0x67, 0xf5, 0x08, 0xa4, 0x24, 0x6e, 0xd2, 0x7f,
- 0x49, 0x39, 0x81, 0x79, 0x27, 0x0c, 0x3c, 0x1e, 0xc5, 0xa3, 0x59, 0xc2,
- 0x34, 0xb1, 0xcb, 0xd6, 0x3d, 0x01, 0x96, 0x01, 0xf3, 0xb3, 0xca, 0xc1,
- 0xf9, 0xb3, 0x9e, 0xb0, 0xef, 0xff, 0xbb, 0xdd, 0xdd, 0x65, 0xa5, 0x6c,
- 0x2c, 0x4b, 0x18, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0xb4, 0xce,
- 0x07, 0x38, 0x5f, 0xd7, 0x23, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x44,
- 0x6f, 0xdd, 0xfd, 0xa0, 0x02, 0xb6, 0x87, 0xe8, 0x35, 0xf6, 0x50, 0x45,
- 0x34, 0x29, 0xd8, 0x31, 0xc3, 0xf6, 0x6b, 0x5d, 0x59, 0x62, 0xfc, 0xd6,
- 0xfa, 0x64, 0xb5, 0x76, 0xe4, 0x97, 0xe8, 0xa2, 0xeb, 0x01, 0x7c, 0x87,
- 0xfc, 0xe8, 0x5e, 0xe2, 0x73, 0x47, 0xfb, 0xbd, 0xb6, 0xdf, 0xee, 0x28,
- 0xad, 0xa1, 0xeb, 0x2c, 0xef, 0x0e, 0xec, 0xcf, 0xea, 0x48, 0x67, 0xcb,
- 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x11, 0xc5, 0xd9, 0x67, 0x4b, 0x8c,
- 0xc9, 0x12, 0x36, 0x1e, 0xfb, 0x61, 0xa9, 0x05, 0xcf, 0x91, 0x4f, 0x3e,
- 0x43, 0x31, 0xf7, 0x07, 0x36, 0x4e, 0x73, 0x8a, 0x43, 0x69, 0xc2, 0xa4,
- 0x43, 0x26, 0xd2, 0xf9, 0x10, 0x3c, 0x87, 0xc3, 0xfb, 0x77, 0x08, 0xf5,
- 0xc7, 0x24, 0x2f, 0xff, 0x81, 0xe9, 0xa5, 0xa8, 0x3a, 0xac, 0x4e, 0x10,
- 0xdd, 0xfe, 0x47, 0xa7, 0x35, 0xc2, 0xd4, 0x41, 0xff, 0xbe, 0xbc, 0xe2,
- 0xdf, 0x3b, 0x16, 0xf0, 0xef, 0x9d, 0xae, 0x27, 0x3f, 0x5a, 0xe4, 0x1f,
- 0x9c, 0x0e, 0xfa, 0x77, 0xa7, 0x1b, 0xfd, 0xbb, 0xf3, 0x6d, 0x08, 0xd5,
- 0xc3, 0x5c, 0x44, 0x39, 0xe2, 0xbe, 0xd1, 0x6f, 0x62, 0xa2, 0xae, 0x12,
- 0xf7, 0xfb, 0xc9, 0x36, 0x6a, 0xc9, 0x0e, 0x57, 0x4a, 0xb7, 0xa1, 0xbc,
- 0xb0, 0x72, 0xed, 0x3b, 0x74, 0xed, 0xa1, 0x56, 0xf8, 0xff, 0xc2, 0x8e,
- 0xbd, 0xc0, 0x73, 0x64, 0x6b, 0xcf, 0xb6, 0x52, 0x5d, 0x79, 0xd5, 0xd6,
- 0x9c, 0x14, 0x6f, 0x2d, 0x4b, 0x6f, 0x13, 0x08, 0xb6, 0x6e, 0x00, 0x16,
- 0xcc, 0xd7, 0x92, 0xc9, 0x09, 0x67, 0x6b, 0x12, 0x4b, 0xb4, 0x8d, 0x78,
- 0x42, 0xa1, 0x54, 0xd3, 0xfa, 0x75, 0xcc, 0x3d, 0x83, 0xef, 0x8c, 0x7a,
- 0x90, 0xda, 0xac, 0x60, 0x9a, 0xb0, 0xca, 0x76, 0x9a, 0x7f, 0x59, 0xac,
- 0x59, 0x99, 0x21, 0x3d, 0x24, 0x15, 0xbe, 0x46, 0x3e, 0xd1, 0xba, 0x8a,
- 0x7c, 0xa2, 0xb2, 0xfe, 0xd3, 0xa4, 0xaf, 0xdc, 0x4c, 0x14, 0x7b, 0x4b,
- 0x3f, 0x91, 0x2a, 0xf9, 0x45, 0x9d, 0x48, 0xe2, 0xac, 0x3d, 0xf6, 0xe9,
- 0xec, 0x1b, 0x56, 0xc8, 0xb6, 0x3b, 0x81, 0xc7, 0x56, 0x44, 0xf6, 0xff,
- 0x27, 0xa9, 0x81, 0xf8, 0x22, 0xd9, 0x65, 0xed, 0x3a, 0xb2, 0x76, 0xb1,
- 0xf6, 0x2f, 0xf0, 0x23, 0x85, 0x65, 0x3b, 0x20, 0xf6, 0x53, 0xbd, 0x4a,
- 0xa5, 0x53, 0xed, 0x02, 0xed, 0x30, 0x9e, 0xe9, 0xe6, 0x6b, 0x01, 0xff,
- 0x81, 0xb1, 0xa4, 0x14, 0xd0, 0xa0, 0xb8, 0x8c, 0x0e, 0x71, 0x60, 0x7a,
- 0x91, 0xff, 0xd1, 0xb1, 0x0d, 0xe2, 0xd1, 0xe9, 0x46, 0xff, 0x60, 0xba,
- 0x53, 0x0c, 0xe6, 0x37, 0x0b, 0x73, 0xe2, 0x5b, 0xc2, 0x9c, 0x4e, 0x09,
- 0x33, 0xdf, 0x43, 0x9f, 0x5b, 0xc4, 0x58, 0x7e, 0x40, 0xec, 0xcd, 0xf3,
- 0xfc, 0xa4, 0x2b, 0x5a, 0xe3, 0x87, 0x14, 0x7b, 0x9f, 0xa3, 0xd8, 0xfb,
- 0x2c, 0xc5, 0xde, 0x67, 0xc8, 0xde, 0x7f, 0x70, 0x15, 0xe3, 0xb2, 0x8d,
- 0x27, 0x19, 0x9b, 0xf8, 0xff, 0xbc, 0x78, 0x86, 0xf4, 0xcd, 0xb2, 0xfb,
- 0x37, 0x64, 0xdb, 0x2c, 0x93, 0x87, 0x38, 0x57, 0x90, 0x9e, 0xde, 0xb7,
- 0x6d, 0xf9, 0xb1, 0x15, 0x8c, 0xa5, 0x06, 0xc4, 0x56, 0xa2, 0x2f, 0xe9,
- 0x24, 0x0c, 0xa4, 0x11, 0x3e, 0xc9, 0x0e, 0x88, 0xbb, 0xf3, 0x7c, 0xfd,
- 0x20, 0x76, 0x52, 0x4d, 0x78, 0x28, 0x16, 0xee, 0xee, 0x25, 0xec, 0xb4,
- 0x89, 0xb0, 0xd3, 0xb2, 0x98, 0x8c, 0x8b, 0x2d, 0x9f, 0x58, 0x58, 0x88,
- 0xe4, 0xfd, 0x71, 0x75, 0x62, 0xa2, 0x92, 0x6f, 0x73, 0x19, 0x70, 0xdd,
- 0x8e, 0xda, 0x1a, 0x4d, 0x3d, 0x91, 0x44, 0x78, 0x7f, 0x5c, 0x82, 0xe9,
- 0x36, 0x5c, 0xb8, 0xcf, 0xae, 0x15, 0xd7, 0x63, 0x74, 0x54, 0x60, 0x5b,
- 0x6b, 0xf2, 0x8f, 0x5c, 0x24, 0xab, 0xb7, 0xdb, 0x11, 0x20, 0xf5, 0x0a,
- 0x99, 0xea, 0xfa, 0x4e, 0x92, 0x5e, 0x07, 0xe5, 0xdc, 0x27, 0xb2, 0xab,
- 0xd0, 0xd0, 0x2a, 0x93, 0x0e, 0x9d, 0xb8, 0xb3, 0x78, 0x13, 0xe9, 0x31,
- 0x72, 0xe4, 0x79, 0x78, 0xfd, 0x2f, 0x8c, 0x19, 0x18, 0xca, 0xe2, 0x7b,
- 0x3e, 0xaa, 0xe1, 0xee, 0x25, 0xfc, 0xf4, 0x03, 0xa2, 0x61, 0x63, 0x6b,
- 0xa4, 0x93, 0x6a, 0x79, 0xc5, 0x6b, 0xb8, 0x31, 0xd2, 0xe4, 0x87, 0xa2,
- 0xa5, 0xc4, 0x2b, 0xf9, 0xc8, 0x91, 0x1d, 0xd2, 0xb7, 0xc4, 0xcf, 0xa7,
- 0x0d, 0x3c, 0x5a, 0xea, 0x11, 0x7f, 0x31, 0x2d, 0x83, 0x74, 0x43, 0x71,
- 0x4b, 0xc7, 0x11, 0xa2, 0xcb, 0x45, 0x18, 0xc9, 0xf5, 0xfb, 0x02, 0x8b,
- 0xb5, 0x24, 0xbe, 0xb3, 0x8a, 0x7d, 0xa1, 0x12, 0xd3, 0x9c, 0xab, 0x80,
- 0xfd, 0x64, 0x93, 0x0d, 0x99, 0x0e, 0xb1, 0x84, 0xbe, 0x5f, 0xa4, 0xbc,
- 0x96, 0x94, 0x3a, 0x45, 0x03, 0x61, 0xd3, 0x85, 0x93, 0x5b, 0xc4, 0x82,
- 0x22, 0x63, 0x51, 0x28, 0x0b, 0x49, 0x46, 0x0b, 0x8b, 0x17, 0x1d, 0x95,
- 0x1a, 0xc0, 0xc5, 0xb6, 0x64, 0xfa, 0x0c, 0xd9, 0x7f, 0x88, 0x62, 0xfb,
- 0x8e, 0x58, 0x27, 0xe1, 0x64, 0xbe, 0x3e, 0x20, 0x86, 0x48, 0x8e, 0x13,
- 0x2e, 0xdb, 0x76, 0xfc, 0x4f, 0x8c, 0xc1, 0xd5, 0x60, 0x20, 0xe4, 0xa6,
- 0xdc, 0xf1, 0xdf, 0xdb, 0x22, 0xe6, 0xf3, 0x52, 0x97, 0xc8, 0xe5, 0x03,
- 0xfe, 0x23, 0x63, 0x9c, 0x67, 0x3a, 0xc4, 0x11, 0xd2, 0x79, 0x96, 0x74,
- 0x9e, 0x25, 0x9d, 0x67, 0x48, 0xe7, 0x99, 0x2f, 0xd1, 0xf9, 0x3e, 0xd2,
- 0xf9, 0xee, 0xfc, 0xaf, 0x6c, 0x1d, 0x3a, 0x0d, 0x03, 0x59, 0xca, 0xcb,
- 0x23, 0x4d, 0x15, 0xfe, 0x3e, 0x24, 0x59, 0xbc, 0x14, 0xfb, 0x86, 0x13,
- 0x5e, 0x83, 0x62, 0x6b, 0x17, 0x3d, 0xf3, 0x95, 0x39, 0x1b, 0x57, 0xfc,
- 0xc3, 0x63, 0x1d, 0x62, 0x98, 0xfc, 0x6e, 0x84, 0xe6, 0x1f, 0x21, 0xbf,
- 0x1b, 0x4c, 0xff, 0x9f, 0xd8, 0x0d, 0xdb, 0x1d, 0x4c, 0x2f, 0xe5, 0xad,
- 0x6a, 0xb2, 0x4b, 0xa7, 0xc1, 0x36, 0xb4, 0x59, 0x24, 0x8f, 0x7e, 0x4b,
- 0x24, 0x8f, 0xa5, 0x44, 0xb2, 0xd0, 0x43, 0x9f, 0x5b, 0xc4, 0x2d, 0x76,
- 0x1d, 0x3a, 0x20, 0x3a, 0x0a, 0x01, 0xff, 0x38, 0xad, 0x33, 0x4e, 0x7c,
- 0x3c, 0x46, 0xeb, 0x3c, 0x66, 0xdb, 0x2e, 0x15, 0x99, 0x5e, 0x5e, 0x8b,
- 0xed, 0x8c, 0xed, 0xeb, 0x32, 0xd1, 0xce, 0xbe, 0x71, 0xb5, 0xc7, 0x43,
- 0x7f, 0x37, 0x38, 0xa0, 0xed, 0x74, 0x56, 0x78, 0xe2, 0xdc, 0xcf, 0xb9,
- 0x9e, 0xe3, 0xb0, 0x62, 0xd7, 0x82, 0xcf, 0x5e, 0xc5, 0x00, 0x8c, 0x07,
- 0x20, 0x2f, 0x30, 0xb6, 0x18, 0xdf, 0x69, 0xfa, 0x1f, 0x34, 0x5f, 0x3f,
- 0xf4, 0x55, 0x90, 0x03, 0xc6, 0x5f, 0x1a, 0x63, 0x4d, 0x14, 0xa7, 0x69,
- 0x4e, 0x39, 0x03, 0x68, 0x19, 0x81, 0xdd, 0x09, 0x41, 0x38, 0x76, 0x11,
- 0xf9, 0x25, 0xd3, 0xaf, 0x76, 0x52, 0x36, 0xc1, 0xd2, 0x21, 0xc8, 0x4b,
- 0x8c, 0x9d, 0xb0, 0xb2, 0x90, 0x6b, 0x8d, 0x3e, 0x5c, 0x19, 0x0a, 0x07,
- 0x3b, 0xa1, 0xa6, 0x2e, 0x38, 0xd4, 0x32, 0xe5, 0xb7, 0xfe, 0xdd, 0x42,
- 0xed, 0x9b, 0x15, 0xdc, 0x27, 0x62, 0xec, 0xbe, 0x13, 0x2d, 0x36, 0x86,
- 0xef, 0x43, 0x73, 0x1e, 0x54, 0x87, 0x0b, 0xbc, 0x43, 0x73, 0xbe, 0xa8,
- 0x7f, 0xc0, 0x39, 0x21, 0x49, 0x58, 0xf0, 0x0b, 0x73, 0x81, 0x70, 0x0c,
- 0xcf, 0xc3, 0x73, 0x84, 0x95, 0x3e, 0x9a, 0xf7, 0x4d, 0x47, 0x73, 0xff,
- 0xa0, 0x50, 0x13, 0x5f, 0x9c, 0x6f, 0x59, 0x1e, 0x62, 0x59, 0xc6, 0xb4,
- 0xaa, 0x35, 0x2f, 0xe3, 0x21, 0xe9, 0x1d, 0x4d, 0x4b, 0xbe, 0x86, 0x10,
- 0x96, 0x51, 0x9d, 0x1c, 0x2d, 0x32, 0x0f, 0xbb, 0x70, 0x46, 0x57, 0xbb,
- 0xa9, 0x1a, 0xa5, 0xba, 0xa5, 0x03, 0x07, 0x29, 0xf6, 0x3e, 0x5a, 0xe2,
- 0x3e, 0xd7, 0x80, 0x58, 0x3e, 0x44, 0x7e, 0x69, 0xdb, 0x13, 0xe4, 0x06,
- 0xe3, 0x61, 0xdc, 0x40, 0xeb, 0xfb, 0xa9, 0xf6, 0x79, 0x9d, 0xd6, 0x97,
- 0x32, 0xea, 0x00, 0xad, 0x9f, 0x7a, 0x43, 0x84, 0x67, 0x89, 0xaf, 0x9e,
- 0x75, 0x8e, 0xe6, 0xbe, 0x5d, 0x42, 0x4d, 0x12, 0xe9, 0xe4, 0xc7, 0xbc,
- 0xf6, 0xc3, 0xcc, 0x0b, 0x7d, 0x52, 0x9d, 0x43, 0x76, 0xd4, 0x54, 0x90,
- 0x45, 0x64, 0x78, 0x3d, 0xf6, 0x4e, 0xad, 0xc7, 0x1e, 0xf2, 0xc7, 0x03,
- 0x7a, 0x2d, 0x42, 0x75, 0xa8, 0xa9, 0xd5, 0x30, 0x7b, 0x41, 0x13, 0x8e,
- 0x1d, 0x2d, 0x8d, 0x64, 0xc7, 0xa7, 0x1b, 0xaa, 0xf0, 0x91, 0xd5, 0xab,
- 0xad, 0xef, 0xa4, 0x88, 0x78, 0x83, 0x07, 0xe3, 0x0e, 0xf2, 0xef, 0x5f,
- 0xfc, 0x9a, 0x02, 0xaa, 0xc7, 0x60, 0xdc, 0x96, 0x10, 0x97, 0xf2, 0x67,
- 0x9d, 0x15, 0x3f, 0x68, 0xc2, 0x15, 0x05, 0xb5, 0x41, 0x6d, 0x39, 0x66,
- 0x15, 0x99, 0xe2, 0x85, 0x69, 0xd7, 0x64, 0x37, 0xe7, 0xba, 0xd1, 0x40,
- 0xf5, 0xf1, 0x9d, 0xb1, 0x5f, 0x5b, 0x9f, 0x2c, 0xe6, 0xe7, 0x4e, 0x7a,
- 0x2a, 0xb1, 0xf3, 0xcb, 0xe6, 0x88, 0x53, 0xbc, 0x69, 0xa6, 0x7a, 0xb6,
- 0x9a, 0x82, 0x74, 0x27, 0xe5, 0x23, 0xb5, 0x27, 0x4d, 0xf5, 0x68, 0x5f,
- 0xa4, 0x59, 0x77, 0x08, 0x37, 0xca, 0x81, 0x70, 0x7f, 0x2f, 0x92, 0xdb,
- 0xfd, 0x73, 0x74, 0x3c, 0x2b, 0x34, 0x17, 0x3d, 0xc7, 0xf3, 0x5c, 0x63,
- 0x4f, 0x27, 0xc9, 0x9e, 0xf8, 0x3e, 0x7f, 0xbf, 0x7a, 0x5f, 0xfe, 0x8a,
- 0xf1, 0x97, 0xff, 0xe4, 0x8f, 0x97, 0x7d, 0xd9, 0xf5, 0x8f, 0xbf, 0xe4,
- 0xfa, 0xff, 0xae, 0xae, 0x2f, 0xd7, 0x39, 0x6d, 0xcc, 0x90, 0x94, 0xb8,
- 0x8f, 0xe9, 0x34, 0x2e, 0xaf, 0xd9, 0xa3, 0xfd, 0x0e, 0xc5, 0x34, 0xee,
- 0x63, 0x70, 0x9e, 0x3e, 0x6f, 0xf7, 0x31, 0x4e, 0x7d, 0x0e, 0xb3, 0x72,
- 0x6c, 0xf1, 0x88, 0xea, 0x11, 0xd3, 0xaa, 0xd7, 0xbe, 0x4d, 0x75, 0xcd,
- 0x2e, 0xf4, 0xc6, 0x74, 0x0c, 0x67, 0xd5, 0xee, 0xdb, 0xa0, 0x25, 0x37,
- 0x0b, 0x9a, 0xa8, 0xe8, 0x11, 0x8e, 0x91, 0xb9, 0x7b, 0xba, 0x49, 0xb5,
- 0x5a, 0x19, 0x55, 0x14, 0x9b, 0x9c, 0x9a, 0x22, 0xa3, 0x18, 0x90, 0x9d,
- 0xc5, 0xa0, 0xec, 0x2e, 0x36, 0xca, 0x55, 0x34, 0xce, 0x37, 0xa2, 0xce,
- 0xde, 0x86, 0x5d, 0x98, 0x6d, 0xf3, 0x9a, 0x0d, 0x86, 0xaa, 0x34, 0x38,
- 0x76, 0x61, 0x4f, 0x8c, 0x9f, 0xed, 0xa0, 0x9a, 0x0d, 0xa2, 0x2e, 0x43,
- 0xc8, 0xd8, 0x10, 0xd8, 0xdb, 0xae, 0x0e, 0x2c, 0x95, 0xb4, 0xce, 0x5f,
- 0x09, 0xa7, 0xec, 0x29, 0x42, 0xf8, 0x33, 0x12, 0x8e, 0xb4, 0xc3, 0xe3,
- 0x59, 0xa5, 0xf6, 0x9d, 0x16, 0x03, 0x78, 0x2a, 0x16, 0xe9, 0xde, 0x26,
- 0x42, 0xb2, 0x97, 0xee, 0xb9, 0x32, 0x14, 0x7f, 0x33, 0xa6, 0xc7, 0xb5,
- 0x4a, 0x0d, 0x4a, 0x22, 0x89, 0x5e, 0x4d, 0xd3, 0x47, 0x20, 0xd3, 0x9a,
- 0x10, 0x55, 0x19, 0x75, 0xf6, 0x4d, 0xc2, 0x54, 0x9f, 0x2c, 0x1b, 0x40,
- 0x6b, 0x5b, 0x64, 0x7f, 0x8f, 0xa4, 0xc9, 0x84, 0xf5, 0x84, 0x33, 0xe3,
- 0xc3, 0xca, 0xc3, 0xf3, 0x7d, 0x1d, 0xcb, 0xfa, 0x30, 0x56, 0x26, 0xbd,
- 0x40, 0xae, 0x29, 0x46, 0x65, 0x1f, 0xe1, 0xfa, 0xe6, 0xc3, 0x8c, 0xb3,
- 0x2c, 0x6b, 0x47, 0xac, 0xfc, 0x75, 0x2f, 0x5a, 0x88, 0xc7, 0x6e, 0x4c,
- 0xa5, 0x19, 0x77, 0x19, 0x98, 0xa4, 0x9a, 0x48, 0x1b, 0x6a, 0xc4, 0x71,
- 0x8a, 0x43, 0x33, 0x69, 0xee, 0xff, 0xf4, 0x91, 0x8c, 0x7b, 0x88, 0xfe,
- 0x2d, 0x54, 0x0f, 0xa7, 0x28, 0x7e, 0xb1, 0x8c, 0x7b, 0xc9, 0xee, 0x21,
- 0x7b, 0x8d, 0x3a, 0xe3, 0xe6, 0x61, 0xc8, 0x1e, 0xc3, 0x6b, 0x5c, 0x77,
- 0x18, 0x75, 0x94, 0xf7, 0x0d, 0xaa, 0x78, 0x10, 0x8d, 0x44, 0xf4, 0x8b,
- 0x88, 0x04, 0x5f, 0x24, 0x7d, 0x0c, 0x6a, 0xc0, 0x6e, 0xbb, 0xd6, 0x76,
- 0xc2, 0xcc, 0x73, 0x0d, 0x0d, 0x4f, 0x55, 0x7b, 0x1d, 0xde, 0xc9, 0x45,
- 0xed, 0x1e, 0x92, 0x49, 0xf5, 0xcf, 0x0b, 0xba, 0x9a, 0x9a, 0xa0, 0xe7,
- 0xb6, 0x2a, 0xff, 0x65, 0x5f, 0x75, 0x1c, 0x32, 0xc5, 0x34, 0xb2, 0xbd,
- 0x3f, 0xf5, 0xbe, 0x49, 0x36, 0x7a, 0xfb, 0xd8, 0x9f, 0x79, 0xaf, 0xc4,
- 0x27, 0xbc, 0x1f, 0xc4, 0x2d, 0x2b, 0x41, 0x78, 0xb4, 0x87, 0xea, 0xed,
- 0x0f, 0x87, 0x4c, 0xef, 0xc5, 0x38, 0xf7, 0x81, 0x9d, 0xf8, 0x3d, 0xfa,
- 0xfd, 0xe4, 0x90, 0x8c, 0x4d, 0x85, 0x06, 0xb8, 0x86, 0x1d, 0x98, 0xd2,
- 0x6f, 0x44, 0xaf, 0x22, 0xe1, 0xee, 0xe8, 0x49, 0xb2, 0x49, 0x89, 0xc6,
- 0x1c, 0xa2, 0xdf, 0xdc, 0xd3, 0x7a, 0x0c, 0xdb, 0x94, 0x69, 0xef, 0x3b,
- 0x71, 0xa6, 0x17, 0x4c, 0xaf, 0x2c, 0x69, 0xb7, 0x62, 0xeb, 0x6d, 0x5c,
- 0x5b, 0xd9, 0xff, 0x9e, 0x17, 0xdb, 0xeb, 0x71, 0x3c, 0xd7, 0x80, 0xe7,
- 0x73, 0xa6, 0xe7, 0xb5, 0xf6, 0x28, 0xfa, 0x86, 0x2c, 0xbc, 0xac, 0x9b,
- 0x03, 0x55, 0x64, 0xe7, 0x09, 0xaa, 0xaf, 0xc2, 0x6d, 0xdc, 0x4b, 0x40,
- 0xc4, 0x81, 0x48, 0x3f, 0x81, 0xcc, 0x3b, 0x28, 0x74, 0xa5, 0x6a, 0xa8,
- 0x4e, 0x3b, 0x27, 0x2c, 0xf7, 0xf6, 0x76, 0x27, 0xd1, 0x00, 0x6c, 0x28,
- 0xb4, 0x90, 0xdc, 0xa2, 0xd8, 0x14, 0x91, 0xb1, 0xb1, 0xa0, 0xe3, 0xf9,
- 0xb4, 0x0f, 0xb7, 0x17, 0xe2, 0x84, 0xbd, 0x15, 0xa2, 0x3d, 0x81, 0x52,
- 0x3a, 0x80, 0x6f, 0x14, 0x1a, 0x49, 0xde, 0x41, 0xdc, 0x58, 0x08, 0xe1,
- 0x44, 0x9a, 0xf3, 0xb7, 0xe1, 0xd9, 0x1a, 0x6f, 0x44, 0x67, 0x41, 0xc3,
- 0x74, 0x1a, 0x9e, 0x07, 0xe2, 0x21, 0x74, 0x14, 0xa2, 0x28, 0x10, 0x86,
- 0xbb, 0x95, 0xe6, 0xbc, 0x9d, 0x74, 0xd2, 0x52, 0x08, 0x60, 0x69, 0x84,
- 0x22, 0x72, 0xc1, 0x27, 0x06, 0x08, 0x5b, 0x25, 0x0a, 0xf5, 0xb8, 0x38,
- 0xcc, 0x76, 0xae, 0x18, 0x7b, 0x72, 0x0a, 0x42, 0x05, 0xac, 0x94, 0x01,
- 0x0a, 0xd6, 0x91, 0x54, 0x81, 0xe8, 0x3d, 0xd8, 0x5e, 0xe9, 0xe1, 0x2e,
- 0x2f, 0x7c, 0xc6, 0x6f, 0x2d, 0xe9, 0xe9, 0xca, 0xe1, 0x69, 0xef, 0x27,
- 0x71, 0x8e, 0x4d, 0x9f, 0xae, 0x79, 0xfd, 0x30, 0x10, 0x1d, 0x67, 0xde,
- 0xec, 0xd8, 0xc8, 0xf1, 0xb0, 0x45, 0xc6, 0xaf, 0x2c, 0xaa, 0x41, 0x43,
- 0x53, 0xbc, 0x57, 0xa0, 0xf9, 0x88, 0x0e, 0x05, 0x49, 0x5a, 0xfb, 0x96,
- 0xc2, 0x0f, 0xad, 0xad, 0x0b, 0x83, 0xb8, 0x39, 0x52, 0x91, 0xd5, 0x39,
- 0xd2, 0xe1, 0xe4, 0x70, 0x03, 0x66, 0x88, 0x06, 0x97, 0xe1, 0x36, 0x8e,
- 0x8d, 0x59, 0xd8, 0xa0, 0x9b, 0xde, 0xd7, 0xda, 0x97, 0xe3, 0xfe, 0xc3,
- 0x83, 0x67, 0xdd, 0xa4, 0xd7, 0x59, 0xfd, 0x0e, 0x3c, 0x3a, 0x8e, 0xaf,
- 0x35, 0x00, 0x8f, 0x04, 0xc1, 0x3d, 0x6b, 0x35, 0x74, 0x02, 0x91, 0xce,
- 0x07, 0x10, 0x51, 0x34, 0xa1, 0xea, 0x2f, 0x0b, 0x24, 0xab, 0x8d, 0xc8,
- 0xd9, 0x5b, 0x80, 0x33, 0x6e, 0xf2, 0xe0, 0xdb, 0x0b, 0x4e, 0x92, 0x51,
- 0x10, 0xa5, 0x61, 0x37, 0x1c, 0xe4, 0x27, 0x97, 0x34, 0x6c, 0xa8, 0x25,
- 0x59, 0x3b, 0x84, 0x4c, 0x7a, 0x6e, 0xc1, 0xb1, 0xa1, 0x79, 0x59, 0xf9,
- 0x70, 0x13, 0xc9, 0xf0, 0xa9, 0x21, 0x6b, 0x97, 0x16, 0x0b, 0x90, 0xac,
- 0x15, 0xa2, 0x6f, 0x5e, 0x4e, 0x2c, 0xbf, 0x79, 0x39, 0xdd, 0x81, 0x3d,
- 0x33, 0x2c, 0xb7, 0xff, 0x1b, 0x79, 0x4d, 0xdb, 0x76, 0xb7, 0x61, 0x2c,
- 0x8a, 0x86, 0xc3, 0x57, 0x65, 0xc7, 0xf4, 0x3d, 0x42, 0x7c, 0x7c, 0xcf,
- 0xbf, 0x3a, 0xd2, 0xf7, 0xbe, 0xf0, 0x11, 0x3d, 0x0a, 0xe9, 0xe6, 0x03,
- 0x17, 0x63, 0x77, 0x92, 0xc9, 0x55, 0x19, 0x07, 0x49, 0xc6, 0xc1, 0x71,
- 0x96, 0xf5, 0xa7, 0x6b, 0xae, 0x90, 0x7c, 0x5f, 0x27, 0x5c, 0x76, 0x43,
- 0x2c, 0x8a, 0x9a, 0xc3, 0x6a, 0xb2, 0xc1, 0x11, 0x4e, 0xd4, 0x0a, 0x50,
- 0x55, 0x82, 0x96, 0x1a, 0x7c, 0xc8, 0x72, 0xd6, 0x49, 0xce, 0xdf, 0x1b,
- 0x24, 0x7e, 0xd6, 0xd3, 0x7c, 0x1b, 0x48, 0xce, 0x49, 0xe2, 0xff, 0x16,
- 0x7b, 0xde, 0x46, 0x9a, 0x77, 0x0b, 0xd5, 0x1e, 0xd3, 0xde, 0x4b, 0x44,
- 0x4f, 0xf4, 0x33, 0x5a, 0x08, 0x8d, 0x47, 0x82, 0xef, 0x53, 0x8d, 0x7d,
- 0xa3, 0x3d, 0x4e, 0xa1, 0x71, 0x4c, 0xfb, 0xcf, 0xab, 0x24, 0xed, 0xcb,
- 0xfa, 0xcd, 0xdf, 0x02, 0xf7, 0x1c, 0x4c, 0xf4, 0x50, 0x1d, 0xb1, 0x85,
- 0x6a, 0x25, 0x99, 0x72, 0x9b, 0x89, 0x1f, 0xc4, 0xd5, 0x68, 0x9d, 0xe0,
- 0xf8, 0x67, 0x92, 0x1f, 0x96, 0xa9, 0x4e, 0x0a, 0x87, 0x66, 0x10, 0x94,
- 0xa5, 0xa2, 0x4c, 0x78, 0xb0, 0x51, 0x76, 0x14, 0xc9, 0x5f, 0x83, 0x3d,
- 0x84, 0xa7, 0x9d, 0x78, 0x31, 0xef, 0xc4, 0x2b, 0xe9, 0x2d, 0x38, 0x50,
- 0xf2, 0x10, 0x6e, 0x36, 0x3d, 0xce, 0x55, 0x13, 0xee, 0x4a, 0x4c, 0x5e,
- 0x86, 0xae, 0x91, 0x87, 0x51, 0x9d, 0x71, 0x76, 0x53, 0x3e, 0xd5, 0x6f,
- 0x21, 0xb9, 0x6c, 0x28, 0xf2, 0xfd, 0x46, 0x64, 0xd2, 0x29, 0xc2, 0x40,
- 0x61, 0xaa, 0x81, 0x9c, 0x98, 0x68, 0x68, 0xb4, 0xfb, 0xba, 0x39, 0xba,
- 0x96, 0x2b, 0x7d, 0xb1, 0xdf, 0x7c, 0xc7, 0x5c, 0x9f, 0xb9, 0x0f, 0xfb,
- 0xb2, 0x3d, 0x84, 0x4d, 0xb7, 0x50, 0x7c, 0xaf, 0xd0, 0x38, 0x1d, 0xef,
- 0xc6, 0xbe, 0xbc, 0x71, 0x35, 0x7e, 0x4c, 0xda, 0xf1, 0xa3, 0x1f, 0x55,
- 0xed, 0xbc, 0x7f, 0xb5, 0x05, 0x77, 0xa5, 0x81, 0xf7, 0xd2, 0xdc, 0x4f,
- 0x24, 0x4c, 0x41, 0xf9, 0xe0, 0x90, 0xce, 0x39, 0x74, 0x0b, 0x96, 0xe6,
- 0x2d, 0xe4, 0x75, 0x0b, 0x67, 0x75, 0x8d, 0x72, 0x34, 0xe7, 0xea, 0x01,
- 0xa1, 0x51, 0x7e, 0x36, 0x9d, 0xfd, 0x88, 0xb4, 0xb3, 0x8e, 0x1e, 0x9e,
- 0xdb, 0x87, 0xea, 0xb7, 0xf7, 0xa1, 0x66, 0xd2, 0x0e, 0x3c, 0x45, 0x8a,
- 0x78, 0x3e, 0x1b, 0x0e, 0xbd, 0x07, 0x6b, 0x97, 0xc3, 0x50, 0x13, 0x4e,
- 0x07, 0xef, 0xcf, 0xf0, 0xfe, 0x94, 0xd6, 0xbd, 0xd4, 0xa1, 0xea, 0x45,
- 0xd1, 0xdc, 0xf3, 0x16, 0xca, 0x1b, 0x65, 0xa8, 0xa1, 0xd7, 0x10, 0x89,
- 0x76, 0xf2, 0x1e, 0x44, 0xa9, 0x92, 0xbb, 0x97, 0xcd, 0xe5, 0x6e, 0x2d,
- 0xef, 0x15, 0xe1, 0x61, 0x09, 0x13, 0x53, 0x96, 0x29, 0x91, 0xfd, 0x4e,
- 0xd1, 0x9c, 0x3f, 0xce, 0xee, 0x42, 0x36, 0x66, 0x59, 0xb7, 0xc7, 0xb5,
- 0xbe, 0x06, 0x07, 0xfe, 0x90, 0x32, 0x39, 0xc8, 0xe6, 0x53, 0xe4, 0x6b,
- 0xa1, 0x1d, 0xed, 0xa6, 0xe5, 0xb6, 0xeb, 0x0a, 0xee, 0x4f, 0x76, 0x89,
- 0x96, 0xc2, 0x16, 0xb1, 0x9c, 0xb0, 0x5b, 0xe8, 0xd8, 0x66, 0xd1, 0x74,
- 0xb4, 0x82, 0xdd, 0x22, 0x85, 0xcf, 0x7a, 0xa8, 0x37, 0xa7, 0x2d, 0xa4,
- 0x89, 0xaf, 0xa7, 0xfe, 0x0e, 0x5f, 0xac, 0x8b, 0x7e, 0x5c, 0xd7, 0xce,
- 0xbe, 0xf8, 0x30, 0x8e, 0xa5, 0xd9, 0xce, 0xfb, 0xb1, 0x87, 0xe4, 0xb3,
- 0x62, 0x88, 0xf7, 0xc3, 0xd4, 0xb3, 0x83, 0x08, 0xf7, 0xbd, 0x2a, 0xd4,
- 0x72, 0x01, 0xcd, 0x7a, 0x8d, 0x83, 0xe3, 0xab, 0x3a, 0xd0, 0xe4, 0xa8,
- 0xd0, 0x9f, 0xc8, 0x83, 0xe2, 0x69, 0x85, 0x87, 0x95, 0xf9, 0xa5, 0x64,
- 0xab, 0xa6, 0xe7, 0x52, 0xbc, 0xb9, 0xbf, 0x1a, 0x1b, 0xc4, 0x07, 0xd3,
- 0x21, 0x78, 0x0f, 0x27, 0x17, 0xfa, 0xd1, 0x21, 0xde, 0xb3, 0xeb, 0xc5,
- 0x4e, 0xf1, 0x4e, 0xbe, 0x5b, 0x5c, 0x9e, 0xe8, 0x42, 0x64, 0xf8, 0x3e,
- 0xf1, 0xf6, 0x04, 0xd3, 0xd9, 0x23, 0xce, 0x4f, 0x73, 0x9f, 0xd4, 0xc2,
- 0x1e, 0x9d, 0xfb, 0xa2, 0x8b, 0xab, 0xe0, 0xb7, 0x70, 0x4c, 0x67, 0x7d,
- 0x72, 0x9f, 0xb0, 0xd2, 0x5f, 0xda, 0x10, 0xcf, 0x59, 0x4e, 0x8d, 0x7b,
- 0xc5, 0x41, 0x9b, 0xdf, 0x29, 0xc2, 0xd1, 0xd3, 0x13, 0x5b, 0xc4, 0xf1,
- 0x7c, 0x85, 0xd7, 0xc9, 0x3c, 0xdb, 0xaf, 0x4c, 0x3a, 0xfe, 0x62, 0x9e,
- 0x36, 0xa1, 0xb4, 0x07, 0xe1, 0xb6, 0xfb, 0x51, 0x16, 0x46, 0xf4, 0x48,
- 0xe8, 0x65, 0x04, 0xe1, 0x2c, 0xb2, 0x6d, 0x5b, 0x78, 0x5a, 0x77, 0xc1,
- 0x31, 0x22, 0x93, 0x8c, 0xc8, 0x96, 0xfc, 0x2e, 0x48, 0x93, 0x5c, 0x1b,
- 0x7c, 0xbd, 0x8a, 0xfb, 0x14, 0x21, 0x89, 0xbf, 0x7f, 0xd1, 0xe6, 0x5c,
- 0x94, 0x0f, 0xb8, 0xbf, 0xfe, 0x57, 0xee, 0x8a, 0xed, 0xb1, 0x5d, 0xcd,
- 0xf7, 0xc4, 0x29, 0xd7, 0xb6, 0x73, 0x2f, 0xdc, 0x83, 0x99, 0x9c, 0x9b,
- 0x5b, 0x14, 0x1e, 0x77, 0xbb, 0x85, 0x0b, 0xba, 0x93, 0xea, 0x97, 0x87,
- 0x28, 0x47, 0x49, 0x90, 0xb5, 0x3b, 0x50, 0x1c, 0x73, 0x4a, 0xbc, 0x5f,
- 0xf5, 0xb3, 0x18, 0xf7, 0x10, 0x80, 0x43, 0xc4, 0xc3, 0xf7, 0x73, 0x21,
- 0x6c, 0xa2, 0xba, 0x2b, 0x64, 0xd7, 0x18, 0xbf, 0x87, 0x53, 0x39, 0x87,
- 0xa0, 0xba, 0xc2, 0x91, 0x58, 0x6d, 0xe1, 0x4a, 0x5b, 0x24, 0xca, 0x7d,
- 0x68, 0x85, 0x72, 0xd6, 0xde, 0x7c, 0x1d, 0x7e, 0x96, 0xab, 0xc3, 0x2b,
- 0x39, 0x0b, 0x07, 0x63, 0x83, 0x3d, 0x5e, 0x8a, 0x95, 0xcb, 0x62, 0x2e,
- 0xec, 0x88, 0x98, 0x8a, 0x17, 0x51, 0x5c, 0x48, 0x5c, 0x87, 0x54, 0x20,
- 0xdc, 0x39, 0x88, 0x7a, 0xbc, 0x91, 0x03, 0x61, 0x09, 0x78, 0x96, 0xd2,
- 0x1c, 0x6f, 0xc7, 0xcc, 0x7e, 0x17, 0xe1, 0xd8, 0x9f, 0x0b, 0xc4, 0x6b,
- 0x60, 0xb9, 0xcf, 0xc4, 0x29, 0x57, 0x17, 0xea, 0xd0, 0x95, 0xab, 0x47,
- 0x0f, 0xe5, 0xac, 0x75, 0xab, 0xe3, 0x78, 0x2b, 0xeb, 0x13, 0x2b, 0xb3,
- 0x83, 0x3d, 0x0a, 0xcd, 0xe9, 0x6a, 0x53, 0xfb, 0x9f, 0x22, 0xe0, 0x26,
- 0x23, 0x4c, 0xe6, 0x8e, 0x07, 0xfc, 0x14, 0x77, 0x8f, 0x8b, 0x4f, 0xf1,
- 0x04, 0xd9, 0xe3, 0x3d, 0xba, 0x5a, 0xbe, 0xe4, 0x88, 0x9c, 0xdd, 0x08,
- 0x75, 0xe0, 0x16, 0x61, 0x46, 0x6b, 0x29, 0x9e, 0x34, 0x54, 0x62, 0x85,
- 0x19, 0x11, 0x32, 0x61, 0x73, 0x27, 0x3c, 0x9a, 0x89, 0xce, 0x76, 0x96,
- 0xa9, 0x07, 0x9e, 0xa3, 0x64, 0x47, 0xd2, 0x17, 0xfb, 0xfb, 0x75, 0x78,
- 0x9d, 0xf2, 0xe5, 0xb9, 0x1c, 0xf7, 0xe6, 0xdd, 0xc6, 0xbb, 0x94, 0x03,
- 0x5e, 0x8a, 0x0d, 0x86, 0x38, 0xf6, 0xe7, 0x63, 0xf8, 0xe7, 0x64, 0x96,
- 0x8d, 0x3e, 0x5a, 0xf3, 0x2e, 0xc1, 0xeb, 0x20, 0xb9, 0xc4, 0xe0, 0xbe,
- 0x9c, 0xcd, 0x0f, 0xc5, 0x63, 0xe6, 0xe9, 0xff, 0x27, 0xed, 0x8f, 0x54,
- 0xc1, 0x5b, 0x4f, 0xba, 0x9c, 0xef, 0x69, 0x5e, 0xdb, 0xcf, 0xe4, 0x7a,
- 0xa6, 0x82, 0x0f, 0xdd, 0x46, 0xb5, 0x78, 0x21, 0xc7, 0x36, 0x67, 0xe1,
- 0x19, 0x5d, 0xa7, 0xda, 0x85, 0x6b, 0xf2, 0x7e, 0xaa, 0x5f, 0xb8, 0xcf,
- 0x64, 0x7a, 0xce, 0x10, 0x85, 0xfb, 0x73, 0x58, 0x2b, 0xc3, 0xb1, 0xa2,
- 0x0a, 0xe3, 0x98, 0x70, 0x3a, 0x09, 0x73, 0x70, 0xac, 0x65, 0x7f, 0x52,
- 0x0c, 0x6d, 0x82, 0xeb, 0xcf, 0x4e, 0x98, 0xb6, 0x1f, 0x57, 0x8b, 0xfb,
- 0xc9, 0x46, 0x5e, 0x8c, 0x55, 0x61, 0x82, 0xea, 0x1f, 0xc9, 0x30, 0x3d,
- 0xdf, 0xa5, 0xe7, 0x13, 0xa3, 0xd8, 0x17, 0x84, 0xe3, 0x4f, 0x14, 0xfc,
- 0x19, 0xde, 0x74, 0xc9, 0x74, 0x1d, 0x9e, 0xee, 0xb8, 0xe9, 0xdd, 0x18,
- 0xaf, 0x16, 0xb7, 0xe6, 0x5a, 0xf0, 0xfe, 0x58, 0x1d, 0xd9, 0x77, 0x3d,
- 0x96, 0x8c, 0x04, 0xf1, 0x36, 0xd1, 0x32, 0x40, 0xb4, 0x7c, 0xd2, 0x66,
- 0x0e, 0x34, 0x40, 0xed, 0xa7, 0xba, 0xa8, 0x9b, 0xfb, 0xcd, 0x4f, 0xeb,
- 0x6a, 0xe7, 0x6d, 0xc2, 0x0b, 0x2d, 0x92, 0x24, 0xd9, 0x5b, 0xd6, 0xb0,
- 0xde, 0xac, 0xfb, 0xc0, 0xfd, 0xa3, 0x3b, 0x70, 0x68, 0x86, 0x69, 0x71,
- 0x1b, 0xcb, 0xa7, 0xf9, 0x53, 0x36, 0xae, 0xb3, 0x3f, 0xbd, 0x73, 0x9f,
- 0x30, 0x42, 0xf6, 0xe7, 0xa7, 0x6b, 0x42, 0xd3, 0xdc, 0xa7, 0x0e, 0x9b,
- 0x6e, 0xf1, 0x53, 0x17, 0xf7, 0xab, 0x93, 0xe0, 0xff, 0x57, 0x5d, 0x95,
- 0x7e, 0xdf, 0x1d, 0x30, 0xed, 0x1e, 0xca, 0x15, 0xbb, 0x97, 0x1d, 0x22,
- 0x37, 0x90, 0x89, 0x3f, 0x99, 0x30, 0x57, 0x20, 0x46, 0x05, 0x7c, 0xbd,
- 0x6c, 0x2e, 0x31, 0x7a, 0xa8, 0x46, 0x90, 0x89, 0x5f, 0x13, 0xfb, 0xda,
- 0x05, 0x0e, 0x69, 0x06, 0x5e, 0xcb, 0x73, 0x2c, 0x77, 0xe2, 0xfb, 0x69,
- 0x35, 0x94, 0x12, 0xe1, 0xce, 0x5b, 0x84, 0x84, 0x50, 0x43, 0x0f, 0x0e,
- 0x51, 0x5e, 0x99, 0x4e, 0x73, 0x1e, 0x71, 0xda, 0xe7, 0x05, 0x6a, 0x29,
- 0x0e, 0x7d, 0x38, 0x54, 0x89, 0xfb, 0x85, 0xb8, 0xba, 0xff, 0xf7, 0x48,
- 0xa7, 0x4f, 0x17, 0x78, 0x4e, 0x13, 0x9f, 0xac, 0x66, 0x1f, 0x56, 0xa3,
- 0x29, 0xe9, 0x5e, 0x84, 0xa6, 0x38, 0xb6, 0xd0, 0x72, 0xb4, 0xd6, 0x91,
- 0xac, 0x1b, 0xdd, 0xf1, 0x2e, 0xd1, 0x53, 0xfc, 0x67, 0xbc, 0x27, 0xa1,
- 0x2c, 0x30, 0x36, 0x8b, 0xf5, 0x93, 0xdc, 0x53, 0xdc, 0x22, 0xba, 0x8b,
- 0xdc, 0x57, 0x1c, 0x10, 0xbf, 0x5f, 0x64, 0x9f, 0x9f, 0xef, 0x2f, 0xce,
- 0xeb, 0x9f, 0xfb, 0x8a, 0xa6, 0xe7, 0x05, 0x92, 0xfd, 0x03, 0x39, 0x8e,
- 0xc9, 0x8e, 0xfb, 0xfd, 0x68, 0xc3, 0x84, 0x0b, 0x9e, 0xd3, 0xf1, 0xaf,
- 0xe0, 0x76, 0xc2, 0x07, 0x4b, 0xb4, 0x8a, 0xfe, 0xd6, 0x4d, 0x48, 0x48,
- 0xb4, 0x91, 0xd0, 0x17, 0xb0, 0x4e, 0x7b, 0x29, 0x9e, 0x65, 0xac, 0xbe,
- 0x00, 0xeb, 0x92, 0xed, 0xcd, 0x2e, 0xf7, 0x28, 0x0e, 0x9b, 0x94, 0x57,
- 0x3c, 0x98, 0xce, 0x2d, 0xa2, 0xda, 0xc0, 0xc2, 0x7e, 0xbd, 0x06, 0x55,
- 0x76, 0x0c, 0xf0, 0x10, 0x9e, 0x84, 0xec, 0xa3, 0x79, 0xd2, 0xc3, 0x32,
- 0xbc, 0x74, 0xef, 0x8c, 0x4e, 0x72, 0x69, 0xaf, 0xcc, 0xdd, 0x3c, 0xb1,
- 0x12, 0x07, 0xc9, 0xe3, 0x6b, 0xb4, 0x28, 0x86, 0x14, 0x1f, 0xc5, 0x9a,
- 0x3b, 0xe6, 0xe6, 0xf4, 0xd0, 0x60, 0x5e, 0xaf, 0xbf, 0xaa, 0xa2, 0x87,
- 0x35, 0x72, 0xa5, 0x06, 0x93, 0xcd, 0x6a, 0x5a, 0x6b, 0x47, 0xfb, 0x16,
- 0x74, 0x0e, 0xf9, 0xc4, 0x2b, 0xe9, 0xbb, 0xad, 0x50, 0x1d, 0x8d, 0x23,
- 0x9b, 0x75, 0xcf, 0xd1, 0xdb, 0x34, 0x21, 0xf3, 0x58, 0xee, 0x79, 0xe0,
- 0xc1, 0x9c, 0x84, 0xc0, 0xdc, 0xf5, 0xf8, 0x44, 0x08, 0x7a, 0x6b, 0x35,
- 0x50, 0x2f, 0xe8, 0x1a, 0xcf, 0xcd, 0x6b, 0xc8, 0xa8, 0x23, 0x3f, 0xb9,
- 0x33, 0x9e, 0xc0, 0xbb, 0x59, 0x27, 0x36, 0x52, 0x9e, 0xbf, 0x31, 0x6d,
- 0xe0, 0x42, 0x29, 0x60, 0xcf, 0x21, 0x19, 0xf3, 0xe3, 0x9c, 0x34, 0xce,
- 0x83, 0xc9, 0x89, 0x2f, 0xd2, 0x17, 0x20, 0x9a, 0x7f, 0x42, 0xdf, 0xf9,
- 0xde, 0x45, 0xbb, 0x3f, 0x70, 0xea, 0x9a, 0xba, 0x4a, 0x1a, 0xe1, 0x9e,
- 0x52, 0x25, 0x17, 0x74, 0xe8, 0xac, 0x4b, 0x3f, 0x66, 0x47, 0x4d, 0x5c,
- 0x58, 0x5d, 0x8b, 0x4f, 0x46, 0x9b, 0x70, 0x7f, 0xce, 0x8b, 0x4b, 0xa3,
- 0x16, 0x56, 0xb6, 0xe1, 0xee, 0x20, 0x61, 0xb1, 0x5a, 0xf2, 0xfb, 0xd7,
- 0xa8, 0xf6, 0xa1, 0x78, 0x4a, 0x94, 0x46, 0x12, 0x1b, 0xc8, 0xae, 0xa3,
- 0x31, 0xa4, 0x6e, 0x8a, 0x47, 0x42, 0x17, 0xf1, 0x3d, 0x8b, 0x62, 0xb1,
- 0xe2, 0x30, 0xba, 0x84, 0xd3, 0xde, 0x67, 0xdc, 0x62, 0xef, 0x4b, 0x4a,
- 0x93, 0x03, 0xc2, 0x51, 0xbc, 0xd6, 0xaf, 0xbf, 0x2c, 0x0f, 0x71, 0xee,
- 0xe1, 0x1e, 0xc6, 0x88, 0xe5, 0xd2, 0xb8, 0x57, 0xb3, 0x59, 0xec, 0x9d,
- 0xb8, 0x9a, 0x9b, 0xae, 0xe6, 0xa3, 0xdd, 0x73, 0x79, 0x68, 0x30, 0xff,
- 0x8b, 0x2f, 0xe0, 0xa8, 0xd0, 0xdc, 0x7e, 0x07, 0xe7, 0x1f, 0x8f, 0x78,
- 0x93, 0xcc, 0x61, 0x1f, 0xf9, 0xe0, 0x49, 0xfd, 0x74, 0x90, 0x32, 0x04,
- 0x9c, 0xad, 0x02, 0x0f, 0xf2, 0x59, 0x93, 0x80, 0x85, 0xcd, 0x7a, 0xc5,
- 0x1e, 0xda, 0xda, 0x5d, 0xe8, 0xa3, 0x9c, 0xe4, 0x8a, 0xf9, 0xc8, 0xd7,
- 0x15, 0xbc, 0xaa, 0xb3, 0x0d, 0x6f, 0x9e, 0xcb, 0x49, 0xbc, 0x7f, 0x5e,
- 0xd9, 0xeb, 0xfe, 0x7c, 0xdf, 0x7b, 0xde, 0x36, 0x75, 0x24, 0x17, 0xc2,
- 0xfb, 0x76, 0x5c, 0xa3, 0xfa, 0x41, 0xa6, 0xda, 0x61, 0x23, 0x12, 0x0b,
- 0x54, 0x6e, 0x6d, 0x10, 0xf6, 0x36, 0xf1, 0xef, 0xdb, 0xfb, 0x70, 0xdf,
- 0x88, 0x84, 0x6a, 0x8d, 0xe3, 0xac, 0x89, 0x43, 0x75, 0x1c, 0xa7, 0xba,
- 0xb0, 0x6b, 0xc4, 0x23, 0xce, 0xe4, 0x9c, 0x78, 0xa2, 0xfb, 0x11, 0x2c,
- 0x68, 0xbd, 0x07, 0xb0, 0x6d, 0x90, 0xbf, 0x7f, 0x0b, 0xa9, 0x45, 0xbc,
- 0x3e, 0xf7, 0xda, 0x04, 0x7c, 0xad, 0xcc, 0x07, 0xbc, 0xef, 0xd3, 0xfc,
- 0xdb, 0x86, 0x9c, 0xe2, 0x62, 0xfa, 0x3f, 0x5b, 0x27, 0x02, 0x8c, 0x13,
- 0xf8, 0x5e, 0x0d, 0xcc, 0x3a, 0x1e, 0xcb, 0x3a, 0xf4, 0x51, 0x6d, 0xda,
- 0x87, 0x21, 0xa2, 0xeb, 0x9c, 0x3d, 0xd7, 0x95, 0x39, 0xfa, 0x7d, 0xa2,
- 0x36, 0x23, 0x9b, 0x41, 0xa2, 0x45, 0x59, 0xdd, 0x8d, 0xda, 0xe2, 0xb5,
- 0xf9, 0xb6, 0xc6, 0xc3, 0xfd, 0x4a, 0xd2, 0x15, 0xe5, 0x84, 0x5e, 0xbc,
- 0x9b, 0x16, 0x78, 0xc7, 0xb6, 0xc1, 0x5e, 0x34, 0xe5, 0x6b, 0x00, 0x3b,
- 0x86, 0xf0, 0xb8, 0xaf, 0x57, 0x6c, 0x5b, 0xea, 0xc3, 0x03, 0xc4, 0x4b,
- 0x0d, 0xf1, 0xf2, 0x61, 0x6c, 0x29, 0xad, 0xc3, 0xd7, 0xfe, 0x9d, 0x3c,
- 0x77, 0xd6, 0x68, 0x6e, 0x2e, 0x4a, 0x18, 0x7e, 0xae, 0xf7, 0x22, 0xd8,
- 0x39, 0x12, 0xe9, 0xf1, 0x49, 0x6c, 0x87, 0x11, 0xdc, 0x3b, 0x79, 0x2b,
- 0xdd, 0xe7, 0xb9, 0x82, 0xb8, 0x2b, 0xe3, 0x14, 0x6f, 0x51, 0xbd, 0x74,
- 0x2a, 0x2d, 0x2d, 0x72, 0xe0, 0x39, 0xeb, 0x89, 0xc0, 0x2e, 0xdc, 0xa4,
- 0x77, 0x61, 0x3b, 0xd9, 0x60, 0x47, 0xd3, 0x2e, 0x8c, 0x92, 0x0d, 0x6c,
- 0xab, 0xa7, 0x1a, 0x2e, 0x56, 0xb2, 0x7a, 0x03, 0x2c, 0x47, 0x81, 0x4e,
- 0xba, 0x5e, 0x47, 0x75, 0x9d, 0x14, 0x23, 0x6b, 0x23, 0xbf, 0x90, 0x35,
- 0x35, 0x97, 0xc4, 0xef, 0xd8, 0x6b, 0xd6, 0x51, 0x9e, 0x76, 0x31, 0x3e,
- 0xf0, 0x33, 0x4e, 0xf8, 0x22, 0x3d, 0xa6, 0x55, 0xa5, 0x69, 0xd1, 0x8d,
- 0x52, 0x53, 0x6e, 0x86, 0x6c, 0x76, 0x7d, 0xeb, 0xb5, 0xcf, 0xcd, 0xcb,
- 0x48, 0x87, 0xbb, 0x75, 0xca, 0x2a, 0x2b, 0x83, 0x50, 0x5a, 0xaf, 0xd5,
- 0xfd, 0xfc, 0x1c, 0x4c, 0x73, 0x25, 0xae, 0x85, 0xa4, 0x88, 0x72, 0x37,
- 0x2e, 0xd0, 0x1a, 0x41, 0x6c, 0x2d, 0x76, 0xa1, 0x77, 0xc4, 0xf1, 0x19,
- 0x3e, 0xf1, 0xb3, 0x2d, 0x7f, 0xc6, 0xff, 0x8e, 0x91, 0x48, 0xa7, 0x77,
- 0x8e, 0xff, 0xed, 0x93, 0x9f, 0xcd, 0x35, 0x90, 0xe1, 0xbc, 0xca, 0xf3,
- 0xf1, 0xb9, 0xa1, 0x79, 0xf9, 0x06, 0xf1, 0x80, 0x3d, 0xdf, 0x61, 0x0f,
- 0xfb, 0xb0, 0x8b, 0x7c, 0x7d, 0x43, 0xab, 0x89, 0x57, 0x13, 0xf7, 0x5b,
- 0x3b, 0x6c, 0x19, 0xdc, 0x6f, 0x3f, 0xdf, 0xd9, 0x74, 0x76, 0x0e, 0xfb,
- 0x54, 0xfa, 0xb0, 0xa7, 0x4a, 0x2d, 0xf6, 0x1e, 0xc3, 0x0f, 0x29, 0x0f,
- 0x3e, 0xf7, 0xb9, 0x3e, 0xdf, 0x76, 0x17, 0xef, 0x4d, 0x3c, 0x5d, 0x92,
- 0x85, 0x73, 0xa4, 0x5a, 0xb8, 0x46, 0x98, 0xb6, 0x8f, 0xe5, 0x8a, 0x8f,
- 0xfd, 0x57, 0x24, 0x03, 0xbc, 0xcf, 0x58, 0xb1, 0xff, 0x68, 0xfb, 0xbd,
- 0xc0, 0x51, 0xd3, 0x53, 0xb5, 0x0a, 0x54, 0xeb, 0x77, 0xdb, 0xf6, 0xb0,
- 0xd0, 0x08, 0xac, 0x7d, 0xae, 0x89, 0xeb, 0x7d, 0xee, 0x0d, 0x6a, 0x6b,
- 0xc7, 0x08, 0x80, 0x6e, 0x55, 0x78, 0x4d, 0xf5, 0x04, 0xf7, 0xeb, 0xb9,
- 0x8f, 0x4f, 0x71, 0xd7, 0x5b, 0xb7, 0xca, 0xf4, 0x2c, 0x58, 0xe5, 0x14,
- 0x8b, 0x33, 0x3d, 0x64, 0x7b, 0x1a, 0x12, 0x19, 0xd3, 0xdb, 0xb0, 0x2a,
- 0x84, 0x87, 0x32, 0xf3, 0x31, 0xb9, 0x05, 0x2d, 0xe3, 0xc0, 0x0f, 0x33,
- 0x41, 0x34, 0x8f, 0x86, 0xfb, 0x6f, 0x95, 0xc2, 0x03, 0xb3, 0x12, 0xdf,
- 0xbb, 0xbc, 0x66, 0xa5, 0x8d, 0xc5, 0x3f, 0x5a, 0xb3, 0xc2, 0xfe, 0x0c,
- 0x18, 0xd7, 0xe7, 0xef, 0x40, 0x7a, 0xc6, 0x33, 0x5b, 0x96, 0x2c, 0x3c,
- 0x14, 0x93, 0x70, 0xb3, 0xfe, 0x6f, 0xc9, 0xb7, 0x04, 0xd9, 0xc6, 0xab,
- 0x9c, 0x83, 0xed, 0x60, 0xb6, 0x64, 0x95, 0x86, 0x55, 0x99, 0x3a, 0x8a,
- 0x49, 0xf5, 0x14, 0x9f, 0xea, 0x70, 0x85, 0x62, 0xd2, 0x8a, 0x36, 0x0b,
- 0x8b, 0xdb, 0xcc, 0xbe, 0xc5, 0xe0, 0x3d, 0x68, 0xd5, 0x2c, 0x0a, 0xb5,
- 0xa7, 0x4b, 0x52, 0xbb, 0xeb, 0x25, 0x05, 0xdb, 0x23, 0x3c, 0x77, 0xd0,
- 0x58, 0x95, 0xaf, 0xe4, 0xd3, 0x4a, 0x5e, 0x75, 0xce, 0xe5, 0x53, 0xb7,
- 0xa1, 0x4f, 0xab, 0x3f, 0x4e, 0x49, 0xbc, 0x6f, 0xd2, 0x83, 0x91, 0x6c,
- 0x0a, 0x7b, 0xb3, 0x21, 0xfc, 0x3a, 0xe3, 0x26, 0xdb, 0x08, 0xeb, 0x3f,
- 0x00, 0x8f, 0xf1, 0x19, 0xb1, 0x7c, 0x38, 0xfa, 0x90, 0xf4, 0x13, 0x94,
- 0x9d, 0xea, 0x11, 0xaa, 0x12, 0x08, 0x37, 0x34, 0x87, 0x5e, 0xc4, 0x4f,
- 0xec, 0x7d, 0x36, 0xa0, 0xc2, 0x43, 0x53, 0x1e, 0xc8, 0x65, 0x3c, 0xb3,
- 0xb0, 0x7b, 0xb2, 0xbc, 0x6f, 0x2c, 0x61, 0xbd, 0x7e, 0x3f, 0xc9, 0x59,
- 0xa0, 0xa9, 0xb5, 0x0e, 0xe5, 0x2d, 0x4e, 0x8c, 0x64, 0x38, 0x0f, 0x7f,
- 0xbc, 0x46, 0x1e, 0x42, 0x79, 0x6e, 0x4f, 0x34, 0xe1, 0xa0, 0x0c, 0xfd,
- 0x72, 0x11, 0x38, 0x48, 0xb1, 0x63, 0x53, 0xec, 0x37, 0x56, 0x05, 0x8f,
- 0xca, 0xfe, 0xf4, 0x98, 0xc0, 0x02, 0x2d, 0x49, 0xf2, 0x70, 0xfa, 0x0f,
- 0xa5, 0xa3, 0x76, 0x0e, 0x1e, 0xa1, 0xf9, 0x93, 0xf6, 0xfc, 0x91, 0xfd,
- 0x4b, 0x25, 0x09, 0xd7, 0xb7, 0x1e, 0xc5, 0xc4, 0xc2, 0x0a, 0x0d, 0x41,
- 0xc2, 0x04, 0x5c, 0xcb, 0xd6, 0x13, 0x8f, 0x9b, 0x1f, 0xe3, 0xbe, 0xe6,
- 0x6f, 0xd7, 0xdc, 0x30, 0xce, 0x7e, 0xfd, 0xf1, 0x9a, 0x77, 0xd3, 0x6a,
- 0xb2, 0x9e, 0xea, 0x87, 0x6a, 0x92, 0xc3, 0xbd, 0x43, 0xdc, 0x4f, 0xa8,
- 0x37, 0x5e, 0x3f, 0xcc, 0x79, 0x59, 0x1d, 0x68, 0x10, 0x3e, 0x71, 0x73,
- 0x46, 0xed, 0x63, 0xc2, 0x2f, 0x47, 0xd4, 0x20, 0xc9, 0xae, 0xf3, 0x1e,
- 0xd1, 0xc7, 0x35, 0x8b, 0x2d, 0xb7, 0xeb, 0xf2, 0x15, 0xdc, 0x11, 0x9e,
- 0xc3, 0x21, 0x51, 0x1b, 0x77, 0x58, 0xd6, 0x9e, 0x18, 0xe7, 0x71, 0xfb,
- 0x4c, 0x00, 0x5d, 0xaf, 0x33, 0x96, 0x52, 0x6d, 0x31, 0xc8, 0xf4, 0xf1,
- 0x19, 0x0f, 0x89, 0x6a, 0xd1, 0xec, 0xab, 0x73, 0xb8, 0xc4, 0x87, 0x7d,
- 0x74, 0xbd, 0x6c, 0xe3, 0x13, 0x3e, 0xa7, 0xe8, 0x35, 0x94, 0xc7, 0xf8,
- 0x6c, 0xe3, 0x6f, 0xd7, 0xac, 0x1f, 0x53, 0x43, 0x12, 0xf1, 0xb1, 0x97,
- 0xf7, 0xe7, 0x69, 0xce, 0x69, 0x9d, 0xe9, 0xbe, 0xbc, 0x86, 0xfb, 0xb1,
- 0x4b, 0x88, 0x6e, 0x2b, 0x1b, 0x66, 0x0c, 0x6a, 0xdb, 0x4a, 0x22, 0x4f,
- 0x55, 0xfd, 0xe2, 0x0a, 0xaf, 0x2e, 0xd2, 0xc9, 0xb1, 0x74, 0x12, 0xa7,
- 0xe2, 0x15, 0xfd, 0xac, 0xcb, 0x7f, 0x03, 0xa9, 0xfa, 0x0e, 0xe4, 0xb2,
- 0x8a, 0x7f, 0x43, 0xa6, 0x03, 0xa3, 0xa4, 0xc3, 0xbb, 0x8b, 0x41, 0x7f,
- 0x47, 0x46, 0x43, 0x6f, 0x91, 0xeb, 0x2b, 0x18, 0x7b, 0xc6, 0x26, 0xe7,
- 0xea, 0xe0, 0x4a, 0x2e, 0x39, 0x90, 0xa9, 0xd8, 0x5c, 0x38, 0xef, 0x99,
- 0x0d, 0x89, 0xca, 0xbc, 0x32, 0xad, 0x23, 0x0f, 0xfd, 0x89, 0x85, 0x85,
- 0x6c, 0x0b, 0x77, 0x60, 0x6c, 0xdc, 0x6f, 0x2e, 0x36, 0x14, 0xac, 0x6a,
- 0xfd, 0x73, 0x7a, 0xb6, 0x05, 0x1f, 0x1f, 0xff, 0x3a, 0xca, 0xdf, 0x24,
- 0x7c, 0x94, 0x49, 0xa2, 0xb9, 0xf5, 0x16, 0xa4, 0xfe, 0x40, 0xc6, 0xd3,
- 0x19, 0x1f, 0x9e, 0xcf, 0x54, 0xf6, 0xec, 0x7f, 0x94, 0x25, 0x3f, 0x24,
- 0x1f, 0x78, 0xee, 0x4b, 0xf7, 0x49, 0x29, 0x9e, 0x3b, 0x78, 0x0f, 0xff,
- 0x1f, 0x1e, 0x77, 0xde, 0x1e, 0xe7, 0x11, 0x75, 0x23, 0xf3, 0xf3, 0x5a,
- 0xd0, 0x5a, 0xff, 0xbe, 0x67, 0x08, 0xf3, 0x81, 0x62, 0x48, 0xe5, 0x8c,
- 0x83, 0x90, 0x47, 0xec, 0x7d, 0x23, 0xc2, 0xb9, 0x11, 0xfd, 0x02, 0x4c,
- 0xb8, 0x09, 0x5f, 0x2d, 0x25, 0x59, 0x68, 0x99, 0x80, 0x5f, 0x2a, 0x2a,
- 0xf4, 0xdf, 0xe8, 0x77, 0x92, 0x7c, 0x9c, 0xc5, 0x8f, 0x28, 0xa6, 0xb0,
- 0x4f, 0x55, 0x72, 0x9c, 0x54, 0x7c, 0xc4, 0x4b, 0xc0, 0x87, 0x3e, 0x2b,
- 0x36, 0x1d, 0xca, 0x2f, 0xf6, 0x32, 0x96, 0xc9, 0x65, 0x2a, 0xbf, 0x23,
- 0x57, 0x7f, 0x93, 0x9e, 0x6d, 0x99, 0x8d, 0xd0, 0x6f, 0x96, 0xc5, 0x73,
- 0x56, 0x6a, 0x33, 0xcb, 0x2b, 0xe0, 0x7f, 0x83, 0xe4, 0x3f, 0x46, 0x34,
- 0x66, 0x69, 0x8d, 0xd7, 0x69, 0xcd, 0x4c, 0xf1, 0x10, 0x8d, 0xe1, 0x7b,
- 0x24, 0x67, 0xdb, 0x76, 0x0f, 0x7b, 0xf9, 0x7c, 0xc2, 0xf3, 0x19, 0x60,
- 0x30, 0x6b, 0xaa, 0xce, 0xb9, 0x73, 0x9d, 0x83, 0x94, 0x2f, 0xab, 0x28,
- 0x16, 0xbd, 0x19, 0xdf, 0x8e, 0x1b, 0x73, 0x6a, 0xd2, 0x24, 0x3c, 0x96,
- 0x52, 0x20, 0x48, 0x77, 0x64, 0xc3, 0x01, 0xe3, 0xdd, 0x74, 0x23, 0xf1,
- 0x14, 0x0e, 0x5d, 0xa0, 0xf1, 0xa6, 0x53, 0xc6, 0x81, 0x51, 0x07, 0x2e,
- 0xf0, 0x1e, 0xb2, 0xa8, 0x3c, 0x6f, 0x82, 0xc7, 0xce, 0x7f, 0xaf, 0xa6,
- 0xba, 0x2e, 0x9c, 0xa0, 0xac, 0x6a, 0xd6, 0x10, 0x6e, 0xcf, 0xb7, 0x3f,
- 0x82, 0x43, 0x54, 0xeb, 0xef, 0x88, 0x85, 0x90, 0xac, 0x8b, 0x53, 0xbd,
- 0xd1, 0xdc, 0x7f, 0x09, 0xff, 0xcd, 0x2a, 0xf3, 0x3e, 0xbc, 0x08, 0x27,
- 0x2e, 0xe1, 0x53, 0xcb, 0xa1, 0x69, 0x67, 0xa7, 0xa0, 0x95, 0x2f, 0xa0,
- 0x79, 0xe0, 0x13, 0xbc, 0x67, 0xf1, 0x1e, 0xbd, 0xec, 0x70, 0x10, 0x06,
- 0x0c, 0x2b, 0x4e, 0x04, 0x50, 0x0e, 0x38, 0xb0, 0x49, 0xe7, 0xde, 0xb4,
- 0x3a, 0xf0, 0x24, 0x61, 0xf9, 0x77, 0x44, 0x73, 0xdf, 0x87, 0x38, 0x6f,
- 0x4d, 0xd4, 0xf1, 0xba, 0x02, 0x89, 0xeb, 0x9b, 0xcf, 0xba, 0xa1, 0x76,
- 0xba, 0x84, 0x96, 0x68, 0x70, 0xfc, 0x95, 0x75, 0x3e, 0xf0, 0xa9, 0xa5,
- 0x45, 0x3e, 0x25, 0x1c, 0xa4, 0x05, 0x27, 0xc9, 0xf6, 0xfb, 0x30, 0x4f,
- 0x9b, 0xa8, 0x86, 0x57, 0x27, 0x1a, 0x18, 0xf7, 0x99, 0x9e, 0x7d, 0x44,
- 0xdb, 0x6b, 0x84, 0x03, 0x76, 0xc4, 0x2e, 0x59, 0xc9, 0x85, 0x7c, 0xfe,
- 0x4f, 0xa9, 0xae, 0xf4, 0xc0, 0xb9, 0x6f, 0x72, 0x07, 0xee, 0x4a, 0x3b,
- 0x49, 0x4e, 0xf3, 0x78, 0xcd, 0x45, 0x31, 0x98, 0x63, 0x7f, 0xf9, 0x3a,
- 0x2a, 0xcd, 0x24, 0x2a, 0xf1, 0xb1, 0x87, 0xe2, 0xc2, 0x6e, 0x3b, 0x17,
- 0xc0, 0xbb, 0x64, 0x55, 0x2b, 0x3e, 0x19, 0x7f, 0xd3, 0x4b, 0xbe, 0xb4,
- 0x4e, 0x6b, 0x83, 0x08, 0x66, 0x4c, 0x51, 0x6b, 0x38, 0xf0, 0x61, 0xbb,
- 0xda, 0x29, 0x39, 0x06, 0x70, 0x7d, 0xcc, 0xb4, 0x7c, 0x9a, 0xd6, 0xd3,
- 0x22, 0x22, 0xdd, 0x45, 0x11, 0x45, 0x75, 0xd1, 0x27, 0x57, 0x17, 0x5b,
- 0x64, 0x6f, 0xd1, 0xf4, 0x28, 0xab, 0xb6, 0x53, 0xdd, 0xb2, 0x8b, 0x6a,
- 0x5b, 0x1f, 0xd5, 0xd7, 0xaa, 0x7e, 0x11, 0x6e, 0x92, 0x7f, 0x08, 0xfb,
- 0x4a, 0x06, 0x9c, 0x99, 0x9d, 0x70, 0x65, 0xc2, 0xca, 0x5e, 0xec, 0x42,
- 0x32, 0x58, 0xc1, 0xb6, 0x32, 0xe9, 0xaa, 0xaa, 0x9d, 0xb1, 0xcc, 0x76,
- 0x9c, 0x9f, 0x60, 0x7c, 0x9e, 0xc0, 0xd6, 0x34, 0xff, 0x86, 0xf7, 0xc5,
- 0xb8, 0x81, 0x93, 0x54, 0x3b, 0x79, 0x5a, 0x1b, 0x48, 0x0f, 0x8d, 0x18,
- 0x2c, 0x09, 0x36, 0x2b, 0xd2, 0x05, 0xbc, 0x27, 0xdb, 0x65, 0x1c, 0x9c,
- 0xa2, 0x44, 0x42, 0xf9, 0xca, 0x99, 0x51, 0x28, 0x4e, 0xc8, 0xf0, 0x69,
- 0x3e, 0xfa, 0x1d, 0xe0, 0x73, 0x4b, 0x64, 0x67, 0xbf, 0x5d, 0xd3, 0x62,
- 0xc7, 0x9a, 0x7a, 0xaa, 0x75, 0xde, 0x21, 0x5e, 0x58, 0x16, 0x06, 0xaa,
- 0x47, 0xe6, 0x6b, 0xc2, 0xf5, 0xb7, 0x55, 0x23, 0x48, 0x73, 0x32, 0x0e,
- 0xac, 0x9c, 0x57, 0x5d, 0x1f, 0x6b, 0x45, 0x21, 0x27, 0xe6, 0x30, 0xd6,
- 0xa0, 0xea, 0xc3, 0x3a, 0x1c, 0xa2, 0xda, 0xdf, 0xaf, 0x6d, 0x45, 0x46,
- 0x29, 0x7b, 0x7f, 0x11, 0xe7, 0x1a, 0x00, 0xde, 0x5e, 0xc2, 0x50, 0x43,
- 0xe9, 0xaf, 0x72, 0xcc, 0xf4, 0xdc, 0x1d, 0xd7, 0x71, 0x24, 0x47, 0x21,
- 0x4a, 0x5b, 0x87, 0xda, 0xb6, 0x2e, 0x7c, 0x58, 0xc7, 0xf8, 0x97, 0x62,
- 0x15, 0xd1, 0xb3, 0x77, 0x2a, 0x60, 0x9f, 0xab, 0xd8, 0x57, 0x9a, 0xa7,
- 0xf9, 0x5a, 0x5a, 0xbf, 0x8c, 0x46, 0x96, 0xc9, 0x3f, 0x44, 0x23, 0xd9,
- 0x2c, 0x61, 0x9e, 0x5c, 0xba, 0x17, 0x2f, 0xa7, 0x79, 0xde, 0x70, 0x52,
- 0x17, 0x0a, 0xf7, 0xe6, 0x6d, 0x99, 0x98, 0x53, 0xbc, 0x06, 0xaf, 0x3f,
- 0xbf, 0x4e, 0x80, 0x6a, 0x85, 0x7f, 0xec, 0x5a, 0x14, 0x37, 0x72, 0xeb,
- 0xa8, 0xee, 0x8c, 0x42, 0xfb, 0xfd, 0x32, 0xe9, 0x83, 0x7b, 0xd5, 0x4b,
- 0x09, 0xf3, 0xc2, 0xf3, 0x4a, 0x9c, 0xcf, 0x30, 0x5b, 0xbb, 0x64, 0xc3,
- 0xb2, 0x5c, 0xed, 0x9a, 0xf2, 0x36, 0xd8, 0x0e, 0x7d, 0xbc, 0xe7, 0xe1,
- 0xd9, 0xdb, 0xee, 0xc3, 0x41, 0xca, 0x81, 0x4f, 0xa5, 0x9b, 0x4d, 0xae,
- 0xfd, 0xc0, 0x38, 0x54, 0xa4, 0xe8, 0xd9, 0x7f, 0x55, 0xcd, 0x3e, 0xbb,
- 0xa7, 0xb4, 0x13, 0x52, 0xa6, 0xa7, 0x9a, 0xeb, 0x0d, 0x37, 0xd5, 0xc9,
- 0x83, 0x69, 0xa6, 0xd7, 0xda, 0xe5, 0xa4, 0xb9, 0x76, 0xc7, 0xb5, 0xd9,
- 0x1b, 0xc9, 0x2e, 0x1a, 0x0c, 0x96, 0x63, 0x00, 0x4f, 0xd0, 0xd8, 0x50,
- 0x89, 0x65, 0x79, 0xa8, 0x9a, 0xfb, 0x9e, 0xfb, 0x48, 0xbf, 0xb5, 0xd9,
- 0xca, 0x3c, 0xd9, 0x52, 0x1f, 0x96, 0x0e, 0xbd, 0x58, 0x5d, 0xa9, 0x7d,
- 0xb8, 0x2e, 0xef, 0xc7, 0xbe, 0x74, 0x00, 0x53, 0xe9, 0x66, 0xe5, 0x05,
- 0xfb, 0xcc, 0x40, 0xa5, 0x47, 0x36, 0x98, 0x9e, 0x1f, 0x13, 0xc0, 0xe4,
- 0xd5, 0xef, 0x2c, 0x9f, 0x4a, 0xef, 0xf4, 0x94, 0x8d, 0xf9, 0x65, 0x4c,
- 0x04, 0x2a, 0x78, 0x88, 0x62, 0x85, 0xf7, 0x51, 0xd2, 0xeb, 0x3b, 0xa4,
- 0x57, 0x89, 0xf4, 0xfa, 0x82, 0xfe, 0x23, 0xc6, 0x2c, 0x9e, 0x3d, 0x71,
- 0x1f, 0xef, 0x13, 0x99, 0x04, 0x5a, 0xec, 0x31, 0x99, 0xb8, 0x13, 0xe7,
- 0x86, 0xf8, 0x6c, 0xe2, 0x47, 0x6b, 0x5e, 0x4a, 0x5b, 0xeb, 0x66, 0x62,
- 0xcd, 0xa9, 0x77, 0x08, 0x4f, 0x9b, 0x7f, 0xa0, 0xea, 0xe7, 0xc9, 0x4f,
- 0xb3, 0xa3, 0x7f, 0x88, 0xf3, 0x75, 0xcd, 0xca, 0xcf, 0x61, 0x7a, 0x1e,
- 0x8f, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0x6d, 0xff, 0x92, 0x9c, 0x2c,
- 0x0e, 0x87, 0xd6, 0x3c, 0xfb, 0x02, 0xfe, 0x23, 0xce, 0x2f, 0x0e, 0xeb,
- 0x2f, 0x80, 0xc7, 0x54, 0xea, 0xf1, 0xf0, 0xf4, 0x7d, 0x7c, 0x9e, 0x2a,
- 0x48, 0x69, 0xb4, 0xb2, 0x9f, 0x95, 0xe6, 0xfd, 0x37, 0x81, 0x89, 0x2d,
- 0x54, 0x4b, 0xdb, 0xe7, 0x58, 0xe1, 0x7d, 0x92, 0xfc, 0x22, 0x3a, 0xcc,
- 0xe3, 0x3f, 0x5e, 0xa3, 0xe5, 0x43, 0x70, 0x10, 0xc6, 0x49, 0x05, 0xd4,
- 0x4e, 0x20, 0xe8, 0x7f, 0x32, 0x1d, 0xa4, 0x1a, 0xad, 0xb9, 0x3b, 0x2a,
- 0xee, 0x9c, 0xdb, 0xf7, 0xe6, 0x3c, 0xf7, 0xf1, 0x9a, 0x63, 0x69, 0x35,
- 0xf5, 0x24, 0x9a, 0x7b, 0x7c, 0xe2, 0x0e, 0xa4, 0xea, 0x9a, 0xfb, 0x4e,
- 0x22, 0x9c, 0xf0, 0x08, 0x35, 0x7a, 0x1e, 0x95, 0x79, 0x96, 0xe5, 0x1d,
- 0x54, 0x27, 0x72, 0x9c, 0x49, 0xe3, 0xa4, 0xe2, 0xc0, 0xf2, 0x56, 0x6d,
- 0x76, 0x12, 0xf3, 0xf6, 0x52, 0x19, 0xb3, 0x2e, 0x4f, 0xe3, 0x1d, 0x0a,
- 0xd5, 0xfb, 0x6e, 0x38, 0xeb, 0x79, 0x4f, 0x71, 0x27, 0x76, 0xa4, 0x39,
- 0x4f, 0x93, 0x5c, 0xc8, 0x37, 0xbb, 0x23, 0x3b, 0xd1, 0x9f, 0x0f, 0xe0,
- 0x50, 0x36, 0xbc, 0x7f, 0x2f, 0xe1, 0xba, 0xe1, 0x52, 0x38, 0xb4, 0x4d,
- 0x04, 0x48, 0xdf, 0x54, 0xff, 0xd7, 0x07, 0xa9, 0x4e, 0x56, 0xe8, 0xbf,
- 0x52, 0xcf, 0xbc, 0x44, 0xf5, 0xcc, 0x39, 0xf2, 0x35, 0xdf, 0x5c, 0xad,
- 0xba, 0x6c, 0xc2, 0xc2, 0x4c, 0x6c, 0x23, 0x2e, 0xdb, 0x3a, 0x0b, 0x92,
- 0x8d, 0x71, 0x2e, 0xe2, 0xb3, 0x35, 0x1e, 0xb1, 0x6d, 0xd8, 0xf4, 0x3c,
- 0xd8, 0x1e, 0x44, 0x38, 0xc3, 0x98, 0x53, 0xfa, 0xa6, 0x83, 0xe4, 0x31,
- 0xa5, 0xed, 0xc2, 0x86, 0xd8, 0x2e, 0xf4, 0xeb, 0x7f, 0x02, 0x77, 0x3d,
- 0xc7, 0x23, 0xd9, 0xac, 0xa5, 0x79, 0x2f, 0xb5, 0x77, 0x21, 0x7c, 0x94,
- 0x73, 0x30, 0x55, 0xc3, 0x43, 0xec, 0xbb, 0x3c, 0xff, 0x6d, 0xc6, 0x0a,
- 0xc2, 0x15, 0x35, 0xed, 0x95, 0x3c, 0x7f, 0x7d, 0x9e, 0xcf, 0x74, 0x82,
- 0x6a, 0x53, 0x78, 0xdf, 0x5a, 0x6d, 0xe0, 0x71, 0x8a, 0x31, 0x89, 0x36,
- 0x17, 0xb0, 0x80, 0xcf, 0x2e, 0x57, 0xea, 0x18, 0xe6, 0x77, 0x69, 0x5e,
- 0x60, 0x3a, 0x4e, 0xf6, 0xf1, 0x77, 0xce, 0x28, 0x85, 0xe6, 0xce, 0x96,
- 0x72, 0xff, 0xe4, 0xb0, 0x95, 0xe4, 0xf7, 0x0d, 0xa4, 0xa0, 0x8f, 0xe2,
- 0x6d, 0xb0, 0x0c, 0x2a, 0xea, 0x29, 0x2e, 0x3b, 0xb4, 0x79, 0xb9, 0xb3,
- 0xac, 0x4f, 0x58, 0x13, 0x73, 0xba, 0x70, 0xd2, 0x33, 0x7b, 0xc6, 0xd4,
- 0x81, 0xbd, 0x68, 0xee, 0x7f, 0x57, 0x54, 0xd9, 0x3b, 0x98, 0x93, 0x2d,
- 0x48, 0x2d, 0x31, 0x9c, 0x5b, 0x3e, 0xc9, 0xae, 0x23, 0x3a, 0x2e, 0x10,
- 0x08, 0x5d, 0x6f, 0xef, 0x73, 0x4d, 0xb6, 0xfc, 0x29, 0xcd, 0xcd, 0xdf,
- 0xff, 0xd8, 0xc7, 0x67, 0x2e, 0x4f, 0x65, 0x9f, 0xb7, 0xa2, 0x0b, 0x2b,
- 0xf2, 0x39, 0x4d, 0xbe, 0x1f, 0x34, 0x24, 0x34, 0x68, 0x91, 0xd9, 0x1e,
- 0xfa, 0xfd, 0xd7, 0x79, 0x42, 0xfb, 0xab, 0xfb, 0xf0, 0xcb, 0x09, 0x03,
- 0x07, 0x28, 0x0f, 0xd4, 0x6a, 0xaa, 0x32, 0x81, 0x10, 0xd7, 0xd2, 0x36,
- 0xff, 0x2b, 0x27, 0xc8, 0x0f, 0xeb, 0x14, 0xbb, 0xc6, 0xa8, 0xf0, 0x77,
- 0x99, 0xf8, 0x7b, 0xd0, 0xc7, 0xbe, 0xb0, 0x84, 0xfc, 0x62, 0x3f, 0xf9,
- 0xeb, 0x01, 0xb2, 0x35, 0xaa, 0xe0, 0xc9, 0x0f, 0xd4, 0xfd, 0x20, 0x7f,
- 0x1d, 0x4e, 0xb3, 0xfc, 0x83, 0xfe, 0x5e, 0x3e, 0xde, 0xac, 0xd9, 0x7d,
- 0x55, 0x3d, 0x24, 0x71, 0xdc, 0xb5, 0xe3, 0xa9, 0x19, 0x92, 0xac, 0x6a,
- 0xa6, 0x6b, 0xb0, 0x14, 0x0e, 0x7a, 0xf9, 0x5d, 0x00, 0x02, 0x87, 0xbd,
- 0x7a, 0x25, 0x57, 0xce, 0x50, 0x3e, 0xba, 0x4c, 0x74, 0x1c, 0x8a, 0x35,
- 0x20, 0x45, 0xf9, 0x28, 0xa3, 0x55, 0x6c, 0x49, 0x9b, 0x66, 0x8c, 0x59,
- 0x6f, 0x04, 0xc7, 0xd5, 0x90, 0xcb, 0xd1, 0x3c, 0x70, 0x06, 0x3b, 0xad,
- 0xf3, 0x75, 0x6c, 0x53, 0x2e, 0x1c, 0x6f, 0x99, 0xb6, 0xca, 0x01, 0xe6,
- 0xd7, 0x81, 0xe7, 0x75, 0xb2, 0x99, 0xc5, 0xe1, 0xe0, 0xf3, 0x94, 0x53,
- 0xa7, 0xe6, 0xf4, 0x11, 0xce, 0xcf, 0xdb, 0xe3, 0x5a, 0x96, 0x75, 0x34,
- 0x05, 0x2d, 0x91, 0x47, 0x2f, 0x7d, 0x6f, 0x0a, 0x5e, 0x9e, 0xb3, 0xd5,
- 0x15, 0xd3, 0xaf, 0xfb, 0xe6, 0xde, 0xcb, 0xb1, 0x9f, 0x09, 0xe5, 0xff,
- 0x88, 0x7e, 0xf3, 0x9c, 0x01, 0xc6, 0x32, 0x7c, 0x56, 0xcb, 0xbb, 0xa3,
- 0xdd, 0xcd, 0xfe, 0xa2, 0xf0, 0x3b, 0x09, 0x1b, 0x86, 0xb9, 0x2f, 0xcc,
- 0x3d, 0x1a, 0x07, 0xf6, 0x5e, 0x7d, 0x67, 0x82, 0x3f, 0x3b, 0xb1, 0x69,
- 0x98, 0x7b, 0x11, 0xa7, 0x6f, 0x90, 0xf1, 0x37, 0x94, 0x87, 0x65, 0xf6,
- 0x79, 0xf2, 0xf5, 0x4f, 0xd7, 0xbc, 0x34, 0xc6, 0x39, 0x35, 0x60, 0xdc,
- 0x95, 0x9e, 0xd7, 0xf1, 0x55, 0x9e, 0xce, 0xde, 0x4d, 0x71, 0x27, 0x93,
- 0x56, 0x07, 0x22, 0x0e, 0x7b, 0x7f, 0x2d, 0x55, 0x14, 0x5f, 0xa5, 0x22,
- 0x8d, 0xe7, 0x53, 0xfc, 0x03, 0x87, 0x43, 0xc8, 0x64, 0xbb, 0xf0, 0x8d,
- 0x61, 0xcb, 0x72, 0xb7, 0x39, 0xf1, 0xca, 0x90, 0x85, 0x0f, 0x62, 0xc0,
- 0xcb, 0x43, 0xe1, 0x81, 0x73, 0xc0, 0xb7, 0x6b, 0xa9, 0x46, 0x6e, 0x11,
- 0x6a, 0x37, 0x61, 0x83, 0xd0, 0x7b, 0x68, 0x0e, 0xe6, 0xa1, 0x9e, 0xdd,
- 0x4d, 0xf3, 0xbd, 0x58, 0x00, 0x7e, 0x59, 0xf0, 0xe2, 0x17, 0xc3, 0x3c,
- 0xa7, 0x17, 0xe7, 0x8e, 0xd6, 0xfb, 0x77, 0xd2, 0x5c, 0x07, 0x29, 0xbe,
- 0x77, 0x1d, 0x4b, 0x60, 0xd3, 0x61, 0x81, 0x68, 0x24, 0x81, 0xce, 0x63,
- 0x35, 0xd8, 0x38, 0x2c, 0xe3, 0xfd, 0x78, 0x0d, 0x6e, 0x39, 0x3a, 0xcf,
- 0x47, 0xa5, 0xaf, 0xc1, 0x67, 0x35, 0xf9, 0x1c, 0xdc, 0xc9, 0x2c, 0xc7,
- 0x6c, 0xca, 0x17, 0x59, 0x8e, 0x81, 0x96, 0x15, 0x6c, 0xaf, 0xf4, 0x39,
- 0x9e, 0xa6, 0xfc, 0xf1, 0x78, 0xbb, 0x16, 0x0c, 0x4a, 0x06, 0x96, 0x8f,
- 0x96, 0xef, 0xac, 0x85, 0x75, 0x8a, 0xf7, 0x33, 0x3e, 0x6a, 0xb1, 0xac,
- 0x4d, 0xf1, 0xc8, 0xec, 0xbd, 0x36, 0xae, 0x0d, 0x90, 0x4f, 0x35, 0xe2,
- 0xf1, 0xec, 0xfc, 0x9e, 0x97, 0xd6, 0x73, 0xc9, 0x61, 0xee, 0x52, 0x60,
- 0x5d, 0xa9, 0x32, 0xac, 0x8f, 0x5c, 0x46, 0x24, 0xf8, 0x80, 0xe0, 0xb3,
- 0x22, 0xdc, 0x13, 0xb7, 0xac, 0x37, 0xe3, 0x96, 0x55, 0x88, 0x9b, 0x9e,
- 0x15, 0xab, 0x14, 0x1c, 0x5b, 0xc6, 0xef, 0x2a, 0x84, 0x93, 0x0d, 0x64,
- 0x5f, 0xde, 0x65, 0x5a, 0x70, 0x2b, 0x54, 0xd3, 0xa4, 0x20, 0x17, 0x5a,
- 0xa8, 0xf6, 0x00, 0x8d, 0xfe, 0x43, 0x43, 0xf5, 0xf8, 0xfe, 0xcc, 0xef,
- 0xf2, 0xf1, 0x1d, 0xbb, 0x9f, 0x76, 0x45, 0xc7, 0xba, 0x5a, 0x44, 0x92,
- 0xf7, 0x80, 0x7b, 0xa3, 0x7c, 0xa6, 0xd5, 0xc4, 0x2d, 0xf1, 0x3e, 0xec,
- 0x18, 0xe6, 0x7d, 0xb6, 0x3a, 0xe3, 0xca, 0xb0, 0xf5, 0xd7, 0x1e, 0xa2,
- 0x7f, 0x5d, 0x7b, 0x73, 0xca, 0x6b, 0xbf, 0xe3, 0xe4, 0x34, 0xd6, 0x8f,
- 0xd5, 0xa1, 0x34, 0xa5, 0x95, 0x97, 0x88, 0xe4, 0x1b, 0x3e, 0x44, 0x82,
- 0x0d, 0x14, 0xab, 0x66, 0xc8, 0x77, 0xa7, 0x4a, 0x5c, 0x07, 0x2c, 0x30,
- 0xac, 0xd1, 0x45, 0x98, 0x9c, 0xa1, 0xb9, 0xb2, 0x5a, 0xe7, 0x07, 0x84,
- 0xf3, 0xaa, 0x0d, 0xab, 0xd6, 0x6b, 0x44, 0xce, 0x36, 0x0b, 0x07, 0x66,
- 0xdb, 0x2c, 0xab, 0xab, 0x5d, 0x1b, 0xa8, 0x11, 0xe8, 0x97, 0x0c, 0x2d,
- 0xd1, 0xe2, 0xc0, 0xd7, 0x82, 0x88, 0x74, 0xbe, 0x89, 0x48, 0xcf, 0x05,
- 0x8a, 0x61, 0x4f, 0x95, 0xf8, 0x9c, 0xf0, 0x23, 0xf8, 0xeb, 0xe1, 0x85,
- 0x38, 0x35, 0xd5, 0x3f, 0xd7, 0x13, 0x83, 0xf7, 0xfa, 0x55, 0x06, 0x8e,
- 0x0f, 0x87, 0xc8, 0x7e, 0xdc, 0x14, 0xd7, 0x65, 0x48, 0x4d, 0x90, 0xeb,
- 0xa8, 0x4e, 0x88, 0x3d, 0x66, 0x59, 0x2b, 0x9a, 0x2a, 0x35, 0xcf, 0x8a,
- 0xe9, 0x6b, 0xdf, 0x71, 0x98, 0xef, 0xf7, 0x04, 0x49, 0x7f, 0xcd, 0xa9,
- 0x1d, 0xe2, 0x8c, 0x65, 0xfe, 0x81, 0x20, 0x9e, 0x7b, 0x6a, 0xe0, 0x65,
- 0xbe, 0x65, 0xec, 0x1e, 0xe5, 0x3e, 0x1c, 0xeb, 0x0d, 0xde, 0xce, 0x38,
- 0xef, 0x97, 0xb3, 0x8e, 0xca, 0xde, 0x0d, 0x71, 0x8a, 0x89, 0xc2, 0x4f,
- 0x78, 0xca, 0xf4, 0x74, 0x50, 0x7e, 0xaa, 0x1a, 0xe6, 0xf7, 0x2d, 0x7c,
- 0x38, 0x40, 0x71, 0xe3, 0xb2, 0x5e, 0x8d, 0x43, 0x75, 0x6a, 0x82, 0xeb,
- 0xe9, 0x27, 0x4b, 0xdc, 0x33, 0xdc, 0x89, 0xed, 0xfc, 0xbe, 0x4a, 0x69,
- 0xb5, 0x7d, 0xb6, 0x90, 0xae, 0x11, 0x36, 0x60, 0x3a, 0xe6, 0xd7, 0xef,
- 0xc4, 0x92, 0x21, 0xd6, 0xe3, 0xc7, 0x6b, 0x82, 0x24, 0xa3, 0xc7, 0xc9,
- 0x2e, 0x24, 0xa3, 0x03, 0xf2, 0x90, 0x65, 0xdd, 0x18, 0xbf, 0x76, 0x0e,
- 0xad, 0xff, 0x82, 0x83, 0xea, 0x3b, 0x07, 0xef, 0xeb, 0xa9, 0x89, 0x13,
- 0xe2, 0xda, 0x39, 0x0b, 0x35, 0xdc, 0x4f, 0x34, 0xa7, 0x2a, 0x79, 0xe9,
- 0x38, 0xe5, 0xa5, 0x97, 0x73, 0xec, 0x23, 0xf5, 0x06, 0xfb, 0x88, 0x44,
- 0xb1, 0x76, 0x7d, 0x3a, 0x84, 0x0b, 0x3a, 0x34, 0x37, 0x62, 0x44, 0x77,
- 0xa4, 0xbb, 0x63, 0x0e, 0xf3, 0xb9, 0x28, 0xfe, 0x4f, 0xe5, 0x78, 0xaf,
- 0x4d, 0xa0, 0x46, 0x63, 0x1b, 0xb0, 0x73, 0x01, 0xc5, 0xb4, 0x7e, 0xd4,
- 0xae, 0x06, 0x2e, 0x0d, 0xf1, 0xfe, 0x8c, 0x86, 0x03, 0xa5, 0x01, 0xd1,
- 0x30, 0xf4, 0x5b, 0x2b, 0x54, 0x35, 0xbf, 0x07, 0xf8, 0x30, 0xef, 0x01,
- 0x92, 0x0d, 0xf4, 0xdb, 0xe7, 0x7c, 0xde, 0x4c, 0xf3, 0x39, 0x9f, 0x70,
- 0x68, 0x13, 0xf9, 0x4e, 0x2f, 0x9a, 0xf5, 0x69, 0xc2, 0xce, 0xb3, 0x44,
- 0x67, 0x93, 0xa8, 0xec, 0x73, 0x45, 0xe6, 0xf6, 0xe9, 0x96, 0xe5, 0x3b,
- 0x45, 0x4d, 0x81, 0x69, 0x0a, 0x10, 0x4d, 0x1d, 0xa2, 0xfa, 0xd8, 0x06,
- 0xe1, 0x3b, 0xd6, 0x25, 0xa4, 0x02, 0xc7, 0xe4, 0x3a, 0x63, 0x4f, 0x8e,
- 0xf3, 0xd9, 0x66, 0xe1, 0x3c, 0xba, 0x45, 0x78, 0x0b, 0x3d, 0xc2, 0x7f,
- 0xcc, 0xc4, 0xfd, 0xf1, 0x2e, 0x9c, 0x1b, 0xe6, 0xb3, 0x6c, 0xf7, 0x89,
- 0x9a, 0xb9, 0xbd, 0x39, 0x6f, 0xa1, 0xd1, 0x5f, 0x48, 0x73, 0x7f, 0xf7,
- 0xe3, 0x35, 0xe9, 0xa1, 0x45, 0xfe, 0xa7, 0xc6, 0x02, 0xfe, 0x27, 0xc7,
- 0xd4, 0xfe, 0x7d, 0xc2, 0xb2, 0x76, 0xc6, 0xfe, 0x03, 0xeb, 0xd0, 0x6a,
- 0x8e, 0x55, 0xf0, 0xc1, 0x6e, 0x92, 0xc7, 0x36, 0xca, 0x2d, 0x93, 0x7a,
- 0xf3, 0x1c, 0x16, 0x51, 0x53, 0xfc, 0xee, 0x1b, 0xfd, 0x77, 0x73, 0x6e,
- 0xe3, 0x7d, 0x4d, 0x67, 0x3b, 0x28, 0xee, 0x7e, 0xc6, 0x6b, 0xcd, 0x10,
- 0x9f, 0x51, 0xeb, 0x87, 0xff, 0x4b, 0xf6, 0xf5, 0xce, 0x7d, 0xb6, 0xaf,
- 0x97, 0x78, 0x52, 0xa8, 0xe5, 0x19, 0xe2, 0xb7, 0xca, 0xf1, 0xb9, 0x3d,
- 0xbd, 0xb9, 0xfd, 0xbc, 0x4e, 0xe1, 0x2b, 0x70, 0x7d, 0x1e, 0x30, 0x5e,
- 0x1f, 0xea, 0x10, 0xde, 0x63, 0xc3, 0x94, 0x1f, 0x37, 0x10, 0xcf, 0x7c,
- 0x76, 0xac, 0x4b, 0xf8, 0x0b, 0x9b, 0x85, 0x8f, 0xf8, 0xac, 0x26, 0x3e,
- 0x71, 0xcc, 0x23, 0xbc, 0xc4, 0xa3, 0x87, 0x78, 0xf4, 0xce, 0xf1, 0xe8,
- 0x29, 0x04, 0xfd, 0xe9, 0x74, 0xbd, 0xff, 0xd1, 0x31, 0xc5, 0xbf, 0x6f,
- 0xcc, 0xb2, 0xde, 0xd7, 0x15, 0x3f, 0xf3, 0xf5, 0xaa, 0xfe, 0x45, 0xbe,
- 0x6e, 0x20, 0xbe, 0x2a, 0x7b, 0xb1, 0xa4, 0xc3, 0x14, 0xeb, 0x90, 0xcf,
- 0x71, 0xcc, 0xf3, 0x75, 0x30, 0xcd, 0xfb, 0x95, 0xbc, 0x6f, 0x39, 0x20,
- 0x56, 0x10, 0x5f, 0x65, 0xe2, 0x6b, 0xe5, 0x97, 0xf0, 0xf5, 0xe1, 0x35,
- 0x7c, 0xbd, 0xfa, 0xf7, 0xf2, 0xe5, 0x11, 0xcb, 0x87, 0x39, 0x0e, 0xdd,
- 0x66, 0xc8, 0xc3, 0x16, 0x61, 0x47, 0x07, 0xbe, 0x3f, 0x05, 0x14, 0xb3,
- 0xbb, 0x20, 0x53, 0xbc, 0x39, 0x1d, 0x8f, 0x84, 0x5e, 0xa1, 0x7a, 0x72,
- 0xba, 0xe4, 0x15, 0xcb, 0xec, 0x3d, 0x59, 0xac, 0x90, 0x89, 0xa6, 0x19,
- 0xfb, 0x5d, 0x33, 0xe8, 0xb5, 0x1a, 0xeb, 0x52, 0x3b, 0xbb, 0x15, 0x91,
- 0x72, 0xc4, 0xd1, 0x25, 0x12, 0x05, 0xde, 0x83, 0xdd, 0x22, 0x56, 0xda,
- 0xfb, 0xaf, 0x9d, 0xe2, 0xfa, 0x42, 0x87, 0x68, 0x21, 0xbb, 0x68, 0x3e,
- 0xc6, 0xe7, 0xc1, 0x36, 0x8b, 0xe6, 0x39, 0x79, 0x2c, 0x27, 0x79, 0x0c,
- 0x7d, 0x4e, 0x1e, 0x1b, 0x6c, 0x79, 0xfc, 0x4c, 0xbf, 0x78, 0x4d, 0x0f,
- 0x8d, 0xeb, 0x2a, 0xca, 0x86, 0x54, 0x3b, 0xd5, 0xce, 0xd5, 0x4e, 0x6f,
- 0xc5, 0xf8, 0x9c, 0x8f, 0x69, 0xd5, 0x68, 0x08, 0x39, 0x0d, 0xb5, 0xe7,
- 0xb4, 0xd0, 0x52, 0xf7, 0x89, 0xe4, 0x26, 0x1f, 0xd5, 0x3f, 0x3b, 0x62,
- 0x91, 0xe4, 0x72, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15, 0x5d, 0xae, 0x2a,
- 0x9a, 0xd8, 0x47, 0xf1, 0xed, 0xc5, 0x9c, 0x44, 0xd8, 0x81, 0xdf, 0x3f,
- 0x73, 0xe2, 0x46, 0x82, 0x12, 0x4f, 0x10, 0xee, 0x78, 0x3c, 0xdb, 0x87,
- 0x27, 0xf2, 0xbd, 0x78, 0x3c, 0xff, 0x77, 0xde, 0xb5, 0x91, 0xbd, 0x46,
- 0x63, 0xa2, 0x72, 0x16, 0xe1, 0xe3, 0xc4, 0x75, 0x11, 0x96, 0xcd, 0x89,
- 0x16, 0x39, 0xc2, 0xb5, 0xae, 0xf3, 0x77, 0xdf, 0xd5, 0xd8, 0x17, 0x7b,
- 0x56, 0xbd, 0x64, 0x63, 0x91, 0x93, 0x6d, 0xc7, 0xec, 0x33, 0x52, 0xe5,
- 0x95, 0x7b, 0xec, 0x77, 0x41, 0x7d, 0xab, 0xef, 0xd2, 0xd8, 0x1f, 0x4e,
- 0xc4, 0xd7, 0xdb, 0xf9, 0xb5, 0x71, 0x6d, 0xe5, 0x3d, 0x99, 0xe0, 0xda,
- 0x4a, 0xaf, 0x26, 0xb0, 0x36, 0x6a, 0x7f, 0x86, 0xd6, 0x56, 0xf6, 0xba,
- 0xf5, 0xb5, 0x4d, 0xf6, 0x67, 0x74, 0x6d, 0xc5, 0xa7, 0xb4, 0xb5, 0x9a,
- 0xfd, 0x19, 0x5f, 0x5b, 0xc9, 0xcb, 0x2d, 0x6b, 0x97, 0x5e, 0x7d, 0xbf,
- 0x86, 0xff, 0xfe, 0x17, 0x9f, 0xed, 0x4e, 0xb2, 0x20, 0x3b, 0x00, 0x00,
- 0x00 };
+ 0xc5, 0x7b, 0x7d, 0x70, 0x1b, 0xe7, 0x79, 0xe7, 0xef, 0xc5, 0x02, 0xe4,
+ 0x02, 0x04, 0x41, 0x90, 0x82, 0x64, 0xf0, 0xca, 0x44, 0x58, 0x61, 0x41,
+ 0xc1, 0x26, 0x2d, 0x2f, 0x28, 0x50, 0x82, 0xcb, 0x55, 0x85, 0x4a, 0xb4,
+ 0x44, 0xc7, 0x74, 0x43, 0x3b, 0x6a, 0x4b, 0x67, 0x3c, 0x09, 0x2a, 0x51,
+ 0x16, 0x2d, 0xcb, 0x16, 0xed, 0xf8, 0x7a, 0xec, 0x9c, 0x27, 0xda, 0x50,
+ 0x1f, 0x96, 0x25, 0x10, 0x00, 0x3f, 0x64, 0xca, 0x9d, 0xce, 0x19, 0x26,
+ 0x29, 0x51, 0xb6, 0xf1, 0x21, 0xc7, 0x4a, 0x6a, 0xcf, 0x24, 0x11, 0x4e,
+ 0x96, 0x65, 0xd9, 0x89, 0x3f, 0x92, 0xf8, 0x7a, 0x4e, 0xa7, 0x37, 0xd5,
+ 0x48, 0xfe, 0x90, 0x2c, 0xf9, 0xa3, 0x69, 0x6f, 0x2a, 0xb5, 0x4e, 0xf7,
+ 0x9e, 0x67, 0x17, 0x94, 0x15, 0xd7, 0x9d, 0x9b, 0xf6, 0xfe, 0x38, 0xce,
+ 0x70, 0x00, 0xec, 0xbe, 0xfb, 0xbe, 0xcf, 0xf7, 0xf3, 0x7b, 0x9e, 0xf7,
+ 0xdd, 0x56, 0xc0, 0x83, 0xea, 0x5f, 0x3d, 0xfd, 0xc7, 0x87, 0x86, 0x1f,
+ 0x8e, 0x2d, 0x5b, 0xb1, 0x8c, 0xbe, 0x76, 0xa2, 0xa1, 0xc6, 0xc9, 0x37,
+ 0x57, 0x08, 0x20, 0xf5, 0x21, 0xfe, 0x43, 0x7f, 0x5f, 0xf9, 0x8f, 0x3d,
+ 0x66, 0xfd, 0x49, 0x80, 0x7f, 0x9e, 0x2e, 0xfe, 0x87, 0xec, 0xd0, 0x93,
+ 0x5d, 0x6b, 0x54, 0xc8, 0x92, 0x7e, 0x79, 0xd5, 0x26, 0x15, 0x48, 0x16,
+ 0xda, 0x42, 0x6b, 0xf1, 0x1b, 0xd3, 0x08, 0x38, 0xc1, 0xd7, 0xbf, 0xa2,
+ 0x7f, 0xb6, 0xe3, 0xc7, 0x2b, 0x95, 0x4f, 0xf3, 0x12, 0x64, 0xbf, 0x7e,
+ 0x10, 0xfe, 0x56, 0xc8, 0x2d, 0xf4, 0xcc, 0x5f, 0x2c, 0x2d, 0x39, 0xe1,
+ 0x9b, 0x9f, 0x0b, 0x86, 0x4b, 0xd7, 0xb0, 0x33, 0x3b, 0x84, 0x23, 0x71,
+ 0xa0, 0x76, 0x34, 0xa2, 0xed, 0x04, 0x72, 0x0e, 0x3d, 0x12, 0x3a, 0x81,
+ 0x10, 0x66, 0x0b, 0x2a, 0x1e, 0x2d, 0xc3, 0x70, 0xea, 0x21, 0x3c, 0x96,
+ 0xfe, 0x17, 0x33, 0xe4, 0xe2, 0x47, 0x86, 0xb0, 0x8b, 0xc6, 0xee, 0x4e,
+ 0x43, 0x0e, 0xea, 0x8f, 0x20, 0x98, 0x85, 0x5c, 0xaf, 0x0f, 0xa3, 0x38,
+ 0x1a, 0x3e, 0x3d, 0x07, 0xa5, 0xaf, 0x59, 0x52, 0x86, 0x80, 0xb6, 0xd4,
+ 0x5d, 0x42, 0xe9, 0x2f, 0x09, 0x25, 0xb1, 0x4d, 0x40, 0x16, 0x34, 0xee,
+ 0x86, 0x02, 0x7f, 0x0e, 0x63, 0x69, 0x41, 0xc6, 0x19, 0x89, 0xe7, 0x59,
+ 0x45, 0xf2, 0x16, 0x70, 0xaa, 0x1a, 0x76, 0x67, 0x79, 0x0d, 0x81, 0x9d,
+ 0xf1, 0x88, 0x7f, 0x06, 0x7c, 0x3f, 0x84, 0x11, 0x6b, 0x9c, 0x42, 0x5c,
+ 0x9b, 0xe6, 0x2e, 0xcd, 0x34, 0x0f, 0x69, 0xb5, 0x30, 0xfc, 0x4a, 0x10,
+ 0x10, 0x18, 0xd1, 0x1c, 0x48, 0xfa, 0xd7, 0x84, 0x9c, 0x50, 0x82, 0x9b,
+ 0xf1, 0xcf, 0xc4, 0x73, 0x32, 0xea, 0x82, 0x3d, 0x3e, 0x85, 0x5a, 0x54,
+ 0xfc, 0xb6, 0xd4, 0xa6, 0xd3, 0xa6, 0x79, 0x4a, 0x75, 0xe2, 0x10, 0xc9,
+ 0x67, 0xa4, 0xf0, 0xcf, 0x66, 0x85, 0x64, 0xb3, 0x4b, 0x9d, 0x5f, 0x5f,
+ 0x46, 0xde, 0x6f, 0x9a, 0x33, 0x74, 0x6f, 0x4f, 0x61, 0x5e, 0xce, 0xa6,
+ 0xe9, 0x50, 0x4d, 0x73, 0x93, 0xfa, 0x4f, 0xe6, 0xc6, 0xdf, 0x1a, 0x1b,
+ 0xc3, 0x33, 0x39, 0x3f, 0x9e, 0xcd, 0x26, 0x51, 0x48, 0x9b, 0x90, 0x74,
+ 0x27, 0x06, 0x47, 0x43, 0xd8, 0x56, 0xec, 0x46, 0x31, 0xad, 0xa4, 0xce,
+ 0xd0, 0x73, 0x1b, 0xe3, 0x2a, 0xee, 0x2f, 0xf6, 0x60, 0x2e, 0x0d, 0xd3,
+ 0xad, 0xab, 0x15, 0xb7, 0x88, 0x62, 0x4b, 0xb1, 0x17, 0xa5, 0xb4, 0x7a,
+ 0x7a, 0x44, 0x44, 0x86, 0x9b, 0x25, 0x27, 0xb6, 0x17, 0xdb, 0xf1, 0x40,
+ 0x31, 0x41, 0xcf, 0x98, 0xf8, 0x5a, 0xac, 0x85, 0xc6, 0x77, 0xe0, 0xe9,
+ 0x49, 0xd3, 0x8c, 0xc6, 0xfc, 0x18, 0x2c, 0x6a, 0x98, 0xcb, 0x39, 0x90,
+ 0x3a, 0xe4, 0x44, 0xea, 0x29, 0x60, 0xcb, 0x53, 0x1d, 0x98, 0xc9, 0x99,
+ 0xd8, 0xa8, 0x8d, 0x34, 0x3b, 0xe0, 0x42, 0xca, 0x2f, 0xe0, 0x52, 0x7d,
+ 0xd8, 0xec, 0xb7, 0x69, 0x3f, 0x23, 0x09, 0x6c, 0x7d, 0x2a, 0x8a, 0x77,
+ 0xd2, 0x06, 0xbe, 0xd6, 0x19, 0xc4, 0x70, 0x31, 0x80, 0x37, 0xd3, 0x01,
+ 0x5a, 0x43, 0xc3, 0x1b, 0x69, 0x99, 0xd6, 0x69, 0xc7, 0xc9, 0x34, 0x8f,
+ 0xe1, 0xb1, 0x5e, 0x0c, 0x14, 0x5b, 0xf0, 0x7a, 0x3a, 0x48, 0x6b, 0x06,
+ 0xf0, 0x2a, 0x8d, 0xbb, 0xb7, 0xa8, 0xe2, 0x34, 0x8d, 0x1b, 0x2c, 0x86,
+ 0xf0, 0x4a, 0xda, 0x4b, 0xb4, 0x06, 0x70, 0x22, 0x3d, 0x84, 0x9d, 0xe9,
+ 0xb6, 0xd3, 0x6b, 0x49, 0x86, 0xa1, 0x05, 0xbc, 0x0e, 0x5f, 0x7b, 0xd7,
+ 0xec, 0x0d, 0x58, 0xa6, 0x42, 0xeb, 0xcc, 0xaf, 0x3b, 0x84, 0x91, 0xf4,
+ 0xa9, 0xaa, 0xbf, 0x68, 0x78, 0x2c, 0x77, 0xd9, 0xfc, 0xf1, 0xd2, 0x16,
+ 0x1c, 0xc9, 0x02, 0x4f, 0xcf, 0x00, 0x33, 0x59, 0xc3, 0xac, 0xd7, 0x4d,
+ 0x73, 0xba, 0xb3, 0x9d, 0xe4, 0xa5, 0xf6, 0x6f, 0xa4, 0x51, 0xcf, 0x96,
+ 0x9d, 0xc0, 0x53, 0x4a, 0x7f, 0x05, 0x0e, 0xe4, 0xe7, 0x9c, 0xa8, 0x19,
+ 0x55, 0x7a, 0xf2, 0x50, 0x4e, 0x6f, 0x21, 0x8f, 0x3a, 0x94, 0x55, 0xfa,
+ 0x0c, 0xec, 0x30, 0x83, 0x7a, 0x6b, 0xa8, 0x5d, 0x32, 0xe1, 0x23, 0x5b,
+ 0x48, 0xb7, 0x9b, 0x66, 0xc3, 0x4a, 0xd3, 0x7c, 0xbd, 0x13, 0xa6, 0x43,
+ 0x57, 0x4f, 0x97, 0xa1, 0x56, 0x3e, 0x82, 0x3a, 0x7c, 0x02, 0x95, 0xaf,
+ 0x78, 0x11, 0x19, 0x0c, 0x4b, 0x91, 0xa1, 0xcb, 0xf4, 0x6c, 0x7d, 0x91,
+ 0xcc, 0x99, 0x78, 0x51, 0x47, 0x81, 0x62, 0x59, 0x86, 0x93, 0xf8, 0x69,
+ 0x1f, 0x35, 0x4d, 0xa7, 0xea, 0x85, 0x97, 0xe4, 0xbb, 0xfe, 0x80, 0x69,
+ 0xbe, 0xaf, 0xf9, 0x51, 0x43, 0xba, 0xb9, 0x65, 0xcc, 0xc4, 0xb4, 0x76,
+ 0x82, 0xe4, 0x29, 0x90, 0xea, 0x8b, 0xd3, 0x33, 0x01, 0x1a, 0x9f, 0xc0,
+ 0xfa, 0xd1, 0x20, 0x9e, 0xc9, 0xca, 0xf8, 0xf1, 0xd2, 0x28, 0xea, 0x68,
+ 0x2e, 0x0f, 0xc9, 0xaa, 0x96, 0xe4, 0x87, 0x22, 0x99, 0x5b, 0xd1, 0xb6,
+ 0x47, 0x14, 0xcf, 0x10, 0x8f, 0x41, 0x7c, 0xbf, 0x1c, 0xc0, 0x73, 0x65,
+ 0x3f, 0x8e, 0x96, 0x5b, 0x70, 0xbc, 0xac, 0xe1, 0x60, 0x4e, 0xd9, 0x5b,
+ 0x81, 0x89, 0x7a, 0x7d, 0x07, 0x1a, 0x96, 0x03, 0x6f, 0xe6, 0x63, 0xc8,
+ 0xe4, 0x4c, 0xb3, 0x40, 0x74, 0x7b, 0x88, 0x8f, 0x37, 0xf2, 0x5f, 0xc5,
+ 0xe1, 0x49, 0x27, 0x42, 0xd3, 0x01, 0x3c, 0x9b, 0x76, 0xe2, 0xfa, 0x8c,
+ 0x62, 0xe4, 0xa1, 0x46, 0xb7, 0x09, 0x35, 0x79, 0x83, 0x50, 0x72, 0x06,
+ 0x22, 0x21, 0x97, 0x70, 0xa0, 0xf5, 0xb0, 0x13, 0x6a, 0x29, 0x04, 0x57,
+ 0xab, 0x0c, 0xb5, 0xf5, 0x21, 0xc0, 0xe7, 0x40, 0x0d, 0xf9, 0xc6, 0xfa,
+ 0xf1, 0x28, 0x5d, 0x0b, 0xd0, 0x35, 0x7c, 0xb5, 0x16, 0xd2, 0x22, 0x09,
+ 0x24, 0x3b, 0x55, 0x42, 0xd2, 0x69, 0x9a, 0x92, 0xda, 0x81, 0xbb, 0x1e,
+ 0x37, 0xcd, 0xf0, 0x72, 0x1e, 0xef, 0x47, 0xb8, 0x44, 0x72, 0x68, 0x25,
+ 0xba, 0xb2, 0x44, 0x67, 0x96, 0xe8, 0xcc, 0x12, 0x9d, 0x59, 0x89, 0xec,
+ 0x46, 0xd1, 0x80, 0x47, 0x48, 0x5f, 0x21, 0xe2, 0xf1, 0x1d, 0x4b, 0x57,
+ 0xcf, 0x95, 0x83, 0xc4, 0x43, 0xc8, 0xe2, 0xe1, 0xe9, 0x9c, 0x80, 0x43,
+ 0x55, 0xfa, 0xce, 0x60, 0x35, 0xc2, 0x31, 0x25, 0x99, 0x47, 0x92, 0x9e,
+ 0x53, 0xf6, 0x1a, 0x50, 0x7a, 0x2a, 0x64, 0x03, 0x1b, 0xfd, 0x09, 0xcc,
+ 0x65, 0x5d, 0xa8, 0x53, 0x95, 0x10, 0xe9, 0x2c, 0x5a, 0xc1, 0x02, 0xdc,
+ 0xe7, 0xa7, 0x39, 0x1d, 0xb2, 0xb0, 0x63, 0xc9, 0x23, 0x88, 0x8c, 0x3b,
+ 0x30, 0xab, 0x49, 0xe4, 0xa3, 0x1a, 0xa4, 0x56, 0x5a, 0xae, 0x14, 0xa7,
+ 0x4f, 0x9a, 0x3f, 0x4b, 0x6b, 0x11, 0x3d, 0x34, 0x1f, 0xf9, 0x26, 0xcb,
+ 0x32, 0x4a, 0x34, 0x3c, 0x6a, 0xd1, 0x7b, 0xb4, 0xfc, 0x75, 0x61, 0xdb,
+ 0x90, 0x4e, 0x36, 0xa3, 0x84, 0x20, 0x94, 0x68, 0x48, 0x28, 0x5a, 0x52,
+ 0xf8, 0x31, 0x53, 0x7e, 0x83, 0xc6, 0x04, 0xae, 0x19, 0xd3, 0x87, 0x91,
+ 0xac, 0xc0, 0x5a, 0xd5, 0xc4, 0x1a, 0xad, 0x0f, 0x3b, 0xcb, 0xf3, 0xbe,
+ 0xc9, 0x31, 0xcc, 0xef, 0x9b, 0x49, 0x77, 0x63, 0x57, 0x36, 0x84, 0x9d,
+ 0x85, 0xa0, 0x6f, 0x3a, 0xcd, 0xf7, 0x54, 0xf2, 0x79, 0xbe, 0x17, 0xb8,
+ 0xe6, 0x5e, 0xcb, 0x35, 0xf7, 0x12, 0x18, 0x99, 0xf8, 0x1d, 0x8a, 0x23,
+ 0x0d, 0xd8, 0xa9, 0x7e, 0x4a, 0xf6, 0xa2, 0x26, 0x06, 0xd0, 0x8c, 0x33,
+ 0xfe, 0x76, 0xec, 0x9f, 0xea, 0xc5, 0xae, 0xa9, 0x65, 0x78, 0x6c, 0xa2,
+ 0x25, 0xe5, 0xd1, 0x49, 0x38, 0x9e, 0x70, 0x72, 0x40, 0x28, 0x43, 0x92,
+ 0x08, 0x47, 0x07, 0xc8, 0x7e, 0x5b, 0x1b, 0x4d, 0xf3, 0x44, 0x8c, 0xec,
+ 0x5b, 0x6b, 0xd3, 0xd6, 0x93, 0x00, 0x2a, 0x7d, 0x4a, 0xcf, 0xbb, 0xf0,
+ 0xe2, 0x76, 0xb2, 0xbb, 0x99, 0x18, 0x06, 0x24, 0x48, 0xed, 0x5e, 0xfc,
+ 0xbd, 0xf9, 0x94, 0x93, 0xe5, 0x6e, 0xee, 0xd8, 0xa4, 0xed, 0x15, 0x1c,
+ 0xeb, 0x6a, 0xae, 0xc6, 0x13, 0x9e, 0x9f, 0x9f, 0x21, 0xdd, 0xd1, 0x3c,
+ 0x83, 0xb1, 0xb6, 0xc4, 0x20, 0x2e, 0x9b, 0x67, 0x36, 0xf4, 0x62, 0xe7,
+ 0xdc, 0x32, 0xec, 0x9b, 0x70, 0x21, 0xd9, 0x28, 0xd0, 0xa0, 0x86, 0x2b,
+ 0xf7, 0x61, 0x19, 0x8c, 0x19, 0x7e, 0xae, 0x17, 0x07, 0xe7, 0xec, 0xdf,
+ 0xd9, 0xab, 0xbf, 0xe7, 0xe7, 0x3b, 0x4f, 0x3a, 0x65, 0x79, 0x72, 0xac,
+ 0x24, 0x15, 0xe8, 0x6d, 0x38, 0x32, 0x11, 0x20, 0xdd, 0x76, 0x0b, 0xe7,
+ 0xe1, 0x45, 0x3e, 0xcf, 0xe3, 0x26, 0x4e, 0x69, 0xa4, 0xe7, 0xec, 0x3a,
+ 0xe1, 0x39, 0xdc, 0x23, 0x5c, 0xa5, 0x3b, 0x45, 0xcd, 0xf4, 0x37, 0x85,
+ 0x7c, 0x38, 0x25, 0x6a, 0x4b, 0xed, 0x24, 0xfb, 0x7e, 0xe1, 0x3e, 0xac,
+ 0x84, 0x42, 0xe2, 0x11, 0xd2, 0xe7, 0x06, 0x21, 0x95, 0xe0, 0x77, 0xe8,
+ 0xc3, 0xc2, 0x51, 0xa2, 0x39, 0x2c, 0x1b, 0xe2, 0x75, 0x82, 0xa4, 0x37,
+ 0x18, 0x92, 0x3e, 0x84, 0x8d, 0x14, 0xff, 0x6f, 0x4d, 0xeb, 0x78, 0x34,
+ 0x5b, 0x4b, 0x31, 0x92, 0x7d, 0xff, 0x32, 0xad, 0xab, 0xe2, 0x31, 0xca,
+ 0x15, 0xb2, 0xbe, 0x0f, 0x3e, 0xf2, 0xb9, 0xd7, 0x63, 0xec, 0x8f, 0x40,
+ 0x21, 0x1b, 0xee, 0x7f, 0x54, 0x98, 0xe6, 0xd6, 0x88, 0xb9, 0x78, 0x5d,
+ 0xac, 0x2d, 0x7a, 0x12, 0xff, 0x68, 0xe6, 0x03, 0x43, 0xa8, 0xef, 0xa4,
+ 0x7b, 0xa3, 0x90, 0x5d, 0xfa, 0x2e, 0x1c, 0xa2, 0x5c, 0xe2, 0xd1, 0x29,
+ 0xbe, 0x8c, 0x86, 0xfb, 0x1f, 0x13, 0x1c, 0xf3, 0x95, 0xca, 0xb3, 0x18,
+ 0x39, 0x5d, 0x0b, 0x25, 0xb4, 0x46, 0xb4, 0x69, 0x75, 0x92, 0x91, 0x68,
+ 0xa6, 0x14, 0xe7, 0xee, 0x54, 0x86, 0xf7, 0x40, 0xf1, 0x5f, 0x00, 0xfb,
+ 0x2a, 0xe7, 0x93, 0x5d, 0x48, 0x58, 0x79, 0xc5, 0xc0, 0x4d, 0x57, 0xf3,
+ 0x8a, 0x4e, 0x76, 0x52, 0x8b, 0x3d, 0x44, 0xd7, 0xcb, 0x9a, 0x12, 0x9c,
+ 0x86, 0xb9, 0x78, 0x40, 0xe3, 0x7b, 0x3a, 0x76, 0x95, 0xcd, 0x90, 0xa4,
+ 0xb3, 0xac, 0x90, 0xaa, 0xd5, 0x99, 0x56, 0x3f, 0xf9, 0xc6, 0x6f, 0xcc,
+ 0x81, 0xb8, 0xac, 0xbd, 0x57, 0xf0, 0x93, 0xbc, 0xe0, 0x73, 0x16, 0xbf,
+ 0x2c, 0xff, 0x9a, 0x70, 0xe8, 0xbf, 0x31, 0xbf, 0x1d, 0x87, 0x6f, 0x71,
+ 0xd1, 0x99, 0xaa, 0xd3, 0xd1, 0x37, 0x3c, 0xba, 0xc3, 0x6c, 0x56, 0x1d,
+ 0x14, 0xab, 0x54, 0x8a, 0xed, 0xde, 0xc4, 0xa5, 0x4e, 0xb7, 0x78, 0xbd,
+ 0x33, 0xd8, 0xfb, 0x51, 0xc1, 0x4d, 0x7a, 0x46, 0xdf, 0xb6, 0x62, 0xc2,
+ 0xf9, 0x21, 0xd9, 0x5a, 0x0d, 0xc5, 0x55, 0x14, 0x5b, 0x7a, 0x2f, 0x50,
+ 0x2e, 0xba, 0x25, 0xe6, 0xfe, 0xe3, 0x1a, 0xdd, 0xf1, 0x55, 0x37, 0x1e,
+ 0xbc, 0x69, 0x36, 0xd1, 0x40, 0xb1, 0xdd, 0x8f, 0xd3, 0xf1, 0x1e, 0x8c,
+ 0x94, 0x6b, 0xc9, 0x0e, 0x9f, 0xaf, 0xec, 0x56, 0x5b, 0x7a, 0x2f, 0xa6,
+ 0x17, 0x53, 0x2c, 0xc1, 0x67, 0x85, 0x4e, 0xb5, 0x6f, 0x9b, 0x38, 0x71,
+ 0xab, 0x07, 0x71, 0x92, 0xab, 0x2c, 0x5f, 0x49, 0xe3, 0xd3, 0xc5, 0xaa,
+ 0x5a, 0x59, 0x2d, 0xb5, 0x0e, 0xc9, 0x52, 0xeb, 0x70, 0x0d, 0xc5, 0xe1,
+ 0xf3, 0x37, 0x0a, 0x9c, 0xba, 0x31, 0x92, 0xa8, 0x11, 0x6e, 0x9c, 0xe9,
+ 0x4b, 0x90, 0x9d, 0xb4, 0xa4, 0xdc, 0x3a, 0xc5, 0x8f, 0x51, 0x01, 0x49,
+ 0x4d, 0x60, 0xe7, 0x0c, 0x1e, 0x19, 0xd1, 0x7a, 0x61, 0xcc, 0xb1, 0x0d,
+ 0xb5, 0x63, 0x64, 0xae, 0x0f, 0x46, 0x59, 0x42, 0x3e, 0x40, 0xcc, 0x97,
+ 0x91, 0x72, 0xe9, 0xed, 0xdd, 0xf9, 0xc2, 0x5d, 0x2e, 0xdb, 0x87, 0x89,
+ 0xff, 0xec, 0xa4, 0x0f, 0x1e, 0xd6, 0xf3, 0x69, 0x92, 0x51, 0x3b, 0x9e,
+ 0x2f, 0x47, 0x29, 0xde, 0x69, 0x24, 0x17, 0x95, 0xe2, 0x45, 0x88, 0xec,
+ 0x4b, 0xc6, 0xc6, 0x09, 0xe5, 0x20, 0xc5, 0x85, 0x5c, 0x9e, 0x40, 0x51,
+ 0x32, 0xe0, 0xa7, 0xfc, 0xfd, 0x6a, 0x35, 0x06, 0x0c, 0xd2, 0xa7, 0x62,
+ 0x24, 0x81, 0x93, 0x0e, 0xa0, 0xa3, 0x59, 0x8f, 0xec, 0x6d, 0x26, 0x7d,
+ 0x34, 0x96, 0xdc, 0xd8, 0x3e, 0xd1, 0x84, 0x07, 0xa6, 0x3c, 0xd8, 0x3a,
+ 0x61, 0xe2, 0x52, 0x8c, 0x6d, 0x43, 0xe9, 0x27, 0x12, 0xbb, 0xeb, 0x48,
+ 0xae, 0xb7, 0xc6, 0x22, 0x09, 0xb7, 0x70, 0xa2, 0xb6, 0xd4, 0x47, 0x38,
+ 0x20, 0xc9, 0x7e, 0xa1, 0xd1, 0x1c, 0xa1, 0x9d, 0xda, 0xed, 0x48, 0x05,
+ 0x64, 0xb8, 0x4a, 0x5e, 0x8a, 0x25, 0xec, 0xc7, 0x7c, 0xef, 0xeb, 0xd8,
+ 0x58, 0xe3, 0x85, 0x94, 0x91, 0x91, 0x23, 0x0c, 0x80, 0x45, 0x35, 0xe8,
+ 0x69, 0x75, 0xd0, 0x7f, 0xc0, 0x37, 0x3b, 0xd9, 0xe2, 0x3b, 0x44, 0xf1,
+ 0x75, 0x4b, 0xd6, 0xc1, 0xeb, 0x30, 0x66, 0xa0, 0xb9, 0xfd, 0x78, 0x9a,
+ 0xe2, 0xf5, 0x43, 0x14, 0x7f, 0x8e, 0x94, 0xcb, 0x82, 0xe3, 0x89, 0xc5,
+ 0x4f, 0x96, 0x78, 0xcb, 0x12, 0x6f, 0x59, 0xe2, 0x8b, 0xe2, 0xc2, 0xd1,
+ 0x2c, 0xf3, 0xf1, 0x6b, 0xf2, 0xd1, 0x04, 0xf1, 0xee, 0xc6, 0x66, 0xa2,
+ 0xf7, 0xc1, 0xa9, 0x3a, 0x6c, 0x23, 0x7a, 0x8b, 0x9a, 0xa2, 0x3d, 0x27,
+ 0x4c, 0xec, 0x8f, 0x29, 0xc6, 0x4f, 0x29, 0x10, 0x39, 0x5a, 0x4d, 0xb3,
+ 0x4f, 0x63, 0x9e, 0x29, 0x5e, 0x39, 0x2c, 0x9e, 0xf7, 0x26, 0xe1, 0xc6,
+ 0x20, 0x3d, 0x33, 0x30, 0x85, 0xcf, 0x1c, 0xc4, 0x93, 0x9b, 0x78, 0xdc,
+ 0xa7, 0x29, 0x89, 0x1b, 0x28, 0xae, 0x9f, 0x53, 0x23, 0x95, 0x73, 0x12,
+ 0x7e, 0x9f, 0xe4, 0x31, 0xcc, 0xf2, 0xb8, 0x89, 0xf8, 0x79, 0x80, 0xf0,
+ 0x4e, 0x3d, 0xc5, 0xa5, 0xc2, 0x81, 0x48, 0xf4, 0x97, 0xc4, 0x7b, 0xa4,
+ 0x44, 0xb4, 0x8f, 0xda, 0xb4, 0xdf, 0xc7, 0xb4, 0xc7, 0x4c, 0xdc, 0x43,
+ 0xb4, 0x1f, 0x26, 0xda, 0x07, 0xb3, 0x2c, 0x0f, 0xce, 0x3b, 0x36, 0xfd,
+ 0x47, 0xca, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x13, 0x36, 0x4e,
+ 0xcd, 0xcb, 0xcb, 0x34, 0xbf, 0xad, 0x1d, 0x33, 0xff, 0x84, 0x64, 0xb6,
+ 0xb8, 0xc4, 0x72, 0x83, 0x51, 0xab, 0x47, 0x0e, 0x6e, 0xc1, 0x7d, 0x0e,
+ 0x78, 0xbc, 0x58, 0x50, 0xe2, 0x5c, 0x10, 0xc2, 0x31, 0xd2, 0xef, 0x71,
+ 0xca, 0x67, 0xcf, 0x97, 0xaf, 0xcd, 0x6f, 0xac, 0xeb, 0x49, 0xd2, 0xb1,
+ 0x92, 0x37, 0x28, 0xb6, 0xa5, 0xca, 0x49, 0xec, 0x9e, 0x42, 0x72, 0x56,
+ 0xfb, 0x6f, 0x14, 0x60, 0x16, 0x91, 0x7d, 0xd5, 0x26, 0xfd, 0xaa, 0x07,
+ 0x9b, 0x66, 0x02, 0x18, 0x2a, 0xaf, 0x41, 0x96, 0xe2, 0xcd, 0x36, 0x8a,
+ 0xcf, 0x1f, 0xc7, 0x92, 0x5b, 0x7d, 0x88, 0x90, 0x7e, 0x03, 0xb8, 0x8f,
+ 0x9e, 0xd9, 0x37, 0xc5, 0x3c, 0xf8, 0xab, 0x7a, 0x0e, 0x60, 0x0b, 0x5d,
+ 0xdb, 0x33, 0x25, 0xe3, 0x25, 0xed, 0x49, 0xc2, 0x34, 0x36, 0xc6, 0xb8,
+ 0x27, 0x0b, 0x3f, 0xb9, 0x27, 0x61, 0xc0, 0x48, 0xf4, 0x25, 0xfa, 0xbd,
+ 0xb9, 0xec, 0xf1, 0x8d, 0x4c, 0xe2, 0x7b, 0x8b, 0x75, 0x1f, 0x16, 0x10,
+ 0x1e, 0xbb, 0x4b, 0x8b, 0x90, 0xdd, 0x3b, 0x31, 0x5c, 0x76, 0xe0, 0x3b,
+ 0x33, 0x1e, 0x3c, 0x34, 0xf1, 0x99, 0x59, 0x13, 0x77, 0xe2, 0x8e, 0x56,
+ 0x0f, 0x1e, 0x9c, 0x49, 0x62, 0xef, 0x14, 0x42, 0xb5, 0xb1, 0x31, 0x8a,
+ 0xdd, 0x76, 0x3e, 0xa8, 0x23, 0xde, 0x1f, 0x9b, 0xf2, 0xfa, 0x06, 0x0f,
+ 0xb0, 0x0c, 0xd6, 0x04, 0xdd, 0x40, 0xa5, 0x36, 0x26, 0x61, 0xb3, 0x26,
+ 0x2d, 0xa8, 0x25, 0x43, 0x7f, 0x92, 0xe6, 0x9b, 0x86, 0xf4, 0xda, 0x62,
+ 0x44, 0x0e, 0x36, 0x4b, 0x95, 0xdc, 0x02, 0x34, 0xe1, 0xa1, 0xb9, 0x24,
+ 0xc6, 0xc8, 0x46, 0xb7, 0x4f, 0x8c, 0x7c, 0xaf, 0x91, 0x62, 0x88, 0xaf,
+ 0x43, 0x19, 0x7c, 0x53, 0xe8, 0x28, 0x44, 0xdc, 0xd8, 0x36, 0xe3, 0xf5,
+ 0x6d, 0x3d, 0x60, 0xae, 0x66, 0x7b, 0xba, 0x77, 0xae, 0x09, 0xf7, 0x4f,
+ 0xd1, 0xb5, 0x09, 0xb6, 0x61, 0xb2, 0xb5, 0x48, 0x2d, 0xf1, 0x16, 0x4e,
+ 0xba, 0x09, 0x33, 0x49, 0xb1, 0x3a, 0x92, 0x87, 0x1b, 0x5b, 0x2c, 0x5b,
+ 0xf0, 0x63, 0xf3, 0x94, 0x89, 0xb3, 0x5a, 0x14, 0x39, 0xb2, 0xeb, 0x83,
+ 0x53, 0xca, 0xe5, 0x6e, 0xc2, 0x3b, 0xef, 0x49, 0xca, 0xc1, 0x56, 0x29,
+ 0x89, 0xa6, 0xe5, 0x14, 0xe3, 0x9b, 0x4c, 0xf3, 0x9e, 0x8e, 0xb6, 0xa1,
+ 0xb7, 0x88, 0xe6, 0x46, 0x7d, 0x11, 0x2a, 0x8d, 0x4a, 0x8e, 0xb0, 0xf3,
+ 0x70, 0x8d, 0xe3, 0x46, 0x9c, 0x59, 0x48, 0x7a, 0x06, 0xc7, 0xf2, 0x80,
+ 0xaf, 0x29, 0x63, 0xe7, 0xb8, 0x26, 0xb2, 0x93, 0xc6, 0x4c, 0xd0, 0xd7,
+ 0x58, 0x82, 0xaf, 0xa6, 0x04, 0xbc, 0x40, 0xf1, 0x65, 0xc1, 0xf2, 0xdf,
+ 0x98, 0xa9, 0x26, 0x0b, 0x13, 0xfa, 0x5e, 0x9c, 0x54, 0x8c, 0x0a, 0x94,
+ 0xbd, 0x14, 0x2a, 0xf1, 0xc4, 0x9c, 0xd3, 0x77, 0x98, 0xf0, 0x5f, 0x93,
+ 0x1a, 0xc5, 0x1e, 0xd2, 0xe7, 0x0e, 0xb2, 0x85, 0xbf, 0x27, 0x7c, 0xf2,
+ 0x58, 0x26, 0x1c, 0xd2, 0x44, 0x3f, 0x4d, 0x0c, 0xec, 0x2a, 0x51, 0xcc,
+ 0x77, 0xac, 0xa5, 0x20, 0xa6, 0x44, 0x29, 0xad, 0x21, 0x9d, 0x71, 0xc1,
+ 0x58, 0x68, 0xeb, 0xe4, 0xfe, 0xec, 0x71, 0xd3, 0xa7, 0xaa, 0xf9, 0x12,
+ 0xe9, 0xec, 0xe1, 0xb2, 0x17, 0xc3, 0x84, 0x07, 0x16, 0x10, 0x8e, 0x7c,
+ 0x90, 0xec, 0x62, 0xfb, 0x84, 0x44, 0xf4, 0xf1, 0xb8, 0x24, 0x92, 0x8b,
+ 0x6c, 0x3c, 0xfa, 0xd0, 0x0c, 0xdb, 0x25, 0xd9, 0x11, 0xd9, 0xe2, 0x31,
+ 0xca, 0xf9, 0xcf, 0xff, 0x16, 0x06, 0x51, 0xfc, 0xc6, 0xd5, 0xdc, 0x6f,
+ 0xcb, 0x63, 0x64, 0x8a, 0x79, 0x56, 0x0e, 0xc2, 0x91, 0xc4, 0x2d, 0xda,
+ 0xaf, 0x28, 0x27, 0x30, 0xef, 0x84, 0x83, 0xa7, 0xa2, 0x94, 0x57, 0x08,
+ 0xdb, 0xc4, 0x2e, 0x99, 0x5b, 0x02, 0x2c, 0x03, 0xe6, 0xe7, 0x66, 0x89,
+ 0xf3, 0x67, 0x13, 0xe1, 0xdf, 0xff, 0x77, 0xbb, 0xdb, 0x64, 0xa6, 0x2c,
+ 0x3c, 0x4b, 0x38, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0x34, 0xcf,
+ 0x04, 0x38, 0x5f, 0x37, 0x21, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x58,
+ 0xeb, 0xd8, 0xf9, 0xa0, 0x1f, 0x6c, 0x0f, 0xd1, 0x6b, 0xec, 0xc1, 0x43,
+ 0x34, 0xf9, 0xb1, 0x75, 0x8e, 0xed, 0xd7, 0xfc, 0x64, 0xb1, 0xfe, 0x2f,
+ 0xe6, 0x95, 0x95, 0xea, 0xc1, 0x5f, 0xe1, 0xeb, 0x74, 0x3d, 0x80, 0xef,
+ 0x90, 0x1f, 0xdd, 0x47, 0x7c, 0x6e, 0xed, 0x7c, 0xc0, 0xf2, 0xdb, 0xad,
+ 0xe5, 0xdf, 0xa3, 0xeb, 0x2c, 0xef, 0x6e, 0x8a, 0x73, 0x1a, 0xf6, 0x65,
+ 0x2b, 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x4b, 0x8a, 0xb3, 0xc7, 0xca,
+ 0x8c, 0xc9, 0x12, 0x16, 0x1e, 0xfb, 0x61, 0xb9, 0x1d, 0x3f, 0x20, 0x9f,
+ 0x7c, 0x9e, 0x62, 0xee, 0xf7, 0x2d, 0x9c, 0xe6, 0x14, 0x8f, 0xa6, 0x55,
+ 0x3c, 0x4d, 0x58, 0x7f, 0x5f, 0x21, 0x84, 0x23, 0xe9, 0xf0, 0xde, 0x0b,
+ 0x50, 0x5e, 0x20, 0x79, 0xf9, 0xf6, 0x52, 0x8d, 0x76, 0x38, 0xad, 0xe4,
+ 0x81, 0xa0, 0x6f, 0x4f, 0xc1, 0xef, 0x1b, 0x49, 0x07, 0x7c, 0x23, 0x84,
+ 0x81, 0x76, 0xa6, 0x5b, 0x7c, 0x3b, 0x0b, 0xcb, 0x11, 0x6a, 0x82, 0xb1,
+ 0x88, 0x72, 0xc2, 0x7d, 0x13, 0x1b, 0x90, 0x6a, 0xb4, 0xe3, 0xfc, 0x03,
+ 0x53, 0x1c, 0x83, 0xdb, 0x52, 0x37, 0x3a, 0xbe, 0x5e, 0xd5, 0xb7, 0x1f,
+ 0x43, 0x74, 0xad, 0xa1, 0x03, 0xbe, 0x37, 0xad, 0x58, 0x0b, 0x3c, 0x4f,
+ 0xb6, 0xf5, 0x50, 0xc7, 0x6f, 0xcc, 0x64, 0xd5, 0xb6, 0x7e, 0x30, 0xe9,
+ 0xa4, 0xf8, 0x6a, 0x9a, 0x47, 0x3b, 0x04, 0x02, 0x1d, 0xdd, 0x30, 0x9a,
+ 0xe6, 0x6b, 0xc8, 0x64, 0xbe, 0xb9, 0x83, 0x22, 0x94, 0x7a, 0x0b, 0x12,
+ 0x0b, 0x28, 0xb5, 0x74, 0xac, 0xae, 0xde, 0x93, 0xf1, 0x9d, 0x09, 0x37,
+ 0x52, 0x4d, 0x7e, 0xcc, 0x12, 0x36, 0xd9, 0x68, 0xc5, 0xa2, 0xb6, 0xd3,
+ 0xc7, 0xa9, 0x96, 0x09, 0x7d, 0xc3, 0x4f, 0xbc, 0x26, 0x21, 0x77, 0x10,
+ 0x90, 0xa8, 0xd2, 0xc4, 0xbf, 0x73, 0x73, 0x51, 0xec, 0x2e, 0xff, 0xd8,
+ 0x61, 0xe7, 0x13, 0x25, 0x9f, 0xc4, 0x4f, 0x28, 0x2f, 0xd2, 0xbd, 0xec,
+ 0x9b, 0x66, 0xc8, 0xb2, 0x33, 0x81, 0xc7, 0x97, 0x45, 0xf6, 0xfe, 0x4f,
+ 0xc7, 0x75, 0xc4, 0x17, 0xc9, 0x2a, 0x6b, 0xd5, 0x8e, 0x0d, 0xd7, 0xa9,
+ 0x0f, 0xe2, 0x2f, 0xfd, 0x2c, 0xcb, 0x61, 0x91, 0xa5, 0x3a, 0xf5, 0x8c,
+ 0x0b, 0x0d, 0x41, 0x35, 0x8b, 0x17, 0xfa, 0xf8, 0x5a, 0xc0, 0xf7, 0x44,
+ 0x3a, 0xe9, 0x08, 0xa8, 0xf0, 0xbb, 0xf4, 0x6e, 0xf1, 0x04, 0x61, 0xc0,
+ 0x89, 0x74, 0x8f, 0x98, 0x28, 0xdc, 0x29, 0x8c, 0xfc, 0x37, 0x85, 0x31,
+ 0x9b, 0x12, 0x46, 0xa1, 0x9f, 0x3e, 0x37, 0x88, 0xc9, 0xc2, 0xb0, 0xd8,
+ 0x5d, 0xe0, 0x79, 0x49, 0x27, 0x34, 0xf7, 0x0f, 0x29, 0xc6, 0xfe, 0x80,
+ 0x62, 0xec, 0x31, 0x8a, 0xb1, 0xcf, 0x93, 0x5d, 0x7f, 0xff, 0x2a, 0x96,
+ 0x65, 0x5b, 0x4e, 0x32, 0x06, 0xf1, 0xfd, 0xbc, 0xf4, 0x12, 0xe9, 0x95,
+ 0x65, 0xf6, 0x13, 0xb2, 0x61, 0x96, 0xc5, 0x7f, 0xe6, 0x9c, 0x40, 0xfa,
+ 0xf8, 0xd0, 0xb2, 0xd9, 0xc7, 0x97, 0x31, 0x66, 0x1a, 0x16, 0x3b, 0x98,
+ 0xae, 0x5a, 0xaa, 0xdb, 0x55, 0xc2, 0x21, 0xd9, 0x61, 0xb1, 0xb1, 0xc0,
+ 0xd7, 0xf7, 0xe1, 0x3e, 0xaa, 0xff, 0xb6, 0xc6, 0xc2, 0x89, 0x6e, 0xc2,
+ 0x48, 0x17, 0x54, 0x73, 0x71, 0x34, 0x46, 0x98, 0xe1, 0xc6, 0x2b, 0x54,
+ 0xab, 0x22, 0xb9, 0x2d, 0xae, 0xe4, 0xf3, 0x76, 0x5e, 0xcd, 0xa5, 0xc1,
+ 0x75, 0x3a, 0x1a, 0x9c, 0xaa, 0x72, 0x24, 0x89, 0xf0, 0xde, 0xb8, 0x03,
+ 0x46, 0x8d, 0xee, 0xc2, 0x80, 0x55, 0x17, 0xae, 0x41, 0x66, 0x42, 0xe0,
+ 0x65, 0xf2, 0x01, 0x17, 0xc9, 0xe8, 0x50, 0x27, 0x3e, 0x23, 0xb5, 0x0a,
+ 0xaa, 0xe3, 0x4f, 0x9f, 0xa5, 0x9c, 0x73, 0x17, 0xe5, 0xd6, 0x89, 0xec,
+ 0x0a, 0x04, 0x3b, 0x64, 0x34, 0x74, 0x38, 0xf1, 0x8d, 0xd2, 0xef, 0xe3,
+ 0x4c, 0x63, 0xe4, 0xe0, 0x0b, 0xf0, 0xf8, 0x5e, 0x9a, 0x64, 0x7a, 0xf0,
+ 0xbd, 0x3a, 0xaa, 0xd7, 0xb6, 0x12, 0x4e, 0x1a, 0x27, 0x1a, 0x7a, 0x3a,
+ 0x22, 0x3d, 0xb7, 0x09, 0xf8, 0x6b, 0xf5, 0x1a, 0x8c, 0xb7, 0xfa, 0xe0,
+ 0x57, 0x53, 0xe2, 0xd5, 0x02, 0xe5, 0x0d, 0xc7, 0x37, 0xc5, 0x5b, 0xb3,
+ 0x3a, 0xf6, 0x96, 0xfb, 0xc5, 0x2f, 0x66, 0x65, 0x90, 0x4e, 0x28, 0x3e,
+ 0x69, 0xc8, 0x10, 0x5d, 0x2e, 0xc2, 0x42, 0x2f, 0xdf, 0x21, 0x70, 0x9d,
+ 0x9a, 0xc4, 0x77, 0x56, 0xb0, 0xcd, 0xdb, 0xb1, 0x2b, 0x98, 0x51, 0x42,
+ 0x49, 0x47, 0xb7, 0x08, 0x52, 0xec, 0x6a, 0xc8, 0xf4, 0x88, 0x06, 0xc2,
+ 0x9e, 0x0b, 0xa7, 0x37, 0x88, 0x05, 0x25, 0xc6, 0x9a, 0xf0, 0x2f, 0x24,
+ 0xd9, 0x2c, 0x2c, 0x7d, 0x20, 0xd9, 0x18, 0xdf, 0xc5, 0xb6, 0x43, 0x39,
+ 0x4a, 0xf6, 0xfd, 0x7a, 0x32, 0x89, 0x5b, 0x3b, 0xd6, 0x20, 0x64, 0xd9,
+ 0xc7, 0xb0, 0xd8, 0x47, 0xf2, 0x4b, 0x5a, 0xfd, 0x07, 0xbf, 0xef, 0xc0,
+ 0x24, 0x5c, 0x7e, 0x1d, 0x21, 0x89, 0x72, 0x43, 0xa9, 0x23, 0x32, 0xf8,
+ 0x96, 0xe8, 0x15, 0xa3, 0x85, 0x80, 0x2f, 0x9d, 0x86, 0xbf, 0x8e, 0x74,
+ 0x9c, 0x26, 0x1d, 0xef, 0x21, 0x1d, 0xef, 0xf9, 0x12, 0x1d, 0xef, 0x24,
+ 0x1d, 0xef, 0x2f, 0xfc, 0x9d, 0xa5, 0x33, 0xa7, 0xae, 0x63, 0x94, 0x72,
+ 0xee, 0x78, 0xab, 0xcd, 0x4f, 0x81, 0x30, 0xea, 0x9e, 0x58, 0xaf, 0x13,
+ 0x1e, 0x9d, 0x62, 0x66, 0x2f, 0x3d, 0xd3, 0x5c, 0xb5, 0x65, 0xbf, 0xef,
+ 0xc9, 0x74, 0xb7, 0x78, 0xd2, 0xf2, 0x2b, 0xc6, 0x8d, 0x49, 0x34, 0xaa,
+ 0x3d, 0x34, 0x17, 0xdb, 0xca, 0x9d, 0x02, 0x4f, 0xb1, 0xbd, 0x7c, 0x93,
+ 0x04, 0xcf, 0x36, 0x93, 0x12, 0x28, 0xb2, 0xdd, 0xf4, 0xd3, 0x6f, 0xb6,
+ 0x9d, 0x0d, 0xa2, 0xb1, 0xf8, 0x45, 0xfb, 0x81, 0xdf, 0xa9, 0xb3, 0xfd,
+ 0xb0, 0x1d, 0x0d, 0x0b, 0x67, 0x91, 0x7c, 0x96, 0xe6, 0x1f, 0x21, 0xba,
+ 0x77, 0xa6, 0xf7, 0x3b, 0x99, 0x36, 0x59, 0x67, 0x3b, 0x62, 0xfb, 0xb9,
+ 0x48, 0xb4, 0xb2, 0xcd, 0x5f, 0xed, 0xd9, 0xd0, 0xdf, 0xef, 0x4a, 0x50,
+ 0xb7, 0x38, 0x6d, 0x1e, 0x38, 0x87, 0x73, 0xce, 0xe6, 0x78, 0xea, 0xb7,
+ 0x6a, 0xba, 0x63, 0x57, 0x73, 0x39, 0xe7, 0x75, 0xc8, 0x0b, 0xf4, 0x80,
+ 0xfe, 0x9d, 0xd6, 0x2b, 0x34, 0xdf, 0x10, 0xb4, 0x15, 0x90, 0x03, 0xfa,
+ 0xa4, 0x3e, 0xd9, 0x4a, 0xf1, 0x96, 0xe6, 0x94, 0x33, 0x80, 0x9a, 0x11,
+ 0xd8, 0x99, 0x10, 0x84, 0x47, 0x17, 0x91, 0xbf, 0xc1, 0xf0, 0xe8, 0x4a,
+ 0x4f, 0x92, 0xee, 0x2d, 0x25, 0x7c, 0xbe, 0x58, 0xdf, 0x06, 0x33, 0x0b,
+ 0xb9, 0x41, 0x1f, 0xc4, 0x27, 0xa3, 0x61, 0xff, 0x79, 0x28, 0xa9, 0xb3,
+ 0x92, 0x52, 0xa1, 0x3c, 0x35, 0x34, 0x22, 0x94, 0xc1, 0xcb, 0x42, 0x49,
+ 0x96, 0xac, 0x1e, 0xcf, 0x36, 0xb4, 0x5b, 0x58, 0x7c, 0x10, 0xd1, 0x02,
+ 0x70, 0x1b, 0x01, 0xbc, 0x7b, 0x6e, 0x26, 0x9b, 0xd4, 0x3e, 0xe2, 0xd8,
+ 0x9e, 0x3c, 0x43, 0x54, 0x2f, 0xce, 0x70, 0xcf, 0x68, 0x5b, 0xb5, 0x67,
+ 0x34, 0x68, 0xf5, 0x8c, 0xce, 0x4b, 0x4a, 0x62, 0xbe, 0x67, 0x74, 0x05,
+ 0x3c, 0x97, 0xd2, 0xef, 0xad, 0xce, 0xb7, 0xb4, 0x3a, 0x5f, 0x5b, 0x01,
+ 0x22, 0x9a, 0x31, 0xcc, 0x1a, 0xd5, 0x43, 0xfc, 0x26, 0x1d, 0xae, 0x88,
+ 0xda, 0x73, 0x18, 0x21, 0x44, 0xa9, 0xde, 0xbd, 0x9e, 0xf2, 0xa0, 0x3b,
+ 0xb3, 0x03, 0x33, 0x9a, 0xd2, 0x37, 0x00, 0xb6, 0x9d, 0x6e, 0xec, 0xa3,
+ 0x18, 0xba, 0xb7, 0xcc, 0xf5, 0xc8, 0xb0, 0x38, 0xcb, 0x76, 0xe3, 0xb4,
+ 0xa5, 0x66, 0xaf, 0xff, 0x70, 0x75, 0xfd, 0x21, 0x6b, 0xfd, 0x0b, 0x92,
+ 0xd2, 0x5f, 0x5d, 0x5f, 0xfb, 0x33, 0xa1, 0xa4, 0x68, 0xfd, 0x9e, 0x3d,
+ 0xb4, 0xbe, 0x4b, 0xe5, 0xb5, 0x1f, 0xe6, 0xb5, 0xe9, 0x73, 0x08, 0xd7,
+ 0x93, 0xdd, 0xbc, 0x57, 0x90, 0xc5, 0xbb, 0xb9, 0x35, 0xd8, 0x35, 0xb3,
+ 0x06, 0x3b, 0xc9, 0xdf, 0xb6, 0x6a, 0x0d, 0x54, 0xa7, 0xa1, 0xde, 0xa7,
+ 0xe2, 0xb2, 0x23, 0x22, 0xa4, 0xf5, 0xed, 0x2d, 0x84, 0x41, 0x4e, 0x34,
+ 0xcb, 0xf8, 0xd4, 0x1c, 0x50, 0xd7, 0xf4, 0x39, 0x91, 0xfc, 0x7d, 0x0f,
+ 0xfe, 0x5c, 0x22, 0xff, 0x7d, 0x67, 0x81, 0x40, 0xd2, 0x63, 0xd5, 0x1c,
+ 0x09, 0xe1, 0x29, 0xfe, 0xd8, 0x69, 0xdb, 0x7b, 0x2b, 0x7c, 0x8d, 0x68,
+ 0x68, 0x50, 0x6f, 0x40, 0x43, 0xa3, 0x6c, 0x38, 0xa8, 0x8e, 0x59, 0x4f,
+ 0x21, 0xd1, 0xcc, 0xf5, 0x51, 0x3c, 0x35, 0x71, 0x65, 0xf9, 0xdf, 0x9b,
+ 0x89, 0xeb, 0xf8, 0x39, 0x02, 0x15, 0x56, 0x4c, 0xfc, 0xb2, 0x39, 0xe2,
+ 0xe4, 0xbf, 0x6d, 0x54, 0x97, 0xd6, 0x51, 0xf0, 0xed, 0xc1, 0x9e, 0xac,
+ 0x92, 0xda, 0x43, 0x75, 0xe5, 0xfe, 0x48, 0x5b, 0xcf, 0x26, 0x51, 0x83,
+ 0xd0, 0xc2, 0xf0, 0xe0, 0x00, 0x92, 0xcd, 0xf5, 0x55, 0x3a, 0x1e, 0x46,
+ 0xb3, 0x8b, 0x9e, 0xe3, 0x79, 0xae, 0xb1, 0xa7, 0x22, 0xd9, 0x13, 0xdf,
+ 0xe7, 0xef, 0x57, 0xef, 0xcb, 0xbf, 0xa3, 0x4f, 0xae, 0xfa, 0xaf, 0x4b,
+ 0xbf, 0xec, 0xfa, 0xb1, 0x2f, 0xb9, 0xfe, 0x6f, 0xd5, 0xe7, 0x95, 0x46,
+ 0xa7, 0x95, 0xfb, 0x93, 0x0e, 0xee, 0x4b, 0x3a, 0xf5, 0x42, 0xd7, 0x2e,
+ 0xf5, 0x3f, 0x51, 0xcc, 0xe2, 0x7e, 0x04, 0xe7, 0xdb, 0x33, 0x56, 0x3f,
+ 0xe2, 0xf8, 0x6f, 0x61, 0x4f, 0x8e, 0x1d, 0x6e, 0x51, 0x37, 0x6e, 0x98,
+ 0x4d, 0xea, 0x1f, 0x51, 0x7d, 0xb2, 0x03, 0x03, 0x31, 0x0d, 0x63, 0x59,
+ 0xa5, 0xef, 0x0e, 0xa8, 0xc9, 0x3b, 0x05, 0x4d, 0x54, 0x72, 0x0b, 0x69,
+ 0xbc, 0x7a, 0x4f, 0x33, 0xa8, 0xe6, 0xaa, 0xa0, 0x96, 0x62, 0x8f, 0x53,
+ 0xf5, 0xcb, 0x28, 0x05, 0x64, 0x67, 0x29, 0x28, 0xd7, 0x94, 0x5a, 0xe4,
+ 0x5a, 0x1a, 0xe7, 0x1d, 0x57, 0x2e, 0xdf, 0x81, 0x1d, 0xb8, 0xbc, 0xdc,
+ 0x63, 0x34, 0xeb, 0x8a, 0xbf, 0x59, 0xda, 0x81, 0x5d, 0x31, 0x7e, 0xb6,
+ 0x9b, 0x6a, 0x2f, 0x88, 0xc6, 0x0c, 0x21, 0x5c, 0x5d, 0x60, 0x37, 0xd5,
+ 0x97, 0x4b, 0x1c, 0x6a, 0xcf, 0xaf, 0x85, 0x53, 0x76, 0x97, 0x20, 0x7c,
+ 0x19, 0x07, 0x0e, 0x76, 0xc2, 0xed, 0x5e, 0xa1, 0x0c, 0x9e, 0x10, 0xc3,
+ 0x78, 0x36, 0x16, 0xe9, 0xdb, 0x2c, 0x42, 0xb2, 0x87, 0xee, 0xb9, 0x32,
+ 0x10, 0x72, 0xc6, 0x70, 0xbb, 0x56, 0x28, 0x41, 0x87, 0x48, 0x62, 0x40,
+ 0x55, 0xb5, 0x71, 0xc8, 0xb4, 0x26, 0x44, 0x6d, 0x46, 0xb9, 0x7c, 0x96,
+ 0xb0, 0xd1, 0x95, 0xa5, 0xc3, 0xe8, 0x58, 0x1e, 0xd9, 0xdb, 0xef, 0x50,
+ 0x65, 0xc2, 0x6c, 0xc2, 0x99, 0xf1, 0xe2, 0xa6, 0x03, 0xf3, 0xfd, 0x19,
+ 0xd3, 0xfc, 0x38, 0x56, 0xb9, 0x97, 0x44, 0x28, 0xd7, 0x97, 0xa2, 0xb2,
+ 0x97, 0xf0, 0x79, 0xdb, 0x01, 0xc6, 0x4b, 0x9c, 0x0f, 0x2a, 0x64, 0x37,
+ 0xed, 0xc4, 0x63, 0x1f, 0x66, 0xd2, 0x8c, 0x9f, 0x74, 0x4c, 0x53, 0x6d,
+ 0xa3, 0x8e, 0xb6, 0x50, 0xae, 0x4f, 0x60, 0x2e, 0xcd, 0x7d, 0x9c, 0x41,
+ 0x92, 0x71, 0x3f, 0xd1, 0xbf, 0x81, 0xea, 0xda, 0x14, 0xc5, 0x2b, 0x96,
+ 0xf1, 0x00, 0xf7, 0x6b, 0xa9, 0x96, 0xfe, 0x79, 0xd7, 0xd7, 0xc6, 0x20,
+ 0xbb, 0xf5, 0xd7, 0xba, 0xae, 0x3f, 0x80, 0x46, 0xca, 0xe7, 0x3a, 0x55,
+ 0x2e, 0x88, 0x46, 0x22, 0xda, 0x79, 0x44, 0x82, 0x2f, 0x93, 0x3e, 0x46,
+ 0x54, 0x60, 0xa7, 0x55, 0x33, 0x3b, 0x61, 0x14, 0xd8, 0xa6, 0xe0, 0xae,
+ 0xed, 0x6c, 0xc4, 0xfb, 0xb9, 0xa8, 0xd5, 0x0b, 0x32, 0xa8, 0x8e, 0x79,
+ 0x49, 0x53, 0x52, 0x79, 0x7a, 0x6e, 0xa3, 0xff, 0x7f, 0xed, 0xa9, 0x8b,
+ 0x43, 0xae, 0x53, 0xd9, 0xbf, 0xfe, 0xdc, 0x73, 0x96, 0x6c, 0xf4, 0xae,
+ 0xc9, 0xbf, 0xf0, 0x7c, 0x12, 0xcf, 0x7b, 0x3e, 0x8a, 0x9b, 0x66, 0x82,
+ 0x70, 0x65, 0x3f, 0xd5, 0xcd, 0x1f, 0x8f, 0x1a, 0x9e, 0xf3, 0x71, 0xee,
+ 0xe9, 0x3a, 0xf1, 0x07, 0xf4, 0xfb, 0xe9, 0x51, 0x19, 0xb7, 0x16, 0x9b,
+ 0xe1, 0x1a, 0x93, 0xc8, 0x3f, 0xd7, 0x52, 0xae, 0x72, 0xe0, 0x9e, 0xe8,
+ 0x51, 0x54, 0x02, 0x0e, 0x1a, 0xb3, 0x9f, 0x7e, 0x73, 0x6f, 0xea, 0x71,
+ 0x6c, 0xf6, 0xcf, 0x7a, 0xde, 0x8f, 0x33, 0xbd, 0x15, 0xa6, 0x97, 0x72,
+ 0xe4, 0xed, 0xd8, 0x78, 0x07, 0x0c, 0x9f, 0x6e, 0xfd, 0xbb, 0x5f, 0xee,
+ 0x6c, 0xc2, 0xe1, 0x5c, 0x33, 0x5e, 0xcc, 0x19, 0xee, 0x9f, 0x76, 0x46,
+ 0x31, 0x38, 0x6a, 0xe2, 0x15, 0xcd, 0x18, 0xae, 0x25, 0x3b, 0x4f, 0x50,
+ 0xad, 0x14, 0x5e, 0xae, 0xf8, 0x2f, 0x0b, 0x44, 0x24, 0x44, 0x86, 0x08,
+ 0x2c, 0xde, 0x4d, 0xa1, 0x2b, 0x55, 0xaf, 0x47, 0xb4, 0xd7, 0x85, 0x59,
+ 0x73, 0x6f, 0xa7, 0x93, 0x68, 0x00, 0xd6, 0x51, 0x4c, 0x9e, 0x4b, 0x47,
+ 0x71, 0x6b, 0x44, 0xc6, 0xfa, 0xa2, 0x86, 0x17, 0xd3, 0x5e, 0xdc, 0x55,
+ 0x8c, 0x13, 0x86, 0xf6, 0x13, 0xed, 0x09, 0x94, 0xd3, 0x01, 0x7c, 0xbd,
+ 0xd8, 0x42, 0xf2, 0x0e, 0x62, 0x6d, 0x91, 0x31, 0x16, 0xe7, 0x67, 0xdd,
+ 0xbd, 0x31, 0xde, 0x82, 0x1e, 0x8a, 0xdf, 0xb3, 0x69, 0xb8, 0xb7, 0xc7,
+ 0x43, 0xe8, 0x2e, 0x46, 0x51, 0x24, 0x2c, 0x76, 0x3b, 0xcd, 0x79, 0x17,
+ 0xe9, 0xa4, 0x9d, 0xea, 0xfb, 0x25, 0x11, 0x42, 0xa8, 0x45, 0xaf, 0x18,
+ 0x26, 0xcc, 0x94, 0x28, 0x36, 0xe1, 0xfc, 0x18, 0xdb, 0xf9, 0x5b, 0x5d,
+ 0xbb, 0x72, 0x7e, 0x84, 0x8a, 0xb8, 0x49, 0x06, 0xb6, 0x51, 0x95, 0x97,
+ 0x2a, 0x12, 0xbd, 0xfb, 0x3a, 0xed, 0x7e, 0xec, 0x0d, 0xc5, 0xcf, 0xf9,
+ 0x6d, 0x20, 0x3d, 0x7d, 0x72, 0x60, 0xd6, 0x73, 0x85, 0x64, 0xe0, 0xd3,
+ 0x7f, 0xd4, 0xf5, 0xc6, 0x01, 0x20, 0x3a, 0xc5, 0xbc, 0x71, 0x7c, 0x0d,
+ 0x27, 0x28, 0xbe, 0xb6, 0xcb, 0xf8, 0xb5, 0x49, 0xb5, 0x64, 0x68, 0x86,
+ 0x7b, 0xff, 0xaa, 0x97, 0xe8, 0xf0, 0x23, 0x49, 0x6b, 0xdf, 0x56, 0xfc,
+ 0xa1, 0xb9, 0x71, 0x61, 0x10, 0x5f, 0x8b, 0xd8, 0xb2, 0x7a, 0x9d, 0x74,
+ 0x38, 0x3d, 0xd6, 0x8c, 0xb9, 0x31, 0xee, 0xad, 0x9c, 0xea, 0x3a, 0x34,
+ 0x69, 0x62, 0x9d, 0x66, 0x78, 0x7e, 0xda, 0x79, 0x03, 0x1e, 0x38, 0x30,
+ 0x72, 0xba, 0x86, 0xf4, 0x7a, 0x59, 0xbb, 0x1b, 0x8f, 0x4e, 0xe1, 0xab,
+ 0xcd, 0xc0, 0x23, 0x41, 0x70, 0xff, 0x59, 0x09, 0x1d, 0x41, 0xa4, 0x67,
+ 0x3b, 0x22, 0x7e, 0x55, 0x28, 0xda, 0x2b, 0x14, 0xab, 0xea, 0x08, 0x3b,
+ 0xdc, 0x46, 0xb5, 0x7c, 0x0d, 0x79, 0xf0, 0x5d, 0x45, 0x27, 0xc9, 0x28,
+ 0x88, 0xf2, 0x58, 0x0d, 0x24, 0xf2, 0x93, 0x0b, 0x2a, 0xd6, 0x35, 0x90,
+ 0xac, 0x25, 0x21, 0x93, 0x9e, 0xdb, 0x71, 0x68, 0x74, 0x5e, 0x56, 0x5e,
+ 0xdc, 0x42, 0x32, 0x7c, 0x76, 0xd4, 0xdc, 0xa1, 0xc6, 0x02, 0x24, 0x6b,
+ 0x3f, 0xd1, 0x37, 0x2f, 0x27, 0x96, 0xdf, 0xbc, 0x9c, 0xee, 0xc6, 0xae,
+ 0x39, 0x96, 0xdb, 0xbf, 0x47, 0x5e, 0xb3, 0x96, 0xdd, 0xad, 0x9b, 0x8c,
+ 0xa2, 0xf9, 0xc0, 0x55, 0xd9, 0x31, 0x7d, 0x8f, 0x10, 0x1f, 0xdf, 0xf3,
+ 0xad, 0x8c, 0x0c, 0x5e, 0x14, 0x5e, 0xa2, 0xc7, 0x4f, 0xba, 0x39, 0xeb,
+ 0x62, 0x0c, 0x4e, 0x32, 0xb9, 0x2a, 0xe3, 0x20, 0xc9, 0x38, 0x38, 0xc5,
+ 0xb2, 0xfe, 0x11, 0xc9, 0x1a, 0x78, 0x83, 0x70, 0xd7, 0xcd, 0xb1, 0x28,
+ 0xea, 0x0f, 0x28, 0xc9, 0x66, 0x29, 0x9c, 0x68, 0x10, 0xa0, 0xea, 0x02,
+ 0xed, 0xf5, 0xf8, 0x98, 0xe5, 0xac, 0x91, 0x9c, 0xbf, 0x37, 0x42, 0xfc,
+ 0xac, 0xa1, 0xf9, 0xd6, 0x91, 0x9c, 0x93, 0xc4, 0xff, 0x6d, 0xd6, 0xbc,
+ 0x2d, 0x34, 0xef, 0x06, 0xaa, 0x21, 0x66, 0x3d, 0x17, 0x88, 0x9e, 0xe8,
+ 0xe7, 0xb4, 0x10, 0xca, 0x8e, 0x04, 0x2f, 0x52, 0xad, 0xbc, 0xd6, 0x1a,
+ 0xe7, 0xa7, 0x71, 0x4c, 0xfb, 0x5b, 0xb5, 0x0e, 0xf5, 0xcb, 0x7a, 0xc7,
+ 0x77, 0x83, 0x7b, 0x07, 0x06, 0xfa, 0xb1, 0x37, 0xbb, 0x81, 0x6a, 0x1e,
+ 0x99, 0x30, 0xa4, 0x81, 0xef, 0xc7, 0x95, 0x68, 0xa3, 0xe0, 0xf8, 0x67,
+ 0x90, 0x1f, 0x56, 0xa8, 0xde, 0x09, 0x87, 0xe6, 0x10, 0x94, 0x1d, 0x25,
+ 0x99, 0xf0, 0x5e, 0x8b, 0x2c, 0x95, 0xc8, 0x5f, 0x83, 0xfd, 0x84, 0x93,
+ 0x9d, 0x78, 0xb9, 0xe0, 0xc4, 0xab, 0xe9, 0x0d, 0x94, 0xe7, 0xdc, 0x84,
+ 0x87, 0x0d, 0xb7, 0x73, 0xc5, 0x81, 0x1a, 0x3b, 0x26, 0x2f, 0x45, 0xef,
+ 0xf8, 0xc3, 0xa8, 0xcb, 0x38, 0xfb, 0x28, 0x47, 0x6b, 0xb7, 0x91, 0x5c,
+ 0xd6, 0x95, 0xf8, 0x7e, 0x0b, 0x32, 0xe9, 0x14, 0xb2, 0xd9, 0x30, 0xd5,
+ 0x32, 0x4e, 0xe4, 0x9b, 0x5b, 0xac, 0xfe, 0x6c, 0x8e, 0xae, 0xe5, 0xca,
+ 0x5f, 0xec, 0x1b, 0x7f, 0xab, 0xda, 0x2f, 0x1e, 0xa4, 0x9c, 0xd2, 0x4f,
+ 0xd8, 0x73, 0x03, 0xc5, 0x77, 0x9b, 0xc6, 0xd9, 0x78, 0x1f, 0xf6, 0x14,
+ 0xf4, 0xab, 0xf1, 0x63, 0xba, 0x60, 0xf7, 0x05, 0xb7, 0x90, 0x3c, 0xce,
+ 0xa5, 0x4d, 0x3c, 0xaa, 0xb1, 0x3e, 0x29, 0x2e, 0xa5, 0xb9, 0x37, 0x68,
+ 0xe2, 0x19, 0x4d, 0x70, 0xbc, 0xa1, 0x3c, 0xba, 0x01, 0x4b, 0x0a, 0x26,
+ 0x4e, 0x6b, 0x2a, 0xc5, 0x2e, 0x18, 0x6e, 0xc2, 0x7e, 0x91, 0xd1, 0x7f,
+ 0x31, 0xf3, 0xce, 0x21, 0xb4, 0x75, 0x02, 0x9b, 0x47, 0x25, 0xcc, 0xcd,
+ 0x5c, 0xcd, 0xd1, 0x78, 0xf1, 0xf3, 0x3c, 0x9d, 0x98, 0x81, 0xb9, 0xc3,
+ 0xa9, 0x2b, 0xc3, 0xbc, 0xd7, 0x32, 0x12, 0x57, 0x12, 0xb5, 0x56, 0xce,
+ 0x56, 0xfb, 0x97, 0x48, 0x8a, 0x56, 0x12, 0x6d, 0xa9, 0x4f, 0x50, 0x59,
+ 0x2f, 0x43, 0x09, 0xfe, 0x0c, 0x91, 0xe8, 0x20, 0xef, 0x29, 0x94, 0xed,
+ 0xfc, 0xbd, 0xb4, 0x9a, 0xbf, 0xc3, 0x05, 0x8f, 0x50, 0xc7, 0x1c, 0xc8,
+ 0xcf, 0x98, 0x94, 0x67, 0x05, 0x66, 0x49, 0xc1, 0x2f, 0x64, 0x77, 0xe0,
+ 0xeb, 0x31, 0xd3, 0xbc, 0x2b, 0xae, 0x0e, 0x36, 0x4b, 0xf8, 0xd3, 0x06,
+ 0xc2, 0x14, 0x64, 0xf7, 0x84, 0x01, 0x10, 0xda, 0xda, 0x69, 0x98, 0x32,
+ 0xd5, 0x0c, 0x35, 0x3a, 0xf7, 0x1a, 0x7b, 0x45, 0x7b, 0x71, 0x83, 0xb8,
+ 0xa1, 0xd8, 0x2f, 0x42, 0x87, 0xee, 0x14, 0xd1, 0xa7, 0x6c, 0xdc, 0xd6,
+ 0x5a, 0xfc, 0xbc, 0x1f, 0xda, 0x43, 0x7c, 0xef, 0xd3, 0x4c, 0x3c, 0x4d,
+ 0xbc, 0xed, 0x2d, 0xdb, 0xb5, 0xc8, 0xee, 0xb4, 0xcd, 0xdb, 0xa3, 0x74,
+ 0xff, 0x62, 0x9a, 0xfd, 0xf1, 0x61, 0xab, 0xd7, 0xd9, 0x4c, 0xcf, 0xdc,
+ 0x9c, 0x0d, 0x87, 0x06, 0x85, 0x32, 0x34, 0x0b, 0xee, 0x77, 0xb6, 0x55,
+ 0x4e, 0x0a, 0xca, 0x3d, 0x12, 0xc7, 0x57, 0xf6, 0x79, 0x9b, 0xf6, 0x65,
+ 0x05, 0x58, 0x71, 0x91, 0xe9, 0xbf, 0x91, 0xea, 0xbe, 0x9f, 0xa5, 0xdb,
+ 0xfa, 0xdd, 0x24, 0xb6, 0xf3, 0xf1, 0x6e, 0x71, 0x89, 0xea, 0xbe, 0x57,
+ 0xd3, 0xc9, 0x85, 0x75, 0xe8, 0x11, 0x17, 0x0a, 0x7d, 0xe2, 0xc3, 0x7c,
+ 0x2f, 0x9c, 0x63, 0xf7, 0x8b, 0x77, 0xf3, 0x4c, 0x5b, 0xbf, 0x38, 0x33,
+ 0x7b, 0xde, 0x92, 0xfd, 0x2e, 0x8d, 0xfb, 0x9a, 0xf5, 0xb5, 0xf0, 0x99,
+ 0x04, 0x4f, 0x59, 0x8f, 0xdc, 0xe7, 0xb3, 0xfb, 0x43, 0xeb, 0xe2, 0x39,
+ 0xd3, 0xa9, 0x72, 0xaf, 0x37, 0x68, 0xf1, 0x38, 0x43, 0x78, 0x79, 0x36,
+ 0xbf, 0x41, 0x1c, 0x2e, 0xd8, 0xfc, 0x4d, 0x17, 0xd8, 0x6e, 0x65, 0xca,
+ 0x0d, 0x5f, 0xcc, 0xcf, 0x06, 0xfc, 0x9d, 0x41, 0xd4, 0x58, 0xfd, 0x24,
+ 0x13, 0xe3, 0x5a, 0x24, 0xf4, 0x0a, 0x82, 0x70, 0x96, 0xd8, 0xa6, 0x4d,
+ 0x3c, 0xa7, 0xb9, 0x20, 0x8d, 0xcb, 0x24, 0x17, 0xb2, 0x21, 0x9f, 0x0b,
+ 0x8e, 0x69, 0xae, 0x01, 0xe2, 0xb5, 0xdc, 0x67, 0x08, 0x39, 0xf8, 0xfb,
+ 0x17, 0x6d, 0xcd, 0x45, 0x79, 0x80, 0xfb, 0xe3, 0x6f, 0xd6, 0xd8, 0x36,
+ 0xc7, 0xf9, 0x68, 0xbe, 0xa7, 0x4d, 0x39, 0xb6, 0x93, 0x7b, 0xd9, 0x6e,
+ 0xcc, 0xe5, 0x6a, 0xb8, 0xc5, 0xe0, 0xae, 0xe9, 0x34, 0x71, 0x4e, 0x73,
+ 0x52, 0x5d, 0xf2, 0x10, 0xe5, 0x26, 0x07, 0x64, 0xf5, 0x6e, 0x94, 0x26,
+ 0x9d, 0x0e, 0xde, 0x73, 0xfa, 0x59, 0x8c, 0x7b, 0x00, 0xc0, 0x7e, 0xe2,
+ 0xe1, 0x99, 0x5c, 0x88, 0xea, 0x7f, 0xb9, 0x5a, 0x43, 0xfc, 0x01, 0x8e,
+ 0xe7, 0x24, 0xd1, 0xac, 0x43, 0x4a, 0xac, 0x34, 0xf1, 0xc9, 0xf2, 0x48,
+ 0xf4, 0x32, 0xc5, 0x2f, 0x3f, 0xe5, 0xaa, 0xdd, 0x85, 0x46, 0xfc, 0x2c,
+ 0xd7, 0x88, 0x57, 0x73, 0xa4, 0xc3, 0xd8, 0x48, 0xbf, 0x87, 0x62, 0xe4,
+ 0xd2, 0x98, 0x0b, 0x5b, 0x23, 0x86, 0xdf, 0x83, 0x28, 0xce, 0x25, 0xae,
+ 0x47, 0x2a, 0x10, 0xee, 0x19, 0x41, 0x13, 0xde, 0xcc, 0x81, 0x30, 0x04,
+ 0xdc, 0x4b, 0x68, 0x8e, 0xf7, 0x62, 0xc6, 0x90, 0x0b, 0x0a, 0xd5, 0x1f,
+ 0x88, 0xd7, 0xc3, 0xac, 0x39, 0x19, 0xa7, 0x1c, 0x5d, 0x6c, 0x44, 0x6f,
+ 0xae, 0x09, 0xfd, 0x94, 0xab, 0x56, 0xaf, 0x8c, 0xe3, 0xdd, 0xac, 0x57,
+ 0xdc, 0x94, 0x1d, 0xe9, 0xf7, 0xd3, 0x9c, 0xae, 0xe5, 0xca, 0xd0, 0xb3,
+ 0x04, 0xd8, 0x64, 0x84, 0xd9, 0xbc, 0xb7, 0xfb, 0x28, 0xde, 0x1e, 0x16,
+ 0x9f, 0xe1, 0x49, 0xb2, 0xc1, 0x2d, 0x9a, 0x52, 0xb9, 0x20, 0x45, 0x4e,
+ 0xaf, 0x87, 0x32, 0x7c, 0x9b, 0x30, 0xa2, 0x0d, 0x14, 0x47, 0x9a, 0xed,
+ 0x18, 0x61, 0x44, 0x84, 0x4c, 0x98, 0xdc, 0x09, 0xb7, 0x6a, 0xa0, 0xa7,
+ 0x93, 0x65, 0xea, 0x86, 0xfb, 0x29, 0xb2, 0x1b, 0xc7, 0x17, 0xfb, 0xf3,
+ 0x8d, 0x78, 0x83, 0xf2, 0xe4, 0xeb, 0x39, 0xc8, 0xb5, 0x14, 0xfb, 0x3f,
+ 0xa0, 0xd8, 0x7f, 0x2a, 0x36, 0x12, 0xe2, 0x98, 0x5f, 0x88, 0xe1, 0x5b,
+ 0x04, 0x83, 0x5b, 0xbc, 0xb4, 0xe6, 0x26, 0xc1, 0xeb, 0x20, 0xb9, 0x58,
+ 0xe7, 0xbe, 0x9a, 0xc5, 0x0f, 0xc5, 0x61, 0xe6, 0xe9, 0xff, 0x27, 0xed,
+ 0xdb, 0x6b, 0xe1, 0x69, 0x22, 0x5d, 0xce, 0xf7, 0x24, 0xaf, 0xed, 0x47,
+ 0x72, 0x1d, 0x63, 0xe3, 0xc2, 0x1a, 0xbd, 0x4e, 0xbc, 0x94, 0x63, 0x9b,
+ 0x33, 0xf1, 0xbc, 0xa6, 0x51, 0xcd, 0xc2, 0xb5, 0xf6, 0x10, 0xd5, 0x2d,
+ 0xdc, 0x27, 0x32, 0xdc, 0x27, 0x89, 0xc2, 0xbd, 0x39, 0xfc, 0x9e, 0x0c,
+ 0x69, 0x59, 0x2d, 0xa6, 0x90, 0x77, 0x3a, 0x09, 0x6b, 0x70, 0x8c, 0x65,
+ 0x3f, 0x7a, 0xab, 0x4b, 0xcd, 0xc3, 0xf0, 0xea, 0x3d, 0x30, 0x2c, 0xdf,
+ 0xad, 0x13, 0x0f, 0x90, 0x8d, 0xbc, 0x1c, 0xab, 0x45, 0x9e, 0xea, 0x1e,
+ 0xc2, 0xdf, 0xee, 0x3f, 0xa3, 0xe7, 0x13, 0x13, 0xd8, 0x13, 0x84, 0xf4,
+ 0x5d, 0x3f, 0xfe, 0x02, 0x67, 0x5d, 0x8c, 0xcb, 0xe1, 0xee, 0x8b, 0x1b,
+ 0x9e, 0xf5, 0xf1, 0x3a, 0x71, 0x7b, 0xae, 0x1d, 0x17, 0x27, 0x1b, 0xc9,
+ 0xbe, 0x9b, 0xb0, 0x78, 0x3c, 0x88, 0xf7, 0x88, 0x96, 0x61, 0x8d, 0xb1,
+ 0xba, 0x31, 0xdc, 0x0c, 0x65, 0x88, 0xea, 0xa1, 0xbe, 0x9f, 0x0b, 0xf6,
+ 0x01, 0xa5, 0xe7, 0x0e, 0xe1, 0x81, 0x1a, 0x49, 0x92, 0xec, 0x4d, 0x73,
+ 0x4c, 0x6b, 0xd3, 0xbc, 0xe0, 0xfe, 0xcf, 0xdd, 0xd8, 0x3f, 0xc7, 0xb4,
+ 0x9c, 0xea, 0xba, 0x61, 0x96, 0x3f, 0x4f, 0x77, 0x5d, 0x6f, 0x7d, 0xbe,
+ 0x56, 0xfd, 0xac, 0x74, 0x85, 0xac, 0xcf, 0x1f, 0xd1, 0x27, 0xf7, 0x99,
+ 0xc3, 0x46, 0x8d, 0xf8, 0xbe, 0x8b, 0xfb, 0xcd, 0x49, 0xf0, 0xff, 0x71,
+ 0x97, 0xdd, 0xaf, 0xbb, 0x1b, 0x86, 0xd5, 0x13, 0xf9, 0xb5, 0xd5, 0x8b,
+ 0x0e, 0x91, 0x1b, 0xc8, 0xc4, 0x9f, 0x4c, 0x58, 0x2b, 0x10, 0xa3, 0xc2,
+ 0xbc, 0x49, 0x36, 0x16, 0xeb, 0xfd, 0x54, 0x1b, 0xc8, 0xc4, 0xaf, 0x81,
+ 0x3d, 0x9d, 0x02, 0xfb, 0x55, 0x1d, 0x3f, 0x2d, 0x70, 0x0c, 0x77, 0xe2,
+ 0x99, 0xb4, 0x12, 0x4a, 0x89, 0x30, 0xd5, 0xf9, 0x0e, 0x84, 0x9a, 0xfb,
+ 0xb1, 0x9f, 0xf2, 0xc9, 0x6c, 0x9a, 0xf3, 0x07, 0x7d, 0x52, 0x3c, 0x6f,
+ 0xa0, 0xf8, 0xf3, 0xf1, 0xa8, 0x1d, 0xef, 0x8b, 0x71, 0x65, 0xef, 0x1f,
+ 0x90, 0x4e, 0x9f, 0x2b, 0xf2, 0x9c, 0x06, 0xae, 0xac, 0x64, 0x1f, 0x56,
+ 0xa2, 0x29, 0xc7, 0x7d, 0x08, 0xcd, 0x70, 0x6c, 0xa1, 0xe5, 0x68, 0xad,
+ 0x83, 0xd9, 0x1a, 0xf4, 0xc5, 0x7b, 0x45, 0x7f, 0xa9, 0x8f, 0xf7, 0x14,
+ 0xfc, 0x0b, 0xf4, 0x3b, 0xc5, 0x9a, 0x69, 0xee, 0x09, 0x6e, 0x10, 0x7d,
+ 0x25, 0xee, 0x0b, 0x0e, 0x8b, 0x6f, 0x94, 0xd8, 0xe7, 0xe7, 0xfb, 0x83,
+ 0xf3, 0xfa, 0xe7, 0xbe, 0xa0, 0xe1, 0x7e, 0x89, 0x64, 0xbf, 0x3d, 0xc7,
+ 0x71, 0x58, 0x7a, 0xc0, 0x87, 0xe5, 0xc8, 0xbb, 0xe0, 0x3e, 0x11, 0xff,
+ 0x1d, 0xdc, 0x45, 0xb8, 0x60, 0xb1, 0x6a, 0xeb, 0x6f, 0x75, 0xde, 0x81,
+ 0xc4, 0x72, 0x12, 0xfa, 0x02, 0xd6, 0xe9, 0x00, 0xc5, 0xb3, 0x8c, 0x39,
+ 0x18, 0x60, 0x5d, 0xb2, 0xbd, 0x59, 0x7d, 0x27, 0xca, 0x2b, 0x06, 0x22,
+ 0x9d, 0x6e, 0xcc, 0xe6, 0x16, 0x51, 0x4d, 0x60, 0x62, 0xaf, 0x56, 0x8f,
+ 0x5a, 0x2b, 0x06, 0xb8, 0x09, 0x47, 0x42, 0xf6, 0xd2, 0x3c, 0xe9, 0x31,
+ 0x19, 0x1e, 0xba, 0x77, 0x92, 0x72, 0xd3, 0xfe, 0x4e, 0x7b, 0xee, 0xb6,
+ 0xfc, 0x4d, 0xd8, 0x47, 0x1e, 0x5f, 0xaf, 0x46, 0x31, 0xea, 0xf7, 0x52,
+ 0xac, 0xf9, 0x56, 0x75, 0xce, 0xcf, 0xc8, 0x36, 0x79, 0xbd, 0x4d, 0xb5,
+ 0xb6, 0x1e, 0x96, 0xc9, 0x76, 0xed, 0x25, 0x1b, 0x75, 0xb4, 0xd6, 0xd6,
+ 0xce, 0x0d, 0xe8, 0x19, 0xf5, 0x8a, 0x57, 0xd3, 0xf7, 0x98, 0xa1, 0x46,
+ 0x1a, 0x47, 0x36, 0x5b, 0x53, 0xa5, 0xb7, 0x35, 0xff, 0xcf, 0xb5, 0x5c,
+ 0xa7, 0x7b, 0x29, 0x8f, 0x3c, 0x98, 0x73, 0x20, 0x50, 0xbd, 0x1e, 0xcf,
+ 0x87, 0xa0, 0x75, 0xd4, 0x01, 0x4d, 0x82, 0xae, 0xf1, 0xdc, 0xbc, 0x86,
+ 0x8c, 0x46, 0xf2, 0x93, 0x6f, 0xc7, 0x13, 0xf8, 0x20, 0xeb, 0xc4, 0x7a,
+ 0xca, 0xef, 0x6b, 0xd3, 0x3a, 0xce, 0x95, 0x6b, 0x79, 0x3d, 0xb2, 0xc3,
+ 0xf9, 0x71, 0x4e, 0x1a, 0xe7, 0xc6, 0x74, 0xfe, 0x8b, 0xf4, 0x05, 0x88,
+ 0xe6, 0x22, 0x8d, 0xe5, 0x7b, 0xe7, 0xad, 0xbe, 0xc0, 0xf1, 0x6b, 0xea,
+ 0x29, 0xc7, 0x38, 0xf7, 0x8a, 0xec, 0x5c, 0xd0, 0xad, 0xb1, 0x2e, 0x7d,
+ 0xb8, 0x3c, 0x61, 0xe0, 0xdc, 0xca, 0x06, 0x5c, 0x99, 0x68, 0xc5, 0x03,
+ 0x39, 0x0f, 0x2e, 0x4c, 0x98, 0xb8, 0x69, 0x39, 0xee, 0x09, 0x12, 0x06,
+ 0x6b, 0x20, 0xbf, 0xff, 0x29, 0xd5, 0x3c, 0x14, 0x4f, 0x89, 0xd2, 0x48,
+ 0x62, 0x1d, 0xd9, 0x75, 0x34, 0x86, 0xd4, 0x2d, 0xf1, 0x48, 0xe8, 0x3c,
+ 0xbe, 0x67, 0x52, 0x2c, 0xf6, 0x4b, 0x7a, 0xaf, 0x70, 0x5a, 0xfb, 0x84,
+ 0x1b, 0xac, 0x7d, 0x45, 0xc7, 0xf4, 0xb0, 0x90, 0x4a, 0xd7, 0xfa, 0xf5,
+ 0x97, 0xe5, 0x21, 0xce, 0x3d, 0x9c, 0x23, 0xc7, 0x4d, 0x97, 0xba, 0xc1,
+ 0xea, 0xd3, 0xec, 0xce, 0x5f, 0xcd, 0x4d, 0x57, 0xf3, 0xd1, 0xce, 0x6a,
+ 0x1e, 0x1a, 0x29, 0xbc, 0xf3, 0x05, 0xfc, 0x14, 0xaa, 0xee, 0x57, 0x70,
+ 0xfe, 0x71, 0x8b, 0xb3, 0x64, 0x0e, 0x7b, 0xc8, 0x07, 0x8f, 0x6a, 0x27,
+ 0x82, 0x94, 0x21, 0xe0, 0xec, 0x10, 0x78, 0x90, 0xcf, 0x8b, 0x04, 0x4c,
+ 0xdc, 0xa9, 0xd9, 0xf6, 0xb0, 0xbc, 0xd3, 0x85, 0x41, 0xca, 0x49, 0xae,
+ 0x98, 0x97, 0x7c, 0xdd, 0x8f, 0xd7, 0x34, 0xb6, 0xe1, 0x5b, 0xaa, 0x39,
+ 0x89, 0xf7, 0xbf, 0xed, 0xbd, 0xea, 0xdf, 0xee, 0x5b, 0xcf, 0xdb, 0xa6,
+ 0x86, 0xe4, 0x42, 0x78, 0xde, 0x8b, 0xab, 0x54, 0x37, 0xc8, 0x54, 0x33,
+ 0xac, 0x47, 0x62, 0x81, 0x92, 0x64, 0xfd, 0xfb, 0x68, 0xee, 0x5f, 0x76,
+ 0x0e, 0xe2, 0xfe, 0x71, 0x07, 0xea, 0x54, 0x8e, 0xb3, 0x06, 0xf6, 0x37,
+ 0x72, 0x9c, 0xea, 0xc5, 0x8e, 0x71, 0xb7, 0x38, 0x99, 0x73, 0xe2, 0xc9,
+ 0xbe, 0x47, 0xb0, 0xa0, 0x63, 0x4b, 0xb5, 0xd7, 0xc9, 0xdf, 0xbf, 0x89,
+ 0xd4, 0x22, 0x5e, 0x9f, 0x7b, 0x68, 0x02, 0xde, 0x0e, 0xe6, 0x03, 0x9e,
+ 0x8b, 0x34, 0xff, 0xe6, 0x51, 0xa7, 0x38, 0x9f, 0xfe, 0x1b, 0xf3, 0x48,
+ 0x80, 0x71, 0x01, 0xdf, 0xab, 0x87, 0xd1, 0xc8, 0x63, 0x59, 0x87, 0x5e,
+ 0xaa, 0x49, 0x07, 0x31, 0x4a, 0x74, 0xbd, 0x6e, 0xcd, 0x75, 0xb6, 0x4a,
+ 0xbf, 0x57, 0x34, 0x64, 0x64, 0x23, 0x48, 0xb4, 0xf8, 0x57, 0xf6, 0xa1,
+ 0xa1, 0x74, 0x6d, 0xbe, 0x25, 0xa3, 0xf7, 0x30, 0x7f, 0x9c, 0x13, 0x06,
+ 0xf0, 0x41, 0x5a, 0xe0, 0x7d, 0xcb, 0x06, 0x07, 0xd0, 0x5a, 0xa0, 0xfa,
+ 0xdf, 0x8a, 0x21, 0x3c, 0x2e, 0x6e, 0xdb, 0xb6, 0x63, 0x10, 0xdb, 0x89,
+ 0x97, 0x7a, 0xe2, 0xe5, 0xe3, 0xd8, 0x12, 0x5a, 0x87, 0xaf, 0x1d, 0x93,
+ 0xab, 0xfd, 0x87, 0xea, 0x5c, 0xab, 0xc0, 0xbd, 0x29, 0xa7, 0x1a, 0xc1,
+ 0xb6, 0xf1, 0x48, 0xbf, 0xd7, 0xc1, 0x76, 0x18, 0xc1, 0x7d, 0xd3, 0x49,
+ 0xba, 0xcf, 0x73, 0x05, 0xb1, 0x29, 0xe3, 0x14, 0xef, 0x52, 0x9d, 0x74,
+ 0x3c, 0xed, 0x58, 0x24, 0xe1, 0x07, 0xe6, 0x93, 0x81, 0x1d, 0xb8, 0x45,
+ 0xeb, 0xc5, 0xbd, 0x64, 0x83, 0xdd, 0xad, 0x3b, 0x30, 0x41, 0x36, 0xb0,
+ 0xb9, 0x89, 0x6a, 0xb7, 0x58, 0xd9, 0x1c, 0x08, 0xb0, 0x1c, 0x05, 0x7a,
+ 0xe8, 0x7a, 0x23, 0xd5, 0x73, 0x8e, 0x18, 0x59, 0x1b, 0xf9, 0x85, 0xac,
+ 0x2a, 0xb9, 0x24, 0xea, 0xad, 0x35, 0x1b, 0x29, 0x4f, 0xbb, 0x18, 0x1f,
+ 0xf8, 0x18, 0x27, 0x7c, 0x91, 0x1e, 0xc3, 0xac, 0x55, 0xd5, 0xe8, 0x7a,
+ 0x47, 0x6b, 0x6e, 0x8e, 0x6c, 0x76, 0x4d, 0xc7, 0xb5, 0xcf, 0xcd, 0xcb,
+ 0x48, 0x43, 0x4d, 0xc7, 0x8c, 0x59, 0xf1, 0x8f, 0xc0, 0xdf, 0x71, 0xad,
+ 0xee, 0xe7, 0xe7, 0x60, 0x9a, 0xed, 0xb8, 0x16, 0x72, 0x44, 0xfc, 0xf7,
+ 0xe0, 0xaf, 0x68, 0x8d, 0x20, 0x36, 0x96, 0x7a, 0x31, 0x30, 0x2e, 0x7d,
+ 0x8e, 0x4f, 0x7c, 0x6c, 0xcb, 0x9f, 0xf3, 0xbf, 0x75, 0x3c, 0xd2, 0xe3,
+ 0xa9, 0xf2, 0x7f, 0xef, 0xf4, 0xe7, 0x73, 0x0d, 0x67, 0x38, 0xaf, 0xf2,
+ 0x7c, 0xbc, 0xef, 0x37, 0x2f, 0xdf, 0x20, 0xb6, 0x5b, 0xf3, 0xed, 0x75,
+ 0xb3, 0x0f, 0xbb, 0xc8, 0xd7, 0xd7, 0x75, 0x18, 0x78, 0x2d, 0xf1, 0x80,
+ 0xb9, 0xd5, 0x92, 0xc1, 0x9f, 0x58, 0xcf, 0xf7, 0xb4, 0x56, 0x2c, 0x7b,
+ 0xb7, 0xfd, 0x96, 0xf7, 0x04, 0x78, 0x8f, 0x60, 0x7e, 0x5f, 0x20, 0x6a,
+ 0xed, 0xd7, 0xd9, 0x7b, 0x03, 0xdf, 0xa2, 0x38, 0xcb, 0xfb, 0x06, 0xb2,
+ 0x70, 0x8e, 0xd7, 0x09, 0xd7, 0x38, 0xd3, 0xf6, 0x81, 0x6c, 0xfb, 0xd8,
+ 0x5f, 0x21, 0x19, 0xe0, 0xfe, 0xa4, 0x6d, 0xff, 0xd1, 0xce, 0xfb, 0x80,
+ 0xa7, 0x0c, 0x77, 0xed, 0x0a, 0x50, 0x8d, 0xdf, 0x67, 0xd9, 0xc3, 0x75,
+ 0xfa, 0xdb, 0xab, 0xfe, 0xb1, 0x95, 0xeb, 0x7c, 0xee, 0x09, 0xbe, 0xbb,
+ 0x6a, 0xb2, 0x55, 0x22, 0x3c, 0xc5, 0x6b, 0xf2, 0xde, 0x02, 0xe7, 0x55,
+ 0x2b, 0xee, 0x7a, 0x1a, 0x57, 0x18, 0xee, 0x05, 0x2b, 0x9c, 0x62, 0x51,
+ 0xa6, 0x9f, 0x6c, 0x4f, 0x45, 0x22, 0x63, 0x78, 0x9a, 0x57, 0x84, 0xf0,
+ 0x50, 0x66, 0x3e, 0x26, 0xb7, 0xa3, 0x7d, 0x0a, 0xf8, 0xdf, 0x99, 0x20,
+ 0xda, 0x26, 0xc2, 0x43, 0xb7, 0x3b, 0xc2, 0xc3, 0xef, 0x38, 0xf8, 0x5e,
+ 0xa1, 0xeb, 0x26, 0x0b, 0x7f, 0x1f, 0xed, 0x5a, 0x66, 0x7d, 0xbe, 0xdd,
+ 0x75, 0x63, 0xe1, 0x6e, 0xa4, 0xe7, 0xdc, 0x97, 0xf3, 0x0e, 0x13, 0x0f,
+ 0xc5, 0x1c, 0xf8, 0x9a, 0xf6, 0xd7, 0xe4, 0x5b, 0x82, 0x6c, 0xe3, 0x18,
+ 0xe7, 0x60, 0x4b, 0xa7, 0xae, 0x15, 0x2a, 0xda, 0x32, 0x8d, 0x84, 0xd7,
+ 0x9a, 0xa8, 0xe6, 0x6f, 0xc4, 0x0f, 0x73, 0x8c, 0xd7, 0x4c, 0x8a, 0xfb,
+ 0x26, 0x5e, 0xef, 0x30, 0x86, 0x82, 0x50, 0x8c, 0x37, 0x85, 0x92, 0xba,
+ 0xdd, 0xa1, 0x1c, 0x69, 0x72, 0xf8, 0xb1, 0x2f, 0x62, 0xe7, 0xd1, 0x4e,
+ 0x2b, 0x6f, 0xbe, 0xd3, 0x65, 0xf7, 0xec, 0x4e, 0x56, 0xf3, 0xeb, 0xa9,
+ 0x2e, 0x6d, 0x56, 0x39, 0x9a, 0x22, 0xff, 0x59, 0x48, 0xf1, 0x73, 0x3c,
+ 0x9b, 0xb2, 0xce, 0x82, 0xfc, 0x32, 0x53, 0x43, 0xb6, 0x11, 0xd6, 0xc6,
+ 0x11, 0x8e, 0x3e, 0x64, 0xd1, 0xfa, 0xb3, 0xae, 0x58, 0xa1, 0x8c, 0x8a,
+ 0x53, 0x39, 0x08, 0x14, 0x09, 0x37, 0xb4, 0xf9, 0x5f, 0x46, 0x99, 0xfb,
+ 0xa1, 0x56, 0xa0, 0x67, 0x1e, 0x5a, 0x0b, 0x40, 0x2e, 0xe3, 0xbe, 0x0c,
+ 0xab, 0x17, 0xeb, 0xc0, 0x5a, 0x6d, 0x3b, 0xe1, 0x42, 0xde, 0xff, 0x15,
+ 0x54, 0x63, 0x37, 0xa2, 0xb2, 0xc1, 0x89, 0xf1, 0x0c, 0xe7, 0xe1, 0x63,
+ 0x5d, 0xf2, 0x28, 0x2a, 0x6e, 0x7b, 0x4f, 0x33, 0xe1, 0xa6, 0x0c, 0x3d,
+ 0x57, 0x22, 0x4c, 0x4a, 0xb1, 0x63, 0x6b, 0xec, 0x37, 0x66, 0xb2, 0xd1,
+ 0xde, 0x53, 0x19, 0x9d, 0x14, 0x58, 0xa0, 0x26, 0x31, 0x3a, 0xe7, 0xf4,
+ 0xa5, 0xd3, 0x51, 0xa4, 0xcb, 0xfc, 0xbc, 0xfb, 0x72, 0xd2, 0x9a, 0x3f,
+ 0xb2, 0x77, 0x89, 0xc3, 0x81, 0x65, 0x1d, 0x87, 0x50, 0x59, 0x68, 0xd3,
+ 0x10, 0x24, 0x4c, 0xc0, 0x35, 0x6c, 0x13, 0xf1, 0x7a, 0xe7, 0xe3, 0x5c,
+ 0x47, 0xfc, 0xa4, 0xeb, 0xe6, 0x29, 0xf6, 0xeb, 0x63, 0x5d, 0x1f, 0xa4,
+ 0x95, 0x64, 0x93, 0x04, 0xb9, 0x8e, 0xf8, 0xbf, 0x6f, 0x94, 0xfb, 0x08,
+ 0xbf, 0xe0, 0x3e, 0x02, 0xe5, 0x65, 0x65, 0xb8, 0x59, 0x78, 0xc5, 0xba,
+ 0x0c, 0xd5, 0x15, 0x44, 0xf3, 0xa5, 0x88, 0xd2, 0x53, 0x22, 0x8c, 0xb2,
+ 0x45, 0x50, 0x5d, 0x57, 0xb6, 0xe5, 0x65, 0x9f, 0xcd, 0xab, 0x5c, 0xc5,
+ 0x21, 0x51, 0x0b, 0x77, 0xf0, 0x3e, 0x34, 0xe7, 0x71, 0x6b, 0x4f, 0x9f,
+ 0xae, 0xff, 0xbc, 0x6b, 0x09, 0xd5, 0x16, 0x23, 0x4c, 0x1f, 0x78, 0xaf,
+ 0x8f, 0x6a, 0xd0, 0xec, 0xf1, 0x2a, 0x2e, 0xf1, 0x56, 0xe5, 0xc2, 0xdf,
+ 0xf9, 0x4c, 0xe2, 0x6b, 0x5d, 0x9b, 0x26, 0xf9, 0x8c, 0xe2, 0x4f, 0xba,
+ 0xd6, 0x4c, 0x2a, 0xa1, 0x8d, 0xb4, 0xee, 0x6e, 0xde, 0x5f, 0xa7, 0x39,
+ 0x67, 0x35, 0xa6, 0xbb, 0xd0, 0x75, 0x73, 0x96, 0x7b, 0xcb, 0xc7, 0xba,
+ 0xcc, 0x6c, 0x98, 0x31, 0xa8, 0x65, 0x2b, 0x89, 0x02, 0x55, 0xf3, 0xd7,
+ 0xd9, 0xbc, 0xba, 0x48, 0x1f, 0x87, 0xd2, 0x84, 0x76, 0xe2, 0xb6, 0x6e,
+ 0x56, 0x17, 0xd6, 0x20, 0xd5, 0xd4, 0x4d, 0x35, 0xa8, 0xdf, 0xb7, 0x36,
+ 0xd3, 0x8d, 0x09, 0xd2, 0xe1, 0xa6, 0x52, 0xd0, 0xd7, 0x9d, 0x51, 0x31,
+ 0x50, 0xe2, 0x7a, 0xb3, 0xd2, 0xb5, 0x6b, 0x72, 0xaa, 0x5a, 0xff, 0xf6,
+ 0x53, 0xcd, 0x4a, 0x76, 0x91, 0xb1, 0x6d, 0xae, 0xb5, 0x40, 0x34, 0x0b,
+ 0x7b, 0x5e, 0x37, 0xad, 0x73, 0xfd, 0xe8, 0x77, 0xcd, 0xd0, 0x42, 0xb6,
+ 0x85, 0xbb, 0xf1, 0xf8, 0x94, 0xcf, 0x08, 0xe8, 0x7e, 0x74, 0x76, 0x9c,
+ 0xa2, 0x67, 0xdb, 0xf1, 0xf8, 0xe1, 0x5b, 0x90, 0xff, 0x23, 0x27, 0x2e,
+ 0x66, 0x92, 0x58, 0xda, 0xf1, 0x55, 0x9c, 0xd9, 0x20, 0xe3, 0xef, 0x32,
+ 0x5e, 0x5c, 0x22, 0xfe, 0x0c, 0x6b, 0x8e, 0x7f, 0xcf, 0xfe, 0x90, 0x5b,
+ 0xb8, 0xc7, 0x35, 0xc6, 0x9e, 0xbf, 0xe7, 0x06, 0xf7, 0xde, 0x0c, 0xd4,
+ 0x10, 0x0e, 0x0a, 0x13, 0xcd, 0x6a, 0x86, 0xcf, 0x38, 0x05, 0x7c, 0x9c,
+ 0x2b, 0xa7, 0x89, 0x27, 0x47, 0xa9, 0xc5, 0xe7, 0x24, 0x7e, 0x9c, 0xa5,
+ 0x73, 0x14, 0x03, 0xd8, 0x07, 0xdc, 0x97, 0x43, 0x96, 0x1d, 0x5c, 0xbb,
+ 0xf6, 0x7e, 0x0f, 0xef, 0xf1, 0x1f, 0xcf, 0x72, 0x6c, 0x14, 0x54, 0xbb,
+ 0x84, 0x90, 0x9c, 0x5d, 0x82, 0x9e, 0xd9, 0xed, 0x74, 0x5d, 0x45, 0x5f,
+ 0xd5, 0xd7, 0x42, 0x05, 0x8f, 0x87, 0xf1, 0x49, 0x2e, 0x63, 0xff, 0x8e,
+ 0x5c, 0xfd, 0xed, 0x16, 0x8d, 0xe3, 0x84, 0x1d, 0x11, 0xb7, 0xf2, 0xb0,
+ 0xda, 0xf1, 0xef, 0xe2, 0xe5, 0x72, 0xca, 0xa2, 0x61, 0x37, 0xcd, 0xc5,
+ 0xb2, 0x79, 0xce, 0x4c, 0xdd, 0xc9, 0xf2, 0x0b, 0xf8, 0x7e, 0x48, 0xfa,
+ 0x98, 0xa4, 0x67, 0x1e, 0x27, 0x1e, 0xca, 0xc4, 0x5b, 0xb6, 0xf4, 0x5d,
+ 0x1a, 0xc3, 0xf7, 0x40, 0xfa, 0x32, 0x14, 0x67, 0xf5, 0x6c, 0xe6, 0x08,
+ 0xe5, 0xcb, 0x5a, 0x8a, 0x45, 0x67, 0xe3, 0xf7, 0x62, 0x6d, 0x4e, 0x49,
+ 0x1a, 0x14, 0x2e, 0x53, 0x7e, 0x08, 0xa7, 0xce, 0x36, 0xfc, 0x36, 0xd9,
+ 0x70, 0x0b, 0x61, 0x80, 0x70, 0xe8, 0x1c, 0x8d, 0x37, 0x9c, 0x32, 0x1e,
+ 0x9b, 0x90, 0x70, 0x8e, 0xf7, 0x80, 0x85, 0xfd, 0xbc, 0x01, 0x1e, 0x3b,
+ 0xff, 0xbd, 0x8e, 0xea, 0xba, 0x70, 0x82, 0xb2, 0xaa, 0x51, 0x4f, 0xb8,
+ 0xbd, 0xd0, 0xf9, 0x08, 0xf6, 0x53, 0x7d, 0xbf, 0x35, 0x46, 0x32, 0x69,
+ 0x8c, 0x53, 0xbd, 0xd1, 0x36, 0x74, 0x01, 0x7f, 0x67, 0x56, 0x78, 0x1f,
+ 0x5d, 0x84, 0x13, 0x17, 0xf0, 0x99, 0x29, 0xa9, 0xea, 0xe9, 0x19, 0xa8,
+ 0x95, 0x73, 0x68, 0x1b, 0xbe, 0x82, 0x0f, 0x4d, 0xde, 0x63, 0x97, 0x25,
+ 0x89, 0x30, 0x60, 0xd8, 0xef, 0x44, 0x00, 0x95, 0x80, 0x84, 0x5b, 0x35,
+ 0xee, 0x49, 0x2b, 0xc3, 0x4f, 0x13, 0x96, 0x7f, 0x5f, 0xb4, 0x0d, 0x7e,
+ 0x8c, 0x33, 0x66, 0xbe, 0x91, 0xd7, 0x15, 0x48, 0xdc, 0xd8, 0x76, 0xba,
+ 0x06, 0x4a, 0x8f, 0x4b, 0xa8, 0x89, 0x66, 0xe9, 0xaf, 0xcd, 0x33, 0x81,
+ 0xcf, 0x4c, 0x35, 0xf2, 0x19, 0xe1, 0x20, 0x35, 0x38, 0x4d, 0x3e, 0x31,
+ 0x88, 0x79, 0xda, 0xfe, 0x81, 0xf8, 0xd7, 0x88, 0x06, 0xc6, 0x7d, 0x86,
+ 0x7b, 0x0f, 0xd1, 0xf6, 0x53, 0xc2, 0x01, 0x5b, 0x63, 0x17, 0xcc, 0xe4,
+ 0x42, 0xeb, 0xfc, 0x5e, 0x9d, 0xdd, 0xfb, 0x66, 0x5f, 0xb9, 0x1b, 0x9b,
+ 0xd2, 0x4e, 0x92, 0xd3, 0x3c, 0x5e, 0x73, 0x51, 0x0c, 0x66, 0x8c, 0x53,
+ 0xb9, 0x9e, 0x4a, 0x33, 0xc7, 0xac, 0x0a, 0xec, 0xa2, 0xb8, 0xb0, 0xd3,
+ 0xca, 0x05, 0xf0, 0x2c, 0x5e, 0xd1, 0x81, 0x2b, 0x53, 0xff, 0xc3, 0x43,
+ 0xfa, 0x5b, 0xad, 0x2e, 0x87, 0x08, 0x66, 0x0c, 0xd1, 0xa0, 0x4b, 0xf8,
+ 0xb8, 0x53, 0xe9, 0x71, 0x48, 0xc3, 0xb8, 0x31, 0x66, 0x98, 0x5e, 0x55,
+ 0xed, 0x6f, 0x17, 0x91, 0xbe, 0x92, 0x88, 0xa2, 0xae, 0xe4, 0x95, 0xeb,
+ 0x4a, 0xed, 0xb2, 0xa7, 0x64, 0xb8, 0xfd, 0x2b, 0xee, 0xa5, 0xba, 0x65,
+ 0x07, 0xd5, 0xb6, 0x5e, 0xaa, 0xaf, 0x15, 0xb2, 0xc7, 0x1a, 0x92, 0x7f,
+ 0x88, 0xe2, 0x80, 0x0e, 0x67, 0x66, 0x1b, 0x5c, 0x99, 0xb0, 0x7f, 0x37,
+ 0x76, 0x20, 0x19, 0xb4, 0xb1, 0xad, 0x4c, 0xba, 0xaa, 0xed, 0x64, 0x2c,
+ 0x73, 0x2f, 0xce, 0xe4, 0x19, 0x9f, 0x27, 0xb0, 0x31, 0xcd, 0xbf, 0xe1,
+ 0x79, 0x39, 0xae, 0xe3, 0x28, 0xd5, 0x4e, 0xee, 0x8e, 0x66, 0xd2, 0x43,
+ 0x0b, 0x46, 0xca, 0x82, 0x4d, 0x90, 0x74, 0x01, 0xcf, 0xd1, 0x4e, 0x19,
+ 0xfb, 0x66, 0x28, 0x91, 0x50, 0x9e, 0x72, 0x92, 0x9d, 0xef, 0x26, 0x1b,
+ 0xf2, 0xaa, 0x5e, 0xfa, 0x1d, 0xe0, 0x73, 0x47, 0x64, 0x93, 0x3f, 0xe9,
+ 0x6a, 0xb7, 0x62, 0xcd, 0x2f, 0xa8, 0xc6, 0xf9, 0x15, 0xf1, 0xc2, 0xb2,
+ 0xd0, 0x51, 0x37, 0x3e, 0x5f, 0x13, 0xae, 0xb9, 0xa3, 0x0e, 0x41, 0x9a,
+ 0x33, 0x58, 0xdd, 0x23, 0x13, 0x58, 0x13, 0xeb, 0x40, 0x31, 0x27, 0xaa,
+ 0x18, 0x6b, 0x44, 0xf1, 0x62, 0x35, 0xf6, 0x53, 0xed, 0xef, 0x53, 0x37,
+ 0x22, 0xe3, 0xaf, 0x78, 0xde, 0x89, 0x73, 0x0d, 0x00, 0xcf, 0x00, 0x61,
+ 0xa8, 0xd1, 0xf4, 0x57, 0x90, 0x5f, 0x08, 0xf7, 0x3d, 0x71, 0x3e, 0x9f,
+ 0x49, 0x21, 0x4a, 0x5d, 0x8d, 0x86, 0xe5, 0xbd, 0xf8, 0xb8, 0x91, 0xf1,
+ 0xaf, 0x97, 0x62, 0x83, 0x8c, 0xdd, 0x33, 0x01, 0xeb, 0x5c, 0x04, 0xc5,
+ 0xc0, 0x2a, 0xcd, 0xd7, 0xd2, 0xfa, 0x65, 0x34, 0xb2, 0x4c, 0xfe, 0x6f,
+ 0x34, 0x92, 0xcd, 0x12, 0xe6, 0xc9, 0xa5, 0x07, 0xf0, 0x4a, 0x9a, 0xe7,
+ 0x0d, 0x27, 0x35, 0xe1, 0xe7, 0x9e, 0xbc, 0x25, 0x13, 0x63, 0x86, 0xd7,
+ 0xf0, 0x5a, 0xb1, 0xc9, 0x5e, 0x27, 0xc0, 0xbd, 0xa2, 0xff, 0xe0, 0x5a,
+ 0x1a, 0xe5, 0xc7, 0xd5, 0x54, 0x77, 0x46, 0xa1, 0x7e, 0xa3, 0x42, 0xfa,
+ 0xe0, 0x1e, 0xf5, 0x12, 0xc2, 0xbc, 0x70, 0xbf, 0x1a, 0xe7, 0x73, 0xc8,
+ 0xe6, 0x0e, 0x59, 0x37, 0x4d, 0x57, 0xa7, 0xea, 0x7f, 0x0f, 0x6c, 0x87,
+ 0x5e, 0xde, 0xeb, 0x70, 0xef, 0xee, 0xf4, 0x62, 0x1f, 0xe5, 0xc0, 0x67,
+ 0xd3, 0x6d, 0x06, 0xd7, 0x7e, 0x60, 0x1c, 0x2a, 0x52, 0xf4, 0xec, 0x50,
+ 0x1d, 0x9f, 0x09, 0xda, 0x55, 0xde, 0x06, 0x47, 0xe6, 0xb6, 0x3a, 0xae,
+ 0x37, 0x6a, 0xa8, 0x4e, 0x1e, 0x49, 0x33, 0xbd, 0xdc, 0x7b, 0x33, 0xcd,
+ 0x9d, 0x71, 0xf5, 0xf2, 0x5a, 0xb2, 0x8b, 0x66, 0x9d, 0xe5, 0x18, 0xc0,
+ 0x93, 0x34, 0x36, 0x54, 0x66, 0x59, 0x7e, 0xb7, 0x8e, 0xfb, 0x9d, 0x7b,
+ 0x48, 0xbf, 0x0d, 0x59, 0x7b, 0x9e, 0x6c, 0x79, 0x10, 0x4b, 0x46, 0x5f,
+ 0xa8, 0xb3, 0x6b, 0x1f, 0xae, 0xcb, 0x87, 0xb0, 0x27, 0x1d, 0xc0, 0x4c,
+ 0xba, 0xcd, 0xff, 0x12, 0x9c, 0xd5, 0xbc, 0xca, 0xe7, 0x88, 0xe7, 0xc7,
+ 0x04, 0x30, 0x7d, 0xf5, 0x3b, 0xcb, 0xc7, 0xee, 0x99, 0x1e, 0xb7, 0x30,
+ 0xbf, 0x8c, 0x7c, 0xc0, 0xae, 0x63, 0x28, 0x56, 0x78, 0x1e, 0x25, 0xbd,
+ 0xbe, 0x4f, 0x7a, 0x75, 0x90, 0x5e, 0x5f, 0xd2, 0xfe, 0x92, 0x31, 0x8b,
+ 0x7b, 0x57, 0xdc, 0xcb, 0xfb, 0x43, 0x06, 0x81, 0x16, 0x6b, 0x4c, 0x26,
+ 0xee, 0xc4, 0xeb, 0x94, 0x07, 0x6b, 0x28, 0xfe, 0x9d, 0x4a, 0x9b, 0xab,
+ 0xe7, 0x62, 0x6d, 0xa9, 0xf7, 0x29, 0x4f, 0x1b, 0x7f, 0xa8, 0x68, 0x67,
+ 0xc8, 0x4f, 0xb3, 0x13, 0x7f, 0x8a, 0x33, 0x8d, 0x6d, 0xfe, 0xb7, 0x60,
+ 0xb8, 0x9f, 0x88, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0xcb, 0xff, 0x0b,
+ 0x39, 0x59, 0x1c, 0x92, 0xda, 0x76, 0xf9, 0x25, 0xfc, 0x15, 0xce, 0x5c,
+ 0x17, 0xd6, 0x5e, 0x02, 0x8f, 0xb1, 0xeb, 0xf1, 0xf0, 0xec, 0xfd, 0x7c,
+ 0x1e, 0x2a, 0x48, 0xe9, 0xcc, 0xde, 0xc7, 0x4a, 0xf3, 0xbe, 0x9b, 0x40,
+ 0x7e, 0x03, 0xd5, 0xd2, 0xd6, 0x39, 0x54, 0x78, 0x9e, 0x26, 0xbf, 0x88,
+ 0x8e, 0xf1, 0xf8, 0x63, 0x5d, 0x6a, 0x21, 0x04, 0x89, 0x30, 0x0e, 0x61,
+ 0x84, 0x1e, 0x3e, 0x9f, 0xf1, 0x74, 0x3a, 0x48, 0xb9, 0xa0, 0xad, 0x2f,
+ 0x2a, 0xbe, 0x0d, 0x1b, 0x03, 0x70, 0x9e, 0x3b, 0x46, 0x79, 0x4e, 0x49,
+ 0x3d, 0x8d, 0xb6, 0x7e, 0xaf, 0xb8, 0x1b, 0xa9, 0xc6, 0xb6, 0xc1, 0xa3,
+ 0x08, 0x13, 0x66, 0x50, 0xa2, 0x67, 0x60, 0xcf, 0xb3, 0xb4, 0x20, 0x51,
+ 0x9d, 0xc8, 0x71, 0x26, 0x8d, 0xa3, 0x7e, 0x09, 0x37, 0x74, 0xa8, 0x97,
+ 0xa7, 0x31, 0x6f, 0x2f, 0xf6, 0x98, 0xd5, 0x05, 0x1a, 0x2f, 0xf9, 0x09,
+ 0xdb, 0xd4, 0xc0, 0x49, 0xb5, 0xbf, 0xa4, 0x6f, 0xc3, 0xd6, 0x34, 0xe7,
+ 0x69, 0x92, 0x0b, 0xf9, 0x66, 0x5f, 0x64, 0x1b, 0x86, 0x0a, 0x01, 0xec,
+ 0xcf, 0x86, 0xf7, 0xee, 0x26, 0x5c, 0x37, 0x56, 0x0e, 0x87, 0x36, 0x8b,
+ 0x00, 0xe9, 0x9b, 0xea, 0xff, 0xa6, 0x20, 0xd5, 0xc9, 0x7e, 0xfa, 0xb7,
+ 0xeb, 0x99, 0x53, 0x54, 0xcf, 0xbc, 0x4e, 0xbe, 0xe6, 0xad, 0xd6, 0xaa,
+ 0x4b, 0xf3, 0x26, 0xe6, 0x62, 0xeb, 0x71, 0xc9, 0xd2, 0x59, 0x90, 0x6c,
+ 0x8c, 0x73, 0x08, 0x9f, 0x8d, 0x71, 0x8b, 0xcd, 0x63, 0x86, 0xfb, 0xc1,
+ 0xce, 0x20, 0xe5, 0x34, 0xc6, 0x9c, 0x8e, 0x3f, 0x92, 0x48, 0x1e, 0x33,
+ 0xea, 0x0e, 0xac, 0x8b, 0xed, 0xc0, 0x90, 0xf6, 0x5d, 0xd4, 0x34, 0x71,
+ 0x3c, 0x92, 0x8d, 0x06, 0x9a, 0xf7, 0x42, 0x67, 0x2f, 0xc2, 0x4f, 0x31,
+ 0x3e, 0xfa, 0x19, 0xe1, 0x23, 0xf6, 0x5d, 0x9e, 0xbf, 0x51, 0x5f, 0x46,
+ 0xb8, 0xa2, 0xbe, 0xd3, 0xce, 0xf3, 0x37, 0x16, 0xf8, 0x4c, 0x26, 0xa8,
+ 0x36, 0x85, 0xe7, 0xdd, 0x95, 0x3a, 0x9e, 0xa0, 0x18, 0x93, 0x58, 0xee,
+ 0x02, 0x16, 0xf0, 0xd9, 0x63, 0xbb, 0x8e, 0x61, 0x7e, 0x97, 0x14, 0x04,
+ 0x66, 0xe3, 0x64, 0x1f, 0xff, 0xea, 0x8c, 0x51, 0xa8, 0x7a, 0x36, 0x94,
+ 0xfb, 0x27, 0x07, 0xcc, 0x24, 0xbf, 0x33, 0xe0, 0xa8, 0xf3, 0x52, 0xbc,
+ 0x0d, 0x56, 0x20, 0x79, 0x39, 0x2e, 0x4b, 0xea, 0xbc, 0xdc, 0x59, 0xd6,
+ 0x47, 0x38, 0xbe, 0x5b, 0xba, 0x70, 0xd2, 0x33, 0xbb, 0x26, 0x95, 0xe1,
+ 0xdd, 0x68, 0x1b, 0xfa, 0x40, 0xd4, 0x5a, 0x3b, 0x97, 0xd3, 0xed, 0x48,
+ 0x2d, 0xd6, 0x9d, 0x1b, 0xae, 0x64, 0x57, 0x13, 0x1d, 0xe7, 0x4c, 0x5c,
+ 0xb7, 0xc6, 0xda, 0xdf, 0x9a, 0x6e, 0xff, 0x73, 0x9a, 0x9b, 0xbf, 0x3f,
+ 0xe0, 0xe5, 0x33, 0x93, 0xc7, 0xb3, 0x2f, 0x9a, 0xd1, 0x85, 0xb6, 0x7c,
+ 0x4e, 0x90, 0xef, 0x07, 0x75, 0x07, 0x9a, 0xd5, 0xc8, 0xe5, 0x7e, 0xfa,
+ 0xfd, 0xb7, 0x05, 0x42, 0xfb, 0x2b, 0x07, 0xf1, 0xab, 0xbc, 0x8e, 0xc7,
+ 0x28, 0x0f, 0x34, 0xa8, 0x8a, 0x3f, 0xcf, 0xfb, 0xd7, 0x31, 0x9b, 0xff,
+ 0x9b, 0xf2, 0xe4, 0x87, 0x8d, 0x7e, 0xab, 0xc6, 0xb0, 0xf9, 0x2b, 0x10,
+ 0x7f, 0x03, 0x5e, 0xf6, 0x85, 0xc5, 0xe4, 0x17, 0x7b, 0xc9, 0x5f, 0x1f,
+ 0x23, 0x5b, 0xa3, 0x0a, 0x9e, 0xfc, 0x40, 0xd9, 0x0b, 0xf2, 0xd7, 0xb1,
+ 0x34, 0xcb, 0x3f, 0xe8, 0x1b, 0x18, 0xe5, 0xb8, 0x6b, 0xf5, 0x55, 0xb5,
+ 0x90, 0x83, 0xe3, 0xae, 0x15, 0x4f, 0x8d, 0x90, 0xe3, 0xd7, 0x75, 0x4c,
+ 0xd7, 0x48, 0x39, 0x1c, 0xf4, 0xf0, 0x79, 0x7e, 0x02, 0x87, 0x03, 0x9a,
+ 0x9d, 0x2b, 0xe7, 0x28, 0x1f, 0x5d, 0x22, 0x3a, 0xf6, 0xc7, 0x9a, 0x91,
+ 0xa2, 0x7c, 0x94, 0x51, 0x6d, 0x5b, 0x52, 0x67, 0x19, 0x63, 0xfe, 0x82,
+ 0x30, 0xa6, 0x12, 0x72, 0x49, 0x6d, 0xc3, 0x27, 0xb1, 0xcd, 0x3c, 0xd3,
+ 0xc8, 0x36, 0xe5, 0xc2, 0xe1, 0xf6, 0x59, 0xb3, 0x12, 0x60, 0x7e, 0x25,
+ 0xbc, 0xa8, 0x91, 0xcd, 0x5c, 0x17, 0x0e, 0xbe, 0x48, 0x39, 0x75, 0xa6,
+ 0xaa, 0x8f, 0x70, 0x61, 0xde, 0x1e, 0x63, 0x2c, 0xeb, 0x68, 0x0a, 0x6a,
+ 0xa2, 0x80, 0x3f, 0xa6, 0xef, 0xad, 0xc1, 0x4b, 0x55, 0x5b, 0x5d, 0x36,
+ 0xfb, 0xdf, 0xbd, 0xd5, 0x77, 0x6c, 0xac, 0x67, 0x42, 0x85, 0xfb, 0xe9,
+ 0x37, 0xcf, 0x19, 0xe0, 0xb3, 0x2d, 0x7c, 0xd6, 0xca, 0xb3, 0xb5, 0xb3,
+ 0x86, 0xfd, 0xc5, 0xcf, 0xef, 0x15, 0xac, 0x1b, 0xe3, 0xbe, 0x30, 0xf7,
+ 0x68, 0x24, 0xec, 0xbe, 0xfa, 0xde, 0x03, 0x7f, 0xf6, 0xe0, 0xd6, 0x31,
+ 0xee, 0x45, 0x9c, 0xb8, 0x59, 0xc6, 0x3f, 0x51, 0x1e, 0x96, 0xd9, 0xe7,
+ 0xc9, 0xd7, 0x7f, 0xd4, 0x75, 0x6a, 0x92, 0x73, 0xea, 0xdb, 0x5d, 0x9b,
+ 0xd2, 0xf3, 0x3a, 0xbe, 0xca, 0xd3, 0xe9, 0x7b, 0x28, 0xee, 0x64, 0xd2,
+ 0xca, 0x70, 0x44, 0xb2, 0xf6, 0xd5, 0x52, 0x25, 0xf1, 0x15, 0x2a, 0xd2,
+ 0x78, 0xbe, 0x5e, 0xf4, 0x8f, 0x85, 0xa8, 0xb6, 0xf1, 0xfb, 0x1e, 0x38,
+ 0x60, 0x52, 0xae, 0x70, 0xe2, 0xe9, 0xd1, 0xb0, 0xf6, 0x26, 0xe1, 0x9d,
+ 0x67, 0x46, 0x4d, 0xf3, 0x4d, 0x0d, 0x7f, 0xd2, 0x40, 0x35, 0x72, 0xbb,
+ 0x50, 0x12, 0x84, 0x0d, 0x42, 0xeb, 0x45, 0x5b, 0xb0, 0x00, 0xe5, 0xf4,
+ 0x4e, 0x9a, 0xef, 0x50, 0x11, 0x78, 0xb1, 0xe8, 0xc1, 0x0b, 0x63, 0xdc,
+ 0xfb, 0xf3, 0xa0, 0xf4, 0x54, 0x93, 0x6f, 0xdb, 0x81, 0x10, 0xc5, 0x58,
+ 0x19, 0xbd, 0x87, 0x12, 0xb8, 0xf5, 0x80, 0x40, 0x34, 0x92, 0x40, 0xcf,
+ 0xa1, 0x7a, 0xac, 0x1f, 0x93, 0x71, 0x31, 0x5e, 0x8f, 0xdb, 0x9e, 0x9a,
+ 0xe7, 0xe3, 0x9d, 0x6a, 0x9d, 0x27, 0x5b, 0xe7, 0xd8, 0x8e, 0x66, 0x39,
+ 0x66, 0x53, 0xbe, 0xc8, 0x72, 0x0c, 0x34, 0xcd, 0x60, 0xa7, 0xdd, 0xe7,
+ 0x78, 0x8e, 0xf2, 0xc7, 0x13, 0x9d, 0x6a, 0x30, 0xe8, 0xd0, 0x71, 0xc3,
+ 0x44, 0xe5, 0xdb, 0x0d, 0x30, 0x8f, 0xf3, 0x1e, 0xc6, 0xa7, 0xed, 0xa6,
+ 0x79, 0x6b, 0x3c, 0x72, 0x99, 0x2a, 0x3b, 0xf2, 0xa9, 0xb7, 0xc9, 0xa7,
+ 0x5a, 0xf0, 0x44, 0x76, 0x7e, 0xaf, 0x4b, 0xed, 0xbf, 0x20, 0x19, 0x3b,
+ 0xfc, 0x30, 0x3f, 0xa9, 0xd5, 0xcd, 0x4f, 0x5d, 0x7a, 0x24, 0xb8, 0x5d,
+ 0xf0, 0x19, 0x11, 0xee, 0x89, 0x9b, 0xe6, 0xd9, 0xb8, 0x69, 0x16, 0xe3,
+ 0x86, 0x7b, 0xd9, 0x0a, 0x3f, 0x0e, 0x2d, 0xe5, 0x77, 0x0d, 0xc2, 0xc9,
+ 0x66, 0xb2, 0x2f, 0xcf, 0x52, 0x35, 0xb8, 0x91, 0xea, 0x2b, 0x83, 0x82,
+ 0x5c, 0x68, 0xa1, 0xd2, 0x0f, 0xb4, 0xf8, 0xf6, 0x8f, 0x36, 0xe1, 0x99,
+ 0xb9, 0xdf, 0xe5, 0xe3, 0x39, 0x56, 0x3f, 0xed, 0x13, 0x0d, 0xab, 0x1b,
+ 0x10, 0x49, 0x6e, 0x01, 0xf7, 0x46, 0xf9, 0x4c, 0xaa, 0x81, 0xdb, 0xe2,
+ 0x83, 0xd8, 0x3a, 0xc6, 0xfb, 0x6b, 0x3f, 0xef, 0xfa, 0x64, 0xcc, 0xfc,
+ 0x5b, 0x37, 0xd1, 0xbf, 0xba, 0xb3, 0x2d, 0xe5, 0xb1, 0xde, 0x55, 0x3a,
+ 0x49, 0x75, 0x40, 0x23, 0xca, 0x33, 0x6a, 0x65, 0xb1, 0x48, 0xbe, 0xe9,
+ 0x45, 0x24, 0xd8, 0x4c, 0xb1, 0x6a, 0x8e, 0x7c, 0x77, 0xa6, 0xcc, 0x75,
+ 0xc0, 0x2f, 0xbb, 0xcc, 0x89, 0x45, 0x98, 0x9e, 0xa3, 0xb9, 0xb2, 0x6a,
+ 0xcf, 0x47, 0x84, 0xf3, 0xea, 0x74, 0xb3, 0xc1, 0xa3, 0x47, 0x4e, 0xb7,
+ 0x09, 0x09, 0x97, 0x97, 0x9b, 0x66, 0x6f, 0xa7, 0x3a, 0x5c, 0x2f, 0x30,
+ 0xe4, 0xd0, 0xd5, 0x44, 0xbb, 0x84, 0xaf, 0x06, 0x11, 0xe9, 0x39, 0x8b,
+ 0x48, 0xff, 0x39, 0x8a, 0x61, 0xcf, 0x96, 0xf9, 0x9c, 0xef, 0x23, 0xf8,
+ 0xdb, 0xb1, 0x85, 0x38, 0x3e, 0xf3, 0x50, 0xb5, 0x27, 0x06, 0xcf, 0x8d,
+ 0x2b, 0x74, 0x1c, 0x26, 0xbd, 0x9e, 0xd4, 0x6a, 0x28, 0xae, 0xcb, 0x70,
+ 0xb4, 0x42, 0x6e, 0xa4, 0x3a, 0x21, 0xf6, 0xb8, 0x69, 0x2e, 0x6b, 0xb5,
+ 0x6b, 0x9e, 0x65, 0xb3, 0xd7, 0xbe, 0xa3, 0x30, 0xdf, 0xef, 0x09, 0x92,
+ 0xfe, 0xda, 0x52, 0x5b, 0xc5, 0x49, 0xd3, 0xf8, 0x43, 0x41, 0x3c, 0xdf,
+ 0x56, 0x0f, 0x0f, 0xf3, 0x2d, 0x63, 0xe7, 0x04, 0xf7, 0xe1, 0x58, 0x6f,
+ 0xf0, 0xf4, 0xc4, 0x79, 0x9f, 0x9c, 0x75, 0x54, 0xf1, 0xac, 0x8b, 0x53,
+ 0x4c, 0x14, 0x3e, 0xc2, 0x53, 0x86, 0xbb, 0x9b, 0xf2, 0x53, 0xed, 0x18,
+ 0xbf, 0x2f, 0xe1, 0xc5, 0x63, 0x14, 0x37, 0x2e, 0x69, 0x75, 0xd8, 0xdf,
+ 0xc8, 0xb6, 0xc3, 0x74, 0x72, 0xcf, 0x70, 0x1b, 0xee, 0xe5, 0x77, 0x4e,
+ 0xca, 0xbf, 0x6b, 0x9d, 0x0d, 0xa4, 0x6b, 0x84, 0x0d, 0x98, 0x8e, 0xf9,
+ 0xf5, 0x7b, 0xb0, 0x78, 0x94, 0xf5, 0x78, 0xac, 0x2b, 0x48, 0x32, 0x7a,
+ 0x82, 0xec, 0xc2, 0xa1, 0x77, 0x43, 0x26, 0x5b, 0x5c, 0x1b, 0xbf, 0x76,
+ 0x0e, 0x75, 0xe8, 0x9c, 0x44, 0xf5, 0x9d, 0xc4, 0xfb, 0x79, 0x4a, 0xe2,
+ 0x88, 0xb8, 0x76, 0xce, 0x7c, 0x3d, 0xf7, 0x13, 0x8d, 0x19, 0x3b, 0x2f,
+ 0x1d, 0xa6, 0xbc, 0xf4, 0x4a, 0x8e, 0x7d, 0xe4, 0x17, 0x96, 0x8f, 0x38,
+ 0x28, 0xd6, 0xae, 0x49, 0x87, 0x70, 0x4e, 0x83, 0x5a, 0x83, 0x18, 0xd1,
+ 0x1d, 0xe9, 0xe9, 0xae, 0x62, 0x3e, 0x17, 0xc5, 0xff, 0x99, 0x9c, 0x32,
+ 0x68, 0xf5, 0x9f, 0x54, 0xa5, 0x8f, 0x3f, 0x79, 0xef, 0x3f, 0xa8, 0x0f,
+ 0xa1, 0x61, 0x25, 0x70, 0x7e, 0x94, 0xfb, 0x55, 0xbc, 0xcf, 0x35, 0x2c,
+ 0xae, 0xf0, 0x7b, 0x61, 0xb5, 0x43, 0x78, 0x2f, 0xce, 0xef, 0x5b, 0xb1,
+ 0xef, 0x3d, 0x0c, 0xf6, 0xbd, 0x06, 0x1a, 0xfb, 0xc9, 0x68, 0x38, 0xd4,
+ 0x43, 0x7e, 0x33, 0x00, 0xeb, 0xbc, 0x90, 0x36, 0x6b, 0xf7, 0xc7, 0x93,
+ 0xa7, 0xaa, 0xfb, 0x5b, 0x91, 0xea, 0xde, 0x5c, 0xb4, 0xd0, 0x23, 0x2e,
+ 0x15, 0x98, 0xa6, 0xb7, 0x89, 0xa6, 0x6e, 0xf1, 0xe1, 0xec, 0x3a, 0x71,
+ 0x71, 0xb6, 0x57, 0x9c, 0x2d, 0x70, 0x4c, 0xfe, 0x79, 0xd7, 0xae, 0x1c,
+ 0xe7, 0xb3, 0x3b, 0xc5, 0xbb, 0xf9, 0x0d, 0xe2, 0x42, 0xa1, 0x5f, 0x7c,
+ 0x34, 0x6b, 0xe0, 0xfe, 0x78, 0x2f, 0x0a, 0x63, 0xf0, 0xbb, 0xf5, 0xfb,
+ 0xc5, 0xa5, 0xbc, 0xdd, 0x27, 0xbc, 0x50, 0x68, 0xf1, 0x15, 0xd2, 0x5c,
+ 0x03, 0x1f, 0xa3, 0x1a, 0x78, 0x91, 0xef, 0x99, 0xc9, 0x80, 0xaf, 0x34,
+ 0xa9, 0x0c, 0xde, 0x23, 0x4c, 0xf3, 0xb6, 0xd8, 0x69, 0xd6, 0xa1, 0xf9,
+ 0x5a, 0xcc, 0xc6, 0x07, 0x3b, 0x49, 0x1e, 0x9b, 0x29, 0xb7, 0x4c, 0x6b,
+ 0x6d, 0x55, 0x2c, 0xc2, 0xb6, 0xce, 0xbc, 0x72, 0xae, 0xe6, 0xfd, 0xa7,
+ 0x21, 0x38, 0x3b, 0x81, 0xbd, 0xe9, 0xcf, 0x79, 0xbd, 0x44, 0xbc, 0x1a,
+ 0xae, 0x21, 0x7c, 0x4c, 0xbc, 0xbe, 0x3e, 0xfa, 0xf9, 0x7e, 0x9e, 0x93,
+ 0xc6, 0xee, 0x4a, 0x87, 0x53, 0x47, 0x84, 0x52, 0x29, 0xd8, 0xfb, 0x79,
+ 0x9a, 0x57, 0x52, 0x4e, 0x8f, 0x50, 0x1d, 0xd1, 0x2a, 0xd9, 0xbc, 0x26,
+ 0xaa, 0xbc, 0xde, 0x44, 0xbc, 0x5e, 0x2c, 0x70, 0x7d, 0xfe, 0x76, 0xd7,
+ 0x1b, 0xa3, 0x63, 0x66, 0x3d, 0xd5, 0xff, 0x75, 0x6a, 0xb7, 0xb8, 0x40,
+ 0x3c, 0x7f, 0x48, 0x3c, 0x7f, 0x5c, 0xb8, 0x53, 0x7c, 0x44, 0x7c, 0x5e,
+ 0x2c, 0xf0, 0x1e, 0x9e, 0x5b, 0x7c, 0x98, 0xb3, 0x79, 0xfc, 0xf0, 0x2a,
+ 0x8f, 0x41, 0xdf, 0xfe, 0x74, 0x93, 0xef, 0xd1, 0x49, 0xbf, 0x6f, 0xcf,
+ 0xa4, 0x69, 0x7e, 0xa8, 0x49, 0x3e, 0xe6, 0xeb, 0x55, 0xed, 0x8b, 0x7c,
+ 0xdd, 0x4c, 0x7c, 0xf1, 0xfe, 0xeb, 0x6f, 0xeb, 0x70, 0x9e, 0xaf, 0xc7,
+ 0xac, 0x73, 0x6c, 0xf6, 0x19, 0xa9, 0x7a, 0xde, 0x83, 0x25, 0xbe, 0x7c,
+ 0x74, 0xfd, 0x95, 0x7f, 0xcd, 0xd7, 0xe0, 0x05, 0xd2, 0x5f, 0xb1, 0xca,
+ 0x57, 0xfd, 0xbf, 0xc9, 0x17, 0xd5, 0xba, 0x63, 0xcc, 0x57, 0xa3, 0xfe,
+ 0xc6, 0x98, 0x49, 0xfa, 0x92, 0xac, 0x77, 0xc1, 0x8a, 0xd9, 0x1d, 0x78,
+ 0x25, 0xc6, 0xef, 0xc7, 0x45, 0x42, 0x47, 0x28, 0x9e, 0xce, 0x96, 0x3d,
+ 0xa2, 0xc6, 0xda, 0x87, 0xc5, 0x1b, 0xb5, 0x44, 0xd3, 0xe1, 0x19, 0x7e,
+ 0xff, 0x0b, 0x1a, 0x61, 0x01, 0x3f, 0xbf, 0x37, 0x37, 0x0d, 0xee, 0x97,
+ 0xf5, 0x8a, 0x86, 0x22, 0xef, 0xbb, 0x6e, 0x10, 0xbe, 0x22, 0x9f, 0xa3,
+ 0xeb, 0x11, 0xde, 0x62, 0xb7, 0xf0, 0x1c, 0x32, 0x4c, 0x8f, 0xba, 0x4e,
+ 0xd4, 0x1d, 0xba, 0x53, 0x78, 0xaa, 0x7b, 0xb0, 0xee, 0x62, 0xd0, 0x97,
+ 0xbe, 0x46, 0x1e, 0x17, 0xb5, 0x9b, 0x2d, 0x79, 0xbc, 0xa6, 0xcd, 0xef,
+ 0x1f, 0x5a, 0xe7, 0x10, 0xf9, 0x1c, 0x9c, 0x27, 0x48, 0xb5, 0x53, 0x43,
+ 0xb5, 0x76, 0x7a, 0x37, 0xc6, 0xe7, 0x7b, 0x0c, 0x92, 0x3f, 0x42, 0x4e,
+ 0x5d, 0xe9, 0x3f, 0x21, 0xd4, 0xd4, 0xfd, 0x22, 0x79, 0xab, 0x97, 0xea,
+ 0x9f, 0xad, 0xb1, 0x48, 0xf2, 0x06, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15,
+ 0x4d, 0xae, 0x2d, 0x19, 0xd8, 0x43, 0xf1, 0xed, 0xe5, 0x9c, 0x83, 0xb0,
+ 0x03, 0xbf, 0x43, 0xe6, 0xc4, 0x5a, 0xbf, 0x17, 0x4f, 0x12, 0xee, 0x78,
+ 0x22, 0x3b, 0x88, 0x27, 0x0b, 0x03, 0x78, 0xa2, 0xf0, 0xaf, 0xde, 0x95,
+ 0x91, 0x3d, 0xfa, 0xf9, 0x95, 0xd5, 0x33, 0x08, 0x89, 0xeb, 0x23, 0x1c,
+ 0xa3, 0x1f, 0x6e, 0x97, 0x23, 0x5c, 0xeb, 0xbe, 0x75, 0xf3, 0x07, 0x2a,
+ 0xfb, 0xa2, 0xba, 0xe2, 0x94, 0x85, 0x45, 0x1e, 0x59, 0x7e, 0xc8, 0x3a,
+ 0x1b, 0x95, 0xbe, 0x69, 0x97, 0xf5, 0x4e, 0xe7, 0x3b, 0x2b, 0x36, 0xa9,
+ 0xec, 0x0f, 0x0f, 0xc7, 0xd7, 0x58, 0xf9, 0xf5, 0x6f, 0x56, 0xd9, 0x3d,
+ 0x9a, 0x77, 0x56, 0x5d, 0x6f, 0xf7, 0xd1, 0x56, 0x45, 0xad, 0xcf, 0x33,
+ 0xab, 0xec, 0xfd, 0xed, 0x4f, 0x57, 0xb5, 0x5a, 0x9f, 0xe7, 0x57, 0xd9,
+ 0x3e, 0xf5, 0xee, 0x2a, 0xd5, 0xfa, 0xfc, 0x87, 0x55, 0x76, 0x5e, 0xbe,
+ 0xb4, 0x6a, 0xc9, 0xd5, 0xf7, 0x63, 0xf8, 0xef, 0xff, 0x00, 0x88, 0xf4,
+ 0x23, 0x6f, 0xec, 0x3a, 0x00, 0x00, 0x00 };
static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
@@ -4582,15 +4513,15 @@ static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
0x00000000 };
static struct fw_info bnx2_txp_fw_09 = {
- /* Firmware version: 4.4.23 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
- .start_addr = 0x08000094,
+ .start_addr = 0x08000098,
.text_addr = 0x08000000,
- .text_len = 0x3b1c,
+ .text_len = 0x3ae8,
.text_index = 0x0,
.gz_text = bnx2_TXP_b09FwText,
.gz_text_len = sizeof(bnx2_TXP_b09FwText),
@@ -4600,15 +4531,15 @@ static struct fw_info bnx2_txp_fw_09 = {
.data_index = 0x0,
.data = bnx2_TXP_b09FwData,
- .sbss_addr = 0x08003b80,
+ .sbss_addr = 0x08003b40,
.sbss_len = 0x6c,
.sbss_index = 0x0,
- .bss_addr = 0x08003bec,
+ .bss_addr = 0x08003bac,
.bss_len = 0x24c,
.bss_index = 0x0,
- .rodata_addr = 0x08003b1c,
+ .rodata_addr = 0x08003ae8,
.rodata_len = 0x30,
.rodata_index = 0x0,
.rodata = bnx2_TXP_b09FwRodata,
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 6fcccef4cf3..a329bee2555 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -1,6 +1,6 @@
/* bnx2x.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * 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
@@ -25,6 +25,16 @@
#endif
+#define BNX2X_MULTI_QUEUE
+
+#define BNX2X_NEW_NAPI
+
+
+#include "bnx2x_reg.h"
+#include "bnx2x_fw_defs.h"
+#include "bnx2x_hsi.h"
+#include "bnx2x_link.h"
+
/* error/debug prints */
#define DRV_MODULE_NAME "bnx2x"
@@ -92,12 +102,10 @@
#define REG_RD(bp, offset) readl(REG_ADDR(bp, offset))
#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
-#define REG_RD64(bp, offset) readq(REG_ADDR(bp, offset))
#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
#define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset))
#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset))
-#define REG_WR32(bp, offset, val) REG_WR(bp, offset, val)
#define REG_RD_IND(bp, offset) bnx2x_reg_rd_ind(bp, offset)
#define REG_WR_IND(bp, offset, val) bnx2x_reg_wr_ind(bp, offset, val)
@@ -152,9 +160,7 @@ struct sw_rx_page {
#define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT)
#define SGE_PAGE_SIZE PAGE_SIZE
#define SGE_PAGE_SHIFT PAGE_SHIFT
-#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN(addr)
-
-#define BCM_RX_ETH_PAYLOAD_ALIGN 64
+#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))addr)
/* SGE ring related macros */
#define NUM_RX_SGE_PAGES 2
@@ -187,6 +193,43 @@ struct sw_rx_page {
#define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK)
+struct bnx2x_eth_q_stats {
+ u32 total_bytes_received_hi;
+ u32 total_bytes_received_lo;
+ u32 total_bytes_transmitted_hi;
+ u32 total_bytes_transmitted_lo;
+ u32 total_unicast_packets_received_hi;
+ u32 total_unicast_packets_received_lo;
+ u32 total_multicast_packets_received_hi;
+ u32 total_multicast_packets_received_lo;
+ u32 total_broadcast_packets_received_hi;
+ u32 total_broadcast_packets_received_lo;
+ u32 total_unicast_packets_transmitted_hi;
+ u32 total_unicast_packets_transmitted_lo;
+ u32 total_multicast_packets_transmitted_hi;
+ u32 total_multicast_packets_transmitted_lo;
+ u32 total_broadcast_packets_transmitted_hi;
+ u32 total_broadcast_packets_transmitted_lo;
+ u32 valid_bytes_received_hi;
+ u32 valid_bytes_received_lo;
+
+ u32 error_bytes_received_hi;
+ u32 error_bytes_received_lo;
+ u32 etherstatsoverrsizepkts_hi;
+ u32 etherstatsoverrsizepkts_lo;
+ u32 no_buff_discard_hi;
+ u32 no_buff_discard_lo;
+
+ u32 driver_xoff;
+ u32 rx_err_discard_pkt;
+ u32 rx_skb_alloc_failed;
+ u32 hw_csum_err;
+};
+
+#define BNX2X_NUM_Q_STATS 11
+#define Q_STATS_OFFSET32(stat_name) \
+ (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4)
+
struct bnx2x_fastpath {
struct napi_struct napi;
@@ -228,20 +271,15 @@ struct bnx2x_fastpath {
u8 index; /* number in fp array */
u8 cl_id; /* eth client id */
u8 sb_id; /* status block number in HW */
-#define FP_IDX(fp) (fp->index)
-#define FP_CL_ID(fp) (fp->cl_id)
-#define BP_CL_ID(bp) (bp->fp[0].cl_id)
-#define FP_SB_ID(fp) (fp->sb_id)
-#define CNIC_SB_ID 0
u16 tx_pkt_prod;
u16 tx_pkt_cons;
u16 tx_bd_prod;
u16 tx_bd_cons;
- u16 *tx_cons_sb;
+ __le16 *tx_cons_sb;
- u16 fp_c_idx;
- u16 fp_u_idx;
+ __le16 fp_c_idx;
+ __le16 fp_u_idx;
u16 rx_bd_prod;
u16 rx_bd_cons;
@@ -250,8 +288,8 @@ struct bnx2x_fastpath {
u16 rx_sge_prod;
/* The last maximal completed SGE */
u16 last_max_sge;
- u16 *rx_cons_sb;
- u16 *rx_bd_cons_sb;
+ __le16 *rx_cons_sb;
+ __le16 *rx_bd_cons_sb;
unsigned long tx_pkt,
rx_pkt,
@@ -266,19 +304,18 @@ struct bnx2x_fastpath {
u64 tpa_queue_used;
#endif
+ struct tstorm_per_client_stats old_tclient;
+ struct ustorm_per_client_stats old_uclient;
+ struct xstorm_per_client_stats old_xclient;
+ struct bnx2x_eth_q_stats eth_q_stats;
+
+ char name[IFNAMSIZ];
struct bnx2x *bp; /* parent */
};
#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
-#define BNX2X_HAS_TX_WORK(fp) \
- ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \
- (fp->tx_pkt_prod != fp->tx_pkt_cons))
-
-#define BNX2X_HAS_RX_WORK(fp) \
- (fp->rx_comp_cons != rx_cons_sb)
-
-#define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
+#define BNX2X_HAS_WORK(fp) (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))
/* MC hsi */
@@ -408,10 +445,13 @@ struct bnx2x_fastpath {
#define BNX2X_RX_CSUM_OK(cqe) \
(!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe)))
+#define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \
+ (((le16_to_cpu(flags) & \
+ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \
+ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT) \
+ == PRS_FLAG_OVERETH_IPV4)
#define BNX2X_RX_SUM_FIX(cqe) \
- ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \
- PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \
- (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
+ BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags)
#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES)
@@ -485,11 +525,8 @@ struct bnx2x_common {
u32 shmem_base;
u32 hw_config;
- u32 board;
u32 bc_ver;
-
- char *name;
};
@@ -535,6 +572,7 @@ struct bnx2x_port {
/* used to synchronize phy accesses */
struct mutex phy_mutex;
+ int need_hw_lock;
u32 port_stx;
@@ -580,6 +618,10 @@ struct bnx2x_eth_stats {
u32 error_bytes_received_hi;
u32 error_bytes_received_lo;
+ u32 etherstatsoverrsizepkts_hi;
+ u32 etherstatsoverrsizepkts_lo;
+ u32 no_buff_discard_hi;
+ u32 no_buff_discard_lo;
u32 rx_stat_ifhcinbadoctets_hi;
u32 rx_stat_ifhcinbadoctets_lo;
@@ -658,19 +700,20 @@ struct bnx2x_eth_stats {
u32 tx_stat_bmac_ufl_hi;
u32 tx_stat_bmac_ufl_lo;
- u32 brb_drop_hi;
- u32 brb_drop_lo;
- u32 brb_truncate_hi;
- u32 brb_truncate_lo;
-
- u32 jabber_packets_received;
+ u32 pause_frames_received_hi;
+ u32 pause_frames_received_lo;
+ u32 pause_frames_sent_hi;
+ u32 pause_frames_sent_lo;
u32 etherstatspkts1024octetsto1522octets_hi;
u32 etherstatspkts1024octetsto1522octets_lo;
u32 etherstatspktsover1522octets_hi;
u32 etherstatspktsover1522octets_lo;
- u32 no_buff_discard;
+ u32 brb_drop_hi;
+ u32 brb_drop_lo;
+ u32 brb_truncate_hi;
+ u32 brb_truncate_lo;
u32 mac_filter_discard;
u32 xxoverflow_discard;
@@ -681,17 +724,16 @@ struct bnx2x_eth_stats {
u32 rx_err_discard_pkt;
u32 rx_skb_alloc_failed;
u32 hw_csum_err;
+
+ u32 nig_timer_max;
};
+#define BNX2X_NUM_STATS 41
#define STATS_OFFSET32(stat_name) \
(offsetof(struct bnx2x_eth_stats, stat_name) / 4)
-#ifdef BNX2X_MULTI
#define MAX_CONTEXT 16
-#else
-#define MAX_CONTEXT 1
-#endif
union cdu_context {
struct eth_context eth;
@@ -746,6 +788,9 @@ struct bnx2x {
atomic_t intr_sem;
struct msix_entry msix_table[MAX_CONTEXT+1];
+#define INT_MODE_INTx 1
+#define INT_MODE_MSI 2
+#define INT_MODE_MSIX 3
int tx_ring_size;
@@ -754,23 +799,26 @@ struct bnx2x {
#endif
u32 rx_csum;
- u32 rx_offset;
u32 rx_buf_size;
#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */
#define ETH_MIN_PACKET_SIZE 60
#define ETH_MAX_PACKET_SIZE 1500
#define ETH_MAX_JUMBO_PACKET_SIZE 9600
+ /* Max supported alignment is 256 (8 shift) */
+#define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \
+ L1_CACHE_SHIFT : 8)
+#define BNX2X_RX_ALIGN (1 << BNX2X_RX_ALIGN_SHIFT)
+
struct host_def_status_block *def_status_blk;
#define DEF_SB_ID 16
- u16 def_c_idx;
- u16 def_u_idx;
- u16 def_x_idx;
- u16 def_t_idx;
- u16 def_att_idx;
+ __le16 def_c_idx;
+ __le16 def_u_idx;
+ __le16 def_x_idx;
+ __le16 def_t_idx;
+ __le16 def_att_idx;
u32 attn_state;
struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS];
- u32 nig_mask;
/* slow path ring */
struct eth_spe *spq;
@@ -778,7 +826,7 @@ struct bnx2x {
u16 spq_prod_idx;
struct eth_spe *spq_prod_bd;
struct eth_spe *spq_last_bd;
- u16 *dsb_sp_prod;
+ __le16 *dsb_sp_prod;
u16 spq_left; /* serialize spq */
/* used to synchronize spq accesses */
spinlock_t spq_lock;
@@ -796,11 +844,11 @@ struct bnx2x {
u32 flags;
#define PCIX_FLAG 1
#define PCI_32BIT_FLAG 2
-#define ONE_TDMA_FLAG 4 /* no longer used */
+#define ONE_PORT_FLAG 4
#define NO_WOL_FLAG 8
#define USING_DAC_FLAG 0x10
#define USING_MSIX_FLAG 0x20
-#define ASF_ENABLE_FLAG 0x40
+#define USING_MSI_FLAG 0x40
#define TPA_ENABLE_FLAG 0x80
#define NO_MCP_FLAG 0x100
#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
@@ -815,12 +863,12 @@ struct bnx2x {
int pm_cap;
int pcie_cap;
+ int mrrs;
struct delayed_work sp_task;
struct work_struct reset_task;
struct timer_list timer;
- int timer_interval;
int current_interval;
u16 fw_seq;
@@ -833,6 +881,9 @@ struct bnx2x {
struct bnx2x_common common;
struct bnx2x_port port;
+ struct cmng_struct_per_port cmng;
+ u32 vn_weight_sum;
+
u32 mf_config;
u16 e1hov;
u8 e1hmf;
@@ -855,7 +906,7 @@ struct bnx2x {
u32 lin_cnt;
int state;
-#define BNX2X_STATE_CLOSED 0x0
+#define BNX2X_STATE_CLOSED 0
#define BNX2X_STATE_OPENING_WAIT4_LOAD 0x1000
#define BNX2X_STATE_OPENING_WAIT4_PORT 0x2000
#define BNX2X_STATE_OPEN 0x3000
@@ -866,8 +917,9 @@ struct bnx2x {
#define BNX2X_STATE_DIAG 0xe000
#define BNX2X_STATE_ERROR 0xf000
- int num_queues;
-#define BP_MAX_QUEUES(bp) (IS_E1HMF(bp) ? 4 : 16)
+ int multi_mode;
+ int num_rx_queues;
+ int num_tx_queues;
u32 rx_mode;
#define BNX2X_RX_MODE_NONE 0
@@ -905,8 +957,6 @@ struct bnx2x {
int executer_idx;
u16 stats_counter;
- struct tstorm_per_client_stats old_tclient;
- struct xstorm_per_client_stats old_xclient;
struct bnx2x_eth_stats eth_stats;
struct z_stream_s *strm;
@@ -918,17 +968,27 @@ struct bnx2x {
};
-#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++)
+#define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT / E1HVN_MAX) : \
+ MAX_CONTEXT)
+#define BNX2X_NUM_QUEUES(bp) max(bp->num_rx_queues, bp->num_tx_queues)
+#define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1)
+#define for_each_rx_queue(bp, var) \
+ for (var = 0; var < bp->num_rx_queues; var++)
+#define for_each_tx_queue(bp, var) \
+ for (var = 0; var < bp->num_tx_queues; var++)
+#define for_each_queue(bp, var) \
+ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++)
#define for_each_nondefault_queue(bp, var) \
- for (var = 1; var < bp->num_queues; var++)
-#define is_multi(bp) (bp->num_queues > 1)
+ for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++)
void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
u32 len32);
+int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
+int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
int wait)
@@ -999,13 +1059,12 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define PCICFG_LINK_SPEED_SHIFT 16
-#define BNX2X_NUM_STATS 42
-#define BNX2X_NUM_TESTS 8
+#define BNX2X_NUM_TESTS 7
-#define BNX2X_MAC_LOOPBACK 0
-#define BNX2X_PHY_LOOPBACK 1
-#define BNX2X_MAC_LOOPBACK_FAILED 1
-#define BNX2X_PHY_LOOPBACK_FAILED 2
+#define BNX2X_PHY_LOOPBACK 0
+#define BNX2X_MAC_LOOPBACK 1
+#define BNX2X_PHY_LOOPBACK_FAILED 1
+#define BNX2X_MAC_LOOPBACK_FAILED 2
#define BNX2X_LOOPBACK_FAILED (BNX2X_MAC_LOOPBACK_FAILED | \
BNX2X_PHY_LOOPBACK_FAILED)
@@ -1068,9 +1127,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define BNX2X_MCP_ASSERT \
GENERAL_ATTEN_OFFSET(MCP_FATAL_ASSERT_ATTENTION_BIT)
-#define BNX2X_DOORQ_ASSERT \
- AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT
-
#define BNX2X_GRC_TIMEOUT GENERAL_ATTEN_OFFSET(LATCHED_ATTN_TIMEOUT_GRC)
#define BNX2X_GRC_RSV (GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCR) | \
GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCT) | \
@@ -1127,12 +1183,13 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
-#define MULTI_FLAGS \
+#define MULTI_FLAGS(bp) \
(TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE)
+ (bp->multi_mode << \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT))
#define MULTI_MASK 0x7f
diff --git a/drivers/net/bnx2x_dump.h b/drivers/net/bnx2x_dump.h
new file mode 100644
index 00000000000..78c6b0353ad
--- /dev/null
+++ b/drivers/net/bnx2x_dump.h
@@ -0,0 +1,526 @@
+/* bnx2x_dump.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 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.
+ */
+
+
+/* This struct holds a signature to ensure the dump returned from the driver
+ * match the meta data file inserted to grc_dump.tcl
+ * The signature is time stamp, diag version and grc_dump version
+ */
+
+struct dump_sign {
+ u32 time_stamp;
+ u32 diag_ver;
+ u32 grc_dump_ver;
+};
+
+#define TSTORM_WAITP_ADDR 0x1b8a80
+#define CSTORM_WAITP_ADDR 0x238a80
+#define XSTORM_WAITP_ADDR 0x2b8a80
+#define USTORM_WAITP_ADDR 0x338a80
+#define TSTORM_CAM_MODE 0x1b1440
+
+#define RI_E1 0x1
+#define RI_E1H 0x2
+#define RI_ONLINE 0x100
+
+#define RI_E1_OFFLINE (RI_E1)
+#define RI_E1_ONLINE (RI_E1 | RI_ONLINE)
+#define RI_E1H_OFFLINE (RI_E1H)
+#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE)
+#define RI_ALL_OFFLINE (RI_E1 | RI_E1H)
+#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_ONLINE)
+
+#define MAX_TIMER_PENDING 200
+#define TIMER_SCAN_DONT_CARE 0xFF
+
+
+struct dump_hdr {
+ u32 hdr_size; /* in dwords, excluding this field */
+ struct dump_sign dump_sign;
+ u32 xstorm_waitp;
+ u32 tstorm_waitp;
+ u32 ustorm_waitp;
+ u32 cstorm_waitp;
+ u16 info;
+ u8 idle_chk;
+ u8 reserved;
+};
+
+struct reg_addr {
+ u32 addr;
+ u32 size;
+ u16 info;
+};
+
+struct wreg_addr {
+ u32 addr;
+ u32 size;
+ u32 read_regs_count;
+ const u32 *read_regs;
+ u16 info;
+};
+
+
+#define REGS_COUNT 558
+static const struct reg_addr reg_addrs[REGS_COUNT] = {
+ { 0x2000, 341, RI_ALL_ONLINE}, { 0x2800, 103, RI_ALL_ONLINE},
+ { 0x3000, 287, RI_ALL_ONLINE}, { 0x3800, 331, RI_ALL_ONLINE},
+ { 0x8800, 6, RI_E1_ONLINE}, { 0xa000, 223, RI_ALL_ONLINE},
+ { 0xa388, 1, RI_ALL_ONLINE}, { 0xa398, 1, RI_ALL_ONLINE},
+ { 0xa39c, 7, RI_E1H_ONLINE}, { 0xa3c0, 3, RI_E1H_ONLINE},
+ { 0xa3d0, 1, RI_E1H_ONLINE}, { 0xa3d8, 1, RI_E1H_ONLINE},
+ { 0xa3e0, 1, RI_E1H_ONLINE}, { 0xa3e8, 1, RI_E1H_ONLINE},
+ { 0xa3f0, 1, RI_E1H_ONLINE}, { 0xa3f8, 1, RI_E1H_ONLINE},
+ { 0xa400, 69, RI_ALL_ONLINE}, { 0xa518, 1, RI_ALL_ONLINE},
+ { 0xa520, 1, RI_ALL_ONLINE}, { 0xa528, 1, RI_ALL_ONLINE},
+ { 0xa530, 1, RI_ALL_ONLINE}, { 0xa538, 1, RI_ALL_ONLINE},
+ { 0xa540, 1, RI_ALL_ONLINE}, { 0xa548, 1, RI_ALL_ONLINE},
+ { 0xa550, 1, RI_ALL_ONLINE}, { 0xa558, 1, RI_ALL_ONLINE},
+ { 0xa560, 1, RI_ALL_ONLINE}, { 0xa568, 1, RI_ALL_ONLINE},
+ { 0xa570, 1, RI_ALL_ONLINE}, { 0xa580, 1, RI_ALL_ONLINE},
+ { 0xa590, 1, RI_ALL_ONLINE}, { 0xa5a0, 1, RI_ALL_ONLINE},
+ { 0xa5c0, 1, RI_ALL_ONLINE}, { 0xa5e0, 1, RI_E1H_ONLINE},
+ { 0xa5e8, 1, RI_E1H_ONLINE}, { 0xa5f0, 1, RI_E1H_ONLINE},
+ { 0xa5f8, 10, RI_E1H_ONLINE}, { 0x10000, 236, RI_ALL_ONLINE},
+ { 0x103bc, 1, RI_ALL_ONLINE}, { 0x103cc, 1, RI_ALL_ONLINE},
+ { 0x103dc, 1, RI_ALL_ONLINE}, { 0x10400, 57, RI_ALL_ONLINE},
+ { 0x104e8, 2, RI_ALL_ONLINE}, { 0x104f4, 2, RI_ALL_ONLINE},
+ { 0x10500, 146, RI_ALL_ONLINE}, { 0x10750, 2, RI_ALL_ONLINE},
+ { 0x10760, 2, RI_ALL_ONLINE}, { 0x10770, 2, RI_ALL_ONLINE},
+ { 0x10780, 2, RI_ALL_ONLINE}, { 0x10790, 2, RI_ALL_ONLINE},
+ { 0x107a0, 2, RI_ALL_ONLINE}, { 0x107b0, 2, RI_ALL_ONLINE},
+ { 0x107c0, 2, RI_ALL_ONLINE}, { 0x107d0, 2, RI_ALL_ONLINE},
+ { 0x107e0, 2, RI_ALL_ONLINE}, { 0x10880, 2, RI_ALL_ONLINE},
+ { 0x10900, 2, RI_ALL_ONLINE}, { 0x12000, 1, RI_ALL_ONLINE},
+ { 0x14000, 1, RI_ALL_ONLINE}, { 0x16000, 26, RI_E1H_ONLINE},
+ { 0x16070, 18, RI_E1H_ONLINE}, { 0x160c0, 27, RI_E1H_ONLINE},
+ { 0x16140, 1, RI_E1H_ONLINE}, { 0x16160, 1, RI_E1H_ONLINE},
+ { 0x16180, 2, RI_E1H_ONLINE}, { 0x161c0, 2, RI_E1H_ONLINE},
+ { 0x16204, 5, RI_E1H_ONLINE}, { 0x18000, 1, RI_E1H_ONLINE},
+ { 0x18008, 1, RI_E1H_ONLINE}, { 0x20000, 24, RI_ALL_ONLINE},
+ { 0x20060, 8, RI_ALL_ONLINE}, { 0x20080, 138, RI_ALL_ONLINE},
+ { 0x202b4, 1, RI_ALL_ONLINE}, { 0x202c4, 1, RI_ALL_ONLINE},
+ { 0x20400, 2, RI_ALL_ONLINE}, { 0x2040c, 8, RI_ALL_ONLINE},
+ { 0x2042c, 18, RI_E1H_ONLINE}, { 0x20480, 1, RI_ALL_ONLINE},
+ { 0x20500, 1, RI_ALL_ONLINE}, { 0x20600, 1, RI_ALL_ONLINE},
+ { 0x28000, 1, RI_ALL_ONLINE}, { 0x28004, 8191, RI_ALL_OFFLINE},
+ { 0x30000, 1, RI_ALL_ONLINE}, { 0x30004, 16383, RI_ALL_OFFLINE},
+ { 0x40000, 98, RI_ALL_ONLINE}, { 0x40194, 1, RI_ALL_ONLINE},
+ { 0x401a4, 1, RI_ALL_ONLINE}, { 0x401a8, 11, RI_E1H_ONLINE},
+ { 0x40200, 4, RI_ALL_ONLINE}, { 0x40400, 43, RI_ALL_ONLINE},
+ { 0x404b8, 1, RI_ALL_ONLINE}, { 0x404c8, 1, RI_ALL_ONLINE},
+ { 0x404cc, 3, RI_E1H_ONLINE}, { 0x40500, 2, RI_ALL_ONLINE},
+ { 0x40510, 2, RI_ALL_ONLINE}, { 0x40520, 2, RI_ALL_ONLINE},
+ { 0x40530, 2, RI_ALL_ONLINE}, { 0x40540, 2, RI_ALL_ONLINE},
+ { 0x42000, 164, RI_ALL_ONLINE}, { 0x4229c, 1, RI_ALL_ONLINE},
+ { 0x422ac, 1, RI_ALL_ONLINE}, { 0x422bc, 1, RI_ALL_ONLINE},
+ { 0x422d4, 5, RI_E1H_ONLINE}, { 0x42400, 49, RI_ALL_ONLINE},
+ { 0x424c8, 38, RI_ALL_ONLINE}, { 0x42568, 2, RI_ALL_ONLINE},
+ { 0x42800, 1, RI_ALL_ONLINE}, { 0x50000, 20, RI_ALL_ONLINE},
+ { 0x50050, 8, RI_ALL_ONLINE}, { 0x50070, 88, RI_ALL_ONLINE},
+ { 0x501dc, 1, RI_ALL_ONLINE}, { 0x501ec, 1, RI_ALL_ONLINE},
+ { 0x501f0, 4, RI_E1H_ONLINE}, { 0x50200, 2, RI_ALL_ONLINE},
+ { 0x5020c, 7, RI_ALL_ONLINE}, { 0x50228, 6, RI_E1H_ONLINE},
+ { 0x50240, 1, RI_ALL_ONLINE}, { 0x50280, 1, RI_ALL_ONLINE},
+ { 0x52000, 1, RI_ALL_ONLINE}, { 0x54000, 1, RI_ALL_ONLINE},
+ { 0x54004, 3327, RI_ALL_OFFLINE}, { 0x58000, 1, RI_ALL_ONLINE},
+ { 0x58004, 8191, RI_ALL_OFFLINE}, { 0x60000, 71, RI_ALL_ONLINE},
+ { 0x60128, 1, RI_ALL_ONLINE}, { 0x60138, 1, RI_ALL_ONLINE},
+ { 0x6013c, 24, RI_E1H_ONLINE}, { 0x60200, 1, RI_ALL_ONLINE},
+ { 0x61000, 1, RI_ALL_ONLINE}, { 0x61004, 511, RI_ALL_OFFLINE},
+ { 0x70000, 8, RI_ALL_ONLINE}, { 0x70020, 21496, RI_ALL_OFFLINE},
+ { 0x85000, 3, RI_ALL_ONLINE}, { 0x8500c, 4, RI_ALL_OFFLINE},
+ { 0x8501c, 7, RI_ALL_ONLINE}, { 0x85038, 4, RI_ALL_OFFLINE},
+ { 0x85048, 1, RI_ALL_ONLINE}, { 0x8504c, 109, RI_ALL_OFFLINE},
+ { 0x85200, 32, RI_ALL_ONLINE}, { 0x85280, 11104, RI_ALL_OFFLINE},
+ { 0xa0000, 16384, RI_ALL_ONLINE}, { 0xb0000, 16384, RI_E1H_ONLINE},
+ { 0xc1000, 7, RI_ALL_ONLINE}, { 0xc1028, 1, RI_ALL_ONLINE},
+ { 0xc1038, 1, RI_ALL_ONLINE}, { 0xc1800, 2, RI_ALL_ONLINE},
+ { 0xc2000, 164, RI_ALL_ONLINE}, { 0xc229c, 1, RI_ALL_ONLINE},
+ { 0xc22ac, 1, RI_ALL_ONLINE}, { 0xc22bc, 1, RI_ALL_ONLINE},
+ { 0xc2400, 49, RI_ALL_ONLINE}, { 0xc24c8, 38, RI_ALL_ONLINE},
+ { 0xc2568, 2, RI_ALL_ONLINE}, { 0xc2600, 1, RI_ALL_ONLINE},
+ { 0xc4000, 165, RI_ALL_ONLINE}, { 0xc42a0, 1, RI_ALL_ONLINE},
+ { 0xc42b0, 1, RI_ALL_ONLINE}, { 0xc42c0, 1, RI_ALL_ONLINE},
+ { 0xc42e0, 7, RI_E1H_ONLINE}, { 0xc4400, 51, RI_ALL_ONLINE},
+ { 0xc44d0, 38, RI_ALL_ONLINE}, { 0xc4570, 2, RI_ALL_ONLINE},
+ { 0xc4600, 1, RI_ALL_ONLINE}, { 0xd0000, 19, RI_ALL_ONLINE},
+ { 0xd004c, 8, RI_ALL_ONLINE}, { 0xd006c, 91, RI_ALL_ONLINE},
+ { 0xd01e4, 1, RI_ALL_ONLINE}, { 0xd01f4, 1, RI_ALL_ONLINE},
+ { 0xd0200, 2, RI_ALL_ONLINE}, { 0xd020c, 7, RI_ALL_ONLINE},
+ { 0xd0228, 18, RI_E1H_ONLINE}, { 0xd0280, 1, RI_ALL_ONLINE},
+ { 0xd0300, 1, RI_ALL_ONLINE}, { 0xd0400, 1, RI_ALL_ONLINE},
+ { 0xd4000, 1, RI_ALL_ONLINE}, { 0xd4004, 2559, RI_ALL_OFFLINE},
+ { 0xd8000, 1, RI_ALL_ONLINE}, { 0xd8004, 8191, RI_ALL_OFFLINE},
+ { 0xe0000, 21, RI_ALL_ONLINE}, { 0xe0054, 8, RI_ALL_ONLINE},
+ { 0xe0074, 85, RI_ALL_ONLINE}, { 0xe01d4, 1, RI_ALL_ONLINE},
+ { 0xe01e4, 1, RI_ALL_ONLINE}, { 0xe0200, 2, RI_ALL_ONLINE},
+ { 0xe020c, 8, RI_ALL_ONLINE}, { 0xe022c, 18, RI_E1H_ONLINE},
+ { 0xe0280, 1, RI_ALL_ONLINE}, { 0xe0300, 1, RI_ALL_ONLINE},
+ { 0xe1000, 1, RI_ALL_ONLINE}, { 0xe2000, 1, RI_ALL_ONLINE},
+ { 0xe2004, 2047, RI_ALL_OFFLINE}, { 0xf0000, 1, RI_ALL_ONLINE},
+ { 0xf0004, 16383, RI_ALL_OFFLINE}, { 0x101000, 12, RI_ALL_ONLINE},
+ { 0x10103c, 1, RI_ALL_ONLINE}, { 0x10104c, 1, RI_ALL_ONLINE},
+ { 0x101050, 1, RI_E1H_ONLINE}, { 0x101100, 1, RI_ALL_ONLINE},
+ { 0x101800, 8, RI_ALL_ONLINE}, { 0x102000, 18, RI_ALL_ONLINE},
+ { 0x102054, 1, RI_ALL_ONLINE}, { 0x102064, 1, RI_ALL_ONLINE},
+ { 0x102080, 17, RI_ALL_ONLINE}, { 0x1020c8, 8, RI_E1H_ONLINE},
+ { 0x102400, 1, RI_ALL_ONLINE}, { 0x103000, 26, RI_ALL_ONLINE},
+ { 0x103074, 1, RI_ALL_ONLINE}, { 0x103084, 1, RI_ALL_ONLINE},
+ { 0x103094, 1, RI_ALL_ONLINE}, { 0x103098, 5, RI_E1H_ONLINE},
+ { 0x103800, 8, RI_ALL_ONLINE}, { 0x104000, 63, RI_ALL_ONLINE},
+ { 0x104108, 1, RI_ALL_ONLINE}, { 0x104118, 1, RI_ALL_ONLINE},
+ { 0x104200, 17, RI_ALL_ONLINE}, { 0x104400, 64, RI_ALL_ONLINE},
+ { 0x104500, 192, RI_ALL_OFFLINE}, { 0x104800, 64, RI_ALL_ONLINE},
+ { 0x104900, 192, RI_ALL_OFFLINE}, { 0x105000, 7, RI_ALL_ONLINE},
+ { 0x10501c, 1, RI_ALL_OFFLINE}, { 0x105020, 3, RI_ALL_ONLINE},
+ { 0x10502c, 1, RI_ALL_OFFLINE}, { 0x105030, 3, RI_ALL_ONLINE},
+ { 0x10503c, 1, RI_ALL_OFFLINE}, { 0x105040, 3, RI_ALL_ONLINE},
+ { 0x10504c, 1, RI_ALL_OFFLINE}, { 0x105050, 3, RI_ALL_ONLINE},
+ { 0x10505c, 1, RI_ALL_OFFLINE}, { 0x105060, 3, RI_ALL_ONLINE},
+ { 0x10506c, 1, RI_ALL_OFFLINE}, { 0x105070, 3, RI_ALL_ONLINE},
+ { 0x10507c, 1, RI_ALL_OFFLINE}, { 0x105080, 3, RI_ALL_ONLINE},
+ { 0x10508c, 1, RI_ALL_OFFLINE}, { 0x105090, 3, RI_ALL_ONLINE},
+ { 0x10509c, 1, RI_ALL_OFFLINE}, { 0x1050a0, 3, RI_ALL_ONLINE},
+ { 0x1050ac, 1, RI_ALL_OFFLINE}, { 0x1050b0, 3, RI_ALL_ONLINE},
+ { 0x1050bc, 1, RI_ALL_OFFLINE}, { 0x1050c0, 3, RI_ALL_ONLINE},
+ { 0x1050cc, 1, RI_ALL_OFFLINE}, { 0x1050d0, 3, RI_ALL_ONLINE},
+ { 0x1050dc, 1, RI_ALL_OFFLINE}, { 0x1050e0, 3, RI_ALL_ONLINE},
+ { 0x1050ec, 1, RI_ALL_OFFLINE}, { 0x1050f0, 3, RI_ALL_ONLINE},
+ { 0x1050fc, 1, RI_ALL_OFFLINE}, { 0x105100, 3, RI_ALL_ONLINE},
+ { 0x10510c, 1, RI_ALL_OFFLINE}, { 0x105110, 3, RI_ALL_ONLINE},
+ { 0x10511c, 1, RI_ALL_OFFLINE}, { 0x105120, 3, RI_ALL_ONLINE},
+ { 0x10512c, 1, RI_ALL_OFFLINE}, { 0x105130, 3, RI_ALL_ONLINE},
+ { 0x10513c, 1, RI_ALL_OFFLINE}, { 0x105140, 3, RI_ALL_ONLINE},
+ { 0x10514c, 1, RI_ALL_OFFLINE}, { 0x105150, 3, RI_ALL_ONLINE},
+ { 0x10515c, 1, RI_ALL_OFFLINE}, { 0x105160, 3, RI_ALL_ONLINE},
+ { 0x10516c, 1, RI_ALL_OFFLINE}, { 0x105170, 3, RI_ALL_ONLINE},
+ { 0x10517c, 1, RI_ALL_OFFLINE}, { 0x105180, 3, RI_ALL_ONLINE},
+ { 0x10518c, 1, RI_ALL_OFFLINE}, { 0x105190, 3, RI_ALL_ONLINE},
+ { 0x10519c, 1, RI_ALL_OFFLINE}, { 0x1051a0, 3, RI_ALL_ONLINE},
+ { 0x1051ac, 1, RI_ALL_OFFLINE}, { 0x1051b0, 3, RI_ALL_ONLINE},
+ { 0x1051bc, 1, RI_ALL_OFFLINE}, { 0x1051c0, 3, RI_ALL_ONLINE},
+ { 0x1051cc, 1, RI_ALL_OFFLINE}, { 0x1051d0, 3, RI_ALL_ONLINE},
+ { 0x1051dc, 1, RI_ALL_OFFLINE}, { 0x1051e0, 3, RI_ALL_ONLINE},
+ { 0x1051ec, 1, RI_ALL_OFFLINE}, { 0x1051f0, 3, RI_ALL_ONLINE},
+ { 0x1051fc, 1, RI_ALL_OFFLINE}, { 0x105200, 3, RI_ALL_ONLINE},
+ { 0x10520c, 1, RI_ALL_OFFLINE}, { 0x105210, 3, RI_ALL_ONLINE},
+ { 0x10521c, 1, RI_ALL_OFFLINE}, { 0x105220, 3, RI_ALL_ONLINE},
+ { 0x10522c, 1, RI_ALL_OFFLINE}, { 0x105230, 3, RI_ALL_ONLINE},
+ { 0x10523c, 1, RI_ALL_OFFLINE}, { 0x105240, 3, RI_ALL_ONLINE},
+ { 0x10524c, 1, RI_ALL_OFFLINE}, { 0x105250, 3, RI_ALL_ONLINE},
+ { 0x10525c, 1, RI_ALL_OFFLINE}, { 0x105260, 3, RI_ALL_ONLINE},
+ { 0x10526c, 1, RI_ALL_OFFLINE}, { 0x105270, 3, RI_ALL_ONLINE},
+ { 0x10527c, 1, RI_ALL_OFFLINE}, { 0x105280, 3, RI_ALL_ONLINE},
+ { 0x10528c, 1, RI_ALL_OFFLINE}, { 0x105290, 3, RI_ALL_ONLINE},
+ { 0x10529c, 1, RI_ALL_OFFLINE}, { 0x1052a0, 3, RI_ALL_ONLINE},
+ { 0x1052ac, 1, RI_ALL_OFFLINE}, { 0x1052b0, 3, RI_ALL_ONLINE},
+ { 0x1052bc, 1, RI_ALL_OFFLINE}, { 0x1052c0, 3, RI_ALL_ONLINE},
+ { 0x1052cc, 1, RI_ALL_OFFLINE}, { 0x1052d0, 3, RI_ALL_ONLINE},
+ { 0x1052dc, 1, RI_ALL_OFFLINE}, { 0x1052e0, 3, RI_ALL_ONLINE},
+ { 0x1052ec, 1, RI_ALL_OFFLINE}, { 0x1052f0, 3, RI_ALL_ONLINE},
+ { 0x1052fc, 1, RI_ALL_OFFLINE}, { 0x105300, 3, RI_ALL_ONLINE},
+ { 0x10530c, 1, RI_ALL_OFFLINE}, { 0x105310, 3, RI_ALL_ONLINE},
+ { 0x10531c, 1, RI_ALL_OFFLINE}, { 0x105320, 3, RI_ALL_ONLINE},
+ { 0x10532c, 1, RI_ALL_OFFLINE}, { 0x105330, 3, RI_ALL_ONLINE},
+ { 0x10533c, 1, RI_ALL_OFFLINE}, { 0x105340, 3, RI_ALL_ONLINE},
+ { 0x10534c, 1, RI_ALL_OFFLINE}, { 0x105350, 3, RI_ALL_ONLINE},
+ { 0x10535c, 1, RI_ALL_OFFLINE}, { 0x105360, 3, RI_ALL_ONLINE},
+ { 0x10536c, 1, RI_ALL_OFFLINE}, { 0x105370, 3, RI_ALL_ONLINE},
+ { 0x10537c, 1, RI_ALL_OFFLINE}, { 0x105380, 3, RI_ALL_ONLINE},
+ { 0x10538c, 1, RI_ALL_OFFLINE}, { 0x105390, 3, RI_ALL_ONLINE},
+ { 0x10539c, 1, RI_ALL_OFFLINE}, { 0x1053a0, 3, RI_ALL_ONLINE},
+ { 0x1053ac, 1, RI_ALL_OFFLINE}, { 0x1053b0, 3, RI_ALL_ONLINE},
+ { 0x1053bc, 1, RI_ALL_OFFLINE}, { 0x1053c0, 3, RI_ALL_ONLINE},
+ { 0x1053cc, 1, RI_ALL_OFFLINE}, { 0x1053d0, 3, RI_ALL_ONLINE},
+ { 0x1053dc, 1, RI_ALL_OFFLINE}, { 0x1053e0, 3, RI_ALL_ONLINE},
+ { 0x1053ec, 1, RI_ALL_OFFLINE}, { 0x1053f0, 3, RI_ALL_ONLINE},
+ { 0x1053fc, 769, RI_ALL_OFFLINE}, { 0x108000, 33, RI_ALL_ONLINE},
+ { 0x108090, 1, RI_ALL_ONLINE}, { 0x1080a0, 1, RI_ALL_ONLINE},
+ { 0x1080ac, 5, RI_E1H_ONLINE}, { 0x108100, 5, RI_ALL_ONLINE},
+ { 0x108120, 5, RI_ALL_ONLINE}, { 0x108200, 74, RI_ALL_ONLINE},
+ { 0x108400, 74, RI_ALL_ONLINE}, { 0x108800, 152, RI_ALL_ONLINE},
+ { 0x109000, 1, RI_ALL_ONLINE}, { 0x120000, 347, RI_ALL_ONLINE},
+ { 0x120578, 1, RI_ALL_ONLINE}, { 0x120588, 1, RI_ALL_ONLINE},
+ { 0x120598, 1, RI_ALL_ONLINE}, { 0x12059c, 23, RI_E1H_ONLINE},
+ { 0x120614, 1, RI_E1H_ONLINE}, { 0x12061c, 30, RI_E1H_ONLINE},
+ { 0x12080c, 65, RI_ALL_ONLINE}, { 0x120a00, 2, RI_ALL_ONLINE},
+ { 0x122000, 2, RI_ALL_ONLINE}, { 0x128000, 2, RI_E1H_ONLINE},
+ { 0x140000, 114, RI_ALL_ONLINE}, { 0x1401d4, 1, RI_ALL_ONLINE},
+ { 0x1401e4, 1, RI_ALL_ONLINE}, { 0x140200, 6, RI_ALL_ONLINE},
+ { 0x144000, 4, RI_ALL_ONLINE}, { 0x148000, 4, RI_ALL_ONLINE},
+ { 0x14c000, 4, RI_ALL_ONLINE}, { 0x150000, 4, RI_ALL_ONLINE},
+ { 0x154000, 4, RI_ALL_ONLINE}, { 0x158000, 4, RI_ALL_ONLINE},
+ { 0x15c000, 7, RI_E1H_ONLINE}, { 0x161000, 7, RI_ALL_ONLINE},
+ { 0x161028, 1, RI_ALL_ONLINE}, { 0x161038, 1, RI_ALL_ONLINE},
+ { 0x161800, 2, RI_ALL_ONLINE}, { 0x164000, 60, RI_ALL_ONLINE},
+ { 0x1640fc, 1, RI_ALL_ONLINE}, { 0x16410c, 1, RI_ALL_ONLINE},
+ { 0x164110, 2, RI_E1H_ONLINE}, { 0x164200, 1, RI_ALL_ONLINE},
+ { 0x164208, 1, RI_ALL_ONLINE}, { 0x164210, 1, RI_ALL_ONLINE},
+ { 0x164218, 1, RI_ALL_ONLINE}, { 0x164220, 1, RI_ALL_ONLINE},
+ { 0x164228, 1, RI_ALL_ONLINE}, { 0x164230, 1, RI_ALL_ONLINE},
+ { 0x164238, 1, RI_ALL_ONLINE}, { 0x164240, 1, RI_ALL_ONLINE},
+ { 0x164248, 1, RI_ALL_ONLINE}, { 0x164250, 1, RI_ALL_ONLINE},
+ { 0x164258, 1, RI_ALL_ONLINE}, { 0x164260, 1, RI_ALL_ONLINE},
+ { 0x164270, 2, RI_ALL_ONLINE}, { 0x164280, 2, RI_ALL_ONLINE},
+ { 0x164800, 2, RI_ALL_ONLINE}, { 0x165000, 2, RI_ALL_ONLINE},
+ { 0x166000, 164, RI_ALL_ONLINE}, { 0x16629c, 1, RI_ALL_ONLINE},
+ { 0x1662ac, 1, RI_ALL_ONLINE}, { 0x1662bc, 1, RI_ALL_ONLINE},
+ { 0x166400, 49, RI_ALL_ONLINE}, { 0x1664c8, 38, RI_ALL_ONLINE},
+ { 0x166568, 2, RI_ALL_ONLINE}, { 0x166800, 1, RI_ALL_ONLINE},
+ { 0x168000, 270, RI_ALL_ONLINE}, { 0x168444, 1, RI_ALL_ONLINE},
+ { 0x168454, 1, RI_ALL_ONLINE}, { 0x168800, 19, RI_ALL_ONLINE},
+ { 0x168900, 1, RI_ALL_ONLINE}, { 0x168a00, 128, RI_ALL_ONLINE},
+ { 0x16a000, 1, RI_ALL_ONLINE}, { 0x16a004, 1535, RI_ALL_OFFLINE},
+ { 0x16c000, 1, RI_ALL_ONLINE}, { 0x16c004, 1535, RI_ALL_OFFLINE},
+ { 0x16e000, 16, RI_E1H_ONLINE}, { 0x16e100, 1, RI_E1H_ONLINE},
+ { 0x16e200, 2, RI_E1H_ONLINE}, { 0x16e400, 183, RI_E1H_ONLINE},
+ { 0x170000, 93, RI_ALL_ONLINE}, { 0x170180, 1, RI_ALL_ONLINE},
+ { 0x170190, 1, RI_ALL_ONLINE}, { 0x170200, 4, RI_ALL_ONLINE},
+ { 0x170214, 1, RI_ALL_ONLINE}, { 0x178000, 1, RI_ALL_ONLINE},
+ { 0x180000, 61, RI_ALL_ONLINE}, { 0x180100, 1, RI_ALL_ONLINE},
+ { 0x180110, 1, RI_ALL_ONLINE}, { 0x180120, 1, RI_ALL_ONLINE},
+ { 0x180130, 1, RI_ALL_ONLINE}, { 0x18013c, 2, RI_E1H_ONLINE},
+ { 0x180200, 58, RI_ALL_ONLINE}, { 0x180340, 4, RI_ALL_ONLINE},
+ { 0x180400, 1, RI_ALL_ONLINE}, { 0x180404, 255, RI_ALL_OFFLINE},
+ { 0x181000, 4, RI_ALL_ONLINE}, { 0x181010, 1020, RI_ALL_OFFLINE},
+ { 0x1a0000, 1, RI_ALL_ONLINE}, { 0x1a0004, 1023, RI_ALL_OFFLINE},
+ { 0x1a1000, 1, RI_ALL_ONLINE}, { 0x1a1004, 4607, RI_ALL_OFFLINE},
+ { 0x1a5800, 2560, RI_E1H_OFFLINE}, { 0x1a8000, 64, RI_ALL_OFFLINE},
+ { 0x1a8100, 1984, RI_E1H_OFFLINE}, { 0x1aa000, 1, RI_E1H_ONLINE},
+ { 0x1aa004, 6655, RI_E1H_OFFLINE}, { 0x1b1800, 128, RI_ALL_OFFLINE},
+ { 0x1b1c00, 128, RI_ALL_OFFLINE}, { 0x1b2000, 1, RI_ALL_OFFLINE},
+ { 0x1b2400, 64, RI_E1H_OFFLINE}, { 0x1b8200, 1, RI_ALL_ONLINE},
+ { 0x1b8240, 1, RI_ALL_ONLINE}, { 0x1b8280, 1, RI_ALL_ONLINE},
+ { 0x1b82c0, 1, RI_ALL_ONLINE}, { 0x1b8a00, 1, RI_ALL_ONLINE},
+ { 0x1b8a80, 1, RI_ALL_ONLINE}, { 0x1c0000, 2, RI_ALL_ONLINE},
+ { 0x200000, 65, RI_ALL_ONLINE}, { 0x200110, 1, RI_ALL_ONLINE},
+ { 0x200120, 1, RI_ALL_ONLINE}, { 0x200130, 1, RI_ALL_ONLINE},
+ { 0x200140, 1, RI_ALL_ONLINE}, { 0x20014c, 2, RI_E1H_ONLINE},
+ { 0x200200, 58, RI_ALL_ONLINE}, { 0x200340, 4, RI_ALL_ONLINE},
+ { 0x200400, 1, RI_ALL_ONLINE}, { 0x200404, 255, RI_ALL_OFFLINE},
+ { 0x202000, 4, RI_ALL_ONLINE}, { 0x202010, 2044, RI_ALL_OFFLINE},
+ { 0x220000, 1, RI_ALL_ONLINE}, { 0x220004, 1023, RI_ALL_OFFLINE},
+ { 0x221000, 1, RI_ALL_ONLINE}, { 0x221004, 4607, RI_ALL_OFFLINE},
+ { 0x225800, 1536, RI_E1H_OFFLINE}, { 0x227000, 1, RI_E1H_ONLINE},
+ { 0x227004, 1023, RI_E1H_OFFLINE}, { 0x228000, 64, RI_ALL_OFFLINE},
+ { 0x228100, 8640, RI_E1H_OFFLINE}, { 0x231800, 128, RI_ALL_OFFLINE},
+ { 0x231c00, 128, RI_ALL_OFFLINE}, { 0x232000, 1, RI_ALL_OFFLINE},
+ { 0x232400, 64, RI_E1H_OFFLINE}, { 0x238200, 1, RI_ALL_ONLINE},
+ { 0x238240, 1, RI_ALL_ONLINE}, { 0x238280, 1, RI_ALL_ONLINE},
+ { 0x2382c0, 1, RI_ALL_ONLINE}, { 0x238a00, 1, RI_ALL_ONLINE},
+ { 0x238a80, 1, RI_ALL_ONLINE}, { 0x240000, 2, RI_ALL_ONLINE},
+ { 0x280000, 65, RI_ALL_ONLINE}, { 0x280110, 1, RI_ALL_ONLINE},
+ { 0x280120, 1, RI_ALL_ONLINE}, { 0x280130, 1, RI_ALL_ONLINE},
+ { 0x280140, 1, RI_ALL_ONLINE}, { 0x28014c, 2, RI_E1H_ONLINE},
+ { 0x280200, 58, RI_ALL_ONLINE}, { 0x280340, 4, RI_ALL_ONLINE},
+ { 0x280400, 1, RI_ALL_ONLINE}, { 0x280404, 255, RI_ALL_OFFLINE},
+ { 0x282000, 4, RI_ALL_ONLINE}, { 0x282010, 2044, RI_ALL_OFFLINE},
+ { 0x2a0000, 1, RI_ALL_ONLINE}, { 0x2a0004, 1023, RI_ALL_OFFLINE},
+ { 0x2a1000, 1, RI_ALL_ONLINE}, { 0x2a1004, 4607, RI_ALL_OFFLINE},
+ { 0x2a5800, 2560, RI_E1H_OFFLINE}, { 0x2a8000, 64, RI_ALL_OFFLINE},
+ { 0x2a8100, 960, RI_E1H_OFFLINE}, { 0x2a9000, 1, RI_E1H_ONLINE},
+ { 0x2a9004, 7679, RI_E1H_OFFLINE}, { 0x2b1800, 128, RI_ALL_OFFLINE},
+ { 0x2b1c00, 128, RI_ALL_OFFLINE}, { 0x2b2000, 1, RI_ALL_OFFLINE},
+ { 0x2b2400, 64, RI_E1H_OFFLINE}, { 0x2b8200, 1, RI_ALL_ONLINE},
+ { 0x2b8240, 1, RI_ALL_ONLINE}, { 0x2b8280, 1, RI_ALL_ONLINE},
+ { 0x2b82c0, 1, RI_ALL_ONLINE}, { 0x2b8a00, 1, RI_ALL_ONLINE},
+ { 0x2b8a80, 1, RI_ALL_ONLINE}, { 0x2c0000, 2, RI_ALL_ONLINE},
+ { 0x300000, 65, RI_ALL_ONLINE}, { 0x300110, 1, RI_ALL_ONLINE},
+ { 0x300120, 1, RI_ALL_ONLINE}, { 0x300130, 1, RI_ALL_ONLINE},
+ { 0x300140, 1, RI_ALL_ONLINE}, { 0x30014c, 2, RI_E1H_ONLINE},
+ { 0x300200, 58, RI_ALL_ONLINE}, { 0x300340, 4, RI_ALL_ONLINE},
+ { 0x300400, 1, RI_ALL_ONLINE}, { 0x300404, 255, RI_ALL_OFFLINE},
+ { 0x302000, 4, RI_ALL_ONLINE}, { 0x302010, 2044, RI_ALL_OFFLINE},
+ { 0x320000, 1, RI_ALL_ONLINE}, { 0x320004, 1023, RI_ALL_OFFLINE},
+ { 0x321000, 1, RI_ALL_ONLINE}, { 0x321004, 4607, RI_ALL_OFFLINE},
+ { 0x325800, 2560, RI_E1H_OFFLINE}, { 0x328000, 64, RI_ALL_OFFLINE},
+ { 0x328100, 536, RI_E1H_OFFLINE}, { 0x328960, 1, RI_E1H_ONLINE},
+ { 0x328964, 8103, RI_E1H_OFFLINE}, { 0x331800, 128, RI_ALL_OFFLINE},
+ { 0x331c00, 128, RI_ALL_OFFLINE}, { 0x332000, 1, RI_ALL_OFFLINE},
+ { 0x332400, 64, RI_E1H_OFFLINE}, { 0x338200, 1, RI_ALL_ONLINE},
+ { 0x338240, 1, RI_ALL_ONLINE}, { 0x338280, 1, RI_ALL_ONLINE},
+ { 0x3382c0, 1, RI_ALL_ONLINE}, { 0x338a00, 1, RI_ALL_ONLINE},
+ { 0x338a80, 1, RI_ALL_ONLINE}, { 0x340000, 2, RI_ALL_ONLINE}
+};
+
+
+#define IDLEREGS_COUNT 277
+static const struct reg_addr idle_addrs[IDLEREGS_COUNT] = {
+ { 0x2114, 1, RI_ALL_ONLINE}, { 0x2120, 1, RI_ALL_ONLINE},
+ { 0x212c, 4, RI_ALL_ONLINE}, { 0x2814, 1, RI_ALL_ONLINE},
+ { 0x281c, 2, RI_ALL_ONLINE}, { 0xa38c, 1, RI_ALL_ONLINE},
+ { 0xa408, 1, RI_ALL_ONLINE}, { 0xa42c, 12, RI_ALL_ONLINE},
+ { 0xa600, 5, RI_E1H_ONLINE}, { 0xa618, 1, RI_E1H_ONLINE},
+ { 0xc09c, 1, RI_ALL_ONLINE}, { 0x103b0, 1, RI_ALL_ONLINE},
+ { 0x103c0, 1, RI_ALL_ONLINE}, { 0x103d0, 1, RI_E1H_ONLINE},
+ { 0x2021c, 11, RI_ALL_ONLINE}, { 0x202a8, 1, RI_ALL_ONLINE},
+ { 0x202b8, 1, RI_ALL_ONLINE}, { 0x20404, 1, RI_ALL_ONLINE},
+ { 0x2040c, 2, RI_ALL_ONLINE}, { 0x2041c, 2, RI_ALL_ONLINE},
+ { 0x40154, 14, RI_ALL_ONLINE}, { 0x40198, 1, RI_ALL_ONLINE},
+ { 0x404ac, 1, RI_ALL_ONLINE}, { 0x404bc, 1, RI_ALL_ONLINE},
+ { 0x42290, 1, RI_ALL_ONLINE}, { 0x422a0, 1, RI_ALL_ONLINE},
+ { 0x422b0, 1, RI_ALL_ONLINE}, { 0x42548, 1, RI_ALL_ONLINE},
+ { 0x42550, 1, RI_ALL_ONLINE}, { 0x42558, 1, RI_ALL_ONLINE},
+ { 0x50160, 8, RI_ALL_ONLINE}, { 0x501d0, 1, RI_ALL_ONLINE},
+ { 0x501e0, 1, RI_ALL_ONLINE}, { 0x50204, 1, RI_ALL_ONLINE},
+ { 0x5020c, 2, RI_ALL_ONLINE}, { 0x5021c, 1, RI_ALL_ONLINE},
+ { 0x60090, 1, RI_ALL_ONLINE}, { 0x6011c, 1, RI_ALL_ONLINE},
+ { 0x6012c, 1, RI_ALL_ONLINE}, { 0xc101c, 1, RI_ALL_ONLINE},
+ { 0xc102c, 1, RI_ALL_ONLINE}, { 0xc2290, 1, RI_ALL_ONLINE},
+ { 0xc22a0, 1, RI_ALL_ONLINE}, { 0xc22b0, 1, RI_ALL_ONLINE},
+ { 0xc2548, 1, RI_ALL_ONLINE}, { 0xc2550, 1, RI_ALL_ONLINE},
+ { 0xc2558, 1, RI_ALL_ONLINE}, { 0xc4294, 1, RI_ALL_ONLINE},
+ { 0xc42a4, 1, RI_ALL_ONLINE}, { 0xc42b4, 1, RI_ALL_ONLINE},
+ { 0xc4550, 1, RI_ALL_ONLINE}, { 0xc4558, 1, RI_ALL_ONLINE},
+ { 0xc4560, 1, RI_ALL_ONLINE}, { 0xd016c, 8, RI_ALL_ONLINE},
+ { 0xd01d8, 1, RI_ALL_ONLINE}, { 0xd01e8, 1, RI_ALL_ONLINE},
+ { 0xd0204, 1, RI_ALL_ONLINE}, { 0xd020c, 3, RI_ALL_ONLINE},
+ { 0xe0154, 8, RI_ALL_ONLINE}, { 0xe01c8, 1, RI_ALL_ONLINE},
+ { 0xe01d8, 1, RI_ALL_ONLINE}, { 0xe0204, 1, RI_ALL_ONLINE},
+ { 0xe020c, 2, RI_ALL_ONLINE}, { 0xe021c, 2, RI_ALL_ONLINE},
+ { 0x101014, 1, RI_ALL_ONLINE}, { 0x101030, 1, RI_ALL_ONLINE},
+ { 0x101040, 1, RI_ALL_ONLINE}, { 0x102058, 1, RI_ALL_ONLINE},
+ { 0x102080, 16, RI_ALL_ONLINE}, { 0x103004, 2, RI_ALL_ONLINE},
+ { 0x103068, 1, RI_ALL_ONLINE}, { 0x103078, 1, RI_ALL_ONLINE},
+ { 0x103088, 1, RI_ALL_ONLINE}, { 0x10309c, 2, RI_E1H_ONLINE},
+ { 0x104004, 1, RI_ALL_ONLINE}, { 0x104018, 1, RI_ALL_ONLINE},
+ { 0x104020, 1, RI_ALL_ONLINE}, { 0x10403c, 1, RI_ALL_ONLINE},
+ { 0x1040fc, 1, RI_ALL_ONLINE}, { 0x10410c, 1, RI_ALL_ONLINE},
+ { 0x104400, 64, RI_ALL_ONLINE}, { 0x104800, 64, RI_ALL_ONLINE},
+ { 0x105000, 3, RI_ALL_ONLINE}, { 0x105010, 3, RI_ALL_ONLINE},
+ { 0x105020, 3, RI_ALL_ONLINE}, { 0x105030, 3, RI_ALL_ONLINE},
+ { 0x105040, 3, RI_ALL_ONLINE}, { 0x105050, 3, RI_ALL_ONLINE},
+ { 0x105060, 3, RI_ALL_ONLINE}, { 0x105070, 3, RI_ALL_ONLINE},
+ { 0x105080, 3, RI_ALL_ONLINE}, { 0x105090, 3, RI_ALL_ONLINE},
+ { 0x1050a0, 3, RI_ALL_ONLINE}, { 0x1050b0, 3, RI_ALL_ONLINE},
+ { 0x1050c0, 3, RI_ALL_ONLINE}, { 0x1050d0, 3, RI_ALL_ONLINE},
+ { 0x1050e0, 3, RI_ALL_ONLINE}, { 0x1050f0, 3, RI_ALL_ONLINE},
+ { 0x105100, 3, RI_ALL_ONLINE}, { 0x105110, 3, RI_ALL_ONLINE},
+ { 0x105120, 3, RI_ALL_ONLINE}, { 0x105130, 3, RI_ALL_ONLINE},
+ { 0x105140, 3, RI_ALL_ONLINE}, { 0x105150, 3, RI_ALL_ONLINE},
+ { 0x105160, 3, RI_ALL_ONLINE}, { 0x105170, 3, RI_ALL_ONLINE},
+ { 0x105180, 3, RI_ALL_ONLINE}, { 0x105190, 3, RI_ALL_ONLINE},
+ { 0x1051a0, 3, RI_ALL_ONLINE}, { 0x1051b0, 3, RI_ALL_ONLINE},
+ { 0x1051c0, 3, RI_ALL_ONLINE}, { 0x1051d0, 3, RI_ALL_ONLINE},
+ { 0x1051e0, 3, RI_ALL_ONLINE}, { 0x1051f0, 3, RI_ALL_ONLINE},
+ { 0x105200, 3, RI_ALL_ONLINE}, { 0x105210, 3, RI_ALL_ONLINE},
+ { 0x105220, 3, RI_ALL_ONLINE}, { 0x105230, 3, RI_ALL_ONLINE},
+ { 0x105240, 3, RI_ALL_ONLINE}, { 0x105250, 3, RI_ALL_ONLINE},
+ { 0x105260, 3, RI_ALL_ONLINE}, { 0x105270, 3, RI_ALL_ONLINE},
+ { 0x105280, 3, RI_ALL_ONLINE}, { 0x105290, 3, RI_ALL_ONLINE},
+ { 0x1052a0, 3, RI_ALL_ONLINE}, { 0x1052b0, 3, RI_ALL_ONLINE},
+ { 0x1052c0, 3, RI_ALL_ONLINE}, { 0x1052d0, 3, RI_ALL_ONLINE},
+ { 0x1052e0, 3, RI_ALL_ONLINE}, { 0x1052f0, 3, RI_ALL_ONLINE},
+ { 0x105300, 3, RI_ALL_ONLINE}, { 0x105310, 3, RI_ALL_ONLINE},
+ { 0x105320, 3, RI_ALL_ONLINE}, { 0x105330, 3, RI_ALL_ONLINE},
+ { 0x105340, 3, RI_ALL_ONLINE}, { 0x105350, 3, RI_ALL_ONLINE},
+ { 0x105360, 3, RI_ALL_ONLINE}, { 0x105370, 3, RI_ALL_ONLINE},
+ { 0x105380, 3, RI_ALL_ONLINE}, { 0x105390, 3, RI_ALL_ONLINE},
+ { 0x1053a0, 3, RI_ALL_ONLINE}, { 0x1053b0, 3, RI_ALL_ONLINE},
+ { 0x1053c0, 3, RI_ALL_ONLINE}, { 0x1053d0, 3, RI_ALL_ONLINE},
+ { 0x1053e0, 3, RI_ALL_ONLINE}, { 0x1053f0, 3, RI_ALL_ONLINE},
+ { 0x108094, 1, RI_ALL_ONLINE}, { 0x1201b0, 2, RI_ALL_ONLINE},
+ { 0x12032c, 1, RI_ALL_ONLINE}, { 0x12036c, 3, RI_ALL_ONLINE},
+ { 0x120408, 2, RI_ALL_ONLINE}, { 0x120414, 15, RI_ALL_ONLINE},
+ { 0x120478, 2, RI_ALL_ONLINE}, { 0x12052c, 1, RI_ALL_ONLINE},
+ { 0x120564, 3, RI_ALL_ONLINE}, { 0x12057c, 1, RI_ALL_ONLINE},
+ { 0x12058c, 1, RI_ALL_ONLINE}, { 0x120608, 1, RI_E1H_ONLINE},
+ { 0x120808, 1, RI_E1_ONLINE}, { 0x12080c, 2, RI_ALL_ONLINE},
+ { 0x120818, 1, RI_ALL_ONLINE}, { 0x120820, 1, RI_ALL_ONLINE},
+ { 0x120828, 1, RI_ALL_ONLINE}, { 0x120830, 1, RI_ALL_ONLINE},
+ { 0x120838, 1, RI_ALL_ONLINE}, { 0x120840, 1, RI_ALL_ONLINE},
+ { 0x120848, 1, RI_ALL_ONLINE}, { 0x120850, 1, RI_ALL_ONLINE},
+ { 0x120858, 1, RI_ALL_ONLINE}, { 0x120860, 1, RI_ALL_ONLINE},
+ { 0x120868, 1, RI_ALL_ONLINE}, { 0x120870, 1, RI_ALL_ONLINE},
+ { 0x120878, 1, RI_ALL_ONLINE}, { 0x120880, 1, RI_ALL_ONLINE},
+ { 0x120888, 1, RI_ALL_ONLINE}, { 0x120890, 1, RI_ALL_ONLINE},
+ { 0x120898, 1, RI_ALL_ONLINE}, { 0x1208a0, 1, RI_ALL_ONLINE},
+ { 0x1208a8, 1, RI_ALL_ONLINE}, { 0x1208b0, 1, RI_ALL_ONLINE},
+ { 0x1208b8, 1, RI_ALL_ONLINE}, { 0x1208c0, 1, RI_ALL_ONLINE},
+ { 0x1208c8, 1, RI_ALL_ONLINE}, { 0x1208d0, 1, RI_ALL_ONLINE},
+ { 0x1208d8, 1, RI_ALL_ONLINE}, { 0x1208e0, 1, RI_ALL_ONLINE},
+ { 0x1208e8, 1, RI_ALL_ONLINE}, { 0x1208f0, 1, RI_ALL_ONLINE},
+ { 0x1208f8, 1, RI_ALL_ONLINE}, { 0x120900, 1, RI_ALL_ONLINE},
+ { 0x120908, 1, RI_ALL_ONLINE}, { 0x14005c, 2, RI_ALL_ONLINE},
+ { 0x1400d0, 2, RI_ALL_ONLINE}, { 0x1400e0, 1, RI_ALL_ONLINE},
+ { 0x1401c8, 1, RI_ALL_ONLINE}, { 0x140200, 6, RI_ALL_ONLINE},
+ { 0x16101c, 1, RI_ALL_ONLINE}, { 0x16102c, 1, RI_ALL_ONLINE},
+ { 0x164014, 2, RI_ALL_ONLINE}, { 0x1640f0, 1, RI_ALL_ONLINE},
+ { 0x166290, 1, RI_ALL_ONLINE}, { 0x1662a0, 1, RI_ALL_ONLINE},
+ { 0x1662b0, 1, RI_ALL_ONLINE}, { 0x166548, 1, RI_ALL_ONLINE},
+ { 0x166550, 1, RI_ALL_ONLINE}, { 0x166558, 1, RI_ALL_ONLINE},
+ { 0x168000, 1, RI_ALL_ONLINE}, { 0x168008, 1, RI_ALL_ONLINE},
+ { 0x168010, 1, RI_ALL_ONLINE}, { 0x168018, 1, RI_ALL_ONLINE},
+ { 0x168028, 2, RI_ALL_ONLINE}, { 0x168058, 4, RI_ALL_ONLINE},
+ { 0x168070, 1, RI_ALL_ONLINE}, { 0x168238, 1, RI_ALL_ONLINE},
+ { 0x1682d0, 2, RI_ALL_ONLINE}, { 0x1682e0, 1, RI_ALL_ONLINE},
+ { 0x168300, 67, RI_ALL_ONLINE}, { 0x168410, 2, RI_ALL_ONLINE},
+ { 0x168438, 1, RI_ALL_ONLINE}, { 0x168448, 1, RI_ALL_ONLINE},
+ { 0x168a00, 128, RI_ALL_ONLINE}, { 0x16e200, 128, RI_E1H_ONLINE},
+ { 0x16e404, 2, RI_E1H_ONLINE}, { 0x16e584, 70, RI_E1H_ONLINE},
+ { 0x1700a4, 1, RI_ALL_ONLINE}, { 0x1700ac, 2, RI_ALL_ONLINE},
+ { 0x1700c0, 1, RI_ALL_ONLINE}, { 0x170174, 1, RI_ALL_ONLINE},
+ { 0x170184, 1, RI_ALL_ONLINE}, { 0x1800f4, 1, RI_ALL_ONLINE},
+ { 0x180104, 1, RI_ALL_ONLINE}, { 0x180114, 1, RI_ALL_ONLINE},
+ { 0x180124, 1, RI_ALL_ONLINE}, { 0x18026c, 1, RI_ALL_ONLINE},
+ { 0x1802a0, 1, RI_ALL_ONLINE}, { 0x1a1000, 1, RI_ALL_ONLINE},
+ { 0x1aa000, 1, RI_E1H_ONLINE}, { 0x1b8000, 1, RI_ALL_ONLINE},
+ { 0x1b8040, 1, RI_ALL_ONLINE}, { 0x1b8080, 1, RI_ALL_ONLINE},
+ { 0x1b80c0, 1, RI_ALL_ONLINE}, { 0x200104, 1, RI_ALL_ONLINE},
+ { 0x200114, 1, RI_ALL_ONLINE}, { 0x200124, 1, RI_ALL_ONLINE},
+ { 0x200134, 1, RI_ALL_ONLINE}, { 0x20026c, 1, RI_ALL_ONLINE},
+ { 0x2002a0, 1, RI_ALL_ONLINE}, { 0x221000, 1, RI_ALL_ONLINE},
+ { 0x227000, 1, RI_E1H_ONLINE}, { 0x238000, 1, RI_ALL_ONLINE},
+ { 0x238040, 1, RI_ALL_ONLINE}, { 0x238080, 1, RI_ALL_ONLINE},
+ { 0x2380c0, 1, RI_ALL_ONLINE}, { 0x280104, 1, RI_ALL_ONLINE},
+ { 0x280114, 1, RI_ALL_ONLINE}, { 0x280124, 1, RI_ALL_ONLINE},
+ { 0x280134, 1, RI_ALL_ONLINE}, { 0x28026c, 1, RI_ALL_ONLINE},
+ { 0x2802a0, 1, RI_ALL_ONLINE}, { 0x2a1000, 1, RI_ALL_ONLINE},
+ { 0x2a9000, 1, RI_E1H_ONLINE}, { 0x2b8000, 1, RI_ALL_ONLINE},
+ { 0x2b8040, 1, RI_ALL_ONLINE}, { 0x2b8080, 1, RI_ALL_ONLINE},
+ { 0x2b80c0, 1, RI_ALL_ONLINE}, { 0x300104, 1, RI_ALL_ONLINE},
+ { 0x300114, 1, RI_ALL_ONLINE}, { 0x300124, 1, RI_ALL_ONLINE},
+ { 0x300134, 1, RI_ALL_ONLINE}, { 0x30026c, 1, RI_ALL_ONLINE},
+ { 0x3002a0, 1, RI_ALL_ONLINE}, { 0x321000, 1, RI_ALL_ONLINE},
+ { 0x328960, 1, RI_E1H_ONLINE}, { 0x338000, 1, RI_ALL_ONLINE},
+ { 0x338040, 1, RI_ALL_ONLINE}, { 0x338080, 1, RI_ALL_ONLINE},
+ { 0x3380c0, 1, RI_ALL_ONLINE}
+};
+
+static const u32 read_reg_e1_0[] = { 0x1b1000 };
+
+#define WREGS_COUNT_E1 1
+static const struct wreg_addr wreg_addrs_e1[WREGS_COUNT_E1] = {
+ { 0x1b0c00, 192, 1, read_reg_e1_0, RI_E1_OFFLINE }
+};
+
+static const u32 read_reg_e1h_0[] = { 0x1b1040, 0x1b1000 };
+
+#define WREGS_COUNT_E1H 1
+static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = {
+ { 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE }
+};
+
+
+static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 };
+
+
+#define TIMER_REGS_COUNT_E1 2
+static const u32 timer_status_regs_e1[TIMER_REGS_COUNT_E1] =
+ { 0x164014, 0x164018 };
+static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] =
+ { 0x1640d0, 0x1640d4 };
+
+#define TIMER_REGS_COUNT_E1H 2
+static const u32 timer_status_regs_e1h[TIMER_REGS_COUNT_E1H] =
+ { 0x164014, 0x164018 };
+static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] =
+ { 0x1640d0, 0x1640d4 };
+
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
index 192fa981b93..e2df2380359 100644
--- a/drivers/net/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x_fw_defs.h
@@ -1,6 +1,6 @@
/* bnx2x_fw_defs.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * 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
@@ -50,8 +50,10 @@
#define TSTORM_ASSERT_LIST_OFFSET(idx) \
(IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \
- (IS_E1H_OFFSET ? (0x3358 + (port * 0x3e8) + (client_id * 0x28)) \
- : (0x9c8 + (port * 0x2f8) + (client_id * 0x28)))
+ (IS_E1H_OFFSET ? (0x3350 + (port * 0x190) + (client_id * 0x10)) \
+ : (0x9c0 + (port * 0x130) + (client_id * 0x10)))
+#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET \
+ (IS_E1H_OFFSET ? 0x1ad8 : 0xffffffff)
#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
(IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \
((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
@@ -81,43 +83,54 @@
(function * 0x38)))
#define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
(IS_E1H_OFFSET ? (0x2010 + (port * 0x5b0) + (stats_counter_id * \
- 0x50)) : (0x4000 + (port * 0x3f0) + (stats_counter_id * 0x38)))
-#define TSTORM_RX_PRODS_OFFSET(port, client_id) \
- (IS_E1H_OFFSET ? (0x3350 + (port * 0x3e8) + (client_id * 0x28)) \
- : (0x9c0 + (port * 0x2f8) + (client_id * 0x28)))
+ 0x50)) : (0x4080 + (port * 0x5b0) + (stats_counter_id * 0x50)))
#define TSTORM_STATS_FLAGS_OFFSET(function) \
(IS_E1H_OFFSET ? (0x2c00 + (function * 0x8)) : (0x4b88 + \
(function * 0x8)))
-#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3b30 : 0x1c20)
+#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3680 : 0x1c20)
#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa040 : 0x2c10)
#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2440 : 0x1200)
#define USTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0x8000 : 0x1000)
+ (IS_E1H_OFFSET ? 0x8960 : 0x1000)
#define USTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
+ (IS_E1H_OFFSET ? (0x8980 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x3298 + (port * 0x258) + (clientId * 0x18)) : \
- (0x5450 + (port * 0x1c8) + (clientId * 0x18)))
+ (IS_E1H_OFFSET ? (0x8018 + (port * 0x4b0) + (clientId * 0x30)) : \
+ (0x5330 + (port * 0x260) + (clientId * 0x20)))
#define USTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0x951a + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0) + (index * 0x4)) : (0x191a + (function * \
- 0x28) + (index * 0x4)))
+ (IS_E1H_OFFSET ? (0x9522 + ((function>>1) * 0x40) + \
+ ((function&1) * 0x100) + (index * 0x4)) : (0x1922 + (function * \
+ 0x40) + (index * 0x4)))
#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1900 + (function * 0x28)))
+ (IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x40) + \
+ ((function&1) * 0x100)) : (0x1900 + (function * 0x40)))
#define USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1908 + (function * 0x28)))
+ (IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x40) + \
+ ((function&1) * 0x100)) : (0x1908 + (function * 0x40)))
+#define USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, clientId) \
+ (IS_E1H_OFFSET ? (0x8020 + (port * 0x4b0) + (clientId * 0x30)) : \
+ 0xffffffff)
+#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
+ (IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1d98 + \
+ (function * 0x8)))
#define USTORM_FUNCTION_MODE_OFFSET \
(IS_E1H_OFFSET ? 0x2448 : 0xffffffff)
#define USTORM_HC_BTR_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x9644 + (port * 0xd0)) : (0x1954 + (port * 0xb8)))
+ (IS_E1H_OFFSET ? (0x9704 + (port * 0xf0)) : (0x1984 + (port * 0xc0)))
#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x3290 + (port * 0x258) + (clientId * 0x18)) : \
- (0x5448 + (port * 0x1c8) + (clientId * 0x18)))
+ (IS_E1H_OFFSET ? (0x8010 + (port * 0x4b0) + (clientId * 0x30)) : \
+ (0x5328 + (port * 0x260) + (clientId * 0x20)))
#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5408 + \
+ (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5308 + \
(function * 0x8)))
+#define USTORM_PAUSE_ENABLED_OFFSET(port) \
+ (IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff)
+#define USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
+ (IS_E1H_OFFSET ? (0x2450 + (port * 0x2d0) + (stats_counter_id * \
+ 0x28)) : (0x4740 + (port * 0x2d0) + (stats_counter_id * 0x28)))
+#define USTORM_RX_PRODS_OFFSET(port, client_id) \
+ (IS_E1H_OFFSET ? (0x8000 + (port * 0x4b0) + (client_id * 0x30)) \
+ : (0x5318 + (port * 0x260) + (client_id * 0x20)))
#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
(IS_E1H_OFFSET ? (0x901a + (port * 0x280) + (cpu_id * 0x28) + \
(index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
@@ -132,12 +145,15 @@
#define USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
(IS_E1H_OFFSET ? (0x9008 + (port * 0x280) + (cpu_id * 0x28)) : \
(0x1408 + (port * 0x280) + (cpu_id * 0x28)))
+#define USTORM_STATS_FLAGS_OFFSET(function) \
+ (IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1d80 + \
+ (function * 0x8)))
#define XSTORM_ASSERT_LIST_INDEX_OFFSET \
(IS_E1H_OFFSET ? 0x9000 : 0x1000)
#define XSTORM_ASSERT_LIST_OFFSET(idx) \
(IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x24a8 + (port * 0x40)) : (0x3ba0 + (port * 0x40)))
+ (IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3ba0 + (port * 0x50)))
#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
(IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \
((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
@@ -149,23 +165,23 @@
(IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \
((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
#define XSTORM_E1HOV_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2ab8 + (function * 0x2)) : 0xffffffff)
+ (IS_E1H_OFFSET ? (0x2c10 + (function * 0x2)) : 0xffffffff)
#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
(IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3b70 + \
(function * 0x8)))
#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2568 + (function * 0x70)) : (0x3c60 + \
- (function * 0x70)))
+ (IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3c80 + \
+ (function * 0x90)))
#define XSTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x2ac8 : 0xffffffff)
+ (IS_E1H_OFFSET ? 0x2c20 : 0xffffffff)
#define XSTORM_HC_BTR_OFFSET(port) \
(IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
#define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
(IS_E1H_OFFSET ? (0xc000 + (port * 0x3f0) + (stats_counter_id * \
0x38)) : (0x3378 + (port * 0x3f0) + (stats_counter_id * 0x38)))
#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2528 + (function * 0x70)) : (0x3c20 + \
- (function * 0x70)))
+ (IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3c40 + \
+ (function * 0x90)))
#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \
(IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \
(function * 0x10)))
@@ -178,7 +194,7 @@
#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
/**
-* This file defines HSI constatnts for the ETH flow
+* This file defines HSI constants for the ETH flow
*/
#ifdef _EVEREST_MICROCODE
#include "microcode_constants.h"
@@ -196,18 +212,18 @@
#define IPV6_HASH_TYPE 3
#define TCP_IPV6_HASH_TYPE 4
-/* Ethernet Ring parmaters */
+
+/* Ethernet Ring parameters */
#define X_ETH_LOCAL_RING_SIZE 13
#define FIRST_BD_IN_PKT 0
#define PARSE_BD_INDEX 1
-#define NUM_OF_ETH_BDS_IN_PAGE \
- ((PAGE_SIZE) / (STRUCT_SIZE(eth_tx_bd)/8))
+#define NUM_OF_ETH_BDS_IN_PAGE ((PAGE_SIZE)/(STRUCT_SIZE(eth_tx_bd)/8))
/* Rx ring params */
-#define U_ETH_LOCAL_BD_RING_SIZE (16)
-#define U_ETH_LOCAL_SGE_RING_SIZE (12)
-#define U_ETH_SGL_SIZE (8)
+#define U_ETH_LOCAL_BD_RING_SIZE 16
+#define U_ETH_LOCAL_SGE_RING_SIZE 12
+#define U_ETH_SGL_SIZE 8
#define U_ETH_BDS_PER_PAGE_MASK \
@@ -229,15 +245,15 @@
#define U_ETH_UNDEFINED_Q 0xFF
/* values of command IDs in the ramrod message */
-#define RAMROD_CMD_ID_ETH_PORT_SETUP (80)
-#define RAMROD_CMD_ID_ETH_CLIENT_SETUP (85)
-#define RAMROD_CMD_ID_ETH_STAT_QUERY (90)
-#define RAMROD_CMD_ID_ETH_UPDATE (100)
-#define RAMROD_CMD_ID_ETH_HALT (105)
-#define RAMROD_CMD_ID_ETH_SET_MAC (110)
-#define RAMROD_CMD_ID_ETH_CFC_DEL (115)
-#define RAMROD_CMD_ID_ETH_PORT_DEL (120)
-#define RAMROD_CMD_ID_ETH_FORWARD_SETUP (125)
+#define RAMROD_CMD_ID_ETH_PORT_SETUP 80
+#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 85
+#define RAMROD_CMD_ID_ETH_STAT_QUERY 90
+#define RAMROD_CMD_ID_ETH_UPDATE 100
+#define RAMROD_CMD_ID_ETH_HALT 105
+#define RAMROD_CMD_ID_ETH_SET_MAC 110
+#define RAMROD_CMD_ID_ETH_CFC_DEL 115
+#define RAMROD_CMD_ID_ETH_PORT_DEL 120
+#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 125
/* command values for set mac command */
@@ -254,12 +270,16 @@
#define ETH_MAX_RX_CLIENTS_E1H 25
/* Maximal aggregation queues supported */
-#define ETH_MAX_AGGREGATION_QUEUES_E1 (32)
-#define ETH_MAX_AGGREGATION_QUEUES_E1H (64)
+#define ETH_MAX_AGGREGATION_QUEUES_E1 32
+#define ETH_MAX_AGGREGATION_QUEUES_E1H 64
+
+/* ETH RSS modes */
+#define ETH_RSS_MODE_DISABLED 0
+#define ETH_RSS_MODE_REGULAR 1
/**
-* This file defines HSI constatnts common to all microcode flows
+* This file defines HSI constants common to all microcode flows
*/
/* Connection types */
@@ -278,25 +298,22 @@
#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
#define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
#define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define ISCSI_STATE \
- (ISCSI_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define FCOE_STATE (FCOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
/* microcode fixed page page size 4K (chains and ring segments) */
-#define MC_PAGE_SIZE (4096)
+#define MC_PAGE_SIZE 4096
/* Host coalescing constants */
/* index numbers */
-#define HC_USTORM_DEF_SB_NUM_INDICES 4
+#define HC_USTORM_DEF_SB_NUM_INDICES 8
#define HC_CSTORM_DEF_SB_NUM_INDICES 8
#define HC_XSTORM_DEF_SB_NUM_INDICES 4
#define HC_TSTORM_DEF_SB_NUM_INDICES 4
#define HC_USTORM_SB_NUM_INDICES 4
#define HC_CSTORM_SB_NUM_INDICES 4
-/* index values - which counterto update */
+/* index values - which counter to update */
#define HC_INDEX_U_TOE_RX_CQ_CONS 0
#define HC_INDEX_U_ETH_RX_CQ_CONS 1
@@ -330,16 +347,16 @@
#define ATTENTION_ID 4
/* max number of slow path commands per port */
-#define MAX_RAMRODS_PER_PORT (8)
+#define MAX_RAMRODS_PER_PORT 8
/* values for RX ETH CQE type field */
-#define RX_ETH_CQE_TYPE_ETH_FASTPATH (0)
-#define RX_ETH_CQE_TYPE_ETH_RAMROD (1)
+#define RX_ETH_CQE_TYPE_ETH_FASTPATH 0
+#define RX_ETH_CQE_TYPE_ETH_RAMROD 1
/**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
-#define EMULATION_FREQUENCY_FACTOR (1600)
-#define FPGA_FREQUENCY_FACTOR (100)
+#define EMULATION_FREQUENCY_FACTOR 1600
+#define FPGA_FREQUENCY_FACTOR 100
#define TIMERS_TICK_SIZE_CHIP (1e-3)
#define TIMERS_TICK_SIZE_EMUL \
@@ -353,12 +370,9 @@
#define TSEMI_CLK1_RESUL_FPGA \
((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-#define USEMI_CLK1_RESUL_CHIP \
- (TIMERS_TICK_SIZE_CHIP)
-#define USEMI_CLK1_RESUL_EMUL \
- (TIMERS_TICK_SIZE_EMUL)
-#define USEMI_CLK1_RESUL_FPGA \
- (TIMERS_TICK_SIZE_FPGA)
+#define USEMI_CLK1_RESUL_CHIP (TIMERS_TICK_SIZE_CHIP)
+#define USEMI_CLK1_RESUL_EMUL (TIMERS_TICK_SIZE_EMUL)
+#define USEMI_CLK1_RESUL_FPGA (TIMERS_TICK_SIZE_FPGA)
#define XSEMI_CLK1_RESUL_CHIP (1e-3)
#define XSEMI_CLK1_RESUL_EMUL \
@@ -383,12 +397,15 @@
#define XSTORM_IP_ID_ROLL_HALF 0x8000
#define XSTORM_IP_ID_ROLL_ALL 0
-#define FW_LOG_LIST_SIZE (50)
+#define FW_LOG_LIST_SIZE 50
#define NUM_OF_PROTOCOLS 4
-#define MAX_COS_NUMBER 16
+#define NUM_OF_SAFC_BITS 16
+#define MAX_COS_NUMBER 4
#define MAX_T_STAT_COUNTER_ID 18
#define MAX_X_STAT_COUNTER_ID 18
+#define MAX_U_STAT_COUNTER_ID 18
+
#define UNKNOWN_ADDRESS 0
#define UNICAST_ADDRESS 1
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index efd764427fa..03c62421d99 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -1,6 +1,6 @@
/* bnx2x_hsi.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * 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
@@ -119,35 +119,15 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_BCM5221 0x00010000
u32 board; /* 0x124 */
-#define SHARED_HW_CFG_BOARD_TYPE_MASK 0x0000ffff
-#define SHARED_HW_CFG_BOARD_TYPE_SHIFT 0
-#define SHARED_HW_CFG_BOARD_TYPE_NONE 0x00000000
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1000 0x00000001
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1001 0x00000002
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G 0x00000003
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1004G 0x00000004
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1007G 0x00000005
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G 0x00000006
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G 0x00000007
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G 0x00000009
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G 0x0000000a
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1023G 0x0000000b
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1033G 0x0000000c
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711T1101 0x0000000d
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711ET1201 0x0000000e
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711A1133G 0x0000000f
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711EA1233G 0x00000010
-
-#define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000
-#define SHARED_HW_CFG_BOARD_VER_SHIFT 16
-#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK 0xf0000000
-#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT 28
-#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK 0x0f000000
-#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT 24
-#define SHARED_HW_CFG_BOARD_REV_MASK 0x00ff0000
+#define SHARED_HW_CFG_BOARD_REV_MASK 0x00FF0000
#define SHARED_HW_CFG_BOARD_REV_SHIFT 16
+#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK 0x0F000000
+#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT 24
+
+#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK 0xF0000000
+#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT 28
+
u32 reserved; /* 0x128 */
};
@@ -198,36 +178,21 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
u32 rdma_mac_lower;
u32 serdes_config;
- /* for external PHY, or forced mode or during AN */
-#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000
-#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT 16
+#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK 0x0000FFFF
+#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT 0
-#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK 0x0000ffff
-#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 0
+#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK 0xFFFF0000
+#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 16
- u16 serdes_tx_driver_pre_emphasis[16];
- u16 serdes_rx_driver_equalizer[16];
- u32 xgxs_config_lane0;
- u32 xgxs_config_lane1;
- u32 xgxs_config_lane2;
- u32 xgxs_config_lane3;
- /* for external PHY, or forced mode or during AN */
-#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000
-#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_SHIFT 16
+ u32 Reserved0[16]; /* 0x158 */
-#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_MASK 0x0000ffff
-#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_SHIFT 0
+ /* for external PHY, or forced mode or during AN */
+ u16 xgxs_config_rx[4]; /* 0x198 */
- u16 xgxs_tx_driver_pre_emphasis_lane0[16];
- u16 xgxs_tx_driver_pre_emphasis_lane1[16];
- u16 xgxs_tx_driver_pre_emphasis_lane2[16];
- u16 xgxs_tx_driver_pre_emphasis_lane3[16];
+ u16 xgxs_config_tx[4]; /* 0x1A0 */
- u16 xgxs_rx_driver_equalizer_lane0[16];
- u16 xgxs_rx_driver_equalizer_lane1[16];
- u16 xgxs_rx_driver_equalizer_lane2[16];
- u16 xgxs_rx_driver_equalizer_lane3[16];
+ u32 Reserved1[64]; /* 0x1A8 */
u32 lane_config;
#define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff
@@ -265,7 +230,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073 0x00000300
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705 0x00000400
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726 0x00000600
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
@@ -319,6 +284,12 @@ struct shared_feat_cfg { /* NVRAM Offset */
u32 config; /* 0x450 */
#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001
+
+ /* Use the values from options 47 and 48 instead of the HW default
+ values */
+#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000
+#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002
+
#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100
};
@@ -372,6 +343,11 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
#define PORT_FEATURE_MBA_ENABLED 0x02000000
#define PORT_FEATURE_MFW_ENABLED 0x04000000
+ /* Check the optic vendor via i2c before allowing it to be used by
+ SW */
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLED 0x00000000
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED 0x08000000
+
u32 wol_config;
/* Default is used when driver sets to "auto" mode */
#define PORT_FEATURE_WOL_DEFAULT_MASK 0x00000003
@@ -512,7 +488,7 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
/****************************************************************************
* Device Information *
****************************************************************************/
-struct dev_info { /* size */
+struct shm_dev_info { /* size */
u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
@@ -641,7 +617,10 @@ struct drv_port_mb {
u32 port_stx;
- u32 reserved[2];
+ u32 stat_nig_timer;
+
+ /* MCP firmware does not use this field */
+ u32 ext_phy_fw_version;
};
@@ -827,11 +806,7 @@ struct mf_cfg {
struct shared_mf_cfg shared_mf_config;
struct port_mf_cfg port_mf_config[PORT_MAX];
-#if defined(b710)
- struct func_mf_cfg func_mf_config[E1_FUNC_MAX];
-#else
struct func_mf_cfg func_mf_config[E1H_FUNC_MAX];
-#endif
};
@@ -862,7 +837,7 @@ struct shmem_region { /* SharedMem Offset (size) */
#define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0
#define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0
- struct dev_info dev_info; /* 0x8 (0x438) */
+ struct shm_dev_info dev_info; /* 0x8 (0x438) */
u8 reserved[52*PORT_MAX];
@@ -1212,8 +1187,9 @@ struct host_func_stats {
#define BCM_5710_FW_MAJOR_VERSION 4
-#define BCM_5710_FW_MINOR_VERSION 5
-#define BCM_5710_FW_REVISION_VERSION 1
+#define BCM_5710_FW_MINOR_VERSION 8
+#define BCM_5710_FW_REVISION_VERSION 53
+#define BCM_5710_FW_ENGINEERING_VERSION 0
#define BCM_5710_FW_COMPILE_FLAGS 1
@@ -1221,18 +1197,12 @@ struct host_func_stats {
* attention bits
*/
struct atten_def_status_block {
- u32 attn_bits;
- u32 attn_bits_ack;
-#if defined(__BIG_ENDIAN)
- u16 attn_bits_index;
- u8 reserved0;
- u8 status_block_id;
-#elif defined(__LITTLE_ENDIAN)
+ __le32 attn_bits;
+ __le32 attn_bits_ack;
u8 status_block_id;
u8 reserved0;
- u16 attn_bits_index;
-#endif
- u32 reserved1;
+ __le16 attn_bits_index;
+ __le32 reserved1;
};
@@ -1305,7 +1275,7 @@ struct igu_ack_register {
* Parser parsing flags field
*/
struct parsing_flags {
- u16 flags;
+ __le16 flags;
#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE (0x1<<0)
#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE_SHIFT 0
#define PARSING_FLAGS_VLAN (0x1<<1)
@@ -1336,8 +1306,8 @@ struct parsing_flags {
struct regpair {
- u32 lo;
- u32 hi;
+ __le32 lo;
+ __le32 hi;
};
@@ -1434,8 +1404,10 @@ struct ustorm_eth_st_context_config {
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<4)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 4
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0x7<<5)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 5
u8 status_block_id;
u8 clientId;
u8 sb_index_numbers;
@@ -1460,14 +1432,18 @@ struct ustorm_eth_st_context_config {
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<4)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 4
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0x7<<5)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 5
#endif
#if defined(__BIG_ENDIAN)
u16 bd_buff_size;
- u16 mc_alignment_size;
+ u8 statistics_counter_id;
+ u8 mc_alignment_log_size;
#elif defined(__LITTLE_ENDIAN)
- u16 mc_alignment_size;
+ u8 mc_alignment_log_size;
+ u8 statistics_counter_id;
u16 bd_buff_size;
#endif
#if defined(__BIG_ENDIAN)
@@ -1479,13 +1455,7 @@ struct ustorm_eth_st_context_config {
u8 __local_bd_prod;
u8 __local_sge_prod;
#endif
-#if defined(__BIG_ENDIAN)
- u16 __bd_cons;
- u16 __sge_cons;
-#elif defined(__LITTLE_ENDIAN)
- u16 __sge_cons;
- u16 __bd_cons;
-#endif
+ u32 reserved;
u32 bd_page_base_lo;
u32 bd_page_base_hi;
u32 sge_page_base_lo;
@@ -1496,16 +1466,16 @@ struct ustorm_eth_st_context_config {
* The eth Rx Buffer Descriptor
*/
struct eth_rx_bd {
- u32 addr_lo;
- u32 addr_hi;
+ __le32 addr_lo;
+ __le32 addr_hi;
};
/*
* The eth Rx SGE Descriptor
*/
struct eth_rx_sge {
- u32 addr_lo;
- u32 addr_hi;
+ __le32 addr_lo;
+ __le32 addr_hi;
};
/*
@@ -1697,7 +1667,7 @@ struct xstorm_eth_ag_context {
};
/*
- * The eth aggregative context section of Tstorm
+ * The eth extra aggregative context section of Tstorm
*/
struct tstorm_eth_extra_ag_context_section {
u32 __agg_val1;
@@ -1908,11 +1878,11 @@ struct eth_tx_bd_flags {
* The eth Tx Buffer Descriptor
*/
struct eth_tx_bd {
- u32 addr_lo;
- u32 addr_hi;
- u16 nbd;
- u16 nbytes;
- u16 vlan;
+ __le32 addr_lo;
+ __le32 addr_hi;
+ __le16 nbd;
+ __le16 nbytes;
+ __le16 vlan;
struct eth_tx_bd_flags bd_flags;
u8 general_data;
#define ETH_TX_BD_HDR_NBDS (0x3F<<0)
@@ -1955,11 +1925,11 @@ struct eth_tx_parse_bd {
#define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7
u8 ip_hlen;
s8 cs_offset;
- u16 total_hlen;
- u16 lso_mss;
- u16 tcp_pseudo_csum;
- u16 ip_id;
- u32 tcp_send_seq;
+ __le16 total_hlen;
+ __le16 lso_mss;
+ __le16 tcp_pseudo_csum;
+ __le16 ip_id;
+ __le32 tcp_send_seq;
};
/*
@@ -2075,44 +2045,44 @@ struct eth_tx_doorbell {
* ustorm status block
*/
struct ustorm_def_status_block {
- u16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
* cstorm status block
*/
struct cstorm_def_status_block {
- u16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
* xstorm status block
*/
struct xstorm_def_status_block {
- u16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
* tstorm status block
*/
struct tstorm_def_status_block {
- u16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
@@ -2131,22 +2101,22 @@ struct host_def_status_block {
* ustorm status block
*/
struct ustorm_status_block {
- u16 index_values[HC_USTORM_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_USTORM_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
* cstorm status block
*/
struct cstorm_status_block {
- u16 index_values[HC_CSTORM_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_CSTORM_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
@@ -2162,9 +2132,9 @@ struct host_status_block {
* The data for RSS setup ramrod
*/
struct eth_client_setup_ramrod_data {
- u32 client_id_5b;
- u8 is_rdma_1b;
- u8 reserved0;
+ u32 client_id;
+ u8 is_rdma;
+ u8 is_fcoe;
u16 reserved1;
};
@@ -2212,12 +2182,12 @@ struct eth_fast_path_rx_cqe {
#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7
u8 placement_offset;
u8 queue_index;
- u32 rss_hash_result;
- u16 vlan_tag;
- u16 pkt_len;
- u16 len_on_bd;
+ __le32 rss_hash_result;
+ __le16 vlan_tag;
+ __le16 pkt_len;
+ __le16 len_on_bd;
struct parsing_flags pars_flags;
- u16 sgl[8];
+ __le16 sgl[8];
};
@@ -2225,7 +2195,7 @@ struct eth_fast_path_rx_cqe {
* The data for RSS setup ramrod
*/
struct eth_halt_ramrod_data {
- u32 client_id_5b;
+ u32 client_id;
u32 reserved0;
};
@@ -2236,11 +2206,11 @@ struct eth_halt_ramrod_data {
struct eth_query_ramrod_data {
#if defined(__BIG_ENDIAN)
u8 reserved0;
- u8 collect_port_1b;
+ u8 collect_port;
u16 drv_counter;
#elif defined(__LITTLE_ENDIAN)
u16 drv_counter;
- u8 collect_port_1b;
+ u8 collect_port;
u8 reserved0;
#endif
u32 ctr_id_vector;
@@ -2251,8 +2221,8 @@ struct eth_query_ramrod_data {
* Place holder for ramrods protocol specific data
*/
struct ramrod_data {
- u32 data_lo;
- u32 data_hi;
+ __le32 data_lo;
+ __le32 data_hi;
};
/*
@@ -2264,16 +2234,6 @@ union eth_ramrod_data {
/*
- * Rx Last BD in page (in ETH)
- */
-struct eth_rx_bd_next_page {
- u32 addr_lo;
- u32 addr_hi;
- u8 reserved[8];
-};
-
-
-/*
* Eth Rx Cqe structure- general structure for ramrods
*/
struct common_ramrod_eth_rx_cqe {
@@ -2282,24 +2242,24 @@ struct common_ramrod_eth_rx_cqe {
#define COMMON_RAMROD_ETH_RX_CQE_TYPE_SHIFT 0
#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x7F<<1)
#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 1
- u8 conn_type_3b;
- u16 reserved1;
- u32 conn_and_cmd_data;
+ u8 conn_type;
+ __le16 reserved1;
+ __le32 conn_and_cmd_data;
#define COMMON_RAMROD_ETH_RX_CQE_CID (0xFFFFFF<<0)
#define COMMON_RAMROD_ETH_RX_CQE_CID_SHIFT 0
#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24)
#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24
struct ramrod_data protocol_data;
- u32 reserved2[4];
+ __le32 reserved2[4];
};
/*
* Rx Last CQE in page (in ETH)
*/
struct eth_rx_cqe_next_page {
- u32 addr_lo;
- u32 addr_hi;
- u32 reserved[6];
+ __le32 addr_lo;
+ __le32 addr_hi;
+ __le32 reserved[6];
};
/*
@@ -2316,17 +2276,17 @@ union eth_rx_cqe {
* common data for all protocols
*/
struct spe_hdr {
- u32 conn_and_cmd_data;
+ __le32 conn_and_cmd_data;
#define SPE_HDR_CID (0xFFFFFF<<0)
#define SPE_HDR_CID_SHIFT 0
#define SPE_HDR_CMD_ID (0xFF<<24)
#define SPE_HDR_CMD_ID_SHIFT 24
- u16 type;
+ __le16 type;
#define SPE_HDR_CONN_TYPE (0xFF<<0)
#define SPE_HDR_CONN_TYPE_SHIFT 0
#define SPE_HDR_COMMON_RAMROD (0xFF<<8)
#define SPE_HDR_COMMON_RAMROD_SHIFT 8
- u16 reserved;
+ __le16 reserved;
};
/*
@@ -2355,9 +2315,9 @@ struct eth_spe {
* doorbell data in host memory
*/
struct eth_tx_db_data {
- u32 packets_prod;
- u16 bds_prod;
- u16 reserved;
+ __le32 packets_prod;
+ __le16 bds_prod;
+ __le16 reserved;
};
@@ -2377,14 +2337,16 @@ struct tstorm_eth_function_common_config {
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3F<<10)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 10
#elif defined(__LITTLE_ENDIAN)
u16 config_flags;
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
@@ -2395,14 +2357,16 @@ struct tstorm_eth_function_common_config {
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3F<<10)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 10
u8 rss_result_mask;
u8 leading_client_id;
#endif
@@ -2422,7 +2386,7 @@ struct eth_update_ramrod_data {
* MAC filtering configuration command header
*/
struct mac_configuration_hdr {
- u8 length_6b;
+ u8 length;
u8 offset;
u16 client_id;
u32 reserved1;
@@ -2432,10 +2396,10 @@ struct mac_configuration_hdr {
* MAC address in list for ramrod
*/
struct tstorm_cam_entry {
- u16 lsb_mac_addr;
- u16 middle_mac_addr;
- u16 msb_mac_addr;
- u16 flags;
+ __le16 lsb_mac_addr;
+ __le16 middle_mac_addr;
+ __le16 msb_mac_addr;
+ __le16 flags;
#define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0)
#define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0
#define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1)
@@ -2484,11 +2448,11 @@ struct mac_configuration_cmd {
* MAC address in list for ramrod
*/
struct mac_configuration_entry_e1h {
- u16 lsb_mac_addr;
- u16 middle_mac_addr;
- u16 msb_mac_addr;
- u16 vlan_id;
- u16 e1hov_id;
+ __le16 lsb_mac_addr;
+ __le16 middle_mac_addr;
+ __le16 msb_mac_addr;
+ __le16 vlan_id;
+ __le16 e1hov_id;
u8 client_id;
u8 flags;
#define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0)
@@ -2544,24 +2508,28 @@ struct tstorm_eth_client_config {
#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 3
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 4
#elif defined(__LITTLE_ENDIAN)
u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 3
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 4
u16 drop_flags;
#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
@@ -2594,9 +2562,61 @@ struct tstorm_eth_mac_filter_config {
/*
+ * common flag to indicate existance of TPA.
+ */
+struct tstorm_eth_tpa_exist {
+#if defined(__BIG_ENDIAN)
+ u16 reserved1;
+ u8 reserved0;
+ u8 tpa_exist;
+#elif defined(__LITTLE_ENDIAN)
+ u8 tpa_exist;
+ u8 reserved0;
+ u16 reserved1;
+#endif
+ u32 reserved2;
+};
+
+
+/*
+ * rx rings pause data for E1h only
+ */
+struct ustorm_eth_rx_pause_data_e1h {
+#if defined(__BIG_ENDIAN)
+ u16 bd_thr_low;
+ u16 cqe_thr_low;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cqe_thr_low;
+ u16 bd_thr_low;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 cos;
+ u16 sge_thr_low;
+#elif defined(__LITTLE_ENDIAN)
+ u16 sge_thr_low;
+ u16 cos;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 bd_thr_high;
+ u16 cqe_thr_high;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cqe_thr_high;
+ u16 bd_thr_high;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 reserved0;
+ u16 sge_thr_high;
+#elif defined(__LITTLE_ENDIAN)
+ u16 sge_thr_high;
+ u16 reserved0;
+#endif
+};
+
+
+/*
* Three RX producers for ETH
*/
-struct tstorm_eth_rx_producers {
+struct ustorm_eth_rx_producers {
#if defined(__BIG_ENDIAN)
u16 bd_prod;
u16 cqe_prod;
@@ -2615,38 +2635,23 @@ struct tstorm_eth_rx_producers {
/*
- * common flag to indicate existence of TPA.
- */
-struct tstorm_eth_tpa_exist {
-#if defined(__BIG_ENDIAN)
- u16 reserved1;
- u8 reserved0;
- u8 tpa_exist;
-#elif defined(__LITTLE_ENDIAN)
- u8 tpa_exist;
- u8 reserved0;
- u16 reserved1;
-#endif
- u32 reserved2;
-};
-
-
-/*
* per-port SAFC demo variables
*/
struct cmng_flags_per_port {
u8 con_number[NUM_OF_PROTOCOLS];
-#if defined(__BIG_ENDIAN)
- u8 fairness_enable;
- u8 rate_shaping_enable;
- u8 cmng_protocol_enable;
- u8 cmng_vn_enable;
-#elif defined(__LITTLE_ENDIAN)
- u8 cmng_vn_enable;
- u8 cmng_protocol_enable;
- u8 rate_shaping_enable;
- u8 fairness_enable;
-#endif
+ u32 cmng_enables;
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_VN (0x1<<0)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_VN_SHIFT 0
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN (0x1<<1)
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN_SHIFT 1
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL (0x1<<2)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL_SHIFT 2
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL (0x1<<3)
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4
+#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x7FFFFFF<<5)
+#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 5
};
@@ -2674,15 +2679,15 @@ struct fairness_vars_per_port {
*/
struct safc_struct_per_port {
#if defined(__BIG_ENDIAN)
- u16 __reserved0;
- u8 cur_cos_types;
+ u16 __reserved1;
+ u8 __reserved0;
u8 safc_timeout_usec;
#elif defined(__LITTLE_ENDIAN)
u8 safc_timeout_usec;
- u8 cur_cos_types;
- u16 __reserved0;
+ u8 __reserved0;
+ u16 __reserved1;
#endif
- u8 cos_to_protocol[MAX_COS_NUMBER];
+ u16 cos_to_pause_mask[NUM_OF_SAFC_BITS];
};
@@ -2702,16 +2707,16 @@ struct cmng_struct_per_port {
*/
struct xstorm_per_client_stats {
struct regpair total_sent_bytes;
- u32 total_sent_pkts;
- u32 unicast_pkts_sent;
+ __le32 total_sent_pkts;
+ __le32 unicast_pkts_sent;
struct regpair unicast_bytes_sent;
struct regpair multicast_bytes_sent;
- u32 multicast_pkts_sent;
- u32 broadcast_pkts_sent;
+ __le32 multicast_pkts_sent;
+ __le32 broadcast_pkts_sent;
struct regpair broadcast_bytes_sent;
- u16 stats_counter;
- u16 reserved0;
- u32 reserved1;
+ __le16 stats_counter;
+ __le16 reserved0;
+ __le32 reserved1;
};
@@ -2727,10 +2732,10 @@ struct xstorm_common_stats {
* Protocol-common statistics collected by the Tstorm (per port)
*/
struct tstorm_per_port_stats {
- u32 mac_filter_discard;
- u32 xxoverflow_discard;
- u32 brb_truncate_discard;
- u32 mac_discard;
+ __le32 mac_filter_discard;
+ __le32 xxoverflow_discard;
+ __le32 brb_truncate_discard;
+ __le32 mac_discard;
};
@@ -2743,17 +2748,17 @@ struct tstorm_per_client_stats {
struct regpair rcv_broadcast_bytes;
struct regpair rcv_multicast_bytes;
struct regpair rcv_error_bytes;
- u32 checksum_discard;
- u32 packets_too_big_discard;
- u32 total_rcv_pkts;
- u32 rcv_unicast_pkts;
- u32 rcv_broadcast_pkts;
- u32 rcv_multicast_pkts;
- u32 no_buff_discard;
- u32 ttl0_discard;
- u16 stats_counter;
- u16 reserved0;
- u32 reserved1;
+ __le32 checksum_discard;
+ __le32 packets_too_big_discard;
+ __le32 total_rcv_pkts;
+ __le32 rcv_unicast_pkts;
+ __le32 rcv_broadcast_pkts;
+ __le32 rcv_multicast_pkts;
+ __le32 no_buff_discard;
+ __le32 ttl0_discard;
+ __le16 stats_counter;
+ __le16 reserved0;
+ __le32 reserved1;
};
/*
@@ -2765,11 +2770,33 @@ struct tstorm_common_stats {
};
/*
+ * Protocol-common statistics collected by the Ustorm (per client)
+ */
+struct ustorm_per_client_stats {
+ struct regpair ucast_no_buff_bytes;
+ struct regpair mcast_no_buff_bytes;
+ struct regpair bcast_no_buff_bytes;
+ __le32 ucast_no_buff_pkts;
+ __le32 mcast_no_buff_pkts;
+ __le32 bcast_no_buff_pkts;
+ __le16 stats_counter;
+ __le16 reserved0;
+};
+
+/*
+ * Protocol-common statistics collected by the Ustorm
+ */
+struct ustorm_common_stats {
+ struct ustorm_per_client_stats client_statistics[MAX_U_STAT_COUNTER_ID];
+};
+
+/*
* Eth statistics query structure for the eth_stats_query ramrod
*/
struct eth_stats_query {
struct xstorm_common_stats xstorm_common;
struct tstorm_common_stats tstorm_common;
+ struct ustorm_common_stats ustorm_common;
};
@@ -2777,6 +2804,7 @@ struct eth_stats_query {
* per-vnic fairness variables
*/
struct fairness_vars_per_vn {
+ u32 cos_credit_delta[MAX_COS_NUMBER];
u32 protocol_credit_delta[NUM_OF_PROTOCOLS];
u32 vn_credit_delta;
u32 __reserved0;
@@ -2788,13 +2816,15 @@ struct fairness_vars_per_vn {
*/
struct fw_version {
#if defined(__BIG_ENDIAN)
- u16 patch;
- u8 primary;
- u8 client;
+ u8 engineering;
+ u8 revision;
+ u8 minor;
+ u8 major;
#elif defined(__LITTLE_ENDIAN)
- u8 client;
- u8 primary;
- u16 patch;
+ u8 major;
+ u8 minor;
+ u8 revision;
+ u8 engineering;
#endif
u32 flags;
#define FW_VERSION_OPTIMIZED (0x1<<0)
@@ -2812,9 +2842,10 @@ struct fw_version {
* FW version stored in first line of pram
*/
struct pram_fw_version {
- u8 client;
- u8 primary;
- u16 patch;
+ u8 major;
+ u8 minor;
+ u8 revision;
+ u8 engineering;
u8 flags;
#define PRAM_FW_VERSION_OPTIMIZED (0x1<<0)
#define PRAM_FW_VERSION_OPTIMIZED_SHIFT 0
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index a6c0b3abba2..39ba2936c0c 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -1,6 +1,6 @@
/* bnx2x_init.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * 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
@@ -22,12 +22,15 @@
#define INIT_ASIC 0x4
#define INIT_HARDWARE 0x7
-#define STORM_INTMEM_SIZE_E1 (0x5800 / 4)
-#define STORM_INTMEM_SIZE_E1H (0x10000 / 4)
-#define TSTORM_INTMEM_ADDR 0x1a0000
-#define CSTORM_INTMEM_ADDR 0x220000
-#define XSTORM_INTMEM_ADDR 0x2a0000
-#define USTORM_INTMEM_ADDR 0x320000
+#define TSTORM_INTMEM_ADDR TSEM_REG_FAST_MEMORY
+#define CSTORM_INTMEM_ADDR CSEM_REG_FAST_MEMORY
+#define XSTORM_INTMEM_ADDR XSEM_REG_FAST_MEMORY
+#define USTORM_INTMEM_ADDR USEM_REG_FAST_MEMORY
+/* RAM0 size in bytes */
+#define STORM_INTMEM_SIZE_E1 0x5800
+#define STORM_INTMEM_SIZE_E1H 0x10000
+#define STORM_INTMEM_SIZE(bp) ((CHIP_IS_E1H(bp) ? STORM_INTMEM_SIZE_E1H : \
+ STORM_INTMEM_SIZE_E1) / 4)
/* Init operation types and structures */
@@ -150,7 +153,6 @@ static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
{
-#ifdef USE_DMAE
int offset = 0;
if (bp->dmae_ready) {
@@ -164,28 +166,28 @@ static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
addr + offset, len);
} else
bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
-#else
- bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
-#endif
}
static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
{
- if ((len * 4) > FW_BUF_SIZE) {
- BNX2X_ERR("LARGE DMAE OPERATION ! addr 0x%x len 0x%x\n",
- addr, len*4);
- return;
- }
- memset(bp->gunzip_buf, fill, len * 4);
+ 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);
- bnx2x_write_big_buf(bp, addr, 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;
+ u32 buf_len32 = FW_BUF_SIZE / 4;
+ u32 len = len64 * 2;
u64 data64 = 0;
int i;
@@ -274,6 +276,9 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
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;
@@ -426,57 +431,57 @@ struct arb_line {
/* derived configuration for each read queue for each max request size */
static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
- {{4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4} },
- {{4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {16 , 3 , 11}, {16 , 3 , 11} },
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81}, {64 , 64 , 120} }
+/* 1 */ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
+ { {4, 8, 4}, {4, 8, 4}, {4, 8, 4}, {4, 8, 4} },
+ { {4, 3, 3}, {4, 3, 3}, {4, 3, 3}, {4, 3, 3} },
+ { {8, 3, 6}, {16, 3, 11}, {16, 3, 11}, {16, 3, 11} },
+ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
+/* 10 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+/* 20 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
};
/* derived configuration for each write queue for each max request size */
static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
- {{4 , 6 , 3}, {4 , 6 , 3}, {4 , 6 , 3} },
- {{4 , 2 , 3}, {4 , 2 , 3}, {4 , 2 , 3} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 9 , 6}, {16 , 9 , 11}, {32 , 9 , 21} },
- {{8 , 47 , 19}, {16 , 47 , 19}, {32 , 47 , 21} },
- {{8 , 9 , 6}, {16 , 9 , 11}, {16 , 9 , 11} },
- {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} }
+/* 1 */ { {4, 6, 3}, {4, 6, 3}, {4, 6, 3} },
+ { {4, 2, 3}, {4, 2, 3}, {4, 2, 3} },
+ { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
+ { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
+ { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
+ { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
+ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
+ { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
+ { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
+/* 10 */{ {8, 9, 6}, {16, 9, 11}, {32, 9, 21} },
+ { {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
+ { {8, 9, 6}, {16, 9, 11}, {16, 9, 11} },
+ { {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
};
/* register addresses for read queues */
static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
- {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
+/* 1 */ {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
PXP2_REG_RQ_BW_RD_UBOUND0},
{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
@@ -494,7 +499,7 @@ static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
PXP2_REG_PSWRQ_BW_UB7},
{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
PXP2_REG_PSWRQ_BW_UB8},
- {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
+/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
PXP2_REG_PSWRQ_BW_UB9},
{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
PXP2_REG_PSWRQ_BW_UB10},
@@ -514,7 +519,7 @@ static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
PXP2_REG_RQ_BW_RD_UBOUND17},
{PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
PXP2_REG_RQ_BW_RD_UBOUND18},
- {PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
+/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
PXP2_REG_RQ_BW_RD_UBOUND19},
{PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
PXP2_REG_RQ_BW_RD_UBOUND20},
@@ -536,7 +541,7 @@ static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
/* register addresses for write queues */
static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
- {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
+/* 1 */ {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
PXP2_REG_PSWRQ_BW_UB2},
@@ -554,7 +559,7 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
PXP2_REG_PSWRQ_BW_UB10},
{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
PXP2_REG_PSWRQ_BW_UB11},
- {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
+/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
PXP2_REG_PSWRQ_BW_UB28},
{PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
PXP2_REG_RQ_BW_WR_UBOUND29},
@@ -572,7 +577,12 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
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);
- r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ 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",
@@ -647,17 +657,18 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, PXP2_REG_WR_HC_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_USDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_CSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_TSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_XSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_QM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_TM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_SRC_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_DBG_MPS, w_order+1);
+ 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, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
}
}
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
index 9755bf6b08d..1f22c9ab66d 100644
--- a/drivers/net/bnx2x_init_values.h
+++ b/drivers/net/bnx2x_init_values.h
@@ -1,7 +1,23 @@
#ifndef __BNX2X_INIT_VALUES_H__
#define __BNX2X_INIT_VALUES_H__
-/* This array contains the list of operations needed to initialize the chip.
+/* 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,
@@ -47,12 +63,16 @@ static const struct raw_op init_ops[] = {
{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000},
{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000},
{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000},
- {OP_ZR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
+ {OP_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, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
+ {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},
@@ -71,15 +91,16 @@ static const struct raw_op init_ops[] = {
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
+ {OP_WR_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 47
-#define SRCH_COMMON_START 47
+#define PRS_COMMON_END 52
+#define SRCH_COMMON_START 52
{OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1},
-#define SRCH_COMMON_END 48
-#define TSDM_COMMON_START 48
+#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},
@@ -92,10 +113,15 @@ static const struct raw_op init_ops[] = {
{OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff},
{OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff},
{OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_ZR, TSDM_REG_AGG_INT_EVENT_0, 0x2},
+ {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, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
+ {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},
@@ -118,8 +144,8 @@ static const struct raw_op init_ops[] = {
{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 86
-#define TCM_COMMON_START 86
+#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},
@@ -129,10 +155,16 @@ static const struct raw_op init_ops[] = {
{OP_WR, TCM_REG_ERR_EVNT_ID, 0x33},
{OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30},
{OP_WR, TCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, TCM_REG_PRS_WEIGHT, 0x4},
- {OP_WR, TCM_REG_PBF_WEIGHT, 0x5},
+ {OP_WR, TCM_REG_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, 0x4},
+ {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},
@@ -149,7 +181,9 @@ static const struct raw_op init_ops[] = {
{OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7},
{OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8},
{OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8},
- {OP_ZR, TCM_REG_N_SM_CTX_LD_4, 0x4},
+ {OP_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},
@@ -175,75 +209,75 @@ static const struct raw_op init_ops[] = {
{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 141
-#define TCM_FUNC0_START 141
+#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 145
-#define TCM_FUNC1_START 145
+#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 149
-#define TCM_FUNC2_START 149
+#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 153
-#define TCM_FUNC3_START 153
+#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 157
-#define TCM_FUNC4_START 157
+#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 161
-#define TCM_FUNC5_START 161
+#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 165
-#define TCM_FUNC6_START 165
+#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 169
-#define TCM_FUNC7_START 169
+#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 173
-#define BRB1_COMMON_START 173
+#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 178
-#define BRB1_PORT0_START 178
+#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 182
-#define BRB1_PORT1_START 182
+#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 186
-#define TSEM_COMMON_START 186
+#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},
@@ -303,143 +337,166 @@ static const struct raw_op init_ops[] = {
{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 + 0x800, 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 + 0x3b28, 0x6},
+ {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 + 0x5000, 0x2},
+ {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 + 0x5008, 0x4},
+ {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_ZP_E1, TSEM_REG_INT_TABLE, 0x940000},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 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, 0x30b10000},
+ {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33250c94},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33c50c2d},
+ {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xe4d195e},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xbc6191f},
+ {OP_WR_64_E1, TSEM_REG_PRAM + 0x11e00, 0x5c400232},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4},
- {OP_WR_64_E1, TSEM_REG_PRAM + 0x117f0, 0x5d020232},
{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 + 0x6140, 0x200224},
- {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x960000},
- {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x360, 0x140244},
- {OP_ZP_E1H, TSEM_REG_PRAM, 0x30cc0000},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x33df0c33},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0xdce192b},
- {OP_WR_64_E1H, TSEM_REG_PRAM + 0x11c70, 0x5c720246},
-#define TSEM_COMMON_END 276
-#define TSEM_PORT0_START 276
+ {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, 0xfc},
+ {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, 0xfa},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0xe},
+ {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, 0xbe},
+ {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, 0x20234},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20239},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2},
-#define TSEM_PORT0_END 294
-#define TSEM_PORT1_START 294
+#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 + 0x43f0, 0xfc},
+ {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 + 0x3738, 0xfa},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0xe},
+ {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 + 0xcb8, 0xbe},
+ {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, 0x20236},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20240},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2},
-#define TSEM_PORT1_END 312
-#define TSEM_FUNC0_START 312
+#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, 0xe},
+ {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 318
-#define TSEM_FUNC1_START 318
+#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, 0xe},
+ {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 324
-#define TSEM_FUNC2_START 324
+#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, 0xe},
+ {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, 0x20248},
-#define TSEM_FUNC2_END 330
-#define TSEM_FUNC3_START 330
+ {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, 0xe},
+ {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, 0x2024a},
-#define TSEM_FUNC3_END 336
-#define TSEM_FUNC4_START 336
+ {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, 0xe},
+ {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, 0x2024c},
-#define TSEM_FUNC4_END 342
-#define TSEM_FUNC5_START 342
+ {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, 0xe},
+ {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, 0x2024e},
-#define TSEM_FUNC5_END 348
-#define TSEM_FUNC6_START 348
+ {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, 0xe},
+ {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, 0x20250},
-#define TSEM_FUNC6_END 354
-#define TSEM_FUNC7_START 354
+ {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, 0xe},
+ {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, 0x20252},
-#define TSEM_FUNC7_END 360
-#define MISC_COMMON_START 360
+ {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},
@@ -447,39 +504,39 @@ static const struct raw_op init_ops[] = {
{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 367
-#define MISC_FUNC0_START 367
+#define MISC_COMMON_END 408
+#define MISC_FUNC0_START 408
{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC0_END 368
-#define MISC_FUNC1_START 368
+#define MISC_FUNC0_END 409
+#define MISC_FUNC1_START 409
{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC1_END 369
-#define MISC_FUNC2_START 369
+#define MISC_FUNC1_END 410
+#define MISC_FUNC2_START 410
{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC2_END 370
-#define MISC_FUNC3_START 370
+#define MISC_FUNC2_END 411
+#define MISC_FUNC3_START 411
{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC3_END 371
-#define MISC_FUNC4_START 371
+#define MISC_FUNC3_END 412
+#define MISC_FUNC4_START 412
{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC4_END 372
-#define MISC_FUNC5_START 372
+#define MISC_FUNC4_END 413
+#define MISC_FUNC5_START 413
{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC5_END 373
-#define MISC_FUNC6_START 373
+#define MISC_FUNC5_END 414
+#define MISC_FUNC6_START 414
{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC6_END 374
-#define MISC_FUNC7_START 374
+#define MISC_FUNC6_END 415
+#define MISC_FUNC7_START 415
{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC7_END 375
-#define NIG_COMMON_START 375
+#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 380
-#define NIG_PORT0_START 380
+#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},
@@ -492,8 +549,8 @@ static const struct raw_op init_ops[] = {
{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 392
-#define NIG_PORT1_START 392
+#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},
@@ -506,11 +563,11 @@ static const struct raw_op init_ops[] = {
{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 404
-#define UPB_COMMON_START 404
+#define NIG_PORT1_END 445
+#define UPB_COMMON_START 445
{OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
-#define UPB_COMMON_END 405
-#define CSDM_COMMON_START 405
+#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},
@@ -550,8 +607,8 @@ static const struct raw_op init_ops[] = {
{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 444
-#define USDM_COMMON_START 444
+#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},
@@ -568,9 +625,14 @@ static const struct raw_op init_ops[] = {
{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, USDM_REG_AGG_INT_EVENT_4, 0x5c},
+ {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, USDM_REG_AGG_INT_MODE_1, 0x1f},
+ {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},
@@ -594,18 +656,21 @@ static const struct raw_op init_ops[] = {
{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 486
-#define CCM_COMMON_START 486
+#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, 0x4},
- {OP_WR, CCM_REG_USEM_WEIGHT, 0x4},
+ {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_CQM_P_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},
@@ -620,8 +685,8 @@ static const struct raw_op init_ops[] = {
{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, 0x240238},
- {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x240254},
+ {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},
@@ -657,8 +722,8 @@ static const struct raw_op init_ops[] = {
{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 547
-#define CCM_FUNC0_START 547
+#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},
@@ -666,8 +731,8 @@ static const struct raw_op init_ops[] = {
{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 554
-#define CCM_FUNC1_START 554
+#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},
@@ -675,8 +740,8 @@ static const struct raw_op init_ops[] = {
{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 561
-#define CCM_FUNC2_START 561
+#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},
@@ -684,8 +749,8 @@ static const struct raw_op init_ops[] = {
{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 568
-#define CCM_FUNC3_START 568
+#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},
@@ -693,8 +758,8 @@ static const struct raw_op init_ops[] = {
{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 575
-#define CCM_FUNC4_START 575
+#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},
@@ -702,8 +767,8 @@ static const struct raw_op init_ops[] = {
{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 582
-#define CCM_FUNC5_START 582
+#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},
@@ -711,8 +776,8 @@ static const struct raw_op init_ops[] = {
{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 589
-#define CCM_FUNC6_START 589
+#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},
@@ -720,8 +785,8 @@ static const struct raw_op init_ops[] = {
{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 596
-#define CCM_FUNC7_START 596
+#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},
@@ -729,8 +794,8 @@ static const struct raw_op init_ops[] = {
{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 603
-#define UCM_COMMON_START 603
+#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},
@@ -739,10 +804,16 @@ static const struct raw_op init_ops[] = {
{OP_WR, UCM_REG_ERR_EVNT_ID, 0x33},
{OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30},
{OP_WR, UCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, UCM_REG_TSEM_WEIGHT, 0x3},
+ {OP_WR, UCM_REG_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_UQM_P_WEIGHT, 0x6},
+ {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},
@@ -756,14 +827,14 @@ static const struct raw_op init_ops[] = {
{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, 0x1b025c},
- {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b0278},
+ {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, 0xd},
+ {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},
@@ -787,56 +858,56 @@ static const struct raw_op init_ops[] = {
{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 659
-#define UCM_FUNC0_START 659
+#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 663
-#define UCM_FUNC1_START 663
+#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 667
-#define UCM_FUNC2_START 667
+#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 671
-#define UCM_FUNC3_START 671
+#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 675
-#define UCM_FUNC4_START 675
+#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 679
-#define UCM_FUNC5_START 679
+#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 683
-#define UCM_FUNC6_START 683
+#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 687
-#define UCM_FUNC7_START 687
+#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 691
-#define USEM_COMMON_START 691
+#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},
@@ -887,69 +958,72 @@ static const struct raw_op init_ops[] = {
{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, 0x102},
+ {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 + 0x57e8, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8020, 0xc8},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d0, 0x5},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x2},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d0 + 0x14, 0x10277},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3760, 0x4},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1e20, 0x42},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3738, 0x9},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b68, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3738 + 0x24, 0x10293},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x20278},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x42},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
+ {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_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x2027a},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x20294},
+ {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, 0x20296},
+ {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, 0x20298},
+ {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, 0x10027c},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x10029a},
+ {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, 0x10028c},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002aa},
- {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc20000},
- {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xc40000},
- {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x13029c},
- {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x368, 0x1302ba},
- {OP_ZP_E1, USEM_REG_PRAM, 0x311c0000},
- {OP_ZP_E1H, USEM_REG_PRAM, 0x31070000},
- {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x33450c47},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x330e0c42},
- {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x38561919},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x389b1906},
- {OP_WR_64_E1, USEM_REG_PRAM + 0x17fe0, 0x5004029e},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x132272d},
- {OP_WR_64_E1H, USEM_REG_PRAM + 0x18250, 0x4fb602bc},
-#define USEM_COMMON_END 787
-#define USEM_PORT0_START 787
+ {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, 0xa},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x28},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1950, 0x2e},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9640, 0x34},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d00, 0x4},
+ {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 + 0x1d20, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3288, 0x96},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5440, 0x72},
+ {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_E1, USEM_REG_FAST_MEMORY + 0x4b78, 0x52},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e08, 0xc},
{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},
@@ -966,23 +1040,26 @@ static const struct raw_op init_ops[] = {
{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 818
-#define USEM_PORT1_START 818
+#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 + 0x1928, 0xa},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x95a0, 0x28},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a08, 0x2e},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9710, 0x34},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d10, 0x4},
+ {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 + 0x1da0, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x34e0, 0x96},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5608, 0x72},
+ {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_E1, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e38, 0xc},
{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},
@@ -999,40 +1076,48 @@ static const struct raw_op init_ops[] = {
{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 849
-#define USEM_FUNC0_START 849
+#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 + 0x4010, 0x2},
-#define USEM_FUNC0_END 851
-#define USEM_FUNC1_START 851
+ {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 + 0x4020, 0x2},
-#define USEM_FUNC1_END 853
-#define USEM_FUNC2_START 853
+ {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 + 0x4030, 0x2},
-#define USEM_FUNC2_END 855
-#define USEM_FUNC3_START 855
+ {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 + 0x4040, 0x2},
-#define USEM_FUNC3_END 857
-#define USEM_FUNC4_START 857
+ {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 + 0x4050, 0x2},
-#define USEM_FUNC4_END 859
-#define USEM_FUNC5_START 859
+ {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 + 0x4060, 0x2},
-#define USEM_FUNC5_END 861
-#define USEM_FUNC6_START 861
+ {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 + 0x4070, 0x2},
-#define USEM_FUNC6_END 863
-#define USEM_FUNC7_START 863
+ {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 + 0x4080, 0x2},
-#define USEM_FUNC7_END 865
-#define CSEM_COMMON_START 865
+ {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},
@@ -1091,29 +1176,30 @@ static const struct raw_op init_ops[] = {
{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, 0x802a0},
+ {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 + 0x6280, 0x240},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b88, 0x2002be},
+ {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, 0x1002a8},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002de},
+ {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, 0x1002b8},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ee},
- {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x6e0000},
- {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x6f0000},
- {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002c8},
- {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x1002fe},
- {OP_ZP_E1, CSEM_REG_PRAM, 0x32580000},
- {OP_ZP_E1H, CSEM_REG_PRAM, 0x31fa0000},
- {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x18270c96},
- {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x19040c7f},
- {OP_WR_64_E1, CSEM_REG_PRAM + 0xb210, 0x682402ca},
- {OP_WR_64_E1H, CSEM_REG_PRAM + 0xb430, 0x67e00300},
-#define CSEM_COMMON_END 944
-#define CSEM_PORT0_START 944
+ {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},
@@ -1123,11 +1209,10 @@ static const struct raw_op init_ops[] = {
{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_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
-#define CSEM_PORT0_END 956
-#define CSEM_PORT1_START 956
+#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},
@@ -1137,46 +1222,53 @@ static const struct raw_op init_ops[] = {
{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_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
-#define CSEM_PORT1_END 968
-#define CSEM_FUNC0_START 968
+#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},
-#define CSEM_FUNC0_END 970
-#define CSEM_FUNC1_START 970
+ {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},
-#define CSEM_FUNC1_END 972
-#define CSEM_FUNC2_START 972
+ {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},
-#define CSEM_FUNC2_END 974
-#define CSEM_FUNC3_START 974
+ {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},
-#define CSEM_FUNC3_END 976
-#define CSEM_FUNC4_START 976
+ {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},
-#define CSEM_FUNC4_END 978
-#define CSEM_FUNC5_START 978
+ {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},
-#define CSEM_FUNC5_END 980
-#define CSEM_FUNC6_START 980
+ {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},
-#define CSEM_FUNC6_END 982
-#define CSEM_FUNC7_START 982
+ {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},
-#define CSEM_FUNC7_END 984
-#define XPB_COMMON_START 984
+ {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 985
-#define DQ_COMMON_START 985
+#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},
@@ -1195,8 +1287,8 @@ static const struct raw_op init_ops[] = {
{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 1003
-#define TIMERS_COMMON_START 1003
+#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},
@@ -1219,14 +1311,18 @@ static const struct raw_op init_ops[] = {
{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 1025
-#define TIMERS_PORT0_START 1025
+#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 1026
-#define TIMERS_PORT1_START 1026
+#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 1027
-#define XSDM_COMMON_START 1027
+#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},
@@ -1249,7 +1345,9 @@ static const struct raw_op init_ops[] = {
{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_ZR, XSDM_REG_AGG_INT_EVENT_12, 0x54},
+ {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},
@@ -1274,8 +1372,8 @@ static const struct raw_op init_ops[] = {
{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 1074
-#define QM_COMMON_START 1074
+#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},
@@ -1576,8 +1674,8 @@ static const struct raw_op init_ops[] = {
{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 1374
-#define PBF_COMMON_START 1374
+#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},
@@ -1585,20 +1683,20 @@ static const struct raw_op init_ops[] = {
{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 1381
-#define PBF_PORT0_START 1381
+#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 1385
-#define PBF_PORT1_START 1385
+#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 1389
-#define XCM_COMMON_START 1389
+#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},
@@ -1607,15 +1705,18 @@ static const struct raw_op init_ops[] = {
{OP_WR, XCM_REG_ERR_EVNT_ID, 0x33},
{OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30},
{OP_WR, XCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, XCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_TSEM_WEIGHT, 0x5},
- {OP_WR, XCM_REG_CSEM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_USEM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_PBF_WEIGHT, 0x7},
- {OP_WR, XCM_REG_NIG1_WEIGHT, 0x1},
+ {OP_WR, XCM_REG_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, 0x5},
- {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x3},
+ {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},
@@ -1633,14 +1734,14 @@ static const struct raw_op init_ops[] = {
{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, 0x1f02cc},
- {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0302},
+ {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, 0xc},
+ {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},
@@ -1663,8 +1764,8 @@ static const struct raw_op init_ops[] = {
{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 1453
-#define XCM_PORT0_START 1453
+#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},
@@ -1673,8 +1774,8 @@ static const struct raw_op init_ops[] = {
{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 1461
-#define XCM_PORT1_START 1461
+#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},
@@ -1683,8 +1784,8 @@ static const struct raw_op init_ops[] = {
{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 1469
-#define XCM_FUNC0_START 1469
+#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},
@@ -1694,8 +1795,8 @@ static const struct raw_op init_ops[] = {
{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 1478
-#define XCM_FUNC1_START 1478
+#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},
@@ -1705,8 +1806,8 @@ static const struct raw_op init_ops[] = {
{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 1487
-#define XCM_FUNC2_START 1487
+#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},
@@ -1716,8 +1817,8 @@ static const struct raw_op init_ops[] = {
{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 1496
-#define XCM_FUNC3_START 1496
+#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},
@@ -1727,8 +1828,8 @@ static const struct raw_op init_ops[] = {
{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 1505
-#define XCM_FUNC4_START 1505
+#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},
@@ -1738,8 +1839,8 @@ static const struct raw_op init_ops[] = {
{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 1514
-#define XCM_FUNC5_START 1514
+#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},
@@ -1749,8 +1850,8 @@ static const struct raw_op init_ops[] = {
{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 1523
-#define XCM_FUNC6_START 1523
+#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},
@@ -1760,8 +1861,8 @@ static const struct raw_op init_ops[] = {
{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 1532
-#define XCM_FUNC7_START 1532
+#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},
@@ -1771,8 +1872,8 @@ static const struct raw_op init_ops[] = {
{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 1541
-#define XSEM_COMMON_START 1541
+#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},
@@ -1827,10 +1928,12 @@ static const struct raw_op init_ops[] = {
{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 + 0x3d00, 0x4},
+ {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_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x4},
+ {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},
@@ -1839,68 +1942,73 @@ static const struct raw_op init_ops[] = {
{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, 0x202eb},
+ {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, 0x402ed},
+ {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 + 0x23d0, 0x20321},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x4034c},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x40323},
+ {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 + 0x2ac8, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202f1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ab8, 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 + 0x1f50, 0x202f3},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100327},
+ {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 + 0x83b0, 0x20337},
+ {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, 0x1002f5},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100339},
+ {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, 0x80305},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80349},
+ {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, 0x8030d},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80351},
- {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xa90000},
- {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xac0000},
- {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130315},
- {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x368, 0x130359},
- {OP_ZP_E1, XSEM_REG_PRAM, 0x344e0000},
- {OP_ZP_E1H, XSEM_REG_PRAM, 0x34620000},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38840d14},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x38240d19},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3e711b35},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3e971b22},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x1dd02ad2},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x21542ac8},
- {OP_WR_64_E1, XSEM_REG_PRAM + 0x1c0d0, 0x47e60317},
- {OP_WR_64_E1H, XSEM_REG_PRAM + 0x1c8d0, 0x46e6035b},
-#define XSEM_COMMON_END 1651
-#define XSEM_PORT0_START 1651
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x10},
+ {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 + 0x3c20, 0x1c},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x10},
+ {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 + 0x2528, 0x1c},
+ {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 + 0x2608, 0x1c},
+ {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 + 0x26e8, 0x1c},
+ {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 + 0x27c8, 0x1c},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d10, 0x100319},
+ {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_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
+ {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},
@@ -1910,31 +2018,33 @@ static const struct raw_op init_ops[] = {
{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, 0x2035d},
+ {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, 0x20329},
+ {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 1683
-#define XSEM_PORT1_START 1683
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3be0, 0x10},
+#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 + 0x3c90, 0x1c},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24e8, 0x10},
+ {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 + 0x2598, 0x1c},
+ {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 + 0x2678, 0x1c},
+ {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 + 0x2758, 0x1c},
+ {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 + 0x2838, 0x1c},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d50, 0x10032b},
+ {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_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
+ {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},
@@ -1944,68 +2054,68 @@ static const struct raw_op init_ops[] = {
{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, 0x2035f},
+ {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, 0x2033b},
+ {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 1715
-#define XSEM_FUNC0_START 1715
+#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 + 0x28b8, 0x100361},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f0, 0x100390},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-#define XSEM_FUNC0_END 1718
-#define XSEM_FUNC1_START 1718
+#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 + 0x28f8, 0x100371},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a30, 0x1003a0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-#define XSEM_FUNC1_END 1721
-#define XSEM_FUNC2_START 1721
+#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 + 0x2938, 0x100381},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a70, 0x1003b0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
-#define XSEM_FUNC2_END 1724
-#define XSEM_FUNC3_START 1724
+#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 + 0x2978, 0x100391},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2ab0, 0x1003c0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
-#define XSEM_FUNC3_END 1727
-#define XSEM_FUNC4_START 1727
+#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 + 0x29b8, 0x1003a1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2af0, 0x1003d0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
-#define XSEM_FUNC4_END 1730
-#define XSEM_FUNC5_START 1730
+#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 + 0x29f8, 0x1003b1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b30, 0x1003e0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
-#define XSEM_FUNC5_END 1733
-#define XSEM_FUNC6_START 1733
+#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 + 0x2a38, 0x1003c1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b70, 0x1003f0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
-#define XSEM_FUNC6_END 1736
-#define XSEM_FUNC7_START 1736
+#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 + 0x2a78, 0x1003d1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2bb0, 0x100400},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
-#define XSEM_FUNC7_END 1739
-#define CDU_COMMON_START 1739
+#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, 0x200033d},
- {OP_WB_E1H, CDU_REG_L1TT, 0x20003e1},
- {OP_WB_E1, CDU_REG_MATT, 0x20053d},
- {OP_WB_E1H, CDU_REG_MATT, 0x2805e1},
+ {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, 0x6055d},
+ {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6056d},
{OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
-#define CDU_COMMON_END 1750
-#define DMAE_COMMON_START 1750
+#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},
@@ -2013,24 +2123,27 @@ static const struct raw_op init_ops[] = {
{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 1757
-#define PXP_COMMON_START 1757
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50563},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50609},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50568},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5060e},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5056d},
-#define PXP_COMMON_END 1762
-#define CFC_COMMON_START 1762
+#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},
-#define CFC_COMMON_END 1766
-#define HC_COMMON_START 1766
+ {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 1767
-#define HC_PORT0_START 1767
+#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},
@@ -2049,8 +2162,8 @@ static const struct raw_op init_ops[] = {
{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 1785
-#define HC_PORT1_START 1785
+#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},
@@ -2069,8 +2182,8 @@ static const struct raw_op init_ops[] = {
{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 1803
-#define HC_FUNC0_START 1803
+#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},
@@ -2086,8 +2199,8 @@ static const struct raw_op init_ops[] = {
{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 1818
-#define HC_FUNC1_START 1818
+#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},
@@ -2103,8 +2216,8 @@ static const struct raw_op init_ops[] = {
{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 1833
-#define HC_FUNC2_START 1833
+#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},
@@ -2120,8 +2233,8 @@ static const struct raw_op init_ops[] = {
{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 1848
-#define HC_FUNC3_START 1848
+#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},
@@ -2137,8 +2250,8 @@ static const struct raw_op init_ops[] = {
{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 1863
-#define HC_FUNC4_START 1863
+#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},
@@ -2154,8 +2267,8 @@ static const struct raw_op init_ops[] = {
{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 1878
-#define HC_FUNC5_START 1878
+#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},
@@ -2171,8 +2284,8 @@ static const struct raw_op init_ops[] = {
{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 1893
-#define HC_FUNC6_START 1893
+#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},
@@ -2188,8 +2301,8 @@ static const struct raw_op init_ops[] = {
{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 1908
-#define HC_FUNC7_START 1908
+#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},
@@ -2205,10 +2318,10 @@ static const struct raw_op init_ops[] = {
{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 1923
-#define PXP2_COMMON_START 1923
- {OP_WR_E1, PXP2_REG_PGL_CONTROL0, 0xe38340},
+#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},
@@ -2220,7 +2333,7 @@ static const struct raw_op init_ops[] = {
{OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
+ {OP_WR_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},
@@ -2247,6 +2360,7 @@ static const struct raw_op init_ops[] = {
{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},
@@ -2323,9 +2437,8 @@ static const struct raw_op init_ops[] = {
{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},
- {OP_WR_E1H, PXP2_REG_PGL_CONTROL0, 0xe38340},
-#define PXP2_COMMON_END 2040
-#define MISC_AEU_COMMON_START 2040
+#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},
@@ -2345,8 +2458,8 @@ static const struct raw_op init_ops[] = {
{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 2059
-#define MISC_AEU_PORT0_START 2059
+#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},
@@ -2379,8 +2492,8 @@ static const struct raw_op init_ops[] = {
{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 2091
-#define MISC_AEU_PORT1_START 2091
+#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},
@@ -2413,7 +2526,7 @@ static const struct raw_op init_ops[] = {
{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 2123
+#define MISC_AEU_PORT1_END 2220
};
@@ -2512,72 +2625,64 @@ static const u32 init_data_e1[] = {
0x00000200, 0x00000001, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, 0x00000000, 0x00003500,
- 0x00000003, 0x00bebc20, 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, 0x00100000, 0x00000000, 0x00000000, 0xffffffff,
+ 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, 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, 0x00003500, 0x00001000, 0x00002080, 0x00003100, 0x00004180,
- 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, 0x0000a480,
- 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, 0x00010780,
- 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, 0x00016a80,
- 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, 0x0001cd80,
- 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, 0x00000604,
- 0xccccccc1, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc, 0x00000000,
+ 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, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00003500, 0x000e01b7, 0x011600d6, 0x0000ffff, 0x00000000, 0x0000ffff,
0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x00100000,
0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x00100000, 0x00000000, 0x007201bb, 0x012300f3, 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,
+ 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,
- 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c,
+ 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,
@@ -2585,41 +2690,41 @@ static const u32 init_data_e1[] = {
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, 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, 0xffffff8a,
- 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
+ 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,
- 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 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, 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,
+ 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,
@@ -2641,16 +2746,26 @@ static const u32 init_data_e1[] = {
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
+ 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[] = {
@@ -2751,11973 +2866,13457 @@ static const u32 init_data_e1h[] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 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, 0x00000000, 0x00100000, 0x00000000, 0x00000000, 0xffffffff,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 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, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 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, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 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, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0x00001000, 0x00002080, 0x00003100, 0x00004180,
- 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, 0x0000a480,
- 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, 0x00010780,
- 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, 0x00016a80,
- 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, 0x0001cd80,
- 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, 0x00000604,
- 0xccccccc5, 0xffffffff, 0xffffffff, 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, 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, 0x00000000,
- 0x00007ff8, 0x00000000, 0x00003500, 0x00100000, 0x00000000, 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, 0x31afffff, 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, 0x058fffff, 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, 0x000d0000, 0x000000d0, 0x000280d0, 0x000b80f8, 0x000201b0,
- 0x000101d0, 0x000c81e0, 0x000002a8, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0x00002000
+ 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, 0x19d9b38a, 0x22717618,
- 0xa70143f8, 0xa4303332, 0x10267103, 0x97e204af, 0xaf0c0c8c, 0x2fd78918,
- 0xcf608621, 0x38606610, 0x4206c402, 0x22450c0c, 0xa07af108, 0xfe407b9a,
- 0xb698a842, 0x76c30328, 0x3bf781d1, 0x34957035, 0x24a458a6, 0x458d5d82,
- 0xa0d7191e, 0x4494efc9, 0xd012d7e5, 0x4538d03f, 0x513f9509, 0x547f4201,
- 0x342fa684, 0xf95049f9, 0xa57f5039, 0x77376129, 0x001e542e, 0x61aa8a92,
- 0x00000360
+ 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,
- 0x204e4cce, 0x30840909, 0x43511879, 0x7c061e1c, 0x201276f4, 0x06bf2ae5,
- 0x0ea2a17c, 0x2de42108, 0xebf8fea5, 0x092132fd, 0xf636c544, 0xda2f45a2,
- 0x05a855e1, 0xa180d03b, 0x4a00ee05, 0x7836daa1, 0xf5ab15bd, 0x62a2968e,
- 0x96ad2248, 0xbfcb17fe, 0x24fbdad6, 0x00664e73, 0xbbf7bdcb, 0x9fa7efd7,
- 0xece7d9dd, 0xebdaf7b3, 0x7b5ad7b5, 0x5d8a3ded, 0x19d7ea62, 0xa0ff873b,
- 0xc631b3ec, 0x9f2c19ae, 0x23a57cc8, 0x6ad8cbd7, 0x3127d43b, 0x0f623c16,
- 0x5b18926d, 0xb59fda32, 0x71ca0d30, 0xbc20be69, 0xebe16767, 0xc654c612,
- 0x9b4aadff, 0xe8f2c994, 0xf073b9f9, 0xf30f81dc, 0x58564b19, 0x63026530,
- 0xafcc6c2b, 0x8fba830f, 0xfc9c0fb1, 0x7ff8739b, 0xf61b24c1, 0xbf874233,
- 0xaf3edfa1, 0x814f682d, 0xedcdb37e, 0x1215494e, 0xd5db1993, 0x140bd2c4,
- 0x9c9abac6, 0x49b4fe54, 0x60282f4f, 0x26534f6c, 0x7935f7d5, 0x8d348ca9,
- 0x9a07e7a5, 0xb34f547c, 0xf7e3d7f5, 0x2b7c8e23, 0xce0d1595, 0x68ae5adf,
- 0x060b7182, 0x64cc7feb, 0xf9e00541, 0xafeec2a3, 0x5f9aef80, 0x8512989f,
- 0x802c99f2, 0xf7e86536, 0x45fb2ecf, 0x8ce1b4fe, 0x387c3d65, 0x6844da7f,
- 0xe139b127, 0x87459c22, 0xe25c6b34, 0x77b19f71, 0xcdc032a4, 0x6991802d,
- 0xb9b58c99, 0x4f2e6ffa, 0x44f5cc65, 0x0b9a7fb6, 0x5d0cdde6, 0x2eec648c,
- 0xde0c1056, 0xf81ffd00, 0xe80525b8, 0x614976a1, 0x4b26cd78, 0xd012cd15,
- 0x7ccedd8b, 0xa538709b, 0xd41479a2, 0xde60eefb, 0xe383bdc7, 0x9880c5dc,
- 0x46ccd8e9, 0x32a864e5, 0xa5dd87e8, 0xe2e53686, 0x15c5fd87, 0x2fb712e3,
- 0xd517f839, 0xf6f1a6eb, 0x078d328f, 0x7f13b9df, 0xcbe07597, 0xaef7d77d,
- 0x78842332, 0xe11f9853, 0xc657753b, 0xde25c7ba, 0x7d8f163e, 0xc70aab2a,
- 0x8e1567a1, 0x66dcfc0b, 0x367b74e7, 0xb18d4a17, 0x16663835, 0x9c62b563,
- 0x03d95a29, 0x3000b258, 0xb58cb5e7, 0xdda0bd20, 0x3abf6894, 0xdf4ae00f,
- 0x852a4b33, 0x0af1fa7a, 0xf2115e69, 0x10cf41a1, 0xb1259ff5, 0x9ef81d8a,
- 0x70ca92cd, 0xe71f3b1c, 0x8b50fe86, 0xe86ee007, 0xec9eddca, 0x6194fde5,
- 0x48553fbb, 0x3858b5f3, 0x7a4fd4bd, 0xdf038c17, 0x38c0f7a7, 0xa56b3ef0,
- 0xfe69bac4, 0xe1a614de, 0x32c67e78, 0x70a6a440, 0xa8d99099, 0x7867e424,
- 0xfc8165ae, 0x3f2e3364, 0x8be635a7, 0x9f737e00, 0xd0d47cd4, 0x783579ab,
- 0x69c85a3f, 0x266aa076, 0x01b630f3, 0x530593d0, 0x7ca8dd1e, 0xb3918d10,
- 0xcda37331, 0x9663fa28, 0x997b9f99, 0x9cf286d7, 0xcf3f341b, 0xbfd7376f,
- 0x2769dccd, 0xdc3f82ae, 0x8e4e7dcc, 0xc0e38f33, 0x12cf00d4, 0x6fc0ef21,
- 0xadbf2c6a, 0x5a19626d, 0x91396241, 0x5dce1c96, 0xb7687a89, 0xf7c073e4,
- 0x907b602f, 0x6ef890ef, 0x05d7a8bd, 0x0d5d8555, 0x1e282025, 0x958afc7f,
- 0x1fba406e, 0x101b6567, 0xbf4a0dff, 0x0d7c03aa, 0xa43faa8d, 0x17bf6d0d,
- 0xd7db1118, 0x4e03be2b, 0x99bfbf18, 0xf8c3d6f9, 0x197aec4b, 0xec3c97d6,
- 0xd798bd25, 0x7e472d1e, 0xea05d31d, 0xfbf0772a, 0x2767808b, 0xecf001c2,
- 0x97f4e3e4, 0xdfedfea3, 0xb9f5b12b, 0x77ef0e38, 0x165ceec9, 0xe70c4dcc,
- 0xfc4ecc73, 0xbc0b40b4, 0x267ee582, 0x02c62729, 0x83cc3d9a, 0xcaa968f4,
- 0x54394efb, 0xe9f7c69f, 0xf9ccf583, 0x00033233, 0x6618d657, 0xb3a557a2,
- 0x7af50731, 0x1cb84575, 0x25c3e2f9, 0x12c0acaf, 0x00ae9cf0, 0x2a388fbe,
- 0xea7ec75e, 0xa21636e6, 0xe870edc8, 0x7b1afe34, 0x7237d647, 0x1fa50f11,
- 0xd06fc02b, 0x1865306d, 0xff4595f2, 0xc60fbfc3, 0x989cba8a, 0x172a17ee,
- 0xe20a3f60, 0xf59fcb8d, 0x0f4207fd, 0xf8261e81, 0x957ecbbc, 0xb63c305f,
- 0xc17e7afe, 0x09500144, 0x13f0cbc1, 0x4552a2c6, 0x663dbd1c, 0xa561e977,
- 0xff3c3138, 0x7404f3d9, 0x001a7cd2, 0x7527c8b7, 0x1cb4356e, 0xa7753df0,
- 0xe075f23d, 0x5275ba93, 0xdb7501c8, 0xefbd173e, 0x11ebcb5d, 0xe9f5cab7,
- 0x0a83a846, 0x7f74706c, 0xb3e47afb, 0x8f5b329d, 0xf5858edd, 0x09ccf418,
- 0xc49b3b01, 0x174ae7d7, 0xdbadd6af, 0x5f7e1f7f, 0x2e60e5d5, 0xf76eafe8,
- 0x87af9ba2, 0x76c3a2fa, 0x36ea4d86, 0xa123ab35, 0xd7c438be, 0x0e32bea5,
- 0x4c97705f, 0xa79f4beb, 0xa076e33b, 0x2726c9cf, 0xd0f182f3, 0xb8ceeee2,
- 0x3aadf80d, 0xbf1cbdb4, 0xf92adeab, 0x7753ed10, 0x85943a6e, 0x9721faf3,
- 0xc92d9af3, 0x0fe06bcc, 0x29d13bfe, 0xef0ebe47, 0x193cc097, 0x7588bbf4,
- 0xac3ea394, 0xad14f4db, 0x4ebe0633, 0xce34e936, 0x10fe1c80, 0xeaef81c6,
- 0x387c925f, 0x0b1b7ac5, 0xeef63ca0, 0xa0d9cd76, 0xd59afce1, 0x6bce3742,
- 0x16ed8aa5, 0x72ede685, 0x75be1179, 0xafbc396a, 0xad4ebb5e, 0x9adf918c,
- 0x70cdc32d, 0x111fc9ad, 0x717d8f38, 0x6f0bec12, 0x1abd60e1, 0x45ea01f5,
- 0xaec6a425, 0xa9496f6b, 0x2d9adf44, 0xf89af332, 0xf83dd388, 0xedd68caf,
- 0x5f375ee0, 0x06dd05b7, 0xdba0aaf4, 0x51d05d69, 0x67892fe9, 0xe91b7c7f,
- 0x2074f000, 0x255ca09e, 0xc0dcf3e0, 0xdfe8154a, 0x2e3a67e3, 0xcbe217bb,
- 0xc79b3b0e, 0xcd39ac60, 0xac0afd9b, 0x7b2a1da3, 0xef99ed10, 0xd3fd86b6,
- 0x966dbd60, 0x8025b302, 0xaa05b65b, 0xce15baf8, 0x857f75c4, 0x946f6f58,
- 0x15af34bc, 0x809fc059, 0x25e98ef7, 0xc049641b, 0xcaf5869e, 0x4b9e3c1f,
- 0xfd43dcfd, 0xfe4fd0a8, 0xcbd1fb85, 0xd1fa98a7, 0x7e8cabcb, 0x493f5016,
- 0x474fd717, 0x786675f9, 0x7e8dabca, 0xcf1fa8ea, 0xff4bcdc5, 0x78660dc6,
- 0xfd4b51be, 0xb1f34ea4, 0xbaeb8680, 0xedd607e0, 0xb6bde197, 0xe3c27535,
- 0xca2f962c, 0xdcf1c61e, 0x7cb12520, 0xc9253291, 0xfea987c4, 0xf43aa661,
- 0x2cbad3a4, 0xe3df8ff4, 0x4754b924, 0x4a17a4aa, 0x9e093a47, 0xa46a4687,
- 0x2eba1e17, 0x87ae3970, 0x4bda3638, 0xab81a90f, 0x0d7c38f5, 0x132c4a70,
- 0x320fb04b, 0x695fbe87, 0x1b2878e7, 0x7df0b675, 0xd6c1bef8, 0xf50a985f,
- 0x3fe95b36, 0x959e3ce2, 0x24969db8, 0x976c46b3, 0xdef6e0e4, 0x0d92dcca,
- 0xb53c18c1, 0x4bfa068f, 0xdbb6fd83, 0x5fc89903, 0x0ebf4bcf, 0x18adbf22,
- 0xfc7d92ad, 0x22aff342, 0x2b8fd041, 0x22665747, 0xc82a1d3e, 0x2af8ec77,
- 0xe3445f8c, 0x7ff1c06f, 0x477c6098, 0xf8d314de, 0xd32a9cce, 0xc6154ef8,
- 0x26df7e07, 0x07c625bd, 0xd8c75dfc, 0xa1bfcd4b, 0x55391df1, 0xb44afe34,
- 0x4fc7634f, 0x27ff181a, 0x5bbb8c12, 0x90d2ebe2, 0x675de7f9, 0xb54e7f9e,
- 0x9f2afe79, 0xdfe95eff, 0x3449f8c4, 0xefcd7dff, 0x54e7f9f1, 0x783bf9f3,
- 0x7be303bf, 0x107ff006, 0xd1247fe7, 0x306ff3fc, 0xad4c7fcf, 0x3e0efe79,
- 0x0fa52ffe, 0x8d1af8c5, 0x13e6abff, 0x6a63fe7c, 0x11d57c69, 0xa91f21f0,
- 0xc91a92a3, 0xed06cf9e, 0x94748234, 0xdcb1ca9f, 0xf2976eee, 0x250f0f08,
- 0x3cfbbe71, 0x1b4df809, 0x042c77d4, 0xacfa0512, 0xcd7cf05e, 0x503552d6,
- 0xde83de24, 0x5d40285b, 0x5f1325d0, 0xd08ed5b3, 0x6f6f0065, 0xfac41c97,
- 0x0b5fd582, 0x71deb4c9, 0xb9cc007f, 0xc3ff3e08, 0xc7d6e3d3, 0x2e5acbce,
- 0x889fb0ec, 0xc388e49a, 0x63632c13, 0x6bbe011b, 0x67f09d25, 0x1e804fd4,
- 0x3f3fa065, 0xe58a3d00, 0x381fc287, 0xa9967a0e, 0x4cd372b1, 0x6f7741df,
- 0xeebcc116, 0x509ff010, 0x2c4fbe38, 0xff884295, 0x507a9fcf, 0xb0b4fd45,
- 0x3e901923, 0xa0834708, 0x476eff53, 0xf844bd68, 0xee7e22f4, 0xec645124,
- 0x5fbec277, 0xe9b866b4, 0xd42cb9bb, 0x1fed0996, 0xb46f3558, 0x67bff30e,
- 0x4c82638e, 0x947f9f7e, 0x8d98e48d, 0x318f81b2, 0xfb29f3a7, 0x39dca828,
- 0xefb26ec7, 0xeb980aef, 0xeb9954f7, 0xdd90f6bd, 0x62c6f686, 0x7e83ad89,
- 0xbf346def, 0xdbb1c637, 0x8c7b0986, 0x0647778f, 0x2c5ef787, 0x9d63e027,
- 0xce9f7ae8, 0x69e035bf, 0x22cec478, 0xd3465eb4, 0xc1678fd1, 0x02d7b274,
- 0x15b79f3a, 0x4eecfbde, 0x73c0057f, 0xe132c3df, 0x747f0ad3, 0x06dfb25f,
- 0xcd745c76, 0xe768ed1f, 0x8563e75a, 0xd665feff, 0xea2ae8f9, 0xeb4179fb,
- 0x5627ce73, 0x2ae86a7e, 0xa63c7e1d, 0xeff85d5d, 0xe18f1f87, 0xb32d9aaf,
- 0xa1c5f54c, 0x17ed4cbb, 0x7a6799ad, 0xb163b0bf, 0xed03fde9, 0xf3ea9a0f,
- 0xda9b0f82, 0xd9acbfdf, 0xc6defef4, 0xefef4cc7, 0x54ca7aa9, 0xacf02bbf,
- 0x739dfda9, 0x4bde99d6, 0x898f16fb, 0x8c0d5e92, 0xf2bb42c9, 0x7e43076d,
- 0x90ddf834, 0x329a8f87, 0xe4d93ca9, 0xe519b2a5, 0xb6dfe414, 0xeb0d979b,
- 0x63d18de7, 0xed0ff6ec, 0x4f28398d, 0xe2b7be56, 0xf0dfcad3, 0x75bc546f,
- 0xc16b28c8, 0xd73d475f, 0xe367d627, 0xf8648f79, 0x2e49cb07, 0xb72e556b,
- 0xcab23bb5, 0x55ae5fd0, 0x718d8523, 0x79018afc, 0x0f344b0e, 0x3a745686,
- 0xd5b80dd2, 0x137cd744, 0x65fb3d9c, 0x651ebf1a, 0xffdff417, 0xb2df1565,
- 0x1c883ea1, 0x1c75b9cc, 0xc87fe3c2, 0xa574f086, 0xd3dbfad3, 0x71f86334,
- 0x4157f105, 0x734d47e5, 0x14d13ca8, 0x5378f2a0, 0x341f9515, 0x6d195235,
- 0x7be5465a, 0xdf2a414d, 0xf2a76a6d, 0x541d4db7, 0x435a6b1e, 0x429a6fe5,
- 0xf936f654, 0x2bf01ca9, 0x26993d0c, 0xff614aec, 0xf5410ac3, 0x322e62d3,
- 0xf24dddfc, 0x7944cbe8, 0x5e7dad3c, 0xe9f37688, 0x72c60e63, 0xcacbe313,
- 0xcaf1090f, 0x545764fc, 0x4c394086, 0x95defa1c, 0xb2e4e9c4, 0xf40c19b1,
- 0xfd9763c6, 0x88bf37c0, 0x861b0aea, 0xb37c87df, 0x05fa71dc, 0x75e915df,
- 0x7f313a21, 0xa06cf17f, 0xfee789c7, 0xedfb04bd, 0xd70a75c1, 0xad3283cb,
- 0xc1b22c97, 0xc18af487, 0xfd3fad1b, 0xbe5e853b, 0xa54efe00, 0xceebf81b,
- 0xd8bb7f41, 0xa7ff53a6, 0x414c1d3b, 0x0e49ee3c, 0xf4eaa861, 0x5c1e0de1,
- 0xda6496ef, 0xf071e3f4, 0xe1759460, 0x5d8b5d5c, 0xf5ccba27, 0x0cd21dd3,
- 0xa6f2bf1e, 0xd67c86dc, 0x0bc7eba4, 0x5499fe90, 0xc92cfd1a, 0xe4e3f554,
- 0x3af8871f, 0xf89535b5, 0x6a36fc14, 0x470d1ff7, 0xe1067ea2, 0x87bf64e8,
- 0xc917c9ef, 0x337ef2ff, 0x7144fe53, 0xfec7b626, 0x0ee7ae39, 0xf91ceff8,
- 0x8dd50af7, 0x72c21b7e, 0x3e3571d0, 0x0f1a6adf, 0x3e1af3be, 0xf3bcb9f1,
- 0x4ec2abf1, 0xbdf9f8c4, 0x71f90638, 0xf7acdd2e, 0x86f54d53, 0xb4dd2cae,
- 0x201fe00e, 0x524aacf7, 0x056a5f90, 0x5a29f4f7, 0x1df004bb, 0x2e8979b1,
- 0x576f120d, 0x01aa8ce7, 0xcb4df22f, 0xb17bd71d, 0x2f1a8765, 0xe9b2716e,
- 0x125157b0, 0x9f235fc3, 0x8e22a87e, 0x8d1c3f9d, 0x368bd427, 0x67334f6e,
- 0x24fe83d0, 0x667a0ccb, 0x6d3409bb, 0x07e43f00, 0x753138c1, 0x21c59fa3,
- 0x75bc7f7b, 0xedc6c7b2, 0x05b8eb64, 0xf85174b2, 0xb47adfab, 0xc56de71c,
- 0xa7d77d63, 0x0be4806a, 0x883257fe, 0x47bf0347, 0x3205156c, 0xe5bd5ff4,
- 0x3f27b27d, 0x1f0b07b2, 0x1ade8f39, 0x7996bf0a, 0xde663922, 0xe38dd641,
- 0x5a7117cc, 0xdf3befe0, 0xe3f17581, 0xe30cecd7, 0xb42cecf0, 0x8303818a,
- 0x3fa8364c, 0x3bf36a20, 0xfb3e286b, 0x41db8db1, 0x0785580b, 0xd62ac29d,
- 0xe0768251, 0x819b6629, 0xdec53a78, 0xa18c4cf0, 0x25590cd3, 0x6ed03cfa,
- 0x7ec043b6, 0xad17d535, 0xd92bd731, 0x33d40cec, 0x2cedab95, 0x4cfcd124,
- 0x3ac8a7ef, 0x3588bbf5, 0xb9f5c0ae, 0xdfe3cec5, 0x8ca675f3, 0x5eeaf802,
- 0xe304be7e, 0xdcc8b7e2, 0x1be2308f, 0xf871878b, 0x54ebc3ab, 0x7dffbc3f,
- 0xae3bc4e7, 0x687df867, 0xc10fae05, 0x936f929d, 0xbf7e2877, 0x7856fc2c,
- 0x487bf58d, 0x51c0459c, 0x1b8a45b7, 0xf057bd37, 0x3f8fc1b7, 0xec36f312,
- 0x1eb197fa, 0xca37f763, 0x332aae22, 0x4a7ee919, 0x296d0677, 0xefe29ef4,
- 0x5f0e1dc1, 0xacefcc0b, 0xf22962ad, 0xc50fd817, 0x59dda62c, 0xf79e805b,
- 0xd257af48, 0xa11299be, 0x7b58107d, 0x357dd894, 0x8c53c939, 0x83376371,
- 0xf71f35f5, 0x241482d5, 0x9aaee158, 0x6e318ac9, 0xfa00fa0d, 0x7e53d27b,
- 0x4bba8258, 0x9fd864eb, 0x971cd323, 0xf5cd7977, 0xf703fc06, 0x8a32c67d,
- 0x558f251f, 0x308c782c, 0x9f6e1fd4, 0xe42fbe25, 0x1f13de11, 0xa1c5887b,
- 0xb9116a74, 0xe9461918, 0xf297f019, 0xf0e35fd0, 0xda007c53, 0xfb79d52f,
- 0x5f07117a, 0x88d976fa, 0x9789e761, 0x15819c35, 0xdd4c7868, 0x519fd388,
- 0x25e26858, 0xac2f55e8, 0xf57a31b6, 0x07e05b65, 0xa3d40f48, 0xe3049f08,
- 0x04f86204, 0x563d571c, 0xf85a0fce, 0x23866fe1, 0xfbf4998d, 0xe5e05b11,
- 0xcdfc7078, 0xe90e67fd, 0x687fe0ff, 0xfa4305ff, 0xfebc75ff, 0xb6de5eeb,
- 0x54fc082b, 0x3da7e3fd, 0x63ecccc0, 0x07c323a5, 0xd4ddaf74, 0xfcb941e6,
- 0x907a0948, 0x64871fae, 0xf2b3f7da, 0xe4315d81, 0x2549afd3, 0x47c43fc4,
- 0xe27c5f27, 0x3eb7b466, 0xc9d764df, 0x88e2dfbf, 0xeb298038, 0xf973173b,
- 0x9f78e2d8, 0x8a7e57d7, 0x65d0d9fc, 0x9bd517d6, 0xd2f0ce9f, 0xfe1415fa,
- 0x87fc846f, 0x287f8dfa, 0x81ac7b47, 0xb3de93f5, 0x9fe3877e, 0xc2f64619,
- 0xe865353c, 0xaebf637b, 0xa1a5e041, 0x654f89f3, 0xf9289612, 0x55f6d68b,
- 0x5cf80fc2, 0x9367fb16, 0x33e464d9, 0xc42c1f03, 0xe5f900fd, 0x8e318be7,
- 0x35f1b3d3, 0xcb14548f, 0x9def5c9f, 0xfdf03f0e, 0xcb137a9f, 0xc5e82f53,
- 0xb0db7b58, 0xc25dbcef, 0xcbc3d97f, 0x83c47b5a, 0x75dafd71, 0x1e105f76,
- 0xf0db6ed7, 0xae30e783, 0x77c3b6f2, 0xb35ff419, 0x5cdfd5ed, 0xed9af507,
- 0x7c99b4f6, 0x31949a1a, 0xf8069748, 0x4184d96f, 0xe4ff543a, 0x8e3bd555,
- 0xd8747f3f, 0xb66a3d20, 0xb8d957ef, 0x1a98f8a1, 0xb546afde, 0xbf097438,
- 0x867e8e5f, 0x2a17f2fc, 0x7de3fdd2, 0x1b911b12, 0x5eeb9f07, 0xf1197b25,
- 0x74147444, 0xa59ba01a, 0x05d0037d, 0x2741abf5, 0x4263fbeb, 0x6f3fb1de,
- 0x4bf3f111, 0x907dc53f, 0x387c3adf, 0xbe97aaff, 0x7c79c1e9, 0xbe7234a8,
- 0xc32dbe7e, 0xd956e30f, 0x953a1983, 0x0bd579fc, 0x5b7e22df, 0x195bf474,
- 0xfe60bf14, 0x0ad91b2c, 0xdf9c2cc1, 0xd3b7b5c2, 0x80592afc, 0x79eaaef8,
- 0xabd702b9, 0x633614cf, 0x78b91c7b, 0x87c5c844, 0x80f1c1eb, 0x0b887df9,
- 0xbc0bee07, 0x06de5321, 0x7c520f63, 0x7ec65be4, 0xf5425b0e, 0x4e9c9ccf,
- 0xefc315b3, 0x96279585, 0xecae375f, 0x1c9cfa46, 0x71811fed, 0x04a606df,
- 0x73a43e05, 0x747cafd0, 0x1f4e08fa, 0xc44a55e6, 0xa7efa077, 0xdf6c73e2,
- 0x8abbf76d, 0x73b1df4d, 0x2fe383b9, 0xdc03e315, 0x7ecf6849, 0x1f7f1198,
- 0xac62b37f, 0xc5576037, 0x7c8c57f0, 0xf8df7973, 0x436f9718, 0x66b343de,
- 0xbd3ffbe0, 0xbf07e5c9, 0xe0057b43, 0xf7a08c8a, 0x48936ffb, 0x2458381f,
- 0xb46f5c9e, 0xbf36b90b, 0xe004f837, 0x1ddd7056, 0x7fec17e0, 0xec9fe118,
- 0xf0d5cad8, 0x6cbe8c5d, 0x433cf1c0, 0x76e433fb, 0x87ff9091, 0xb3fcb314,
- 0x13ee5cb5, 0xc2411bfb, 0xf43dad4f, 0x5e50e783, 0x1f713e41, 0xbd9b76ba,
- 0xc9fde702, 0xb9bf83d6, 0x93e4e41b, 0x66a721b0, 0xd39569fd, 0xb0d71daa,
- 0x09fa7278, 0x93c413a6, 0x571e7853, 0xf128b54e, 0xfe957ff1, 0x82f7f034,
- 0x3e867f05, 0xab47844c, 0xf15ebc3e, 0xfaad3e12, 0xc9bdfe10, 0x9ff2864a,
- 0xbf0677c1, 0x6ea8ff55, 0x019dea0c, 0x6ef834be, 0xbe0d2f80, 0x342f121b,
- 0x3e886fe1, 0xf00cd8c3, 0x7feec549, 0x99fcc72d, 0x5f7c3dda, 0x843bbe14,
- 0x9f93c075, 0x871d61bb, 0xd6c5a546, 0xd87a9643, 0xa96fded2, 0x07da5857,
- 0x4b46f52c, 0x0bf710fb, 0x3caa0ebb, 0x6a62254f, 0x82ce5f6f, 0xef538c6e,
- 0xd21e2995, 0xc0af3007, 0xb9ada4bc, 0x6863cc21, 0x5338f173, 0x02baba7f,
- 0xde9f57f5, 0xb07b41ef, 0x73e3c5df, 0x9efd157d, 0xec3b18d4, 0xe9323dfd,
- 0xcd8868df, 0x822fe788, 0x8bf44187, 0x79ef44b2, 0xacba7ddc, 0xf8c32ce5,
- 0xc3ec874a, 0xe682cd90, 0xdfb83d3b, 0xff27b7df, 0x7cf03996, 0xb69911e1,
- 0xfed0faf3, 0xfb34414e, 0x3f18ac95, 0x7c1623ed, 0xa38c06e6, 0xdafee1ef,
- 0xbb165582, 0xbe22ad82, 0xaa96d4a8, 0xbfc117a8, 0x8fbcc0fa, 0x5abbf9c0,
- 0xd6b557f4, 0xdef8defc, 0x37abe3f0, 0x8407df9a, 0xf9167fdf, 0xf1d2ed1d,
- 0xbbf73c6c, 0x09378f19, 0x2e5d3afd, 0xe00e65ba, 0xccb0efbf, 0xef4e5f90,
- 0xa7ff0991, 0x737df2b7, 0x8b5f9f8a, 0x7a4fda7c, 0x0f53c0cd, 0x589a85ca,
- 0xfcecf4ef, 0xd023c95d, 0x3bd776a4, 0x6504ffc5, 0x0bb7aecf, 0x97f5867f,
- 0x8779cadf, 0x753f6d0d, 0x2bf68b9f, 0x69b9f6fa, 0xef6fb17f, 0xc11e732f,
- 0x8f876efa, 0xfdf6fef2, 0xa7f918b9, 0x0aa3b96f, 0x68df56f5, 0xecb667ee,
- 0x947173fd, 0xa256c9d6, 0xee76e5db, 0xf3de9ee7, 0x6949efef, 0x70acc258,
- 0x4c97dffd, 0x9f86b771, 0xd65e28ba, 0x25cff7b7, 0xa5fbf6b1, 0xec5ea7ce,
- 0xd9b9f623, 0x5f081d9c, 0x697fdf2a, 0x1bb5d9f8, 0xa20f319a, 0x00fabf73,
- 0xcffa9fbc, 0x3ea3145f, 0xedc1dbec, 0xf47b5e9a, 0x9b27dc05, 0xb962b6d0,
- 0x8bd5e81d, 0x64fb8142, 0x0b2f3f6d, 0xf2f0f16a, 0x2f01c505, 0x8f7f1f16,
- 0x9fff48f8, 0xf6890f80, 0xb8f76bbf, 0xe7094e43, 0xdef797fd, 0xcfb03d41,
- 0xcc697c41, 0x337093f7, 0x9a171dd9, 0x6e57d577, 0x62e452de, 0xbff2bde6,
- 0xedbbff39, 0x2acf825e, 0x7cf94307, 0xdf5443ef, 0xbc11f6e6, 0x9befc917,
- 0xdf746abf, 0x5cf77401, 0xfe87de78, 0xc8fdd2c7, 0x3aee827d, 0xfc3499e6,
- 0xdf0417f3, 0x2773d597, 0x3dd39bfe, 0xfb0dfcd1, 0xaf9b71fc, 0x6ce30f23,
- 0x3ac3fd68, 0xb767b9ad, 0xf1efd863, 0xb475b3b1, 0x2fb16517, 0x846f8569,
- 0x191ffdca, 0x5e3127f7, 0x3c899a37, 0xd10fee6d, 0xad0c1d96, 0x8f649568,
- 0x6e0ada2a, 0x6ebe2b27, 0xf1e5e03f, 0x28fbe72b, 0x384d8787, 0xf67ac016,
- 0x438a3e0d, 0x56c2fc5b, 0xb025f989, 0x6f2b9553, 0x8a7e8c3c, 0xe22dac7d,
- 0x7df2a628, 0xf88a572c, 0x4d575da2, 0x64568bfe, 0xe6bcbbae, 0xe7f443ba,
- 0x677e1c64, 0x9c610b26, 0x80e2be59, 0xf265f98e, 0x50498578, 0x208eb177,
- 0x4c8e09fa, 0xc47ff7f3, 0xb898d364, 0x11ebda2c, 0xbe7fd7b0, 0x07c50375,
- 0xfef8bd4e, 0xcd6fd8cd, 0x04e664cf, 0x756ef4bc, 0x8df208b3, 0xffd15212,
- 0xfd94eea8, 0x523c8f3c, 0x3ecc6b72, 0xd62761a0, 0x704dd8fc, 0x8470ef55,
- 0xd5f7c266, 0x4c5f7ebb, 0x7ef2f6eb, 0x2f8363b2, 0x3d4f3c4a, 0x7dc62d18,
- 0x0e716abe, 0xf1a74ac0, 0xf77f8f2a, 0x839e4eec, 0x85b4bafe, 0x875649e7,
- 0x623bb4ef, 0xaac64bf2, 0xf11da376, 0x1287f051, 0x7c20a9e5, 0x8679f9b1,
- 0x43f3da9d, 0x65d7c389, 0x65be610f, 0xbded96f5, 0x3ea87718, 0xd9a1f0e6,
- 0x53e5b0d7, 0xfd4f6b8a, 0x944f36f1, 0xe4d92cfc, 0xf7f10e77, 0xd744c8b6,
- 0xb23acefa, 0xf44ea15b, 0x8fc70fad, 0x2fc85c7b, 0xdef1f9a9, 0x6140415d,
- 0x7b364fcd, 0xb271ae30, 0xfc87937b, 0x8fe72dbe, 0xeff10cb7, 0xd79d8fc2,
- 0x7f893bbf, 0xb774fd80, 0xb78ff16a, 0x15fb270c, 0xb7892be0, 0x4df065df,
- 0x5ecfb6cd, 0xcf63f8c0, 0x405e4f8e, 0xfaff6b78, 0xfed017c7, 0x3a5cfb64,
- 0xbc3443ee, 0xbf14aff8, 0x2a5bbe31, 0x87f7aee4, 0xd5ee299b, 0xf6357e0b,
- 0xc3f7bbd6, 0x7a3ff41c, 0x0325ffb7, 0x7ba5e4fd, 0xf9c08fa7, 0x7539dd2e,
- 0xbf238b04, 0x1b7c8946, 0x9bb888ba, 0x3b075e95, 0x7c9d920f, 0x7e8de80a,
- 0x1ebf80ca, 0x0ff1e3ae, 0xb7d3f0af, 0x0e6f8fc6, 0x6f3bcbf1, 0x936be5bd,
- 0x50fbb4b0, 0x3fd05c0d, 0x78e8137f, 0x6fd045f5, 0x5fc263eb, 0x53bf4f89,
- 0xe9d007f8, 0x57f0aabb, 0xeb3efd04, 0xe7fdf85c, 0xf0e75df0, 0xe479fe84,
- 0xc466f022, 0xfd57ef4f, 0x3728abcf, 0xf1447e3b, 0x4cdba410, 0xb6ef6898,
- 0xee3072cf, 0xffbd91fc, 0xef579e3e, 0xad1fd1d0, 0xc916fbde, 0xa3ceef4f,
- 0x22649f14, 0x06cbd98e, 0x93b8f1fe, 0xd86b85c8, 0xbd7ee6e8, 0xfdfa3fc0,
- 0x173d0f5e, 0x63e73dfe, 0xe44fefc3, 0xf2a9bfef, 0xae23023c, 0x1df1b75b,
- 0xd20f3fe1, 0x74829a4b, 0x71bcff7a, 0x3a0f0368, 0x6c7261e2, 0x5c7e2afc,
- 0x29ce2065, 0xadc465e8, 0x5053e206, 0x4578c6cf, 0xc58b7a48, 0xebbd07d1,
- 0xd7abdc78, 0x199fce6e, 0x678f0fa4, 0xa72adafd, 0x638b8ba1, 0x2ffe085d,
- 0xea889f8b, 0x0c73c535, 0x8d9cf53c, 0xab4fc7af, 0x37fa9e3c, 0x902c87ef,
- 0x9f21fbac, 0x75d63f22, 0xf3f2afbe, 0xcbbcfc04, 0xc8b7bec0, 0x5179ebf7,
- 0x8ac878a6, 0xe3d241f0, 0xec617d56, 0x55e15997, 0xd54f5c1c, 0xa275f177,
- 0xa43b8767, 0x073d3f41, 0xd73f1376, 0x455f7d6f, 0x96d0f33f, 0x9edca89f,
- 0xeb83f2e2, 0xfe062844, 0x17f6979e, 0xcf1d78f3, 0x338eb63f, 0xd2f1c1cc,
- 0x38fe27b0, 0x353f5b0d, 0x0c13538d, 0xf37f3cab, 0x549de3fc, 0x7f6277fc,
- 0x0cedbb27, 0x864ef3f3, 0xf6f119e5, 0xeb133f67, 0x035e71a6, 0xb3ca4bd7,
- 0x33cfca3e, 0x89237a4c, 0x1e9798f2, 0x9e0ef19d, 0xe20a5b8b, 0x6760f68c,
- 0xced3e733, 0x428ff07f, 0xbd1e777a, 0x6a75c65b, 0xc637e217, 0xb3792c2e,
- 0xf41baa71, 0x15bbc942, 0xad5d9093, 0x31f266fa, 0x187e099b, 0x03ae0467,
- 0x9e0fd0ad, 0x27fcc02f, 0x94f64784, 0x647840cf, 0xe2bba6dd, 0xb5da95e4,
- 0x36f3ca0a, 0xe6ebb5fa, 0x76766e3c, 0xe9fb17a2, 0x0bc8c2bd, 0x3c4148aa,
- 0x3b7dd67d, 0x29159d2f, 0x99d679fa, 0xecbe848f, 0xef01f269, 0x581673f3,
- 0xbdf9106f, 0xd20e7b55, 0xb0aaa2b9, 0xaf80bcc4, 0xe483acc5, 0xaa4766e6,
- 0xdb335bc8, 0xfe7bd50f, 0x7757da85, 0x2c35f6f2, 0x3cf1ed4c, 0x1f24c446,
- 0x07762d13, 0x913eefe7, 0xa67b51d7, 0xf6624584, 0x7c13ef71, 0x9ba4d3db,
- 0xc22d7bf4, 0xa939e1a7, 0x2ea71a6e, 0x8e34dc3c, 0xcceeaed1, 0x93122c75,
- 0x74a7547f, 0x9dd5bf13, 0x671a3bf9, 0x329abe40, 0xfb890f09, 0x7b82651f,
- 0x2629ffb0, 0xbffb0778, 0xe6b5c681, 0xe6ce6677, 0x5bacc271, 0xce341979,
- 0x852654bd, 0xb76f005a, 0x0e25816b, 0x5ee99f68, 0xc32afb9d, 0x285356f3,
- 0x8761fa3f, 0x8cde50a4, 0x4a759f38, 0x583682d7, 0xd6d39f6f, 0xa303753f,
- 0x707f813c, 0x2793135c, 0x3e7422c0, 0xe43768d3, 0x208f25bd, 0x15013f1b,
- 0xf2f80b28, 0x68c11e45, 0xb4f3a516, 0x3cfcdd6b, 0xcd2d18e0, 0x106fdf86,
- 0xde71be76, 0x40f9c86f, 0x0bc0b9cb, 0x9b4c079d, 0x18e0fa5a, 0x396f631f,
- 0x798a9d3e, 0x967769e2, 0x83a51f6e, 0xa652c1df, 0xe9737d51, 0x97a82cf8,
- 0xf5e16fb5, 0xcf8e975f, 0xab957a81, 0x246bd793, 0xb35fabca, 0x60b4c172,
- 0xe5e825d1, 0x252300db, 0x11bcbd26, 0xe2aa71e9, 0x7a163bdd, 0x5fa14f31,
- 0x1565f8e5, 0x14f46ed8, 0xed6cb78e, 0xa788eddd, 0x3368b631, 0xefef93ea,
- 0xea2a73fd, 0x09d32f71, 0xd56b3a3f, 0x68f07e91, 0xe4f3b9ca, 0xc2f359c3,
- 0xa5d9fe0c, 0x1c227605, 0xd2c7f36d, 0xaae7bc39, 0x1fd13826, 0x6cf2235c,
- 0x0fc81d9e, 0x7ef1e7e4, 0x75fbe0ee, 0xeb0f2299, 0x29b9a3f4, 0x0fa3cec3,
- 0x5dbb321a, 0x7d5c0c4a, 0xb3ed3f4a, 0xff7d9df7, 0xc49bcc3e, 0x759c6a7a,
- 0x37fbf065, 0x93c90a5d, 0xe981ff39, 0x0b5fc469, 0xde217f04, 0xf879319c,
- 0xcaa0e48b, 0x8874c3cf, 0x8e9a6ef5, 0xb58297f3, 0xbeabb9f2, 0x68169e3c,
- 0xcf90f781, 0xbc8871df, 0x34be711b, 0x7be33ce6, 0x79eb4788, 0x8a8e8dc6,
- 0x55977e28, 0xe5072679, 0xa27ce06d, 0xf48591d4, 0x64779eb3, 0x9e2dbf4a,
- 0x9c5eb11f, 0xf7044c77, 0x3e819d8f, 0x9fef3f1c, 0x830e3bbd, 0x40bd5fdc,
- 0xe7ca61f5, 0xa526cbd5, 0x215cfc2b, 0x820d05d9, 0x5c6d32af, 0x1887b03f,
- 0x39f6d3ed, 0xebfa3f24, 0xc9d4df7d, 0x305ec80e, 0xbee6fc93, 0xe630dce4,
- 0xc23df513, 0xfd8297cf, 0x8f7ca120, 0x711293de, 0x3f3e4879, 0xe7e7c8b7,
- 0x3cc97b66, 0x6f39df6e, 0xd3fa9457, 0xc8607f45, 0x0f9e0c67, 0xfaf993ee,
- 0x25e4d7de, 0xe0b34638, 0x2f13b47e, 0xd38f3c76, 0xf017fe7c, 0xf0633baf,
- 0x811c740f, 0x426734f5, 0xc6708e3a, 0x1cf5a3a1, 0x204711ea, 0x587ddb1b,
- 0x86056879, 0x4fe7ac5e, 0x42cc1299, 0xdbe9593c, 0x6b3c74a0, 0xec662987,
- 0x16ec94f9, 0x2f577e83, 0xc32ba5f3, 0x8b1cf44d, 0xe7bd5e70, 0x6dc21b53,
- 0x527bf1d0, 0x8277bb7c, 0xd667af93, 0x44e632f1, 0xed38816d, 0x5095978b,
- 0x499f807f, 0x8f5cfc16, 0x14e29af3, 0xfc50c2eb, 0x2fed8f5c, 0x8bfe3f02,
- 0xc7e18fc1, 0xae3908d5, 0xa0277dc1, 0xb3bc1ff3, 0xdc60f233, 0x3e235972,
- 0xa649bc5d, 0x9fb42db8, 0x28319599, 0x6daf8bf7, 0x7e076fdc, 0x44bcfc59,
- 0x9c40b4fc, 0x9c44ff2f, 0xefe6b13f, 0x9209ce55, 0x1e70bd9e, 0x46f4885f,
- 0xf3f316cd, 0x7fc29dbb, 0xca1cb374, 0x47f715cb, 0xad7f82c8, 0x09ad3ff8,
- 0x6a905eb9, 0xc7a5676a, 0x299b46e8, 0xea6b3c0f, 0xd7e43f40, 0x6fbcda67,
- 0x17edfc51, 0x20f18676, 0x293692bf, 0x2498f882, 0x4b7ec34d, 0xfd197c85,
- 0xb666598d, 0xe68372eb, 0xedf979f3, 0x9779f3e6, 0xb5348c75, 0x9e4d7cbf,
- 0xa115fde9, 0xafef4d2b, 0x54c132da, 0xcebe171f, 0xaeeafed4, 0x7c7d5332,
- 0xfb5346e4, 0x9b678789, 0xdf74d7ea, 0xf93f6a6d, 0xfbd37cd8, 0xa6d5a36b,
- 0xb47fd7f7, 0x5aff54c4, 0xb531ffff, 0xfae42c8f, 0x665340eb, 0x7c98f1f6,
- 0xaa0f03e3, 0x3f9f1d36, 0x8bd36858, 0xf8679f63, 0x9658c5bd, 0x4e9fd1f8,
- 0x3aa767a4, 0xd763b2b3, 0x376652f7, 0x4ea99fe9, 0xf0643d73, 0x0bf00e4b,
- 0x45937f10, 0x6dbc80ef, 0xd5193941, 0x983b4378, 0xe2e46ca1, 0xa7941482,
- 0xc5f9f1a7, 0x9236d9c9, 0x9d08fab3, 0x0e738f8b, 0x17356dfe, 0xf7482ef9,
- 0x2e1980a1, 0xa33100ca, 0x9606e60c, 0x29060b0a, 0x28f99cd9, 0xeebad2ef,
- 0x15bdeb1b, 0xdc9c071f, 0x6178701e, 0xdfd9379d, 0x645fee21, 0x3129731e,
- 0xa8f590f8, 0x1ef0eea9, 0xd77fe2d6, 0xeb2e7a6d, 0x69754cc7, 0xffca4cd1,
- 0x3d970449, 0x1b4dfe73, 0xb3d9bf41, 0xcf1a5402, 0xe2d8e6db, 0x9d45f7e6,
- 0x9de79717, 0xf10bbed0, 0xfb18a5fc, 0x39748a2e, 0x33c6f695, 0x3f56af98,
- 0xeffc9fb7, 0x3f59872c, 0x237dd60c, 0x97963e78, 0xf9d4279f, 0xda9b6b9f,
- 0xdf75c26f, 0xb7c2e798, 0x7e606767, 0x7f027642, 0xe7c5c73c, 0xd55342f1,
- 0x8cf00b4d, 0x2589da09, 0x73b2e783, 0x68e50d22, 0xf9118d7f, 0xe2d8cfd4,
- 0x759d3de7, 0x047b7f72, 0x13b4682a, 0xcb3f7e34, 0x3d77caa9, 0x2455b298,
- 0x7f22ce07, 0xbbbabfce, 0xf65f9f84, 0x7c3cf265, 0xf437e09d, 0xf1568e5c,
- 0x1cadea0c, 0xb9bcd730, 0x3119e143, 0x2e4662b7, 0x661d6fbc, 0xef5469f3,
- 0xf05ce897, 0x870d8ca3, 0x957fadf6, 0x03d6be09, 0x905e52d7, 0xda1805aa,
- 0x993cc6e1, 0xf63037c8, 0xbb4b3e11, 0xd6d4fc8d, 0x05ce072b, 0xb55bf231,
- 0xf7ec6e8a, 0x0858bc33, 0x932d69c6, 0xb473ef4c, 0x010f078e, 0xc99d951c,
- 0xd6549714, 0x967e4cdc, 0x69e1c99a, 0xd962417d, 0xe3c3c112, 0x0f8e1ee6,
- 0x42ea83c0, 0x3f73fb3a, 0x869319b7, 0x2a2975f7, 0x9d1ceb9d, 0x8d719e20,
- 0x5b7ebf01, 0x9709d906, 0x5795e19b, 0x21e0fd3f, 0x89d903cc, 0xfde11637,
- 0x3d04cb22, 0x4b6df3cd, 0x5dcb7d9b, 0x4de5aed0, 0xb800c999, 0x30d8ca37,
- 0x0a1c879a, 0x41b7c1c5, 0x1afb802f, 0x535e5b84, 0x15ccf34e, 0x74045e74,
- 0xd32575c6, 0xe8833156, 0x3863619e, 0x37fc2b4f, 0x7fdcb8b8, 0x790ba5cd,
- 0xe369bcad, 0x90172c70, 0x9b5e81bc, 0xba97fd86, 0xd311da12, 0xdbf4715c,
- 0xa8ffee85, 0x087dd39d, 0x136fd94b, 0x61636d76, 0xfa0cbdac, 0xd7ec16f0,
- 0x8f29cba8, 0x17bf6316, 0x141bbbb2, 0xee617b5f, 0xb432ed85, 0x0cff90c7,
- 0x39e60c7b, 0xcfbbc70f, 0x31ebd665, 0xeb9e7c7a, 0x4ac9ece2, 0xdde1f76c,
- 0x12f6b891, 0x1bb271e8, 0xfaf8d5d3, 0x1e82fbee, 0x28caba0d, 0x3ec1302f,
- 0x5c5d77d1, 0x4ff3adae, 0xc85ddeb4, 0x611bc8ef, 0x14ec07ee, 0xa5583ff2,
- 0xa756fb4a, 0x58f75d1f, 0x68fbe621, 0x9bc79479, 0xcb519fa8, 0x0f3f20de,
- 0xe204f9f0, 0xbb5fc0c1, 0xc69e7f85, 0xc5d6f1f7, 0xcda7c05a, 0xd70ecf84,
- 0x7f9fd845, 0xf328b9fb, 0x815e9e79, 0x0ffbd077, 0xf5b83e92, 0xb38c12bd,
- 0x39fedfd4, 0x79bffde9, 0xb8e6399c, 0x802f1181, 0x9c716a71, 0x2aff5bde,
- 0x8a51bae2, 0xbcecb647, 0xab07ee9c, 0x49f4332b, 0x45ce93a3, 0x7d11e766,
- 0xf872ed4e, 0xc353ce11, 0xd4ec5c78, 0x3087c9ae, 0xd349f32e, 0x73d8bce1,
- 0x3a5ea759, 0xfe87625a, 0x5a38ed4e, 0x0f5e90a2, 0xf78cde11, 0xa5fee775,
- 0xe377fd04, 0xdf00c1fc, 0x4bafe339, 0xf9fc16bf, 0xf180f165, 0x525fda78,
- 0xcf68b3d8, 0xd6a5e00d, 0x2a7ff79c, 0xc412bdf9, 0x13ffe603, 0x463c045e,
- 0x8bb57bbc, 0xa45a9fc7, 0xc6e31060, 0x54f7522d, 0xff06d38c, 0x4073a317,
- 0x9256b799, 0xcc3dfe99, 0xd61abc03, 0xb7db0ca1, 0x3e667db1, 0x750b9b1b,
- 0x111d2bc7, 0x1dd49f7c, 0xed42bca6, 0x4b047758, 0x8fdfb44f, 0x47fa86db,
- 0x6f2c7efa, 0x86ff02d7, 0x0feb0fe3, 0xfdf2815e, 0x3313058f, 0x4ca12631,
- 0x62f61df5, 0x852ce21e, 0x7d3a6dee, 0x2275a658, 0x3d739663, 0xa8ceff3f,
- 0x5eedccfe, 0x9392375a, 0x81e9f38c, 0x15575c5c, 0xf611fa56, 0xf815d5bb,
- 0xc33ff904, 0x08785dd6, 0xfb1d73be, 0x79e60e6d, 0xeda2f71b, 0x8fd8ad2a,
- 0xbbfdc6fb, 0x367aef25, 0x9c9f6e34, 0x28dfe5c4, 0xbe3527bf, 0xc961f98d,
- 0x63a7db8f, 0xae7bebbc, 0x0547ba46, 0x999df9fe, 0x702b9fd0, 0x71854b0f,
- 0xc66da924, 0x876ea0d7, 0x7bf1e3f7, 0xd02b5b5b, 0x606a5761, 0xbbde0d94,
- 0x87ad73a5, 0x8dfc3df1, 0x49c965f9, 0x9ef15ae7, 0xe7493538, 0xb902d0f3,
- 0xba818748, 0x4c77750e, 0x2ba969dd, 0xabcc6ebc, 0x285fe0ee, 0x0f7eb3ef,
- 0xef07d7bf, 0x337dc333, 0xe50cb7bc, 0xe849353f, 0xb1698d09, 0xdacea1e7,
- 0x3c49e902, 0xe5c8593e, 0x265f88c4, 0x97e22f78, 0xe291ac85, 0x60f1236b,
- 0x5bda3e75, 0xb0e654dd, 0xf88d2a7e, 0x51f31e5b, 0xa82ac059, 0xa83acb1c,
- 0xa98592bc, 0x54dd622c, 0x2a7eb316, 0xb1974c7d, 0x547cc09c, 0x8f1ad9a6,
- 0xf97d474e, 0xcbe93b0b, 0x1e0f2dc2, 0x0508c918, 0x6aa5ba26, 0x69867e5c,
- 0x2864a1a5, 0x80388b57, 0x16a9ae71, 0x3545e669, 0xd07d90a0, 0x93ea6423,
- 0xee20b635, 0x2ab9b29f, 0xe715af3d, 0x3edf6b80, 0x27e47640, 0xaa79f8fe,
- 0x4b949353, 0xeb3287dc, 0x1ab586c7, 0x73e41be1, 0x1ebbe22a, 0xcdba82e1,
- 0x1ee74dd9, 0xdfc3cbed, 0x745f7196, 0x45f69d9b, 0xa026506b, 0x0c2ee35e,
- 0xa7984b35, 0x9f6a515b, 0xf24d7c44, 0xce1a9353, 0x9e0da098, 0x78fac407,
- 0xebdf906d, 0xc1ca9ebb, 0xf78ff67d, 0xf9eb4dbf, 0x34b9c9f5, 0xa3ceba9f,
- 0xfb4dc06a, 0xcdca2a76, 0xf603e9c7, 0x6d8dd937, 0x9e0a5f2e, 0x25ffe93b,
- 0xc0ca8fbf, 0x7e95f7df, 0xc7beec57, 0x745026e1, 0x37af632a, 0xabf95265,
- 0xbf952f26, 0x1f99d268, 0xf623b91c, 0xe11136a8, 0x11d02f4d, 0xf0f44fde,
- 0x612663eb, 0x179e7b1e, 0x7692d3e7, 0xd444d57c, 0x77d93e3f, 0x77638c19,
- 0xf7849f2f, 0xce64b627, 0x95947ca6, 0x1fe704da, 0xc5169e00, 0x71874ce7,
- 0x6876d35f, 0xd3794197, 0xb89d9317, 0xd696bfae, 0xdf7179a9, 0x3aedfc64,
- 0x7f4103ee, 0xfea56fab, 0x09bfa2ec, 0x18ff6c4e, 0xf60da3f6, 0x6fd45fb3,
- 0xc348ef72, 0x189a87f7, 0x7a537dc1, 0xf7f61a67, 0xaf85a2f3, 0xdf84984f,
- 0xbbdee2db, 0x3499d374, 0x67bb07e6, 0xe61c99e6, 0x737af587, 0x2895e359,
- 0x9a4ddfff, 0xf904e6d6, 0xab1b7257, 0x4dac5f51, 0x09cdb9ba, 0x3653efc6,
- 0xf54e93a0, 0x0015dae9, 0x1fae34c7, 0xbc36f200, 0x659ed06f, 0xfc3af8a3,
- 0x8e5eeba3, 0x8eb8fea0, 0x2d969fbf, 0xfda010f2, 0x9f9fc7cc, 0xad57768e,
- 0xe962f9c4, 0xd3ee8ced, 0x544f6448, 0xf3a2499d, 0x7afd4679, 0xf31104ba,
- 0x8fb483d8, 0x43c67552, 0xbe2efae7, 0x1ce9a73f, 0x34fed0e0, 0x95f0ef1a,
- 0x29f93f06, 0xbb74b36e, 0xf970cfc8, 0xefbb6047, 0x83f98dd9, 0x7c44edbd,
- 0x0a83d40d, 0xaa23dbe8, 0x6df9ff31, 0x6e7f40d3, 0xb3df0756, 0x658f9829,
- 0xf47e67bc, 0x89248f87, 0x7e3ab07a, 0xfb4b24fb, 0x4dfea33c, 0xe7856f6a,
- 0xbac1ae7b, 0x5f2bda13, 0x08ea0638, 0x4b3653df, 0xf18cc37f, 0x6afea11f,
- 0xbed16572, 0x12bf55f5, 0xaae0ef43, 0x667bd2f3, 0xad6dd3d2, 0x9011fdf0,
- 0x6ebf5a73, 0xa17eb467, 0xf462f9dc, 0x6eb14ce0, 0xd2b99d55, 0x3a418f44,
- 0xfee89b14, 0xec65c821, 0xada2eb3e, 0x2173a4df, 0xbcbc9333, 0xe7e4161f,
- 0x9be6d69c, 0x3fff57f6, 0x1c2b7f1c, 0x4c7004fe, 0x63862ffb, 0x41bc69ac,
- 0xf04c8a38, 0x51c3e7fd, 0xf28e0096, 0x561c14af, 0xc728c57b, 0xf642bda0,
- 0xb0f38f2a, 0xb7b236e5, 0x151552fb, 0x369897f3, 0x5204ec85, 0x8eea5e19,
- 0xf146f1f6, 0x8f7799ae, 0xf3b61e63, 0x995dac2a, 0xe82afa80, 0xed7dc3cc,
- 0xe07ef16f, 0x740561f9, 0x2754e8d0, 0x177b47ed, 0xfc60d454, 0xb2a73bdf,
- 0xf1bd4a8e, 0x33ffbc16, 0x3c7fa0a7, 0xb4eb77da, 0x98db17b4, 0x6905ef49,
- 0x241e97dd, 0x13ee76bb, 0x2c94dadb, 0xcf8d9bd4, 0x052c1da2, 0xce1db5b7,
- 0xeb9ef78a, 0x5f927bad, 0x542975a2, 0x3f44aec6, 0x850ae428, 0xda3d200f,
- 0x23d21f34, 0x7b5089f7, 0xc795d41e, 0x8066be6c, 0x6d0d4957, 0x2bf00f59,
- 0x9afa164f, 0xf5087de1, 0x527fb61f, 0xab3de109, 0xd9bc9a2b, 0x8b49bf78,
- 0xb7d68fb0, 0xdf31d4ce, 0xb30a9ed8, 0xb0ae5204, 0xf685de37, 0xd7e49afa,
- 0xe2d79cdb, 0x1f6be07a, 0x267af3ae, 0x8f39b5c0, 0xc55339e5, 0x437f587b,
- 0x1ea46ccd, 0x7f4af753, 0x5fbcf995, 0x80dff36f, 0x6a92fceb, 0x157fbfc6,
- 0x879b95e3, 0xefe17819, 0x5c7531bd, 0xc1e6944f, 0xf79834fa, 0xbeb9e786,
- 0x47fa147f, 0x13e61f7b, 0x1c6e3b24, 0x8c324f9f, 0x2710f78d, 0xf5a3cf8f,
- 0x8beb0435, 0x578fdf07, 0xb1963ce8, 0x671ce3bf, 0x6c1dfda3, 0xdce4f58f,
- 0x73ffda3c, 0x08be62ce, 0x6966ede6, 0xf150bf7c, 0x38fcc34f, 0xf8bf00f7,
- 0x8aa8de29, 0x926d0ffd, 0xa93fff79, 0x39b4bbf5, 0x7e64549e, 0xd7302cee,
- 0x1f37cc1d, 0xb66a9683, 0x592879f9, 0xb387efc4, 0xe457e891, 0x6c3682db,
- 0x510b0577, 0x908b1579, 0x458e3f5d, 0x86357ea9, 0x38f1f33e, 0x700e9794,
- 0x997e644d, 0x642b47c7, 0x68163bf4, 0xbf68cd81, 0xfe164c6f, 0x6fde48ca,
- 0x77c1454b, 0xbe297ba6, 0xc5e519b1, 0x559eafa8, 0x448df14e, 0x3c69a5f2,
- 0xdee2388e, 0xfbdef382, 0x8f8cf539, 0x3ce46379, 0xbb79e35d, 0xba31b70d,
- 0x0f61a28f, 0xf78ca3f7, 0x7ef324af, 0x2fc4121b, 0xc15fae41, 0x459f7c79,
- 0x74b9edcb, 0xd3dfc9cf, 0xda8fb03d, 0x17548218, 0x6dfb9b79, 0x513b7b16,
- 0x92cfd91e, 0x80f2fe79, 0x18fc235f, 0xce9035f2, 0xe0597fc2, 0xbe6ee832,
- 0xc7b8c1cf, 0x4dc84fa1, 0xc44aa55f, 0x09834068, 0x05b7e9ea, 0x4a801ee8,
- 0x35ca9f31, 0x1fe819a5, 0x177fd82c, 0xf570b9c1, 0x0e30352c, 0x23cdc9cf,
- 0x5d7818bc, 0xfe0ff160, 0xbcf131d8, 0x9ec332f1, 0xc303fc36, 0x09fab01f,
- 0x71bfbe89, 0x43a27eec, 0xed296679, 0x7b237edb, 0xc0eb0d96, 0x4fbc7e6d,
- 0x78af38ca, 0x9feecec4, 0x6439445d, 0xb3f9f033, 0x550f7e2e, 0x7543dc48,
- 0x0c3f9bd8, 0xff919bbf, 0xbe5815c5, 0xa86b0ce6, 0x7b3b5fb7, 0x1ff266f4,
- 0x7986b094, 0xee14a717, 0xc67519ff, 0xbf14c8ce, 0xc9bf7817, 0x8fdd06fd,
- 0xefee5370, 0x9d78bce8, 0x573a0dfb, 0x4ed3aa7e, 0xb9377279, 0xf7b169c2,
- 0xbb94dc67, 0xf87ced37, 0x2387fc31, 0x79c3de02, 0x6804e49f, 0xe19f915c,
- 0x4b9d20df, 0x35bdfc4e, 0x471ae33f, 0x61f23759, 0x5dd7e0b7, 0x8345205a,
- 0x21766db2, 0xacda4fc9, 0xbfde4e49, 0x94247f39, 0xc57c44cc, 0xff0647cc,
- 0x5905ef59, 0xe873f12a, 0x386ae089, 0xafad3363, 0xa884f783, 0x8af6beb4,
- 0x26774378, 0x907afa7b, 0xd1ac5997, 0xe26ffb4e, 0xc916957e, 0x313d476b,
- 0xdfb96fcb, 0x5551e447, 0x2df0f588, 0x6a051f91, 0xe63f55f1, 0x7d3f3175,
- 0x63ee2dd7, 0x8f602c61, 0xfd023f97, 0xaddaf49a, 0xdbf5cc33, 0xeb75cc2b,
- 0x1e46863d, 0x7a4d2bcc, 0x5d3dec76, 0x87e812d3, 0xa5db351b, 0xcd1a0fc5,
- 0xae2303f1, 0xc3f98757, 0xe3c2cfb4, 0x7c9dd37a, 0x8b88b2fc, 0x341a2ff6,
- 0xb8861d75, 0x3de19f51, 0xae35d3f6, 0x845e306f, 0x574d04f7, 0x436dfb8c,
- 0xef939f22, 0x6457a47b, 0x7dfdfb8a, 0x54af7499, 0x1ce99257, 0x386711ab,
- 0x494de05d, 0x3b7f0f3d, 0xad70d8d6, 0x54afa818, 0x07c89d1a, 0x5e79b32b,
- 0x871f20d5, 0xc754f14c, 0xfdee351a, 0x80fd0372, 0xe273c15e, 0xdb6fb12e,
- 0xd8f5f8ae, 0x5ec38478, 0xda7f23a1, 0x5edd65dd, 0xab55e5e0, 0xabc72cee,
- 0xbf305a0b, 0x4694ec17, 0x822bebed, 0xed3b4fe0, 0xaf78c3be, 0xf36dd3af,
- 0xacdc7ae2, 0xab3f68d9, 0xeb49d325, 0x56a90aef, 0xe8d2f5c7, 0x685519d7,
- 0x3cb5a73e, 0xe0897fd2, 0x669fc153, 0xbe631fb4, 0x6f3fea8f, 0x0dda8d3c,
- 0xe0eaffb9, 0x756714b5, 0xff946d79, 0x746816a4, 0x5fc19a8f, 0x6b9c7ed6,
- 0x24fdb894, 0xba427fc2, 0xd794a3db, 0xdfc5abd6, 0xbb497e5f, 0xb9eebcc4,
- 0xea777896, 0xf8230a6f, 0xe0f514bd, 0x8f902eb9, 0xab8c3497, 0xabfd3e8d,
- 0x47c92f52, 0xe1afcf06, 0x2da2db72, 0x5fbcf277, 0x89693df3, 0x4bc0d1f8,
- 0x47283c22, 0x4fdc51fe, 0xfab1601f, 0x563529c6, 0x68e1bed0, 0x138a6d85,
- 0x5cdc514f, 0x3e28b74f, 0x6bf95fe2, 0x075c4e15, 0x9ccad39a, 0xa6df9fb8,
- 0xd1725378, 0x33223c3e, 0xeab59b8c, 0xca31b966, 0x4f7ef1c7, 0x8898e380,
- 0x27df5a8b, 0x380bc825, 0xc7f5d627, 0xeddb5ff7, 0x009f0f3f, 0x491e68de,
- 0x7a8e8a79, 0x7873b641, 0xed7dc593, 0xc44dfa89, 0xe7ec4f1f, 0x8abbe0f7,
- 0xca8e749c, 0x38ab5e3a, 0xf00ad72f, 0x9adb9da0, 0xbee3e30d, 0xc9d157b8,
- 0xc49b1e8e, 0xa17c319c, 0xf7a24ea4, 0x3c34b5a7, 0x135ac7bb, 0xa7819df0,
- 0x1f552ed7, 0x97fc2c07, 0x978a5bfe, 0x5fdff0c7, 0x6bdff1e3, 0x1ce973c8,
- 0x2d7bd8fe, 0xbfbe5495, 0xc8d78567, 0xdb6677af, 0xc04bed4c, 0xa371e0b7,
- 0x032a1cef, 0x50311cd6, 0xf1870607, 0x71cf513a, 0x74e22e7f, 0x714fb60e,
- 0x55bca77f, 0xc39d3aa1, 0xebfcef83, 0xf74f6a34, 0xcea1d4d9, 0xf6aa3f07,
- 0xb0e98d4e, 0x4bd59f3e, 0x6f00ddd3, 0x7e01f749, 0x9d33a61e, 0xf88b5eff,
- 0x8def0ade, 0x1bf74e1e, 0x29953a3d, 0xc23ffcc7, 0xece83fdf, 0x1c62f24e,
- 0xfc5873b7, 0xcc7883df, 0x742fe46d, 0x28c8fd88, 0x4fa44bed, 0xff51ebe5,
- 0x8ff264ee, 0x99a7e286, 0xb16177df, 0xc1ee0637, 0x77642250, 0xc3bb0ad4,
- 0x2e64bf18, 0xf287aff3, 0xeed624d5, 0xca70fb04, 0x15dff8c0, 0x47802dfb,
- 0x9f96fb80, 0x4ffb455d, 0xc2af7f46, 0x33ed84b2, 0x92c5a232, 0x13fc097c,
- 0xcefba666, 0x42d19cea, 0xd97b1fdc, 0xf88e9816, 0xcd16386e, 0x1be77ac0,
- 0xbc1ec927, 0x72ee1e10, 0x7b9a7d73, 0x479f6195, 0xeb38d8d4, 0xe7a5edd2,
- 0x8b570f3d, 0xfd1890f1, 0x72b78836, 0x7e90ebc2, 0xe8af3fa1, 0xe92be31f,
- 0x3ae9f12d, 0x2c919f48, 0xf47cfc38, 0x89c161c9, 0x22a12e9c, 0xe7dc7f4e,
- 0x5d937983, 0xf59b741f, 0x8afeffc9, 0x130d37cc, 0xd29f80d1, 0xbef3c4a1,
- 0xde2cef78, 0xe3c4bb8f, 0x693fad35, 0x1d457b0a, 0x4987c316, 0xfa84e82c,
- 0x4be88e2d, 0x7518ff68, 0x0e2dfde3, 0xcfec69e0, 0x90c8e5c9, 0xf1b9dadf,
- 0xedc736e5, 0xc74df9e1, 0xf7dc1e22, 0x03e38e98, 0xbfc33bbe, 0x3ac77ba7,
- 0x3f8664bb, 0x6e62309d, 0x83680e40, 0x0fda1a74, 0xfc86abd7, 0x95793983,
- 0xed3fc85b, 0xfee32ee3, 0x8c67a1b5, 0x6b725eef, 0x8b8fa697, 0x7af39c86,
- 0xe408e509, 0xcb2e10ea, 0xbdf8cb39, 0x5ee2b577, 0x0f711e9b, 0xdfc207e2,
- 0xaff73a60, 0x3eb07b8d, 0xf7c81c28, 0xd6af3f23, 0xde0effe5, 0xca8ec343,
- 0x27fa6f94, 0xfdc29fdd, 0xd4bfb343, 0x31b9ee23, 0x66b6a5fc, 0x36736f71,
- 0x4936e7e7, 0xf6167fba, 0xf74a363b, 0xf0646718, 0xa738d3f5, 0xf4a332c7,
- 0x1f065a7b, 0x7fb3e225, 0x7a80f211, 0x8f97182f, 0xe32fe255, 0xeeb007f9,
- 0xb5ec6305, 0xd0151ff9, 0x98079bb9, 0x0f97e28f, 0x60b327b4, 0x5f3b5e0c,
- 0x732f9f88, 0x29db8c42, 0x456679ee, 0x7c835e7c, 0xb9d1e7ce, 0x0fdc3e3c,
- 0xe8fe70a7, 0x7779f714, 0xc464fe2a, 0xe175a253, 0xf65e80c4, 0x2b1f2327,
- 0x99bc1c5f, 0xc79af5c6, 0xfbf457bd, 0xe2cabfb3, 0x8f0004f7, 0x7b607f42,
- 0x1762c7a7, 0xf0feb25d, 0x419bd69b, 0xbd234fbc, 0x43fae972, 0x48fe80bf,
- 0xf2c2fa23, 0xe2bb41ee, 0x57bf30c5, 0xb6c3c5ed, 0xd0e3eb19, 0xe5c840ad,
- 0xdd0ae995, 0x84557643, 0xda89fbaf, 0xf7130c65, 0x5a3c0b0a, 0x8fcb4be1,
- 0x08b71fcf, 0xf196d43a, 0x9ef1917b, 0x942f9c76, 0xafe83e39, 0xd20b4ca7,
- 0xbc8bbff3, 0xdad17187, 0xfe2f0e1d, 0x0ecf524e, 0x85ea1557, 0xaa8e1d9e,
- 0xfa50daf5, 0x9bf42df9, 0xff8cec2c, 0x64bffae9, 0x2fe27fae, 0x4ba01f71,
- 0xad1c7ba6, 0x76e93dfd, 0xfa0377d3, 0xe5dd813b, 0x2d33fa10, 0x9ec5d399,
- 0xab4dd7c7, 0xf023dd5c, 0x67c08f76, 0x1e57b89a, 0xae2721d6, 0x39bb4643,
- 0x0094fde2, 0xef3f7b8b, 0xfa570863, 0xecf03ae0, 0xfbf632b2, 0x7d3bf8e1,
- 0x742b8a41, 0x839236fe, 0xf294f6fd, 0xfbf58138, 0x8c67c162, 0xc9e8ed99,
- 0xfd12bcd3, 0xd258611e, 0x807edf71, 0x4f7e61de, 0xb2770af0, 0xc5a2cfb0,
- 0xf73f92f7, 0x48a3f524, 0x0f1c50af, 0x0dbf366c, 0x0a7e88f3, 0x9e4c5b76,
- 0xbd16bde6, 0xbe678563, 0x13b7cf9b, 0xa3f637f5, 0xdde38b45, 0x5bac60ff,
- 0x86d3bcc6, 0x49e0e59b, 0x26c71f0f, 0x25974bc6, 0x6eba0f1a, 0xebe30c77,
- 0xe60bcf31, 0x479e127a, 0xc80b39e8, 0xfaee00e3, 0xfc6fc5fb, 0x59ce7888,
- 0x13d2b03d, 0x5da00763, 0xb095eb4e, 0xc6553bc3, 0x5d844bf7, 0x8274fa88,
- 0x90770b16, 0x6d974906, 0xf12b5f5c, 0x43cc35f5, 0x9b897efc, 0x2fb419fa,
- 0x4fb11db8, 0x389d6bcc, 0x8daafa3f, 0x21bd92b5, 0xe9c864f0, 0x6e9c8b4e,
- 0xec357cf5, 0x77e275b4, 0xf17e912d, 0x614ae1f4, 0xf31c95af, 0x95bcc78f,
- 0x1f342acb, 0xdd25a1fa, 0x9e600fb3, 0xfc1ee14e, 0x39419a61, 0x8cfc142e,
- 0xc18dcdfd, 0x6e3cefdf, 0xe6f7dd93, 0x857f0457, 0x7cc0d8c7, 0xebd18def,
- 0x7ae1eeff, 0x2dfc1d2b, 0x5fd38394, 0x785ebd11, 0x9e00e2ac, 0xba05aac3,
- 0xf830caa3, 0x6f3c33a3, 0xe1ed0bb9, 0xf687cc63, 0x9e786f74, 0x47f01c6d,
- 0x3f6e1aef, 0xd5f9e80e, 0x97a05f1c, 0x2f97a8c3, 0x2e4fe63b, 0xc296ba82,
- 0x7365eef5, 0x2967bf19, 0x5fa10eec, 0xf489e86d, 0xe2a7fadb, 0x727d6f3e,
- 0xe62bb363, 0x2efb40f9, 0xa83b9f68, 0xdf516a6f, 0xf3db1378, 0x79925323,
- 0xc71e7b3e, 0xe664f4cb, 0xaf3c0174, 0xdc6506e6, 0xb2f57cc7, 0xaf7809dc,
- 0x40a4a1fa, 0x7ef812d1, 0x0e3e0cf2, 0x2e8472eb, 0x47878dcb, 0x4433afae,
- 0xe44328dc, 0xf124676f, 0xe70a4572, 0x979d24f7, 0x1f9ce9f7, 0xe3f13c32,
- 0xbb44cb4c, 0x3bd71b3e, 0xb7c6978f, 0x914bae4b, 0x8b3ced2e, 0xdfc6b24f,
- 0x17494baf, 0x06db6af7, 0x3fc1b5f5, 0xc677c427, 0xfc6265f8, 0x89986745,
- 0x8d29167f, 0xce8b37c4, 0x8637c428, 0x3fe2245c, 0x1aeeff63, 0x14c6e047,
- 0x9fa3f79c, 0x209c6315, 0xdf0f6577, 0xdfdfc237, 0x7cb136b9, 0x4181eb18,
- 0x9df3d06f, 0x3d00cf18, 0xad0a693f, 0xfc8bcf43, 0x31a72e53, 0xf08ffa76,
- 0xbb3b1df7, 0x8e6bccaf, 0x7ac0eba1, 0x8cfee3e9, 0x85195d75, 0x89e9c049,
- 0x7298d5e7, 0xcaedfaa9, 0xf1787604, 0x5e1da97f, 0xe4813dd2, 0x578101f6,
- 0xc466be23, 0x7897f0b1, 0x8ab3bdb9, 0x1a7931f0, 0xffc06f97, 0x22ff8156,
- 0x1a7fff8e, 0x643dffc0, 0x79707427, 0x4bd688c9, 0xf45f24f9, 0x453bf19d,
- 0xa0df27b9, 0x293dce7c, 0xa9df7fdc, 0xbe409ffb, 0xbbf2255c, 0xa888cf27,
- 0x407b58de, 0x2ad17efc, 0x1af9c0fb, 0x591bc7ca, 0x0ecdfbcb, 0x189497ef,
- 0x8596d1f9, 0xf9802cc7, 0xf9f15767, 0x9bb14dac, 0x5875a7d6, 0x485f2e87,
- 0xbb2dfae1, 0x6015222a, 0x4a376b7f, 0x1237f40a, 0xf809877f, 0x0b236466,
- 0xd0fefec5, 0x4f1f1f48, 0x07a485f3, 0xd3e7068a, 0xa4559b6e, 0xcf695e83,
- 0xa0b5f648, 0x3606a4c8, 0xbed79f23, 0xf2fca11b, 0x2b76efc9, 0x9e5fc7e8,
- 0xcf82dfea, 0x6578f98d, 0xbefd247d, 0xce1cbbf9, 0x32f7610e, 0x71e1cd16,
- 0xfe0427ff, 0x887b0bd7, 0x23dfa61d, 0x94fdb8d2, 0xe9ac7cb1, 0xff0ce777,
- 0xfa73fd07, 0xb599693d, 0x70a78a33, 0xbcb196fd, 0x834bec90, 0x57e7a61f,
- 0xd3e7c46c, 0x01315c47, 0x5fc897ef, 0x77f05115, 0xd6ba7fa5, 0x94fef716,
- 0xc01f4243, 0xcec7f63c, 0x6b7242e3, 0x9d27b3b4, 0x67936f9f, 0x0ddbb7c4,
- 0x3e7d2c3e, 0x0fba6eed, 0xb86555b1, 0xffe064ef, 0x378ad4f2, 0xe1919e11,
- 0x46e11275, 0x49c4678c, 0xcfca39f0, 0x9cf9aa07, 0x5cf9425e, 0x82cc63b6,
- 0x556cf958, 0x2ceb3e89, 0xe86e13bf, 0xae14de8b, 0xad48efc7, 0x71f203f8,
- 0x1453d77d, 0x91bc59b7, 0x424c1eff, 0xfe245cfc, 0x78cdde60, 0xf80d5dcf,
- 0xa3ef7817, 0xeec89614, 0xf7c39dad, 0x72b76adf, 0x2aad657e, 0x1b5703dd,
- 0x7f411ede, 0x7ea3d462, 0xd5a76e1f, 0x2d2edd6c, 0xa8ebc18c, 0x27e510da,
- 0xe436ee5c, 0x2b19eb89, 0xd8dc63df, 0xc876fc05, 0x9eeaedc5, 0xff07ee52,
- 0x7ac9083f, 0x0080006b, 0x00000000, 0x00088b1f, 0x00000000, 0x7dd5ff00,
- 0xd5947c79, 0x6779f0b9, 0xcc93324f, 0x2133df64, 0x61262201, 0x01161212,
- 0xa0084933, 0x24584e08, 0x81ec36c8, 0x8bf628ac, 0x0c197e95, 0x6f62e452,
- 0xb90556ac, 0xda544076, 0x1a080962, 0x88b0e834, 0x148d6ad0, 0x43b05b05,
- 0x921088a5, 0x6f16b629, 0x79e7bd69, 0x799939ce, 0xf8b0ccdf, 0xabbf7ed1,
- 0x9cce1c7f, 0xf3cf6cf7, 0x273f679c, 0x2d675a5d, 0x2ba42229, 0xcae6c229,
- 0x9dbde424, 0x91488ee3, 0xe9769884, 0x55ae503d, 0xd034496d, 0x7483b5f6,
- 0x4eda16b6, 0x62909b88, 0x8e35a242, 0x12cfd0dd, 0x92adb26b, 0x49eab108,
- 0xc848d9a1, 0xeec4f1b0, 0xf0b7e5a6, 0xafad095f, 0x425cf5a4, 0xc1d334ee,
- 0x293fa0e2, 0xc9089874, 0x9c709b36, 0xc3211578, 0xac39090b, 0x34432e25,
- 0x8be0bb21, 0x89ac8411, 0xe399c472, 0xb10f1e60, 0xf196fed1, 0x4258f7f4,
- 0x5b891a6a, 0x6cd5f3a2, 0xf423adda, 0x76847277, 0x6524224a, 0xd6f384bb,
- 0x2d2cdf6c, 0x5e67bfa0, 0x075fb5d8, 0xa19357df, 0x7ab3f461, 0xd03b8d89,
- 0x7180cf62, 0xf61c7b49, 0x9654eb13, 0xbd70b884, 0xe9b7c6c3, 0x0e38b9ac,
- 0xbff4a3ee, 0x079f4ab6, 0x5666cfec, 0x9b3577e3, 0xa64feeb6, 0x626a91f3,
- 0xefc56fee, 0xe6c5dff6, 0xff89e8d7, 0x675864fb, 0xa2e75b2e, 0xc4baff5c,
- 0x2aaad7fe, 0xdfb4cd73, 0x5b08f8da, 0xb38b6d0b, 0x7ac18738, 0x0f3aa78d,
- 0x61918851, 0xa73a3ca7, 0x77febfd1, 0xd1848475, 0x58c3877e, 0x15b352ff,
- 0x47563ae1, 0xcebbf85c, 0xe3a56395, 0x8e17ee1d, 0x49b9bde3, 0xa4e01e35,
- 0x2773270d, 0x3793f9d3, 0xb454956d, 0xe6411b1e, 0x23d6023a, 0x5cc7bbd6,
- 0x062e6156, 0x1c227438, 0x706936ea, 0x473a15fd, 0xff5cf2f6, 0x2acc5377,
- 0xf4c0f79c, 0xfa5e74cf, 0x7c6fd3fb, 0x6ba9f884, 0xb06dec95, 0x748fd6de,
- 0xac00f2d3, 0x7893533f, 0xf6102642, 0x3e7b33df, 0xefe959d2, 0xfc337613,
- 0xa9deedd5, 0xaecb4059, 0x1a4ba352, 0x303c780c, 0xaeace807, 0x24c24f4d,
- 0x06739fc0, 0xa74943c0, 0x78841e02, 0x42be81d3, 0xe80233e1, 0x3aaa08a8,
- 0x67a47f77, 0xfa64e667, 0xdd346b7d, 0x8ee811bf, 0xd91883ed, 0xbec10fef,
- 0xc7e902e2, 0xafe60cb9, 0x801db708, 0x28515173, 0xac085ad9, 0x23ee18f3,
- 0x31c19cb6, 0x79953d70, 0x0ab3d6c1, 0x618b89e7, 0x378d12f3, 0xe713e61d,
- 0xd64d4e2b, 0xff7f4292, 0xfa578e26, 0x4efd87bb, 0xfcf239fa, 0x6de256eb,
- 0x75c259ab, 0x55a7a107, 0x53dacf80, 0xa7a30f1e, 0x93d00d4e, 0x8fa0bf58,
- 0xc6693657, 0x56e39e07, 0x6bc70eb3, 0x1d706b35, 0xa27e00cf, 0xe765a968,
- 0x065599f2, 0x198ff237, 0xf9488f63, 0xebf72f14, 0xabbe503c, 0xed0b5f9a,
- 0xf9b326ef, 0x0f54aad7, 0xa3ed7d40, 0xf882d246, 0xf0093fb4, 0x123d303c,
- 0xa55b52f1, 0x38e9eb73, 0xb126bf4f, 0x26e8cbba, 0xceb59ff4, 0x1fa10ba9,
- 0xbdb30d89, 0x1e737804, 0xf5334dd2, 0x3d2b27a5, 0xfbfa56f6, 0xce763684,
- 0xdb6a1e04, 0xdd015d18, 0x5c39bc23, 0xcb74f0fd, 0xc7c08dce, 0xa333289a,
- 0x00274a07, 0x616d9aef, 0x3606b3e6, 0xe804b7d7, 0x37ab22d2, 0xcf9927b4,
- 0x35ebf8e6, 0x83a00ff0, 0x8648c4ed, 0x75f075d2, 0xee72a1be, 0x19d43c02,
- 0x14b587bc, 0xfa4f43b5, 0xa2875cf0, 0x5fa69adb, 0x843b380d, 0x47896590,
- 0x55e714b0, 0x47ed8fdb, 0xc70eff7c, 0xd250cbfb, 0xba730ff1, 0xc36a29a9,
- 0xb67358f3, 0x71b1cf11, 0xc667e33c, 0x4d7e7253, 0xbf7c13c8, 0x8a9c71eb,
- 0x6ab1b688, 0x9f8af70a, 0x1216e64a, 0x912e5f9a, 0x8e8da388, 0x83a6c5f7,
- 0xbe00f391, 0xe355bf57, 0x7ed8c37e, 0xd0fe704f, 0x1c028db5, 0x4751bde9,
- 0x46f7ec82, 0xe39e23c7, 0x86bde012, 0x7b6bbec3, 0x513f88f9, 0x8b6d717a,
- 0xbdff01b2, 0xc3ca7db8, 0xeeeba27f, 0x53625ada, 0x38b4d903, 0x717c7e90,
- 0x942db661, 0x64d5627e, 0xbef144bc, 0xe460edaa, 0xcbefda48, 0xd42e0c5f,
- 0x7cdd7ed3, 0x535e179d, 0x1e5c0137, 0x9dc7657d, 0x96e35ed0, 0x778f8062,
- 0x3fe9fb6d, 0x6f57cf81, 0x9308006d, 0xa3bc5f96, 0x54efd2f3, 0xf7eccdee,
- 0xf866516d, 0x9f17cbee, 0xdde013bc, 0xed82d6d2, 0x8cdc5e17, 0xecaf03f5,
- 0xe9bffb78, 0x488eb577, 0xe1777c1b, 0x9788fdb5, 0x0ec6a75a, 0xd7450dfb,
- 0xcfdceccf, 0x849b64f8, 0x31548de7, 0x5ae825fe, 0xaf97efd0, 0x28111dcc,
- 0x8ed56a1f, 0x4fbe0954, 0x925edbd0, 0x9ca05e50, 0x688c3778, 0xdffee8c2,
- 0x9681a5a3, 0xfbe5ea15, 0x2ce780b5, 0xd908cfc6, 0xa7b5e42c, 0x6f7efe84,
- 0x75e6c449, 0x3eaeee70, 0x26e78d98, 0x1d1dd182, 0x31c7c0c7, 0x434438c0,
- 0x0fbeb0ec, 0xb2db6fd3, 0xa547ce8e, 0x924efb34, 0x47779c70, 0xce05bedf,
- 0x8c2f58bd, 0xda0f3937, 0x9e41532b, 0xf2d7df88, 0x670dae75, 0xe722edf2,
- 0xc6653537, 0x7c5e50b5, 0xf00aac35, 0x0ef3af53, 0x72fc00b0, 0x5b471d19,
- 0x6daebf18, 0x37adae5b, 0xe71c7f62, 0xa0a7ca13, 0xe9e7a3cc, 0xf49f3d1c,
- 0x0edfadab, 0xc97ef981, 0x193864f8, 0x3e98fb0e, 0xf0048ceb, 0xd46dc88b,
- 0x7f5c20d6, 0x9629dac1, 0xae87db02, 0x4947e760, 0x2316b9b7, 0xb73b1b87,
- 0x532bbbc9, 0xf4b7c8ad, 0xfa01feb6, 0xb3b57253, 0xbf7f44c5, 0xa6d3857b,
- 0xe6f774a6, 0x536363f9, 0x1c95fd68, 0xabd20869, 0xd8f2625a, 0xea79c465,
- 0xe7c8ca9a, 0x2d23bd74, 0x9bc75cec, 0x428ee689, 0x342a9e3f, 0xf8446344,
- 0xd5af90fb, 0x7af2e5ad, 0x31275b2b, 0x98a7d2f8, 0x8ef19fb0, 0x683aff68,
- 0xeb11a33f, 0xf2fbf4be, 0xaaba3e40, 0x755a3e50, 0x820bdeb8, 0xfe57117f,
- 0x7f3f3cec, 0x139b7aa0, 0x475e35e8, 0x8fe3234b, 0xfbfc7495, 0x9695a52c,
- 0x1f197f38, 0x7095dace, 0x74ed0f5a, 0x762dd79c, 0x8b6c8efc, 0x50afc991,
- 0xe39eb07c, 0xbbc919ff, 0xb5cce818, 0x740ccc37, 0x77a77f5d, 0x5c1f2040,
- 0xb07c616b, 0xf74dd39b, 0xef2f465e, 0xd82e54aa, 0x6e5bbbdf, 0xa8740cdf,
- 0xff03c794, 0x8695762b, 0x2edc9b8e, 0xc92f0199, 0xf0cb269b, 0x55baf547,
- 0xe5d657a0, 0x5f814348, 0x7fcbed48, 0xd7ad1b75, 0xbd41bc53, 0x9f3f377e,
- 0xef854f54, 0x172bdbeb, 0xb1297cc2, 0x12d4d977, 0x536347ea, 0x96bebd68,
- 0x7ff9c314, 0x37becd26, 0x9121f705, 0x4f20ac97, 0xf20d5ea9, 0xf50f2e34,
- 0x56e77af1, 0x8e49bfd4, 0x85bdcb8e, 0x27d7afa8, 0xf9c1b4ce, 0xf627c3ea,
- 0xaf7d42ae, 0x0b6e1ade, 0x684fdfa3, 0xfa601e97, 0xf5b0918e, 0x4fa87648,
- 0xc3748f70, 0xf8092e7a, 0x39db5288, 0xdeefe607, 0xda2e27a3, 0x71dedefe,
- 0xbd05cf28, 0xa3d75e98, 0x98d68f5c, 0x2fcbd025, 0xe7c9db36, 0x65982554,
- 0x05bc22b1, 0x67b66b3c, 0x5c9ce0aa, 0x9ff0ede2, 0x43cb9e35, 0x42dd69fa,
- 0x2d67d20f, 0xf563dbd7, 0x030782f6, 0x28f427f0, 0x82fc1d25, 0xa6f27fd3,
- 0x621c1243, 0xaeee7e25, 0xba069e26, 0xa937bbbe, 0xa8f9253c, 0x7c8fdd5f,
- 0x6c8e957f, 0xb78efa91, 0x8a8bf383, 0xf0014718, 0x46e98ac9, 0xaa7f205b,
- 0xc2abb708, 0x423cf402, 0xfa2a451c, 0x1378f9dd, 0xd875ffc2, 0xacbd1077,
- 0x63967fb7, 0x22bbc02b, 0xa7ed0c21, 0xf95d5a7b, 0x5d6d1fa4, 0xe7055e15,
- 0x2363f292, 0xed334df2, 0xdf8bbf4f, 0xe445f232, 0xd705a4b3, 0x6662d9b5,
- 0x8a38c4e3, 0x64b5811a, 0x39305639, 0xdb05b266, 0x3f7c7dcf, 0x29cfa607,
- 0x4c9d0150, 0xf4f4da35, 0x92dfa7bb, 0xb8dd23e6, 0xf384c0a8, 0xec715ce2,
- 0xd8af662e, 0x5388ee80, 0x7d56fa83, 0x9c1dc3a3, 0xd71d18ae, 0xf40bfd53,
- 0x88574a70, 0x2676fab7, 0xddb8227f, 0x50227c07, 0x4ae715df, 0xd7e05b9c,
- 0xde823740, 0xd1bdb9c4, 0xcfcdd9f3, 0x7fdd3747, 0xde9a7d20, 0x6eb97464,
- 0xda14b595, 0x731055d7, 0xb4aabda0, 0xf870ac83, 0x62fadd68, 0x11c61b84,
- 0xe2ce2e7c, 0xa8fc0b38, 0x35d1cb7e, 0x2f9cb648, 0xf8f9bfd5, 0x67e96b80,
- 0xcf1b0d06, 0x07708ee0, 0x82818fd2, 0xa58854db, 0x4473f80b, 0x12df5c93,
- 0xdcb93fe5, 0x65facef8, 0x7c01a4ae, 0xa8f2fd09, 0x0b4ff9ca, 0x45292fd7,
- 0xa626f490, 0xaf03c65f, 0x25b07e07, 0x24fc0dc2, 0x77389e3e, 0x97cf5905,
- 0xbc099cfc, 0x3e233b0a, 0x1c9f7d92, 0x5324f4cd, 0x8b2efb34, 0x0bf60197,
- 0xcaab079e, 0x43a88679, 0x8fd101cb, 0xc5db0bae, 0x1fed7a7a, 0xfc6f5b03,
- 0xacb603a3, 0xffa7c00b, 0x0856dd5c, 0xef5ace78, 0xfa37ccd1, 0x48f211e7,
- 0x7eb03f49, 0x9fb05b90, 0xdfd0dcca, 0x76e7eeb5, 0xcb9e829c, 0x633af9f8,
- 0xf2ddf821, 0x68eae718, 0x45159f5a, 0xff1431ec, 0x23d1deb3, 0xdf1c913d,
- 0x6b43b000, 0x8fa5c434, 0xdd6abc06, 0xfe3c00de, 0xfb40f00d, 0x2e0c98f5,
- 0x2d073d35, 0x68e2ce31, 0x8cab9e3a, 0xc7a03cd8, 0x0bf29f7e, 0x53c49738,
- 0x81a4fc0c, 0x8e012378, 0x239c982f, 0x757abbe0, 0xa9d43a67, 0xf30f931d,
- 0xecc11b3c, 0xb551df27, 0xc785207b, 0x47f78365, 0x2e7ae923, 0xb9b2c8af,
- 0xdfa738e8, 0xdf9efdfc, 0xed2fafd3, 0x19cd22f9, 0x0deb57c0, 0xc626832a,
- 0x4896ef5f, 0xbe105b55, 0xc99a233b, 0x09dbccd3, 0x68b804e9, 0xaeb7a87c,
- 0x8027b308, 0xbec567df, 0xe96b84d2, 0xca570df3, 0x9e603b88, 0xfa1fda06,
- 0x4b195c35, 0x8c8243dc, 0xf903c74b, 0x992570d0, 0x3cd862b8, 0x315437c0,
- 0xfbf8ce4c, 0xed1713a7, 0xaa455a7f, 0xe7fbad83, 0xbb5f0cd1, 0xac1f1909,
- 0xd7df077d, 0xfcec7eee, 0x6e4836fa, 0xaf160fb0, 0x14d47930, 0xcfe98ba4,
- 0x362d2fa0, 0x48aa3cbb, 0x8f943fe0, 0x4e34460d, 0x647b5035, 0xf467971e,
- 0xa028cd3b, 0xcf199757, 0xc39f93a1, 0x7defed79, 0xc589fe03, 0x4518621a,
- 0xb06f99c7, 0xbfa14e1d, 0x2638c9ff, 0xc2c4c412, 0x83c4a687, 0xd5984b1c,
- 0xbd2273a8, 0x7e83318d, 0xea51912a, 0xa5ae236f, 0x8f50690f, 0x74a27a45,
- 0xac718ba0, 0x3a00ba04, 0xf5983a04, 0xe26be320, 0x5e7e5cfb, 0x59f87495,
- 0x8ecf7c08, 0xf181cb29, 0x358e512c, 0x5e0fdf48, 0x6ebff192, 0xf3f2fbc9,
- 0x4dcba740, 0xdf4897b6, 0x70e13ffe, 0xd4e829ef, 0x2e5a2c91, 0xea3a47ff,
- 0x9def1da3, 0x675d3e04, 0xa0d47a30, 0x76d6ec57, 0x283ec579, 0xd945060e,
- 0xf073c29f, 0x739651c3, 0x02482694, 0xe3d71dfd, 0x03bf00dc, 0x0363db9d,
- 0x151adce9, 0xeba2740d, 0x10c38bc5, 0x490bc7ef, 0xd1f1c935, 0x31f11471,
- 0x01d760df, 0x1dd817dc, 0x5159beb8, 0x0cb3629e, 0x6feab9fe, 0xf871bf6f,
- 0xf9e7e7af, 0x61d28eb4, 0x83b07390, 0xc31543c3, 0x64e9c6f8, 0xd3a7af46,
- 0x282ef549, 0xf692d107, 0xd78fdd3b, 0x007d790b, 0xd59e2eff, 0x797e700f,
- 0xa77d9f3a, 0x3e33e79c, 0x7b18eccf, 0xf68bc007, 0x4f00e8f3, 0x41b9876f,
- 0xeafca64f, 0x8f13a700, 0x155f9025, 0x1f0006f9, 0xf8a629ec, 0x5759fba2,
- 0x013f4bea, 0xde9f64fc, 0x7d7ac5bc, 0xd7c27dbc, 0x97e59df5, 0xa1afca8d,
- 0x49f5f932, 0x885f9334, 0x1d12ba27, 0x11b2abd3, 0xea17483f, 0x5bcfc71b,
- 0xf4ee0c61, 0x51a3789c, 0x1cf2794e, 0xaffd7c01, 0x8f826e1c, 0xe3970e9c,
- 0xf7f7c5d1, 0xeb473f25, 0xde4ccda3, 0x30e97cd9, 0xe0e8e9ce, 0xc7ed5f78,
- 0x239e3747, 0x0c4e6fbd, 0xa8fbb7a5, 0x442ba0be, 0xf587ac7c, 0x734bb1f4,
- 0x73857f3d, 0x8980f0dc, 0x22bbdc80, 0xa1f22be6, 0x97ca937f, 0x4e8f0674,
- 0x87afd41d, 0x27d1f01f, 0xd4951a51, 0xd5a02274, 0x71c5621c, 0x9e3328c8,
- 0x3e5eb0b3, 0xf38989a2, 0xef3947c3, 0xc8af8e29, 0x0e734918, 0x36236af0,
- 0xa3e737e8, 0x29b34caf, 0x1b325c9d, 0xcf2a2a5c, 0xd19caaae, 0x79efe031,
- 0xbbea28f8, 0x019e74a7, 0xed20c6ad, 0xcf0bcf3a, 0xb9f6fe4a, 0x74bb533f,
- 0xeeef1cf4, 0x74c9faec, 0xa7677fba, 0xd8e706da, 0x1faff2b9, 0xa5bd030c,
- 0x4feb6b53, 0xd7aeae50, 0x991a3ec0, 0x254a767e, 0xefc5ff87, 0xc187edc9,
- 0x540f0c31, 0x133a409f, 0x5854e0fc, 0xeba13e64, 0xfd3c4259, 0x51e7ee81,
- 0xef4a17c3, 0x10f725f2, 0x181627ca, 0x7dfd22a7, 0xe85dc0f1, 0x9c485e6f,
- 0xb9e62fc8, 0xe40c7fb4, 0xcad60ba3, 0xe55a8beb, 0xc9cf25f5, 0xdffebdeb,
- 0x4effb972, 0x98635394, 0x0ba8ba5c, 0x863e3ede, 0x9777e3d1, 0xee5083c7,
- 0xf9c795f6, 0xe395a728, 0xaee5c3de, 0x1e42cb90, 0x84315c37, 0xe388c718,
- 0x7c1c5c5c, 0xf5f1f7fd, 0xa3315c37, 0x3fdbef7c, 0xd53ae516, 0x813bf0c4,
- 0x892b86cf, 0x0ba8bbf8, 0x2fdfd07d, 0x8ca3c715, 0xc22e7cdf, 0xdf85fe7f,
- 0x19efd057, 0xd0921889, 0xfb927b5e, 0xe0f9cc6b, 0xf2033a87, 0x39d9e29d,
- 0xa5edbc8e, 0x48f79c4b, 0x3f4d00d2, 0xf72b7d3f, 0x82e0e941, 0xd59f8037,
- 0x716298c6, 0x3064c1de, 0x73e82bcc, 0x5115c3ce, 0xb0ffdf20, 0x50213cb2,
- 0x6bf5eaff, 0x447d98e8, 0xaf265188, 0xcd9e4288, 0x2bf2a76b, 0x0188f51f,
- 0xef9f9740, 0xb9f4819b, 0x81e2d890, 0xe9f67b6e, 0xf7ffd1d3, 0x5898e51d,
- 0x3cd714cf, 0xa92fd32d, 0x65e7a090, 0x4a7f9f32, 0x5467d307, 0xf516bb06,
- 0x9ab13b15, 0x64a4d1e3, 0x130a96f2, 0x168fad0d, 0x5a1e2075, 0x2337c51f,
- 0xfeba7f41, 0xf324bcd1, 0x9e70899d, 0x1aaf30f4, 0x113b90d8, 0x361196ca,
- 0x9225942b, 0xc1d6c343, 0x34963cf0, 0x2af7c2a6, 0xf4cd5783, 0x7882ba25,
- 0x63e62fe8, 0xafaf1375, 0xce797a9e, 0x68ddf822, 0xe3af73c2, 0xf05578eb,
- 0xc031032f, 0xcf46f5be, 0xe24f1897, 0x8accaba5, 0x1faba876, 0x9c3fbb41,
- 0xd79811b4, 0x82e4bc68, 0x59899acd, 0xf9987a82, 0x0211e7b2, 0x52e8cd7c,
- 0xb6be460d, 0xf49af913, 0x7be062fe, 0x03e68f94, 0xaed90d1f, 0x2efea0f1,
- 0x5f3452f8, 0x4be70b5f, 0x21c18449, 0xbe71d886, 0x23169b1f, 0xae338a5f,
- 0x86ffa090, 0x97c8f1c8, 0xb4f001e2, 0x46bc663d, 0x1ce267c6, 0x95427af2,
- 0x94e49ebc, 0x14e40dd7, 0xe3c903ca, 0x0636fc48, 0xf01c91ed, 0xd8cb683b,
- 0xce1e99f9, 0xeb0dd5d6, 0x1139fba3, 0x937ffaa3, 0xbb7245fb, 0x475a3eb5,
- 0x4f150fd0, 0xa8c1e62d, 0x61889c07, 0x2e67c07a, 0x90fb5768, 0xfee09eff,
- 0x1de3a983, 0xdf8a1a15, 0x07c972fb, 0x8f9e5a76, 0xef869e73, 0xac691c67,
- 0xaaf5a5ab, 0x879e49f7, 0xe6250596, 0x9f14ed9a, 0x6c9b666b, 0x1afad28f,
- 0x576d2313, 0x22f51e9c, 0xb698f202, 0xa225566f, 0xfc01a3ff, 0x6bff74ad,
- 0x3a006f40, 0x5ed04fe8, 0x1ac87aa6, 0x79b7ed03, 0xcebcd99d, 0xdf2a7e0a,
- 0xfa07f058, 0x16f31116, 0x5c3ce412, 0xe28ce7a5, 0x53a845f5, 0xbe9c4a3c,
- 0xe15befc4, 0x2f562cf7, 0x1e760a19, 0x83ab2ffb, 0xcff02832, 0xfddce8e4,
- 0xa51d3d61, 0xcf5a38da, 0x7f43631a, 0x617ce131, 0x9f879898, 0x73fe91bb,
- 0xbc05ed80, 0x64f1dd9e, 0x978c3c45, 0xca7e504b, 0xd62c0dce, 0xca187f4c,
- 0x73c0edcc, 0xfff1077b, 0xfb95e307, 0x8dbc47c7, 0xceef6de1, 0x61d8f166,
- 0x387ecf1a, 0x597923d7, 0x8774cbc0, 0xa511fe54, 0xed8342d7, 0x802b1ee0,
- 0x7d86a1d4, 0xde3f350f, 0x708ff302, 0x7c03147c, 0xf281946c, 0x0cb65a03,
- 0x59ccd9b7, 0xf8156fb8, 0x42b5ba97, 0x40a3d91e, 0x92ad4dae, 0x7d00ff5c,
- 0xe11a8c60, 0xe53197f3, 0x7794d751, 0x3ab22a4d, 0xd6acce50, 0xf3f7fcc9,
- 0x65ff9963, 0xecd8ec5c, 0x2c079458, 0x962837de, 0xdba009f2, 0x7c03921c,
- 0xe71ce022, 0xa55d77c3, 0xce750ebf, 0x9cfcede5, 0xd10fb34f, 0xcfcb3ea2,
- 0x8eabe0bb, 0x669e7670, 0x74069210, 0x22349532, 0xba563dff, 0x7dfbcf14,
- 0x7805a5c4, 0xe0c65a7d, 0x653dd62c, 0x98af5cbc, 0xa7d790e6, 0x0ef52957,
- 0x7fbc7b3a, 0x794e19de, 0x3fa164fb, 0x8feb978e, 0x55cffeb3, 0x84b5ca0b,
- 0xcdbeeb97, 0x54f83f00, 0x03f81c6d, 0xfa33243b, 0x8c243bc1, 0x195434fb,
- 0x6c6fe0dc, 0x5bf16768, 0xefd05ab2, 0x7e80c7bc, 0x31da5653, 0xbedf571e,
- 0x80145a53, 0xb75a94af, 0x207cfc04, 0xc8275185, 0x9c77ae2f, 0x83f7bad0,
- 0x52c4fcbf, 0x9e74e24a, 0xe1df3c83, 0x143be410, 0x34cee9fa, 0x28fff987,
- 0x3c7fa315, 0x03611cd5, 0xaaad79bd, 0x6b85fd10, 0xbf324d23, 0xf655baee,
- 0xf84ef80a, 0xcafe4509, 0x6c693d74, 0x43a7fe63, 0xcc8d8cc8, 0x76e6e43f,
- 0xd32c7672, 0x6afb68cb, 0xce294ff4, 0x410c5c6d, 0x333711b9, 0x5580fd07,
- 0xe045051d, 0x07f2a587, 0xb1d9d3fd, 0xe55fec56, 0xd5ff402c, 0x1819c6dd,
- 0xd8e86817, 0xf46859ac, 0x82c3cfd3, 0x044822ee, 0x5faf5dd0, 0xfd1e9768,
- 0x8e555742, 0xd57d001f, 0x44f93cea, 0x7bf8974e, 0x84b2f928, 0xe65b5de3,
- 0xc288b198, 0x9d03e7a5, 0xaa3bec0d, 0x5ebe2040, 0xfe416bdb, 0x904c99a7,
- 0x252eafcf, 0x367b27c8, 0x17c8bf33, 0x687bea96, 0xb52d590b, 0x8eee1f22,
- 0x5ff08b1e, 0x7a843c66, 0x4a26f548, 0x7e7c014f, 0xbd7956d9, 0xb2fb3086,
- 0xba1f7b76, 0xf8247e44, 0x796efd55, 0xe4cd923f, 0xb9c38db7, 0x42d1f380,
- 0x054a6d87, 0x96cabd2c, 0x6244ecc5, 0xfc5e3e07, 0x0bfb8ebe, 0x85cf9967,
- 0x597b8b01, 0xd41e96ba, 0x66af3a63, 0xcdf198e7, 0x928f3e62, 0xfd73179f,
- 0x9d0d4ee7, 0xcfafd0a7, 0x3f561314, 0x2750eaa4, 0x2debfcaa, 0x1e84fde2,
- 0xc0a9f825, 0x4270e957, 0x3b3a5386, 0x8fddf020, 0xd37c03f4, 0x25ce91f1,
- 0xc68954c8, 0xef605df1, 0x51f3e48c, 0x5d01707a, 0x370654b9, 0xa91aefd0,
- 0x0188e511, 0xae5a65f4, 0x57c89c93, 0xa976a8df, 0x4823de01, 0x327b94e3,
- 0x4676bf81, 0x9d289c00, 0x9fa40e1c, 0xdf49e216, 0x08e8c929, 0xbf2cbbdb,
- 0x82474a0e, 0x653e7bef, 0xba04c0fa, 0x02a71863, 0x3cb40902, 0x3a412d24,
- 0x5a7c6719, 0xad7ffd03, 0x78d3f662, 0xfac0d6e2, 0xfc72cc2a, 0xd7944b8f,
- 0xa1f6b2ef, 0xdbff8c0f, 0xe4273c39, 0x82eddbc8, 0xdf39116f, 0x995724ca,
- 0xe1f8fb7d, 0x8eaec087, 0x10392268, 0x9d1aa3df, 0xf8907fad, 0x2dec4f49,
- 0xc4f7c3f7, 0xf7c3f106, 0xafbeb968, 0xc3faafa0, 0x27ace617, 0xe7143a7e,
- 0xa8d20ee1, 0x9370a44e, 0x8ef161de, 0x28fe803b, 0x90370c3d, 0x486fd05c,
- 0x8973f311, 0x6de821f3, 0xc545af28, 0x20cafa71, 0xa35f4019, 0xbfd0c3db,
- 0x19d00779, 0x3e02dba5, 0x42df90ae, 0xde196f2f, 0xa532ae87, 0x78e3942c,
- 0x1f1c84de, 0x7f9ed922, 0x72f41324, 0x01e5ea17, 0x87131474, 0x11d288fc,
- 0x723ecf9e, 0xa0aede52, 0xe3ef8133, 0x252cdf5c, 0x535f488d, 0x3d2c5655,
- 0x2f4ecc95, 0x40d54e37, 0x3326f7ff, 0x74031b3a, 0xcbdf0598, 0x20dca4e9,
- 0x90e92baf, 0x9c0aa8ce, 0xa1974957, 0xe8032ce8, 0x98c7c84c, 0xa8d9d3eb,
- 0x674e5bb8, 0x826ee2a3, 0xdadf04ce, 0x372e6619, 0x96aedc82, 0xf90c0e50,
- 0xea05bb20, 0x5132eb03, 0xb169dccf, 0x46f6c41d, 0x69d45ed6, 0x42de4357,
- 0x9ede0ad6, 0x7a8728e9, 0xa76d1343, 0x671f1743, 0x2bd90d79, 0xa3c17b59,
- 0xe04d078d, 0xfeb172c7, 0x46b97e6f, 0xdddb491d, 0xd2ff786b, 0x37a872d6,
- 0xbffd65ac, 0x60c87880, 0xb77287c8, 0xadb7efc0, 0xb331b4cf, 0x25b7e994,
- 0xa53bbf7c, 0x5fb1075d, 0xe4b7eb2b, 0xa09c21b0, 0xd6f4ccfd, 0x4b3ef93b,
- 0xc67db136, 0x78f77e7e, 0x458ba52b, 0x5fea173e, 0x43b554e7, 0xb085af91,
- 0xd6a54b3f, 0x51c72854, 0xdda50bb6, 0xeeab5b60, 0x5b61e2c7, 0x714d14e8,
- 0xe2217fcc, 0xaeaf1048, 0x9a67d00c, 0x245d98e2, 0x268f8bbe, 0x8d911fa8,
- 0x4437b426, 0x2cf3cb9c, 0x850ec091, 0x50bf423d, 0x5971af71, 0x8c2fa88d,
- 0x2ef110cb, 0x9d3e66af, 0xafdbe0b7, 0xaff306c6, 0x3d31c734, 0xbf8f3ce5,
- 0xddabdf8b, 0x13bf2e2c, 0xe0192488, 0x7057f87a, 0x3c42775e, 0x1727098b,
- 0x65780e19, 0x727e27f5, 0x6a5add60, 0x35512fbc, 0xcc205c6a, 0x23cc25d2,
- 0x3c49d49a, 0xd77d9151, 0x3c434e3f, 0x8407963a, 0xa2dc5feb, 0xc2203cc3,
- 0xc134d9f9, 0xc7f5469e, 0xe3953df3, 0x4fe0a369, 0xe010c843, 0xde38d34f,
- 0x3d5033ee, 0xab72e518, 0x5e37c156, 0x21b1be40, 0x6f2dfea4, 0x6a95f057,
- 0xae62ef3e, 0x3e252f77, 0x49ce4bd4, 0x6fcf2c6e, 0x8d777a60, 0x35ea38f1,
- 0x9e991b3d, 0xa8bc4b59, 0xcb752cf7, 0x36cd42f9, 0x4daebd79, 0x97686f5e,
- 0x5cf27bd7, 0x86cf4f38, 0x4fe0a1ba, 0x03ee7eab, 0x0b56dff4, 0xf396e2fe,
- 0x32564217, 0x20ecf2fe, 0xed28e7f4, 0xeef76a70, 0xa1f8c38b, 0xe82d6679,
- 0x58227305, 0x98da82be, 0x64c07c87, 0x14383b40, 0x39da501f, 0x8320ef42,
- 0x2a0f9f82, 0xcf000c69, 0xc6777800, 0x921edb5d, 0x21f02bb7, 0x39fb91ec,
- 0x7c50a63e, 0x93bf3cc3, 0x1cf768ec, 0x31f0ca5b, 0xe902b8cd, 0x0c65d3e1,
- 0xba2ec21f, 0xaec83b79, 0x90762efe, 0xce2e5fd2, 0xb09a7755, 0x8768ad4f,
- 0x29800036, 0xf37bae9f, 0x9fa00bc4, 0x358eef8a, 0xc04d3893, 0x2a563c79,
- 0x9e4e8ff7, 0xe4287a70, 0x2b0f6e3b, 0x93e00bfb, 0xffa1c474, 0xd8412eb0,
- 0xe9fc6c45, 0xf2eaff3c, 0xe8a8ccca, 0x89bdd96b, 0x009a619d, 0xc68f6cff,
- 0x4e760917, 0xe70955cf, 0x4825ba85, 0xffdfc91c, 0x87c41878, 0xf9dfcefb,
- 0x3f03dfbd, 0xe302217b, 0x3257977f, 0xa6f2ef7b, 0x7c079881, 0x0549c791,
- 0xde1c961c, 0xce17b6f6, 0x1c31d35b, 0x7f7246af, 0x1db687bd, 0xe2633bd5,
- 0x3caa0e41, 0x2c57463a, 0x1df6219e, 0x42e96fda, 0xc03ba6fe, 0x0a4face4,
- 0xfa4ebcc7, 0xb8c080fb, 0xe302524e, 0x7e0e42c3, 0x2d6afdcc, 0x17d8a5bd,
- 0xc4b42bf3, 0x3d60b3d8, 0xc1bac31f, 0x1691f43f, 0xbbf835f9, 0xa548ce21,
- 0xee89492e, 0xa3881ebb, 0x3881bd6f, 0xc99e2dba, 0xf694a583, 0x62cd3f30,
- 0xcef9802f, 0x79e1b8f3, 0x1f3a771e, 0x2350e2c9, 0x5f1f19e3, 0xe44dfbca,
- 0xf110f9e5, 0xd9ddf16e, 0x35618366, 0x9b1feb5d, 0x36756189, 0xf567f125,
- 0x339f988d, 0x67abed8b, 0x39f305af, 0xf8aabf45, 0x8eb0a5d2, 0x18c71621,
- 0x9eb61728, 0xa9fa05d1, 0xa83f607b, 0xf57db04f, 0xcc52b184, 0xb95f1557,
- 0x3ce01e34, 0xec788bc3, 0x75108fad, 0x33df8e07, 0xc24ff19a, 0xfc7510fd,
- 0x5b8a85fc, 0xa55e2f5d, 0xe6cefb8c, 0xefb889e3, 0x9914362c, 0x73bee3cd,
- 0x0a4d640c, 0x91db9f6d, 0x48d5ecc0, 0xdc5900d7, 0x537115d7, 0x87417771,
- 0xb8fe693d, 0x889bc6e9, 0xfe20fe9b, 0x7f4dc796, 0x6e241f10, 0xbfa78caa,
- 0xb6417a0e, 0x980f0f1f, 0xd42adc19, 0xcfe0e5b5, 0x6090bcbc, 0xe901731e,
- 0xd028ecf7, 0x89688eb3, 0x137c8adb, 0xe1ebe3f5, 0x22a1ce2d, 0x39df9956,
- 0xd603589c, 0x968ce49f, 0x0ee351d5, 0xa94c0fc8, 0x4ff5964e, 0xfb27ec6b,
- 0x9069a33e, 0x55d33dac, 0xad67ab28, 0x7df643bd, 0x5932d6ff, 0x7773e07d,
- 0xcdbfbecb, 0xbf56593d, 0x7e40ff0c, 0x767e46a6, 0x65fbb6fb, 0x1d1c97fd,
- 0xddca7e82, 0x9712fe5c, 0x287733bd, 0xfac0a373, 0xcbe6daf3, 0xc91e23c6,
- 0x45f6d123, 0x23174f1c, 0x85893dd9, 0x3f9fcc9d, 0x6c997db8, 0x2d751afc,
- 0x47194fe2, 0xc3be242c, 0x96ea3f98, 0x37d21e6c, 0x7db4b8ae, 0x9ebbf633,
- 0xfafc227e, 0xb14de207, 0x24c91748, 0x92b3d199, 0x70bd8c1e, 0x05197b80,
- 0xa3b3c064, 0x20f4648a, 0x1b851bc3, 0x6f2ea9fa, 0xd1de6137, 0x700ba392,
- 0x3944fa3d, 0xe559843d, 0x239110f4, 0x4d9307a7, 0xe1a8ff8e, 0xe12bfc72,
- 0xe9cbb16d, 0xffe97881, 0xcc7780d7, 0xfcbd3978, 0x1ddce0ab, 0x1c81e3cf,
- 0xd90e43be, 0x37088c5b, 0xec243f96, 0xa3b73d7b, 0xcfdcac49, 0x7fa7f425,
- 0x1578f3c6, 0xd5f8471f, 0xb42e48d7, 0x66e37bcb, 0x9ee93dc3, 0x1bcfb04c,
- 0x38f3f309, 0x41c50954, 0x7bf884fd, 0x80a13f28, 0x67ae54eb, 0xfa3b10d6,
- 0xfc4117a5, 0x2b67969b, 0x677fa297, 0x1d69f189, 0x9938bff4, 0xc4d563e9,
- 0x7afdfc8d, 0xdc256ff1, 0x01252f40, 0x1c25547e, 0x63c90ea5, 0xe5c33e02,
- 0x10e93240, 0xf2c9c072, 0x12fee5f8, 0x00b2f102, 0x5ef4253e, 0x9f80be31,
- 0x7c625fe0, 0xe059f83d, 0x19f8281c, 0x45e391c9, 0x63815fe9, 0x181a1860,
- 0xc092b12f, 0xafd28af8, 0x50a7f7e2, 0xa7ce92bb, 0x216cc8ce, 0xcc436f14,
- 0x15d7f476, 0xf099ce93, 0xa0a7f0bb, 0xd236e17f, 0x29085feb, 0x8f13ae9f,
- 0xbc92e29d, 0x8df667cf, 0x2eb88ac3, 0xbfe7c305, 0x49479da7, 0xe4f7c456,
- 0x01c60737, 0x2ff5f51d, 0x45be4eda, 0x7cab51c7, 0x3f7e8131, 0x4f7f5fe1,
- 0xee7ee2f2, 0x48c7f623, 0x4f519e80, 0xcccec6da, 0x952eff04, 0x3250918b,
- 0x5769143f, 0xf41ad9ea, 0x4ee8aaff, 0x486bde80, 0xd3329c40, 0x75758edf,
- 0xe68dfadf, 0xc13afcbb, 0x2cbd9dcc, 0xfe70935f, 0xd0c3ec27, 0x7d7c98f6,
- 0x330b8c0b, 0x82fbfa25, 0xc0dc75c0, 0x037e453a, 0x7884e3dc, 0x9f2a26c6,
- 0xb04bcf51, 0x17515ea2, 0x3b13ea7e, 0x99d4567c, 0x36d7a81e, 0x0301a8e8,
- 0x7aebf8f6, 0x936c9716, 0x4c3fcbeb, 0xa12ef960, 0xa8f3c0e1, 0xf5cc7614,
- 0x47911df4, 0x16e01135, 0x944b3eb0, 0x9f803fe3, 0x9ef49da4, 0xfefe5493,
- 0xcc2eea15, 0xaedcbc13, 0xf54efbc6, 0x1fc85da3, 0xf1aaf7ea, 0xe8777508,
- 0x756f3ef1, 0x93d441fb, 0x03299aba, 0x85c97aa2, 0xe6b33a66, 0xec57f01a,
- 0x207d9437, 0x4c5e8df2, 0x9f33fce0, 0x2be607e4, 0x8af83e51, 0xdaf60f8c,
- 0x4a79bdad, 0x93e304af, 0x28dcea15, 0x9bdae7b8, 0xa5f1a287, 0x8fc00e4f,
- 0x720f1f72, 0x1a37e43b, 0x5d025b47, 0xd4ce99d7, 0x0abc6067, 0x64e1c775,
- 0xc90acf80, 0x12b47106, 0xa87fbb3d, 0x35b72f57, 0x0375d806, 0x203b521f,
- 0xc57a795e, 0xbf70d183, 0x503b8c59, 0x393de152, 0xf67d7642, 0x9f8822fd,
- 0xa3adb2cd, 0x667ad9b5, 0x2f7e6657, 0xcf4593c2, 0x763a3bd7, 0xafdb4b3f,
- 0x7dfef311, 0xe3fa3516, 0x0c64d562, 0xaf5885d0, 0x7e2857b8, 0x70cefb87,
- 0x5efc4d7f, 0xf21be2d2, 0x071f2d00, 0xaff62cfa, 0x37dca4af, 0x87e8d1a4,
- 0x6e9c7d7b, 0xdd45e80d, 0x443f2606, 0x6b31159e, 0x30ad7cf0, 0xaa75f3b0,
- 0x3d9bb0bf, 0xeabfb026, 0x9851ecc3, 0x9a91f5e7, 0x17f95d80, 0x82ca3db3,
- 0xdea2b3fb, 0xfaccc2b9, 0xde7cf375, 0xa1969f15, 0x12d7165d, 0x7ce8cf3c,
- 0x6a9fb302, 0x7964a8af, 0x0f1ab546, 0x5ed50be6, 0x913e61d1, 0x148ffdf8,
- 0xfe01ae0e, 0xd9f3fcfa, 0x0b5d6163, 0x7c0d6d88, 0x046d60bf, 0x21e80571,
- 0x8958af22, 0x7c71efff, 0x44345bd7, 0xe7ef1833, 0xddf5ae3a, 0x0754ff5b,
- 0x9d12efbd, 0x5c71cec8, 0xa5ebcb39, 0xe1c60576, 0x2585df94, 0x6cfc8a4a,
- 0xecafde2f, 0x5bdb07cd, 0x61ae409a, 0xb15fd7e7, 0xebb3f2cb, 0x57e87f69,
- 0x228c657f, 0x4b8f9b3f, 0xfd1ab3c7, 0xe0a16079, 0x6604bdff, 0x9e43d4df,
- 0xdfc090d7, 0xe7f8fd19, 0x5b79e589, 0x7f3848de, 0xe3576f3f, 0x1f9fe3fd,
- 0x12df8d51, 0x12c3dd64, 0xc506dc19, 0xdc5cf069, 0xcdf621ee, 0xdf17e641,
- 0xe205fb89, 0x7d729c7e, 0x73bccbbb, 0xc6c3fd60, 0x72aeff30, 0xec89419c,
- 0xddeeb13b, 0xf51f0cd1, 0x607c536f, 0x9fcb08fe, 0x5ded1ddd, 0x2cc0fc8c,
- 0x8e7cf3c7, 0x7b77dde7, 0xcbbef1d3, 0x0e7ecc5d, 0xcd570f45, 0x4f8007ce,
- 0x42374ed4, 0xaa19192e, 0x01cc9469, 0xf47aebe7, 0x4abb87e0, 0x70bed786,
- 0xc57e21d7, 0xffdf42b8, 0xc63539f2, 0xc63cbff1, 0x1bb12dcf, 0xf77c80a5,
- 0xebf3092f, 0xa12ad97f, 0x49df3f9e, 0x2fe51348, 0xa0d6b6f3, 0xa5f8b85e,
- 0x03629821, 0x7ca4afbf, 0x21225e64, 0xfe72d277, 0x775c796a, 0x7e3efae1,
- 0x7f281239, 0x94469117, 0x969f8b17, 0xeb26abf7, 0x837a0cff, 0x3e8cde32,
- 0xcf176a4f, 0xf77ae44e, 0xf8143250, 0x7d2f03fd, 0x86b48ba5, 0x94f3ffa6,
- 0x806b669f, 0xecb01aaf, 0xb963366a, 0x28bed13c, 0x39a5c291, 0x089d59d1,
- 0x188f8cfe, 0x5ed72e3c, 0x2e00f266, 0x7e008e4f, 0xd33ca12d, 0xd8f164cf,
- 0x723dc21f, 0x9ebd0f0a, 0xd47575c9, 0x7093c9ca, 0xff846e95, 0x8e79af30,
- 0x2d8de505, 0xf63de811, 0x63c6e317, 0x222fd75e, 0x75bf00ec, 0xc197eea5,
- 0x556eb08f, 0x0d71fa38, 0xce0f167a, 0x82aa5eda, 0xedb703fb, 0x1f83f696,
- 0x5563a1a3, 0x37efdc0e, 0x8f31c35a, 0x5e63aa20, 0x6c639326, 0xc716d89e,
- 0x2c67c04e, 0xeba36bdc, 0x4ee9975a, 0xe99a7c64, 0xf61cf539, 0x3ff5923d,
- 0xebb39ee1, 0x21ef1aa8, 0xbcb0d65e, 0xe18441fa, 0xc12be455, 0x5cfa81dc,
- 0x241b8517, 0x939ef5d5, 0x8da3c936, 0x301c77c4, 0xa8fb50ce, 0xc8267e27,
- 0x30699f9b, 0xaebbd34e, 0x20ca9277, 0xcce4231e, 0xfcccc94c, 0x9d5f5c42,
- 0x2c7fc441, 0xe9c5539e, 0x53d70661, 0xf8304667, 0x74b627ce, 0x81bf77e8,
- 0xd1e8aa44, 0x56de5999, 0xd1abfb8c, 0x116f405a, 0x7ad08971, 0x4e7f7042,
- 0x7626cbfd, 0x0df2521f, 0x682e4180, 0x79d6b909, 0x43f9c3db, 0x97e600fd,
- 0x0ec4d925, 0xb7fab071, 0xf8866e07, 0xc59c3e87, 0x321f2959, 0xef277bc0,
- 0xfba63c82, 0x1856fa5e, 0xdc42bf7b, 0x0bdb3687, 0xc3617ee0, 0xcc42d4e4,
- 0xc3e9385f, 0xb5ba0877, 0xaf3c74de, 0x5448bf94, 0x38987e06, 0xa50d1eef,
- 0xaa64faf3, 0x3ffad16f, 0xbd581b12, 0x8ab1779f, 0x3d2407d6, 0xbc83eace,
- 0x4b6ea0e7, 0x0d1efa7a, 0xf42b63dc, 0xfad3562e, 0xac2da484, 0x324b060e,
- 0xcfd26f85, 0xf1d171ee, 0x3eb8582f, 0x3de2f363, 0x0737fad0, 0x84fd02aa,
- 0x7f189263, 0xbec610ba, 0xe64990bb, 0xe778064e, 0x873eff04, 0x5cf42f7f,
- 0x9fd15fb1, 0xf7ef0624, 0x4b7b9719, 0x92d03df9, 0x8c36b208, 0x915c95c5,
- 0x3a870f14, 0xec5c6206, 0xcb346240, 0xf17b35df, 0x8e31109d, 0x4f18a780,
- 0xe40cbbcc, 0xc9f311b0, 0xe2f964aa, 0x79d27e5c, 0xd93ce356, 0x727f7676,
- 0xe0016a72, 0xc34de28f, 0xbc01a6f1, 0x30d77b89, 0xf91f25ae, 0x43f010fd,
- 0xbf4aba1f, 0x5baff4cf, 0x38572749, 0x616d2c9d, 0x259f40f1, 0x24a9e90b,
- 0x513bbf82, 0x04c7df24, 0x4931bf0e, 0x5ecfb616, 0x384824bc, 0x63870b4f,
- 0xe4c077aa, 0x77df9bbc, 0xcf5b1278, 0x0077dead, 0x7ef0ecbe, 0xdbf6a1c4,
- 0x30fdb0b6, 0x473d017c, 0xa4f75ea3, 0xab0bbc6c, 0xd387fd14, 0x8dfb0903,
- 0x3ffec2ce, 0x100defe4, 0x5fb7a5b2, 0x3fd33e66, 0xf7152f41, 0x4eeb89e4,
- 0xed17e812, 0xc6df0fbd, 0xf7faadee, 0xdf114f79, 0xd3ef99a7, 0x96e9f6cc,
- 0xee392bd1, 0xea6a9f4b, 0xf0bdc74b, 0xb72f1def, 0x3b278f90, 0x83c6c1e7,
- 0x2f0a1d73, 0x316e93a3, 0x2a758a3d, 0x670bd9e0, 0x3c04fac5, 0xbf637ce1,
- 0x8a5d395c, 0x9d42da75, 0x38efccef, 0x57eb295f, 0xbfcb30f7, 0x5d395625,
- 0x54ceedd7, 0xf45bdc41, 0xee3e0a3b, 0xcb5fbf38, 0x98e3c499, 0x443524a9,
- 0xa4c2dcde, 0x30fea0b8, 0xe7695dfc, 0x3e5858f5, 0xefded2b2, 0xc275b389,
- 0x25d7343d, 0xa47a7f76, 0x71013fc2, 0x7f465d92, 0x917cbf3f, 0xf87177d7,
- 0xf8aff5f5, 0x91677ef0, 0xab35ecbe, 0x9bff908d, 0xebf20ef4, 0x07b2a8a2,
- 0xf57d6933, 0xdfc8fd86, 0xbeca528b, 0x7cfca4ca, 0xac0386cd, 0xafb2f6fd,
- 0xe93d41fa, 0xd897ab20, 0x4f7e035f, 0xc67bc1c8, 0x88f5f924, 0x7159261f,
- 0x0ab9755e, 0xd5eadfdf, 0xa3d1de5f, 0x1ae022fe, 0xabd22caa, 0x9fc5831a,
- 0x81e97b5a, 0xc38609c5, 0xa790ad3f, 0xaf78edc4, 0xf7c76646, 0xaffbb244,
- 0x86fefb3d, 0x4f9e19f7, 0xf004fe72, 0x35d110d0, 0x1fd69327, 0xe30cf88d,
- 0xea9d9250, 0xb0c7e021, 0xba2cc99a, 0x9d6ba95e, 0xb225f403, 0x20d066cc,
- 0x075fb95c, 0xf0a2f4de, 0x9fedeb7b, 0xa6c2923d, 0x463ac071, 0xf0d03e70,
- 0x435f37f6, 0x82e1b2dc, 0xe1ea06d1, 0x0f0d8e88, 0xa235be82, 0x30dfd7e3,
- 0x5feecc39, 0x008f7588, 0x7dfd1dbf, 0xd71ebb78, 0xb6e3a23f, 0xc8fdf045,
- 0x016476df, 0xe53e8c9d, 0xd0b60169, 0x148defb3, 0x2fcdfdf9, 0x186f99ae,
- 0xe0248e32, 0x54aa27f1, 0xde3c2145, 0x8ab8f060, 0x71dd51f9, 0xd178d6c7,
- 0xdfbf27b9, 0x8c76f542, 0xe1265e83, 0x8bd3f036, 0x7f4ac57b, 0xba4ac9e0,
- 0x68fbfa3f, 0x80415d1f, 0x85725cde, 0x7a01ffda, 0xc8b12978, 0x2486e5ea,
- 0xe615f7d9, 0xb8fb594c, 0xed64dbc4, 0x640b5977, 0x233909f5, 0xb44fdf64,
- 0xf7eaca95, 0xf64bbf0e, 0x52bda57d, 0xb4f02f56, 0x721fbec9, 0x7ede5da4,
- 0x0f01a89c, 0x076d2785, 0x6b3e2ca1, 0xd0e2b747, 0xa1078df3, 0x0617f11c,
- 0xf43fa50e, 0x076d2b8e, 0x0fe177e1, 0x1157de55, 0x6ae9d1fe, 0xdc175ba3,
- 0xa1a89a0f, 0x8bc925e5, 0x62ad44fc, 0x305e55f7, 0x6f01bb39, 0x094abee2,
- 0x122943f8, 0x625ee62a, 0x3167b2f7, 0x4049d87f, 0x19a7f00c, 0x9de3f426,
- 0xfabe36d4, 0x4ec7167b, 0xda37be03, 0x77db2557, 0x6ca715c9, 0xa964a5df,
- 0x65cb4f02, 0xc3f30af5, 0x25c7efb2, 0xdfb592ae, 0x815c7d65, 0xf56527a7,
- 0x0a0db689, 0xe0566d3c, 0x76b267e9, 0xdc1ddf41, 0xf836f53f, 0xca396895,
- 0x780e59db, 0x0fbcf3b8, 0xb3bc31f1, 0x74f01cb5, 0xc436c9c7, 0x51c79157,
- 0xe872ec0e, 0x5083c691, 0x05fda87a, 0x27340efd, 0xd9a87962, 0xc3a9fe8a,
- 0x1e5839cd, 0xefe1b669, 0x8e1e6abf, 0x76cdfbe5, 0x3cd37f2c, 0x66cecb1e,
- 0xcd6d9607, 0xaefdf86d, 0xdfe676e6, 0xd7bde98a, 0x807e069f, 0x1eb7956e,
- 0x27643eee, 0x7e044ec7, 0xedee1dd9, 0xaea3fa86, 0x2fc089e8, 0xa1130007,
- 0xcbcf9c78, 0x3df629b1, 0x0dbf94c9, 0x91756649, 0xb2a6d057, 0x5e1e8017,
- 0x09e331b2, 0x8f211a4d, 0x9a2472ad, 0xa06eac2d, 0xe6364475, 0x613c655b,
- 0x55e4254f, 0x60772510, 0x7bd4227d, 0x90fb58c2, 0x4113198d, 0xf1ceff0f,
- 0xbc9f7b60, 0x20e492c0, 0xcf57e0f1, 0xbfe04d5b, 0xa0757639, 0x8c71e009,
- 0xa4ecb1fb, 0x968f3b40, 0x2d029aa5, 0x0a93d9c8, 0x3d9444bd, 0xc9f1d2aa,
- 0xdb6fb071, 0xbe43cc34, 0x7e804b5b, 0xdecc4b27, 0x4ff5df15, 0x1317f9e1,
- 0x1d4f68f5, 0x6117d957, 0x7be493de, 0x64bce001, 0x7b8410e3, 0x0e97c98f,
- 0xb1b45bf0, 0x7ce3d590, 0x80b6482f, 0x67c196ba, 0x8982c6fa, 0x0a5bdcae,
- 0xe0c1059f, 0x666c9d53, 0x9ec7b6fa, 0xa8807a06, 0xd7b4af1f, 0x5e3e79c1,
- 0xa2fbc76a, 0x767a1cc7, 0xbc261d7e, 0xf63440e7, 0xfe0169e2, 0x5ac9b39c,
- 0x2e1537ec, 0xf35f819e, 0x739e357e, 0x29553c25, 0x3a470f4c, 0x46733b01,
- 0xc705da04, 0xb7deec55, 0x14ccfbf2, 0x0c5d1f66, 0xeb77ee0f, 0xa6cbdbc7,
- 0x87babdd4, 0x22b3d78e, 0x71ee870c, 0xac7d440c, 0x7bc251a7, 0x1be73db5,
- 0xbd76b12f, 0xe304838d, 0x5fe13392, 0x8ed5fdb4, 0x31faff07, 0x15b3fefd,
- 0x21943611, 0xbf0841e6, 0xb3c7f9fb, 0x3fa80c63, 0x569c9ecd, 0x26717206,
- 0x31cd738f, 0xdc31e269, 0xe0e8b1a5, 0xc685ba09, 0x82143582, 0xa56c7164,
- 0xa9cc9e0e, 0x06be5d4e, 0x4fd965ca, 0xf0ada2ea, 0x35ced77e, 0xd1d6c6a0,
- 0xfc8c5c23, 0x3341fbcf, 0x26dcd75d, 0x73d995b5, 0x6bdaae5c, 0x433f2a6e,
- 0x9e71efd0, 0x8081432f, 0x87166af6, 0xc597e8b7, 0x325b74e9, 0x91e4138f,
- 0xa7df763c, 0x1db00e37, 0xf66ba4e8, 0xc4420307, 0x5cede409, 0xc744fc7f,
- 0xbbbe55e6, 0x4ecde620, 0x71fe7a61, 0xd04ca51d, 0x7267ef27, 0xabeabf20,
- 0xfee98b47, 0x2acc3bf3, 0xadcfc38c, 0xb87803db, 0xa8f1cedc, 0x9e70ed25,
- 0x7de6b8a6, 0x8a4ab986, 0x93d79a7b, 0x734eb697, 0x2cbca079, 0x03ca3af2,
- 0x5f70e5e5, 0x45c8396b, 0x7c451f21, 0xcd5cd3d0, 0xf22372f9, 0x4dcd43d3,
- 0xecdc3f58, 0xf348f2c2, 0x5b97ce5a, 0xe6fdfdb1, 0x765f38e7, 0x0dbcbe73,
- 0xae68ef7f, 0x66edf2c2, 0x28969627, 0x7e016fc7, 0xcc4e0d53, 0x83777bef,
- 0xeb7c409e, 0xf31e8772, 0x7889e80e, 0xc858f9e1, 0xbde3d1a7, 0x8d5e653b,
- 0xd2f7cf92, 0x25f7df43, 0xf4f300fe, 0xbe80c3e6, 0x9e9a1198, 0x09ab118e,
- 0x92dfd2f8, 0xbe82269b, 0x356acc7d, 0x657d3e81, 0xa5f21363, 0x49ab7663,
- 0x24dfeb4b, 0x9ddacc3f, 0xd69e9356, 0xc3e37bff, 0x3565ddac, 0xdffad185,
- 0xeacfbf93, 0xc482c26e, 0xe7c8cd29, 0x0874894b, 0x21b947ce, 0x17150c73,
- 0x1e975e54, 0x2e317382, 0x3818de71, 0x56c97517, 0xacbb8fa4, 0x7d410eab,
- 0x0d66ce42, 0x1bb6c55c, 0xbf43560b, 0x0d4ad8b2, 0xba931bf4, 0x1bf4357c,
- 0x26a4fd9b, 0xdcf8dfb0, 0x7ea1ab9d, 0x06b36d8f, 0xce3ad3f4, 0xa238c4c7,
- 0x9f05da2e, 0x835e7916, 0x0f281c3b, 0x281ddbf2, 0xca5c040f, 0x063e56a6,
- 0x7686c77e, 0x3ac12cc9, 0xc1bd4aa6, 0xab91c86f, 0x291af787, 0xfe7a8ebf,
- 0xba2ad309, 0xdfa806cf, 0x5627f581, 0x9dfe5add, 0x97d71292, 0xe7e09f7f,
- 0xe43de41d, 0xb1d09f65, 0x001e32f7, 0x7de314b8, 0x2bbe1334, 0xd0269c49,
- 0x3cb89ab3, 0x6d25095f, 0x3bebcedf, 0xd9579c85, 0xdfd0a7fb, 0x7db85373,
- 0xd83f97d9, 0xfcf41d60, 0x8439ee2b, 0xa1fce768, 0x7b2cc530, 0xb08ea15f,
- 0xcbd7557b, 0x31e6531b, 0x9629f32b, 0xf6c3b691, 0x1479becc, 0xc7bd84b5,
- 0xae4fcca2, 0xad5eec27, 0xd7b94f32, 0xfc670aae, 0x0d780ab4, 0x2989e3a5,
- 0x6564f921, 0xe135f14a, 0x910f6f20, 0xb094bd97, 0xf93eec3c, 0x5b1f3c35,
- 0x8ce22fb9, 0xf25def63, 0xfee56cfc, 0xddf45d04, 0xbf832b5f, 0xea9fc186,
- 0x7d600b77, 0x044d7315, 0xfc8156fc, 0xf06be3e7, 0xbb3f251f, 0xfa727c55,
- 0x9f763adc, 0x6b1f2fbf, 0xc7c2094a, 0xb2975e44, 0xdc2a7a14, 0x3efc831b,
- 0xec060f78, 0x9c123bfc, 0x3d97402d, 0x55afbe65, 0xb2c68760, 0x2dbb93f7,
- 0xbbf035ce, 0x03f963a4, 0xbcf6af22, 0xd04bf5ca, 0xf94a9edb, 0x6ebbf215,
- 0x8cf41610, 0xe075a3ac, 0x8e2c4367, 0xe48fd0f5, 0xef817578, 0x1fca8730,
- 0xe1cb9a7d, 0xe59125be, 0xfe6cf655, 0x0fde86e6, 0x0a8f050a, 0xdc2f28f5,
- 0x3c3cb85f, 0x9767e502, 0xfef03c44, 0x3c69576b, 0x695d2dea, 0xb7940d3a,
- 0x4aee2eda, 0x2be3801b, 0xa4aee3ed, 0xef3606e1, 0xfe50f1d8, 0x115ce926,
- 0x790fbdc8, 0xcebb613e, 0xe037e435, 0x86111e1f, 0x257bfa71, 0x41c0116f,
- 0x1d775769, 0xcd66559d, 0xd35f6bef, 0xfd818dfd, 0x3d519ed5, 0xacddbf06,
- 0xf4db5dbd, 0xed3c8135, 0x09574d91, 0xbcdf8fe4, 0x9d19ddfd, 0xc2bd056f,
- 0x322402d9, 0x13ea8bac, 0xfcbd7eb4, 0xb5124ba4, 0xec0333d3, 0x66bfe1f2,
- 0x54bc4a79, 0xde7de7da, 0x92e65b4b, 0x7a95c3e7, 0x44df318a, 0xfbc48ded,
- 0x9ef62aaa, 0x7a57c882, 0xd4f3db8f, 0x829b3f5e, 0x74ceb87e, 0xfdfebd99,
- 0x823ce74f, 0xf30c207c, 0xff6d5e33, 0xfad60e3c, 0x9fb8ce87, 0xd3f565bc,
- 0x6bf98377, 0x5f679812, 0x565974db, 0xed7ee2ef, 0x2fbb2d56, 0x354ffb54,
- 0xc72a25ca, 0xc89e22d6, 0x0103dd01, 0xfdb495f2, 0x83de17b9, 0x04abbf29,
- 0x1d7ca180, 0xfb4ec939, 0x887b7255, 0x9d587790, 0x95c48fdb, 0xe271eac2,
- 0x7ab31ffb, 0xa9fef89a, 0x4f3a7649, 0xe7689265, 0x75e36ffd, 0x33d58797,
- 0x647ff7c5, 0xbb589bdf, 0x498ed37e, 0x3f05ce70, 0xdfcaa537, 0xddfca201,
- 0xcd7c5a92, 0x3b791a7c, 0xdde2ffe7, 0xdfef8a9f, 0x9c01f115, 0x730936d3,
- 0x6a576ae7, 0x317f5fd1, 0xf03f2dba, 0x7791507d, 0x613728e3, 0xebdd541e,
- 0x0b80b703, 0x1e3a6d53, 0x44ca7a0f, 0xa154ff9e, 0xe59c6236, 0xc7c67af2,
- 0x8b79e943, 0xe194de9b, 0x7f3b4fab, 0x9103178f, 0x4f4bbe74, 0x90f7b024,
- 0xee313bb3, 0xe995383f, 0x22bef0f1, 0xf915e7dc, 0xc459b15c, 0xec71f60e,
- 0x5dec611b, 0xc89db3c8, 0xc1bf175f, 0x1b75d7fc, 0x9b3ca20e, 0xffa2b6af,
- 0x673f5c68, 0x47c42a71, 0x30039d4c, 0x36f4ddee, 0x673fc39e, 0xcb9c7998,
- 0xcf081b97, 0x5fe17dd1, 0x97f81d7a, 0xbfe13bfe, 0x180dea9b, 0x8613dae7,
- 0xc6826cf6, 0x1c41b3ab, 0x577b24f3, 0xdb872172, 0xe23fced0, 0x7887ff7d,
- 0xc59daa3d, 0x959e4469, 0x54a1f798, 0x8f038313, 0x7e4dd487, 0x43c4147f,
- 0x224afe04, 0xb7f81b48, 0x1c6c1e29, 0x83c0360f, 0x2e3fb780, 0x0665fb42,
- 0xbd956b8e, 0x1ee02b5f, 0xe92b1cea, 0x195bac43, 0x3c665827, 0x5df80c54,
- 0x81799376, 0xbe38d297, 0xfbcc5e35, 0x410673fb, 0xb8f028b9, 0x5dde2fb2,
- 0xc4d771a9, 0x5ffdbcbb, 0xdc25778c, 0x8f2d6594, 0x7f7f297b, 0x2ff55521,
- 0x36ffe385, 0xc6ecea7f, 0xb9f6b2fd, 0xc86f474d, 0xa0fc2adf, 0xabbf2eff,
- 0x7a4eb7f0, 0xe20a896d, 0x7c7b4a32, 0x6be3ba5a, 0xdf7bbfa0, 0x09ee47fc,
- 0x00f57c58, 0x90793fcc, 0x51abe5ef, 0x11ecfb7f, 0x355f4f4a, 0xa9d43f32,
- 0xad6a5ffd, 0x63e97d79, 0xb11515f6, 0xecd5d007, 0x20b48fa6, 0xcd5366af,
- 0xea3c5822, 0x309e9cef, 0x81f2847f, 0xc6d1032a, 0x555ff3d2, 0xae73dec5,
- 0x344bc082, 0x6d271e96, 0x1e21a49f, 0xd2b5af78, 0x31e8f1a8, 0xb7bf241e,
- 0xb9efe7aa, 0x7652c352, 0x576d557f, 0xb4d37e63, 0x748e2ce1, 0xef0db1bf,
- 0xf238ce25, 0x6847a5e8, 0x2aed593b, 0xe2b77966, 0x54efd19e, 0xfa1f1337,
- 0x7e612a7b, 0x1dc78954, 0xee316b97, 0x61f7eca8, 0x4d63f32a, 0xbf2c4b52,
- 0x4fcb2f60, 0xee91e713, 0x90be88ef, 0xbbc3c1e5, 0x5a8d95a6, 0xd07cc0cf,
- 0xfea3f63f, 0x557c30d1, 0x61afe03e, 0x9f46748c, 0x1b03d7ef, 0xfd82fe9a,
- 0x5958fc95, 0xe9dfa8de, 0x4823e6b3, 0x3c5f422f, 0xbac1ecd5, 0xab350fd2,
- 0x6e303fe4, 0xee2fe233, 0x5e472816, 0x66189fb5, 0x95f6eefd, 0x9d84abb0,
- 0x04dbb4a5, 0xb5ef10bf, 0xc3fc140d, 0x777b11f0, 0xbccac351, 0x15ff3934,
- 0xd9f2957c, 0x7f8c3482, 0x006ff9ca, 0x7ff6c61f, 0xd3f61f17, 0xfc0da37d,
- 0xeca95535, 0xdd25737d, 0xf93226d7, 0x7577a4a9, 0x19f51ab9, 0x3a0bbd25,
- 0x19becfbf, 0x20b375fd, 0x31d74f56, 0xfbc241ab, 0xff5f2752, 0xba0643e1,
- 0xa7b6ae84, 0xe8f7b2b4, 0xfbee926e, 0xe9b381ca, 0x9677df30, 0x9c33a403,
- 0xf8665bdd, 0x47d69458, 0xbb4d2e8e, 0xb7951cb6, 0x17f18bff, 0xbe73ff64,
- 0xca241c9b, 0xd473057b, 0xd39f362a, 0x213ef2c8, 0xcdc7acef, 0x675579ee,
- 0xd37be2b6, 0x122fb864, 0x7dd2c8f8, 0xc58eb26a, 0x01493437, 0x117508ef,
- 0xe92327cf, 0xb1464bef, 0xf9943877, 0x4f3cf598, 0x37719973, 0xbe5213de,
- 0x3df22407, 0xca78f9eb, 0x7f448177, 0xf9582f71, 0x34c6d02e, 0x90ad7f7e,
- 0xf838b214, 0x3753f9b5, 0xff00c9c8, 0x66d5f770, 0xa4b673b4, 0xae47f1fd,
- 0x6f3c7e51, 0x3e7ee34b, 0xbf6c5d3f, 0xff6c5d0e, 0x6a1749ff, 0xef7c56d3,
- 0xe2e966e3, 0x3f7dab11, 0x8f9c5bac, 0x96fc73de, 0x78b1cf1e, 0xf967b80f,
- 0x471ef8ab, 0xe30437cf, 0xc3f3d740, 0x6bb17494, 0xbacfa33d, 0xaf144c5b,
- 0xd0b94f23, 0xb8e2303f, 0x0dbfef13, 0x990edf7b, 0x90e0a4c6, 0x16eb0d43,
- 0x1bd0827a, 0xdf80fcfc, 0x1d79e153, 0x6e37ca37, 0xaff1be36, 0xfb886b8a,
- 0x4f5add32, 0xdb9009f1, 0xbe82c37b, 0x8d257d97, 0xef50edc9, 0x9ca25a6e,
- 0x534f0057, 0xef15df38, 0xd9a8566f, 0x3b97b93b, 0x589fe8d5, 0xfedf83f1,
- 0xdf6b79f2, 0x58fa95f1, 0x5072f983, 0x0d9446fb, 0x5f2f962a, 0xbcc56e58,
- 0xc07bb02c, 0x17fc215f, 0x5847efca, 0xd1d3c2cb, 0x69d51ede, 0xc73cf587,
- 0x5f0a13d6, 0x123e4d0d, 0xa87ceef8, 0x15f61bf9, 0x9c07e79b, 0xbde9098f,
- 0x9cf99676, 0x1bef8fc1, 0x6dff8ba5, 0x3524fffa, 0xfe544971, 0xa66e49e6,
- 0x57a6124f, 0x589d22ce, 0x2c3e21ce, 0x4fe5849d, 0x2c3627cf, 0xaef61217,
- 0x670ca1f9, 0x8de83a49, 0x0fbe1f5a, 0xbff5e97b, 0x4cfbe2e7, 0x856c8e77,
- 0xe55ba89c, 0x55ea56b7, 0x8fbe053d, 0xd8ff03a7, 0x2b74f7f3, 0x7b1bffca,
- 0x94507aa7, 0x107a4a7d, 0x4a6ff6bf, 0xc4beecd5, 0x5e5107c9, 0x1f599a54,
- 0xfdf98632, 0xe2642627, 0xcdf3f1f9, 0x6f82cd84, 0xef2afc42, 0xdfc58a8c,
- 0x77f84a97, 0x2abdda79, 0x8b79623c, 0xa86add32, 0x79ed66ef, 0x44b71675,
- 0xc22379eb, 0x8b72fb58, 0x67ddf21b, 0xcb9e2f13, 0xaeed90b9, 0xbd13bff6,
- 0x7bf9d880, 0x127ebe06, 0xc3a8bfed, 0x89b6f2c0, 0x9bf61b37, 0x1049760f,
- 0xe997f73b, 0xee0fbcec, 0xe0fdf8c7, 0xe15fb932, 0x267ede21, 0xe013aca3,
- 0xfb74bbf1, 0x0d7ce0f7, 0xf75cee8e, 0x53f81154, 0xc2fc0454, 0x18788c5f,
- 0x5fa228e3, 0x11ecb598, 0xc4876ef8, 0xfb5d8bf2, 0xd2dde2f4, 0xfc7f40f8,
- 0x55f28ca1, 0x74daddf0, 0xc1429fc6, 0x942efe15, 0x261d8823, 0x8306d5f2,
- 0x427e886e, 0xed06ef82, 0x437d5890, 0x577bd8fa, 0xe977d11b, 0xcc33fd02,
- 0xec31fcea, 0x108eb063, 0xbfffac23, 0xd219bdf8, 0xef710e98, 0x55e82f25,
- 0x4a7c5fa0, 0x27dc31c5, 0x63b53df8, 0xed4d3ca1, 0x40ff2851, 0xcf2851ed,
- 0xca147b50, 0x0a3da9cf, 0x362ba2e5, 0x14971c78, 0xce7fd867, 0xbbf83ce8,
- 0x33a62f1b, 0xc32679b9, 0xc75b29d9, 0x63ae1d3e, 0xc7f3a587, 0xec75d14f,
- 0x82ad93d8, 0xe0a12cfb, 0x6fefb3d1, 0xf820cee9, 0x93dfcdec, 0x6ccbe782,
- 0xefe7f3e4, 0xcfdca0d6, 0x2e46f76f, 0x3daef80e, 0xc878875d, 0x123673db,
- 0xf736efc6, 0xd12ed5c2, 0xb1524ead, 0x330bfb7a, 0x0b9d5def, 0x0277b0fb,
- 0xeef9e8fe, 0xfdbf3280, 0xfb863fb7, 0x8c7c741b, 0xbe48f6c7, 0x532f4067,
- 0x6fb943ee, 0xffba2fb1, 0xc77fd075, 0x13b07e9e, 0x3b086fca, 0xfbd8fb2f,
- 0xbbf77db8, 0xaf7bd70a, 0xf70457de, 0x56fdee12, 0xf41f341d, 0xc229464c,
- 0x99d056bb, 0xba71b788, 0xaefaf812, 0x1e395ae7, 0x0017ef11, 0x3c82b50f,
- 0xfa091aba, 0x5b8f2560, 0xfeceefb6, 0x1cb9ef10, 0x3bf81351, 0xe5a38381,
- 0xc19d4ee7, 0xf3289dce, 0x801ce9f6, 0xcefb1daf, 0x9cfbc365, 0xf0d93f14,
- 0x4abf5b77, 0x17f32fef, 0x66f88de6, 0xfd0fd023, 0xe02eff1e, 0x02b9b20c,
- 0x0d33f3e2, 0x2d85dffb, 0xa99f36cd, 0xdcfcf880, 0x9430e944, 0x6399acf3,
- 0xf22f2e21, 0x94e4179a, 0x74a3861e, 0xf512ad8f, 0x2e6052b8, 0xdca17201,
- 0xe71fc110, 0x46287215, 0x98971f56, 0x2efefb22, 0x7dac966b, 0xb2edce42,
- 0x26fbdef6, 0xdffe21b6, 0x7c3c01fb, 0x465e20fd, 0x8efec1f7, 0x7dec4bd9,
- 0xc73dbcdd, 0xd69dbeef, 0x0d3cbd27, 0xc1db63df, 0x2aed27db, 0xd623bfc7,
- 0xa3a9e143, 0xe1f9d48a, 0x14f33f8f, 0x13b0a60c, 0x78bdf76a, 0xbe67de18,
- 0x1d709dae, 0xfbd420fb, 0xd2bfa2a1, 0xf2fca03e, 0x072fc0c7, 0x0cd53ebf,
- 0x231da1f1, 0x790649be, 0xefc19994, 0x21bb7187, 0x9ef4dd14, 0x61fac90f,
- 0x2528fde0, 0x28f210dd, 0x4e5643a7, 0x01eec63a, 0xfb3f2cdd, 0xb433f013,
- 0xf0245dc3, 0xfd2a08ef, 0xb6758365, 0xff041f0f, 0xb86a07ce, 0x3f7bd109,
- 0x5bfc316b, 0xb277a7ed, 0x4963f370, 0x0bbbf8b1, 0xee7ae0f4, 0xc1959b3f,
- 0x76a4ace2, 0x454963ff, 0xe2b276fe, 0xb27bec8c, 0xab235a52, 0xd794ceaf,
- 0x09ae97d7, 0x0f4a1fec, 0x3cdcfc5b, 0xee0f339d, 0xff4149f1, 0x7aef626e,
- 0xd85f3962, 0xecf904b7, 0xf14bfdb9, 0xbf2ab9ef, 0x81e3a7af, 0x08716fdf,
- 0xd3f82af9, 0xcf7b350c, 0x4cbed957, 0xb5bb67cc, 0x614a7df3, 0x6f5c798f,
- 0x69fbb930, 0x93275394, 0x7f4c19eb, 0xc9e1b4bd, 0x710d7c1f, 0x9eccbda4,
- 0x726164ba, 0x17f77f23, 0xcc7bf82a, 0x7d19c383, 0x2abd9be5, 0x53d327b8,
- 0xbc82e11d, 0x26a586ed, 0xdc1bb7cc, 0xa189f7cf, 0xfc1f9080, 0x1a7fd0f4,
- 0x0efe7d28, 0xc805bf2e, 0xb9d01ee1, 0x8cf1fd68, 0x49872843, 0xb86fcb2e,
- 0x9c7cfb55, 0xbfa864ea, 0x317e3194, 0xcb8fe807, 0x55cf422b, 0x57a463c3,
- 0x021f017e, 0xc0fd40b8, 0xf0fbdf4f, 0x1e33f069, 0xfc02fc65, 0x0f513307,
- 0x7ee51bb0, 0x1ef63685, 0x0bbd9598, 0x4242f222, 0x87658ff1, 0x5760755a,
- 0xf1fe6ade, 0xc4f9f5f2, 0x8f1409b1, 0x3e597b0d, 0xfe8ee5f7, 0x6f802451,
- 0xf0d7e128, 0xb7cf0a9c, 0xa87777a8, 0x5079c3c7, 0x70164bde, 0xb201e626,
- 0x181e78f7, 0x20c9b7fd, 0xa7d81f97, 0x50f44161, 0x1155acf3, 0x833cc06b,
- 0x8e51e9f7, 0x98f7f589, 0xf7d91f39, 0x5cd2e8d7, 0x220aae56, 0xa01ea94f,
- 0xa03d058d, 0xf5bb4252, 0x65097de3, 0x258fff00, 0xe216b1e2, 0x3a2f9810,
- 0xbf070d85, 0x899df11b, 0xe04d1cc4, 0x6ec27afb, 0x5a6fb69d, 0x3f57d07f,
- 0x63ff3dd9, 0x69f2198a, 0x879e1646, 0x1f8ef0e9, 0x16c7ef85, 0x43f81a47,
- 0xeb78f126, 0x175f16c7, 0x8f1fd5e8, 0x6fc0908e, 0x0d5fc749, 0x7d7d8be3,
- 0x35a475ac, 0xed17fa06, 0xfbd3be83, 0x42bda25d, 0x0274b2bd, 0x11678bc4,
- 0x5efcd77c, 0xc9a3d335, 0x0b3cec3b, 0x7520dabe, 0xc73be346, 0x32bb9319,
- 0xa684ff68, 0xab3da11f, 0x51ba27cc, 0x6ed7ba3d, 0x77b126de, 0x4e8c6c32,
- 0xfc5d47eb, 0x7f3a74c9, 0x41efb53d, 0xdf6babaf, 0x28a6ef8f, 0x7b5ef9ed,
- 0xbc2fe94a, 0x7fe83f8e, 0xca6fb100, 0x0080005b, 0x00000000, 0x00088b1f,
- 0x00000000, 0x58adff00, 0xe554700b, 0xdef73e15, 0x66cd927d, 0x421b22f3,
- 0x260ddde2, 0x9b709601, 0xf51e4357, 0x8ca4109a, 0x6388376d, 0xfadea56a,
- 0x59092040, 0xd6a27509, 0x0071a6e1, 0x3b634ea9, 0xb33088a3, 0x2331e1d2,
- 0x3054d353, 0x32d740a3, 0x5da96255, 0x66d42d8b, 0x88d46b98, 0xf1a6c935,
- 0xa1986655, 0x5ef7fce7, 0xd6086f76, 0xe6ccdd3a, 0xe73effec, 0x9cff8f3b,
- 0xaa36c01f, 0x5cfb0195, 0x8bdff016, 0xed2bf1f6, 0x8ca2c020, 0x06ac43b0,
- 0x27c8f2d8, 0xfb0dbd7f, 0x990dedd4, 0x47f18b63, 0x475f8e3e, 0x5c8054b3,
- 0x000ea580, 0xd4c0154f, 0xbee8b4fe, 0xf097f500, 0xd9b00350, 0x80453f87,
- 0x9c944e8f, 0x8ff1c6ed, 0x8703b0de, 0x9f1b275d, 0xdb107c9e, 0xf9a7f65b,
- 0x059e349c, 0xef8d3e6a, 0x38aa8d2b, 0x6a7e3ee1, 0x27073ba4, 0xfb4ba60e,
- 0xbdc3fc71, 0xc61fcfa5, 0xafe786f6, 0xaecd8897, 0xd9883c5d, 0x0d885fd8,
- 0x3e6dffea, 0xfd7e075b, 0xfd2e75dc, 0x92e0e15c, 0xf8d0379f, 0xce896cc1,
- 0xcb39a569, 0x75ec2e00, 0xf00e50cb, 0x7dcac419, 0x731f00c5, 0x1b8f18ea,
- 0xcf87f3b7, 0xb3c03c73, 0xe494a50e, 0x37fbb8de, 0x7947ab7f, 0xe77e0f9a,
- 0xdfc865e9, 0x40b93386, 0x5cf2c0fb, 0x787e0186, 0x1a728b98, 0x9708b5e7,
- 0x60085abc, 0x067158fa, 0xb4f89284, 0xdefb721f, 0xe2b81977, 0xd32073b7,
- 0xca1aeed2, 0x965fbdf7, 0x8e83b76c, 0xd9c3dc31, 0x7d0eff68, 0x65798608,
- 0x09d5f109, 0x0808039a, 0x97847298, 0x9c085400, 0x13ff840c, 0x65ff864e,
- 0xa490dcfa, 0xf8cf222d, 0x1941e0e8, 0x6cfce0f0, 0x702bf970, 0x97e3a2b9,
- 0xdf74a278, 0xad66c44e, 0xcd500598, 0xbd592df6, 0x8b7fc924, 0x15e9b230,
- 0x977a7fdc, 0xef627253, 0x0cee1bb8, 0xa73eae87, 0xeb64cc55, 0x053eb9d7,
- 0x7fb2765b, 0xadbfcf53, 0x51c810ed, 0x27d15f5c, 0xb48fde56, 0xafcbd0db,
- 0x0c35e1fc, 0x8f2781f7, 0xee78669e, 0x3a1de079, 0xe98794f7, 0xb8eb4e0f,
- 0x23683827, 0xd6fdcc39, 0x56c0a6b9, 0xc73efc49, 0xc7fb35f8, 0xae5b399e,
- 0x4763fee0, 0xda039716, 0x7c425df3, 0x67c459ec, 0xfe7e3d32, 0xa783a461,
- 0xf15732fe, 0x476fcd5c, 0xcfdb34cf, 0x1c738f6c, 0xe483b793, 0x829bfec0,
- 0x9e228de1, 0x09903603, 0x4b9dd1bf, 0x422d7e18, 0x9ff48328, 0xdfcac8f8,
- 0xfdcd3e4c, 0xfdccfe4d, 0xa43d79cd, 0xc261c42f, 0xc2cf2f11, 0xa24539fe,
- 0x6f09ae45, 0x43d33cbc, 0x3fd63efd, 0x14ed8591, 0x9fa36b7b, 0x1736dfa8,
- 0xbf9073d8, 0xea4e36b6, 0x42afd603, 0x0531a316, 0x2ffc3bc7, 0xd841b81b,
- 0xab767685, 0x93906761, 0x5a3f236d, 0xdf5dba03, 0x8bc7fb5a, 0x76e0179c,
- 0xfa03b018, 0xf7be39cb, 0xe3a42ec7, 0x13b4bf03, 0xbe10e87e, 0x4e5fb431,
- 0xbcbf877d, 0x4db96af8, 0xa58d804a, 0x5f831bc6, 0x22ca09b5, 0xcf84cfb8,
- 0x014bf2a3, 0x1b39119e, 0x8508579b, 0xa5c70f34, 0x3a81da18, 0x90fa94e8,
- 0x787c4b9f, 0xe1dfe12f, 0x1f939588, 0xf12eeb98, 0xe71feb0a, 0x7d23af4e,
- 0x1e562d83, 0x647d474e, 0x40cb803a, 0x65c52b9a, 0x0cfd43c4, 0x23015c58,
- 0x9518f1fe, 0x1d849ce8, 0x8f9106da, 0xfd37ea46, 0xaaa4ed13, 0x7a0c8f99,
- 0xfc93f392, 0x0195db5b, 0xb2aacfdd, 0x2cc0c8f9, 0xc327f1fe, 0x4060fb0f,
- 0xd617fdd0, 0x7ae710b8, 0x59006703, 0x64df7f20, 0x3cb937b4, 0x54e30131,
- 0x0552ebc2, 0x18febfe4, 0xf5db01ea, 0x44abd8b6, 0x07a1ebd1, 0x310759f5,
- 0x6b21bf7d, 0x8f70e6fc, 0xfc1c703b, 0xa91c598b, 0x8dbbd433, 0xd1e9008b,
- 0xee8cfd05, 0xd102e2e4, 0xa314c16f, 0x446cf832, 0x97467611, 0x15d19843,
- 0x25746110, 0x0aba33f4, 0x19bd1806, 0xa2c28ce2, 0xf8b01f58, 0x58df13ff,
- 0xdf6f921a, 0x5a465fc7, 0x66441b75, 0xc32987f3, 0x078dafce, 0xaf9af546,
- 0x500ac78f, 0x6baf8cfc, 0x8cbf32e1, 0x8b89b9d9, 0xd711ec93, 0x27ea21b9,
- 0xdb1a08da, 0x5c3206e7, 0x1046e7dc, 0x066ed46d, 0xbe5bb599, 0x9ab51e22,
- 0xb3425362, 0xbb3cd2e0, 0x70345c9d, 0xab2c25e9, 0x185afa93, 0xd4db5910,
- 0x149f201b, 0x27d6afff, 0x559f1114, 0x889f4d69, 0x03b22218, 0xc61b61bd,
- 0xa6caaad7, 0x2f6c62ee, 0xb7a93c08, 0xed2a9beb, 0xfbd39e12, 0x8c72f08b,
- 0xee0c2eab, 0x2845c46e, 0xa916a016, 0x0396f6e2, 0xb85395fa, 0x54ff225f,
- 0x10f100dc, 0x40b9e373, 0xc256d0fe, 0x3e2dbfee, 0x3aef3f5d, 0xda00f494,
- 0xe62ba777, 0x2de71115, 0x74792dbd, 0xe8776e0f, 0x2b9bbefb, 0x65057e2e,
- 0xae39e272, 0x383ca48a, 0xadb1baae, 0x4f776271, 0x57ee7920, 0x5020af38,
- 0x9af3ed7d, 0xfc488afc, 0x4804ab80, 0x3dc605cf, 0x2f58383d, 0xef9d3c49,
- 0xe96be763, 0x383ddd25, 0xbc3fa4f4, 0xa44bf690, 0x90b5f6eb, 0xd24dcff0,
- 0x94b90135, 0x27f667c6, 0x1a38bf7a, 0x1f137dc3, 0xaeb8c1e0, 0xd394a031,
- 0x56bc5db9, 0xf87a8954, 0x0779da69, 0x4fb4dfe9, 0x0772950e, 0x4327dbca,
- 0xbeecc1d4, 0xaf2577c1, 0x77da4e2a, 0x0fdc5ee2, 0x870aa871, 0x5c38ed9b,
- 0x493916d3, 0x6fe956b4, 0xa73a11c6, 0x12e9f89e, 0xbe91d6a6, 0x38cf3327,
- 0x37fe603e, 0x2333b75f, 0x313f1d2e, 0xde8170fc, 0x7f8a430c, 0xf8b89d75,
- 0x1e303ff9, 0x247b4d76, 0xec7f5e9a, 0x26f06e99, 0x3ab30afd, 0xfd30dc4b,
- 0x19c86eac, 0x85bcd813, 0xc6fcd2f7, 0x14c52333, 0xd1186f6f, 0x42dc30fa,
- 0x02d9f8e2, 0x7b8ddedd, 0xfb82fe41, 0x8b42f73a, 0xb8c74a80, 0x1088f9bf,
- 0x9b5ca275, 0xda304f29, 0x743fb62a, 0xd0649da1, 0x8f93d97c, 0xe437ad72,
- 0x83fe1cea, 0x6d3a8303, 0x1bbc92a3, 0xefd7fe0c, 0xca66fbb9, 0xed4436fb,
- 0xdf8ef8c9, 0x36e891f6, 0x90fdbbe2, 0x21229fb5, 0xac65dfc9, 0xabbca0ef,
- 0xeb37f298, 0xfc782ebc, 0xba97145f, 0x9bfdac86, 0x4c39e902, 0x063dc60f,
- 0x9f78be46, 0xa3e48731, 0x71f379bc, 0xb289d447, 0x2ddbde6d, 0xe85da8f9,
- 0xdd1c5891, 0x5bb328f3, 0xc9ec3e73, 0xfa623666, 0xc01d86e7, 0xc71360f2,
- 0x329c07a5, 0x81e963e9, 0x62df963c, 0x0af2ce5e, 0xcecc138c, 0x1c262297,
- 0x990bddda, 0xcf1e4153, 0x9978e179, 0xcbf37944, 0x6f78655b, 0x333f9241,
- 0x0e116f6f, 0x3ed03b37, 0x1f01efa6, 0x50357de5, 0xae0374f6, 0x87653eab,
- 0x834f8e28, 0x0be98fae, 0xebbfcb3c, 0x64fd2b86, 0x231cc207, 0x4f31f86e,
- 0x2dc3c14f, 0x253101ce, 0x75f135cf, 0x2b4b7a1a, 0xa78cb2cb, 0xeb2cf34b,
- 0xd6836a33, 0x0f1caaf5, 0xd69c50d5, 0x8bca67d7, 0xc341f32c, 0x306f1c3f,
- 0x5deedbe0, 0xb7ec8a71, 0x66feb3d1, 0x657b29c2, 0x53be6585, 0xff102638,
- 0x2cda9f0d, 0x8426fc7a, 0xce51d39b, 0x0f31b7da, 0xc6ea73c1, 0x4d6ee3ad,
- 0x7ee75a05, 0xa01f253b, 0x7b6b44fd, 0xf987b4c0, 0x1ed53f30, 0xae7b7892,
- 0x50f649e0, 0x782c0b03, 0x0aebc4cf, 0xf3071efe, 0x6ee1ba87, 0xd86e5fc6,
- 0x9b5e7b8a, 0xc57cf715, 0x7ac1738a, 0x1185ce2b, 0xf5d7ce2b, 0xa80d7158,
- 0x778adc56, 0x5fe659d4, 0x6964dfdf, 0x655aee97, 0xba30bf99, 0x7c5ed2da,
- 0xfccb76e8, 0x59770325, 0x6d0e97c6, 0xf69b8cb4, 0xdfff5335, 0x619e6d88,
- 0x5ff03c5f, 0x53caffa2, 0x99ce590f, 0x888077a9, 0x6bd6f840, 0x5703bb00,
- 0xedfabdeb, 0x578af07e, 0x0f029deb, 0xf5339de5, 0xa7fa453f, 0xffe86f38,
- 0xc629d233, 0x17bd37b9, 0xfd37271e, 0xcf1e9a6e, 0xb886845a, 0xb06d7a4c,
- 0xcfeb7ab3, 0x3a737662, 0x1ee303c5, 0x18f71b0b, 0xecc1dfac, 0xdbd3ec21,
- 0x493a5c52, 0x5ce2ac71, 0xaaf899b8, 0x512722d2, 0xd0b9a84c, 0xf3419cdf,
- 0x387d1065, 0xfaf0339f, 0x36072d5e, 0x7b613f8b, 0x5bcf126e, 0x03215ed4,
- 0x8a5fd727, 0x4b30b1f6, 0xbf9e0ec5, 0x6ae718da, 0x55a27bf5, 0x052d8376,
- 0xf35ac697, 0xfe3108fe, 0x316ffc4c, 0xe7cc08ea, 0x3cf941c1, 0x05f68aef,
- 0xa45fcb66, 0xafcb025d, 0xbd6f9614, 0xa27629ce, 0x22f15c6b, 0x9e4aeb8a,
- 0xb8882f32, 0xc892f24d, 0xeb4e33f2, 0x2412a123, 0x6a565d18, 0x754cab66,
- 0x30a39618, 0xd19f290f, 0xfb187aaa, 0x2f46ad3e, 0x1253e97b, 0x18838a54,
- 0xdf394717, 0xfb5c4ab6, 0x45c7dd66, 0xca2d6f74, 0xff501790, 0x3c8ef795,
- 0xabe30b94, 0x412a8bc6, 0xb1c43ea0, 0xda63e1fa, 0xdf8a5964, 0x7bb3b0ee,
- 0x6a7a8c0a, 0x599381ad, 0x9c61dd4f, 0xac5b8a3b, 0x76bdf8c7, 0x478675e8,
- 0xd59c7fbb, 0x926f689f, 0x7bbff70f, 0xea82a7be, 0x252b9049, 0xeb370ebd,
- 0x7fe102ab, 0x7acd47b9, 0xdbf35af4, 0x752c17fd, 0xefd61c2e, 0xafef6b97,
- 0xca4d7b32, 0xfa3fefad, 0x77bb1a58, 0x6c2b1f46, 0x7fdc9a22, 0x36bfed92,
- 0x3ec596f2, 0xbbf9ecee, 0xa47eeec5, 0xd7196bbe, 0x05eca672, 0x3476bf28,
- 0x100fc57f, 0xce2389bf, 0x5133aa1a, 0xa60fdf5f, 0x13dac1d4, 0xbce9cba5,
- 0x3fe72eff, 0x5b23be19, 0x905b60e3, 0xd6fcf394, 0x6dadac73, 0x299d18d5,
- 0x9a9759a7, 0x287bf1d4, 0xa67ea1b3, 0x6cd239b8, 0x41232cef, 0xb91f6f3d,
- 0xdd136e71, 0x0e8523bf, 0xf44b4e9b, 0x4bad7e76, 0x4958af6f, 0xecf76134,
- 0x8474baa0, 0x7b439903, 0xf9f79d18, 0x516e0701, 0x403ca797, 0xa69a2672,
- 0x2977a73e, 0x288ad1c8, 0x2a664c9e, 0x873f520f, 0x167e5fc9, 0xf284b3e3,
- 0xfabc0bff, 0x7018c06b, 0xad6ddf60, 0x7a4fd794, 0x647fbb75, 0x2aad2ddf,
- 0x199952e2, 0x40eb4ade, 0x917bd8d6, 0x8ef9afc9, 0xd52f7542, 0x4eb70921,
- 0x263907b7, 0x74198eff, 0x28d4d537, 0x1d064bdf, 0x384afbe5, 0x4edd87f2,
- 0x7e601fd8, 0x315e5320, 0xfba9cc7d, 0x8bc00d81, 0x711defe3, 0x3cf6473e,
- 0xbca67917, 0x9633b305, 0xcefc57ff, 0x6138a319, 0x14e4bfbe, 0xe10b3f8b,
- 0xec979cfa, 0x4c9fceac, 0xbfc86b17, 0xb2afbd3b, 0xa0a6ebbc, 0x40e4c032,
- 0x8c7e2849, 0xdbee751e, 0x2a4dfcc9, 0x7ffe9d5a, 0x103b677d, 0xa68c7564,
- 0x3bc691e7, 0x8b77299b, 0x7b9338f0, 0x4813977a, 0xe37b89ce, 0xbbd8854f,
- 0x7c445492, 0xdf3af28e, 0x7ca6bf26, 0x7dc91ca6, 0xcd6edcbe, 0x7be4a2f7,
- 0xf212f6d6, 0x7f51c403, 0x3bb813c7, 0xfeb2cf57, 0x9aabe90c, 0xa09da7bd,
- 0xa231b638, 0xf525a7bf, 0x3bc0ffde, 0x0f61b7a4, 0x5ad7638b, 0xcece533f,
- 0x0f0cc313, 0x2487f394, 0xa79c8a5f, 0x7eef2983, 0x3ecfc713, 0xbebf1215,
- 0x38c2897c, 0x3c4cdf7b, 0xc448b177, 0x5ec79df5, 0xd276473f, 0x33ffd469,
- 0x739da9df, 0x9acc7eb0, 0x6f1a7ded, 0xc97c9485, 0x6f9fae69, 0x04c7aeb3,
- 0x886cfc99, 0x0af291fc, 0x5e2927bc, 0x8be4f79b, 0x69c19d46, 0x4d78b1af,
- 0x6efd91e7, 0x5f7654e3, 0x7d05ef99, 0x5447de1c, 0x2cdd2b97, 0x79d70b8e,
- 0x17cfb224, 0x74e306d1, 0x34e4d8ff, 0xa33c2ef6, 0x54e79d8e, 0xd93b253e,
- 0x1e5356f2, 0x6f83b9d5, 0x27ea32ac, 0x36a91efd, 0xce9ab2ec, 0x1943fe27,
- 0x32a93eec, 0x4571abf8, 0x0cbade58, 0x177f4154, 0x1e19de30, 0x7752cd7b,
- 0xa2bf07fd, 0x17f0846b, 0x000017f0
+ 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, 0x33ab678a, 0x32ea7830,
- 0x31e9c830, 0x43d24c30, 0xb712d388, 0x9fa65173, 0x8181859d, 0x81b98813,
- 0x5f881798, 0xbc303231, 0xff5e2466, 0x3b046147, 0xe181804b, 0x0b6f9013,
- 0x32089fa4, 0xb2075c30, 0x0371033f, 0x88073f90, 0x35b10057, 0x480fbf90,
- 0xa3e204df, 0x1845fc40, 0x095ff9bf, 0x42156fc8, 0xe3443fe5, 0xafc4159f,
- 0xf980825f, 0xb1e40472, 0xe42269e1, 0x0a6dc7c7, 0xde040ef4, 0x67ca86a6,
- 0xe0606553, 0xaac58a07, 0x91dbf843, 0x6281f3e4, 0xf610aaec, 0x8606396b,
- 0x1db9405f, 0x7dcdd86a, 0x0dff9403, 0x9a86ab94, 0xf1b90003, 0x03685054,
- 0x00000368
+ 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, 0x7dedff00, 0x45547809, 0xbedd70b6, 0xe9d3bb7d,
- 0x84849d25, 0x1674b090, 0x26c43510, 0x630a0840, 0x944c2127, 0x615151a8,
- 0x8408ec44, 0xf9707d90, 0x37d7d470, 0xdf95012c, 0x3e30eb89, 0x0e0c1a74,
- 0x1036a0c3, 0xc6c06a30, 0x680e8300, 0x8cc08378, 0x364584cb, 0x5c710921,
- 0x7f9e6466, 0xbb75539d, 0x48e9bdef, 0x9bdffc74, 0x3f6fef37, 0x556ea2bf,
- 0x5b3aaa9d, 0xaa753a9d, 0x42049462, 0x1be426ae, 0x71f4d1f8, 0x10921091,
- 0x69f2bb4e, 0xb910963a, 0x96bfca27, 0xff6e0d56, 0x401904fa, 0x5be6b9c8,
- 0x4254e65c, 0xc1513d3c, 0x39f969ab, 0x4cdf9e7f, 0xbcb60bcb, 0x7cd230ef,
- 0x08d116f5, 0x16ed86e5, 0x4ab9df6c, 0xd6be43f0, 0x55d8fedc, 0x45bddf34,
- 0x68286b24, 0x2066ceb2, 0x889c8439, 0xb467ec22, 0x2122481b, 0xad961665,
- 0x1663bd5e, 0x62de57f4, 0xfeda1626, 0x81e8b344, 0x82b582fc, 0xaafed09f,
- 0x4a665b5f, 0xf9e6f0a6, 0x45c58085, 0x371f6bf3, 0x2c84ecb9, 0xa381feda,
- 0x19c846c3, 0x9971145f, 0x81e51e70, 0xfc2a424c, 0xd324a71b, 0x041b15f6,
- 0xafc281b7, 0x13be7558, 0x2cd157c6, 0xbc29170d, 0xe25675ca, 0xfefac91a,
- 0x6d7f4086, 0x2dbfb0c7, 0x57f40652, 0x136ee17e, 0x929e6111, 0xd355da07,
- 0x95bcc071, 0x1af8cf7e, 0x18446b89, 0xa1bfd59f, 0x357ad1fd, 0x986e0b2f,
- 0x78818d62, 0xaf9d1c61, 0x60bfa659, 0x9bd5f983, 0xf3d5d846, 0xf30add28,
- 0x36aff0a8, 0xf8c1b14d, 0x32ca9b56, 0xd72af0c3, 0x515c493d, 0x4cadf1aa,
- 0x9555e81f, 0x3e33d3eb, 0x054f19a2, 0x06c05925, 0x6e9bf678, 0x7efe151c,
- 0x7a458858, 0x3513ae57, 0xf1e529f0, 0xfd3efcbb, 0xbc83c527, 0x9b5feecd,
- 0x02dba61a, 0x2bb7fd27, 0xa71eb74c, 0x1ceec742, 0x7d257c35, 0xc741e80c,
- 0x6273e8d3, 0x092f84fa, 0x2e7ca7d3, 0xbe33d3a4, 0xf4ae9891, 0xb3fbf1b9,
- 0x574c5cbe, 0x3e983cf9, 0xd4c22bef, 0x7ac12bef, 0x31d37c6b, 0xf179f26d,
- 0x72be8bfb, 0xeaf9d74c, 0xdf7afbf0, 0xf8374c42, 0xb2fefc64, 0x01a6396f,
- 0xbe4da74e, 0xfb369895, 0xab6f58fc, 0x2da61d6f, 0x5f7e00be, 0x98e7f1c1,
- 0x748cf248, 0x710f0efe, 0xb8937252, 0x449e4f62, 0x2c2571f3, 0xce53389f,
- 0xa27cd133, 0x3e29e697, 0x7982ab92, 0xae4f9a66, 0x1f43e563, 0x3451f924,
- 0xe566543f, 0xf93c2b69, 0x6b4f9a16, 0x5623e564, 0x34d1f9c9, 0xcacfc23f,
- 0xcc10db2f, 0x65fcd2b7, 0xd59e5601, 0x346c0a4a, 0xf964159f, 0x029ebdec,
- 0xb767cd3b, 0x87ce7cb3, 0xe6838172, 0x7b583a73, 0x1203de3d, 0x6d284d99,
- 0x3c8b959e, 0x6f3441c6, 0x37137722, 0xa37c8bc5, 0xe28138c7, 0xf9617241,
- 0x5827f976, 0xc2e4c9be, 0x367976f2, 0x1e4b3796, 0x572a3f2c, 0xc9b37961,
- 0x917fe583, 0x56fcc5ef, 0xa6e58bc9, 0xfac37ffa, 0x2c5e4d5b, 0x865faa4f,
- 0xc64916f9, 0x1beacbf2, 0x498b7eb1, 0x9627f2c6, 0x9933d2fc, 0xef04fb96,
- 0x8b67c053, 0x49396f05, 0x2409fe07, 0x69fe5095, 0xe074c810, 0xc98107d7,
- 0x20fcd1c6, 0x605dca13, 0x200bce57, 0x001bf8af, 0x1f17b2f9, 0xcf384549,
- 0xc2891c21, 0xc70e2f11, 0x03573bbd, 0x5cbbbdc7, 0xd422f381, 0x1fe96c5b,
- 0x2beec09c, 0x5dd9e3b5, 0x0579c0a1, 0x37fbd8e1, 0x26eff72f, 0xbbf3c76a,
- 0x0b4e052a, 0xdfed89c2, 0xd3ed3678, 0xbed367e2, 0x20767e10, 0x37fa127e,
- 0xb577ec9e, 0x377ec9f8, 0x70779f84, 0x07fa833c, 0x5abbd367, 0x377a6cfc,
- 0xe03f9f84, 0x6ff48678, 0x69efd95e, 0x5efd93f1, 0x221f3f08, 0xc1fed49c,
- 0x8b5f7e69, 0x43f7e69f, 0xe104f9f8, 0xbcdfef0c, 0xe2d41ec6, 0x10c1ec67,
- 0x3f113a7e, 0x4e0ff697, 0x7e2d41f3, 0xf0860f9a, 0x678e25f3, 0x35e6ff54,
- 0x3f1690f6, 0xf0850f63, 0x33800443, 0xd9e37fba, 0x3f1691fa, 0xe10a3f5b,
- 0xc67082c7, 0x393c6ff5, 0x93f16b1f, 0x3f0871f3, 0x42670871, 0xfd6ce0ff,
- 0xad9f8b58, 0x93f0871f, 0xf5267082, 0x7f395e6f, 0xe727e2d6, 0x64fc21cf,
- 0x3e3c9c20, 0xd8e1421e, 0xf2d386fb, 0x2d3f1689, 0x33f0849f, 0xf214e10a,
- 0x4e045cf1, 0x7e2d09ee, 0xf0844f72, 0xae708393, 0x969c1fe9, 0xb4fc5a13,
- 0xe7e1089c, 0x5d73846a, 0x7b95e6ff, 0xdc9f8b52, 0xa33f0c93, 0xc1b496f7,
- 0x40d7437a, 0x4c9b48b7, 0x08f1ee38, 0x64e8beb4, 0x26e9d179, 0x8a888760,
- 0x3dda417d, 0xdb6fad22, 0x08fd9b10, 0xf919db51, 0xec78c037, 0xdb52fad4,
- 0xd1b93119, 0xd62bbb1a, 0xc7c9a713, 0xea6b2517, 0x69a49427, 0xbf4e07ca,
- 0xc83e534c, 0xa7c9ad9b, 0xa9a95f94, 0x5f2ea43f, 0xf0b61f93, 0x54fd4d5a,
- 0x3e4d26f9, 0x344ff97d, 0xde3787f5, 0x64bf29a5, 0xfca68565, 0x4d02ff52,
- 0x3f75f2fe, 0x151fd4d3, 0xbf29a458, 0x4d11e5a2, 0x13e0e8f9, 0x3d98fc9a,
- 0x8fea6acf, 0x29a35f6b, 0xbd787f1f, 0xc7427ca6, 0x529e4d26, 0x72e279c2,
- 0xcf81179e, 0x07ebb309, 0x0b9ed099, 0x37984dda, 0x4ed0db25, 0x5ccbda0f,
- 0x4d1d29c7, 0x006baf06, 0x8486814d, 0xc979dbae, 0x507497e5, 0xa577df3a,
- 0xfd2712f7, 0x7bc99f7e, 0xfd823385, 0x902fe949, 0x065d4824, 0xcbe5f548,
- 0xf97fc624, 0x1c461729, 0x0d6beda1, 0x696223dd, 0xf790cbbe, 0xf1f94094,
- 0x7c80c159, 0x3a922d19, 0x266d17a8, 0x4b2ff768, 0x564179cd, 0x21f2e7f1,
- 0x3084ee54, 0x3792e5dc, 0xe78aec09, 0xc193dfeb, 0x421868ce, 0xc84c95e7,
- 0x82f784af, 0x3f6d0672, 0x4bc92ca4, 0xd44d99e1, 0x6ff7570e, 0x6267fda2,
- 0xffd04dff, 0x37fa3efa, 0xfa6ae5a7, 0xae5a1a8f, 0x44ca3fe9, 0x3b5277fb,
- 0xef10feb3, 0x4ae9129f, 0x0e115e42, 0xa1e6ff61, 0x32ffd8e5, 0xa88fdd13,
- 0xf50e8ffb, 0xf1f20cdf, 0x109ff43a, 0x5769fe61, 0xb43fe76a, 0x137f3b42,
- 0xfaf6ff9b, 0xa3fef33f, 0x0a6ffe71, 0x1ff3667f, 0x6fe6c15a, 0xfd437066,
- 0xdff8423b, 0xa77ff309, 0x4fa7f9af, 0x587fced4, 0x66fe7695, 0xf5bbffd6,
- 0x36ff7927, 0xe13dffec, 0xb0ff9b24, 0x64dfec2a, 0x7f81baf6, 0x75d1294c,
- 0x193fda7e, 0x40d1154c, 0x0fda1760, 0x28e323a4, 0xb0f21313, 0xb8e38690,
- 0xdbf19a2f, 0xdf94d117, 0x88c8bf50, 0x9aa7e21f, 0x6a43ee8c, 0x6e542cb8,
- 0x1e8133c8, 0x1fba72c2, 0x3a87cb99, 0xfe4445a7, 0xfd994f26, 0x3b78e9c3,
- 0xf219445b, 0xe49a9e73, 0x6b577d07, 0x40967726, 0xc209233b, 0x1e9e4ff7,
- 0x2f3d46b5, 0x51b73a7d, 0x91a1d13a, 0x391e362f, 0xa3ac8c9f, 0x26042be3,
- 0x9fce1718, 0x421dfba0, 0xe94711f7, 0x93d2027e, 0x7e8fed12, 0x43f74e3f,
- 0x9b96a4c4, 0x64476c7a, 0x7419fbcf, 0xe512b7fc, 0xde79c1e7, 0xe1452281,
- 0x4ffe1919, 0xd0357dd0, 0x95a36e63, 0x1e3c3f22, 0x6f9c1f3a, 0x5fe0a977,
- 0xd2bc7023, 0xf6f1b7f6, 0xe147c604, 0x36b272cf, 0x0f72511f, 0xb79f28a2,
- 0x67035e32, 0x4d2ff106, 0x5f6feda2, 0xb42243b1, 0x74a141ce, 0x97e002c8,
- 0xc4122407, 0x0247647d, 0x40cce4c9, 0x0c9d7be1, 0xa5d36dfe, 0x382a1de3,
- 0x4f28a4b3, 0xaccf1d09, 0xef1c45fb, 0xbcb6af0c, 0x63d5bb63, 0xcae9a2c8,
- 0x494224cf, 0xb6b97b7e, 0x6d3a8efc, 0xda85cefe, 0x098f9d3c, 0x5952b5d6,
- 0x874e9dff, 0xd0aef3ce, 0x69c4e9bc, 0x9b2f367e, 0x35925cbd, 0x686d8474,
- 0x034f2f0e, 0x13c413b4, 0x5def4fb6, 0x2681f29f, 0x0ea56f3f, 0xff8be71e,
- 0xddffff4f, 0xc96daff4, 0x1aae3f8b, 0x9ae07557, 0x7aaae3f8, 0xd46eeb95,
- 0x67fbe7e4, 0x5bcfea68, 0x9f29aa59, 0x535f38db, 0x4ff97b3e, 0xf952f935,
- 0x3bfd4d7e, 0xca6bd617, 0x587ba8ef, 0xf97b7e53, 0x0cfc9ae3, 0xf5352fef,
- 0x5abe9b6f, 0x9f6c2e53, 0xd703ac3f, 0x41b0ef4d, 0xa3fc0fe0, 0x299f0099,
- 0xfbf0acfc, 0xa6125f29, 0x4c2e7c67, 0x530f41eb, 0x8d786efd, 0x4a6bb5a5,
- 0x573e8187, 0x54a4fff8, 0xa5f41437, 0xfaf59f9e, 0xf4a7cf57, 0xcec91297,
- 0x812ad250, 0xd63ac094, 0xe55eedc5, 0xcebe39fb, 0xd308b211, 0xcb93132a,
- 0xf2834daa, 0xc1f20389, 0xbeb67511, 0x808092e1, 0xcde020f3, 0xa5ba004c,
- 0x4d4bb5d0, 0x38cd74d7, 0xb110eecf, 0xc9901aff, 0x94dcb009, 0xff40326c,
- 0x37a1b6c1, 0x78f1828f, 0x25be6336, 0xb3aded01, 0xe3f8a2be, 0x095fc046,
- 0xd37ca7a6, 0xf3e13d31, 0x57dc7a62, 0x5f51e98e, 0xbe1da61d, 0xec7e9885,
- 0xd0fd3193, 0x3fd31cb7, 0x3d311af9, 0xe9895bec, 0xd31f9f41, 0x53079f4e,
- 0x55ff4f85, 0xf0ca3ae8, 0x73d74edf, 0x328eba6a, 0x3878d938, 0xf1851f5d,
- 0x939bb046, 0xa71918c1, 0x563c47b2, 0xe02eabf4, 0x896a70fe, 0xef2b3f31,
- 0xd705317b, 0x7f8b768e, 0x9ee1e824, 0x011b7f91, 0xc39ee47e, 0xed480174,
- 0xfa7a7e7b, 0xe20789f5, 0xccbdfb41, 0x3187174f, 0xd12dcbbd, 0x0316af0c,
- 0xd4d92229, 0xa2fe1b5e, 0xcc4caefb, 0xb41c491b, 0xb46fbbf7, 0x6d4b8047,
- 0xc5efc041, 0xfed8baf0, 0x3bc01645, 0x39d7ecf1, 0xa4328e90, 0x4db8bb31,
- 0x0494bb44, 0x7e03705f, 0xecd67a43, 0x6d3f024e, 0x139370f7, 0xb8a7bdd7,
- 0x9fc15a9f, 0xfe0af2cc, 0xafe10e1e, 0x97f10931, 0x14bfc5f1, 0x3ba788fe,
- 0x6151a6eb, 0xbe139dfc, 0x39ca7f1d, 0x1bbfbe89, 0xe277e344, 0x0544aecb,
- 0x0943edaf, 0xe02de7ed, 0xa7bf0a7f, 0xc01892f9, 0xd93ec873, 0x87f7f662,
- 0x4e80e74e, 0x6abc30b6, 0x3d9ebc1d, 0xeec0382f, 0x7064905f, 0x67808f1e,
- 0xa40ead25, 0x3b6a6d3a, 0xef9b45a9, 0x028a1469, 0x62b8cf68, 0xfd028da6,
- 0xcf1e74eb, 0x84993d00, 0x416702a9, 0x3c79c992, 0xe4c3e91e, 0xca2c437a,
- 0x145f19fd, 0xc7a1fbd6, 0xf09c17d1, 0x31c99a38, 0xf9501eda, 0xf5df7a4d,
- 0xe353e4fb, 0x37e04c5f, 0x17d2ad23, 0xd144bf60, 0x0381bfff, 0xbcc46232,
- 0x2036b702, 0xe02be6ca, 0x7f4d06fb, 0x394b9db4, 0xed26fbc3, 0x48c1e4db,
- 0x4afc284e, 0xf0468a97, 0xbe038d49, 0xf6b538b5, 0x5f26ac51, 0xa9c832db,
- 0x1fe097b1, 0x72928f54, 0x577c08c1, 0xcba6d9c5, 0xd02e5b68, 0x538255f1,
- 0x6055f80a, 0x3aa3aaf5, 0xf0175e4c, 0xaf5be2cb, 0x46cd4172, 0x7c7eaf9c,
- 0x1a377e94, 0xbf8f7d8d, 0xafb9ec52, 0x6c7c8224, 0xcabb7ae1, 0x240afcc0,
- 0xf9c0764a, 0x1d924917, 0x6871d937, 0xd07e10b6, 0x51fb470f, 0xf33815e5,
- 0xd6b752fd, 0xcf91957e, 0xbf981acf, 0x6eefdf40, 0xe2e137e8, 0xb0d9abf8,
- 0x5bcc0a7f, 0x969ac78f, 0xca2f26f3, 0x272ffd15, 0xbf05478c, 0x6ec96295,
- 0x58afc291, 0xd5f70477, 0xc47924a7, 0x17a2df03, 0x96df8f7b, 0x9aaac274,
- 0xa1da4cb7, 0x7972bb9f, 0xdb75c447, 0x9f5f5407, 0x1e44bdfe, 0xa05cba01,
- 0xa0e354b5, 0xe4310516, 0xbbf5ed84, 0x618b2b9a, 0xfb0d3efd, 0xe72faa15,
- 0x38071290, 0x6349cb1d, 0xe7e7d80e, 0xf008a188, 0x87fc8e74, 0x4e8a8c63,
- 0xe2134467, 0x47efda89, 0xf6a3e3d5, 0xed4f26bb, 0x8cbe4d77, 0xe70894dc,
- 0x494f65d9, 0xfce02fc4, 0x127fe534, 0x79f7489d, 0xec01aea4, 0x5b12c59d,
- 0x1272efd7, 0x5f1d0a63, 0xe5cfabf5, 0x79fcd294, 0xca23d991, 0x38fcec79,
- 0xc08afe36, 0x9687936a, 0x731e6b1f, 0xda0455eb, 0xfd601bfb, 0xee08b791,
- 0xf8deaeb5, 0xd7e3aefd, 0x87b1578f, 0xf30b9d7a, 0x13af5471, 0x7648fe3c,
- 0x8533e711, 0x4e8c631f, 0x45237f8d, 0x9744bf97, 0x7fcba31f, 0x401f796f,
- 0x295ef234, 0xe38c537a, 0xfec37c98, 0x2376304e, 0xf86f7f3f, 0x5fe0bd49,
- 0x1fc283f2, 0xd13393ac, 0x8507e63b, 0xfc6bd19f, 0x5f824757, 0x5b4beafd,
- 0x2a9faa65, 0x41da795e, 0x6d3a7ea8, 0x53744c6c, 0x5dad57fa, 0x383e00ea,
- 0xc01d9465, 0x62fda7cf, 0xbe823f91, 0xf0a8d7bb, 0x8026c783, 0x49fe0dff,
- 0xff599fe1, 0xaeb0f5e8, 0x7256b17f, 0x9d6d5fa2, 0xf2a66839, 0xbf3cd35a,
- 0xfe616498, 0x3b2fcb08, 0x45be422f, 0xbf159fcb, 0x85d13a7e, 0x314e52fa,
- 0x8838ffa0, 0xd34d7ff6, 0xdd605327, 0x28dd25af, 0xd076fa67, 0xb87157ff,
- 0x629a953e, 0x46e3977a, 0xb3da113e, 0xa3f36d5f, 0xfc0745e7, 0x06fd03ab,
- 0xdce5fafa, 0xda332f8e, 0x1afea007, 0xfe83c64f, 0xfc41f052, 0x5f178ecc,
- 0xfc0b2e7d, 0x7e9b67a7, 0x785410ef, 0x27ace452, 0xaf57fb30, 0x97d6fabb,
- 0xd50e549d, 0x4f62a3f6, 0xfef85ab8, 0x55a595a3, 0x1571d052, 0xab5593d5,
- 0x3f4cb725, 0xc2f4bd57, 0x3f82cf8b, 0xf7668ff3, 0xf2bf0a70, 0xaf075da5,
- 0x8dcaf9a4, 0x366280d2, 0x18909b0d, 0xfd2d4ba6, 0x9876617f, 0x779b150e,
- 0xd8a35c99, 0xc2e307f7, 0xb8dca8f4, 0xf54644c3, 0x604147c6, 0x16c3a987,
- 0x23812e81, 0x12fec053, 0x09bbfd5f, 0xbb7a7ee8, 0x46a60640, 0x5deae7c0,
- 0x9e019f68, 0x4e9c8e90, 0xeae9ba21, 0x80ba52d7, 0xa4e8573e, 0xfae22f2f,
- 0x32b9e004, 0x7e5f9f91, 0xfe84e21d, 0xfcc37664, 0xdbbe5fcb, 0x6938f301,
- 0xfd7c63ac, 0x0f44d2dc, 0x925cb7ed, 0xb2989d13, 0xdfcfe5ef, 0x6f36fc8b,
- 0xcc89bdff, 0x6419e58f, 0x1e49b5c0, 0xbb9bf304, 0x5f9c16ea, 0xdf22f119,
- 0x96273f95, 0xdcfc7e80, 0x46368a48, 0x8d4f8b90, 0xb9380ecc, 0x74b81a86,
- 0xb2e9277e, 0xff337183, 0x14fc6221, 0x3f453f21, 0x2e7cbdd9, 0xfcc382d4,
- 0x4e8c51e7, 0x5c0d196f, 0xaf15a8ae, 0x65a6d7e6, 0x339f40ed, 0xe1033c43,
- 0x1896a5bc, 0xe10f8e65, 0xdc570a1b, 0xd190385f, 0x398cb887, 0xc3b51dbc,
- 0xd43be00a, 0x963c976f, 0xf23b4d2c, 0xffb86a4d, 0x74ff787b, 0x3f60d1dc,
- 0xbc8c4c9d, 0x2928180f, 0x71d74f72, 0xe4a97f15, 0xd37bc99b, 0x15be4cc3,
- 0x58dff779, 0x397fe504, 0xda07e4c0, 0xc748fac1, 0xe5881c15, 0xa809a63b,
- 0x1824cc0f, 0x249bae49, 0x72dad72e, 0xb8e84f85, 0x8a8c428d, 0x1c7e005f,
- 0xa6ed1fe2, 0x3b68a7b2, 0x85acbe95, 0xe1bd1cfe, 0x8f3b7229, 0x9009ffcb,
- 0xf2c3cbff, 0xb931564f, 0x95bedbef, 0x92553f11, 0x4167c5ff, 0xca7ca95e,
- 0xa957902e, 0xe9fde604, 0x3f83b686, 0x69f272a1, 0xad539140, 0x69cbd4fe,
- 0x097ba6f9, 0x4e5ea7f0, 0x475c1d3f, 0xfd29ca22, 0x074e511e, 0xea97fc77,
- 0x0e7f054f, 0x153fab49, 0x1e17d87d, 0xb7f0faf5, 0x53e21746, 0xefe90faf,
- 0xcde9c900, 0x29df0a7f, 0xdbf156fc, 0x77a061ea, 0xf0a97c42, 0x152f885d,
- 0x57cfd3be, 0xf97d3f8b, 0xd199f061, 0xf6bc9571, 0x4a1494fe, 0xc156aacf,
- 0xbb61766d, 0x78a790dd, 0xbfb330f2, 0x00ca7771, 0xcbafde75, 0x3df57407,
- 0xae897cba, 0xaf9757be, 0xb3f7d5d3, 0x9b4b487d, 0x041f2089, 0x45a5f535,
- 0xfc738644, 0xee226dee, 0x98e8bbbb, 0xaefb681b, 0x997ea90d, 0x16a583ea,
- 0x4eefbfb6, 0xfe803530, 0x3b7672ea, 0x616f20e2, 0x92aeb5fe, 0xcaac476e,
- 0x2ad23c3e, 0xf0edfea2, 0xfb48a293, 0x22d16a13, 0x5f483a9e, 0xa3bcece5,
- 0x5d0db450, 0x46977e08, 0x81ae0dd1, 0x39b7f539, 0xaba1bce0, 0xe986fd35,
- 0xb7dcfbf4, 0xe85f0c45, 0xc164768a, 0x31ec88b8, 0x0bed520e, 0x99f9114e,
- 0xb33e7489, 0x60fed95b, 0x5d9d0ace, 0x5f205641, 0x31eed994, 0xf6a45e81,
- 0x9fad51fc, 0x0577f19e, 0x4abe5787, 0x57b4ae5b, 0x4d158df6, 0xdf2f72da,
- 0x5c495667, 0xa3268c5f, 0x308f3ed9, 0xafd7093f, 0x0de66285, 0xbbfe29d3,
- 0xf80488f6, 0x4455a7a5, 0x106cf7fc, 0x226fe0fc, 0x4dca0272, 0xbd46e90d,
- 0x2ce9e0a6, 0x6fa985c8, 0xcb7673bd, 0xd00f3947, 0x3f5b552a, 0x9a77fac8,
- 0xc7fadd9e, 0xfe406f11, 0x3f4343d5, 0x17ebbd20, 0x79e0b76c, 0x3b76d76e,
- 0x6d76afc6, 0x01f437db, 0x7666bfc8, 0xb6bb38c3, 0xfc05997f, 0x5cc8b5d3,
- 0x6bab7a0e, 0x2cd7db08, 0x5665f6de, 0x4b93ae07, 0x90bf6e90, 0xa7aabed8,
- 0x858febf5, 0x59d29001, 0xddbffac1, 0xda9dfe8a, 0xa7182dd7, 0xcbedb5db,
- 0x87edaf1c, 0x3f0d4f9b, 0x93b2efbf, 0x7c609be9, 0xba7cecb1, 0x2f098df6,
- 0xabfed3d4, 0x6698779b, 0x3782f2d3, 0xfa059eff, 0xb3136bb0, 0x8ea53a6b,
- 0x7a7ce1e7, 0x8bedd2cd, 0x4ee78a24, 0x42648a10, 0x4df0d47e, 0x09199cbe,
- 0x7f477f2f, 0xf1f17f53, 0x7c18ffda, 0x53ef1808, 0x47f76ad5, 0xbfef3009,
- 0xe801fc7e, 0xe466ed81, 0x9fbe654b, 0xeed1ea06, 0x0fbcd8b8, 0xfdc7bcc3,
- 0x085bcd2b, 0x5fde67f6, 0xfbd393fe, 0xe385c921, 0x6f41cbd3, 0x1f76df3e,
- 0xbbb25fe6, 0xe4fdbc71, 0x7fa681f7, 0xa26fba31, 0x7c5c7774, 0xe4ff39de,
- 0xee9beef3, 0x74e2cf6f, 0x8c7de277, 0xe38eff37, 0xee7aaefb, 0xf3a1ffd6,
- 0xb373ec57, 0x8f3da4a1, 0x693a6f8e, 0x316183b4, 0x2f67a123, 0x8799c484,
- 0x8c0065fc, 0x8ae7e257, 0x332df1fa, 0x048ffdb1, 0x5fb4c6e7, 0xf7c08b72,
- 0x743f6c75, 0xae1fb73d, 0xf6865c1f, 0x661ef5e8, 0x496313af, 0x8858de49,
- 0x46e39aff, 0x3ec9273f, 0x2dfc85ec, 0xbb5e7893, 0x20577c2f, 0xe3da811e,
- 0xda2d0fd7, 0x0de9f603, 0x33418d83, 0xfa408f4b, 0xcf7f83be, 0x665feed5,
- 0xdbf9b578, 0xb7f36ba6, 0x82b77870, 0xbffb4571, 0x83f044b5, 0xf21a535f,
- 0x39f80254, 0x1112b9a5, 0xa9138804, 0x84fb0a5b, 0xedb44a5b, 0x767ec367,
- 0xf38f185c, 0xe153bca3, 0xa46a21fc, 0x61b8f880, 0x24fa8885, 0xf840532a,
- 0xc612b925, 0x28627e13, 0x173c01c9, 0xf35f198f, 0x0dce0633, 0xf1cf9df3,
- 0xd0ea4655, 0xbe1721de, 0x0e6266f9, 0xda0973f8, 0x843df34b, 0xf5ed475c,
- 0x304289b2, 0x3ce5ca9a, 0xb2639123, 0x9029cfc1, 0xa73f1aa3, 0x1fbf0f36,
- 0x5ce18625, 0xfc5f7eac, 0x7fa743f8, 0x347ffca6, 0x90cdda83, 0xf33bb9e2,
- 0xaafb29d7, 0x1e195b3b, 0x7f04ab6b, 0x5055f21a, 0x7c539f52, 0x85fe626d,
- 0x06383f3f, 0xe7ef2ae5, 0x7ed862a3, 0xcced032f, 0xf6676e5a, 0xf018aec8,
- 0xa6b4f46f, 0x02b1f3f3, 0x3f023787, 0xadfbe7ef, 0x3ef9c03f, 0x0b26bb4d,
- 0xfdd8228d, 0x78fd1ba4, 0x590b64f2, 0xee0e211b, 0xa7e29303, 0x1ffdc3a8,
- 0xa01cc4fc, 0xa3cdfb23, 0x54e2634d, 0xdd715b74, 0x6f566369, 0xa8efc03a,
- 0x1fe83cea, 0xefec2fc5, 0x2dfbaf00, 0x224a531d, 0x971cf7cc, 0xfeb7e2df,
- 0x6eb5f78a, 0x00954d6a, 0x164d372f, 0x9fa6e735, 0x75bef898, 0xe303190c,
- 0x1aeb7e2a, 0xcba004c7, 0xf70dd11e, 0xcf5b6ab3, 0xce11bc9b, 0x04f8f48f,
- 0x97dfe8f8, 0xcf8065dc, 0x42c7ff63, 0x8fb59f60, 0x4264e79f, 0x6e2674bc,
- 0x4fe03de5, 0x75e382fa, 0x7489d9aa, 0x4f38b9be, 0x66fda04a, 0xc3473b36,
- 0xaf325691, 0xad16153f, 0xc11c1071, 0x92f529da, 0x23bd58ab, 0xa44d6726,
- 0x128a2ff9, 0xfb8579f8, 0x9fe15cbe, 0x3f796e8f, 0x61f307b7, 0xeecc993d,
- 0x6be6f5d5, 0x53d1f282, 0xdf41f824, 0xf309fec3, 0xe03eecc5, 0x972b033e,
- 0x597a626f, 0x9e3d7be1, 0xcf0ccdd3, 0x3c05ff4a, 0xf0ccd23f, 0xc159e0a3,
- 0x4abc7eaf, 0xaeafaa7d, 0x6e21fb56, 0x32fd1968, 0xad3587ac, 0x4140d382,
- 0x4c3b18d5, 0x2db58720, 0x67e04b8f, 0x7062e19f, 0xa5907ae9, 0x6a9dd73e,
- 0x6debe766, 0x02cd57d9, 0x056cf93e, 0x7b684bb5, 0x0ef39ccf, 0x19f77758,
- 0xbdc1efdc, 0x915df949, 0x7d16fdac, 0x79cf81f5, 0x1aa364ed, 0xf38e2a6e,
- 0x093caae6, 0x57b726dc, 0xaa0690ed, 0x39aa69f8, 0xef95cb0e, 0x6cae55c9,
- 0xc3fb4ef8, 0x998fc871, 0x6787c409, 0x3ef1da06, 0xb175edda, 0x03cb0f8c,
- 0x4f984c3b, 0x7f4afac5, 0x797a3f4a, 0x8dac569a, 0xd05d99fb, 0x52f01831,
- 0xe3de0e6c, 0x9da7c08e, 0xbbe40e9c, 0xca1e13ae, 0x8bff59b7, 0x947b89d6,
- 0x2a43a275, 0x6c89c551, 0xa73d3335, 0x4606275a, 0xd416275a, 0x1d0206bb,
- 0x1f4b6c16, 0xe0b24208, 0x48c4c2ed, 0x3efbc4eb, 0x88785e76, 0x9aecdfdf,
- 0x2b89d746, 0x34c4eb54, 0xbe89f20b, 0xc4acdf9d, 0x9d645d61, 0x5ff6e850,
- 0x87de6fac, 0x7c822275, 0xd76b366f, 0x4b5b5b89, 0x75b89d71, 0x57b9a89a,
- 0xb17cdeb1, 0x712f2275, 0xb725e606, 0xbcff0235, 0x43e1edcf, 0xfa0ebe3c,
- 0x34e2f581, 0xde84ffe8, 0x7a5f46eb, 0xeafeb1fd, 0x3c26fff5, 0xc17d7a2b,
- 0x781eec2d, 0xc8243e6f, 0x50660bcf, 0x3f002ebd, 0xe0bebd32, 0xd317ee0e,
- 0xd012d9e9, 0x7ad563b3, 0xf1afb596, 0xb6a175b2, 0x3317f525, 0x1a4ff969,
- 0xad147725, 0xdeb093ff, 0xddeb51cd, 0x1377a0d3, 0x72dde822, 0x6b3f77a6,
- 0x53f6831d, 0x88fbf35f, 0xcfaa5beb, 0xf811dc32, 0xab4cfa63, 0xb1ce9ee6,
- 0xdccbbfd1, 0x4fb2f20c, 0x4fbb73c4, 0x77b01db8, 0x82c6eff4, 0x144a7a9f,
- 0xa71c4f1b, 0x5c8fa767, 0x81ea993b, 0x9ecc3982, 0x2220deae, 0x999a6afe,
- 0x4464d7fc, 0x3f345dfb, 0x26affb25, 0x636e57c8, 0x06746fe7, 0xfa2a79c5,
- 0x68ebee57, 0xe5703f00, 0x0fcf016a, 0xf019ce21, 0xb3e38f39, 0xfb895dcc,
- 0x80fc7d15, 0xe6ad17e2, 0xaeb7e6f5, 0x3ea9ff46, 0xe33aa0ae, 0xafb0d3da,
- 0x3a333628, 0xfc166f14, 0x1ce153ab, 0xfdcf575b, 0x541b9e30, 0xc7dfb407,
- 0x15cef9f0, 0x619b9983, 0xe89ef55f, 0x8dceb48e, 0xfca5e3d1, 0x7ecbc41f,
- 0xffb1978a, 0x17d2f1ef, 0x8f7da81e, 0x3e3d64fe, 0xbd7145c6, 0x82c64d92,
- 0xf0627e1c, 0xdf915ea0, 0x642e3111, 0x35c3e3ce, 0xa20bfef7, 0x67dabe98,
- 0xdc4036f0, 0xe2c35cae, 0xdaade647, 0xe6912bb8, 0x68c80667, 0x5bcf4770,
- 0x43875da9, 0x0bb37eeb, 0x7599f5d7, 0x1388051b, 0xfdefcb9c, 0xc71ffb94,
- 0x58ee12f7, 0x5a79d748, 0xd9b6767f, 0xfb9fe70b, 0x37a8dd2d, 0x105dbe15,
- 0x3a97ecc5, 0xc9638e3e, 0x7d7193dd, 0x289c116a, 0x5b0b418f, 0xe09d28af,
- 0x09b6871d, 0x74e14e5f, 0x16887e61, 0x4a5ac746, 0x29e79037, 0x8ebf3cad,
- 0x2bb781d9, 0x77e080f9, 0x7757a009, 0x085dec48, 0x9c0bc481, 0x11f5aa08,
- 0x12f2d5ce, 0x76de7455, 0x5afff184, 0xfc1f8dc1, 0x43efbff4, 0x9ef93ee7,
- 0xe5fd31d9, 0x0b4f0577, 0x6fde7474, 0x831e2f69, 0x1b8233e7, 0x8d68c7df,
- 0xe38573c5, 0x079dec8d, 0xcbd3b799, 0x5c3bec05, 0x8dcabf2a, 0x1f887030,
- 0x9c60b22d, 0xc69bf61e, 0xbded32ec, 0xd7135940, 0x4ee35df3, 0xda3b496a,
- 0x3178e163, 0x802637ef, 0xb5182457, 0xc8dd5c71, 0xfc003fe7, 0x02dfcdd7,
- 0x3139249f, 0xa76ef46e, 0xeec9ddf2, 0xdb7cf06f, 0x33439c90, 0x5b3f7e29,
- 0xdd79e22e, 0xc1d7066d, 0x1e6fa089, 0xcbc80891, 0x0f257b67, 0xb8ac075b,
- 0x3bee94ee, 0x4a5ef786, 0x2911ec59, 0x2fad887d, 0xfe78f8c7, 0x0f6dd744,
- 0x604844f8, 0x4dfbc41c, 0x7428ef73, 0xec64df81, 0x2e70a5fe, 0xf3817376,
- 0xe7a041e0, 0x93bdecc3, 0x700bcba3, 0x4ff7769f, 0xc3b79405, 0xfed06e94,
- 0x07a96996, 0xef7ed20f, 0xe7809e58, 0x093d335c, 0xd7b9c2b7, 0xdba2bdcc,
- 0xbecdeb45, 0x73836ec1, 0x4523a9af, 0xe7e155e2, 0x7e8ed20e, 0x3f75999a,
- 0x5dc605bd, 0x3143d74e, 0x85fdd215, 0x4abf2103, 0xb2b5f6c0, 0xb29034d7,
- 0xf3cafb4e, 0xffb4b1a6, 0xd00f5a32, 0xd58abb5e, 0xdc126dab, 0xd65b7a10,
- 0xcbea38fa, 0x1f0126b2, 0xf6a76896, 0xeb83146f, 0xdb70a28f, 0x34f6d157,
- 0x03da0f3f, 0x5bd8a6dc, 0x96ab3ce1, 0xe7db138e, 0x6479e3d6, 0x8b476d19,
- 0x4fd37b49, 0x55fcde11, 0x447b8102, 0x8fa9b9e5, 0xbdbc02e5, 0x0fca1b92,
- 0xc625f8ed, 0xfda2cc8d, 0x67f0a20d, 0xe8851d8b, 0x70407b57, 0x83233be2,
- 0x5d7e9033, 0x70686130, 0x64fd0d3c, 0x42e9d718, 0x71d51834, 0x1616c908,
- 0xb0b65cdf, 0xd5e601be, 0x1aa42721, 0x9bceaf90, 0x4e3f1d60, 0xf6a5edf1,
- 0x8b1331eb, 0x8f93686f, 0x7a543a99, 0x1d25bc74, 0x969cd8f5, 0x9f2f3c3c,
- 0xbcf04a4b, 0xeccf5bdc, 0x2d4b2391, 0x30ec017e, 0xbe1439c9, 0xe3352db7,
- 0xd897cef7, 0xa439d3fa, 0x27a1fd03, 0xee044957, 0x955e2d39, 0xf1d00cfe,
- 0xf90906e4, 0x424e7c4d, 0x25ef363d, 0x5b6b27e6, 0xbc9ee0c5, 0xcfdec4c7,
- 0x9f9a7281, 0xff651bf7, 0x6563d5ab, 0x53d40aae, 0x2bd4bd7a, 0x7aa9efee,
- 0x2f6cb013, 0x14cf757d, 0x741557d4, 0xeb4601dd, 0x3706afa5, 0xaf52bfa0,
- 0x4d896aaf, 0x10d953d1, 0x3d5a5237, 0xe04ad664, 0xc0583be3, 0xb5f07b76,
- 0x75869fcf, 0xe04ecab7, 0xf9d18d4b, 0x82f8c08c, 0x6cccbc80, 0xc839f8dd,
- 0x0b4cf941, 0x0273bbbe, 0xb37200e8, 0x59c59e22, 0xdf114bf9, 0xbce51c4a,
- 0x573e5a95, 0x7867b5ce, 0xaf51e245, 0xe256e55f, 0xf43bd551, 0xda57e510,
- 0x822d9dcf, 0xfe4022df, 0xc77beec8, 0xe389de62, 0x83edc85a, 0xe7e47615,
- 0x5f9ff743, 0xeb3afc0a, 0xbd808141, 0x036f644e, 0x2b3587ac, 0x65f81705,
- 0xdac83de7, 0x61eda3cf, 0xc97e87dc, 0xb7f28af8, 0x66bff80b, 0xb1bbe3d5,
- 0x02e0937e, 0x975687f8, 0x2e513da2, 0x9bcb048b, 0x81fee08e, 0x5f1853ae,
- 0x898b26d4, 0x4b35ffc0, 0x95304ecc, 0xf8523e14, 0x17bf08f2, 0x59dca24d,
- 0x9f76d337, 0xde849000, 0x174e28fc, 0xf029eb42, 0xf8ccad49, 0x924bc8ec,
- 0xe2e6d81b, 0xc3eec97c, 0xabebe49e, 0x532ddcf8, 0xd73cc106, 0xb68638b2,
- 0xb0260555, 0x05fa4e23, 0xcdef8f3c, 0xb6a6c497, 0x7cbe14a3, 0xfafa604e,
- 0xbda87162, 0xa5f38ef8, 0xa9947fc2, 0xb5595f71, 0x0f702257, 0x5e8fcf57,
- 0xc42b7029, 0x4cbe940b, 0x5bc743e7, 0xda3f70d0, 0x691e0aeb, 0x65f2113e,
- 0xa1ef1646, 0x91b543c8, 0xe77d05c5, 0x37fae9f1, 0x7961ec5b, 0x4adc5910,
- 0xbbfbf690, 0x9c602f0d, 0x47f5b9dc, 0xe6fb47ae, 0x8007ca0d, 0x12760dff,
- 0x1f87fdc4, 0xb34550f5, 0x4238c1e8, 0x66e73063, 0x895dbed5, 0xc57ca897,
- 0xd8aef88e, 0xd317f664, 0x8f5b15f6, 0xf5f9e165, 0xe78c6ea2, 0x680bd790,
- 0x23b9131f, 0x546fee0b, 0x86dc5918, 0x64582ede, 0xb3aa7e61, 0x83a759af,
- 0x63ac26dd, 0x045569ef, 0x2acc936e, 0x16fdeebf, 0xe787a949, 0x33a53229,
- 0xf18693dc, 0x5271dfa9, 0xfece35e2, 0x455ff186, 0x5cf6848b, 0x9d8dbac5,
- 0x71577f10, 0xdcfb8cd8, 0x31e775da, 0x95e0b89e, 0xae1df097, 0x135116da,
- 0xee2bd57f, 0xe7889d69, 0xd5cd351b, 0xf341bf18, 0x1351ce78, 0x77ff1c88,
- 0xca9cf8b1, 0x956db657, 0x372b0a29, 0xef81daff, 0x75afb572, 0x7593bde0,
- 0xd8771edf, 0xf029ce2b, 0x39c6b7f0, 0x507f819d, 0x45adfac6, 0xd644e71b,
- 0xc746bd31, 0x9ee91397, 0x7adec841, 0x21e7f3e9, 0xa6ecf70e, 0xf1879f4f,
- 0x67e7fd56, 0x061c43cf, 0x82716ed9, 0xfebb523d, 0x54638c7d, 0x30b2edda,
- 0x37f3affb, 0xcff8c6bf, 0xdd9a3fce, 0xdb73ad00, 0x6f60a1c9, 0x6bfc6e74,
- 0xde75c422, 0xfd10adb3, 0x296cf739, 0xf8224818, 0xf814940b, 0xf88fdfd6,
- 0xdabd3d53, 0x5e30db9a, 0x37a51ce4, 0xdc5087e8, 0xc59aa05a, 0xbc78ba01,
- 0x71c886da, 0xd3e2bdbe, 0x61be6f9a, 0x66c5e812, 0x345c1766, 0xa500ed4e,
- 0xa0fd15e3, 0xb98786df, 0xbf4c893e, 0x4a0ff073, 0xfa3a63a7, 0xf73cde7d,
- 0x5942cf57, 0x719f7c73, 0xe07ec16a, 0x0e23894d, 0x169d3c58, 0xbf4d9b90,
- 0xa040b8c5, 0xf40bb15b, 0xc143e7f3, 0xea4a7c2f, 0xf743ff46, 0x5bde3336,
- 0x0876d8ab, 0xcb73a7e5, 0x25d38c7e, 0x93b79e3c, 0xfe2c7e84, 0x6a7afb92,
- 0xbe2cec9b, 0xe21fe38d, 0xfc0e5cdf, 0x18dce3ce, 0x6ff12b1f, 0x0dbdc57d,
- 0xefe34e8f, 0xbcf8b02a, 0x780fa6ea, 0x5e98591c, 0xe9d02e42, 0x13c6b7c8,
- 0x0270782a, 0xe3abc61e, 0x17c72338, 0x397de286, 0xa07e80bd, 0x9a7143a7,
- 0xe2183f34, 0x21c2fcf6, 0x741f4112, 0x9ff166ae, 0x1ef6929d, 0x2c3e9868,
- 0xad15d3ae, 0xff7f5393, 0x362f39e2, 0x9f8aeffe, 0x269768d8, 0xd3c151ae,
- 0xf5910bd9, 0xf0b44178, 0x9a93dd8f, 0x05efe823, 0xc02747e4, 0x1311f979,
- 0x7c5e7bc1, 0x37dca4ff, 0xb3b4fee2, 0x0b8c45eb, 0xa1b4086c, 0x8bebd71e,
- 0xa24e7e1a, 0xd12def1f, 0xb4d54f4c, 0xece275b0, 0x46dfbb26, 0xeb7d9ce1,
- 0x9ae7e435, 0x324c470d, 0xdd7bb785, 0x2b8b1366, 0xeb03f260, 0xfe355f84,
- 0xc8ef2fb3, 0xdfcdbd42, 0x33f7d215, 0xdb53f79b, 0xda9fb91a, 0xfd35e70d,
- 0x9301ca54, 0xfef176d3, 0xb73d18ce, 0xed33bc01, 0x133a5ecc, 0xdd228b10,
- 0x2d12998b, 0x2373fdf1, 0xf5d373f3, 0xb257df12, 0x4494f7b3, 0x5fda3447,
- 0x0f73d8f7, 0xd4800cc7, 0x8b127184, 0xc55c79eb, 0xa024ee43, 0xb5fb62f7,
- 0x14bbc604, 0xc7daabf0, 0x012f4e4b, 0x2a4a4dbb, 0x673eab19, 0x1a6fc651,
- 0x157e2060, 0x17b1effd, 0x27fd840d, 0x6183ca31, 0x7da7d71c, 0xaff58469,
- 0xf7fcc7dd, 0x0cb1c2e4, 0x746edef8, 0x70a78aee, 0x6e0b27db, 0xe6f6bd70,
- 0xe43f067b, 0xdf68f04f, 0x7a588485, 0xdb8f5f98, 0xdda0f680, 0x2ad27410,
- 0x4f696ec4, 0x8bac0dc2, 0x18898cb8, 0xe8718f02, 0xa6a2f88f, 0x073abdc1,
- 0xd429e6a1, 0xef351b73, 0x1ae4c424, 0x9026ef75, 0xbd741903, 0x557e71b1,
- 0xf67672fc, 0x03b70a6f, 0xcd8863df, 0xbec0f524, 0xb45eec2b, 0xefe49e1b,
- 0x48dfd058, 0x23886788, 0x3bf56ed1, 0xcd5fb42e, 0x5fb410fb, 0xa3d63e4d,
- 0x1917c7cd, 0x5f5a478f, 0xa638f9e2, 0x43c43688, 0xd941a16c, 0x4f0f15af,
- 0x363b8f0c, 0x5083b881, 0xe30d9d7e, 0xc978a9c0, 0x6cd879ea, 0xf1d371da,
- 0x4c44f469, 0x606c8766, 0x777cd4e3, 0xf3809712, 0xd3bf68f7, 0xdbf26af1,
- 0xaa3c79a3, 0xdf411891, 0x09daa2d9, 0x068f7fc7, 0x7b8c4bdf, 0x7d022487,
- 0xcb57df08, 0xc411ee04, 0xfed079f0, 0xe09df535, 0x6bfd601d, 0x4ec190e1,
- 0x2bbf7df5, 0xccb7faf8, 0xe81ef25a, 0x75619c9b, 0x313bc818, 0xbde26489,
- 0xa801d6d5, 0xe616d29f, 0x2f346393, 0xcabe3234, 0x6e504158, 0x9c59ba32,
- 0x8d12590a, 0x8a39a8f6, 0xb86c96c8, 0x296444c7, 0xf3f17a1b, 0x22d725f3,
- 0x5c650503, 0xb68d794e, 0x37ceed6b, 0x0844a5cc, 0xbf851140, 0x31f3da37,
- 0xa370dff4, 0x1a30c937, 0x74b7de3e, 0xda9460e7, 0x6823c14b, 0xb5ddee10,
- 0xe90b0867, 0x089af781, 0xf01777b9, 0x4f286378, 0xbacf7082, 0xf7943a31,
- 0xdf7d5144, 0x67f2c698, 0xba5defa3, 0x3fbbc29c, 0x346ce4a6, 0x79ca278c,
- 0x05779e19, 0x17fe70e3, 0x71945f5b, 0x98ea6c8e, 0xf9963d12, 0xcf1de14d,
- 0x3dd0f6e1, 0xd7875c6a, 0x107c94da, 0xcd2511f7, 0x55af51fb, 0xb963f607,
- 0x1d34f201, 0x2531df16, 0xeb109625, 0x930b4ba3, 0xfd78852e, 0x9d0324d2,
- 0x974780e7, 0x60fb82ee, 0xa23c3c61, 0xb0d183c1, 0x499ed77c, 0xdf2c3c6a,
- 0x7f487605, 0xbac030f1, 0x89f2e97c, 0xe5379ffd, 0xc42b788b, 0xf019e43b,
- 0x87f1a5dd, 0xa15fe86d, 0x47ae0b3f, 0x3eeace1c, 0xfb2abfee, 0xc5270a11,
- 0x5fcc2e3a, 0xaf853b4a, 0x749be2fa, 0xbd8cbce2, 0x9fe5a7af, 0x0327ab62,
- 0x7ab70de0, 0xe1c6d9f6, 0xf63ef1fc, 0x3dd7af54, 0xaf984c79, 0x063bcd89,
- 0xb32ef7ee, 0xaaca35de, 0xcd4ecbf2, 0xd1a6205b, 0x2c8166f1, 0x93e78424,
- 0x8cb650b0, 0xf04cf3a0, 0x7ace3018, 0x063bd599, 0xef4c71fa, 0x8495d20e,
- 0x31de009a, 0x0b961882, 0x6d86bfa5, 0x50debf6c, 0x622ff06a, 0xc002bde7,
- 0x8747f30b, 0x19ba3f8e, 0x411cb47f, 0x3d69a8fe, 0xa5a3f8c2, 0x0bf81f3e,
- 0x9f60cdce, 0x47ba48df, 0x79afdd03, 0x48d0a9b4, 0xb5987ff9, 0xf28521bb,
- 0x14d64485, 0x788a5f16, 0xaf8c31fd, 0xf8f87d17, 0x45f57994, 0x693dc6df,
- 0x7ec2668f, 0xcf01af72, 0x85bc14bb, 0x8b2b07ec, 0xf7641c23, 0x6a7e834e,
- 0xc3763b73, 0xf9ed37f4, 0x70db8c0f, 0x0769bdec, 0xa34c77b4, 0xfb857214,
- 0x08bbdc6d, 0xa46dcbdf, 0x319000f3, 0x75865ba4, 0x307c6fbd, 0x03e109f9,
- 0xc04c9eec, 0x979411c7, 0x109efcf5, 0xffbc3b95, 0xdecacc3a, 0x65679865,
- 0xac07e7fb, 0x1d994f22, 0xc7b7b096, 0xdaadfb04, 0x9fac0625, 0x7aa66900,
- 0xdeb04bfe, 0x26a35603, 0xa7a14e5e, 0x93544fc2, 0x877de15a, 0x3def588c,
- 0xb389fe5a, 0x29e0a9a6, 0x11f31eed, 0x4a0c9cf7, 0xdd779d87, 0xe52aeb0d,
- 0xed351b9f, 0xc0164946, 0xf81f529b, 0x687d1233, 0xae8c45bb, 0x17b05671,
- 0x205cee36, 0x7f42f9c2, 0xef039ae9, 0x39fad1c7, 0x89b75256, 0xa189cfb6,
- 0x79e3e429, 0xa7cf207e, 0x43fd34b0, 0xdfa041b7, 0xebbf7357, 0x171e56b3,
- 0x065e7460, 0xcb3c53ef, 0x29313af1, 0x4505d71a, 0x8066c16e, 0x3f236b73,
- 0x4eeb4ebf, 0x14dd0033, 0x1b763639, 0x68ba7682, 0x065d19a5, 0xc7786388,
- 0xec6de747, 0x7b5cef5b, 0xa7bfbb29, 0xa732feff, 0xafb6f7f3, 0xaf75eabf,
- 0x4ba065f7, 0x63c75475, 0xcd7cd137, 0xf9e19fa5, 0xcd6b22e0, 0x3b73ea55,
- 0xff1faa7d, 0x3a4e173b, 0xfcec3ec0, 0xc9145cca, 0x32b0eece, 0x6f8f77fb,
- 0xec53b63a, 0xe815242e, 0x413df564, 0x5768a633, 0x1e5508fd, 0xc63651d0,
- 0x656afac1, 0x75aba4fe, 0x147f03f7, 0x42bd7e64, 0xf41238d2, 0x5fd58e64,
- 0xe5c38b8c, 0x481718e9, 0x51f662be, 0xce0ffd14, 0x79f90a97, 0x73b0e798,
- 0x397f2c27, 0xe3938d31, 0x2a4c7ea0, 0xda23cfc2, 0xe272b9f7, 0x5de82365,
- 0xf08a9e92, 0xe574a20a, 0xd1da0903, 0x30cb92e4, 0xa890ab9e, 0xbe3a31ec,
- 0x6fc6749c, 0xba964753, 0x9feff327, 0x6cfaf301, 0xd61319c4, 0x66b8d7f3,
- 0xec6b27b8, 0xe8374694, 0x5dffdfed, 0x3c5233bc, 0xe31b78c5, 0x12be3dc7,
- 0xeb339c37, 0x12ef9af1, 0xbd5dd896, 0x9fc7abf1, 0x3e0adf1e, 0xfbcb78f5,
- 0xce393dd0, 0x7a3f1bd5, 0x5074287c, 0xc7c7acf0, 0x8a6ff03b, 0xcd3277af,
- 0x3bdacef8, 0x77df8646, 0xdec8b9a8, 0xfda0f46d, 0x43c7c85a, 0x4fb457ed,
- 0x6eec120b, 0xe29e1ec6, 0x78f0c4c2, 0xe3d578f5, 0xe3bf8731, 0x7c446242,
- 0xe0377447, 0x0161f28b, 0x7ed04c1c, 0x7099b60b, 0x578248ff, 0x06fc7513,
- 0x47be061d, 0x17973577, 0xd6392f05, 0x00b19dba, 0xe78a9ccf, 0xa57f57d7,
- 0x5b0b67b5, 0x7f069ca7, 0x778c4e40, 0x8941f809, 0x5f384a98, 0x15f2d51d,
- 0xd535971f, 0xa8eaf9cf, 0x9198af8e, 0x0bcacf13, 0x74f2ba9d, 0x85507e82,
- 0x56f3f4ef, 0xf815ebf8, 0x9e37a130, 0xb2cafe14, 0x993bfb71, 0x387b060c,
- 0x31b1b5eb, 0x6b499fa0, 0xc3bf445c, 0x2125c3f8, 0x914f9c38, 0x0de2050f,
- 0xffa6777d, 0x9daa7a03, 0x3f2a82ae, 0x5bd10cc0, 0xa7a08b60, 0xc4993e14,
- 0xc88935e9, 0x347fc03b, 0x12ff1889, 0x5553f7b2, 0x99e657f3, 0x9e605242,
- 0x4c5d58af, 0x8679f3bf, 0x47cd4de6, 0xde44fba0, 0x1b28c4ff, 0xdd20b7de,
- 0xfc21b3c6, 0x32bbe1a7, 0x3c2e29b2, 0x27d7890e, 0xb308eb43, 0x7be266d7,
- 0xe42f14b6, 0x1c786b1b, 0xc4609b5e, 0x38f85677, 0x928badce, 0x79ed4e21,
- 0xec073bd1, 0xdec2b3b8, 0x319f9c2c, 0x37d60238, 0x2d67f97d, 0x9ca06b3b,
- 0x7ac32bd6, 0x2295fc7c, 0x6f742ff3, 0xa4d7fb33, 0x52876df6, 0x4075c671,
- 0x70899f91, 0x900af15f, 0x8c0a60b7, 0xca586afb, 0x7cfdba68, 0xf2fbee39,
- 0xd08db25a, 0x299eaecf, 0x4f9f9718, 0x5fb0463c, 0xe7af7cf5, 0xeb3f3d6f,
- 0x8fec37f9, 0xfb0a1ee8, 0x2fcaef90, 0xe2169d8a, 0x6f94c39b, 0xc29beb54,
- 0x1e7f942f, 0x8d75bc05, 0x3019e4fd, 0xfd8df7ab, 0x37d6112c, 0xdb0f0ec5,
- 0xa0c79e1b, 0xb8f65f5e, 0xbbff8762, 0xf034fbcd, 0xcf7491a3, 0x2369f682,
- 0xefb8065d, 0xf3cdb6fe, 0xec577c0c, 0x2bed8b93, 0xe1ba4ec8, 0x8b337ca5,
- 0x206021d3, 0xbcabdef8, 0x753d4040, 0xa096e907, 0x24ea3bbf, 0x9675fecd,
- 0x07e3fba5, 0xfeb03ce0, 0xf2078c12, 0x889a9442, 0x715c59ed, 0x31efbf03,
- 0xe0047bb2, 0xda85cef5, 0x64d8f8f6, 0xcd5df84e, 0xafb6058f, 0x48e9659f,
- 0xa5b47b80, 0xbebeb6b2, 0x7a1e657f, 0xb576fab8, 0x78219dfc, 0xb2add8b7,
- 0x31b55e0b, 0xde34263b, 0x03bbf877, 0xf006df14, 0xea5eb4d7, 0xff02247f,
- 0x2a37a92a, 0xaf18d32e, 0x99b62fb2, 0xff7a47a7, 0xc147e943, 0xaed24cf7,
- 0x916ff3e0, 0xe89a2fde, 0xc37dfb65, 0x79cd4153, 0x746692bb, 0x2ebb464f,
- 0x1da02023, 0x33c8155d, 0xf3d8d6cc, 0xcbdbbf6c, 0x2977879e, 0x0ef37ea0,
- 0xea07cf66, 0xd5505f71, 0xab37f6cc, 0x99398ce1, 0xed13240f, 0x15bed0fc,
- 0xe1aaa0e2, 0x1e563f9d, 0xe9e6ab84, 0xd7feac8d, 0x87a685b6, 0xe9df6033,
- 0x34dc924d, 0x86a1e2bf, 0x6a3fba28, 0x42162548, 0x5d7f47f7, 0x1594d0f1,
- 0xe2ca54b9, 0xc589023c, 0x426d837c, 0x5fc9f7ff, 0x01b078af, 0x7f74c9f6,
- 0xed5363d5, 0x8f92fb5b, 0xe21736e3, 0xeafdafb1, 0x5f2531fd, 0x077e54db,
- 0xa27bfd3d, 0x7fc0315c, 0xf47df30f, 0xc2ef0bb5, 0x92e581fd, 0xde21430b,
- 0xbba7226b, 0xa9fdced9, 0x3acf7656, 0xed9af45f, 0x5d6fdf20, 0xe27e0118,
- 0xc31e4677, 0x7f2b597d, 0xafaf716f, 0x8523ed1c, 0x6676718e, 0x697b5fd7,
- 0x15f6039b, 0x03fb8dd7, 0x673f0fde, 0x9d99ef64, 0xec6935cd, 0x856c87d8,
- 0x495f0071, 0xd044da29, 0xeec713cb, 0x7ceb0c3c, 0x5843eb5f, 0xd0047bff,
- 0xfec2e4ff, 0x69df3c44, 0xbf00e5de, 0xdf7e59cd, 0x5b735cfc, 0xad345de2,
- 0x0707f8de, 0xf9d2a7ec, 0xdb19cefc, 0xaa9b7df1, 0xcbbe222d, 0xbc4dfb40,
- 0xcdc7fc1d, 0x611e73b3, 0xd7a944dd, 0xd5dfc23f, 0x49bfec50, 0xaf9fb251,
- 0x12df8a87, 0xbab8e1df, 0x1c58f459, 0x73c0edbd, 0x2c9ed27b, 0xc9107a06,
- 0x1a3e1c3d, 0x0bb44ec9, 0xfd0df9f9, 0x7ef784ed, 0x9bccf3b7, 0x7cdd9fcd,
- 0x73913215, 0xd802e5c9, 0xcc01de47, 0xb0f4c739, 0xfd5dbf62, 0xa93fd695,
- 0x5bf31fb7, 0x21492f47, 0xdef60f88, 0x1fc9b77b, 0xec2ecec9, 0x9ed1129e,
- 0xc471e424, 0xf496f657, 0x4cfef0a9, 0x2706dbf6, 0xcec83bf4, 0xf9b6b1f8,
- 0xa51f7c33, 0x856f0486, 0xd1669af2, 0xa6df2419, 0x1efc979f, 0x57545efe,
- 0xbe02e4ab, 0x15dd6aed, 0x16f90595, 0xb55dfd11, 0x0e5e26fb, 0x2ad9d67c,
- 0xb5213be1, 0x80713edb, 0xf7d6501e, 0x7ef656ce, 0x31eb5748, 0xedc0aefc,
- 0x1cbf896c, 0x068d9dd6, 0xb9dcbfb6, 0xd0566ffb, 0xe85e6f0b, 0xad7dc789,
- 0xb6f73eb2, 0x052f117f, 0xbfe43176, 0x44bfdb55, 0xe200789c, 0x24630a9f,
- 0x3b610a22, 0xfcfad7b5, 0x27625921, 0x7ce9d7bd, 0x08c5f758, 0x37c735eb,
- 0xfc08cfed, 0xefbf5fae, 0x6a7b73b5, 0xf786c908, 0xc42e5af5, 0xcdbde257,
- 0x1173ab56, 0x5d985ffa, 0xccf3b5d2, 0xfbe15313, 0xdbdd915e, 0xdf2220bf,
- 0x72bdb5bf, 0x8d4d8758, 0xd7a406f7, 0x77ce8317, 0x7feb41be, 0xf99a2bb1,
- 0xcbee8da3, 0xc206f7d5, 0x5f1cfdf5, 0xae7664c1, 0xbbc32725, 0xeedbdf38,
- 0x2ef5eeec, 0xb47613d5, 0x80a7bb3b, 0xeab11dfa, 0xc5f40988, 0x53c97b20,
- 0xac040f4c, 0xe4991780, 0x6fda10a7, 0x07c93479, 0x27aeeafe, 0xdba3884e,
- 0x0060c7b2, 0x9b5d8cba, 0xeb2ef18a, 0xfcdfb9f9, 0x5529a340, 0xf3e65fa5,
- 0x9253a373, 0xf54e343c, 0xf4c1d93d, 0x155da9c0, 0xf93d42bf, 0x1e193347,
- 0x1bfc5d61, 0x4d9b67d7, 0x500dd4f2, 0xf701a8ef, 0xbf773b1b, 0x69de1bbe,
- 0x35d87f9b, 0x0399d61a, 0x5eb40f20, 0x0df5decb, 0xf2db2f10, 0x6aef4121,
- 0x68a9534e, 0x41befda0, 0x760fcc5c, 0xe0fb80c0, 0x7890ff90, 0xfb9e61e2,
- 0xf9bf6ced, 0xe6831ec6, 0xfe0de99c, 0x765be83e, 0x33b7c189, 0x3da6d43f,
- 0xb7a0f1f9, 0x6fbdd907, 0x8f6b1e00, 0x5c383477, 0x6299bf61, 0xb0384d27,
- 0xfa28ea69, 0x0d6709cf, 0xebb7204e, 0xe6111ac0, 0x48453aeb, 0xd97a40ac,
- 0x2ede144d, 0xce37bc35, 0x1c747832, 0x2a9c816f, 0xef2ba7f8, 0xff3499a3,
- 0x0e31bb46, 0xfc14a4e2, 0xfa50f32b, 0x67880577, 0xc9450db5, 0xfc5be9b3,
- 0xe69c4ab7, 0xde512718, 0x9cbe4727, 0xcfbcf76a, 0x3b4641f8, 0x68aed4f6,
- 0xf33647b4, 0x95248c75, 0x29fc030e, 0xa782fa74, 0xeafa78ca, 0x075f3cff,
- 0xf2bbf494, 0x25c97af5, 0x77f0df23, 0x30725cfa, 0xb1e21d2a, 0xeff1d25a,
- 0x55e2a8a1, 0xa93e03cf, 0x87f8d602, 0x060c3a5a, 0xb3554fb8, 0x67c5884d,
- 0xd769fa42, 0x18ccf886, 0x396bfe40, 0x2b8e504c, 0xf994fdd6, 0xe1bea8ef,
- 0x79e157ef, 0x3f0fc834, 0xd0241e97, 0xeaeb4274, 0xdf8829c5, 0x2ae403a0,
- 0x372a278c, 0x9a35d690, 0xdfe75f80, 0xfc79d2c3, 0x4afe777c, 0xd967ca2f,
- 0x67a7162a, 0x38e2a475, 0x257e71ce, 0x8864e886, 0x1bb068e3, 0x4fc9f134,
- 0xdd3dbe70, 0xf41b64fc, 0xd62bf94b, 0x6cafcb41, 0x1819fc79, 0xa7afc2ae,
- 0x5384249b, 0xff3dad1e, 0x7830744e, 0x7e300e5b, 0xe524d09f, 0x1349fbc3,
- 0x7f04e264, 0x6b4d1bf0, 0x6fdfd045, 0x32a73f00, 0xfd758739, 0xac47aed4,
- 0xeef5833f, 0xdf808188, 0x9489b379, 0xc5c9546f, 0x6aafd5ce, 0x5d62b7e4,
- 0x6ff454fd, 0xa009c477, 0x55b915e7, 0xe4d9bef0, 0xffe506be, 0x4ffc9d7a,
- 0x418bed66, 0x27bd6858, 0x593ffcb9, 0x7e9fe544, 0x158a6d8a, 0x5366ce00,
- 0x26b4f7e4, 0xff1fbe39, 0xf1eaf485, 0x92757a5e, 0x1de7ed83, 0x9affb4e9,
- 0x3f707aeb, 0xe71f1a1f, 0x2b27279b, 0x002a937c, 0x05291bfe, 0x145f0033,
- 0x68cfc0af, 0xcdbe82b7, 0x8277c34b, 0x22e3f37a, 0x234ddce5, 0xa6bd61b7,
- 0x06f7afc8, 0xe4ce4f18, 0x5f60c5ba, 0xc8cb17c7, 0xef05a7a7, 0xaeba38b0,
- 0x8e79069d, 0x394617a0, 0x42f91e98, 0x11de6af2, 0x920e3def, 0x4e5d7c0c,
- 0x2f306a77, 0x02704ab2, 0xd772947d, 0xe09fbe2a, 0x4aef94f0, 0xfde37bfe,
- 0xbdfcbd2f, 0xb8718e55, 0x6420999e, 0xad9f8473, 0x47c84467, 0x6b8620b9,
- 0xe6de4193, 0x27ec75d3, 0xb4ec75aa, 0xaafc88d4, 0xce3ee1e0, 0xb2c45fef,
- 0xfce70f79, 0x3f6c0d31, 0x173f37c4, 0x81468c13, 0x3028b5c9, 0xfe011779,
- 0x5e575de9, 0x5d7f7c83, 0xdcafbe64, 0x33f91ab0, 0xf789c8b6, 0xba349e41,
- 0x9199b12d, 0xd31fb1f4, 0x817f6b9d, 0x63e02bfb, 0xe4befb90, 0x80e41ca0,
- 0x3f7fe044, 0xfd157fe5, 0x7ca03e14, 0xa54384f1, 0xa17cf427, 0x7829df9c,
- 0xff3bacd9, 0xf5c1c8fb, 0x7d5d4f3c, 0xf328a1c4, 0x3e74def9, 0xbfce8bdb,
- 0xcb0e7461, 0xd15bd017, 0x9c818f13, 0xce5beb8d, 0xac4e316c, 0x6cd1f0d7,
- 0xe468fb8c, 0xde0140e7, 0xe7dd685f, 0x39d7d9fc, 0xf7ab32ce, 0xe0fe3575,
- 0x1995d1bc, 0x6e428fe6, 0x6b582ed7, 0x8df473c6, 0xbcb3c984, 0xbeafda33,
- 0x5234e9a7, 0xfaa29403, 0x09e7d01d, 0x21070ab8, 0x22685aef, 0xf83f7419,
- 0x4ee96a45, 0x71f9a788, 0x8a3c5cbb, 0x49a363ce, 0xee1d769e, 0x00d7dc0b,
- 0x0d8a6bfc, 0x88af884e, 0xf00538f5, 0x004ba043, 0xeb2f70e4, 0xfbba4c67,
- 0xbaafdc72, 0x1f4063dc, 0x52f4e01c, 0xa1e0abe8, 0x2faef5af, 0x9862daba,
- 0x72f0245c, 0x99791ebd, 0x4f034dcb, 0x6447ae2f, 0x41c9e411, 0x18448bbc,
- 0x07a644ff, 0x22647a43, 0xcfbe73c1, 0xf3e47a75, 0x7c8f5e1f, 0xb923d1ae,
- 0x08f5111d, 0xff9445fd, 0x68b9a684, 0x91c392cf, 0x862959ed, 0xb009c7ad,
- 0x097ad28e, 0xa1fbfb32, 0x52df3807, 0xc438c48e, 0xc63326c6, 0xc87a2b5d,
- 0xc3e48d31, 0xc0753bdf, 0xa6b50bba, 0x824f0f79, 0x9324d7f3, 0x4f83ce0b,
- 0xf748dd4b, 0xdcc374d3, 0x2251fc88, 0xe823bd00, 0x0b7e0223, 0x99834ff9,
- 0x456c5ddf, 0x48505939, 0xb9dd1d70, 0x55f23c76, 0x009a7179, 0x2eb15b7c,
- 0xb8f28056, 0xe8034ec9, 0xe31e652b, 0xc6481a17, 0x94839418, 0x8c1c9518,
- 0xc044eb97, 0x6f78b0d7, 0xc84b1492, 0xff4f3165, 0xb9b7ed58, 0x7ed5e684,
- 0xf65f9a1b, 0x9736fc5d, 0x65c9fcfd, 0x73c9b7e0, 0x8cc64678, 0x65cdff43,
- 0xac0ce690, 0x6f4a8913, 0xfb8ecc5d, 0xcb52fcbe, 0x40e443fd, 0xacec7f2f,
- 0xc7f42e75, 0xd47c024e, 0x06789f24, 0x153be1c0, 0x366eed11, 0x2f5c018e,
- 0xd2090f90, 0x9d494063, 0x4512fe08, 0x87035cef, 0x1ed428ae, 0x1433ce01,
- 0x85bd0379, 0xce3c6ee7, 0x7655fc01, 0x91fbd7f4, 0x931f208f, 0x2b47d61d,
- 0xdf110d8a, 0xc633be11, 0x67ea83f6, 0xd6f5fad2, 0xf8f0e59f, 0xe9e5115f,
- 0x3d9518ce, 0xd1f164f4, 0xc10e7644, 0x9bbbe5de, 0x45abf1f7, 0x192ef7ee,
- 0x615f7e10, 0x4324d9b4, 0x10f1293c, 0x4f155397, 0x410ab42c, 0xfea7c43b,
- 0x746e760d, 0x0337fdbf, 0xb7fabfa6, 0xb054a292, 0x6e0c5be7, 0x7c41196a,
- 0x7b83ca05, 0x267bc118, 0x616efe01, 0x23cd9b5e, 0x8843bf81, 0x3da0f7e2,
- 0xdc8df3da, 0x681ba1ee, 0x3356e2f9, 0xaebdcdfe, 0x1eefe53c, 0xb21ef1b8,
- 0x7dacdf82, 0xb8c48e4f, 0x1ba3634d, 0x858d6ce4, 0x51635fc1, 0x6062bbea,
- 0x1cebeebd, 0x64c2e27d, 0xfe29f7f4, 0x41dd89c5, 0xd692f011, 0xe0b032ed,
- 0xb18fd635, 0x957ce09b, 0xc700f5f3, 0x9b3de6fb, 0x73c75844, 0x862e3726,
- 0x764bcefd, 0xf3c00aef, 0x76b51395, 0x0ea158de, 0xb9246eff, 0x493ee086,
- 0x0ef88f91, 0x9a4c03b2, 0x1e1dc3d8, 0x9e573d50, 0xfd80ecf2, 0x11094c64,
- 0xae2a9e00, 0x5f2017e7, 0xb8478064, 0xbdfc006e, 0x08b7fe4e, 0x7bcd9c39,
- 0xf79005f2, 0x0593ed01, 0xfe6f6657, 0xeefb095e, 0x04fe2cb1, 0x07ecaae8,
- 0xb2f6fd87, 0x534fe0c9, 0x618d6fea, 0xaf2afc7a, 0xc45c00b7, 0x422f3e74,
- 0xfba613bf, 0xa929e0db, 0x9b72e5f1, 0xcf9aa5c9, 0x52f0827c, 0xc79c643a,
- 0x3cdec3a0, 0x62d9f748, 0x4f2bdfb1, 0x656e3105, 0x70c11d60, 0x07ed219e,
- 0x521a7ed0, 0x1d002ed7, 0x0b79ef37, 0x7db83bc7, 0x5cb94b27, 0x80f6e26d,
- 0x367dae32, 0xe3ee5eb6, 0xe70dd1e7, 0x7af97ad8, 0x92e3178c, 0xe4347994,
- 0x28ea9379, 0x6f1095fc, 0x78efb633, 0x4263b79b, 0x016f36f1, 0x77a76abd,
- 0xd3de06ec, 0xf7120dfb, 0x247a451e, 0xf1db642e, 0x08177b95, 0xce5627a0,
- 0x5037ec8c, 0xee4ac5f4, 0xb5c55577, 0x5aa317bc, 0xc696a72f, 0xfa54d359,
- 0x4cf76948, 0x3365ae38, 0x53796b8f, 0x52d46ed3, 0x0cd3f00b, 0x8c10e79b,
- 0x3f7bf95b, 0xd1dff9eb, 0x0ab1f651, 0x0c9d52be, 0xdcc7af5f, 0x8dce0fb8,
- 0xca4e4f00, 0x912debc7, 0x9c13c3e3, 0x306f6e06, 0x8ced217e, 0x6a1e605f,
- 0xb702ebbb, 0x78f2ae3b, 0x4f8c8c0b, 0xc93e453e, 0xdf01b7f5, 0xdb922f8e,
- 0x1087ff80, 0x8c4527ce, 0x1efcf44f, 0x7ce38ced, 0xef004dd2, 0xb1bde163,
- 0x3ff1fa08, 0x067cd863, 0xff23e7b4, 0x0af87950, 0x3a949bd7, 0x4923c251,
- 0xc38c54e7, 0x7e995584, 0x69eb931f, 0x7a737e03, 0xd39e504a, 0x07664ead,
- 0xa0fe32a5, 0x426705ed, 0x2ffe9e58, 0x4f842ce7, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7dedff00, 0xd554780b, 0xb3dae8b9, 0x64932667, 0x6f264c92,
- 0x80849af2, 0x3c870108, 0x4e3d2878, 0x0f78601e, 0x02483508, 0x48042bc3,
- 0xd2d04132, 0x20196f1e, 0x83548086, 0xa96a1ea5, 0x5af11e0e, 0xd528368a,
- 0xf09d8360, 0x41d0582a, 0x396b42d1, 0x0a8a2341, 0xf41ea009, 0xfffde3d0,
- 0xcccdad7f, 0x228899de, 0xb9eefbf6, 0x62ecfd37, 0xdaf6bded, 0x8fdffaff,
- 0xfb0cd7b5, 0x33d6c60f, 0x2a1d76c6, 0x8cb96c96, 0x794bfbc5, 0xc5a398cb,
- 0x8cf3d8cc, 0xff40b595, 0x9dbbfc2b, 0x7463cfb1, 0x1630258c, 0x2b18916b,
- 0xa46fac64, 0x598dfa85, 0x187ae4ae, 0x15d236bf, 0x79c0496d, 0x26090e74,
- 0xecc27e19, 0xf8743065, 0x99997af2, 0xc4bf5e71, 0xd5acc664, 0xbc232296,
- 0x2ec6b537, 0x7efe60b9, 0x0b78ce91, 0x0b1703cd, 0x79d22da0, 0x2d73c0d7,
- 0x66a38ed1, 0x6792cf78, 0x269d2dc2, 0xc15f7f46, 0xb12db57f, 0x35bbbeaa,
- 0x2039d2c5, 0xff825fd0, 0x0eff8148, 0xc61b1331, 0xc5bf0d58, 0x2caec896,
- 0x6b57cc0b, 0x0e6878ea, 0xf37eebf4, 0x92c191b9, 0x805eb86c, 0x7943f9e3,
- 0x81cd7391, 0xd62adef5, 0x55c39b79, 0xcff187a2, 0xc66eb946, 0xf08e47e7,
- 0xa1e193ee, 0x7d9e65e1, 0xa40b687a, 0xb0517dfa, 0xd996365e, 0xae3f41b7,
- 0x4347b583, 0x8744f637, 0x47fa1a23, 0xa784b1cd, 0xb4743f5b, 0x62fac2e7,
- 0xe7c24c9c, 0x38f95f01, 0xe5778b1f, 0xde23073b, 0xe00ccb96, 0x61e90178,
- 0x8e3d36be, 0xdf04759a, 0x53873351, 0x4884c3a1, 0x5d0b28c7, 0x4f5ef467,
- 0xd7801b31, 0x95d04c37, 0x579e8379, 0x4cc5a75a, 0xcf1baee3, 0x307d309f,
- 0x7fdb599e, 0xe813f8bd, 0x32dff1bb, 0xf029dde1, 0xd617dd1e, 0xef09f3fd,
- 0x95e0ba26, 0x61f7533a, 0xdb51f009, 0x5864db26, 0x9664a0c2, 0xd8c719db,
- 0x0eadfb9a, 0x5a2783e4, 0x8c187b24, 0xb3660e67, 0x25643224, 0xdff9d622,
- 0xb7610cc7, 0xac170b40, 0x6293ce30, 0xde436ef4, 0x43337fd9, 0x02b1dc38,
- 0xc3e8068e, 0x05165d73, 0x0df50730, 0x459feaec, 0xf861f182, 0x6a4b982f,
- 0x80976f69, 0x30466b70, 0xdee00197, 0x3f1326d7, 0xe118d13e, 0x7ff9830d,
- 0xe1e2e3bb, 0xb9cfd099, 0x82cb875f, 0x339609bf, 0x43a8f891, 0x395a0afa,
- 0x0f4034da, 0x8472edf7, 0x2df1865d, 0x5843d111, 0xfb45630c, 0x9ad9f988,
- 0xbc0f307e, 0x047b4d67, 0x3f4d6fad, 0xe22c8f90, 0xff917b83, 0x591947f7,
- 0x04bf5c0a, 0x86e38372, 0x46378eb3, 0x74e80565, 0x59d3f5a9, 0xeefd617b,
- 0xd76f3e48, 0x91fd2bde, 0xe3fb957f, 0x97b5cc56, 0x2c5633e6, 0xf38a7ebb,
- 0x1d5fd729, 0xe2345ef0, 0x8234b19b, 0x0727e897, 0x378abbe0, 0x1cafc70b,
- 0x7475a7a5, 0xae3b08b1, 0x60e8c5bb, 0x29cf2748, 0x5e0adfce, 0x746f04eb,
- 0x709e15b5, 0x389efac1, 0xe7c76691, 0x852f5abb, 0xb37de0eb, 0x230f5c63,
- 0xeef4e5dd, 0xe22e6768, 0x1dcdd2f3, 0xe75eb8b9, 0xd2ef8446, 0xaeacf791,
- 0xdf5aebdc, 0x7d64df63, 0x49b9bd6e, 0x3fc9e98a, 0xda903e5a, 0x8690bfda,
- 0xd4309c90, 0xe60c9e5b, 0x6eeb035d, 0x49b43c1c, 0x634f4246, 0xc64f9436,
- 0x06672c2a, 0x313de805, 0x12ddb9c6, 0x188e5f24, 0x2f5c0ee7, 0x8f3527be,
- 0xde1cf9d6, 0x5e74721f, 0x5d7741be, 0xf4297ceb, 0xaf447d3a, 0x5a9eb15a,
- 0x0327d993, 0xe1976cfc, 0x3e450e93, 0x0bc27bb3, 0xf08bd8f4, 0x27ed8a79,
- 0xbfcf485c, 0x106bed9a, 0xc5bf7a1f, 0xeff04519, 0x11b1f7c7, 0xbd719273,
- 0xff1d236b, 0xf6fe8665, 0x83f38c55, 0x127f6114, 0xbf73b716, 0xe4f50235,
- 0x9fd718c4, 0xba81be71, 0xd09cb38b, 0x753bf02f, 0x781db973, 0x92fbac4d,
- 0x97a8e09e, 0x58ebfe71, 0xaf425fff, 0xfe1d07bf, 0x05074c16, 0x7d04a33f,
- 0x507e2147, 0x3feb7721, 0xf00530e9, 0x4f528123, 0x8f9cf6b5, 0x840c8eb1,
- 0x07f77db7, 0xbe603bfd, 0x983e57ba, 0xf75bf285, 0xb7111872, 0x639be5f4,
- 0x17cf8f90, 0x7316f2b1, 0xc9fa7d4f, 0x3ebb7aca, 0x4b4eb187, 0x1ad5e936,
- 0xbeb237e6, 0xda974fa8, 0x14fa41f5, 0x47fba620, 0x3809fe0c, 0x994291ff,
- 0xbbbe02ad, 0xc49e1f64, 0xa569e842, 0xb3256d7d, 0x7fd807cf, 0xf00e7a8e,
- 0x4177643f, 0xcda5e10c, 0x3b58fa4a, 0x6acac8fe, 0xef4e697b, 0x1a191df3,
- 0xbb45ee5e, 0xb0673121, 0xe588497d, 0xb4572576, 0x081d28a0, 0xa317b9e7,
- 0x74b81ebc, 0x68adef2e, 0xb73a7806, 0x0f7ccdeb, 0xe639cbf0, 0x9407f65f,
- 0x6ccd4f9f, 0xa1c76a1b, 0x8aafe56f, 0x0fdbc80a, 0xffb5f046, 0xd1a3a5e0,
- 0x613f1836, 0x4f78bee7, 0xc07efe10, 0xe55e9ff4, 0x2f7c2cdf, 0x7d30fc23,
- 0x07a47f47, 0x44d9c3fb, 0x7613b41b, 0x7ce7881f, 0x3a43a890, 0xeb7a172f,
- 0x64697877, 0x2b09be60, 0x948f88ea, 0x1365ed7e, 0xf505c6f3, 0x9a237ef5,
- 0x66cbdabe, 0x5f7185e6, 0x49e2a258, 0x7d61f47f, 0x537c7f50, 0x2baf69bc,
- 0xf4323b78, 0xefda066c, 0xf9a1e1f3, 0x77188464, 0x09323ec9, 0x4609a3fd,
- 0xc4258e5f, 0x34bcc638, 0x57aebb4e, 0xa5ecba57, 0x1be1defa, 0x96ae646f,
- 0xf4347c10, 0x99c37bea, 0xd97ae407, 0xa1d90356, 0x32fe57a3, 0xf7e81f2d,
- 0x658316c1, 0xfab3e035, 0x7ed2fbd7, 0x87abf70e, 0xe8245986, 0xe5f3607f,
- 0xfc2f1f20, 0x75c4ecb5, 0x5965b07f, 0x3f683ce2, 0x01ac7e06, 0x356e1638,
- 0xadeaf5d0, 0xb3f5d2f7, 0xfe174f82, 0xea10613a, 0xd7fba3f9, 0xab3ae227,
- 0x87f6b1ff, 0x1a762fa8, 0x4286832d, 0xb243b35b, 0xc5c90697, 0x55c2a7e2,
- 0x563a9dfd, 0xd650eb8d, 0xd5d724cd, 0xa78036fb, 0xddf7562a, 0x6afd97fc,
- 0x95fc05ff, 0xf204d8aa, 0x09dd2657, 0xbc2baeeb, 0xbee27e44, 0xc7641183,
- 0xc99668ff, 0xfd0df01f, 0x02df3fcf, 0xe87f92fd, 0x0843e4ed, 0xf42d1f3e,
- 0xa4c96332, 0xbc4caa87, 0x4f5bb25f, 0x944944fe, 0xf186f84c, 0xff70d1e6,
- 0x1f78c45f, 0x37e40de8, 0x34da8f26, 0x8e8dc612, 0x13f43031, 0x78b7c5ff,
- 0x7efd0302, 0xbbfd65fb, 0x29eb411d, 0xd003cd66, 0x06622911, 0x1e8775cd,
- 0xd49897af, 0x8ce747d7, 0x6e768b3b, 0x5d7d45b4, 0x58869b91, 0x0141ffe0,
- 0xf077dffe, 0xc3c647a3, 0xc88eaafa, 0x86bb0fdc, 0xe10d797e, 0x5f9d23d7,
- 0xcf01d8ad, 0x3958151d, 0x8683e57a, 0x11abe414, 0xfd0d5b12, 0x9584ae0f,
- 0x0b879285, 0xbca36fe8, 0x80efa033, 0xda277d00, 0xa3ed5d17, 0xb11e4c38,
- 0xe11f6af4, 0xee7ae6ff, 0x11d1e5eb, 0x6bf7a46b, 0x6e56a0f5, 0x383d2fbe,
- 0x0c81e861, 0x4fb5144f, 0x4ec9fb63, 0x7ab45fae, 0x14f7ab51, 0xd6f0b4b8,
- 0xf4a9d65e, 0x1b58d0dd, 0x3de80b8d, 0x1bbde923, 0x8d1d5f18, 0x815f110d,
- 0x797c265d, 0xae29e986, 0x0de1bf03, 0xb66b971c, 0x480115c5, 0x48ec960d,
- 0xcc33e7d4, 0xee50b7ae, 0xb03b7f32, 0x1ebd8194, 0x8759a3b4, 0xe24ba37a,
- 0x106edaf4, 0x0373f62d, 0x623bcff1, 0xbcb1edfd, 0xc50ff10f, 0x8a2bd98d,
- 0xfeb07bd9, 0x84f31330, 0xf7bd91e7, 0xf302f218, 0xa2e31cbf, 0x8c458d71,
- 0xdcb19dc7, 0x601ecbef, 0x7e6059d3, 0x87592036, 0x70265af4, 0x25a576b1,
- 0x7bf813b7, 0x6a64cadd, 0xe7c45fd1, 0x68237b3c, 0xce4bef5d, 0x6b772821,
- 0x7a5a7c05, 0xfe155b64, 0xf60ff676, 0x87141687, 0x56d1d3d6, 0xe8a7ad3d,
- 0xe81919d1, 0x7edfbc6f, 0xcfea0677, 0x3f5e01f7, 0x3dbd3fda, 0x84fcebe6,
- 0x3e3c8587, 0x8c44ec28, 0x267f2388, 0xc7d804e4, 0xb5fd13b1, 0xbfba4e95,
- 0xb539656e, 0xa0ae571b, 0x59b1ddfb, 0x91e8fef4, 0x81b3fbcf, 0x641b9d7e,
- 0x8c0b03b2, 0xf0b1fece, 0x8e934ede, 0xeaf7d1e2, 0xccbb65cd, 0x5c519d78,
- 0xf1d1e0b3, 0x142e50db, 0xf563ba38, 0xd6deeeb4, 0x3ebd6d99, 0x3acb5dfd,
- 0x5d1ed1a2, 0x0077c7e5, 0x7e01893b, 0x32bb219c, 0xc71809ad, 0x38e22474,
- 0xbfefe4b7, 0xee808283, 0x956ff40c, 0xeccafff7, 0x6216b6c8, 0xa106c39c,
- 0x7044b45c, 0x7385a37b, 0xd9f395a0, 0xc13695da, 0xfda80307, 0xef61f858,
- 0xa10a9da3, 0xcf116e57, 0x6e3b361d, 0x6630f7c1, 0xd6937f26, 0xda3bfa81,
- 0x42708791, 0xf78050bc, 0xcbd52587, 0xdbf90906, 0xf80df5c2, 0x771fdca5,
- 0x2c71c48e, 0x044d21de, 0xf9130c7a, 0x05f2de9b, 0xb4de385a, 0xe6d0f972,
- 0xc9569411, 0xf95a9423, 0x6b16fe7a, 0x6c77e551, 0x2a11cc2d, 0xcad5b07f,
- 0xc3b266f5, 0x7ada4721, 0xd702bb97, 0xf3191ebb, 0xdecce524, 0x51a49a0f,
- 0x3f98ed2d, 0xaef52949, 0x634afcc2, 0x3d0e56ac, 0xc95798e1, 0x3d12e976,
- 0xefd12e30, 0x1c02322a, 0xe912625b, 0x7eac497d, 0xc0abd215, 0x1745a3a5,
- 0x4af08fec, 0x4307904a, 0x047e85f2, 0x79470d09, 0x9ae51f1b, 0x5f9df843,
- 0xc368c6bf, 0x464793fc, 0x025672fd, 0x38fe013e, 0xa422207b, 0x228f773f,
- 0x1f7152b7, 0x4f05e934, 0x050f0819, 0x1662fd4f, 0xd4f05bc2, 0x28297a1d,
- 0x6ac87f4e, 0x3d9dfc20, 0xe29338b0, 0xac6193e6, 0x79cf565f, 0x545f051b,
- 0x60bf7c09, 0xab77cd0c, 0x5baffbc5, 0x7f82774f, 0xd3d2a893, 0x8109adab,
- 0xed5d4c7c, 0xb3d3d245, 0xfc3edcac, 0xb072df4a, 0x57f3e00f, 0xf11d99f3,
- 0xad99f8be, 0xc17ba794, 0x077632d8, 0xc74ea7ae, 0xffb00f30, 0xfb07cbe0,
- 0xdf387fa0, 0x83fd1436, 0xd91fcfab, 0x7fd788de, 0x2286cd55, 0x1bbc53fe,
- 0x7c07cc25, 0xf84cde1e, 0x185b7cfa, 0x5a4b055b, 0xec65ac74, 0xb9bfa04f,
- 0xaf50c746, 0x6f0dd768, 0xb192e832, 0x237419f5, 0xff51fd38, 0xc6077429,
- 0x143d2232, 0x50fe21ba, 0xf6dfed9f, 0xc0afc112, 0x46c625b5, 0xccfc5bf8,
- 0x27c8b1ce, 0x12ac6a7d, 0xb81467e6, 0xb89dabbe, 0xf7f3f681, 0x3f666fd6,
- 0x69fa465f, 0x6ed6a7ed, 0xf63b30ce, 0x86bbfe90, 0xf8231cfd, 0x0f4237f0,
- 0x41ed98db, 0x23b253cc, 0x68f7ca3a, 0xf82a52e9, 0x7a2f2831, 0x791d7ac4,
- 0x2b5661d1, 0x179b57bd, 0x7ae46edd, 0x66cad9b4, 0x87e5094f, 0x9b757809,
- 0x17688dba, 0x90a4dbe3, 0x99a8e97a, 0x9bd025eb, 0x9f7241ff, 0x86af5a1a,
- 0xc419efc0, 0x7c3bcddb, 0x5e54717b, 0xba244e6c, 0x0fcf805d, 0x7814f854,
- 0xe0aaf054, 0x88a631b3, 0xf0bb65f8, 0x70c4b733, 0x9970297c, 0x8e7194e3,
- 0x7a5f380b, 0x0bfafa2f, 0xff806781, 0xbf1fc232, 0xeaf2a99c, 0xbe3d3e4a,
- 0x0b1923de, 0xca302cd0, 0xb9c665bf, 0x5c601956, 0x7f6648f7, 0x1531fa12,
- 0x77d42296, 0x3b7b6ad6, 0xcf1bdde6, 0xe366bcf1, 0x4d5de652, 0x7ffe30f3,
- 0xa3ca6cae, 0xe69dde22, 0x5941769e, 0x532bd81f, 0x15c1215c, 0xf635f711,
- 0x45ca06ea, 0x9337dc72, 0x10b8f48b, 0x731b7b74, 0xc7210980, 0x4379c5f7,
- 0xaf0739d0, 0xb7ce8b5f, 0xe5e57889, 0xcd472998, 0x0cb56fc2, 0x4b5dd009,
- 0xdf91becf, 0xc4f78f51, 0x09716dcb, 0x61b2f13d, 0x1e806e82, 0xec22c9d7,
- 0xa4ceeca1, 0xdf3defb8, 0x442e293f, 0x54fe1fbe, 0xab13f4fe, 0x84dfafed,
- 0x5326be70, 0x4fc4f49c, 0x27988c3b, 0x0ad2f256, 0x812feebc, 0x773f40a3,
- 0x56a3a97d, 0x26d75eb9, 0x55dc63e5, 0xf90aefb4, 0x5fed5dc7, 0xa5dc7f92,
- 0xf7958ff1, 0x89ec03de, 0x365a31f2, 0xdc5fff13, 0x9978e3c2, 0x146dfed9,
- 0x643ee1c0, 0xf11b5e60, 0xb40ff92f, 0xc45fe85e, 0x633fc716, 0xe16f78a4,
- 0xf98617e1, 0x08cc52e0, 0xe105b31d, 0xc111d62b, 0x8af8416c, 0xfaaab32b,
- 0xaa3ece09, 0xd9e549f1, 0xae29fbaa, 0xa9fbaa81, 0x7eaa79d5, 0xaaadfd7a,
- 0xb76099f1, 0x9e59fb82, 0x7df1aa71, 0xfaaaa69b, 0x56ef9afd, 0x871e678d,
- 0x39d6073f, 0xa6f3ac5f, 0xe35573cd, 0x61f24f99, 0x2081647d, 0xc7dbc7f3,
- 0xc8fac21c, 0xb88f917c, 0x3558bbd9, 0x756682df, 0x08f0815e, 0x956aab78,
- 0xb78863d8, 0xd5fbeacd, 0x531b1b6d, 0x55e45da1, 0x758c5f5f, 0x53f9090f,
- 0x3af7fd7d, 0xe3f432e7, 0xcea7197f, 0xbe935dd3, 0x45ae9b9e, 0xc70fbb5f,
- 0x7f2288ef, 0x79e1e167, 0xc9614724, 0xdb86fa6a, 0x7f16be22, 0x9aac0391,
- 0xafbff0fb, 0x5d945fc1, 0xfc5a0fcd, 0xc1f759e9, 0xceab8054, 0xac7dd92b,
- 0xb516fe27, 0xb538256e, 0xede2d3f8, 0xbcea718f, 0xd748dace, 0x971bd45e,
- 0x0ccb975a, 0xbc65f3f3, 0xf5a978fe, 0x6c4721d3, 0x7ef97941, 0x5fe5e6bd,
- 0x97910b8d, 0xcb7ac2ef, 0xd41bec2d, 0x817df65b, 0x8b030878, 0xb27a0063,
- 0xd5d37611, 0x20784afa, 0x5bd5af0f, 0xfb7a0b4a, 0xcfa4716f, 0x35a97503,
- 0x98b0f4f0, 0xaf089db7, 0xef18b752, 0xb7bc1172, 0xe1232020, 0xa75f333f,
- 0xe1e00f32, 0x7c679c3d, 0xe3123591, 0xeffb9da7, 0xb58078a1, 0x073d73c5,
- 0x1f1e0f24, 0xfe9297e4, 0xa67fc16c, 0x48fc3d90, 0x704fc3d8, 0x321ec53e,
- 0x57bf959f, 0xe6dec3d8, 0xbd16ea51, 0x995ed2b5, 0x58dd2fea, 0xcfa1097f,
- 0xd1dff18d, 0x23d27cae, 0x0f8c69ff, 0xbdee0f8e, 0x3af51074, 0x1e3c3de0,
- 0x051519d6, 0xd80a52f6, 0x8c8b7fcb, 0x3eeb7926, 0x826f7b2c, 0xb64d170b,
- 0xa06e6b18, 0x7785a2be, 0xab9ac994, 0x6de3d20f, 0x365eda92, 0x23ff71e6,
- 0x1dfb9e31, 0x2fdccc93, 0xe9d62c1d, 0xeeebf8d6, 0x82971e26, 0x05b75434,
- 0xe38381f9, 0x3bfc68a3, 0x71834511, 0x5c455b3d, 0xd12598df, 0x89251afb,
- 0x312dfaec, 0x9dff74c5, 0x6c5ca2b8, 0x0ef789fb, 0xda089f46, 0x8f0e6ce6,
- 0x5013ec4d, 0xc710ffe6, 0x4c5b6217, 0x8b78e0ed, 0x0658efc8, 0x448fbd22,
- 0xa35e6838, 0x29fcab2c, 0xe78bcda5, 0x99a7447e, 0x2a937e29, 0xe8463c7f,
- 0x8717cc31, 0x26393091, 0xe40c4e8c, 0xea3c998b, 0xe45e31b8, 0xdc7a2589,
- 0x5dbc7481, 0xbcb7b1d0, 0x658063b1, 0x4439bc3f, 0x1c97d8de, 0x1f6c6f32,
- 0x78637943, 0xd2eb8f52, 0x0e918fe6, 0x3c80d691, 0xaabf8c4c, 0xdf50d26f,
- 0x3c756634, 0xe3f91e32, 0x127f6ca8, 0x13c77f41, 0xb6e00439, 0x7c7675d9,
- 0xb616e464, 0x0bfa1c3a, 0x2fca363d, 0x8afe2019, 0xefc80bca, 0x4e2cf892,
- 0xd33e13ff, 0xfc3fb810, 0xe63b671d, 0x634ffb93, 0xcdff5456, 0x1a24b9ac,
- 0x2c2d88fd, 0x2552bc64, 0xd17c66f8, 0x3ce5195e, 0x25f81ba1, 0xe2aa3d04,
- 0xbdbf8a75, 0xbc36e900, 0xf50975db, 0x4807a289, 0xb45c6195, 0xb27e475f,
- 0xe896f9f6, 0x07c42592, 0x9279d0de, 0xe387334e, 0x29738442, 0x57783fce,
- 0xcdf51187, 0xce6f4542, 0xd03d31d7, 0xbf414ef7, 0xbaf0b73b, 0xd5f2bb34,
- 0x5fe2b257, 0xa19f9a31, 0x2d38583e, 0x87798bca, 0x1e596d85, 0x5129cb82,
- 0x76ddc55e, 0x85fd89cc, 0x8c160505, 0x657f1d73, 0xe40199d2, 0x77ae319a,
- 0xa28cecf4, 0xc67ec807, 0xaa629d53, 0xb34eabe0, 0xfd04e08d, 0xe81221bc,
- 0xaacb70b0, 0xe12fb8bd, 0x54677fad, 0x7721388f, 0xa6c9c30f, 0xe4567203,
- 0x1567ab61, 0xaf30f879, 0xf3134c77, 0xf784be78, 0x9def029a, 0xd69876de,
- 0x3cc0c273, 0xae97e026, 0xd0d9773d, 0x304c6d4f, 0x457f89d9, 0xec94eb9d,
- 0x878c807a, 0x410ebbbe, 0x6916d19b, 0x58eb0f59, 0xafdc6463, 0x11d845d5,
- 0x1dcd13ff, 0xf897e27a, 0xf1e23d6e, 0xf467410d, 0x4fcfc9ed, 0x39274460,
- 0x96e9c755, 0x44fbe369, 0xbff9d472, 0xc1dd0497, 0xebc34c6b, 0x58df2313,
- 0x7cce036e, 0xc70fd376, 0xdea247e9, 0x1679637b, 0xdd365bf4, 0xfc8f4e35,
- 0xa7c6fa9d, 0xcfea2059, 0xf7e72a6f, 0x69f1bd07, 0x6d77f436, 0xdfefc19a,
- 0x5ecfbc46, 0x38f774dc, 0x74bfebcc, 0xf9f02f55, 0x12422097, 0xc395bfae,
- 0xe2a1f574, 0x92bc5f0b, 0x7c06665f, 0x4fedb38f, 0x3aced027, 0xc3b7fa95,
- 0x237faaa0, 0xdf8098c7, 0x62be0bc6, 0x0764d1f1, 0x8dfa09c6, 0x3f68fbd7,
- 0x23e4ce8c, 0x1ac4defc, 0x8037c82c, 0xe55f4dad, 0xc07f7cf7, 0x4bf9a9ae,
- 0x02b63072, 0x2cd92de8, 0x566b27c4, 0xda385730, 0x5ddd40fd, 0xcceeebc7,
- 0xe057ef89, 0x03dfde51, 0xdead202e, 0x16d70c1a, 0xab81479a, 0x0798686b,
- 0x9fb149e5, 0x525d5c0a, 0xf498e3f7, 0x0f2fd9fe, 0x75ba404e, 0x48677545,
- 0x7090dfd0, 0x95d8e890, 0x64b8fdd0, 0x381bea0f, 0x5a6ccf1d, 0xef03ce36,
- 0xce3b28d9, 0x1986dca0, 0x2692bef9, 0x3de0538c, 0x3cb8260f, 0xbe03cf58,
- 0xef90fbb3, 0x87a48dd2, 0x79d40b4a, 0x67c16e89, 0xdeb813cb, 0x5cd61d1f,
- 0xd2f80c7f, 0xab624bbd, 0xcafbbc60, 0x89da2325, 0x8da76d89, 0x76eb680e,
- 0xbea2369d, 0xcc3ec3aa, 0x18c5b753, 0x12796f52, 0xd43f6164, 0xf481f07e,
- 0xe3c40ffe, 0x12f985be, 0xd9eee255, 0xfb1a3b1d, 0x55c1ccf7, 0xa8f77632,
- 0x5d91a39d, 0x0fed9d2a, 0x759b3b60, 0x9a16401c, 0x7e5592e1, 0x48eacce9,
- 0x595b5f95, 0xcfeaa71f, 0x80ea066e, 0x915ecf5c, 0x181f8eaa, 0xcf00abc4,
- 0x43f8160c, 0xe82e56fd, 0x83792338, 0xccadf71f, 0x1d3c1970, 0x6c4df341,
- 0x22b7a55b, 0x9d92f5dc, 0xd987afd4, 0x7c99b9f0, 0x3dead085, 0xd1b0f5c1,
- 0x51893cad, 0x7f226e57, 0x80fb02bf, 0xd91a8ad7, 0x0f10936b, 0x6eefba46,
- 0x5bbee895, 0x4b5777dc, 0xec961d4a, 0xe3016cee, 0x46c73dcc, 0xe110b6d3,
- 0xcef02bdf, 0x4b3b2f2e, 0x7afc28fc, 0x36e55d65, 0x7d70b3b0, 0x06dbfa6d,
- 0x8ff6779c, 0x45971624, 0x50eceaeb, 0xafdd51e1, 0x19f757ac, 0x9e6030eb,
- 0xf50af67a, 0xc209e1f5, 0x83620e9e, 0x25469e50, 0x2f927a48, 0xfd24ffd1,
- 0x007cd7ed, 0xf3b2e3df, 0x83e004f6, 0xea8fa31a, 0x2ecb8f50, 0xe1f72bea,
- 0xb9231d7a, 0xe4807f03, 0x5cf92258, 0x8a587063, 0x95ae8fd0, 0xb2676f88,
- 0x2b217f20, 0x72fa9e30, 0x093dfecf, 0x135a5fdc, 0xf54e5cee, 0x65923db0,
- 0xd52a5c1b, 0x07e8f43b, 0xe74291ae, 0x70259643, 0x418d7879, 0xf5700ef4,
- 0xbb452647, 0xd78c677e, 0xffedef03, 0xf41e39c7, 0x03e7fbef, 0xee50d81f,
- 0x2f19bdb9, 0xf024cdec, 0xebffd12f, 0x9394b72f, 0x68c5bf7e, 0xec2efd21,
- 0x1c2fa290, 0xa1db51bf, 0x288769f1, 0x79b498fe, 0x8bd405c3, 0x791d7d39,
- 0x07be011b, 0x1ffbf9c3, 0x71792ddc, 0xee5d4e1f, 0x499fd241, 0xdef81ec0,
- 0x47a164ba, 0xacfbd55b, 0x21af5092, 0xa5c84cc3, 0x1498a6f7, 0x1e90776e,
- 0xbac57c94, 0x497e80af, 0x69a9bde2, 0xe257c236, 0xd70916e2, 0xab3cce9d,
- 0x45cf8ed0, 0xb40c2c21, 0x97cfedd7, 0xbe7f5a4a, 0xe4f9fc9b, 0x7bc5230e,
- 0x9df8dbac, 0xe73d73f2, 0xfcd432ff, 0x53aa7cb0, 0x2bf2e207, 0xb9a798d1,
- 0xafdf4f67, 0x9b24dfdd, 0xc1b771d4, 0xc7bb8ea2, 0x9feb500f, 0xdeb57689,
- 0xafa23c99, 0xc714feea, 0x3bfdd520, 0xfd55f2cb, 0x54dbcee9, 0x2f2aefe3,
- 0x92c3f551, 0x00f269c7, 0xe44abcea, 0x255e7500, 0xa3ceaeca, 0x7dfe1d84,
- 0x317804b9, 0x2e1d3c9a, 0xc81343c0, 0xc06b08c6, 0x368a0c8e, 0x22367151,
- 0x6d8cdc3f, 0x1f30d0d3, 0x1f5349f2, 0x1d87871e, 0x07d937be, 0x766298f3,
- 0xf104b098, 0x1c5bc95b, 0x9a007307, 0xf03a9ea8, 0x39bfb57e, 0x17db8532,
- 0xb825f5a5, 0x36844f5e, 0x2a5b19f7, 0x14fd67f7, 0x1822989f, 0x345e8bf7,
- 0xc4a45f91, 0xe93ccac9, 0x50074569, 0xefdee47f, 0x6b09baa0, 0x27cc1665,
- 0x7914693e, 0xbef917d4, 0x0ed6dcdb, 0xbe48239d, 0xfae44cef, 0xe2ce17e0,
- 0x5d7f38b1, 0x9459581b, 0x1aefcda7, 0xd7593eb1, 0xf68d1ed6, 0x5df3886c,
- 0x02ebe623, 0xd39d85d7, 0x5d604777, 0x722d77e5, 0x72cafdc8, 0x1febcf22,
- 0xf2bd7a14, 0x547c40de, 0xafa02c34, 0xf5f2772b, 0x92374e55, 0x46c2c13e,
- 0x7a0dbd28, 0x2ade67ba, 0xf28c1ed8, 0x03ba803e, 0xdc6ab7f4, 0x2e3c69ec,
- 0x8dbd00aa, 0x5cfa0c72, 0x91ad3f7d, 0x73e80bf4, 0x010bf5d5, 0x15fb9e7d,
- 0x19c2773c, 0xe8f65f7a, 0x3f375e14, 0xfc212ae1, 0x88f002ff, 0x7a2ff27e,
- 0xf3e38de0, 0x167af85a, 0x37441f69, 0x2929b8ed, 0xb67c7fdc, 0x433d7d17,
- 0xc949f5d0, 0xd4ca879f, 0xbe208ced, 0x8d72699d, 0x7a47ccef, 0xf588de7c,
- 0x4bdfca89, 0xdfeced0c, 0x7ed30fda, 0x03cee33d, 0xd28fb889, 0x912072dd,
- 0x18d5df01, 0x8fd0ab6c, 0xa3b0be07, 0xead753df, 0x5b6bf823, 0x7af1dbf2,
- 0x4764ab6d, 0x75deec55, 0x93ad0c61, 0xbd623475, 0xe05ec9ef, 0x76e44cca,
- 0x8da26064, 0x985c07e7, 0xc3e7c113, 0xf9095ebc, 0xc212f400, 0xcd625bb5,
- 0x9d727fd0, 0xb79d6429, 0xff7be052, 0x57c5233a, 0xae3cf035, 0x41fa60e3,
- 0x68f909a3, 0xc24bac27, 0x1e9b1c75, 0x372ff389, 0x142ff430, 0xfba5cef8,
- 0x4ffae14f, 0x070087ce, 0x2f99afae, 0x2e4fbe13, 0x05c87917, 0x58cfea06,
- 0xdd7e2464, 0x46bdff37, 0xac9defcc, 0x4bdcfbe1, 0xf9467c16, 0x248b19be,
- 0x8a993f65, 0xd57e159f, 0x7f96a7f2, 0xf569f07b, 0x98e9f1f5, 0x3a7cabc4,
- 0xd03ced04, 0xf212747d, 0xce218fcf, 0xb2b9f946, 0xf00490cf, 0xec5a3766,
- 0xb06bafb8, 0x11207dec, 0x7e3ec4f5, 0x56cd687f, 0xdb1beb89, 0xa98728dd,
- 0x1eb6464d, 0xae44cbfd, 0xbd206697, 0xdd69710a, 0x7bc52452, 0x4bd46cfe,
- 0x0ef7ca59, 0x13be5606, 0xae7a71f3, 0x94bf066f, 0x107d75bc, 0x39129adf,
- 0x707a2abf, 0x76b99190, 0xa5bfde52, 0xe79814cf, 0xdbaf0359, 0xfaf98864,
- 0x331eedf5, 0x089fda05, 0xe027997e, 0x0af7fa50, 0xcd4f67fe, 0x344efc20,
- 0x5b8fbc71, 0x75c0abe1, 0x8b5d1934, 0x84fee112, 0xd06bb78c, 0xbf6535ce,
- 0x42f94b9a, 0xa73b2366, 0x46fbe7c4, 0x1965b07e, 0xe6fc37ac, 0xf863a208,
- 0xe4168d9e, 0x057ef0e3, 0x7c10ae49, 0xcbeeb4a7, 0x3902e636, 0x4d9cbbaa,
- 0xb29fd2ad, 0xf691acf7, 0x185db721, 0x39727243, 0xcf2bae99, 0xf9114a2d,
- 0x53dfb12a, 0x9e825fc9, 0x0bc88fd6, 0xc0f0538c, 0x215e1770, 0xd114f3c2,
- 0x3652d96b, 0x37d1a794, 0xd667fad2, 0xc0e6931c, 0x1c19773c, 0xd6167306,
- 0x77c7cacf, 0x537ee0e6, 0x71fd5cc6, 0xb9899d9f, 0xcfdfb88c, 0xcaff7d42,
- 0xb1bfea64, 0x63ed46d2, 0xd0cfe726, 0x5fdf4cde, 0x4df68fdf, 0x2cea3fa6,
- 0x1d74f786, 0xb6be0831, 0x3a94be10, 0x9936a5d0, 0xa5fee099, 0x35d5125d,
- 0x5d67f815, 0x715cc3ee, 0xdf15fd8c, 0x5da9ef07, 0x3be926f1, 0x3185f57b,
- 0xad0d1718, 0x7d88dd39, 0xc6cf8af7, 0x0a713fa0, 0xf5f907ec, 0x4b27dfe0,
- 0x198e47a8, 0xc55d7f71, 0xf3cd2b65, 0x0c7baeac, 0x15e797ca, 0xa74dea89,
- 0x93182f5a, 0x08627db8, 0x9f5816ca, 0x1895d703, 0xb771f84b, 0xfa71d50d,
- 0x4ab8f0e6, 0xc0fb43f0, 0x1e91a32f, 0xd7b615a6, 0x0fe7c36f, 0x77e50cc9,
- 0xb477717d, 0x3dfe8425, 0xfeb2f301, 0x6ad81d7c, 0x3d1b97ef, 0x5cf0ecfd,
- 0xfef42eb9, 0x9f0557a8, 0x3e29a602, 0x11293fc0, 0x55ff99e5, 0xac6292c2,
- 0x22f8f714, 0xdb2b8e40, 0xb1eace4a, 0xbbd897ad, 0xbd8c78ea, 0xf7b7e41b,
- 0xb4df87c6, 0xf4f9c3ad, 0xe201f641, 0x07e41646, 0x54c8dc61, 0xbcf0f7ef,
- 0x924e7a52, 0xaf3ac42b, 0x1f4741ca, 0xd57a0366, 0xf3ba0135, 0x5207df91,
- 0x5af77e7b, 0x298fca1b, 0xb451fba2, 0x8ebfac13, 0x8f5a8ce2, 0x93d9ffda,
- 0x4f78e5cc, 0x77eb9732, 0x12f1d513, 0xa3ef45c4, 0x145c431c, 0xa0df858d,
- 0x9d7b4978, 0xca1325e2, 0x1077bc15, 0x10f9e7d0, 0x2e4e1f70, 0x3df908fe,
- 0x9f133583, 0xe473e033, 0x3f3aed2f, 0x9153f613, 0xd72819eb, 0x5cadbfc8,
- 0x1ef3b5ae, 0x0cfa2e4f, 0xfb8759e1, 0x8de842b5, 0x6b3ac557, 0x97c23337,
- 0xf095b37b, 0x766d8e74, 0x9e5f0316, 0xfeb03803, 0x4674e5df, 0xc67d62c6,
- 0x9ab48ce5, 0x6ea07a03, 0xb73d0473, 0xdc6a672e, 0x2447e81c, 0xdf3fbe71,
- 0x3c42625a, 0xe5ccdacf, 0x29df794f, 0x94388cdf, 0xb74342a7, 0xd3f70ed1,
- 0xa3474eda, 0xfbb857df, 0xc39438ce, 0x47fce0de, 0xed775f12, 0xe3c67b8a,
- 0x87f85df7, 0xfea54cf9, 0x33ed5ee6, 0x0578dd52, 0x7f6dfe23, 0x28756ff1,
- 0x22dbe7c7, 0xcf37682d, 0xa0f489ed, 0x257aeffe, 0x2893abcc, 0x80c4f0ee,
- 0xe8673b5e, 0xe5fe4498, 0xfe82d96e, 0x8f95fb9d, 0x7479451f, 0x9e8618bf,
- 0xb6d25b1e, 0xbdda02f6, 0x67b1b69a, 0x9f6843f5, 0x1e553ff9, 0x47dc576a,
- 0xffd2917e, 0x89c9a578, 0x9ebcf47a, 0xad2589eb, 0xbbbf902f, 0x21a5cae4,
- 0xb73ef758, 0xa186bfe7, 0xf1ff735e, 0x67d430d2, 0x1a5c3fee, 0x2fddf786,
- 0xf287d645, 0xc8a55657, 0x5ec57f44, 0xabd71d66, 0x0b1f43f2, 0x686ac8fe,
- 0x9bfdc32e, 0xd9a6c785, 0xdcab7f31, 0xa3a7ec2f, 0x6f85fafd, 0x082dc695,
- 0xafc1ae7a, 0x05ebc32f, 0xe7234ac7, 0x4765f107, 0x2fc941b2, 0x075e575e,
- 0x0587eaef, 0x3afc71e5, 0x5b8c3847, 0x7df3d7e7, 0x1792d5b4, 0x5ff00be3,
- 0xdf91cfb4, 0xce28b5d4, 0x04fc9ebb, 0x05c1f8e7, 0x5f67efd8, 0x62b5436f,
- 0xe413903a, 0xebf0cd27, 0x47c0617c, 0x3e616de5, 0xfafdeff2, 0xfe17d4d3,
- 0x1f0bacd3, 0x21496544, 0xde0333f2, 0x5c7a8d18, 0xbf81a79b, 0xf15b8428,
- 0x5dea2ab7, 0x36bf08e9, 0xfcbb337f, 0x690fca0e, 0x7e5937f3, 0x01626ebd,
- 0x4d79e7d6, 0x937f9d74, 0xf145e509, 0xbb7e9143, 0x67ffc842, 0x8a7e9c49,
- 0x75f8355c, 0x7f069744, 0xda0729b1, 0x2efee2f3, 0x1df8a730, 0x9ddb4347,
- 0xd08f30db, 0x48aee570, 0x1c355dac, 0x3bf0ca9f, 0xb14b2e8e, 0x773e1fa9,
- 0xf4d30ee5, 0x68bf00dc, 0x8927b7df, 0x9f80cbeb, 0x3deeda10, 0x9ff9e427,
- 0x27b6ff65, 0xffcfcd5d, 0x20ff6d5f, 0x9499df0e, 0x4cf87140, 0x71e1279e,
- 0x286ed6b8, 0xf79958fa, 0x9ee7415d, 0xf92cf8fa, 0x932f1037, 0xc9377e3e,
- 0xdad2e346, 0x1c51c4a6, 0x9c5a7c7d, 0xfe73dccd, 0xcebb7abe, 0x7e73db9a,
- 0x7b738fc5, 0x184c071c, 0x3ef838e7, 0x8934f731, 0x7e2ad5f6, 0x9129db9f,
- 0x30aeee3f, 0x029c7178, 0xcf1a7f97, 0x18774eab, 0xc052e1bc, 0xc7fc543f,
- 0x12edf7ab, 0x49fc57dd, 0x3bf46fc5, 0x5a771e79, 0x98ffbf01, 0x093275c9,
- 0x70be41eb, 0x92385eba, 0x79cc675f, 0x77fa1520, 0x246250fd, 0x549fc2ff,
- 0x6feb54f8, 0xfbeb6c5e, 0xb7e4fbb5, 0xe454fe08, 0x1f23432c, 0x108afd8a,
- 0xfb43aa78, 0xfbf6871d, 0xae5f950b, 0xf7ec179d, 0x8e7a24b9, 0x6f05f3d1,
- 0xe2a19de9, 0xfe6295f3, 0xa0fd207f, 0x2feff34d, 0x99d37842, 0xf6b9f69f,
- 0x85bb5766, 0xfddbd37f, 0xcf286f88, 0xf89d8403, 0x4e73c967, 0x790cfff2,
- 0xf617eabe, 0xe1dd9df2, 0xc9c1a2e4, 0xdeb97f48, 0xf7f2845f, 0xfac84367,
- 0x7f8115f4, 0x7c557388, 0xa8dd207c, 0x5dc8b8c3, 0x4d03f3cd, 0x29d7b6b1,
- 0xd32c397e, 0x1025ebfe, 0xb6ffa207, 0xda85b2f8, 0xa193f41a, 0x31ccf99d,
- 0x9997ea03, 0x9bf86ad5, 0xcf8b7730, 0xa2f2cd2f, 0x4ac95cdf, 0xd954af29,
- 0xfdc16b16, 0x2d094dcc, 0x3cae5107, 0xb6db64db, 0x06ebf1e0, 0x9e26f18a,
- 0xa58eab6f, 0xe34c93fd, 0x6bd65407, 0x5fb57dfd, 0x13c89b70, 0xfc1fe6f5,
- 0xeb9c3da1, 0xc9324395, 0x97e61d79, 0xd8cc616e, 0x7b82f5c6, 0x4de53845,
- 0xb8435e30, 0x79215c3e, 0xad77004d, 0xdea1f718, 0xaa27f94f, 0xb390c1a7,
- 0x51131b6d, 0x5d43992e, 0xea7daa3f, 0xda9bd22d, 0x9775923a, 0xad5d0ba8,
- 0xb0930d1b, 0x64f10b5f, 0x3697fa12, 0x3fc464db, 0x47daa7c0, 0x1705f8a6,
- 0xf147bd0f, 0xbcddcce7, 0x7ea3d3fe, 0xd78e34d4, 0x0d3ec48f, 0x76721e6d,
- 0xa903c1e6, 0x8dd76bb6, 0x198f5aea, 0xe1e8ae30, 0x8efc687f, 0xf3ab269f,
- 0x9e7a998c, 0x936ccdc7, 0xca9f982c, 0xbe1c7814, 0xeafc822e, 0x1f9f7f31,
- 0xa140fa87, 0x1c29f9d3, 0x7e4fe7af, 0x045b445a, 0x84b7aefe, 0x70febac3,
- 0xa99bf972, 0xd9336fbc, 0x91e5b9f0, 0xdff43df4, 0xbc4489ef, 0xdc5a01fe,
- 0x09d2f997, 0xa47cc87d, 0x1fe5c294, 0x93cfe1ec, 0x2fde1ed1, 0xb07ad2f2,
- 0x7c815187, 0x9b39f68e, 0xc209ae78, 0xee63ca14, 0xa6fdf5e6, 0xea38d714,
- 0x6d9b32ff, 0x41d0ff23, 0x8017e779, 0x345f31af, 0xf58b1608, 0x5822e7e7,
- 0x9a8bd603, 0x92af5c12, 0x6752fd1c, 0xe7823943, 0xd9e4cea9, 0x88fb2369,
- 0xce7ac328, 0x2649b010, 0xf7c0d7da, 0x74140c47, 0x1638814c, 0xcd0049eb,
- 0x0f37ac34, 0x219d7512, 0xf38f4c11, 0xad70683f, 0x48eb19bf, 0x2afb7aed,
- 0xdc7b0212, 0xf59ea894, 0xebc1c925, 0x499d4ae2, 0x56f78fa9, 0x3df09267,
- 0xaf0e1f7c, 0x727d892b, 0xfd893d4a, 0xae4549d0, 0x19ea2335, 0x6949adc6,
- 0x0bedbbec, 0xf9e759eb, 0xdab9c63b, 0xc047cf3a, 0xa13f3ce3, 0x1fae2bae,
- 0xe9f13cf0, 0x0e27adb7, 0xb8376648, 0xa3f1c5fe, 0xf620bb85, 0x5bc52262,
- 0x68cff8ff, 0x976db3b2, 0x75761ec8, 0xe53f3187, 0x9e783b1d, 0xef7f8dbd,
- 0x5b7105d3, 0xbd9d9042, 0x7b5bf843, 0xff884adb, 0x234bf977, 0xb0bd7c71,
- 0x4f8eebe3, 0xd3bf13bb, 0xb4f5f8f2, 0x1e31872f, 0xebf2ed87, 0xb96fd10b,
- 0x22f97481, 0xcdfd4429, 0x93edc114, 0x4b9e8e56, 0xe7a4f9e6, 0x947f3992,
- 0x97f1e49c, 0xa3af397b, 0x705e8458, 0x0f491997, 0x944f4c1e, 0x5279fc94,
- 0xeecb3aa8, 0x951bb26e, 0x3fda248b, 0x9675dd7b, 0xb76176d6, 0xb2e9f934,
- 0x7b37a431, 0xd5075bcb, 0x33f755cd, 0xe13ec452, 0xdd7f3cc1, 0xf5a16c9c,
- 0x1687eb5a, 0xaca64ba1, 0xe1d206ff, 0x5bf7ca68, 0xf3eaed67, 0x27bfcefd,
- 0xdc9c8421, 0xfb3ff9c0, 0x4397e79e, 0x381ba7e9, 0xefc4df7f, 0xf93fff17,
- 0xf79fe79e, 0x6467e33d, 0xfff43d28, 0x6d003eea, 0x2fbb5f9d, 0x0fef5b40,
- 0x83c0bc3b, 0x1b4ad6f7, 0x9ad07dba, 0x972c5fa2, 0x63eb5540, 0x1da1329f,
- 0xd792309d, 0x9a95d6c1, 0xc0a55bbc, 0x5f0500fe, 0x1c7953a7, 0xe0bdc961,
- 0x673c0389, 0x71a5fc38, 0xc91b2798, 0x0aee0e28, 0xa630f5e7, 0xa14ca4b7,
- 0x9496f6fd, 0x9b37a0a9, 0xe95ef97a, 0x6f5f3141, 0xad3d2476, 0x214a70e8,
- 0x943c8eff, 0xea2596bf, 0xbe569652, 0x6de996df, 0xbde95329, 0x87f414b6,
- 0xebf3f662, 0xd8e63ed1, 0xb2d9704a, 0x683c52a6, 0x1ef842cb, 0xeb5ef511,
- 0x9859feb8, 0x5f82b68f, 0x8dc0f588, 0x78a41758, 0x94e342d6, 0xc3eccdf7,
- 0xc0c47de1, 0x7adfac24, 0x99fbe66e, 0x5542f358, 0xc188ef3d, 0xa24739d7,
- 0xea275e7a, 0x5f3aa3eb, 0x825993ee, 0xb9bf0189, 0x67542cbb, 0xffe46d7c,
- 0x5bbfc01e, 0x65bdf5e2, 0x1f643e16, 0xc700cdc6, 0xc4f93db2, 0x8ef733bf,
- 0xc6054bfc, 0x1cfc391d, 0xa5711e90, 0x109c17c8, 0x5f250ef9, 0xdeb5d4a0,
- 0x53927911, 0xb6817f98, 0xd021f303, 0x37747d4a, 0xa1493eda, 0x1223c7ec,
- 0x8e790fcf, 0xbe50fcf2, 0x7837ded1, 0xc0b464df, 0xaf1f1ceb, 0x9ef9285b,
- 0xf93d62ed, 0x617d963f, 0x37e697e0, 0x9da2360e, 0x8f4c6fcf, 0xc38876c0,
- 0xef12c3ab, 0x753bf98c, 0xf142fd0a, 0xee1f7251, 0xd43bac8f, 0x17bd754d,
- 0x99fe7534, 0xff748c7d, 0x99c7e0b8, 0x97f5187d, 0x41afd3f5, 0x946631f7,
- 0x4f550e45, 0x18b884aa, 0xc4d39ce1, 0x5df056e1, 0xe095b3e9, 0xe81f4e7b,
- 0xaf36c46e, 0xf284ab3a, 0x1a1735ed, 0x5f737fd1, 0x76f074b9, 0x6d1997ca,
- 0xeacc4f18, 0x2edde750, 0x96fdf2a5, 0x7bfc482f, 0x3d58cf4c, 0x63f9c7c5,
- 0xd63fc4f5, 0x5f8a70ca, 0x9b2606ad, 0xfb853fb1, 0xf1657945, 0xd367d825,
- 0xcc1fc962, 0x5d8b643b, 0x83c81b90, 0x4f2ec759, 0xab5d3c40, 0xd3e4aabe,
- 0x4639331e, 0x6dbf3d22, 0xc8f6b57d, 0xaa57da71, 0x8bc14bac, 0xaded2752,
- 0x73ecaabe, 0xaa7d9770, 0xd6e197da, 0xfcc18f77, 0xd39efe63, 0xd2cfb146,
- 0xa8159c92, 0xbeefe6bf, 0xa5577540, 0xbfaeeace, 0x3c357e40, 0xe490e747,
- 0x4053f903, 0xc95aee4f, 0x022fafeb, 0xc2b6d83c, 0xd7001dfa, 0x6c7eb0cb,
- 0x78fd60db, 0x039595fd, 0xb4adf5a8, 0xe577bb53, 0x6ddd6a08, 0xeb5ea817,
- 0x7f63d3ea, 0x1ef3d524, 0xfaf39d97, 0x5247f7a8, 0x93ef5b5f, 0xc6be7823,
- 0xdf40c87d, 0x988fb82b, 0xb5177f48, 0xf8c4c9cd, 0xae63f3e0, 0x0ebb844c,
- 0x7c416deb, 0x0f61de71, 0xce3173c7, 0x58e1ed3b, 0x3f6fcb67, 0x2ffdc46b,
- 0x11bf7a75, 0x710061f3, 0x744d6e2a, 0xf7c0baef, 0x8515b6f7, 0x59af7e23,
- 0xfffd6b17, 0x536fb175, 0x202afb17, 0xf247a49f, 0x56c73a9c, 0xc2390f6c,
- 0x89e90417, 0x4f5e4e75, 0x4d939759, 0x99c9b872, 0x683f3b1d, 0x9e3286be,
- 0xcd8eb0bf, 0x3ebe0f09, 0xf340cd35, 0xa09cf15b, 0x156fef10, 0xea06ecfa,
- 0x213ed6ed, 0x47f3b6fc, 0x48ddf44d, 0x9985eefb, 0xea5fc41d, 0xb2badc7c,
- 0xfdf899f9, 0x1844e7bd, 0x75f3c7eb, 0xd31c7caa, 0xcb7ae3d4, 0xd32ccdcb,
- 0xce29c239, 0xbb40ceea, 0x319bcdad, 0xb706777d, 0x7e548eeb, 0x9527835e,
- 0xea3d608d, 0xde657f72, 0xfc6072b7, 0xd91d328c, 0x973ea50b, 0x2b67a657,
- 0x56f33f81, 0x9754bc18, 0xa69fd32b, 0x6c6e22fb, 0x22a5e4b0, 0x623a9f9f,
- 0x57da84b4, 0xaa7b2f6d, 0xb79e1b29, 0x5c7648d7, 0x77eab5d6, 0xa3edad95,
- 0x16fd6953, 0xf124e519, 0x53efa320, 0xf8f3d67b, 0xd63cef7e, 0xe30a54dc,
- 0x82ce8e58, 0x679b51f6, 0xbf433e43, 0xef879b44, 0x4bbbf612, 0x48c1cfd8,
- 0x8f9c04db, 0x73ca4bfb, 0x4d29fe5a, 0xaf36be95, 0xfdca905f, 0xbcb286aa,
- 0xdf483975, 0xf6863a09, 0xd8aca1a4, 0x9f341394, 0xe34f552e, 0x60fac11e,
- 0x907d707c, 0x75b501d7, 0xe5cf4541, 0x06317fb7, 0xf409bdf1, 0x7731da35,
- 0xe41faf32, 0x087452bf, 0x4e0046f5, 0xc94dbebe, 0x8eb7bf57, 0x0c5d7c65,
- 0xf679cbf7, 0xcb9f9448, 0xdee9f09b, 0x139fc448, 0xb5ea1eec, 0xcc6b3923,
- 0xe8268fa8, 0x1dfbf10b, 0x5aba53b7, 0xd27ac267, 0x8f57af9d, 0xf209efc3,
- 0x863d0fa7, 0x615e9f78, 0x7780fda0, 0x063e5ebe, 0x2ff62baf, 0xd5d6fa7f,
- 0x807f7811, 0xe1b70f64, 0xbc62b2fd, 0x0f877e3f, 0x226ce933, 0xdcfa0742,
- 0x8f53a47f, 0xc998f372, 0xf00a9d95, 0x75114fe6, 0xa76e0aa6, 0x314db7a7,
- 0xaa4fee30, 0xf4bee6ec, 0x741f29cf, 0xea9f2da9, 0xefb87147, 0xaf603721,
- 0x1d80f7f2, 0xb1d80a8b, 0x4abf6aef, 0xcf842d53, 0x218ec05b, 0xbc29d63c,
- 0xbfa5af3e, 0x37bfd04e, 0x1e9bd4bb, 0xe783fb46, 0x4a7ca0a8, 0xb8ed3dc9,
- 0xc33ef30d, 0xf0975fd1, 0xf95e9590, 0x6fd0a96f, 0x73f8bdb1, 0x7af80af7,
- 0xfad537dd, 0x2d33a9cf, 0x521ffd4d, 0x97f11267, 0xe2526f52, 0x9e04d7b5,
- 0xa175f695, 0x77f3be37, 0x435c680c, 0x0d60c77e, 0xacc31dfd, 0x44873a16,
- 0x80e18ef9, 0x8ced1591, 0xe2b3fdc7, 0x93af26bb, 0x8f03a4fc, 0x37f1b5fd,
- 0x935df8f1, 0x80672784, 0x76463c3d, 0xae8f395e, 0x9e63edae, 0xfbe16d6f,
- 0x435b6bc0, 0x9912eb9f, 0x297bedc6, 0x33ea87ac, 0x98ed7f62, 0xe44ea25d,
- 0x596d7a30, 0x4fbcb798, 0x74b79c1f, 0xca09fcdb, 0xc52f5dbe, 0x663cea7b,
- 0x3acb796f, 0x6afc3be5, 0xd1df8ec9, 0xd31e775c, 0x7ee1f7c1, 0x4be63cdb,
- 0xce3aeaa9, 0xad0b1481, 0xd125dcbf, 0x9d264cb9, 0xe7f686b3, 0x425922bf,
- 0x9a3eebed, 0xbc75e5ca, 0x6d3c83a8, 0xf4f1fce4, 0x8bed12ad, 0x90edefc7,
- 0xc2bf4fee, 0x3a79b7bf, 0xa36f7f8f, 0xef943dd4, 0xd40e6e68, 0x3b3be83d,
- 0xe51bfbe5, 0xfbe51a7b, 0x239b29cd, 0x07e23ce8, 0xdcc92d0d, 0x5f10f5ef,
- 0xf61e2bfe, 0x30d0f580, 0x5e4a1f56, 0xfd16a777, 0xbb8d2a6b, 0x476f71e1,
- 0x29ff086a, 0x7848e309, 0x5ed499cf, 0xa9b385e3, 0xfa8178ea, 0x46e178da,
- 0x4bee3dd5, 0xdd7a3765, 0x8df94203, 0x2dfe7037, 0x9bfcf3df, 0x4d6dd143,
- 0x15f3e878, 0x1d44d32b, 0x380e735d, 0x245df1eb, 0x924debb7, 0x51b72fed,
- 0xf540dd3d, 0x36af4574, 0x73f9f145, 0x7b4a7cc5, 0xb3d71a47, 0xf9d0864d,
- 0xdc62a9b2, 0x2831d946, 0xcf41da0d, 0x8397f3a8, 0xcbf9d45b, 0xe7d55a5b,
- 0xa9f50c85, 0x3fc903cf, 0xa61f3ea4, 0x1f3eafd0, 0xf509f866, 0x3b2330f9,
- 0xdcc3e7d4, 0x7cfaa1f6, 0xab741f98, 0x5fb797f3, 0x5ef9aa9e, 0x77cfcbd3,
- 0x7e0dce02, 0x4f34c4ae, 0x4e8d2e73, 0x844d2e73, 0xcd1a5ce6, 0xde622839,
- 0xcd1f4f2c, 0xf5ea34f9, 0x971eb159, 0xb8f5fd7b, 0x44d8fa67, 0x386fae3d,
- 0x5948f73e, 0x6dfa384e, 0xffd377ca, 0x97ccf821, 0xf48b9ae6, 0x5b1ead71,
- 0xb1d57c87, 0xf3032c2a, 0x29d5ae2e, 0x83f03c72, 0xbe8921eb, 0x9d5e2f9b,
- 0xe67bfb42, 0x3f250c35, 0xc8398f29, 0x638caa4f, 0x5873cf21, 0xd6f5c69f,
- 0x33037adc, 0x6ccbe0c6, 0xd0a81d46, 0x5b124d73, 0x798dedcf, 0x3561f022,
- 0xbb587ce3, 0xd53458ee, 0x59dd85bd, 0xaac151c4, 0xb9d217eb, 0x5d73da0d,
- 0x318b586a, 0xbc59e605, 0x41e49da1, 0x628bce7b, 0x9e62dc87, 0x7df516da,
- 0x8170db37, 0x1d6789ce, 0xee33b446, 0x86fdf556, 0xb32f5134, 0x8dca3b33,
- 0x1328beeb, 0x02c597fa, 0x4836732f, 0xce0fac16, 0xb84f686b, 0x0ef3fa0b,
- 0x296f14c9, 0xce3d6178, 0x73a5c9e1, 0xea1e2fd2, 0x45f3fe47, 0xc7092d9b,
- 0xbc79a2b9, 0xc35de920, 0x9c657af1, 0x5f9e386b, 0x0a327dd6, 0xa761f1bf,
- 0x5fc8eb2f, 0x08681f00, 0x36166df9, 0x3bcf3824, 0xc44960c7, 0xdd878b3c,
- 0xa6714c93, 0x75957b88, 0xc7104dbb, 0xe21f6346, 0xe93ebe54, 0x46e8892b,
- 0xfc1bad26, 0xf80f7c22, 0x9ac7143f, 0xfa156998, 0xcd6d673f, 0x3afae889,
- 0x5f90301f, 0x2c477731, 0x1b7315f9, 0xfe788c4a, 0xb15ddcc1, 0x79967fb4,
- 0xae31c71c, 0xba78e855, 0x3260ff21, 0x25b73bcc, 0xe9ab2ecb, 0x17138aa7,
- 0xe8569d37, 0xba0d79d6, 0x1ba28675, 0xfd754bd0, 0x17e134e5, 0xfbb17a08,
- 0xbdfbe8e3, 0xfa07a58a, 0x62efbe61, 0x0efd387d, 0xc038cf45, 0x5a64f5c3,
- 0x29de2abc, 0x8e3573eb, 0x2fba73a3, 0xba24286d, 0xf655e969, 0xe386f3df,
- 0xafec55f7, 0x8dfd0c51, 0xf66cbeca, 0x5b3eb854, 0xb955f2e2, 0xfa196c66,
- 0x7d0a6f39, 0x8b88baf8, 0x045c618e, 0x189bfc7e, 0x2dff4117, 0x05fd1711,
- 0x4f6822e3, 0x6d045c62, 0x4fff38a7, 0x00603391, 0x4293d7e2, 0xd55e4ebe,
- 0x3193cbf3, 0xdff6569f, 0x80ea166f, 0xb53c12e7, 0x33a74693, 0xf6a1d936,
- 0xa9a7cba7, 0x830ee9fd, 0xed324c65, 0x81f5e26b, 0x54dbceb9, 0x66de99e3,
- 0x1b073cc4, 0x4eb81f90, 0xc466c7f6, 0x098cc73c, 0x3ff1aa71, 0xf5554a6c,
- 0x0c5fa02f, 0xeb294df0, 0x777ebaab, 0x7f5520c5, 0x424065ce, 0x95af723e,
- 0xe22ce79f, 0x2794ca24, 0x9f0dea06, 0xfa4f0fd6, 0xe9fbc011, 0xd7dd0311,
- 0xeba143d2, 0xca3acdfc, 0x0cdbcedf, 0x3b79836b, 0x5c91e79b, 0x8a227c7d,
- 0xdc6987ce, 0x08daff91, 0x61de9fe8, 0xa764fda0, 0xc21ee21b, 0xef4faaf3,
- 0xefc68848, 0x328d5cf2, 0xb59e91f3, 0xe6559e90, 0x4558692d, 0xc7307fbf,
- 0xf947661b, 0xf3dfb39f, 0xfdc7d2b8, 0x0645b401, 0xecb8e3e5, 0x3f4449f5,
- 0x7b77e107, 0x3fc5e538, 0x058f3034, 0x1d79cbfc, 0x250fae1c, 0xb3fd80d6,
- 0xfff4efe1, 0x6e71c011, 0x0e957362, 0x48f928fd, 0xe7cbe902, 0x5b7c8665,
- 0xe740d4b1, 0x4b7a2f09, 0x267d8ade, 0x7a72a5e5, 0x1d3bf4cb, 0xcd187b6c,
- 0x4381bacf, 0xdff2dc60, 0x5eb93d84, 0xffa8b9e4, 0xf5dec1fb, 0x8f913f82,
- 0x8e658c3e, 0xe7960258, 0x963a3e1b, 0x009e7540, 0x7043bd3e, 0x3bd4bfdd,
- 0xbd83a5fb, 0x3bcaa8fa, 0xfddaf484, 0x5a572409, 0xb91a77bc, 0x1ca0f2de,
- 0x197d0148, 0x9dfe3390, 0x3d833cd5, 0xaafa4ed1, 0x55f50520, 0xe50306e7,
- 0x11de9915, 0xcf70ebcd, 0xef2b1f13, 0xc6dbd4e9, 0x4d9d7c20, 0xe11df459,
- 0xd9320ddc, 0x3e3fe43b, 0xebe3cbde, 0xe30bb28d, 0xe4934f75, 0xcb5d78c2,
- 0x0e96cb37, 0x9815dfa7, 0xd9193885, 0x4f9c0f53, 0xa50775e1, 0x3f0f78bf,
- 0x74159fd7, 0x0e0da7e8, 0x7f03475e, 0x5f9f325f, 0x26bc7739, 0xf0a74ffb,
- 0x878ba668, 0xf7e0c6fa, 0xcb8f6738, 0xb36767c4, 0x0325879b, 0xedd13f3d,
- 0xe823f61d, 0x73d13c7f, 0x70fd8f46, 0xebc454d7, 0x0c86dd12, 0xabba1efc,
- 0x6e87bded, 0x7a3ee783, 0x312760d6, 0xfa40915f, 0x45f6f163, 0x7df75f99,
- 0x3ef05810, 0x48e8cf3c, 0x4b9f0091, 0x30632d6c, 0x3980b07f, 0xf8e21d85,
- 0x79e0edb1, 0x9e26cb0c, 0x30af78d7, 0x67ee3d6a, 0x5bc9a79b, 0x13be27bc,
- 0xa92e905c, 0xa2ed84fc, 0xf9c74f3f, 0xf3c73d9b, 0xd2a7f059, 0xfbf16eff,
- 0x57de8a1e, 0x6b0d75f4, 0x7fa9f3a6, 0xf04d9e94, 0x34bc922c, 0x9a4f0eae,
- 0x65551506, 0xcd6af1e1, 0x8a5e6133, 0xe9606d47, 0xdd80fc82, 0x6e7a36e9,
- 0x47d9f1b1, 0x32176d91, 0x669f5f3f, 0x6f0647dc, 0xa7ab3f95, 0x6cb2a9bd,
- 0xfcd2b06d, 0x57ee3b06, 0xb4e4285c, 0xfaf259b6, 0x6ec83af8, 0x2cf3102e,
- 0x6b537610, 0x23d87a9f, 0xa05a1d8d, 0x59acb3b1, 0x5e01576d, 0x815b973a,
- 0x33a70b57, 0xb0f08a32, 0xcf9f99b8, 0x1ef2e551, 0x4b70449c, 0x0f64a076,
- 0x67321678, 0xe3ae2c69, 0x6b8f1e19, 0xabaed3e1, 0x9d62bc07, 0xecabb85a,
- 0x01727c17, 0xda0a3dff, 0x8759a9df, 0xbfad0f42, 0xcaa5d0a6, 0xd55bf1c3,
- 0xdf3d1126, 0x3207eabf, 0xf0aa07da, 0xff816b0b, 0x4e779ea9, 0x70b67d42,
- 0xacdfe813, 0xfc28ff00, 0x44b598b4, 0x31d4bf23, 0xd496235f, 0x7e5afacf,
- 0xcf0b3238, 0xe7463a65, 0x7d585547, 0x80b174fd, 0x1fdfcf42, 0x8041fb2a,
- 0xbe78b5af, 0x17af5d16, 0x11d44c6f, 0xd3c039e8, 0xfa64a782, 0x9c6827ae,
- 0x243d7f88, 0x8f1ed54f, 0xd5cbeb11, 0xdc3e7e7a, 0xeb74e0b5, 0x5d29eff9,
- 0xfc5ede13, 0xf70aefa4, 0xf9bde907, 0x4262fd59, 0x9d6529e9, 0x72bd08ef,
- 0xb7aefb4d, 0xbec8c5df, 0x8f984827, 0x575f4de9, 0x00bebb09, 0x67b43ced,
- 0xe740bf36, 0xe9bfbe2e, 0xd55f3a05, 0xda02ecf8, 0xf3667097, 0xf7f087bc,
- 0x98ecce23, 0xe17d7647, 0x775d8a63, 0x85fd8319, 0x9e73cd92, 0xafc85ff8,
- 0xdd5384cf, 0x4bbf6ab8, 0x47a039c4, 0x336d9c61, 0x136c9bd7, 0xd10ba3d7,
- 0xfd92e5fe, 0xddc709bb, 0x09bae557, 0x3ae83ef9, 0xe6fbc5d9, 0x07b77eb9,
- 0xb7efbde6, 0x2d0f7691, 0x79e3e2d9, 0xed0f8b67, 0x7f3ded5f, 0x0bbf4539,
- 0xeb791f25, 0x87bd8ac7, 0x577aedee, 0x97ca0642, 0xf2b5f3b0, 0xfa0b0cd6,
- 0xfc2ec205, 0x173df1b3, 0x14fe4df1, 0x4dbbf7c7, 0x6defcf1c, 0xdc6f78e0,
- 0xd3e297d1, 0x92fa9b77, 0x8eeef51f, 0xf9ef847e, 0xe4df01eb, 0x7ed4db47,
- 0x1be01354, 0x37c404e3, 0xbf7735c0, 0xcedbe04d, 0xf1c4ddf1, 0x76f036cc,
- 0x7abc0f7e, 0xfbf4fce8, 0x8ecc3dfe, 0xe187c17e, 0x3e97f23e, 0x99d329dc,
- 0xa59f8a67, 0xb19f39f8, 0x1fd1c7e6, 0xa8bdf053, 0xea087fbf, 0x7f8d8a97,
- 0x2fbc468a, 0x2393c9da, 0x1ccdf03d, 0x076fe849, 0x2fd57fde, 0x0848cb2a,
- 0x21be8bf2, 0x9398ea5d, 0xe1d723f6, 0x82436479, 0xbf2b3df6, 0xe7dda65b,
- 0xc8f9e36c, 0x99376630, 0xed349e10, 0x18b9afef, 0xbcfe7bee, 0xf75985df,
- 0xab771c90, 0x12634f7e, 0x9cf019f3, 0xd122d602, 0xe5da967e, 0x188ba34b,
- 0x4f5a3f9e, 0xe0cdac70, 0xbc2bbd76, 0xb2fc833b, 0xef1c613d, 0xf3aaf19d,
- 0x6fdd2789, 0xb457f98f, 0xf9f847fb, 0x763c93c4, 0x1a4e67ca, 0x2ab93431,
- 0x2e0bae88, 0xab8973f3, 0xf2e6032e, 0xc6fdf7f1, 0x0587bed2, 0xcea853cd,
- 0x496d055f, 0xbe5ef8f0, 0xc19b5bbf, 0xb8539be3, 0x973c3ca6, 0x9d7efc49,
- 0xea8d1738, 0x539b80b4, 0x373a4ee1, 0xc98254ef, 0x8bbacfce, 0xeffdf3a1,
- 0xa6707a16, 0x13ed20f9, 0xcc3c7987, 0xbfd6e78a, 0xab014069, 0x8b3c7530,
- 0xe4ecf021, 0xe935eef7, 0x837f6b70, 0x7773e445, 0x13d7157d, 0xd51d009e,
- 0x23b9b9e7, 0x9a3fe742, 0x87255e05, 0x610cea83, 0xbc047730, 0x3619e7ff,
- 0x6fec5d7e, 0x9e805b67, 0x85cf3d51, 0x0f33ae53, 0xa6b60f3f, 0x2b7dfe18,
- 0x7a848ce3, 0xfaa9d643, 0x7f7e4635, 0xc9c4c67b, 0xf631469b, 0xf7ac0306,
- 0xf194bf45, 0x8c4e7f38, 0x4d75f717, 0xaca373c6, 0xaf89ead8, 0x4799eaa6,
- 0x3326dbc7, 0x79c43bd6, 0xfe049351, 0xbe608fa6, 0xdf7de018, 0x89b9f561,
- 0xbe74f977, 0x93af009b, 0x21ba5cf1, 0xcd9cfe78, 0x38f78160, 0x8c3ca4cb,
- 0x7f566a4f, 0x64f77833, 0x94de4f94, 0x8e9d7d06, 0x9e63f9c3, 0xf989988f,
- 0x2cc3c079, 0xe72fdb3d, 0x5e237a71, 0xed1b56dc, 0x2a5ee8f3, 0x25147ed1,
- 0x7bd0af2f, 0x4f2f2068, 0xe0299c74, 0xa29a7983, 0x686379f1, 0x50ce1d7a,
- 0x8a16e8e2, 0xf90897af, 0xe5c8a25c, 0x9e5cb50e, 0x7e823a45, 0xc8893dc6,
- 0x0b453357, 0x6bf9a4eb, 0x73947bc4, 0xf064cfd3, 0x0c99e97c, 0xfe387f5e,
- 0xccc7df2d, 0x45469cfc, 0xf8c36b3e, 0x27fbcafc, 0xc333b68b, 0xf02bf34a,
- 0x1ff1f368, 0x7e43596c, 0xccb7f552, 0x1be907c7, 0xc6497baa, 0x7a88f9ee,
- 0x49c25fe9, 0x5b1a66ee, 0x7b9bd5fa, 0x1dce538e, 0x037e60ac, 0x55300faf,
- 0x6cb4741d, 0x2b2c73a6, 0x9afbfe24, 0x1e51455d, 0x6be60c5d, 0x8ada440c,
- 0xe973f31f, 0xfbe709de, 0xee632b3b, 0x607e849b, 0x4f51b445, 0x7f31ece7,
- 0x40565654, 0xc91636ef, 0x04214e74, 0x6eb19382, 0x7feb06b6, 0x23b0ffbc,
- 0xa24bb28d, 0x51d7b3ff, 0x02bb4d1f, 0x43fea7f4, 0x0f101d93, 0xf7101d75,
- 0x7cf4c3d9, 0x8f8203d7, 0xfde73f3d, 0x37f7285f, 0xe53afef3, 0xffde16fe,
- 0xe8bf3299, 0x5fdcd46f, 0x4bffb9a5, 0x627c4fde, 0xfa0f64cb, 0xa59cc5af,
- 0xe8956e2b, 0x05ca3577, 0xf6ac559f, 0x742b7e11, 0xcc5b797b, 0x6b82ba7c,
- 0x74ce2b8f, 0x211fa396, 0xa1467547, 0xe5909e9d, 0x75bb4728, 0x2b2bba6b,
- 0x53c5da13, 0xd6118f24, 0xc97b8ecd, 0x45ea4c6e, 0xbe0b971f, 0xf9f1b22d,
- 0x3cc37c14, 0xbf0b3303, 0x847e3cfd, 0x4f35412b, 0xf3c0f5fe, 0x798f5b6b,
- 0x3ccf5d46, 0xbaf52cba, 0x89e83f14, 0x385dc76c, 0x2e1ed69f, 0x063da9f9,
- 0x35ec50f3, 0xeae1fdf1, 0x987c8c96, 0xbb73c97f, 0xefd0aa33, 0x1d40fe12,
- 0x3c7cc3da, 0xc3db82e7, 0xf24fdb8f, 0xdabb707d, 0xbf30638d, 0x3db06d0f,
- 0xce05e9ac, 0xd89d4c8a, 0xd791b047, 0xab3b9ec5, 0xd12e7a47, 0x0c799cb5,
- 0x52adfbed, 0x1127dfe8, 0xe5ea9dcf, 0x66e68e77, 0x90d43d72, 0xeb8398e3,
- 0x3464c92c, 0xe84d64be, 0x9b7f9a73, 0x8572edc9, 0x86f37bb0, 0x806c9945,
- 0xaee3c2e7, 0xaabfb835, 0x1e564b6a, 0xa56785e6, 0xfcc92f17, 0x376abcda,
- 0xf1b6abcf, 0xd5856abc, 0x37941cbf, 0xedb33a7b, 0x633a5361, 0x914dffe3,
- 0x78591033, 0xe94c2cb6, 0x74b939bf, 0x617bcf14, 0x4713dd7f, 0x39b9461e,
- 0xfe60f084, 0x08e0f87c, 0x591d0bd4, 0xe80b3a91, 0x7369598b, 0xacfe469e,
- 0xda03fe1c, 0x1614532f, 0xcf0e7fd5, 0xcc5f13cf, 0x42ae734a, 0xe63c7138,
- 0x5f465c43, 0x0eb05dc2, 0xed32abd7, 0x890d7553, 0x4efc8574, 0xe9e1e059,
- 0xebe10b4c, 0xfd199010, 0xe50e0514, 0x2fe7e0fd, 0x9d7cc3f7, 0xe28653ab,
- 0xb4be4e77, 0x85996da2, 0xd2fbf781, 0xbf048f5c, 0xfac753bf, 0x4df1a863,
- 0xc05878e1, 0x06e90db1, 0xcc9473ad, 0xdef1411c, 0x5548d2d4, 0x3884da7f,
- 0xd7ce08e6, 0xf5554b4e, 0xaafa2bcb, 0x7f3ddfc6, 0xc4feea90, 0x7d417f30,
- 0xbbdbbf90, 0xe7e1e49f, 0x4545458f, 0xbfbcbee0, 0x36f67db7, 0xd7745efe,
- 0x7d1db253, 0xb67b45da, 0x03478dbd, 0xb39fc45f, 0x8da43ca0, 0x1d1f66f2,
- 0xd73f1992, 0xae0fa1c2, 0xfe639d0f, 0x1077f147, 0x2907ab7a, 0xcb12eef1,
- 0x801dfa7e, 0x3a0f5d1b, 0x41ea2998, 0xed0f2c79, 0xb7fac5e1, 0x67576f28,
- 0xb73bebe6, 0x8b4f9f9b, 0x057f53e7, 0x3e077efc, 0x65e1fe88, 0x4bb5e50f,
- 0xfd534f5a, 0xeb932aac, 0xa5b4bae9, 0xdd8bf47a, 0x181da2d0, 0x062afa03,
- 0xcedfc5f8, 0x7dc2ef06, 0xdc51596c, 0x953cbf5f, 0x2be438b1, 0x9439e79e,
- 0x53bf4b18, 0x8ca9a4bc, 0x8e5dd7ae, 0x975ff9a0, 0xcd4fb4fd, 0x754492f3,
- 0x95a98988, 0xc6bf71ab, 0xee4f08a1, 0xc4ef7832, 0x8651dddf, 0xc5dbab78,
- 0x944c91f7, 0x0a5828df, 0x19734d6d, 0x66513f3d, 0x17f02487, 0xfb7097c6,
- 0xbe6d113b, 0x46e0f715, 0x2bbb47ad, 0x7ffd7d1b, 0x18c67a85, 0xe6267a45,
- 0x7ef4ddf2, 0x3d1365f7, 0x88f425df, 0x35c383a1, 0xae93b2fa, 0x59f0fc2b,
- 0x77eab666, 0x4f090c7f, 0x91f7f1e9, 0xc68c1d0d, 0x903cbb8f, 0xafbd655a,
- 0xfa77f80e, 0xc2435b5d, 0xfa5fb4a7, 0x42c978d5, 0x0f46886e, 0x1e1faa5f,
- 0xa9e842c3, 0xf111efab, 0x5fea1848, 0x72ccbf68, 0x3012da44, 0x63d0e99e,
- 0x4d99885d, 0xffe44fb4, 0x0538cd00, 0x00800076, 0x00000000, 0x00088b1f,
- 0x00000000, 0x7dc5ff00, 0xd554780b, 0x399ef0b5, 0x66491e67, 0x99212726,
- 0x4ce21024, 0xe010245e, 0x0f080424, 0x860240cb, 0x084013a7, 0xbc80e834,
- 0x2b101025, 0x0337e95e, 0x60d22049, 0x45405283, 0x68b0503b, 0xaaf8ff6d,
- 0x0131f5a9, 0xe94a0fe4, 0x7ab7bd60, 0x52036b6f, 0xe08d4504, 0xb16dcfed,
- 0xbdad6bfe, 0x3267324f, 0xfdeded41, 0xbe3ef9ff, 0x3ef6759d, 0x7af6b1fb,
- 0xb30fb5ef, 0xcb5d8aca, 0x0afb188b, 0x9318137f, 0xbb302e8e, 0xda663286,
- 0xb1ecc67d, 0xb2816631, 0x96bea23c, 0x046b4f31, 0x2e4995ac, 0x19236323,
- 0x3950b6fc, 0xfbc1db0b, 0x631f77cc, 0x576ec64e, 0x4a6dff18, 0xb1832c65,
- 0xed04dfbf, 0x0fde7b53, 0x852ea01b, 0x968bc0b1, 0xbbf861e0, 0xc72fb65f,
- 0x89e1f505, 0xec39faac, 0x55670e47, 0xcddfa1d9, 0xda15b29d, 0x39559b31,
- 0x9ff806ec, 0x6f82ff34, 0x8ba77f39, 0x12b7ffcf, 0xfdfd84db, 0xb084c276,
- 0x7ed5e607, 0x921188ff, 0x31dfa7ab, 0x63b5332e, 0x5675d74a, 0xd7bad8ca,
- 0x603b5c12, 0xc1fb337d, 0x5ebb8033, 0xba0f04b5, 0xa43339e9, 0x68396960,
- 0x8e75fa80, 0x8c2f7cae, 0x5c7afe5f, 0x7e830d88, 0x19938f5f, 0xae52f38c,
- 0xa5e20c6f, 0x1541f5fc, 0xf24c0706, 0xa0cc8b15, 0x3c9ba4dd, 0x5f79f163,
- 0xaf5e8df3, 0xf9c60256, 0x18a7cefc, 0xadbbbdf1, 0x5529b5fc, 0x22624086,
- 0xc954d774, 0x16c608d8, 0x9b0d9b5f, 0x6b92d8c2, 0x5afb04f1, 0x75abf3f8,
- 0xdf705369, 0x49866eae, 0x6c963ac3, 0x017d0c36, 0x765cc5d6, 0x30f00f35,
- 0xada2c073, 0x5339e60c, 0x677ad232, 0xd60a490e, 0x71dbd343, 0x73e0c7bf,
- 0x664861d6, 0x3db97a6c, 0xd6f18460, 0xdfa8535c, 0x1a2e6bda, 0x64b5ed6f,
- 0xb35dd782, 0xdae4b952, 0xb96e7a60, 0x801e6466, 0x1c035e97, 0xdb273c00,
- 0x3fd70ab7, 0x4a96feb3, 0x35b7cf1c, 0x8b67d4a3, 0x82b317a4, 0x92f40574,
- 0xb3d6dcbe, 0x05f6fafe, 0x2fe85530, 0xb2f44bc5, 0x88f2ca14, 0x0e8265fa,
- 0x56b6f1a2, 0xa537ffec, 0x5f411a97, 0x3ca16c4b, 0x54c1e023, 0x856ea717,
- 0x71495cf9, 0x6cbc414d, 0x6fe38078, 0x6e5bc983, 0x786ef987, 0xcec2a0c4,
- 0xd9473bb0, 0x32f00cad, 0xb33addea, 0x176e822f, 0x5cc61b5c, 0xd739feb0,
- 0x7dbca972, 0xae336fa0, 0x79b5f17f, 0xa8c34f02, 0x2364d664, 0x46d8c51b,
- 0x4e1757dc, 0xb3ef9928, 0x7517df98, 0x85eed3a3, 0x6538bff1, 0xb88bfaa2,
- 0x5530252f, 0x9c09e04f, 0x51682997, 0x2ebcc00f, 0x8140589a, 0x9f73b8ad,
- 0xdf000591, 0x41f4a14b, 0xb07b5d09, 0x291de59d, 0x92ed8ed8, 0x04a92798,
- 0x2deb09f1, 0x057c63e0, 0xc2192eff, 0xfd42f7f9, 0x965b3327, 0x81e0731b,
- 0x86552a74, 0x9cf27e75, 0xbe7824c4, 0x4e1bfd6a, 0x95ab1e58, 0x5029640e,
- 0xcc10d1bf, 0x3d8c4937, 0xe2f6fb22, 0xd85a3eba, 0xd0656ffa, 0xf3cb7cee,
- 0x0d57dc0e, 0x2872adaf, 0x0569fb0f, 0xee60067c, 0x6552cdad, 0x26c346d0,
- 0xa1ed0d54, 0xa39e8d6f, 0xb5f57ce9, 0xaba7a26c, 0x2fa19675, 0xdd031d20,
- 0x415af3e2, 0xfd2177ef, 0xacea6943, 0xe9c8f414, 0x5aeba35f, 0x5aadcb99,
- 0x0030625b, 0xbff99bf3, 0xf500fe80, 0xf2a85f6b, 0x2bba444e, 0x5079a830,
- 0x32fc11ac, 0xe0f83a53, 0xcf83e458, 0x787ad452, 0x579af93e, 0xc1f3d73c,
- 0xc674fe4b, 0xbc4b19f2, 0xd5c690b6, 0xe822dfe8, 0xdff484dd, 0x2d83de8f,
- 0xd9fffe05, 0x77ff9edf, 0xdb90f3f8, 0x6be216f7, 0x7fca1c9a, 0x3b4b052c,
- 0x94e4d1d1, 0xe7e9192a, 0xb3cfcb9b, 0xd59e7e42, 0x7db5cfc9, 0xb7f0cfc8,
- 0x04d787e4, 0xd85a543f, 0x2e22de1d, 0x7bdb67df, 0x3d97ebfa, 0xea0b9ce9,
- 0x7819743f, 0xf343ff7f, 0xca5bf0fe, 0x86fd7ffd, 0x42afff72, 0x79cb47ee,
- 0x9ca1fd06, 0xc2d5ecff, 0xf781ea20, 0xd405e819, 0xb824af7b, 0x403d0b0e,
- 0x313e227a, 0xd03d2378, 0x5fe77b90, 0x7f03d0fb, 0xa3fdbc43, 0x3fa3407a,
- 0xfe345f8d, 0x9a21f8d0, 0x987e347f, 0xf13503fe, 0x401fdc5e, 0x1fe461cc,
- 0xae0cf039, 0x5095d6a3, 0xf1a97c8c, 0x0c17dad1, 0xf4bd67c4, 0x1e9be083,
- 0x0bebd13e, 0x3e341f8d, 0x56a6f8d1, 0x28b2c3f0, 0xb526387e, 0xde163c3e,
- 0x15f6eedb, 0xf87b53b9, 0xd173cd63, 0x7a4fa17a, 0xcb4f4862, 0xd218ea52,
- 0x91942d53, 0x83e964f4, 0xdfdd8a9e, 0x126e9e8e, 0x9e8ebfed, 0x6a66dc2a,
- 0x4f483ff7, 0x3191ee15, 0xfbb269e9, 0x5c57689f, 0xa97dfbad, 0xb573e60b,
- 0xbbace414, 0xbfa6de87, 0x90ddb8c5, 0x7e915763, 0x3af9e23a, 0x8303cc3b,
- 0x2beed8f5, 0xd4788756, 0x67db52e8, 0x86580ecd, 0xb6e50074, 0x9c2aef6c,
- 0xa07c476f, 0x9337fd68, 0x96cfb477, 0x53d9b094, 0xd61dfb84, 0xecbeffe9,
- 0x72dfb5c5, 0xdfdc6b9f, 0xddf86e4c, 0xd17b74ff, 0x272d8eef, 0x7d9dff02,
- 0x7f0e599d, 0x94f047f6, 0xf61e33d7, 0x660287e7, 0xcbf22f61, 0xfead32bc,
- 0x191e2d37, 0x3dfc03e5, 0x30f04696, 0xc381e12b, 0x0ae1d381, 0x87f4e798,
- 0x5803ebbb, 0xa27c793f, 0x0c798fe8, 0x8ffda7ac, 0x6e15bc0f, 0xc2defd26,
- 0x94ebeff1, 0xe02343bd, 0x11ed8052, 0xbc145970, 0xc877b79f, 0x7ea14c9d,
- 0xa0af9c82, 0xc209437f, 0x7e827f5a, 0x55f8e799, 0xc52cf3c0, 0x3ec076c0,
- 0xf0394bad, 0x6b9455c6, 0x7066066d, 0xfd81e045, 0x04c9ebde, 0x20c578ba,
- 0x7b08ffe0, 0xf85b1972, 0xb84f8702, 0xc812d4ff, 0xbe02fd15, 0x9b7408d7,
- 0x091e0d5a, 0x66535bfa, 0x7bbb6608, 0x5b84fbe3, 0x7cdaabd3, 0xdfea5540,
- 0x6f94e667, 0x6d1a3ef7, 0xbd367ef4, 0x8b7cb21f, 0x678fe7f1, 0x7b0c609e,
- 0x1f820ff8, 0x63134a2a, 0x4b779fd6, 0x01d7ff1c, 0x4787c6d6, 0xc1fd6073,
- 0x5975fc18, 0x1a3617f4, 0xd6ff3e05, 0x36167482, 0x6bfef86b, 0x327be20b,
- 0x8274dd63, 0x13e30374, 0x7fdc7ffc, 0x7cc936f5, 0x7c289eb9, 0x6fbd68dd,
- 0x2057c0c6, 0x372cbf6a, 0x6ee9f7c0, 0xbef3d0b9, 0xe87eff4b, 0x4ef5fb46,
- 0xdd05f1af, 0xd8e8d4ae, 0x44f7a3a3, 0x99f44bd9, 0x02506298, 0xbd6b8f40,
- 0x2fe8cd71, 0xa9a7f0f4, 0x8e14f10a, 0x87a9e3d3, 0x1555ccff, 0x448fb236,
- 0xe42eeb7b, 0xbbb1af5f, 0x6ec7e73d, 0x029e66ba, 0xd29a2bc0, 0x41d27ef8,
- 0x8d80aecb, 0x09ea82e8, 0x77988dce, 0x46b63f34, 0xf8a3e3c1, 0xc91ff057,
- 0x8007d40f, 0x6f943ca7, 0xaecd6729, 0xb3513a08, 0x313e9e39, 0xa7946ab0,
- 0x8edc49e1, 0xd2f3670c, 0xfaa06d9b, 0x1fbe6cb2, 0xe386511e, 0xa7a0f023,
- 0x2bfa109f, 0x3c26eb11, 0xd6d1482d, 0x0335505d, 0xe64e15d6, 0x73b2d3f5,
- 0x7b320577, 0x66fee8e0, 0x05541764, 0xcffb228a, 0x5d78833f, 0xcde6f020,
- 0xeb06741e, 0x4b507935, 0x11f44284, 0x8b507940, 0x4de861f4, 0xbdd9e91f,
- 0xf51033e8, 0x8374c7be, 0xbf7ab3f7, 0x9f7a89ef, 0xcdbe5299, 0x66df62fb,
- 0x656bed44, 0x4456bed4, 0x1c1a35c1, 0x4d5fc9d4, 0xdb692f2e, 0x7984e8d5,
- 0xe40475dc, 0xe7a48b2c, 0x77cf4451, 0x8efd1a29, 0xbb7a833e, 0x08cb9e87,
- 0xf62add9e, 0x1766302d, 0x942a9fea, 0xe07b63c3, 0x08872839, 0x19e55b1e,
- 0xc6afa91e, 0x3db942ed, 0x3f6b49bf, 0x6c2fda9e, 0x99bbfad0, 0x647db5ea,
- 0xd154ef81, 0xc3b90abe, 0x60ce1302, 0xf857eafd, 0x3d07f5fb, 0x0fc86e67,
- 0xd978512d, 0xa207051f, 0x1afeefda, 0xf510d6fd, 0xfaa8e6fe, 0x5f7828e6,
- 0x7fa4dc14, 0x0352f17f, 0xa062e1f1, 0x6888dc07, 0x8fa68cbe, 0xedbbb387,
- 0x6e7d6e9c, 0xa77d91b0, 0xf5e9abe3, 0xe0fc7e1c, 0xa2a6aacc, 0xd6fb3808,
- 0xdff700aa, 0x2697480d, 0x73207fc6, 0x83d01203, 0xf9b90fa9, 0xb2e8be83,
- 0xf3df5a20, 0x9fe13ffa, 0x332f6819, 0x4c725d9d, 0x92edc3d2, 0x6745ef36,
- 0x43e11636, 0x42a9ae0d, 0x5efa7a7f, 0x9fc0bafd, 0xaac2f015, 0xbb08cc8a,
- 0xcaa0b028, 0xad4eb113, 0xbf2f94fd, 0xe7bc7092, 0x1d5417b3, 0x499afa82,
- 0x983abca1, 0x2f324d67, 0xa84a5f41, 0xf889d7af, 0x255794cd, 0x9acbea2f,
- 0x86de50f8, 0xb27588a2, 0x675c7cd6, 0xed12fdfb, 0xf61ea04f, 0x98b4f007,
- 0x8f0a2381, 0x331e64ee, 0xc4fa81cb, 0xc24f4dc4, 0x97eec77b, 0x7e9ea136,
- 0x273f537f, 0x39c943fa, 0x963ceedc, 0x19739378, 0x7709edc0, 0xdf6dbc90,
- 0xa3ca993e, 0x975b6792, 0xd9dbd8c2, 0x856caaab, 0x78489f58, 0x69707d3a,
- 0xefa016d5, 0x7a2ed933, 0x38ac97df, 0xdeded0db, 0x5d876261, 0xe2952f38,
- 0x5a778b48, 0x7ce0778a, 0xa2710cb6, 0x47e4b9fd, 0xa0325355, 0x934692dd,
- 0xa754768a, 0xf9c2c951, 0x364c76f9, 0x06d2fd63, 0xa16e0651, 0xffbff5f2,
- 0xed01dea4, 0xa8371ebb, 0xcdfda107, 0x35beb45f, 0x4d15e00c, 0xd16e2a39,
- 0x2807e06b, 0x7db9ce30, 0xd0128283, 0x757107e5, 0xf6f16627, 0xb8afdb0c,
- 0xab3d3aee, 0xca4bdb14, 0x017f6856, 0x7cfda39e, 0xa0e901e1, 0xb0e5e701,
- 0x49601bc7, 0x1464be17, 0x68d0b9cf, 0xee7c6209, 0xfb77cd9c, 0x9f671c3e,
- 0x767d2d09, 0x1872e0c1, 0x1d9f0f00, 0x3d2ab7bc, 0xc45b9f03, 0xb49bdefe,
- 0xd8b0f018, 0xa43f4dd8, 0x7127964f, 0x7becb3f8, 0x3ac30eab, 0x88323c2e,
- 0x722b57e2, 0x80d95d3c, 0xcf5cc2af, 0x107e58e7, 0xebd6f5c7, 0x40ee977f,
- 0x97d7fe3b, 0xbe913897, 0xd6f426fe, 0x3896d76b, 0x55d84497, 0x89913fcb,
- 0xbb375e0e, 0x5f7ce236, 0x40681f8f, 0xa0e81b3f, 0x97c9c61f, 0xe805bf0a,
- 0x31f3d379, 0xcd7fabec, 0xdabf6896, 0xde3a907f, 0x6deba3a5, 0xdfc8a7a4,
- 0x93f6d800, 0xa002bbad, 0x365bcfdb, 0x8e500fb1, 0x7147ee6d, 0xc84ca5db,
- 0x82e26781, 0xf4b157e8, 0xf8c8fcd6, 0x8a1f374d, 0xd80c7ff6, 0x847faf09,
- 0xfdf7e8f6, 0x761ff031, 0x7eddeb66, 0x401ec385, 0xbb43e2e3, 0x78fdc65d,
- 0xb85ff65f, 0xfe5bde0f, 0xc0f489b8, 0x3753c7f2, 0x40b8e177, 0x8b571837,
- 0x1c82d75e, 0xf4638f13, 0x878197c5, 0xfe742aab, 0xbf24c3ca, 0xfccbe2fb,
- 0x75543c9f, 0x5f37d6c8, 0x7cb850ae, 0xc9b8f29a, 0x62b4fc8b, 0xa0665da4,
- 0xfe3d264f, 0xcfc461c6, 0x2571f58a, 0x8af89816, 0x5fb42dc7, 0x407b769d,
- 0xc39f7a81, 0x5941272e, 0xd6e5c39a, 0xed171cbc, 0x64c4b973, 0x0d95096b,
- 0x82bd6f18, 0x2f800de1, 0xcf787a6d, 0x23e71868, 0x1a379c16, 0xc3c577f0,
- 0x0bcaf4e9, 0x991dc512, 0x826791ec, 0xb8c95cbc, 0xf93da89c, 0xfc2279bc,
- 0xc56eb2b9, 0x5707f40c, 0x3ae74d05, 0xf18e0f85, 0xf9ac75d8, 0xea186973,
- 0xa273fd57, 0xf3d62704, 0x49d61adf, 0x35b6a372, 0xdaebfbf6, 0xe467cff4,
- 0x0c2e53d8, 0x2e431861, 0x2bb10c01, 0x067ca675, 0x03615c4b, 0x96f582fe,
- 0xbcd037ef, 0x82926c57, 0x79779816, 0x3e2f1e3f, 0x37fd87ef, 0x0a03bad3,
- 0x73762bc0, 0x1982b3bd, 0xf3f85682, 0x29ebfd96, 0xc84c797e, 0xe606c599,
- 0x20fefa45, 0x3f42cd4e, 0x71e3f97f, 0x4f15df84, 0x47b7faac, 0x2dcebde0,
- 0xfd225333, 0x174825ea, 0x9accbf1c, 0x87cfd3dc, 0x859fbe5b, 0x63fe5ff4,
- 0x3d618ff0, 0x2fd8922b, 0xbf71b816, 0xb65cb232, 0xb62b769e, 0xdbcf9fde,
- 0x7e0d7f81, 0x2407e2f4, 0xd17b075a, 0x78107a42, 0xdbc4895d, 0x669386d2,
- 0x5bff1173, 0xdafb0a71, 0x39bc7285, 0xe7fbc12c, 0x11b25ea0, 0x119d02fe,
- 0xb03bf271, 0x23920caf, 0x8d5f5c3e, 0x6cc770d1, 0x8ccba7ea, 0x8733bd7c,
- 0x441b43c7, 0xbd4b38b9, 0x0fcfe29d, 0x6eadd45a, 0x4a348fde, 0xbbfc03cc,
- 0x3978635a, 0x2fd981c6, 0x5957142d, 0x89e710d7, 0xe23f9073, 0x5dfa0e79,
- 0x9cd93327, 0xfa72fd8c, 0x72e2e35b, 0x2bbf9e03, 0x3b5af3c3, 0x49b58b97,
- 0x97ae6f80, 0xffe8463d, 0x872bfc33, 0xac3197f7, 0xf1eefde7, 0x85f53d0d,
- 0xfd5f10c3, 0x3ce355e6, 0xdf112e7e, 0x2c1e3202, 0xe7eefb43, 0xabf408d2,
- 0x6c703f17, 0xbbd9ca0a, 0xf0562d9e, 0xf8bfc5d5, 0xbb89e91d, 0xa2773ec4,
- 0x037a8f9d, 0x7ca167e0, 0x45cb8732, 0x42e3c49f, 0x687c0a4f, 0xd7d5adfb,
- 0xf1e2603e, 0x28e79079, 0xfcb76a40, 0xb5adfa9e, 0x67289d87, 0x8d345f6b,
- 0x94fc7942, 0x2d92ff98, 0x0bbfc703, 0x94c4b3f4, 0x5a5ea0a8, 0x46699813,
- 0x818b4d78, 0x52f79ee0, 0x3f1e90b3, 0x81c9786e, 0x5c41f274, 0x4ff50f28,
- 0xf538fad7, 0xe1402e20, 0x1b8fb971, 0xfc620ef2, 0xb612a966, 0xe97ea01b,
- 0x94649cc6, 0x212befd3, 0xdfbfd633, 0xec2236ea, 0x08f19451, 0x04e1e47b,
- 0xab220c7f, 0xca0fd055, 0xbe06b599, 0x399e6b9f, 0xf186ce66, 0xfdc3937e,
- 0xfe7e4f9b, 0xf38c7cbb, 0xf38566d4, 0x7ec07f51, 0x3c400fe7, 0xfd206d3f,
- 0xc919f6bb, 0x67ac3713, 0x7ee2d7bf, 0x16ad7f03, 0x85f6bcfb, 0xba45ee97,
- 0x5dfb8b5f, 0x805e9bd2, 0xf3d38f6e, 0x614c0ee7, 0x48e3fdfc, 0x02be9a17,
- 0x8c94c1b8, 0x9f0e3a71, 0x02fce1ce, 0xf3f82bcf, 0x4bc91140, 0x67682390,
- 0x5f7bd346, 0xd8b1fbfb, 0x2c5b25bf, 0x163f5724, 0xc0f9dbfb, 0xbfdc0e8b,
- 0xec7e7e4f, 0xd4a39e04, 0xd8da073e, 0x05ee8315, 0xfae1d63e, 0xb27f341d,
- 0x7ae1d623, 0xefeb3d1d, 0x6fc173a6, 0x9f5f18eb, 0xb275deb6, 0x2f56bf58,
- 0xd62cbfde, 0x7c0986b9, 0xf38830bd, 0xe427e097, 0xb4c7b457, 0xf992f9f5,
- 0x267d1afb, 0xffb972e7, 0x99ff2137, 0xfc40ead2, 0x9ca2fee0, 0x98f1fa01,
- 0x01b90947, 0x16793e4d, 0x5fb11fe6, 0x73b3fcda, 0xae403cf9, 0x7b929279,
- 0xc8d3b1f6, 0xb73ac656, 0x78e5c84c, 0x9698db3c, 0xfbf806d5, 0x892bfc18,
- 0x23957a71, 0x46e8d3c6, 0x67fcaf1b, 0xdd70d355, 0xfb087fd0, 0x3f7dc6d7,
- 0x3f632090, 0x1fce33ef, 0xbe35fcda, 0x345faf2c, 0xed81d8ad, 0x14e7b13e,
- 0xdd39bae1, 0x542ae766, 0x802ed07a, 0x066d3df7, 0x159f4f8a, 0xc6d9fcfe,
- 0x8a4b1c97, 0x25dde87a, 0xd93f8de6, 0x1a9e7bd9, 0x33d045fd, 0xfb7cb3cd,
- 0x6b0869fc, 0x4ba68df3, 0x7d1a6f0d, 0x64a9cdb2, 0xe9d344af, 0x66b3ccba,
- 0xb9fa2f1c, 0x807cb766, 0xffe415f1, 0xf2e3c654, 0x6e78ec0d, 0x9f863e84,
- 0xd1ea8d8d, 0xd79c9a0f, 0x14baf3f4, 0x2fc225cf, 0x43703a0b, 0x5366e736,
- 0xc72977bf, 0xfde039b7, 0x74c3e731, 0x87d9abfe, 0x92117f37, 0xf48e3112,
- 0x5224bb82, 0x7cb9adcf, 0x96b6e89c, 0xbfa1b785, 0xdf81f8b3, 0xf48d1ccd,
- 0xce8994f9, 0x4e37165b, 0xbddda336, 0xa39df0ea, 0x35cfdf70, 0xa9763d71,
- 0x6893e461, 0x7a6b9f37, 0x116779d8, 0x653e57be, 0xbc5f3c2c, 0xf5f698ab,
- 0x4cf0b883, 0x91eebb84, 0x6f7841d8, 0x9b91e1dc, 0xce3c0217, 0xae12537e,
- 0x5243fdef, 0x3a08d8c5, 0xcd94ca58, 0x934ed10b, 0x8be41513, 0xab3c85f7,
- 0x5a7df137, 0x517fe82e, 0x45f3e72e, 0xebcb7f62, 0x7cf1f3eb, 0xc800ebbc,
- 0x8d63c051, 0xc21ad5d9, 0x234d5f71, 0xd81d7fbb, 0x74c9e908, 0xd2764d4e,
- 0x66b3334a, 0x6b73d094, 0x693f3c06, 0xeb83df0a, 0xbd8f7939, 0x58e20b78,
- 0x096a3eba, 0x5f896fb7, 0xf1a5aec0, 0x3168edbb, 0x2e82658f, 0xded3fba3,
- 0x1ebb40ef, 0xff989ee5, 0xe6a786a5, 0x74babea1, 0xd7192f24, 0x71abe1ff,
- 0x7cdf684d, 0x4c72e268, 0xaeec1feb, 0x11f691f3, 0x183a5bd8, 0x0c1d2aec,
- 0x6f5e75f4, 0xbc256d8f, 0xb7ab9bdc, 0xad3a34ab, 0x18979f59, 0xcbd01799,
- 0x0a43fefe, 0x9cf7ff9d, 0x644e8cbf, 0x7742e431, 0x880fd5dc, 0x3c6c67ca,
- 0xcf18fada, 0xf9f2f84d, 0x2ddfda30, 0xeb02c516, 0x8e748f3c, 0x4a2f4be7,
- 0x72b7eedc, 0xe2ff3fba, 0x77fa2088, 0xe1c0ffcb, 0x2086ade5, 0xdf1edd1e,
- 0xf6c25db5, 0x4beec0cb, 0xb3d84433, 0x03cd77bb, 0x545767f2, 0x680cb6df,
- 0xcf08e57f, 0x5b6a8077, 0x227b1d94, 0x1db7d5c3, 0x5fb6cffb, 0x61c0b8b5,
- 0x532adf0d, 0x9e1adf11, 0x75e67f35, 0x92b287a0, 0xea7dbc1e, 0xebf6495f,
- 0xca8fbf65, 0x1f670ccf, 0x6c74871c, 0x5f91544f, 0xb0f6dd7e, 0xfbf70034,
- 0xe8ebe285, 0x25b58e97, 0x9fb7c82a, 0xb9d137fa, 0x1d7f65e6, 0x6b7eda95,
- 0x5f9bb171, 0x3ef7a768, 0xcaf11b6d, 0x35ef7838, 0xd790a25b, 0x35f731c9,
- 0xeee3bf3a, 0xf0d3a3f5, 0x8faeb6b9, 0xabfbe3ee, 0x23a3fbcd, 0x5d703a77,
- 0x7bf58fed, 0x6bee0c65, 0xf682a242, 0xdf910ad9, 0x971f6171, 0x89ad170f,
- 0xfd80ce4f, 0x8e7fb8bd, 0x5c9c8193, 0x1e773ed6, 0xaafe5f3e, 0x5cfb4141,
- 0x81cab57d, 0xcb3f8df1, 0x4b050e9d, 0xf3842f78, 0xca128391, 0x6c95b1a3,
- 0x1b1fb60e, 0xfa0b9992, 0xd3833319, 0x72cb98c9, 0x3e780f10, 0xb714e786,
- 0x714f1eb8, 0xc3f5f80b, 0xbf658dfc, 0x0d0ef1e2, 0x35df9aef, 0x04dbac4e,
- 0x2e7447ec, 0xf197979e, 0x7fee1fe7, 0x77f6167e, 0xc14990e9, 0xc87a7f79,
- 0x06affd44, 0xe308c97f, 0xfdc23c5d, 0xdce38410, 0xdfdcc7c8, 0xfdcadd58,
- 0x26f5da8d, 0x37b1398f, 0xb447963d, 0x9e0ebf43, 0x55dc70b9, 0x3a34de82,
- 0xebe1ed5d, 0x0d7a0d5b, 0xb74d1bd7, 0x1b75ac49, 0xe8ebe9e2, 0xedd29bf7,
- 0x135e90df, 0xe87cb758, 0xe8bed7a6, 0xf913e044, 0xa355e91d, 0xf8fbd587,
- 0x6b727a39, 0x3ba444f1, 0x79343e8d, 0x0ac49812, 0x9bd66f50, 0xdde60159,
- 0x2af18c04, 0x9b2a81ca, 0x7f7284cb, 0x05674a4e, 0x1e4965a2, 0xb952a797,
- 0xfd4463d1, 0x79216f53, 0x526f2d11, 0xdffcb8f2, 0xed074483, 0x2a14f28b,
- 0xfc8eac4d, 0x8584ad07, 0x5cfd440c, 0x9ffc9095, 0x5372682e, 0x65b383de,
- 0xb8d57f98, 0x54727be4, 0xede506c6, 0xe488f0e6, 0x97a82691, 0x5d9a1feb,
- 0x9e457001, 0x445e6067, 0xa70e97bf, 0xc0f5c40d, 0x8c1e5773, 0x97c53dbb,
- 0xb33ae583, 0x67f7e48d, 0x9b61ae86, 0xcfed3ddc, 0xff7f6abc, 0xb81eaed7,
- 0xd4b2c4d3, 0xcd198422, 0xcaef2b5b, 0xe3e60cf3, 0x612f9fe8, 0xe2f291ac,
- 0x5dfbff02, 0xe7e043b4, 0xdefec2b5, 0x8969e82a, 0xfdc216d5, 0xcba64d64,
- 0xa80576dd, 0xca26a67e, 0x04b30748, 0x872adc1d, 0x42fdf1da, 0xb05ca0d6,
- 0xffb3e992, 0x3a377eab, 0x05d995a7, 0x87a03fad, 0x3eb04ccf, 0x900367a0,
- 0x196026d7, 0x06b12003, 0x95e197e4, 0xd85ffdff, 0x75807d6f, 0x6b9e11c6,
- 0x067b9414, 0x057e33e6, 0x63826d65, 0x3c33c618, 0x3643d92f, 0x3f0dc7d8,
- 0x5fba204f, 0x5217ec25, 0xa65f98c6, 0x74b0f5f0, 0x8f7fde7e, 0xfd0fb7a0,
- 0x5817372c, 0xf47613fb, 0xb1e61953, 0x1b37ce2a, 0x78c6bdf1, 0x0b836b2a,
- 0x81deb4f9, 0xbf27c576, 0x09145490, 0xc8dd846b, 0x7e0aa50e, 0xa0134297,
- 0x785dc3be, 0x8d4bf510, 0x6ecb97a0, 0x606f7e46, 0xfaf2858b, 0x5963f5d8,
- 0x995c03f7, 0xfe8a8b7d, 0xb767e5e4, 0x7d832ee7, 0x0ed8c0b2, 0xe854e758,
- 0x6aa60cb3, 0x73a25802, 0x03f520de, 0x3c0701f5, 0x387ee6df, 0xf319d38b,
- 0xfdb47ae2, 0x6bdef0d1, 0xb468603f, 0x66568d2f, 0x90b1ff42, 0xff9057ed,
- 0x8c997db4, 0xfff03dce, 0x9c791786, 0x75818363, 0xf9af18c3, 0x8d780ad0,
- 0x4f6a5f21, 0x267641be, 0x27405bb0, 0x19dff657, 0x1d95ff5b, 0xffd76330,
- 0x98d83d6c, 0x315ff427, 0x037b262b, 0xadfd0697, 0x4b266d10, 0xd7192e35,
- 0x91556a93, 0x9e3c361e, 0x1d867a43, 0xa0f44dd9, 0xfbfb63b5, 0x736c9d11,
- 0x55ff844b, 0xcc4cb06d, 0x4feb69d3, 0xda338b79, 0x5c74a992, 0x97e7a74b,
- 0x94ab7c9e, 0x3fbe1bcb, 0x369a7f33, 0x7e83f289, 0x6d4a883a, 0xbd041b1e,
- 0xe2be7869, 0xc93e7815, 0xbb06d5f5, 0x397dfc99, 0x79489850, 0x0b121d8c,
- 0xe4f73c02, 0x57e2131c, 0x6d74e78a, 0x57323749, 0xc459bc0c, 0xe2b9c47e,
- 0xded22b99, 0x68c2780f, 0xf517cfd7, 0x51c90509, 0xe6df7cf5, 0xb7cfe589,
- 0xf3819cad, 0x75fdabb6, 0x4c776ce3, 0x92ba20e9, 0x5f38cb2e, 0xeb0304cb,
- 0x352be787, 0x3b987dfa, 0xc69b0f57, 0xd5f24e7f, 0xbf7a3e34, 0x4dfd0999,
- 0xfcff478b, 0x17a13cb5, 0xe461590a, 0x9fc2f63e, 0x0d7c4acd, 0x78ef79da,
- 0x9875e780, 0xedc5d058, 0xafc7b435, 0xb7442c78, 0xde04e3db, 0x21e9a50c,
- 0xa6589f68, 0x47925fc7, 0x957eaf8f, 0x7aa4fc7a, 0xab4878f5, 0x67d5d6ce,
- 0xeaeb06f8, 0xd12cac07, 0xc6eb03c1, 0xb4dfdaea, 0x760e9269, 0xdae9a607,
- 0xd6cd34e7, 0x0b2d79c1, 0xed07ed75, 0x2faba25b, 0xd5d6ae0c, 0x41b2390f,
- 0xfd6d0f07, 0xe1fb5d17, 0xf5755b6d, 0xba1da1c5, 0x0f1d11fa, 0xe191e0e9,
- 0x47ed7547, 0x57507bbf, 0x69f3a63f, 0x8bb8fd5d, 0x9be0e9cf, 0xb5d65ebb,
- 0xa8ed709f, 0xdec89e0e, 0xb72fb5d2, 0x4f074efe, 0xd743fe56, 0x0ff496fe,
- 0x5d53f574, 0xa7eaeb1f, 0xc1d55c17, 0x097d9877, 0xea97c8f9, 0xcdef74df,
- 0x8e1fae62, 0x9f9e3a07, 0x00435462, 0xfc85f3db, 0x8c977410, 0xdaed13fa,
- 0x7485965c, 0x1f1a593a, 0x336bba22, 0x4457e8a8, 0x63f927eb, 0x65e307af,
- 0x8a8325ec, 0xb044ac71, 0xf188e4eb, 0x70563c92, 0x7ee07b00, 0x4e0e8a95,
- 0xdaeba6f5, 0x74bb55a7, 0x02be19f5, 0x9580fd5d, 0x581e0eaa, 0x7f6ba657,
- 0x0e8f26d3, 0x752a0776, 0xbc9a73ed, 0xa5af383a, 0xd07ed75a, 0xbeae9f3e,
- 0x5752b830, 0x9d48e43f, 0xbada1e0e, 0x787ed749, 0x5f57405b, 0xd5d26a1c,
- 0xd168e88f, 0xfbc323c1, 0xbf47ed74, 0x8fd5d41b, 0xaba23ce9, 0x55b1771f,
- 0xd5dcdf07, 0xe13f6ba6, 0x4f07485a, 0xed752764, 0x7467adcb, 0x3de564f0,
- 0xd25bfb5d, 0xa7eaeacf, 0xeae92eba, 0x7a647b35, 0xe7fae7c1, 0xa9993ec2,
- 0xfdee97fe, 0x430f24c0, 0x673c08fa, 0xa05deb50, 0xb9b3f2ff, 0x2d13073e,
- 0xc67b424e, 0xc945f94b, 0x7207a098, 0x2060312b, 0x5b9542ba, 0x149ef143,
- 0x52a453d2, 0x0347985c, 0xde81de7a, 0xf68ddb93, 0x9d8f426d, 0x88d5f995,
- 0x7d676e6f, 0x30387d1f, 0x944db65d, 0x0de563aa, 0xc79f3f7e, 0xfbe50e39,
- 0xa2a7e436, 0x14ecf11f, 0xb157b3b4, 0xe79c36c0, 0xb128a964, 0x71a8e313,
- 0x568538fa, 0x645eb54e, 0x77dd8472, 0xb325ae32, 0xfcfe06e4, 0x2665eb54,
- 0x57e8888f, 0xb00c2fc4, 0xfd110dfe, 0x807e083f, 0x8b7f3e0c, 0x6c0af81f,
- 0x0afc87a4, 0xe9fdbbc1, 0xbbf1ef04, 0x2fe7dca8, 0xbf51f2a0, 0xfdfbf54a,
- 0xe13f0465, 0xf41c10f7, 0xd0795257, 0x87e7a5ef, 0x3f04d5fc, 0x96317e09,
- 0xc64fc047, 0x77f069f2, 0xf019feb1, 0x85fe117f, 0xab65403f, 0x3f9e89bf,
- 0xf8216fe7, 0x823eff05, 0x520fe97f, 0x423fe6d9, 0x56fecbe5, 0xdfc57faa,
- 0xfe6bf046, 0x7f21c110, 0xfd47c107, 0xfb8f8261, 0x84f825df, 0x0eca93bf,
- 0xdf2a45ff, 0xfd5177f4, 0x8235ff29, 0x6f53f67b, 0xf3e346ff, 0x65571123,
- 0x215c4ec2, 0x70a587e8, 0x273970fb, 0xd042b605, 0xa81269ad, 0xfa3fb457,
- 0x3cc41fe7, 0x574891d6, 0xa7574405, 0x1efd8dbe, 0x25697fed, 0x9bf719d0,
- 0x3c781bd7, 0x22efd346, 0xefd3405f, 0x7f70f735, 0xbbd81175, 0x43ffff18,
- 0xaf3fb71c, 0xd00a99d4, 0xc431ab8e, 0x5d2f68ab, 0xd933fba9, 0xafcf0c47,
- 0x78ee4581, 0x476072c5, 0x0356df84, 0xfde11bef, 0x18b45999, 0x4c3ac356,
- 0x332a2e74, 0x357c048f, 0x37efa076, 0x0f561fa8, 0x7fc80634, 0xd1f305b6,
- 0xa07dbb6f, 0x7ef48c2f, 0x09d96ea5, 0xd2a28fc2, 0x4b4ce0b9, 0xc63e7528,
- 0x144a4e49, 0x1f0bebdf, 0x785e44eb, 0x5daff59f, 0xbc3b44ca, 0x0f92eff2,
- 0xc9b4e7f7, 0x83718d5e, 0x1fb9f20f, 0x51be41fa, 0xe81e5e57, 0xfcf3873b,
- 0x76eebd8b, 0x2ff0a023, 0xe4ff59df, 0xbf1eeedd, 0x3d7456f9, 0x62ae5ec1,
- 0x29e5132e, 0x6e1bcf32, 0xe636eae8, 0x0b3e7823, 0xa67b7950, 0xd75c63ef,
- 0xd8241602, 0x1592d637, 0xf3d15d6b, 0x03908bfa, 0xea37c97f, 0xbe59feca,
- 0xf2f3e4ff, 0x8f4ebcd0, 0xd71f25b9, 0x616bcda5, 0x3fe68b96, 0x813d758b,
- 0xabcbfbf3, 0xe4305f9f, 0xff8fa6f4, 0x61b0ba01, 0x31da0598, 0xc7a8df3c,
- 0xafa81cc4, 0xf940cfbf, 0xd45d1ad9, 0xdf104060, 0xbca06cdb, 0x013a1efd,
- 0x2bbf40fa, 0xf1ee8ba5, 0x0f249d01, 0x23193a42, 0x4f60cc05, 0xf306369e,
- 0xbc5e740d, 0x84718ccc, 0x1f402915, 0xc1d37dd9, 0x409f715a, 0x95f40e7b,
- 0xfa7dfd89, 0x8805d1ab, 0x8daf75af, 0xeabe2171, 0xe80fb08d, 0xa929be27,
- 0x8b851f3c, 0x50dc697e, 0x5932578a, 0x34ce3155, 0xde5b12d3, 0xe9c41f8e,
- 0xa9ba74e7, 0xe9fd4832, 0x074a55cf, 0x1d2b7df1, 0xc373f7c4, 0x48d70ffa,
- 0x47d3ef30, 0x947dd12f, 0xf4dff35e, 0xc46e6166, 0x9db5d7bc, 0x2189e29d,
- 0xfe8be7bf, 0xcc91ba34, 0x5b01df76, 0xe9babce4, 0xfbae1c78, 0xc740492f,
- 0x17c74439, 0x9670fcf0, 0x1f3895c5, 0x09404eca, 0x1fbee9da, 0x2dffe42b,
- 0x4b952a61, 0x15ca9799, 0xb748edb0, 0x332ec0de, 0x6b357be2, 0xcb6be7a5,
- 0x1d2274ee, 0xc8fa372f, 0x99835e2f, 0xcb9e78b7, 0x01d22aba, 0x6d35b76f,
- 0xd01d2379, 0xd765a737, 0xcecf8c64, 0x037e2e0e, 0x8643aacb, 0x0a87980b,
- 0xe70b317c, 0x6ba869d5, 0x2fe30fec, 0xe362667c, 0x4b3e7800, 0xdec1fbe2,
- 0xc9a1fbe2, 0x0375e88d, 0x941bcc1f, 0xd0f2eb8a, 0xa54724ba, 0xb66a0f8e,
- 0xa5218f32, 0x9bbe1f27, 0xfaeeca2f, 0x5f9400d3, 0x07c51772, 0x4966bdd6,
- 0xcd5e7dc6, 0xf0603db8, 0xcd0ff168, 0xe744600e, 0x1578b177, 0xe8247ddb,
- 0x8c81a3fa, 0x0323fae8, 0x3d258438, 0xf2cb29f6, 0xf4e497a5, 0xc675ebe8,
- 0x9e218667, 0xe2d79f40, 0xd07f577c, 0x8dd8adba, 0x85983f72, 0x69e989f6,
- 0xd6ef5a8b, 0x55f615e9, 0xeb5c4f42, 0x3b8f1341, 0x50cbcf45, 0xd0bfe276,
- 0x5998b11e, 0x8039cf00, 0xe428d9af, 0xe266fee7, 0x2d447aab, 0x7926c7c6,
- 0x557cfc5d, 0x3169ffdf, 0xb92f8edf, 0xf5801c3f, 0xf7a49c60, 0x594f5c38,
- 0x21c67be2, 0x3464e1b9, 0x9c41cece, 0x98f1b57f, 0xed1333ad, 0x7de3fbf7,
- 0xd5fdc03f, 0x3f9a3de2, 0x30fee1d9, 0x8d99ee97, 0xf74354bd, 0xe858c637,
- 0x22addf7e, 0x196b760e, 0xaadd838f, 0x47c6bdc5, 0xe2a2bdc5, 0xec7c6c2f,
- 0x97269838, 0xefc95319, 0xd07f642d, 0x17f14fd6, 0xd2f60e4d, 0x3090b0ab,
- 0x145da5c5, 0xcb8ee8af, 0x1e799b14, 0xad306b8d, 0xe4e42cc7, 0x4f972f4e,
- 0xd569fbda, 0xfce8c2e0, 0xd5cb2b08, 0x0e8a11f9, 0xae97581e, 0x26d37f6b,
- 0x1ddeae97, 0xe7d5d028, 0x383aa934, 0xd74ca5af, 0x8f3ed07e, 0x560c2e0e,
- 0x390fdaea, 0x43c1d5e2, 0xed75ab5b, 0x74f9b787, 0x95a1c5f5, 0x1d11faba,
- 0x64783a75, 0xfdae9378, 0xba0377e8, 0x4d9d31fa, 0x1771faba, 0xcdf0745b,
- 0xed74fb5d, 0xea0b5c27, 0xa7b227ea, 0xd6e5f574, 0x64f07567, 0xf6ba57e5,
- 0x74fd0b8f, 0xeebb7a4b, 0x49d754f9, 0x0bd37bdd, 0xc7e0e8ce, 0x0f919f71,
- 0x0f899816, 0xe9efaa66, 0x10f267de, 0xe39b938a, 0x1dfdb3f8, 0x3ca3146f,
- 0x170c6fdc, 0x6e3e9f23, 0xf96374ec, 0xb5b5c184, 0xce49d01f, 0xd61489f8,
- 0xbc58abce, 0x3341cb15, 0x5d5318b6, 0x0f731fb0, 0x393d456c, 0xe8dda6a4,
- 0xd2e87804, 0x889d5bb3, 0x290635f7, 0xd1bdf10d, 0x88e58f5d, 0x74a513cd,
- 0xb0d91fa8, 0xe8e51eb8, 0x8b33e6e8, 0x007496d1, 0xfe3187cf, 0x3e887b25,
- 0x69186637, 0xc6471bde, 0xcedcde53, 0x9d1936b1, 0x9c3b9d96, 0xdc0f180d,
- 0x09a4a3b9, 0xbf606dcb, 0x358ccd07, 0xe58efd81, 0x83dfb00e, 0x3c6c8be0,
- 0xe424e7f3, 0x53a6e547, 0xbf2e78e9, 0xaa47d27d, 0x4a15c551, 0xbf438f73,
- 0x22f1a9cd, 0x3b9a515f, 0x4efb7411, 0xdf8049e4, 0x1730923f, 0xe1a370f3,
- 0xad788717, 0x72f7c805, 0xbaed1b8b, 0xac06fd5e, 0xfe017efa, 0x927afd66,
- 0x1e785fb1, 0xad216f33, 0xf7e1eb80, 0xde5a8c0b, 0x715be53a, 0xb04a1c53,
- 0x9e41123f, 0xf0e98f35, 0xcabc00ad, 0xee819d4a, 0x26fb8b09, 0xf8a6aa18,
- 0x26aff5ee, 0x2e9c03c4, 0xe451dbde, 0xfe802bcb, 0x9ca0606c, 0xf497a08b,
- 0xd04700a5, 0xefc05ec7, 0xf99edcb9, 0x0630ee98, 0xa60b9064, 0x1555789f,
- 0x516c79c6, 0x7b97393c, 0x223b7acd, 0xdc8de44f, 0xf7146057, 0x68a8e65f,
- 0xc057dcff, 0xfe23dcf5, 0xe7cff38b, 0xf35dff62, 0x329e03cf, 0x0f988696,
- 0xf54d99e4, 0x611a98aa, 0xb17567aa, 0xf19bc8fc, 0x6fbc0612, 0xee92763a,
- 0x702aafaf, 0xd4325e11, 0xff775a16, 0x646fd0a5, 0x33ae4d9c, 0xda403e60,
- 0xce033ae6, 0xaaf14d2f, 0xacc78e78, 0xbcfddd4e, 0x997f4db4, 0xa7e41e7f,
- 0xb155efc9, 0x46ba699d, 0x222b218f, 0x925aaafb, 0x47cc62c8, 0xfc9d6d2b,
- 0x7aafa8fc, 0x759bc947, 0x625a3794, 0xd111e173, 0xeab6c5e3, 0x7bf63103,
- 0x66efd895, 0x9b7c7e87, 0xe4203e76, 0x718555f4, 0xf7f8213d, 0x6b0e24ee,
- 0x5c5ddcfd, 0xf9c37692, 0xce7463ee, 0x30cdc1a9, 0xf9a9e20e, 0xd715bb7a,
- 0x0b798cdf, 0xe9182fa4, 0x547e2789, 0xa1876070, 0xa2f63ef7, 0xc4fca047,
- 0xce8fa412, 0x83f03d60, 0xa2acd8bd, 0xdefb645d, 0xdeea0372, 0x89475674,
- 0x1591b637, 0x1bb0f21d, 0x4f5aafcc, 0x3d3e6987, 0x97d9329d, 0x62faf941,
- 0x1c3d351f, 0xafa66fbd, 0xc872d272, 0xd979e2ee, 0x67fe4e1b, 0xef022f9c,
- 0x557c123f, 0xe4245ac6, 0x95acb193, 0x4c2cf1ca, 0x175877e5, 0xc8a61e95,
- 0x2a624e58, 0x4bcc1595, 0x475614e5, 0xa16b2565, 0xa56b1a72, 0x530b0672,
- 0x950afe09, 0x5f90a65e, 0x36f41b35, 0x97997396, 0x8eac79ca, 0x1d229fca,
- 0x59ab3e03, 0x590bc10b, 0xc06d952b, 0xfaa5787f, 0x586f9065, 0x0df202be,
- 0xe9fcd7cb, 0x2efc8654, 0xbf47cae6, 0xe3ca80bf, 0x13ca957e, 0x3b2a32fe,
- 0xf76a1efc, 0xca92bfa6, 0x952f7e53, 0x54d5fda7, 0x6a3efd86, 0x257fb6f7,
- 0xebf8ef95, 0xff37fca8, 0xf5df2a26, 0x77fca807, 0x7995137f, 0x39764666,
- 0xcf15082b, 0x7e67fc06, 0x60b8f660, 0x3c0aaf1f, 0x5318f31e, 0xff70530b,
- 0x4df18664, 0x2231c55b, 0x48cb9b0a, 0x5c9addf7, 0x289dd947, 0x3b734f07,
- 0x27669ecd, 0x72d6d03b, 0x613e619c, 0x4a53a19b, 0x793cbd80, 0xd6b98ee4,
- 0xaf93d042, 0x150486b0, 0xadbba5e1, 0x309e07a0, 0x027eeb85, 0x960bc7f5,
- 0xce82b5cc, 0xfb7f6b1a, 0x4c39a7e3, 0xb38e63f5, 0xdfe0057a, 0x1bb1591e,
- 0x3ce130af, 0x57bede50, 0xe62e7ab0, 0xf2155feb, 0x00c37c02, 0xb7ad2de5,
- 0xb16f3105, 0x3168e5b8, 0x7531b62a, 0x37d412b6, 0x1e28ed11, 0xe8bb57d0,
- 0xc7bded7a, 0xe2129d6a, 0x64cff9a1, 0x9cccb37e, 0x9dc63150, 0x7e35fb22,
- 0x7499f1b3, 0xdb23f183, 0xdfd06e19, 0x9fcf228e, 0xfffccf50, 0xfa68f3a6,
- 0xec757d36, 0x062efa59, 0x7e438aeb, 0xe5c4983e, 0xa5d8174d, 0x0b34dfe8,
- 0x364b79b8, 0xb507a9d9, 0xcbefb37c, 0x5e307f54, 0xf081d2bd, 0x378a5c96,
- 0xe2792734, 0x637db10b, 0xcc9dc936, 0x63794604, 0x8a13d53b, 0xe3ef822b,
- 0xb2fcb90b, 0x7285fcdd, 0xefe5ca27, 0xae8f0ccb, 0x3bfefa6f, 0xde00b71d,
- 0x05468d5c, 0xe6f12df7, 0x7e512a77, 0xa3cb3704, 0x18e32124, 0x12792fd5,
- 0xaa9da6fd, 0xf61f3e39, 0x0ea200f5, 0x1b26aced, 0xfd9959d9, 0xc377c542,
- 0xcf328d78, 0x6f968aff, 0x9cb90bb3, 0xc34bda37, 0xc0b76e74, 0x4478c2ea,
- 0xd9b0f25f, 0xf3c2caef, 0x6fbc6764, 0x287e0331, 0x4a676a7c, 0xa7732823,
- 0xa313db83, 0xf6483a9f, 0x27c8b344, 0xd2314c6d, 0x256c49f7, 0x445203ce,
- 0xc87336bf, 0x36f8e785, 0xb163e0a3, 0x3207e69e, 0xf7b75f29, 0xefba5d3c,
- 0x9855d915, 0x6e1c8447, 0xee817116, 0x3ff446f1, 0xcdc44520, 0x4a90966c,
- 0x4bfa69e3, 0x3fc76f1b, 0x914ede36, 0x678da927, 0x9f5fa51f, 0xf5a61cdd,
- 0xa1fd85d9, 0xd713b78d, 0xe30f2317, 0xf5c3c76b, 0x5a378e45, 0x25bb3ebf,
- 0x4bb3eb4c, 0x1ee95edc, 0xf1ec476f, 0x4f671afa, 0x569cfe54, 0x72e42fce,
- 0x7632cc15, 0xd33ff60e, 0x09f9e9c2, 0xd9c5d313, 0x7e7a0937, 0xa69788b2,
- 0x992e5c09, 0xcfba669c, 0x7179d133, 0x6db5d217, 0x9dce91b7, 0xc827296c,
- 0x4ed3927e, 0x40fc8931, 0x9fcf8ad6, 0x02f7f030, 0x7998e6a9, 0xe1fc7b2b,
- 0x7111b9f9, 0xceb534e3, 0x134ff980, 0xe30c1d9d, 0x3314b6ec, 0x6296dfad,
- 0xfca1c60d, 0xcd809955, 0xdb8004c1, 0x0b1b7c8b, 0x954e3d61, 0xc5338bf3,
- 0x92f3007c, 0xdfa1aad2, 0x84ff7d08, 0x772663a0, 0xee22abba, 0xc45b3cd7,
- 0xaf8d49ed, 0x7237e7a3, 0x41ff5f30, 0x4f31e7f0, 0x8f0c6ba7, 0xdc3e9c93,
- 0x5987fc9f, 0xd07bc60f, 0xc0fd3e8f, 0x77820ae0, 0xf5f3a58c, 0x4ec787d3,
- 0xd6627f41, 0x8246698e, 0xe303ac0d, 0x2c76b31f, 0xccf3e234, 0xdffb461c,
- 0xf24cd675, 0xd58ed675, 0x4cbffda2, 0xc665f6c1, 0x6e30cfc0, 0x91ef7650,
- 0x8c8b8c04, 0x00373fb5, 0xcec6d3cb, 0xa07df88d, 0x1bf6155b, 0x5bbcd734,
- 0xb228ed92, 0x36c81eab, 0x44f59fa1, 0x99bf3f21, 0x9e263cc3, 0xbf25e187,
- 0xf091fc7e, 0xfbb2bc31, 0x72aed69d, 0xb4f6c63c, 0x9cb1c729, 0xdaf15214,
- 0xf0e8ab32, 0x4a72c71e, 0xcd02aeb8, 0x5b77cad9, 0x3159638e, 0xe204f7dc,
- 0x46f7f0f7, 0xc614fc95, 0x6e6fbac9, 0xd93bda3c, 0x0f27435b, 0x44d65c50,
- 0x94f6c2f7, 0x18249b79, 0x6bcb8f6f, 0x27b43d45, 0xf248db25, 0x256ea935,
- 0x3c6073ad, 0x51ee75c3, 0x45c9717c, 0xbec97724, 0x11ec137f, 0xe7eeffdc,
- 0x33f9fcf1, 0x151afe82, 0xf88935af, 0x027ca140, 0x9acbb09b, 0x151d2799,
- 0x04f76ca1, 0xc7b72e31, 0xc078e5c3, 0x6c52fdc6, 0x58ec0dbe, 0xec6992ba,
- 0x95594fd9, 0x60c779f5, 0xb2bf60de, 0x10b28768, 0xa6bc5fed, 0x0fe8308a,
- 0xc61d5dfe, 0xe6dda1f5, 0x36be38a4, 0xfa14b97f, 0x9c33a08b, 0xcf5b6cff,
- 0x67b8da7b, 0x237e7ac4, 0x1f1ef4e4, 0xef9b4fef, 0x463728db, 0x465dbcd2,
- 0xe6248f9c, 0x4630eb03, 0x1da227cc, 0xde7bafad, 0xf7e74d4c, 0xdf8c3d4d,
- 0x392e6543, 0x8b0efd62, 0x1e912ad7, 0xbf482a34, 0xf948d576, 0x2fdb76fc,
- 0x7a3f0f29, 0x790a171d, 0x7287eabc, 0x365fa188, 0xe430f54d, 0x1e2a1fcb,
- 0x0164abb2, 0x0edc29cb, 0x624fc793, 0xcaf588a6, 0xdda89329, 0xf18f6834,
- 0x096569c5, 0x74ebd22a, 0x70a0dad6, 0x2e78e03f, 0x318f2fcc, 0x2cb75e5d,
- 0x9faac7e0, 0xf0bb72ab, 0x7b4b592a, 0xf745da01, 0x9dbca72c, 0x3ad30d86,
- 0x05e9be70, 0xa193dbeb, 0xdf39fbde, 0xe3cc5677, 0xcb760372, 0x8cdfbcba,
- 0x9e470095, 0x30f4fb5f, 0xbdae83d0, 0x43365746, 0x847682a5, 0xaefae131,
- 0xecbf983c, 0x2c1bfae0, 0x4637365c, 0x5d17ba3c, 0xfb6bfc09, 0x4b9c1f63,
- 0x1c6d94f8, 0xb54bacef, 0x89f7c6de, 0x84fe8de8, 0x6d81eaf1, 0xbebd1f31,
- 0x7de20a42, 0x7b777b4a, 0x1afb8a96, 0x96d94fbd, 0xb8795dae, 0xca4675fe,
- 0x2bc68f0f, 0xb9b711d8, 0xa4d6ce91, 0xa73c3d50, 0xe8cc6f7c, 0x8a47eee9,
- 0xe3f7eb05, 0xca3fdaeb, 0xbe78bb82, 0x7a79fea9, 0x059bc94a, 0x500714a5,
- 0xebeb36f9, 0xf7ea36f3, 0x283a6315, 0x1654d3c7, 0xfdbfb90c, 0x394b4e7e,
- 0xbd6cc158, 0xbba355f7, 0xe5b17ecc, 0xce421bfc, 0xd3282667, 0xa7ce500a,
- 0xf3fec91a, 0x23531aa6, 0x8329defd, 0xf09cfeb9, 0x37e48d92, 0xf74ac0fb,
- 0x3850d4d6, 0x49c4ed01, 0x3ec9185f, 0xd1d4e37f, 0x3941a787, 0x9b4b37f9,
- 0x0ce4ddb0, 0x86ed0e78, 0xc47d74be, 0x84b7649d, 0x5f5f910b, 0xed93a166,
- 0x4c3b1fa8, 0x2da7bdf4, 0x26536c9f, 0x4cabfee1, 0x6d29dcc5, 0xdc6215dc,
- 0x5e029b5f, 0x996ea792, 0x51e7e41d, 0xf6d2bfd7, 0x2865c789, 0xf036577f,
- 0xbad57bb5, 0x9997d23a, 0xf142cc45, 0xd22af0ee, 0x19e31bc7, 0xa56ccbf2,
- 0xcf08bbf5, 0x4664ecbe, 0xeab66fe8, 0xf3c62d32, 0xce676119, 0x44d35451,
- 0x3f95552c, 0x73e7f2b7, 0x9f3d0f15, 0x73f87aab, 0x6feff71b, 0x3f610253,
- 0x2d9b77f4, 0xddfd85d9, 0xfd797aa6, 0x9fd50b35, 0x172fff02, 0x171ac158,
- 0xb7ae5050, 0xf3f2345c, 0xd13c5f2f, 0xa4ada37b, 0x2bf385c3, 0x36fdd235,
- 0x3ee893b0, 0x4bc54ef2, 0x32f791f7, 0xf822065f, 0x64d9d2e5, 0x629cbf47,
- 0x2f4b7ba4, 0xbf0c8c7b, 0x91a81403, 0x41423df9, 0x67572f47, 0x3654f9d2,
- 0xebf71322, 0x43b256bb, 0x0fa0f11a, 0xe7f757db, 0xf6e642fa, 0x2951bec3,
- 0x6161ded4, 0x074895c9, 0x3bca6587, 0x1e78e1ff, 0x650f943f, 0x735ed107,
- 0x5df9e8d6, 0xe9c49d2e, 0xf20a6541, 0x25550cc1, 0xcddfafba, 0xf88ba354,
- 0x7d87de9e, 0x2cee75a5, 0x1fa2bb7d, 0x55546bc2, 0x93a18ce2, 0x6fa5f517,
- 0x8cf83c73, 0xb3be4794, 0x9befbc54, 0xd7c70874, 0xe0b07cf8, 0xf4ae4d4f,
- 0xf52a4396, 0xa49a4f63, 0x306800ee, 0xbffc800c, 0x51cf0ccf, 0x74cb242e,
- 0xa9706adf, 0xf586521c, 0xe8867df0, 0x4fe0b077, 0xcf9e88f9, 0xe1e90ef2,
- 0xeeff0447, 0x1fb92163, 0xe8c2dbf6, 0x8b406a5c, 0x3e781dbe, 0xd1639406,
- 0x22abfc7c, 0xd48f1683, 0x9e17a1e1, 0xd9d7b17d, 0x5c40aeb3, 0xc8cbad3e,
- 0x5de425d7, 0x3d2b6dae, 0xd56455cf, 0x2d62f385, 0x07fae36f, 0x40c1921c,
- 0x352afd85, 0x7801cece, 0x71264046, 0x49859337, 0xbadd7c5e, 0x2b5c451b,
- 0xebd19d7a, 0x44b065bb, 0xf1cccbeb, 0xca6ec979, 0x326ec990, 0x18c2006d,
- 0xbdb0d78e, 0xa3716e3b, 0xd4fb3b3d, 0xe6439060, 0x182b567b, 0xe4233e0f,
- 0x892be992, 0x56fdd7d3, 0xda5357a2, 0xfbc8828c, 0x4f86972a, 0xf318333a,
- 0x7ababfbd, 0x4f8f1072, 0xe5a3fe11, 0x7f455fdc, 0xf9f53a63, 0xc62ee386,
- 0xe9c7e547, 0x5c270df3, 0x1f951feb, 0x1f951397, 0x3f574437, 0x95111959,
- 0x2a2e371f, 0x075cae3f, 0xae982f4f, 0x9d533f6b, 0x2d6f83a3, 0x7daeaefb,
- 0x5d4ee795, 0xbbca9cfd, 0x79b7f574, 0xf3c1d6ef, 0xb5d7efab, 0xd7abe05f,
- 0xe5777fd5, 0x20f5740f, 0x8bc6622f, 0xf74a3c31, 0x613dd386, 0x3016a0fa,
- 0x3d8637bc, 0x57722920, 0xf471fea4, 0x1e4c5fe1, 0x71e3f7c2, 0x3b093fcd,
- 0xc4591c78, 0x838b595f, 0x7c5ab1e2, 0x9a763436, 0xb722fd15, 0xbd434d45,
- 0xf5cb7ece, 0x74380b06, 0xdf89cb71, 0x1b76a4ab, 0xfce9b292, 0xb3b051e3,
- 0xef30f97d, 0xe927cf20, 0x1c6b001f, 0x500ddbe3, 0xd7febb42, 0x2237cccc,
- 0x9e2c1e62, 0x3cb585c7, 0xe64f3107, 0x8bf3e049, 0x61f7cfe3, 0xfd1f313c,
- 0x0f952b38, 0x4173b53a, 0xf6bf6195, 0xf2807332, 0xed834b11, 0x036f9866,
- 0xc51447c8, 0xc74e5e12, 0xbd4db838, 0x7aaa3de1, 0xb3dd3a7f, 0x050d2db1,
- 0x3aa5d04c, 0x3d1fd1e4, 0x7cdbef02, 0xe314e28c, 0x11ffec87, 0x433ce1c6,
- 0xbb3f345c, 0xf7bcf1cc, 0x74b97ff6, 0x9265e518, 0x45f5ee93, 0xb1dda7d7,
- 0x6e37f3f9, 0xd177bf50, 0x765bdef7, 0xdf6ff7a3, 0xa231b674, 0xcbf9afbe,
- 0x13ccfeb6, 0x66590741, 0xad55fdfd, 0xfae10ef4, 0x3358dd7d, 0x49272fc5,
- 0x604399be, 0xfec6cfbc, 0xe1db7bf5, 0xbe2b4fbd, 0x3bfd1db8, 0xe7c5ee78,
- 0xfaf08ed0, 0x2c95e669, 0x04399e7c, 0xb3d47fec, 0xbe662c71, 0xadd05f9c,
- 0x45d3569c, 0x99aa79fe, 0x6b4e43e2, 0xb0f3fce7, 0xf1516def, 0xcbf46682,
- 0x447baf01, 0x8f8b447c, 0x59fa2ddf, 0xe9494a21, 0x660e73a4, 0x527dd00d,
- 0xc5ec5ecd, 0x86328e0f, 0x936ca37e, 0xc5ca442f, 0xc53354f6, 0x4cc52407,
- 0x3292e779, 0x2823be8a, 0xe78fa381, 0x985b7637, 0xd4f68cfc, 0x900f1451,
- 0xce286342, 0xa885b360, 0x2fb6bf3f, 0x77dfdeaa, 0xbcd3cf5a, 0x759feefa,
- 0xc7704f3f, 0x1e6a2718, 0x47d61e38, 0xccc0738f, 0xdcb9dfb8, 0xf1be331a,
- 0x0d8990e2, 0x5f915243, 0x82dd773b, 0xd8bbfafc, 0x312b5972, 0x81183e8f,
- 0x6486879f, 0xfe605d13, 0x5c62307c, 0x848f97cc, 0xdee80281, 0x6aa0c104,
- 0x71425a06, 0xa13c7083, 0x6acd9a07, 0xa087d93a, 0xf71f70fe, 0x0a7e7e09,
- 0x51fc8d68, 0x03ef87e1, 0x51f2c63e, 0xda7642bf, 0x843fe07e, 0xa8bbf09f,
- 0xa80bfa0c, 0xa957e83c, 0x8cbf90fe, 0x1efd27e0, 0x2bf88f82, 0xefda7ca9,
- 0xf8cfe7a5, 0x85fe09ab, 0xab6547df, 0x7f3d257f, 0xf0475fce, 0x044dfe0b,
- 0x42ed12ff, 0x9a27cf19, 0xdfd97ca8, 0xf8aff542, 0x9afc11f7, 0xc865483f,
- 0x1f9e847f, 0x7c12b7f5, 0xf046dfdc, 0xe0887f09, 0x95077f0e, 0xf4c3fa6f,
- 0x5dff94fc, 0x2758afde, 0xfc672278, 0x45b49780, 0x79da1746, 0xcc968b69,
- 0x6f7800ae, 0x6df74cb5, 0x4be40b9d, 0x1e2e8007, 0xf7f26555, 0x5234aef6,
- 0x2bb347dc, 0x486cd6f7, 0xb9faa72a, 0x1592df54, 0xbed9764f, 0x77ba66a5,
- 0xedc55b6d, 0x46ccb659, 0x32c56ded, 0x72ba3fd5, 0xcd8dd92e, 0xae300538,
- 0x07818c32, 0x25bb6326, 0xfbdf9246, 0xefbae2a2, 0x6f79fd89, 0x45efcc88,
- 0x2253891d, 0x5b6b21cf, 0xbaf07493, 0x7ce50cb6, 0x25dcdd04, 0x989b61c6,
- 0xc49df91c, 0x33bdf64f, 0x79d602af, 0x0f7be497, 0xfba7c8e5, 0x3403cdcf,
- 0xcbb5a331, 0xc8e4fc8c, 0xbea7ad89, 0x4b3fe4d4, 0xdbf8893f, 0xbf84caab,
- 0x69c6eabd, 0x2c5fe8b9, 0x137be992, 0xcfe48b69, 0xbfe99fd1, 0x997ba640,
- 0xc53255b6, 0xa322d903, 0x5a46c7c0, 0x7305ff77, 0xe9b95ea9, 0x9dd1c514,
- 0x27878eab, 0xf802dda3, 0x387da3ca, 0x4fdf8494, 0xd77110ca, 0x94f1297d,
- 0x9f3d1637, 0xf8bbff2f, 0x19f80cd9, 0x5f3f1315, 0xa3cfc2c6, 0x7f75fee2,
- 0x68857df1, 0x31df693c, 0xcf7c547d, 0xc791b03b, 0xa5dba3ef, 0xe62ab888,
- 0x4ff7d174, 0x1f92656a, 0x81f059fb, 0xc59d807c, 0x7de3dd32, 0xb3ead264,
- 0x733e6007, 0x114a7c8a, 0xc855039e, 0x26c65147, 0x6ffef257, 0x893f235a,
- 0xbaf40574, 0xb76849ea, 0x99fa617d, 0x05fb287c, 0x7f18ed5c, 0x9fde8fb5,
- 0x8df313e1, 0xc5b217a5, 0x447bf63c, 0x81e614fc, 0xaadb3b71, 0xf9c785dd,
- 0x504559b8, 0x657accef, 0x77fd5e2a, 0x9832edcd, 0x2c5feca0, 0x2cf1c7af,
- 0x893f4ddf, 0x3c06a5e3, 0x38c578da, 0x53c537de, 0x69157dd6, 0xf75deeb1,
- 0x4ebf0f25, 0x12288e0e, 0xb00674f7, 0x1f072801, 0x9c527531, 0xcb86703a,
- 0xd326a641, 0x71e8b87d, 0x98fbcafa, 0x6193f028, 0xd10de7e1, 0xf6eb4def,
- 0xee54025b, 0xa2aff4f7, 0xb2c9a83c, 0x233d0ef8, 0xc4c37b7f, 0x0dcb6578,
- 0x421e63ce, 0x36840bf9, 0x7e8988be, 0x7ef2a732, 0x9b9fbc8c, 0x27827ad9,
- 0x0dc094da, 0x8b7601ce, 0x5157507e, 0x95c2c45e, 0x3de11abb, 0xca265bfb,
- 0xbe4bb355, 0x7e77245d, 0xe47f912b, 0x3aacb634, 0x62dfd116, 0x1ced1eb1,
- 0x8a35f302, 0x88f39ee4, 0x91f01af4, 0xbdadf022, 0xd1c450b7, 0x6f7ebb1f,
- 0x1445e512, 0xfb438c6f, 0x12b32f6f, 0x214cd81d, 0x7f0238a5, 0x0eff0336,
- 0xebfcf44e, 0x1e5acc8b, 0x28e26d80, 0xfc64473c, 0x51ca30be, 0x3eabf798,
- 0xd1deff07, 0x0fa677a2, 0x17fc7807, 0x383f9d32, 0x7bf3c597, 0x52367fd0,
- 0x226bcf7e, 0xb59df85e, 0x2c3f7415, 0x4ff44b1d, 0x78054fd1, 0x86a666fc,
- 0x8d9f7df0, 0xaf9bc1fc, 0xed22e7c9, 0xec152412, 0x4645dc6f, 0x5d71e5f1,
- 0xd83eeeb2, 0xf6fa8b98, 0xfa12ffb0, 0xfa9de9b5, 0xfe426976, 0xe8da473b,
- 0x1f769d1e, 0xdee5f9cf, 0x13d272c2, 0x1fff24f1, 0xe7e26553, 0x076d4ac7,
- 0x2b76ddb0, 0xa27e84bb, 0x4155817d, 0x8ceed039, 0x1b6ab927, 0xf3f64f11,
- 0xd6a3ccf6, 0x659fc04e, 0xda0a3be4, 0xbe2d032b, 0x7ebb1803, 0xbcc668b4,
- 0xc72431f4, 0x5c03be7b, 0x2f077a06, 0x733c1037, 0xbda6920f, 0xe9df48d8,
- 0x63345fda, 0xb68c804f, 0x5b979a16, 0x7cf30652, 0x35786ec0, 0x9c760dda,
- 0x63b418fb, 0xd0e01ea0, 0x9401df70, 0x7529e947, 0xcd5748ed, 0x292ba3b6,
- 0x429a5d0e, 0xabe4d572, 0x689ca10b, 0x91ac4b56, 0xc9f1adfc, 0x1afbe5b7,
- 0x3afef711, 0x7ebafffe, 0x4df3e2fb, 0xfaef9c85, 0x7e68038a, 0x9a7f747e,
- 0x60c6ff5f, 0x90a37efe, 0xe6b381e7, 0x70bf7298, 0x65279728, 0x5661ef22,
- 0xaf7d254a, 0x53a0567d, 0xa1d3fca6, 0x9bd80fdc, 0x867ca76a, 0xc2166ebd,
- 0x016079f8, 0x2ba40fd7, 0x29b29e88, 0x086cd54e, 0x3c1c812b, 0x70b90d0f,
- 0x97e09c5f, 0xd17bffe1, 0xa418d0bc, 0x7d05d8ef, 0x393df871, 0x17e747e8,
- 0xc57b4ad8, 0xd77ec9ab, 0x1f78d0e2, 0x439bbf1f, 0xa09820ae, 0x7d236af6,
- 0xbdfa261f, 0xf0f4bb9b, 0x787a6b84, 0xe77fd322, 0x87aadca5, 0xf87a2b27,
- 0x6e472153, 0x9f3fd749, 0xfdc3d2ea, 0x338c1c17, 0x1415fbf2, 0x828ed2af,
- 0xc60ef7e1, 0x200806c5, 0xfca16a47, 0x6b9d01a0, 0x3f341e48, 0xbff88338,
- 0x7c7d1aff, 0x6dd59d38, 0x9c603649, 0x59dcff5a, 0xefd68674, 0x073fd1ac,
- 0xfc60e83c, 0x7dd209ec, 0x3c9f70c5, 0x387fe614, 0xe657e79f, 0x7869de48,
- 0x5a0263e4, 0xfdf915bb, 0xdb8fbe76, 0xfe0b5f64, 0x4adb16bf, 0xa0af2853,
- 0xb5f7c2cc, 0xf77c58ab, 0xdf8525a6, 0xbcb35edb, 0xa67f0dc9, 0xfba6cc8d,
- 0xfedd6dd8, 0x2be48fb5, 0xe291be3b, 0x646b7bff, 0x8676aefa, 0x85eb4035,
- 0xc5d15c75, 0x5cba34a9, 0x6049cfc0, 0x587aba3d, 0x3d3d15cf, 0xa874443c,
- 0x31f90bad, 0xe45eb110, 0xfb4440c3, 0x72fb86f7, 0x8fc8dd71, 0x72e3cf91,
- 0x0f744d3b, 0x2fa7ac59, 0x42e4d4be, 0xd68f3899, 0x10bed2f2, 0x69796a63,
- 0x695e451b, 0x878f439b, 0x5127aa2f, 0xf08be11c, 0x0c5f789c, 0x0fbe453e,
- 0xc7be73e4, 0x87bc3b72, 0xfae7bd7c, 0x1e38a9e2, 0xc44081ca, 0x084e1bf7,
- 0xed87fc3a, 0xbb2896ca, 0x3fbfecfb, 0xaec8cf59, 0xeb0a1cac, 0x8e781dac,
- 0xdf174fdf, 0xf4213ab7, 0xe9c094be, 0xebbcafa6, 0x56bc9efa, 0x8a5bae2b,
- 0x12bbe3ca, 0x020daf85, 0x57fbda5f, 0xd3c26c94, 0x6b728e95, 0x4262785f,
- 0x1f21323e, 0xb32a7bf1, 0x4c6ecfca, 0x3a5b1955, 0xf879b9f4, 0x7759887d,
- 0x02cd2d9d, 0xd7d0f378, 0xb3d3fc38, 0xa6800c2f, 0x2dfcfd1f, 0xf67c3f0e,
- 0xf9154c8b, 0xe1e73ff2, 0xe21c23f7, 0xaf9b45dc, 0xa1fade36, 0xb758dedc,
- 0x238f1ce9, 0xbf3a5ec8, 0xc97a77ac, 0xa52cffcf, 0x07e781cb, 0x9cbb52eb,
- 0xd7206e4b, 0x40ba6dd7, 0xe9860c71, 0x5f30a351, 0x9f129188, 0x57c7e5ad,
- 0x1de3f3ea, 0xd7c4d58e, 0x50501616, 0x3d59c5de, 0x7d7e7e74, 0x73e68ba8,
- 0xf9ab531b, 0x0f2bb9f9, 0x5dd667f7, 0x5ff69886, 0x8f9150e3, 0x68df42ca,
- 0xf2f2265c, 0x768994e7, 0x7117f8ca, 0x9e8cdb9c, 0xfffbd446, 0x2a51663a,
- 0xbf2d098a, 0x3dcf4869, 0xe6df43b7, 0x0face4fe, 0x24575c0c, 0x53f178f2,
- 0xcf345dc3, 0xea0038c8, 0xe5f6be85, 0x3d53d088, 0x38a1e2fb, 0x87b27d67,
- 0xe5d28bef, 0x92fb82d8, 0x5adce5d4, 0x7bfaf7d4, 0x3e144fed, 0xcd32875a,
- 0x7e90967e, 0xda7f0ebf, 0x607968fe, 0x1e5706f5, 0x87172bd9, 0x609fe2e8,
- 0xf6bcbbe8, 0x718df4d8, 0xa7360d4a, 0x648e297b, 0x300b514a, 0xeffeb84f,
- 0xe9bccc52, 0xb74e8273, 0xbee9e238, 0x4cc3bd75, 0x1ddabdf7, 0x61da183b,
- 0xc236db56, 0x89a3854b, 0x835c9e61, 0xb7d2b59b, 0x82f2a20f, 0x790bec1b,
- 0x659f2a7d, 0x8e4d54c3, 0xc6d67e71, 0xdc94aabb, 0x772a2e30, 0xa3affff2,
- 0xf2477aaf, 0xec1f9e34, 0xb07e5330, 0x8bae6894, 0x26dc1f95, 0x5c768dec,
- 0x83ae0a57, 0xf5b4c9c7, 0xaf3c5d58, 0x9c639f11, 0xd1f2eccc, 0xada2e3ff,
- 0x87ec4dbb, 0xaae2ded6, 0x25ef2863, 0xf942eab3, 0xff73c52a, 0x4147f51d,
- 0xc6d49c84, 0x89a87e7f, 0xae1b0bdf, 0x2b35fcf0, 0x7eb317d7, 0x7f19886b,
- 0xf3543abf, 0xbf19beb7, 0xdb32f469, 0x3461f3c8, 0x336b9ebe, 0x981ed07b,
- 0x7ca74b6b, 0x8040b99d, 0xda239317, 0xbf3e677f, 0xe9ab29bf, 0x1bbf4748,
- 0xdfc5e137, 0x4c36f801, 0xf6f4f117, 0x6bdd1354, 0x3cc0db7a, 0xe74652e8,
- 0x49bd7a23, 0xb79a7193, 0x80db38ce, 0x31d8786c, 0xcbe504be, 0x13728ee1,
- 0x3b0067de, 0xca186e21, 0x46eea599, 0xbf30efbc, 0x7fbe98a6, 0xd77fc5a2,
- 0x49303d09, 0xddb039f2, 0x9a3f6367, 0xde6c4155, 0x7fdf4595, 0x88dff114,
- 0xbb44fd76, 0xaca26ed3, 0xc03efa2e, 0x45e8e515, 0x83f68b9f, 0xf1a21af2,
- 0xf912fb89, 0x72698bff, 0x8b3bf502, 0xe123b3b2, 0x949d89ed, 0xa9e9af6f,
- 0xcdf23ea6, 0xf2130db6, 0x714fe351, 0x7cc7109e, 0x6493c456, 0xf37b72f0,
- 0x3f4fd3c8, 0x37b1eced, 0xa43d0877, 0xd05093f5, 0x2209954a, 0x78a0c4ef,
- 0x2564fe88, 0x75801e90, 0xfb197d36, 0x61dcf89e, 0x716d8e5c, 0xf6c74b6f,
- 0x3a6ab915, 0x79d14bfa, 0x51eef5de, 0xf57fc8e9, 0xaafd3553, 0xaff9235a,
- 0x7bff9ddd, 0x75b42f3c, 0xb9e45898, 0xc669747c, 0xe41bb573, 0xfdc59bed,
- 0xc7476dc8, 0xbcbe3158, 0xc61256cd, 0xb66dd9f3, 0xbb721294, 0x478f3c6c,
- 0xf1b36f6b, 0xca9b3abc, 0x1b36d5e3, 0xf2d37bcf, 0x27ddda6f, 0xbb5a0f08,
- 0xfef8c3e1, 0xff7e54d9, 0x520d5e21, 0x1bd938bb, 0xb8acbcc0, 0x66f64614,
- 0xc77f959c, 0xc8c0a12f, 0xf9fc31ac, 0xea266182, 0x49665b67, 0x9b54ec98,
- 0xd87642ec, 0x4e925e96, 0x0df11272, 0xbbdbd6e3, 0x19f745f1, 0x6b7c0856,
- 0xf3b7d4fd, 0xa9bede75, 0x08c56e72, 0x8bbd13b4, 0xd9b74e90, 0xbf315896,
- 0xde97b254, 0xc3f5bfb0, 0xca7cba0c, 0x7994fe9e, 0xd815bfa2, 0x512f649f,
- 0x8b133fb0, 0xfa0cfffd, 0xbbfebcc5, 0x819815e7, 0x60e3df46, 0x9e4fbb4c,
- 0x68cf4b1e, 0x439c55a5, 0x0ff7bf44, 0xfacd95db, 0x93d82578, 0x75830d0f,
- 0x3b9e66d5, 0x709e9131, 0x5e31b27b, 0xd849177c, 0xdbc2b285, 0x3df91a37,
- 0x637bed4d, 0x27289d9a, 0x73d0f1e9, 0xc3ef8a7f, 0x31c78555, 0xc518daae,
- 0xf9f9a257, 0xba63a9ea, 0x67a8107b, 0xc6dec23d, 0x8f48ed12, 0x3895cf19,
- 0x8efc6b5f, 0x3f28ba77, 0xf77f9aaa, 0x2918a6c4, 0xf400c25f, 0xddad744b,
- 0x8a4af9df, 0x115d7f69, 0xab486afb, 0x6dbf8951, 0xa32c42a1, 0xf3bf7bf9,
- 0xf3f22154, 0xfadd69fe, 0x6d75c156, 0xf7e5ca48, 0x564e4f17, 0x5fc3d962,
- 0x71c25f77, 0xa4ddc76e, 0xcf5c9d67, 0x3fbebffe, 0xaf34e8d1, 0x66debd44,
- 0x97f7fbd0, 0x50fddc85, 0x9afd8ff0, 0xdbbcf74c, 0x22ef7c8b, 0xde8c98bd,
- 0xfb07d46a, 0xbf9366eb, 0x501e0324, 0x30dfeeef, 0xc0af2a2d, 0x08b0fef7,
- 0x326b2e7e, 0x1aa677d3, 0xbf208fc0, 0xa31f6a2e, 0xb7eda7f1, 0xf9abdb06,
- 0xbfb69a39, 0x216cd313, 0x764bb791, 0xb9653387, 0xb398e501, 0xd9f067da,
- 0xec987db1, 0xfddabe8d, 0xad3bc84c, 0xb7fb0dbd, 0x3c4afce1, 0x8c4c7bfc,
- 0x6b24aef2, 0xec7fffec, 0x810f0a30, 0xcbac2b1f, 0x82aa7471, 0xeec24afd,
- 0xe8f9146d, 0xd5a94af5, 0x94bef113, 0x149d6a54, 0x7df52f41, 0x874a87c4,
- 0x942bdb77, 0xfce5a7e7, 0x60af684b, 0xbe4d9f5e, 0x20471ddc, 0x675e20ff,
- 0x47e36a2f, 0x9cf7bb9f, 0xbe3a73b3, 0xbd9294aa, 0xbb018f28, 0x4307ec00,
- 0x489bd2d2, 0x3f7c9a3f, 0x743c034e, 0xfca167bd, 0x3f05f7db, 0xec7e0a76,
- 0xd8056e4b, 0xb7dcba51, 0x4bc71d95, 0x2527401e, 0xf5274889, 0x39dd4699,
- 0x8b16568c, 0x5fb0c675, 0xfc8f87f2, 0x90cbf646, 0x17ec31e1, 0xcf224fb4,
- 0xf12ed1cf, 0xb445c844, 0xec313c4b, 0xf0a36697, 0xe779c4df, 0xadab9369,
- 0xfa70f013, 0xcefa44e6, 0xdbb469cd, 0xfb3ec04a, 0xdc5cd9e9, 0xee865994,
- 0x3b0853ef, 0x760c1191, 0x5e7077da, 0x1abbcc55, 0x1cd6ffff, 0x883f1bc9,
- 0xffd197e7, 0xfb75f2ab, 0x40b80719, 0xfbc76cbc, 0x1f744570, 0xf9d632ae,
- 0xe9baf7da, 0x88974504, 0x601e11c3, 0x5be22217, 0x5176e2bd, 0xa30c3a71,
- 0xe6fde774, 0xfdbf6ef4, 0xdae281ba, 0x882c7d3b, 0xb5bfb9df, 0x7b571f4c,
- 0xed99e443, 0xcf88ca5c, 0x86b41676, 0x53495fd0, 0xabc9c519, 0x73f6fa3c,
- 0xe3bfa32a, 0xddbf8fac, 0xcf4535e6, 0xd6ebbe97, 0xc06fac5f, 0x9714d5ee,
- 0x8b8f15eb, 0xfad1c38a, 0xf2943f50, 0x46adbc78, 0x6f655f9f, 0x7ddf419e,
- 0x12aeac66, 0x34cce7d7, 0xda8f8c32, 0xcff3a3ab, 0x1ecf0202, 0x9e1a5a12,
- 0xd878efb5, 0x7bfc8d8a, 0x540981a4, 0xe1c1e5af, 0x3a2705f7, 0x5b65d67b,
- 0x2c53e62f, 0xd881ace2, 0xf189daeb, 0x2e57cc46, 0x83c4830a, 0x302e70fe,
- 0xa30d464e, 0xbac299ef, 0x8705e775, 0xd0356f77, 0x03e147ff, 0x3c26ed71,
- 0x9813cfe8, 0x5afb40cf, 0x807f3fa3, 0x68e0ea75, 0xecebfebb, 0xb3bbc3f9,
- 0x58ff7e63, 0x5038b52b, 0x7610f8af, 0x383a4800, 0x6ca77c5c, 0xf68a1b28,
- 0x2378ad8d, 0x4c95c3ed, 0x0acaf79e, 0xa1bb9f62, 0x0ddf8f9d, 0x327c8a9a,
- 0xa679fd12, 0xf302cefb, 0x6f9f94c8, 0x3573e328, 0xa672f3f4, 0xd7c4622b,
- 0xb1307896, 0xbcfff04a, 0x1fa0f78a, 0x8c00b167, 0xdf1063df, 0xbdc4969f,
- 0x26062da4, 0xd514cc23, 0xb5e4f3ca, 0xe9043cef, 0x8d7d0f3b, 0x8b077da3,
- 0xda7bf805, 0x37dfd138, 0x74fbd1ba, 0x7e894d1f, 0x3ae282bf, 0xe17df8da,
- 0x17efafbd, 0x9dfcb1fd, 0x953e3c91, 0xc35a7449, 0xeba71fb4, 0x2b74ddc5,
- 0x53b83c93, 0x0f0f4eab, 0x773e7e45, 0xf74a824f, 0x0475b56f, 0x8eb44ba6,
- 0xf75fd96f, 0x595dd23c, 0x5881defc, 0xdbefe897, 0x117e8bae, 0x9301acf2,
- 0x1a8e816f, 0xcf91ef81, 0x2e93296c, 0xa10e74c9, 0xbf8bcfbf, 0x35fd1173,
- 0xf9493d1c, 0xbdc47b3b, 0xa75c6d70, 0x8a0433ea, 0x3c107ef0, 0xd08f118f,
- 0xdf8ca5ca, 0xf5e6d28f, 0x3504017f, 0x7fe05f6a, 0x00007fe0
+ 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, 0xe733ff00, 0x51f86062, 0x39fbc10f, 0x716e1819,
- 0x0143f822, 0xd9433117, 0x1017fa40, 0x606463bf, 0xbc48cf78, 0x040e357e,
- 0x033b2f7b, 0x3e200ac3, 0xfef03ec0, 0xc95c481a, 0x4ebb3f4d, 0x622ed1d0,
- 0x067e2ef0, 0x0c023d86, 0x1082590c, 0x54417ffe, 0x08fcddf9, 0x651898b6,
- 0xf5012976, 0x93320003, 0x038009d3, 0x00000380
+ 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, 0x7dd5ff00, 0xc5547c0b, 0xbddcf8d5, 0xeecddd8f,
- 0x21079b26, 0x086e3c21, 0x4bc60a22, 0x9bade102, 0x88b46204, 0x7d608a89,
- 0x8420182d, 0x96d22247, 0xedf7ed7e, 0x5ab11062, 0x68db151b, 0x34105db1,
- 0x060b28da, 0x2df0980c, 0xaa5694a0, 0xd1f58df1, 0x90cbc8a0, 0xf87e8784,
- 0xce7feb69, 0x7bbbb999, 0x7c486eef, 0xfefdfbf4, 0x730ecfe9, 0x3399dee7,
- 0x9ce735e7, 0xc92b3339, 0x210cb102, 0xbbf81be4, 0x22ad909c, 0xa46c6421,
- 0xe5a22aec, 0x79fc4218, 0x8126c08e, 0xafaed090, 0x4234908e, 0x54cd364e,
- 0xec84d9ad, 0x2e8473ce, 0x0327eda7, 0x6d2b0185, 0x76f6de2f, 0x4beb44a2,
- 0xb41289b6, 0xf1d9765b, 0x4275cefb, 0xd6d5ea00, 0xd12607b6, 0x9136f77a,
- 0x935da06c, 0xd242d390, 0x23623909, 0x61754fec, 0x559dbe7d, 0x7ddfac97,
- 0xd9578c2b, 0xfa76256c, 0xd12691fd, 0x9b65f503, 0xe3a10084, 0x8f71d92d,
- 0xb7f68032, 0xed042020, 0x7a6fad2a, 0x845d5150, 0xfdebb5dc, 0x212776c4,
- 0xa2367c27, 0xca8f382a, 0xaa4228e0, 0x064a5b02, 0x1aabefd0, 0xfb42cd05,
- 0xaa775aaf, 0x6aabe013, 0x69102f92, 0x1c1a8b7f, 0xc6c11d44, 0x78c086fe,
- 0xbc703b7b, 0x1830f26d, 0x3bebf2af, 0x3cc22215, 0xb77c0f65, 0xf301c284,
- 0xe13dc7d6, 0x74f1c7ab, 0x9a792e7c, 0x5bdf478e, 0xc1a09cfa, 0x885a9714,
- 0xdce8e017, 0x84fd9f61, 0x52b7e613, 0x9e8aee19, 0x30ed9cc7, 0x7ac0aa8f,
- 0xf009c4a5, 0x8fe657ad, 0xa8b7f48a, 0xf846f7e1, 0x7bfa73ea, 0xe5cddaa3,
- 0xe9451f09, 0x8abd48f0, 0xf6904f10, 0x5280a44b, 0xf9e4497e, 0xd2324207,
- 0x4883517b, 0x7fa45b54, 0xfa42794a, 0x9b7fffd1, 0xc1e293fe, 0x6c0aeadf,
- 0x6dd08eca, 0x16681b99, 0x3769dba1, 0x5dd4a3a7, 0x5ebfdd10, 0xa0f4003e,
- 0xdcf9d4f0, 0xcbe43e58, 0x4fad72c0, 0xd6fdbc45, 0x7acb0237, 0x1fcf869f,
- 0x72c78df3, 0xe583cf9d, 0x58a57c1f, 0xf8657c06, 0x6cdf06de, 0xbcfa372c,
- 0x5f49fcf8, 0xbe0d9625, 0x8cfe7c1a, 0x8d96056f, 0x7f3e3f3e, 0xcb06b7ce,
- 0xcb0eafa0, 0x5a2f40ad, 0xf802f936, 0x035f76de, 0x20becd96, 0x6be9df3e,
- 0x8e7ef2c6, 0xa4c9c4c7, 0x4878a250, 0x253710f4, 0xee99493b, 0x3d699429,
- 0xd3d58ca5, 0x2a17f66f, 0xa5ee9eb4, 0x01978a75, 0x5685438b, 0xc3501f5a,
- 0x92ff07da, 0x7d68d914, 0x0fb59fb0, 0x6453dfbd, 0x75a1f5a7, 0x3af87dac,
- 0xad02517f, 0xf6b00f0f, 0x45431b8b, 0x38bf5a0e, 0x5b73dac8, 0xd693b148,
- 0x9eac4373, 0xec53c077, 0x36bcf5a2, 0xc0f82f56, 0xeb489c5f, 0xfbeced05,
- 0x51011d89, 0x61d2c675, 0x4edeacab, 0xf9d6ad28, 0x1348f4af, 0xef515d68,
- 0x8fc51a24, 0x948f5aff, 0x7b21f149, 0xbfe43db0, 0x149bdb09, 0xe1bfb60f,
- 0x76fac0af, 0x87ed8bd9, 0x5d584bfd, 0x17fb62f1, 0xbd629ffe, 0xbb63f659,
- 0xd58fa56d, 0x0fb63f15, 0xfb06b958, 0xb00729df, 0x07cad47d, 0x12a77db1,
- 0x5687f6c0, 0x4a99e63d, 0xf782b5eb, 0xb48fc0b7, 0xc03924ac, 0x328cc14f,
- 0x05ab4fca, 0xf7f81b32, 0x28e980bf, 0x54ceae5f, 0xfeb70e50, 0x9009e0ad,
- 0x834bfc5f, 0x7f27fcfa, 0xffdf8d95, 0x6991fb11, 0xfdef623f, 0xde3abde4,
- 0xabde4fd0, 0x0d3f7a95, 0xbdad5ef0, 0x7d6cfd6f, 0x9e11a275, 0x7ef4ab57,
- 0xae3c20b6, 0xef2bcdbe, 0x7846c9b5, 0xf7ac5b5e, 0x49e113b3, 0x4d3c1bee,
- 0xd3f11b6f, 0x3f1876f4, 0x7e9e117b, 0xcc67837d, 0x8cfc463b, 0x9f8c2779,
- 0x664fd803, 0x7a69fadf, 0xa69f88c7, 0x79f8c277, 0xa835e71b, 0xf31af36f,
- 0x633f11ae, 0xe7e30dde, 0xbb278423, 0xff6cfd6f, 0xed9f88d0, 0x73f1861f,
- 0xa0b9fb14, 0xf82af36f, 0x829f88c8, 0xe9f8c28f, 0xea2e7ec6, 0x3fdb3f5b,
- 0xfb67e232, 0x7cfc6147, 0xd25cfd89, 0xfc1579b7, 0x829f88c3, 0x63f1847f,
- 0xd19fa011, 0xf9a7837d, 0x9a7e2353, 0xc7e30d3f, 0xed8cfd81, 0x8fe33c1b,
- 0xfe33f118, 0x693f1848, 0x427dd002, 0x3e69fadf, 0xf34fc462, 0x067e3091,
- 0xfa533f61, 0x47f1af36, 0x7f19f88d, 0xe19f8c34, 0x2a42af38, 0xa10f00f7,
- 0xee7ab8fd, 0x2349e767, 0x0c9e767e, 0xec52e7e3, 0x27ed1a67, 0x267ef7a7,
- 0x33f11a76, 0x9f8c33b1, 0x95cfd8f1, 0x6767eb7d, 0x3b3f11a7, 0x29f8c33b,
- 0xdd5cfc44, 0xec4d79b7, 0x6267e232, 0xfe4fc317, 0x89c5355b, 0x85ae9db4,
- 0x993f489a, 0x08f1e1d4, 0x59ba2eb4, 0x046b745d, 0xb75112ec, 0x479b4837,
- 0x1b3bdfa4, 0x457ef393, 0xa28eeda2, 0x8b979872, 0x76d1635a, 0x04f8d247,
- 0xec939d83, 0x53d43149, 0xde18074b, 0xd43657ef, 0xf67fded0, 0x4cf686c5,
- 0x9ea19e6f, 0xf0d13955, 0x229aa0fe, 0x8ac87d43, 0x67ef0cab, 0xd435affb,
- 0xd8fcd673, 0x7505fef0, 0x17ed0d73, 0xda1957d6, 0x332c0a2f, 0xfc3647d4,
- 0x4bfde187, 0xda197782, 0x95fe6d2f, 0xe8747da1, 0x7f3d4321, 0xf78663ff,
- 0x306db6c7, 0xf83b8fb4, 0x427da18c, 0x7d4356fb, 0x269db1d2, 0x3ee9cf3b,
- 0x45d79232, 0xecc27be0, 0xed054cfe, 0xc14b90bd, 0x89c032ba, 0xd76efc76,
- 0xa530f57c, 0x76e7b2af, 0x17d28d35, 0xbae84a68, 0xf2a0385e, 0xfcfa76c2,
- 0x17bd13a7, 0x9ff3e9ba, 0xdd4bde2a, 0xca53ec71, 0x80c9020f, 0x6940b552,
- 0x6647bf6e, 0xf59458fc, 0xf443f0f5, 0xf74b6afb, 0xb75a64f0, 0xc0f58588,
- 0x2c107fbf, 0x2209a7c8, 0x12f781a9, 0x82fd04ac, 0x9e0bb27b, 0xebf147f0,
- 0x0e54419a, 0x6bbf4885, 0xd8066f64, 0xbe561b19, 0x643b07ee, 0xaf3a20f5,
- 0x213c8401, 0x0ff21ebc, 0x9a0fdfa3, 0xfda5e19f, 0xa76a1559, 0xd0af8f47,
- 0xf8e147f1, 0x73fe300d, 0x1d6f8c3d, 0xbe30de3a, 0x61a5706d, 0xc7429b7c,
- 0x607b5377, 0x7c7c7be5, 0x8489844a, 0x87bc2f3c, 0x57075be3, 0x28f7f8e2,
- 0x1e895fd4, 0x7e3c213f, 0x2ecbc833, 0x9c6c7f18, 0x689d0ff9, 0x2ae0ff9c,
- 0x3615fce3, 0x0f2b3dff, 0x7013f1f1, 0x43857bfe, 0xab83fe6c, 0xacadfcd8,
- 0x89f8f0df, 0x87effc61, 0xd3dabff9, 0x1b2673fc, 0xb1643fe7, 0x3656fe71,
- 0x8f2b1bfe, 0x389df1f3, 0x71c29bfe, 0x8b21ff36, 0xeac57c71, 0x947f80d5,
- 0x009a84ac, 0xa40c9f1d, 0xb03fa98a, 0xca071d0b, 0xa9942911, 0x30b5f909,
- 0x69f8e114, 0x2fb7e302, 0xa1bf2812, 0x73e3f1be, 0xad9aa012, 0x9c5dfa80,
- 0x163517d7, 0xb097a02a, 0xf32bfa9d, 0xcd15a838, 0x5937f222, 0x405c0d6b,
- 0x166cede1, 0x58af50fd, 0xfa00253b, 0x6e4adaaf, 0x24ef832b, 0x9fe78212,
- 0x86c9723e, 0xcb9979e8, 0x91f27579, 0x0b7928f6, 0x644551fb, 0x6f850d44,
- 0xd8c1301a, 0xea63fd48, 0x5fea1107, 0x0cfd407c, 0x13f25942, 0x11f78d99,
- 0xdea097f5, 0x6825fd4e, 0x7e256427, 0x2b7bbb47, 0xc65fc283, 0x6258ffe1,
- 0xcdf1faf2, 0xe54fc042, 0x8f9f8bf3, 0xb6f53f46, 0xf48a0e15, 0xfc731c08,
- 0x9d3a86a9, 0xd4e81f97, 0xd81ac3bd, 0x557e2020, 0x8a3957c0, 0xafb72126,
- 0x8eb8a2c9, 0x252effbc, 0xfd45267b, 0xf723c40d, 0xb2dfefa7, 0xa6e4185c,
- 0x58f4cee3, 0xe13ad8f3, 0x5ca0b2c9, 0x78cb2c93, 0x1a6dae42, 0x481ed32d,
- 0xb8fe47b9, 0xebdc6a3d, 0x99f58d4a, 0xa77ac665, 0x142d91ec, 0x8172ceae,
- 0xcefda7ac, 0xd76c6d9a, 0x525a71c7, 0x78f99d18, 0xbe0ce965, 0xc1e65059,
- 0x79d23763, 0xab7d9bb6, 0xbb7d53c3, 0xa0585d4c, 0x011fbfa7, 0xf0d3faba,
- 0xd9bb1fbd, 0xcef0cdbc, 0x329e6d96, 0x73d9cf3a, 0xb7f000c4, 0xefbffe19,
- 0xb92c7872, 0xb0f35cb4, 0xf3b12c4c, 0xa37fc331, 0xa09f3cd7, 0x4df0eb0c,
- 0x8ce7e695, 0xfa708e6f, 0x41fc0c7f, 0x1fc0a3cb, 0x9cc3fe14, 0x957a223f,
- 0xd5b547f1, 0xa1f8033b, 0x209151fb, 0xdcbf395d, 0x5e65f9c0, 0x082f919d,
- 0xc740caf1, 0xbc85b305, 0xc1f1455f, 0x0b07ce2c, 0x737c8dea, 0x99cbf10b,
- 0xe372e871, 0x6777f5da, 0xfbf3b1a8, 0x4dcdf390, 0xfc46eff7, 0xd193cec4,
- 0xa74e56e9, 0xed8c6a5b, 0xdeba7037, 0xbb3ae9c2, 0xa997c1fe, 0x563f20fa,
- 0x7bc83203, 0x7a742ff5, 0xe9e81bb6, 0xc334f4e5, 0xe7a72b79, 0xf4673fad,
- 0xcedbc334, 0x7f5ed9e9, 0x63432646, 0x77c335e1, 0xf9988adb, 0x39cf4028,
- 0xacf4f8fe, 0x3d4c2e6e, 0x497cf51c, 0xc3d4caf0, 0xa8b67251, 0x5f50dca1,
- 0xf0d1b818, 0x39fa82fe, 0x7579f686, 0xb7ed0d0b, 0x50c3b9af, 0xb9ffe39f,
- 0x56dbfde1, 0xdfb434ac, 0xa1af7352, 0x07caa6fd, 0xbd1bf50d, 0x9fde1a8f,
- 0xa1bd7b35, 0xd3d9667d, 0x4aebf686, 0xe5ea18b7, 0xf7861d9e, 0x870b5d85,
- 0xeabae3b4, 0x887f63fd, 0x4567be27, 0x3beb353e, 0xf61e2f5d, 0x88fcf8a9,
- 0xc796046f, 0x3f3e1a7c, 0xe58f1be1, 0x74dfd04a, 0x60ecb05d, 0x7343f565,
- 0xe2a3b886, 0xdac89f1e, 0xbdb3d060, 0x7dfd43e9, 0x7fa3deb3, 0x14ecf159,
- 0x902c5cbd, 0xbb075832, 0x3fad1db8, 0x49d7c53f, 0xb942ee42, 0xb930ac5c,
- 0xb335bc5d, 0x3d422488, 0x4e26bc34, 0xcf2c267c, 0x33e70141, 0x00c72eaf,
- 0x91fa82e7, 0xe036f826, 0xf9030b38, 0x1a8be786, 0xebbe1926, 0x7c222dd8,
- 0x27c6414b, 0xb65672c0, 0x85f002c7, 0xeebe0ef6, 0xb3d78012, 0x4beb02d7,
- 0xe7b43f73, 0xa9a57c3a, 0x73c02587, 0x7cc79619, 0xe23cb1b3, 0xd87962f3,
- 0xc7e58957, 0xdb2c1abe, 0xfcb02b7d, 0xf2c7e7c8, 0x2c1adf03, 0xc3abeeff,
- 0x1eafa0f2, 0x017c77cb, 0x35f2df2c, 0x2f86f960, 0xaf9b6588, 0x9f4ecb19,
- 0x5e5d4b07, 0x4865f8a2, 0xe8bf1466, 0x8fd74ffa, 0x9cbf38c7, 0xc7897e00,
- 0x7c8c1b17, 0x41ae5471, 0x43eb30be, 0xfacc1d33, 0xc3f2bbef, 0xdbb30b58,
- 0x443f2fbe, 0xa2659de8, 0xf46f4e77, 0xbd146226, 0x0cdc5ac7, 0xfbef4e1e,
- 0xf638de00, 0xb8b025fa, 0x83b28bf7, 0xff160e3c, 0x6a7a71e5, 0x2ff8b201,
- 0xbe96bb1f, 0x52f686db, 0xe3e80460, 0x77fe23d3, 0x4fb7c438, 0x6752b41f,
- 0x99f9e7aa, 0x1e23d7e9, 0x86fd0788, 0x28ba01f9, 0xdbb6c7e4, 0xed5e1813,
- 0xe84a5216, 0x05ef717a, 0x47736a4f, 0x29225d61, 0x2b407df0, 0x97e9c577,
- 0xdf80a0da, 0xeb5af0de, 0xfa1722fa, 0x57d8f23b, 0xb58e5005, 0x61343b30,
- 0x30f688af, 0x01a13d09, 0xdefac37e, 0xdc4065aa, 0xc502fbb8, 0xc071eb8d,
- 0x9f9fc469, 0xf8220bd6, 0xa8e297bb, 0xbab3d70d, 0xb0dfc40c, 0xf667862f,
- 0xe9bd7f01, 0x39f0dec9, 0xdfe03037, 0xf4decf82, 0x8b7a6f57, 0x9ae7d478,
- 0x76bbfce9, 0x2bf7925d, 0x50d4f415, 0x80f4ffe6, 0xc7bf7d6f, 0xf0254f0c,
- 0xf3bed8f1, 0xceba5771, 0x09836dc7, 0x906de71d, 0xe9ffda17, 0x80930ba6,
- 0xb41fb42e, 0x71b7bbbb, 0xba17b9fb, 0xf636cc9e, 0x2fe5cd57, 0x42925fdc,
- 0xb8e94b84, 0x4921452e, 0xbd161d74, 0x1bf4442b, 0xf83f76b4, 0x5a1cbbe3,
- 0xd8fe0aad, 0x2a435789, 0xdbf468f4, 0x227fef4f, 0x659bfc11, 0xe1f71619,
- 0xcbd47438, 0xb76cc125, 0x680fda33, 0xd74fd636, 0xf441a509, 0xeba4d493,
- 0xc075812f, 0x0c3c3eed, 0x960672f4, 0x32cb3f7a, 0x54e1f714, 0x23d33fa4,
- 0x67a8c98d, 0xf86cf84e, 0x470d0fde, 0xe044fd4f, 0xd09f2268, 0xdf1481ef,
- 0x7efcf4e4, 0x9d20728f, 0x485e2055, 0xc02fe45a, 0xffd3b37f, 0xfd0a19be,
- 0xfbd7584a, 0x7e8a0ead, 0xbcf0a5eb, 0xfd1e30d1, 0x32f7d54e, 0xe59ebbe1,
- 0x7447224d, 0xdb74a77e, 0x175bf7c2, 0x46ddd835, 0x50d930bb, 0x74ce6eaf,
- 0xf844ec1b, 0x95c21807, 0xb77c0482, 0x975db398, 0x7c035ce4, 0xe3043f74,
- 0xf605df80, 0xbb5b12de, 0x4c5155e2, 0xe72f80da, 0x5ef9d78e, 0xd53ef59d,
- 0x915fc74f, 0xf917c809, 0x1055429a, 0xa0ae8fe9, 0xb7eb42c4, 0xa6dcdaf3,
- 0xbd61d345, 0xf6616e3a, 0x4b290578, 0x92b37f04, 0x7c4015d4, 0x94b124f2,
- 0x249e5c82, 0x47e6246f, 0xa2fbe1c9, 0xbedcf082, 0x531768c6, 0x5f50d97f,
- 0xcfac6f50, 0xc3a6d727, 0xb5fcf2be, 0xa0080932, 0xafed8c2f, 0x168e4c88,
- 0xb0d59a90, 0xd995afbe, 0x4dd7363a, 0xdf0a2ca4, 0x2f1e1792, 0x1feb4398,
- 0xd31ecc8b, 0xa61745f7, 0x82abf830, 0x6d0f15eb, 0xff29a4ff, 0xe879aa06,
- 0xb0d581f7, 0x09b7f95e, 0x963526da, 0x7e16df7e, 0xfafabc33, 0xcb3fb31f,
- 0x20d258e1, 0xec710278, 0x0ebe6e80, 0x4d2e7aeb, 0x08e21b72, 0xe2a3d42a,
- 0x9f99df0c, 0x9f8188d2, 0x36bd17ee, 0x1fe31fa9, 0xa904a7f0, 0x9f7ef15b,
- 0xfa6233fe, 0xfec6934f, 0xa40ffd80, 0xfa1817fd, 0xf8507f57, 0x3fc0c587,
- 0x4bff5e2a, 0xbb76785e, 0xaa93ea9f, 0x12248fcd, 0x971e3eba, 0x4a35d2ea,
- 0xee9bc5df, 0x1f3a044e, 0xc089fc93, 0x6203c7af, 0x7ace2069, 0xe9d25735,
- 0x100a71ed, 0xd27f82c7, 0x733c4ffe, 0x5ff7fa1f, 0x18dd926c, 0x86b06a9f,
- 0x971e54ac, 0x4e9c2d36, 0x887eb172, 0x2539efd5, 0xc8d9bd42, 0x3d4f557f,
- 0x0af90e92, 0xbc785394, 0xecf68426, 0x969f8dd2, 0xba44bae0, 0xdfcc8e51,
- 0x52e7f8c1, 0x51cdff50, 0x29db6292, 0x5777e89c, 0x3754bc73, 0x4c4a77dd,
- 0xa3b57f84, 0xbf7e6c3f, 0xd7a5db92, 0x23b4ae49, 0xe32704d4, 0x87d038c8,
- 0x80483e3a, 0x0be2a5d9, 0x1c42e78f, 0x2be363b2, 0x9e144289, 0x1d3a3974,
- 0x3b8ffdbc, 0x6df59ed5, 0x68b39527, 0xaf5f47fb, 0x4f6e66d4, 0xb172b0b7,
- 0x449c4a1c, 0xf5e2e0f5, 0x8fa7e6b2, 0xc4fb3f17, 0x5c418f93, 0x76ab3df0,
- 0xd17fed01, 0x33bf2fb3, 0x6d17d691, 0xb3a6d391, 0xf4853869, 0xe9aa5d08,
- 0x22f22b7f, 0xfe7aa874, 0x84bd4565, 0x4a65ff3d, 0xb68b1e84, 0x25c856ec,
- 0x0e28f8b1, 0x9dda56ee, 0x3c12e871, 0x81f60254, 0x153fc2f8, 0x5df1fba0,
- 0x1d9fe902, 0x5feb9f07, 0xf01ff5c6, 0x74e47484, 0xf4cdd30a, 0x0ba5357e,
- 0x4e9d6be8, 0x5cb1f6e6, 0xea7f40bf, 0xe7e7e428, 0x54fc5276, 0xc1aaddfe,
- 0xbb9f2bfc, 0x71e61133, 0x7c61aa54, 0xe9ddf8fd, 0xa56e3a1e, 0x63774fec,
- 0xfe579ec9, 0x6fc827e1, 0x49ff5e0b, 0x8867c63a, 0x6b82d327, 0xe6133f8f,
- 0x4cdd6f37, 0xe27cdf9c, 0x7cabbe45, 0xfd032c5c, 0x4a44b9f7, 0x8b91c4b7,
- 0xe3b31283, 0x06a06e8e, 0x51df9d18, 0x7e60acba, 0xe6221bca, 0x07721129,
- 0x09fff901, 0x10b50b9f, 0x8db9feb0, 0xa4b369d1, 0xcad461fb, 0x8dd7e68c,
- 0x7d01b4f7, 0xf4f20c4e, 0x6a8b7d87, 0x3e39f922, 0xbf686f84, 0xfad3ebe2,
- 0x5550fa33, 0xa3bfc05b, 0x3c317ceb, 0x64dbf787, 0xf0d73d8f, 0x3b26f91d,
- 0x3e72fe32, 0x013b853e, 0xe9a3e7d6, 0x4954edf1, 0xdaf87416, 0x457f1448,
- 0xf79337c9, 0xf932f78d, 0x503de5d6, 0x67ed0a5e, 0x03f262df, 0x47fac1df,
- 0xc7f50ae1, 0x0bd7ddf6, 0x24ac0fa8, 0x37ae4f14, 0x8dae5cca, 0x509f3aed,
- 0x292125b8, 0xffa05f8a, 0xee3fc414, 0x4b5fcc57, 0x97d28bbf, 0x625e30d5,
- 0xdcba7f6c, 0xfff2e02e, 0xc8ffc826, 0x7593fc88, 0xb67bee4c, 0x17a8fc9f,
- 0x2781cb17, 0xa579031f, 0x4157e9f2, 0x9832e55e, 0x7b8d67f7, 0x9531f9df,
- 0xba82cf93, 0xa7f51a9c, 0xb72b4e59, 0xe4f1258e, 0x46a733f4, 0x7d29cae2,
- 0x9d4e571e, 0xffc7c8ed, 0xc753fa57, 0xfc2657df, 0x27b0fae9, 0x61f59a3c,
- 0x3e22a4bd, 0xfe90facd, 0x620a45bd, 0x3be74ff9, 0xfeaadf9d, 0xe80864b4,
- 0xea5f309d, 0x4be6177c, 0xe262ef9d, 0x99fc06a1, 0x18865fdb, 0x816b8510,
- 0xf032fead, 0x809a6c23, 0x87617e72, 0x6ceef305, 0xbff40463, 0x584bd446,
- 0x1ee2dd7f, 0x8ce8760b, 0xf67c2f49, 0xededf273, 0xbe5aefff, 0x307b63e0,
- 0x861ca03b, 0x74d14be0, 0xe0c2d71c, 0x02403eac, 0x781f5143, 0x7f28b2c4,
- 0xf7970e79, 0x9ad83e17, 0xec2c780f, 0x8ed4951a, 0xfa30727a, 0x6f5cd593,
- 0x49abf69c, 0xb74f4fa0, 0x78bfa0e4, 0x8ae8bf7a, 0x34f7ff97, 0x209fefa7,
- 0xaecb463e, 0xa44ea48d, 0xba45d6fc, 0x6ff06ed1, 0x714d91b4, 0xcba6aff6,
- 0x5f7e2f4c, 0x01fd007c, 0xdbdb4f1f, 0xd8e2ca4b, 0xf9f2b7b1, 0x25f3d8ce,
- 0xb7178fae, 0xbd80b7ac, 0x8b46f174, 0x41bfefc1, 0x479d7ce6, 0x67af80f2,
- 0xc6bbb1ec, 0x8bf71e00, 0x5649e41a, 0xbc529cb7, 0xf342fc71, 0xb07fa1fc,
- 0xdd93eeb7, 0xca2f4fc8, 0x0f01dbc1, 0x11b49e2f, 0xa1db2fd8, 0x078a2dd4,
- 0x830a9de7, 0x4661c773, 0x2f0a1f97, 0x50ce5d85, 0x3673c411, 0x58dbe412,
- 0xf3e4133a, 0xb0240dd3, 0x2de81b32, 0xc1237ab2, 0xca0a57bc, 0x77c327af,
- 0xa35ed35f, 0xe6c2f3e4, 0xe8127f2d, 0x045b4b7b, 0x2fb685b7, 0xe015da95,
- 0x64e6ea97, 0x68d8f411, 0x74ffcf55, 0x147d725f, 0x4b27ddff, 0x13bd9788,
- 0xf009bc5f, 0x2143a672, 0x79efcfb0, 0x68f31ba9, 0x23e4b4cf, 0xaf34f5bf,
- 0xb2e47de7, 0x43f412a9, 0x3a665f10, 0x304c6a8e, 0x7b1527d4, 0x335c0007,
- 0xb5cbedac, 0x2bb77838, 0xa1fdeecc, 0xb2b7b3e4, 0x96fbf2cf, 0xb15ebf2e,
- 0xfeef8a2c, 0xfdbf2b1e, 0xb2efc9e3, 0x987f6a95, 0x9cd6b2f7, 0x65cf80fe,
- 0xc5fb917f, 0x7d67abe3, 0xccdc2fcc, 0x9abb65f3, 0x1a5efca8, 0x544dbf25,
- 0x01c4e37e, 0xe581fa5f, 0xdf9059f7, 0x2bbdf038, 0xf2e8fa33, 0x0872db9b,
- 0xc9b737e5, 0x7933c862, 0x7d76e655, 0xf42bf28f, 0xea0d3ebb, 0xa388e6b2,
- 0x100f01af, 0xe3ccdcc7, 0xc80e30fc, 0x71b8a4b1, 0x63957d9e, 0x8e59bfdf,
- 0x98236d97, 0x6f4b1317, 0x76cbc726, 0x80163950, 0x978e4cee, 0xce3952b5,
- 0x11df958e, 0xbecbf231, 0xdf621a5f, 0xff673757, 0x5e3a66ee, 0x6cd6479e,
- 0x88bcfdf4, 0x968d8f3c, 0x70914967, 0xbcf231be, 0xbcf26fbf, 0x9533cb8d,
- 0x1c5aa1d3, 0xc62d6aba, 0x2717acfc, 0x1e7c6d1c, 0x226ff2f8, 0x5baf49fa,
- 0xeafb5d98, 0x8063a384, 0x7870a62f, 0x743a7086, 0x7fd8fcfa, 0xd347c4c9,
- 0x5f8a4e41, 0xe42dfbaa, 0x28d92f35, 0x4b87d013, 0x1fa10e9b, 0xe8ab8e6a,
- 0xbe399576, 0x7311eba2, 0x8351659c, 0xc7c79eb1, 0x11db172f, 0xa89af25e,
- 0x77c38a6d, 0xb9c13d79, 0xe71deebf, 0xbd9c0898, 0x79f47dc5, 0x3e9706f4,
- 0x970a31af, 0x1f24d197, 0x8f1489e2, 0xbffe2f28, 0x2a87188a, 0x90c0bc2b,
- 0xeb913fef, 0xc2bafcc9, 0x944b0862, 0xf80e3e43, 0xec77f551, 0xb1b27d83,
- 0x303cd507, 0xb44d27a7, 0x7a9fc17a, 0xf28ddeda, 0x0965d3ac, 0xbc0dcba7,
- 0xd407179f, 0x55bf0114, 0x586e0b37, 0x5f43aa77, 0xbd86b9e2, 0x02517e8f,
- 0x55b0b47c, 0x0f915b70, 0xe7e0294f, 0x17f5d095, 0xe5bf29f8, 0x0bbdda14,
- 0xf8450b5b, 0x010ee17e, 0xc37bd213, 0xb6e95f4f, 0x59e3d388, 0x7009df80,
- 0x8d75b376, 0x57b7a7c3, 0xfc037e4b, 0x5b9d8fc5, 0x56e0c59d, 0xde046aad,
- 0xe77861b1, 0x3eaf3888, 0xbde3abc2, 0x98977837, 0xe4daf8e8, 0x220f1833,
- 0xf27dc92d, 0x5c6dbe6b, 0xa1b49aaa, 0xa7c7a67f, 0xf3bd17ee, 0x951b8864,
- 0x8e31920a, 0xedf18ddb, 0x8fffa01f, 0xf83fd7ce, 0x6eba2117, 0x09f1b9fd,
- 0x67c9f7c4, 0xba00cd0e, 0x24517a2c, 0xce974a36, 0xe1091746, 0x0140483e,
- 0x8935543a, 0x48f78c1e, 0x5ceb82a1, 0x65a8f8d1, 0x42ecd8f8, 0xd5b5583d,
- 0xbf4e981a, 0x49fedaaf, 0x9d33d82e, 0xcbef7577, 0x19ffbf02, 0xf898e501,
- 0x1f6173db, 0xfb624aa8, 0x6efc663b, 0xd8fad854, 0x1b31c3b1, 0x606841e4,
- 0x82aa8be7, 0x946b64b3, 0x457bfc3d, 0x7be971c6, 0x7fe6d798, 0x30bcc05a,
- 0x5cfa2f80, 0xd36f9e8b, 0x4bf334f1, 0x00e59aaa, 0x6aaa539c, 0x7109d2d8,
- 0x5683aa92, 0x1baad75c, 0xb75c614e, 0xa8b3f378, 0x459bab7f, 0xe31c9f83,
- 0x2188369f, 0x4d57f82b, 0x4ece304b, 0x1eb087eb, 0xe9a71f8c, 0xb45a8fcd,
- 0x1fbb75b9, 0xa7f9e4e4, 0x529cf112, 0xf444a6db, 0x1fce1b53, 0x47f18a1f,
- 0xd79ef783, 0xf9c13d1f, 0x318a6fe3, 0x521a479e, 0xf0a54fd1, 0xb1c59415,
- 0xff7cc3d7, 0x807fe7ec, 0xd6c76978, 0xf000fecf, 0x99d7fe2e, 0xe282fc3f,
- 0xbbb2ec91, 0x3f55ff41, 0x9bc636f3, 0x728eeff4, 0xf4f9d5bd, 0xeba71853,
- 0x41aacf7c, 0x47ad9d6f, 0xaabc4307, 0xe997cb73, 0x6f2c9f60, 0xd6f6869d,
- 0xfdc56df2, 0x40fb1c49, 0x036f812f, 0x9a13887d, 0x69b7b5e9, 0xf38060ef,
- 0x6c37a524, 0x0be38609, 0x5e2c25c1, 0x42b8f2a3, 0x6c78fc63, 0xe9a11c4c,
- 0x8ca66bba, 0x54d65281, 0xc27887d2, 0x978e945b, 0x8d7e81f6, 0x89ef6fcc,
- 0x1fe1277e, 0xd5b24e94, 0x9bcfbf48, 0x31f1fde6, 0xed4a6b68, 0xea109e31,
- 0x78f4de03, 0xc78a1bef, 0xdaf9056d, 0xdf8c27fa, 0xd3a6dd00, 0xfb3e7689,
- 0x938860f9, 0x6fbb931f, 0x56d57dc5, 0x5797ee2b, 0xf28bbeb5, 0x75edb9d3,
- 0x8f0937b4, 0xf09276bb, 0xf1938b1f, 0x8dead3dc, 0xe087162e, 0x853887f8,
- 0x79cf889a, 0xb1f1823c, 0x29e8a71e, 0x7585713e, 0x6523cf28, 0x1b259471,
- 0x298857df, 0x8f8c23ee, 0xd13df3ac, 0x1b83c749, 0x3a2e30f0, 0x0e3f16de,
- 0x72cb8e14, 0x20fd017a, 0xa78e16ce, 0x8840fad1, 0x778404af, 0xd07d1c49,
- 0xe9c59eb9, 0xfe63653a, 0x2c3e8449, 0xa26456fe, 0xdecf3eb3, 0xe0dea7d6,
- 0xc9f8b6ff, 0x6c79c587, 0xbe3a9e2c, 0xe7c7af8e, 0xb7ef8559, 0x98215a5f,
- 0x802a6ff7, 0x1d34971f, 0x513f2052, 0xf9f4c75f, 0xbc3b7076, 0xf31119e3,
- 0xf707576b, 0xeb371ea2, 0xde70a58b, 0x3fbc0e21, 0x6d2ef0e3, 0xc744eb66,
- 0x49c05756, 0xb3d8e9fb, 0x6979f903, 0x4fc521e3, 0xf0d7dbfb, 0x46fcc2bc,
- 0x4eb03f26, 0xefe0a204, 0x2e776e78, 0xbb322f8b, 0xddce3cdf, 0xd3a79e56,
- 0xea9c7f12, 0x718653c6, 0x0a83f916, 0xff3e97cb, 0xcf242778, 0x44efe82c,
- 0x5f204c9b, 0x2c5044f2, 0x593fb78d, 0xdc799569, 0x74958eba, 0x25f3c4bd,
- 0x449e762e, 0xde30514c, 0xfe35dcb1, 0x941a5260, 0x507e0a8a, 0x5fb64aed,
- 0x5a9ffb5b, 0x36bbd006, 0xc78c06f9, 0xebf099d6, 0xc217734e, 0xd4f71339,
- 0xaec031b2, 0xec937d66, 0x5fe018b1, 0xafed2aee, 0xd1573852, 0x275ce07e,
- 0xef3c3491, 0x94962622, 0xb7447cc2, 0x138f6dc5, 0x659d9307, 0x17851bc4,
- 0x9f3c6dd9, 0x57cebe42, 0x9f7d1fa1, 0x6dadb175, 0x3dba361f, 0xc495f002,
- 0xaf0bd5f7, 0xbbbce377, 0x580d051a, 0xd563aa9c, 0x05f2ce9d, 0xdae8dd60,
- 0x2e4b949a, 0x87890fc5, 0xfe0e27ae, 0xbddc685c, 0xaad1f41b, 0xa649e244,
- 0xaab14672, 0x4e70398a, 0xc84db467, 0xf53d3e01, 0x5fb48bea, 0x60488b7b,
- 0xa9cbbf8b, 0x92790be7, 0xe41cce41, 0x010bcc7e, 0x3526fe56, 0x5f39a702,
- 0xe92bc084, 0xd3bc7391, 0x39c62744, 0xd113af4e, 0xc5c9159f, 0xfccc9bbf,
- 0xf8001273, 0x88b27af9, 0x4a1a79c3, 0xc142bf78, 0x7f05da3c, 0x4420be79,
- 0xf1a21d18, 0xf46a5a95, 0x89edeb17, 0x436fb0b9, 0xc8369efc, 0xfde0ae4b,
- 0x9e332bf5, 0xe7e2a1f3, 0xcf52fb07, 0x7e6cffd3, 0x7fd07ec9, 0xa8f9de15,
- 0x36cffbd7, 0xdb32039e, 0xe42f08ef, 0x7bb9500d, 0xe7b5884c, 0x5c1e5b2b,
- 0xb1e0f90d, 0x0464f3fb, 0x91541be4, 0xa1f20d04, 0x077df6cd, 0xf1c84de8,
- 0xe0271271, 0xd97d67b1, 0x87db7e0b, 0x98f26eff, 0x0b57e2f3, 0x2e8dfbc1,
- 0xf058dfdc, 0x3f51db97, 0xf88c3359, 0xfc46abb5, 0xf198463a, 0x4bb3c468,
- 0xb28de233, 0x787ce079, 0x3c6f1a4e, 0xb3c6655f, 0x0e1da844, 0xd0404af6,
- 0xf931fe80, 0x11ebcd0f, 0xa6fcdeee, 0x8f5f1b34, 0x5fe95e38, 0xa99d2d99,
- 0x533b806c, 0x985ca10a, 0x19cb28e5, 0x83dfe012, 0xf12b02d2, 0x7e85cd2b,
- 0x8f9f0649, 0x73bec150, 0x00891c80, 0x047286af, 0xcf402827, 0x6e07c83b,
- 0x7c85a7a0, 0xd919be42, 0x2cef3d33, 0x5cd0e97f, 0xe03ad5fa, 0xae514bdf,
- 0x14a939d8, 0x06cda812, 0xb0dcd539, 0x367d076e, 0xf38242b5, 0x18ad44e6,
- 0xddcce706, 0xc7903e58, 0x451aefde, 0x182c5f30, 0xfa0e9b3a, 0x291e7aa9,
- 0x80f7fd03, 0xfc033dd2, 0xccedfbdb, 0xaec8b94f, 0xa5ff3ea0, 0x9cafdf5d,
- 0xa9cb97fa, 0xc8b5763c, 0xebc39c2a, 0xbb64d96a, 0x22cdea00, 0x4eaef79e,
- 0xc608bbae, 0x19916cef, 0xc0b6155c, 0xb7c7e005, 0x741eb8ca, 0xf3c64c56,
- 0xadbb612c, 0x7613ed85, 0x78927cb5, 0xef3e947b, 0x22f87e6c, 0x6a3c3388,
- 0x793fbf89, 0x9df2cdbd, 0xfaf0d4fc, 0x3f9314db, 0xe58dbd71, 0x94303c4f,
- 0xf96963ce, 0x330ebe69, 0xe9c49879, 0xabfcd2fc, 0x5adbfe70, 0xe74f3fa8,
- 0xfcde2251, 0x3ce84ba3, 0x312dbc27, 0xd33c4afd, 0xa3b3a4e7, 0x0efef03c,
- 0x3e0065a2, 0x02214c26, 0xf784f3c8, 0x8febee08, 0x7e8f99a9, 0x94898bd5,
- 0x4c5f29cf, 0x0b7ca16d, 0x89c3ae7a, 0x36d8fbf6, 0xc997c0c9, 0xc17bbd53,
- 0x90771ccf, 0x771dbea0, 0x9e3ed8d0, 0xa71c4404, 0xd27cf8dd, 0xc6bd6331,
- 0x1233f7c6, 0xf7f03a49, 0x8445afda, 0x689babab, 0xbb7ed177, 0xfde0062a,
- 0xe1675d02, 0xbf2d1494, 0xade34b16, 0x8c6d2bf3, 0x08551e2f, 0xce8f2fae,
- 0xc13ee277, 0x9855f99e, 0xcfc5fd27, 0x9de243bd, 0x4bd28bbb, 0xddff6c49,
- 0xa7814493, 0x604abd7c, 0x8ccbaef8, 0x4bd297de, 0xbe758f9d, 0x7339f9d6,
- 0x5e37827e, 0xcec38ade, 0xf9a29dec, 0xfc050423, 0x01025db2, 0xe5de76bc,
- 0x9b5fe435, 0x2bb93f4b, 0x6ea9e00b, 0xb676833e, 0x1e7e25ad, 0x225b06d4,
- 0xf2eefbf3, 0x8d7c84af, 0x04a1529f, 0xbf73d8fd, 0x5aafd16b, 0x88534103,
- 0xe6ead9eb, 0x79a7b9e0, 0xe201b236, 0xe65d52b0, 0xfbe02eb5, 0x53572be2,
- 0xb32b1f78, 0x951f9d20, 0xbfdf8435, 0x2f8c1084, 0x077e4c48, 0xa3eb20ce,
- 0xda357fcf, 0xb46d9b0a, 0x1b9b66df, 0x6af54ffb, 0xfdafc002, 0xc1127ff3,
- 0x673ae99e, 0xe00e3a45, 0xddfe8ffe, 0xaf66369b, 0x6cf762dd, 0x9527fe05,
- 0x9a1f2869, 0x48ad5137, 0x14a07385, 0x4fe271ef, 0xe29a5dba, 0xc28dbaa5,
- 0xe0b4e293, 0x78f110be, 0x979eb754, 0x517bf840, 0x024240f2, 0x5d05bc81,
- 0x422d0a9f, 0x7ff945c8, 0x0219cd8c, 0x92a5233f, 0x60829bce, 0x5fd63627,
- 0x3e11d49b, 0x907986c7, 0x200b2f94, 0xde609df9, 0x415a2403, 0xd59ebaff,
- 0x64aaf3f5, 0xd566fa82, 0x96a05283, 0x6a4eb3f6, 0x24fc43b7, 0xc116a3db,
- 0xa48a7356, 0x41baf9e2, 0x1d1e4c95, 0x87278f39, 0xec2a15ed, 0xde25ffa3,
- 0xef8e2f16, 0x8b757ce6, 0xe03efbdd, 0xf77f773b, 0x346b301e, 0x7b4f1b3b,
- 0x79f686d9, 0x3b706f58, 0xbbaf84ac, 0xfb653e13, 0x397424c6, 0x71e863e6,
- 0xa0deb37a, 0x08a6f072, 0x44a9f572, 0x87943cf0, 0x4f40affe, 0x1fd288c9,
- 0x682c9d7c, 0xb68bd9ae, 0x2f6a389b, 0x57a4e3f0, 0x8c73ecf0, 0xc077191e,
- 0x7ef00b5b, 0xe661fd57, 0x2a21d187, 0xa33e9c8f, 0xec173854, 0xfda1d70e,
- 0x937d265f, 0x3fa63e56, 0xcf9cb5da, 0xe5d5f8cc, 0x79ef2cda, 0x56bdb42b,
- 0x488035ec, 0x84438f30, 0x0e6a1c08, 0x2203a3e8, 0x855df7d8, 0x5c285f94,
- 0x28ee411b, 0x0d9f26bf, 0xb37c095c, 0x3b0ae5b6, 0x5e77c7c8, 0xebf4423f,
- 0x7fe3b8a8, 0x7681de88, 0x08983f96, 0xfbba5878, 0x423f5f2c, 0x5d30e748,
- 0xc7447ca9, 0x37be7443, 0x172eb9f3, 0x394070b5, 0x009b9d87, 0x104288fa,
- 0xeb256b09, 0xe8a760dc, 0xd86d75f6, 0x7cc64d9e, 0x366ee5ef, 0xdbacad5e,
- 0xe60d9ae5, 0xd455dcbb, 0x2efb7cff, 0xffa8e7d5, 0x5d2f9512, 0x7fa3752d,
- 0x214e7d56, 0x81efd481, 0x7a3a16af, 0x455f01ba, 0xf8b17ef6, 0xd472081a,
- 0xf9cbffef, 0xcf9e6cdc, 0x3e646a3d, 0xc5f78893, 0x0a17aa76, 0x64cfacee,
- 0xcade417c, 0x7e0be688, 0xf927b1de, 0x1be54f1e, 0x7918c7dc, 0x84f1c936,
- 0x96c72a16, 0xe4d63958, 0x4827bc32, 0xbea0756b, 0x59f5cb33, 0x076aaf3e,
- 0xa24dfbc3, 0x9f3067f7, 0x60f74b6a, 0x955cbbe0, 0xc0a74ea4, 0xe88b36e6,
- 0x54b69007, 0xbb123ac3, 0xdc59fbbe, 0x7a07af8a, 0xa668529c, 0xb3e74d7c,
- 0x0bbdeec9, 0xcdd6a5e4, 0x58384afc, 0xa3707604, 0x3c377bcd, 0x12d85077,
- 0x88c75ce0, 0x838b3650, 0xd4720c84, 0x4c38dc93, 0x490c1172, 0xe9f93eb8,
- 0xd08174fa, 0xf6c53c33, 0xd52f0664, 0x0c7f6016, 0xb06c202c, 0xf9f304a5,
- 0xf3b2e606, 0xd8f303f8, 0xd84f59fd, 0x91b9bad9, 0xd97a07af, 0x075b2b68,
- 0xe2259378, 0x777de6b7, 0x885401b8, 0x7bb26e0b, 0x6cfe831e, 0x479c1ea5,
- 0x02689b96, 0x292ca3e5, 0x53fec028, 0x605562ca, 0xd6c240f1, 0x7f692813,
- 0x42d5d359, 0x20b28f58, 0x07de0097, 0x9c8e263b, 0xefe5dab4, 0x8e6ac717,
- 0xb95ba3b1, 0xe853ec1c, 0xb3a7537c, 0x3c70e43c, 0xf80f8286, 0x80dd74ed,
- 0x9cfced93, 0x93f835e5, 0x7ecd9e19, 0xe60c1015, 0xddfaf125, 0x29ec910a,
- 0x2df8f7e8, 0x86c59df0, 0x68838f7e, 0x078bd041, 0xce5ceced, 0x035b416a,
- 0xdd48dff5, 0x40b7b836, 0x2607ebe7, 0xf449ab5f, 0xa729c495, 0xa517c173,
- 0xf026fe7c, 0xd3e4e75b, 0x0ce157c3, 0x7e3307ba, 0xbc8688f3, 0xcd6e9d47,
- 0x766e81b2, 0xeb447388, 0x7e829761, 0xa090a77b, 0xb9d39f81, 0x0a706050,
- 0x2a179e36, 0x5c2fe319, 0xfdfae9cf, 0xe9bcd82b, 0x8ff1f307, 0x6c567bc6,
- 0xd1e00d9a, 0x1b9f0fe1, 0x31eb9d32, 0xc8c9fb9f, 0x3263c709, 0x4cab4f31,
- 0xc852bb81, 0xda0716e9, 0x4c89d555, 0xd0fccdae, 0x79c2941f, 0x7c50cbce,
- 0xedf4097d, 0x8324d72f, 0xcb7fed1e, 0xafa044e1, 0x825d0f19, 0xd83ef47f,
- 0x1c9bfab7, 0x2f5b7f77, 0x94063233, 0x91999d83, 0xfea58199, 0xc529debc,
- 0x26a5ef8d, 0x6bb8cf7c, 0x46dbe580, 0x026a6bf1, 0xf7a4efed, 0x283c778d,
- 0xf718ddee, 0xf8604fae, 0x3c7457ae, 0x672049aa, 0xc496ba91, 0xb32779ce,
- 0x8cdc1c7b, 0xb67d6b9e, 0x7e8a4972, 0x467683cf, 0xf2b9e23f, 0x6b025046,
- 0xf909b265, 0xf465c59a, 0xe8aa5c7c, 0x1992fd18, 0x8df5bf5c, 0xff7d872e,
- 0x9c6484dc, 0xd3b5d9ef, 0x7274bc70, 0xc5387d97, 0x8b32fceb, 0x939af106,
- 0x089eff73, 0x66e6ff47, 0x3c1015b5, 0x1ab35a62, 0x16ffaefc, 0x9409b9bd,
- 0x54f5694e, 0x3e32a511, 0x74a3b900, 0x13f712b9, 0xe6e258e7, 0x604d8ddf,
- 0x76a7f57e, 0x919b8e37, 0x22bcb831, 0x103eba3f, 0x23f3a4e9, 0x8accc395,
- 0x61739131, 0x24a63f94, 0x2ea791c4, 0x7ec33499, 0xd30fae80, 0x7d75fe38,
- 0x1a43cbac, 0xefec19c8, 0xa8fd5195, 0x7f2873d3, 0x90e31d35, 0xfcb427f8,
- 0xf3b04bf9, 0xa114a713, 0xbff2a3be, 0x0465e506, 0xd076dfd3, 0xc7f151a7,
- 0x0777d6ae, 0x87debec1, 0x05c679ff, 0x90ff3bfb, 0x3fa05dba, 0x4df2fd8f,
- 0x7c11e417, 0x87164bf8, 0x1fe4d5b8, 0x9e981379, 0xcd94260f, 0xe6dd7982,
- 0x378167fb, 0x0ac92f8a, 0x90b15fb6, 0xf3c6bb2e, 0xbcf3c683, 0xf3e6824b,
- 0x77ec7ebb, 0x8e3f1489, 0xc3a708fe, 0x4af5c6c2, 0x7be30a96, 0x8f3d0217,
- 0x58efff71, 0x4367bb13, 0xe36e6787, 0xa27c0568, 0xf958b47f, 0xcc9b76be,
- 0x74cf05d6, 0x72f2a7d8, 0xdce199bc, 0xfd81cbb7, 0x44447bcd, 0x1d0e64bf,
- 0xafd5056b, 0x679616de, 0xbcc79e6b, 0x3812d50f, 0x5eef3f2f, 0x785dfd01,
- 0x9d7497ff, 0x07b8aef2, 0xf3ccb3f7, 0x603fdf34, 0xfba4b73e, 0xfd380b49,
- 0xe517882b, 0xa20f262f, 0x9b3bed85, 0xf7a77ae3, 0xfe6038e7, 0x3f7025f7,
- 0x838c80a3, 0xfbad877c, 0x2f9d2687, 0x9f83aacf, 0xf3c13ed7, 0x08f98f33,
- 0x5412b396, 0xe5ba2e76, 0xabe012f5, 0xf05bcda5, 0xab6f96be, 0x1cb4966f,
- 0x8931fc4f, 0x1f6a1de8, 0x21fe07ae, 0x3760c15e, 0x467f5d2e, 0xc32c7e61,
- 0xf9fccdc3, 0xdc5f30cd, 0x72f76527, 0x3e58bcdc, 0xcb9f7d1b, 0x7cc609d3,
- 0xf9f08eeb, 0x258f3673, 0x9f481f7c, 0x679f999f, 0x5e78b025, 0xd5f2c6c5,
- 0x6b94e803, 0xe60e8f5b, 0xdf300ae7, 0x3317e75a, 0x65202c3f, 0x14429925,
- 0x8d7e5bdd, 0xa9f4ea70, 0xe7c39ba8, 0xfbe0cfe3, 0xe710196f, 0xcc0f8de9,
- 0xdb94eef4, 0x9a7c8307, 0xc3d9dde9, 0x09adf0f9, 0x50afdd6c, 0xffa0253d,
- 0xd5b291e6, 0xe3bb28ee, 0xefb75498, 0x1b372017, 0xad46df19, 0x7b38cca7,
- 0x79f5c645, 0x0fed4b99, 0x1d210cf7, 0xbdfec026, 0xe9ef0fd5, 0x79f11ce3,
- 0xe01261b4, 0x13cb14b9, 0xd86d32be, 0xfcfb48b0, 0x4224cf47, 0x046bb53c,
- 0xa74b78c1, 0xc7ef08cb, 0xf3c22209, 0x62c3a731, 0xef5feda9, 0xd8d9ce83,
- 0x47097986, 0x9af1e6be, 0xf1a5adaf, 0xbe4ff9e6, 0x9f7e11fe, 0x6e5cadca,
- 0x36e1ff74, 0x5b5bb74e, 0xdcf3bed8, 0x0f48e575, 0x0720fdf3, 0x16497704,
- 0x1c1bcaed, 0xcdfd00ad, 0x5da799f4, 0x6bf41c71, 0xfdc89d0c, 0x98bd2f9c,
- 0x2f51534f, 0x4cc27c62, 0x9b870abf, 0x35abcde5, 0xea2d6fe8, 0xe55dcf41,
- 0xafae7a60, 0x63cf31f3, 0x7a80934e, 0x82ff0ccf, 0x0f572b8d, 0x367f3020,
- 0x8479d8bf, 0xe19ea206, 0x55e7d4f3, 0x473c3441, 0xd38fb31a, 0xce89397e,
- 0x72d85cab, 0x2ec1e63b, 0x2c27f3a5, 0x1bf183de, 0x5e1d7e1d, 0xc44a3cf3,
- 0xf106d90e, 0x068215d6, 0xdef636fa, 0x5ee18f16, 0xbb0d39a8, 0x8efd0207,
- 0x21abed48, 0x2fc47bfe, 0xf5d6ffa0, 0xb445c101, 0xfb808d6b, 0xafd23d5e,
- 0xf4ede585, 0x051ac74c, 0x58aa39ee, 0xe3a5c427, 0x6d42fa82, 0x59de9458,
- 0x1b52b818, 0x88378066, 0x1a8b1c79, 0xa7cf0dca, 0xb8fa8c38, 0x35237937,
- 0x74d2f3f1, 0x4de5d2f9, 0x870abf97, 0x52ffe2ca, 0x36565f60, 0xd107e9e8,
- 0xf67aa0cf, 0xc38b076a, 0x7d23703c, 0x67a3e965, 0x79fc710c, 0xe67d19e3,
- 0x79f1d389, 0xc503eb4f, 0xcedf4183, 0xedf51872, 0x3e8f9df7, 0xf42e5d0f,
- 0xc2e599f9, 0xfe3d7f8c, 0x1983a665, 0xd81700ff, 0x1d5a07fb, 0x9004bb81,
- 0xbfa70677, 0x76708ed5, 0x70691466, 0x7c00e59e, 0xd2dcf540, 0xfd631fcc,
- 0xb96cb126, 0xee34fd03, 0xf3f16907, 0x0ff6c26d, 0xfec463b7, 0x1e301196,
- 0xc8341311, 0x2cb3170b, 0xbce95b35, 0x1cb421c4, 0x9ac1e905, 0xeb9fe708,
- 0xe1132f8a, 0x7e5a86de, 0xc2d6ba3e, 0xfde96dce, 0x75b071ad, 0x39772f49,
- 0x683b56ca, 0x6b5f27ff, 0x78b0702b, 0x3819fa2f, 0x93ee114f, 0xd8317ea4,
- 0xcc132fb3, 0x234bcd4f, 0x0ebe817b, 0xf20f19e2, 0x85238cfd, 0xfb655f9f,
- 0x0b2ff46c, 0x796acd4a, 0xf908d55e, 0xa6077dfd, 0x5a703dc1, 0x6ccee592,
- 0xf1c27f5a, 0x5967ab3a, 0xa9bb64ce, 0x8378edff, 0xce5a47d5, 0xa7f5a50c,
- 0x3ab26f1c, 0x0551086c, 0xade3b4f3, 0x3051fe69, 0x3fdf9b8e, 0xf20919e0,
- 0x5f985920, 0x3051ed2b, 0xa3efacfe, 0x2c06a2af, 0x00cfaff8, 0xba9f82ff,
- 0x0e4fe8b2, 0x7915ef88, 0xbf1fd854, 0xfdb6821f, 0xe3a97bbe, 0xf0587455,
- 0x01280a5e, 0x3e385bff, 0x2690ba75, 0x23c848cf, 0x48cf4124, 0xe5d877d8,
- 0xdd0136f0, 0x5db40ff3, 0xf4d47206, 0xf00bdfc6, 0xac21ccfe, 0x28ca7c9f,
- 0xc9e6df70, 0x8fad0617, 0xe5dbbfde, 0xf401dc28, 0x3b4064a1, 0xe4dd5041,
- 0xd4176a66, 0xc95e3f52, 0x68c47f01, 0x7e713787, 0x6ca12d7b, 0xc0d9f237,
- 0x8e1fd310, 0x8fd0bdb2, 0x2da4572e, 0xa77c4fa5, 0x4110aee4, 0x3564a63f,
- 0x720b9c1f, 0x9cecdff8, 0x60f1e0ac, 0xf0e6dbfe, 0x3f6c20fd, 0xe9fb01dd,
- 0x9235afa0, 0x71e74fe1, 0x238f1605, 0xfe510569, 0xfd079f05, 0x37dc2a7e,
- 0xf6c1ce32, 0x44bce95b, 0x13461f58, 0x887ccb15, 0x6a00e413, 0x49df58bd,
- 0x417f0782, 0xcec87ffb, 0x035b74fc, 0x2c5dc431, 0x5f7eb64e, 0x7dd992e8,
- 0x5af0722d, 0xa709e3d0, 0x78f41b88, 0x848ae3d7, 0xfb9218f9, 0xb09fb847,
- 0xde0042cf, 0x1b80e4a7, 0x17ddd9e2, 0x1206ea49, 0xd38bafe9, 0x21f7ef5b,
- 0xe208bd45, 0xcc5ca31d, 0x90aa78be, 0xf768fe60, 0xfb002571, 0xb659294c,
- 0xfabf689a, 0xef7b072b, 0xcfa2a4d6, 0xd6c11e81, 0x8fe30204, 0x440d45db,
- 0x353f874a, 0x1f81d9e6, 0x288e0336, 0xeeac521e, 0x94bfa03b, 0x6cde1433,
- 0xfc41ee7c, 0x24e8ea4a, 0x5789df8a, 0xbfb85539, 0xf07b29e1, 0x7b9fcc2a,
- 0x24f782d6, 0x72b4566d, 0xad3e6fa8, 0xf35e21ba, 0x01307654, 0x05acf3e7,
- 0xa139b3e7, 0x1465e2fb, 0x608d5fee, 0x20e4bf7e, 0xe4052d92, 0x83bd48a8,
- 0x32704f3e, 0xc2cab87d, 0x938a68e4, 0x0243cfc9, 0xde0f3f1d, 0xd1f9442b,
- 0xbaba1bf3, 0x7e8879d9, 0xc089b7d7, 0xbae509c7, 0xc1121e3f, 0x465c9e8f,
- 0xec9cfd70, 0x3a2a0394, 0x1ce71e9f, 0x08cbff4a, 0xfb2e1f5b, 0x5fc63160,
- 0x82de0529, 0xebd80bdf, 0xf052f7e4, 0x39cb987d, 0xed214c9f, 0x53e7ac22,
- 0x442d11ce, 0x9cfcbbc7, 0x9f3d7714, 0x527dfbc6, 0x7d125220, 0x2aacf0af,
- 0x1215df01, 0xad3b7ae3, 0xc438e4be, 0xa66d8b7b, 0x235eb0e7, 0xf4091e3c,
- 0xb1b734d7, 0xaf93a47d, 0xe0c9834f, 0x3d1abce8, 0x1c4d3e6e, 0x0bda28f5,
- 0x78068aa5, 0xbcf4e2d9, 0x7e44fb0b, 0x2f9e26ea, 0x8fa4f33e, 0x388d3fe5,
- 0x72f18097, 0xe04e9fca, 0xebeb8b8b, 0xef3a76fc, 0xfeb1878b, 0xaf410f81,
- 0x5a78f85c, 0xf7f9e82a, 0x4bd1beb9, 0xbf80ef9d, 0xbf8c49dc, 0xe44697dc,
- 0xc49214b3, 0x0de446c6, 0xd9fa0ef8, 0x8a6e0729, 0xa92f7e7b, 0x0fd9d4a8,
- 0x4ed041e6, 0x36d32fbe, 0x1f4ce41b, 0xe32701e7, 0x7ab9736b, 0x10ddb2e5,
- 0xce7ff707, 0x03a98bd6, 0x5a1e61ce, 0x62488fd8, 0xd6ad567c, 0xf203375d,
- 0xc6329c62, 0xf9f9d3bb, 0xc97e68ab, 0x9d17e28c, 0xcc9d3aef, 0xa7f9d68f,
- 0x989bc778, 0x39fc5fdf, 0x126cee21, 0xfe7507b6, 0xf8cfccb9, 0x6cfdb2f0,
- 0x7f8de89d, 0xa9eedd3c, 0xf8631ea0, 0x9be33f66, 0xf81fca22, 0xf03d10fb,
- 0x966f998f, 0x5f37caf5, 0x967e0227, 0x779f16b7, 0x67d9a59f, 0x973393cc,
- 0xf3f11c13, 0x624d9f28, 0xa943b1fc, 0xe82e51fb, 0x1a2dab8b, 0x15ca03e8,
- 0x3e52d759, 0xdfa091df, 0x03935a7b, 0xd3122df5, 0xac5a5b3f, 0x38b67fa8,
- 0x678c5ebd, 0x68f3b065, 0x43b6f244, 0xc036b41e, 0xf3df46a6, 0x8d93a57c,
- 0x13439413, 0xf41d828e, 0xf1ff4617, 0x8dc1e757, 0x82b32430, 0x31cc61d1,
- 0x0d98bd65, 0x8f853be9, 0x00bd7f00, 0x577e833a, 0x73c1587d, 0x2b0f4bfe,
- 0xd85f17a8, 0xc4097af5, 0xcb7cf48d, 0x2f5f3b71, 0xef051a29, 0x9c7b3e33,
- 0x8ebd63eb, 0x27a0e7a9, 0x4ea6f74d, 0x997f4c20, 0x032d3def, 0xb48dc9fe,
- 0x9d03ef9b, 0xd61e4545, 0xb5db6b9d, 0xcc16a069, 0x0ace81f7, 0xfff6855d,
- 0x699e83cc, 0x7dce352e, 0x6e1f9ca0, 0xc1db6d20, 0x4fdf3525, 0x6de7d749,
- 0xaf93ff30, 0x2f881484, 0x919a9506, 0x9aeebeec, 0xba3fd01c, 0xc51fe1dc,
- 0x11c3f05b, 0xbf68fb86, 0x5fbef3e4, 0x08bdd893, 0xbfee0aed, 0xefb09afc,
- 0x7add7c82, 0xdde2c9d3, 0xbb9fcb79, 0x7e61f409, 0xb9f707a5, 0x9f98934a,
- 0xb2121bfc, 0x34bd00e5, 0x41c8e309, 0x2a3e2d59, 0x5223de44, 0x0f3808d9,
- 0x425fb3b5, 0xb9af8c3e, 0xc138efbc, 0xf7ba90ae, 0x26e377c3, 0xde83e5e6,
- 0x955e8e76, 0x0e98eb0a, 0x74ab8537, 0x87023393, 0xbe5ed70e, 0x39ae68ce,
- 0xe1fcc0ef, 0xcd43d03b, 0xe0d88e87, 0x820f9d7b, 0xfd18a7ad, 0xe801f8a3,
- 0xe107e11f, 0x78eba836, 0x87e707f8, 0xfc6dff2f, 0xf159fd40, 0xfe00fc3c,
- 0xe2f7e260, 0xe689ff87, 0xfdaf6a07, 0xaf6519d3, 0xa7961505, 0x3e75d7a5,
- 0xc428e458, 0x608534f7, 0x65d905be, 0xe2dfbf67, 0xf038c64d, 0x46366ef3,
- 0x064787d7, 0x76e22f83, 0xe37930a5, 0x0e8f5df7, 0x8e576809, 0x66e10aa6,
- 0xa206e3b4, 0xbe38d43e, 0x804111c8, 0x1730ac7b, 0xcbec0b37, 0xc5c82a50,
- 0x10f4eb68, 0xc756fff0, 0x1f605965, 0xe72639e6, 0x1f6d7f00, 0x5815fcb1,
- 0xa80fb6b2, 0x1aa37e7c, 0xbd749fb1, 0xab7797b7, 0xc5c43f8f, 0x0f72e1f8,
- 0x7a014f3b, 0x5d0e1a3b, 0x005903ff, 0xcb34210e, 0xf5038df2, 0xe83b4b75,
- 0xe2838073, 0x9a40b775, 0xb4283ec0, 0xc18ad278, 0x9217ebce, 0xd6aece00,
- 0xbc43072f, 0x9fcb7a68, 0xd3bc020f, 0xcd267df5, 0xb664cfb8, 0x477b75a3,
- 0x7b742bf7, 0xd088a248, 0xb76826ed, 0xb86ee7f0, 0xafd61b1f, 0x71cf0d90,
- 0xbd5a743e, 0x57e5c3c8, 0xce98f3a2, 0x690d71e7, 0xd7c8b843, 0x99337cdf,
- 0xc70667d2, 0x24fdf4c7, 0xed0b9094, 0xf14d5c84, 0xfc44b570, 0xab9c7449,
- 0x1c7c8135, 0x8cd727c5, 0xefe1d637, 0x3f48f4b2, 0x5e6fbdbd, 0xe299261f,
- 0xdcb7dff1, 0xabe763ef, 0xe763eaff, 0x150e2767, 0xa82c12fd, 0xb9d933e3,
- 0xc3c33759, 0x7afe257e, 0xc98b88f5, 0x7b4b44f1, 0xdc1b9c2e, 0x5c2bf3bd,
- 0xfcecf71f, 0x13b01dea, 0x08971c27, 0x3c4e01e4, 0xf709263e, 0xe067c73d,
- 0x6fde9d3e, 0x0e4da7f5, 0xff239ec2, 0xef82f7e8, 0x1478f0a3, 0xe586cf80,
- 0x3d0f1d8b, 0x3d9dfd0c, 0x3ce8912c, 0x3bc512f3, 0x2569e20c, 0x7df87efc,
- 0xf497b302, 0x5efc7df6, 0x5972ffe6, 0x9b6b7ef8, 0x625efdc4, 0xd5f3a28d,
- 0xe524f354, 0xf57ae845, 0x52e3d2b1, 0xe07d2c6e, 0x0f9d63ef, 0xdc6793cf,
- 0x579fa95b, 0x23f8e3ae, 0xf3c3df7b, 0xdd345700, 0x7e7d8121, 0x3c488645,
- 0xa95ee351, 0x2a3e0f52, 0x8b8f71ee, 0x76eae5e7, 0x1fa7deca, 0xf706919e,
- 0x7a988859, 0xe5b2dd55, 0xb7a85c95, 0x71cf7189, 0x457bf19b, 0xf0121dcb,
- 0x262e17ff, 0x3f8dbd1f, 0x27ca62f1, 0x09dd0297, 0x040af3b3, 0x7d332394,
- 0x7dfcecf7, 0x9ea8fb6a, 0xfd13ddf1, 0xb17874cd, 0x2ff708a3, 0x9987a37a,
- 0x79d1776f, 0x42fce9fa, 0x6a7e9e74, 0xb9f1ed8f, 0x2f92feb1, 0xbf3aeb03,
- 0x913eb756, 0xce9cf60a, 0x1952d3a7, 0xf1d84cdf, 0x46712a70, 0xdbc665e8,
- 0x66fd395f, 0x0ce66d11, 0x826dcffa, 0xe17d42e6, 0xcf906d27, 0x9c61c652,
- 0xda0956f5, 0xcfe7841f, 0x59b1d79b, 0xd7bc28e2, 0xd97bd7ba, 0xa0ca1587,
- 0x15ebcd6e, 0x7c0e17dc, 0x4aa75e6d, 0x7049d40f, 0xb48958ad, 0x6e31e99c,
- 0x9970eba7, 0x2936fce9, 0x04f479c3, 0xcc0f99a7, 0xb9f6eaf0, 0xc5394f7e,
- 0xda14b4c7, 0x216ab5df, 0x1d662fce, 0x69e978e6, 0x5e69edfd, 0x7ffc4d47,
- 0xd7d4d8e6, 0xc93dbd00, 0xe66e999b, 0x947f5d76, 0x587900c0, 0xf91ec1fa,
- 0xf48e95c2, 0x10a7392d, 0x0f1bec0f, 0xa24f93b4, 0x7d3221d6, 0x9ddbf208,
- 0x27acf66e, 0xce7a5b7e, 0x11a9bc42, 0x1f9b93be, 0xeddf0074, 0xb01cea90,
- 0x59c533af, 0xf1449b5e, 0xa2d3f535, 0x74bcf1eb, 0xc84085bb, 0xa9cb5a6c,
- 0xa84710bd, 0x9f30483e, 0x7765a8ba, 0x4be9f031, 0x51fa1b52, 0x7909675d,
- 0x6cceca30, 0x8075a96e, 0xc69cd61d, 0x4bed03ce, 0xcdbc8626, 0xbf191247,
- 0x3d3e1f36, 0xfda713c3, 0x8ebf6f00, 0x7172d278, 0xfc61765d, 0x058d64a3,
- 0xd0553fe7, 0xbb034e5e, 0x0f7646e5, 0xb8eb5763, 0xbc28d397, 0xa324b79d,
- 0x7cd6999e, 0x4a6e1dcf, 0xf33fe088, 0x1cf779f1, 0xdf40db41, 0xac35512b,
- 0xe3645497, 0x7fb8f8be, 0x1d375ea5, 0xd194afda, 0x2e2699bf, 0x751e2096,
- 0x03c84332, 0xd0a7717f, 0xa77e12be, 0xc6ce5fcd, 0x2a7f6e21, 0x4c6f9ff8,
- 0xbf8d1d4f, 0xf5eaa26d, 0x6bf7f00b, 0x5b4fc988, 0x6eccedbe, 0x3e5f6d2b,
- 0xc77cc053, 0xe22cee69, 0x929fe28f, 0xf99e9435, 0xfa5b2f94, 0x5f5f0117,
- 0x673c6a57, 0x41ccb335, 0x63f1d102, 0xc2c32dc1, 0xb5e78fb3, 0x7efc0b76,
- 0x57e72e59, 0x359f7e71, 0x5df0d53b, 0x66766139, 0xdd9136f5, 0x7ec85257,
- 0xaf975127, 0xbc39711f, 0x37c7fb8a, 0x700cb37a, 0x0d28874c, 0x693334fd,
- 0xd75dda28, 0xe5c76d9c, 0xe0fc5cb9, 0x78e89bad, 0xf2611a3f, 0xabc5c56b,
- 0xd8322f90, 0xc84cca7e, 0x6f41122e, 0x66bbdf1a, 0x471eb1bc, 0x27abcf8e,
- 0xb3307d74, 0x9bfdc455, 0xcf148599, 0xd3b18902, 0x18beadbf, 0x865ed167,
- 0xe7b5d078, 0x04bbf83c, 0x83e2fa31, 0x2fa4efd2, 0x3832a05e, 0xd2f5ca9e,
- 0x0fdfee44, 0x6f408322, 0x1f1b134c, 0xa2ea3e06, 0x0e35a6eb, 0x8eebe91f,
- 0x5097efee, 0x21be0639, 0x8f18691d, 0x032e769d, 0x7f7449f3, 0xa847ac3f,
- 0xb1c5a25d, 0xcc4bee97, 0x1307dc31, 0x76512bd6, 0xfdf05c89, 0xd46992ed,
- 0x00f2551e, 0x9fc481be, 0xe30cfa8f, 0x70902592, 0x8cc1f102, 0xa9e71853,
- 0x8affa896, 0x4c13f3eb, 0x097fd1cf, 0x30f91129, 0x9c7a2bdb, 0xdba49ad9,
- 0x093e4653, 0x97af1bc7, 0xf3a3ee31, 0x13e00949, 0x117affe4, 0xf1bd3ae3,
- 0x6f7e3e8d, 0xfaa212fc, 0x0f384928, 0xfbf970bf, 0xbcf2fcb6, 0xc8c327ce,
- 0x89f0beb0, 0xbf3a1fce, 0xa609d8c4, 0xeb4f5078, 0xe9894bcd, 0xd69edf88,
- 0xc847979b, 0xb37bd7a8, 0x3126766b, 0x744aee3d, 0x5d577f63, 0x7609d334,
- 0x11eb958d, 0xc70add7d, 0x9f19eab5, 0x573edcbc, 0x6aa3fd82, 0x11d91fd0,
- 0x60f1e83a, 0xae972f9d, 0x9cff1821, 0x6756f5ce, 0x56078b2b, 0x7003154f,
- 0xe5b8a284, 0x9d5987c1, 0xd3a2cbdd, 0x27ce6af7, 0x096ed285, 0x1af3777e,
- 0xbe20d04d, 0xc4f1e1e4, 0x8094e719, 0xafab1d9a, 0xc75fba74, 0x0bbf07bf,
- 0x23c6bfde, 0x1c4ba804, 0x3baecfa3, 0x188aecc7, 0xcfbc2a7b, 0x891e62ab,
- 0xeb4e5f99, 0x86421f74, 0x0aed3bfc, 0x76fce921, 0x6f7dfe85, 0x1e064e74,
- 0x65ee7a06, 0x1d80aef7, 0xe2be740f, 0x3afd849c, 0xccf18c93, 0xbf791db3,
- 0xbf93df41, 0xcdafbe6f, 0xc6de9f3c, 0x17f746ff, 0x8fa0ffb8, 0xcec4957b,
- 0x27d79bc7, 0xd75e9c7d, 0x99bdfe23, 0xe293c37e, 0x3eba7ddb, 0xd73fc18e,
- 0xafd13dd7, 0xebad7d37, 0xbeb77fc5, 0xd7d7fbd6, 0xb35c7d13, 0x8fc9ef1e,
- 0xeaf2f5d4, 0xdf8c16f5, 0xfafee14c, 0x9e2f1e14, 0x6ce2c499, 0xeedeb8b3,
- 0x0166dcfa, 0xb3282ebb, 0x6eff30fd, 0x36a1c627, 0xd0f662ef, 0x724e3c9b,
- 0x9c6220b7, 0x16b1eee4, 0x17d4dbd4, 0x4b7987ca, 0x808c8445, 0x2c01dcfd,
- 0x8528df4e, 0x6bef50ca, 0x6f738112, 0xefdfeaaf, 0xfd04dff1, 0x70f1fddf,
- 0xa3c62d4b, 0xc7e06d43, 0x7093cb8f, 0xaad92c5f, 0xb3bafc62, 0x03f78ad5,
- 0xd9f8ed75, 0xf9fa196e, 0x5ae0689c, 0x0d6ad4be, 0x1e814bef, 0x101e2699,
- 0xaba33f21, 0x59fde09b, 0x8a876793, 0x429b3fc1, 0x0e216ada, 0xf9615130,
- 0x3d3c66e8, 0xcc31f7ca, 0x7de114fb, 0x9f665689, 0x7644bb15, 0xfb4f580f,
- 0xe60acd12, 0x2fb6f757, 0xa0967851, 0x2fb3169d, 0xd2f4ccd1, 0x9897ddb7,
- 0xdf87b808, 0x9ff9d367, 0xc3d227eb, 0x8566c4fe, 0xbf7567ed, 0xbfb0132e,
- 0xb8b4b1c9, 0xf6dea371, 0x4aec7629, 0x1d3dc0f0, 0x4deff99b, 0xc035d8ec,
- 0xfcf6e6a3, 0x777b6e7e, 0xcda4a811, 0x984ad78d, 0xb9e3c6f7, 0x19a0b8e1,
- 0x66ff1caf, 0xc8156e7c, 0x07c4072a, 0xe0a9b45b, 0xbfb8f517, 0x71c1edd3,
- 0x5d478afa, 0x491f364e, 0x6f9f00f0, 0x03c0323e, 0xfc003fe3, 0xab59710a,
- 0x93f015fb, 0x9d3e1c77, 0x8abcfb80, 0xa4bf0547, 0xb1a6d93b, 0xef8c8973,
- 0x03c39983, 0x9abd0fb0, 0x84e6f9f3, 0x4c8ebfee, 0x61afde8b, 0x39fa33fb,
- 0x60855aff, 0xc2df883e, 0x78cc41f2, 0xeb66e41b, 0xebc4e6b5, 0xa69c89c3,
- 0x35f2f18a, 0x7f9662b5, 0x807e7e60, 0xf03977f3, 0x7147ed01, 0x8956b833,
- 0xaeff8465, 0xcef58128, 0xbfe5af5c, 0xc67b4387, 0x1cd565df, 0xed2a3396,
- 0x67d278e3, 0x40efc057, 0x3b96f96b, 0x2f70dc73, 0xf2ca5083, 0xb2f92c3c,
- 0xc493c846, 0xd6953a52, 0x0ecb922b, 0xb883f526, 0xe40d73b1, 0x479e4333,
- 0x2f445a5e, 0x0ad747dc, 0x2e245e5b, 0xbf12b0eb, 0x3d70ec1d, 0x79e79fcf,
- 0xfbebb52c, 0x3eecedd1, 0x86fe8aea, 0x850e4e73, 0xbfbf477e, 0x9a3deade,
- 0xa14cf984, 0x7dd29544, 0x78698ef9, 0x76e2907f, 0x3e477ce3, 0xf803293f,
- 0xd9f5c281, 0xff5c31ff, 0xc82e0f1b, 0x3a71816f, 0x062c8eb6, 0x087231fd,
- 0xd08b599c, 0x7c41aa87, 0xbc120f6e, 0x01fff12f, 0x512809c2, 0x00008000,
- 0x00088b1f, 0x00000000, 0x5bb5ff00, 0xd554740d, 0x79bfff9d, 0xbe4cdef3,
- 0x21264cdf, 0x012f0842, 0x1c424242, 0x61f08062, 0xc4443e1d, 0x602a0320,
- 0x43e196eb, 0x9a1af909, 0x7ab76eba, 0x2904930e, 0xb693db02, 0xb654e56e,
- 0x28bb560e, 0x82609d89, 0x04ec2681, 0x6eb50314, 0x5b604040, 0x6a445477,
- 0xbb8d3243, 0xb29eec54, 0xf7bdffff, 0x60c33325, 0x392dd9e9, 0xddf73739,
- 0x7ffdeefb, 0xf75ffefc, 0x595c003e, 0xc9a00392, 0xe7b73aa6, 0x001aa802,
- 0x6dbcdc64, 0xa0556052, 0x324e4018, 0x63240a6d, 0xd4da669b, 0x668a6d86,
- 0x9aa9e362, 0x70805ace, 0x6c14b2ce, 0xf2ce70b4, 0xc6efbc29, 0xc34b9656,
- 0xfdec32c1, 0x45f38a5d, 0xe1d90a9c, 0xfec49e0f, 0x39148ffb, 0x42ff63b7,
- 0xa4096a62, 0xe7f2ac01, 0x3fb08535, 0x1b1fe2d5, 0x69ceba44, 0x1a6d2c9e,
- 0xfe2dd7c0, 0x7be32089, 0x68529bc9, 0xf005c97d, 0xbab63b1d, 0x22948f06,
- 0xd5d02e7d, 0x60a300f1, 0x08a976b7, 0xeb82a900, 0x05f6f1e9, 0x58074c2b,
- 0x8eff1339, 0xf19217d8, 0x53d22679, 0x741b9fce, 0xb405fee0, 0x30cf41bf,
- 0x5dad901d, 0xeff6024a, 0x96eff63a, 0x8fb81851, 0xdf9313f7, 0xbf8b6122,
- 0xa2fd7fd4, 0xbfc3efc9, 0xdb9f6807, 0x792bb669, 0xc43674cd, 0xebf999f6,
- 0xeb119946, 0x3e7c1fc3, 0x65092f8d, 0x9015d59d, 0xf33efd8a, 0xd8ab2147,
- 0xf4677f07, 0xe327e67a, 0x45ce337b, 0x8175c73f, 0xd62d9fe8, 0x0cbf072d,
- 0xa1998f28, 0x61b379e8, 0x5c641fe7, 0xe8e5f677, 0x14b40be7, 0x3467e307,
- 0xf8cebe8c, 0xbd70aa43, 0x6f5f2b7a, 0x34bc9de8, 0xcd9bfd40, 0xbb945328,
- 0x8e50cbaa, 0x77fa75ed, 0x66fb4017, 0x700f979c, 0xb595b360, 0xeb6b4e53,
- 0xcdcefe88, 0xe0152008, 0xd62ce6d0, 0x98c69aaa, 0x561a729c, 0x3ec44943,
- 0x90c7df1a, 0x2e39d0e3, 0x82a1a9c7, 0x5f60e6e7, 0xafc055e9, 0x4b39f08f,
- 0xb80869c8, 0x9534879c, 0xf1fa79c9, 0xc411dd9f, 0x132c9647, 0x25fc11e8,
- 0x17a089e8, 0x0a93f48c, 0xd97d51ec, 0xd5cf8fd0, 0xdfeb8597, 0x714fd621,
- 0x075a8e8e, 0xa113f8fc, 0x85f643bf, 0x71f212bd, 0x05657247, 0x9e5693f1,
- 0xd96eb517, 0x427ab13b, 0xd3cbe1c1, 0x209fc890, 0xc69fa69e, 0x33f988f1,
- 0x00923e1c, 0xfa26ff94, 0x4cb34039, 0x62eb3476, 0x6f27f3f4, 0xc99bb7a6,
- 0x9b9e4a13, 0xe5ebf8e3, 0xcb457369, 0xb4517d33, 0xd1dc333c, 0x2ab51cf2,
- 0x79b76e5a, 0xa632e5a2, 0xf8d47272, 0x51a54dd8, 0x99df71fd, 0xd73f3515,
- 0x3faa2f37, 0xa8e2db7e, 0x979b13f9, 0xed27f547, 0xfcd47afa, 0xa8daff42,
- 0x55bda2f1, 0x29ffa4b7, 0x79a8fa81, 0x57d35e24, 0xcef6ffe8, 0xf3ed46ef,
- 0x2fffd6b7, 0x9c7ff463, 0xd234d97c, 0xf447fa17, 0xf24a838b, 0xd99f0936,
- 0x93f25690, 0xafb7aeb6, 0xbe976849, 0xe88fba79, 0x67062df0, 0x2b3d8e13,
- 0x6bf225bb, 0x26d45063, 0x4c5b1bf4, 0xfefe4950, 0x6ad326fb, 0x9d88f277,
- 0xb624d71f, 0x982af3fe, 0xf3d1ec13, 0xcc8f1796, 0x14d3da33, 0xf88da61f,
- 0xf45bafd9, 0x3df210a6, 0x147ee655, 0xf269ebfd, 0xa7a417af, 0x8a997214,
- 0x8a78a7c3, 0xed59bc59, 0x0e06d6c6, 0xb4db1ea9, 0x5faebf11, 0x505ce547,
- 0x98ff2ffd, 0x3b213fe8, 0xdffa465f, 0x86dc8125, 0x89bb56bf, 0xc361f3ec,
- 0x9a7ae96f, 0x21ae822d, 0x048fa5e4, 0xd0d3d66c, 0xfad0c3e7, 0x9dafccf1,
- 0x4805a6ff, 0xce55e7ff, 0xb2ff318f, 0x099f6bf0, 0xfe4fd6bf, 0xbc647f2c,
- 0x528fcf72, 0x7ce75c74, 0x440a2c01, 0xe42c29c8, 0x58d06604, 0x75cd99bc,
- 0x876aa176, 0xbfae18f2, 0x44d87df2, 0x13fcacfb, 0xef7c8a6c, 0xdec29acf,
- 0xb326b3fb, 0x59360576, 0x1815e728, 0xaca56ccb, 0x5db0941f, 0xe40a0bda,
- 0xe4f32c01, 0xf794242a, 0x03a679c0, 0xa292b4b7, 0xc107bdf1, 0x3fff90ad,
- 0x14dacdfb, 0xcebc379a, 0x4fdd4fdb, 0x8a815d38, 0x7dff61b6, 0x44c94f9b,
- 0x53be107f, 0xf711f162, 0xf773d2b1, 0xa69e6323, 0x3c167338, 0xbea0ce57,
- 0xad938396, 0x600bac67, 0x1733f28f, 0xe3a60854, 0x160bbe3a, 0x4748cbff,
- 0x4561b23d, 0x8f77d4fd, 0xb0647e62, 0x3fad8fea, 0xc7ab79c6, 0x9c52c684,
- 0xa7f550be, 0xc3f3d27c, 0x20afd0bb, 0x3d124b6f, 0x118cb619, 0xff5f9c39,
- 0x638d0a79, 0x867a65bc, 0xcbe7167d, 0xd8fb7e4c, 0x71bcc67b, 0x6da3b9b6,
- 0x5c72e724, 0xf88de664, 0xb00a5a33, 0xa9549f94, 0x177e9ffe, 0x0a1384e9,
- 0xcbc0cf5b, 0xfa978146, 0x24547d5c, 0x8653ea5e, 0xf08a32f1, 0xccb2ff52,
- 0x3bbea6ec, 0x97280fc1, 0xde770233, 0xfb5ed77d, 0x9e1d4eae, 0xb88c7cef,
- 0x9f2711d1, 0x8c746e20, 0x6e229f7b, 0xd90dffa8, 0xfde8953d, 0xa9c7e778,
- 0xc1f75a1e, 0x507ba35b, 0x06fd9f0a, 0xc738f7c9, 0x9d0c10fb, 0xbdba7e65,
- 0x1d21f750, 0x3b5c0ff3, 0x5d5cf94b, 0x60b745bb, 0x742d8aff, 0x7f9a79ec,
- 0x5f9a0250, 0x4e604c17, 0xf25daeab, 0x5578e027, 0x31d6db67, 0x596aafd8,
- 0xc3614656, 0xbbc10a9b, 0xe4bf7c68, 0x4bf1c46f, 0x1725839b, 0x87bae027,
- 0x75a25dae, 0x75f10e07, 0xe60e6f2f, 0xb0300e53, 0xb407cd7f, 0x05bb4d5e,
- 0xb1bf2812, 0xb431d505, 0xa0149b5f, 0x3f032afd, 0xcafd6950, 0xa04d9697,
- 0x6f7aa6f4, 0x1109c4cf, 0xc0e06b7e, 0x39475549, 0x60ffb655, 0xc65798a1,
- 0xe19f97c3, 0xa37fe0d7, 0x1cdf27bf, 0x6ff13fe9, 0xf093d91f, 0xf216bfbf,
- 0xbe35d55f, 0x7e89c489, 0x8979e3a5, 0x84d595f9, 0x5b870ba7, 0xda4bfb7f,
- 0x4ebfe0ef, 0xd940dc24, 0xdc1bc9ad, 0xeb17163e, 0xf9703ec4, 0x429dd53d,
- 0x452e53f2, 0xff3e73fb, 0x435dcd90, 0x2a9861fb, 0xc48444d8, 0xd0db87e4,
- 0x93e4801e, 0x43ecc89b, 0x6bab0e4e, 0xd1ef9e90, 0xacc7a404, 0xd8b5d585,
- 0xf31766df, 0x97feacf2, 0xafa46f73, 0xf26666c3, 0x2781e6b1, 0xed186fd2,
- 0x3a471a7e, 0xa67de68e, 0x4ebc7086, 0x6e12acbf, 0x53bf82eb, 0xdbdfa475,
- 0x5742e1f9, 0x3602f79c, 0x9314afee, 0xd94f72bb, 0x4bd47d88, 0xf089218d,
- 0xce92707e, 0x2f9b58f2, 0x48ebe8c4, 0xf98f89d0, 0x3d377e07, 0xefdeb114,
- 0x26131f11, 0x7eebf48c, 0x428961f1, 0xc3fd7b72, 0xc8ca7312, 0xe4cc81f3,
- 0x3a5c7f4a, 0x3a78bc78, 0xf6997dd5, 0xd1603dad, 0x13be191b, 0x77c2419c,
- 0x3d139257, 0x6d5be135, 0xf7c48b2c, 0xbaee8cc3, 0x4889d92e, 0x65ceba87,
- 0x3f36069e, 0x906a49c5, 0x08fae73b, 0x66e6b267, 0xc1ff8478, 0xa54710fd,
- 0xa3fa37f4, 0xcfcf3695, 0xe4e67f49, 0xbc48c4e0, 0x394299d5, 0xcfe9128d,
- 0xc2373cd3, 0x9f64e4fe, 0x7920e8de, 0x7d653ba6, 0x898a7f44, 0x0f4065eb,
- 0x8e29daa5, 0x50f5c66d, 0xdfc1031e, 0xb7fc92a5, 0x92b3ae76, 0xa6c77fdd,
- 0x55593d31, 0xff61ae9f, 0xbe47d4db, 0x4aeea9b7, 0x996dabb2, 0x0d764089,
- 0xef8676d9, 0x01d784bf, 0xbd5457b2, 0xb8a01e02, 0x36f0203a, 0xff981630,
- 0x708fdca5, 0x37be5326, 0xa3c8cc9e, 0x676f3cd1, 0x08c5c94f, 0xae0e077e,
- 0x4a7d1274, 0x321f7f22, 0xf7635e39, 0xc3814ffd, 0x9b6b4da7, 0xe1c446e7,
- 0x15bf79d8, 0x00e43478, 0xab165f66, 0x8cf13107, 0xdb3adf87, 0x1fe433bc,
- 0x0bbbb69f, 0x899b0fc8, 0xaea3c230, 0xe703a5c6, 0xcde907ff, 0xc85c7f98,
- 0x1a3c5555, 0x214df5c9, 0x33754557, 0xeb61a339, 0xfcc3c764, 0xed71a9e5,
- 0xdfc10bec, 0xbd68dcb6, 0x2abbcec7, 0xbe4c53f8, 0xe744b5ac, 0xcdd99961,
- 0xfa661ea0, 0x060de637, 0x77fd71af, 0x8bbf7e7d, 0x05773cec, 0xaf67e7c3,
- 0x11ca9614, 0xcdb38eeb, 0xffe22ffb, 0x8a0f0313, 0x0ee88b2f, 0xdeb1f0c5,
- 0xf892fee6, 0xc83bf236, 0x4e12dc76, 0x4e07d440, 0x3eb0ef11, 0xabe33028,
- 0x24e89083, 0xf226deff, 0x19b83360, 0xa9c0924e, 0x05d77ab3, 0xfc8d9abf,
- 0x6098f535, 0x9b53763b, 0x8139ca24, 0x9ccd608d, 0x228c9b2a, 0x52c565c2,
- 0x0c8c88af, 0xf6ed53c7, 0xbd20b77b, 0xf327c107, 0xfeba39ba, 0x92e49705,
- 0x37deeb22, 0xbdd7e2ab, 0x644d3dbb, 0xeea97fd7, 0xad34199d, 0xfafed351,
- 0x1d8277fa, 0x1822e8f3, 0xdb27a3ce, 0xa0544675, 0x102fe380, 0x7b33f44c,
- 0xf09f54c4, 0x1a7e4fdb, 0x922bf9e5, 0xa553ce29, 0x0dab0281, 0x78eec4a0,
- 0xda365b66, 0x3fce04d7, 0xefe89bf5, 0x0c679e5e, 0x4e6fd3d7, 0xfa277966,
- 0x93d59921, 0x4625a09a, 0x1f98656f, 0xd88d3a41, 0xe0f1eaa3, 0xc9532fb1,
- 0xf5dab6ef, 0x84bd277f, 0xf940cb8f, 0xa439825b, 0xd5d8e2da, 0x3163ca01,
- 0xcedc790f, 0x9dac6bcf, 0xfb8fcb92, 0x5017755b, 0xb4d04f7c, 0x7d8472a9,
- 0x3625d815, 0x85d8f6af, 0xc7f3151c, 0x5277a62b, 0x9afd718b, 0x74a9fd8e,
- 0xfe7d53ac, 0xed4a74d4, 0x0a9ecd8b, 0x4cfbce3b, 0xa56f93da, 0xbf9b70bc,
- 0x0813e484, 0xbc51a5e6, 0x9f06629d, 0x7a46f4b9, 0x594abbbc, 0xcbb75591,
- 0x5d29dace, 0xbca06c77, 0xfce41bd4, 0x0e0a1ed2, 0xeb027615, 0xd936740f,
- 0xbfef3d69, 0xff268f75, 0x56032fb4, 0xf578ff91, 0x7dfcc98b, 0xfe699833,
- 0xe04dbb1a, 0xf3a26fdc, 0xdce27da7, 0x130be06a, 0x3fec679b, 0xacae73a5,
- 0x838a0e21, 0x0fc847cd, 0x58597424, 0x12f0951e, 0x61747970, 0x38e7477e,
- 0x8a01ef87, 0x70368343, 0x9ade384a, 0x4f796618, 0xbfa2dbb8, 0x9adc9128,
- 0x55bcec81, 0x214af5e5, 0xf27f7202, 0xbf6373c8, 0xe8e7ae84, 0xe170898c,
- 0x6097b8a2, 0x933b866e, 0xc29de523, 0x73b46ee8, 0x0626b53c, 0x9794c94d,
- 0x9178044f, 0x274235d1, 0x3a0d7db0, 0x6f7f990b, 0x9e97c355, 0x34ba3074,
- 0x702141c2, 0x926ba13a, 0x412dfe4e, 0x123e3173, 0x93e9dd34, 0x5bcba46e,
- 0xda178982, 0x611bf7cd, 0xaec98ed8, 0x7d2389bd, 0x6b42da2b, 0xf835c71e,
- 0x20b33e16, 0x0e4fa23b, 0xfde47ca6, 0x3ef7ece7, 0x9d9b25b3, 0x5464f917,
- 0x29b61275, 0x6753e276, 0x74d7a27c, 0x39729465, 0x494e5138, 0x3c3e3e56,
- 0x4c9e711f, 0xcf3e64fd, 0x1692d169, 0x017b32e7, 0x2f2317b2, 0x5e0a5c7b,
- 0xb5ed0bba, 0xb4ee07ff, 0xdfabe462, 0x1689e474, 0x35fbf79c, 0xf620fc81,
- 0x179ea94f, 0xfc6f9f09, 0x298eed66, 0x155b6fe4, 0x9df90567, 0x2c87ef90,
- 0xd1557dff, 0x1dd847b7, 0x09338764, 0x78fbb1bf, 0x90fe37cf, 0x83c1dbf2,
- 0xc9d56e92, 0x887386ef, 0x4faebaee, 0xdee7f255, 0x7cb21f83, 0xe7ba6e76,
- 0xafea3b35, 0x3e61b3bc, 0x342675c9, 0x2ebf9137, 0x20417912, 0xa193fb8b,
- 0x362ff9d3, 0xb4e1e844, 0x7b0837b0, 0xea7c51c6, 0x987af612, 0x3b6c4eea,
- 0x4f1e1e7a, 0xba8877eb, 0x01af78d8, 0xb9218c8e, 0xac9bc237, 0x7e378e1d,
- 0x59c222f3, 0x6aeb59d1, 0x77fcc457, 0x7abf3ced, 0xbdf3ced7, 0x379ee9f5,
- 0x3dd53e49, 0xc4a9a91f, 0x0e40c5e7, 0xac0193d5, 0x7e38b58f, 0x637ed864,
- 0x0e6bc9ec, 0x7bdf34ab, 0x415f9819, 0x43496f7d, 0xdb3bedfd, 0x3e0d7939,
- 0xa49d40ef, 0x9e709e51, 0x8a1d87d7, 0x6fcd0c7b, 0x84b57338, 0x2201d8fc,
- 0xdab9e902, 0xe48e3d5d, 0x979ff886, 0x06d67648, 0x7619afcc, 0x8a764c5a,
- 0xfe1317ef, 0xc85fa8cb, 0xdaab72fc, 0x65d998b7, 0x2ec80987, 0x1eccff11,
- 0xc51aff10, 0xed0d62e3, 0x893fbd81, 0x9f6b79d9, 0x58f2c5c9, 0x5913ebf4,
- 0xd403de7f, 0xa05bed6f, 0x21373b31, 0x5ec94b9e, 0x3ad84783, 0xa4898001,
- 0x91dc093a, 0xf60503e7, 0xc337a654, 0xf6174e5f, 0xd3d0281b, 0x9247c89c,
- 0x47d9472c, 0x7de49c44, 0x3f5d4711, 0x9e67c7fa, 0xfb4f839d, 0x44d09c44,
- 0xfdc73c7c, 0xac45b7fe, 0xd66b7faa, 0xc7ca16d2, 0xf1b32d7f, 0x227ce2c3,
- 0x44727028, 0xdc504f9c, 0x6f3f51d0, 0x69d7738a, 0x1fa177d8, 0x34daee9d,
- 0xf2aa729f, 0xa947cd45, 0xcc0ee59d, 0xce7154a7, 0x0aa3beaa, 0xc222f337,
- 0x7b91fb5f, 0xf7e4cc8b, 0xaefaf3ce, 0x07f0cbfd, 0x9e1ca2af, 0x8ff28c38,
- 0x1d90a713, 0xafcc3f86, 0x8dd640c6, 0xe19283e3, 0x4bde7647, 0x97681c78,
- 0x4848fa47, 0xfa9b021d, 0x9fdbe919, 0x9fdf61f1, 0x474acaee, 0x78711e79,
- 0x9e51d2b2, 0xccbf2783, 0x38ecb324, 0x9bab11fd, 0x115755db, 0x0f3da7e1,
- 0x3838cd4b, 0x73f3a735, 0xf44b3294, 0xced18af9, 0x3071e74e, 0x243b07df,
- 0x9acb1756, 0x76e6ea9f, 0xfe62a5d9, 0x2b7c1973, 0x11bf9366, 0x828f81e7,
- 0x1fc2e7f8, 0xa263cfd4, 0x2be528fb, 0x7b1eb718, 0xaf398956, 0x3c2264db,
- 0xe092e86d, 0xe57bc827, 0x1771d8ee, 0xc46a5bcb, 0xf73b1b3a, 0xfa831b1c,
- 0x7a297aac, 0x2be50d5e, 0xc03c9cec, 0x169acfea, 0x499f3a25, 0x78cb7917,
- 0x0b794f18, 0x07f989e2, 0x16bd0cc5, 0x8745efc4, 0x6b4c90a7, 0x09cb899f,
- 0xcbb32afd, 0xb4bf9142, 0x28fee3ce, 0xccfc057c, 0x8e06f66e, 0xb3dd22a6,
- 0xb49d725a, 0x1f332cc7, 0xcb99d59f, 0xfd980ce2, 0x445432f2, 0x90b3cbb9,
- 0xd73ed3e5, 0x47942ce9, 0xa093f0a5, 0x8daef3f1, 0x914aaf82, 0x47f46dcf,
- 0xfc133dd3, 0x86cfb44d, 0xa83392bd, 0x1280f9d3, 0x8af3af37, 0x9d766a75,
- 0x7bc7463c, 0x79e881b5, 0x6f1f215e, 0xfdf3f467, 0xd58136c0, 0x347ce2e9,
- 0xf9d87207, 0xd5adef78, 0x7857bf53, 0xac4a717e, 0x166f8c63, 0xf243a9b8,
- 0x7e35bf48, 0xa9b84fd9, 0x3ca97c94, 0x35e485bf, 0x033af748, 0xa0fe3a2f,
- 0xf90bd63c, 0x617813ac, 0xb5fbe17c, 0xdd3f25bb, 0x19dfad2b, 0x81a3ff4d,
- 0x0f090b35, 0x6caab8b1, 0x5b7e5851, 0xca549b05, 0x5571636f, 0x66978c35,
- 0x2c58e295, 0xd23cea9e, 0x79e6e84d, 0xee95fff9, 0xcec8256a, 0x59ffaa7d,
- 0xfe88fa72, 0x74a96ff6, 0x7da378fe, 0x1956fd70, 0xfd7c1138, 0x6f3cfcb5,
- 0x4c327fe0, 0x945dfa66, 0x50758b7e, 0xa6dd3e74, 0x3218fb72, 0x0362f3f3,
- 0x2fefb13f, 0x3df8f914, 0x57b580bb, 0xa54f3f3a, 0xbec1dff3, 0xad6054a1,
- 0x3fc51169, 0xf0884fea, 0x79d2fb3b, 0xeb35b89d, 0xbe53efe3, 0xe29b4f7e,
- 0x6a0e4cc4, 0x8a6e2ac6, 0xdf6335d3, 0x11109cca, 0x79d2da57, 0xdb4f79fd,
- 0x74098da3, 0xe48af0ce, 0xec1bf324, 0xd423fbfa, 0xce48b5f7, 0xb1fef889,
- 0x6777a1be, 0x92b23e93, 0xde7ad3a6, 0x5a8bbbee, 0xc5ec7fb1, 0x75919c3b,
- 0xe73b31e5, 0x0ab19eef, 0xa3fd9b8b, 0x41567e93, 0x3dae80e7, 0x0ffb8ecc,
- 0x9d92aebd, 0x904ab60f, 0xcb1d1b85, 0x8f9afa3a, 0x27039cea, 0xe7c64a55,
- 0x43549fb7, 0x5c0f915f, 0xc82b72c1, 0x559b49ce, 0x1ddc6baa, 0xca21a89f,
- 0x90fa5e8f, 0x75553f9d, 0x548fcc4a, 0x3afd96ed, 0xfbb479fe, 0x5470950d,
- 0xa8c122d7, 0x8571c8dc, 0xa3bf938d, 0xdc2da7fe, 0x5cf81a7f, 0xe068f02b,
- 0x5aebc0d3, 0x6dd667e1, 0x63e3c68b, 0x1a3adae0, 0x65b47fdf, 0xcd794a8d,
- 0xfdf1cda3, 0x36afe18c, 0xfe88fd50, 0xe8aec37f, 0x71871b79, 0x387e63e8,
- 0x1bf59fd6, 0x42842c38, 0x7050e1c2, 0xe23338ed, 0xaac9eafe, 0x5ee71071,
- 0xb7111de4, 0x3379b88d, 0x7e740eb9, 0xf3bc52ae, 0x6eac2b66, 0xb7ff66f0,
- 0xab93891a, 0xbb0b2702, 0x53f4c0fe, 0x80b3d5d1, 0x9e025bf6, 0x92ef921a,
- 0xf28d24ae, 0xb7108ae0, 0x165dc5db, 0xfa225fbf, 0x2dce2c4c, 0xd216c081,
- 0x0b61e0ff, 0x243c773f, 0x84087cb1, 0xe420db1f, 0x77c841bd, 0x6359d603,
- 0xe62f294a, 0x82c6f475, 0xa528c73d, 0x6bcf13af, 0x254d1f8e, 0xee062f39,
- 0xb8071667, 0x65f4319f, 0xe31b89c4, 0xa49bf861, 0x0b2eeaef, 0xf708f7d0,
- 0x5f733f09, 0xe919fa0b, 0xbc1fbb46, 0xc5e1892d, 0x8de9c1d7, 0xed758b8d,
- 0x0e4df3d1, 0x890e5f9e, 0x11cf36bc, 0x308aafad, 0x7ae31524, 0xe9d9758b,
- 0x99f56f67, 0x12deff69, 0xf5d3dd89, 0x3cd3e3ea, 0x9c38f471, 0xdd7c8b57,
- 0xf3a52fe8, 0xd01f9c2d, 0xeb23939a, 0x9e0e9df1, 0x94cd577f, 0x88ff247d,
- 0x696965fa, 0x65fadc6e, 0xbfe703a6, 0xe76ebd9d, 0xc5fac8d4, 0x709f27b5,
- 0x1facbdf8, 0x7f929455, 0x64fee168, 0x4dd71ca0, 0x581c7ca3, 0xb16deb7e,
- 0xf0cea9f8, 0xef288e22, 0x427087ba, 0xdd25d9f6, 0xfcc1384d, 0xcd126eff,
- 0x437aba32, 0x627597fe, 0x97e5c63c, 0xc303f82d, 0x9c09f1dd, 0xa8db946f,
- 0x5180f578, 0xc17dd407, 0x79e34df3, 0xeac4399d, 0x892eba81, 0xc8fdb6e1,
- 0xa45c9cb5, 0x8ffbb077, 0xfdb06b39, 0xa38f0707, 0x1f02f3ed, 0x572077d1,
- 0xf371ad5b, 0x2dbf61ca, 0x5276616d, 0x593284a7, 0xf31071de, 0x3f5819bb,
- 0xd58cfa9c, 0x1247ed0f, 0xf6b9d356, 0x38cf5ac0, 0xd4f42bed, 0x3f2c8d00,
- 0xac2d846d, 0x3225fca5, 0xf1a0db9f, 0x131e4aef, 0x4ffa8ef1, 0xc31fae21,
- 0x8d2b5fb9, 0x5b7c17e7, 0xfa374b67, 0xd4afc303, 0x1757bc0a, 0x294ad9ef,
- 0x539e6c57, 0x3308ec2b, 0x62df1678, 0x0e9d9bf3, 0x9c08bf91, 0x644a9c36,
- 0x71e0eaf9, 0x5d33a359, 0x474feb94, 0x7986fe53, 0x739c5e7a, 0x2e04cfcc,
- 0x65fdc5fb, 0xe4ccb943, 0x5bc99a66, 0xf9421f23, 0x9e0cbc31, 0xbe53f64c,
- 0x8df8745f, 0xf57fd23c, 0x69179c5e, 0x0f3fa877, 0xcfc7aefb, 0x481b5c70,
- 0xc6327762, 0x6fc3bef8, 0x359c264c, 0x9f32fa9c, 0xbe5ae5eb, 0x7d39b8ea,
- 0xbc492b46, 0xbc49358e, 0x8730ed8e, 0xf27ea952, 0xfedd941e, 0x7a1a7d08,
- 0x476117fe, 0xfaf5e660, 0xface871e, 0x171c5d0d, 0xe2de6ea6, 0x79f82bfe,
- 0xbff6c28d, 0xe21e7c61, 0x1ae22be5, 0x7ba85d10, 0xb86612af, 0x31349ef3,
- 0x8727bc7a, 0xbbe32332, 0x451dd68f, 0x06a1af7e, 0x02491f98, 0xc7e8b3f2,
- 0xdef7547c, 0xe5812e77, 0x76f2c74b, 0x95bf3054, 0xadf90327, 0x4d554e27,
- 0xf90f8c8a, 0x27e7990e, 0xca2c8724, 0xfbe59e56, 0xc234390b, 0x73ef5172,
- 0xce92bf1c, 0x527580e5, 0x6c71d937, 0xf9ab749d, 0x05b7436e, 0x7bd81ce8,
- 0x13bec2c1, 0x81bddab9, 0x85f0e1d5, 0x19f91267, 0xa76e78f0, 0x1bc389f6,
- 0xabf3d126, 0xcede3787, 0xc6a52fce, 0x23e5f8a8, 0x2f28b2fa, 0xe3a9933a,
- 0x99f76d78, 0xc2ad604c, 0x647ea7e8, 0xc1d77afc, 0x4f60d7e3, 0x90a73b02,
- 0x00e38f20, 0x5bad4426, 0xcb16fed3, 0x653a6a23, 0x8c1e2457, 0xf0703ef7,
- 0xc223eafc, 0x9013f101, 0x6dcf4c5c, 0x7ce9adbc, 0xad53d19d, 0x1b1e9804,
- 0xde3e145a, 0x2fcc5bca, 0xb03e1d19, 0x36fe88fb, 0xf7e6bf3a, 0x02bcec1a,
- 0x18fb3267, 0x6ff4282a, 0xe8affec7, 0xc875ca11, 0xdcfe026f, 0x9b83eec2,
- 0x11a7c77a, 0x5f7a87ee, 0x178bc477, 0x083dd0ef, 0x97227a92, 0xe3b117d7,
- 0x39f8327b, 0xdcf389c2, 0xeb989d8f, 0x9fcf1499, 0xaf1e60f9, 0xef2125b7,
- 0xbc516576, 0x3217b4fb, 0xdecf39f8, 0xe209df6c, 0x812dbfa7, 0xdbf5a7dd,
- 0xfce8b9f8, 0xe9cdc7fd, 0xa5db7714, 0xaa3f1469, 0x405fde0b, 0x2fd8f8f7,
- 0x782b7e63, 0xd61bdd90, 0x742db4b6, 0x2ea3a1c5, 0xc5f1fb83, 0xc8fbfc6a,
- 0x7bf8c5db, 0xf510cce0, 0xee130ed1, 0xa2855ef7, 0x8679676d, 0xf436f92b,
- 0xff0bf7bf, 0x8512c0fb, 0x81ef25e5, 0x077bf0ae, 0x54b03f7e, 0x85fbd1f8,
- 0x1e5a5e5f, 0xed9727ed, 0x7ee9a786, 0xbe2b9960, 0xac487e1f, 0x6c5c1cbf,
- 0x451607dd, 0xe4487bcf, 0xa3b90f77, 0x10ca4f9f, 0xf21f37fe, 0x3006ffc9,
- 0xebbe901e, 0x5c58130b, 0xc4ca6fbd, 0xb1c179b8, 0xfdeec0cd, 0xbffdc57b,
- 0xc286f7a1, 0x3abc59f7, 0x35fe73d1, 0x09dbf31b, 0x5ee71790, 0x195e246b,
- 0xd720fef6, 0xa82fb8b7, 0x868d38d5, 0xe560afde, 0x652e7913, 0x90b17de8,
- 0x04def57f, 0xaf9ef22d, 0xea8b6036, 0xd36f3b7b, 0xf9f8462e, 0xf46f816a,
- 0x73c8e6fd, 0x67b29d8a, 0x0bdd0671, 0x3e59fb58, 0xb8b01c8d, 0x08e57c85,
- 0x112c72be, 0x6dcae8f1, 0x77e2e26b, 0x8fbb3f84, 0x6b077dfb, 0xcc2d0a7b,
- 0x92036aee, 0x6aa3ee9f, 0xac9ebc83, 0xc9ebc05d, 0x579e76fc, 0xf25078ae,
- 0xbee624bb, 0x067d134e, 0x795a967e, 0x327036fc, 0x1f812f2c, 0x7e78a71a,
- 0xb1e788bf, 0x7d049a38, 0x779ce90b, 0xd2724ba5, 0x78b171f7, 0xea6abe5a,
- 0x6f9ee45b, 0x9bc41f86, 0x16327e42, 0xf0cf3f47, 0x1a632b7c, 0x4c570bab,
- 0x144f75c1, 0xb8439a7e, 0xdd89bba9, 0xdb7a14ec, 0x413bec9b, 0xbf66bef1,
- 0x5fdf07b8, 0x792219d8, 0xf7cb02f4, 0x5b7d6dfa, 0xcc1e79eb, 0x836bc1ee,
- 0xdefa4e09, 0xc92bb6b5, 0xf6fd4099, 0x54c9c486, 0xcec9761f, 0xb457ec24,
- 0xf2405c9f, 0xdfe328ac, 0x61a9d465, 0xb4ae6f96, 0x5e92b679, 0xa27b3897,
- 0x3a0dbfee, 0x58f3866f, 0x0902f6bf, 0xe76fe327, 0xe0c85e6f, 0xf8feaef1,
- 0x719399e7, 0xcf36e9ab, 0xf07ba26e, 0xba5557ad, 0x7e4ef326, 0x4eba6163,
- 0x6f3674f3, 0x16cf4b49, 0xe8357e3a, 0xee343b0f, 0x367f155f, 0x6f8b23cb,
- 0x86907bed, 0x50976f83, 0x73d03cde, 0xc08d44bc, 0xfa3d7f77, 0x6bfa38e7,
- 0x5bb09300, 0x69256b33, 0xb86fc8b9, 0x8fbb7b1d, 0x41b9d266, 0x316fd93f,
- 0x295267b5, 0xbdb6d62e, 0xf2913a97, 0x1ade0e8c, 0x92e95deb, 0x87303cd9,
- 0x894a1ff2, 0x4669efa4, 0x5f0095df, 0xff942007, 0xf1c894c0, 0xfb6fffa6,
- 0xae38413f, 0xeca286b5, 0x561390df, 0x47563eed, 0x7bb0b61e, 0x8927ba75,
- 0x92ea9efc, 0x2c0cf5c0, 0x674ec86e, 0x78f0bdd2, 0xf0ccc54a, 0x10cdf508,
- 0x9ee9db34, 0xeff32836, 0xff99b2cc, 0x9ff62e9e, 0xd0f60e61, 0xc53396f7,
- 0xe82ce2bd, 0x06bef363, 0x40bad661, 0x0f3b5333, 0xb72dac9c, 0x32a3ef06,
- 0x901038af, 0x4cc1ff49, 0x9592edb3, 0xf1007f7d, 0x37223df4, 0xe4325c33,
- 0x13fdd321, 0x962f5eff, 0x8f02eb9f, 0xefdc5c33, 0xdf412a50, 0x80439659,
- 0x09df77dd, 0x1def7121, 0x58d98f9f, 0xd77dd1a7, 0x893b689d, 0x367e1e4c,
- 0x23f10e7f, 0x7427e3c7, 0x2c33531f, 0x293e88d0, 0x9eba6998, 0x0c7ceb74,
- 0x375b0266, 0xe0785d75, 0xfb91b2c9, 0xdbd76742, 0x50bbe8e7, 0xdf62e5c9,
- 0xc9ad3a8d, 0x04975641, 0x7ec3fdcd, 0x39200f2c, 0x66626d73, 0xf777c8c6,
- 0x3df601e0, 0xf777ec45, 0xcce5eec4, 0x8cb4ef91, 0xfaf73fef, 0xc426eb97,
- 0xd5872ac7, 0x4a3e2329, 0xd07739ad, 0xcd39e0f9, 0x8d399893, 0x996d03be,
- 0xfb3116c8, 0x53bcb1a7, 0x5c092ae0, 0xe4bfc4e5, 0x07fbbe32, 0x389f1786,
- 0x8265f6bf, 0x9252ae9f, 0x91587c30, 0x43881dae, 0x5fa19dab, 0xe159efa7,
- 0xe53af9a9, 0x566d5bb7, 0x166fe527, 0x846937a2, 0xff2b26de, 0x7ef8c1ee,
- 0x4d8e562b, 0x663e8328, 0xcb2b4e7f, 0x628fd78b, 0x6b8f34f7, 0xb27fbf9c,
- 0xfd10a678, 0x1bcca78f, 0xd16ef945, 0xb164e62f, 0x30e51bfc, 0xe98390c7,
- 0x80e7ffc6, 0x3c91977c, 0x817fff63, 0x802a2fc1, 0x72134681, 0x48d7f834,
- 0x5c6f143f, 0xbf431fa8, 0xd9722379, 0x57f9c891, 0xf18f4be8, 0xec9d5dec,
- 0x836f9634, 0xcf05ffbf, 0x10785073, 0x00107850
+ 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, 0x94f3ff00, 0x51f86066, 0x257bc08f, 0x799c1819,
- 0x8968c550, 0x1819390b, 0x0bf1030e, 0xda005620, 0xc0c5caeb, 0xfdc406e0,
- 0x88013c40, 0x3eb100bf, 0x01830337, 0xd902a710, 0x736e6852, 0x17ba0264,
- 0xd8815d88, 0x32bf881d, 0x637c3030, 0x767ede20, 0x623da021, 0x2039fe08,
- 0xfd04b2fb, 0xf0d83ffc, 0xdafa655d, 0xc0c2a817, 0x2a83a310, 0x8fc68b16,
- 0x466fc1d3, 0x027c9a3c, 0x8f113f1a, 0x5473717e, 0x2a019d7e, 0x8188c93f,
- 0x9a920f61, 0x6efc037a, 0x81afc741, 0x3100df7a, 0x74769a00, 0x0003685d,
- 0x00000000
+ 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, 0x45547809, 0xbedd70b6, 0x4e9def4b,
- 0x62585908, 0x81511007, 0x05e42ce9, 0x62d9b1c4, 0x970621f4, 0x66854611,
- 0x44749ecb, 0xf9d1c1c6, 0x153610d3, 0xc713309d, 0x60ec44e0, 0x81a0d050,
- 0x60241009, 0x3cc0ea03, 0x64ffe31d, 0xb83066dc, 0xc5a4c6b0, 0xfcb8df0d,
- 0x4dd54e75, 0x11d37bdf, 0x7fef999c, 0xca3fbff3, 0xfb5ba957, 0x539cead9,
- 0x2c922aa7, 0x4222e910, 0xab9f83be, 0x409bf908, 0x4d171908, 0x69e5a909,
- 0x24e05295, 0xbfa2e024, 0xe1521366, 0xd3cb4254, 0x43b29909, 0x48955f0e,
- 0xc8428df3, 0x7da6f34c, 0x6eef2c56, 0x53b0f960, 0xfe5a11f1, 0xd3cd1371,
- 0x8ee6033e, 0xe5a0ae87, 0xd9221d91, 0xb28edd08, 0x21124899, 0xfd842dc7,
- 0x0e7cd364, 0x96568521, 0x3fdc68ad, 0xb717da07, 0xf6958999, 0x68bbb157,
- 0x5f3415c6, 0x50264874, 0x32d362a5, 0x97cd1065, 0xc8168484, 0xf3664cf7,
- 0x4314ee0b, 0x1efd689b, 0xcdd24757, 0x574e420e, 0x2147885b, 0x91d9c6a4,
- 0x4268d374, 0xf2db434a, 0xb3695da0, 0x581135e0, 0x5397a6c7, 0x045b5d61,
- 0x4843d9af, 0xf13b66d9, 0xf873628c, 0xde3bfe8e, 0xa2af862a, 0x3ae98be5,
- 0x88b7ed09, 0x1111e6d4, 0x78a75fc6, 0x9df8519c, 0x38e376ae, 0x0b62be6a,
- 0xabb6871d, 0xc2f0567c, 0xc44d2b12, 0xefc742df, 0xf59d6dde, 0xb7d60384,
- 0x84e9194c, 0xa056ad75, 0xde68515e, 0xe607ab4e, 0xd1e4a8d7, 0x4686d2f2,
- 0xb47470a5, 0x03cdb2bf, 0x1faaf3f4, 0x94d7ec9e, 0xd5d3d31b, 0x46467884,
- 0xf884a5f3, 0x44bf685a, 0xc733290a, 0x407fbf44, 0x081909e2, 0x63c48bfd,
- 0x214ff689, 0x4783df89, 0x5e14afe8, 0x844ebdc1, 0xc5b78aab, 0x27bbfa6e,
- 0x6eb3b78a, 0x9229478e, 0x4d5feda3, 0xd03c021f, 0x9c02d4f9, 0xcf96ba68,
- 0x4c9135cf, 0x2eff6892, 0xe903711f, 0x351eb7f5, 0x3cc995ad, 0x185ac742,
- 0xc693e31c, 0xee42bcd3, 0x7e425e20, 0x37c722bd, 0x241fe695, 0x6f3039fe,
- 0x062fe4d1, 0x92d2113c, 0x4abbf402, 0xfd60b320, 0xd349813f, 0x94a955f2,
- 0x6bdc293e, 0x213ce5a7, 0x89ee7c0a, 0xf27c2f90, 0xa7ec74fe, 0x6851fb08,
- 0xdfcfc33f, 0x572f3b8f, 0xaf3b8fd7, 0x0aa7ed58, 0x585db1fb, 0x1379b53f,
- 0x2bc9f3f4, 0x1bb9fb55, 0xd85d71fb, 0x4f57dcba, 0xeae7cfd4, 0x7e27ec72,
- 0x69f897aa, 0x07a5517d, 0x6913e1d2, 0x3e39a3b9, 0xa5a27ef3, 0x812bc98b,
- 0x4b949dff, 0x971174b4, 0x61d1d36b, 0x97412fbc, 0x8fb93da7, 0x30f3ce5f,
- 0x7c82cb88, 0x50520ca9, 0x641a4c2e, 0x35dcf9c1, 0xe17281c8, 0x4bfe09ae,
- 0x301e74dc, 0x79a54936, 0x7723ffc5, 0xf3a6ba0c, 0xa40a4814, 0xc6a4131e,
- 0x8332d5f2, 0x5fc1e4c3, 0xdb463c8f, 0x91914c07, 0x4ebf34f1, 0xac38f498,
- 0x21311363, 0xa9226c7c, 0x33367a82, 0x3ab4f941, 0xa089e73d, 0x866b4e06,
- 0xd10bfc52, 0xfec8d77e, 0x2dafa014, 0xd020e6e4, 0x94a1aadb, 0xf21107c9,
- 0x70a6f074, 0x87eda250, 0x3c00a616, 0x6fe50acd, 0x1d0af8ed, 0xff8e347f,
- 0x03bf8c1c, 0x77d71fc6, 0x5cb0f37c, 0xb496f8dd, 0x16f8dd62, 0xe94f8e85,
- 0x9db9377d, 0x37e14f8f, 0x83e79081, 0xe6f8e1b7, 0x7f1c62b4, 0x758a42b5,
- 0xc77adbe3, 0xfdd6017f, 0x1feb7f52, 0xfebf4136, 0xfafd52b4, 0xc3feb615,
- 0xdf1f1164, 0x63ffeb86, 0x7f5b2170, 0xbf5b295a, 0x3bdbf599, 0xfe17abbe,
- 0x8fbac1af, 0xe1feb7f4, 0xbfebf513, 0x7ebf5ca8, 0x6dff1b33, 0x77c7c152,
- 0x04eff8e0, 0x2ffad9cb, 0x15f1c72a, 0x740bdfb3, 0x55b60ca4, 0x64f8e885,
- 0x64886508, 0x4c3e5194, 0x42102547, 0x6191d7db, 0x6cbb8708, 0xb0beee8c,
- 0x44737a51, 0x51091de5, 0xacf2a28e, 0x597cd392, 0xe40524f3, 0xb953962c,
- 0x754f88b7, 0x74889b61, 0xa1ccea4d, 0xbb7ce98b, 0xe420c4db, 0x195dd617,
- 0x23bf7112, 0x9da00b73, 0xfdf0c244, 0x6cc787a3, 0x98cbaed4, 0x8f95aa2e,
- 0x88f8ea77, 0x993827cd, 0xf3a2aa8c, 0x3044069b, 0x4e3f9a2e, 0xf2a128e5,
- 0x472a7df3, 0xd3213d21, 0x0ff7e8f1, 0x8a259ca9, 0xb1966f96, 0xde483c7d,
- 0x72049518, 0x971cfd82, 0x2f8fbc18, 0xff004211, 0xa1ddd62f, 0x545a7c80,
- 0x8f40a76b, 0xf1c023ce, 0x0e6dd914, 0x9e10146d, 0x2dcf801e, 0xfc848ac8,
- 0x9535a295, 0x7ea8b682, 0x6dddae80, 0x8532b424, 0x76b05fd6, 0x5d3750de,
- 0xccb3adff, 0x1fec2299, 0x84d837c4, 0x9b064c7c, 0xd5990972, 0x4c1e4eba,
- 0x92ccb733, 0xb4d4efdf, 0xe7d7ed9f, 0xe7d62d6f, 0x6c90e5bb, 0x44a37d02,
- 0xdfb48d20, 0xe5f4abdb, 0x42f138ea, 0x1f2bc302, 0x6c4927ef, 0x9a43b7be,
- 0x88dd9f09, 0xd66e39d7, 0xe04f9d56, 0x7184991e, 0x481cecbf, 0xb103ff10,
- 0xd6cddf9e, 0x1cef9c6d, 0xa02be2d9, 0xb77399f3, 0xce34f088, 0xdd9f73bf,
- 0xd34b1a67, 0x20654ffa, 0x8c7ae341, 0xd4bb9ff3, 0xea371eb8, 0xc682f361,
- 0x8c4e8cef, 0x9b6814f4, 0x4d43e034, 0x6b968abd, 0xa1a87c06, 0x33cdb2af,
- 0xd092f975, 0xa2fd5d6c, 0xf2ba79fa, 0xba25b545, 0xee6b05f2, 0x05e7e5d0,
- 0x9fd5d6ef, 0xae9974bb, 0xfbaaf6fc, 0x16b7e574, 0x67e5d3af, 0xeaebd7fb,
- 0x51ab32df, 0x2bec2e57, 0xe513a8b9, 0x54a2ffaa, 0x36df2bd0, 0x9547a013,
- 0x387e55de, 0xe9829d59, 0xa60f6ae9, 0x294f80cb, 0xb3769bff, 0xde71b034,
- 0x2aefc045, 0x55c84e9c, 0x464fc069, 0xd3c237ba, 0x67f4df48, 0x487dac70,
- 0x5205cb4d, 0x87ae7200, 0xf7eacfef, 0x120e5c73, 0x72d31cb2, 0xf96df185,
- 0xc4c9d4f6, 0xc8f0f905, 0xfdff472a, 0xd7011692, 0x1e8b4041, 0xd4a37808,
- 0x70ebc3aa, 0xf6bb3cdd, 0x257e388b, 0x0078eef0, 0x0132c155, 0x307c21f8,
- 0x3031c6ed, 0xcc72df1f, 0xfdc40db7, 0x7f3aabb7, 0xc01287c0, 0x93d300af,
- 0x3d30b3d5, 0xf4c7ed5e, 0x4c62eac3, 0xc2aeafdf, 0x297ab3b4, 0x83ab47a6,
- 0x7aa5fe98, 0x54efa60d, 0x56fa62d7, 0x7fa63d75, 0xda610eae, 0x54c3ed5d,
- 0x395edba5, 0x4af5c899, 0x1dd3ffae, 0xf967f302, 0x7bfa445a, 0x37a3f207,
- 0xacf1f805, 0xa0918be3, 0xcb7d9f37, 0xef2f404c, 0x7a465e0f, 0xc4ae17e8,
- 0x61457a87, 0xac870a88, 0x1b56e5be, 0x44d593c3, 0x1b9509f2, 0xa4fc5df7,
- 0xcc68fe77, 0xda01244b, 0x9d33bc87, 0x411dfa31, 0xc3e75f10, 0xc645f113,
- 0x71f140de, 0xe5bfd1fc, 0xf8e7bf40, 0x283b653e, 0xc2497ee2, 0x5f01784f,
- 0xfee1b81a, 0xe5c1d913, 0xf7e079f2, 0x7e1540f1, 0xa684691d, 0xd2370413,
- 0x3356d9df, 0xed8e0091, 0xfda110f6, 0x84f43d9c, 0xc5bbf60b, 0x87f72629,
- 0xa6a0e031, 0x6ee92d15, 0x689f7687, 0xd6cfe7d3, 0x282df90a, 0x37713d37,
- 0x72ba018d, 0x011c3fbb, 0x54c14ff8, 0x8a7167ed, 0x0070fee2, 0x45f18fc2,
- 0x29d23c73, 0xdeb0dbb5, 0xfd1e7b3f, 0x479d13f5, 0xb680f92b, 0xf8645b47,
- 0x3e91edf9, 0x533e96f8, 0xed4f000a, 0x9fb017f2, 0xefbfe8db, 0x12bf4186,
- 0x037ed5e6, 0xfcd0622d, 0xacdef823, 0xf3b68f1b, 0xb43136a8, 0x255e9feb,
- 0x27a55c72, 0x0bfeda2a, 0xce3b403a, 0xfdcbd6ea, 0xd03e5d78, 0xedd6ea96,
- 0xe50bf003, 0x482c527b, 0x9ce52f40, 0xc7247a7a, 0xefce811a, 0xf461e088,
- 0x157ab026, 0xefc54e96, 0x00ec3241, 0xae7e603d, 0x5b9e6f4a, 0xf972a5de,
- 0xe4c87fd4, 0x9aff287e, 0xda272ace, 0xc4c0951f, 0x780bf344, 0xd96b7e6e,
- 0xa7779074, 0x5e1f6c4c, 0x605c0a48, 0xda931494, 0x3e43d01c, 0xa07ca626,
- 0xffc98ffb, 0xec696576, 0x05261181, 0x8d60b3e7, 0xfaa41f7e, 0x545f2e93,
- 0x9217cfaf, 0xce80921b, 0x1264eb0b, 0xf51f8012, 0xc62689e5, 0x6aa4450f,
- 0x2b0fec15, 0xdf313db8, 0x74c1a44d, 0x1ebb157e, 0xe74799cb, 0xc989b971,
- 0x2ebed56f, 0x2ff36049, 0x7c54696d, 0xd683fcb4, 0x415c9fac, 0x15687da0,
- 0x3b8219f8, 0x4f26ef04, 0xd0fdfc5f, 0xabe71bf9, 0xec7d1fee, 0x8a8f3e7c,
- 0x142f82cd, 0x6f191f63, 0x13fef812, 0x035e3844, 0x99e8d6eb, 0xa8387337,
- 0xf28679f9, 0xeffe430a, 0xa244b7a6, 0x8223b7a3, 0x40d366ff, 0x5fa05f46,
- 0xf1445209, 0xa7fd23ff, 0x9e7fe9f4, 0xb13fdc69, 0xffb421ff, 0x15ff5d1c,
- 0x47fed4ff, 0xddff99f4, 0xd8affab1, 0x906775b5, 0xe7d29bca, 0xba11761e,
- 0x6a929cff, 0xff14bc93, 0xba569be5, 0x4a4e0e80, 0xf3d01741, 0x1f9890a9,
- 0x3f57618a, 0x3e0f4bd7, 0x0f760087, 0x3ffb4afc, 0x3303f4fd, 0x62f97f60,
- 0x7b46ec93, 0x6c39b366, 0xd95afca6, 0x8c9d325a, 0x9631fcc5, 0x0889fd5f,
- 0x7d3d36f9, 0x70f53e96, 0x28c7f812, 0x3f7d70a5, 0x6552fa8c, 0xb07947d3,
- 0x044804ff, 0x0ed8ccf9, 0x80973fc6, 0x129e71f2, 0xce9cb7d7, 0x00f0f513,
- 0xf5a04b87, 0xf0444f81, 0xe64e924d, 0x2fd434a7, 0xc84f7ae6, 0x4e3c4ce4,
- 0x6ff23c55, 0x5e40dfe4, 0x2120f0aa, 0xbb88f7a6, 0x760b1b1e, 0x7fd3576b,
- 0x9c0d04b8, 0xdb3b3e54, 0xe7f1e0b2, 0xe3cbfd3d, 0x45876e6e, 0x9db085db,
- 0x6beb8da7, 0x972d2ced, 0x63f02ec3, 0xdeca3796, 0xbe5cfd20, 0x1f2789f5,
- 0x6df23b05, 0xda62f7b3, 0x97d6d97f, 0xe6813cfe, 0x89c9b6cb, 0x1c32d9d3,
- 0x2f145242, 0x696ffa01, 0xa50f1466, 0xf1497fbf, 0xefdf618c, 0xa3e2884d,
- 0x857edb6c, 0x8f0be98c, 0x95fb2d29, 0xbc0c474e, 0x03cb1cb4, 0xf5dc4abd,
- 0x3f78028d, 0xc9204fb5, 0xd9e031e9, 0x07ea12f8, 0x23c42700, 0xde2f53c7,
- 0x1403f50c, 0x55cf202f, 0x97cb193c, 0xfd037973, 0x3d234679, 0xf83cfb3f,
- 0x7b31df7d, 0xcfc5fd61, 0x7582e9de, 0x18aa909c, 0x32b63f5d, 0x2dc747c9,
- 0x6e498396, 0xe2f7d94c, 0x7a433f0d, 0x67fd7a2b, 0xf35ecc49, 0x6f709aa5,
- 0xfac2a60a, 0x8cdc3516, 0x7e242beb, 0xc7e2bba4, 0x8f9002c4, 0x7f244b9f,
- 0xb8be0c5b, 0x717c6458, 0xb4552362, 0xd04efae8, 0xa0fd076d, 0x6d0c5bff,
- 0x1dc57f42, 0x67fff804, 0x2c9affaa, 0x16e7fcc6, 0x4dafa786, 0xb54f9eaa,
- 0x36bd2d3c, 0xfc00eead, 0x4bea1e9c, 0x80573f06, 0x0f0e4148, 0xafda3be1,
- 0x64b4faf8, 0x91e21f86, 0xaa3b7872, 0xef814c07, 0xf643bf50, 0xdaeac759,
- 0xa3d2ef91, 0xe3e12fe3, 0x60db79d3, 0x44913eff, 0xac625b8a, 0xf2a8a66f,
- 0x35c7dd3d, 0x6fe1a5f4, 0xf74defc6, 0xf956fe31, 0x1f33343d, 0x837b3fca,
- 0x83b40ff1, 0x2bce91fd, 0xfbe58c9c, 0x1e50126f, 0x16384998, 0x9cc9375f,
- 0x2ae5f5af, 0x4b79d09d, 0x5e869c42, 0x8404ffa0, 0x0ab7fa3f, 0x8d3b68eb,
- 0x78c00cbc, 0xa9fdbeae, 0xf9c45b7c, 0xf9ea23df, 0xbe30349f, 0x0abf5fef,
- 0x2e573ee2, 0x147c9e87, 0x67f295f8, 0x2afc03d0, 0xcfbac017, 0xf3fc1f34,
- 0x9c9f294f, 0x54f95169, 0x7c8d3f2f, 0x5c7dbc5a, 0xb33d3e4c, 0x9f362336,
- 0xf931efd2, 0xd3e32d74, 0x53f25bff, 0xc03e5f85, 0xfc28f2ef, 0x1fd87954,
- 0xf0f28d1c, 0xe1079323, 0xf4879469, 0xd3920de7, 0xba54fe97, 0xf4ade953,
- 0x408b8a99, 0xa5d2f4ee, 0x74bd774a, 0x1f5dd2a9, 0x7e0e88ff, 0xa004f2c6,
- 0x05274a05, 0x0de48fbb, 0x6f2cf8a6, 0xb440e767, 0xa790cbdd, 0x36e1f270,
- 0x1e5f6a46, 0x87cda89c, 0x4316f90c, 0x5f219f7d, 0x37efa860, 0xf50cabe4,
- 0xd03fcc43, 0x48215076, 0x7d5d6107, 0x3a093979, 0x57b72fc1, 0x87affb44,
- 0x6d1579ce, 0x1e9cd3df, 0xb079520a, 0xeaeccad2, 0x156540c8, 0x771eafc8,
- 0x790095c4, 0x7b6bd32b, 0x78ae220a, 0xac787e8d, 0xdbf9445d, 0x5af92219,
- 0x1f94457f, 0x9d7f106a, 0xe672bfa4, 0x3a269c67, 0x3d8296d2, 0xc17a2b59,
- 0xecb85d44, 0x3cb81716, 0x5f87da7a, 0x5f7e8b3f, 0xe3c45874, 0x6b9b1e8b,
- 0x048bcc2c, 0xc6aa527d, 0x8249382e, 0x7e089dbf, 0x1f6676c3, 0xd06b5c2c,
- 0xa45ac82b, 0x12c7428b, 0xd522e405, 0xfbd7dfe7, 0x977d194d, 0x1b8afef2,
- 0x7b6ae5f4, 0x3b023938, 0x5f49b4ad, 0xce76e7ee, 0x67bd2a93, 0x17940c90,
- 0x7d80c060, 0x34ebe5cd, 0xb3f5f471, 0x0e7bfc28, 0xe5e80489, 0xf088bb6c,
- 0xceccdb3f, 0x20704909, 0x89254df2, 0xe1535ca0, 0xa17c05d4, 0xba772ff4,
- 0xe735fc76, 0x7ca55a1e, 0x7f63bbe7, 0x9daed347, 0x03dc8f6f, 0xa66f5df9,
- 0xd6fa4bbd, 0x8acfb29f, 0x7d9ed9fe, 0xe94f3c4e, 0xda6afbd9, 0x6ddf903d,
- 0x7b3cc2f6, 0x16397df6, 0xb967a7e8, 0x56e418b9, 0x7f8a50cf, 0xfdecd69a,
- 0xee276c72, 0x6f102b93, 0xd30a8baf, 0x76ffda73, 0x94844854, 0xfff60aae,
- 0x33f4767d, 0xa2b79e04, 0xef67a07f, 0xc77e3997, 0x953d6f3f, 0xc7a4dcfc,
- 0x876d6649, 0x7f33c5f9, 0xf8cf6073, 0xb9c19627, 0x657eeb6f, 0xf29f2d01,
- 0x416337c2, 0x676cf61e, 0xdcb74d7a, 0x05ce01b9, 0xeef352fe, 0xb9c29932,
- 0x1062981b, 0x862bb995, 0x623a0e4c, 0xf41be5c1, 0x3c285c7b, 0x067ffd3e,
- 0xf79e021e, 0x433bb795, 0xfdd60116, 0x4177d1d5, 0x2333ec0e, 0x3debaa5d,
- 0xf50cb2d3, 0x3badf38e, 0xf5f66241, 0x0b759cff, 0x77590be1, 0x8daff486,
- 0x07a25def, 0x83e462f1, 0xf7be74be, 0x756fcc2e, 0x17be717a, 0xff33ef48,
- 0x83ffd7c5, 0xe29dbef1, 0x75fe75dd, 0xaf8bfd57, 0x1fbc7fbb, 0xeef1c39e,
- 0xc0f57386, 0xfce0df0b, 0xab9ca87e, 0xf7e717fd, 0xeaafd6fe, 0x79307fe7,
- 0xf5a0c8de, 0x03ad49f3, 0x2a6b8b14, 0xa0ce1c0e, 0x72187fa5, 0x3be61e30,
- 0x18c39f99, 0x125fb7e7, 0xc164fdb0, 0x891d7684, 0xc75db817, 0x5cc1a1ec,
- 0xa4bc187f, 0xc190f510, 0x7a641e43, 0x83a9e483, 0xa43fbe73, 0xcc62f02d,
- 0xcb7cc902, 0x95f7790f, 0x0bb7af3c, 0x1f10277f, 0x4e0e411c, 0xa043f7fb,
- 0x22190e9f, 0x534afea2, 0x745f5bd4, 0xe5efb3e5, 0xb97ece8a, 0x67b7a3c6,
- 0x76f512f2, 0xdfde54cf, 0x3fe6c234, 0x428421cd, 0x87930e14, 0xfc1126fe,
- 0x962f939c, 0x79f34089, 0xec02bfc4, 0x7d0ea984, 0x19c18f7f, 0x580fc68c,
- 0x16bb6964, 0xaf16dffc, 0xd25dfd80, 0x62794265, 0x0e9016c9, 0x984bd546,
- 0x1ee4dd7f, 0x719e7007, 0x7733aec5, 0xfa97f013, 0x528f1614, 0x5fdefcc0,
- 0x44ddf77f, 0xf0e2e388, 0xaeffa22b, 0x036eff03, 0x7ae8db09, 0x18244917,
- 0x4efe0097, 0xf3afbc81, 0xf0f3ea77, 0x68a4e3f3, 0xdfabe73f, 0xb3fe1d1f,
- 0xee945dd3, 0xdbb0a7df, 0x1c08e90d, 0x53dad25e, 0xe0ced6ff, 0x84857815,
- 0x6ef3b186, 0x2e7340b1, 0xeccca974, 0xd97f5dee, 0xccf6059e, 0x71d19ea4,
- 0xa0471f8c, 0xfae0197e, 0x89e259e5, 0x1f803af3, 0x79e1c787, 0x19d121d7,
- 0x0b6bde2b, 0x819eb3b7, 0xf69a5073, 0x115a9134, 0x41127df4, 0xc9b05dff,
- 0x88c53642, 0x4d94483b, 0xe39c5cfc, 0x3988fe8d, 0xe36787e0, 0xe34da22f,
- 0x9aeb78b4, 0xdb1a4a7e, 0xf3f00f17, 0xe21ce6be, 0xd82f851f, 0x2ddf0075,
- 0x82bcced6, 0x923b7c18, 0x81c66fc3, 0xbe9ed0af, 0x04d1bdac, 0x93597e7c,
- 0x969e7749, 0x3dfd7326, 0xbcc26493, 0x3ab01c66, 0x872f01b3, 0xd9c42f44,
- 0x513fda05, 0x83ce31fc, 0xfe84f08c, 0x9b7a8fc1, 0xed7846ec, 0x00165b91,
- 0x6c7cf75c, 0xed676021, 0x62cb6a56, 0x0a4ff3cd, 0xd222e79b, 0xf4d8e772,
- 0x4ef83d7f, 0x278471ea, 0x44d2bd83, 0xd2fbaf90, 0x3e3a411f, 0x408499bb,
- 0x037d831e, 0x336ce172, 0x8280fdc1, 0xd3b041e4, 0xa55fbf28, 0x692fdfb5,
- 0xec0cf6db, 0x82ed9523, 0x95cb5c1b, 0xfe02a752, 0xbc5b40b9, 0xc33b7208,
- 0xba21c6a3, 0xe1a4dcc7, 0x0964db8b, 0xc2707be1, 0xdc615b9e, 0x0214bb4f,
- 0xc5ef9afb, 0xfee40b88, 0xc859eda7, 0xebadfd07, 0xdae4d5f7, 0xc3f412a9,
- 0x1e919ae4, 0x74db3746, 0xff442bf9, 0x19afe020, 0xde25cee6, 0x96fbf818,
- 0xcb05d9d3, 0x67ffd0b7, 0x550dedf2, 0x02c5f9be, 0x2cbd1f0d, 0x23557db3,
- 0xc96392df, 0x2782c5b7, 0x78bee019, 0xc064f0ef, 0xf2c3e2eb, 0x6df258c0,
- 0xdf3b356b, 0x8fc78e7a, 0xf952b4f6, 0x7c8d23f6, 0x2df2a56b, 0x8b7ff9c6,
- 0xcf5ffaac, 0xff42df23, 0x15b7fc3d, 0xf58c5be4, 0x53f0e41e, 0xf6d8dbe5,
- 0xc6df2863, 0x71749ab6, 0xdccbcf96, 0x7cafd99f, 0x04de0613, 0xd921d4fa,
- 0x3f418f6b, 0xf6feb95b, 0x819f8f1c, 0x7dce4071, 0xdce503f5, 0xe72a173b,
- 0xace09bfe, 0x3bc5b9ca, 0xf69fc608, 0xe72643a5, 0x72a6ef16, 0x647a004e,
- 0x5ef16e72, 0x0638fcc2, 0x8faa36f9, 0xbf58237c, 0x07dacc32, 0xb91fd2da,
- 0xe997f68d, 0x5a16bd93, 0xef2a333f, 0xdde569c6, 0xbbc9fd57, 0xef261743,
- 0x47797076, 0x9030d8e5, 0xf0fa46af, 0x74e3ebb6, 0xd13f8cf7, 0x97e07bfc,
- 0x673c4557, 0xcec4dd7a, 0xfe34fe05, 0x57d03644, 0x33e6c281, 0xd7f46142,
- 0xfec41d5d, 0xd6c8bca7, 0xf160e157, 0x4cad95bb, 0x166cac3f, 0x6bfa1e42,
- 0xf0af84de, 0xaf64a8bc, 0x7e699240, 0x27d599a6, 0x24e7a94f, 0x86867a64,
- 0x96e6161e, 0xa1777fa1, 0xbfe02c44, 0x9de4732d, 0x2cb63d02, 0xcb7bf997,
- 0xc392f7f8, 0xdfc0ab9d, 0xc05eb259, 0xee353273, 0xecbf8d50, 0xbede5e73,
- 0xc681fd0c, 0x3c19f373, 0x33c6664e, 0xc631a842, 0x66d97fb9, 0xa71a7e7d,
- 0x276299e7, 0x26bc8bc2, 0xe0c5377a, 0x2f5eb51f, 0x38710e9c, 0x9fb88935,
- 0xc289c2f6, 0x17de93cd, 0xd3d3144e, 0x70a29233, 0xae957929, 0xf5ffbb37,
- 0xae3370aa, 0x9677f55b, 0x83fa7ef1, 0x3ee70a83, 0x2770e7eb, 0xd2728424,
- 0x95ab8f08, 0x16683f5e, 0xba50a7c4, 0xfc133941, 0x0d7188a3, 0xd62e9305,
- 0x8eb843dd, 0xed564fd3, 0x8c7029a4, 0x7de2133d, 0xfeaddce1, 0x6e21978e,
- 0x9e5bdc6f, 0xaf4ed84c, 0xc3f66098, 0x6b16dbf9, 0x4aa0e504, 0x87408d87,
- 0xf0f7ae14, 0xaa0cf67e, 0x61768c9a, 0x3d06e09b, 0x22b61024, 0xae14035c,
- 0x20242f70, 0x2806fc31, 0x1dff023d, 0x8305ff5c, 0x03c15ee3, 0x753c80fe,
- 0xd0bc02bf, 0x0ced59fa, 0x8090812f, 0x1126c978, 0xd657bbf4, 0xc030de0b,
- 0xe111adaf, 0xfa67caa7, 0x49e2d0e3, 0x2c52bf43, 0x9a4ac5fa, 0xd78cb2fd,
- 0xfdae619b, 0x8cf3d033, 0x88d264a7, 0x7dffa6e0, 0x279f3d1f, 0xa788c3fe,
- 0xb6bc39c7, 0x001d3c02, 0xbbd308b7, 0x3de15fc2, 0x203cb515, 0x9cf07505,
- 0xefb9e8f2, 0x1538d785, 0x20c7405e, 0x89e7dadf, 0x136c2f90, 0xbef480c8,
- 0x307385eb, 0xec97bf2d, 0x7ffac63d, 0x1892f04c, 0xba60beeb, 0x8b9e87ee,
- 0x7f82dd29, 0x36ba3fbd, 0xe151a9c2, 0xe7a726fb, 0xaf23593f, 0xef3d0164,
- 0x49cf9015, 0x3ceebc7b, 0xf4c2bf6b, 0x4a562d88, 0x91dd74f7, 0xa377b2c3,
- 0xd83cafa7, 0xf60be1ce, 0xd01ef683, 0x8810b0a5, 0xc16cdc0f, 0xc79c2f38,
- 0x6a9fa630, 0x2b56f3e5, 0x76537819, 0x7987fdff, 0x47e9fdff, 0x8c0c7e6a,
- 0x6dcd7107, 0xd151bc74, 0x83fb8cf1, 0x6f9ff76a, 0x3972af5d, 0x4baef7f7,
- 0xc687e71d, 0x074804c1, 0x878d55e2, 0xc7f82239, 0xe5cfa0c8, 0xae3e920b,
- 0xd6e5c22c, 0x1fffdc3f, 0x927fafbf, 0x4e7bc6e2, 0xefd5ba77, 0x02cfa46e,
- 0x41e7e137, 0x7d84df13, 0x3b1f53ff, 0x9136caf7, 0xff611323, 0xa0132c98,
- 0x915f4fab, 0xe9f96fd1, 0x79671654, 0x2507abfd, 0xcf5cdd70, 0xf5c8a162,
- 0xb3b404e3, 0xc7ae875e, 0x216e1e83, 0xbf0891be, 0x954fb82c, 0xc53b54d1,
- 0x733af943, 0x5206a873, 0xe24894ef, 0x936f009f, 0xeb780244, 0xe2980df0,
- 0x3f3bf9a0, 0x32e01922, 0xb601faa3, 0x06443ccf, 0xbe09bd42, 0x8cc66881,
- 0x8decfd6f, 0xc63ce91b, 0x3d7a22bf, 0x83ccdeb4, 0xfaa1070e, 0x1306a8f4,
- 0x35e06bf1, 0xc06a8481, 0x43fe346f, 0xef308ddf, 0x40efaa62, 0x7b717efc,
- 0xf20b8d63, 0x0fb6020d, 0x2e79fd04, 0xf5ad9eba, 0x0e5de49f, 0x83d68172,
- 0xac0d026e, 0xf049a05e, 0x616a4842, 0xe5053afb, 0x17809346, 0x0486b6bd,
- 0x86fd6162, 0xaddfb42c, 0x367db40d, 0x3db45fec, 0xc9f4dbf4, 0xdc82371b,
- 0xf6c4f3a1, 0xb63ceccd, 0x00f3b690, 0x81dd34bf, 0x083495fd, 0x1419ee04,
- 0xa97db337, 0x0bd915f8, 0xd7fbade5, 0x9d3b7ee3, 0x0e9a978e, 0x2a7850fb,
- 0x12c8d7de, 0x6d8f78dc, 0x5fc450fa, 0x23f8610f, 0x1c984389, 0xdb9e7813,
- 0xf7deaa3d, 0xe430f32b, 0x32ef4283, 0xe7ed0065, 0xd303b94f, 0x9f57484d,
- 0x7da7a028, 0xa7ede148, 0xc79d7ef0, 0xfdcc1c29, 0xecd4e940, 0xe1e6cd8b,
- 0xdb617ed8, 0x5a7f8c24, 0xfcf00a44, 0xa678c67e, 0xa576be6f, 0xbafe0435,
- 0x10c8e4d7, 0x4af07ef8, 0xdeef7e33, 0xf770e4ca, 0xcff44ed0, 0x0990689e,
- 0x69a82fdc, 0x9c5e5110, 0xbcf19668, 0x464c7c5a, 0x95b45db9, 0x1b071fe9,
- 0x4027bf58, 0x393f036f, 0xd17cd394, 0xfbdb8116, 0xf6ab4e4c, 0x9d9ba167,
- 0xb772abbb, 0xcfbbaf82, 0x4cb7543e, 0xca359201, 0x8f2e0adb, 0x02a4a94b,
- 0xddca3342, 0x7577380a, 0xe31a5f01, 0x3b511c83, 0xfc20e806, 0xe575d215,
- 0x3b01322b, 0x2ba0f846, 0x6a7de60f, 0xee7e80af, 0x0f82edf1, 0xdf8bbdce,
- 0xff508732, 0xfb9bcd0e, 0xde5fd80b, 0x55081336, 0xa0780e3d, 0x1cd72a72,
- 0xe86fcbf9, 0x5baf53f7, 0xd2841220, 0xbb843ccd, 0xbd99df1a, 0x6471c589,
- 0x04975ebf, 0xd4c92cf7, 0x8a072801, 0xd7e245ea, 0x825389c8, 0xb29fc6ef,
- 0x8dadc1fd, 0x6a56cce3, 0x3d7f610b, 0xd1f2666a, 0xd88649b3, 0xccd2b208,
- 0x0fb534e4, 0x64b2fe30, 0x4524baf7, 0x7b250743, 0xf48925d7, 0x071e2afb,
- 0x2bfb0351, 0xb0a2576d, 0x09f64a71, 0x38cd46ee, 0xbf6a3f6a, 0x6ed66eca,
- 0xf6965ef8, 0xcc097fd7, 0xb9f9d70f, 0xd8c2f202, 0xfbf19f4f, 0x3ff727e9,
- 0x7409d5cf, 0x89afb95e, 0xfb9ca418, 0xdae1f4c1, 0x55350073, 0xde7215e3,
- 0x069f1130, 0xb17fb97e, 0xdf069f11, 0xdf28e3ad, 0xd75dfc53, 0x02ac8426,
- 0x15298fe4, 0x037798d9, 0xff72579f, 0x7654e573, 0xf19ad3be, 0xfbe00afa,
- 0xd202d9e9, 0x95fa0903, 0xafa88901, 0xb8ce2079, 0x2fb59b28, 0x1f81eda2,
- 0xfe33d75b, 0x03c272a4, 0x61b2a472, 0x6fd61e5d, 0x7fd03c12, 0xd43ce36b,
- 0x45738a47, 0xc74de582, 0x6e2a3f50, 0x7c08963b, 0x0eb6f94c, 0x89ca81f4,
- 0x71c83766, 0xfe551f95, 0x05c78d7e, 0x0c7b8b13, 0x0067e3c4, 0xcbec0df3,
- 0x4c2be2d7, 0x199a07ae, 0x1972063f, 0x55b6bebf, 0x085e1586, 0x9f3f237f,
- 0x55f8ccd8, 0x3ce6ec7c, 0xb45ca7b8, 0x1ca7c589, 0x80a2986c, 0x24227d3e,
- 0x97d37ee0, 0x6ade99bf, 0x811aefe4, 0x543f7bed, 0x5bf954bf, 0x73fa63e5,
- 0x4e578c1d, 0xb5ee14f9, 0x867af919, 0x3be7f2dc, 0x7faf7ce9, 0xce87ae96,
- 0xef8fca77, 0xe46a7576, 0x4127cd24, 0x716250be, 0xa95caa3c, 0xd7bc5890,
- 0x619f9e0f, 0x7acd1bfc, 0x734ac8ff, 0x6e6b8b3c, 0xcfee9192, 0xf87d9fc7,
- 0xf3f902ec, 0x7ceaf942, 0x2f8ea9fc, 0xb3f7d5ee, 0xb19bd392, 0xd70a6ebf,
- 0x1feb8530, 0xb8c09f9a, 0x3e9f8fb1, 0x53f00336, 0x39d287b6, 0x93b357d0,
- 0x49ce4184, 0x4aafdc21, 0xc61f455b, 0x9ce14abf, 0x3e5a9d1b, 0x653e7166,
- 0x9e9139cf, 0x439bb74a, 0xd2fb69d3, 0xc58c1f9d, 0x11e58bb8, 0x3e0a438c,
- 0x60e5f5cd, 0x83e058e7, 0x1bc58952, 0x00c2e519, 0xe8673b0b, 0x059f6dda,
- 0xb33613eb, 0x2da5fd7b, 0xcd66c8b7, 0x22cd84b9, 0x1cf0f5ab, 0x18e94830,
- 0xfcc255ee, 0xd5c9f7b4, 0x2daea338, 0xb6944e4c, 0x960768c9, 0x0dd6de6e,
- 0x6fa5a371, 0x15dfd199, 0xc609fcd8, 0x6e794fc1, 0x0253fa2b, 0xfceea26d,
- 0xdebc4fac, 0x866c3166, 0x0ad6b378, 0xf9a3ef3c, 0x896f9863, 0xbe7ab71d,
- 0xe7b2b2b8, 0x520ceef6, 0xfefd9610, 0x97c81729, 0x5c9b1dd3, 0xf9b7b718,
- 0xfb65e3fb, 0xdcb5e7c4, 0x79f1bdf7, 0xca17e1a7, 0x862d1338, 0x03cdc6f8,
- 0xf3a48f50, 0x718829cb, 0x97abd1ce, 0x037cfd6f, 0x6d778fc4, 0xe601b33f,
- 0xa7edfe5b, 0x887e201b, 0x7ee2b3ec, 0x08fa7817, 0xedaadfc6, 0x7ee1627e,
- 0x614f2d8f, 0xdbf772dc, 0xd6f42f66, 0x1a44f7bd, 0x6f758fc4, 0xfc092afb,
- 0x4ef64b96, 0x92eebf43, 0x4992531d, 0x4d42fd8c, 0x17436e81, 0xc46d3710,
- 0x83d6c1d7, 0x31f4e718, 0xbfc837c5, 0x96cb78de, 0xeabf160a, 0xcd9671e1,
- 0xfbd3e3b1, 0xdeb655c4, 0x2095fd78, 0xfe995bf7, 0xcaf8de78, 0x7f1e2837,
- 0x6bf80174, 0xb102fd56, 0xfc31f7f1, 0x76e21e32, 0xbcfbf8f5, 0x8fe3d175,
- 0x80eb5942, 0xc32be37e, 0x35370017, 0xc5927dfe, 0xbe016d57, 0xc60cfed9,
- 0xa6de02b3, 0xf9ff607b, 0x0dee0d3c, 0x7323949c, 0x5ed93ef0, 0x09e21bb3,
- 0x89bef74b, 0xe3bdd3fc, 0x1343f475, 0x4dde871e, 0xdc587f7a, 0xd9d7c0b0,
- 0x997164e4, 0xb710fe1c, 0x77e171e9, 0xe8c99f1e, 0xecdb8d58, 0xa7735e2f,
- 0x6ad9e985, 0xd3457e5c, 0x31fe3cbb, 0x17212f8a, 0x7bec74f0, 0x70a811ef,
- 0x1c397370, 0x1d8e3f8d, 0xa71bdb17, 0xf805f1ce, 0x37a87d83, 0x87e698be,
- 0xe8dfa264, 0x1e43124d, 0xb8b23774, 0x7f596ee5, 0x1f8a33df, 0xcdbc8f16,
- 0x0ba1a7c8, 0xdf3e438b, 0x7c287ffc, 0x33f28236, 0xba9c2fb0, 0xc72d8ebe,
- 0xff7ce0df, 0x5967df77, 0xb3ef1828, 0x63d027fc, 0x0531eb45, 0x3b5ee0ec,
- 0x8bb7af9b, 0x9ebbd5fb, 0x759e3116, 0x9441cb55, 0x517946e3, 0xc458ef09,
- 0x0b71ef98, 0xd8dbc3d7, 0xddb5d13e, 0x7ed07219, 0x46ec0eba, 0x3e6cae7a,
- 0xe09c40a6, 0xaf7f9bcb, 0xc629f3b0, 0x844fb03f, 0x7aeff334, 0x1658ff76,
- 0xf8fccd6f, 0xe33e71c6, 0x63da04e3, 0xfe68138f, 0x594e3744, 0x3b7145b0,
- 0x69de3fce, 0xf40b77c9, 0xe983ba77, 0xc45ba783, 0xb9f758fc, 0x66fbe4de,
- 0x743d7bef, 0x4177c4bf, 0x101dec9c, 0xfd4365d1, 0xf7338972, 0x4844b8ad,
- 0xa9ef8c15, 0x81e3c659, 0x014de97e, 0xaf38d77c, 0x95df3025, 0x9f8d5f00,
- 0x09fb7647, 0x4a72a5e8, 0x15f83641, 0x4946f28c, 0x06909134, 0xf99c4bff,
- 0xef3c1ec9, 0x7c010f08, 0x2138cd1e, 0x19efbf43, 0x49ef54fc, 0x9d325564,
- 0xc1417bdf, 0x4bf68cbb, 0x6860febe, 0xff6fb381, 0xaf7fde6a, 0x552bf3a8,
- 0xc147239a, 0x582f212e, 0xdc41be31, 0x17f7c567, 0xb8ac1b02, 0xbe3b83de,
- 0xebf5127c, 0x9d84cdc7, 0x85eb50fb, 0x9b915fd2, 0xc76271f5, 0x06fe1b97,
- 0xa63433fa, 0xa06d17e3, 0x686ec1f5, 0xd39da3b6, 0x2c6e3db3, 0x5e8a45f8,
- 0xc80667b8, 0xa33b22b3, 0x92e7a2c7, 0xbfb43543, 0xfe5903e3, 0x78a1d6f8,
- 0xbb6cbfdf, 0x0f0ce313, 0x0955d8ee, 0x73f752fb, 0x52fb0276, 0xcf5c0bf7,
- 0x1fbf867f, 0xb47b2f54, 0x4425c6f1, 0x71ef68f2, 0x959e4194, 0xfc107de3,
- 0x047ce1c9, 0x38b6aafe, 0xf541ffbc, 0x1f3f5d5f, 0xbcbb91cb, 0x41c1c748,
- 0x784bdeec, 0x6303c810, 0x4afcb53d, 0x8f7e30eb, 0x4473b698, 0x489407eb,
- 0x0ed7cb21, 0x03a4f262, 0x656b5feb, 0xf796affc, 0xcfd597ed, 0xd5d30eb7,
- 0xf257db53, 0xf48c41f7, 0xe055b37b, 0x2e6fc1fe, 0x45fef589, 0xf7e3f98c,
- 0x6824099f, 0x9b653d02, 0x8225df15, 0xdf10f37b, 0xe76153be, 0x30aee55a,
- 0x87b23fbe, 0x5b72e3cb, 0x1943df18, 0xf501e7c4, 0x9d2c4f21, 0x56bbe2cf,
- 0xde04acbb, 0xc178a9c7, 0x577c03e9, 0xf8f2fcec, 0x8e21b2ef, 0xd4718ecd,
- 0x1cfc2f15, 0x1cc2a0e9, 0x10fc039e, 0x1b2666d9, 0x1db7cf81, 0xed7e034e,
- 0x0969c392, 0x575e73df, 0xbc3662d1, 0x71d6c01f, 0x0afebaba, 0xdeace7b8,
- 0x47ed2ca7, 0x656b3cce, 0x585fe87e, 0x78ad4b7d, 0x677fadae, 0xacf574e7,
- 0xaf57b82c, 0xc4b52fd6, 0xad6b8b96, 0x4f763ff2, 0x5ee7d1d8, 0x40eb5ae2,
- 0x923a63d0, 0x4953efc0, 0xe7906ef5, 0x87d39ba5, 0x80e09f80, 0xee77bd55,
- 0xe8fd8389, 0x7b41ec80, 0x3eed521a, 0x9bdab273, 0xff008d25, 0x892ca8cd,
- 0xf1a7a3ae, 0x0441c293, 0xb3ad0ee2, 0x0dbdc962, 0xa3c23b56, 0xc5f662d4,
- 0x0cf8d7ba, 0xc107d7a7, 0xc6c71fe8, 0xc750fe03, 0x5087203d, 0x79b70f0e,
- 0x2ed43f58, 0x9b65ef82, 0xdee96767, 0xb16a90c5, 0x8453e51e, 0x53a90967,
- 0x5bf235b2, 0x6964af1d, 0x05949676, 0xeaffa5df, 0x8a3157a5, 0x444c1267,
- 0x30e250bd, 0xbaa97526, 0x5c9204fb, 0x29f80160, 0x892dc0a4, 0xc8b52a40,
- 0x82d236ef, 0x5baa83a9, 0x2aa8fdec, 0x64f27202, 0x0417bbef, 0xeebc28d3,
- 0x1c1fb946, 0xe9c5c84a, 0x13dfff70, 0xafc0d6e7, 0xf9c2eacd, 0xc22aa598,
- 0x3774c5e4, 0xd04223e8, 0xf4a3be4f, 0x9f9d5354, 0x7f48f405, 0x0cff707c,
- 0x3f3a0f4d, 0xafe5fb97, 0x74a20f40, 0xfb59deca, 0x50d50931, 0x28f84310,
- 0x132755fa, 0x9ad83ef6, 0xded688b7, 0x6fe72bf8, 0x728fdc12, 0x3fa241cc,
- 0xb1079a11, 0x26b6f20a, 0x385cdbee, 0x49b87447, 0xbb42f418, 0x34ed8483,
- 0x4e968c75, 0x95dff96b, 0x3a1af34d, 0x97d44f75, 0xca82f91b, 0x2db8c335,
- 0xefda3f08, 0x3f7e8667, 0xd9fbf433, 0xc2abf5f7, 0xe8d96029, 0x5609f785,
- 0xb8701756, 0x1c2cf1b1, 0xa33e146e, 0x62337de0, 0x79f979b2, 0xc6d5c238,
- 0xfa866367, 0x6c83af14, 0x07a708e9, 0x2045f6e2, 0xd624966e, 0x577bb013,
- 0xa69f6c08, 0x4d0e053f, 0x20b6e23b, 0xc7c7de1f, 0xf4636419, 0xef5bdeae,
- 0xe78adf5b, 0x5bea7d1a, 0x8b6fabfb, 0xdfd9df5d, 0xe731ec7c, 0x4ce543f3,
- 0xfe6f0be5, 0x7b61ce09, 0x829b8de5, 0x6f274732, 0x9c28d906, 0x7f8fe22a,
- 0x985f89db, 0xa21968de, 0xe80d9fc7, 0x6d8fd295, 0x11bbfe84, 0xcbd1fdef,
- 0x9a0ebe3c, 0x75d2a477, 0x3f8f94fd, 0x639d89b5, 0xf984b6df, 0xe7b9a8dd,
- 0xf2b7fa83, 0x14b53ffa, 0x18e0ffa1, 0xb6e9177f, 0xde17a67a, 0xe788af76,
- 0xfdde7dcd, 0xff285f81, 0x0854bedc, 0xbd63d385, 0xe09a4463, 0x3e5cd47e,
- 0x205df1be, 0xade4f13f, 0x0bbd6311, 0xbd4ce8c4, 0x6f7c6557, 0xe0292160,
- 0xbfe93def, 0x91bab26f, 0xd61e410e, 0x4bee8e8e, 0x8e9475c1, 0x74a49f41,
- 0x70ece70c, 0x3ce3063d, 0xf38b0a5c, 0xe78a18e8, 0x3b3caa63, 0xe1c4f1eb,
- 0xd34deafe, 0x78b817bd, 0x5e3927bc, 0x73a5af23, 0x2b7bdd36, 0x0537b235,
- 0xee7c95e4, 0xa6a1e232, 0x1e8d42af, 0xea9ca68f, 0x10ccc8a1, 0x277284a6,
- 0x9c810a45, 0xa405dc93, 0x9958f408, 0x5f5aa7d1, 0x57acbc49, 0xfe8d7c6f,
- 0x878801bb, 0x3be2e5d2, 0xd728c93c, 0xe00b05ed, 0xf5cae893, 0xe97d1dfa,
- 0xad95b821, 0x9dd606bb, 0x353d77de, 0xfa8bd78a, 0xf7de84f3, 0x3f302c69,
- 0xd379ecd1, 0x0ffbf303, 0xa51f8099, 0x27bc7c2f, 0x677e1443, 0xde318343,
- 0x3e9b8c43, 0xdf57c612, 0x9d535c45, 0x2bade782, 0x2b897bf8, 0xfe6147aa,
- 0xe59efe7e, 0xa60f6aaa, 0xde2cfc2a, 0xcfc77c5a, 0x6ff58232, 0x24fc7371,
- 0xfc7c389a, 0x52592fa8, 0xd01cf0aa, 0xc30aaeea, 0x086459fb, 0xda6027dd,
- 0x9f845aee, 0x87e826e2, 0x6f31f5a4, 0xe54d3c86, 0x0f88d1fa, 0x8a455dc9,
- 0xddbe7968, 0xcdc020ff, 0x7ba419ea, 0x329cd01f, 0x03df7bec, 0xf5a7a5ec,
- 0x72262e4c, 0x27c2327a, 0x65ef6151, 0x9fd474aa, 0xe3c3555e, 0xf6ae1f74,
- 0xdfc35a62, 0x7781aa81, 0x3d48147f, 0xedc81f98, 0x470a1ac4, 0xdf08fef8,
- 0x73aa6b37, 0x972cfcb1, 0xaaa68957, 0x25c032fd, 0x66ff3081, 0xc90c9062,
- 0x14042c21, 0xc482527e, 0x9cf57903, 0xe6c69dd0, 0x7441e9cd, 0xdc77864b,
- 0x5e008f3c, 0x26cb0eea, 0x4b8b93f0, 0x681f25af, 0xe59c59e8, 0x99bf078b,
- 0xb00bf0e8, 0x78003dff, 0x4759f3a5, 0x96ef85e7, 0xc9587a72, 0xd39abef1,
- 0x1f407dc3, 0xd3907d34, 0xfae8afc5, 0x65e35f21, 0xe6d601f7, 0xc4b778b3,
- 0xc77f130c, 0xf1b44c2c, 0x16def164, 0x2275d0a2, 0xc5307a8f, 0x5bc8ea77,
- 0xfb17a466, 0xa113e268, 0x43bbadfc, 0x82c91dec, 0xe337d854, 0x272377d5,
- 0xe367e27a, 0xc4b0d545, 0x991373df, 0xf311d1dd, 0xef1ac67d, 0xefd80b01,
- 0xeec7cdfd, 0xa4afa5f5, 0xd9ebd9e3, 0xfe01c5bd, 0x688bd982, 0xf54f51de,
- 0x8ce5026f, 0xde741d2e, 0xc67d1a45, 0xbffd8fde, 0x51cd7ed4, 0x7be7c51b,
- 0xe45141b0, 0xb87ebaff, 0x614be015, 0xc73f01ed, 0x2a4172c3, 0xf1c3fff0,
- 0x8735fdb1, 0x83d2326d, 0x1d32fb2b, 0x3ec9d73d, 0x989ee76c, 0x3afba3a9,
- 0xa612772e, 0x577dd04e, 0x6defcce5, 0xb12eef4c, 0xbcc2cffb, 0xc5d1ce92,
- 0xbc4a7e51, 0xa9dcb621, 0xdc209591, 0xc319afdf, 0xa6705ce4, 0x3eabf4c2,
- 0xa7c98472, 0x6f32e4b3, 0x645f4350, 0xf03d4114, 0xee8a998b, 0xc035c1dd,
- 0x7e5e941f, 0x057ee9cd, 0xc54d01f0, 0x4dd20a11, 0xda1374c2, 0x5f38aba9,
- 0x68f9cfdd, 0x87a3e72d, 0xc2467f80, 0xdf8cae3b, 0x051de224, 0x8b8d48fb,
- 0xc0258fbd, 0x8d49b4ff, 0xe85cfe6d, 0xb32de6af, 0x350fe700, 0x11752f92,
- 0x977e29e4, 0xef8f307b, 0xedeb06ea, 0xbbf1589e, 0x9293ed4b, 0xc95e14ec,
- 0xdfbf8676, 0xfe2167d4, 0x316f6e2c, 0xd8724bac, 0x19afaed0, 0x658e2969,
- 0xbdecd81f, 0x53b74ef0, 0x9fc80f78, 0x817f6bd0, 0x666ea17b, 0x37fdc20e,
- 0x06399f70, 0x33b18cfd, 0x04864079, 0xff0d08c9, 0xdcf7f1d7, 0x46482788,
- 0xf2c0e469, 0xf808f38b, 0x7ff2fa77, 0x136ff23f, 0x02357f93, 0x780c57df,
- 0x5531f755, 0xd78049fe, 0xb9e77d01, 0xdd5ca2f2, 0xcb997b3d, 0x3cbd636f,
- 0x4f9d9dbb, 0x2fc46f11, 0x70a72df4, 0xce6bb3ca, 0x09c49495, 0x5d95efbd,
- 0x461d6315, 0xf61277b9, 0x9225903f, 0x5905df1f, 0x191e78a8, 0x8fe4f20f,
- 0x3fa5fe2c, 0xaf1d40fd, 0xee315ce8, 0x72e785f3, 0xae299f71, 0x20fe45cf,
- 0xd8d78de0, 0x7e1a2749, 0x9dbc02e6, 0xa3e7e7a8, 0xe208720d, 0xbc6ff652,
- 0x14d9a1e7, 0x88370b9e, 0xd7fefeec, 0x6a277ddf, 0xb6481be2, 0xf53af507,
- 0xa113b43d, 0x73da5d3b, 0x58dfc2ec, 0xf62fa07d, 0x3614cfb7, 0x6bdfb6c4,
- 0x53d057e0, 0x1e801f29, 0x4881f54a, 0x5f85f418, 0x08bdf15b, 0x68dc1f35,
- 0x540ef98f, 0x195a7dbe, 0xddbe67d0, 0xc4a42777, 0xfafe8091, 0x8ea1e6fe,
- 0xa67c1c7b, 0x28f64e70, 0x70a5b38f, 0x9ff3a99f, 0xe3b273b1, 0x2c421fdc,
- 0x78db94fd, 0x729fa7b9, 0x21678b17, 0xeae5d8ee, 0x3b714e7c, 0x7b46e170,
- 0xfd8c7968, 0xefbf217c, 0x479f90b7, 0xd53ff8a8, 0xba3137ab, 0x3f2ffb51,
- 0xdfe18a37, 0x53c26740, 0x3eae9063, 0x7fa3243d, 0x4aea784d, 0xf2a52f7c,
- 0x97eb059c, 0x415fde8b, 0x4d79161c, 0xf3bbba44, 0x873c38f0, 0xc3bc32ea,
- 0xb7f387b8, 0x2b9e169a, 0x8599e9d5, 0xec0a05a1, 0x2ae785cb, 0xde211e91,
- 0x1397ee11, 0x934bf6f2, 0x13574e24, 0x6991fda0, 0xa2bd69cb, 0x64bf464e,
- 0xfd12b062, 0xef768d84, 0xdae431fd, 0xe747bb1e, 0x2cea2837, 0x2389fec7,
- 0xe7351248, 0x7bf90bf5, 0xd8e745e1, 0x1dc4847b, 0xcf402924, 0xe944de5c,
- 0x6c6eff52, 0xcbe18997, 0xf857deb8, 0x5de95f3a, 0xd67e84ef, 0x5eb663fb,
- 0x7517cfbe, 0xf5d61ae6, 0xd6b1f1bb, 0x44cf5d15, 0xdfce5f6c, 0x31372df9,
- 0x9fe5abbc, 0xf4d5f1f3, 0xb82cf578, 0xf84a4361, 0xa185903b, 0xff78153b,
- 0x3e21b0a8, 0xb3acd041, 0x5d56fea8, 0xfd61495c, 0xaaff7c3c, 0x329e61a8,
- 0x7a47235f, 0xecfc14f1, 0xa22349a5, 0x81fcfa78, 0x1dcb699e, 0x1c14afb0,
- 0xfe3b3e03, 0xe79cc564, 0xf0cbf409, 0x8e095276, 0x72b942ad, 0x3dd62ba7,
- 0x788dcf94, 0x1b78e7ab, 0x35a32411, 0x97c54672, 0x4df1fdb1, 0xf9c17765,
- 0xecf5f1f4, 0xe5fe8f75, 0x1a7c6c4c, 0x3076e8e1, 0x71e9a9f8, 0x2ffb2fba,
- 0xeb978e08, 0x85fa9be2, 0x0abfc723, 0xd53bf527, 0x1c0eacab, 0xa37bb097,
- 0x0417b9f5, 0x8cf8e8bf, 0xbe2a4e3e, 0x7e41eb91, 0x7c093951, 0x07c9ea7a,
- 0xe5db6ac6, 0x840d27db, 0x85ed4871, 0x6fdd8f9d, 0xfd41a7f7, 0x21ef64e0,
- 0xd15bca0f, 0x5dd7435b, 0x7768f712, 0xdfab5718, 0x935656bf, 0x4a5fc12b,
- 0xc12b87ed, 0x05b5436f, 0xe6a8a3d4, 0x847d05e0, 0x7ac5f156, 0x83926a17,
- 0x5656b3f9, 0x95bfa157, 0x0dc48258, 0xf8c23d7e, 0x42cc9c92, 0xd0e497ff,
- 0xec8a01eb, 0x4dbf8377, 0x6591f7e1, 0x3d26bfc9, 0xc4d9ec1b, 0xbe06a08c,
- 0xbc583957, 0xc594dac4, 0xb7438841, 0x38719f80, 0xeace37fa, 0xa517fbec,
- 0xdd280385, 0xda7dcfa9, 0xe5cbe846, 0xfe8216c4, 0xbbf4d1b4, 0x74891e76,
- 0x4c7dbade, 0xe2c9170f, 0x890f73c2, 0x8715bf70, 0x7282fd07, 0xc3973578,
- 0xdc2eedcb, 0x645d567f, 0x8ea0fb42, 0x0b7ec3fb, 0x8b84307e, 0x84327684,
- 0x257d40dd, 0xb0eb882e, 0xd0447ac2, 0x7798c3db, 0x22328bc2, 0x4025b13e,
- 0x04789e3e, 0xe1200fc8, 0xf687a055, 0x0bbcea4c, 0xfd58a7be, 0x5fbf01b3,
- 0x151c76a4, 0xe05a0fc0, 0x5ce004bf, 0x3c33062f, 0x62e3feb4, 0xa5ea0324,
- 0x12b7a2d1, 0xc4117a58, 0xe735fb41, 0xce1dec2b, 0x9bec5e68, 0x64a968bf,
- 0xfaf86f38, 0x2ff96d12, 0x0762beac, 0xf656fbec, 0x07e24d7e, 0x9ab9ca02,
- 0x01773f5e, 0x71a9dbde, 0xd23d7f30, 0x21d5d005, 0x959f4fb6, 0xe809713c,
- 0xf5951b3f, 0x5e1e6ea2, 0x76e25e5d, 0x53a5134d, 0xf4ab8bf0, 0x99f24231,
- 0xae2e8e80, 0x78b5dfa5, 0xc15fa18c, 0x39fa2338, 0x47e7504f, 0x157a45c7,
- 0xfdb0e5cf, 0x7b0f40d6, 0xa0ff3604, 0x0fecced5, 0xaf011412, 0x93c255b3,
- 0x3c7cb056, 0xddf07f51, 0x3f55b7cf, 0xf2c15937, 0xcc0b966e, 0xc66ae767,
- 0x5f6eccf9, 0xe5fe01dd, 0x0ba9edd9, 0xb6659ce0, 0x208ff2e5, 0x0e4723dd,
- 0xfc4e41d8, 0xf9a3bd8c, 0xca2f23d3, 0xbc778a20, 0x43ef11b1, 0x71f9ce3f,
- 0x80c8890e, 0x2b713f7f, 0xc21e4fcc, 0x5e27cdf5, 0xc1916f9e, 0x1c2dbd7e,
- 0x9a3af9ba, 0xd0c5fdbb, 0xcd5a6075, 0x09791439, 0x716fe6d0, 0x5a2fa1e7,
- 0x7de6d76d, 0xbb59e599, 0xdff81c28, 0xb82c90c1, 0x2dbae8ae, 0x9d750708,
- 0xa3e226b4, 0xfdfc4e17, 0xbd2e1520, 0x7adfb6eb, 0xfb0bf82d, 0x2db36f93,
- 0x71623e63, 0x465e6cb9, 0x45067d38, 0xc3915ef0, 0xf2e807b7, 0x1daf8761,
- 0x12dca4f8, 0x21869349, 0x5f2184df, 0x4a2ffa29, 0x78f870a2, 0x8192ffa8,
- 0x018e8f00, 0xbe67a417, 0xd5fce9ca, 0x83f7def4, 0xbe99d113, 0x66c1f986,
- 0xb55b7a70, 0x9b8c4de3, 0x7b30f8fc, 0xf442a90f, 0xfa0f7f5c, 0x4b1244bf,
- 0x57d355ef, 0x2de61fb9, 0x9d1f7a87, 0xc48673ad, 0xd5a33de0, 0x667af78e,
- 0xfd3a8b64, 0xc0b6467b, 0xc63ad7e3, 0x4bd3a4de, 0xeeba7057, 0x11c40fdb,
- 0xb059fb18, 0x55da3274, 0x24f7153b, 0x0dc1ff90, 0x4c16ce8c, 0x671089f5,
- 0x808d613c, 0x1ff188fe, 0x87901276, 0x09e2ea0b, 0xb82f839c, 0xbc16717b,
- 0xe1d95097, 0x3904eb69, 0xe0bc1219, 0xef164b47, 0x9d25f8c8, 0xd807c3d7,
- 0x3bf90c3e, 0x9f0e9e60, 0x2bf1a1c7, 0x1955c977, 0xdbeba06e, 0x0b903e1d,
- 0xbdf26ef3, 0x922d780d, 0x76b5fbc2, 0x3cdbbcc8, 0xf31f40b9, 0x4c3eac5a,
- 0x51b2442d, 0x224f36b9, 0x15934816, 0xdf215922, 0xece7d4fe, 0x3bad86b0,
- 0xec2c46d9, 0x80afe1fb, 0xacdf2e4e, 0xa63dd6e8, 0x51ff9f45, 0x119f3e9b,
- 0x0eb3e7d6, 0x80b7f3e9, 0x87d1a31a, 0xe765ec0e, 0xd86765dc, 0x05e7c13d,
- 0x7fc083d8, 0x37b9466a, 0x073daca5, 0x3ccf4dce, 0xf94134eb, 0xfd986f9e,
- 0xc562d916, 0xbff6cbf7, 0x44b62363, 0xbad4c778, 0xd8cfca11, 0xffc0725a,
- 0xfc63eb44, 0x4735dd03, 0xf3b1fd82, 0x0cced532, 0xcec49c61, 0x7b9c596f,
- 0x04398b64, 0x7667b1e7, 0xd02cf53f, 0x832d99dd, 0x5e79ef51, 0xdfa09a08,
- 0xaf0c7de0, 0x9d2e6c13, 0xacdb29fc, 0x3846ebb7, 0x73d53e99, 0xf10b994a,
- 0xebd4974f, 0x48697dd7, 0x64ed1f9f, 0xd13e67f2, 0x73874f7c, 0x14aacf66,
- 0x48278ba0, 0x5983fbcc, 0x9f7f264e, 0xed515a7e, 0x33bf916c, 0xd1493c46,
- 0xa27b4f7b, 0x064b3fe7, 0xc0001c43, 0x7bf45862, 0xb55c6199, 0x7cb96fff,
- 0xfa7ee44f, 0xc222abc8, 0xb17574e7, 0x57b89cee, 0xa6f6ad3f, 0x33ecd54c,
- 0x93fbf585, 0xb85ea1e6, 0xd6be693f, 0x3072db2e, 0x738856e9, 0xdfe12cd9,
- 0xfd9f2a4f, 0x121343e4, 0x02d8bbe1, 0x1f7285f3, 0x2f2d1fd8, 0xd51ea0b9,
- 0x71b5333f, 0xe3f54523, 0xf66aa652, 0x974a1fd7, 0xbb4aefbd, 0xe5767c19,
- 0x1d78dc16, 0x835977c5, 0x656a85e8, 0xfbff372d, 0x837b8018, 0xcb5cf78c,
- 0xbef8c9b7, 0x0af1a079, 0x359413f4, 0xef879ebf, 0xe79fade8, 0x48e57985,
- 0x44cc40a4, 0x904dc0d7, 0x81df6c9e, 0xfd95d5ef, 0x3c914eb5, 0x7d3d5f30,
- 0x3f437a50, 0x7280d517, 0xf01e006e, 0x54f8c32d, 0xae11bbf5, 0x7b7d2125,
- 0x17febe23, 0x33fa37a7, 0x63778b4a, 0x83d301bd, 0xca4877f8, 0xa3b95297,
- 0x3fca2fb1, 0x38f8c5ac, 0x542838e3, 0xb0d0e735, 0x1f90797f, 0x271f7cad,
- 0xc7872582, 0x79670e8f, 0xe80f377c, 0x197fd60b, 0xfb81ea99, 0x7c90378d,
- 0xc2179f48, 0xe322890f, 0x6c3bf46b, 0x775f23b5, 0xfc9f3bb9, 0xf343d01d,
- 0x18c73c18, 0x767befc4, 0xdef8c279, 0x0ff7faa0, 0x5f2cdcba, 0xf8c56eda,
- 0x2b1f338a, 0x4196cf28, 0x7fd4175c, 0xd1326ad6, 0xb6cce67d, 0x4e219301,
- 0xbd85abb0, 0x65ba7b2f, 0x7be564c0, 0xff2347f6, 0x31d6fbaa, 0x6fee95f8,
- 0x1b7d384f, 0x15df009c, 0x79328e2c, 0x55465540, 0xeda93c0c, 0x0caa9512,
- 0xb7221fb0, 0x991bbc3b, 0x720e93be, 0x053facff, 0xdc79f9ed, 0xae37b17f,
- 0xd7e819e0, 0xe8faeb49, 0xe24384bf, 0x0fafa046, 0xee5def44, 0xb5f3d1e1,
- 0xbc7ed985, 0x30564a4f, 0x4481663b, 0x4fd512c2, 0x1fbc8017, 0x8394798b,
- 0x8c041a0b, 0x56b85a2b, 0xef781ebf, 0x0377fb54, 0x5e2fe18a, 0x9138870d,
- 0x1b8b4c16, 0xb025e5f4, 0xfe30b87f, 0x4bcfcf03, 0x70e5f49b, 0xbdf41093,
- 0xccefe6f2, 0x39f6e0b1, 0x7be7d751, 0x1f93a9c9, 0x8f8fca32, 0x5f5c02c4,
- 0x909b5819, 0x702afdf2, 0x42ca6e77, 0xa59ee20a, 0x66165213, 0x04183be1,
- 0x1645a7f6, 0xb2657412, 0x8003bc3c, 0xc9fc83ac, 0xf5825bde, 0x9487ef69,
- 0xa1e1254d, 0x613ae8ae, 0xf272da7d, 0x5963c306, 0xe31e10bb, 0x8237de8a,
- 0x95eb6a75, 0x3797f5f3, 0x837e759b, 0x84f3880a, 0xefd69538, 0x797ebacc,
- 0x37dd1cfc, 0xe7e29589, 0x1bb95ee1, 0xfc5634ba, 0xa70e51f9, 0x4c2e6f87,
- 0x15fcbe05, 0x388381e8, 0x3da97320, 0x0271c20a, 0x8e85b803, 0xcdeacb63,
- 0x72ce7963, 0xf9d4ff96, 0x10fd5e55, 0x7ec9376a, 0x2058573c, 0xf70cbc16,
- 0xfdba669a, 0x17fc025f, 0x12697c98, 0x246fa7f2, 0x652e47c6, 0xb3247feb,
- 0x18aad2ea, 0xc78aa9f6, 0x782d0adf, 0xcddc17be, 0x76673df6, 0x3bfad644,
- 0xee4c5de3, 0xc4e81dc4, 0x0ec8fe78, 0xae11ef01, 0x3de18e17, 0x78d7f5bb,
- 0x29cfd808, 0x17206f14, 0x05640bd7, 0xdd9563bc, 0x978ef33a, 0x36d97f00,
- 0x5a2a77d4, 0x0e158927, 0x77d33f5c, 0x708d55ec, 0x773c98ce, 0x33d02654,
- 0x1bdcf75d, 0x83cbbbe0, 0x183aa5e3, 0x0f2ca41d, 0x0d1e2fa6, 0xf1dc17e3,
- 0x18dbf012, 0x4d3fde1b, 0x2672b0a6, 0xf406ba60, 0xb1921497, 0xca77e41f,
- 0xf8264f74, 0xb1761f5a, 0xc49a0671, 0xcf4133b9, 0x84f964ca, 0x46df057b,
- 0xb875ae24, 0xc93364fe, 0x77c2f987, 0x602d13d0, 0x887963cf, 0x554a79e1,
- 0x3c9f8c06, 0x4a89a59c, 0x5e82e318, 0xcedef151, 0xb89673e2, 0x25e3ca09,
- 0x4e4a4d5f, 0xe95feda0, 0x952d86a2, 0x510caf53, 0x03b0e1f5, 0x623210f4,
- 0xf5cfab14, 0x2c1925e1, 0x4d313dee, 0xbd5857d5, 0x9717d91e, 0x75f3f205,
- 0xe67f17a6, 0x9c41c5f0, 0xec4a15da, 0x1c49dbb8, 0x3673814f, 0xfff8d212,
- 0xc0beb303, 0x73811c7b, 0xecd2122e, 0x9b2ef007, 0xbcb37e36, 0x17be00f8,
- 0x303a415c, 0x45a2b80e, 0x857a6f1f, 0x2ab8f62d, 0x99ce079d, 0x42ed1048,
- 0xc0271f0a, 0xce0ab227, 0x057b8271, 0xce06aff4, 0x19a82429, 0x412e703f,
- 0x679def9f, 0xad13f612, 0xdaf5f447, 0x247ac4be, 0xe305d3b7, 0x713bbb74,
- 0x939c08bf, 0xafba9db0, 0x414c84f4, 0xdd6fea99, 0xc3de561e, 0xeb55a3df,
- 0xcf75fdab, 0x977df852, 0x55dbf608, 0x8511054d, 0x9feda3cb, 0xbcb39fa0,
- 0x45c23f7d, 0x7c2887a5, 0x81a824ec, 0x474d524f, 0xfb7944d8, 0x584d0fe7,
- 0x4a52fa3d, 0x1f38075a, 0xf6ae2707, 0xa2e5a44d, 0xf6d7c749, 0x473e5eec,
- 0x49b0f2f1, 0x2bc8fee4, 0xa89d4f57, 0xbdfaf3c9, 0xbe3f83ed, 0x47b3ca1a,
- 0x1ecbf6b3, 0xcb0feaba, 0xa25ca8a5, 0x702b48eb, 0x4316f26a, 0x63f341de,
- 0xa1b77934, 0x9e50d13c, 0x610fc862, 0xe19cbbf5, 0xc84bd134, 0x5ca687da,
- 0x03dfc12d, 0x81cf0d4a, 0xc56bfb9b, 0xefe1abbc, 0xb364562b, 0xd95817bf,
- 0x3859782e, 0x655f8313, 0xa76cf9ef, 0xc03460b2, 0x9065e3a1, 0x826de503,
- 0x4770f41b, 0xe630b6cb, 0xd3479da1, 0x7bdd85ae, 0x86396f2a, 0x7fedfaed,
- 0xf8f90994, 0x63ef51fe, 0x15c5f3bd, 0x78fae991, 0x19e2fef3, 0x26fe088f,
- 0x3be8b8d7, 0xdedb5dbd, 0x37bdfe8c, 0x53ba472a, 0x8e51077d, 0x067fee1a,
- 0x288e3e60, 0xbc70a89f, 0x7c59d47f, 0x31ddf0b7, 0xdb6047ed, 0x64f92fb7,
- 0x7f91e819, 0x0e3138ad, 0xfb782af4, 0xdf8df610, 0x614ba10a, 0xf8947a1f,
- 0x6f71852f, 0x3f78b8af, 0x547d913c, 0xde0c7cee, 0x87cffdb5, 0x7f0d5ee6,
- 0xb3a8eeef, 0xa9fc2873, 0x52ae239e, 0x81d1c7c4, 0x4292f89d, 0xcb195c66,
- 0x6a1ced0f, 0x5db7f9a2, 0xe2fe59eb, 0x2f20c7ce, 0xed632dc4, 0x150e74c7,
- 0x2c3260dd, 0x726dfc47, 0x3ff7e6c7, 0xcea33972, 0xbee1eeef, 0xa42e0097,
- 0x7037ed9c, 0xe542d0bd, 0xd3d29ce9, 0x7851375b, 0x1d85f9cc, 0xaea6dce5,
- 0xfa65af1b, 0xe200b070, 0xbc39928d, 0xb9443f71, 0x90dea12e, 0x42607b0a,
- 0xb4ce9f14, 0x17ee0f0e, 0x036d5597, 0xce79207d, 0x1a2fdc68, 0xb8acbe9c,
- 0x4374d171, 0xe2b34b22, 0x8bae4cdc, 0x961fbc26, 0xf5138f7c, 0x77f15fa5,
- 0x21df29ae, 0x5e38387d, 0xbb3173de, 0xf3173dec, 0x4e741c2b, 0x11de7ec3,
- 0x222deb7c, 0x056824a4, 0x50d896bc, 0x91b5b90f, 0xd72a15ca, 0xebbcf8eb,
- 0xfe8a5dd6, 0x5fc15b82, 0xfbbe1a3b, 0x47461352, 0x0cbafcf5, 0xed44779a,
- 0xbe99bab0, 0xda7bed54, 0x5cac8d75, 0xe9755b95, 0x5fbabdac, 0x71b0d725,
- 0xe9757f92, 0x5d875846, 0x8bf5e762, 0xb8dc8d66, 0x1bfff70c, 0x1fc0e2b2,
- 0x82a5f3e2, 0xc961fcdd, 0x9fe81330, 0x861a7e2a, 0xd172befb, 0x73f29ff2,
- 0xbd4f1516, 0x5b1c65f6, 0xea9102f7, 0x3fbd740f, 0xfd71fb72, 0xcb189f54,
- 0x3e99b30e, 0x4cd74591, 0x5225f034, 0xfef838e7, 0x694e083f, 0x147feeb0,
- 0xbc777f4e, 0xf73ef4f4, 0xbe61325e, 0xe84f4b15, 0xb870bdef, 0xcb0856ff,
- 0xf79ad9c9, 0xb077e848, 0xfa76bf33, 0xce69c7c7, 0x53dce7e7, 0xbaa77a81,
- 0x77cffb1e, 0x64dfc3e5, 0x51a7f234, 0x8efa3c2f, 0x3ff82d65, 0x282d2a8e,
- 0x4b5e8f8f, 0x51c5fef0, 0xaa941efe, 0xa2fce6d7, 0xd3b015ec, 0x4889c536,
- 0xbe09f71f, 0x7dc78054, 0xfee01e94, 0xa28f1ab6, 0xf175c7ee, 0x4085f5a1,
- 0xc68f370f, 0x881eef73, 0x4b7a848c, 0x2eb8df99, 0xf0ed13be, 0x371ef1ba,
- 0x07d0099d, 0x5b3231e2, 0x5d4fff41, 0xbab3a306, 0x3ef0cb92, 0x2097a505,
- 0xe8cd9fb6, 0x41266eae, 0x766ea1bb, 0x959bd20a, 0x9f30ac84, 0xa927e8fe,
- 0x10a3c586, 0x7b5637c9, 0x638c1d6e, 0x767b117e, 0x41378ee7, 0x456b5d8f,
- 0x8950163d, 0xc9b51de7, 0x074a5f38, 0xaa5748c5, 0xd49bf67d, 0x0f68fdd0,
- 0x5feed17a, 0xc3cdf4ed, 0xeed2fff9, 0x5837f981, 0x264b1ac9, 0x05643598,
- 0x1f3e49ca, 0xc608fb52, 0x7ae5cc2f, 0x67c57be1, 0xfc7fa09d, 0xff504e3c,
- 0xec0fa52e, 0x9584f9f0, 0x7ed7bfcf, 0xf9a9ec0c, 0x6277b2f7, 0x3e699ac9,
- 0x9d05f9fd, 0xb9f8126b, 0xc47d4ff9, 0x87e37409, 0xffe82e76, 0xff709cbf,
- 0xbb2f7fc6, 0xb4824acf, 0xfb68a8fd, 0xc1df81fb, 0xf9b22e5f, 0x27bb6a93,
- 0xf7a0fbd6, 0x44bf71c7, 0xed3e23ed, 0xc638ea78, 0xf8bda97e, 0xc28bc000,
- 0x8cf70c3d, 0x7f64bf22, 0xdf38c097, 0xa0f22544, 0xa9cf9695, 0xefe1e316,
- 0x3a97fb88, 0x7ceabd71, 0xae4726e7, 0xa1847f44, 0xcaf6e3ff, 0xab67f01c,
- 0x57b90ff6, 0x5c21ef63, 0x845e6894, 0xb411f87b, 0xe77cfaa3, 0xeed1b1f6,
- 0xb35be424, 0xdc6f5eb6, 0xcc3047be, 0x4795d39f, 0x7e6f0090, 0x28af1e7e,
- 0x5ef83991, 0x2ade6194, 0xba73773c, 0x08c2e953, 0xc0fdddef, 0x1ce9513b,
- 0x97fafd0a, 0xc64e119a, 0xf4fdd5fe, 0x1fe52b11, 0x82f5774a, 0x7f5af480,
- 0xc7f71db7, 0x49e46b1e, 0xefb8d7bc, 0x7777c46a, 0x4103cd89, 0xb5528f5a,
- 0xf633cf1d, 0x9e8cf3b1, 0x81239d91, 0x9ae9ba9f, 0xdd3f147d, 0x418d8aaf,
- 0xd5049d41, 0x37155e8f, 0xef77fd02, 0xb3f586be, 0x89dececc, 0xbdc30806,
- 0xaadfe0c4, 0x81f39fc1, 0x002fbd89, 0x6b458f7f, 0xd1bdc377, 0xbca8cce2,
- 0x180281e8, 0x573d4dbf, 0x38e097f2, 0x3df0dab7, 0xe0934a81, 0xb2abbd03,
- 0x67bc32f4, 0xd1dff840, 0xa568e551, 0x99a3da89, 0x34afbe51, 0x31723fbd,
- 0x491293f3, 0xf5a347e3, 0xb03b045e, 0x03b6b2dc, 0x49bb51ef, 0x6843eff4,
- 0x6b95a5fc, 0xf3037ccf, 0xf8356caf, 0x83fe0c11, 0xa53d2d52, 0xf504e947,
- 0x531f907e, 0x775bde09, 0xbf3dbcf2, 0x018efd03, 0xf030ce7e, 0xd6d77b00,
- 0xc042dd99, 0xc9381aaf, 0xed0996f4, 0x0ec1078d, 0x18efcf8f, 0x700dcb0a,
- 0x9ef19f3f, 0x75f6f8c9, 0xaa95d822, 0x6bb1a3be, 0x8c61bd2f, 0x4df76536,
- 0xf1864ec1, 0xf013e13a, 0xc9f6c48d, 0xf74803ff, 0x800023ad, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b, 0x733ef0b5, 0x9992bcce,
- 0x9264cce4, 0x0927de4c, 0x27010084, 0xd4500421, 0xe6a2bc21, 0xa2d101da,
- 0x3c2438b5, 0xa0992112, 0xf7ad8b95, 0x24844032, 0x111a0804, 0xa284e028,
- 0x17edaf62, 0x04c0622c, 0x16c45407, 0x6b5ec5fb, 0x46f7f6d5, 0x485ca008,
- 0x6c5cb046, 0xad7bfcb5, 0x67324fbd, 0xde952892, 0x1e9f7cde, 0xecfbd9f6,
- 0xaf6b5ac7, 0xa5b3def7, 0x90d74b32, 0x44b44849, 0xc8485488, 0xbb11a6c2,
- 0xfe840957, 0x5b6673b9, 0x862a7909, 0x83c9e03c, 0x33c8abb2, 0x72599086,
- 0x9e3c8c71, 0xb1722390, 0xf7878e59, 0xda1e9181, 0x08e3f88e, 0x55c84499,
- 0xe075bbf8, 0x24203693, 0x625dbfbe, 0x8d7e4d76, 0x0e76e865, 0x83a7fd03,
- 0xd8b6d090, 0x8f986ec0, 0xd1796024, 0x0d2df46f, 0x613a3f38, 0x7687df3a,
- 0xfe600666, 0x40c9a415, 0x4a5909b2, 0xd2220602, 0x8fe22676, 0xda4fa029,
- 0x173e962c, 0x2512356f, 0x55dfe097, 0x40655ffa, 0x6ccd265b, 0xe0a54b5e,
- 0x90862111, 0xfb13a425, 0xdb57b259, 0x1234e96e, 0x2afad2b4, 0xc3460913,
- 0x5f5b55b3, 0x0f38424d, 0xa355db5f, 0x44d27fa6, 0x36db8508, 0x3b662133,
- 0xf99dc9cc, 0xe87f9d38, 0xb76bbd6d, 0x6869c842, 0x870fd492, 0x38e2d88e,
- 0xa8947380, 0x568675c3, 0xd3760745, 0x48eb7675, 0xb70a3ec5, 0xc0f2364d,
- 0x59ecfa6c, 0x0d8738a9, 0x9d8c7043, 0x3c20663d, 0x2b990e1b, 0x6e7f1402,
- 0x55708759, 0xd5895fdf, 0x40cbb963, 0x7d695a2a, 0x5fda6ad1, 0xf57d7f5e,
- 0x7c2f163d, 0x70165337, 0xbbe780de, 0x0d64cf00, 0x3ded077e, 0x71a8fc74,
- 0x777ea9ec, 0xcdfb5f67, 0xfe14df0c, 0x952dff30, 0x27802d51, 0x0493b922,
- 0x04759407, 0x63cf2ee9, 0x0fefd2f0, 0xfd7e7405, 0x5849f40d, 0x31ad7f7b,
- 0x97b62cf0, 0xe5a0ade7, 0xb9e69f43, 0x489c281a, 0xd03e7bae, 0x5173d2c1,
- 0xf1c1d00a, 0xff5f3f73, 0xf17f5a5b, 0xa4628353, 0x36800bf5, 0x090f1e28,
- 0xe7684ade, 0x3c8a37bf, 0x352ddf4b, 0xbb8c3710, 0x8088c0f4, 0x807bf69f,
- 0xb0feb196, 0x1a59c715, 0x90b6dde3, 0xa5f4b3f6, 0x40a51778, 0xf03eaaf2,
- 0xdf5073c2, 0x4b3d7661, 0xc51a5dfb, 0xa1e971e8, 0xbe7efc14, 0xf014bbd9,
- 0xfc0c6c93, 0x7be92fc7, 0xf5d19af2, 0x245c7d2c, 0xff3045c1, 0x0166ad8b,
- 0x75849dda, 0xad27d2c5, 0xed5d6013, 0xbfb63c74, 0xefd21692, 0xb227d54e,
- 0x9d387175, 0xe91a30da, 0x8d9e8b79, 0x60283fe7, 0xcf7a93fb, 0x3e5a248c,
- 0x6bbe72f9, 0xf5eaad15, 0x4a068218, 0x4b4dbe7f, 0x84b1904e, 0x5d94eb94,
- 0x38722700, 0xe2abe71a, 0x7171b7c3, 0x1efbd429, 0x124eec7c, 0xf4fef433,
- 0x310919b5, 0x0f6bd3f5, 0xfd03a509, 0x6ac8af6f, 0x7b71d20d, 0x44ba47da,
- 0xe45275ac, 0x5990fa53, 0x833d6edb, 0x8f43a86b, 0xfb5af4fb, 0xb44af587,
- 0x5bfc1f1f, 0xf0dd2784, 0xbc017eea, 0xc1c59787, 0x747f14ca, 0x8943bebd,
- 0x7ac8af08, 0x0bbbd5b3, 0x13f553f8, 0x0af1f3ff, 0xf9086f84, 0xc78a6919,
- 0x1de7467d, 0xbbefd134, 0x5f7159b7, 0xb4a63c65, 0xf77e0175, 0xb69d70db,
- 0x0ad16e69, 0x58991de5, 0x314571be, 0x86c71539, 0xaf940925, 0xa4ffa44c,
- 0x49122efd, 0xdf00a9ad, 0xeda36ce7, 0x869cbccf, 0x24645cf8, 0xcfba2675,
- 0xebc32349, 0xa7ca1699, 0x8dca7c28, 0xc967c85d, 0xe804087f, 0x85abb685,
- 0x20e94b76, 0xe1030549, 0x034b7c06, 0x395840b7, 0xb5abce8b, 0xff742445,
- 0xfaa7ca10, 0xcfd59fd6, 0x693f80c7, 0x337f27be, 0x57e8e16a, 0x63ee2df9,
- 0x59c4a8ba, 0x51f9fa63, 0x18e7ac47, 0x12c3f3e3, 0x44677e01, 0xf29972ef,
- 0x8fc4c5b7, 0x0492b1fc, 0x478ea9f1, 0xbbe32df9, 0xe177c626, 0xfc0d7519,
- 0x8ad241f7, 0x380ab37c, 0xf77c60d2, 0xc777ca31, 0x0977cd0e, 0xb807c9a9,
- 0xb8b7eefa, 0xf803ce00, 0x2aefe72f, 0x8c0d131e, 0x58f8df0f, 0xfd792440,
- 0xeadd7870, 0xcfa0e73e, 0x06e242e8, 0xc0fbe7fe, 0x806e5264, 0x516487b2,
- 0x4eb0ecf8, 0xad027ef9, 0x0dc449f7, 0x93ba337c, 0xfbe85bb8, 0x87e2669d,
- 0x2826a6fe, 0xc0d38fd8, 0x792f42e8, 0x2fad3e48, 0xea0cee2a, 0x13c49f60,
- 0xb5bdf819, 0xd3bff593, 0x802bbf4a, 0xaefc04ef, 0xa9137bef, 0xbefb0a8d,
- 0xe91990f8, 0x6b41f2e8, 0xd0f288c0, 0xfda3619b, 0x48d1fc25, 0x873dbd60,
- 0x7be7c8ac, 0x2b6e64f4, 0x4910ef6d, 0x73e22b4d, 0xd827f62d, 0x27e9f132,
- 0x680429c5, 0x053db857, 0xab2132b6, 0x65575f91, 0xf283de76, 0x81519f76,
- 0xd6d97c7d, 0x74ca1cb5, 0xe5a7e23c, 0xdb05652f, 0xcd4ff6f9, 0xef7d09ff,
- 0x0c5c58f3, 0xa07cdeba, 0xa3f8a317, 0x6f144c7b, 0x42c7c433, 0x5679d28f,
- 0xe06459a5, 0xfe32d3c7, 0xb4bdfef4, 0x3d7ed9fc, 0x9fde0231, 0x64973a9d,
- 0x2a27cd0d, 0x5d93fa03, 0x64baf461, 0xd55cb6af, 0xdafb2daa, 0x9b54e5b4,
- 0x1a2671d5, 0x2aeba6f7, 0xb1a327a5, 0x3a16d3e6, 0x46abe35f, 0x967f9be4,
- 0xe03699bd, 0x31d0ba0b, 0xe331a380, 0xe02f58fc, 0x0173fdb9, 0x1b4a469e,
- 0xbe0c799d, 0x9b2eafb0, 0x79c867e7, 0xfe97cf43, 0x47087499, 0x93c189b7,
- 0x9b1f07f1, 0xee57dd12, 0xf5d08ecf, 0x251d9a2f, 0xee37c6af, 0xa045f1d2,
- 0x891ce0af, 0x9f6deb6f, 0x5db16309, 0x5989f225, 0x579d1db4, 0xb7c656c5,
- 0x18ce9297, 0x54d50fd8, 0x145131af, 0x78636c3e, 0x2a1b5258, 0x367fd20a,
- 0xc2464bdb, 0x25afa53c, 0x1d7fe00f, 0x87a61bf4, 0xb1d366dd, 0x72cd7bf6,
- 0x368e06b7, 0x96d7d94d, 0xed877724, 0xff7c2597, 0x60904513, 0x7af94b3d,
- 0x6f782f7e, 0x9955f803, 0xe8530cba, 0xfd7eb7f8, 0xc5efca05, 0x75c6ca2b,
- 0xdbd70b8f, 0x1757c88c, 0xf7c5ea3f, 0x399b6faf, 0xcdb7d71f, 0xcfdc00ac,
- 0x9e9014ec, 0x025aa717, 0x5bcffa26, 0x5b9f4c6d, 0x8413bf4c, 0x848c7081,
- 0x331dd9db, 0x6747409d, 0xdfcf1b09, 0x59e4e4ca, 0x9b2bc299, 0xcefe81b5,
- 0xebbe31b6, 0x33f33adb, 0x778b4fe0, 0x67902e8a, 0x1aeac3a4, 0x7d3ca04e,
- 0xf40b42e4, 0x0a6e2977, 0x6bbcdf6d, 0x7be22cba, 0xfd8013d1, 0x6f3bb923,
- 0x5da5efa5, 0x78df5013, 0xcd91a763, 0x0e7a66d3, 0xd7eb71d6, 0x92c7ea22,
- 0x2f41788e, 0x47b8366b, 0x76557ec2, 0xf0033b3c, 0xb2567672, 0x42ffdb0e,
- 0xc3c03220, 0xde0122b6, 0x0f24162f, 0xad8acfec, 0x72e1a595, 0x11136cd9,
- 0x1e32535f, 0xe0b2e84b, 0xe407ba7e, 0xba4ed554, 0xd9fc607f, 0xaf7fbd1f,
- 0x3d3f7c23, 0x6174445c, 0xbfc77672, 0x5fc13d20, 0x34f808b0, 0xeef5c583,
- 0xbab4632b, 0x80726a2f, 0x5d5e2e5f, 0xa20f2393, 0x8bedf7bf, 0x8e1f741d,
- 0x4d836426, 0xb0755720, 0xfd1aed31, 0xdfbd2876, 0x0373ab92, 0xe22e4ddc,
- 0x133e967e, 0xa0bf548d, 0xa025f07c, 0x1a78788f, 0x97d23e10, 0x877ded0f,
- 0xcd926bae, 0xc7a053fb, 0x07cee20c, 0xb9212bbc, 0x005baa98, 0xc80fd462,
- 0xb7d3230e, 0x6defa624, 0x81cf2789, 0xfb8ea0be, 0x1e2fe84b, 0x1b1ec2f9,
- 0xc3e7b7ed, 0x5c018eaf, 0x8fcfd3ab, 0xbbecf905, 0xa14185f2, 0x0bb4b5eb,
- 0x2e2dafc8, 0xf17a010f, 0x0b22cfb5, 0xacf9faf2, 0x40e4c5cf, 0x6afebae4,
- 0xcfb67a63, 0x4e7ec211, 0x6dfed9db, 0xdcfa31b6, 0x002a22be, 0x23bb75fc,
- 0xff498660, 0x7c94fbbd, 0xc538a545, 0xe189a573, 0x57e7b4d9, 0x3be8116e,
- 0xa1c3c820, 0xd1fdb0ac, 0x202f315b, 0xdb3e71d2, 0xf2c7ed93, 0x912e29fe,
- 0xfcf659d6, 0xe00b2eac, 0x4177a6d4, 0x2bab8b7b, 0xd9f7d606, 0xb031539e,
- 0x223d8abe, 0xf022bbae, 0xbcc2c279, 0xbaf0be7e, 0xc00dfde0, 0x4b04388b,
- 0x6cf87f38, 0x0584a5cf, 0x98395416, 0x1c1c2c7c, 0x29e4472e, 0x5bb7809d,
- 0x3978616f, 0x00630bf7, 0x3339def8, 0xfc615f95, 0xc9959cf6, 0x263693b3,
- 0x4d69091f, 0x57d37907, 0x07573fbe, 0x6648ffe3, 0x5a1877eb, 0xfe3f61d3,
- 0xe7eda0b7, 0x091d3ac1, 0x595ede50, 0xf9434147, 0x5e17b9d1, 0xff7e0749,
- 0xa4afb3d9, 0x2fcd8597, 0x79f53bf2, 0x9aedc6de, 0x26dda7a6, 0x51195e3a,
- 0xc2a60bc7, 0xe32e6578, 0x485fc027, 0xdf7774dd, 0xcf62c9be, 0xab64f6f0,
- 0xaf60f91b, 0x1d00a8cb, 0x56f5dfaa, 0x804db944, 0xfe426217, 0x062ed657,
- 0xdb9fd08d, 0xfa01cc3d, 0x447dfab6, 0x4638aeff, 0x809b424f, 0x5e746976,
- 0x77f1f908, 0x2d4ef7e6, 0x7f9e293e, 0x32ae7801, 0x10a58e85, 0xc0030fa4,
- 0x916d50cd, 0xac253e40, 0x7a15f461, 0xbffa8744, 0x0169d921, 0x4e6b767e,
- 0x6e8ead54, 0xcc544744, 0xa7f54258, 0x6c5ce4b4, 0x74662fef, 0x81204fef,
- 0x590c0235, 0x96bf2023, 0x3a9c5e99, 0xb40dc891, 0xd33b3df8, 0xb5c49c57,
- 0xbc46cc55, 0x507fe00b, 0x05caa1e1, 0x8fe01fa0, 0xd21304e7, 0xa02ed08f,
- 0x5aea289e, 0x43bf41e7, 0x5d9e53d1, 0x3d1953b5, 0x49ff95f5, 0xe76454f4,
- 0x9e803bf4, 0x93d20abc, 0x3d3834d3, 0xbbf90229, 0x07bf13da, 0x0e44acec,
- 0xef9c4daf, 0x31311e84, 0x19050abf, 0xf794b7ac, 0x04b26a57, 0x2e1f9045,
- 0x30aef9fd, 0xd507627b, 0x494ec16f, 0x3e9e7d02, 0x57ccd653, 0xb3a46f10,
- 0xe8daec0b, 0x8f942609, 0x999d75eb, 0x8e24afa0, 0x7407d9aa, 0xaf2f3891,
- 0x67da0d60, 0x079036a9, 0xbfd15b20, 0xd3d8a2b0, 0x2fa6171d, 0x2fa80874,
- 0xc6ea3f54, 0x99db53f7, 0x661be07e, 0xd7d77d40, 0xcf01f826, 0x00431ed5,
- 0x817aa0f4, 0x1bfc01f9, 0xefd80acc, 0x156536cd, 0xbff34fd0, 0x5d3f2e29,
- 0xf9806f47, 0xd7497a13, 0xbd009fae, 0x3ed05855, 0xb605b66f, 0x7776822d,
- 0x03bb61e7, 0xf8d9137f, 0xdf8e09c3, 0x7a8adf9c, 0x0a6df37a, 0xfc7003f3,
- 0x2772cf35, 0xa81f40d9, 0xe6e7eed3, 0x9d927716, 0x52b5efbe, 0xcaf1d0c0,
- 0x8788cd1a, 0x99c19164, 0xfc989ac4, 0x4c17c819, 0x8984f700, 0x4f4d311c,
- 0xb7d3bea3, 0x80a729cf, 0x6faf3272, 0xd0e3a4ce, 0x3cf35879, 0x9f79a099,
- 0x3c7e5a6a, 0x024fd28a, 0xc46e87f8, 0xebd07e26, 0x564c61a3, 0x4f70c376,
- 0x9244e8e9, 0x86cef6a1, 0xcac39369, 0xf7ff7dbc, 0x69f6efff, 0xfb7728a9,
- 0x54da61ea, 0xb765ab1e, 0x9d6bce99, 0xa25ebfb5, 0x4da9aefa, 0xd7fbdf60,
- 0x8a9d3edf, 0x1d415ee8, 0x377aceff, 0x44cca9f8, 0xfcf85e33, 0xf5fe88a4,
- 0xa28b7fb4, 0x02565fb6, 0xa0553dfd, 0x73aedf96, 0xd26df9d3, 0x9043fb6b,
- 0xa0a1eff2, 0x4f8be78e, 0xdc9c686a, 0x3d5017af, 0xdf1f6021, 0xfbac1faf,
- 0x06e9b4a8, 0x7cb4563a, 0x577200c9, 0x873ef395, 0xe447fa80, 0xef897d7e,
- 0x57ccefd7, 0xba3d5187, 0xbf47a348, 0xdabe4764, 0x24b60335, 0x6f903fb5,
- 0x10f31efb, 0x3ea8e7d0, 0xfa8ec072, 0x4733f9c8, 0xeccf7d68, 0x514b1cbf,
- 0x79b2dda0, 0xaefaf7a0, 0xbeb74848, 0xa04062bd, 0xfbe26b74, 0xc0f1ca85,
- 0x9e9fa170, 0x9d39941e, 0x0744fcda, 0x8c21df74, 0xd57d23f7, 0x714ddfa4,
- 0x3ee71299, 0xb7ef8f62, 0xfdd7231b, 0x0fd99d91, 0x6de2dcbe, 0x1effd039,
- 0xd09e8081, 0x61327b90, 0x9f4dda01, 0xfb0c2c24, 0x29edb2ae, 0x5ee56784,
- 0xfc70a0fd, 0x1c222ec8, 0xecbe0fab, 0x2e71be06, 0xa84f2020, 0x37f50290,
- 0x854572d2, 0x5241340e, 0x2f7f9818, 0x35cc8fac, 0x7d74e190, 0x409bd041,
- 0x977bda8f, 0x375846ff, 0xafa04ffd, 0xa1167bb6, 0xd73edd3c, 0x30992164,
- 0x0865b2cf, 0x0dca3907, 0x2dc86870, 0xaa71824e, 0x4590cd67, 0x1c7aa7a8,
- 0x7a3f57d4, 0xd30c405f, 0xf4da1b03, 0x14e7a025, 0x57ee7d51, 0xf669de74,
- 0x745c4bdb, 0xfb88a71f, 0xe5a61ff2, 0xf1f0432d, 0x6e4c1c47, 0xff1e0ad4,
- 0x5fd10af7, 0x6ffdc247, 0x6f4c6d19, 0x683768bc, 0xed17affc, 0xd9377e12,
- 0xc81539df, 0x15d4b0e7, 0x8fb4fa0d, 0xfb073fb8, 0xca2c7899, 0xc62788b3,
- 0x152b1c8f, 0x1c992bf4, 0x806feb5d, 0xda12c9fa, 0x7aea442f, 0xa9edc612,
- 0x081ab877, 0x7e5007df, 0x9eed0f34, 0xabde71f9, 0x5c454740, 0x3839ed4f,
- 0xaf2cbf33, 0x7faaef5f, 0x0d581ad6, 0x3caad4fc, 0xf4fc0251, 0x24f9094b,
- 0xa73a8531, 0xff2a7ed2, 0x1b7ec76a, 0x7151bda2, 0xe6f5fe74, 0x81d03d40,
- 0x76c445bf, 0x20a6d98e, 0x73d9f3f4, 0x2fd016d6, 0x02268ef5, 0x15cd4c74,
- 0x1c9887f4, 0xf2d0a21e, 0x497cff54, 0xa1117900, 0xbf054ccf, 0x0e2bda11,
- 0xf3162bf4, 0x529c31fd, 0x6e1319c1, 0x71abda85, 0xf1cdfafd, 0xf048e6af,
- 0x747bd552, 0x9de7e626, 0xc08a3736, 0xe86d64f8, 0xcafc0e98, 0x7a024e8e,
- 0x80ab5570, 0xbee554e3, 0x65bb0064, 0xdfdb2b49, 0x50676e3e, 0x5e83a5f8,
- 0xcd171d91, 0x465acbf5, 0x58f3a4ef, 0x45f9c00a, 0x68424f86, 0xbdb86b3b,
- 0xd5d98ab2, 0xf7033fbc, 0xbf715787, 0x58849511, 0xd54e363f, 0x67f35633,
- 0x71f27b13, 0x6e9d08b7, 0x2f99e011, 0xeab6fc68, 0xe31c7a73, 0x4347b13b,
- 0x86ff6033, 0xff817d28, 0x6b309b68, 0x7d749bd9, 0x728fc6db, 0xa4e60a81,
- 0xc01624e4, 0x148a4a7b, 0x9f6d85ee, 0x21ba00cf, 0x6bf70425, 0xb114db75,
- 0x400dc78a, 0xae8c485f, 0xc4fa8169, 0x3e517207, 0xfc1f1f83, 0xb87077ff,
- 0xff985926, 0x9fdab9ce, 0x8c1e50f9, 0x26f659ef, 0x0a263f8c, 0x148915e3,
- 0x3e3b5637, 0xe57fc0eb, 0x4047f924, 0x954b3afe, 0x1a8f9802, 0x89d78a37,
- 0x43cacc0f, 0xbb658e3e, 0xa6ef704b, 0x6ce3bbcf, 0xdf6a2eb8, 0xe17cc095,
- 0x0ddb807d, 0x4e274760, 0x7187c9ad, 0xcf044e21, 0x84a0a49e, 0xcf2a68fe,
- 0x6d3a059f, 0xaf00ca33, 0x3eb7b6d2, 0x6a5b7900, 0xe822ad22, 0x4b7a113f,
- 0xf35dcc56, 0x2f7b6e80, 0x38f5d99c, 0x03eeebcc, 0x47e22f2e, 0x7adc8fab,
- 0xcfcbd30b, 0x80ad1b3d, 0xf39bb91e, 0xb23faa6d, 0x982fc138, 0x47a9191d,
- 0xb5a7123e, 0xffcafa4b, 0xcd923d70, 0xf7e74fcf, 0xf77f186c, 0xb7afbb71,
- 0xc80c62e2, 0xf47d55af, 0x517fe546, 0xb6529ebf, 0xd813fa27, 0x45767d67,
- 0xb5223e84, 0x840538b0, 0xdaef90d9, 0xe2fe3c0c, 0xff07ce76, 0xf9072d87,
- 0xa2e7f1cf, 0x173740fd, 0x97a8cd5b, 0x10433649, 0xb2fb55e6, 0x8013a031,
- 0x7578720f, 0x818ab8f0, 0x39ec6bc7, 0x0714280a, 0xfbe41e0c, 0x2cf497fe,
- 0x781312ae, 0x5e5a39e1, 0xc789387a, 0xeff6085d, 0xf08d183f, 0xc4a51a5e,
- 0x7f4bff42, 0x9e20471d, 0x03c74bd2, 0x7b37cf3c, 0x4d780a7f, 0xc9feb236,
- 0xc585466b, 0x36398279, 0x0096870a, 0xe54effd3, 0xba0682ea, 0x17d016ee,
- 0x3546dfa0, 0xd9d6c2fe, 0xc58521bb, 0x0119400f, 0xfb9eacbb, 0xcab8d5e9,
- 0x2b87e661, 0x5393f1e7, 0x033d17b3, 0xa15ab4a1, 0xb4ec04a6, 0xd0530dcb,
- 0x89fcbd6f, 0xaf2cf859, 0x17dbfad3, 0xaf7c1a91, 0x3f5527c6, 0x19711977,
- 0xefdcfe98, 0x7d51d43f, 0x8a93a946, 0x12667e41, 0x03c83579, 0x37b14fc5,
- 0xe96b3e81, 0x81789413, 0x93b69942, 0x80511dea, 0x3ab575ef, 0x5afe5b94,
- 0xa9da1b9d, 0x1c56f2f4, 0x57fd23f3, 0x5097f31c, 0x1c600750, 0xe7ab59f5,
- 0xdfde7efe, 0xc20ba22a, 0xe7b02753, 0x192a593a, 0xfdab7e4c, 0x4c6bead5,
- 0x4e6f4053, 0xfb3fa1d3, 0x173dc1b2, 0x1cf6c5fd, 0xb5ad53c4, 0xd584aea6,
- 0x6cba5ee3, 0xfeb0790e, 0x96298966, 0x3f03b144, 0xfa6388ed, 0x16dc2445,
- 0x91cb6936, 0x80ca9071, 0xbc4e5cb6, 0x59b29223, 0x7dfc20dc, 0x9767e707,
- 0xbc39321b, 0xbbe0065d, 0xa557faea, 0xd2e9b832, 0xad2b33d8, 0x41d02e78,
- 0x3285f816, 0xaafcc9e1, 0xff382574, 0x021d9bac, 0x7cc447d2, 0x9e8c6d6b,
- 0x0fccf5fc, 0x3fcef7f9, 0xe367de72, 0x763ef812, 0x56be213b, 0x5e301b2e,
- 0x12fead7a, 0xdf6b4393, 0xf1ff95f6, 0xe7b32df6, 0x2fc645eb, 0xa97c8c88,
- 0x396b664c, 0x0b9eb825, 0xd50b7bc2, 0xf51d601b, 0x91f00162, 0x705977a9,
- 0x2987d51d, 0x55f5a11f, 0x83a5758f, 0xee2eaf5c, 0x80bc81ca, 0x6cc2f848,
- 0xd19f9525, 0x6a0e6576, 0x50de808f, 0x0d878da7, 0xd3ba038c, 0xeec1e31c,
- 0x2defb539, 0xccfb5f90, 0xbfe8bf28, 0xff61188e, 0xbe44cc1f, 0x3bc589f6,
- 0xbe3ee21c, 0xe7aee0a8, 0x618f4133, 0xbb55547a, 0xc4f405b1, 0xf8b0dab2,
- 0x51affc1a, 0x75236f1b, 0x93bbf476, 0x8afbed66, 0x0ddf111d, 0x2135bf88,
- 0xbc18b65e, 0x53bf6123, 0xf1f18439, 0x023a950b, 0x5d172df8, 0x5d48408b,
- 0xf3f56b30, 0xaf86560b, 0xfe550e69, 0xcf0072b8, 0x7801e57d, 0x9e00e576,
- 0x1bc475cb, 0xe0154fde, 0x2977e299, 0x9785f3c7, 0x9e00e427, 0x909befcf,
- 0xa2de7803, 0xbec3726f, 0x4b7b2599, 0xd3dd8e00, 0x415fa83d, 0xd1f613bc,
- 0x7de3d2b5, 0xf464f37d, 0xf390df78, 0x5bf8c7fc, 0x8b8f9286, 0x95a1e6fa,
- 0x92830e8f, 0xcca0fc0a, 0x3946fc64, 0xfa837f09, 0xf4464cf3, 0xeafe1c7f,
- 0x1bcc46d2, 0x3f511768, 0x2c3bfb51, 0x3f41b379, 0xd381fc3a, 0xee8617e5,
- 0x8afc0adf, 0xe0fcffc5, 0x02ed5167, 0xe48cbf55, 0xfbe63fc7, 0xfdc3b37a,
- 0xd83bfd99, 0xb8ffaaa7, 0x0531b782, 0x77bd312e, 0xfe62e08f, 0x27f456e3,
- 0x97cc7757, 0x69fc5fc1, 0xab8ff980, 0xff47ce5f, 0xf5e06571, 0xdfc80a60,
- 0x7b064176, 0x27cf72a4, 0xfd2c8b31, 0x73b52f76, 0x886e809b, 0xfa471b49,
- 0xa62a7034, 0x3ef382dc, 0x768ef30d, 0xf7400c84, 0x23fed4d5, 0x52d54974,
- 0x5bf418e8, 0x17a820ed, 0xed69b614, 0xb8054a41, 0x031eedee, 0xededddf2,
- 0x75f80042, 0x999bc182, 0xa48d720a, 0xe40718ca, 0xc3976cfb, 0xe8f301dd,
- 0x03bb6b8f, 0xa33cb08e, 0x48b16dae, 0xe27a5dbf, 0x6d9f8196, 0x267e72b3,
- 0xf3fb7f21, 0x21a05b0e, 0x73f86f4c, 0x9509e980, 0x4491be6a, 0xd7c51282,
- 0x0fee39a2, 0xefc0df01, 0x3efc1183, 0xa3c6acbc, 0x3cfc4097, 0xde1dee22,
- 0x1f8e2fae, 0xf4d6f716, 0x95f26a43, 0x5bdc6d42, 0x7667ef5b, 0x2b0fdd33,
- 0x57e9fa0a, 0xbf4a83c5, 0xed1fdcd5, 0x16b938ab, 0x26d7d7e8, 0x2f5f60c8,
- 0x5dfa3175, 0xe32fed4a, 0x9dfb81d8, 0x0dfa52b4, 0xed4377e3, 0xe4228fff,
- 0x7bff47d1, 0x3b5068f2, 0xf8df74fd, 0xebabdf6c, 0x7df7fd57, 0xd8176ceb,
- 0x57588cbe, 0xe91adda4, 0xceed5777, 0x5f87e56b, 0xafc3f045, 0xa1f88ffe,
- 0x7e287e29, 0xfc6b8da8, 0x7ff0fcdd, 0x4cf1be39, 0x3a31d3c7, 0x332a2aca,
- 0xd7a64efd, 0xe2f135b9, 0xcdc5a219, 0xcb22a6e2, 0xbb8c8897, 0xdc78332b,
- 0xd7e7ed9d, 0x5f11165f, 0x5c3e3c55, 0x417561d5, 0x62cb0ad3, 0xc646cf8c,
- 0xfb241f4f, 0x228a0066, 0x614ba8e3, 0x7b7f671f, 0x9e3f353c, 0x5ce947c5,
- 0xa14f2132, 0xdfcb58a8, 0x8a5cb75f, 0xbbe186f3, 0x021a8f38, 0x49b5d083,
- 0xd87b13f2, 0x99e35bfb, 0xcf3afd3e, 0x481a71e7, 0x6ca1e41d, 0xc1bb46b2,
- 0x58ea718e, 0x9c4a51be, 0x78fc4a67, 0x9e1cefe0, 0x744fbf07, 0xe8cf2e14,
- 0xf89f915b, 0xe02e2cab, 0x471faa7f, 0xf7077fed, 0x9d2b5e83, 0xddaf1bdf,
- 0x7fe57df7, 0x572fbed2, 0xe37bfbc7, 0x6c295b76, 0x2081fb34, 0x38809efd,
- 0xba40e653, 0xa19faa1d, 0xbc7977e8, 0xee3c5967, 0xcc58f73b, 0xfe46bd9f,
- 0x3a185d12, 0xb222fe05, 0x7f80a8df, 0x2825fc13, 0xb8931b17, 0x022aeebd,
- 0x2ebe4338, 0x0c7d6be4, 0xb4349cff, 0xb7d8d8fe, 0xd8fe99ff, 0xe907fe57,
- 0x9ec8378f, 0xeeceb08d, 0x901cee29, 0x74aceb6f, 0xbe1760fe, 0x768cf2c0,
- 0xee7d1998, 0x925d1810, 0xe4d77115, 0xaf13d977, 0x867b9fe5, 0x2efff79c,
- 0xa7fd6cff, 0xc4bfcff1, 0xe8751f80, 0x2f2cfc7e, 0xcdd3b8b7, 0x776469e3,
- 0x07db7f98, 0xfbf466f9, 0xeabe7c23, 0x2e5c9dfb, 0x47dc125a, 0xff9c1f81,
- 0xb12264d0, 0x6429e554, 0x63dab17c, 0x7542f8c1, 0xa97bcb2b, 0xff208c7e,
- 0x69ff06ae, 0x6715f81e, 0x26f7d011, 0x0027bcd9, 0xb23eebcf, 0xf058c5f8,
- 0xa026cfbb, 0xc87cf5df, 0xbd967fca, 0x7bef509d, 0x19e30bac, 0x61cfb3cd,
- 0xd5d155de, 0x0a4b6b4b, 0x47e8be71, 0x4d491870, 0x1afe9e38, 0xd596f2cf,
- 0x783e95e7, 0x7fafd1bb, 0x11e582be, 0x196e1cfb, 0x5faa11fc, 0x44e95a3c,
- 0x7ef5533f, 0x8915b4a6, 0x27e43d6c, 0xd54f48a9, 0x83e4a7fb, 0x9ab494ff,
- 0x2dcf41f3, 0xed05a3fa, 0x268ff3bd, 0xfcc49e63, 0x9859ef38, 0x7030b5af,
- 0x19a5e81b, 0x77d01c74, 0x2dbbefcf, 0xf2ade61f, 0x3fe02dbf, 0x58b7eda7,
- 0x62717eb5, 0x95ddf962, 0xfea8a7cf, 0xb7f410f3, 0x6243ef85, 0x359a2a69,
- 0xf757bec8, 0xc3a8a27b, 0x607f13fe, 0xcab938c2, 0x89e8b60f, 0xcfdd94d7,
- 0xcf10fe47, 0x3c1cfbde, 0x167db15f, 0x65e14fcb, 0xf0aa7f0b, 0xfe98ecdc,
- 0x1fc79807, 0xcbeba5e2, 0x4b05930b, 0x75eb3c78, 0x7887fbc1, 0x8032cf16,
- 0x8a314e7d, 0x2be8967e, 0x92ce7f4c, 0x5647480d, 0x3e30dfba, 0xf408e943,
- 0xcea1c9f8, 0x9d74b1a9, 0x93839ac3, 0xaf87be01, 0xd24f10e8, 0x9f1813ac,
- 0x78d81589, 0xf55d8dd9, 0x22ffc023, 0xa03377bf, 0x8b926952, 0xc937d421,
- 0x404e49e6, 0x2e4d7a7f, 0x7bfc578c, 0xec93cb3d, 0x42bf4688, 0xcc52fa73,
- 0xc8f9ec93, 0x489cfe88, 0xfd3ea0f9, 0x45e63564, 0x27fdb566, 0xfbac09c6,
- 0xd4dc0d05, 0x0b04f8e7, 0x3bf95f8b, 0xcd6e6067, 0x57f20764, 0x188fe3a9,
- 0x25ea969f, 0x56a43ce0, 0x8199d6ef, 0xe822ad7f, 0x2cde1ce7, 0x195f00eb,
- 0xf7a62f3c, 0x7ac75ff0, 0xe3514ed1, 0xd7960102, 0x0b5aefa4, 0xaab497f6,
- 0xe03f16eb, 0x574dbf63, 0x85fd079d, 0xd2cfd1aa, 0xcf804d11, 0xaf65b467,
- 0x339689be, 0x838c64ea, 0x925a1ef5, 0xba557e81, 0xac83e1ce, 0xe5813d33,
- 0x18133921, 0xd11d48bd, 0xd267903a, 0xd182e266, 0x32dd6b33, 0xcb8779f8,
- 0x25b9d212, 0x70025bc1, 0x807ce68d, 0xb8c288ac, 0x7e6255a2, 0x8f8aeb11,
- 0x44e7017e, 0x03f3f176, 0x9e8f0f47, 0x7abdfe8d, 0x5fb80049, 0xc9bcb1b6,
- 0x73da0939, 0x3ef0fd07, 0x59a7f98a, 0xe4c9ff1d, 0xfa0b1d17, 0x3e8cf497,
- 0x0b477aa4, 0x587711f8, 0x7b6f98bd, 0xc4506d73, 0xfddc9938, 0x66128964,
- 0xf2656ccf, 0xb32f7aa4, 0x97ed23bf, 0x5523936f, 0xd2395a09, 0xe927fe57,
- 0xae122b27, 0x5a212ed3, 0x4f522e7b, 0x06dfb489, 0xfd11dbe8, 0xa8afa50d,
- 0xfdc52779, 0xd9bd30e3, 0x7e43eaaa, 0xb14e5e4d, 0x4c4b8d85, 0xdb27feda,
- 0xcc8f9665, 0xd61274f3, 0x9024ab28, 0xd046ff57, 0x0be6a72f, 0x5e598bf9,
- 0xf9475f8f, 0x97c4265f, 0x284f309a, 0x01050485, 0x045d66fd, 0x7c844bbe,
- 0xe3ddfa21, 0xef385909, 0x2755c49d, 0x04547f22, 0xf219b798, 0x352f304c,
- 0x8c116db0, 0xc705b773, 0xc99e4331, 0x70154838, 0x3a7e036f, 0x11c582b5,
- 0x05dca992, 0xc61e4dfa, 0x973cd0e8, 0xf9a89be5, 0x87fe6a24, 0x0e62870a,
- 0x8b11e4df, 0xd5ef8132, 0x4017de0b, 0x1817a9cf, 0x981bfc7c, 0x46d9a11f,
- 0x6e5a68f5, 0xf9851cae, 0xf584bd7e, 0x21d0afef, 0x80f9aa5d, 0x7615c3cd,
- 0x226fe53e, 0xf9cdefea, 0x4064bf2c, 0x5c044a1e, 0x6e943cd5, 0xf603b7ab,
- 0xe4c8b26d, 0xa2379aa8, 0xfe1849d2, 0xde3a66fc, 0xbfa60ef6, 0x70185717,
- 0xb795bd1d, 0xb7b1ffa3, 0xce404752, 0x191bb717, 0xb78c45dd, 0x0481ae7d,
- 0x60295fa1, 0x8e79fcc6, 0x5fd36fff, 0xc1735e29, 0x65747bbf, 0x0a6eb8c9,
- 0x7a5637e3, 0x166bd9f0, 0xd7c8455a, 0x01e68731, 0xf89cda47, 0x49a43ba3,
- 0x4a135790, 0xecc92817, 0x54a0fe70, 0x37a072a2, 0x9431f43e, 0x9c7c4c5f,
- 0x76878795, 0xd1fdb409, 0xd8a51da7, 0x9931681e, 0x98253f90, 0xeb96fd4b,
- 0x40646f90, 0xc0a7c6be, 0xd748aa87, 0x0bf44eda, 0xc856f971, 0x669921f8,
- 0x94bf300c, 0x77b1fe82, 0xee513293, 0xf6b3725b, 0xaa7d4277, 0xb469fd11,
- 0xddfde91e, 0xbd5853e1, 0x524ef0c2, 0x836f2cad, 0x9f81f974, 0x05399bbd,
- 0xb055d2fd, 0xf4fea81f, 0x057bc5a6, 0xe8417af0, 0xe0fb0e5c, 0x9affe9dd,
- 0xe17df407, 0x01864fc0, 0xa06999bf, 0xfc20f97a, 0xe32771e5, 0x4b7abd2f,
- 0x79fb409d, 0x1215e2dc, 0xe883f969, 0x95203379, 0x14dc6e7c, 0x200d1c03,
- 0xe04417fe, 0x7f1cf177, 0x5f4c39b6, 0x08f34db4, 0xc6b9f790, 0xef11e6cc,
- 0xbfa8dc95, 0x7708e778, 0x11aff5d3, 0x94433eb8, 0x143bb458, 0x8eec1625,
- 0xc21e2ba5, 0xef916fbc, 0x9bad49e7, 0x7f97d045, 0x4df8f2b7, 0xe5a1b0d2,
- 0xf6115df0, 0x1254fa85, 0x8b663ad9, 0x8fa018ca, 0x6fe342b5, 0x3de0934a,
- 0x31e9b3a3, 0x5f210a2b, 0x4d74667a, 0x22cdc621, 0xf7d2c7df, 0x23656179,
- 0x14d4b76b, 0x3d28974a, 0x61decd3b, 0xf3cb9700, 0xfb0e593f, 0xbbf27977,
- 0xc2be431f, 0xd6e27abb, 0xe24d3ec3, 0x1f2a4371, 0x32c7bf01, 0x286e2c6c,
- 0x031a9d6f, 0xef866ce5, 0xe30048db, 0xd873a5d4, 0x483bc139, 0x6d176d67,
- 0x57a9d337, 0xece8c2ba, 0xbe5b4536, 0x2e5b5723, 0xff1179e5, 0xbfbed2e2,
- 0xc0248493, 0x7e26f7ff, 0xfdfc223d, 0x1beecd8f, 0x0aaffe61, 0x3fd28f2c,
- 0x87a8c889, 0xe83f043a, 0x495fa305, 0x5926e7e6, 0xb9cfdfbe, 0x44caf31d,
- 0x7b09f582, 0x0f21bb4d, 0x8b07f55f, 0x93b47ebc, 0xc8ec3298, 0x84ae508f,
- 0xe8379e04, 0x390918c0, 0x7e664cb0, 0x40d6da51, 0x5f3039fb, 0x5824b841,
- 0xa016e474, 0xd21342eb, 0x298a5175, 0x28e0e80a, 0x3f1f23a7, 0x55d2a387,
- 0x903c4491, 0x9e8740bf, 0xf577cf03, 0xfff011f2, 0x78233ffa, 0x29908a4e,
- 0xf231e612, 0x855908b1, 0xbd39a7e5, 0xedf9551e, 0x6fc849bf, 0x701ab4df,
- 0x16bf895f, 0x439f805b, 0x5fd6991b, 0xf3851c6c, 0xdd03f753, 0x091cc3bd,
- 0xfde672e8, 0x44983a4a, 0x2acaccae, 0x38f862bd, 0x410fe401, 0x738d523d,
- 0xbefa99a5, 0x4977c373, 0x74bb9fbc, 0x8a4cde2c, 0xdc9d1c78, 0x3f7cc465,
- 0xbfb42f5e, 0xf7e025f5, 0xdc4cc4f1, 0xb7887b74, 0x3446e80b, 0x4ba014b8,
- 0xdae5ce95, 0x9d29bf43, 0x79c9eb04, 0xbb73d704, 0xe4f58655, 0x6b9c3252,
- 0xae3ba7c7, 0xf461fa00, 0xefb1462e, 0xfb792aef, 0x3e8c2926, 0xec55f7e8,
- 0xf7ed68fb, 0x3dbdfa4e, 0xfa18fbec, 0xefc0de7d, 0x72220909, 0xbff3e76e,
- 0xee89e79d, 0xba829ab1, 0x917fd0b1, 0x13bf45d2, 0xc3f7d813, 0xe07be862,
- 0x7cdab9fb, 0x65d1320c, 0x88de3cc2, 0xc2998bfc, 0xd7404963, 0xdaaa99b7,
- 0x6fff68bb, 0xd4ccfc71, 0xf380bf79, 0xcbcd6f66, 0x57fc0379, 0xbfba2625,
- 0x055f60b2, 0x7ad202d7, 0xb19f78a7, 0xddfee365, 0x2d5ff401, 0x69d8477a,
- 0x69be82f9, 0xdc4cb2d8, 0xe3133b17, 0xc55fce07, 0xa00ebabf, 0x3ea7a003,
- 0xb798883a, 0x67722f8a, 0xedac262b, 0x3c087aa4, 0x9084bd55, 0xac9f961a,
- 0x8baff5a4, 0x530ccb12, 0x0bd030cd, 0xe3f4aade, 0x7b699dbe, 0x9e97f312,
- 0x04bef24f, 0xc37b9df3, 0x3412e9e7, 0x011fce76, 0xdf3a207e, 0xce5ffd5f,
- 0x06bfd557, 0x667ee7e4, 0x0ee7e4d0, 0x71d47fb5, 0x8957a07d, 0x82dbc790,
- 0x39beb6f9, 0xab9c1716, 0x68be41f0, 0x5079c621, 0x30243aaf, 0x982fd57d,
- 0xad741eb8, 0xe984bc79, 0xfa7d554b, 0xbd0f2692, 0xbbcd9f39, 0xfa829979,
- 0x6b02abd6, 0x984f9fef, 0xd78b363e, 0x5eb1942f, 0x6e6f57cd, 0xe6b5fe61,
- 0xd0284797, 0x50a3d52f, 0xae58931e, 0xfe3265a7, 0x91493cda, 0x44dc0cfd,
- 0xafcfe848, 0xfa67a2de, 0xab9d76df, 0x0c41f308, 0xf1623f54, 0x869fc65b,
- 0xfd23f1b3, 0xaa275f70, 0xc3f30076, 0x41ff95f5, 0xb259b87e, 0x7f693897,
- 0xe9dcf30b, 0x17982cfa, 0xfa51c7f3, 0x2049d1dc, 0x1866ac4d, 0x91b7cde8,
- 0xd974f79a, 0x68069f48, 0xa534773f, 0x7d0d6ccf, 0x8cf19d1a, 0x22bcc21f,
- 0x1d2441f9, 0x6578c566, 0xd6d9a7e8, 0xd06ac7fa, 0x2e8ddb37, 0xf2ca7f96,
- 0x40f922e9, 0x48167cd8, 0x510e3e6c, 0x0738f9c4, 0xecb5cf9b, 0x4cfa7093,
- 0x0c3f6c24, 0x25125fb5, 0xf416b7e2, 0x9b1f97ef, 0xbd6023bd, 0x2d66fb7d,
- 0xcc062fb3, 0x7d20b45b, 0x8b2f73dd, 0x99a2f837, 0x43b8835c, 0x167f1d12,
- 0x7a9eff1f, 0xfcf78746, 0x4b7480d0, 0xf9841fa7, 0xb3f5e6cf, 0xdf30abda,
- 0xfd34f668, 0xff0d2ec9, 0xe7bc2375, 0x1c7376f2, 0x02d87af9, 0x71b54a73,
- 0xb3f7b985, 0xa4ddc6b8, 0xbdf30f46, 0x9fb68e67, 0x73f1a4b9, 0x7b9a9fc8,
- 0x54fdf6bf, 0xc9b9df67, 0x788f1011, 0xbde1db83, 0x7ec0bf74, 0xf17e337a,
- 0x7e94658e, 0xaf34fc47, 0xd303fc00, 0x6cf72a13, 0xb7e7e5a6, 0x9bf2c28f,
- 0xd1f83f09, 0x2bbf50bb, 0x20d3cb07, 0x08ec0c19, 0x6f208fd8, 0x3dbdee8a,
- 0x86fb8e93, 0x8cbbf799, 0xa33bdbe5, 0x68b3cdbc, 0x2cd8e73b, 0xc69c1bcc,
- 0x42ef4df9, 0x0dc77f56, 0xfa1a9656, 0xb97e8280, 0x79a15169, 0xf227ff40,
- 0x790050ff, 0x78b2d3ac, 0x51d5e0b9, 0xf8437e50, 0x4dd81e7c, 0x0916553d,
- 0xcc9d5fe0, 0x73a399fc, 0x0a48e085, 0xde766997, 0x575b157f, 0xc90bc169,
- 0x15a63fb0, 0xbb467eb3, 0x4367d4a6, 0x2c45dd3b, 0x629b24f7, 0xfbaa1f80,
- 0xfb93996c, 0xe49eb807, 0x15fefbe1, 0x71b527f7, 0x498f5fb4, 0x3d12c170,
- 0xfb413f13, 0x39d85894, 0x533b8f2c, 0x54e87f02, 0xdc73cb37, 0x02ac8aba,
- 0xcdeb647d, 0xad0d696e, 0x7a226a9f, 0xce946b90, 0x9b7a011f, 0xf4f3e13b,
- 0x8b2e2018, 0x3a55ce96, 0xf7d2a59a, 0xd31d2d34, 0xe713f9fd, 0xcfe76ff8,
- 0xf7363a1a, 0x7a50f1d3, 0x1d579d39, 0xb49bbfee, 0x9c6faaf2, 0x39187d88,
- 0x01fc50ee, 0x67f9c2fe, 0x715afcff, 0xb642a5bf, 0xc7ec3658, 0x6e3f7526,
- 0x7418f803, 0x24fe789d, 0xc28d7043, 0xe8439b03, 0xd2fcea15, 0x305927c0,
- 0x27f05e70, 0xfb1d7aa9, 0x9b1d8073, 0x77e9ebca, 0x9fef626e, 0x05ff1d17,
- 0xd96b7fe4, 0x350a767c, 0xbd709f8c, 0xab7fb55a, 0x69b6f5d5, 0xc5145bd7,
- 0xc13b7bce, 0xe93e814f, 0xf37d51fc, 0xa83c06be, 0x3971f1eb, 0xb1e4c73d,
- 0xeedae81a, 0xfd2395b6, 0x5ff89f7c, 0xa0e87d06, 0xe6187bc5, 0xefe75479,
- 0x2163fb00, 0x925c6371, 0xce6bc7d2, 0x9d42fd30, 0xaa9c246f, 0x919fe087,
- 0x4f8489eb, 0x513ade3f, 0x77cf539f, 0x1af7adf5, 0x21eaa9d7, 0x3fd6830e,
- 0x1cfee764, 0x00dff73b, 0x2e3c8145, 0xd02e5125, 0x04baa7eb, 0x894a27d4,
- 0x6970f909, 0x76df9309, 0x5437d30b, 0xfed43f39, 0x8216f5b8, 0x2974a9fc,
- 0xd8c9e7e1, 0x30e922ba, 0x823d7491, 0xd9499e76, 0x39f600b6, 0xff4a25e8,
- 0xcc2d4bfc, 0xa9c57bcf, 0xf1aef5ca, 0xcafbd720, 0xd77ae403, 0xf337e078,
- 0xa3fc6d44, 0x2ff30af4, 0x7c10afda, 0x193eba96, 0x5edd720f, 0xf81e35d2,
- 0xeeb1add6, 0x1f9f012f, 0x361f98eb, 0x24fa8e12, 0xbc5fea9d, 0xdc8cfa26,
- 0xe95c6a3f, 0x94d78b4d, 0x1fdfbe34, 0x2ce84171, 0x38ae4682, 0xcdeff799,
- 0xf4a63a04, 0xf2897288, 0xc157abc7, 0x837f8398, 0x532c721c, 0x092d9bf9,
- 0x2e08dbf8, 0x8f8c3dc7, 0xdb758b9c, 0x0d1c5893, 0x8710f2e1, 0x572e74cb,
- 0xd110ee2f, 0x9dcd3f9f, 0xdcb834fb, 0x24f5c77d, 0x8dd7fb80, 0x5f097172,
- 0xa53a45d7, 0xd17fb420, 0xe2c67a8a, 0x1e31cbb7, 0x8eab6231, 0x72726128,
- 0x734a2064, 0xbde8c47f, 0x4c794d76, 0xfda6b26b, 0x9a596d0d, 0x28e0fcfa,
- 0xe3b8fd4d, 0xf8f29a05, 0xed351bce, 0xac507c27, 0xbaea4f29, 0xa6fed35d,
- 0xca6b674f, 0xac123014, 0x0283b9fb, 0x7dd74ed9, 0xcd3ee873, 0x7dbdfff7,
- 0x0b8871c6, 0x33f6e29e, 0x733bbbf1, 0xa8161c29, 0x4ca57c74, 0x08505fdb,
- 0x07c0450a, 0x4682dfd8, 0x853cd796, 0xdfbc2e42, 0x7d5a4d85, 0x6d56f162,
- 0xf37da2b9, 0x0395e05a, 0x8a6a21f3, 0x646c88e1, 0x7934c43e, 0x75e80ebe,
- 0x2fd51276, 0x91c63040, 0x1ac7c838, 0x1b7fdf6a, 0xb0c873fe, 0x6b3fc36f,
- 0x7a80d5bf, 0x7fb7e2fd, 0xafa41455, 0xfe2d4e8c, 0xff168acd, 0xfc5ab9d1,
- 0xfc5a5d5b, 0xe2d44ec7, 0xe2d6e6df, 0x8b44ae3f, 0x168f78ff, 0xb57389ff,
- 0x6af24ff8, 0xa1529ff1, 0x8d5a7fc5, 0x2b19df16, 0xf4ccf8b4, 0xffbda83f,
- 0x2aff0224, 0x7baeccff, 0x149ee228, 0xd185d11d, 0x0b474a81, 0xe798153c,
- 0xc7e9bc32, 0xe922719a, 0x3a8dda81, 0xda8b87bc, 0x6b85db71, 0xbdca0fa7,
- 0x491a5fd0, 0xf1244f1f, 0xb13b183c, 0xeef9455f, 0x40f8127e, 0xf2a15ea4,
- 0x1e3970ad, 0xc50eff6e, 0x27c806cf, 0x290f0f6e, 0x361ec09f, 0x43c3dbf7,
- 0x9087e9d1, 0x53fa838d, 0xee8bfa23, 0x2e3cd995, 0xe049abc1, 0xf225fd5f,
- 0x04e90fbb, 0x7ef9d227, 0xe3a1eb08, 0x1a35187f, 0x203f18fd, 0x7fcfd441,
- 0x74871908, 0x712007b0, 0x13e73e99, 0x5ce59f05, 0x7ee42f5e, 0xdbd9a70e,
- 0x16a97006, 0x300919bd, 0x9e276a6e, 0xe227221f, 0x855ee9ae, 0x976fe093,
- 0x7f06e908, 0x98f67d3b, 0x519c7d19, 0x289b87f9, 0x9678308e, 0x5172154d,
- 0x30a3157f, 0xfbeca80f, 0xb2a5ca02, 0xcecf61ff, 0x4707a624, 0x50acd73e,
- 0xf5c4d9e1, 0xfc0fa600, 0xe3c29277, 0x416bc433, 0xe064b9b8, 0xe63fb4fb,
- 0xf319feff, 0x4925d193, 0xec78ec57, 0xf80cf10a, 0xa241f386, 0x8c73cd89,
- 0xe8574c44, 0x8bc4d1fb, 0x49c7dffa, 0x7aee3859, 0xd632b289, 0xb7e828ef,
- 0xefa3c60b, 0x045c5ba7, 0xd3a2bdfc, 0xabffd045, 0xc32b0996, 0xf55bac1f,
- 0x7a72a5eb, 0xcc2563d8, 0xe7e1157f, 0x2729114b, 0x3d157c85, 0x94ed0f3b,
- 0xf0bb32b6, 0x18ceab98, 0x792a2eb6, 0xed7e706d, 0xc81cf4db, 0x96133d2f,
- 0x5ee14e0f, 0x3f1c9833, 0xa8e2cc9e, 0x6e9a566b, 0x0f497886, 0xbe3d078f,
- 0xf80cdc92, 0xe6172514, 0x417dc181, 0x0defb0b6, 0xb61f5a0e, 0x498b24df,
- 0x3c5bd653, 0xdac65978, 0x17483595, 0xd1af7e7a, 0x6487d4ba, 0x217f986f,
- 0x4c4f8f9a, 0x1027227e, 0xbfd2f2ae, 0x5812a74f, 0x674b28af, 0x9feaf634,
- 0xdc0146ae, 0xa93d38aa, 0xe93a35f3, 0xdeed6138, 0x2557f4e1, 0xfe601a77,
- 0x741c50ef, 0xea413c42, 0x56bde074, 0xffb8e975, 0x37f0e4ef, 0x908217ee,
- 0xe0946ff7, 0xd2f4268c, 0xd28e3cd9, 0xf477dae9, 0x6b25e204, 0x7e44cfc7,
- 0xb8d7b066, 0x1e4f05a8, 0xeca1677e, 0xea9e041d, 0x2e94e8d3, 0x61a3f387,
- 0x9e0edcc9, 0x3e002640, 0xca0f9906, 0xf66587a7, 0x59e3c3cd, 0x3fc3c1be,
- 0x4c7f9824, 0xa2bfd056, 0x13c4f87e, 0x1b1bf217, 0xc6cbe109, 0x50037495,
- 0xa561b71b, 0xa8737889, 0xa835221c, 0x3710251f, 0xfe6351d2, 0xfd395709,
- 0xebf052ce, 0x3787b05c, 0x0d53ff8c, 0x1f45ad94, 0x61b94055, 0x90ad8be4,
- 0xb981642b, 0x23bf3038, 0xa2b66700, 0xef7cfd46, 0xef07686a, 0x425f3e21,
- 0xacf9d3df, 0x821ed31f, 0x0f63d1f6, 0x51f50a7d, 0x9b29a096, 0x3f75177e,
- 0x45b04971, 0xb253855c, 0x4856d3e9, 0x8e28a17b, 0x4f47dfe6, 0xc646fd64,
- 0xbb2d1203, 0x93217dd9, 0xb1678f09, 0x1faaec73, 0xbbb2de3e, 0xc6f818a9,
- 0x53fd6d30, 0x96711e1c, 0x41678e97, 0xe7612a7d, 0x93fd7957, 0x7966debc,
- 0xe598b3a9, 0xdfbe681c, 0xb58ffbcc, 0x50bf18e8, 0xb1b78f08, 0xdebc4dfa,
- 0x093bd6ac, 0xfab1a78f, 0xb46f5e7a, 0xba12fcb0, 0xafdf35ad, 0xdc27e3e3,
- 0x30de23af, 0x89cc74fa, 0xfa30de22, 0x35da97b0, 0x9d85bd65, 0x25a79523,
- 0xfb53be6b, 0x1b8f9c7d, 0xf34b3933, 0x28d8699d, 0x34cefb6d, 0x710f2394,
- 0x0b521b38, 0xf9eaf534, 0xb3a7226c, 0x276b3276, 0xf4d46e39, 0x6251517b,
- 0x999fff61, 0xcbadd2a4, 0x90fb7404, 0xe2112b35, 0xb99581b4, 0x1f0144a0,
- 0x3f994fe1, 0x6674789d, 0xcb054acd, 0xb8bfdc99, 0x2c44e566, 0x0b74a6ef,
- 0x74accff5, 0x2d277961, 0x53f9f42b, 0x58950fda, 0x07ed1b64, 0x7ed34fca,
- 0xed14f9e0, 0xd24f9e07, 0x337ea0f1, 0x9bca0efd, 0xde507f68, 0xe58dd2b0,
- 0xb04b2bf5, 0x83d2bf5c, 0xe72b75e5, 0x95f1f3e2, 0x59ae7c5e, 0xbbf58159,
- 0x3beb8593, 0x22485f7f, 0x93bbb9e3, 0xdde7f7c7, 0x16dcf1ab, 0xd476e0c3,
- 0x32ffce01, 0x8988e788, 0xa5c63fd1, 0x8f5b1ad2, 0xe719bd80, 0x6a48f861,
- 0x5b7ac1ac, 0xfd471b09, 0x24fc388e, 0x331d88b5, 0x5950fc64, 0x230df98d,
- 0x7317cb09, 0xc45289fa, 0x9fc25fcf, 0xbcff4214, 0xabe5ab94, 0x71f91199,
- 0x9923b3ea, 0xb0e279d9, 0xc72c371a, 0x8413d134, 0xcb8b5e7c, 0x33b1e78b,
- 0xa9ced0ae, 0xe57b1cbd, 0x5f80a216, 0xbfab54bf, 0x6815a7da, 0x4af144f4,
- 0xa533b635, 0x6769a7de, 0xda699470, 0x5cc92d95, 0xa47804eb, 0x1b1875b0,
- 0xbd101157, 0xe3379b0b, 0x999367b8, 0xebd74bbd, 0x3efbff47, 0xeb97ad81,
- 0x7ccbcf4d, 0xe446a6bd, 0xac6c23ab, 0xd7eb1398, 0xff3c3f01, 0xafdc58ab,
- 0x43a33dcf, 0x1248dfff, 0x46be01d0, 0xf50cf153, 0x96174863, 0x4aee006f,
- 0x1144f9cb, 0x848e3ca1, 0x7aa4bed0, 0xb3257fd3, 0x6633d0b8, 0x79a50b88,
- 0x23f9679f, 0x392b9441, 0xaa391f1c, 0x8a55b8fe, 0x4e9da7f4, 0x7b56fb46,
- 0x5b8d449e, 0x2516b2ae, 0x33d13e82, 0xb44f7e44, 0x169bbef3, 0x27463850,
- 0xfaa7c5cd, 0x1ba2bd7e, 0x55e57cf4, 0x4cefaf0e, 0x77c601e7, 0x6afce8c2,
- 0x0bbfa532, 0x0c83bf79, 0x2c3d5219, 0x1af0f684, 0x941fcabd, 0xfd0fe058,
- 0xe62c5765, 0x2127b473, 0xc199447c, 0xde95b9e7, 0x7fa9249b, 0xf997e29d,
- 0xe49be432, 0xbdb67cf0, 0x34dd972b, 0xc75fea4d, 0x5fb614e8, 0xf22b4973,
- 0xce875cfb, 0xa735ecc5, 0x0f33bec6, 0x79c3726b, 0x7114715f, 0x48c42e41,
- 0x5ee784d2, 0xc889bfc5, 0xb7a3c47f, 0x17ea8511, 0x40807251, 0x2fda873e,
- 0x8fe276e1, 0xc2fcbf38, 0x2de70d32, 0x94f7aba6, 0xf9af51b9, 0x90c97642,
- 0xb345f2cf, 0x4f123f1e, 0x6573eb6a, 0x4a5e07d7, 0x47f68b97, 0x517a60bb,
- 0x5f784db9, 0x204bb89b, 0x83ce02a9, 0x99d9a7e5, 0x5adfaa7e, 0xe0e3fc44,
- 0x2e37aed0, 0xa5dae005, 0xc2a9d01c, 0x8aabb69e, 0x3f06ec33, 0x0b8008d4,
- 0x2e5873c0, 0x5f2171c2, 0xab95deef, 0x14ee4e10, 0x6935e786, 0x7cf9dc2a,
- 0xf70ddb88, 0x566a2dbb, 0x3aed5bed, 0x7f15e7d7, 0x3b6bea0f, 0x8bd3cc45,
- 0x9885e784, 0x286263f7, 0x3346cba2, 0xa79d0cff, 0xc129e61b, 0xbe00e3bc,
- 0x58b3d704, 0x5ce00436, 0x5ad08f66, 0x31a97182, 0x971e123a, 0x53339f52,
- 0x277aff18, 0xb467c659, 0x0b4dde73, 0xef9785c6, 0xc31eba47, 0x122c4fd7,
- 0xbb7093cb, 0x5abf7095, 0xf0676a83, 0x3e28ea3c, 0xa0fbbedf, 0x2f3cb146,
- 0x0adce90b, 0xd9431779, 0x614c3f11, 0x3b7ef2f1, 0xe806a282, 0xf309bc67,
- 0x7cd41a1b, 0x055de514, 0x13e96bf3, 0x9c4c51f2, 0xd959d74e, 0xfaea043d,
- 0xbe30a656, 0xa3e392b9, 0x22ecc4d7, 0x27e4db88, 0x6f9f9d84, 0x58fb472f,
- 0xb6f4f38d, 0xd552fcb3, 0x49c950ff, 0x060df7a0, 0x221dde87, 0xdb2a77c6,
- 0x0ef760ef, 0xf7893c76, 0x14bed235, 0xde7287a0, 0x6b4ebcbe, 0xe3d82f0f,
- 0x0ca51b59, 0xc117bbb4, 0x03d9ab7d, 0x3b48eded, 0xae14b1fb, 0x3e48babf,
- 0x354e71c4, 0xa28b1f66, 0x126435f3, 0x2297bf3c, 0x6ef784be, 0x09b3ed53,
- 0x79243bee, 0x488fbeec, 0x6a92bfbc, 0x15ef3840, 0x5a5b8f08, 0x8ef7fe90,
- 0xef7ffb67, 0x0e778b91, 0x93dcfda7, 0x7ea6e0c1, 0xcb064f77, 0x0607dd33,
- 0x4adf7d15, 0xf960c948, 0xdc38bb3c, 0x9b9f33bf, 0x5573e5ac, 0xa2c75d6d,
- 0x3b77e415, 0x8f7bde81, 0x0f2625fd, 0xef0847f7, 0x833f7f2d, 0x0de607cd,
- 0x74fbf479, 0xa70bcf9f, 0x12297d83, 0xfaeeb79f, 0xda698cf4, 0x7bc85d79,
- 0x3676e12f, 0x579856af, 0x4264f04f, 0x3ab47e78, 0x83c57daf, 0xfd7cef9f,
- 0x9133e77a, 0x5068a7ce, 0x26fd1d38, 0x0c33ed38, 0xf80f9f3e, 0x0de3fe7c,
- 0xc0c0ef76, 0xd3d4ebfa, 0xefc04476, 0x807bcec5, 0x7ef9d35d, 0x847a0290,
- 0x63013bb3, 0xad7e1c4c, 0x0b3e9c85, 0xa171df39, 0x1f7c444d, 0xa4bcc04d,
- 0xfbd58956, 0xab028bec, 0x8ebafd28, 0x7900c82c, 0x88d0fd60, 0x86f8c5f7,
- 0x4b8b37c8, 0x97d8eb65, 0x870a0c2c, 0xe47f5e18, 0xb7f61944, 0x012303fe,
- 0xf5cb507e, 0xab72f5f4, 0x5501ee09, 0x02e508e1, 0x4219f4fa, 0x2e505c8b,
- 0x58a4c2fc, 0xc74f1906, 0xb114dbc6, 0xd4f1d46f, 0x973529a7, 0x3785ddf9,
- 0xdea3c844, 0xbc3df934, 0xa15367af, 0x3bf73c84, 0x4b59bfc3, 0xef82172f,
- 0xe8c9dc25, 0x7a0a94c5, 0xe63a7094, 0x13ecb47b, 0x03cdbf42, 0xb8bc19f8,
- 0x4647df7e, 0x840c22d2, 0x2f4e25d3, 0xf5d4faea, 0xdeb6f3ab, 0xd6f300bc,
- 0xf1301f01, 0x7a9d5498, 0xd5f21e2f, 0x60f72e58, 0x2627285d, 0x7d0f2c4b,
- 0xdd7884bc, 0x3c46f134, 0xc78fb027, 0x0c93439b, 0x7e43de83, 0xfd7f1f0b,
- 0x04ecff95, 0xaedfd5fb, 0x44d9f3c7, 0x45de72ea, 0x8ef7c8e9, 0x52bdf784,
- 0xfb812a7a, 0xb89c8e67, 0xdd7a0318, 0x847aa94d, 0x0fc04df3, 0x115c3e41,
- 0xff7f304b, 0x18b217c4, 0x5393ff46, 0x7497ae45, 0xfe5e4276, 0x979602c6,
- 0x807ae16c, 0x057744e5, 0xf132dfcc, 0x4c2146c7, 0x1aa5e6ce, 0x868dbbf1,
- 0xf68b8250, 0x4910ebe7, 0x2e81f510, 0xefab47bc, 0xe0cc91dc, 0x05485d50,
- 0x47dc1e4c, 0x9ad7eeca, 0x3e30aa9c, 0x807de74b, 0xf91a8fbe, 0xf50e5c85,
- 0xacbc7485, 0x32adeffe, 0x78d467c3, 0xa6c59f76, 0xe193bfc9, 0x8158aefe,
- 0xafb43de0, 0x7935eaa4, 0xe8649ffa, 0x9d9dbf78, 0x65f9bfa0, 0x5b09f309,
- 0x40990f83, 0xc5f757af, 0x86dd54d3, 0xfdf8eb76, 0xe626ebaa, 0x805ce006,
- 0x4a7fc74a, 0x61527af5, 0xbc5f747d, 0xa7577a84, 0x47c22a67, 0xc97c87ce,
- 0xef13a431, 0x0685210d, 0xae4be419, 0x6fd9a74e, 0xea6f1c2d, 0xa8a5ea93,
- 0x69c23cef, 0x62f79559, 0x39e0898b, 0x62b32ba3, 0xd3152f41, 0x25cf3d54,
- 0x6cff1c03, 0xe1fa8399, 0x8d2d37d9, 0xf57cf1e1, 0xb3da9a79, 0x797f4341,
- 0x0333cba1, 0xde222fda, 0x2e8fa0b5, 0xe735166a, 0x7df2cfae, 0x144af0be,
- 0xf5e98609, 0x87de270b, 0x5e1647e7, 0xaa412189, 0xe7e59d27, 0x3cf2ce7d,
- 0x654f7f9f, 0xaf81b2f2, 0x75ea4b67, 0x08aefbea, 0x0ff3b97e, 0x7e3195cf,
- 0xf700eff9, 0x00cba12a, 0x8de36e7c, 0xfe3cc17f, 0x0f4ed4d3, 0x3ad37ce6,
- 0x6c3048e3, 0x5776be9c, 0x7e9eb84c, 0xff3828bc, 0x105af5fe, 0xfda9a70e,
- 0x4c70cdff, 0xbfb1c0d1, 0x1c0d2cff, 0x839ff607, 0x995e9fe3, 0x8ffd2dfb,
- 0x457fa21e, 0x7efeff33, 0x3db8e187, 0x8f9ecb47, 0x68e5fba6, 0x57f6f570,
- 0xb0ed5f21, 0x272fef11, 0x78c5ad6d, 0x0417e89e, 0x3f2d99cf, 0x90c7e5fc,
- 0xb77cb687, 0xf46305c1, 0x5cf343ea, 0x6187c883, 0x7dc3f644, 0x6f73ea3e,
- 0x27ae366a, 0x0a49bdf2, 0x666f90c8, 0x55e495ca, 0x9d65e80a, 0x1fb8d581,
- 0x549fc84c, 0x6fdab83f, 0x9ea88a6d, 0xad7dc567, 0x10d0dbde, 0x7c00eded,
- 0xe6a5167f, 0x8237f91d, 0x67f2ad1f, 0x85eecca2, 0xa21da1b3, 0xe225b1fa,
- 0x91a3bf45, 0xe5e40878, 0xdf7865e7, 0x53fefe00, 0xafc006ca, 0xe3d98e2d,
- 0xb723ff45, 0x3b9836f7, 0x7e30ae9d, 0xe954fbf7, 0xd6fce4fa, 0xfe333908,
- 0x4c82e7fd, 0xe61efcce, 0xfe762551, 0xf2132cb2, 0xbdf8bb08, 0xe3018a3d,
- 0xf0c78505, 0xd532afbe, 0x8c8baf5e, 0x40d9a75f, 0xeefd55ff, 0x044f9031,
- 0x9646c23a, 0xcd1e5dbf, 0x89bfe5ca, 0x907573c3, 0xf0079fc2, 0xec5d156e,
- 0xe119379e, 0xa1af917a, 0x1d31b4d7, 0xe1cbd9e0, 0x75fdb17a, 0x62ee57bc,
- 0x7fc470dd, 0xc13f6bf9, 0x25f6a17b, 0x0ea77cf3, 0x729fca2b, 0xee08aba3,
- 0xcc97db2d, 0x2956ccf4, 0xa6105318, 0x2d4bae77, 0xbe7abe46, 0xf40eb86e,
- 0x7fae1572, 0xa360fce6, 0x4293efea, 0x2ebbf045, 0xbf830be7, 0xdfb7f945,
- 0xa267bf8c, 0x1165f03b, 0xd1b76fde, 0x1782f788, 0x65b9181f, 0xcaafad2e,
- 0xa59e61d1, 0xe71980ee, 0xdd81a173, 0x82df03af, 0x903aae9c, 0x52c3bf82,
- 0x3cc21d1e, 0x5728aaa9, 0xca41c40e, 0xf784dc0f, 0x30da9f7a, 0xe5f81d32,
- 0x1d2578c9, 0x40dd35ef, 0x7dd74e81, 0x7b0463b2, 0xcf013f5f, 0x463759ad,
- 0x5ff3077b, 0xf22472a8, 0xc97d9efe, 0x006d3df9, 0xd726919f, 0x2d3e5a6e,
- 0xeb9c58b8, 0x82b66878, 0x9e171671, 0x9cb72bdf, 0xdbef1afb, 0x7ee4fe6a,
- 0x481def82, 0x161daab7, 0x97395e39, 0xa10cfb33, 0x387bf079, 0xdc386be5,
- 0xab9f2c0d, 0x839f975c, 0x8df70e65, 0xe65cf711, 0xab7831a5, 0x242753cf,
- 0xca8c2fbc, 0x67c874ff, 0x88d8753e, 0xe36a7674, 0xaaaf3c68, 0x614e578e,
- 0x797dd322, 0x058caed2, 0x634b8ebc, 0x0d7caafc, 0xf7d52fb3, 0x25cdbae5,
- 0x8750e780, 0xbd2bf988, 0xe2062872, 0xb53b6a1c, 0x769eb7dc, 0x65d77f11,
- 0xc411f25f, 0x0227a537, 0xcd7ba4f4, 0xf7d5f28a, 0xe037719a, 0xf1217cf3,
- 0xfe5c8347, 0xce4efd80, 0xea230ed1, 0x321fbdbd, 0xfdc074bb, 0x3a509649,
- 0x7be81fdc, 0x58f9052d, 0x17685a6f, 0xeccd93d3, 0xbd77b55e, 0x2c3c7813,
- 0x9647df89, 0xe5d9fa04, 0xf410730e, 0xf8c4fa33, 0x71ec9f86, 0xd1c3fbe2,
- 0xf436fc04, 0x53854019, 0xdfc4efd8, 0xfc4d2095, 0x7efc4efb, 0x0477ba79,
- 0xd9e5e5f0, 0x7c0b7fb4, 0x2eed8ddf, 0x806f7967, 0xe64bfd32, 0xbf6325e3,
- 0x7c0cde69, 0x64e17c2f, 0xc4d0a7bf, 0xdeb13beb, 0xc04ef467, 0x4ad1fc75,
- 0xe759065a, 0x55bbdef5, 0x7887169c, 0xe14de754, 0x245efa8c, 0x98d26a5c,
- 0x23c2a47e, 0xf0fb2e92, 0x03f32df9, 0x97c009bf, 0x363c33b4, 0x3e30348c,
- 0xf51a3f52, 0xa51b525a, 0xd55a13c9, 0xf761cec1, 0x9e22b06c, 0xa7eef57b,
- 0xde851e41, 0xaf7613d5, 0xc008d515, 0xf07130bf, 0xe78e72fd, 0xb3d65709,
- 0x2f73a27c, 0x6f9f4d9c, 0x678af381, 0x5515e735, 0x24ed1f3f, 0x1628fc06,
- 0x96531297, 0x116cf4c7, 0x377ec7e7, 0xc15ea367, 0x6ff207df, 0x847e8918,
- 0x00e50653, 0xc3518efe, 0x55d01d18, 0x1ef18bbd, 0x9f5b137f, 0x7a8e5f7a,
- 0x7c244def, 0xd9b2d35a, 0xef1091ef, 0xf2877003, 0xf024a249, 0xffde1a60,
- 0xa2ff0155, 0xa618afa0, 0x3f919b73, 0x185ca0d4, 0xe196cf78, 0xe83f7e5b,
- 0x3fbcb6ff, 0xeb3ae09d, 0x9018fe5d, 0xccca9fab, 0x53d8a3de, 0x6c8bae50,
- 0x69a7789d, 0x4f6bc812, 0xd63c5a5b, 0x54fc3f23, 0x9f2af560, 0xa07eb01b,
- 0xda07e817, 0xa78ebed1, 0x3219bf31, 0x8ca7b809, 0x8f900df8, 0x9f27caa6,
- 0x3ce0e920, 0x894db76d, 0xaeec7a01, 0xbd83b6cf, 0x1253665c, 0xc2e8c20a,
- 0x73c106f7, 0x37dc0aa4, 0x5f7e013c, 0xfc163dc2, 0x5aecfb75, 0x7ce4417f,
- 0x35d29a5e, 0x77febc2f, 0xedff4c69, 0x8a28fbe2, 0xdf9063c3, 0x2fbc4279,
- 0x77af78e6, 0xfb416f79, 0xe2dda231, 0x1e9cb1ad, 0xbd37de22, 0xf798affa,
- 0x4f7b43b1, 0x78f8cfdc, 0xf8371e9f, 0x19e01b85, 0x15baf985, 0xab9f199b,
- 0xe734bb78, 0xf3c65651, 0x1e5a53d5, 0x58e3dfc7, 0x0e7a7bb0, 0xf10b7c61,
- 0x82e3d2a0, 0xe80e7774, 0xa26da171, 0x62a2fb0c, 0xa9f388ab, 0xdb4c9a97,
- 0x5b33fbe8, 0x55dfa8f5, 0x499cf9f0, 0xde20c6f5, 0x28192224, 0xde48cfdc,
- 0xb75fd418, 0x891ddff1, 0xf76d0758, 0x0830549e, 0xcf0c4c7c, 0x41ec9f08,
- 0x1d5de0e8, 0xfc0169e2, 0xa3cc197e, 0xe4bf4045, 0x03ef3499, 0x76a6ee50,
- 0xdbffde3b, 0x59f78954, 0x8cfbc244, 0xb9f48bc9, 0x8547af98, 0x2a38e467,
- 0x9e017b3c, 0xdf1d2fa0, 0xf7cf728e, 0x4b140894, 0x425fb48e, 0xc74a7a7b,
- 0x826f8ff4, 0xdea99bf7, 0xcd9c80a2, 0x400fedfa, 0xf889d5ce, 0x1d65267b,
- 0x422409d9, 0x58dd835e, 0x189ccef6, 0xac9c985d, 0x7e31166f, 0x766c3f52,
- 0x7f6c42cc, 0xafa04ef1, 0xa12b8a93, 0xe8ddac20, 0x8178bef4, 0x9be55f06,
- 0xe3031aff, 0x71ea3454, 0x7a5e2a5d, 0xff909ce9, 0xbfa34536, 0x843537a8,
- 0xea78aafd, 0x83c06fa3, 0xddb44f4a, 0x1f32e95d, 0xa8fc8fc7, 0xe45bd33b,
- 0x164e841a, 0x85c7493d, 0xf15ab6fe, 0x1d6bc2fe, 0x1f478557, 0xc6bef9be,
- 0x5771e032, 0x75bffa26, 0x4c984aef, 0x6669b27d, 0x72e3ec3a, 0xdfc02f2a,
- 0x3e842e50, 0x3b247bc6, 0x6b0f788c, 0x0f25e6f9, 0x1fe578c0, 0xdf50751a,
- 0x58e6787d, 0x5e04579c, 0x07d29c29, 0xccdef7a3, 0x0c2bba50, 0xc09f547e,
- 0x27aeadfd, 0x0f38de6c, 0x7de14f6a, 0x1499bd24, 0x607c619f, 0xbbd33a76,
- 0x80d97b68, 0xc3eecdf4, 0x1caf5be9, 0x62395eb1, 0xa411efbd, 0xe2f2e26f,
- 0x647c167a, 0x05fbc1d4, 0x0391dc4f, 0x86eeb5fe, 0x6eaeb8a9, 0xec2c7bbb,
- 0xda74eeaf, 0x72fc20ff, 0x9d7413c1, 0xceb0df79, 0x6be23326, 0x43da75c8,
- 0xac37c8bb, 0x50e9c7d3, 0x4969e75d, 0x2bdfc189, 0xf012283b, 0x3cd2f897,
- 0x65626f1b, 0x9f289dfc, 0x6f83d19e, 0x31e63473, 0xfbb3b4f6, 0x403e55c9,
- 0x7a46bbc7, 0x743d21d0, 0x265b2b17, 0x106d7d02, 0xed8bc865, 0x5bf7186e,
- 0xeeaf1df8, 0x7a0ca28d, 0x83317742, 0x2807e51f, 0x3dd3bbb7, 0xb0f96277,
- 0xea8f7f1e, 0xdf5fd354, 0x1de173c7, 0xfae0857a, 0x42e71b3c, 0xf817ce99,
- 0x3dcb851a, 0xe3d55f4c, 0x9eebebfa, 0xff7a83aa, 0xfcf01bd6, 0xacf940c3,
- 0xa3457385, 0x4487d9a8, 0xdf3c7052, 0xaf782913, 0xca670a83, 0x1ec07361,
- 0xe501e152, 0xe1fa6339, 0xa0e7e3e2, 0xf7602f41, 0x067e7120, 0x7262c9f0,
- 0x0081ce02, 0x28f3831f, 0x48abc943, 0x47a913fe, 0xaf8fbcfd, 0x6571f968,
- 0x3e18efc4, 0x125e5118, 0x469637c1, 0xd44557d4, 0xe77cf953, 0xe4e7fe60,
- 0x2b5f2d0c, 0xfd5470e3, 0x041bbda0, 0x24cb43b4, 0xcff600c5, 0x7c98534b,
- 0xe988972e, 0xec97dc16, 0x44994b7c, 0xf0058d6a, 0xb70865de, 0xb57f6893,
- 0x472d3b46, 0xdb443e31, 0xcac21895, 0xe755bf2a, 0x878701f3, 0x7ecefcfa,
- 0xe321d281, 0x8fa41f15, 0x28af181f, 0x757eb310, 0x83abec02, 0xbe95da22,
- 0x21fc99b7, 0xf2da5d5f, 0x97ee03a2, 0x30bcc6cd, 0x7091fd75, 0x14bb6dec,
- 0xd7ebbf03, 0xe780dc73, 0xe3dacb93, 0xb2fed18a, 0x7b850687, 0xda9f5f0f,
- 0x15d48f5f, 0x6f5c2b33, 0xe1315d26, 0xd65aa3bf, 0xd8256976, 0x7e7e14b3,
- 0x9f8f8c31, 0x062f88ea, 0xd7fcb2bb, 0x7e70c5c9, 0xdaa196d6, 0x1acfcafd,
- 0x341cdf61, 0xe7a23fa2, 0xf83ab9ed, 0x0aede7be, 0xf78e5cfe, 0x3e9cf5b8,
- 0xc7e30e95, 0xfee7b4e8, 0x5b6fdc0d, 0xd764fbae, 0x0fffc0cd, 0x09ae6625,
- 0xeb9737f3, 0x7e1ed00a, 0x079a1f51, 0x7e7aa6f3, 0xaa57e41d, 0x1432d8fd,
- 0xf071af96, 0x0fe02eec, 0x15a636a7, 0x39e95b00, 0xdfed0238, 0xe5c70f9e,
- 0x247f68c8, 0xbc2f80b9, 0x339657a8, 0xdaeac57b, 0x1fdfd99d, 0xc671038c,
- 0x8a13839e, 0xf3d05fc0, 0x2d2f9b21, 0xb680ffa3, 0xa51e43f3, 0x4e8c6fda,
- 0xdd7904d9, 0xb47ad7e4, 0x3afa1e23, 0xb9ee113b, 0x1e0c3188, 0x41bb019f,
- 0x1abcd79b, 0xabdeade7, 0x2c57691d, 0x4f961e20, 0xa97f611b, 0xda4773f7,
- 0x69a41589, 0xd030976d, 0xb88aa45e, 0xfb009fc9, 0x456bfd5a, 0xef64bf79,
- 0xbef6a355, 0x9fdf3f62, 0x65c7e426, 0xa0363f74, 0xfcc029bf, 0xa0e2757b,
- 0x65efd771, 0x9e3ae264, 0xbcdbfe8e, 0x9ebc30ae, 0x49c911d4, 0x40d27ae1,
- 0xc182ce4c, 0xe9cbc6ec, 0xb40d9f60, 0x1fa2cf17, 0xbefc3ca3, 0x6ed03230,
- 0xc01c593c, 0x0d93bdbc, 0xc09efe22, 0x918ddaf5, 0x97bfabdf, 0x2c20c9e0,
- 0x6772191f, 0x3764dfed, 0xc2abe76b, 0xc77fccd3, 0xe2fdb222, 0xca37160c,
- 0x6e245afd, 0x7a1df7d8, 0xdd13bf3c, 0x1f96c5f2, 0xebb67d00, 0xe3054ce5,
- 0x0b7bf82b, 0xf988a0e4, 0xa7edbd7f, 0x39041e62, 0x1e1c7073, 0xd793eb23,
- 0x938c4507, 0x4a5db4f4, 0xed0a7880, 0xbec6e307, 0x405ca78e, 0xe3cd43bf,
- 0xfaf10cd1, 0x08eef9fc, 0x1f8f28bf, 0xc99cb4f7, 0xf94efe01, 0xb019a3e0,
- 0xe2be733f, 0x15756cf7, 0xf9d1fd01, 0x1bdefea1, 0xa5fa8cb8, 0xf41c5da9,
- 0x19f5aafe, 0xcfe3eb86, 0x8bf20325, 0xf7c467d6, 0x095ab3cf, 0x7ece4019,
- 0xb4c51e5b, 0xc3570b83, 0x4dbd33fd, 0xb77f0b82, 0xb9445db9, 0x3a3da0b5,
- 0x4cbc50a0, 0x72c1611b, 0xee764ef9, 0xf9388663, 0x2e6ff07d, 0x7fa220de,
- 0xf2cb48f3, 0x6798f5f7, 0xe58327a1, 0x5de7f461, 0xc6147c3c, 0xdc14fc59,
- 0xc4ff4312, 0x6fd00dfb, 0x8102d3e5, 0xcc884a9f, 0x779818bf, 0x144f35d1,
- 0xc05de607, 0x6907e5f9, 0x466d15bf, 0x3c0faff4, 0x1bc840ef, 0x21f7fd09,
- 0xbc6f0ee5, 0x9f6d28ef, 0xf96062db, 0x3e35667f, 0x0ef685d5, 0xd0f3b209,
- 0xa74f073d, 0x877d1e03, 0xb1fd07fe, 0xd20fed43, 0x0e3cf2ce, 0x57dfb066,
- 0xd2fafdcc, 0xda419e9d, 0x8b3cf237, 0x327f7abd, 0x5b47b1e8, 0xe83f232e,
- 0x6cfcc83d, 0xfc4ff643, 0x0aefe666, 0x570fd19a, 0x0edf2ad8, 0x83ea84fb,
- 0xeedf5eb0, 0xd377b3b5, 0xbd55f9b2, 0x6f95aa02, 0x0bf705b8, 0xdff08fec,
- 0xc9f75203, 0x53a71e5e, 0x791a47f3, 0x3f9a8dbe, 0x4493e6a2, 0x27cd43ce,
- 0x7c614c69, 0xf3c32f23, 0x945bd001, 0xe77ecfce, 0x68cf2233, 0xc8a1bca8,
- 0x71910773, 0x8ae24182, 0x46c0af2c, 0xc6a06e30, 0xbe540d17, 0x31d647c3,
- 0xd06537b3, 0x227bfd7a, 0xc5434fda, 0x1c75d51b, 0x79865139, 0x8b2f5556,
- 0xb0bfafe8, 0xbce3cf5f, 0xe9438c21, 0xc8617c4f, 0x7ece7e44, 0xcb47c95f,
- 0x5937def0, 0xd28efcd2, 0xe71e1c57, 0xd9f07233, 0x978fb923, 0xe47b7ed2,
- 0xf5e80332, 0x4a0b13fa, 0x9de8de40, 0xd7980665, 0xa6c51391, 0x4d9bc04c,
- 0xb6b37dc2, 0x53b71d5d, 0x3ffffe86, 0x1f012a80, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7db5ff00, 0x55945c0b, 0xe779f8da, 0x380c2b9d, 0xa5117280,
- 0x380a0ee1, 0xdb95902a, 0x9784268e, 0x4d32d45a, 0xe5450757, 0xdb698032,
- 0xcbbaeee7, 0x5acd4d78, 0xb5aca8dd, 0xbcc0c1be, 0x1a163b60, 0x25a3b614,
- 0xb68b9599, 0x3f9b5b99, 0x0286f328, 0xffb9f562, 0xcffebf6d, 0x3af39cf3,
- 0x7e988ef3, 0xbf67dfbb, 0xde73877e, 0x73ce7d73, 0x9339cf3f, 0x196e39a6,
- 0x9eb19fd3, 0xcadb2d1c, 0xc87b3b18, 0x630d81bc, 0xf7fc07ec, 0xacf2c653,
- 0x18036312, 0x319abafb, 0x3e57deaf, 0x7c81fb3f, 0x02d8c196, 0x316358e6,
- 0x33235a43, 0xbfd191af, 0x1d1fb01f, 0xf281ee9b, 0x988357f9, 0x5dafc237,
- 0xb63d14f4, 0x94357f9b, 0x3d424779, 0x3677af13, 0x4f285204, 0x1872f1c0,
- 0x9de912cb, 0x6edf2d22, 0xebf69cb2, 0xa613c2bf, 0xc53557ca, 0xf9a74e58,
- 0x47f8e5f2, 0x636ffc0c, 0x98c91646, 0x97627f93, 0xdb74fc5e, 0x913f485c,
- 0x5856091c, 0x9ed48557, 0xb10c0f7f, 0xef57ba26, 0x2d3ae330, 0x63f29bcc,
- 0x5e608ceb, 0xd5ae71bf, 0xf5a46abb, 0x2566e0f8, 0x6bd6f9b8, 0x5d7c3826,
- 0x38137d1d, 0xe8e0aac6, 0x05413feb, 0x4ffbebc7, 0xaebff1a1, 0xff49bb4e,
- 0xbfd06f43, 0x5f7f3555, 0xee3449bf, 0x0b0d0caa, 0xa4f486cd, 0x5e00cdc1,
- 0xcb235500, 0x1d80cc65, 0x795654c1, 0x66ad19c7, 0x75257b5f, 0x6cb171b1,
- 0x946f7c14, 0xfdf0dc0b, 0x25ae6592, 0x985d5219, 0xa1dbb186, 0x705ecebd,
- 0x086bf417, 0x41708f0b, 0x89ac133f, 0xc2efaeb4, 0x28301516, 0x08f06eff,
- 0x838f15d9, 0xfcc42a2c, 0xf2c541aa, 0xe37f1c7a, 0xb5f70c73, 0x0fc7c8ca,
- 0xfc332fd9, 0xba30eece, 0x777ea193, 0x7996c7cb, 0x06dfce30, 0x3ee0e639,
- 0xc909f32b, 0x3ee19779, 0x6dc726b3, 0x3d8c2185, 0x0dac616e, 0x50f6daf3,
- 0x725eaf5c, 0x405de7fc, 0x06afec0f, 0x77c90f56, 0x25aa4726, 0xcabed7c3,
- 0x01f9a7aa, 0x68b2c435, 0xa50d5f5c, 0x08574d55, 0x8916d6ce, 0xaf7ca5d6,
- 0x77043d62, 0x8851e586, 0x7d2b5a93, 0x16a4726f, 0x71e6fa66, 0xccf7ffad,
- 0x9fd00d2e, 0x433fff61, 0xdadd9e11, 0x906dfb9e, 0x60e45a7a, 0x11aef87f,
- 0xf0763974, 0x50ed5937, 0xfaed895e, 0xdbd8f631, 0xf30ca9e5, 0x9c2c9e86,
- 0xffb7c1f7, 0xe90ed591, 0x6fcbfb77, 0x50edf2c3, 0x6ef90adf, 0xcda54f7d,
- 0x6624bfaf, 0xf9466971, 0x0fb16ad2, 0xf7dbe581, 0xf3881caf, 0xdcc1d068,
- 0xa59c61c3, 0x474f2365, 0x9fd83a20, 0xb5b8478e, 0xec3d58e8, 0x54d35747,
- 0xe54af919, 0x43058c27, 0xf619bb3e, 0x83d9f207, 0xfb035b99, 0x93ffb953,
- 0x955fb8e9, 0x068b7a39, 0xbc341296, 0xbe02bdcd, 0x2d18e507, 0x2c53e212,
- 0xeccf5f1f, 0xfb62258c, 0xb7dc08bc, 0x2a310637, 0x41f997ff, 0x6bdbc71d,
- 0xbc7bc0fc, 0xabc601b2, 0x47efdb90, 0xa17c003e, 0xf2a5f11e, 0x668e6fa3,
- 0x4f46b158, 0x78cfee24, 0xd0f8171c, 0x369fa2c7, 0xac0ee16b, 0xfbe0fdd7,
- 0x2de8b06b, 0xf5c0e1c9, 0xb68c62b8, 0x68cfc47a, 0xbf14c277, 0xaacd7d7d,
- 0x4ff0f6a1, 0x221dbc42, 0xa07bbae6, 0x22587167, 0x470ee5fe, 0x30d2a87c,
- 0x3643f207, 0x077a8009, 0xe66165e2, 0xe9ebcc94, 0xd415b18a, 0x7b56dbdf,
- 0x57c735b3, 0x336993ff, 0xd07d1d33, 0xc12a6221, 0x0479ef53, 0x6153d9e7,
- 0x7d856db6, 0x827e0bf8, 0x334f2f76, 0x5850e578, 0x56bcce8f, 0x193a3c02,
- 0x0075bb3c, 0xd9b57fac, 0x73ae1ef1, 0xd7e343fa, 0x183a5e60, 0x788c5d61,
- 0x8b9ed459, 0x726d12fb, 0x3be3807c, 0x22db8e8d, 0x06978961, 0xc1fb523b,
- 0x08c2b356, 0x98566f0e, 0xfce7d859, 0x797c7cf9, 0x54b841a6, 0x36f4b808,
- 0x7c43f626, 0x5fad7aed, 0x74f98316, 0xca095869, 0xdf312e87, 0x988f2073,
- 0x712e9f1f, 0x4117d31f, 0x63bad2fd, 0xeb7eb9fa, 0xeecc60af, 0xfc7eb8c9,
- 0x301fb88b, 0xffd785fe, 0xa1afddf8, 0xf76fceab, 0xc004b0a5, 0xad22e913,
- 0xc71dbbeb, 0x9df58b66, 0xd63ff5c5, 0x87a713db, 0x073d3975, 0x887f9cf4,
- 0x527b69f5, 0x5d7d6c7e, 0xc27cb69a, 0xa5927d8b, 0xaed7de3e, 0x7e58f1a2,
- 0x497be02c, 0x9908d85d, 0xe20a59e3, 0x061ba959, 0xa55bc3f1, 0x8b3e051f,
- 0x5debbf05, 0x1413e02a, 0x5af2859a, 0xfe328f81, 0xccf800a9, 0xe1e4f6d6,
- 0x0b2f663c, 0xea7e70d3, 0xbe51fc26, 0x1eaa59cf, 0x30e22577, 0x1bf5cfcc,
- 0x66f34dc9, 0x2b86ff3c, 0xf21ebdcc, 0xbf95cd06, 0x21bd454c, 0xbd436353,
- 0xf0104b61, 0xfd8c1180, 0x8bcfec59, 0xe18c1fc0, 0xcb16be54, 0xfb7883a3,
- 0xee3567e8, 0x70bed095, 0xe1e1336c, 0x9b6695cb, 0x3115630c, 0x8530ac60,
- 0x47aecc79, 0xe63d7fb8, 0x61dbfb1f, 0x1de2839d, 0xfeb0f151, 0xb89a1139,
- 0x1c3cd0bf, 0x9c032743, 0xc70e68d8, 0xc207b840, 0xe8b30a7f, 0x36c65fb0,
- 0xa7ee9068, 0xe652f858, 0xa78e9c4b, 0xc70ebb32, 0xa839907b, 0xbd2ef1de,
- 0x1c1d019d, 0x3060f407, 0x8b9887ef, 0x373067ca, 0x979933a5, 0xb59cffea,
- 0x03a15e53, 0xfd39ffc0, 0x8d9ffe39, 0xb26f0992, 0xc7be01e2, 0x2f06b382,
- 0x7e4c7585, 0x6199352e, 0x0803359f, 0xf79b373e, 0xb1c38964, 0x1db8eacd,
- 0xf05bdfd7, 0xd0354bed, 0x25e8c68f, 0x27c6bbfc, 0x78100dc6, 0xa27ce3f8,
- 0x09e397ad, 0x06398390, 0xd8af70e0, 0xe5ed7bd2, 0x8cbd7093, 0xfe9e4859,
- 0x9e5fd04c, 0xb3fd666c, 0x6dd97c71, 0xa5d8b9c0, 0xbe42468f, 0xd6cc8c60,
- 0x5bde3cc3, 0xbede48ce, 0x13765c37, 0x869f20ae, 0x7e8bf7f6, 0xba998d27,
- 0xcbd41faa, 0xdb3dbeff, 0x20c1690b, 0x7eed97dd, 0x7fbe35f8, 0x4830aaed,
- 0xcba92427, 0x2d36b227, 0x065275c2, 0xf3f1fb94, 0xf5d5b3fb, 0xe198e00e,
- 0x2328db98, 0x0f8ccdfd, 0x18267fe9, 0x90d843b2, 0xbd1f641f, 0x9de9eb28,
- 0x0ddf4574, 0xef10d8f3, 0xb2fb8b98, 0x67afbef8, 0x2d33bd23, 0xca2468fb,
- 0x5d7ca3a9, 0x00dd025f, 0xd5d3b206, 0x7e80d120, 0x883e80ce, 0xb7a073f9,
- 0xdaa17a61, 0xd045e94a, 0x577bf0b3, 0x9ef28db5, 0xec72c2f8, 0xcbdaee77,
- 0x4e06475a, 0x6df0852b, 0x36b7c089, 0x8c13578d, 0xb255b4f4, 0x625c7ca1,
- 0x0c1b1b6a, 0x1f525bf0, 0x671d836f, 0x569e4d65, 0xb7b17e9c, 0x75b71f30,
- 0xad45e1c1, 0x055c5698, 0x6cbd078c, 0x1ff85cae, 0x7f5d0788, 0x7dda72f9,
- 0x7ab67e50, 0xbe7f8d14, 0x77e34eda, 0xfa501756, 0x37e3bc7e, 0x4b7b0f38,
- 0x15846b47, 0xe132e577, 0x1d0d7dcb, 0xe7c858da, 0xd23b25d9, 0xe676dde1,
- 0x6d3d0376, 0xb5b971d6, 0xd216e419, 0x29cc98e5, 0x50ca3e2f, 0xc71e38ae,
- 0x509c1ef1, 0xdcfd879a, 0x8b48aa3f, 0x9efa1ef5, 0x1f7888b1, 0x8f0cddde,
- 0xbf5f0059, 0x7844b6f4, 0xfd634978, 0xae59ea19, 0x0be93223, 0x2a985abd,
- 0x727bdff4, 0x7b05db88, 0x626f78bb, 0xc5b7f214, 0xb8546b3a, 0x0ceb5f1f,
- 0xbb9d6be0, 0x97f68f6f, 0x9ee19d77, 0xbe433eef, 0x4be705f4, 0x5e6733b0,
- 0x8e65be40, 0x76fee1b6, 0xf404bb09, 0xcf9460c9, 0x47417a95, 0xdf3057c0,
- 0x14e6c419, 0xd5f73e42, 0x1748b1d8, 0x7caa1e38, 0x7949df0a, 0x5f84b9f5,
- 0x6de37d5b, 0xecffccf7, 0x725fc805, 0x903a5c6b, 0xa7989753, 0x575c4deb,
- 0xfa86d99d, 0x0da49a63, 0xea784a5a, 0x934c3a26, 0xc0a5daac, 0xfabc7657,
- 0x303fc0e2, 0x1b181bd4, 0xdadfdf05, 0xe77c4c14, 0xd4ed9d2d, 0x22ff6c52,
- 0x53caff6f, 0x09b2fcbf, 0x462b27d3, 0x3ef112fc, 0x5ae09c3e, 0x21d2fbfc,
- 0x63436788, 0xbfa01b61, 0x5e486f5d, 0x99631653, 0xc4560735, 0x6d867cc0,
- 0x840cd0e9, 0xb49d7874, 0x21a1d312, 0xf8658705, 0x95bc5efe, 0x21b231e6,
- 0x72458e5e, 0xecfee819, 0xa87fa4a7, 0x9a8c92f5, 0x320763cb, 0x44327e9f,
- 0x7dc05cf2, 0x62721959, 0xb63fc904, 0xdbd9fa91, 0x99e3f532, 0x7cd00eb4,
- 0x7a45de70, 0xb70bc91b, 0xecf116ab, 0x46cd2392, 0xeba17afa, 0x4bdfdc79,
- 0xca1b488e, 0x571a7d8f, 0xff589de8, 0xf9d69694, 0x50b1dd46, 0x35fbe41d,
- 0xbe0998ea, 0x21ef0c57, 0xd83159b9, 0xc1dc70ca, 0x805bdd2f, 0xdc6ca9f0,
- 0x38fd4b5b, 0xea09368d, 0xd2bdec95, 0x8d94728a, 0xc464b667, 0x7f9e46af,
- 0x86dd9c62, 0xf6a4b572, 0x2b6f9e5b, 0x58217ca4, 0x3fac5a13, 0xcf69eb8f,
- 0xdac53909, 0x117f88b3, 0xfb7d5aca, 0xc67c04f5, 0x5de39bef, 0x3ecc8b31,
- 0xe97206f9, 0x8c59d202, 0x1b6fb79e, 0xe08e333b, 0x49728b72, 0x3d39e7e9,
- 0x4e509973, 0xacfcb9ea, 0xf8817e07, 0x17fffd01, 0xd1c8aff6, 0x6cca5958,
- 0x3ec77584, 0xb4adb067, 0xd338fade, 0x3921adfb, 0x5575e8aa, 0x89585f42,
- 0x36fda055, 0x804e43b3, 0xb90be671, 0x0cd6b4cb, 0x319e43d4, 0xa409b5db,
- 0xa3de81d7, 0x4c667921, 0x0658bd40, 0x4fd12f3d, 0xdf8733cf, 0x366b3c92,
- 0xfdb143db, 0x2fefd6ad, 0x3157f9e6, 0x444b424f, 0x31c85748, 0xf23de03b,
- 0xa127764e, 0xeb0357aa, 0xe790701b, 0x6dfa1213, 0x7aba055a, 0xfa958252,
- 0x7c11f801, 0xca19e761, 0x243ca509, 0xb841e39b, 0x47fa48c3, 0xe1a2c454,
- 0x9af0fc8b, 0x1123bd69, 0x5bffeb0e, 0xbfa84af6, 0x1bb33ffd, 0xbe7025f1,
- 0x3fdc0945, 0xb9890bf1, 0x97578834, 0x45af54f5, 0x8febbed7, 0x34a5aed0,
- 0xed7686c3, 0xd821e43e, 0xf49ea84f, 0xe61096a9, 0x99697a42, 0x7d46e91c,
- 0xa7b42dec, 0x88661e90, 0x7c4626f6, 0x40c665ba, 0x0d0387e2, 0xf35c1800,
- 0xaf6f034a, 0x2641f45b, 0x963cbff6, 0xc94ac7e4, 0xf48136bd, 0xcbe49935,
- 0x6a8fc149, 0x6533bcc2, 0x9cb9af28, 0x939c70c2, 0x61569760, 0xa22092bd,
- 0x7b309abb, 0x7dd7f20c, 0xdf132dff, 0x790e19ab, 0xf225f133, 0xb64cd4c7,
- 0xfe4184c7, 0x351fb161, 0x67faeeb5, 0x69c9bfb1, 0x3281aeb4, 0xe2f5445b,
- 0xe99f3f79, 0xfdc73b78, 0xdbd45ac1, 0x20c50241, 0x4e285efc, 0x2a07c866,
- 0x44cec613, 0xf7ec52bc, 0x28df82e9, 0x630363fd, 0xfc63ea2e, 0xf5f98cdf,
- 0x07aba426, 0x201d4c4b, 0x92c9d839, 0xbf682115, 0xbd90e83e, 0x1e5bd406,
- 0xd35fb3c8, 0x7fb0120b, 0xb3c24cfb, 0xf27ec562, 0xbdb843ce, 0xeb6463dd,
- 0x7d847f49, 0xdf1ebccd, 0x22633c2a, 0x52c7edfc, 0xf397a703, 0xd7482f38,
- 0x714a3b07, 0xe34d55de, 0xcaedfc23, 0x8757f319, 0xf18bdd12, 0x23db562e,
- 0x5ea1274e, 0x32a94050, 0xc14e329e, 0xea5da314, 0x818df68f, 0x4239aaf4,
- 0x7832ad0f, 0x4dfd21a7, 0xa31e3937, 0x642eca71, 0x7fd8bea1, 0x9c3f5a4a,
- 0x32fbf77f, 0x253d3c43, 0x3214f5f6, 0x45a7c46c, 0x4c2f8421, 0x8ebf1de4,
- 0xf41cfd20, 0xc737c21a, 0xde5286ef, 0xccc7b7a1, 0x1c5cfc47, 0xca71f84c,
- 0x729fbfc2, 0xcd7e1186, 0x87f95dfa, 0xaa7be00c, 0x78784f50, 0x3f2645aa,
- 0xca96dfcf, 0xb9c03d5e, 0x67d5ca6b, 0xd75da053, 0x3772afb2, 0xe2beda43,
- 0x3f9438f3, 0x4c5456b3, 0xcab376c2, 0xfc8fdd96, 0x3d7446f9, 0x441069cb,
- 0x35b6e1cc, 0xd711bec1, 0xd5ca7fd9, 0x03cbe47c, 0xcfcf9dcb, 0x0983f287,
- 0xcf88678e, 0x112bdbe8, 0x7d6f951e, 0x73fa8711, 0x7b2bf377, 0x6dfd215a,
- 0xfa79e388, 0xf8dee2be, 0xb099d8d5, 0xb0b52abf, 0xb73f805f, 0xc45e3a27,
- 0xbce355ef, 0xa2eed829, 0xe11f2dae, 0x9add96c6, 0xa5a17dde, 0x76849f7e,
- 0x254b5060, 0x0b3bb2a5, 0x7929d1e7, 0x8444a543, 0xb00be823, 0x6f168bee,
- 0xb9e21868, 0xb7cbc3d0, 0x5347d7ab, 0x077e148b, 0x91ee5768, 0xb3d226ed,
- 0x6f9c7add, 0x2872fd60, 0x58b77aa7, 0xbc3cc65e, 0xa9e9ac3c, 0x7b7ef8bb,
- 0x179fb0bd, 0xc56f2476, 0xf7b4befd, 0x3b7f1495, 0x7ebd3038, 0x17fd7cbe,
- 0x8e00bf11, 0x8744a117, 0x5060d5f8, 0x3b5d7fd9, 0xd5f85462, 0xbdd523b5,
- 0x762f8fde, 0x6cc1be09, 0x88c9dc9e, 0x2e4f76f7, 0x9f0a55ea, 0x164f4660,
- 0x9e696fd9, 0x1457b42c, 0x3d0ac33e, 0xf6ee5429, 0x7dfd60a4, 0x7d9acf68,
- 0x8aed96e3, 0xfdcf5dad, 0x364d2e8e, 0xc56e87e6, 0xcdefd2bc, 0x59ba97d6,
- 0xbba7caaf, 0x09d3f9d5, 0x73b69fdc, 0x83b15ea7, 0x30476165, 0x568fb2ab,
- 0x5c11afae, 0xe057aafe, 0x2e6c68f2, 0xafe00dfa, 0xe7379a04, 0xddb93be3,
- 0x23b86fbc, 0x62a9f916, 0x830bef9f, 0x51ca067c, 0xaf256f3e, 0xde7021c0,
- 0x20bafe2b, 0x967bfd16, 0x4e508d44, 0x3f88516c, 0x2f9c4d2b, 0xbe81d4ad,
- 0x4976819a, 0x5ad3c8c9, 0xd16c57b4, 0x1c1f5ac5, 0x6e1e6c16, 0xb85d3a44,
- 0x1fd1b865, 0x1f6e561f, 0xf30ad879, 0x6b5db8bc, 0xd4af29c3, 0x7d429fba,
- 0xd976e56c, 0xddf462e3, 0x17fa8768, 0x628f07cd, 0xb85b05bd, 0xbf69429f,
- 0x744e7370, 0x873cdfb1, 0x33c3576e, 0x0fcea3d3, 0x07e7526b, 0xf391aea2,
- 0xdc376f3f, 0x3c8fceab, 0xfd9fceac, 0x10d3a3cb, 0xd7644aed, 0x87ea3253,
- 0x461fe79f, 0xdf6e71b9, 0xdfe4a11b, 0x15b8a2f9, 0x9b85def5, 0x7d8670d5,
- 0x701f5093, 0x2e48936d, 0xe903ba96, 0x65ba6fa3, 0xd7e2b96c, 0x93c7f34b,
- 0xd56ae632, 0xbf5f5fc6, 0xd9a67993, 0x74b48fd1, 0x23d3c8f1, 0xe1defd7d,
- 0x7b47a4d9, 0x1bdc7027, 0xdb3329d1, 0x165f68ad, 0xeedfe28d, 0x7d963a5c,
- 0x6d882205, 0xf88f9638, 0x4484f457, 0xf5e8b6f2, 0x2f9177d4, 0x3199ec77,
- 0x0569d281, 0xcfc50f04, 0xf245b0b2, 0x32de4086, 0xfcede38a, 0xc19b92cd,
- 0x32aee7bc, 0xc541fca8, 0x58f3d41b, 0xbefea350, 0xdfc0e9b0, 0xc4bfe825,
- 0xe51e92f8, 0x4316c956, 0xfdcb1f80, 0x65e1ea0e, 0xd9d918e7, 0x183f7565,
- 0xcd73f2fa, 0xbae1d657, 0xb8fae19b, 0x07d3e78a, 0xf806634f, 0x857efef8,
- 0xfea11233, 0x32b5359d, 0x3982adc2, 0x9224b31e, 0x860de99d, 0x7d002c79,
- 0x9069f509, 0x2baeb4b7, 0x0db9fb9b, 0x4cce54f1, 0xb5857e50, 0xbe1ca2e5,
- 0xe36218d2, 0x5cb6b0fe, 0x4217e40b, 0xc256e11e, 0x9c7c1236, 0x8e657fc8,
- 0xf9bf762f, 0xe7f93ee2, 0x8fae46d9, 0x03deb53b, 0xd6728708, 0xff70ed4e,
- 0x6139ebfc, 0x51c3275d, 0xcf6808df, 0xaf0fe46c, 0xdf69eb32, 0x307e9aaa,
- 0xec577ff8, 0x512ec500, 0x59ff6dfc, 0xe21070f6, 0xfec96af5, 0xd4c651bc,
- 0xf115a7bd, 0x724cd4b8, 0xce5ae1fe, 0xd9d06bcf, 0x6cd7fd02, 0xf37d274a,
- 0x829ec961, 0x4c9b65eb, 0x1e810764, 0xdb3abf18, 0x3e81d7a7, 0x9fa132e8,
- 0xbdc834b8, 0xe70fbf15, 0x8ccd79f6, 0xde17d214, 0xe45e3c92, 0x3867aec3,
- 0xe64cd4bd, 0x64f353f8, 0x0cff7d0c, 0xfa831aa7, 0x6a4bd722, 0x3d72a536,
- 0x60f3e656, 0xfe210bbf, 0xe62f1358, 0xf34ac035, 0xc9f5f452, 0x8973c716,
- 0x5e2ceb7e, 0xf4247a01, 0x995bfc5f, 0x95829fa1, 0x3c92dc44, 0xaa7217af,
- 0x8dc99367, 0x52d3eefe, 0x3f9e2b61, 0x13dfb35c, 0x1dcfdf39, 0xea26df6b,
- 0x58bc5f91, 0x4ffd7933, 0x3567bc71, 0x7ef195d6, 0x53dbb7f0, 0xbd3fcf50,
- 0xf70234c9, 0xce70d4e9, 0x72c773b7, 0x25d801bf, 0xee90adf6, 0xfca8d449,
- 0xb9127bab, 0xd13fb09d, 0x3ce9e94a, 0xc90c47ee, 0x0cff242e, 0xf1f115ec,
- 0x17ec75c0, 0x85f58aed, 0xc7d27e47, 0xb0f8147c, 0x4e7f7c71, 0x5c91223f,
- 0x58a4f584, 0x7bfb9f20, 0x4e75f913, 0xeca2f90b, 0x0e51e00b, 0xbfc15bc9,
- 0x49fc459e, 0x27f014c4, 0x51fc2fbb, 0x60c3c7e3, 0x7f1098ef, 0x1f683f00,
- 0x327afc15, 0xf011f693, 0xe7a1f087, 0xf00dd349, 0x285f6d47, 0xe5a9adeb,
- 0x5da047f6, 0x3270f801, 0xa0bcefd1, 0x0427ac26, 0x3c14b7cf, 0x8e775a60,
- 0x205a39ff, 0xe6c9e41e, 0x4befe434, 0xea1b20a4, 0x7f844bdd, 0x467cc97b,
- 0x8b658df3, 0x68d7a424, 0x0ec895e6, 0xec266d66, 0x003d27ef, 0xfc3a3f73,
- 0xf32355e9, 0x58637b97, 0x8f7f2a98, 0x3f554631, 0xfaaf12cf, 0xba746f7e,
- 0xeb78fbea, 0x627e5570, 0xfaaa1dda, 0xa8c6d9f7, 0x351b3ff2, 0xb27f555e,
- 0x6f2ab27d, 0xce2d1667, 0x60baa5bf, 0x6f1fda24, 0x5e921757, 0xd1970810,
- 0x5baf8386, 0xea46206d, 0x00b453b4, 0x0efdd1bf, 0x7c87892e, 0x14d33aff,
- 0xe8c7e02d, 0xe25783d8, 0xd5a2602d, 0x43eff105, 0x80495e0f, 0x305d747c,
- 0xc8c5dfcf, 0x67581f1e, 0x9332e29e, 0x093630bf, 0xeaed3ce0, 0xf66843a2,
- 0xca7cb27d, 0x75a478fc, 0x3ff33267, 0x7566d8b7, 0xe53d6184, 0x547f52bb,
- 0xefb52152, 0xfcf9ccbe, 0x393fb827, 0x760a7aff, 0xb18fc917, 0xac6c341c,
- 0x5be74cd1, 0x78bba8cc, 0x7c0cafcd, 0x8633b253, 0x6a96b9fe, 0xc22d67d8,
- 0xb7a948cb, 0xc1e942da, 0xdf4a68ea, 0x62b2b6ad, 0x756b6780, 0xab87a51a,
- 0xa47e546d, 0x1fa5147a, 0x3d29db56, 0x69405d5a, 0xa521755b, 0xb34f2812,
- 0xb36c6f90, 0x3c21d5ad, 0x33b0da5c, 0xd9fe3e30, 0xe1f2df17, 0x519d96ad,
- 0xff2a15f6, 0x4dcf64ca, 0xb20d75a2, 0x945b9f90, 0xa9ffda1f, 0xe8d1f915,
- 0xf5e1236c, 0xd59b7368, 0x48f3cd98, 0x99977567, 0xebca1357, 0xf5ebfd69,
- 0xfe470cf7, 0xa669da30, 0x50bd497a, 0xbdeb0b2f, 0xf2c5a317, 0xca1b7a45,
- 0x3f04e7cb, 0x901cd10e, 0x5e909c71, 0xc834367e, 0x144ef9c0, 0x5df85fa8,
- 0xf5d5a3f1, 0x8706f1f2, 0x9df3a22f, 0xc4cdb3c1, 0x15b9147f, 0xc18de11b,
- 0xd12ec5f9, 0xe6887953, 0x2efd15b8, 0x09ded55d, 0x84e3af88, 0x67a71f9c,
- 0xa60f3869, 0x94f92209, 0x1adf7f27, 0xcdc5f90b, 0x398c70d2, 0xdc286718,
- 0x96a1f642, 0x6feb31d3, 0xb6b8fae2, 0xa815f4ad, 0xd6323c77, 0x15a11eb6,
- 0x81258fbd, 0x5557959e, 0xf2728190, 0xf448db38, 0x31d43f3d, 0x6a6df10f,
- 0x46bdd006, 0x13f40920, 0xfc4c105d, 0x6a7f7bb3, 0x53cdea0e, 0x0cbdd60c,
- 0x292ca2e8, 0x4a7ef087, 0x648e6b3f, 0x445dfcc1, 0xaca25327, 0x9e1b257b,
- 0x194ce49e, 0x71bfc777, 0xd2493d2e, 0x7ca9c7fa, 0xc31e3922, 0x5c1455f9,
- 0xf5f9f3d2, 0xebf89e90, 0xb3f12b24, 0xc9190701, 0x21f19edf, 0x7fd15fc4,
- 0x61f918b5, 0xeb073586, 0x427ae9c5, 0xfba0ee31, 0x5dc52d7b, 0x07d0cd40,
- 0x2f1efcfc, 0x8c78f0b5, 0x9a1bbc40, 0x554de5cc, 0xaa038f12, 0x291a368c,
- 0xcf9cb96d, 0x30a24e28, 0xd036ed09, 0x5794fb1e, 0xdcb99383, 0xe7a35f8b,
- 0x49643afe, 0x107b6530, 0x8c2ef253, 0x2c7da907, 0xecee5148, 0xc7a64e00,
- 0xe87f9476, 0x5492e3f7, 0xdf58edf5, 0x11d99df7, 0x9dfb4a9c, 0xbf7e9375,
- 0x43c62b4a, 0xdcc0597c, 0x7e4084b8, 0xb87245fe, 0xfb411e72, 0x137f62fc,
- 0x324993d9, 0x71e037e0, 0xfc87b06c, 0x8e26757f, 0x9e1a49ef, 0x77f869d6,
- 0x93e8107d, 0x790c1f90, 0x3efa773c, 0x1e49e1d9, 0x0599ed40, 0xa87bcbdb,
- 0xd0f30c7d, 0x28f7ca78, 0x9d435ef4, 0x304f2041, 0xfa6b2d1d, 0xe498db84,
- 0x7d211f31, 0xf91f0177, 0x775f8fda, 0xf52e8705, 0x6c4aa7df, 0x376ff66f,
- 0xed29da96, 0xd86a962b, 0xffc411d7, 0x922a5f08, 0xb7377634, 0x5095df37,
- 0x7a6d604f, 0xbb4a6b94, 0xbeefc013, 0x05ff7806, 0x27a61ff8, 0xf8e1ef81,
- 0xc3df019f, 0xf7c06ff4, 0xf014fcb0, 0x81db4c3d, 0x97f961ef, 0x9d30f7c0,
- 0x1b243336, 0x69aaa4e9, 0x855afb0c, 0xff873af7, 0x3189ddf9, 0xd9cbe37d,
- 0x9ed76e24, 0xfbfbef88, 0x7c71277f, 0xdf37713a, 0xd7906eb7, 0xfe019fa8,
- 0xdf84b2ad, 0x87776e58, 0xef9e73f0, 0xd77eb8d2, 0x5ff3c31d, 0x3fa8e926,
- 0xc66d86bb, 0xe9a5dff6, 0xe649ef29, 0xf85ba372, 0xa8ff012f, 0xc31e657f,
- 0x7aaa4a86, 0x814d24ee, 0xdef98fbb, 0x23c7cc9d, 0x1c3d44fc, 0x0fde31f1,
- 0x84ad2b3f, 0xf178819f, 0x249ba085, 0x58bbc703, 0x27c8f1e4, 0xbe744ca3,
- 0xe3b5f30a, 0xc49d7479, 0xfc3af1f1, 0xe77b70d4, 0x7e84fc3a, 0xe7804e08,
- 0x093fa412, 0x35251fc0, 0x45b77988, 0xe082fc86, 0xa0b3a2dc, 0x3227efff,
- 0x6bdb1600, 0x84ce8f7a, 0x10c8d8f2, 0xe41d9e2b, 0xd45e6e3d, 0xebb8ff17,
- 0x35ff5ddf, 0xffaf547a, 0x738b75ba, 0x375d5b93, 0x97e413f1, 0xf07d3f88,
- 0x1fc82187, 0x33f87c72, 0x849ed926, 0x264b74fd, 0xbb81fa2d, 0x022f1c4d,
- 0x1a5dfbd7, 0x3f055fc7, 0x18fc40be, 0xbac3fd80, 0xb9eb7d12, 0x80a0ff36,
- 0x14642df5, 0x8fb8110f, 0x5bf15f0a, 0x39c91dd7, 0x2601b83e, 0x041efc92,
- 0x71fd1bf2, 0xc70b649e, 0x676701f3, 0x81f9426f, 0xffea0272, 0xfafdc341,
- 0x56bedf0a, 0x2673c92e, 0x39f8a867, 0x67b07b43, 0xcbe881bf, 0xaf2561ab,
- 0x43825da1, 0x8f59d9f9, 0xf6f5f325, 0xa0d64f4e, 0x9df5d4de, 0x27f145d9,
- 0xa14e7b03, 0x59b5d67d, 0x6d3db8c7, 0x3c81249f, 0x057e8f9b, 0x8dc5fa2b,
- 0xa17b6e74, 0xd43d991a, 0x853e5cf3, 0xf3d56176, 0xe8023332, 0x9dbfe7e4,
- 0x60b2f886, 0x7a82cebf, 0x4fcdcac7, 0x3b7c461f, 0x515928d3, 0xc23577de,
- 0x457ea1b2, 0x04db884d, 0x8f21f3f5, 0xf59a17f5, 0x8f1f2b6e, 0x18a74cf4,
- 0x65536bef, 0xefa5fa02, 0x70475e79, 0xc783b05e, 0x79b3bc31, 0x9f639d09,
- 0x0a2c4b71, 0xcbcbe5da, 0x9fd0635a, 0x3364a2f8, 0x39a73b40, 0xefda3cff,
- 0xcd983b65, 0x3d8afe8b, 0xb2be7421, 0x7f1d46a0, 0xa4dee250, 0x64a27d47,
- 0xacbcba8b, 0x9d879d4e, 0x6ceb7e21, 0x3c33c750, 0x15e22c92, 0xf270d9d2,
- 0x9384d633, 0xd3f0a01e, 0xf631d91b, 0x324f9cc5, 0xfa244df6, 0xdffde549,
- 0xe6697dc6, 0xdf22c9f9, 0xdf4bf901, 0xe0517df2, 0xbf9ca952, 0x4f6cb0c7,
- 0x99dfc636, 0x55c7682c, 0xca157f36, 0xa82cee30, 0xcfa27efd, 0x538a6537,
- 0xbb24d75a, 0x2d15be10, 0x3e3197a6, 0x31ef72af, 0xe10435bd, 0x01e908fe,
- 0x1ad732f7, 0x1abcbfb4, 0x3c236b0d, 0x15ff236a, 0x202cf7b3, 0xc9b370bf,
- 0x6f3de742, 0x133ada7e, 0x66257bf3, 0xdc1c7dc2, 0xe0b2784e, 0x75ce9979,
- 0xb93e6a19, 0x71913c3e, 0x3d9f715f, 0x16bf68fd, 0x3ee3bee2, 0x3ee3bec3,
- 0xd89fb8cb, 0xe6ef443e, 0xccedc278, 0xfef9db33, 0x2f9efb2a, 0xdf93d06f,
- 0xf3ef96b8, 0x3fd7cf3d, 0xa078441b, 0x680f0263, 0xe16ccfdf, 0xbfdfaefb,
- 0xf1103f5a, 0x0f0036b7, 0xf0d70d9a, 0x1d77e700, 0x7fec041e, 0x07cbf0a9,
- 0xfee041e2, 0x44f82bdf, 0x10fa3c9e, 0xfe2cd9c6, 0xf1571f05, 0xef0ecd73,
- 0xaa0478ac, 0x11ff1a9c, 0x392cdd9a, 0x049635fa, 0xb421bd72, 0xc0f909b0,
- 0x86bb09f1, 0xfc099c53, 0x9c524633, 0xddefc11b, 0x053dfd5f, 0x7e3bbfe9,
- 0xe23796f2, 0x703aff69, 0xc161dd1d, 0x96ee7e5c, 0x1b9512dc, 0x538006bc,
- 0xa451f01e, 0x81b6f643, 0x07ba91ce, 0x31e8f43c, 0x693f77c8, 0x48f6e1b6,
- 0x951f6e76, 0x1277bcb7, 0x31ac86fd, 0x9fb2aecf, 0x8e537d84, 0x6f7e15f6,
- 0xefcafb00, 0x7cb24e3c, 0x4f3eed44, 0xcaf5a04e, 0xb266db1a, 0x9598ea83,
- 0xe3af63ce, 0xbdf88cf7, 0xa1ba07e2, 0xf7c0163e, 0xeb9efc7d, 0x2835cc61,
- 0xb14be90c, 0xb47e14b3, 0x0f4bf850, 0x1b44763d, 0x03aceb81, 0xb5bee3b8,
- 0x8fea1f00, 0xdb9d3d7e, 0x8dd1f92a, 0xf1167fa8, 0xce78e00a, 0x469f68b5,
- 0xd332fc46, 0x0f029d7c, 0x605f112b, 0x07d9659d, 0x775f5142, 0x6ce1fe0a,
- 0x497f210e, 0x8f98db19, 0xe30655f8, 0x9bc0fb79, 0x487bedb2, 0xde19bfcf,
- 0x655bfa28, 0x3fdebaa3, 0x250c9f90, 0x03f9927e, 0xfc69dfe0, 0x37c7c73b,
- 0x7e8ce4f2, 0xcbdc0718, 0x6e90fdac, 0x52d7246f, 0xfb290337, 0x36ee9bf5,
- 0xcfcaad32, 0x33e5516f, 0xfaaad13d, 0xaaac9ac3, 0x69bdc3ef, 0x0f23efaa,
- 0x9cf954db, 0xfaaa51b6, 0xabb49fb7, 0x17b477f2, 0x75dfeaa8, 0xef9550ae,
- 0xfcf580cd, 0xbdd739c8, 0xfeaa92d1, 0xd549ab78, 0x042a683f, 0x6169899f,
- 0x335ef2aa, 0xfa8dd387, 0xeea6cfbd, 0x7f6fb157, 0xffdd4a36, 0xdfbabb64,
- 0x6d87dd5b, 0xa0b52720, 0xb9076f6f, 0xd04ee989, 0x6fa0b5cb, 0x8e5e8037,
- 0x2f4157f9, 0x7a03d4c7, 0x06bf9639, 0x1be6397a, 0xfcc72f41, 0x3023b03e,
- 0x405d54df, 0x85d59be9, 0x78337e54, 0x0f718ab5, 0x888f718b, 0xc4db1971,
- 0xe04dfee5, 0x7f68a1f2, 0xc36fb454, 0x3c3e49f6, 0xd64828ac, 0x1d3a055c,
- 0x8f5e7e13, 0xc5f65ae7, 0xd768f9ed, 0xb32fbcf7, 0xcc2740ad, 0xdd5c3ee1,
- 0x0452e51f, 0xec2faf3f, 0x0efd00f9, 0x2d137b95, 0xaeb06e78, 0xf8a3e3e9,
- 0xb651abbd, 0x6c1ddd22, 0xfb142afa, 0x141578b9, 0x9e4291bc, 0x77f9de41,
- 0xf0f5f946, 0xc7d5e31d, 0x964501ef, 0xe48794e4, 0x2524c5d4, 0x0e7ba6ef,
- 0xf47b0d85, 0xb6fe74ed, 0xefbfbe87, 0x6fbfa9d1, 0xb77d55af, 0xf73c7d60,
- 0xcec9bad5, 0xf4a4d0be, 0xcefaa5e7, 0xfa8ec924, 0xefed85f1, 0xb738c1ac,
- 0x11453d8a, 0xde567e78, 0xde722c70, 0xd2ffc08f, 0xc8195dbe, 0xa19a2bd7,
- 0xbfafb33f, 0xc89d668a, 0x933bf9f3, 0x2387e4f6, 0x18906edf, 0x6c8b928a,
- 0x950dc523, 0x913bd537, 0xcda7952f, 0x4e39e1d4, 0xf61647b7, 0x73c38f3f,
- 0xc7d7185a, 0xe742573c, 0xf27fbf41, 0xe31fba1c, 0xde5bba69, 0xbb71c509,
- 0xdf869ef1, 0xc2913efe, 0x5227daf5, 0x8b87bdf8, 0x6284ef8d, 0xcf3ac5fc,
- 0x5aee1c3b, 0xa0ffad2f, 0x4a4377c8, 0x69926ef0, 0x3557a5fd, 0x7f4a0fb4,
- 0xd4c8a6cf, 0xe4a6f8cf, 0x71d75c10, 0x8dcf1f0f, 0xce3005c1, 0x62a2a4f8,
- 0xe891ff9c, 0xe9323919, 0xdc6fdc75, 0x3d62643d, 0x8e7813ea, 0xf5dd97de,
- 0x55b7e89a, 0x9fbdf7c4, 0xf22b7af4, 0x110523db, 0x880649c3, 0xb8533b7a,
- 0x77af919d, 0x389ca124, 0x1f92b66e, 0x62414579, 0x41efee08, 0xe0bcb14c,
- 0x97cbf265, 0x8ef1f235, 0x1142da5b, 0x8e378eef, 0x516f5194, 0x71c3abfa,
- 0x6facf8fd, 0x4fb45cdf, 0x335aee25, 0x3fdbe3f6, 0xb14eee5e, 0xee23bb50,
- 0x3f50d363, 0x4c169e3a, 0x9eab45fa, 0x37977b9f, 0x78f6fd70, 0xecad6c4b,
- 0x16e15e77, 0xa69dd1fb, 0x6aed7da1, 0x337a89d2, 0x9eaa99eb, 0x9d57ef8e,
- 0x77163e7a, 0x57a853c7, 0xe9945f3b, 0xb7538eee, 0x7fd71228, 0x7e7a8b76,
- 0x4ece0225, 0xd232379d, 0xcd9d5f0f, 0x4cc6e8d7, 0xd0acde78, 0x53f69589,
- 0x69e3c7d9, 0x1e3b2f5c, 0x390befcd, 0x5e13d4f7, 0x5b7de4fb, 0xb11dea3c,
- 0x4ee3c1ff, 0x2ad7666f, 0x5d9f80fa, 0xd3aed0c4, 0x68e62415, 0x3f727c12,
- 0x79fec52b, 0x97b400ca, 0x040ec90a, 0x3f210f64, 0xfdc3ea08, 0xedfeff90,
- 0xb7b71c59, 0xd440f411, 0x134d8c83, 0xaf4afef0, 0xe604080d, 0xe745bbdb,
- 0x198bf616, 0x4205d2f5, 0x756b3d2f, 0xbe78cae4, 0xeb435cb8, 0x81dd8272,
- 0x825d8a71, 0x13da5ddf, 0x07d233ff, 0xb416cb0e, 0x70f1ee67, 0xc0d9d63d,
- 0x4f4ad2f5, 0xa346effc, 0xb3a0ddde, 0x535a0559, 0x2fd0ac5c, 0xf5bd08ce,
- 0x3d1ef2cc, 0x25fb27d9, 0x5ff434f6, 0xce89b4d2, 0x7e842bab, 0x90372151,
- 0xb370b09e, 0xbd002f5a, 0xdf2f9545, 0x0837a81e, 0x5d47907f, 0x7277d8ae,
- 0x21fd35ea, 0xd011ed1d, 0x0e90a34b, 0xdcad53a2, 0x93ec266f, 0x28b69925,
- 0x5a75f7a4, 0x4fc504eb, 0xdaaaf080, 0xce297aff, 0xb20ceddb, 0xf4b0bd91,
- 0xf76b824d, 0xe90edc37, 0x8f04668e, 0xdbe1c66e, 0xbbf1c4dd, 0x8db9274a,
- 0x95d01ed8, 0xee4a33fa, 0xba87a8e5, 0x2f89437a, 0xf4805631, 0xb70678b0,
- 0x0be8ed37, 0x850bf485, 0x29f9140e, 0x5bbfba71, 0xf9872edb, 0x54e487f1,
- 0x138e77ae, 0x424b3b71, 0x06bf246c, 0x9d9eb91a, 0x8e19e257, 0xec1030f8,
- 0x9f9f8368, 0x2dd9a07a, 0x52babd61, 0xe45717ee, 0x45ad64f3, 0x7e2bfd87,
- 0x4cfce522, 0xb7895fe9, 0x16ff69bf, 0xebecdfe8, 0x0fdde01f, 0xdb257de1,
- 0x6e39f246, 0x6d2f72b2, 0xb2a3d111, 0x6f808b9e, 0x1f451fe8, 0x739bee0a,
- 0x7e7c81cb, 0xf746ddfe, 0xf943f2cc, 0x5c45f23c, 0x4f107e73, 0xbf72a4c7,
- 0x0e54cacc, 0x2a9166b7, 0x549beb7c, 0xc854d8fb, 0xf23aa7b7, 0x42dca953,
- 0xdae4b9f8, 0xa88c807d, 0xeef83ef6, 0xbdf88fe2, 0x0f402bbb, 0xbe7e7fc8,
- 0xa926b248, 0xe78e22f4, 0xe308bc55, 0x468c4e1f, 0x6decb838, 0xce789169,
- 0xce6be9ce, 0xc9359352, 0xec2e4fdf, 0xc4db0c2f, 0xd1529c73, 0x4a52c4be,
- 0x4b1c15f7, 0xd7e8ad23, 0x487a42af, 0x07fe39b8, 0xdbfc3de2, 0xc956f882,
- 0xde7e360c, 0xa6ddf81e, 0x417b3d45, 0x09c45d00, 0x4875ad3c, 0xfb598e74,
- 0xb9fb96bd, 0xd7e44966, 0x790a107a, 0x57a8b7bc, 0xa3e28632, 0x9d2c841e,
- 0x17f4d503, 0xe9fdafe7, 0xb101ea7c, 0xdc4507fe, 0x279d21c0, 0x8730fd1e,
- 0xcdf9f82a, 0x73a1e60c, 0x8dac59e2, 0x95c113d2, 0xb9d4bd7b, 0xd1da306b,
- 0xe40c3a9f, 0xb55da9ff, 0x6bf90435, 0xc1655b16, 0x93202373, 0xbc8c3fed,
- 0x78119eb1, 0xbdc4a4be, 0x9edcfb2a, 0xf11ab85a, 0x51ec1ce0, 0xdbeb88f4,
- 0x97b27f97, 0x1f3a69e2, 0x43da7d7d, 0x1e9bed0c, 0x5b28778a, 0xee9a3c34,
- 0x5b58b855, 0x7f6fae5a, 0xf654fd95, 0xaaacca0f, 0x0cb5857d, 0x674cf802,
- 0xe95eb93d, 0xc0a9fbe6, 0x33d74e39, 0xf2094115, 0xe050f88b, 0xaf702b3e,
- 0x3dc48b64, 0x674745a0, 0x5787fd40, 0x4fa8ac69, 0x37efb75e, 0x89af1fd9,
- 0x4886f27f, 0x68dea764, 0xfa7d94bf, 0x742fb8b9, 0x3bb78c32, 0xfc9973f9,
- 0xfbdbff7d, 0x63aa4df5, 0x3bc92a7f, 0x1b749f4b, 0xa237a748, 0x034b39cb,
- 0x4e8037e8, 0x0da5d1af, 0x3fdbf3fe, 0xa250d2c7, 0x9d7f6547, 0x517fb056,
- 0xd884b5fe, 0xfdfaecdc, 0xe7163b44, 0xb128d653, 0xa15ba417, 0x7bb276d7,
- 0x700bf703, 0xe0f28ec5, 0x553a00f3, 0x7c46f1f6, 0x277be14b, 0xbb9e5cf4,
- 0xfce9931e, 0x7bc90bf0, 0x2c7c82c8, 0xd7dd38fd, 0xb17fea52, 0x23f06dbc,
- 0x6317cfd0, 0xcf427a78, 0xbc94f9e3, 0xe5fb883d, 0xb83188be, 0x485ffd70,
- 0x9e5163e9, 0xc7fd217f, 0xa51f3cfd, 0x467e62b7, 0xe40b58d4, 0x3f14e84f,
- 0x87c10ade, 0x3c7fdcdd, 0x5471f6e3, 0x32ef624f, 0x2ff5bf7f, 0xcf5bf225,
- 0xf38e9601, 0x5cfb1f8b, 0x9f940241, 0x70e255fa, 0xac5b5f3a, 0x62e50fee,
- 0xb8fff93c, 0xd5f776dd, 0x86515d1e, 0xf26b9c6f, 0x5e65dc6c, 0xf64c9c5e,
- 0xad808941, 0xdb9d3c3d, 0xcf7e6ea9, 0xbd379150, 0xfb375f87, 0x0bcf27fb,
- 0x7cb5ee7f, 0xfe7193fa, 0xb6c0eaf2, 0x9fb05227, 0x0b2bbd12, 0xab9f1bef,
- 0xca1c43fd, 0x8f6d92f5, 0xb99e90a7, 0xda0a5d6d, 0x9f5b250b, 0x3e53b148,
- 0x8af641d8, 0x73bbaf96, 0xaf2f1df7, 0xeb6bd3f7, 0x3f9eb9d3, 0x0f2078cb,
- 0x4309cdf5, 0x3f46ad2f, 0x24aff278, 0xd6f44c8b, 0xe0e51ab6, 0xef8e34ec,
- 0x7c48c6ac, 0xa2fde199, 0xbefed8fe, 0x47c7e43a, 0x15d2bed2, 0x34ecbd43,
- 0x3663c12d, 0x82886f73, 0x64ad6cef, 0xf5fe67a9, 0x6139d307, 0x1f492ad1,
- 0x5be51fdd, 0xe3b470d8, 0x68c2d3b2, 0x0ed7731e, 0xd9f2c56f, 0x04f978cb,
- 0x38f1bb83, 0x9e9cf3f6, 0x804067e2, 0x9bc7f825, 0x3b71a767, 0x8906ce6a,
- 0x9c656bf4, 0x6b2367e4, 0x9d99d7fd, 0x39f3e426, 0xe521f137, 0x65a4db1e,
- 0x868ddec7, 0x1d6a0f7e, 0xf7c1a677, 0x499ccfa3, 0x2e333e42, 0xda067cfc,
- 0xc77ac919, 0xeeb8a50b, 0xcb8a06ad, 0x958aceca, 0x88fea0a3, 0x8d3cc747,
- 0x45659ce9, 0x3fa2942f, 0x3871b375, 0xf3e56f0f, 0x35592c5b, 0x53be3f68,
- 0x845cd0fb, 0x8c67b9db, 0xae2f1fa4, 0x3f628d4d, 0x02bfef62, 0x614d6ffb,
- 0xfbd8076c, 0x7b02ee98, 0xed4bef1f, 0xfca68eae, 0x94adab1f, 0xbf1ce9b2,
- 0x1f385b16, 0x237f51b9, 0x02b78ec1, 0x0b5ec91f, 0x78fe81fd, 0x107f6f46,
- 0xa43c99d7, 0xb13aeb62, 0x3f6864ae, 0x0f7f15dc, 0xdd7b21c2, 0x5aa8ad23,
- 0xe7e3498e, 0x5f1c1f7a, 0xf1fa471b, 0x4a978eb2, 0xb486fbe1, 0xded8d9c2,
- 0xd932e5b8, 0x3f34efef, 0x5de11b3e, 0xd7c0d5b2, 0xee7dd627, 0x17a89499,
- 0xfbd77fa0, 0xaba7b23a, 0xb4bc74b6, 0x1b79d20e, 0xe3fbd11e, 0x77aeadfb,
- 0xcdcf9896, 0x7046eae8, 0xd5d39ff8, 0x3f447113, 0x32ae815b, 0xaaba75fe,
- 0xe09cb65a, 0xe15a5af7, 0x9fc834ea, 0x90e2b9d3, 0xffa5ce9e, 0xb5dcf084,
- 0x2bf8225f, 0xbf6955fc, 0x9bdb8d32, 0x06cf1ae5, 0x7f04efd2, 0x3a2c16fd,
- 0xe681ef84, 0xdfa829b3, 0xe334db7e, 0xafbdd747, 0xd233bf9a, 0x7ff5f004,
- 0x734942c7, 0x1b448ef5, 0xc4572fac, 0xdf7e07dd, 0xce51a69d, 0xe05e48f1,
- 0xae2fc93f, 0xd62602a2, 0x92e51c2f, 0x7b420de4, 0xf3dee9aa, 0x379450da,
- 0xad52fb12, 0xfd2fb21f, 0xe68dede4, 0x12b4b37b, 0xf8fad1fb, 0x3527edee,
- 0xee43f7aa, 0xbd520f68, 0x8ecd71c7, 0x9d3d3280, 0x2ad4c4a3, 0xbf18f6f1,
- 0x4e9cd5d3, 0xc5e7fdf1, 0x7daea27d, 0x3f712f60, 0xdefd9309, 0xdcdf3835,
- 0x367c8599, 0x6f95bd70, 0x387e1276, 0x4cbf1e9b, 0xf8d364f6, 0x9bacdaf3,
- 0xb6c0ffaf, 0xe2677a4e, 0x173daebc, 0x7d2ea2ed, 0x43ee167b, 0x9f9c5be5,
- 0xa0e14fff, 0xd5ae9794, 0x649dbf73, 0x4f2efb21, 0x79f648be, 0x9f6e61d7,
- 0x4cbf3657, 0x85b7b4fc, 0x34aa47fb, 0xe851f96d, 0xd1d4584f, 0x37acfc8a,
- 0x954bdb9a, 0xe8ff9ee2, 0xb5072144, 0xff78713d, 0x9f3892e0, 0x7c34ec55,
- 0xb5e90037, 0x5271e34a, 0x305650dc, 0x0b8f73c3, 0x3e50cf48, 0x1afc697b,
- 0xee73f3c4, 0x3f902301, 0x8ff5907e, 0xfda7f24a, 0x9322d829, 0xe2ab297e,
- 0xc3adaf9a, 0x14c0f32d, 0xc1abe8a6, 0x2adef8aa, 0x6467f5bd, 0xe7e11eef,
- 0x3843555e, 0x3937b13d, 0x3aac553d, 0xebf68fa0, 0x9e82afef, 0xc26f3d14,
- 0x7441fe9f, 0xfb64cff9, 0xa33f217f, 0x5fd86ffb, 0x24b73f74, 0xbeb97a89,
- 0x8b733e73, 0x640bafb0, 0x24d55efa, 0x62ef3c33, 0x1e7421d1, 0x5236c05f,
- 0xe604e09c, 0xb17a4d19, 0x7c29fdb6, 0x9fe26587, 0x371891e4, 0x9d2e7a05,
- 0x3907e71b, 0xe8ae3092, 0x70124684, 0xf64f64f5, 0xe9396793, 0x968d4e5c,
- 0x3d639225, 0xa7a4c131, 0x315e9f8c, 0xfa7f5fcb, 0x4fedc487, 0x26f487e8,
- 0xf7e1eee6, 0x593dbc40, 0x4c64effe, 0x22f053fb, 0x93cc8b92, 0x9c6fcd3d,
- 0xa71e74fc, 0x9dcf0571, 0x89549f81, 0xf93ccdf3, 0x0ed167fb, 0x9f9fbc5a,
- 0xc4d09deb, 0xc9714a7f, 0xc258af78, 0x1efcbbfb, 0xbb307337, 0x7327e91d,
- 0xa95fdd00, 0x8c312dda, 0x366cab2f, 0x4d7f456c, 0x123daea5, 0xd35d79f1,
- 0xe7c47a27, 0xccef3c2a, 0xb97ff7e4, 0xf742daff, 0x8c2cabb9, 0x534557e4,
- 0x47e8a7ea, 0xa5cc38ab, 0x18f68568, 0xb7c8e9d9, 0xc6f2bc71, 0x3b97643d,
- 0x72ec9799, 0x6f1a8367, 0xf6fba37a, 0x5ba7e7a3, 0x8c62ef55, 0x63e9ccdf,
- 0x9ac3c61a, 0x43f939a9, 0xd54747c7, 0xc9bbdffa, 0xb5f0e74f, 0x51ab9dcb,
- 0x904ee98f, 0x4a8ef86c, 0x156b9077, 0x14ae47ea, 0xbf74d7ae, 0x017b2bbd,
- 0xf67717f1, 0x077c4cd4, 0xe3b1eb86, 0xcad26ed7, 0xdf19f37e, 0xdd7ffdc2,
- 0x1f64ac41, 0x1063bbed, 0x29fdc7ee, 0x39e90585, 0xd1cc7ef4, 0x234fd0bb,
- 0xae04e9ee, 0x9f0a68e3, 0xdff411cf, 0x3de6f864, 0xf3963631, 0x3c26e633,
- 0x62f7156a, 0xa516f894, 0x578116fd, 0x8917ecd7, 0xc46e9dfb, 0x04bcf05f,
- 0xbcf132e3, 0x229dd304, 0x4bcf137e, 0x88aaff30, 0x12f3c4df, 0x12f3c72c,
- 0xf88a37cc, 0xc12f3c4d, 0x60979e3c, 0xdf88a6fa, 0xa553823c, 0x1ae6b3b8,
- 0xa4568bc4, 0xfcbe81b5, 0xfc80f089, 0x13fd7540, 0x3f3a92e1, 0x8bfaa250,
- 0x5c6b9bd2, 0xb4a7e819, 0xfdc57908, 0x1d83eb94, 0x2af840bf, 0x15cf0ef7,
- 0xe90fbd3c, 0x8cf85c68, 0xbd5f4859, 0xf90c0dfd, 0xc774aed0, 0xf877ac32,
- 0x9b493df0, 0xe89a3f88, 0xc3c4f8fc, 0x05f75543, 0x5c8da4c7, 0x31f90d95,
- 0x6bdc4966, 0x50ac38de, 0x5cf0fbb1, 0x5b28a5bc, 0x0582f9cb, 0xd93ce4f5,
- 0x2ce38c59, 0x448d318e, 0xd53c3bfe, 0x1fba78f1, 0xb81fcebf, 0xa1f50930,
- 0x53f59d56, 0x3eba97f4, 0x9bb431d2, 0x529abf14, 0xe63a90cf, 0x3e376c19,
- 0x08d5712d, 0x0c881fec, 0xcf5d9cf9, 0x767e701a, 0xdfc4b04d, 0x916ab08d,
- 0xf6233c0f, 0xeb95ac7b, 0x55bd5ec5, 0x76768e1b, 0x78fe98d0, 0xf62ada7e,
- 0xdfd8b0f7, 0xf17f6223, 0x969c69bc, 0x8a61379f, 0x2a984de7, 0xd2c75a71,
- 0x274a5f0a, 0x21c4f6f8, 0xddbf157c, 0x1a3ee504, 0x9ea1c4f3, 0xd7c099f0,
- 0x919f0407, 0x79eb0ad2, 0x2fdd0f3b, 0xb4fe172c, 0xa0be714e, 0xe76953ac,
- 0x9dc7cf6b, 0x67f38c32, 0x13dc4fd6, 0x185cc41b, 0x8de53af7, 0x7507f218,
- 0xce3df9b9, 0xc8db4029, 0xfc1bd8bf, 0x73459dfc, 0x7af2993a, 0x295bd514,
- 0xe1159afc, 0x0718296d, 0x49e825df, 0x76f72bc9, 0xde40462b, 0xafab8bec,
- 0x8296d298, 0x925df571, 0x54788349, 0x3f7f95b1, 0x22ade82e, 0xbca7f441,
- 0xc4f46087, 0xef743ee1, 0xef0e237f, 0x7b37ad89, 0xef7e7017, 0x98f2f7e5,
- 0x84e30537, 0x29cf253a, 0xdfad878c, 0x8c41f939, 0x79d4ed87, 0x8efcc25e,
- 0xc41f539d, 0x694ed878, 0xff8b29cf, 0x389e01f7, 0xdfad978c, 0xf7e44539,
- 0xf36614bc, 0x3b5eebcb, 0x2bf5df85, 0xf1883ea6, 0xee0d13b3, 0x2f88d5c3,
- 0x6578e47f, 0x0cf7bdda, 0x99bca7c2, 0x7763ebeb, 0x1af8bdef, 0x21bde3ca,
- 0x55ff6e74, 0x7bc13c7a, 0x1b2bf365, 0xf6bacf10, 0xd60e88e8, 0xd2f27c37,
- 0x819ea9af, 0x689b2b9e, 0x6ba364f0, 0x979dd5e4, 0x2771c01f, 0xc1be7b06,
- 0xcc869ffc, 0x8c4c79a6, 0xeefc74e0, 0x3107a290, 0xef6bbd9e, 0xee90c7ee,
- 0xfc63f626, 0x132ef5de, 0xebd94fed, 0xaed0e3e9, 0x9b690aef, 0xee57fd8d,
- 0xfdf3f034, 0xbde8a3d7, 0xee749e88, 0xb21d2e6f, 0xabe50e31, 0xdb1dcde6,
- 0xc67e8d7e, 0x6f3a269d, 0xfae70aa9, 0x9b5c995d, 0xdfed08fb, 0x80fedbcb,
- 0xa261def3, 0xf452cff3, 0x74be40ad, 0x17bf325b, 0x66afcffe, 0xc9e43ee3,
- 0xca7ee85b, 0x0d267537, 0xdeb8e1c2, 0x83ef0fde, 0xc8eb8eb8, 0xf9152cce,
- 0x7c1113d2, 0xf9edc13e, 0x37fd7fb4, 0x2d7ca1c6, 0xfde5f88b, 0xf289ef38,
- 0xced097c6, 0xf7f0af61, 0x00efcecd, 0xf3bb41b8, 0x0e8a3af5, 0x4211daed,
- 0xa53bb6f7, 0xddf1b38d, 0xaf3d570c, 0x48da69d7, 0xa7d574f0, 0x76bdf7f2,
- 0xb0c3a740, 0xf95526de, 0xb257faf9, 0xb0bd0ed0, 0xa3d92273, 0xf42b9e0a,
- 0x78175652, 0xafdf8c2f, 0x337f132c, 0xfd998b8b, 0xf6174afc, 0x02f5df3d,
- 0xd0bfb5f3, 0xc8fba3a0, 0x0ab606a5, 0x7a1571e3, 0xb7bd8b28, 0xa657d700,
- 0x7d414da9, 0xfb6474a5, 0xf38ba46c, 0x868c6626, 0x39081f7a, 0x7cb8d655,
- 0x37bdea32, 0x431dcf9a, 0x56fa1f38, 0x4db7e1d0, 0x79ffb726, 0xb7fa605f,
- 0x50fd666a, 0x7cffcbeb, 0xdc9efa91, 0x138f7a07, 0x70cab3ed, 0x414e3fce,
- 0x5fe006fd, 0xfce10fb7, 0x7552ce62, 0x3c218cfd, 0xdf52b10e, 0x4ef2829e,
- 0x887d3fe9, 0xda83eb85, 0x2a277a76, 0x5944ddb0, 0xfc5d9bf0, 0xa35969de,
- 0x1df741d4, 0x3e91a410, 0x5d199678, 0xe9d38c6e, 0x73a21f6b, 0xbde03ec5,
- 0x34f12182, 0x8983595e, 0x07972dee, 0x7ea287b5, 0x0f690ce4, 0xeba7bd45,
- 0x8bde994d, 0xafebedc4, 0x1be09ff4, 0x9617f14f, 0x5376747a, 0x72c1e35f,
- 0x885e2ed0, 0x3e28037f, 0xeb40921b, 0xe60a692e, 0xed2da4f7, 0xf0386f74,
- 0xd3ae211e, 0x5d8f47e2, 0xfa472f4d, 0x87b3e7db, 0x57ff0bc4, 0xf74dd107,
- 0x438cbf3f, 0xb0d3283c, 0x785e7855, 0x15f7e241, 0x15f74f20, 0xc773882e,
- 0x41ccefb2, 0xbe173f88, 0x771d1275, 0xe7c4ed49, 0x88aabbcc, 0xdae9743f,
- 0x4349cf89, 0xae7c417f, 0x367dac2b, 0xd0f32df2, 0x4c7bfc35, 0x4fbc6cfb,
- 0xc8886173, 0xf724660f, 0x40daee07, 0xcca264fc, 0xcbd818e3, 0x0bf70b3a,
- 0x142f7871, 0xed6c6270, 0x3bb26a89, 0x8fd45674, 0x424a8762, 0xd6fbd7ff,
- 0xa9e8fb2f, 0x3777598b, 0xf0967d22, 0x9f406277, 0xf50d786a, 0xf49119be,
- 0xdc204dce, 0xfebe7394, 0x805f7fe1, 0x710a64fb, 0xe7821cac, 0x64ed19d5,
- 0x93b60057, 0xb6f95efe, 0x6ecbec81, 0xe436cf5d, 0xc7661d5f, 0xa9cf58e3,
- 0x2d935b6f, 0xf6fa7de1, 0x9bdf3c56, 0x7be3dca0, 0x575be385, 0x9efccbc6,
- 0x7c273882, 0xbe03ec4e, 0xf88b5881, 0x7e7df121, 0x0ff5e9a7, 0xb574df91,
- 0x0e9f1225, 0x4df3a7a4, 0x0a7bd34f, 0xbbae4127, 0x93ffecfc, 0x79d0af45,
- 0xc38c74fc, 0x3f7f5f30, 0xa9fbf7b5, 0x0db20764, 0x8f88e57e, 0x207cea35,
- 0xbd2f105c, 0x11703a2a, 0x5ba78fdc, 0x63a3bbf8, 0x821de8db, 0x9029f96b,
- 0x07f2fd97, 0xf501f203, 0xea3b5ef1, 0x2f51c70f, 0xf60e3840, 0x7dbb209e,
- 0x5d938f37, 0xf28d7209, 0x9ce9837b, 0xe41bb358, 0xb72e7f56, 0x87945e50,
- 0xaabf91b6, 0xce81af6b, 0x9f345637, 0x03f5c38d, 0xa65f923e, 0x488df9bc,
- 0x12bfe7b4, 0xc7c80376, 0xd94b8a48, 0xf6891cdb, 0xd4ee5287, 0x7c445278,
- 0x0ff2167c, 0xf642bca5, 0x553dd0a6, 0x39de8da9, 0x4de70af8, 0x632f21f5,
- 0x9c3ad19e, 0xd67ba712, 0x0a6bdfcc, 0x8213b7dc, 0xa07f019f, 0xbc572777,
- 0x0a05fdc9, 0x7c15283f, 0x679620e5, 0x28b7fa70, 0xde7843e7, 0x07df7483,
- 0xe140789f, 0xf9116c7b, 0xb10f8e73, 0xf68ab872, 0x37f72fd4, 0xb7b8b8f1,
- 0x3212b33a, 0xdaf59db0, 0xfc6b8f7d, 0x5fc7d128, 0x13440f90, 0x8ba1581f,
- 0xbd957584, 0x3abbd124, 0xe796b3a5, 0x50b67543, 0xe7bd08fb, 0xae718259,
- 0x15e7ebe6, 0x43154788, 0x34ca9c38, 0xdb2eeedc, 0xcf39d126, 0x3f3f1d05,
- 0x71437e03, 0x2dc70bf4, 0x9bfa47cf, 0xef42bfdf, 0xacdf1f6f, 0x5beeebff,
- 0x1f9e5a2f, 0x979d07d5, 0x3ad4dd2d, 0x5fdf5d80, 0x3f36a3a9, 0xb97d7ad2,
- 0x260bef32, 0x75639e65, 0x31e1fc03, 0xbe3e797d, 0xf8d0b8fb, 0xaf83c2af,
- 0xc1b342fb, 0xe017728b, 0x77b5e74b, 0xf2a45d5f, 0xbfacdeab, 0x73a6e652,
- 0x3fcd1b8f, 0xde4a7530, 0x0ad71413, 0x744f55f4, 0x37e37406, 0x024363de,
- 0x452511fc, 0x157bd1b7, 0xfcdba28e, 0x298111fd, 0x1a81ca30, 0x5170d98a,
- 0xdb38740a, 0x943c07d6, 0xb94389fa, 0x8131f55f, 0x962703c7, 0x231aff3f,
- 0xe86d8e3f, 0xc7df1b80, 0xfff043b8, 0x718fbe5b, 0xb7af304f, 0x574164df,
- 0xbffef74b, 0x7bb83f93, 0x3f3a79b5, 0x18b33067, 0x9d1adef8, 0xefdfd5b9,
- 0xb7b889fb, 0xe996f780, 0xee9a79fe, 0x1949fdc7, 0x49fcd721, 0x04646fa4,
- 0x574af9d3, 0x6f9215d3, 0x16392ddd, 0x6ae9073c, 0xde919b73, 0x5ff9feaa,
- 0xbb872891, 0xb8a6be5a, 0xcfefaeb0, 0x3ad8bc52, 0xb077b711, 0xb55bc449,
- 0xbcb04359, 0x7cabe0bb, 0xa45eb7ac, 0xf7027f3e, 0xe2a92ba7, 0x9f7bf02f,
- 0x1cd0d667, 0xdd6b3f7c, 0x3e30d953, 0x45cc6e33, 0x7376007e, 0x9f0dca38,
- 0xf51ac11f, 0xe88bf163, 0x72d24847, 0xe8a6023f, 0xe24a4847, 0xa3cc047e,
- 0xf453011f, 0xfa396023, 0x7e8f3011, 0x1fa3cc04, 0x47e8f301, 0x08fd14c0,
- 0xb88dfe58, 0x8c0dd12f, 0xcd39fb8b, 0x6097f7c4, 0x6fc030fc, 0x78bf7889,
- 0x777f3d49, 0xa04bef07, 0x7e2ebbfc, 0xcfc451a6, 0xf9d13678, 0xd95ed55f,
- 0xf7845b86, 0x18295c2a, 0x0873d347, 0x7b553ffd, 0x2b72db24, 0x79a74f96,
- 0xf9c96bac, 0xd7961674, 0x5ef86ceb, 0xdf13e016, 0xe2895acf, 0xea5aca98,
- 0x2e355fc9, 0xcdc53f6a, 0x0c483557, 0x0cd3acfd, 0x90ae4edc, 0x9d0474a1,
- 0x5d1e9297, 0xfb236861, 0x64bb7ca5, 0x5c9fbff5, 0xf132ea35, 0x78dce509,
- 0x2ac4ff01, 0xb16b263c, 0x79dace4a, 0x69fe13fc, 0x9137c5f5, 0x17a7e21e,
- 0x64f3c02d, 0xa7bf972c, 0x60151b7b, 0x374846e0, 0x6b2a7f8f, 0xe306b3d9,
- 0x0e356ea6, 0xe2a1e5ea, 0xbf3878fc, 0x4cf0518f, 0x30bdeef1, 0x0346ef5e,
- 0xd2bb29e9, 0xbf113b1d, 0xe4ece90e, 0xdfb4396f, 0xe9d67644, 0x7f2aa94d,
- 0x883c9e4b, 0x758b1dfc, 0xe1efc912, 0xb60f0ea9, 0x1e60a7bb, 0x89ee59f9,
- 0x563a210e, 0x5a90d0f0, 0x81f21af8, 0xf25699c5, 0xd819e56f, 0x113fa82f,
- 0x53eca557, 0xde894ade, 0x36622e4d, 0xc7305fba, 0x5389dfce, 0xc39b75de,
- 0x82839c78, 0x49378b57, 0x364eddfc, 0x5b3ce088, 0xcb4e73c0, 0xc74ef47b,
- 0x5778833c, 0xbfcfc34e, 0x78f3d763, 0xc2f8f986, 0x8177be11, 0x7c9327d8,
- 0xca1dbb7d, 0xe283c11d, 0x8d6f7eb8, 0x8e8bfec2, 0x373e28e8, 0x14beea2f,
- 0x71f9c907, 0x7920c714, 0x0c3fca67, 0xa9fe31fd, 0xa438638e, 0xeb841c2b,
- 0x253c456e, 0xd2838eff, 0x9425d523, 0x251c7e2a, 0xff7bb06e, 0xfc707b1b,
- 0x6efe2abc, 0xc5ef0dec, 0x3f7df505, 0xf027b94c, 0x0e29c619, 0x1f1ff5c0,
- 0xc4dbef89, 0xe1b6677e, 0xf6a2f3fa, 0x44aabdd3, 0x933fffd1, 0xfee0cf0b,
- 0x0b9943d8, 0xcc39e1db, 0x3e678046, 0x3f42402e, 0xf78ec7b9, 0x4bf67a53,
- 0xbe5f8a16, 0x5a6e6f8e, 0x5521f18d, 0x6bbd1249, 0x31b41f9d, 0xcffa122f,
- 0x21b7884f, 0xe26aaedf, 0x482ed67e, 0xe5dfbef9, 0x18aaf7a6, 0x826a3f7f,
- 0x53fbb7d8, 0x3a1f7f1c, 0x513e57c0, 0xcb7755d0, 0x7bb71e15, 0x1d6c3f73,
- 0xf8c73fbd, 0x0ff41f7b, 0xe87135e6, 0x2ac7f260, 0x10dbd378, 0x26f115b5,
- 0x9bb78324, 0x0e98eb35, 0xcd2906f5, 0xfc80cc61, 0xabcbe2ec, 0x7d9d6923,
- 0xf894c5fb, 0x98bf40f6, 0xbffd7f3f, 0xb0ff6b88, 0x47a5117a, 0xda5297ab,
- 0xefa2ed56, 0xcb6e1720, 0x6a7f35b8, 0xfe1f464a, 0xf6b46654, 0xf40ab923,
- 0x01d6fdcd, 0x6ba053fe, 0xdf5d1f8d, 0x773612d3, 0x351dea2d, 0x128f7a7a,
- 0x98978ce3, 0x32d80f89, 0x2aa3f4fa, 0xdf933370, 0x469997b5, 0xa6c7fc20,
- 0xf0356a25, 0x490ccefd, 0x74865e75, 0x3a43eb82, 0x44e914c1, 0x7cefe7eb,
- 0x9c240f51, 0x1700f5cd, 0xda2601e9, 0x81cb35d7, 0xeef8487f, 0x3fc5458f,
- 0x0ff0062e, 0xa61e5830, 0x062d55fb, 0x8946877a, 0xc90b1cb7, 0xf07d11d5,
- 0x27e70f13, 0x3b3c8383, 0x657fbee8, 0x1ef3c510, 0x3afc71d2, 0xc9c78eb4,
- 0xfe42b315, 0x7cf5d0de, 0xcccbee85, 0xf539e88b, 0xef3fa807, 0x33e93309,
- 0xe416626b, 0x257c3bfe, 0xe0106507, 0x4b2c6b9d, 0x9be0b8c3, 0x03bbcaa5,
- 0xd021ded7, 0x271cf78b, 0xaa6a77f0, 0x5953fe84, 0x54fa216c, 0x6a5661ee,
- 0xb06b1d3d, 0x1e10ff5e, 0xf465a1ef, 0xcd71c8ce, 0xa9eefe40, 0x13e3b3a0,
- 0x1b9fc912, 0xc5e3d2b9, 0x93ee7b7e, 0x71da7de8, 0x831dfcc1, 0xf3a14d3c,
- 0xaefef815, 0x7d47df86, 0x9029df11, 0x5fb95f71, 0x93ef77c4, 0x05b169eb,
- 0x7fb95b21, 0xb3fbbf98, 0x00fe1252, 0xb74b6ef1, 0x1fdde03b, 0x374aeef1,
- 0x08f59c2b, 0xcae981f2, 0x27d68ffb, 0xa6a07cf1, 0xf7788874, 0xcf7fe387,
- 0xf90da364, 0x3e70cd59, 0x04d29aff, 0xac948fee, 0xb98e51cb, 0x1c68c37e,
- 0x833fbbdf, 0x1fb2bbe9, 0xa72e3bca, 0x43bf1c43, 0x9ef811be, 0xe152b3cb,
- 0x4fd8f98c, 0x27af9f26, 0x43e3f399, 0xb93c8633, 0xc838e10d, 0xf87a839a,
- 0xb96151dc, 0xac47e012, 0x800cb996, 0xa69be87f, 0x69d66e77, 0xbc602bdd,
- 0x2f715a41, 0x3df82b5f, 0x82341974, 0x90f5dbea, 0x217a7a2f, 0x8abca3b3,
- 0x6c5ef465, 0x879f9192, 0x29863b43, 0x946469ba, 0x85fb8c83, 0xfef1fa8a,
- 0x7b98a28b, 0xd9fd4485, 0x673c4a35, 0x020efe2e, 0xb6173f23, 0xed411d0f,
- 0xdede1a5d, 0xb6f485ae, 0x51defe44, 0x9d036acf, 0x3e3d1683, 0xa4e3e498,
- 0xedfbeab1, 0x38f067df, 0x985d2505, 0xf9d15569, 0x74e955dc, 0xd577389e,
- 0x43d40a8c, 0x74c10d1c, 0x81f3af1f, 0x9df0bb97, 0xbdd972f1, 0x6bb413e0,
- 0x216f1d32, 0x5920b95f, 0x0a85ef67, 0x477c1f73, 0x0e31718f, 0x6f4be4cf,
- 0xed70dca2, 0xbaef8a39, 0x4c80ffdd, 0xfc67efed, 0x8ab6647d, 0x9f7903bf,
- 0x1a36b2eb, 0xb46fbffa, 0x0ef27e44, 0xf50e2593, 0x5fb122ba, 0x14ff82ad,
- 0x829c19ad, 0x787df576, 0x9c87dece, 0x3d793291, 0xf76dfbe5, 0x635d9530,
- 0x990ddf10, 0x25b7bd7c, 0x6bc5eff2, 0xa1891d0d, 0xa9bcea98, 0x8d86da90,
- 0x65f118fd, 0xdfcb0252, 0x25fc708c, 0x987633f7, 0x97ce9798, 0xae0933eb,
- 0xf1d3d60e, 0x6ea3ae38, 0x63a3ad28, 0xde8e258c, 0x8aef10bf, 0xfe70b7ce,
- 0x8f8631d4, 0x1ed2ca73, 0xe9c19e12, 0x9d17df07, 0xebf4b627, 0xba9f2ba5,
- 0x5bcdea1d, 0x927ba466, 0x4a999ff3, 0x1abcca76, 0xb247ee99, 0x45f7ea0d,
- 0xe2749e41, 0x0bdf02fc, 0x14177c0d, 0xa0f11cf7, 0x78448378, 0x9b4adb74,
- 0x7bdfcf1e, 0x009e8136, 0xdecd8bdf, 0x8a0bd424, 0x0adb266d, 0x43778fa9,
- 0xe5b807bf, 0x8ccbbbe2, 0x592126fc, 0x6e38ab8e, 0x7a22c6d1, 0xc33833a7,
- 0xdbb0fe41, 0xfd441ec0, 0x4e4c8ee7, 0xbc00933f, 0xb683cef4, 0x9fed063d,
- 0xaf1c193d, 0x525b8526, 0x269784cc, 0x3bbbf786, 0x9c149674, 0x936ac75f,
- 0x499ef506, 0x027e382b, 0x23b518dd, 0x059fbe30, 0x111efd21, 0xd72d67ed,
- 0x7e42d616, 0x90ed8810, 0xe19bc470, 0x0e8f9f84, 0xf119fc73, 0xd86fdcef,
- 0xf39fe428, 0xf3e26c36, 0xb4cffb12, 0x9ef0e36d, 0xf8fab9e5, 0xa0571811,
- 0xc3a3c3e0, 0xfd325ac6, 0x8901e0f1, 0x73d61ff6, 0x6d8de518, 0xccc8dcd8,
- 0x007e5401, 0x58d263f1, 0xe421c52f, 0xe7864ec9, 0x8cd1bdf8, 0x197be9e2,
- 0xb5ded7a7, 0x0a6fe25a, 0x01f8509f, 0xef1d83e0, 0xadfb2ac7, 0x2bff85f0,
- 0x43e0043d, 0x1be1457c, 0xf0517f0a, 0x8133e14b, 0xc01b3578, 0x6a08f77c,
- 0xe14cfc4f, 0xcd0eb863, 0x517f1f08, 0x76b759f6, 0xadfc868c, 0xe4f39f62,
- 0x40dfbb8b, 0x49989438, 0x1706b96f, 0x12e091b3, 0xf84d67a7, 0x47caea3e,
- 0x402cf70a, 0x416dfc7c, 0x331fea3c, 0x18f7d44b, 0x7d48be7f, 0x52ce717f,
- 0x59c5fdf5, 0x843e3f4b, 0x5086a77e, 0xbfdc04c7, 0xf33dbf53, 0xfe50a7e2,
- 0x90bdbf9f, 0x8becedcc, 0xb8e1cff5, 0x3cc482cb, 0x96bcf9da, 0xdcbe49e9,
- 0xfc30f426, 0x9732fb87, 0x8a2d3a71, 0xf28a3b0f, 0x29c22e6f, 0x611fdf0b,
- 0x89bfcf04, 0xf62539fd, 0xf73568a7, 0x24b8743b, 0x5dcc43f2, 0xad74e825,
- 0x97f25efa, 0x383dac31, 0xf97f77d1, 0xc4a4dfcb, 0xf72b5d21, 0xf96b1d95,
- 0xe969667d, 0x1c5fd261, 0xae50fbca, 0x96a1f780, 0xcf7bf2b6, 0xc4fbeaed,
- 0x3d76d9c1, 0xb71829f9, 0x1da6e6a3, 0x1b35f1e4, 0xb28a0b25, 0xbc5e5162,
- 0x57dd5256, 0xdf93247b, 0xd0cc6b17, 0xfa0bbf72, 0x1f38949c, 0x7c04be3f,
- 0x15cfee83, 0x5fae1c6f, 0xe747c7e0, 0x6979f28a, 0xf2954a1a, 0x571e0cc6,
- 0x03448c1a, 0x4b4faefd, 0x7e27cfd0, 0xa8bf2567, 0xda6e7f52, 0x37e83588,
- 0x7f01bb98, 0xfed7c79d, 0x6a5a9937, 0x26f428df, 0xfcf80de7, 0xfc2a38b5,
- 0x379a0ef3, 0xaf65d3d9, 0xdf157aee, 0xdcfb2fbd, 0x6ca67240, 0xcf5f3898,
- 0xa54ee770, 0x9f7e63f3, 0xf7ec52aa, 0x845f5db8, 0xd5509da2, 0x8671dfc8,
- 0xcad303b4, 0xef642565, 0x1e80da57, 0xf78fafc2, 0xcfd5f77e, 0xd95fb943,
- 0x9f41ab15, 0xa59df888, 0xc8afc6ca, 0xdefca0ef, 0x2abb6052, 0x6e50fbe9,
- 0xff985abf, 0xede411ef, 0x549d11d7, 0xb97b7335, 0xf215ef6a, 0x5fed579b,
- 0x63e8e91d, 0x13dfd7fd, 0xe8e2abb1, 0xcb86d8ab, 0x06fe0f74, 0x4c9eeaf1,
- 0xedc3eef1, 0x538a76ec, 0x2b8a32d7, 0x2ebbf6ba, 0x8d1fe4ee, 0xacdaac8f,
- 0x5ea078a1, 0x9e1fb5ad, 0xfb8b75c7, 0xbef58151, 0xd776e4cd, 0x7c23a025,
- 0x41bba377, 0xee9df3a6, 0xabbfee06, 0x15ba786c, 0x8256a5ef, 0x5ec30ce1,
- 0xd9543fbb, 0x7fa33328, 0x1fc61adc, 0x9e78dc45, 0xe842bbe5, 0x8f52981d,
- 0xf987af64, 0x34bd82f4, 0xc73e6fc0, 0x1b955e05, 0x2fb4b93c, 0x0387fe62,
- 0x96d29df4, 0x2b9ee9a7, 0xfd22ebd4, 0x8cc18fe4, 0x1cf5939f, 0x6e7679c5,
- 0x5ae74919, 0x953d9ea5, 0x086c77e4, 0x0b9578a6, 0xe9bdf53a, 0x53bc6253,
- 0xafee3c99, 0xb124e313, 0xe932abfd, 0xa44f38a7, 0x3a920bc7, 0x68b4e38e,
- 0x6dc05a77, 0xa54ba09d, 0x23a7a97e, 0x9fea0934, 0xd298fa6d, 0xd4bf512e,
- 0x728596dc, 0x30636cf3, 0xdb3d63dd, 0xb7fc87f8, 0x9e4bbc60, 0x3f25fd31,
- 0x74b292fa, 0x88b63f7c, 0x08eeb8fb, 0x43c4cf71, 0x886ce9eb, 0xacbed095,
- 0x9d5ef110, 0x6a87af8d, 0xff5d7e88, 0x4d5defde, 0xb15deebf, 0xfea046ef,
- 0xbd576c62, 0xd5bff62b, 0xff28a57f, 0xe3142a44, 0xb9c5e8f4, 0x101dff30,
- 0xe13ba08b, 0xcc3d9d8f, 0x7fde10fa, 0xdff01f65, 0xffbd030d, 0x668fb439,
- 0xec8239ff, 0x0ffdfc4f, 0x21f37fcc, 0x3d9b2f3f, 0xe895f052, 0xd7f41cf6,
- 0xfd73c477, 0x2816b9c1, 0x0e5a4011, 0xf802e5f8, 0xe61add39, 0x2cd0fc80,
- 0x02753f6e, 0xe187ebfe, 0xe58e3cc8, 0xf877d814, 0x35eb8c9e, 0x4cec8e7e,
- 0xbde0a6f0, 0x4f114ebe, 0xa6f70ce0, 0x17bf4044, 0xa7389e05, 0xdffc5378,
- 0xf56e74a9, 0x45cd3c52, 0xdf873f11, 0x1ce79fd1, 0xc475ebc1, 0xdee8ba5b,
- 0x8610dec6, 0x8de6aafa, 0x8ac3c210, 0x0d5b4c57, 0xa8d2767e, 0x5f0fae2c,
- 0xad77f3d4, 0x7cf8db5d, 0x5237434a, 0x7e05173f, 0xa46d0697, 0xf7129df9,
- 0x3cf54b83, 0xf463a1df, 0x0ecf7c9e, 0x85cf6efe, 0x387db698, 0xe91d85ce,
- 0x11da6714, 0x44d05eef, 0x497c79df, 0x17834ed9, 0x477e75e7, 0x2a03dd08,
- 0x3a66edf8, 0x33adec5f, 0xceffc848, 0xcf74600f, 0x00fd7ce1, 0x25e7d792,
- 0xcf37f92b, 0xfd411fbf, 0xa52f5595, 0xc0652cfb, 0x84ef5026, 0xb5f500b4,
- 0xc7cff5f3, 0x7e42fd21, 0x6c1de62d, 0x215fece3, 0x260f6e9d, 0xcec2f33b,
- 0x9ffba47f, 0xe06928f7, 0x9fb289b9, 0x59e9f7ca, 0x2e986edc, 0xcb2b34e0,
- 0x832dcfc2, 0xd026cf3d, 0x037d38fa, 0x002ec99c, 0x7177a27a, 0x239a794e,
- 0xeca7e825, 0xca3b108d, 0x379d0ef7, 0x87040fe5, 0x30bbf160, 0xf3c2ec8c,
- 0x2ec822db, 0xfa9a2d07, 0x932dbf39, 0x389543e2, 0xaba84993, 0x12663ed1,
- 0x2de4f37c, 0x706ef459, 0xe1c5305d, 0xbb7e3d94, 0x644ee286, 0xbd9777ae,
- 0xc8926f3a, 0xa69cf1db, 0x56bf57ec, 0x49fe45e0, 0x29d48e25, 0xe3c568f8,
- 0xb8c3f577, 0x9967f65b, 0x68aee3e2, 0x20639c79, 0x0964765c, 0x45efba3e,
- 0xe0275ba2, 0x502efe39, 0x2f0388b9, 0x2cfdc9df, 0x7aee6be5, 0x51e3f88e,
- 0xdf38c31d, 0x43a79e8b, 0xb4fee1fd, 0xded7c7e8, 0xa1cbf546, 0x41ff6f3e,
- 0x9b67cd28, 0x0392e28e, 0xdb96ebf7, 0xa5ff94ef, 0xd01e65f6, 0x0738fa03,
- 0x1edac2be, 0x40f91cfb, 0xa2e6c983, 0xd7b71e52, 0xe02cf3a9, 0xc44c19f7,
- 0xc4c33a1f, 0xf35689ef, 0x35f281f8, 0x71477f13, 0xd2a7c70a, 0xee85a61d,
- 0x36e9cfbe, 0x115cfe0b, 0x7487eb61, 0x41fb0158, 0xbf1f09f7, 0xb375ee8b,
- 0x7da8eb3f, 0x131e7ae0, 0xe1d1aeed, 0xdcff1e6e, 0x4bef9039, 0x24a9abe7,
- 0x38c23a77, 0xc97cc35e, 0xe30ced4e, 0x60480529, 0xe3858ddc, 0x0f18e743,
- 0xd29ddfd9, 0x743b4a1e, 0x52d95dbc, 0x5e177bf1, 0x44e2371e, 0x77c44d9c,
- 0xa1b43677, 0x38fc81be, 0x5ea50477, 0xeff5f843, 0x931e0386, 0xc593d77d,
- 0x7f129be5, 0x93d6ef43, 0x47a3d35f, 0x7a10ea7e, 0xfae1b39f, 0x7ba033df,
- 0xc5120def, 0xe959ff1d, 0x94ffc447, 0xcacf0e73, 0xe39d125d, 0xa47aaf97,
- 0x7cbef114, 0x4899a6d1, 0xca3aca0f, 0xed00acb5, 0xa6490eaf, 0x3f5d80f9,
- 0xf5c64a67, 0xfdf029e3, 0x513fd04c, 0x8067228e, 0x59654ed6, 0x6d953d15,
- 0xab9cfe84, 0x4e340da4, 0xf27762bc, 0xc27029f5, 0x638c1f73, 0x3701fc54,
- 0xcf32bf5a, 0x57a7cd1b, 0x788ea1f0, 0xe346efeb, 0x13247f7e, 0xfdf2b93f,
- 0x3fe17ec8, 0x2fd1b7a2, 0xe1fd2a59, 0x11d4127d, 0xc8839fa1, 0x046e30cf,
- 0x3cc0bb6f, 0x8087e853, 0xd5a6e37c, 0x1a43f3a9, 0x468cf9d4, 0x45ab3e75,
- 0xabbdb79d, 0xe3159fce, 0x3b42702a, 0x6c3def18, 0xd01ff717, 0x4bfbc60e,
- 0x1e630768, 0xd14c60ed, 0xb472c60e, 0x768f3183, 0x0ed1e630, 0x1db9eab6,
- 0xc1da298c, 0x8c359e58, 0xcb59c9c3, 0x0fb090fd, 0x9f8f3a76, 0x026efca1,
- 0x8fa885d8, 0xbd220e96, 0xa8be7d0e, 0xedfff437, 0x478805d5, 0xd44710a6,
- 0xc38c1cb0, 0x83135b6a, 0x93e203f5, 0x664c239c, 0xafb437f4, 0xd506bb3e,
- 0x63b30e90, 0xe257d610, 0xbe962a96, 0xd6efbf43, 0xe7fadcbe, 0x227df29f,
- 0xfbf287bf, 0xbef86543, 0x2e7e4cbb, 0x391dff23, 0xf7afb19b, 0x8ce303a3,
- 0x22f895fe, 0x368e8abb, 0x53fe5c12, 0x7c8313d7, 0x461dabfe, 0x2bf5677a,
- 0x4d931f71, 0xe77ea8b7, 0xde79daf1, 0xcb9d1293, 0x9c2c3ddc, 0x061ef7da,
- 0x790fbbfd, 0xd0f3a4aa, 0x9f77ef59, 0x4906de78, 0xa6dce383, 0x276470e7,
- 0x1c6f1164, 0x4ea77fca, 0xf51531cc, 0xa7f9bf73, 0xf85483bb, 0x787b7433,
- 0x0c35efc0, 0xd61fd554, 0x7bf01094, 0xbfd4430d, 0xf2c0f023, 0x4f676803,
- 0x555230dd, 0x6bd20aef, 0x28d5ca36, 0x85c597e2, 0x27c40577, 0x4f7eaa86,
- 0xa7ae896f, 0xbfa871e3, 0xc90c6f64, 0xb7986283, 0xf388a47d, 0x49c7a581,
- 0xb7c435ae, 0x3dfa256b, 0xde4279b2, 0xf96aa5b0, 0xe7e5a25b, 0x3646f87a,
- 0xbdce83ea, 0x84fef451, 0x16258f82, 0x811b0f66, 0x596dbcf1, 0xde1fb45e,
- 0xf117397f, 0x8dae42aa, 0x781bdfc3, 0xc36f7254, 0xc217a78b, 0x01de44f7,
- 0x38d63fdf, 0x2f0f112a, 0x3a39ce1e, 0xb17ce00a, 0x4b7ba641, 0xe46f3a71,
- 0xff0fb308, 0x209674e2, 0x8ddaffdc, 0xf41bfdfc, 0x3ee1c95b, 0x18dda8fc,
- 0xf6649411, 0x87c15bad, 0x41def4db, 0xaf5d704b, 0x02af4899, 0xd3e49a3d,
- 0xe932c395, 0x2463256f, 0x62b9e917, 0x4b7dca9d, 0x85a73d65, 0x78d2c83d,
- 0xef8a8fbf, 0x640fd317, 0xce1d6159, 0x1938a6ea, 0x61a6b8f9, 0x63a40c5b,
- 0xc3758e8c, 0xa8efe006, 0xef8a7f25, 0x227d9497, 0xf8ef8c33, 0xd09ee6ba,
- 0xdccf503b, 0x824db3ad, 0x5f1be3fc, 0x6595fba6, 0xed1eb75a, 0xb51d92d2,
- 0x5ee68f74, 0x82d26ef1, 0x9f6445ed, 0xc88b642f, 0xc4a73cce, 0x94780b9d,
- 0x58b6958c, 0x823dde60, 0x7788946f, 0xf1f7942b, 0xefe76cae, 0xb8503f3e,
- 0xf5e77e87, 0x902f5165, 0x9c3f7a5e, 0xfd00379a, 0xf6c91e4d, 0x1f4cf763,
- 0xc03fa0c4, 0xad57a987, 0x75703e94, 0x9fb9d908, 0xa184afe0, 0xb008c8bc,
- 0xf1e43f77, 0xbbf8bd19, 0xef78f148, 0x2a7fdbd2, 0x3adbc3ee, 0xc00a87da,
- 0x7823519f, 0x909dc33c, 0xdf568e16, 0x171aa9f7, 0xe9f7c2ac, 0xa08e8fcc,
- 0x7c1869bf, 0x607f97ee, 0xfeaaa252, 0x0d0c0f43, 0xbe1187a0, 0x742e74ef,
- 0xb44e2aa7, 0x4acb9962, 0xe4f1f4f7, 0xd21cbfce, 0x13678465, 0xd82bed54,
- 0x78bd5f14, 0x45ba3bfe, 0x7a6d7f84, 0x344a97b4, 0xba7d6e3c, 0xb79443a3,
- 0x442c3953, 0x25b79745, 0x72e53eda, 0x83e3c751, 0x3a7b1f85, 0x97d89dfe,
- 0x168d845c, 0xc9efe2e3, 0xa1c1ffa1, 0x54da3bd6, 0x3fc22271, 0xfdc69154,
- 0x36ae1543, 0x01df9e3d, 0x00b1b5fc, 0xfc8dca92, 0x6fa8085d, 0xf9e70d8c,
- 0x7fae2365, 0xc3fb0f2f, 0x0f2ac877, 0x2f4845cb, 0xf12bdf81, 0x0f9c027d,
- 0xe94273fa, 0xbfde719d, 0xcfc157e8, 0xc09438c0, 0xb5f1b27e, 0xdf7a1c9f,
- 0x9aa3de8f, 0x89efc85a, 0xf9933d3b, 0x3c00fbbd, 0x15fdf853, 0xfd12cf7c,
- 0x43be1fdb, 0x5dbbd678, 0x00b76367, 0xf73b4a8f, 0xdfe20677, 0xbe0f5802,
- 0x51a0b86f, 0x5e25b9b2, 0xfff2e10f, 0xf482dc01, 0x00800036, 0x00000000,
- 0x00088b1f, 0x00000000, 0x5bcdff00, 0x6595580d, 0xf3be7e9a, 0x700e01c7,
- 0x0427e540, 0x094a880f, 0x44101df6, 0x18293b53, 0x54da1595, 0x021f44a2,
- 0x9a2824fe, 0x2edb52ed, 0x4c7350c7, 0x4a976867, 0x57a3ab1b, 0xb5accd39,
- 0x8cce9a98, 0x7e927bbb, 0xa772b268, 0xa9aeae69, 0x66b663b5, 0x3b448dae,
- 0xb5b4d45d, 0xdfbefdcf, 0x23bef9c7, 0xb5cced4c, 0xd7175c3f, 0xfff79e73,
- 0xe7defe7d, 0xbbf79e7d, 0xc89132a3, 0x1befe24d, 0xffe56ffe, 0xd5a212ec,
- 0x441f9d07, 0xabe5a30a, 0xae0decfb, 0x60fd65cb, 0xcbf5c5da, 0xc32a63f1,
- 0x9c284a23, 0xd70770c7, 0x4d5dc69b, 0x27b53edb, 0x97f1ca03, 0x3463fc69,
- 0x284a83c3, 0x1e3c5ca4, 0xca8d9055, 0x0c61d689, 0xf1c0d11f, 0x3f685d3b,
- 0xaf214bb0, 0xa09d9a22, 0xd41eb974, 0x62bbdeb7, 0xc8614d3e, 0xf5e6cc63,
- 0x11741c2d, 0x1b8d1295, 0xe6e5c27f, 0x1487fd7e, 0xbbf70f75, 0xca21d065,
- 0x10e41d5b, 0x6a21acfb, 0xf9bdf867, 0x9dc1d117, 0xefeb269d, 0x60f37865,
- 0xbb17e8ba, 0xe87a21ce, 0x6e88b9f4, 0x7645c274, 0x798dfed3, 0xa22ff1f5,
- 0x71ff4c53, 0x1af6e9e3, 0x0a27510f, 0x7f0cb8b2, 0x8fb90257, 0x86688ca8,
- 0xccfa349a, 0xb2efc264, 0xf21e786f, 0xa3d3a0f0, 0x512162ed, 0x8f0c6890,
- 0xc7ad22eb, 0xd2593c03, 0xb8e92bd9, 0x48cbe9ce, 0x99dfe22d, 0x3bfa56c9,
- 0x3728297c, 0x61d869c6, 0xa3d31f23, 0x3d363eca, 0x8c68e3c2, 0xc8b43e83,
- 0x345f036b, 0x1bcdbc7d, 0x4c46e7c7, 0xce4db4fd, 0xb9f6e274, 0xd809461b,
- 0x574def10, 0x8361beb9, 0xf0c426bd, 0xa467ef83, 0x7d1cb057, 0x7a39c9b0,
- 0xc1f10f3e, 0xa97353dd, 0x80957818, 0x5b8c1fa7, 0xbc5cf214, 0x26d506af,
- 0x37fad1e8, 0xf9dae4ef, 0xe3b627e7, 0xfe788bc9, 0x92874d96, 0x559c782b,
- 0xf72ade9b, 0x6ddd13e6, 0xde54dad3, 0xf76539ff, 0xe5e82f5e, 0x86a53ddd,
- 0x52015dc7, 0xd8ee5f30, 0xdc419554, 0xdeebe5ae, 0x79e3bdc7, 0xe99c1bbd,
- 0x8f9f9636, 0x3b276d7f, 0x2759cfcb, 0xe24cbd05, 0x7e52f1b3, 0x18953ecf,
- 0x3f7964ea, 0x9e2050ab, 0x5fda57cb, 0x5b718298, 0x75888e3a, 0xbd1db2ac,
- 0xb5fff305, 0xc32de79b, 0x99bda1bc, 0x4e0d5798, 0x86dabcc4, 0xd15a2909,
- 0xb35afcc8, 0x75d044a3, 0x99f7076f, 0xa8817448, 0xba7b7c1a, 0x9ff02dc3,
- 0x59a13076, 0x6475f7d4, 0x0ed9fc0a, 0x1d3d809f, 0xbbbca285, 0xddf92bc8,
- 0xc75fefd9, 0x50e704f3, 0x7c079b61, 0x783a14f3, 0x092a77fd, 0xa8029c6a,
- 0xf7c17866, 0xff04b327, 0x5d88790c, 0xa27eaccf, 0x5e7c9326, 0x26a6e839,
- 0x455efc93, 0xae7c16a9, 0xbed2cb3b, 0xa9679bca, 0x52f33abf, 0x3e35fd4b,
- 0xaebf05bf, 0xfda5ba70, 0x1655eaf5, 0x6b8ac6fc, 0x0417ed2c, 0x9bf05816,
- 0xed2d6baa, 0xb069ae6f, 0x68badfd4, 0x56bea5a5, 0x97c16b5b, 0xd2dbb8ac,
- 0x0db6b6fe, 0x7900fa96, 0x7272c41d, 0x63e3f994, 0xf313ffba, 0xd7cef005,
- 0x7ccc7827, 0xd6d7399d, 0xdc8c33d6, 0x32dc861e, 0x07f5de7f, 0xe47c839e,
- 0x321ca4d8, 0x53cb100c, 0xf513eaaf, 0x305614d9, 0x2cbd9b0f, 0xbb6c4dc8,
- 0x8999fad8, 0x31f33ec7, 0x7ffd730f, 0xf6c1c8b1, 0x63b4e660, 0xbf19e3a5,
- 0x916fbfc9, 0xccc8ed83, 0x067d8e2b, 0x19ff0dfc, 0x5dc4df89, 0xf6fef067,
- 0xf20a2c37, 0x995e673a, 0x3d654dbf, 0xea9d37a4, 0x7cb23453, 0x0e4ddf62,
- 0x30c06fb9, 0x31e023cb, 0x17c04796, 0x0a9b1e59, 0x79665e88, 0x50ebec04,
- 0x3b2ff945, 0xde3c042a, 0x8df01011, 0x4f016a8e, 0xf808d474, 0x02458eab,
- 0x1343bafe, 0xb1d37efd, 0x3a77c042, 0x6ff944da, 0x7c05da3b, 0xca2823af,
- 0xa11557df, 0x8202bcff, 0x0339c2dd, 0xf6ed5df9, 0x2e7ced84, 0xf9e711d0,
- 0xfacabb21, 0xeed804ad, 0xdf14dd33, 0xd863aa68, 0x449146d9, 0x91c465e8,
- 0x8bf9867a, 0x37edc39f, 0x741d476a, 0x1b8f18c6, 0x381f13df, 0x3442bb07,
- 0x31267bd6, 0x1fc07e5a, 0x03e504f8, 0x2539f505, 0x3ebd9fcc, 0xf9f053ed,
- 0x4dc692e6, 0xae376c29, 0x09cdaafc, 0x46db7939, 0x8f93862b, 0xb23e5d5e,
- 0x638c141d, 0x29b8177e, 0xf0269298, 0x0e618b80, 0x88eec397, 0x0177de3f,
- 0x81e43e60, 0xb963e508, 0xb670cdde, 0xf10a793b, 0xe5c394f9, 0x142f2176,
- 0xc27ac870, 0xb41e5c78, 0xa9e745a5, 0xdf61241a, 0x84716d66, 0x1c921f60,
- 0xc895b614, 0x7225c9f6, 0xdcb3e05e, 0xe5857e3d, 0x478b5664, 0x327ef20d,
- 0x2255deb8, 0x0cec07da, 0xf73dfc9f, 0x514c229b, 0xd444a130, 0xbd72f58b,
- 0xa0d54758, 0xcff40146, 0xef4e3524, 0x41f596ef, 0x6bc59ff4, 0x30c15f80,
- 0x9c79f184, 0x7689d600, 0x185db289, 0xce7c14e3, 0xf49b24f3, 0x9642fec5,
- 0xdf65fb83, 0x9f6152e9, 0xe44ed273, 0x3f31eec1, 0xfeb9f9c6, 0xdbd9d4a6,
- 0x9a9fcc23, 0x26bfef38, 0xf34a5f32, 0xff9402b4, 0xc13f194a, 0x4c17e60f,
- 0xc4935319, 0xe7c6c4f6, 0x39f630e4, 0x3f062f96, 0xf41bba0c, 0x48dbe58d,
- 0x4f891afc, 0x1aa9fcb1, 0xf41bd28c, 0x512f991a, 0xff9505fe, 0x754cbe7b,
- 0x7ac6ecf4, 0x2adc5ae2, 0x7c6df3d6, 0xe69fbdba, 0x869370a5, 0x80cbdf41,
- 0x5eb4f267, 0x5d2351e8, 0x9a0bcf35, 0xe0c5ed79, 0x0bbb6c4f, 0x03e3b423,
- 0x779c56f7, 0x6d273e7d, 0x8b5ff9e5, 0xa0a73a67, 0x33f1e03c, 0xf6eae61f,
- 0x84da8fa2, 0x2937673d, 0xea54fe08, 0xb45b9aac, 0x9597f85c, 0x36bfab1e,
- 0x8d9aabef, 0xe8de7798, 0xcd95ff18, 0x6bd1ce32, 0xa6af71f5, 0xf56e312e,
- 0x6bbb6b58, 0xdaf0bf75, 0x5df96b02, 0xcbafdd7e, 0x91d83ca3, 0xbae5524a,
- 0xcbf09b68, 0xdc72bd2a, 0xe3af9d6c, 0x099a767d, 0x80e691be, 0x77f17af1,
- 0x7bd600ae, 0x7e050535, 0xbc04850d, 0x9c62c28e, 0x01d0d9eb, 0x09c891bf,
- 0x9fddc5bc, 0x5e9162eb, 0x87ded76d, 0x8e49f3df, 0xeb852936, 0xfbb5e333,
- 0x89bd17a1, 0xe1add437, 0xce96e6f9, 0x63bf402d, 0x2fe13e95, 0x178f731c,
- 0xdfe40bfe, 0x8fd51699, 0x17fed957, 0xf97adaf0, 0x897c007c, 0x160287cf,
- 0x7cf857f6, 0xe16d7e00, 0x79bf4206, 0xa61c853e, 0xaffd1b7d, 0x4721cef3,
- 0xf7f6c8e9, 0x1b3f29ba, 0xbc9cb1ab, 0x92a93a96, 0x55a70192, 0xa5afbf62,
- 0x8c24d866, 0x7c580973, 0xff3860b8, 0xe8bf90ca, 0x31c8f37c, 0x1b3a646a,
- 0xa7a58d74, 0x813fe741, 0x470dcfae, 0xc4955ed7, 0x3ee03639, 0x313d9ab0,
- 0xf6944d6a, 0x89387020, 0xd77e5932, 0xa087b21d, 0x89631f8f, 0xd25f1859,
- 0xbfa50a89, 0xef5f5ebe, 0x16341d47, 0x53a7a6f4, 0xba5df944, 0xcfb736cc,
- 0xd65cfb10, 0x7dfa215e, 0x88bda719, 0x092f9c75, 0x820f644f, 0x99d5da3e,
- 0xf9e7833c, 0x0abb59e4, 0xeec5bbff, 0xd742a6db, 0x4fabb35f, 0x55f4b8f1,
- 0xe842ee6f, 0x86a393d3, 0xb8b467bd, 0x7b8d1d25, 0x357957c6, 0xc8ef38bd,
- 0xf5299a5b, 0x85e81490, 0x8d8f3e71, 0xf2c2bb63, 0xe125cbbb, 0x7975e748,
- 0x12a7db02, 0x49d85ed1, 0x4fdc7f83, 0x4e3cd9e0, 0x0fc8ec39, 0x7e3f8413,
- 0x9ef0252e, 0x9256f31f, 0xbf659fc5, 0x81add857, 0xb38e92d1, 0x3323e269,
- 0x73ecaf19, 0x07eb8852, 0x1b5da52a, 0xdd85b8f0, 0xd1b57aac, 0xa9dcfb01,
- 0x4cb88bdb, 0xf498f7be, 0x4097de3f, 0x26fc933e, 0xf059a616, 0x4b12f524,
- 0x7c8a94fb, 0xe06a7d4b, 0xa8fd4b32, 0x3e0b12ea, 0xa58666a6, 0x39a2c67d,
- 0xbb4b3c16, 0x7b3ed2d6, 0x6e0b42c5, 0x596ca1d8, 0x8b6d3944, 0xb5c7fd2d,
- 0xcfb4b52f, 0xa961de0b, 0x44e060a7, 0xd6aff721, 0xb2df8ffb, 0xe4cf5ace,
- 0x2f4395b5, 0x928fdfe4, 0xe614fbab, 0xd967b55f, 0x84e5e87c, 0xebac7bae,
- 0xc7657fb1, 0xa29d9039, 0xffa628d0, 0xddab3ed5, 0xe2b4caab, 0x8bff5e95,
- 0xaf5cdd60, 0x9fb2eed5, 0xb29e40a7, 0xf2961cdb, 0xddba25b1, 0xc453429c,
- 0xf8dbf87d, 0xe1665daf, 0x2ebd2c7f, 0xfe038796, 0xb49bb730, 0x97072ac3,
- 0x3072ac86, 0x1cab69f9, 0xe558f714, 0x5623f2e0, 0xad87f039, 0x67da5072,
- 0x13b28395, 0xf6983956, 0x0c0e558e, 0xd7e58cf9, 0x3e5588f4, 0xe5345348,
- 0x8aebf08f, 0x89f956b3, 0xbf510fe5, 0x8f3cdfe0, 0xfde68f42, 0x185afcf9,
- 0xfe21afc3, 0x77e1bd30, 0x4e4f0ece, 0x67d55e01, 0xf7cf10a7, 0xabcfbe98,
- 0xf279b727, 0x74ee9ed9, 0xd0257568, 0x3aae5d73, 0x0d5ca4b3, 0x87881df4,
- 0x198fafdd, 0x5a59c7ff, 0x1a2fda03, 0x0bae59f5, 0x4dafd1f2, 0x39e97dc2,
- 0x1ddd8495, 0xe7c72097, 0x4758b27b, 0xa87b1ef0, 0xd271d793, 0x3ec0a5d6,
- 0x2b6b2737, 0xa2f6ffd1, 0x07708536, 0xfe82a0a3, 0x971cfff5, 0x1c7ebc0b,
- 0x151e7b89, 0x2416ca45, 0x7d62ed45, 0x7af39736, 0xf7e896d6, 0xb9eb9514,
- 0x1912fadf, 0xbd5248b7, 0x290f112e, 0x20e200a2, 0xadc8bd7c, 0x8e3d062f,
- 0x3d024fc7, 0x9b2a6dba, 0x7d388a38, 0xf067d829, 0xa53d3b55, 0xfe113f48,
- 0x7fee8e5e, 0x4eff5365, 0x0ed273ac, 0x97ab9cb2, 0x30e4dc86, 0xd3f27dd1,
- 0xdc5e0b5e, 0x7f696993, 0xa59f11f9, 0xb42e1fde, 0xa9f697d4, 0x44ecbc16,
- 0xb4fda585, 0x7c160277, 0xd2daa47a, 0x35b38afe, 0x229c7c16, 0x5f7fafef,
- 0xe3e92f92, 0x7de44563, 0xba9fdfd6, 0xf788ab7b, 0xe1ad7bc9, 0x23d7534f,
- 0x4ce23701, 0xdec71cba, 0x404c5c87, 0xfec5cff0, 0xb183ce2f, 0x6b47e96e,
- 0x294fbaf7, 0xdd3f51c9, 0xff0db3f0, 0x01558295, 0xfdc3b9f3, 0xfba2f9e4,
- 0x6d7f86f3, 0x8bd3cdf8, 0x721ce27d, 0x26cabc6e, 0xc911c1e4, 0xc7d79c82,
- 0xfdf7b0d1, 0xbde44be7, 0xc6fd7621, 0x9fe762ba, 0xed95ec5e, 0x729f71f5,
- 0xc335edd3, 0x5cba33f9, 0x735f1c2d, 0xb8f9f214, 0x79677d53, 0x9e7f7fde,
- 0xb3cfa4ce, 0x2e5cde84, 0xb3675fd7, 0x31a3f889, 0x52a991cf, 0x7f380d5e,
- 0x7e3bfb0e, 0xe37deea2, 0x1fd87876, 0x21ddbc79, 0x9fc708e2, 0x2c1b515b,
- 0x01443f80, 0xef8e338c, 0x7c0fe003, 0xae1fdc0a, 0xfd176a99, 0xbd4897cf,
- 0x1265da8b, 0x24807976, 0x5dda07ff, 0x0c317ee2, 0x181c85bf, 0xcc7c41fb,
- 0x62e32051, 0x398b8880, 0x062e321c, 0x4031711c, 0xfe50c5c4, 0xf02a875c,
- 0x02151d83, 0x2023be7f, 0xd51d23f0, 0xa3bcfe02, 0x721b9446, 0xe32f4b13,
- 0x1ff0663e, 0xa373886a, 0xe71e4620, 0xe5f927df, 0xd9aceb5b, 0x6f9c5bc3,
- 0x24a56aa3, 0xa6dbcf4a, 0x2dc8794a, 0x3b407495, 0xed48ffe8, 0x2945ecaa,
- 0x900ea788, 0x47fbc52f, 0x53ff86e2, 0x6ee830f4, 0xfaa357dc, 0x2461f526,
- 0xbfee34bd, 0xd0acfba6, 0x8c7d58bb, 0xba58dbd5, 0xbdeb3f8b, 0x8d7bde59,
- 0xa7ae85f8, 0xbd0c5f06, 0x16a45276, 0x605425f6, 0xef7d06ab, 0xd1eab24f,
- 0xbe92a5f5, 0x8623d003, 0x74de7ca7, 0x7687ce1b, 0x5607f0af, 0x90ccb6e8,
- 0xec87e6d3, 0xf3e27ce2, 0xed37e3d6, 0x7db779b7, 0x6eef9ea8, 0xe215bfbc,
- 0x201d9d5c, 0xda5f1f71, 0x737684a5, 0xf5a086bf, 0x2521147c, 0xfae46fae,
- 0xe35fb817, 0x33f3d896, 0xf221d620, 0xe6b5bc2c, 0x72fd6b2e, 0x33c91efd,
- 0x632760ba, 0x96570af3, 0x4aa0e7ea, 0x5f7237ea, 0xdd105ee2, 0xa1572e97,
- 0x873829f1, 0xcbb4af70, 0xce3846b8, 0x21f3af74, 0x8a2a3fce, 0x0a133d33,
- 0x746e4e71, 0x177c13a8, 0xcf41a1cb, 0x9e833ca1, 0xeae7184f, 0xe23f753f,
- 0x8bc7cf8b, 0x7fcf057b, 0xbe76e823, 0xff40aecf, 0x7a08f287, 0x3b41f3fb,
- 0xe73e99d9, 0xba09c60f, 0x7e3b627e, 0x94cfbe4b, 0x5f28b877, 0xb015c941,
- 0xa8c6fb1f, 0x65d661c1, 0xfb222d40, 0xe1bf588f, 0x99ee3250, 0xfcc8cf2d,
- 0xbd33cb44, 0x7b2605e9, 0x10ea5cd8, 0xa6dbbbfb, 0xff2294b5, 0x8b9ddf60,
- 0x5f1dde7b, 0xce00a686, 0xb12de3d7, 0x77b219fb, 0x47211533, 0x613fbc03,
- 0xb115aaef, 0x0497b63f, 0x989b7b3d, 0x02ce3c9b, 0x34068f0a, 0x96da00f2,
- 0x2307c10a, 0xae10d00f, 0xb9b8fb10, 0x8133b973, 0xde76449b, 0x8be0955b,
- 0x392207e6, 0xc7fe08b4, 0x9b827948, 0xde315506, 0x886706f7, 0xcd281e71,
- 0xc6d0fe93, 0x1fe16bed, 0x3934f65e, 0x53888741, 0xa74b138e, 0xf3ca943f,
- 0x1d3c1320, 0xbadfdd13, 0xe7b08a0d, 0xc02ba0eb, 0x9ec22bb7, 0x5d67f81b,
- 0xf1255e3a, 0x3c49373b, 0x516cf4e2, 0x117ee452, 0x013ec02f, 0x6bdc1fb1,
- 0x05f1e9f7, 0xfb1003ec, 0x18ec3940, 0xe031d870, 0x61c063b0, 0xc76100c7,
- 0x6a94be50, 0x43e71172, 0xacd2a33e, 0xaa6e8327, 0xc825f934, 0xe4719867,
- 0x91edcc33, 0x23d730cf, 0x47ae619f, 0x238cc33e, 0x8f6e619f, 0x4719867c,
- 0x1edcc33e, 0x8e330cf9, 0x3db9867c, 0x7ae619f2, 0xf5cc33e4, 0x719867c8,
- 0xedcc33e4, 0xd730cf91, 0x58aededf, 0xb3b71df2, 0x35dc86f9, 0xf21348ee,
- 0xa6af3631, 0x7efe720f, 0x3977d7e2, 0xa3e7c1f3, 0xebb7212b, 0xc954135a,
- 0xc96aaee7, 0x3e491b77, 0x3e0ad7f7, 0x7892ebdf, 0x1de19a95, 0x1e422fc6,
- 0xe640b2a1, 0x47910011, 0x011e4400, 0x4a847910, 0x0023cc87, 0x72808f22,
- 0x910011e4, 0x1e440047, 0x04791001, 0x0011e440, 0x3f404791, 0x910011e4,
- 0xf2394047, 0x23c88008, 0xaf24fca0, 0x6304f903, 0x0ba3f05d, 0x963cf72c,
- 0xcf3dcb43, 0x47e1c16b, 0x8fc3db9b, 0x8fc3d736, 0x8fc3d736, 0xa3f0e336,
- 0x47e1edcd, 0xa957719b, 0xfc17e84f, 0xf83f7369, 0xb8bc66d3, 0x6212f82b,
- 0xfaefd744, 0x91808bdd, 0xc571e524, 0x41ec67cb, 0x4f7c8c5a, 0x4dc95e24,
- 0x545cf955, 0x192b8b5c, 0x844b06d7, 0x7ea14fde, 0xf22df81b, 0x2d37ccb7,
- 0xcde4214c, 0x14c8bf8b, 0x513e46f5, 0xfddf31fc, 0xe7f84907, 0x5d7245dd,
- 0xbc957f46, 0x7da34076, 0x5dbe1f14, 0x3b46fcec, 0xeb4d2f61, 0x1f9b0be0,
- 0xbdff7cf9, 0x2cad929e, 0x8a6d7b4f, 0xb2f74ff0, 0x1870b59f, 0xf74b34bb,
- 0xf6daf69b, 0x7ee04b1f, 0xba8a0dfd, 0xe89e8787, 0x09673ea0, 0x0256d4e8,
- 0xd4c2623f, 0xd47f3d54, 0x71616336, 0x3c46dd74, 0x0044ed8f, 0xfd99e779,
- 0x79e26ae4, 0xb907fd66, 0xb9cfe19a, 0x7e811fa4, 0x0e4dcfb8, 0x263d812a,
- 0xaa7cbef9, 0xe0b4ff3c, 0x5c4d19da, 0xdb5f793e, 0x77f8668c, 0x8fdfb209,
- 0x7416489f, 0xb2a361bc, 0x99fbcec7, 0xbb028fb9, 0xbe855db9, 0xbcfbc9ee,
- 0xaf3126ae, 0xce6cd5d7, 0x75caefbf, 0xa45f70f9, 0x88a66548, 0x3c842bc5,
- 0xde37419d, 0x1fd88bdf, 0xc43ef89b, 0x1d3d5765, 0x24d0fdef, 0xa93dad1f,
- 0x91cd7c16, 0x2687ef2c, 0x1f855b39, 0xeec4172c, 0x16adce21, 0xf5abe59d,
- 0x9a95b7f2, 0x9e784bcf, 0x0bbf7756, 0x35359bf4, 0x6c346ab5, 0x275251ff,
- 0x36a6ee40, 0xebc31a6c, 0xd50142d2, 0xdabd03ee, 0x93f8125e, 0xe2170235,
- 0x27d62e53, 0x4149c3ce, 0xa4c89c25, 0xdbb821b8, 0xebf19a36, 0xe99c1b83,
- 0x548fbf68, 0xf89303b8, 0x7449767f, 0xc274455f, 0x5e40af16, 0x499477a8,
- 0x7c72d8fe, 0x57e2f20f, 0x58f9049d, 0x613af0e0, 0x8dfd626f, 0xec0f77d8,
- 0xec2adc7f, 0x21d39f54, 0x3fdd3afc, 0xb5caf06a, 0x29d1b67e, 0x43868ffc,
- 0x3ea07fec, 0xde30dfc6, 0xa1dfb043, 0x1f8e7186, 0x720d4ebc, 0xb7dacb55,
- 0x7383bbc5, 0xa9bda179, 0xf2e7d72c, 0x0152dff7, 0x0aed90bf, 0x0dfb29ec,
- 0xb9654e77, 0x52f4d86b, 0x915dee32, 0x6fe101e0, 0xa1f1b67c, 0x905f1964,
- 0x9d2689f9, 0xa6fc464e, 0x9347e759, 0x03e5eefe, 0xa96c5bb6, 0xf186ee71,
- 0x2bd7815e, 0x3f588afc, 0x9bfbc891, 0x82bf5c99, 0xb195b3f7, 0x361adbe5,
- 0xfec5d267, 0xae6fe1a2, 0xb95de7d2, 0xb7de29d1, 0x3890a0ac, 0xac86560f,
- 0xfee957ed, 0xada7aae7, 0xca983fe5, 0xa1f2277e, 0xdfa9df86, 0xdbd4ee93,
- 0x7bdebc34, 0xda7bf0b3, 0x5075c89c, 0x07e906dd, 0x4d0a7ed1, 0xb5cf8050,
- 0x775e33c5, 0xc32aa028, 0xba9bcdc8, 0x931f343f, 0x0c173d32, 0xb23b0826,
- 0x8112f070, 0x299832df, 0x8583ade0, 0x19b11cb2, 0x4aa473e6, 0xe3c7dd09,
- 0x41fba5bf, 0x265e0f37, 0x198207ea, 0x58078e42, 0x14c5318e, 0x165d3edd,
- 0xd6117a50, 0x36d4ef9e, 0xf9fae18d, 0x95f849bb, 0xe25fc3d7, 0x9ff0458a,
- 0x7907a14a, 0x6f9f1855, 0x0f21346f, 0x9756b07a, 0x1203d67b, 0xec202376,
- 0x1082e559, 0xd22c93de, 0x6fc0dbf6, 0xe0b5fe43, 0xebf00729, 0x57cb8a83,
- 0xe215ee24, 0x77c86cfe, 0x27d41eac, 0x8f26f1ea, 0xc50d278c, 0x5e58b09b,
- 0xc5b5051a, 0x47afae01, 0x9d12f06c, 0xa4aa4cb1, 0x77df5922, 0x91bc5b50,
- 0x353fbdcf, 0xb367511e, 0xb3f57e09, 0x8a07b79f, 0x32aa274a, 0x94db27a0,
- 0xe8bead92, 0x9f289e7a, 0xba665033, 0xf5d52f27, 0x032ef58a, 0xdf758ef7,
- 0xc341909f, 0x6c0605f8, 0xbf433a64, 0x772253ea, 0xfeea4c29, 0x64a814a9,
- 0xbe92d6d6, 0x79fe244f, 0x3c758b9d, 0xdff6d0f7, 0xfa08f16e, 0xd4fcfc08,
- 0x45838b35, 0xac1d867f, 0x77d01c53, 0xadbe0ec3, 0xb7a0e768, 0x3cc8eead,
- 0xa8b135f0, 0xc5be05df, 0x6db6e7d2, 0x3127db3d, 0x24cb721d, 0x5d5ceaff,
- 0x80b8f14e, 0xd3dc4e42, 0xb9e48b1a, 0xee5f0e42, 0xf11f9112, 0xb19fb889,
- 0x6fe00fef, 0xf497430f, 0xc36fe932, 0xa4b9f63f, 0xff080c7f, 0xe04fef18,
- 0x7f87031f, 0x18ff080c, 0x818ff0e5, 0x0e063fc3, 0xfc3818ff, 0xc7f84063,
- 0x16d87f28, 0xf33f7538, 0x685b51f3, 0xd39661ff, 0xee6b47c7, 0x51ef9e32,
- 0x238f92ea, 0x63fb1348, 0x627611b9, 0x7cb13ec8, 0x72a3cbb9, 0xf4fdb4b4,
- 0x547e5b21, 0x7cb69a9e, 0xdc29f3ba, 0x841fd983, 0x945b6b3e, 0x9194dc70,
- 0x3b89ece5, 0x3cbe8412, 0xd84b8f71, 0x89d73add, 0x5179dc97, 0xfedbbe7a,
- 0x27694eb7, 0x3c7c13c3, 0x78b6e2ee, 0x89ff7615, 0xac1c9af2, 0x1548b137,
- 0xd9c0197c, 0xb256f88e, 0xa5f28796, 0x4ce5e274, 0x57ff576e, 0x7ea2e7af,
- 0x173cd1cd, 0x11c36fec, 0x1f4ce6ff, 0x21136bfa, 0xaf1e0daf, 0xeac5fe0b,
- 0xbce2a98d, 0x7190cfad, 0x9140965c, 0x31f83307, 0xdfc64cbb, 0x80ef79fa,
- 0x127bf417, 0xc0b9c813, 0x2df24ed2, 0xb88cdf56, 0x2b5c6c62, 0x72795f1a,
- 0x22e23e4b, 0xf4ed49a3, 0xc42f4c5d, 0xd1255c3d, 0xfc6c4ab8, 0x5d5f4863,
- 0x19e78964, 0x7e994d70, 0xa9efd74f, 0xd4f743cd, 0xf01979a2, 0xbc541fe7,
- 0x79373f88, 0x674eb77c, 0x89cfa9bc, 0x3f348817, 0x62cae7cd, 0x8afbffbc,
- 0xbdf80f77, 0x56ec2fde, 0xebc2781d, 0x2151da69, 0xc429b6f4, 0xfac8d470,
- 0xdec1e4bd, 0x5f619f9c, 0xeb0b80e1, 0x5c06f26c, 0xa77f2669, 0x98094bb1,
- 0xf819fddf, 0x8e3265ed, 0x07d7c758, 0xf5b6efd0, 0x88a5ae79, 0x83dbb25b,
- 0x746b6ef7, 0x71fa3139, 0x625ef13b, 0x0cbd3e7e, 0x7de7eab9, 0xbe616ec1,
- 0x4bf8d312, 0x7e69be31, 0xb5fc2f6e, 0x62496595, 0xef2f06bc, 0x2bd00f3b,
- 0x1074c9d6, 0xcedfea74, 0x3cc4f9e3, 0xe18dee82, 0x7ac55390, 0xf1834ef0,
- 0x1390dec5, 0xe8dd2cf3, 0x6d7ef117, 0xdb479c9b, 0x862aea92, 0xbaf0e73f,
- 0x1e7ecc72, 0xb2e41dcb, 0xd1fa970e, 0x0fc2bd62, 0xa53a626e, 0x634cffc1,
- 0x3173d7bf, 0xf5f41abd, 0x5aa57537, 0x07aec6fd, 0xad4fe09d, 0xf2c4ae7e,
- 0x8e5d31e1, 0xcabc6e97, 0x08efe845, 0x533ef0b8, 0x6ffde9d3, 0x22b7e36b,
- 0xfddb523f, 0xf18f3388, 0x4fd265ed, 0x46740c7d, 0x3c3f383c, 0xfa53ef01,
- 0xf78bc6d7, 0x2edeb5b6, 0x7a21dfb1, 0x81f4c43f, 0x11ade25f, 0x093966f4,
- 0x535afde2, 0xd1bf95b7, 0x718924f5, 0x841bba9b, 0x68732dfe, 0x1d79af2e,
- 0xa0985e3b, 0x596a5d30, 0x3f9c15ef, 0xf2172d5e, 0x5ba1e673, 0x793ec573,
- 0x9273a09d, 0xd8879bea, 0x908dcb04, 0xea7e436b, 0x1b3ea54b, 0x932c1df3,
- 0x65839cf1, 0xbfe9c7c3, 0xb69b4f4d, 0x71005035, 0x15524cbc, 0xd4f5dbe5,
- 0x5f434fd0, 0x6538f56b, 0xa405b6e3, 0x9f0dec99, 0x0dcf6ddf, 0xdd019f43,
- 0xf9d62c9e, 0x917cf4c9, 0xf7baf14c, 0xe5d67e74, 0xe31ef55b, 0x7557dc61,
- 0x139bafbd, 0x28b6b09e, 0xb798deda, 0x83f64d2e, 0x5ece43fc, 0xf682e9d5,
- 0xdd7b44eb, 0xa376e99e, 0xec6ec871, 0xbb0e94db, 0x79115fb1, 0xa5db75ab,
- 0x99eeb75f, 0xfadf1124, 0xdf8775f7, 0x9ddb85b8, 0x3d77787b, 0xabac6bf6,
- 0x44ed2c29, 0xb053fb33, 0x73f4cb1b, 0x7b58b3bf, 0xc7a4cca7, 0xccf77f4d,
- 0xe2c5e844, 0xdf99ff1e, 0x1877d892, 0x67bde6f6, 0x0cf6f17e, 0x357cf45f,
- 0xcb74b1f6, 0x3c1b38bf, 0x7dc9ba66, 0x2a5c2d6e, 0x5f8139de, 0x6e357fb8,
- 0x81de4454, 0xffc25dda, 0x2b1df834, 0xbfac0d07, 0x1ca89e8d, 0xc91ffc18,
- 0xe50d726f, 0x0dff24e7, 0x60721b7e, 0x13e0dbf0, 0xf9359ce1, 0xffbac6fd,
- 0xb17bafa0, 0xeb5fbf2e, 0x4578b77a, 0xd0996b9e, 0x23573cf7, 0xafaf5ee4,
- 0x0f96b26d, 0x643bc9f1, 0x2f4337df, 0x9f247a06, 0x6539b606, 0x45df721c,
- 0xb9c5ca7c, 0xb963ac6f, 0xd66c6f1e, 0x74cb86e3, 0x94f9983f, 0x6a665e54,
- 0x53e484f7, 0xffafb3e3, 0x627dcfeb, 0x6d8ed27f, 0xe2fe138f, 0x82fd9ed2,
- 0x1e5bb55f, 0xbb71e674, 0x7719729c, 0x6df3b21c, 0xe7e22f7e, 0x76ecb78b,
- 0xca73ff42, 0xe562dd25, 0x077f4ebd, 0xe715d06b, 0xf73a628f, 0x7bb0f68c,
- 0xf59e79fb, 0xf193e36b, 0x6798c6ae, 0xe394b95e, 0x34d4b6c6, 0xd6d8d7cc,
- 0xabdc03f0, 0xab1fbb0c, 0xa5e3a777, 0xf1e52c3e, 0xafa797a0, 0x15d77352,
- 0x332f9c5d, 0xc972ace0, 0x79311fb7, 0x3b258ef1, 0xe227e7b1, 0x049ac41d,
- 0x82e5f915, 0xf3084882, 0x6eb18e42, 0xbc45db17, 0x89682987, 0x14758a7c,
- 0x02ff7c90, 0xf3269498, 0xef8ce91f, 0x305765e1, 0xd84bb7cc, 0x2107d3a8,
- 0xe8d3d434, 0x1ff61948, 0xf246b76b, 0x34f90c2b, 0x53b589c6, 0xc96fed23,
- 0xe9dfdc77, 0x525e3d3c, 0x79bae6a8, 0x4e1ffade, 0xfa3f1152, 0x12ba7db6,
- 0x6869be64, 0x15ac2cbf, 0xb7ecc369, 0x4683de40, 0x55776fde, 0xbdfb30fa,
- 0xebac0f28, 0x7bd6f189, 0x25d23f28, 0x15a723f3, 0xdfb8b73e, 0xe2f1b5e9,
- 0x2fb199bd, 0x5dff3e23, 0x9477e7df, 0x8b71e9a7, 0xc9fc1248, 0xff5d04ba,
- 0xf94712c3, 0x71b95302, 0x46f49fde, 0xf64cd292, 0xfd36c3f9, 0x76c8a43c,
- 0x1f6f8311, 0x9c73884f, 0x649d3aec, 0xca7c822b, 0xd6fd19f5, 0xed93d53b,
- 0xe29b73b0, 0xf66efbc4, 0x8e23369b, 0x154c1cd4, 0xdadb99f1, 0xe0eccf4b,
- 0x98db6e71, 0x5ebf0aad, 0xe997f3f7, 0x7d712ff6, 0x6869e6c3, 0x0bcf23bf,
- 0x53d9be3f, 0x2dfc42e3, 0x2b817bb1, 0xf2bdf85f, 0xabe4601e, 0x03542bd6,
- 0xfb0e5bfd, 0xbdb2bd08, 0x66f38050, 0xffe90ef9, 0x16d1b7cf, 0x75c73be4,
- 0x82cbccd6, 0xa8a9d87d, 0x176927f0, 0x7ee351db, 0x6923b6c6, 0x72cecd4a,
- 0x962bebd0, 0x32ff1e3b, 0xec76b19c, 0x7b8027a7, 0x817fb127, 0xa03d60fd,
- 0xb4b9564b, 0x4fbb278f, 0xa28af925, 0xbf53fcf4, 0xc2e4317f, 0x23359bc8,
- 0xf20a33ee, 0xf90e9751, 0x63f3d268, 0x0ae7bb9b, 0x4df779bc, 0x4e973be2,
- 0x647be634, 0x0f5583d3, 0x733e5907, 0xb5347a75, 0x7e01bdce, 0x713d8ad1,
- 0xe35ee2a9, 0xfd9ae60c, 0xf7dda6d0, 0xce5eef8b, 0xdf178eee, 0x177a54bd,
- 0x3ef2a654, 0xf54aed97, 0xc2e74ddb, 0xddfeba2b, 0xf2d73ad1, 0x8f334afd,
- 0x7ff1e5e9, 0xde2893df, 0xa5df192f, 0x8ed6e55c, 0xfbe34ec1, 0xf93ee994,
- 0x68964a5d, 0x3e361bef, 0x1d33c06f, 0xd3073bf2, 0xd4373677, 0xd696ff72,
- 0x6718c903, 0x956f43d5, 0xd7108533, 0x1a7c037a, 0x8766cefa, 0xf9a6cefc,
- 0x77bfe1a1, 0x3e435c81, 0x4b211c57, 0x50b6f17e, 0xb543f08a, 0xef90b930,
- 0xfc24bcd6, 0x6a76b3dc, 0xf86eb9c7, 0x44794625, 0x94d9c3a7, 0x7ff05cae,
- 0x7247dee5, 0x9c7c6e71, 0xbdbaf124, 0x7612feb7, 0x4e327b48, 0x120edffa,
- 0x50636dfe, 0xf7c6cbfa, 0x1baa4453, 0xe573f0f7, 0x95bc6289, 0xc63877fa,
- 0x10bfd8ba, 0xa83b1fe5, 0xf7c0eb1a, 0x77e79035, 0xf066e11d, 0x47f65df3,
- 0x4578ef91, 0xbb77bf97, 0x7bc4f3ec, 0xf8045622, 0x1d76ef15, 0xd11e4248,
- 0xecaac3f0, 0xf0ec05ef, 0x7e290e97, 0x4589c39c, 0x863dc427, 0x6ac978f4,
- 0x75b794af, 0xcbce733f, 0x2afc2d1e, 0x08e2d251, 0xd7e386bb, 0x34dfba1d,
- 0x2fdc1f84, 0xfb2d65ee, 0xd2d05fa4, 0x05f84a73, 0x7c619f86, 0xdf6ab747,
- 0x1827e129, 0x941f56fd, 0x283d6974, 0x6d0a1bcb, 0xa025bc46, 0xacbee014,
- 0xd9727c08, 0x38364bfd, 0x25e6f8cc, 0xbd000a1b, 0x5fa43c7a, 0x0b5be5f8,
- 0x33ee257f, 0x71f51bad, 0xe69a7719, 0x4636994b, 0xe5c5c77e, 0xefe83de3,
- 0x5adfdcb3, 0x50fbca0f, 0x8b6135b8, 0xdabb1778, 0x6cec00e3, 0x7cf388f5,
- 0x10ad9b57, 0x4a03c9ef, 0x8ee7f082, 0xc6b9efea, 0x3c4dfaac, 0xd45904e2,
- 0x13cb6bdf, 0xa7f2b8ef, 0x14193cf1, 0x8cbaef14, 0xfc2e67ef, 0x18a547e3,
- 0xe45c767f, 0x97802200, 0x096c7b4e, 0x53b325f2, 0xf8a0a522, 0x951f87a5,
- 0x00e44678, 0x60de50e2, 0xe9ca92f7, 0x695c467f, 0xaf8962be, 0x6568adbf,
- 0xe0eb4120, 0x6b8c9779, 0xfe7c8bf4, 0x8e52698c, 0x7be31cc6, 0x5f51ee24,
- 0x303dc478, 0xf89b5463, 0x228a8bae, 0x147768a5, 0x823e587d, 0xf084265f,
- 0xc93c8c3e, 0x983ccf32, 0xa8ef121f, 0x30df32dc, 0xf02e9fd0, 0xb431ce30,
- 0xda2dd4ff, 0x5dd1cac7, 0xa0fde4d3, 0x63e64e26, 0x399c546f, 0x9b9300ff,
- 0xfa0b5da7, 0x8bdbe4d5, 0xdef1e3fd, 0xbf03be4e, 0x0d6de7a0, 0xbe8e797f,
- 0x9efd1caf, 0xd324bae7, 0x0253fd03, 0xe5ddf101, 0x1ac7457d, 0xfd03ff31,
- 0xd0fe426e, 0xa738c778, 0xabde413f, 0xe716a92e, 0x5073e2ab, 0x563fb71d,
- 0x1de30b64, 0x16e403ff, 0xc7726579, 0x78b6d9f8, 0x395b1ef1, 0x3817cafa,
- 0x9fedb267, 0xfef0a6f6, 0x5152ffb3, 0x07eb8361, 0x26f63cce, 0x3dc1bac3,
- 0x7d8fb1fb, 0xf6235ac9, 0xfaa07271, 0x7e24c694, 0x56e3dbc0, 0xe645f9e5,
- 0xfbbd1ff5, 0x5b34e48b, 0xfa175d74, 0x78733ccf, 0xc45ba02a, 0xb51ce7a5,
- 0xcc5638cb, 0xfa642e7a, 0x6e70bbc4, 0xc17ee827, 0x5ee10b63, 0xef68e738,
- 0x1cdf583b, 0x7dc677bc, 0x6f3cedc1, 0x97c8e73e, 0x1af78a93, 0x64df9d30,
- 0x1ac0ed47, 0xef4a3cfd, 0x0579bdf4, 0xed57c9ce, 0x73037884, 0x963ff052,
- 0x1fc16f7f, 0x699ce3c1, 0x2a36def2, 0x4d3826bf, 0x072863e8, 0x3ed338fa,
- 0xd0b53bfc, 0x638f4534, 0xfc1a7e49, 0xf063f832, 0xdd33a0c3, 0x14a5e270,
- 0xf8b7d045, 0x3fae9287, 0xe2fd7410, 0x4b5626f8, 0xd70fe4ba, 0x7ffefa0a,
- 0xfbc8eba3, 0x0d85df93, 0xde1eefed, 0x7f659e5f, 0xda5ffd3f, 0xeff7d09f,
- 0xd613bfbc, 0x8677a5fd, 0x4e4127e3, 0x7f09b21e, 0x28bdf62a, 0x97b09215,
- 0x1104f6f5, 0xe412d537, 0x276c06f7, 0x349d825f, 0xeab8e3ec, 0x8afc3148,
- 0x638f4493, 0x8f5b115d, 0x5a78ff28, 0xb19390be, 0x7c4b2274, 0x9488e137,
- 0x54ed6fc1, 0x76dd3b02, 0x8733c8c0, 0x7a565f61, 0x42edde44, 0xf27416c8,
- 0xa1a9ddf8, 0xde78cb9d, 0x448b9bee, 0xd102e51e, 0x1f382394, 0x7f082457,
- 0x84953bb4, 0x9daeeadd, 0xe796fc28, 0xc2e7b6bf, 0x4dafed5f, 0x6edbf910,
- 0xfc3b647f, 0x3e09eecf, 0x7f4dc835, 0xf844d0a1, 0x6e05c1ab, 0x02f74f31,
- 0xb7bb0769, 0x83f7c8e7, 0xf209fa14, 0x48ae8f48, 0xeec17910, 0xc42c81dd,
- 0xd24c3ecf, 0x2e1f434e, 0xb873cbb1, 0x19cb8f3b, 0xd4d4ac3e, 0x62bc6336,
- 0x6d48eeb9, 0x797bb3c2, 0x3602f894, 0xb27e5c99, 0x6be4493d, 0xe2317d0d,
- 0xa782e3d5, 0xc64e8276, 0xebefb677, 0x5dd065f2, 0x0eefc809, 0x721bfa0d,
- 0xbba75a36, 0xb794af72, 0xabc7f7a1, 0x1e3fbc49, 0x77c04bcb, 0xaa71f56a,
- 0x32be740f, 0xeb12fb45, 0x7ccb5cee, 0x92fd63b1, 0x1df127fe, 0x95fe30e1,
- 0xd38f42b3, 0xd45fdfe8, 0xf523b493, 0xed16f7c6, 0x282defd6, 0x79153632,
- 0xdc47213b, 0x9abef7ff, 0x8dd80ab8, 0xc125df82, 0x4fff1c6e, 0x80efb0fb,
- 0xbcf215bc, 0x296bc4f0, 0xfdfebda2, 0x1f5fe189, 0x83947ff7, 0xdde4e273,
- 0xfc058caf, 0xad26a92a, 0x70f5d782, 0x70f3e7ed, 0x159fbd74, 0xbccddf11,
- 0x8e65fb5f, 0xfbdfb788, 0xeff7908a, 0x02ffceba, 0xb38b7a5f, 0x000040d0
+ 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, 0x33b3af8a, 0x21716830,
- 0x9f0143f8, 0x38606664, 0x8167c40d, 0x81859798, 0x818997c1, 0x78898fc1,
- 0x10c533fd, 0x0611416c, 0x5e203b06, 0xf0c0c42e, 0xce21044e, 0x10c0ce28,
- 0x20c0ca2d, 0xafe10a2b, 0x6266d204, 0x40ff71d4, 0x4c194663, 0x089207b1,
- 0x79161336, 0x268ccc64, 0xca8520ef, 0x7fa02167, 0x2517f1a0, 0x22acbe54,
- 0x8a846e84, 0x9793457f, 0x432bca83, 0x094df5fd, 0x502ab9bb, 0x1aa00079,
- 0x03605f82, 0x00000360
+ 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, 0xd554780d, 0x733ee8b5, 0x49999cce,
- 0x21264cce, 0x61021309, 0x40a02092, 0x200c7e18, 0xf7f09d78, 0x803aa568,
- 0x07515a56, 0x43f21081, 0xbd1f5202, 0x24266bed, 0x1bd568c1, 0xab45a8fa,
- 0x68a90076, 0x62348ed1, 0xa80740a8, 0x0db6a85c, 0xc7f42ad6, 0xc405ad1b,
- 0x96aa4490, 0x6bb94abe, 0xe64fbdad, 0x4019939c, 0x6f5fb7bd, 0x6fd697bf,
- 0x67d9cfb3, 0xdfd7b5ef, 0xb5ed6b5e, 0x897628f7, 0xec650ee5, 0xc75dfe02,
- 0x319902d8, 0xf4a27576, 0x0d0ebbc1, 0x07f8adfe, 0xccdd2832, 0x2862b12f,
- 0x2f6e2cfd, 0xfc707281, 0xd65e9618, 0xf37e18c9, 0x959905f1, 0x3271e632,
- 0xb09417f1, 0xdaf2f5ee, 0x6d87b2b7, 0xd5b28428, 0x6cc653f7, 0x67aaed8c,
- 0x44f66181, 0xff57873b, 0x91c17e2e, 0xfa4870cb, 0x877560cb, 0xbb87c187,
- 0xb6e2e7a4, 0x8ef58c89, 0x7e2d8161, 0x5dde0718, 0xcffd059b, 0x316dec61,
- 0x704605e6, 0x8a50b85c, 0x4b8231df, 0xe73af8fb, 0x0ee76842, 0x00c55fad,
- 0x7334cf5e, 0xb9a26d7b, 0xf50d18ee, 0xa5fa8991, 0x6ca603da, 0x881de00c,
- 0xed5c03f0, 0xd79a4ef5, 0x81bdeb8f, 0xb6305761, 0xf547dea7, 0x2a7ef57d,
- 0xe923f5e3, 0x00fa81f9, 0xb05873d5, 0xeac7f090, 0x66ca2c36, 0x8536f1ac,
- 0x7412c7dd, 0x8c3d66f9, 0xfea24577, 0x222cd1a7, 0xa4fee4c3, 0x00423bb0,
- 0x132bc36b, 0xbca13a32, 0x7f41db1f, 0x28018d0f, 0x3fda26c6, 0xdce5f6bc,
- 0xcb181399, 0xdc91eafb, 0xbde00399, 0x46c616c4, 0xd2ad78e3, 0x9df031bc,
- 0xdbd1fbca, 0xeb6325eb, 0xed9a0f88, 0x65afdfc9, 0xf2cf0212, 0x7e60ac0e,
- 0x0f6bf437, 0x07013be7, 0x04c644b7, 0xb8c3065b, 0x186bec48, 0x111b32fb,
- 0x370e0089, 0x8c799761, 0xf342d0ed, 0x5f1cbbf0, 0x91230a48, 0x299c40c3,
- 0x2cab658c, 0x470a4b1c, 0x2b71c103, 0x4b0733fe, 0x0f4bd53f, 0x7ef571f2,
- 0xe711b2f4, 0xcee4e507, 0xde2c5b30, 0x77fbe197, 0xe862d242, 0xe7c5d9bf,
- 0x736302f3, 0x1249bc70, 0x12b9610b, 0x2dfa1299, 0x312732c7, 0xe5c60aee,
- 0x6173bae1, 0x547e8416, 0xc785985f, 0xfc837ef0, 0x6c8ca6fb, 0x1b7f9b9a,
- 0xda9443f1, 0x474ddb1b, 0x88b6fcb8, 0xedc7033d, 0x23ed883d, 0xf6c3163e,
- 0x39b6682f, 0x3b44b45b, 0x6e499e1d, 0x968b685b, 0x16c82fe8, 0xe5d3fa9b,
- 0xbe72764d, 0x81def9d3, 0xda9c809f, 0xc228fbe1, 0x3705983b, 0xbdebc127,
- 0x07a5be62, 0x3c06415d, 0xa3542ead, 0xafa9242e, 0x39eb0cb5, 0x0640594b,
- 0xe5eb4e1a, 0x0703b8f3, 0x3bcc49c9, 0x37c003e7, 0xfec01d94, 0x08e3e60c,
- 0xda03a8b0, 0x826b79ab, 0x1f4f5065, 0x1b02d5cc, 0x3672631c, 0xcdc473c9,
- 0x97a1c3fa, 0xfc13c7da, 0x00df1748, 0x0604ef5d, 0x41dba832, 0x78020ca1,
- 0xa83b8f1a, 0xe5dc8fff, 0xfd33b143, 0xf1f553bb, 0x3e414b71, 0xa61fd74e,
- 0x83beabb2, 0x63faeeca, 0x0f1aa654, 0x26c6d124, 0x60df8c03, 0x5dca2741,
- 0x075d12a1, 0xffee37fd, 0x218ff32a, 0x878823f8, 0x2d16cd74, 0x4e665e42,
- 0xf815cd59, 0xe12b7c45, 0x8e6ef9bc, 0xbdb3c45f, 0x866d0950, 0x2ad9cf32,
- 0x786d1aad, 0xfc40740e, 0xb87c1e97, 0x2ea4f101, 0x855ce365, 0x4f9c2f28,
- 0x97c89f11, 0x5f381abb, 0x284efd62, 0x029539af, 0xef1c5def, 0x53a9dada,
- 0xc06099df, 0x5c82c29f, 0x28bf39ae, 0x78c77ff0, 0x7b343a80, 0xbde82645,
- 0xbc077fbc, 0x9e7d268e, 0x906b95c1, 0x9e2adea1, 0x30ddebac, 0xabd27e23,
- 0x5079edc0, 0x97cfac1f, 0xf8897ff9, 0xfa04dcd8, 0xd57eeb09, 0x21fbc2af,
- 0x70e0f5a2, 0xca545cc5, 0x1ee7cb5b, 0x62bc6092, 0xa8fde3f9, 0x29d487de,
- 0xf41a776f, 0x6042c165, 0x86c622bc, 0x2f3f35ae, 0x30eb988c, 0xf3042d80,
- 0x3f316e2f, 0xd9dcce3f, 0x2e19d227, 0x80906e48, 0xbd5af37e, 0x849a45ec,
- 0xf58dde95, 0x0dd9ae2c, 0xf427a175, 0xdc99e4ba, 0xadf98119, 0x900592be,
- 0x449269c6, 0xefc56c78, 0x141e8f80, 0x7e96fde5, 0xac9952f4, 0x02ef50d9,
- 0xf4c983de, 0xd654be58, 0x56bc748b, 0xfd8bde9a, 0xe6312ba6, 0x54bf90d5,
- 0xfb6b13e2, 0xf1a14934, 0xa08e94d3, 0x14deeb8c, 0xb6adeebe, 0x9e51c6f7,
- 0x03f99756, 0x028f5c11, 0x4cdf9251, 0x5e50b358, 0x363c013f, 0x9363c389,
- 0xf5189c68, 0xdb2beb03, 0xbc38e122, 0xfa57d5df, 0x0d4a4459, 0x2d191fe7,
- 0x1698ec62, 0x3cfec4ce, 0x709ca492, 0x58d3e826, 0xb36ff451, 0xc372eaa1,
- 0x7513abfb, 0x7c739ddf, 0x4379c7c8, 0x772bf4cd, 0x7f2015d6, 0xb3628654,
- 0x7a4e7f91, 0x0edeba7e, 0xf602def3, 0x9ff80282, 0x61e50ce4, 0xea8b353f,
- 0xf30aa386, 0xe303a2e3, 0x1eb7b26e, 0x39824b07, 0x5ff48859, 0x0175cccb,
- 0x67dbde05, 0xf03b712a, 0x01f27da5, 0xac5c57b2, 0xc9c7eb8e, 0x07b43291,
- 0xef83239c, 0x455ef0ca, 0xdee78079, 0x75c32b60, 0xbccc39c4, 0x9b3c83ce,
- 0xb9b64aea, 0x5ccf4a9e, 0xf8ca5caa, 0x84069efa, 0xb267fc22, 0x995fe228,
- 0xf841281c, 0xf3e6bc1e, 0xaa67847e, 0x84a5d7c4, 0xde72e2fe, 0xbfb5ef47,
- 0x00361dc8, 0xf972b79f, 0xee4afb5f, 0x8f8809b0, 0x73979a56, 0x0b926ac6,
- 0x7323f115, 0x13b90ff9, 0xf878ebdf, 0x961bcf7b, 0xf4979a05, 0x5027f393,
- 0x6f3e363f, 0x9f9ea3f7, 0x7e3dbcf1, 0x366bd41d, 0x6df7a44b, 0x9f845cfb,
- 0x3d7947ee, 0xd88356ee, 0x5013ccfe, 0x3ad57c07, 0x8a9c1e3a, 0x665e7bf8,
- 0x0b3d085b, 0x4ecfa86d, 0x3b68f6e8, 0x78bb97af, 0xfef366b5, 0x8afbf1db,
- 0x7d430776, 0xf97bb35c, 0xbea1530d, 0x619db0fc, 0x0d6d9a93, 0xafa820ea,
- 0xac314a88, 0xf4e74cf7, 0xa392ec89, 0x8f7da0db, 0x66f723a7, 0x271dd70d,
- 0xb8008ff3, 0x37b91ddd, 0x46571f01, 0xdf8d9b9f, 0x0290ee55, 0xc7983140,
- 0xf07943b6, 0x5253cd5d, 0x5c7c01c0, 0xf99d3db5, 0x89e5f60d, 0x1d7e3936,
- 0x93cc19ca, 0x59cbbf41, 0x4fa46ceb, 0xaa0db6cd, 0xd39f40df, 0xdf9923f5,
- 0x3cd7a891, 0x77c0e305, 0x02959f2b, 0x3695c538, 0xef753f6e, 0xaadc2d76,
- 0xd41afce1, 0xd79c6ee1, 0x5bb62a3d, 0xcbbc5d1e, 0x36f847e5, 0x7de1b3ab,
- 0xd59ba3e5, 0xa85e8372, 0x640a3eda, 0xa6d700c9, 0x24e181e2, 0x0f01237a,
- 0x8953c133, 0xedd6867a, 0xa5768aa8, 0x2daa7cfe, 0x6ab1f893, 0x5fea6cbb,
- 0xd7e47ba7, 0xc887ec8c, 0x55e1375e, 0x2f6adba7, 0xa08eebe3, 0xa0af59db,
- 0x6a5bd2a3, 0x1f2f5fec, 0x50383a44, 0xfca97b5f, 0xca8fbd56, 0xa27ef58d,
- 0xbf8843cf, 0xc64edc11, 0x97d760e7, 0x827b2f21, 0xc3ec0bcc, 0xcb06e6b2,
- 0x0acf50ec, 0xa2ee7af1, 0xc8bfe4b0, 0xec12f5fc, 0x04e0c5de, 0x7afdfac1,
- 0xf63b0150, 0x8abc3521, 0xa6fc6005, 0x04ce08ff, 0x528ff77b, 0x4afa8638,
- 0xb82b85b6, 0x287cc5dc, 0xfac5eb77, 0x13f25db3, 0xa9e7d61e, 0xba1f6fa4,
- 0x2cab74ad, 0x6366b989, 0xf7fbfcbd, 0xbb3f5215, 0xfa151fa9, 0x3f74be29,
- 0x364fb7b9, 0x7b7b93f5, 0x01cfde85, 0xf2ed27ea, 0xf6e879fa, 0xdcf0cc6b,
- 0xf3f7a95e, 0xb9e3f532, 0xdee579bc, 0xcf0ccd31, 0xcfd4d51d, 0xd20145c0,
- 0x3fceb2b7, 0xb43bd60c, 0x8e647717, 0x5341fa37, 0xc0dfd36d, 0x520dc5f5,
- 0x8ca3e465, 0x792669c9, 0x99660cca, 0x0ce603ea, 0x09cfb532, 0x0fde9915,
- 0x8595785c, 0x89ef352f, 0x408ea251, 0xf68b43a1, 0xf49520f1, 0x2720d94e,
- 0x20f77fc1, 0xddcef48d, 0xe04784d7, 0xa2b08e3a, 0x1ab7737f, 0xea4deb1e,
- 0xcc4874c7, 0x86dfa587, 0x3dfdf5a5, 0x9e9c1ec2, 0xb7f0f1ff, 0x5b5afbe0,
- 0xa84cf0ef, 0xfb2b6bbf, 0xbcf9e233, 0x3269ffd0, 0x6976c3ab, 0xeffa460e,
- 0xadd2c29e, 0x5b5e0311, 0x48bf0086, 0xec5b7e89, 0xa3f21f61, 0x901a9364,
- 0x510fd73f, 0xfa041b19, 0x1fdb1d74, 0x9ee73581, 0xc43ee521, 0x2ffd03bf,
- 0x8c2af8e3, 0x77c69a3f, 0xb77c60d8, 0x8ef8f92d, 0xf1a6c9a2, 0xa615059d,
- 0x8c2a9df1, 0x6991f20f, 0x9df18973, 0xad6617e4, 0x8ef8d273, 0xff1a0a82,
- 0x9855951e, 0x1beb4fc6, 0xc60da07f, 0xfee3621d, 0x17f9bf4a, 0x7f9e635d,
- 0xfe79a541, 0xa17f9f2a, 0x9f8c532d, 0x5a2ff346, 0x2ff3e5e7, 0x77f3e4a8,
- 0xc6fb7ef0, 0x7fe1f4f7, 0x263f8e04, 0xe28ef8c5, 0x0ff9e669, 0xdfcf36ad,
- 0x671fc7c1, 0x6be313cb, 0x75f8fe34, 0xa1ff3e3e, 0xeabe34d5, 0x8f900708,
- 0xbab4fcd4, 0x8343da28, 0x240dfb41, 0x72a4181d, 0xbb93f724, 0xe38222a4,
- 0x77ce34ee, 0xbf01a51f, 0xca7d0969, 0x9e29eba2, 0x74f052b2, 0x35328ed5,
- 0x07bc5a3c, 0x00997f7b, 0x4cbb6975, 0x3a36cd7c, 0xbc0057a2, 0xf932eddd,
- 0x5e374b3b, 0x3d69951b, 0x1808fee5, 0xfe7c7190, 0xd98f6fc7, 0xb5979c62,
- 0x3f6ad65c, 0xab9069d1, 0x9d3efd3e, 0xf803ac8d, 0x535e4836, 0x69e804fd,
- 0x06dea674, 0x49e58c7d, 0xf3c0338c, 0xb38f4077, 0x7ffdfd11, 0xd1b5eee8,
- 0x0a2faf30, 0x1c284ff8, 0x48d627df, 0x47ffc451, 0xa8a9561b, 0xa6b596cf,
- 0x07d3d1a3, 0x53a0ad47, 0xd9076eef, 0x3f4f8055, 0x1216e7e2, 0xbf7ec645,
- 0x24870bef, 0x6f967bb0, 0x6efa601a, 0xfb368b11, 0xfb92fda0, 0xc2f10f17,
- 0xe85d6ffc, 0x1f932f18, 0x91b7cc18, 0x1b7cb31c, 0xdb0b4ef8, 0xa1f3d836,
- 0xbb42cb72, 0x52f94fc9, 0xb5bf5cd8, 0xb6ef5cc2, 0xcf18ed47, 0xb1215eea,
- 0x6defd0cd, 0xff8b7675, 0x6159c7c3, 0x08f112cb, 0x8117de3e, 0xe8f07986,
- 0xe3c72c36, 0xf5d12f63, 0x56ff2f76, 0x6bf6a787, 0x90547076, 0xe8399d7e,
- 0x0e48b347, 0x2f6177f9, 0xde15b79f, 0x60ceeddb, 0xfdb9e008, 0xd3e132ab,
- 0xbee77f0a, 0xec0da0f4, 0x7f4dced1, 0x6e7da3b2, 0xfe158f9d, 0xe75ad63b,
- 0x7d7155e3, 0x3eb11c58, 0x5aec988f, 0x2f6dacbd, 0x818efadb, 0x9f626a9f,
- 0xe18efadb, 0xf3edaabb, 0xd115f54c, 0x2fda992f, 0xf4d8b4df, 0x0aeb597e,
- 0x2d25fbd3, 0xc5f54cab, 0xda9aaf91, 0xc1b6b1df, 0xbab6fef4, 0x6fef4d7b,
- 0xaa60d8ad, 0xb0fc297f, 0x0b2dfda9, 0x4bde9b37, 0xed0c56fb, 0x1e1abd24,
- 0xeb76879a, 0x59f90771, 0xf2ebbf3a, 0x16ec0a70, 0xdd834f2c, 0xca036582,
- 0x6dbfc829, 0xb76b2f37, 0x35ea1e2c, 0xed2761f8, 0x4f280575, 0xe2b7be56,
- 0xf0dfcad3, 0x1d6c9f97, 0x8c6acbd2, 0x3dbf4143, 0x24393f16, 0x1f1ea0f4,
- 0xdcb956ac, 0x9bccef56, 0xb57ffe8e, 0x975e1f1a, 0x93ec4fc4, 0xf34498e7,
- 0xe7a56860, 0x5b80dd20, 0xdaab780d, 0xb3826c5e, 0xe34cbf6b, 0x05d944af,
- 0x0a5f37fd, 0x88f5c71d, 0x2c160fc5, 0x04f08318, 0xf6f5437f, 0xbb7f5a1c,
- 0x7d6ce7ea, 0x0bf88ec7, 0x7eaa7951, 0xea279521, 0x53be54c3, 0xdbe5415f,
- 0x765475f5, 0xf2a5afd6, 0x9508facd, 0xa16fabbf, 0xadf537f2, 0xdfab1e54,
- 0xf5ebe544, 0xebbb2a51, 0x7cea5483, 0x4327a7db, 0xfe156ec2, 0xb7224805,
- 0xe45cc55b, 0x96b8bedc, 0xacf1e50f, 0xb470d1f6, 0x031ecfcb, 0xc6a61722,
- 0x521f9597, 0xc90595e2, 0x028f28ae, 0x7ff4079d, 0x74e34aef, 0x1cd8d972,
- 0xdee37a06, 0xc01fbe2b, 0x15d41338, 0x47df8596, 0x49dcf303, 0x107f05fa,
- 0x3a2975e9, 0xc96f60b1, 0x89c7a07c, 0x8a5afe47, 0x456c86fd, 0x28385edc,
- 0xe2c97ad3, 0xaf48035b, 0xe9378a4f, 0x402fbf27, 0xa39339b9, 0x00a3afe3,
- 0xb2df04e3, 0xb39fa979, 0x20a60e6d, 0x47a4f71e, 0xf67d2431, 0xae0f56f0,
- 0x727dab77, 0xb31f18d4, 0xc2b13596, 0x4f9866a8, 0x7eb9bb6d, 0xc39a55b6,
- 0x8cfe69e3, 0x5f20c69b, 0x50efa379, 0xa547d15c, 0x9f6acfde, 0xfee8e34a,
- 0x4991db38, 0x217e0a7c, 0x86affbb5, 0x093f5523, 0x1fd8da38, 0x2e287700,
- 0xb93f8a17, 0x0f94ce5f, 0xb1bb8c54, 0x708ff63d, 0x7fc0773d, 0x6591d017,
- 0x7ef5d50a, 0xc472636b, 0xef9f1631, 0xdf078d30, 0xfb9f75f9, 0xf8c5d142,
- 0xf4276155, 0x9b6a8279, 0x0e443e8f, 0x6a2b95f2, 0xa699fbd6, 0x5e7b6d7a,
- 0xe00eb4d4, 0x59ee403f, 0x3ae0a485, 0xa8b82d58, 0x245ad147, 0xec8c6f80,
- 0xf126fce7, 0x4ece3576, 0xbe47ec35, 0x54e2fc69, 0xa56cb63f, 0x3be15af9,
- 0xabd87f5d, 0x5c7e245c, 0x3bbd9f25, 0xffc8bed9, 0x48bef996, 0xd3db8db5,
- 0xa0f119cc, 0x117ccabf, 0xe18bc60f, 0x0fc3eb4f, 0x8e304df9, 0xb3f7aea1,
- 0x4def6a22, 0xd9764eb6, 0x1d6c9db8, 0x7b8c45b7, 0xdcadfc29, 0xce367471,
- 0x95c78adb, 0xb4abefed, 0xffc0a31f, 0xd478134a, 0x0e463bf1, 0xdfc0c8b5,
- 0x22dfdb95, 0x3d94f27b, 0x176bfc32, 0xe1fd5bd1, 0xb7147cd7, 0x611de7d5,
- 0x9dce381d, 0xff67f17d, 0x7585bf2d, 0xed97ddf1, 0xf62cbe3c, 0x70387437,
- 0xf506d0d3, 0x6776a225, 0x9bc5155b, 0x3d75dddf, 0x594b6fd9, 0x644e83c8,
- 0x452d6b05, 0xb30cf03b, 0x9d3c41cd, 0x267aaf61, 0x43b4e818, 0x974e4956,
- 0x10ed98b4, 0xf54d5fb0, 0xf5cc9be5, 0x173f3672, 0x46f94cf5, 0x344a8b3b,
- 0x47fbd33f, 0x7fe12f65, 0x8f5bab39, 0x9da373eb, 0xe9ddb3ef, 0xe83e4a65,
- 0x1e179adb, 0xff38c52b, 0x7ebe648f, 0x1593f1ea, 0xab8edc59, 0x31566d8c,
- 0xb687ffbe, 0xca9c5f09, 0x7ae8fbf0, 0xcf221f5c, 0xfe6d814b, 0xa4fdf8fe,
- 0xd5e15bf0, 0x717eefd7, 0xcd47011c, 0xbc692976, 0x892cbf77, 0x63f39ff5,
- 0xbaa5e286, 0x5be7d76e, 0x22c9afea, 0x19332c1e, 0xebc67ee9, 0xe832d88c,
- 0xf38e207d, 0x3408e9db, 0x72c2fcc2, 0xf64c98e8, 0x1984bc44, 0x30e585da,
- 0x5e92ef3d, 0x93bb4729, 0xb412f129, 0x21ed6123, 0x3f05553e, 0x129e69c8,
- 0x31bb778c, 0x67718bbe, 0xd60b6797, 0xe62bbbd7, 0x16b51c62, 0xf7f401f5,
- 0x61f66780, 0xb2709fdc, 0xf81078d6, 0xef33e1d7, 0xe6fcb82f, 0x75ea3a7a,
- 0x00f877d4, 0x8c02f9f7, 0x23e954e2, 0x01dcedcd, 0x1f6cfd73, 0x5f7ce29e,
- 0xf71c589c, 0x0cb8b5c7, 0x4ac9b3e3, 0x54bf9f57, 0x871afe84, 0x5a64ec1f,
- 0x7978d6ff, 0x7e2295fb, 0xf4f8e6bf, 0x89175981, 0x939ed547, 0xceb0d458,
- 0x2abd2ad4, 0x39ed61f2, 0x6a7f9e85, 0xd587eabd, 0xf357a0d6, 0x929a70e5,
- 0xc228f5c3, 0x6138c127, 0xe3809f03, 0xf9ca35ea, 0x7c3f0b08, 0x99b2386a,
- 0x918fbf49, 0xe0c9f9c3, 0xfbfdd4f8, 0xe23ff5fa, 0x61ffb4bf, 0x909ffafd,
- 0x179affac, 0x8115d99e, 0x87f2a2f5, 0x3300f6df, 0xd69577b3, 0xbdd000dc,
- 0x07b35b7a, 0x1294f2e5, 0xdf5d20f1, 0xa273ca8d, 0x52a1f849, 0xa82ef9d1,
- 0x3fc4a549, 0x9fa747c4, 0xe80de6fe, 0xcdb47fc7, 0x7eff25ee, 0x00ee23bb,
- 0xb6d95ca6, 0x76c7cb82, 0x7ebc5bc7, 0x9fc8fbcf, 0x7d66edb5, 0xb7e4f951,
- 0x7eb4fd73, 0x1bff8445, 0xe561ff27, 0x8d9c7f13, 0xeb2d58f6, 0xfd67bd25,
- 0x973fc70e, 0x62c2f645, 0x7bffa335, 0x56b21f7d, 0xedb6a5e0, 0x3ee3ef9b,
- 0xe7db6d44, 0xe9a1724e, 0xfad1bf24, 0x07f0855d, 0xd9dc556e, 0xc49baf14,
- 0xe9bf2126, 0xee516178, 0x3c2fc80f, 0x9cf18256, 0xf65e27ae, 0x7c8da348,
- 0xd9dff5ca, 0xfdef92d8, 0xae5a9fd8, 0x1a3f41ba, 0xcedd6eed, 0x3f0bb7f3,
- 0xab2f0f66, 0xee0f71ed, 0xb66f541f, 0xf55cbed3, 0xffbf5b33, 0x8e57c608,
- 0x4057023b, 0xbccf55ff, 0x5035faf4, 0x9ece7aaf, 0x434f973d, 0xf4137293,
- 0xd6ff85a9, 0xa3d04f8e, 0xa92f47f2, 0xcf8d0fb8, 0xa0959ebf, 0xfb73d54b,
- 0x3fa63655, 0xf6c4663e, 0x125a9dab, 0x9adec4fa, 0xfc86fe8d, 0xe91579c2,
- 0x893eeeff, 0x824c2c0d, 0x912fcdcf, 0x22788cdd, 0xf57a0a7a, 0xbed2cfd1,
- 0x7a42e816, 0x6b2f42d1, 0xfe4269bb, 0xa78c5fb1, 0xfb3f7f03, 0xf977dc63,
- 0x7880238d, 0x2ef678a8, 0xa4e7ce0f, 0xfcf9c752, 0xcc5ce6b1, 0x47b0a8b3,
- 0xf254bd72, 0x7f8f15e7, 0xf96ff885, 0x52e4afd1, 0xf305833c, 0x443b646c,
- 0xcb9e70f2, 0xe699bd1e, 0xc4c2ce59, 0xc98f1587, 0xa1f0ff94, 0x973ce6c2,
- 0x16de4e44, 0x8b727272, 0x4e859283, 0xfb8242e2, 0xd1caaf10, 0x5bcf146d,
- 0xaf92f145, 0x6c47fbe8, 0x743fd535, 0x2bb57a72, 0x4b0c1fba, 0x9f7f9189,
- 0xe903a7b8, 0x70487a74, 0x6b81c620, 0xf8111299, 0xbf402e90, 0x0359d1f2,
- 0x5f989d39, 0x81df1529, 0xcf819ffe, 0x3d877db1, 0x7d312ae8, 0x26142ec7,
- 0xc6235fc6, 0xd0d3b807, 0x0b993dbe, 0xf99260f6, 0x3d25d865, 0x0cc1d46e,
- 0x7790667c, 0xdc4fff2e, 0x975de5cb, 0x39bce8ff, 0xd783fef8, 0x77e11cb8,
- 0x5c00bf68, 0x7ef481f1, 0xe9124dff, 0x278b0707, 0xec27f393, 0xefcdce42,
- 0xf002fcad, 0xf71eb82b, 0x938e0df1, 0xfb207445, 0x7c237cb6, 0x38abd46f,
- 0xbf7fa7ae, 0x172f1cba, 0x8af7e0fa, 0xfa100fc8, 0xf5ca3d80, 0x243f6a40,
- 0x7b75edc2, 0xa08ffbf4, 0x46bc82fc, 0xf6bf28fc, 0xbdffce10, 0xff5f071d,
- 0x7bcdc832, 0xcd6e5d31, 0xb72ad57a, 0x66af3b15, 0x3df6e4c9, 0xca92c02d,
- 0x2a4f3c2d, 0xf1275ab7, 0xaf5bdff3, 0xed5478ea, 0xebaabd66, 0xb4f854c9,
- 0x8acdc9ea, 0xd56af09f, 0x1af7f093, 0x8fcfed2b, 0xfcea1f3a, 0x9a83f957,
- 0xfa8fa8a1, 0xc3e754f8, 0xf9d53e3e, 0xd13c5fb0, 0xfbeb4784, 0x18dc605f,
- 0xfbb425f8, 0x81f3b3d7, 0xf87bd5ae, 0x777c2cbe, 0xaf80eb08, 0x5ad37720,
- 0x1b67e50f, 0x3d4b51eb, 0xb41f6966, 0xf69643d4, 0xcebd4b61, 0xe3ca3ed2,
- 0x5507ed69, 0x37139f9e, 0x63afb7b5, 0xb1c63711, 0xc714caf7, 0xd79801ee,
- 0x3b3df7c3, 0xc291a30a, 0x6f5b5e44, 0xf51eba8e, 0xd7b78f59, 0xaf62f683,
- 0x7aefc78b, 0x4c9ebd42, 0xd6f69d83, 0x71f4991e, 0x49cd9467, 0x05824fe6,
- 0x64ebf44d, 0xb8f3dea9, 0xddda0f7c, 0x592cde30, 0x718b582b, 0xf2995698,
- 0xdc369667, 0x8cfcc1e2, 0x37c53d9e, 0xcbe7842e, 0x9b7cc88e, 0xf2541230,
- 0x29dc7e0c, 0x9a687916, 0xf7c7fb84, 0xec97fd13, 0xd2dd7ee1, 0x73f393fb,
- 0x5caef8a5, 0xdea2a35b, 0x6dec7f04, 0xde83bee3, 0x96a3c54f, 0x17ae7be7,
- 0xfdfdcf7c, 0xefcc27ca, 0xb03e22c3, 0x71fbe74c, 0xcff71c6c, 0xae77e519,
- 0x96777a16, 0x85c6fa3c, 0xc39e8740, 0x39be4332, 0x3a2647bb, 0xf7c1dd9c,
- 0x3ece29ef, 0x97b5f905, 0xaf8e9df4, 0x118f942e, 0xd750f5a9, 0xfd2fbff3,
- 0xdea9341a, 0xef92dbf5, 0xebb5d942, 0xb117f0f8, 0x051bc2fe, 0xdbfd65bf,
- 0xa2e7d8cf, 0x7d9e8d7d, 0xec87da6e, 0x82f3fbd9, 0xb77d61af, 0xf6708023,
- 0x0973fbec, 0x3acf51f2, 0xb1ea0547, 0x1fdc219e, 0xe7fbdc6d, 0x3f5a4e92,
- 0x937e789b, 0x67c3fb9d, 0x4df5fcf7, 0x984b1b29, 0xfb07da15, 0xa87f69d2,
- 0x8a2ec7f6, 0xfdecf5ab, 0xced1a973, 0x59f3acff, 0x7b1bf629, 0x4ee16cdc,
- 0xef932f84, 0x38bed4d3, 0xe6036b65, 0x57edb463, 0x19fbc097, 0x825f393f,
- 0x2767b1fa, 0xedba7bb7, 0x7ee38f9d, 0x2fed77da, 0xbd03b3ae, 0x063851ba,
- 0x3f529a81, 0x92d11e9e, 0xc53ce5e1, 0x1f172f0b, 0xe0c7ff3b, 0xf57da243,
- 0xa8ee3dea, 0xff79c253, 0xa2dfcde5, 0x20e7d83e, 0xfbe7d4be, 0xec81ac5e,
- 0xfbcd4b91, 0xbcdd3fe8, 0xcce5f8a5, 0x7c1ff7bb, 0xf26377de, 0xe5fdd5db,
- 0xef9f3fa0, 0xcfea9bbd, 0xef0403b8, 0x57bbf265, 0xfd1c7955, 0x9ffe741f,
- 0x813bee98, 0xcf4b9eee, 0xf83fec7b, 0xfdd353bc, 0xee82edc8, 0xa947cc5e,
- 0x8279c9fd, 0xb9ea93ef, 0xce87ff1b, 0xefd7b75f, 0x315a05b3, 0xbd1d3b2f,
- 0xe1e73c01, 0xe182df9e, 0xce46fbc1, 0x28dda2f7, 0x2b4bfd8b, 0xfb95117c,
- 0xf3c4b27d, 0x1e10d9d6, 0x4fc263cf, 0xd710f342, 0x272b454f, 0xd6d154bb,
- 0x94ccdd93, 0xf0104740, 0x7755df72, 0x87d72806, 0xc6163f8d, 0x0169e0fa,
- 0xfc5b578a, 0x058926c5, 0x9557b025, 0x187f3eab, 0x48fb16fd, 0x4251dc5b,
- 0xde585be5, 0x7690e223, 0x67f26aaf, 0xbae6d1b4, 0x3bae6fcb, 0xc64e7f44,
- 0x58fa77e1, 0xf2d1e314, 0x98bc0795, 0x538f26cf, 0xbb2ea618, 0xfd046b58,
- 0xfccf8706, 0x73f422fd, 0xb45bf10d, 0xb060e3db, 0xad8efbfd, 0xf3383f14,
- 0x60375bf4, 0xca2f55bf, 0xe97809cc, 0x7166e1de, 0xaa251be4, 0xd9523fa2,
- 0xbe290726, 0x174bc4a2, 0x750bf618, 0x87eab17b, 0x72ab826e, 0x173a23a7,
- 0xf5dcafbe, 0xb75a1287, 0x3d92f5d7, 0x0a5a791b, 0x3be1a36c, 0xb03f704b,
- 0xbe7e4952, 0xe79511e4, 0x4eed751b, 0xbc7e885f, 0x6be79db4, 0xb16ec656,
- 0x28790c3b, 0xdebb541b, 0xf228f88e, 0x2cf94494, 0x4f319f08, 0xbb57b750,
- 0x7c38929e, 0xe628f6ed, 0x7f6e567d, 0x11e31bae, 0x011cc795, 0xb76b1b74,
- 0xeff14fbf, 0xc67c3f19, 0x977e49d3, 0xfb43f26c, 0x65db7ff9, 0xb6caeba2,
- 0xa15bb21a, 0x195df44e, 0x27d6fe13, 0x7eaa4ff4, 0x1e1777b8, 0xd1faa894,
- 0x778c1e93, 0xe6d8ee9c, 0xfb703f21, 0xfd31e3c5, 0xbdd8bdfc, 0xc2fbdfc2,
- 0x54e3e449, 0xfc69defe, 0x3f51d807, 0xf37e2d55, 0xc76401f6, 0xc9a59c02,
- 0xfe74c7f6, 0xc3e67aa9, 0xd95e31c7, 0xc7bdf3b5, 0xbfeaee11, 0xb471e9fd,
- 0x973ed943, 0x6a2df717, 0xc535fe9f, 0xdeeff477, 0xa25c7954, 0x2927a9fb,
- 0xfe0dd63e, 0xbdd6f636, 0xfa0164f7, 0xfdcfdd23, 0xe7fd1725, 0xd1677b35,
- 0xcf358ff9, 0x92c818cf, 0x225eb1c8, 0x232f46ff, 0xdba5673e, 0x6483b6c1,
- 0xba019f2f, 0xe7d2bfa3, 0x786ac7c7, 0xfc2fc47c, 0xe3c91df7, 0xf5fcfda1,
- 0x5e3705b6, 0x6db8f98b, 0x83aa00f6, 0xafedfa4b, 0x5ec73d01, 0x88771d06,
- 0x0bec4cf8, 0xcfdbf517, 0x5e803fe0, 0xfc742de7, 0xf7d96db0, 0x6d77c11e,
- 0xedfa5203, 0x9fc0cbf1, 0xa23d6f1e, 0x940e9d06, 0xa03f9db7, 0x6fd20978,
- 0xfbb84c2e, 0x300b0f99, 0xdeca7d5e, 0xb1e53b7b, 0xd17875ef, 0xfbdcad4f,
- 0xf753c906, 0x9e2947f3, 0xb3dc44c9, 0xf1fdf59b, 0xa1c894f8, 0xcdc27dab,
- 0x07417dfd, 0x3df8078c, 0xfdf85cf4, 0x78f5af9c, 0x4038aa40, 0xe4f3c1d0,
- 0xcd7038f4, 0x7e15bf13, 0xd26e8275, 0x5bd7a464, 0xeb5f8d17, 0x1e22f078,
- 0x5ce31926, 0x7d2ee3c9, 0xdd0b2e71, 0x5f56f8f4, 0x83ea0b1c, 0x95119e31,
- 0x371648de, 0xe3ccdeed, 0x7376dd63, 0x4e824dfe, 0xd535ee3c, 0xe8d38e61,
- 0x2f254df3, 0x6a5edcba, 0x4f149f1e, 0xbb08d0a3, 0xbabe3fba, 0xdfae4e3e,
- 0xde5c776f, 0xfdca757e, 0x7592a594, 0xc736e53f, 0xbc3f68d5, 0x57ca32a5,
- 0x0c79e5e8, 0xc8b9befa, 0x5a7aec17, 0xfac978a6, 0xefd241d8, 0xefa1fd56,
- 0xade159b7, 0x6caef013, 0xd747ebe7, 0x8354774e, 0xec0eba7e, 0xb95ebe26,
- 0xfd152de3, 0x7fdb43cf, 0x8b3b72a4, 0x1fae11cb, 0xba7cc351, 0xc25fdd9e,
- 0xdf3c7ae3, 0x37ce3ad9, 0xa93edc1c, 0x9c7c93dd, 0x9bef1dda, 0xc48aa9c6,
- 0x79ff9e54, 0x2b4ef1f1, 0xbfb05bc1, 0x3a761dd3, 0x263a73cf, 0xbfb649cf,
- 0x1761d8bb, 0x2f2b41f6, 0xbca51d61, 0xbcfca3ee, 0xd357c4c5, 0xcd7a0f28,
- 0xc5bf39d1, 0x406b8c73, 0x6c4ed1ac, 0xda7ce06b, 0xf9827ff6, 0xa3b6ef48,
- 0xfd71965f, 0x35f885da, 0xafa58bd8, 0x8370cdd5, 0x5dfd287e, 0xabb22268,
- 0x3a4cef55, 0x0fc13366, 0x75c40ce3, 0xc1fa09a1, 0x9fcc7dfc, 0xcf647842,
- 0x8f0839ec, 0x5d79b5ec, 0xed52f249, 0xcaf2885a, 0x5eed7ef5, 0xc338de73,
- 0x4fd086f3, 0x5e7a95f7, 0xf1032851, 0xcdc761f4, 0x328674bc, 0x775917bc,
- 0xd9bd094e, 0xf1601f55, 0x081cfc11, 0x7e456bd6, 0x839ec570, 0x560f51b3,
- 0x2fe624c4, 0xada473c4, 0x763f3724, 0xa573f264, 0x515db351, 0xd457e7b9,
- 0xb78db2be, 0x6a3162af, 0x8c45e78f, 0x6c4d5bf6, 0xe11ec582, 0xf223ddfc,
- 0x95cfaa42, 0xff21b8b2, 0x9f8267eb, 0x26bdeaba, 0xf08d5f3d, 0xd61afb41,
- 0xc4d4e341, 0xd1c69806, 0x9b9cd5db, 0x46afea6a, 0xab7e20e9, 0xf42ff739,
- 0xeabe4fbc, 0xd487847d, 0xe09be7fd, 0x853ff44e, 0xeb2427c5, 0xb73d1a7f,
- 0xe6fa87e6, 0xde6378f3, 0x882cbd02, 0xe88cfea2, 0xd3ca73e7, 0xbf808da2,
- 0x3ff85a23, 0xdcf81f50, 0x625f0b1b, 0x326cde78, 0x709f59e5, 0x0f047c88,
- 0x047cf0f3, 0x7583622d, 0xcb6d11f8, 0xf28c6986, 0x8c3b4e0d, 0x5e2c06f9,
- 0x6f447a82, 0x25bdefd7, 0x7e30611f, 0x1650aa02, 0xde631670, 0x8d07ac3f,
- 0xb05b3cf3, 0x9f9ba8fe, 0xbd602c93, 0x60ff31fb, 0x0a03f0ab, 0xdc58ce31,
- 0xa7e4bcff, 0x3d99273d, 0xd0d56ca3, 0x9cb36300, 0xa02a6723, 0x296fb32f,
- 0x0bdf2e7b, 0x3d9b1966, 0xb3d0f313, 0x971b2c9f, 0x4b58f507, 0xcbff7f27,
- 0x500571b2, 0xe2eae63f, 0xca24abef, 0xbe5b57d3, 0x7da2333b, 0x137d3d06,
- 0xa4d4a660, 0x409cb3a7, 0xdfa133cf, 0x1f99717d, 0x557a1ef3, 0xc216678e,
- 0x73264376, 0x7ed60dfc, 0x75fa1cf7, 0x0d9d6d43, 0xb7be5fa8, 0x7499cff7,
- 0x23f30fde, 0x6b1e9cf0, 0xe11d22f2, 0x170be4d1, 0xe6b3afc9, 0x74fce999,
- 0xec5c3b95, 0xdf363a04, 0x23ce9239, 0xde31523e, 0x26e37e89, 0x70f3b791,
- 0x3f21be5f, 0x93b57897, 0x44f9f7ef, 0x0fd9d75e, 0x2eb2330a, 0x7d6a1fa2,
- 0x0628278b, 0x5e947ab8, 0xf9efb7da, 0x31dbadf8, 0x99eb130f, 0xc499d649,
- 0x7be94bf7, 0xf3053e6b, 0x2d9f1366, 0x78867c15, 0xfaf21a73, 0x9511cb97,
- 0xc55bda07, 0x8bd337fa, 0xd52297f3, 0x9f5185f2, 0xb4c74f1c, 0xd3c45cf0,
- 0xcf299ce7, 0x7a45ce75, 0x6675cf5a, 0xe0374339, 0xe7e57977, 0xfaee500a,
- 0xad4a69ce, 0xeb3f4879, 0xf4a64fb9, 0x19f992da, 0xcfb9c45b, 0x710f7054,
- 0x71c36f85, 0xdfe27e8a, 0x7fe41879, 0x803552ec, 0xd763a4a9, 0xa4280c4e,
- 0x45de789f, 0x3c2be0ad, 0x1ee74eae, 0xcfb466ee, 0x8290e3db, 0xdcf7d7e8,
- 0x60bb25e5, 0xe4b9d2f0, 0x17a4f75f, 0xa93f30c6, 0xda7e6be7, 0x427b040f,
- 0xb21f3942, 0xf2ee2327, 0x647e9c90, 0xcc8fd391, 0xb71e6972, 0xbdbf82e7,
- 0x8af3fa93, 0xcfd0c0fe, 0xee9f9c4d, 0xdf7af991, 0x3827ef53, 0x7ec8b086,
- 0x772f1fb4, 0x853bafbc, 0x03e8281d, 0x1186fff8, 0x66c740ff, 0x3a43afac,
- 0xc74a4c8e, 0xb47464e6, 0xe49dc79e, 0xfd87df0c, 0x443f2c9c, 0xe7ad72e7,
- 0xc9129970, 0xe9593c43, 0x3eb4ab5b, 0xb9d25b8c, 0x3b27de7b, 0xd8dfa746,
- 0x4e88e3b5, 0x843e7a06, 0xf3dd8c70, 0xd6e10dbe, 0x291df8e9, 0xc14c1db9,
- 0x8ffbabc0, 0xd3b0bb97, 0xbed24e16, 0xf5296d64, 0x82d9f807, 0xf3f018e3,
- 0x9fbfd614, 0xe14f3f1a, 0x3f032fbc, 0x7e0e5ecf, 0x4aaf3f74, 0xee1571c8,
- 0xff9d015b, 0x5b9f9fe8, 0x96cee304, 0x15d3e235, 0xef8a64db, 0x79b9fb42,
- 0x5fb909b9, 0x3f6ea531, 0xf15c579e, 0xb4fc4498, 0x7fbf9c54, 0xb7bf9c4f,
- 0x2f9603e6, 0xbd9e908c, 0x94605e74, 0x76d546f4, 0x09c3f3f3, 0x3ca02afe,
- 0x89ef715f, 0x15805f7e, 0x213567ff, 0x365d4bd7, 0xfd02bde3, 0x66ceb7e4,
- 0x9bcf2bca, 0xf90fd7d1, 0xff9b3efd, 0xfdd38a0d, 0x6e30cecc, 0x27b25414,
- 0x131f11c6, 0x6fd899a5, 0xbd2f9099, 0xcd6ba1bf, 0xc4615e76, 0xb8b03e7c,
- 0xf03e7cc5, 0xf9f3568a, 0xcc9b11c0, 0x8caf03e7, 0x8e07cf9a, 0x54de3eda,
- 0xc6bb131f, 0xfb6c7ed4, 0x5c7d5374, 0xf6a6f3fc, 0x37cf0e13, 0xf8eeafd5,
- 0xa4fda9b2, 0xde9a7763, 0x34ace94f, 0x6a7a9fbd, 0x6d7ea9b5, 0xda9abfef,
- 0xfd7197c7, 0xe47ea075, 0xfa9e6354, 0xcdaa5581, 0x0d57cf8b, 0x8c4b79b7,
- 0xfe8373cf, 0x834b2c12, 0xd2a767e8, 0x579c33b3, 0xf7ae354e, 0xd26ecc65,
- 0xe69c333f, 0xe225c7ba, 0x2fc00510, 0x2e01fc40, 0xbc815cb3, 0x1e40bae5,
- 0xb5a6ebf2, 0x83c7870c, 0x40cb0c56, 0xcb390279, 0x9c9e5d75, 0x93bb63e5,
- 0xb1ebe32b, 0x003eec9e, 0x2ef910b5, 0xb29bf942, 0xe32ff738, 0xfe32173d,
- 0xc2a5443f, 0x5e4a1122, 0x7c860167, 0xf5f75d6f, 0x8f8adef5, 0x27c78b80,
- 0x04f0fe1d, 0xdc3f2cc5, 0x4c55f0df, 0x92f80c50, 0x76a675bd, 0x499cff0e,
- 0xef89f7c6, 0xdfcc9342, 0xa5d5342d, 0x7f2973e5, 0x765c1528, 0x4f5192df,
- 0xe7b37e80, 0x7f52a62d, 0x96d0bcde, 0x06f05f34, 0xc3f467d7, 0xc9ff3ca3,
- 0x80dddf60, 0xfd933974, 0xf79843ea, 0x2f5172b6, 0x0e79e3f9, 0xd4487eb3,
- 0x3a2f3df9, 0xb3d68f3c, 0xebdeb8d1, 0x4196dae7, 0x9a6dd621, 0xf3e3b2ef,
- 0x61af3173, 0xfd3f0a70, 0xc79f3101, 0x96a323eb, 0xa7306322, 0x41793ce9,
- 0xda3676bc, 0x9e454361, 0xe4b643f6, 0x2e5553f9, 0x440caebe, 0x82f68d45,
- 0xc13ed2a6, 0x79dff299, 0x55abf530, 0xff21570e, 0xa3b639de, 0x0ea39f94,
- 0x3f7e78f8, 0x77d75b87, 0x21e85a05, 0x60055fd4, 0xfb0bf9b6, 0x517033c3,
- 0xbc214e68, 0x05b2ca6f, 0x4af7aa34, 0xebf8de74, 0xbed03320, 0xc1326fe9,
- 0x0a6074d7, 0x5aa915e5, 0x27464598, 0x7e44c9e6, 0xf0efbe82, 0xe44df661,
- 0xd55d36bf, 0x9188de77, 0x3a85ab3f, 0x370fdfb0, 0xa6dc69da, 0x7de992e9,
- 0xeabad681, 0xde51c010, 0x4bf14e96, 0xe40dd365, 0x0e3ea97f, 0x12e3d34f,
- 0x3c112c1b, 0xe1eece3c, 0x7c3c00f8, 0x2670f105, 0x4d91f858, 0xafbc349f,
- 0xbce950c9, 0x711490e8, 0xfc3a6d8e, 0x3a2691c1, 0xc3308de7, 0xf6fc6f2d,
- 0x3f9843aa, 0x807a7cf2, 0x2e3ea4a4, 0x779e6ae8, 0x1bfcf673, 0x1aed04bf,
- 0x1e19935f, 0xc277f0f9, 0x91f34f1a, 0x7824d1a3, 0xf006e9d7, 0x957e436f,
- 0xf9a6cd37, 0x2f7a0a16, 0x3ae37a07, 0xe685b3e3, 0x6d73fd10, 0x9d6be70c,
- 0x07a10ec7, 0x8579719e, 0xf97396fc, 0xf51d2df3, 0x73d204c4, 0x73ffd86d,
- 0x73f694ae, 0xdd892b9b, 0x517ba975, 0x1c7617aa, 0xca0e52c2, 0xd427ee01,
- 0xcfda370d, 0xe27f1fa0, 0x72cdf832, 0xb04bd7c6, 0xe1d94bdf, 0x65a04ab5,
- 0xeda5e178, 0x90cfb434, 0x0cfb750f, 0xe71479e6, 0x9e8b0bf9, 0xa3f5e837,
- 0x4499e6c9, 0xed8ebfaf, 0x9e397e4e, 0xbd027ed4, 0x8e64764e, 0x65ff5c9a,
- 0xd47a71a4, 0xf946557a, 0x97f62985, 0xedc9696c, 0xdfeb54c6, 0xa290fca5,
- 0xc07ee681, 0x847f216e, 0xdfb4ab95, 0xcd83f675, 0x3cc70ef7, 0xf288ad21,
- 0x93f55383, 0x04c976bf, 0x22bfcf81, 0x9dfc741e, 0xf015e0b3, 0xeba4d7f9,
- 0xd3e03564, 0x4b27c266, 0xf47b0cbb, 0x32bb9fd3, 0x16ea179f, 0xe0758778,
- 0x16075a2d, 0xf18a59bc, 0x7f379597, 0xa7c0eb44, 0x39a1671e, 0x0fc7a08e,
- 0x21df9c60, 0xfc17ba9e, 0x3b7dc44d, 0xf8d95e29, 0x17ba08fc, 0xaeba66af,
- 0x749cea4f, 0x117072ee, 0x2ecce7d1, 0x3ce11047, 0x66e3c593, 0x3a4d7667,
- 0xf799f184, 0x19670fea, 0xd9e67ce9, 0xe876a5a3, 0xa3ceccef, 0xf7e90aa5,
- 0x9ddee9a8, 0x2abf0b9a, 0x3f5e7f45, 0x77c7d0df, 0xd3ebe4ce, 0x3f3f8275,
- 0x5e301e29, 0x0a51fb4f, 0xbbed187b, 0x9b54bc3e, 0x499c15cf, 0xf114b37f,
- 0x0eb97800, 0x43d3aee9, 0x332b878f, 0xdc60663a, 0xfc0bf7b6, 0x2e8da93e,
- 0xe352a71e, 0xcd769875, 0xe35b879c, 0xc475a658, 0x3b50ef28, 0xd2c711d6,
- 0xc41bd9d3, 0x7676a7ed, 0x5fb1e7e7, 0x7eef29ef, 0x06f567ac, 0xd0c7873e,
- 0x06afe765, 0xbb7c03bd, 0x71fade71, 0xf7e94fe8, 0xd98af96b, 0xe0b1c2c8,
- 0xe25e61bf, 0x2dcb8a58, 0xe607efc0, 0x71c41eda, 0xf37325a5, 0x6c5c8196,
- 0x8794a8f2, 0x1c08cca9, 0xf37c23f6, 0xecef8214, 0x17df9961, 0x85b9cf32,
- 0xfc67bf9f, 0xfd9b921e, 0xa7d4beb4, 0xc3e3e7e9, 0x2afeb885, 0x1a516cac,
- 0x85a707d4, 0xd732c0ef, 0x10fc31d6, 0xf63ae77c, 0x609c029b, 0xd0bfc1e9,
- 0xcabb3abd, 0x3f71fb42, 0xe4b777ba, 0xc7fac2df, 0x7e85ebfd, 0x48efcbd0,
- 0xef31c775, 0xebbefeac, 0xec7c6166, 0xba3aae3b, 0x82fe05f7, 0xe7f41f4e,
- 0x32cadf0a, 0x6a691c61, 0xa16b9cf3, 0xe3f7876e, 0xcd69fbf0, 0x577ed04d,
- 0xaf1f3866, 0x534b71c2, 0xc10f0f9a, 0xb5bca33a, 0xcd29b4fa, 0xfe663011,
- 0xe3cbcd35, 0x10b85aed, 0xf757d4e9, 0xa86ddd42, 0x85752d3b, 0xd579f5d7,
- 0xe50bfc1c, 0xc3dcae95, 0xd9ca2def, 0x1bdf8f33, 0xee8f3ed7, 0x134e6b8d,
- 0x9a63447a, 0x58563cf1, 0xf88bdf0e, 0x195e92ea, 0x8f48e5ce, 0x2f78a67b,
- 0x59c39ee2, 0x06e3c51d, 0x62eec1e1, 0xbc78cbb4, 0x52f580b3, 0x8aebc7a9,
- 0x61ca8058, 0x48e5442c, 0x55e54ad6, 0x68e5462c, 0x096541d6, 0xc032a5eb,
- 0xe39632bc, 0x6cca8059, 0x59d1dd5b, 0x667f4fa8, 0x7c3a7d27, 0x8303aafb,
- 0x44de9118, 0xc78d66b7, 0x656bd6e9, 0xdcbc1ad9, 0x3f50f828, 0x348d5557,
- 0xdb62be03, 0xe87ec8f3, 0xdef63212, 0xf7045b26, 0xf9a3d963, 0x9c5abcf4,
- 0x7e3eae47, 0xf7cdec80, 0x60f3c982, 0xbb8bc05f, 0x963ed33e, 0x3ed67f59,
- 0x41be11aa, 0x39405f7e, 0x41708959, 0xa0ece6dd, 0x75f69773, 0x3ee907b1,
- 0xb4ec67b8, 0x18555abf, 0xbd43b32a, 0xa061776a, 0x7a8720c1, 0x6655703e,
- 0x96bc772c, 0xf5888f38, 0xdf825a71, 0x286fb657, 0x77fb7dc0, 0xf5a71ff7,
- 0x85e987fe, 0xb69a9f34, 0x4dd86aa3, 0xca2a7efb, 0x7d39bbcd, 0x97d93af6,
- 0x0640aecd, 0xfde9779e, 0x4b6fbf39, 0x94f7dfc7, 0xdf71975e, 0x283d70e4,
- 0x5ee9b042, 0xf951f7a9, 0x953f7a8b, 0xb2f7ab3f, 0x4700f820, 0x04da9dec,
- 0x30ce4f9c, 0x7bfbca2f, 0x432bd8de, 0x7cbe6227, 0xe601bf91, 0xcefd98d7,
- 0xded013fd, 0x7401c80c, 0x75eeec0b, 0xf3b42513, 0xcf29f37c, 0xbc6d1ee5,
- 0x4f008ff3, 0xe67012a3, 0x6b2fb8c0, 0xa02bb53b, 0x24fcfebc, 0xe5ffce27,
- 0x0fcd36ec, 0xddc61bf5, 0x247dc5ec, 0x02e36fe8, 0xfa2ecfea, 0xf6c4ef1b,
- 0x5a3f62f7, 0xa2fd9fa2, 0x677bbd7e, 0x543fbe36, 0xebee08cf, 0xb1b2da73,
- 0xbd1f7fbf, 0x13f195ec, 0xba477ee9, 0x17caca2f, 0x66cb9fd7, 0xe6cbb041,
- 0x41602b9e, 0xd393c7a0, 0xf942aeeb, 0xd1bfd357, 0xa0fd04ec, 0xa255d614,
- 0xb7a6f0be, 0x1f413b34, 0x9d01b06c, 0xa59f54bc, 0xcc70095d, 0xb181fae4,
- 0xa432e696, 0xc62bb03b, 0xae8fe1e3, 0xfa82399b, 0x7efe1ae3, 0xd79160e6,
- 0xf7e3ed00, 0xed0b31bd, 0x918a6ab2, 0x66e6b630, 0xa479f746, 0xce2a37b2,
- 0xc1a8b3a5, 0xba61fbae, 0x42a7e49f, 0x4c3ed089, 0xbd0f39c5, 0x5cfefcbf,
- 0xfd8873a6, 0xfde8d3fb, 0x7e74abe1, 0x679c520a, 0xdf2273cd, 0x881c15c3,
- 0xd763beed, 0xb8f60fe7, 0x57d5f113, 0xcc3e288f, 0xffe7d043, 0x49ffcd28,
- 0xef1ef135, 0xf7d81cf5, 0x7fd1059e, 0xea26923e, 0xb7922791, 0x2fb4b34f,
- 0x34cfebd2, 0x1fd69ccf, 0x12b8ef9e, 0x57b42775, 0xeafa3bce, 0x9b06df08,
- 0x7d2cbfa5, 0xfc69e7fc, 0xb45942aa, 0x5052f7df, 0x723bd031, 0xabef19a8,
- 0x78ef454d, 0x9b9b2fda, 0xae23fbe0, 0x5fad1950, 0xbf5a3337, 0x0602ee50,
- 0xe34f183d, 0xb9c555fe, 0x247a2651, 0x7a6250e8, 0xd2e4127e, 0x7cbb4fb8,
- 0xfe745dc7, 0xe7e69e24, 0x3f08b0fd, 0xb168f557, 0xfff67f69, 0xe169f1c3,
- 0xc7014b28, 0x1c33bfcc, 0x3fe49a57, 0xd368c701, 0x387efff3, 0x6380a466,
- 0x1c153ff6, 0x2f457b56, 0x2bda2fff, 0xcabda357, 0x9d6c41e3, 0xf7fdce8d,
- 0xe52a2a64, 0xc99369ef, 0xe195204e, 0xdf68eea7, 0xcd779f2f, 0x8b1c7bfc,
- 0x615f9db1, 0xd478ca2d, 0x11671157, 0x857f87ee, 0x0fcf03f7, 0x8683a02b,
- 0x1f693a64, 0x5434bfdb, 0xfe05fb85, 0x5435e585, 0x546eeb7a, 0x587a5f70,
- 0xefb438ef, 0x4fd96b36, 0xde933337, 0x2fbad08b, 0xb6bb22ad, 0x9b279be3,
- 0x6078df71, 0x68c3dd5a, 0x93914b07, 0x24a787cd, 0xd6f5cf7b, 0xd14fd32f,
- 0xce9d14ba, 0x293f42ae, 0x0ec68aea, 0xb59a3d20, 0xf0a3d200, 0x2296d19b,
- 0xdaf72ba8, 0xaf000d02, 0xbedd1992, 0x1e57e005, 0x4d764e18, 0xb61ff514,
- 0x6e89407f, 0xfa9dfcc1, 0x1bb7c500, 0xa5b47d85, 0xf317ae69, 0x3099ed98,
- 0x7ae5204b, 0xd097dd7b, 0x7534d75e, 0xae0a73bd, 0x01968107, 0x01f75e5e,
- 0xb1164f5c, 0x78a66722, 0xb46feb0f, 0x1af20d81, 0x6fe97eea, 0xbab79f32,
- 0xd70d383e, 0x8c95d5f9, 0xf7087f7f, 0xd2cc9e89, 0xfbdfc2f1, 0x4f5c750d,
- 0x7d448694, 0xeb7bcc26, 0xf7df5c63, 0xd1ebaba6, 0x44f987de, 0xc31b8ec8,
- 0x630e93e7, 0xf4fe007b, 0xbeb44571, 0xf17d6146, 0x0a71fbe0, 0xf7d2f79d,
- 0x6c639c83, 0xed841fb4, 0xc2ea7ee9, 0x742fda22, 0x388163ce, 0x69e703e6,
- 0x09517f7c, 0x3b3cc4ce, 0x04bf1f77, 0x8aa6ce29, 0xa26d12fd, 0xad205f39,
- 0x99b45be9, 0xfcda369e, 0x5ccc39dc, 0x9dc0b077, 0x60ec8f74, 0x2681be4b,
- 0xb00687f6, 0x1457e841, 0x6c3622db, 0xca85da07, 0x76df7851, 0xec811e31,
- 0x0c58faa4, 0x31e31691, 0x0c1d3f2b, 0x3282c09b, 0x6486a38f, 0x698e3bf4,
- 0x07947ce1, 0x66e2269f, 0x8dbf7883, 0x36ff61a1, 0x8ff14fcb, 0xf5efb47c,
- 0xb379c6fa, 0x4a91fe29, 0x889a22be, 0xec36dee7, 0xce9af7a2, 0x19100738,
- 0xc68e6ff4, 0x6f6b81f3, 0xd779f7e2, 0x947ee1ee, 0xe8b27efe, 0x9c4536b7,
- 0x327ae413, 0xd63df9c2, 0x485edb39, 0x0e7cacf7, 0x75f356e9, 0x6b4fc31b,
- 0xdfb9c7e2, 0x53b7b166, 0x158da1e5, 0x5f9f4dfe, 0xf218fc23, 0xc2ce902d,
- 0xd2ea597f, 0x4fbe6ee9, 0xa247bf42, 0x4f4dc847, 0xa8c44ab9, 0xea098345,
- 0xe9853739, 0x3172821e, 0x654df29f, 0x2c1fe8b9, 0x8225ffdd, 0x79c6d973,
- 0x5e4bde2a, 0xe13171be, 0x52ebc745, 0xa7f07f8b, 0x8d1709d6, 0xb4f6e9a7,
- 0xfee81fee, 0x484fd580, 0x47e7fdf5, 0xcc3a27ee, 0x3ed195f6, 0x3c1affef,
- 0xe07586cf, 0x67de20b6, 0x473ffba5, 0xf98eecec, 0x73655cf8, 0x2ec3f9f0,
- 0x54560f7e, 0xd87583dc, 0xdf859c5f, 0x7f3e29cd, 0x3b2f9625, 0xedea1a63,
- 0x7a3e3f97, 0x4a0ff903, 0x8d3cc34c, 0xfff70a33, 0xe7633af4, 0x0bf38a64,
- 0x7eef5fbc, 0xb867ee95, 0x74f7f0be, 0xfdc6bd3e, 0x3f639d2a, 0x3ca766d3,
- 0xb15debbb, 0x1dfde36c, 0xcdee17d7, 0x747e18be, 0x8088e1ff, 0x7bd170f7,
- 0x571a6105, 0xb70473e4, 0x53d2174a, 0xe7cd6f7f, 0x3e98ecd8, 0xa669e513,
- 0x2ff9e926, 0xcd97c88d, 0xfc9387f3, 0xe89bcf64, 0xf39bfde4, 0xc791b24d,
- 0x47cfeeae, 0xef59ff3a, 0xf1235925, 0xe0a9ef73, 0x19b405aa, 0x3dc4d1d7,
- 0xef3d2a25, 0x0e86f116, 0x54f6fb1f, 0xac799790, 0x75fb4ece, 0xfd177ee2,
- 0x4179975e, 0x2242fdcb, 0xd6242aff, 0x5e4437c3, 0xa7e63cd5, 0x376817ef,
- 0x75bf51d9, 0x6e60fb88, 0xf1bb6162, 0x425ea67c, 0xb6bd26bf, 0x7eb98e60,
- 0xb75cc873, 0xe7a8a3de, 0xdeb4fccd, 0x89ef153f, 0x999dfbd3, 0xd3ec3f42,
- 0xb03c5d3e, 0x67507e2f, 0x71e81f8e, 0x43cc1abf, 0x1e18fda6, 0xe4e59bf7,
- 0xbb8f4fe3, 0x56a37f68, 0x16e33753, 0xc5b3ea0c, 0xc6967cf0, 0x8bc60df5,
- 0x59a29ef0, 0x6f1f7e8a, 0x80e7bf54, 0xf909cbbe, 0x0ddc6336, 0x5ee930f3,
- 0xdf1e70ab, 0xa0721157, 0x0ece19c7, 0x5e6467f3, 0x4db5bf84, 0xba9ee9b2,
- 0x13b895fb, 0x00fee0f9, 0xf04ac3cf, 0x6f14d471, 0x49a936d5, 0xebebb7ef,
- 0x9e0af407, 0x3ee0724f, 0x01f7d02f, 0xc635e825, 0x887b3423, 0xf4f776ea,
- 0xf2f23f0e, 0xe3661b03, 0x988d1055, 0xca760c1f, 0x6957da3b, 0x03db767d,
- 0x621ef187, 0xc7e6dbb7, 0xb341b8f5, 0xa357bed1, 0xefeb49cf, 0x8bdaa97a,
- 0xebf7a4fc, 0xae0854ee, 0x06515ab3, 0xabff08bb, 0xda334fe0, 0x87df31af,
- 0x9e37dff5, 0xddfaed46, 0x0a7075bf, 0x131d59c5, 0x17bc016d, 0xb1ac1d5c,
- 0xcfc9243f, 0x936f1bec, 0x549fb492, 0x77494ff8, 0xf507a77b, 0x7c96b743,
- 0x2dc8ba3f, 0x3fc2fb89, 0xb22c3ca5, 0x5f33c3c4, 0xefc71e1f, 0x8a1bcea5,
- 0x8a3e490b, 0x2b6f20dc, 0xccf59dc7, 0xe47c93f0, 0x2e1c7cf2, 0xabda8db7,
- 0x6c379e4e, 0x152da7be, 0x4978ea3f, 0xc8e50785, 0x37e78c5d, 0x7f719986,
- 0x43c52dce, 0x4e32d794, 0xb8afba49, 0x51a1e056, 0xcabf1009, 0xb89c86d7,
- 0x4f64340e, 0x7ffee277, 0x28cfe2b3, 0x88f0fb44, 0xd66e30cc, 0x8dcb35e4,
- 0xfb88b65e, 0x6dbae745, 0x7559ef49, 0xeeff92da, 0xbe6e5dce, 0x9fecb44e,
- 0x52dee742, 0xd46809f1, 0xa5a5d910, 0xf3ef178a, 0x5e1ced96, 0x04fc8a57,
- 0xfc54dfbd, 0x177eef71, 0x61993dff, 0x659f3a4e, 0x9c49af1d, 0x78026bc3,
- 0x1a6dced0, 0x6c7841dc, 0xd178a89a, 0xd3f9768e, 0x5ed0d398, 0xef489cc9,
- 0x78d96acf, 0xa5359026, 0x4f1d3be0, 0x9f6db9d7, 0x16c2ff8d, 0x0df9cbfe,
- 0xfc0dcbc5, 0xff193ab7, 0x983c875d, 0xde37e1c3, 0xf264a9ab, 0xbc2b3ffd,
- 0xde3e7e7a, 0x9fcc6e87, 0x845f052a, 0x1c8e8dc7, 0xec0c3e9a, 0x303abedd,
- 0x86d78c38, 0x73fb8e7a, 0xd133a771, 0x647dd1be, 0x75429376, 0xdf07df3a,
- 0x6cf7f105, 0x39fdc4da, 0xc1f3a835, 0x45beaa8f, 0x9f585e63, 0xbb2ccaef,
- 0xda51e717, 0xab9f8071, 0xf9a1cb69, 0xadef8b57, 0x9c3dc6f0, 0x2f1ee39f,
- 0x82c71995, 0x77dfc03f, 0xf348eb68, 0x2db71c63, 0xd639db8b, 0xf5bbceef,
- 0xb156873c, 0xfb49d1df, 0xf8333912, 0x3bbbd47a, 0xfea3fc9d, 0xf7e069f8,
- 0x8dec5869, 0x94367bbe, 0xd51dd938, 0xc7d0eec2, 0x82c45d2f, 0x2f4bbbf8,
- 0x2716b1a5, 0x843b87d8, 0x2df6321c, 0x780a5fb1, 0x7c6fb804, 0x3fed1471,
- 0x04bdfde9, 0xcfb612cb, 0x912cedcd, 0x3fc0cfe4, 0x6fba6631, 0x39d9c6ad,
- 0xbe47f51c, 0x46edde1c, 0x6758e33f, 0x5edbd62e, 0xe0f64d3d, 0x73f0f0a5,
- 0x51c2bf81, 0x571e7dba, 0x35d6718d, 0xf45d95cf, 0xc6355d7c, 0x50fe0c43,
- 0xe9b36f02, 0xa17ebf79, 0x1fe8bf3f, 0x8d392be3, 0xa09ae9c9, 0x4c8b3e4f,
- 0x0a7d18b8, 0x25d23de8, 0x1fd39a3a, 0xde60f9f7, 0x607fd764, 0x09ef27d1,
- 0x9f4ffd7a, 0xae26366f, 0x40e53f01, 0xf188e789, 0x9fbc5bde, 0x6fc794f7,
- 0x15b27f5a, 0xcb3553f6, 0x2c6987c0, 0x8dfa84e2, 0xd167ce8e, 0xfaebd3fe,
- 0xc7c11bfb, 0x39fd8c9a, 0xf2e91cb9, 0xb928bd5b, 0xedcb7edc, 0x3c0efc21,
- 0xbee0f716, 0xfc628bc7, 0xe81fd8b6, 0x76b6b3be, 0x3d4fe199, 0x96145c0c,
- 0x4e825ac3, 0xebe1fbfd, 0x60ff2e8f, 0x0b728e4e, 0x4a3947f9, 0x6bfdcb5f,
- 0xdfe8cf5d, 0xcfb47915, 0xee8f1f66, 0xc8ac4e77, 0x75724393, 0x05f44308,
- 0x7bbdf96b, 0xa2ff0b6f, 0xd39fdc5a, 0x18c7dfa5, 0xde33691c, 0x5a76f5bb,
- 0x87fd1441, 0xe5f787b7, 0xed1ae609, 0xf0576aaf, 0x1bbef0df, 0x7ca65476,
- 0xc1bc0fd5, 0x9a2fee0c, 0x712ea7fd, 0x3fee8eaf, 0xffdf8b35, 0x7f398362,
- 0x1dd24b37, 0x91ffb0f3, 0x72af749d, 0xa75f2e6e, 0xcc7f73f5, 0xf64259d7,
- 0x54abe0b7, 0x0f39f77c, 0x83d40f97, 0xad7ca491, 0x0dbf9e9a, 0x70c460eb,
- 0x53cee84e, 0xcf1ce8c3, 0x78a01612, 0x749692e6, 0xbde03116, 0xf9e4f1ed,
- 0xbe848b35, 0x4ef7136f, 0x5e7cd1b3, 0xf3e7be09, 0x1c975b68, 0xbe0c9eee,
- 0xfb89b70e, 0x6094dbc5, 0xd529e23a, 0x078fa13a, 0x3ca74b04, 0x6f07f387,
- 0xe6fd71a0, 0xfa257f71, 0xb26ff17d, 0xc0037df8, 0xd827d0a3, 0x9b1e1bfe,
- 0xe2bebe49, 0xb3faacf9, 0x24feb4cc, 0x9e933ef0, 0x927d767f, 0x927d0979,
- 0xf251ef4d, 0x3a78ced0, 0x7b75efc6, 0xce6db0fa, 0xdb742496, 0xaaf4e424,
- 0x3fee851c, 0x76e7151b, 0xb976aa40, 0x639ee259, 0x7c2b4781, 0xf9c9c5d9,
- 0xfe0ca5e3, 0x7e74f57d, 0x1bde334f, 0xb285f38f, 0x75fd0020, 0xf422d74d,
- 0x6fe25ffc, 0x7ab49c62, 0xbf8fc3a7, 0xd3b5d7cf, 0xa27a8155, 0x62a3a76b,
- 0x7e9fd68b, 0x3b663cbb, 0x4ccf99f7, 0xf58c7fbf, 0x705174a0, 0x5fd1cfc2,
- 0x3ee99768, 0x927f6b49, 0xecf34dc7, 0xec29e7d3, 0xb9b9afb0, 0xe74ecd3e,
- 0xf117b174, 0x572ad475, 0x1d3c8547, 0x2d90f215, 0x75876bee, 0x92eb89c9,
- 0x0217eede, 0x2cc393df, 0xe7c17de9, 0xb12e02dd, 0x76bc3c2e, 0x04c3fb06,
- 0x08ce7dfc, 0x7eda19c5, 0x7ec02f13, 0xdc78cabb, 0x16fdfac0, 0x998c67c1,
- 0x3349eaed, 0xb9e612fd, 0xc5e498b0, 0xfdbd7c7d, 0xb7bf18a4, 0xd3b9fff8,
- 0xdbc5ecfb, 0x807bbfc8, 0xf49a2eff, 0x81eb8a53, 0x61b4170d, 0xc18fd15e,
- 0x5ff8338e, 0x1de8b2bf, 0x0baf3c2b, 0xefc4da78, 0xeb8d3287, 0xf55d2b61,
- 0x779f4c75, 0x1cb300f6, 0xd7ff82c8, 0x9647328a, 0xb9743c68, 0x7d7c591c,
- 0x5cc4f9e6, 0x49d2e24f, 0x1e5859cf, 0xbcaf7003, 0x90e6fc43, 0x95dcef88,
- 0x31ef3e19, 0xe9da3df0, 0xbb097eb4, 0x6fdc4dbc, 0xa889dba9, 0x466bc74f,
- 0x0e0223b8, 0x4ad7d71b, 0xf30d7d72, 0xe2a7bf10, 0xf6127ea6, 0x262bb706,
- 0x166dfc0a, 0xb25f51e7, 0x3fb226b1, 0x39749e04, 0x9661951d, 0x7f8ca2d3,
- 0xacdd390e, 0xa4727cf2, 0x787d325f, 0x9427ed1e, 0x71c16387, 0x4572c798,
- 0x5fa00b48, 0xff31da5a, 0x0cf1e600, 0x943f83df, 0xe1e39093, 0xbfb19f82,
- 0x2dfc0645, 0xf09b70c8, 0x7f8cf9f7, 0xf877bb0e, 0xdf37d631, 0x7d7a0cdb,
- 0xe5c68655, 0x942ffc00, 0x9a7f8a83, 0xe00e86f9, 0xa06aae39, 0x9d0caa3b,
- 0x8b62da3f, 0x3ed0b9d7, 0x6802c63e, 0x16c7775f, 0x7f00c6db, 0xf6e26f74,
- 0xdf9e9f63, 0x7a05f1c8, 0xf97a8639, 0xf4c1638a, 0x275f50d1, 0x458ae3f8,
- 0x14e7df8c, 0xcfd14773, 0xce44f5d6, 0x7033bd4d, 0x7a6577df, 0xf0cb835d,
- 0x3b7dafbc, 0xe84c2fb4, 0x37d46a9b, 0x7df6d4fe, 0x8d3a466b, 0xe209eb87,
- 0x733a5665, 0x979e00ba, 0xee32230a, 0x4574be6b, 0xe7bc78e1, 0x785a50fd,
- 0x7ef86af4, 0x0e3e1cd2, 0xaf44776b, 0xd2ff1248, 0x88ae75f5, 0x7c8ae54f,
- 0x5e34dcef, 0x45f42c7e, 0xc1f39783, 0x9ebcbdaf, 0xcf1e49eb, 0x17ef11ea,
- 0xdcef5cc8, 0x2edc9657, 0xc67c6589, 0xb24063f8, 0x1963e3c6, 0x6f9ee239,
- 0xeb5f425b, 0x7c4273fc, 0x2edf8fa7, 0x9cfcb5e6, 0xe59fe264, 0xcdf11d4a,
- 0x3d0a73f2, 0x1522e5d7, 0x79fbe9ff, 0x78e11d9b, 0xbe7bd406, 0xc60961fe,
- 0xe9ef0a0d, 0xf848fbe2, 0x5253407b, 0x1ebe87cb, 0x3d06f4e8, 0x0df186df,
- 0x2713f3d0, 0x18f43ad3, 0x9c85975f, 0x1ff4ec1a, 0xb659efe0, 0xd4555c75,
- 0xdf6ba060, 0xfee0197a, 0xd95d758c, 0x57c4c980, 0x89d79ea7, 0xa3ef2ccf,
- 0x25e1d852, 0xbc3b577f, 0xc93c63b4, 0x578112ed, 0xc7a6de3d, 0x507b18b5,
- 0x13f731f8, 0xe4cd277e, 0xdff80df2, 0x9a3ff021, 0x7dbbffe3, 0xec95bff8,
- 0x2f2e5684, 0xa52b9db9, 0xfa2f9262, 0xa4ddff4e, 0x52afd3c2, 0x2f78e77e,
- 0x13ffe7f7, 0xc9555084, 0x00008000, 0x00088b1f, 0x00000000, 0x7dd5ff00,
- 0xd5d47c79, 0xcefdf8b5, 0x3324b677, 0x5f64ccc9, 0x25849308, 0x2126126a,
- 0x26504109, 0xc5116109, 0xfb094049, 0x515983b0, 0x2fb5696c, 0x4a444103,
- 0x505d8bdf, 0xd101da94, 0x101ac55a, 0x83b06034, 0x6795622c, 0x05b054a4,
- 0x2108ee3b, 0xf16b43c9, 0x3dde5a57, 0x999bdee7, 0x006677ef, 0x7e7ebe7d,
- 0xdeb8ff0f, 0xdef7cbb9, 0xfb3dce73, 0x3ab3c9bd, 0x21094b25, 0x0b62a21b,
- 0x99941c48, 0xc84b125e, 0xbd3e0988, 0xe90844dd, 0x95242448, 0xa423aefe,
- 0x475aea0b, 0x2423c932, 0xbd389ead, 0xbed19eb4, 0xfad2d25f, 0x8637f865,
- 0xc94ad310, 0xfe9e30b9, 0xd3b694be, 0x3a166ddf, 0x9ed03130, 0x1609ebcc,
- 0xd025213b, 0x820d27cf, 0x936f36f9, 0xb4be74b4, 0x62908976, 0x2f13365a,
- 0x4b8c0ac9, 0x99efb073, 0x01695e1c, 0xbb48dfed, 0xac849191, 0x59e754d3,
- 0x14996812, 0xbfa568e3, 0x07bab06d, 0x4fea7ec0, 0xda667cf9, 0x2ea9c465,
- 0x7b8e9bad, 0xb4cceac2, 0x63f60624, 0x24692d97, 0x53989087, 0x366d9d6c,
- 0xfb05d732, 0x174cfe23, 0xc63f240c, 0x15b211f5, 0x93289bd7, 0xab46c423,
- 0x2f7e87d0, 0xd6ee7569, 0x7d6052f5, 0x6ee23649, 0x49496da7, 0x84d3bdc4,
- 0x2291d7fd, 0x7048d7da, 0x87ab493f, 0x059f5d6c, 0xde7179f3, 0x36d71caa,
- 0xf92abdf8, 0xfa56a2ba, 0x9f06ce7b, 0xb71d3e76, 0x0266b377, 0x2bcc53ec,
- 0x0916d1ca, 0x8c7dd1c7, 0x7d89fd80, 0x9289fba8, 0x5bae0f10, 0xb345d3f4,
- 0x5bf685fd, 0x4cc6f385, 0x6d0df060, 0x2f6c77ff, 0x0cc265ff, 0x1afd6f58,
- 0x0148313d, 0x75613ff8, 0x4d7002dd, 0x0122df6b, 0xa68c3e6c, 0xf02c3474,
- 0x29a30fdd, 0x76b0153d, 0x87f3853b, 0x79474a7a, 0xb48a3a01, 0xb295fafe,
- 0xa0f0e173, 0xe23d1afa, 0x2c9e8b69, 0x5e0bcf6d, 0xdf5c6adf, 0xcb068b22,
- 0x2cd756a3, 0xc7634f80, 0xfbc07ac3, 0xe81f6db2, 0xcef857dd, 0xee91c2b5,
- 0xe296957f, 0xb25daebd, 0x4ae92818, 0xe81392ed, 0xe8d6bea0, 0x6fd47805,
- 0xd64b7467, 0xa183bde8, 0xa7c3bede, 0xf7e9eda1, 0xfd321d3b, 0x0efb6eb9,
- 0x7c105169, 0x12bdebd3, 0x59a86bac, 0x1e9f2b9c, 0xfe8a95cf, 0x4578510f,
- 0x1c3bba51, 0x5a463c45, 0x3c9b9776, 0xb76f8512, 0xfd0f5dce, 0x1c6353ba,
- 0xf5efda1e, 0x488fe31d, 0x779adcf4, 0xae507c1a, 0x314d6cd3, 0xd775f6d2,
- 0x41ad1deb, 0xbad36774, 0x6b38c176, 0x8ab1d982, 0x206eca7e, 0x9c131645,
- 0x47fe2577, 0xc5cecfdc, 0xa32c4b6e, 0xe08a4223, 0x316e3c5c, 0x82893d63,
- 0xf7d28cbb, 0xd75b1d61, 0xe1e8c24e, 0x836b9c52, 0x23e3bf05, 0x3ade3a0e,
- 0x3a979d81, 0x7e891fba, 0x2ef36eaf, 0x623927dc, 0x6fa7b843, 0x75bbf097,
- 0xb9e0b7db, 0x73bb3ace, 0x2ffa1ebf, 0x2451a525, 0x1b9cce98, 0xd5efcf83,
- 0x426235f0, 0xade81ebb, 0xf2a1f38e, 0x3e936e5f, 0xafdfda0a, 0xa3c2322d,
- 0xfdb6f36e, 0x647bf469, 0xb60cb129, 0x13fdbf63, 0x06b5f7d9, 0x607fc412,
- 0x9d6c799d, 0x8ff8828b, 0x3e187fd8, 0xaf585bf4, 0x41d754e9, 0x487c87c6,
- 0x6afd628f, 0x7e7076bc, 0x3c4f4e38, 0x93debbf8, 0x1df3a76b, 0xf9c68ece,
- 0x73805f04, 0xa5f9c35c, 0x6213d686, 0x5a0eb9e8, 0x9e6f588f, 0x82d3a2b5,
- 0x3842e870, 0xe2d66c34, 0xaef4abfa, 0xce83cb41, 0xb9f9efc3, 0xfbda6d79,
- 0xfdfd3f7a, 0x83bf2fe7, 0x936869f8, 0x48cfc09c, 0x3bfa3bdb, 0xbfac01f2,
- 0x21124991, 0xb7fb0893, 0x7a3bf771, 0xd27dfd3b, 0x86bf862e, 0x0bb43b5d,
- 0xccfa014c, 0x1cdafb3a, 0x7686b3a0, 0x00928903, 0x582eee7f, 0x054e9a8f,
- 0x8ddf043c, 0x0998cf84, 0x0f128f8c, 0xcf485f3d, 0x731aacee, 0x8a5f6f80,
- 0x353a30d3, 0x2dbbdfb1, 0x1fa01eac, 0x974007f7, 0xd78ed155, 0x15545ce0,
- 0x02568e49, 0xfb863ceb, 0x7064a848, 0x754f5e0c, 0x997e647e, 0x85e5cf18,
- 0x63599fd6, 0x7eaf9c0e, 0xf7c7cfbe, 0xfc995e02, 0x49dfb1f0, 0xb03f2bb6,
- 0xd2de356e, 0x0ff612ad, 0x01174f43, 0x26b96a7e, 0xe3e82fd6, 0x0ab59bd7,
- 0xeab061f9, 0x55833e71, 0x08dbeb8b, 0x7e72a1f8, 0xcb9d8ea3, 0x5e8cab8d,
- 0xc7d31fe4, 0x9f28911d, 0xfbd0cf36, 0x99a43ca0, 0x87ed0f5f, 0xd7f7d8d2,
- 0x43773469, 0x136add7d, 0x3a7c4569, 0xa044d68d, 0x4bc4589b, 0x6bdead7d,
- 0xfcfcf3a0, 0xeabfc645, 0x012f263d, 0xba9ee83e, 0x8491c610, 0x8053c728,
- 0xfd41f737, 0x7a50e61d, 0x6f63d3b2, 0x6a4fbfa7, 0xe04ce767, 0xa451f281,
- 0x04bf212b, 0xf4f0035c, 0xc08dce2a, 0x0b38a5c7, 0x2cee5be7, 0x33dd7780,
- 0x738fde51, 0x132eb7d9, 0xa2ab4ba0, 0xea91d4de, 0xa818d8fd, 0x00ffc1d7,
- 0x52a76c1d, 0x83ae94ad, 0x765d33af, 0x6efb075f, 0xeb0ffa30, 0x4f4b6a28,
- 0x8eb9e1f6, 0x2b75b744, 0x98fb4cdf, 0xa57743ea, 0x38a581bc, 0xa56cbaaf,
- 0x78e52e3c, 0x9bcbc01f, 0xd41f8cac, 0x79e3b715, 0x19b8fbac, 0x0269b1cf,
- 0x53a667e3, 0xc84d7e4a, 0xb2beb84f, 0xc557c701, 0x29938fb4, 0x257eabdc,
- 0x64495a59, 0x2244b97e, 0x9fa7902e, 0x3b103e6d, 0xe97be00f, 0x8dfb8cb2,
- 0x6c9dfb62, 0xfba8e765, 0xa4700a19, 0x093d66f7, 0x9d6bdfb3, 0x4b8ef88f,
- 0x0e3af780, 0x95edeeeb, 0xf4a13f23, 0xce2679e2, 0xdcf7fc01, 0xf83f29f6,
- 0x7bbbae84, 0x9b9418db, 0xa42ead09, 0x28c4be9f, 0x3f4a56c7, 0x20993209,
- 0x6aafbc51, 0x8a3b103f, 0xb9fcfb8e, 0x8f204561, 0x9e75f117, 0x095e517d,
- 0xebfd5970, 0xf6866e17, 0x0f14af3a, 0x99fbbc7c, 0xf813fd5f, 0x4d6dd2fc,
- 0xd69149a0, 0xf7a77ee7, 0xef1a7ed3, 0x33fbf616, 0xf7e81671, 0xdf0f93f9,
- 0x6d6ef00c, 0xb3f6c56f, 0xfac16e4f, 0xe17ebf6b, 0xf207ffd5, 0x80eb15de,
- 0xdc5f677e, 0x77a9788f, 0xdfb09d6b, 0x71bd7448, 0x27c67ec7, 0x39c3ae41,
- 0x4bfc65a8, 0xdfa0b5d0, 0x773d7fcf, 0xa87cb064, 0x12195d97, 0x38364ff4,
- 0x5e50929e, 0x14389ca0, 0x7451b445, 0xd2d3afff, 0x792acb48, 0xe01d7ef9,
- 0x33f18739, 0x790921aa, 0x7f431bed, 0xcc4c7dbf, 0x2f3bd416, 0xcf0833dd,
- 0x3ba30c4d, 0xcf918f3a, 0x88798463, 0xf33ea096, 0xa875e676, 0xcd2952d7,
- 0xce1249fa, 0x1ba6e873, 0x17b9c2b6, 0x6af985eb, 0x3abda1f2, 0xf889e403,
- 0xe75f1d7d, 0xdf2668ba, 0x537e71ce, 0x075a6157, 0xa3e7b9e5, 0x8d3f016a,
- 0x2b10ff7a, 0xd18f2fc0, 0x265643f1, 0x97dbea87, 0x384d1aeb, 0x9779e71e,
- 0xf32829f2, 0x94fa79e9, 0x6bda579e, 0xf0e1e5db, 0x3e32dfbd, 0x60ca4d19,
- 0x7d66d31f, 0x62fc0120, 0x75759af2, 0x58e7d708, 0x7052c53b, 0x760ae97b,
- 0xfb74d47e, 0xcfc4d5a4, 0x69b73b0f, 0xec33aabb, 0x8e0cb7c8, 0x53fa41c1,
- 0xab7752da, 0xcb7efe99, 0xa643b70a, 0xccf7b774, 0xb4e971b1, 0x695cebfe,
- 0x2cabd238, 0x31ec7931, 0x561a77e1, 0xe88f9256, 0xcfc9dfb9, 0x68859275,
- 0xe00a2c6f, 0xb44b4aa9, 0x1f7f8426, 0x7586b5f2, 0x636f5e5c, 0xbec624eb,
- 0x1c6629cc, 0x16d1ba67, 0x671d0758, 0x2fbd6132, 0x907ccef3, 0x945a9e8f,
- 0xae3d768f, 0x5fe0acf7, 0x3b3053c4, 0xa81fc03f, 0x7a06e6de, 0x7b33d24d,
- 0xb563f805, 0xf2e6f419, 0x4092d623, 0xdacd1499, 0x6d9270d5, 0x3bae9db4,
- 0x7ec4e6df, 0x857899e4, 0x07c48afc, 0x37fe391b, 0x40c5fe4a, 0x513d9e67,
- 0xc6eba016, 0x1443fd9b, 0x53870976, 0x9e9ba70f, 0x0e5e8c3d, 0xd81e3469,
- 0x37ada1df, 0x4295696c, 0xae50f1e5, 0x4875a79f, 0xda4bc016, 0xfe051ae6,
- 0x0ab75ea8, 0x5c86caf4, 0xf7f514a9, 0xbfbfe58e, 0x291bd68e, 0xb8dea0de,
- 0xaa4f9f8b, 0xc6ff42a7, 0xf085ea8e, 0x8984f4bd, 0xfd42590e, 0xad3a5c68,
- 0x1293d637, 0x071bff38, 0xe3a4f738, 0x94f2243e, 0xd529e41d, 0x269e41ab,
- 0xde3ea3e6, 0xfa86dee8, 0x73d5c937, 0xf510b7b9, 0x9994c6f5, 0x215f380e,
- 0x2acf627c, 0xed1af7d4, 0xda288ed1, 0x7487527f, 0x4c77d337, 0x7247ad84,
- 0x77927d42, 0x73d61794, 0x9447c05e, 0xf039aeba, 0x06dd9efd, 0xafeda1e2,
- 0xf28f19ef, 0xf98bd05c, 0x75ca0325, 0x8122d69b, 0xc5ae7e5e, 0x4c1a3e49,
- 0x9cb81fc8, 0xdbacf011, 0x7381a59e, 0xc3b79e72, 0x97127b3f, 0xc36bb487,
- 0x67d21f42, 0x13dbd73d, 0x7bc2ce0c, 0xf427f082, 0x641d3528, 0xd35e18db,
- 0xe0941f36, 0x73f1ab10, 0x6be252cb, 0x65bbeba2, 0xa637c6b3, 0x19abf500,
- 0xe957f7c8, 0x742956c9, 0xc63621be, 0x5de2aa2f, 0xab27c085, 0xc11c99a6,
- 0xda2aa9fc, 0xd20a89a9, 0x157108f3, 0x26763d83, 0xcff08cc9, 0xeac3d9b7,
- 0x79f6a165, 0xb74fda14, 0x480a79b6, 0x155d6d36, 0x92e70b5d, 0xf21363f2,
- 0x0f1d0b4d, 0x51d6fdf6, 0xbefb324f, 0xb14de715, 0x8ef9d859, 0x83371577,
- 0xb5c7203f, 0xb331c982, 0x8e7edc23, 0x3e1e855a, 0x740350a7, 0x00e4d532,
- 0xafe7f2bb, 0x6e91f348, 0xc260543c, 0x38af7179, 0x2bd99136, 0xe23ba00e,
- 0xd5bea2d6, 0x86f2ecd8, 0xc7462ba7, 0x02ff548d, 0x15d29c3d, 0x83b1ade2,
- 0xf7611fc9, 0xd6089f03, 0x12b9c577, 0x35f816e7, 0x37a08dd0, 0xf5af6e71,
- 0xf3f0f67c, 0x1ff743d1, 0xbde69f4c, 0xafd72e8c, 0xfb4397b2, 0x09622afa,
- 0x76d557b6, 0x1f0e1d90, 0x8c9fdbad, 0x823cc2f1, 0xbab06dcf, 0xbd60da66,
- 0xab58df5b, 0xd4be0125, 0x21a1f7b8, 0x8ccfd257, 0xd19f365a, 0xa60de31b,
- 0xb705231f, 0x0f4b08b9, 0x9598e7f0, 0xf723fde1, 0xcf4c4cda, 0x65fab6fb,
- 0x7c05a49e, 0x5f32fd09, 0xe36bdf76, 0x08a525fa, 0xe992b992, 0xebc04997,
- 0x8d6c1f81, 0x113f02f1, 0x7af5267e, 0x099cfcdc, 0x233b0abc, 0x7ff59629,
- 0x359b9f98, 0xbc63dfbc, 0xf05fb20c, 0xee35d83c, 0x591c880f, 0xdf71880e,
- 0x7c4bdf95, 0x3523c847, 0x41fac0fd, 0xaa7ec16e, 0x6bf722f3, 0x38edcfdb,
- 0xe1ef3d15, 0xe016abe7, 0xbc627a08, 0xe700effb, 0x19c47159, 0xeb3ff14f,
- 0x27a40677, 0x0437db92, 0x2d3ad0ec, 0x806c18f1, 0x1fd79d57, 0x78a6b784,
- 0x6cd7be36, 0x1cf4c8f4, 0x6f778a5c, 0x153c7987, 0x3d03e1c4, 0x5f9487f6,
- 0xbe24b9c0, 0x4d27e012, 0x700b1fc4, 0xdbbac5b4, 0xaee53e91, 0x3b53a84c,
- 0xf3be00a6, 0x9fb30c48, 0xbd90defa, 0x2e3c2943, 0x3efffd18, 0xc2e7ae8a,
- 0x87871c8a, 0xef7a73ce, 0x99ff779f, 0xfbbf3ef6, 0x7ec101b3, 0xeca346ac,
- 0xea07c6d2, 0x6da9123d, 0xbb77c30f, 0x986fcc6c, 0xbbf08375, 0xbadea1f5,
- 0x0c99ca22, 0xfb159f7e, 0xa4af93ca, 0xac5d37cf, 0x3f20de24, 0x0f1d135c,
- 0x8e2e9ae3, 0xe643dfc3, 0x7c81f3a5, 0x4e98ba68, 0x77d9c33c, 0x30fc6f80,
- 0xc0dbf19e, 0x3f6c4cf8, 0xf3fa51ad, 0x3c45e5fa, 0x422ed7c3, 0x1f6b8426,
- 0xb5f6cf1a, 0xdf9d9b2b, 0x17924dbe, 0x2bc583ec, 0x82993ecc, 0x19fd3174,
- 0x16c5a5f4, 0x0b134f8f, 0xb1f287fc, 0xa9c68861, 0xcc8f6a46, 0xf68cf2e3,
- 0x7a068ed3, 0x1cf058f5, 0x9c39f9ba, 0xd7faf1d7, 0xac589fe0, 0x74d1c625,
- 0xc746f99e, 0xfbfa74e1, 0xb1b1a627, 0xde162620, 0xe409253b, 0x66acf258,
- 0x32122ff4, 0xa9fa02d6, 0x97cb4644, 0x0fa4ae63, 0x458f5169, 0xf074a27a,
- 0x2faef16f, 0x1d021d04, 0xf187bacc, 0x49ffd135, 0x17f3869b, 0x1fbe1d25,
- 0xc6efdf01, 0xe80afc57, 0xd738c1ec, 0x7bde703f, 0x5ff82bce, 0xfa7fe48f,
- 0xe5d3a071, 0x2453c766, 0xc389bc74, 0x4bb0b7bd, 0xdef1fe0f, 0x44c8ffe5,
- 0xf5f3b47d, 0x1ba7c093, 0x0c9f268c, 0x5d2ec57a, 0x03ec5fb7, 0x339c62e4,
- 0xf38e9e3a, 0xfada383c, 0x9209a529, 0xfdc77f4c, 0xde144ed2, 0xbc191b77,
- 0x5b778ddf, 0xee9113e3, 0x757d82e7, 0xb38f68c1, 0xfbe8bd01, 0x2632e3f1,
- 0x3243f005, 0x74bc4acc, 0x997881be, 0x01ea746f, 0x2e9c0bfe, 0x38ace75c,
- 0x8145895f, 0xf2f93c87, 0x078ed70d, 0xd3eb9f99, 0x730e5fe0, 0xb872861e,
- 0xd1fa10fc, 0xa31a74f2, 0x6499d3db, 0xaf284ee9, 0x771d25a7, 0x8bd79b3a,
- 0xef087d78, 0x37eac497, 0x5d3dba72, 0xbfa9fac0, 0xceff2773, 0x62cef1bb,
- 0xe71d1380, 0x5ebe03d3, 0xbe82f28d, 0x8dd6f94c, 0x7c5e8cf1, 0x55be60d6,
- 0xf80437dc, 0xc5096f61, 0xfacfdd1b, 0x13ccbef2, 0x19f657c0, 0x57ed5b2c,
- 0xbe64dfc7, 0xc72d6fae, 0x958e541c, 0xe4d8e42a, 0x10c72678, 0x7a25744f,
- 0x420d5fa6, 0xc87d20fc, 0x1b9f8ed7, 0xe9dc19a2, 0x478da979, 0x77cbe579,
- 0x86f7f105, 0x044e7678, 0xad1d393f, 0x38dfe3c4, 0xfbc79c1f, 0x6616f1c9,
- 0x32fa39ef, 0xb6d39e61, 0xbbff78f0, 0x8b1f1fad, 0x1967be81, 0x53c4e6fa,
- 0xea93bb7a, 0xc422fa0d, 0x09eb0c87, 0x7cf34fb1, 0xdcf3857f, 0x8099b774,
- 0xef866bfc, 0x589e2225, 0x7d97297c, 0x3d4f7297, 0x1f86afd4, 0x52a7d5f0,
- 0xf4c9243e, 0x563c3643, 0x1aa71676, 0x16f3c16d, 0xee4fcfd5, 0xfa8f860f,
- 0xbe38a7bb, 0xda4bc6d6, 0x0e8f014f, 0x737180e2, 0x3cc2f9de, 0x79c9d29b,
- 0xa1a3d18b, 0xbb2dcd72, 0xbb7ec3d7, 0xea06f07f, 0xbef4a7bd, 0x30a66d21,
- 0x13df7aed, 0xf681488f, 0x3d91bfb9, 0x778e7a7a, 0x62ff7575, 0xbbbfdd1a,
- 0x39c0764b, 0xd7ffdf76, 0x7f4023a3, 0xc039d2e9, 0x75f2a0ac, 0xd1f61683,
- 0x53b4f4cc, 0xcffc251a, 0x47694f7d, 0x46f1c33c, 0x33a40af5, 0xf14e0fc1,
- 0x6212e5b8, 0x159fba41, 0xea15bb1d, 0x6e4be5fe, 0x7ce63885, 0xa4ec38e2,
- 0xeeecfff0, 0x5e77e889, 0x2fc89c44, 0x1f7479e6, 0x05d3f306, 0x45f594eb,
- 0xfd3aca6d, 0x92efd222, 0x73bfd547, 0xf865707f, 0x78d1daf8, 0xd39d27a6,
- 0xcfdf6f87, 0x7cbdbfdb, 0x837881be, 0x7c8080f4, 0xd5dfc02d, 0x39021ef3,
- 0xd390125c, 0x5d373e42, 0x8f308a8c, 0xb73f7f09, 0xdffafc38, 0xe9a37ce6,
- 0x79e515a2, 0xfc04f8e8, 0xd8666a9d, 0xe9b5e04f, 0xc4f12a62, 0x3f42ea07,
- 0xc0cb8c0c, 0x2c002a76, 0xf804c69f, 0x0b03f080, 0x2240fe3a, 0xdfb454c6,
- 0xac7ae61e, 0x52fc00a5, 0xa7bc801f, 0x278f76f8, 0x12e9faaf, 0x3a97dde7,
- 0xa01d9b44, 0x283ef573, 0x07f59c3d, 0xe24fb9f1, 0xae7809cd, 0xf0619186,
- 0x73a7415d, 0x0715507e, 0xf72ffef2, 0xeb072657, 0x0e7efd63, 0xa897b33d,
- 0x2dc85524, 0xf36b92a2, 0x2b1ca83a, 0x0862bd40, 0xf68f8d30, 0xb93e474d,
- 0x80923890, 0x19f77b8e, 0xf81fd132, 0x5899e52d, 0x3ccf14cf, 0x1337d31d,
- 0xf0d70e50, 0x64e94fef, 0xe8c68dfa, 0xe2fea1d4, 0x124b7624, 0xee4c989a,
- 0xa5a2a152, 0x1d449bf5, 0x47d68788, 0x3048cdf3, 0x26ffae9e, 0xeef9925e,
- 0x06573814, 0xec0caef8, 0x65029bc8, 0x1d8748eb, 0x4b9231ca, 0xf0c1d6cb,
- 0x67348e3c, 0xd18d7f40, 0x89fd332f, 0xc60920ae, 0xbab1ef8b, 0x4cd7d799,
- 0x116730bd, 0xe3326efc, 0x75f3d7f9, 0x7ca0490c, 0x246df60c, 0xc1b7d846,
- 0xe31cfbe4, 0x54f4bc4b, 0xf52ed1d8, 0x03f41364, 0x02769344, 0xce9935df,
- 0x16b3607b, 0x1ea09162, 0xbbe0b965, 0x337f008f, 0x90c33479, 0x009f5dbf,
- 0xade96f7e, 0x28ffc0c5, 0xf3802d3f, 0xeb5db11f, 0xf05e7d43, 0x5f5f1b27,
- 0xa94fe72b, 0xfec24054, 0x7e9fce65, 0xfc8c5e6a, 0xf6b88129, 0x14da7f03,
- 0x53f9013b, 0x7ae37132, 0x156827e2, 0xa5d1267c, 0x6ad727ac, 0x23c87c55,
- 0xdd52fac1, 0xe48ddfca, 0xc907ca14, 0x1cb94ae7, 0x2e4a768f, 0x157423f8,
- 0x44f51cec, 0xb4fd78b1, 0x9aceb668, 0xbff31b04, 0xfdb8b145, 0x2101f4d5,
- 0x017ad5ff, 0xb5da5629, 0x413d368d, 0xb512553f, 0x7ea187a8, 0xf4c09350,
- 0xd03df783, 0x5f21f72e, 0x0bfdc13e, 0xaab82753, 0x77df14b4, 0x4ea391e6,
- 0x724b2e5a, 0xba5026d7, 0xb9a47e99, 0x6bd69ea1, 0x3ef922df, 0xb18e165a,
- 0xf8a76dd4, 0xecdb3b5d, 0x6beb4d58, 0x3dd48ccd, 0x97d40689, 0xda69c808,
- 0x829345be, 0xf02691fe, 0xb47e52c7, 0x4011e216, 0xda098317, 0x593f54d3,
- 0xb6e3a46b, 0xd658b7ac, 0xd58fc1db, 0x85fc0e37, 0x65888b7d, 0x3e73092b,
- 0x4773d12e, 0xd424fcf1, 0x4e255e29, 0x6df7e26f, 0xab0e7bf0, 0x3b05298f,
- 0xe9cbfd90, 0xfc0b0ca4, 0x4f2cb937, 0x5cb3a9a0, 0x39eb4897, 0x4fe81d63,
- 0x8c4f9c26, 0xe7e1df10, 0x5ce05470, 0xaf217b60, 0xb87cea0f, 0xcbe6092a,
- 0xaeee0e23, 0x58239c0b, 0x50fe85ac, 0xe0f1ccca, 0x09237c73, 0x2af983fc,
- 0xde23f303, 0x43b6f2c6, 0x76bc59b3, 0x1fb7d684, 0x5e28f9ce, 0xd332f216,
- 0x43be5525, 0xe8c8bfe9, 0x0edbb038, 0xb0c97520, 0x43cb52ef, 0x91fdf0ad,
- 0x81e277ae, 0x52368daf, 0xd6cb40fe, 0x92c38732, 0x80d6fb83, 0x2747a9ff,
- 0x0e3393e4, 0x11606b73, 0x9cd5fbf4, 0x96d6a696, 0xfb0c5edf, 0xec0992eb,
- 0x5c1ca22f, 0xc1359329, 0x8be787f2, 0x09fbfa88, 0x207fbfcc, 0x21379c61,
- 0x74f82e28, 0x7283d702, 0x8ff02e49, 0x2cfdf3a0, 0xf9775bd0, 0xbfce919b,
- 0xff9f9db2, 0x75c39c3b, 0x3e72efa8, 0x8badf820, 0x274cc5e7, 0xa7c01d4e,
- 0x01f28a2b, 0xbe563f5a, 0x34c0f90c, 0xdfdfc6e2, 0xa6f060ab, 0x7cc1d788,
- 0xf5282653, 0xca5c3b8d, 0xb55ab4fa, 0x9ebf423e, 0x74eef814, 0x46bdb2b7,
- 0x941397e8, 0xeface5fa, 0x9ca2b25f, 0xe1ba7e4d, 0x97f040f2, 0x8225d54f,
- 0xe793b0df, 0x184a74bb, 0xf9e26a1f, 0x921d4d2e, 0xa9a5df22, 0x8903de73,
- 0x8d2ef941, 0x77cb571d, 0x09c8fa61, 0xf83f779d, 0xa32c4fd5, 0x39dfa63b,
- 0x0e22f3c0, 0x51445e42, 0x73ccfe80, 0x52909f98, 0x33d1fa33, 0xd00e312c,
- 0x8a69d7ab, 0x2eb8afd0, 0xfff0acd6, 0xace55fae, 0x9fc27e82, 0xa65cf228,
- 0x3b734819, 0x641d53f3, 0x8fcc5cf9, 0xb4f6e5e4, 0x7e124137, 0xc7e835e1,
- 0xc4df9d52, 0x24f28278, 0xfa2e6671, 0x0b3b6b0b, 0x4b5fc18b, 0xb1fa12e5,
- 0x1c7609bd, 0x442eeb5f, 0xa62dd73f, 0x683f18e9, 0x5da2dcea, 0xcfd00a68,
- 0xc5dd055f, 0xbba01890, 0x4ed1ff7e, 0xdc8ffa03, 0xa06bebb2, 0xafbd7aaf,
- 0x12e92880, 0x77248f7f, 0xebbc7096, 0x17d35c2a, 0x1ef4b851, 0xfec03bd5,
- 0xe2058aa3, 0x563dc5eb, 0x1ada83e4, 0x4d7efc82, 0xd97e4139, 0x4ff985bb,
- 0xbd2eb33e, 0x9afef815, 0xaa72826a, 0xe10e36c7, 0x0f788cbf, 0xa5b8e93b,
- 0x053d299b, 0xb6bbfff1, 0xa4f5eb29, 0xfd78f91d, 0x44ba10f6, 0x56f824be,
- 0x3acbb103, 0x52ec6b88, 0x9883278e, 0x7870777c, 0x3abe7217, 0xadb18efc,
- 0xae1f6f10, 0x2c85fc61, 0xa0d7a474, 0xf2cb34fd, 0xbab01469, 0xe92ba5a7,
- 0x33e6bd47, 0x8cc73b32, 0xf9f0967f, 0x84bd7cd5, 0x6b3745eb, 0x1450a1a9,
- 0x7f6873d0, 0x74d41fac, 0xc09a29ca, 0x38f98b3a, 0xbe095fa1, 0x5e55f02a,
- 0xa5194846, 0x39139bb3, 0x3649b3be, 0x8fce9be0, 0x46412e74, 0xf7e70d8b,
- 0x8a343d80, 0x83d28f7f, 0xa3cae807, 0x7e817a31, 0x28cd4ad7, 0x47a08c4f,
- 0xe4bd72d3, 0xf2fafe46, 0xf40c8f52, 0x4f349231, 0xf80b35b9, 0xf00c576c,
- 0x15274a1f, 0xfa018989, 0xccbe2569, 0x8e82921d, 0xfadbbdb0, 0x123a5866,
- 0x1ef7dffc, 0x11260bd3, 0xefd1bfaa, 0xf4c4ff3a, 0x12d28397, 0xc7aa13a4,
- 0xe5fd041d, 0xafb30d4d, 0x406dd226, 0x128b2abf, 0x9453e3ff, 0x10f689f5,
- 0x013cc0fa, 0xbd3c3f67, 0xa4cf585a, 0xa73f655c, 0xc9445fe0, 0x25c8b2bf,
- 0x743f0766, 0xbfb05ef8, 0x5c925663, 0x8d520788, 0x4c3831cf, 0xf13ea5bc,
- 0xd7dbf73b, 0xdbf18627, 0x3db8eaf7, 0xc6b3a2a0, 0x6ce767c3, 0x147a0120,
- 0xd246e2e7, 0xf850a72c, 0xf163bf49, 0x0e811b91, 0x19945d29, 0x3be81e49,
- 0xc3f998a4, 0x7410f9c4, 0x1b6bca57, 0x240d9d04, 0x6ece8103, 0x7f4288ea,
- 0x6f408de8, 0xf90b7e94, 0x0b9e42bc, 0x2cb5bdbd, 0xa4b2be84, 0x39eb941c,
- 0xae424f40, 0x8f1c970f, 0x7a0597df, 0xf6f507bb, 0x436a7a20, 0x3d28927a,
- 0x4427bfa1, 0x55db2a5e, 0x7ef026f4, 0xe5a3eb9c, 0x85ed19a4, 0x4e4cd1a9,
- 0x3d99aafa, 0xd224d94f, 0x8c35ebdb, 0x1388aade, 0x289cade9, 0xa8d2a4e9,
- 0x91e9abac, 0xa4a3517e, 0x9bd23737, 0xd1234e9a, 0x37a040db, 0xafe32f21,
- 0x137b6f4e, 0xff33ff4d, 0xedbd285a, 0x76b92c4d, 0x6c7c137a, 0xd2a59447,
- 0xa97c7204, 0xf8617284, 0x50ad41d1, 0x8590da1f, 0xab0ee7fa, 0x37b600e3,
- 0x2ee2f6b3, 0x0ef90ca7, 0x7b782b39, 0xea12ab96, 0x3b692b4d, 0x38e4ba9d,
- 0x741887cb, 0x5c2f6b3f, 0x0cc07cdd, 0x1b0f2f7e, 0xb5f3f7bf, 0xf76d2c72,
- 0xcbe3e5ae, 0xdea12adb, 0xff8d8eb4, 0xc328e20c, 0xdbca8f20, 0xb75fbf0a,
- 0xccc1cb21, 0x8ef7a657, 0x21ddfbe1, 0xe3803ced, 0x25b8d8da, 0x04d18d87,
- 0xcfa66ced, 0x39f7ccde, 0x67db3366, 0x4cb747c2, 0xa7bf83b0, 0xd8fa83cf,
- 0x52fa9aa7, 0xec1173e4, 0x2da972d4, 0xc0f1ca03, 0xbbc064bf, 0xcd9c9d63,
- 0xe95b68e2, 0x644abe27, 0x7f110e7e, 0x75773882, 0x55f37e90, 0x8a13f322,
- 0x8236497e, 0xcc7912fa, 0x8888768c, 0x211ef98f, 0xd84f9c12, 0x148b8c23,
- 0xd39f1b2f, 0xf8c3fa8c, 0xe64e2281, 0xdfa7ced7, 0xc5fcbc2d, 0x987e70b8,
- 0xbd32247f, 0xdb8f0ce5, 0x7a97df8b, 0x077f3c59, 0xc01a4910, 0xd626f755,
- 0x2b0844ad, 0xbc03290f, 0x46cc7ab2, 0xa8ebc7e9, 0xd344bf91, 0x7080f5ac,
- 0xff3094cb, 0xf1177268, 0xae86c5c5, 0xf896bc7f, 0x087f2cf4, 0x55b8bfd7,
- 0x8443f98f, 0x383bb5f3, 0xc1e8c8fe, 0x72a7ce78, 0x7124a53c, 0x19387dbb,
- 0x0eea7c0e, 0x8d3bb78e, 0xa7263acd, 0xfe2a74db, 0x7a049191, 0xfa88a6cf,
- 0xc55db2b8, 0xeff2965f, 0xf87ae62e, 0xfe87d232, 0x1eb94fc2, 0xd313667e,
- 0xed22efc3, 0x7dec2fe8, 0x0d9de98c, 0x2f407b74, 0xbe4abccb, 0xb28cf750,
- 0xacaed0de, 0x0eb15237, 0xa87537f3, 0xf31e4ef8, 0x6a6ef6c3, 0xdbff0528,
- 0xa28f47d2, 0xe0a977df, 0x9f255e33, 0xc67ee421, 0x1eb91e67, 0x7b6a3ffd,
- 0xd4e9d85d, 0x0929be3e, 0x999690e3, 0xcc37a0f5, 0x0f796189, 0xf91f29b2,
- 0xf688d982, 0xa0be2472, 0x5e8483b6, 0x7f0fae42, 0x3204a85e, 0xe0823ec2,
- 0x5fef82ef, 0xb6525ec1, 0xec23f0ab, 0x3f1c1995, 0xe1fe2853, 0x76127f3b,
- 0x9f8632d2, 0x0875c4a9, 0x5ddef3f0, 0x6ec23f0c, 0x9276e6fa, 0x93b60e53,
- 0xad75bd84, 0xefda92f6, 0xcf5bce2e, 0xdacf6100, 0x026d9ed1, 0xddfe5340,
- 0x13c4f7b0, 0xefd02455, 0x68710b58, 0x72f54175, 0x66b57fa5, 0xc852e9d2,
- 0xae88cc9f, 0x46e017b8, 0xffd1133a, 0xec2c90d8, 0x34ff3627, 0xe175cf9e,
- 0xdb38accb, 0x29c4fc95, 0x836b86f3, 0x6d5ee3ec, 0x43d82c5f, 0xfc2497bd,
- 0x61add42e, 0xf18151e2, 0xe87c710b, 0xf7bebbf7, 0x4f73e067, 0xf13c60c4,
- 0x2ecc97c2, 0x2879b0bc, 0xe39f15e6, 0x87015771, 0x799f8725, 0x70e70fd5,
- 0x10e182e5, 0xbc93aebf, 0x6da6ed5f, 0x9fee8c23, 0xd3adf9c3, 0xbe8cf4f8,
- 0xec445c58, 0xd3dfb23b, 0xff4f7c83, 0x7dbf931a, 0x89e63452, 0x0487dfd2,
- 0x273687c7, 0xf081f8b3, 0xf93909c7, 0xe56f5e47, 0xa35a9ef7, 0x3f98fec4,
- 0xf3bc52e2, 0x1fff8029, 0x57e0fd61, 0xfc87477a, 0x10e6fc1c, 0x9952a4b7,
- 0xd742dba4, 0x6df9f105, 0xdf9f10d7, 0xc5e4c499, 0xb08b4a39, 0xe73645be,
- 0x33bdf08b, 0x86790e3c, 0xc4ceb1c7, 0xbed6b8b2, 0x7cacfefe, 0x2267979b,
- 0xbf45d1c4, 0xae8c5b8f, 0x3ede9435, 0x35ae216c, 0x1fd83e54, 0xde633431,
- 0xafb62ccf, 0xcc563dde, 0xfee31513, 0x0e7e5494, 0xd5acf1d6, 0x85ca1875,
- 0x347bca6d, 0xd41fb0bd, 0x7abed837, 0xbe2958a3, 0xeaa4a7f7, 0xdecf8073,
- 0x67c47ee9, 0xa8a47d7f, 0xdefe70bb, 0x5fc8fc9b, 0x345bf709, 0x2918f3f0,
- 0xf8b5760e, 0x3c8e3a97, 0x1e6f9c5b, 0xa6c59e47, 0x1c79b322, 0xac918e79,
- 0x73eda74d, 0xffd1933b, 0x33d634be, 0xf6471144, 0x78a37cc4, 0xdec7a0be,
- 0xec388101, 0x0e20df63, 0x3be9397b, 0x4e5ec38f, 0x5587130a, 0x025fe9c7,
- 0xc01741bd, 0x0616ddc3, 0xbeb92ab7, 0x17a0fc12, 0x8fcc1216, 0x8fd9242e,
- 0xec3d068c, 0x91788e88, 0xfa3d326f, 0x744b786a, 0xe15d8869, 0xf6268ebf,
- 0xbaa4fda0, 0x6a3a8a6d, 0x877941e6, 0x14d34be9, 0x673407e3, 0x5c0ffa2b,
- 0x3da2bd79, 0xa8a453cb, 0x51bbace7, 0x5b707fd1, 0xf43ea285, 0xfd145bd1,
- 0x28d6f3af, 0x7fe017ea, 0xc8c9af90, 0x66786ed7, 0x92fc6286, 0xf52c5e37,
- 0x7cb9b6c1, 0x8b72e56e, 0x795d9c78, 0x02fdcca5, 0x9f6fc8fb, 0xf89798af,
- 0x0a549f24, 0xeff64971, 0x87bb2c5c, 0xc58bb0b1, 0xdc758607, 0x684ef8a5,
- 0xa32ed25c, 0x9121d5de, 0xf8d0a4c7, 0x87ced2e4, 0x8ade42d7, 0xffa17f5a,
- 0xa0c5b572, 0x3e6344ef, 0xa99f5aa4, 0xa027364a, 0xd24691de, 0xe9ab5d18,
- 0x0f0fd4c2, 0x4851f7b8, 0xba323c86, 0x0a174158, 0xa1f851fc, 0x76c2eb7f,
- 0x2d35e633, 0xd2016379, 0x494521a3, 0x25765117, 0x2ae4c45d, 0x50ecc2e9,
- 0x995c41d2, 0xf0d40e92, 0x74953ab6, 0xbff4fc41, 0x7e3bc02b, 0xd46e9282,
- 0x7d222ef0, 0xd80f3187, 0xdf00392b, 0xeb2f786a, 0xbafb82d8, 0x3cb8be9a,
- 0x3917c799, 0x741f877c, 0x6e109ab6, 0xf8493f2c, 0xeedc0c03, 0xbf4a0926,
- 0x56abd098, 0x8dbd7325, 0xf2fc23cf, 0xda0f256b, 0xb871fdf1, 0x2fa65f32,
- 0x66f9ec0b, 0xae43fcc2, 0xc3139207, 0xf7f117fa, 0x0145fe48, 0xff5ca9d7,
- 0xff2c23ac, 0xf31478e6, 0xbd5c7d0b, 0x8b42fd0c, 0xd1ea3349, 0x73c66ae7,
- 0xfb07a1ff, 0x0219e1a9, 0x529d353f, 0xf904957d, 0x1aa2ef5f, 0x142726b2,
- 0xe4a7529e, 0x533dc333, 0x81e429d2, 0x5013dd9b, 0x84e857fa, 0x12bf3052,
- 0x5f98b0fa, 0x31f04fc0, 0xfc01af31, 0x540e7032, 0x2ae48d7c, 0xc7f6a2f1,
- 0x963031c0, 0xec5bc706, 0xa33e3824, 0xfc04c3f6, 0x84fed42f, 0xacc0e178,
- 0x3a07b856, 0x3f44e2dc, 0x9ae9095f, 0xff0bbf09, 0xae21fa0b, 0x887efd23,
- 0x2aea7288, 0x1e29ddf1, 0x5678ffc9, 0xc4575c68, 0x3e182989, 0x3c1d33fa,
- 0x800fb25a, 0x1decd475, 0x1474089a, 0x9c7497ea, 0x23ce857c, 0xa1e2fa6b,
- 0x2824155f, 0x5f7dc507, 0x9fb8fc97, 0x81f3893b, 0x8dddfbe0, 0x4cdc7da4,
- 0xf95307f4, 0xf3250b18, 0xb50e915b, 0x7f45adde, 0x04ee86b1, 0x048ebde8,
- 0x02b33bc5, 0x439758ed, 0x479ad7eb, 0xc2c53933, 0x3e5809f3, 0x4ffce128,
- 0xed9191d8, 0x16fae535, 0x49661698, 0xc105f7f4, 0x7586b8eb, 0xb8097c8a,
- 0x90710a27, 0xd7042981, 0xc76c95d3, 0x4fa21bdf, 0x6e84ebbd, 0xc1995dc5,
- 0x9e936e7a, 0xb760361a, 0x716064bf, 0xfea576cd, 0xf4c29d1c, 0xe070c8e0,
- 0xbb2a59f9, 0x8f7a6ae6, 0x4aeacfc8, 0xf7d628b6, 0x362b9c60, 0xc06f7e85,
- 0x92a7ff49, 0x4abe3026, 0xc43cc6ee, 0xde321d0b, 0x89bc6aa7, 0x3dc687f1,
- 0x9ea11e32, 0x17de034e, 0x0071da5e, 0x16eea5f5, 0x7ea880ca, 0x7e85b672,
- 0xe015f079, 0x246fdaaf, 0x31e4417b, 0x7ee1490d, 0x10520288, 0xf105079c,
- 0xf1b094fd, 0x27fcfeff, 0x93e73b65, 0x1c5e7255, 0xcfeda3dc, 0x65f6d16b,
- 0x47e104d6, 0xb8af8fbd, 0x73aa525d, 0x70a14f0d, 0x632ba0fb, 0x2557cc23,
- 0x034e1e77, 0x1c90acf8, 0x631b7f10, 0x0d1bf760, 0x734772f2, 0xf4379d90,
- 0x7105d95e, 0xee2bd3ce, 0x69fdc1b1, 0x4950ef31, 0xa8f0f783, 0x0ffef185,
- 0x36ee218b, 0xd69eb1cb, 0x9d981b66, 0x18bdf599, 0x5f3d0e5f, 0xfbb3d3bf,
- 0x66ecba5f, 0x67d057bc, 0x976fd195, 0x40b19320, 0xe2bd6217, 0x1df8a2de,
- 0xfe4353ee, 0x4c7df8a6, 0xbbf0df6b, 0xb14a6969, 0x187bde2b, 0xbc37d953,
- 0xbb8014d9, 0x4c6ad7c8, 0xfd05afd4, 0xeac8c7a8, 0x7a8b99c4, 0x3b230ae4,
- 0x3db8a75f, 0xb0b06a76, 0xe0e67da7, 0x28c6a83c, 0x93e61c67, 0xb01323bd,
- 0x38b4bf3b, 0x5fb8ace3, 0xc2c79b0b, 0xf9e1e9e6, 0xabde2bc3, 0xb12d7b40,
- 0x531e7c35, 0xbbd30a43, 0x8aca2feb, 0xad7aa63c, 0xea91f30f, 0xbf15ea2f,
- 0xe2e1487f, 0xf3ea0431, 0x071a0ccf, 0x1c405beb, 0x82ffa16b, 0x13c43175,
- 0x3c8897a4, 0x7c3d3566, 0x68dff1cd, 0x30ed12d5, 0xbaec0fbc, 0xfe57bf52,
- 0x5fbd8729, 0x468a48f3, 0x1e61a1e4, 0x3037b531, 0xf7eea79e, 0x7cea29ef,
- 0xe7de3f33, 0xdb37cfec, 0x77c57e53, 0x962f1a19, 0x1bc1f22b, 0xd71878e9,
- 0x2aac7178, 0x4bcf9c1f, 0x029bb3e7, 0xe0916679, 0x5b3275ff, 0x91e42357,
- 0xceff07c5, 0x9df029e8, 0xe6179e04, 0xf8f3858f, 0xf78c876c, 0xa23d9f9d,
- 0xcc35b099, 0x5c393bba, 0xe2d44fae, 0x47c1b939, 0x7cc25b9c, 0xf713f45f,
- 0x3c7dc419, 0x5576faf5, 0xfac0e7f8, 0x7e658c47, 0x2f3cf561, 0x758af870,
- 0x7c31b2ef, 0xf14abe34, 0x2c28f981, 0xcd97774f, 0x83f918bf, 0x4fe78945,
- 0x763ad992, 0xc4cfe2dd, 0xcc899cfc, 0x0f448eae, 0x7fdd58f7, 0x9a6e3d45,
- 0x48d57209, 0xb259b6a9, 0xabb79d04, 0xee0043d1, 0xa1af02b2, 0xbb63d770,
- 0x63f3f798, 0x7e7edcec, 0x61539d8c, 0xa8fe7c0f, 0xf401f98c, 0xa0a49b40,
- 0x09cffb3c, 0xde7c0b8b, 0x3ffea126, 0x4ac84ddf, 0x6de677ca, 0xe2fa63ab,
- 0x7531c353, 0x9fbf7e07, 0x547997f2, 0xcb4cddde, 0xf1546bf9, 0x08576e61,
- 0x8370bc39, 0x1b21deca, 0x3cc64bfe, 0x279466cf, 0x1cae7f8b, 0xa4db74bf,
- 0xea7be0cf, 0x4afa3638, 0x71fcfda9, 0x4bcbd70a, 0x83c82949, 0x42fa9fbb,
- 0x7c8f6b1f, 0x7e50ce1e, 0xf030683b, 0xdd96235d, 0x2f2c162d, 0x41bb38a6,
- 0xdd53e83e, 0x7bd7c0bd, 0xbaf061df, 0xc9817f50, 0x39bcb80b, 0x84b9f812,
- 0x9330cef2, 0x841f79c5, 0x2e14ec7b, 0xfb930306, 0x35fddc72, 0x5e957193,
- 0x7e118ba4, 0xca2b1ccb, 0xd00a4723, 0xe373c27f, 0x13fc0027, 0xc2718b9f,
- 0x7b97d6be, 0xc37f069f, 0xe8d155fa, 0x581a35ff, 0x7b67399c, 0xc0ec06b9,
- 0xfb4976eb, 0xd4d1dfc1, 0xde172ab9, 0xa3d93017, 0xae213f31, 0x93165e73,
- 0x093bec73, 0x801daead, 0x57b804cf, 0x3eb5d747, 0xf8c29bcb, 0x1a83d338,
- 0x257bcc39, 0x3dc07ffb, 0x321bcf6b, 0xa0bc83de, 0xd7fcf965, 0x915f8613,
- 0x0edf050f, 0x29baf7d6, 0x40d0c8dc, 0xc976fafd, 0x77c58ba7, 0x515e3024,
- 0x3497dabf, 0x6fd1e413, 0xe9ef18b4, 0x52efd75f, 0x23ae202b, 0xc94cd0e4,
- 0x5c47fcc2, 0xc44e9d9f, 0xaa17163f, 0x9d3274e5, 0x6333b1eb, 0x13e77c18,
- 0x9b8c2647, 0x1ab12461, 0x5666947a, 0xfee097b6, 0xd05674ea, 0x237c4407,
- 0xde111eb2, 0xb4f8d3ef, 0x94c7dd99, 0x24c086fa, 0x72a7c167, 0x3a37f385,
- 0xc69dc995, 0x4b8fcc21, 0xc4271106, 0x1d5f1ad3, 0x72ec05ba, 0xdb8b3443,
- 0x8464be52, 0x810e56f7, 0x5efba6bc, 0x7b144af6, 0xc7dc433f, 0xe10b38b6,
- 0x4d53637e, 0xb7de1146, 0xef87d93a, 0xfce8f420, 0x297e7899, 0x4ca891bf,
- 0xb6d373bc, 0xce94b55b, 0x3ea8d31b, 0x366beb46, 0x0b55bced, 0xfdb2e4f7,
- 0xfeb4358b, 0x58b7a6fc, 0x4ffef5fb, 0xa6f2fea1, 0xc8bdac13, 0xf5a658bf,
- 0x613e9b63, 0xa4d060ed, 0x4d97f211, 0xe87ab7dd, 0x5cad67fc, 0xf1f871df,
- 0xdee36a1e, 0x7f609aa1, 0x8ca99be2, 0x628d9d5f, 0x9166cefd, 0xef0035b9,
- 0x5ffdf0dc, 0x24f0d548, 0xc52c368d, 0x9278c57e, 0x22dc7e12, 0xbf196e3e,
- 0x86263a87, 0xf1628bac, 0xc52c4f29, 0xa1cec1c3, 0x989b5f18, 0xf370e36a,
- 0x62253be3, 0x314f011e, 0x5deef89f, 0xbe599720, 0x9e706d5a, 0x7f1cddfa,
- 0xf06b3bf4, 0xec9c833b, 0x464d66fe, 0xe28fe021, 0xa6f1cb4d, 0x7b89bc05,
- 0xb5af30df, 0x70fff900, 0xbc1f5bf0, 0x0567fb44, 0x93a6add6, 0xa7c65496,
- 0xb8b2b597, 0x07359f62, 0x0c4c69e9, 0x58a2f77f, 0x1c638fb9, 0x5aa66f0e,
- 0x01073df9, 0xbf0964af, 0x98e1cad3, 0x93521fe1, 0xfdf7cdff, 0x77cf5f30,
- 0x7c20efbd, 0x8afde139, 0x6dd71d83, 0xb1b1fb65, 0xcf4a54bc, 0x1ef3d436,
- 0x7677cc56, 0x197c6a95, 0x5fb0903d, 0x7f8e0e5b, 0x2077bf90, 0x7182f3de,
- 0x3f4c0559, 0xdc55bd05, 0x9b9e27d3, 0xb4ffb049, 0x3b7e3eff, 0xd81b37bb,
- 0x7cc5ade7, 0x4fbe169f, 0x57a7db0b, 0x78e4af41, 0x7354e65f, 0xc3f71d28,
- 0xbcbe7fbf, 0xe29f3e22, 0x0f9b879c, 0xbc2475ce, 0xf1aefc1c, 0x82a9d622,
- 0x559c3f67, 0x84f013eb, 0xf2e38df3, 0xd6297494, 0xf3a472f9, 0xbf2df59d,
- 0x35c6ce57, 0xf7e580fc, 0xae92bb12, 0x6965761b, 0xc62e7e20, 0x2ecf03e5,
- 0x3ebdf809, 0x6076e54b, 0x9088c906, 0x352e778f, 0x7f0cbfbc, 0xbd81db57,
- 0xacef9656, 0x26f407f6, 0x109cba3a, 0xeecf3a47, 0xf9528f6f, 0xb29e202f,
- 0x171814d3, 0xfaca2f90, 0xbf0634c8, 0x1f4bff50, 0x362d2fde, 0x7768bc54,
- 0x31eebb50, 0xbfc06dcd, 0xee2ae38b, 0x98f5a2c9, 0xc06ddd34, 0x2bd38bbf,
- 0xfca2c8be, 0x67a69cdc, 0xbe2a1bf5, 0x63fa86c8, 0x8c7fd67a, 0xf7e045f3,
- 0x6dbfa3c4, 0x8f406a6c, 0xb3b34d88, 0x1a9553fb, 0x5fabff7c, 0x019df97f,
- 0xd70117f5, 0x41b16548, 0x4e2e1cd3, 0xe8269c95, 0xca13c581, 0x90ed7fe0,
- 0x7cedc4f7, 0xe76156bf, 0xfbb2c6f7, 0xfefbbdb7, 0xb227f786, 0x6919dcd3,
- 0x314d5d74, 0x68b273dd, 0xfbcc757d, 0x9c92af18, 0x3f010f54, 0x6642dd87,
- 0xdd4af5d1, 0x2fa05deb, 0x461cbb91, 0xfb95c22d, 0x314de07d, 0x5e57bf0a,
- 0xe97dcdfd, 0x582e33ec, 0x07ce48c7, 0xfafd5e9a, 0x3673882b, 0xc039359d,
- 0x73b23e2d, 0x6fa03dd3, 0xf37cec8d, 0xd987266b, 0xeeb10f7d, 0xa3d7e091,
- 0x187597bf, 0x3b23fd70, 0xfd045baf, 0x33a1fd47, 0xa6e4e807, 0x6056be53,
- 0x5efbbd0b, 0x1fde574e, 0x798aecfd, 0x4de3118c, 0xe89f1e02, 0x1499e809,
- 0x7833371e, 0xab7cc25c, 0x6b63c49e, 0x2b97a8fd, 0xbd50d3ef, 0x17a6e31d,
- 0xfc03b448, 0xb35ee2f8, 0xb2785fda, 0xfe8fee9a, 0x5d1f537e, 0x3cde9041,
- 0x3291a2e6, 0x9cbd4092, 0x4af51558, 0x7fa2aa63, 0xd14b2595, 0x3ae53e3e,
- 0x7b44fb45, 0x293ea2a1, 0xffa2a477, 0x45728e6d, 0x89b2f6fd, 0xced5fe8a,
- 0xd0bd456a, 0x3fe8aed7, 0xb28748fc, 0x019138fd, 0x1d27450f, 0xf92ca007,
- 0xc76e89d8, 0x07cd33d2, 0x25f91ca0, 0x5fda8703, 0xf6c5e37a, 0xf0bbf003,
- 0xc7efaa97, 0x34e9ff08, 0x87d5e4d9, 0x68a693f7, 0xf25e7969, 0x35913f23,
- 0x2d8c7eec, 0xe02f7dd6, 0x198fdc4d, 0x8a52fe03, 0xe7b9aa84, 0x59f0bdd9,
- 0x12765fcc, 0x69fc0310, 0x7cfd19ba, 0xcfcd7527, 0xbdc599ff, 0xbbdf0007,
- 0xb156afa9, 0xdd1731ef, 0x93977d8a, 0x2d3c2a65, 0x2cabd457, 0x1ff4503f,
- 0xd14ab29f, 0x90fed13e, 0x2b0f4f0a, 0x3639b7ea, 0x45b4f0a9, 0x28dfa785,
- 0x70edfbda, 0x157abfee, 0x1cb44efc, 0x04aaefed, 0xa67cdc3c, 0xd651f10f,
- 0x780956d5, 0x3b64f1ba, 0xe7d8abe2, 0x597604aa, 0x00f9a47a, 0x7f6a3e94,
- 0x5ad7b8c1, 0xd83cb052, 0xd5ff4762, 0x2c5c96e1, 0xf038b48f, 0x94b7dff7,
- 0x8b56f961, 0x6cffcb13, 0x57658099, 0xf6cb0b8b, 0xbfec7696, 0xf983a5b3,
- 0xdffbe2bf, 0x7e001815, 0xbf8d1e81, 0x3c56ee11, 0xe434d8f7, 0xfed13d9f,
- 0x26afa81e, 0x9636de77, 0x81e78d32, 0xcc9d8089, 0xcee9a3cb, 0xbf94e9d1,
- 0xac1c85ed, 0x41fe4092, 0x0859c6bb, 0xb4e1f87a, 0x0ed13f05, 0x5581e420,
- 0x958b14ae, 0x8eb48dd5, 0x643186c8, 0x199c4fc1, 0x25105e74, 0x70584c18,
- 0xa37bd41b, 0xb4defb58, 0xf279b705, 0x637107fe, 0xe17e4867, 0x7130b4e1,
- 0xd8cfe7e3, 0x39cfe0cd, 0x19a86976, 0xfb8c71e0, 0x50a49cb5, 0xe5968f37,
- 0xc81d42da, 0xbd2a93d9, 0xe4539444, 0xde61b7f2, 0x0ee38d76, 0x45be6fcc,
- 0x6b7e8047, 0x8aef6624, 0x99d3db7e, 0x9b7bd0bd, 0xe3a9ed01, 0xbc22e71a,
- 0x3df52717, 0x49ee7001, 0xa9ca3efb, 0x265f735e, 0xed3bafc0, 0xd89eac7b,
- 0x08e484f7, 0x7c18ebaa, 0xf7bb4fde, 0xd9cf86bb, 0xf85092b4, 0x5859a6f4,
- 0x1ce7c0dc, 0xaf007a80, 0x3676af1f, 0xdcac9c60, 0x71f61839, 0xe76065cc,
- 0xfbc665d7, 0x2ceb4413, 0xbfc823b9, 0xc3ae9753, 0xa2e15371, 0x6739f81b,
- 0xd5ce78c8, 0x9d287cf0, 0x27481fd9, 0x8f4e6760, 0xb8e0bb41, 0x5737dd86,
- 0x9d267ff7, 0x1173d9c9, 0x0dfd83de, 0x94c57b87, 0xd377e786, 0x44577af9,
- 0xaebdd4e1, 0xf58fa8a1, 0x9f784b36, 0xf34cf7b7, 0x706ed679, 0xdc609070,
- 0x1ffc2672, 0xf3be7f6d, 0x91febf9e, 0x457f7ff6, 0x8865038c, 0xdf847ae5,
- 0x7679de0c, 0xa7f511bc, 0x2a0335d9, 0xe4ce2e40, 0x6639b071, 0xc386126d,
- 0x3c3d56b4, 0x54d0b89d, 0x904296b8, 0xd6a84e2c, 0x4b4553c3, 0x85af9633,
- 0x0f41aef2, 0x9f09e1eb, 0x6b1dbcfa, 0xa06d8d41, 0xf904b847, 0x0b68ff9f,
- 0x95dcd75d, 0x73d99db2, 0xeb3aae5c, 0x871e51be, 0x3ce3dfa0, 0x010286af,
- 0xd367d5ed, 0xfb7f8525, 0x61af0e59, 0xcc7f5ce9, 0x1eecf927, 0x609c7f51,
- 0xeefb9c38, 0x448747d9, 0xdb282388, 0x2ef8feb9, 0xfd56e77f, 0xeef883ee,
- 0xc7ef1c73, 0x413294f5, 0xe4c19c9f, 0x17ed4140, 0xfee84bab, 0x1a2d3a0b,
- 0x6dcfd38c, 0xb8780dd8, 0xa8f1c1d0, 0x9e701d23, 0xbde678a6, 0xaa4d398f,
- 0x9357a17b, 0x4b2e8e97, 0x2cbcb065, 0x832abbf6, 0x5f5965e5, 0x45c8255b,
- 0x2d7d1f21, 0x6e3f394b, 0xb07a3e46, 0x0fd62565, 0x3cb078b7, 0xf38eb2d2,
- 0x7f6c36e3, 0xce51e5ab, 0x1f9cbd8f, 0x77bf833f, 0xf962d4b6, 0xcb1b8b6a,
- 0x33dce307, 0x3e226e00, 0xc6e8d539, 0x9b43d1bc, 0x5fe2040c, 0x980d3a17,
- 0xc44f4097, 0x40278f13, 0xef018dde, 0x6ff3a9f5, 0x9fbe7cd4, 0xb7df421e,
- 0x189e9c58, 0xfa033794, 0xf4c8c0e2, 0xcdd88c74, 0xedfe97c0, 0x0f9057f1,
- 0xcddbb31d, 0xa4b74fa0, 0x38bca277, 0x759bb4e6, 0xbc79eeb4, 0xedbbb593,
- 0xafad0366, 0xdac7df4a, 0x1473763d, 0x7c7eafad, 0x12f76b1f, 0xf83f220c,
- 0xc7c86bf8, 0x107489ca, 0x31a547ce, 0x17152c6b, 0x1f975e54, 0x3e317384,
- 0x3858de65, 0x3d725f17, 0xd57da27d, 0xca4fa841, 0xab85a2dd, 0xe1534edf,
- 0x9157181a, 0x7185ad50, 0xaf963363, 0x06e37181, 0x1e0dac3d, 0xc76f2137,
- 0xeadfa81a, 0xfd05a2d8, 0xc7ce4bf4, 0x2ea23cc4, 0x169f05da, 0x3ac360f9,
- 0x0a0f285d, 0x0f285c3a, 0xa62a5c04, 0x7e003f56, 0xc90ea6c7, 0xa63ac122,
- 0x71c1fd4a, 0x846ba5c8, 0xbf2922f7, 0x8efe98de, 0xd71d1579, 0xb11bf504,
- 0xa65593fe, 0x6f7f94ef, 0xdf230f4d, 0x0ef3f04e, 0xbbf21ef2, 0x3bd9e84f,
- 0x5c035f1d, 0x9b9ef04a, 0x24b5df19, 0xe3fa336e, 0x3d833641, 0xb69e7204,
- 0x1965e70f, 0x6453fb97, 0xcef876e7, 0xc3f9918b, 0xabfcfccb, 0x68444dee,
- 0x4f61fce7, 0x4bd985ba, 0x06875dfc, 0xd07e86d2, 0xa997e5ab, 0xf9d5a1f3,
- 0x59ff2216, 0x4f515f9d, 0xa1307bd8, 0xdeecce79, 0xb39e486e, 0x19a2abb0,
- 0x5e05ad3f, 0x78f8e943, 0x0957cf3a, 0xabc9c385, 0x3864e1c0, 0x87ec8438,
- 0x2eef3178, 0x74c6ff24, 0xdeacf11c, 0xb2277117, 0x3f8936f7, 0x5d04feec,
- 0x8dafee84, 0xe0cb5fc1, 0xb3bbf54f, 0xb9aae780, 0xab7e0266, 0xc7f3fe60,
- 0x351ff02b, 0xf8aefb5f, 0x0db9b4e5, 0x5080fdec, 0x1c39763e, 0xc2f7131f,
- 0x53d0a5d5, 0xe41a3ee1, 0x343bc201, 0x4befe760, 0x80674776, 0xf7d1567e,
- 0xd0ec0695, 0xf37ef604, 0x9cdb9b22, 0xe922e141, 0xc8817e59, 0xf1a33dc3,
- 0xb6f416fc, 0xc9e6cdb4, 0xb0832fa8, 0x4ac767a0, 0x7e3fe0eb, 0x878aead6,
- 0xafd72471, 0x3a077e0f, 0x7a699e52, 0xa17f9306, 0x5fe45125, 0xfaf96ef6,
- 0x8a2fde9a, 0x792a8f04, 0x41ee1fb4, 0x418b285c, 0x112dd9f9, 0xdb3fbc1f,
- 0x7a849e5d, 0xbd00f74b, 0xdaefca16, 0x301eee2e, 0xdb57e704, 0x65a9ddc7,
- 0x71ddf646, 0xd0eca013, 0x079d1fbb, 0x0691e0fe, 0xcdbc938c, 0xc7270ff3,
- 0xb7c3fcb0, 0xc980fdf9, 0x004a5e1f, 0xf65938f9, 0xa1481525, 0x1bf77676,
- 0x05ec2ab3, 0xdd36f6a1, 0xefd858ef, 0x976eecd5, 0x6006cbb1, 0xf5dfdb55,
- 0x9022bf2b, 0xe56a3de7, 0xe3f90225, 0xbc7b73ff, 0xa4f5132b, 0x9533e4ab,
- 0x415b79f5, 0x897318ff, 0x228e39e5, 0x9525ce2c, 0x9bf2c9bd, 0xdbb6a978,
- 0xbda868e7, 0xa76a1d9e, 0xa5fd92cf, 0xd421ef50, 0xd809cf5e, 0x374ec2eb,
- 0x45bf9610, 0x3806f7ed, 0xddb9e717, 0x8f13314e, 0x7c3f2179, 0xc87dce6f,
- 0x9f30a217, 0x8f8ef9e3, 0x7fad6112, 0xc5fc4ae9, 0xbd00f62b, 0x22be5937,
- 0xf5fa79c1, 0xc120bf2b, 0x7375bcef, 0x8e9b773f, 0xffaa43dd, 0x8a728ca7,
- 0x8075b5ca, 0x9af27aa7, 0x7920eefe, 0xabffda4b, 0x28c3de1f, 0x3586abff,
- 0xb4f5bc81, 0x7ed2764c, 0x223edcd5, 0xac76f91e, 0x32927b73, 0x289ed646,
- 0xeacbbffa, 0x13ff4403, 0xbbf49d93, 0x9da2a9d5, 0xd78ebf8f, 0x6c76ee89,
- 0x0df312cf, 0x6b337565, 0x72f8cb6f, 0x8231e832, 0xe0cc6fbf, 0x47bf91f2,
- 0x63fdf944, 0xcc578919, 0x73b651bf, 0x1fde2079, 0xc4e1faaa, 0x6e70a398,
- 0xb5cc25db, 0x875fbfab, 0xb673fbfe, 0xf7e082f6, 0x8e9e454a, 0x798cd2ab,
- 0x0d2f0d53, 0x22740add, 0x81278f9b, 0xe3c5d2de, 0x09b255f1, 0x36172ee3,
- 0x491ebe30, 0xf2bc5bef, 0x42be0515, 0xc0fbf9da, 0xdfa49818, 0x6493ff3b,
- 0xa0f33ef6, 0xe80bcc2e, 0xde0c7ce0, 0xc37b847b, 0x212bff22, 0x5ec13887,
- 0x8a39784e, 0x71f953bd, 0xc5dbf217, 0x767f332f, 0x2803a6c3, 0x76cbe6df,
- 0xc89d27f4, 0xf00abf76, 0x0d7731e9, 0xcaf838c1, 0x3f5d7157, 0xdc785bb2,
- 0x182f2fab, 0xe143879e, 0xc0abfbff, 0x4afff7ff, 0xfc82eff8, 0xbb73e032,
- 0x4dbed0a3, 0x0ef5fad6, 0x649e6b88, 0xe79e5cef, 0xfaed2b70, 0xf815df10,
- 0xd3b30667, 0xdc583ae2, 0x8965e446, 0xc333feef, 0x1e74eccc, 0x79a8691f,
- 0x47c4346b, 0xc4c6fe04, 0x77f07690, 0x38383c53, 0x07801c1e, 0x9c40ef01,
- 0x0acb8e84, 0xb0aed79e, 0x23dc050f, 0x7d35639d, 0xe3ab7588, 0x0e997706,
- 0xef7e0096, 0x847986fa, 0xb0b4cfdf, 0xcc7eb4f9, 0xf011fc13, 0x1e00c4ca,
- 0xef940375, 0x46bc5180, 0x22b9280d, 0xffed95de, 0xc35778cb, 0xf3d65d4d,
- 0xf7fa9838, 0xff3403a1, 0xbffc70ab, 0xdd9d5fe6, 0x3ed15fbc, 0xd71be577,
- 0x7e157fe4, 0x1f957fd1, 0xf5ff9236, 0x16ee992f, 0x2fc9bba0, 0xfc40d12e,
- 0xffbdf6e6, 0x8b013bc8, 0x5e303bf7, 0xcbdf0f74, 0xf6ffa317, 0x9e947dfe,
- 0x7e6668be, 0x3ffb53a9, 0x43f3d9d7, 0x45f663e9, 0xe8833899, 0x77caf66a,
- 0x669f2074, 0x5c22cd53, 0xa70d6a7c, 0xa127cc27, 0x48d6a07c, 0xfcf40974,
- 0xf7b2d6d7, 0x10216ba5, 0xe7d2c363, 0xb593eda6, 0xc7ef07c4, 0x3eb49b56,
- 0x9487c603, 0xfc0d61f7, 0x686a597d, 0xcac5ee2a, 0x9ef3194e, 0x716328ee,
- 0x76a619a5, 0xfd38dfbc, 0xf7f3eac8, 0xe35dd9c1, 0xba796129, 0x9fd27ee2,
- 0x5e24df34, 0x37e406b4, 0x1e259ff8, 0xc3ae5c87, 0x5c7aa438, 0xfe7600ed,
- 0xcb12cb26, 0xf2c3d837, 0xa479c4d7, 0x28623bfb, 0xf0f37962, 0xb3756ace,
- 0x00b437ce, 0xa8fd8ff4, 0xad95347f, 0x353c002a, 0x303e958d, 0xc0f40414,
- 0xa25f95a6, 0xc7e6a37e, 0xfd5af2ea, 0x1cb7ef50, 0xfa117a41, 0x1f16a9e2,
- 0xa97ed5d6, 0x8c7e6359, 0x5f919c71, 0xd470bd32, 0x1189e725, 0x6f6f6ff6,
- 0xd84b3b09, 0x4e3b6a5d, 0x5ef10bf0, 0x0b00fb5c, 0x77c6bb93, 0x5a8ffbd8,
- 0x4034be56, 0x5f057729, 0xef767ca5, 0x4a5fe400, 0x87c41bfe, 0xc55ffdb1,
- 0xdf740387, 0x4dff00ec, 0x6f7b066d, 0xf5f74d5d, 0xaa7e4c29, 0x94ae5de9,
- 0xd3519f51, 0x3bf3a0bb, 0x7fd05b9d, 0xd2c60b37, 0x926acc75, 0xc9d59ef0,
- 0xd7bc1e97, 0xddd09748, 0xe29d33fe, 0x486fbc3d, 0xe072a1f7, 0xbe23b463,
- 0x5d201cb5, 0x33feecd1, 0xa84f47c3, 0xc0a0bd1c, 0xbd1ca84f, 0x5fc4aff0,
- 0xf9cffd98, 0xf0907276, 0xc8bb7f3c, 0x6b239ff3, 0x26dcf7d8, 0x790a0796,
- 0x765ebd68, 0x56696c2f, 0x4d7fbe1b, 0xe058b20d, 0xc9f6cb23, 0x778b3d64,
- 0xde835368, 0xbe26ea2b, 0xe0494777, 0x9bf9624f, 0xf7b3464b, 0x9a79d43e,
- 0x91b3ff22, 0xb4cbbb8f, 0x54788f4b, 0xe62443bd, 0xd443bf51, 0x67fc7a38,
- 0xf7e7ff18, 0x0fefd58b, 0xf9e4ca0d, 0x88a4459f, 0xccafc7c5, 0x5e407aa7,
- 0x7b8df906, 0xbda0b52e, 0xf4399793, 0x01193c3f, 0x8665177c, 0x99a5d7e8,
- 0x94b3d657, 0xfa62ffed, 0xf0dbcd90, 0x4a6f913d, 0xe72c861f, 0x38b75824,
- 0xf9e7fd27, 0x679e0315, 0xef713ef1, 0xbdf1e7f2, 0x09afde8f, 0xe6ae87c6,
- 0xcdd3199f, 0xf4dd03ae, 0x4cd5b7b1, 0x94ea3ef1, 0x2304fd07, 0xdef1bb8f,
- 0x9cb788dc, 0x0a4c8190, 0x5864ba0f, 0x841bd0b7, 0x0be0111e, 0xcf0b7efc,
- 0xfe56b8f7, 0xdc4bfff1, 0xe9b3dc43, 0x4e4af9d1, 0x13defc80, 0xef1df615,
- 0x2b9a99d5, 0x60f9ffbe, 0xe0357b9c, 0xbfe70a69, 0x2ad01de2, 0x7bdbbd99,
- 0x3f464ba1, 0xfd1f8ac5, 0xdb8fb7e1, 0xeb57e743, 0x2f964d67, 0xd247ae50,
- 0x2c349bd7, 0xd2a8beaf, 0x605af98e, 0x42df80ff, 0xfdd431f8, 0x7e2bd90f,
- 0xf776899e, 0xac272ee8, 0x9eb651e7, 0x5a6af848, 0xbf0a5ff9, 0x37efa449,
- 0xccb12bed, 0x7f1f3a0f, 0xfd0494cc, 0x06353e5b, 0x74ad7df0, 0x0ecd7ff1,
- 0x8f132c98, 0xbe70e544, 0x257a65e4, 0x2ce5fa61, 0x1ce585d2, 0x9ba587d2,
- 0xf9eabcb0, 0x42e581c4, 0x65d3cf7e, 0x0991bf77, 0x1f5d55fe, 0xfe7b53be,
- 0xe1e7bfa5, 0x8f37503b, 0xa95c836a, 0xad9fcaef, 0x0b7aafd6, 0x0d38fefb,
- 0xbfeec7f8, 0x0f51da67, 0xb377b6b8, 0xd3ce71bd, 0xddfc6199, 0xb32e59ff,
- 0xee97157b, 0x5a4def65, 0x363218d8, 0x2574fb11, 0x09f9e167, 0x2de4cdf0,
- 0x5c426f82, 0x0d03ff2b, 0x932fcb8b, 0x7505eff0, 0xc47835f8, 0x796517f2,
- 0x62efa865, 0x560df9ed, 0x717904af, 0xfb58a323, 0x5dfe2b72, 0x8fc4d9cf,
- 0x3c2e72e7, 0x3dc32b65, 0x0b963b09, 0x54d4fbf8, 0xe896cee3, 0x469d45f8,
- 0xfc4dcf96, 0x05bf6083, 0xb1849f60, 0xf206cb77, 0xe3367438, 0x542ac3f7,
- 0x0fce05fe, 0x3315ec1a, 0xe172d206, 0x48192740, 0xad987ee9, 0x20cffd6b,
- 0x86b7606f, 0xcfafbdc0, 0xe300fe46, 0x2fdc622b, 0xe83a15ec, 0xf2c482f7,
- 0x0cfb3d8e, 0xa4d4bde2, 0xcbbd3f60, 0xfd03195e, 0xa8b6146c, 0x2b80451f,
- 0x572abdfc, 0xe44c7b18, 0x1d030db1, 0x0485fd11, 0x417a25df, 0x819cf562,
- 0x4d7dbe3f, 0x3d30fa1e, 0xc2fe87a0, 0x7d80ceee, 0x6213d30c, 0x92fff582,
- 0xcd21afdf, 0x5f0f1099, 0x034184f2, 0x547bc67a, 0x833dc31c, 0x167b533f,
- 0x2ed4d3ca, 0xd42ff285, 0x03f2852e, 0xf942976a, 0xa14bb511, 0x10b1745c,
- 0xbe2224de, 0xd862ce81, 0xa83b888f, 0x903f9bd7, 0xbb06cdc9, 0x1d62867b,
- 0x8eb8f4fb, 0x3f5dac17, 0xc75d19fd, 0x6907bb0b, 0x244bbee0, 0xfbeef478,
- 0xfe95e65b, 0x7f888d3e, 0xf107dba8, 0xd2ec17ef, 0xe82fdca2, 0x0e2ec7f0,
- 0x503157ea, 0x77f3e38f, 0xf30b1c7f, 0xe1fa58f7, 0x56e894ea, 0xbd586b27,
- 0x845e57e2, 0x39dd836b, 0xcf4bf603, 0x4fd838f7, 0x7e1fc741, 0xe83af70a,
- 0xeda718fc, 0x8236fa95, 0x87dea67e, 0x5f62df7a, 0x61ebff74, 0xb3bb0bfc,
- 0xdf942761, 0xf65e7610, 0x437977b1, 0xf70abbf7, 0xafa1bb73, 0xdc2bee18,
- 0x9b0e597e, 0x2f60da27, 0xc57f7847, 0x38fed0f5, 0x812ba71c, 0xae7b6faf,
- 0xf111f3d5, 0x50f001ee, 0x4ba3c83b, 0x560fa0b1, 0xc76678f3, 0xe36f41ae,
- 0x322397fd, 0x385fbf81, 0x773ca6cc, 0x1278e13f, 0xbd3efe65, 0xc2f5f00b,
- 0xc1074fbe, 0x3f14a07b, 0xc9efe083, 0x60e068fe, 0xfe7dfe45, 0x031fafc8,
- 0xf1fda1fa, 0x274e15ef, 0x6e20aa5b, 0xffb8d33f, 0xb6696c10, 0x882a83e5,
- 0x914dcfdb, 0xcf39430e, 0xe20e359e, 0x79df22f5, 0x61f96e41, 0x3ab74a38,
- 0x2b8f51aa, 0x2412e607, 0x318d2a17, 0x216051fc, 0xf515e287, 0x8ae929f1,
- 0x39ed13fe, 0xb949f68a, 0xfbda2837, 0x8638a1ef, 0x06cf7e07, 0x4365f478,
- 0x83ee8d1c, 0xa7b57dfd, 0xca77cc64, 0x96fc7ddf, 0xf27d681b, 0x7be077d3,
- 0xf6f02f6f, 0xf12b3bc9, 0x52f59bef, 0x22a9ea78, 0xa1eca675, 0xc9833f8d,
- 0xfd42f654, 0xc30f27be, 0xd8dfd0bb, 0x2760885e, 0x97a611d4, 0xd417b246,
- 0x9be50276, 0x39be053f, 0x16a9a5ec, 0x617f0fc8, 0x2069d7e4, 0xe40fb697,
- 0xfb7066ef, 0xf4fd1221, 0xfec9139f, 0x29fdf076, 0xbf88fd35, 0xc9ca2d6f,
- 0xa13dd8c7, 0x3ed7ca6f, 0x7686be01, 0xafdb87b9, 0xcff954bc, 0x6f1de986,
- 0x9efe03df, 0x94dc32a3, 0xb5bfbfe8, 0x0e5ffe18, 0xb8593dd0, 0x04d481e5,
- 0xfa03ddfc, 0xa7f72370, 0xeb90367d, 0x1ffbf553, 0xb40e2d48, 0x281f1593,
- 0xa5fb93fa, 0x9afa8ab5, 0x437d652c, 0xf1e0daf9, 0xc5b1f491, 0xbbd3ce8f,
- 0x9f9ee1f3, 0x3aeff614, 0x8127aff6, 0x4b7d87f3, 0xba7edf90, 0xbdfe197f,
- 0x46ff7559, 0x01f81f3a, 0xb3904717, 0x974d4f82, 0xeac23bd9, 0xef8abff6,
- 0xefdbbe39, 0x8f6147bd, 0x332f5e79, 0x9c5efbf9, 0x13a0af5b, 0xf9eefb3b,
- 0xe8ff0f4d, 0xed2b882b, 0x79d57661, 0x051f932b, 0xc0d33ebb, 0x161e8bdf,
- 0xc0abe8cd, 0x3dc0d7e2, 0x7e06ff9a, 0x00334c2b, 0x0000334c, 0x00088b1f,
- 0x00000000, 0x18adff00, 0xf514707b, 0x7bdbdbf9, 0x79724b92, 0x71211240,
- 0xc220572f, 0x4849ac91, 0x92ea4903, 0xf03ea410, 0xa2a21900, 0x799e0fae,
- 0x2a93a84a, 0x028d361d, 0xd6d36d52, 0x4f4e2a2a, 0xd1954a2c, 0x2562bc34,
- 0x40569478, 0x2f2a7b1d, 0x419cca69, 0xee421923, 0x8cc38a8c, 0xbf7dfa1d,
- 0x5eddcddd, 0xc9a75502, 0xf6fbbf1f, 0xcfdef8f7, 0x05048af0, 0x571a0192,
- 0x02a62a26, 0xc8dc8280, 0x00b5fb71, 0xbb4c6176, 0x94e00b3d, 0x157004c9,
- 0xa5029fd0, 0x30276100, 0xf0efdd38, 0xbdbf423d, 0x225f1c91, 0x9e5eef7e,
- 0x77dc2323, 0x4055a560, 0x5dfd12f8, 0x361b5d17, 0x709563df, 0xd480197f,
- 0x0fb91ce1, 0x1d300ad0, 0xe7f015df, 0x32a3a458, 0xe784db92, 0xf716faee,
- 0x2412fc55, 0x828f9d20, 0x76048f4e, 0x15798f80, 0x0624279e, 0x8df3c49f,
- 0x22b07847, 0x3810033f, 0x8ec7077e, 0x004ab339, 0x814fd396, 0x815877be,
- 0xc005bf67, 0xefb42bef, 0xdf97cbcb, 0x6f084904, 0xf286f4b1, 0x4970fbd8,
- 0x90e30343, 0xaadced7e, 0x9d5bb7bf, 0x78c9feb4, 0xff1e01ae, 0xb5fbc782,
- 0xd7ef6410, 0x7b7dc0ed, 0xf5f97ecc, 0x0dfbd39f, 0x0af78cbb, 0xbef4c485,
- 0x0a03f4a9, 0xb3ecf12f, 0xb6adf089, 0xf9aaf8ab, 0xb1bc3f6f, 0x837af918,
- 0x69f86d17, 0x64c4df68, 0xd98fe2f0, 0x91aca428, 0x8cdc6c72, 0xe145a48f,
- 0x5cfc7dc1, 0x47379d3f, 0x1b4fe672, 0x44906f29, 0xb561c913, 0xbab7c54b,
- 0x80059be2, 0x9b7756f8, 0xe02bb801, 0x1083c8d9, 0xdba0a783, 0xa33bf3e6,
- 0x2a5d87f4, 0x5fdd058f, 0xaaf2cea7, 0x01d12b6b, 0x405e2aed, 0xa67a41bb,
- 0x47496071, 0x139f307c, 0xac72e1b7, 0xe492a33b, 0x80838c74, 0xb89ec850,
- 0x2df48ed5, 0xefa39f54, 0x1fc5484e, 0xc2667999, 0xcbd340b3, 0x2f77d2c2,
- 0x516f7872, 0x4889a2f7, 0x75df1c01, 0x1cd431ef, 0x0c3c152c, 0x2c5062df,
- 0x296397a4, 0xa466ecbe, 0xddcf1e73, 0x1c12f3ed, 0xff10e019, 0xae048ab1,
- 0x3fef638d, 0x7cebef42, 0xb2f8b31d, 0xb35f189b, 0x37a87d5d, 0x5fc29a4e,
- 0x8f29184a, 0xd0cd5ca8, 0x5797eba7, 0x59ec86dd, 0xd7e6afdf, 0x1d31bace,
- 0x5c04b8f5, 0x16fba436, 0x610c0d1e, 0xdfe6cb78, 0xe03126e6, 0x5f2819ef,
- 0xf44a982e, 0x2d0584fa, 0x68cfde02, 0xd39835f9, 0x5667e462, 0x8fd74efd,
- 0xf491cf2e, 0xf9abf8a8, 0x7c84a0f2, 0x98e76d0e, 0xaa88351d, 0x9f94369d,
- 0xc462c3fb, 0x45e410df, 0xefa9e90e, 0xe492703a, 0x03aeb1d8, 0xce8016cc,
- 0xad6c5d75, 0x7c033bb7, 0xd98fe33e, 0x838d09af, 0xc1a55bf8, 0x74775f8c,
- 0x1c7fca3f, 0x3032cbbc, 0xf802e70c, 0x13bf7d93, 0xbf359f90, 0x62d8f2f8,
- 0x794376a2, 0xb207f30a, 0xf4a3abb9, 0x9c015817, 0x5b647f48, 0xc32b7f82,
- 0xa27eaa23, 0xfeff6dd9, 0x719a2749, 0x0b1dffbf, 0x1583db33, 0x1cfe0f4f,
- 0x12db35e1, 0x53fb9c98, 0xfda2c941, 0x0afd93ad, 0x8a6e581e, 0xdc9334f4,
- 0x6dc5133b, 0xf3f9ffb8, 0x81dd5f93, 0x2757caf0, 0xf926448a, 0xdf845091,
- 0xefa011b3, 0x3dd8b33b, 0xcbbc5590, 0x5fe4ff34, 0x729bf69e, 0x4d397fda,
- 0xfeba3c24, 0x90ef3ece, 0x35f5e500, 0x685df204, 0xa538e782, 0xd70f84cf,
- 0xe69c769a, 0x36ad3ed0, 0x75e92779, 0x397fb3d5, 0x54fc865e, 0xd3f37cbd,
- 0x95be9033, 0x7a058d1f, 0x11d7aa27, 0xe42920f1, 0x51e038a5, 0x9f2680e3,
- 0xff0eedda, 0xa57131a7, 0x00c523be, 0xf9657637, 0x47898d3f, 0x18caa0b5,
- 0x1f98e7ee, 0x35fe69d5, 0x20df978d, 0x4843d47d, 0xb110938d, 0xf2155d92,
- 0x2171449c, 0xc98d84f2, 0x3ecede3f, 0x2ecc4c10, 0x53204ceb, 0x034c2f7c,
- 0xaff9267b, 0xfc2fcaac, 0x9bade4c4, 0x42fd3650, 0x93ffeeaa, 0xb58b4c16,
- 0x37869ecf, 0xdb373ec9, 0x380e7d98, 0x3c67f980, 0x290b7f9e, 0xfb32fcec,
- 0x861fcc57, 0x45cb4bf3, 0xc0c51730, 0xee28905e, 0x4509b615, 0xacdae00f,
- 0x964a65e9, 0xadfc442f, 0x9eedf8ea, 0xb73c98f7, 0xf08a783c, 0xfd32761e,
- 0xdcaa7bc1, 0xc4d41cc3, 0xf665a9e6, 0x7bff342f, 0x7dcfe0c1, 0x97c89ccf,
- 0xddbefdf1, 0xed01f353, 0xd83e5ef9, 0x67ca1cf7, 0xfa783130, 0x0f3b5c61,
- 0xf28e387f, 0x75bd3c62, 0xe01a5f2d, 0x478d4e01, 0x7e07c475, 0xbbeb913f,
- 0xe181f640, 0xde87c584, 0xfc98d34d, 0x326f79aa, 0x6fdc3fe9, 0x4e9e2fa4,
- 0x3e9d7dfd, 0x9cfd7dfd, 0xebeaadd9, 0x9f9835bc, 0xcc9fdf8a, 0xefac1811,
- 0xe60a4f9f, 0xbbe938a7, 0x8a973d4b, 0xd5bd8c70, 0x6fd44fd0, 0x37e31d8d,
- 0xc35357d2, 0xbec06d89, 0x713f142b, 0x5fb8c80d, 0x26a6f997, 0xd1d9f037,
- 0x766916ce, 0x6669e906, 0x82b73bca, 0xb48bd76a, 0x743b7df8, 0xe5fd0058,
- 0x67f5a9a4, 0x3a075c76, 0x63916f7e, 0xca72afe3, 0xf7ea6974, 0x254abf8f,
- 0x3f1c51e4, 0x3ab272ef, 0x339ba267, 0x90d973b3, 0x5f70e74d, 0x281da00c,
- 0x0db1369d, 0xdf7991e9, 0x57bc6e35, 0x93e40d67, 0x64f7e81f, 0x07df665e,
- 0x9196f7b8, 0xc81cc1be, 0x8a4ff567, 0x3bac3815, 0xa0c563c2, 0xbe50f284,
- 0xe2571606, 0x02d865e3, 0x47489d35, 0xfdd77d05, 0xb8a4ed11, 0xe9d4d4ca,
- 0xc65e251c, 0xbd3407c1, 0x9a99a715, 0x8ff1463a, 0xe91f68db, 0x5e0e836b,
- 0x7f355ff5, 0xc6726996, 0xd6c7cf84, 0x5c5a0d33, 0x15d9270f, 0xdb2fe91e,
- 0xb8407a87, 0x40381ccc, 0xb43d7a2b, 0x42673ea0, 0xcbaf7d40, 0x6729bf18,
- 0x78f9612c, 0x33238b2a, 0xe7aef535, 0x68f4809a, 0xeb857ca7, 0xd3c82e26,
- 0xb08813fa, 0x99970255, 0x5b3b1456, 0xad8f8367, 0xad89a073, 0xad9da173,
- 0x5b074037, 0x5b20826f, 0x0da04a61, 0xeb5ffc58, 0x0c3cc3ea, 0xa26e5d3f,
- 0x18bc5c7c, 0x87f3469a, 0x2ebc9ab5, 0xea8c0f2f, 0x1e5c3f25, 0x64ce4073,
- 0x2e4e5d74, 0x9d98f213, 0x91b172eb, 0x073de23d, 0xad6933f8, 0x877b1080,
- 0x99de925c, 0xe0998205, 0x5c18902a, 0x51e51dfd, 0xb2cd921a, 0x54b91477,
- 0x8f276e8d, 0x9171726a, 0xea8d8f0d, 0x605baf6b, 0xcc37aeb0, 0xff1499d0,
- 0x7213ea47, 0x84e2ce88, 0x0c052fca, 0x21f77e11, 0x6be3199f, 0xb3655171,
- 0xf74ee107, 0xe3199f49, 0x65597168, 0x6ac44591, 0xdf63f5b3, 0x4765846c,
- 0x1fa03e52, 0x3bc831d9, 0x87bc3e50, 0xfa54d287, 0x7ca7e39e, 0x101fe369,
- 0x07654fc9, 0xadd59040, 0x17e45568, 0xaeef357e, 0xba7aa971, 0x4b3f26d9,
- 0x0f6f587e, 0xc3c80924, 0x0cead69a, 0xac1b87ca, 0x8c9fbbea, 0x89bea615,
- 0x1e21b172, 0x2f94617b, 0x081c57dc, 0xb9a13887, 0x47a51dc5, 0xf01dffc7,
- 0x784af9fe, 0xafca650f, 0x09bf29b9, 0xc61beb22, 0xb3bb796b, 0x97c44cb3,
- 0xa3170e90, 0xa9389423, 0x26dc85b9, 0xde97b7cb, 0xf6aa270b, 0x7b6c97b6,
- 0x75ed747a, 0xd3ddbb4b, 0xb70f7e47, 0x8027b37e, 0x433f86ef, 0x5def78c4,
- 0xce8fbcb7, 0x39429a35, 0x5f97a845, 0x92b69c26, 0xcaf6e83d, 0x209692a1,
- 0xf8126ddf, 0xca0fccad, 0x9675c35d, 0xe1ef6a27, 0xca1ef8a5, 0xabe7d8a3,
- 0x4a0fb2c2, 0xd20e9a6a, 0x57b72a5a, 0x39e10ee1, 0xf236f442, 0xffa46591,
- 0xac8f94c1, 0x9c7f319f, 0x169ddaa0, 0x1ff7baa7, 0x0abc7879, 0xdfc620fa,
- 0xbc5ff71a, 0x8f8c2ff0, 0x914e438d, 0x7bed978e, 0x7dea99a6, 0xcab0cfdd,
- 0xdd11c433, 0xd97666ef, 0x773b3c02, 0x5f3a52cd, 0x878f51f1, 0x3d75efe2,
- 0x832a36a1, 0xc627ddc3, 0xd7aff6ab, 0x3f70dfe9, 0x6e7c4f24, 0xa6487b47,
- 0xa7ca8b3c, 0xef37683e, 0xab7f21b7, 0x60d07ea9, 0xf6abf185, 0x58ff7a95,
- 0x561fe47f, 0x19f03bea, 0xa95df885, 0xcb62bfd1, 0x5d91377d, 0xfb1bf4ad,
- 0x6cafbd41, 0xf6d5ced4, 0x1f13d7f8, 0xe78ddbb5, 0xccafa91a, 0xeb0cfaa7,
- 0x75d50f31, 0xaa5bfb71, 0xd8d95f58, 0x1ffefc65, 0x2495f637, 0x81bf2d60,
- 0xd72e4756, 0x4e7f10ce, 0xfd59e7d6, 0xf56de436, 0x8ba2cdf3, 0xc8a76ce0,
- 0xf5d1ebe2, 0xb61e7b10, 0xd15b31a4, 0x46e575fd, 0xc3c7d58e, 0x364bdffd,
- 0x7828e889, 0xbdd58329, 0x7ab3af58, 0xd9881d03, 0x86ca016b, 0x3d7bfb43,
- 0x426b9225, 0xe777af3c, 0xff4f5489, 0x67049d75, 0xf4fa512c, 0xdf9abe7a,
- 0x3ea56551, 0x93ec7ee9, 0xef210ec8, 0x37bc72e9, 0xfc05b0fd, 0xaa043fb8,
- 0x9ace863e, 0xf33e5d58, 0xe49e4ec8, 0xfd518fcf, 0x026996d9, 0x0e1e4621,
- 0xa3080c61, 0x4d36f5f4, 0xa979097f, 0xf144fd86, 0xe4fdc32a, 0x7ec35cd2,
- 0x2b69239b, 0x0a4501e1, 0x8e284b7a, 0x48a4efab, 0x20f70c53, 0x5fb8ff84,
- 0x437189ae, 0x64c39cd2, 0x15ce15cf, 0x3690de6c, 0x9e78d0b7, 0x5f13cb5f,
- 0x87b833b6, 0x657f957c, 0xe675e836, 0x7e9e1180, 0x10921db4, 0x39a8e3af,
- 0x00a16e6e, 0xc13625d5, 0xd5ca5df8, 0x4c0262ec, 0x861bcc30, 0x961ceee5,
- 0x0945d92b, 0xf720c8fc, 0x1ea1b978, 0x3434dd58, 0x422a29c1, 0x7d630f54,
- 0xd467f946, 0x259fe518, 0x7e3de51b, 0xd9de5185, 0x5f79464d, 0xab9462dd,
- 0xcdca315b, 0xe1a671b3, 0x4af6c4fc, 0xf3793c03, 0xd7f3860d, 0xe01817f8,
- 0x376fdba9, 0x71d69f9c, 0xa0bf61af, 0x5f61956b, 0xd9cbb3b7, 0xd581b5c1,
- 0x0266f671, 0xa0ec15d3, 0x0643f0e8, 0xff7af17c, 0x12aaf831, 0x47a5ce51,
- 0x48c2de51, 0x1484703b, 0x6f1878a0, 0x57faf107, 0xaadff4e2, 0x93f793e5,
- 0xee4e3ece, 0x8f412f3a, 0xa0bcda7f, 0xb1fac2dc, 0x55690a7f, 0xcb567489,
- 0xaf2d3e6b, 0x644df6c1, 0xa973e024, 0x0f1418b0, 0x3c2b1c52, 0xbb22abe9,
- 0x1d350e2c, 0xe4a0f644, 0x32557b6c, 0x7040979d, 0x4b47538d, 0x5296fe74,
- 0x72b1cc0e, 0x8f366742, 0xa171ca8b, 0xe327cad2, 0xfd6fb2e1, 0x54ecc96d,
- 0xcfa7c33a, 0x3552b87d, 0x1c97cc6f, 0x47918e60, 0x4f9ea945, 0x5d5e8cbc,
- 0x089cfaee, 0x52b07deb, 0xfbb26fbd, 0xd5a3dcdb, 0x9e66e237, 0xab325fd5,
- 0x32710ec7, 0x6add1f9b, 0x7d90e60f, 0x5f90c99f, 0x317cc5c9, 0x56051268,
- 0x36a171bf, 0x8c4c2a62, 0x6e52f251, 0x9f512f9b, 0xcd2aed86, 0x8bf21727,
- 0x465e2be7, 0xa2542bbe, 0xb7f4c5b6, 0x99de5727, 0x739e794b, 0xbbc22fad,
- 0x973ccfef, 0x9fcc7943, 0xf7a2ed2c, 0x1921e787, 0xd9c617c8, 0x48504990,
- 0x1c43ca04, 0xd1ce2feb, 0xfc623323, 0xe585a376, 0xadfad02b, 0xe939353b,
- 0x0d12d6fd, 0xb13e2f6f, 0x9df8e302, 0x3c98875d, 0xb407336a, 0x7449ad3e,
- 0x4df7fbe1, 0xbf521670, 0xa8915209, 0xff7ae9f6, 0x3eff9e35, 0x57ef5579,
- 0x36be772f, 0x07d0dfb3, 0x51b48ec3, 0xf3f18de7, 0xeadf28ac, 0x258fbdfb,
- 0xfbd3fcb0, 0x1f9b3658, 0x641fdf46, 0x9b3b8173, 0xc7d8303e, 0x1b1f2ddd,
- 0xe51eeeec, 0x287ec313, 0x8f19623d, 0x64f687fc, 0xe503b9cd, 0xadb77e77,
- 0xd450fa84, 0x4c6e7f57, 0x627a1c9f, 0xf7c26cf2, 0xc73cf9bf, 0x1759e8e8,
- 0x9d34f364, 0x4eebd3cf, 0x2eb43832, 0x3e78d6c4, 0x5f55bef5, 0x3c837fad,
- 0xc227ea33, 0x9b47118d, 0xd479d4c3, 0xd667beba, 0xc3ca4ab8, 0xb356d93d,
- 0xe1524eba, 0x0abb52ac, 0x6b4b99cf, 0x48dce2d8, 0x070f6b7d, 0xd0f68712,
- 0x9785d57b, 0x7744f8ac, 0x50f56c86, 0xb9195a5d, 0x482b7340, 0xe379b10f,
- 0x41d954d2, 0x062c39df, 0x9d1952b3, 0x383fa893, 0x035e526b, 0x2f25018c,
- 0xf53e71fe, 0xaa498301, 0xf8be27dd, 0xe9057cdc, 0x97c5257e, 0x0a40f74c,
- 0x94e76359, 0xfa859cfa, 0xc253ea62, 0xf0cd750e, 0xcc8f8c70, 0x478a75b8,
- 0xd3d7578d, 0x9af5ef8a, 0xe47126da, 0x80dacf0f, 0x07e8a7e6, 0x4317d512,
- 0x1faa6cfb, 0x70920198, 0xdb6eccff, 0xe3cf640b, 0x5faa6690, 0x7d635ab0,
- 0xb65be141, 0x7d09c500, 0x11ee933e, 0xfbc5e57e, 0x6c2d7be9, 0x2898300e,
- 0xd77f9094, 0xf5601d27, 0x595c89d7, 0x15f9b0f2, 0x7a3f1448, 0x6eb6d8f7,
- 0x3991e752, 0xafff120b, 0x0f12b873, 0x6a4233eb, 0xe1cda95d, 0xf9abbe74,
- 0x43df19c7, 0x7c406d9b, 0x7c1a5f9e, 0x4ee6cbca, 0xd9d10e62, 0xd6e9526b,
- 0xd3f9d5e9, 0x73be88f9, 0xe7d5bb65, 0xd779d149, 0x07e44986, 0xce754728,
- 0x2f7773c7, 0x7dfee518, 0x7cb2beba, 0x558f88f3, 0x2dbcea4d, 0x07f6f7aa,
- 0x8ede914f, 0xbb1c5938, 0x3e78fddc, 0x611ff7eb, 0xef3e40f2, 0xf862fe22,
- 0x9989e25c, 0x3eef9e0b, 0xf85794f1, 0xb385fce1, 0xf878f9d5, 0x02398b85,
- 0x77dfafde, 0xc9d924e8, 0x6e3c1cf0, 0x831b6d8e, 0x68ea657d, 0x0acc6bf3,
- 0x4d92f531, 0x6cc13fbf, 0x9f218fbc, 0xfc8bacfc, 0x5d89eb11, 0xf9421f5a,
- 0x9eb6e292, 0xb1d9772f, 0xe2df454f, 0xb8b36f42, 0x8ec9784d, 0xcb0a73d7,
- 0xa15cfa5b, 0x44bcc38d, 0x599b963a, 0x76afe73c, 0xbba7648a, 0xd482f6d0,
- 0x04a59ad7, 0xeb8e3f36, 0xe4dbd76f, 0xd65ec947, 0x4199507c, 0x3be76ffd,
- 0x957d6837, 0x6ba64f9a, 0xf09d39f6, 0x64de1f13, 0x358a5796, 0x4dec4afa,
- 0x3321d53c, 0xf9d5e140, 0x788f3681, 0x8fd66dec, 0x775717fd, 0x1c70ea99,
- 0x00001c70
+ 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, 0x33a98f8a, 0x32e8f430,
- 0x31e8a430, 0x43d4dc30, 0xcf12d388, 0xbf4ca2e1, 0x83030b30, 0x038b1028,
- 0x7f1024b1, 0xf8606463, 0x7ebc48ce, 0xbb04115e, 0x81818045, 0x070fc80f,
- 0x1905ffd2, 0x330b3e18, 0xf903f030, 0x6dfc80b3, 0x88087c40, 0x376280c3,
- 0x2067f480, 0x02c40fbe, 0x17cdf822, 0x417f2024, 0x07ff9508, 0x1042ff8d,
- 0x61637ebf, 0x0496f2fc, 0x4de1b1e4, 0x0f8cdc04, 0xef40a77f, 0x6a87e040,
- 0x557d7ca8, 0xa02b0606, 0x843a8758, 0x7e4908ff, 0x40cc5016, 0x93e6c215,
- 0x05506067, 0x61ab1ff2, 0x281f9737, 0x5f9406af, 0x00073506, 0x15e5ac6f,
- 0x00000368
+ 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, 0x7dedff00, 0x45147809, 0xf4f570da, 0x73264cf4,
- 0x10909264, 0xa70930ae, 0xe15c380a, 0x1084ca30, 0xa8ea2416, 0x1388a888,
- 0x2e421081, 0xf57175d1, 0x11c3a7fb, 0x9e375941, 0x1d47facb, 0xa22cdc10,
- 0x60188806, 0xb200c1c0, 0x1761bb8a, 0xc363d715, 0x01921a0d, 0xe5c58f15,
- 0xeaadf7ab, 0x44ceee99, 0xeff3eba2, 0xe3fdfb7e, 0x575453e3, 0xef555bf5,
- 0x5dbd6f5d, 0x71024a31, 0x02e426f6, 0xf211c6fc, 0x4908488c, 0xe36d9689,
- 0x1749c7c3, 0x92cde442, 0x8840ad6b, 0x343dbaf0, 0xfb21046e, 0x33010956,
- 0x587687ad, 0xd3f5a109, 0xcc07d735, 0xd43eb419, 0x9afac1ec, 0xbee7ac1c,
- 0x48c3aefa, 0x8aafa5eb, 0x761ba846, 0xdb34729c, 0x37372908, 0x7d05723d,
- 0x24557e1e, 0xc450e9ab, 0xb240c535, 0x471e3908, 0xad196fd8, 0x685212a7,
- 0x55d2d561, 0x3cc2673b, 0xc4cc1a8a, 0x6e94e142, 0x15ed7b99, 0xaf773eb4,
- 0xe94ba044, 0x77534ada, 0x10179f5a, 0x68bea0ea, 0x4e3887c7, 0x545278db,
- 0x4f908837, 0x35c471fd, 0x4d1dd680, 0xe7d137a9, 0x130d81c5, 0x7af17fa1,
- 0xfda06dc1, 0x7e766b8b, 0xeb8bf004, 0x8522bea5, 0x4ad6bf3f, 0xd8d9035c,
- 0x63ac0817, 0xdf30b5ce, 0xc4483fd2, 0xe745eb4c, 0xc01136ef, 0xe4dab191,
- 0x8ff8c3b5, 0x18765c9a, 0x51c716a7, 0x7bfa59f0, 0xaf7d0e3a, 0x0dc165ec,
- 0x10332b4b, 0x75a7cc1f, 0xf3fa658b, 0xa5575836, 0xbfbc3fa9, 0xf41341e5,
- 0xd8281b9b, 0xfcc1716c, 0xc2269956, 0x99566b3c, 0xe145070a, 0x517dafcd,
- 0x2be3af33, 0xa9f574fb, 0xa7e5f5da, 0x735a8a7e, 0x884c5eb4, 0xf306cea7,
- 0x1fae980e, 0x547e7d1c, 0xcf7a4448, 0x2b8915af, 0x529f0a2e, 0xefcb9f1e,
- 0x1f027fd2, 0xd607b76c, 0xb5e94466, 0x8eff09c0, 0x93acebd2, 0xce18cfd3,
- 0xca57c352, 0x740e8047, 0x277ed53e, 0xd3f98f96, 0xefc27cb0, 0xe53dbc42,
- 0x4ae5881f, 0x3f9f1bbf, 0x658d1fed, 0xe583df8d, 0x5849feb3, 0xec5efc06,
- 0x1d3fdab7, 0x1f7e35cb, 0x5fc17f3e, 0xbfad6584, 0xf3af9f02, 0xbd72c42f,
- 0x2fe7c65f, 0x596197fb, 0x72c6afe7, 0x96257fa3, 0xf600fef5, 0xd7e9ccdb,
- 0xe7c3afe0, 0x580dfd5b, 0x2c21fd06, 0x62f7f877, 0xd5e382b9, 0x8c724d91,
- 0x0f0e2f14, 0x20715271, 0x1c9ef949, 0xbc93d689, 0x433a9eac, 0x7ad131ce,
- 0x29d68faa, 0x8497ba9e, 0xdeb4cc72, 0xa7b582bd, 0xc7c6403f, 0xccba7ad1,
- 0x785733da, 0x3d685bc6, 0xf7b59ab3, 0xc7c791af, 0x00ff7ad3, 0x7d74bf6b,
- 0xd695bc68, 0xed63ad2f, 0xd7248243, 0x4243eb46, 0x9f6c3eac, 0xeb4ed727,
- 0x3d589ac3, 0xd73923eb, 0xcd59eb41, 0x2db1fdec, 0x5a04dca1, 0xed661b1f,
- 0x166f9d57, 0x67f8315d, 0x459be4b3, 0xf2032d28, 0x1bb18f14, 0x777c9bad,
- 0x97c53713, 0x1c63d53c, 0xc923f143, 0xbe4bbed8, 0x4c1bdb1d, 0x27bfb632,
- 0x56fb6217, 0x27ed8029, 0xdf6c72e5, 0xfb600a6a, 0xac42f2b7, 0xb610a507,
- 0xb12b2adb, 0xc214d07f, 0x87caf4f6, 0xd4877db0, 0xcaeeed8c, 0x877db1c7,
- 0x1fdb19a9, 0x99e3525b, 0x0b0feb40, 0x2f81a7be, 0x22be0b17, 0xadf807d2,
- 0xf94bcd2e, 0xd3204aad, 0x0117bf81, 0xaaf6d253, 0x47d4266e, 0x7ace3f9b,
- 0x6f38145e, 0xe17a8176, 0x20650f0b, 0x8e11e79c, 0x1788e144, 0xc9f59387,
- 0xac9c0d68, 0x38148a4f, 0xa58e11eb, 0x7f367073, 0x9f3b5632, 0x38158a4f,
- 0x149192af, 0xeb73bd8e, 0xb65bfaca, 0x2b7f3e76, 0xc0ece051, 0x6e7624f9,
- 0xb4c70d3e, 0x163869f8, 0x389bcfc1, 0xcdce949f, 0x2d71f467, 0x8f1f467e,
- 0xe109a7e0, 0x9c1ceb74, 0xfc5ae386, 0xe08f1c34, 0xd38403e7, 0x1aeb73ab,
- 0x9f8b427d, 0xf82227d1, 0xc9f88c39, 0xad9c1ce8, 0xd9f8b5a7, 0x9f823a7a,
- 0xbf4e10cf, 0x6c6badce, 0x633f16ab, 0xf9f8235b, 0x4975d702, 0x6d6ce0e7,
- 0x6b67e2d5, 0xdf3f046b, 0x9dc19c21, 0x36d8d75b, 0xb6c67e2d, 0x1263f045,
- 0xced0ce00, 0xa5f827cd, 0x2fc13f16, 0x4049f823, 0x373b2338, 0x5a73ec9f,
- 0x8b9f64fc, 0xe10d27e0, 0x9c1ce98c, 0x7e2d39e0, 0xf822e782, 0x573840c9,
- 0xd95d6e76, 0x93f1695f, 0x3f0455fd, 0xf7400a97, 0x421f3e1c, 0x863bd8e1,
- 0x2d3be3b3, 0x177c767e, 0x9c70cfc1, 0xcf9f1e4f, 0xf55ce045, 0xae7e2d0f,
- 0x3f0447fa, 0x726708d9, 0xf8ece0e7, 0x3b3f1687, 0x4fc111fe, 0x9aebae1e,
- 0xaaebadce, 0x5cfc5a0b, 0x67e18175, 0xdcbad1d4, 0x6d4eda04, 0xafa45ba3,
- 0xf1ef3b8c, 0x3a2eb408, 0xba745d59, 0xa22df809, 0x26908fe2, 0xb7df488f,
- 0xf61c4fad, 0x25fb5110, 0x75826fe3, 0xa697a9d9, 0x46124bf6, 0xa0fc6bc7,
- 0xa6924f44, 0xbba93c9e, 0x378a7fa6, 0x75ded353, 0xf69aa5fa, 0x9a61be6e,
- 0xb1a28f7a, 0x2abdfe9a, 0xbdea6bc6, 0xe9ad5e17, 0xa0df219f, 0x7659f7a9,
- 0xbf7fa6ab, 0xed353bea, 0x6b165603, 0x2c092fda, 0xab2fd4d0, 0xffa6a5fd,
- 0x9a45bae0, 0x1e1bcbf6, 0x0d0fb4d2, 0x0fa9a63d, 0xa6b4fbdf, 0xd5a6c8ff,
- 0x0751f69a, 0xc7da69d7, 0xd4d46f34, 0x55b938af, 0xf0caffd3, 0xb8fa9a1b,
- 0xf4d2dfaf, 0x1e7394a7, 0x45d78cbf, 0xfb820b90, 0x099bb902, 0xdd90c5fd,
- 0x77537584, 0xd827db1b, 0x29475d0b, 0x9f064ddd, 0x812d0bab, 0xfdda84e6,
- 0x0345ee9c, 0xdc5f299a, 0xc037d63b, 0x6bdf9f49, 0x8cee5df2, 0x7e509fe1,
- 0x941a4811, 0xfa94032e, 0xc62507f6, 0x9c7be3af, 0xbe887fef, 0xf7086e5f,
- 0xbff5a44f, 0xc002721b, 0xd4082fdf, 0x157ca7eb, 0xe80a922f, 0x1e266f17,
- 0x3307dfe0, 0x55979eb2, 0x17acbcfc, 0x0a215395, 0x4be49977, 0x5d643f03,
- 0xf832bbe5, 0xe8bd5529, 0xf213baba, 0x486ef0a2, 0xefdf4bee, 0xa3e69855,
- 0xea26ccf0, 0x37c7abe7, 0xe107f1d1, 0xcfc075f8, 0x94fc619b, 0x339be3f6,
- 0x8fc66b47, 0x8cd22f4b, 0xe3a2671f, 0xafbea93b, 0x4f8f98fc, 0x90963289,
- 0x38c7c26d, 0x08bd39be, 0x44d07fc7, 0xf1ea3df7, 0x87e323e3, 0x3a7bfd60,
- 0x58e67f5a, 0x8bd3faed, 0xb137ebb5, 0x7955bff5, 0x8f1f8f8c, 0x385b7feb,
- 0x5e9fd6c6, 0x666fd6cc, 0x3be32370, 0x826ff822, 0xd1d7bff5, 0x6b64fbfa,
- 0x44bbdfd7, 0x1b337ebb, 0xa795afff, 0x1c36f8f9, 0x34e143ff, 0x12ef7f5b,
- 0xf664df1c, 0x4c7f81b9, 0x022be23d, 0x93d27c74, 0xc0aeae2a, 0x281c742e,
- 0xa6512607, 0x2149e427, 0x6f71e713, 0x73b7e33c, 0x50df94f1, 0x9cf8c91f,
- 0xa3e6a804, 0xce329cfb, 0xe7d7f3fb, 0x616f4098, 0xccefdd3b, 0xdd9d53e1,
- 0x937f2220, 0x7e81cc27, 0x0dadbe74, 0xd9f50ca2, 0x00195c4f, 0x266e58fd,
- 0x3de17877, 0xf3c10923, 0x5e0e4f63, 0xbe975ead, 0x1d2d539c, 0x17c8d66f,
- 0x9e3c8f9b, 0xf3a0ac0c, 0x182603cb, 0xa71fad19, 0x98d829fb, 0x12fba61e,
- 0x74484f28, 0x28fcfa3c, 0x01916fdd, 0xc4a9b96a, 0x79ec88f7, 0xff9d2fb7,
- 0x3cfca234, 0x51dbceb8, 0x233c28a4, 0x1af1ffc3, 0x98f40021, 0xf9f74d53,
- 0x372ff92a, 0x170ef933, 0x02d58108, 0xff7d2bc7, 0x813efe66, 0x33f851f9,
- 0x8f9dec9d, 0x47b35c77, 0xedfdd070, 0x9c0d64ca, 0x6960485b, 0xb6ff7d1a,
- 0x62253b15, 0xe828be00, 0xe5f800b5, 0x7084897e, 0x429cda9f, 0xa0667106,
- 0x064e7df0, 0xd2e9e6ff, 0x9c1566d1, 0xc79c5299, 0xf333e74b, 0x7be7113e,
- 0xdedb4f8b, 0x31eac3bc, 0xcae5a10c, 0x494225cf, 0xb6915b7e, 0x6d0af6fd,
- 0xda858efd, 0xee0f5d3a, 0xfd640bf3, 0xba1cba73, 0xeb233bce, 0xf5a70ba6,
- 0xd66dbc59, 0xd0d64932, 0x4d736e91, 0x133dbc59, 0x4f104ed0, 0xf69f7ef8,
- 0x681f29fd, 0xea5773ea, 0xf8be71e0, 0xdffff4ff, 0x86f2ff4d, 0x5547c59c,
- 0x9bad2af3, 0xaaa8f8bc, 0xebdafcdf, 0x8179f535, 0xe7fd345b, 0xb4d02cae,
- 0xa79ea9cf, 0xecb59f69, 0x40bd4d2e, 0xffd34fbe, 0x9a95858e, 0x962bdbf6,
- 0x2b6fda6b, 0xbf53547a, 0x4d5bf7c5, 0xafa79bff, 0x3b0bb4d2, 0x466ef5e6,
- 0xddebe9bb, 0xf4fe928d, 0x7c026607, 0xc2b3f0a6, 0x69fd27ef, 0x77ea7e58,
- 0x7a095961, 0xc377ea98, 0xaf965616, 0xfa0de82e, 0x13ffe15c, 0xe83a4552,
- 0xeb3f3d4b, 0x4f9eaff5, 0x2c47afe9, 0x4b29433f, 0x3b05e204, 0x64fdc6d6,
- 0xdc37f9e5, 0x0ce782ce, 0xc9898965, 0x6ec6c965, 0xea0389e3, 0xb615fea1,
- 0x3a92e18e, 0x2041d701, 0x74029a4a, 0x976d41eb, 0x347dae9a, 0x29d96cf3,
- 0x2065f8e2, 0xdcc06393, 0x60187778, 0xfa6350fc, 0x3e61838d, 0xdeb1d79e,
- 0x56fe8290, 0xe2d27f8b, 0x7f00fda3, 0xfa4f2c5e, 0xdc7963a7, 0xa8f2c3ef,
- 0xc3cb08bf, 0x9b2c0afe, 0xfcb10bfd, 0xf9632fc4, 0x96197f91, 0x6357f57f,
- 0x12bfd079, 0x01fcf7cb, 0x1efd5b2c, 0xfd3e152c, 0x18eba14f, 0xae9cbfc3,
- 0x3ae9a8df, 0xf364e0c6, 0x187d74e1, 0x6fc31be6, 0xc8ce0fee, 0xe23f9548,
- 0xdb718c99, 0x4ece3c05, 0xc71624c8, 0xa62f63e5, 0x6fd09ae0, 0x3d040c09,
- 0xb7e0767c, 0x7d4e21fd, 0x4a2520f6, 0xd3ebc746, 0x3c43afd3, 0xeffa0f10,
- 0x974a0185, 0x96edf6e4, 0x8b578678, 0xc3224c81, 0xefde5908, 0x839df705,
- 0x49246eb0, 0x7dc07ef0, 0x5c063dbd, 0x7e020bea, 0xc5d7862f, 0x004373f6,
- 0xffa7f1de, 0x18e5059e, 0xe307f303, 0x4bf4451b, 0x3779e849, 0x67a237e0,
- 0x8834eecd, 0x99fb86f7, 0x9af7689c, 0x4fe2d6ae, 0xbf835abe, 0x55fc11e5,
- 0xfafe21a7, 0xc28ffb9e, 0x8784f11f, 0x8a3830dc, 0xef846fbf, 0x1e729fc7,
- 0x36ef1fa3, 0xf883f8d1, 0xc1552db2, 0xa13a536b, 0xf811fce3, 0x5b3fc29f,
- 0xf001203f, 0x1173811c, 0x7faf08fa, 0xe8fa0e9c, 0x16c9d034, 0x0e9f7785,
- 0xcfbdd9de, 0x5fefc03b, 0x47ca2690, 0x2959e063, 0x6432eb4b, 0x6a4fda9b,
- 0x56cfd6d0, 0xd0ea930b, 0x4c25719f, 0xd7fa0c1d, 0x40951f29, 0xa961a64f,
- 0x669059c0, 0x7d2871c2, 0x4faf5c98, 0xd4ffb944, 0x7efd871f, 0x047479ea,
- 0x7a8f3a27, 0x0fbe8472, 0x4fa17f2c, 0xe43bfdc7, 0x2617e353, 0xa091b388,
- 0x97fc0e74, 0x05fffa38, 0x46237838, 0xcb702bac, 0x7cd944eb, 0xaf5f3c39,
- 0xe7be8f19, 0x2f06ce52, 0x3c9f7e64, 0x8571c918, 0xa8a9a95f, 0x48d61881,
- 0xac8b5be0, 0x35128ff5, 0x6e86f2f5, 0x825fc6b2, 0x4a3d507f, 0xf023048a,
- 0x9f67094b, 0x996da336, 0x0bf7e740, 0x3e816208, 0xd2bf5810, 0xcf9366b8,
- 0x78b2fc05, 0xe82e15da, 0xd5eb8d59, 0x2fd28fcf, 0x3c7528c3, 0xd9e2f9ff,
- 0xe431bd7b, 0xdbd72763, 0x57160625, 0x03b27120, 0x9a48d7ce, 0x8ec1b8ec,
- 0xf045b353, 0x3a3b7183, 0x0a0f0a8e, 0x2901799c, 0x995ff5ac, 0x5818b65c,
- 0xee3f40bc, 0x94dc619f, 0x6cafe38b, 0xb089fefd, 0xcb1e3d6e, 0x7c98ce1a,
- 0xbff45728, 0x151e28ac, 0xf442fefc, 0xeba459fe, 0x843dae2a, 0x9293eafb,
- 0xeffeffdc, 0xe7ed8bd1, 0x6e3b4b6f, 0x265bad55, 0x9dce304d, 0xc440f9a3,
- 0x5487f375, 0x5b7a9f5f, 0x5d010f22, 0xaa5ed3ce, 0x828f5079, 0xfea2b218,
- 0xf3f59dfa, 0x9f7ec1f3, 0xf7053cda, 0xd789b32b, 0x22ca4101, 0xfe059d52,
- 0x986269f9, 0x4d3a7804, 0xae18ecfe, 0xd139d3a2, 0xfea1f484, 0xfcf561fb,
- 0xa9aeffa8, 0x535dff53, 0xa437242f, 0xe178f9c2, 0x08091213, 0xfb4d3eb8,
- 0x7089d171, 0x2a8a92e7, 0x4b1677f0, 0xe9dfaecc, 0x541ec624, 0xf6be979f,
- 0xad01564c, 0x7f32277f, 0x9def3944, 0x377b7547, 0xb75c5eda, 0xeda1e4ca,
- 0x4f87ea47, 0xfbc082bb, 0x3fb02a81, 0x7b82abf2, 0x7e3dabad, 0xf5fce87f,
- 0xa1fc55f3, 0x7ccee776, 0x82b5a51e, 0xcf831027, 0x67c646ac, 0x30f63f0a,
- 0x8df1353a, 0x70faba01, 0xae9c7d5d, 0xbde5a3fe, 0xfbc8d10b, 0x00df442f,
- 0x6f930a63, 0xc609dfd8, 0x8ff3f230, 0x0ed69f86, 0x149ff0fe, 0x9cad4f7e,
- 0x7ee3f851, 0xdb7df852, 0x2c4a7fcd, 0xbdafa5f8, 0xfaa659b4, 0x2795f8a9,
- 0xa7ea841d, 0x54eac653, 0xc97fa537, 0xe00ea5da, 0xd9469383, 0x2a7cfc01,
- 0xc40a4e20, 0x8c8b77d0, 0x3daff702, 0x6fe20136, 0xff0a4ff0, 0x5f0f75d3,
- 0x7387710b, 0xc627256b, 0x21cd6ad5, 0xb2d39533, 0x64f979fa, 0xb10fd608,
- 0x446783fa, 0xf96837a8, 0x4f77f8b3, 0x5f50baa6, 0x180c3dca, 0xffa10e3f,
- 0xd8e6b65f, 0xe5fbb044, 0xa6728c24, 0xffc60f7f, 0x53ed093a, 0x7da12981,
- 0x53e46e3b, 0x2bf67de1, 0x8cf87faf, 0xf27280e8, 0x7427d009, 0x03f184e7,
- 0xdc457bfd, 0x68dbbf9f, 0xf3f182ef, 0xe8146451, 0x242f0531, 0xf179fcc0,
- 0x408667b5, 0xcd65b51c, 0x85410edb, 0xcede452f, 0x6e7acdd6, 0xbd63abab,
- 0x51e54ad9, 0x7e2a47ed, 0xef81ab85, 0x2cac8243, 0xc80e4291, 0x255929ab,
- 0xb8fa65b9, 0x5fe7a5e4, 0x9ae21a78, 0xfddd981f, 0x2ff9fc28, 0x2c6f7eed,
- 0x20dfcfad, 0xcb67c975, 0x51a909b0, 0xffd394fa, 0xd28b0e17, 0x6ed378a3,
- 0x7b306b93, 0x945240fe, 0xec37f32e, 0xedc19134, 0xb75b91f1, 0x8b6cd4d3,
- 0x43ba9f41, 0x130fc113, 0x04cefb5f, 0x43b53ff4, 0x62335d20, 0x6ed573e0,
- 0x4f00d3f4, 0xaf4e4f48, 0xfd74fd08, 0x405d29cb, 0xa5e9ebaf, 0xf41537ef,
- 0x0b830a4b, 0xbf9412f9, 0xf90ade5f, 0xbb357f48, 0x2f450f01, 0xf580eddf,
- 0x3056309c, 0x69667f3e, 0x5f8e87aa, 0x4ea9c924, 0xa2f3d92c, 0xfc8e7f67,
- 0xcfff7737, 0xcb5c5953, 0xb680cdd3, 0xeb06ee4a, 0x1373539c, 0xf890b3ae,
- 0x9e8b0f90, 0x2fa0bd11, 0x499234bf, 0xc9c8621b, 0x4e4e5cb7, 0xa5c4a6ac,
- 0xcd413ceb, 0xfce9e610, 0xc5ac0c59, 0x185dfa38, 0x5f39fb37, 0xb0e8f50b,
- 0xa31c65fe, 0xc0d19357, 0xeaf52ef5, 0xe6bbfcd5, 0xd3a026c1, 0x5d3cbda7,
- 0x9ca5fce1, 0x0f8e6518, 0x2b8502e1, 0xcaebcfee, 0xc65c44e8, 0xf51efe2c,
- 0x39e172cb, 0x3c926ff4, 0xf79a2196, 0xe88c85c8, 0xf1f0f7f8, 0xc1e3bce9,
- 0x1a913a9f, 0x40305f7b, 0xb502ec52, 0x533e2aeb, 0xff933bc9, 0xbc99cb35,
- 0xb81ff22b, 0x7fb4127e, 0x11c98071, 0x92f607bc, 0x15d42bce, 0x154e77db,
- 0x49983f50, 0xaf9c9628, 0x6b9cb891, 0x42fcf5db, 0x12146fe7, 0xe3037c54,
- 0xd01d2124, 0x827c2a9f, 0xa3d2afbe, 0xa3ae30e5, 0x8e455c3d, 0xf07d72e7,
- 0x6b03e825, 0x1a901f54, 0xf63a07a6, 0x53c4657b, 0xe1781489, 0x2a5f9069,
- 0xe40bb2af, 0xfac2f257, 0xf8df5b3f, 0x6e54adde, 0xe453ab3e, 0xf557ab56,
- 0xf1b45b72, 0x54f804e7, 0xf59fb72f, 0xe53120ac, 0x298f3e96, 0xff9b3db7,
- 0xc1557a25, 0xd5a4ba63, 0xec9e8aab, 0x3d7a9f08, 0x42e8c5b9, 0x24f5eabc,
- 0x59201dfd, 0xe151f9ed, 0x8aff8543, 0x0ded2c5f, 0xa7c228fa, 0xf8461f0a,
- 0xfd43e154, 0xd478b5ba, 0x9e7c63b7, 0xcb778bf2, 0x507b13bb, 0x050496ba,
- 0xef85d9b7, 0xc53a81ed, 0x0b6d8797, 0xe8f4f7aa, 0x7407aea2, 0x7f5d3af5,
- 0xd5eeae8f, 0xeae9f7f5, 0x01feba15, 0x68694fb6, 0x87e41134, 0xb4bfa690,
- 0x9f90c888, 0xe22ede16, 0x9d1b41b9, 0xbf7d1573, 0x40467d6d, 0xa961faa6,
- 0xc3dbed85, 0xd02aa629, 0xb0ce6d67, 0x16ea0923, 0xf36b7f16, 0x2a891d86,
- 0x5050f1ff, 0x1cdc7d44, 0xed629320, 0x8bc7a85f, 0x1d266bf4, 0x90f3b3b5,
- 0x10c778b6, 0xb44f2f18, 0xf8842fa5, 0x86e8b54c, 0x95d98e23, 0x5ce03b37,
- 0xe7d82da2, 0xf9f4e9ba, 0x2c883f9c, 0x18f6422d, 0x0df6a9bb, 0x54fc8927,
- 0x95f900b6, 0xb3fe902b, 0x311f6c82, 0x7e6c457b, 0x15efe62e, 0x8131eeda,
- 0xfffea4de, 0x5f5c7561, 0xa3545381, 0xc29c1e7b, 0x2fed9ef9, 0xdb68d78b,
- 0xfa3f7c7d, 0x0fdf0a5f, 0x7ed94325, 0x0838b090, 0xe279bbd7, 0x53a6eba0,
- 0x15edb43a, 0xd9cdf009, 0x387488a0, 0x40085ebb, 0x29c88a5c, 0x24653f28,
- 0xc14efa8c, 0xc7c80b57, 0x50f58e80, 0x671fabcb, 0x94bb4fdd, 0xc870fe6c,
- 0xcb65a5ff, 0x6ffa0fe6, 0xef6bfa83, 0xda487fa7, 0x61ddcff7, 0xb6df73c1,
- 0x27cc761d, 0x4efedb6e, 0xdf50fdfa, 0x3cc37662, 0x357c76db, 0x6da8f804,
- 0xf408b991, 0xb62f5b58, 0xfdbc59ff, 0x68cd21ab, 0xfd20973f, 0x8b13256a,
- 0xfeff04d7, 0x4a05d089, 0x0ff02aba, 0xf9727e78, 0x20804b56, 0x7cb2affc,
- 0x3d6e9fb6, 0xbf9cfc65, 0x6fa64ecd, 0xb225f984, 0x6df2ec73, 0xa4af9e63,
- 0xefd697e3, 0xeda2cd34, 0x377fafb9, 0x3791f304, 0x55a7bf32, 0xce167e6a,
- 0x6f4937b1, 0x9e28922e, 0xba38415b, 0x299d7213, 0xc5b6572e, 0x1877cbc2,
- 0x3e2cea97, 0x7ed892de, 0x1f1fdff4, 0x9511e602, 0x3881ed04, 0xcdfdd601,
- 0x3e821f27, 0xbe4661d8, 0x59fbd654, 0x23fa255d, 0xa9f75b17, 0xd07c31ff,
- 0xa10b75d9, 0xce3bacce, 0xeebdeff4, 0xce172447, 0xed072f4f, 0xbdfb7cf9,
- 0xeec97f58, 0x9276f9c6, 0xfe9a07df, 0x237df8c3, 0xe2e3bba5, 0xbfd9feeb,
- 0xa63bbaf9, 0x72661ffb, 0x1f213bba, 0xeff5fcac, 0x543f7e70, 0x1ffdcdcf,
- 0xbf8af7ca, 0x9b78366e, 0xa6fce872, 0x383b6a93, 0x9ca4b716, 0x73a907dd,
- 0x745f5ee6, 0xfc4af981, 0xbf3f51fc, 0xefb62695, 0x997ce093, 0x126e4b8e,
- 0xed8f7ef8, 0xfee5ae93, 0x0b3db5c5, 0xd6bd2fd1, 0x6277fcc3, 0x46737af4,
- 0x6cd89e40, 0xc943c637, 0xa83e83b0, 0xaf2574df, 0x7f8bf76b, 0xa0478814,
- 0xe9b5f9fe, 0x9f82f693, 0x634f5d7a, 0x43caccc8, 0xe0ebbe50, 0xf76b47cf,
- 0xb4f8b733, 0x6ba79bf5, 0x787137eb, 0xa2b9c0d3, 0x0af34fe3, 0x4a7f8801,
- 0x81489ebd, 0x4734a878, 0xf9008222, 0x614b1524, 0x579370df, 0xb03dfefb,
- 0xc5191dcf, 0x82b8bce3, 0x114e70f9, 0x7c405037, 0x4442b75c, 0x4837127d,
- 0xd1def840, 0x1e1de612, 0x00b37833, 0x47c3f9cf, 0x8192fd95, 0xe77ac373,
- 0x92157c71, 0xc877f40a, 0xb2170bf9, 0x4bee20b3, 0xe79a5fd0, 0xea1ae421,
- 0x0b6617b7, 0x63c878a1, 0x61391231, 0x0543c418, 0x0f135872, 0x77e1d6d5,
- 0xce146a55, 0xc477fac5, 0xf9753f8f, 0x87ffca37, 0x433fea25, 0x2cf3e789,
- 0xb3eca7ae, 0x3c3208ee, 0x81089796, 0x90abe44c, 0xb0cf3ea4, 0xfdff1999,
- 0x28e181ed, 0x1ebf3957, 0x7ff6c09c, 0xa0bbf023, 0x9e67ee72, 0x10095d95,
- 0xec1b38f7, 0x72d1cfc3, 0xfc18be1d, 0xbbef9fbc, 0x007902fe, 0x209b6cb4,
- 0xffe08b54, 0xfbc63093, 0xb21609e4, 0x5cbe4636, 0x8739498b, 0x207dc0af,
- 0xa02cc4fc, 0xa5cdfb23, 0xa92426af, 0x9ae2b6e8, 0xed21c653, 0xc3bf00e9,
- 0x7e4bce31, 0x3cfb096c, 0x4b7eebc0, 0x8c6f44f3, 0xcb83fef5, 0xdf1bfe6f,
- 0x376377e0, 0xc0243304, 0x44130dcb, 0x39eaf9cd, 0x87e3f713, 0xaf30e193,
- 0x3b2637fc, 0xf65d00c6, 0x4ef86e8a, 0xc6783cac, 0xce718be4, 0xc027c7a4,
- 0xc90073c7, 0x3cf8085d, 0x810b2bf2, 0xfc3bd6fd, 0xe41067dc, 0xadc20f61,
- 0x4ce207bd, 0x0b8b3366, 0x713b30cd, 0xe7e6379e, 0xdc742948, 0xa1cef541,
- 0x9dd5f470, 0x46019ff7, 0x5124246b, 0x7e94f7b0, 0xbf584bdd, 0x59672643,
- 0x113ff5ac, 0x733ae2c7, 0xd1defb89, 0xdd1fbfc2, 0x0f6d7e72, 0x327b078d,
- 0xd8e77d81, 0xca09af9e, 0x4249d9c7, 0xec3df400, 0x2f9eb09f, 0xc779bda0,
- 0x1be5dac0, 0xf8565e98, 0x11e78f5e, 0xf8cacf1c, 0x0c7d7953, 0xcf052f97,
- 0xf3f57e0a, 0x7d53fa55, 0x8f1d4e35, 0xe861aeb8, 0xcb0f60cb, 0x40d38282,
- 0x9b199541, 0xe587204d, 0x104a8f0d, 0xc5c5bf8f, 0x307b52e0, 0x3bfe7d44,
- 0xe1ceccc3, 0x315d871b, 0xf3e4f813, 0xa12fd415, 0x9f667bef, 0x7ddd8071,
- 0x13fee0c7, 0xff29077c, 0xbf6b2451, 0xe87d5f47, 0x904f1677, 0x703370d4,
- 0xe496379e, 0xb93e1048, 0xd4a764ad, 0x334fc555, 0xaed849cc, 0xe25eef3c,
- 0xe9cf061a, 0xf90f3878, 0x3c813311, 0x4d7541f2, 0x6ddbfdf8, 0x0f8c8915,
- 0x9a76ea8b, 0xfd819eb0, 0x7194f195, 0x3534f2f4, 0x341f9b5f, 0x27b9b72b,
- 0x1cdf25e0, 0x831dc7ba, 0x95982f4f, 0x681f8873, 0x6f943c27, 0xb22ffc87,
- 0x7628f713, 0xaaf259a2, 0x34de49f2, 0xd9573933, 0xecb1ae89, 0x574a82c4,
- 0x82c3a057, 0x82ba7ded, 0x43f82c90, 0x3b2c6a5e, 0x9d9faef1, 0xbfcfbe2b,
- 0x4a9b6d23, 0x2ae5c4ed, 0x82d5313b, 0x6f7fa27c, 0x7693b983, 0xffdba142,
- 0x2ef37d63, 0xf21889d8, 0x4fe38bbd, 0x82d313b1, 0xa6276805, 0xdf35154d,
- 0xf3336c5f, 0x76877178, 0x16f52722, 0x6b6e4bac, 0x9779fe0c, 0xf3efc3fb,
- 0x07183c3c, 0x5cb7c5ec, 0x46edebff, 0x371d7a47, 0xa13b2335, 0x7845ffd7,
- 0x02faf456, 0x339b2fea, 0x4121f162, 0x0b705e7e, 0xf002ebd5, 0x0bebd323,
- 0x3171e76e, 0x82f59e9d, 0xd6a11d9e, 0x32fdecb3, 0xe50bb31f, 0x99bf190d,
- 0xad6fdb41, 0xb471dc96, 0xbd51adff, 0xbbd6a59b, 0x77a476df, 0xfdde988b,
- 0xfd1c383c, 0xf7d68ea7, 0x54b7d731, 0xc775f59f, 0x33e98fe0, 0x77ef9aac,
- 0x737d0c8e, 0x979026d0, 0xd73c4477, 0x80fdc63b, 0x1cdf437d, 0xe9eaf101,
- 0xbbe44671, 0xad9e9cbe, 0x813c527e, 0x36772fe2, 0xd74ba7f3, 0xb2bf888b,
- 0x65ff267a, 0x45c042b5, 0x7d8713eb, 0xfcfa8263, 0x8e7ceced, 0x473f20ae,
- 0xeff9ff45, 0x3c415734, 0x012afe78, 0x1f2117cf, 0x9739f01a, 0x3dd0b3e3,
- 0xfa2bf71f, 0xf1e5833c, 0x72e4d58e, 0xd3f18784, 0xdf3fde52, 0x72f8c61c,
- 0xf704effe, 0x1f3ed22a, 0xd5efb4a1, 0x319f60a7, 0xdcf756bf, 0x11cf1cbd,
- 0x718b5fa8, 0x6d3ad2d4, 0x4ff71e7b, 0x41a188e6, 0xf57f609b, 0xcb1dd127,
- 0x22fd29de, 0x27fa29f8, 0xe29fb3f1, 0x874fc467, 0x9dc1799f, 0xa1fe5f18,
- 0xe3e3d178, 0xbf5c7167, 0x4023230c, 0x3c198f1e, 0xb7e45fa8, 0x9923cc44,
- 0xcd3f68fd, 0x7137043d, 0xe0c779be, 0x5f3c82ab, 0x9be58cb9, 0xb0d9adcc,
- 0x67d6953b, 0x10a191d4, 0x52bb9e96, 0xf6238f6b, 0xfcc5debf, 0x020d8a82,
- 0xe1ce15e4, 0x051509df, 0x1b7bc51e, 0xed485f6e, 0x6b3fed3d, 0xe707d998,
- 0x612dfba3, 0xff0a9fd4, 0xf263892e, 0xe3cf88b4, 0x04f0f748, 0x820d53b4,
- 0x6432e513, 0xd28b7661, 0x6893ee09, 0x44d5f31c, 0x8f16174e, 0x2c746068,
- 0xb90374a7, 0xf5e4189e, 0xde0fe63a, 0xcec33c16, 0x253b82b5, 0x40852f76,
- 0xb9df5192, 0xd8acff71, 0xcb673847, 0x77d15549, 0xffc621fb, 0x3e37056b,
- 0xfeffd008, 0x4076fa19, 0xe99fc557, 0x3c157d2c, 0x79d1d12d, 0x7f29a5bf,
- 0x08d79e38, 0x23a7bc6e, 0x0be78898, 0xbdd9ab47, 0xfe718f13, 0xec05cbd7,
- 0x60f7d43f, 0x87130f5c, 0x1649d37c, 0x71c3ebcc, 0xa67f9933, 0xd6508efd,
- 0xd0fd01e4, 0xd272953c, 0x34597e84, 0x34e7ccbf, 0x249fdd83, 0x5f79b518,
- 0x9ffb9461, 0xdfdbfe00, 0xc5a49f07, 0xdbb97da1, 0xf6369ec9, 0xf4191132,
- 0xf90932fb, 0xeb8366e8, 0x2fd06cbd, 0xe404490f, 0x237df3e3, 0x05d19fdf,
- 0x8fe445da, 0x97867782, 0x80a48841, 0x829126e5, 0x3a5d98fb, 0x2bffc7c2,
- 0x019ed7b5, 0x83f0487c, 0xf80189fd, 0x7baa6cae, 0xe20b9e67, 0x2ff62326,
- 0x1bb1f385, 0xbdef9d73, 0xce5c7407, 0xbc395bee, 0x69f7172c, 0xa025df77,
- 0xf4a41d9c, 0x4d373802, 0x3def78cd, 0x97dbbf3a, 0xd739e0a5, 0x34ca4f0c,
- 0xb19af738, 0x68bb744f, 0xd9d759bf, 0x364e706d, 0x7c48a065, 0x4edcbc2a,
- 0x334e309a, 0x9baee2a3, 0xa88a4e40, 0x547b843d, 0xf3fb828a, 0x46bd42ba,
- 0x65cbf7c0, 0x9d2ba99f, 0x33cad35f, 0xfc7411a6, 0xd00fda42, 0xfac35e5d,
- 0xdc11af95, 0x185baa90, 0x64f5147c, 0x2f011ae1, 0xfea268aa, 0x1b831c6f,
- 0x9b70a388, 0xb4fbe86a, 0x07de173e, 0xa7126bb8, 0x395679c1, 0x3fbe279d,
- 0x25cf12ba, 0xb47be90b, 0xb9ad3499, 0xabcde10b, 0x6f7c0811, 0xe33a3454,
- 0x6f00d191, 0xf686e49f, 0x16fe77f7, 0xd2664af3, 0xf851baf1, 0x3ce6c4b3,
- 0x2fddab8c, 0x93bef138, 0xee517dd9, 0x91dcb8da, 0xb9d87d81, 0xef9440b4,
- 0xfcea8c7e, 0x96164184, 0xb0b85d07, 0xd5d60ab2, 0x1864a72c, 0x98ce9f90,
- 0xa51f8ec0, 0xff51f6f8, 0xe58988f5, 0x47ca343d, 0xfd2acd4c, 0x07d2d939,
- 0x437671e5, 0x3999ea0e, 0xe7e78bc4, 0x8fe64abe, 0x096a5a1c, 0x4987e008,
- 0xde7874ce, 0xcf8cd4b8, 0x76625f5b, 0x3357b5a7, 0xd44f43c6, 0x87be0448,
- 0xe7d35c5a, 0x89e3a029, 0x139e12f5, 0xa848cf8b, 0xc4bee6cf, 0x358d64e2,
- 0x5a89ee0c, 0x9f72dfa6, 0xe82269b9, 0x956bb9ed, 0x1ead6573, 0xa315742b,
- 0xc2c67a9e, 0x5f5e92f4, 0x5154f5e9, 0x76d8aaf5, 0xb1899ee8, 0x2acf50ed,
- 0xc0ecaf16, 0x9b13973e, 0x4186a7a2, 0x6941495e, 0x812b99af, 0x89676f9f,
- 0x2da14dde, 0x76093e5f, 0xf78ec4b7, 0x9d199503, 0x3f8c094f, 0x19ffe808,
- 0x825f0dc1, 0xb0cd143c, 0xc73ffde0, 0x47201e81, 0xdcf1922b, 0x805030b3,
- 0x2ef25778, 0xf2d4aee7, 0x7dce72bb, 0x1e244f8b, 0xb22afdb5, 0xdfaa8f12,
- 0xf945fffb, 0x47738e96, 0x08b01083, 0xe7b43f50, 0xeeb023e7, 0xe42d79c4,
- 0x3b0ac1fe, 0xf7fbf5f2, 0x7c0a599d, 0x8101f33b, 0x644edf80, 0xc3d8155f,
- 0x0b8295b2, 0x1f73b3e2, 0xa5cfef60, 0xdfbcc3ef, 0x2fe32dff, 0x902ee7ca,
- 0x479ab283, 0x35ff60f7, 0xbfe00b82, 0xfd00aabf, 0x24592289, 0x10e6bed8,
- 0xbda823ee, 0x46a3fcc2, 0x39054c59, 0x76625b28, 0xc2b779c2, 0x1e7f0a4f,
- 0x9351dfe2, 0x1b90f738, 0x00e77be9, 0x14be0c48, 0x7b110ba7, 0x2e53fc0a,
- 0xf43b7e33, 0x1106e492, 0xb27f38b9, 0xfe1567ef, 0x46ff8113, 0xb1aff944,
- 0xfc04d726, 0xe0202278, 0xf02e7cb9, 0xefe7f02f, 0xb10cf895, 0x8ba8fda9,
- 0x0f9ea7f1, 0xe51ff1db, 0x0af3d03b, 0xa8fc2a7f, 0x46c3c3e7, 0x7de60d32,
- 0xae0b52f7, 0xcb6ab723, 0xce4c85b4, 0xb7273cf0, 0x9054beea, 0xcb2342eb,
- 0x5af050fb, 0x4279646a, 0x44f5e6ed, 0x675ba9a5, 0x479ba7e6, 0x2a3d8b37,
- 0x63cb220f, 0xde71d109, 0xe63cff5c, 0x775e9dd3, 0x6ff45ae8, 0x003e51b6,
- 0x93b7affc, 0x0243ee10, 0xeb8a8fa8, 0x1be60f45, 0x3759431a, 0x4aeff6aa,
- 0x57fcc4fe, 0xe2ef88ec, 0x3e40e68d, 0xf378bf7d, 0x8e782191, 0xdff988bd,
- 0xfd013af2, 0x0f372263, 0x8a3def81, 0x438f2c8d, 0x613c17ef, 0x96f0fb61,
- 0xe0e9d62d, 0xecb509b7, 0xbae2af5e, 0x2ab3259b, 0x45b0fbbe, 0xb9e1fa52,
- 0x0ce94c8a, 0xfcc355df, 0x294af7d4, 0xbf2d1bf9, 0xdc57fc67, 0x573fa120,
- 0x15a1bb5c, 0x0f8af3f2, 0x5bbf719a, 0xf3067b5e, 0x795f738f, 0xd63fdd89,
- 0xb2f26a20, 0xd543e5da, 0x51ce788a, 0x798a5f56, 0xe78eb41c, 0x3c75651d,
- 0xe607e8ff, 0x657fcceb, 0xa29966fb, 0xdfa6fe70, 0xb09ef039, 0xfc0eb5a6,
- 0xfbf6a54e, 0xe5db13f3, 0xe72dd53f, 0x9cd74ff9, 0x631fa820, 0x0a7d3fe7,
- 0x947b80ff, 0x27fcda2c, 0x1bf4cb52, 0xac56679d, 0x7e2213ef, 0x3e5f4bd7,
- 0x2dbbf90b, 0x167b3f1b, 0x8ff25de6, 0xbc859fcf, 0x09d00a0c, 0xbaf94a7e,
- 0x51df3177, 0x85a0ef79, 0xff7e83ef, 0x6d17cc3b, 0x06ecc0fd, 0x4fdbad68,
- 0xd1ff83a4, 0x549be1ba, 0x67bd03c8, 0x77c61e7b, 0xb73579ee, 0x6f15892b,
- 0x6ff025e3, 0xaaf913a0, 0xd635ba7a, 0xc8fe6237, 0xd0774a69, 0xb6bc9113,
- 0x2f9652ba, 0x6cf9e2e8, 0x07e763eb, 0xab5fcbb7, 0x2bbaf1bf, 0x33d63f41,
- 0x79a2e13f, 0x3d28076c, 0x1d04ef2f, 0xc57cf3d7, 0x37be6bba, 0xfc34ed8f,
- 0x2bebd283, 0xf01f368b, 0xcf39facb, 0xf56d0d3d, 0xb1e61dc9, 0x3f813a85,
- 0xd1b8ff25, 0x83c431e2, 0x117c6d1c, 0x7e8107f3, 0xd7d02ef9, 0xbc43a65f,
- 0xc614a4f8, 0xbb7844b8, 0x2b7bbf19, 0xca3efede, 0xfbabeb53, 0xf097bf31,
- 0x1256e03c, 0x4d7cb1f9, 0x5f2a031e, 0x6ff96763, 0x1f900e9c, 0x73e072e7,
- 0xf8c7079e, 0xeb8fc95a, 0x6c6e2f28, 0xe38b267c, 0xd2e8bcf1, 0x3cf21f35,
- 0x84dd28b3, 0x43af40d1, 0xa8779bdf, 0x7809c1e0, 0xfbcea518, 0x18879d8c,
- 0xd1d4fbc9, 0x7a09e80d, 0x49d7923c, 0xbf213deb, 0x1fbc202f, 0x75b88f2b,
- 0x6d17cb15, 0x93dfb495, 0xf2c4e946, 0xebc64740, 0xb9d036e4, 0xad8bcffc,
- 0xa9e287e3, 0xc34bbc5f, 0x5abe0a37, 0xefd6c7ce, 0x7f85e3d3, 0xd9ab7bee,
- 0x82fbfe82, 0xfbe1e39b, 0x2643fa82, 0xf18bdf82, 0xddf2957d, 0xb5b78f12,
- 0x7f3113ac, 0x11aeaab0, 0x7f5ebbf5, 0x1473f194, 0xe38b7cfd, 0x6b2ade99,
- 0x65a3f660, 0xa3603da3, 0xd8de5a70, 0xb65d7c82, 0xf20990fe, 0x6ed4f6b1,
- 0x03bcb132, 0x3f604726, 0xb7f9aa02, 0x0873bcbc, 0x9f7e73ea, 0x859c7e91,
- 0x60f29c7c, 0xd7ca71ec, 0x338cd19f, 0x3933ae5f, 0xef1f176d, 0x66e7a353,
- 0x1369f780, 0xad3ea3f3, 0xfac52713, 0x78b6e6be, 0xababef89, 0x3b50fc99,
- 0xd93af78a, 0xa24e3dd9, 0xb2fd1e23, 0x0fa3ec7b, 0xf780fdc2, 0x47984dd8,
- 0xe792b8b1, 0x3b97fc5d, 0xd8bde80d, 0xf981357e, 0xaafc052e, 0xd392f7f6,
- 0x939fc047, 0xd423bcd2, 0xfcca30e7, 0x240c5d4d, 0xb7bf3ea0, 0xfb0aea4f,
- 0x7b946253, 0xcdae3cc2, 0x7608cafc, 0xe2cfc9b1, 0x91fce4fb, 0xc9bcf0be,
- 0x4c9ddce8, 0x104d36e1, 0x6d9a10dc, 0x7e0cf7cf, 0xd1e0ce24, 0x39095fde,
- 0xb3beb0f8, 0x89fa036e, 0x49c84376, 0xa5bb10bb, 0xb8370d29, 0xa632e22e,
- 0xe63cea62, 0x8fe43faf, 0xe7df0beb, 0x5b750839, 0xa8db9fa1, 0x61216fb9,
- 0xff7751b4, 0x97d03902, 0xe71b1fda, 0x675e2557, 0x70a6ff67, 0x875ef19b,
- 0x12a441c4, 0xdd8577d8, 0xe3c4fe87, 0x5f7e0f0e, 0x21037f46, 0xc48921df,
- 0xc1f7d5bb, 0xf73571d0, 0x3571d04c, 0xb68f44f5, 0x78c93c9e, 0x49bd9634,
- 0x2898f3e6, 0x890f10da, 0x2fee0679, 0xa5fbf27b, 0x989de746, 0x6821dc42,
- 0x7986c6bf, 0x64bc54e3, 0x366c3af5, 0xfce9bced, 0x61227a34, 0x606cb350,
- 0x773cd4f3, 0xeb809712, 0xd39f68f7, 0x7fea6af9, 0xcdf6e789, 0xefa08c48,
- 0x844d716c, 0x06acffe3, 0xde8c4bdf, 0x4cc254a4, 0x4e93cc26, 0x483fbe13,
- 0xe3a0ebe0, 0x213bfa6b, 0xd7c6c07a, 0x9d3d21c2, 0x2f06efea, 0xc6b076e7,
- 0xfa0a3dea, 0x0577ab26, 0xa766fa26, 0xc3a39e09, 0x0bb05b69, 0x85cca7ea,
- 0xad08e4b9, 0xaf8cd50b, 0x2820aefa, 0x2cc37d37, 0x892c858f, 0x1cd53f47,
- 0x30cb6447, 0xc88a1ef8, 0x251830d2, 0x5c9fcfc0, 0x94140c8b, 0x35e51971,
- 0x3c305efa, 0x128730de, 0x289a0ea1, 0x9ef143fc, 0xaafc61cf, 0x86697deb,
- 0x793cb0a1, 0x946caee9, 0x62204bda, 0xeff4a868, 0x4b257bde, 0x9f7b81f9,
- 0x0ddfec88, 0xa95ab876, 0xdf0ec553, 0x47c7576b, 0xaa389eea, 0x5933abef,
- 0xbfd8785d, 0x424f5974, 0x0af04b1e, 0x7107d056, 0x3cf14bce, 0xeb84942c,
- 0x517d98bf, 0x4d7039e6, 0x11f8c4f3, 0xf70a9e2c, 0x47b3f68a, 0x7b46c7be,
- 0xd4a6d6bc, 0xf0bfb843, 0xbd47efd6, 0x1fb75a56, 0xa7500ddb, 0xe6e4ef65,
- 0x29123d89, 0x79d5ac56, 0x5f809769, 0xa066905b, 0x5ac4bceb, 0xc1a8dbbd,
- 0x3c1a13c3, 0xa63d1718, 0x3f63c3c3, 0x3c970f08, 0xa1e218fc, 0x7ca6ebb3,
- 0xe94ad031, 0x80c72537, 0x3a8d37f7, 0x0bf8c368, 0x1ed059fd, 0x3aab3871,
- 0xd9568ef8, 0x6e3850a7, 0x97f0a380, 0x57c29ef2, 0x1f4df11d, 0xdd94bce2,
- 0x9fe5a7eb, 0x0c67ab02, 0xf56b1bc0, 0xe0a5b31c, 0xeebbf1fa, 0xef02be29,
- 0x5f28e484, 0x386f9b13, 0x635c277c, 0x55bc73bd, 0x929daf15, 0xa4cc40b3,
- 0x5905cdf3, 0x4f5d1918, 0xd2d942ca, 0xc533ae9f, 0xec3cc063, 0x126fab1a,
- 0x1e98e38c, 0x48f5510e, 0x70df005d, 0xa38e8c41, 0x76d547c8, 0x2aaf8fb6,
- 0xb1160430, 0xe00160f3, 0x59a3f945, 0xc6611fc7, 0x90870d1f, 0x8782ca3f,
- 0x54347f18, 0xe7e78f8e, 0xae8fb06a, 0x40a1e126, 0x57d699f7, 0x28bd8cf2,
- 0x55c358df, 0x485f283d, 0xfcbcfaf2, 0x33af104b, 0xcf87d262, 0x4757594b,
- 0x9bdeadf4, 0xd820f0f9, 0xe033ee67, 0x37829879, 0x2b62dfa5, 0x661cb3cb,
- 0xfc03cdf7, 0xde6e8f95, 0xb8dbe403, 0xd798cff7, 0xc377d8e1, 0x31df784e,
- 0x15c85295, 0xdf7ab71d, 0xb7bfbc22, 0x4003ae9a, 0x0cb09026, 0x7c63bd76,
- 0xe089f930, 0x419efc03, 0x28438f80, 0x77f8eb2f, 0xf0ee5445, 0x56deda3b,
- 0x03c3bf76, 0x52079656, 0xc979156d, 0x7d94b0fc, 0xffb04d67, 0xc0625f2a,
- 0x0e5029fe, 0x097faf52, 0x1ab6abf6, 0x0a74f935, 0xa27e155d, 0xf70ad49a,
- 0xe8955c44, 0x9fe5ae5b, 0x0aa66b24, 0x23def29e, 0x4d9de27e, 0xaed46519,
- 0xbb06ef3b, 0xd0a7f94a, 0x53d3b2aa, 0xc0164b06, 0x287f845b, 0x0fa2c67f,
- 0x3037ef7d, 0xfe038c1e, 0x0b5d86c2, 0xe8773844, 0xe0b35d2c, 0x3fda3a1e,
- 0x362a4acb, 0x12b3f7d2, 0x64f50968, 0xebcaef5e, 0xe7d9583d, 0xa041b723,
- 0xb8f157cf, 0x9e562bec, 0x5e746037, 0xbc5cf70a, 0x9d9af1c2, 0xa0bb4566,
- 0xa291adc8, 0x8db5ce0f, 0x333b7cfc, 0xba00699c, 0x0c6c7229, 0x6a76421b,
- 0x2e8d32b4, 0xbc39e403, 0xe179f7e5, 0xbd23b0bc, 0xec25f573, 0xf3fd3fbb,
- 0x1f9f3e46, 0xdd7f5fed, 0x46e0fbee, 0x5c696fc0, 0xd03723f3, 0x9f25d97a,
- 0x91769c63, 0xf50aecb5, 0xd4be9e79, 0xf3adffcf, 0x1fe01c27, 0x9e6d7eb6,
- 0xfecfcb14, 0xdffccaca, 0xf8e9febd, 0x2177e29e, 0xab2740a9, 0x63342fbf,
- 0x55d57e89, 0x8e80f2a8, 0xec0931b2, 0x99c595ab, 0x2bbee9c6, 0xaec7ce54,
- 0x5fb8b10a, 0xe833e816, 0xdd8335df, 0xf335fe57, 0x7fe8e28f, 0xc794ee70,
- 0x32dec9cf, 0x69db16fa, 0x3b08b7bf, 0xa84acd6f, 0x93ef8468, 0xcf033988,
- 0xf688732b, 0xe4acafbe, 0x8f3809ea, 0x479c0c84, 0xbdae9c6e, 0x40346cab,
- 0xcc0c9f7b, 0x2a23cc57, 0x23ce8cbf, 0x78c10fab, 0x29701916, 0x194d85e6,
- 0xb79ff948, 0xeccc0e7f, 0x426711b7, 0x764fef54, 0xa09de2dd, 0xddaa5bf1,
- 0xfedfc7a0, 0x5623bc4e, 0x3675c5fe, 0xfd7b9fc6, 0x03e42f5e, 0xde3cf1e8,
- 0xbbb12c25, 0x8f5be3da, 0x15fe3d4f, 0x98f1eabc, 0x427b91f3, 0xe93c0c52,
- 0xbf3d12f1, 0xba00ac0c, 0xd1140de4, 0xd074297e, 0xcbf689e3, 0x5f6f7e87,
- 0xf9c1fb42, 0x08c2b8ab, 0x43372f76, 0x457fdc20, 0xc22f36ff, 0x257fcc1f,
- 0x3748ed5d, 0xe3db5e3d, 0x979f93d1, 0x1edf5d1a, 0x37e617c0, 0x3e400fb9,
- 0xc24da359, 0x1c684971, 0xbc7be751, 0x04e4f102, 0xbbef1e1c, 0xaa40c71b,
- 0x5762aef8, 0xff2888e2, 0xeb5afb8c, 0x2705e6e7, 0x39ff029e, 0x04b7c12b,
- 0xcc44a6e2, 0x8a3a3cc0, 0x3e5ac3bf, 0xcd6bfce3, 0xf8a13e40, 0x0c43b6d4,
- 0x664fde07, 0x5d4e79ed, 0xf4cf8ebb, 0xecf857eb, 0xa6307815, 0x3e14be3d,
- 0x7ee3689b, 0x13d27779, 0x5b21e4fc, 0xde802446, 0x98a4c126, 0x075188f1,
- 0x9c3811bd, 0x051f915f, 0x773c8be2, 0xf427f9f6, 0x8eb51357, 0x1cc0f8aa,
- 0x2d9b77d1, 0xf852fe86, 0xb74e4ae3, 0x13bc892b, 0x12574be2, 0x7d9117e3,
- 0xfd744640, 0xde3c6cb3, 0x80f483d2, 0xbab2ee75, 0xaf997ed8, 0xea6eb233,
- 0xb3dd0256, 0x71d9f8f9, 0x834efc36, 0x112d8d84, 0xbde267fc, 0x2929b235,
- 0xf7890f3a, 0x8415e927, 0xf03371f9, 0x178a5cbe, 0x9d1ac172, 0x609b42c7,
- 0xf85c7bc4, 0xc6d74e3c, 0xb6df90c9, 0x003df44e, 0xf6116ceb, 0x19f5c10d,
- 0xeec1fd43, 0x6f3fdbe9, 0xed0655d8, 0xf6215fb4, 0x2f9ff3e3, 0x7843b8b2,
- 0x3ab039bb, 0x94ff63a3, 0x07da358a, 0xe1b22e45, 0x41cbc8bb, 0xcc22c2ce,
- 0x53cfc83b, 0xc2299c76, 0x3887a0fd, 0xe1465c97, 0x113b3eed, 0xa973f9f3,
- 0x7a7e81ba, 0xb7f3d7be, 0x90279f9e, 0x4f784cf0, 0x363fc7cf, 0xdff1400f,
- 0x90737c22, 0xeeca8df2, 0xf942fc29, 0x5d1b79e7, 0x6388db77, 0xfdbb814f,
- 0x53cf88ce, 0xfe29eec1, 0xf10fd479, 0x3afd00bc, 0xff15d3f2, 0xf7cd937c,
- 0xc233f412, 0x99fbe87a, 0xf8065d03, 0xcd90fe7e, 0x573c32f3, 0xed8b96fc,
- 0x232ec837, 0x3be74819, 0xcea1d393, 0x593ef040, 0xf6808179, 0x961276ec,
- 0x2bdbbc60, 0x76becd24, 0xc9fc25a6, 0x587e70fd, 0x99ed0039, 0x14fabe0f,
- 0x8f967df1, 0x13bfc55c, 0x0fee1819, 0x163bbefb, 0x43c7df6a, 0xbde8acc2,
- 0xbed09f9d, 0x6e0092dd, 0x877c0a73, 0xfb6b205b, 0xd657c7eb, 0x7fab87a1,
- 0x63df9caf, 0xbb22f704, 0x9fc2fe55, 0x8d8fcc6c, 0x7e2df7cc, 0x37c5018f,
- 0xc1b3d5d8, 0xc50f024b, 0xf4a55fe0, 0x8c7b25c5, 0xe6f5a3c3, 0xb1e9e6ed,
- 0xc65117ee, 0x833df051, 0xfcf82934, 0x65ff1636, 0xc01c58fb, 0x734844f0,
- 0x7d94af4e, 0xdfd013c3, 0xa0275beb, 0x97525d7f, 0xf1a59863, 0xb83ed9f3,
- 0xf70f9f9d, 0xfaff405d, 0xafcfcc9d, 0x42fdc4ab, 0xf7db3d49, 0x5cef82ac,
- 0x0c89f3ba, 0xb23fff42, 0xa9bc859f, 0x9047b852, 0x53e087b5, 0xacd53ef5,
- 0x897db27f, 0xf611b969, 0xc934bea3, 0x5abfeb4d, 0xf747155e, 0xc419554d,
- 0x29bee842, 0x27cb57f1, 0xb54d18ae, 0x20479273, 0xb2af5889, 0xfefce98d,
- 0xcb57f939, 0xe36596aa, 0xaede2bbe, 0x2476cfda, 0x2e6de71f, 0xfb4763c4,
- 0xbc12c7d8, 0x3c5576c9, 0xb3ff4f42, 0xe004ae71, 0x7f7ce5bf, 0x59c2f57d,
- 0x0cb06fb8, 0xf90e9f38, 0xee9cd961, 0xb38f3b2e, 0xdcf7d95a, 0x00f4d6e5,
- 0x456ba9e8, 0xd9e60b9f, 0xfef9c6f6, 0x6b7e4710, 0xb7dc11e0, 0x8ebdf905,
- 0x5e45fcfb, 0x65fabe75, 0x5f67e676, 0x03a3497d, 0x8cd71df6, 0x677e0bfc,
- 0xeec8da7e, 0x6d196b4d, 0x4fb9f8d2, 0x032ef2da, 0xd1494af8, 0xce7e8227,
- 0x20ebb11e, 0xec8efbd8, 0x780ed444, 0xe403b004, 0x3c54fefc, 0xeddfaa07,
- 0x0b65d880, 0x74fd6eff, 0x9dea637d, 0xf0dd2cb4, 0xb7ec0717, 0xcfccedb2,
- 0xc26c6d3b, 0x5e4a747b, 0x079ef115, 0x6dea6e3a, 0x9fae5f10, 0x1b10f595,
- 0x076d4e26, 0x43afbf09, 0x8caf07f1, 0x2edc0393, 0xbc4d712a, 0xbd5c63df,
- 0xda38b1e8, 0xf7a785fb, 0x0f9e3e66, 0x1b922174, 0xd92325dd, 0x3f227e85,
- 0x5dbfa1e7, 0x0ef0af70, 0xfebd795e, 0x40af1bf3, 0x4276a266, 0xd7c93f00,
- 0x98ef0585, 0xb7fc563e, 0xe36b5f71, 0x527f7a97, 0x83e33bb1, 0x20f49743,
- 0x8dd71780, 0x5ec21df8, 0xe94de623, 0xf0bccdfd, 0xcafc0ec4, 0x363f9147,
- 0x02b1f7d6, 0x19d9873d, 0x7fd7965f, 0x94aef78e, 0xb834d091, 0x5eaca6ff,
- 0xf7c88674, 0x6f25e9e9, 0x6ac1dfc3, 0xe02e4a0b, 0xeee0b6df, 0x6f5021b8,
- 0x561e3110, 0x65f64efe, 0x41ad67c0, 0x291fef09, 0x01cc7edf, 0xf3b140fa,
- 0x2f7641ad, 0x08f05b49, 0xb6e0573e, 0x065f2436, 0x818367f6, 0xed773fed,
- 0xfa0ad6f9, 0x67f3f5e1, 0xabdf7193, 0xff9d69d8, 0x7377c4ab, 0xbe2462ed,
- 0x896ff6ab, 0xf2007d98, 0x2412f2a7, 0x7f510a22, 0xfe9d9db5, 0x93b12c88,
- 0x823af6f6, 0x8231e27f, 0x77edeb9c, 0xfb3adf04, 0xfb9d88fd, 0x30c8bd8f,
- 0xe1afc7b8, 0xfc7cf27c, 0x756833ee, 0x0cf8c22e, 0x76da4ff3, 0x14d8fa7d,
- 0x644fbe78, 0x179ffddf, 0xd8dfef91, 0xb377bf31, 0x2af78d4d, 0x6eb9d7a4,
- 0xd1b75a67, 0xc776e7fe, 0xd1b578b3, 0xbbfa997d, 0x00ff6883, 0x3ba857c7,
- 0xbb92f73b, 0x3f3b7dc3, 0xb70cffda, 0x45eaffbb, 0xb8d2f790, 0xc35044f0,
- 0x990e6bfd, 0xb30c5f40, 0x7a625f7b, 0x7a0acea0, 0x7be32640, 0x516e3a10,
- 0xfc0f193c, 0x4e24ae15, 0x757bc3c8, 0x7400c1af, 0x0336b119, 0xf1d664f3,
- 0x7579c173, 0x950ca6d5, 0xcfc7997e, 0x724a4e95, 0xf9ea927a, 0x03d30770,
- 0x3f177727, 0x03f2fa87, 0xc317e933, 0x983b263e, 0x9264dbbd, 0x7e87aca7,
- 0xefb80d87, 0xeb67b5d8, 0x6e0fb81e, 0x50d741de, 0x41a737b0, 0x86bc281e,
- 0x20aaeb7d, 0x23e1b6cf, 0xbf5416b0, 0x0d1029af, 0xc46ddc74, 0x0764e2c5,
- 0x8dffb80c, 0x278917c4, 0x29f9d619, 0xf6dbbfd7, 0x50e7341a, 0xa43df8db,
- 0x39d9da1f, 0x8b3b7ed4, 0x3bdc6d53, 0x944ef93e, 0xd001df43, 0x9b47e5ff,
- 0x68ae1cab, 0x97f14d5c, 0x38d81cc6, 0xe7fd3065, 0x13831698, 0xb03aedc8,
- 0xbaf5845a, 0x25db524e, 0x13fe7690, 0x1a89f785, 0x0616b6de, 0x0de3ce8f,
- 0xff055390, 0x3c3f02d4, 0x35b7d688, 0xbf209319, 0xb2bfc14a, 0x577c650e,
- 0xb2acf11d, 0x367928a1, 0x577c4f7e, 0xb87cf7b9, 0xa0f72893, 0xb6ce5f23,
- 0x3f195a7b, 0x3f50e9c8, 0xfd1e3bb9, 0x9edc4d92, 0xde82b491, 0x4e853f80,
- 0x7f660e09, 0x3474f994, 0xbfa73c7e, 0xbe50fe52, 0x64b9275e, 0x1f7e1be4,
- 0xc50e4ba0, 0xae3c81f5, 0x77f83e86, 0xae79545a, 0x47c00ef1, 0xd47e368b,
- 0xc0306cd0, 0xdb6558f7, 0x66bc4485, 0x6dfe93a4, 0x758ccf84, 0x070d7fc8,
- 0x7171ca09, 0xbe2c5ded, 0xf83d4247, 0x5e7858bd, 0xcfc3f20d, 0xb409bbad,
- 0xb55c131c, 0x37e207b8, 0x8ab900e4, 0x0dca89e2, 0x26d51594, 0xf779d7e0,
- 0x3f2e72b0, 0xd2b79dff, 0x5859f287, 0xfafbf2c3, 0x7cd8323a, 0x4312bf38,
- 0xfbc8777c, 0x7fdb8e78, 0x022fde65, 0xa9fad2df, 0x611bc7fa, 0x975fca5c,
- 0xdeee203a, 0x3053e8f0, 0x4f5f855d, 0x4e1091ad, 0x7cf6bc51, 0xd74e72fc,
- 0x7e300f57, 0x1a46b31f, 0x8d31f70f, 0xe2138991, 0xacd6dbc5, 0x6f7f4115,
- 0x60ce7e03, 0xfd760e72, 0xac87eee4, 0x773b04bf, 0x2e2040c8, 0x8a44c9bd,
- 0x62e4a836, 0x34d7aad7, 0x5b5c5bf2, 0xdfe30539, 0xe80249cd, 0x156e4579,
- 0xb9326fbc, 0x5ffca327, 0x09ff93ab, 0x0e39fdec, 0xb9c79746, 0x893e3ffc,
- 0x947d3fca, 0x005126b8, 0xb14c9b38, 0xf69ae9ef, 0xa22ff923, 0xd3b68f57,
- 0x6c1cd3ab, 0x43e8ef5f, 0xe6bb2fc7, 0x23ebee2c, 0xf37ce3f3, 0x6f8504f8,
- 0x7fc00432, 0x5f60a535, 0x2bc517c0, 0xaffa33f0, 0x32736fa0, 0xf6a1bef1,
- 0x3948b8fc, 0x6dc8d397, 0xf229af54, 0x7a022beb, 0x58a84d67, 0x72767e0c,
- 0x7a7c8cbe, 0x4ef5f04a, 0x14ed76a2, 0xbd0c73c8, 0xf4c1d130, 0xa7c939c8,
- 0xfdbcafb9, 0xe077483c, 0x63ba22eb, 0x1a917583, 0x51f409c1, 0x6c355dda,
- 0xc394b15f, 0xf52b9e53, 0x2ff78d1f, 0x9783c5da, 0x333d983a, 0x7fb056c1,
- 0x2233d980, 0x20b9478c, 0x83bbab86, 0x76a3cdbc, 0x1d9556ec, 0x2355253b,
- 0xf8782abf, 0x73f7e735, 0x57dd6c89, 0x829679f1, 0x673aa7ef, 0xa3041ba2,
- 0x145ae4c0, 0x008bbc98, 0xb1eed4ff, 0xafef9193, 0xf3f7cd89, 0xfe42afd7,
- 0xc4e49c4c, 0x371e48ef, 0x83892dba, 0x00e3e962, 0xfed6bb96, 0xc059f706,
- 0x1df720c7, 0xc81141c9, 0xffc18901, 0x2affca01, 0x407c29fa, 0x8745e2f9,
- 0xf9e84f4a, 0x53df3942, 0x7749b2f0, 0xeb8e783e, 0xba5e46f9, 0x5153c83a,
- 0xe9a3f3d6, 0xce8ed2dc, 0x473a306f, 0xade80be5, 0x81df89e8, 0x2c74a59c,
- 0x9c12fd67, 0x8faa9f38, 0x485e6167, 0xaa273f35, 0xf329e3e3, 0x42f5c03e,
- 0x353ce747, 0x1c5fdf56, 0xd748f3ba, 0xe47f28a0, 0xc176bf71, 0xb39e335a,
- 0x9e4c206f, 0x01f15de5, 0x4e9e77f5, 0x294c7523, 0x3e808faa, 0x3856891f,
- 0x42d77504, 0xc74be913, 0xb051973d, 0x7e6df20b, 0x0fe724d6, 0x60d8eba6,
- 0x835ea792, 0x64f701fb, 0xdf393f80, 0x6f7884e0, 0x4029c7a2, 0x0343023c,
- 0xd8fb8720, 0xb8fbc338, 0xab7dc32f, 0xf41c3dcb, 0x2f4e69c1, 0x1e0abe85,
- 0x1d77b23a, 0x025fb5d1, 0xede3a73f, 0x26f23d7a, 0x38e79b97, 0x47ae2f1e,
- 0xc9e41164, 0x448b7c41, 0xd3367f98, 0x923d1183, 0xd01cf04d, 0x9e55c7c1,
- 0x509ff52b, 0x5212388f, 0x74647a54, 0x423d4c73, 0x3fe5317f, 0xf41ccd65,
- 0xd8c1c967, 0x027a6cfe, 0x6029c7b3, 0x14bf6947, 0xd33dfd99, 0x503edcd3,
- 0xc57cc48e, 0x8c6635ea, 0xc87a2be3, 0x878c9531, 0x00eacfbf, 0xa6bd0bbb,
- 0x095e0efa, 0x2669b3e7, 0x9f179c17, 0xf748c292, 0x5cc37453, 0x15e1fc8d,
- 0xf431de80, 0x85f88111, 0x2c9ed7fc, 0x51062efe, 0x11e4164e, 0xd6bba3b4,
- 0x2abe428e, 0x8014cfca, 0x136b8b6f, 0x9a4f6805, 0xbe8034e0, 0x6a31d652,
- 0x49fc88a1, 0x824460e5, 0xe4a31e8a, 0xd5f0110a, 0x2697d93b, 0xd6fdd225,
- 0x4cfd57af, 0xd0f1bf1d, 0x68b48afa, 0x1fd686fc, 0x7ceb75b4, 0x213726fc,
- 0x3fe420f0, 0xe4f0eadc, 0x5635b8c0, 0x59942e6f, 0xce302b5d, 0x88bcd9db,
- 0xe52fcb1f, 0x0e444e3c, 0xcecb8bb4, 0x5c6175ac, 0xa7cc1a76, 0xa7f1fbac,
- 0x73de1c00, 0x66efd311, 0xf5c2e8f3, 0x2088f902, 0x2b78ba3d, 0x28978844,
- 0x384ee77a, 0xf6a14594, 0xa1ae7008, 0x2de81bc8, 0x3c95a7f0, 0xd95b8808,
- 0x401f6e31, 0xc27a823e, 0x5a3ea8b0, 0x79886f91, 0x04c2f15f, 0x9faa4fdb,
- 0x9beff049, 0x477ca97f, 0x2d3ca228, 0xebe9504c, 0xa70ff3c7, 0x7608f3b2,
- 0x7cdddfaf, 0xb916e78c, 0x4ba034ff, 0xa1867ef4, 0xf90c9366, 0x5c43c4a6,
- 0xb1fe554e, 0x76421410, 0x56fd63c8, 0x874a1e20, 0x2c456fb6, 0xde3ffb9f,
- 0xcfe01949, 0xd4dc1837, 0x0bfc8233, 0x6f770794, 0xd4a7df82, 0x73127bf1,
- 0x091e6d1a, 0x1c421de2, 0xa3da8eff, 0x1d18e73d, 0xdb4f5f4e, 0xf8cd0717,
- 0x72dafdb7, 0xe0afbf94, 0x1598efc6, 0xe7790efc, 0xd79881f1, 0x8376ac69,
- 0x30b6ad9c, 0x2c2dabf8, 0xa2dab76e, 0x004ae7bc, 0x79d1ddbb, 0x1ec2f67b,
- 0xe253ff18, 0x90e1d98d, 0x0cc9f808, 0xc92c0cbb, 0x0c678d8d, 0x72b75c13,
- 0xf1c75f0e, 0x46ef69bf, 0xd679ec11, 0xb0c5ea84, 0xf763d9ef, 0x6bfa00bd,
- 0xdfd6b66c, 0xf3f0211b, 0xf704c9e1, 0x249c8a4b, 0xe09d9337, 0x6c1e24da,
- 0x1a0a80f6, 0x13b3d27b, 0x5e0995f6, 0x553c0022, 0x8006cffe, 0x8478ba4b,
- 0xdfc0ba6b, 0xfb7fe5eb, 0xb4d9c390, 0x7200bc77, 0x8269a5df, 0x9ed41ae0,
- 0xfec257cf, 0x53cb047b, 0xfb2afa01, 0x5e2fdec2, 0xa5f0013a, 0xfae26ff4,
- 0x2f9f0afc, 0x74c64217, 0x7718213d, 0x2340f4cc, 0xaa35495c, 0xb9346e48,
- 0x4799eb54, 0x668f5e10, 0xedd1d719, 0xca072fa0, 0x1c44b663, 0x10c9ec77,
- 0xad74b7e6, 0x43f69020, 0x401d357a, 0x4557aa3f, 0xdcf40093, 0x9c0df7b4,
- 0x5da6cf6f, 0xb5f2e4ac, 0xca05fb91, 0x98d98ebc, 0xcfc63cdd, 0x334eaba9,
- 0xc12079bb, 0xca4bf987, 0x7c72aa3a, 0xfe141569, 0x19cbc84a, 0xce5e71d1,
- 0xb2930491, 0xd608ffdf, 0x79bd3e57, 0x3ea0f00f, 0xefba907e, 0x7523d230,
- 0xaf96db21, 0x0040b7dc, 0x4672b17d, 0xa281f8ec, 0xf8f25637, 0xe5ff2aab,
- 0x4f4f5a94, 0x66b24829, 0xf292f4aa, 0xfcd153de, 0xff3c4d97, 0x7bcd03e5,
- 0x805a9783, 0x79b2ee9f, 0xe573c0ce, 0xe3ad0bef, 0xd947b77f, 0xbaf82acf,
- 0x80fcc9c2, 0x1fd70903, 0xc0247383, 0xf1f29393, 0x3cec4b3a, 0x069dcbf2,
- 0x7e3077ee, 0x5f8c4d21, 0xff6a1d60, 0xb001bfeb, 0x00d7432f, 0x0000d743,
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0xc9332666,
- 0xe4cc9924, 0x40275e49, 0x21c40a30, 0xeb141021, 0xef0c0124, 0x02415041,
- 0x8042120c, 0x2a941324, 0x8065bd6d, 0x8d520318, 0x8bd4b45e, 0xd7a5783a,
- 0x2941b622, 0x84ec1a86, 0x3a0bc157, 0x94b62a28, 0xaa54141b, 0xa5ac4090,
- 0xd7f97b96, 0x661f7b5a, 0x962264ce, 0xbfefbf62, 0x767e9fff, 0x67d9cfb3,
- 0xfbd7b59f, 0x649ecfb1, 0x1258c4ab, 0xdd3b3763, 0xd8c67a65, 0xc1b758be,
- 0x88d8c45a, 0x596edf62, 0xb9786c61, 0xda1eb777, 0x3bbf564c, 0x94061136,
- 0x6826c733, 0x3dac1dec, 0xa384da0e, 0xb838ce1d, 0xa36adfdf, 0xacfa6e79,
- 0x8c2db98b, 0xab98950d, 0x97631065, 0x60d6eff0, 0x31d56a9b, 0x0627f306,
- 0xe306254a, 0x6cb8c436, 0xe961bef8, 0x4001b2f5, 0xf1d66449, 0x03631fac,
- 0x2b8d0aad, 0x96ee762c, 0xa7563de1, 0x8b79c64b, 0x9ef4ac63, 0x6a771cc6,
- 0x1d3e7f3d, 0x4e89679f, 0x37c02269, 0x5b18bfec, 0xfb6ddd03, 0x1065254b,
- 0x6f1467be, 0xc0b67319, 0x056057f8, 0x115970a1, 0x9f7c249e, 0x39ebef44,
- 0x4acf3bbf, 0x129ceaf0, 0xa8fc324c, 0xe860c7c5, 0x32f5a5f0, 0x02c89fc2,
- 0x6d000312, 0x2312d6d5, 0xc6bd37bc, 0xfe61b921, 0xf95c629b, 0x0e635cf8,
- 0x6d0a1c5c, 0x0ab7ce89, 0xe7103b9e, 0xf981653c, 0xf668bf17, 0xfa31349e,
- 0xd5ff04bb, 0xfa6824b6, 0xef34d69e, 0x7f60bcc9, 0x0d23fe31, 0x4ccfdbfe,
- 0x3563186c, 0x407b16fc, 0xef8cdf76, 0x3c7535a9, 0x75fa173a, 0xc8caf8bf,
- 0xae0a4960, 0x6578e017, 0x3dcc417f, 0xa77ae096, 0x9977a4f5, 0xbd27a935,
- 0xde824a87, 0x4ade8163, 0xb29f7a4f, 0x3b7a0824, 0xfac107db, 0xc24c5de2,
- 0x135f01e7, 0x85dc3d39, 0xb788c1ae, 0x380332a5, 0x587a455e, 0x538f4cae,
- 0xa71fce16, 0x2a1e9c2c, 0x38c6e61d, 0x75d2b4ef, 0x96f5ef46, 0xbebc3cb2,
- 0xdcae8276, 0x16cf8117, 0xee342d59, 0x05fcf1aa, 0x99e287d3, 0xfb6dfdb5,
- 0xc1efa10f, 0xf784cb7f, 0xc0378845, 0x583f5c7b, 0xf84ebff7, 0x53f91928,
- 0x203aea67, 0xdb6a3e01, 0x25864564, 0x9c954c0c, 0x5b190b27, 0x89cda0f5,
- 0x8b5cf07c, 0xf18288e4, 0x6b14c9cc, 0x22564332, 0x75fd9d62, 0x11bb3e7c,
- 0x8360b85a, 0xa334de71, 0xcef2136f, 0x8c33c01e, 0x380824f3, 0x001fe01a,
- 0x0555a747, 0x0df749cc, 0x559ff2ec, 0xf851fb82, 0x6a4b982f, 0x80976f69,
- 0x998aab70, 0xef7000db, 0x1f89936e, 0xf68c6b9f, 0x2ffcc145, 0x607f396d,
- 0x3ffbf426, 0xc165c3a8, 0x27eb04df, 0x53a8f831, 0x1cad04ba, 0xc3d3ca67,
- 0xed1c877d, 0x4b7c6190, 0x8b3e5c74, 0x3764ac67, 0x955b3f31, 0x7bc0f30b,
- 0xd347b556, 0x82e556fa, 0x1f10e47c, 0xd9f8863c, 0x69646b13, 0xe41bbd70,
- 0x670dc706, 0xcc8cef1d, 0xbba9d209, 0xbbd9cbf5, 0x189efd60, 0x2627af3e,
- 0xde00c7cb, 0x07175dce, 0x5b8f1f20, 0xca35cf36, 0xd924d8ce, 0xafe91ebd,
- 0xde66f73e, 0x6f8871c7, 0x5e0832c6, 0x841c9fa2, 0xacde32ef, 0xac72bf1c,
- 0xc9d1d69e, 0xeeb81da2, 0x2193a316, 0x39c7bc9d, 0xad78ab7f, 0xd9d1bc13,
- 0x0dd47456, 0x68ee7beb, 0xef9f0386, 0xeb36ed6c, 0xe2cb7de0, 0x75c0bfdd,
- 0x715d99c9, 0xcf8841ae, 0x063bebee, 0x097a1e91, 0xfc1f77af, 0x741ee6d8,
- 0x86dbeb55, 0x7d695fcf, 0x49a5bd1e, 0x3fc9ef8a, 0xb5207ce1, 0xca55ffb5,
- 0xa8613927, 0xcc59bcb7, 0xddd60ab7, 0x93487838, 0xc69e848c, 0xc64f9414,
- 0x0c9fac2a, 0x2abbd20c, 0xf107b5de, 0x8cd7caac, 0x843ed778, 0x5e93df0b,
- 0x8fdceb40, 0xf343fcfd, 0xabba0d0a, 0xc8e1e75a, 0xfe13f4eb, 0x6a7ac56b,
- 0x0cbf164d, 0x866db3f0, 0xf9543a2f, 0x5e13dbec, 0x0e31c7a0, 0x1ba8e3af,
- 0x8b7bf9e9, 0x43e21563, 0x62bab01f, 0xf8e3fe09, 0x373c563e, 0x21bbd715,
- 0x858f69c6, 0x30579bf1, 0xb4520fce, 0xdc5879e3, 0x68b63dd6, 0xf15593d4,
- 0xdf3853ee, 0xb3f3ba0d, 0x02c7685d, 0xdc3ddd2e, 0xd7867c0e, 0x7adddd61,
- 0xc65ea382, 0xfd62aff9, 0x71f322e7, 0xd9fc3a0f, 0x54e7a21a, 0xf4148cfc,
- 0x41f8891d, 0xffa5dc85, 0xc414c3a2, 0x3d4a048f, 0x3e73d6dd, 0x10b23ac6,
- 0x9f1df6de, 0xf980e80e, 0x74f8deea, 0xdd6fca36, 0xb888a26f, 0x7d737ea3,
- 0xd9f1f23c, 0xc5bd3612, 0x7e9f53d2, 0xa5debcb1, 0x1ffae607, 0xcbd25f6b,
- 0x44602c35, 0xb2db5d3b, 0xd10fa5c4, 0xe93100a7, 0xc08683dd, 0x60ff9c04,
- 0x0056cc91, 0x863b75df, 0x7a08b0a7, 0x5adf6d5a, 0xb9955cce, 0xf512fd8c,
- 0x8ed7f21c, 0x9784f1a1, 0xe3e91b36, 0x9707f1f0, 0x1946bb57, 0xe0ef9f7a,
- 0x1f74f310, 0xcc213f3c, 0x8131b90f, 0xa23195db, 0x44e94505, 0x8f6ccf38,
- 0xd2e179f5, 0xe2f78299, 0xcce9e018, 0xbd0b77b6, 0x58672fc0, 0x51d7bee0,
- 0x30b4be7e, 0x0c267bf4, 0x4570af79, 0x6ede506c, 0xbf6be629, 0x7143b5e5,
- 0xb09f8c0a, 0x37a27775, 0x30b77f04, 0xf99797fd, 0xcbdf0737, 0x1df4c7d7,
- 0xec1e9003, 0x0ac9d3f5, 0xec7613b4, 0xa07ce44d, 0x4bce90e8, 0x15fade85,
- 0x9c111a5e, 0x3ab2c26f, 0x60c2a8d7, 0x9982f6bf, 0xfafb42f9, 0x5f4d1180,
- 0x5d0b05ed, 0x26c427b7, 0xc3e8fe92, 0xf8fea0fa, 0xbf0b78b6, 0xe0ede2ae,
- 0x6859d390, 0x239acfbf, 0x62edc9f3, 0x4463b75c, 0x1347fa0a, 0xd6fefe8c,
- 0xf318e308, 0x75f0b8d1, 0xeddcb9bd, 0x3bdb951a, 0xcc8de37c, 0x1cafc91d,
- 0x9afdc09f, 0x7999876e, 0xdbefae41, 0x743b2068, 0xd307e2e8, 0x9f7e810a,
- 0x5758306e, 0x9fab3e02, 0xaff19dd9, 0x487abf70, 0xfe825594, 0x3fbf8aa7,
- 0x6782f1f2, 0xfbae1764, 0x25f70dd3, 0x73f683cf, 0x801ac7e0, 0x0346c163,
- 0xf8deaf5d, 0x5a7eba7d, 0x6782e9f0, 0x9ea20692, 0x4d67b43f, 0xfab3ae32,
- 0x13be1fbf, 0xa356c5f5, 0x6810e075, 0xae48b66b, 0xb1722151, 0xa6b305e8,
- 0xaac755bf, 0xbaea1d71, 0x7cbee499, 0xbc78015f, 0xba0fdc09, 0x8f65ff6a,
- 0x7f017fd6, 0xfdc09bc5, 0x61534995, 0xdd4575dd, 0xdeee27e4, 0xfc764d17,
- 0xfc9916b7, 0xbf90ff01, 0xd08de7fc, 0xbd6ffb2f, 0xc1087c83, 0x5e85a3e7,
- 0xf48f2c66, 0xf7899550, 0xc9e876cb, 0x958b289f, 0xd07edf09, 0x08c8a313,
- 0x61a32d39, 0xe7d4f7dc, 0x46eb91e4, 0xf1d1b8c0, 0xe27e8606, 0x268bfcf7,
- 0xb7efd030, 0xd47fd05e, 0x529eb211, 0x23a3d4e6, 0x9a0cc252, 0xe3a3abeb,
- 0x08ff479e, 0x1ea3d326, 0xef69332f, 0xee3fee8f, 0xd1bbda34, 0x5575ed56,
- 0x39439e7e, 0x83941818, 0xf4fefbdd, 0x675878c4, 0xfb9941d5, 0x33d05763,
- 0x72bae16f, 0x566fde91, 0x0ee7816c, 0xba1cec09, 0x1a4369f8, 0xc4b157f2,
- 0xd3ff4256, 0x91e5518b, 0xd54622e4, 0x9ce80c37, 0x44f3a417, 0x7dcbc2c7,
- 0xc5c98b14, 0x11f72e4b, 0xefaf6ffe, 0xef2e59be, 0xfbd2304e, 0xb861f5c3,
- 0xfa577cfc, 0xbd90c270, 0x6a58de59, 0x17ed8e7f, 0x099eb95b, 0xfae18fd7,
- 0x1c2b854f, 0xb20bdade, 0x4f8def46, 0x505c6850, 0xfee919ff, 0x3eb38c35,
- 0x6710884b, 0x7c267d81, 0x29e98779, 0xe1ff03be, 0x641b8e0c, 0x0025ec51,
- 0x6fb58352, 0x25f5ea0c, 0x5e177716, 0x86e97ecf, 0x0c17e851, 0x43acd2dc,
- 0x7129d1fd, 0x88366d7a, 0x8283fb16, 0x045fd071, 0xfa131cdf, 0x53a0e200,
- 0x2efb6816, 0xc31f632b, 0xcc4ca2fa, 0xbb202e6b, 0x041435ef, 0x7e023fe7,
- 0x8d99c60c, 0x9fc78c25, 0xebffdc09, 0xace8a79b, 0xcbc3ff30, 0xc093cead,
- 0xa797abcf, 0xf2f2cb52, 0xfbbf4874, 0x6fd06e04, 0xbbbce7c4, 0xa75d69a2,
- 0xca3e5724, 0xbe02c3e5, 0x62dc7a70, 0x35dbf953, 0x9a2fd420, 0x5f591a5f,
- 0xd3d36f5f, 0x66a792f8, 0x71dfa164, 0x2ceefdaa, 0x00a7a3d4, 0x41da00de,
- 0x9bfe23bd, 0x84c785fc, 0xec223e3c, 0x2788bc45, 0x04e4227f, 0xd5b9c7d8,
- 0xd174eb82, 0xa7cbd5fd, 0xf2f8fb53, 0xc63f7465, 0x12fc4396, 0x4095e237,
- 0xc9dfa05f, 0x83d932b5, 0x80d746f9, 0x49ef7804, 0xd2e28e93, 0xe52deb8f,
- 0x9d782cdb, 0xff337c51, 0x509bf1a9, 0xb5cb2e2e, 0xeb6f4758, 0x7576c5bc,
- 0x7596bc7a, 0xba5da1c4, 0x00c78fcc, 0x7e41c93b, 0x6fbb2f9c, 0x3c6115b2,
- 0xe38c91d3, 0xc060523c, 0xba060a16, 0xaa3f50b2, 0xe2d57fef, 0x8496c5bc,
- 0x881b0ef1, 0xcd12d172, 0x9c384eed, 0x1efd05a3, 0xbe08ae5e, 0x88d6a3c8,
- 0xddc624be, 0xe822af68, 0xb9e27195, 0x38e71613, 0x42dfd11b, 0x03ad277e,
- 0x38eee5f8, 0x0ebc44e7, 0x6c64c371, 0x3cf0a587, 0x558b29cf, 0xe2538bf0,
- 0x9a6bb97e, 0xa71e422d, 0x3841bcb7, 0x3c6d671c, 0x4f9e138f, 0x9f355b50,
- 0xe7ac4730, 0x26ab04ab, 0x30b4a3cf, 0x423ca467, 0xe348cd9b, 0x394e9d52,
- 0xee5de946, 0xf23fba86, 0x992f98ca, 0x4e281cce, 0xda5b2329, 0x36928f31,
- 0xf302b7ca, 0xe1098d2c, 0x6335e872, 0x5bafa57e, 0x7185ec97, 0x897701c9,
- 0x1ed8e011, 0xa5f04c9f, 0x4815fab0, 0x1d6ea1af, 0x9ee87a2d, 0x06a49f68,
- 0x50a4307b, 0x509047e8, 0x655bca33, 0xa441fbac, 0xfacab0f3, 0xf3054655,
- 0xf5195e50, 0x9dc969cb, 0x38fe036d, 0xa23a37bd, 0x9b13f75f, 0x6952fbd0,
- 0xef0a961f, 0x7840c179, 0x93c2fa18, 0xa1de11b3, 0x97a6dc2f, 0x5ff5e242,
- 0xdf040cd8, 0xb28bbde9, 0x30fe7e29, 0xf4e6e58a, 0xe0a3779c, 0xdf02158b,
- 0xf3231aaf, 0xdc6233dd, 0x93e9eb55, 0x6b24e7e0, 0xb633f4f4, 0x5d4cbc90,
- 0xd3d279ed, 0xf429b03f, 0xb7d37f9e, 0xf803ebec, 0xe64ab7fc, 0x7a2fbc40,
- 0xebe52371, 0x8cb6355e, 0xa9eb82dd, 0x07cc31d3, 0x9bf7d9ec, 0x4fd07d7d,
- 0xa08654ac, 0xf9f9707f, 0xf11b9b83, 0xb355bffa, 0x34ff8821, 0xe612e3df,
- 0x3732be05, 0xdabebe13, 0xc056c514, 0x6e1e1692, 0xe843fb19, 0x31d1afaf,
- 0xebe12bd4, 0x74193786, 0x0dfad8a9, 0x7f4e62ba, 0xdd2a7fd4, 0x488cb181,
- 0x886e950f, 0x7b67d43f, 0xf046bd36, 0x8f6d70ab, 0x7a2d70e7, 0xe458eb71,
- 0x36353e93, 0x2a34f309, 0x9da8ff5c, 0x33f686b8, 0x2572e820, 0x8e1ef9fb,
- 0xe19fb70b, 0xc5897376, 0x5dc71479, 0x15ce7ec9, 0xe847b5fc, 0x8f298561,
- 0x1d92be60, 0x27de51d4, 0x6c732e9c, 0x9fa3f23d, 0x3f22aeda, 0x8b66c53a,
- 0x6cdd1f98, 0xd9b47ae4, 0x894ce6c6, 0x04130f20, 0x5d75babc, 0x898bb446,
- 0xbd44526d, 0xf5c2ca74, 0xafcde812, 0x23d3ee49, 0xf808d5eb, 0xff70ec95,
- 0x5dfe2dfa, 0xa120aa38, 0x5dba0c7f, 0x3d9d4f80, 0x8f029f14, 0x7c555e2a,
- 0x884be2fa, 0x3f0b365f, 0xa4bc7b73, 0xb3aee389, 0x169ce3ab, 0x2f664f7c,
- 0xced13afa, 0xedf8039f, 0xa5c4def8, 0x575f934c, 0xf589eaf3, 0x1438c95e,
- 0x3ca302cd, 0xbdddb65c, 0xbae300c2, 0xf3c73046, 0xb0af8fd0, 0xb3bea096,
- 0x31da3b55, 0x8678deff, 0x971b37e7, 0x9a4adf30, 0x73fff187, 0x2a7ca5f7,
- 0xe965dde2, 0xf5d41769, 0x67eabd81, 0x22e570e7, 0xabd9bd5c, 0x8517286b,
- 0x17276ff6, 0xd6e891c5, 0x6bf5cf15, 0xebdff184, 0xe2b7ce85, 0xf9d12bf5,
- 0x390f510e, 0xfc853f12, 0x6b3f944d, 0xe1ee907e, 0x918e2cf4, 0x7b7cb1fe,
- 0x19dcbc4f, 0x276b2f09, 0xb8f4f2e8, 0x88ed164e, 0xda167764, 0xffbcf3bf,
- 0xcf527b42, 0x69fc3fbc, 0x56e7e7fc, 0x0ebede3a, 0xa64b7ce1, 0x1fb9e938,
- 0x5f311877, 0x55a7e6ac, 0x4b5f3d78, 0xb9fa09cc, 0x5a996bf3, 0x9b5d7af5,
- 0x57718854, 0xe48beec9, 0x7fb6771f, 0x6771fe4d, 0xbeac7f98, 0x4f605ef7,
- 0xb2d18f94, 0xfcfff885, 0xcbcf1e06, 0x48e9f94c, 0xdfb3c380, 0xf10a7cc0,
- 0xb40ff92f, 0x679fe85e, 0xf1c7e1cc, 0x1ec9625b, 0x8f30382e, 0xac5f1cf0,
- 0xbe084a63, 0x4cd19c12, 0xbd97c109, 0x27e9a6dc, 0xc668fab9, 0xabef4ca7,
- 0xbee69fb9, 0xbd3f7341, 0xcfd340ba, 0x3349bfac, 0xa9597b3e, 0x1de39fa6,
- 0xafdf19a7, 0x3f4d76e9, 0xcd6ef9b7, 0xb8e6cdf8, 0xe00ea9e7, 0xc3fa0675,
- 0x7ac52b7a, 0x8f7f5baf, 0x97e639e6, 0x992f58fc, 0xf9fdc82f, 0xb1fb31e6,
- 0xf229525e, 0x16fbd713, 0xdf9de669, 0xe82fcdac, 0x74bed759, 0x4f9d5fc0,
- 0xbfa1f872, 0xfef6bd60, 0x848dd6c2, 0xed3e85cf, 0x6a2fc5f5, 0xa687f9fb,
- 0x4c71c40e, 0x7f442aef, 0x6d76d7ee, 0x748ae2be, 0x55775ef6, 0xd54a8e74,
- 0x68acd9d2, 0xbf8e1ce9, 0xd85b3c98, 0x37dff87d, 0xa1d62fe0, 0x0aef8be5,
- 0x6bb07f7f, 0x621b9cf3, 0xcf51c7dc, 0x952eb775, 0xcbebe619, 0xbbb23d79,
- 0x83fccbf5, 0x7d3c844a, 0xfd3c8f6e, 0xbb10f627, 0x3be9e6a6, 0x2372feb1,
- 0x97f516fb, 0x3c457fdd, 0x31e58144, 0x8acdff80, 0xf5cba61d, 0x2f307316,
- 0xd4bfae1f, 0x5ff7f416, 0x83d7a4ec, 0xf055aa75, 0xf7f8b0f4, 0x5aa7085d,
- 0x9eef18c7, 0x88def04b, 0xff808c80, 0xea9d7c2c, 0x4b87803c, 0x12f8cf38,
- 0x51c60c5b, 0x4bdcf75b, 0x4b6b0171, 0x480efae4, 0xc43e3a1e, 0xda3d253f,
- 0x234cff82, 0xe44c68bb, 0x1894d176, 0xbf31c712, 0xd857bf8d, 0x51e6dec5,
- 0xb5bd18eb, 0xea992ed2, 0x8f585d31, 0xfbd7a089, 0xf683fe26, 0xf91e8be5,
- 0x4589bed0, 0xf7c27121, 0x7ea1f7bb, 0x26e7bc07, 0x63627bc2, 0x414a6ec1,
- 0x98d3f9bb, 0xaeb79238, 0x3aefb203, 0xa4de70b8, 0x0506dbc4, 0xf0e12deb,
- 0x9dd9348e, 0xde7d10fa, 0x66ed6926, 0x43f70163, 0x9db9120a, 0xf8f0b2ad,
- 0x7be8ac75, 0x4f76fcc2, 0x414f8f13, 0x42dbaa1a, 0x89b1c1fc, 0x5cfe34b1,
- 0x5c58c974, 0xdf1146cf, 0xf448e637, 0x224946be, 0x5f1e5efb, 0x75d7163a,
- 0x8e525ec1, 0x3e044ae3, 0x046fa2c7, 0x0e5f736d, 0x0df6228f, 0x13ebf3a8,
- 0xb6127c61, 0x4d8ed4a5, 0xc83f0ab4, 0xfbd2037a, 0xde93b444, 0x8d65946b,
- 0x93b6a55f, 0x2ebaf912, 0x0a2acda2, 0x2168c9ca, 0x1e846337, 0x1471fcc3,
- 0xc2739309, 0xde4d64e8, 0x513188f8, 0x7a258de4, 0xbc7489dc, 0xb7b1d055,
- 0xcf33b23c, 0x69d507ba, 0xad791e78, 0xd591e799, 0x3c8f733c, 0xc44c63b2,
- 0x21d2323c, 0x879416c6, 0xf5978985, 0x9bea0673, 0x278e9cc6, 0x1c7f23c6,
- 0x23cf1d92, 0x31bcc7e8, 0xe2b700f9, 0x91f039d0, 0x4ad81b11, 0x7817f433,
- 0x1933ca15, 0x2d8b0e20, 0xc3efca08, 0x9f843989, 0xa6fd47c1, 0xfc3fb87c,
- 0xf31dab98, 0x31a603ca, 0x66ffaa1b, 0x87165cd6, 0x1606c4fe, 0x29596e31,
- 0x64be39e8, 0x9e728c97, 0x12fc05d4, 0x052b1e81, 0x578e403d, 0x77873d20,
- 0xeec9bbb9, 0xaa403d08, 0x3da3e30c, 0xc397f23a, 0x57103f9f, 0x7bd230f6,
- 0xbe722fb0, 0xc385a2e4, 0xfd718c61, 0xbc1fe704, 0xfa88c3ad, 0x37aa8166,
- 0x0f4c752b, 0xe82a9df4, 0xaf037537, 0x978bb353, 0x9faac92e, 0x867e68c5,
- 0xb4c160fa, 0x1fe61f58, 0x78e5b416, 0x44972e09, 0xdb4f15f9, 0x17f61761,
- 0xc56a1d0c, 0x7bf9d778, 0x47927d26, 0x7ae31a2e, 0x513ecf47, 0xcfd900f5,
- 0xdc5baa44, 0xa2eaf82e, 0x41382145, 0x018daf3f, 0xb0d82c3a, 0x53ee1762,
- 0x19dfef78, 0xca8e27d5, 0xb270c35d, 0xcb39003b, 0xb3d5b00a, 0x387c028a,
- 0x2699e695, 0x0d7ef1e6, 0xdf0535ef, 0x01db477b, 0x0351cf5a, 0x5f809af3,
- 0xa5de773a, 0x98dabfa0, 0xff107264, 0x71d7ba8a, 0x1910fdd9, 0x1d577d0f,
- 0x2da33682, 0xd606bac6, 0xb8c8cab1, 0x768bab7f, 0x5a27fe20, 0x2fc4f43a,
- 0xc47a5d89, 0x674159e3, 0xdfc9f1f4, 0x2744624f, 0xe9c75d39, 0x7df0ad96,
- 0x79b5fd23, 0x751377c0, 0x1902fe42, 0xcc627d78, 0xe0154b3b, 0x2aeb03cc,
- 0x7f41e9c7, 0x677f8c4f, 0x0ff40e69, 0x4e3f9bae, 0x313dfc0f, 0x732f9dfd,
- 0x5adfd440, 0x0fefc557, 0xbecbe77c, 0x5bac0fd0, 0x4cdfefc0, 0x59decfbc,
- 0xf30e3d57, 0xd65eeffb, 0x07fe7c0b, 0x57ef2e64, 0xba51cadb, 0xc67148fa,
- 0xcf3544b1, 0x1ef80ccc, 0x8eefdb57, 0xa9759da2, 0x41a770f5, 0x8e470f53,
- 0x8dbf0131, 0x12c57c17, 0x8c0ec8e3, 0xaf1bf413, 0x18fed3f7, 0xf84fc99d,
- 0x58358ebd, 0x5b006f91, 0xf6152eeb, 0xaed07f7c, 0x724bf969, 0xe80cb632,
- 0xe256292d, 0x98cb5593, 0x3f768cdb, 0xf1d78758, 0xe1733c3a, 0xd47855fb,
- 0x0b80f7f7, 0x85b7ab48, 0xe681b5c2, 0x1ceae151, 0x7945e512, 0x0aa7ed52,
- 0xf5d4a757, 0xb7bf262c, 0x013fbda4, 0xdb19d6e9, 0xff412595, 0x4423a4c5,
- 0xaea4cec7, 0x48472567, 0xa8e9c0df, 0x38c5727b, 0x19e7bc2f, 0x024ba9d9,
- 0xf91946fc, 0x8c26933e, 0x8f3de057, 0x58bdb924, 0x73be03df, 0x32ef91f8,
- 0x4687a48d, 0x27e6d50d, 0xcf9c492c, 0x3a3b459a, 0x30feb9aa, 0x9b67a5f0,
- 0x78c056c4, 0x236ec5cf, 0x6d8989da, 0x684e8c27, 0x309db6eb, 0xc3aabea2,
- 0xb753cc3e, 0x6f5118c1, 0x7992486d, 0x0fcc329e, 0xe0399bde, 0xc7dc44a1,
- 0x45512950, 0x091ddeee, 0xef7fb1a3, 0xf8255c5c, 0x8eb7232d, 0xb966c7c6,
- 0x76c21fda, 0x8bd8eb0e, 0x2dc3342c, 0x99d2fc6b, 0xbf1a31d5, 0x5dbd5676,
- 0x0cd39fd3, 0x9eb901d4, 0x1b5d2cb3, 0x5b88303f, 0x2c199e01, 0x6dfa87f8,
- 0x8ce3a0ba, 0xdc01b5d4, 0x6dc332c7, 0xcc8476f0, 0x856db137, 0xd77086de,
- 0xbf520e4b, 0x73e0a65e, 0xa10af933, 0xeb437bd5, 0x795ba362, 0x86aea332,
- 0xd815fbfb, 0x5456bc07, 0x42453e4b, 0xbee9183c, 0xfba255a7, 0x47c7d69e,
- 0xcf323ee1, 0x26f28952, 0x3c447dc9, 0x1cefec24, 0x51e82b01, 0xf333ce03,
- 0xa3b312fb, 0xbefe10de, 0xe99cff0a, 0x3f89a7e5, 0xaeaf9f85, 0x7602ba73,
- 0xc9cfae17, 0xfe80c4fe, 0x64efac35, 0xda9f0687, 0x6d7aacfe, 0x6d32ce7f,
- 0xf0926a7f, 0x81b207df, 0x93d34f28, 0x55ea3d24, 0xe645ffb5, 0x01f96ffb,
- 0x6bb2cd9e, 0x8d67f226, 0xa8f54fd1, 0xfa9bb2cd, 0x5eb87dea, 0xc0ee48c7,
- 0x9639201f, 0x19573e48, 0xf412d69c, 0xe2256ba3, 0xc42c99db, 0x8e09c85f,
- 0xb3dcbea7, 0xd71268ff, 0xaeccab3b, 0xdb1754a5, 0xc1375929, 0xa77a51a5,
- 0x55c0fd1e, 0xc8bce452, 0xdedc4963, 0x8a20c5be, 0x2006b807, 0x9f5da293,
- 0xc2f3ef1a, 0x76fc077b, 0xfbfd17ae, 0x07c08501, 0xb73dca0a, 0xbd85e337,
- 0x25fe0499, 0xe4037ffa, 0xdfa4e996, 0x495a346f, 0xa43b0bbf, 0x2fe70bea,
- 0x7c6876b4, 0x3f8a7ec6, 0x7b5fad26, 0xff62f50e, 0xc782ce7e, 0xcc47be01,
- 0xec8ffdfc, 0x2fb87c90, 0x3ed06ea7, 0xc0299fd2, 0xbadef816, 0x5b47a154,
- 0x52aefbb5, 0x2e61af50, 0x7a20c27f, 0xe5499a6f, 0x41e92776, 0xbbaa5fc9,
- 0x4529fa04, 0x0ca6f7bc, 0xbc95f085, 0x75c245a8, 0x0aef3267, 0x463fe3b4,
- 0xb60a4c21, 0x8fcfed57, 0x79fdc292, 0x65e6124b, 0x148c3b52, 0xe32eb1ef,
- 0xeba7943f, 0xf2327f39, 0xb0fcf859, 0x0757aa7c, 0x718bf2e3, 0x77b9af98,
- 0xdc6fbf67, 0xb49b24ef, 0xaac1b771, 0xe7c7bb8d, 0x44cff569, 0x4cef5687,
- 0xb9a7ee2e, 0x5039c53f, 0x796a7f73, 0x877fa6a1, 0xf8cd66eb, 0x6997a6bb,
- 0xe3a951fa, 0xda00f2c2, 0x9e4c4afc, 0xeb12bf36, 0xa251e6d0, 0xba7afc0e,
- 0x9a317804, 0xc06e1dbc, 0x46c81343, 0x47682db1, 0xa899c606, 0x685d1b48,
- 0x34db60b6, 0x7c8fca24, 0xc787d4d2, 0xbe0751e1, 0x7987ea9f, 0x4c5bf14c,
- 0x49788a58, 0x8a6295f2, 0x7544d018, 0xd41e1bd5, 0xd3d39bfa, 0xeda95cb8,
- 0x99f724b1, 0xbc1bac64, 0x7f73a4a8, 0x89f14036, 0xbf719a29, 0xfc89bb68,
- 0xbe4e3522, 0x9465a71c, 0x0eba409c, 0xf549d07a, 0xaccad613, 0xde7c5798,
- 0xdba9f228, 0x41dc3ef9, 0x673a1dad, 0x492f7c88, 0x49e0fae6, 0x9c58e957,
- 0xac0daebf, 0xfad3ca2c, 0xa7588c8f, 0x8f6b6bac, 0xef967b43, 0x7988c8fa,
- 0x6175e0bb, 0xd15df4e7, 0x55f95f58, 0xff711c8b, 0xf7cc92b2, 0x7a13ec6b,
- 0x83f7d67d, 0xb0c951f1, 0xb59e7ea0, 0xc32fcbb5, 0x5e8167fb, 0x4a6bf2f3,
- 0xfa0d3d24, 0x3ccf1359, 0xa7eea699, 0xc1ec6a71, 0x037ec5dd, 0xed6a9fd9,
- 0x78d339f8, 0x5c7a045c, 0x91a33d7b, 0x1d630bf4, 0x815bcc06, 0x8fdcd75e,
- 0xd271164b, 0x12e83640, 0xaea381e8, 0x2bb5fbc8, 0xc744f4d3, 0xa232eea3,
- 0x4f8093c3, 0xec9f97f4, 0xd78e3f81, 0x65ede12b, 0xfa1081e4, 0x4fab8f85,
- 0xcbf47ee3, 0x07ede8bd, 0x979f7d04, 0x54a80502, 0xe268ae3d, 0xb9a699df,
- 0xf73f718b, 0x1aafccbe, 0xeb315eb1, 0x7b4312d7, 0x03f687fb, 0xb8cf8fb4,
- 0xee326f75, 0xecb4f4af, 0x7fc0664d, 0x05650635, 0x1fc0f3fa, 0xea7ff40e,
- 0x7f04fd5a, 0x3b614b6d, 0x956daf5e, 0x3d92a81c, 0xa18dcedb, 0x468eb275,
- 0xdf3dffac, 0x93235c0b, 0x5b755fb9, 0x04f3c2b2, 0xda27786e, 0x3e516dfd,
- 0x00fc849f, 0xdae109fa, 0xe866b121, 0x14dabf3f, 0xa0fbeeb1, 0xd59ef7c0,
- 0x6ab38a46, 0xc75c79e0, 0x467dccbe, 0x56d3f213, 0xeb849758, 0x0c477c38,
- 0xc0d4bfce, 0xe150cfd0, 0x3819933b, 0xb0ffeb8e, 0xb81d0212, 0x2652aabe,
- 0x54b87f7c, 0x9fe723e4, 0xb8c74c6a, 0x77ef96a6, 0x4dd95ddf, 0xab0fbe79,
- 0x36569fb9, 0x397240df, 0x57f70963, 0xe55af9c2, 0x9f05a7db, 0x386ff386,
- 0xd7e0f6df, 0xd7e3abea, 0xe6bf20ca, 0xfa07dda3, 0x3e414e8f, 0xeeff01fa,
- 0xddc5fa65, 0xbb801486, 0x81d5a36f, 0xcb06bdfb, 0x519287be, 0xf7e6ec6f,
- 0x946cd487, 0xee51feb8, 0x37a5f5c6, 0x091ad919, 0xedd389f9, 0x85374101,
- 0x14314975, 0xa2fa05ff, 0xbf51ca9e, 0xe9b03087, 0xa73f315b, 0xf067fae7,
- 0xd71ba96b, 0x6e6ff084, 0x555be732, 0x32340e2f, 0x07aa56f7, 0x0299f4b4,
- 0xe06cbcf3, 0x312c9cf5, 0xaebf6e5f, 0x5da05331, 0xe4f5cc9f, 0xda87010a,
- 0x80e4275f, 0xf84ddc65, 0xf8e2689c, 0x5fccb71f, 0x99f8eb81, 0xea30fdd1,
- 0xef5909d5, 0x6bdda0d7, 0x20e6fbea, 0x07321fca, 0xbc6ae1f9, 0xa7c47bbe,
- 0xf583ee1b, 0x268faf9a, 0x3e779afa, 0x367e456e, 0x714d0ee7, 0xb53fe047,
- 0x61c85cf5, 0xd5f03b6e, 0xaad47e85, 0x4ebb29fd, 0x729f691b, 0x2431b9db,
- 0xe8d2172f, 0x535cfaba, 0xc1cf971a, 0x9aa83f62, 0xadbd04cf, 0x8e082e2f,
- 0x70c0f153, 0xc2115e77, 0xebd102f3, 0x086c25be, 0x4e3fab4f, 0x73599feb,
- 0xf30b9a58, 0x1a7065dc, 0xf7ef802c, 0xc62fa7e3, 0x2e6f2ffd, 0x851dcc67,
- 0xcc4ceffb, 0x03ee1d7d, 0xb03f52b4, 0xeffa953c, 0xdda8572c, 0x84bd7262,
- 0x4f63ba78, 0xabed2e7d, 0x55ca7ccc, 0x3ce9ef0a, 0x053b1068, 0xa827e44d,
- 0x36eea1f5, 0x7ee09999, 0xea8936f7, 0xb3fc2a9d, 0x3733a42f, 0xe3df97e8,
- 0xdac1e0fb, 0xde92ef65, 0x1b9f5473, 0x90d27183, 0xd88d139a, 0xf3fb2cf7,
- 0x8e2ff418, 0x3e413d83, 0xa59fbf03, 0x0e4fa84a, 0x5ddf711b, 0xcd3b05c5,
- 0x6baeb2f3, 0xf79dca0c, 0x50ea890d, 0x19cf5bc7, 0x62bdb853, 0x5806ca08,
- 0xffe0139f, 0xeb813922, 0x3a21b693, 0xdca1df4e, 0xd0fc11af, 0x71d7c37e,
- 0x32d30f48, 0xf19bede5, 0x4332fdf9, 0xda535eb9, 0xa08d6715, 0xbcc28f87,
- 0x75c15c98, 0x7f7e1b60, 0xeb9bd1ba, 0xeba6e780, 0xfa9bef22, 0xbe72f92c,
- 0xff14e482, 0x0ab7e024, 0x60b36fc1, 0x8a36f149, 0x20d1fc83, 0xcadab3cf,
- 0xadb1eb4e, 0xda47d897, 0x147d8cf8, 0xc6f7c7e2, 0xadb6df87, 0x8372f9c3,
- 0x59238c7d, 0x71845f88, 0xdfbcd324, 0x994cf3cb, 0x11dc53fd, 0x0e5979d6,
- 0x03bfc03a, 0xe381d57a, 0xdf91d8a4, 0x767b5207, 0xca0ac3c7, 0xebba298f,
- 0x6c17b429, 0x8ee28e80, 0x1fd6af5a, 0xe5ca963a, 0xc0aa58e1, 0x7e368a5b,
- 0x4e493882, 0x1c5271e1, 0xe2438416, 0x14ebf0a7, 0xae50993f, 0x8103bde0,
- 0xa244af3e, 0x29a96a4f, 0xabe50925, 0x019cf899, 0x857f239f, 0x229ed3af,
- 0xae42d9f2, 0x235ca067, 0xb972b6ff, 0x3bb79f0e, 0xf38ec4b5, 0x5c7dc6ae,
- 0x69c6f411, 0xf5daceb1, 0xb3cbe112, 0x3a784ede, 0x4abbd6c3, 0x00cf2f81,
- 0xa02fb81c, 0x498ae5d3, 0xdb8d7ac0, 0x04b36315, 0xfadd40f5, 0x756e7a18,
- 0x73eddbff, 0xc2979fa1, 0x6b6cfef9, 0x3cf10999, 0x3f973d7b, 0xfdc77df5,
- 0x4f28ec33, 0xa32e8645, 0xb467ee03, 0x3f43889d, 0x54c768b0, 0x6f61ca3b,
- 0x70a86670, 0xf16fbb2e, 0x07e73b49, 0xf5aa6fcc, 0xbf4acf38, 0x78bff111,
- 0x6dfe2319, 0x3a87fedf, 0x6db3e394, 0x87b45631, 0x78c67667, 0xbe77ff51,
- 0x49d3e511, 0xe3788714, 0x319daf41, 0x7f224c74, 0xc56c8773, 0xc6f3d1f8,
- 0x3ca14fe7, 0xa147b67a, 0xb716c7e7, 0xed0e7c3d, 0xd8db4d5e, 0xda7cfad3,
- 0x954ffe87, 0xf765da87, 0xfed57ad3, 0x0a4dcbe7, 0x7ab3d1ea, 0xb71627ae,
- 0xeffe4abe, 0xf9dd8be2, 0xb33f0f58, 0x50c36ff3, 0xdb7e79af, 0x99f50c3d,
- 0x61eef5e7, 0x5af3df78, 0xbf247d4c, 0xf3c697c5, 0xccbdaa40, 0xe4d7a239,
- 0x5d85a28b, 0x2e6869c8, 0x459d7dc7, 0x3039a787, 0x2fdeab9f, 0x7ed1d5ca,
- 0x46f7a2fe, 0x3c87e7d9, 0x97d010d7, 0x87a1f5e3, 0x8654c547, 0x41aa65f2,
- 0x555e37cd, 0xeaef079e, 0x75e48587, 0x19a73a02, 0xe80eadc6, 0x6adafef9,
- 0x06f187c9, 0xcfe12ff8, 0xb9d53f91, 0x435beed0, 0xfc6b827e, 0xcfd8a1e0,
- 0x5051ac75, 0xf6f698ad, 0x6697f10f, 0x28fe7404, 0x6de9a3e0, 0xf7f27e51,
- 0xd413fa03, 0xecd47e17, 0xe6c69f73, 0x34f21148, 0x468cef79, 0xaf9e1e3d,
- 0x8458bf81, 0xdeaff55b, 0xa3f9e34f, 0x0eab7a8c, 0x345667f7, 0xb5e22b30,
- 0xfa675e47, 0x0a2f946d, 0x8128efcf, 0x4e7c2675, 0x22b3afe9, 0x8a5faabc,
- 0x4116dc74, 0x72a6240f, 0xaf9544bf, 0xe88e8086, 0x352810d3, 0x563687f5,
- 0xab36d7c8, 0x68f7be8e, 0x09ba9b68, 0x170d0bf3, 0x0c198aef, 0x723869ef,
- 0x3defc33b, 0xa6a5ad3a, 0xe2ee7c5c, 0x063ba66d, 0xfc26f905, 0xb852c77d,
- 0x0bfa0cde, 0x21dfed91, 0x59fecfa1, 0x8a40f076, 0xff3de44e, 0x1083b6ef,
- 0x7852079f, 0xe7933e7c, 0x1e7c784f, 0xbd543f6e, 0x092bceac, 0xcbd4f73a,
- 0x81cfc9a7, 0xb2f49a38, 0xb8d0aa94, 0x7629b68c, 0x4c8faf8a, 0x9e962bb3,
- 0x3bd3f7f3, 0x3d41b674, 0x39fd57e7, 0xd7b9d78f, 0x938f7184, 0x4cf323ef,
- 0xaddf6893, 0x5c79ffea, 0x9ee5f912, 0xc70f830a, 0xa60570a9, 0x1dec7cf1,
- 0x2ccf834e, 0xd544fd05, 0xdf7cbc8f, 0xd57dd121, 0xc7fd54af, 0x77e78b80,
- 0xf7e50da7, 0x17dc98b7, 0xf71f2ed0, 0xd17ae99b, 0x319d7e08, 0xab8c5ed7,
- 0x6253baee, 0x5f8407a4, 0xb869f2a9, 0xadbe79df, 0xa3ee37df, 0x53f820df,
- 0x30acb395, 0x58ed50f9, 0xc7970a5e, 0x85e3b43a, 0xaaffc768, 0xe7c3cff1,
- 0x496e3b05, 0x3d18e7a5, 0xbd3df43f, 0xfebc522b, 0x0ca790ac, 0x3d817e95,
- 0x266f0825, 0xd83ed00b, 0x7c6becde, 0xded7971a, 0xb909e7ee, 0xdf3c92b9,
- 0x3fccf426, 0x52cb9e4b, 0xb5f877ff, 0x5ec3fd97, 0x2cfbc7be, 0x2a4264b5,
- 0xae5a35e0, 0xfca0940f, 0x6221a7fd, 0xd85d3add, 0x3577886b, 0x699bd9f4,
- 0xe47c61d4, 0x83f9e6a9, 0x6de504a6, 0xc80e638a, 0x317b3fb4, 0xc7e883c4,
- 0x4090ba2d, 0xcbfa0d6d, 0xf17cced0, 0x6623d530, 0x6fe16b56, 0x3e2e9cc2,
- 0x87c724bf, 0x362cf3fe, 0xb34cf28a, 0xb8ac12da, 0xa929b9df, 0x95ca1f65,
- 0x6cac9377, 0x50bf1d0a, 0x79e26f1d, 0xb46965b8, 0xf98592bf, 0xc3eab303,
- 0x7fad7efd, 0x1bc8b370, 0xbc27e6f5, 0x7ae66ede, 0x724cbf65, 0xa6f9875e,
- 0xb633191b, 0x59e0bd71, 0x7524f3c6, 0x7be82b6d, 0xff715aac, 0xf2807d33,
- 0x835f5450, 0x1edba7a1, 0x6479464f, 0xa93d6d4e, 0x48f785f6, 0x95d7865f,
- 0x5eb8db6c, 0xa2c8d4f2, 0xc24c348e, 0x93c42d7e, 0x2a5fe829, 0x3bc464ca,
- 0x57d9a5c0, 0xcf05faa6, 0xf9d2ba8b, 0x1c531ffd, 0x2f47733a, 0x71a6a475,
- 0xf6248ebc, 0x23acf46f, 0xae9bdbed, 0x548eb95c, 0x80d87ad7, 0xea95c5f1,
- 0x5ea4cf49, 0xde5127ae, 0xf3cf5b31, 0x926dd9bb, 0xd955f315, 0xc3dd7c6d,
- 0x7f934757, 0x958fe63d, 0x2a07d476, 0xe14ece9d, 0xe1fb3df8, 0x75b42597,
- 0xab7a8fe0, 0xfaf5d619, 0x4ddf4b87, 0xa4c57de7, 0x634b73e0, 0x3fe9bbe8,
- 0xf8831bde, 0xa45a1d7d, 0xf5476bcf, 0xc193f391, 0xa92bf57c, 0xf9167794,
- 0xc3d83d6a, 0x275e60d8, 0x855bb9fc, 0x70826bbe, 0x3b9af285, 0x29bfdd78,
- 0xfa8e3dcd, 0x36cbeb3f, 0xa4e89f91, 0xc0abf47c, 0x1a3798d7, 0xbac58b08,
- 0x59a32ff4, 0x9a91d603, 0x926fdc92, 0xa74cfd1c, 0xf3c11ca0, 0x6ef27f54,
- 0x623ec855, 0x3ceb0bea, 0x858046f9, 0x7df03bf6, 0x3a083713, 0x8b3c41a6,
- 0x33402571, 0x03d0eb0d, 0x3f27bd45, 0xfe71e99a, 0x35ee0c47, 0xa97d63d7,
- 0x4158ef5d, 0x4fb0e042, 0x7759ed89, 0x5ebc9c92, 0xd49fd6ae, 0xf56f79ba,
- 0x93df0927, 0xea8ff9cf, 0x9cff624d, 0x7762675a, 0xb5f8a8ba, 0x619eb8aa,
- 0x832c3afc, 0xd2faeb5d, 0xd42392df, 0x4c294c7f, 0x7ada67f8, 0x57bc9ae3,
- 0xdeff4f88, 0xa96de33a, 0x1efb1fec, 0x0adc07a6, 0x0c322eff, 0xe709a1ee,
- 0xfaee2993, 0x91c4bfef, 0x26eb6d9d, 0x15d9d87b, 0x7f9402c5, 0xf779e0ec,
- 0x503dfe36, 0x496fc427, 0x7e767621, 0x57779f0a, 0xfff1195b, 0x18a8c0b6,
- 0x0a58ff1c, 0x23eac7a7, 0xbfa2a6d3, 0x69e80def, 0x3c630ebf, 0xd016db1e,
- 0x72dfa117, 0x9a92e90d, 0xd12e891a, 0xcb853edc, 0x7f6121d1, 0xba72a50f,
- 0xe3c87d95, 0x5e52cf30, 0xbd0ab15f, 0x75e7a9e0, 0xc9997df5, 0x4f4f9a92,
- 0xd97f5489, 0x637645d1, 0xf68942d6, 0xfadb7ed5, 0x916913cb, 0x5b33f1eb,
- 0xbfae444f, 0xfd218f94, 0x3b3e5bd9, 0x4b7d8f3c, 0x0f63c89a, 0x5fec79e6,
- 0xbd695aa5, 0x2521fab6, 0xfaeab2c8, 0xbe1d21af, 0x87408b48, 0x5c7f386b,
- 0xdf5b77fa, 0x7d5230fd, 0x6fce1af7, 0xe16efe4b, 0xa7e92257, 0xf3bf386b,
- 0xfd7f9e3b, 0x8aff3c77, 0x77ff18ef, 0xff9844a5, 0x01fdd5ff, 0xf0fff5e1,
- 0xfbe102fd, 0xcc0ea200, 0x87bde2f7, 0x7e5db5a5, 0xdb714d68, 0x07a04ba7,
- 0x982f09f5, 0x184e8ed0, 0xab61ebc1, 0x1b7c9947, 0x01bee0a5, 0x832c5f15,
- 0x41d611c7, 0xc076bce7, 0x30339673, 0xb2f98eca, 0xe0e28c11, 0x8baf334e,
- 0x6d35bd31, 0xb7c3ed0a, 0x7e0edda6, 0xdf2f5349, 0x174e6d33, 0x762f6171,
- 0xc9466464, 0xacefa867, 0xd5a5fb61, 0x6aea29d6, 0x0fbe56d6, 0xb495e997,
- 0x4abde9db, 0xf143fa1a, 0x38f5f87b, 0x246e733f, 0xdb9c94b8, 0x72541e29,
- 0x4427be10, 0x6e36d7fd, 0xa5e60e40, 0x6217e06d, 0xac71f05d, 0x6b3c520f,
- 0xfbea71a5, 0xbf87d87e, 0x930309ef, 0xbdeb9eb0, 0x6273ef9e, 0x5d4d6a96,
- 0x7fc1a0ef, 0x7544ae72, 0x8c0fb93d, 0x0ff3a43f, 0x30473e7a, 0xd077e031,
- 0x1bd52b36, 0x1ff11adf, 0x26bbfc79, 0xcfbbe75e, 0xc6ec87ca, 0xb8e019b8,
- 0xf121676f, 0x235dccef, 0xf8c0a83e, 0x2f3f3fa3, 0x295c47a4, 0x454705f2,
- 0x17cd43be, 0x63adf5a8, 0x1c724f22, 0x76d02ff3, 0x5a043e60, 0x5aee8fa5,
- 0x4fa527db, 0x84f2fd04, 0xde43f3c4, 0x543f3c43, 0x0bf47468, 0xb8394fdd,
- 0xb9abe70f, 0x50bf5e7e, 0xc59b3df3, 0x207f0a7a, 0x2fc0a3fb, 0x6c1c6c2d,
- 0xd85f3b44, 0x6d8d1998, 0xc3a7d3be, 0xca8cef52, 0x7e953aad, 0xb868f891,
- 0xfdeae758, 0x7bdf545d, 0xffeeac35, 0x3f7c3ec3, 0xc7e0b743, 0xd461f61f,
- 0xbf572fbf, 0xf8c7dd0a, 0x52395691, 0xc416695d, 0xdce708c5, 0x8ab70e26,
- 0xa57e59ef, 0x6273df0c, 0xb623576f, 0x6539d505, 0x39af7794, 0x9bfe88d7,
- 0xbef762e7, 0x665f295b, 0x989e3054, 0xbbcda1dd, 0xfe7832d9, 0x7f8955fd,
- 0xab1de9af, 0x70b8f8a7, 0xc7f89eac, 0xf14ccb36, 0x64c0cdab, 0x70a7f60b,
- 0x3ca0a8bf, 0x6cfb0cb1, 0x83f9025a, 0x8495fb05, 0x798283f9, 0xa5d8db30,
- 0x2ba78849, 0x7cd559d5, 0x739316da, 0xeff3d23a, 0x1ed6b3ad, 0x4dfb423c,
- 0x78a975d5, 0xbda5eb51, 0x7dd559d5, 0x2ff29e0f, 0x3c34fb35, 0x9831aefa,
- 0x79dc2c7f, 0x5ff628c2, 0x8273535a, 0x1dc2d875, 0xaafea8e7, 0xf53d5bd6,
- 0x86afc8e7, 0x929ce8e7, 0xfd79cb6d, 0x81c03b75, 0xdbac2b6d, 0x06fcf009,
- 0x1b6d8dd6, 0xbfaf1bac, 0x5a8f3cb1, 0xb50772ff, 0x531796bb, 0x93ec085b,
- 0xedbac366, 0x2edbaa39, 0xdf63d3ef, 0x36f5d524, 0x2895aecb, 0x3f7521ef,
- 0xfdd787ea, 0xaf9e68e4, 0xd037ecf1, 0x839e0c77, 0x25dfd226, 0x31b3736d,
- 0xb0eaf83e, 0xaee11b3b, 0x085bbac3, 0x3a759c5f, 0xc66e78cc, 0x8cc39759,
- 0xf6c2b6f5, 0x0fdc46d3, 0x180fa753, 0x90061f31, 0x4596e3a7, 0x7c73b6cf,
- 0x895b6fdf, 0xc57bf119, 0xffeb58fa, 0x3dfd8faf, 0xa0acb1f5, 0x291e927c,
- 0x1b9ce970, 0x34efddb1, 0x13d10fcf, 0x9ebc5dab, 0x5f7fbab2, 0xae75c392,
- 0x219509be, 0xf39435f3, 0x6c6d85fc, 0xf5e8737f, 0x1e061925, 0x4239e047,
- 0x41ffde11, 0x8e35dd1f, 0xf41fdd5f, 0x9d57e089, 0xefa2643d, 0x2c77da49,
- 0xc418eec8, 0x1f343f05, 0x32bcbab7, 0xf7cfbf1b, 0xb9628d1e, 0xc9a75f3c,
- 0xbab0b1c7, 0xb9796f5c, 0xa73ae599, 0x750bf699, 0x0edda165, 0x7d319fcf,
- 0xebb71657, 0x9e7e74ce, 0x159d3783, 0xb9f51eb3, 0x7bdf33df, 0x8cfc61fd,
- 0x0bd91d72, 0x50574eb5, 0x81cb67ae, 0x19960b3f, 0x2b9f547c, 0xfba09fd7,
- 0xb06c6e22, 0x9f23a416, 0xb4683f1f, 0x3c2d5e62, 0x7f28e63f, 0x3c2fa9a1,
- 0x1c91a8ef, 0xd52bacb8, 0xe07dd4f1, 0x47db5ab3, 0x086dbe63, 0x051a6e6b,
- 0xafe90fcf, 0xe9fee2b3, 0xbe3cf59e, 0xf840bbff, 0x3679e139, 0x4bf433e4,
- 0x71f0f3c2, 0xe20f9ce9, 0x9cfdb9d2, 0x0a2db480, 0x173ea3ce, 0xd2f33fce,
- 0xf0bf75b5, 0xfdc553fb, 0xd582f286, 0x13be91fd, 0x49ed0c74, 0xa9a97943,
- 0x397cc87f, 0xdb7f7ce9, 0x4c1f5813, 0xf20fad0c, 0x5d78603a, 0x8573d550,
- 0x831d7fed, 0xfa075ef8, 0x2798ed1a, 0x0a0fd795, 0x8fd928df, 0xa708237a,
- 0x7a953fd8, 0x04ec7bf9, 0x70c5d7c6, 0xa7779cff, 0x82b9f944, 0x8aee5f09,
- 0x81733e81, 0x76bd43dd, 0x0b2affb0, 0xfa09a3ea, 0xc7aefc22, 0xd72e92e3,
- 0x349eb099, 0x71eaedf5, 0xe1419df8, 0x230e431d, 0x30a8ee5d, 0xd540fed0,
- 0x7b7d4dee, 0x7f7e18fa, 0xbc68cae3, 0xcc39279f, 0x2f2f5e0a, 0xb7e3ebc5,
- 0xce9331f8, 0xa0742226, 0x4f0703cf, 0xb66e51ea, 0x1825dc98, 0x114e173f,
- 0x6e0aa675, 0x9b68efa7, 0xe7e46062, 0xeee6ed69, 0x1f28afcc, 0x4856ddd4,
- 0xee3b23f5, 0xb414187f, 0xc13b8537, 0x3b5ec58e, 0xdd2f363b, 0x11bcf84a,
- 0x63c218ec, 0xf4ebc29b, 0x11cff4e1, 0x2ecdeff4, 0xd187a6f5, 0x2b39e0fe,
- 0x6a529f28, 0x60ae3b4f, 0xfa3867de, 0xc21e12eb, 0x35ff2bd2, 0xd096fd0b,
- 0x4eb73f8b, 0xfbaf7bf0, 0x39ff5aa7, 0xf4e6a675, 0x63751dff, 0xeb52fe35,
- 0x76bc6a4d, 0xda81f046, 0x3fed159e, 0x1a037dfc, 0x37df88d7, 0xdf7f22d8,
- 0xce85bb30, 0x6fbf5129, 0x25646bd8, 0x3f71135b, 0xc9def8ad, 0xa4fc8537,
- 0xbeff4fbd, 0xf88917f1, 0x278493bd, 0x3c3d806b, 0x3d5e764c, 0xedaeaeaf,
- 0x6d6f9e73, 0x6bc3fbe1, 0xfb9f235b, 0x77da0372, 0x2728ef78, 0x2b51bd23,
- 0xd98edbf6, 0x9744ea26, 0xebf796f3, 0x1e96f343, 0xeea49025, 0xbc51f5e3,
- 0xf663cda7, 0x53acb796, 0x96afcfbf, 0xae1f681c, 0x59b70fb4, 0x35edd7ec,
- 0xe6fce98f, 0x79e1b97d, 0xb5d3f7cc, 0x69939c75, 0x74ff5a56, 0x36e744b7,
- 0x1aae7499, 0x86ffb7da, 0xcfb48d64, 0x87610bfb, 0xc83a8bc6, 0x3f9c8dcf,
- 0x44937e7e, 0x77e0dfdf, 0x9ff74878, 0xc3bfc1bf, 0xff0179f9, 0x7bad470e,
- 0x5cd7dfa8, 0xd07bac1f, 0x77ea77f7, 0x3677ea39, 0x539d77ea, 0xb9d347d6,
- 0x5a188fc5, 0xebdfb952, 0x3a7cbe25, 0xe8fdd19d, 0x491f5628, 0x97a68f5e,
- 0x845e9d3c, 0xdc79aee3, 0x423d297b, 0xe30c3bdc, 0x218f7848, 0x3c85e203,
- 0x305e2916, 0xe2691465, 0xc787ea05, 0xeeaad70b, 0xcfc0a4f1, 0x6df75c35,
- 0x6bc6fc91, 0xdfebff38, 0x45affcf1, 0x732adba2, 0x1f17f3e4, 0xbe8490cc,
- 0xce179ed7, 0xc92f7c7a, 0xa4937aed, 0xd533707c, 0x4f540dd3, 0x536af557,
- 0xbc7f9f2c, 0x6da9a7c8, 0x0c9b6895, 0x4b65f391, 0x6467fdc4, 0x93e438e7,
- 0xf36a2f81, 0xb45b8397, 0x5b1bcbf9, 0x0c88e7b5, 0x09cf6bf1, 0x3dafdc29,
- 0xa028a63f, 0xf8663f3d, 0x31f9ed51, 0xe7b43a23, 0x99fcdcc7, 0x5b98fcf6,
- 0xcbf9b4ba, 0x1edc2f5b, 0x8fa71df6, 0x9c09479f, 0x995cfa1b, 0xb9d85e69,
- 0x73b0ba35, 0xcec3a26b, 0x1f3b09ad, 0xe39bcc45, 0x7e7613ed, 0x367d768d,
- 0xba0dc7ac, 0xefdc7afa, 0x1ea228fa, 0xcf8ccfd7, 0xdfde513d, 0xfa9b7e8c,
- 0x097ff53d, 0xe1913b3e, 0x71f4815e, 0x875b1caf, 0x22b1d57c, 0x2ef30b2a,
- 0x726995ee, 0xfb83f022, 0xa7be8951, 0x46995d2f, 0x35e67bfb, 0xa93f210c,
- 0x4fc93980, 0x1167659a, 0x9cd879cf, 0x3decf5c1, 0x8c6606f5, 0x462997c7,
- 0x33d0a81d, 0xc35b124d, 0x22658ded, 0xe33561f0, 0xfabb587c, 0xbdd51c70,
- 0xc859dd85, 0xebaac151, 0x0e79d017, 0xa8bde7e1, 0xc623c676, 0x6316b0d5,
- 0x68bbcc1a, 0x47c93b6d, 0x1e3079f8, 0xea1cf6b6, 0xb096dae1, 0x7db7f5eb,
- 0x1ff7f8ca, 0x3c8bf446, 0x2ffbdaad, 0x99ba8864, 0x7e503983, 0x9ac7f7dc,
- 0x152ccfd0, 0x56bb99f8, 0x709d62b2, 0xd27b435e, 0xb79fd05d, 0x4bb8a65f,
- 0x71eb0fc5, 0x3a20cf4e, 0xfefcfd57, 0xcfa3f25c, 0x8e0a4a2b, 0xb8f1c773,
- 0x87bbd241, 0x7659f5e3, 0xe73c70f7, 0x58c3ebac, 0x9d87f6fc, 0xdf9320b8,
- 0x3e50be00, 0x96566ff9, 0x9def9a1f, 0x6326b06b, 0xeecbc5be, 0x5378a54d,
- 0x7e2abfc4, 0x6788263c, 0xf10fb0e3, 0x749f5f2a, 0x91fa2249, 0xff02eb69,
- 0x7e03df08, 0x26b3c510, 0x7e815a66, 0x39a569d0, 0xd7605d19, 0x2ff20643,
- 0x4092d9ee, 0x0d3dc5fe, 0x1f3c4665, 0x096d9ee1, 0x79969fb4, 0xbe30479d,
- 0xa279e955, 0x2a5f70a1, 0x4b4f7bcc, 0xd2d6438e, 0xd137e4f1, 0x09d35171,
- 0x7b277e95, 0x48c9dfa1, 0x69ba03f4, 0x4321ffae, 0x6e8209f8, 0x7d3b41ec,
- 0x64b157e7, 0xffe62e6f, 0xe99bd7ce, 0xc67a2bf7, 0x37ae5e05, 0xc4d26f2b,
- 0x2e7de53f, 0xbe7475c7, 0x22daf777, 0xdd385fa2, 0xde67ffca, 0x8afefc70,
- 0xa1963efd, 0x1fab31ff, 0xc63b739b, 0xb79712c9, 0x96c6ab59, 0xa5f3bfa3,
- 0x8b6fcfd0, 0xc630e938, 0xbfd7e049, 0xf412718b, 0xd27113df, 0x41271807,
- 0x49c621fb, 0xe7149ed0, 0x0772aa05, 0xfb7c408c, 0xafb790b5, 0x6378d433,
- 0xd7e62a69, 0xdde7ffca, 0x5f159d22, 0xa349e3f5, 0xec9b1933, 0xd3d7fad4,
- 0xebfd69a7, 0x4c75830e, 0xd581da2a, 0x8f705ebc, 0x78cd66eb, 0x988c57a6,
- 0x857960f7, 0x8f64ebc1, 0x3de62314, 0x6bb04c66, 0x94d9dfc6, 0x32dbe9ae,
- 0x94f75a15, 0xeb9a7ef2, 0xd40c5777, 0x005ee7f4, 0x5df90cc7, 0x59f92629,
- 0xc626e22a, 0xac5d398a, 0xf597ec7c, 0x001e53c3, 0x683cbf78, 0xf4e1fba0,
- 0xb95ae950, 0xee7ca65e, 0xf312f5bc, 0x9b278802, 0x7d7c91e7, 0xce96347e,
- 0x52dc6991, 0xf43156f8, 0xd0316c4f, 0x0d13b2fe, 0x7cf147f6, 0x925b13eb,
- 0x3dbbf0e2, 0xfccca377, 0xa4ad77a4, 0xcb79d577, 0xefd0561a, 0x45f5cc26,
- 0xcc0f5039, 0x567de3dd, 0x4ddfa3ed, 0x4e50665b, 0xbf3ec88e, 0x1273f444,
- 0x299b377e, 0x8199fe4f, 0x92a7f179, 0xb87075e6, 0x0358933e, 0x8f9b4ff6,
- 0xe000780d, 0xb9b13338, 0x957e874a, 0xf489307c, 0x43322be7, 0x6258adbe,
- 0x1787f3a0, 0xc46f27be, 0xd20a933e, 0xfa65bd39, 0x39b60f7d, 0x5d67e68a,
- 0x6e3021c0, 0x9ea22fe9, 0x5ef2235f, 0x60f5ffd4, 0x9fc11adf, 0x259f47c8,
- 0x01026730, 0x7f0ff3cb, 0x75449c3a, 0x7d3e209f, 0xffeeb8f9, 0x64c6bbd0,
- 0x54fefd02, 0xfd27cbe5, 0xc91260f6, 0x4fde3855, 0xf2feb91a, 0x41481ca2,
- 0x339419bd, 0x3cd5fdfe, 0x41d92383, 0x1a686b7a, 0x6b93adea, 0x6467940d,
- 0xaf1c677a, 0x7c42bdcb, 0xa4e7beac, 0xf083195e, 0xa1ca6c9d, 0x59ef0cef,
- 0x43fd932b, 0x7de3e3fe, 0x971fff9c, 0x7bbf18dd, 0xc637249b, 0x737ce1ef,
- 0xf4e192df, 0x11b3047b, 0xea7a2327, 0xbc69b381, 0x17f6a10e, 0x07bfe4ed,
- 0xe87686c0, 0x5d0e0da7, 0x9f7f0347, 0x4e7358bb, 0xdfdf4d79, 0x9c23c71d,
- 0x17efefce, 0x9ce9df8f, 0x9f13223e, 0x3cdbee9d, 0xf9e8152c, 0xb0d76e85,
- 0xf9ffa007, 0x7a27ef44, 0xfbb46fa4, 0x62ebc43e, 0xfc2cdadd, 0xedb3ba6e,
- 0x866f47e3, 0xb2f4fee7, 0xbe6241c1, 0xc7f4892c, 0xb30bcda2, 0x21bbe9bf,
- 0x787dfcc6, 0x2699d1de, 0x2b173e01, 0x9f30632d, 0x84b99f30, 0x51f8e23d,
- 0x86bcf0b6, 0x73cf1d75, 0xbb145c7c, 0x79b4e306, 0x8f8c7961, 0x8d83f7c5,
- 0x6fc69299, 0xf5c99838, 0xe71d3cd7, 0x38b7886f, 0xb1a631bf, 0x5edeaa03,
- 0x220fbf8c, 0xaa80ed07, 0x33586bb7, 0xb3fd6b9d, 0xff34becc, 0xbf47c942,
- 0x27875223, 0x2af8c354, 0x6b638f2b, 0x51f28c5e, 0xe580aa9c, 0x8e0ff10b,
- 0xe7813ea1, 0x7e5f1916, 0x0177d90a, 0x8675f00b, 0xc193fb8d, 0xe9c81557,
- 0xacaa7f69, 0x346c1b1b, 0xfb81c1bf, 0x79081719, 0x7c966dad, 0x25075e7e,
- 0xcc5f3a3b, 0xd1d85f33, 0xc3d4fb70, 0xa3d9852e, 0x977661f9, 0x2ced6b35,
- 0x79e74bc0, 0xc386f0ab, 0x25898ae9, 0xe66a2c3c, 0xdcab3efb, 0x08937dbe,
- 0x1401c96e, 0x02cf01ed, 0x80951ae6, 0xc79178eb, 0x85f0e1e9, 0xbc07abaf,
- 0x70e19d62, 0xd1ce3957, 0x5b35e5f7, 0xf857c224, 0x847a543a, 0x5d2a71fb,
- 0xbf1cbcaa, 0xd1126d55, 0xff65d4f3, 0x50fed190, 0x0b586f95, 0x79e42ffc,
- 0x5d608f95, 0x2dbf5093, 0x38fa0758, 0x2d3f27a7, 0xc8712d62, 0xdfcc7537,
- 0xd3f72588, 0x473b96fe, 0x4e79e0e4, 0xa9dce987, 0x573f9b0a, 0xeca88097,
- 0x96fcb47c, 0xe3879f20, 0xbdf44afb, 0x5131fc5a, 0x00e7a067, 0x905ff35f,
- 0x909ffbe9, 0xf63e2271, 0x7b557c92, 0x3fac46bd, 0xb9f9eb57, 0xd3825772,
- 0xcbbfe7a3, 0x05784574, 0xdc35af3e, 0x7f5a59d1, 0xe577e839, 0x5bd247c6,
- 0x098f3aea, 0x7b45733d, 0xc5dc77af, 0x4927dec8, 0x4de9af98, 0x3b09577f,
- 0x3eed1f3f, 0x7fac9fb4, 0x3c6bce95, 0x3a55eeb5, 0xf2f8d59f, 0xf0b7da7c,
- 0x8f79fac9, 0x7c4fefe2, 0xd91e65b2, 0xab4f05f9, 0x0c6dde76, 0xd6ca1ff5,
- 0x5fee7dcf, 0x345f6f90, 0x6ab95d53, 0x41c45b8f, 0x9c6157a0, 0x51eb9eb2,
- 0xd5eb8eb6, 0x070f6805, 0x0ebc3d91, 0xe55fddc7, 0x3ff90ebe, 0xc9d93ae4,
- 0x7fb9e7fb, 0xbde613b5, 0x8718a5ff, 0xf56c9697, 0xd5b4bcf3, 0xf6b0f68f,
- 0xd38e0fde, 0x07c94bef, 0x6a81fbdf, 0x139e19ff, 0x42ce2ee5, 0xbf761339,
- 0x6598de56, 0xec223b45, 0xdf1b3fc4, 0xc9be20f7, 0xfef8e2bf, 0xf9e389a8,
- 0xef1cb5e3, 0x51fa5b8d, 0x5351fafc, 0x3eabf23f, 0xf84b92da, 0xf8035cae,
- 0xd15abf26, 0x804d55fa, 0x101f8c6f, 0x3dd700df, 0x6f81147b, 0x1377c707,
- 0xcb5b33c7, 0x781ecadb, 0xebf9d2f5, 0x947bfff7, 0xcf84fd03, 0x9ff27ecc,
- 0xd32adb3e, 0xdfaa6959, 0x7f3dfaa5, 0xa2cfcd66, 0x7be2a67f, 0x3e4080e1,
- 0xc78a97ea, 0x7887177f, 0x2795b85f, 0x9be07a4f, 0xbce85339, 0xbfefcbfd,
- 0xce2d27ec, 0xbe93f50a, 0x98ea5d25, 0xd72bf68b, 0xf96639e1, 0xd5a2fb21,
- 0xdf0b3fdf, 0x7cf0ad07, 0x98731465, 0x464f084c, 0xb9b8eff8, 0xfe8bee19,
- 0xecdcf72a, 0xbb8e497b, 0x31c7bf34, 0x780df989, 0x916b019e, 0xed4bbf68,
- 0x257125d2, 0xad2dcf0c, 0x67363827, 0x69df3b71, 0x3f22caee, 0xc714676d,
- 0x359ba8fb, 0x07a4d1f1, 0x423ff11d, 0x3f20e03f, 0xd79278df, 0x49cef941,
- 0xab5243c5, 0xff3ae842, 0xb8d73f02, 0x9cc482ea, 0xc09dfc76, 0x622fb4b1,
- 0xda14f37e, 0x6d055007, 0x5ef8e859, 0x9cdbcfbe, 0xc7a2f3c5, 0x78054d71,
- 0x1df8939e, 0x1a9e713c, 0x370171d5, 0x3a2ecdc7, 0x9278ef6f, 0xc8cfc1c9,
- 0x07dfa78b, 0xc1e85bb8, 0xb47d9699, 0xf1e61c8f, 0x7b9e1b32, 0x0501aeff,
- 0xf1d4c2ac, 0x73c68632, 0xbefe3f52, 0xff5b8749, 0xdf22ac1b, 0xbd92edbb,
- 0x3a413c27, 0xf381cf6a, 0x8fce4744, 0xfdc59abc, 0xa4e9c929, 0xcc14443a,
- 0xdfef0d1d, 0xebf0a59e, 0xdb3bff62, 0xed8cf400, 0x7a9c9e79, 0x39f9799d,
- 0xf0a535b2, 0x67189bef, 0xb21bd424, 0x31afd34e, 0x9e87fbf2, 0x5d793d9d,
- 0x30ef6306, 0xf43f7ac0, 0xff8f1953, 0x70fbc6e7, 0x3c64d7df, 0xad86ca6f,
- 0x76eaf89e, 0x78eaf33d, 0x7ac164db, 0x6a673888, 0x1ddfc092, 0x0f1fccc5,
- 0xa03fefbc, 0x2ef16f3d, 0x1d7fcebf, 0x9e3275e0, 0xe78f9767, 0x2b0629d6,
- 0x2e55c7bc, 0x52bc6015, 0xc1dbf2b3, 0xc2ecf1db, 0x4246ebc9, 0x70e3a75f,
- 0x29e780fe, 0x1efe6266, 0xcf5b30f0, 0x9c05c8f6, 0x8f1788de, 0x207da14d,
- 0xda244b5d, 0xede6a2af, 0x090f7a55, 0x8e89ede6, 0x307c0533, 0x3e1c534f,
- 0xaf4c8c6f, 0xb8d4b22f, 0xede285ba, 0x173e42c5, 0x45b972ab, 0x6c96972b,
- 0x8ff44741, 0x45336f01, 0xf9a4eb0b, 0xd47bc46b, 0xd9cdd773, 0x36737e7c,
- 0xf2ffe38f, 0x598fbe77, 0xaa8ef9f8, 0xf146d67c, 0x4ff7d5f9, 0xb6546d16,
- 0xe155e68d, 0x7fd7cf09, 0xf91561ba, 0x677fd549, 0xdf443ebe, 0x324c5d50,
- 0xea225576, 0x4999efa5, 0x5b1a66ee, 0x3d2deb72, 0x15e7a9c7, 0x8180b056,
- 0xbe440fd7, 0xd1a3d84c, 0xbfce85b2, 0xeff890ac, 0xc4967674, 0xe720757a,
- 0xbf7cccc7, 0x1ff079e7, 0xc0153df1, 0xef31f817, 0x27fbf8ac, 0x11583fa1,
- 0x7b63d467, 0x73cfcccc, 0xb102c39e, 0xfd413939, 0xd32258db, 0xfbcc8739,
- 0xafac64f4, 0x213ac2ad, 0xcce63fef, 0xe894aca0, 0xea36f73f, 0x811769a5,
- 0x9befa80f, 0xa93884ec, 0xcfb8af73, 0x9df3d236, 0xf67e090f, 0x27fde26e,
- 0x279bfbd5, 0xab9df3e3, 0xe4bffbd5, 0xf3a89ffd, 0x61e3fe8b, 0xdd8457f7,
- 0xdfef19ff, 0x272fdcf4, 0x2d8fd17b, 0x715dace5, 0xcfbf4493, 0x1bd423f1,
- 0x562b0fa0, 0x15cf09fa, 0x2dbc5dba, 0xd0dd7e65, 0xcaab8f2b, 0xed08fd76,
- 0x327b1c95, 0x92f5ed16, 0x67f5271c, 0x6747ba66, 0x8a68bb43, 0xbac235e4,
- 0xd91f11d9, 0xe8bd498f, 0xbd091fe5, 0xf9f0a55c, 0x3cc37c54, 0xfe8bb293,
- 0x9cfe79fe, 0xbb9e63dd, 0x5d9e06ae, 0x66914f08, 0xc0d5f71e, 0x768e5d73,
- 0xda1fd51e, 0x23f9d7d3, 0x2edc2b84, 0x23b1fe2e, 0xec53f31e, 0xe29df12d,
- 0x42ac96ca, 0x2ff17f98, 0xa1556477, 0x82fc25ff, 0x768bb43a, 0xdb83173c,
- 0x3fdbcfc5, 0xb6e5fbe4, 0x60c71bb5, 0x50da001d, 0x0bd358bb, 0xb56cde9c,
- 0xaf38ffce, 0xb4f2fe1b, 0x58b9e91e, 0xd3c9f2d7, 0x926fe768, 0x59777e22,
- 0xde3b9e2d, 0x3525efcb, 0xe03f7366, 0x87cefea5, 0xb20b6f10, 0xb291e919,
- 0x79cf9155, 0xb1e85b7e, 0xe6ff610a, 0x29358b0d, 0x23a2e780, 0x0fb855ee,
- 0x4e436aab, 0x978de601, 0x963e9667, 0xd6f98dfd, 0x6d6f9e2e, 0x0ad6f9e3,
- 0x2829605b, 0xf666f671, 0x32998f5b, 0xa9fe0fc1, 0xb220672a, 0x94796cf0,
- 0x79353fda, 0x0f9e48d4, 0xcfcbfec3, 0xe50c7f1d, 0x83c23f66, 0x83e1f5f9,
- 0x743f51a3, 0xace8c4e4, 0x25fe47a0, 0x089bee63, 0xb7e1acc7, 0x929a7ed0,
- 0x7301d8a8, 0xf89efe79, 0x5c325fe2, 0x38dd709b, 0x6e24f31e, 0x2ee93fa3,
- 0x4dfb8758, 0xbab3f699, 0x91dc63f3, 0x2efff3ea, 0xb666f0f0, 0x3afdda95,
- 0x0820b380, 0xf07efa87, 0x600697f7, 0xd32b93be, 0x50f7e086, 0x0e4a3227,
- 0xdf051764, 0xbdc3227f, 0xdf53e11d, 0x06c7527f, 0x6df1c860, 0xd05578e1,
- 0x0dd200f7, 0xe048d75a, 0xefb890b7, 0x9a3151f6, 0x7609b4fe, 0xe3cd0ce6,
- 0xf4d74b4e, 0xd3f457a7, 0x72bbbf8c, 0xc4fee6a0, 0xfad0c0a8, 0x77b7bf10,
- 0xf7cbc97f, 0x46c6c4ef, 0x3fbdfee3, 0x7df9fdb6, 0xcee9fdfc, 0xfa076417,
- 0x6e770bb6, 0x168f1f7a, 0xb5f40f3e, 0xa1527e53, 0xf69fda7c, 0x839f8ccb,
- 0xd687d4e1, 0xc0b0ce91, 0x60a52353, 0xeb6dfb7c, 0x7bad8b47, 0xae0577e8,
- 0xf3e8dd55, 0x287f516c, 0x1f680560, 0x47bfd7cf, 0x0b3abd79, 0x1d99e75f,
- 0x3c5b9cfc, 0xf012fae7, 0x20f86dfd, 0x40178bfa, 0x97fc83f1, 0x7aa09eb5,
- 0xae6c9adb, 0x9632ebaf, 0xf64fd1e8, 0x65f68b40, 0x78ade80c, 0x3b409be0,
- 0xf70dbc1b, 0x72c4e5bd, 0x54c2fdff, 0x8fef9bca, 0xfd9ff9e6, 0xfbf409c9,
- 0xc69b8bc7, 0x0bbaf5d2, 0xdbff3431, 0xb5f68072, 0xa8935f79, 0x7d31314e,
- 0xcf5c4ad6, 0xdf4401ff, 0x80006da0, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7dcdff00, 0xd554780b, 0x399ef0b5, 0x67091e67, 0x99212726, 0xe4c21024,
- 0x4e010249, 0xaaf08042, 0x9e180903, 0x6831004e, 0x0cfde1d0, 0xaf4a8809,
- 0x04819bf4, 0xa86c1808, 0x3bd15014, 0x6ad480a4, 0xa6a3ea6f, 0xd004c7d6,
- 0xa0d2941b, 0xdef6b7fe, 0x22c01b5b, 0xda046a28, 0xfad2de9f, 0x3ef6b5af,
- 0x82499cc9, 0xbf7b7b72, 0xdbe3ef9f, 0xb3ef6759, 0xd7bdeb1f, 0x6b4cfb5e,
- 0x7eef2074, 0xff99b185, 0x1b297b72, 0x97dad8c6, 0x1e609e4c, 0x857bd2c0,
- 0xd35ca0eb, 0xbeb19530, 0x5356b308, 0xd731631c, 0x046c61ef, 0x2c018cc1,
- 0x64ec728d, 0x435a5031, 0xc3c64fd9, 0x3b43ab33, 0xeaac66ec, 0x37bd147a,
- 0x3011d8bd, 0xdbbc7d43, 0xc648d8c4, 0xe953ed2c, 0xcbd7c9fd, 0xfc6bfea8,
- 0xfd631b77, 0xaf54e9dc, 0x438496c3, 0xdb0522f2, 0xb4fda89b, 0xaca843eb,
- 0xca873ebc, 0x147e7277, 0x84fac3ef, 0x17fa536b, 0x526f1c02, 0x64ac4a71,
- 0x628d999c, 0xa33b7eec, 0x47ab577f, 0xaba530c7, 0x72d2c8df, 0xe81e625d,
- 0x44dd76cf, 0x8f74c0e5, 0x6c604ee6, 0xd976a6d6, 0xec51eb8e, 0x8034e1ea,
- 0xcbddf28b, 0x93debaf2, 0xbab7cd8e, 0x7bfbc287, 0xd03d58ce, 0xe2ca0dbf,
- 0xc64afab0, 0xdd794d3c, 0x36e51bc7, 0xdb193ad3, 0x6c2ce54c, 0xcbb3ef07,
- 0xef3865df, 0x6f3e557b, 0x912611b6, 0xb60658cc, 0xbf7ae84f, 0x60c1d00d,
- 0x6d97815e, 0x77f0c3c1, 0xd4afba51, 0x4db4fd0d, 0x602fe564, 0x6a5b723f,
- 0x371fe399, 0x38b799ff, 0xfe6271ff, 0x46d896bf, 0xb7d7efec, 0x81e6d6dd,
- 0x3c3cb579, 0xeee48462, 0xb75ef7ea, 0x76abf795, 0xcf4060dc, 0xb8fa37aa,
- 0x66fac277, 0xdc208f02, 0xd82dbaf1, 0x99cf4698, 0x5b4b1e29, 0xabea09a3,
- 0x5ed91d9c, 0xcdf8bf18, 0x6ff210a8, 0x32519bcb, 0x9f7e7183, 0xe917bbe9,
- 0xa0e6fc58, 0x26139312, 0x464d9af9, 0xd036583e, 0xef3e1f73, 0xf1bdbe6d,
- 0xd69c6009, 0x535fc911, 0x18814cca, 0x1d5f6fe0, 0x82859397, 0xef5d173f,
- 0xc84fb043, 0xc4ead5cf, 0xabb74829, 0xb0d2609b, 0x4c9b458e, 0x75825f43,
- 0xcb43b731, 0xeccc3c02, 0x730b60bf, 0x69995ca2, 0xc48733bd, 0xe9a06b06,
- 0x06b1eb9a, 0x9ebcabf9, 0xbdaffd46, 0xeb9e97de, 0xc848b672, 0x19f90d87,
- 0x9f8225e0, 0x197e45ef, 0x1b8725d3, 0xe28f7dd3, 0x80d667fa, 0xbe78c3bc,
- 0x2885c92d, 0x62fc5d47, 0x80af9155, 0x8596925f, 0xcb4d4dc9, 0xf42a987c,
- 0x7e25ef1f, 0x71650259, 0xc152fd58, 0x7b789107, 0x65f916ec, 0x48bf68b3,
- 0x01996509, 0x28ea960f, 0xe7cc0b6d, 0x0a7bbc4a, 0x0efd65e2, 0x16f5bf8e,
- 0xe603b16f, 0x9371febb, 0x8b619406, 0xa8ec3947, 0x587d4687, 0xf185f56d,
- 0xc3ebfced, 0x30f01b98, 0x95267ae7, 0x83be01fe, 0xd785feb8, 0x0d3a09e7,
- 0x8bb992a3, 0xd8c5cccc, 0x1baba406, 0xe9c45427, 0xad77e62c, 0x43e2747a,
- 0x53b5fe30, 0x88bfaa16, 0xa9802d78, 0xe34f027a, 0x9b412cbc, 0x75e61076,
- 0x2a02c2d1, 0x7ef169d0, 0xdfa00589, 0x46fa5025, 0xd83d52d0, 0x1481f6ce,
- 0xb176c16c, 0x805b13cc, 0xe6f584f8, 0x86be31f0, 0x6d4c97ff, 0xfd410fd9,
- 0x961b33e7, 0x81e03399, 0x86412a74, 0x82fe7e75, 0xbe7824c4, 0x2e5bdd72,
- 0x94ab1e58, 0x50aaa60e, 0xcc14c1bf, 0x7be280b6, 0x86bdf646, 0xbbd3e07a,
- 0x08adfe9b, 0xf0dc7dda, 0xaae913a2, 0x0e49b5e3, 0x4d3f6165, 0xcc00cf80,
- 0x2a5ea9bd, 0x6c342a0d, 0x5da1b29f, 0x73f3adfc, 0xbaaf9f24, 0xba78419e,
- 0xfa1b6d5a, 0xf031f212, 0xf5d73e2d, 0xae3aeaf1, 0xbefd75d7, 0xcebff056,
- 0xd73295d7, 0x4c4a955b, 0x6e169030, 0x13bcca6f, 0x4c72ef91, 0xb70b165a,
- 0x8e8f8d37, 0x32f83945, 0x5d61ab5e, 0x839742f6, 0x8049fc57, 0xa47b2ebc,
- 0xc7ae81cb, 0xf3aebd75, 0x26af6ebd, 0x2f2fe4fd, 0x79fc3bfe, 0x81d7cd32,
- 0xe64d307c, 0xec9a6b76, 0x1c9a3e20, 0xff23265f, 0x79fd7b7c, 0xb3cfe856,
- 0xb6b9fd06, 0xc7f9fd17, 0xf387945b, 0xda967f42, 0x3cde7dd8, 0x3b67dfae,
- 0x4a2bfaba, 0x834b649f, 0x1334947e, 0xcd47fbb5, 0xf3e3495b, 0xfef3b6f8,
- 0x6fceb12f, 0xd303fbd2, 0xa46fd4ac, 0x1fd0679e, 0x5f2ff9ea, 0x1da20dcf,
- 0x5d8188f8, 0x5af7bb40, 0x6161f71f, 0x444ec807, 0x666f04c7, 0xb9927e07,
- 0xa7e22078, 0x4ee03b07, 0x80ec3bfb, 0xbcba57ce, 0xcba1f2e8, 0xe8fca443,
- 0x11fd30f2, 0xa421e62d, 0x30e6200f, 0x781c8fca, 0xe951d70e, 0x728f93ee,
- 0xf811cba9, 0xdd672461, 0x9b9083ec, 0xda31392e, 0x742e5d0b, 0xa6e5d139,
- 0x52c5c852, 0x3cba1721, 0x1e9a971c, 0x3def0b1b, 0x432be697, 0xb1f2e87c,
- 0xbb4885e6, 0x313f2bd0, 0xf1a5a7e4, 0xa9f90cd5, 0x7e70ca12, 0x4fc2f5b2,
- 0x9f916ef3, 0x9dbed24a, 0x8d32b11f, 0x40ff11fb, 0xd6995a7e, 0x0ab15fb3,
- 0xca7fecf9, 0xfd5ab8af, 0xcc37429b, 0xe8216ae7, 0x7e2eb4d9, 0xe32efe9b,
- 0xf806437e, 0x46b450d9, 0x5ab675f3, 0xb06b0407, 0x1aacd7dd, 0x01fba8f1,
- 0x7dee914b, 0x27f4f8bb, 0xfe71ff60, 0xc15bfd3a, 0xedf75fff, 0xd9d11df4,
- 0xf566df16, 0xdbbd21e4, 0x37bff60c, 0x5bb1f17f, 0x6fe6f3a4, 0x4243e749,
- 0xfa0ffc6f, 0xd17a878b, 0x1eff8713, 0x862cceba, 0xfc21fb3f, 0x3c67af7b,
- 0x02fbe7d0, 0xa2f39c0e, 0xd22bccbc, 0x3c1bdbeb, 0xe01fa899, 0x8234b1cf,
- 0x0f09d987, 0x56db3e02, 0xfe9cf302, 0x007d6758, 0x8f8f27eb, 0x8f33ef11,
- 0x3fb57589, 0x5b51f691, 0xd60bda3d, 0xaf8dedc0, 0x0d0ef65d, 0x76010b83,
- 0x1145c184, 0xdede01f0, 0x9533b729, 0x972084fc, 0x54dfe82b, 0xfd15f340,
- 0x9e65fe09, 0xcf015713, 0xdb1354b3, 0x8aaa7409, 0x55d6f83f, 0x26cd6bd4,
- 0xe1877266, 0xebc97021, 0xf6fd0149, 0x9fc0499a, 0x37c079b7, 0x0e25fbb8,
- 0xabf0767f, 0xfa2c8086, 0x8d6c7f05, 0xc9a5b740, 0xbfa091e4, 0x60a64535,
- 0x7c775a7a, 0x67c9d67f, 0x54c07cfa, 0xd667df1a, 0x1f7b5bf8, 0xa7ef4de9,
- 0xdb21fbd3, 0xd77f8c2d, 0xf609e678, 0xd29b0fe0, 0x292c5db9, 0x3eb1e98c,
- 0xf8e25d2a, 0x3eb001bf, 0xd39a3c3e, 0x91e5f7c4, 0xf9d363ed, 0xb3666db8,
- 0x3763a7c0, 0x559b59f2, 0x1bb2b7c7, 0xb1993df1, 0xbe413e4e, 0x4e09f181,
- 0xeaca5469, 0x4f5cbe64, 0xb66ebe04, 0x74d32fde, 0x5f0ba63f, 0xd97a0881,
- 0xabef826e, 0x6ddbe03d, 0x33743f7c, 0xdbb9fd7a, 0x576f82fb, 0x31ec7ce8,
- 0xec8c7bf0, 0x898cfe25, 0xe001a937, 0xa8deb5c7, 0x742fdc7a, 0x195267c9,
- 0x88ca2de1, 0x4bf92ea7, 0xc8512b2e, 0xfdf5123f, 0x7afca377, 0xb9ed9dcd,
- 0x0d7cea3c, 0x5e00e7ef, 0xf7c695d1, 0xdbf7a547, 0xbe23c81d, 0xe5827aa0,
- 0xca4779b0, 0x3c045363, 0x857e423e, 0x40fe91fc, 0xca78007b, 0x7f16fd42,
- 0xe30eead6, 0x7f053b93, 0xe5626e7c, 0x26db4fa8, 0x2db23f71, 0xa40f979d,
- 0x02ccb8f3, 0x754b97c1, 0xc30e8a7e, 0x427f9183, 0x5b095fb8, 0x7e69e137,
- 0x63cf2ebc, 0xbac066cb, 0x7d78e2da, 0xdda8e355, 0x382e9481, 0x8d75bfb2,
- 0x2f10cb63, 0x8a07fd9d, 0x997da0ce, 0x40f6f02f, 0x813398e3, 0x1767413c,
- 0x7fda19d9, 0x50047f01, 0x7f22541f, 0xc7f3ba98, 0xfc6ef484, 0xdf788819,
- 0xfbc9b963, 0xf7dfddc5, 0x2ccfbc44, 0xbef2b7f1, 0x088cdba0, 0xd04696ba,
- 0xae0224b5, 0x41a0e1d0, 0x797aeaff, 0xadeef351, 0xeac7982e, 0x5967a0a3,
- 0x2d4f3f38, 0xad5fb943, 0xed3bfcea, 0x176bf20c, 0x3c274f3f, 0xf9d26ecf,
- 0xd46ec675, 0x87a865c3, 0x73c176c7, 0x3c110f50, 0x1313ccb3, 0xed66af6e,
- 0x57757b46, 0x0efede9d, 0xad777f6a, 0xea979fde, 0xcf423a75, 0x42d74465,
- 0x3ecd5edd, 0x5eabf583, 0x4d1fefe3, 0x9026739f, 0x68791379, 0x81cbc088,
- 0xd1103808, 0xd837cf7e, 0xf788dab7, 0xd7d44537, 0x23fbc047, 0xfbe33ae0,
- 0x4898970b, 0x3f02170e, 0xe5222120, 0x9a3f9232, 0x9cfd3bd3, 0x526e7b4e,
- 0xc833bfc8, 0x0e1af4d5, 0x95f74b1f, 0x706129d5, 0x2e32c2e3, 0xf01a3017,
- 0x7ff185a5, 0x120373a0, 0x17a583f0, 0x1bd4d9bd, 0xda44e65f, 0x7bff5e7b,
- 0xfd1933fc, 0x4bf06665, 0xb8464b8e, 0x0ef31245, 0x90d99d54, 0x78750f87,
- 0xa7ee196d, 0xae33efa7, 0xa2b3f60b, 0x49594d7e, 0xd6c45fb8, 0xd6c27994,
- 0xf29fb7a9, 0x1c25afd7, 0xd5c6c3ef, 0xbea08765, 0xab285262, 0x5e38cb1a,
- 0xd094bd82, 0xf889575e, 0x25d794cd, 0x8acbda2f, 0xfad650e8, 0x35883f70,
- 0x5b3ae365, 0x3e88961e, 0x0fa01a81, 0x732169e0, 0x2eced15b, 0x832b1e66,
- 0x4c4b5cad, 0xf023c6cc, 0xa587f1de, 0x3fa7688d, 0x85d7d8da, 0x19d1a1fb,
- 0x3c717f7c, 0x296ba066, 0xee7d2dc0, 0xb2db7d23, 0xc795327d, 0x0eb6cf24,
- 0xdbffb195, 0x929970f8, 0x8431f58b, 0x0fe9aba7, 0xf9066d95, 0x9bba53f8,
- 0x538beaf0, 0x6fe8cd5d, 0x8c30b4ef, 0x51a63397, 0x2ee1691c, 0x9c4efe5b,
- 0x2e21e6cf, 0xfd173ff4, 0x324a6cb0, 0xd5b45bb4, 0xd51fa1a2, 0x7153566e,
- 0x939dbe7e, 0xa4bf58ad, 0xdb819456, 0x6ff37ca9, 0x4271aa3f, 0x4ca78efb,
- 0x9fb4235a, 0xdde9ad70, 0xaf2f0061, 0x4490d0cb, 0x33375c6f, 0xb739c615,
- 0x0250507f, 0x551f3cbe, 0xde2cf6fd, 0xe5fb619e, 0x67a7dc37, 0x497b6215,
- 0x2fed02dd, 0x9ff473c0, 0x1a90ec2f, 0xa72f384d, 0x4b04da23, 0x4657f0ba,
- 0x5b0b9cf1, 0xcf8c416d, 0xf77c539d, 0xf671c7ee, 0x67d3d05b, 0xa76e4c17,
- 0x9f10f009, 0x292cb3b1, 0x04db9f19, 0x2ec6773d, 0x685f3904, 0xb21fe4ee,
- 0x3962cb27, 0x1da3ff1c, 0x1d618765, 0x441f1e17, 0x195dabf1, 0xc00c849e,
- 0x1e991df7, 0xa3e79617, 0xf37addb8, 0xe87dd26f, 0xf2f2ffc7, 0x97f21722,
- 0xd3cb833b, 0xb917d71b, 0x55f98516, 0x89973ecb, 0xbab4de0f, 0xdf7ce037,
- 0xc2601e8c, 0x41f0367d, 0x2f938c5f, 0xe016fb11, 0xf62f8de7, 0x97fd5fe0,
- 0x1e5ac7f0, 0x36ef1849, 0xd27ef5f0, 0x00dfb49f, 0x87e33f38, 0xc7c003bb,
- 0xb236db1f, 0x9b8c28f3, 0x75dc52fa, 0xe07a1309, 0xee20a8b9, 0x535258ab,
- 0xa6fc7876, 0xfb450e53, 0x841c05df, 0x7b41dfd7, 0x2efdf7dc, 0xf08e1ff0,
- 0xfdbd0bf3, 0x8023a772, 0x0e27c5ce, 0xf8f48c87, 0xf85ff648, 0xecb7bc2e,
- 0x81d90b29, 0x6c254f65, 0x8171c0ea, 0x16ae306f, 0x867f2eb9, 0xabd5d685,
- 0x6523b25c, 0xfbe12925, 0xbfa4c395, 0xe9cb937b, 0x0ecb8719, 0x972ef5e5,
- 0x9fae55cb, 0xf1653ca6, 0x1f2d3ca2, 0x70d990e9, 0xf53d26c6, 0xcfc461d6,
- 0x055175f2, 0xf2f89836, 0xaf446ca7, 0xa0238776, 0xe9cfbd42, 0x9ca16390,
- 0xd6f5c19f, 0x3f2e0ca6, 0xed9312c5, 0x62d65405, 0xcc0af5bc, 0x97c02fa7,
- 0x77b63e36, 0x29f38c34, 0x0d1bce0b, 0xe1e2bbf8, 0x25e57a7c, 0x4c8ee289,
- 0x4133c8f6, 0x5c60ae5f, 0x7c9e544f, 0xfe113ad1, 0x5ff562ac, 0x5c1fb049,
- 0x067cbd51, 0x06570bee, 0xc5dae72d, 0xb16bfc5e, 0x55b3d45c, 0x5bd811fc,
- 0xfefebd63, 0xfa4ed61a, 0xa229b2a3, 0x4ff6fabe, 0xd5537e30, 0x3ebe7c6c,
- 0xa17f11c3, 0x7258c30f, 0x5d8a6001, 0x3364b6a9, 0x0572ea58, 0x5dd60ce4,
- 0xf344c07c, 0x0a51be5f, 0xc5fe60da, 0xf8dc797d, 0xc1f03f63, 0x407f5a20,
- 0x1ef97805, 0x33967f6e, 0x7f0ed053, 0x1d607ede, 0x0a2f31c5, 0xc4d0b37d,
- 0xe7e7c8bc, 0xdc54b4a3, 0x2a7b2fef, 0xfcbcf08a, 0xf6ff95e9, 0xbed7bc38,
- 0xf87c6679, 0xf90ebafe, 0xd999e383, 0xf9fabae3, 0x52f7f364, 0xff8a0e51,
- 0xb0c9f619, 0xecb1e5de, 0x90d3f3a7, 0x6ea9c96e, 0xf2ddaba5, 0xf3670f2d,
- 0x86cfb076, 0x21dc2f75, 0xcbd83ad1, 0x2087b236, 0x3e386af3, 0xb49ed497,
- 0x633db95a, 0xd9f84baa, 0xf5e7d46e, 0x7fbc126d, 0x8525ea0e, 0x0f6817f0,
- 0x87df978b, 0x3e93257d, 0x2afae1f1, 0x66fba6cc, 0x561d3f53, 0x3317ef94,
- 0xd9f45c78, 0x2ee7ee0c, 0xa5eed54c, 0x36a3f438, 0xef1a4b6d, 0xe6251a47,
- 0x4abcfb01, 0x3a32db73, 0x8db9fcc7, 0xb5552be2, 0x27289e51, 0x2f3c4bed,
- 0x3255bf40, 0xd871ad93, 0x1ae75f2f, 0xf01fd737, 0xcf1943fc, 0x3f5c1c67,
- 0xbe02c656, 0x6638ce15, 0xfc4bffe8, 0x97f7832b, 0xfdebac3c, 0x5d4df1ce,
- 0x10c3b9f5, 0x95e77d5f, 0x979e3ce3, 0x19017e48, 0x9fa1168f, 0x0234bcf7,
- 0x770bd7f7, 0xfa829f1c, 0xf2cff576, 0xe1757c55, 0x7b27df4f, 0xb9d05ab1,
- 0xb47dfd1d, 0x0cff001f, 0x7e4253ca, 0x0f8f127c, 0xd0f8129d, 0x57d7ade9,
- 0x38f0b0ee, 0x5475e83d, 0x7f9b9524, 0x3a56fd43, 0x6fa85cda, 0x8cb65f2b,
- 0x6bfcbd42, 0x5fb43f9c, 0xf8c079b4, 0x167f810f, 0xb4546259, 0x33026b4f,
- 0x69af08ad, 0xf5dc1130, 0xf22a425e, 0xafb567e3, 0xce4f9138, 0xd0b28547,
- 0x8bac750e, 0x01711ad2, 0x7dcf8f2a, 0x88d59b56, 0x6a259c71, 0xf504c39b,
- 0xc464364b, 0x48febea1, 0xfeb1590d, 0x3334a6a3, 0x1d551ec2, 0x1e47b08f,
- 0xa067f04e, 0xff049aba, 0x6b59bea0, 0xf35cf4e2, 0x3a6b71dc, 0xac55778c,
- 0xdfe7f3f7, 0x4f78c6cf, 0x365b6a65, 0x77a011da, 0xf3c47f76, 0xc3b226b3,
- 0x3c939f6b, 0xe8bac351, 0x0de916bd, 0xd04ab5f2, 0xaf4bed79, 0xbf7c843c,
- 0xd05de916, 0x6f805f9d, 0x17f3d04f, 0xfc614e0e, 0x17c813fd, 0xb802ddba,
- 0x377182d6, 0x09af872b, 0x25e7803e, 0x8f2079fc, 0x11e826f4, 0xf92337f4,
- 0xc6fa37bd, 0xb7fb7266, 0xf48db368, 0xe7266c6b, 0x2f1df6fb, 0x9f7e913b,
- 0x6dfc7f3f, 0x7ca94f3c, 0xbbb2ac01, 0xf817be07, 0x3bf5c2a8, 0x4fe4fe69,
- 0x9d7ae154, 0xe4efeb5d, 0x556f2173, 0x5f4faf8c, 0xd62c956f, 0xf78bd7af,
- 0xbc8532e3, 0x97af8130, 0x12f97106, 0x8af284f2, 0x3ebe997e, 0x5f7f1c5f,
- 0x4ca2cfe7, 0x62699fce, 0x726d4c9d, 0xbe907e22, 0x7f8067a8, 0x4251d63c,
- 0xcf93406f, 0x0ff3067f, 0xff3e97a3, 0xd00f3152, 0xb8d89e6b, 0x9bb63a2e,
- 0xce9e8ad9, 0x3933f32f, 0x9add9cdf, 0xf80cda98, 0x59f60cfb, 0xfc006794,
- 0xa78d872a, 0x5e3e8df3, 0xa6ca4ff1, 0xffa1bae1, 0x8faff610, 0x8fa051fb,
- 0xc47cfd8c, 0xf3e87cb8, 0xb8b2e5d7, 0x7cb4c166, 0xdcfbb627, 0xeb879191,
- 0x6697e3e6, 0x07bef4aa, 0xdf7803fd, 0x38a26cd3, 0xafb159f5, 0x15f5bb3f,
- 0x2ebca2e7, 0xde229f7e, 0xabb27fc3, 0xfe753cfb, 0x9a67e30b, 0xbbf6f167,
- 0xcfac21a6, 0x752f9237, 0xc9fce9bc, 0xdf902536, 0x55a7c912, 0x38ad6729,
- 0xdd73e45e, 0x718f397f, 0x5fff9416, 0xff248298, 0x6644ecb5, 0x7f865d98,
- 0x65d51b0a, 0xb3af361f, 0x51cb7b51, 0xbd75076e, 0xaaebdbaf, 0xc425cf78,
- 0x79328ff7, 0xf56ac91e, 0xf42736c4, 0x36e3e633, 0xfdd60f3a, 0x42d709c5,
- 0x95c60c52, 0x082b4a5e, 0x2e6b77b7, 0xadfe209f, 0x70db6d64, 0xc770b3ff,
- 0x234733fb, 0x42d8fe9f, 0xb70b2fe7, 0x1fa2b64e, 0xe2f0f2be, 0x73ff4851,
- 0x5d9edc75, 0x04791daa, 0x7573e8fd, 0xe716b98f, 0x53c57be1, 0x85f3c2c6,
- 0xbe89f3bb, 0x66daa3e7, 0x80f1dc22, 0xbde11ac4, 0x6e478771, 0x71e01bba,
- 0xb8b1818e, 0x490e8fce, 0xf8c36325, 0x37530961, 0x9b7e8ddd, 0x7ca2a31c,
- 0x5af4247c, 0x6bd3858d, 0xdaffe097, 0x79cb92ce, 0x364d4d71, 0x1c77979e,
- 0xf80a7d04, 0x9bbab0a9, 0xebee3842, 0xa80fb489, 0x524b6d82, 0x935b9d1c,
- 0xcac2b4df, 0xf405c9ec, 0xcf0c9edc, 0x1eda5a4f, 0x7c9cf5c0, 0x19bf91c0,
- 0x18dd2b71, 0xbbfb88b5, 0xe7e03724, 0xbe3af8d2, 0x0bd479f4, 0x4fec8b3e,
- 0xfd15bf7f, 0x627fd47c, 0x7f6a97fe, 0xd6ed0f3c, 0x7159a3a5, 0x5e4ffeb8,
- 0x3f43aa8f, 0xd70b13e7, 0xe0ff7a67, 0xee1c7d7f, 0x65bf8127, 0x32bfc180,
- 0x1f67c0c0, 0x2db5fd1b, 0x33a7af34, 0xce95fe8d, 0xb2eb15af, 0x04f3c262,
- 0x99e3f9ba, 0x744796b7, 0x02880fd9, 0x318c5d16, 0xf6ef8c0c, 0x6d8bebf9,
- 0xd8378fe8, 0xf3ac1b54, 0x3c77e463, 0xe2597a6f, 0xe73b00fb, 0x1e5f8fff,
- 0xdefdc411, 0xf0e4ffb2, 0x105326b2, 0xec4ea553, 0xfb612ede, 0x25ffe0a5,
- 0xdbfcc29a, 0x01e7bb3d, 0x9a2bb3db, 0xb4325b6f, 0xe79472bf, 0x12b5403f,
- 0x9dbed7e1, 0xf7dffeec, 0xc178f567, 0x6bbc74af, 0xebbc434c, 0x39f7d6f8,
- 0x145f026f, 0xefe17415, 0xf20aff0b, 0x7dfb2f67, 0x3a697e54, 0xe438e8fb,
- 0x868c4767, 0xe6cbf372, 0x48fea4c7, 0x6ff297f7, 0xac757ee0, 0xfca2a312,
- 0x48dfe17e, 0xfd978c87, 0x74ea54d5, 0x1365e3d7, 0xf7a16a5e, 0xf11e68be,
- 0xef7838da, 0xeb86250d, 0xf7cf0f6f, 0x646fa488, 0xebfdc7de, 0x73e22746,
- 0x7e9f5d7d, 0x9f59d397, 0x1747a7f7, 0x2d5d713b, 0x6d7df64f, 0x4fb7d20c,
- 0xdafe8a8c, 0x71f79172, 0x13d73f61, 0x4731ed17, 0x2f9d0066, 0x62e3981e,
- 0xb69737a0, 0xcf879dcc, 0x526ebd97, 0x5ed75fd1, 0xfee2732f, 0xbb720fea,
- 0xde12c553, 0xe47ce10b, 0x697a84a0, 0x839b296c, 0x6486c7ed, 0xc67e86e6,
- 0x32fce0cc, 0xc41cb2e6, 0xe0cf9f83, 0x6e33c539, 0x033c5344, 0xbcc5f5fe,
- 0xe0bfa58e, 0xef1d1071, 0x9c6c7efa, 0x1030f758, 0xf177e243, 0x3f88b8bc,
- 0x8bc0e4ff, 0x4bbfb0b3, 0xce2a2c87, 0x16438bfb, 0xec157fea, 0xde30cca3,
- 0x5f7ca3c5, 0x1a547082, 0x7fdf33ca, 0xfbe26aac, 0x1675ca8f, 0x3ba6358f,
- 0xb587165f, 0x3c1efdc3, 0x2bb8e373, 0xfcea1f05, 0xd7c3caba, 0x1cec0ab7,
- 0xf89bf7ae, 0x6d359637, 0xc6f5bc43, 0x7f96dfc7, 0xfa8cb333, 0x7b6f93a2,
- 0x578117e3, 0x5be47f94, 0xed562f9d, 0x71ece7e7, 0x9113f94d, 0xd13e74ff,
- 0x12604bf5, 0x5a7b41cb, 0x98396563, 0x47301397, 0xca17a86b, 0xed05b714,
- 0xf6f89cc0, 0x23cf4412, 0x4abf5c59, 0x198f66c5, 0x8d8d51ed, 0x78b747f4,
- 0xc7d71677, 0x283e6421, 0x7952ccef, 0xa6ab25be, 0x825e857d, 0xed0032e3,
- 0xb89f5976, 0x49a1ba3f, 0xd9c6e1e9, 0xd975f032, 0x3207b8b8, 0x87bcc634,
- 0x4478728f, 0xd40b48dc, 0xb333d2cb, 0xccae004b, 0x0ac94cf2, 0xe1d2f7eb,
- 0x1eb801c4, 0x9f153e78, 0x37de28ff, 0xea246b23, 0xf9f4857f, 0x618ea697,
- 0xdabad31b, 0xf1dd799f, 0x5ddd2fd1, 0xa585bb70, 0xeb08796a, 0x9ee5e5f3,
- 0xec1ccf2c, 0x22f9f227, 0xde52b6c6, 0x3f5fe05c, 0xfe04ff44, 0x8f40ed79,
- 0x2d5f043b, 0xa4212bb2, 0x5cb3ab33, 0xc037f4ee, 0x8c5a6015, 0x259b748c,
- 0x390ee4f8, 0xe7ef82d4, 0x82f55ab2, 0x03a25c9d, 0x5dedf75f, 0xd80603af,
- 0xe03fbd05, 0xb02d2f87, 0x136be03e, 0x1046dfb0, 0xb120131d, 0xe998f402,
- 0x33fd7fb5, 0x60135bf6, 0xe78451ed, 0x10c2f50a, 0xccface0c, 0xd959435f,
- 0xe30c39c7, 0x1c579e1d, 0xb8e80521, 0xc43ef9fe, 0x1f852bff, 0xc4457cc3,
- 0xbe541bcf, 0x4b1be61e, 0xe080f6fc, 0xacfc4fb7, 0xf044133a, 0x0bec7673,
- 0x70f1e619, 0xc461ef94, 0xa9f31afb, 0x946ef5d4, 0xfa271ad7, 0x54ff9f19,
- 0xac3550d2, 0x3b24fe11, 0x5ee42094, 0xf506dd0a, 0x8db969ad, 0x0ab66f68,
- 0xc69cb97e, 0xd81c3f68, 0x3fbca36c, 0xea78e376, 0xa69700c3, 0x3ee1aedf,
- 0xb6cff2f3, 0x3a052e67, 0x38bd40d9, 0xa1539d61, 0xb75822cf, 0xce896005,
- 0x4f448381, 0xe1380fa8, 0xc7b4b6f9, 0x319f3952, 0x4eb5ca2f, 0xddef1d1f,
- 0xa34301e8, 0x33b669df, 0x732bee0b, 0xe51501d9, 0x27cba74f, 0xe01bc076,
- 0xfe6e327b, 0x7fac1f41, 0xeb7ffb99, 0xa613ac4d, 0xfb374eb8, 0x9ff916f7,
- 0x83016e20, 0xf8b0397e, 0xa2c3d9db, 0xe21c5683, 0x81e2ed96, 0xcaf51ee2,
- 0x257ae8bf, 0x1f93e59f, 0xf1844b82, 0x93368b96, 0x8cb70aa5, 0x6bb049eb,
- 0x9feb17c8, 0xc3bb20ca, 0x8590fc66, 0xfa0763b7, 0x4b6cbf12, 0x2b0e8893,
- 0xd7944d9b, 0x3fb9b338, 0x8cd54373, 0x3a54bee6, 0xf3d327af, 0x2dde474b,
- 0xd3877ae4, 0x8933e669, 0xe88f2893, 0xea544199, 0xf82f58f3, 0x15f3c74e,
- 0x1cb3c72f, 0x1e37ddc8, 0x2d5a13cf, 0x3f26e82c, 0x35cfd784, 0xb4afde11,
- 0x7f91979e, 0xb1304ee6, 0xd14b00be, 0x496dcf9c, 0x01eee666, 0x9f4136bf,
- 0x73347728, 0x6a0bed87, 0xf88d9ca2, 0xda780b1e, 0x97701f70, 0x2727d768,
- 0xa74ed0ce, 0x8e813ce7, 0x331594bb, 0x9ddb1d70, 0xbf915a53, 0xc33f5a1c,
- 0xb14936b8, 0xabcc1f20, 0xee63d230, 0x196c235c, 0x5be915ff, 0x73e378cb,
- 0x5f08c79b, 0xcb98e9d4, 0x18e9c372, 0xfa0f3f86, 0x363c57e1, 0xdee63f8e,
- 0x79e01e37, 0x7cc3f861, 0x32292b96, 0x147b6fe1, 0xade017c7, 0xa63cf911,
- 0x58b788c8, 0x7d4f118f, 0x48f88d4b, 0x9bd71af0, 0xa86e9e58, 0x360df64f,
- 0x515ff7d4, 0x54078060, 0x1fb4358f, 0x019271b8, 0x334c0b4e, 0x9ba8cfb4,
- 0x1ab3806d, 0x1fb436ee, 0xa1917fb4, 0xcab8373e, 0xe8e43f50, 0xb43c037a,
- 0xed0c9fe9, 0x316f3787, 0x7687e7d4, 0xb447ea1a, 0x8f00c0fe, 0xd0c27b6c,
- 0x8d87f47e, 0xed31fa86, 0xc7ea1acf, 0x00c17c5d, 0xd578e84f, 0xebb6fed0,
- 0x44f00cc7, 0x7da1aef6, 0x037dfdb1, 0x0ffd593c, 0x93dbfb43, 0xa7ea1bce,
- 0xd4333fba, 0x6ab9cf4f, 0x7f6a6780, 0xb6afb431, 0xa36546fa, 0x265d2aff,
- 0xc059aab9, 0xeb4aeae5, 0x71ca3b1c, 0xdff03651, 0x7fc9d610, 0xd29ed0e3,
- 0x62a5857e, 0x34b264fc, 0xd9f2443e, 0xdf70d26c, 0xe4af6911, 0x8c1ebccf,
- 0x4c57b1ab, 0x06234f74, 0x361c8ecc, 0x0ec7ac7e, 0xb82ec41b, 0x806aa96f,
- 0x8649bc13, 0x6ee589f6, 0x2fb27d43, 0x7fdf50c7, 0x07806685, 0xda191754,
- 0x31e8dc0f, 0x528169c0, 0x3a8cfb43, 0x6ace01af, 0x1fb43728, 0xa867dfb4,
- 0x30ae0dcf, 0x5a390fd4, 0x3687806d, 0x1fb4346d, 0xd4301cde, 0x0cea87e7,
- 0x1b5a23f5, 0xb6c8f00c, 0xa3f686fd, 0xea1a0c3f, 0x351fb4c7, 0xd8bb8fd4,
- 0x74278064, 0xdfda1b34, 0x80643d76, 0x8693b227, 0x33f6c5f6, 0xfab27806,
- 0xdbfb435b, 0xea1ace93, 0x192fbaa7, 0x64ff75ea, 0xc657ce7a, 0x995fc2e7,
- 0xf0d9fda9, 0x8792607e, 0x5e047f21, 0x6e356930, 0xa766f6c6, 0xde817f13,
- 0xd0928f6e, 0x3e52f1bf, 0xf4261c52, 0x04c65f01, 0xe857c44c, 0x5c5057ea,
- 0xafe29e28, 0x98dc5a64, 0x1f760377, 0xb4e67fe3, 0xfb77f434, 0x295df974,
- 0xf6f88f5f, 0x6cd1d77e, 0xdb6bf646, 0xa7bca944, 0xd9a3c33c, 0xebf20e3c,
- 0xd953df6c, 0xf8bfb809, 0xbbf414d9, 0x36c0b257, 0x2964e79c, 0xde1da62f,
- 0x8c651d3b, 0x54e5e863, 0x6c2de03b, 0x1aa3273e, 0xb26e0a52, 0xbf6a9fdf,
- 0xfb3bed4c, 0x130df115, 0x587d7fac, 0xbec28fff, 0xadbf0640, 0x05720fc1,
- 0xfc0fecbe, 0xfc7bc12a, 0xf5ef0449, 0xefdca9bb, 0x09f2a1cf, 0x07f546bf,
- 0x3f0445fc, 0x1c10f7ed, 0xd95297f4, 0xf3d2f7e8, 0x8272fe43, 0x197ec08f,
- 0x7fb0a3cb, 0xd859f2c6, 0x73fd6307, 0xf8462fb0, 0x9500fea7, 0x7a3afe4d,
- 0x81bf82fe, 0xfbfc97e0, 0x3fb9fe09, 0xffb36548, 0xfaaf9528, 0x35fea89b,
- 0x6fc1337f, 0x870443f8, 0x1f04adfc, 0x7c11b7f3, 0xc121ffc2, 0xa9dbfb6f,
- 0xa45ff56c, 0x077f1df2, 0x5ff29fd5, 0x9e8bb827, 0x12387f46, 0xf88a9f9f,
- 0xe37e132b, 0x2c3fc172, 0xcb8bfb9e, 0xe5b02b38, 0x932d6f82, 0x78c10dc0,
- 0x46ecbf60, 0x891d7bcc, 0x7c43957c, 0xfc56ea75, 0x98fdc8f9, 0xf19f025e,
- 0x133af4fd, 0x76e8d78f, 0xe817e45e, 0x03c5527e, 0x00bb1f7c, 0x273c5ffc,
- 0xee28cff8, 0xb6a95eaf, 0x573fa0e4, 0xf0d68a61, 0xf54ae51c, 0x610fc81f,
- 0x220dde78, 0xb66bdf72, 0xf6c33b83, 0xbef01571, 0x4eafde19, 0x54f9a34d,
- 0x9d0b56b0, 0x23cccaa3, 0x33dd5c81, 0xf89d77c0, 0x4039807a, 0x98256afb,
- 0xff38fb8d, 0xf05fdf00, 0xa5ea95f9, 0x547e136f, 0x670fce8d, 0x770942da,
- 0xa4e4fc61, 0xdebff144, 0xf22551f0, 0x7fad7bc8, 0xfa0a52e3, 0x937fa5e5,
- 0xd39f487c, 0xc6394716, 0xf8839c13, 0xc839d4be, 0x5263286c, 0x30418e7d,
- 0xaa393f9f, 0x0a0335ef, 0x759df4ff, 0xeb4fee47, 0x81df47da, 0x9bf0515b,
- 0x42db98cb, 0xf3cc8d79, 0xb85d5e16, 0xbe08f993, 0xfca8058b, 0x35cf8a5e,
- 0x0fe62468, 0x8df60905, 0xb4f6a5b5, 0xa579c8ae, 0x207ae20d, 0x50d9906d,
- 0xb9f5484e, 0x393fbfb1, 0xd3af343c, 0xc6cf6e63, 0xfaf3e975, 0xdf9baa5e,
- 0x4f1d609f, 0xf4fefce3, 0x4c1757fa, 0xe3f9dd19, 0x0a17c01f, 0xc7686f9a,
- 0x06a41cf0, 0xafdf0764, 0xf289aef9, 0xa8be75b9, 0xbe2180c0, 0x7944c9b7,
- 0x027c5dfe, 0xb0fb81fc, 0xf7ba0ef8, 0x01327c07, 0x8c6ab9d7, 0x5f82b014,
- 0xcc1cda79, 0xf2b9d136, 0x15c62b52, 0x7f03c796, 0x07cef7a4, 0x03fdc56b,
- 0xd7f039fd, 0x2fcf48ed, 0x073a317e, 0xc6f555f1, 0xabe23718, 0xc0740cc6,
- 0x923be37d, 0xb857f3c6, 0x0dc697ea, 0x932678a5, 0x4fe30d35, 0xeb3d6d33,
- 0x7f82e5db, 0x4a59274e, 0xf19fd483, 0x413ee5fc, 0x3d04fbb7, 0x64fbafd7,
- 0x3ef3048d, 0xdd12ec7d, 0xff36e95f, 0x983c8f8d, 0x55c7c619, 0x78a767cd,
- 0x5bdfd07a, 0xdf3a7f44, 0xef875648, 0xaf3e12a0, 0x465e3e4e, 0x7c0b12fc,
- 0x7c7c419c, 0x6719cf01, 0x7731dcd9, 0x280ed941, 0xfbe94109, 0x81f69567,
- 0xe546988b, 0x72a5e612, 0xf91d9039, 0x6dd81bd6, 0x62af7c45, 0x6d7cf44d,
- 0xf21762d1, 0x8fb332f1, 0x306bc9f6, 0x7dcf1753, 0x12494759, 0x36ea4bc6,
- 0xe80495bf, 0x7bb0d39b, 0x676fc632, 0x85be1707, 0xd321d965, 0x055bcc05,
- 0xce2ef8b9, 0xbd54ddab, 0x7f8c1fb5, 0xb71373f7, 0xb3e787f6, 0xf60f4e24,
- 0xae87a72e, 0x0dd72237, 0xe499b072, 0xeb43d633, 0x06a59c92, 0xc2d8a839,
- 0xaef8a63c, 0xb94ef9fc, 0xfbfd5a28, 0xe4bfa8fe, 0x54178a0e, 0x438b61bd,
- 0xdc62af3a, 0xf479301f, 0x07ee8878, 0xd5f3e230, 0x76c35a2c, 0xfebe0a9f,
- 0xbe230074, 0x1b04d4fe, 0xff2e82c2, 0x92faa594, 0xecba320a, 0xb9f99575,
- 0xb0278861, 0x9f89fbe7, 0xcb6d37cf, 0x1fbd434f, 0xc4ff454c, 0xab4dacf2,
- 0x15d83349, 0xae9f75f6, 0x16a3d738, 0x9c8a871e, 0xede8a997, 0x623fa33f,
- 0x9e00b2b3, 0xb35c8083, 0xfdcf2851, 0x355724ac, 0x978c5a88, 0xf9baf24d,
- 0xffb1ac39, 0xadbe62d3, 0xdd71e57f, 0xe307ac00, 0xe1c7dd26, 0xdd16ca76,
- 0x0de90e35, 0x9a71a317, 0xead19107, 0xed298f1c, 0x37bfe829, 0x8e7efb44,
- 0x3fe3d1f4, 0x35b2befa, 0xba4c93ed, 0x52f63697, 0x18f7dd05, 0x80fba363,
- 0xd8b88877, 0x2e3c451d, 0x071e8776, 0x07111f1b, 0xb0c7888b, 0xc5c73df1,
- 0x98ccbd74, 0xe4f9c166, 0xd7d4ffb2, 0x5d18f14f, 0xabb3760f, 0x8a3690b0,
- 0x6e29bb57, 0xc99f19d1, 0x4cf8f2b7, 0xd5c53249, 0xee4f42ad, 0xa4fd72f2,
- 0x0e589fbf, 0x3ec3185b, 0x0d32cec2, 0x00d508fb, 0x324ea80f, 0xd1b81fb4,
- 0x0b4fa86d, 0x33ea18e4, 0x9c0334ea, 0x686450d5, 0xc7bf683f, 0x4b06e700,
- 0x1c87ed0d, 0xa1e01af5, 0xf686e54d, 0x867d9bc3, 0x0ad0fcfa, 0xd688fd43,
- 0xb23c036a, 0xfda1a36d, 0x86030fe8, 0x75ed31fa, 0x1771fa86, 0x84f00c1b,
- 0xf686fd8e, 0x1a0f5db7, 0x1fb227ea, 0xed8bea1b, 0x93c0333f, 0xda185fd5,
- 0xd3ec253f, 0x862d49ed, 0x5c4407e7, 0xa4fbaa62, 0x39e9fde1, 0x53f00c67,
- 0x87946f48, 0x879256f9, 0xf783f596, 0x07fd0055, 0x186b37ac, 0xfda999f3,
- 0xab2fd0d6, 0x6dfc47ee, 0x52cfe28d, 0x947cb6a4, 0xedcca7db, 0x6d3e5869,
- 0x7dc16f72, 0x89f8c66f, 0x2acef614, 0xcb05b859, 0x9b363341, 0x9f40dc13,
- 0xa0b707b9, 0x68a90c98, 0x1e00bb31, 0x16ece4ba, 0x8d61d217, 0xfc444a49,
- 0xc1ab486f, 0x89a6c472, 0x8fd41252, 0x83585dac, 0xfd71757a, 0x61cb8599,
- 0xd837a35e, 0xa09dcd89, 0x3e30da0b, 0x6f887b26, 0xe29b0037, 0x8c8c363a,
- 0x5dbbfca6, 0x37191563, 0xba76bb33, 0xb86e316a, 0x1d41676b, 0xafc0db96,
- 0xac620e0f, 0x2c7afc0e, 0x1f5f8277, 0x386e8584, 0x945887f3, 0xa9e07553,
- 0xdfd73c24, 0xcd53e93e, 0xfb0ae1ac, 0xe3013dcd, 0x8b4427d6, 0x737ec7bc,
- 0x7f426627, 0x0f00ab28, 0xdcfa71f8, 0xbe1dd280, 0x2a3bc436, 0x372a1707,
- 0xd7bfa1a4, 0xc0c0dfad, 0xc3e227b9, 0xa27805fa, 0xf5fa6dfc, 0x785fb078,
- 0xc3de63de, 0x9f6e1ce4, 0xf59ae407, 0xd7ca023c, 0x943a2ee2, 0x80c497e0,
- 0xd31fab9e, 0xf80e5bea, 0x136ad595, 0xf71637dd, 0x4da43056, 0x5f1be071,
- 0x700f16df, 0x64ef7892, 0x8e0e6f9e, 0x72e380ab, 0x927f8c2e, 0xc61c0096,
- 0xbf00fb1f, 0xf35d2ce7, 0x0e67dcb1, 0x2c2fa0c8, 0x069a65c5, 0x20b93ce3,
- 0xfb9d369a, 0x22ff46ac, 0xfc9de44b, 0xfbcc473c, 0xfd0d1cc6, 0xf58b9fa2,
- 0x8df7ee3c, 0xfd82d8fe, 0x7932a0af, 0x40f98849, 0x579a29cf, 0xcb0ad4c3,
- 0x8cda3fd7, 0x07c04ef7, 0x8a3b426a, 0xf98737cf, 0xb8732b1b, 0x5af9625f,
- 0xa5baf8a2, 0x85c5abc6, 0x4c916f8d, 0x4fed3dd5, 0x1065e237, 0x5186af7c,
- 0x49f8e5bd, 0xac9f4fba, 0x52969835, 0xe786213f, 0x3f884a21, 0x4d05a7ef,
- 0x923e004b, 0xff7c36e3, 0x9812dfa1, 0x4fbc787f, 0xbe6136ae, 0x6aa6e242,
- 0x5121e213, 0xbe786af5, 0xc35edcc8, 0xc6e275f9, 0x1e3fa3b5, 0x6af6f381,
- 0x99610798, 0xc87df3ae, 0x9cb5448e, 0x703262d7, 0xea5ee2dd, 0x1316b755,
- 0xf43ac3df, 0xe7e76952, 0x3bd5bd5b, 0xa6a9de0b, 0xc502d7bc, 0x4f58478d,
- 0x07e52be5, 0x23b3e07b, 0xa92fdc39, 0xa3e71a77, 0xc217e7e8, 0x19555c6e,
- 0x6f425bb7, 0x61cb1fdc, 0xf3fb9fbd, 0xcdd9120b, 0x44dfbbe6, 0x5c3ab1e7,
- 0xde20e30f, 0xd8b46fea, 0x98f56f11, 0x8bf64167, 0xfa7add91, 0x77073987,
- 0x4ff3ba9a, 0x89003937, 0xbe40298b, 0x01ac1b3c, 0xadf239fc, 0xca69fa1a,
- 0xe84ccb83, 0x6ab1240b, 0x4652184a, 0xc3cab496, 0x72bf326e, 0xfa27ff23,
- 0x64c1f28c, 0x37dd325f, 0xfdd57410, 0x7474ee82, 0xde206627, 0xe579e5df,
- 0x89dcd3eb, 0x5f9d4748, 0x63fc9fd7, 0x0e8c2f94, 0x2e7e081f, 0xca120d62,
- 0x44d658eb, 0x46d678e5, 0x075877e5, 0xcaa61e95, 0x1a624e58, 0x4bcc2595,
- 0x4d5614e5, 0xa06b2965, 0xa26b1a72, 0xa36b0672, 0x5453f612, 0xfb4a997a,
- 0x57e0d9be, 0x79973960, 0xaac79ca9, 0x7c80bca9, 0x672df80e, 0xcddf040d,
- 0x066ca89a, 0x841ee03d, 0x953b0971, 0xc59e81af, 0x127f0df2, 0x9bbf2195,
- 0x97186db9, 0x84f2a1c8, 0x6df2a35f, 0xad95117f, 0x7bb50f7e, 0xe54a5fc7,
- 0xca97bf29, 0x2a72fed3, 0x6a3efcdb, 0x057f9ef7, 0xabf81f95, 0xff37fca9,
- 0xf43f2a46, 0x77fca807, 0x59951d7f, 0x06fb4656, 0x9fca1396, 0x3948f40d,
- 0x81b8f56f, 0x1cb905ae, 0xe63dc78f, 0xa478dc84, 0xfe30cca7, 0x271c94aa,
- 0x66dc5126, 0xe757bfba, 0xa316c63e, 0xfdcd3e3e, 0x83a24748, 0xe1a554fc,
- 0xc8bcc304, 0xd4bb5366, 0xcf6b6807, 0xe7b5cff5, 0x8d7f1d82, 0x10d1f6d5,
- 0x0763ddae, 0xa5b4f47b, 0x5047faad, 0xf378fd2f, 0xced83b5c, 0x3ef78eb1,
- 0x54c3967b, 0xab04e63f, 0xe6760151, 0x5783df6e, 0xa81e70b2, 0xbc7e93f7,
- 0x4ce6ee63, 0x27d7279c, 0x500d77b0, 0x853ad5fe, 0x1bf2aff2, 0xa1a3e58e,
- 0x14ad531d, 0x6b0bdda0, 0xde8af147, 0xebd645da, 0xe9593def, 0xf50f1092,
- 0x01eda07f, 0xe508c94b, 0xbc2c5c63, 0x1bb7f35f, 0x1937499f, 0xe99dbc3f,
- 0xcc9dfd26, 0xfee6a4f3, 0x91e7c07f, 0xfaf96dfc, 0x3be8cff8, 0x0a23ac1f,
- 0x9631bbe5, 0xf00e9feb, 0x55ff719b, 0xcdfae02f, 0x3747e4e9, 0xdf7379ea,
- 0x31bea993, 0x8ad2bb5a, 0x8a4ce6f0, 0x7ac7d487, 0xfdb173a2, 0x43d274d6,
- 0xe5187d29, 0xded2edbd, 0x7261dd56, 0xeb97353f, 0x35c2655d, 0x8bea3175,
- 0x8f0cc9ef, 0xef7e07da, 0x01dbd683, 0x66adee6f, 0xcc529efa, 0xd14a0f84,
- 0xc937042e, 0xf3a124a3, 0x3a2fd518, 0x5dbafb82, 0x1b3a359a, 0x51107ae8,
- 0x9d5ffe87, 0x4a5ffe42, 0x7e3e50df, 0xccab6a57, 0xf522d7f3, 0xbe316edd,
- 0x86d851d9, 0x6f9fadef, 0xa4bc6377, 0xef58fd37, 0xf9e3e40f, 0xb7da2bb7,
- 0xac3c8190, 0x7e3e7dc8, 0x2e15382b, 0x1e6bf727, 0x17363dcc, 0x8bd543ef,
- 0xf1add8bc, 0x8adefa66, 0x283ae052, 0x58abf585, 0xb3b26e43, 0x62c72166,
- 0x523bf53d, 0xfbb8ef28, 0xd7f68d3c, 0xc23cc1a1, 0x88bd74f4, 0x378e745b,
- 0x2941dfa2, 0xd8a7ae2c, 0xa78d1a42, 0xbc7d33db, 0xf1bdff9d, 0x4f7c8976,
- 0x28c73c7d, 0xd61cfae3, 0x439f5a36, 0x78fa41f8, 0x3d7d70bb, 0xe37c8de4,
- 0xf0beb878, 0xd71b46f1, 0xd1b5b0e7, 0xf7121cfa, 0xdbc73a6b, 0xbd78f3d9,
- 0x2237b38d, 0xf72f4fff, 0xdc13ff0a, 0x180e7643, 0xf9c6c534, 0x330b69f9,
- 0x92bc039c, 0x1ff3edcb, 0x595f38f2, 0xc97ae36e, 0xfdd2b2e2, 0x8bae89a4,
- 0x95af91bb, 0x173a663d, 0x26dfe253, 0x3c4e4b3f, 0xa7da24c5, 0xfe7c26b2,
- 0x17bf89b4, 0x98f6b048, 0x5fd7b367, 0x2c333a34, 0x55a89dae, 0x6b6f309b,
- 0xe195aba2, 0x6f128039, 0xf12bf5a5, 0xea1460f6, 0xd8098d5f, 0xfe83ec1a,
- 0x8bdf50c4, 0x974f30b9, 0x15c5e5c6, 0xf9883d6f, 0xd0e58954, 0x9e3e186f,
- 0xe4cc7c16, 0xb0b2b4f6, 0x791d42fb, 0x5cba1f1c, 0xc36fce47, 0xc6878e60,
- 0xea2af049, 0x8e3c31cd, 0x3f70fa73, 0x7accc7da, 0xfb83da34, 0x063bd3fc,
- 0x73bc1097, 0x9c01e52c, 0x0a763c3e, 0xed666bee, 0xd826669c, 0x3e315ac4,
- 0xdde76b33, 0x929e7c66, 0x1dfe88c1, 0x5fa4ad67, 0x255ced67, 0x14d3ffda,
- 0x0e645f6c, 0x1ae304fc, 0xed1d0f45, 0xb19b7183, 0x63fa178e, 0xbedcda79,
- 0x7477bf01, 0x857eca87, 0x73779bee, 0x7d4d039c, 0x0b748ed9, 0x977ec5c6,
- 0xe697cfcb, 0xe7858f30, 0xee29788d, 0xdb68fe30, 0xfc82bc71, 0x628ea69d,
- 0x34f76e3c, 0x9cb027ab, 0xc84ad214, 0x9ef56c2d, 0x5b4a72c0, 0xbbba0975,
- 0x9c361fa5, 0xb861b2c0, 0xdf8877ef, 0x2a8e0fc3, 0x49c60678, 0x68dceefd,
- 0xb7d277f4, 0xa41e4e84, 0xee85b1b8, 0xf22dedb9, 0xde3049d6, 0x8ed7b75e,
- 0x7c6f6876, 0x6bf499ba, 0x5a0af56c, 0x866880e7, 0xfaabdceb, 0x6fbfd0a2,
- 0xef46e714, 0x2c4731f8, 0x7f3479ec, 0xbfe099fe, 0x1ed7aaad, 0x52a0724b,
- 0xfc2283be, 0x49e67ab4, 0x3b284342, 0x1b8c413c, 0x3d70f5ee, 0x7ef8501e,
- 0x036f9b19, 0x98ae8ebf, 0x29e8bb9a, 0x7f31b26b, 0xec1bdc1a, 0x50ed1657,
- 0x883fa217, 0x06116ed7, 0x13bfc1fb, 0x743db8c4, 0x673a2e28, 0x172fe7d0,
- 0x7c617f42, 0xad9ff386, 0x8fa7bd74, 0xf6160eab, 0x5ed3f041, 0x9f4fef1f,
- 0xb760ec6f, 0x731b5ef8, 0x923e719b, 0xc3ac0f98, 0xb09f361c, 0xcebeb476,
- 0x892d3379, 0x30f59fdf, 0xb996af7e, 0x3bf5b0e5, 0x44bb5e6d, 0x22acd076,
- 0x33343aff, 0x28704bdd, 0x04fba73f, 0x1ac8eb91, 0xdf69e3cc, 0x051f6197,
- 0x79a699eb, 0xf7e5ca18, 0x55f90f55, 0x78e580b2, 0xe3c987ee, 0xd84b3127,
- 0x49f8e57a, 0xb41a6ed4, 0xb4e7f8c7, 0xf21a3ea2, 0x54d674eb, 0xc17df2ab,
- 0x5f984c89, 0xfc866316, 0x4fc05974, 0x9650bf96, 0x71abc6e6, 0xe8392d0d,
- 0x8cb03d17, 0xd76a8cf2, 0xf9c56b4f, 0x6bace526, 0xef7a8389, 0x2cee9c57,
- 0xfb0dc79f, 0x790d91ef, 0x002bc9cb, 0xf75f3f0e, 0x07e06119, 0xaf9d7b43,
- 0x8aa95314, 0xcfb9847e, 0x3059dd8d, 0xedc9d97f, 0x6cb87837, 0xf2f10f6e,
- 0xf0257c6e, 0xc667d3af, 0xa7c24ce0, 0xb3bc70ac, 0x277ecd0e, 0x1bf113a7,
- 0xd5e309fd, 0x3e62d880, 0x14894d7d, 0x8ea1fbc4, 0x012cf6ce, 0xa7491ae9,
- 0xeec75b74, 0x957f5c2c, 0x23dbf299, 0xc47e0af1, 0x67c8699d, 0x1ea9e26b,
- 0x3abe539e, 0xf6752266, 0x1b04f523, 0xed4df1e9, 0xddc1609f, 0xf8d64f3c,
- 0xe0be293c, 0x8a429c9d, 0xcc9c6847, 0x0dacfac6, 0x8c62ba46, 0xa278f509,
- 0xb4a182c6, 0xb4e7a75b, 0xa612c6f8, 0xceaba774, 0x7b7d2977, 0x10f2f3d6,
- 0xea03b093, 0xf3d41cb4, 0xfff26609, 0x84e609bc, 0xd6f07df0, 0x725f7cc1,
- 0xe90a2bdb, 0x4ede766f, 0x50b4eff7, 0x13f41f5b, 0x93335d27, 0xa9d6fe7f,
- 0x834d8f63, 0x96aff272, 0xc9bb61d4, 0xbf46edb0, 0x372be862, 0xbf262c46,
- 0xe5172da5, 0x3a1655f5, 0xb1f682d9, 0x827142d5, 0x536f9fcd, 0x35fd2127,
- 0x7d3e7146, 0xb98323dc, 0x25a5fa9d, 0x9a7d25e0, 0x7e46b326, 0x6be3765e,
- 0x3e3c4e9d, 0xb2c77944, 0xabddaf89, 0xbd935755, 0x3663c94c, 0xadb7c78a,
- 0x21bc7b24, 0xccbca19a, 0x41ee9b56, 0x1765f678, 0xb37f4333, 0x2165b735,
- 0x3f091f9e, 0x59aa8e73, 0x69a96226, 0x3f9db9fc, 0xe87aab9f, 0xc3cd5cf9,
- 0xbf7c2b9f, 0x681aa77f, 0x777f43f3, 0xec6e712a, 0xcbcd4eef, 0xa8dbafeb,
- 0xffec14fe, 0x47b4efd0, 0xebd45405, 0xfccd170d, 0x4d17ce7c, 0x2955befc,
- 0xfce37568, 0x4f74cd0a, 0xba24fc0f, 0xf54bbd5f, 0x7deafdd2, 0x088c97cc,
- 0x3670b57e, 0xc6afd1f9, 0xd5fee99b, 0xe5331eab, 0x642a0581, 0xf0521f7e,
- 0x29e5abd1, 0x8e967e74, 0xdd7a44c8, 0x643f2763, 0x62441e2b, 0xdc7ef2fb,
- 0x7fdcc85e, 0x9e2a3fd8, 0x2c6d3bda, 0xe0f914ae, 0xf2f94cb0, 0xe3cf1fdf,
- 0xf4a1f298, 0xae6bfa20, 0xcbbca30a, 0x3f389385, 0x39454c68, 0xc469a198,
- 0x987b35f7, 0xdc937666, 0x5740fbd3, 0xc2aee75a, 0x22fa4af7, 0x24d346bc,
- 0x7d06182e, 0x1ef85351, 0x4ccf83c7, 0x0abbeff9, 0x49befbc5, 0x5d7c7087,
- 0xf90b07ce, 0x774af5d4, 0x3f51a43d, 0xda49d88e, 0xc306804e, 0xfbff2800,
- 0xf51cf0ad, 0xf74c9c42, 0xca1706c6, 0x97587521, 0x7e8b27dc, 0x94f90b07,
- 0x2ce51a8f, 0x7e1190eb, 0x7eefc85c, 0x62fb9216, 0xce8c0dbf, 0x1837facd,
- 0xc7cec1db, 0x522c7a84, 0x3f0baf8e, 0xdd0f1233, 0x79ebecf0, 0x0aeb5d9d,
- 0xbad36544, 0x425d7ccc, 0x5b2a65df, 0x2aa679e8, 0x179c6e6b, 0xd70f786b,
- 0x0c90ffdf, 0xabd02a0e, 0xe31b3cd0, 0x3202333c, 0xac99bba9, 0x37c5f48d,
- 0x88ab7bad, 0x33ae4573, 0x06db7d72, 0x64bf5c4b, 0x37e4bcf8, 0x37e4cb25,
- 0x6303d659, 0xe56bc70c, 0x23b79dde, 0xeece875d, 0x59da0433, 0x62a5581f,
- 0x7a155a5c, 0xc4b5f2c9, 0x3b61ebf9, 0x7125abf1, 0x7df84e46, 0x24da919b,
- 0x51c50875, 0x841c9eaf, 0x2d77c771, 0x3d48ff84, 0xc7086637, 0x637698f3,
- 0x8bb8e45e, 0x7c7911d1, 0xdbc8bcc6, 0xc88bf7ae, 0xc888cbe3, 0xa8621be3,
- 0x888eac9f, 0x171be3c8, 0x6c57c791, 0x4ce7a780, 0x9be3c88f, 0x28ef8063,
- 0xbed0c7ba, 0x50d8b3cc, 0xb574a73f, 0xef4efea1, 0xaef806fd, 0xed0d87f2,
- 0x0c6afbe7, 0x78acf7f5, 0xfa0f50c4, 0x73b8c7a2, 0x87ae10f1, 0x6d3c936b,
- 0x103081f4, 0xfe0f6f78, 0x1dcaa480, 0xd9c7f6e1, 0x56a2fecb, 0x7d29e3d0,
- 0xe248127f, 0x8f116671, 0x10c47705, 0x9d8d0daf, 0x517dc766, 0x444b4d9a,
- 0xcd7ecebb, 0x585806ed, 0xc4e6f9c3, 0xdda94b07, 0x3a74d8fa, 0xfc027987,
- 0xc0e81f6c, 0x77cf20da, 0x6f0017e9, 0xabf79e1c, 0xf5da1285, 0x78a56ebb,
- 0x583ce76e, 0x5577f529, 0xf3ea2f9c, 0x43f18fdc, 0xecdbee1b, 0x54cf3254,
- 0xe28e3f1e, 0xe9751eed, 0xc31a96e7, 0xd6451d7e, 0x164be500, 0x30ac5b06,
- 0x8fd05adf, 0x97849af8, 0x55dda1ec, 0x3de9bb45, 0x127f1ab0, 0x96520fdd,
- 0xe8160284, 0xbf27eab2, 0xf0e3e1f8, 0x1463e2be, 0x27f878a7, 0x7e21fcbf,
- 0xc43fc407, 0xc871744d, 0xeefbcf1c, 0x874ba7fd, 0xbac65f51, 0x64625ee8,
- 0x9b7de27d, 0x26eb7abe, 0x3c16fbf5, 0x37a5dbf8, 0x8ddeff7b, 0xd586b767,
- 0x597f36f7, 0x613cc7e9, 0x356a907c, 0xcbd5c3de, 0xaabe0bef, 0xf8a56b1a,
- 0x57c92ce5, 0xe5fcf28f, 0x707affd8, 0x45f7bc3b, 0x717bb5c9, 0xbfcf077f,
- 0x1da1cf8f, 0x948bf5e1, 0x3cf8a92b, 0xfff80865, 0x58a36768, 0x6f7cf98f,
- 0x8b7ee10c, 0x41d1589c, 0x2b04f3fb, 0xf65c87c5, 0xee3fa3f9, 0x447358cb,
- 0xf71ea0bc, 0xf7a760e5, 0x1e88f88a, 0xf4417f2f, 0x92944473, 0x41ce9f3a,
- 0xf7403d98, 0xb17f7562, 0x8b383c9b, 0x651bee18, 0xae10be45, 0xac125b17,
- 0x54901f14, 0x4b77e52b, 0x2efa28ea, 0x7d1b04a2, 0x2872473c, 0x68cfb46d,
- 0xf1451849, 0x86342900, 0x128a0ce2, 0x40defea2, 0x7ee024ba, 0x77dfb8c6,
- 0x5d682bd9, 0x3acff7bd, 0xeb49f79f, 0x79889c61, 0x1f5878e0, 0xfc41ce39,
- 0x9bda1c2e, 0xe31ef665, 0x4c86d71b, 0x4af48e3c, 0xbeefb5b3, 0xfdf5e51d,
- 0x5eb2f59e, 0x307f9e62, 0x86673f0c, 0x605f13a4, 0x6c307f7e, 0x0fe3cc5c,
- 0xe8038187, 0x60c1079e, 0x42d8066a, 0xb9f88351, 0x6f578d05, 0x3fc892d5,
- 0x7487f304, 0xe7908dfc, 0x61af023f, 0xc3ec57b9, 0x635c83f7, 0x255f84f9,
- 0xc800ed3f, 0xfb4fc21f, 0xfd0654dd, 0xfa365439, 0xe43faa35, 0x88f8222f,
- 0x51f043df, 0xcf95297f, 0xfcf4bdfa, 0xc1397f39, 0xa8fbf53f, 0xa0aff26c,
- 0xabf82fe7, 0xbfc97e09, 0xa39fe091, 0xe785985f, 0xbe547513, 0xfaa06fea,
- 0x09fbfcd7, 0xa41fc37e, 0x4a3fe432, 0x9bf98fcf, 0x6fe13e08, 0x7f6df826,
- 0x7f56e088, 0xf8ef952b, 0x29f9e8db, 0xa30487ff, 0x45fee23a, 0xe03f19d2,
- 0xd9817125, 0xe25e7e8d, 0x4bb34582, 0x2e57de00, 0xd7617dd3, 0x41d2f97c,
- 0x34278be0, 0xfb7bf699, 0xee299856, 0xfb95fba3, 0x16c7d62a, 0xaa5cfd53,
- 0x268d486f, 0x12ff6cbf, 0x571fdd2b, 0x967f7256, 0xbda8552d, 0xfd532f92,
- 0x92e62b13, 0x538f58df, 0xd92ae700, 0x1931d81c, 0x93322ddb, 0x111fdefe,
- 0xe3ca4dd7, 0x4f293f76, 0x8faff7e6, 0xcfc20546, 0x629b2b29, 0x7355700d,
- 0x30e3e072, 0xc62d59be, 0x1c991b61, 0xcfc7ddfe, 0xaf307ff7, 0x90f9d604,
- 0x03ca4be4, 0xe0717c7c, 0x99d83cdc, 0xc3bdb332, 0xcce4f28a, 0x8d4ed9e8,
- 0xebcfd3cf, 0xfe224e92, 0xe13269f6, 0x61b69f6f, 0x2fee265a, 0xddf4c816,
- 0xf205c48c, 0xe99fb857, 0xfba65f37, 0x994acaa4, 0x816c81e2, 0x0363e059,
- 0xfcdfbbad, 0x0eaf54b9, 0x7471453c, 0x6d13cad7, 0x016fd193, 0x1d11657c,
- 0x39e2c50e, 0xbb88b26e, 0xa68f8fee, 0xf9c8b6bc, 0xf17bff8c, 0x33f009b3,
- 0x8cfc47aa, 0x4f3f09ef, 0xfde3fb88, 0x222277c4, 0x977fa4f1, 0x7df109f5,
- 0x1e06c0f2, 0x376c8fbf, 0x731fcc47, 0x2e3be8ce, 0x8fe93295, 0x23b82c03,
- 0xf998e31b, 0x7e43dd32, 0xb3aad27c, 0x3f3e6107, 0x91ddf3c8, 0x2c9fed07,
- 0x8ea18f91, 0xfde52b8d, 0x1f235c0f, 0x7e02be41, 0xda04795d, 0xe93bbf6d,
- 0x7d94364c, 0x8c16ee03, 0x1f463abf, 0xf989f648, 0x161764f6, 0x80fbbf0a,
- 0x2b4fc447, 0x651a3df9, 0x13dc9ee5, 0x3805dc7c, 0xb5f52bae, 0x0309f8a9,
- 0x930edcf7, 0xf97eca05, 0xcf1c3af2, 0x49d24f76, 0xe0212f1c, 0xc7cbc7d1,
- 0x9e2dbef1, 0x925bbf52, 0xf1bdd3d8, 0x37e1f4de, 0x79f5c1e9, 0x7f513ee2,
- 0xe0f51fd6, 0x8a7696e3, 0x70ce0753, 0x38b4c83d, 0x3917bfba, 0x27f96f4e,
- 0x649f8101, 0x886f3f1b, 0xe7476f7c, 0xf02025be, 0xf28cafd8, 0xe2cb26b4,
- 0xf68cfabb, 0x4627ebdb, 0x726f9bab, 0xd403f31e, 0x1eafa0bf, 0x9fa263ce,
- 0x1fbca994, 0x0267ef33, 0x44f0475b, 0xe4dc0d45, 0xe88f601c, 0x00fd8fc7,
- 0x7bbf1f7e, 0x18adeec5, 0x42d77cb7, 0xc90e74b9, 0xcef49bb7, 0x1fda25af,
- 0x2b0dccb9, 0x17f5878f, 0x9fa97c14, 0x48de6043, 0x79d7565e, 0xec055244,
- 0xadf0c291, 0x88b8f7bf, 0xe3793fa3, 0x9bca58a1, 0x8510dfc8, 0x663edffe,
- 0x2c503e27, 0x0c3f3521, 0x7f898a7f, 0xfe7227cf, 0x7aacf2c7, 0x7132805e,
- 0x32239e14, 0xf519cf7e, 0x75fbcc28, 0xb77f939f, 0xd307c169, 0xfe3c0387,
- 0x0fe74c9a, 0xfcd1a5ae, 0xcc1ff6fe, 0x86f46794, 0x677e1788, 0x63dd096d,
- 0xf712c24b, 0x054fb8a7, 0xa626fc78, 0x9f7df085, 0x09c1fb42, 0xe173e5d7,
- 0x0ab2097e, 0x22ee37f6, 0xb8f2f8a3, 0x6f70d90e, 0x6345cc6d, 0x84bfa07b,
- 0x76a4dafb, 0xa144bb63, 0x15235dff, 0x7e8ffefa, 0xd7f5d06f, 0x64c5b97d,
- 0xff49a227, 0x24c9a93f, 0x2a164fcf, 0x76ddb107, 0xfb84bb3b, 0xbb7cc744,
- 0xc5a07a8a, 0x557a4d15, 0xfe4d1119, 0x6394f6f3, 0x9fc076f6, 0x2a07e46d,
- 0x6c032bfa, 0xbb1883be, 0xab73edfe, 0x218d25e7, 0x5df5de3d, 0x3bb022e3,
- 0xf282f978, 0x9decd699, 0x1579899c, 0xd8eefa66, 0x7ab73c7f, 0x2277f86f,
- 0x307524d3, 0x84ec57cf, 0xe0dfa157, 0x418fb9c0, 0x33ea063f, 0xd7c61cf0,
- 0x29217a8e, 0xf905babe, 0xb6395eaa, 0x85d0e282, 0x2d57a4f1, 0xea10eabe,
- 0xc0ad7a89, 0xbadf2e1e, 0xdcaadc9c, 0xd5ce293f, 0xbffe49be, 0xe4dedfa9,
- 0x2e5c95fc, 0x01c5bd77, 0xb77e7df4, 0x5ebec4fe, 0xdfdfc21e, 0xe079f42a,
- 0xbd47b5ac, 0xd72866bf, 0xef224517, 0x297c5661, 0x567e7f7d, 0x3cc65da0,
- 0x2e50cf50, 0x1c12fb47, 0x2fb0cf94, 0x7e30858d, 0xedcf981e, 0xe20ad903,
- 0x538a74a7, 0xd4da9bd5, 0x0a43d200, 0x2e2e91b9, 0xefe187d8, 0x6ddfd478,
- 0xf977d20e, 0xfc28be82, 0x63f41e3e, 0x852817d8, 0xe4d5e2dd, 0x6871ebbf,
- 0x7e008efc, 0x82b687ff, 0xca3a82e0, 0x9b9df4cd, 0x7426f7c8, 0xaedbe118,
- 0xcc89e11b, 0x629abdf8, 0xac9e11bb, 0x43a1e11a, 0xf6e2bef9, 0xa9f3e324,
- 0x6fdc236e, 0x9994637e, 0x78a0ffdf, 0x0c147e95, 0xb8c03eff, 0x64017f58,
- 0x60f7e20c, 0x21afb7fb, 0xe8ff507d, 0x7eff920c, 0xcae2226b, 0x8195b00c,
- 0xf3e36a71, 0x2d859cc4, 0xaaed7e98, 0x87be2390, 0x2ce746d2, 0x73c30f80,
- 0xf20b7cfc, 0x9e6ce1ff, 0xdc30d9ff, 0xc8e87937, 0xde1c79ae, 0xcfce9b33,
- 0x035f562c, 0x28c74efd, 0x36d2ec99, 0x9b75d399, 0x35ba72a6, 0x5779d327,
- 0x60b44aa2, 0x5d5f3645, 0x4723c61a, 0xc91e299a, 0x3df9e21a, 0xd3fae7f4,
- 0x2c6241f9, 0xe773439f, 0xfa47dbfe, 0x40d89d97, 0x2afb03e7, 0x788efa64,
- 0xf9403db2, 0x2bceb053, 0xce963886, 0x39f9f3b7, 0x50d7ac0a, 0x62bceb0f,
- 0x101f97e4, 0xa2f5f49d, 0xf0c206bc, 0x081a7280, 0xbe699b8f, 0x940788e5,
- 0x51e7f0d7, 0xba16ed99, 0xd3d62d4f, 0x7aeadc9b, 0x579c48a3, 0xd76c79eb,
- 0x1e7a98c4, 0xff9106db, 0xe234ecda, 0x24f95ae1, 0x6b5c338a, 0xebed139b,
- 0x2f418e49, 0x2f5c6c04, 0xde1db960, 0x7bdfb943, 0x1c54e163, 0x2044f50f,
- 0x16147bec, 0x6dffa7c1, 0xc221b3bf, 0xeffb3f2f, 0xf9186a47, 0x9e208f9d,
- 0xe39c072a, 0x77c5edf7, 0xb6782cbc, 0x3ea5cf07, 0xcb7aaf9c, 0xcae9af1b,
- 0xbae3b5bf, 0xbfbc88a5, 0x5af8112b, 0xbfa5f02f, 0x274d457f, 0x2d695d3c,
- 0x2786f7b6, 0x1327f426, 0x332f13fa, 0xbb3e2ace, 0xec634121, 0x9fdfe799,
- 0x671d0327, 0x985b3ead, 0xcf9bf00a, 0xcfc39eff, 0x3fa97d9c, 0xec361d34,
- 0x3df879f3, 0x9d8f598c, 0xa1a296bd, 0x85de26dc, 0x8a70c3df, 0xbe7d1973,
- 0x092f78fa, 0xf1b5597d, 0x90671e1e, 0x357724bd, 0x01c52f2e, 0x70ef8cbe,
- 0x5542f9e2, 0xd16b8742, 0xd57ef44d, 0xfbf97bc6, 0x0a353e98, 0x5cb889f3,
- 0xfbf3d6cd, 0xfdf98d4b, 0xd22ae74e, 0x5016367b, 0xd9442f51, 0xeebe743d,
- 0x3a26e619, 0x72b4c9dc, 0xceeebe7e, 0x5accfa42, 0x3fd1ea6d, 0xe7aa1d6c,
- 0xd5be86fb, 0x2bdc4cb8, 0xda245398, 0xc65fe3a9, 0x7b34ee71, 0xf05fa2b6,
- 0x482cc67f, 0xcf41b740, 0x75d21a7f, 0xadd0ef4f, 0x759cffdc, 0x496dc4de,
- 0xff278f0c, 0x575f3871, 0xed009c78, 0xf9746f46, 0x3c5d1bac, 0x89ad0714,
- 0xa8ba70f3, 0x48cdce1d, 0xd70ed897, 0xd7debc96, 0x113e8ddf, 0xf82ab8f8,
- 0xe42bfd1e, 0x9fc26fd7, 0x4f3d1f4e, 0xcee4c6ac, 0x40e67f22, 0x147c437f,
- 0xaf6e0236, 0x76fe67a3, 0xc88f7d87, 0x38a5e49a, 0xcb5e2593, 0x9ae67cc1,
- 0xe63d49bf, 0xe30f6777, 0x6766f37e, 0xaf17dd34, 0xbee95a71, 0x27738b5a,
- 0xaecd3f43, 0x94bc236c, 0xe618eb38, 0xb3a6d5d1, 0x06edfe26, 0xad715e63,
- 0xef5e6ef3, 0x9dacb3e2, 0x2e31eba6, 0xb4e7b5cf, 0x8103b418, 0xaf2edfd3,
- 0xbfe76e58, 0xbd5bd25b, 0xcf1a6e33, 0x295a762b, 0xb18a58af, 0x5794f756,
- 0xc7c117fc, 0x78beb82d, 0xa78f0f5c, 0xbbb2ebe9, 0x3e23fe79, 0xd59a78c7,
- 0xafdfa3ed, 0x97ffd7d1, 0x7a2e9ca1, 0x9abb9b7b, 0xac97dea1, 0xacf51b9a,
- 0x884fbe24, 0x4c272476, 0xffe3ea5f, 0xef85a869, 0x4a953597, 0x8ddb9db3,
- 0x39eebf59, 0x30f47c3f, 0x9dc92dd3, 0xcdb337ce, 0x97466f3c, 0xd58ab9ef,
- 0x5cc37e83, 0x7af28925, 0x2fea02e6, 0xffb585c6, 0x1efc5dce, 0x2125acaa,
- 0xee3fbd3f, 0x07df97b6, 0x2e983df0, 0xa9bde9e2, 0xf59fba16, 0x7079899e,
- 0xb79919eb, 0x4ec6f5e8, 0x1de3edc6, 0xa2d6ce33, 0x620c6638, 0xb0e43f74,
- 0x78e762b3, 0xccc3fe46, 0xae60d061, 0xde326caf, 0x9e5d98c7, 0xafb616ff,
- 0x8f407612, 0x49f55717, 0x91fe520d, 0x6c339be4, 0x3f8dc624, 0x6242559d,
- 0xdf4a91df, 0x4f6aecbd, 0xf6b0e371, 0xd3fb45f3, 0x1d71c469, 0x2b83ddf4,
- 0x3e8bb1ea, 0xf287d137, 0x8bf12221, 0x9dff0a74, 0xa07f5d35, 0xfe1167dd,
- 0x48fc3879, 0x13dd394c, 0xbd57edd0, 0xf578e7a5, 0xbd0986af, 0x38adcba9,
- 0x1f33b087, 0x4c91345d, 0x1ea7ee5e, 0x67d9f67d, 0xea7e5d5d, 0xf49f610e,
- 0x8333a27e, 0xf98d1954, 0x549a502a, 0xaca3f10f, 0x60052756, 0xdaffdb9d,
- 0x27f7fdf3, 0xf01e7975, 0x2fb61260, 0xb072fb71, 0xdf17cc8c, 0x072cba96,
- 0x34db72e5, 0x946aeedd, 0x9cedbe37, 0xbe7437fb, 0x1bcf0efa, 0x9d90196f,
- 0x4a517988, 0x59be45ab, 0xe415a65e, 0x3d137dd5, 0x3ff7156e, 0x631b1db7,
- 0x36f4f8c7, 0xcf0da0a5, 0xf129b777, 0x536db405, 0xde901e78, 0x5e78515e,
- 0x78f1a29e, 0xbcf0a2b7, 0xa77f3d39, 0x84dbc065, 0x03ddbd0f, 0x8d15af82,
- 0xd288e3df, 0x5d9da81a, 0xb2f7d2f6, 0xe28cf1ec, 0xff957652, 0xa67450ee,
- 0x907bd999, 0x2cc3b5d7, 0xe5b61f64, 0xa24db415, 0x146ec9f9, 0x05496d93,
- 0x1147a449, 0x8d7ef0ef, 0x316f13a3, 0x0a9fc788, 0xd4fdebbc, 0xde75f0b4,
- 0x417771bb, 0x23f45f49, 0x5f9087bd, 0xec8b29b7, 0x7246ef78, 0xbfb4de14,
- 0x432661e6, 0x7f57663e, 0x7f450a97, 0x24fec53f, 0xfd8a8147, 0xbfcf5859,
- 0xe8b6f8bb, 0xef3defe7, 0xfa360cc0, 0x226308de, 0xd494268f, 0x2761f9d3,
- 0x631cf0fd, 0xfef7f744, 0xbd677edb, 0xfe09de31, 0xbf516fe6, 0x7b9de654,
- 0xe13d127b, 0x68d6e6fe, 0xbf742fae, 0xfb795651, 0x0f7e66ad, 0x9abeff55,
- 0xb1ca47ee, 0xdd743c46, 0xb874e303, 0xc838f2aa, 0x7c518555, 0xafae5226,
- 0xb86e3a9e, 0xd8768147, 0x2c71fc23, 0x0cf4cfd1, 0x2e2973c2, 0xa3dcbadf,
- 0xebfd444e, 0x1f7f7728, 0xa8a4abbf, 0x30b7ca66, 0x5f12ff01, 0x9243de77,
- 0xc6cff47a, 0x3574e70d, 0x24685625, 0xb7284ae7, 0xe03f3927, 0x728b953a,
- 0x1ecba07d, 0x03aeb8ab, 0x1389dce7, 0xbf5ce4c3, 0xbff7a21f, 0x3564e4fe,
- 0x74df5d7c, 0x6e79c2ff, 0x8f64fde7, 0xff1edc5d, 0xd8c7df6f, 0x40aeb2ea,
- 0x326cdffb, 0xc391e5ea, 0x86d63eb9, 0x75e0f88b, 0xb3b7ee99, 0xe1b4bea1,
- 0xd98b3f80, 0xf97a8e5b, 0xdfdf3540, 0x1499b1ca, 0x7eb03987, 0x829e445a,
- 0x30f0d06f, 0xb3aa2c79, 0x85abbe92, 0x03ed077d, 0x491ae823, 0x3afe9d2f,
- 0xe7e728ec, 0x27bd3a72, 0x91212a26, 0x89fe4c07, 0x09997e2b, 0xdcab9af5,
- 0xb039f267, 0x81d91b7d, 0x115ddade, 0xaf6f4ffa, 0xce0aff60, 0x73e280af,
- 0xa0e75057, 0xfcf6a49f, 0x51976cfb, 0xec7e0498, 0xb1e72eb0, 0x2bf62aa9,
- 0xab793f09, 0x51af6fc8, 0xb09eed0b, 0x42d8a5f7, 0x3e30a4fb, 0xde25e9a9,
- 0xc7ae1fe4, 0xefb4439b, 0x4810efd7, 0x9e60d7e8, 0xee5f22a0, 0x7ed0478c,
- 0x9df0d4a2, 0xdefc7d45, 0x5f39edcf, 0x690b555f, 0x018f281f, 0x0bfc017f,
- 0x8192ec53, 0xbe2d3764, 0xfcc44e7f, 0x28dadf95, 0x2123f79f, 0x3e42ed9f,
- 0x0163d37b, 0x2d2e8c76, 0xf027616e, 0x49f008d2, 0x49f20c41, 0x70d98a4d,
- 0x9b97a3ae, 0xe26f3ac4, 0xbf0f54e7, 0xc1e73f35, 0x39f83de1, 0x9f84c7e8,
- 0xe2ffa3cf, 0xe89bd309, 0xf07a78bf, 0x62cdea73, 0x53ce27ff, 0xcddc5b4f,
- 0xd39780ed, 0x3be86213, 0xf87d193f, 0xe8d3df3d, 0x7f8015f7, 0x4cd9ccf7,
- 0x532cd624, 0x843a77e7, 0x0608c99f, 0xca276f3f, 0xaef31945, 0xd5bddfc2,
- 0xdf8988e5, 0x3a26f9a3, 0xe0dc06cf, 0x3de3b6bc, 0x87ba3cbc, 0x39d3da57,
- 0xfe4eb1de, 0xc7a61301, 0x401f08fb, 0x5a38b09d, 0x4460f8b7, 0x31c3103c,
- 0x19c5f99d, 0xbf6fdbdd, 0xf9f8a261, 0xe20b1f2e, 0x51dc02ef, 0xbddf8c64,
- 0x76d9f225, 0x7f24612d, 0x429a72bb, 0x6a245fe8, 0x65f1e28c, 0x39fb631e,
- 0xbddf91a5, 0xeef9c636, 0xe7225af4, 0xebb5df4b, 0x7fd7d627, 0xff8a2acf,
- 0x22fdc645, 0x3eb47de3, 0x3c8523b4, 0x1854afee, 0xf51cb8f3, 0xd8bbe833,
- 0x714af860, 0x3314ae7d, 0xa3ac38c3, 0x2dcf323c, 0x21ecf020, 0x59e3a665,
- 0x92899eff, 0x6bdfe66f, 0xf546dc0d, 0x7e1dbe7a, 0xaba27177, 0x3aca5d6b,
- 0x117c9f31, 0xbcf40dcf, 0xd7185dae, 0xbce8bcc4, 0xd084d036, 0xc605ce1f,
- 0xf460ae49, 0xb75857bd, 0xf0e25ce1, 0xfa262d9e, 0xa31f0f1d, 0x1e01a1ef,
- 0xcc16e78c, 0x5850f147, 0x039ce1bf, 0x238069d6, 0xe4df01f7, 0x93de1fff,
- 0xa277e3de, 0x278f52f5, 0x61338b75, 0x2fa48007, 0xbdf38b86, 0xfa286ca1,
- 0x06fe4a41, 0x1495c3a2, 0x72cb5f9e, 0xdbdf3e7a, 0xf7e1fd09, 0x72887e93,
- 0x01718092, 0x04def866, 0x0f74c8f3, 0xe7c454c0, 0xe5ebea6a, 0x48c79742,
- 0xccd16dbe, 0xa684798e, 0xea0f6882, 0x600d9b13, 0xf8852efc, 0xee24b74e,
- 0x283ffd3f, 0x00812bd4, 0x0000812b, 0x00088b1f, 0x00000000, 0x9095ff00,
- 0x50c34b31, 0x97bf8514, 0x4a36ac46, 0x1056dac1, 0xa8508a09, 0x755a5095,
- 0x97375433, 0x221d0e8c, 0x38ba383a, 0xfc5d251b, 0x09f9ce01, 0xe6e284fe,
- 0x482ae0e6, 0x22bf8290, 0x26a697de, 0xcbbd0820, 0x77dde779, 0xddf73dce,
- 0x2e8dcc2b, 0x5eca7550, 0x75619047, 0x444506d2, 0x9aea1152, 0x47e17536,
- 0x3cd6a5a4, 0x7c22c128, 0x4c12092e, 0xecbbaa75, 0xfbd45ab2, 0x5ffed246,
- 0x73e4ec6f, 0x7569fd73, 0x27e7cad2, 0x22ff8eba, 0xba77e898, 0x00839d12,
- 0xe4e3e1d6, 0x65f68fbd, 0xc8773d13, 0x5f94dcac, 0xd53da3e8, 0x3970079b,
- 0x3adf376b, 0xdbe20d46, 0x0aa8f38a, 0xa567047b, 0xfd398f74, 0xed34737e,
- 0xb0a56f2d, 0xef37e657, 0xbf89695e, 0xc21b71a5, 0xc1ec8481, 0xc81447a8,
- 0xbe0daad1, 0xb9417dcd, 0x3e99cb8b, 0xbf05c593, 0x67eb81f0, 0xf3ba7931,
- 0x8416bf0f, 0xcb62bcbf, 0x5f1dd7ff, 0x7f74f68d, 0x6b7d238c, 0xbb92f72c,
- 0x50a8dce1, 0xd9f695f8, 0xf4112ed5, 0x738dbcf3, 0xf3e569f1, 0x742b007e,
- 0x02505747, 0x00000250
+ 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, 0xe24bff00, 0x51f86062, 0x38cfc10f, 0x90981819,
- 0x770143f8, 0x01684331, 0x21060616, 0x62636620, 0x22676060, 0x072bbf5e,
- 0x9d877d82, 0x1038e181, 0x781f67df, 0x5e240d7f, 0xbb3f4dcd, 0x2ed1d37e,
- 0x7e27f062, 0x02af8606, 0x058b0c0c, 0x210b7c21, 0xfccff954, 0x18a47608,
- 0x02a57665, 0x150003f5, 0x8051b77b, 0x008051b7
+ 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, 0x7dddff00, 0x45547c79, 0xbedd70b6, 0x97a7774b,
- 0x42c84274, 0x4010dc20, 0x804d8854, 0x024de3b0, 0x10602a31, 0x66b71c11,
- 0x04484b0f, 0xd3ce7cde, 0x0831baf9, 0x544e38e8, 0x387c0666, 0xa8d041af,
- 0x1a0c1a51, 0x166bc3b0, 0x26665419, 0xb8c38e3a, 0x6c8a89bc, 0xfd011242,
- 0x5f283798, 0x3b75539d, 0x4dba6f7d, 0xe3fbe65c, 0x45a7efcb, 0xeab7badd,
- 0x9cead9d4, 0x25aaa753, 0xd7a92059, 0xfe197212, 0x48a6f968, 0x51d11908,
- 0x1fb715b6, 0x04846927, 0x6dd5915e, 0x7fc22102, 0x0ed722b9, 0x16c8e427,
- 0xf5a56821, 0x21075ec8, 0xd3767eb4, 0x9735a0b4, 0x0e057d90, 0xbb3fde0d,
- 0x25eb08b5, 0x96e2febb, 0x2ee57b68, 0x65ba8251, 0x8b7729ef, 0x6b2a9093,
- 0xe963a3f3, 0x225df6f3, 0x228742d9, 0x490b1281, 0x8db8e427, 0xac8bbfb0,
- 0xaacec0be, 0xddf79b95, 0x3456fd05, 0xf69d895a, 0xe17bb953, 0xbeb4b1d4,
- 0xe04cb0f0, 0xab6dca95, 0xbeb45e94, 0xa0842828, 0x0fdec0fe, 0x62b69c70,
- 0x4c1a1152, 0x8dbf69c8, 0xbad057a8, 0x067d39bb, 0xb838be7d, 0x5fde14a3,
- 0x2d782f5c, 0x9bc5fdf4, 0xfe819df6, 0xfdc83717, 0x92ffda45, 0x0751073a,
- 0x132fb1b1, 0xa9fcc798, 0x1be56f00, 0x7ad2b132, 0x0a15a5c5, 0xb5491c01,
- 0xc60bb94a, 0x5d514c7f, 0x1c61ce30, 0xe567c747, 0xfa1c7473, 0x0497b2dd,
- 0x996d4c2f, 0x9e00f885, 0x59f6ddd6, 0x5e613b4f, 0xf08194ab, 0x0ab5eefd,
- 0x3830b7bc, 0x0abb15fb, 0x4a566df0, 0x9b4dce01, 0x3b830595, 0xf7525bfa,
- 0xe3ae0196, 0x7c32f21b, 0xf2e6ed31, 0xd5109fb4, 0x4c5f51da, 0x02721688,
- 0xda6541dc, 0x17e78e90, 0xf7a41484, 0xa8913a92, 0x29fe8eb6, 0x49e90861,
- 0xfa17ffff, 0x2683e04f, 0x6e5b7057, 0x7b96bd07, 0x0ed5bfe8, 0x70f39d7a,
- 0x85ed49fa, 0xe5ebfdb1, 0x0a0740a3, 0x83dfad4f, 0x4cfee3e5, 0x55fbd72c,
- 0xfc6fdbc4, 0xe0dcb083, 0x27f3e2f7, 0xdcb0a3fd, 0xfcb0d7e4, 0xcb0cbf9d,
- 0xdf1cbfa0, 0x859fe2db, 0x0fbf56e5, 0xafe33f9f, 0x5fceb2c0, 0xf79fcf8d,
- 0xbd658bdf, 0x5fcf803f, 0x32c3aff2, 0x72c5afe4, 0x96037fa7, 0xbe20fe0d,
- 0x0ebf8af7, 0x087f46cb, 0x37f1ef9f, 0x47f61962, 0xf40bdcb0, 0xdfc465a5,
- 0xff7ee58c, 0xfa0f2c51, 0x43bbf05b, 0x3e5893fe, 0x1eeef1c2, 0x8a248a47,
- 0x3c46b737, 0xea485c54, 0xa648ad64, 0x5672d4f5, 0x5023bf4f, 0xba7ad0a4,
- 0x1e29d68f, 0x148d2d7b, 0x57bd6959, 0xb9cf6b35, 0x68db149f, 0xdac0273d,
- 0x15a23dfb, 0x5fbd69db, 0xb81f6b2d, 0x449c5029, 0xac8303eb, 0x48faaafd,
- 0xafd683b1, 0xfcf6b10a, 0xd2712930, 0xd5847e7a, 0x25688e0b, 0x682f5a2e,
- 0x0fc2f566, 0x5a6e2503, 0xdf616c2f, 0x2913398f, 0x31f5a649, 0xc27daced,
- 0x43d13225, 0x808813eb, 0xd16762f5, 0x2f5a14c4, 0x697ab0f6, 0x1a92d9ef,
- 0xcaf6ff87, 0xe509732d, 0x4dc0ba85, 0xeb45949a, 0xe20acb4a, 0xcc0cf8a5,
- 0x26447ac2, 0x48fda0f3, 0x8d26b660, 0xac8575a6, 0x0efff684, 0xfdf6c62c,
- 0xeded8ab2, 0xbed81581, 0xddb1515f, 0xac7eeab2, 0x6c35941f, 0x20f55b4f,
- 0xd1507fbe, 0xaae07db0, 0x487eb147, 0xa8fb61f6, 0xf7c5bf55, 0x6c3e290f,
- 0x50757c7f, 0xffeb489b, 0x00b6f821, 0xbe08d75f, 0xfc07920a, 0xa72cca1a,
- 0x2046bafc, 0x1e3e40b3, 0xf2a6a606, 0xd14b26b0, 0xfdedbf40, 0x5169f0ba,
- 0x069dbce0, 0x3ccf05f5, 0xbcfd8b9c, 0xb4c8fd80, 0x7eebb11f, 0xca337c26,
- 0x6f84cfd0, 0x1a7ef42a, 0x7b1abde0, 0xfbd9faf7, 0x3c2318cd, 0xfbd62cdf,
- 0x5c7ec269, 0x84d79bdd, 0xf08ce3cb, 0xf7aa5e5c, 0x49fb0873, 0x113c1ee9,
- 0x9fa1a479, 0xef50bc88, 0x4fd84fe7, 0xa3c1eecf, 0xfd0da329, 0xbd22ca68,
- 0x4fd8a39f, 0x89faf756, 0xf08d6328, 0x7ef44b28, 0xfa7ec63e, 0x9a5e6f74,
- 0x1e11bc75, 0xcfdea56b, 0x6e7ba469, 0xefd9faf7, 0xbf67e232, 0xf39f8a2b,
- 0xee80cf08, 0x6dd8abcd, 0x3bb14fc4, 0xd84b9f8a, 0xebdd95cf, 0x88dbbf67,
- 0x28eefd9f, 0xe601647e, 0xf37ba435, 0xe2364e2a, 0x8a3938a7, 0xf000b71f,
- 0x3c1eed0c, 0xf11a7b07, 0x1467b073, 0xcf08193f, 0x33c1ee88, 0x9f88dd31,
- 0xfc51e989, 0xe8cf08a8, 0x3073f5ee, 0x839f88dd, 0x5cfc51e9, 0xef8cfd89,
- 0x6626bcde, 0x3133f118, 0x029f8a23, 0x57c8a7ec, 0xda10f087, 0x3f712b8f,
- 0xf118fa87, 0x144fa873, 0x9fb1633f, 0xbc9fb449, 0xcd29fbae, 0x34a7e231,
- 0x899f8a27, 0xbbebe788, 0x1ca1cfd7, 0xe50e7e23, 0x0533f144, 0xbdd299fb,
- 0x35f69579, 0x2fb4a7e2, 0xd2b5cfc3, 0xe8675c50, 0xe915e9da, 0x2ef5d727,
- 0xbefa04d2, 0xd17561e8, 0xf76025e3, 0x433dba88, 0xbe91359a, 0x294facef,
- 0xdac49878, 0x0277c535, 0xcad45c7e, 0x926bb58b, 0xec192547, 0xd52d14a8,
- 0xd651ef50, 0xcf7ef0cb, 0xf6867ef2, 0x1957598c, 0x057cb3da, 0xc5767a86,
- 0x7dfbc318, 0xf50d8baa, 0x60def7be, 0x70373f78, 0xb79ea1b3, 0xf78627ee,
- 0x31ced407, 0x61b15fb4, 0xcafda1b1, 0xfd4372e0, 0x377fbaea, 0xf4243fbc,
- 0x9afda180, 0xed0d87c6, 0x1b8f2343, 0x3f0ec3ea, 0x447f7869, 0xfb4316f3,
- 0x1bcfa3c8, 0xecb747da, 0x9ec7d434, 0x7f7863dc, 0x437efb7c, 0x6f8bdafd,
- 0x222fde1a, 0xdbda367f, 0xef0c0fb6, 0x6a7cf24f, 0xf32ebf68, 0xea9d9373,
- 0x9abf1cf4, 0x2b9045d7, 0x20497e82, 0x357b414b, 0xaeb052e2, 0x3f3272f4,
- 0x3d40b5c5, 0xd947f946, 0x434d573f, 0xd47fa4be, 0x55ea286e, 0x7d0b4571,
- 0xbe31d3fe, 0xf9f43c2b, 0x35df154f, 0x0df6389e, 0x648137e5, 0xa05aa942,
- 0x95afb734, 0x6717bf19, 0x31f81a5f, 0xd2cabefd, 0xd685303e, 0x2145897b,
- 0x04578f90, 0x49d5da0b, 0xf786a922, 0xfd04ac92, 0x85b9b5a6, 0xe462074f,
- 0x6a1f5d61, 0xfd1d0867, 0x997d93ae, 0xfaad4768, 0xce760028, 0x5e743e9a,
- 0x4d7908bd, 0xe81228f8, 0xb3efbf4f, 0xfb47d320, 0xcfd42ab3, 0xa15f1d88,
- 0xf1c60fe3, 0x870f2023, 0x9d11fc60, 0x1bf6b7c7, 0x96df1865, 0xdf186153,
- 0x3df1d0a6, 0xf55c3fd4, 0x129f1f19, 0x6f210c61, 0xf8e19f09, 0x1c0a9cd6,
- 0xfd42ad7f, 0x93f1d8ae, 0xc337e3a2, 0x344bdffc, 0x8c637eff, 0x6c59cff3,
- 0xe6c2bf9c, 0xb3aafeff, 0x9c24fc7c, 0x59c207ff, 0xc59cff36, 0xd656fe6c,
- 0x777c746f, 0x302dff14, 0xe304f1fe, 0x19c6f35b, 0xa977dfe7, 0x3656fe71,
- 0x5f55e9fe, 0x389df1f2, 0x97c2e7fe, 0x977dfe6c, 0xd58af8e2, 0x51fe05e7,
- 0x83aa93b2, 0x9bd27c74, 0x600cbe2a, 0x940e3a17, 0xd0a95283, 0xe84db210,
- 0x34fc7087, 0x57dbf189, 0x50df9449, 0x39f0059f, 0x59cd5209, 0xce46fd48,
- 0x8bea4beb, 0xd87bd014, 0xf9adfd4e, 0x8d79d41c, 0x5937f222, 0xa00e0d6f,
- 0x8a36b6f0, 0x5bcfa801, 0xfa083e3f, 0xee4acab5, 0x24ef872e, 0x9fe78112,
- 0x96c87afd, 0xcb9979d8, 0xf1f2b5f9, 0x8b791896, 0x64c581fa, 0x6f853550,
- 0x88c13012, 0xd427fa8e, 0xf8c7038f, 0x10f7ea43, 0x2a7cffea, 0x9bfef1b3,
- 0x6f507bfa, 0x3a1efea1, 0x7e1564ce, 0x377bbb47, 0xce5fc293, 0x6244ffe1,
- 0x1dc9faf2, 0xe5403042, 0x0d9fabf3, 0xeefaff45, 0xe9141d7b, 0x0ecc701d,
- 0xe9d430f4, 0xa74002bc, 0xe0d6ddf6, 0xabf10116, 0xa1a6be02, 0x77321268,
- 0x75c5365d, 0xdd7ffbc7, 0xe090e53b, 0xa256e426, 0xfdf419c9, 0x7d0a573b,
- 0x19dc743c, 0xad80b59a, 0x05b65a43, 0x5b649ae5, 0x73721146, 0xf69950c3,
- 0xf269a640, 0xe3312d27, 0xd6332f4e, 0xeb1b9467, 0x5b26b2ad, 0xd3ad5c28,
- 0xf699b204, 0xb196733b, 0xbfa71f5d, 0x99d19525, 0x714e578f, 0xcd1f4592,
- 0x1e00b284, 0xb3ce907b, 0x1d5bec3c, 0x32b9aa9e, 0x1f1fa089, 0xae8049e8,
- 0xef7c3481, 0x6f361e27, 0x64b3bc33, 0xe74e569b, 0x18b66b39, 0xc336fe04,
- 0x875efeff, 0xe5a7c966, 0x626427ba, 0x331f3ce9, 0xccf9b7fc, 0xb0c909f3,
- 0x615edfce, 0xe6f8ce7e, 0x27ffa738, 0x3cb41fc0, 0xe141fc01, 0xa3f9c63f,
- 0xfe32af43, 0xa6fab2a8, 0x6fb43f02, 0x95d20914, 0x9cadcbf3, 0x1ad7e65f,
- 0x9f1082f9, 0x385c740c, 0x3878284b, 0x72660f86, 0xc1b8583e, 0x927737c8,
- 0x87159c80, 0xdfadb72e, 0xdaa660fc, 0x711f7e79, 0x91fdb9be, 0xce9f887d,
- 0xba7464f3, 0xcee9d38b, 0xadfb636a, 0x7277ae9c, 0xf0daceba, 0x7d54ebd8,
- 0x41a89f90, 0xeabde419, 0x2d9e9d3e, 0x38fa7a06, 0xde70cd3d, 0xd779e9c5,
- 0xcd3d18cf, 0x7a70b6f0, 0x2f386cb6, 0xe19d7e93, 0xf777c335, 0x83e69dbd,
- 0x81d9ad71, 0x6aacf4f8, 0x2c715a2c, 0xe86579e6, 0x62c715fa, 0xdd496ce4,
- 0x517d4334, 0xfbc336f0, 0x36cc370b, 0x5dafcfb4, 0xbb9f6864, 0x7d431eee,
- 0x8667e076, 0x77beeff7, 0xcefda195, 0xed0c87ea, 0x663c57b7, 0xdbe6dfa8,
- 0xe67f7868, 0xf686cdac, 0x19cfe519, 0xed97a7da, 0x69a7d430, 0x0bef0dbb,
- 0x6df5177b, 0xf7d575c1, 0xef10199f, 0xf9159bfc, 0x74efacd4, 0xafcc78bd,
- 0xfee3f3e2, 0xf49e5841, 0x69f9f17b, 0x572c28ff, 0xeba6fe81, 0x2b376582,
- 0xdd9f1eab, 0x9742f817, 0x6f654f8b, 0xaed9e80e, 0xbefea1f4, 0xbfd1ef59,
- 0x8a7678ec, 0x48152e5e, 0x6d83ac39, 0x9fd74edc, 0x4ecc2ddb, 0x2c01e420,
- 0x6e4c2a97, 0x2accee97, 0x47a86e26, 0x133b5606, 0x02424bf7, 0x6d7e67ce,
- 0x85ce019e, 0xc136ae1b, 0x6af905b7, 0xe1987051, 0xb1ba92f9, 0xecceef86,
- 0x65be1113, 0x61a3e320, 0xdf7f2b39, 0x7233fa02, 0x10fa6720, 0x00fb5780,
- 0xd13d8deb, 0x2fe33b9e, 0x006c715b, 0xcb1cb9e0, 0x5859fe93, 0xb0fbf71e,
- 0xc0afe63c, 0x357f13f2, 0x7bfe2d96, 0x7f6ffcb1, 0xfd0fcb00, 0xdf7cb0eb,
- 0x51e58b5f, 0xdf2c06ff, 0x7cb107f3, 0xe5875fd7, 0x9610fe3b, 0x2c46fecd,
- 0x961afd5b, 0xf0c4bcba, 0x18acdf4b, 0x9ff5d17e, 0x724f1fae, 0xfc0d397e,
- 0xb62f8f12, 0x84e2f918, 0x617c8d5c, 0x3a6687d6, 0xf7dff598, 0x3f2987e5,
- 0xd0743f12, 0xef44db3b, 0x9de8aebc, 0x7bd0c629, 0xe0c3c58a, 0x05fef4e1,
- 0x5ec71bc0, 0xfb8b049f, 0x483b1888, 0xfac0b22b, 0x2fef9cb0, 0x3f5807d0,
- 0xa1aec7c7, 0xbda335dd, 0xfa041c14, 0xffa0dcf8, 0xf9f10819, 0x51294773,
- 0xcfcf1372, 0x7884bf4c, 0xabe8f180, 0x2e94820b, 0xdbb73a3d, 0xed5e1893,
- 0xe8465216, 0x80d0f17a, 0x0673bc67, 0xa9225d63, 0x3bd07df0, 0x5fa715cd,
- 0x7e02836a, 0x8d6bc2bb, 0xe87cabeb, 0xff93f8ef, 0x8a72842c, 0x49a1d985,
- 0x87b44407, 0x2f69e449, 0xefaa37e0, 0x884cdead, 0x500fb763, 0x931eb83c,
- 0x02fe2312, 0x3dfc06c5, 0x8cd47144, 0x266d59eb, 0x57ffafe2, 0x81bab303,
- 0x64f4aebf, 0x039cf857, 0xe017fef3, 0xd5fd2bb3, 0x9a22de95, 0x9d2352fa,
- 0x21dedb7f, 0x30ab0f05, 0x5be3b7ee, 0xc332b7df, 0x7c8ef813, 0xf3ae96dc,
- 0xa10e7371, 0xf2e59ce3, 0x8ae1ae72, 0xb44ba064, 0x29e82e9f, 0x3947d7fc,
- 0xe6cebfa0, 0x6b5bfb1a, 0x21592fee, 0x5c7435c2, 0x6490a297, 0xbe885642,
- 0x06fd115a, 0xfc004b6f, 0x6f0ebdf1, 0xd8fe0a8d, 0x54463fe9, 0xb7e8d9e8,
- 0xb4fc3b9f, 0xe59bfc1b, 0xb1f56299, 0xcbd47438, 0xb56e50ca, 0x680fd633,
- 0xd5cfd634, 0x9c21650a, 0xcb7c9a97, 0x3c075810, 0xd064c7d5, 0xea5899cb,
- 0x54cf2cfd, 0x7f4a1c70, 0x53ea47a6, 0xf69ccf50, 0x1fbdf0db, 0xfd448e1b,
- 0x40d1c074, 0x83dfa53e, 0x4bce5d88, 0x39427efc, 0x10282e90, 0xf961248f,
- 0xecdff02b, 0xfdcbbff4, 0xeb095fa0, 0x2155bf7a, 0x06bd6031, 0xc61bd79e,
- 0xfaa9dfa3, 0x977c2c1e, 0x7224de58, 0x4a77e75c, 0x7ef837b7, 0x7b3a92f1,
- 0x4c2ed1b5, 0x1aabd431, 0x760daab3, 0x0c03fc22, 0x02410ae1, 0x6729777b,
- 0xb9c936bf, 0x2b68f80e, 0xdf80fb04, 0xa55ef605, 0xa9f145ad, 0xc0cd2628,
- 0xe946739f, 0xfcceaf7c, 0x53a7ea80, 0xe404c96f, 0x50a25c8b, 0x47f47615,
- 0xa1625057, 0x36bcb9f5, 0x64c961a7, 0xbd4eaf58, 0xf5da2372, 0x1bb948f3,
- 0x520acdfc, 0xcff1085b, 0x0652c4b3, 0xbc967972, 0x23161ee3, 0x0545e787,
- 0xcebb99e1, 0x7f531768, 0xb85f50d9, 0x405f58c1, 0x7d874e6e, 0x65eb05f0,
- 0x5f401412, 0x153fdb18, 0x242d1c99, 0x7d606bd5, 0x75b32f5f, 0x48878e6c,
- 0x555f54d9, 0xe154fabe, 0x1fff5a6c, 0xf42dc591, 0xa945dd7d, 0x1c589fcc,
- 0xb468acda, 0x6186d3fd, 0x43cd52b7, 0x81ae0fbf, 0x4bb02af5, 0x3b536ef0,
- 0xc2bbefd3, 0x5f57866f, 0x2fed3bff, 0xeb2a3873, 0xc7182d04, 0x0249b00e,
- 0x580377f7, 0x863c960e, 0x5328c2b8, 0x53f37bfd, 0xd3f0311a, 0x4aa7d156,
- 0x80ff193d, 0xed48253f, 0xf487ef8a, 0xffa9d99f, 0xff6a3fc1, 0x85ff69bd,
- 0xfd47fe86, 0xeff7fda8, 0x6944ff04, 0x2bfee744, 0x95f17d5f, 0x8b27d500,
- 0x4ddaffb7, 0x4a78fae8, 0x52f74daa, 0xf6dd2efa, 0x7ce81ba0, 0x81b80a52,
- 0xc5054f5f, 0xf59c60b2, 0xe0493eea, 0x14e6a2f6, 0xff058e20, 0x7e9ffda4,
- 0xdfe817fe, 0xf64db57f, 0xceaa7c60, 0x3952b11a, 0x68b0d65c, 0xfac7c932,
- 0xf6beacc7, 0x8dea110b, 0xfc5bfe46, 0x21d3afec, 0x0a7282df, 0xd044d78f,
- 0xf5b65d9e, 0x975852b3, 0xca3b48aa, 0x183bf991, 0xea2a62ff, 0x724ad9bf,
- 0x270a76e7, 0x1c55ddfa, 0xbf0d552f, 0x437442f8, 0xd009fd79, 0x4043d417,
- 0x5dfcd8bf, 0x974fb705, 0xe3b4ae4a, 0x232714d4, 0x8bd048c9, 0x90485e3a,
- 0xabe2a7d9, 0x3c43e54f, 0xb7d6ccf2, 0xbe0c42dc, 0x173a7974, 0x7b9ffb9a,
- 0xb77ac4d4, 0xac5bca95, 0x5bafa41d, 0xabb7236a, 0x2a5cacc3, 0x1f90dc47,
- 0xecb374b3, 0x4bc7d00d, 0x99fa7c5f, 0xf83e2127, 0x0077ab37, 0x8bc97fed,
- 0x8637bfaf, 0x90ec97d6, 0x69b326d3, 0x0ef48538, 0xffd154fa, 0xa0e82dee,
- 0x5f97e2c7, 0xec21d457, 0x1da9fdf9, 0x63b25974, 0x7486429f, 0x684947c6,
- 0x8ce2d29f, 0xc7d09f43, 0x882760a5, 0x00ad7eaf, 0x15ed4ffd, 0x1c6e4648,
- 0x1d7e6e7c, 0x13c000ed, 0x2bd393d2, 0xfbd33f4a, 0xa02e9455, 0x32f4cdb7,
- 0xf40537bf, 0x2fd608cb, 0xfe502de4, 0xe40f697e, 0xf56fbd15, 0x5e2a1e02,
- 0xf986e15a, 0x19aa909c, 0x60f53f9f, 0xafc746ba, 0x1ee90390, 0x8af3d92c,
- 0xf21bfddf, 0xffb7c2df, 0x35e31d2d, 0xe0b2cb44, 0x82c8145a, 0x34dfce79,
- 0x80b9e703, 0x2b0f90f8, 0x41cb129e, 0x91297e1f, 0xe4711db2, 0x93973ce4,
- 0x71285b13, 0xd04f3ce9, 0x6df30665, 0xdb8311de, 0x87beded0, 0x37f83e80,
- 0x316a173e, 0x1b4bfd60, 0x921bd7a3, 0xab5197ee, 0xb77f9633, 0x3a066dae,
- 0x65a3ee9d, 0x15463ec0, 0x1f1c0291, 0xafda65c2, 0x0ca4f6f8, 0x4aa22746,
- 0xba3bfc85, 0x73c097ee, 0xd659bf78, 0xef86f9ec, 0x8edce5c8, 0xf1f257f1,
- 0xb049dc29, 0x8f489f5e, 0xb2aab76f, 0xbae807ae, 0x3167c31d, 0x7fe4cef2,
- 0xde4c43eb, 0x4e0ff975, 0x0bf6832b, 0x823932ef, 0xa43d60ef, 0xb0324570,
- 0x022ddf7d, 0x892b07ea, 0xadf393c4, 0x63739732, 0x285f99bb, 0x1c9092fc,
- 0x4e3037c3, 0xf701d22a, 0xa7ac1631, 0xd1e8c7df, 0xddd7182a, 0x8e5d5fb9,
- 0xd07d7217, 0x6407d26a, 0x8903d313, 0xae00aaed, 0xe0e54b7f, 0xfc824f33,
- 0xa80d7952, 0x3972bf20, 0xfaf3ffcc, 0x84fdef03, 0x21e7cdca, 0x7a8d6e5d,
- 0x15b72cd5, 0x7890473b, 0xd3b9fb72, 0x2dcae24b, 0x6e571e7d, 0xcfc82d9d,
- 0xaaf5afff, 0x990cc78e, 0x0eeaf1e2, 0x327aea3c, 0x7acd3e11, 0xc6a4a772,
- 0xeff493d5, 0x99d8525d, 0xd43e751f, 0x0bf16ff9, 0x1f417d95, 0xe754f945,
- 0xea9f28c3, 0x5e29d87c, 0xb9a3c06a, 0xefb0effd, 0xdb62fc01, 0x7518f538,
- 0x015e6d21, 0x338afee5, 0xb4afcc16, 0x5f70170d, 0x0906d064, 0x3c5b6feb,
- 0x9d4ec023, 0xcfd5f63a, 0xbbbe467f, 0xcb7df07f, 0x3f3e2957, 0x6ec84019,
- 0x5f046528, 0xc8e7a58a, 0xeab38330, 0x43f60908, 0xe589a0fd, 0xcff4fe31,
- 0xbdf76665, 0x61cee1fa, 0xb6a2c780, 0xa82dc9c1, 0x9fa20737, 0xc8f5c559,
- 0x0c9a80b9, 0x385cf5fa, 0x73c9fd0f, 0xbc574587, 0x38e7c6fc, 0xf8805f7d,
- 0xb6db2d19, 0xf2915a92, 0x47691b5d, 0xd5b022bb, 0xd9c5b646, 0x9990aadf,
- 0xf8a1fc9e, 0x3e03fa00, 0x94b7b39e, 0x73b1c796, 0xbbeb9dff, 0x81fffba9,
- 0xe155e6eb, 0xa7b016cd, 0x316adaae, 0xeb9605c4, 0x0a405d7c, 0xeea7af80,
- 0x0386bbb7, 0x5e8b0f1e, 0x0aad03c8, 0xe2f8a17f, 0xf9e68df8, 0x8f60ff43,
- 0x707b2b3d, 0xd0e4d7dc, 0x6bc3c05c, 0xf6046d67, 0xb52b76d3, 0xf9c1e24b,
- 0xb9c1852b, 0xcba318fb, 0xa297858f, 0x18a46736, 0x095b3de2, 0x3a676df2,
- 0x73f3e413, 0x2ab82475, 0xb22de817, 0x68353d7a, 0x9414fbe8, 0xef838e5f,
- 0x635ed12e, 0xc68af3e4, 0xf4082f1d, 0xc16165bd, 0xcbeda163, 0xf80516a4,
- 0x4531aaa5, 0x54367d04, 0x3d5bf3d5, 0xe1896e43, 0x096567bf, 0xcc6079e7,
- 0x5e03b76b, 0x08519fce, 0x076801e4, 0xf84f31db, 0xf218787c, 0xbd79a25b,
- 0x275327ec, 0x410fd0ca, 0x71d3363e, 0xa1927d70, 0xd7c4b63e, 0x6a9ae00b,
- 0x8de9596d, 0x1c01f783, 0x7c963fef, 0x5b765576, 0xe5d5df7e, 0xc79627d7,
- 0x9d57ddf0, 0x9e2337e5, 0xa55f2efc, 0x97bcc066, 0x0065e537, 0x21bf973e,
- 0x57c78cf7, 0xdf99fa2f, 0x03e79db8, 0xf95035b7, 0x7e4626bd, 0xc6fca81b,
- 0xfcb61389, 0x22fbf2c8, 0x7b3c6fc8, 0x9757cf8c, 0xc7f0fcdf, 0x0df9bf28,
- 0xca1e4316, 0xefaf9969, 0xe857e509, 0xd41a4b79, 0x8e23af65, 0x403c06be,
- 0xdf3b739c, 0x40718007, 0xbbe5558e, 0xfc7ff1c9, 0xf978e58b, 0x3379822e,
- 0xe4cde99d, 0x2a6ef978, 0x9dd002c7, 0x26f2f1c9, 0x9db9c72a, 0x275077e5,
- 0x2fdf65f9, 0xabefb08b, 0x7b7f731a, 0x40af1d07, 0xfa36bd93, 0x3c87417e,
- 0x6795888f, 0xcf204955, 0xcf27bb87, 0x533cb8bb, 0x8de7ed39, 0xd86f5743,
- 0xdaf61f98, 0x2ff513e8, 0x41fe5f03, 0x6de9ff44, 0xff73b30b, 0x70c4fa38,
- 0x00db8be0, 0x632fca1e, 0xfd5a1d39, 0x74bfec01, 0x9074c6cc, 0xb5839293,
- 0xec3c81bf, 0x0132adca, 0xe1acb87d, 0xcd53f463, 0xbedd1771, 0x745fc732,
- 0xc38e623d, 0xbd33a92c, 0x9dbe30a7, 0xbc20b626, 0x77a24fe4, 0xd3be1c5b,
- 0xe704ebdf, 0x9cf7dae1, 0xece03bc3, 0xcfa42e2a, 0xf4b82ba3, 0x7c2b9579,
- 0x864a1bbd, 0xe291bc41, 0xf025e511, 0xaa7188a6, 0x8601a2f2, 0x72b70cf3,
- 0x16d58738, 0x62d84095, 0x80ebe41a, 0x9ee1b55f, 0x368fb043, 0x005aa8e2,
- 0x31d8f566, 0x57f81f56, 0x51dbd9cf, 0x3cba759e, 0x3964f9c4, 0x5eb5e7ef,
- 0x6fc0c5d5, 0x07828d55, 0xc8aa9dd6, 0xc6dcf03f, 0x955f8d81, 0x6a2d1f02,
- 0xe4563c12, 0xf0142fc3, 0xfae94afb, 0x2c34fc0b, 0xbfda05fc, 0x448a9a8b,
- 0x6ed17ef8, 0xbbe41301, 0xe9774fc2, 0xf7c396b6, 0x04efc022, 0xbad9db38,
- 0xdbd3e1c6, 0x0180a4ab, 0x2f2792fe, 0x7066c9ae, 0x03b556ab, 0x785111de,
- 0xaf388b67, 0xe3abc26e, 0x1f782bbd, 0xe3deb852, 0xb8d3fc74, 0x222f18f3,
- 0xf96e94e1, 0x6e35df37, 0xd19a4555, 0x57e3d35f, 0x2adf455b, 0x6588e219,
- 0xf38c6482, 0xfbfc63b6, 0x7fffe847, 0xf07fadbe, 0xdd74222f, 0xd3fd7dfa,
- 0xcfb3ef88, 0xe8153c7f, 0x9135e4b2, 0x5a5d28d8, 0x82245deb, 0x054124fb,
- 0x41b8b0e8, 0x240e30d4, 0xbba70a45, 0xc351f162, 0x85ddb1f0, 0x4ef1707a,
- 0xfd32706b, 0x9f2bf17e, 0xd33d83e6, 0xa1fb40fa, 0x3c03886c, 0x931ca02f,
- 0xec3e4b40, 0xd8962d13, 0xbf198dbe, 0x87c58511, 0xcc76eccf, 0xea107902,
- 0xc5a9b9d8, 0x35b299a1, 0x557e1ec6, 0x641c5991, 0x15af3b37, 0xbcc04e78,
- 0xf62f8031, 0x8f9e8edc, 0xe639e673, 0x946e2c97, 0x6afe7083, 0x568edd71,
- 0x3e2c9b88, 0xad75c56a, 0x8c0beeaa, 0x7f6c96fb, 0x6aef9d91, 0x72fe0d14,
- 0x4eb53f27, 0xbfc1588c, 0x38c4a86a, 0x8c7fad3c, 0x0bf710f5, 0xb51fa3bf,
- 0x2bd37b64, 0x25c28a01, 0xc6eb3f2f, 0xdbcd5873, 0xd6afe8dc, 0xa8dc7b7d,
- 0x7a1a5f93, 0x53a5fb88, 0x97df804e, 0xcd3d2fc8, 0x62b4e4f9, 0x7aebeff2,
- 0xe14abfa0, 0x638f2c2c, 0xfff947b7, 0x077f2fc5, 0x3b33d571, 0xc01dff3f,
- 0xf39bf4bd, 0xe28fbbbf, 0x7bb5ec93, 0x3d560f40, 0x438c17ff, 0x5649dfe9,
- 0x7b9fafae, 0xad78e316, 0xa17ab37f, 0x13a6d6b7, 0x6ac71039, 0x748ff1dd,
- 0x365653b0, 0x6bbb424d, 0x0c92aee5, 0xd04ec712, 0x60dfe04b, 0x6688e237,
- 0x38681dba, 0x9e700390, 0x748774a5, 0x21bc68be, 0x38e2c954, 0xd4338f2a,
- 0x76db8fc7, 0x4c342b8a, 0x70fc69bf, 0x4aaf6528, 0x785f11ba, 0x9af3d297,
- 0x9eb1d06e, 0x534291c7, 0x70be35be, 0xe941fe16, 0xc6356795, 0x986cbe17,
- 0x424f9fff, 0x848f435b, 0x374885f1, 0x85c7a7f0, 0xdf2d14db, 0xf3b9720a,
- 0x00eb8c05, 0x09d326fd, 0x65f8beb7, 0x4fd5c40e, 0x6177edca, 0x15935bbe,
- 0x3717d7f7, 0xa9e515fd, 0x68dbd775, 0x9f1e127f, 0x3fd1256d, 0xb9e34716,
- 0x5d5b55aa, 0xe9c12e2c, 0xd50b7100, 0x7c79cf8d, 0x1eb5f182, 0xaf1448b7,
- 0xc7ed6058, 0x5c594ef3, 0x07eb72a5, 0x83c5310a, 0xeb1d5184, 0xe97a227e,
- 0x1e00f078, 0xe3c6c646, 0xa287c7e2, 0xdd1338f1, 0x87109e80, 0x68dbc68b,
- 0x5dc437bd, 0xe35fc282, 0x375b77c5, 0xab5e38b3, 0xe95bcc6c, 0xcf8b13a0,
- 0x5bd136cd, 0xeb576f9f, 0xf8f35756, 0x069a78ae, 0xcecf768b, 0x29733af8,
- 0x6d5f7ebe, 0x3ed87e15, 0xbcc13ceb, 0x7c0353ef, 0xb1f0d959, 0xfa8d7902,
- 0xf7cfa6fa, 0xcfcfb70c, 0x5e622f3c, 0x01d09aee, 0xfd66efd4, 0x61ce0cb1,
- 0x37f781c4, 0x8d65de1c, 0xb338fd6c, 0xd27415d3, 0xdfecce7e, 0xacbd7c8d,
- 0x402563fe, 0xf7543bfb, 0x49fcc2b2, 0x7eb04726, 0x3fe06304, 0x7cbed2f3,
- 0xfe647f16, 0xad9c7980, 0x85563f5c, 0x55538fe3, 0x9c6185ff, 0xc2908125,
- 0x7dbfacf2, 0x3692d3bc, 0xdd3bfa13, 0xb3c8132c, 0xcb121d3c, 0xae6bede2,
- 0x5f7ccab5, 0xb9c596b3, 0xe78a3ae9, 0x9cec5c5e, 0x60aa988b, 0x6ba5641c,
- 0x5f3851d4, 0xa8a5d2b9, 0xacd51fe0, 0x35bcfb62, 0x0266f73f, 0x6e526bbd,
- 0xad6d78c5, 0x349ebf09, 0x7f9c114f, 0x1f2c4cf1, 0xd66aec0e, 0xc59a293b,
- 0x574aff00, 0xe14a8659, 0x81fb4d5c, 0xf244a8f3, 0xd11c39e2, 0xf3065a5d,
- 0x8f163d11, 0x4c7c4e3d, 0x5f139676, 0x8f645e0c, 0xb90cdcf1, 0x7e854c34,
- 0xa5d9fdf4, 0xd843e6b6, 0xe004d1e8, 0xc7ef892b, 0xc1e2dd17, 0x0bd5b779,
- 0xaa71605e, 0x3a4f559e, 0x758033cb, 0x72676da4, 0x3f06b93e, 0x5f5d1a24,
- 0x50b9fc1c, 0xe81f6fbf, 0xa26ed5a5, 0xa33950a5, 0x3cc55558, 0xd4343f38,
- 0x9f01e426, 0xd7c7f17e, 0xb0f6bf68, 0xa0352048, 0x19e7a9cd, 0x67202969,
- 0xe608f20e, 0x5f2b0093, 0xa701d1ee, 0xc084cf39, 0x97e7312b, 0x8c4e8927,
- 0x24db9c7f, 0x922b9fa2, 0x8e3b7eab, 0x0824edf9, 0x65f5f3f0, 0x1cf38709,
- 0xf0231175, 0xe30bbd7e, 0x98df0bf3, 0x7403f28b, 0x8f57c588, 0xb91fa332,
- 0x87ceeec1, 0x768d9dfd, 0x492816f7, 0xbc866b40, 0xdfbc79e6, 0x73c6e59e,
- 0x030c5448, 0xe7ce7f60, 0x82f9faf2, 0xaf98c3d2, 0x7a805be0, 0xf196633e,
- 0xbed9929c, 0x1fb50897, 0x0a0d7d61, 0xb38908de, 0x19b8dfaf, 0xdecaeee1,
- 0xb0e8f1d7, 0x3909bd51, 0x04e24e42, 0x97d6263c, 0x65b7e05d, 0x0dc76fe0,
- 0xb5f8eeff, 0x6bf11a66, 0x75f88d57, 0xcfe3320c, 0xd7975f88, 0xe6ca2f88,
- 0x6fc36fc1, 0xb9e328f2, 0x7e157faf, 0x1db8d987, 0xff4af1c9, 0x4ce96dca,
- 0x59dc0365, 0xc2e50452, 0xced9472c, 0xeeff0088, 0x855c1693, 0xe85d795f,
- 0xf9f264af, 0x77d8f308, 0x1123900e, 0x1ca2f5e0, 0xd00bc9c1, 0xa1f20ef3,
- 0x2169e807, 0x57cb929f, 0x8ae7a627, 0x9e3f0769, 0x04dabf43, 0xf20d7bfc,
- 0x955f3b03, 0xb935824a, 0x0f5ea720, 0xbf21dfac, 0x864f3bcd, 0x3bc4f673,
- 0xaf9c006f, 0x68f960f7, 0x6dbf7b01, 0x1a73c130, 0x7485c8a1, 0xf3554fd0,
- 0xbfe83949, 0xa9f69547, 0x6cbef7e0, 0x1bbdf167, 0xd3ea0aec, 0xae16eda7,
- 0x71be2757, 0xb6c7952d, 0xf9c2acb0, 0x36f0b6c0, 0x37a800db, 0xbd6e788a,
- 0x4af6a52a, 0x2c35bf18, 0xd9e6b833, 0xbfc00382, 0x3d71926f, 0x0e379d68,
- 0xed44c1cf, 0x4fdb30b7, 0xea7f0b6c, 0xcfa31b9e, 0xb89f1b5b, 0x1b0fe212,
- 0x31f7f12d, 0xdf2cd857, 0xae8d7fcb, 0xf29d0dbf, 0x58d8562e, 0xfda3c75e,
- 0x4d963ce8, 0x61d7c73b, 0x39630f26, 0xb82e0f9d, 0x2bbfe701, 0x3a7cfd4c,
- 0x8ef1528f, 0x79d0871b, 0xc48bfe8e, 0x26d12bf4, 0x47674ecf, 0x1afde080,
- 0x5fa82fd0, 0x0e2cff6b, 0x44a0b887, 0xf0c45ce0, 0x6fe805ea, 0x7ca6e6bd,
- 0x50a2f94e, 0xbe030d0b, 0xc14e189d, 0x3eaa0a7b, 0x8fd76824, 0xfc0c9668,
- 0xd5d7c859, 0x9f1616c2, 0xd8d4791f, 0x3245ba3e, 0x8c4141d9, 0x693d8f1f,
- 0xf3ab5e7c, 0x03a49bb9, 0x24bfaf9f, 0xd517900a, 0x0fbc4ed6, 0xe6dbb850,
- 0xda3842f5, 0x2b29c02e, 0xcb125e5a, 0x9bf7ade2, 0x6b0f2c6d, 0x9d7042a3,
- 0x89c0b8d9, 0x17fb08fb, 0xeb3cc62c, 0xebe67eaf, 0x5edcef1b, 0x664a7e8c,
- 0x325af5fb, 0xbdfc0519, 0xaf78605a, 0xb7dd8acd, 0x9f9d4bd2, 0xf9d6fe75,
- 0x92416b3a, 0xcbde5e2f, 0x7bb33b60, 0x120c178a, 0xf6d7f014, 0xa9fc780a,
- 0x219f01f5, 0x065cdb7f, 0x00d903c8, 0x79e3554f, 0xe16dbbb4, 0xfb5479f8,
- 0x0fe66e6d, 0x0558103e, 0xa53f1e79, 0x327a09c2, 0xd1ebbf71, 0xa083aadf,
- 0xab677c2a, 0xa6e78d9d, 0x16c8dbe6, 0xb54ad388, 0x80bb3759, 0x5fae4bff,
- 0xb27de143, 0xebeb82dc, 0xf08bd946, 0xc1092a07, 0xa73f03f8, 0xd92a7bd5,
- 0xec7e7b1c, 0xa8e8ad88, 0xa8f7ce8d, 0xeef383cd, 0x000af3e1, 0xffebf7bf,
- 0xa6bb06e3, 0xe915a2ed, 0x43fb8bd8, 0x6de777fa, 0xd80f4f0c, 0x7be077b5,
- 0x72869152, 0xbdb9f5e2, 0x39c186f3, 0x18f78a55, 0x5fa0ea39, 0xea91e700,
- 0xc28e3aa3, 0x20b4ea93, 0x534d125f, 0x031e7a3d, 0xc8c5efe1, 0x04088905,
- 0xbd741cf2, 0x8885842a, 0x70c1ca8b, 0x7e02339b, 0x9d056a47, 0x4ec10537,
- 0x66bfac6c, 0x1cf44ce9, 0x5251e61c, 0xe4842cbe, 0x12798279, 0xfd05a890,
- 0xd756faeb, 0x0853abd3, 0xc7eacbca, 0xed0d60a4, 0x62d49367, 0xae4af887,
- 0x56c316a6, 0xe2a4aa74, 0x153ebcf9, 0x1c73f304, 0x44a54f79, 0xf42a16ed,
- 0xef11bf43, 0x1fe7178e, 0xe5f1d76a, 0x2be027fb, 0x7efb70ff, 0x76bc6f30,
- 0x75f79e36, 0x51e9da1b, 0xb1edc1fd, 0x8efebe52, 0x2bed8cfe, 0x24b5c893,
- 0xd66f8e36, 0x327dba1f, 0x03cb7c7a, 0x6feef80e, 0xadda4e0c, 0xe08ddf06,
- 0x13ea8df3, 0x0c8e6ebe, 0xbf427d53, 0x3b0f082f, 0x82eef100, 0x771c990f,
- 0x038727d2, 0xfbefe022, 0x5f3311ea, 0xb9508d0c, 0x5583ede4, 0x89ecbf38,
- 0xafbda1d6, 0xd277a8dd, 0x40cf0da6, 0x9bf3973b, 0x7cbacf19, 0xe0bee59b,
- 0x2b01ef5e, 0x60910b83, 0x1d08871e, 0xa079a870, 0x60888e97, 0x5115b7ef,
- 0x0eb8503c, 0xb94bf972, 0xe61ebc10, 0x9d7c3ebf, 0x7be4e41d, 0xfa1127af,
- 0xf27c4c75, 0xde37d171, 0xdcf8f2ce, 0xfb658780, 0x24f5f02e, 0xca8ef482,
- 0xd8939501, 0xffce8978, 0xe5d77e66, 0x3a0e06a3, 0x0bf9e1e7, 0x28aceb02,
- 0xbdf0f084, 0x00f26c95, 0xbb7b755e, 0x24b7db86, 0xdff68590, 0xebe10f4a,
- 0xf8104e51, 0xedd646a4, 0x362daf75, 0x55d2b53e, 0xfb6df19c, 0xa9175535,
- 0x8793167f, 0xa3b5255d, 0x517556ff, 0x1bdfe7c1, 0x450a617f, 0xf37f01ba,
- 0xe33b3ded, 0x57c83c6f, 0xe62fffcf, 0xbf3ccab7, 0xfcc76ab5, 0x6bdf12c6,
- 0x147f542d, 0xe35758ae, 0x7793f150, 0xeb3b0b33, 0x657cfd05, 0x96603d22,
- 0x6b4b91f7, 0xb498600f, 0x72af790b, 0x3212fc70, 0x98d9f41d, 0x725bb508,
- 0x05ffcb3b, 0x072abf3e, 0xaddb7bc3, 0x9e4103ed, 0xdfbe8856, 0x16a811d9,
- 0x8aec058b, 0x1eed04dd, 0x6e63beef, 0x1ee6f794, 0xb3a7f586, 0xf660105d,
- 0xf4475f26, 0x48d0a7b8, 0x738e80e5, 0x0e7beec4, 0x30f1affa, 0x340e14bf,
- 0x623a7e81, 0x5e03d5f3, 0x24c6141d, 0x28324f38, 0x28e2cb92, 0x25dc8311,
- 0x49873392, 0xde74428e, 0xe805aeb0, 0x484036ba, 0x7b02cf0c, 0xd502230a,
- 0xf4b7602e, 0xb06c242e, 0x06f30465, 0x7bb3e77b, 0xb0177a00, 0xb4dec77b,
- 0x5bc938b3, 0xcbd11d7c, 0x03f2b623, 0x912cbf00, 0xfbe0b580, 0x42a00dc3,
- 0x5d88f17c, 0xb27807db, 0x8f386995, 0x0af10f6c, 0x52d98e94, 0xad7d8048,
- 0xc0aaa5d4, 0xad848ae2, 0xfed25043, 0x45ab27b2, 0xfeecf740, 0x6509cf04,
- 0x4713fd83, 0xe5d98e6e, 0x6b07161f, 0x1f8764ec, 0x487172e3, 0x31edf3a1,
- 0x473fe599, 0x7c1439e3, 0xebab6fc0, 0xeb6c9c56, 0x225f2c97, 0x6cf0c290,
- 0x6080cbf6, 0xd7892f30, 0x6488541f, 0x29bf454f, 0xb0197c00, 0x726fd0d8,
- 0xef086f10, 0xc7ea4949, 0xbc1145ee, 0x2bfea0eb, 0xf706dda9, 0xa0f2e825,
- 0xe3a3f9f3, 0xf44af66e, 0x73f8f755, 0x52d3e0f9, 0xe027ff7e, 0xb9dc75b9,
- 0x2671ab81, 0xef8c39ed, 0x6790d134, 0x51afd3a9, 0x0ecfd036, 0xfd5892f1,
- 0x810652ed, 0x242ade3d, 0x6a5fc179, 0x7830245d, 0x43cf1b05, 0xccf30c95,
- 0xa33f3074, 0xfec5eb8d, 0x0f38b949, 0xf3a09d7d, 0x5d71875b, 0xe7a23cd3,
- 0x8ce74c8e, 0x3290e7cc, 0x9df1a2f3, 0x2b07cc2c, 0x184ee057, 0x40ec2e72,
- 0xddcaacfb, 0x9ce2439e, 0xb168c993, 0xa6073dc7, 0xfd6f1497, 0x5e427a92,
- 0xe80a7561, 0x993b8cd9, 0xa3e3307e, 0x3d0c084d, 0x7f63fb04, 0xa3eee390,
- 0xe66665eb, 0xe8f3298d, 0xd75999fb, 0xdf3fa963, 0xc6e294e0, 0x0925c70b,
- 0x0c8fcc3f, 0x18df3cb2, 0xf3071dfe, 0xe77beb39, 0xbfc50d3d, 0x1be9e31d,
- 0x37de1892, 0x6fbc3124, 0xaa7c7450, 0x1d7f20c9, 0x5f21af75, 0x96dfbd62,
- 0x509e4122, 0x73e50b20, 0xbbd187be, 0xed0d7de3, 0xbb449e96, 0x125036fe,
- 0x0db265eb, 0x7dc59ef9, 0xdfe0bcf4, 0x994b9ff8, 0xdba7ed48, 0x8d505f38,
- 0xc29be8c0, 0x7eb0bee0, 0x4e9b8e12, 0x1481da2d, 0x2dca0bcf, 0x9d07885e,
- 0x1bbef39d, 0xc9cdc88e, 0x78242e6e, 0x0d7ab5f4, 0x157f73f8, 0xd125b77d,
- 0x5036d27e, 0xf183d545, 0xa525c805, 0x8fb8f5d3, 0x3712db39, 0xc497cfef,
- 0x925776fc, 0xccc8e107, 0xea748a9c, 0x014e4fa8, 0xa7ccc37f, 0xe6b35e54,
- 0xb738ef0d, 0x1166f946, 0x6f2cd9e0, 0x1469326d, 0x208add70, 0x7674d2be,
- 0x975b7ae6, 0x43903497, 0xa72a8fd8, 0x73a7547a, 0x3a6afe3f, 0x4ff13bc6,
- 0x1ffeff08, 0xc7b847e0, 0xd45ea317, 0x620c88e5, 0x7a0ede7a, 0xd9ce2637,
- 0x3ed7f4d6, 0xd1f89fb0, 0x60bbcfcf, 0x52efe93f, 0xecf40bbb, 0xecfffbc9,
- 0x8f863c82, 0x8ef167ee, 0xd7fe4cbb, 0xff4c4923, 0x5e54947f, 0xdbbaf303,
- 0x2fa175ff, 0xbdc95f86, 0x51645f6c, 0x6f9d3450, 0xae379e34, 0x17cf990c,
- 0x95df1007, 0xfd78fc52, 0xe71624fe, 0x59bf5459, 0x7c6156c9, 0xae81afdf,
- 0x797fb927, 0x03dd81b2, 0xa733c3a2, 0x3e02a87e, 0x56c3dfd7, 0x2cdeafbe,
- 0x9b43f5b3, 0x3e62fb0c, 0x9c33378e, 0xa4fdf887, 0xa22d7ff3, 0x8e9b33df,
- 0xc3d52f75, 0xf3cb30be, 0xfe63cf35, 0x9c296a47, 0x90ff9fe7, 0xbc34fe80,
- 0xcf5d3f7f, 0xc5aef77c, 0x3cf333fd, 0xa08fdf3b, 0x90b5dfa1, 0xce7cdbd3,
- 0xed98616a, 0x3e23cf6f, 0xf94ecf94, 0x0f966118, 0x9e238e6d, 0x00e79c3b,
- 0xf126343c, 0x3242ab7d, 0x762ef212, 0xfc97ee1e, 0x675ef96d, 0xd3f2b9f8,
- 0xa4f44f3c, 0x9359609f, 0xdbf3b2a4, 0x814bb7e1, 0xee3596bf, 0xbe657bc0,
- 0x0caa3eab, 0x84ff729f, 0x6a25e874, 0xe811fe5f, 0xc1827c48, 0xf9b65cee,
- 0x65fcc2bc, 0xf83b9f86, 0x1f003bf3, 0xeececfb8, 0xa963b90f, 0xdef6217c,
- 0x8c92f799, 0xa267ebfb, 0x3cd9e4e7, 0x93bef92a, 0x5f333f3e, 0x9b3e70d7,
- 0x9ada75b7, 0x35ca745e, 0xf872274d, 0xfbcc0779, 0x2166f9d6, 0x8acd2f29,
- 0xbd3a1fc3, 0xfe107ca2, 0xd3abc225, 0x6ced5e69, 0x2640af3e, 0x84cbf7df,
- 0x2f9992b8, 0xd76f3aba, 0x80e4b72a, 0xdee99abc, 0xfb3ce09a, 0x3ed893df,
- 0x2b553ced, 0x9f38bd05, 0xc4f1af94, 0xa5272bd8, 0x81f743da, 0x7c656d1c,
- 0xe06bd51c, 0x7ebe82bc, 0x7cf5c64b, 0x80cd4bb9, 0x1e90917b, 0x87615e70,
- 0xe9ef0035, 0x6bf71ce3, 0xf0197f5a, 0x69e5865d, 0x7fd6b97f, 0x82fb4740,
- 0x10dde78d, 0x441b6dc7, 0xead3be30, 0x71ebc232, 0xc78f0888, 0xa5bbd6c1,
- 0x1f37f352, 0xdada0e80, 0xc711f98c, 0xd0f8f12f, 0xbc596b25, 0x10ed5e79,
- 0xdd05f70c, 0xf74ae5c5, 0xf4e6ee3f, 0xf6cc2bbb, 0x9a6ce7bd, 0xdf30f486,
- 0xfb847267, 0x041bb32d, 0xfa6623d4, 0x775ef7cc, 0xdcedf40a, 0xdf7e1160,
- 0x11e45e89, 0x6e99bba4, 0x761e1deb, 0xad548dbf, 0xc73f7dc0, 0x4fb80937,
- 0xde8124b8, 0x8f0777fb, 0x3e737767, 0x822479e6, 0x55d6e17f, 0x98117a6b,
- 0xf80550ff, 0x3ebf0cdc, 0x6344f9ff, 0x37cf877a, 0xcb48bcd1, 0x829f2cb5,
- 0xc28be3af, 0x65a97eec, 0xaf2c888f, 0x748bc793, 0xcd7875f8, 0x971528f3,
- 0xdb6f3e62, 0x09f31106, 0xd7040aef, 0x77cbbdc0, 0x3d7016ad, 0x5d27444d,
- 0x32fbe84f, 0x63671acb, 0xf68f957e, 0xdb697603, 0xd9170487, 0xde0275b6,
- 0x9e90937f, 0x94579661, 0x30849e88, 0x74a3cdba, 0x7e6e387b, 0x3fd6915c,
- 0x78273f76, 0x763fd6bd, 0x3084897f, 0xdd4964af, 0x4af3c334, 0x774f5187,
- 0x3aa47f25, 0x2e9cde7e, 0xe9fcba6f, 0x9c1eb8f2, 0xa51fb073, 0x5ceca1e0,
- 0xe863cfc0, 0xfbfd50af, 0xff8b0773, 0x7d1b7a3c, 0xf3c6d965, 0xf984fd86,
- 0xe6bd18a3, 0x79f1938b, 0xe28375a2, 0xd787a0c1, 0xf87a8c3a, 0x9f47ce87,
- 0xfa272e87, 0x6272ccfc, 0x0f4cdefe, 0xa6670e3d, 0x001e998b, 0x470df827,
- 0x07c11c9a, 0x04479c28, 0xc9a07706, 0x66b7708e, 0xfe706896, 0xedd65966,
- 0x0f811e58, 0x57bd8347, 0xed038cfe, 0x7957ee56, 0x4503e7e3, 0xf76e25ed,
- 0x41961988, 0x93111e30, 0x2ec790bc, 0x77aa5b66, 0x7d8a79d2, 0xd2183969,
- 0x9c22bd99, 0x992daee7, 0x143dc220, 0x77bcfc35, 0x379d858d, 0xc3dbfbd3,
- 0xed97a0f1, 0x8046f28e, 0x9a9fece7, 0xfe2c1d0b, 0xce0afe8c, 0x143dee13,
- 0x760dbfa8, 0xf304ebf0, 0xc8d20b69, 0x83b7a001, 0xee40a368, 0x72a4743f,
- 0xffed9c3b, 0x286cbfd1, 0xcbcb56bd, 0x3f9097aa, 0x49b3e2fc, 0x37b25f70,
- 0x9722b2d9, 0x38e2ffd6, 0xb9ee093d, 0xce5b66f3, 0xfda87ae7, 0xd59cf8ed,
- 0xef9cb6af, 0x737feb47, 0xd875619c, 0xf87b82a8, 0x0527671c, 0x1e38c306,
- 0xb5eae7a6, 0x243e41ab, 0xa597f30b, 0xc3c60afd, 0xd5fdfdf5, 0x17e0e694,
- 0x79f9c87f, 0x17e2aacd, 0x2c67101c, 0x6fd854d6, 0x71be0ade, 0xea5fefcf,
- 0x161d1578, 0x4a0367bc, 0x1ca7ffc0, 0x485d3a9f, 0xe4357683, 0x7690923d,
- 0xb483ec35, 0x1dc77c3b, 0x91d87db4, 0x572009e6, 0x5fbcef0d, 0xf68df788,
- 0xa30cfd65, 0xf3a6e20c, 0x9f6afb39, 0x8afbb1cd, 0xcfa28eed, 0x0c943e81,
- 0xaa084768, 0xed41dc87, 0xa88d1a86, 0x31f81e4a, 0x81bdbb46, 0x49d7d9f3,
- 0xcf91e7e5, 0x9f50477a, 0x7df0e53c, 0xfd9be305, 0xda9cd211, 0xf253fe2d,
- 0x7af8c5ef, 0xd1e3766a, 0xff9f2039, 0x0afdcec5, 0x7af9869a, 0x9ef7a3db,
- 0x1df7f410, 0x710bc924, 0x9925e236, 0xb71e7481, 0x4abe30b0, 0x4bf18c2b,
- 0xf7e87cf8, 0x951ee113, 0x1fb60e91, 0x8227e74c, 0xa894369f, 0xf8830e58,
- 0x9ab01e43, 0x487beb0f, 0xb47de8e8, 0xccedc7ff, 0x11d5b7ef, 0x84675c43,
- 0x7707d993, 0x275c58b9, 0x0cdd0e49, 0x0be93dfa, 0xdefd01e2, 0xe12294f6,
- 0xb9e4a67e, 0x0e39f711, 0xf82e3059, 0x40f41cac, 0x4afdbd7c, 0x3a42dd49,
- 0x74e36bfa, 0x5c7dfbd7, 0x7884af51, 0xb3175cca, 0x222d9e27, 0x7edaf798,
- 0xfec2094a, 0xadb66a57, 0xcf4fd63a, 0x4faddfe7, 0xa4e41e2e, 0x8929a865,
- 0xf723f8c0, 0xd2928352, 0x02fa85e3, 0x76c5f03b, 0x43c511c0, 0x0f73d5aa,
- 0x9e7a97f4, 0xcf8b9bc2, 0xa4afc435, 0xf8a64d0e, 0x5383731d, 0x9e297b85,
- 0xc06e87b5, 0x2d17bf3c, 0x76d3ff78, 0xea0d3bc5, 0x1ea9cfdb, 0x9b3d0788,
- 0xf9c24a1b, 0xf9c168bc, 0xbf6a4f6c, 0xfb85396a, 0x8e2c41e1, 0x64883920,
- 0x2a79054b, 0xcfa1ef56, 0x7d993bc7, 0xe4c2dabb, 0x62a9daa9, 0x8e8171fd,
- 0x15ef005f, 0xf9e91ca1, 0xeced6d17, 0x5bcf471c, 0xe7e0459a, 0x3fba69a4,
- 0x0fc1111f, 0x704e571f, 0x94e71d5d, 0xad3a2a83, 0x2176739a, 0xd6ceffdc,
- 0x2e1f098d, 0x29f2cc9d, 0xefc2efbd, 0xf2701c21, 0xbef836fb, 0x4f9cb5d0,
- 0xd11693c6, 0x5fc7db46, 0x2e48de24, 0x8c6af7dc, 0x5a633edf, 0xfef127e7,
- 0x44cf76b5, 0x8c445c78, 0x0da4f0eb, 0xae20a7a5, 0x09344c5c, 0x66c4a9f8,
- 0xdcf5876a, 0x9ac4f70d, 0xf273c9ee, 0xe4872b75, 0xe8fde6c4, 0xe249fb71,
- 0x47688de0, 0xc05e2994, 0xf6a70ecb, 0x0d4fd857, 0xdbf2f750, 0xf8cf3de2,
- 0xa0d67e59, 0x57020e8b, 0x74fe50ff, 0xdaae7cc2, 0xd3b01b50, 0x9fd55f79,
- 0x087c0ff5, 0xa78ae5fa, 0xbe807ad2, 0xe97a7377, 0xc077cea5, 0xc6649e5f,
- 0x3a6b9e5f, 0x273ef3e4, 0xf2e89b8b, 0xfd077c06, 0xb78391ec, 0xa41fdbc7,
- 0xf01f7afc, 0x41270eeb, 0x5917fa7b, 0x672059b6, 0x9dfb38fa, 0xe5cdff8c,
- 0xf7cb559a, 0x0412efc1, 0xc6eb64be, 0x31175ec4, 0x6eba2e4f, 0xab783327,
- 0x53e9dad4, 0x29c76f21, 0x3a4e5e63, 0xcb16373f, 0xfc31592f, 0xab5df3a2,
- 0x3adff993, 0xfeec94ff, 0x284b9e33, 0x06fa92f9, 0x376a24b9, 0x2133fcea,
- 0xb37dc110, 0x89d98409, 0x99d9fe66, 0x2e8a7f80, 0xade812a8, 0x9873fc4e,
- 0xbe224ff1, 0xb048fda1, 0xe7f99a0e, 0xe3b72719, 0x25cff212, 0x6569e037,
- 0xeeb7c953, 0x8dfa34ef, 0x72e67cf9, 0xbe7e23b4, 0xef1c67e7, 0x1bda95bb,
- 0x4c6f41f3, 0x2f4178b1, 0xbec8ee50, 0x3bbbc299, 0xb5d7bf49, 0x3bea0f3a,
- 0x7687a624, 0x87a8ad84, 0x3e7d3876, 0xb2658b8c, 0xf24474f3, 0xb6fe40b5,
- 0x8d4d97b7, 0x7efb27bd, 0x39218fce, 0xd804fa32, 0x3e306f45, 0x00a53518,
- 0x5921bc6e, 0x185e98f3, 0x0cd9527e, 0xd0b28fbf, 0x9386f455, 0x74067fbe,
- 0xc753ac07, 0x60b7bc14, 0xf50531d9, 0xdf7babe3, 0x93b8852e, 0x723a179e,
- 0xc5a5dbcf, 0xc67de183, 0xfd736f6f, 0x6531d7aa, 0xe9a5f41e, 0x84d1d85e,
- 0xbdf331e9, 0x47c0e5ae, 0xe6ed1df9, 0x49434efb, 0x933d2e2c, 0x0e9bb2a8,
- 0xf958fd31, 0x885d7083, 0x99d3def9, 0x4fd01b91, 0x5f5de5b8, 0x394f7bfc,
- 0xdfef987f, 0x77c93afc, 0xf95fe61a, 0x985ef342, 0xbad95102, 0xafaa521d,
- 0x579ef766, 0xe93f01e7, 0x147f8872, 0x068fa17f, 0xf5ddee19, 0x11e8f5f2,
- 0x7beec4af, 0xbf705168, 0x7d8497e7, 0x98ebe217, 0x40f4c5cd, 0x6e97cac1,
- 0x55873807, 0x2e800768, 0xf9993bff, 0x1122bfd7, 0xcdd01e5b, 0x3a9c612b,
- 0x2725ab24, 0x88f78e84, 0xce083e54, 0x99e9ed75, 0x5fc60c34, 0x5c39f2e8,
- 0xed486f60, 0x91bbe187, 0x81860a63, 0x5d0e771e, 0x35d603dd, 0x570a6e1d,
- 0x076736d9, 0x175c3a1c, 0x742cbf39, 0x7ab876cd, 0x2f40efb2, 0xdc7c7e35,
- 0xfcebdf06, 0x82fa6a10, 0x5f0c41f1, 0xf0741f00, 0xd4377085, 0xf1a43c75,
- 0xd8ffaf52, 0x97fba17c, 0xf805f25d, 0xc5efee8f, 0x715c4317, 0x73da82f8,
- 0xd9b9e1c3, 0x2c290b9e, 0xfcfccccf, 0xbe114729, 0xe60855ef, 0x76bd9089,
- 0xbe3bbbf6, 0xbf2f8c14, 0xb66361ec, 0x073c747d, 0x5ceb957c, 0xf90e4ca9,
- 0x2343df3d, 0x439fda02, 0x03b8a2a9, 0xa8debced, 0x7f1cbd27, 0xc020b8e4,
- 0x4b985dfd, 0x68760d9c, 0x6bd807a4, 0x2393ad43, 0x1d3b0f20, 0x7ec1b213,
- 0xcb8c702c, 0x32bff983, 0xb05be568, 0xabd2bda4, 0x6aade5e2, 0xeba57d87,
- 0x5bbc03c3, 0x5d5bfc7d, 0xd5ae3f8c, 0xd010f9d8, 0xe870b1eb, 0x099003eb,
- 0x332210e0, 0xa81d972d, 0x142dc3c7, 0x1c02d76f, 0x04fb0f14, 0x43f600d2,
- 0x2b4b4591, 0x67b03b01, 0xdb380244, 0x0391fe9a, 0xe1c9a771, 0x78051fdf,
- 0x5bfbeb27, 0x96fee35e, 0xedd6ded9, 0xd0ffdd21, 0x228925ed, 0xa0abb742,
- 0xa73c047d, 0xbdc0f4f8, 0x45beb0e0, 0xf53e786c, 0x95ea73f1, 0x8967971a,
- 0x9f3263ce, 0x19a44dc7, 0x2e9722e1, 0xe9471e5f, 0x63e39533, 0x491261f2,
- 0x427687ca, 0xfdc014a6, 0x4c902433, 0x15e299c7, 0x7c3127c8, 0x6328d373,
- 0xa426fe1d, 0xd5d3f477, 0x6375e6fb, 0xffce29ac, 0x7ec3cb43, 0x4dfc6e76,
- 0x3c173b3f, 0x90189fa6, 0x951dfd60, 0x7b03cecb, 0x2b0e1e18, 0x23b1d7f1,
- 0x58c79e5c, 0x3ce1f25a, 0xff3dbee4, 0xff7375c4, 0x07be7f9e, 0x53e8e476,
- 0xc63c8112, 0x2786a731, 0x28ebbee3, 0xef4af915, 0x06b3eab7, 0x49cf6107,
- 0x87e87dec, 0x15da3c28, 0xcb0d9f00, 0xfe3cced7, 0xe177f404, 0xf3624498,
- 0x5f154be4, 0x968f887f, 0x0ff17bf2, 0xd29ecc09, 0xfbf10fdb, 0x78b977a8,
- 0x93d28e7c, 0x1ac4c7fb, 0x5429e743, 0x74172513, 0xc9ca75d0, 0x7e5253b2,
- 0xdfc0fa67, 0x7e1f3a27, 0x57749e4b, 0xfb0e7ea5, 0x5eb62ef7, 0xc37f0392,
- 0x35d70cf3, 0xfd8123dc, 0x48a65d7e, 0xaf7198b4, 0x1fa7a957, 0xebd8f713,
- 0x07bfd932, 0x2a627b9e, 0x111e79e4, 0x2aac6531, 0x7cade3bc, 0x718b37a8,
- 0xf19ba7cf, 0x1ef85d7b, 0x887ff809, 0x574dc99b, 0x8ab98fe3, 0x4035c9f2,
- 0xc0ecc277, 0xc8e50142, 0x7bfddf4c, 0xcb47a3fe, 0x4ef8c4e0, 0x1d337f44,
- 0x8c533b5e, 0xd15d21fb, 0x7bb7ccc3, 0x57033ce9, 0xd97aefc0, 0xd77f0048,
- 0x83f583cb, 0xebac4cfe, 0xf4d55afc, 0xf3b00f74, 0xd49d3e74, 0xe8cdf183,
- 0x20f44fdd, 0x997a0ece, 0x19b826f1, 0x75d976fd, 0x633bc4bb, 0x67f47d2a,
- 0xa3210eba, 0xe4334806, 0x587394d9, 0x8a5bbe67, 0xf9e10976, 0x6df5e6ff,
- 0x24c778a6, 0xdd5da750, 0x3a8b7f4b, 0xb9f75bbb, 0x95a91d97, 0x952c1d60,
- 0xc63d3256, 0x1e1d78ed, 0x42ff9d33, 0x44fe11ca, 0xc0f999f0, 0x68aee70c,
- 0xeb86b27e, 0xfb4f7e81, 0x72b9fef4, 0xe8799c6a, 0xd085b8f8, 0xfbaf38f5,
- 0xdb8e71eb, 0x4fe7ffc8, 0xa013fc4e, 0x99bc9135, 0xd76e66e9, 0x0c2947f5,
- 0x00658050, 0xee2193ec, 0xd2879474, 0x60d10a8b, 0x9db7ba5f, 0x379b1a7c,
- 0xe40af93a, 0xf61e15b7, 0x2dbf112c, 0xdf1228bb, 0x93be0eb0, 0x00731f1b,
- 0x6a96eddf, 0xf7f45e1d, 0x5324d5a7, 0xacfc4d3c, 0x073c16f8, 0x102162de,
- 0xfe149b5a, 0x19c400e2, 0xcc128eaa, 0xef0e2f07, 0x3d3e012b, 0x9fa33528,
- 0x908176d5, 0xceec62c7, 0x038d70c6, 0x34c6b2ec, 0x50e99e76, 0x9be4310a,
- 0x7d33711e, 0xdcec78dd, 0xbb4e2d54, 0x79f8cc98, 0xf2d2d13a, 0xd74b3fe9,
- 0x3f00fe51, 0xe30ba7b8, 0xef051324, 0xb76069eb, 0x9feec6dc, 0xf91a6b6c,
- 0xb7851a7a, 0xd414cef5, 0xd71a9333, 0x84a1e3de, 0x0c3d7d08, 0x16cfb79f,
- 0x7be85bbc, 0xeb17aaa5, 0xd172f3a5, 0x4df91bef, 0xa193e98f, 0xfd197afd,
- 0x52e2499e, 0x6755e209, 0xf0028533, 0x2d08f727, 0xf2f7e0ab, 0x38d8d302,
- 0x01e813c4, 0x933be9fe, 0xdfc50c7b, 0xfaf55174, 0x205dfc00, 0x56dff262,
- 0xcfbf3aee, 0xce57db4a, 0x733f3010, 0x049b2792, 0x74a7f862, 0xbaf3829d,
- 0x0c519c39, 0xccbd3d7c, 0xc22c4e78, 0xe519c9ed, 0xdd8c120e, 0x283c1527,
- 0xedec87d7, 0x5cefe2b7, 0xe604c936, 0x0df9cba7, 0xce67df9c, 0x6ef861ea,
- 0xa776611a, 0x7237572e, 0xfb81bbf9, 0xb2f9b7cd, 0x1397e30d, 0x81fd0f66,
- 0x92044fb4, 0x3cb32794, 0xcdeda9a2, 0x2f0edeef, 0x8047bd89, 0x9071bc3e,
- 0x9715efc9, 0xc8be46ae, 0xc780bc14, 0xfb635e29, 0xe74ca34d, 0x6bf24d14,
- 0x20330fd6, 0xacec4a3b, 0x307d7427, 0x219449a3, 0x88a3341e, 0x62ed19e2,
- 0x95dedda3, 0x949918be, 0x525c5f40, 0xa433041f, 0xb0f8be93, 0x8be97bec,
- 0x32dba957, 0x36f5ca8a, 0x21f46f5d, 0x4c6f407d, 0x009feb12, 0xeba36a3e,
- 0x1f0e35a6, 0x1e8eebe9, 0x72a52807, 0x0ce07a8c, 0x749e2fcb, 0x86048b31,
- 0xa201c475, 0x25da847a, 0xd2f638de, 0x619e777e, 0x57aa23ff, 0xb912ec62,
- 0x25db87f0, 0xaa3da893, 0xbd7c0014, 0xc252be11, 0x90a596e2, 0xc3f102c8,
- 0x0e302fcc, 0x7f512554, 0xa7e7d716, 0xffa39e99, 0xe43b5212, 0xe8af6cc3,
- 0x3c09e871, 0x97e6617e, 0x16f23c68, 0x3a42e319, 0x3e02949f, 0x116ffe41,
- 0x2ba09f71, 0x37c7d1be, 0x14c44bf3, 0x5f92ea1f, 0x577ddcb8, 0xe6ed397e,
- 0xa4fea1f1, 0x44f8777f, 0x5f9d0fe7, 0x9bcdebcc, 0xa25138a6, 0xb09fe6f5,
- 0xbc4cf4de, 0x483ebcde, 0x95debd46, 0x992e735d, 0x6e89f9e9, 0x75773b0f,
- 0xd8270ce5, 0x59921335, 0x6ebe817e, 0x1b5de345, 0xdebc9f18, 0x7d824732,
- 0x1fd02aa6, 0xd0741db9, 0x5f3ac5e3, 0x60275b2e, 0xd732747c, 0x2c4dad5f,
- 0x5135585e, 0x8fd1c20c, 0x4f63f092, 0x6fbb3ab0, 0x14efa746, 0xd24527ce,
- 0xff7e093e, 0xe0af26f4, 0xc693b885, 0x35538de3, 0x668de301, 0x44d7b5bd,
- 0x1fbce9f7, 0xbbe0bff0, 0x2084ca9b, 0xfd6693f8, 0xb322fd36, 0x53d93a2f,
- 0xccd89f7c, 0x7326572f, 0xf497d0fd, 0x15da57fd, 0xddbf92a3, 0xefbfd0ae,
- 0xb065ce8a, 0xc0ffa0a6, 0x3b0193ee, 0xdd7ce81e, 0x2dfb0945, 0x49da3649,
- 0xfc14ce17, 0xfe4f7d0a, 0x3a1ef9be, 0x1aba7cf3, 0x17f750bf, 0x8fa0ffb8,
- 0xcec4837b, 0xa7d79bf7, 0xfe23d72e, 0x775e999d, 0xb5e31b24, 0x3d745d3a,
- 0x5cef09dc, 0x5ba2274f, 0xd75a7a57, 0x3d6aff87, 0xafaff7ad, 0x66b8fa23,
- 0x7fc89dfd, 0x9af1f5d4, 0xdb8c16cd, 0xfa7ee78c, 0xfe3f1e78, 0x7ee7b705,
- 0xdffccc99, 0x166d2fb6, 0x32436f58, 0xec0b27db, 0x69fc6273, 0x07665efb,
- 0xbe2a5cd9, 0x6220a0f7, 0x11c1e47c, 0xd4d7d416, 0xf3061a07, 0x19098a96,
- 0xbdbdfb04, 0xbd6f7ed8, 0x7d472914, 0x9c0895ef, 0x8c5d13d3, 0x1fdc1e1f,
- 0x7ffa1db8, 0x968193f0, 0x474f8c1a, 0x1a5ec19a, 0x7ee12059, 0xc5558a59,
- 0x936b7678, 0x6a3bef15, 0xf6bffddb, 0x97cfd0c9, 0xe52e0bc4, 0x746b26c1,
- 0xc7f40abf, 0x0888f124, 0xed6d1cf9, 0x1b03ef04, 0x02522b37, 0xd278d97e,
- 0xfffe035c, 0xc1e58518, 0x6cd4f19b, 0xfbcca75a, 0x2c4d255d, 0xc5c4a5ff,
- 0xed3a5ff3, 0xefe33457, 0x04904f26, 0xbce90d6f, 0xc992f15f, 0xefd8e9df,
- 0xd15fb04a, 0x77d1f4c8, 0x0318afdd, 0xde7ca034, 0xd701cba4, 0xbec1244f,
- 0xed8576c5, 0xcdbfb577, 0x6993d3ed, 0x5d46e371, 0xdeec5fed, 0x7dc1a49b,
- 0xeff9db23, 0xdbdeec6c, 0x13f3534b, 0xd2df9fbf, 0xd8d30c5e, 0x84b37f5e,
- 0xbe3c73f9, 0x9a0b8d1b, 0x90e9cbf1, 0x6b481f68, 0xf5041cf4, 0xe7df7095,
- 0xaae18a82, 0x5d4f8aef, 0x4f1fb66e, 0xb7ef80d2, 0x01a5ef1f, 0xdc79fb1c,
- 0xbcf56bd0, 0xeec2f605, 0x7092e763, 0x54d1583f, 0x53da4ff0, 0xae765e6c,
- 0x2841c992, 0xf610606b, 0xeff0f7ab, 0xbfb527b6, 0xec5a7579, 0xbfdb0e7e,
- 0xd7d9cfd1, 0x47f30428, 0x3f961602, 0x0cdfc662, 0x3b938f0f, 0x2274faf1,
- 0xbc62a9a7, 0x096f503c, 0x3f3057cb, 0xce4c3c97, 0xfdfe2fff, 0x80006684,
- 0x00008000, 0x00088b1f, 0x00000000, 0x5bbdff00, 0xd554780d, 0xdceefe99,
- 0xf26677b9, 0xfc999933, 0x4dc2fe10, 0x00908102, 0x7e100843, 0x502021d4,
- 0x4540647e, 0x043abaec, 0xa1bf9085, 0x56d3ebb1, 0x4126e1f7, 0x27d3e08a,
- 0x6796dd6d, 0x57067db5, 0x3b1254b6, 0x770704c1, 0x08a00ec2, 0x80a0db54,
- 0x11dae3c2, 0x2486a229, 0xec56bb0d, 0x3befdd6e, 0x6664dce7, 0xecfa5c18,
- 0xf8728376, 0x9cf739ee, 0xfbdf7cef, 0xb3739dfd, 0x330001d3, 0x68776e01,
- 0xdb00d900, 0x8c802f64, 0xde0820cf, 0x16e91bf4, 0xd305d609, 0x7ae77688,
- 0xa9dfe0a7, 0xce1a6ba6, 0x2cb0ef91, 0x7a448f35, 0x42d1e986, 0xc639e7a4,
- 0x699e7a72, 0xf806e286, 0xba5bc867, 0xcfc00e68, 0x03875e9c, 0xd257e9d7,
- 0x00194876, 0x65049366, 0x528ed859, 0xec373803, 0x65ac0152, 0x3c1daeb8,
- 0xaa40174e, 0xd21b7405, 0x54fb360d, 0x1e95f1a0, 0xd11a4b6d, 0x87c43d00,
- 0xa5039a39, 0xd336bed8, 0xbe00b304, 0xadc1fb4d, 0x1ef8aaa4, 0xc5a8ffbe,
- 0xfb81ce37, 0xec46b7ab, 0x1ff6015a, 0xa40473ba, 0x6c1d7ed1, 0xcf2f25bf,
- 0xc60285cb, 0x33ffe157, 0xf8c9655f, 0x75f0a6da, 0x2c940f7a, 0x64bf5c04,
- 0x1a5f8a1c, 0x59994fd6, 0x416dcf63, 0xf49f3d00, 0x9095c9e0, 0xeeaa716e,
- 0xce34f99d, 0xb6f267d0, 0x21fd4145, 0x69aa725f, 0xce51e90b, 0xc0e96d30,
- 0x89874ef6, 0xac58bfcd, 0xb7903003, 0x8e0df51a, 0x5335bc81, 0x96fa4d38,
- 0x4881b2e5, 0x9b7f5239, 0x871e7eee, 0x0f8198c2, 0xddfa471e, 0x3bdc4a07,
- 0xc290be91, 0x502eb1e5, 0x7a4512d0, 0x363025ba, 0x9d397c82, 0xf7c92f3e,
- 0x04c0969b, 0x2db4a786, 0xe4bf34e9, 0xca0ef801, 0x3d104243, 0xf16efb80,
- 0x0216a680, 0x1ce7808c, 0x90004b97, 0x332af82b, 0x2560bad9, 0x8737deb9,
- 0x1758d5cb, 0x1c856865, 0x3f82a7e4, 0xf5c0f837, 0xc1beb47d, 0x301f10cf,
- 0x153971c6, 0x4857cfd8, 0xd33cd1f7, 0x0a321e50, 0xfff3d705, 0xa0b014de,
- 0x3ff8fdfc, 0x325f2fd1, 0xc9897405, 0x2cfd6d3d, 0x33ad88f6, 0x9966ade7,
- 0x9fe3ab31, 0xecd44c59, 0xbb543ca7, 0xf748ec02, 0xad462f98, 0x37f61d62,
- 0x9cf91c6e, 0x7d9fde27, 0x8d30b7c2, 0xc7e2f7da, 0xffa783cd, 0x15fbe320,
- 0xe5019010, 0xd09a2732, 0x31fe5a1f, 0x4aef3fcd, 0x77bff3fc, 0x7db167a4,
- 0x5f51828d, 0x77227db1, 0x95a35eb8, 0x66f837af, 0xd3e10641, 0xa2d9466c,
- 0x864d55fc, 0xa2bf6c0a, 0x3a003b9f, 0x0b38e2b7, 0x56adc1c0, 0xe3394ed6,
- 0x84eb40d8, 0x269022b6, 0x35babc02, 0x1d86b597, 0x0f03394d, 0x7598d4c1,
- 0x390dde04, 0xe5c7be0e, 0xe93a3d38, 0x5691f3a7, 0xd010284e, 0x5730e586,
- 0x5d106bc8, 0xf079e906, 0x475b9a4a, 0xbbc9d67a, 0x4b4fb265, 0x98b409ae,
- 0x14b4d9fd, 0xd30d26d0, 0x715c93a9, 0xb8f42cb4, 0x9e7f66cd, 0xf4f742e1,
- 0x333ae2e4, 0xeee93ac4, 0x41f37151, 0xe8c4ff00, 0xe2d755f3, 0x67ee1213,
- 0x0af55a46, 0x454657da, 0xe5fcdc41, 0xbbcbc66f, 0x091ebc0c, 0x8fbf765f,
- 0xb3fbe3fc, 0xcc7f60ce, 0x2b488af8, 0xfbc547c3, 0x5ee7cff1, 0x6f3ba78a,
- 0xc99bb7a6, 0x74fea613, 0x2e5fd67e, 0x5e27a74f, 0xe34b999e, 0x8ded99e5,
- 0x7588e797, 0xe91af2f1, 0xe8c7978b, 0xfd71c9ea, 0xc594b763, 0x33bee3d1,
- 0xbe7c6e37, 0x1747195e, 0x371658ee, 0x9aeb427e, 0xeee27a38, 0x2f8dc66f,
- 0xf5c5540e, 0xf9abec97, 0x253ff48b, 0x9e3718d8, 0x1afa6cc4, 0x7d0b4ffd,
- 0xbfbd6e2f, 0x9dfffe96, 0xcf7e8ff4, 0x7a44bfd0, 0x42fa499f, 0x1c36593f,
- 0x06b89c9f, 0xf8674bf9, 0xda12eb8d, 0xe9a95ea5, 0x0cbebcc4, 0xf7d82ddc,
- 0xc895ec8c, 0x51468dbf, 0x6c6fd09b, 0xf9354133, 0x4c981ffd, 0x86d3790f,
- 0x94e4dced, 0xaacffcd8, 0x14b8a660, 0xe94d6e3b, 0x4da338f0, 0x78d89a77,
- 0xd37edfc3, 0xd144b5a2, 0xb9974e9f, 0x9b3f453f, 0x707f44ee, 0x21427a41,
- 0xe964a937, 0xc594af8a, 0xd8bc879d, 0x6a4b213a, 0xd86336c4, 0xa15f6bbf,
- 0x81a82e52, 0xfe213fbd, 0xbdeec94f, 0x486fffc8, 0x17492320, 0xef3f166e,
- 0xa696fc37, 0xf8633865, 0xe2334c1a, 0xf14196ad, 0x42e1f073, 0x3fced7e6,
- 0xf50b4e88, 0xfbe55e7f, 0x115fc631, 0xe153ed7e, 0x9fc97ad7, 0xabfb8659,
- 0x5d38fcf7, 0x4fce79c3, 0x18c1a582, 0x390b1539, 0x2c1c1981, 0x3ae3ccee,
- 0x4bb350bb, 0xdff388d9, 0xa16c2ef7, 0x13fbee75, 0x6f7d896c, 0xfe6153b6,
- 0x6653b671, 0x726c5aed, 0x316bce51, 0x18cb39a6, 0x5db0911d, 0xb2140275,
- 0x7cbed5cb, 0x0ef28485, 0xe176cfb8, 0xd1480b92, 0xe03ddef8, 0x9fffc855,
- 0x9d3eb07b, 0xf3cd0dc6, 0x117713c6, 0xa2a2d73e, 0xd7792f29, 0xe8392ba9,
- 0x936e060f, 0x75c49c58, 0xfbdcf4ac, 0x2927e8c0, 0xdf039cbe, 0xafa8b3d5,
- 0xf366e035, 0x7222f319, 0x05ccfce3, 0x38992215, 0x12c17e8f, 0x347c8bd8,
- 0xfa825e52, 0xc11eec69, 0xcd7f5fe2, 0x827fdb1f, 0x1d1a1ee3, 0xfaf14b1d,
- 0x8a9fcd42, 0xeff7cf48, 0x7d434196, 0x77c5377e, 0x90c0e117, 0xaf87f9c3,
- 0xc63f53a5, 0xd867a65d, 0x65ef716f, 0xdecfdbf2, 0x73adc633, 0xde9bb82e,
- 0xd0140a83, 0x67f11b9c, 0x496814b4, 0xe06a352e, 0x3e43dfe7, 0xe6c294e1,
- 0x59b2f033, 0x5f31a5e0, 0x978b111b, 0xbc21f4c6, 0x71ab7cb0, 0xa6ecccaf,
- 0x0016dbb1, 0x8159cb94, 0xebfeff3b, 0x234f7d2f, 0x1f3de782, 0xc4346e21,
- 0x3711efc9, 0x8fbdc61a, 0x3f443711, 0x886b7b2a, 0xfe9e8fdf, 0x79a3eec8,
- 0xbe35b9ef, 0x7381a5fb, 0x3df2437f, 0x083ef1c9, 0x5f98e783, 0x28d62cef,
- 0xf0785baf, 0xebca39fa, 0x9a2d3a1a, 0xceabe905, 0x6967f1e8, 0x680921fc,
- 0xc6c4437c, 0xa743559c, 0x7f61b014, 0xfb63a84d, 0xda6ba468, 0xd8539756,
- 0x7221dbf0, 0x901ff507, 0x7fd8cd02, 0x7b5eab79, 0xf0b87509, 0x6997ebd5,
- 0xf957bede, 0xeab657bc, 0x9013cc1b, 0x03feb03e, 0xd3aeaf9a, 0x6fd43602,
- 0x8ea2339f, 0xa43af5a6, 0x1d57ad20, 0xf34aa1fc, 0x7ab0bf57, 0xb539a53c,
- 0xc6aa9afb, 0xbebff8c7, 0x0d55a783, 0xf9dd54e5, 0x5c62c5c3, 0x015f0f39,
- 0xfec63766, 0x369a0737, 0x2ee36398, 0x7b275bfe, 0x2df77e12, 0xe175ff21,
- 0x271216c2, 0x67ae95fa, 0x7657e625, 0xb872bf33, 0x85fedffd, 0x8bf43bd6,
- 0x281b8409, 0x837935bf, 0xb1716757, 0x5703ac41, 0x9ea951de, 0x2e54e869,
- 0x7c65e7c7, 0x77a735fc, 0xf92673af, 0x85b49855, 0x79f13bd5, 0x25940ee2,
- 0x7e7ae1e5, 0x390fb30a, 0x8f5d406d, 0x069f7cfc, 0xc7663f20, 0xf4855a80,
- 0x5718970e, 0xcdec0d60, 0x3ebf91bf, 0x67ad99a7, 0xac5f002d, 0xcfda30df,
- 0x82b1ff44, 0xd528d54f, 0x9515da17, 0xf910db70, 0x7f90d544, 0xc5c3e87f,
- 0x7def249e, 0x6295fc22, 0x29ef56f2, 0x468fb61f, 0x714a39a9, 0x44d0f1aa,
- 0xd67a674d, 0x2ebf8ca3, 0x58fb469b, 0x5993f078, 0x3ef998d1, 0x578c7c43,
- 0x5f86e986, 0x2155387d, 0xe1fcbdb9, 0xcc7a7354, 0xaad2723e, 0xe0f94903,
- 0xbb49e2f1, 0x5bad0af7, 0x35a2d07f, 0xdcdb7c33, 0x3877c211, 0x44668dd5,
- 0xcb9b56f8, 0x3f7df163, 0x2c21bbe3, 0xd0e911bb, 0x6bed5a10, 0xddd3e362,
- 0xb43906a4, 0xc99c2740, 0x23c32f0e, 0x37ae27fc, 0xfe30e28b, 0x756a3fa0,
- 0x78477efa, 0x55e9a731, 0xdaf898e6, 0x35e68a60, 0x5f3fa44b, 0xfb1882eb,
- 0xad74d393, 0x99e48b39, 0x61b596e9, 0xae2629fd, 0x6a2d3e97, 0xdb1c5177,
- 0xbd91f38a, 0x93b13e44, 0x3687b7fc, 0x3beec958, 0x47ae0e9c, 0x481cd755,
- 0x877a09b7, 0xbb26adea, 0xc29391da, 0x2e31b5eb, 0x09ffef86, 0xaf647daf,
- 0x3e028eb8, 0x09f77f56, 0x058df5bc, 0xf7297fe6, 0x94c99c23, 0x199215ef,
- 0xce341cf9, 0xbdaa6a1f, 0x87976b14, 0x7f1373ee, 0x1f7f0a4a, 0x135e3872,
- 0x7175cdd7, 0xaa693d9c, 0x13105d6a, 0xe5c71387, 0xc399b8d0, 0xceb30072,
- 0x697001ce, 0xfefc324f, 0x776959c2, 0xde5dfe91, 0xcd87e449, 0x51e118c4,
- 0x81f29353, 0xd95cb3e3, 0x2e4de3c3, 0x554f5b07, 0xeb920e7c, 0xad39397f,
- 0x67265ea8, 0xec8d6c34, 0x057f6878, 0x9b3b526a, 0x91def82e, 0xc4f7af1f,
- 0x38c4d371, 0x56e7a4c5, 0x65879f11, 0xdafd3766, 0x31bfd300, 0x9d723fae,
- 0xed7c3feb, 0x79d90f2e, 0xcf865afe, 0x5c597f4f, 0xbbccc726, 0x853959ce,
- 0x12e793f6, 0x5cf45078, 0x2ba47be2, 0x733f1f7e, 0x62b8677a, 0x4c601fce,
- 0x04e12dd6, 0x16e07d44, 0x83eb0ef1, 0xb57c6649, 0xe4dc521f, 0x1e443bdf,
- 0xc32f066c, 0x35b82a49, 0xe07af756, 0x7f70f3d7, 0xb04c472d, 0x1d3b4913,
- 0xf3628c72, 0x04d8b079, 0x8a326cbb, 0x4b158f08, 0x323212bd, 0x9ae25fec,
- 0xc86d8df6, 0x65d021ef, 0xd7c73f5e, 0x3c91e0c1, 0xfbfd6c52, 0xd5adcd5a,
- 0x5af9cfbf, 0xeb13cec8, 0xd31139df, 0x16e3357a, 0x96d7e0ea, 0x1f83ad25,
- 0x53d7c574, 0xc634bb0f, 0xc712705c, 0x12923061, 0x3028e7e0, 0x845c7083,
- 0xedfa84e1, 0xa555bc39, 0x275649be, 0xf4d733c6, 0x418c76a7, 0xe5cf1b3b,
- 0xfd0b7440, 0x8df3ca3b, 0xb5fabaa1, 0x44ff2cc9, 0x7ab3247f, 0x497821d2,
- 0xe6395fd0, 0x7118bc49, 0x91e5d5c7, 0xc9da5fe3, 0xb4bbb6ff, 0x067e92df,
- 0x7940ca4e, 0x551ccd9c, 0xebec499d, 0x98b3e520, 0xe2e4bc8f, 0x921ad67e,
- 0xdf5c013c, 0xe28079aa, 0x98e1cdbc, 0x59d8c72e, 0x85c78b95, 0xf217e3fa,
- 0xaf23cc54, 0x97b4de9a, 0x5d75fce2, 0xcc74ec07, 0xedfe7b53, 0xb4147459,
- 0x4edbecc8, 0xb4a9fb76, 0xf94ac8a7, 0x54c08ee1, 0x52304f92, 0x77714190,
- 0x7374198a, 0xf8fc8dd9, 0x50a6e377, 0x33bb0d86, 0x3c253b59, 0xa7e51363,
- 0x2fdf08fe, 0x0ba0a1ad, 0x8c490e2c, 0xb8b50bee, 0xbfff3e68, 0x3f228f76,
- 0x9f9b3fb5, 0x45f8be2f, 0x0cdf7f09, 0xacff1a66, 0x1ef029cb, 0xd479d130,
- 0xd58e717e, 0xc6cc85f7, 0x094feb19, 0x881d902d, 0xeb48d283, 0x164e7651,
- 0xca7cb0b6, 0x797002f6, 0xa3cf3184, 0x4bc39cf3, 0xbf51e280, 0xf612dc13,
- 0xb00ca7b7, 0xdba067fc, 0x912f3da2, 0xec815adc, 0x75e55dbd, 0xf602314b,
- 0x73f0da40, 0xf85b3d63, 0x44e674a7, 0xfc50f0b8, 0xe15b99b3, 0x7958b4b6,
- 0x877933a7, 0xa6c80f29, 0x34a62275, 0x77d1cfca, 0x1af8cf3e, 0xbad813e6,
- 0xccc59f06, 0x03abb7cf, 0x62cf1f97, 0x0708397c, 0x84f9c0c5, 0xfc8d44f0,
- 0x61e1cd9c, 0x3439b0fb, 0xc8dd2eb7, 0x262a7f97, 0x3f3f6860, 0x7b218668,
- 0xa7f6fb26, 0xb456d30c, 0x8e02f685, 0x3c37d06b, 0x0c7e68b5, 0x62a68e4d,
- 0xaed3fdf8, 0x1b6d4f8d, 0x748dcec3, 0x8a9ff519, 0xf68bba6d, 0xbd0aedc9,
- 0x8cbb27a7, 0x728dc1cb, 0xfef2b54a, 0xf388f1a1, 0xf8d3a234, 0x91c5b738,
- 0xd99f2cba, 0x18bd900b, 0xa5b7d9f9, 0x503be5c8, 0xf43fbdb5, 0xbee29466,
- 0x1f474d7a, 0x9f71c36b, 0x45160fad, 0x7d50fea8, 0x5f3e13ef, 0xd76abf79,
- 0xedbbf214, 0xf9057b8a, 0x23fea89f, 0xa8bf0796, 0xec633b68, 0xe40cc60e,
- 0xd7137e10, 0xfe6f9ff1, 0xfdb9e511, 0xaacd2487, 0xc81dff91, 0xc21bbe23,
- 0xd7e4ab1f, 0x643e87fd, 0x9913ed79, 0x5eb42bbe, 0x2169a845, 0xb40e75c9,
- 0x2edf90b6, 0x3041f911, 0xc193fb97, 0x37cf4533, 0x9ec1e8c5, 0x0edc7129,
- 0x9c51c6f8, 0x3d7b0b0a, 0xb627f54c, 0x2fee475d, 0x44bbf9a4, 0xd7bc6c7d,
- 0x93474704, 0x35e19bdc, 0x9dc50ed6, 0xe1297980, 0xf59ce4ac, 0x78cc4f21,
- 0xbf3f266b, 0x02f58ab5, 0x133fbe99, 0x2e47b5bf, 0xe7da76aa, 0xd51e60a5,
- 0x93ac4195, 0xc8fc491d, 0xd826fd90, 0xa03cdf93, 0x15ff78d2, 0xf5057e60,
- 0xf5032dbd, 0x685cffb7, 0xde7c7af2, 0xa0c93a85, 0xaf3ce17c, 0xef14bb13,
- 0x74df1a68, 0xe4a9f3f6, 0xa82806c7, 0x779f7fe1, 0xb9238ed7, 0x532bfe21,
- 0x803acec8, 0x4ec335f9, 0xf14ec94b, 0x7fc252fd, 0xccc5d139, 0x3dabb72f,
- 0x765d98cb, 0x12ec8099, 0x01eccff1, 0xb8a0eff1, 0x7b40ea5c, 0x644fef60,
- 0x63dede76, 0x167cb0f2, 0x4604fafd, 0x744dde57, 0x0722cf7b, 0xe21373b3,
- 0x35ec8cb9, 0x13cd9472, 0xa634a004, 0xec6f025c, 0xcb954139, 0xf86cf0ce,
- 0x7ec22dcb, 0x0cb49383, 0x5523ee37, 0x23ece396, 0x5a725e26, 0x7fc7d3c4,
- 0x9ea793fc, 0xa78f4f99, 0x10e138f3, 0xce9b5271, 0x22a3fefc, 0x3ebe3556,
- 0xe51b5577, 0xacc96fe5, 0xa738b0ff, 0x1c9c0888, 0x1414e715, 0xcfd43437,
- 0x75fce26b, 0xf41ed226, 0x5b3cb3a3, 0x556e5216, 0x18f5b4b1, 0xc1bd73b5,
- 0xce329485, 0x4c73d75f, 0x425e66e1, 0xfa3cebf8, 0xf933128d, 0xcebcf3bd,
- 0xe072fceb, 0x0e511783, 0xf9461d8f, 0xb8538927, 0xcc3f861d, 0xee4346b3,
- 0x92fdfd8d, 0xf97e47e1, 0xfa43aa0d, 0x1a61e53a, 0x020363e3, 0x9955e89b,
- 0x474a78bf, 0xf4c83ec6, 0x7944c9ac, 0x35bed9ca, 0x9cef9499, 0xcc8732fe,
- 0x45ccebb2, 0xaa773f56, 0x4fc2129e, 0x9c960167, 0x7b7a7049, 0x51f4c2a6,
- 0x673f896e, 0x84c7da31, 0xb0e9141d, 0xb1f5624b, 0xfd5008ec, 0x547b29dc,
- 0x80ae83cc, 0xf91e76be, 0xf81e711b, 0x0f1f8808, 0x6cfd41fe, 0x9423e414,
- 0xdadc60b7, 0x77128cf8, 0x2de4673e, 0xb07bc675, 0xdaf844c5, 0x1fe09614,
- 0xcfd51651, 0xa3af8fc5, 0xd9e705bc, 0x7c73da1c, 0xe6b5ea34, 0xca7e8485,
- 0x79b9d85b, 0x75a3d590, 0xfe5c4a6d, 0x38a658f2, 0x42842c0f, 0x57105fca,
- 0x66284fcc, 0x1c416138, 0x6df6c84f, 0x6fdf3b20, 0xff42f2e2, 0x0373ecca,
- 0xb79f15e1, 0x34bf7257, 0xcc021570, 0x8f05f67e, 0xb9df91d9, 0x5a6ef96d,
- 0xf799ae63, 0xf3e50dcf, 0x40730d7b, 0xa90a8d5e, 0xb316f8f0, 0x9cf75afc,
- 0x54b945c9, 0x0e097f0b, 0x59b5fe7e, 0xe45abeec, 0x4a039b77, 0x2fcefcd2,
- 0x4081cdc6, 0x69bbad0b, 0x47cec49f, 0x8fc5f76b, 0xd5390bf7, 0x9c7d3eed,
- 0x83eafd8e, 0x4e42fd09, 0xf3fc50fe, 0x78727c03, 0x1e5390d6, 0xf373b1e4,
- 0x6756b713, 0x7cf0a67d, 0x8f316de3, 0x38161fd1, 0x906dc06a, 0x7202eb7e,
- 0x2d547080, 0xf79e76e9, 0xdc7ada42, 0x060306df, 0xb941fe1a, 0xb4e42c3c,
- 0xed87e041, 0x7fafdf1f, 0xbdd00a4e, 0xc74fc3d3, 0x5e035ff3, 0xdf3e3475,
- 0x952df9d8, 0xf112f5ce, 0xb0a6dd56, 0xc846b7fc, 0x355f1127, 0x5569f843,
- 0xe225be29, 0xdd27c1ab, 0xb79e7f84, 0x37f96fff, 0xa6235cf4, 0xec2255a9,
- 0x1ff6a89c, 0xddaeb724, 0xfb435f7c, 0x4bfbfb11, 0xd0de75f7, 0xcc9864f7,
- 0xf334bdf4, 0xf8a5eb16, 0xe543bb7c, 0xe6683376, 0x9e06cae7, 0x2c5fdf12,
- 0xbb25f5f2, 0x357ade79, 0xe74ecd74, 0x833dfdc4, 0x69ad6076, 0xa247c529,
- 0xa5f8c7c7, 0x5d79324f, 0xa3f73dbd, 0xbf3e501f, 0x637143a4, 0x637507a6,
- 0xf1c52f15, 0xe7afb1ba, 0x2bad8f8c, 0x1d25f8c5, 0xe8db348f, 0x9297e23c,
- 0x3fb2cc9b, 0x894777fc, 0xf724dbd6, 0x78ff7c04, 0xe66fe0cf, 0x53725e91,
- 0xfe7cd167, 0xda4b3bee, 0xfcfe3e91, 0xfd6c770c, 0xf7c5dc79, 0xc2ac64b7,
- 0xa8ef6ae2, 0x415a7fd4, 0x3d9e85e7, 0x5f7bbecc, 0xfb25597d, 0x20976fef,
- 0x9e3a1717, 0x1d25ec7b, 0xf07bdde5, 0xfac94ab4, 0x6ad3cec2, 0x85f26bf4,
- 0x458e58ab, 0xab6a79d8, 0xb78f754a, 0x946af7eb, 0x3e17a7f2, 0x3554e764,
- 0x3e53e794, 0xd01c9cf6, 0xbac79ff0, 0x4f09515f, 0x8c126d0d, 0x57ed8fc8,
- 0x41f93f58, 0xe36e3fa2, 0x69c0d4fe, 0x81a5c095, 0x55b70353, 0xd86cffc2,
- 0x86971c91, 0x9e08da9f, 0xbe70a3ed, 0xabd6da47, 0xd23d0794, 0x137e3f1a,
- 0x68d399d5, 0xa6e5c73c, 0x9bfdf1dd, 0x33a8f087, 0xefe89d3f, 0x1e04b24a,
- 0xf098a18b, 0x1aa91838, 0x7fdc4667, 0x1c66ba7e, 0x7947b924, 0x2377c453,
- 0xbe4cdebe, 0x2a6ba17d, 0x18ff45c5, 0xfe17d585, 0xc6a1ff31, 0x166665e2,
- 0xf0e2cbc7, 0x569e981f, 0xa22c8f84, 0xaf8256f5, 0x32bce48e, 0x7ca0ea9c,
- 0xdb944579, 0x25b0b2f1, 0x3f889010, 0x2b878b13, 0x708db821, 0xc2d87fd0,
- 0x955f29cf, 0xc204de58, 0x72126dbf, 0xbce424df, 0xd1b1eb09, 0xa883ddf4,
- 0xdd441bc7, 0x9ed279bd, 0x340254e3, 0x93bafe88, 0xe724ecc7, 0xcffdc065,
- 0x3ff720b2, 0x788cfe86, 0x18f76892, 0xfd241ea9, 0x402d86d7, 0x172c33df,
- 0x1b7967fe, 0x46e91ffa, 0x323fd03f, 0xef47e195, 0xc6277ce2, 0xf8ce86cf,
- 0x78b20bf1, 0xf2283a3e, 0x712caae0, 0xb6f4203e, 0x4b520062, 0x9a65be71,
- 0xb7b00eec, 0xfeb4cc7a, 0x4788a989, 0x5684ff9c, 0xa24be198, 0x8dfda34f,
- 0x7a0defc8, 0xe18b9d15, 0x35a3a0f8, 0x7f7eb62d, 0xebd78b2b, 0x9d647335,
- 0xef5310f4, 0x4fcb2aac, 0x377cef5a, 0x31bfc70b, 0xd3d3c366, 0xcf1deb63,
- 0xe3c2229e, 0xbc7f73f7, 0xf157be82, 0xd2ff71b7, 0x66f38157, 0x2c0efe50,
- 0x59b7f61f, 0xf8975402, 0x37544f11, 0x90bc212c, 0x3ba586bd, 0x2f582f09,
- 0xaff3493c, 0xdc3b2ba6, 0xc610eaff, 0xf57e9c69, 0xfc303fa2, 0xf7cf1c9d,
- 0x911b728d, 0xea307eac, 0x782f8686, 0x6f3c6a7e, 0xfd594730, 0x189610d0,
- 0x5e8f3b7e, 0x7e47cbcf, 0x98ffbbfb, 0x50db1eb7, 0x9db38f16, 0xf48bc195,
- 0xede7c91d, 0xe879a4d6, 0xb6971f90, 0x50697b31, 0x3f2c39a2, 0xe0f98439,
- 0xde37ac6c, 0x1bd594fe, 0x0f6d479d, 0xcab43cb1, 0x35f1ce37, 0x66826a7a,
- 0xc336cf96, 0x9e52d636, 0x6dff9b13, 0x52eff072, 0x48388a36, 0xeb8813f4,
- 0xf6f6388d, 0x83fd1bb2, 0x05ea6fe1, 0xbe8337ae, 0xa3749e7d, 0x7617a89f,
- 0x67ba5b53, 0x8968a53b, 0xb0bd5079, 0x59fccc27, 0x83cc4bdc, 0x6bc04ade,
- 0x2c29dbd3, 0x293fedcf, 0x184ce83b, 0x51f3fbe5, 0x7e61ef94, 0x1ce4905f,
- 0xcf8153f4, 0xd9ff715e, 0xf9332154, 0xd6f0e699, 0x8e509bc8, 0xa7fd370c,
- 0x275402d3, 0xa57e1c94, 0xbb507080, 0xdac5c70f, 0xc7d1ea1f, 0xf00a0fbe,
- 0x2a60a573, 0xfa31d3bb, 0x657e1ff7, 0xe9ade132, 0xb88b2fed, 0xa917ae7e,
- 0xcfe73759, 0xd7892568, 0xd78926bf, 0xa8e65dbf, 0xff2eea9d, 0x881bd921,
- 0xefa1abd1, 0xc08e040f, 0x8bfcebcc, 0x9ba31a59, 0xa61f1cc2, 0xfae2de6e,
- 0x8f39f96b, 0xa1bfd6c2, 0xf37112bf, 0x880ef135, 0x5f80c42f, 0xf3f86019,
- 0x7e31369f, 0x7307a7fc, 0x4ebee362, 0xff208ef3, 0xcc0754d7, 0xf902a49f,
- 0x3a67f45d, 0xdfcbcbd5, 0xea7cb1b3, 0x15aec178, 0xc8157fcc, 0xb1ebfe40,
- 0xc6266bb7, 0x598d8bc6, 0x254c3f32, 0x1652e439, 0x5f5f0cf3, 0xd619a1c8,
- 0x8e027388, 0xb9338fe7, 0xeafac15f, 0x89cf64cf, 0xe6add5f5, 0x16dd4dc5,
- 0xff6473a0, 0xcefb0b05, 0x4deef3e4, 0x2f877eac, 0xdfc9137c, 0x8d37cf80,
- 0x6f0ec7da, 0x3fcf489a, 0x1a79bc3f, 0x9a94f73b, 0x4e99e2e3, 0xbe52e5fc,
- 0xc3473674, 0xb3eefafe, 0xfab8bbec, 0x4ff1856e, 0xcb3c6c74, 0xefe7e6c8,
- 0xec6c47fd, 0x0282437c, 0x1f18038e, 0xe75d6f37, 0xa8bf2ceb, 0x589ec90b,
- 0x8def183c, 0xb171e6cb, 0x20e05b30, 0x9e987928, 0x175b783b, 0x53f1997a,
- 0x1e9904ab, 0xde14da9b, 0xcc5bcedf, 0x3a1f193b, 0xbfe274b8, 0xf9bfce83,
- 0xe73b08bd, 0x3ecc91c0, 0x07152706, 0x6bfd2276, 0x1d72847a, 0x3f80980c,
- 0xe4fbb0b7, 0x19851396, 0x13c1fb84, 0x8b25672f, 0x3dd26f1b, 0x54e5420a,
- 0x1243af3e, 0xf3652ffb, 0xe75387f3, 0xb53b3fb9, 0x993137c0, 0x92a1d35f,
- 0x9092e9d7, 0x34b2a777, 0x45dc7dd9, 0x31bedf31, 0x4fda29fa, 0xdd8d876f,
- 0xf93af5c7, 0x03c2ea79, 0x1499cd27, 0x99a53b7f, 0x276a4714, 0xbe88bbbd,
- 0x9cba4003, 0xe46d5afc, 0xac77bb10, 0xec58eb6f, 0x4747c249, 0x32dfc736,
- 0xe67df935, 0x3bff44b7, 0x7516cee0, 0xae132ed4, 0xc50acef7, 0x1de593b1,
- 0xe891b49e, 0x7e12ef87, 0x0a95eef8, 0x01de53cb, 0x16f7e14d, 0x95617efc,
- 0x0977b3f0, 0x22aabcff, 0x57be3fb9, 0x39fab3cc, 0x17ee9278, 0xc7e27b56,
- 0xbdf22bdd, 0xf361e035, 0xa134bddf, 0xf77de45f, 0xc1f2137a, 0x8b87e16c,
- 0x70fc88a0, 0xe903e310, 0xc6d8b1bd, 0x29f2ece2, 0x09e69213, 0xd2ffd1c7,
- 0xc42703f7, 0xfe860477, 0x65df8a9b, 0x91d4ebf1, 0x99392ff3, 0x4141b6ff,
- 0xe1b1fb92, 0xfdd865f8, 0xe2ef5c3d, 0xc1dea1be, 0x7ff43479, 0xd8a32b15,
- 0xff432d73, 0x7f73674f, 0xb6cfbb59, 0xb0bef625, 0xa38ce83e, 0x5b91a1fd,
- 0xfbf8c52e, 0x8c73815a, 0x73d8e601, 0xdf641790, 0xf4d9d9d3, 0xcb2f6b3d,
- 0x2c0771af, 0xf2bee17e, 0x2cf2bec4, 0xeae97131, 0x7149f5c8, 0x973fbc3c,
- 0x167ffdce, 0x5b148f6b, 0x07d5fd98, 0x6bdd00a5, 0x3db847d5, 0xb123dfd6,
- 0xcea2c273, 0x857bec23, 0xb7248bb5, 0x33b1bb87, 0xa3819fc4, 0xcf1e5655,
- 0xc90cbc0d, 0xfa88e04b, 0x25dfbe29, 0x9e227be2, 0x62cf4226, 0x8f3eff9a,
- 0xecefa6e4, 0x75a38a6e, 0x30a75fd3, 0x211c3374, 0x9bf2152e, 0x24fa7889,
- 0xf249d7db, 0xed71fac3, 0x54ff9c14, 0x8479c7f1, 0xd89b869f, 0x1d856fd1,
- 0x4fd34bed, 0x3baffc51, 0x0fd5ee20, 0x24a28714, 0xf2c01397, 0xcf675ec0,
- 0x1f9e46f6, 0xfaf57bb3, 0x0f7d8d88, 0x754e1f58, 0x6cee88db, 0x754c994a,
- 0xa7765864, 0xf3a2bd22, 0xdfaa22f4, 0xeff39457, 0x01d41a3c, 0x3ab68796,
- 0xbf89277d, 0xb8a6ee95, 0xcf8374fb, 0xd13de19b, 0xe1245dcf, 0xfcf5ff64,
- 0x972145cf, 0x72d793c6, 0x9d7e1326, 0x5365dfbe, 0x45fd793c, 0xfcf6ae95,
- 0x9c595f93, 0x8d38d1a9, 0x76d95b8d, 0xe31d1b64, 0xcf4ffc1a, 0x4efe3076,
- 0x2c318129, 0xb5bd2cbf, 0x0e9a4bef, 0xf29531bd, 0x2723bee9, 0x3831aaa7,
- 0x7f446def, 0x4d7f449d, 0x6bf61260, 0xad24ad66, 0xb70ef911, 0xb1f77f67,
- 0xe85f3a1c, 0xa52e3b25, 0xe29dacf6, 0x3bc77d64, 0x779409f6, 0x98d6f174,
- 0x66586aef, 0x2d1cc0e3, 0x963d37ba, 0x7f1927bf, 0x1e7c8357, 0xddd16880,
- 0x5bfb6253, 0x40fdaffe, 0x03f30e7a, 0x603f38d1, 0x7bab09c8, 0x8799d59d,
- 0x9e9eec2d, 0xbf625bee, 0xe1ce2acf, 0x1636697e, 0x73af643d, 0x90b99ee8,
- 0x3c333352, 0x2219b440, 0x07dd1766, 0xddfe6447, 0xe7e618da, 0x67f58967,
- 0xe847239b, 0xe239cdbb, 0xf42e727e, 0xc3b771b0, 0xe03d6b00, 0x095b5330,
- 0x5856d66e, 0x6ca9cb23, 0x65060d2f, 0xc7247fd2, 0xe56cbcec, 0x4c90f2bf,
- 0x3372c3df, 0x1e4365c3, 0xf163dd32, 0xf712ffef, 0xf1c39953, 0xfdc3db38,
- 0xf416a50f, 0x040566dd, 0x6df9fdd9, 0xe8f71510, 0x0f31f7c9, 0x37ba37eb,
- 0x99d30dbb, 0x008f2614, 0xf69f3f1b, 0x4fdb2723, 0x33533974, 0x7f10722c,
- 0xf4c72452, 0xefadea55, 0xd8073fa3, 0x030df6bc, 0x0f978f7d, 0xc3ba3bdf,
- 0xdf47bc6f, 0x0f1e4a99, 0x6dd50efb, 0x1d508b4d, 0x1de8da83, 0xe80563f2,
- 0x56aa7337, 0xfe1ccce6, 0xc07c1f9e, 0xfc48cfbe, 0x7bb69f9e, 0xbbf86725,
- 0xd27be32f, 0x9a35817d, 0x2eb1f109, 0x1196eacb, 0xbcd6651f, 0x657bec19,
- 0xe1256fa7, 0x36d482ea, 0x0e624d81, 0xa87964cc, 0x782a55c0, 0x92ff682a,
- 0x027df8c7, 0xc5d17860, 0x039eb7f9, 0x5238f7ec, 0x2bf7fc2d, 0xad0e2176,
- 0x8d7e862e, 0x27858fbe, 0xef946a16, 0xdd5a776e, 0x8859cf94, 0x7e61d4df,
- 0x3bfcac5b, 0x5e6b168a, 0xf1b8fc80, 0x3ca2585d, 0x3d16505b, 0x56dd0ecc,
- 0xfc272f96, 0xc59b47fe, 0xcf922df7, 0x472bd3b7, 0xf25c1e50, 0x2cb9f9ab,
- 0xcc79472f, 0xba61e437, 0x7028f7f1, 0xfda1dfff, 0x82fefe27, 0x04546fb1,
- 0xc8438f03, 0x838390d3, 0xc77144f4, 0xf4327a83, 0x9f2c305c, 0x0e5c295d,
- 0x52417d0a, 0xc8d5dec8, 0x6ff7135e, 0x01bfefec, 0x8f1a3ec3, 0x00003430
+ 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, 0x277bff00, 0xa3f0c0cd, 0xa5fd811e, 0x79ba1818,
- 0x8968c550, 0x30327137, 0x303170b0, 0x06710268, 0x2036ded0, 0x17c40edd,
- 0x1022f880, 0x3033719b, 0x11710214, 0xf2032f10, 0x56dcd093, 0x50c0c4c1,
- 0x4035c405, 0x3ac4075c, 0xba0c0c8c, 0x1fdbc48c, 0xf0c0c42f, 0xd7c10c42,
- 0x48606710, 0xff9fa491, 0x54ee1b07, 0xc27dafa1, 0x860c0caa, 0x4662a8ba,
- 0x5d637c68, 0xa09866fc, 0xf1a29bc9, 0x17e8f0cd, 0x87e540b4, 0xe3f2a219,
- 0x7618198c, 0x3709a922, 0x7416efc4, 0xf7a802fc, 0x00031025, 0x22037beb,
- 0x00000368
+ 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, 0x73b9f8b9, 0xc999dee7,
- 0xac84992c, 0x5d86f12c, 0x48409c04, 0x5876c443, 0x0622b4a4, 0x30a20a97,
- 0x9037d96c, 0xff69f0fa, 0xa5ab0819, 0x68d06a1a, 0x68304ec1, 0x1a0741b0,
- 0x01c04830, 0x6a2be2d4, 0x6d8ad3ec, 0x2c3480c5, 0x0dc46486, 0x3ff2d3de,
- 0xcdce77df, 0x11337bdc, 0xbffbfb6c, 0x4f169fe5, 0xb7fb3dce, 0xe77cef9d,
- 0x92cc5f3b, 0x407e1240, 0xa1f865c8, 0x211318e9, 0x5d245c64, 0x88fdfd6c,
- 0xe5227d53, 0xacc8957f, 0x465a48e0, 0x46dbe42a, 0xb213be45, 0xb16feb12,
- 0x589346b9, 0xc402d348, 0x93df3f45, 0x84592268, 0xf826e7dc, 0x9bce25b3,
- 0x12126426, 0x6f7168de, 0x25dfa74d, 0xd02425c5, 0xb720fd74, 0x4a76805f,
- 0xebc3e412, 0x9a56f725, 0x165f5f27, 0xcad9bda1, 0x27e813da, 0xf87c9089,
- 0xd221107d, 0xe8f89145, 0x024ba4fc, 0x32245ba6, 0x4fce972f, 0x2646df72,
- 0x73f3223a, 0x9392e427, 0x994efbf4, 0x52efd396, 0x37d5ae42, 0x2d7e5232,
- 0xe4fe7011, 0x5fec4aeb, 0xfbb56f1d, 0xd717ab36, 0xdfb517eb, 0x5c17dcbb,
- 0xcb757df0, 0x2d0fd8ed, 0xc39675c1, 0x9e5a14fc, 0xa6265270, 0x3811ff48,
- 0x351c7005, 0x71d0b4af, 0xf08847bf, 0x84ed37ca, 0xb76abbae, 0x5c2858a4,
- 0x4296ef26, 0xd2f9a03f, 0x7900213a, 0x211b01d3, 0x9b9d6e14, 0x94e43e59,
- 0x7cff50bd, 0x2ed3cd3d, 0x8fad2dca, 0xdd7000dc, 0x38ad922d, 0xe609ae4c,
- 0xadc2aedb, 0x6cf3e599, 0x775a5b2c, 0x2fb42e70, 0x1b10b668, 0x6f74afed,
- 0x681b8cfe, 0x4488ff3e, 0xb6e94aa0, 0x9a5f7215, 0x41080c2f, 0x224d77c8,
- 0x8f7fbe38, 0xeb46d818, 0x935ab977, 0x3c70a4ee, 0xca256957, 0x676f3a30,
- 0x141dd26b, 0x9d81450e, 0x515da153, 0x1201e0a3, 0xdb7bbc9a, 0x5db4a9eb,
- 0x63c176e9, 0x6e2970a1, 0x386513b0, 0xfa65c39b, 0x0c49bdaf, 0x2f9680fd,
- 0xe924eba5, 0xa9ead780, 0x37f18444, 0x02338aca, 0xc39573a7, 0xe4896289,
- 0x71d3b74b, 0x17b2bb68, 0xb12c0f04, 0x407c44cc, 0x6d7b9d97, 0xc0719eb3,
- 0x43c856fa, 0xb5aeb09d, 0x0fcbd432, 0x5363dfcc, 0xf2757e60, 0xb45e5a54,
- 0xd3ce4eb9, 0xe1b8bfe0, 0x3558a23a, 0x941daaf3, 0x630fa5ac, 0x89928e7a,
- 0x84453e76, 0x200e8378, 0x533c8083, 0x857d17c3, 0x7177c438, 0x9feba883,
- 0x44909242, 0xe8f7dffa, 0xfe5e14af, 0xab844efd, 0x9ca5b78a, 0x5dbc548e,
- 0xcc43fce0, 0xff6d2ce1, 0xe008fa6a, 0xbaa7ce81, 0x2fe98dd2, 0xad30532b,
- 0x3f1054a9, 0x68fc038f, 0xdbcf81ba, 0x344c8135, 0x5e5d71d3, 0x8b3606e2,
- 0x289dee9f, 0x2e7c7cd1, 0xe3dd27cb, 0x596f9413, 0x2e3e9abf, 0x4f03e6f9,
- 0xbd53226e, 0x979a54e6, 0x87884b7d, 0xd5be6f8e, 0x213c653b, 0xa3df12af,
- 0xe4d17eb0, 0x12bc002b, 0xa5c94c12, 0x50235978, 0xb5e14239, 0xe1491616,
- 0xd29526b0, 0xe3d3c533, 0x233d66f7, 0x09ad7c0a, 0xf67bcf90, 0xa7ec74e1,
- 0x6991fb16, 0xdcae833f, 0x6cdcd24f, 0x73493f5d, 0xea7ed40b, 0xab989fb0,
- 0xb9f1e7eb, 0xccf9fa39, 0x79fb522d, 0xae89ea1e, 0xd2575bab, 0xf9fa09bc,
- 0x7ec12bcc, 0x10f1ef92, 0xaa2fad1f, 0xbd5a43f4, 0x34772d22, 0x98798dc6,
- 0xd268e968, 0x49cfe81e, 0x474b4ab9, 0x3a31d9b1, 0xc6f38a7e, 0xa67df2eb,
- 0x4fd5d5f5, 0x2ba81dcc, 0xc2359e4f, 0x770e9740, 0x0f3c75fb, 0x91597293,
- 0x32bee5ef, 0x7d899dca, 0xfbff38ad, 0xee503afb, 0x1be39fdc, 0x86f3a6e6,
- 0xff8a12b9, 0xf5df65fb, 0x437428ee, 0x149025d7, 0xa4131548, 0x12b5f2c6,
- 0x7ea4db83, 0x413d0f5f, 0xc29b97db, 0xfe68e343, 0x8ff13088, 0x80bfeeb0,
- 0x8b78a530, 0xd4054911, 0x9410b18b, 0xb3d36b7f, 0xe06bf19e, 0xa5006eba,
- 0xefd22117, 0x0297c93a, 0xafe6d8f4, 0xae7d03f0, 0x60532019, 0x54827212,
- 0x6983fc84, 0x297901fb, 0x4c8b7f00, 0x7c7687e5, 0x123f8e99, 0xf1876fc7,
- 0xdf197a3b, 0x375b3032, 0x40ad35be, 0xa655be37, 0x08fe53e3, 0xf1f397fb,
- 0x0872fc29, 0xc72c94f9, 0x05692df1, 0x995afe38, 0x8fc6e814, 0x4bff1ee9,
- 0x186bf718, 0xfaca313f, 0xd7e8e607, 0x5fa4569f, 0x4fd6ccbf, 0xf8f9f856,
- 0x417eb831, 0xa7f5b3f0, 0x5bf5b115, 0xe3ddbf58, 0x2fe1babb, 0x875c740b,
- 0x07facbd0, 0xffafd04d, 0xfafd129a, 0xf77c6c2d, 0x7c7c758a, 0x271f8e07,
- 0xbfeb63ac, 0x97c704a6, 0xd00f3e2d, 0xa62fdc91, 0x69fb0022, 0xc940ca7f,
- 0x98bd0328, 0x84278f0e, 0x93df93ca, 0xfb870881, 0x7ddd1863, 0xcde94319,
- 0x24a79111, 0xee903940, 0xa69c65c3, 0xca271b8b, 0xe3f67f6c, 0x4f98bebe,
- 0x88b35175, 0x2c6a4d74, 0xbe742181, 0x1fa2cd9d, 0x6e6a8bf2, 0x9fb8880c,
- 0x98823d32, 0xffbe0849, 0xada8d375, 0xd31975da, 0x7b52d5c5, 0xbaaf869b,
- 0x3224fbe5, 0xafce82bc, 0x5c608802, 0xe54edf24, 0xf872a134, 0x90c79524,
- 0x5e98969e, 0x71ca8a72, 0x37cb4c32, 0xe25e982b, 0xa70eef27, 0x9f09fff3,
- 0xc199bb7f, 0x10997dbb, 0xb97ff800, 0xf20c8971, 0x9db5716c, 0x8f323d02,
- 0xf0a78e72, 0xf5004b5e, 0x001dba29, 0x5642ee7c, 0x03c3e424, 0x502ebcb7,
- 0xb6bf2d3d, 0x3dddae8f, 0x853ab024, 0x61b85fd6, 0x5d3700fe, 0x96599cff,
- 0x4fec2231, 0x84cfdbc4, 0x99fa4c7c, 0xd59909b2, 0x47ea51b4, 0x92cd7733,
- 0xda69b64e, 0xf3e9f6cf, 0xf9f40a73, 0x9920294e, 0x14299f40, 0xf7ed1d48,
- 0xb97d0ade, 0x2134ce3a, 0x8f95e19e, 0x830a13f7, 0x5ee9fa54, 0x67c0c748,
- 0xae75e237, 0xe755b59b, 0x44a0fe53, 0xb71fb842, 0x7fc41225, 0xb9f3d622,
- 0xf38dbad9, 0xbd592b9d, 0x733e74b9, 0x9e11101f, 0x1db7f9c6, 0xa34d7bb0,
- 0x99fb5a69, 0x5c682404, 0xf3fe718f, 0xe3d71b96, 0x987f6196, 0x677e37ef,
- 0xa7a46274, 0x8f89e6f2, 0x53d0d29d, 0x8f47f069, 0x2bb4d29d, 0xcba9986e,
- 0xeb660617, 0xced7e7ea, 0xae2f95d7, 0x2f95d42e, 0x9744b75c, 0x407fef9f,
- 0xf2de7f57, 0x7bf2ba15, 0xcaebd62b, 0xd46c14e7, 0x9efb67e5, 0x6bbfd5d4,
- 0x5cae9d56, 0x4d785038, 0xdf55ca1b, 0xb7a0a935, 0x4021607e, 0xabbd2a8f,
- 0xea8670fc, 0xa39e902d, 0x2ba40b7a, 0xff294f80, 0xb4b2f69b, 0x6bfceb7c,
- 0xfebd1adc, 0x069154b4, 0x7ba464fc, 0xf48d3c23, 0x45fa7f4d, 0xb4d487db,
- 0x20b92044, 0x7ef8bae7, 0x5ebf7eae, 0x647a7130, 0x7e129de7, 0x95d9289e,
- 0x3bce093a, 0x68687225, 0x7ef7a385, 0x75c05049, 0x13d2d010, 0x5a946f01,
- 0x6e2b7035, 0x679ba418, 0xc71141c7, 0xa5de032f, 0xe4832ff2, 0x0f200b36,
- 0x6ed38742, 0xf1f3051f, 0x4cf905ee, 0xff71139a, 0xf69ca8ed, 0xe00929d8,
- 0x99e98b97, 0xb69859ca, 0x3d30fa57, 0xe9805955, 0x4c0acac9, 0x63972adb,
- 0x8fd2bc7a, 0xd72a5fe9, 0xcaa7fa61, 0x558f4c6a, 0xc7fa62d6, 0x9da600ca,
- 0x554c5e95, 0x9396edba, 0xe56f5cb9, 0x81fa0be7, 0x2d7cade9, 0x15bdfd22,
- 0x0293d1f9, 0xf1c178fc, 0xcbd050e5, 0x48a31c2f, 0x5e1def4e, 0x15e87a46,
- 0x7a8bc4ae, 0xe2805e45, 0x72cf4fb9, 0x93c30c5b, 0x11a644cd, 0x0fd6372a,
- 0x60b3d679, 0x24cde624, 0x3c07da1e, 0xfa519d33, 0xe0147ba5, 0x22784aeb,
- 0x3868f0de, 0xf53fb70f, 0xefd0599f, 0xb640c2f5, 0x71161e5f, 0x67a124bf,
- 0xefaf803c, 0x95e1370a, 0x6f80d30f, 0xf0aa27ce, 0x34234d6b, 0xb1b8225d,
- 0x164d0bff, 0xb6380662, 0x847003d8, 0x19e470bd, 0x4b77ec17, 0x53eac453,
- 0x57877b63, 0xdabd3069, 0x794f59a1, 0xa17f3eb3, 0xcec6985a, 0x1dec4af9,
- 0xdcae80a3, 0x0086a7d5, 0x553053fe, 0x229a59fb, 0xb9ea38e3, 0x21c63496,
- 0x2173d29d, 0xcf67fbd6, 0x227eb7a3, 0x1f2268f3, 0xbb01d853, 0xe5741e5c,
- 0x7c0f4bf3, 0x73973f9b, 0xd22d4f01, 0xc79fb097, 0x07977fd0, 0xcc66bf42,
- 0x0796fdab, 0x7ae5bf45, 0x1ba8def8, 0xd453b68f, 0xebb43733, 0xa4cd5e9d,
- 0x15275d5d, 0xdedc196d, 0xab60dc52, 0x38fdcbd6, 0x39bcbe5d, 0x0fb75ab5,
- 0xef942fc0, 0x06608149, 0x54e129ba, 0xac7665d4, 0x1cfce813, 0x2dfb0526,
- 0x52bd5817, 0x53ec9b6b, 0x415b0c90, 0xad90580f, 0xd7729dd2, 0x3e5ca99f,
- 0x3c897bfb, 0xeedce50c, 0x2547f6a2, 0xfcd13130, 0xd05b9e42, 0xe41d3c54,
- 0x373dd9dd, 0x88b0fea3, 0x10e0bae4, 0xb3aa4053, 0x4f390f40, 0xee80d34c,
- 0xb83f93cf, 0x03ce6ac6, 0xce324c73, 0xfd3ae167, 0x27f5483e, 0x56bf3e5d,
- 0xb723cf9f, 0xe79d0125, 0x202448d5, 0xcbea3f00, 0x7e31366f, 0x6b1527c8,
- 0xc5587f60, 0xdc0b13cf, 0xf28fdcc4, 0x5b4be97b, 0x79d3e6b2, 0xf931302c,
- 0x0bdf9ead, 0x511e99e3, 0xc193ac14, 0xd371f39e, 0x40dc9fd8, 0x0d607da0,
- 0xbbfc31d8, 0xa536cf05, 0xebbefe27, 0x55f38dfc, 0x761e8ff7, 0xd28f3e04,
- 0x881bc106, 0x98548fb2, 0xf8ffbe04, 0xeb097e99, 0x1b99e8d6, 0x435af90c,
- 0xff90debe, 0x812de9bb, 0x61cde8e8, 0x25306df2, 0xfd02fa32, 0x6587304a,
- 0x7fd23fdf, 0x6bfe8f4a, 0xf7fda9ff, 0xe967fda7, 0xa7ffaffa, 0xc7b83ff6,
- 0xfad183fc, 0xc7697d2f, 0x37953f1e, 0x726e2f45, 0x9cffba11, 0x79275735,
- 0xb64bfe28, 0xe2fb46ad, 0x05dfb319, 0x20367cf4, 0x39440b4e, 0x71369f57,
- 0x3af125bb, 0xc0f73804, 0x73ffb4af, 0x067cffcf, 0xdcbe5b9c, 0x3cf1b926,
- 0x590960d3, 0x35969f28, 0xa3274e15, 0xe5827f31, 0x422a7ed7, 0x9f4f59be,
- 0x4a6dcf45, 0xa51bfb02, 0x87efae14, 0xab2a5f50, 0xd854ebff, 0x1849ca7f,
- 0x0ed8ccf9, 0x8f18bfc6, 0x1cbe71f2, 0xce9cb3db, 0x72f0f513, 0xa6f2970e,
- 0xba2a7f9f, 0x69d1fd20, 0x369317b4, 0xed8d93d4, 0x73feb80a, 0x684ce4cc,
- 0xf91eaaa7, 0xc81ef91e, 0x242e154d, 0xf11ff4c0, 0xe1a32da5, 0xff51dafc,
- 0x81a0977b, 0x176fca97, 0xfd7f0b82, 0x5cbbd2b2, 0xb1e7e4ee, 0xb600bb48,
- 0xdeb99a53, 0x12d2c2d6, 0x7b02e429, 0xe49d4969, 0x25cfd3f1, 0xf6799e3b,
- 0x7e4f3829, 0xa10cf160, 0x78ef17fd, 0x34398fed, 0x4a53bc5f, 0x4049ce98,
- 0xa7e08a48, 0x3e5bfe9c, 0xa28f8226, 0x2b26bedf, 0x87f7d8a3, 0x297823e2,
- 0x265079de, 0x63c27aa3, 0xdca0f072, 0x9f8288e6, 0xa0a989e0, 0x7d2f895f,
- 0xcffe0323, 0x7248101e, 0xd678147a, 0x027a86bd, 0xc9f109c0, 0x3f8dd5f1,
- 0x8a72fd43, 0x46eb9017, 0xedeb197c, 0xfa05f2e5, 0xa521fb05, 0x065e17ef,
- 0x2c9ff33b, 0xc143801e, 0x60b9f70b, 0x15cda73d, 0xacb7ce8c, 0xf1d2f24e,
- 0x927f240b, 0xbdf6531b, 0x229fe9e0, 0xf3bfe5fd, 0x7e7624d3, 0x709aa6f3,
- 0xc2a7f2af, 0xbe6f173a, 0x4799d713, 0x0587487c, 0x905cc45b, 0xc9985f97,
- 0xf8519db4, 0xe4c89e64, 0x14ade9e6, 0xa79d74b9, 0x768436e9, 0x81883fd7,
- 0x58bf686d, 0xfc1e4042, 0x9397b554, 0xc2ff98a5, 0x4e35f0ca, 0xaa7ef554,
- 0xb7e969f5, 0xe02b6d7e, 0x6f00dce9, 0xcabdd832, 0xe1cfd989, 0xfda65c21,
- 0x94dcef8a, 0x1444f0cc, 0x476f1673, 0xf0c982f5, 0x4ab7ea1d, 0x5d68db5e,
- 0x3d39723b, 0x3e32fe32, 0x0c779d3e, 0x93a7e7ec, 0xca304148, 0xaa8836fa,
- 0xbafba01c, 0xfc34ce86, 0x7ebff8ce, 0x9577e33d, 0xa73303ff, 0xefe7f941,
- 0x76823e32, 0x79d25fb0, 0xfcb19285, 0xca021de0, 0x45090b07, 0x897af3e3,
- 0xdcbeb9f3, 0xfe742f48, 0x43562166, 0x3c4e3037, 0x5eed01e2, 0xbdb43579,
- 0xb8c2ae56, 0xaafd9eae, 0xe5cf9c7c, 0x9522ddc1, 0xe445d707, 0xe4ccd901,
- 0x977aef40, 0x2258f11f, 0x0a7d9e05, 0xabf297f8, 0x95fe015f, 0x9ffd6172,
- 0xe3fe1e34, 0x3e6f94dd, 0xab7caa09, 0xbe46ab97, 0x2e35d82d, 0xb27edf2a,
- 0xdf3a2321, 0xf951efd2, 0xdbe30376, 0x5572d7ff, 0xa8956385, 0x9caaab97,
- 0x469e0dec, 0x2a269939, 0x9ca35708, 0x92ef3fa4, 0xa8f49eac, 0x7f4aa1d2,
- 0xbd29bf45, 0x3751e406, 0xd874aa9d, 0x1d2aa74d, 0xe89fb0f6, 0xbf2c68e0,
- 0xd2826819, 0xf7deee4b, 0x78a3f6a6, 0xf761692d, 0xebddb450, 0xf2f0a790,
- 0xaa4736e2, 0xa097ef5f, 0xf90c07cd, 0xd7bea1a0, 0xd435cf90, 0x15f219f7,
- 0x6601fa86, 0x2c3e683f, 0x9087a413, 0x92b4beae, 0xb7609df8, 0xdda22fdb,
- 0x79ce8bae, 0xd5df6d0d, 0x53f01e98, 0xc6dab0f9, 0x44e18fce, 0xb3c80d79,
- 0x15d8772e, 0xd31b790f, 0xc372bb7b, 0xfe8d38ae, 0x4445a278, 0x2016dc79,
- 0x8cf6b4d3, 0x21545f08, 0x6f48dafe, 0xd90ecce5, 0x77eec315, 0x691d126f,
- 0x59dce1cb, 0x19287a2d, 0xee2b4590, 0xba898172, 0xadd065ab, 0xc5f7e8b3,
- 0x5aec886f, 0xa735efc4, 0x670dce6a, 0x09f1ff88, 0x6d97dc02, 0x6c2ffc40,
- 0x4588e761, 0x73d3a21b, 0xe7976f11, 0xdc832658, 0x49fffaa4, 0xed559dad,
- 0xe1b360a7, 0x9ccdcb7b, 0x3cf1abee, 0x2faf5457, 0xd0f3f1f7, 0x647e5549,
- 0x1f940c90, 0xf381d070, 0x37bb9738, 0x9d6f2389, 0x75d0f145, 0x37402444,
- 0xc4445a17, 0x764685c3, 0x89fc495f, 0x24653fc8, 0x854ef28c, 0xc7f00757,
- 0x50e5deb0, 0xb30feec7, 0x4a55a41e, 0xf479fcf6, 0xb1da68af, 0xfba183e7,
- 0xfbd2ff20, 0x3d267f69, 0x603e4feb, 0xd76e3b43, 0xbbde2701, 0x337fed74,
- 0xefc841ed, 0xbef078b5, 0xa357c0f9, 0x56ba8e81, 0x8e400a5a, 0xf7600d75,
- 0xbffb55f4, 0xfb86dd1a, 0x9fc42ae7, 0x5fceccd3, 0xf3fe5a17, 0x5fb3dc38,
- 0x02aba168, 0x1d80e0fd, 0x2fe5e1ed, 0xd08ed0db, 0x2cabffb5, 0xb79fe39f,
- 0xbf7e329e, 0xb324e5d2, 0xe2fcc176, 0x7cba5d98, 0x5667f8df, 0xd373fdc0,
- 0x2d217941, 0x37cafc9f, 0x763e41a3, 0x4f7a62ed, 0x34f6d4a7, 0xaca41fdc,
- 0xa242b4ba, 0xe604ee70, 0xf94f4be8, 0xf92672ab, 0xcb834647, 0xb91f6837,
- 0xff5c785a, 0x021e063f, 0xb49623de, 0x01560338, 0xf8e97dd6, 0x1c1e419f,
- 0xaa5d20b0, 0xb824fdeb, 0x2b91f502, 0xac067bad, 0xd37ff13b, 0xd5d085ba,
- 0xbff4bbac, 0xe33fbe39, 0x0f91a8fb, 0xfef9d27a, 0xc3bf31fb, 0x5ef9c1e9,
- 0xe2ffbd25, 0x77de1b7f, 0xaebbbc51, 0xffc6eebc, 0x1deeebe6, 0xe5cc6fef,
- 0xfdc37778, 0xdf2bf97b, 0xabbefce0, 0x3ffa3b9c, 0xbeaafd74, 0xf2933bfe,
- 0x3fad066e, 0x403b548d, 0xe951f8b1, 0x683237a1, 0x1ffaefe9, 0x4ef9838e,
- 0xc635f7e2, 0x66637df9, 0x7049bee7, 0x25c7436f, 0xef3f0271, 0x3f5273b1,
- 0x5bf45fae, 0x487a8796, 0x40bffebf, 0x9598827d, 0xfc0fb81a, 0x0f42da5d,
- 0x319036fa, 0x77907cc7, 0xfaf3c8df, 0x04afe2f3, 0xcaab85e2, 0x1f37697e,
- 0x7fb53d01, 0x58f5117f, 0xfafea29a, 0xfb1a6baa, 0xceeb225e, 0xf4523f33,
- 0x09a99be7, 0x14d073fa, 0x844ddfde, 0x8726ffcd, 0x38500810, 0x58f01a4c,
- 0x2743d802, 0x4088910d, 0x6f8953f3, 0xa61b9c15, 0x7dfdf438, 0xe3c4f700,
- 0xb7cc7022, 0x7f022dee, 0xc047ab3e, 0x987586fe, 0x33589e50, 0xe183a405,
- 0xbfcc66b5, 0x038f7263, 0xe1b8cf38, 0x201e4fa5, 0xcaf55760, 0x65cba14c,
- 0x2faff1f6, 0x05909e5f, 0x03f66fe7, 0x50b778fe, 0x66d17d7d, 0xeba18a12,
- 0xfe266c5d, 0x8bb078d8, 0xcea4e40a, 0xc3cfaa2e, 0x2293f7cf, 0x7ea95cfd,
- 0xcff8746f, 0x74a25f4e, 0x2108727f, 0xfbc5217b, 0x53cf662e, 0x6bdf57cf,
- 0x3f2af061, 0xd903024a, 0xab98b8bd, 0x2c5a3fb9, 0xe97bba31, 0xc2c6bb2f,
- 0xd76266b9, 0x8fc658c8, 0x904fcc99, 0x881797eb, 0x0071eb12, 0xc58a0e3f,
- 0xa223b17b, 0xd9df9a33, 0xfade7e76, 0xd297dc0d, 0x549eabb4, 0x93f7a08b,
- 0xfcf9da30, 0x2db256f5, 0xae427f8a, 0x382ddaa4, 0x988fe8de, 0x367af605,
- 0x34da62fe, 0x8eb78b56, 0xa3cd67e9, 0x7e01e27b, 0x2bee6a4e, 0xc2f851fe,
- 0xbbe00ef9, 0x3536d6dd, 0x2edf0a37, 0x633d9890, 0x784ba1c6, 0x52d11ebe,
- 0x1f3e0267, 0xddd26f51, 0x712dddbb, 0x190c7dfd, 0x719af303, 0x04cce6c8,
- 0x3d111cbc, 0xde57efe0, 0x8beca9f2, 0x84646f72, 0xf60ff427, 0x8dc95ad6,
- 0x8293eee3, 0xfbae010b, 0x9c095bce, 0xd5caf6b7, 0xe9e6d1c5, 0x2e79b0b0,
- 0x46fbc126, 0x83f7ffa7, 0x472ec4ef, 0x579c1268, 0x75f209ea, 0x4823fa4f,
- 0x481a17c7, 0x9c31e400, 0x5c2e406f, 0x1fb82468, 0x02fc9050, 0xdf946bce,
- 0xc73da07f, 0xf9de6b0f, 0xca47d81b, 0x9837045a, 0x6dcccba0, 0xcaedd832,
- 0x9044e39b, 0xea8a19db, 0x751ee90f, 0x6a2f8687, 0xebc23325, 0x39bece70,
- 0x1d67ee30, 0xcd7d8132, 0x05d86afb, 0x96b3ff72, 0xbd07c8b1, 0x95b7ebad,
- 0x048a68a4, 0x6ba410fd, 0x6c8c3d23, 0x6fe5d18c, 0x817d7d10, 0xda5866bf,
- 0xe0a27996, 0x7c66472f, 0x2df2d57a, 0x7c99fff0, 0x6f95577b, 0xc357313e,
- 0xd1992647, 0x25be46bd, 0x4b6f9347, 0xe0192505, 0xa0ff74be, 0xd2ebc064,
- 0x68c4a437, 0x25476df2, 0x917b07bb, 0x3576b1fb, 0xbd76f951, 0x5135be46,
- 0x4fc516f9, 0xf13243a0, 0xf20aedfd, 0xc35ff02d, 0xbe403b7f, 0xbe67a345,
- 0x6df2a83f, 0x9409cb74, 0x4c9ba36f, 0x2fccff3a, 0x84df28af, 0x9f403bc4,
- 0xec79223a, 0x0767e851, 0xe45edfd7, 0x0e30367e, 0xb271b9c8, 0x5abfc71b,
- 0xb5729739, 0x08bfee72, 0x5b9caace, 0x9fa09bba, 0x643a4f6a, 0x5ee96e72,
- 0xa004e72a, 0x96e72647, 0x8ecc27ee, 0xc36f9063, 0x8237c87b, 0xac42cbf5,
- 0xfa73797d, 0xfed0f713, 0x8f2578c6, 0x131fd695, 0xb4e37791, 0x6c9c6ef2,
- 0x90f73846, 0x4eae4777, 0xf2e6edde, 0x81b1ca8e, 0xf48d5f20, 0xfbd169e1,
- 0x7f1beeff, 0xc0b7f1ba, 0x788a6f2f, 0x898ef50f, 0x35bc17dd, 0xd02674fe,
- 0xc99906d7, 0x7b971f5f, 0xec7e959d, 0x6cabf27f, 0xec8da57d, 0x1359413d,
- 0xeacb0fd3, 0x7f4280c5, 0x09739a9d, 0xf70a93ef, 0xe699240b, 0x1faa5a67,
- 0xfd3e8077, 0x3eb8449c, 0x43433d3d, 0x8bb28b0f, 0x655bced1, 0x94256d73,
- 0x8999178f, 0xc5b9ec15, 0x4167a98e, 0x66ce2d9f, 0xfe62dff6, 0x544bf55d,
- 0xf78d33fd, 0x4bcd79e9, 0x7a47ef5e, 0xb0cfabde, 0x78cebc30, 0x1f800846,
- 0xf67bcf61, 0xe285ca00, 0x15f7fd06, 0xc533fd7c, 0x79178436, 0x8b6cf45b,
- 0x8c2b3fc2, 0xe1c23a70, 0x83a2e144, 0x0a884053, 0xe9e98a27, 0xb8114919,
- 0xb6d9be14, 0x85c0ec06, 0x6f780a4f, 0x0ab75c68, 0x55fae337, 0xd176aa38,
- 0x7e5fde62, 0x33be1d4b, 0x8545c231, 0xdd1e11b3, 0xa3c03770, 0xfff6e64a,
- 0xfc16320c, 0xa0dd2858, 0x9bfff19c, 0xb90ffe88, 0xdee88713, 0xf2e7ac43,
- 0xc4f56c7f, 0x3ddd70c9, 0xe182fc13, 0xc976ae3e, 0x37dfe0eb, 0x063298ee,
- 0x721bd3b6, 0x97b83e2c, 0xa30b6edb, 0xf0e9541c, 0xcd874e23, 0xfafbbe1c,
- 0x73c24c56, 0x06e0b361, 0x643ca43d, 0x5396b843, 0x2ad1b47a, 0x72fc9f87,
- 0x1bab872a, 0xf334bbdf, 0xc1e289fd, 0x751fe704, 0xf7b00abf, 0x185b6331,
- 0x181bca5e, 0x1849325e, 0xb565efed, 0xd7442782, 0x04bcd653, 0xf95582fd,
- 0x5a1c7f4c, 0x5fa1453c, 0x25fa3473, 0x8acc9c60, 0xbcc59bec, 0xf54b0cde,
- 0x3f9ec11f, 0x1d47f283, 0xdffd2192, 0x95f7d0b7, 0xf88c45fc, 0x6dc390fa,
- 0x01d5c007, 0xfd330bf0, 0xdf09742b, 0xe5e5a8cd, 0xae0ebf66, 0xc8ba9f93,
- 0xa0bf6fe8, 0x1ba51d80, 0xb4cf406e, 0x370a9c7c, 0x43c067a0, 0xf2117ccb,
- 0x7dde1479, 0x17ae7bd2, 0x7cb4c7ee, 0x04ffb85f, 0xe08b7feb, 0xfdd65121,
- 0x3bfbe99d, 0xfc6f75d2, 0xbe8191fe, 0x8f85b2df, 0xdefa058e, 0x93df202f,
- 0x3dfd3896, 0x4dcecc97, 0x0f946ddb, 0x0de61ee0, 0xe955b3c9, 0x1cc21f29,
- 0x509e70ce, 0x6b927634, 0x57e02161, 0xff4560d8, 0x40c79c30, 0xe56aafa6,
- 0x491b0ef5, 0xf7b323bc, 0xf9c6fffe, 0x497d37ac, 0xf1828fcd, 0xd3368e40,
- 0xc64786f1, 0xaa17ee33, 0xeb4ae01d, 0xb1fe5bb2, 0x7ce3a975, 0x7299ff57,
- 0x28f78ad2, 0xc38d1faa, 0xe0942be4, 0x304d3afc, 0xc2d1fdeb, 0x70ffcf1c,
- 0x2dfcb2ff, 0xab1493fd, 0x4de2fdee, 0x29f883a2, 0x4af33edc, 0xcb542fc8,
- 0xec026f78, 0x3ee8931f, 0x8ecf9348, 0x1eff7b8e, 0x5ef1172c, 0xfb37d6e6,
- 0xd5bdc294, 0x8a67ccad, 0xa0219adc, 0x740ef0fe, 0x70f41e36, 0xf85af12b,
- 0xfb3cb490, 0x7801717b, 0x5f519067, 0x7ca1593d, 0x5021a63d, 0x7267a905,
- 0xc02de138, 0x009144d7, 0x7dbd5abe, 0x7bfec326, 0x06495fdf, 0x9ea8ce98,
- 0x398cfd80, 0x5ea11242, 0x8f11378e, 0x3e9be333, 0x3a76f77f, 0x4547f1bf,
- 0xcdeb428f, 0x0070ec3c, 0x6cdf0d9f, 0x5c0d3e22, 0x0aa04872, 0x4fe347ec,
- 0x79076f79, 0x1ef54050, 0x682ff7f0, 0x4172aba9, 0xed80b37e, 0xa9befdcb,
- 0x1dbf3a2e, 0xbd4e9fb5, 0xad02e40e, 0x6f94dd07, 0xebcaf566, 0xb2b80f05,
- 0x946cb5e6, 0x0bd46e51, 0x476ca0f8, 0xd6562040, 0xfb4ac06f, 0xb699b1dd,
- 0x8bfd84cf, 0xeb7e87b6, 0x76f77d3f, 0x9e743b90, 0xdd91bed8, 0x76d1e6cf,
- 0xfd49f00a, 0x70afec12, 0x5de040b3, 0xdb234142, 0x4a8e0a9f, 0x3a6f281e,
- 0xbbee24f8, 0xa978e9d3, 0x851fb0e9, 0x8efbe0a6, 0xdf1b82b1, 0x43494dd5,
- 0x0b05d5b9, 0x01d60686, 0xe05cbeec, 0x51fe7e79, 0x2d37bff5, 0xcf377fcc,
- 0x43ee42b3, 0x3b2b79fb, 0xf484dd31, 0xfa0ca9f4, 0x6f0a29da, 0x3bf7851f,
- 0x70e17fdc, 0x9b72c7f6, 0x673c7f66, 0xbff48419, 0xfa2279a8, 0xb9262d4b,
- 0x633faf78, 0xdf3bd33c, 0x0016d1be, 0x52dbddbb, 0x3f7c3fb8, 0xbf05a37c,
- 0x7260ee77, 0x1b4073b8, 0x6f4f69da, 0x47bc0896, 0xa22cdaa8, 0x28dd389c,
- 0xb8b5fde1, 0x9db94245, 0x21e983bf, 0x7eb33787, 0xfd30374f, 0x3b96f26d,
- 0x9c3ec2a7, 0xefbd4dbf, 0x3d5a7266, 0x0bb9e687, 0x519bfb75, 0xb872aace,
- 0xa0a3c394, 0x5fef0eba, 0x54b7728d, 0xf20d0fdd, 0x65ee14b6, 0x8435fef1,
- 0x341a547c, 0x983913fa, 0x0d73863c, 0x12e843d0, 0x51d977d2, 0x46b9c089,
- 0x2a63b8f8, 0xec2ce7ac, 0x7c7cb4f7, 0xfb85e08b, 0x966382f0, 0x81e3ea00,
- 0x15fef3f9, 0x2c0f99f6, 0xbfc05044, 0xca83e29d, 0xf84b6ca9, 0xefd18f2f,
- 0x82b1df67, 0x9fa508a7, 0xd57f08f9, 0x1b73342f, 0x7cc8f3f3, 0xde0926a7,
- 0x7d29927f, 0xd7e40e50, 0x91a7c48a, 0xef05671b, 0xfdb377ed, 0xfff5adc1,
- 0xf3ab94cc, 0x6fed9f60, 0xd951f265, 0xddfbe126, 0x447cfcc3, 0xb7e80bcf,
- 0x6377b859, 0x87a1ac92, 0x931bfdc2, 0x6b20e8a8, 0x15447fb8, 0x285bf77f,
- 0x0f0a71b3, 0xcd3aee08, 0x6a3f6a38, 0xd65ef2bf, 0x967ed06e, 0x217fd6f6,
- 0xf9d70fcc, 0xc3720c85, 0xf18f4fd8, 0xfb27e97b, 0xc0d62fdf, 0xb7eced3b,
- 0xce6e7445, 0x20fa78fe, 0x9a80bded, 0x590c7eaa, 0x57889aef, 0xbfecbf03,
- 0x06af10c4, 0x28e34ddf, 0xddfc53ff, 0xb9f4ccd2, 0xe42771a6, 0xbbcc4cd2,
- 0xb8cbdf81, 0x0a6cba3d, 0xca69efbb, 0xf0156778, 0x014cf4ff, 0x7df881e9,
- 0xd4049f72, 0x4ff014df, 0xed64cfce, 0xe07b69f3, 0x1927a6cb, 0xa179529f,
- 0xdb293c80, 0xd62a71bc, 0xe81417af, 0x3e6ea9bf, 0xd90525ea, 0xfaf2c122,
- 0x1527a813, 0x00489f34, 0x5bfca67e, 0xd940fa03, 0xc41b8b04, 0x2a97cab1,
- 0xfdcdbf9f, 0x3dd58989, 0xcbf8fc0a, 0xf0a2a980, 0x709478b7, 0x65f195bd,
- 0xdbe33679, 0xb04877b7, 0x73e1abc2, 0x8f956be4, 0xcce3e045, 0xde1f1f08,
- 0xbe06593c, 0xd0101d3e, 0xc83262ef, 0xedf3e001, 0x31efb702, 0xf96af63d,
- 0x667a4afc, 0xd85fe529, 0x573e552f, 0xcfc8daf9, 0x3bb6e6ad, 0xddf71e60,
- 0x4c75c368, 0x3fdefefe, 0x15e4c7de, 0xfe4dd7de, 0x204903fe, 0xccccf31f,
- 0x6b8547af, 0x81f999a9, 0xcd5798f5, 0x6af5390a, 0xc79867e6, 0x5ede8b46,
- 0xc712d872, 0x25eb9dfc, 0xf12bfba4, 0xbb3e0f67, 0x5abcfe4a, 0x7f12babe,
- 0xfb8be3aa, 0x061cfdf5, 0xd9eb8e20, 0x6385275f, 0x77f1c288, 0x5fa0cf8d,
- 0x4fe7f9d9, 0x143c00cc, 0x0e74a3ef, 0x24e8d5f4, 0xe6739021, 0x455bee00,
- 0xfd17a24d, 0xaca1cd65, 0x3e5a9ddb, 0xc53ffe66, 0x9e913a2f, 0x0259768a,
- 0xa2fb69d3, 0x468f1f3d, 0x61958c3f, 0x3ff24ff4, 0x7f65f5cf, 0x83e068db,
- 0x43f33322, 0x9985ca32, 0x773fa656, 0x82cfb5ec, 0x2c0d09f5, 0xf05140de,
- 0xb9a2c92e, 0x956698a7, 0x2f787ad4, 0x0c74a7e8, 0x7e6131ef, 0xaaee77da,
- 0x76c751ff, 0x9a8a2726, 0x2dc400a5, 0xd9d86a28, 0x45a5fe09, 0xff682cc7,
- 0x14f86f2a, 0xbf27e7fd, 0x2bed03b8, 0xeea2cde5, 0x3f87ad3e, 0xb218835f,
- 0x535a1f80, 0xd1ffde29, 0x07cc09fc, 0x77dcffb9, 0x7e2b37f4, 0x3f1eff71,
- 0x6ff16105, 0x7c81739f, 0xcdbad739, 0x0d7d7e85, 0xdb5feedf, 0xb82f7fc3,
- 0xddeffb9e, 0xb9e09a72, 0xdeffba26, 0x3285f839, 0xbd5683ca, 0xe8691eff,
- 0x9d25fa83, 0x946e5667, 0xfd6e8ffb, 0x4f17c77c, 0xc779ff83, 0x869e4fae,
- 0xedfc9779, 0xafc1a7b3, 0xe1b01c88, 0xfcfe57be, 0xabafe87b, 0x6564dbb6,
- 0xfdb9da74, 0xee77f439, 0x81e2c0fc, 0x9ff73ade, 0xb2ff034e, 0x92979dce,
- 0x6cb99ec0, 0xef684dff, 0x727bb65d, 0x6fb28932, 0x6fd029a8, 0xadfc2ae0,
- 0xdc3b788d, 0x9ffd1874, 0x83bc53ce, 0xcbf6ec1c, 0x7f32960c, 0x63fb8557,
- 0x6ff74636, 0xd97fe1ef, 0x37adfb74, 0x626ffc82, 0xfd15e4fa, 0xf8a5df30,
- 0xf02afebc, 0x6dfdc8d8, 0xab7cb783, 0xf879e61f, 0xc9abe285, 0x9a2fc780,
- 0x29faff16, 0xd3ea6b28, 0xe8661fab, 0xfaa7e02a, 0xdeadfbcf, 0x6fc0ac57,
- 0xfe837ebb, 0xe9bf80af, 0x5f47ec0a, 0x83fbc1a4, 0x2e785233, 0xfde13fec,
- 0x52bf8c16, 0xe47dffb4, 0xefddcea7, 0x709a9da0, 0xd24ef63f, 0x8dfcc3fd,
- 0x7adebe05, 0xe4dff327, 0x4eff0078, 0xb9df85c5, 0x6ba3271f, 0x37b3bfd5,
- 0xacafcebf, 0xfd56ff4c, 0xffeb4bfa, 0x2324fdcc, 0x01b21378, 0xf5be275f,
- 0x070a823d, 0x11cb9737, 0x7ee8e5bf, 0xcb7eddb4, 0x3e01bc06, 0xf6ea9f61,
- 0xfef9a64b, 0xf24ed063, 0xf83f347e, 0xefe63ace, 0xdfe929dc, 0xc4f0468f,
- 0x0d5823df, 0xab81cbfe, 0xd2be5ff3, 0x9c2bbe3a, 0x3452824e, 0x3abc27ae,
- 0xdf2e8ebe, 0x3fc26d13, 0x916d5ef6, 0x931f7c60, 0x7f044b60, 0xcf681390,
- 0xf37f3eec, 0xfb7076f5, 0x22f3c77b, 0x09aebffa, 0x6ef9461e, 0x10651f94,
- 0x7cca2347, 0xbe98d987, 0xf6ccd65e, 0xce5d8e8f, 0xd3f68380, 0xd22f6871,
- 0x09e35975, 0x7bfb4fd9, 0x32b7e1bd, 0x7c62c7bb, 0x4047fb04, 0x178e9eb3,
- 0x7e668e0e, 0x6fdeccda, 0x1f1c671c, 0xfa25bca7, 0x9f8de538, 0xf629c6ea,
- 0xe3b76507, 0x339de3ca, 0xfe82ef7b, 0x3d32b5ce, 0x9c505cf1, 0x587ded16,
- 0xf7e24d8a, 0xa52cd561, 0x25c628fb, 0x2438b271, 0xf5062ba2, 0xecce65ce,
- 0x9009b163, 0x5407e8ca, 0x0dfb82b5, 0x0293ccfd, 0xfe72aef8, 0x577cc098,
- 0xf6357c03, 0x23edc91f, 0x294aafa0, 0x776099b9, 0x391dca30, 0x1a0244c1,
- 0x4e732f7c, 0x5ef0564b, 0xf01fd424, 0xb4e33c79, 0x647efd04, 0x647d5fb0,
- 0xe9926b26, 0x0bf23efc, 0x5fb4159e, 0x03c7f5f2, 0xfb3d9d72, 0x87bef357,
- 0xa9bd9d44, 0x0e3e12cc, 0x8af215e7, 0xc423ef0d, 0xe78c3603, 0x0db4fe50,
- 0xf7787bd7, 0xdea2cf57, 0x610b6bfd, 0x54f443f7, 0xdca47103, 0xbbd38fac,
- 0x3ffa7abf, 0xc686af41, 0xa7fcfc74, 0x4f387d69, 0xfcf1da34, 0x762bb5d3,
- 0xafcfea34, 0xe403383c, 0xd19dbe5a, 0xc98bfe63, 0x5fda2a81, 0xb7cb227b,
- 0xf18018ef, 0x39778a03, 0xf0f11fd1, 0x60ca97ee, 0xd17cea9f, 0xa4066e0e,
- 0xffae15f3, 0x3bc786ff, 0xad1495aa, 0x3121725f, 0x2077da2b, 0xe56790c5,
- 0x7f049ef8, 0x811f38b2, 0x1639ab1d, 0xbd508fdf, 0x79cfd758, 0x07bf7c29,
- 0x97dfd8e9, 0xf5099bbd, 0xac607905, 0x1fff96a7, 0xe5b7931b, 0x11ceda16,
- 0x872e5fa9, 0xbabe58f3, 0xad27932f, 0x2ae7ff58, 0x9ef2f39d, 0xebfab2fd,
- 0xf575036d, 0x3c65f6d4, 0x7e9188de, 0x16fde71f, 0x2c337c37, 0x288d3c5a,
- 0x3fefc7f3, 0x04df8815, 0x1b4ecb7a, 0x778251c6, 0xbf0fe0f8, 0x5ff76647,
- 0xc610ae25, 0xe5c7d933, 0x084c4971, 0xe5f4abe3, 0x90fa80f3, 0x17b6d627,
- 0x2fa5ef00, 0xe7c408d9, 0xe9c57d29, 0xee977c05, 0x57fdaaf9, 0x66efe099,
- 0xe95ebb47, 0x7482ff2b, 0xcd096a50, 0x3b6578c5, 0x99e2042d, 0x237cec75,
- 0x43b5f80d, 0x7fc5a50a, 0x695ebdcb, 0x478862d0, 0x52efe7e0, 0x7de18303,
- 0xb33efabd, 0xd33917a8, 0xdef76365, 0xbdde6cfb, 0x7d77e436, 0x95739edc,
- 0xefb483cd, 0xe8948bb4, 0x9b4df172, 0x69d977f4, 0xa3b8e5bb, 0x37c73bc7,
- 0x49e73e61, 0x2018126b, 0x0e3ea8cb, 0x21a8bcf2, 0x0fd83fbd, 0x77d4d90e,
- 0xec2c4aec, 0x05248747, 0x0687d9cf, 0xfbb5fd28, 0xab4a99cc, 0xaed09662,
- 0xdd576983, 0x097d79a7, 0x66da27f8, 0x1f7b9345, 0x8f08ecd9, 0x1bc5ab22,
- 0x07649ded, 0x02deafdf, 0x1b224063, 0x1d43f817, 0x401490f7, 0x4628bc39,
- 0x0ff4fd61, 0xb8bdf0c8, 0x2d20ef61, 0xd5cd0a1c, 0x29f28f58, 0xd490b3c2,
- 0xf91a99c8, 0xb8578ead, 0xf198a1dc, 0x3ff9ba3d, 0x8c55e9ba, 0xc88d19e0,
- 0x7472789a, 0xb33b45c7, 0x2cc0eefa, 0x7e015ae5, 0x9b75c932, 0x6a952045,
- 0x1218f7e4, 0xd541d4c4, 0xaabf162e, 0x3c9c8082, 0x83471dd3, 0xd7811a60,
- 0xfdf72803, 0x92190803, 0x1286fa0e, 0xefc0d6eb, 0xf385cd92, 0x082b98b1,
- 0xddd31793, 0x7e0a7fa0, 0xe94cb91f, 0x61b2aaa9, 0x40f78b10, 0x0d7ef0bc,
- 0x3f3a5855, 0x4bf5fb97, 0xd5f907a0, 0x27df70b8, 0x620a2a81, 0xbb453370,
- 0xe2c224eb, 0x463bad99, 0xb48fe7b4, 0xffaf8118, 0x0731ca20, 0x6984fc89,
- 0xc82ac41e, 0xbfd8aadb, 0x9cfdc365, 0xa0424dc3, 0x241dda1f, 0x63a9a764,
- 0x969cf9a4, 0x34995dff, 0xf74ba1af, 0x91b97d04, 0x335ca82f, 0xf8441b8c,
- 0x373f7ed1, 0xa1b9fbf4, 0xadbfcfdf, 0xe54e155f, 0x10e941d6, 0x65756087,
- 0x8d8dc390, 0xa370e567, 0x710e19f0, 0xc62988d7, 0x11cdefc3, 0x367c31ae,
- 0xf14fa816, 0x1d26273a, 0xd8f3f4e1, 0xaff06103, 0x04b50925, 0x04abc3ce,
- 0xc922fe35, 0x11da6875, 0x70f915b7, 0x4e671f3d, 0xf577a30c, 0xfacf7c1d,
- 0xe8efbc36, 0x5bd6df51, 0xf5e898fd, 0xc7cdbd9d, 0xdf3e751e, 0xbd94ce55,
- 0x705bfef2, 0x6f2ddb5f, 0xfa9414dc, 0x6273db77, 0x71a5bf68, 0xc36b7fed,
- 0xb46f4c2f, 0x2fe3d7f6, 0xd295e806, 0xfd60cc4f, 0x7bde2377, 0x7cf997a3,
- 0x48ef341d, 0x9bbaeba5, 0x9ea53f8f, 0xb3df77dd, 0xe8e3d98c, 0xf50bcff1,
- 0x77faf0e7, 0xaed1f35b, 0x87e62270, 0x9ee12718, 0xde17a65a, 0xf78890f3,
- 0x08e23dab, 0x7f942fc1, 0x042e5dee, 0xe2d1e942, 0xe3779122, 0xf8f3ff68,
- 0x4338c6f8, 0x5d4ca23e, 0x338b4627, 0x7d4ce8c4, 0x5f8c6587, 0xf2e488b0,
- 0xeffa51f8, 0x933736ed, 0x5c80e687, 0x2fb2323d, 0x3a5237f9, 0xd2927d06,
- 0x8967dc31, 0x712d3dfc, 0xfabfccc9, 0x3c9d788e, 0xb128a0bb, 0xc536bfb8,
- 0x2e1be2eb, 0xc724af1d, 0xf9b5e469, 0xbf175da2, 0xa4f24aa5, 0x2e92bc80,
- 0xca14475e, 0x3ec5f257, 0x5394d144, 0x1999143d, 0xee5136dc, 0x200398a4,
- 0x5ceecce7, 0x6c7a0f92, 0xb54fa31c, 0xa2309cbe, 0x9b7c6f5b, 0x262c7bfe,
- 0xe96cf911, 0xc6192512, 0xeb73da09, 0xcae893e1, 0x3d1cf8f6, 0x83bfc1e9,
- 0xd60abbad, 0x3d73de9d, 0x83c7b255, 0x774e73fa, 0xcc2b1bbc, 0xef28b44f,
- 0xdfbf302b, 0x2aec044b, 0x39e3e13d, 0xbbf0a013, 0x7e87e810, 0xf4ec6221,
- 0xc3afe8a1, 0x1075e4f5, 0xf5ca91cf, 0xe3be3c55, 0xf1cf1e2a, 0x737f1e61,
- 0xa8f38f0d, 0xa9eacfc2, 0xd68238c6, 0xab7facc1, 0xc127e39b, 0x43e3e1c4,
- 0x529ac97d, 0x3684f781, 0xe2084577, 0x74fe9171, 0xbb69809f, 0xb27e11ab,
- 0x927da09b, 0x05bcc7d6, 0x6a9534f2, 0xcc1e2247, 0x4f920aee, 0xfbb61fcb,
- 0xd9b802de, 0x41bc7d14, 0xc340ca4b, 0x9e01b0bd, 0xc93d3d2a, 0xa70262e4,
- 0x127c2327, 0x53df1664, 0xf4dea3a5, 0xcfee2aaa, 0x83d2a9bb, 0x2b8f1569,
- 0x84710555, 0x8f294e20, 0xcfc89423, 0x8e145589, 0xbe09fdf0, 0x6655566f,
- 0x9da67963, 0xa60953ed, 0xc012838a, 0xbb309e25, 0xf49f8267, 0x55cc22cf,
- 0xfc527e14, 0x7abc8144, 0xe7c3588f, 0x7441e9cd, 0xe1710d9b, 0x2f002794,
- 0x26486f35, 0x9715e7b8, 0xd63e4cdf, 0xcb38b3d0, 0x3476071b, 0x6013e1d1,
- 0xe039fbff, 0x2367ce95, 0x59c6179d, 0x9ab0f4e5, 0xa72d7de3, 0xde3cf587,
- 0x5d382fe7, 0x0fd74a3c, 0x7b0f2af9, 0x1a61b037, 0xc84b8bf3, 0x68b8f130,
- 0x3bf5a221, 0x8904f38b, 0x3c89d74c, 0x718a60aa, 0x0b31c8ef, 0x247d8bd2,
- 0x7e508af1, 0x8b0081ec, 0x0a9b9963, 0x1a9c66fb, 0x128272b7, 0xb61f1b37,
- 0x3e3ccc86, 0x1dcec89c, 0x3de351ad, 0x590e7956, 0xdbdefce1, 0xdcce0e7c,
- 0xf6bc6043, 0xd20e8851, 0x7b3b97c7, 0x6a3bcd31, 0x7f4dfea9, 0xda5f1eec,
- 0x5ae7a06a, 0x373f010b, 0xbe7f9d07, 0xf7b1af46, 0xd9080762, 0xa9d8a47f,
- 0x45074b3c, 0x97f7e283, 0x006c83b5, 0x05730a67, 0xa49b1dec, 0x039054dc,
- 0xdba2e29b, 0x4cec626d, 0x8e65765f, 0x8d75d1d0, 0xee76c5e4, 0xf4746309,
- 0x4fe5c35f, 0xdd1c94fc, 0x7cde5577, 0x0bfac31e, 0x30997dda, 0x998ba4af,
- 0xb709bfc8, 0x553f9745, 0x3887ec92, 0x98a35500, 0x94cff3bc, 0x43d59e99,
- 0x7539309e, 0xf8f08c81, 0x86467435, 0xbf07d413, 0xe2eb299c, 0x3e03ae19,
- 0x63710619, 0x02affd19, 0x38a9a07e, 0x89fa4658, 0xf3c26e9f, 0x5fce1aea,
- 0xda7e730f, 0x11e9f9c0, 0xc40b23e0, 0x677c659f, 0xb0e19e26, 0x58b9549f,
- 0xfe012ddc, 0xc5549b4f, 0x7187982c, 0x04598f8e, 0x32a89fb8, 0x4317537b,
- 0x59e2d6be, 0xe31e60a9, 0xed6bfb01, 0xdf7f344a, 0x2ce27d90, 0x6cd7853b,
- 0x6ac7bf8e, 0xacfe22c7, 0xac014f6e, 0xc188eccb, 0x50d57df3, 0x73b4416b,
- 0xb33b74c2, 0x2f78508f, 0x4cfa7e84, 0x873ee9cb, 0x66a19981, 0xfdc21666,
- 0x1d077831, 0xedca7e85, 0xfd218f4c, 0x46b064fd, 0x38f0d40e, 0x93f14471,
- 0xb0791ae1, 0x0254c872, 0x729e9e76, 0xb83917a0, 0x2ac1c98d, 0x062fef81,
- 0xf8f156bc, 0x341caadb, 0xc4a35e03, 0x4d7d5ad7, 0xbe7deeb6, 0xb1b8e5c4,
- 0x3b3b3ade, 0x9e21ad37, 0x59e84fb0, 0x0eb4e14e, 0x3fd914e0, 0xa0e3ba73,
- 0x3aca20fd, 0x0ceff28c, 0x532083ec, 0x338c3ecc, 0x9e5648b2, 0xe5720f18,
- 0x4cbf98df, 0x3a827a6f, 0x42c5fe5e, 0x2ef267dc, 0xbffdc78e, 0x213c76a0,
- 0x2b02ae70, 0xf69de6bd, 0x753fcde9, 0xd74ede01, 0xcdd3fbf2, 0x57fc0052,
- 0x2eaed74e, 0x4db57cc3, 0xfc4c9c01, 0x882e03e5, 0x69e8b2cb, 0xcf53ef11,
- 0xd0d3f8c4, 0xcbebefff, 0x7f8d4597, 0xb5ba8ac4, 0x169f2069, 0xef8b5d6d,
- 0x7bc4ceec, 0xf26ae687, 0xbd415324, 0x96d38d50, 0x0bc58cf7, 0xfb6f5dfa,
- 0xe8e6de52, 0xf82afde7, 0xca5af415, 0x1eb7a02f, 0x4384e574, 0x7e67ff14,
- 0xb27d4369, 0x4277f64a, 0x1dab6abe, 0xf8aa905a, 0x1e3ff1e8, 0x0bb4dfb6,
- 0x76c3c7e4, 0x89483eef, 0xed4bc583, 0xf8ea3e6d, 0x856b60ed, 0x78a7b77b,
- 0xa78a141c, 0x1bbb3a99, 0xe76b77bb, 0xed621476, 0x97863ca5, 0xbb94bd2b,
- 0x710c9f98, 0xe7572f47, 0x1f9f9673, 0x07b56d17, 0x03d14656, 0x84f7f116,
- 0x867df88b, 0xbb672f4a, 0x67462df5, 0x1725ff6a, 0x62f465af, 0xb9e14ba0,
- 0x9f874851, 0x7f70911d, 0x11bb9e11, 0x5d94b4e3, 0x12fd61b4, 0xf828f3d1,
- 0x45b79377, 0xdefbd3a4, 0x59f78718, 0x9078861d, 0x09e983a2, 0xb1779a6a,
- 0xe69fa758, 0xb0ca1605, 0x2c5de79f, 0xf60c7463, 0x93983867, 0x689b5e6f,
- 0x0396f4e6, 0xb4dd2fed, 0x6fcbd692, 0x264ef463, 0xbed0cbf8, 0x3cf76758,
- 0x8a0e451c, 0x3717450e, 0x84adbf34, 0x49f873b5, 0x7ffee682, 0x9e8b8f11,
- 0x45c5917f, 0x493f6e24, 0xf2e73a01, 0xfa9f4229, 0x261db5f8, 0x7ae32f86,
- 0x133af813, 0x437bd7ba, 0x3efdeb2f, 0x0fd72f5b, 0x1bc6dbf2, 0xf1abf5d6,
- 0x5915d6d1, 0x5fac04cf, 0x970de3c2, 0xd5de1898, 0x4c1d1bf2, 0x7b69ab0e,
- 0xa5e22ce5, 0x8f2151fb, 0xb81798ab, 0xcf3e064f, 0x2f171cdb, 0x5f99d668,
- 0xa7e7473b, 0x1f3b5792, 0x6fe570e3, 0xd02f2f9e, 0x9e3755f0, 0x6baf29fc,
- 0x86e374f1, 0x3a57533e, 0xbdca1f60, 0x3ee301d6, 0x65f73a5b, 0xbc32fd02,
- 0xa3fd919d, 0xdd0e502b, 0xcef68ae7, 0xdbc046e5, 0x387ced38, 0xc9fb06de,
- 0xa37bed48, 0x58e3d18b, 0xbe2b6fb6, 0xdbbbee1f, 0x4451649f, 0xd137977a,
- 0xe38469f1, 0x59bf0e2c, 0x8e1c70dd, 0x8657547e, 0x7f3a75e3, 0xc8e15ea9,
- 0x49c2aff1, 0xb0f54efd, 0x18448e99, 0x57f7b097, 0x0aafe3b5, 0x27f1917e,
- 0xa1defaf0, 0xa2fc824f, 0xf4f812f2, 0x1f3fb3ec, 0xb0f76dad, 0x30bde27d,
- 0xbabea90e, 0xd83fb57b, 0xdf50797d, 0x0473c93f, 0xadfe6bce, 0xae8aa7a2,
- 0xa9f630bb, 0x56ae10ce, 0xaeaddfbf, 0x760e186c, 0x20caaad6, 0x40bb54a6,
- 0x8a6a8bbd, 0x685fd01e, 0x78b46f15, 0xbc39eb54, 0x32b65757, 0x4fd5913b,
- 0x240f60dc, 0x99c92f8c, 0x333768b1, 0x837af43b, 0x60dcf92c, 0x7bf993a7,
- 0x5becc967, 0xe7099e97, 0xbf0c84e0, 0x1d6bbe06, 0x4362ffcc, 0xf83f52ca,
- 0x3ec159ed, 0x22ed0839, 0x81767417, 0x9c8bcd57, 0xf0d4ee94, 0xf58331a3,
- 0x904252e5, 0x246e1da0, 0x479daefd, 0x2eceab42, 0xd98b846a, 0x12fbc2ea,
- 0x2ef6e133, 0xeff50f0e, 0x72e5ac64, 0xcddb86b8, 0x197b071e, 0xbb4adf85,
- 0x35a3f70b, 0x39d898d7, 0xf3c66ac3, 0x40f1b835, 0x8fd6397d, 0x7ac1b0eb,
- 0x43f3d044, 0xe4427798, 0x7b43111a, 0x238f9009, 0x3ef9008a, 0xf406b424,
- 0x6d89aed6, 0xd9f7c3f7, 0xe01d5f36, 0xd6d4cbf7, 0x4fd802e3, 0x00c37d73,
- 0x3fa2b5ce, 0x7ff5a143, 0xa033862d, 0x3a2d1a5e, 0x6bd2cf16, 0xa7daafc0,
- 0xf16197b9, 0xb1792340, 0xe59afe67, 0xc53dc366, 0xe5b4c3d7, 0x2d946cfb,
- 0x7bfcf5c6, 0x0b1f0929, 0x74b6ef28, 0xf173c9db, 0x8e51d07d, 0xa00fa44f,
- 0xbf6c23af, 0x625660be, 0x4dfd99e3, 0x67675579, 0x6aaf2ab6, 0xf3f333c6,
- 0x57a53d50, 0x74aba7b0, 0x35ecd832, 0xa90d3d01, 0x74b5dfa6, 0x832f4511,
- 0x72f70671, 0x0fcea11f, 0x3c0007de, 0x6c598bc5, 0xc5d031bf, 0x25fb6ebe,
- 0xb32a7bfb, 0xaf33c255, 0xa238f962, 0xd1fc60fe, 0xe3edba0f, 0xcdde58ab,
- 0xd80be572, 0x05a1dc7d, 0xa6d7e8b1, 0xcb7663ce, 0xc3d056da, 0x2ea4b766,
- 0xd999fb84, 0x0afeebd6, 0x7c293ee9, 0xe2720ec8, 0xe79e2ca7, 0x2abdefdd,
- 0xfbba69d9, 0xdef8addd, 0xcfdf34fa, 0x04b092e6, 0xb711f7f8, 0x01ebeccc,
- 0xc405d3e4, 0x0941f3c3, 0x84f7bdce, 0x42de7702, 0x1abef773, 0x628e05b8,
- 0x5f848f73, 0x82f97403, 0xc368a9ee, 0x7b35db56, 0xd679675e, 0x66fd7bae,
- 0xb227ae2b, 0x5fae2b5e, 0xf6441f5d, 0xb8eef2c4, 0x912e2cc0, 0x0b498f0a,
- 0xdb67bad9, 0x7c98fce7, 0xdb39de8b, 0xccafea3a, 0xc7cd887f, 0xa1cf9f08,
- 0x4ec5ca88, 0xa4e4d787, 0xe1d0ffeb, 0x5eb49d15, 0x669c3589, 0x62fc881e,
- 0xe8997c81, 0xae8926bb, 0xdf00fcff, 0x438044b0, 0xd2ab9f6b, 0xf4e4df2f,
- 0xefa726fd, 0xe3bbd337, 0x1ea02718, 0xae024f7d, 0xb3a7066b, 0x47dfbb35,
- 0x6ff3cc3f, 0xa54b78b0, 0x83eb72a2, 0x49133768, 0x6aac38b4, 0xdfb726fa,
- 0x0e954e28, 0x0dce3c03, 0x4d1997e3, 0x9fbbf476, 0xf4ea2991, 0x029919f0,
- 0x1d6b87f7, 0x2f4e877d, 0xd2f5c55d, 0xff80fd9e, 0x859fb181, 0x39e327cb,
- 0x9eec8f6c, 0xffdff208, 0x85b3a334, 0x293c2853, 0x13ace5dd, 0xfc70def0,
- 0xf20236a9, 0x1c4d6170, 0x85f3fb81, 0x20fbfc0f, 0xd650c788, 0x81b734aa,
- 0x1e080c9c, 0x8b25bfb0, 0x467e324b, 0x10e9b5e7, 0xbf2187db, 0xf0e9e604,
- 0x3d8d0e2a, 0xc8aa43ba, 0xdf5d0370, 0x3c82f0eb, 0xf7877f98, 0x6fe78c03,
- 0x7b041d0e, 0xf99ebab7, 0x00d928f7, 0x9b41f9ff, 0x312b5317, 0x36b950c7,
- 0x90ac4cdf, 0x6cc4cb26, 0x73cb7c83, 0x1e4bb05f, 0x18e4eeb6, 0xdfdf6562,
- 0x72f404b8, 0x5bac835d, 0x3ea0a8f7, 0x3eb37d7f, 0xe7d2119f, 0xe7d11ec7,
- 0x431a83b7, 0xffc395f1, 0xfda1d4ce, 0x877f0216, 0x0b45f8a6, 0x0cbeb3fa,
- 0x05fa007b, 0x4dde50da, 0x82c96e2e, 0x5e4fd6fb, 0x9ce09a70, 0xdf9befbf,
- 0x786d7de2, 0xc9e31d87, 0x0c53fc1f, 0xc07f0189, 0xa15b6d17, 0x04e298bc,
- 0x2fc577ec, 0x0ec0eada, 0x7a8467b2, 0x5fa00d1e, 0x31bf9ec5, 0x76f0f9bf,
- 0x6fee004b, 0xdcfbd93f, 0x9f6f400b, 0xfa87ef6c, 0xdf82cbce, 0xd7f9fd04,
- 0xc4e67c33, 0x272d7db0, 0xde33d286, 0x75cfebbb, 0x1c993bf7, 0x1e6caf69,
- 0x4e59fb01, 0xb47fb33c, 0x011c1e57, 0x8f0e5cfb, 0x49eaae43, 0xbc7e3c39,
- 0x274fea9b, 0xe51439d9, 0x0fce70c2, 0xb2058179, 0xd5fa01d7, 0x5390188a,
- 0x79e5675d, 0xac358fe0, 0x15470f56, 0xf406d7cf, 0x7cf92bdf, 0xf7cd1016,
- 0x56f7b874, 0xbd00a4d6, 0xbea2433d, 0xf9c35c7b, 0x65e7f9e8, 0xf22fbcf5,
- 0xd14468f8, 0xc88acfbc, 0x1facb273, 0xbe0025f8, 0x17be4606, 0xfb55c61b,
- 0xfffbca9f, 0x92fccacc, 0xce1c3813, 0x7d411e55, 0xaddf5ba0, 0x68a77af4,
- 0x07b579f2, 0xfc23e693, 0xd02d260e, 0x1fb6f39e, 0xfe039a4e, 0xfc660d36,
- 0xb32553bb, 0x27247d9f, 0x418bbe01, 0x03942798, 0xaf823b1c, 0xd51ea0b9,
- 0xfd68c767, 0x6f6bf257, 0xecd14ef2, 0xce95dfd7, 0xbb65e3bb, 0xca5e5c19,
- 0x16fdbdce, 0xa2cdbba0, 0x0715aa07, 0x1479bcef, 0x84b37bc0, 0x764b72ef,
- 0xbdb7184a, 0xb406eebc, 0xbe371453, 0xffe31533, 0x03df393d, 0x9332caf3,
- 0x9a0c715c, 0xf480ee18, 0x8c6ecb4c, 0x61fc57af, 0x60566c8d, 0xa3ba7abe,
- 0xa3f08c74, 0x6dd6541a, 0x15de53c0, 0x7eab3fe8, 0x30b7e237, 0xc46f6fa0,
- 0x1ba72b53, 0x8b5c33fa, 0x3ebd636f, 0x8ef8fdd3, 0x953964b2, 0x543b1a63,
- 0xf46aa9c9, 0x038e33d7, 0xa344da37, 0x7703eca7, 0x1dafe01b, 0xfe836fcc,
- 0xee2cd608, 0xe5883ad7, 0xd0200e31, 0x047fac15, 0x3bc0a299, 0x34c8dbcc,
- 0xd1b95548, 0x0d1c1d91, 0xda165ff5, 0xf615fd9e, 0xed7e44e7, 0x2e308770,
- 0x3efe5f62, 0x796143b5, 0xa83aeff5, 0x362d45e5, 0xe4f8f3f4, 0x71f28cbc,
- 0x4197f805, 0x266c17fd, 0x3ebfdd13, 0x1267d9d9, 0x04762df8, 0x73dcbc59,
- 0xe4933ec1, 0x8d77d96f, 0x0fdd4172, 0x74afc04f, 0xe9c2fcdf, 0x4b7ec30d,
- 0xcebf3156, 0x19153ee4, 0xa4f05115, 0x2b904bb6, 0x123ce032, 0xd9e1d7be,
- 0xa7f2708a, 0xc1723ec3, 0x81f68297, 0x121edcf9, 0x06fdceef, 0xbad275fa,
- 0xfe2ffa5e, 0xe815b888, 0x73d163eb, 0xe4507bbf, 0xa6516f9e, 0x90f3df0f,
- 0xb45cec55, 0x66424cd0, 0x842eefaa, 0xe63463fd, 0xb85bbf71, 0xa6ff4059,
- 0xebf41b45, 0xdaad7881, 0x405087bf, 0x22dfb1aa, 0x60b4c412, 0x10bcbeb3,
- 0xf81723f6, 0xfc7bb067, 0xb97d7aa2, 0xa4a84efa, 0x1a25b2f1, 0xea20bedc,
- 0x2ec9bcfa, 0xb36e179a, 0xdbeefce2, 0x35eecb14, 0x7d85e264, 0x89c9bc30,
- 0xf898bc72, 0xbe3f3bd8, 0x303f960f, 0xd288bbdf, 0x85f2d767, 0x307d45de,
- 0x7d81077e, 0xf895b16f, 0x1e58635d, 0x0b2017e2, 0x38b29f21, 0xed4eb051,
- 0x29e2963b, 0x15c03424, 0x53ac2f59, 0x65de4e5b, 0x116e2cf8, 0xbd60a342,
- 0x64427ef0, 0x2bd6d5eb, 0x692870e1, 0x11ece8b4, 0x0a7fe0a5, 0x974d337e,
- 0xb97eba2d, 0x8fdd1f3f, 0x69e28d89, 0x0ddcb753, 0x4fcd1b5c, 0xd78738fe,
- 0x52f33ba6, 0x051f3f81, 0x072fb33d, 0x173d3668, 0x61cc9083, 0x71d2b780,
- 0xe776c662, 0x256b3cb1, 0x647d4fcb, 0x51e90fe0, 0x1bcefe1b, 0x142c6fde,
- 0xf7875f73, 0x7db9cf57, 0x71d1763f, 0x69bc9a16, 0xef53e466, 0x5cd7f450,
- 0xc4ffd6ce, 0x2b6b8a98, 0x557b9ca2, 0x042e3e7c, 0xbfd1bef1, 0xceabed97,
- 0x7da4b0cc, 0xc5c8b45f, 0xa1ec4fe4, 0x10777c36, 0xbbe02dde, 0x138527c7,
- 0xc9f02ef8, 0xce04291f, 0x6f1429e5, 0x149f1f20, 0xbf882ac8, 0x7334d995,
- 0xbf806bc9, 0xa3d418cc, 0x8a269b4a, 0x3f5c0ea5, 0x15eca3d3, 0x99ef7075,
- 0x18f86f3c, 0xeeba6ba0, 0xff01b779, 0x5b8414bb, 0x41d183aa, 0xfa7f4aca,
- 0x7e3091d2, 0x80d792ee, 0xe0c546ef, 0x0a64d93b, 0xa63c672b, 0x4a2f40eb,
- 0x41071921, 0x574ca78e, 0x772d80c6, 0x938d8b93, 0xcde71268, 0x0c6dfd04,
- 0x243fc7cb, 0x7122b778, 0x2575c46d, 0x369fd85b, 0x7fa0ef82, 0x804ec15a,
- 0xe78601e5, 0x301915c9, 0x9620f27e, 0xf421c826, 0x8dda3a53, 0xcdea1f77,
- 0xe504dccb, 0x134bb2f2, 0xfb69e393, 0xc0f41da3, 0xd1d5e54c, 0x1d9eaafe,
- 0x439e8072, 0xf5670f06, 0x2cb15eb9, 0x27e5f983, 0x10faa9a4, 0x7925d7ab,
- 0xfc82c763, 0xdbe9877c, 0xb1bc3b9f, 0x837737e0, 0xb80fdd1c, 0xfca9e386,
- 0x34049da2, 0xd67cbff2, 0xa4def897, 0xf74ba2fc, 0x69c9e21d, 0x0a4b49fd,
- 0xe3dc610e, 0x7e8ad252, 0xbd41a5c9, 0x310debff, 0xe955c7d1, 0x48a2fcbc,
- 0x95c751fc, 0xf62fdff5, 0xd13efe21, 0xbfe925ea, 0xf9f4145f, 0x3d78afe6,
- 0xd9277e33, 0xc7382e6d, 0x077d874d, 0xe4c049e4, 0xe08fae97, 0xa6ddd3a5,
- 0x153a6fdb, 0x71e2ef96, 0xb572d575, 0x3259ceff, 0xc6139f7f, 0xa92a3a71,
- 0x79f0a240, 0xb453e5aa, 0x1cb496a3, 0x74a8f844, 0x9d938111, 0x4a7035f8,
- 0x990d6aaa, 0xfeff8f28, 0x476b4591, 0x72514b5e, 0x3fb3f388, 0xf297ad6f,
- 0x2fc4126f, 0x3db7f0d7, 0x51df9bb3, 0x89326ccc, 0xbf99dedc, 0x4d04ca76,
- 0x6eefd79e, 0x21f82fef, 0x648e6794, 0xa47bdfed, 0x072b77f0, 0x5d13e447,
- 0x53ae5a47, 0xf21ab793, 0xa51f9a0e, 0xe50dbbc9, 0x14f28609, 0xab3fbe43,
- 0xa50ce1df, 0xda421e89, 0x21fd291e, 0x8eb95dfc, 0x885cd0d4, 0xac41b038,
- 0xddfc21f8, 0xf64cd2c9, 0x5acb1477, 0xb3730f04, 0xf32bf062, 0x87307bb0,
- 0x385e4da7, 0xfad0e012, 0x9283c83a, 0xfa0dc166, 0x33b823be, 0xa7687984,
- 0xd905da68, 0xe092ad3b, 0x6bd76c09, 0xc84dc3ff, 0x3f0f0fcf, 0xe4aef589,
- 0xeba644ef, 0xf37be0fd, 0x7c9874b3, 0x53df6117, 0xec770ce3, 0x77f23f7c,
- 0xcef7e8ed, 0x9461ef54, 0xaaf786a7, 0x471f30e5, 0x38545f84, 0x02fc3c3e,
- 0xf3fc5dc6, 0x40f796a8, 0xfb2fb00d, 0x95e80574, 0x1e9e961f, 0xc4167a07,
- 0xe3fd846e, 0x2d702171, 0x114f47ec, 0xee30b5df, 0x0e43a5bd, 0x39949fc2,
- 0x816db52e, 0x1ec31050, 0x3ff08f5d, 0x001b6cee, 0xdae8927f, 0x4f961ad8,
- 0x1008c36c, 0xfd37626b, 0x39fb4cd0, 0x806da03e, 0xc547e689, 0x43e5661e,
- 0xfe40b6da, 0xb0dfd8ce, 0x036d51f2, 0x1d1c3744, 0xdb7f111a, 0x3ef9d1dc,
- 0x1bc9962d, 0x06437e75, 0x4163537b, 0xfb612a8f, 0xb4873c0e, 0xb73ab952,
- 0x6d8edce8, 0xff731e14, 0x6ef28ed5, 0x3fedc75b, 0x3fb1fa66, 0x92a0fc17,
- 0x5f71bc39, 0x466ef944, 0xf61521bd, 0x3e08f8c2, 0x0aad699d, 0x2a231bee,
- 0x905e8276, 0xee24773c, 0xef4e9d1b, 0x9171d8da, 0x9a048bf4, 0x8dac79d2,
- 0x2ef93375, 0x5b3df09a, 0xd44e83f2, 0xf1e51e9f, 0x21df29ba, 0x5e38387d,
- 0x8cf5f2c6, 0xa1e7658d, 0xd84dd744, 0xaf5cddcf, 0xd81f59ad, 0xfff0a36e,
- 0xde0e7a93, 0x39e4f4c8, 0xc4ee5475, 0x37817f82, 0x1cc9e415, 0x8c8f07b0,
- 0xbfbd55e4, 0x1de68326, 0xcd58f391, 0x36aa6f4c, 0x1d4d782e, 0x55e5572b,
- 0xaf6b3a4d, 0x55c95bee, 0x8fc93e0c, 0xd615bb5e, 0xff333761, 0x86b3c581,
- 0x7a815d6e, 0x5f386dc0, 0xc2a6f5e2, 0xe154fcb9, 0xa3e81340, 0x0da67e2a,
- 0xeb82def6, 0x2a38f7e1, 0xd7f1d49e, 0x142f75f2, 0xf6011ea9, 0xe10fb774,
- 0xd18af549, 0xe99d72ec, 0x5ae96b15, 0x7c2a1f01, 0x1c6db989, 0x045fff7c,
- 0x0cffa5a7, 0x7eddfd38, 0xbc7bd3dc, 0xfd0359c7, 0xad3f2e97, 0xe1c38f7f,
- 0x9210b8fe, 0xf1353392, 0x3877e853, 0xf2eade77, 0x735622fd, 0xc1f735bf,
- 0xd53fd452, 0xe5ffd8f5, 0x917769a5, 0xd469fc9e, 0xc9ff8f0f, 0x02ec01ba,
- 0xca20e5c7, 0x263fe3e3, 0x38e42ef8, 0xeaa5678f, 0x5aff59b7, 0x6dce147c,
- 0x222b11ff, 0x7a54d87d, 0xe6777210, 0xa7aef851, 0x3bbc39db, 0xd464fd57,
- 0xc786bafd, 0xe079ada1, 0xd1af7c3a, 0x3cf0da45, 0x2826cfee, 0x67cbbb3f,
- 0x4a72c50f, 0xc81b7e27, 0x8c18c289, 0x41935fc7, 0xcd497df0, 0x0e5811ec,
- 0xc7f458e7, 0x71c56d99, 0x3a32666a, 0x478c29ac, 0x5dc8217b, 0x746f5b80,
- 0xecc55494, 0x1decc41f, 0x7f1fbdad, 0xf9f9962f, 0x76db33db, 0xed7a0fbf,
- 0xb5ea1b06, 0x57bc4280, 0xf1c64ea9, 0x8fec3d28, 0xcd97fdc5, 0xa963e163,
- 0x5c718781, 0xd603da0f, 0x51f3bd3a, 0xaeccfdce, 0xdb37fcc0, 0x18eb3ac8,
- 0x5590e638, 0x7cf92f28, 0xe813f548, 0xeb8f3157, 0x5c151f89, 0x721e8270,
- 0x1edbb634, 0xf9f385e0, 0x17cac202, 0x013f643c, 0x0f05abe7, 0x64b778b1,
- 0xfd5e4ddd, 0x6b9d093d, 0xf9d3d812, 0x09d86d4f, 0x3b41f070, 0x1ffff417,
- 0xe41f784e, 0xc3bd887b, 0x7eda7e25, 0x47fda478, 0x9760f7c0, 0x49fcd917,
- 0x16895da5, 0x58a3f4e7, 0xfd5397ee, 0x9e3b5784, 0x5fb18e3a, 0x036c8e7a,
- 0x0f70a37e, 0xf0a83bc1, 0x59dfd8cf, 0x4137ce30, 0x46c2ff0e, 0x8a56e7cb,
- 0x3c292b71, 0xb89dcb7d, 0xf3be755e, 0xa237c392, 0x7fd0c29d, 0x0b2cbdbb,
- 0x79eae7ec, 0x39a43c88, 0xe45c21ff, 0xf8845e48, 0x573c6101, 0xcfcef8f5,
- 0x2873c6cd, 0x68b37f21, 0x2bbf75eb, 0xfcc30450, 0x82295d39, 0xe3e6f019,
- 0x1cb2fef7, 0xeb720b9e, 0x50eb02ff, 0x8000589e, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7dc5ff00, 0xd5547c0b, 0x73b9f899, 0x3332bcef, 0x49324cc9,
- 0x9b8f2126, 0x80402107, 0x52024c49, 0x1878431f, 0xa4076b35, 0x438b5b16,
- 0x921123c2, 0xb175b689, 0x5100cb65, 0x8d042208, 0x41380abc, 0xbb6bba50,
- 0x060222c1, 0xb6a2d11a, 0x6eb42fea, 0xfdfeed57, 0x58f88845, 0x16544649,
- 0xefffad5b, 0x99b9cefb, 0x514493b9, 0x67f4ddbb, 0x739ee72f, 0x77cef9cf,
- 0xcef9f7be, 0xe99a1619, 0xf4662deb, 0xfc3e79f7, 0x33577f87, 0x3034e896,
- 0x7cd8ca96, 0x96773599, 0xeb47df44, 0x6d67aa25, 0x34967d5b, 0x0bbc02c6,
- 0x66f536e6, 0x607da1fb, 0x694df9b9, 0xeb88bc22, 0x6330b19f, 0xb56d8c15,
- 0x993590b2, 0xf4126db1, 0xbbcf0e53, 0x7935e16c, 0x23580d8c, 0xc602b08f,
- 0x59afc782, 0x1bfbef80, 0x4d065412, 0x08589876, 0x8ee3a1cb, 0x576c3ef0,
- 0x64c45bd4, 0x7c1807a8, 0x24be786e, 0x0d248477, 0x5e9ac608, 0x87acf792,
- 0xae47fd76, 0xb2acfde5, 0x41ca0ca9, 0xb8c136a8, 0x575fd0c1, 0xa4c644b2,
- 0xff1a1639, 0x6c2921cc, 0x66c3fac6, 0x85e0d3e6, 0xbfe1faff, 0x2f1832fa,
- 0x2719086c, 0x102b13c1, 0x8236c38e, 0x40da6603, 0x813f7de3, 0x9bf187ad,
- 0x00cf920c, 0x8db74df5, 0xf0e1af0b, 0x67e01858, 0xc9ad0099, 0xe8245ac0,
- 0xb5e0532f, 0xe8ba70c9, 0xa75e128e, 0xf8a5bb40, 0x3dda950f, 0xcb9c012b,
- 0x647a1b2c, 0xe1399380, 0x0dbfa83f, 0xeba2f3eb, 0xbfe1b4d0, 0x3479c33f,
- 0x2db8041d, 0x3d97b851, 0x6dc79fa6, 0x27ad14cc, 0x7eb443b8, 0x2f8e72b6,
- 0x47858336, 0x510ebc03, 0x84f755b6, 0xf2c7c465, 0x65ccece9, 0xef44f4d0,
- 0xeb1dbf2c, 0x3c2d593b, 0x5f30ef83, 0xda9ee018, 0x28ccf1d5, 0xeeaaef68,
- 0x06e9c6c9, 0xa0b1ff97, 0x3ae8b2ef, 0xde5e706b, 0x766659b5, 0x03be8f1a,
- 0xec077c50, 0x9cec6ed4, 0xd5cfb109, 0x41aa5df4, 0xebc715be, 0x881957c5,
- 0x04865f1c, 0xc8696ce3, 0xdabae037, 0xb0057814, 0xb31b6a2e, 0xd9e11567,
- 0xc1c73457, 0xec8983d8, 0xd3e13f56, 0xfe87e95b, 0x2d56751e, 0xe97f4274,
- 0x9d5baaae, 0xbf1c7ca9, 0x029fa703, 0x6ba50d40, 0x47e1a9ed, 0xd05e976b,
- 0x1f6cda5c, 0xc4db9db9, 0x9ed916f1, 0xf083de14, 0x17951228, 0xb1d8deff,
- 0x8853e09e, 0x95d8ee6e, 0xebf84617, 0xe9099b59, 0x9b0b197c, 0x5b178e90,
- 0xe8112858, 0x4b343162, 0x6d92e782, 0xacc6a666, 0x5f58435f, 0xae1ced66,
- 0xd3f74a65, 0x4dd22252, 0x74b3f50f, 0xb2ddbebf, 0x01dbac19, 0xd6168df5,
- 0xa767c36d, 0x4589bebe, 0xe1e08e08, 0xfebacdcf, 0xc3ad1b59, 0xc8632b76,
- 0xbe6549a7, 0xfe01bbbc, 0xef460bc8, 0xb7cfa01e, 0x7868bac4, 0x35567648,
- 0x64139e20, 0xb233cd03, 0x03de16ca, 0xb033ecf3, 0x4de75c7a, 0x1ceb762e,
- 0x64aff678, 0xa12342be, 0x77ae2263, 0x1fd73e3c, 0x7d23d6b5, 0x13f9416c,
- 0x38373f43, 0x5ee7848d, 0xbe47ab13, 0xfd0d5ca9, 0xa6a5c8c5, 0xfc01ec9b,
- 0x9726976e, 0xc46f9d60, 0xa86b6675, 0x9e91ed8c, 0x4fe32e12, 0x83bdbbed,
- 0xa7f337ed, 0x4b7bf9c2, 0xae074243, 0x0cee9453, 0xc4aee88c, 0xf7c00a6f,
- 0x583c8547, 0x38fdf960, 0x40a3f7a4, 0xa1f7c808, 0x0b972b4e, 0x72fe738a,
- 0xa77d1f28, 0x455ebbc4, 0xe272e0fa, 0xd812f7e8, 0xf9f2186a, 0xdef5fef7,
- 0xfcfea197, 0x0cd5263b, 0x46910bf5, 0x4a8f3d60, 0x85e387cc, 0xf787309e,
- 0xc065bbc1, 0xb2cf08b6, 0x28c213e3, 0x02990edf, 0x38e117db, 0xfbbd1b8f,
- 0x8965bbe0, 0x423c5fe1, 0xa05e19f5, 0x9194f644, 0x88e861d3, 0x109f7f8d,
- 0xb95fb7fe, 0x1bdd3eb1, 0xac7bf682, 0x07c81381, 0x09356699, 0x97bf65fb,
- 0xbba71f19, 0x3bf805c8, 0x824af38d, 0x38495427, 0xfa83974e, 0x58cafe01,
- 0x699cfd04, 0x80f9a74d, 0x38e1f4dc, 0xf79a3667, 0x32dcdca0, 0xed44ae38,
- 0xb3fd1b4f, 0xfa7ca032, 0x2aef5289, 0x9bf01aa8, 0x7f404dba, 0x5f4b4dc1,
- 0xea17a064, 0xc46eea0c, 0xa36e3b0f, 0x11eb6879, 0x06a4b8dc, 0xadb783eb,
- 0xdae501b8, 0x7289fc48, 0xbbc8c59a, 0x41c9167e, 0x9f51dffa, 0xfa8dd9df,
- 0x57ac6ba0, 0x2c0f5aa6, 0x9387d03e, 0x7233edb7, 0x198e46fc, 0xb52f4f89,
- 0xa50ba47f, 0x1c0feb92, 0x94f20827, 0xf242fc69, 0x0f2ca634, 0x18ebe657,
- 0xfc4e9a3c, 0xdb3f5f1f, 0xf908f811, 0xfffee9a7, 0x8ab96379, 0x9e4845e3,
- 0xe254b6b1, 0xdbbb8033, 0x6df7df02, 0xe55f1077, 0xf70f50ae, 0x741ebae2,
- 0x335d3cd1, 0xcb03b27c, 0x3ca8f33b, 0x1c6dc855, 0xe2c6f516, 0xcaf48c29,
- 0x58b59962, 0xd17de8ca, 0xf67f6876, 0xcf5a6c89, 0xceb666c5, 0x36ce7c02,
- 0xdb3ffa70, 0xf00a7201, 0x25ee6753, 0x4dfecb39, 0xb518fb62, 0xcb76c16b,
- 0xb28c9060, 0xb94378a1, 0x385bc3a5, 0x7ffa0ca6, 0xe907676a, 0x8a720601,
- 0x9a05d8c5, 0xa4f9431c, 0xcdfd9efb, 0x4863c7ac, 0xc7c4b793, 0xd9f4a930,
- 0x28f2a213, 0x72cfe9d9, 0x30a16055, 0x5677f11d, 0x04e9dc0e, 0x8584b6f9,
- 0xb0363e48, 0xe36a7a6e, 0x72e5bc81, 0x2ee5c2d7, 0x412e133e, 0x3ac6defe,
- 0xa2366e49, 0xee4e1a44, 0x3bb900ae, 0xcbb96471, 0xe2297358, 0xdd8b7835,
- 0x221e788b, 0xd77c857f, 0xc4dd31d6, 0x15d4f0e5, 0x44959961, 0xe89a90f1,
- 0x115a969b, 0x57c1abd5, 0x1275162d, 0x1f2cfd96, 0xda63ade5, 0x7d41a7bf,
- 0x943e6150, 0xe61eb69b, 0xbbf780eb, 0xf3f5fd84, 0xf1fa9534, 0x185d3898,
- 0x852b3f15, 0x9eaacafa, 0x49f2036e, 0xbca2732a, 0xfef0f477, 0xbbe03977,
- 0xcb8efc32, 0x2defc1cd, 0xe62125ac, 0x56a3aafb, 0x470ba3a2, 0xe933611c,
- 0x0bae40c3, 0xb3fb4bfa, 0xfea4ec99, 0xf3920ea3, 0xaf3646fd, 0xd1bbda13,
- 0xbcf5a21e, 0xaefbfa87, 0x219e8f2b, 0x218a3556, 0x8dd74aed, 0xecd65642,
- 0x9ebcc683, 0x1edf489b, 0xc7c8ab30, 0x77bd5c17, 0x63c61962, 0xedbf2728,
- 0xf05da952, 0x9fd2f4e0, 0xdfa0fbc2, 0x0dd8e5ee, 0x98bd2294, 0x64dd1fe5,
- 0x259b7581, 0x05dc88af, 0xdb663670, 0x6787289d, 0x9fd7fee4, 0xbbf2866e,
- 0x8ccc8d07, 0xfa6fbeeb, 0xb23f963c, 0x1b08689c, 0xd0c6f74f, 0xfafdd2eb,
- 0xbea76372, 0x2fac3c1c, 0xb872e1df, 0xde278ecf, 0xf40e7ef4, 0xbf373664,
- 0x9af001d3, 0xdc93329f, 0xf815debc, 0x26e7a467, 0xe224e443, 0xfefb9cd1,
- 0x73ae00c4, 0x3e1207d7, 0x3d2640cd, 0xc8bf1c25, 0x0bac1757, 0xd8c39d72,
- 0x857b51eb, 0x47840c59, 0x513d06b0, 0x20e410f9, 0xdef95f01, 0xbfe61a7d,
- 0x73824e78, 0xd5f1bd35, 0xbda25454, 0xe0b23042, 0x45df6bb6, 0x35da1ebb,
- 0x0d989c90, 0xfaae00ed, 0x2f6e5c6d, 0xc8893d63, 0xd7604d0f, 0x7f096058,
- 0xb1f4e2e7, 0xd95225b4, 0x4f6cff0d, 0x708b1eae, 0x7e299f2a, 0xd8b5ff5c,
- 0xf61d8c6f, 0x1dfb8b90, 0xdb5bf74b, 0xa1f862fa, 0x2ba5d3b1, 0xb4670f07,
- 0x5de2c5f5, 0x25533ff0, 0xb6ded625, 0xb90f021b, 0x7b0f9152, 0xfc60d34d,
- 0x88fb3fab, 0xe592f7f4, 0x0a9d90cf, 0xedc058f3, 0x728aab36, 0x4f5dc975,
- 0x2fcd7bd3, 0x276d9b38, 0xed99e0bf, 0x99765e66, 0x17767ca8, 0x74965bf7,
- 0xa79c614a, 0xca62e734, 0xbba79434, 0x1b334e8c, 0x3c78d78a, 0x3ff3bdbe,
- 0xf54c1913, 0xfa3a426d, 0x1bb71213, 0x6489cd9c, 0x89cdaa9f, 0xb7051f68,
- 0xca2ef35d, 0x64bb25a9, 0x7635ea2f, 0xcd1de1cc, 0xec733cb0, 0xf3f63b22,
- 0x8034ca61, 0x4cf77da3, 0x65ef4ca7, 0x48f9187f, 0x0d5cf5f1, 0x93dd95ef,
- 0x67b7e455, 0x97f87177, 0x208f2cb8, 0x99fd5d1d, 0x62b2764c, 0xcfb40160,
- 0xb1be4dda, 0xceeab7c8, 0x7d70b37d, 0x699d9ede, 0x94bff6a0, 0xe2f11398,
- 0xef869e5a, 0x1f8a4897, 0x5b7eb4f9, 0x7eac4d43, 0x1325d5be, 0x5dcb4dbf,
- 0x276bd691, 0xf509babe, 0xe02ee355, 0xce7f1c23, 0xd9ba7feb, 0x692be51d,
- 0xa61bb6ce, 0x1a8fff62, 0x8377c8bd, 0x3fe7777a, 0x5fe17d11, 0x6dca2577,
- 0xca6faf8e, 0xc69b6667, 0x2845cd27, 0x6eac973f, 0x630e722e, 0xc9f20fcf,
- 0x6f97ce4e, 0xb7ee24b9, 0xeceb2566, 0x00fc91dd, 0x87c1b17b, 0x9978b7f8,
- 0xd33c1f6f, 0x7f430dc1, 0xa159212f, 0x136484fa, 0xe4f949e1, 0xa92ffd8e,
- 0x3e071768, 0x65ccfa44, 0x27d452be, 0x9559c46a, 0xec2b7484, 0xdb93b605,
- 0x907f6081, 0x9525b5bd, 0xc63eb23d, 0xfe8933ff, 0x8a7c4e40, 0xb5ffa272,
- 0x7e224f4f, 0x9fde729b, 0x783afa88, 0x0a9323f1, 0x4977b5f3, 0x5eedbf24,
- 0x09ba433f, 0x0b66cd76, 0x3772a24b, 0x217ae5e8, 0x26375e7e, 0x751cb91b,
- 0xab9fa847, 0xb73f3852, 0xd3d118bb, 0x6409e58e, 0x8770ee97, 0x57f408ad,
- 0x29f65be5, 0xe7587568, 0x675f0b06, 0xfb5fdecb, 0xb0f3a464, 0x658d1ce4,
- 0x40c7f395, 0x0cb0fcfd, 0xb7bbbce3, 0x83e54420, 0xd432bcd3, 0xbc3ef7d9,
- 0x74f11f2e, 0xf6c5e8d8, 0x226f6f76, 0xbdddefce, 0x7e711267, 0x9a657bf5,
- 0x83f87d77, 0x512545b4, 0x2917f139, 0x768c9050, 0xc7b25b82, 0xf7778bca,
- 0xd0b6987e, 0xd253fdce, 0xe3c3e597, 0xad35dd25, 0xfabfbf18, 0xef2ebe2a,
- 0x461cd2fd, 0x159ef839, 0xfc8c59f4, 0xf5c1cf7d, 0xcd64d4db, 0x41cce8cf,
- 0x565833fd, 0xfc701ac6, 0xfcf9391f, 0x1ccea6dd, 0x96ffcbe4, 0xb6dcfdf4,
- 0x9061664e, 0x24eb0d4b, 0xff990616, 0xcc9e2fde, 0xeefff941, 0x6a7327be,
- 0xff8be063, 0xd0ce7b4e, 0x9af113c6, 0xd78da65a, 0xd5e3859d, 0xa26fcd7a,
- 0x66eb619c, 0x26f906fa, 0xdb633f9f, 0x8a3e6db3, 0xd7000ca7, 0xdf6a1d22,
- 0xf827d40d, 0xcc2eb82c, 0x4e90c612, 0x6ddc976d, 0xbe7cfec6, 0xdfda3742,
- 0xfd71f7da, 0x927a0ab7, 0xa7e44b0e, 0x24224ada, 0xfcb6bf9f, 0x13d7e8f7,
- 0x4c98d9d6, 0x72723ff2, 0x30fa2314, 0x4d4cde21, 0x55f50576, 0x5f4e1ada,
- 0xc81b1f91, 0x2427701f, 0x3f60644e, 0x763d3299, 0x17576f94, 0x9218b425,
- 0x184e7df0, 0x166767db, 0x2aa177d3, 0x34a1ff4e, 0x0c9e7146, 0xff212cd6,
- 0x97b72732, 0xe730a6b3, 0x4fee287a, 0x878c76e6, 0x05c9b779, 0xc612feb4,
- 0x68bc3425, 0x08e901fa, 0x927be5e5, 0xea48e885, 0x947ec892, 0xb1f39d0d,
- 0xeae891df, 0x8ad75c6e, 0x960d5d28, 0xb57441ff, 0x086f1b49, 0xa254055d,
- 0x78658f2b, 0xf62552ba, 0x90b3da95, 0x74affd1f, 0x424daf81, 0x6c7e44fe,
- 0x4016f1e1, 0x46b7ce19, 0xb16357f4, 0x47a8cb77, 0x63f7c6bc, 0xc13b8fe3,
- 0x25ff45ee, 0x787ced03, 0x40b35a8e, 0x3d6375a5, 0xdaefe8bd, 0x5f485b26,
- 0xc9e86bde, 0x7d263b43, 0xa401f35c, 0x25f9f48f, 0x6fc86b65, 0x5ea172cb,
- 0x714b5d40, 0xfdd3e587, 0x7e808edc, 0x9b668e91, 0xba6b3fc8, 0xdb9f9a6b,
- 0x2fc4d511, 0x15560dc1, 0xaef4e0f5, 0xf76455bc, 0x335e60af, 0xf6c771d1,
- 0x9c2f18c5, 0xaca2f76b, 0x213c62b3, 0xe7afe705, 0x93a956bb, 0xb5d0f1ec,
- 0x5d728bcc, 0xbbb6478b, 0x14ff777a, 0x09437ff5, 0xf183f7f9, 0x7a4642c9,
- 0xcbe5dda3, 0x1ebc0648, 0xa78f1bfa, 0x194297b5, 0xf5894f9e, 0xcbed9f6c,
- 0x76b94170, 0xdef09583, 0x07ebc1de, 0x49a0801c, 0xfea4a714, 0xeb859258,
- 0x81f2a1a1, 0x53699be2, 0x0db7f698, 0xb95a99cb, 0x41d92b6d, 0xe7b7ff1a,
- 0x251c7871, 0xc8b43cfe, 0xf1dcdf2f, 0x47f0027c, 0xa68dc61a, 0xb42117d2,
- 0xc92e29f7, 0x7cb614cb, 0x648000d0, 0xeb27f162, 0x5b115c67, 0xdfa3ede6,
- 0x7ac7af5b, 0xf583bfd0, 0x65e83608, 0x02b3ecad, 0xd11d6b1c, 0x60ec057a,
- 0x7c4961cb, 0x3375e4ff, 0x92fe610b, 0x93f43f18, 0xafc61f56, 0x5e374cac,
- 0x5c4a7c2c, 0xdfe846ff, 0x77ed6aae, 0x0684cf56, 0xe569960f, 0xb2f9d78f,
- 0xbea33fa0, 0xf8a9423f, 0x78da0b1e, 0x63383dcf, 0xa8ac86fd, 0xc2f6007d,
- 0x34cf2827, 0xebed613b, 0x60936d35, 0x43f39b2c, 0x4d5fea13, 0x12dd07df,
- 0xfcf121d9, 0xbe914b6a, 0x085d7d99, 0xcea575f6, 0x70a5b6be, 0xb2167afb,
- 0x2425f824, 0xfc2b83bf, 0xb05bed0c, 0xbeb0924b, 0xcff7b5ff, 0xfdf50d3e,
- 0x7272fe73, 0x6eed8a94, 0x557e8f9f, 0xf242a2f0, 0x0e5fb837, 0x9637c04b,
- 0x83576e2e, 0xb478a73e, 0x39b73f46, 0x42b8fd05, 0xed6ce30c, 0xa40aa4c7,
- 0x73a3f077, 0xf96b03be, 0x665f14a3, 0x9fd4454a, 0x65f79f8c, 0x189e3c29,
- 0x5edaae2c, 0x95effd84, 0xeb0bda18, 0x2da74f8b, 0xcdea7f24, 0xdf3145b4,
- 0x907e1c35, 0xdfb0d9f0, 0x2f1e2c38, 0x8f09914b, 0xf09e474d, 0x2f78dca1,
- 0xa84c912c, 0x68adc257, 0x1bd7d6d7, 0xe56422d0, 0x533705e1, 0x899e7d7c,
- 0x65f9868d, 0xdc177d08, 0x2a68637f, 0x93fe1bce, 0xff0ed5e0, 0x3b139262,
- 0xb4ec59e6, 0x7b5c514f, 0x99c1e13b, 0xac3c43e0, 0xc0caae2f, 0xcf669a71,
- 0x1e5c5272, 0x6fac39ec, 0x147bebba, 0x5ae0d7a7, 0x8d58d87f, 0xd8254ef6,
- 0xb806bf75, 0xabaf93b3, 0x8f5f02f6, 0xfe940f92, 0x465bca10, 0xba2fe390,
- 0x48b45d39, 0xcbb7d0fe, 0x62c78e29, 0x87b972e3, 0x7d78fdb9, 0x69da898a,
- 0x514fafef, 0x8457af08, 0xb923a67a, 0x6d7a571c, 0x99075768, 0xabf403ef,
- 0xeeaedf99, 0xf2e275a3, 0xa552bdcb, 0xddc59378, 0xac24ef7b, 0x7f2142bf,
- 0x0fbd2986, 0xadfdb8e0, 0x267aef6e, 0x77cb00f8, 0xea1c5095, 0x1e604a68,
- 0xb0a56fae, 0x5c8ffb57, 0x125b5a53, 0xf75abfb5, 0x01abc239, 0xf50ead0f,
- 0x93946afe, 0x2724289f, 0x33d22599, 0xf869fa1d, 0xfbf5326b, 0x0ea05b07,
- 0x86b569fb, 0x420e915b, 0x73b5321d, 0x6374b1cf, 0xe23eef3f, 0xd33b40e8,
- 0x48636ee8, 0x50bee0c7, 0xf6e2c49c, 0xd3ca1533, 0x09140b43, 0x5d9c45f5,
- 0x49e31d33, 0x29b8b7e4, 0xf82558de, 0xc1503463, 0x42b10b59, 0x5129e7cb,
- 0x4ff9e73b, 0x52f82ae7, 0x160c7fb3, 0x319e1f1e, 0xf8e1812f, 0x49c89eec,
- 0xdd9bc603, 0xe1ed0c3d, 0xc6894ec6, 0xdc7e2c69, 0xd2cbfe84, 0x41dfce4e,
- 0xfe006fe1, 0x58aed072, 0x76136291, 0x77a70b66, 0x147273d6, 0xbe31f9e2,
- 0x3b418c9e, 0xb2dfac47, 0xfd69da8a, 0xbc9c4499, 0x4093c451, 0xdafd5213,
- 0x58cecd14, 0xc26d9e2d, 0x6ee3e0ce, 0x327c7a91, 0xd254b3e2, 0xe7b573c5,
- 0x9277216e, 0x2166444e, 0xbe8046ff, 0x5db4ae30, 0x6ffb7d9a, 0x2bdb7e61,
- 0x14d179c6, 0xc93900f3, 0x481ef865, 0x7e5ef011, 0x485983f8, 0x119aac37,
- 0x9e1d36bf, 0xfd8a3726, 0xd217b404, 0x581dcd6d, 0x316b7e9f, 0xef8c67e9,
- 0x5ec0bee3, 0x3b0cd781, 0x5679eb8f, 0x9f70f287, 0xff84e92d, 0xf8e2dff6,
- 0x1f681213, 0xc6d61d23, 0x75cf4c91, 0xb0f2d718, 0x3f51a7d2, 0x32d46a7b,
- 0x4fdb4784, 0xd9a8fdc2, 0xa9c72425, 0x7c95ec9c, 0xabf9e07b, 0x01e11714,
- 0x846abcfc, 0xed87df17, 0xf4adfdd1, 0x38a5cde9, 0xe11fee2e, 0x5ba33fb3,
- 0xeb3538a1, 0xfc8fbddd, 0xf113b37e, 0xb9f87355, 0xd6ff5157, 0xed275858,
- 0x2dd9c5f7, 0xf1bc4e3f, 0x03a39449, 0xbeeecee7, 0xcefae11b, 0xd6806f21,
- 0x5c8f6f47, 0xcfb7157d, 0x5367dbdf, 0x23dc8ed1, 0x8fd836e4, 0x5fa127c4,
- 0xde327f72, 0x45397c8e, 0x960c9fef, 0x2476eeff, 0xf0042f87, 0xef918bed,
- 0x0dffe141, 0x444f9fd4, 0x20faf5fd, 0x2bffa03c, 0xed5076a3, 0x2bed1b5e,
- 0x7117fa0f, 0x8ff3c8f6, 0x0f4842d8, 0x14ad3be7, 0xfec45477, 0xe44739cc,
- 0x8b52444e, 0x284de4eb, 0xbdb7836f, 0xf0032bf7, 0xf7c1d29f, 0xec49143b,
- 0x3320bc87, 0x73e37fbe, 0x294feec6, 0x5f1e59ae, 0x3e47ca09, 0x6e2265ef,
- 0x48b92cb4, 0x7c32fbe5, 0x62596a5f, 0x53da1177, 0xb43d094f, 0xabef812c,
- 0xdd4cb80c, 0xac7baeb8, 0xb429f381, 0x67bfc2ff, 0xb1ab31bf, 0x611d2ffb,
- 0x299dd76e, 0x609b7436, 0x1f681d9e, 0xe06dbae0, 0xfb8330fb, 0x1dcdc7d5,
- 0x51938266, 0xc455a079, 0x95fdb5eb, 0x571e3ce3, 0xce51f627, 0x10fc59cc,
- 0x48b5a96e, 0x9fe8d5cd, 0x8d3f585d, 0xde77d7e2, 0x759e9b3f, 0xf771f4eb,
- 0xde99acc5, 0x5a94fb6b, 0x7996bbbc, 0x8e5edc4d, 0x600d11c6, 0x94eba8bf,
- 0x7997d42a, 0xe51ab9cc, 0xd5821abf, 0x16cf0c9a, 0x2ed1a278, 0x73b42419,
- 0x02775694, 0x16daefae, 0x50a9e903, 0xed87c18b, 0xb8e73c34, 0xd2a91c79,
- 0xb01ae3cd, 0x471c6154, 0x4518b67b, 0xb7f45fdc, 0xf1ba198a, 0x73f89069,
- 0x1ea953ad, 0xfd6b5f4e, 0x2d9b18b5, 0x648ba718, 0x7dae281b, 0x479be4c1,
- 0x22e4e371, 0xb67c0216, 0x55d79a38, 0x9de27af3, 0x9f88d60b, 0xb854afea,
- 0x64d4c921, 0x376e9f94, 0xe3c6538f, 0xbe9b516d, 0xd21fbf1c, 0xeb97d610,
- 0x464c6058, 0x883fdf01, 0x7376ef7d, 0x7d6175f9, 0xd7b7c09e, 0x9b567284,
- 0x8e2caaff, 0x7f364337, 0xcd5767e6, 0x77c83a43, 0x203f2899, 0xabe3c5df,
- 0x3f821330, 0x44b74aff, 0x6f0711f4, 0x486d1a0b, 0xdf7cad5f, 0x1fc2abee,
- 0xee55f70f, 0x7c1fa134, 0xab67dc1e, 0xdf689a73, 0x24e352f4, 0x72f5bab7,
- 0xf7fcb068, 0x9fb967f7, 0x3c8b2ad4, 0xa1c9270e, 0xcb9f275a, 0x48fbc919,
- 0x83b7be37, 0x68f3809d, 0x6ed0cb95, 0x9da37e99, 0xdc74d1e6, 0xc6e0714a,
- 0xa839bd15, 0x7aaa9bc7, 0x203f308b, 0xad08bf1e, 0x682fc9a2, 0xff06eb57,
- 0xd884ed03, 0xc547e476, 0x7efa07ef, 0x3f454ee4, 0xe781cce7, 0xb01d5f50,
- 0x7f82be92, 0x38c66d3d, 0xb23c91cb, 0x023ac6a3, 0x305db02b, 0xa3f77ba1,
- 0x70b76879, 0xcbb1a9bb, 0x617681dc, 0x3ecc4b6d, 0x06dffe1b, 0x5b1bbefd,
- 0x77f14c97, 0x5f7faed6, 0xbbee33bf, 0x6d70fb21, 0x4c5bceb4, 0xefc8b181,
- 0x9f6877a0, 0x81835cfc, 0x64ebb7f6, 0xb79462ef, 0x7b7aace7, 0xaf839cfc,
- 0x9addcfd7, 0xc22de13d, 0x0f2c1e75, 0x116f6759, 0x819d73ae, 0x69fb6205,
- 0xf58675c4, 0xf9d6265d, 0x8b9313dc, 0x3fdf9d70, 0xd708b930, 0xcdb18b79,
- 0xa8f37c87, 0x1b90f033, 0xe99bedfa, 0xf70a7b27, 0x2e8f913d, 0xc40f1e95,
- 0xff81e3d1, 0xefa47a3d, 0xc787d246, 0xebd0e106, 0xcd49b743, 0x6b507942,
- 0x5ea17f31, 0xe361bfc4, 0xc5331678, 0xfa7f8e3b, 0x5047c6e1, 0x64c9740e,
- 0x1dfd688f, 0x68050257, 0xd57f1d0f, 0x23490de3, 0xed18bff7, 0x07da0aad,
- 0x455c610c, 0x7b3403f3, 0x9f1e5e32, 0xc779f312, 0x7b42abed, 0x8dc6ebfc,
- 0x4b3bc5eb, 0xe76e43f8, 0x3cbc95ee, 0x7149dc6e, 0x0b63a6e4, 0x7e27189c,
- 0xc6e3cc27, 0x52944f4d, 0xfc21b8dc, 0x2de6374c, 0x89c92eb1, 0xdec347fe,
- 0xdb171337, 0xf82e7ea3, 0x5f236fb5, 0x3f7e8b31, 0x99f09de9, 0xc13b3ac4,
- 0x71ea157d, 0x42623b9b, 0x7f026fba, 0x9ad4f30f, 0xec49c894, 0x28cdc9b7,
- 0xb0fca31f, 0xf2d3ffde, 0x4df876a2, 0x74777724, 0xd7946149, 0x5e40a669,
- 0x9635ea16, 0x8b6b3ce5, 0x6ec7d9f2, 0x77f71b9f, 0xbedbfba3, 0xe4c771ff,
- 0x4f6ef51b, 0x35edfa22, 0xe5139f32, 0x908776d9, 0xb7c90a67, 0xc2ba778f,
- 0xb788ff3c, 0xedcc38ff, 0xef2d0684, 0x0add6148, 0xb9e2d7ac, 0xbd70d7be,
- 0xc777de51, 0xb2d8fbc9, 0x14bd2fb6, 0xf6e3d1f7, 0x0ddb63bf, 0xecc7e7ee,
- 0x61faeb7f, 0xb96aa5cd, 0x5f5bff7e, 0x327ee21f, 0xb2f2c3f0, 0xeb6afd28,
- 0x936fd1a0, 0xeb074388, 0xf483df4f, 0x392c3c1b, 0xe65bbed1, 0x0cbbf4e5,
- 0xc4f32dfc, 0x3acefca1, 0x238979f5, 0xaa697ff1, 0xcb07ff9e, 0xeaf8a0ff,
- 0x9c9aa915, 0xcdaf7ce4, 0x0fdb8b5f, 0xe24bb3ce, 0xaf37197c, 0x3e353f78,
- 0x99f9aede, 0x6f0f2a97, 0xe387841c, 0x0ffcb063, 0xc6b78796, 0xfda465e1,
- 0x0f2caf8c, 0x35f797ff, 0x35b63a1e, 0xb40efd11, 0x594fd1e3, 0xf3c8cfb7,
- 0xb1fd0023, 0x64b3c5fb, 0x9fef8fbb, 0x7ebd5aca, 0x259d5e1f, 0x5f39e1f6,
- 0x4c84f33f, 0xf628d6eb, 0x398f1b89, 0xdeb4d8bc, 0x69f684be, 0x6f4ff7e3,
- 0xe1660763, 0xa3efc552, 0x2e7e432e, 0xd4fdf2f8, 0xbcc1d4d6, 0x5bcc3c85,
- 0xcbd2aca8, 0x1fec67f9, 0xd66204a6, 0x1c04aabd, 0xdbe86182, 0x725884a2,
- 0xa9adfbcc, 0x467eaedc, 0x4c78f7e4, 0xa5e61d6c, 0x7cd8726c, 0x0c78cfe8,
- 0x47e8ff3c, 0x28edfe29, 0xc0aa2d17, 0x32ef91eb, 0x21e5e003, 0x95c92763,
- 0x8bdda350, 0xdf8b5072, 0x2c7ffd68, 0x592ec1f6, 0xfbd1c7ff, 0x7a65ff81,
- 0x53cfc78f, 0x755f78da, 0xe01b6edf, 0x8c17c746, 0xdc45f8e8, 0x4a1bca5f,
- 0x33f523bf, 0x9cbf1d12, 0x95217fea, 0x226fa2e4, 0xa25c2be5, 0x4795b19c,
- 0x889c60ce, 0x18ab341d, 0x0938c4d7, 0x190dc7e9, 0x5bd26f22, 0x80f29b39,
- 0xbf9895bd, 0xf3fe06f5, 0xc8ed91f2, 0xe1f5c1be, 0x88df6476, 0xecf5f3eb,
- 0xfe9dbbc8, 0x7d6748b3, 0x6f947cd3, 0xf001d6be, 0x0bf87fa3, 0xd3b4779e,
- 0xa773e9ca, 0x2d92e9c4, 0x78a4b94f, 0x7471a7cb, 0x91ffe9f5, 0x8da4b51c,
- 0xbdfe5764, 0x125fe8e5, 0x723a7e31, 0xa79e213f, 0x7843d55b, 0xd8931c8b,
- 0x76b8989e, 0xe0cff310, 0xaf010cfb, 0xe123fef6, 0xf34c2c37, 0xfbc1a665,
- 0x58b35ff7, 0x3e981258, 0x362e5ce5, 0xafb4edf9, 0xf3c9d4d0, 0x30569a5f,
- 0x184de392, 0x78c12d37, 0x98b66ce2, 0x428189e2, 0xfb5b93cc, 0x27243dba,
- 0x0e7dbc61, 0xffaf3b43, 0xdebe5e35, 0xfec62815, 0x697a2b83, 0xce7da31f,
- 0x5587947b, 0xf787f9f9, 0xbc139754, 0x9b704f14, 0x6e25e7f5, 0x0efbe34c,
- 0xa69fd3da, 0xe28fbbad, 0xf3d7eff9, 0xdba0e2bc, 0x84b8c4e7, 0xa9b70f16,
- 0xd0afb43d, 0x6f1b9074, 0x0f9f3295, 0xd11669fb, 0x69c1d353, 0x653718a5,
- 0xb452d69d, 0x6cff2b77, 0xfdefbf27, 0x4f2932bb, 0xe04a68e2, 0x51d7846a,
- 0xed16be1e, 0x07185cd3, 0x0ff7deed, 0x708a5b5c, 0x0b6ff26b, 0xfda1cdc6,
- 0x1e3e8716, 0xdf3c2cce, 0x51d1e1bb, 0x1abcdc5a, 0xf045b3f1, 0x55b7b321,
- 0xef861ece, 0x974f7e35, 0xfa7fd40d, 0x3fb42df7, 0x2d83c9ae, 0x14b01646,
- 0x24c8e544, 0x74183f91, 0xaec5fc8b, 0x453f3cd9, 0xa9e2ed94, 0xf71df3e1,
- 0xaf3849cc, 0x37ca6949, 0x4a72c7db, 0xac7dd8f6, 0xea0148bf, 0xd0c4f317,
- 0xa515874f, 0x22ed8b78, 0x9df3a3b7, 0xc723a226, 0xa7f7c63a, 0x9ed08e80,
- 0x33d222bf, 0x59e6093d, 0x057dded8, 0x45f8f7e2, 0x3293ad03, 0x97da45fb,
- 0x78f89249, 0x5b7a1b05, 0xc61c60c7, 0xb895caf9, 0xb39b6a94, 0x36f8b70a,
- 0xa477fcb9, 0x1737df11, 0xff5578e3, 0x9379e461, 0x5f146cc7, 0x4659cf68,
- 0xaffd9379, 0x3ee7759b, 0xb6219fe2, 0xf324f29a, 0xf691ff0f, 0x25071c07,
- 0xe7b4de1d, 0xbe76697d, 0x99ea156f, 0x5735b945, 0x2abe49b8, 0x421cfec7,
- 0x5569437b, 0x16b0f250, 0x4560cfa3, 0x518ab5f9, 0xbb747f3c, 0x95eb80d3,
- 0x0662f22b, 0x6275ff8e, 0x6d15fc80, 0xf3cc203f, 0xf7bd8c9a, 0xaca61fa0,
- 0x842abdea, 0x65d071eb, 0xa9b8c268, 0xf144d231, 0x8a366396, 0x2e1ee6af,
- 0x282dfd58, 0xd273aee7, 0xd1c0d7fe, 0x6f94b9a5, 0x3d1cf30e, 0x4cef3ccc,
- 0xcd4879e3, 0x63945e82, 0x33ea0336, 0xe2f33365, 0x3e2d79e8, 0x7ef802e7,
- 0x3a2153b4, 0x0816985f, 0x9e0e7ae3, 0xc09e596f, 0x3c28b7cf, 0xfe58e23e,
- 0xdcf12ffa, 0xb7116ec8, 0xfc7c713d, 0xb5f38a1c, 0xfde2122a, 0x51e78b82,
- 0x3fa6963e, 0xf7c51087, 0xcd47ca09, 0xae47f63f, 0xf60da0bf, 0x7d3918af,
- 0x0eeead28, 0x3bf6278c, 0x7b7f9402, 0x4cb74b65, 0xbece63fb, 0x18d5aa07,
- 0xd71b66bf, 0xb9fb4d27, 0xc7ef1e1f, 0xf91e997c, 0xe13ca0ed, 0xfcb0647a,
- 0x7a4fb20f, 0x57c7f4e2, 0xde984ff6, 0x53b78baf, 0x21b8fde2, 0x7f5c7776,
- 0x5a2bd923, 0x745549be, 0x3b376e1c, 0xa4287b34, 0xb2a9c7cb, 0x166bf38b,
- 0x260fff7d, 0x22ff793b, 0x8d6d273f, 0x7d414aba, 0xe28c2ff5, 0x90fe5a73,
- 0xaa142f96, 0x213d79e2, 0xb7ce8583, 0xe51b5879, 0xdd628d09, 0xb4714492,
- 0xa7df865e, 0x7c10be63, 0xf2d2ffff, 0xcc5dffa9, 0x39264ebb, 0xbf084aa9,
- 0x524cf315, 0xf6f0ee10, 0x77de38c5, 0x159e34ec, 0xc8524cf3, 0xcdfe209f,
- 0xd4fcf3f4, 0x7f7cf5e9, 0x30f41321, 0x390b3396, 0x99e75a5d, 0xcb555f28,
- 0x4cf2d11f, 0x0954bc34, 0x598e677c, 0x5072879c, 0x92d947cb, 0xfb44ade0,
- 0x7b0255a7, 0x90d3e71a, 0x784bf220, 0xf90dedbf, 0xaff7a461, 0x8f127f9b,
- 0x650f2d67, 0x3d206272, 0x5e7a22bd, 0xd11fcb4e, 0x3d6626e8, 0xc71dae09,
- 0x555f3db8, 0x0c79a26f, 0x71475c34, 0x030681c9, 0xd55fbd43, 0x1874e665,
- 0x798ede37, 0xfd8dd626, 0xe52b612a, 0xf87a0bd7, 0xd6167b32, 0xbee318b7,
- 0x2fee5627, 0x7fde03e8, 0x3d276576, 0xa752ac07, 0x33ce893c, 0x950947ce,
- 0x5eb8e9e3, 0x6af31cb9, 0x90123922, 0x0fed84d0, 0x353950d7, 0xa79606f2,
- 0x51ae5e7a, 0x8c0c4f40, 0xa096ec8e, 0x2ddb7fbd, 0x99b48cbc, 0x7d3dfa09,
- 0xe4a84d76, 0x363be81b, 0x2aa36f24, 0x37e2953d, 0xbc50f4f7, 0x72bbe848,
- 0x0cd91f2e, 0xabc79873, 0x9d9b8a54, 0x3b23c8ca, 0x7f9c5ec0, 0xb3eb07b0,
- 0x836714cc, 0x53ffa27a, 0x7af1a7a3, 0xcb3faf95, 0x0dfcf072, 0xf9421bd6,
- 0x1a6f2a76, 0x911babc5, 0xb29ec03f, 0x7073023b, 0x3d49cf5d, 0x9c3f2277,
- 0x25cff99a, 0x0ee7e748, 0xe510b4fd, 0xb02635cf, 0x379187d3, 0xde5c1969,
- 0xebed180c, 0x65e7e824, 0xd8fbe07b, 0xf9b6abcf, 0x7cd530b3, 0x1334ca5e,
- 0xa1601d1e, 0xff28c85f, 0xb9fac552, 0xd1fb72e6, 0x612fc335, 0x2b1ae81e,
- 0xa0352387, 0x099ec8f8, 0x03be95cc, 0x09235ff3, 0x49a986fb, 0x6aa887e4,
- 0xcb21fa12, 0x5946b9c4, 0xf82cb7f0, 0x7b2b0ffb, 0xd830150a, 0x2cdcef2e,
- 0xdedfe70f, 0x686fe718, 0x5ce94dcf, 0xd591cf4e, 0x6e1f4809, 0xd7df91e3,
- 0x26c93ac0, 0xbdf1186f, 0xfb41db26, 0x2a3b4fb7, 0xafd0bd3d, 0xe52ffb94,
- 0x26bd5798, 0x71ca5ffb, 0xf64e4d9f, 0xe531fc7a, 0xf52ae94d, 0x21db0337,
- 0xe5cd6cfe, 0xbbfd7f18, 0xfd0497f5, 0xfefd7c95, 0x7331fb06, 0x225996b8,
- 0xddf00a39, 0x03c0d6cd, 0x16177eb8, 0xb3fb49bc, 0x7a9e6677, 0x4e2bf303,
- 0x88cf9919, 0x9c432472, 0x8ebd033f, 0x75cc9ee3, 0xce53f3f1, 0xb113d36d,
- 0xf2e9c05c, 0x7da6165a, 0xfcb99af5, 0xacf5e3bc, 0xda17a5a7, 0xaa31e35d,
- 0x71fc31bd, 0x5f2faaad, 0xd72fac5f, 0x7f8e3c88, 0xdfdfeaf2, 0xd20a22c0,
- 0x7ca7b7e9, 0xfdf62636, 0x2fdf5653, 0x929e8f90, 0xe867de78, 0xfb24e672,
- 0xd0852dd9, 0x64ff199e, 0xc9ff38a6, 0x55ff13f3, 0x4e4f5ff8, 0xb69f5461,
- 0x82c7b2df, 0x2d9e22f5, 0x1ef1fa8b, 0x264dc966, 0x30fa49b9, 0x473c8922,
- 0xb0f1ed37, 0x793bb743, 0x9ada175c, 0x0b439fa0, 0x9a4bc254, 0x42aec0dd,
- 0x10b72bfe, 0xbe7469ff, 0x0af40ac6, 0x651ca978, 0x5dfa4049, 0xc36ef463,
- 0xb304e4be, 0x5a6ffa8a, 0x96fa85a2, 0xfe90a67f, 0x33356558, 0xdc4f9427,
- 0x68654097, 0x44e07247, 0x718c2985, 0xee4235ee, 0x481bf7cb, 0xcc2a567f,
- 0xd01b798f, 0x9fdf1bae, 0x3b50b0c8, 0x7c5cd298, 0xf1a8ca7f, 0xf28534d5,
- 0x1aec0538, 0xf488c13f, 0x57e0ab7e, 0xb3cdf059, 0xfb8d0700, 0x7141dc82,
- 0x05bd5530, 0x632de7cb, 0x70511ce8, 0x629b9cf0, 0x9d8ac1c0, 0xf8bbdf82,
- 0x3f8d3339, 0xd2017935, 0x28b710ad, 0x6d0e3125, 0x3ea1a7af, 0x6b5f6466,
- 0x07edaafc, 0x76b45b66, 0xcffb0f8a, 0x3cd9df10, 0xdcb84279, 0x47fca668,
- 0x7aea5ef1, 0x1fa413ee, 0xaf77af8d, 0x3d7c40bd, 0x3fc5df14, 0x0e75f2a6,
- 0x98f7c727, 0x391fe42c, 0xea164c61, 0xaf2e359f, 0x17298fea, 0x4bcff903,
- 0x3b407c46, 0x7d58df28, 0x918950aa, 0xe70f36f3, 0x4be76857, 0xb09f7c01,
- 0x67c859aa, 0xc8db8cc3, 0x7dfdb5c7, 0xb8c0f5c7, 0x0384eed0, 0x7b7685c6,
- 0x436ee6ad, 0x4fe370e2, 0x2fbc7151, 0x6eb1971b, 0x04eb9e22, 0x420e815e,
- 0xe13a3718, 0x5e3d1030, 0x4f7bf227, 0x58f1f2a4, 0xa65f3eb1, 0x40d0e810,
- 0xfcfa58f9, 0x9da46b98, 0xb6efa82d, 0x20f7135a, 0xe8273ddd, 0x67eda4e2,
- 0x3cef6885, 0x59e8bf37, 0x92b3eb94, 0x9120b556, 0x893ac75c, 0x757935ef,
- 0x4acde321, 0x1adc832c, 0xbff581e7, 0x7cd4ff33, 0xd759fcec, 0x5fd442d6,
- 0x7bc60f20, 0xafc28752, 0x37069fd1, 0xfbd221d2, 0xc1c61d20, 0xbb11d1af,
- 0x0b1293a1, 0x88bd8177, 0x047ecd4f, 0x91e7884f, 0xf9d1d9ab, 0xb2cf1101,
- 0x3479f334, 0x6bee0884, 0x9e500f5c, 0x0199e5d9, 0x69d6079f, 0x720fa4de,
- 0x59ec6c14, 0x76e30630, 0xffb4ef00, 0xede3784b, 0xa7cb2fe5, 0xb58f891e,
- 0xfb39a5f1, 0x383a9f29, 0xd5f94ed7, 0x693e45d3, 0x7140deb0, 0xc8abf074,
- 0x96626f1e, 0xa9ddca30, 0xf2d5bec2, 0x3c4a8ffc, 0xc27a193e, 0xb18beeac,
- 0x59e68793, 0x1dc794ab, 0xb1f3c15a, 0x46e0ed07, 0x9060ec95, 0x0573badb,
- 0x765ca5ed, 0xd2aedfb7, 0x24a79979, 0x80b43ede, 0x7db3dc51, 0xe45fa8b6,
- 0x58f76b0c, 0x7cd16948, 0x460ef6f7, 0xc8eedff4, 0x594cfaa7, 0x16fdcb9c,
- 0x79ed37d7, 0xbf6c4fdc, 0xb7ea88b9, 0x52c78424, 0x87d88f5e, 0xf5fb81df,
- 0x7f1fb05f, 0xe3f3479f, 0xb0751c78, 0xa38a77fc, 0xb40cea3e, 0x2a2dfd21,
- 0x8118e5f1, 0x3c4cea5e, 0xbaf40a9e, 0x7a6187b3, 0xfa21735f, 0xe6b2d73b,
- 0x44050c57, 0x2e905baf, 0x7a078de7, 0xebd1d02d, 0x97054f56, 0x469708db,
- 0x5a7483af, 0x17379f1c, 0x76fb6308, 0x9b9fe757, 0x32e83fd0, 0x30de797b,
- 0x978c83cf, 0x2cf0310f, 0x6e3c3854, 0xf6782659, 0xc1c4ff13, 0x137c2973,
- 0x8ce9a74b, 0xfc48c7f3, 0x90b0ae93, 0x3fca2ca3, 0x4f03594f, 0x7c83b8e2,
- 0x0bf70f74, 0xdb2dc087, 0xba6e9e89, 0x0517ef99, 0xe3ef5c6d, 0x8c0651be,
- 0x7f8c5b3f, 0x867fab53, 0x96cddb0b, 0xe1ba1e38, 0x1cff007f, 0xabbb3f51,
- 0xe6c6f291, 0x8e9e30cc, 0x793473b5, 0xcd53eda9, 0x746fed13, 0x1e6236ce,
- 0xfd1adcf7, 0x5bbcd0fe, 0x4dd4fef8, 0xccfdf573, 0xa03e1b63, 0x6cd646fc,
- 0xbbcdfc44, 0x8aff5f45, 0x695f7067, 0x3d2bee0c, 0x0329e22b, 0x47c827c0,
- 0xb25d4dbf, 0xf3a076f3, 0x292f3f31, 0xcccf38c3, 0x9bbd86b4, 0x8ee8fca1,
- 0x6dfe5471, 0x747ff7da, 0x1777eb0a, 0x41867951, 0x90c7e7e2, 0x8acf810f,
- 0x2ebe6f2b, 0x89f5112f, 0x4676f7e8, 0x81093def, 0xced0d9f6, 0xf29f3133,
- 0xf888673e, 0x5e22c0c0, 0x0724fd7f, 0x55bded4f, 0x8ceaf8a5, 0xe47cc884,
- 0xff4b1783, 0x90f30cb3, 0x728be467, 0xb0e353d9, 0xc1f4acfc, 0xfd67d47c,
- 0xd705768d, 0xc79329a1, 0x4b17c7a5, 0xe22763dd, 0x7fd12c79, 0x4d579f23,
- 0x91322fd9, 0xf154664f, 0xa77bc67e, 0x3b6016b5, 0xf72a79c3, 0x11125a67,
- 0x19bf1aff, 0xd9a41f84, 0x27217e8d, 0xd9bdf49e, 0xfafd0292, 0xa717922d,
- 0x26f29fe8, 0x9d9817c5, 0xfbf3a79f, 0x6b8c14f2, 0x3cf1f74f, 0xd8ab6dd5,
- 0xb6f3b42a, 0xd653e95d, 0x0b74fd40, 0x7a04f5a3, 0xbd206537, 0x2720fe4f,
- 0xaecc8911, 0x9e8d77a7, 0x3e746b66, 0xc0cf4f43, 0xfefc76a7, 0x8eb5e4cb,
- 0x7a51ad9e, 0x09ce291e, 0xa0646570, 0x5e96f85c, 0x138e0d8f, 0xe3f18fc7,
- 0xf027248e, 0x46de562f, 0xbe24ebe1, 0xbfecc2cb, 0x36cbe402, 0xe1c72f8d,
- 0x1e864cfc, 0x2b943f3a, 0x01d1c779, 0x0b5e29dc, 0xfe38b9e9, 0xc6cbe0d4,
- 0x50d972d8, 0xd14ff0b8, 0xe7fe50ec, 0x9643f8c6, 0x7cef87a8, 0x170a392c,
- 0xf1153f8c, 0xf0e1eec0, 0xb99a92ec, 0x867e115c, 0xd268b716, 0x3f587be6,
- 0x7e04cadf, 0x7183df8e, 0x285bda26, 0xf708371d, 0x3683ac25, 0xdfd0a09f,
- 0x877e2d73, 0x1df6e609, 0xcfd11d57, 0xba834177, 0x811d5d70, 0x279c236f,
- 0xe863a10c, 0x3e622d8f, 0xfa065fda, 0x445467f0, 0x37834bd7, 0x234d4f1e,
- 0xf9f8d1c8, 0xba27e3c4, 0xf8193d6e, 0x0de7ced4, 0xe712f7ce, 0xb89f6f19,
- 0x5f78fa4d, 0x25cb88b2, 0xc570e347, 0x12c35f58, 0xf38714bc, 0xd5bfe44a,
- 0x7281bd80, 0x519aa6b9, 0x6ed9243c, 0x669c38a0, 0x27c48c77, 0x48c55f57,
- 0x632cd54e, 0x9f205ce2, 0xa63d3c5f, 0x931fdeb3, 0xb7516bff, 0xaf7e442f,
- 0xf0f2ebb7, 0x6e3cec6b, 0x1b935ebf, 0xf502b7ac, 0x887960fc, 0x40adef9e,
- 0xff7f13b9, 0x1e45cd57, 0x28be4e2f, 0xfbc6b3d1, 0xf9ea0566, 0x0adeeae4,
- 0x240f5f94, 0x75c5eef9, 0xe3c0c37d, 0xdcf8f1ea, 0xe2d0619a, 0xa74497c5,
- 0x78347cf1, 0xd811dace, 0xf168e381, 0x0f5273a4, 0x38a64f8f, 0x3c81ff45,
- 0x4ba067a4, 0x20669a23, 0x1cff3f27, 0x37fc519d, 0xf726ede0, 0x7b9c9aed,
- 0x18dce498, 0x5cfdd7a1, 0xbe9cf89e, 0x4e1c19bd, 0x021dcbc2, 0x9e85332f,
- 0x2653bf3d, 0xaf86643f, 0xa16e2b78, 0xb2379f04, 0x8fb1f130, 0x8f76a3f4,
- 0xa83079d7, 0x63fdb1ba, 0x4bb7d20e, 0xfda3a85e, 0x0cdb31a5, 0x97d18d4c,
- 0xba09c363, 0xefc641fb, 0x2795d64f, 0xdaea6674, 0xaf9c3a4f, 0x1eed2fab,
- 0xecbfaba7, 0xb95d32f9, 0xaeaa67a2, 0xab57e4fd, 0x7bcbe574, 0x7fb5d3af,
- 0xe03df504, 0xccef5bf5, 0xefffbdd1, 0xc79eb31d, 0x232bdcfd, 0x7f7dd3df,
- 0x5819c446, 0x0c53d7c8, 0xd1a85ff3, 0xdd5ac5ef, 0x74d660f7, 0x0728954b,
- 0x0dc2dff8, 0x1a7d4f3c, 0xbfb62c60, 0x7b7a6d45, 0x508b2662, 0x58535f7e,
- 0xcc3376f2, 0x37d7d353, 0xbc20ee1c, 0x013dd97e, 0x0c0bdc63, 0x197d0f48,
- 0x858c6760, 0x14b0a47f, 0x891bb3cc, 0xfd6cbfff, 0xd7e1588b, 0x47b37f5a,
- 0x5556febf, 0x62b6febf, 0xbc3bfafd, 0x9a4ff5fa, 0x977f5fa2, 0x29febf4f,
- 0x4ff5fad5, 0x3fd7ebf5, 0xfd7e9e7d, 0xf5fa0233, 0x5faf551f, 0xfd66ecf7,
- 0xd72ee77a, 0xe85e6baf, 0x36fdfd36, 0xd1a07471, 0x0b4f2693, 0x7711ddd6,
- 0x19818e1f, 0xa342e862, 0x7afe85b3, 0xdd1a5fca, 0x78dd13f6, 0x8631f4f1,
- 0x6fcbbc89, 0x99851f48, 0x7f981740, 0x3f92cc99, 0x1bef3d27, 0xd43a999d,
- 0x56e4d0be, 0xf58f3eac, 0x6792478f, 0xf094f443, 0x53d44797, 0xa35b2fe8,
- 0x7448f2fe, 0xfd031afa, 0xa06f834a, 0x4ecdd838, 0x0489c70e, 0x887fb76e,
- 0x3b439755, 0xe0053368, 0x03e70d7d, 0x3096bfe3, 0xdf1de29e, 0x1c469d63,
- 0x43d616f7, 0x422cf9cf, 0xea7300cf, 0x642c7dce, 0x7f88937e, 0x8159975c,
- 0x4ade9171, 0x1617a394, 0xf6837a9c, 0xb94c5eb3, 0x4e327ba4, 0x68c97ee3,
- 0xb90acec6, 0x26fb87d1, 0x8ab7ee50, 0xa98fa078, 0x9e7c18ee, 0xdacbf115,
- 0x57e912e9, 0x7e502726, 0x2577ed57, 0xffb54fd2, 0x99759fc3, 0xff1eae3c,
- 0xc35cb35c, 0x0bb09b6b, 0x5f707db8, 0xbbf54aa6, 0xb276aa60, 0x944ebd43,
- 0xdf1fd0ff, 0x44d878c7, 0xc2c7b9fe, 0xa29504e1, 0xe3a64c5c, 0xb8eeb474,
- 0xcbee78fe, 0x4df0e163, 0x22e59850, 0x02cf1fbc, 0x95de1764, 0xdffd4f99,
- 0xe38880ab, 0xfec38ffd, 0x15684a3d, 0xc07fd1c5, 0x5bf471f4, 0xa38a259a,
- 0x85e000ff, 0xf5e9c7a7, 0xcad61ea0, 0x33bc05ab, 0x4fbc1db0, 0x184b34f7,
- 0xfdbafaff, 0x78c3f60d, 0x7887f83f, 0x59a1e2d7, 0x58668740, 0x603fbdd7,
- 0x8f8bcf14, 0x41928e8b, 0x93fe63a2, 0xf7ab9f91, 0x9fb8db28, 0xd4ebd27a,
- 0xd1987dc5, 0xbf20e785, 0xbcc2decc, 0xe731b3e5, 0x87bd600c, 0xe9747fbd,
- 0xbf2fbe28, 0x31676566, 0x4fd88dd1, 0x7ee57bbc, 0x978acb2a, 0x3ef10af2,
- 0xf7cc572a, 0xc7d43726, 0x8762bbf0, 0x90e463ef, 0xcba7eed1, 0xd959ee57,
- 0x4678fb43, 0xdad66f71, 0x819c3bac, 0x2fc77898, 0x631d8533, 0x1a673109,
- 0xfc37a613, 0xe19d33bd, 0xe54ecafa, 0xcb5fac6c, 0x886c979e, 0xcf4146b7,
- 0xd7ba092f, 0x607b36e0, 0x5eb818bc, 0xe8def412, 0x3ce131ec, 0xe8b5825e,
- 0xd2b4b8c1, 0xd3fba6e3, 0x1c93716e, 0x83ac41ba, 0x8dd4a0f9, 0x0acc4ae7,
- 0x5ec5f99e, 0x832fda7a, 0x64bcf726, 0x76efb864, 0x2435c54f, 0xcdc94d4f,
- 0x8fa06ede, 0xc8b4be1f, 0xaf061819, 0x51ecd3da, 0xc5cac42e, 0x5f8532e7,
- 0xc64d993e, 0x1e061975, 0x743f93d2, 0x587e6ff2, 0x7e58f3c1, 0xf94603f8,
- 0xfc396ced, 0x94f14655, 0xf724bcca, 0x2f422c5c, 0x0604ac37, 0xe8f6031c,
- 0x980b0b4a, 0x66b21f41, 0x98d2d3b2, 0x4369e88f, 0x3ade8be9, 0xf65ecef8,
- 0xcff462bb, 0xaff8abef, 0x2a3b2c66, 0xf2c7af5f, 0x758fb1fa, 0x1d9a0e62,
- 0xde537161, 0xe0af1850, 0xaff7184c, 0x3b6357fb, 0x1f798f7c, 0xe01ef0d5,
- 0x574277b9, 0x26dbdb04, 0xeb077d1e, 0x96ddec13, 0xe12ef802, 0x0055e616,
- 0xf2dea95f, 0x74f00569, 0xb02f4395, 0xbdf136d4, 0x37ef0a6d, 0xdd26bf7e,
- 0x43df87be, 0xfb130573, 0x045efca2, 0xd5233f6d, 0x0aada7be, 0xbea156e5,
- 0x8f8141fe, 0xcfe3fb14, 0x303d63e7, 0xad1668dc, 0xbbd4407f, 0x54f78fec,
- 0xdd165cf1, 0xff459bf7, 0x97037649, 0xfb132a57, 0x937ebcb6, 0xf56ab7a8,
- 0x65f6261e, 0xa8ab7d79, 0xde79db37, 0xeeb7b012, 0xfc62b5fb, 0x2c0c5bb4,
- 0xeecf4310, 0x102c09b9, 0x35c91f43, 0xd1b2bac9, 0x3b25cfce, 0xbeea6467,
- 0x5bbdfad3, 0x45789b8c, 0x4b3beebe, 0xfb7d38e1, 0xcfa4c9b9, 0x367810ee,
- 0xeae99565, 0xacfef3b5, 0xf273b45d, 0xaa7b8a76, 0xaaf3dfae, 0xe072849a,
- 0xdd1ae5ec, 0xb7482d7a, 0xd3f23877, 0xbc21bf71, 0xa3353a12, 0xa788b13c,
- 0x683d3c53, 0xa553c05c, 0x7b889e72, 0x853959ae, 0x6e807bca, 0x95a1feb1,
- 0x82ef2a5e, 0x9fcf0ab2, 0xbc2a3f43, 0x60fd0edf, 0x83f42b79, 0x1fa107cf,
- 0xe3003e7c, 0xf866fd61, 0xa09bcb0e, 0xb7df2c3f, 0x7be547d2, 0xb9535657,
- 0xca9fa575, 0xa3ce576b, 0x032bdde7, 0xb2b35cf4, 0x8e67ea9e, 0x6bedfae2,
- 0xb39405e7, 0x9980bcf8, 0xe7a22aa3, 0x80bcb43a, 0xfef0d30e, 0xb8a3cddc,
- 0xfe65cc1c, 0xfe9c2da7, 0xecc89ee9, 0xa34f9d0d, 0xe7e29bdf, 0xa1b191eb,
- 0xd55dea99, 0x3bed1c7c, 0xacb10ee6, 0x158c7e4a, 0xea4bf5db, 0x1997ca6a,
- 0xcceae3cb, 0x256a6213, 0xfe974ebf, 0x13e90894, 0x5f2f58a5, 0xdfc3ccf3,
- 0xe3101d53, 0x3ecd85c8, 0x8a658e9c, 0xc4f31bbf, 0x9d00deed, 0x08bdcfef,
- 0x9b1f839d, 0xa62af174, 0xaee2e982, 0xc9d1dbd1, 0x7674ca33, 0x89b17caa,
- 0xbeb259da, 0x72676ba7, 0xd5daead7, 0xc7bbcd2e, 0xc518f883, 0xb0de61e7,
- 0xb8c0658a, 0xd337da8b, 0xbac5ebb8, 0xbdf97cc1, 0x3e2407d6, 0x3dbf615f,
- 0xb5f314ea, 0x3ab9206c, 0x458bc5c6, 0xca032149, 0x9d7ff7c3, 0xc8fafc44,
- 0x478a0643, 0x0361658e, 0x5078d7ae, 0x813f58d3, 0x127952f5, 0x9728574a,
- 0xf2c65532, 0x7e422c65, 0xab6fd82e, 0xe49b9d71, 0x285643c0, 0x3c0ecb9f,
- 0xba91f3ca, 0x8914af49, 0xecd228f5, 0x7c4a6dd8, 0x28dd6f7c, 0xe7f58ff2,
- 0x9bf7e295, 0xd32a3957, 0x1fe8fed1, 0xe6cc7f21, 0x42dcf339, 0xe32dbfc0,
- 0xef6a7a4d, 0xc30d55ef, 0x787de39e, 0xf2cdf494, 0xfbfac33e, 0x1fde81b8,
- 0x2b9c79c6, 0x5e6603f9, 0x08c2a6b1, 0x8c6b09f9, 0x93509c9a, 0xecb63d98,
- 0xf331624d, 0xabe56478, 0xec090a05, 0x764de100, 0xe7cc746a, 0xea527f2b,
- 0x22a63cc4, 0x7fb93791, 0x8ce14665, 0x7befd1d1, 0xb3141d04, 0xc5ff924e,
- 0xfc97836e, 0xe7539f48, 0xdb0b5a77, 0x445e787c, 0x98bcc71e, 0xb5963363,
- 0xf96b39d1, 0x23c9326f, 0x4cb5c4f9, 0xc123bb05, 0x7b216619, 0xfc265fb4,
- 0xf9091fd7, 0x067d91f9, 0x68e72fc1, 0xc8f9e1f7, 0xe9c8f9de, 0xd49e6275,
- 0xfa46ed47, 0xafad3e48, 0x5f7a762f, 0x2e9d000d, 0x22f3683e, 0x6dc50978,
- 0xbca03f74, 0x1259625b, 0x20f3c1c1, 0x6cbdb993, 0x42c956dc, 0x1b579eb0,
- 0xbf098702, 0x8321eabd, 0x5da1fca6, 0xee898a63, 0x78831f67, 0x6e5e23b1,
- 0x43819c2e, 0x1e131617, 0xbf798917, 0x26b1e625, 0x80bfc35b, 0x787cf987,
- 0x76e2e09f, 0xcfd6efcd, 0xaa92def3, 0x4b7d636f, 0xa0f94c8f, 0x973cf8f1,
- 0x44c4a7f8, 0xf1daf058, 0x70046e3c, 0xa0fc85be, 0x8829dc20, 0xb69fbe5f,
- 0xe30a69c4, 0xa97ee039, 0x30f29ab3, 0x7f281827, 0xdf2e9e35, 0xf368f617,
- 0x6d3d2728, 0xcf44b39e, 0x73df72d1, 0x7fc8530b, 0xaed67ae0, 0x9f16bcf0,
- 0xf78d8d4f, 0x28e2d7ad, 0x413f5f22, 0xdf783bc0, 0x479e38d8, 0xdb3d6768,
- 0x24664f30, 0x9590c6bf, 0xc0d7e717, 0x54fd20d2, 0x651f2858, 0xa4e796bd,
- 0x8f29529e, 0xe7989e1b, 0xba741164, 0xb9efc1d6, 0x3a37e6d0, 0xd1d1cb8b,
- 0x06ff9c59, 0x86de5a2c, 0x2634a6af, 0xabb6bfff, 0x6d75fc8e, 0xc4406a3f,
- 0xf4120649, 0x820d47fb, 0x6d9e0614, 0x7dc04aab, 0x1fbe3690, 0x3d75d0d5,
- 0xd8f2efbf, 0x285f7403, 0x3d22a9f4, 0x75f689d4, 0xfafef4eb, 0xe201fda2,
- 0x4078f8d7, 0x980fffbc, 0x1e5da133, 0x67e7ffef, 0xcbdf7f09, 0xe9bf714a,
- 0x938286cc, 0x29b70009, 0xd1b9d18f, 0x74e3f251, 0xa5583bef, 0x26cf786d,
- 0xcaf7e12b, 0x0fffafc4, 0x97844db2, 0xdf5f12fd, 0xf13b68d0, 0x2e0afec1,
- 0x7d3ff607, 0x28d186fe, 0x7d2572cf, 0x91ae713e, 0x818b77df, 0xc9df787e,
- 0xf970f558, 0x0cb23362, 0x5fcf4cdf, 0x8d7b97a1, 0xda4f7b87, 0xd37f9254,
- 0x4f3d70b3, 0x84b125fe, 0xf74228f8, 0x83b9a3e6, 0x78dc21e3, 0xe180e36e,
- 0xf4b1f983, 0x452cddf0, 0x66f86dc0, 0x1e8678f2, 0xaf2573ae, 0xe1c75da4,
- 0xf50b29ba, 0xb4e9f763, 0x0d7c7cd8, 0xc35503ae, 0xf86e2b9f, 0x029a78a6,
- 0x8b0e54f0, 0xc22ffaa7, 0xf0d301d3, 0xc04cfcf0, 0xf2cf6ff3, 0xd6862efb,
- 0x6dfb437f, 0x1efe1c67, 0xc509b9eb, 0x33fbc036, 0x2fa79fc2, 0x04c2f68d,
- 0x05cb3afe, 0xf90b967d, 0x895f25e3, 0x4c9f5f05, 0x0a9d64f9, 0x72c1a94b,
- 0x2aef42e5, 0x4a7f7a35, 0xfca010d0, 0x79baf67c, 0x4477f958, 0x990385c8,
- 0x3878b0d2, 0xf4f9e628, 0xa8b9b58b, 0xd57dee67, 0xb42e50cc, 0x5efdfb08,
- 0xef05a767, 0x88f0d59f, 0x067832e5, 0x5ec5914d, 0x647f972c, 0x8cc3ed51,
- 0x6de3e067, 0x6d1be38a, 0xabf9ed3c, 0x0fae62ac, 0xcc6567a5, 0xc574dfdb,
- 0xd42f742b, 0x648572a6, 0x7fc6d7ef, 0xce5e9ebb, 0x7692bf75, 0x5f97a703,
- 0x4934bd21, 0x1b7e256f, 0xf22941ca, 0xcbee0972, 0xff34029b, 0x43b1e020,
- 0xeda78a1a, 0xf9b45e82, 0xe0d7f369, 0x90b95c76, 0x9af1c1d6, 0x41c69499,
- 0x17d35ed1, 0xe1ff4249, 0x5c5f48bc, 0x0f73f0a1, 0xfbad0a15, 0xe95329a6,
- 0xb101ca5c, 0xdcb91e2f, 0xf83dec34, 0xf76f027d, 0x0f63fc5e, 0x2ea1b5fa,
- 0xc00bdd23, 0x8dcf5e94, 0x4bf12f78, 0x0c33dd0a, 0xf78d54f4, 0xe2fd3d1c,
- 0xf3b444f9, 0xf2e2ccde, 0x2e2ccdec, 0xca2e070f, 0xe45e74d5, 0x729c8fc5,
- 0xce9ffd0c, 0x4d3ec592, 0x039e0f4f, 0xf3c658d9, 0x1ec2eddf, 0x57d8bfb0,
- 0xa7dbf08f, 0xc52cc4fc, 0xb21fdbd0, 0x46d704cc, 0x0bcd2453, 0xc98f05fd,
- 0x82ec9bac, 0x6dafba5e, 0x939b9cf0, 0xfca9a1e3, 0x8ef68659, 0xe3df8bbd,
- 0xe54b3a76, 0x3ee01672, 0xc613ef04, 0xc3ace47e, 0x2f1872fa, 0xc3bdfa3f,
- 0xa133d7c9, 0xb2a3df82, 0x383f8ae9, 0x24b89ef1, 0xc7fdd189, 0xea36c83f,
- 0x57ada1ce, 0x2cec1cb9, 0x3b41e9ef, 0x2854e42e, 0xfbb3a72f, 0xfbda0b0e,
- 0xf2f85f1a, 0x8ad7bcf8, 0x4ed77cfb, 0x39e30e29, 0xd78e8d14, 0x202e0764,
- 0xbe046edf, 0xafec9c78, 0xc274ff1e, 0xf314b38f, 0x1eb0275c, 0x9586afba,
- 0x87c89c9b, 0x8e8306c5, 0xe6c9aedf, 0x413da374, 0xf3dd93fd, 0x9abb4163,
- 0x2c3b97de, 0x7db5cf0c, 0x1276717c, 0xb672a7da, 0x9d79ef66, 0xed8fc788,
- 0x7c4ec973, 0x0df6b7fb, 0xda0779b1, 0x73f02df3, 0xcb44c7bb, 0x59febc8b,
- 0x0b317ed8, 0xe97683dc, 0x775976e2, 0xc16dffde, 0xda2e8be7, 0x9d8c7758,
- 0xf7ca68bf, 0xa2d2bce8, 0xfef4898b, 0xf49f916d, 0x2a4bc8b6, 0x8af0f314,
- 0xdfd915e7, 0xc6f7fed0, 0xff5dcbc9, 0x972d48f9, 0xd0d98597, 0x6bd4a36f,
- 0xe36a7f42, 0xb9d0bfd4, 0x7fc0b791, 0xd17f36ef, 0x7758533c, 0xed83b8cc,
- 0x77595a2e, 0xa8baec4a, 0xbe747704, 0x6b7faa76, 0xf04be7a5, 0xc7874a38,
- 0x3a05ff68, 0xbfed0e3c, 0x5adfea88, 0xfd25fc59, 0xffa11f8f, 0xd1fc1d3c,
- 0x7de90b7e, 0x47da89ff, 0x272fc06d, 0x78ef57ba, 0x8eebf30a, 0x7cfee99b,
- 0x8ab3b876, 0x92fdafce, 0x3bc6b9d1, 0x06f27f8f, 0xb9ddcde6, 0x31c5e4c7,
- 0xf9918c06, 0x43f461de, 0xf0867321, 0x79ed291e, 0xcd017643, 0x45bdfe27,
- 0x0f313b09, 0x38ac52ce, 0x58593f51, 0xf135784f, 0x93e48583, 0xfad79716,
- 0x2672871d, 0xf76a3e46, 0xf62bbc85, 0x0b60ff8d, 0xc0aecc2c, 0x8157f732,
- 0x9c623773, 0xd961e1ad, 0x7421efc9, 0xc5a23f91, 0xf3f415bb, 0xe3d4300a,
- 0xe3fe7867, 0x4b03723f, 0x0e7e6e91, 0xdfe300e2, 0x01bd84f2, 0xff0a4f8a,
- 0x8f6b3eef, 0xf7231bc7, 0xdf2b6456, 0x8b6fdf4c, 0x7f1537d3, 0xeb9ba47a,
- 0x8f38159b, 0x57e7b946, 0x8e7879b5, 0x1bdc57a9, 0x5bdd92a5, 0xee927e5b,
- 0xfcd5ab97, 0xfbf175f9, 0xb42ed9ec, 0x7cf8b583, 0xa13fe622, 0xf3c8dfbe,
- 0xbc6cebef, 0x14fbf75c, 0x4789cf3a, 0xef104a45, 0xdf97b29d, 0xfc24e82b,
- 0x0f30179e, 0x20e63658, 0x9e04077e, 0x433d77cf, 0x5f9e18f7, 0xa0e89a37,
- 0xa53f37ee, 0x640ec97b, 0x63acfc8a, 0x7543d20e, 0xde256f66, 0x93207793,
- 0x4a9d9bdb, 0x8c596277, 0xab36b9fd, 0xfbebe48a, 0xd01b46eb, 0xbaf0d73e,
- 0x8d85c853, 0x89503c5a, 0x6dfde254, 0xbf7797ef, 0xa0f07a4c, 0xc6e77e95,
- 0x4a93e870, 0xa3714fba, 0xafa5ee99, 0xcb76343a, 0x2c6fa83c, 0xa8be5032,
- 0xe09590e1, 0xdf9eb739, 0xa2df84ef, 0x343c6ebe, 0xa80f7e8a, 0xbca116ce,
- 0x6f04c6ae, 0xd497ee11, 0xdd16fa1d, 0xbee67f27, 0x372839b1, 0x39aaa74f,
- 0x7dee7f74, 0xf7987480, 0xf86363e9, 0x74c9d6fb, 0xd1b1d25e, 0xae2e1816,
- 0xf893e9a1, 0x640ea3fb, 0x461ff696, 0x78b58cfc, 0x917940f7, 0xb8b03f76,
- 0xf9eeac0f, 0xf3151cc8, 0x557f85ac, 0x33ef7f67, 0xfdadf7ba, 0x3d385bcd,
- 0xcd027df3, 0xb71f8b3f, 0x039de84e, 0xfc7cc8a6, 0x35baa67d, 0x9e26ff02,
- 0x28675687, 0xd327dfa5, 0xee31bff0, 0x0457d57e, 0x99e7b5de, 0xb7ba1517,
- 0x1c81ec0e, 0x733a57dc, 0x76f44cdc, 0x3a78e366, 0x578dad2f, 0x0271b807,
- 0x564e9e9f, 0xfefae227, 0xbaafc859, 0xd4efdc35, 0x3619d7de, 0x477ae357,
- 0x6f94c98e, 0x248ce033, 0xd6887ee2, 0xce0f2b4e, 0xdfa64ba7, 0xf9903a19,
- 0xd03bad34, 0x32ba4315, 0xfa41c6fc, 0xfe1bf836, 0x97ef457b, 0xf50d90b3,
- 0xf266abf4, 0x331c4ed3, 0xf03c1d93, 0x3b773f1a, 0x7b2f1ee4, 0xadef0724,
- 0x1466fe0c, 0xec81b5c9, 0x376e6ec8, 0xb8dee95b, 0xc9815381, 0x432cff62,
- 0x81978bdc, 0x6385daf6, 0xd7b46ed6, 0x20fb49e0, 0x43d7b621, 0xe8db8fef,
- 0xd2780ffe, 0x1d260939, 0x9cefd0f4, 0x7df136b0, 0x677f7d0f, 0xca0c604e,
- 0xa00b3be9, 0xdf7e3b7f, 0xe42eed47, 0x19612607, 0x78c532fe, 0x766fd499,
- 0x4bde9720, 0xeff8791f, 0xfa89b47b, 0x9a0faa1e, 0x1e699303, 0x8eb0767f,
- 0x4df9e661, 0x2f7b7fef, 0x9be4853b, 0x99e03706, 0xbc78bfec, 0xe20c7278,
- 0x3e385df7, 0x7072e9e2, 0x3e04bf3d, 0x5f90a78c, 0x71d7c5d2, 0x971358fd,
- 0xc9e3ad27, 0x431ba5ce, 0x569af262, 0xe89b7b1d, 0xdbe8c072, 0x72297a8a,
- 0xbdf8c8ca, 0x6019606a, 0x6f0a619c, 0xfce36757, 0x9ef1c1a4, 0x686e6fc8,
- 0xef4f79e5, 0x9cede2fd, 0x273c7605, 0x9ceeb6fb, 0x83f716ac, 0xae31124e,
- 0x89aaf762, 0xdedc25b5, 0xfe2e0996, 0x8d1b4dfb, 0x554efd2a, 0x14b1bee8,
- 0x5263384f, 0x8ebdd10f, 0x901827eb, 0x5cbd5a9e, 0xf8da84f6, 0x9afbb4bc,
- 0xe2977bb4, 0x9cddf2f1, 0x38bbfe02, 0xde2b702c, 0xa99a7dd9, 0x8db36269,
- 0xc7ab9fee, 0xebca017f, 0x2b3e0d0b, 0xbd25bfcf, 0x379ef430, 0x8efc97d3,
- 0xf96dffd5, 0xe68cb907, 0x250dead9, 0xc77d5ea2, 0x583efdc9, 0xbbf4953d,
- 0x7749e7cc, 0xbea066e8, 0x939adff6, 0x0724f54a, 0x7d7891df, 0xf2699d3c,
- 0x903e086e, 0xfc5fb06e, 0x3dbefa0e, 0x48d5c787, 0x79bde058, 0x7ba2642c,
- 0x0abe8461, 0xcf018a4a, 0xd4b9f775, 0xbecba444, 0x55e482d6, 0x52e0a798,
- 0xe862cad3, 0xa32cf824, 0x9e2accf3, 0xbf8c984f, 0x889be273, 0xc903bcf1,
- 0x3c4238fa, 0xeb4f8f3c, 0xff5b1f9d, 0x772e1cd3, 0x1fb8735b, 0x261cebf8,
- 0x3c78feec, 0x22583a72, 0x1bd5a0e8, 0xcafc8ab8, 0xb64b76b8, 0x88fa0925,
- 0xd4f6df7b, 0xcabe533f, 0x85bdfd4e, 0xde3d6235, 0x9214de79, 0x8133e126,
- 0x37eb8df2, 0xff577973, 0x5dd14d42, 0xfce74cbc, 0x4ddc75a7, 0x70b30fbf,
- 0xc622cccf, 0x8bad17e5, 0x730b9f46, 0xdf68457c, 0x4ecbb645, 0x6dfa93e4,
- 0xaad3c132, 0xc3b659b4, 0x8cdbb3fb, 0x0bd5f764, 0x0566ce78, 0x14dd6912,
- 0xef0098a6, 0x22409567, 0xc5dbb5d9, 0xcdc4e0ef, 0xa2bdda03, 0x1f830d94,
- 0xc2675f0b, 0x7430c14f, 0xeb40ca70, 0x898130b4, 0xe89347df, 0xecd9c79c,
- 0xee58adc0, 0xee9e7f03, 0xa06b6e9f, 0xf1e2557b, 0x2012d67d, 0xe6225d7a,
- 0x7e33e1a3, 0x039f0d1c, 0x9fb44f88, 0xfa41df9e, 0x8ca0f82f, 0xee9ecc14,
- 0xecfc90fa, 0xbe66c769, 0xbf7c2df1, 0x1518ec19, 0xcbfe6df5, 0x077d47df,
- 0x98ed0a72, 0x690563da, 0xa36f4e2c, 0xd2fb593f, 0x8c4344dc, 0x976d6cbe,
- 0xb5a59f69, 0x22e24e70, 0x06fe7f6a, 0xaad3afa4, 0xa62cad37, 0x9a392bdd,
- 0xaf5fa93f, 0x4d7fcdba, 0x37ea71c4, 0xda5e6918, 0x4c000cba, 0x6cdb8724,
- 0x81ffa461, 0xabf508ac, 0x7d20d3ad, 0xf4683ae3, 0xcd3eed04, 0x78718a71,
- 0x2f2fb6bc, 0x861de950, 0x003f164e, 0xdb7f62e3, 0xe69f741c, 0xe1ab8ea5,
- 0x05bd7063, 0xd719535f, 0xc51e7771, 0x14a70dc7, 0xdd3f064a, 0xf20e4d76,
- 0x07d81d71, 0x93a88718, 0xbdd06f22, 0x74ccc7a6, 0xe6dd6fef, 0x78e2b7a5,
- 0x0d99af75, 0xfc77df58, 0x5704899a, 0x9e02badc, 0xf7a38672, 0x8e48bc81,
- 0x607f0637, 0x6b7f1057, 0x9b8189f3, 0x8b3f00e0, 0xc819c5ee, 0x918cf583,
- 0xe1cd7f03, 0xef681af1, 0xf37d1134, 0xe706997b, 0xaf9b8ceb, 0xafbe6e33,
- 0xe66fa230, 0x167cd00d, 0xe0366ebe, 0x5ff785fb, 0xb771845f, 0x69d3f5be,
- 0xbec97d5e, 0x7d5fc889, 0x30ffd039, 0xfde172f2, 0x2f92cf30, 0x959b6798,
- 0x79c46bd6, 0xb3764726, 0x27a7982f, 0xb7cf3f57, 0x7e913514, 0xcc88e34f,
- 0xcc128e30, 0x16fc6ff6, 0x97efd32f, 0x1e9c8d05, 0x746d9b82, 0x8bbfaa2e,
- 0xc9af8fdf, 0x12ef1801, 0xf440c1e9, 0x6ea557d0, 0x75f48299, 0xfdc4ec9f,
- 0x97f5be8a, 0x2fbf8cbd, 0x7651b7d7, 0x57d0dda2, 0xf207f1c5, 0x5f78f480,
- 0x2a06ff8e, 0xefd2371f, 0xfb699da4, 0x3ee89feb, 0xfa466382, 0x3c81e23d,
- 0x5879c6ff, 0xae517806, 0xe26e5e01, 0xe691ab76, 0xc1eebadf, 0xda1f5875,
- 0x6fce8936, 0x7ad7d50c, 0x906fd73c, 0x14c87c75, 0xde0bc695, 0x17ee8a3f,
- 0x120cf0d1, 0x23fd08b6, 0x9e581f0d, 0x978a213b, 0x8f7f38a0, 0x8fbf0276,
- 0xc433c84b, 0x13d73e4f, 0xe5058e78, 0x19a79e18, 0xcbc55f49, 0x7bbd789f,
- 0x4fb6ae63, 0x0dc797a9, 0x79afbf71, 0x69795c5b, 0x1658dc9c, 0x5718df57,
- 0x86f9fa0f, 0xcfd2e2e1, 0xa2cf8e0c, 0x1a21927e, 0x4fb81d1f, 0x56b4bf22,
- 0x07e84d51, 0xeb8d3e3d, 0x59853ae7, 0xe4be22ae, 0x156a73e7, 0xc32e62d6,
- 0xac535ef7, 0xb5fd04bf, 0x9ca19398, 0xb410e5c0, 0x94c536ab, 0xc1ab7935,
- 0xa3c04ab3, 0x9c76bf3d, 0x7dc466a0, 0x15b9558c, 0xca31f743, 0xbf5ffce4,
- 0x11d67e88, 0xe0ccfc99, 0xb0ff5c0b, 0xf2dc3f4f, 0x3bef1b98, 0x323ca02e,
- 0x78f1fe6d, 0x61fc381c, 0xe4defd22, 0x5f3a26f3, 0x5295db5e, 0x72587e45,
- 0x6fbc5864, 0x44fae5cd, 0xe95fafeb, 0x6b1d9c4d, 0xc4deb347, 0xadf7dfd8,
- 0x4ae1fc3d, 0x7f016bf4, 0x8e463921, 0x5a96399f, 0xdd65fe85, 0xf0ab32ef,
- 0x5cd1efbc, 0x3ea00e2d, 0xe6f901bc, 0x13e29988, 0x33cc2ffd, 0x2ffdf7e0,
- 0x9de78bd4, 0xff609f74, 0x7072675b, 0xfe8344fc, 0xcf7f89be, 0x9d54f6e5,
- 0x57ddcde1, 0x9a3ffca2, 0x2626b79e, 0x28675d0e, 0x31f8bf23, 0xc23e6463,
- 0x3aff760d, 0xfad503cc, 0x12ab9a39, 0xde47fd1c, 0xe1f28dde, 0x32ecc6cc,
- 0x47fd2b14, 0xdc1f90c6, 0x4565daff, 0xff6b5f78, 0x945e197d, 0xd5198f0b,
- 0xe2dfb93b, 0x8bc9eef0, 0xe0e387f6, 0x91ff63fe, 0x3f1895c9, 0xc38d7fe8,
- 0x278a650b, 0xe610bb40, 0x26fd6a5f, 0x984dd41a, 0x677ece8f, 0x8ee2bf24,
- 0xf1d20acf, 0xd344957e, 0xa050f7f0, 0xc3cfa11f, 0xd6f34d5e, 0xfde37df2,
- 0x37ff2d0c, 0xeed30fde, 0x17f78f8b, 0x3ddb59eb, 0xef1c9798, 0x6e618237,
- 0xdf89a509, 0x4ebfa733, 0xf74bf7d2, 0xdfd66e7f, 0xf6121d9f, 0x71e48580,
- 0x7ae3f02d, 0x79853f8a, 0x3c9d6fdc, 0xc5ec7eec, 0x6fa76e5c, 0x7e6dfdb5,
- 0x9ebacc6f, 0x03c53036, 0x626d3d78, 0x70d94f16, 0x9c85e3fe, 0xc37b925a,
- 0xb1758dfb, 0xa1b1d6f7, 0xaae9e47e, 0x9df9e530, 0xefd32f5e, 0xf5c3c459,
- 0xf8c8fd55, 0xebdfb5ef, 0xc4ed04f8, 0x00938c54, 0xe45fc9a4, 0xd5e1eb3f,
- 0xbf1569f0, 0x01fff2a3, 0x949113dd, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7db5ff00, 0xc5547c0b, 0xbddcf8d5, 0xc3764cfb, 0x083c8426, 0x813bcd84,
- 0x44902c24, 0x8f2ed4ac, 0x0310f0c4, 0x5850822a, 0x89de4020, 0xc5b0fd60,
- 0x40802166, 0x151a86d1, 0x260dda2b, 0x22ec1208, 0x760d1201, 0x4a888941,
- 0xadb45503, 0x202a25f2, 0xd4109204, 0xeb6bfe8f, 0x73339cff, 0xd0820fb3,
- 0xcfe8fbf6, 0x99dee64e, 0x7de733b9, 0xfd999cce, 0xf7f87bfe, 0x17bec613,
- 0x62a2d9a5, 0xc963106c, 0x2d9990ff, 0x43b2b194, 0x891ae71a, 0xafdac0b1,
- 0xf50b999f, 0x398d16ee, 0xf958c2c6, 0x6726d921, 0x659ac630, 0x3e0c4267,
- 0x08a822ff, 0x8f3797de, 0x33cccb31, 0x9cb3795e, 0xac654ce7, 0xd86ae9ab,
- 0x671a54e2, 0xfd88c5ba, 0xa1dab69f, 0xc2acc834, 0x57b4f465, 0x4c8b58ca,
- 0x69de28f3, 0x9932fea8, 0xe1efbfd1, 0xb05752bf, 0x29bcbd4f, 0xbd4bfab2,
- 0x7f8c5ea7, 0x367fc244, 0x8c5967a6, 0xec57f095, 0x6187ea72, 0x5dde6053,
- 0x1912e7b5, 0xb2a8d12c, 0xa1325ac7, 0x169df89e, 0x67b58ceb, 0x7e6899e5,
- 0x67981641, 0x20dbf3b7, 0xb7d2f306, 0xbf9c36c8, 0x2c32fcff, 0xff32c65a,
- 0xc2e5f983, 0xf33cc2fc, 0x5864f983, 0x59e67906, 0xb2d1e966, 0x3e879858,
- 0xc48d9d28, 0xa369b616, 0xfc22fda0, 0x6a2fde13, 0x058d3c59, 0x79a93631,
- 0xe0031ac9, 0xb25abba1, 0x7e79e0ea, 0xf00dc00b, 0x764dbf90, 0x932f005a,
- 0x311d5692, 0xd3f17d40, 0xe6ba1ef0, 0xcf4ee3c8, 0x9ecbf686, 0xb87ea990,
- 0x1ad391f6, 0x0d36ebc4, 0x031e21d3, 0xef8bb682, 0xa15f9c31, 0xcb615f98,
- 0x7c120bd4, 0xd921d96f, 0xf5fec6ea, 0x5f3e2b26, 0x79f341bc, 0x96fad7bb,
- 0xde301fe0, 0xd392ad92, 0xa92de30d, 0x95df7df6, 0x38b2d0e9, 0xefd5bfe8,
- 0x99faed79, 0x54b14247, 0x51d60933, 0x8f7df4e8, 0xf986deff, 0x77bf8b94,
- 0x8c1e6c26, 0x3032e9f8, 0x61f806d6, 0x8630f6ea, 0x1a3dbba5, 0x7cd5d8f1,
- 0x58f11a36, 0x24fffafe, 0xa7f07eb2, 0x14c5ac94, 0xe0102e7a, 0xf7d89169,
- 0xabfba42a, 0x69faf3d3, 0xe7087a3f, 0xc71a9d8b, 0x3fbc2b60, 0x746dfb52,
- 0xb349d23b, 0x1fb9987d, 0x9f1bedfa, 0x08aa0c39, 0x8606dd2c, 0x3ccb8665,
- 0x4de4f905, 0xd213798d, 0x33f5f6c7, 0xf0dd43b7, 0x00660686, 0xf12304f5,
- 0x12c7f20b, 0x3e1571af, 0xd9b129d9, 0x99426654, 0x6892f38a, 0x930fdf5e,
- 0x1e771e88, 0xd09e9dee, 0x69867cdf, 0x21e8dda8, 0x347dda8c, 0xd2356f2c,
- 0x11ca805b, 0x3660f884, 0xe014259b, 0xaafa092b, 0xe121595a, 0x4d5608f3,
- 0xa2e610e5, 0xecc605f2, 0xaccf6c46, 0x63338466, 0x7e118343, 0x5eb4f3c4,
- 0xe6e90abb, 0x9b770267, 0x8e0f4e24, 0x87ace660, 0x3d5ae5bf, 0xa6300793,
- 0xd841ed65, 0xf33694c9, 0xbde0c3d7, 0x255943e6, 0x43c8bd01, 0xcd5a7c15,
- 0x8c6fdf88, 0xc6f00df7, 0x17f7e1df, 0xa578e2e5, 0x83a665fb, 0x6a372ef1,
- 0xed88db98, 0x9da05f81, 0xb5affde6, 0x5a972831, 0xeb009624, 0x3e3a8728,
- 0xb6a71f2f, 0x52e0bd39, 0x78f0e16f, 0xf04892da, 0x8edb52e8, 0x33fa434d,
- 0x2c3ad22f, 0x2e7e4e38, 0x11347183, 0xaf38b48b, 0xd04fefc3, 0x82de20c7,
- 0xeb37c4d5, 0xb6ef945b, 0x64fc7199, 0x78f329d5, 0xa993df78, 0xf1e1db66,
- 0xcdc6a3f9, 0xf7ca47c8, 0x3f1c2cba, 0x12812b67, 0x97cf3c92, 0x8397dc64,
- 0xfb3297fd, 0xa5a3a47a, 0x7b733235, 0x0d79fdd1, 0x6b92f7c7, 0xc63dcc81,
- 0x4cc45fab, 0x6b92d75a, 0xbcfcf441, 0x6f3bb781, 0x9ef174e2, 0xc7c5d385,
- 0x885fbbe2, 0xaf2dbffa, 0xeaf2beac, 0xef1f0bf2, 0xd6e5c458, 0xa547487b,
- 0x44ce7b52, 0x88fac4f8, 0xf5ca2d5e, 0xe66695b3, 0x3ad0fdd6, 0xd7b73207,
- 0x5ddafb77, 0x40f73033, 0x6859b86f, 0x1af59efe, 0xcad9fde9, 0x31c09b88,
- 0x9e8e07ca, 0xe07ce3f1, 0x89f8fd78, 0x656cfef4, 0x1fc64df2, 0x63f18371,
- 0x19efe67c, 0xaf9e9e37, 0x20b1554d, 0x9fb5aba0, 0x6cc49ce8, 0x74a7ae7a,
- 0xbad6ef82, 0xfd2de927, 0x4d83aff0, 0xe163628a, 0x8b9ca37d, 0xbcd97c74,
- 0xae7c8cc8, 0x74b90609, 0xd8d7f41b, 0x7180ef72, 0x0321c175, 0x5aaf7e91,
- 0xdf5d68e2, 0x1d105706, 0xb4743b7f, 0x8fc188ec, 0x7d61e454, 0x997c90ed,
- 0x59fab378, 0x7ae5f392, 0x21d37dfe, 0x9fe44a60, 0xaf42f5db, 0x18bcc9ff,
- 0xd43553be, 0xf4c98fae, 0xf994c7cc, 0xb33c4336, 0x9430fb26, 0x819b8f03,
- 0x801f896f, 0x5abd61af, 0x3bbbfec9, 0x9fd81f80, 0x8a1eac75, 0x24f60d6f,
- 0x471f17b3, 0x09fd70c4, 0x728510dc, 0xa86ac1d1, 0x4aba6f2c, 0xff00b670,
- 0xf794bae2, 0xe087ace5, 0xc2cd7c8e, 0x16d52691, 0x4f64df7a, 0xccf34bca,
- 0x78eecfa3, 0x0150e8c7, 0xfd0ee9ff, 0xd9e10823, 0x6e99eead, 0x22d5d285,
- 0x77c37a07, 0x8fe70c64, 0x4ebf4309, 0x65e7876f, 0xd3e40fd8, 0x27166f23,
- 0xd329fca1, 0xbce3a4f5, 0xf7f9bc8f, 0xdff79474, 0x861e2a1e, 0x7b4277cf,
- 0x3db413b2, 0xf1af5665, 0xa1d999e2, 0x9329eb1a, 0xef88e263, 0x3cef9ffc,
- 0xe7183554, 0x886200d1, 0x5677c085, 0xe5f717be, 0xdb072440, 0x18672853,
- 0x0b7a97c8, 0xcaf74dda, 0x3eca5728, 0xea04db02, 0xbf5ccd19, 0x4e650c67,
- 0x67da0c55, 0x7c46cd1f, 0xcd6a6595, 0xc04a582a, 0x1ae736a8, 0xa9901f78,
- 0x1d1ea337, 0x5f7f843e, 0x0e3cfa8b, 0x440f67fb, 0xe414fdbc, 0x0f247fec,
- 0x2becfcea, 0x06b2a9f7, 0xdca95ef8, 0x00e51d3e, 0x31e985c8, 0x07d97e30,
- 0xb5489f5f, 0x309e8b60, 0xd0b74fc4, 0xe3127f3f, 0x37931a3c, 0xfbaae913,
- 0xe3d777fe, 0xbb2437a3, 0x88e3d71d, 0x5f515bd4, 0xec6708b0, 0xcebc2f4c,
- 0xba09518d, 0xba01ee01, 0xb6e62e1d, 0x796bb067, 0x6725e930, 0xb943d208,
- 0x1e51d98a, 0xd40069b2, 0xf32e91db, 0xf5a666d2, 0xd0d79fa7, 0x6c62cb78,
- 0x4abe708b, 0xcd668ffb, 0xc3f7b34d, 0x04a94887, 0x21ebad4f, 0xa94f679c,
- 0xf01dbad1, 0x82be21f0, 0xd2cd2f7e, 0x93b065b9, 0x0dc635ba, 0x27d1d012,
- 0x075bf381, 0x184ffac1, 0xceb815ed, 0x5e4c0fd9, 0xc8e9758f, 0xa472cb40,
- 0x59ed85cb, 0x06399788, 0xbef8c3fb, 0x161f6f44, 0x3cbc4b06, 0x00349ed4,
- 0x40de6a95, 0x97966f0e, 0xfcefd796, 0x753c7cf9, 0x54b7fa46, 0x31b7a5c0,
- 0x49d9006e, 0x67480daf, 0x152e9f30, 0xd0fd402b, 0x15fbe625, 0x25e623e8,
- 0x279c0ba7, 0x7da10bb5, 0xed49dd61, 0x97f5af22, 0xeae08582, 0x3a7a2ec7,
- 0x1745db86, 0xdbfefdf7, 0x9d50c05f, 0x44481cdf, 0xba58b5bb, 0x76faeb44,
- 0x62f9c9d7, 0xbeb8d57d, 0xa27b7a47, 0x12aeb0b5, 0x972d61d7, 0xea7d621f,
- 0x5a1fc49e, 0x2daa975f, 0x80e2e887, 0xf18fae64, 0x3c6d2bf4, 0xf4051399,
- 0x3c17505e, 0x9674e65a, 0xe8567488, 0xd1788f84, 0x028e32b1, 0xde42e59f,
- 0xf014aef5, 0xb676e009, 0xfbe51f02, 0x33e0fc67, 0x8d93dd5f, 0x2abf98f3,
- 0xa9e5c558, 0x7947e893, 0xefa560bf, 0xfb14ab77, 0x49c931e7, 0x7ebc66f3,
- 0xdcec11d0, 0xea9d7504, 0xa2f787ea, 0xb2a690dd, 0x2db0dda2, 0x68c06400,
- 0xf028fec6, 0x07c802f3, 0xdf3d087d, 0x0223cf80, 0x6788ff78, 0xe82ace54,
- 0x99a1379f, 0x32a5f0e8, 0x6f8655a3, 0x98e0642d, 0x331614c0, 0x67d9d91b,
- 0x50fdffc7, 0x68f3ac3b, 0xf08ddd8c, 0x1550305f, 0xc3cd21fd, 0xda06623e,
- 0x1c38e36f, 0xfd17b3af, 0x99933fe0, 0xb1e46435, 0xfbe42acd, 0x94be6699,
- 0xe3e71225, 0x834d997b, 0xd99fbbdf, 0x2ea9dda9, 0x93fd0dad, 0xc15be853,
- 0x0e601fbc, 0x39873e7a, 0xdccb9ca9, 0xaca7fed4, 0x1f0aea9d, 0x082ffd00,
- 0x3e7ff4e5, 0xf9ba265c, 0x327de718, 0x4ae87d30, 0x678cc758, 0x5fc81293,
- 0xf04419ab, 0x67bcd9b9, 0x8f8e1c48, 0x71dbd8c6, 0x6fdcde9c, 0x7181ac5e,
- 0xd1377a54, 0x989c9f5f, 0xe1d04834, 0xb689cb0f, 0xcc7f3ede, 0xb8700918,
- 0x2ef4a04b, 0x63f9315b, 0x3991b2d9, 0xe36d3f00, 0x53fa2764, 0x43ab6cc7,
- 0x93aa6543, 0xcab36d5e, 0x59dff7a4, 0x50194ccd, 0xc694677f, 0x6b74455a,
- 0x5d3c3d23, 0xcd7d978c, 0x7800f6fe, 0x586e5d3e, 0xdcf50c1b, 0x790fe021,
- 0xd0e4d5d1, 0xb3e46abd, 0xcfbef129, 0xfafaa5a7, 0x6ab3774d, 0x3d3be119,
- 0x61ddb7c3, 0x95d00b84, 0x3ffb962a, 0xfe1b386c, 0x8fe1ecbd, 0x31f9147b,
- 0x1bb6aaed, 0xd62631e6, 0xf585886e, 0xecfbbf2f, 0x532efc7c, 0xa0c60fb3,
- 0xb3213a5e, 0x73fef04d, 0xd81b13e0, 0x82565f4b, 0x397e0306, 0xd61ff607,
- 0x0d3b02bf, 0x16958bcb, 0x5d812f2a, 0x2abbef85, 0x207f54ad, 0x16242f36,
- 0xc368bf40, 0xed1db515, 0xfa2ceafe, 0x5f410afe, 0x2ab72a6d, 0xbb67f910,
- 0xb87d4564, 0x2136d0c2, 0xa2b6e010, 0x180ac63e, 0xae4d4566, 0xbe7e9c56,
- 0xd1072f3b, 0x4558f4b8, 0xd7a5962b, 0xd2076624, 0x8bce417e, 0x3ebbf1c6,
- 0xddd67cfc, 0xe57cfcf0, 0x85fefa58, 0xbf7d1b4a, 0xca9732b3, 0x3c7b588a,
- 0x74b5b3b6, 0x20b40eb4, 0x7d10ae36, 0xa1d0dddc, 0xb67a828e, 0xdf21b24d,
- 0x4e6369dd, 0xab75e027, 0xada9eb86, 0x0f90a7a0, 0x7ccda7c7, 0x7a8661e1,
- 0xe38e9ec4, 0x30a53fdc, 0x3e99c71b, 0xdb1aa176, 0x631df03d, 0x743c6303,
- 0x65ba3376, 0xf2fc727e, 0xddd1129b, 0x1ee59565, 0xc71cabb4, 0x7a0fb265,
- 0x185530d5, 0xe193f7bf, 0x74e0074e, 0x70b8fef9, 0x35cb6794, 0x2f10f096,
- 0x27e9d639, 0xdcf73ac7, 0xdfade116, 0xdf5c433a, 0xd0e505fe, 0x810e5c67,
- 0xb7ee74a5, 0x118ca728, 0x976fc456, 0x520043f0, 0xcb8fa881, 0x406f82b4,
- 0x33bd608e, 0x83c82d80, 0x51abd67a, 0xf00f9013, 0x8f24967b, 0xf57c499c,
- 0x585fd8d9, 0xe9dbdf3c, 0xdf97f25a, 0x53b2fd42, 0x5e80d0e5, 0x5d5cccba,
- 0xeabae3af, 0x17b4568c, 0xc0752593, 0xefec10ca, 0x964bbe24, 0x2095ea2c,
- 0xfabd7647, 0x19e7e0c2, 0x8d8c09da, 0x6c6ff785, 0xf3392409, 0x667ac686,
- 0x817ff625, 0xc9f97ff7, 0xc26f3f47, 0xd1d289f2, 0x1059428f, 0xcd70421b,
- 0x70e14dff, 0x5111b3a4, 0x6f180680, 0x6dc941f7, 0xad2c6748, 0x489af0e6,
- 0x6dc8cf98, 0x50c1aa1d, 0xaa93aa8e, 0xca611cb0, 0xfbc3263d, 0xcd0b58b2,
- 0x8c434c63, 0x32ec851c, 0x9f97f9d8, 0x6be1bd90, 0x5cd6a487, 0x79983099,
- 0x92e191ec, 0xa5e222eb, 0x347a74ca, 0x4d563be9, 0xb96fece3, 0x69734ff7,
- 0xe0e9601d, 0xad6a17bc, 0x8e9c1fa4, 0xcbb3a45a, 0xd92b64f6, 0xe78e79e7,
- 0xed97bf10, 0x17d45661, 0xff5fc007, 0xa33fb611, 0xac1e75a6, 0xf184193b,
- 0x07e0019b, 0xe97de01b, 0x93d21ea8, 0x0c2d43a5, 0xc5f43bbf, 0x3e1172bb,
- 0x6bfb8d65, 0xbd129c69, 0x82d9fd15, 0x515b57fd, 0xccc9b26f, 0xd5f4809a,
- 0x9abfebc8, 0x1ea2b364, 0x86fda82d, 0xa8f2dbd7, 0x83de079e, 0xe62fdb1a,
- 0x42b3d976, 0x74f6b12f, 0xb2445b92, 0x7ebe0f16, 0xfdf1af05, 0x644718d6,
- 0xcfa3d185, 0x416d0f40, 0xf2d488fe, 0xe6136dfe, 0x6e5c1346, 0xe3290f51,
- 0x0e65ab3c, 0x2d45ea03, 0x20f597d7, 0x603e902f, 0x7c7117fc, 0xc9466f45,
- 0xac235a52, 0x1d59ea3b, 0xf8b7b397, 0xd603d99d, 0xec54de93, 0x1f6172b8,
- 0xe8136154, 0xbfb465df, 0x8970f282, 0x6d4cb3d0, 0xe3bb4549, 0x776da333,
- 0x6071d92c, 0x7f48a8e7, 0x65eb1efd, 0x7175d832, 0x319d765e, 0x17f496e4,
- 0xe3f6d933, 0x7db56e7a, 0x9fe798a8, 0x03433cc5, 0x1d2c9da2, 0x87f80afd,
- 0x7858e984, 0x587186d2, 0x447ef1f4, 0xc156eb24, 0xe11d073a, 0x8bb1e3f5,
- 0x1b05acb7, 0x77a47dfd, 0x3382470e, 0xfb430050, 0xca6e794c, 0x6210f4e0,
- 0x11dd93d7, 0x5462b03e, 0x337d1785, 0xc20c7bb5, 0x653fd363, 0xdb7684b7,
- 0xfc5233ff, 0x86de7fc7, 0xfd7fee38, 0x150e624c, 0x2d15d7d2, 0xb4d16bb5,
- 0xf43dfeef, 0xb54c296b, 0x007b3fa2, 0x71c7adf0, 0x8ec96a66, 0x05db416a,
- 0x09ccb7da, 0x86f7b923, 0xc741cb86, 0xdfde009c, 0xf7c10000, 0x689dc3ab,
- 0x55d60da7, 0xe38697bc, 0xdf120557, 0x1b9c68b4, 0xc7fc7162, 0xb2f8d206,
- 0xe8e1bdfe, 0xe4227d7f, 0x9ee49551, 0xc76df18b, 0xefc32d15, 0xa3bb04d5,
- 0x535ea1ca, 0x7fda9c38, 0xed192a02, 0x5b609ac4, 0x03d9ca24, 0xfe4994ff,
- 0xba828cd5, 0xc513e491, 0xd8666a61, 0xfea18322, 0x4d4bc0a0, 0x99feb3ad,
- 0x4c9e7c50, 0xb8c60ce3, 0xe18bb61e, 0xc345fce3, 0x07a7d9fb, 0x075ed1aa,
- 0xf089144d, 0x027e6dfb, 0xe3c2d2c5, 0x0871c826, 0xcfb7e15f, 0x19477216,
- 0xb3e83b1f, 0xffe30ed0, 0x37a92ce6, 0x5fdd7f20, 0x0d00e860, 0x58293ec2,
- 0xf5bf4263, 0xd6ecbb7e, 0xf7605c81, 0xecfadb65, 0xdf1c5882, 0xbd21c726,
- 0x937e2be5, 0xf5c2317b, 0xdb3d1ecd, 0xe0237644, 0xba7aed35, 0x1fdf80bb,
- 0xf8e3fe80, 0xc7fdbca7, 0x9fe71d42, 0x6887480b, 0x43da060f, 0x4de5fe70,
- 0xf6f29f93, 0x592ce72b, 0x40724417, 0xa552f77c, 0x132fa9ed, 0xa5c84ed0,
- 0xf2aef952, 0x7a99dcbd, 0xfe8a149b, 0x7189ce8d, 0x0ec205c0, 0x67b9d72d,
- 0x673e3f21, 0xefa30fb0, 0x474c5d14, 0x6674317b, 0x475c00f2, 0x0e60bbf7,
- 0x0233db41, 0x805067cf, 0x4c2b9e23, 0xd44c3744, 0x4818bfed, 0xdf04b9f6,
- 0x62fa3a41, 0xda3b698d, 0x2dad7673, 0xd1d20972, 0x47b240f2, 0xc1dc80ce,
- 0x0494cf71, 0xfbce1d13, 0xc8fbf175, 0xb4f2676f, 0x5a679f44, 0xe9f7bdb8,
- 0x85add94a, 0xbccd77f5, 0xf4224cf6, 0x45f55aeb, 0xdb2856d6, 0x1a35fcd7,
- 0x35bcd1f5, 0xdfb0d3a5, 0xd355a2bc, 0xe2374e11, 0x3a2579f3, 0x6e1cccc1,
- 0xb76ce353, 0x6742be23, 0x3941cb5e, 0xe4b8b83d, 0x17c18c39, 0xc4efd9c7,
- 0xdb6997f5, 0x651e10cb, 0x8d167c6f, 0xf37773f6, 0xa15b7bcb, 0x27d9336c,
- 0x35b2bf60, 0xc3acc577, 0x55ff84c1, 0x017c06a6, 0x671e7d1d, 0xe5f7c1cf,
- 0xd889dc93, 0x2da692ef, 0x56c6e107, 0x7ddd9add, 0x80fea5b1, 0x40607e84,
- 0xb295194b, 0xd1e71d33, 0xa483b929, 0xd8238438, 0x4beeb00f, 0x70507766,
- 0xc98d452a, 0xe9de289e, 0x5a9a3ebb, 0x403b8898, 0x6c9762bf, 0x32dd2033,
- 0xebe716a7, 0x9e18bedf, 0x7c5bbb53, 0xfc5cc45e, 0x93d37079, 0xab7d2077,
- 0x37f71b99, 0xd84aee2e, 0xbcbff88e, 0x6f44e5ff, 0xbcbfd83f, 0xfd7cbe7e,
- 0x00be9097, 0x89e0978e, 0x41abe906, 0x75ffe3e7, 0xfa248aed, 0xfd11ef82,
- 0x724aed74, 0x8f92f26e, 0x307e425d, 0x066b2bab, 0x95cdbdd2, 0x22967685,
- 0x95de982f, 0xb25bfe4e, 0x15fd1d2b, 0x3cb0de45, 0x773d2257, 0xfdb112ba,
- 0x8d67f401, 0xed16ef9e, 0xc4ddaa8e, 0x550e8ee3, 0x6c47d606, 0xee32bac7,
- 0xb497d6cd, 0x4f53eb55, 0x9fd6fa71, 0x95fcf210, 0x1f8ab457, 0x82bf0b2c,
- 0x5a3c1459, 0x7046fdb8, 0x8156b3f9, 0x5951c3cb, 0xbf803718, 0xdcde6962,
- 0xfb857e6f, 0xd94607cd, 0x2aae50a3, 0x6081f9fe, 0x5ea2a7a8, 0xea56f3e5,
- 0xe7fc1c0a, 0x4bcfe6bd, 0xf7be30a3, 0x1f8f1c46, 0xbcb81955, 0xb97032aa,
- 0x1594dab4, 0x34abef8e, 0xa2a6c760, 0xee2c72bf, 0x0e078d4b, 0x366d2ae7,
- 0xf57dc110, 0xe9475ba5, 0x6d976f91, 0xa6f7a51b, 0x639daa8f, 0xde60598e,
- 0xadaa7697, 0xb52a84b8, 0xd7b449f3, 0x2eca76aa, 0x7af7a307, 0x64bfb41b,
- 0xdb02723c, 0xe3c6dd2d, 0x65ff4a16, 0xf96db35b, 0xb11ef35e, 0x69be17d3,
- 0xc8fadf2e, 0x51fadf26, 0xfd0645b4, 0xb946fdeb, 0x8e63eb7d, 0x7fcfd6f9,
- 0x242cf0f8, 0xf1d902c3, 0xe3f68ca4, 0xa18e735f, 0xc0eaf93e, 0xf78a20c1,
- 0x8adf967c, 0xadb2f176, 0x3c0770be, 0x3827684a, 0x77a44876, 0xfcfe9d0b,
- 0x031f3fd2, 0x5f389446, 0x14dd37b2, 0x3aab4731, 0x9df6fae6, 0x86cb35cc,
- 0x7f95a571, 0x8c72fb8a, 0x5ddbdc67, 0x0fe8b45b, 0x46f77ff9, 0x368ccb7c,
- 0x1637c60b, 0x7eefe58e, 0xfb2272b4, 0x7cdbc702, 0x71e90732, 0xd224afe1,
- 0x25f70bc3, 0xd3748dbd, 0x14ce77b1, 0x12e5672a, 0xcbb8943c, 0x6dc916b2,
- 0x2c79ba82, 0x650fdbeb, 0x6b45ef30, 0xa1f13e75, 0xf3becdfc, 0xfbe35a58,
- 0xe1d3597e, 0x6bbee1bf, 0xda45fe81, 0xa6d82ea7, 0x396b8bf3, 0xbd3b42df,
- 0x7e462be8, 0xf7dd5178, 0x5ee2feba, 0x143ac44b, 0xee3990fb, 0x6e4eb864,
- 0x8edf8202, 0x3d7207ff, 0xc4d76cc4, 0x8dd8f20f, 0x95a9aa3f, 0xcca57e11,
- 0x8e3988fe, 0x207751fc, 0x0ea967cc, 0xa4d1b1ec, 0x577d6987, 0x78a00eb7,
- 0x06673c07, 0xb5957e78, 0xbe7ea165, 0xf2b268da, 0x965b5938, 0xa0cbea19,
- 0x602bf08e, 0x12a704d5, 0xa732cb94, 0xddb79b1b, 0xb3adf4e0, 0x97b76e6a,
- 0x1187dda8, 0x9dacc51e, 0xbd1e21fa, 0xbac095db, 0x3b41093e, 0xb33fafc4,
- 0xdcbc9c52, 0x95fc25a8, 0xf3af7d37, 0x0bf8af7e, 0xc4a2ff8a, 0xf4577ee1,
- 0xb7d20060, 0x3587d846, 0x5b7b9d1b, 0x94eb3d61, 0x0316deb8, 0x6b07a7c9,
- 0x7b07bcb9, 0x59d71130, 0xd68525b3, 0x8b64a0fd, 0xf6b68759, 0x7fd13d0c,
- 0xd3d8304d, 0x924764a1, 0x237600bd, 0x733dadd9, 0x12edceb4, 0x372e8fda,
- 0x4f35c1da, 0xca06f8f3, 0x9f6bb249, 0x527d9030, 0x27db8333, 0xa9c25b35,
- 0xca705fff, 0xf2576891, 0x913cd4f9, 0x995dedc6, 0x8ce163f7, 0x65f607e6,
- 0x5e6bdea2, 0xb2ff5d8a, 0xf1113ed9, 0x26b7acad, 0xfb84c7b8, 0xe060ac1d,
- 0x7af9e92d, 0x007abfa1, 0xff07180e, 0xc56bca52, 0xdda5097d, 0x1f5cf17d,
- 0xedb04d64, 0x5e28ed10, 0xb19aaf9e, 0xa79827e9, 0x52ca8cf0, 0x7f05e315,
- 0xd7112d9b, 0xc316e5ff, 0x99d3c468, 0x679e5c51, 0x05f1e04d, 0xdb6c5bf0,
- 0x5e22ff71, 0xfd7713e5, 0x614ef8a9, 0xf5e685bc, 0x2f8f3665, 0x28f2329a,
- 0xdab6038e, 0xf5f6fe82, 0xbef9e30b, 0xef36be68, 0x99fb8ff8, 0x3617028f,
- 0x5f17fb89, 0xbe91243e, 0x9a24f584, 0x1bf59ea1, 0xbe7fc503, 0xc1477a14,
- 0x2651d007, 0xc72161e9, 0xc67e90c2, 0x19e7e878, 0xa40e1741, 0xfd378b0b,
- 0x83c7d2f8, 0x09ecff02, 0x04d69f6e, 0x13cd7af3, 0x9fa03729, 0x650ffdfe,
- 0xfcb535bd, 0x01dfbfbd, 0xde36b074, 0x74fe9e0b, 0x4cced4c0, 0x7f35fdef,
- 0x8d96c83a, 0x57e728c9, 0xb4560148, 0xfe0857c7, 0x1184b158, 0x0ab1463d,
- 0x8235f909, 0x008f29b9, 0xc70181e4, 0xc00f71fb, 0x7f0f8bdc, 0xbccf4d72,
- 0x1678dff5, 0xa89f53ec, 0x9f69f48f, 0x79f18e6d, 0x8a44577f, 0x96c9fbcf,
- 0xa9f53e51, 0xb4fbb7c9, 0xde3adbbf, 0xd8cf7ea7, 0x67ed3ec9, 0xd4f866d8,
- 0xc6accc6d, 0xee54b7f9, 0xcde0fb24, 0x97dc574a, 0x65c3d709, 0x3ec8ee9c,
- 0xa6b1958b, 0xaa6707ba, 0x0dc61e81, 0x0622b238, 0xede387ea, 0xe4751ebc,
- 0xb1998c6a, 0xf217e2b7, 0x572388fa, 0x347ea163, 0xdfaf117e, 0x7f5fc8c1,
- 0x4cf17e27, 0x15c52a47, 0x667e218f, 0x8a38ab5d, 0xab47e16e, 0x41892e67,
- 0x24c92f1e, 0x67ecae39, 0x3f6313dc, 0xbcacfc84, 0x8d9fda57, 0xafbbfde7,
- 0x7ddff970, 0x2377cb85, 0xfe83291a, 0x32fc12fd, 0x0e04fefa, 0x6f413622,
- 0xa62ffda4, 0x8bea5cd7, 0x94fc8343, 0x3c618c6c, 0xf012a5af, 0xd370809d,
- 0x34aee953, 0x32a47953, 0x2bb7ca82, 0xe01f2c2d, 0x4c995ada, 0x2b4ab1e5,
- 0x395e3f3d, 0x2bf7ca96, 0xa89e546d, 0xadb2a5cc, 0x094a8f32, 0x2879a98c,
- 0x3758763f, 0x0e2e1068, 0xbd39f075, 0xc6e52f27, 0xcecd4c72, 0xc685f829,
- 0x5f6c186f, 0x31dd93c4, 0x71714cc4, 0xd35bbcf1, 0x73d222f3, 0xc16615d5,
- 0xa6c3b87c, 0x9fb416d3, 0x44f532ab, 0x9b4f52ef, 0xb8ebe505, 0xbaaf5e0c,
- 0x675166d2, 0xfdea3af0, 0x28d760ee, 0xa5550bd4, 0x189aeb46, 0x448eef7c,
- 0xa157197e, 0x387fa2b5, 0x3e67a7a9, 0xa338f1f2, 0xf47a82d6, 0x2df5a9b0,
- 0x73ca3df1, 0xdcc2bba9, 0x3457dc2a, 0xe2cc59b4, 0x7c0e383b, 0xc1f50637,
- 0xbbe187b8, 0xed056e34, 0x679b8d07, 0xe4aefbec, 0x0ffd5df7, 0xe4a2777f,
- 0x5ef8ddf5, 0xff3a6ef8, 0xbbe7c5ae, 0xe5ec996e, 0x0fb26e2b, 0x11ad83ba,
- 0xfa955f28, 0x4a9f7c24, 0x33d24271, 0x196e2ce3, 0xe887eff7, 0x070d3cb8,
- 0xa5e0d2f3, 0x6278956f, 0x675f2f5d, 0x08bba557, 0xb0926af9, 0x59692657,
- 0xa993c232, 0x98fe2802, 0x1ad77f2d, 0xcde5f505, 0x9dcc28d2, 0xdbcba498,
- 0x9aae7e46, 0xca161dcb, 0xb75332f5, 0xed0cbe15, 0x5945854e, 0x486adf31,
- 0x0f1601c4, 0x3cbb3872, 0xfaf51537, 0xd4df9129, 0x484f641c, 0x9bdc7980,
- 0x254a720a, 0xd9f71988, 0xde490372, 0xca4a1f77, 0xa67f7b44, 0x019fb2ce,
- 0x3c26a71f, 0x720d5333, 0x4b00e671, 0xfac664a6, 0xb70f5e36, 0xbde097ec,
- 0x73333d99, 0xc1ffedd2, 0x4934fafe, 0x381f97ed, 0xadf80136, 0xc8b2f734,
- 0xfb21ec57, 0xe498c7f6, 0x77e28834, 0x9ec7a46e, 0x03d226c9, 0x8e5b8f18,
- 0x92d53bf2, 0x35a2ed89, 0xff08413d, 0x94d4efee, 0x832d023f, 0xe38af3ee,
- 0xf3c2d8bc, 0xe3f9fc4a, 0xabd70272, 0x9f3cf1e5, 0xaf422ca9, 0x4ae5b2a7,
- 0x8f7ca30e, 0x3ff478bc, 0x57edeac1, 0x0277febf, 0x598e1fdf, 0x47f1e5af,
- 0x6530a114, 0xea53005b, 0xa96bcc0e, 0x3140247d, 0x4e006d46, 0x547ec5a6,
- 0x24cdfa6f, 0x1b7b4fb5, 0x67bcf7b6, 0xd29f0436, 0xcf7ea4bf, 0x8bc6d66f,
- 0x2cbd21ef, 0x825c4e65, 0x4da9febf, 0x0bfc510c, 0xa10bf3c2, 0xe38bf206,
- 0xa057a065, 0x1740a8cf, 0x0ceb33c5, 0xdcc17e9c, 0xc54eb2a0, 0xc0036bdf,
- 0x50fa85fe, 0x9a3ee3a8, 0x22bed13b, 0x67f51071, 0xef2fec66, 0x2291fea5,
- 0x1f794e6f, 0x1979518e, 0x0cdae9f3, 0x55938e58, 0x4e4dc2fd, 0xc46bff1c,
- 0x83a55777, 0x2fd2f59d, 0x2b41815d, 0x8654f1bd, 0xfdde8dfd, 0xa53f5026,
- 0xfdd8297f, 0x9c920767, 0x8d297a26, 0x2b3e5157, 0x4b6fcdf8, 0x36b0d768,
- 0xa561ea2d, 0xab9069df, 0x410fbdf8, 0x09f962ce, 0xc0b3d7c8, 0x9ca97f9b,
- 0x95a7e54d, 0xa67e7a76, 0xf6ca80b2, 0xfe7a0aca, 0x2a4ae579, 0x6535cd67,
- 0x37949f20, 0xbd6766ad, 0xa5d4bae8, 0x4bef7bb1, 0x3fdf1e9e, 0xe04aecbd,
- 0x98e9dd76, 0x95bbdffe, 0xbc7277f7, 0x817d8375, 0xdfd024f6, 0x8dc8735a,
- 0x136e8ced, 0x377abfdf, 0x7773d385, 0x25d7af24, 0x536ea868, 0xffd8adb1,
- 0xd12d14dd, 0xc6448aeb, 0x2c7889db, 0xdf8d1fd0, 0x3e54e707, 0x19ced28e,
- 0x2fedcaaf, 0xf225984f, 0xe89f4476, 0xc63d202f, 0x9967d178, 0x9fd3e885,
- 0x39136a2e, 0x38ebc4df, 0x2ea145dd, 0x708c7dc2, 0x0a731383, 0xdc36be60,
- 0x3893af57, 0x9f475e3d, 0x5d9fee2a, 0x0e309f47, 0x5ce809c1, 0x7ec7f282,
- 0xef94a3f4, 0x0b6fbe0a, 0xe08cfd33, 0xa331a2dc, 0x0cb1f8be, 0xaafec580,
- 0x0f9813de, 0xb266151e, 0xf6489ee0, 0xfe8ac6e3, 0x123fc7e4, 0x6ffd7db8,
- 0x1f8fbfaf, 0xdd7fd77d, 0xd07ec5ba, 0xe49baead, 0xa44bca09, 0xc3e47e9f,
- 0x3e4504a5, 0x1391fa70, 0x3f50e76d, 0x35064b74, 0x0dbbb3c6, 0x83ae2e9c,
- 0x4fa70a5b, 0x056a3e85, 0xbae1447d, 0xe9eb3ce2, 0xdf807f9b, 0xca3196fa,
- 0xa3c7f0eb, 0xd6bc5722, 0x2f04f7f5, 0xd818c279, 0x487fd017, 0x09f69189,
- 0x099a2457, 0xce83dd7e, 0x6f02dfcf, 0xe27a159f, 0xa7df1579, 0xdf76e450,
- 0x305e4973, 0x9e47d523, 0x7a33b433, 0xbf88e90e, 0xf0562adc, 0xf851fa1a,
- 0x70bf2f29, 0xef53c0ac, 0xee154cec, 0x6b7d75bf, 0xcd1e5074, 0x68339ee0,
- 0x056d7447, 0x7ffc8003, 0xf40934db, 0x878c12d9, 0xafbe3058, 0x8be8fda7,
- 0x24b20f60, 0x72bae768, 0xf298ed06, 0x07a664e7, 0x7dcfc9d0, 0x65e90b33,
- 0x998d21e9, 0x4fad9aec, 0x3b7a431d, 0x505928d7, 0xc23577df, 0xb39f71b2,
- 0x4034e4c6, 0x63a81cfb, 0x653b65fb, 0x03522527, 0x14fe907b, 0x286b3bdf,
- 0x777b458b, 0xa33f73e2, 0xb5a5f8fd, 0x71870b12, 0xa2badadf, 0xe7ea1235,
- 0xf9fcf1b6, 0x7fcf032a, 0x6b3791cf, 0xb47c6307, 0x312f3f96, 0x7bfe50e6,
- 0x75662ed1, 0xaf65bc63, 0xa5f3fc89, 0x1579be35, 0xeb7cdb05, 0x5cbe2285,
- 0xbcfbe754, 0x4f37c1a4, 0xc8a24c63, 0xa36148c3, 0x135a5e28, 0x22807642,
- 0x77e46f4f, 0x397396d9, 0x61d7d8c9, 0x0f95ef18, 0xb9fd137d, 0x8867d791,
- 0x2fd4077a, 0xa2f1c37f, 0xc94ca5c0, 0x1964882b, 0x23cc0cae, 0x3f719834,
- 0x8bf9acaa, 0x73f98620, 0x89d3ed01, 0x29975f3f, 0x93636adf, 0xa569fb4c,
- 0x3097862d, 0xff6cb0cf, 0x84c5ad49, 0xec887f70, 0x6398bb80, 0x6e8bfa3d,
- 0x6fe44a95, 0x8ddc51b7, 0x52967ad9, 0x60d9bb7c, 0xf65afd46, 0x73adc7fa,
- 0x625fbeb1, 0xd0e3c406, 0xa593a276, 0x5fb4c9cf, 0xc9f2d0cd, 0x8c89d0f2,
- 0xbb3c4578, 0xcf3ed006, 0xe23bc432, 0xe78ef019, 0x34e7e41b, 0xbba5f784,
- 0xb55f7a64, 0xed8b4ab5, 0x7e3939cf, 0xc8e7bc15, 0x45cf08ab, 0x4e7c702f,
- 0x99feae7c, 0x5d83a400, 0xdf73b21a, 0x79837e82, 0xd03a1f3f, 0x77e3e21e,
- 0xdf144bd5, 0x6683a3ea, 0xe01d1f5d, 0x07466f3c, 0x67a49fc0, 0x0607466f,
- 0x4fe41794, 0x8a1a3b8f, 0xf8cfedf6, 0x9db8947c, 0x1f9b9712, 0x10fa59d2,
- 0xd8884d34, 0x1b2cf647, 0x08955f60, 0xe4cce672, 0x74dc280f, 0x51eeca6a,
- 0xff034f94, 0xbf9461f4, 0xfb7cf047, 0x444b7fe7, 0x331dd079, 0x18c1db63,
- 0xae0767c2, 0x90383ba7, 0x923dd3eb, 0x3ae7a253, 0x93be0eb7, 0xf915720d,
- 0xa3a9bd92, 0xa0f743f8, 0x893e1e07, 0x184f68fb, 0xc92e88ad, 0xe2bafdc6,
- 0xc13e7796, 0xcc6b27f8, 0x7df8f9b6, 0x462b2fc2, 0x37df10bf, 0xb5e85f80,
- 0x3f9928df, 0x4bbf7ea0, 0xcb75a58c, 0xf256eb2a, 0x0598eadf, 0xe5eb95ed,
- 0xaff9233f, 0x686eafc4, 0x01e9f99f, 0x76e7fc8f, 0xf10c7319, 0xe5c0b73b,
- 0xf71132d3, 0x71c8fa3d, 0x675c40f5, 0x53373f1d, 0x297202d8, 0xf8a5ce94,
- 0xd13297c8, 0x19d23cfe, 0x472bf1c0, 0xec9501c5, 0x9d3e472d, 0xec94e384,
- 0x2194e3e2, 0x981c20fd, 0xdc0099fb, 0x28697027, 0x84c4591e, 0x5932695c,
- 0xe47e96dd, 0x7aed5d48, 0xe9fd7f34, 0x37ec18a7, 0x1d3f845c, 0xb6fa3595,
- 0x97ca03fb, 0xd25f2411, 0x077f47be, 0x23d32369, 0xd4e5b247, 0xf5afe801,
- 0xe400cb32, 0xb9e91be3, 0xdac0ada4, 0x38a6e35e, 0xb3ed4cf5, 0xa9f6615f,
- 0x7c22b9a7, 0xb26c8fda, 0xe51fbcf8, 0x3f79f64e, 0xa7d598e6, 0xd636d99e,
- 0x9f6dfda7, 0xb7ea7cd8, 0xb4fae7b7, 0x3cabe3bf, 0x2a6f7a9f, 0xf607e7ac,
- 0x908aeeef, 0xb64fda7c, 0x07c67c18, 0x99f04e0d, 0xf3ec1c9a, 0xe1c8d7bc,
- 0xef71a374, 0xab8efab6, 0x8cf7b9f8, 0x867f1df5, 0x5bdc77cd, 0xd00ec3c5,
- 0x4d106a9b, 0x628f413b, 0xc0254af9, 0x86f1ec1d, 0xbfaa08ca, 0xd2a1695a,
- 0xcf4c9955, 0x52b4ab5f, 0x2c72b1bd, 0x7d800fd5, 0xb026f58f, 0x1d7cb1f7,
- 0x7e7c7cec, 0x8ab57833, 0xdf131eef, 0xcbbe2e3d, 0x076e16d8, 0xef2e04dc,
- 0x4427fe8b, 0xafec36ff, 0x6961d0f1, 0x1aeaa66e, 0x90f8edf0, 0x2f8c5a0b,
- 0xe7b796d8, 0xf3df9fa0, 0x03b6ccae, 0xf3bb305f, 0xea286558, 0x1f3c81a9,
- 0x3de7af21, 0xed97178c, 0xfee3338f, 0x3fa6c6c7, 0x5df7c09d, 0x33c5328d,
- 0x117d348e, 0xba5ce384, 0x503ecc06, 0x97a837e8, 0xfaa24dfc, 0x798f7826,
- 0x82f793f8, 0xcb7a4b61, 0x52eb7a45, 0xd27752bc, 0x86bc8df9, 0xda76dabd,
- 0xef4bdc57, 0xf5be05df, 0xd6b3bf79, 0xdb19bde7, 0xdab67ee3, 0xc5f77e49,
- 0x373c6526, 0x97892fb5, 0xc5d23ce8, 0xc7ad6f9d, 0xbdd2be7c, 0x3ee2070b,
- 0xc9c37160, 0x003fc5b0, 0x7607cbff, 0x2f5ca2a7, 0xf9c5966d, 0x695e3e23,
- 0x891e72b3, 0x7e24bfcf, 0xca084e6f, 0x218906ed, 0x6ab12e7a, 0x6e2a8fca,
- 0x39412faa, 0x573c9c5a, 0x9721f143, 0x3c01e22c, 0xccc4b0df, 0xbae67db8,
- 0x35e7841a, 0x3a3ae0ff, 0xba85f31d, 0xc20ade5b, 0xf9e376ef, 0xdefc2f13,
- 0xdcedc493, 0xdfb8927b, 0x2df1a974, 0xd1b93f3a, 0xbb8716f5, 0x3feb4dda,
- 0x50ddea22, 0x649bbc12, 0x35e17f5a, 0x8ca0f099, 0x4c9260f7, 0x4a6e4de3,
- 0x4ebae130, 0xf2f7f8b9, 0x79fc2c93, 0x9c7cc2fc, 0x3988f1ff, 0x95d93299,
- 0x3ddf2e3c, 0xca3d6a7c, 0xe80fcc51, 0x047b0fcf, 0xb5f985c7, 0x77c63c8a,
- 0x0eb5f7e3, 0xcf1fb806, 0x748a381d, 0x274fe280, 0x473dfb71, 0x3d478f6b,
- 0xa168ca71, 0xdc9af838, 0xf7e21338, 0x3cf89608, 0x57da25f7, 0xdfe46a28,
- 0x0b6e653b, 0xd53bba42, 0x3b464638, 0x40af1946, 0xbe8fb77c, 0x20e6f0fb,
- 0x6b38153c, 0x078e388d, 0x7e79fc7f, 0x71e69992, 0x167279dc, 0x92a74bda,
- 0x68cec903, 0xfcfdf2d5, 0xef6e06e2, 0xaa896a9e, 0x5bf6bd95, 0xba3e05f2,
- 0xd7845593, 0x688d26ae, 0xf99eb737, 0x7c70d3b4, 0xc7cef9d5, 0x1278ecec,
- 0x1792eced, 0x54933a64, 0xc308a9a2, 0xe6df9ff5, 0x0102bf3b, 0x3b8d12e7,
- 0x5e8bcc2c, 0xf8fb9a4b, 0xde7448c6, 0x8589f0ac, 0xf1e0a9f0, 0xc73f3254,
- 0x9f822a72, 0x5bd92a83, 0xd1ed744f, 0x19ae3cf7, 0xbf3c5ff5, 0xae7e66f6,
- 0xf9780f62, 0x3cfd0c49, 0xa65c6e4d, 0xf7a3d62a, 0xbf6d137b, 0xfe841a4b,
- 0x85f91e53, 0x8a26ec40, 0x3c7da08b, 0xa7efe500, 0x7b77e0cf, 0xd879f91b,
- 0x11737d52, 0x5af5fbee, 0xbe604181, 0x4e34dbbd, 0xd118cfe1, 0xec2a5d4e,
- 0x7b16f3d4, 0xa3fb8c96, 0xaeb455ab, 0x89d90692, 0x425d98f9, 0x1bde5dde,
- 0x69d20f73, 0x8cd931c9, 0x5744cdfe, 0x65c7afcc, 0xfb26de90, 0xedc5ccae,
- 0x129db2dc, 0x7d8ab5d9, 0x8bec2a51, 0x3d8ec273, 0xdb87bab7, 0xf62487b7,
- 0xcec78c54, 0x45761528, 0x3d79bca9, 0x9ffb2be6, 0x396c2daf, 0xfd89e74c,
- 0xef16d5cf, 0xba97adf4, 0xbf8aeb7c, 0x9f524ef7, 0xfe82927f, 0x94a7d809,
- 0xc0a9f12f, 0xacafe2a7, 0x2386b348, 0x5b546fbf, 0x037128a6, 0xa1f95784,
- 0x6f38857d, 0x95804967, 0x6f9587fc, 0xbfbb5c10, 0x77497ee6, 0x77f5a304,
- 0xeedf0e33, 0xe5df4e26, 0xc7a9c91a, 0x7023a8fe, 0x5ce4bd3c, 0xa3a8768d,
- 0x12e48837, 0xf7c1e1e6, 0xfee1cf96, 0xa3630da7, 0x855a9530, 0x29fd140f,
- 0xa9decdce, 0xbd83976e, 0x2495c3e4, 0x124e776e, 0x4c2b48f9, 0x835fd256,
- 0xc1ebb9c5, 0x0f6f6e7a, 0x53573b56, 0x6631fe3c, 0xf2714359, 0x4e90a303,
- 0xf14eae30, 0x123d55ff, 0xeb1fc3c5, 0x063f9091, 0x7911ad9b, 0xf849f55e,
- 0x0763d53e, 0x48f6330c, 0xc7ba9df8, 0xd73af894, 0x66d433ef, 0x894fce0d,
- 0x87fb293b, 0x7394fcca, 0xf3e7ff08, 0x8cfcc333, 0xbe01f99e, 0xabff6007,
- 0x0fb25619, 0xe72867a2, 0x1e482afd, 0x04bcf028, 0x70093ef4, 0xa41d3185,
- 0x876d929b, 0x40fe7873, 0xcbdf9d1b, 0xc8ebe209, 0x39e3f911, 0x941cbc01,
- 0x2b35f1cc, 0x9e8bc799, 0x3722a510, 0x85b649df, 0x2fb94325, 0x39322f39,
- 0x62ce73d3, 0x9cfc07f9, 0x87bcbf85, 0x574f44e7, 0xee510f81, 0x3242b4fd,
- 0x63d8fbc7, 0xf9cabf9c, 0x2a3e3ea3, 0xe225e0fe, 0xb5b0e613, 0x9e618725,
- 0x05efe702, 0x78e60d2b, 0x1728be2f, 0xc5a6207e, 0x7297fee2, 0x5cc0be4e,
- 0xec40e748, 0xe8ccc32b, 0x97cb9597, 0xafff5e28, 0x93795df2, 0xe06ddd6f,
- 0x4936eff4, 0x9edcffe4, 0x13cf67dc, 0xfe0b463f, 0xb44bb5a8, 0x9dfb5c2f,
- 0xe6dbc79a, 0xbb5f1449, 0x7cf21e1f, 0x60aed17a, 0xdd9be53c, 0x37da550f,
- 0xfb1509ab, 0x9fb4a1d6, 0xf7589f77, 0xe2df22fd, 0x8315c6a8, 0xa5a3a0f1,
- 0x3f8e2b7a, 0x7f68b987, 0xa36b1e7d, 0xd96074f2, 0xee0d377e, 0xfcfe8a18,
- 0xc51d76c7, 0x6ed76aa1, 0x4f5ca137, 0xb8cd6b67, 0xd8a006cf, 0x5b98fdf9,
- 0xf2538fdf, 0x0e2ec189, 0xfc04fa47, 0x7ffc46cf, 0x1889b805, 0xe2ff7d7d,
- 0x3e53f68f, 0xfbc3e752, 0xd0c03d66, 0xff21eaaf, 0xb562a8a8, 0x1c4df686,
- 0xcb392dac, 0xef055783, 0xf0fade0a, 0x1f16616a, 0x869ac2bc, 0x4be49c20,
- 0xfd2e4833, 0x77a8664e, 0x0557866f, 0xf8113fee, 0xe5ccd659, 0x15be3f97,
- 0xe7803c3c, 0xdf48e2a3, 0x313c236e, 0x7f4bc91d, 0xbe19b87a, 0xe1e73080,
- 0x3aa189ab, 0x54a32ff2, 0x2d469e5c, 0x38be2895, 0xb50fd997, 0xf02b3943,
- 0xbbd10d53, 0x813cdbc0, 0xf3998fb7, 0xff98e4ee, 0x93bdbc3d, 0x3c9d579c,
- 0xf5be7ae8, 0xf11bd3e7, 0xfac58965, 0x3a5f4547, 0x1fa3f219, 0x6bf1fb3f,
- 0xf0ad1e1f, 0xda3c2f3f, 0x5f110657, 0x6e5be1f6, 0x88bd35b8, 0xaa1c607f,
- 0x716bdf89, 0x60957e53, 0x57cf8021, 0xa6f57d93, 0x2e053782, 0x9deb8a37,
- 0xc23b72d6, 0xfb4c88f1, 0xee499f98, 0x639466a3, 0xfce8a729, 0xb3fed29b,
- 0x1f436dd5, 0x1b3e7182, 0x5ad3cbcf, 0xd4a91f9e, 0x3e3c016d, 0xcea459f8,
- 0x4cfdeb81, 0xfa80994a, 0xbfe933e2, 0xb87af3a6, 0x39f582d6, 0x50cc13e1,
- 0xe251ad3f, 0x7c446b89, 0x67e549c0, 0x449b6e73, 0x36f624ed, 0x3f9f8ef3,
- 0x7cfc512a, 0x9c728801, 0x6784cc5f, 0xfeaf3173, 0x46e3cfcc, 0x72df3ed1,
- 0x1f50f1df, 0x921c50c7, 0x5e778bfb, 0xf42cd1eb, 0x7a7d3bd2, 0xfe15d270,
- 0xce933f3c, 0xd808161b, 0xb85242da, 0xe7e4ec7f, 0xd33d1536, 0xd19f6c7b,
- 0x417a4e3b, 0xeafb95c4, 0x7b444f29, 0x3bc3a9eb, 0xe388957e, 0xe91d6814,
- 0xabfb7e78, 0xd1a3e7da, 0xf1d8289e, 0xb7d92278, 0xa226363b, 0xfdb0529f,
- 0xaa368957, 0x4fc9da07, 0x7775f352, 0xa5fdb9ee, 0xe77a5e4d, 0x6fdce1d1,
- 0x9c3fa799, 0x94ee768d, 0x61d79711, 0xe7e13e3c, 0xf387dd12, 0x0eb6d653,
- 0x64fcdff5, 0x46acef4e, 0xe199724f, 0x73c02df9, 0x75ddca7d, 0x93c7a7c8,
- 0x43e4d0bf, 0x9a8a5d3b, 0x399f33e0, 0x7ee38737, 0x5cc906f6, 0x0fdbbccf,
- 0x85cafda5, 0x446d256b, 0xe0b7ea28, 0xea3fe851, 0x1e698252, 0x6a8c368b,
- 0x57f3e7c5, 0x7453e7f1, 0x3853c6ce, 0xca5ab3ce, 0x10f90237, 0xafc79deb,
- 0xf1e7e14b, 0xc8966c17, 0x93be57ae, 0xad584cf0, 0x29753af7, 0xd4672f42,
- 0xce51dc91, 0x755b4e09, 0x1808edf2, 0xbb6a9ff7, 0x39c60529, 0x78b9f4f1,
- 0x149f3c37, 0xfd152172, 0xfdad049b, 0xeeb885b7, 0x83ca3aed, 0x928f48cb,
- 0xe8fda1c3, 0x853fc787, 0x0b5582e5, 0xf2885b7f, 0x147eab71, 0xf3e6174f,
- 0x55592e5b, 0xaadf3f28, 0xc211607d, 0xf5a7abed, 0xaf2f9764, 0xfd670a4d,
- 0xbe528ff0, 0x8dc7f80c, 0x7a955d82, 0x9a57772a, 0x9eda3ce9, 0xffaa08ca,
- 0x2542d2be, 0x6be9cd9b, 0x8dcb99b9, 0xe6378d1b, 0x80b3205a, 0xc1b19abd,
- 0x70632cc0, 0x9c96ce5f, 0x18487002, 0xa37dba5e, 0xa56e1758, 0x4cc4728c,
- 0x6c643844, 0x4d15a87c, 0xee14d0da, 0x6a77bd67, 0xedf23443, 0x2f1d55b2,
- 0x537ae216, 0x7f6146f2, 0x142bb6fd, 0xf9ab7837, 0xef08f9f1, 0xbe3aed82,
- 0xafeeb13e, 0xff0c4e9e, 0x78ef8c2d, 0x7c7e4357, 0x178eb6f9, 0x78b94237,
- 0x6f5a43f3, 0xf5d5bf7a, 0xfbe14c8e, 0xabe3379d, 0x5fe1c11b, 0x455fabe7,
- 0x7f6cff13, 0xf9e1ee9c, 0x7caaf977, 0xdf826ad5, 0xd9bc94ba, 0x695f5f48,
- 0x4fc8d11c, 0x98fca55f, 0x4871dce8, 0xf22bf822, 0x4b3fe955, 0xe558bfc0,
- 0xc62e3cda, 0x61bf5f23, 0xc3df0419, 0xd113e7cd, 0x69a6fdae, 0xfbae0fce,
- 0xb7bf2540, 0xebe009a5, 0x52882f7d, 0x71ed6966, 0x965f5856, 0xffe0c738,
- 0x12a291de, 0x6fdf2cf6, 0x57927fc7, 0x17e8077e, 0x4f9800c7, 0x0ee48b49,
- 0xe9ae3f40, 0x20ea0bae, 0xfb1233d4, 0xc91e27dc, 0x7a5ee7d8, 0xbdf346f6,
- 0xe3865959, 0xeee47824, 0x7ca89f6d, 0xbdb963ee, 0x7ee7c03d, 0x03ff3e93,
- 0x3f69699e, 0x3956b227, 0x4c7980bf, 0x7429cd5d, 0x9682e25e, 0x00ebb1e3,
- 0x3e3c39d8, 0x7baf64c3, 0x77342e22, 0xf59ca3a6, 0xebd96f5f, 0x251f449d,
- 0x215f8f4d, 0xf269b63f, 0xcdfa7505, 0x47787fd7, 0x71dbdd27, 0x859ed341,
- 0xb69754fe, 0x50f11d3d, 0xe79706f6, 0x941c2aff, 0x601b85e7, 0x65e7c021,
- 0x24e89e92, 0x7144be5b, 0x3c63ae81, 0xfcd6502e, 0xded3c912, 0x29971e16,
- 0x84e5b557, 0xa2a31c63, 0x59e515a3, 0x93f7046f, 0x09bdc4ca, 0x1e84e2e3,
- 0xe344f754, 0xd8b70e79, 0x3bfc5627, 0xf90187bc, 0x2ae55cb5, 0xf4a5fca1,
- 0x2dfb8640, 0xe19f9117, 0x3195fcf9, 0xbfce91eb, 0x8d1a0e72, 0xf4bdf1f2,
- 0x1c5197bf, 0x66810fef, 0xd911ec99, 0x6fbc2f27, 0x27994e1d, 0xaec530c8,
- 0x8bc9f409, 0xee5ad72e, 0x38f67b21, 0x1f2b7fdf, 0xbd89f9ce, 0x74a9f9ce,
- 0x846d61ed, 0x820d78d7, 0x6efb149f, 0x4efe1fca, 0xd138797c, 0x92f91c76,
- 0x78e215ce, 0x929c0311, 0x7965da24, 0x2d8d1bf6, 0x95cfafc2, 0x93797de9,
- 0x8e5f70cc, 0x2f289845, 0x53559720, 0xe614e57e, 0x339b471a, 0xf127f6ea,
- 0x7fa99b5e, 0xfe60c790, 0xb441f816, 0x60139d7f, 0xa6fcc78f, 0xc0492ad3,
- 0xc33195d5, 0x87e99f4b, 0x4e353d73, 0xf58f4896, 0x9d920644, 0xe9767932,
- 0x69fb6f3c, 0x83b78ab4, 0x626ec871, 0xae7e1ece, 0xee93ddc6, 0xacc8ef7d,
- 0x9056043f, 0x8cae645e, 0x89df5e59, 0xe6f5ce1c, 0x06ffdc55, 0xfb17293a,
- 0x77f2d9ac, 0xbd3da0cf, 0x5fdf10fc, 0xf98aad3c, 0xe8b3f318, 0xe784b6dc,
- 0x7939f9a3, 0xbc366766, 0x6d2baf67, 0x2a079d10, 0xcc3123df, 0xd66b2b73,
- 0x5138c76d, 0x0c3da699, 0xd36379e9, 0xe7a45a47, 0x4d77dc72, 0x79abe7e3,
- 0x724f5cdc, 0x48ccdcbc, 0x2536957f, 0xbbf18c7d, 0x8b5c63d2, 0x924faa96,
- 0x1b728e7f, 0xb8dc57bf, 0x12f1fc97, 0xbc7f26e6, 0x6e97c1a4, 0x8ffa237a,
- 0xb70e47df, 0x3233dcf8, 0x8fe72b79, 0x325ee259, 0x93b0e226, 0xbd6bc223,
- 0x0a4531cf, 0xcee4d83c, 0x74c76875, 0xbc564ac7, 0xc03ba697, 0x23ed16b1,
- 0x6bb72247, 0x9ddcdfba, 0x8be494b1, 0x34dee333, 0xdb8757bc, 0x6c3793b1,
- 0xf35ecb51, 0xe3ee2c99, 0x05600eeb, 0xf6ef0807, 0x908f8821, 0xe1a8bca4,
- 0x9e3ee883, 0x7c607713, 0xf27b9c48, 0x446fc75f, 0x38b8e85c, 0x7bcca9bf,
- 0x9714546a, 0x7449cc67, 0x19ce2ad4, 0x4a367929, 0x1eb10aff, 0x3d077ec5,
- 0xfb43fe1d, 0x934fb825, 0xf269f62f, 0xbe4d3ec5, 0x17c9a7d8, 0x62f934fb,
- 0xec5f269f, 0x7d8be4d3, 0x4fb17c9a, 0x69f62f93, 0x0d3ec5f2, 0x54e2c3e5,
- 0x11cdff31, 0xd1ea34fb, 0xc1b5e456, 0x10e9fa9e, 0xdf60fabf, 0x2443a7f6,
- 0x8960fadf, 0x257c4fda, 0x118769f6, 0x2166a3e3, 0x547c789f, 0x2a79df39,
- 0xe1193ed0, 0xfce79cac, 0x03a9f72a, 0x42934fc8, 0xd9bf90e6, 0xca26fe0b,
- 0xf6e1caa3, 0xec776c3c, 0x2df8c4d8, 0x140d2724, 0xe0fd3ce7, 0x98739f08,
- 0xacc793e3, 0xc6307bc5, 0x7e71251b, 0x9e647abc, 0x38c1ffe2, 0x66165b13,
- 0x307cb9a8, 0x2d9cbda3, 0x77e3e497, 0xc61a4796, 0x24d61ca0, 0xf70ee7db,
- 0x8339db92, 0x5da3c597, 0x7cb1aad4, 0xc75af18c, 0xbf3a1a07, 0x94f5c4ab,
- 0x8d25ef76, 0x937ec42f, 0x8ed6e393, 0xfcf5f1c6, 0x969b38be, 0x6cfce035,
- 0xee8940aa, 0x3516616e, 0xe1c283ca, 0x58266e9c, 0xd6ec7db8, 0x1821d45a,
- 0x1f18098f, 0xad13798a, 0x04c7cf02, 0x3c0b8f9e, 0xa4d77ee3, 0x85dfbe04,
- 0x6177ee25, 0xd58de4a9, 0x1f2de4a5, 0x27b4f24e, 0xc4ace11a, 0xe728a6fd,
- 0xee8b98fc, 0xd0517c33, 0xbe70d26d, 0x7261f2cf, 0x09c3a3de, 0xb73a2e3f,
- 0x69e22c59, 0x437f629d, 0xcfd2a759, 0xfbf19fd3, 0x0732465c, 0x83b367ee,
- 0x08764f22, 0x9f5023d8, 0xe49c3079, 0x7a1e7290, 0x07ee18e6, 0xfce27db0,
- 0x13258462, 0xc44aa3f9, 0xfc9cbb53, 0x48696d1c, 0x239e225b, 0xa57c12e8,
- 0xd17395d4, 0x6ea1a3a5, 0x284b9cf4, 0x8896d99d, 0x24ba12e7, 0x0dce8a83,
- 0x4fefe76f, 0x8d2bbe09, 0xf729e315, 0xd15de84e, 0x43ee8788, 0xbcf1a307,
- 0x7ba326dd, 0x6efb9729, 0x2811de7e, 0x3a96f316, 0xcc19d725, 0xf7747dcf,
- 0x1e63f71b, 0xf5c6a77d, 0xdb1fd622, 0xcc7ee87d, 0xf694edcf, 0xbf7b319e,
- 0xc68ae41f, 0x7747ddfc, 0x83f7f0b7, 0x6c18bef6, 0x5e6baaf5, 0xb5ef833b,
- 0x8fdd0e6b, 0x7553bcf9, 0x489563ce, 0x74e7bf2f, 0xffb3d865, 0xb8adc21c,
- 0x13eddb99, 0xf4bfecf6, 0xfde5ea1a, 0x3fefda26, 0xe0863c38, 0xf2fcd55d,
- 0xaeb3a466, 0xbfde3cbd, 0x17a3e1a9, 0x74ed417f, 0x54dc0d74, 0xc1832b9d,
- 0x9eecd677, 0x1a9af34b, 0xeb1afae8, 0x46388d4f, 0x903a98f3, 0x11d6f3f3,
- 0xe78fddef, 0xeff6ba01, 0x6ef90479, 0x683000ea, 0xf9bb3e71, 0x7da2a0f9,
- 0xbfd09329, 0xcdb532ef, 0x5ecbf1c7, 0xf339d1d1, 0x74e17da2, 0xc3dbc72f,
- 0x9939f963, 0xa8d1d5e1, 0xefaf5567, 0x508bf1da, 0xfda0676c, 0x6e10f29e,
- 0xb5c915e7, 0xfe110f59, 0x3cf1da5e, 0x81977bce, 0x310b5ff6, 0xc2f502a6,
- 0xa714091d, 0x5f1fe37f, 0x643c47cc, 0x7ce8dbcb, 0x0675d7cf, 0x94e1c215,
- 0xcf0036d6, 0x694e38d3, 0x142cdfc8, 0xfcd3c2f5, 0x60517dbc, 0x2fe10e7b,
- 0xf51a3ab4, 0x47c0d16c, 0xa7bce3a7, 0xa22fd5ca, 0xe65ec3bf, 0xd85dc6f7,
- 0x7e837005, 0x9435ea17, 0xcbb5daad, 0x3be2e744, 0x78f9eaa5, 0x9ea3893f,
- 0x5434ebb7, 0xf51d3c13, 0xb4defc49, 0x48e8305d, 0xe7c5b76c, 0x97fa85f9,
- 0xbd1fd1d3, 0xf254caf8, 0x55fa154b, 0xcea8a5f8, 0x3f1d7cff, 0xfe245ab7,
- 0x33076666, 0x2e93c57a, 0xebae781e, 0xffd3ccb7, 0xce868362, 0xd8ea1779,
- 0x560fcc5a, 0xea28a1f8, 0x5f5c5cae, 0x1136aa91, 0x31c296ed, 0x2f91f3ed,
- 0x3e98182e, 0x27bdda02, 0xe35155f4, 0xff6819ea, 0xa63e68de, 0xbf8f9c11,
- 0xeb7ae089, 0xd383269b, 0xbfd1bf7b, 0x9992b4fc, 0xd4f04fdf, 0x7be15a7f,
- 0xad3df0de, 0xb4fd04ab, 0x3f2e10b2, 0xbc7b40ce, 0x7c502e93, 0xbf4ac167,
- 0x78239273, 0xb699645e, 0x9ef5113d, 0x863ffe32, 0xa85db99b, 0xb7fba76e,
- 0x454dfbfc, 0xc8e50473, 0xb79e7e6e, 0xa0ea51a8, 0x52082273, 0x8b667baf,
- 0xe6270ef4, 0x8787f509, 0x07812c88, 0x11b9eb18, 0xa28f3431, 0x079d0306,
- 0x0f680e2f, 0xc4a93b42, 0xf6841ed4, 0x32ebd74f, 0xe889c3dd, 0x8fc6550b,
- 0x894f7cf5, 0x34ba1613, 0xdf7f4336, 0x1c60e583, 0x0dfe1972, 0x047578a0,
- 0x682a27df, 0xcfe7e40a, 0x1e74edcd, 0x263cffdb, 0xc5ecd3ae, 0x2f4d5d8f,
- 0xe9fb7985, 0x797047a3, 0x10752dd0, 0xe3ff74df, 0x83a468f3, 0x8b5b1522,
- 0x251795fb, 0xea022e7e, 0xa2e21e74, 0xfa2cf7d8, 0xf48018d6, 0x129bf173,
- 0xa92ee3e2, 0xfb5ce49d, 0x7c933fee, 0x93b4d2e8, 0xc468fb9c, 0xe8fc937f,
- 0x8f9f6e0a, 0x447dab72, 0xd91f7f0f, 0x23cf1f3e, 0x7c7589bd, 0x81fff78f,
- 0xfddaeffe, 0xefa8fded, 0x8f3ccaa7, 0x31a4bd82, 0x8710f8f3, 0x270132f7,
- 0xae9c36c6, 0x6343ff24, 0x2dd0fd41, 0x166f03e8, 0x98fe5e64, 0xcc5d4fc2,
- 0xf911a7b2, 0xc7df80b3, 0xc3557603, 0xcdff686b, 0x84fba309, 0xeca6e1fc,
- 0xfc868633, 0x69e2296d, 0xc0fec986, 0x69538008, 0x17f93b6a, 0x87a4ed40,
- 0x91d4deca, 0xe9add99f, 0x2bf281d9, 0x8b9f64c5, 0x6db44aed, 0xbc2433eb,
- 0x15bda0a7, 0xca29fa4d, 0x3997c7f9, 0xbea575bd, 0x884dcfc4, 0x8162ca7d,
- 0xb25bbc07, 0xe243e916, 0x69ab7e78, 0x6f28fbdf, 0x48e2daba, 0xd3f3fb4e,
- 0xe8a7a685, 0x404f8a9e, 0xe2bc3baf, 0x7c2c9f00, 0x6601f299, 0xf1881e63,
- 0xbdbe73fa, 0xfe4bdddf, 0xf5ecdb20, 0xc6b1e91c, 0x170feeb7, 0x0fb74ba4,
- 0xde68381f, 0x00df903b, 0xda13c5fe, 0xbe877ee8, 0xcba84cfa, 0x7e23f55e,
- 0x78f6bf75, 0x0fda005f, 0x505d843b, 0x9a7dd432, 0x3c3df7fc, 0xf40ab76f,
- 0x07f7d51a, 0x6aa57e52, 0x50ade80f, 0x5f50b7ae, 0x51b50714, 0xbf6baadc,
- 0xd779f68e, 0xc68f9f34, 0x523d03f5, 0xf9b8a67c, 0x7ccbdd20, 0x4c87fd10,
- 0x94618fd2, 0x39bfb317, 0xe510fd0c, 0x95ca8979, 0xd3f5f228, 0xcf287e51,
- 0x2277654b, 0xda95f39d, 0x8388fee8, 0x2a25de62, 0x1758cba8, 0xdf3896f3,
- 0x2f7e66b3, 0x5ede3f96, 0x76edc119, 0x9f740f90, 0x79d79ae7, 0x079140dc,
- 0x1cae4285, 0x9ca9e7c1, 0x3ecacdff, 0x442d7411, 0x4e47efbe, 0x0b308f24,
- 0xe282b87f, 0x58463b3a, 0xa7f45d78, 0x89dc7971, 0xd1bd97de, 0x8a9b1e99,
- 0x3dca2cfd, 0x14791e5f, 0x282f91e7, 0x0e482207, 0xc184d1ac, 0x945e8aba,
- 0xc2a2fee8, 0xa073ab79, 0x7ea65b39, 0x2d49ee88, 0xe35bbcc0, 0xa7f2f3f5,
- 0x57b8f1a3, 0xec52f288, 0xe0ed1503, 0x351740fb, 0xe40d1f7c, 0x2ff5e50d,
- 0x073ab49b, 0x68496ff9, 0x4fdbd6a9, 0xd7f8d9be, 0x58af5b9d, 0x0fde139d,
- 0xdcad179f, 0x5d883ad2, 0xbda15e3f, 0x72cc2736, 0xde6573fd, 0x3cca0d17,
- 0x79066827, 0xeaf663c3, 0x734fbc1c, 0x85dffe99, 0xc5f75f07, 0xf51b9d66,
- 0xf697c02e, 0x56bcee83, 0xbd5f13e1, 0xcc8578d9, 0x371ffb49, 0x597fbf9a,
- 0x534fb922, 0x57f02d5e, 0xf9d9f13d, 0xa0fdef68, 0xf6be4229, 0x160a25c5,
- 0x407ba30e, 0x79870bec, 0x4bfc25c7, 0x55839410, 0xa0e23394, 0xbe70f812,
- 0x28781fb5, 0x0467ffed, 0x329a4fcf, 0xe0d5f382, 0xbdcfc5a9, 0xa39e28c6,
- 0xe3741d4e, 0x54a621f3, 0x7cb74fce, 0x2062643e, 0x60c8776f, 0xf74fb8c6,
- 0x5c51bfa1, 0x719d7bb8, 0x306fdf36, 0xdf7848b2, 0xddb6911a, 0x8afbfe3b,
- 0xe7814738, 0x7efce9be, 0xe387e6b2, 0xbea6a94a, 0x1bd912b8, 0xcfb481a9,
- 0x9574d5d2, 0x4b775bf4, 0x43f719a6, 0x469cdaba, 0x7ff2b7e4, 0xea184ffc,
- 0xb396aee1, 0xf5d69794, 0x57ca79dd, 0x06f228db, 0x7c89348f, 0x098b36af,
- 0x7ee7779f, 0x36ed8391, 0x5713d289, 0xa53171e0, 0x2565fc54, 0xff75e07e,
- 0x6b8428d1, 0x93e379bd, 0xa60f3019, 0x1ddfa6af, 0x0439ff00, 0xae2787f5,
- 0xa1ff0960, 0x2b8c4a3c, 0xb8f027c4, 0x57189602, 0xb8f0d788, 0xae31d602,
- 0x15c62580, 0x15c639f0, 0x05718eb0, 0x015c63ac, 0xc05718eb, 0xf80ae312,
- 0x8e716bfc, 0x378c1ba3, 0x9234f71e, 0xcf515ffc, 0x88576bf7, 0xd457a1fb,
- 0x85b7944a, 0x0f5038e7, 0xd3c7975e, 0x5c78f228, 0xb03f685b, 0x456cbf7c,
- 0x0f79e154, 0x79f30e87, 0x3c628e7a, 0x64af7ca8, 0xe7c16d5d, 0x1b1e69b3,
- 0x9e3f325b, 0x35ebcf87, 0xac97bc56, 0x309be5bb, 0xb515778c, 0x6adc53d4,
- 0x2d21f852, 0x6241b9e1, 0xa59d6f18, 0xa9727ee3, 0xd3474f0c, 0xd1d929be,
- 0xf236baa5, 0x4a778a5f, 0xddf3ef66, 0x90af63e5, 0x9bcbe89c, 0xf9cc1972,
- 0xc6d5fa3e, 0x4ff0aef3, 0x57d88fc4, 0xf49bca5e, 0x3d9159e5, 0x2d1f65e2,
- 0x7c64fdc5, 0xe7477f2e, 0xd1c14a4b, 0x93f5281d, 0xcfb7e587, 0x77b2d45c,
- 0xe29bde3d, 0x77dcdfbf, 0x9f6fcf5e, 0xd8aa6579, 0xcfc51e4f, 0x9d3ee489,
- 0x7c3f67bf, 0x475ab7af, 0x70e54af6, 0x266a657b, 0x28d86be6, 0x90f472ee,
- 0x2fadfc81, 0xc4f924b7, 0x21e5b25d, 0xae58f714, 0x6b8f4891, 0xb0ebed92,
- 0xc5dcc4df, 0x18996f14, 0x567e2261, 0xa4bdf0e8, 0xfdf1c7bc, 0xc50b34f2,
- 0xec75b2bb, 0xc89e3467, 0xf89282ef, 0xa24abb2d, 0x3217a97b, 0x597b9d2b,
- 0xf2f7e360, 0x2de8f729, 0x41cf3c60, 0x5be5aba1, 0x282bb224, 0xfb861100,
- 0x0b9e1c9d, 0x7ba1de5a, 0xc4eb164f, 0xbe2a7e3d, 0x89b51e1f, 0xc12cbfe7,
- 0xdef0a41b, 0x58abd010, 0xb37d9e82, 0x03db9e1d, 0x3b734487, 0xe38e12df,
- 0xa1ae3c2f, 0xf0ece13c, 0xa4ed13bb, 0x3e5127ef, 0xf6ef5e03, 0x921f88fd,
- 0x0cf9bea3, 0x43793547, 0x48addd70, 0xb1e714a7, 0xb2bc7953, 0x9e254a80,
- 0x762fe4a3, 0x17b83a1f, 0xce5d9fbf, 0xe1bde5ef, 0xfe80bd79, 0xe729adcf,
- 0xf9145e15, 0x53aa5175, 0x75fcf063, 0x2b46b7d4, 0xfc3b3fae, 0x8af79d10,
- 0x4e1fe313, 0xe5037bcc, 0x39882d8a, 0xcbee1fb0, 0x733c0354, 0xc6120170,
- 0x3c365dcd, 0x4873d337, 0xf51e5332, 0xcb73f275, 0x29efcc3a, 0xdee8978f,
- 0xea809cf0, 0x3f1830ec, 0x8ac63627, 0x89bcbbf2, 0xa0bb5dc7, 0xc3bf78e4,
- 0x3181f749, 0x14d73f7e, 0x2490b781, 0x4cd489fb, 0x82a9f3cf, 0xae5bba6f,
- 0x9be1fcf2, 0xe8eb65c7, 0xb06613be, 0x21b1f72a, 0x188ea7de, 0x8559f14a,
- 0xc21b7a6e, 0x7cdd23b7, 0xbcc3f42e, 0x68352779, 0x6c987c3f, 0x30e10cff,
- 0xbacaff3f, 0xff675a30, 0xcf2531f1, 0xa63e3fde, 0xabffedc8, 0x2bf7fafc,
- 0x513ca82b, 0xb6ca92b9, 0x07bd074a, 0xea75f0bd, 0xff55c5ad, 0x8ff5f08e,
- 0x65bd32ab, 0xe057e900, 0xf6c71e6f, 0x5f02a38b, 0x7af8bcab, 0xa2f04b62,
- 0xd47f680d, 0x4ffee968, 0x615e77cc, 0x49a03924, 0xaa9e37eb, 0xf148cdc0,
- 0x18665ed7, 0x909ff08d, 0xc156a71c, 0x926901fb, 0xf200fecf, 0xf90fae09,
- 0x13e44b04, 0xf3dc57b5, 0x70b02d05, 0x1c07b706, 0x08180f64, 0x8357ebaf,
- 0x1ef090fc, 0xfc8fb325, 0x3f27e4b8, 0x907971c0, 0xf0b57dce, 0xef2526fc,
- 0xd7140273, 0x4f23f746, 0x0c9e5c5c, 0xc2ed700d, 0x0b2d0cef, 0xa3e2bca0,
- 0x475f4e1a, 0xb9bcf237, 0xefc7967c, 0xae5eba6f, 0x163e2104, 0xf339ec0f,
- 0xfc5fb43c, 0x35d9232b, 0x669723eb, 0x257227fd, 0xc3c38d20, 0x63258131,
- 0xcacdf27e, 0xe045ee7e, 0x314e66f7, 0x2e5b9f91, 0x7cb2a0ec, 0x72a7f133,
- 0xed4cb43e, 0xed8f58ea, 0xff3c4d42, 0xbee8cd43, 0xc1aa5396, 0xc1599efc,
- 0xc4a6a767, 0x58605e51, 0xa887bf15, 0xee896ee7, 0xc8149e03, 0x56c857ef,
- 0x0cbc95e5, 0xb956dfef, 0x54c1efc5, 0x122bf8d3, 0x73d15c79, 0x6bdb951e,
- 0xba26b951, 0xbaf6413f, 0xc631a93f, 0x39f45eeb, 0x6ecfbefc, 0x4dff72a7,
- 0xa087bcde, 0x7e1ccd5f, 0xb33766cf, 0x03fb813c, 0x7100828e, 0xb5e8127f,
- 0x99fdcf0c, 0xedc9fe07, 0x15429ebc, 0x19ad539d, 0xeb8d5965, 0x42cc79aa,
- 0x27f73def, 0xe8dcf871, 0x82db9c3e, 0x8369f9ec, 0xe717bfae, 0xce6f2919,
- 0x669fec12, 0xe34ff7e4, 0xeed08de5, 0x4fe19ce8, 0x0e3840ec, 0x3da264b1,
- 0x706c68be, 0x11f40496, 0x06f306a5, 0xd4630fe8, 0x46d05f74, 0x71f313b5,
- 0x7dc5a887, 0xef216a01, 0xd180c861, 0x85a6ded4, 0x96a7c2fa, 0xabea1b31,
- 0xf3f74628, 0xfef9ebc6, 0x5863f438, 0x4646b862, 0x7c78c83d, 0x3e00e168,
- 0x4670c2fe, 0x45a5cfbf, 0x3bf25016, 0x2677f0b3, 0xb0bbc518, 0xea68d07f,
- 0xfef150ef, 0xc3943536, 0x523df8e2, 0xb474eb3d, 0xf1f0ba2f, 0xa71fa4a1,
- 0x773df04d, 0xe78d327f, 0xb8e5282d, 0x9f0f8b74, 0x429b5a2f, 0xd68b8bfb,
- 0x3b4529ce, 0x4810dec4, 0xef3b02e7, 0xef0ba97b, 0x9d962f71, 0xf5823f4b,
- 0x57b74ecc, 0x4a2f7c23, 0xa1fbf996, 0xdffba2c1, 0x8c9e62d2, 0xf2e335dd,
- 0x774e50eb, 0xf7813dec, 0x4fbf4de4, 0x19d3fea6, 0xad9a8fbf, 0xde6cf7e5,
- 0x8ea2b8ed, 0x1eeff180, 0xbcbc5127, 0x468e60c3, 0xc0a16efb, 0x5c69f3d7,
- 0x3f5c2f7e, 0xebfd1134, 0xbddf71bb, 0x5a733d1f, 0x0fde53b4, 0xfc7cc89b,
- 0xfbc54f9b, 0xfef8d34f, 0xfe38b0fc, 0xae837f3e, 0x4b082e23, 0x4a093b8d,
- 0x4ec2758d, 0x58b4cf5c, 0xe115b396, 0x378f28f8, 0x9b981876, 0x8d3eb1e8,
- 0x3d676ae0, 0x3ae38f1d, 0x3ad046ea, 0xa39bc63a, 0x710e5ee9, 0x3312eb7f,
- 0xe31d4f97, 0x98ce77f9, 0xa9214ddb, 0x1ef07f9c, 0xa502c5d7, 0x3d565767,
- 0x5bb41b79, 0xe74f4abc, 0x7d3c9735, 0x8b2bf92f, 0xa73a646b, 0xdefb36c9,
- 0xc4fa0ae3, 0xbff3f38d, 0xdeffd58f, 0xd239c455, 0x8966fe41, 0x955868e8,
- 0xf1fb8b55, 0x4ec05b3d, 0x46f9f780, 0x05da3c77, 0x758356f9, 0xbdcfd48d,
- 0xdc01dfac, 0x6b9ef0b2, 0xcf93f146, 0xe01fedd3, 0x2f561777, 0x03507ba4,
- 0x1714ed53, 0x217e061b, 0x48413fda, 0x69d7003f, 0x7fba5e00, 0x891edd42,
- 0x34facffe, 0x9cc43cf1, 0x34ba2468, 0x0ee7e430, 0xe711398d, 0xa0ceb1d7,
- 0x6d319942, 0xe04fa70d, 0x347abd1b, 0x0160339e, 0x4bbfbfc8, 0x6f3974e3,
- 0x16af3ab5, 0x6d4043ea, 0x6e90429b, 0x4e7d1146, 0x50ebdab6, 0x18f57daf,
- 0x73728b1b, 0x7c2de6f1, 0x4cff025e, 0x34e746dd, 0x198faabf, 0x0a06798d,
- 0x4eb64c3d, 0x4de69b38, 0x8449f707, 0x31cf587f, 0xeb1a37d4, 0x2f5c4ea2,
- 0xf48c3f3c, 0x9b826d31, 0xe5b212f2, 0xbcfdfa12, 0xf74608de, 0xce32f4f2,
- 0xd41bbdaf, 0x391467a4, 0xa003c8a1, 0xd39e1b07, 0x7ffdf055, 0xf2287f65,
- 0x7243e006, 0x8a1b9145, 0x4be8517c, 0x74fe3391, 0x7cc01f35, 0x4fea68e7,
- 0x63914cf2, 0x68d50eb8, 0xf0517c8f, 0x5e30d9ac, 0x81577145, 0xd2f96ce7,
- 0x8708839e, 0x2dd92302, 0xea31707d, 0x5ad12e09, 0xcff784d6, 0xb7943d56,
- 0xe3d22977, 0xd063732f, 0xe05b98fe, 0xa7f29e7b, 0x28e7be15, 0x3df4ac17,
- 0xe56f3947, 0xfc628e9f, 0x0fb00d89, 0x9cfc074b, 0x17b9e5f9, 0xefea863e,
- 0x8131797e, 0xea97d9fb, 0xaeefc59f, 0x68f3100a, 0xa55af3e7, 0x4c31bd25,
- 0x0ff881d8, 0x7188b2f1, 0x13185d3e, 0xdff5027c, 0x093f105f, 0xf1c1ffb8,
- 0x67e04673, 0xe80fc211, 0xae3ae17e, 0x121c3a97, 0xad1623c5, 0xc1ba7c15,
- 0xe7f47cf7, 0x303dac91, 0xfa8e73ce, 0xa312c7f3, 0x7395af91, 0xfc0df6d3,
- 0xf2b4b55c, 0x762fd918, 0x872d7ee5, 0x2b5afddf, 0xebf9f95b, 0xcd73df76,
- 0x2d361981, 0xf7182bc5, 0x1f2516a3, 0xd536f9e1, 0xbbf71992, 0xfcf3c5f3,
- 0xb9cf920d, 0x1e749cb9, 0xa698da17, 0xa3b63c26, 0xcaf1429d, 0x0a2fd26a,
- 0xa0dc829d, 0xd5f97c73, 0xbd4bb4a3, 0xf122e8e4, 0xcab2717c, 0x36d777e7,
- 0xebfdf1a6, 0x181a6476, 0xac725377, 0x3bc90976, 0x9547c50b, 0x47928bf6,
- 0xc1b8c7af, 0xebf8cda2, 0x33fe9e47, 0x367cf9d3, 0xdc94f98a, 0xe5f7ce40,
- 0xb79fe155, 0x9fc9bcd3, 0xf7757a2e, 0x033bf8ab, 0x91d57f45, 0x291a299e,
- 0x9d53d9f6, 0x3ed2f759, 0x55d73f32, 0x693df026, 0xe84167f7, 0xf2379427,
- 0xeca1b2fb, 0x556cb2c0, 0x65fbf901, 0x9087e056, 0xdfbff3eb, 0x41aff57e,
- 0x88ecbe3c, 0x47ffbf12, 0xd65563bf, 0x1fc505f8, 0x64772ed0, 0x4f9478d0,
- 0x5cbfdfee, 0xfb882efa, 0x9704edb1, 0x84df43ec, 0x5ff63cd1, 0xf979b8a5,
- 0xf66175a1, 0xdd7dd67e, 0xcf110139, 0x2af81728, 0xe0af9b67, 0xaaf95afe,
- 0xc82cf3dc, 0xbf7fbe33, 0xce22e975, 0x8dbb1b70, 0x4cd5d6f2, 0x5ccf7de5,
- 0x07e133af, 0xb7cb25f3, 0xbd9d73f2, 0xdc00cb6a, 0xe716eb97, 0x1ddbfcb4,
- 0xc37ee74f, 0x0c27e065, 0xc8377444, 0xddd3cfb4, 0x6578e3c0, 0xe2b54f0d,
- 0x7032d8f9, 0x959d919c, 0x8d654473, 0xeb7bd332, 0x1a47cc35, 0x1679e378,
- 0xfdd136ef, 0xc92e8534, 0xe9f30f56, 0x90697f05, 0x165e7cd7, 0x73ac5574,
- 0xcaf8e165, 0x72105ffc, 0xd857694c, 0xb79d14f2, 0x645d7685, 0x903efc9f,
- 0x9eb2fdf1, 0xcecf3813, 0x7f68636d, 0xb7b5d0ab, 0x0d8fe28c, 0x72b79481,
- 0x7e7be351, 0xdef89f7b, 0x676e74be, 0x24de6274, 0xa6557ff6, 0x13ce19b8,
- 0xe4a2f1f9, 0x2cd1cf9b, 0x73a735fa, 0x3a7e653b, 0x7da503e7, 0x2823aba1,
- 0x6f9fda1e, 0x6f9513fa, 0x6f7c7b61, 0xbd474b6c, 0x9031be79, 0x6f9ed3ce,
- 0x0de73e7c, 0xd765def8, 0x8bc950f8, 0xf3a74ebf, 0x6de5e5f8, 0x73b05ce2,
- 0xe26738a0, 0x3674f5a2, 0x5fe84944, 0xaffc8a96, 0x417dc6ce, 0xc75fe22a,
- 0x627bf67f, 0xefbbafb3, 0x264c77ac, 0xf76cbf9e, 0x7fecefb9, 0xf132fc6b,
- 0x13caa8dc, 0xb7bfe1df, 0x5ddf94ca, 0x4a76f331, 0x48fe763c, 0x0e7803cb,
- 0x7fc7bd97, 0xfeec0d97, 0x9a3fd167, 0xe481c7ff, 0xadefe27f, 0xf7ebfd60,
- 0xfcd9bef9, 0x44ae4231, 0x4cbe53b4, 0x1fb70c47, 0xcc48364a, 0x062b7006,
- 0x680072fa, 0xb3329c4b, 0x231dfde3, 0x2772fef9, 0x2476bfd0, 0x67ca0bc9,
- 0x1dfe0339, 0x6bc10efd, 0x24b93f7c, 0xe7889dd6, 0x5e453b03, 0x3b884941,
- 0x7b8c2071, 0xc949d049, 0xb7a2774c, 0xddb2537f, 0x9735794d, 0xbe1d3e44,
- 0xc95e78c7, 0x23aede68, 0xe745dcc6, 0x189bf638, 0x83aaabda, 0xd2c3a226,
- 0xbddb0d97, 0x4699d5cf, 0x92fffb72, 0xee1bdf96, 0x53e7c1d8, 0xe34d5418,
- 0x5df4125c, 0xf34d5018, 0x29ce233b, 0xbd796a17, 0xbee8c343, 0xfc5d9efe,
- 0x918ba13e, 0x3bf0076d, 0x50a57717, 0x8c4769de, 0xbd136973, 0x452679e7,
- 0x38dce8af, 0x4cbb0baf, 0xf7282e74, 0x9f695b97, 0x274eb7b1, 0xc2e1dc61,
- 0x1ee74620, 0x220fd42e, 0xb2417d7d, 0xc2f37c50, 0xbc6903bb, 0x7495caa2,
- 0xc408a5be, 0x509dda04, 0x76bda2e6, 0x68b9fea1, 0x6fa85fe4, 0x559dbac0,
- 0xf239ffcf, 0xbbfe4ee9, 0xf95f1710, 0xbef78a7b, 0xeffa528f, 0x54f8289f,
- 0xe48da7de, 0x923698fc, 0x91a8f3f3, 0x3bde7e66, 0x2c4cf5d0, 0x37f38fad,
- 0x02fc99c0, 0xafba27e0, 0x39ab8ce7, 0x8a71824c, 0xa86c9a0e, 0xee343bdf,
- 0x0e09e7c4, 0x7877e281, 0x1785f918, 0xbf240c76, 0x1a68ac1c, 0x348ec2e7,
- 0xf252d3ca, 0xada1a64d, 0x234c7846, 0xdbcb66f8, 0xe5fee9d2, 0xc7ca40ba,
- 0x36fc7a29, 0xc89fe515, 0x7a2eeedc, 0x5134f175, 0x4d7ee1b7, 0xa17fcfd1,
- 0x93e28bc0, 0x89695e4a, 0x8fa5a390, 0xf30031df, 0x651fd970, 0xaabb93ca,
- 0xfe8f79e6, 0x48e5f970, 0xbc0f4721, 0x025b7c40, 0xc3bf8e74, 0xc2f22c54,
- 0x71e15f8b, 0x77f5e296, 0xf1f24b3c, 0xde618684, 0x53d725ef, 0x2f70de41,
- 0x96e5c918, 0xda95bfa7, 0xde7b4317, 0x9a20bdff, 0xe50d0ecf, 0xebe3fb29,
- 0x22bffb96, 0x8bfd5bff, 0xf407605c, 0x957c1fb3, 0x57f23db5, 0x060d0394,
- 0xf29e83ab, 0x8d4ebdfc, 0xdf3f296b, 0xd0f92060, 0xaf7e2c19, 0x11e792b5,
- 0xfa9faf14, 0x3857ca6b, 0x699d2f75, 0x7fece65a, 0xa474aebf, 0x0f8bef86,
- 0x3e400eb4, 0xe07c052c, 0x3a1f8078, 0xa8fece5f, 0xebfefea1, 0xcb923a99,
- 0xdc3e3ef5, 0x3ba1f3c3, 0x74bc7307, 0x7a449abe, 0xd39823a7, 0xfc97cc35,
- 0x5e60ced4, 0xe604a252, 0x3d3998df, 0x91778e74, 0xed29ddff, 0xc343b2a5,
- 0x14ad15fb, 0xe6e22bbf, 0x482523f9, 0xff7871b3, 0xb436e6cf, 0x671e503b,
- 0xadd2a68d, 0x1efeb90b, 0xf263a076, 0x7e0a8eef, 0xe870f252, 0xae280177,
- 0x3ca2d2e9, 0xafbb0bb5, 0xdffae1a4, 0xefe7e08b, 0xae43ca25, 0xfb29291b,
- 0x540794ec, 0x2b3c25cc, 0x9fb44876, 0xa1f6bc5f, 0xe2fba442, 0x91732d8a,
- 0x1475941f, 0xfa2e59ab, 0x4c921d49, 0x7ebf01f3, 0xebd4ccc1, 0xf7c0a7bf,
- 0x197ccaf7, 0x3d27cfdf, 0x6fb6bc03, 0x53b145a4, 0x578c3559, 0x4cda56b2,
- 0xfc5189df, 0x053ebe4e, 0x83efb84e, 0x3c4a8cf9, 0x57eb46e0, 0xf9a379e6,
- 0x75e423bc, 0xd7e58c47, 0x1fdf10e3, 0xae4f24c8, 0x4066377e, 0x6dd80fc8,
- 0xcaa14bf4, 0x0fff3078, 0x38c11751, 0x56790acf, 0x79c3f30c, 0xfdf36e26,
- 0x3ae4807d, 0x06f0fadf, 0xa36a7adf, 0xc5bd3d6f, 0xdb7d6eb7, 0xdf82deb7,
- 0x09c0f4cd, 0x073c61fd, 0x879c53b1, 0xcf187f40, 0x8c3fa133, 0xb187f475,
- 0x9f187f44, 0x758c3fa3, 0x8eb187f4, 0x8925b0fe, 0xa258c3fb, 0x65cf8c3f,
- 0x4953872b, 0x023f8f2d, 0x2fb46c1e, 0x5df9473f, 0xd10bf00a, 0x421c2d1e,
- 0x7cc61d76, 0x7e9577e9, 0xd2296d79, 0xfd930cd1, 0xcc4cc8d2, 0x1f5b6ac7,
- 0xf2fded89, 0x1b464a94, 0x686f188c, 0x3d7e775f, 0x2629219a, 0xaf6c15fb,
- 0xae952fe4, 0x4f7e8b7c, 0xe5b57daf, 0x78e13f8f, 0xf287b8a2, 0x78454f7b,
- 0x714cbe4f, 0xf8a33d2e, 0xdfdf559e, 0xf9fedc3d, 0x679ab746, 0x5801fff4,
- 0x00db8bbb, 0x0000db8b, 0x00088b1f, 0x00000000, 0x7ccdff00, 0xd594740b,
- 0xe6feefbd, 0x49324995, 0x41e42126, 0x21e4cc20, 0x49389311, 0x47114bc8,
- 0xa8d53048, 0x684d43c3, 0x4092138c, 0xa3c30480, 0x7b96c4eb, 0xa4401833,
- 0x51b78d70, 0xa13a3951, 0xe85de94a, 0xb6950a09, 0x1006739c, 0x4e6d8ac5,
- 0xb6abad5b, 0xa9078838, 0x68349687, 0x69edec57, 0xdff7ffef, 0xbef997df,
- 0xbc7b5249, 0xacdd77ab, 0x7bfe7ba5, 0xfe3f6fef, 0xeffffdef, 0xfc42108d,
- 0xfb5bfe85, 0xdaf08c7c, 0x85fdff05, 0x442fdfff, 0x59cf10b9, 0x0e9d3247,
- 0xd77c2e21, 0x4f5c5bbe, 0x1868ac65, 0x06e6a42a, 0x09a449bb, 0xb8df11b1,
- 0x5335a884, 0xef0479a7, 0x28c7f651, 0xa4f34c42, 0x885d3108, 0x49f933d1,
- 0x05fffa82, 0x2c4f377f, 0xa8cac75b, 0xadde0eb3, 0x6ccf3098, 0x548af09b,
- 0x735dfb1a, 0x4f1a05f0, 0xa24d79d4, 0xea4d8842, 0x35ece71a, 0x59105109,
- 0x38c1b5ef, 0xbfeb7421, 0x018a60ee, 0x619a1a2e, 0xb1fd7fe8, 0x497b431c,
- 0xbda1ae68, 0x13d6f96d, 0x962144e6, 0xf4332eed, 0xbc116abb, 0xa7cfabcf,
- 0xea6e0307, 0xf0d1bbe7, 0x3aea109d, 0x936eb29d, 0xc3fce475, 0xd1d37fd4,
- 0xe3004f4c, 0x2f0b35ee, 0x8d03b7ed, 0x2b6442a5, 0x4f181d81, 0x179e2a0c,
- 0x6a56bc68, 0xe8bb53f7, 0x9d38f3b1, 0x2c3b7e2a, 0x2da4e022, 0x9bf3447d,
- 0xd1e77fa9, 0xc256e0f4, 0xc9c61f4b, 0xf0a776a4, 0x6b78d326, 0x87170ee6,
- 0x6f359c68, 0xd042bb7e, 0x83ccbb16, 0x215cced9, 0x03c12b36, 0x9f10b34e,
- 0xab4e1ca4, 0xd98776a6, 0xf443c8bf, 0xfca67cb9, 0xe78455c7, 0x1ecc87cb,
- 0x0d6d93cc, 0x291295a5, 0xab268385, 0x038cec06, 0xcdfb07fd, 0x63a24175,
- 0x9cc3ad16, 0xc18fe112, 0x797169fe, 0x35bec88e, 0x0b6d987e, 0x7d84dccd,
- 0x79eb1cbd, 0x0a3f8041, 0x9dbc62ef, 0x8fe02b31, 0x80945b8e, 0x3ec8faed,
- 0x77e53a37, 0xea3e7eda, 0x7c0632a5, 0xdb3e65e6, 0xbe5fb6ac, 0x8bb144f6,
- 0x7bd9d1f6, 0x2c4cdb2c, 0xe874ceb0, 0x01952640, 0xfb19bfbb, 0xffcc18e9,
- 0x679a7cc5, 0x61663bed, 0x3efffea6, 0x9ab128b0, 0x8bc9f7f6, 0xc13d4f56,
- 0xdb7ff70f, 0xac7da616, 0x1e6d04b5, 0x3bbe3b2a, 0x7952f368, 0xae41c1eb,
- 0x65b0755f, 0xb575f831, 0x7d81dee8, 0xbf12b25f, 0xb1d1f0eb, 0xa4e7d950,
- 0x31eebf75, 0xc4777f31, 0x6bda3f09, 0xa74ff3cd, 0x95077f62, 0xb97b2c12,
- 0x85adb0ef, 0x7ed47bea, 0x7a32f2d1, 0x74ed5976, 0xa43a3fea, 0x92a7de30,
- 0xd743bb8f, 0x1b2c7cb2, 0x7cb97373, 0x88213aec, 0xbe11df25, 0xa5744122,
- 0x3ef01ab5, 0xfcccd67a, 0x1cdc7a39, 0x8749f414, 0x0cba942d, 0x2b17f874,
- 0xf88ba1d3, 0xa4f88aa7, 0x40df7e8b, 0xd9be6fa5, 0xd40fbfc0, 0xbdf81bc4,
- 0x88e4e841, 0xcc47bbc6, 0xebcbc030, 0xeffd0d73, 0x945d7e5d, 0xda46943c,
- 0x0dfff8cd, 0xbb827691, 0x4a5c04b6, 0xc685a022, 0x30b72a7a, 0xf866dd9f,
- 0x8d2c4bbe, 0x3f9f03f4, 0x678c6fff, 0x4b6d8621, 0x26bf688b, 0xafd107a2,
- 0xad5e7fc1, 0x6d3d730f, 0xb39720c4, 0x98bf3d73, 0xf2317c4f, 0x47ec55b6,
- 0xdf089fc5, 0x7f46e815, 0x20e913b9, 0x9d5a1104, 0xb1d68937, 0xa9c908fe,
- 0x618a5f41, 0x06eb17d0, 0x74b6ba1d, 0x2a628bd4, 0xb4059be9, 0xb0c0ae8f,
- 0xf8c1dbad, 0x4a1164b7, 0xa22bf7d6, 0xdbfb8527, 0xbc2452b3, 0xac47f505,
- 0xf875861f, 0x686378c3, 0x816e633f, 0xafb744bc, 0xac0b7da7, 0x3dfeec47,
- 0x2dfad5f4, 0xde631f75, 0xea3cdaf5, 0xae9f1af8, 0xebdf4bde, 0x9e3d1dd6,
- 0x72c5c4a3, 0xe1e0f6bd, 0x7e1067d7, 0x4b92f996, 0x439d4720, 0x852dac4b,
- 0xd34df913, 0x9a0f57fb, 0xf06e3183, 0xb7e629df, 0x8f5683d1, 0xb2f01bf8,
- 0x0f182bde, 0x8ab87cd1, 0xf9a765f6, 0x3c511d57, 0x03f64541, 0xf146d67e,
- 0x9acdc627, 0xbe1a6f04, 0xd517f1c6, 0x683f1abe, 0x298fab9d, 0x09cbe841,
- 0xa7c68978, 0x3f2acf3a, 0x0aeb90fd, 0xc6a2baf2, 0xf2d15515, 0xfe86c9b8,
- 0xe114fba3, 0x1f18be54, 0x2c6cc74b, 0xe573b3df, 0x2a8e47fe, 0xddf4fd9e,
- 0xae16633d, 0x1f1fe71f, 0xf214ade1, 0x921f0137, 0x7e527c9f, 0xe34b1eee,
- 0x7c5efeef, 0x34fc45f5, 0xefdc573b, 0x7af44473, 0x621e9e44, 0x49294b3e,
- 0x5b48bd48, 0xace5dfa0, 0x3b3d541f, 0x4d243e95, 0xfc94facf, 0x71e7e603,
- 0xf894e3bb, 0xa57568dc, 0xeb4f8327, 0xd468f68c, 0xd64a4ae2, 0x642d21f9,
- 0xc0d35d67, 0xc2d333bf, 0x609f8e34, 0x4f4d57e8, 0x76f1d5fb, 0x0ecdcb6c,
- 0x6ff3beeb, 0xea09a6b7, 0x1a75bd9f, 0xceb12d97, 0x9691d834, 0xec1f66ad,
- 0xa48f87e3, 0x5f1155a7, 0x9addb87d, 0x7c434f5a, 0x6cbce0f8, 0x96b80451,
- 0xc58f0bcb, 0x131d0434, 0x625d55f7, 0xfd747c62, 0xaed8f7f7, 0x3674d6fd,
- 0xb77201b1, 0x156268fd, 0xfb6eb38d, 0x649c2acf, 0xfe4c87cf, 0xffda12ba,
- 0xdb20ca27, 0x2c1ce173, 0xfc4515f6, 0x6bdbb589, 0x3bf761d3, 0x59ea7cff,
- 0x56ff7dd8, 0xf8899a6b, 0x273f37e8, 0x3db0a87b, 0x52e23f63, 0x4be3e4ac,
- 0xfb07c42f, 0x292fff88, 0xf54b1bc2, 0x8a27cc6b, 0x7afb069d, 0xffcc1efc,
- 0xb79a76cf, 0x0f06f31c, 0x4f5e6064, 0xebcc1ae0, 0xe49f9adf, 0xddfe2bff,
- 0x7fa57b03, 0xe7b54077, 0xa0328857, 0x3b5ec1db, 0x97abffc3, 0x88473d10,
- 0x0c19bd43, 0xe2ebd4bf, 0x80b7a872, 0x3914d7eb, 0x46fbbd25, 0x3cd2364a,
- 0xa0a28581, 0xa3aded9b, 0xdfeb42c0, 0xe079c4a4, 0x3c526c4f, 0xfdd04ee9,
- 0xced2c9e7, 0x5e8bf4aa, 0xe4234dcf, 0xf3f8e983, 0x68bb31e6, 0x2deff1d3,
- 0x2f00d922, 0xfa1a67b2, 0x86dd3ad7, 0xae335bf6, 0xc57fb435, 0x6f806255,
- 0xf436a82f, 0x8b73c3bf, 0xeaabbe01, 0x4bfe862b, 0xf00c4bbc, 0x4346bab2,
- 0x2d7dbbff, 0x1b7bf686, 0x1bda18d6, 0xf00c1bfd, 0x341e3b57, 0x7bafbff4,
- 0x2bdda1ab, 0xbbd8169c, 0x171f44e3, 0x885ffde1, 0xbd37282e, 0xd3d0ef9d,
- 0x5322fe75, 0x7c24d0f7, 0xf48968fb, 0xea517e6f, 0x98fe05dd, 0x487c9265,
- 0xc3ae17a5, 0xd427b033, 0x0a42259e, 0x38622bfb, 0xdd137c13, 0x7e7dba2f,
- 0x2eabc9fc, 0xf4ada1a2, 0xe90b06c3, 0x2795f98d, 0xbe0972cb, 0x1b6be5f3,
- 0xe61fa42d, 0x2af278df, 0xb6951fe0, 0x32fb7235, 0xc345aec1, 0x04376fcb,
- 0x6ff39d68, 0x81edd9ce, 0xe913f3df, 0x9fc54cf7, 0xbe5b77d8, 0x10ca37dc,
- 0x93ca23f1, 0x5f288fc4, 0xb36c7e23, 0xfc47bf92, 0xaf4cf288, 0xd47feb87,
- 0xd9e5c55b, 0x3f972f5e, 0x72e3adee, 0xe5c7d7b8, 0xb81b7b4f, 0x9faf79fc,
- 0xb7b77bbf, 0x7af7cb83, 0x97feb9bb, 0xfe5c3dbd, 0xf5c037aa, 0x2c2896af,
- 0x0102b4ff, 0x037b05bd, 0x776f5dfe, 0x77a4cc84, 0xe5eb31c5, 0xf24abd71,
- 0xdda578ad, 0xa2a95c54, 0x6ebeca89, 0x5c878e11, 0x17c92d86, 0x39f8be89,
- 0x7a237ed9, 0xea2e22d4, 0xc61fadfc, 0xaf424f7a, 0xc9d33108, 0xffad58fa,
- 0x69ef52a7, 0x15ee5fae, 0x977a7d7a, 0xd023ffdb, 0xb2f71dfb, 0xec3332fc,
- 0x24e9f753, 0x24c77a6a, 0x93e3263a, 0x593e5467, 0xc62c4f60, 0x3d816ef9,
- 0xb27b083b, 0x83ee12c0, 0x4cfbea1e, 0x3d221eb8, 0xc6c12274, 0x11efa97a,
- 0xca13fb0b, 0x9be182a7, 0x7dc30552, 0xa19b0d9f, 0x3d381777, 0x54576c19,
- 0x022ecf38, 0xdd722949, 0x4a1e6758, 0xa7cd53c2, 0xf3b045e1, 0x2e6c3937,
- 0x5f9c09e8, 0xcf314a62, 0x02bcdabb, 0xd7bd52e3, 0xff3fdf46, 0x68990899,
- 0x5fa8b35d, 0x10a5f32c, 0x87d81728, 0x87923ecd, 0x276f5499, 0x9bd51678,
- 0x02d7bb65, 0x6c3a7c3a, 0x76a11d86, 0x03db2491, 0x7cc894a6, 0x2c133ada,
- 0xeca97e34, 0xe72a5897, 0x39c0bc01, 0x3ad0a254, 0x1e1cbafb, 0x02dd21e0,
- 0x5efee7de, 0x543f7f33, 0x3a1e04e2, 0xfb411e1d, 0xe2052c20, 0xaf1fb94a,
- 0xd722c133, 0x5fa9f353, 0x432fd178, 0x71d46278, 0x803db2ec, 0x0d4a6e71,
- 0x8f805a65, 0x20279b6e, 0x9d62f1c7, 0xfb2f17e8, 0xb93acc85, 0xad03fbcd,
- 0xacffec97, 0xf4376194, 0x4c43f12e, 0x2bd4f829, 0x539961f9, 0xa97083f2,
- 0x1a1fcab0, 0x4a752cbf, 0xedcafc92, 0x78d29677, 0xafe718be, 0x7fce49e3,
- 0x97e6e4aa, 0x512cdf10, 0x1fbff5fd, 0xfd2578bf, 0x7bbd5267, 0xf468df22,
- 0xe347f8d1, 0xd23e6883, 0xb7a340f8, 0x7f345df6, 0x3455f345, 0x4bb02d3f,
- 0x0f8e833a, 0x49f91329, 0x906874f9, 0x6769dfd7, 0x4fcd16bb, 0x35307cd1,
- 0x4e7dc93f, 0xfd08a3e4, 0xcf2f8f81, 0xde6ec347, 0xa4fb66c7, 0x8ff1a47c,
- 0x1f1a4fc6, 0x16223fdd, 0xcb535127, 0x9475eb98, 0xcffc727b, 0x8ab48f40,
- 0xab33165b, 0xbe45cd38, 0x9efd8984, 0x5bdfa298, 0x501fc4b1, 0x2f73c23c,
- 0x2e3381fc, 0x7ec5d8ab, 0x4251d7b6, 0xeaa45bf4, 0x9ba233d1, 0x8fb91ced,
- 0x46b5d001, 0xc2a2f125, 0xd77fecd5, 0x2c7e8c38, 0x88fc232c, 0x17efd4db,
- 0x0db7c9ff, 0x6a9c58eb, 0x536f6ff4, 0x455be3fd, 0x375f8f3f, 0xf0bdaa33,
- 0x6f9bf656, 0x6fd633cb, 0x5efd5528, 0xcf4370b7, 0x5c8f08d6, 0x7ecdd89f,
- 0x572a8d6b, 0x72fd2a59, 0x9f31665d, 0xfc2b58f0, 0xd7f72816, 0x62f3677e,
- 0x80455bdc, 0x2088afe1, 0x108bb797, 0x1907738f, 0x0977c002, 0x69dc0561,
- 0x91b6c91f, 0xfb37ad48, 0xf85f803f, 0x39fe59db, 0xc636c738, 0xcf20fbfa,
- 0x6cefe2a7, 0x5be6807a, 0x0f28b654, 0x71ac9ddf, 0xd2753fb1, 0x1dfecb9e,
- 0x129ac2e4, 0xc937cf91, 0xfd91e63e, 0x13f6453a, 0x9fb269e5, 0xdec76479,
- 0xf809fb20, 0x02ad82b6, 0x29762ddf, 0xb7dba2c2, 0xceedfdf6, 0x6d32c245,
- 0x7b74fb6a, 0xfa67f7f1, 0x4adf7f89, 0x1223539e, 0x60d65651, 0xa7256fbf,
- 0x6319649b, 0xd5e8b2e3, 0x4ffcc9bc, 0xf322ff8d, 0xa6f9e62d, 0xd786b3c2,
- 0x786a7c68, 0x7d7812fe, 0x3ebc3269, 0xced82253, 0x595fda8f, 0x5755b88f,
- 0xde6fd4bc, 0x06441357, 0xa3c6eff1, 0x1bfd1cf2, 0xe313312c, 0xf7b53c4b,
- 0xe42c28dc, 0x2bdc7f4a, 0xaaf3c002, 0x8fae6a9e, 0xf7898f8e, 0x6bf8616e,
- 0xd9572f2a, 0xdde821fd, 0x6ba1a5cb, 0x1f12c3c8, 0xbc4bebef, 0xedf9e681,
- 0xce0f664b, 0xd7669d27, 0xace20f6e, 0x2f3d996f, 0x9d3ffbe0, 0x724a5eca,
- 0x369f9e25, 0xd3ac39e9, 0x9da8f12e, 0xe39dbec3, 0xce14b963, 0x23c80cb2,
- 0x5f9829fd, 0x92665ff3, 0xfe27692f, 0xe59367dd, 0x454cfe54, 0x529fe91c,
- 0x50facfee, 0xc77d1fa3, 0x538d1670, 0xeb26fa41, 0xaf3e38d1, 0xf7de9d78,
- 0x08d50ed8, 0xc5afbf83, 0x25534623, 0x6b88171e, 0xb03c449e, 0x04558ce6,
- 0x82147da9, 0x250cf68f, 0x7a35bd08, 0xfa19aae6, 0x114136b6, 0x542f60d3,
- 0x6193127d, 0x3e9d2e12, 0x09c57588, 0xe38f8e97, 0x700c520b, 0xa1866782,
- 0x8e55527f, 0x3bd93da1, 0xad3ed0d7, 0x4f00d4ae, 0xe860ddf7, 0xd0b0de9f,
- 0x6ffa6700, 0xeacff433, 0x35806a58, 0xab25957d, 0x15eeacc4, 0xf767ef86,
- 0x77f434ac, 0xda1ad607, 0xfb8971cd, 0xbc068f59, 0x4e3405c3, 0xee4e3a9d,
- 0x7e868dce, 0xaa6dd082, 0xbfc89c80, 0xceeb1267, 0x3acf4428, 0xc87aaac7,
- 0xd7ff7e69, 0xd734eb8d, 0xbca9925b, 0x7fd465d5, 0x784619b5, 0x4284e391,
- 0x4e458b43, 0xeace1ea3, 0x8ce018b6, 0xd79bd232, 0x51628fd1, 0x2f82f1cc,
- 0xae7fbfa2, 0x78d1fe81, 0x84f07e22, 0x69ec9fd0, 0xb37aeb00, 0x8f7b02d5,
- 0x1f7e82fc, 0xf1e82fc8, 0x1e82fc80, 0xdf417e46, 0x7d05f91f, 0xfa0bf23b,
- 0x4633b2f6, 0x1b0f97fa, 0x9ef95fe9, 0x5f1afe91, 0xeaa7454e, 0x843f91b0,
- 0x7f2bf15f, 0x5e374e85, 0x344ff232, 0x37266e7d, 0xf4153927, 0xd7213c50,
- 0x9dd7a797, 0xfa22f451, 0xf7c04c04, 0x9f4904cc, 0xa04975d0, 0xb319ed57,
- 0x8ffc1208, 0xc77cfb51, 0x23286fe2, 0xab86f03d, 0xebfa0334, 0x147ae166,
- 0x9dc5db71, 0x86884f26, 0x7e35115d, 0x7dff0cf5, 0x1a17a465, 0xb6cd5da6,
- 0xfc463f81, 0xdc9e7073, 0xd9ddeaa5, 0xc0fc7271, 0x127cc142, 0xd839baf8,
- 0x339ee347, 0xcfd02bf5, 0xb7f44fdf, 0x0bfbfbe3, 0xd47f79bb, 0xcdf7c143,
- 0x0d931aff, 0xe0b679b8, 0x0c28b073, 0x88492f97, 0x2ce6c5e8, 0xd43b27aa,
- 0xe39ea655, 0xdf4ed43c, 0xb8c99775, 0x69c7824e, 0xa15178e3, 0x444e22f0,
- 0xe6ecafc7, 0x6ce3e022, 0x63e01cec, 0xde41e4c0, 0x25756c20, 0xde051f41,
- 0xbde40b34, 0x9fc217e0, 0x57faa59b, 0x29e46259, 0x5ece73ac, 0xd7abb061,
- 0x62c2ed06, 0x0d397fc8, 0x8650d170, 0xc7f5ffa1, 0x92f6865c, 0xbda18150,
- 0x00c78cec, 0x19570f97, 0xe7be57fa, 0xe1d5c035, 0x1bff433a, 0xf00cf92f,
- 0xef9e456c, 0x239653bf, 0x992e21f3, 0x387e6bdf, 0x6bfa5079, 0xf9afdcf2,
- 0x49ffa2d5, 0x38711daf, 0xbf357f95, 0x6da3f35c, 0xcfd04084, 0xf6c2d3b6,
- 0xfa5da660, 0xf62dfec9, 0x6827c8f3, 0x57e6bafe, 0x08a9fe6b, 0x76f57ad4,
- 0xf693be87, 0x35ebf545, 0x8bf359ff, 0x4c5d8b13, 0xb236eb3f, 0x4b07e0ab,
- 0xae761338, 0x1a4c4639, 0x4cb9790f, 0xd7a25b9e, 0x7a2badaf, 0xa762c4fe,
- 0xdc7517e4, 0x7ee2ec17, 0xccfe24df, 0xf57caabf, 0x63beb99f, 0xad67cfe0,
- 0xbb56f79e, 0xf4f3ebff, 0x1321fc25, 0xf5f352fe, 0x264dfd72, 0xc767c713,
- 0xd72e5fd7, 0x0bf595af, 0xd921dfc9, 0x37e2f359, 0x1fc83af7, 0xc2c7b678,
- 0xaf339671, 0xe40c6c5c, 0x5e121fc1, 0xfc9b338c, 0x3e07d07c, 0x0b07ce05,
- 0xdf3ccdcb, 0x772932a5, 0xcf2cbd11, 0xd242a365, 0xc6c7b47f, 0xe849d479,
- 0xeda07ccd, 0x8b43f107, 0x510dc655, 0xc9686e22, 0xc0437197, 0x44a21b88,
- 0x2ff510dc, 0x3e187af7, 0xf0c55bd2, 0x0cbd7af7, 0xe3adeb1f, 0x3ebd07f2,
- 0x26f8d7ae, 0x79da5f1a, 0xc43fa34b, 0x2f237610, 0x1feb1f8a, 0x6d72f492,
- 0xd3f6fab0, 0xa24deb16, 0xe08d294e, 0x8f151ef3, 0x3c49e633, 0x7fe41fa0,
- 0xe6b57eaa, 0x9bc424c2, 0xc92b8547, 0xaae257f9, 0x687c2f7f, 0x973f1f78,
- 0x949bcb8e, 0x52e4a987, 0xceeb3f3b, 0xd1772cab, 0xb72d18f2, 0x3fe778d1,
- 0xfc7bb9dd, 0x53c5ab5c, 0xe8d53954, 0x55b5c9a2, 0x5fa11b84, 0xce267982,
- 0x609c3f53, 0xf3c5a394, 0x077f7e24, 0xbcf2a239, 0x326699cb, 0xfdb2f847,
- 0x1017f271, 0x4869ef1f, 0x8059e0e4, 0x7dba8fce, 0xd2faf02e, 0x2b7ea06e,
- 0xd062ac07, 0xb0757d85, 0x44096d1d, 0xd8471b9f, 0xaddb6c9f, 0x3e469f38,
- 0xe7e4e77f, 0xd13fce4a, 0x6fc26d38, 0xfbdbbac3, 0xab56fd8d, 0xfce8cae7,
- 0xd53cd54a, 0x878479de, 0x7f351ffd, 0x19f6a1de, 0x6e609fe7, 0x60df1a92,
- 0x1432a479, 0xb9bf3ba3, 0x8b28ef90, 0xb8b784c0, 0x6dc3d802, 0x6bbe4f16,
- 0x7869bf22, 0x97e7989b, 0xf7c41bf7, 0xa0fcf962, 0x232ff9e5, 0x6afa0fcf,
- 0xffb514f9, 0x985980e5, 0x48e0df71, 0x7fa7e70c, 0x4f7b3a6b, 0x7f974b8e,
- 0x11b79099, 0x309fb889, 0x27ba687a, 0xb4bac930, 0x1b361fd2, 0x684c91ee,
- 0x11347adf, 0x17cec9e7, 0xf3a69e65, 0x796953c5, 0x3cd7bd3a, 0x1bfbc2cf,
- 0xe7dbf932, 0x9bdc8f4d, 0x60c7fb58, 0x357aca31, 0x9fbd127e, 0x5f36bd71,
- 0xa519fe61, 0xab5eb1fd, 0xa47f7853, 0x49e40517, 0x112fd7cb, 0x5a9454a1,
- 0xb3bfc43e, 0xe5a0e99a, 0xd5425a43, 0xfbbb8fbc, 0xa8e35b56, 0x2da9f84b,
- 0x48ae71b5, 0x4b3c249e, 0x2a99bfde, 0xac6cb25f, 0x3e5bc784, 0xb38f2376,
- 0xe65b9e6d, 0xd9edb64f, 0xee6fff00, 0x1e056141, 0x4e3956c2, 0x553e9e34,
- 0xdcb924e5, 0x6e37b7a8, 0x6f6f5855, 0xf796ad84, 0x6b6f587c, 0x157ed5f0,
- 0xa6f095ae, 0x5b0e12ed, 0x24953b1d, 0x05c45fb9, 0xd8944fb0, 0x87b1ce0f,
- 0xf60238d4, 0x40fb1281, 0x6015f43d, 0xd0c02be8, 0xafa18057, 0xa15f4250,
- 0x65f0a57e, 0xbc888e23, 0x4e4e8d4e, 0xd1a9d790, 0xebc81ff9, 0x75e461e8,
- 0xd791fdf4, 0xaf23b7d1, 0x5e476fa3, 0xaf230f47, 0xbc8fefa3, 0x5e461e8e,
- 0x791fdf47, 0xbc8c3d1d, 0xf23fbe8e, 0xe476fa3a, 0xc8edf475, 0xe461e8eb,
- 0x91fdf475, 0xdfb7d1d7, 0xf218a3df, 0x9a93f73e, 0xeeb5df06, 0x71fcc69d,
- 0x313bedda, 0x41fbe88f, 0x66bf9ffc, 0x8f9d01cd, 0x6edf01af, 0x48f38aec,
- 0x49d7f73a, 0xa4849bba, 0xd32348f3, 0xc24d8b79, 0xe7749eb5, 0xf20ffe24,
- 0x99563529, 0x7c89414f, 0x53e44a0a, 0x529f2250, 0x29f32f93, 0x414f9128,
- 0x2829f23d, 0x89414f91, 0xe44a0a7c, 0x9f225053, 0x14f91282, 0x0a7c877c,
- 0x5053e44a, 0x4a0a7c8f, 0x7f5053e4, 0xbc81d68e, 0xf82eb68a, 0xf38679cb,
- 0xe1a1f11c, 0xc034e73c, 0xfdf597f0, 0xdbeb2fe1, 0xdbeb2fe1, 0x61eb2fe1,
- 0xfefacbf8, 0xb0f597f0, 0xe58b9e69, 0xfeb37e0c, 0x7acdf83b, 0x703fa8b8,
- 0x3ba0b11a, 0x35eefdf6, 0xe504e194, 0xdf49c559, 0x15b7ff97, 0x638583c8,
- 0x0f64ec95, 0x0fadbfd9, 0xd821a8ad, 0x2ba7deaf, 0xd0262316, 0x44d8f39b,
- 0x04487f37, 0xe8a08f71, 0xd76e4cf3, 0x47fcaaf2, 0x22392f74, 0x535f0fd8,
- 0x7da5d724, 0x334e11ef, 0x047fad4a, 0xf45fbc9e, 0xd63f5afc, 0x9075ba97,
- 0xfdc12c9d, 0x8e2d9286, 0x4fc45dd2, 0xfb0a4c07, 0x9fc807a1, 0x5e893a5a,
- 0xa3fd50aa, 0x27c3a603, 0xa22f70e3, 0xa7ecf145, 0x88b1afa1, 0xe052d633,
- 0xfe14bba9, 0xb2797642, 0xdf75afea, 0xda3f7b80, 0x1db8b5ba, 0xf22f09e9,
- 0x8447f3ef, 0xb9e68dad, 0x6b6153e9, 0x9366df87, 0xc3be02fe, 0x80baedb9,
- 0xe3afdde2, 0x697282ef, 0x0d81fcff, 0xfd51b437, 0x6fba8775, 0x171f8768,
- 0xcefbbf27, 0xc78c8973, 0xfb29b73b, 0xf99fb4cd, 0x90778487, 0xcb9495fa,
- 0x8775dff3, 0x9e36b69c, 0xd76b69d7, 0x97d843df, 0x5ce1736d, 0x8835c228,
- 0x8a7989ff, 0xf0444178, 0x0d7bfb46, 0x4486bbfb, 0x75d7f105, 0x3ffb6307,
- 0xd751f1d2, 0x7e01b250, 0xff6658e0, 0x59fe3a47, 0x72441f87, 0xec206e41,
- 0xf24aa756, 0xc3bd6af5, 0x79c51be4, 0x623ecba2, 0x9a6efe03, 0x7b8b5c97,
- 0xf0b8e26c, 0xe6ef83e4, 0x4e9f6cb5, 0xbd07f2eb, 0xba03dc1e, 0xd3eed3e9,
- 0x63ef3f0c, 0x82a7d998, 0x70f6c7d7, 0xc509404e, 0x0cee2a13, 0x09529a0c,
- 0xd5b023be, 0x87fe869a, 0x00ee0784, 0xa0b12899, 0x42afb234, 0x558a6c31,
- 0xd4e22fc0, 0x91ff1d34, 0x7e0e58e6, 0x0558f129, 0xc58963f8, 0x89be8569,
- 0xefa237f6, 0x71ff907f, 0x6867bcaf, 0x6b1ec0b5, 0x538b51fe, 0x36eaf5ae,
- 0x2d1ffb2b, 0xd0ffc947, 0xfcd52bdd, 0x085eed0d, 0x109e1df9, 0xdb91f8ec,
- 0xb9d42e39, 0x7fbe1de1, 0x783b89f1, 0xfaf89920, 0xf7c39c93, 0xb7e1b954,
- 0xc94fac28, 0x272ce86f, 0x3f6cb63c, 0x55f3889d, 0xfb0af038, 0x3db7571b,
- 0x08e3289e, 0xa6d11f32, 0xcf8b49e2, 0x68f4abb4, 0x7d01ef53, 0x3bcb7a48,
- 0x086eed87, 0xbd6836f7, 0xfb4457ec, 0xb91f9a87, 0x384f1b4e, 0xa45c45df,
- 0x8bb7f683, 0x5bbbd5a0, 0x89886476, 0xd53ae3fe, 0xcdb35caf, 0x3a7ef7ca,
- 0xc2ed9044, 0x3f54609a, 0xbacfbef5, 0x9dfac683, 0xa7fe51e5, 0xeed22e7a,
- 0x7dbcb6e5, 0x7ff66eea, 0x6f9cadba, 0xfd2ada6b, 0x04587121, 0x8bc015f3,
- 0x3704b14c, 0x947af51d, 0x27e7f849, 0x1f545faa, 0x2ebc658e, 0x7d678b19,
- 0x8b2c74b2, 0x32c67be1, 0x4c77bcb9, 0x8a5c8bde, 0x3bd10c58, 0x9104ab5c,
- 0xea99fb4f, 0x7b8ddd0f, 0x2063a092, 0x9479f99d, 0x145319f8, 0xae6a7aab,
- 0x77053957, 0xdfeadeb3, 0xf5987b8e, 0xcbfd8283, 0xd137e03b, 0xa3f00df8,
- 0xdc1e41a6, 0xb73f7cb5, 0x6ef9114e, 0x9506c3c8, 0x041e49ff, 0xeb2f0feb,
- 0x41259ab5, 0xf069afdc, 0xee81361f, 0x03f81c9a, 0xef802de7, 0x57362808,
- 0xf8279f21, 0x79f1acbc, 0xc7343cb4, 0x8725f1ab, 0xfb8d1f8c, 0x9d2c58a7,
- 0xd7e045bb, 0xded4bc2b, 0x0ce0188c, 0xf7081195, 0xfdb28509, 0xaf5fd1e4,
- 0xd3c386d8, 0x343f8c97, 0xaf4c4c99, 0xf6f7f211, 0x70c56043, 0x65e43a6d,
- 0xcbba52b7, 0x53cf5915, 0x572f0b95, 0x2bc5cee8, 0xf922f955, 0x63f9c74b,
- 0xe9f923e3, 0x40ff1262, 0xcf095b2b, 0xa4e6b390, 0xa214d7f0, 0xc2e527cc,
- 0xdb0c435b, 0xe27dd428, 0x73ad0422, 0x7c670a85, 0x9dfdee2f, 0x861f8c85,
- 0x5e5f962f, 0xbffc2811, 0x8a4d87d0, 0xab57ef85, 0xfc9871f8, 0xefc3951f,
- 0x831787b7, 0x2385f1ae, 0x1a2dd036, 0x1eedf73f, 0xf08733da, 0xe9215190,
- 0xb7eb64d7, 0x045179f2, 0xb55f88ad, 0x22fb4a16, 0xafecae2c, 0xc5c43e72,
- 0xdf6d3e71, 0x89f7aa1f, 0xace1f1a3, 0x7e027690, 0xf48e6bb2, 0x4fc25193,
- 0xf81c7dc6, 0x27e180c9, 0x8c9f84a3, 0x80c9f87a, 0x860327e1, 0x7e180c9f,
- 0xc9f84a32, 0xe4c27fa8, 0xd130ff3d, 0xf05369f3, 0xa7c4abf0, 0x4dfaa59f,
- 0xa7feb415, 0xd79b8f71, 0x11fde7ef, 0x195eb0df, 0x5fc453d7, 0x1f088af6,
- 0x70b9ecad, 0xe11394d4, 0xbf9db6a7, 0xe205ea7f, 0x17e4958f, 0x3bfd9e42,
- 0xf14c5095, 0xdcf67cd4, 0x979638da, 0x636ebee7, 0x1b64dbfd, 0x47776d3e,
- 0xcf7ef9f0, 0x7d4ab4ff, 0xd177ca19, 0x63ba2bb8, 0x4fffd03d, 0xb1d2fa55,
- 0x0f42f8de, 0xad32e5d3, 0x251def89, 0xbf50b3fa, 0x9ebf0c52, 0xbf9afd41,
- 0xda3676f1, 0xb6ee381f, 0x1cb70f41, 0xe191d92b, 0x177ef7c2, 0xe1c5b5f8,
- 0x58cfc1b4, 0xed992dbf, 0x8cba736e, 0x73c712db, 0x47a34bde, 0xb78c8555,
- 0xb829527d, 0x979ea2bc, 0x25d64108, 0x6e927e86, 0xc5a6f2d1, 0x58e3a311,
- 0xf3ca7891, 0x0710733b, 0x3e9e1549, 0x217c44d7, 0x8d2b61ce, 0xe3a251c4,
- 0x6af2e31d, 0x9df88613, 0x50a9ae56, 0xdbcef70c, 0x85abcfc7, 0xd7e1d38b,
- 0x1138a63f, 0xb8736e6f, 0xb826adee, 0x37158ced, 0x8a7d4532, 0xf04996cb,
- 0x738a23c8, 0xb9bde83f, 0x1356f584, 0xf78a5268, 0xb72cd50b, 0xcb2a416d,
- 0xafef96a6, 0xd66a763e, 0x90afb1f7, 0xb67586d7, 0x14b6bd39, 0xdad3df9d,
- 0xf7f578af, 0xb1b83520, 0x9b0dc642, 0xfc0118e8, 0x6dd9b7dd, 0x2538895b,
- 0xffb83fb9, 0x13e546b7, 0xc7ea3bed, 0x73ea1ff7, 0xabe0ebc4, 0xf417da11,
- 0xd52be616, 0xe312bf8d, 0xfea7e6eb, 0x56b5b7ec, 0x2d78f024, 0x1bb7da4e,
- 0x49d793a5, 0x8d3c6078, 0x5cf1a1ec, 0xbde30f3c, 0x7ab41435, 0xbbdc1eb0,
- 0x33857820, 0x2b3cc568, 0x7c7095b7, 0xce5bbfdf, 0x6c99dfe3, 0x675f822b,
- 0xe966da71, 0x3be23dfd, 0x0e1365f0, 0x5ebca9f7, 0x08db87f6, 0x43f0294f,
- 0x75ffc853, 0x8b57c44c, 0xfeb6feba, 0xd8ffa364, 0xf41598ff, 0x4aed5469,
- 0x549e1d34, 0xb6e578f9, 0xd7786c5b, 0xf2f166d0, 0x8abf07bb, 0x10df7fef,
- 0x90f90bbb, 0xad2781c6, 0xae1f826e, 0x93f67e90, 0xeadf9215, 0xb8f94273,
- 0x21b231e7, 0x3721ef96, 0xbf79fb3a, 0x9c7ef8e3, 0xc4ff03f0, 0x137c63e9,
- 0x9f70049f, 0x48c06daf, 0x127ac8df, 0x81b6dc78, 0x55bf9616, 0xa9cdbf16,
- 0x13dec75f, 0xa5e10af9, 0x815ee491, 0xb3fa71fd, 0x1f173fc1, 0xf79b37bf,
- 0x7be4eb49, 0xe2d71e54, 0x37cc798c, 0xff1ad7cc, 0x79499734, 0xa97be6d6,
- 0xbdf3c2c2, 0xb4e525f4, 0xdf0b776d, 0x10cd6983, 0x62f9451e, 0x53e4d539,
- 0x3546d793, 0x7bbad92e, 0xf4ebf089, 0xeeefd90d, 0xcfc12797, 0x2b9d7565,
- 0x3e127a54, 0xb8ba135f, 0x3d2abbdd, 0x728c729b, 0xee30f18f, 0x9bee5529,
- 0x37f28616, 0x6bfa4614, 0xc8a536f3, 0xe0ffc0ef, 0xbd2a53b3, 0xf7237fd1,
- 0xeaa4f157, 0xbd71d68d, 0x1a7b6871, 0x8561c6f4, 0xf71b54f3, 0xe36ebf48,
- 0xe71c098b, 0xaf8d8ffa, 0xea1ef8fe, 0x8313c9f7, 0x13f7facd, 0x27a9216d,
- 0x829fc9da, 0xdaa558de, 0xff6286fd, 0x72742b4f, 0x17adf6dc, 0xac5c81af,
- 0xf8b92a18, 0x0efbc14b, 0xeafcdf41, 0x73be1fc5, 0x5f622b83, 0xdcac7db5,
- 0x16d66ff9, 0x726f1e87, 0x560abb9f, 0x493cef0a, 0x5ac39c2f, 0x1df229b7,
- 0xfd8d8f59, 0xd1de8d4f, 0xf242d07c, 0xf088eadb, 0xa9ff4681, 0x78db26fc,
- 0x5fd24e3e, 0x07c6b7a3, 0x3a35bd1a, 0x9d297bf1, 0xfbadafff, 0x2b5e9533,
- 0x531dfe54, 0x87456ee5, 0xe58ab6db, 0x056b6ddd, 0xb1fa6bdf, 0x4e3f58cd,
- 0x7eb8e727, 0xc0b901df, 0x69d022bb, 0xc655b774, 0xa04d0f23, 0xbeec3653,
- 0x6ad58eb6, 0x8d5db1dc, 0xfcd2ae1f, 0x4c7f62e0, 0xab4e8ea5, 0x6a74939f,
- 0x5fede97d, 0xfbc5c0ff, 0x4f6c7a93, 0x2b8bfb0c, 0xbd330e87, 0x663e771a,
- 0xf4bf5375, 0x5f41b74a, 0x389776b7, 0xb15f3711, 0xf90ad073, 0x4d74af4f,
- 0xea4defca, 0xaf0d60bd, 0xce8a3fb0, 0xa1fd69ee, 0x3cd30ef7, 0x26c4379b,
- 0x368d1ee2, 0xf252b78f, 0x72776b75, 0xed6be60a, 0x381ff96e, 0x3f7a68cf,
- 0xc42eee5a, 0x4958794a, 0x2f2e429f, 0xdec9e2dc, 0x3f313858, 0x959595a6,
- 0x10cf6e92, 0x256f717a, 0xbbe87e2b, 0x03d643c0, 0x93e41e71, 0x41c2f2f3,
- 0xc63e0bcc, 0x17a46dba, 0xaf25ff71, 0xac7bfc33, 0xbe745c83, 0x213282ef,
- 0xd23be645, 0x926fde08, 0xcc72b3ef, 0x52afbcb2, 0x0f6a3bda, 0x86a45da1,
- 0x68ffb1cb, 0x5f9535bd, 0x36a7f1a1, 0x9a9eb44e, 0x57777f6a, 0xa2fa794a,
- 0xab705dfd, 0x4f029371, 0x6de69db6, 0x078e747e, 0xda2fa471, 0xe64e2da7,
- 0x4bf7c697, 0x32955acc, 0xe4f37ec9, 0xfdea6839, 0x4da6d40e, 0x7909dfb2,
- 0xb44e555f, 0x79e3efbb, 0x27997e92, 0xdd90a0b9, 0x6c2eefa2, 0x65fbe588,
- 0x38b4beda, 0x5efadffd, 0x14cac1e1, 0x4e14fe35, 0x14d93f80, 0x487fcaa7,
- 0xa25fa8c2, 0xfdecd7ab, 0x21386739, 0x3f9fa745, 0xa1ed56ea, 0x3c81ef08,
- 0x815c9e8b, 0xfeb9c778, 0x42a6090b, 0x9f5ca7f0, 0xab66ddf6, 0xf40f5ce7,
- 0xbe18f6dc, 0xd37e4eef, 0xda93c40e, 0xa71cc903, 0xeca7afb9, 0xe71a5ee2,
- 0xfc596dbe, 0xf3f350de, 0x2ffaa957, 0x8ecb737e, 0xebdff44a, 0x6f8fc276,
- 0x886cf877, 0x2c0fc5c3, 0xdfb0e5b1, 0x5a01cf2b, 0x22b36ade, 0x0c9efc7c,
- 0x657211fa, 0x7b07913a, 0xf4af7ab3, 0x624debff, 0xb39bf227, 0x338b7cfb,
- 0x529e1fa1, 0xc527f03c, 0xdaa3d23e, 0xc7748c79, 0x6fbec587, 0xef68bf41,
- 0xc6c2e6ef, 0x219fb19a, 0x829dce2f, 0x07ec0bfc, 0xa65e01eb, 0x6e71fca9,
- 0xab827ce0, 0x2fcf8230, 0xe3481efb, 0xd67f2d0b, 0x194ff88e, 0x0d29a3f8,
- 0xe6a6d1fc, 0x2c0c76c9, 0x707db862, 0xe9fbbf19, 0x473a6743, 0xfb563db6,
- 0xef08a044, 0xda3e2578, 0x09dd16ba, 0x7f63a8bf, 0x35ce324c, 0xb640d6d9,
- 0x1b6d0fde, 0x01df987c, 0xe58c1a5d, 0xce354077, 0x67b83525, 0x7c9f6ab3,
- 0x3bf5a767, 0xb597eaa1, 0xef0c8b5d, 0x4c69da79, 0xd9ff8d27, 0x5fdf3c50,
- 0x04e9ded3, 0x95e3feec, 0x4ebdf2e5, 0xd3be4bb5, 0xaefee4c9, 0x5af4e349,
- 0xbe57b179, 0x3bbdd0fb, 0xbe91b3ba, 0x257aecef, 0x7bace311, 0x4e1567fc,
- 0xceb7c713, 0x77f1fc60, 0xbbe57b47, 0x27c7f6a3, 0xbe03ff7f, 0x1c767f06,
- 0xc6790c53, 0xec4982fb, 0xc243fa87, 0xdfb6fc86, 0xbdcfd829, 0xb03d1664,
- 0xa25f9aeb, 0xc552ffd5, 0xfea4a5c3, 0xcd7fd06c, 0x61b32781, 0x20937e37,
- 0xf703a6e1, 0xc87a08fe, 0xf48c7cff, 0xfd822dbf, 0xf480d6db, 0x64f7b597,
- 0x38ec7842, 0x19547f87, 0x46b9f2cf, 0xada4977d, 0xae0bfc8b, 0xd4458dff,
- 0x6f781d61, 0xdf7e7e04, 0x3d076a12, 0x147f27df, 0x2a138f79, 0x6fdfbdff,
- 0x87f7cc5e, 0x57e01048, 0x4affdfbc, 0x9a89f202, 0xfe6b561f, 0xb4ef1795,
- 0xef951e37, 0x870be381, 0xd4231cf9, 0xa77ac978, 0xdf8db7e4, 0x4ace2eb7,
- 0x6b8abf65, 0xdb212d3a, 0xab5af464, 0xf0e34dfa, 0x2e7cc391, 0xfd243ceb,
- 0xf3a1ce82, 0x7e6817ec, 0x70bef686, 0xecf3a1dd, 0xaddf6827, 0xd2f1223f,
- 0xb7d64475, 0x78b49814, 0xc3c9578b, 0x38615979, 0xb4d2c2bf, 0x9b9b00d5,
- 0x3a505ab6, 0x08c878d5, 0x0abbe5fb, 0x99e7ca7e, 0xb8ea6dae, 0xf3755b04,
- 0x974d56c5, 0x3ea8daef, 0xa5ef81d7, 0xbbdad73d, 0x50f3c88e, 0x276e2ba8,
- 0xef5d83df, 0xebeca0b0, 0xdf3db072, 0xc02a6dd7, 0x12af757d, 0x71dcfec7,
- 0xf4d6fef5, 0x22c6ef75, 0x4629904e, 0x7cdc994e, 0x15666b6f, 0x022e9b8d,
- 0x7b4b8f7c, 0x9fe5744f, 0xf8c32e3f, 0xafc2620b, 0x5b980220, 0x7909a335,
- 0xe1490593, 0xf73c6032, 0xd384ba58, 0x0e20afc3, 0x37240ce5, 0xa5f28f21,
- 0x8af54ae3, 0x30eece21, 0x0a07aff9, 0xdb2ec6ba, 0xc4635c64, 0x5799b906,
- 0xfa68f925, 0xe2473a49, 0x83b9f51c, 0xd3e981cf, 0x9b9df9ba, 0xa1970c28,
- 0x837c71df, 0x8c7f60fb, 0x420eff93, 0xf6f5979e, 0x027558c6, 0x3de99797,
- 0xa425aeaa, 0x9f0363e6, 0xf7f8829b, 0xa12b8e04, 0xbcfdeb6f, 0x4f292aee,
- 0x979918be, 0xceb14bbd, 0xe4fa27fa, 0x835fdb90, 0xcc72fa75, 0xb8b92545,
- 0x7def2b17, 0xb7f3515f, 0x50bcbf9a, 0x7a96769d, 0xc8cdb3ce, 0xb4fe4070,
- 0xd78a89fb, 0x1f52efcb, 0x8ad93c2a, 0xc4737f75, 0x1620efce, 0x73c9c48e,
- 0xb63a8cd5, 0xd9b17daf, 0x2e283fec, 0xfea2688b, 0x214d0b27, 0xa6ffdfdc,
- 0x599e73b0, 0x6dfca3d8, 0xc3df2c53, 0xf1bf8e56, 0x964dec39, 0x92a7f7f9,
- 0xff599f68, 0x8ba078a0, 0xfe2f479b, 0x6ca84fe3, 0x187fdb1a, 0xfe4911fb,
- 0xb9c3f066, 0x7ef3bad1, 0x9d37f542, 0xb48f7643, 0x8fbf4263, 0x9e7e0fe3,
- 0xac8a6298, 0xc5c8caef, 0x879d5f17, 0xe9f1ced2, 0x32cdc785, 0x9eb5159e,
- 0xbe2e192b, 0x98fd4e0f, 0xa61c573e, 0x0b87ce20, 0x0f7a9f8f, 0x7b885beb,
- 0xd83738ce, 0xf6f597ad, 0x2566b84e, 0x150e7e23, 0x88ac97fa, 0xb540783e,
- 0xae7d694b, 0x7b08dc9f, 0x2059a6f9, 0x651440ee, 0x07d6883e, 0x425f833f,
- 0xaa37c6fe, 0x07ed79e4, 0x546fbe39, 0x67065cb1, 0x9be72e41, 0xb69fbf27,
- 0xe3514aaf, 0xd1ae9259, 0x8ba68b74, 0xe7716f86, 0x8524e9f0, 0xa8f45cf1,
- 0xc62eefc4, 0xb767e7ef, 0x198a9893, 0xc636fbff, 0xf86ffff3, 0xca7de2fd,
- 0xfbe373f7, 0xd3ed3afc, 0x77e7d86d, 0x93ed1ffe, 0xbcdfc0f5, 0x3ee361cf,
- 0xb142fad3, 0x8f37c073, 0x8acfd89b, 0x0a2a37be, 0x66d1eb04, 0x53c71c73,
- 0xddf271fd, 0xd3cfe901, 0xde9a9fd0, 0x2e175d9c, 0x4e71bf82, 0xaeb16788,
- 0xeb8869b0, 0x30e5562f, 0xc314ccdf, 0xc27efc99, 0x3f872e12, 0x35bfb66b,
- 0x4bb223f7, 0x0f048f03, 0xf4e34abf, 0x56a7c129, 0xeddd5f41, 0x95dcfce0,
- 0xa56029a0, 0x45920679, 0x7f9a31f1, 0xce5ccd60, 0xaa115cb3, 0xb1b06a9e,
- 0xecf6a29e, 0xca37b41e, 0xf9fdeff6, 0xa3f81ec2, 0xf782f923, 0xae225033,
- 0xc0f04bd9, 0xff6e0292, 0xf6e7a6a1, 0x97efc824, 0x8193e608, 0xef7c2935,
- 0x83a7e9e4, 0x0e8ec2d7, 0x11337a0c, 0xf44cab57, 0x19c74187, 0x079f6966,
- 0xe54f54dc, 0xb1af8a13, 0xc914e31d, 0xe31b86f5, 0x43403a5e, 0x2a91e6c5,
- 0x3d73faa5, 0xd5cf9c09, 0x638b47e4, 0x7f9c0ecf, 0xded2780a, 0xf2a07f23,
- 0xc5778699, 0xa667df2b, 0xe8d678aa, 0x6a5bf1a0, 0xa6cf7c9c, 0x377c916c,
- 0xbd791f7e, 0x33c8fbe0, 0x27782969, 0x71e31cd7, 0x4adfdf01, 0xfd618ff2,
- 0x3e881b7d, 0xd243ec66, 0x5bde1ce1, 0x997fe24e, 0x7e5a4dab, 0x3463df9f,
- 0x9a5fa90b, 0x3d17f7b5, 0x2217f7c6, 0xef19333c, 0xe89f9891, 0x3edd67fb,
- 0x5fbe355b, 0xd2fb65ee, 0xd9def2ac, 0x7a4f34ff, 0x5aa9286f, 0x623b95da,
- 0x9dfc89fd, 0xf3450efa, 0x7c96cfc3, 0xe4f60b3c, 0xcc6f83dc, 0xa2577944,
- 0xf69ab92f, 0x1fe344f3, 0x7dc4c316, 0xf7e61990, 0xfe341f34, 0xe5c71671,
- 0xfcc1bcb7, 0x57aeb7ff, 0x01ffc75b, 0x0934e170, 0x000048d0
+ 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_link.c b/drivers/net/bnx2x_link.c
index fefa6ab1306..ed648acef7c 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -1,4 +1,4 @@
-/* Copyright 2008 Broadcom Corporation
+/* Copyright 2008-2009 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -22,14 +22,9 @@
#include <linux/ethtool.h>
#include <linux/mutex.h>
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
#include "bnx2x.h"
/********************************************************/
-#define SUPPORT_CL73 0 /* Currently no */
#define ETH_HLEN 14
#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
#define ETH_MIN_PACKET_SIZE 60
@@ -139,6 +134,26 @@
#define PHY_SGMII_FLAG 0x2
#define PHY_SERDES_FLAG 0x4
+/* */
+#define SFP_EEPROM_CON_TYPE_ADDR 0x2
+ #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
+ #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
+
+#define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
+ #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
+ #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
+#define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
+#define SFP_EEPROM_VENDOR_NAME_SIZE 16
+#define SFP_EEPROM_OPTIONS_ADDR 0x40
+ #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
+#define SFP_EEPROM_OPTIONS_SIZE 2
+
+#define SFP_MODULE_TYPE_UNKNOWN 0x0
+#define SFP_MODULE_TYPE_LC 0x1
+#define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE 0x2
+#define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE 0x3
+
+#define SFP_LIMITING_MODE_VALUE 0x0044
/**********************************************************/
/* INTERFACE */
/**********************************************************/
@@ -154,13 +169,34 @@
(_bank + (_addr & 0xf)), \
_val)
-static void bnx2x_set_phy_mdio(struct link_params *params)
+static void bnx2x_set_serdes_access(struct link_params *params)
{
struct bnx2x *bp = params->bp;
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
- params->port*0x18, 0);
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
- DEFAULT_PHY_DEV_ADDR);
+ u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ /* Set Clause 22 */
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
+ udelay(500);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
+ udelay(500);
+ /* Set Clause 45 */
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
+}
+static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
+{
+ struct bnx2x *bp = params->bp;
+ if (phy_flags & PHY_XGXS_FLAG) {
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
+ params->port*0x18, 0);
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
+ DEFAULT_PHY_DEV_ADDR);
+ } else {
+ bnx2x_set_serdes_access(params);
+
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
+ params->port*0x10,
+ DEFAULT_PHY_DEV_ADDR);
+ }
}
static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
@@ -277,8 +313,10 @@ static u8 bnx2x_emac_enable(struct link_params *params,
port*4, 0);
}
- /* enable emac */
- REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
+ bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
+ EMAC_RX_MODE_RESET);
+ bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
+ EMAC_TX_MODE_RESET);
if (CHIP_REV_IS_SLOW(bp)) {
/* config GMII mode */
@@ -317,6 +355,9 @@ static u8 bnx2x_emac_enable(struct link_params *params,
val &= ~0x810;
EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
+ /* enable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
+
/* enable emac for jumbo packets */
EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
(EMAC_RX_MTU_SIZE_JUMBO_ENA |
@@ -495,7 +536,7 @@ static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
udelay(500);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
val);
- bnx2x_set_phy_mdio(params);
+ bnx2x_set_phy_mdio(params, phy_flags);
}
void bnx2x_link_status_update(struct link_params *params,
@@ -746,12 +787,17 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
return 0;
}
-static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
+static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
{
u32 emac_base;
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- emac_base = GRCBASE_EMAC0;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ /* All MDC/MDIO is directed through single EMAC */
+ if (REG_RD(bp, NIG_REG_PORT_SWAP))
+ emac_base = GRCBASE_EMAC0;
+ else
+ emac_base = GRCBASE_EMAC1;
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
@@ -769,11 +815,12 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
{
u32 tmp, saved_mode;
u8 i, rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
+ u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
+
saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT);
@@ -838,10 +885,11 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
u16 i;
u8 rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
+ u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
+
saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT));
@@ -964,6 +1012,8 @@ static u8 bnx2x_reset_unicore(struct link_params *params)
(mii_control |
MDIO_COMBO_IEEO_MII_CONTROL_RESET));
+ bnx2x_set_serdes_access(params);
+
/* wait for the reset to self clear */
for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
udelay(5);
@@ -1153,62 +1203,9 @@ static void bnx2x_set_autoneg(struct link_params *params,
MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
reg_val);
- /* Enable Clause 73 Aneg */
- if ((vars->line_speed == SPEED_AUTO_NEG) &&
- (SUPPORT_CL73)) {
- /* Enable BAM Station Manager */
+ /* CL73 Autoneg Disabled */
+ reg_val = 0;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL1,
- (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
- MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
- MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
-
- /* Merge CL73 and CL37 aneg resolution */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL3,
- &reg_val);
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL3,
- (reg_val |
- MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
-
- /* Set the CL73 AN speed */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB1,
- MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
- /* In the SerDes we support only the 1G.
- In the XGXS we support the 10G KX4
- but we currently do not support the KR */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "XGXS\n");
- /* 10G KX4 */
- reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
- } else {
- DP(NETIF_MSG_LINK, "SerDes\n");
- /* 1000M KX */
- reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
- }
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB1,
- MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
-
- /* CL73 Autoneg Enabled */
- reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
- } else {
- /* CL73 Autoneg Disabled */
- reg_val = 0;
- }
CL45_WR_OVER_CL22(bp, params->port,
params->phy_addr,
MDIO_REG_BANK_CL73_IEEEB0,
@@ -1341,44 +1338,25 @@ static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
static void bnx2x_restart_autoneg(struct link_params *params)
{
struct bnx2x *bp = params->bp;
+ u16 mii_control;
DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
- if (SUPPORT_CL73) {
- /* enable and restart clause 73 aneg */
- u16 an_ctrl;
+ /* Enable and restart BAM/CL37 aneg */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB0,
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- &an_ctrl);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB0,
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- (an_ctrl |
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
-
- } else {
- /* Enable and restart BAM/CL37 aneg */
- u16 mii_control;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
- DP(NETIF_MSG_LINK,
- "bnx2x_restart_autoneg mii_control before = 0x%x\n",
- mii_control);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
- MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
- }
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ &mii_control);
+ DP(NETIF_MSG_LINK,
+ "bnx2x_restart_autoneg mii_control before = 0x%x\n",
+ mii_control);
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ (mii_control |
+ MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+ MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
}
static void bnx2x_initialize_sgmii_process(struct link_params *params,
@@ -1609,7 +1587,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
u32 gp_status)
{
struct bnx2x *bp = params->bp;
-
+ u16 new_line_speed;
u8 rc = 0;
vars->link_status = 0;
@@ -1629,7 +1607,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
switch (gp_status & GP_STATUS_SPEED_MASK) {
case GP_STATUS_10M:
- vars->line_speed = SPEED_10;
+ new_line_speed = SPEED_10;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_10TFD;
else
@@ -1637,7 +1615,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
case GP_STATUS_100M:
- vars->line_speed = SPEED_100;
+ new_line_speed = SPEED_100;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_100TXFD;
else
@@ -1646,7 +1624,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
case GP_STATUS_1G:
case GP_STATUS_1G_KX:
- vars->line_speed = SPEED_1000;
+ new_line_speed = SPEED_1000;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_1000TFD;
else
@@ -1654,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
case GP_STATUS_2_5G:
- vars->line_speed = SPEED_2500;
+ new_line_speed = SPEED_2500;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_2500TFD;
else
@@ -1671,32 +1649,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
case GP_STATUS_10G_KX4:
case GP_STATUS_10G_HIG:
case GP_STATUS_10G_CX4:
- vars->line_speed = SPEED_10000;
+ new_line_speed = SPEED_10000;
vars->link_status |= LINK_10GTFD;
break;
case GP_STATUS_12G_HIG:
- vars->line_speed = SPEED_12000;
+ new_line_speed = SPEED_12000;
vars->link_status |= LINK_12GTFD;
break;
case GP_STATUS_12_5G:
- vars->line_speed = SPEED_12500;
+ new_line_speed = SPEED_12500;
vars->link_status |= LINK_12_5GTFD;
break;
case GP_STATUS_13G:
- vars->line_speed = SPEED_13000;
+ new_line_speed = SPEED_13000;
vars->link_status |= LINK_13GTFD;
break;
case GP_STATUS_15G:
- vars->line_speed = SPEED_15000;
+ new_line_speed = SPEED_15000;
vars->link_status |= LINK_15GTFD;
break;
case GP_STATUS_16G:
- vars->line_speed = SPEED_16000;
+ new_line_speed = SPEED_16000;
vars->link_status |= LINK_16GTFD;
break;
@@ -1708,13 +1686,26 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
}
+ /* Upon link speed change set the NIG into drain mode.
+ Comes to deals with possible FIFO glitch due to clk change
+ when speed is decreased without link down indicator */
+ if (new_line_speed != vars->line_speed) {
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+ + params->port*4, 0);
+ msleep(1);
+ }
+ vars->line_speed = new_line_speed;
vars->link_status |= LINK_STATUS_SERDES_LINK;
if ((params->req_line_speed == SPEED_AUTO_NEG) &&
((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
(XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
+ (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
+ (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
vars->autoneg = AUTO_NEG_ENABLED;
if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
@@ -1758,38 +1749,44 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
return rc;
}
-static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
+static void bnx2x_set_gmii_tx_driver(struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 lp_up2;
u16 tx_driver;
+ u16 bank;
/* read precomp */
-
CL45_RD_OVER_CL22(bp, params->port,
params->phy_addr,
MDIO_REG_BANK_OVER_1G,
MDIO_OVER_1G_LP_UP2, &lp_up2);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_TX0,
- MDIO_TX0_TX_DRIVER, &tx_driver);
-
/* bits [10:7] at lp_up2, positioned at [15:12] */
lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
- if ((lp_up2 != 0) &&
- (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
- /* replace tx_driver bits [15:12] */
- tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
- tx_driver |= lp_up2;
- CL45_WR_OVER_CL22(bp, params->port,
+ if (lp_up2 == 0)
+ return;
+
+ for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
+ bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
+ CL45_RD_OVER_CL22(bp, params->port,
params->phy_addr,
- MDIO_REG_BANK_TX0,
- MDIO_TX0_TX_DRIVER, tx_driver);
+ bank,
+ MDIO_TX0_TX_DRIVER, &tx_driver);
+
+ /* replace tx_driver bits [15:12] */
+ if (lp_up2 !=
+ (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
+ tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
+ tx_driver |= lp_up2;
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ bank,
+ MDIO_TX0_TX_DRIVER, tx_driver);
+ }
}
}
@@ -1890,6 +1887,25 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL, 0xa040);
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+ params->port);
+
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+ params->port);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 1<<15);
+
+ break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
/* Unset Low Power Mode and SW reset */
/* Restore normal power mode*/
@@ -1907,9 +1923,6 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
{
- u16 emac_base;
- emac_base = (params->port) ? GRCBASE_EMAC0 :
- GRCBASE_EMAC1;
/* Restore normal power mode*/
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
@@ -1937,6 +1950,23 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+ params->port);
+
+ /* HW reset */
+ bnx2x_hw_reset(bp, params->port);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 1<<15);
+ break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
break;
@@ -1968,6 +1998,31 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
}
}
+
+static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
+ u32 shmem_base, u32 spirom_ver)
+{
+ DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
+ (u16)(spirom_ver>>16), (u16)spirom_ver);
+ REG_WR(bp, shmem_base +
+ offsetof(struct shmem_region,
+ port_mb[port].ext_phy_fw_version),
+ spirom_ver);
+}
+
+static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
+ u32 ext_phy_type, u8 ext_phy_addr,
+ u32 shmem_base)
+{
+ u16 fw_ver1, fw_ver2;
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2, &fw_ver2);
+ bnx2x_save_spirom_version(bp, port, shmem_base,
+ (u32)(fw_ver1<<16 | fw_ver2));
+}
+
static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
{
struct bnx2x *bp = params->bp;
@@ -1976,7 +2031,6 @@ static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- u16 fw_ver1, fw_ver2;
/* Need to wait 200ms after reset */
msleep(200);
@@ -2012,14 +2066,10 @@ static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
/* Wait 100ms */
msleep(100);
- /* Print the PHY FW version */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &fw_ver2);
- DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+ bnx2x_save_bcm_spirom_ver(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ params->shmem_base);
}
static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
@@ -2037,7 +2087,7 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc801, &val);
+ MDIO_PMA_REG_8073_CHIP_REV, &val);
if (val != 1) {
/* No need to workaround in 8073 A1 */
@@ -2069,7 +2119,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc801, &val);
+ MDIO_PMA_REG_8073_CHIP_REV, &val);
if (val > 0) {
/* No need to workaround in 8073 A1 */
@@ -2085,7 +2135,8 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc820, &val);
+ MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+ &val);
/* If bit [14] = 0 or bit [13] = 0, continue on with
system initialization (XAUI work-around not required,
as these bits indicate 2.5G or 1G link up). */
@@ -2103,7 +2154,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc841, &val);
+ MDIO_PMA_REG_8073_XAUI_WA, &val);
if (val & (1<<15)) {
DP(NETIF_MSG_LINK,
"XAUI workaround has completed\n");
@@ -2121,9 +2172,8 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
}
static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr)
+ u8 ext_phy_addr, u32 shmem_base)
{
- u16 fw_ver1, fw_ver2;
/* Boot port from external ROM */
/* EDC grst */
bnx2x_cl45_write(bp, port,
@@ -2173,17 +2223,496 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_MISC_CTRL1, 0x0000);
- bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ bnx2x_save_bcm_spirom_ver(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ shmem_base);
+}
+
+static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+ /* Need to wait 100ms after reset */
+ msleep(100);
+
+ /* Set serial boot control for external load */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+
+ /* Micro controller re-boot */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+ /* Set soft reset */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL2,
+ 0x73A0);
+
+ /* Clear soft reset.
+ Will automatically reset micro-controller re-boot */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+ /* wait for 150ms for microcode load */
+ msleep(150);
+
+ /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+
+ msleep(200);
+ bnx2x_save_bcm_spirom_ver(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ params->shmem_base);
+}
+
+static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
+ u8 ext_phy_addr, u8 tx_en)
+{
+ u16 val;
+ DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
+ tx_en, port);
+ /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
ext_phy_addr,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+ MDIO_PMA_REG_PHY_IDENTIFIER,
+ &val);
+
+ if (tx_en)
+ val &= ~(1<<15);
+ else
+ val |= (1<<15);
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER,
+ val);
+}
+
+
+static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+ u8 byte_cnt, u8 *o_buf) {
+ struct bnx2x *bp = params->bp;
+ u16 val, i;
+ u8 port = params->port;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ if (byte_cnt > 16) {
+ DP(NETIF_MSG_LINK, "Reading from eeprom is"
+ " is limited to 0xf\n");
+ return -EINVAL;
+ }
+ /* Set the read command byte count */
+ bnx2x_cl45_write(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
+ (byte_cnt | 0xa000));
+
+ /* Set the read command address */
+ bnx2x_cl45_write(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
+ addr);
+
+ /* Activate read command */
+ bnx2x_cl45_write(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
+ 0x2c0f);
+
+ /* Wait up to 500us for command complete status */
+ for (i = 0; i < 100; i++) {
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
+ if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
+ MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
+ break;
+ udelay(5);
+ }
+
+ if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
+ MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
+ DP(NETIF_MSG_LINK,
+ "Got bad status 0x%x when reading from SFP+ EEPROM\n",
+ (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
+ return -EINVAL;
+ }
+
+ /* Read the buffer */
+ for (i = 0; i < byte_cnt; i++) {
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
+ o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
+ }
+
+ for (i = 0; i < 100; i++) {
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
+ if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
+ MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
+ return 0;;
+ msleep(1);
+ }
+ return -EINVAL;
+}
+
+
+static u8 bnx2x_get_sfp_module_type(struct link_params *params,
+ u8 *module_type)
+{
+ struct bnx2x *bp = params->bp;
+ u8 val;
+ *module_type = SFP_MODULE_TYPE_UNKNOWN;
+
+ /* First check for copper cable */
+ if (bnx2x_read_sfp_module_eeprom(params,
+ SFP_EEPROM_CON_TYPE_ADDR,
+ 1,
+ &val) != 0) {
+ DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
+ return -EINVAL;
+ }
+
+ switch (val) {
+ case SFP_EEPROM_CON_TYPE_VAL_COPPER:
+ {
+ u8 copper_module_type;
+ /* Check if its active cable( includes SFP+ module)
+ of passive cable*/
+ if (bnx2x_read_sfp_module_eeprom(params,
+ SFP_EEPROM_FC_TX_TECH_ADDR,
+ 1,
+ &copper_module_type) !=
+ 0) {
+ DP(NETIF_MSG_LINK,
+ "Failed to read copper-cable-type"
+ " from SFP+ EEPROM\n");
+ return -EINVAL;
+ }
+
+ if (copper_module_type &
+ SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
+ DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
+ *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
+ } else if (copper_module_type &
+ SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
+ DP(NETIF_MSG_LINK, "Passive Copper"
+ " cable detected\n");
+ *module_type =
+ SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
+ } else {
+ DP(NETIF_MSG_LINK, "Unknown copper-cable-"
+ "type 0x%x !!!\n", copper_module_type);
+ return -EINVAL;
+ }
+ break;
+ }
+ case SFP_EEPROM_CON_TYPE_VAL_LC:
+ DP(NETIF_MSG_LINK, "Optic module detected\n");
+ *module_type = SFP_MODULE_TYPE_LC;
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
+ val);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+
+/* This function read the relevant field from the module ( SFP+ ),
+ and verify it is compliant with this board */
+static u8 bnx2x_verify_sfp_module(struct link_params *params,
+ u8 module_type)
+{
+ struct bnx2x *bp = params->bp;
+ u8 *str_p, *tmp_buf;
+ u16 i;
+
+#define COMPLIANCE_STR_CNT 6
+ u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
+ "FINISAR CORP. ", "Amphenol"};
+ u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
+ /* Passive Copper cables are allowed to participate,
+ since the module is hardwired to the copper cable */
+
+ if (!(params->feature_config_flags &
+ FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
+ DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
+ return 0;
+ }
+
+ if (module_type != SFP_MODULE_TYPE_LC) {
+ DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
+ return 0;
+ }
+
+ /* In case of non copper cable or Active copper cable,
+ verify that the SFP+ module is compliant with this board*/
+ if (bnx2x_read_sfp_module_eeprom(params,
+ SFP_EEPROM_VENDOR_NAME_ADDR,
+ SFP_EEPROM_VENDOR_NAME_SIZE,
+ buf) != 0) {
+ DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
+ " module EEPROM\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
+ str_p = compliance_str[i];
+ tmp_buf = buf;
+ while (*str_p) {
+ if ((u8)(*tmp_buf) != (u8)(*str_p))
+ break;
+ str_p++;
+ tmp_buf++;
+ }
+
+ if (!(*str_p)) {
+ DP(NETIF_MSG_LINK, "SFP+ Module verified, "
+ "index=%x\n", i);
+ return 0;
+ }
+ }
+ DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
+ return -EINVAL;
+}
+
+
+static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
+ u8 module_type)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 options[SFP_EEPROM_OPTIONS_SIZE];
+ u8 limiting_mode;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u16 cur_limiting_mode;
+ if (bnx2x_read_sfp_module_eeprom(params,
+ SFP_EEPROM_OPTIONS_ADDR,
+ SFP_EEPROM_OPTIONS_SIZE,
+ options) != 0) {
+ DP(NETIF_MSG_LINK, "Failed to read Option field from"
+ " module EEPROM\n");
+ return -EINVAL;
+ }
+ limiting_mode = !(options[0] &
+ SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
+
bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
ext_phy_addr,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &fw_ver2);
- DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+ MDIO_PMA_REG_ROM_VER2,
+ &cur_limiting_mode);
+ DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
+ cur_limiting_mode);
+
+ if (limiting_mode &&
+ (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
+ DP(NETIF_MSG_LINK,
+ "Module options = 0x%x.Setting LIMITING MODE\n",
+ options[0]);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2,
+ SFP_LIMITING_MODE_VALUE);
+ } else { /* LRM mode ( default )*/
+
+ DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
+ options[0]);
+
+ /* Changing to LRM mode takes quite few seconds.
+ So do it only if current mode is limiting
+ ( default is LRM )*/
+ if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
+ return 0;
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LRM_MODE,
+ 0);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2,
+ 0x128);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL0,
+ 0x4008);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LRM_MODE,
+ 0xaaaa);
+ }
+ return 0;
+}
+
+static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
+{
+ u8 val;
+ struct bnx2x *bp = params->bp;
+ u16 timeout;
+ /* Initialization time after hot-plug may take up to 300ms for some
+ phys type ( e.g. JDSU ) */
+ for (timeout = 0; timeout < 60; timeout++) {
+ if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
+ == 0) {
+ DP(NETIF_MSG_LINK, "SFP+ module initialization "
+ "took %d ms\n", timeout * 5);
+ return 0;
+ }
+ msleep(5);
+ }
+ return -EINVAL;
+}
+
+static u8 bnx2x_sfp_module_detection(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 module_type;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+ if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
+ DP(NETIF_MSG_LINK, "Module detection is not required "
+ "for this phy\n");
+ return 0;
+ }
+
+ DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
+ params->port);
+
+ if (bnx2x_get_sfp_module_type(params,
+ &module_type) != 0) {
+ DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
+ if (!(params->feature_config_flags &
+ FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
+ /* In case module detection is disabled, it trys to
+ link up. The issue that can happen here is LRM /
+ LIMITING mode which set according to the module-type*/
+ DP(NETIF_MSG_LINK, "Unable to read module-type."
+ "Probably due to Bit Stretching."
+ " Proceeding...\n");
+ } else {
+ return -EINVAL;
+ }
+ } else if (bnx2x_verify_sfp_module(params, module_type) !=
+ 0) {
+ /* check SFP+ module compatibility */
+ DP(NETIF_MSG_LINK, "Module verification failed!!\n");
+ /* Turn on fault module-detected led */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH,
+ params->port);
+ return -EINVAL;
+ }
+
+ /* Turn off fault module-detected led */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_LOW,
+ params->port);
+
+ /* Check and set limiting mode / LRM mode */
+ bnx2x_bcm8726_set_limiting_mode(params, module_type);
+
+ /* Enable transmit for this module */
+ bnx2x_bcm8726_set_transmitter(bp, params->port,
+ ext_phy_addr, 1);
+ return 0;
+}
+
+void bnx2x_handle_module_detect_int(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u32 gpio_val;
+ u8 port = params->port;
+ /* Set valid module led off */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH,
+ params->port);
+
+ /* Get current gpio val refelecting module plugged in / out*/
+ gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
+
+ /* Call the handling function in case module is detected */
+ if (gpio_val == 0) {
+
+ bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
+ port);
+
+ if (bnx2x_wait_for_sfp_module_initialized(params)
+ == 0)
+ bnx2x_sfp_module_detection(params);
+ else
+ DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
+ } else {
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
+ port);
+ /* Module was plugged out. */
+ /* Disable transmit for this module */
+ bnx2x_bcm8726_set_transmitter(bp, params->port,
+ ext_phy_addr, 0);
+ }
}
static void bnx2x_bcm807x_force_10G(struct link_params *params)
@@ -2227,7 +2756,7 @@ static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc801, &val);
+ MDIO_PMA_REG_8073_CHIP_REV, &val);
if (val == 0) {
/* Mustn't set low power mode in 8073 A0 */
@@ -2365,31 +2894,40 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params,
MDIO_AN_DEVAD,
MDIO_AN_REG_ADV_PAUSE, val);
}
+static void bnx2x_set_preemphasis(struct link_params *params)
+{
+ u16 bank, i = 0;
+ struct bnx2x *bp = params->bp;
+ for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
+ bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ bank,
+ MDIO_RX0_RX_EQ_BOOST,
+ params->xgxs_config_rx[i]);
+ }
+
+ for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
+ bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ bank,
+ MDIO_TX0_TX_DRIVER,
+ params->xgxs_config_tx[i]);
+ }
+}
static void bnx2x_init_internal_phy(struct link_params *params,
struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u8 port = params->port;
if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
- u16 bank, rx_eq;
-
- rx_eq = ((params->serdes_config &
- PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
- PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
-
- DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
- for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
- bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
- CL45_WR_OVER_CL22(bp, port,
- params->phy_addr,
- bank ,
- MDIO_RX0_RX_EQ_BOOST,
- ((rx_eq &
- MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
- MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
- }
+ if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
+ bnx2x_set_preemphasis(params);
/* forced speed requested? */
if (vars->line_speed != SPEED_AUTO_NEG) {
@@ -2494,12 +3032,53 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_addr,
MDIO_WIS_DEVAD,
MDIO_WIS_REG_LASI_CNTL, 0x1);
+
+ /* BCM8705 doesn't have microcode, hence the 0 */
+ bnx2x_save_spirom_version(bp, params->port,
+ params->shmem_base, 0);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8706\n");
-
- msleep(10);
+ /* Wait until fw is loaded */
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER1, &val);
+ if (val)
+ break;
+ msleep(10);
+ }
+ DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
+ "after %d ms\n", cnt);
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ u8 i;
+ u16 reg;
+ for (i = 0; i < 4; i++) {
+ reg = MDIO_XS_8706_REG_BANK_RX0 +
+ i*(MDIO_XS_8706_REG_BANK_RX1 -
+ MDIO_XS_8706_REG_BANK_RX0);
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_XS_DEVAD,
+ reg, &val);
+ /* Clear first 3 bits of the control */
+ val &= ~0x7;
+ /* Set control bits according to
+ configuation */
+ val |= (params->xgxs_config_rx[i] &
+ 0x7);
+ DP(NETIF_MSG_LINK, "Setting RX"
+ "Equalizer to BCM8706 reg 0x%x"
+ " <-- val 0x%x\n", reg, val);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_XS_DEVAD,
+ reg, val);
+ }
+ }
/* Force speed */
/* First enable LASI */
bnx2x_cl45_write(bp, params->port,
@@ -2566,9 +3145,95 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
0x1200);
}
-
+ bnx2x_save_bcm_spirom_ver(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ params->shmem_base);
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
+ bnx2x_bcm8726_external_rom_boot(params);
+
+ /* Need to call module detected on initialization since
+ the module detection triggered by actual module
+ insertion might occur before driver is loaded, and when
+ driver is loaded, it reset all registers, including the
+ transmitter */
+ bnx2x_sfp_module_detection(params);
+ if (params->req_line_speed == SPEED_1000) {
+ DP(NETIF_MSG_LINK, "Setting 1G force\n");
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL, 0x40);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_10G_CTRL2, 0xD);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 0x5);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x400);
+ } else if ((params->req_line_speed ==
+ SPEED_AUTO_NEG) &&
+ ((params->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
+ DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV, 0x20);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_CL73, 0x040c);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FC_LD, 0x0020);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_AN, 0x1000);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, 0x1200);
+
+ /* Enable RX-ALARM control to receive
+ interrupt for 1G speed change */
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 0x4);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x400);
+ } else { /* Default 10G. Set only LASI control */
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 1);
+ }
+
+ /* Set TX PreEmphasis if needed */
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
+ "TX_CTRL2 0x%x\n",
+ params->xgxs_config_tx[0],
+ params->xgxs_config_tx[1]);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TX_CTRL1,
+ params->xgxs_config_tx[0]);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TX_CTRL2,
+ params->xgxs_config_tx[1]);
+ }
+ break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
{
@@ -2615,7 +3280,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_type,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xca13,
+ MDIO_PMA_REG_M8051_MSGOUT_REG,
&tmp1);
bnx2x_cl45_read(bp, params->port,
@@ -2682,7 +3347,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
- 0x8329, &tmp1);
+ MDIO_AN_REG_8073_2_5G, &tmp1);
if (((params->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
@@ -2696,7 +3361,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc801, &phy_ver);
+ MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
DP(NETIF_MSG_LINK, "Add 2.5G\n");
if (phy_ver > 0)
tmp1 |= 1;
@@ -2711,7 +3376,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
- 0x8329, tmp1);
+ MDIO_AN_REG_8073_2_5G, tmp1);
}
/* Add support for CL37 (passive mode) II */
@@ -2786,6 +3451,8 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
break;
}
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ {
+ u16 fw_ver1, fw_ver2;
DP(NETIF_MSG_LINK,
"Setting the SFX7101 LASI indication\n");
@@ -2815,6 +3482,50 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_CTRL, val);
+
+ /* Save spirom version */
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_VER1, &fw_ver1);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_VER2, &fw_ver2);
+
+ bnx2x_save_spirom_version(params->bp, params->port,
+ params->shmem_base,
+ (u32)(fw_ver1<<16 | fw_ver2));
+
+ break;
+ }
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ DP(NETIF_MSG_LINK,
+ "Setting the BCM8481 LASI control\n");
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 0x1);
+
+ /* Restart autoneg */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, &val);
+ val |= 0x200;
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, val);
+
+ bnx2x_save_bcm_spirom_ver(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ params->shmem_base);
+
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
DP(NETIF_MSG_LINK,
@@ -2898,38 +3609,43 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8706\n");
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
+ /* Clear RX Alarm*/
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
-
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
+ &val2);
+ /* clear LASI indication*/
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
+ &val1);
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
+ &val2);
+ DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
+ "0x%x\n", val1, val2);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_SD, &rx_sd);
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
+ &rx_sd);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &pcs_status);
-
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
+ &pcs_status);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS, &val2);
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
+ &val2);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS, &val2);
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
+ &val2);
- DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
+ DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
" pcs_status 0x%x 1Gbps link_status 0x%x\n",
rx_sd, pcs_status, val2);
/* link is up if both bit 0 of pmd_rx_sd and
@@ -2939,19 +3655,31 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
(val2 & (1<<1)));
if (ext_phy_link_up) {
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
+ /* If transmitter is disabled,
+ ignore false link up indication */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER,
+ &val1);
+ if (val1 & (1<<15)) {
+ DP(NETIF_MSG_LINK, "Tx is "
+ "disabled\n");
+ ext_phy_link_up = 0;
+ break;
+ }
+ }
+
if (val2 & (1<<1))
vars->line_speed = SPEED_1000;
else
vars->line_speed = SPEED_10000;
}
- /* clear LASI indication*/
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &val2);
break;
-
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
{
@@ -3006,7 +3734,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
ext_phy_type,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xca13,
+ MDIO_PMA_REG_M8051_MSGOUT_REG,
&val1);
/* Check the LASI */
@@ -3051,17 +3779,17 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
}
}
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS,
+ &an1000_status);
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS,
+ &an1000_status);
/* Check the link status on 1.1.2 */
bnx2x_cl45_read(bp, params->port,
@@ -3078,7 +3806,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
"an_link_status=0x%x\n",
val2, val1, an1000_status);
- ext_phy_link_up = (((val1 & 4) == 4) ||
+ ext_phy_link_up = (((val1 & 4) == 4) ||
(an1000_status & (1<<1)));
if (ext_phy_link_up &&
bnx2x_8073_is_snr_needed(params)) {
@@ -3106,11 +3834,11 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
}
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc820,
- &link_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+ &link_status);
/* Bits 0..2 --> speed detected,
bits 13..15--> link is down */
@@ -3144,17 +3872,17 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
} else {
/* See if 1G link is up for the 8072 */
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS,
+ &an1000_status);
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS,
+ &an1000_status);
if (an1000_status & (1<<1)) {
ext_phy_link_up = 1;
vars->line_speed = SPEED_1000;
@@ -3214,7 +3942,53 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
(val2 & (1<<14)));
}
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ /* Clear LASI interrupt */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
+ val1);
+ /* Check 10G-BaseT link status */
+ /* Check Global PMD signal ok */
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
+ &rx_sd);
+ /* Check PCS block lock */
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
+ &pcs_status);
+ DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
+ rx_sd, pcs_status);
+ if (rx_sd & pcs_status & 0x1) {
+ vars->line_speed = SPEED_10000;
+ ext_phy_link_up = 1;
+ } else {
+
+ /* Check 1000-BaseT link status */
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD, 0xFFE1,
+ &val1);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD, 0xFFE1,
+ &val2);
+ DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
+ "0x%x-->0x%x\n", val1, val2);
+ if (val2 & (1<<2)) {
+ vars->line_speed = SPEED_1000;
+ ext_phy_link_up = 1;
+ }
+ }
+
+ break;
default:
DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
params->ext_phy_config);
@@ -3414,7 +4188,7 @@ static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
ext_phy_addr,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
- &ctrl);
+ &ctrl);
if (!(ctrl & (1<<15))) {
DP(NETIF_MSG_LINK, "Reset completed\n\n");
break;
@@ -3440,91 +4214,39 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
{
struct bnx2x *bp = params->bp;
u32 ext_phy_type = 0;
- u16 val = 0;
- u8 ext_phy_addr = 0 ;
+ u32 spirom_ver = 0;
u8 status = 0 ;
- u32 ver_num;
if (version == NULL || params == NULL)
return -EINVAL;
+ spirom_ver = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region,
+ port_mb[params->port].ext_phy_fw_version));
+
/* reset the returned value to zero */
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
if (len < 5)
return -EINVAL;
- /* Take ext phy out of reset */
- if (!driver_loaded)
- bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
- ext_phy_type);
-
- /* wait for 1ms */
- msleep(1);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER1, &val);
- version[2] = (val & 0xFF);
- version[3] = ((val & 0xFF00)>>8);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
- &val);
- version[0] = (val & 0xFF);
- version[1] = ((val & 0xFF00)>>8);
+ version[0] = (spirom_ver & 0xFF);
+ version[1] = (spirom_ver & 0xFF00) >> 8;
+ version[2] = (spirom_ver & 0xFF0000) >> 16;
+ version[3] = (spirom_ver & 0xFF000000) >> 24;
version[4] = '\0';
- if (!driver_loaded)
- bnx2x_turn_off_sf(bp, params->port);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- /* Take ext phy out of reset */
- if (!driver_loaded)
- bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
- ext_phy_type);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &val);
- ver_num = val<<16;
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &val);
- ver_num |= val;
- status = bnx2x_format_ver(ver_num, version, len);
- break;
- }
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &val);
- ver_num = val<<16;
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &val);
- ver_num |= val;
- status = bnx2x_format_ver(ver_num, version, len);
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ status = bnx2x_format_ver(spirom_ver, version, len);
break;
-
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
break;
@@ -3571,7 +4293,7 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params,
(MDIO_REG_BANK_CL73_IEEEB0 +
(MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
0x6041);
-
+ msleep(200);
/* set aer mmd back */
bnx2x_set_aer_mmd(params, vars);
@@ -3624,6 +4346,14 @@ static void bnx2x_ext_phy_loopback(struct link_params *params)
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 0x0001);
+ break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* SFX7101_XGXS_TEST1 */
bnx2x_cl45_write(bp, params->port, ext_phy_type,
@@ -3870,9 +4600,15 @@ static u8 bnx2x_link_initialize(struct link_params *params,
}
if (vars->phy_flags & PHY_XGXS_FLAG) {
- if (params->req_line_speed &&
+ if ((params->req_line_speed &&
((params->req_line_speed == SPEED_100) ||
- (params->req_line_speed == SPEED_10))) {
+ (params->req_line_speed == SPEED_10))) ||
+ (!params->req_line_speed &&
+ (params->speed_cap_mask >=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
+ (params->speed_cap_mask <
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+ )) {
vars->phy_flags |= PHY_SGMII_FLAG;
} else {
vars->phy_flags &= ~PHY_SGMII_FLAG;
@@ -3888,11 +4624,13 @@ static u8 bnx2x_link_initialize(struct link_params *params,
/* init ext phy and enable link state int */
non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
- (params->loopback_mode == LOOPBACK_XGXS_10) ||
- (params->loopback_mode == LOOPBACK_EXT_PHY));
+ (params->loopback_mode == LOOPBACK_XGXS_10));
if (non_ext_phy ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
+ (params->loopback_mode == LOOPBACK_EXT_PHY)) {
if (params->req_line_speed == SPEED_AUTO_NEG)
bnx2x_set_parallel_detection(params, vars->phy_flags);
bnx2x_init_internal_phy(params, vars);
@@ -4086,6 +4824,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
return -EINVAL;
break;
}
+ DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
bnx2x_link_initialize(params, vars);
msleep(30);
@@ -4094,7 +4833,23 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
return 0;
}
-u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
+static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
+{
+ DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
+
+ /* Set serial boot control for external load */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL, 0x0001);
+
+ /* Disable Transmitter */
+ bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
+
+}
+
+u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
+ u8 reset_ext_phy)
{
struct bnx2x *bp = params->bp;
@@ -4132,28 +4887,37 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
*/
/* clear link led */
bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
- if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
+ if (reset_ext_phy) {
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
+ "low power mode\n",
+ port);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ port);
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ {
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ /* Set soft reset */
+ bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
+ break;
+ }
+ default:
/* HW reset */
-
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
MISC_REGISTERS_GPIO_OUTPUT_LOW,
port);
-
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_LOW,
port);
-
DP(NETIF_MSG_LINK, "reset external PHY\n");
- } else if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
- "low power mode\n",
- port);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
}
}
/* reset the SerDes/XGXS */
@@ -4194,6 +4958,11 @@ static u8 bnx2x_update_link_down(struct link_params *params,
/* activate nig drain */
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ msleep(10);
+
/* reset BigMac */
bnx2x_bmac_rx_disable(bp, params->port);
REG_WR(bp, GRCBASE_MISC +
@@ -4225,7 +4994,7 @@ static u8 bnx2x_update_link_up(struct link_params *params,
if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
if (!(vars->phy_flags &
PHY_SGMII_FLAG))
- bnx2x_set_sgmii_tx_driver(params);
+ bnx2x_set_gmii_tx_driver(params);
}
}
@@ -4238,6 +5007,7 @@ static u8 bnx2x_update_link_up(struct link_params *params,
/* update shared memory */
bnx2x_update_mng(params, vars->link_status);
+ msleep(20);
return rc;
}
/* This function should called upon link interrupt */
@@ -4276,6 +5046,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* Check external link change only for non-direct */
@@ -4310,6 +5083,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
(ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
(ext_phy_link_up && !vars->phy_link_up))
bnx2x_init_internal_phy(params, vars);
@@ -4371,16 +5145,17 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
u16 fw_ver1;
bnx2x_bcm8073_external_rom_boot(bp, port,
- ext_phy_addr[port]);
+ ext_phy_addr[port], shmem_base);
bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- if (fw_ver1 == 0) {
+ if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
DP(NETIF_MSG_LINK,
- "bnx2x_8073_common_init_phy port %x "
- "fw Download failed\n", port);
+ "bnx2x_8073_common_init_phy port %x:"
+ "Download failed. fw version = 0x%x\n",
+ port, fw_ver1);
return -EINVAL;
}
@@ -4406,7 +5181,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
/* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
- /* Phase2 of POWER_DOWN_RESET*/
+ /* Phase2 of POWER_DOWN_RESET */
/* Release bit 10 (Release Tx power down) */
bnx2x_cl45_read(bp, port,
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
@@ -4441,12 +5216,51 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
}
+
+static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+{
+ u8 ext_phy_addr;
+ u32 val;
+ s8 port;
+ /* Use port1 because of the static port-swap */
+ /* Enable the module detection interrupt */
+ val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
+ val |= ((1<<MISC_REGISTERS_GPIO_3)|
+ (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
+ REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
+
+ bnx2x_hw_reset(bp, 1);
+ msleep(5);
+ for (port = 0; port < PORT_MAX; port++) {
+ /* Extract the ext phy address for the port */
+ u32 ext_phy_config = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].external_phy_config));
+
+ ext_phy_addr =
+ ((ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
+ ext_phy_addr);
+
+ bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
+
+ /* Set fault module detected LED on */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH,
+ port);
+ }
+
+ return 0;
+}
+
u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
{
u8 rc = 0;
u32 ext_phy_type;
- DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
+ DP(NETIF_MSG_LINK, "Begin common phy init\n");
/* Read the ext_phy_type for arbitrary port(0) */
ext_phy_type = XGXS_EXT_PHY_TYPE(
@@ -4460,6 +5274,12 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
rc = bnx2x_8073_common_init_phy(bp, shmem_base);
break;
}
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ /* GPIO1 affects both ports, so there's need to pull
+ it for single port alone */
+ rc = bnx2x_8726_common_init_phy(bp, shmem_base);
+
+ break;
default:
DP(NETIF_MSG_LINK,
"bnx2x_common_init_phy: ext_phy 0x%x not required\n",
diff --git a/drivers/net/bnx2x_link.h b/drivers/net/bnx2x_link.h
index 47cb585f427..19a866dc10e 100644
--- a/drivers/net/bnx2x_link.h
+++ b/drivers/net/bnx2x_link.h
@@ -1,4 +1,4 @@
-/* Copyright 2008 Broadcom Corporation
+/* Copyright 2008-2009 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -66,8 +66,6 @@ struct link_params {
/* Device parameters */
u8 mac_addr[6];
-
-
/* shmem parameters */
u32 shmem_base;
u32 speed_cap_mask;
@@ -77,7 +75,6 @@ struct link_params {
#define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
u16 hw_led_mode; /* part of the hw_config read from the shmem */
- u32 serdes_config;
u32 lane_config;
u32 ext_phy_config;
#define XGXS_EXT_PHY_TYPE(ext_phy_config) (ext_phy_config & \
@@ -89,6 +86,12 @@ struct link_params {
/* phy_addr populated by the CLC */
u8 phy_addr;
+ u16 xgxs_config_rx[4]; /* preemphasis values for the rx side */
+
+ u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */
+ u32 feature_config_flags;
+#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
+#define FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED (2<<0)
/* Device pointer passed to all callback functions */
struct bnx2x *bp;
};
@@ -125,8 +128,11 @@ struct link_vars {
/* Initialize the phy */
u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
-/* Reset the link. Should be called when driver or interface goes down */
-u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars);
+/* Reset the link. Should be called when driver or interface goes down
+ Before calling phy firmware upgrade, the reset_ext_phy should be set
+ to 0 */
+u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
+ u8 reset_ext_phy);
/* bnx2x_link_update should be called upon link interrupt */
u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
@@ -163,6 +169,10 @@ u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
u8 driver_loaded, char data[], u32 size);
+/* bnx2x_handle_module_detect_int should be called upon module detection
+ interrupt */
+void bnx2x_handle_module_detect_int(struct link_params *params);
+
/* Get the actual link status. In case it returns 0, link is up,
otherwise link is down*/
u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
@@ -170,4 +180,5 @@ u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
/* One-time initialization for external phy after power up */
u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
+
#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 7c533797c06..00a78e8677b 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -1,6 +1,6 @@
/* bnx2x_main.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * 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
@@ -50,15 +50,13 @@
#include <linux/zlib.h>
#include <linux/io.h>
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
+
#include "bnx2x.h"
#include "bnx2x_init.h"
+#include "bnx2x_dump.h"
-#define DRV_MODULE_VERSION "1.45.23"
-#define DRV_MODULE_RELDATE "2008/11/03"
+#define DRV_MODULE_VERSION "1.48.105"
+#define DRV_MODULE_RELDATE "2009/03/02"
#define BNX2X_BC_VER 0x040200
/* Time in jiffies before concluding the transmitter is hung */
@@ -69,30 +67,36 @@ static char version[] __devinitdata =
DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Eliezer Tamir");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
+static int multi_mode = 1;
+module_param(multi_mode, int, 0);
+MODULE_PARM_DESC(multi_mode, " Use per-CPU queues");
+
static int disable_tpa;
-static int use_inta;
+module_param(disable_tpa, int, 0);
+MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature");
+
+static int int_mode;
+module_param(int_mode, int, 0);
+MODULE_PARM_DESC(int_mode, " Force interrupt mode (1 INT#x; 2 MSI)");
+
static int poll;
+module_param(poll, int, 0);
+MODULE_PARM_DESC(poll, " Use polling (for debug)");
+
+static int mrrs = -1;
+module_param(mrrs, int, 0);
+MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)");
+
static int debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, " Default debug msglevel");
+
static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
-static int use_multi;
-module_param(disable_tpa, int, 0);
-module_param(use_inta, int, 0);
-module_param(poll, int, 0);
-module_param(debug, int, 0);
-MODULE_PARM_DESC(disable_tpa, "disable the TPA (LRO) feature");
-MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
-MODULE_PARM_DESC(poll, "use polling (for debug)");
-MODULE_PARM_DESC(debug, "default debug msglevel");
-
-#ifdef BNX2X_MULTI
-module_param(use_multi, int, 0);
-MODULE_PARM_DESC(use_multi, "use per-CPU queues");
-#endif
static struct workqueue_struct *bnx2x_wq;
enum bnx2x_board_type {
@@ -213,7 +217,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
dmae->comp_val = DMAE_COMP_VAL;
- DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
+ DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
"dst_addr [%x:%08x (%08x)]\n"
DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
@@ -234,7 +238,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
if (!cnt) {
- BNX2X_ERR("dmae timeout!\n");
+ BNX2X_ERR("DMAE timeout!\n");
break;
}
cnt--;
@@ -289,7 +293,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
dmae->comp_val = DMAE_COMP_VAL;
- DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
+ DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
"dst_addr [%x:%08x (%08x)]\n"
DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
@@ -306,7 +310,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
while (*wb_comp != DMAE_COMP_VAL) {
if (!cnt) {
- BNX2X_ERR("dmae timeout!\n");
+ BNX2X_ERR("DMAE timeout!\n");
break;
}
cnt--;
@@ -468,7 +472,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
static void bnx2x_fw_dump(struct bnx2x *bp)
{
u32 mark, offset;
- u32 data[9];
+ __be32 data[9];
int word;
mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
@@ -502,82 +506,103 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
BNX2X_ERR("begin crash dump -----------------\n");
- for_each_queue(bp, i) {
+ /* Indices */
+ /* Common */
+ BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
+ " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
+ " spq_prod_idx(%u)\n",
+ bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
+ bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+
+ /* Rx */
+ for_each_rx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
- struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
- BNX2X_ERR("queue[%d]: tx_pkt_prod(%x) tx_pkt_cons(%x)"
- " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)\n",
- i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
- fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
- BNX2X_ERR(" rx_bd_prod(%x) rx_bd_cons(%x)"
+ BNX2X_ERR("fp%d: rx_bd_prod(%x) rx_bd_cons(%x)"
" *rx_bd_cons_sb(%x) rx_comp_prod(%x)"
" rx_comp_cons(%x) *rx_cons_sb(%x)\n",
- fp->rx_bd_prod, fp->rx_bd_cons,
+ i, fp->rx_bd_prod, fp->rx_bd_cons,
le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod,
fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb));
- BNX2X_ERR(" rx_sge_prod(%x) last_max_sge(%x)"
- " fp_c_idx(%x) *sb_c_idx(%x) fp_u_idx(%x)"
- " *sb_u_idx(%x) bd data(%x,%x)\n",
- fp->rx_sge_prod, fp->last_max_sge, fp->fp_c_idx,
- fp->status_blk->c_status_block.status_block_index,
- fp->fp_u_idx,
- fp->status_blk->u_status_block.status_block_index,
- hw_prods->packets_prod, hw_prods->bds_prod);
-
- start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
- end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
- for (j = start; j < end; j++) {
- struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+ BNX2X_ERR(" rx_sge_prod(%x) last_max_sge(%x)"
+ " fp_u_idx(%x) *sb_u_idx(%x)\n",
+ fp->rx_sge_prod, fp->last_max_sge,
+ le16_to_cpu(fp->fp_u_idx),
+ fp->status_blk->u_status_block.status_block_index);
+ }
- BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
- sw_bd->skb, sw_bd->first_bd);
- }
+ /* Tx */
+ for_each_tx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
- start = TX_BD(fp->tx_bd_cons - 10);
- end = TX_BD(fp->tx_bd_cons + 254);
- for (j = start; j < end; j++) {
- u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+ BNX2X_ERR("fp%d: tx_pkt_prod(%x) tx_pkt_cons(%x)"
+ " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)\n",
+ i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
+ fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
+ BNX2X_ERR(" fp_c_idx(%x) *sb_c_idx(%x)"
+ " bd data(%x,%x)\n", le16_to_cpu(fp->fp_c_idx),
+ fp->status_blk->c_status_block.status_block_index,
+ hw_prods->packets_prod, hw_prods->bds_prod);
+ }
- BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
- j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
- }
+ /* Rings */
+ /* Rx */
+ for_each_rx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503);
- for (j = start; j < end; j++) {
+ for (j = start; j != end; j = RX_BD(j + 1)) {
u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j];
struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
- BNX2X_ERR("rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
- j, rx_bd[1], rx_bd[0], sw_bd->skb);
+ BNX2X_ERR("fp%d: rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
+ i, j, rx_bd[1], rx_bd[0], sw_bd->skb);
}
start = RX_SGE(fp->rx_sge_prod);
end = RX_SGE(fp->last_max_sge);
- for (j = start; j < end; j++) {
+ for (j = start; j != end; j = RX_SGE(j + 1)) {
u32 *rx_sge = (u32 *)&fp->rx_sge_ring[j];
struct sw_rx_page *sw_page = &fp->rx_page_ring[j];
- BNX2X_ERR("rx_sge[%x]=[%x:%x] sw_page=[%p]\n",
- j, rx_sge[1], rx_sge[0], sw_page->page);
+ BNX2X_ERR("fp%d: rx_sge[%x]=[%x:%x] sw_page=[%p]\n",
+ i, j, rx_sge[1], rx_sge[0], sw_page->page);
}
start = RCQ_BD(fp->rx_comp_cons - 10);
end = RCQ_BD(fp->rx_comp_cons + 503);
- for (j = start; j < end; j++) {
+ for (j = start; j != end; j = RCQ_BD(j + 1)) {
u32 *cqe = (u32 *)&fp->rx_comp_ring[j];
- BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n",
- j, cqe[0], cqe[1], cqe[2], cqe[3]);
+ BNX2X_ERR("fp%d: cqe[%x]=[%x:%x:%x:%x]\n",
+ i, j, cqe[0], cqe[1], cqe[2], cqe[3]);
}
}
- BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
- " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
- " spq_prod_idx(%u)\n",
- bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
- bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+ /* Tx */
+ for_each_tx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
+ end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
+ for (j = start; j != end; j = TX_BD(j + 1)) {
+ struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+
+ BNX2X_ERR("fp%d: packet[%x]=[%p,%x]\n",
+ i, j, sw_bd->skb, sw_bd->first_bd);
+ }
+
+ start = TX_BD(fp->tx_bd_cons - 10);
+ end = TX_BD(fp->tx_bd_cons + 254);
+ for (j = start; j != end; j = TX_BD(j + 1)) {
+ u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+
+ BNX2X_ERR("fp%d: tx_bd[%x]=[%x:%x:%x:%x]\n",
+ i, j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
+ }
+ }
bnx2x_fw_dump(bp);
bnx2x_mc_assert(bp);
@@ -590,37 +615,44 @@ static void bnx2x_int_enable(struct bnx2x *bp)
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
u32 val = REG_RD(bp, addr);
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
+ int msi = (bp->flags & USING_MSI_FLAG) ? 1 : 0;
if (msix) {
- val &= ~HC_CONFIG_0_REG_SINGLE_ISR_EN_0;
+ val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_INT_LINE_EN_0);
val |= (HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+ } else if (msi) {
+ val &= ~HC_CONFIG_0_REG_INT_LINE_EN_0;
+ val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+ HC_CONFIG_0_REG_ATTN_BIT_EN_0);
} else {
val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
HC_CONFIG_0_REG_INT_LINE_EN_0 |
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
- val, port, addr, msix);
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
+ val, port, addr);
REG_WR(bp, addr, val);
val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
}
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
- val, port, addr, msix);
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) mode %s\n",
+ val, port, addr, (msix ? "MSI-X" : (msi ? "MSI" : "INTx")));
REG_WR(bp, addr, val);
if (CHIP_IS_E1H(bp)) {
/* init leading/trailing edge */
if (IS_E1HMF(bp)) {
- val = (0xfe0f | (1 << (BP_E1HVN(bp) + 4)));
+ val = (0xee0f | (1 << (BP_E1HVN(bp) + 4)));
if (bp->port.pmf)
- /* enable nig attention */
- val |= 0x0100;
+ /* enable nig and gpio3 attention */
+ val |= 0x1100;
} else
val = 0xffff;
@@ -643,15 +675,19 @@ static void bnx2x_int_disable(struct bnx2x *bp)
DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
val, port, addr);
+ /* flush all outstanding writes */
+ mmiowb();
+
REG_WR(bp, addr, val);
if (REG_RD(bp, addr) != val)
BNX2X_ERR("BUG! proper val not read from IGU!\n");
+
}
static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
{
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
- int i;
+ int i, offset;
/* disable interrupt handling */
atomic_inc(&bp->intr_sem);
@@ -661,11 +697,10 @@ static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
/* make sure all ISRs are done */
if (msix) {
+ synchronize_irq(bp->msix_table[0].vector);
+ offset = 1;
for_each_queue(bp, i)
- synchronize_irq(bp->msix_table[i].vector);
-
- /* one more for the Slow Path IRQ */
- synchronize_irq(bp->msix_table[i].vector);
+ synchronize_irq(bp->msix_table[i + offset].vector);
} else
synchronize_irq(bp->pdev->irq);
@@ -733,6 +768,23 @@ static u16 bnx2x_ack_int(struct bnx2x *bp)
* fast path service functions
*/
+static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
+{
+ u16 tx_cons_sb;
+
+ /* Tell compiler that status block fields can change */
+ barrier();
+ tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb);
+ return (fp->tx_pkt_cons != tx_cons_sb);
+}
+
+static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
+{
+ /* Tell compiler that consumer and producer can change */
+ barrier();
+ return (fp->tx_pkt_prod != fp->tx_pkt_cons);
+}
+
/* free skb in the packet ring at pos idx
* return idx of last bd freed
*/
@@ -824,9 +876,10 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
return (s16)(fp->bp->tx_ring_size) - used;
}
-static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
+static void bnx2x_tx_int(struct bnx2x_fastpath *fp)
{
struct bnx2x *bp = fp->bp;
+ struct netdev_queue *txq;
u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons;
int done = 0;
@@ -835,6 +888,7 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
return;
#endif
+ txq = netdev_get_tx_queue(bp->dev, fp->index);
hw_cons = le16_to_cpu(*fp->tx_cons_sb);
sw_cons = fp->tx_pkt_cons;
@@ -856,32 +910,30 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
sw_cons++;
done++;
-
- if (done == work)
- break;
}
fp->tx_pkt_cons = sw_cons;
fp->tx_bd_cons = bd_cons;
- /* Need to make the tx_cons update visible to start_xmit()
- * before checking for netif_queue_stopped(). Without the
- * memory barrier, there is a small possibility that start_xmit()
- * will miss it and cause the queue to be stopped forever.
- */
- smp_mb();
-
/* TBD need a thresh? */
- if (unlikely(netif_queue_stopped(bp->dev))) {
+ if (unlikely(netif_tx_queue_stopped(txq))) {
+
+ __netif_tx_lock(txq, smp_processor_id());
- netif_tx_lock(bp->dev);
+ /* Need to make the tx_bd_cons update visible to start_xmit()
+ * before checking for netif_tx_queue_stopped(). Without the
+ * memory barrier, there is a small possibility that
+ * start_xmit() will miss it and cause the queue to be stopped
+ * forever.
+ */
+ smp_mb();
- if (netif_queue_stopped(bp->dev) &&
+ if ((netif_tx_queue_stopped(txq)) &&
(bp->state == BNX2X_STATE_OPEN) &&
(bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
- netif_wake_queue(bp->dev);
+ netif_tx_wake_queue(txq);
- netif_tx_unlock(bp->dev);
+ __netif_tx_unlock(txq);
}
}
@@ -895,12 +947,12 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
DP(BNX2X_MSG_SP,
"fp %d cid %d got ramrod #%d state is %x type is %d\n",
- FP_IDX(fp), cid, command, bp->state,
+ fp->index, cid, command, bp->state,
rr_cqe->ramrod_cqe.ramrod_type);
bp->spq_left++;
- if (FP_IDX(fp)) {
+ if (fp->index) {
switch (command | fp->state) {
case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
BNX2X_FP_STATE_OPENING):
@@ -1060,8 +1112,7 @@ static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
pci_dma_sync_single_for_device(bp->pdev,
pci_unmap_addr(cons_rx_buf, mapping),
- bp->rx_offset + RX_COPY_THRESH,
- PCI_DMA_FROMDEVICE);
+ RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
prod_rx_buf->skb = cons_rx_buf->skb;
pci_unmap_addr_set(prod_rx_buf, mapping,
@@ -1242,7 +1293,7 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
where we are and drop the whole packet */
err = bnx2x_alloc_rx_sge(bp, fp, sge_idx);
if (unlikely(err)) {
- bp->eth_stats.rx_skb_alloc_failed++;
+ fp->eth_q_stats.rx_skb_alloc_failed++;
return err;
}
@@ -1347,7 +1398,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
/* else drop the packet and keep the buffer in the bin */
DP(NETIF_MSG_RX_STATUS,
"Failed to allocate new skb - dropping packet!\n");
- bp->eth_stats.rx_skb_alloc_failed++;
+ fp->eth_q_stats.rx_skb_alloc_failed++;
}
fp->tpa_state[queue] = BNX2X_TPA_STOP;
@@ -1358,7 +1409,7 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
u16 bd_prod, u16 rx_comp_prod,
u16 rx_sge_prod)
{
- struct tstorm_eth_rx_producers rx_prods = {0};
+ struct ustorm_eth_rx_producers rx_prods = {0};
int i;
/* Update producers */
@@ -1376,16 +1427,16 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
*/
wmb();
- for (i = 0; i < sizeof(struct tstorm_eth_rx_producers)/4; i++)
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4,
+ for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++)
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4,
((u32 *)&rx_prods)[i]);
mmiowb(); /* keep prod updates ordered */
DP(NETIF_MSG_RX_STATUS,
- "Wrote: bd_prod %u cqe_prod %u sge_prod %u\n",
- bd_prod, rx_comp_prod, rx_sge_prod);
+ "queue[%d]: wrote bd_prod %u cqe_prod %u sge_prod %u\n",
+ fp->index, bd_prod, rx_comp_prod, rx_sge_prod);
}
static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
@@ -1419,7 +1470,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
DP(NETIF_MSG_RX_STATUS,
"queue[%d]: hw_comp_cons %u sw_comp_cons %u\n",
- FP_IDX(fp), hw_comp_cons, sw_comp_cons);
+ fp->index, hw_comp_cons, sw_comp_cons);
while (sw_comp_cons != hw_comp_cons) {
struct sw_rx_bd *rx_buf = NULL;
@@ -1509,7 +1560,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
DP(NETIF_MSG_RX_ERR,
"ERROR flags %x rx packet %u\n",
cqe_fp_flags, sw_comp_cons);
- bp->eth_stats.rx_err_discard_pkt++;
+ fp->eth_q_stats.rx_err_discard_pkt++;
goto reuse_rx;
}
@@ -1526,7 +1577,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
DP(NETIF_MSG_RX_ERR,
"ERROR packet dropped "
"because of alloc failure\n");
- bp->eth_stats.rx_skb_alloc_failed++;
+ fp->eth_q_stats.rx_skb_alloc_failed++;
goto reuse_rx;
}
@@ -1552,7 +1603,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
DP(NETIF_MSG_RX_ERR,
"ERROR packet dropped because "
"of alloc failure\n");
- bp->eth_stats.rx_skb_alloc_failed++;
+ fp->eth_q_stats.rx_skb_alloc_failed++;
reuse_rx:
bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
goto next_rx;
@@ -1565,10 +1616,11 @@ reuse_rx:
if (likely(BNX2X_RX_CSUM_OK(cqe)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- bp->eth_stats.hw_csum_err++;
+ fp->eth_q_stats.hw_csum_err++;
}
}
+ skb_record_rx_queue(skb, fp->index);
#ifdef BCM_VLAN
if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
(le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
@@ -1614,7 +1666,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
{
struct bnx2x_fastpath *fp = fp_cookie;
struct bnx2x *bp = fp->bp;
- int index = FP_IDX(fp);
+ int index = fp->index;
/* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -1623,8 +1675,8 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
}
DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
- index, FP_SB_ID(fp));
- bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID, 0, IGU_INT_DISABLE, 0);
+ index, fp->sb_id);
+ bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -1636,15 +1688,14 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
prefetch(&fp->status_blk->c_status_block.status_block_index);
prefetch(&fp->status_blk->u_status_block.status_block_index);
- netif_rx_schedule(&bnx2x_fp(bp, index, napi));
+ napi_schedule(&bnx2x_fp(bp, index, napi));
return IRQ_HANDLED;
}
static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
{
- struct net_device *dev = dev_instance;
- struct bnx2x *bp = netdev_priv(dev);
+ struct bnx2x *bp = netdev_priv(dev_instance);
u16 status = bnx2x_ack_int(bp);
u16 mask;
@@ -1653,7 +1704,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
DP(NETIF_MSG_INTR, "not our interrupt!\n");
return IRQ_NONE;
}
- DP(NETIF_MSG_INTR, "got an interrupt status %u\n", status);
+ DP(NETIF_MSG_INTR, "got an interrupt status 0x%x\n", status);
/* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -1675,7 +1726,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
prefetch(&fp->status_blk->c_status_block.status_block_index);
prefetch(&fp->status_blk->u_status_block.status_block_index);
- netif_rx_schedule(&bnx2x_fp(bp, 0, napi));
+ napi_schedule(&bnx2x_fp(bp, 0, napi));
status &= ~mask;
}
@@ -1788,26 +1839,50 @@ static int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource)
/* HW Lock for shared dual port PHYs */
static void bnx2x_acquire_phy_lock(struct bnx2x *bp)
{
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
mutex_lock(&bp->port.phy_mutex);
- if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
- bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ if (bp->port.need_hw_lock)
+ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_MDIO);
}
static void bnx2x_release_phy_lock(struct bnx2x *bp)
{
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
- if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ if (bp->port.need_hw_lock)
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_MDIO);
mutex_unlock(&bp->port.phy_mutex);
}
+int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port)
+{
+ /* The GPIO should be swapped if swap register is set and active */
+ int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+ REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port;
+ int gpio_shift = gpio_num +
+ (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+ u32 gpio_mask = (1 << gpio_shift);
+ u32 gpio_reg;
+ int value;
+
+ if (gpio_num > MISC_REGISTERS_GPIO_3) {
+ BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+ return -EINVAL;
+ }
+
+ /* read GPIO value */
+ gpio_reg = REG_RD(bp, MISC_REG_GPIO);
+
+ /* get the requested pin value */
+ if ((gpio_reg & gpio_mask) == gpio_mask)
+ value = 1;
+ else
+ value = 0;
+
+ DP(NETIF_MSG_LINK, "pin %d value 0x%x\n", gpio_num, value);
+
+ return value;
+}
+
int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
{
/* The GPIO should be swapped if swap register is set and active */
@@ -1861,6 +1936,52 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
return 0;
}
+int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
+{
+ /* The GPIO should be swapped if swap register is set and active */
+ int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+ REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port;
+ int gpio_shift = gpio_num +
+ (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+ u32 gpio_mask = (1 << gpio_shift);
+ u32 gpio_reg;
+
+ if (gpio_num > MISC_REGISTERS_GPIO_3) {
+ BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+ return -EINVAL;
+ }
+
+ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+ /* read GPIO int */
+ gpio_reg = REG_RD(bp, MISC_REG_GPIO_INT);
+
+ switch (mode) {
+ case MISC_REGISTERS_GPIO_INT_OUTPUT_CLR:
+ DP(NETIF_MSG_LINK, "Clear GPIO INT %d (shift %d) -> "
+ "output low\n", gpio_num, gpio_shift);
+ /* clear SET and set CLR */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
+ break;
+
+ case MISC_REGISTERS_GPIO_INT_OUTPUT_SET:
+ DP(NETIF_MSG_LINK, "Set GPIO INT %d (shift %d) -> "
+ "output high\n", gpio_num, gpio_shift);
+ /* clear CLR and set SET */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
+ break;
+
+ default:
+ break;
+ }
+
+ REG_WR(bp, MISC_REG_GPIO_INT, gpio_reg);
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+
+ return 0;
+}
+
static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
{
u32 spio_mask = (1 << spio_num);
@@ -1915,13 +2036,16 @@ static void bnx2x_calc_fc_adv(struct bnx2x *bp)
bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
+
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
bp->port.advertising |= (ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
+
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
bp->port.advertising |= ADVERTISED_Asym_Pause;
break;
+
default:
bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
@@ -1946,7 +2070,8 @@ static void bnx2x_link_report(struct bnx2x *bp)
if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) {
if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) {
printk(", receive ");
- if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ if (bp->link_vars.flow_ctrl &
+ BNX2X_FLOW_CTRL_TX)
printk("& transmit ");
} else {
printk(", transmit ");
@@ -1961,7 +2086,7 @@ static void bnx2x_link_report(struct bnx2x *bp)
}
}
-static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
+static u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
{
if (!BP_NOMCP(bp)) {
u8 rc;
@@ -1977,18 +2102,24 @@ static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
bnx2x_acquire_phy_lock(bp);
+
+ if (load_mode == LOAD_DIAG)
+ bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
+
rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+
bnx2x_release_phy_lock(bp);
bnx2x_calc_fc_adv(bp);
- if (bp->link_vars.link_up)
+ if (CHIP_REV_IS_SLOW(bp) && bp->link_vars.link_up) {
+ bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
bnx2x_link_report(bp);
-
+ }
return rc;
}
- BNX2X_ERR("Bootcode is missing -not initializing link\n");
+ BNX2X_ERR("Bootcode is missing - can not initialize link\n");
return -EINVAL;
}
@@ -2001,17 +2132,17 @@ static void bnx2x_link_set(struct bnx2x *bp)
bnx2x_calc_fc_adv(bp);
} else
- BNX2X_ERR("Bootcode is missing -not setting link\n");
+ BNX2X_ERR("Bootcode is missing - can not set link\n");
}
static void bnx2x__link_reset(struct bnx2x *bp)
{
if (!BP_NOMCP(bp)) {
bnx2x_acquire_phy_lock(bp);
- bnx2x_link_reset(&bp->link_params, &bp->link_vars);
+ bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1);
bnx2x_release_phy_lock(bp);
} else
- BNX2X_ERR("Bootcode is missing -not resetting link\n");
+ BNX2X_ERR("Bootcode is missing - can not reset link\n");
}
static u8 bnx2x_link_test(struct bnx2x *bp)
@@ -2025,119 +2156,42 @@ static u8 bnx2x_link_test(struct bnx2x *bp)
return rc;
}
-/* Calculates the sum of vn_min_rates.
- It's needed for further normalizing of the min_rates.
-
- Returns:
- sum of vn_min_rates
- or
- 0 - if all the min_rates are 0.
- In the later case fairness algorithm should be deactivated.
- If not all min_rates are zero then those that are zeroes will
- be set to 1.
- */
-static u32 bnx2x_calc_vn_wsum(struct bnx2x *bp)
-{
- int i, port = BP_PORT(bp);
- u32 wsum = 0;
- int all_zero = 1;
-
- for (i = 0; i < E1HVN_MAX; i++) {
- u32 vn_cfg =
- SHMEM_RD(bp, mf_cfg.func_mf_config[2*i + port].config);
- u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
- FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
- if (!(vn_cfg & FUNC_MF_CFG_FUNC_HIDE)) {
- /* If min rate is zero - set it to 1 */
- if (!vn_min_rate)
- vn_min_rate = DEF_MIN_RATE;
- else
- all_zero = 0;
-
- wsum += vn_min_rate;
- }
- }
-
- /* ... only if all min rates are zeros - disable FAIRNESS */
- if (all_zero)
- return 0;
-
- return wsum;
-}
-
-static void bnx2x_init_port_minmax(struct bnx2x *bp,
- int en_fness,
- u16 port_rate,
- struct cmng_struct_per_port *m_cmng_port)
+static void bnx2x_init_port_minmax(struct bnx2x *bp)
{
- u32 r_param = port_rate / 8;
- int port = BP_PORT(bp);
- int i;
+ u32 r_param = bp->link_vars.line_speed / 8;
+ u32 fair_periodic_timeout_usec;
+ u32 t_fair;
- memset(m_cmng_port, 0, sizeof(struct cmng_struct_per_port));
+ memset(&(bp->cmng.rs_vars), 0,
+ sizeof(struct rate_shaping_vars_per_port));
+ memset(&(bp->cmng.fair_vars), 0, sizeof(struct fairness_vars_per_port));
- /* Enable minmax only if we are in e1hmf mode */
- if (IS_E1HMF(bp)) {
- u32 fair_periodic_timeout_usec;
- u32 t_fair;
-
- /* Enable rate shaping and fairness */
- m_cmng_port->flags.cmng_vn_enable = 1;
- m_cmng_port->flags.fairness_enable = en_fness ? 1 : 0;
- m_cmng_port->flags.rate_shaping_enable = 1;
+ /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
+ bp->cmng.rs_vars.rs_periodic_timeout = RS_PERIODIC_TIMEOUT_USEC / 4;
- if (!en_fness)
- DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
- " fairness will be disabled\n");
-
- /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
- m_cmng_port->rs_vars.rs_periodic_timeout =
- RS_PERIODIC_TIMEOUT_USEC / 4;
-
- /* this is the threshold below which no timer arming will occur
- 1.25 coefficient is for the threshold to be a little bigger
- than the real time, to compensate for timer in-accuracy */
- m_cmng_port->rs_vars.rs_threshold =
+ /* this is the threshold below which no timer arming will occur
+ 1.25 coefficient is for the threshold to be a little bigger
+ than the real time, to compensate for timer in-accuracy */
+ bp->cmng.rs_vars.rs_threshold =
(RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
- /* resolution of fairness timer */
- fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
- /* for 10G it is 1000usec. for 1G it is 10000usec. */
- t_fair = T_FAIR_COEF / port_rate;
+ /* resolution of fairness timer */
+ fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
+ /* for 10G it is 1000usec. for 1G it is 10000usec. */
+ t_fair = T_FAIR_COEF / bp->link_vars.line_speed;
- /* this is the threshold below which we won't arm
- the timer anymore */
- m_cmng_port->fair_vars.fair_threshold = QM_ARB_BYTES;
+ /* this is the threshold below which we won't arm the timer anymore */
+ bp->cmng.fair_vars.fair_threshold = QM_ARB_BYTES;
- /* we multiply by 1e3/8 to get bytes/msec.
- We don't want the credits to pass a credit
- of the T_FAIR*FAIR_MEM (algorithm resolution) */
- m_cmng_port->fair_vars.upper_bound =
- r_param * t_fair * FAIR_MEM;
- /* since each tick is 4 usec */
- m_cmng_port->fair_vars.fairness_timeout =
- fair_periodic_timeout_usec / 4;
-
- } else {
- /* Disable rate shaping and fairness */
- m_cmng_port->flags.cmng_vn_enable = 0;
- m_cmng_port->flags.fairness_enable = 0;
- m_cmng_port->flags.rate_shaping_enable = 0;
-
- DP(NETIF_MSG_IFUP,
- "Single function mode minmax will be disabled\n");
- }
-
- /* Store it to internal memory */
- for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
- ((u32 *)(m_cmng_port))[i]);
+ /* we multiply by 1e3/8 to get bytes/msec.
+ We don't want the credits to pass a credit
+ of the t_fair*FAIR_MEM (algorithm resolution) */
+ bp->cmng.fair_vars.upper_bound = r_param * t_fair * FAIR_MEM;
+ /* since each tick is 4 usec */
+ bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4;
}
-static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
- u32 wsum, u16 port_rate,
- struct cmng_struct_per_port *m_cmng_port)
+static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
{
struct rate_shaping_vars_per_vn m_rs_vn;
struct fairness_vars_per_vn m_fair_vn;
@@ -2153,17 +2207,18 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
} else {
vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
- /* If FAIRNESS is enabled (not all min rates are zeroes) and
+ /* If fairness is enabled (not all min rates are zeroes) and
if current min rate is zero - set it to 1.
This is a requirement of the algorithm. */
- if ((vn_min_rate == 0) && wsum)
+ if (bp->vn_weight_sum && (vn_min_rate == 0))
vn_min_rate = DEF_MIN_RATE;
vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
}
- DP(NETIF_MSG_IFUP, "func %d: vn_min_rate=%d vn_max_rate=%d "
- "wsum=%d\n", func, vn_min_rate, vn_max_rate, wsum);
+ DP(NETIF_MSG_IFUP,
+ "func %d: vn_min_rate=%d vn_max_rate=%d vn_weight_sum=%d\n",
+ func, vn_min_rate, vn_max_rate, bp->vn_weight_sum);
memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
@@ -2175,55 +2230,20 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
m_rs_vn.vn_counter.quota =
(vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
-#ifdef BNX2X_PER_PROT_QOS
- /* per protocol counter */
- for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++) {
- /* maximal Mbps for this protocol */
- m_rs_vn.protocol_counters[protocol].rate =
- protocol_max_rate[protocol];
- /* the quota in each timer period -
- number of bytes transmitted in this period */
- m_rs_vn.protocol_counters[protocol].quota =
- (u32)(rs_periodic_timeout_usec *
- ((double)m_rs_vn.
- protocol_counters[protocol].rate/8));
- }
-#endif
-
- if (wsum) {
+ if (bp->vn_weight_sum) {
/* credit for each period of the fairness algorithm:
number of bytes in T_FAIR (the vn share the port rate).
- wsum should not be larger than 10000, thus
- T_FAIR_COEF / (8 * wsum) will always be grater than zero */
+ vn_weight_sum should not be larger than 10000, thus
+ T_FAIR_COEF / (8 * vn_weight_sum) will always be greater
+ than zero */
m_fair_vn.vn_credit_delta =
- max((u64)(vn_min_rate * (T_FAIR_COEF / (8 * wsum))),
- (u64)(m_cmng_port->fair_vars.fair_threshold * 2));
+ max((u32)(vn_min_rate * (T_FAIR_COEF /
+ (8 * bp->vn_weight_sum))),
+ (u32)(bp->cmng.fair_vars.fair_threshold * 2));
DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta=%d\n",
m_fair_vn.vn_credit_delta);
}
-#ifdef BNX2X_PER_PROT_QOS
- do {
- u32 protocolWeightSum = 0;
-
- for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++)
- protocolWeightSum +=
- drvInit.protocol_min_rate[protocol];
- /* per protocol counter -
- NOT NEEDED IF NO PER-PROTOCOL CONGESTION MANAGEMENT */
- if (protocolWeightSum > 0) {
- for (protocol = 0;
- protocol < NUM_OF_PROTOCOLS; protocol++)
- /* credit for each period of the
- fairness algorithm - number of bytes in
- T_FAIR (the protocol share the vn rate) */
- m_fair_vn.protocol_credit_delta[protocol] =
- (u32)((vn_min_rate / 8) * t_fair *
- protocol_min_rate / protocolWeightSum);
- }
- } while (0);
-#endif
-
/* Store it to internal memory */
for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
REG_WR(bp, BAR_XSTRORM_INTMEM +
@@ -2236,11 +2256,10 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
((u32 *)(&m_fair_vn))[i]);
}
+
/* This function is called upon link interrupt */
static void bnx2x_link_attn(struct bnx2x *bp)
{
- int vn;
-
/* Make sure that we are synced with the current statistics */
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
@@ -2248,6 +2267,19 @@ static void bnx2x_link_attn(struct bnx2x *bp)
if (bp->link_vars.link_up) {
+ /* dropless flow control */
+ if (CHIP_IS_E1H(bp)) {
+ int port = BP_PORT(bp);
+ u32 pause_enabled = 0;
+
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ pause_enabled = 1;
+
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_PAUSE_ENABLED_OFFSET(port),
+ pause_enabled);
+ }
+
if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
struct host_port_stats *pstats;
@@ -2265,36 +2297,38 @@ static void bnx2x_link_attn(struct bnx2x *bp)
bnx2x_link_report(bp);
if (IS_E1HMF(bp)) {
+ int port = BP_PORT(bp);
int func;
+ int vn;
for (vn = VN_0; vn < E1HVN_MAX; vn++) {
if (vn == BP_E1HVN(bp))
continue;
- func = ((vn << 1) | BP_PORT(bp));
+ func = ((vn << 1) | port);
/* Set the attention towards other drivers
on the same port */
REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
(LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
}
- }
- if (CHIP_IS_E1H(bp) && (bp->link_vars.line_speed > 0)) {
- struct cmng_struct_per_port m_cmng_port;
- u32 wsum;
- int port = BP_PORT(bp);
+ if (bp->link_vars.link_up) {
+ int i;
+
+ /* Init rate shaping and fairness contexts */
+ bnx2x_init_port_minmax(bp);
- /* Init RATE SHAPING and FAIRNESS contexts */
- wsum = bnx2x_calc_vn_wsum(bp);
- bnx2x_init_port_minmax(bp, (int)wsum,
- bp->link_vars.line_speed,
- &m_cmng_port);
- if (IS_E1HMF(bp))
for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port,
- wsum, bp->link_vars.line_speed,
- &m_cmng_port);
+ bnx2x_init_vn_minmax(bp, 2*vn + port);
+
+ /* Store it to internal memory */
+ for (i = 0;
+ i < sizeof(struct cmng_struct_per_port) / 4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4,
+ ((u32 *)(&bp->cmng))[i]);
+ }
}
}
@@ -2471,6 +2505,7 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
NIG_REG_MASK_INTERRUPT_PORT0;
u32 aeu_mask;
+ u32 nig_mask = 0;
if (bp->attn_state & asserted)
BNX2X_ERR("IGU ERROR\n");
@@ -2496,7 +2531,7 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
bnx2x_acquire_phy_lock(bp);
/* save nig interrupt mask */
- bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
+ nig_mask = REG_RD(bp, nig_int_mask_addr);
REG_WR(bp, nig_int_mask_addr, 0);
bnx2x_link_attn(bp);
@@ -2551,7 +2586,7 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
/* now set back the mask */
if (asserted & ATTN_NIG_FOR_FUNC) {
- REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
+ REG_WR(bp, nig_int_mask_addr, nig_mask);
bnx2x_release_phy_lock(bp);
}
}
@@ -2573,9 +2608,8 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
BNX2X_ERR("SPIO5 hw attention\n");
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* Fan failure attention */
/* The PHY reset is controlled by GPIO 1 */
@@ -2606,6 +2640,13 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
}
}
+ if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 |
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) {
+ bnx2x_acquire_phy_lock(bp);
+ bnx2x_handle_module_detect_int(&bp->link_params);
+ bnx2x_release_phy_lock(bp);
+ }
+
if (attn & HW_INTERRUT_ASSERT_SET_0) {
val = REG_RD(bp, reg_offset);
@@ -2622,7 +2663,7 @@ static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
{
u32 val;
- if (attn & BNX2X_DOORQ_ASSERT) {
+ if (attn & AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT) {
val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
BNX2X_ERR("DB hw attention 0x%x\n", val);
@@ -2868,10 +2909,6 @@ static void bnx2x_sp_task(struct work_struct *work)
if (status & 0x1)
bnx2x_attn_int(bp);
- /* CStorm events: query_stats, port delete ramrod */
- if (status & 0x2)
- bp->stats_pending = 0;
-
bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx),
IGU_INT_NOP, 1);
bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
@@ -2896,7 +2933,7 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
return IRQ_HANDLED;
}
- bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
+ bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -2985,16 +3022,41 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
#define UPDATE_EXTEND_TSTAT(s, t) \
do { \
- diff = le32_to_cpu(tclient->s) - old_tclient->s; \
- old_tclient->s = le32_to_cpu(tclient->s); \
- ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
+ diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \
+ old_tclient->s = tclient->s; \
+ ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
+ } while (0)
+
+#define UPDATE_EXTEND_USTAT(s, t) \
+ do { \
+ diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
+ old_uclient->s = uclient->s; \
+ ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
} while (0)
#define UPDATE_EXTEND_XSTAT(s, t) \
do { \
- diff = le32_to_cpu(xclient->s) - old_xclient->s; \
- old_xclient->s = le32_to_cpu(xclient->s); \
- ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
+ diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \
+ old_xclient->s = xclient->s; \
+ ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
+ } while (0)
+
+/* minuend -= subtrahend */
+#define SUB_64(m_hi, s_hi, m_lo, s_lo) \
+ do { \
+ DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \
+ } while (0)
+
+/* minuend[hi:lo] -= subtrahend */
+#define SUB_EXTEND_64(m_hi, m_lo, s) \
+ do { \
+ SUB_64(m_hi, 0, m_lo, s); \
+ } while (0)
+
+#define SUB_EXTEND_USTAT(s, t) \
+ do { \
+ diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
+ SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
} while (0)
/*
@@ -3021,11 +3083,12 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
{
if (!bp->stats_pending) {
struct eth_query_ramrod_data ramrod_data = {0};
- int rc;
+ int i, rc;
ramrod_data.drv_counter = bp->stats_counter++;
- ramrod_data.collect_port_1b = bp->port.pmf ? 1 : 0;
- ramrod_data.ctr_id_vector = (1 << BP_CL_ID(bp));
+ ramrod_data.collect_port = bp->port.pmf ? 1 : 0;
+ for_each_queue(bp, i)
+ ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id);
rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
((u32 *)&ramrod_data)[1],
@@ -3041,7 +3104,9 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
static void bnx2x_stats_init(struct bnx2x *bp)
{
int port = BP_PORT(bp);
+ int i;
+ bp->stats_pending = 0;
bp->executer_idx = 0;
bp->stats_counter = 0;
@@ -3063,9 +3128,19 @@ static void bnx2x_stats_init(struct bnx2x *bp)
&(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
/* function stats */
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ memset(&fp->old_tclient, 0,
+ sizeof(struct tstorm_per_client_stats));
+ memset(&fp->old_uclient, 0,
+ sizeof(struct ustorm_per_client_stats));
+ memset(&fp->old_xclient, 0,
+ sizeof(struct xstorm_per_client_stats));
+ memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats));
+ }
+
memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
- memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
- memset(&bp->old_xclient, 0, sizeof(struct xstorm_per_client_stats));
memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
bp->stats_state = STATS_STATE_DISABLED;
@@ -3079,6 +3154,8 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
*stats_comp = DMAE_COMP_VAL;
+ if (CHIP_REV_IS_SLOW(bp))
+ return;
/* loader */
if (bp->executer_idx) {
@@ -3468,7 +3545,11 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
{
struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
- struct regpair diff;
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
+ struct {
+ u32 lo;
+ u32 hi;
+ } diff;
UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
@@ -3478,7 +3559,7 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
- UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
@@ -3499,12 +3580,23 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
UPDATE_STAT64(tx_stat_gterr,
tx_stat_dot3statsinternalmactransmiterrors);
UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
+
+ estats->pause_frames_received_hi =
+ pstats->mac_stx[1].rx_stat_bmac_xpf_hi;
+ estats->pause_frames_received_lo =
+ pstats->mac_stx[1].rx_stat_bmac_xpf_lo;
+
+ estats->pause_frames_sent_hi =
+ pstats->mac_stx[1].tx_stat_outxoffsent_hi;
+ estats->pause_frames_sent_lo =
+ pstats->mac_stx[1].tx_stat_outxoffsent_lo;
}
static void bnx2x_emac_stats_update(struct bnx2x *bp)
{
struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
@@ -3537,6 +3629,24 @@ static void bnx2x_emac_stats_update(struct bnx2x *bp)
UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
+
+ estats->pause_frames_received_hi =
+ pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi;
+ estats->pause_frames_received_lo =
+ pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo;
+ ADD_64(estats->pause_frames_received_hi,
+ pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi,
+ estats->pause_frames_received_lo,
+ pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo);
+
+ estats->pause_frames_sent_hi =
+ pstats->mac_stx[1].tx_stat_outxonsent_hi;
+ estats->pause_frames_sent_lo =
+ pstats->mac_stx[1].tx_stat_outxonsent_lo;
+ ADD_64(estats->pause_frames_sent_hi,
+ pstats->mac_stx[1].tx_stat_outxoffsent_hi,
+ estats->pause_frames_sent_lo,
+ pstats->mac_stx[1].tx_stat_outxoffsent_lo);
}
static int bnx2x_hw_stats_update(struct bnx2x *bp)
@@ -3545,7 +3655,11 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
struct nig_stats *old = &(bp->port.old_nig_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
struct bnx2x_eth_stats *estats = &bp->eth_stats;
- struct regpair diff;
+ struct {
+ u32 lo;
+ u32 hi;
+ } diff;
+ u32 nig_timer_max;
if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
bnx2x_bmac_stats_update(bp);
@@ -3554,7 +3668,7 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
bnx2x_emac_stats_update(bp);
else { /* unreached */
- BNX2X_ERR("stats updated by dmae but no MAC active\n");
+ BNX2X_ERR("stats updated by DMAE but no MAC active\n");
return -1;
}
@@ -3576,134 +3690,211 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
pstats->host_port_stats_start = ++pstats->host_port_stats_end;
+ nig_timer_max = SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer);
+ if (nig_timer_max != estats->nig_timer_max) {
+ estats->nig_timer_max = nig_timer_max;
+ BNX2X_ERR("NIG timer max (%u)\n", estats->nig_timer_max);
+ }
+
return 0;
}
static int bnx2x_storm_stats_update(struct bnx2x *bp)
{
struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
- int cl_id = BP_CL_ID(bp);
struct tstorm_per_port_stats *tport =
- &stats->tstorm_common.port_statistics;
- struct tstorm_per_client_stats *tclient =
- &stats->tstorm_common.client_statistics[cl_id];
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
- struct xstorm_per_client_stats *xclient =
- &stats->xstorm_common.client_statistics[cl_id];
- struct xstorm_per_client_stats *old_xclient = &bp->old_xclient;
+ &stats->tstorm_common.port_statistics;
struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
struct bnx2x_eth_stats *estats = &bp->eth_stats;
- u32 diff;
+ int i;
+
+ memset(&(fstats->total_bytes_received_hi), 0,
+ sizeof(struct host_func_stats) - 2*sizeof(u32));
+ estats->error_bytes_received_hi = 0;
+ estats->error_bytes_received_lo = 0;
+ estats->etherstatsoverrsizepkts_hi = 0;
+ estats->etherstatsoverrsizepkts_lo = 0;
+ estats->no_buff_discard_hi = 0;
+ estats->no_buff_discard_lo = 0;
- /* are storm stats valid? */
- if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ int cl_id = fp->cl_id;
+ struct tstorm_per_client_stats *tclient =
+ &stats->tstorm_common.client_statistics[cl_id];
+ struct tstorm_per_client_stats *old_tclient = &fp->old_tclient;
+ struct ustorm_per_client_stats *uclient =
+ &stats->ustorm_common.client_statistics[cl_id];
+ struct ustorm_per_client_stats *old_uclient = &fp->old_uclient;
+ struct xstorm_per_client_stats *xclient =
+ &stats->xstorm_common.client_statistics[cl_id];
+ struct xstorm_per_client_stats *old_xclient = &fp->old_xclient;
+ struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
+ u32 diff;
+
+ /* are storm stats valid? */
+ if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
bp->stats_counter) {
- DP(BNX2X_MSG_STATS, "stats not updated by tstorm"
- " tstorm counter (%d) != stats_counter (%d)\n",
- tclient->stats_counter, bp->stats_counter);
- return -1;
- }
- if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
+ DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm"
+ " xstorm counter (%d) != stats_counter (%d)\n",
+ i, xclient->stats_counter, bp->stats_counter);
+ return -1;
+ }
+ if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
bp->stats_counter) {
- DP(BNX2X_MSG_STATS, "stats not updated by xstorm"
- " xstorm counter (%d) != stats_counter (%d)\n",
- xclient->stats_counter, bp->stats_counter);
- return -2;
- }
+ DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm"
+ " tstorm counter (%d) != stats_counter (%d)\n",
+ i, tclient->stats_counter, bp->stats_counter);
+ return -2;
+ }
+ if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) !=
+ bp->stats_counter) {
+ DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm"
+ " ustorm counter (%d) != stats_counter (%d)\n",
+ i, uclient->stats_counter, bp->stats_counter);
+ return -4;
+ }
- fstats->total_bytes_received_hi =
- fstats->valid_bytes_received_hi =
+ qstats->total_bytes_received_hi =
+ qstats->valid_bytes_received_hi =
le32_to_cpu(tclient->total_rcv_bytes.hi);
- fstats->total_bytes_received_lo =
- fstats->valid_bytes_received_lo =
+ qstats->total_bytes_received_lo =
+ qstats->valid_bytes_received_lo =
le32_to_cpu(tclient->total_rcv_bytes.lo);
- estats->error_bytes_received_hi =
+ qstats->error_bytes_received_hi =
le32_to_cpu(tclient->rcv_error_bytes.hi);
- estats->error_bytes_received_lo =
+ qstats->error_bytes_received_lo =
le32_to_cpu(tclient->rcv_error_bytes.lo);
- ADD_64(estats->error_bytes_received_hi,
- estats->rx_stat_ifhcinbadoctets_hi,
- estats->error_bytes_received_lo,
- estats->rx_stat_ifhcinbadoctets_lo);
-
- ADD_64(fstats->total_bytes_received_hi,
- estats->error_bytes_received_hi,
- fstats->total_bytes_received_lo,
- estats->error_bytes_received_lo);
- UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, total_unicast_packets_received);
- UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
- total_multicast_packets_received);
- UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
- total_broadcast_packets_received);
-
- fstats->total_bytes_transmitted_hi =
+ ADD_64(qstats->total_bytes_received_hi,
+ qstats->error_bytes_received_hi,
+ qstats->total_bytes_received_lo,
+ qstats->error_bytes_received_lo);
+
+ UPDATE_EXTEND_TSTAT(rcv_unicast_pkts,
+ total_unicast_packets_received);
+ UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
+ total_multicast_packets_received);
+ UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
+ total_broadcast_packets_received);
+ UPDATE_EXTEND_TSTAT(packets_too_big_discard,
+ etherstatsoverrsizepkts);
+ UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard);
+
+ SUB_EXTEND_USTAT(ucast_no_buff_pkts,
+ total_unicast_packets_received);
+ SUB_EXTEND_USTAT(mcast_no_buff_pkts,
+ total_multicast_packets_received);
+ SUB_EXTEND_USTAT(bcast_no_buff_pkts,
+ total_broadcast_packets_received);
+ UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard);
+ UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard);
+ UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard);
+
+ qstats->total_bytes_transmitted_hi =
le32_to_cpu(xclient->total_sent_bytes.hi);
- fstats->total_bytes_transmitted_lo =
+ qstats->total_bytes_transmitted_lo =
le32_to_cpu(xclient->total_sent_bytes.lo);
- UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
- total_unicast_packets_transmitted);
- UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
- total_multicast_packets_transmitted);
- UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
- total_broadcast_packets_transmitted);
+ UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
+ total_unicast_packets_transmitted);
+ UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
+ total_multicast_packets_transmitted);
+ UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
+ total_broadcast_packets_transmitted);
+
+ old_tclient->checksum_discard = tclient->checksum_discard;
+ old_tclient->ttl0_discard = tclient->ttl0_discard;
+
+ ADD_64(fstats->total_bytes_received_hi,
+ qstats->total_bytes_received_hi,
+ fstats->total_bytes_received_lo,
+ qstats->total_bytes_received_lo);
+ ADD_64(fstats->total_bytes_transmitted_hi,
+ qstats->total_bytes_transmitted_hi,
+ fstats->total_bytes_transmitted_lo,
+ qstats->total_bytes_transmitted_lo);
+ ADD_64(fstats->total_unicast_packets_received_hi,
+ qstats->total_unicast_packets_received_hi,
+ fstats->total_unicast_packets_received_lo,
+ qstats->total_unicast_packets_received_lo);
+ ADD_64(fstats->total_multicast_packets_received_hi,
+ qstats->total_multicast_packets_received_hi,
+ fstats->total_multicast_packets_received_lo,
+ qstats->total_multicast_packets_received_lo);
+ ADD_64(fstats->total_broadcast_packets_received_hi,
+ qstats->total_broadcast_packets_received_hi,
+ fstats->total_broadcast_packets_received_lo,
+ qstats->total_broadcast_packets_received_lo);
+ ADD_64(fstats->total_unicast_packets_transmitted_hi,
+ qstats->total_unicast_packets_transmitted_hi,
+ fstats->total_unicast_packets_transmitted_lo,
+ qstats->total_unicast_packets_transmitted_lo);
+ ADD_64(fstats->total_multicast_packets_transmitted_hi,
+ qstats->total_multicast_packets_transmitted_hi,
+ fstats->total_multicast_packets_transmitted_lo,
+ qstats->total_multicast_packets_transmitted_lo);
+ ADD_64(fstats->total_broadcast_packets_transmitted_hi,
+ qstats->total_broadcast_packets_transmitted_hi,
+ fstats->total_broadcast_packets_transmitted_lo,
+ qstats->total_broadcast_packets_transmitted_lo);
+ ADD_64(fstats->valid_bytes_received_hi,
+ qstats->valid_bytes_received_hi,
+ fstats->valid_bytes_received_lo,
+ qstats->valid_bytes_received_lo);
+
+ ADD_64(estats->error_bytes_received_hi,
+ qstats->error_bytes_received_hi,
+ estats->error_bytes_received_lo,
+ qstats->error_bytes_received_lo);
+ ADD_64(estats->etherstatsoverrsizepkts_hi,
+ qstats->etherstatsoverrsizepkts_hi,
+ estats->etherstatsoverrsizepkts_lo,
+ qstats->etherstatsoverrsizepkts_lo);
+ ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi,
+ estats->no_buff_discard_lo, qstats->no_buff_discard_lo);
+ }
+
+ ADD_64(fstats->total_bytes_received_hi,
+ estats->rx_stat_ifhcinbadoctets_hi,
+ fstats->total_bytes_received_lo,
+ estats->rx_stat_ifhcinbadoctets_lo);
memcpy(estats, &(fstats->total_bytes_received_hi),
sizeof(struct host_func_stats) - 2*sizeof(u32));
- estats->mac_filter_discard = le32_to_cpu(tport->mac_filter_discard);
- estats->xxoverflow_discard = le32_to_cpu(tport->xxoverflow_discard);
- estats->brb_truncate_discard =
+ ADD_64(estats->etherstatsoverrsizepkts_hi,
+ estats->rx_stat_dot3statsframestoolong_hi,
+ estats->etherstatsoverrsizepkts_lo,
+ estats->rx_stat_dot3statsframestoolong_lo);
+ ADD_64(estats->error_bytes_received_hi,
+ estats->rx_stat_ifhcinbadoctets_hi,
+ estats->error_bytes_received_lo,
+ estats->rx_stat_ifhcinbadoctets_lo);
+
+ if (bp->port.pmf) {
+ estats->mac_filter_discard =
+ le32_to_cpu(tport->mac_filter_discard);
+ estats->xxoverflow_discard =
+ le32_to_cpu(tport->xxoverflow_discard);
+ estats->brb_truncate_discard =
le32_to_cpu(tport->brb_truncate_discard);
- estats->mac_discard = le32_to_cpu(tport->mac_discard);
-
- old_tclient->rcv_unicast_bytes.hi =
- le32_to_cpu(tclient->rcv_unicast_bytes.hi);
- old_tclient->rcv_unicast_bytes.lo =
- le32_to_cpu(tclient->rcv_unicast_bytes.lo);
- old_tclient->rcv_broadcast_bytes.hi =
- le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
- old_tclient->rcv_broadcast_bytes.lo =
- le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
- old_tclient->rcv_multicast_bytes.hi =
- le32_to_cpu(tclient->rcv_multicast_bytes.hi);
- old_tclient->rcv_multicast_bytes.lo =
- le32_to_cpu(tclient->rcv_multicast_bytes.lo);
- old_tclient->total_rcv_pkts = le32_to_cpu(tclient->total_rcv_pkts);
-
- old_tclient->checksum_discard = le32_to_cpu(tclient->checksum_discard);
- old_tclient->packets_too_big_discard =
- le32_to_cpu(tclient->packets_too_big_discard);
- estats->no_buff_discard =
- old_tclient->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
- old_tclient->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
-
- old_xclient->total_sent_pkts = le32_to_cpu(xclient->total_sent_pkts);
- old_xclient->unicast_bytes_sent.hi =
- le32_to_cpu(xclient->unicast_bytes_sent.hi);
- old_xclient->unicast_bytes_sent.lo =
- le32_to_cpu(xclient->unicast_bytes_sent.lo);
- old_xclient->multicast_bytes_sent.hi =
- le32_to_cpu(xclient->multicast_bytes_sent.hi);
- old_xclient->multicast_bytes_sent.lo =
- le32_to_cpu(xclient->multicast_bytes_sent.lo);
- old_xclient->broadcast_bytes_sent.hi =
- le32_to_cpu(xclient->broadcast_bytes_sent.hi);
- old_xclient->broadcast_bytes_sent.lo =
- le32_to_cpu(xclient->broadcast_bytes_sent.lo);
+ estats->mac_discard = le32_to_cpu(tport->mac_discard);
+ }
fstats->host_func_stats_start = ++fstats->host_func_stats_end;
+ bp->stats_pending = 0;
+
return 0;
}
static void bnx2x_net_stats_update(struct bnx2x *bp)
{
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct net_device_stats *nstats = &bp->dev->stats;
+ int i;
nstats->rx_packets =
bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
@@ -3715,34 +3906,33 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
- nstats->rx_bytes = bnx2x_hilo(&estats->valid_bytes_received_hi);
+ nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
- nstats->rx_dropped = old_tclient->checksum_discard +
- estats->mac_discard;
+ nstats->rx_dropped = estats->mac_discard;
+ for_each_queue(bp, i)
+ nstats->rx_dropped +=
+ le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
+
nstats->tx_dropped = 0;
nstats->multicast =
- bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
+ bnx2x_hilo(&estats->total_multicast_packets_received_hi);
nstats->collisions =
- estats->tx_stat_dot3statssinglecollisionframes_lo +
- estats->tx_stat_dot3statsmultiplecollisionframes_lo +
- estats->tx_stat_dot3statslatecollisions_lo +
- estats->tx_stat_dot3statsexcessivecollisions_lo;
-
- estats->jabber_packets_received =
- old_tclient->packets_too_big_discard +
- estats->rx_stat_dot3statsframestoolong_lo;
+ bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi);
nstats->rx_length_errors =
- estats->rx_stat_etherstatsundersizepkts_lo +
- estats->jabber_packets_received;
- nstats->rx_over_errors = estats->brb_drop_lo + estats->brb_truncate_lo;
- nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo;
- nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo;
- nstats->rx_fifo_errors = old_tclient->no_buff_discard;
+ bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) +
+ bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi);
+ nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) +
+ bnx2x_hilo(&estats->brb_truncate_hi);
+ nstats->rx_crc_errors =
+ bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi);
+ nstats->rx_frame_errors =
+ bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi);
+ nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi);
nstats->rx_missed_errors = estats->xxoverflow_discard;
nstats->rx_errors = nstats->rx_length_errors +
@@ -3753,46 +3943,61 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
nstats->rx_missed_errors;
nstats->tx_aborted_errors =
- estats->tx_stat_dot3statslatecollisions_lo +
- estats->tx_stat_dot3statsexcessivecollisions_lo;
- nstats->tx_carrier_errors = estats->rx_stat_falsecarriererrors_lo;
+ bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) +
+ bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi);
+ nstats->tx_carrier_errors =
+ bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi);
nstats->tx_fifo_errors = 0;
nstats->tx_heartbeat_errors = 0;
nstats->tx_window_errors = 0;
nstats->tx_errors = nstats->tx_aborted_errors +
- nstats->tx_carrier_errors;
+ nstats->tx_carrier_errors +
+ bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi);
+}
+
+static void bnx2x_drv_stats_update(struct bnx2x *bp)
+{
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
+ int i;
+
+ estats->driver_xoff = 0;
+ estats->rx_err_discard_pkt = 0;
+ estats->rx_skb_alloc_failed = 0;
+ estats->hw_csum_err = 0;
+ for_each_queue(bp, i) {
+ struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats;
+
+ estats->driver_xoff += qstats->driver_xoff;
+ estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt;
+ estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed;
+ estats->hw_csum_err += qstats->hw_csum_err;
+ }
}
static void bnx2x_stats_update(struct bnx2x *bp)
{
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
- int update = 0;
if (*stats_comp != DMAE_COMP_VAL)
return;
if (bp->port.pmf)
- update = (bnx2x_hw_stats_update(bp) == 0);
-
- update |= (bnx2x_storm_stats_update(bp) == 0);
-
- if (update)
- bnx2x_net_stats_update(bp);
+ bnx2x_hw_stats_update(bp);
- else {
- if (bp->stats_pending) {
- bp->stats_pending++;
- if (bp->stats_pending == 3) {
- BNX2X_ERR("stats not updated for 3 times\n");
- bnx2x_panic();
- return;
- }
- }
+ if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) {
+ BNX2X_ERR("storm stats were not updated for 3 times\n");
+ bnx2x_panic();
+ return;
}
+ bnx2x_net_stats_update(bp);
+ bnx2x_drv_stats_update(bp);
+
if (bp->msglevel & NETIF_MSG_TIMER) {
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
+ struct tstorm_per_client_stats *old_tclient =
+ &bp->fp->old_tclient;
+ struct bnx2x_eth_q_stats *qstats = &bp->fp->eth_q_stats;
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct net_device_stats *nstats = &bp->dev->stats;
int i;
@@ -3807,20 +4012,22 @@ static void bnx2x_stats_update(struct bnx2x *bp)
(u16)(le16_to_cpu(*bp->fp->rx_cons_sb) -
bp->fp->rx_comp_cons),
le16_to_cpu(*bp->fp->rx_cons_sb), nstats->rx_packets);
- printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n",
- netif_queue_stopped(bp->dev) ? "Xoff" : "Xon",
- estats->driver_xoff, estats->brb_drop_lo);
+ printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u "
+ "brb truncate %u\n",
+ (netif_queue_stopped(bp->dev) ? "Xoff" : "Xon"),
+ qstats->driver_xoff,
+ estats->brb_drop_lo, estats->brb_truncate_lo);
printk(KERN_DEBUG "tstats: checksum_discard %u "
- "packets_too_big_discard %u no_buff_discard %u "
+ "packets_too_big_discard %lu no_buff_discard %lu "
"mac_discard %u mac_filter_discard %u "
"xxovrflow_discard %u brb_truncate_discard %u "
"ttl0_discard %u\n",
- old_tclient->checksum_discard,
- old_tclient->packets_too_big_discard,
- old_tclient->no_buff_discard, estats->mac_discard,
- estats->mac_filter_discard, estats->xxoverflow_discard,
- estats->brb_truncate_discard,
- old_tclient->ttl0_discard);
+ le32_to_cpu(old_tclient->checksum_discard),
+ bnx2x_hilo(&qstats->etherstatsoverrsizepkts_hi),
+ bnx2x_hilo(&qstats->no_buff_discard_hi),
+ estats->mac_discard, estats->mac_filter_discard,
+ estats->xxoverflow_discard, estats->brb_truncate_discard,
+ le32_to_cpu(old_tclient->ttl0_discard));
for_each_queue(bp, i) {
printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
@@ -3969,7 +4176,7 @@ static void bnx2x_timer(unsigned long data)
struct bnx2x_fastpath *fp = &bp->fp[0];
int rc;
- bnx2x_tx_int(fp, 1000);
+ bnx2x_tx_int(fp);
rc = bnx2x_rx_int(fp, 1000);
}
@@ -4017,10 +4224,10 @@ static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id)
{
int port = BP_PORT(bp);
- bnx2x_init_fill(bp, BAR_USTRORM_INTMEM +
+ bnx2x_init_fill(bp, USTORM_INTMEM_ADDR +
USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
sizeof(struct ustorm_status_block)/4);
- bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM +
+ bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR +
CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
sizeof(struct cstorm_status_block)/4);
}
@@ -4074,18 +4281,18 @@ static void bnx2x_zero_def_sb(struct bnx2x *bp)
{
int func = BP_FUNC(bp);
- bnx2x_init_fill(bp, BAR_USTRORM_INTMEM +
+ bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR +
+ TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
+ sizeof(struct tstorm_def_status_block)/4);
+ bnx2x_init_fill(bp, USTORM_INTMEM_ADDR +
USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
sizeof(struct ustorm_def_status_block)/4);
- bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM +
+ bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR +
CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
sizeof(struct cstorm_def_status_block)/4);
- bnx2x_init_fill(bp, BAR_XSTRORM_INTMEM +
+ bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR +
XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
sizeof(struct xstorm_def_status_block)/4);
- bnx2x_init_fill(bp, BAR_TSTRORM_INTMEM +
- TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
- sizeof(struct tstorm_def_status_block)/4);
}
static void bnx2x_init_def_sb(struct bnx2x *bp,
@@ -4221,10 +4428,6 @@ static void bnx2x_update_coalesce(struct bnx2x *bp)
USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
U_SB_ETH_RX_CQ_INDEX),
bp->rx_ticks ? 0 : 1);
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
- U_SB_ETH_RX_BD_INDEX),
- bp->rx_ticks ? 0 : 1);
/* HC_INDEX_C_ETH_TX_CQ_CONS */
REG_WR8(bp, BAR_CSTRORM_INTMEM +
@@ -4255,8 +4458,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
if (fp->tpa_state[i] == BNX2X_TPA_START)
pci_unmap_single(bp->pdev,
pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size,
- PCI_DMA_FROMDEVICE);
+ bp->rx_buf_size, PCI_DMA_FROMDEVICE);
dev_kfree_skb(skb);
rx_buf->skb = NULL;
@@ -4271,16 +4473,13 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
u16 ring_prod, cqe_ring_prod;
int i, j;
- bp->rx_buf_size = bp->dev->mtu;
- bp->rx_buf_size += bp->rx_offset + ETH_OVREHEAD +
- BCM_RX_ETH_PAYLOAD_ALIGN;
+ bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN;
+ DP(NETIF_MSG_IFUP,
+ "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size);
if (bp->flags & TPA_ENABLE_FLAG) {
- DP(NETIF_MSG_IFUP,
- "rx_buf_size %d effective_mtu %d\n",
- bp->rx_buf_size, bp->dev->mtu + ETH_OVREHEAD);
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
for (i = 0; i < max_agg_queues; i++) {
@@ -4303,7 +4502,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
}
}
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
fp->rx_bd_cons = 0;
@@ -4378,8 +4577,8 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
for (i = 0; i < bp->rx_ring_size; i++) {
if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
BNX2X_ERR("was only able to allocate "
- "%d rx skbs\n", i);
- bp->eth_stats.rx_skb_alloc_failed++;
+ "%d rx skbs on queue[%d]\n", i, j);
+ fp->eth_q_stats.rx_skb_alloc_failed++;
break;
}
ring_prod = NEXT_RX_IDX(ring_prod);
@@ -4415,7 +4614,7 @@ static void bnx2x_init_tx_ring(struct bnx2x *bp)
{
int i, j;
- for_each_queue(bp, j) {
+ for_each_tx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
for (i = 1; i <= NUM_TX_RINGS; i++) {
@@ -4468,27 +4667,20 @@ static void bnx2x_init_context(struct bnx2x *bp)
for_each_queue(bp, i) {
struct eth_context *context = bnx2x_sp(bp, context[i].eth);
struct bnx2x_fastpath *fp = &bp->fp[i];
- u8 sb_id = FP_SB_ID(fp);
-
- context->xstorm_st_context.tx_bd_page_base_hi =
- U64_HI(fp->tx_desc_mapping);
- context->xstorm_st_context.tx_bd_page_base_lo =
- U64_LO(fp->tx_desc_mapping);
- context->xstorm_st_context.db_data_addr_hi =
- U64_HI(fp->tx_prods_mapping);
- context->xstorm_st_context.db_data_addr_lo =
- U64_LO(fp->tx_prods_mapping);
- context->xstorm_st_context.statistics_data = (BP_CL_ID(bp) |
- XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
+ u8 cl_id = fp->cl_id;
+ u8 sb_id = fp->sb_id;
context->ustorm_st_context.common.sb_index_numbers =
BNX2X_RX_SB_INDEX_NUM;
- context->ustorm_st_context.common.clientId = FP_CL_ID(fp);
+ context->ustorm_st_context.common.clientId = cl_id;
context->ustorm_st_context.common.status_block_id = sb_id;
context->ustorm_st_context.common.flags =
- USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT;
- context->ustorm_st_context.common.mc_alignment_size =
- BCM_RX_ETH_PAYLOAD_ALIGN;
+ (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT |
+ USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS);
+ context->ustorm_st_context.common.statistics_counter_id =
+ cl_id;
+ context->ustorm_st_context.common.mc_alignment_log_size =
+ BNX2X_RX_ALIGN_SHIFT;
context->ustorm_st_context.common.bd_buff_size =
bp->rx_buf_size;
context->ustorm_st_context.common.bd_page_base_hi =
@@ -4500,13 +4692,29 @@ static void bnx2x_init_context(struct bnx2x *bp)
(USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA |
USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING);
context->ustorm_st_context.common.sge_buff_size =
- (u16)(BCM_PAGE_SIZE*PAGES_PER_SGE);
+ (u16)min((u32)SGE_PAGE_SIZE*PAGES_PER_SGE,
+ (u32)0xffff);
context->ustorm_st_context.common.sge_page_base_hi =
U64_HI(fp->rx_sge_mapping);
context->ustorm_st_context.common.sge_page_base_lo =
U64_LO(fp->rx_sge_mapping);
}
+ context->ustorm_ag_context.cdu_usage =
+ CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
+ CDU_REGION_NUMBER_UCM_AG,
+ ETH_CONNECTION_TYPE);
+
+ context->xstorm_st_context.tx_bd_page_base_hi =
+ U64_HI(fp->tx_desc_mapping);
+ context->xstorm_st_context.tx_bd_page_base_lo =
+ U64_LO(fp->tx_desc_mapping);
+ context->xstorm_st_context.db_data_addr_hi =
+ U64_HI(fp->tx_prods_mapping);
+ context->xstorm_st_context.db_data_addr_lo =
+ U64_LO(fp->tx_prods_mapping);
+ context->xstorm_st_context.statistics_data = (cl_id |
+ XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
context->cstorm_st_context.sb_index_number =
C_SB_ETH_TX_CQ_INDEX;
context->cstorm_st_context.status_block_id = sb_id;
@@ -4515,10 +4723,6 @@ static void bnx2x_init_context(struct bnx2x *bp)
CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
CDU_REGION_NUMBER_XCM_AG,
ETH_CONNECTION_TYPE);
- context->ustorm_ag_context.cdu_usage =
- CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
- CDU_REGION_NUMBER_UCM_AG,
- ETH_CONNECTION_TYPE);
}
}
@@ -4527,14 +4731,15 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
int func = BP_FUNC(bp);
int i;
- if (!is_multi(bp))
+ if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
return;
- DP(NETIF_MSG_IFUP, "Initializing indirection table\n");
+ DP(NETIF_MSG_IFUP,
+ "Initializing indirection table multi_mode %d\n", bp->multi_mode);
for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
REG_WR8(bp, BAR_TSTRORM_INTMEM +
TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
- BP_CL_ID(bp) + (i % bp->num_queues));
+ bp->fp->cl_id + (i % bp->num_rx_queues));
}
static void bnx2x_set_client_config(struct bnx2x *bp)
@@ -4544,13 +4749,13 @@ static void bnx2x_set_client_config(struct bnx2x *bp)
int i;
tstorm_client.mtu = bp->dev->mtu;
- tstorm_client.statistics_counter_id = BP_CL_ID(bp);
tstorm_client.config_flags =
- TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+ (TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE |
+ TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE);
#ifdef BCM_VLAN
if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) {
tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
+ TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE;
DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
}
#endif
@@ -4568,6 +4773,8 @@ static void bnx2x_set_client_config(struct bnx2x *bp)
}
for_each_queue(bp, i) {
+ tstorm_client.statistics_counter_id = bp->fp[i].cl_id;
+
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id),
((u32 *)&tstorm_client)[0]);
@@ -4596,18 +4803,22 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
tstorm_mac_filter.mcast_drop_all = mask;
tstorm_mac_filter.bcast_drop_all = mask;
break;
+
case BNX2X_RX_MODE_NORMAL:
tstorm_mac_filter.bcast_accept_all = mask;
break;
+
case BNX2X_RX_MODE_ALLMULTI:
tstorm_mac_filter.mcast_accept_all = mask;
tstorm_mac_filter.bcast_accept_all = mask;
break;
+
case BNX2X_RX_MODE_PROMISC:
tstorm_mac_filter.ucast_accept_all = mask;
tstorm_mac_filter.mcast_accept_all = mask;
tstorm_mac_filter.bcast_accept_all = mask;
break;
+
default:
BNX2X_ERR("BAD rx mode (%d)\n", mode);
break;
@@ -4658,19 +4869,64 @@ static void bnx2x_init_internal_port(struct bnx2x *bp)
REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
}
+/* Calculates the sum of vn_min_rates.
+ It's needed for further normalizing of the min_rates.
+ Returns:
+ sum of vn_min_rates.
+ or
+ 0 - if all the min_rates are 0.
+ In the later case fainess algorithm should be deactivated.
+ If not all min_rates are zero then those that are zeroes will be set to 1.
+ */
+static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
+{
+ int all_zero = 1;
+ int port = BP_PORT(bp);
+ int vn;
+
+ bp->vn_weight_sum = 0;
+ for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+ int func = 2*vn + port;
+ u32 vn_cfg =
+ SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+ u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
+ FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
+
+ /* Skip hidden vns */
+ if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
+ continue;
+
+ /* If min rate is zero - set it to 1 */
+ if (!vn_min_rate)
+ vn_min_rate = DEF_MIN_RATE;
+ else
+ all_zero = 0;
+
+ bp->vn_weight_sum += vn_min_rate;
+ }
+
+ /* ... only if all min rates are zeros - disable fairness */
+ if (all_zero)
+ bp->vn_weight_sum = 0;
+}
+
static void bnx2x_init_internal_func(struct bnx2x *bp)
{
struct tstorm_eth_function_common_config tstorm_config = {0};
struct stats_indication_flags stats_flags = {0};
int port = BP_PORT(bp);
int func = BP_FUNC(bp);
- int i;
+ int i, j;
+ u32 offset;
u16 max_agg_size;
if (is_multi(bp)) {
- tstorm_config.config_flags = MULTI_FLAGS;
+ tstorm_config.config_flags = MULTI_FLAGS(bp);
tstorm_config.rss_result_mask = MULTI_MASK;
}
+ if (IS_E1HMF(bp))
+ tstorm_config.config_flags |=
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM;
tstorm_config.leading_client_id = BP_L_ID(bp);
@@ -4681,17 +4937,29 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
bnx2x_set_storm_rx_mode(bp);
- /* reset xstorm per client statistics */
- for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) {
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
- i*4, 0);
- }
- /* reset tstorm per client statistics */
- for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) {
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
- i*4, 0);
+ for_each_queue(bp, i) {
+ u8 cl_id = bp->fp[i].cl_id;
+
+ /* reset xstorm per client statistics */
+ offset = BAR_XSTRORM_INTMEM +
+ XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+ for (j = 0;
+ j < sizeof(struct xstorm_per_client_stats) / 4; j++)
+ REG_WR(bp, offset + j*4, 0);
+
+ /* reset tstorm per client statistics */
+ offset = BAR_TSTRORM_INTMEM +
+ TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+ for (j = 0;
+ j < sizeof(struct tstorm_per_client_stats) / 4; j++)
+ REG_WR(bp, offset + j*4, 0);
+
+ /* reset ustorm per client statistics */
+ offset = BAR_USTRORM_INTMEM +
+ USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+ for (j = 0;
+ j < sizeof(struct ustorm_per_client_stats) / 4; j++)
+ REG_WR(bp, offset + j*4, 0);
}
/* Init statistics related context */
@@ -4707,6 +4975,11 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4,
((u32 *)&stats_flags)[1]);
+ REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func),
+ ((u32 *)&stats_flags)[0]);
+ REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4,
+ ((u32 *)&stats_flags)[1]);
+
REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func),
((u32 *)&stats_flags)[0]);
REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4,
@@ -4726,6 +4999,13 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
+ U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
+ U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+
if (CHIP_IS_E1H(bp)) {
REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET,
IS_E1HMF(bp));
@@ -4745,20 +5025,91 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
min((u32)(min((u32)8, (u32)MAX_SKB_FRAGS) *
SGE_PAGE_SIZE * PAGES_PER_SGE),
(u32)0xffff);
- for_each_queue(bp, i) {
+ for_each_rx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)),
+ USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id),
U64_LO(fp->rx_comp_mapping));
REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)) + 4,
+ USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4,
U64_HI(fp->rx_comp_mapping));
REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
+ USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id),
max_agg_size);
}
+
+ /* dropless flow control */
+ if (CHIP_IS_E1H(bp)) {
+ struct ustorm_eth_rx_pause_data_e1h rx_pause = {0};
+
+ rx_pause.bd_thr_low = 250;
+ rx_pause.cqe_thr_low = 250;
+ rx_pause.cos = 1;
+ rx_pause.sge_thr_low = 0;
+ rx_pause.bd_thr_high = 350;
+ rx_pause.cqe_thr_high = 350;
+ rx_pause.sge_thr_high = 0;
+
+ for_each_rx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ if (!fp->disable_tpa) {
+ rx_pause.sge_thr_low = 150;
+ rx_pause.sge_thr_high = 250;
+ }
+
+
+ offset = BAR_USTRORM_INTMEM +
+ USTORM_ETH_RING_PAUSE_DATA_OFFSET(port,
+ fp->cl_id);
+ for (j = 0;
+ j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4;
+ j++)
+ REG_WR(bp, offset + j*4,
+ ((u32 *)&rx_pause)[j]);
+ }
+ }
+
+ memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port));
+
+ /* Init rate shaping and fairness contexts */
+ if (IS_E1HMF(bp)) {
+ int vn;
+
+ /* During init there is no active link
+ Until link is up, set link rate to 10Gbps */
+ bp->link_vars.line_speed = SPEED_10000;
+ bnx2x_init_port_minmax(bp);
+
+ bnx2x_calc_vn_weight_sum(bp);
+
+ for (vn = VN_0; vn < E1HVN_MAX; vn++)
+ bnx2x_init_vn_minmax(bp, 2*vn + port);
+
+ /* Enable rate shaping and fairness */
+ bp->cmng.flags.cmng_enables =
+ CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
+ if (bp->vn_weight_sum)
+ bp->cmng.flags.cmng_enables |=
+ CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
+ else
+ DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
+ " fairness will be disabled\n");
+ } else {
+ /* rate shaping and fairness are disabled */
+ DP(NETIF_MSG_IFUP,
+ "single function mode minmax will be disabled\n");
+ }
+
+
+ /* Store it to internal memory */
+ if (bp->port.pmf)
+ for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
+ ((u32 *)(&bp->cmng))[i]);
}
static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
@@ -4795,13 +5146,17 @@ static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
fp->cl_id = BP_L_ID(bp) + i;
fp->sb_id = fp->cl_id;
DP(NETIF_MSG_IFUP,
- "bnx2x_init_sb(%p,%p) index %d cl_id %d sb %d\n",
- bp, fp->status_blk, i, FP_CL_ID(fp), FP_SB_ID(fp));
+ "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d sb %d\n",
+ i, bp, fp->status_blk, fp->cl_id, fp->sb_id);
bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping,
- FP_SB_ID(fp));
+ fp->sb_id);
bnx2x_update_fpsb_idx(fp);
}
+ /* ensure status block indices were read */
+ rmb();
+
+
bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping,
DEF_SB_ID);
bnx2x_update_dsb_idx(bp);
@@ -5137,12 +5492,21 @@ static void enable_blocks_attention(struct bnx2x *bp)
}
+static void bnx2x_reset_common(struct bnx2x *bp)
+{
+ /* reset_common */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+ 0xd3ffff7f);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
+}
+
static int bnx2x_init_common(struct bnx2x *bp)
{
u32 val, i;
DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp));
+ bnx2x_reset_common(bp);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
@@ -5170,6 +5534,8 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
+ /* make sure this value is 0 */
+ REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0);
/* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
@@ -5238,14 +5604,6 @@ static int bnx2x_init_common(struct bnx2x *bp)
}
bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- if (CHIP_REV_IS_SLOW(bp)) {
- /* fix for emulation and FPGA for no pause */
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513);
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513);
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0);
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0);
- }
-
bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
/* set NIC mode */
@@ -5258,37 +5616,10 @@ static int bnx2x_init_common(struct bnx2x *bp)
bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
- if (CHIP_IS_E1H(bp)) {
- bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- TSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- CSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- XSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- USTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- } else { /* E1 */
- bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- }
+ 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);
@@ -5310,8 +5641,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, i, 0xc0cac01a);
/* TODO: replace with something meaningful */
}
- if (CHIP_IS_E1H(bp))
- bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
+ bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
REG_WR(bp, SRC_REG_SOFT_RST, 0);
if (sizeof(union cdu_context) != 1024)
@@ -5330,6 +5660,11 @@ static int bnx2x_init_common(struct bnx2x *bp)
bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
+ /* enable context validation interrupt from CFC */
+ REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
+
+ /* 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);
@@ -5382,9 +5717,14 @@ static int bnx2x_init_common(struct bnx2x *bp)
return -EBUSY;
}
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ bp->port.need_hw_lock = 1;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* Fan failure is indicated by SPIO 5 */
bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
MISC_REGISTERS_SPIO_INPUT_HI_Z);
@@ -5423,6 +5763,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
static int bnx2x_init_port(struct bnx2x *bp)
{
int port = BP_PORT(bp);
+ u32 low, high;
u32 val;
DP(BNX2X_MSG_MCP, "starting port init port %x\n", port);
@@ -5457,6 +5798,8 @@ 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));
/* Port QM comes here */
#ifdef BCM_ISCSI
@@ -5467,12 +5810,38 @@ static int bnx2x_init_port(struct bnx2x *bp)
func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
#endif
/* Port DQ comes here */
- /* Port BRB1 comes here */
+
+ bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START),
+ (port ? BRB1_PORT1_END : BRB1_PORT0_END));
+ if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
+ /* no pause for emulation and FPGA */
+ low = 0;
+ high = 513;
+ } else {
+ if (IS_E1HMF(bp))
+ low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246);
+ else if (bp->dev->mtu > 4096) {
+ if (bp->flags & ONE_PORT_FLAG)
+ low = 160;
+ else {
+ val = bp->dev->mtu;
+ /* (24*1024 + val*4)/256 */
+ low = 96 + (val/64) + ((val % 64) ? 1 : 0);
+ }
+ } else
+ low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160);
+ high = low + 56; /* 14*1024/256 */
+ }
+ REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low);
+ REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high);
+
+
/* Port PRS comes here */
/* Port TSDM comes here */
/* Port CSDM comes here */
/* Port USDM comes here */
/* Port XSDM comes here */
+
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,
@@ -5481,6 +5850,7 @@ static int bnx2x_init_port(struct bnx2x *bp)
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);
+
/* Port UPB comes here */
/* Port XPB comes here */
@@ -5539,36 +5909,63 @@ static int bnx2x_init_port(struct bnx2x *bp)
/* Port EMAC1 comes here */
/* Port DBU comes here */
/* Port DBG comes here */
+
bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
port ? NIG_PORT1_END : NIG_PORT0_END);
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
if (CHIP_IS_E1H(bp)) {
- u32 wsum;
- struct cmng_struct_per_port m_cmng_port;
- int vn;
-
/* 0x2 disable e1hov, 0x1 enable */
REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
(IS_E1HMF(bp) ? 0x1 : 0x2));
- /* Init RATE SHAPING and FAIRNESS contexts.
- Initialize as if there is 10G link. */
- wsum = bnx2x_calc_vn_wsum(bp);
- bnx2x_init_port_minmax(bp, (int)wsum, 10000, &m_cmng_port);
- if (IS_E1HMF(bp))
- for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port,
- wsum, 10000, &m_cmng_port);
+ /* support pause requests from USDM, TSDM and BRB */
+ REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0 + port*4, 0x7);
+
+ {
+ REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0);
+ REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0);
+ REG_WR(bp, NIG_REG_PAUSE_ENABLE_0 + port*4, 1);
+ }
}
/* Port MCP comes here */
/* Port DMAE comes here */
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ {
+ u32 swap_val, swap_override, aeu_gpio_mask, offset;
+
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_INPUT_HI_Z, port);
+
+ /* The GPIO should be swapped if the swap register is
+ set and active */
+ swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+ swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
+
+ /* Select function upon port-swap configuration */
+ if (port == 0) {
+ offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
+ aeu_gpio_mask = (swap_val && swap_override) ?
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
+ } else {
+ offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
+ aeu_gpio_mask = (swap_val && swap_override) ?
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
+ }
+ val = REG_RD(bp, offset);
+ /* add GPIO3 to group */
+ val |= aeu_gpio_mask;
+ REG_WR(bp, offset, val);
+ }
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* add SPIO 5 to group 0 */
val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
val |= AEU_INPUTS_ATTN_BITS_SPIO5;
@@ -5614,10 +6011,17 @@ static int bnx2x_init_func(struct bnx2x *bp)
{
int port = BP_PORT(bp);
int func = BP_FUNC(bp);
+ u32 addr, val;
int i;
DP(BNX2X_MSG_MCP, "starting func init func %x\n", func);
+ /* set MSI reconfigure capability */
+ addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0);
+ val = REG_RD(bp, addr);
+ val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0;
+ REG_WR(bp, addr, val);
+
i = FUNC_ILT_BASE(func);
bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context));
@@ -5647,9 +6051,6 @@ static int bnx2x_init_func(struct bnx2x *bp)
}
bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, HC_REG_FUNC_NUM_P0 + port*4, func);
-
/* Reset PCIE errors for debug */
REG_WR(bp, 0x2114, 0xffffffff);
REG_WR(bp, 0x2120, 0xffffffff);
@@ -5778,20 +6179,19 @@ static void bnx2x_free_mem(struct bnx2x *bp)
int i;
/* fastpath */
+ /* Common */
for_each_queue(bp, i) {
- /* Status blocks */
+ /* status blocks */
BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
bnx2x_fp(bp, i, status_blk_mapping),
sizeof(struct host_status_block) +
sizeof(struct eth_tx_db_data));
+ }
+ /* Rx */
+ for_each_rx_queue(bp, i) {
- /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
- BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
- bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
bnx2x_fp(bp, i, rx_desc_mapping),
@@ -5808,6 +6208,15 @@ static void bnx2x_free_mem(struct bnx2x *bp)
bnx2x_fp(bp, i, rx_sge_mapping),
BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
}
+ /* Tx */
+ for_each_tx_queue(bp, i) {
+
+ /* fastpath tx rings: tx_buf tx_desc */
+ BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
+ bnx2x_fp(bp, i, tx_desc_mapping),
+ sizeof(struct eth_tx_bd) * NUM_TX_BD);
+ }
/* end of fastpath */
BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
@@ -5850,29 +6259,20 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
int i;
/* fastpath */
+ /* Common */
for_each_queue(bp, i) {
bnx2x_fp(bp, i, bp) = bp;
- /* Status blocks */
+ /* status blocks */
BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
&bnx2x_fp(bp, i, status_blk_mapping),
sizeof(struct host_status_block) +
sizeof(struct eth_tx_db_data));
+ }
+ /* Rx */
+ for_each_rx_queue(bp, i) {
- bnx2x_fp(bp, i, hw_tx_prods) =
- (void *)(bnx2x_fp(bp, i, status_blk) + 1);
-
- bnx2x_fp(bp, i, tx_prods_mapping) =
- bnx2x_fp(bp, i, status_blk_mapping) +
- sizeof(struct host_status_block);
-
- /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
- BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
- sizeof(struct sw_tx_bd) * NUM_TX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
- &bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
sizeof(struct sw_rx_bd) * NUM_RX_BD);
BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
@@ -5891,6 +6291,23 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
&bnx2x_fp(bp, i, rx_sge_mapping),
BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
}
+ /* Tx */
+ for_each_tx_queue(bp, i) {
+
+ bnx2x_fp(bp, i, hw_tx_prods) =
+ (void *)(bnx2x_fp(bp, i, status_blk) + 1);
+
+ bnx2x_fp(bp, i, tx_prods_mapping) =
+ bnx2x_fp(bp, i, status_blk_mapping) +
+ sizeof(struct host_status_block);
+
+ /* fastpath tx rings: tx_buf tx_desc */
+ BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
+ sizeof(struct sw_tx_bd) * NUM_TX_BD);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
+ &bnx2x_fp(bp, i, tx_desc_mapping),
+ sizeof(struct eth_tx_bd) * NUM_TX_BD);
+ }
/* end of fastpath */
BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
@@ -5944,7 +6361,7 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i) {
+ for_each_tx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
u16 bd_cons = fp->tx_bd_cons;
@@ -5962,7 +6379,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
{
int i, j;
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
for (i = 0; i < NUM_RX_BD; i++) {
@@ -5974,8 +6391,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
pci_unmap_single(bp->pdev,
pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size,
- PCI_DMA_FROMDEVICE);
+ bp->rx_buf_size, PCI_DMA_FROMDEVICE);
rx_buf->skb = NULL;
dev_kfree_skb(skb);
@@ -6006,10 +6422,6 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
"state %x\n", i, bp->msix_table[i + offset].vector,
bnx2x_fp(bp, i, state));
- if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
- BNX2X_ERR("IRQ of fp #%d being freed while "
- "state != closed\n", i);
-
free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]);
}
}
@@ -6021,32 +6433,37 @@ static void bnx2x_free_irq(struct bnx2x *bp)
pci_disable_msix(bp->pdev);
bp->flags &= ~USING_MSIX_FLAG;
+ } else if (bp->flags & USING_MSI_FLAG) {
+ free_irq(bp->pdev->irq, bp->dev);
+ pci_disable_msi(bp->pdev);
+ bp->flags &= ~USING_MSI_FLAG;
+
} else
free_irq(bp->pdev->irq, bp->dev);
}
static int bnx2x_enable_msix(struct bnx2x *bp)
{
- int i, rc, offset;
+ int i, rc, offset = 1;
+ int igu_vec = 0;
- bp->msix_table[0].entry = 0;
- offset = 1;
- DP(NETIF_MSG_IFUP, "msix_table[0].entry = 0 (slowpath)\n");
+ bp->msix_table[0].entry = igu_vec;
+ DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec);
for_each_queue(bp, i) {
- int igu_vec = offset + i + BP_L_ID(bp);
-
+ igu_vec = BP_L_ID(bp) + offset + i;
bp->msix_table[i + offset].entry = igu_vec;
DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d "
"(fastpath #%u)\n", i + offset, igu_vec, i);
}
rc = pci_enable_msix(bp->pdev, &bp->msix_table[0],
- bp->num_queues + offset);
+ BNX2X_NUM_QUEUES(bp) + offset);
if (rc) {
- DP(NETIF_MSG_IFUP, "MSI-X is not attainable\n");
- return -1;
+ DP(NETIF_MSG_IFUP, "MSI-X is not attainable rc %d\n", rc);
+ return rc;
}
+
bp->flags |= USING_MSIX_FLAG;
return 0;
@@ -6064,27 +6481,60 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
}
for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ sprintf(fp->name, "%s.fp%d", bp->dev->name, i);
rc = request_irq(bp->msix_table[i + offset].vector,
- bnx2x_msix_fp_int, 0,
- bp->dev->name, &bp->fp[i]);
+ bnx2x_msix_fp_int, 0, fp->name, fp);
if (rc) {
- BNX2X_ERR("request fp #%d irq failed rc -%d\n",
- i + offset, -rc);
+ BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc);
bnx2x_free_msix_irqs(bp);
return -EBUSY;
}
- bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_IRQ;
+ fp->state = BNX2X_FP_STATE_IRQ;
}
+ i = BNX2X_NUM_QUEUES(bp);
+ if (is_multi(bp))
+ printk(KERN_INFO PFX
+ "%s: using MSI-X IRQs: sp %d fp %d - %d\n",
+ bp->dev->name, bp->msix_table[0].vector,
+ bp->msix_table[offset].vector,
+ bp->msix_table[offset + i - 1].vector);
+ else
+ printk(KERN_INFO PFX "%s: using MSI-X IRQs: sp %d fp %d\n",
+ bp->dev->name, bp->msix_table[0].vector,
+ bp->msix_table[offset + i - 1].vector);
+
+ return 0;
+}
+
+static int bnx2x_enable_msi(struct bnx2x *bp)
+{
+ int rc;
+
+ rc = pci_enable_msi(bp->pdev);
+ if (rc) {
+ DP(NETIF_MSG_IFUP, "MSI is not attainable\n");
+ return -1;
+ }
+ bp->flags |= USING_MSI_FLAG;
+
return 0;
}
static int bnx2x_req_irq(struct bnx2x *bp)
{
+ unsigned long flags;
int rc;
- rc = request_irq(bp->pdev->irq, bnx2x_interrupt, IRQF_SHARED,
+ if (bp->flags & USING_MSI_FLAG)
+ flags = 0;
+ else
+ flags = IRQF_SHARED;
+
+ rc = request_irq(bp->pdev->irq, bnx2x_interrupt, flags,
bp->dev->name, bp->dev);
if (!rc)
bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ;
@@ -6096,7 +6546,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
napi_enable(&bnx2x_fp(bp, i, napi));
}
@@ -6104,7 +6554,7 @@ static void bnx2x_napi_disable(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
}
@@ -6112,10 +6562,10 @@ static void bnx2x_netif_start(struct bnx2x *bp)
{
if (atomic_dec_and_test(&bp->intr_sem)) {
if (netif_running(bp->dev)) {
- if (bp->state == BNX2X_STATE_OPEN)
- netif_wake_queue(bp->dev);
bnx2x_napi_enable(bp);
bnx2x_int_enable(bp);
+ if (bp->state == BNX2X_STATE_OPEN)
+ netif_tx_wake_all_queues(bp->dev);
}
}
}
@@ -6123,11 +6573,9 @@ static void bnx2x_netif_start(struct bnx2x *bp)
static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
{
bnx2x_int_disable_sync(bp, disable_hw);
- if (netif_running(bp->dev)) {
- bnx2x_napi_disable(bp);
- netif_tx_disable(bp->dev);
- bp->dev->trans_start = jiffies; /* prevent tx timeout */
- }
+ bnx2x_napi_disable(bp);
+ netif_tx_disable(bp->dev);
+ bp->dev->trans_start = jiffies; /* prevent tx timeout */
}
/*
@@ -6143,9 +6591,9 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
* unicasts 0-31:port0 32-63:port1
* multicast 64-127:port0 128-191:port1
*/
- config->hdr.length_6b = 2;
- config->hdr.offset = port ? 31 : 0;
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.length = 2;
+ config->hdr.offset = port ? 32 : 0;
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
/* primary MAC */
@@ -6170,9 +6618,9 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
config->config_table[0].cam_entry.lsb_mac_addr);
/* broadcast */
- config->config_table[1].cam_entry.msb_mac_addr = 0xffff;
- config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
- config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
+ config->config_table[1].cam_entry.msb_mac_addr = cpu_to_le16(0xffff);
+ config->config_table[1].cam_entry.middle_mac_addr = cpu_to_le16(0xffff);
+ config->config_table[1].cam_entry.lsb_mac_addr = cpu_to_le16(0xffff);
config->config_table[1].cam_entry.flags = cpu_to_le16(port);
if (set)
config->config_table[1].target_table_entry.flags =
@@ -6201,9 +6649,9 @@ static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
* unicasts: by func number
* multicast: 20+FUNC*20, 20 each
*/
- config->hdr.length_6b = 1;
+ config->hdr.length = 1;
config->hdr.offset = BP_FUNC(bp);
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
/* primary MAC */
@@ -6237,7 +6685,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
int *state_p, int poll)
{
/* can take a while if any port is running */
- int cnt = 500;
+ int cnt = 5000;
DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
poll ? "polling" : "waiting", state, idx);
@@ -6255,8 +6703,12 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
}
mb(); /* state is changed by bnx2x_sp_event() */
- if (*state_p == state)
+ if (*state_p == state) {
+#ifdef BNX2X_STOP_ON_ERROR
+ DP(NETIF_MSG_IFUP, "exit (cnt %d)\n", 5000 - cnt);
+#endif
return 0;
+ }
msleep(1);
}
@@ -6289,33 +6741,133 @@ static int bnx2x_setup_leading(struct bnx2x *bp)
static int bnx2x_setup_multi(struct bnx2x *bp, int index)
{
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+
/* reset IGU state */
- bnx2x_ack_sb(bp, bp->fp[index].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+ bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
/* SETUP ramrod */
- bp->fp[index].state = BNX2X_FP_STATE_OPENING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
+ fp->state = BNX2X_FP_STATE_OPENING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0,
+ fp->cl_id, 0);
/* Wait for completion */
return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
- &(bp->fp[index].state), 0);
+ &(fp->state), 0);
}
static int bnx2x_poll(struct napi_struct *napi, int budget);
+
+static void bnx2x_set_int_mode(struct bnx2x *bp)
+{
+ int num_queues;
+
+ switch (int_mode) {
+ case INT_MODE_INTx:
+ case INT_MODE_MSI:
+ num_queues = 1;
+ bp->num_rx_queues = num_queues;
+ bp->num_tx_queues = num_queues;
+ DP(NETIF_MSG_IFUP,
+ "set number of queues to %d\n", num_queues);
+ break;
+
+ case INT_MODE_MSIX:
+ default:
+ if (bp->multi_mode == ETH_RSS_MODE_REGULAR)
+ num_queues = min_t(u32, num_online_cpus(),
+ BNX2X_MAX_QUEUES(bp));
+ else
+ num_queues = 1;
+ bp->num_rx_queues = num_queues;
+ bp->num_tx_queues = num_queues;
+ DP(NETIF_MSG_IFUP, "set number of rx queues to %d"
+ " number of tx queues to %d\n",
+ bp->num_rx_queues, bp->num_tx_queues);
+ /* if we can't use MSI-X we only need one fp,
+ * so try to enable MSI-X with the requested number of fp's
+ * and fallback to MSI or legacy INTx with one fp
+ */
+ if (bnx2x_enable_msix(bp)) {
+ /* failed to enable MSI-X */
+ num_queues = 1;
+ bp->num_rx_queues = num_queues;
+ bp->num_tx_queues = num_queues;
+ if (bp->multi_mode)
+ BNX2X_ERR("Multi requested but failed to "
+ "enable MSI-X set number of "
+ "queues to %d\n", num_queues);
+ }
+ break;
+ }
+ bp->dev->real_num_tx_queues = bp->num_tx_queues;
+}
+
static void bnx2x_set_rx_mode(struct net_device *dev);
/* must be called with rtnl_lock */
static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{
u32 load_code;
- int i, rc;
+ int i, rc = 0;
#ifdef BNX2X_STOP_ON_ERROR
+ DP(NETIF_MSG_IFUP, "enter load_mode %d\n", load_mode);
if (unlikely(bp->panic))
return -EPERM;
#endif
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
+ bnx2x_set_int_mode(bp);
+
+ if (bnx2x_alloc_mem(bp))
+ return -ENOMEM;
+
+ for_each_rx_queue(bp, i)
+ bnx2x_fp(bp, i, disable_tpa) =
+ ((bp->flags & TPA_ENABLE_FLAG) == 0);
+
+ for_each_rx_queue(bp, i)
+ netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+ bnx2x_poll, 128);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ for_each_rx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ fp->poll_no_work = 0;
+ fp->poll_calls = 0;
+ fp->poll_max_calls = 0;
+ fp->poll_complete = 0;
+ fp->poll_exit = 0;
+ }
+#endif
+ bnx2x_napi_enable(bp);
+
+ if (bp->flags & USING_MSIX_FLAG) {
+ rc = bnx2x_req_msix_irqs(bp);
+ if (rc) {
+ pci_disable_msix(bp->pdev);
+ goto load_error1;
+ }
+ } else {
+ if ((rc != -ENOMEM) && (int_mode != INT_MODE_INTx))
+ bnx2x_enable_msi(bp);
+ bnx2x_ack_int(bp);
+ rc = bnx2x_req_irq(bp);
+ if (rc) {
+ BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
+ if (bp->flags & USING_MSI_FLAG)
+ pci_disable_msi(bp->pdev);
+ goto load_error1;
+ }
+ if (bp->flags & USING_MSI_FLAG) {
+ bp->dev->irq = bp->pdev->irq;
+ printk(KERN_INFO PFX "%s: using MSI IRQ %d\n",
+ bp->dev->name, bp->pdev->irq);
+ }
+ }
+
/* Send LOAD_REQUEST command to MCP
Returns the type of LOAD command:
if it is the first port to be initialized
@@ -6325,19 +6877,22 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
- return -EBUSY;
+ rc = -EBUSY;
+ goto load_error2;
+ }
+ if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ rc = -EBUSY; /* other port in diagnostic mode */
+ goto load_error2;
}
- if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
- return -EBUSY; /* other port in diagnostic mode */
} else {
int port = BP_PORT(bp);
- DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+ DP(NETIF_MSG_IFUP, "NO MCP - load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
load_count[0]++;
load_count[1 + port]++;
- DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
+ DP(NETIF_MSG_IFUP, "NO MCP - new load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
if (load_count[0] == 1)
load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
@@ -6354,66 +6909,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bp->port.pmf = 0;
DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
- /* if we can't use MSI-X we only need one fp,
- * so try to enable MSI-X with the requested number of fp's
- * and fallback to inta with one fp
- */
- if (use_inta) {
- bp->num_queues = 1;
-
- } else {
- if ((use_multi > 1) && (use_multi <= BP_MAX_QUEUES(bp)))
- /* user requested number */
- bp->num_queues = use_multi;
-
- else if (use_multi)
- bp->num_queues = min_t(u32, num_online_cpus(),
- BP_MAX_QUEUES(bp));
- else
- bp->num_queues = 1;
-
- if (bnx2x_enable_msix(bp)) {
- /* failed to enable MSI-X */
- bp->num_queues = 1;
- if (use_multi)
- BNX2X_ERR("Multi requested but failed"
- " to enable MSI-X\n");
- }
- }
- DP(NETIF_MSG_IFUP,
- "set number of queues to %d\n", bp->num_queues);
-
- if (bnx2x_alloc_mem(bp))
- return -ENOMEM;
-
- for_each_queue(bp, i)
- bnx2x_fp(bp, i, disable_tpa) =
- ((bp->flags & TPA_ENABLE_FLAG) == 0);
-
- if (bp->flags & USING_MSIX_FLAG) {
- rc = bnx2x_req_msix_irqs(bp);
- if (rc) {
- pci_disable_msix(bp->pdev);
- goto load_error;
- }
- } else {
- bnx2x_ack_int(bp);
- rc = bnx2x_req_irq(bp);
- if (rc) {
- BNX2X_ERR("IRQ request failed, aborting\n");
- goto load_error;
- }
- }
-
- for_each_queue(bp, i)
- netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
- bnx2x_poll, 128);
-
/* Initialize HW */
rc = bnx2x_init_hw(bp, load_code);
if (rc) {
BNX2X_ERR("HW init failed, aborting\n");
- goto load_int_disable;
+ goto load_error2;
}
/* Setup NIC internals and enable interrupts */
@@ -6425,7 +6925,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
rc = -EBUSY;
- goto load_rings_free;
+ goto load_error3;
}
}
@@ -6434,12 +6934,12 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
rc = bnx2x_setup_leading(bp);
if (rc) {
BNX2X_ERR("Setup leading failed!\n");
- goto load_netif_stop;
+ goto load_error3;
}
if (CHIP_IS_E1H(bp))
if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
- BNX2X_ERR("!!! mf_cfg function disabled\n");
+ DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
bp->state = BNX2X_STATE_DISABLED;
}
@@ -6447,7 +6947,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
for_each_nondefault_queue(bp, i) {
rc = bnx2x_setup_multi(bp, i);
if (rc)
- goto load_netif_stop;
+ goto load_error3;
}
if (CHIP_IS_E1(bp))
@@ -6456,25 +6956,25 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_set_mac_addr_e1h(bp, 1);
if (bp->port.pmf)
- bnx2x_initial_phy_init(bp);
+ bnx2x_initial_phy_init(bp, load_mode);
/* Start fast path */
switch (load_mode) {
case LOAD_NORMAL:
/* Tx queue should be only reenabled */
- netif_wake_queue(bp->dev);
+ netif_tx_wake_all_queues(bp->dev);
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
break;
case LOAD_OPEN:
- netif_start_queue(bp->dev);
+ netif_tx_start_all_queues(bp->dev);
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
- if (bp->flags & USING_MSIX_FLAG)
- printk(KERN_INFO PFX "%s: using MSI-X\n",
- bp->dev->name);
break;
case LOAD_DIAG:
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
bp->state = BNX2X_STATE_DIAG;
break;
@@ -6492,37 +6992,41 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
return 0;
-load_netif_stop:
- bnx2x_napi_disable(bp);
-load_rings_free:
+load_error3:
+ bnx2x_int_disable_sync(bp, 1);
+ if (!BP_NOMCP(bp)) {
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ }
+ bp->port.pmf = 0;
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-load_int_disable:
- bnx2x_int_disable_sync(bp, 1);
+load_error2:
/* Release IRQs */
bnx2x_free_irq(bp);
-load_error:
+load_error1:
+ bnx2x_napi_disable(bp);
+ for_each_rx_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
- bp->port.pmf = 0;
- /* TBD we really need to reset the chip
- if we want to recover from this */
return rc;
}
static int bnx2x_stop_multi(struct bnx2x *bp, int index)
{
+ struct bnx2x_fastpath *fp = &bp->fp[index];
int rc;
/* halt the connection */
- bp->fp[index].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, index, 0);
+ fp->state = BNX2X_FP_STATE_HALTING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0);
/* Wait for completion */
rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
- &(bp->fp[index].state), 1);
+ &(fp->state), 1);
if (rc) /* timeout */
return rc;
@@ -6531,13 +7035,13 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
/* Wait for completion */
rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
- &(bp->fp[index].state), 1);
+ &(fp->state), 1);
return rc;
}
static int bnx2x_stop_leading(struct bnx2x *bp)
{
- u16 dsb_sp_prod_idx;
+ __le16 dsb_sp_prod_idx;
/* if the other port is handling traffic,
this can take a lot of time */
int cnt = 500;
@@ -6547,7 +7051,7 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
/* Send HALT ramrod */
bp->fp[0].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, BP_CL_ID(bp), 0);
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0);
/* Wait for completion */
rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
@@ -6571,13 +7075,13 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
*bp->dsb_sp_prod, dsb_sp_prod_idx);
#ifdef BNX2X_STOP_ON_ERROR
bnx2x_panic();
-#else
- rc = -EBUSY;
#endif
+ rc = -EBUSY;
break;
}
cnt--;
msleep(1);
+ rmb(); /* Refresh the dsb_sp_prod */
}
bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
@@ -6595,8 +7099,6 @@ static void bnx2x_reset_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);
- REG_WR(bp, HC_REG_CONFIG_0 + port*4, 0x1000);
-
/* Clear ILT */
base = FUNC_ILT_BASE(func);
for (i = base; i < base + ILT_PER_FUNC; i++)
@@ -6629,14 +7131,6 @@ static void bnx2x_reset_port(struct bnx2x *bp)
/* TODO: Close Doorbell port? */
}
-static void bnx2x_reset_common(struct bnx2x *bp)
-{
- /* reset_common */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
- 0xd3ffff7f);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
-}
-
static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
{
DP(BNX2X_MSG_MCP, "function %d reset_code %x\n",
@@ -6677,22 +7171,23 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bnx2x_set_storm_rx_mode(bp);
bnx2x_netif_stop(bp, 1);
- if (!netif_running(bp->dev))
- bnx2x_napi_disable(bp);
+
del_timer_sync(&bp->timer);
SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
(DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- /* Wait until tx fast path tasks complete */
- for_each_queue(bp, i) {
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+
+ /* Wait until tx fastpath tasks complete */
+ for_each_tx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
cnt = 1000;
- smp_rmb();
- while (BNX2X_HAS_TX_WORK(fp)) {
+ while (bnx2x_has_tx_work_unload(fp)) {
- bnx2x_tx_int(fp, 1000);
+ bnx2x_tx_int(fp);
if (!cnt) {
BNX2X_ERR("timeout waiting for queue[%d]\n",
i);
@@ -6705,30 +7200,26 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
}
cnt--;
msleep(1);
- smp_rmb();
}
}
/* Give HW time to discard old tx messages */
msleep(1);
- /* Release IRQs */
- bnx2x_free_irq(bp);
-
if (CHIP_IS_E1(bp)) {
struct mac_configuration_cmd *config =
bnx2x_sp(bp, mcast_config);
bnx2x_set_mac_addr_e1(bp, 0);
- for (i = 0; i < config->hdr.length_6b; i++)
+ for (i = 0; i < config->hdr.length; i++)
CAM_INVALIDATE(config->config_table[i]);
- config->hdr.length_6b = i;
+ config->hdr.length = i;
if (CHIP_REV_IS_SLOW(bp))
config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
else
config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port);
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -6792,11 +7283,11 @@ unload_error:
if (!BP_NOMCP(bp))
reset_code = bnx2x_fw_command(bp, reset_code);
else {
- DP(NETIF_MSG_IFDOWN, "NO MCP load counts %d, %d, %d\n",
+ DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
load_count[0]--;
load_count[1 + port]--;
- DP(NETIF_MSG_IFDOWN, "NO MCP new load counts %d, %d, %d\n",
+ DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
if (load_count[0] == 0)
reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
@@ -6816,12 +7307,15 @@ unload_error:
/* Report UNLOAD_DONE to MCP */
if (!BP_NOMCP(bp))
bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+
bp->port.pmf = 0;
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+ for_each_rx_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
@@ -6862,6 +7356,64 @@ reset_task_exit:
* Init service functions
*/
+static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func)
+{
+ switch (func) {
+ case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0;
+ case 1: return PXP2_REG_PGL_PRETEND_FUNC_F1;
+ case 2: return PXP2_REG_PGL_PRETEND_FUNC_F2;
+ case 3: return PXP2_REG_PGL_PRETEND_FUNC_F3;
+ case 4: return PXP2_REG_PGL_PRETEND_FUNC_F4;
+ case 5: return PXP2_REG_PGL_PRETEND_FUNC_F5;
+ case 6: return PXP2_REG_PGL_PRETEND_FUNC_F6;
+ case 7: return PXP2_REG_PGL_PRETEND_FUNC_F7;
+ default:
+ BNX2X_ERR("Unsupported function index: %d\n", func);
+ return (u32)(-1);
+ }
+}
+
+static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func)
+{
+ u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val;
+
+ /* Flush all outstanding writes */
+ mmiowb();
+
+ /* Pretend to be function 0 */
+ REG_WR(bp, reg, 0);
+ /* Flush the GRC transaction (in the chip) */
+ new_val = REG_RD(bp, reg);
+ if (new_val != 0) {
+ BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n",
+ new_val);
+ BUG();
+ }
+
+ /* From now we are in the "like-E1" mode */
+ bnx2x_int_disable(bp);
+
+ /* Flush all outstanding writes */
+ mmiowb();
+
+ /* Restore the original funtion settings */
+ REG_WR(bp, reg, orig_func);
+ new_val = REG_RD(bp, reg);
+ if (new_val != orig_func) {
+ BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n",
+ orig_func, new_val);
+ BUG();
+ }
+}
+
+static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func)
+{
+ if (CHIP_IS_E1H(bp))
+ bnx2x_undi_int_disable_e1h(bp, func);
+ else
+ bnx2x_int_disable(bp);
+}
+
static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
{
u32 val;
@@ -6874,10 +7426,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
*/
bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
- if (val == 0x7)
- REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
-
if (val == 0x7) {
u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
/* save our func */
@@ -6885,6 +7433,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
u32 swap_en;
u32 swap_val;
+ /* clear the UNDI indication */
+ REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
+
BNX2X_DEV_INFO("UNDI is active! reset device\n");
/* try unload UNDI on port 0 */
@@ -6910,8 +7461,10 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
bnx2x_fw_command(bp, reset_code);
}
- REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
- HC_REG_CONFIG_0), 0x1000);
+ /* now it's safe to release the lock */
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
+
+ bnx2x_undi_int_disable(bp, func);
/* close input traffic and wait for it */
/* Do not rcv packets to BRB */
@@ -6954,7 +7507,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
bp->fw_seq =
(SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK);
- }
+
+ } else
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
}
}
@@ -6971,12 +7526,19 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
id |= ((val & 0xf) << 12);
val = REG_RD(bp, MISC_REG_CHIP_METAL);
id |= ((val & 0xff) << 4);
- REG_RD(bp, MISC_REG_BOND_ID);
+ val = REG_RD(bp, MISC_REG_BOND_ID);
id |= (val & 0xf);
bp->common.chip_id = id;
bp->link_params.chip_id = bp->common.chip_id;
BNX2X_DEV_INFO("chip ID is 0x%x\n", id);
+ val = (REG_RD(bp, 0x2874) & 0x55);
+ if ((bp->common.chip_id & 0x1) ||
+ (CHIP_IS_E1(bp) && val) || (CHIP_IS_E1H(bp) && (val == 0x55))) {
+ bp->flags |= ONE_PORT_FLAG;
+ BNX2X_DEV_INFO("single port device\n");
+ }
+
val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4);
bp->common.flash_size = (NVRAM_1MB_SIZE <<
(val & MCPR_NVM_CFG4_FLASH_SIZE));
@@ -7001,15 +7563,21 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
BNX2X_ERR("BAD MCP validity signature\n");
bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
- bp->common.board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
-
- BNX2X_DEV_INFO("hw_config 0x%08x board 0x%08x\n",
- bp->common.hw_config, bp->common.board);
+ BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config);
bp->link_params.hw_led_mode = ((bp->common.hw_config &
SHARED_HW_CFG_LED_MODE_MASK) >>
SHARED_HW_CFG_LED_MODE_SHIFT);
+ bp->link_params.feature_config_flags = 0;
+ val = SHMEM_RD(bp, dev_info.shared_feature_config.config);
+ if (val & SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED)
+ bp->link_params.feature_config_flags |=
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED;
+ else
+ bp->link_params.feature_config_flags &=
+ ~FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED;
+
val = SHMEM_RD(bp, dev_info.bc_rev) >> 8;
bp->common.bc_ver = val;
BNX2X_DEV_INFO("bc_ver %X\n", val);
@@ -7028,7 +7596,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
bp->flags |= NO_WOL_FLAG;
}
BNX2X_DEV_INFO("%sWoL capable\n",
- (bp->flags & NO_WOL_FLAG) ? "Not " : "");
+ (bp->flags & NO_WOL_FLAG) ? "not " : "");
val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
@@ -7121,48 +7689,60 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
SUPPORTED_Asym_Pause);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_2500baseX_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_2500baseX_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
@@ -7178,6 +7758,22 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
SUPPORTED_Asym_Pause);
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
bp->link_params.ext_phy_config);
@@ -7403,12 +7999,12 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
{
int port = BP_PORT(bp);
u32 val, val2;
+ u32 config;
+ u16 i;
bp->link_params.bp = bp;
bp->link_params.port = port;
- bp->link_params.serdes_config =
- SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
bp->link_params.lane_config =
SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
bp->link_params.ext_phy_config =
@@ -7421,10 +8017,35 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->port.link_config =
SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
- BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n"
- KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x"
- " link_config 0x%08x\n",
- bp->link_params.serdes_config,
+ /* Get the 4 lanes xgxs config rx and tx */
+ for (i = 0; i < 2; i++) {
+ val = SHMEM_RD(bp,
+ dev_info.port_hw_config[port].xgxs_config_rx[i<<1]);
+ bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff);
+ bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff);
+
+ val = SHMEM_RD(bp,
+ dev_info.port_hw_config[port].xgxs_config_tx[i<<1]);
+ bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff);
+ bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff);
+ }
+
+ config = SHMEM_RD(bp, dev_info.port_feature_config[port].config);
+ if (config & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED)
+ bp->link_params.feature_config_flags |=
+ FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
+ else
+ bp->link_params.feature_config_flags &=
+ ~FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
+
+ /* If the device is capable of WoL, set the default state according
+ * to the HW
+ */
+ bp->wol = (!(bp->flags & NO_WOL_FLAG) &&
+ (config & PORT_FEATURE_WOL_ENABLED));
+
+ BNX2X_DEV_INFO("lane_config 0x%08x ext_phy_config 0x%08x"
+ " speed_cap_mask 0x%08x link_config 0x%08x\n",
bp->link_params.lane_config,
bp->link_params.ext_phy_config,
bp->link_params.speed_cap_mask, bp->port.link_config);
@@ -7471,7 +8092,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
"(0x%04x)\n",
func, bp->e1hov, bp->e1hov);
} else {
- BNX2X_DEV_INFO("Single function mode\n");
+ BNX2X_DEV_INFO("single function mode\n");
if (BP_E1HVN(bp)) {
BNX2X_ERR("!!! No valid E1HOV for func %d,"
" aborting\n", func);
@@ -7521,6 +8142,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
static int __devinit bnx2x_init_bp(struct bnx2x *bp)
{
int func = BP_FUNC(bp);
+ int timer_interval;
int rc;
/* Disable interrupt handling until HW is initialized */
@@ -7544,6 +8166,16 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
printk(KERN_ERR PFX
"MCP disabled, must load devices in order!\n");
+ /* Set multi queue mode */
+ if ((multi_mode != ETH_RSS_MODE_DISABLED) &&
+ ((int_mode == INT_MODE_INTx) || (int_mode == INT_MODE_MSI))) {
+ printk(KERN_ERR PFX
+ "Multi disabled since int_mode requested is not MSI-X\n");
+ multi_mode = ETH_RSS_MODE_DISABLED;
+ }
+ bp->multi_mode = multi_mode;
+
+
/* Set TPA flags */
if (disable_tpa) {
bp->flags &= ~TPA_ENABLE_FLAG;
@@ -7553,18 +8185,18 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->dev->features |= NETIF_F_LRO;
}
+ bp->mrrs = mrrs;
bp->tx_ring_size = MAX_TX_AVAIL;
bp->rx_ring_size = MAX_RX_AVAIL;
bp->rx_csum = 1;
- bp->rx_offset = 0;
bp->tx_ticks = 50;
bp->rx_ticks = 25;
- bp->timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
- bp->current_interval = (poll ? poll : bp->timer_interval);
+ timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
+ bp->current_interval = (poll ? poll : timer_interval);
init_timer(&bp->timer);
bp->timer.expires = jiffies + bp->current_interval;
@@ -7609,14 +8241,16 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
cmd->port = PORT_FIBRE;
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
cmd->port = PORT_TP;
break;
@@ -7838,6 +8472,84 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
info->regdump_len = 0;
}
+#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
+#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
+
+static int bnx2x_get_regs_len(struct net_device *dev)
+{
+ static u32 regdump_len;
+ struct bnx2x *bp = netdev_priv(dev);
+ int i;
+
+ if (regdump_len)
+ return regdump_len;
+
+ if (CHIP_IS_E1(bp)) {
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E1_ONLINE(reg_addrs[i].info))
+ regdump_len += reg_addrs[i].size;
+
+ for (i = 0; i < WREGS_COUNT_E1; i++)
+ if (IS_E1_ONLINE(wreg_addrs_e1[i].info))
+ regdump_len += wreg_addrs_e1[i].size *
+ (1 + wreg_addrs_e1[i].read_regs_count);
+
+ } else { /* E1H */
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E1H_ONLINE(reg_addrs[i].info))
+ regdump_len += reg_addrs[i].size;
+
+ for (i = 0; i < WREGS_COUNT_E1H; i++)
+ if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info))
+ regdump_len += wreg_addrs_e1h[i].size *
+ (1 + wreg_addrs_e1h[i].read_regs_count);
+ }
+ regdump_len *= 4;
+ regdump_len += sizeof(struct dump_hdr);
+
+ return regdump_len;
+}
+
+static void bnx2x_get_regs(struct net_device *dev,
+ struct ethtool_regs *regs, void *_p)
+{
+ u32 *p = _p, i, j;
+ struct bnx2x *bp = netdev_priv(dev);
+ struct dump_hdr dump_hdr = {0};
+
+ regs->version = 0;
+ memset(p, 0, regs->len);
+
+ if (!netif_running(bp->dev))
+ return;
+
+ dump_hdr.hdr_size = (sizeof(struct dump_hdr) / 4) - 1;
+ dump_hdr.dump_sign = dump_sign_all;
+ dump_hdr.xstorm_waitp = REG_RD(bp, XSTORM_WAITP_ADDR);
+ dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR);
+ dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR);
+ dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR);
+ dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE;
+
+ memcpy(p, &dump_hdr, sizeof(struct dump_hdr));
+ p += dump_hdr.hdr_size + 1;
+
+ if (CHIP_IS_E1(bp)) {
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E1_ONLINE(reg_addrs[i].info))
+ for (j = 0; j < reg_addrs[i].size; j++)
+ *p++ = REG_RD(bp,
+ reg_addrs[i].addr + j*4);
+
+ } else { /* E1H */
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E1H_ONLINE(reg_addrs[i].info))
+ for (j = 0; j < reg_addrs[i].size; j++)
+ *p++ = REG_RD(bp,
+ reg_addrs[i].addr + j*4);
+ }
+}
+
static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct bnx2x *bp = netdev_priv(dev);
@@ -7996,7 +8708,7 @@ static void bnx2x_disable_nvram_access(struct bnx2x *bp)
MCPR_NVM_ACCESS_ENABLE_WR_EN)));
}
-static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
+static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val,
u32 cmd_flags)
{
int count, i, rc;
@@ -8032,8 +8744,7 @@ static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
/* we read nvram data in cpu order
* but ethtool sees it as an array of bytes
* converting to big-endian will do the work */
- val = cpu_to_be32(val);
- *ret_val = val;
+ *ret_val = cpu_to_be32(val);
rc = 0;
break;
}
@@ -8047,7 +8758,7 @@ static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
{
int rc;
u32 cmd_flags;
- u32 val;
+ __be32 val;
if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
DP(BNX2X_MSG_NVM,
@@ -8103,6 +8814,9 @@ static int bnx2x_get_eeprom(struct net_device *dev,
struct bnx2x *bp = netdev_priv(dev);
int rc;
+ if (!netif_running(dev))
+ return -EAGAIN;
+
DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
@@ -8163,7 +8877,7 @@ static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
int rc;
u32 cmd_flags;
u32 align_offset;
- u32 val;
+ __be32 val;
if (offset + buf_size > bp->common.flash_size) {
DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
@@ -8292,7 +9006,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
if ((bp->state == BNX2X_STATE_OPEN) ||
(bp->state == BNX2X_STATE_DISABLED)) {
rc |= bnx2x_link_reset(&bp->link_params,
- &bp->link_vars);
+ &bp->link_vars, 1);
rc |= bnx2x_phy_init(&bp->link_params,
&bp->link_vars);
}
@@ -8382,7 +9096,8 @@ static void bnx2x_get_pauseparam(struct net_device *dev,
{
struct bnx2x *bp = netdev_priv(dev);
- epause->autoneg = (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
+ epause->autoneg = (bp->link_params.req_flow_ctrl ==
+ BNX2X_FLOW_CTRL_AUTO) &&
(bp->link_params.req_line_speed == SPEED_AUTO_NEG);
epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
@@ -8514,8 +9229,7 @@ static const struct {
{ "nvram_test (online)" },
{ "interrupt_test (online)" },
{ "link_test (online)" },
- { "idle check (online)" },
- { "MC errors (online)" }
+ { "idle check (online)" }
};
static int bnx2x_self_test_count(struct net_device *dev)
@@ -8703,24 +9417,23 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
u16 len;
int rc = -ENODEV;
- if (loopback_mode == BNX2X_MAC_LOOPBACK) {
+ /* check the loopback mode */
+ switch (loopback_mode) {
+ case BNX2X_PHY_LOOPBACK:
+ if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10)
+ return -EINVAL;
+ break;
+ case BNX2X_MAC_LOOPBACK:
bp->link_params.loopback_mode = LOOPBACK_BMAC;
- bnx2x_acquire_phy_lock(bp);
bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
-
- } else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
- bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
- bnx2x_acquire_phy_lock(bp);
- bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
- /* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
-
- } else
+ break;
+ default:
return -EINVAL;
+ }
- pkt_size = 1514;
+ /* prepare the loopback packet */
+ pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
+ bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
if (!skb) {
rc = -ENOMEM;
@@ -8732,6 +9445,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
for (i = ETH_HLEN; i < pkt_size; i++)
packet[i] = (unsigned char) (i & 0xff);
+ /* send the loopback packet */
num_pkts = 0;
tx_start_idx = le16_to_cpu(*fp->tx_cons_sb);
rx_start_idx = le16_to_cpu(*fp->rx_cons_sb);
@@ -8756,12 +9470,10 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
wmb();
- fp->hw_tx_prods->bds_prod =
- cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1);
+ le16_add_cpu(&fp->hw_tx_prods->bds_prod, 1);
mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod =
- cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
- DOORBELL(bp, FP_IDX(fp), 0);
+ le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
+ DOORBELL(bp, fp->index, 0);
mmiowb();
@@ -8816,23 +9528,27 @@ test_loopback_exit:
static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
{
- int rc = 0;
+ int rc = 0, res;
if (!netif_running(bp->dev))
return BNX2X_LOOPBACK_FAILED;
bnx2x_netif_stop(bp, 1);
+ bnx2x_acquire_phy_lock(bp);
- if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
- DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
- rc |= BNX2X_MAC_LOOPBACK_FAILED;
+ res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up);
+ if (res) {
+ DP(NETIF_MSG_PROBE, " PHY loopback failed (res %d)\n", res);
+ rc |= BNX2X_PHY_LOOPBACK_FAILED;
}
- if (bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up)) {
- DP(NETIF_MSG_PROBE, "PHY loopback failed\n");
- rc |= BNX2X_PHY_LOOPBACK_FAILED;
+ res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up);
+ if (res) {
+ DP(NETIF_MSG_PROBE, " MAC loopback failed (res %d)\n", res);
+ rc |= BNX2X_MAC_LOOPBACK_FAILED;
}
+ bnx2x_release_phy_lock(bp);
bnx2x_netif_start(bp);
return rc;
@@ -8856,14 +9572,14 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
{ 0x778, 0x70 },
{ 0, 0 }
};
- u32 buf[0x350 / 4];
+ __be32 buf[0x350 / 4];
u8 *data = (u8 *)buf;
int i, rc;
u32 magic, csum;
rc = bnx2x_nvram_read(bp, 0, data, 4);
if (rc) {
- DP(NETIF_MSG_PROBE, "magic value read (rc -%d)\n", -rc);
+ DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc);
goto test_nvram_exit;
}
@@ -8880,7 +9596,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
nvram_tbl[i].size);
if (rc) {
DP(NETIF_MSG_PROBE,
- "nvram_tbl[%d] read data (rc -%d)\n", i, -rc);
+ "nvram_tbl[%d] read data (rc %d)\n", i, rc);
goto test_nvram_exit;
}
@@ -8905,9 +9621,12 @@ static int bnx2x_test_intr(struct bnx2x *bp)
if (!netif_running(bp->dev))
return -ENODEV;
- config->hdr.length_6b = 0;
- config->hdr.offset = 0;
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.length = 0;
+ if (CHIP_IS_E1(bp))
+ config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
+ else
+ config->hdr.offset = BP_FUNC(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -8980,9 +9699,6 @@ static void bnx2x_self_test(struct net_device *dev,
buf[5] = 1;
etest->flags |= ETH_TEST_FL_FAILED;
}
- buf[7] = bnx2x_mc_assert(bp);
- if (buf[7] != 0)
- etest->flags |= ETH_TEST_FL_FAILED;
#ifdef BNX2X_EXTRA_DEBUG
bnx2x_panic_dump(bp);
@@ -8992,40 +9708,98 @@ static void bnx2x_self_test(struct net_device *dev,
static const struct {
long offset;
int size;
+ u8 string[ETH_GSTRING_LEN];
+} bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = {
+/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" },
+ { Q_STATS_OFFSET32(error_bytes_received_hi),
+ 8, "[%d]: rx_error_bytes" },
+ { Q_STATS_OFFSET32(total_unicast_packets_received_hi),
+ 8, "[%d]: rx_ucast_packets" },
+ { Q_STATS_OFFSET32(total_multicast_packets_received_hi),
+ 8, "[%d]: rx_mcast_packets" },
+ { Q_STATS_OFFSET32(total_broadcast_packets_received_hi),
+ 8, "[%d]: rx_bcast_packets" },
+ { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" },
+ { Q_STATS_OFFSET32(rx_err_discard_pkt),
+ 4, "[%d]: rx_phy_ip_err_discards"},
+ { Q_STATS_OFFSET32(rx_skb_alloc_failed),
+ 4, "[%d]: rx_skb_alloc_discard" },
+ { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" },
+
+/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" },
+ { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, "[%d]: tx_packets" }
+};
+
+static const struct {
+ long offset;
+ int size;
u32 flags;
#define STATS_FLAGS_PORT 1
#define STATS_FLAGS_FUNC 2
+#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT)
u8 string[ETH_GSTRING_LEN];
} bnx2x_stats_arr[BNX2X_NUM_STATS] = {
-/* 1 */ { STATS_OFFSET32(valid_bytes_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_bytes" },
+/* 1 */ { STATS_OFFSET32(total_bytes_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_bytes" },
{ STATS_OFFSET32(error_bytes_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_error_bytes" },
- { STATS_OFFSET32(total_bytes_transmitted_hi),
- 8, STATS_FLAGS_FUNC, "tx_bytes" },
- { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
- 8, STATS_FLAGS_PORT, "tx_error_bytes" },
+ 8, STATS_FLAGS_BOTH, "rx_error_bytes" },
{ STATS_OFFSET32(total_unicast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_ucast_packets" },
+ 8, STATS_FLAGS_BOTH, "rx_ucast_packets" },
{ STATS_OFFSET32(total_multicast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_mcast_packets" },
+ 8, STATS_FLAGS_BOTH, "rx_mcast_packets" },
{ STATS_OFFSET32(total_broadcast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_bcast_packets" },
- { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
- 8, STATS_FLAGS_FUNC, "tx_packets" },
- { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
- 8, STATS_FLAGS_PORT, "tx_mac_errors" },
-/* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
- 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
+ 8, STATS_FLAGS_BOTH, "rx_bcast_packets" },
{ STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
8, STATS_FLAGS_PORT, "rx_crc_errors" },
{ STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
8, STATS_FLAGS_PORT, "rx_align_errors" },
+ { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
+ 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
+ { STATS_OFFSET32(etherstatsoverrsizepkts_hi),
+ 8, STATS_FLAGS_PORT, "rx_oversize_packets" },
+/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
+ 8, STATS_FLAGS_PORT, "rx_fragments" },
+ { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
+ 8, STATS_FLAGS_PORT, "rx_jabbers" },
+ { STATS_OFFSET32(no_buff_discard_hi),
+ 8, STATS_FLAGS_BOTH, "rx_discards" },
+ { STATS_OFFSET32(mac_filter_discard),
+ 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
+ { STATS_OFFSET32(xxoverflow_discard),
+ 4, STATS_FLAGS_PORT, "rx_fw_discards" },
+ { STATS_OFFSET32(brb_drop_hi),
+ 8, STATS_FLAGS_PORT, "rx_brb_discard" },
+ { STATS_OFFSET32(brb_truncate_hi),
+ 8, STATS_FLAGS_PORT, "rx_brb_truncate" },
+ { STATS_OFFSET32(pause_frames_received_hi),
+ 8, STATS_FLAGS_PORT, "rx_pause_frames" },
+ { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
+ 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
+ { STATS_OFFSET32(nig_timer_max),
+ 4, STATS_FLAGS_PORT, "rx_constant_pause_events" },
+/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt),
+ 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"},
+ { STATS_OFFSET32(rx_skb_alloc_failed),
+ 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" },
+ { STATS_OFFSET32(hw_csum_err),
+ 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" },
+
+ { STATS_OFFSET32(total_bytes_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_bytes" },
+ { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
+ 8, STATS_FLAGS_PORT, "tx_error_bytes" },
+ { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_packets" },
+ { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
+ 8, STATS_FLAGS_PORT, "tx_mac_errors" },
+ { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
+ 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
8, STATS_FLAGS_PORT, "tx_single_collisions" },
{ STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
8, STATS_FLAGS_PORT, "tx_multi_collisions" },
- { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
+/* 30 */{ STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
8, STATS_FLAGS_PORT, "tx_deferred" },
{ STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
8, STATS_FLAGS_PORT, "tx_excess_collisions" },
@@ -9033,14 +9807,6 @@ static const struct {
8, STATS_FLAGS_PORT, "tx_late_collisions" },
{ STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
8, STATS_FLAGS_PORT, "tx_total_collisions" },
- { STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
- 8, STATS_FLAGS_PORT, "rx_fragments" },
-/* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
- 8, STATS_FLAGS_PORT, "rx_jabbers" },
- { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
- 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
- { STATS_OFFSET32(jabber_packets_received),
- 4, STATS_FLAGS_FUNC, "rx_oversize_packets" },
{ STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
{ STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
@@ -9053,52 +9819,46 @@ static const struct {
8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
{ STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
- { STATS_OFFSET32(etherstatspktsover1522octets_hi),
+/* 40 */{ STATS_OFFSET32(etherstatspktsover1522octets_hi),
8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
-/* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_xon_frames" },
- { STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_xoff_frames" },
- { STATS_OFFSET32(tx_stat_outxonsent_hi),
- 8, STATS_FLAGS_PORT, "tx_xon_frames" },
- { STATS_OFFSET32(tx_stat_outxoffsent_hi),
- 8, STATS_FLAGS_PORT, "tx_xoff_frames" },
- { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
- { STATS_OFFSET32(mac_filter_discard),
- 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
- { STATS_OFFSET32(no_buff_discard),
- 4, STATS_FLAGS_FUNC, "rx_discards" },
- { STATS_OFFSET32(xxoverflow_discard),
- 4, STATS_FLAGS_PORT, "rx_fw_discards" },
- { STATS_OFFSET32(brb_drop_hi),
- 8, STATS_FLAGS_PORT, "brb_discard" },
- { STATS_OFFSET32(brb_truncate_hi),
- 8, STATS_FLAGS_PORT, "brb_truncate" },
-/* 40 */{ STATS_OFFSET32(rx_err_discard_pkt),
- 4, STATS_FLAGS_FUNC, "rx_phy_ip_err_discards"},
- { STATS_OFFSET32(rx_skb_alloc_failed),
- 4, STATS_FLAGS_FUNC, "rx_skb_alloc_discard" },
-/* 42 */{ STATS_OFFSET32(hw_csum_err),
- 4, STATS_FLAGS_FUNC, "rx_csum_offload_errors" }
+ { STATS_OFFSET32(pause_frames_sent_hi),
+ 8, STATS_FLAGS_PORT, "tx_pause_frames" }
};
-#define IS_NOT_E1HMF_STAT(bp, i) \
- (IS_E1HMF(bp) && (bnx2x_stats_arr[i].flags & STATS_FLAGS_PORT))
+#define IS_PORT_STAT(i) \
+ ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT)
+#define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC)
+#define IS_E1HMF_MODE_STAT(bp) \
+ (IS_E1HMF(bp) && !(bp->msglevel & BNX2X_MSG_STATS))
static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{
struct bnx2x *bp = netdev_priv(dev);
- int i, j;
+ int i, j, k;
switch (stringset) {
case ETH_SS_STATS:
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
- strcpy(buf + j*ETH_GSTRING_LEN,
- bnx2x_stats_arr[i].string);
- j++;
+ if (is_multi(bp)) {
+ k = 0;
+ for_each_queue(bp, i) {
+ for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
+ sprintf(buf + (k + j)*ETH_GSTRING_LEN,
+ bnx2x_q_stats_arr[j].string, i);
+ k += BNX2X_NUM_Q_STATS;
+ }
+ if (IS_E1HMF_MODE_STAT(bp))
+ break;
+ for (j = 0; j < BNX2X_NUM_STATS; j++)
+ strcpy(buf + (k + j)*ETH_GSTRING_LEN,
+ bnx2x_stats_arr[j].string);
+ } else {
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ strcpy(buf + j*ETH_GSTRING_LEN,
+ bnx2x_stats_arr[i].string);
+ j++;
+ }
}
break;
@@ -9111,13 +9871,22 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
static int bnx2x_get_stats_count(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
- int i, num_stats = 0;
+ int i, num_stats;
- for (i = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
- num_stats++;
+ if (is_multi(bp)) {
+ num_stats = BNX2X_NUM_Q_STATS * BNX2X_NUM_QUEUES(bp);
+ if (!IS_E1HMF_MODE_STAT(bp))
+ num_stats += BNX2X_NUM_STATS;
+ } else {
+ if (IS_E1HMF_MODE_STAT(bp)) {
+ num_stats = 0;
+ for (i = 0; i < BNX2X_NUM_STATS; i++)
+ if (IS_FUNC_STAT(i))
+ num_stats++;
+ } else
+ num_stats = BNX2X_NUM_STATS;
}
+
return num_stats;
}
@@ -9125,29 +9894,71 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *buf)
{
struct bnx2x *bp = netdev_priv(dev);
- u32 *hw_stats = (u32 *)&bp->eth_stats;
- int i, j;
-
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
+ u32 *hw_stats, *offset;
+ int i, j, k;
- if (bnx2x_stats_arr[i].size == 0) {
- /* skip this counter */
- buf[j] = 0;
- j++;
- continue;
+ if (is_multi(bp)) {
+ k = 0;
+ for_each_queue(bp, i) {
+ hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
+ for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
+ if (bnx2x_q_stats_arr[j].size == 0) {
+ /* skip this counter */
+ buf[k + j] = 0;
+ continue;
+ }
+ offset = (hw_stats +
+ bnx2x_q_stats_arr[j].offset);
+ if (bnx2x_q_stats_arr[j].size == 4) {
+ /* 4-byte counter */
+ buf[k + j] = (u64) *offset;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ }
+ k += BNX2X_NUM_Q_STATS;
}
- if (bnx2x_stats_arr[i].size == 4) {
- /* 4-byte counter */
- buf[j] = (u64) *(hw_stats + bnx2x_stats_arr[i].offset);
+ if (IS_E1HMF_MODE_STAT(bp))
+ return;
+ hw_stats = (u32 *)&bp->eth_stats;
+ for (j = 0; j < BNX2X_NUM_STATS; j++) {
+ if (bnx2x_stats_arr[j].size == 0) {
+ /* skip this counter */
+ buf[k + j] = 0;
+ continue;
+ }
+ offset = (hw_stats + bnx2x_stats_arr[j].offset);
+ if (bnx2x_stats_arr[j].size == 4) {
+ /* 4-byte counter */
+ buf[k + j] = (u64) *offset;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ }
+ } else {
+ hw_stats = (u32 *)&bp->eth_stats;
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ if (bnx2x_stats_arr[i].size == 0) {
+ /* skip this counter */
+ buf[j] = 0;
+ j++;
+ continue;
+ }
+ offset = (hw_stats + bnx2x_stats_arr[i].offset);
+ if (bnx2x_stats_arr[i].size == 4) {
+ /* 4-byte counter */
+ buf[j] = (u64) *offset;
+ j++;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[j] = HILO_U64(*offset, *(offset + 1));
j++;
- continue;
}
- /* 8-byte counter */
- buf[j] = HILO_U64(*(hw_stats + bnx2x_stats_arr[i].offset),
- *(hw_stats + bnx2x_stats_arr[i].offset + 1));
- j++;
}
}
@@ -9194,6 +10005,8 @@ static struct ethtool_ops bnx2x_ethtool_ops = {
.get_settings = bnx2x_get_settings,
.set_settings = bnx2x_set_settings,
.get_drvinfo = bnx2x_get_drvinfo,
+ .get_regs_len = bnx2x_get_regs_len,
+ .get_regs = bnx2x_get_regs,
.get_wol = bnx2x_get_wol,
.set_wol = bnx2x_set_wol,
.get_msglevel = bnx2x_get_msglevel,
@@ -9271,6 +10084,18 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
return 0;
}
+static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
+{
+ u16 rx_cons_sb;
+
+ /* Tell compiler that status block fields can change */
+ barrier();
+ rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+ if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+ rx_cons_sb++;
+ return (fp->rx_comp_cons != rx_cons_sb);
+}
+
/*
* net_device service functions
*/
@@ -9281,7 +10106,6 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
napi);
struct bnx2x *bp = fp->bp;
int work_done = 0;
- u16 rx_cons_sb;
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -9294,33 +10118,42 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
bnx2x_update_fpsb_idx(fp);
- if (BNX2X_HAS_TX_WORK(fp))
- bnx2x_tx_int(fp, budget);
+ if (bnx2x_has_tx_work(fp))
+ bnx2x_tx_int(fp);
- rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
- if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- rx_cons_sb++;
- if (BNX2X_HAS_RX_WORK(fp))
+ if (bnx2x_has_rx_work(fp)) {
work_done = bnx2x_rx_int(fp, budget);
- rmb(); /* BNX2X_HAS_WORK() reads the status block */
- rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
- if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- rx_cons_sb++;
+ /* must not complete if we consumed full budget */
+ if (work_done >= budget)
+ goto poll_again;
+ }
- /* must not complete if we consumed full budget */
- if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
+ /* BNX2X_HAS_WORK() reads the status block, thus we need to
+ * ensure that status block indices have been actually read
+ * (bnx2x_update_fpsb_idx) prior to this check (BNX2X_HAS_WORK)
+ * so that we won't write the "newer" value of the status block to IGU
+ * (if there was a DMA right after BNX2X_HAS_WORK and
+ * if there is no rmb, the memory reading (bnx2x_update_fpsb_idx)
+ * may be postponed to right before bnx2x_ack_sb). In this case
+ * there will never be another interrupt until there is another update
+ * of the status block, while there is still unhandled work.
+ */
+ rmb();
+ if (!BNX2X_HAS_WORK(fp)) {
#ifdef BNX2X_STOP_ON_ERROR
poll_panic:
#endif
- netif_rx_complete(napi);
+ napi_complete(napi);
- bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID,
+ bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, FP_SB_ID(fp), CSTORM_ID,
+ bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
}
+
+poll_again:
return work_done;
}
@@ -9396,7 +10229,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
rc = XMIT_PLAIN;
else {
- if (skb->protocol == ntohs(ETH_P_IPV6)) {
+ if (skb->protocol == htons(ETH_P_IPV6)) {
rc = XMIT_CSUM_V6;
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
rc |= XMIT_CSUM_TCP;
@@ -9417,7 +10250,10 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
return rc;
}
-/* check if packet requires linearization (packet is too fragmented) */
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
+/* check if packet requires linearization (packet is too fragmented)
+ no need to check fragmentation if page size > 8K (there will be no
+ violation to FW restrictions) */
static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
u32 xmit_type)
{
@@ -9476,7 +10312,6 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
wnd_sum -=
skb_shinfo(skb)->frags[wnd_idx].size;
}
-
} else {
/* in non-LSO too fragmented packet should always
be linearized */
@@ -9494,6 +10329,7 @@ exit_lbl:
return to_copy;
}
+#endif
/* called with netif_tx_lock
* bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
@@ -9503,6 +10339,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
struct bnx2x_fastpath *fp;
+ struct netdev_queue *txq;
struct sw_tx_bd *tx_buf;
struct eth_tx_bd *tx_bd;
struct eth_tx_parse_bd *pbd = NULL;
@@ -9519,12 +10356,14 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
#endif
- fp_index = (smp_processor_id() % bp->num_queues);
+ fp_index = skb_get_queue_mapping(skb);
+ txq = netdev_get_tx_queue(dev, fp_index);
+
fp = &bp->fp[fp_index];
if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) {
- bp->eth_stats.driver_xoff++,
- netif_stop_queue(dev);
+ fp->eth_q_stats.driver_xoff++,
+ netif_tx_stop_queue(txq);
BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
return NETDEV_TX_BUSY;
}
@@ -9534,8 +10373,10 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
- /* First, check if we need to linearize the skb
- (due to FW restrictions) */
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
+ /* First, check if we need to linearize the skb (due to FW
+ restrictions). No need to check fragmentation if page size > 8K
+ (there will be no violation to FW restrictions) */
if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
/* Statistics of linearization */
bp->lin_cnt++;
@@ -9546,6 +10387,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
}
+#endif
/*
Please read carefully. First we use one BD which we mark as start,
@@ -9599,9 +10441,9 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
hlen = (skb_network_header(skb) - skb->data + vlan_off) / 2;
/* for now NS flag is not used in Linux */
- pbd->global_data = (hlen |
- ((skb->protocol == ntohs(ETH_P_8021Q)) <<
- ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
+ pbd->global_data =
+ (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
+ ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
pbd->ip_hlen = (skb_transport_header(skb) -
skb_network_header(skb)) / 2;
@@ -9745,12 +10587,10 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
wmb();
- fp->hw_tx_prods->bds_prod =
- cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
+ le16_add_cpu(&fp->hw_tx_prods->bds_prod, nbd);
mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod =
- cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
- DOORBELL(bp, FP_IDX(fp), 0);
+ le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
+ DOORBELL(bp, fp->index, 0);
mmiowb();
@@ -9761,10 +10601,10 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* We want bnx2x_tx_int to "see" the updated tx_bd_prod
if we put Tx into XOFF state. */
smp_mb();
- netif_stop_queue(dev);
- bp->eth_stats.driver_xoff++;
+ netif_tx_stop_queue(txq);
+ fp->eth_q_stats.driver_xoff++;
if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
- netif_wake_queue(dev);
+ netif_tx_wake_queue(txq);
}
fp->tx_pkt++;
@@ -9776,6 +10616,8 @@ static int bnx2x_open(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
+ netif_carrier_off(dev);
+
bnx2x_set_power_state(bp, PCI_D0);
return bnx2x_nic_load(bp, LOAD_OPEN);
@@ -9795,7 +10637,7 @@ static int bnx2x_close(struct net_device *dev)
return 0;
}
-/* called with netif_tx_lock from set_multicast */
+/* called with netif_tx_lock from dev_mcast.c */
static void bnx2x_set_rx_mode(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
@@ -9854,12 +10696,12 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
config->config_table[i].
cam_entry.lsb_mac_addr);
}
- old = config->hdr.length_6b;
+ old = config->hdr.length;
if (old > i) {
for (; i < old; i++) {
if (CAM_IS_INVALID(config->
config_table[i])) {
- i--; /* already invalidated */
+ /* already invalidated */
break;
}
/* invalidate */
@@ -9873,9 +10715,9 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
else
offset = BNX2X_MAX_MULTICAST*(1 + port);
- config->hdr.length_6b = i;
+ config->hdr.length = i;
config->hdr.offset = offset;
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -10061,7 +10903,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_open = bnx2x_open,
.ndo_stop = bnx2x_close,
.ndo_start_xmit = bnx2x_start_xmit,
- .ndo_set_multicast_list = bnx2x_set_rx_mode,
+ .ndo_set_multicast_list = bnx2x_set_rx_mode,
.ndo_set_mac_address = bnx2x_change_mac_addr,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = bnx2x_ioctl,
@@ -10075,7 +10917,6 @@ static const struct net_device_ops bnx2x_netdev_ops = {
#endif
};
-
static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
struct net_device *dev)
{
@@ -10254,7 +11095,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
printk(KERN_INFO "%s", version);
/* dev zeroed in init_etherdev */
- dev = alloc_etherdev(sizeof(*bp));
+ dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT);
if (!dev) {
printk(KERN_ERR PFX "Cannot allocate net device\n");
return -ENOMEM;
@@ -10269,30 +11110,26 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
return rc;
}
- rc = register_netdev(dev);
- if (rc) {
- dev_err(&pdev->dev, "Cannot register net device\n");
- goto init_one_exit;
- }
-
pci_set_drvdata(pdev, dev);
rc = bnx2x_init_bp(bp);
+ if (rc)
+ goto init_one_exit;
+
+ rc = register_netdev(dev);
if (rc) {
- unregister_netdev(dev);
+ dev_err(&pdev->dev, "Cannot register net device\n");
goto init_one_exit;
}
- netif_carrier_off(dev);
-
- bp->common.name = board_info[ent->driver_data].name;
printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
- " IRQ %d, ", dev->name, bp->common.name,
+ " IRQ %d, ", dev->name, board_info[ent->driver_data].name,
(CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
bnx2x_get_pcie_width(bp),
(bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
dev->base_addr, bp->pdev->irq);
printk(KERN_CONT "node addr %pM\n", dev->dev_addr);
+
return 0;
init_one_exit:
@@ -10424,14 +11261,16 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
struct mac_configuration_cmd *config =
bnx2x_sp(bp, mcast_config);
- for (i = 0; i < config->hdr.length_6b; i++)
+ for (i = 0; i < config->hdr.length; i++)
CAM_INVALIDATE(config->config_table[i]);
}
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+ for_each_rx_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
@@ -10557,8 +11396,8 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
static struct pci_error_handlers bnx2x_err_handler = {
.error_detected = bnx2x_io_error_detected,
- .slot_reset = bnx2x_io_slot_reset,
- .resume = bnx2x_io_resume,
+ .slot_reset = bnx2x_io_slot_reset,
+ .resume = bnx2x_io_resume,
};
static struct pci_driver bnx2x_pci_driver = {
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index a67b0c358ae..b8ce6fc927a 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -1,6 +1,6 @@
/* bnx2x_reg.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * 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
@@ -30,8 +30,20 @@
address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address
BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */
#define BRB1_REG_FREE_LIST_PRS_CRDT 0x60200
+/* [RW 10] The number of free blocks above which the High_llfc signal to
+ interface #n is de-asserted. */
+#define BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD_0 0x6014c
+/* [RW 10] The number of free blocks below which the High_llfc signal to
+ interface #n is asserted. */
+#define BRB1_REG_HIGH_LLFC_LOW_THRESHOLD_0 0x6013c
/* [RW 23] LL RAM data. */
#define BRB1_REG_LL_RAM 0x61000
+/* [RW 10] The number of free blocks above which the Low_llfc signal to
+ interface #n is de-asserted. */
+#define BRB1_REG_LOW_LLFC_HIGH_THRESHOLD_0 0x6016c
+/* [RW 10] The number of free blocks below which the Low_llfc signal to
+ interface #n is asserted. */
+#define BRB1_REG_LOW_LLFC_LOW_THRESHOLD_0 0x6015c
/* [R 24] The number of full blocks. */
#define BRB1_REG_NUM_OF_FULL_BLOCKS 0x60090
/* [ST 32] The number of cycles that the write_full signal towards MAC #0
@@ -125,6 +137,10 @@
stands for weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define CCM_REG_CQM_P_WEIGHT 0xd00b8
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_CQM_S_WEIGHT 0xd00bc
/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
if 1 - normal activity. */
@@ -132,6 +148,10 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the SDM interface is detected. */
#define CCM_REG_CSDM_LENGTH_MIS 0xd0170
+/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_CSDM_WEIGHT 0xd00b4
/* [RW 28] The CM header for QM formatting in case of an error in the QM
inputs. */
#define CCM_REG_ERR_CCM_HDR 0xd0094
@@ -211,6 +231,11 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the STORM interface is detected. */
#define CCM_REG_STORM_LENGTH_MIS 0xd016c
+/* [RW 3] The weight of the STORM input in the WRR (Weighted Round robin)
+ mechanism. 0 stands for weight 8 (the most prioritised); 1 stands for
+ weight 1(least prioritised); 2 stands for weight 2 (more prioritised);
+ tc. */
+#define CCM_REG_STORM_WEIGHT 0xd009c
/* [RW 1] Input tsem Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -323,7 +348,11 @@
set one of these bits. the bit description can be found in CFC
specifications */
#define CFC_REG_ERROR_VECTOR 0x10403c
+/* [WB 93] LCID info ram access */
+#define CFC_REG_INFO_RAM 0x105000
+#define CFC_REG_INFO_RAM_SIZE 1024
#define CFC_REG_INIT_REG 0x10404c
+#define CFC_REG_INTERFACES 0x104058
/* [RW 24] {weight_load_client7[2:0] to weight_load_client0[2:0]}. this
field allows changing the priorities of the weighted-round-robin arbiter
which selects which CFC load client should be served next */
@@ -337,8 +366,6 @@
#define CFC_REG_NUM_LCIDS_ALLOC 0x104020
/* [R 9] Number of Arriving LCIDs in Link List Block */
#define CFC_REG_NUM_LCIDS_ARRIVING 0x104004
-/* [R 9] Number of Inside LCIDs in Link List Block */
-#define CFC_REG_NUM_LCIDS_INSIDE 0x104008
/* [R 9] Number of Leaving LCIDs in Link List Block */
#define CFC_REG_NUM_LCIDS_LEAVING 0x104018
/* [RW 8] The event id for aggregated interrupt 0 */
@@ -730,6 +757,7 @@
#define DORQ_REG_SHRT_CMHEAD 0x170054
#define HC_CONFIG_0_REG_ATTN_BIT_EN_0 (0x1<<4)
#define HC_CONFIG_0_REG_INT_LINE_EN_0 (0x1<<3)
+#define HC_CONFIG_0_REG_MSI_ATTN_EN_0 (0x1<<7)
#define HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 (0x1<<2)
#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 (0x1<<1)
#define HC_REG_AGG_INT_0 0x108050
@@ -1410,6 +1438,29 @@
This is the result value of the pin; not the drive value. Writing these
bits will have not effect. */
#define MISC_REG_GPIO 0xa490
+/* [RW 8] These bits enable the GPIO_INTs to signals event to the
+ IGU/MCP.according to the following map: [0] p0_gpio_0; [1] p0_gpio_1; [2]
+ p0_gpio_2; [3] p0_gpio_3; [4] p1_gpio_0; [5] p1_gpio_1; [6] p1_gpio_2;
+ [7] p1_gpio_3; */
+#define MISC_REG_GPIO_EVENT_EN 0xa2bc
+/* [RW 32] GPIO INT. [31-28] OLD_CLR port1; [27-24] OLD_CLR port0; Writing a
+ '1' to these bit clears the corresponding bit in the #OLD_VALUE register.
+ This will acknowledge an interrupt on the falling edge of corresponding
+ GPIO input (reset value 0). [23-16] OLD_SET [23-16] port1; OLD_SET port0;
+ Writing a '1' to these bit sets the corresponding bit in the #OLD_VALUE
+ register. This will acknowledge an interrupt on the rising edge of
+ corresponding SPIO input (reset value 0). [15-12] OLD_VALUE [11-8] port1;
+ OLD_VALUE port0; RO; These bits indicate the old value of the GPIO input
+ value. When the ~INT_STATE bit is set; this bit indicates the OLD value
+ of the pin such that if ~INT_STATE is set and this bit is '0'; then the
+ interrupt is due to a low to high edge. If ~INT_STATE is set and this bit
+ is '1'; then the interrupt is due to a high to low edge (reset value 0).
+ [7-4] INT_STATE port1; [3-0] INT_STATE RO port0; These bits indicate the
+ current GPIO interrupt state for each GPIO pin. This bit is cleared when
+ the appropriate #OLD_SET or #OLD_CLR command bit is written. This bit is
+ set when the GPIO input does not match the current value in #OLD_VALUE
+ (reset value 0). */
+#define MISC_REG_GPIO_INT 0xa494
/* [R 28] this field hold the last information that caused reserved
attention. bits [19:0] - address; [22:20] function; [23] reserved;
[27:24] the master that caused the attention - according to the following
@@ -1554,6 +1605,14 @@
command bit is written. This bit is set when the SPIO input does not
match the current value in #OLD_VALUE (reset value 0). */
#define MISC_REG_SPIO_INT 0xa500
+/* [RW 32] reload value for counter 4 if reload; the value will be reload if
+ the counter reached zero and the reload bit
+ (~misc_registers_sw_timer_cfg_4.sw_timer_cfg_4[1] ) is set */
+#define MISC_REG_SW_TIMER_RELOAD_VAL_4 0xa2fc
+/* [RW 32] the value of the counter for sw timers1-8. there are 8 addresses
+ in this register. addres 0 - timer 1; address - timer 2�address 7 -
+ timer 8 */
+#define MISC_REG_SW_TIMER_VAL 0xa5c0
/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
loaded; 0-prepare; -unprepare */
#define MISC_REG_UNPREPARED 0xa424
@@ -1660,6 +1719,19 @@
/* [RW 4] led mode for port0: 0 MAC; 1-3 PHY1; 4 MAC2; 5-7 PHY4; 8-MAC3;
9-11PHY7; 12 MAC4; 13-15 PHY10; */
#define NIG_REG_LED_MODE_P0 0x102f0
+/* [RW 3] for port0 enable for llfc ppp and pause. b0 - brb1 enable; b1-
+ tsdm enable; b2- usdm enable */
+#define NIG_REG_LLFC_EGRESS_SRC_ENABLE_0 0x16070
+/* [RW 1] SAFC enable for port0. This register may get 1 only when
+ ~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same
+ port */
+#define NIG_REG_LLFC_ENABLE_0 0x16208
+/* [RW 16] classes are high-priority for port0 */
+#define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0 0x16058
+/* [RW 16] classes are low-priority for port0 */
+#define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0 0x16060
+/* [RW 1] Output enable of message to LLFC BMAC IF for port0 */
+#define NIG_REG_LLFC_OUT_EN_0 0x160c8
#define NIG_REG_LLH0_ACPI_PAT_0_CRC 0x1015c
#define NIG_REG_LLH0_ACPI_PAT_6_LEN 0x10154
#define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244
@@ -1730,6 +1802,10 @@
#define NIG_REG_NIG_INT_STS_1 0x103c0
/* [R 32] Parity register #0 read */
#define NIG_REG_NIG_PRTY_STS 0x103d0
+/* [RW 1] Pause enable for port0. This register may get 1 only when
+ ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same
+ port */
+#define NIG_REG_PAUSE_ENABLE_0 0x160c0
/* [RW 1] Input enable for RX PBF LP IF */
#define NIG_REG_PBF_LB_IN_EN 0x100b4
/* [RW 1] Value of this register will be transmitted to port swap when
@@ -1739,6 +1815,10 @@
#define NIG_REG_PRS_EOP_OUT_EN 0x10104
/* [RW 1] Input enable for RX parser request IF */
#define NIG_REG_PRS_REQ_IN_EN 0x100b8
+/* [RW 5] control to serdes - CL45 DEVAD */
+#define NIG_REG_SERDES0_CTRL_MD_DEVAD 0x10370
+/* [RW 1] control to serdes; 0 - clause 45; 1 - clause 22 */
+#define NIG_REG_SERDES0_CTRL_MD_ST 0x1036c
/* [RW 5] control to serdes - CL22 PHY_ADD and CL45 PRTAD */
#define NIG_REG_SERDES0_CTRL_PHY_ADDR 0x10374
/* [R 1] status from serdes0 that inputs to interrupt logic of link status */
@@ -1885,6 +1965,7 @@
#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2 0x400e4
#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3 0x400e8
#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4 0x400ec
+#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5 0x400f0
/* [RW 32] The CM header for flush message where 'load existed' bit in CFC
load response is set and packet type is 0. Used in packet start message
to TCM. */
@@ -1893,6 +1974,7 @@
#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2 0x400c4
#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3 0x400c8
#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4 0x400cc
+#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5 0x400d0
/* [RW 32] The CM header for a match and packet type 1 for loopback port.
Used in packet start message to TCM. */
#define PRS_REG_CM_HDR_LOOPBACK_TYPE_1 0x4009c
@@ -2035,6 +2117,19 @@
#define PXP2_REG_PGL_INT_XSDM_5 0x1204e8
#define PXP2_REG_PGL_INT_XSDM_6 0x1204ec
#define PXP2_REG_PGL_INT_XSDM_7 0x1204f0
+/* [RW 3] this field allows one function to pretend being another function
+ when accessing any BAR mapped resource within the device. the value of
+ the field is the number of the function that will be accessed
+ effectively. after software write to this bit it must read it in order to
+ know that the new value is updated */
+#define PXP2_REG_PGL_PRETEND_FUNC_F0 0x120674
+#define PXP2_REG_PGL_PRETEND_FUNC_F1 0x120678
+#define PXP2_REG_PGL_PRETEND_FUNC_F2 0x12067c
+#define PXP2_REG_PGL_PRETEND_FUNC_F3 0x120680
+#define PXP2_REG_PGL_PRETEND_FUNC_F4 0x120684
+#define PXP2_REG_PGL_PRETEND_FUNC_F5 0x120688
+#define PXP2_REG_PGL_PRETEND_FUNC_F6 0x12068c
+#define PXP2_REG_PGL_PRETEND_FUNC_F7 0x120690
/* [R 1] this bit indicates that a read request was blocked because of
bus_master_en was deasserted */
#define PXP2_REG_PGL_READ_BLOCKED 0x120568
@@ -2498,6 +2593,11 @@
considered zero so practically there are only 20 bits in this register;
queues 63-0 */
#define QM_REG_BASEADDR 0x168900
+/* [RW 32] The base logical address (in bytes) of each physical queue. The
+ index I represents the physical queue number. The 12 lsbs are ignore and
+ considered zero so practically there are only 20 bits in this register;
+ queues 127-64 */
+#define QM_REG_BASEADDR_EXT_A 0x16e100
/* [RW 16] The byte credit cost for each task. This value is for both ports */
#define QM_REG_BYTECRDCOST 0x168234
/* [RW 16] The initial byte credit value for both ports. */
@@ -3438,6 +3538,16 @@
#define SRC_REG_KEYRSS0_0 0x40408
#define SRC_REG_KEYRSS0_7 0x40424
#define SRC_REG_KEYRSS1_9 0x40454
+#define SRC_REG_KEYSEARCH_0 0x40458
+#define SRC_REG_KEYSEARCH_1 0x4045c
+#define SRC_REG_KEYSEARCH_2 0x40460
+#define SRC_REG_KEYSEARCH_3 0x40464
+#define SRC_REG_KEYSEARCH_4 0x40468
+#define SRC_REG_KEYSEARCH_5 0x4046c
+#define SRC_REG_KEYSEARCH_6 0x40470
+#define SRC_REG_KEYSEARCH_7 0x40474
+#define SRC_REG_KEYSEARCH_8 0x40478
+#define SRC_REG_KEYSEARCH_9 0x4047c
#define SRC_REG_LASTFREE0 0x40530
#define SRC_REG_NUMBER_HASH_BITS0 0x40400
/* [RW 1] Reset internal state machines. */
@@ -3481,6 +3591,10 @@
/* [RC 1] Message length mismatch (relative to last indication) at the In#9
interface. */
#define TCM_REG_CSEM_LENGTH_MIS 0x50174
+/* [RW 3] The weight of the input csem in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_CSEM_WEIGHT 0x500bc
/* [RW 8] The Event ID in case of ErrorFlg is set in the input message. */
#define TCM_REG_ERR_EVNT_ID 0x500a0
/* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -3524,6 +3638,7 @@
#define TCM_REG_N_SM_CTX_LD_2 0x50058
#define TCM_REG_N_SM_CTX_LD_3 0x5005c
#define TCM_REG_N_SM_CTX_LD_4 0x50060
+#define TCM_REG_N_SM_CTX_LD_5 0x50064
/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
if 1 - normal activity. */
@@ -3563,6 +3678,10 @@
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
#define TCM_REG_STORM_TCM_IFEN 0x50010
+/* [RW 3] The weight of the STORM input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_STORM_WEIGHT 0x500ac
/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
if 1 - normal activity. */
@@ -3598,10 +3717,22 @@
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
#define TCM_REG_TM_TCM_IFEN 0x5001c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TM_WEIGHT 0x500d0
/* [RW 6] QM output initial credit. Max credit available - 32.Write writes
the initial credit value; read returns the current value of the credit
counter. Must be initialized to 32 at start-up. */
#define TCM_REG_TQM_INIT_CRD 0x5021c
+/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TQM_P_WEIGHT 0x500c8
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TQM_S_WEIGHT 0x500cc
/* [RW 28] The CM header value for QM request (primary). */
#define TCM_REG_TQM_TCM_HDR_P 0x50090
/* [RW 28] The CM header value for QM request (secondary). */
@@ -3628,6 +3759,10 @@
/* [RC 1] Message length mismatch (relative to last indication) at the In#8
interface. */
#define TCM_REG_USEM_LENGTH_MIS 0x50170
+/* [RW 3] The weight of the input usem in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_USEM_WEIGHT 0x500b8
/* [RW 21] Indirect access to the descriptor table of the XX protection
mechanism. The fields are: [5:0] - length of the message; 15:6] - message
pointer; 20:16] - next pointer. */
@@ -3677,6 +3812,7 @@
#define TM_REG_EN_CL1_INPUT 0x16400c
/* [RW 1] Enable client2 input. */
#define TM_REG_EN_CL2_INPUT 0x164010
+#define TM_REG_EN_LINEAR0_TIMER 0x164014
/* [RW 1] Enable real time counter. */
#define TM_REG_EN_REAL_TIME_CNT 0x1640d8
/* [RW 1] Enable for Timers state machines. */
@@ -3684,14 +3820,22 @@
/* [RW 4] Load value for expiration credit cnt. CFC max number of
outstanding load requests for timers (expiration) context loading. */
#define TM_REG_EXP_CRDCNT_VAL 0x164238
+/* [RW 32] Linear0 logic address. */
+#define TM_REG_LIN0_LOGIC_ADDR 0x164240
/* [RW 18] Linear0 Max active cid (in banks of 32 entries). */
#define TM_REG_LIN0_MAX_ACTIVE_CID 0x164048
/* [WB 64] Linear0 phy address. */
#define TM_REG_LIN0_PHY_ADDR 0x164270
+/* [RW 1] Linear0 physical address valid. */
+#define TM_REG_LIN0_PHY_ADDR_VALID 0x164248
/* [RW 24] Linear0 array scan timeout. */
#define TM_REG_LIN0_SCAN_TIME 0x16403c
+/* [RW 32] Linear1 logic address. */
+#define TM_REG_LIN1_LOGIC_ADDR 0x164250
/* [WB 64] Linear1 phy address. */
#define TM_REG_LIN1_PHY_ADDR 0x164280
+/* [RW 1] Linear1 physical address valid. */
+#define TM_REG_LIN1_PHY_ADDR_VALID 0x164258
/* [RW 6] Linear timer set_clear fifo threshold. */
#define TM_REG_LIN_SETCLR_FIFO_ALFULL_THR 0x164070
/* [RW 2] Load value for pci arbiter credit cnt. */
@@ -3708,6 +3852,17 @@
#define TM_REG_TM_INT_STS 0x1640f0
/* [RW 8] The event id for aggregated interrupt 0 */
#define TSDM_REG_AGG_INT_EVENT_0 0x42038
+#define TSDM_REG_AGG_INT_EVENT_1 0x4203c
+#define TSDM_REG_AGG_INT_EVENT_10 0x42060
+#define TSDM_REG_AGG_INT_EVENT_11 0x42064
+#define TSDM_REG_AGG_INT_EVENT_12 0x42068
+#define TSDM_REG_AGG_INT_EVENT_13 0x4206c
+#define TSDM_REG_AGG_INT_EVENT_14 0x42070
+#define TSDM_REG_AGG_INT_EVENT_15 0x42074
+#define TSDM_REG_AGG_INT_EVENT_16 0x42078
+#define TSDM_REG_AGG_INT_EVENT_17 0x4207c
+#define TSDM_REG_AGG_INT_EVENT_18 0x42080
+#define TSDM_REG_AGG_INT_EVENT_19 0x42084
#define TSDM_REG_AGG_INT_EVENT_2 0x42040
#define TSDM_REG_AGG_INT_EVENT_20 0x42088
#define TSDM_REG_AGG_INT_EVENT_21 0x4208c
@@ -3723,6 +3878,19 @@
#define TSDM_REG_AGG_INT_EVENT_30 0x420b0
#define TSDM_REG_AGG_INT_EVENT_31 0x420b4
#define TSDM_REG_AGG_INT_EVENT_4 0x42048
+/* [RW 1] The T bit for aggregated interrupt 0 */
+#define TSDM_REG_AGG_INT_T_0 0x420b8
+#define TSDM_REG_AGG_INT_T_1 0x420bc
+#define TSDM_REG_AGG_INT_T_10 0x420e0
+#define TSDM_REG_AGG_INT_T_11 0x420e4
+#define TSDM_REG_AGG_INT_T_12 0x420e8
+#define TSDM_REG_AGG_INT_T_13 0x420ec
+#define TSDM_REG_AGG_INT_T_14 0x420f0
+#define TSDM_REG_AGG_INT_T_15 0x420f4
+#define TSDM_REG_AGG_INT_T_16 0x420f8
+#define TSDM_REG_AGG_INT_T_17 0x420fc
+#define TSDM_REG_AGG_INT_T_18 0x42100
+#define TSDM_REG_AGG_INT_T_19 0x42104
/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
#define TSDM_REG_CFC_RSP_START_ADDR 0x42008
/* [RW 16] The maximum value of the competion counter #0 */
@@ -3967,6 +4135,10 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the dorq interface is detected. */
#define UCM_REG_DORQ_LENGTH_MIS 0xe0168
+/* [RW 3] The weight of the input dorq in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_DORQ_WEIGHT 0xe00c0
/* [RW 8] The Event ID in case ErrorFlg input message bit is set. */
#define UCM_REG_ERR_EVNT_ID 0xe00a4
/* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -4030,6 +4202,10 @@
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
#define UCM_REG_STORM_UCM_IFEN 0xe0010
+/* [RW 3] The weight of the STORM input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_STORM_WEIGHT 0xe00b0
/* [RW 4] Timers output initial credit. Max credit available - 15.Write
writes the initial credit value; read returns the current value of the
credit counter. Must be initialized to 4 at start-up. */
@@ -4040,6 +4216,10 @@
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
#define UCM_REG_TM_UCM_IFEN 0xe001c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_TM_WEIGHT 0xe00d4
/* [RW 1] Input tsem Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -4092,6 +4272,10 @@
stands for weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define UCM_REG_UQM_P_WEIGHT 0xe00cc
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_UQM_S_WEIGHT 0xe00d0
/* [RW 28] The CM header value for QM request (primary). */
#define UCM_REG_UQM_UCM_HDR_P 0xe0094
/* [RW 28] The CM header value for QM request (secondary). */
@@ -4107,6 +4291,10 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the SDM interface is detected. */
#define UCM_REG_USDM_LENGTH_MIS 0xe0158
+/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_USDM_WEIGHT 0xe00c8
/* [RW 1] Input xsem Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -4114,6 +4302,10 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the xsem interface isdetected. */
#define UCM_REG_XSEM_LENGTH_MIS 0xe0164
+/* [RW 3] The weight of the input xsem in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_XSEM_WEIGHT 0xe00bc
/* [RW 20] Indirect access to the descriptor table of the XX protection
mechanism. The fields are:[5:0] - message length; 14:6] - message
pointer; 19:15] - next pointer. */
@@ -4163,6 +4355,7 @@
#define USDM_REG_AGG_INT_EVENT_30 0xc40b0
#define USDM_REG_AGG_INT_EVENT_31 0xc40b4
#define USDM_REG_AGG_INT_EVENT_4 0xc4048
+#define USDM_REG_AGG_INT_EVENT_5 0xc404c
/* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
or auto-mask-mode (1) */
#define USDM_REG_AGG_INT_MODE_0 0xc41b8
@@ -4177,6 +4370,8 @@
#define USDM_REG_AGG_INT_MODE_17 0xc41fc
#define USDM_REG_AGG_INT_MODE_18 0xc4200
#define USDM_REG_AGG_INT_MODE_19 0xc4204
+#define USDM_REG_AGG_INT_MODE_4 0xc41c8
+#define USDM_REG_AGG_INT_MODE_5 0xc41cc
/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
#define USDM_REG_CFC_RSP_START_ADDR 0xc4008
/* [RW 16] The maximum value of the competion counter #0 */
@@ -4427,6 +4622,10 @@
/* [RC 1] Set at message length mismatch (relative to last indication) at
the dorq interface. */
#define XCM_REG_DORQ_LENGTH_MIS 0x20230
+/* [RW 3] The weight of the input dorq in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_DORQ_WEIGHT 0x200cc
/* [RW 8] The Event ID in case the ErrorFlg input message bit is set. */
#define XCM_REG_ERR_EVNT_ID 0x200b0
/* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -4465,6 +4664,10 @@
/* [RC 1] Set at message length mismatch (relative to last indication) at
the nig0 interface. */
#define XCM_REG_NIG0_LENGTH_MIS 0x20238
+/* [RW 3] The weight of the input nig0 in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_NIG0_WEIGHT 0x200d4
/* [RW 1] Input nig1 Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -4523,6 +4726,10 @@
writes the initial credit value; read returns the current value of the
credit counter. Must be initialized to 4 at start-up. */
#define XCM_REG_TM_INIT_CRD 0x2041c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_TM_WEIGHT 0x200ec
/* [RW 28] The CM header for Timers expiration command. */
#define XCM_REG_TM_XCM_HDR 0x200a8
/* [RW 1] Timers - CM Interface enable. If 0 - the valid input is
@@ -4608,6 +4815,10 @@
stands for weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define XCM_REG_XQM_P_WEIGHT 0x200e4
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_XQM_S_WEIGHT 0x200e8
/* [RW 28] The CM header value for QM request (primary). */
#define XCM_REG_XQM_XCM_HDR_P 0x200a0
/* [RW 28] The CM header value for QM request (secondary). */
@@ -4665,6 +4876,8 @@
#define XSDM_REG_AGG_INT_EVENT_10 0x166060
#define XSDM_REG_AGG_INT_EVENT_11 0x166064
#define XSDM_REG_AGG_INT_EVENT_12 0x166068
+#define XSDM_REG_AGG_INT_EVENT_13 0x16606c
+#define XSDM_REG_AGG_INT_EVENT_14 0x166070
#define XSDM_REG_AGG_INT_EVENT_2 0x166040
#define XSDM_REG_AGG_INT_EVENT_20 0x166088
#define XSDM_REG_AGG_INT_EVENT_21 0x16608c
@@ -4964,9 +5177,11 @@
#define EMAC_RX_MODE_FLOW_EN (1L<<2)
#define EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10)
#define EMAC_RX_MODE_PROMISCUOUS (1L<<8)
+#define EMAC_RX_MODE_RESET (1L<<0)
#define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31)
#define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3)
#define EMAC_TX_MODE_FLOW_EN (1L<<4)
+#define EMAC_TX_MODE_RESET (1L<<0)
#define MISC_REGISTERS_GPIO_0 0
#define MISC_REGISTERS_GPIO_1 1
#define MISC_REGISTERS_GPIO_2 2
@@ -4976,6 +5191,10 @@
#define MISC_REGISTERS_GPIO_FLOAT_POS 24
#define MISC_REGISTERS_GPIO_HIGH 1
#define MISC_REGISTERS_GPIO_INPUT_HI_Z 2
+#define MISC_REGISTERS_GPIO_INT_CLR_POS 24
+#define MISC_REGISTERS_GPIO_INT_OUTPUT_CLR 0
+#define MISC_REGISTERS_GPIO_INT_OUTPUT_SET 1
+#define MISC_REGISTERS_GPIO_INT_SET_POS 16
#define MISC_REGISTERS_GPIO_LOW 0
#define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1
#define MISC_REGISTERS_GPIO_OUTPUT_LOW 0
@@ -5015,11 +5234,12 @@
#define MISC_REGISTERS_SPIO_OUTPUT_LOW 0
#define MISC_REGISTERS_SPIO_SET_POS 8
#define HW_LOCK_MAX_RESOURCE_VALUE 31
-#define HW_LOCK_RESOURCE_8072_MDIO 0
#define HW_LOCK_RESOURCE_GPIO 1
+#define HW_LOCK_RESOURCE_MDIO 0
#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
#define HW_LOCK_RESOURCE_SPIO 2
#define HW_LOCK_RESOURCE_UNDI 5
+#define PRS_FLAG_OVERETH_IPV4 1
#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18)
#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31)
#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9)
@@ -5034,6 +5254,8 @@
#define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11)
#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13)
#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12)
+#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (1<<5)
+#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (1<<9)
#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12)
#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (1<<15)
#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (1<<14)
@@ -5188,7 +5410,7 @@
#define PCICFG_COMMAND_INT_DISABLE (1<<10)
#define PCICFG_COMMAND_RESERVED (0x1f<<11)
#define PCICFG_STATUS_OFFSET 0x06
-#define PCICFG_REVESION_ID 0x08
+#define PCICFG_REVESION_ID_OFFSET 0x08
#define PCICFG_CACHE_LINE_SIZE 0x0c
#define PCICFG_LATENCY_TIMER 0x0d
#define PCICFG_BAR_1_LOW 0x10
@@ -5216,9 +5438,28 @@
#define PCICFG_PM_CSR_STATE (0x3<<0)
#define PCICFG_PM_CSR_PME_ENABLE (1<<8)
#define PCICFG_PM_CSR_PME_STATUS (1<<15)
+#define PCICFG_MSI_CAP_ID_OFFSET 0x58
+#define PCICFG_MSI_CONTROL_ENABLE (0x1<<16)
+#define PCICFG_MSI_CONTROL_MCAP (0x7<<17)
+#define PCICFG_MSI_CONTROL_MENA (0x7<<20)
+#define PCICFG_MSI_CONTROL_64_BIT_ADDR_CAP (0x1<<23)
+#define PCICFG_MSI_CONTROL_MSI_PVMASK_CAPABLE (0x1<<24)
#define PCICFG_GRC_ADDRESS 0x78
#define PCICFG_GRC_DATA 0x80
+#define PCICFG_MSIX_CAP_ID_OFFSET 0xa0
+#define PCICFG_MSIX_CONTROL_TABLE_SIZE (0x7ff<<16)
+#define PCICFG_MSIX_CONTROL_RESERVED (0x7<<27)
+#define PCICFG_MSIX_CONTROL_FUNC_MASK (0x1<<30)
+#define PCICFG_MSIX_CONTROL_MSIX_ENABLE (0x1<<31)
+
#define PCICFG_DEVICE_CONTROL 0xb4
+#define PCICFG_DEVICE_STATUS 0xb6
+#define PCICFG_DEVICE_STATUS_CORR_ERR_DET (1<<0)
+#define PCICFG_DEVICE_STATUS_NON_FATAL_ERR_DET (1<<1)
+#define PCICFG_DEVICE_STATUS_FATAL_ERR_DET (1<<2)
+#define PCICFG_DEVICE_STATUS_UNSUP_REQ_DET (1<<3)
+#define PCICFG_DEVICE_STATUS_AUX_PWR_DET (1<<4)
+#define PCICFG_DEVICE_STATUS_NO_PEND (1<<5)
#define PCICFG_LINK_CONTROL 0xbc
@@ -5363,6 +5604,42 @@
#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1
#define MDIO_TX0_TX_DRIVER_ICBUF1T 1
+#define MDIO_REG_BANK_TX1 0x8070
+#define MDIO_TX1_TX_DRIVER 0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK 0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT 12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT 8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK 0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT 4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK 0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T 1
+
+#define MDIO_REG_BANK_TX2 0x8080
+#define MDIO_TX2_TX_DRIVER 0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK 0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT 12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT 8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK 0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT 4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK 0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T 1
+
+#define MDIO_REG_BANK_TX3 0x8090
+#define MDIO_TX3_TX_DRIVER 0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK 0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT 12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT 8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK 0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT 4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK 0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T 1
+
#define MDIO_REG_BANK_XGXS_BLOCK0 0x8000
#define MDIO_BLOCK0_XGXS_CONTROL 0x10
@@ -5566,9 +5843,30 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_PMA_REG_ROM_VER2 0xca1a
#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b
#define MDIO_PMA_REG_PLL_BANDWIDTH 0xca1d
+#define MDIO_PMA_REG_GEN_CTRL2 0xca1e
+#define MDIO_PMA_REG_MISC_CTRL0 0xca23
+#define MDIO_PMA_REG_LRM_MODE 0xca3f
#define MDIO_PMA_REG_CDR_BANDWIDTH 0xca46
#define MDIO_PMA_REG_MISC_CTRL1 0xca85
+#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL 0x8000
+#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK 0x000c
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE 0x0000
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE 0x0004
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IN_PROGRESS 0x0008
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_FAILED 0x000c
+#define MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT 0x8002
+#define MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR 0x8003
+#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF 0xc820
+#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
+#define MDIO_PMA_REG_8726_TX_CTRL1 0xca01
+#define MDIO_PMA_REG_8726_TX_CTRL2 0xca05
+
+
+#define MDIO_PMA_REG_8073_CHIP_REV 0xc801
+#define MDIO_PMA_REG_8073_SPEED_LINK_STATUS 0xc820
+#define MDIO_PMA_REG_8073_XAUI_WA 0xc841
+
#define MDIO_PMA_REG_7101_RESET 0xc000
#define MDIO_PMA_REG_7107_LED_CNTL 0xc007
#define MDIO_PMA_REG_7101_VER1 0xc026
@@ -5598,6 +5896,12 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_XS_PLL_SEQUENCER 0x8000
#define MDIO_XS_SFX7101_XGXS_TEST1 0xc00a
+#define MDIO_XS_8706_REG_BANK_RX0 0x80bc
+#define MDIO_XS_8706_REG_BANK_RX1 0x80cc
+#define MDIO_XS_8706_REG_BANK_RX2 0x80dc
+#define MDIO_XS_8706_REG_BANK_RX3 0x80ec
+#define MDIO_XS_8706_REG_BANK_RXA 0x80fc
+
#define MDIO_AN_DEVAD 0x7
/*ieee*/
#define MDIO_AN_REG_CTRL 0x0000
@@ -5619,6 +5923,8 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_AN_REG_CL37_FC_LD 0xffe4
#define MDIO_AN_REG_CL37_FC_LP 0xffe5
+#define MDIO_AN_REG_8073_2_5G 0x8329
+
#define IGU_FUNC_BASE 0x0400
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 8a83eb283c2..a306230381c 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -29,7 +29,7 @@
// General definitions
#define BOND_ETH_P_LACPDU 0x8809
-#define PKT_TYPE_LACPDU __constant_htons(BOND_ETH_P_LACPDU)
+#define PKT_TYPE_LACPDU cpu_to_be16(BOND_ETH_P_LACPDU)
#define AD_TIMER_INTERVAL 100 /*msec*/
#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 27fb7f5c21c..8dc6fbb9a41 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -822,7 +822,7 @@ static int rlb_initialize(struct bonding *bond)
_unlock_rx_hashtbl(bond);
/*initialize packet type*/
- pk_type->type = __constant_htons(ETH_P_ARP);
+ pk_type->type = cpu_to_be16(ETH_P_ARP);
pk_type->dev = NULL;
pk_type->func = rlb_arp_recv;
@@ -892,7 +892,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
memset(&pkt, 0, size);
memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
- pkt.type = __constant_htons(ETH_P_LOOP);
+ pkt.type = cpu_to_be16(ETH_P_LOOP);
for (i = 0; i < MAX_LP_BURST; i++) {
struct sk_buff *skb;
@@ -1628,6 +1628,10 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
* no other locks may be held.
*/
void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
+ __releases(&bond->curr_slave_lock)
+ __releases(&bond->lock)
+ __acquires(&bond->lock)
+ __acquires(&bond->curr_slave_lock)
{
struct slave *swap_slave;
int i;
@@ -1704,6 +1708,10 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
* Called with RTNL
*/
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
+ __releases(&bond->curr_slave_lock)
+ __releases(&bond->lock)
+ __acquires(&bond->lock)
+ __acquires(&bond->curr_slave_lock)
{
struct bonding *bond = netdev_priv(bond_dev);
struct sockaddr *sa = addr;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 9fb388388fb..9c326a50a3e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1002,6 +1002,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
static void bond_do_fail_over_mac(struct bonding *bond,
struct slave *new_active,
struct slave *old_active)
+ __releases(&bond->curr_slave_lock)
+ __releases(&bond->lock)
+ __acquires(&bond->lock)
+ __acquires(&bond->curr_slave_lock)
{
u8 tmp_mac[ETH_ALEN];
struct sockaddr saddr;
@@ -1710,6 +1714,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
case BOND_MODE_ALB:
new_slave->state = BOND_STATE_ACTIVE;
bond_set_slave_inactive_flags(new_slave);
+ bond_select_active_slave(bond);
break;
default:
pr_debug("This slave is always active in trunk mode\n");
@@ -3193,6 +3198,8 @@ out:
#ifdef CONFIG_PROC_FS
static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(&dev_base_lock)
+ __acquires(&bond->lock)
{
struct bonding *bond = seq->private;
loff_t off = 0;
@@ -3232,6 +3239,8 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void bond_info_seq_stop(struct seq_file *seq, void *v)
+ __releases(&bond->lock)
+ __releases(&dev_base_lock)
{
struct bonding *bond = seq->private;
@@ -3369,7 +3378,7 @@ static int bond_info_seq_show(struct seq_file *seq, void *v)
return 0;
}
-static struct seq_operations bond_info_seq_ops = {
+static const struct seq_operations bond_info_seq_ops = {
.start = bond_info_seq_start,
.next = bond_info_seq_next,
.stop = bond_info_seq_stop,
@@ -3537,11 +3546,26 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
}
break;
case NETDEV_CHANGE:
- /*
- * TODO: is this what we get if somebody
- * sets up a hierarchical bond, then rmmod's
- * one of the slave bonding devices?
- */
+ if (bond->params.mode == BOND_MODE_8023AD || bond_is_lb(bond)) {
+ struct slave *slave;
+
+ slave = bond_get_slave_by_dev(bond, slave_dev);
+ if (slave) {
+ u16 old_speed = slave->speed;
+ u16 old_duplex = slave->duplex;
+
+ bond_update_speed_duplex(slave);
+
+ if (bond_is_lb(bond))
+ break;
+
+ if (old_speed != slave->speed)
+ bond_3ad_adapter_speed_changed(slave);
+ if (old_duplex != slave->duplex)
+ bond_3ad_adapter_duplex_changed(slave);
+ }
+ }
+
break;
case NETDEV_DOWN:
/*
@@ -4113,7 +4137,7 @@ static int bond_neigh_setup(struct net_device *dev, struct neigh_parms *parms)
const struct net_device_ops *slave_ops
= slave->dev->netdev_ops;
if (slave_ops->ndo_neigh_setup)
- return slave_ops->ndo_neigh_setup(dev, parms);
+ return slave_ops->ndo_neigh_setup(slave->dev, parms);
}
return 0;
}
@@ -4724,7 +4748,7 @@ static void bond_free_all(void)
*/
int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
{
- int mode = -1, i, rv;
+ int modeint = -1, i, rv;
char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
for (p = (char *)buf; *p; p++)
@@ -4734,13 +4758,13 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
if (*p)
rv = sscanf(buf, "%20s", modestr);
else
- rv = sscanf(buf, "%d", &mode);
+ rv = sscanf(buf, "%d", &modeint);
if (!rv)
return -1;
for (i = 0; tbl[i].modename; i++) {
- if (mode == tbl[i].mode)
+ if (modeint == tbl[i].mode)
return tbl[i].mode;
if (strcmp(modestr, tbl[i].modename) == 0)
return tbl[i].mode;
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 840b3d1a22f..0effefa1b88 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -806,7 +806,7 @@ static int cas_reset_mii_phy(struct cas *cp)
cas_phy_write(cp, MII_BMCR, BMCR_RESET);
udelay(100);
- while (limit--) {
+ while (--limit) {
val = cas_phy_read(cp, MII_BMCR);
if ((val & BMCR_RESET) == 0)
break;
@@ -979,7 +979,7 @@ static void cas_phy_init(struct cas *cp)
writel(val, cp->regs + REG_PCS_MII_CTRL);
limit = STOP_TRIES;
- while (limit-- > 0) {
+ while (--limit > 0) {
udelay(10);
if ((readl(cp->regs + REG_PCS_MII_CTRL) &
PCS_MII_RESET) == 0)
@@ -2506,7 +2506,7 @@ static irqreturn_t cas_interruptN(int irq, void *dev_id)
if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
#ifdef USE_NAPI
cas_mask_intr(cp);
- netif_rx_schedule(&cp->napi);
+ napi_schedule(&cp->napi);
#else
cas_rx_ringN(cp, ring, 0);
#endif
@@ -2557,7 +2557,7 @@ static irqreturn_t cas_interrupt1(int irq, void *dev_id)
if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
#ifdef USE_NAPI
cas_mask_intr(cp);
- netif_rx_schedule(&cp->napi);
+ napi_schedule(&cp->napi);
#else
cas_rx_ringN(cp, 1, 0);
#endif
@@ -2613,7 +2613,7 @@ static irqreturn_t cas_interrupt(int irq, void *dev_id)
if (status & INTR_RX_DONE) {
#ifdef USE_NAPI
cas_mask_intr(cp);
- netif_rx_schedule(&cp->napi);
+ napi_schedule(&cp->napi);
#else
cas_rx_ringN(cp, 0, 0);
#endif
@@ -2691,7 +2691,7 @@ rx_comp:
#endif
spin_unlock_irqrestore(&cp->lock, flags);
if (enable_intr) {
- netif_rx_complete(napi);
+ napi_complete(napi);
cas_unmask_intr(cp);
}
return credits;
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index d984b799576..58f6fc055f6 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1612,7 +1612,7 @@ int t1_poll(struct napi_struct *napi, int budget)
int work_done = process_responses(adapter, budget);
if (likely(work_done < budget)) {
- netif_rx_complete(napi);
+ napi_complete(napi);
writel(adapter->sge->respQ.cidx,
adapter->regs + A_SG_SLEEPING);
}
@@ -1630,7 +1630,7 @@ irqreturn_t t1_interrupt(int irq, void *data)
if (napi_schedule_prep(&adapter->napi)) {
if (process_pure_responses(adapter))
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
else {
/* no data, no NAPI needed */
writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
@@ -1967,8 +1967,7 @@ void t1_sge_stop(struct sge *sge)
tx_sched_stop(sge);
for (i = 0; i < MAX_NPORTS; i++)
- if (sge->espibug_skb[i])
- kfree_skb(sge->espibug_skb[i]);
+ kfree_skb(sge->espibug_skb[i]);
}
/*
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index f66548751c3..3f476c7c073 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -428,7 +428,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
printk(KERN_WARNING "%s: rx: polling, but no queue\n",
priv->dev->name);
spin_unlock(&priv->rx_lock);
- netif_rx_complete(napi);
+ napi_complete(napi);
return 0;
}
@@ -514,7 +514,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
if (processed == 0) {
/* we ran out of packets to read,
* revert to interrupt-driven mode */
- netif_rx_complete(napi);
+ napi_complete(napi);
cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
return 0;
}
@@ -536,7 +536,7 @@ fatal_error:
}
spin_unlock(&priv->rx_lock);
- netif_rx_complete(napi);
+ napi_complete(napi);
netif_tx_stop_all_queues(priv->dev);
napi_disable(&priv->napi);
@@ -802,9 +802,9 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
if (status & MAC_INT_RX) {
queue = (status >> 8) & 7;
- if (netif_rx_schedule_prep(&priv->napi)) {
+ if (napi_schedule_prep(&priv->napi)) {
cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
- __netif_rx_schedule(&priv->napi);
+ __napi_schedule(&priv->napi);
}
}
@@ -1161,7 +1161,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
- priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id,
+ priv->phy = phy_connect(dev, dev_name(&cpmac_mii->phy_map[phy_id]->dev),
&cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phy)) {
if (netif_msg_drv(priv))
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index a89d8cc5120..71eaa431371 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -42,7 +42,6 @@
#include <linux/cache.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
-#include <linux/inet_lro.h>
#include "t3cdev.h"
#include <asm/io.h>
@@ -69,6 +68,8 @@ struct port_info {
struct net_device_stats netstats;
int activity;
__be32 iscsi_ipv4addr;
+
+ int link_fault; /* link fault was detected */
};
enum { /* adapter flags */
@@ -92,6 +93,7 @@ struct rx_sw_desc;
struct sge_fl { /* SGE per free-buffer list state */
unsigned int buf_size; /* size of each Rx buffer */
unsigned int credits; /* # of available Rx buffers */
+ unsigned int pend_cred; /* new buffers since last FL DB ring */
unsigned int size; /* capacity of free list */
unsigned int cidx; /* consumer index */
unsigned int pidx; /* producer index */
@@ -178,15 +180,11 @@ enum { /* per port SGE statistics */
SGE_PSTAT_TX_CSUM, /* # of TX checksum offloads */
SGE_PSTAT_VLANEX, /* # of VLAN tag extractions */
SGE_PSTAT_VLANINS, /* # of VLAN tag insertions */
- SGE_PSTAT_LRO_AGGR, /* # of page chunks added to LRO sessions */
- SGE_PSTAT_LRO_FLUSHED, /* # of flushed LRO sessions */
- SGE_PSTAT_LRO_NO_DESC, /* # of overflown LRO sessions */
SGE_PSTAT_MAX /* must be last */
};
-#define T3_MAX_LRO_SES 8
-#define T3_MAX_LRO_MAX_PKTS 64
+struct napi_gro_fraginfo;
struct sge_qset { /* an SGE queue set */
struct adapter *adap;
@@ -194,17 +192,14 @@ 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 net_lro_mgr lro_mgr;
- struct net_lro_desc lro_desc[T3_MAX_LRO_SES];
- struct skb_frag_struct *lro_frag_tbl;
- int lro_nfrags;
+ struct napi_gro_fraginfo lro_frag_tbl;
int lro_enabled;
- int lro_frag_len;
void *lro_va;
struct net_device *netdev;
struct netdev_queue *tx_q; /* associated netdev TX queue */
unsigned long txq_stopped; /* which Tx queues are stopped */
struct timer_list tx_reclaim_timer; /* reclaims TX buffers */
+ struct timer_list rx_reclaim_timer; /* reclaims RX buffers */
unsigned long port_stats[SGE_PSTAT_MAX];
} ____cacheline_aligned;
@@ -230,6 +225,7 @@ struct adapter {
unsigned int slow_intr_mask;
unsigned long irq_stats[IRQ_NUM_STATS];
+ int msix_nvectors;
struct {
unsigned short vec;
char desc[22];
@@ -247,6 +243,7 @@ struct adapter {
struct delayed_work adap_check_task;
struct work_struct ext_intr_handler_task;
struct work_struct fatal_error_handler_task;
+ struct work_struct link_fault_handler_task;
struct dentry *debugfs_root;
@@ -289,6 +286,8 @@ void t3_os_ext_intr_handler(struct adapter *adapter);
void t3_os_link_changed(struct adapter *adapter, int port_id, int link_status,
int speed, int duplex, int fc);
void t3_os_phymod_changed(struct adapter *adap, int port_id);
+void t3_os_link_fault(struct adapter *adapter, int port_id, int state);
+void t3_os_link_fault_handler(struct adapter *adapter, int port_id);
void t3_sge_start(struct adapter *adap);
void t3_sge_stop(struct adapter *adap);
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 5c3c05da4d9..e1b22490ff5 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -1005,7 +1005,8 @@ static int ael2005_reset(struct cphy *phy, int wait)
{ 0, 0, 0, 0 }
};
- int err, lasi_ctrl;
+ int err;
+ unsigned int lasi_ctrl;
err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
if (err)
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index db4f4f575b6..9ee021e750c 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -280,6 +280,7 @@ struct mac_stats {
unsigned long num_toggled; /* # times toggled TxEn due to stuck TX */
unsigned long num_resets; /* # times reset due to stuck TX */
+ unsigned long link_faults; /* # detected link faults */
};
struct tp_mib_stats {
@@ -701,6 +702,8 @@ int t3_phy_lasi_intr_handler(struct cphy *phy);
void t3_intr_enable(struct adapter *adapter);
void t3_intr_disable(struct adapter *adapter);
void t3_intr_clear(struct adapter *adapter);
+void t3_xgm_intr_enable(struct adapter *adapter, int idx);
+void t3_xgm_intr_disable(struct adapter *adapter, int idx);
void t3_port_intr_enable(struct adapter *adapter, int idx);
void t3_port_intr_disable(struct adapter *adapter, int idx);
void t3_port_intr_clear(struct adapter *adapter, int idx);
@@ -708,6 +711,7 @@ int t3_slow_intr_handler(struct adapter *adapter);
int t3_phy_intr_handler(struct adapter *adapter);
void t3_link_changed(struct adapter *adapter, int port_id);
+void t3_link_fault(struct adapter *adapter, int port_id);
int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data);
@@ -744,6 +748,8 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n,
int t3_mac_reset(struct cmac *mac);
void t3b_pcs_reset(struct cmac *mac);
+void t3_mac_disable_exact_filters(struct cmac *mac);
+void t3_mac_enable_exact_filters(struct cmac *mac);
int t3_mac_enable(struct cmac *mac, int which);
int t3_mac_disable(struct cmac *mac, int which);
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 0089746b8d0..d8be89621bf 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -90,6 +90,7 @@ static const struct pci_device_id cxgb3_pci_tbl[] = {
CH_DEVICE(0x30, 2), /* T3B10 */
CH_DEVICE(0x31, 3), /* T3B20 */
CH_DEVICE(0x32, 1), /* T3B02 */
+ CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */
{0,}
};
@@ -169,6 +170,40 @@ static void link_report(struct net_device *dev)
}
}
+void t3_os_link_fault(struct adapter *adap, int port_id, int state)
+{
+ struct net_device *dev = adap->port[port_id];
+ struct port_info *pi = netdev_priv(dev);
+
+ if (state == netif_carrier_ok(dev))
+ return;
+
+ if (state) {
+ struct cmac *mac = &pi->mac;
+
+ netif_carrier_on(dev);
+
+ /* Clear local faults */
+ t3_xgm_intr_disable(adap, pi->port_id);
+ t3_read_reg(adap, A_XGM_INT_STATUS +
+ pi->mac.offset);
+ t3_write_reg(adap,
+ A_XGM_INT_CAUSE + pi->mac.offset,
+ F_XGM_INT);
+
+ t3_set_reg_field(adap,
+ A_XGM_INT_ENABLE +
+ pi->mac.offset,
+ F_XGM_INT, F_XGM_INT);
+ t3_xgm_intr_enable(adap, pi->port_id);
+
+ t3_mac_enable(mac, MAC_DIRECTION_TX);
+ } else
+ netif_carrier_off(dev);
+
+ link_report(dev);
+}
+
/**
* t3_os_link_changed - handle link status changes
* @adapter: the adapter associated with the link change
@@ -196,10 +231,34 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat,
if (link_stat != netif_carrier_ok(dev)) {
if (link_stat) {
t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+ /* Clear local faults */
+ t3_xgm_intr_disable(adapter, pi->port_id);
+ t3_read_reg(adapter, A_XGM_INT_STATUS +
+ pi->mac.offset);
+ t3_write_reg(adapter,
+ A_XGM_INT_CAUSE + pi->mac.offset,
+ F_XGM_INT);
+
+ t3_set_reg_field(adapter,
+ A_XGM_INT_ENABLE + pi->mac.offset,
+ F_XGM_INT, F_XGM_INT);
+ t3_xgm_intr_enable(adapter, pi->port_id);
+
netif_carrier_on(dev);
} else {
netif_carrier_off(dev);
- pi->phy.ops->power_down(&pi->phy, 1);
+
+ t3_xgm_intr_disable(adapter, pi->port_id);
+ t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
+ t3_set_reg_field(adapter,
+ A_XGM_INT_ENABLE + pi->mac.offset,
+ F_XGM_INT, 0);
+
+ if (is_10G(adapter))
+ pi->phy.ops->power_down(&pi->phy, 1);
+
+ t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
t3_mac_disable(mac, MAC_DIRECTION_RX);
t3_link_start(&pi->phy, mac, &pi->link_config);
}
@@ -338,7 +397,7 @@ static void free_irq_resources(struct adapter *adapter)
free_irq(adapter->msix_info[0].vec, adapter);
for_each_port(adapter, i)
- n += adap2pinfo(adapter, i)->nqsets;
+ n += adap2pinfo(adapter, i)->nqsets;
for (i = 0; i < n; ++i)
free_irq(adapter->msix_info[i + 1].vec,
@@ -508,19 +567,9 @@ static void set_qset_lro(struct net_device *dev, int qset_idx, int val)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
- int i, lro_on = 1;
adapter->params.sge.qset[qset_idx].lro = !!val;
adapter->sge.qs[qset_idx].lro_enabled = !!val;
-
- /* let ethtool report LRO on only if all queues are LRO enabled */
- for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; ++i)
- lro_on &= adapter->params.sge.qset[i].lro;
-
- if (lro_on)
- dev->features |= NETIF_F_LRO;
- else
- dev->features &= ~NETIF_F_LRO;
}
/**
@@ -1182,6 +1231,10 @@ static int cxgb_close(struct net_device *dev)
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
+ /* Stop link fault interrupts */
+ t3_xgm_intr_disable(adapter, pi->port_id);
+ t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
+
t3_port_intr_disable(adapter, pi->port_id);
netif_tx_stop_all_queues(dev);
pi->phy.ops->power_down(&pi->phy, 1);
@@ -1308,6 +1361,7 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"CheckTXEnToggled ",
"CheckResets ",
+ "LinkFaults ",
};
static int get_sset_count(struct net_device *dev, int sset)
@@ -1433,13 +1487,15 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
- *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_AGGR);
- *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_FLUSHED);
- *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_NO_DESC);
+ *data++ = 0;
+ *data++ = 0;
+ *data++ = 0;
*data++ = s->rx_cong_drops;
*data++ = s->num_toggled;
*data++ = s->num_resets;
+
+ *data++ = s->link_faults;
}
static inline void reg_block_dump(struct adapter *ap, void *buf,
@@ -1575,7 +1631,6 @@ static int speed_duplex_to_caps(int speed, int duplex)
static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- int cap;
struct port_info *p = netdev_priv(dev);
struct link_config *lc = &p->link_config;
@@ -1585,7 +1640,7 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
* being requested.
*/
if (cmd->autoneg == AUTONEG_DISABLE) {
- cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+ int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
if (lc->supported & cap)
return 0;
}
@@ -1826,28 +1881,6 @@ static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
memset(&wol->sopass, 0, sizeof(wol->sopass));
}
-static int cxgb3_set_flags(struct net_device *dev, u32 data)
-{
- struct port_info *pi = netdev_priv(dev);
- int i;
-
- if (data & ETH_FLAG_LRO) {
- if (!(pi->rx_offload & T3_RX_CSUM))
- return -EINVAL;
-
- pi->rx_offload |= T3_LRO;
- for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
- set_qset_lro(dev, i, 1);
-
- } else {
- pi->rx_offload &= ~T3_LRO;
- for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
- set_qset_lro(dev, i, 0);
- }
-
- return 0;
-}
-
static const struct ethtool_ops cxgb_ethtool_ops = {
.get_settings = get_settings,
.set_settings = set_settings,
@@ -1877,8 +1910,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
.get_regs = get_regs,
.get_wol = get_wol,
.set_tso = ethtool_op_set_tso,
- .get_flags = ethtool_op_get_flags,
- .set_flags = cxgb3_set_flags,
};
static int in_range(int val, int lo, int hi)
@@ -2459,8 +2490,20 @@ static void check_link_status(struct adapter *adapter)
struct net_device *dev = adapter->port[i];
struct port_info *p = netdev_priv(dev);
- if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev))
+ spin_lock_irq(&adapter->work_lock);
+ if (p->link_fault) {
+ spin_unlock_irq(&adapter->work_lock);
+ continue;
+ }
+ spin_unlock_irq(&adapter->work_lock);
+
+ if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) {
+ t3_xgm_intr_disable(adapter, i);
+ t3_read_reg(adapter, A_XGM_INT_STATUS + p->mac.offset);
+
t3_link_changed(adapter, i);
+ t3_xgm_intr_enable(adapter, i);
+ }
}
}
@@ -2505,6 +2548,8 @@ static void t3_adap_check_task(struct work_struct *work)
struct adapter *adapter = container_of(work, struct adapter,
adap_check_task.work);
const struct adapter_params *p = &adapter->params;
+ int port;
+ unsigned int v, status, reset;
adapter->check_task_cnt++;
@@ -2523,6 +2568,54 @@ static void t3_adap_check_task(struct work_struct *work)
if (p->rev == T3_REV_B2)
check_t3b2_mac(adapter);
+ /*
+ * Scan the XGMAC's to check for various conditions which we want to
+ * monitor in a periodic polling manner rather than via an interrupt
+ * condition. This is used for conditions which would otherwise flood
+ * the system with interrupts and we only really need to know that the
+ * conditions are "happening" ... For each condition we count the
+ * detection of the condition and reset it for the next polling loop.
+ */
+ for_each_port(adapter, port) {
+ struct cmac *mac = &adap2pinfo(adapter, port)->mac;
+ u32 cause;
+
+ cause = t3_read_reg(adapter, A_XGM_INT_CAUSE + mac->offset);
+ reset = 0;
+ if (cause & F_RXFIFO_OVERFLOW) {
+ mac->stats.rx_fifo_ovfl++;
+ reset |= F_RXFIFO_OVERFLOW;
+ }
+
+ t3_write_reg(adapter, A_XGM_INT_CAUSE + mac->offset, reset);
+ }
+
+ /*
+ * We do the same as above for FL_EMPTY interrupts.
+ */
+ status = t3_read_reg(adapter, A_SG_INT_CAUSE);
+ reset = 0;
+
+ if (status & F_FLEMPTY) {
+ struct sge_qset *qs = &adapter->sge.qs[0];
+ int i = 0;
+
+ reset |= F_FLEMPTY;
+
+ v = (t3_read_reg(adapter, A_SG_RSPQ_FL_STATUS) >> S_FL0EMPTY) &
+ 0xffff;
+
+ while (v) {
+ qs->fl[i].empty += (v & 1);
+ if (i)
+ qs++;
+ i ^= 1;
+ v >>= 1;
+ }
+ }
+
+ t3_write_reg(adapter, A_SG_INT_CAUSE, reset);
+
/* Schedule the next check update if any port is active. */
spin_lock_irq(&adapter->work_lock);
if (adapter->open_device_map & PORT_MASK)
@@ -2537,9 +2630,23 @@ static void ext_intr_task(struct work_struct *work)
{
struct adapter *adapter = container_of(work, struct adapter,
ext_intr_handler_task);
+ int i;
+ /* Disable link fault interrupts */
+ for_each_port(adapter, i) {
+ struct net_device *dev = adapter->port[i];
+ struct port_info *p = netdev_priv(dev);
+
+ t3_xgm_intr_disable(adapter, i);
+ t3_read_reg(adapter, A_XGM_INT_STATUS + p->mac.offset);
+ }
+
+ /* Re-enable link fault interrupts */
t3_phy_intr_handler(adapter);
+ for_each_port(adapter, i)
+ t3_xgm_intr_enable(adapter, i);
+
/* Now reenable external interrupts */
spin_lock_irq(&adapter->work_lock);
if (adapter->slow_intr_mask) {
@@ -2572,10 +2679,42 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
spin_unlock(&adapter->work_lock);
}
+static void link_fault_task(struct work_struct *work)
+{
+ struct adapter *adapter = container_of(work, struct adapter,
+ link_fault_handler_task);
+ int i;
+
+ for_each_port(adapter, i) {
+ struct net_device *netdev = adapter->port[i];
+ struct port_info *pi = netdev_priv(netdev);
+
+ if (pi->link_fault)
+ t3_link_fault(adapter, i);
+ }
+}
+
+void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
+{
+ struct net_device *netdev = adapter->port[port_id];
+ struct port_info *pi = netdev_priv(netdev);
+
+ spin_lock(&adapter->work_lock);
+ pi->link_fault = 1;
+ queue_work(cxgb3_wq, &adapter->link_fault_handler_task);
+ spin_unlock(&adapter->work_lock);
+}
+
static int t3_adapter_error(struct adapter *adapter, int reset)
{
int i, ret = 0;
+ if (is_offload(adapter) &&
+ test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) {
+ cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_DOWN, 0);
+ offload_close(&adapter->tdev);
+ }
+
/* Stop all ports */
for_each_port(adapter, i) {
struct net_device *netdev = adapter->port[i];
@@ -2584,10 +2723,6 @@ static int t3_adapter_error(struct adapter *adapter, int reset)
cxgb_close(netdev);
}
- if (is_offload(adapter) &&
- test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
- offload_close(&adapter->tdev);
-
/* Stop SGE timers */
t3_stop_sge_timers(adapter);
@@ -2639,6 +2774,9 @@ static void t3_resume_ports(struct adapter *adapter)
}
}
}
+
+ if (is_offload(adapter) && !ofld_disable)
+ cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_UP, 0);
}
/*
@@ -2683,7 +2821,6 @@ void t3_fatal_err(struct adapter *adapter)
CH_ALERT(adapter, "FW status: 0x%x, 0x%x, 0x%x, 0x%x\n",
fw_status[0], fw_status[1],
fw_status[2], fw_status[3]);
-
}
/**
@@ -2752,7 +2889,7 @@ static void set_nqsets(struct adapter *adap)
int i, j = 0;
int num_cpus = num_online_cpus();
int hwports = adap->params.nports;
- int nqsets = SGE_QSETS;
+ int nqsets = adap->msix_nvectors - 1;
if (adap->params.rev > 0 && adap->flags & USING_MSIX) {
if (hwports == 2 &&
@@ -2781,18 +2918,25 @@ static void set_nqsets(struct adapter *adap)
static int __devinit cxgb_enable_msix(struct adapter *adap)
{
struct msix_entry entries[SGE_QSETS + 1];
+ int vectors;
int i, err;
- for (i = 0; i < ARRAY_SIZE(entries); ++i)
+ vectors = ARRAY_SIZE(entries);
+ for (i = 0; i < vectors; ++i)
entries[i].entry = i;
- err = pci_enable_msix(adap->pdev, entries, ARRAY_SIZE(entries));
+ while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0)
+ vectors = err;
+
+ if (!err && vectors < (adap->params.nports + 1))
+ err = -1;
+
if (!err) {
- for (i = 0; i < ARRAY_SIZE(entries); ++i)
+ for (i = 0; i < vectors; ++i)
adap->msix_info[i].vec = entries[i].vector;
- } else if (err > 0)
- dev_info(&adap->pdev->dev,
- "only %d MSI-X vectors left, not using MSI-X\n", err);
+ adap->msix_nvectors = vectors;
+ }
+
return err;
}
@@ -2934,6 +3078,7 @@ static int __devinit init_one(struct pci_dev *pdev,
INIT_LIST_HEAD(&adapter->adapter_list);
INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
+ INIT_WORK(&adapter->link_fault_handler_task, link_fault_task);
INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
@@ -2960,7 +3105,7 @@ static int __devinit init_one(struct pci_dev *pdev,
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_LRO;
+ netdev->features |= NETIF_F_GRO;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 2d7f69aff1d..620d80be6aa 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -153,6 +153,18 @@ void cxgb3_remove_clients(struct t3cdev *tdev)
mutex_unlock(&cxgb3_db_lock);
}
+void cxgb3_err_notify(struct t3cdev *tdev, u32 status, u32 error)
+{
+ struct cxgb3_client *client;
+
+ mutex_lock(&cxgb3_db_lock);
+ list_for_each_entry(client, &client_list, client_list) {
+ if (client->err_handler)
+ client->err_handler(tdev, status, error);
+ }
+ mutex_unlock(&cxgb3_db_lock);
+}
+
static struct net_device *get_iff_from_mac(struct adapter *adapter,
const unsigned char *mac,
unsigned int vlan)
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h
index d514e5019df..a8e8e5fcdf8 100644
--- a/drivers/net/cxgb3/cxgb3_offload.h
+++ b/drivers/net/cxgb3/cxgb3_offload.h
@@ -64,10 +64,16 @@ void cxgb3_register_client(struct cxgb3_client *client);
void cxgb3_unregister_client(struct cxgb3_client *client);
void cxgb3_add_clients(struct t3cdev *tdev);
void cxgb3_remove_clients(struct t3cdev *tdev);
+void cxgb3_err_notify(struct t3cdev *tdev, u32 status, u32 error);
typedef int (*cxgb3_cpl_handler_func)(struct t3cdev *dev,
struct sk_buff *skb, void *ctx);
+enum {
+ OFFLOAD_STATUS_UP,
+ OFFLOAD_STATUS_DOWN
+};
+
struct cxgb3_client {
char *name;
void (*add) (struct t3cdev *);
@@ -76,6 +82,7 @@ struct cxgb3_client {
int (*redirect)(void *ctx, struct dst_entry *old,
struct dst_entry *new, struct l2t_entry *l2t);
struct list_head client_list;
+ void (*err_handler)(struct t3cdev *tdev, u32 status, u32 error);
};
/*
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index a035d5c2444..1b5327b5a96 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -170,6 +170,10 @@
#define S_RSPQ0DISABLED 8
+#define S_FL0EMPTY 16
+#define V_FL0EMPTY(x) ((x) << S_FL0EMPTY)
+#define F_FL0EMPTY V_FL0EMPTY(1U)
+
#define A_SG_EGR_RCQ_DRB_THRSH 0x54
#define S_HIRCQDRBTHRSH 16
@@ -258,6 +262,10 @@
#define V_RSPQCREDITOVERFOW(x) ((x) << S_RSPQCREDITOVERFOW)
#define F_RSPQCREDITOVERFOW V_RSPQCREDITOVERFOW(1U)
+#define S_FLEMPTY 1
+#define V_FLEMPTY(x) ((x) << S_FLEMPTY)
+#define F_FLEMPTY V_FLEMPTY(1U)
+
#define A_SG_INT_ENABLE 0x60
#define A_SG_CMDQ_CREDIT_TH 0x64
@@ -2207,6 +2215,15 @@
#define A_XGM_RX_EXACT_MATCH_LOW_8 0x854
+#define A_XGM_INT_STATUS 0x86c
+
+#define S_LINKFAULTCHANGE 9
+#define V_LINKFAULTCHANGE(x) ((x) << S_LINKFAULTCHANGE)
+#define F_LINKFAULTCHANGE V_LINKFAULTCHANGE(1U)
+
+#define A_XGM_XGM_INT_ENABLE 0x874
+#define A_XGM_XGM_INT_DISABLE 0x878
+
#define A_XGM_STAT_CTRL 0x880
#define S_CLRSTATS 2
@@ -2405,6 +2422,10 @@
#define V_XAUIPCSALIGNCHANGE(x) ((x) << S_XAUIPCSALIGNCHANGE)
#define F_XAUIPCSALIGNCHANGE V_XAUIPCSALIGNCHANGE(1U)
+#define S_XGM_INT 0
+#define V_XGM_INT(x) ((x) << S_XGM_INT)
+#define F_XGM_INT V_XGM_INT(1U)
+
#define A_XGM_INT_CAUSE 0x8d8
#define A_XGM_XAUI_ACT_CTRL 0x8dc
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 14f9fb3e879..a7555cb3fa4 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -61,12 +61,19 @@
#define FL1_PG_ORDER (PAGE_SIZE > 8192 ? 0 : 1)
#define SGE_RX_DROP_THRES 16
+#define RX_RECLAIM_PERIOD (HZ/4)
/*
+ * Max number of Rx buffers we replenish at a time.
+ */
+#define MAX_RX_REFILL 16U
+/*
* Period of the Tx buffer reclaim timer. This timer does not need to run
* frequently as Tx buffers are usually reclaimed by new Tx packets.
*/
#define TX_RECLAIM_PERIOD (HZ / 4)
+#define TX_RECLAIM_TIMER_CHUNK 64U
+#define TX_RECLAIM_CHUNK 16U
/* WR size in bytes */
#define WR_LEN (WR_FLITS * 8)
@@ -304,21 +311,25 @@ static void free_tx_desc(struct adapter *adapter, struct sge_txq *q,
* reclaim_completed_tx - reclaims completed Tx descriptors
* @adapter: the adapter
* @q: the Tx queue to reclaim completed descriptors from
+ * @chunk: maximum number of descriptors to reclaim
*
* Reclaims Tx descriptors that the SGE has indicated it has processed,
* and frees the associated buffers if possible. Called with the Tx
* queue's lock held.
*/
-static inline void reclaim_completed_tx(struct adapter *adapter,
- struct sge_txq *q)
+static inline unsigned int reclaim_completed_tx(struct adapter *adapter,
+ struct sge_txq *q,
+ unsigned int chunk)
{
unsigned int reclaim = q->processed - q->cleaned;
+ reclaim = min(chunk, reclaim);
if (reclaim) {
free_tx_desc(adapter, q, reclaim);
q->cleaned += reclaim;
q->in_use -= reclaim;
}
+ return q->processed - q->cleaned;
}
/**
@@ -334,6 +345,18 @@ static inline int should_restart_tx(const struct sge_txq *q)
return q->in_use - r < (q->size >> 1);
}
+static void clear_rx_desc(const struct sge_fl *q, struct rx_sw_desc *d)
+{
+ if (q->use_pages) {
+ if (d->pg_chunk.page)
+ put_page(d->pg_chunk.page);
+ d->pg_chunk.page = NULL;
+ } else {
+ kfree_skb(d->skb);
+ d->skb = NULL;
+ }
+}
+
/**
* free_rx_bufs - free the Rx buffers on an SGE free list
* @pdev: the PCI device associated with the adapter
@@ -351,14 +374,7 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
q->buf_size, PCI_DMA_FROMDEVICE);
- if (q->use_pages) {
- if (d->pg_chunk.page)
- put_page(d->pg_chunk.page);
- d->pg_chunk.page = NULL;
- } else {
- kfree_skb(d->skb);
- d->skb = NULL;
- }
+ clear_rx_desc(q, d);
if (++cidx == q->size)
cidx = 0;
}
@@ -423,6 +439,14 @@ static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp,
return 0;
}
+static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
+{
+ if (q->pend_cred >= q->credits / 4) {
+ q->pend_cred = 0;
+ t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+ }
+}
+
/**
* refill_fl - refill an SGE free-buffer list
* @adapter: the adapter
@@ -463,10 +487,7 @@ nomem: q->alloc_failed++;
err = add_one_rx_buf(buf_start, q->buf_size, d, sd, q->gen,
adap->pdev);
if (unlikely(err)) {
- if (!q->use_pages) {
- kfree_skb(sd->skb);
- sd->skb = NULL;
- }
+ clear_rx_desc(q, sd);
break;
}
@@ -478,19 +499,19 @@ nomem: q->alloc_failed++;
sd = q->sdesc;
d = q->desc;
}
- q->credits++;
count++;
}
- wmb();
- if (likely(count))
- t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+
+ q->credits += count;
+ q->pend_cred += count;
+ ring_fl_db(adap, q);
return count;
}
static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
{
- refill_fl(adap, fl, min(16U, fl->size - fl->credits),
+ refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits),
GFP_ATOMIC | __GFP_COMP);
}
@@ -515,13 +536,15 @@ static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q,
wmb();
to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen));
to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen));
- q->credits++;
if (++q->pidx == q->size) {
q->pidx = 0;
q->gen ^= 1;
}
- t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+
+ q->credits++;
+ q->pend_cred++;
+ ring_fl_db(adap, q);
}
/**
@@ -585,8 +608,8 @@ static void t3_reset_qset(struct sge_qset *q)
memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
q->txq_stopped = 0;
q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
- kfree(q->lro_frag_tbl);
- q->lro_nfrags = q->lro_frag_len = 0;
+ q->rx_reclaim_timer.function = NULL;
+ q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
}
@@ -733,7 +756,9 @@ recycle:
return skb;
}
- if (unlikely(fl->credits < drop_thres))
+ if (unlikely(fl->credits < drop_thres) &&
+ refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits - 1),
+ GFP_ATOMIC | __GFP_COMP) == 0)
goto recycle;
use_orig_buf:
@@ -813,14 +838,15 @@ recycle:
len - SGE_RX_PULL_LEN);
newskb->len = len;
newskb->data_len = len - SGE_RX_PULL_LEN;
+ newskb->truesize += newskb->data_len;
} else {
skb_fill_page_desc(newskb, skb_shinfo(newskb)->nr_frags,
sd->pg_chunk.page,
sd->pg_chunk.offset, len);
newskb->len += len;
newskb->data_len += len;
+ newskb->truesize += len;
}
- newskb->truesize += newskb->data_len;
fl->credits--;
/*
@@ -1161,7 +1187,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
txq = netdev_get_tx_queue(dev, qidx);
spin_lock(&q->lock);
- reclaim_completed_tx(adap, q);
+ reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
credits = q->size - q->in_use;
ndesc = calc_tx_descs(skb);
@@ -1570,7 +1596,7 @@ static int ofld_xmit(struct adapter *adap, struct sge_txq *q,
unsigned int ndesc = calc_tx_descs_ofld(skb), pidx, gen;
spin_lock(&q->lock);
- again:reclaim_completed_tx(adap, q);
+again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
ret = check_desc_avail(adap, q, skb, ndesc, TXQ_OFLD);
if (unlikely(ret)) {
@@ -1612,7 +1638,7 @@ static void restart_offloadq(unsigned long data)
struct adapter *adap = pi->adapter;
spin_lock(&q->lock);
- again:reclaim_completed_tx(adap, q);
+again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
while ((skb = skb_peek(&q->sendq)) != NULL) {
unsigned int gen, pidx;
@@ -1938,6 +1964,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
skb->ip_summed = CHECKSUM_NONE;
+ skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
if (unlikely(p->vlan_valid)) {
struct vlan_group *grp = pi->vlan_grp;
@@ -1945,10 +1972,8 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
qs->port_stats[SGE_PSTAT_VLANEX]++;
if (likely(grp))
if (lro)
- lro_vlan_hwaccel_receive_skb(&qs->lro_mgr, skb,
- grp,
- ntohs(p->vlan),
- p);
+ vlan_gro_receive(&qs->napi, grp,
+ ntohs(p->vlan), skb);
else {
if (unlikely(pi->iscsi_ipv4addr &&
is_arp(skb))) {
@@ -1965,7 +1990,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
dev_kfree_skb_any(skb);
} else if (rq->polling) {
if (lro)
- lro_receive_skb(&qs->lro_mgr, skb, p);
+ napi_gro_receive(&qs->napi, skb);
else {
if (unlikely(pi->iscsi_ipv4addr && is_arp(skb)))
cxgb3_arp_process(adap, skb);
@@ -1981,59 +2006,6 @@ static inline int is_eth_tcp(u32 rss)
}
/**
- * lro_frame_ok - check if an ingress packet is eligible for LRO
- * @p: the CPL header of the packet
- *
- * Returns true if a received packet is eligible for LRO.
- * The following conditions must be true:
- * - packet is TCP/IP Ethernet II (checked elsewhere)
- * - not an IP fragment
- * - no IP options
- * - TCP/IP checksums are correct
- * - the packet is for this host
- */
-static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
-{
- const struct ethhdr *eh = (struct ethhdr *)(p + 1);
- const struct iphdr *ih = (struct iphdr *)(eh + 1);
-
- return (*((u8 *)p + 1) & 0x90) == 0x10 && p->csum == htons(0xffff) &&
- eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
-}
-
-static int t3_get_lro_header(void **eh, void **iph, void **tcph,
- u64 *hdr_flags, void *priv)
-{
- const struct cpl_rx_pkt *cpl = priv;
-
- if (!lro_frame_ok(cpl))
- return -1;
-
- *eh = (struct ethhdr *)(cpl + 1);
- *iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
- *tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
-
- *hdr_flags = LRO_IPV4 | LRO_TCP;
- return 0;
-}
-
-static int t3_get_skb_header(struct sk_buff *skb,
- void **iph, void **tcph, u64 *hdr_flags,
- void *priv)
-{
- void *eh;
-
- return t3_get_lro_header(&eh, iph, tcph, hdr_flags, priv);
-}
-
-static int t3_get_frag_header(struct skb_frag_struct *frag, void **eh,
- void **iph, void **tcph, u64 *hdr_flags,
- void *priv)
-{
- return t3_get_lro_header(eh, iph, tcph, hdr_flags, priv);
-}
-
-/**
* lro_add_page - add a page chunk to an LRO session
* @adap: the adapter
* @qs: the associated queue set
@@ -2049,8 +2021,9 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
{
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
struct cpl_rx_pkt *cpl;
- struct skb_frag_struct *rx_frag = qs->lro_frag_tbl;
- int nr_frags = qs->lro_nfrags, frag_len = qs->lro_frag_len;
+ 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;
int offset = 0;
if (!nr_frags) {
@@ -2064,18 +2037,20 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
fl->buf_size, PCI_DMA_FROMDEVICE);
+ prefetch(&qs->lro_frag_tbl);
+
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_nfrags++;
- qs->lro_frag_len = frag_len;
+ qs->lro_frag_tbl.nr_frags++;
+ qs->lro_frag_tbl.len = frag_len;
if (!complete)
return;
- qs->lro_nfrags = qs->lro_frag_len = 0;
+ qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
cpl = qs->lro_va;
if (unlikely(cpl->vlan_valid)) {
@@ -2084,35 +2059,15 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
struct vlan_group *grp = pi->vlan_grp;
if (likely(grp != NULL)) {
- lro_vlan_hwaccel_receive_frags(&qs->lro_mgr,
- qs->lro_frag_tbl,
- frag_len, frag_len,
- grp, ntohs(cpl->vlan),
- cpl, 0);
- return;
+ vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
+ &qs->lro_frag_tbl);
+ goto out;
}
}
- lro_receive_frags(&qs->lro_mgr, qs->lro_frag_tbl,
- frag_len, frag_len, cpl, 0);
-}
+ napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
-/**
- * init_lro_mgr - initialize a LRO manager object
- * @lro_mgr: the LRO manager object
- */
-static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr)
-{
- lro_mgr->dev = qs->netdev;
- lro_mgr->features = LRO_F_NAPI;
- lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
- lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
- lro_mgr->max_desc = T3_MAX_LRO_SES;
- lro_mgr->lro_arr = qs->lro_desc;
- lro_mgr->get_frag_header = t3_get_frag_header;
- lro_mgr->get_skb_header = t3_get_skb_header;
- lro_mgr->max_aggr = T3_MAX_LRO_MAX_PKTS;
- if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
- lro_mgr->max_aggr = MAX_SKB_FRAGS;
+out:
+ qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
}
/**
@@ -2275,8 +2230,7 @@ no_mem:
} else if ((len = ntohl(r->len_cq)) != 0) {
struct sge_fl *fl;
- if (eth)
- lro = qs->lro_enabled && is_eth_tcp(rss_hi);
+ lro &= eth && is_eth_tcp(rss_hi);
fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
if (fl->use_pages) {
@@ -2356,10 +2310,6 @@ next_fl:
}
deliver_partial_bundle(&adap->tdev, q, offload_skbs, ngathered);
- lro_flush_all(&qs->lro_mgr);
- qs->port_stats[SGE_PSTAT_LRO_AGGR] = qs->lro_mgr.stats.aggregated;
- qs->port_stats[SGE_PSTAT_LRO_FLUSHED] = qs->lro_mgr.stats.flushed;
- qs->port_stats[SGE_PSTAT_LRO_NO_DESC] = qs->lro_mgr.stats.no_desc;
if (sleeping)
check_ring_db(adap, qs, sleeping);
@@ -2775,7 +2725,8 @@ irq_handler_t t3_intr_handler(struct adapter *adap, int polling)
*/
void t3_sge_err_intr_handler(struct adapter *adapter)
{
- unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE);
+ unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE) &
+ ~F_FLEMPTY;
if (status & SGE_PARERR)
CH_ALERT(adapter, "SGE parity error (0x%x)\n",
@@ -2805,13 +2756,13 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
}
/**
- * sge_timer_cb - perform periodic maintenance of an SGE qset
+ * sge_timer_tx - perform periodic maintenance of an SGE qset
* @data: the SGE queue set to maintain
*
* Runs periodically from a timer to perform maintenance of an SGE queue
* set. It performs two tasks:
*
- * a) Cleans up any completed Tx descriptors that may still be pending.
+ * Cleans up any completed Tx descriptors that may still be pending.
* Normal descriptor cleanup happens when new packets are added to a Tx
* queue so this timer is relatively infrequent and does any cleanup only
* if the Tx queue has not seen any new packets in a while. We make a
@@ -2821,51 +2772,87 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
* up). Since control queues use immediate data exclusively we don't
* bother cleaning them up here.
*
- * b) Replenishes Rx queues that have run out due to memory shortage.
- * Normally new Rx buffers are added when existing ones are consumed but
- * when out of memory a queue can become empty. We try to add only a few
- * buffers here, the queue will be replenished fully as these new buffers
- * are used up if memory shortage has subsided.
*/
-static void sge_timer_cb(unsigned long data)
+static void sge_timer_tx(unsigned long data)
{
- spinlock_t *lock;
struct sge_qset *qs = (struct sge_qset *)data;
- struct adapter *adap = qs->adap;
+ struct port_info *pi = netdev_priv(qs->netdev);
+ struct adapter *adap = pi->adapter;
+ unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0};
+ unsigned long next_period;
if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
- reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]);
+ tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
+ TX_RECLAIM_TIMER_CHUNK);
spin_unlock(&qs->txq[TXQ_ETH].lock);
}
if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) {
- reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD]);
+ tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD],
+ TX_RECLAIM_TIMER_CHUNK);
spin_unlock(&qs->txq[TXQ_OFLD].lock);
}
- lock = (adap->flags & USING_MSIX) ? &qs->rspq.lock :
- &adap->sge.qs[0].rspq.lock;
- if (spin_trylock_irq(lock)) {
- if (!napi_is_scheduled(&qs->napi)) {
- u32 status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);
-
- if (qs->fl[0].credits < qs->fl[0].size)
- __refill_fl(adap, &qs->fl[0]);
- if (qs->fl[1].credits < qs->fl[1].size)
- __refill_fl(adap, &qs->fl[1]);
-
- if (status & (1 << qs->rspq.cntxt_id)) {
- qs->rspq.starved++;
- if (qs->rspq.credits) {
- refill_rspq(adap, &qs->rspq, 1);
- qs->rspq.credits--;
- qs->rspq.restarted++;
- t3_write_reg(adap, A_SG_RSPQ_FL_STATUS,
- 1 << qs->rspq.cntxt_id);
- }
+
+ next_period = TX_RECLAIM_PERIOD >>
+ (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
+ TX_RECLAIM_TIMER_CHUNK);
+ mod_timer(&qs->tx_reclaim_timer, jiffies + next_period);
+}
+
+/*
+ * sge_timer_rx - perform periodic maintenance of an SGE qset
+ * @data: the SGE queue set to maintain
+ *
+ * a) Replenishes Rx queues that have run out due to memory shortage.
+ * Normally new Rx buffers are added when existing ones are consumed but
+ * when out of memory a queue can become empty. We try to add only a few
+ * buffers here, the queue will be replenished fully as these new buffers
+ * are used up if memory shortage has subsided.
+ *
+ * b) Return coalesced response queue credits in case a response queue is
+ * starved.
+ *
+ */
+static void sge_timer_rx(unsigned long data)
+{
+ spinlock_t *lock;
+ struct sge_qset *qs = (struct sge_qset *)data;
+ struct port_info *pi = netdev_priv(qs->netdev);
+ struct adapter *adap = pi->adapter;
+ u32 status;
+
+ lock = adap->params.rev > 0 ?
+ &qs->rspq.lock : &adap->sge.qs[0].rspq.lock;
+
+ if (!spin_trylock_irq(lock))
+ goto out;
+
+ if (napi_is_scheduled(&qs->napi))
+ goto unlock;
+
+ if (adap->params.rev < 4) {
+ status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);
+
+ if (status & (1 << qs->rspq.cntxt_id)) {
+ qs->rspq.starved++;
+ if (qs->rspq.credits) {
+ qs->rspq.credits--;
+ refill_rspq(adap, &qs->rspq, 1);
+ qs->rspq.restarted++;
+ t3_write_reg(adap, A_SG_RSPQ_FL_STATUS,
+ 1 << qs->rspq.cntxt_id);
}
}
- spin_unlock_irq(lock);
}
- mod_timer(&qs->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
+
+ if (qs->fl[0].credits < qs->fl[0].size)
+ __refill_fl(adap, &qs->fl[0]);
+ if (qs->fl[1].credits < qs->fl[1].size)
+ __refill_fl(adap, &qs->fl[1]);
+
+unlock:
+ spin_unlock_irq(lock);
+out:
+ mod_timer(&qs->rx_reclaim_timer, jiffies + RX_RECLAIM_PERIOD);
}
/**
@@ -2906,10 +2893,10 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
{
int i, avail, ret = -ENOMEM;
struct sge_qset *q = &adapter->sge.qs[id];
- struct net_lro_mgr *lro_mgr = &q->lro_mgr;
init_qset_cntxt(q, id);
- setup_timer(&q->tx_reclaim_timer, sge_timer_cb, (unsigned long)q);
+ setup_timer(&q->tx_reclaim_timer, sge_timer_tx, (unsigned long)q);
+ setup_timer(&q->rx_reclaim_timer, sge_timer_rx, (unsigned long)q);
q->fl[0].desc = alloc_ring(adapter->pdev, p->fl_size,
sizeof(struct rx_desc),
@@ -2986,10 +2973,6 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
q->fl[0].order = FL0_PG_ORDER;
q->fl[1].order = FL1_PG_ORDER;
- q->lro_frag_tbl = kcalloc(MAX_FRAME_SIZE / FL1_PG_CHUNK_SIZE + 1,
- sizeof(struct skb_frag_struct),
- GFP_KERNEL);
- q->lro_nfrags = q->lro_frag_len = 0;
spin_lock_irq(&adapter->sge.reg_lock);
/* FL threshold comparison uses < */
@@ -3041,8 +3024,6 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
q->tx_q = netdevq;
t3_update_qset_coalesce(q, p);
- init_lro_mgr(q, lro_mgr);
-
avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
GFP_KERNEL | __GFP_COMP);
if (!avail) {
@@ -3064,6 +3045,8 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
V_NEWTIMER(q->rspq.holdoff_tmr));
mod_timer(&q->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
+ mod_timer(&q->rx_reclaim_timer, jiffies + RX_RECLAIM_PERIOD);
+
return 0;
err_unlock:
@@ -3088,6 +3071,8 @@ void t3_stop_sge_timers(struct adapter *adap)
if (q->tx_reclaim_timer.function)
del_timer_sync(&q->tx_reclaim_timer);
+ if (q->rx_reclaim_timer.function)
+ del_timer_sync(&q->rx_reclaim_timer);
}
}
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 2d1433077a8..ff262a04ded 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -512,6 +512,13 @@ static const struct adapter_info t3_adap_info[] = {
F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
{ S_GPIO9, S_GPIO3 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T320"},
+ {},
+ {},
+ {1, 0,
+ F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO6_OEN | F_GPIO7_OEN |
+ 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" },
};
/*
@@ -1146,6 +1153,38 @@ int t3_cim_ctl_blk_read(struct adapter *adap, unsigned int addr,
return ret;
}
+static void t3_gate_rx_traffic(struct cmac *mac, u32 *rx_cfg,
+ u32 *rx_hash_high, u32 *rx_hash_low)
+{
+ /* stop Rx unicast traffic */
+ t3_mac_disable_exact_filters(mac);
+
+ /* stop broadcast, multicast, promiscuous mode traffic */
+ *rx_cfg = t3_read_reg(mac->adapter, A_XGM_RX_CFG);
+ t3_set_reg_field(mac->adapter, A_XGM_RX_CFG,
+ F_ENHASHMCAST | F_DISBCAST | F_COPYALLFRAMES,
+ F_DISBCAST);
+
+ *rx_hash_high = t3_read_reg(mac->adapter, A_XGM_RX_HASH_HIGH);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_HIGH, 0);
+
+ *rx_hash_low = t3_read_reg(mac->adapter, A_XGM_RX_HASH_LOW);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, 0);
+
+ /* Leave time to drain max RX fifo */
+ msleep(1);
+}
+
+static void t3_open_rx_traffic(struct cmac *mac, u32 rx_cfg,
+ u32 rx_hash_high, u32 rx_hash_low)
+{
+ t3_mac_enable_exact_filters(mac);
+ t3_set_reg_field(mac->adapter, A_XGM_RX_CFG,
+ F_ENHASHMCAST | F_DISBCAST | F_COPYALLFRAMES,
+ rx_cfg);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_HIGH, rx_hash_high);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, rx_hash_low);
+}
/**
* t3_link_changed - handle interface link changes
@@ -1163,9 +1202,32 @@ void t3_link_changed(struct adapter *adapter, int port_id)
struct cphy *phy = &pi->phy;
struct cmac *mac = &pi->mac;
struct link_config *lc = &pi->link_config;
+ int force_link_down = 0;
phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
+ if (!lc->link_ok && link_ok) {
+ u32 rx_cfg, rx_hash_high, rx_hash_low;
+ u32 status;
+
+ t3_xgm_intr_enable(adapter, port_id);
+ t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
+ t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
+ t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+ status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
+ if (status & F_LINKFAULTCHANGE) {
+ mac->stats.link_faults++;
+ force_link_down = 1;
+ }
+ t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+
+ if (force_link_down) {
+ t3_os_link_fault_handler(adapter, port_id);
+ return;
+ }
+ }
+
if (lc->requested_fc & PAUSE_AUTONEG)
fc &= lc->requested_fc;
else
@@ -1195,6 +1257,57 @@ void t3_link_changed(struct adapter *adapter, int port_id)
t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
}
+void t3_link_fault(struct adapter *adapter, int port_id)
+{
+ struct port_info *pi = adap2pinfo(adapter, port_id);
+ struct cmac *mac = &pi->mac;
+ struct cphy *phy = &pi->phy;
+ struct link_config *lc = &pi->link_config;
+ int link_ok, speed, duplex, fc, link_fault;
+ u32 rx_cfg, rx_hash_high, rx_hash_low;
+
+ t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
+
+ if (adapter->params.rev > 0 && uses_xaui(adapter))
+ t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, 0);
+
+ t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
+ t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+ t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+
+ link_fault = t3_read_reg(adapter,
+ A_XGM_INT_STATUS + mac->offset);
+ link_fault &= F_LINKFAULTCHANGE;
+
+ phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
+
+ if (link_fault) {
+ lc->link_ok = 0;
+ lc->speed = SPEED_INVALID;
+ lc->duplex = DUPLEX_INVALID;
+
+ t3_os_link_fault(adapter, port_id, 0);
+
+ /* Account link faults only when the phy reports a link up */
+ if (link_ok)
+ mac->stats.link_faults++;
+
+ msleep(1000);
+ t3_os_link_fault_handler(adapter, port_id);
+ } else {
+ if (link_ok)
+ t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
+ F_TXACTENABLE | F_RXEN);
+
+ pi->link_fault = 0;
+ lc->link_ok = (unsigned char)link_ok;
+ lc->speed = speed < 0 ? SPEED_INVALID : speed;
+ lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
+ t3_os_link_fault(adapter, port_id, link_ok);
+ }
+}
+
/**
* t3_link_start - apply link configuration to MAC/PHY
* @phy: the PHY to setup
@@ -1316,7 +1429,7 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
#define MC7_INTR_MASK (F_AE | F_UE | F_CE | V_PE(M_PE))
#define XGM_INTR_MASK (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \
V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR) | \
- F_TXFIFO_UNDERRUN | F_RXFIFO_OVERFLOW)
+ F_TXFIFO_UNDERRUN)
#define PCIX_INTR_MASK (F_MSTDETPARERR | F_SIGTARABT | F_RCVTARABT | \
F_RCVMSTABT | F_SIGSYSERR | F_DETPARERR | \
F_SPLCMPDIS | F_UNXSPLCMP | F_RCVSPLCMPERR | \
@@ -1353,11 +1466,11 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
V_TX1TPPARERRENB(M_TX1TPPARERRENB) | \
V_RXTPPARERRENB(M_RXTPPARERRENB) | \
V_MCAPARERRENB(M_MCAPARERRENB))
+#define XGM_EXTRA_INTR_MASK (F_LINKFAULTCHANGE)
#define PL_INTR_MASK (F_T3DBG | F_XGMAC0_0 | F_XGMAC0_1 | F_MC5A | F_PM1_TX | \
F_PM1_RX | F_ULP2_TX | F_ULP2_RX | F_TP1 | F_CIM | \
F_MC7_CM | F_MC7_PMTX | F_MC7_PMRX | F_SGE3 | F_PCIM0 | \
F_MPS0 | F_CPL_SWITCH)
-
/*
* Interrupt handler for the PCIX1 module.
*/
@@ -1688,7 +1801,14 @@ static void mc7_intr_handler(struct mc7 *mc7)
static int mac_intr_handler(struct adapter *adap, unsigned int idx)
{
struct cmac *mac = &adap2pinfo(adap, idx)->mac;
- u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset);
+ /*
+ * We mask out interrupt causes for which we're not taking interrupts.
+ * This allows us to use polling logic to monitor some of the other
+ * conditions when taking interrupts would impose too much load on the
+ * system.
+ */
+ u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset) &
+ ~F_RXFIFO_OVERFLOW;
if (cause & V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR)) {
mac->stats.tx_fifo_parity_err++;
@@ -1708,10 +1828,20 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx)
mac->stats.xaui_pcs_ctc_err++;
if (cause & F_XAUIPCSALIGNCHANGE)
mac->stats.xaui_pcs_align_change++;
+ if (cause & F_XGM_INT) {
+ t3_set_reg_field(adap,
+ A_XGM_INT_ENABLE + mac->offset,
+ F_XGM_INT, 0);
+ mac->stats.link_faults++;
+
+ t3_os_link_fault_handler(adap, idx);
+ }
t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
+
if (cause & XGM_INTR_FATAL)
t3_fatal_err(adap);
+
return cause != 0;
}
@@ -1917,6 +2047,22 @@ void t3_intr_clear(struct adapter *adapter)
t3_read_reg(adapter, A_PL_INT_CAUSE0); /* flush */
}
+void t3_xgm_intr_enable(struct adapter *adapter, int idx)
+{
+ struct port_info *pi = adap2pinfo(adapter, idx);
+
+ t3_write_reg(adapter, A_XGM_XGM_INT_ENABLE + pi->mac.offset,
+ XGM_EXTRA_INTR_MASK);
+}
+
+void t3_xgm_intr_disable(struct adapter *adapter, int idx)
+{
+ struct port_info *pi = adap2pinfo(adapter, idx);
+
+ t3_write_reg(adapter, A_XGM_XGM_INT_DISABLE + pi->mac.offset,
+ 0x7ff);
+}
+
/**
* t3_port_intr_enable - enable port-specific interrupts
* @adapter: associated adapter
@@ -3610,7 +3756,15 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
adapter->params.info = ai;
adapter->params.nports = ai->nports;
adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
- adapter->params.linkpoll_period = 0;
+ /*
+ * We used to only run the "adapter check task" once a second if
+ * we had PHYs which didn't support interrupts (we would check
+ * their link status once a second). Now we check other conditions
+ * in that routine which could potentially impose a very high
+ * interrupt load on the system. As such, we now always scan the
+ * adapter state once a second ...
+ */
+ adapter->params.linkpoll_period = 10;
adapter->params.stats_update_period = is_10G(adapter) ?
MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
adapter->params.pci.vpd_cap_addr =
@@ -3700,7 +3854,14 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
ETH_ALEN);
init_link_config(&p->link_config, p->phy.caps);
p->phy.ops->power_down(&p->phy, 1);
- if (!(p->phy.caps & SUPPORTED_IRQ))
+
+ /*
+ * If the PHY doesn't support interrupts for link status
+ * changes, schedule a scan of the adapter links at least
+ * once a second.
+ */
+ if (!(p->phy.caps & SUPPORTED_IRQ) &&
+ adapter->params.linkpoll_period > 10)
adapter->params.linkpoll_period = 10;
}
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index b1b25c37aa1..7bf963ec554 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.1-ko"
+#define DRV_VERSION "1.1.2-ko"
/* Firmware version */
#define FW_VERSION_MAJOR 7
-#define FW_VERSION_MINOR 0
+#define FW_VERSION_MINOR 1
#define FW_VERSION_MICRO 0
#endif /* __CHELSIO_VERSION_H */
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index 9d7786937aa..f87f9435049 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -150,7 +150,8 @@ int t3_mac_reset(struct cmac *mac)
static int t3b2_mac_reset(struct cmac *mac)
{
struct adapter *adap = mac->adapter;
- unsigned int oft = mac->offset;
+ unsigned int oft = mac->offset, store;
+ int idx = macidx(mac);
u32 val;
if (!macidx(mac))
@@ -158,14 +159,28 @@ static int t3b2_mac_reset(struct cmac *mac)
else
t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0);
+ /* Stop NIC traffic to reduce the number of TXTOGGLES */
+ t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 0);
+ /* Ensure TX drains */
+ t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN, 0);
+
t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
+ /* Store A_TP_TX_DROP_CFG_CH0 */
+ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+ store = t3_read_reg(adap, A_TP_TX_DROP_CFG_CH0 + idx);
+
msleep(10);
+ /* Change DROP_CFG to 0xc0000011 */
+ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+ t3_write_reg(adap, A_TP_PIO_DATA, 0xc0000011);
+
/* Check for xgm Rx fifo empty */
+ /* Increased loop count to 1000 from 5 cover 1G and 100Mbps case */
if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft,
- 0x80000000, 1, 5, 2)) {
+ 0x80000000, 1, 1000, 2)) {
CH_ERR(adap, "MAC %d Rx fifo drain failed\n",
macidx(mac));
return -1;
@@ -191,11 +206,21 @@ static int t3b2_mac_reset(struct cmac *mac)
F_DISPAUSEFRAMES | F_EN1536BFRAMES |
F_RMFCS | F_ENJUMBO | F_ENHASHMCAST);
- if (!macidx(mac))
+ /* Restore the DROP_CFG */
+ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+ t3_write_reg(adap, A_TP_PIO_DATA, store);
+
+ if (!idx)
t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE);
else
t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE);
+ /* re-enable nic traffic */
+ t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 1);
+
+ /* Set: re-enable NIC traffic */
+ t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 1);
+
return 0;
}
@@ -236,7 +261,7 @@ int t3_mac_set_num_ucast(struct cmac *mac, int n)
return 0;
}
-static void disable_exact_filters(struct cmac *mac)
+void t3_mac_disable_exact_filters(struct cmac *mac)
{
unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_LOW_1;
@@ -247,7 +272,7 @@ static void disable_exact_filters(struct cmac *mac)
t3_read_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1); /* flush */
}
-static void enable_exact_filters(struct cmac *mac)
+void t3_mac_enable_exact_filters(struct cmac *mac)
{
unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_HIGH_1;
@@ -332,18 +357,9 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
return -EINVAL;
t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
- /*
- * Adjust the PAUSE frame watermarks. We always set the LWM, and the
- * HWM only if flow-control is enabled.
- */
- hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
- MAC_RXFIFO_SIZE * 38 / 100);
- hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
- lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
-
if (adap->params.rev >= T3_REV_B2 &&
(t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) {
- disable_exact_filters(mac);
+ t3_mac_disable_exact_filters(mac);
v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset);
t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset,
F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST);
@@ -355,14 +371,14 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
if (t3_wait_op_done(adap, reg + mac->offset,
F_RXFIFO_EMPTY, 1, 20, 5)) {
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
- enable_exact_filters(mac);
+ t3_mac_enable_exact_filters(mac);
return -EIO;
}
t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
V_RXMAXPKTSIZE(mtu));
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
- enable_exact_filters(mac);
+ t3_mac_enable_exact_filters(mac);
} else
t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
@@ -452,9 +468,12 @@ int t3_mac_enable(struct cmac *mac, int which)
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
- t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
+ t3_write_reg(adap, A_TP_PIO_DATA,
+ adap->params.rev == T3_REV_C ?
+ 0xc4ffff01 : 0xc0ede401);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
- t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
+ t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx,
+ adap->params.rev == T3_REV_C ? 0 : 1 << idx);
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
@@ -510,15 +529,12 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
struct adapter *adap = mac->adapter;
struct mac_stats *s = &mac->stats;
unsigned int tx_tcnt, tx_xcnt;
- unsigned int tx_mcnt = s->tx_frames;
- unsigned int rx_mcnt = s->rx_frames;
- unsigned int rx_xcnt;
+ u64 tx_mcnt = s->tx_frames;
int status;
status = 0;
tx_xcnt = 1; /* By default tx_xcnt is making progress */
tx_tcnt = mac->tx_tcnt; /* If tx_mcnt is progressing ignore tx_tcnt */
- rx_xcnt = 1; /* By default rx_xcnt is making progress */
if (tx_mcnt == mac->tx_mcnt && mac->rx_pause == s->rx_pause) {
tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
A_XGM_TX_SPI4_SOP_EOP_CNT +
@@ -529,11 +545,11 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
A_TP_PIO_DATA)));
} else {
- goto rxcheck;
+ goto out;
}
} else {
mac->toggle_cnt = 0;
- goto rxcheck;
+ goto out;
}
if ((tx_tcnt != mac->tx_tcnt) && (mac->tx_xcnt == 0)) {
@@ -546,23 +562,6 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
}
} else {
mac->toggle_cnt = 0;
- goto rxcheck;
- }
-
-rxcheck:
- if (rx_mcnt != mac->rx_mcnt) {
- rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
- A_XGM_RX_SPI4_SOP_EOP_CNT +
- mac->offset))) +
- (s->rx_fifo_ovfl -
- mac->rx_ocnt);
- mac->rx_ocnt = s->rx_fifo_ovfl;
- } else
- goto out;
-
- if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 &&
- mac->rx_xcnt == 0) {
- status = 2;
goto out;
}
@@ -570,8 +569,6 @@ out:
mac->tx_tcnt = tx_tcnt;
mac->tx_xcnt = tx_xcnt;
mac->tx_mcnt = s->tx_frames;
- mac->rx_xcnt = rx_xcnt;
- mac->rx_mcnt = s->rx_frames;
mac->rx_pause = s->rx_pause;
if (status == 1) {
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 7ce3053530f..861c867fca8 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -1027,7 +1027,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
printk(version);
if (bdev)
- snprintf(name, sizeof(name), "%s", bdev->bus_id);
+ snprintf(name, sizeof(name), "%s", dev_name(bdev));
else {
i = 0;
dev = root_lance_dev;
@@ -1105,10 +1105,10 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
start = to_tc_dev(bdev)->resource.start;
len = to_tc_dev(bdev)->resource.end - start + 1;
- if (!request_mem_region(start, len, bdev->bus_id)) {
+ if (!request_mem_region(start, len, dev_name(bdev))) {
printk(KERN_ERR
"%s: Unable to reserve MMIO resource\n",
- bdev->bus_id);
+ dev_name(bdev));
ret = -EBUSY;
goto err_out_dev;
}
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 6445cedd586..4ec055dc717 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -2937,7 +2937,7 @@ static int dfx_rcv_init(DFX_board_t *bp, int get_buffers)
for (i = 0; i < (int)(bp->rcv_bufs_to_post); i++)
for (j = 0; (i + j) < (int)PI_RCV_DATA_K_NUM_ENTRIES; j += bp->rcv_bufs_to_post)
{
- struct sk_buff *newskb = __dev_alloc_skb(NEW_SKB_SIZE, GFP_NOIO);
+ struct sk_buff *newskb = __netdev_alloc_skb(bp->dev, NEW_SKB_SIZE, GFP_NOIO);
if (!newskb)
return -ENOMEM;
bp->descr_block_virt->rcv_data[i+j].long_0 = (u32) (PI_RCV_DESCR_M_SOP |
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index e4cef491dc7..55625dbbae5 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -606,8 +606,8 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
return -ENXIO;
- printk ("%s: %s at 0x%04lx",
- device->bus_id, depca_signature[lp->adapter], ioaddr);
+ printk("%s: %s at 0x%04lx",
+ dev_name(device), depca_signature[lp->adapter], ioaddr);
switch (lp->depca_bus) {
#ifdef CONFIG_MCA
@@ -669,7 +669,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
spin_lock_init(&lp->lock);
sprintf(lp->adapter_name, "%s (%s)",
- depca_signature[lp->adapter], device->bus_id);
+ depca_signature[lp->adapter], dev_name(device));
status = -EBUSY;
/* Initialisation Block */
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index bcf92917bbf..254ec62b5f5 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -930,13 +930,15 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
struct net_device *dev = dev_id;
board_info_t *db = netdev_priv(dev);
int int_status;
+ unsigned long flags;
u8 reg_save;
dm9000_dbg(db, 3, "entering %s\n", __func__);
/* A real interrupt coming */
- spin_lock(&db->lock);
+ /* holders of db->lock must always block IRQs */
+ spin_lock_irqsave(&db->lock, flags);
/* Save previous register address */
reg_save = readb(db->io_addr);
@@ -972,7 +974,7 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
/* Restore previous register address */
writeb(reg_save, db->io_addr);
- spin_unlock(&db->lock);
+ spin_unlock_irqrestore(&db->lock, flags);
return IRQ_HANDLED;
}
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
new file mode 100644
index 00000000000..db1e31f9520
--- /dev/null
+++ b/drivers/net/dnet.c
@@ -0,0 +1,994 @@
+/*
+ * Dave DNET Ethernet Controller driver
+ *
+ * Copyright (C) 2008 Dave S.r.l. <www.dave.eu>
+ * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.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.
+ */
+#include <linux/version.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+
+#include "dnet.h"
+
+#undef DEBUG
+
+/* function for reading internal MAC register */
+u16 dnet_readw_mac(struct dnet *bp, u16 reg)
+{
+ u16 data_read;
+
+ /* issue a read */
+ dnet_writel(bp, reg, MACREG_ADDR);
+
+ /* since a read/write op to the MAC is very slow,
+ * we must wait before reading the data */
+ ndelay(500);
+
+ /* read data read from the MAC register */
+ data_read = dnet_readl(bp, MACREG_DATA);
+
+ /* all done */
+ return data_read;
+}
+
+/* function for writing internal MAC register */
+void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val)
+{
+ /* load data to write */
+ dnet_writel(bp, val, MACREG_DATA);
+
+ /* issue a write */
+ dnet_writel(bp, reg | DNET_INTERNAL_WRITE, MACREG_ADDR);
+
+ /* since a read/write op to the MAC is very slow,
+ * we must wait before exiting */
+ ndelay(500);
+}
+
+static void __dnet_set_hwaddr(struct dnet *bp)
+{
+ u16 tmp;
+
+ tmp = cpu_to_be16(*((u16 *) bp->dev->dev_addr));
+ dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG, tmp);
+ tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 2)));
+ dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG, tmp);
+ tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 4)));
+ dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG, tmp);
+}
+
+static void __devinit dnet_get_hwaddr(struct dnet *bp)
+{
+ u16 tmp;
+ u8 addr[6];
+
+ /*
+ * from MAC docs:
+ * "Note that the MAC address is stored in the registers in Hexadecimal
+ * form. For example, to set the MAC Address to: AC-DE-48-00-00-80
+ * would require writing 0xAC (octet 0) to address 0x0B (high byte of
+ * Mac_addr[15:0]), 0xDE (octet 1) to address 0x0A (Low byte of
+ * Mac_addr[15:0]), 0x48 (octet 2) to address 0x0D (high byte of
+ * Mac_addr[15:0]), 0x00 (octet 3) to address 0x0C (Low byte of
+ * Mac_addr[15:0]), 0x00 (octet 4) to address 0x0F (high byte of
+ * Mac_addr[15:0]), and 0x80 (octet 5) to address * 0x0E (Low byte of
+ * Mac_addr[15:0]).
+ */
+ tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG);
+ *((u16 *) addr) = be16_to_cpu(tmp);
+ tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG);
+ *((u16 *) (addr + 2)) = be16_to_cpu(tmp);
+ tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG);
+ *((u16 *) (addr + 4)) = be16_to_cpu(tmp);
+
+ if (is_valid_ether_addr(addr))
+ memcpy(bp->dev->dev_addr, addr, sizeof(addr));
+}
+
+static int dnet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+ struct dnet *bp = bus->priv;
+ u16 value;
+
+ while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG)
+ & DNET_INTERNAL_GMII_MNG_CMD_FIN))
+ cpu_relax();
+
+ /* only 5 bits allowed for phy-addr and reg_offset */
+ mii_id &= 0x1f;
+ regnum &= 0x1f;
+
+ /* prepare reg_value for a read */
+ value = (mii_id << 8);
+ value |= regnum;
+
+ /* write control word */
+ dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG, value);
+
+ /* wait for end of transfer */
+ while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG)
+ & DNET_INTERNAL_GMII_MNG_CMD_FIN))
+ cpu_relax();
+
+ value = dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_DAT_REG);
+
+ pr_debug("mdio_read %02x:%02x <- %04x\n", mii_id, regnum, value);
+
+ return value;
+}
+
+static int dnet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+ u16 value)
+{
+ struct dnet *bp = bus->priv;
+ u16 tmp;
+
+ pr_debug("mdio_write %02x:%02x <- %04x\n", mii_id, regnum, value);
+
+ while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG)
+ & DNET_INTERNAL_GMII_MNG_CMD_FIN))
+ cpu_relax();
+
+ /* prepare for a write operation */
+ tmp = (1 << 13);
+
+ /* only 5 bits allowed for phy-addr and reg_offset */
+ mii_id &= 0x1f;
+ regnum &= 0x1f;
+
+ /* only 16 bits on data */
+ value &= 0xffff;
+
+ /* prepare reg_value for a write */
+ tmp |= (mii_id << 8);
+ tmp |= regnum;
+
+ /* write data to write first */
+ dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_DAT_REG, value);
+
+ /* write control word */
+ dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG, tmp);
+
+ while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG)
+ & DNET_INTERNAL_GMII_MNG_CMD_FIN))
+ cpu_relax();
+
+ return 0;
+}
+
+static int dnet_mdio_reset(struct mii_bus *bus)
+{
+ return 0;
+}
+
+static void dnet_handle_link_change(struct net_device *dev)
+{
+ struct dnet *bp = netdev_priv(dev);
+ struct phy_device *phydev = bp->phy_dev;
+ unsigned long flags;
+ u32 mode_reg, ctl_reg;
+
+ int status_change = 0;
+
+ spin_lock_irqsave(&bp->lock, flags);
+
+ mode_reg = dnet_readw_mac(bp, DNET_INTERNAL_MODE_REG);
+ ctl_reg = dnet_readw_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG);
+
+ if (phydev->link) {
+ if (bp->duplex != phydev->duplex) {
+ if (phydev->duplex)
+ ctl_reg &=
+ ~(DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP);
+ else
+ ctl_reg |=
+ DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP;
+
+ bp->duplex = phydev->duplex;
+ status_change = 1;
+ }
+
+ if (bp->speed != phydev->speed) {
+ status_change = 1;
+ switch (phydev->speed) {
+ case 1000:
+ mode_reg |= DNET_INTERNAL_MODE_GBITEN;
+ break;
+ case 100:
+ case 10:
+ mode_reg &= ~DNET_INTERNAL_MODE_GBITEN;
+ break;
+ default:
+ printk(KERN_WARNING
+ "%s: Ack! Speed (%d) is not "
+ "10/100/1000!\n", dev->name,
+ phydev->speed);
+ break;
+ }
+ bp->speed = phydev->speed;
+ }
+ }
+
+ if (phydev->link != bp->link) {
+ if (phydev->link) {
+ mode_reg |=
+ (DNET_INTERNAL_MODE_RXEN | DNET_INTERNAL_MODE_TXEN);
+ } else {
+ mode_reg &=
+ ~(DNET_INTERNAL_MODE_RXEN |
+ DNET_INTERNAL_MODE_TXEN);
+ bp->speed = 0;
+ bp->duplex = -1;
+ }
+ bp->link = phydev->link;
+
+ status_change = 1;
+ }
+
+ if (status_change) {
+ dnet_writew_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG, ctl_reg);
+ dnet_writew_mac(bp, DNET_INTERNAL_MODE_REG, mode_reg);
+ }
+
+ spin_unlock_irqrestore(&bp->lock, flags);
+
+ if (status_change) {
+ if (phydev->link)
+ printk(KERN_INFO "%s: link up (%d/%s)\n",
+ dev->name, phydev->speed,
+ DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
+ else
+ printk(KERN_INFO "%s: link down\n", dev->name);
+ }
+}
+
+static int dnet_mii_probe(struct net_device *dev)
+{
+ struct dnet *bp = netdev_priv(dev);
+ struct phy_device *phydev = NULL;
+ int phy_addr;
+
+ /* find the first phy */
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+ if (bp->mii_bus->phy_map[phy_addr]) {
+ phydev = bp->mii_bus->phy_map[phy_addr];
+ break;
+ }
+ }
+
+ if (!phydev) {
+ printk(KERN_ERR "%s: no PHY found\n", dev->name);
+ return -ENODEV;
+ }
+
+ /* TODO : add pin_irq */
+
+ /* attach the mac to the phy */
+ if (bp->capabilities & DNET_HAS_RMII) {
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
+ &dnet_handle_link_change, 0,
+ PHY_INTERFACE_MODE_RMII);
+ } else {
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
+ &dnet_handle_link_change, 0,
+ PHY_INTERFACE_MODE_MII);
+ }
+
+ if (IS_ERR(phydev)) {
+ printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
+ return PTR_ERR(phydev);
+ }
+
+ /* mask with MAC supported features */
+ if (bp->capabilities & DNET_HAS_GIGABIT)
+ phydev->supported &= PHY_GBIT_FEATURES;
+ else
+ phydev->supported &= PHY_BASIC_FEATURES;
+
+ phydev->supported |= SUPPORTED_Asym_Pause | SUPPORTED_Pause;
+
+ phydev->advertising = phydev->supported;
+
+ bp->link = 0;
+ bp->speed = 0;
+ bp->duplex = -1;
+ bp->phy_dev = phydev;
+
+ return 0;
+}
+
+static int dnet_mii_init(struct dnet *bp)
+{
+ int err, i;
+
+ bp->mii_bus = mdiobus_alloc();
+ if (bp->mii_bus == NULL)
+ return -ENOMEM;
+
+ bp->mii_bus->name = "dnet_mii_bus";
+ bp->mii_bus->read = &dnet_mdio_read;
+ bp->mii_bus->write = &dnet_mdio_write;
+ bp->mii_bus->reset = &dnet_mdio_reset;
+
+ snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
+
+ bp->mii_bus->priv = bp;
+
+ bp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!bp->mii_bus->irq) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ bp->mii_bus->irq[i] = PHY_POLL;
+
+ platform_set_drvdata(bp->dev, bp->mii_bus);
+
+ if (mdiobus_register(bp->mii_bus)) {
+ err = -ENXIO;
+ goto err_out_free_mdio_irq;
+ }
+
+ if (dnet_mii_probe(bp->dev) != 0) {
+ err = -ENXIO;
+ goto err_out_unregister_bus;
+ }
+
+ return 0;
+
+err_out_unregister_bus:
+ mdiobus_unregister(bp->mii_bus);
+err_out_free_mdio_irq:
+ kfree(bp->mii_bus->irq);
+err_out:
+ mdiobus_free(bp->mii_bus);
+ return err;
+}
+
+/* For Neptune board: LINK1000 as Link LED and TX as activity LED */
+int dnet_phy_marvell_fixup(struct phy_device *phydev)
+{
+ return phy_write(phydev, 0x18, 0x4148);
+}
+
+static void dnet_update_stats(struct dnet *bp)
+{
+ u32 __iomem *reg = bp->regs + DNET_RX_PKT_IGNR_CNT;
+ u32 *p = &bp->hw_stats.rx_pkt_ignr;
+ u32 *end = &bp->hw_stats.rx_byte + 1;
+
+ WARN_ON((unsigned long)(end - p - 1) !=
+ (DNET_RX_BYTE_CNT - DNET_RX_PKT_IGNR_CNT) / 4);
+
+ for (; p < end; p++, reg++)
+ *p += readl(reg);
+
+ reg = bp->regs + DNET_TX_UNICAST_CNT;
+ p = &bp->hw_stats.tx_unicast;
+ end = &bp->hw_stats.tx_byte + 1;
+
+ WARN_ON((unsigned long)(end - p - 1) !=
+ (DNET_TX_BYTE_CNT - DNET_TX_UNICAST_CNT) / 4);
+
+ for (; p < end; p++, reg++)
+ *p += readl(reg);
+}
+
+static int dnet_poll(struct napi_struct *napi, int budget)
+{
+ struct dnet *bp = container_of(napi, struct dnet, napi);
+ struct net_device *dev = bp->dev;
+ int npackets = 0;
+ unsigned int pkt_len;
+ struct sk_buff *skb;
+ unsigned int *data_ptr;
+ u32 int_enable;
+ u32 cmd_word;
+ int i;
+
+ while (npackets < budget) {
+ /*
+ * break out of while loop if there are no more
+ * packets waiting
+ */
+ if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) {
+ napi_complete(napi);
+ int_enable = dnet_readl(bp, INTR_ENB);
+ int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF;
+ dnet_writel(bp, int_enable, INTR_ENB);
+ return 0;
+ }
+
+ cmd_word = dnet_readl(bp, RX_LEN_FIFO);
+ pkt_len = cmd_word & 0xFFFF;
+
+ if (cmd_word & 0xDF180000)
+ printk(KERN_ERR "%s packet receive error %x\n",
+ __func__, cmd_word);
+
+ skb = dev_alloc_skb(pkt_len + 5);
+ if (skb != NULL) {
+ /* Align IP on 16 byte boundaries */
+ skb_reserve(skb, 2);
+ /*
+ * 'skb_put()' points to the start of sk_buff
+ * data area.
+ */
+ data_ptr = (unsigned int *)skb_put(skb, pkt_len);
+ for (i = 0; i < (pkt_len + 3) >> 2; i++)
+ *data_ptr++ = dnet_readl(bp, RX_DATA_FIFO);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_receive_skb(skb);
+ npackets++;
+ } else
+ printk(KERN_NOTICE
+ "%s: No memory to allocate a sk_buff of "
+ "size %u.\n", dev->name, pkt_len);
+ }
+
+ budget -= npackets;
+
+ if (npackets < budget) {
+ /* We processed all packets available. Tell NAPI it can
+ * stop polling then re-enable rx interrupts */
+ napi_complete(napi);
+ int_enable = dnet_readl(bp, INTR_ENB);
+ int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF;
+ dnet_writel(bp, int_enable, INTR_ENB);
+ return 0;
+ }
+
+ /* There are still packets waiting */
+ return 1;
+}
+
+static irqreturn_t dnet_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct dnet *bp = netdev_priv(dev);
+ u32 int_src, int_enable, int_current;
+ unsigned long flags;
+ unsigned int handled = 0;
+
+ spin_lock_irqsave(&bp->lock, flags);
+
+ /* read and clear the DNET irq (clear on read) */
+ int_src = dnet_readl(bp, INTR_SRC);
+ int_enable = dnet_readl(bp, INTR_ENB);
+ int_current = int_src & int_enable;
+
+ /* restart the queue if we had stopped it for TX fifo almost full */
+ if (int_current & DNET_INTR_SRC_TX_FIFOAE) {
+ int_enable = dnet_readl(bp, INTR_ENB);
+ int_enable &= ~DNET_INTR_ENB_TX_FIFOAE;
+ dnet_writel(bp, int_enable, INTR_ENB);
+ netif_wake_queue(dev);
+ handled = 1;
+ }
+
+ /* RX FIFO error checking */
+ if (int_current &
+ (DNET_INTR_SRC_RX_CMDFIFOFF | DNET_INTR_SRC_RX_DATAFIFOFF)) {
+ printk(KERN_ERR "%s: RX fifo error %x, irq %x\n", __func__,
+ dnet_readl(bp, RX_STATUS), int_current);
+ /* we can only flush the RX FIFOs */
+ dnet_writel(bp, DNET_SYS_CTL_RXFIFOFLUSH, SYS_CTL);
+ ndelay(500);
+ dnet_writel(bp, 0, SYS_CTL);
+ handled = 1;
+ }
+
+ /* TX FIFO error checking */
+ if (int_current &
+ (DNET_INTR_SRC_TX_FIFOFULL | DNET_INTR_SRC_TX_DISCFRM)) {
+ printk(KERN_ERR "%s: TX fifo error %x, irq %x\n", __func__,
+ dnet_readl(bp, TX_STATUS), int_current);
+ /* we can only flush the TX FIFOs */
+ dnet_writel(bp, DNET_SYS_CTL_TXFIFOFLUSH, SYS_CTL);
+ ndelay(500);
+ dnet_writel(bp, 0, SYS_CTL);
+ handled = 1;
+ }
+
+ if (int_current & DNET_INTR_SRC_RX_CMDFIFOAF) {
+ if (napi_schedule_prep(&bp->napi)) {
+ /*
+ * There's no point taking any more interrupts
+ * until we have processed the buffers
+ */
+ /* Disable Rx interrupts and schedule NAPI poll */
+ int_enable = dnet_readl(bp, INTR_ENB);
+ int_enable &= ~DNET_INTR_SRC_RX_CMDFIFOAF;
+ dnet_writel(bp, int_enable, INTR_ENB);
+ __napi_schedule(&bp->napi);
+ }
+ handled = 1;
+ }
+
+ if (!handled)
+ pr_debug("%s: irq %x remains\n", __func__, int_current);
+
+ spin_unlock_irqrestore(&bp->lock, flags);
+
+ return IRQ_RETVAL(handled);
+}
+
+#ifdef DEBUG
+static inline void dnet_print_skb(struct sk_buff *skb)
+{
+ int k;
+ printk(KERN_DEBUG PFX "data:");
+ for (k = 0; k < skb->len; k++)
+ printk(" %02x", (unsigned int)skb->data[k]);
+ printk("\n");
+}
+#else
+#define dnet_print_skb(skb) do {} while (0)
+#endif
+
+static int dnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+
+ struct dnet *bp = netdev_priv(dev);
+ u32 tx_status, irq_enable;
+ unsigned int len, i, tx_cmd, wrsz;
+ unsigned long flags;
+ unsigned int *bufp;
+
+ tx_status = dnet_readl(bp, TX_STATUS);
+
+ pr_debug("start_xmit: len %u head %p data %p\n",
+ skb->len, skb->head, skb->data);
+ dnet_print_skb(skb);
+
+ /* frame size (words) */
+ len = (skb->len + 3) >> 2;
+
+ spin_lock_irqsave(&bp->lock, flags);
+
+ tx_status = dnet_readl(bp, TX_STATUS);
+
+ bufp = (unsigned int *)(((unsigned long) skb->data) & ~0x3UL);
+ wrsz = (u32) skb->len + 3;
+ wrsz += ((unsigned long) skb->data) & 0x3;
+ wrsz >>= 2;
+ tx_cmd = ((((unsigned long)(skb->data)) & 0x03) << 16) | (u32) skb->len;
+
+ /* check if there is enough room for the current frame */
+ if (wrsz < (DNET_FIFO_SIZE - dnet_readl(bp, TX_FIFO_WCNT))) {
+ for (i = 0; i < wrsz; i++)
+ dnet_writel(bp, *bufp++, TX_DATA_FIFO);
+
+ /*
+ * inform MAC that a packet's written and ready to be
+ * shipped out
+ */
+ dnet_writel(bp, tx_cmd, TX_LEN_FIFO);
+ }
+
+ if (dnet_readl(bp, TX_FIFO_WCNT) > DNET_FIFO_TX_DATA_AF_TH) {
+ netif_stop_queue(dev);
+ tx_status = dnet_readl(bp, INTR_SRC);
+ irq_enable = dnet_readl(bp, INTR_ENB);
+ irq_enable |= DNET_INTR_ENB_TX_FIFOAE;
+ dnet_writel(bp, irq_enable, INTR_ENB);
+ }
+
+ /* free the buffer */
+ dev_kfree_skb(skb);
+
+ spin_unlock_irqrestore(&bp->lock, flags);
+
+ dev->trans_start = jiffies;
+
+ return 0;
+}
+
+static void dnet_reset_hw(struct dnet *bp)
+{
+ /* put ts_mac in IDLE state i.e. disable rx/tx */
+ dnet_writew_mac(bp, DNET_INTERNAL_MODE_REG, DNET_INTERNAL_MODE_FCEN);
+
+ /*
+ * RX FIFO almost full threshold: only cmd FIFO almost full is
+ * implemented for RX side
+ */
+ dnet_writel(bp, DNET_FIFO_RX_CMD_AF_TH, RX_FIFO_TH);
+ /*
+ * TX FIFO almost empty threshold: only data FIFO almost empty
+ * is implemented for TX side
+ */
+ dnet_writel(bp, DNET_FIFO_TX_DATA_AE_TH, TX_FIFO_TH);
+
+ /* flush rx/tx fifos */
+ dnet_writel(bp, DNET_SYS_CTL_RXFIFOFLUSH | DNET_SYS_CTL_TXFIFOFLUSH,
+ SYS_CTL);
+ msleep(1);
+ dnet_writel(bp, 0, SYS_CTL);
+}
+
+static void dnet_init_hw(struct dnet *bp)
+{
+ u32 config;
+
+ dnet_reset_hw(bp);
+ __dnet_set_hwaddr(bp);
+
+ config = dnet_readw_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG);
+
+ if (bp->dev->flags & IFF_PROMISC)
+ /* Copy All Frames */
+ config |= DNET_INTERNAL_RXTX_CONTROL_ENPROMISC;
+ if (!(bp->dev->flags & IFF_BROADCAST))
+ /* No BroadCast */
+ config |= DNET_INTERNAL_RXTX_CONTROL_RXMULTICAST;
+
+ config |= DNET_INTERNAL_RXTX_CONTROL_RXPAUSE |
+ DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST |
+ DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL |
+ DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS;
+
+ dnet_writew_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG, config);
+
+ /* clear irq before enabling them */
+ config = dnet_readl(bp, INTR_SRC);
+
+ /* enable RX/TX interrupt, recv packet ready interrupt */
+ dnet_writel(bp, DNET_INTR_ENB_GLOBAL_ENABLE | DNET_INTR_ENB_RX_SUMMARY |
+ DNET_INTR_ENB_TX_SUMMARY | DNET_INTR_ENB_RX_FIFOERR |
+ DNET_INTR_ENB_RX_ERROR | DNET_INTR_ENB_RX_FIFOFULL |
+ DNET_INTR_ENB_TX_FIFOFULL | DNET_INTR_ENB_TX_DISCFRM |
+ DNET_INTR_ENB_RX_PKTRDY, INTR_ENB);
+}
+
+static int dnet_open(struct net_device *dev)
+{
+ struct dnet *bp = netdev_priv(dev);
+
+ /* if the phy is not yet register, retry later */
+ if (!bp->phy_dev)
+ return -EAGAIN;
+
+ if (!is_valid_ether_addr(dev->dev_addr))
+ return -EADDRNOTAVAIL;
+
+ napi_enable(&bp->napi);
+ dnet_init_hw(bp);
+
+ phy_start_aneg(bp->phy_dev);
+
+ /* schedule a link state check */
+ phy_start(bp->phy_dev);
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+static int dnet_close(struct net_device *dev)
+{
+ struct dnet *bp = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ napi_disable(&bp->napi);
+
+ if (bp->phy_dev)
+ phy_stop(bp->phy_dev);
+
+ dnet_reset_hw(bp);
+ netif_carrier_off(dev);
+
+ return 0;
+}
+
+static inline void dnet_print_pretty_hwstats(struct dnet_stats *hwstat)
+{
+ pr_debug("%s\n", __func__);
+ pr_debug("----------------------------- RX statistics "
+ "-------------------------------\n");
+ pr_debug("RX_PKT_IGNR_CNT %-8x\n", hwstat->rx_pkt_ignr);
+ pr_debug("RX_LEN_CHK_ERR_CNT %-8x\n", hwstat->rx_len_chk_err);
+ pr_debug("RX_LNG_FRM_CNT %-8x\n", hwstat->rx_lng_frm);
+ pr_debug("RX_SHRT_FRM_CNT %-8x\n", hwstat->rx_shrt_frm);
+ pr_debug("RX_IPG_VIOL_CNT %-8x\n", hwstat->rx_ipg_viol);
+ pr_debug("RX_CRC_ERR_CNT %-8x\n", hwstat->rx_crc_err);
+ pr_debug("RX_OK_PKT_CNT %-8x\n", hwstat->rx_ok_pkt);
+ pr_debug("RX_CTL_FRM_CNT %-8x\n", hwstat->rx_ctl_frm);
+ pr_debug("RX_PAUSE_FRM_CNT %-8x\n", hwstat->rx_pause_frm);
+ pr_debug("RX_MULTICAST_CNT %-8x\n", hwstat->rx_multicast);
+ pr_debug("RX_BROADCAST_CNT %-8x\n", hwstat->rx_broadcast);
+ pr_debug("RX_VLAN_TAG_CNT %-8x\n", hwstat->rx_vlan_tag);
+ pr_debug("RX_PRE_SHRINK_CNT %-8x\n", hwstat->rx_pre_shrink);
+ pr_debug("RX_DRIB_NIB_CNT %-8x\n", hwstat->rx_drib_nib);
+ pr_debug("RX_UNSUP_OPCD_CNT %-8x\n", hwstat->rx_unsup_opcd);
+ pr_debug("RX_BYTE_CNT %-8x\n", hwstat->rx_byte);
+ pr_debug("----------------------------- TX statistics "
+ "-------------------------------\n");
+ pr_debug("TX_UNICAST_CNT %-8x\n", hwstat->tx_unicast);
+ pr_debug("TX_PAUSE_FRM_CNT %-8x\n", hwstat->tx_pause_frm);
+ pr_debug("TX_MULTICAST_CNT %-8x\n", hwstat->tx_multicast);
+ pr_debug("TX_BRDCAST_CNT %-8x\n", hwstat->tx_brdcast);
+ pr_debug("TX_VLAN_TAG_CNT %-8x\n", hwstat->tx_vlan_tag);
+ pr_debug("TX_BAD_FCS_CNT %-8x\n", hwstat->tx_bad_fcs);
+ pr_debug("TX_JUMBO_CNT %-8x\n", hwstat->tx_jumbo);
+ pr_debug("TX_BYTE_CNT %-8x\n", hwstat->tx_byte);
+}
+
+static struct net_device_stats *dnet_get_stats(struct net_device *dev)
+{
+
+ struct dnet *bp = netdev_priv(dev);
+ struct net_device_stats *nstat = &dev->stats;
+ struct dnet_stats *hwstat = &bp->hw_stats;
+
+ /* read stats from hardware */
+ dnet_update_stats(bp);
+
+ /* Convert HW stats into netdevice stats */
+ nstat->rx_errors = (hwstat->rx_len_chk_err +
+ hwstat->rx_lng_frm + hwstat->rx_shrt_frm +
+ /* ignore IGP violation error
+ hwstat->rx_ipg_viol + */
+ hwstat->rx_crc_err +
+ hwstat->rx_pre_shrink +
+ hwstat->rx_drib_nib + hwstat->rx_unsup_opcd);
+ nstat->tx_errors = hwstat->tx_bad_fcs;
+ nstat->rx_length_errors = (hwstat->rx_len_chk_err +
+ hwstat->rx_lng_frm +
+ hwstat->rx_shrt_frm + hwstat->rx_pre_shrink);
+ nstat->rx_crc_errors = hwstat->rx_crc_err;
+ nstat->rx_frame_errors = hwstat->rx_pre_shrink + hwstat->rx_drib_nib;
+ nstat->rx_packets = hwstat->rx_ok_pkt;
+ nstat->tx_packets = (hwstat->tx_unicast +
+ hwstat->tx_multicast + hwstat->tx_brdcast);
+ nstat->rx_bytes = hwstat->rx_byte;
+ nstat->tx_bytes = hwstat->tx_byte;
+ nstat->multicast = hwstat->rx_multicast;
+ nstat->rx_missed_errors = hwstat->rx_pkt_ignr;
+
+ dnet_print_pretty_hwstats(hwstat);
+
+ return nstat;
+}
+
+static int dnet_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct dnet *bp = netdev_priv(dev);
+ struct phy_device *phydev = bp->phy_dev;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_ethtool_gset(phydev, cmd);
+}
+
+static int dnet_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct dnet *bp = netdev_priv(dev);
+ struct phy_device *phydev = bp->phy_dev;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phydev, cmd);
+}
+
+static int dnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct dnet *bp = netdev_priv(dev);
+ struct phy_device *phydev = bp->phy_dev;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_mii_ioctl(phydev, if_mii(rq), cmd);
+}
+
+static void dnet_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strcpy(info->driver, DRV_NAME);
+ strcpy(info->version, DRV_VERSION);
+ strcpy(info->bus_info, "0");
+}
+
+static const struct ethtool_ops dnet_ethtool_ops = {
+ .get_settings = dnet_get_settings,
+ .set_settings = dnet_set_settings,
+ .get_drvinfo = dnet_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+};
+
+static const struct net_device_ops dnet_netdev_ops = {
+ .ndo_open = dnet_open,
+ .ndo_stop = dnet_close,
+ .ndo_get_stats = dnet_get_stats,
+ .ndo_start_xmit = dnet_start_xmit,
+ .ndo_do_ioctl = dnet_ioctl,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+};
+
+static int __devinit dnet_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct net_device *dev;
+ struct dnet *bp;
+ struct phy_device *phydev;
+ int err = -ENXIO;
+ unsigned int mem_base, mem_size, irq;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "no mmio resource defined\n");
+ goto err_out;
+ }
+ mem_base = res->start;
+ mem_size = resource_size(res);
+ irq = platform_get_irq(pdev, 0);
+
+ if (!request_mem_region(mem_base, mem_size, DRV_NAME)) {
+ dev_err(&pdev->dev, "no memory region available\n");
+ err = -EBUSY;
+ goto err_out;
+ }
+
+ err = -ENOMEM;
+ dev = alloc_etherdev(sizeof(*bp));
+ if (!dev) {
+ dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n");
+ goto err_out;
+ }
+
+ /* TODO: Actually, we have some interesting features... */
+ dev->features |= 0;
+
+ bp = netdev_priv(dev);
+ bp->dev = dev;
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ spin_lock_init(&bp->lock);
+
+ bp->regs = ioremap(mem_base, mem_size);
+ if (!bp->regs) {
+ dev_err(&pdev->dev, "failed to map registers, aborting.\n");
+ err = -ENOMEM;
+ goto err_out_free_dev;
+ }
+
+ dev->irq = irq;
+ err = request_irq(dev->irq, dnet_interrupt, 0, DRV_NAME, dev);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n",
+ irq, err);
+ goto err_out_iounmap;
+ }
+
+ dev->netdev_ops = &dnet_netdev_ops;
+ netif_napi_add(dev, &bp->napi, dnet_poll, 64);
+ dev->ethtool_ops = &dnet_ethtool_ops;
+
+ dev->base_addr = (unsigned long)bp->regs;
+
+ bp->capabilities = dnet_readl(bp, VERCAPS) & DNET_CAPS_MASK;
+
+ dnet_get_hwaddr(bp);
+
+ if (!is_valid_ether_addr(dev->dev_addr)) {
+ /* choose a random ethernet address */
+ random_ether_addr(dev->dev_addr);
+ __dnet_set_hwaddr(bp);
+ }
+
+ err = register_netdev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
+ goto err_out_free_irq;
+ }
+
+ /* register the PHY board fixup (for Marvell 88E1111) */
+ err = phy_register_fixup_for_uid(0x01410cc0, 0xfffffff0,
+ dnet_phy_marvell_fixup);
+ /* we can live without it, so just issue a warning */
+ if (err)
+ dev_warn(&pdev->dev, "Cannot register PHY board fixup.\n");
+
+ if (dnet_mii_init(bp) != 0)
+ goto err_out_unregister_netdev;
+
+ dev_info(&pdev->dev, "Dave DNET at 0x%p (0x%08x) irq %d %pM\n",
+ bp->regs, mem_base, dev->irq, dev->dev_addr);
+ dev_info(&pdev->dev, "has %smdio, %sirq, %sgigabit, %sdma \n",
+ (bp->capabilities & DNET_HAS_MDIO) ? "" : "no ",
+ (bp->capabilities & DNET_HAS_IRQ) ? "" : "no ",
+ (bp->capabilities & DNET_HAS_GIGABIT) ? "" : "no ",
+ (bp->capabilities & DNET_HAS_DMA) ? "" : "no ");
+ phydev = bp->phy_dev;
+ dev_info(&pdev->dev, "attached PHY driver [%s] "
+ "(mii_bus:phy_addr=%s, irq=%d)\n",
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
+
+ return 0;
+
+err_out_unregister_netdev:
+ unregister_netdev(dev);
+err_out_free_irq:
+ free_irq(dev->irq, dev);
+err_out_iounmap:
+ iounmap(bp->regs);
+err_out_free_dev:
+ free_netdev(dev);
+err_out:
+ return err;
+}
+
+static int __devexit dnet_remove(struct platform_device *pdev)
+{
+
+ struct net_device *dev;
+ struct dnet *bp;
+
+ dev = platform_get_drvdata(pdev);
+
+ if (dev) {
+ bp = netdev_priv(dev);
+ if (bp->phy_dev)
+ phy_disconnect(bp->phy_dev);
+ mdiobus_unregister(bp->mii_bus);
+ kfree(bp->mii_bus->irq);
+ mdiobus_free(bp->mii_bus);
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
+ iounmap(bp->regs);
+ free_netdev(dev);
+ }
+
+ return 0;
+}
+
+static struct platform_driver dnet_driver = {
+ .probe = dnet_probe,
+ .remove = __devexit_p(dnet_remove),
+ .driver = {
+ .name = "dnet",
+ },
+};
+
+static int __init dnet_init(void)
+{
+ return platform_driver_register(&dnet_driver);
+}
+
+static void __exit dnet_exit(void)
+{
+ platform_driver_unregister(&dnet_driver);
+}
+
+module_init(dnet_init);
+module_exit(dnet_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Dave DNET Ethernet driver");
+MODULE_AUTHOR("Ilya Yanok <yanok@emcraft.com>, "
+ "Matteo Vit <matteo.vit@dave.eu>");
diff --git a/drivers/net/dnet.h b/drivers/net/dnet.h
new file mode 100644
index 00000000000..37f5b30fa78
--- /dev/null
+++ b/drivers/net/dnet.h
@@ -0,0 +1,225 @@
+/*
+ * Dave DNET Ethernet Controller driver
+ *
+ * Copyright (C) 2008 Dave S.r.l. <www.dave.eu>
+ *
+ * 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 _DNET_H
+#define _DNET_H
+
+#define DRV_NAME "dnet"
+#define DRV_VERSION "0.9.1"
+#define PFX DRV_NAME ": "
+
+/* Register access macros */
+#define dnet_writel(port, value, reg) \
+ writel((value), (port)->regs + DNET_##reg)
+#define dnet_readl(port, reg) readl((port)->regs + DNET_##reg)
+
+/* ALL DNET FIFO REGISTERS */
+#define DNET_RX_LEN_FIFO 0x000 /* RX_LEN_FIFO */
+#define DNET_RX_DATA_FIFO 0x004 /* RX_DATA_FIFO */
+#define DNET_TX_LEN_FIFO 0x008 /* TX_LEN_FIFO */
+#define DNET_TX_DATA_FIFO 0x00C /* TX_DATA_FIFO */
+
+/* ALL DNET CONTROL/STATUS REGISTERS OFFSETS */
+#define DNET_VERCAPS 0x100 /* VERCAPS */
+#define DNET_INTR_SRC 0x104 /* INTR_SRC */
+#define DNET_INTR_ENB 0x108 /* INTR_ENB */
+#define DNET_RX_STATUS 0x10C /* RX_STATUS */
+#define DNET_TX_STATUS 0x110 /* TX_STATUS */
+#define DNET_RX_FRAMES_CNT 0x114 /* RX_FRAMES_CNT */
+#define DNET_TX_FRAMES_CNT 0x118 /* TX_FRAMES_CNT */
+#define DNET_RX_FIFO_TH 0x11C /* RX_FIFO_TH */
+#define DNET_TX_FIFO_TH 0x120 /* TX_FIFO_TH */
+#define DNET_SYS_CTL 0x124 /* SYS_CTL */
+#define DNET_PAUSE_TMR 0x128 /* PAUSE_TMR */
+#define DNET_RX_FIFO_WCNT 0x12C /* RX_FIFO_WCNT */
+#define DNET_TX_FIFO_WCNT 0x130 /* TX_FIFO_WCNT */
+
+/* ALL DNET MAC REGISTERS */
+#define DNET_MACREG_DATA 0x200 /* Mac-Reg Data */
+#define DNET_MACREG_ADDR 0x204 /* Mac-Reg Addr */
+
+/* ALL DNET RX STATISTICS COUNTERS */
+#define DNET_RX_PKT_IGNR_CNT 0x300
+#define DNET_RX_LEN_CHK_ERR_CNT 0x304
+#define DNET_RX_LNG_FRM_CNT 0x308
+#define DNET_RX_SHRT_FRM_CNT 0x30C
+#define DNET_RX_IPG_VIOL_CNT 0x310
+#define DNET_RX_CRC_ERR_CNT 0x314
+#define DNET_RX_OK_PKT_CNT 0x318
+#define DNET_RX_CTL_FRM_CNT 0x31C
+#define DNET_RX_PAUSE_FRM_CNT 0x320
+#define DNET_RX_MULTICAST_CNT 0x324
+#define DNET_RX_BROADCAST_CNT 0x328
+#define DNET_RX_VLAN_TAG_CNT 0x32C
+#define DNET_RX_PRE_SHRINK_CNT 0x330
+#define DNET_RX_DRIB_NIB_CNT 0x334
+#define DNET_RX_UNSUP_OPCD_CNT 0x338
+#define DNET_RX_BYTE_CNT 0x33C
+
+/* DNET TX STATISTICS COUNTERS */
+#define DNET_TX_UNICAST_CNT 0x400
+#define DNET_TX_PAUSE_FRM_CNT 0x404
+#define DNET_TX_MULTICAST_CNT 0x408
+#define DNET_TX_BRDCAST_CNT 0x40C
+#define DNET_TX_VLAN_TAG_CNT 0x410
+#define DNET_TX_BAD_FCS_CNT 0x414
+#define DNET_TX_JUMBO_CNT 0x418
+#define DNET_TX_BYTE_CNT 0x41C
+
+/* SOME INTERNAL MAC-CORE REGISTER */
+#define DNET_INTERNAL_MODE_REG 0x0
+#define DNET_INTERNAL_RXTX_CONTROL_REG 0x2
+#define DNET_INTERNAL_MAX_PKT_SIZE_REG 0x4
+#define DNET_INTERNAL_IGP_REG 0x8
+#define DNET_INTERNAL_MAC_ADDR_0_REG 0xa
+#define DNET_INTERNAL_MAC_ADDR_1_REG 0xc
+#define DNET_INTERNAL_MAC_ADDR_2_REG 0xe
+#define DNET_INTERNAL_TX_RX_STS_REG 0x12
+#define DNET_INTERNAL_GMII_MNG_CTL_REG 0x14
+#define DNET_INTERNAL_GMII_MNG_DAT_REG 0x16
+
+#define DNET_INTERNAL_GMII_MNG_CMD_FIN (1 << 14)
+
+#define DNET_INTERNAL_WRITE (1 << 31)
+
+/* MAC-CORE REGISTER FIELDS */
+
+/* MAC-CORE MODE REGISTER FIELDS */
+#define DNET_INTERNAL_MODE_GBITEN (1 << 0)
+#define DNET_INTERNAL_MODE_FCEN (1 << 1)
+#define DNET_INTERNAL_MODE_RXEN (1 << 2)
+#define DNET_INTERNAL_MODE_TXEN (1 << 3)
+
+/* MAC-CORE RXTX CONTROL REGISTER FIELDS */
+#define DNET_INTERNAL_RXTX_CONTROL_RXSHORTFRAME (1 << 8)
+#define DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST (1 << 7)
+#define DNET_INTERNAL_RXTX_CONTROL_RXMULTICAST (1 << 4)
+#define DNET_INTERNAL_RXTX_CONTROL_RXPAUSE (1 << 3)
+#define DNET_INTERNAL_RXTX_CONTROL_DISTXFCS (1 << 2)
+#define DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS (1 << 1)
+#define DNET_INTERNAL_RXTX_CONTROL_ENPROMISC (1 << 0)
+#define DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL (1 << 6)
+#define DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP (1 << 5)
+
+/* SYSTEM CONTROL REGISTER FIELDS */
+#define DNET_SYS_CTL_IGNORENEXTPKT (1 << 0)
+#define DNET_SYS_CTL_SENDPAUSE (1 << 2)
+#define DNET_SYS_CTL_RXFIFOFLUSH (1 << 3)
+#define DNET_SYS_CTL_TXFIFOFLUSH (1 << 4)
+
+/* TX STATUS REGISTER FIELDS */
+#define DNET_TX_STATUS_FIFO_ALMOST_EMPTY (1 << 2)
+#define DNET_TX_STATUS_FIFO_ALMOST_FULL (1 << 1)
+
+/* INTERRUPT SOURCE REGISTER FIELDS */
+#define DNET_INTR_SRC_TX_PKTSENT (1 << 0)
+#define DNET_INTR_SRC_TX_FIFOAF (1 << 1)
+#define DNET_INTR_SRC_TX_FIFOAE (1 << 2)
+#define DNET_INTR_SRC_TX_DISCFRM (1 << 3)
+#define DNET_INTR_SRC_TX_FIFOFULL (1 << 4)
+#define DNET_INTR_SRC_RX_CMDFIFOAF (1 << 8)
+#define DNET_INTR_SRC_RX_CMDFIFOFF (1 << 9)
+#define DNET_INTR_SRC_RX_DATAFIFOFF (1 << 10)
+#define DNET_INTR_SRC_TX_SUMMARY (1 << 16)
+#define DNET_INTR_SRC_RX_SUMMARY (1 << 17)
+#define DNET_INTR_SRC_PHY (1 << 19)
+
+/* INTERRUPT ENABLE REGISTER FIELDS */
+#define DNET_INTR_ENB_TX_PKTSENT (1 << 0)
+#define DNET_INTR_ENB_TX_FIFOAF (1 << 1)
+#define DNET_INTR_ENB_TX_FIFOAE (1 << 2)
+#define DNET_INTR_ENB_TX_DISCFRM (1 << 3)
+#define DNET_INTR_ENB_TX_FIFOFULL (1 << 4)
+#define DNET_INTR_ENB_RX_PKTRDY (1 << 8)
+#define DNET_INTR_ENB_RX_FIFOAF (1 << 9)
+#define DNET_INTR_ENB_RX_FIFOERR (1 << 10)
+#define DNET_INTR_ENB_RX_ERROR (1 << 11)
+#define DNET_INTR_ENB_RX_FIFOFULL (1 << 12)
+#define DNET_INTR_ENB_RX_FIFOAE (1 << 13)
+#define DNET_INTR_ENB_TX_SUMMARY (1 << 16)
+#define DNET_INTR_ENB_RX_SUMMARY (1 << 17)
+#define DNET_INTR_ENB_GLOBAL_ENABLE (1 << 18)
+
+/* default values:
+ * almost empty = less than one full sized ethernet frame (no jumbo) inside
+ * the fifo almost full = can write less than one full sized ethernet frame
+ * (no jumbo) inside the fifo
+ */
+#define DNET_CFG_TX_FIFO_FULL_THRES 25
+#define DNET_CFG_RX_FIFO_FULL_THRES 20
+
+/*
+ * Capabilities. Used by the driver to know the capabilities that the ethernet
+ * controller inside the FPGA have.
+ */
+
+#define DNET_HAS_MDIO (1 << 0)
+#define DNET_HAS_IRQ (1 << 1)
+#define DNET_HAS_GIGABIT (1 << 2)
+#define DNET_HAS_DMA (1 << 3)
+
+#define DNET_HAS_MII (1 << 4) /* or GMII */
+#define DNET_HAS_RMII (1 << 5) /* or RGMII */
+
+#define DNET_CAPS_MASK 0xFFFF
+
+#define DNET_FIFO_SIZE 1024 /* 1K x 32 bit */
+#define DNET_FIFO_TX_DATA_AF_TH (DNET_FIFO_SIZE - 384) /* 384 = 1536 / 4 */
+#define DNET_FIFO_TX_DATA_AE_TH 384
+
+#define DNET_FIFO_RX_CMD_AF_TH (1 << 16) /* just one frame inside the FIFO */
+
+/*
+ * Hardware-collected statistics.
+ */
+struct dnet_stats {
+ u32 rx_pkt_ignr;
+ u32 rx_len_chk_err;
+ u32 rx_lng_frm;
+ u32 rx_shrt_frm;
+ u32 rx_ipg_viol;
+ u32 rx_crc_err;
+ u32 rx_ok_pkt;
+ u32 rx_ctl_frm;
+ u32 rx_pause_frm;
+ u32 rx_multicast;
+ u32 rx_broadcast;
+ u32 rx_vlan_tag;
+ u32 rx_pre_shrink;
+ u32 rx_drib_nib;
+ u32 rx_unsup_opcd;
+ u32 rx_byte;
+ u32 tx_unicast;
+ u32 tx_pause_frm;
+ u32 tx_multicast;
+ u32 tx_brdcast;
+ u32 tx_vlan_tag;
+ u32 tx_bad_fcs;
+ u32 tx_jumbo;
+ u32 tx_byte;
+};
+
+struct dnet {
+ void __iomem *regs;
+ spinlock_t lock;
+ struct platform_device *pdev;
+ struct net_device *dev;
+ struct dnet_stats hw_stats;
+ unsigned int capabilities; /* read from FPGA */
+ struct napi_struct napi;
+
+ /* PHY stuff */
+ struct mii_bus *mii_bus;
+ struct phy_device *phy_dev;
+ unsigned int link;
+ unsigned int speed;
+ unsigned int duplex;
+};
+
+#endif /* _DNET_H */
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 86bb876fb12..0504db9ad64 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -167,7 +167,7 @@
#define DRV_NAME "e100"
#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.5.23-k6"DRV_EXT
+#define DRV_VERSION "3.5.24-k2"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
#define PFX DRV_NAME ": "
@@ -240,6 +240,7 @@ static struct pci_device_id e100_id_table[] = {
INTEL_8255X_ETHERNET_DEVICE(0x1093, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1094, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1095, 7),
+ INTEL_8255X_ETHERNET_DEVICE(0x10fe, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
@@ -275,6 +276,7 @@ enum phy {
phy_82562_em = 0x032002A8,
phy_82562_ek = 0x031002A8,
phy_82562_eh = 0x017002A8,
+ phy_82552_v = 0xd061004d,
phy_unknown = 0xFFFFFFFF,
};
@@ -943,6 +945,22 @@ static int mdio_read(struct net_device *netdev, int addr, int reg)
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;
+ }
+
mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
}
@@ -1276,16 +1294,12 @@ static int e100_phy_init(struct nic *nic)
if (addr == 32)
return -EAGAIN;
- /* Selected the phy and isolate the rest */
- for (addr = 0; addr < 32; addr++) {
- if (addr != nic->mii.phy_id) {
- mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
- } else {
- bmcr = mdio_read(netdev, addr, MII_BMCR);
- mdio_write(netdev, addr, MII_BMCR,
- bmcr & ~BMCR_ISOLATE);
- }
- }
+ /* Isolate all the PHY ids */
+ for (addr = 0; addr < 32; addr++)
+ mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
+ /* Select the discovered PHY */
+ bmcr &= ~BMCR_ISOLATE;
+ mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
/* Get phy ID */
id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
@@ -1303,7 +1317,18 @@ static int e100_phy_init(struct nic *nic)
mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
}
- if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
+ if (nic->phy == phy_82552_v) {
+ u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
+
+ /* 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);
+
+ /* Reset for the above changes to take effect */
+ bmcr = mdio_read(netdev, nic->mii.phy_id, MII_BMCR);
+ bmcr |= BMCR_RESET;
+ mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
+ } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
(mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) &&
!(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {
/* enable/disable MDI/MDI-X auto-switching. */
@@ -1944,9 +1969,9 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
if (stat_ack & stat_ack_rnr)
nic->ru_running = RU_SUSPENDED;
- if (likely(netif_rx_schedule_prep(&nic->napi))) {
+ if (likely(napi_schedule_prep(&nic->napi))) {
e100_disable_irq(nic);
- __netif_rx_schedule(&nic->napi);
+ __napi_schedule(&nic->napi);
}
return IRQ_HANDLED;
@@ -1962,7 +1987,7 @@ static int e100_poll(struct napi_struct *napi, int budget)
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
e100_enable_irq(nic);
}
@@ -2134,6 +2159,9 @@ err_clean_rx:
}
#define MII_LED_CONTROL 0x1B
+#define E100_82552_LED_OVERRIDE 0x19
+#define E100_82552_LED_ON 0x000F /* LEDTX and LED_RX both on */
+#define E100_82552_LED_OFF 0x000A /* LEDTX and LED_RX both off */
static void e100_blink_led(unsigned long data)
{
struct nic *nic = (struct nic *)data;
@@ -2143,10 +2171,19 @@ static void e100_blink_led(unsigned long data)
led_on_559 = 0x05,
led_on_557 = 0x07,
};
+ u16 led_reg = MII_LED_CONTROL;
+
+ if (nic->phy == phy_82552_v) {
+ led_reg = E100_82552_LED_OVERRIDE;
- nic->leds = (nic->leds & led_on) ? led_off :
- (nic->mac < mac_82559_D101M) ? led_on_557 : led_on_559;
- mdio_write(nic->netdev, nic->mii.phy_id, MII_LED_CONTROL, nic->leds);
+ nic->leds = (nic->leds == E100_82552_LED_ON) ?
+ E100_82552_LED_OFF : E100_82552_LED_ON;
+ } else {
+ nic->leds = (nic->leds & led_on) ? led_off :
+ (nic->mac < mac_82559_D101M) ? led_on_557 :
+ led_on_559;
+ }
+ mdio_write(nic->netdev, nic->mii.phy_id, led_reg, nic->leds);
mod_timer(&nic->blink_timer, jiffies + HZ / 4);
}
@@ -2375,13 +2412,15 @@ static void e100_diag_test(struct net_device *netdev,
static int e100_phys_id(struct net_device *netdev, u32 data)
{
struct nic *nic = netdev_priv(netdev);
+ u16 led_reg = (nic->phy == phy_82552_v) ? E100_82552_LED_OVERRIDE :
+ MII_LED_CONTROL;
if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
mod_timer(&nic->blink_timer, jiffies);
msleep_interruptible(data * 1000);
del_timer_sync(&nic->blink_timer);
- mdio_write(netdev, nic->mii.phy_id, MII_LED_CONTROL, 0);
+ mdio_write(netdev, nic->mii.phy_id, led_reg, 0);
return 0;
}
@@ -2686,6 +2725,9 @@ static void __devexit e100_remove(struct pci_dev *pdev)
}
}
+#define E100_82552_SMARTSPEED 0x14 /* SmartSpeed Ctrl register */
+#define E100_82552_REV_ANEG 0x0200 /* Reverse auto-negotiation */
+#define E100_82552_ANEG_NOW 0x0400 /* Auto-negotiate now */
static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
@@ -2698,6 +2740,15 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
pci_save_state(pdev);
if ((nic->flags & wol_magic) | e100_asf(nic)) {
+ /* enable reverse auto-negotiation */
+ if (nic->phy == phy_82552_v) {
+ u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED);
+
+ mdio_write(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED, smartspeed |
+ E100_82552_REV_ANEG | E100_82552_ANEG_NOW);
+ }
if (pci_enable_wake(pdev, PCI_D3cold, true))
pci_enable_wake(pdev, PCI_D3hot, true);
} else {
@@ -2721,6 +2772,16 @@ static int e100_resume(struct pci_dev *pdev)
/* ack any pending wake events, disable PME */
pci_enable_wake(pdev, 0, 0);
+ /* disbale reverse auto-negotiation */
+ if (nic->phy == phy_82552_v) {
+ u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED);
+
+ mdio_write(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED,
+ smartspeed & ~(E100_82552_REV_ANEG));
+ }
+
netif_device_attach(netdev);
if (netif_running(netdev))
e100_up(nic);
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index f5581de0475..e9a416f4016 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -182,7 +182,6 @@ struct e1000_tx_ring {
/* array of buffer information structs */
struct e1000_buffer *buffer_info;
- spinlock_t tx_lock;
u16 tdh;
u16 tdt;
bool last_tx_tso;
@@ -238,7 +237,6 @@ struct e1000_adapter {
u16 link_speed;
u16 link_duplex;
spinlock_t stats_lock;
- spinlock_t tx_queue_lock;
unsigned int total_tx_bytes;
unsigned int total_tx_packets;
unsigned int total_rx_bytes;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 26474c92193..93b861d032b 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -31,7 +31,7 @@
char e1000_driver_name[] = "e1000";
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-#define DRV_VERSION "7.3.20-k3-NAPI"
+#define DRV_VERSION "7.3.21-k3-NAPI"
const char e1000_driver_version[] = DRV_VERSION;
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
@@ -577,12 +577,30 @@ out:
void e1000_down(struct e1000_adapter *adapter)
{
+ struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
+ u32 rctl, tctl;
/* signal that we're down so the interrupt handler does not
* reschedule our watchdog timer */
set_bit(__E1000_DOWN, &adapter->flags);
+ /* disable receives in the hardware */
+ rctl = er32(RCTL);
+ ew32(RCTL, rctl & ~E1000_RCTL_EN);
+ /* flush and sleep below */
+
+ /* can be netif_tx_disable when NETIF_F_LLTX is removed */
+ netif_stop_queue(netdev);
+
+ /* disable transmits in the hardware */
+ tctl = er32(TCTL);
+ tctl &= ~E1000_TCTL_EN;
+ ew32(TCTL, tctl);
+ /* flush both disables and wait for them to finish */
+ E1000_WRITE_FLUSH();
+ msleep(10);
+
napi_disable(&adapter->napi);
e1000_irq_disable(adapter);
@@ -595,7 +613,6 @@ void e1000_down(struct e1000_adapter *adapter)
adapter->link_speed = 0;
adapter->link_duplex = 0;
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
e1000_reset(adapter);
e1000_clean_all_tx_rings(adapter);
@@ -940,7 +957,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
err = pci_enable_device(pdev);
} else {
bars = pci_select_bars(pdev, IORESOURCE_MEM);
- err = pci_enable_device(pdev);
+ err = pci_enable_device_mem(pdev);
}
if (err)
return err;
@@ -1048,8 +1065,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->features |= NETIF_F_LLTX;
-
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
netdev->vlan_features |= NETIF_F_HW_CSUM;
@@ -1368,8 +1383,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
return -ENOMEM;
}
- spin_lock_init(&adapter->tx_queue_lock);
-
/* Explicitly disable IRQ since the NIC can be in any state. */
e1000_irq_disable(adapter);
@@ -1624,7 +1637,6 @@ setup_tx_desc_die:
txdr->next_to_use = 0;
txdr->next_to_clean = 0;
- spin_lock_init(&txdr->tx_lock);
return 0;
}
@@ -1882,8 +1894,6 @@ int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
* e1000_setup_rctl - configure the receive control registers
* @adapter: Board private structure
**/
-#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
- (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
static void e1000_setup_rctl(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
@@ -2056,17 +2066,14 @@ void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info)
{
- if (buffer_info->dma) {
- pci_unmap_page(adapter->pdev,
- buffer_info->dma,
- buffer_info->length,
- PCI_DMA_TODEVICE);
- buffer_info->dma = 0;
- }
+ buffer_info->dma = 0;
if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(buffer_info->skb);
buffer_info->skb = NULL;
}
+ buffer_info->time_stamp = 0;
/* buffer_info must be completely set up in the transmit path */
}
@@ -2865,11 +2872,11 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter,
return false;
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
cmd_len |= E1000_TXD_CMD_TCP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
/* XXX not handling all IPV6 headers */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
cmd_len |= E1000_TXD_CMD_TCP;
@@ -2915,13 +2922,21 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
{
struct e1000_hw *hw = &adapter->hw;
struct e1000_buffer *buffer_info;
- unsigned int len = skb->len;
- unsigned int offset = 0, size, count = 0, i;
+ unsigned int len = skb_headlen(skb);
+ unsigned int offset, size, count = 0, i;
unsigned int f;
- len -= skb->data_len;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+ offset = 0;
+
while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
@@ -2956,18 +2971,18 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
size -= 4;
buffer_info->length = size;
- buffer_info->dma =
- pci_map_single(adapter->pdev,
- skb->data + offset,
- size,
- PCI_DMA_TODEVICE);
+ buffer_info->dma = map[0] + offset;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
len -= size;
offset += size;
count++;
- if (unlikely(++i == tx_ring->count)) i = 0;
+ if (len) {
+ i++;
+ if (unlikely(i == tx_ring->count))
+ i = 0;
+ }
}
for (f = 0; f < nr_frags; f++) {
@@ -2975,9 +2990,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
- offset = frag->page_offset;
+ offset = 0;
while (len) {
+ i++;
+ if (unlikely(i == tx_ring->count))
+ i = 0;
+
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
/* Workaround for premature desc write-backs
@@ -2993,23 +3012,16 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
size -= 4;
buffer_info->length = size;
- buffer_info->dma =
- pci_map_page(adapter->pdev,
- frag->page,
- offset,
- size,
- PCI_DMA_TODEVICE);
+ buffer_info->dma = map[f + 1] + offset;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
len -= size;
offset += size;
count++;
- if (unlikely(++i == tx_ring->count)) i = 0;
}
}
- i = (i == 0) ? tx_ring->count - 1 : i - 1;
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -3185,7 +3197,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0;
unsigned int len = skb->len - skb->data_len;
- unsigned long flags;
unsigned int nr_frags;
unsigned int mss;
int count = 0;
@@ -3290,22 +3301,15 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
(hw->mac_type == e1000_82573))
e1000_transfer_dhcp_info(adapter, skb);
- if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
- /* Collision - tell upper layer to requeue */
- return NETDEV_TX_LOCKED;
-
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
- if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
return NETDEV_TX_BUSY;
- }
if (unlikely(hw->mac_type == e1000_82547)) {
if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
netif_stop_queue(netdev);
mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
}
@@ -3320,7 +3324,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tso = e1000_tso(adapter, tx_ring, skb);
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -3336,16 +3339,21 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (likely(skb->protocol == htons(ETH_P_IP)))
tx_flags |= E1000_TX_FLAGS_IPV4;
- e1000_tx_queue(adapter, tx_ring, tx_flags,
- e1000_tx_map(adapter, tx_ring, skb, first,
- max_per_txd, nr_frags, mss));
+ count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
+ nr_frags, mss);
- netdev->trans_start = jiffies;
+ 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);
- /* Make sure there is space in the ring for the next send. */
- e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+ } else {
+ dev_kfree_skb_any(skb);
+ tx_ring->buffer_info[first].time_stamp = 0;
+ tx_ring->next_to_use = first;
+ }
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -3687,12 +3695,12 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (likely(netif_rx_schedule_prep(&adapter->napi))) {
+ if (likely(napi_schedule_prep(&adapter->napi))) {
adapter->total_tx_bytes = 0;
adapter->total_tx_packets = 0;
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
} else
e1000_irq_enable(adapter);
@@ -3712,7 +3720,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
struct e1000_hw *hw = &adapter->hw;
u32 rctl, icr = er32(ICR);
- if (unlikely(!icr))
+ if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags)))
return IRQ_NONE; /* Not our interrupt */
/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
@@ -3747,16 +3755,18 @@ static irqreturn_t e1000_intr(int irq, void *data)
ew32(IMC, ~0);
E1000_WRITE_FLUSH();
}
- if (likely(netif_rx_schedule_prep(&adapter->napi))) {
+ if (likely(napi_schedule_prep(&adapter->napi))) {
adapter->total_tx_bytes = 0;
adapter->total_tx_packets = 0;
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
- } else
+ __napi_schedule(&adapter->napi);
+ } else {
/* this really should not happen! if it does it is basically a
* bug, but not a hard error, so enable ints and continue */
- e1000_irq_enable(adapter);
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ e1000_irq_enable(adapter);
+ }
return IRQ_HANDLED;
}
@@ -3773,28 +3783,21 @@ static int e1000_clean(struct napi_struct *napi, int budget)
adapter = netdev_priv(poll_dev);
- /* e1000_clean is called per-cpu. This lock protects
- * tx_ring[0] from being cleaned by multiple cpus
- * simultaneously. A failure obtaining the lock means
- * tx_ring[0] is currently being cleaned anyway. */
- if (spin_trylock(&adapter->tx_queue_lock)) {
- tx_cleaned = e1000_clean_tx_irq(adapter,
- &adapter->tx_ring[0]);
- spin_unlock(&adapter->tx_queue_lock);
- }
+ tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
adapter->clean_rx(adapter, &adapter->rx_ring[0],
&work_done, budget);
- if (tx_cleaned)
+ if (!tx_cleaned)
work_done = budget;
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
if (likely(adapter->itr_setting & 3))
e1000_set_itr(adapter);
- netif_rx_complete(napi);
- e1000_irq_enable(adapter);
+ napi_complete(napi);
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ e1000_irq_enable(adapter);
}
return work_done;
@@ -3813,15 +3816,16 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info;
unsigned int i, eop;
unsigned int count = 0;
- bool cleaned = false;
+ bool cleaned;
unsigned int total_tx_bytes=0, total_tx_packets=0;
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
- while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
- for (cleaned = false; !cleaned; ) {
+ while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+ (count < tx_ring->count)) {
+ for (cleaned = false; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop);
@@ -3844,10 +3848,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#define E1000_TX_WEIGHT 64
- /* weight of a sort for tx, to avoid endless transmit cleanup */
- if (count++ == E1000_TX_WEIGHT)
- break;
}
tx_ring->next_to_clean = i;
@@ -3869,8 +3869,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
/* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = false;
- if (tx_ring->buffer_info[eop].dma &&
- time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
+ if (tx_ring->buffer_info[i].time_stamp &&
+ time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
(adapter->tx_timeout_factor * HZ))
&& !(er32(STATUS) & E1000_STATUS_TXOFF)) {
@@ -3892,7 +3892,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
readl(hw->hw_addr + tx_ring->tdt),
tx_ring->next_to_use,
tx_ring->next_to_clean,
- tx_ring->buffer_info[eop].time_stamp,
+ tx_ring->buffer_info[i].time_stamp,
eop,
jiffies,
eop_desc->upper.fields.status);
@@ -3903,7 +3903,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
adapter->total_tx_packets += total_tx_packets;
adapter->net_stats.tx_bytes += total_tx_bytes;
adapter->net_stats.tx_packets += total_tx_packets;
- return cleaned;
+ return (count < tx_ring->count);
}
/**
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index cf43ee743b3..6c01a2072c8 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -40,6 +40,7 @@
* 82573E Gigabit Ethernet Controller (Copper)
* 82573L Gigabit Ethernet Controller
* 82574L Gigabit Network Connection
+ * 82583V Gigabit Network Connection
*/
#include <linux/netdevice.h>
@@ -61,6 +62,7 @@
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
+static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw);
static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
@@ -99,6 +101,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
phy->type = e1000_phy_m88;
break;
case e1000_82574:
+ case e1000_82583:
phy->type = e1000_phy_bm;
break;
default:
@@ -121,6 +124,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
return -E1000_ERR_PHY;
break;
case e1000_82574:
+ case e1000_82583:
if (phy->id != BME1000_E_PHY_ID_R2)
return -E1000_ERR_PHY;
break;
@@ -164,6 +168,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_82573:
case e1000_82574:
+ case e1000_82583:
if (((eecd >> 15) & 0x3) == 0x3) {
nvm->type = e1000_nvm_flash_hw;
nvm->word_size = 2048;
@@ -250,7 +255,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
case e1000_media_type_internal_serdes:
func->setup_physical_interface =
e1000_setup_fiber_serdes_link_82571;
- func->check_for_link = e1000e_check_for_serdes_link;
+ func->check_for_link = e1000_check_for_serdes_link_82571;
func->get_link_up_info =
e1000e_get_speed_and_duplex_fiber_serdes;
break;
@@ -261,6 +266,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
switch (hw->mac.type) {
case e1000_82574:
+ case e1000_82583:
func->check_mng_mode = e1000_check_mng_mode_82574;
func->led_on = e1000_led_on_82574;
break;
@@ -374,6 +380,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
return e1000e_get_phy_id(hw);
break;
case e1000_82574:
+ case e1000_82583:
ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
if (ret_val)
return ret_val;
@@ -463,8 +470,15 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
if (ret_val)
return ret_val;
- if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574)
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ break;
+ default:
ret_val = e1000e_acquire_nvm(hw);
+ break;
+ }
if (ret_val)
e1000_put_hw_semaphore_82571(hw);
@@ -504,6 +518,7 @@ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
switch (hw->mac.type) {
case e1000_82573:
case e1000_82574:
+ case e1000_82583:
ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data);
break;
case e1000_82571:
@@ -778,7 +793,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
* Must acquire the MDIO ownership before MAC reset.
* Ownership defaults to firmware after a reset.
*/
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
extcnf_ctrl = er32(EXTCNF_CTRL);
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
@@ -794,6 +812,9 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
msleep(2);
i++;
} while (i < MDIO_OWNERSHIP_TIMEOUT);
+ break;
+ default:
+ break;
}
ctrl = er32(CTRL);
@@ -819,8 +840,16 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
* Need to wait for Phy configuration completion before accessing
* NVM and Phy.
*/
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574)
+
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
msleep(25);
+ break;
+ default:
+ break;
+ }
/* Clear any pending interrupt events. */
ew32(IMC, 0xffffffff);
@@ -830,6 +859,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
hw->dev_spec.e82571.alt_mac_addr_is_present)
e1000e_set_laa_state_82571(hw, true);
+ /* Reinitialize the 82571 serdes link state machine */
+ if (hw->phy.media_type == e1000_media_type_internal_serdes)
+ hw->mac.serdes_link_state = e1000_serdes_link_down;
+
return 0;
}
@@ -886,17 +919,22 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
ew32(TXDCTL(0), reg_data);
/* ...for both queues. */
- if (mac->type != e1000_82573 && mac->type != e1000_82574) {
+ switch (mac->type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ e1000e_enable_tx_pkt_filtering(hw);
+ reg_data = er32(GCR);
+ reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
+ ew32(GCR, reg_data);
+ break;
+ default:
reg_data = er32(TXDCTL(1));
reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
E1000_TXDCTL_FULL_TX_DESC_WB |
E1000_TXDCTL_COUNT_DESC;
ew32(TXDCTL(1), reg_data);
- } else {
- e1000e_enable_tx_pkt_filtering(hw);
- reg_data = er32(GCR);
- reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
- ew32(GCR, reg_data);
+ break;
}
/*
@@ -961,18 +999,30 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
}
/* Device Control */
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
reg = er32(CTRL);
reg &= ~(1 << 29);
ew32(CTRL, reg);
+ break;
+ default:
+ break;
}
/* Extended Device Control */
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
reg = er32(CTRL_EXT);
reg &= ~(1 << 23);
reg |= (1 << 22);
ew32(CTRL_EXT, reg);
+ break;
+ default:
+ break;
}
if (hw->mac.type == e1000_82571) {
@@ -980,12 +1030,33 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
reg |= E1000_PBA_ECC_CORR_EN;
ew32(PBA_ECC, reg);
}
+ /*
+ * Workaround for hardware errata.
+ * Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572
+ */
+
+ if ((hw->mac.type == e1000_82571) ||
+ (hw->mac.type == e1000_82572)) {
+ reg = er32(CTRL_EXT);
+ reg &= ~E1000_CTRL_EXT_DMA_DYN_CLK_EN;
+ ew32(CTRL_EXT, reg);
+ }
- /* PCI-Ex Control Register */
- if (hw->mac.type == e1000_82574) {
+
+ /* PCI-Ex Control Registers */
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82583:
reg = er32(GCR);
reg |= (1 << 22);
ew32(GCR, reg);
+
+ reg = er32(GCR2);
+ reg |= 1;
+ ew32(GCR2, reg);
+ break;
+ default:
+ break;
}
return;
@@ -1005,7 +1076,10 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
u32 vfta_offset = 0;
u32 vfta_bit_in_reg = 0;
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
if (hw->mng_cookie.vlan_id != 0) {
/*
* The VFTA is a 4096b bit-field, each identifying
@@ -1020,6 +1094,9 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
}
+ break;
+ default:
+ break;
}
for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
/*
@@ -1118,9 +1195,16 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
* the default flow control setting, so we explicitly
* set it to full.
*/
- if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
- hw->fc.requested_mode == e1000_fc_default)
- hw->fc.requested_mode = e1000_fc_full;
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ if (hw->fc.requested_mode == e1000_fc_default)
+ hw->fc.requested_mode = e1000_fc_full;
+ break;
+ default:
+ break;
+ }
return e1000e_setup_link(hw);
}
@@ -1199,6 +1283,131 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
}
/**
+ * e1000_check_for_serdes_link_82571 - Check for link (Serdes)
+ * @hw: pointer to the HW structure
+ *
+ * Checks for link up on the hardware. If link is not up and we have
+ * a signal, then we need to force link up.
+ **/
+static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+ u32 rxcw;
+ u32 ctrl;
+ u32 status;
+ s32 ret_val = 0;
+
+ ctrl = er32(CTRL);
+ status = er32(STATUS);
+ rxcw = er32(RXCW);
+
+ if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) {
+
+ /* Receiver is synchronized with no invalid bits. */
+ switch (mac->serdes_link_state) {
+ case e1000_serdes_link_autoneg_complete:
+ if (!(status & E1000_STATUS_LU)) {
+ /*
+ * We have lost link, retry autoneg before
+ * reporting link failure
+ */
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ hw_dbg(hw, "AN_UP -> AN_PROG\n");
+ }
+ break;
+
+ case e1000_serdes_link_forced_up:
+ /*
+ * If we are receiving /C/ ordered sets, re-enable
+ * auto-negotiation in the TXCW register and disable
+ * forced link in the Device Control register in an
+ * attempt to auto-negotiate with our link partner.
+ */
+ if (rxcw & E1000_RXCW_C) {
+ /* Enable autoneg, and unforce link up */
+ ew32(TXCW, mac->txcw);
+ ew32(CTRL,
+ (ctrl & ~E1000_CTRL_SLU));
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ hw_dbg(hw, "FORCED_UP -> AN_PROG\n");
+ }
+ break;
+
+ case e1000_serdes_link_autoneg_progress:
+ /*
+ * If the LU bit is set in the STATUS register,
+ * autoneg has completed sucessfully. If not,
+ * try foring the link because the far end may be
+ * available but not capable of autonegotiation.
+ */
+ if (status & E1000_STATUS_LU) {
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_complete;
+ hw_dbg(hw, "AN_PROG -> AN_UP\n");
+ } else {
+ /*
+ * Disable autoneg, force link up and
+ * full duplex, and change state to forced
+ */
+ ew32(TXCW,
+ (mac->txcw & ~E1000_TXCW_ANE));
+ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+ ew32(CTRL, ctrl);
+
+ /* Configure Flow Control after link up. */
+ ret_val =
+ e1000e_config_fc_after_link_up(hw);
+ if (ret_val) {
+ hw_dbg(hw, "Error config flow control\n");
+ break;
+ }
+ mac->serdes_link_state =
+ e1000_serdes_link_forced_up;
+ hw_dbg(hw, "AN_PROG -> FORCED_UP\n");
+ }
+ mac->serdes_has_link = true;
+ break;
+
+ case e1000_serdes_link_down:
+ default:
+ /* The link was down but the receiver has now gained
+ * valid sync, so lets see if we can bring the link
+ * up. */
+ ew32(TXCW, mac->txcw);
+ ew32(CTRL,
+ (ctrl & ~E1000_CTRL_SLU));
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ hw_dbg(hw, "DOWN -> AN_PROG\n");
+ break;
+ }
+ } else {
+ if (!(rxcw & E1000_RXCW_SYNCH)) {
+ mac->serdes_has_link = false;
+ mac->serdes_link_state = e1000_serdes_link_down;
+ hw_dbg(hw, "ANYSTATE -> DOWN\n");
+ } else {
+ /*
+ * We have sync, and can tolerate one
+ * invalid (IV) codeword before declaring
+ * link down, so reread to look again
+ */
+ udelay(10);
+ rxcw = er32(RXCW);
+ if (rxcw & E1000_RXCW_IV) {
+ mac->serdes_link_state = e1000_serdes_link_down;
+ mac->serdes_has_link = false;
+ hw_dbg(hw, "ANYSTATE -> DOWN\n");
+ }
+ }
+ }
+
+ return ret_val;
+}
+
+/**
* e1000_valid_led_default_82571 - Verify a valid default LED config
* @hw: pointer to the HW structure
* @data: pointer to the NVM (EEPROM)
@@ -1216,11 +1425,19 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
return ret_val;
}
- if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
- *data == ID_LED_RESERVED_F746)
- *data = ID_LED_DEFAULT_82573;
- else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
- *data = ID_LED_DEFAULT;
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ if (*data == ID_LED_RESERVED_F746)
+ *data = ID_LED_DEFAULT_82573;
+ break;
+ default:
+ if (*data == ID_LED_RESERVED_0000 ||
+ *data == ID_LED_RESERVED_FFFF)
+ *data = ID_LED_DEFAULT;
+ break;
+ }
return 0;
}
@@ -1513,3 +1730,19 @@ struct e1000_info e1000_82574_info = {
.nvm_ops = &e82571_nvm_ops,
};
+struct e1000_info e1000_82583_info = {
+ .mac = e1000_82583,
+ .flags = FLAG_HAS_HW_VLAN_FILTER
+ | FLAG_HAS_WOL
+ | FLAG_APME_IN_CTRL3
+ | FLAG_RX_CSUM_ENABLED
+ | FLAG_HAS_SMART_POWER_DOWN
+ | FLAG_HAS_AMT
+ | FLAG_HAS_CTRLEXT_ON_LOAD,
+ .pba = 20,
+ .get_variants = e1000_get_variants_82571,
+ .mac_ops = &e82571_mac_ops,
+ .phy_ops = &e82_phy_ops_bm,
+ .nvm_ops = &e82571_nvm_ops,
+};
+
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index e6caf29d425..243aa499fe9 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -69,6 +69,7 @@
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
+#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
#define E1000_CTRL_EXT_EIAME 0x01000000
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 37bcb190eef..f37360aa12a 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -101,6 +101,7 @@ enum e1000_boards {
board_82572,
board_82573,
board_82574,
+ board_82583,
board_80003es2lan,
board_ich8lan,
board_ich9lan,
@@ -195,8 +196,6 @@ struct e1000_adapter {
u16 link_duplex;
u16 eeprom_vers;
- spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
-
/* track device up/down/testing state */
unsigned long state;
@@ -401,6 +400,7 @@ extern struct e1000_info e1000_82571_info;
extern struct e1000_info e1000_82572_info;
extern struct e1000_info e1000_82573_info;
extern struct e1000_info e1000_82574_info;
+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;
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index e48956d924b..4d25ede8836 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -790,6 +790,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
break;
case e1000_82573:
case e1000_82574:
+ case e1000_82583:
case e1000_ich8lan:
case e1000_ich9lan:
case e1000_ich10lan:
@@ -1589,7 +1590,7 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
*data = 0;
if (hw->phy.media_type == e1000_media_type_internal_serdes) {
int i = 0;
- hw->mac.serdes_has_link = 0;
+ hw->mac.serdes_has_link = false;
/*
* On some blade server designs, link establishment
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index f25e961c6b3..d8b82296f41 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -206,6 +206,7 @@ enum e1e_registers {
E1000_MANC2H = 0x05860, /* Management Control To Host - RW */
E1000_SW_FW_SYNC = 0x05B5C, /* Software-Firmware Synchronization - RW */
E1000_GCR = 0x05B00, /* PCI-Ex Control */
+ E1000_GCR2 = 0x05B64, /* PCI-Ex Control #2 */
E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
E1000_SWSM = 0x05B50, /* SW Semaphore */
E1000_FWSM = 0x05B54, /* FW Semaphore */
@@ -338,6 +339,8 @@ enum e1e_registers {
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
#define E1000_DEV_ID_82574L 0x10D3
+#define E1000_DEV_ID_82574LA 0x10F6
+#define E1000_DEV_ID_82583V 0x150C
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
@@ -375,6 +378,7 @@ enum e1000_mac_type {
e1000_82572,
e1000_82573,
e1000_82574,
+ e1000_82583,
e1000_80003es2lan,
e1000_ich8lan,
e1000_ich9lan,
@@ -458,6 +462,13 @@ enum e1000_smart_speed {
e1000_smart_speed_off
};
+enum e1000_serdes_link_state {
+ e1000_serdes_link_down = 0,
+ e1000_serdes_link_autoneg_progress,
+ e1000_serdes_link_autoneg_complete,
+ e1000_serdes_link_forced_up
+};
+
/* Receive Descriptor */
struct e1000_rx_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
@@ -786,6 +797,7 @@ struct e1000_mac_info {
bool in_ifs_mode;
bool serdes_has_link;
bool tx_pkt_filtering;
+ enum e1000_serdes_link_state serdes_link_state;
};
struct e1000_phy_info {
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index e415e81ecd3..6d1aab6316b 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -390,8 +390,6 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
}
static DEFINE_MUTEX(nvm_mutex);
-static pid_t nvm_owner_pid = -1;
-static char nvm_owner_name[TASK_COMM_LEN] = "";
/**
* e1000_acquire_swflag_ich8lan - Acquire software control flag
@@ -408,16 +406,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
might_sleep();
- if (!mutex_trylock(&nvm_mutex)) {
- WARN(1, KERN_ERR "e1000e mutex contention. Owned by process "
- "%s (pid %d), required by process %s (pid %d)\n",
- nvm_owner_name, nvm_owner_pid,
- current->comm, current->pid);
-
- mutex_lock(&nvm_mutex);
- }
- nvm_owner_pid = current->pid;
- strncpy(nvm_owner_name, current->comm, TASK_COMM_LEN);
+ mutex_lock(&nvm_mutex);
while (timeout) {
extcnf_ctrl = er32(EXTCNF_CTRL);
@@ -435,8 +424,6 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
ew32(EXTCNF_CTRL, extcnf_ctrl);
- nvm_owner_pid = -1;
- strcpy(nvm_owner_name, "");
mutex_unlock(&nvm_mutex);
return -E1000_ERR_CONFIG;
}
@@ -460,8 +447,6 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
ew32(EXTCNF_CTRL, extcnf_ctrl);
- nvm_owner_pid = -1;
- strcpy(nvm_owner_name, "");
mutex_unlock(&nvm_mutex);
}
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 66741104ffd..18a4f5902f3 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -159,41 +159,6 @@ void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
}
/**
- * e1000_mta_set - Set multicast filter table address
- * @hw: pointer to the HW structure
- * @hash_value: determines the MTA register and bit to set
- *
- * The multicast table address is a register array of 32-bit registers.
- * The hash_value is used to determine what register the bit is in, the
- * current value is read, the new bit is OR'd in and the new value is
- * written back into the register.
- **/
-static void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
-{
- u32 hash_bit, hash_reg, mta;
-
- /*
- * The MTA is a register array of 32-bit registers. It is
- * treated like an array of (32*mta_reg_count) bits. We want to
- * set bit BitArray[hash_value]. So we figure out what register
- * the bit is in, read it, OR in the new bit, then write
- * back the new value. The (hw->mac.mta_reg_count - 1) serves as a
- * mask to bits 31:5 of the hash value which gives us the
- * register we're modifying. The hash bit within that register
- * is determined by the lower 5 bits of the hash value.
- */
- hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
- hash_bit = hash_value & 0x1F;
-
- mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg);
-
- mta |= (1 << hash_bit);
-
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta);
- e1e_flush();
-}
-
-/**
* e1000_hash_mc_addr - Generate a multicast hash value
* @hw: pointer to the HW structure
* @mc_addr: pointer to a multicast address
@@ -281,8 +246,13 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count)
{
- u32 hash_value;
u32 i;
+ u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC);
+
+ if (!mcarray) {
+ printk(KERN_ERR "multicast array memory allocation failed\n");
+ return;
+ }
/*
* Load the first set of multicast addresses into the exact
@@ -302,20 +272,24 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
}
}
- /* Clear the old settings from the MTA */
- hw_dbg(hw, "Clearing MTA\n");
- for (i = 0; i < hw->mac.mta_reg_count; i++) {
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
- e1e_flush();
- }
-
/* Load any remaining multicast addresses into the hash table. */
for (; mc_addr_count > 0; mc_addr_count--) {
+ u32 hash_value, hash_reg, hash_bit, mta;
hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
hw_dbg(hw, "Hash value = 0x%03X\n", hash_value);
- e1000_mta_set(hw, hash_value);
+ hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+ hash_bit = hash_value & 0x1F;
+ mta = (1 << hash_bit);
+ mcarray[hash_reg] |= mta;
mc_addr_list += ETH_ALEN;
}
+
+ /* write the hash table completely */
+ for (i = 0; i < hw->mac.mta_reg_count; i++)
+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]);
+
+ e1e_flush();
+ kfree(mcarray);
}
/**
@@ -501,7 +475,7 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
ew32(TXCW, mac->txcw);
ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
- mac->serdes_has_link = 1;
+ mac->serdes_has_link = true;
}
return 0;
@@ -566,7 +540,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
ew32(TXCW, mac->txcw);
ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
- mac->serdes_has_link = 1;
+ mac->serdes_has_link = true;
} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
/*
* If we force link for non-auto-negotiation switch, check
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 91817d0afca..bfb2d6c85c5 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -44,10 +44,11 @@
#include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/pm_qos_params.h>
+#include <linux/aer.h>
#include "e1000.h"
-#define DRV_VERSION "0.3.3.3-k6"
+#define DRV_VERSION "0.3.3.4-k4"
char e1000e_driver_name[] = "e1000e";
const char e1000e_driver_version[] = DRV_VERSION;
@@ -56,6 +57,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
[board_82572] = &e1000_82572_info,
[board_82573] = &e1000_82573_info,
[board_82574] = &e1000_82574_info,
+ [board_82583] = &e1000_82583_info,
[board_80003es2lan] = &e1000_es2_info,
[board_ich8lan] = &e1000_ich8_info,
[board_ich9lan] = &e1000_ich9_info,
@@ -99,8 +101,8 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
skb->protocol = eth_type_trans(skb, netdev);
if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(vlan));
+ vlan_gro_receive(&adapter->napi, adapter->vlgrp,
+ le16_to_cpu(vlan), skb);
else
napi_gro_receive(&adapter->napi, skb);
}
@@ -565,15 +567,14 @@ next_desc:
static void e1000_put_txbuf(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info)
{
- if (buffer_info->dma) {
- pci_unmap_page(adapter->pdev, buffer_info->dma,
- buffer_info->length, PCI_DMA_TODEVICE);
- buffer_info->dma = 0;
- }
+ buffer_info->dma = 0;
if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(buffer_info->skb);
buffer_info->skb = NULL;
}
+ buffer_info->time_stamp = 0;
}
static void e1000_print_tx_hang(struct e1000_adapter *adapter)
@@ -620,15 +621,16 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
struct e1000_buffer *buffer_info;
unsigned int i, eop;
unsigned int count = 0;
- bool cleaned = 0;
+ bool cleaned;
unsigned int total_tx_bytes = 0, total_tx_packets = 0;
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
- while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
- for (cleaned = 0; !cleaned; ) {
+ while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+ (count < tx_ring->count)) {
+ for (cleaned = 0; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop);
@@ -654,10 +656,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#define E1000_TX_WEIGHT 64
- /* weight of a sort for tx, to avoid endless transmit cleanup */
- if (count++ == E1000_TX_WEIGHT)
- break;
}
tx_ring->next_to_clean = i;
@@ -678,13 +676,11 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
}
if (adapter->detect_tx_hung) {
- /*
- * Detect a transmit hang in hardware, this serializes the
- * check with the clearing of time_stamp and movement of i
- */
+ /* Detect a transmit hang in hardware, this serializes the
+ * check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = 0;
- if (tx_ring->buffer_info[eop].dma &&
- time_after(jiffies, tx_ring->buffer_info[eop].time_stamp
+ if (tx_ring->buffer_info[i].time_stamp &&
+ time_after(jiffies, tx_ring->buffer_info[i].time_stamp
+ (adapter->tx_timeout_factor * HZ))
&& !(er32(STATUS) & E1000_STATUS_TXOFF)) {
e1000_print_tx_hang(adapter);
@@ -695,7 +691,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
adapter->total_tx_packets += total_tx_packets;
adapter->net_stats.tx_bytes += total_tx_bytes;
adapter->net_stats.tx_packets += total_tx_packets;
- return cleaned;
+ return (count < tx_ring->count);
}
/**
@@ -1152,7 +1148,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
* read ICR disables interrupts using IAM
*/
- if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ if (icr & E1000_ICR_LSC) {
hw->mac.get_link_status = 1;
/*
* ICH8 workaround-- Call gig speed drop workaround on cable
@@ -1179,12 +1175,12 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
adapter->total_tx_bytes = 0;
adapter->total_tx_packets = 0;
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
@@ -1218,7 +1214,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
* IMC write
*/
- if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ if (icr & E1000_ICR_LSC) {
hw->mac.get_link_status = 1;
/*
* ICH8 workaround-- Call gig speed drop workaround on cable
@@ -1246,12 +1242,12 @@ static irqreturn_t e1000_intr(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
adapter->total_tx_bytes = 0;
adapter->total_tx_packets = 0;
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
@@ -1265,7 +1261,8 @@ static irqreturn_t e1000_msix_other(int irq, void *data)
u32 icr = er32(ICR);
if (!(icr & E1000_ICR_INT_ASSERTED)) {
- ew32(IMS, E1000_IMS_OTHER);
+ if (!test_bit(__E1000_DOWN, &adapter->state))
+ ew32(IMS, E1000_IMS_OTHER);
return IRQ_NONE;
}
@@ -1282,7 +1279,8 @@ static irqreturn_t e1000_msix_other(int irq, void *data)
}
no_link_interrupt:
- ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
+ if (!test_bit(__E1000_DOWN, &adapter->state))
+ ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
return IRQ_HANDLED;
}
@@ -1320,10 +1318,10 @@ static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
adapter->rx_ring->set_itr = 0;
}
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
}
@@ -1698,7 +1696,6 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- spin_lock_init(&adapter->tx_queue_lock);
return 0;
err:
@@ -2007,32 +2004,25 @@ static int e1000_clean(struct napi_struct *napi, int budget)
!(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
goto clean_rx;
- /*
- * e1000_clean is called per-cpu. This lock protects
- * tx_ring from being cleaned by multiple cpus
- * simultaneously. A failure obtaining the lock means
- * tx_ring is currently being cleaned anyway.
- */
- if (spin_trylock(&adapter->tx_queue_lock)) {
- tx_cleaned = e1000_clean_tx_irq(adapter);
- spin_unlock(&adapter->tx_queue_lock);
- }
+ tx_cleaned = e1000_clean_tx_irq(adapter);
clean_rx:
adapter->clean_rx(adapter, &work_done, budget);
- if (tx_cleaned)
+ if (!tx_cleaned)
work_done = budget;
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
if (adapter->itr_setting & 3)
e1000_set_itr(adapter);
- netif_rx_complete(napi);
- if (adapter->msix_entries)
- ew32(IMS, adapter->rx_ring->ims_val);
- else
- e1000_irq_enable(adapter);
+ napi_complete(napi);
+ if (!test_bit(__E1000_DOWN, &adapter->state)) {
+ if (adapter->msix_entries)
+ ew32(IMS, adapter->rx_ring->ims_val);
+ else
+ e1000_irq_enable(adapter);
+ }
}
return work_done;
@@ -2922,8 +2912,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
if (e1000_alloc_queues(adapter))
return -ENOMEM;
- spin_lock_init(&adapter->tx_queue_lock);
-
/* Explicitly disable IRQ since the NIC can be in any state. */
e1000_irq_disable(adapter);
@@ -3320,7 +3308,7 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
adapter->stats.algnerrc += er32(ALGNERRC);
adapter->stats.rxerrc += er32(RXERRC);
- if (hw->mac.type != e1000_82574)
+ 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);
@@ -3777,23 +3765,30 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
unsigned int i;
u8 css;
u32 cmd_len = E1000_TXD_CMD_DEXT;
+ __be16 protocol;
if (skb->ip_summed != CHECKSUM_PARTIAL)
return 0;
- switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
+ protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+ else
+ protocol = skb->protocol;
+
+ switch (protocol) {
+ case cpu_to_be16(ETH_P_IP):
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
cmd_len |= E1000_TXD_CMD_TCP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
/* XXX not handling all IPV6 headers */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
cmd_len |= E1000_TXD_CMD_TCP;
break;
default:
if (unlikely(net_ratelimit()))
- e_warn("checksum_partial proto=%x!\n", skb->protocol);
+ e_warn("checksum_partial proto=%x!\n",
+ be16_to_cpu(protocol));
break;
}
@@ -3832,42 +3827,40 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
{
struct e1000_ring *tx_ring = adapter->tx_ring;
struct e1000_buffer *buffer_info;
- unsigned int len = skb->len - skb->data_len;
- unsigned int offset = 0, size, count = 0, i;
+ unsigned int len = skb_headlen(skb);
+ unsigned int offset, size, count = 0, i;
unsigned int f;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ adapter->tx_dma_failed++;
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+ offset = 0;
+
while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
- /* Workaround for premature desc write-backs
- * in TSO mode. Append 4-byte sentinel desc */
- if (mss && !nr_frags && size == len && size > 8)
- size -= 4;
-
buffer_info->length = size;
- /* set time_stamp *before* dma to help avoid a possible race */
buffer_info->time_stamp = jiffies;
- buffer_info->dma =
- pci_map_single(adapter->pdev,
- skb->data + offset,
- size,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) {
- dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
- adapter->tx_dma_failed++;
- return -1;
- }
buffer_info->next_to_watch = i;
+ buffer_info->dma = map[0] + offset;
+ count++;
len -= size;
offset += size;
- count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
+
+ if (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ }
}
for (f = 0; f < nr_frags; f++) {
@@ -3875,49 +3868,27 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
- offset = frag->page_offset;
+ offset = 0;
while (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
- /* Workaround for premature desc write-backs
- * in TSO mode. Append 4-byte sentinel desc */
- if (mss && f == (nr_frags-1) && size == len && size > 8)
- size -= 4;
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
- buffer_info->dma =
- pci_map_page(adapter->pdev,
- frag->page,
- offset,
- size,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(adapter->pdev,
- buffer_info->dma)) {
- dev_err(&adapter->pdev->dev,
- "TX DMA page map failed\n");
- adapter->tx_dma_failed++;
- return -1;
- }
-
buffer_info->next_to_watch = i;
+ buffer_info->dma = map[f + 1] + offset;
len -= size;
offset += size;
count++;
-
- i++;
- if (i == tx_ring->count)
- i = 0;
}
}
- if (i == 0)
- i = tx_ring->count - 1;
- else
- i--;
-
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -4069,7 +4040,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0;
unsigned int len = skb->len - skb->data_len;
- unsigned long irq_flags;
unsigned int nr_frags;
unsigned int mss;
int count = 0;
@@ -4138,18 +4108,12 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (adapter->hw.mac.tx_pkt_filtering)
e1000_transfer_dhcp_info(adapter, skb);
- if (!spin_trylock_irqsave(&adapter->tx_queue_lock, irq_flags))
- /* Collision - tell upper layer to requeue */
- return NETDEV_TX_LOCKED;
-
/*
* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time
*/
- if (e1000_maybe_stop_tx(netdev, count + 2)) {
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
+ if (e1000_maybe_stop_tx(netdev, count + 2))
return NETDEV_TX_BUSY;
- }
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= E1000_TX_FLAGS_VLAN;
@@ -4161,7 +4125,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tso = e1000_tso(adapter, skb);
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
return NETDEV_TX_OK;
}
@@ -4178,22 +4141,20 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (skb->protocol == htons(ETH_P_IP))
tx_flags |= E1000_TX_FLAGS_IPV4;
+ /* if count is 0 then mapping error has occured */
count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
- if (count < 0) {
- /* handle pci_map_single() error in e1000_tx_map */
+ 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);
+
+ } else {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
- return NETDEV_TX_OK;
+ tx_ring->buffer_info[first].time_stamp = 0;
+ tx_ring->next_to_use = first;
}
- 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);
-
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
return NETDEV_TX_OK;
}
@@ -4543,6 +4504,14 @@ static int e1000_resume(struct pci_dev *pdev)
return err;
}
+ /* AER (Advanced Error Reporting) hooks */
+ err = pci_enable_pcie_error_reporting(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
+ "0x%x\n", err);
+ /* non-fatal, continue */
+ }
+
pci_set_master(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
@@ -4637,24 +4606,29 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
int err;
+ pci_ers_result_t result;
e1000e_disable_l1aspm(pdev);
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
- return PCI_ERS_RESULT_DISCONNECT;
- }
- pci_set_master(pdev);
- pci_restore_state(pdev);
+ result = PCI_ERS_RESULT_DISCONNECT;
+ } else {
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
- e1000e_reset(adapter);
- ew32(WUS, ~0);
+ e1000e_reset(adapter);
+ ew32(WUS, ~0);
+ result = PCI_ERS_RESULT_RECOVERED;
+ }
+
+ pci_cleanup_aer_uncorrect_error_status(pdev);
- return PCI_ERS_RESULT_RECOVERED;
+ return result;
}
/**
@@ -4922,12 +4896,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- /*
- * We should not be using LLTX anymore, but we are still Tx faster with
- * it.
- */
- netdev->features |= NETIF_F_LLTX;
-
if (e1000e_enable_mng_pass_thru(&adapter->hw))
adapter->flags |= FLAG_MNG_PT_ENABLED;
@@ -5091,6 +5059,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
+ int err;
/*
* flush_scheduled work may reschedule our watchdog task, so
@@ -5125,6 +5094,12 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
free_netdev(netdev);
+ /* AER disable */
+ err = pci_disable_pcie_error_reporting(pdev);
+ if (err)
+ dev_err(&pdev->dev,
+ "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+
pci_disable_device(pdev);
}
@@ -5156,6 +5131,8 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
board_80003es2lan },
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
index b07ba1924de..d2f6ee1a629 100644
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -216,13 +216,13 @@ static int __init e21_probe1(struct net_device *dev, int ioaddr)
printk(" %02X", station_addr[i]);
if (dev->irq < 2) {
- int irqlist[] = {15,11,10,12,5,9,3,4}, i;
- for (i = 0; i < 8; i++)
+ int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4};
+ for (i = 0; i < ARRAY_SIZE(irqlist); i++)
if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
dev->irq = irqlist[i];
break;
}
- if (i >= 8) {
+ if (i >= ARRAY_SIZE(irqlist)) {
printk(" unable to get IRQ %d.\n", dev->irq);
retval = -EAGAIN;
goto out;
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 6271b9411cc..6e317caf429 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0096"
+#define DRV_VERSION "EHEA_0100"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index dfe92264e82..ac0c5b438e0 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -155,6 +155,8 @@ static void ehea_update_firmware_handles(void)
int num_fw_handles, k, l;
/* Determine number of handles */
+ mutex_lock(&ehea_fw_handles.lock);
+
list_for_each_entry(adapter, &adapter_list, list) {
num_adapters++;
@@ -176,15 +178,19 @@ static void ehea_update_firmware_handles(void)
if (num_fw_handles) {
arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
if (!arr)
- return; /* Keep the existing array */
+ goto out; /* Keep the existing array */
} else
goto out_update;
list_for_each_entry(adapter, &adapter_list, list) {
+ if (num_adapters == 0)
+ break;
+
for (k = 0; k < EHEA_MAX_PORTS; k++) {
struct ehea_port *port = adapter->port[k];
- if (!port || (port->state != EHEA_PORT_UP))
+ if (!port || (port->state != EHEA_PORT_UP)
+ || (num_ports == 0))
continue;
for (l = 0;
@@ -207,6 +213,7 @@ static void ehea_update_firmware_handles(void)
}
arr[i].adh = adapter->handle;
arr[i++].fwh = port->qp_eq->fw_handle;
+ num_ports--;
}
arr[i].adh = adapter->handle;
@@ -216,16 +223,20 @@ static void ehea_update_firmware_handles(void)
arr[i].adh = adapter->handle;
arr[i++].fwh = adapter->mr.handle;
}
+ num_adapters--;
}
out_update:
kfree(ehea_fw_handles.arr);
ehea_fw_handles.arr = arr;
ehea_fw_handles.num_entries = i;
+out:
+ mutex_unlock(&ehea_fw_handles.lock);
}
static void ehea_update_bcmc_registrations(void)
{
+ unsigned long flags;
struct ehea_bcmc_reg_entry *arr = NULL;
struct ehea_adapter *adapter;
struct ehea_mc_list *mc_entry;
@@ -233,6 +244,8 @@ static void ehea_update_bcmc_registrations(void)
int i = 0;
int k;
+ spin_lock_irqsave(&ehea_bcmc_regs.lock, flags);
+
/* Determine number of registrations */
list_for_each_entry(adapter, &adapter_list, list)
for (k = 0; k < EHEA_MAX_PORTS; k++) {
@@ -250,7 +263,7 @@ static void ehea_update_bcmc_registrations(void)
if (num_registrations) {
arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC);
if (!arr)
- return; /* Keep the existing array */
+ goto out; /* Keep the existing array */
} else
goto out_update;
@@ -261,6 +274,9 @@ static void ehea_update_bcmc_registrations(void)
if (!port || (port->state != EHEA_PORT_UP))
continue;
+ if (num_registrations == 0)
+ goto out_update;
+
arr[i].adh = adapter->handle;
arr[i].port_id = port->logical_port_id;
arr[i].reg_type = EHEA_BCMC_BROADCAST |
@@ -272,9 +288,13 @@ static void ehea_update_bcmc_registrations(void)
arr[i].reg_type = EHEA_BCMC_BROADCAST |
EHEA_BCMC_VLANID_ALL;
arr[i++].macaddr = port->mac_addr;
+ num_registrations -= 2;
list_for_each_entry(mc_entry,
&port->mc_list->list, list) {
+ if (num_registrations == 0)
+ goto out_update;
+
arr[i].adh = adapter->handle;
arr[i].port_id = port->logical_port_id;
arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
@@ -288,6 +308,7 @@ static void ehea_update_bcmc_registrations(void)
EHEA_BCMC_MULTICAST |
EHEA_BCMC_VLANID_ALL;
arr[i++].macaddr = mc_entry->macaddr;
+ num_registrations -= 2;
}
}
}
@@ -296,6 +317,8 @@ out_update:
kfree(ehea_bcmc_regs.arr);
ehea_bcmc_regs.arr = arr;
ehea_bcmc_regs.num_entries = i;
+out:
+ spin_unlock_irqrestore(&ehea_bcmc_regs.lock, flags);
}
static struct net_device_stats *ehea_get_stats(struct net_device *dev)
@@ -308,7 +331,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
memset(stats, 0, sizeof(*stats));
- cb2 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+ cb2 = (void *)get_zeroed_page(GFP_ATOMIC);
if (!cb2) {
ehea_error("no mem for cb2");
goto out;
@@ -341,7 +364,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
stats->rx_packets = rx_packets;
out_herr:
- kfree(cb2);
+ free_page((unsigned long)cb2);
out:
return stats;
}
@@ -370,8 +393,6 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
EHEA_L_PKT_SIZE);
if (!skb_arr_rq1[index]) {
pr->rq1_skba.os_skbs = fill_wqes - i;
- ehea_error("%s: no mem for skb/%d wqes filled",
- dev->name, i);
break;
}
}
@@ -387,26 +408,19 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
ehea_update_rq1a(pr->qp, adder);
}
-static int ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
+static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
{
- int ret = 0;
struct sk_buff **skb_arr_rq1 = pr->rq1_skba.arr;
struct net_device *dev = pr->port->netdev;
int i;
for (i = 0; i < pr->rq1_skba.len; i++) {
skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
- if (!skb_arr_rq1[i]) {
- ehea_error("%s: no mem for skb/%d wqes filled",
- dev->name, i);
- ret = -ENOMEM;
- goto out;
- }
+ if (!skb_arr_rq1[i])
+ break;
}
/* Ring doorbell */
ehea_update_rq1a(pr->qp, nr_rq1a);
-out:
- return ret;
}
static int ehea_refill_rq_def(struct ehea_port_res *pr,
@@ -435,10 +449,12 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
u64 tmp_addr;
struct sk_buff *skb = netdev_alloc_skb(dev, packet_size);
if (!skb) {
- ehea_error("%s: no mem for skb/%d wqes filled",
- pr->port->netdev->name, i);
q_skba->os_skbs = fill_wqes - i;
- ret = -ENOMEM;
+ if (q_skba->os_skbs == q_skba->len - 2) {
+ ehea_info("%s: rq%i ran dry - no mem for skb",
+ pr->port->netdev->name, rq_nr);
+ ret = -ENOMEM;
+ }
break;
}
skb_reserve(skb, NET_IP_ALIGN);
@@ -830,7 +846,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)
while ((rx != budget) || force_irq) {
pr->poll_counter = 0;
force_irq = 0;
- netif_rx_complete(napi);
+ napi_complete(napi);
ehea_reset_cq_ep(pr->recv_cq);
ehea_reset_cq_ep(pr->send_cq);
ehea_reset_cq_n1(pr->recv_cq);
@@ -841,7 +857,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)
if (!cqe && !cqe_skb)
return rx;
- if (!netif_rx_reschedule(napi))
+ if (!napi_reschedule(napi))
return rx;
cqe_skb = ehea_proc_cqes(pr, EHEA_POLL_MAX_CQES);
@@ -859,7 +875,7 @@ static void ehea_netpoll(struct net_device *dev)
int i;
for (i = 0; i < port->num_def_qps; i++)
- netif_rx_schedule(&port->port_res[i].napi);
+ napi_schedule(&port->port_res[i].napi);
}
#endif
@@ -867,7 +883,7 @@ static irqreturn_t ehea_recv_irq_handler(int irq, void *param)
{
struct ehea_port_res *pr = param;
- netif_rx_schedule(&pr->napi);
+ napi_schedule(&pr->napi);
return IRQ_HANDLED;
}
@@ -915,7 +931,7 @@ int ehea_sense_port_attr(struct ehea_port *port)
struct hcp_ehea_port_cb0 *cb0;
/* may be called via ehea_neq_tasklet() */
- cb0 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+ cb0 = (void *)get_zeroed_page(GFP_ATOMIC);
if (!cb0) {
ehea_error("no mem for cb0");
ret = -ENOMEM;
@@ -996,7 +1012,7 @@ int ehea_sense_port_attr(struct ehea_port *port)
out_free:
if (ret || netif_msg_probe(port))
ehea_dump(cb0, sizeof(*cb0), "ehea_sense_port_attr");
- kfree(cb0);
+ free_page((unsigned long)cb0);
out:
return ret;
}
@@ -1007,7 +1023,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
u64 hret;
int ret = 0;
- cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb4 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb4) {
ehea_error("no mem for cb4");
ret = -ENOMEM;
@@ -1075,7 +1091,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP))
netif_carrier_on(port->netdev);
- kfree(cb4);
+ free_page((unsigned long)cb4);
out:
return ret;
}
@@ -1201,11 +1217,11 @@ static int ehea_fill_port_res(struct ehea_port_res *pr)
int ret;
struct ehea_qp_init_attr *init_attr = &pr->qp->init_attr;
- ret = ehea_init_fill_rq1(pr, init_attr->act_nr_rwqes_rq1
- - init_attr->act_nr_rwqes_rq2
- - init_attr->act_nr_rwqes_rq3 - 1);
+ ehea_init_fill_rq1(pr, init_attr->act_nr_rwqes_rq1
+ - init_attr->act_nr_rwqes_rq2
+ - init_attr->act_nr_rwqes_rq3 - 1);
- ret |= ehea_refill_rq2(pr, init_attr->act_nr_rwqes_rq2 - 1);
+ ret = ehea_refill_rq2(pr, init_attr->act_nr_rwqes_rq2 - 1);
ret |= ehea_refill_rq3(pr, init_attr->act_nr_rwqes_rq3 - 1);
@@ -1302,7 +1318,7 @@ static int ehea_configure_port(struct ehea_port *port)
struct hcp_ehea_port_cb0 *cb0;
ret = -ENOMEM;
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0)
goto out;
@@ -1338,7 +1354,7 @@ static int ehea_configure_port(struct ehea_port *port)
ret = 0;
out_free:
- kfree(cb0);
+ free_page((unsigned long)cb0);
out:
return ret;
}
@@ -1748,7 +1764,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
goto out;
}
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
ehea_error("no mem for cb0");
ret = -ENOMEM;
@@ -1769,8 +1785,6 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
- spin_lock(&ehea_bcmc_regs.lock);
-
/* Deregister old MAC in pHYP */
if (port->state == EHEA_PORT_UP) {
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -1791,9 +1805,8 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
out_upregs:
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
out_free:
- kfree(cb0);
+ free_page((unsigned long)cb0);
out:
return ret;
}
@@ -1817,7 +1830,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable)
if ((enable && port->promisc) || (!enable && !port->promisc))
return;
- cb7 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+ cb7 = (void *)get_zeroed_page(GFP_ATOMIC);
if (!cb7) {
ehea_error("no mem for cb7");
goto out;
@@ -1836,7 +1849,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable)
port->promisc = enable;
out:
- kfree(cb7);
+ free_page((unsigned long)cb7);
return;
}
@@ -1953,8 +1966,6 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
ehea_promiscuous(dev, 0);
- spin_lock(&ehea_bcmc_regs.lock);
-
if (dev->flags & IFF_ALLMULTI) {
ehea_allmulti(dev, 1);
goto out;
@@ -1984,7 +1995,6 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
out:
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
return;
}
@@ -2217,7 +2227,7 @@ static void ehea_vlan_rx_register(struct net_device *dev,
port->vgrp = grp;
- cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
ehea_error("no mem for cb1");
goto out;
@@ -2228,7 +2238,7 @@ static void ehea_vlan_rx_register(struct net_device *dev,
if (hret != H_SUCCESS)
ehea_error("modify_ehea_port failed");
- kfree(cb1);
+ free_page((unsigned long)cb1);
out:
return;
}
@@ -2241,7 +2251,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
int index;
u64 hret;
- cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
ehea_error("no mem for cb1");
goto out;
@@ -2262,7 +2272,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
if (hret != H_SUCCESS)
ehea_error("modify_ehea_port failed");
out:
- kfree(cb1);
+ free_page((unsigned long)cb1);
return;
}
@@ -2276,7 +2286,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
vlan_group_set_device(port->vgrp, vid, NULL);
- cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
ehea_error("no mem for cb1");
goto out;
@@ -2297,7 +2307,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
if (hret != H_SUCCESS)
ehea_error("modify_ehea_port failed");
out:
- kfree(cb1);
+ free_page((unsigned long)cb1);
return;
}
@@ -2309,7 +2319,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
u64 dummy64 = 0;
struct hcp_modify_qp_cb0 *cb0;
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
ret = -ENOMEM;
goto out;
@@ -2372,7 +2382,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
ret = 0;
out:
- kfree(cb0);
+ free_page((unsigned long)cb0);
return ret;
}
@@ -2465,8 +2475,6 @@ static int ehea_up(struct net_device *dev)
if (port->state == EHEA_PORT_UP)
return 0;
- mutex_lock(&ehea_fw_handles.lock);
-
ret = ehea_port_res_setup(port, port->num_def_qps,
port->num_add_tx_qps);
if (ret) {
@@ -2503,8 +2511,6 @@ static int ehea_up(struct net_device *dev)
}
}
- spin_lock(&ehea_bcmc_regs.lock);
-
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret) {
ret = -EIO;
@@ -2526,10 +2532,7 @@ out:
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
-
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -2579,9 +2582,6 @@ static int ehea_down(struct net_device *dev)
if (port->state == EHEA_PORT_DOWN)
return 0;
- mutex_lock(&ehea_fw_handles.lock);
-
- spin_lock(&ehea_bcmc_regs.lock);
ehea_drop_multicast_list(dev);
ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -2590,7 +2590,6 @@ static int ehea_down(struct net_device *dev)
port->state = EHEA_PORT_DOWN;
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
ret = ehea_clean_all_portres(port);
if (ret)
@@ -2598,7 +2597,6 @@ static int ehea_down(struct net_device *dev)
dev->name, ret);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -2664,7 +2662,7 @@ int ehea_stop_qps(struct net_device *dev)
u64 dummy64 = 0;
u16 dummy16 = 0;
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
ret = -ENOMEM;
goto out;
@@ -2716,7 +2714,7 @@ int ehea_stop_qps(struct net_device *dev)
ret = 0;
out:
- kfree(cb0);
+ free_page((unsigned long)cb0);
return ret;
}
@@ -2766,7 +2764,7 @@ int ehea_restart_qps(struct net_device *dev)
u64 dummy64 = 0;
u16 dummy16 = 0;
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
ret = -ENOMEM;
goto out;
@@ -2819,7 +2817,7 @@ int ehea_restart_qps(struct net_device *dev)
ehea_refill_rq3(pr, 0);
}
out:
- kfree(cb0);
+ free_page((unsigned long)cb0);
return ret;
}
@@ -2950,7 +2948,7 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
u64 hret;
int ret;
- cb = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb) {
ret = -ENOMEM;
goto out;
@@ -2967,7 +2965,7 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
ret = 0;
out_herr:
- kfree(cb);
+ free_page((unsigned long)cb);
out:
return ret;
}
@@ -2981,7 +2979,7 @@ int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo)
*jumbo = 0;
/* (Try to) enable *jumbo frames */
- cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb4 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb4) {
ehea_error("no mem for cb4");
ret = -ENOMEM;
@@ -3009,7 +3007,7 @@ int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo)
} else
ret = -EINVAL;
- kfree(cb4);
+ free_page((unsigned long)cb4);
}
out:
return ret;
@@ -3040,7 +3038,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
port->ofdev.dev.parent = &port->adapter->ofdev->dev;
port->ofdev.dev.bus = &ibmebus_bus_type;
- sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++);
+ dev_set_name(&port->ofdev.dev, "port%d", port_name_cnt++);
port->ofdev.dev.release = logical_port_release;
ret = of_device_register(&port->ofdev);
@@ -3069,6 +3067,22 @@ static void ehea_unregister_port(struct ehea_port *port)
of_device_unregister(&port->ofdev);
}
+static const struct net_device_ops ehea_netdev_ops = {
+ .ndo_open = ehea_open,
+ .ndo_stop = ehea_stop,
+ .ndo_start_xmit = ehea_start_xmit,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ehea_netpoll,
+#endif
+ .ndo_get_stats = ehea_get_stats,
+ .ndo_set_mac_address = ehea_set_mac_addr,
+ .ndo_set_multicast_list = ehea_set_multicast_list,
+ .ndo_change_mtu = ehea_change_mtu,
+ .ndo_vlan_rx_register = ehea_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid
+};
+
struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
u32 logical_port_id,
struct device_node *dn)
@@ -3121,19 +3135,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
/* initialize net_device structure */
memcpy(dev->dev_addr, &port->mac_addr, ETH_ALEN);
- dev->open = ehea_open;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ehea_netpoll;
-#endif
- dev->stop = ehea_stop;
- dev->hard_start_xmit = ehea_start_xmit;
- dev->get_stats = ehea_get_stats;
- dev->set_multicast_list = ehea_set_multicast_list;
- dev->set_mac_address = ehea_set_mac_addr;
- dev->change_mtu = ehea_change_mtu;
- dev->vlan_rx_register = ehea_vlan_rx_register;
- dev->vlan_rx_add_vid = ehea_vlan_rx_add_vid;
- dev->vlan_rx_kill_vid = ehea_vlan_rx_kill_vid;
+ dev->netdev_ops = &ehea_netdev_ops;
+ ehea_set_ethtool_ops(dev);
+
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
| NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
| NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
@@ -3142,7 +3146,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
INIT_WORK(&port->reset_task, ehea_reset_port);
- ehea_set_ethtool_ops(dev);
ret = register_netdev(dev);
if (ret) {
@@ -3370,7 +3373,6 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
- mutex_lock(&ehea_fw_handles.lock);
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
@@ -3450,11 +3452,12 @@ out_kill_eq:
ehea_destroy_eq(adapter->neq);
out_free_ad:
+ list_del(&adapter->list);
kfree(adapter);
out:
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
+
return ret;
}
@@ -3473,8 +3476,6 @@ static int __devexit ehea_remove(struct of_device *dev)
flush_scheduled_work();
- mutex_lock(&ehea_fw_handles.lock);
-
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
@@ -3484,7 +3485,6 @@ static int __devexit ehea_remove(struct of_device *dev)
kfree(adapter);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return 0;
}
@@ -3518,12 +3518,14 @@ static int ehea_mem_notifier(struct notifier_block *nb,
/* Readd canceled memory block */
case MEM_ONLINE:
ehea_info("memory is going online");
+ set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages))
return NOTIFY_BAD;
ehea_rereg_mrs(NULL);
break;
case MEM_GOING_OFFLINE:
ehea_info("memory is going offline");
+ set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages))
return NOTIFY_BAD;
ehea_rereg_mrs(NULL);
@@ -3531,6 +3533,9 @@ static int ehea_mem_notifier(struct notifier_block *nb,
default:
break;
}
+
+ ehea_update_firmware_handles();
+
return NOTIFY_OK;
}
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 49d766ebbcf..3747457f5e6 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -1005,7 +1005,7 @@ void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle)
unsigned long ret;
u64 *rblock;
- rblock = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ rblock = (void *)get_zeroed_page(GFP_KERNEL);
if (!rblock) {
ehea_error("Cannot allocate rblock memory.");
return;
@@ -1022,5 +1022,5 @@ void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle)
else
ehea_error("Error data could not be fetched: %llX", res_handle);
- kfree(rblock);
+ free_page((unsigned long)rblock);
}
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index a832cc5d6a1..c26cea0b300 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -33,7 +33,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco 10G Ethernet Driver"
-#define DRV_VERSION "1.0.0.648"
+#define DRV_VERSION "1.0.0.933"
#define DRV_COPYRIGHT "Copyright 2008 Cisco Systems, Inc"
#define PFX DRV_NAME ": "
@@ -97,6 +97,7 @@ struct enic {
____cacheline_aligned struct vnic_rq rq[1];
unsigned int rq_count;
int (*rq_alloc_buf)(struct vnic_rq *rq);
+ u64 rq_bad_fcs;
struct napi_struct napi;
struct net_lro_mgr lro_mgr;
struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 7d60551d538..03403a51f7e 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -400,10 +400,13 @@ static irqreturn_t enic_isr_legacy(int irq, void *data)
return IRQ_NONE; /* not our interrupt */
}
- if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY))
+ if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY)) {
+ vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_NOTIFY]);
enic_notify_check(enic);
+ }
if (ENIC_TEST_INTR(pba, ENIC_INTX_ERR)) {
+ vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_ERR]);
enic_log_q_error(enic);
/* schedule recovery from WQ/RQ error */
schedule_work(&enic->reset);
@@ -411,8 +414,8 @@ static irqreturn_t enic_isr_legacy(int irq, void *data)
}
if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) {
- if (netif_rx_schedule_prep(&enic->napi))
- __netif_rx_schedule(&enic->napi);
+ if (napi_schedule_prep(&enic->napi))
+ __napi_schedule(&enic->napi);
} else {
vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
}
@@ -440,7 +443,7 @@ static irqreturn_t enic_isr_msi(int irq, void *data)
* writes).
*/
- netif_rx_schedule(&enic->napi);
+ napi_schedule(&enic->napi);
return IRQ_HANDLED;
}
@@ -450,7 +453,7 @@ static irqreturn_t enic_isr_msix_rq(int irq, void *data)
struct enic *enic = data;
/* schedule NAPI polling for RQ cleanup */
- netif_rx_schedule(&enic->napi);
+ napi_schedule(&enic->napi);
return IRQ_HANDLED;
}
@@ -476,6 +479,8 @@ static irqreturn_t enic_isr_msix_err(int irq, void *data)
{
struct enic *enic = data;
+ vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_ERR]);
+
enic_log_q_error(enic);
/* schedule recovery from WQ/RQ error */
@@ -488,8 +493,8 @@ static irqreturn_t enic_isr_msix_notify(int irq, void *data)
{
struct enic *enic = data;
+ vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_NOTIFY]);
enic_notify_check(enic);
- vnic_intr_unmask(&enic->intr[ENIC_MSIX_NOTIFY]);
return IRQ_HANDLED;
}
@@ -570,11 +575,11 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
* to each TCP segment resulting from the TSO.
*/
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ if (skb->protocol == cpu_to_be16(ETH_P_IP)) {
ip_hdr(skb)->check = 0;
tcp_hdr(skb)->check = ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
- } else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+ } else if (skb->protocol == cpu_to_be16(ETH_P_IPV6)) {
tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
}
@@ -616,7 +621,7 @@ static inline void enic_queue_wq_skb(struct enic *enic,
vlan_tag_insert, vlan_tag);
}
-/* netif_tx_lock held, process context with BHs disabled */
+/* netif_tx_lock held, process context with BHs disabled, or BH */
static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct enic *enic = netdev_priv(netdev);
@@ -683,7 +688,7 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev)
net_stats->rx_bytes = stats->rx.rx_bytes_ok;
net_stats->rx_errors = stats->rx.rx_errors;
net_stats->multicast = stats->rx.rx_multicast_frames_ok;
- net_stats->rx_crc_errors = stats->rx.rx_crc_errors;
+ net_stats->rx_crc_errors = enic->rq_bad_fcs;
net_stats->rx_dropped = stats->rx.rx_no_bufs;
return net_stats;
@@ -928,12 +933,8 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
if (packet_error) {
- if (bytes_written > 0 && !fcs_ok) {
- if (net_ratelimit())
- printk(KERN_ERR PFX
- "%s: packet error: bad FCS\n",
- netdev->name);
- }
+ if (bytes_written > 0 && !fcs_ok)
+ enic->rq_bad_fcs++;
dev_kfree_skb_any(skb);
@@ -1068,8 +1069,8 @@ static int enic_poll(struct napi_struct *napi, int budget)
if (netdev->features & NETIF_F_LRO)
lro_flush_all(&enic->lro_mgr);
- netif_rx_complete(napi);
- vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
+ napi_complete(napi);
+ vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
}
return rq_work_done;
@@ -1095,9 +1096,9 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
- /* Accumulate intr event credits for this polling
+ /* Return intr event credits for this polling
* cycle. An intr event is the completion of a
- * a WQ or RQ packet.
+ * RQ packet.
*/
vnic_intr_return_credits(&enic->intr[ENIC_MSIX_RQ],
@@ -1112,7 +1113,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
if (netdev->features & NETIF_F_LRO)
lro_flush_all(&enic->lro_mgr);
- netif_rx_complete(napi);
+ napi_complete(napi);
vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
}
@@ -1461,6 +1462,26 @@ static int enic_dev_soft_reset(struct enic *enic)
return err;
}
+static int enic_set_niccfg(struct enic *enic)
+{
+ const u8 rss_default_cpu = 0;
+ const u8 rss_hash_type = 0;
+ const u8 rss_hash_bits = 0;
+ const u8 rss_base_cpu = 0;
+ const u8 rss_enable = 0;
+ const u8 tso_ipid_split_en = 0;
+ const u8 ig_vlan_strip_en = 1;
+
+ /* Enable VLAN tag stripping. RSS not enabled (yet).
+ */
+
+ return enic_set_nic_cfg(enic,
+ rss_default_cpu, rss_hash_type,
+ rss_hash_bits, rss_base_cpu,
+ rss_enable, tso_ipid_split_en,
+ ig_vlan_strip_en);
+}
+
static void enic_reset(struct work_struct *work)
{
struct enic *enic = container_of(work, struct enic, reset);
@@ -1476,8 +1497,10 @@ static void enic_reset(struct work_struct *work)
enic_stop(enic->netdev);
enic_dev_soft_reset(enic);
+ vnic_dev_init(enic->vdev, 0);
enic_reset_mcaddrs(enic);
enic_init_vnic_resources(enic);
+ enic_set_niccfg(enic);
enic_open(enic->netdev);
rtnl_unlock();
@@ -1620,14 +1643,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
unsigned int i;
int err;
- const u8 rss_default_cpu = 0;
- const u8 rss_hash_type = 0;
- const u8 rss_hash_bits = 0;
- const u8 rss_base_cpu = 0;
- const u8 rss_enable = 0;
- const u8 tso_ipid_split_en = 0;
- const u8 ig_vlan_strip_en = 1;
-
/* Allocate net device structure and initialize. Private
* instance data is initialized to zero.
*/
@@ -1793,14 +1808,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
enic_init_vnic_resources(enic);
- /* Enable VLAN tag stripping. RSS not enabled (yet).
- */
-
- err = enic_set_nic_cfg(enic,
- rss_default_cpu, rss_hash_type,
- rss_hash_bits, rss_base_cpu,
- rss_enable, tso_ipid_split_en,
- ig_vlan_strip_en);
+ err = enic_set_niccfg(enic);
if (err) {
printk(KERN_ERR PFX
"Failed to config nic, aborting.\n");
@@ -1858,7 +1866,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
if (using_dac)
netdev->features |= NETIF_F_HIGHDMA;
-
enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM);
enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR;
@@ -1870,7 +1877,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE;
enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
-
err = register_netdev(netdev);
if (err) {
printk(KERN_ERR PFX
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 11708579b6c..e21b9d636ae 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -34,6 +34,9 @@ struct vnic_res {
unsigned int count;
};
+#define VNIC_DEV_CAP_INIT 0x0001
+#define VNIC_DEV_CAP_PERBI 0x0002
+
struct vnic_dev {
void *priv;
struct pci_dev *pdev;
@@ -50,6 +53,7 @@ struct vnic_dev {
dma_addr_t stats_pa;
struct vnic_devcmd_fw_info *fw_info;
dma_addr_t fw_info_pa;
+ u32 cap_flags;
};
#define VNIC_MAX_RES_HDR_SIZE \
@@ -575,9 +579,9 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
{
u64 a0 = (u32)arg, a1 = 0;
int wait = 1000;
- int r = 0;
+ int r = 0;
- if (vnic_dev_capable(vdev, CMD_INIT))
+ if (vdev->cap_flags & VNIC_DEV_CAP_INIT)
r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
else {
vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
@@ -587,8 +591,8 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
}
- }
- return r;
+ }
+ return r;
}
int vnic_dev_link_status(struct vnic_dev *vdev)
@@ -626,6 +630,22 @@ u32 vnic_dev_mtu(struct vnic_dev *vdev)
return vdev->notify_copy.mtu;
}
+u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev)
+{
+ if (!vnic_dev_notify_ready(vdev))
+ return 0;
+
+ return vdev->notify_copy.link_down_cnt;
+}
+
+u32 vnic_dev_notify_status(struct vnic_dev *vdev)
+{
+ if (!vnic_dev_notify_ready(vdev))
+ return 0;
+
+ return vdev->notify_copy.status;
+}
+
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
enum vnic_dev_intr_mode intr_mode)
{
@@ -682,6 +702,11 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
if (!vdev->devcmd)
goto err_out;
+ vdev->cap_flags = 0;
+
+ if (vnic_dev_capable(vdev, CMD_INIT))
+ vdev->cap_flags |= VNIC_DEV_CAP_INIT;
+
return vdev;
err_out:
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index b9dc1821c80..8aa8db2fd03 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -102,6 +102,8 @@ int vnic_dev_link_status(struct vnic_dev *vdev);
u32 vnic_dev_port_speed(struct vnic_dev *vdev);
u32 vnic_dev_msg_lvl(struct vnic_dev *vdev);
u32 vnic_dev_mtu(struct vnic_dev *vdev);
+u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev);
+u32 vnic_dev_notify_status(struct vnic_dev *vdev);
int vnic_dev_close(struct vnic_dev *vdev);
int vnic_dev_enable(struct vnic_dev *vdev);
int vnic_dev_disable(struct vnic_dev *vdev);
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index 8062c75154e..2587f34fbfb 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -191,7 +191,7 @@ enum vnic_devcmd_cmd {
CMD_INIT_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 31),
/* INT13 API: (u64)a0=paddr to vnic_int13_params struct
- * (u8)a1=INT13_CMD_xxx */
+ * (u32)a1=INT13_CMD_xxx */
CMD_INT13 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_FC, 32),
/* logical uplink enable/disable: (u64)a0: 0/1=disable/enable */
@@ -207,6 +207,11 @@ enum vnic_devcmd_cmd {
* in: (u32)a0=cmd
* out: (u32)a0=errno, 0:valid cmd, a1=supported VNIC_STF_* bits */
CMD_CAPABILITY = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 36),
+
+ /* persistent binding info
+ * in: (u64)a0=paddr of arg
+ * (u32)a1=CMD_PERBI_XXX */
+ CMD_PERBI = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_FC, 37),
};
/* flags for CMD_OPEN */
@@ -259,6 +264,7 @@ struct vnic_devcmd_notify {
u32 status; /* status bits (see VNIC_STF_*) */
u32 error; /* error code (see ERR_*) for first ERR */
u32 link_down_cnt; /* running count of link down transitions */
+ u32 perbi_rebuild_cnt; /* running count of perbi rebuilds */
};
#define VNIC_STF_FATAL_ERR 0x0001 /* fatal fw error */
#define VNIC_STF_STD_PAUSE 0x0002 /* standard link-level pause on */
diff --git a/drivers/net/enic/vnic_intr.h b/drivers/net/enic/vnic_intr.h
index ce633a5a7e3..9a53604edce 100644
--- a/drivers/net/enic/vnic_intr.h
+++ b/drivers/net/enic/vnic_intr.h
@@ -76,6 +76,20 @@ static inline void vnic_intr_return_credits(struct vnic_intr *intr,
iowrite32(int_credit_return, &intr->ctrl->int_credit_return);
}
+static inline unsigned int vnic_intr_credits(struct vnic_intr *intr)
+{
+ return ioread32(&intr->ctrl->int_credits);
+}
+
+static inline void vnic_intr_return_all_credits(struct vnic_intr *intr)
+{
+ unsigned int credits = vnic_intr_credits(intr);
+ int unmask = 1;
+ int reset_timer = 1;
+
+ vnic_intr_return_credits(intr, credits, unmask, reset_timer);
+}
+
static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba)
{
/* read PBA without clearing */
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index a539bc3163c..b60e27dfcfa 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1114,9 +1114,9 @@ static irqreturn_t epic_interrupt(int irq, void *dev_instance)
if ((status & EpicNapiEvent) && !ep->reschedule_in_poll) {
spin_lock(&ep->napi_lock);
- if (netif_rx_schedule_prep(&ep->napi)) {
+ if (napi_schedule_prep(&ep->napi)) {
epic_napi_irq_off(dev, ep);
- __netif_rx_schedule(&ep->napi);
+ __napi_schedule(&ep->napi);
} else
ep->reschedule_in_poll++;
spin_unlock(&ep->napi_lock);
@@ -1293,7 +1293,7 @@ rx_action:
more = ep->reschedule_in_poll;
if (!more) {
- __netif_rx_complete(napi);
+ __napi_complete(napi);
outl(EpicNapiEvent, ioaddr + INTSTAT);
epic_napi_irq_on(dev, ep);
} else
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 40125694bd9..51ead7941f8 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -159,7 +159,7 @@ static void eql_timer(unsigned long param)
add_timer(&eql->timer);
}
-static char version[] __initdata =
+static const char version[] __initconst =
"Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)\n";
static const struct net_device_ops eql_netdev_ops = {
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index daf7272c335..891be28a7d4 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -93,8 +93,8 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
#include <asm/byteorder.h>
/* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n";
/* This driver was written to use PCI memory space, however some x86 systems
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 7e33c129d51..a515acccc61 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -36,46 +36,32 @@
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/cacheflush.h>
+#ifndef CONFIG_ARCH_MXC
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
+#endif
+
#include "fec.h"
-#if defined(CONFIG_FEC2)
-#define FEC_MAX_PORTS 2
+#ifdef CONFIG_ARCH_MXC
+#include <mach/hardware.h>
+#define FEC_ALIGNMENT 0xf
#else
-#define FEC_MAX_PORTS 1
-#endif
-
-#if defined(CONFIG_M5272)
-#define HAVE_mii_link_interrupt
+#define FEC_ALIGNMENT 0x3
#endif
/*
* Define the fixed address of the FEC hardware.
*/
-static unsigned int fec_hw[] = {
#if defined(CONFIG_M5272)
- (MCF_MBAR + 0x840),
-#elif defined(CONFIG_M527x)
- (MCF_MBAR + 0x1000),
- (MCF_MBAR + 0x1800),
-#elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
- (MCF_MBAR + 0x1000),
-#elif defined(CONFIG_M520x)
- (MCF_MBAR+0x30000),
-#elif defined(CONFIG_M532x)
- (MCF_MBAR+0xfc030000),
-#else
- &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
-#endif
-};
+#define HAVE_mii_link_interrupt
static unsigned char fec_mac_default[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -98,6 +84,7 @@ static unsigned char fec_mac_default[] = {
#else
#define FEC_FLASHMAC 0
#endif
+#endif /* CONFIG_M5272 */
/* Forward declarations of some structures to support different PHYs
*/
@@ -162,7 +149,7 @@ typedef struct {
* account when setting it.
*/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
#else
#define OPT_FRAME_SIZE 0
@@ -182,6 +169,8 @@ struct fec_enet_private {
struct net_device *netdev;
+ struct clk *clk;
+
/* 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];
@@ -190,6 +179,7 @@ struct fec_enet_private {
/* 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 */
@@ -342,10 +332,10 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
* 4-byte boundaries. Use bounce buffers to copy data
* and get it aligned. Ugh.
*/
- if (bdp->cbd_bufaddr & 0x3) {
+ if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
unsigned int index;
index = bdp - fep->tx_bd_base;
- memcpy(fep->tx_bounce[index], (void *) bdp->cbd_bufaddr, bdp->cbd_datlen);
+ memcpy(fep->tx_bounce[index], (void *)skb->data, skb->len);
bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
}
@@ -359,8 +349,8 @@ 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.
*/
- flush_dcache_range((unsigned long)skb->data,
- (unsigned long)skb->data + skb->len);
+ dma_sync_single(NULL, bdp->cbd_bufaddr,
+ bdp->cbd_datlen, 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.
@@ -633,6 +623,9 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
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
@@ -1114,7 +1107,7 @@ static phy_info_t const phy_info_am79c874 = {
/* register definitions for the 8721 */
#define MII_KS8721BL_RXERCR 21
-#define MII_KS8721BL_ICSR 22
+#define MII_KS8721BL_ICSR 27
#define MII_KS8721BL_PHYCR 31
static phy_cmd_t const phy_cmd_ks8721bl_config[] = {
@@ -1223,93 +1216,14 @@ static phy_info_t const * const phy_info[] = {
#ifdef HAVE_mii_link_interrupt
static irqreturn_t
mii_link_interrupt(int irq, void * dev_id);
-#endif
-#if defined(CONFIG_M5272)
/*
- * Code specific to Coldfire 5272 setup.
+ * This is specific to the MII interrupt setup of the M5272EVB.
*/
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- volatile unsigned long *icrp;
- static const struct idesc {
- char *name;
- unsigned short irq;
- irq_handler_t handler;
- } *idp, id[] = {
- { "fec(RX)", 86, fec_enet_interrupt },
- { "fec(TX)", 87, fec_enet_interrupt },
- { "fec(OTHER)", 88, fec_enet_interrupt },
- { "fec(MII)", 66, mii_link_interrupt },
- { NULL },
- };
-
- /* Setup interrupt handlers. */
- for (idp = id; idp->name; idp++) {
- if (request_irq(idp->irq, idp->handler, IRQF_DISABLED, idp->name, dev) != 0)
- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq);
- }
-
- /* Unmask interrupt at ColdFire 5272 SIM */
- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
- *icrp = 0x00000ddd;
- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = 0x0d000000;
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- * See 5272 manual section 11.5.8: MSCR
- */
- fep->phy_speed = ((((MCF_CLK / 4) / (2500000 / 10)) + 5) / 10) * 2;
- fecp->fec_mii_speed = fep->phy_speed;
-
- fec_restart(dev, 0);
-}
-
-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.
- * If it is all 1's or 0's, use the default.
- */
- iap = (unsigned char *)FEC_FLASHMAC;
- if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
- iap = fec_mac_default;
- if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
- (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);
- iap = &tmpaddr[0];
- }
-
- memcpy(dev->dev_addr, iap, ETH_ALEN);
-
- /* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
+static void __inline__ fec_request_mii_intr(struct net_device *dev)
{
+ if (request_irq(66, mii_link_interrupt, IRQF_DISABLED, "fec(MII)", dev) != 0)
+ printk("FEC: Could not allocate fec(MII) IRQ(66)!\n");
}
static void __inline__ fec_disable_phy_intr(void)
@@ -1327,244 +1241,7 @@ static void __inline__ fec_phy_ack_intr(void)
*icrp = 0x0d000000;
}
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- * Do not need to make region uncached on 5272.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
-
-/*
- * Code specific to Coldfire 5230/5231/5232/5234/5235,
- * the 5270/5271/5274/5275 and 5280/5282 setups.
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- struct fec_enet_private *fep;
- int b;
- static const struct idesc {
- char *name;
- unsigned short irq;
- } *idp, id[] = {
- { "fec(TXF)", 23 },
- { "fec(RXF)", 27 },
- { "fec(MII)", 29 },
- { NULL },
- };
-
- fep = netdev_priv(dev);
- b = (fep->index) ? 128 : 64;
-
- /* Setup interrupt handlers. */
- for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name, dev) != 0)
- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
- }
-
- /* Unmask interrupts at ColdFire 5280/5282 interrupt controller */
- {
- volatile unsigned char *icrp;
- volatile unsigned long *imrp;
- int i, ilip;
-
- b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0;
- icrp = (volatile unsigned char *) (MCF_IPSBAR + b +
- MCFINTC_ICR0);
- for (i = 23, ilip = 0x28; (i < 36); i++)
- icrp[i] = ilip--;
-
- imrp = (volatile unsigned long *) (MCF_IPSBAR + b +
- MCFINTC_IMRH);
- *imrp &= ~0x0000000f;
- imrp = (volatile unsigned long *) (MCF_IPSBAR + b +
- MCFINTC_IMRL);
- *imrp &= ~0xff800001;
- }
-
-#if defined(CONFIG_M528x)
- /* Set up gpio outputs for MII lines */
- {
- volatile u16 *gpio_paspar;
- volatile u8 *gpio_pehlpar;
-
- gpio_paspar = (volatile u16 *) (MCF_IPSBAR + 0x100056);
- gpio_pehlpar = (volatile u16 *) (MCF_IPSBAR + 0x100058);
- *gpio_paspar |= 0x0f00;
- *gpio_pehlpar = 0xc0;
- }
-#endif
-
-#if defined(CONFIG_M527x)
- /* Set up gpio outputs for MII lines */
- {
- volatile u8 *gpio_par_fec;
- volatile u16 *gpio_par_feci2c;
-
- gpio_par_feci2c = (volatile u16 *)(MCF_IPSBAR + 0x100082);
- /* Set up gpio outputs for FEC0 MII lines */
- gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100078);
-
- *gpio_par_feci2c |= 0x0f00;
- *gpio_par_fec |= 0xc0;
-
-#if defined(CONFIG_FEC2)
- /* Set up gpio outputs for FEC1 MII lines */
- gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100079);
-
- *gpio_par_feci2c |= 0x00a0;
- *gpio_par_fec |= 0xc0;
-#endif /* CONFIG_FEC2 */
- }
-#endif /* CONFIG_M527x */
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- * See 5282 manual section 17.5.4.7: MSCR
- */
- fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
- fecp->fec_mii_speed = fep->phy_speed;
-
- fec_restart(dev, 0);
-}
-
-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.
- * If it is all 1's or 0's, use the default.
- */
- iap = FEC_FLASHMAC;
- if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
- iap = fec_mac_default;
- if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
- (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);
- iap = &tmpaddr[0];
- }
-
- memcpy(dev->dev_addr, iap, ETH_ALEN);
-
- /* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- * Do not need to make region uncached on 5272.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M520x)
-
-/*
- * Code specific to Coldfire 520x
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- struct fec_enet_private *fep;
- int b;
- static const struct idesc {
- char *name;
- unsigned short irq;
- } *idp, id[] = {
- { "fec(TXF)", 23 },
- { "fec(RXF)", 27 },
- { "fec(MII)", 29 },
- { NULL },
- };
-
- fep = netdev_priv(dev);
- b = 64 + 13;
-
- /* Setup interrupt handlers. */
- for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0)
- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
- }
-
- /* Unmask interrupts at ColdFire interrupt controller */
- {
- volatile unsigned char *icrp;
- volatile unsigned long *imrp;
-
- icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
- MCFINTC_ICR0);
- for (b = 36; (b < 49); b++)
- icrp[b] = 0x04;
- imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
- MCFINTC_IMRH);
- *imrp &= ~0x0001FFF0;
- }
- *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
- *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- * See 5282 manual section 17.5.4.7: MSCR
- */
- fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
- fecp->fec_mii_speed = fep->phy_speed;
-
- fec_restart(dev, 0);
-}
-
+#ifdef CONFIG_M5272
static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
@@ -1578,146 +1255,7 @@ static void __inline__ fec_get_mac(struct net_device *dev)
* Get MAC address from FLASH.
* If it is all 1's or 0's, use the default.
*/
- iap = FEC_FLASHMAC;
- if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
- iap = fec_mac_default;
- if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
- (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);
- iap = &tmpaddr[0];
- }
-
- memcpy(dev->dev_addr, iap, ETH_ALEN);
-
- /* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M532x)
-/*
- * Code specific for M532x
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- struct fec_enet_private *fep;
- int b;
- static const struct idesc {
- char *name;
- unsigned short irq;
- } *idp, id[] = {
- { "fec(TXF)", 36 },
- { "fec(RXF)", 40 },
- { "fec(MII)", 42 },
- { NULL },
- };
-
- fep = netdev_priv(dev);
- b = (fep->index) ? 128 : 64;
-
- /* Setup interrupt handlers. */
- for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0)
- printk("FEC: Could not allocate %s IRQ(%d)!\n",
- idp->name, b+idp->irq);
- }
-
- /* Unmask interrupts */
- MCF_INTC0_ICR36 = 0x2;
- MCF_INTC0_ICR37 = 0x2;
- MCF_INTC0_ICR38 = 0x2;
- MCF_INTC0_ICR39 = 0x2;
- MCF_INTC0_ICR40 = 0x2;
- MCF_INTC0_ICR41 = 0x2;
- MCF_INTC0_ICR42 = 0x2;
- MCF_INTC0_ICR43 = 0x2;
- MCF_INTC0_ICR44 = 0x2;
- MCF_INTC0_ICR45 = 0x2;
- MCF_INTC0_ICR46 = 0x2;
- MCF_INTC0_ICR47 = 0x2;
- MCF_INTC0_ICR48 = 0x2;
-
- MCF_INTC0_IMRH &= ~(
- MCF_INTC_IMRH_INT_MASK36 |
- MCF_INTC_IMRH_INT_MASK37 |
- MCF_INTC_IMRH_INT_MASK38 |
- MCF_INTC_IMRH_INT_MASK39 |
- MCF_INTC_IMRH_INT_MASK40 |
- MCF_INTC_IMRH_INT_MASK41 |
- MCF_INTC_IMRH_INT_MASK42 |
- MCF_INTC_IMRH_INT_MASK43 |
- MCF_INTC_IMRH_INT_MASK44 |
- MCF_INTC_IMRH_INT_MASK45 |
- MCF_INTC_IMRH_INT_MASK46 |
- MCF_INTC_IMRH_INT_MASK47 |
- MCF_INTC_IMRH_INT_MASK48 );
-
- /* Set up gpio outputs for MII lines */
- MCF_GPIO_PAR_FECI2C |= (0 |
- MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
- MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
- MCF_GPIO_PAR_FEC = (0 |
- MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
- MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- */
- fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
- fecp->fec_mii_speed = fep->phy_speed;
-
- fec_restart(dev, 0);
-}
-
-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.
- * If it is all 1's or 0's, use the default.
- */
- iap = FEC_FLASHMAC;
+ iap = (unsigned char *)FEC_FLASHMAC;
if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
(iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
iap = fec_mac_default;
@@ -1734,122 +1272,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
/* Adjust MAC if using default MAC address */
if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- * Do not need to make region uncached on 532x.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-#else
-
-/*
- * Code specific to the MPC860T setup.
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- volatile immap_t *immap;
-
- immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */
-
- if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
- panic("Could not allocate FEC IRQ!");
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
- bd_t *bd;
-
- bd = (bd_t *)__res;
- memcpy(dev->dev_addr, bd->bi_enetaddr, ETH_ALEN);
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- extern uint _get_IMMR(void);
- volatile immap_t *immap;
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */
-
- /* Configure all of port D for MII.
- */
- immap->im_ioport.iop_pdpar = 0x1fff;
-
- /* Bits moved from Rev. D onward.
- */
- if ((_get_IMMR() & 0xffff) < 0x0501)
- immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
- else
- immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
-
- /* Set MII speed to 2.5 MHz
- */
- fecp->fec_mii_speed = fep->phy_speed =
- ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
-
- /* Enable MII command finished interrupt
- */
- fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_hash = PKT_MAXBUF_SIZE;
- /* Enable big endian and don't care about SDMA FC.
- */
- fecp->fec_fun_code = 0x78000000;
-}
-
-static void __inline__ fec_uncache(unsigned long addr)
-{
- pte_t *pte;
- pte = va_to_pte(mem_addr);
- pte_val(*pte) |= _PAGE_NO_CACHE;
- flush_tlb_page(init_mm.mmap, mem_addr);
+ dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
}
-
#endif
/* ------------------------------------------------------------------------- */
@@ -2055,7 +1479,9 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
printk("FEC: No PHY device found.\n");
/* Disable external MII interface */
fecp->fec_mii_speed = fep->phy_speed = 0;
+#ifdef HAVE_mii_link_interrupt
fec_disable_phy_intr();
+#endif
}
}
@@ -2237,12 +1663,12 @@ fec_set_mac_address(struct net_device *dev)
}
-/* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
- */
/*
* XXX: We need to clean up on failure exits here.
+ *
+ * index is only used in legacy code
*/
-int __init fec_enet_init(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;
@@ -2250,15 +1676,11 @@ int __init fec_enet_init(struct net_device *dev)
cbd_t *cbd_base;
volatile fec_t *fecp;
int i, j;
- static int index = 0;
-
- /* Only allow us to be probed once. */
- if (index >= FEC_MAX_PORTS)
- return -ENXIO;
/* Allocate memory for buffer descriptors.
*/
- mem_addr = __get_free_page(GFP_KERNEL);
+ mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
+ &fep->bd_dma, GFP_KERNEL);
if (mem_addr == 0) {
printk("FEC: allocate descriptor memory failed?\n");
return -ENOMEM;
@@ -2269,7 +1691,7 @@ int __init fec_enet_init(struct net_device *dev)
/* Create an Ethernet device instance.
*/
- fecp = (volatile fec_t *) fec_hw[index];
+ fecp = (volatile fec_t *)dev->base_addr;
fep->index = index;
fep->hwp = fecp;
@@ -2280,18 +1702,24 @@ int __init fec_enet_init(struct net_device *dev)
fecp->fec_ecntrl = 1;
udelay(10);
- /* Set the Ethernet address. If using multiple Enets on the 8xx,
- * this needs some work to get unique addresses.
- *
- * This is our default MAC address unless the user changes
- * it via eth_mac_addr (our dev->set_mac_addr handler).
- */
+ /* Set the Ethernet address */
+#ifdef CONFIG_M5272
fec_get_mac(dev);
+#else
+ {
+ unsigned long l;
+ l = fecp->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;
+ 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;
- /* XXX: missing check for allocation failure */
-
- fec_uncache(mem_addr);
/* Set receive and transmit descriptor base.
*/
@@ -2313,8 +1741,6 @@ int __init fec_enet_init(struct net_device *dev)
mem_addr = __get_free_page(GFP_KERNEL);
/* XXX: missing check for allocation failure */
- fec_uncache(mem_addr);
-
/* Initialize the BD for every fragment in the page.
*/
for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
@@ -2357,13 +1783,13 @@ int __init fec_enet_init(struct net_device *dev)
/* Set receive and transmit descriptor base.
*/
- fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
- fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_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;
- /* Install our interrupt handlers. This varies depending on
- * the architecture.
- */
- fec_request_intrs(dev);
+#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;
@@ -2375,8 +1801,6 @@ int __init fec_enet_init(struct net_device *dev)
fecp->fec_hash_table_low = 0;
#endif
- dev->base_addr = (unsigned long)fecp;
-
/* The FEC Ethernet specific entries in the device structure. */
dev->open = fec_enet_open;
dev->hard_start_xmit = fec_enet_start_xmit;
@@ -2390,7 +1814,16 @@ int __init fec_enet_init(struct net_device *dev)
mii_free = mii_cmds;
/* setup MII interface */
- fec_set_mii(dev, fep);
+ fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+ fecp->fec_x_cntrl = 0x00;
+
+ /*
+ * 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;
@@ -2403,7 +1836,6 @@ int __init fec_enet_init(struct net_device *dev)
fep->phy_addr = 0;
mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
- index++;
return 0;
}
@@ -2430,7 +1862,6 @@ fec_restart(struct net_device *dev, int duplex)
/* Clear any outstanding interrupt.
*/
fecp->fec_ievent = 0xffc00000;
- fec_enable_phy_intr();
/* Set station address.
*/
@@ -2445,12 +1876,11 @@ fec_restart(struct net_device *dev, int duplex)
*/
fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
- fec_localhw_setup();
-
/* Set receive and transmit descriptor base.
*/
- fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
- fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_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;
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->cur_rx = fep->rx_bd_base;
@@ -2552,39 +1982,171 @@ fec_stop(struct net_device *dev)
/* Clear outstanding MII command interrupts.
*/
fecp->fec_ievent = FEC_ENET_MII;
- fec_enable_phy_intr();
fecp->fec_imask = FEC_ENET_MII;
fecp->fec_mii_speed = fep->phy_speed;
}
-static int __init fec_enet_module_init(void)
+static int __devinit
+fec_probe(struct platform_device *pdev)
{
- struct net_device *dev;
- int i, err;
-
- printk("FEC ENET Version 0.2\n");
-
- for (i = 0; (i < FEC_MAX_PORTS); i++) {
- dev = alloc_etherdev(sizeof(struct fec_enet_private));
- if (!dev)
- return -ENOMEM;
- err = fec_enet_init(dev);
- if (err) {
- free_netdev(dev);
- continue;
+ struct fec_enet_private *fep;
+ struct net_device *ndev;
+ int i, irq, ret = 0;
+ struct resource *r;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ return -ENXIO;
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (!r)
+ return -EBUSY;
+
+ /* Init network device */
+ ndev = alloc_etherdev(sizeof(struct fec_enet_private));
+ if (!ndev)
+ return -ENOMEM;
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ /* setup board info structure */
+ fep = netdev_priv(ndev);
+ memset(fep, 0, sizeof(*fep));
+
+ ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r));
+
+ if (!ndev->base_addr) {
+ ret = -ENOMEM;
+ goto failed_ioremap;
+ }
+
+ platform_set_drvdata(pdev, ndev);
+
+ /* This device has up to three irqs on some platforms */
+ for (i = 0; i < 3; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (i && irq < 0)
+ break;
+ ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
+ if (ret) {
+ while (i >= 0) {
+ irq = platform_get_irq(pdev, i);
+ free_irq(irq, ndev);
+ i--;
+ }
+ goto failed_irq;
}
- if (register_netdev(dev) != 0) {
- /* XXX: missing cleanup here */
- free_netdev(dev);
- return -EIO;
+ }
+
+ fep->clk = clk_get(&pdev->dev, "fec_clk");
+ if (IS_ERR(fep->clk)) {
+ ret = PTR_ERR(fep->clk);
+ goto failed_clk;
+ }
+ clk_enable(fep->clk);
+
+ ret = fec_enet_init(ndev, 0);
+ if (ret)
+ goto failed_init;
+
+ ret = register_netdev(ndev);
+ if (ret)
+ goto failed_register;
+
+ return 0;
+
+failed_register:
+failed_init:
+ clk_disable(fep->clk);
+ clk_put(fep->clk);
+failed_clk:
+ for (i = 0; i < 3; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq > 0)
+ free_irq(irq, ndev);
+ }
+failed_irq:
+ iounmap((void __iomem *)ndev->base_addr);
+failed_ioremap:
+ free_netdev(ndev);
+
+ return ret;
+}
+
+static int __devexit
+fec_drv_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct fec_enet_private *fep = netdev_priv(ndev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ fec_stop(ndev);
+ clk_disable(fep->clk);
+ clk_put(fep->clk);
+ iounmap((void __iomem *)ndev->base_addr);
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+ return 0;
+}
+
+static int
+fec_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct net_device *ndev = platform_get_drvdata(dev);
+ struct fec_enet_private *fep;
+
+ if (ndev) {
+ fep = netdev_priv(ndev);
+ if (netif_running(ndev)) {
+ netif_device_detach(ndev);
+ fec_stop(ndev);
}
+ }
+ return 0;
+}
- printk("%s: ethernet %pM\n", dev->name, dev->dev_addr);
+static int
+fec_resume(struct platform_device *dev)
+{
+ struct net_device *ndev = platform_get_drvdata(dev);
+
+ if (ndev) {
+ if (netif_running(ndev)) {
+ fec_enet_init(ndev, 0);
+ netif_device_attach(ndev);
+ }
}
return 0;
}
+static struct platform_driver fec_driver = {
+ .driver = {
+ .name = "fec",
+ .owner = THIS_MODULE,
+ },
+ .probe = fec_probe,
+ .remove = __devexit_p(fec_drv_remove),
+ .suspend = fec_suspend,
+ .resume = fec_resume,
+};
+
+static int __init
+fec_enet_module_init(void)
+{
+ printk(KERN_INFO "FEC Ethernet Driver\n");
+
+ return platform_driver_register(&fec_driver);
+}
+
+static void __exit
+fec_enet_cleanup(void)
+{
+ platform_driver_unregister(&fec_driver);
+}
+
+module_exit(fec_enet_cleanup);
module_init(fec_enet_module_init);
MODULE_LICENSE("GPL");
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 292719dacef..76c64c92e19 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -14,7 +14,7 @@
/****************************************************************************/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
/*
* Just figures, Motorola would have to change the offsets for
* registers in the same peripheral device on different models
@@ -103,12 +103,19 @@ typedef struct fec {
/*
* Define the buffer descriptor structure.
*/
+#ifdef CONFIG_ARCH_MXC
+typedef 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 {
unsigned short cbd_sc; /* Control and status info */
unsigned short cbd_datlen; /* Data length */
unsigned long cbd_bufaddr; /* Buffer address */
} cbd_t;
-
+#endif
/*
* The following definitions courtesy of commproc.h, which where
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 5b910cf6374..a858c6ff80d 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -39,7 +39,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
-#define FORCEDETH_VERSION "0.62"
+#define FORCEDETH_VERSION "0.64"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@@ -87,8 +87,8 @@
#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 0x000400 /* device supports hw statistics version 2 */
-#define DEV_HAS_STATISTICS_V3 0x000800 /* device supports hw statistics version 3 */
+#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 */
@@ -102,7 +102,7 @@
enum {
NvRegIrqStatus = 0x000,
#define NVREG_IRQSTAT_MIIEVENT 0x040
-#define NVREG_IRQSTAT_MASK 0x81ff
+#define NVREG_IRQSTAT_MASK 0x83ff
NvRegIrqMask = 0x004,
#define NVREG_IRQ_RX_ERROR 0x0001
#define NVREG_IRQ_RX 0x0002
@@ -113,17 +113,13 @@ enum {
#define NVREG_IRQ_LINK 0x0040
#define NVREG_IRQ_RX_FORCED 0x0080
#define NVREG_IRQ_TX_FORCED 0x0100
-#define NVREG_IRQ_RECOVER_ERROR 0x8000
+#define NVREG_IRQ_RECOVER_ERROR 0x8200
#define NVREG_IRQMASK_THROUGHPUT 0x00df
#define NVREG_IRQMASK_CPU 0x0060
#define NVREG_IRQ_TX_ALL (NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
#define NVREG_IRQ_RX_ALL (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
#define NVREG_IRQ_OTHER (NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR)
-#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \
- NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RX_FORCED| \
- NVREG_IRQ_TX_FORCED|NVREG_IRQ_RECOVER_ERROR))
-
NvRegUnknownSetupReg6 = 0x008,
#define NVREG_UNKSETUP6_VAL 3
@@ -132,7 +128,7 @@ enum {
* NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
*/
NvRegPollingInterval = 0x00c,
-#define NVREG_POLL_DEFAULT_THROUGHPUT 970 /* backup tx cleanup if loop max reached */
+#define NVREG_POLL_DEFAULT_THROUGHPUT 65535 /* backup tx cleanup if loop max reached */
#define NVREG_POLL_DEFAULT_CPU 13
NvRegMSIMap0 = 0x020,
NvRegMSIMap1 = 0x024,
@@ -157,6 +153,9 @@ enum {
#define NVREG_XMITCTL_HOST_SEMA_ACQ 0x0000f000
#define NVREG_XMITCTL_HOST_LOADED 0x00004000
#define NVREG_XMITCTL_TX_PATH_EN 0x01000000
+#define NVREG_XMITCTL_DATA_START 0x00100000
+#define NVREG_XMITCTL_DATA_READY 0x00010000
+#define NVREG_XMITCTL_DATA_ERROR 0x00020000
NvRegTransmitterStatus = 0x088,
#define NVREG_XMITSTAT_BUSY 0x01
@@ -289,8 +288,10 @@ enum {
#define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE 0x04
#define NVREG_WAKEUPFLAGS_ENABLE 0x1111
- NvRegPatternCRC = 0x204,
- NvRegPatternMask = 0x208,
+ NvRegMgmtUnitGetVersion = 0x204,
+#define NVREG_MGMTUNITGETVERSION 0x01
+ NvRegMgmtUnitVersion = 0x208,
+#define NVREG_MGMTUNITVERSION 0x08
NvRegPowerCap = 0x268,
#define NVREG_POWERCAP_D3SUPP (1<<30)
#define NVREG_POWERCAP_D2SUPP (1<<26)
@@ -303,6 +304,8 @@ enum {
#define NVREG_POWERSTATE_D1 0x0001
#define NVREG_POWERSTATE_D2 0x0002
#define NVREG_POWERSTATE_D3 0x0003
+ NvRegMgmtUnitControl = 0x278,
+#define NVREG_MGMTUNITCONTROL_INUSE 0x20000
NvRegTxCnt = 0x280,
NvRegTxZeroReXmt = 0x284,
NvRegTxOneReXmt = 0x288,
@@ -460,7 +463,7 @@ union ring_type {
/* General driver defaults */
#define NV_WATCHDOG_TIMEO (5*HZ)
-#define RX_RING_DEFAULT 128
+#define RX_RING_DEFAULT 512
#define TX_RING_DEFAULT 256
#define RX_RING_MIN 128
#define TX_RING_MIN 64
@@ -582,11 +585,17 @@ union ring_type {
#define NV_MSI_X_VECTOR_TX 0x1
#define NV_MSI_X_VECTOR_OTHER 0x2
+#define NV_MSI_PRIV_OFFSET 0x68
+#define NV_MSI_PRIV_VALUE 0xffffffff
+
#define NV_RESTART_TX 0x1
#define NV_RESTART_RX 0x2
#define NV_TX_LIMIT_COUNT 16
+#define NV_DYNAMIC_THRESHOLD 4
+#define NV_DYNAMIC_MAX_QUIET_COUNT 2048
+
/* statistics */
struct nv_ethtool_str {
char name[ETH_GSTRING_LEN];
@@ -744,11 +753,13 @@ struct fe_priv {
u16 gigabit;
int intr_test;
int recover_error;
+ int quiet_count;
/* General data: RO fields */
dma_addr_t ring_addr;
struct pci_dev *pci_dev;
u32 orig_mac[2];
+ u32 events;
u32 irqmask;
u32 desc_ver;
u32 txrxctl_bits;
@@ -758,6 +769,8 @@ struct fe_priv {
u32 register_size;
int rx_csum;
u32 mac_in_use;
+ int mgmt_version;
+ int mgmt_sema;
void __iomem *base;
@@ -812,13 +825,18 @@ struct fe_priv {
/* power saved state */
u32 saved_config_space[NV_PCI_REGSZ_MAX/4];
+
+ /* for different msi-x irq type */
+ char name_rx[IFNAMSIZ + 3]; /* -rx */
+ char name_tx[IFNAMSIZ + 3]; /* -tx */
+ char name_other[IFNAMSIZ + 6]; /* -other */
};
/*
* Maximum number of loops until we assume that a bit in the irq mask
* is stuck. Overridable with module param.
*/
-static int max_interrupt_work = 15;
+static int max_interrupt_work = 4;
/*
* Optimization can be either throuput mode or cpu mode
@@ -828,9 +846,10 @@ static int max_interrupt_work = 15;
*/
enum {
NV_OPTIMIZATION_MODE_THROUGHPUT,
- NV_OPTIMIZATION_MODE_CPU
+ NV_OPTIMIZATION_MODE_CPU,
+ NV_OPTIMIZATION_MODE_DYNAMIC
};
-static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;
+static int optimization_mode = NV_OPTIMIZATION_MODE_DYNAMIC;
/*
* Poll interval for timer irq
@@ -857,7 +876,7 @@ enum {
NV_MSIX_INT_DISABLED,
NV_MSIX_INT_ENABLED
};
-static int msix = NV_MSIX_INT_DISABLED;
+static int msix = NV_MSIX_INT_ENABLED;
/*
* DMA 64bit
@@ -923,7 +942,7 @@ static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target,
delaymax -= delay;
if (delaymax < 0) {
if (msg)
- printk(msg);
+ printk("%s", msg);
return 1;
}
} while ((readl(base + offset) & mask) != target);
@@ -1052,6 +1071,24 @@ static void nv_disable_hw_interrupts(struct net_device *dev, u32 mask)
}
}
+static void nv_napi_enable(struct net_device *dev)
+{
+#ifdef CONFIG_FORCEDETH_NAPI
+ struct fe_priv *np = get_nvpriv(dev);
+
+ napi_enable(&np->napi);
+#endif
+}
+
+static void nv_napi_disable(struct net_device *dev)
+{
+#ifdef CONFIG_FORCEDETH_NAPI
+ struct fe_priv *np = get_nvpriv(dev);
+
+ napi_disable(&np->napi);
+#endif
+}
+
#define MII_READ (-1)
/* mii_rw: read/write a register on the PHY.
*
@@ -1760,7 +1797,7 @@ static void nv_do_rx_refill(unsigned long data)
struct fe_priv *np = netdev_priv(dev);
/* Just reschedule NAPI rx processing */
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
}
#else
static void nv_do_rx_refill(unsigned long data)
@@ -2365,14 +2402,16 @@ static inline void nv_tx_flip_ownership(struct net_device *dev)
*
* Caller must own np->lock.
*/
-static void nv_tx_done(struct net_device *dev)
+static int nv_tx_done(struct net_device *dev, int limit)
{
struct fe_priv *np = netdev_priv(dev);
u32 flags;
+ int tx_work = 0;
struct ring_desc* orig_get_tx = np->get_tx.orig;
while ((np->get_tx.orig != np->put_tx.orig) &&
- !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID)) {
+ !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) &&
+ (tx_work < limit)) {
dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n",
dev->name, flags);
@@ -2398,6 +2437,7 @@ static void nv_tx_done(struct net_device *dev)
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
+ tx_work++;
}
} else {
if (flags & NV_TX2_LASTPACKET) {
@@ -2415,6 +2455,7 @@ static void nv_tx_done(struct net_device *dev)
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
+ tx_work++;
}
}
if (unlikely(np->get_tx.orig++ == np->last_tx.orig))
@@ -2426,17 +2467,19 @@ static void nv_tx_done(struct net_device *dev)
np->tx_stop = 0;
netif_wake_queue(dev);
}
+ return tx_work;
}
-static void nv_tx_done_optimized(struct net_device *dev, int limit)
+static int nv_tx_done_optimized(struct net_device *dev, int limit)
{
struct fe_priv *np = netdev_priv(dev);
u32 flags;
+ int tx_work = 0;
struct ring_desc_ex* orig_get_tx = np->get_tx.ex;
while ((np->get_tx.ex != np->put_tx.ex) &&
!((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX_VALID) &&
- (limit-- > 0)) {
+ (tx_work < limit)) {
dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n",
dev->name, flags);
@@ -2460,6 +2503,7 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
+ tx_work++;
if (np->tx_limit) {
nv_tx_flip_ownership(dev);
@@ -2474,6 +2518,7 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
np->tx_stop = 0;
netif_wake_queue(dev);
}
+ return tx_work;
}
/*
@@ -2546,7 +2591,7 @@ static void nv_tx_timeout(struct net_device *dev)
/* 2) check that the packets were not sent already: */
if (!nv_optimized(np))
- nv_tx_done(dev);
+ nv_tx_done(dev, np->tx_ring_size);
else
nv_tx_done_optimized(dev, np->tx_ring_size);
@@ -2907,6 +2952,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
* Changing the MTU is a rare event, it shouldn't matter.
*/
nv_disable_irq(dev);
+ nv_napi_disable(dev);
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock);
@@ -2935,6 +2981,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
+ nv_napi_enable(dev);
nv_enable_irq(dev);
}
return 0;
@@ -3375,50 +3422,71 @@ static void nv_msi_workaround(struct fe_priv *np)
}
}
+static inline int nv_change_interrupt_mode(struct net_device *dev, int total_work)
+{
+ struct fe_priv *np = netdev_priv(dev);
+
+ if (optimization_mode == NV_OPTIMIZATION_MODE_DYNAMIC) {
+ if (total_work > NV_DYNAMIC_THRESHOLD) {
+ /* transition to poll based interrupts */
+ np->quiet_count = 0;
+ if (np->irqmask != NVREG_IRQMASK_CPU) {
+ np->irqmask = NVREG_IRQMASK_CPU;
+ return 1;
+ }
+ } else {
+ if (np->quiet_count < NV_DYNAMIC_MAX_QUIET_COUNT) {
+ np->quiet_count++;
+ } else {
+ /* reached a period of low activity, switch
+ to per tx/rx packet interrupts */
+ if (np->irqmask != NVREG_IRQMASK_THROUGHPUT) {
+ np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
static irqreturn_t nv_nic_irq(int foo, void *data)
{
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- u32 events;
- int i;
+#ifndef CONFIG_FORCEDETH_NAPI
+ int total_work = 0;
+ int loop_count = 0;
+#endif
dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name);
- for (i=0; ; i++) {
- if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
- events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
- writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
- } else {
- events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
- writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
- }
- dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
- if (!(events & np->irqmask))
- break;
-
- nv_msi_workaround(np);
+ if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
+ np->events = readl(base + NvRegIrqStatus);
+ writel(np->events, base + NvRegIrqStatus);
+ } else {
+ np->events = readl(base + NvRegMSIXIrqStatus);
+ writel(np->events, base + NvRegMSIXIrqStatus);
+ }
+ dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
+ if (!(np->events & np->irqmask))
+ return IRQ_NONE;
- spin_lock(&np->lock);
- nv_tx_done(dev);
- spin_unlock(&np->lock);
+ nv_msi_workaround(np);
#ifdef CONFIG_FORCEDETH_NAPI
- if (events & NVREG_IRQ_RX_ALL) {
- spin_lock(&np->lock);
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
- /* Disable furthur receive irq's */
- np->irqmask &= ~NVREG_IRQ_RX_ALL;
+ /* Disable furthur irq's
+ (msix not enabled with napi) */
+ writel(0, base + NvRegIrqMask);
- if (np->msi_flags & NV_MSI_X_ENABLED)
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- spin_unlock(&np->lock);
- }
#else
- if (nv_rx_process(dev, RX_WORK_PER_LOOP)) {
+ do
+ {
+ int work = 0;
+ if ((work = nv_rx_process(dev, RX_WORK_PER_LOOP))) {
if (unlikely(nv_alloc_rx(dev))) {
spin_lock(&np->lock);
if (!np->in_shutdown)
@@ -3426,65 +3494,56 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
spin_unlock(&np->lock);
}
}
-#endif
- if (unlikely(events & NVREG_IRQ_LINK)) {
- spin_lock(&np->lock);
- nv_link_irq(dev);
- spin_unlock(&np->lock);
- }
- if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
- spin_lock(&np->lock);
- nv_linkchange(dev);
- spin_unlock(&np->lock);
- np->link_timeout = jiffies + LINK_TIMEOUT;
- }
- if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
- dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
- dev->name, events);
- }
- if (unlikely(events & (NVREG_IRQ_UNKNOWN))) {
- printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
- dev->name, events);
- }
- if (unlikely(events & NVREG_IRQ_RECOVER_ERROR)) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- np->recover_error = 1;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
- }
- spin_unlock(&np->lock);
- break;
- }
- if (unlikely(i > max_interrupt_work)) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
+ spin_lock(&np->lock);
+ work += nv_tx_done(dev, TX_WORK_PER_LOOP);
+ spin_unlock(&np->lock);
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
- }
- spin_unlock(&np->lock);
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
+ if (!work)
break;
- }
+ total_work += work;
+
+ loop_count++;
}
+ while (loop_count < max_interrupt_work);
+
+ if (nv_change_interrupt_mode(dev, total_work)) {
+ /* setup new irq mask */
+ writel(np->irqmask, base + NvRegIrqMask);
+ }
+
+ if (unlikely(np->events & NVREG_IRQ_LINK)) {
+ spin_lock(&np->lock);
+ nv_link_irq(dev);
+ spin_unlock(&np->lock);
+ }
+ if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+ spin_lock(&np->lock);
+ nv_linkchange(dev);
+ spin_unlock(&np->lock);
+ np->link_timeout = jiffies + LINK_TIMEOUT;
+ }
+ if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+ spin_lock(&np->lock);
+ /* disable interrupts on the nic */
+ if (!(np->msi_flags & NV_MSI_X_ENABLED))
+ writel(0, base + NvRegIrqMask);
+ else
+ writel(np->irqmask, base + NvRegIrqMask);
+ pci_push(base);
+
+ if (!np->in_shutdown) {
+ np->nic_poll_irq = np->irqmask;
+ np->recover_error = 1;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock(&np->lock);
+ }
+#endif
dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name);
- return IRQ_RETVAL(i);
+ return IRQ_HANDLED;
}
/**
@@ -3497,45 +3556,38 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- u32 events;
- int i;
+#ifndef CONFIG_FORCEDETH_NAPI
+ int total_work = 0;
+ int loop_count = 0;
+#endif
dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized\n", dev->name);
- for (i=0; ; i++) {
- if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
- events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
- writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
- } else {
- events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
- writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
- }
- dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
- if (!(events & np->irqmask))
- break;
-
- nv_msi_workaround(np);
+ if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
+ np->events = readl(base + NvRegIrqStatus);
+ writel(np->events, base + NvRegIrqStatus);
+ } else {
+ np->events = readl(base + NvRegMSIXIrqStatus);
+ writel(np->events, base + NvRegMSIXIrqStatus);
+ }
+ dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
+ if (!(np->events & np->irqmask))
+ return IRQ_NONE;
- spin_lock(&np->lock);
- nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
- spin_unlock(&np->lock);
+ nv_msi_workaround(np);
#ifdef CONFIG_FORCEDETH_NAPI
- if (events & NVREG_IRQ_RX_ALL) {
- spin_lock(&np->lock);
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
- /* Disable furthur receive irq's */
- np->irqmask &= ~NVREG_IRQ_RX_ALL;
+ /* Disable furthur irq's
+ (msix not enabled with napi) */
+ writel(0, base + NvRegIrqMask);
- if (np->msi_flags & NV_MSI_X_ENABLED)
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- spin_unlock(&np->lock);
- }
#else
- if (nv_rx_process_optimized(dev, RX_WORK_PER_LOOP)) {
+ do
+ {
+ int work = 0;
+ if ((work = nv_rx_process_optimized(dev, RX_WORK_PER_LOOP))) {
if (unlikely(nv_alloc_rx_optimized(dev))) {
spin_lock(&np->lock);
if (!np->in_shutdown)
@@ -3543,66 +3595,57 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
spin_unlock(&np->lock);
}
}
-#endif
- if (unlikely(events & NVREG_IRQ_LINK)) {
- spin_lock(&np->lock);
- nv_link_irq(dev);
- spin_unlock(&np->lock);
- }
- if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
- spin_lock(&np->lock);
- nv_linkchange(dev);
- spin_unlock(&np->lock);
- np->link_timeout = jiffies + LINK_TIMEOUT;
- }
- if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
- dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
- dev->name, events);
- }
- if (unlikely(events & (NVREG_IRQ_UNKNOWN))) {
- printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
- dev->name, events);
- }
- if (unlikely(events & NVREG_IRQ_RECOVER_ERROR)) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- np->recover_error = 1;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
- }
- spin_unlock(&np->lock);
+ spin_lock(&np->lock);
+ work += nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
+ spin_unlock(&np->lock);
+
+ if (!work)
break;
- }
- if (unlikely(i > max_interrupt_work)) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
+ total_work += work;
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
- }
- spin_unlock(&np->lock);
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
- break;
- }
+ loop_count++;
+ }
+ while (loop_count < max_interrupt_work);
+ if (nv_change_interrupt_mode(dev, total_work)) {
+ /* setup new irq mask */
+ writel(np->irqmask, base + NvRegIrqMask);
+ }
+
+ if (unlikely(np->events & NVREG_IRQ_LINK)) {
+ spin_lock(&np->lock);
+ nv_link_irq(dev);
+ spin_unlock(&np->lock);
}
+ if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+ spin_lock(&np->lock);
+ nv_linkchange(dev);
+ spin_unlock(&np->lock);
+ np->link_timeout = jiffies + LINK_TIMEOUT;
+ }
+ if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+ spin_lock(&np->lock);
+ /* disable interrupts on the nic */
+ if (!(np->msi_flags & NV_MSI_X_ENABLED))
+ writel(0, base + NvRegIrqMask);
+ else
+ writel(np->irqmask, base + NvRegIrqMask);
+ pci_push(base);
+
+ if (!np->in_shutdown) {
+ np->nic_poll_irq = np->irqmask;
+ np->recover_error = 1;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock(&np->lock);
+ }
+
+#endif
dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name);
- return IRQ_RETVAL(i);
+ return IRQ_HANDLED;
}
static irqreturn_t nv_nic_irq_tx(int foo, void *data)
@@ -3627,10 +3670,6 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
spin_unlock_irqrestore(&np->lock, flags);
- if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
- dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
- dev->name, events);
- }
if (unlikely(i > max_interrupt_work)) {
spin_lock_irqsave(&np->lock, flags);
/* disable interrupts on the nic */
@@ -3659,13 +3698,22 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
struct net_device *dev = np->dev;
u8 __iomem *base = get_hwbase(dev);
unsigned long flags;
- int pkts, retcode;
+ int retcode;
+ int tx_work, rx_work;
if (!nv_optimized(np)) {
- pkts = nv_rx_process(dev, budget);
+ spin_lock_irqsave(&np->lock, flags);
+ tx_work = nv_tx_done(dev, np->tx_ring_size);
+ spin_unlock_irqrestore(&np->lock, flags);
+
+ rx_work = nv_rx_process(dev, budget);
retcode = nv_alloc_rx(dev);
} else {
- pkts = nv_rx_process_optimized(dev, budget);
+ spin_lock_irqsave(&np->lock, flags);
+ tx_work = nv_tx_done_optimized(dev, np->tx_ring_size);
+ spin_unlock_irqrestore(&np->lock, flags);
+
+ rx_work = nv_rx_process_optimized(dev, budget);
retcode = nv_alloc_rx_optimized(dev);
}
@@ -3676,44 +3724,42 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
spin_unlock_irqrestore(&np->lock, flags);
}
- if (pkts < budget) {
- /* re-enable receive interrupts */
- spin_lock_irqsave(&np->lock, flags);
-
- __netif_rx_complete(napi);
-
- np->irqmask |= NVREG_IRQ_RX_ALL;
- if (np->msi_flags & NV_MSI_X_ENABLED)
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
+ nv_change_interrupt_mode(dev, tx_work + rx_work);
+ if (unlikely(np->events & NVREG_IRQ_LINK)) {
+ spin_lock_irqsave(&np->lock, flags);
+ nv_link_irq(dev);
spin_unlock_irqrestore(&np->lock, flags);
}
- return pkts;
-}
-#endif
-
-#ifdef CONFIG_FORCEDETH_NAPI
-static irqreturn_t nv_nic_irq_rx(int foo, void *data)
-{
- struct net_device *dev = (struct net_device *) data;
- struct fe_priv *np = netdev_priv(dev);
- u8 __iomem *base = get_hwbase(dev);
- u32 events;
+ if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+ spin_lock_irqsave(&np->lock, flags);
+ nv_linkchange(dev);
+ spin_unlock_irqrestore(&np->lock, flags);
+ np->link_timeout = jiffies + LINK_TIMEOUT;
+ }
+ if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+ spin_lock_irqsave(&np->lock, flags);
+ if (!np->in_shutdown) {
+ np->nic_poll_irq = np->irqmask;
+ np->recover_error = 1;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock_irqrestore(&np->lock, flags);
+ __napi_complete(napi);
+ return rx_work;
+ }
- events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL;
- writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
+ if (rx_work < budget) {
+ /* re-enable interrupts
+ (msix not enabled in napi) */
+ __napi_complete(napi);
- if (events) {
- netif_rx_schedule(&np->napi);
- /* disable receive interrupts on the nic */
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- pci_push(base);
+ writel(np->irqmask, base + NvRegIrqMask);
}
- return IRQ_HANDLED;
+ return rx_work;
}
-#else
+#endif
+
static irqreturn_t nv_nic_irq_rx(int foo, void *data)
{
struct net_device *dev = (struct net_device *) data;
@@ -3760,7 +3806,6 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
return IRQ_RETVAL(i);
}
-#endif
static irqreturn_t nv_nic_irq_other(int foo, void *data)
{
@@ -3810,10 +3855,6 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data)
spin_unlock_irq(&np->lock);
break;
}
- if (events & (NVREG_IRQ_UNKNOWN)) {
- printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
- dev->name, events);
- }
if (unlikely(i > max_interrupt_work)) {
spin_lock_irqsave(&np->lock, flags);
/* disable interrupts on the nic */
@@ -3918,21 +3959,27 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
np->msi_flags |= NV_MSI_X_ENABLED;
if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) {
/* Request irq for rx handling */
- if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, IRQF_SHARED, dev->name, dev) != 0) {
+ sprintf(np->name_rx, "%s-rx", dev->name);
+ if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector,
+ &nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_err;
}
/* Request irq for tx handling */
- if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, IRQF_SHARED, dev->name, dev) != 0) {
+ sprintf(np->name_tx, "%s-tx", dev->name);
+ if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector,
+ &nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_free_rx;
}
/* Request irq for link and timer handling */
- if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, IRQF_SHARED, dev->name, dev) != 0) {
+ sprintf(np->name_other, "%s-other", dev->name);
+ if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector,
+ &nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
@@ -4046,19 +4093,19 @@ static void nv_do_nic_poll(unsigned long data)
mask |= NVREG_IRQ_OTHER;
}
}
- np->nic_poll_irq = 0;
-
/* disable_irq() contains synchronize_irq, thus no irq handler can run now */
if (np->recover_error) {
np->recover_error = 0;
- printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
+ printk(KERN_INFO "%s: MAC in recoverable error state\n", dev->name);
if (netif_running(dev)) {
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);
+ if (np->driver_data & DEV_HAS_POWER_CNTRL)
+ nv_mac_reset(dev);
nv_txrx_reset(dev);
/* drain rx queue */
nv_drain_rxtx(dev);
@@ -4076,6 +4123,11 @@ static void nv_do_nic_poll(unsigned long data)
pci_push(base);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
pci_push(base);
+ /* clear interrupts */
+ if (!(np->msi_flags & NV_MSI_X_ENABLED))
+ writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
+ else
+ writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
/* restart rx engine */
nv_start_rxtx(dev);
@@ -4085,11 +4137,11 @@ static void nv_do_nic_poll(unsigned long data)
}
}
-
writel(mask, base + NvRegIrqMask);
pci_push(base);
if (!using_multi_irqs(dev)) {
+ np->nic_poll_irq = 0;
if (nv_optimized(np))
nv_nic_irq_optimized(0, dev);
else
@@ -4100,18 +4152,22 @@ static void nv_do_nic_poll(unsigned long data)
enable_irq_lockdep(np->pci_dev->irq);
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
+ np->nic_poll_irq &= ~NVREG_IRQ_RX_ALL;
nv_nic_irq_rx(0, dev);
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
+ np->nic_poll_irq &= ~NVREG_IRQ_TX_ALL;
nv_nic_irq_tx(0, dev);
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
}
if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
+ np->nic_poll_irq &= ~NVREG_IRQ_OTHER;
nv_nic_irq_other(0, dev);
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
}
}
+
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4560,6 +4616,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
if (netif_running(dev)) {
nv_disable_irq(dev);
+ nv_napi_disable(dev);
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock);
@@ -4612,6 +4669,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
+ nv_napi_enable(dev);
nv_enable_irq(dev);
}
return 0;
@@ -4738,7 +4796,7 @@ static int nv_set_tx_csum(struct net_device *dev, u32 data)
struct fe_priv *np = netdev_priv(dev);
if (np->driver_data & DEV_HAS_CHECKSUM)
- return ethtool_op_set_tx_hw_csum(dev, data);
+ return ethtool_op_set_tx_csum(dev, data);
else
return -EOPNOTSUPP;
}
@@ -4764,12 +4822,12 @@ static int nv_get_sset_count(struct net_device *dev, int sset)
else
return NV_TEST_COUNT_BASE;
case ETH_SS_STATS:
- if (np->driver_data & DEV_HAS_STATISTICS_V1)
- return NV_DEV_STATISTICS_V1_COUNT;
+ if (np->driver_data & DEV_HAS_STATISTICS_V3)
+ return NV_DEV_STATISTICS_V3_COUNT;
else if (np->driver_data & DEV_HAS_STATISTICS_V2)
return NV_DEV_STATISTICS_V2_COUNT;
- else if (np->driver_data & DEV_HAS_STATISTICS_V3)
- return NV_DEV_STATISTICS_V3_COUNT;
+ else if (np->driver_data & DEV_HAS_STATISTICS_V1)
+ return NV_DEV_STATISTICS_V1_COUNT;
else
return 0;
default:
@@ -5038,9 +5096,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
if (test->flags & ETH_TEST_FL_OFFLINE) {
if (netif_running(dev)) {
netif_stop_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
- napi_disable(&np->napi);
-#endif
+ nv_napi_disable(dev);
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock_irq(&np->lock);
@@ -5098,9 +5154,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
/* restart rx engine */
nv_start_rxtx(dev);
netif_start_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
- napi_enable(&np->napi);
-#endif
+ nv_napi_enable(dev);
nv_enable_hw_interrupts(dev, np->irqmask);
}
}
@@ -5169,6 +5223,7 @@ static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
/* The mgmt unit and driver use a semaphore to access the phy during init */
static int nv_mgmt_acquire_sema(struct net_device *dev)
{
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
int i;
u32 tx_ctrl, mgmt_sema;
@@ -5191,8 +5246,10 @@ static int nv_mgmt_acquire_sema(struct net_device *dev)
/* verify that semaphore was acquired */
tx_ctrl = readl(base + NvRegTransmitterControl);
if (((tx_ctrl & NVREG_XMITCTL_HOST_SEMA_MASK) == NVREG_XMITCTL_HOST_SEMA_ACQ) &&
- ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE))
+ ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE)) {
+ np->mgmt_sema = 1;
return 1;
+ }
else
udelay(50);
}
@@ -5200,6 +5257,51 @@ static int nv_mgmt_acquire_sema(struct net_device *dev)
return 0;
}
+static void nv_mgmt_release_sema(struct net_device *dev)
+{
+ struct fe_priv *np = netdev_priv(dev);
+ u8 __iomem *base = get_hwbase(dev);
+ u32 tx_ctrl;
+
+ if (np->driver_data & DEV_HAS_MGMT_UNIT) {
+ if (np->mgmt_sema) {
+ tx_ctrl = readl(base + NvRegTransmitterControl);
+ tx_ctrl &= ~NVREG_XMITCTL_HOST_SEMA_ACQ;
+ writel(tx_ctrl, base + NvRegTransmitterControl);
+ }
+ }
+}
+
+
+static int nv_mgmt_get_version(struct net_device *dev)
+{
+ struct fe_priv *np = netdev_priv(dev);
+ u8 __iomem *base = get_hwbase(dev);
+ u32 data_ready = readl(base + NvRegTransmitterControl);
+ u32 data_ready2 = 0;
+ unsigned long start;
+ int ready = 0;
+
+ writel(NVREG_MGMTUNITGETVERSION, base + NvRegMgmtUnitGetVersion);
+ writel(data_ready ^ NVREG_XMITCTL_DATA_START, base + NvRegTransmitterControl);
+ start = jiffies;
+ while (time_before(jiffies, start + 5*HZ)) {
+ data_ready2 = readl(base + NvRegTransmitterControl);
+ if ((data_ready & NVREG_XMITCTL_DATA_READY) != (data_ready2 & NVREG_XMITCTL_DATA_READY)) {
+ ready = 1;
+ break;
+ }
+ schedule_timeout_uninterruptible(1);
+ }
+
+ if (!ready || (data_ready2 & NVREG_XMITCTL_DATA_ERROR))
+ return 0;
+
+ np->mgmt_version = readl(base + NvRegMgmtUnitVersion) & NVREG_MGMTUNITVERSION;
+
+ return 1;
+}
+
static int nv_open(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
@@ -5344,9 +5446,7 @@ static int nv_open(struct net_device *dev)
ret = nv_update_linkspeed(dev);
nv_start_rxtx(dev);
netif_start_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
- napi_enable(&np->napi);
-#endif
+ nv_napi_enable(dev);
if (ret) {
netif_carrier_on(dev);
@@ -5378,9 +5478,7 @@ static int nv_close(struct net_device *dev)
spin_lock_irq(&np->lock);
np->in_shutdown = 1;
spin_unlock_irq(&np->lock);
-#ifdef CONFIG_FORCEDETH_NAPI
- napi_disable(&np->napi);
-#endif
+ nv_napi_disable(dev);
synchronize_irq(np->pci_dev->irq);
del_timer_sync(&np->oom_kick);
@@ -5571,14 +5669,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
}
- np->msi_flags = 0;
- if ((id->driver_data & DEV_HAS_MSI) && msi) {
- np->msi_flags |= NV_MSI_CAPABLE;
- }
- if ((id->driver_data & DEV_HAS_MSI_X) && msix) {
- np->msi_flags |= NV_MSI_X_CAPABLE;
- }
-
np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG;
if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) ||
(id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) ||
@@ -5723,14 +5813,35 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
} else {
np->tx_flags = NV_TX2_VALID;
}
- if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) {
- np->irqmask = NVREG_IRQMASK_THROUGHPUT;
- if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
- np->msi_flags |= 0x0003;
- } else {
+
+ np->msi_flags = 0;
+ if ((id->driver_data & DEV_HAS_MSI) && msi) {
+ np->msi_flags |= NV_MSI_CAPABLE;
+ }
+ if ((id->driver_data & DEV_HAS_MSI_X) && msix) {
+ /* msix has had reported issues when modifying irqmask
+ as in the case of napi, therefore, disable for now
+ */
+#ifndef CONFIG_FORCEDETH_NAPI
+ np->msi_flags |= NV_MSI_X_CAPABLE;
+#endif
+ }
+
+ if (optimization_mode == NV_OPTIMIZATION_MODE_CPU) {
np->irqmask = NVREG_IRQMASK_CPU;
if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
np->msi_flags |= 0x0001;
+ } else if (optimization_mode == NV_OPTIMIZATION_MODE_DYNAMIC &&
+ !(id->driver_data & DEV_NEED_TIMERIRQ)) {
+ /* start off in throughput mode */
+ np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+ /* remove support for msix mode */
+ np->msi_flags &= ~NV_MSI_X_CAPABLE;
+ } else {
+ optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;
+ np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+ if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
+ np->msi_flags |= 0x0003;
}
if (id->driver_data & DEV_NEED_TIMERIRQ)
@@ -5771,19 +5882,26 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (id->driver_data & DEV_HAS_MGMT_UNIT) {
/* management unit running on the mac? */
- if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) {
- np->mac_in_use = readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST;
- dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", pci_name(pci_dev), np->mac_in_use);
- if (nv_mgmt_acquire_sema(dev)) {
- /* management unit setup the phy already? */
- if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
- NVREG_XMITCTL_SYNC_PHY_INIT) {
- /* phy is inited by mgmt unit */
- phyinitialized = 1;
- dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
- } else {
- /* we need to init the phy */
- }
+ if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST) &&
+ (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) &&
+ nv_mgmt_acquire_sema(dev) &&
+ nv_mgmt_get_version(dev)) {
+ np->mac_in_use = 1;
+ if (np->mgmt_version > 0) {
+ np->mac_in_use = readl(base + NvRegMgmtUnitControl) & NVREG_MGMTUNITCONTROL_INUSE;
+ }
+ dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n",
+ pci_name(pci_dev), np->mac_in_use);
+ /* management unit setup the phy already? */
+ if (np->mac_in_use &&
+ ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
+ NVREG_XMITCTL_SYNC_PHY_INIT)) {
+ /* phy is inited by mgmt unit */
+ phyinitialized = 1;
+ dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n",
+ pci_name(pci_dev));
+ } else {
+ /* we need to init the phy */
}
}
}
@@ -5945,6 +6063,8 @@ static void __devexit nv_remove(struct pci_dev *pci_dev)
/* restore any phy related changes */
nv_restore_phy(dev);
+ nv_mgmt_release_sema(dev);
+
/* free all structures */
free_rings(dev);
iounmap(get_hwbase(dev));
@@ -5995,6 +6115,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);
+
netif_device_attach(dev);
if (netif_running(dev)) {
rc = nv_open(dev);
@@ -6011,9 +6133,20 @@ static void nv_shutdown(struct pci_dev *pdev)
if (netif_running(dev))
nv_close(dev);
- nv_restore_mac_addr(pdev);
+ /*
+ * Restore the MAC so a kernel started by kexec won't get confused.
+ * If we really go for poweroff, we must not restore the MAC,
+ * otherwise the MAC for WOL will be reversed at least on some boards.
+ */
+ if (system_state != SYSTEM_POWER_OFF) {
+ nv_restore_mac_addr(pdev);
+ }
pci_disable_device(pdev);
+ /*
+ * Apparently it is not possible to reinitialise from D3 hot,
+ * only put the device into D3 if we really go for poweroff.
+ */
if (system_state == SYSTEM_POWER_OFF) {
if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled))
pci_enable_wake(pdev, PCI_D3hot, np->wolenabled);
@@ -6057,115 +6190,115 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+ .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),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+ .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),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+ .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),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+ .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_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
},
{ /* MCP51 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
@@ -6173,15 +6306,15 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
- .driver_data = DEV_NEED_TIMERIRQ|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,
+ .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,
},
{0,},
};
@@ -6209,7 +6342,7 @@ static void __exit exit_nic(void)
module_param(max_interrupt_work, int, 0);
MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
module_param(optimization_mode, int, 0);
-MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer.");
+MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer. In dynamic mode (2), the mode toggles between throughput and CPU mode based on network load.");
module_param(poll_interval, int, 0);
MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535.");
module_param(msi, int, 0);
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index ce900e54d8d..b037ce9857b 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -209,7 +209,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
if (received < budget) {
/* done */
- netif_rx_complete(napi);
+ napi_complete(napi);
(*fep->ops->napi_enable_rx)(dev);
}
return received;
@@ -478,7 +478,7 @@ fs_enet_interrupt(int irq, void *dev_id)
/* NOTE: it is possible for FCCs in NAPI mode */
/* to submit a spurious interrupt while in poll */
if (napi_ok)
- __netif_rx_schedule(&fep->napi);
+ __napi_schedule(&fep->napi);
}
}
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/fsl_pq_mdio.c
index f3706e415b4..b3079a5a7f2 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -1,13 +1,12 @@
/*
- * drivers/net/gianfar_mii.c
- *
- * Gianfar Ethernet Driver -- MIIM bus implementation
+ * Freescale PowerQUICC Ethernet Driver -- MIIM bus implementation
* Provides Bus interface for MIIM regs
*
- * Author: Andy Fleming
- * Maintainer: Kumar Gala
+ * Author: Andy Fleming <afleming@freescale.com>
+ *
+ * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc.
*
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
+ * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips)
*
* 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
@@ -40,9 +39,10 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+#include <asm/ucc.h>
#include "gianfar.h"
-#include "gianfar_mii.h"
+#include "fsl_pq_mdio.h"
/*
* Write value to the PHY at mii_id at register regnum,
@@ -53,17 +53,17 @@
* the local mdio pins, which may not be the same as system mdio bus, used for
* controlling the external PHYs, for example.
*/
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
- int regnum, u16 value)
+int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
+ int regnum, u16 value)
{
/* Set the PHY address and the register address we want to write */
- gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+ out_be32(&regs->miimadd, (mii_id << 8) | regnum);
/* Write out the value we want */
- gfar_write(&regs->miimcon, value);
+ out_be32(&regs->miimcon, value);
/* Wait for the transaction to finish */
- while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
+ while (in_be32(&regs->miimind) & MIIMIND_BUSY)
cpu_relax();
return 0;
@@ -75,75 +75,77 @@ int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
* done on the bus attached to the local interface,
* which may be different from the generic mdio bus
* This is helpful in programming interfaces like
- * the TBI which, inturn, control interfaces like onchip SERDES
+ * the TBI which, in turn, control interfaces like onchip SERDES
* and are always tied to the local mdio pins, which may not be the
* same as system mdio bus, used for controlling the external PHYs, for eg.
*/
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum)
+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs,
+ int mii_id, int regnum)
{
u16 value;
/* Set the PHY address and the register address we want to read */
- gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+ out_be32(&regs->miimadd, (mii_id << 8) | regnum);
/* Clear miimcom, and then initiate a read */
- gfar_write(&regs->miimcom, 0);
- gfar_write(&regs->miimcom, MII_READ_COMMAND);
+ out_be32(&regs->miimcom, 0);
+ out_be32(&regs->miimcom, MII_READ_COMMAND);
/* Wait for the transaction to finish */
- while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
+ while (in_be32(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
cpu_relax();
/* Grab the value of the register from miimstat */
- value = gfar_read(&regs->miimstat);
+ value = in_be32(&regs->miimstat);
return value;
}
-/* Write value to the PHY at mii_id at register regnum,
+/*
+ * Write value to the PHY at mii_id at register regnum,
* on the bus, waiting until the write is done before returning.
- * All PHY configuration is done through the TSEC1 MIIM regs */
-int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+ */
+int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
{
- struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
+ struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
/* Write to the local MII regs */
- return(gfar_local_mdio_write(regs, mii_id, regnum, value));
+ return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value));
}
-/* Read the bus for PHY at addr mii_id, register regnum, and
- * return the value. Clears miimcom first. All PHY
- * configuration has to be done through the TSEC1 MIIM regs */
-int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+/*
+ * Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value. Clears miimcom first.
+ */
+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
- struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
+ struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
/* Read the local MII regs */
- return(gfar_local_mdio_read(regs, mii_id, regnum));
+ return(fsl_pq_local_mdio_read(regs, mii_id, regnum));
}
/* Reset the MIIM registers, and wait for the bus to free */
-static int gfar_mdio_reset(struct mii_bus *bus)
+static int fsl_pq_mdio_reset(struct mii_bus *bus)
{
- struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
- unsigned int timeout = PHY_INIT_TIMEOUT;
+ struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
+ int timeout = PHY_INIT_TIMEOUT;
mutex_lock(&bus->mdio_lock);
/* Reset the management interface */
- gfar_write(&regs->miimcfg, MIIMCFG_RESET);
+ out_be32(&regs->miimcfg, MIIMCFG_RESET);
/* Setup the MII Mgmt clock speed */
- gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
+ out_be32(&regs->miimcfg, MIIMCFG_INIT_VALUE);
/* Wait until the bus is free */
- while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
- --timeout)
+ while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
cpu_relax();
mutex_unlock(&bus->mdio_lock);
- if(timeout == 0) {
+ if (timeout < 0) {
printk(KERN_ERR "%s: The MII Bus is stuck!\n",
bus->name);
return -EBUSY;
@@ -190,18 +192,21 @@ static int *create_irq_map(struct device_node *np)
return irqs;
}
-
-void gfar_mdio_bus_name(char *name, struct device_node *np)
+void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
{
- const u32 *reg;
+ const u32 *addr;
+ u64 taddr = OF_BAD_ADDR;
- reg = of_get_property(np, "reg", NULL);
+ addr = of_get_address(np, 0, NULL, NULL);
+ if (addr)
+ taddr = of_translate_address(np, addr);
- snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0);
+ snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name,
+ (unsigned long long)taddr);
}
/* Scan the bus in reverse, looking for an empty spot */
-static int gfar_mdio_find_free(struct mii_bus *new_bus)
+static int fsl_pq_mdio_find_free(struct mii_bus *new_bus)
{
int i;
@@ -218,27 +223,85 @@ static int gfar_mdio_find_free(struct mii_bus *new_bus)
return i;
}
-static int gfar_mdio_probe(struct of_device *ofdev,
- const struct of_device_id *match)
+
+#ifdef CONFIG_GIANFAR
+static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs)
{
- struct gfar_mii __iomem *regs;
struct gfar __iomem *enet_regs;
- struct mii_bus *new_bus;
+
+ /*
+ * This is mildly evil, but so is our hardware for doing this.
+ * Also, we have to cast back to struct gfar because of
+ * definition weirdness done in gianfar.h.
+ */
+ enet_regs = (struct gfar __iomem *)
+ ((char __iomem *)regs - offsetof(struct gfar, gfar_mii_regs));
+
+ return &enet_regs->tbipa;
+}
+#endif
+
+
+#ifdef CONFIG_UCC_GETH
+static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id)
+{
+ struct device_node *np = NULL;
int err = 0;
- u64 addr, size;
+
+ for_each_compatible_node(np, NULL, "ucc_geth") {
+ struct resource tempres;
+
+ err = of_address_to_resource(np, 0, &tempres);
+ if (err)
+ continue;
+
+ /* if our mdio regs fall within this UCC regs range */
+ if ((start >= tempres.start) && (end <= tempres.end)) {
+ /* Find the id of the UCC */
+ const u32 *id;
+
+ id = of_get_property(np, "cell-index", NULL);
+ if (!id) {
+ id = of_get_property(np, "device-id", NULL);
+ if (!id)
+ continue;
+ }
+
+ *ucc_id = *id;
+
+ return 0;
+ }
+ }
+
+ if (err)
+ return err;
+ else
+ return -EINVAL;
+}
+#endif
+
+
+static int fsl_pq_mdio_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
struct device_node *np = ofdev->node;
struct device_node *tbi;
+ struct fsl_pq_mdio __iomem *regs;
+ u32 __iomem *tbipa;
+ struct mii_bus *new_bus;
int tbiaddr = -1;
+ u64 addr, size;
+ int err = 0;
new_bus = mdiobus_alloc();
if (NULL == new_bus)
return -ENOMEM;
- new_bus->name = "Gianfar MII Bus",
- new_bus->read = &gfar_mdio_read,
- new_bus->write = &gfar_mdio_write,
- new_bus->reset = &gfar_mdio_reset,
- gfar_mdio_bus_name(new_bus->id, np);
+ new_bus->name = "Freescale PowerQUICC MII Bus",
+ new_bus->read = &fsl_pq_mdio_read,
+ new_bus->write = &fsl_pq_mdio_write,
+ new_bus->reset = &fsl_pq_mdio_reset,
+ fsl_pq_mdio_bus_name(new_bus->id, np);
/* Set the PHY base address */
addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
@@ -253,7 +316,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
new_bus->irq = create_irq_map(np);
- if (new_bus->irq == NULL) {
+ if (NULL == new_bus->irq) {
err = -ENOMEM;
goto err_unmap_regs;
}
@@ -261,13 +324,34 @@ static int gfar_mdio_probe(struct of_device *ofdev,
new_bus->parent = &ofdev->dev;
dev_set_drvdata(&ofdev->dev, new_bus);
- /*
- * This is mildly evil, but so is our hardware for doing this.
- * Also, we have to cast back to struct gfar_mii because of
- * definition weirdness done in gianfar.h.
- */
- enet_regs = (struct gfar __iomem *)
- ((char *)regs - offsetof(struct gfar, gfar_mii_regs));
+ if (of_device_is_compatible(np, "fsl,gianfar-mdio") ||
+ of_device_is_compatible(np, "fsl,gianfar-tbi") ||
+ of_device_is_compatible(np, "gianfar")) {
+#ifdef CONFIG_GIANFAR
+ tbipa = get_gfar_tbipa(regs);
+#else
+ err = -ENODEV;
+ goto err_free_irqs;
+#endif
+ } else if (of_device_is_compatible(np, "fsl,ucc-mdio") ||
+ of_device_is_compatible(np, "ucc_geth_phy")) {
+#ifdef CONFIG_UCC_GETH
+ u32 id;
+
+ 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);
+#else
+ err = -ENODEV;
+ goto err_free_irqs;
+#endif
+ } else {
+ err = -ENODEV;
+ goto err_free_irqs;
+ }
for_each_child_of_node(np, tbi) {
if (!strncmp(tbi->type, "tbi-phy", 8))
@@ -282,9 +366,9 @@ static int gfar_mdio_probe(struct of_device *ofdev,
}
if (tbiaddr == -1) {
- gfar_write(&enet_regs->tbipa, 0);
+ out_be32(tbipa, 0);
- tbiaddr = gfar_mdio_find_free(new_bus);
+ tbiaddr = fsl_pq_mdio_find_free(new_bus);
}
/*
@@ -297,7 +381,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
goto err_free_irqs;
}
- gfar_write(&enet_regs->tbipa, tbiaddr);
+ out_be32(tbipa, tbiaddr);
/*
* The TBIPHY-only buses will find PHYs at every address,
@@ -308,7 +392,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
err = mdiobus_register(new_bus);
- if (err != 0) {
+ if (err) {
printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
new_bus->name);
goto err_free_irqs;
@@ -321,57 +405,64 @@ err_free_irqs:
err_unmap_regs:
iounmap(regs);
err_free_bus:
- mdiobus_free(new_bus);
+ kfree(new_bus);
return err;
}
-static int gfar_mdio_remove(struct of_device *ofdev)
+static int fsl_pq_mdio_remove(struct of_device *ofdev)
{
- struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+ struct device *device = &ofdev->dev;
+ struct mii_bus *bus = dev_get_drvdata(device);
mdiobus_unregister(bus);
- dev_set_drvdata(&ofdev->dev, NULL);
+ dev_set_drvdata(device, NULL);
iounmap((void __iomem *)bus->priv);
bus->priv = NULL;
- kfree(bus->irq);
mdiobus_free(bus);
return 0;
}
-static struct of_device_id gfar_mdio_match[] =
-{
+static struct of_device_id fsl_pq_mdio_match[] = {
{
- .compatible = "fsl,gianfar-mdio",
+ .type = "mdio",
+ .compatible = "ucc_geth_phy",
+ },
+ {
+ .type = "mdio",
+ .compatible = "gianfar",
+ },
+ {
+ .compatible = "fsl,ucc-mdio",
},
{
.compatible = "fsl,gianfar-tbi",
},
{
- .type = "mdio",
- .compatible = "gianfar",
+ .compatible = "fsl,gianfar-mdio",
},
{},
};
-static struct of_platform_driver gianfar_mdio_driver = {
- .name = "fsl-gianfar_mdio",
- .match_table = gfar_mdio_match,
-
- .probe = gfar_mdio_probe,
- .remove = gfar_mdio_remove,
+static struct of_platform_driver fsl_pq_mdio_driver = {
+ .name = "fsl-pq_mdio",
+ .probe = fsl_pq_mdio_probe,
+ .remove = fsl_pq_mdio_remove,
+ .match_table = fsl_pq_mdio_match,
};
-int __init gfar_mdio_init(void)
+int __init fsl_pq_mdio_init(void)
{
- return of_register_platform_driver(&gianfar_mdio_driver);
+ return of_register_platform_driver(&fsl_pq_mdio_driver);
}
-void gfar_mdio_exit(void)
+void fsl_pq_mdio_exit(void)
{
- of_unregister_platform_driver(&gianfar_mdio_driver);
+ 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/fsl_pq_mdio.h b/drivers/net/fsl_pq_mdio.h
new file mode 100644
index 00000000000..36dad527410
--- /dev/null
+++ b/drivers/net/fsl_pq_mdio.h
@@ -0,0 +1,45 @@
+/*
+ * Freescale PowerQUICC MDIO Driver -- MII Management Bus Implementation
+ * Driver for the MDIO bus controller on Freescale PowerQUICC processors
+ *
+ * Author: Andy Fleming
+ *
+ * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef __FSL_PQ_MDIO_H
+#define __FSL_PQ_MDIO_H
+
+#define MIIMIND_BUSY 0x00000001
+#define MIIMIND_NOTVALID 0x00000004
+#define MIIMCFG_INIT_VALUE 0x00000007
+#define MIIMCFG_RESET 0x80000000
+
+#define MII_READ_COMMAND 0x00000001
+
+struct fsl_pq_mdio {
+ u32 miimcfg; /* MII management configuration reg */
+ u32 miimcom; /* MII management command reg */
+ u32 miimadd; /* MII management address reg */
+ u32 miimcon; /* MII management control reg */
+ u32 miimstat; /* MII management status reg */
+ u32 miimind; /* MII management indication reg */
+ u8 reserved[28]; /* Space holder */
+ u32 utbipar; /* TBI phy address reg (only on UCC) */
+} __attribute__ ((packed));
+
+
+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
+int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
+int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
+ int regnum, u16 value);
+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum);
+int __init fsl_pq_mdio_init(void);
+void fsl_pq_mdio_exit(void);
+void fsl_pq_mdio_bus_name(char *name, struct device_node *np);
+#endif /* FSL_PQ_MDIO_H */
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index ea530673236..9d81e7a48db 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -93,7 +93,7 @@
#include <linux/of.h>
#include "gianfar.h"
-#include "gianfar_mii.h"
+#include "fsl_pq_mdio.h"
#define TX_TIMEOUT (1*HZ)
#undef BRIEF_GFAR_ERRORS
@@ -140,13 +140,26 @@ static void gfar_halt_nodisable(struct net_device *dev);
void gfar_start(struct net_device *dev);
static void gfar_clear_exact_match(struct net_device *dev);
static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
-
-extern const struct ethtool_ops gfar_ethtool_ops;
+static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION("Gianfar Ethernet Driver");
MODULE_LICENSE("GPL");
+static const struct net_device_ops gfar_netdev_ops = {
+ .ndo_open = gfar_enet_open,
+ .ndo_start_xmit = gfar_start_xmit,
+ .ndo_stop = gfar_close,
+ .ndo_change_mtu = gfar_change_mtu,
+ .ndo_set_multicast_list = gfar_set_multi,
+ .ndo_tx_timeout = gfar_timeout,
+ .ndo_do_ioctl = gfar_ioctl,
+ .ndo_vlan_rx_register = gfar_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = gfar_netpoll,
+#endif
+};
+
/* Returns 1 if incoming frames use an FCB */
static inline int gfar_uses_fcb(struct gfar_private *priv)
{
@@ -166,6 +179,9 @@ static int gfar_of_init(struct net_device *dev)
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;
if (!np || !of_device_is_available(np))
return -ENODEV;
@@ -195,6 +211,26 @@ static int gfar_of_init(struct net_device *dev)
}
}
+ stash = of_get_property(np, "bd-stash", NULL);
+
+ if(stash) {
+ priv->device_flags |= FSL_GIANFAR_DEV_HAS_BD_STASHING;
+ priv->bd_stash_en = 1;
+ }
+
+ stash_len = of_get_property(np, "rx-stash-len", NULL);
+
+ if (stash_len)
+ priv->rx_stash_size = *stash_len;
+
+ stash_idx = of_get_property(np, "rx-stash-idx", NULL);
+
+ if (stash_idx)
+ priv->rx_stash_index = *stash_idx;
+
+ if (stash_len || stash_idx)
+ priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING;
+
mac_addr = of_get_mac_address(np);
if (mac_addr)
memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN);
@@ -255,7 +291,7 @@ static int gfar_of_init(struct net_device *dev)
of_node_put(phy);
of_node_put(mdio);
- gfar_mdio_bus_name(bus_name, mdio);
+ fsl_pq_mdio_bus_name(bus_name, mdio);
snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
bus_name, *id);
}
@@ -329,8 +365,10 @@ static int gfar_probe(struct of_device *ofdev,
return -ENOMEM;
priv = netdev_priv(dev);
- priv->dev = dev;
+ priv->ndev = dev;
+ priv->ofdev = ofdev;
priv->node = ofdev->node;
+ SET_NETDEV_DEV(dev, &ofdev->dev);
err = gfar_of_init(dev);
@@ -351,6 +389,9 @@ static int gfar_probe(struct of_device *ofdev,
/* Reset MAC layer */
gfar_write(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
+ /* We need to delay at least 3 TX clocks */
+ udelay(2);
+
tempval = (MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
gfar_write(&priv->regs->maccfg1, tempval);
@@ -366,21 +407,12 @@ static int gfar_probe(struct of_device *ofdev,
SET_NETDEV_DEV(dev, &ofdev->dev);
/* Fill in the dev structure */
- dev->open = gfar_enet_open;
- dev->hard_start_xmit = gfar_start_xmit;
- dev->tx_timeout = gfar_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = gfar_netpoll;
-#endif
- dev->stop = gfar_close;
- dev->change_mtu = gfar_change_mtu;
dev->mtu = 1500;
- dev->set_multicast_list = gfar_set_multi;
+ dev->netdev_ops = &gfar_netdev_ops;
dev->ethtool_ops = &gfar_ethtool_ops;
- dev->do_ioctl = gfar_ioctl;
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
priv->rx_csum_enable = 1;
@@ -390,11 +422,8 @@ static int gfar_probe(struct of_device *ofdev,
priv->vlgrp = NULL;
- if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
- dev->vlan_rx_register = gfar_vlan_rx_register;
-
+ if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN)
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- }
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
priv->extended_hash = 1;
@@ -422,7 +451,7 @@ static int gfar_probe(struct of_device *ofdev,
priv->hash_width = 8;
priv->hash_regs[0] = &priv->regs->gaddr0;
- priv->hash_regs[1] = &priv->regs->gaddr1;
+ priv->hash_regs[1] = &priv->regs->gaddr1;
priv->hash_regs[2] = &priv->regs->gaddr2;
priv->hash_regs[3] = &priv->regs->gaddr3;
priv->hash_regs[4] = &priv->regs->gaddr4;
@@ -463,6 +492,9 @@ static int gfar_probe(struct of_device *ofdev,
goto register_fail;
}
+ device_init_wakeup(&dev->dev,
+ priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+
/* fill out IRQ number and name fields */
len_devname = strlen(dev->name);
strncpy(&priv->int_name_tx[0], dev->name, len_devname);
@@ -508,7 +540,7 @@ static int gfar_remove(struct of_device *ofdev)
dev_set_drvdata(&ofdev->dev, NULL);
iounmap(priv->regs);
- free_netdev(priv->dev);
+ free_netdev(priv->ndev);
return 0;
}
@@ -517,7 +549,7 @@ static int gfar_remove(struct of_device *ofdev)
static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
{
struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
unsigned long flags;
u32 tempval;
@@ -566,7 +598,7 @@ static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
static int gfar_resume(struct of_device *ofdev)
{
struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
unsigned long flags;
u32 tempval;
int magic_packet = priv->wol_en &&
@@ -835,12 +867,12 @@ void stop_gfar(struct net_device *dev)
free_irq(priv->interruptTransmit, dev);
free_irq(priv->interruptReceive, dev);
} else {
- free_irq(priv->interruptTransmit, dev);
+ free_irq(priv->interruptTransmit, dev);
}
free_skb_resources(priv);
- dma_free_coherent(&dev->dev,
+ dma_free_coherent(&priv->ofdev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -862,12 +894,12 @@ static void free_skb_resources(struct gfar_private *priv)
if (!priv->tx_skbuff[i])
continue;
- dma_unmap_single(&priv->dev->dev, txbdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, txbdp->bufPtr,
txbdp->length, DMA_TO_DEVICE);
txbdp->lstatus = 0;
for (j = 0; j < skb_shinfo(priv->tx_skbuff[i])->nr_frags; j++) {
txbdp++;
- dma_unmap_page(&priv->dev->dev, txbdp->bufPtr,
+ dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr,
txbdp->length, DMA_TO_DEVICE);
}
txbdp++;
@@ -884,7 +916,7 @@ static void free_skb_resources(struct gfar_private *priv)
if(priv->rx_skbuff != NULL) {
for (i = 0; i < priv->rx_ring_size; i++) {
if (priv->rx_skbuff[i]) {
- dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, rxbdp->bufPtr,
priv->rx_buffer_size,
DMA_FROM_DEVICE);
@@ -950,7 +982,7 @@ int startup_gfar(struct net_device *dev)
gfar_write(&regs->imask, IMASK_INIT_CLEAR);
/* Allocate memory for the buffer descriptors */
- vaddr = (unsigned long) dma_alloc_coherent(&dev->dev,
+ vaddr = (unsigned long) dma_alloc_coherent(&priv->ofdev->dev,
sizeof (struct txbd8) * priv->tx_ring_size +
sizeof (struct rxbd8) * priv->rx_ring_size,
&addr, GFP_KERNEL);
@@ -1162,7 +1194,7 @@ err_rxalloc_fail:
rx_skb_fail:
free_skb_resources(priv);
tx_skb_fail:
- dma_free_coherent(&dev->dev,
+ dma_free_coherent(&priv->ofdev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -1180,6 +1212,8 @@ static int gfar_enet_open(struct net_device *dev)
napi_enable(&priv->napi);
+ skb_queue_head_init(&priv->rx_recycle);
+
/* Initialize a bunch of registers */
init_registers(dev);
@@ -1200,13 +1234,24 @@ static int gfar_enet_open(struct net_device *dev)
netif_start_queue(dev);
+ device_set_wakeup_enable(&dev->dev, priv->wol_en);
+
return err;
}
-static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
+static inline struct txfcb *gfar_add_fcb(struct sk_buff **skbp)
{
- struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
-
+ struct txfcb *fcb;
+ struct sk_buff *skb = *skbp;
+
+ if (unlikely(skb_headroom(skb) < GMAC_FCB_LEN)) {
+ struct sk_buff *old_skb = skb;
+ skb = skb_realloc_headroom(old_skb, GMAC_FCB_LEN);
+ if (!skb)
+ return NULL;
+ dev_kfree_skb_any(old_skb);
+ }
+ fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
cacheable_memzero(fcb, GMAC_FCB_LEN);
return fcb;
@@ -1281,7 +1326,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&priv->txlock, flags);
/* check if there is space to queue this packet */
- if (nr_frags > priv->num_txbdfree) {
+ if ((nr_frags+1) > priv->num_txbdfree) {
/* no space, stop the queue */
netif_stop_queue(dev);
dev->stats.tx_fifo_errors++;
@@ -1311,7 +1356,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (i == nr_frags - 1)
lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
- bufaddr = dma_map_page(&dev->dev,
+ bufaddr = dma_map_page(&priv->ofdev->dev,
skb_shinfo(skb)->frags[i].page,
skb_shinfo(skb)->frags[i].page_offset,
length,
@@ -1327,23 +1372,25 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Set up checksumming */
if (CHECKSUM_PARTIAL == skb->ip_summed) {
- fcb = gfar_add_fcb(skb);
- lstatus |= BD_LFLAG(TXBD_TOE);
- gfar_tx_checksum(skb, fcb);
+ fcb = gfar_add_fcb(&skb);
+ if (likely(fcb != NULL)) {
+ lstatus |= BD_LFLAG(TXBD_TOE);
+ gfar_tx_checksum(skb, fcb);
+ }
}
if (priv->vlgrp && vlan_tx_tag_present(skb)) {
- if (unlikely(NULL == fcb)) {
- fcb = gfar_add_fcb(skb);
+ if (unlikely(NULL == fcb))
+ fcb = gfar_add_fcb(&skb);
+ if (likely(fcb != NULL)) {
lstatus |= BD_LFLAG(TXBD_TOE);
+ gfar_tx_vlan(skb, fcb);
}
-
- gfar_tx_vlan(skb, fcb);
}
/* setup the TxBD length and buffer pointer for the first BD */
priv->tx_skbuff[priv->skb_curtx] = skb;
- txbdp_start->bufPtr = dma_map_single(&dev->dev, skb->data,
+ txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
@@ -1396,6 +1443,7 @@ static int gfar_close(struct net_device *dev)
napi_disable(&priv->napi);
+ skb_queue_purge(&priv->rx_recycle);
cancel_work_sync(&priv->reset_task);
stop_gfar(dev);
@@ -1423,15 +1471,11 @@ static void gfar_vlan_rx_register(struct net_device *dev,
{
struct gfar_private *priv = netdev_priv(dev);
unsigned long flags;
- struct vlan_group *old_grp;
u32 tempval;
spin_lock_irqsave(&priv->rxlock, flags);
- old_grp = priv->vlgrp;
-
- if (old_grp == grp)
- return;
+ priv->vlgrp = grp;
if (grp) {
/* Enable VLAN tag insertion */
@@ -1532,7 +1576,7 @@ static void gfar_reset_task(struct work_struct *work)
{
struct gfar_private *priv = container_of(work, struct gfar_private,
reset_task);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
if (dev->flags & IFF_UP) {
stop_gfar(dev);
@@ -1579,7 +1623,7 @@ static int gfar_clean_tx_ring(struct net_device *dev)
(lstatus & BD_LENGTH_MASK))
break;
- dma_unmap_single(&dev->dev,
+ dma_unmap_single(&priv->ofdev->dev,
bdp->bufPtr,
bdp->length,
DMA_TO_DEVICE);
@@ -1588,7 +1632,7 @@ static int gfar_clean_tx_ring(struct net_device *dev)
bdp = next_txbd(bdp, base, tx_ring_size);
for (i = 0; i < frags; i++) {
- dma_unmap_page(&dev->dev,
+ dma_unmap_page(&priv->ofdev->dev,
bdp->bufPtr,
bdp->length,
DMA_TO_DEVICE);
@@ -1596,7 +1640,17 @@ static int gfar_clean_tx_ring(struct net_device *dev)
bdp = next_txbd(bdp, base, tx_ring_size);
}
- dev_kfree_skb_any(skb);
+ /*
+ * If there's room in the queue (limit it to rx_buffer_size)
+ * we add this skb back into the pool, if it's the right size
+ */
+ if (skb_queue_len(&priv->rx_recycle) < priv->rx_ring_size &&
+ skb_recycle_check(skb, priv->rx_buffer_size +
+ RXBUF_ALIGNMENT))
+ __skb_queue_head(&priv->rx_recycle, skb);
+ else
+ dev_kfree_skb_any(skb);
+
priv->tx_skbuff[skb_dirtytx] = NULL;
skb_dirtytx = (skb_dirtytx + 1) &
@@ -1627,9 +1681,15 @@ static void gfar_schedule_cleanup(struct net_device *dev)
spin_lock_irqsave(&priv->txlock, flags);
spin_lock(&priv->rxlock);
- if (netif_rx_schedule_prep(&priv->napi)) {
+ if (napi_schedule_prep(&priv->napi)) {
gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED);
- __netif_rx_schedule(&priv->napi);
+ __napi_schedule(&priv->napi);
+ } else {
+ /*
+ * Clear IEVENT, so interrupts aren't called again
+ * because of the packets that have already arrived.
+ */
+ gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK);
}
spin_unlock(&priv->rxlock);
@@ -1649,7 +1709,7 @@ static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
struct gfar_private *priv = netdev_priv(dev);
u32 lstatus;
- bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
+ bdp->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
priv->rx_buffer_size, DMA_FROM_DEVICE);
lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
@@ -1669,8 +1729,10 @@ struct sk_buff * gfar_new_skb(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
struct sk_buff *skb = NULL;
- /* We have to allocate the skb, so keep trying till we succeed */
- skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT);
+ skb = __skb_dequeue(&priv->rx_recycle);
+ if (!skb)
+ skb = netdev_alloc_skb(dev,
+ priv->rx_buffer_size + RXBUF_ALIGNMENT);
if (!skb)
return NULL;
@@ -1807,7 +1869,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
skb = priv->rx_skbuff[priv->skb_currx];
- dma_unmap_single(&priv->dev->dev, bdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
priv->rx_buffer_size, DMA_FROM_DEVICE);
/* We drop the frame if we failed to allocate a new buffer */
@@ -1818,7 +1880,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
if (unlikely(!newskb))
newskb = skb;
else if (skb)
- dev_kfree_skb_any(skb);
+ __skb_queue_head(&priv->rx_recycle, skb);
} else {
/* Increment the number of packets */
dev->stats.rx_packets++;
@@ -1830,6 +1892,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
skb_put(skb, pkt_len);
dev->stats.rx_bytes += pkt_len;
+ if (in_irq() || irqs_disabled())
+ printk("Interrupt problem!\n");
gfar_process_frame(dev, skb, amount_pull);
} else {
@@ -1865,7 +1929,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
static int gfar_poll(struct napi_struct *napi, int budget)
{
struct gfar_private *priv = container_of(napi, struct gfar_private, napi);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
int tx_cleaned = 0;
int rx_cleaned = 0;
unsigned long flags;
@@ -1886,7 +1950,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
return budget;
if (rx_cleaned < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* Clear the halt bit in RSTAT */
gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
@@ -2303,23 +2367,12 @@ static struct of_platform_driver gfar_driver = {
static int __init gfar_init(void)
{
- int err = gfar_mdio_init();
-
- if (err)
- return err;
-
- err = of_register_platform_driver(&gfar_driver);
-
- if (err)
- gfar_mdio_exit();
-
- return err;
+ return of_register_platform_driver(&gfar_driver);
}
static void __exit gfar_exit(void)
{
of_unregister_platform_driver(&gfar_driver);
- gfar_mdio_exit();
}
module_init(gfar_init);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index b1a83344acc..dd499d7cde2 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -46,7 +46,6 @@
#include <linux/workqueue.h>
#include <linux/ethtool.h>
#include <linux/fsl_devices.h>
-#include "gianfar_mii.h"
/* The maximum number of packets to be handled in one call of gfar_poll */
#define GFAR_DEV_WEIGHT 64
@@ -126,9 +125,12 @@ extern const char gfar_driver_version[];
#define DEFAULT_RX_COALESCE 0
#define DEFAULT_RXCOUNT 0
-#define MIIMCFG_INIT_VALUE 0x00000007
-#define MIIMCFG_RESET 0x80000000
-#define MIIMIND_BUSY 0x00000001
+#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+ | SUPPORTED_10baseT_Full \
+ | SUPPORTED_100baseT_Half \
+ | SUPPORTED_100baseT_Full \
+ | SUPPORTED_Autoneg \
+ | SUPPORTED_MII)
/* TBI register addresses */
#define MII_TBICON 0x11
@@ -312,7 +314,7 @@ extern const char gfar_driver_version[];
#define ATTRELI_EI(x) (x)
#define BD_LFLAG(flags) ((flags) << 16)
-#define BD_LENGTH_MASK 0x00ff
+#define BD_LENGTH_MASK 0x0000ffff
/* TxBD status field bits */
#define TXBD_READY 0x8000
@@ -736,7 +738,8 @@ struct gfar_private {
spinlock_t rxlock;
struct device_node *node;
- struct net_device *dev;
+ struct net_device *ndev;
+ struct of_device *ofdev;
struct napi_struct napi;
/* skb array and index */
@@ -756,6 +759,8 @@ struct gfar_private {
unsigned int rx_stash_size;
unsigned int rx_stash_index;
+ struct sk_buff_head rx_recycle;
+
struct vlan_group *vlgrp;
/* Unprotected fields */
@@ -826,8 +831,7 @@ extern void gfar_halt(struct net_device *dev);
extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
int enable, u32 regnum, u32 read);
void gfar_init_sysfs(struct net_device *dev);
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
- int regnum, u16 value);
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
+
+extern const struct ethtool_ops gfar_ethtool_ops;
#endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 59b3b5d98ef..dbf06e9313c 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -600,6 +600,7 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
spin_lock_irqsave(&priv->bflock, flags);
priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
+ device_set_wakeup_enable(&dev->dev, priv->wol_en);
spin_unlock_irqrestore(&priv->bflock, flags);
return 0;
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
deleted file mode 100644
index 65c242cd468..00000000000
--- a/drivers/net/gianfar_mii.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * drivers/net/gianfar_mii.h
- *
- * Gianfar Ethernet Driver -- MII Management Bus Implementation
- * Driver for the MDIO bus controller in the Gianfar register space
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala
- *
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-#ifndef __GIANFAR_MII_H
-#define __GIANFAR_MII_H
-
-struct gfar_private; /* forward ref */
-
-#define MIIMIND_BUSY 0x00000001
-#define MIIMIND_NOTVALID 0x00000004
-
-#define MII_READ_COMMAND 0x00000001
-
-#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
- | SUPPORTED_10baseT_Full \
- | SUPPORTED_100baseT_Half \
- | SUPPORTED_100baseT_Full \
- | SUPPORTED_Autoneg \
- | SUPPORTED_MII)
-
-struct gfar_mii {
- u32 miimcfg; /* 0x.520 - MII Management Config Register */
- u32 miimcom; /* 0x.524 - MII Management Command Register */
- u32 miimadd; /* 0x.528 - MII Management Address Register */
- u32 miimcon; /* 0x.52c - MII Management Control Register */
- u32 miimstat; /* 0x.530 - MII Management Status Register */
- u32 miimind; /* 0x.534 - MII Management Indicator Register */
-};
-
-int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
-int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
- int regnum, u16 value);
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
-struct mii_bus *gfar_get_miibus(const struct gfar_private *priv);
-int __init gfar_mdio_init(void);
-void gfar_mdio_exit(void);
-
-void gfar_mdio_bus_name(char *name, struct device_node *np);
-#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 782c2017008..dd26da74f27 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -53,6 +53,9 @@ static ssize_t gfar_set_bd_stash(struct device *dev,
u32 temp;
unsigned long flags;
+ if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING))
+ return count;
+
/* Find out the new setting */
if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
new_setting = 1;
@@ -81,7 +84,7 @@ static ssize_t gfar_set_bd_stash(struct device *dev,
return count;
}
-DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
+static DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
static ssize_t gfar_show_rx_stash_size(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -100,6 +103,9 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev,
u32 temp;
unsigned long flags;
+ if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
+ return count;
+
spin_lock_irqsave(&priv->rxlock, flags);
if (length > priv->rx_buffer_size)
goto out;
@@ -130,8 +136,8 @@ out:
return count;
}
-DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
- gfar_set_rx_stash_size);
+static DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
+ gfar_set_rx_stash_size);
/* Stashing will only be enabled when rx_stash_size != 0 */
static ssize_t gfar_show_rx_stash_index(struct device *dev,
@@ -152,6 +158,9 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev,
u32 temp;
unsigned long flags;
+ if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
+ return count;
+
spin_lock_irqsave(&priv->rxlock, flags);
if (index > priv->rx_stash_size)
goto out;
@@ -172,8 +181,8 @@ out:
return count;
}
-DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
- gfar_set_rx_stash_index);
+static DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
+ gfar_set_rx_stash_index);
static ssize_t gfar_show_fifo_threshold(struct device *dev,
struct device_attribute *attr,
@@ -210,8 +219,8 @@ static ssize_t gfar_set_fifo_threshold(struct device *dev,
return count;
}
-DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
- gfar_set_fifo_threshold);
+static DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
+ gfar_set_fifo_threshold);
static ssize_t gfar_show_fifo_starve(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -247,7 +256,8 @@ static ssize_t gfar_set_fifo_starve(struct device *dev,
return count;
}
-DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve, gfar_set_fifo_starve);
+static DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve,
+ gfar_set_fifo_starve);
static ssize_t gfar_show_fifo_starve_off(struct device *dev,
struct device_attribute *attr,
@@ -284,8 +294,8 @@ static ssize_t gfar_set_fifo_starve_off(struct device *dev,
return count;
}
-DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
- gfar_set_fifo_starve_off);
+static DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
+ gfar_set_fifo_starve_off);
void gfar_init_sysfs(struct net_device *dev)
{
@@ -293,12 +303,9 @@ void gfar_init_sysfs(struct net_device *dev)
int rc;
/* Initialize the default values */
- priv->rx_stash_size = DEFAULT_STASH_LENGTH;
- priv->rx_stash_index = DEFAULT_STASH_INDEX;
priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
- priv->bd_stash_en = DEFAULT_BD_STASH;
/* Create our sysfs files */
rc = device_create_file(&dev->dev, &dev_attr_bd_stash);
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 7e8b3c59a7d..310ee035067 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -171,7 +171,7 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#include <asm/unaligned.h>
#include <asm/cache.h>
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n"
KERN_INFO " Some modifications by Eric kasten <kasten@nscl.msu.edu>\n"
KERN_INFO " Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n";
@@ -1244,7 +1244,7 @@ do { \
csum_add(sum, (ih)->saddr & 0xffff); \
csum_add(sum, (ih)->daddr >> 16); \
csum_add(sum, (ih)->daddr & 0xffff); \
- csum_add(sum, __constant_htons(IPPROTO_UDP)); \
+ csum_add(sum, cpu_to_be16(IPPROTO_UDP)); \
csum_add(sum, (uh)->len); \
} while (0)
@@ -1255,7 +1255,7 @@ do { \
csum_add(sum, (ih)->saddr & 0xffff); \
csum_add(sum, (ih)->daddr >> 16); \
csum_add(sum, (ih)->daddr & 0xffff); \
- csum_add(sum, __constant_htons(IPPROTO_TCP)); \
+ csum_add(sum, cpu_to_be16(IPPROTO_TCP)); \
csum_add(sum, htons(len)); \
} while (0)
#endif
@@ -1296,7 +1296,7 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* tack on checksum tag */
u32 tagval = 0;
struct ethhdr *eh = (struct ethhdr *)skb->data;
- if (eh->h_proto == __constant_htons(ETH_P_IP)) {
+ if (eh->h_proto == cpu_to_be16(ETH_P_IP)) {
struct iphdr *ih = (struct iphdr *)((char *)eh + ETH_HLEN);
if (ih->protocol == IPPROTO_UDP) {
struct udphdr *uh
@@ -1605,7 +1605,7 @@ static int hamachi_rx(struct net_device *dev)
*/
if (ntohs(ih->tot_len) >= 46){
/* don't worry about frags */
- if (!(ih->frag_off & __constant_htons(IP_MF|IP_OFFSET))) {
+ if (!(ih->frag_off & cpu_to_be16(IP_MF|IP_OFFSET))) {
u32 inv = *(u32 *) &buf_addr[data_size - 16];
u32 *p = (u32 *) &buf_addr[data_size - 20];
register u32 crc, p_r, p_r1;
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 2d4089894ec..155160052c8 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -322,23 +322,25 @@ static const struct header_ops sp_header_ops = {
.rebuild = sp_rebuild_header,
};
+static const struct net_device_ops sp_netdev_ops = {
+ .ndo_open = sp_open_dev,
+ .ndo_stop = sp_close,
+ .ndo_start_xmit = sp_xmit,
+ .ndo_set_mac_address = sp_set_mac_address,
+};
+
static void sp_setup(struct net_device *dev)
{
/* Finish setting up the DEVICE info. */
- dev->mtu = SIXP_MTU;
- dev->hard_start_xmit = sp_xmit;
- dev->open = sp_open_dev;
+ dev->netdev_ops = &sp_netdev_ops;
dev->destructor = free_netdev;
- dev->stop = sp_close;
-
- dev->set_mac_address = sp_set_mac_address;
+ dev->mtu = SIXP_MTU;
dev->hard_header_len = AX25_MAX_HEADER_LEN;
dev->header_ops = &sp_header_ops;
dev->addr_len = AX25_ADDR_LEN;
dev->type = ARPHRD_AX25;
dev->tx_queue_len = 10;
- dev->tx_timeout = NULL;
/* Only activated in AX.25 mode */
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
@@ -788,9 +790,9 @@ static struct tty_ldisc_ops sp_ldisc = {
/* Initialize 6pack control device -- register 6pack line discipline */
-static char msg_banner[] __initdata = KERN_INFO \
+static const char msg_banner[] __initdata = KERN_INFO \
"AX.25: 6pack driver, " SIXPACK_VERSION "\n";
-static char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initdata = KERN_ERR \
"6pack: can't register line discipline (err = %d)\n";
static int __init sixpack_init_driver(void)
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 81a65e3a1c0..bb78c11559c 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -203,7 +203,6 @@ struct baycom_state {
unsigned char buf[TXBUFFER_SIZE];
} hdlctx;
- struct net_device_stats stats;
unsigned int ptt_keyed;
struct sk_buff *skb; /* next transmit packet */
@@ -423,7 +422,7 @@ static void encode_hdlc(struct baycom_state *bc)
bc->hdlctx.bufptr = bc->hdlctx.buf;
bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;
dev_kfree_skb(skb);
- bc->stats.tx_packets++;
+ bc->dev->stats.tx_packets++;
}
/* ---------------------------------------------------------------------- */
@@ -547,7 +546,7 @@ static void do_rxpacket(struct net_device *dev)
pktlen = bc->hdlcrx.bufcnt-2+1; /* KISS kludge */
if (!(skb = dev_alloc_skb(pktlen))) {
printk("%s: memory squeeze, dropping packet\n", dev->name);
- bc->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
cp = skb_put(skb, pktlen);
@@ -555,7 +554,7 @@ static void do_rxpacket(struct net_device *dev)
memcpy(cp, bc->hdlcrx.buf, pktlen - 1);
skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
- bc->stats.rx_packets++;
+ dev->stats.rx_packets++;
}
static int receive(struct net_device *dev, int cnt)
@@ -802,19 +801,6 @@ static int baycom_set_mac_address(struct net_device *dev, void *addr)
/* --------------------------------------------------------------------- */
-static struct net_device_stats *baycom_get_stats(struct net_device *dev)
-{
- struct baycom_state *bc = netdev_priv(dev);
-
- /*
- * Get the current statistics. This may be called with the
- * card open or closed.
- */
- return &bc->stats;
-}
-
-/* --------------------------------------------------------------------- */
-
static void epp_wakeup(void *handle)
{
struct net_device *dev = (struct net_device *)handle;
@@ -1065,10 +1051,10 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
hi.data.cs.ptt = !!(bc->stat & EPP_PTTBIT);
hi.data.cs.dcd = !(bc->stat & EPP_DCDBIT);
hi.data.cs.ptt_keyed = bc->ptt_keyed;
- hi.data.cs.tx_packets = bc->stats.tx_packets;
- hi.data.cs.tx_errors = bc->stats.tx_errors;
- hi.data.cs.rx_packets = bc->stats.rx_packets;
- hi.data.cs.rx_errors = bc->stats.rx_errors;
+ hi.data.cs.tx_packets = dev->stats.tx_packets;
+ hi.data.cs.tx_errors = dev->stats.tx_errors;
+ hi.data.cs.rx_packets = dev->stats.rx_packets;
+ hi.data.cs.rx_errors = dev->stats.rx_errors;
break;
case HDLCDRVCTL_OLDGETSTAT:
@@ -1116,6 +1102,14 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* --------------------------------------------------------------------- */
+static const struct net_device_ops baycom_netdev_ops = {
+ .ndo_open = epp_open,
+ .ndo_stop = epp_close,
+ .ndo_do_ioctl = baycom_ioctl,
+ .ndo_start_xmit = baycom_send_packet,
+ .ndo_set_mac_address = baycom_set_mac_address,
+};
+
/*
* Check for a network adaptor of this type, and return '0' if one exists.
* If dev->base_addr == 0, probe all likely locations.
@@ -1143,17 +1137,12 @@ static void baycom_probe(struct net_device *dev)
/*
* initialize the device struct
*/
- dev->open = epp_open;
- dev->stop = epp_close;
- dev->do_ioctl = baycom_ioctl;
- dev->hard_start_xmit = baycom_send_packet;
- dev->get_stats = baycom_get_stats;
/* Fill in the fields of the device structure */
bc->skb = NULL;
+ dev->netdev_ops = &baycom_netdev_ops;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = baycom_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */
dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 46f8f3390e7..d509b371a56 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -87,7 +87,8 @@
#include <linux/bpqether.h>
-static char banner[] __initdata = KERN_INFO "AX.25: bpqether driver version 004\n";
+static const char banner[] __initdata = KERN_INFO \
+ "AX.25: bpqether driver version 004\n";
static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
@@ -96,8 +97,8 @@ static char bpq_eth_addr[6];
static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
static int bpq_device_event(struct notifier_block *, unsigned long, void *);
-static struct packet_type bpq_packet_type = {
- .type = __constant_htons(ETH_P_BPQ),
+static struct packet_type bpq_packet_type __read_mostly = {
+ .type = cpu_to_be16(ETH_P_BPQ),
.func = bpq_rcv,
};
@@ -110,7 +111,6 @@ struct bpqdev {
struct list_head bpq_list; /* list of bpq devices chain */
struct net_device *ethdev; /* link to ethernet device */
struct net_device *axdev; /* bpq device (bpq#) */
- struct net_device_stats stats; /* some statistics */
char dest_addr[6]; /* ether destination address */
char acpt_addr[6]; /* accept ether frames from this address only */
};
@@ -222,8 +222,8 @@ static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
skb_pull(skb, 2); /* Remove the length bytes */
skb_trim(skb, len); /* Set the length of the data */
- bpq->stats.rx_packets++;
- bpq->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
ptr = skb_push(skb, 1);
*ptr = 0;
@@ -292,7 +292,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
bpq = netdev_priv(dev);
if ((dev = bpq_get_ether_dev(dev)) == NULL) {
- bpq->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
kfree_skb(skb);
return -ENODEV;
}
@@ -300,8 +300,8 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
skb->protocol = ax25_type_trans(skb, dev);
skb_reset_network_header(skb);
dev_hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
- bpq->stats.tx_packets++;
- bpq->stats.tx_bytes+=skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes+=skb->len;
dev_queue_xmit(skb);
netif_wake_queue(dev);
@@ -309,16 +309,6 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
}
/*
- * Statistics
- */
-static struct net_device_stats *bpq_get_stats(struct net_device *dev)
-{
- struct bpqdev *bpq = netdev_priv(dev);
-
- return &bpq->stats;
-}
-
-/*
* Set AX.25 callsign
*/
static int bpq_set_mac_address(struct net_device *dev, void *addr)
@@ -396,6 +386,7 @@ static int bpq_close(struct net_device *dev)
* Proc filesystem
*/
static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
int i = 1;
struct bpqdev *bpqdev;
@@ -428,6 +419,7 @@ static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void bpq_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
rcu_read_unlock();
}
@@ -454,7 +446,7 @@ static int bpq_seq_show(struct seq_file *seq, void *v)
return 0;
}
-static struct seq_operations bpq_seqops = {
+static const struct seq_operations bpq_seqops = {
.start = bpq_seq_start,
.next = bpq_seq_next,
.stop = bpq_seq_stop,
@@ -477,16 +469,17 @@ static const struct file_operations bpq_info_fops = {
/* ------------------------------------------------------------------------ */
+static const struct net_device_ops bpq_netdev_ops = {
+ .ndo_open = bpq_open,
+ .ndo_stop = bpq_close,
+ .ndo_start_xmit = bpq_xmit,
+ .ndo_set_mac_address = bpq_set_mac_address,
+ .ndo_do_ioctl = bpq_ioctl,
+};
static void bpq_setup(struct net_device *dev)
{
-
- dev->hard_start_xmit = bpq_xmit;
- dev->open = bpq_open;
- dev->stop = bpq_close;
- dev->set_mac_address = bpq_set_mac_address;
- dev->get_stats = bpq_get_stats;
- dev->do_ioctl = bpq_ioctl;
+ dev->netdev_ops = &bpq_netdev_ops;
dev->destructor = free_netdev;
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index e67103396ed..881bf818bb4 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -195,7 +195,7 @@ struct scc_priv {
int chip;
struct net_device *dev;
struct scc_info *info;
- struct net_device_stats stats;
+
int channel;
int card_base, scc_cmd, scc_data;
int tmr_cnt, tmr_ctrl, tmr_mode;
@@ -239,7 +239,6 @@ static int scc_open(struct net_device *dev);
static int scc_close(struct net_device *dev);
static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static int scc_send_packet(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *scc_get_stats(struct net_device *dev);
static int scc_set_mac_address(struct net_device *dev, void *sa);
static inline void tx_on(struct scc_priv *priv);
@@ -441,6 +440,13 @@ static void __init dev_setup(struct net_device *dev)
memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
}
+static const struct net_device_ops scc_netdev_ops = {
+ .ndo_open = scc_open,
+ .ndo_stop = scc_close,
+ .ndo_start_xmit = scc_send_packet,
+ .ndo_do_ioctl = scc_ioctl,
+};
+
static int __init setup_adapter(int card_base, int type, int n)
{
int i, irq, chip;
@@ -576,11 +582,7 @@ static int __init setup_adapter(int card_base, int type, int n)
sprintf(dev->name, "dmascc%i", 2 * n + i);
dev->base_addr = card_base;
dev->irq = irq;
- dev->open = scc_open;
- dev->stop = scc_close;
- dev->do_ioctl = scc_ioctl;
- dev->hard_start_xmit = scc_send_packet;
- dev->get_stats = scc_get_stats;
+ dev->netdev_ops = &scc_netdev_ops;
dev->header_ops = &ax25_header_ops;
dev->set_mac_address = scc_set_mac_address;
}
@@ -961,14 +963,6 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
}
-static struct net_device_stats *scc_get_stats(struct net_device *dev)
-{
- struct scc_priv *priv = dev->ml_priv;
-
- return &priv->stats;
-}
-
-
static int scc_set_mac_address(struct net_device *dev, void *sa)
{
memcpy(dev->dev_addr, ((struct sockaddr *) sa)->sa_data,
@@ -1216,17 +1210,17 @@ static void special_condition(struct scc_priv *priv, int rc)
}
if (priv->rx_over) {
/* We had an overrun */
- priv->stats.rx_errors++;
+ priv->dev->stats.rx_errors++;
if (priv->rx_over == 2)
- priv->stats.rx_length_errors++;
+ priv->dev->stats.rx_length_errors++;
else
- priv->stats.rx_fifo_errors++;
+ priv->dev->stats.rx_fifo_errors++;
priv->rx_over = 0;
} else if (rc & CRC_ERR) {
/* Count invalid CRC only if packet length >= minimum */
if (cb >= 15) {
- priv->stats.rx_errors++;
- priv->stats.rx_crc_errors++;
+ priv->dev->stats.rx_errors++;
+ priv->dev->stats.rx_crc_errors++;
}
} else {
if (cb >= 15) {
@@ -1239,8 +1233,8 @@ static void special_condition(struct scc_priv *priv, int rc)
priv->rx_count++;
schedule_work(&priv->rx_work);
} else {
- priv->stats.rx_errors++;
- priv->stats.rx_over_errors++;
+ priv->dev->stats.rx_errors++;
+ priv->dev->stats.rx_over_errors++;
}
}
}
@@ -1275,7 +1269,7 @@ static void rx_bh(struct work_struct *ugli_api)
skb = dev_alloc_skb(cb + 1);
if (skb == NULL) {
/* Drop packet */
- priv->stats.rx_dropped++;
+ priv->dev->stats.rx_dropped++;
} else {
/* Fill buffer */
data = skb_put(skb, cb + 1);
@@ -1283,8 +1277,8 @@ static void rx_bh(struct work_struct *ugli_api)
memcpy(&data[1], priv->rx_buf[i], cb);
skb->protocol = ax25_type_trans(skb, priv->dev);
netif_rx(skb);
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += cb;
+ priv->dev->stats.rx_packets++;
+ priv->dev->stats.rx_bytes += cb;
}
spin_lock_irqsave(&priv->ring_lock, flags);
/* Move tail */
@@ -1351,15 +1345,15 @@ static void es_isr(struct scc_priv *priv)
write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
if (res) {
/* Update packet statistics */
- priv->stats.tx_errors++;
- priv->stats.tx_fifo_errors++;
+ priv->dev->stats.tx_errors++;
+ priv->dev->stats.tx_fifo_errors++;
/* Other underrun interrupts may already be waiting */
write_scc(priv, R0, RES_EXT_INT);
write_scc(priv, R0, RES_EXT_INT);
} else {
/* Update packet statistics */
- priv->stats.tx_packets++;
- priv->stats.tx_bytes += priv->tx_len[i];
+ priv->dev->stats.tx_packets++;
+ priv->dev->stats.tx_bytes += priv->tx_len[i];
/* Remove frame from FIFO */
priv->tx_tail = (i + 1) % NUM_TX_BUF;
priv->tx_count--;
@@ -1425,7 +1419,7 @@ static void tm_isr(struct scc_priv *priv)
write_scc(priv, R15, DCDIE);
priv->rr0 = read_scc(priv, R0);
if (priv->rr0 & DCD) {
- priv->stats.collisions++;
+ priv->dev->stats.collisions++;
rx_on(priv);
priv->state = RX_ON;
} else {
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 8eba61a1d4a..61de56e45ee 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -154,7 +154,7 @@ static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
pkt_len = s->hdlcrx.len - 2 + 1; /* KISS kludge */
if (!(skb = dev_alloc_skb(pkt_len))) {
printk("%s: memory squeeze, dropping packet\n", dev->name);
- s->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
cp = skb_put(skb, pkt_len);
@@ -162,7 +162,7 @@ static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
- s->stats.rx_packets++;
+ dev->stats.rx_packets++;
}
void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s)
@@ -326,7 +326,7 @@ void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s)
s->hdlctx.len = pkt_len+2; /* the appended CRC */
s->hdlctx.tx_state = 2;
s->hdlctx.bitstream = 0;
- s->stats.tx_packets++;
+ dev->stats.tx_packets++;
break;
case 2:
if (!s->hdlctx.len) {
@@ -427,19 +427,6 @@ static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr)
}
/* --------------------------------------------------------------------- */
-
-static struct net_device_stats *hdlcdrv_get_stats(struct net_device *dev)
-{
- struct hdlcdrv_state *sm = netdev_priv(dev);
-
- /*
- * Get the current statistics. This may be called with the
- * card open or closed.
- */
- return &sm->stats;
-}
-
-/* --------------------------------------------------------------------- */
/*
* Open/initialize the board. This is called (in the current kernel)
* sometime after booting when the 'ifconfig' program is run.
@@ -568,10 +555,10 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
bi.data.cs.ptt = hdlcdrv_ptt(s);
bi.data.cs.dcd = s->hdlcrx.dcd;
bi.data.cs.ptt_keyed = s->ptt_keyed;
- bi.data.cs.tx_packets = s->stats.tx_packets;
- bi.data.cs.tx_errors = s->stats.tx_errors;
- bi.data.cs.rx_packets = s->stats.rx_packets;
- bi.data.cs.rx_errors = s->stats.rx_errors;
+ bi.data.cs.tx_packets = dev->stats.tx_packets;
+ bi.data.cs.tx_errors = dev->stats.tx_errors;
+ bi.data.cs.rx_packets = dev->stats.rx_packets;
+ bi.data.cs.rx_errors = dev->stats.rx_errors;
break;
case HDLCDRVCTL_OLDGETSTAT:
@@ -630,6 +617,14 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* --------------------------------------------------------------------- */
+static const struct net_device_ops hdlcdrv_netdev = {
+ .ndo_open = hdlcdrv_open,
+ .ndo_stop = hdlcdrv_close,
+ .ndo_start_xmit = hdlcdrv_send_packet,
+ .ndo_do_ioctl = hdlcdrv_ioctl,
+ .ndo_set_mac_address = hdlcdrv_set_mac_address,
+};
+
/*
* Initialize fields in hdlcdrv
*/
@@ -669,21 +664,13 @@ static void hdlcdrv_setup(struct net_device *dev)
s->bitbuf_hdlc.shreg = 0x80;
#endif /* HDLCDRV_DEBUG */
- /*
- * initialize the device struct
- */
- dev->open = hdlcdrv_open;
- dev->stop = hdlcdrv_close;
- dev->do_ioctl = hdlcdrv_ioctl;
- dev->hard_start_xmit = hdlcdrv_send_packet;
- dev->get_stats = hdlcdrv_get_stats;
/* Fill in the fields of the device structure */
s->skb = NULL;
+ dev->netdev_ops = &hdlcdrv_netdev;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = hdlcdrv_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */
dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index bbdb311b842..032c0db4c41 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -59,8 +59,6 @@ struct mkiss {
unsigned char *xhead; /* pointer to next byte to XMIT */
int xleft; /* bytes left in XMIT queue */
- struct net_device_stats stats;
-
/* Detailed SLIP statistics. */
int mtu; /* Our mtu (to spot changes!) */
int buffsize; /* Max buffers sizes */
@@ -253,7 +251,7 @@ static void ax_bump(struct mkiss *ax)
if (ax->rbuff[0] > 0x0f) {
if (ax->rbuff[0] & 0x80) {
if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
- ax->stats.rx_errors++;
+ ax->dev->stats.rx_errors++;
spin_unlock_bh(&ax->buflock);
return;
@@ -268,7 +266,7 @@ static void ax_bump(struct mkiss *ax)
*ax->rbuff &= ~0x80;
} else if (ax->rbuff[0] & 0x20) {
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
- ax->stats.rx_errors++;
+ ax->dev->stats.rx_errors++;
spin_unlock_bh(&ax->buflock);
return;
}
@@ -295,7 +293,7 @@ static void ax_bump(struct mkiss *ax)
if ((skb = dev_alloc_skb(count)) == NULL) {
printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
ax->dev->name);
- ax->stats.rx_dropped++;
+ ax->dev->stats.rx_dropped++;
spin_unlock_bh(&ax->buflock);
return;
}
@@ -303,8 +301,8 @@ static void ax_bump(struct mkiss *ax)
memcpy(skb_put(skb,count), ax->rbuff, count);
skb->protocol = ax25_type_trans(skb, ax->dev);
netif_rx(skb);
- ax->stats.rx_packets++;
- ax->stats.rx_bytes += count;
+ ax->dev->stats.rx_packets++;
+ ax->dev->stats.rx_bytes += count;
spin_unlock_bh(&ax->buflock);
}
@@ -344,7 +342,7 @@ static void kiss_unesc(struct mkiss *ax, unsigned char s)
return;
}
- ax->stats.rx_over_errors++;
+ ax->dev->stats.rx_over_errors++;
set_bit(AXF_ERROR, &ax->flags);
}
spin_unlock_bh(&ax->buflock);
@@ -406,7 +404,7 @@ static void ax_changedmtu(struct mkiss *ax)
memcpy(ax->xbuff, ax->xhead, ax->xleft);
} else {
ax->xleft = 0;
- ax->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
@@ -417,7 +415,7 @@ static void ax_changedmtu(struct mkiss *ax)
memcpy(ax->rbuff, orbuff, ax->rcount);
} else {
ax->rcount = 0;
- ax->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
set_bit(AXF_ERROR, &ax->flags);
}
}
@@ -444,7 +442,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */
len = ax->mtu;
printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
- ax->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
netif_start_queue(dev);
return;
}
@@ -518,8 +516,8 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
- ax->stats.tx_packets++;
- ax->stats.tx_bytes += actual;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += actual;
ax->dev->trans_start = jiffies;
ax->xleft = count - actual;
@@ -664,32 +662,28 @@ static int ax_close(struct net_device *dev)
return 0;
}
-static struct net_device_stats *ax_get_stats(struct net_device *dev)
-{
- struct mkiss *ax = netdev_priv(dev);
-
- return &ax->stats;
-}
-
static const struct header_ops ax_header_ops = {
.create = ax_header,
.rebuild = ax_rebuild_header,
};
+static const struct net_device_ops ax_netdev_ops = {
+ .ndo_open = ax_open_dev,
+ .ndo_stop = ax_close,
+ .ndo_start_xmit = ax_xmit,
+ .ndo_set_mac_address = ax_set_mac_address,
+};
+
static void ax_setup(struct net_device *dev)
{
/* Finish setting up the DEVICE info. */
dev->mtu = AX_MTU;
- dev->hard_start_xmit = ax_xmit;
- dev->open = ax_open_dev;
- dev->stop = ax_close;
- dev->get_stats = ax_get_stats;
- dev->set_mac_address = ax_set_mac_address;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->type = ARPHRD_AX25;
dev->tx_queue_len = 10;
dev->header_ops = &ax_header_ops;
+ dev->netdev_ops = &ax_netdev_ops;
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
@@ -929,7 +923,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
while (count--) {
if (fp != NULL && *fp++) {
if (!test_and_set_bit(AXF_ERROR, &ax->flags))
- ax->stats.rx_errors++;
+ ax->dev->stats.rx_errors++;
cp++;
continue;
}
@@ -982,9 +976,9 @@ static struct tty_ldisc_ops ax_ldisc = {
.write_wakeup = mkiss_write_wakeup
};
-static char banner[] __initdata = KERN_INFO \
+static const char banner[] __initdata = KERN_INFO \
"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
-static char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initdata = KERN_ERR \
"mkiss: can't register line discipline (err = %d)\n";
static int __init mkiss_init_driver(void)
@@ -993,8 +987,9 @@ static int __init mkiss_init_driver(void)
printk(banner);
- if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0)
- printk(msg_regfail);
+ status = tty_register_ldisc(N_AX25, &ax_ldisc);
+ if (status != 0)
+ printk(msg_regfail, status);
return status;
}
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index c011af7088e..d712e7af780 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -184,7 +184,8 @@
#include "z8530.h"
-static char banner[] __initdata = KERN_INFO "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
+static const char banner[] __initdata = KERN_INFO \
+ "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
static void t_dwait(unsigned long);
static void t_txdelay(unsigned long);
@@ -1542,23 +1543,24 @@ static int scc_net_alloc(const char *name, struct scc_channel *scc)
/* * Network driver methods * */
/* ******************************************************************** */
+static const struct net_device_ops scc_netdev_ops = {
+ .ndo_open = scc_net_open,
+ .ndo_stop = scc_net_close,
+ .ndo_start_xmit = scc_net_tx,
+ .ndo_set_mac_address = scc_net_set_mac_address,
+ .ndo_get_stats = scc_net_get_stats,
+ .ndo_do_ioctl = scc_net_ioctl,
+};
+
/* ----> Initialize device <----- */
static void scc_net_setup(struct net_device *dev)
{
dev->tx_queue_len = 16; /* should be enough... */
- dev->open = scc_net_open;
- dev->stop = scc_net_close;
-
- dev->hard_start_xmit = scc_net_tx;
+ dev->netdev_ops = &scc_netdev_ops;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = scc_net_set_mac_address;
- dev->get_stats = scc_net_get_stats;
- dev->do_ioctl = scc_net_ioctl;
- dev->tx_timeout = NULL;
-
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
@@ -2073,7 +2075,7 @@ static int scc_net_seq_show(struct seq_file *seq, void *v)
return 0;
}
-static struct seq_operations scc_net_seq_ops = {
+static const struct seq_operations scc_net_seq_ops = {
.start = scc_net_seq_start,
.next = scc_net_seq_next,
.stop = scc_net_seq_stop,
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 5407f7486c9..500a40b2afe 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -77,7 +77,8 @@
/* --------------------------------------------------------------------- */
static const char yam_drvname[] = "yam";
-static char yam_drvinfo[] __initdata = KERN_INFO "YAM driver version 0.8 by F1OAT/F6FBB\n";
+static const char yam_drvinfo[] __initdata = KERN_INFO \
+ "YAM driver version 0.8 by F1OAT/F6FBB\n";
/* --------------------------------------------------------------------- */
@@ -115,10 +116,6 @@ struct yam_port {
struct net_device *dev;
- /* Stats section */
-
- struct net_device_stats stats;
-
int nb_rxint;
int nb_mdint;
@@ -507,7 +504,7 @@ static inline void yam_rx_flag(struct net_device *dev, struct yam_port *yp)
} else {
if (!(skb = dev_alloc_skb(pkt_len))) {
printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
- ++yp->stats.rx_dropped;
+ ++dev->stats.rx_dropped;
} else {
unsigned char *cp;
cp = skb_put(skb, pkt_len);
@@ -515,7 +512,7 @@ static inline void yam_rx_flag(struct net_device *dev, struct yam_port *yp)
memcpy(cp, yp->rx_buf, pkt_len - 1);
skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
- ++yp->stats.rx_packets;
+ ++dev->stats.rx_packets;
}
}
}
@@ -677,7 +674,7 @@ static void yam_tx_byte(struct net_device *dev, struct yam_port *yp)
yp->tx_count = 1;
yp->tx_state = TX_HEAD;
}
- ++yp->stats.tx_packets;
+ ++dev->stats.tx_packets;
break;
case TX_TAIL:
if (--yp->tx_count <= 0) {
@@ -716,7 +713,7 @@ static irqreturn_t yam_interrupt(int irq, void *dev_id)
handled = 1;
if (lsr & LSR_OE)
- ++yp->stats.rx_fifo_errors;
+ ++dev->stats.rx_fifo_errors;
yp->dcd = (msr & RX_DCD) ? 1 : 0;
@@ -778,16 +775,16 @@ static int yam_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " TxTail %u\n", yp->txtail);
seq_printf(seq, " SlotTime %u\n", yp->slot);
seq_printf(seq, " Persist %u\n", yp->pers);
- seq_printf(seq, " TxFrames %lu\n", yp->stats.tx_packets);
- seq_printf(seq, " RxFrames %lu\n", yp->stats.rx_packets);
+ seq_printf(seq, " TxFrames %lu\n", dev->stats.tx_packets);
+ seq_printf(seq, " RxFrames %lu\n", dev->stats.rx_packets);
seq_printf(seq, " TxInt %u\n", yp->nb_mdint);
seq_printf(seq, " RxInt %u\n", yp->nb_rxint);
- seq_printf(seq, " RxOver %lu\n", yp->stats.rx_fifo_errors);
+ seq_printf(seq, " RxOver %lu\n", dev->stats.rx_fifo_errors);
seq_printf(seq, "\n");
return 0;
}
-static struct seq_operations yam_seqops = {
+static const struct seq_operations yam_seqops = {
.start = yam_seq_start,
.next = yam_seq_next,
.stop = yam_seq_stop,
@@ -812,26 +809,6 @@ static const struct file_operations yam_info_fops = {
/* --------------------------------------------------------------------- */
-static struct net_device_stats *yam_get_stats(struct net_device *dev)
-{
- struct yam_port *yp;
-
- if (!dev)
- return NULL;
-
- yp = netdev_priv(dev);
- if (yp->magic != YAM_MAGIC)
- return NULL;
-
- /*
- * Get the current statistics. This may be called with the
- * card open or closed.
- */
- return &yp->stats;
-}
-
-/* --------------------------------------------------------------------- */
-
static int yam_open(struct net_device *dev)
{
struct yam_port *yp = netdev_priv(dev);
@@ -877,10 +854,10 @@ static int yam_open(struct net_device *dev)
/* Reset overruns for all ports - FPGA programming makes overruns */
for (i = 0; i < NR_PORTS; i++) {
- struct net_device *dev = yam_devs[i];
- struct yam_port *yp = netdev_priv(dev);
- inb(LSR(dev->base_addr));
- yp->stats.rx_fifo_errors = 0;
+ struct net_device *yam_dev = yam_devs[i];
+
+ inb(LSR(yam_dev->base_addr));
+ yam_dev->stats.rx_fifo_errors = 0;
}
printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq,
@@ -1068,6 +1045,14 @@ static int yam_set_mac_address(struct net_device *dev, void *addr)
/* --------------------------------------------------------------------- */
+static const struct net_device_ops yam_netdev_ops = {
+ .ndo_open = yam_open,
+ .ndo_stop = yam_close,
+ .ndo_start_xmit = yam_send_packet,
+ .ndo_do_ioctl = yam_ioctl,
+ .ndo_set_mac_address = yam_set_mac_address,
+};
+
static void yam_setup(struct net_device *dev)
{
struct yam_port *yp = netdev_priv(dev);
@@ -1088,18 +1073,11 @@ static void yam_setup(struct net_device *dev)
dev->base_addr = yp->iobase;
dev->irq = yp->irq;
- dev->open = yam_open;
- dev->stop = yam_close;
- dev->do_ioctl = yam_ioctl;
- dev->hard_start_xmit = yam_send_packet;
- dev->get_stats = yam_get_stats;
-
skb_queue_head_init(&yp->send_queue);
+ dev->netdev_ops = &yam_netdev_ops;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = yam_set_mac_address;
-
dev->type = ARPHRD_AX25;
dev->hard_header_len = AX25_MAX_HEADER_LEN;
dev->mtu = AX25_MTU;
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
index 5e070f44663..0486cbe01ad 100644
--- a/drivers/net/hp-plus.c
+++ b/drivers/net/hp-plus.c
@@ -467,7 +467,7 @@ init_module(void)
if (this_dev != 0) break; /* only autoprobe 1st one */
printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n");
}
- dev = alloc_ei_netdev();
+ dev = alloc_eip_netdev();
if (!dev)
break;
dev->irq = irq[this_dev];
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 87a706694fb..a815e17a0ab 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -134,7 +134,7 @@ static inline void emac_report_timeout_error(struct emac_instance *dev,
EMAC_FTR_440EP_PHY_CLK_FIX))
DBG(dev, "%s" NL, error);
else if (net_ratelimit())
- printk(KERN_ERR "%s: %s\n", dev->ndev->name, error);
+ printk(KERN_ERR "%s: %s\n", dev->ofdev->node->full_name, error);
}
/* EMAC PHY clock workaround:
@@ -2594,6 +2594,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)
if (of_device_is_compatible(np, "ibm,emac-460ex") ||
of_device_is_compatible(np, "ibm,emac-460gt"))
dev->features |= EMAC_FTR_460EX_PHY_CLK_FIX;
+ if (of_device_is_compatible(np, "ibm,emac-405ex") ||
+ of_device_is_compatible(np, "ibm,emac-405exr"))
+ dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
} else if (of_device_is_compatible(np, "ibm,emac4")) {
dev->features |= EMAC_FTR_EMAC4;
if (of_device_is_compatible(np, "ibm,emac-440gx"))
diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c
index c40cd8df221..ac9d964e59e 100644
--- a/drivers/net/ibm_newemac/phy.c
+++ b/drivers/net/ibm_newemac/phy.c
@@ -60,7 +60,7 @@ int emac_mii_reset_phy(struct mii_phy *phy)
udelay(300);
- while (limit--) {
+ while (--limit) {
val = phy_read(phy, MII_BMCR);
if (val >= 0 && (val & BMCR_RESET) == 0)
break;
@@ -84,7 +84,7 @@ int emac_mii_reset_gpcs(struct mii_phy *phy)
udelay(300);
- while (limit--) {
+ while (--limit) {
val = gpcs_phy_read(phy, MII_BMCR);
if (val >= 0 && (val & BMCR_RESET) == 0)
break;
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index dfa6348ac1d..5c6315df86b 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1028,10 +1028,10 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
ibmveth_assert(lpar_rc == H_SUCCESS);
- netif_rx_complete(napi);
+ napi_complete(napi);
if (ibmveth_rxq_pending_buffer(adapter) &&
- netif_rx_reschedule(napi)) {
+ napi_reschedule(napi)) {
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
VIO_IRQ_DISABLE);
goto restart_poll;
@@ -1047,11 +1047,11 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance)
struct ibmveth_adapter *adapter = netdev_priv(netdev);
unsigned long lpar_rc;
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
VIO_IRQ_DISABLE);
ibmveth_assert(lpar_rc == H_SUCCESS);
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
}
diff --git a/drivers/net/igb/Makefile b/drivers/net/igb/Makefile
index 1927b3fd6f0..8372cb9a8c1 100644
--- a/drivers/net/igb/Makefile
+++ b/drivers/net/igb/Makefile
@@ -1,7 +1,7 @@
################################################################################
#
# Intel 82575 PCI-Express Ethernet Linux driver
-# Copyright(c) 1999 - 2007 Intel Corporation.
+# 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,
@@ -33,5 +33,5 @@
obj-$(CONFIG_IGB) += igb.o
igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \
- e1000_mac.o e1000_nvm.o e1000_phy.o
+ e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index f5e2e7235fc..efd9be21488 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 - 2008 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -62,17 +62,12 @@ static bool igb_sgmii_active_82575(struct e1000_hw *);
static s32 igb_reset_init_script_82575(struct e1000_hw *);
static s32 igb_read_mac_addr_82575(struct e1000_hw *);
-
-struct e1000_dev_spec_82575 {
- bool sgmii_active;
-};
-
static s32 igb_get_invariants_82575(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
struct e1000_nvm_info *nvm = &hw->nvm;
struct e1000_mac_info *mac = &hw->mac;
- struct e1000_dev_spec_82575 *dev_spec;
+ struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575;
u32 eecd;
s32 ret_val;
u16 size;
@@ -85,8 +80,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
mac->type = e1000_82575;
break;
case E1000_DEV_ID_82576:
+ case E1000_DEV_ID_82576_NS:
case E1000_DEV_ID_82576_FIBER:
case E1000_DEV_ID_82576_SERDES:
+ case E1000_DEV_ID_82576_QUAD_COPPER:
mac->type = e1000_82576;
break;
default:
@@ -94,17 +91,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
break;
}
- /* MAC initialization */
- hw->dev_spec_size = sizeof(struct e1000_dev_spec_82575);
-
- /* Device-specific structure allocation */
- hw->dev_spec = kzalloc(hw->dev_spec_size, GFP_KERNEL);
-
- if (!hw->dev_spec)
- return -ENOMEM;
-
- dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
-
/* Set media type */
/*
* The 82575 uses bits 22:23 for link mode. The mode can be changed
@@ -195,13 +181,13 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
/* PHY function pointers */
if (igb_sgmii_active_82575(hw)) {
- phy->ops.reset_phy = igb_phy_hw_reset_sgmii_82575;
- phy->ops.read_phy_reg = igb_read_phy_reg_sgmii_82575;
- phy->ops.write_phy_reg = igb_write_phy_reg_sgmii_82575;
+ phy->ops.reset = igb_phy_hw_reset_sgmii_82575;
+ phy->ops.read_reg = igb_read_phy_reg_sgmii_82575;
+ phy->ops.write_reg = igb_write_phy_reg_sgmii_82575;
} else {
- phy->ops.reset_phy = igb_phy_hw_reset;
- phy->ops.read_phy_reg = igb_read_phy_reg_igp;
- phy->ops.write_phy_reg = igb_write_phy_reg_igp;
+ phy->ops.reset = igb_phy_hw_reset;
+ phy->ops.read_reg = igb_read_phy_reg_igp;
+ phy->ops.write_reg = igb_write_phy_reg_igp;
}
/* Set phy->phy_addr and phy->id. */
@@ -229,6 +215,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
return -E1000_ERR_PHY;
}
+ /* if 82576 then initialize mailbox parameters */
+ if (mac->type == e1000_82576)
+ igb_init_mbx_params_pf(hw);
+
return 0;
}
@@ -451,7 +441,7 @@ static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
* SFP documentation requires the following to configure the SPF module
* to work on SGMII. No further documentation is given.
*/
- ret_val = hw->phy.ops.write_phy_reg(hw, 0x1B, 0x8084);
+ ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
if (ret_val)
goto out;
@@ -480,28 +470,28 @@ static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
s32 ret_val;
u16 data;
- ret_val = phy->ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
+ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
if (active) {
data |= IGP02E1000_PM_D0_LPLU;
- ret_val = phy->ops.write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = phy->ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&data);
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else {
data &= ~IGP02E1000_PM_D0_LPLU;
- ret_val = phy->ops.write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
/*
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
@@ -510,24 +500,24 @@ static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
* SmartSpeed, so performance is maintained.
*/
if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = phy->ops.read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, &data);
if (ret_val)
goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, data);
if (ret_val)
goto out;
} else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = phy->ops.read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, &data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, data);
if (ret_val)
goto out;
@@ -699,11 +689,18 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
/* SGMII link check is done through the PCS register. */
if ((hw->phy.media_type != e1000_media_type_copper) ||
- (igb_sgmii_active_82575(hw)))
+ (igb_sgmii_active_82575(hw))) {
ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
&duplex);
- else
+ /*
+ * Use this flag to determine if link needs to be checked or
+ * not. If we have link clear the flag so that we do not
+ * continue to check for link.
+ */
+ hw->mac.get_link_status = !hw->mac.serdes_has_link;
+ } else {
ret_val = igb_check_for_copper_link(hw);
+ }
return ret_val;
}
@@ -796,7 +793,7 @@ static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
}
/**
- * igb_update_mc_addr_list_82575 - Update Multicast addresses
+ * igb_update_mc_addr_list - Update Multicast addresses
* @hw: pointer to the HW structure
* @mc_addr_list: array of multicast addresses to program
* @mc_addr_count: number of multicast addresses to program
@@ -808,9 +805,9 @@ static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
* The parameter rar_count will usually be hw->mac.rar_entry_count
* unless there are workarounds that change this.
**/
-void igb_update_mc_addr_list_82575(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count,
- u32 rar_used_count, u32 rar_count)
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count,
+ u32 rar_used_count, u32 rar_count)
{
u32 hash_value;
u32 i;
@@ -1044,7 +1041,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
* depending on user settings.
*/
hw_dbg("Forcing Speed and Duplex\n");
- ret_val = igb_phy_force_speed_duplex(hw);
+ ret_val = hw->phy.ops.force_speed_duplex(hw);
if (ret_val) {
hw_dbg("Error Forcing Speed and Duplex\n");
goto out;
@@ -1103,6 +1100,13 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
E1000_CTRL_SWDPIN1;
wr32(E1000_CTRL, reg);
+ /* Power on phy for 82576 fiber adapters */
+ if (hw->mac.type == e1000_82576) {
+ reg = rd32(E1000_CTRL_EXT);
+ reg &= ~E1000_CTRL_EXT_SDP7_DATA;
+ wr32(E1000_CTRL_EXT, reg);
+ }
+
/* Set switch control to serdes energy detect */
reg = rd32(E1000_CONNSW);
reg |= E1000_CONNSW_ENRGSRC;
@@ -1220,20 +1224,12 @@ out:
**/
static bool igb_sgmii_active_82575(struct e1000_hw *hw)
{
- struct e1000_dev_spec_82575 *dev_spec;
- bool ret_val;
-
- if (hw->mac.type != e1000_82575) {
- ret_val = false;
- goto out;
- }
+ struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
- dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
+ if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
+ return false;
- ret_val = dev_spec->sgmii_active;
-
-out:
- return ret_val;
+ return dev_spec->sgmii_active;
}
/**
@@ -1423,6 +1419,44 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
rd32(E1000_MPC);
}
+/**
+ * igb_vmdq_set_loopback_pf - enable or disable vmdq loopback
+ * @hw: pointer to the hardware struct
+ * @enable: state to enter, either enabled or disabled
+ *
+ * enables/disables L2 switch loopback functionality.
+ **/
+void igb_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
+{
+ u32 dtxswc = rd32(E1000_DTXSWC);
+
+ if (enable)
+ dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+ else
+ dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+
+ wr32(E1000_DTXSWC, dtxswc);
+}
+
+/**
+ * igb_vmdq_set_replication_pf - enable or disable vmdq replication
+ * @hw: pointer to the hardware struct
+ * @enable: state to enter, either enabled or disabled
+ *
+ * enables/disables replication of packets across multiple pools.
+ **/
+void igb_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
+{
+ u32 vt_ctl = rd32(E1000_VT_CTL);
+
+ if (enable)
+ vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
+ else
+ vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;
+
+ wr32(E1000_VT_CTL, vt_ctl);
+}
+
static struct e1000_mac_operations e1000_mac_ops_82575 = {
.reset_hw = igb_reset_hw_82575,
.init_hw = igb_init_hw_82575,
@@ -1433,16 +1467,16 @@ static struct e1000_mac_operations e1000_mac_ops_82575 = {
};
static struct e1000_phy_operations e1000_phy_ops_82575 = {
- .acquire_phy = igb_acquire_phy_82575,
+ .acquire = igb_acquire_phy_82575,
.get_cfg_done = igb_get_cfg_done_82575,
- .release_phy = igb_release_phy_82575,
+ .release = igb_release_phy_82575,
};
static struct e1000_nvm_operations e1000_nvm_ops_82575 = {
- .acquire_nvm = igb_acquire_nvm_82575,
- .read_nvm = igb_read_nvm_eerd,
- .release_nvm = igb_release_nvm_82575,
- .write_nvm = igb_write_nvm_spi,
+ .acquire = igb_acquire_nvm_82575,
+ .read = igb_read_nvm_eerd,
+ .release = igb_release_nvm_82575,
+ .write = igb_write_nvm_spi,
};
const struct e1000_info e1000_82575_info = {
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index c1928b5efe1..eaf97705036 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 - 2008 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -28,7 +28,7 @@
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
-void igb_update_mc_addr_list_82575(struct e1000_hw*, u8*, u32, u32, u32);
+void igb_update_mc_addr_list(struct e1000_hw*, u8*, u32, u32, u32);
extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
@@ -40,8 +40,11 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
+#define E1000_SRRCTL_DROP_EN 0x80000000
#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002
+#define E1000_MRQC_ENABLE_VMDQ 0x00000003
+#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
@@ -58,9 +61,6 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
E1000_EICR_RX_QUEUE2 | \
E1000_EICR_RX_QUEUE3)
-#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
-#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
-
/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
/* Receive Descriptor - Advanced */
@@ -95,12 +95,6 @@ union e1000_adv_rx_desc {
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
-/* RSS Hash results */
-
-/* RSS Packet Types as indicated in the receive descriptor */
-#define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */
-#define E1000_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */
-
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
struct {
@@ -116,6 +110,7 @@ union e1000_adv_tx_desc {
};
/* Adv Transmit Descriptor Config Masks */
+#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
@@ -149,11 +144,8 @@ struct e1000_adv_tx_context_desc {
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
/* Direct Cache Access (DCA) definitions */
-#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
-#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */
-
-#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */
-#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
+#define E1000_DCA_CTRL_DCA_MODE_DISABLE 0x01 /* DCA Disable */
+#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
@@ -170,4 +162,44 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
+#define MAX_NUM_VFS 8
+
+#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
+
+/* Easy defines for setting default pool, would normally be left a zero */
+#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
+#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
+
+/* Other useful VMD_CTL register defines */
+#define E1000_VT_CTL_IGNORE_MAC (1 << 28)
+#define E1000_VT_CTL_DISABLE_DEF_POOL (1 << 29)
+#define E1000_VT_CTL_VM_REPL_EN (1 << 30)
+
+/* Per VM Offload register setup */
+#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */
+#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */
+#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */
+#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */
+#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */
+#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */
+#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */
+#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */
+#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
+#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
+
+#define E1000_VLVF_ARRAY_SIZE 32
+#define E1000_VLVF_VLANID_MASK 0x00000FFF
+#define E1000_VLVF_POOLSEL_SHIFT 12
+#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT)
+#define E1000_VLVF_LVLAN 0x00100000
+#define E1000_VLVF_VLANID_ENABLE 0x80000000
+
+#define E1000_IOVCTL 0x05BBC
+#define E1000_IOVCTL_REUSE_VFQ 0x00000001
+
+#define ALL_QUEUES 0xFFFF
+
+void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
+void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
+
#endif
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 40d03426c12..ad2d319d0f8 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 - 2008 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -42,33 +42,11 @@
#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
-#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
-#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
-#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
-#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
-#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
-#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
-#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
-#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
-
-/* Wake Up Status */
-
-/* Wake Up Packet Length */
-
-/* Four Flexible Filters are supported */
-#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
-
-/* Each Flexible Filter is at most 128 (0x80) bytes in length */
-#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
-
/* Extended Device Control */
-#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
-#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
-#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
-#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
-#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
+/* Physical Func Reset Done Indication */
+#define E1000_CTRL_EXT_PFRSTD 0x00004000
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
@@ -103,13 +81,7 @@
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
-#define E1000_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
-#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
-#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
-#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
-#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
-#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
+#define E1000_RXD_STAT_TS 0x10000 /* Pkt was time stamped */
#define E1000_RXDEXT_STATERR_CE 0x01000000
#define E1000_RXDEXT_STATERR_SE 0x02000000
@@ -119,14 +91,6 @@
#define E1000_RXDEXT_STATERR_IPE 0x40000000
#define E1000_RXDEXT_STATERR_RXE 0x80000000
-/* mask to determine if packets should be dropped due to frame errors */
-#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
- E1000_RXD_ERR_CE | \
- E1000_RXD_ERR_SE | \
- E1000_RXD_ERR_SEQ | \
- E1000_RXD_ERR_CXE | \
- E1000_RXD_ERR_RXE)
-
/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
E1000_RXDEXT_STATERR_CE | \
@@ -145,16 +109,11 @@
/* Management Control */
#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
-#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
/* Enable Neighbor Discovery Filtering */
#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
/* Enable MAC address filtering */
#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000
-/* Enable MNG packets to host memory */
-#define E1000_MANC_EN_MNG2HOST 0x00200000
-/* Enable IP address filtering */
-
/* Receive Control */
#define E1000_RCTL_EN 0x00000002 /* enable */
@@ -162,14 +121,11 @@
#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
-#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
-#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
@@ -226,11 +182,7 @@
/* enable link status from external LINK_0 and LINK_1 pins */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
-#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
-#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
-#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
-#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
#define E1000_CTRL_RST 0x04000000 /* Global reset */
#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
@@ -308,9 +260,7 @@
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
/* LED Control */
-#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT 0
-#define E1000_LEDCTL_LED0_IVRT 0x00000040
#define E1000_LEDCTL_LED0_BLINK 0x00000080
#define E1000_LEDCTL_MODE_LED_ON 0xE
@@ -357,12 +307,7 @@
#define MAX_JUMBO_FRAME_SIZE 0x3F00
-/* Extended Configuration Control and Size */
-#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040
-
/* PBA constants */
-#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
-#define E1000_PBA_24K 0x0018
#define E1000_PBA_34K 0x0022
#define E1000_PBA_64K 0x0040 /* 64KB */
@@ -378,41 +323,15 @@
/* Interrupt Cause Read */
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
-#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
-#define E1000_ICR_RXO 0x00000040 /* rx overrun */
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
-#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
-#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */
-#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
-#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
-#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
-#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
-#define E1000_ICR_TXD_LOW 0x00008000
-#define E1000_ICR_SRPD 0x00010000
-#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
-#define E1000_ICR_MNG 0x00040000 /* Manageability event */
-#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
+#define E1000_ICR_VMMB 0x00000100 /* VM MB event */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
-/* queue 0 Rx descriptor FIFO parity error */
-#define E1000_ICR_RXD_FIFO_PAR0 0x00100000
-/* queue 0 Tx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR0 0x00200000
-/* host arb read buffer parity error */
-#define E1000_ICR_HOST_ARB_PAR 0x00400000
-#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
-/* queue 1 Rx descriptor FIFO parity error */
-#define E1000_ICR_RXD_FIFO_PAR1 0x01000000
-/* queue 1 Tx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR1 0x02000000
-/* FW changed the status of DISSW bit in the FWSM */
-#define E1000_ICR_DSW 0x00000020
/* LAN connected device generates an interrupt */
-#define E1000_ICR_PHYINT 0x00001000
-#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
+#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */
/* Extended Interrupt Cause Read */
#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
@@ -423,7 +342,6 @@
#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */
#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */
#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */
-#define E1000_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */
/* TCP Timer */
@@ -441,17 +359,19 @@
E1000_IMS_TXDW | \
E1000_IMS_RXDMT0 | \
E1000_IMS_RXSEQ | \
- E1000_IMS_LSC)
+ E1000_IMS_LSC | \
+ E1000_IMS_DOUTSYNC)
/* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
+#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+#define E1000_IMS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
/* Extended Interrupt Mask Set */
-#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */
#define E1000_EIMS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */
/* Interrupt Cause Set */
@@ -481,6 +401,10 @@
* manageability enabled, allowing us room for 15 multicast addresses.
*/
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
+#define E1000_RAL_MAC_ADDR_LEN 4
+#define E1000_RAH_MAC_ADDR_LEN 2
+#define E1000_RAH_POOL_MASK 0x03FC0000
+#define E1000_RAH_POOL_1 0x00040000
/* Error Codes */
#define E1000_ERR_NVM 1
@@ -490,10 +414,10 @@
#define E1000_ERR_MAC_INIT 5
#define E1000_ERR_RESET 9
#define E1000_ERR_MASTER_REQUESTS_PENDING 10
-#define E1000_ERR_HOST_INTERFACE_COMMAND 11
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
+#define E1000_ERR_MBX 15
/* Loop limit on how long we wait for auto-negotiation to complete */
#define COPPER_LINK_UP_LIMIT 10
@@ -510,30 +434,9 @@
/* Flow Control */
#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
-/* Transmit Configuration Word */
-#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
-
-/* Receive Configuration Word */
-
-/* PCI Express Control */
-#define E1000_GCR_RXD_NO_SNOOP 0x00000001
-#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
-#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004
-#define E1000_GCR_TXD_NO_SNOOP 0x00000008
-#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
-#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
-
-#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
- E1000_GCR_RXDSCW_NO_SNOOP | \
- E1000_GCR_RXDSCR_NO_SNOOP | \
- E1000_GCR_TXD_NO_SNOOP | \
- E1000_GCR_TXDSCW_NO_SNOOP | \
- E1000_GCR_TXDSCR_NO_SNOOP)
-
/* PHY Control Register */
#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
-#define MII_CR_POWER_DOWN 0x0800 /* Power down */
#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
@@ -609,6 +512,7 @@
#define NVM_ID_LED_SETTINGS 0x0004
/* For SERDES output amplitude adjustment. */
#define NVM_INIT_CONTROL2_REG 0x000F
+#define NVM_INIT_CONTROL3_PORT_B 0x0014
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
@@ -663,10 +567,8 @@
#define IGP_LED3_MODE 0x07000000
/* PCI/PCI-X/PCI-EX Config space */
-#define PCI_HEADER_TYPE_REGISTER 0x0E
#define PCIE_LINK_STATUS 0x12
-#define PCI_HEADER_TYPE_MULTIFUNC 0x80
#define PCIE_LINK_WIDTH_MASK 0x3F0
#define PCIE_LINK_WIDTH_SHIFT 4
@@ -763,4 +665,8 @@
#define E1000_GEN_CTL_ADDRESS_SHIFT 8
#define E1000_GEN_POLL_TIMEOUT 640
+#define E1000_VFTA_ENTRY_SHIFT 5
+#define E1000_VFTA_ENTRY_MASK 0x7F
+#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
+
#endif
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 99504a600a8..68aac20c31c 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -32,7 +32,6 @@
#include <linux/delay.h>
#include <linux/io.h>
-#include "e1000_mac.h"
#include "e1000_regs.h"
#include "e1000_defines.h"
@@ -41,6 +40,8 @@ struct e1000_hw;
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
+#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
+#define E1000_DEV_ID_82576_NS 0x150A
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
@@ -144,144 +145,6 @@ enum e1000_fc_type {
e1000_fc_default = 0xFF
};
-
-/* Receive Descriptor */
-struct e1000_rx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- __le16 length; /* Length of data DMAed into data buffer */
- __le16 csum; /* Packet checksum */
- u8 status; /* Descriptor status */
- u8 errors; /* Descriptor Errors */
- __le16 special;
-};
-
-/* Receive Descriptor - Extended */
-union e1000_rx_desc_extended {
- struct {
- __le64 buffer_addr;
- __le64 reserved;
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length;
- __le16 vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
-
-#define MAX_PS_BUFFERS 4
-/* Receive Descriptor - Packet Split */
-union e1000_rx_desc_packet_split {
- struct {
- /* one buffer for protocol header(s), three data buffers */
- __le64 buffer_addr[MAX_PS_BUFFERS];
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length0; /* length of buffer 0 */
- __le16 vlan; /* VLAN tag */
- } middle;
- struct {
- __le16 header_status;
- __le16 length[3]; /* length of buffers 1-3 */
- } upper;
- __le64 reserved;
- } wb; /* writeback */
-};
-
-/* Transmit Descriptor */
-struct e1000_tx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 cso; /* Checksum offset */
- u8 cmd; /* Descriptor control */
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
- __le16 special;
- } fields;
- } upper;
-};
-
-/* Offload Context Descriptor */
-struct e1000_context_desc {
- union {
- __le32 ip_config;
- struct {
- u8 ipcss; /* IP checksum start */
- u8 ipcso; /* IP checksum offset */
- __le16 ipcse; /* IP checksum end */
- } ip_fields;
- } lower_setup;
- union {
- __le32 tcp_config;
- struct {
- u8 tucss; /* TCP checksum start */
- u8 tucso; /* TCP checksum offset */
- __le16 tucse; /* TCP checksum end */
- } tcp_fields;
- } upper_setup;
- __le32 cmd_and_length;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 hdr_len; /* Header length */
- __le16 mss; /* Maximum segment size */
- } fields;
- } tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct e1000_data_desc {
- __le64 buffer_addr; /* Address of the descriptor's buffer address */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 typ_len_ext;
- u8 cmd;
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 popts; /* Packet Options */
- __le16 special;
- } fields;
- } upper;
-};
-
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
@@ -359,6 +222,7 @@ struct e1000_hw_stats {
u64 lenerrs;
u64 scvpc;
u64 hrmpc;
+ u64 doosync;
};
struct e1000_phy_stats {
@@ -409,6 +273,7 @@ struct e1000_host_mng_command_info {
#include "e1000_mac.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
+#include "e1000_mbx.h"
struct e1000_mac_operations {
s32 (*check_for_link)(struct e1000_hw *);
@@ -422,25 +287,25 @@ struct e1000_mac_operations {
};
struct e1000_phy_operations {
- s32 (*acquire_phy)(struct e1000_hw *);
+ s32 (*acquire)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_phy_info)(struct e1000_hw *);
- s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
- void (*release_phy)(struct e1000_hw *);
- s32 (*reset_phy)(struct e1000_hw *);
+ s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
+ void (*release)(struct e1000_hw *);
+ s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
- s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
+ s32 (*write_reg)(struct e1000_hw *, u32, u16);
};
struct e1000_nvm_operations {
- s32 (*acquire_nvm)(struct e1000_hw *);
- s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
- void (*release_nvm)(struct e1000_hw *);
- s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
+ s32 (*acquire)(struct e1000_hw *);
+ s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
+ void (*release)(struct e1000_hw *);
+ s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_info {
@@ -483,7 +348,6 @@ struct e1000_mac_info {
bool asf_firmware_present;
bool autoneg;
bool autoneg_failed;
- bool disable_av;
bool disable_hw_init_bits;
bool get_link_status;
bool ifs_params_forced;
@@ -565,9 +429,40 @@ struct e1000_fc_info {
enum e1000_fc_type original_type;
};
+struct e1000_mbx_operations {
+ s32 (*init_params)(struct e1000_hw *hw);
+ s32 (*read)(struct e1000_hw *, u32 *, u16, u16);
+ s32 (*write)(struct e1000_hw *, u32 *, u16, u16);
+ s32 (*read_posted)(struct e1000_hw *, u32 *, u16, u16);
+ s32 (*write_posted)(struct e1000_hw *, u32 *, u16, u16);
+ s32 (*check_for_msg)(struct e1000_hw *, u16);
+ s32 (*check_for_ack)(struct e1000_hw *, u16);
+ s32 (*check_for_rst)(struct e1000_hw *, u16);
+};
+
+struct e1000_mbx_stats {
+ u32 msgs_tx;
+ u32 msgs_rx;
+
+ u32 acks;
+ u32 reqs;
+ u32 rsts;
+};
+
+struct e1000_mbx_info {
+ struct e1000_mbx_operations ops;
+ struct e1000_mbx_stats stats;
+ u32 timeout;
+ u32 usec_delay;
+ u16 size;
+};
+
+struct e1000_dev_spec_82575 {
+ bool sgmii_active;
+};
+
struct e1000_hw {
void *back;
- void *dev_spec;
u8 __iomem *hw_addr;
u8 __iomem *flash_address;
@@ -578,9 +473,12 @@ struct e1000_hw {
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
+ struct e1000_mbx_info mbx;
struct e1000_host_mng_dhcp_cookie mng_cookie;
- u32 dev_spec_size;
+ union {
+ struct e1000_dev_spec_82575 _82575;
+ } dev_spec;
u16 device_id;
u16 subsystem_vendor_id;
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 97f0049a5d6..f4c315b5a90 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -37,19 +37,6 @@
static s32 igb_set_default_fc(struct e1000_hw *hw);
static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
-/**
- * igb_remove_device - Free device specific structure
- * @hw: pointer to the HW structure
- *
- * If a device specific structure was allocated, this function will
- * free it.
- **/
-void igb_remove_device(struct e1000_hw *hw)
-{
- /* Freeing the dev_spec member of e1000_hw structure */
- kfree(hw->dev_spec);
-}
-
static s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
@@ -131,6 +118,37 @@ void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
}
/**
+ * igb_vfta_set - enable or disable vlan in VLAN filter table
+ * @hw: pointer to the HW structure
+ * @vid: VLAN id to add or remove
+ * @add: if true add filter, if false remove
+ *
+ * Sets or clears a bit in the VLAN filter table array based on VLAN id
+ * and if we are adding or removing the filter
+ **/
+s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
+{
+ u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
+ u32 mask = 1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
+ u32 vfta = array_rd32(E1000_VFTA, index);
+ s32 ret_val = 0;
+
+ /* bit was set/cleared before we started */
+ if ((!!(vfta & mask)) == add) {
+ ret_val = -E1000_ERR_CONFIG;
+ } else {
+ if (add)
+ vfta |= mask;
+ else
+ vfta &= ~mask;
+ }
+
+ igb_write_vfta(hw, index, vfta);
+
+ return ret_val;
+}
+
+/**
* igb_check_alt_mac_addr - Check for alternate MAC addr
* @hw: pointer to the HW structure
*
@@ -148,7 +166,7 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
u16 offset, nvm_alt_mac_addr_offset, nvm_data;
u8 alt_mac_addr[ETH_ALEN];
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+ ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1,
&nvm_alt_mac_addr_offset);
if (ret_val) {
hw_dbg("NVM Read Error\n");
@@ -165,7 +183,7 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
for (i = 0; i < ETH_ALEN; i += 2) {
offset = nvm_alt_mac_addr_offset + (i >> 1);
- ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
@@ -213,7 +231,8 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
- if (!hw->mac.disable_av)
+ /* If MAC address zero, no need to set the AV bit */
+ if (rar_low || rar_high)
rar_high |= E1000_RAH_AV;
wr32(E1000_RAL(index), rar_low);
@@ -588,8 +607,7 @@ static s32 igb_set_default_fc(struct e1000_hw *hw)
* control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM.
*/
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_INIT_CONTROL2_REG, 1,
- &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
@@ -720,11 +738,11 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
* has completed. We read this twice because this reg has
* some "sticky" (latched) bits.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg);
if (ret_val)
goto out;
@@ -742,11 +760,11 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
* Page Ability Register (Address 5) to determine how
* flow control was negotiated.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_AUTONEG_ADV,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
&mii_nway_adv_reg);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_LP_ABILITY,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
&mii_nway_lp_ability_reg);
if (ret_val)
goto out;
@@ -1041,7 +1059,7 @@ static s32 igb_valid_led_default(struct e1000_hw *hw, u16 *data)
{
s32 ret_val;
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
+ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index cbee6af7d91..a34de526963 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -58,12 +58,12 @@ s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
void igb_clear_vfta(struct e1000_hw *hw);
+s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
void igb_config_collision_dist(struct e1000_hw *hw);
void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
void igb_put_hw_semaphore(struct e1000_hw *hw);
void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
s32 igb_check_alt_mac_addr(struct e1000_hw *hw);
-void igb_remove_device(struct e1000_hw *hw);
void igb_reset_adaptive(struct e1000_hw *hw);
void igb_update_adaptive(struct e1000_hw *hw);
void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
@@ -83,13 +83,8 @@ enum e1000_mng_mode {
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
-#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
-#define E1000_HICR_EN 0x01 /* Enable bit - RO */
-/* Driver sets this bit when done to put command in RAM */
-#define E1000_HICR_C 0x02
-
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
extern u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
new file mode 100644
index 00000000000..fe71c7ddaa0
--- /dev/null
+++ b/drivers/net/igb/e1000_mbx.c
@@ -0,0 +1,447 @@
+/*******************************************************************************
+
+ Intel(R) Gigabit Ethernet Linux driver
+ Copyright(c) 2007-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 "e1000_mbx.h"
+
+/**
+ * igb_read_mbx - Reads a message from the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to read
+ *
+ * returns SUCCESS if it successfuly read message from buffer
+ **/
+s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ /* limit read to size of mailbox */
+ if (size > mbx->size)
+ size = mbx->size;
+
+ if (mbx->ops.read)
+ ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_write_mbx - Write a message to the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully copied message into the buffer
+ **/
+s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = 0;
+
+ if (size > mbx->size)
+ ret_val = -E1000_ERR_MBX;
+
+ else if (mbx->ops.write)
+ ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_msg - checks to see if someone sent us mail
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (mbx->ops.check_for_msg)
+ ret_val = mbx->ops.check_for_msg(hw, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_ack - checks to see if someone sent us ACK
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (mbx->ops.check_for_ack)
+ ret_val = mbx->ops.check_for_ack(hw, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_rst - checks to see if other side has reset
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (mbx->ops.check_for_rst)
+ ret_val = mbx->ops.check_for_rst(hw, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_poll_for_msg - Wait for message notification
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message notification
+ **/
+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)
+ goto out;
+
+ while (mbx->ops.check_for_msg(hw, mbx_id)) {
+ if (!countdown)
+ break;
+ countdown--;
+ udelay(mbx->usec_delay);
+ }
+out:
+ return countdown ? 0 : -E1000_ERR_MBX;
+}
+
+/**
+ * igb_poll_for_ack - Wait for message acknowledgement
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message acknowledgement
+ **/
+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)
+ goto out;
+
+ while (mbx->ops.check_for_ack(hw, mbx_id)) {
+ if (!countdown)
+ break;
+ countdown--;
+ udelay(mbx->usec_delay);
+ }
+out:
+ return countdown ? 0 : -E1000_ERR_MBX;
+}
+
+/**
+ * igb_read_posted_mbx - Wait for message notification and receive message
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message notification and
+ * copied it into the receive buffer.
+ **/
+s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!mbx->ops.read)
+ goto out;
+
+ ret_val = igb_poll_for_msg(hw, mbx_id);
+
+ if (!ret_val)
+ ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+out:
+ return ret_val;
+}
+
+/**
+ * igb_write_posted_mbx - Write a message to the mailbox, wait for ack
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully copied message into the buffer and
+ * received an ack to that message within delay * timeout period
+ **/
+s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = 0;
+
+ if (!mbx->ops.write)
+ goto out;
+
+ /* send msg*/
+ ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+
+ /* if msg sent wait until we receive an ack */
+ if (!ret_val)
+ ret_val = igb_poll_for_ack(hw, mbx_id);
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_init_mbx_ops_generic - Initialize NVM function pointers
+ * @hw: pointer to the HW structure
+ *
+ * Setups up the function pointers to no-op functions
+ **/
+void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ mbx->ops.read_posted = igb_read_posted_mbx;
+ mbx->ops.write_posted = igb_write_posted_mbx;
+}
+
+static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
+{
+ u32 mbvficr = rd32(E1000_MBVFICR);
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (mbvficr & mask) {
+ ret_val = 0;
+ wr32(E1000_MBVFICR, mask);
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_msg_pf - checks to see if the VF has sent mail
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
+ ret_val = 0;
+ hw->mbx.stats.reqs++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_ack_pf - checks to see if the VF has ACKed
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
+ ret_val = 0;
+ hw->mbx.stats.acks++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_rst_pf - checks to see if the VF has reset
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
+{
+ u32 vflre = rd32(E1000_VFLRE);
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (vflre & (1 << vf_number)) {
+ ret_val = 0;
+ wr32(E1000_VFLRE, (1 << vf_number));
+ hw->mbx.stats.rsts++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_write_mbx_pf - Places a message in the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if it successfully copied message into the buffer
+ **/
+static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
+ u16 vf_number)
+{
+ u32 p2v_mailbox;
+ s32 ret_val = 0;
+ u16 i;
+
+ /* Take ownership of the buffer */
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+
+ /* Make sure we have ownership now... */
+ p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+ if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
+ /* failed to grab ownership */
+ ret_val = -E1000_ERR_MBX;
+ goto out_no_write;
+ }
+
+ /*
+ * flush any ack or msg which may already be in the queue
+ * as they are likely the result of an error
+ */
+ igb_check_for_ack_pf(hw, vf_number);
+ igb_check_for_msg_pf(hw, vf_number);
+
+ /* copy the caller specified message to the mailbox memory buffer */
+ for (i = 0; i < size; i++)
+ array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
+
+ /* Interrupt VF to tell it a message has been sent and release buffer*/
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
+
+ /* update stats */
+ hw->mbx.stats.msgs_tx++;
+
+out_no_write:
+ return ret_val;
+
+}
+
+/**
+ * igb_read_mbx_pf - Read a message from the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @vf_number: the VF index
+ *
+ * This function copies a message from the mailbox buffer to the caller's
+ * memory buffer. The presumption is that the caller knows that there was
+ * a message due to a VF request so no polling for message is needed.
+ **/
+static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
+ u16 vf_number)
+{
+ u32 p2v_mailbox;
+ s32 ret_val = 0;
+ u16 i;
+
+ /* Take ownership of the buffer */
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+
+ /* Make sure we have ownership now... */
+ p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+ if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
+ /* failed to grab ownership */
+ ret_val = -E1000_ERR_MBX;
+ goto out_no_read;
+ }
+
+ /* copy the message to the mailbox memory buffer */
+ for (i = 0; i < size; i++)
+ msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
+
+ /* Acknowledge the message and release buffer */
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
+
+ /* update stats */
+ hw->mbx.stats.msgs_rx++;
+
+ ret_val = 0;
+
+out_no_read:
+ return ret_val;
+}
+
+/**
+ * e1000_init_mbx_params_pf - set initial values for pf mailbox
+ * @hw: pointer to the HW structure
+ *
+ * Initializes the hw->mbx struct to correct values for pf mailbox
+ */
+s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+
+ if (hw->mac.type == e1000_82576) {
+ mbx->timeout = 0;
+ mbx->usec_delay = 0;
+
+ mbx->size = E1000_VFMAILBOX_SIZE;
+
+ mbx->ops.read = igb_read_mbx_pf;
+ mbx->ops.write = igb_write_mbx_pf;
+ mbx->ops.read_posted = igb_read_posted_mbx;
+ mbx->ops.write_posted = igb_write_posted_mbx;
+ mbx->ops.check_for_msg = igb_check_for_msg_pf;
+ mbx->ops.check_for_ack = igb_check_for_ack_pf;
+ mbx->ops.check_for_rst = igb_check_for_rst_pf;
+
+ mbx->stats.msgs_tx = 0;
+ mbx->stats.msgs_rx = 0;
+ mbx->stats.reqs = 0;
+ mbx->stats.acks = 0;
+ mbx->stats.rsts = 0;
+ }
+
+ return 0;
+}
+
diff --git a/drivers/net/igb/e1000_mbx.h b/drivers/net/igb/e1000_mbx.h
new file mode 100644
index 00000000000..6ec9890a8f7
--- /dev/null
+++ b/drivers/net/igb/e1000_mbx.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+
+ Intel(R) Gigabit Ethernet Linux driver
+ Copyright(c) 2007-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 _E1000_MBX_H_
+#define _E1000_MBX_H_
+
+#include "e1000_hw.h"
+
+#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */
+#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
+#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
+
+#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
+#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */
+#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
+#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */
+
+#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
+
+/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
+ * PF. The reverse is true if it is E1000_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+#define E1000_VT_MSGTYPE_ACK 0x80000000 /* Messages below or'd with
+ * this are the ACK */
+#define E1000_VT_MSGTYPE_NACK 0x40000000 /* Messages below or'd with
+ * this are the NACK */
+#define E1000_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still
+ clear to send requests */
+#define E1000_VT_MSGINFO_SHIFT 16
+/* bits 23:16 are used for exra info for certain messages */
+#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
+
+#define E1000_VF_RESET 0x01 /* VF requests reset */
+#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
+#define E1000_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
+#define E1000_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
+#define E1000_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
+
+#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
+
+s32 igb_read_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_write_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_read_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_write_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_check_for_msg(struct e1000_hw *, u16);
+s32 igb_check_for_ack(struct e1000_hw *, u16);
+s32 igb_check_for_rst(struct e1000_hw *, u16);
+s32 igb_init_mbx_params_pf(struct e1000_hw *);
+
+#endif /* _E1000_MBX_H_ */
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c
index a84e4e429fa..a88bfe2f1e8 100644
--- a/drivers/net/igb/e1000_nvm.c
+++ b/drivers/net/igb/e1000_nvm.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -419,7 +419,7 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
goto out;
}
- ret_val = hw->nvm.ops.acquire_nvm(hw);
+ ret_val = hw->nvm.ops.acquire(hw);
if (ret_val)
goto out;
@@ -468,7 +468,7 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
msleep(10);
release:
- hw->nvm.ops.release_nvm(hw);
+ hw->nvm.ops.release(hw);
out:
return ret_val;
@@ -487,14 +487,14 @@ s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num)
s32 ret_val;
u16 nvm_data;
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
*part_num = (u32)(nvm_data << 16);
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
@@ -515,29 +515,23 @@ out:
**/
s32 igb_read_mac_addr(struct e1000_hw *hw)
{
- s32 ret_val = 0;
- u16 offset, nvm_data, i;
+ u32 rar_high;
+ u32 rar_low;
+ u16 i;
- for (i = 0; i < ETH_ALEN; i += 2) {
- offset = i >> 1;
- ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
- if (ret_val) {
- hw_dbg("NVM Read Error\n");
- goto out;
- }
- hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
- hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
- }
+ rar_high = rd32(E1000_RAH(0));
+ rar_low = rd32(E1000_RAL(0));
+
+ for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
+ hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
- /* Flip last bit of mac address if we're on second port */
- if (hw->bus.func == E1000_FUNC_1)
- hw->mac.perm_addr[5] ^= 1;
+ for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
+ hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
for (i = 0; i < ETH_ALEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
-out:
- return ret_val;
+ return 0;
}
/**
@@ -554,7 +548,7 @@ s32 igb_validate_nvm_checksum(struct e1000_hw *hw)
u16 i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
- ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
@@ -587,7 +581,7 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
u16 i, nvm_data;
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
- ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error while updating checksum.\n");
goto out;
@@ -595,7 +589,7 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
- ret_val = hw->nvm.ops.write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
+ ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val)
hw_dbg("NVM Write Error while updating checksum.\n");
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index 17fddb91c9f..de2d4862468 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -31,10 +31,6 @@
#include "e1000_mac.h"
#include "e1000_phy.h"
-static s32 igb_get_phy_cfg_done(struct e1000_hw *hw);
-static void igb_release_phy(struct e1000_hw *hw);
-static s32 igb_acquire_phy(struct e1000_hw *hw);
-static s32 igb_phy_reset_dsp(struct e1000_hw *hw);
static s32 igb_phy_setup_autoneg(struct e1000_hw *hw);
static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
u16 *phy_ctrl);
@@ -43,9 +39,6 @@ static s32 igb_wait_autoneg(struct e1000_hw *hw);
/* Cable length tables */
static const u16 e1000_m88_cable_length_table[] =
{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
-#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
- (sizeof(e1000_m88_cable_length_table) / \
- sizeof(e1000_m88_cable_length_table[0]))
static const u16 e1000_igp_2_cable_length_table[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
@@ -91,13 +84,13 @@ s32 igb_get_phy_id(struct e1000_hw *hw)
s32 ret_val = 0;
u16 phy_id;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_ID1, &phy_id);
+ ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
if (ret_val)
goto out;
phy->id = (u32)(phy_id << 16);
udelay(20);
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_ID2, &phy_id);
+ ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
if (ret_val)
goto out;
@@ -118,11 +111,11 @@ static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
{
s32 ret_val;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
+ ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
+ ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
out:
return ret_val;
@@ -257,9 +250,12 @@ out:
**/
s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
{
- s32 ret_val;
+ s32 ret_val = 0;
+
+ if (!(hw->phy.ops.acquire))
+ goto out;
- ret_val = igb_acquire_phy(hw);
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
@@ -268,16 +264,15 @@ s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
if (ret_val) {
- igb_release_phy(hw);
+ hw->phy.ops.release(hw);
goto out;
}
}
- ret_val = igb_read_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
+ ret_val = igb_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+ data);
- igb_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return ret_val;
@@ -294,9 +289,12 @@ out:
**/
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
{
- s32 ret_val;
+ s32 ret_val = 0;
- ret_val = igb_acquire_phy(hw);
+ if (!(hw->phy.ops.acquire))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
@@ -305,16 +303,15 @@ s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
if (ret_val) {
- igb_release_phy(hw);
+ hw->phy.ops.release(hw);
goto out;
}
}
- ret_val = igb_write_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
+ ret_val = igb_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
- igb_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return ret_val;
@@ -339,8 +336,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
}
/* Enable CRS on TX. This must be set for half-duplex operation. */
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
@@ -383,8 +379,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
if (phy->disable_polarity_correction == 1)
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
@@ -393,8 +388,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw,
- M88E1000_EXT_PHY_SPEC_CTRL,
+ ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
&phy_data);
if (ret_val)
goto out;
@@ -413,8 +407,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
}
- ret_val = hw->phy.ops.write_phy_reg(hw,
- M88E1000_EXT_PHY_SPEC_CTRL,
+ ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
phy_data);
if (ret_val)
goto out;
@@ -449,7 +442,7 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.reset_phy(hw);
+ ret_val = phy->ops.reset(hw);
if (ret_val) {
hw_dbg("Error resetting the PHY.\n");
goto out;
@@ -464,8 +457,8 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
*/
if (phy->type == e1000_phy_igp) {
/* disable lplu d3 during driver init */
- if (hw->phy.ops.set_d3_lplu_state)
- ret_val = hw->phy.ops.set_d3_lplu_state(hw, false);
+ if (phy->ops.set_d3_lplu_state)
+ ret_val = phy->ops.set_d3_lplu_state(hw, false);
if (ret_val) {
hw_dbg("Error Disabling LPLU D3\n");
goto out;
@@ -473,13 +466,13 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
}
/* disable lplu d0 during driver init */
- ret_val = hw->phy.ops.set_d0_lplu_state(hw, false);
+ ret_val = phy->ops.set_d0_lplu_state(hw, false);
if (ret_val) {
hw_dbg("Error Disabling LPLU D0\n");
goto out;
}
/* Configure mdi-mdix settings */
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
if (ret_val)
goto out;
@@ -497,7 +490,7 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
data |= IGP01E1000_PSCR_AUTO_MDIX;
break;
}
- ret_val = hw->phy.ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
if (ret_val)
goto out;
@@ -510,33 +503,31 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
*/
if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
/* Disable SmartSpeed */
- ret_val = hw->phy.ops.read_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
+ ret_val = phy->ops.read_reg(hw,
+ IGP01E1000_PHY_PORT_CONFIG,
+ &data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
/* Set auto Master/Slave resolution process */
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_CTRL,
- &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
if (ret_val)
goto out;
data &= ~CR_1000T_MS_ENABLE;
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_1000T_CTRL,
- data);
+ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
if (ret_val)
goto out;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_CTRL, &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
if (ret_val)
goto out;
@@ -560,7 +551,7 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
default:
break;
}
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_1000T_CTRL, data);
+ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
if (ret_val)
goto out;
}
@@ -609,12 +600,12 @@ s32 igb_copper_link_autoneg(struct e1000_hw *hw)
* Restart auto-negotiation by setting the Auto Neg Enable bit and
* the Auto Neg Restart bit in the PHY control register.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
if (ret_val)
goto out;
phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
if (ret_val)
goto out;
@@ -656,15 +647,13 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
phy->autoneg_advertised &= phy->autoneg_mask;
/* Read the MII Auto-Neg Advertisement Register (Address 4). */
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_AUTONEG_ADV,
- &mii_autoneg_adv_reg);
+ ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
if (ret_val)
goto out;
if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
/* Read the MII 1000Base-T Control Register (Address 9). */
- ret_val = hw->phy.ops.read_phy_reg(hw,
- PHY_1000T_CTRL,
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
&mii_1000t_ctrl_reg);
if (ret_val)
goto out;
@@ -785,17 +774,16 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_AUTONEG_ADV,
- mii_autoneg_adv_reg);
+ ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
if (ret_val)
goto out;
hw_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
- ret_val = hw->phy.ops.write_phy_reg(hw,
- PHY_1000T_CTRL,
- mii_1000t_ctrl_reg);
+ ret_val = phy->ops.write_reg(hw,
+ PHY_1000T_CTRL,
+ mii_1000t_ctrl_reg);
if (ret_val)
goto out;
}
@@ -819,13 +807,13 @@ s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw)
u16 phy_data;
bool link;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val)
goto out;
igb_phy_force_speed_duplex_setup(hw, &phy_data);
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
if (ret_val)
goto out;
@@ -833,16 +821,14 @@ s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw)
* Clear Auto-Crossover to force MDI manually. IGP requires MDI
* forced whenever speed and duplex are forced.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
- ret_val = hw->phy.ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
if (ret_val)
goto out;
@@ -897,20 +883,18 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
* forced whenever speed and duplex are forced.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
hw_dbg("M88E1000 PSCR: %X\n", phy_data);
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val)
goto out;
@@ -919,7 +903,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
/* Reset the phy to commit changes. */
phy_data |= MII_CR_RESET;
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
if (ret_val)
goto out;
@@ -940,7 +924,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* We didn't get link.
* Reset the DSP and cross our fingers.
*/
- ret_val = hw->phy.ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
M88E1000_PHY_PAGE_SELECT,
0x001d);
if (ret_val)
@@ -957,8 +941,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
@@ -968,8 +951,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* the reset value of 2.5MHz.
*/
phy_data |= M88E1000_EPSCR_TX_CLK_25;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
@@ -977,14 +959,12 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* In addition, we must re-enable CRS on Tx for both half and full
* duplex.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
out:
return ret_val;
@@ -1071,15 +1051,13 @@ s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
s32 ret_val;
u16 data;
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- &data);
+ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
if (!active) {
data &= ~IGP02E1000_PM_D3_LPLU;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP02E1000_PHY_POWER_MGMT,
+ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
@@ -1090,27 +1068,27 @@ s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
* SmartSpeed, so performance is maintained.
*/
if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = hw->phy.ops.read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = hw->phy.ops.read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
@@ -1120,22 +1098,19 @@ s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
(phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
(phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
data |= IGP02E1000_PM_D3_LPLU;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP02E1000_PHY_POWER_MGMT,
+ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = hw->phy.ops.read_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
data);
}
@@ -1176,7 +1151,7 @@ s32 igb_check_downshift(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, offset, &phy_data);
+ ret_val = phy->ops.read_reg(hw, offset, &phy_data);
if (!ret_val)
phy->speed_downgraded = (phy_data & mask) ? true : false;
@@ -1199,7 +1174,7 @@ static s32 igb_check_polarity_m88(struct e1000_hw *hw)
s32 ret_val;
u16 data;
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
if (!ret_val)
phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
@@ -1228,8 +1203,7 @@ static s32 igb_check_polarity_igp(struct e1000_hw *hw)
* Polarity is determined based on the speed of
* our connection.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
- &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
if (ret_val)
goto out;
@@ -1246,7 +1220,7 @@ static s32 igb_check_polarity_igp(struct e1000_hw *hw)
mask = IGP01E1000_PSSR_POLARITY_REVERSED;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, offset, &data);
+ ret_val = phy->ops.read_reg(hw, offset, &data);
if (!ret_val)
phy->cable_polarity = (data & mask)
@@ -1271,10 +1245,10 @@ static s32 igb_wait_autoneg(struct e1000_hw *hw)
/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
if (phy_status & MII_SR_AUTONEG_COMPLETE)
@@ -1310,10 +1284,10 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
* twice due to the link bit being sticky. No harm doing
* it across the board.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
if (phy_status & MII_SR_LINK_STATUS)
@@ -1350,8 +1324,7 @@ s32 igb_get_cable_length_m88(struct e1000_hw *hw)
s32 ret_val;
u16 phy_data, index;
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
if (ret_val)
goto out;
@@ -1372,8 +1345,8 @@ out:
*
* The automatic gain control (agc) normalizes the amplitude of the
* received signal, adjusting for the attenuation produced by the
- * cable. By reading the AGC registers, which reperesent the
- * cobination of course and fine gain value, the value can be put
+ * cable. By reading the AGC registers, which represent the
+ * combination of coarse and fine gain value, the value can be put
* into a lookup table to obtain the approximate cable length
* for each channel.
**/
@@ -1392,14 +1365,13 @@ s32 igb_get_cable_length_igp_2(struct e1000_hw *hw)
/* Read the AGC registers for all channels */
for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = hw->phy.ops.read_phy_reg(hw, agc_reg_array[i],
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data);
if (ret_val)
goto out;
/*
* Getting bits 15:9, which represent the combination of
- * course and fine gain values. The result is a number
+ * coarse and fine gain values. The result is a number
* that can be put into the lookup table to obtain the
* approximate cable length.
*/
@@ -1456,7 +1428,7 @@ s32 igb_get_phy_info_m88(struct e1000_hw *hw)
u16 phy_data;
bool link;
- if (hw->phy.media_type != e1000_media_type_copper) {
+ if (phy->media_type != e1000_media_type_copper) {
hw_dbg("Phy info is only valid for copper media\n");
ret_val = -E1000_ERR_CONFIG;
goto out;
@@ -1472,33 +1444,29 @@ s32 igb_get_phy_info_m88(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
- ? true
- : false;
+ ? true : false;
ret_val = igb_check_polarity_m88(hw);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
if (ret_val)
goto out;
phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? true : false;
if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
- ret_val = hw->phy.ops.get_cable_length(hw);
+ ret_val = phy->ops.get_cable_length(hw);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data);
if (ret_val)
goto out;
@@ -1552,8 +1520,7 @@ s32 igb_get_phy_info_igp(struct e1000_hw *hw)
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
- &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
if (ret_val)
goto out;
@@ -1561,12 +1528,11 @@ s32 igb_get_phy_info_igp(struct e1000_hw *hw)
if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_1000MBPS) {
- ret_val = hw->phy.ops.get_cable_length(hw);
+ ret_val = phy->ops.get_cable_length(hw);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
- &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
if (ret_val)
goto out;
@@ -1599,12 +1565,12 @@ s32 igb_phy_sw_reset(struct e1000_hw *hw)
s32 ret_val;
u16 phy_ctrl;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
if (ret_val)
goto out;
phy_ctrl |= MII_CR_RESET;
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+ ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
if (ret_val)
goto out;
@@ -1635,7 +1601,7 @@ s32 igb_phy_hw_reset(struct e1000_hw *hw)
goto out;
}
- ret_val = igb_acquire_phy(hw);
+ ret_val = phy->ops.acquire(hw);
if (ret_val)
goto out;
@@ -1650,74 +1616,14 @@ s32 igb_phy_hw_reset(struct e1000_hw *hw)
udelay(150);
- igb_release_phy(hw);
+ phy->ops.release(hw);
- ret_val = igb_get_phy_cfg_done(hw);
+ ret_val = phy->ops.get_cfg_done(hw);
out:
return ret_val;
}
-/* Internal function pointers */
-
-/**
- * igb_get_phy_cfg_done - Generic PHY configuration done
- * @hw: pointer to the HW structure
- *
- * Return success if silicon family did not implement a family specific
- * get_cfg_done function.
- **/
-static s32 igb_get_phy_cfg_done(struct e1000_hw *hw)
-{
- if (hw->phy.ops.get_cfg_done)
- return hw->phy.ops.get_cfg_done(hw);
-
- return 0;
-}
-
-/**
- * igb_release_phy - Generic release PHY
- * @hw: pointer to the HW structure
- *
- * Return if silicon family does not require a semaphore when accessing the
- * PHY.
- **/
-static void igb_release_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.release_phy)
- hw->phy.ops.release_phy(hw);
-}
-
-/**
- * igb_acquire_phy - Generic acquire PHY
- * @hw: pointer to the HW structure
- *
- * Return success if silicon family does not require a semaphore when
- * accessing the PHY.
- **/
-static s32 igb_acquire_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.acquire_phy)
- return hw->phy.ops.acquire_phy(hw);
-
- return 0;
-}
-
-/**
- * igb_phy_force_speed_duplex - Generic force PHY speed/duplex
- * @hw: pointer to the HW structure
- *
- * When the silicon family has not implemented a forced speed/duplex
- * function for the PHY, simply return 0.
- **/
-s32 igb_phy_force_speed_duplex(struct e1000_hw *hw)
-{
- if (hw->phy.ops.force_speed_duplex)
- return hw->phy.ops.force_speed_duplex(hw);
-
- return 0;
-}
-
/**
* igb_phy_init_script_igp3 - Inits the IGP3 PHY
* @hw: pointer to the HW structure
@@ -1730,75 +1636,75 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
/* PHY init IGP 3 */
/* Enable rise/fall, 10-mode work in class-A */
- hw->phy.ops.write_phy_reg(hw, 0x2F5B, 0x9018);
+ hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);
/* Remove all caps from Replica path filter */
- hw->phy.ops.write_phy_reg(hw, 0x2F52, 0x0000);
+ hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);
/* Bias trimming for ADC, AFE and Driver (Default) */
- hw->phy.ops.write_phy_reg(hw, 0x2FB1, 0x8B24);
+ hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);
/* Increase Hybrid poly bias */
- hw->phy.ops.write_phy_reg(hw, 0x2FB2, 0xF8F0);
+ hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);
/* Add 4% to TX amplitude in Giga mode */
- hw->phy.ops.write_phy_reg(hw, 0x2010, 0x10B0);
+ hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);
/* Disable trimming (TTT) */
- hw->phy.ops.write_phy_reg(hw, 0x2011, 0x0000);
+ hw->phy.ops.write_reg(hw, 0x2011, 0x0000);
/* Poly DC correction to 94.6% + 2% for all channels */
- hw->phy.ops.write_phy_reg(hw, 0x20DD, 0x249A);
+ hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);
/* ABS DC correction to 95.9% */
- hw->phy.ops.write_phy_reg(hw, 0x20DE, 0x00D3);
+ hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);
/* BG temp curve trim */
- hw->phy.ops.write_phy_reg(hw, 0x28B4, 0x04CE);
+ hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);
/* Increasing ADC OPAMP stage 1 currents to max */
- hw->phy.ops.write_phy_reg(hw, 0x2F70, 0x29E4);
+ hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);
/* Force 1000 ( required for enabling PHY regs configuration) */
- hw->phy.ops.write_phy_reg(hw, 0x0000, 0x0140);
+ hw->phy.ops.write_reg(hw, 0x0000, 0x0140);
/* Set upd_freq to 6 */
- hw->phy.ops.write_phy_reg(hw, 0x1F30, 0x1606);
+ hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);
/* Disable NPDFE */
- hw->phy.ops.write_phy_reg(hw, 0x1F31, 0xB814);
+ hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);
/* Disable adaptive fixed FFE (Default) */
- hw->phy.ops.write_phy_reg(hw, 0x1F35, 0x002A);
+ hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);
/* Enable FFE hysteresis */
- hw->phy.ops.write_phy_reg(hw, 0x1F3E, 0x0067);
+ hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);
/* Fixed FFE for short cable lengths */
- hw->phy.ops.write_phy_reg(hw, 0x1F54, 0x0065);
+ hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);
/* Fixed FFE for medium cable lengths */
- hw->phy.ops.write_phy_reg(hw, 0x1F55, 0x002A);
+ hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);
/* Fixed FFE for long cable lengths */
- hw->phy.ops.write_phy_reg(hw, 0x1F56, 0x002A);
+ hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);
/* Enable Adaptive Clip Threshold */
- hw->phy.ops.write_phy_reg(hw, 0x1F72, 0x3FB0);
+ hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);
/* AHT reset limit to 1 */
- hw->phy.ops.write_phy_reg(hw, 0x1F76, 0xC0FF);
+ hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);
/* Set AHT master delay to 127 msec */
- hw->phy.ops.write_phy_reg(hw, 0x1F77, 0x1DEC);
+ hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);
/* Set scan bits for AHT */
- hw->phy.ops.write_phy_reg(hw, 0x1F78, 0xF9EF);
+ hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);
/* Set AHT Preset bits */
- hw->phy.ops.write_phy_reg(hw, 0x1F79, 0x0210);
+ hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);
/* Change integ_factor of channel A to 3 */
- hw->phy.ops.write_phy_reg(hw, 0x1895, 0x0003);
+ hw->phy.ops.write_reg(hw, 0x1895, 0x0003);
/* Change prop_factor of channels BCD to 8 */
- hw->phy.ops.write_phy_reg(hw, 0x1796, 0x0008);
+ hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
/* Change cg_icount + enable integbp for channels BCD */
- hw->phy.ops.write_phy_reg(hw, 0x1798, 0xD008);
+ hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
/*
* Change cg_icount + enable integbp + change prop_factor_master
* to 8 for channel A
*/
- hw->phy.ops.write_phy_reg(hw, 0x1898, 0xD918);
+ hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
/* Disable AHT in Slave mode on channel A */
- hw->phy.ops.write_phy_reg(hw, 0x187A, 0x0800);
+ hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
/*
* Enable LPLU and disable AN to 1000 in non-D0a states,
* Enable SPD+B2B
*/
- hw->phy.ops.write_phy_reg(hw, 0x0019, 0x008D);
+ hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
/* Enable restart AN on an1000_dis change */
- hw->phy.ops.write_phy_reg(hw, 0x001B, 0x2080);
+ hw->phy.ops.write_reg(hw, 0x001B, 0x2080);
/* Enable wh_fifo read clock in 10/100 modes */
- hw->phy.ops.write_phy_reg(hw, 0x0014, 0x0045);
+ hw->phy.ops.write_reg(hw, 0x0014, 0x0045);
/* Restart AN, Speed selection is 1000 */
- hw->phy.ops.write_phy_reg(hw, 0x0000, 0x1340);
+ hw->phy.ops.write_reg(hw, 0x0000, 0x1340);
return 0;
}
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index 8f8fe0a780d..3228a862031 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -44,7 +44,6 @@ enum e1000_smart_speed {
s32 igb_check_downshift(struct e1000_hw *hw);
s32 igb_check_reset_block(struct e1000_hw *hw);
s32 igb_copper_link_autoneg(struct e1000_hw *hw);
-s32 igb_phy_force_speed_duplex(struct e1000_hw *hw);
s32 igb_copper_link_setup_igp(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index bdf5d839c4b..0bd7728fe46 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -73,8 +73,75 @@
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
-#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n)))
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
+
+/* IEEE 1588 TIMESYNCH */
+#define E1000_TSYNCTXCTL 0x0B614
+#define E1000_TSYNCTXCTL_VALID (1<<0)
+#define E1000_TSYNCTXCTL_ENABLED (1<<4)
+#define E1000_TSYNCRXCTL 0x0B620
+#define E1000_TSYNCRXCTL_VALID (1<<0)
+#define E1000_TSYNCRXCTL_ENABLED (1<<4)
+enum {
+ E1000_TSYNCRXCTL_TYPE_L2_V2 = 0,
+ E1000_TSYNCRXCTL_TYPE_L4_V1 = (1<<1),
+ E1000_TSYNCRXCTL_TYPE_L2_L4_V2 = (1<<2),
+ E1000_TSYNCRXCTL_TYPE_ALL = (1<<3),
+ E1000_TSYNCRXCTL_TYPE_EVENT_V2 = (1<<3) | (1<<1),
+};
+#define E1000_TSYNCRXCFG 0x05F50
+enum {
+ E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE = 0<<0,
+ E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE = 1<<0,
+ E1000_TSYNCRXCFG_PTP_V1_FOLLOWUP_MESSAGE = 2<<0,
+ E1000_TSYNCRXCFG_PTP_V1_DELAY_RESP_MESSAGE = 3<<0,
+ E1000_TSYNCRXCFG_PTP_V1_MANAGEMENT_MESSAGE = 4<<0,
+
+ E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE = 0<<8,
+ E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE = 1<<8,
+ E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_REQ_MESSAGE = 2<<8,
+ E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_RESP_MESSAGE = 3<<8,
+ E1000_TSYNCRXCFG_PTP_V2_FOLLOWUP_MESSAGE = 8<<8,
+ E1000_TSYNCRXCFG_PTP_V2_DELAY_RESP_MESSAGE = 9<<8,
+ E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_FOLLOWUP_MESSAGE = 0xA<<8,
+ E1000_TSYNCRXCFG_PTP_V2_ANNOUNCE_MESSAGE = 0xB<<8,
+ E1000_TSYNCRXCFG_PTP_V2_SIGNALLING_MESSAGE = 0xC<<8,
+ E1000_TSYNCRXCFG_PTP_V2_MANAGEMENT_MESSAGE = 0xD<<8,
+};
+#define E1000_SYSTIML 0x0B600
+#define E1000_SYSTIMH 0x0B604
+#define E1000_TIMINCA 0x0B608
+
+#define E1000_RXMTRL 0x0B634
+#define E1000_RXSTMPL 0x0B624
+#define E1000_RXSTMPH 0x0B628
+#define E1000_RXSATRL 0x0B62C
+#define E1000_RXSATRH 0x0B630
+
+#define E1000_TXSTMPL 0x0B618
+#define E1000_TXSTMPH 0x0B61C
+
+#define E1000_ETQF0 0x05CB0
+#define E1000_ETQF1 0x05CB4
+#define E1000_ETQF2 0x05CB8
+#define E1000_ETQF3 0x05CBC
+#define E1000_ETQF4 0x05CC0
+#define E1000_ETQF5 0x05CC4
+#define E1000_ETQF6 0x05CC8
+#define E1000_ETQF7 0x05CCC
+
+/* Filtering Registers */
+#define E1000_SAQF(_n) (0x5980 + 4 * (_n))
+#define E1000_DAQF(_n) (0x59A0 + 4 * (_n))
+#define E1000_SPQF(_n) (0x59C0 + 4 * (_n))
+#define E1000_FTQF(_n) (0x59E0 + 4 * (_n))
+#define E1000_SAQF0 E1000_SAQF(0)
+#define E1000_DAQF0 E1000_DAQF(0)
+#define E1000_SPQF0 E1000_SPQF(0)
+#define E1000_FTQF0 E1000_FTQF(0)
+#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
+#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
+
/* Split and Replication RX Control - RW */
/*
* Convenience macros
@@ -110,7 +177,6 @@
: (0x0E018 + ((_n) * 0x40)))
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \
: (0x0E028 + ((_n) * 0x40)))
-#define E1000_TARC(_n) (0x03840 + (_n << 8))
#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \
@@ -226,16 +292,14 @@
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
(0x054E4 + ((_i - 16) * 8)))
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
-#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
+#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - RO */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
-#define E1000_HOST_IF 0x08800 /* Host Interface */
-#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
@@ -243,9 +307,7 @@
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
-#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
-#define E1000_HICR 0x08F00 /* Host Inteface Control */
/* RSS registers */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
@@ -254,18 +316,27 @@
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
/* MSI-X Allocation Register (_i) - RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4))
-/* MSI-X Table entry addr low reg 0 - RW */
-#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10))
-/* MSI-X Table entry addr upper reg 0 - RW */
-#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10))
-/* MSI-X Table entry message reg 0 - RW */
-#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10))
-/* MSI-X Table entry vector ctrl reg 0 - RW */
-#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10))
/* Redirection Table - RW Array */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
+/* VT Registers */
+#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */
+#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */
+#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */
+#define E1000_VFRE 0x00C8C /* VF Receive Enables */
+#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
+#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
+#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
+#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
+#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
+/* These act per VF so an array friendly macro is used */
+#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
+#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
+#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
+#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
+ * Filter - RW */
+
#define wr32(reg, value) (writel(value, hw->hw_addr + reg))
#define rd32(reg) (readl(hw->hw_addr + reg))
#define wrfl() ((void)rd32(E1000_STATUS))
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 5a27825cc48..4e8464b9df2 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -34,25 +34,15 @@
#include "e1000_mac.h"
#include "e1000_82575.h"
-struct igb_adapter;
-
-#ifdef CONFIG_IGB_LRO
-#include <linux/inet_lro.h>
-#define MAX_LRO_AGGR 32
-#define MAX_LRO_DESCRIPTORS 8
-#endif
+#include <linux/clocksource.h>
+#include <linux/timecompare.h>
+#include <linux/net_tstamp.h>
-/* Interrupt defines */
-#define IGB_MIN_DYN_ITR 3000
-#define IGB_MAX_DYN_ITR 96000
+struct igb_adapter;
/* ((1000000000ns / (6000ints/s * 1024ns)) << 2 = 648 */
#define IGB_START_ITR 648
-#define IGB_DYN_ITR_PACKET_THRESHOLD 2
-#define IGB_DYN_ITR_LENGTH_LOW 200
-#define IGB_DYN_ITR_LENGTH_HIGH 1000
-
/* TX/RX descriptor defines */
#define IGB_DEFAULT_TXD 256
#define IGB_MIN_TXD 80
@@ -67,8 +57,21 @@ struct igb_adapter;
#define IGB_MIN_ITR_USECS 10
/* Transmit and receive queues */
-#define IGB_MAX_RX_QUEUES 4
-#define IGB_MAX_TX_QUEUES 4
+#define IGB_MAX_RX_QUEUES (adapter->vfs_allocated_count ? \
+ (adapter->vfs_allocated_count > 6 ? 1 : 2) : 4)
+#define IGB_MAX_TX_QUEUES IGB_MAX_RX_QUEUES
+#define IGB_ABS_MAX_TX_QUEUES 4
+
+#define IGB_MAX_VF_MC_ENTRIES 30
+#define IGB_MAX_VF_FUNCTIONS 8
+#define IGB_MAX_VFTA_ENTRIES 128
+
+struct vf_data_storage {
+ unsigned char vf_mac_addresses[ETH_ALEN];
+ u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
+ u16 num_vf_mc_hashes;
+ bool clear_to_send;
+};
/* RX descriptor control thresholds.
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
@@ -94,12 +97,9 @@ struct igb_adapter;
#define IGB_RXBUFFER_512 512
#define IGB_RXBUFFER_1024 1024
#define IGB_RXBUFFER_2048 2048
-#define IGB_RXBUFFER_4096 4096
-#define IGB_RXBUFFER_8192 8192
#define IGB_RXBUFFER_16384 16384
-/* Packet Buffer allocations */
-
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
/* How many Tx Descriptors do we need to call netif_wake_queue ? */
#define IGB_TX_QUEUE_WAKE 16
@@ -176,29 +176,18 @@ struct igb_ring {
struct napi_struct napi;
int set_itr;
struct igb_ring *buddy;
-#ifdef CONFIG_IGB_LRO
- struct net_lro_mgr lro_mgr;
- bool lro_used;
-#endif
};
};
char name[IFNAMSIZ + 5];
};
-#define IGB_DESC_UNUSED(R) \
- ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
- (R)->next_to_clean - (R)->next_to_use - 1)
-
#define E1000_RX_DESC_ADV(R, i) \
(&(((union e1000_adv_rx_desc *)((R).desc))[i]))
#define E1000_TX_DESC_ADV(R, i) \
(&(((union e1000_adv_tx_desc *)((R).desc))[i]))
#define E1000_TX_CTXTDESC_ADV(R, i) \
(&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
-#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
-#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
-#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
/* board specific private data structure */
@@ -248,7 +237,6 @@ struct igb_adapter {
u64 hw_csum_err;
u64 hw_csum_good;
- u64 rx_hdr_split;
u32 alloc_rx_buff_failed;
bool rx_csum;
u32 gorc;
@@ -262,6 +250,10 @@ struct igb_adapter {
struct napi_struct napi;
struct pci_dev *pdev;
struct net_device_stats net_stats;
+ struct cyclecounter cycles;
+ struct timecounter clock;
+ struct timecompare compare;
+ struct hwtstamp_config hwtstamp_config;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
@@ -283,28 +275,17 @@ struct igb_adapter {
unsigned int flags;
u32 eeprom_wol;
- /* for ioport free */
- int bars;
- int need_ioport;
-
- struct igb_ring *multi_tx_table[IGB_MAX_TX_QUEUES];
-#ifdef CONFIG_IGB_LRO
- unsigned int lro_max_aggr;
- unsigned int lro_aggregated;
- unsigned int lro_flushed;
- unsigned int lro_no_desc;
-#endif
+ struct igb_ring *multi_tx_table[IGB_ABS_MAX_TX_QUEUES];
unsigned int tx_ring_count;
unsigned int rx_ring_count;
+ unsigned int vfs_allocated_count;
+ struct vf_data_storage *vf_data;
};
#define IGB_FLAG_HAS_MSI (1 << 0)
-#define IGB_FLAG_MSI_ENABLE (1 << 1)
-#define IGB_FLAG_HAS_DCA (1 << 2)
-#define IGB_FLAG_DCA_ENABLED (1 << 3)
-#define IGB_FLAG_IN_NETPOLL (1 << 5)
-#define IGB_FLAG_QUAD_PORT_A (1 << 6)
-#define IGB_FLAG_NEED_CTX_IDX (1 << 7)
+#define IGB_FLAG_DCA_ENABLED (1 << 1)
+#define IGB_FLAG_QUAD_PORT_A (1 << 2)
+#define IGB_FLAG_NEED_CTX_IDX (1 << 3)
enum e1000_state_t {
__IGB_TESTING,
@@ -334,24 +315,24 @@ extern void igb_set_ethtool_ops(struct net_device *);
static inline s32 igb_reset_phy(struct e1000_hw *hw)
{
- if (hw->phy.ops.reset_phy)
- return hw->phy.ops.reset_phy(hw);
+ if (hw->phy.ops.reset)
+ return hw->phy.ops.reset(hw);
return 0;
}
static inline s32 igb_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
{
- if (hw->phy.ops.read_phy_reg)
- return hw->phy.ops.read_phy_reg(hw, offset, data);
+ if (hw->phy.ops.read_reg)
+ return hw->phy.ops.read_reg(hw, offset, data);
return 0;
}
static inline s32 igb_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data)
{
- if (hw->phy.ops.write_phy_reg)
- return hw->phy.ops.write_phy_reg(hw, offset, data);
+ if (hw->phy.ops.write_reg)
+ return hw->phy.ops.write_reg(hw, offset, data);
return 0;
}
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 3c831f1472a..fb09c8ad9f0 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -88,16 +88,11 @@ static const struct igb_stats igb_gstrings_stats[] = {
{ "rx_long_byte_count", IGB_STAT(stats.gorc) },
{ "rx_csum_offload_good", IGB_STAT(hw_csum_good) },
{ "rx_csum_offload_errors", IGB_STAT(hw_csum_err) },
- { "rx_header_split", IGB_STAT(rx_hdr_split) },
+ { "tx_dma_out_of_sync", IGB_STAT(stats.doosync) },
{ "alloc_rx_buff_failed", IGB_STAT(alloc_rx_buff_failed) },
{ "tx_smbus", IGB_STAT(stats.mgptc) },
{ "rx_smbus", IGB_STAT(stats.mgprc) },
{ "dropped_smbus", IGB_STAT(stats.mgpdc) },
-#ifdef CONFIG_IGB_LRO
- { "lro_aggregated", IGB_STAT(lro_aggregated) },
- { "lro_flushed", IGB_STAT(lro_flushed) },
- { "lro_no_desc", IGB_STAT(lro_no_desc) },
-#endif
};
#define IGB_QUEUE_STATS_LEN \
@@ -293,15 +288,15 @@ static int igb_set_rx_csum(struct net_device *netdev, u32 data)
static u32 igb_get_tx_csum(struct net_device *netdev)
{
- return (netdev->features & NETIF_F_HW_CSUM) != 0;
+ return (netdev->features & NETIF_F_IP_CSUM) != 0;
}
static int igb_set_tx_csum(struct net_device *netdev, u32 data)
{
if (data)
- netdev->features |= NETIF_F_HW_CSUM;
+ netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
else
- netdev->features &= ~NETIF_F_HW_CSUM;
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
return 0;
}
@@ -310,15 +305,13 @@ static int igb_set_tso(struct net_device *netdev, u32 data)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- if (data)
+ if (data) {
netdev->features |= NETIF_F_TSO;
- else
- netdev->features &= ~NETIF_F_TSO;
-
- if (data)
netdev->features |= NETIF_F_TSO6;
- else
+ } else {
+ netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6;
+ }
dev_info(&adapter->pdev->dev, "TSO is %s\n",
data ? "Enabled" : "Disabled");
@@ -405,7 +398,7 @@ static void igb_get_regs(struct net_device *netdev,
regs_buff[34] = rd32(E1000_RLPML);
regs_buff[35] = rd32(E1000_RFCTL);
regs_buff[36] = rd32(E1000_MRQC);
- regs_buff[37] = rd32(E1000_VMD_CTL);
+ regs_buff[37] = rd32(E1000_VT_CTL);
/* Transmit */
regs_buff[38] = rd32(E1000_TCTL);
@@ -598,12 +591,12 @@ static int igb_get_eeprom(struct net_device *netdev,
return -ENOMEM;
if (hw->nvm.type == e1000_nvm_eeprom_spi)
- ret_val = hw->nvm.ops.read_nvm(hw, first_word,
+ ret_val = hw->nvm.ops.read(hw, first_word,
last_word - first_word + 1,
eeprom_buff);
else {
for (i = 0; i < last_word - first_word + 1; i++) {
- ret_val = hw->nvm.ops.read_nvm(hw, first_word + i, 1,
+ ret_val = hw->nvm.ops.read(hw, first_word + i, 1,
&eeprom_buff[i]);
if (ret_val)
break;
@@ -650,14 +643,14 @@ static int igb_set_eeprom(struct net_device *netdev,
if (eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
- ret_val = hw->nvm.ops.read_nvm(hw, first_word, 1,
+ ret_val = hw->nvm.ops.read(hw, first_word, 1,
&eeprom_buff[0]);
ptr++;
}
if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
- ret_val = hw->nvm.ops.read_nvm(hw, last_word, 1,
+ ret_val = hw->nvm.ops.read(hw, last_word, 1,
&eeprom_buff[last_word - first_word]);
}
@@ -670,7 +663,7 @@ static int igb_set_eeprom(struct net_device *netdev,
for (i = 0; i < last_word - first_word + 1; i++)
eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);
- ret_val = hw->nvm.ops.write_nvm(hw, first_word,
+ ret_val = hw->nvm.ops.write(hw, first_word,
last_word - first_word + 1, eeprom_buff);
/* Update the checksum over the first part of the EEPROM if needed
@@ -694,7 +687,7 @@ static void igb_get_drvinfo(struct net_device *netdev,
/* EEPROM image version # is reported as firmware version # for
* 82575 controllers */
- adapter->hw.nvm.ops.read_nvm(&adapter->hw, 5, 1, &eeprom_data);
+ adapter->hw.nvm.ops.read(&adapter->hw, 5, 1, &eeprom_data);
sprintf(firmware_version, "%d.%d-%d",
(eeprom_data & 0xF000) >> 12,
(eeprom_data & 0x0FF0) >> 4,
@@ -863,23 +856,26 @@ static struct igb_reg_test reg_test_82576[] = {
{ E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_RDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- /* Enable all four RX queues before testing. */
- { E1000_RXDCTL(0), 0x100, 1, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+ { E1000_RDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_RDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+ /* Enable all RX queues before testing. */
+ { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+ { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
/* RDH is read-only for 82576, only test RDT. */
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_RDT(4), 0x40, 12, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
+ { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, 0 },
{ E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
{ E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
{ E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_TDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+ { E1000_TDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_TDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_TDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
@@ -926,12 +922,13 @@ static struct igb_reg_test reg_test_82575[] = {
static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
int reg, u32 mask, u32 write)
{
+ struct e1000_hw *hw = &adapter->hw;
u32 pat, val;
u32 _test[] =
{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
- writel((_test[pat] & write), (adapter->hw.hw_addr + reg));
- val = readl(adapter->hw.hw_addr + reg);
+ wr32(reg, (_test[pat] & write));
+ val = rd32(reg);
if (val != (_test[pat] & write & mask)) {
dev_err(&adapter->pdev->dev, "pattern test reg %04X "
"failed: got 0x%08X expected 0x%08X\n",
@@ -946,9 +943,10 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
int reg, u32 mask, u32 write)
{
+ struct e1000_hw *hw = &adapter->hw;
u32 val;
- writel((write & mask), (adapter->hw.hw_addr + reg));
- val = readl(adapter->hw.hw_addr + reg);
+ wr32(reg, write & mask);
+ val = rd32(reg);
if ((write & mask) != (val & mask)) {
dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
" got 0x%08X expected 0x%08X\n", reg,
@@ -1014,12 +1012,14 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
for (i = 0; i < test->array_len; i++) {
switch (test->test_type) {
case PATTERN_TEST:
- REG_PATTERN_TEST(test->reg + (i * test->reg_offset),
+ REG_PATTERN_TEST(test->reg +
+ (i * test->reg_offset),
test->mask,
test->write);
break;
case SET_READ_TEST:
- REG_SET_AND_CHECK(test->reg + (i * test->reg_offset),
+ REG_SET_AND_CHECK(test->reg +
+ (i * test->reg_offset),
test->mask,
test->write);
break;
@@ -1061,7 +1061,7 @@ static int igb_eeprom_test(struct igb_adapter *adapter, u64 *data)
*data = 0;
/* Read and add up the contents of the EEPROM */
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
- if ((adapter->hw.nvm.ops.read_nvm(&adapter->hw, i, 1, &temp))
+ if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp))
< 0) {
*data = 1;
break;
@@ -1091,16 +1091,17 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
{
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- u32 mask, i = 0, shared_int = true;
+ u32 mask, ics_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) {
+ if (adapter->msix_entries)
/* NOTE: we don't test MSI-X interrupts here, yet */
return 0;
- } else if (adapter->flags & IGB_FLAG_HAS_MSI) {
+
+ if (adapter->flags & IGB_FLAG_HAS_MSI) {
shared_int = false;
if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
*data = 1;
@@ -1116,16 +1117,31 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
}
dev_info(&adapter->pdev->dev, "testing %s interrupt\n",
(shared_int ? "shared" : "unshared"));
-
/* Disable all the interrupts */
wr32(E1000_IMC, 0xFFFFFFFF);
msleep(10);
+ /* Define all writable bits for ICS */
+ switch(hw->mac.type) {
+ case e1000_82575:
+ ics_mask = 0x37F47EDD;
+ break;
+ case e1000_82576:
+ ics_mask = 0x77D4FBFD;
+ break;
+ default:
+ ics_mask = 0x7FFFFFFF;
+ break;
+ }
+
/* Test each interrupt */
- for (; i < 10; i++) {
+ for (; i < 31; i++) {
/* Interrupt to test */
mask = 1 << i;
+ if (!(mask & ics_mask))
+ continue;
+
if (!shared_int) {
/* Disable the interrupt to be reported in
* the cause register and then force the same
@@ -1134,8 +1150,12 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;
- wr32(E1000_IMC, ~mask & 0x00007FFF);
- wr32(E1000_ICS, ~mask & 0x00007FFF);
+
+ /* Flush any pending interrupts */
+ wr32(E1000_ICR, ~0);
+
+ wr32(E1000_IMC, mask);
+ wr32(E1000_ICS, mask);
msleep(10);
if (adapter->test_icr & mask) {
@@ -1151,6 +1171,10 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;
+
+ /* Flush any pending interrupts */
+ wr32(E1000_ICR, ~0);
+
wr32(E1000_IMS, mask);
wr32(E1000_ICS, mask);
msleep(10);
@@ -1168,11 +1192,15 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;
- wr32(E1000_IMC, ~mask & 0x00007FFF);
- wr32(E1000_ICS, ~mask & 0x00007FFF);
+
+ /* Flush any pending interrupts */
+ wr32(E1000_ICR, ~0);
+
+ wr32(E1000_IMC, ~mask);
+ wr32(E1000_ICS, ~mask);
msleep(10);
- if (adapter->test_icr) {
+ if (adapter->test_icr & mask) {
*data = 5;
break;
}
@@ -1180,7 +1208,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
}
/* Disable all the interrupts */
- wr32(E1000_IMC, 0xFFFFFFFF);
+ wr32(E1000_IMC, ~0);
msleep(10);
/* Unhook test interrupt handler */
@@ -1244,6 +1272,7 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
struct igb_ring *tx_ring = &adapter->test_tx_ring;
struct igb_ring *rx_ring = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
+ struct igb_buffer *buffer_info;
u32 rctl;
int i, ret_val;
@@ -1260,7 +1289,7 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
goto err_nomem;
}
- tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
+ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
&tx_ring->dma);
@@ -1274,7 +1303,7 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
((u64) tx_ring->dma & 0x00000000FFFFFFFF));
wr32(E1000_TDBAH(0), ((u64) tx_ring->dma >> 32));
wr32(E1000_TDLEN(0),
- tx_ring->count * sizeof(struct e1000_tx_desc));
+ tx_ring->count * sizeof(union e1000_adv_tx_desc));
wr32(E1000_TDH(0), 0);
wr32(E1000_TDT(0), 0);
wr32(E1000_TCTL,
@@ -1283,27 +1312,31 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT);
for (i = 0; i < tx_ring->count; i++) {
- struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
+ union e1000_adv_tx_desc *tx_desc;
struct sk_buff *skb;
unsigned int size = 1024;
+ tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
skb = alloc_skb(size, GFP_KERNEL);
if (!skb) {
ret_val = 3;
goto err_nomem;
}
skb_put(skb, size);
- tx_ring->buffer_info[i].skb = skb;
- tx_ring->buffer_info[i].length = skb->len;
- tx_ring->buffer_info[i].dma =
- pci_map_single(pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
- tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma);
- tx_desc->lower.data = cpu_to_le32(skb->len);
- tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
- E1000_TXD_CMD_IFCS |
- E1000_TXD_CMD_RS);
- tx_desc->upper.data = 0;
+ buffer_info = &tx_ring->buffer_info[i];
+ buffer_info->skb = skb;
+ buffer_info->length = skb->len;
+ buffer_info->dma = pci_map_single(pdev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ tx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
+ tx_desc->read.olinfo_status = cpu_to_le32(skb->len) <<
+ E1000_ADVTXD_PAYLEN_SHIFT;
+ tx_desc->read.cmd_type_len = cpu_to_le32(skb->len);
+ tx_desc->read.cmd_type_len |= cpu_to_le32(E1000_TXD_CMD_EOP |
+ E1000_TXD_CMD_IFCS |
+ E1000_TXD_CMD_RS |
+ E1000_ADVTXD_DTYP_DATA |
+ E1000_ADVTXD_DCMD_DEXT);
}
/* Setup Rx descriptor ring and Rx buffers */
@@ -1319,7 +1352,7 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
goto err_nomem;
}
- rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc);
+ rx_ring->size = rx_ring->count * sizeof(union e1000_adv_rx_desc);
rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
&rx_ring->dma);
if (!rx_ring->desc) {
@@ -1338,16 +1371,17 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
wr32(E1000_RDH(0), 0);
wr32(E1000_RDT(0), 0);
rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
- rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
- E1000_RCTL_RDMTS_HALF |
+ rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
wr32(E1000_RCTL, rctl);
- wr32(E1000_SRRCTL(0), 0);
+ wr32(E1000_SRRCTL(0), E1000_SRRCTL_DESCTYPE_ADV_ONEBUF);
for (i = 0; i < rx_ring->count; i++) {
- struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
+ union e1000_adv_rx_desc *rx_desc;
struct sk_buff *skb;
+ buffer_info = &rx_ring->buffer_info[i];
+ rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
skb = alloc_skb(IGB_RXBUFFER_2048 + NET_IP_ALIGN,
GFP_KERNEL);
if (!skb) {
@@ -1355,11 +1389,11 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
goto err_nomem;
}
skb_reserve(skb, NET_IP_ALIGN);
- rx_ring->buffer_info[i].skb = skb;
- rx_ring->buffer_info[i].dma =
- pci_map_single(pdev, skb->data, IGB_RXBUFFER_2048,
- PCI_DMA_FROMDEVICE);
- rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma);
+ buffer_info->skb = skb;
+ buffer_info->dma = pci_map_single(pdev, skb->data,
+ IGB_RXBUFFER_2048,
+ PCI_DMA_FROMDEVICE);
+ rx_desc->read.pkt_addr = cpu_to_le64(buffer_info->dma);
memset(skb->data, 0x00, skb->len);
}
@@ -1458,7 +1492,7 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)
E1000_CTRL_TFCE |
E1000_CTRL_LRST);
reg |= E1000_CTRL_SLU |
- E1000_CTRL_FD;
+ E1000_CTRL_FD;
wr32(E1000_CTRL, reg);
/* Unset switch control to serdes energy detect */
@@ -1745,6 +1779,15 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
/* return success for non excluded adapter ports */
retval = 0;
break;
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+ /* quad port adapters only support WoL on port A */
+ if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
+ wol->supported = 0;
+ break;
+ }
+ /* return success for non excluded adapter ports */
+ retval = 0;
+ break;
default:
/* dual port cards only support WoL on port A from now on
* unless it was enabled in the eeprom for port B
@@ -1827,9 +1870,6 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return 0;
}
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define IGB_ID_INTERVAL (HZ/4)
-
/* bit defines for adapter->led_status */
#define IGB_LED_ON 0
@@ -1921,18 +1961,6 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
int j;
int i;
-#ifdef CONFIG_IGB_LRO
- int aggregated = 0, flushed = 0, no_desc = 0;
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
- flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
- no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
- }
- adapter->lro_aggregated = aggregated;
- adapter->lro_flushed = flushed;
- adapter->lro_no_desc = no_desc;
-#endif
igb_update_stats(adapter);
for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index b82b0fb2056..ca842163dce 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-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,
@@ -34,6 +34,7 @@
#include <linux/ipv6.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
+#include <linux/net_tstamp.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
@@ -48,12 +49,12 @@
#endif
#include "igb.h"
-#define DRV_VERSION "1.2.45-k2"
+#define DRV_VERSION "1.3.16-k2"
char igb_driver_name[] = "igb";
char igb_driver_version[] = DRV_VERSION;
static const char igb_driver_string[] =
"Intel(R) Gigabit Ethernet Network Driver";
-static const char igb_copyright[] = "Copyright (c) 2008 Intel Corporation.";
+static const char igb_copyright[] = "Copyright (c) 2007-2009 Intel Corporation.";
static const struct e1000_info *igb_info_tbl[] = {
[board_82575] = &e1000_82575_info,
@@ -61,8 +62,10 @@ static const struct e1000_info *igb_info_tbl[] = {
static struct pci_device_id igb_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
@@ -105,7 +108,6 @@ static irqreturn_t igb_intr_msi(int irq, void *);
static irqreturn_t igb_msix_other(int irq, void *);
static irqreturn_t igb_msix_rx(int irq, void *);
static irqreturn_t igb_msix_tx(int irq, void *);
-static int igb_clean_rx_ring_msix(struct napi_struct *, int);
#ifdef CONFIG_IGB_DCA
static void igb_update_rx_dca(struct igb_ring *);
static void igb_update_tx_dca(struct igb_ring *);
@@ -115,9 +117,6 @@ static bool igb_clean_tx_irq(struct igb_ring *);
static int igb_poll(struct napi_struct *, int);
static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int);
static void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
-#ifdef CONFIG_IGB_LRO
-static int igb_get_skb_hdr(struct sk_buff *skb, void **, void **, u64 *, void *);
-#endif
static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
static void igb_tx_timeout(struct net_device *);
static void igb_reset_task(struct work_struct *);
@@ -125,6 +124,16 @@ static void igb_vlan_rx_register(struct net_device *, struct vlan_group *);
static void igb_vlan_rx_add_vid(struct net_device *, u16);
static void igb_vlan_rx_kill_vid(struct net_device *, u16);
static void igb_restore_vlan(struct igb_adapter *);
+static void igb_ping_all_vfs(struct igb_adapter *);
+static void igb_msg_task(struct igb_adapter *);
+static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
+static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
+static void igb_set_mc_list_pools(struct igb_adapter *, int, u16);
+static void igb_vmm_control(struct igb_adapter *);
+static inline void igb_set_vmolr(struct e1000_hw *, int);
+static inline int igb_set_vf_rlpml(struct igb_adapter *, int, int);
+static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
+static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
static int igb_suspend(struct pci_dev *, pm_message_t);
#ifdef CONFIG_PM
@@ -139,12 +148,18 @@ static struct notifier_block dca_notifier = {
.priority = 0
};
#endif
-
#ifdef CONFIG_NET_POLL_CONTROLLER
/* for netdump / net console */
static void igb_netpoll(struct net_device *);
#endif
+#ifdef CONFIG_PCI_IOV
+static ssize_t igb_set_num_vfs(struct device *, struct device_attribute *,
+ const char *, size_t);
+static ssize_t igb_show_num_vfs(struct device *, struct device_attribute *,
+ char *);
+DEVICE_ATTR(num_vfs, S_IRUGO | S_IWUSR, igb_show_num_vfs, igb_set_num_vfs);
+#endif
static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
pci_channel_state_t);
static pci_ers_result_t igb_io_slot_reset(struct pci_dev *);
@@ -178,6 +193,54 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+/**
+ * Scale the NIC clock cycle by a large factor so that
+ * relatively small clock corrections can be added or
+ * substracted at each clock tick. The drawbacks of a
+ * large factor are a) that the clock register overflows
+ * more quickly (not such a big deal) and b) that the
+ * increment per tick has to fit into 24 bits.
+ *
+ * Note that
+ * TIMINCA = IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS *
+ * IGB_TSYNC_SCALE
+ * TIMINCA += TIMINCA * adjustment [ppm] / 1e9
+ *
+ * The base scale factor is intentionally a power of two
+ * so that the division in %struct timecounter can be done with
+ * a shift.
+ */
+#define IGB_TSYNC_SHIFT (19)
+#define IGB_TSYNC_SCALE (1<<IGB_TSYNC_SHIFT)
+
+/**
+ * The duration of one clock cycle of the NIC.
+ *
+ * @todo This hard-coded value is part of the specification and might change
+ * in future hardware revisions. Add revision check.
+ */
+#define IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS 16
+
+#if (IGB_TSYNC_SCALE * IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS) >= (1<<24)
+# error IGB_TSYNC_SCALE and/or IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS are too large to fit into TIMINCA
+#endif
+
+/**
+ * igb_read_clock - read raw cycle counter (to be used by time counter)
+ */
+static cycle_t igb_read_clock(const struct cyclecounter *tc)
+{
+ struct igb_adapter *adapter =
+ container_of(tc, struct igb_adapter, cycles);
+ struct e1000_hw *hw = &adapter->hw;
+ u64 stamp;
+
+ stamp = rd32(E1000_SYSTIML);
+ stamp |= (u64)rd32(E1000_SYSTIMH) << 32ULL;
+
+ return stamp;
+}
+
#ifdef DEBUG
/**
* igb_get_hw_dev_name - return device name string
@@ -188,9 +251,44 @@ char *igb_get_hw_dev_name(struct e1000_hw *hw)
struct igb_adapter *adapter = hw->back;
return adapter->netdev->name;
}
+
+/**
+ * igb_get_time_str - format current NIC and system time as string
+ */
+static char *igb_get_time_str(struct igb_adapter *adapter,
+ char buffer[160])
+{
+ cycle_t hw = adapter->cycles.read(&adapter->cycles);
+ struct timespec nic = ns_to_timespec(timecounter_read(&adapter->clock));
+ struct timespec sys;
+ struct timespec delta;
+ getnstimeofday(&sys);
+
+ delta = timespec_sub(nic, sys);
+
+ sprintf(buffer,
+ "HW %llu, NIC %ld.%09lus, SYS %ld.%09lus, NIC-SYS %lds + %09luns",
+ hw,
+ (long)nic.tv_sec, nic.tv_nsec,
+ (long)sys.tv_sec, sys.tv_nsec,
+ (long)delta.tv_sec, delta.tv_nsec);
+
+ return buffer;
+}
#endif
/**
+ * igb_desc_unused - calculate if we have unused descriptors
+ **/
+static int igb_desc_unused(struct igb_ring *ring)
+{
+ if (ring->next_to_clean > ring->next_to_use)
+ return ring->next_to_clean - ring->next_to_use - 1;
+
+ return ring->count + ring->next_to_clean - ring->next_to_use - 1;
+}
+
+/**
* igb_init_module - Driver Registration Routine
*
* igb_init_module is the first routine called when the driver is
@@ -206,10 +304,11 @@ static int __init igb_init_module(void)
global_quad_port_a = 0;
- ret = pci_register_driver(&igb_driver);
#ifdef CONFIG_IGB_DCA
dca_register_notify(&dca_notifier);
#endif
+
+ ret = pci_register_driver(&igb_driver);
return ret;
}
@@ -242,6 +341,7 @@ module_exit(igb_exit_module);
static void igb_cache_ring_register(struct igb_adapter *adapter)
{
int i;
+ unsigned int rbase_offset = adapter->vfs_allocated_count;
switch (adapter->hw.mac.type) {
case e1000_82576:
@@ -251,9 +351,11 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
* and continue consuming queues in the same sequence
*/
for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].reg_idx = Q_IDX_82576(i);
+ adapter->rx_ring[i].reg_idx = rbase_offset +
+ Q_IDX_82576(i);
for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i].reg_idx = Q_IDX_82576(i);
+ adapter->tx_ring[i].reg_idx = rbase_offset +
+ Q_IDX_82576(i);
break;
case e1000_82575:
default:
@@ -353,7 +455,7 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
a vector number along with a "valid" bit. Sadly, the layout
of the table is somewhat counterintuitive. */
if (rx_queue > IGB_N0_QUEUE) {
- index = (rx_queue >> 1);
+ index = (rx_queue >> 1) + adapter->vfs_allocated_count;
ivar = array_rd32(E1000_IVAR0, index);
if (rx_queue & 0x1) {
/* vector goes into third byte of register */
@@ -368,7 +470,7 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
array_wr32(E1000_IVAR0, index, ivar);
}
if (tx_queue > IGB_N0_QUEUE) {
- index = (tx_queue >> 1);
+ index = (tx_queue >> 1) + adapter->vfs_allocated_count;
ivar = array_rd32(E1000_IVAR0, index);
if (tx_queue & 0x1) {
/* vector goes into high byte of register */
@@ -406,7 +508,7 @@ static void igb_configure_msix(struct igb_adapter *adapter)
/* Turn on MSI-X capability first, or our settings
* won't stick. And it will take days to debug. */
wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE |
- E1000_GPIE_PBA | E1000_GPIE_EIAME |
+ E1000_GPIE_PBA | E1000_GPIE_EIAME |
E1000_GPIE_NSICR);
for (i = 0; i < adapter->num_tx_queues; i++) {
@@ -505,9 +607,6 @@ static int igb_request_msix(struct igb_adapter *adapter)
goto out;
ring->itr_register = E1000_EITR(0) + (vector << 2);
ring->itr_val = adapter->itr;
- /* overwrite the poll routine for MSIX, we've already done
- * netif_napi_add */
- ring->napi.poll = &igb_clean_rx_ring_msix;
vector++;
}
@@ -545,6 +644,11 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
int err;
int numvecs, i;
+ /* Number of supported queues. */
+ /* Having more queues than CPUs doesn't make sense. */
+ adapter->num_rx_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
+ adapter->num_tx_queues = min_t(u32, IGB_MAX_TX_QUEUES, num_online_cpus());
+
numvecs = adapter->num_tx_queues + adapter->num_rx_queues + 1;
adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry),
GFP_KERNEL);
@@ -686,7 +790,10 @@ static void igb_irq_enable(struct igb_adapter *adapter)
wr32(E1000_EIAC, adapter->eims_enable_mask);
wr32(E1000_EIAM, adapter->eims_enable_mask);
wr32(E1000_EIMS, adapter->eims_enable_mask);
- wr32(E1000_IMS, E1000_IMS_LSC);
+ if (adapter->vfs_allocated_count)
+ wr32(E1000_MBVFIMR, 0xFF);
+ wr32(E1000_IMS, (E1000_IMS_LSC | E1000_IMS_VMMB |
+ E1000_IMS_DOUTSYNC));
} else {
wr32(E1000_IMS, IMS_ENABLE_MASK);
wr32(E1000_IAM, IMS_ENABLE_MASK);
@@ -777,12 +884,12 @@ static void igb_configure(struct igb_adapter *adapter)
igb_rx_fifo_flush_82575(&adapter->hw);
- /* call IGB_DESC_UNUSED which always leaves
+ /* call igb_desc_unused which always leaves
* at least 1 descriptor unused to make sure
* next_to_use != next_to_clean */
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &adapter->rx_ring[i];
- igb_alloc_rx_buffers_adv(ring, IGB_DESC_UNUSED(ring));
+ igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring));
}
@@ -810,6 +917,10 @@ int igb_up(struct igb_adapter *adapter)
if (adapter->msix_entries)
igb_configure_msix(adapter);
+ igb_vmm_control(adapter);
+ igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
+ igb_set_vmolr(hw, adapter->vfs_allocated_count);
+
/* Clear any pending interrupts. */
rd32(E1000_ICR);
igb_irq_enable(adapter);
@@ -855,6 +966,10 @@ void igb_down(struct igb_adapter *adapter)
netdev->tx_queue_len = adapter->tx_queue_len;
netif_carrier_off(netdev);
+
+ /* record the stats before reset*/
+ igb_update_stats(adapter);
+
adapter->link_speed = 0;
adapter->link_duplex = 0;
@@ -885,11 +1000,14 @@ void igb_reset(struct igb_adapter *adapter)
/* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required.
*/
- if (mac->type != e1000_82576) {
- pba = E1000_PBA_34K;
- }
- else {
+ switch (mac->type) {
+ case e1000_82576:
pba = E1000_PBA_64K;
+ break;
+ case e1000_82575:
+ default:
+ pba = E1000_PBA_34K;
+ break;
}
if ((adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) &&
@@ -911,7 +1029,7 @@ void igb_reset(struct igb_adapter *adapter)
/* the tx fifo also stores 16 bytes of information about the tx
* but don't include ethernet FCS because hardware appends it */
min_tx_space = (adapter->max_frame_size +
- sizeof(struct e1000_tx_desc) -
+ sizeof(union e1000_adv_tx_desc) -
ETH_FCS_LEN) * 2;
min_tx_space = ALIGN(min_tx_space, 1024);
min_tx_space >>= 10;
@@ -955,6 +1073,20 @@ void igb_reset(struct igb_adapter *adapter)
fc->send_xon = 1;
fc->type = fc->original_type;
+ /* disable receive for all VFs and wait one second */
+ if (adapter->vfs_allocated_count) {
+ int i;
+ for (i = 0 ; i < adapter->vfs_allocated_count; i++)
+ adapter->vf_data[i].clear_to_send = false;
+
+ /* ping all the active vfs to let them know we are going down */
+ igb_ping_all_vfs(adapter);
+
+ /* disable transmits and receives */
+ wr32(E1000_VFRE, 0);
+ wr32(E1000_VFTE, 0);
+ }
+
/* Allow time for pending master requests to run */
adapter->hw.mac.ops.reset_hw(&adapter->hw);
wr32(E1000_WUC, 0);
@@ -971,21 +1103,6 @@ void igb_reset(struct igb_adapter *adapter)
igb_get_phy_info(&adapter->hw);
}
-/**
- * igb_is_need_ioport - determine if an adapter needs ioport resources or not
- * @pdev: PCI device information struct
- *
- * Returns true if an adapter needs ioport resources
- **/
-static int igb_is_need_ioport(struct pci_dev *pdev)
-{
- switch (pdev->device) {
- /* Currently there are no adapters that need ioport resources */
- default:
- return false;
- }
-}
-
static const struct net_device_ops igb_netdev_ops = {
.ndo_open = igb_open,
.ndo_stop = igb_close,
@@ -1022,24 +1139,14 @@ static int __devinit igb_probe(struct pci_dev *pdev,
struct net_device *netdev;
struct igb_adapter *adapter;
struct e1000_hw *hw;
- struct pci_dev *us_dev;
const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
unsigned long mmio_start, mmio_len;
- int i, err, pci_using_dac, pos;
- u16 eeprom_data = 0, state = 0;
+ int err, pci_using_dac;
+ u16 eeprom_data = 0;
u16 eeprom_apme_mask = IGB_EEPROM_APME;
u32 part_num;
- int bars, need_ioport;
- /* do not allocate ioport bars when not needed */
- need_ioport = igb_is_need_ioport(pdev);
- if (need_ioport) {
- bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
- err = pci_enable_device(pdev);
- } else {
- bars = pci_select_bars(pdev, IORESOURCE_MEM);
- err = pci_enable_device_mem(pdev);
- }
+ err = pci_enable_device_mem(pdev);
if (err)
return err;
@@ -1061,28 +1168,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
}
}
- /* 82575 requires that the pci-e link partner disable the L0s state */
- switch (pdev->device) {
- case E1000_DEV_ID_82575EB_COPPER:
- case E1000_DEV_ID_82575EB_FIBER_SERDES:
- case E1000_DEV_ID_82575GB_QUAD_COPPER:
- us_dev = pdev->bus->self;
- pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
- if (pos) {
- pci_read_config_word(us_dev, pos + PCI_EXP_LNKCTL,
- &state);
- state &= ~PCIE_LINK_STATE_L0S;
- pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL,
- state);
- dev_info(&pdev->dev,
- "Disabling ASPM L0s upstream switch port %s\n",
- pci_name(us_dev));
- }
- default:
- break;
- }
-
- err = pci_request_selected_regions(pdev, bars, igb_driver_name);
+ err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM),
+ igb_driver_name);
if (err)
goto err_pci_reg;
@@ -1097,7 +1185,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
pci_save_state(pdev);
err = -ENOMEM;
- netdev = alloc_etherdev_mq(sizeof(struct igb_adapter), IGB_MAX_TX_QUEUES);
+ netdev = alloc_etherdev_mq(sizeof(struct igb_adapter),
+ IGB_ABS_MAX_TX_QUEUES);
if (!netdev)
goto err_alloc_etherdev;
@@ -1110,15 +1199,13 @@ static int __devinit igb_probe(struct pci_dev *pdev,
hw = &adapter->hw;
hw->back = adapter;
adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
- adapter->bars = bars;
- adapter->need_ioport = need_ioport;
mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0);
err = -EIO;
- adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
- if (!adapter->hw.hw_addr)
+ hw->hw_addr = ioremap(mmio_start, mmio_len);
+ if (!hw->hw_addr)
goto err_ioremap;
netdev->netdev_ops = &igb_netdev_ops;
@@ -1146,8 +1233,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
/* Initialize skew-specific constants */
err = ei->get_invariants(hw);
if (err)
- goto err_hw_init;
+ goto err_sw_init;
+ /* setup the private structure */
err = igb_sw_init(adapter);
if (err)
goto err_sw_init;
@@ -1156,11 +1244,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
/* set flags */
switch (hw->mac.type) {
- case e1000_82576:
case e1000_82575:
- adapter->flags |= IGB_FLAG_HAS_DCA;
adapter->flags |= IGB_FLAG_NEED_CTX_IDX;
break;
+ case e1000_82576:
default:
break;
}
@@ -1180,27 +1267,25 @@ static int __devinit igb_probe(struct pci_dev *pdev,
"PHY reset is blocked due to SOL/IDER session.\n");
netdev->features = NETIF_F_SG |
- NETIF_F_HW_CSUM |
+ NETIF_F_IP_CSUM |
NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
+ netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
-#ifdef CONFIG_IGB_LRO
- netdev->features |= NETIF_F_LRO;
-#endif
+ netdev->features |= NETIF_F_GRO;
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
- netdev->vlan_features |= NETIF_F_HW_CSUM;
+ netdev->vlan_features |= NETIF_F_IP_CSUM;
netdev->vlan_features |= NETIF_F_SG;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->features |= NETIF_F_LLTX;
adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
/* before reading the NVM, reset the controller to put the device in a
@@ -1227,25 +1312,15 @@ static int __devinit igb_probe(struct pci_dev *pdev,
goto err_eeprom;
}
- init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &igb_watchdog;
- adapter->watchdog_timer.data = (unsigned long) adapter;
-
- init_timer(&adapter->phy_info_timer);
- adapter->phy_info_timer.function = &igb_update_phy_info;
- adapter->phy_info_timer.data = (unsigned long) adapter;
+ setup_timer(&adapter->watchdog_timer, &igb_watchdog,
+ (unsigned long) adapter);
+ setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
+ (unsigned long) adapter);
INIT_WORK(&adapter->reset_task, igb_reset_task);
INIT_WORK(&adapter->watchdog_task, igb_watchdog_task);
- /* Initialize link & ring properties that are user-changeable */
- adapter->tx_ring->count = 256;
- for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i].count = adapter->tx_ring->count;
- adapter->rx_ring->count = 256;
- for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].count = adapter->rx_ring->count;
-
+ /* Initialize link properties that are user-changeable */
adapter->fc_autoneg = true;
hw->mac.autoneg = true;
hw->phy.autoneg_advertised = 0x2f;
@@ -1253,7 +1328,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
hw->fc.original_type = e1000_fc_default;
hw->fc.type = e1000_fc_default;
- adapter->itr_setting = 3;
+ adapter->itr_setting = IGB_DEFAULT_ITR;
adapter->itr = IGB_START_ITR;
igb_validate_mdi_setting(hw);
@@ -1264,10 +1339,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
* enable the ACPI Magic Packet filter
*/
- if (hw->bus.func == 0 ||
- hw->device_id == E1000_DEV_ID_82575EB_COPPER)
- hw->nvm.ops.read_nvm(hw, NVM_INIT_CONTROL3_PORT_A, 1,
- &eeprom_data);
+ if (hw->bus.func == 0)
+ hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+ else if (hw->bus.func == 1)
+ hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
if (eeprom_data & eeprom_apme_mask)
adapter->eeprom_wol |= E1000_WUFC_MAG;
@@ -1287,6 +1362,16 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
adapter->eeprom_wol = 0;
break;
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+ /* if quad port adapter, disable WoL on all but port A */
+ if (global_quad_port_a != 0)
+ adapter->eeprom_wol = 0;
+ else
+ adapter->flags |= IGB_FLAG_QUAD_PORT_A;
+ /* Reset for multiple quad port adapters */
+ if (++global_quad_port_a == 4)
+ global_quad_port_a = 0;
+ break;
}
/* initialize the wol settings based on the eeprom settings */
@@ -1309,18 +1394,82 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (err)
goto err_register;
+#ifdef CONFIG_PCI_IOV
+ /* since iov functionality isn't critical to base device function we
+ * can accept failure. If it fails we don't allow iov to be enabled */
+ if (hw->mac.type == e1000_82576) {
+ err = pci_enable_sriov(pdev, 0);
+ if (!err)
+ err = device_create_file(&netdev->dev,
+ &dev_attr_num_vfs);
+ if (err)
+ dev_err(&pdev->dev, "Failed to initialize IOV\n");
+ }
+
+#endif
#ifdef CONFIG_IGB_DCA
- if ((adapter->flags & IGB_FLAG_HAS_DCA) &&
- (dca_add_requester(&pdev->dev) == 0)) {
+ 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, 2);
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
igb_setup_dca(adapter);
}
#endif
+ /*
+ * Initialize hardware timer: we keep it running just in case
+ * that some program needs it later on.
+ */
+ memset(&adapter->cycles, 0, sizeof(adapter->cycles));
+ adapter->cycles.read = igb_read_clock;
+ adapter->cycles.mask = CLOCKSOURCE_MASK(64);
+ adapter->cycles.mult = 1;
+ adapter->cycles.shift = IGB_TSYNC_SHIFT;
+ wr32(E1000_TIMINCA,
+ (1<<24) |
+ IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS * IGB_TSYNC_SCALE);
+#if 0
+ /*
+ * Avoid rollover while we initialize by resetting the time counter.
+ */
+ wr32(E1000_SYSTIML, 0x00000000);
+ wr32(E1000_SYSTIMH, 0x00000000);
+#else
+ /*
+ * Set registers so that rollover occurs soon to test this.
+ */
+ wr32(E1000_SYSTIML, 0x00000000);
+ wr32(E1000_SYSTIMH, 0xFF800000);
+#endif
+ wrfl();
+ timecounter_init(&adapter->clock,
+ &adapter->cycles,
+ ktime_to_ns(ktime_get_real()));
+
+ /*
+ * Synchronize our NIC clock against system wall clock. NIC
+ * time stamp reading requires ~3us per sample, each sample
+ * was pretty stable even under load => only require 10
+ * samples for each offset comparison.
+ */
+ memset(&adapter->compare, 0, sizeof(adapter->compare));
+ adapter->compare.source = &adapter->clock;
+ adapter->compare.target = ktime_get_real;
+ adapter->compare.num_samples = 10;
+ timecompare_update(&adapter->compare, 0);
+
+#ifdef DEBUG
+ {
+ char buffer[160];
+ printk(KERN_DEBUG
+ "igb: %s: hw %p initialized timer\n",
+ igb_get_time_str(adapter, buffer),
+ &adapter->hw);
+ }
+#endif
+
dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
/* print bus type/speed/width info */
dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n",
@@ -1353,15 +1502,14 @@ err_eeprom:
if (hw->flash_address)
iounmap(hw->flash_address);
- igb_remove_device(hw);
igb_free_queues(adapter);
err_sw_init:
-err_hw_init:
iounmap(hw->hw_addr);
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_selected_regions(pdev, bars);
+ pci_release_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM));
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -1381,9 +1529,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_IGB_DCA
struct e1000_hw *hw = &adapter->hw;
-#endif
int err;
/* flush_scheduled work may reschedule our watchdog task, so
@@ -1399,7 +1545,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
dev_info(&pdev->dev, "DCA disabled\n");
dca_remove_requester(&pdev->dev);
adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
- wr32(E1000_DCA_CTRL, 1);
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_DISABLE);
}
#endif
@@ -1412,15 +1558,29 @@ static void __devexit igb_remove(struct pci_dev *pdev)
if (!igb_check_reset_block(&adapter->hw))
igb_reset_phy(&adapter->hw);
- igb_remove_device(&adapter->hw);
igb_reset_interrupt_capability(adapter);
igb_free_queues(adapter);
- iounmap(adapter->hw.hw_addr);
- if (adapter->hw.flash_address)
- iounmap(adapter->hw.flash_address);
- pci_release_selected_regions(pdev, adapter->bars);
+#ifdef CONFIG_PCI_IOV
+ /* reclaim resources allocated to VFs */
+ if (adapter->vf_data) {
+ /* disable iov and allow time for transactions to clear */
+ pci_disable_sriov(pdev);
+ msleep(500);
+
+ kfree(adapter->vf_data);
+ adapter->vf_data = NULL;
+ wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
+ msleep(100);
+ dev_info(&pdev->dev, "IOV Disabled\n");
+ }
+#endif
+ iounmap(hw->hw_addr);
+ if (hw->flash_address)
+ iounmap(hw->flash_address);
+ pci_release_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM));
free_netdev(netdev);
@@ -1455,11 +1615,6 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
- /* Number of supported queues. */
- /* Having more queues than CPUs doesn't make sense. */
- adapter->num_rx_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
- adapter->num_tx_queues = min_t(u32, IGB_MAX_TX_QUEUES, num_online_cpus());
-
/* This call may decrease the number of queues depending on
* interrupt mode. */
igb_set_interrupt_capability(adapter);
@@ -1522,6 +1677,10 @@ static int igb_open(struct net_device *netdev)
* clean_rx handler before we do so. */
igb_configure(adapter);
+ igb_vmm_control(adapter);
+ igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
+ igb_set_vmolr(hw, adapter->vfs_allocated_count);
+
err = igb_request_irq(adapter);
if (err)
goto err_req_irq;
@@ -1597,7 +1756,6 @@ static int igb_close(struct net_device *netdev)
*
* Return 0 on success, negative on failure
**/
-
int igb_setup_tx_resources(struct igb_adapter *adapter,
struct igb_ring *tx_ring)
{
@@ -1611,7 +1769,7 @@ int igb_setup_tx_resources(struct igb_adapter *adapter,
memset(tx_ring->buffer_info, 0, size);
/* round up to nearest 4K */
- tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
+ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
@@ -1658,7 +1816,7 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
for (i = 0; i < IGB_MAX_TX_QUEUES; i++) {
r_idx = i % adapter->num_tx_queues;
adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
- }
+ }
return err;
}
@@ -1677,13 +1835,13 @@ static void igb_configure_tx(struct igb_adapter *adapter)
int i, j;
for (i = 0; i < adapter->num_tx_queues; i++) {
- struct igb_ring *ring = &(adapter->tx_ring[i]);
+ struct igb_ring *ring = &adapter->tx_ring[i];
j = ring->reg_idx;
wr32(E1000_TDLEN(j),
- ring->count * sizeof(struct e1000_tx_desc));
+ ring->count * sizeof(union e1000_adv_tx_desc));
tdba = ring->dma;
wr32(E1000_TDBAL(j),
- tdba & 0x00000000ffffffffULL);
+ tdba & 0x00000000ffffffffULL);
wr32(E1000_TDBAH(j), tdba >> 32);
ring->head = E1000_TDH(j);
@@ -1703,12 +1861,11 @@ static void igb_configure_tx(struct igb_adapter *adapter)
wr32(E1000_DCA_TXCTRL(j), txctrl);
}
-
-
- /* Use the default values for the Tx Inter Packet Gap (IPG) timer */
+ /* disable queue 0 to prevent tail bump w/o re-configuration */
+ if (adapter->vfs_allocated_count)
+ wr32(E1000_TXDCTL(0), 0);
/* Program the Transmit Control Register */
-
tctl = rd32(E1000_TCTL);
tctl &= ~E1000_TCTL_CT;
tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
@@ -1732,21 +1889,12 @@ static void igb_configure_tx(struct igb_adapter *adapter)
*
* Returns 0 on success, negative on failure
**/
-
int igb_setup_rx_resources(struct igb_adapter *adapter,
struct igb_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size, desc_len;
-#ifdef CONFIG_IGB_LRO
- size = sizeof(struct net_lro_desc) * MAX_LRO_DESCRIPTORS;
- rx_ring->lro_mgr.lro_arr = vmalloc(size);
- if (!rx_ring->lro_mgr.lro_arr)
- goto err;
- memset(rx_ring->lro_mgr.lro_arr, 0, size);
-#endif
-
size = sizeof(struct igb_buffer) * rx_ring->count;
rx_ring->buffer_info = vmalloc(size);
if (!rx_ring->buffer_info)
@@ -1773,10 +1921,6 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
return 0;
err:
-#ifdef CONFIG_IGB_LRO
- vfree(rx_ring->lro_mgr.lro_arr);
- rx_ring->lro_mgr.lro_arr = NULL;
-#endif
vfree(rx_ring->buffer_info);
dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
"the receive descriptor ring\n");
@@ -1825,21 +1969,21 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
- (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
+ (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
/*
* enable stripping of CRC. It's unlikely this will break BMC
* redirection as it did with e1000. Newer features require
* that the HW strips the CRC.
- */
+ */
rctl |= E1000_RCTL_SECRC;
/*
- * disable store bad packets, long packet enable, and clear size bits.
+ * disable store bad packets and clear size bits.
*/
- rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256);
+ rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
- if (adapter->netdev->mtu > ETH_DATA_LEN)
+ /* enable LPE when to prevent packets larger than max_frame_size */
rctl |= E1000_RCTL_LPE;
/* Setup buffer sizes */
@@ -1865,7 +2009,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
*/
/* allocations using alloc_page take too long for regular MTU
* so only enable packet split for jumbo frames */
- if (rctl & E1000_RCTL_LPE) {
+ if (adapter->netdev->mtu > ETH_DATA_LEN) {
adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
srrctl |= adapter->rx_ps_hdr_size <<
E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
@@ -1875,6 +2019,30 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
}
+ /* Attention!!! For SR-IOV PF driver operations you must enable
+ * queue drop for all VF and PF queues to prevent head of line blocking
+ * if an un-trusted VF does not provide descriptors to hardware.
+ */
+ if (adapter->vfs_allocated_count) {
+ u32 vmolr;
+
+ j = adapter->rx_ring[0].reg_idx;
+
+ /* set all queue drop enable bits */
+ wr32(E1000_QDE, ALL_QUEUES);
+ srrctl |= E1000_SRRCTL_DROP_EN;
+
+ /* disable queue 0 to prevent tail write w/o re-config */
+ wr32(E1000_RXDCTL(0), 0);
+
+ vmolr = rd32(E1000_VMOLR(j));
+ if (rctl & E1000_RCTL_LPE)
+ vmolr |= E1000_VMOLR_LPE;
+ if (adapter->num_rx_queues > 0)
+ vmolr |= E1000_VMOLR_RSSE;
+ wr32(E1000_VMOLR(j), vmolr);
+ }
+
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i].reg_idx;
wr32(E1000_SRRCTL(j), srrctl);
@@ -1884,6 +2052,54 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
}
/**
+ * igb_rlpml_set - set maximum receive packet size
+ * @adapter: board private structure
+ *
+ * Configure maximum receivable packet size.
+ **/
+static void igb_rlpml_set(struct igb_adapter *adapter)
+{
+ u32 max_frame_size = adapter->max_frame_size;
+ struct e1000_hw *hw = &adapter->hw;
+ u16 pf_id = adapter->vfs_allocated_count;
+
+ if (adapter->vlgrp)
+ max_frame_size += VLAN_TAG_SIZE;
+
+ /* if vfs are enabled we set RLPML to the largest possible request
+ * size and set the VMOLR RLPML to the size we need */
+ if (pf_id) {
+ igb_set_vf_rlpml(adapter, max_frame_size, pf_id);
+ max_frame_size = MAX_STD_JUMBO_FRAME_SIZE + VLAN_TAG_SIZE;
+ }
+
+ wr32(E1000_RLPML, max_frame_size);
+}
+
+/**
+ * igb_configure_vt_default_pool - Configure VT default pool
+ * @adapter: board private structure
+ *
+ * Configure the default pool
+ **/
+static void igb_configure_vt_default_pool(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u16 pf_id = adapter->vfs_allocated_count;
+ u32 vtctl;
+
+ /* not in sr-iov mode - do nothing */
+ if (!pf_id)
+ return;
+
+ vtctl = rd32(E1000_VT_CTL);
+ vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
+ E1000_VT_CTL_DISABLE_DEF_POOL);
+ vtctl |= pf_id << E1000_VT_CTL_DEFAULT_POOL_SHIFT;
+ wr32(E1000_VT_CTL, vtctl);
+}
+
+/**
* igb_configure_rx - Configure receive Unit after Reset
* @adapter: board private structure
*
@@ -1895,7 +2111,7 @@ static void igb_configure_rx(struct igb_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
u32 rctl, rxcsum;
u32 rxdctl;
- int i, j;
+ int i;
/* disable receives while setting up the descriptors */
rctl = rd32(E1000_RCTL);
@@ -1909,14 +2125,14 @@ static void igb_configure_rx(struct igb_adapter *adapter)
/* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring */
for (i = 0; i < adapter->num_rx_queues; i++) {
- struct igb_ring *ring = &(adapter->rx_ring[i]);
- j = ring->reg_idx;
+ struct igb_ring *ring = &adapter->rx_ring[i];
+ int j = ring->reg_idx;
rdba = ring->dma;
wr32(E1000_RDBAL(j),
- rdba & 0x00000000ffffffffULL);
+ rdba & 0x00000000ffffffffULL);
wr32(E1000_RDBAH(j), rdba >> 32);
wr32(E1000_RDLEN(j),
- ring->count * sizeof(union e1000_adv_rx_desc));
+ ring->count * sizeof(union e1000_adv_rx_desc));
ring->head = E1000_RDH(j);
ring->tail = E1000_RDT(j);
@@ -1930,16 +2146,6 @@ static void igb_configure_rx(struct igb_adapter *adapter)
rxdctl |= IGB_RX_HTHRESH << 8;
rxdctl |= IGB_RX_WTHRESH << 16;
wr32(E1000_RXDCTL(j), rxdctl);
-#ifdef CONFIG_IGB_LRO
- /* Intitial LRO Settings */
- ring->lro_mgr.max_aggr = MAX_LRO_AGGR;
- ring->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;
- ring->lro_mgr.get_skb_header = igb_get_skb_hdr;
- ring->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
- ring->lro_mgr.dev = adapter->netdev;
- ring->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
- ring->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
-#endif
}
if (adapter->num_rx_queues > 1) {
@@ -1964,7 +2170,10 @@ static void igb_configure_rx(struct igb_adapter *adapter)
writel(reta.dword,
hw->hw_addr + E1000_RETA(0) + (j & ~3));
}
- mrqc = E1000_MRQC_ENABLE_RSS_4Q;
+ if (adapter->vfs_allocated_count)
+ mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
+ else
+ mrqc = E1000_MRQC_ENABLE_RSS_4Q;
/* Fill out hash function seeds */
for (j = 0; j < 10; j++)
@@ -1989,27 +2198,23 @@ static void igb_configure_rx(struct igb_adapter *adapter)
rxcsum |= E1000_RXCSUM_PCSD;
wr32(E1000_RXCSUM, rxcsum);
} else {
+ /* 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;
+ if (adapter->rx_csum)
+ rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE;
+ else
+ rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE);
- /* Enable IPv4 payload checksum for UDP fragments
- * Must be used in conjunction with packet-split. */
- if (adapter->rx_ps_hdr_size)
- rxcsum |= E1000_RXCSUM_IPPCSE;
- } else {
- rxcsum &= ~E1000_RXCSUM_TUOFL;
- /* don't need to clear IPPCSE as it defaults to 0 */
- }
wr32(E1000_RXCSUM, rxcsum);
}
- if (adapter->vlgrp)
- wr32(E1000_RLPML,
- adapter->max_frame_size + VLAN_TAG_SIZE);
- else
- wr32(E1000_RLPML, adapter->max_frame_size);
+ /* Set the default pool for the PF's first queue */
+ igb_configure_vt_default_pool(adapter);
+
+ igb_rlpml_set(adapter);
/* Enable Receives */
wr32(E1000_RCTL, rctl);
@@ -2052,14 +2257,10 @@ static void igb_free_all_tx_resources(struct igb_adapter *adapter)
static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
struct igb_buffer *buffer_info)
{
- if (buffer_info->dma) {
- pci_unmap_page(adapter->pdev,
- buffer_info->dma,
- buffer_info->length,
- PCI_DMA_TODEVICE);
- buffer_info->dma = 0;
- }
+ buffer_info->dma = 0;
if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(buffer_info->skb);
buffer_info->skb = NULL;
}
@@ -2128,11 +2329,6 @@ void igb_free_rx_resources(struct igb_ring *rx_ring)
vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
-#ifdef CONFIG_IGB_LRO
- vfree(rx_ring->lro_mgr.lro_arr);
- rx_ring->lro_mgr.lro_arr = NULL;
-#endif
-
pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
rx_ring->desc = NULL;
@@ -2232,15 +2428,18 @@ static void igb_clean_all_rx_rings(struct igb_adapter *adapter)
static int igb_set_mac(struct net_device *netdev, void *p)
{
struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
+ memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
+
+ hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
- adapter->hw.mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+ igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
return 0;
}
@@ -2260,7 +2459,7 @@ static void igb_set_multi(struct net_device *netdev)
struct e1000_hw *hw = &adapter->hw;
struct e1000_mac_info *mac = &hw->mac;
struct dev_mc_list *mc_ptr;
- u8 *mta_list;
+ u8 *mta_list = NULL;
u32 rctl;
int i;
@@ -2281,17 +2480,15 @@ static void igb_set_multi(struct net_device *netdev)
}
wr32(E1000_RCTL, rctl);
- if (!netdev->mc_count) {
- /* nothing to program, so clear mc list */
- igb_update_mc_addr_list_82575(hw, NULL, 0, 1,
- mac->rar_entry_count);
- return;
+ if (netdev->mc_count) {
+ mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+ if (!mta_list) {
+ dev_err(&adapter->pdev->dev,
+ "failed to allocate multicast filter list\n");
+ return;
+ }
}
- mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
- if (!mta_list)
- return;
-
/* The shared function expects a packed array of only addresses. */
mc_ptr = netdev->mc_list;
@@ -2301,8 +2498,13 @@ static void igb_set_multi(struct net_device *netdev)
memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
mc_ptr = mc_ptr->next;
}
- igb_update_mc_addr_list_82575(hw, mta_list, i, 1,
- mac->rar_entry_count);
+ igb_update_mc_addr_list(hw, mta_list, i,
+ adapter->vfs_allocated_count + 1,
+ mac->rar_entry_count);
+
+ igb_set_mc_list_pools(adapter, i, mac->rar_entry_count);
+ igb_restore_vf_multicasts(adapter);
+
kfree(mta_list);
}
@@ -2315,6 +2517,46 @@ static void igb_update_phy_info(unsigned long data)
}
/**
+ * igb_has_link - check shared code for link and determine up/down
+ * @adapter: pointer to driver private info
+ **/
+static bool igb_has_link(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ bool link_active = false;
+ s32 ret_val = 0;
+
+ /* get_link_status is set on LSC (link status) interrupt or
+ * rx sequence error interrupt. get_link_status will stay
+ * false until the e1000_check_for_link establishes link
+ * for copper adapters ONLY
+ */
+ switch (hw->phy.media_type) {
+ case e1000_media_type_copper:
+ if (hw->mac.get_link_status) {
+ ret_val = hw->mac.ops.check_for_link(hw);
+ link_active = !hw->mac.get_link_status;
+ } else {
+ link_active = true;
+ }
+ break;
+ case e1000_media_type_fiber:
+ ret_val = hw->mac.ops.check_for_link(hw);
+ link_active = !!(rd32(E1000_STATUS) & E1000_STATUS_LU);
+ break;
+ case e1000_media_type_internal_serdes:
+ ret_val = hw->mac.ops.check_for_link(hw);
+ link_active = hw->mac.serdes_has_link;
+ break;
+ default:
+ case e1000_media_type_unknown:
+ break;
+ }
+
+ return link_active;
+}
+
+/**
* igb_watchdog - Timer Call-back
* @data: pointer to adapter cast into an unsigned long
**/
@@ -2330,34 +2572,16 @@ static void igb_watchdog_task(struct work_struct *work)
struct igb_adapter *adapter = container_of(work,
struct igb_adapter, watchdog_task);
struct e1000_hw *hw = &adapter->hw;
-
struct net_device *netdev = adapter->netdev;
struct igb_ring *tx_ring = adapter->tx_ring;
- struct e1000_mac_info *mac = &adapter->hw.mac;
u32 link;
u32 eics = 0;
- s32 ret_val;
int i;
- if ((netif_carrier_ok(netdev)) &&
- (rd32(E1000_STATUS) & E1000_STATUS_LU))
+ link = igb_has_link(adapter);
+ if ((netif_carrier_ok(netdev)) && link)
goto link_up;
- ret_val = hw->mac.ops.check_for_link(&adapter->hw);
- if ((ret_val == E1000_ERR_PHY) &&
- (hw->phy.type == e1000_phy_igp_3) &&
- (rd32(E1000_CTRL) &
- E1000_PHY_CTRL_GBE_DISABLE))
- dev_info(&adapter->pdev->dev,
- "Gigabit has been disabled, downgrading speed\n");
-
- if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
- !(rd32(E1000_TXCW) & E1000_TXCW_ANE))
- link = mac->serdes_has_link;
- else
- link = rd32(E1000_STATUS) &
- E1000_STATUS_LU;
-
if (link) {
if (!netif_carrier_ok(netdev)) {
u32 ctrl;
@@ -2396,6 +2620,9 @@ static void igb_watchdog_task(struct work_struct *work)
netif_carrier_on(netdev);
netif_tx_wake_all_queues(netdev);
+ igb_ping_all_vfs(adapter);
+
+ /* link state has changed, schedule phy info update */
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -2409,6 +2636,10 @@ static void igb_watchdog_task(struct work_struct *work)
netdev->name);
netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev);
+
+ igb_ping_all_vfs(adapter);
+
+ /* link state has changed, schedule phy info update */
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -2418,9 +2649,9 @@ static void igb_watchdog_task(struct work_struct *work)
link_up:
igb_update_stats(adapter);
- mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
+ hw->mac.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
adapter->tpt_old = adapter->stats.tpt;
- mac->collision_delta = adapter->stats.colc - adapter->colc_old;
+ hw->mac.collision_delta = adapter->stats.colc - adapter->colc_old;
adapter->colc_old = adapter->stats.colc;
adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
@@ -2431,7 +2662,7 @@ link_up:
igb_update_adaptive(&adapter->hw);
if (!netif_carrier_ok(netdev)) {
- if (IGB_DESC_UNUSED(tx_ring) + 1 < tx_ring->count) {
+ if (igb_desc_unused(tx_ring) + 1 < tx_ring->count) {
/* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going
* to get done, so reset controller to flush Tx.
@@ -2577,7 +2808,7 @@ static unsigned int igb_update_itr(struct igb_adapter *adapter, u16 itr_setting,
if (bytes > 25000) {
if (packets > 35)
retval = low_latency;
- } else if (bytes < 6000) {
+ } else if (bytes < 1500) {
retval = low_latency;
}
break;
@@ -2609,15 +2840,13 @@ static void igb_set_itr(struct igb_adapter *adapter)
adapter->tx_itr,
adapter->tx_ring->total_packets,
adapter->tx_ring->total_bytes);
-
current_itr = max(adapter->rx_itr, adapter->tx_itr);
} else {
current_itr = adapter->rx_itr;
}
/* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (adapter->itr_setting == 3 &&
- current_itr == lowest_latency)
+ if (adapter->itr_setting == 3 && current_itr == lowest_latency)
current_itr = low_latency;
switch (current_itr) {
@@ -2669,6 +2898,7 @@ set_itr_now:
#define IGB_TX_FLAGS_VLAN 0x00000002
#define IGB_TX_FLAGS_TSO 0x00000004
#define IGB_TX_FLAGS_IPV4 0x00000008
+#define IGB_TX_FLAGS_TSTAMP 0x00000010
#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
#define IGB_TX_FLAGS_VLAN_SHIFT 16
@@ -2734,7 +2964,7 @@ static inline int igb_tso_adv(struct igb_adapter *adapter,
mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
- /* Context index must be unique per ring. */
+ /* For 82575, context index must be unique per ring. */
if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
mss_l4len_idx |= tx_ring->queue_index << 4;
@@ -2779,13 +3009,24 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ __be16 protocol;
+
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+ const struct vlan_ethhdr *vhdr =
+ (const struct vlan_ethhdr*)skb->data;
+
+ protocol = vhdr->h_vlan_encapsulated_proto;
+ } else {
+ protocol = skb->protocol;
+ }
+
+ switch (protocol) {
+ case cpu_to_be16(ETH_P_IP):
tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
break;
- case __constant_htons(ETH_P_IPV6):
+ 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;
@@ -2804,6 +3045,8 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
context_desc->mss_l4len_idx =
cpu_to_le32(tx_ring->queue_index << 4);
+ else
+ context_desc->mss_l4len_idx = 0;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
@@ -2816,8 +3059,6 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
return true;
}
-
-
return false;
}
@@ -2832,25 +3073,33 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
unsigned int len = skb_headlen(skb);
unsigned int count = 0, i;
unsigned int f;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+
buffer_info = &tx_ring->buffer_info[i];
BUG_ON(len >= IGB_MAX_DATA_PER_TXD);
buffer_info->length = len;
/* set time_stamp *before* dma to help avoid a possible race */
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = pci_map_single(adapter->pdev, skb->data, len,
- PCI_DMA_TODEVICE);
+ buffer_info->dma = map[count];
count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
struct skb_frag_struct *frag;
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
@@ -2859,19 +3108,10 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
buffer_info->length = len;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = pci_map_page(adapter->pdev,
- frag->page,
- frag->page_offset,
- len,
- PCI_DMA_TODEVICE);
-
+ buffer_info->dma = map[count];
count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
}
- i = ((i == 0) ? tx_ring->count - 1 : i - 1);
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -2894,6 +3134,9 @@ static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
if (tx_flags & IGB_TX_FLAGS_VLAN)
cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
+ if (tx_flags & IGB_TX_FLAGS_TSTAMP)
+ cmd_type_len |= E1000_ADVTXD_MAC_TSTAMP;
+
if (tx_flags & IGB_TX_FLAGS_TSO) {
cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
@@ -2956,7 +3199,7 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
/* We need to check again in a case another CPU has just
* made room available. */
- if (IGB_DESC_UNUSED(tx_ring) < size)
+ if (igb_desc_unused(tx_ring) < size)
return -EBUSY;
/* A reprieve! */
@@ -2968,13 +3211,11 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
static int igb_maybe_stop_tx(struct net_device *netdev,
struct igb_ring *tx_ring, int size)
{
- if (IGB_DESC_UNUSED(tx_ring) >= size)
+ if (igb_desc_unused(tx_ring) >= size)
return 0;
return __igb_maybe_stop_tx(netdev, tx_ring, size);
}
-#define TXD_USE_COUNT(S) (((S) >> (IGB_MAX_TXD_PWR)) + 1)
-
static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
struct net_device *netdev,
struct igb_ring *tx_ring)
@@ -2982,11 +3223,10 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
struct igb_adapter *adapter = netdev_priv(netdev);
unsigned int first;
unsigned int tx_flags = 0;
- unsigned int len;
u8 hdr_len = 0;
+ int count = 0;
int tso = 0;
-
- len = skb_headlen(skb);
+ union skb_shared_tx *shtx;
if (test_bit(__IGB_DOWN, &adapter->state)) {
dev_kfree_skb_any(skb);
@@ -3007,7 +3247,21 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
/* this is a hard error */
return NETDEV_TX_BUSY;
}
- skb_orphan(skb);
+
+ /*
+ * TODO: check that there currently is no other packet with
+ * time stamping in the queue
+ *
+ * When doing time stamping, keep the connection to the socket
+ * a while longer: it is still needed by skb_hwtstamp_tx(),
+ * called either in igb_tx_hwtstamp() or by our caller when
+ * doing software time stamping.
+ */
+ shtx = skb_tx(skb);
+ if (unlikely(shtx->hardware)) {
+ shtx->in_progress = 1;
+ tx_flags |= IGB_TX_FLAGS_TSTAMP;
+ }
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= IGB_TX_FLAGS_VLAN;
@@ -3018,7 +3272,6 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
tx_flags |= IGB_TX_FLAGS_IPV4;
first = tx_ring->next_to_use;
-
tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags,
&hdr_len) : 0;
@@ -3029,18 +3282,27 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
if (tso)
tx_flags |= IGB_TX_FLAGS_TSO;
- else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags))
- if (skb->ip_summed == CHECKSUM_PARTIAL)
- tx_flags |= IGB_TX_FLAGS_CSUM;
-
- igb_tx_queue_adv(adapter, tx_ring, tx_flags,
- igb_tx_map_adv(adapter, tx_ring, skb, first),
- skb->len, hdr_len);
-
- netdev->trans_start = jiffies;
+ else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags) &&
+ (skb->ip_summed == CHECKSUM_PARTIAL))
+ tx_flags |= IGB_TX_FLAGS_CSUM;
- /* Make sure there is space in the ring for the next send. */
- igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
+ /*
+ * count reflects descriptors mapped, if 0 then mapping error
+ * has occured and we need to rewind the descriptor queue
+ */
+ count = igb_tx_map_adv(adapter, tx_ring, skb, first);
+
+ 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 {
+ dev_kfree_skb_any(skb);
+ tx_ring->buffer_info[first].time_stamp = 0;
+ tx_ring->next_to_use = first;
+ }
return NETDEV_TX_OK;
}
@@ -3051,7 +3313,7 @@ static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *netdev)
struct igb_ring *tx_ring;
int r_idx = 0;
- r_idx = skb->queue_mapping & (IGB_MAX_TX_QUEUES - 1);
+ r_idx = skb->queue_mapping & (IGB_ABS_MAX_TX_QUEUES - 1);
tx_ring = adapter->multi_tx_table[r_idx];
/* This goes back to the question of how to logically map a tx queue
@@ -3073,8 +3335,8 @@ static void igb_tx_timeout(struct net_device *netdev)
/* Do the reset outside of interrupt context */
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
- wr32(E1000_EICS, adapter->eims_enable_mask &
- ~(E1000_EIMS_TCP_TIMER | E1000_EIMS_OTHER));
+ wr32(E1000_EICS,
+ (adapter->eims_enable_mask & ~adapter->eims_other));
}
static void igb_reset_task(struct work_struct *work)
@@ -3092,8 +3354,7 @@ static void igb_reset_task(struct work_struct *work)
* Returns the address of the device statistics structure.
* The statistics are actually updated from the timer callback.
**/
-static struct net_device_stats *
-igb_get_stats(struct net_device *netdev)
+static struct net_device_stats *igb_get_stats(struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
@@ -3119,7 +3380,6 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
}
-#define MAX_STD_JUMBO_FRAME_SIZE 9234
if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
return -EINVAL;
@@ -3127,6 +3387,7 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
msleep(1);
+
/* igb_down has a dependency on max_frame_size */
adapter->max_frame_size = max_frame;
if (netif_running(netdev))
@@ -3152,6 +3413,12 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
#else
adapter->rx_buffer_len = PAGE_SIZE / 2;
#endif
+
+ /* if sr-iov is enabled we need to force buffer size to 1K or larger */
+ if (adapter->vfs_allocated_count &&
+ (adapter->rx_buffer_len < IGB_RXBUFFER_1024))
+ adapter->rx_buffer_len = IGB_RXBUFFER_1024;
+
/* adjust allocation if LPE protects us, and we aren't using SBP */
if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
(max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))
@@ -3296,8 +3563,7 @@ void igb_update_stats(struct igb_adapter *adapter)
/* Phy Stats */
if (hw->phy.media_type == e1000_media_type_copper) {
if ((adapter->link_speed == SPEED_1000) &&
- (!igb_read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_tmp))) {
+ (!igb_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
adapter->phy_stats.idle_errors += phy_tmp;
}
@@ -3309,7 +3575,6 @@ void igb_update_stats(struct igb_adapter *adapter)
adapter->stats.mgpdc += rd32(E1000_MGTPDC);
}
-
static irqreturn_t igb_msix_other(int irq, void *data)
{
struct net_device *netdev = data;
@@ -3318,15 +3583,24 @@ static irqreturn_t igb_msix_other(int irq, void *data)
u32 icr = rd32(E1000_ICR);
/* reading ICR causes bit 31 of EICR to be cleared */
- if (!(icr & E1000_ICR_LSC))
- goto no_link_interrupt;
- hw->mac.get_link_status = 1;
- /* guard against interrupt when we're going down */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
-
-no_link_interrupt:
- wr32(E1000_IMS, E1000_IMS_LSC);
+
+ if(icr & E1000_ICR_DOUTSYNC) {
+ /* HW is reporting DMA is out of sync */
+ adapter->stats.doosync++;
+ }
+
+ /* Check for a mailbox event */
+ if (icr & E1000_ICR_VMMB)
+ igb_msg_task(adapter);
+
+ if (icr & E1000_ICR_LSC) {
+ hw->mac.get_link_status = 1;
+ /* guard against interrupt when we're going down */
+ if (!test_bit(__IGB_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+ }
+
+ wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_VMMB);
wr32(E1000_EIMS, adapter->eims_other);
return IRQ_HANDLED;
@@ -3342,6 +3616,7 @@ static irqreturn_t igb_msix_tx(int irq, void *data)
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_tx_dca(tx_ring);
#endif
+
tx_ring->total_bytes = 0;
tx_ring->total_packets = 0;
@@ -3362,13 +3637,11 @@ static void igb_write_itr(struct igb_ring *ring)
if ((ring->adapter->itr_setting & 3) && ring->set_itr) {
switch (hw->mac.type) {
case e1000_82576:
- wr32(ring->itr_register,
- ring->itr_val |
+ wr32(ring->itr_register, ring->itr_val |
0x80000000);
break;
default:
- wr32(ring->itr_register,
- ring->itr_val |
+ wr32(ring->itr_register, ring->itr_val |
(ring->itr_val << 16));
break;
}
@@ -3386,8 +3659,8 @@ static irqreturn_t igb_msix_rx(int irq, void *data)
igb_write_itr(rx_ring);
- if (netif_rx_schedule_prep(&rx_ring->napi))
- __netif_rx_schedule(&rx_ring->napi);
+ if (napi_schedule_prep(&rx_ring->napi))
+ __napi_schedule(&rx_ring->napi);
#ifdef CONFIG_IGB_DCA
if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
@@ -3409,11 +3682,11 @@ static void igb_update_rx_dca(struct igb_ring *rx_ring)
dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
if (hw->mac.type == e1000_82576) {
dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576;
- dca_rxctrl |= dca_get_tag(cpu) <<
+ dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
E1000_DCA_RXCTRL_CPUID_SHIFT;
} else {
dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK;
- dca_rxctrl |= dca_get_tag(cpu);
+ dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
}
dca_rxctrl |= E1000_DCA_RXCTRL_DESC_DCA_EN;
dca_rxctrl |= E1000_DCA_RXCTRL_HEAD_DCA_EN;
@@ -3436,11 +3709,11 @@ static void igb_update_tx_dca(struct igb_ring *tx_ring)
dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
if (hw->mac.type == e1000_82576) {
dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576;
- dca_txctrl |= dca_get_tag(cpu) <<
+ dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
E1000_DCA_TXCTRL_CPUID_SHIFT;
} else {
dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK;
- dca_txctrl |= dca_get_tag(cpu);
+ dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
}
dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN;
wr32(E1000_DCA_TXCTRL(q), dca_txctrl);
@@ -3473,19 +3746,16 @@ static int __igb_notify_dca(struct device *dev, void *data)
struct e1000_hw *hw = &adapter->hw;
unsigned long event = *(unsigned long *)data;
- if (!(adapter->flags & IGB_FLAG_HAS_DCA))
- goto out;
-
switch (event) {
case DCA_PROVIDER_ADD:
/* if already enabled, don't do it again */
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
break;
- adapter->flags |= IGB_FLAG_DCA_ENABLED;
/* Always use CB2 mode, difference is masked
* in the CB driver. */
- wr32(E1000_DCA_CTRL, 2);
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
if (dca_add_requester(dev) == 0) {
+ adapter->flags |= IGB_FLAG_DCA_ENABLED;
dev_info(&adapter->pdev->dev, "DCA enabled\n");
igb_setup_dca(adapter);
break;
@@ -3498,11 +3768,11 @@ static int __igb_notify_dca(struct device *dev, void *data)
dca_remove_requester(dev);
dev_info(&adapter->pdev->dev, "DCA disabled\n");
adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
- wr32(E1000_DCA_CTRL, 1);
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_DISABLE);
}
break;
}
-out:
+
return 0;
}
@@ -3518,6 +3788,322 @@ static int igb_notify_dca(struct notifier_block *nb, unsigned long event,
}
#endif /* CONFIG_IGB_DCA */
+static void igb_ping_all_vfs(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 ping;
+ int i;
+
+ for (i = 0 ; i < adapter->vfs_allocated_count; i++) {
+ ping = E1000_PF_CONTROL_MSG;
+ if (adapter->vf_data[i].clear_to_send)
+ ping |= E1000_VT_MSGTYPE_CTS;
+ igb_write_mbx(hw, &ping, 1, i);
+ }
+}
+
+static int igb_set_vf_multicasts(struct igb_adapter *adapter,
+ u32 *msgbuf, u32 vf)
+{
+ int n = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
+ u16 *hash_list = (u16 *)&msgbuf[1];
+ struct vf_data_storage *vf_data = &adapter->vf_data[vf];
+ int i;
+
+ /* only up to 30 hash values supported */
+ if (n > 30)
+ n = 30;
+
+ /* salt away the number of multi cast addresses assigned
+ * to this VF for later use to restore when the PF multi cast
+ * list changes
+ */
+ vf_data->num_vf_mc_hashes = n;
+
+ /* VFs are limited to using the MTA hash table for their multicast
+ * addresses */
+ for (i = 0; i < n; i++)
+ vf_data->vf_mc_hashes[i] = hash_list[i];;
+
+ /* Flush and reset the mta with the new values */
+ igb_set_multi(adapter->netdev);
+
+ return 0;
+}
+
+static void igb_restore_vf_multicasts(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct vf_data_storage *vf_data;
+ int i, j;
+
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ vf_data = &adapter->vf_data[i];
+ for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
+ igb_mta_set(hw, vf_data->vf_mc_hashes[j]);
+ }
+}
+
+static void igb_clear_vf_vfta(struct igb_adapter *adapter, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 pool_mask, reg, vid;
+ int i;
+
+ pool_mask = 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
+
+ /* Find the vlan filter for this id */
+ for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+ reg = rd32(E1000_VLVF(i));
+
+ /* remove the vf from the pool */
+ reg &= ~pool_mask;
+
+ /* if pool is empty then remove entry from vfta */
+ if (!(reg & E1000_VLVF_POOLSEL_MASK) &&
+ (reg & E1000_VLVF_VLANID_ENABLE)) {
+ reg = 0;
+ vid = reg & E1000_VLVF_VLANID_MASK;
+ igb_vfta_set(hw, vid, false);
+ }
+
+ wr32(E1000_VLVF(i), reg);
+ }
+}
+
+static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 reg, i;
+
+ /* It is an error to call this function when VFs are not enabled */
+ if (!adapter->vfs_allocated_count)
+ return -1;
+
+ /* Find the vlan filter for this id */
+ for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+ reg = rd32(E1000_VLVF(i));
+ if ((reg & E1000_VLVF_VLANID_ENABLE) &&
+ vid == (reg & E1000_VLVF_VLANID_MASK))
+ break;
+ }
+
+ if (add) {
+ if (i == E1000_VLVF_ARRAY_SIZE) {
+ /* Did not find a matching VLAN ID entry that was
+ * enabled. Search for a free filter entry, i.e.
+ * one without the enable bit set
+ */
+ for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+ reg = rd32(E1000_VLVF(i));
+ if (!(reg & E1000_VLVF_VLANID_ENABLE))
+ break;
+ }
+ }
+ if (i < E1000_VLVF_ARRAY_SIZE) {
+ /* Found an enabled/available entry */
+ reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
+
+ /* if !enabled we need to set this up in vfta */
+ if (!(reg & E1000_VLVF_VLANID_ENABLE)) {
+ /* add VID to filter table, if bit already set
+ * PF must have added it outside of table */
+ if (igb_vfta_set(hw, vid, true))
+ reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT +
+ adapter->vfs_allocated_count);
+ reg |= E1000_VLVF_VLANID_ENABLE;
+ }
+ reg &= ~E1000_VLVF_VLANID_MASK;
+ reg |= vid;
+
+ wr32(E1000_VLVF(i), reg);
+ return 0;
+ }
+ } else {
+ if (i < E1000_VLVF_ARRAY_SIZE) {
+ /* remove vf from the pool */
+ reg &= ~(1 << (E1000_VLVF_POOLSEL_SHIFT + vf));
+ /* if pool is empty then remove entry from vfta */
+ if (!(reg & E1000_VLVF_POOLSEL_MASK)) {
+ reg = 0;
+ igb_vfta_set(hw, vid, false);
+ }
+ wr32(E1000_VLVF(i), reg);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
+{
+ int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
+ int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
+
+ return igb_vlvf_set(adapter, vid, add, vf);
+}
+
+static inline void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ /* disable mailbox functionality for vf */
+ adapter->vf_data[vf].clear_to_send = false;
+
+ /* reset offloads to defaults */
+ igb_set_vmolr(hw, vf);
+
+ /* reset vlans for device */
+ igb_clear_vf_vfta(adapter, vf);
+
+ /* reset multicast table array for vf */
+ adapter->vf_data[vf].num_vf_mc_hashes = 0;
+
+ /* Flush and reset the mta with the new values */
+ igb_set_multi(adapter->netdev);
+}
+
+static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
+ u32 reg, msgbuf[3];
+ u8 *addr = (u8 *)(&msgbuf[1]);
+
+ /* process all the same items cleared in a function level reset */
+ igb_vf_reset_event(adapter, vf);
+
+ /* set vf mac address */
+ igb_rar_set(hw, vf_mac, vf + 1);
+ igb_set_rah_pool(hw, vf, vf + 1);
+
+ /* enable transmit and receive for vf */
+ reg = rd32(E1000_VFTE);
+ wr32(E1000_VFTE, reg | (1 << vf));
+ reg = rd32(E1000_VFRE);
+ wr32(E1000_VFRE, reg | (1 << vf));
+
+ /* enable mailbox functionality for vf */
+ adapter->vf_data[vf].clear_to_send = true;
+
+ /* reply to reset with ack and vf mac address */
+ msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK;
+ memcpy(addr, vf_mac, 6);
+ igb_write_mbx(hw, msgbuf, 3, vf);
+}
+
+static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)
+{
+ unsigned char *addr = (char *)&msg[1];
+ int err = -1;
+
+ if (is_valid_ether_addr(addr))
+ err = igb_set_vf_mac(adapter, vf, addr);
+
+ return err;
+
+}
+
+static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 msg = E1000_VT_MSGTYPE_NACK;
+
+ /* if device isn't clear to send it shouldn't be reading either */
+ if (!adapter->vf_data[vf].clear_to_send)
+ igb_write_mbx(hw, &msg, 1, vf);
+}
+
+
+static void igb_msg_task(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 vf;
+
+ for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
+ /* process any reset requests */
+ if (!igb_check_for_rst(hw, vf)) {
+ adapter->vf_data[vf].clear_to_send = false;
+ igb_vf_reset_event(adapter, vf);
+ }
+
+ /* process any messages pending */
+ if (!igb_check_for_msg(hw, vf))
+ igb_rcv_msg_from_vf(adapter, vf);
+
+ /* process any acks */
+ if (!igb_check_for_ack(hw, vf))
+ igb_rcv_ack_from_vf(adapter, vf);
+
+ }
+}
+
+static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
+{
+ u32 mbx_size = E1000_VFMAILBOX_SIZE;
+ u32 msgbuf[mbx_size];
+ struct e1000_hw *hw = &adapter->hw;
+ s32 retval;
+
+ retval = igb_read_mbx(hw, msgbuf, mbx_size, vf);
+
+ if (retval)
+ dev_err(&adapter->pdev->dev,
+ "Error receiving message from VF\n");
+
+ /* this is a message we already processed, do nothing */
+ if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK))
+ return retval;
+
+ /*
+ * until the vf completes a reset it should not be
+ * allowed to start any configuration.
+ */
+
+ if (msgbuf[0] == E1000_VF_RESET) {
+ igb_vf_reset_msg(adapter, vf);
+
+ return retval;
+ }
+
+ if (!adapter->vf_data[vf].clear_to_send) {
+ msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
+ igb_write_mbx(hw, msgbuf, 1, vf);
+ return retval;
+ }
+
+ switch ((msgbuf[0] & 0xFFFF)) {
+ case E1000_VF_SET_MAC_ADDR:
+ retval = igb_set_vf_mac_addr(adapter, msgbuf, vf);
+ break;
+ case E1000_VF_SET_MULTICAST:
+ retval = igb_set_vf_multicasts(adapter, msgbuf, vf);
+ break;
+ case E1000_VF_SET_LPE:
+ retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf);
+ break;
+ case E1000_VF_SET_VLAN:
+ retval = igb_set_vf_vlan(adapter, msgbuf, vf);
+ break;
+ default:
+ dev_err(&adapter->pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]);
+ retval = -1;
+ break;
+ }
+
+ /* notify the VF of the results of what it sent us */
+ if (retval)
+ msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
+ else
+ msgbuf[0] |= E1000_VT_MSGTYPE_ACK;
+
+ msgbuf[0] |= E1000_VT_MSGTYPE_CTS;
+
+ igb_write_mbx(hw, msgbuf, 1, vf);
+
+ return retval;
+}
+
/**
* igb_intr_msi - Interrupt Handler
* @irq: interrupt number
@@ -3533,19 +4119,24 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
igb_write_itr(adapter->rx_ring);
+ if(icr & E1000_ICR_DOUTSYNC) {
+ /* HW is reporting DMA is out of sync */
+ adapter->stats.doosync++;
+ }
+
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
hw->mac.get_link_status = 1;
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- netif_rx_schedule(&adapter->rx_ring[0].napi);
+ napi_schedule(&adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
/**
- * igb_intr - Interrupt Handler
+ * igb_intr - Legacy Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
**/
@@ -3557,7 +4148,6 @@ static irqreturn_t igb_intr(int irq, void *data)
/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
* need for the IMC write */
u32 icr = rd32(E1000_ICR);
- u32 eicr = 0;
if (!icr)
return IRQ_NONE; /* Not our interrupt */
@@ -3568,7 +4158,10 @@ static irqreturn_t igb_intr(int irq, void *data)
if (!(icr & E1000_ICR_INT_ASSERTED))
return IRQ_NONE;
- eicr = rd32(E1000_EICR);
+ if(icr & E1000_ICR_DOUTSYNC) {
+ /* HW is reporting DMA is out of sync */
+ adapter->stats.doosync++;
+ }
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
hw->mac.get_link_status = 1;
@@ -3577,11 +4170,31 @@ static irqreturn_t igb_intr(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- netif_rx_schedule(&adapter->rx_ring[0].napi);
+ napi_schedule(&adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
+static inline void igb_rx_irq_enable(struct igb_ring *rx_ring)
+{
+ struct igb_adapter *adapter = rx_ring->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+
+ if (adapter->itr_setting & 3) {
+ if (adapter->num_rx_queues == 1)
+ igb_set_itr(adapter);
+ else
+ igb_update_ring_itr(rx_ring);
+ }
+
+ if (!test_bit(__IGB_DOWN, &adapter->state)) {
+ if (adapter->msix_entries)
+ wr32(E1000_EIMS, rx_ring->eims_value);
+ else
+ igb_irq_enable(adapter);
+ }
+}
+
/**
* igb_poll - NAPI Rx polling callback
* @napi: napi polling structure
@@ -3590,70 +4203,64 @@ static irqreturn_t igb_intr(int irq, void *data)
static int igb_poll(struct napi_struct *napi, int budget)
{
struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
- struct igb_adapter *adapter = rx_ring->adapter;
- struct net_device *netdev = adapter->netdev;
- int tx_clean_complete, work_done = 0;
+ int work_done = 0;
- /* this poll routine only supports one tx and one rx queue */
#ifdef CONFIG_IGB_DCA
- if (adapter->flags & IGB_FLAG_DCA_ENABLED)
- igb_update_tx_dca(&adapter->tx_ring[0]);
+ if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_rx_dca(rx_ring);
#endif
- tx_clean_complete = igb_clean_tx_irq(&adapter->tx_ring[0]);
+ igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
+ if (rx_ring->buddy) {
#ifdef CONFIG_IGB_DCA
- if (adapter->flags & IGB_FLAG_DCA_ENABLED)
- igb_update_rx_dca(&adapter->rx_ring[0]);
+ if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_tx_dca(rx_ring->buddy);
#endif
- igb_clean_rx_irq_adv(&adapter->rx_ring[0], &work_done, budget);
+ if (!igb_clean_tx_irq(rx_ring->buddy))
+ work_done = budget;
+ }
- /* If no Tx and not enough Rx work done, exit the polling mode */
- if ((tx_clean_complete && (work_done < budget)) ||
- !netif_running(netdev)) {
- if (adapter->itr_setting & 3)
- igb_set_itr(adapter);
- netif_rx_complete(napi);
- if (!test_bit(__IGB_DOWN, &adapter->state))
- igb_irq_enable(adapter);
- return 0;
+ /* If not enough Rx work done, exit the polling mode */
+ if (work_done < budget) {
+ napi_complete(napi);
+ igb_rx_irq_enable(rx_ring);
}
- return 1;
+ return work_done;
}
-static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
+/**
+ * igb_hwtstamp - utility function which checks for TX time stamp
+ * @adapter: board private structure
+ * @skb: packet that was just sent
+ *
+ * If we were asked to do hardware stamping and such a time stamp is
+ * available, then it must have been for this skb here because we only
+ * allow only one such packet into the queue.
+ */
+static void igb_tx_hwtstamp(struct igb_adapter *adapter, struct sk_buff *skb)
{
- struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
- struct igb_adapter *adapter = rx_ring->adapter;
+ union skb_shared_tx *shtx = skb_tx(skb);
struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- int work_done = 0;
-#ifdef CONFIG_IGB_DCA
- if (adapter->flags & IGB_FLAG_DCA_ENABLED)
- igb_update_rx_dca(rx_ring);
-#endif
- igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
-
-
- /* If not enough Rx work done, exit the polling mode */
- if ((work_done == 0) || !netif_running(netdev)) {
- netif_rx_complete(napi);
-
- if (adapter->itr_setting & 3) {
- if (adapter->num_rx_queues == 1)
- igb_set_itr(adapter);
- else
- igb_update_ring_itr(rx_ring);
+ if (unlikely(shtx->hardware)) {
+ u32 valid = rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID;
+ if (valid) {
+ u64 regval = rd32(E1000_TXSTMPL);
+ u64 ns;
+ struct skb_shared_hwtstamps shhwtstamps;
+
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ regval |= (u64)rd32(E1000_TXSTMPH) << 32;
+ ns = timecounter_cyc2time(&adapter->clock,
+ regval);
+ timecompare_update(&adapter->compare, ns);
+ shhwtstamps.hwtstamp = ns_to_ktime(ns);
+ shhwtstamps.syststamp =
+ timecompare_transform(&adapter->compare, ns);
+ skb_tstamp_tx(skb, &shhwtstamps);
}
-
- if (!test_bit(__IGB_DOWN, &adapter->state))
- wr32(E1000_EIMS, rx_ring->eims_value);
-
- return 0;
}
-
- return 1;
}
/**
@@ -3694,6 +4301,8 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
skb->len;
total_packets += segs;
total_bytes += bytecount;
+
+ igb_tx_hwtstamp(adapter, skb);
}
igb_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -3703,7 +4312,6 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
if (i == tx_ring->count)
i = 0;
}
-
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop);
}
@@ -3712,7 +4320,7 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
if (unlikely(count &&
netif_carrier_ok(netdev) &&
- IGB_DESC_UNUSED(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
+ igb_desc_unused(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
*/
@@ -3768,44 +4376,11 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
return (count < tx_ring->count);
}
-#ifdef CONFIG_IGB_LRO
- /**
- * igb_get_skb_hdr - helper function for LRO header processing
- * @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to ip header structure
- * @tcph: pointer to tcp header structure
- * @hdr_flags: pointer to header flags
- * @priv: pointer to the receive descriptor for the current sk_buff
- **/
-static int igb_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
- u64 *hdr_flags, void *priv)
-{
- union e1000_adv_rx_desc *rx_desc = priv;
- u16 pkt_type = rx_desc->wb.lower.lo_dword.pkt_info &
- (E1000_RXDADV_PKTTYPE_IPV4 | E1000_RXDADV_PKTTYPE_TCP);
-
- /* Verify that this is a valid IPv4 TCP packet */
- if (pkt_type != (E1000_RXDADV_PKTTYPE_IPV4 |
- E1000_RXDADV_PKTTYPE_TCP))
- return -1;
-
- /* Set network headers */
- skb_reset_network_header(skb);
- skb_set_transport_header(skb, ip_hdrlen(skb));
- *iphdr = ip_hdr(skb);
- *tcph = tcp_hdr(skb);
- *hdr_flags = LRO_IPV4 | LRO_TCP;
-
- return 0;
-
-}
-#endif /* CONFIG_IGB_LRO */
-
/**
* igb_receive_skb - helper function to handle rx indications
- * @ring: pointer to receive ring receving this packet
+ * @ring: pointer to receive ring receving this packet
* @status: descriptor status field as written by hardware
- * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
+ * @rx_desc: receive descriptor containing vlan and type information.
* @skb: pointer to sk_buff to be indicated to stack
**/
static void igb_receive_skb(struct igb_ring *ring, u8 status,
@@ -3815,31 +4390,23 @@ static void igb_receive_skb(struct igb_ring *ring, u8 status,
struct igb_adapter * adapter = ring->adapter;
bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
-#ifdef CONFIG_IGB_LRO
- if (adapter->netdev->features & NETIF_F_LRO &&
- skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ skb_record_rx_queue(skb, ring->queue_index);
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
if (vlan_extracted)
- lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
- adapter->vlgrp,
- le16_to_cpu(rx_desc->wb.upper.vlan),
- rx_desc);
+ vlan_gro_receive(&ring->napi, adapter->vlgrp,
+ le16_to_cpu(rx_desc->wb.upper.vlan),
+ skb);
else
- lro_receive_skb(&ring->lro_mgr,skb, rx_desc);
- ring->lro_used = 1;
+ napi_gro_receive(&ring->napi, skb);
} else {
-#endif
if (vlan_extracted)
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
le16_to_cpu(rx_desc->wb.upper.vlan));
else
-
netif_receive_skb(skb);
-#ifdef CONFIG_IGB_LRO
}
-#endif
}
-
static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
u32 status_err, struct sk_buff *skb)
{
@@ -3867,17 +4434,19 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
{
struct igb_adapter *adapter = rx_ring->adapter;
struct net_device *netdev = adapter->netdev;
+ struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
union e1000_adv_rx_desc *rx_desc , *next_rxd;
struct igb_buffer *buffer_info , *next_buffer;
struct sk_buff *skb;
- unsigned int i;
- u32 length, hlen, staterr;
bool cleaned = false;
int cleaned_count = 0;
unsigned int total_bytes = 0, total_packets = 0;
+ unsigned int i;
+ u32 length, hlen, staterr;
i = rx_ring->next_to_clean;
+ buffer_info = &rx_ring->buffer_info[i];
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
@@ -3885,25 +4454,22 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
if (*work_done >= budget)
break;
(*work_done)++;
- buffer_info = &rx_ring->buffer_info[i];
- /* HW will not DMA in data larger than the given buffer, even
- * if it parses the (NFS, of course) header to be larger. In
- * that case, it fills the header buffer and spills the rest
- * into the page.
- */
- hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
- E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
- if (hlen > adapter->rx_ps_hdr_size)
- hlen = adapter->rx_ps_hdr_size;
+ skb = buffer_info->skb;
+ prefetch(skb->data - NET_IP_ALIGN);
+ buffer_info->skb = NULL;
+
+ i++;
+ if (i == rx_ring->count)
+ i = 0;
+ next_rxd = E1000_RX_DESC_ADV(*rx_ring, i);
+ prefetch(next_rxd);
+ next_buffer = &rx_ring->buffer_info[i];
length = le16_to_cpu(rx_desc->wb.upper.length);
cleaned = true;
cleaned_count++;
- skb = buffer_info->skb;
- prefetch(skb->data - NET_IP_ALIGN);
- buffer_info->skb = NULL;
if (!adapter->rx_ps_hdr_size) {
pci_unmap_single(pdev, buffer_info->dma,
adapter->rx_buffer_len +
@@ -3913,10 +4479,19 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
goto send_up;
}
+ /* HW will not DMA in data larger than the given buffer, even
+ * if it parses the (NFS, of course) header to be larger. In
+ * that case, it fills the header buffer and spills the rest
+ * into the page.
+ */
+ hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
+ E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
+ if (hlen > adapter->rx_ps_hdr_size)
+ hlen = adapter->rx_ps_hdr_size;
+
if (!skb_shinfo(skb)->nr_frags) {
pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_ps_hdr_size +
- NET_IP_ALIGN,
+ adapter->rx_ps_hdr_size + NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
skb_put(skb, hlen);
}
@@ -3942,13 +4517,6 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
skb->truesize += length;
}
-send_up:
- i++;
- if (i == rx_ring->count)
- i = 0;
- next_rxd = E1000_RX_DESC_ADV(*rx_ring, i);
- prefetch(next_rxd);
- next_buffer = &rx_ring->buffer_info[i];
if (!(staterr & E1000_RXD_STAT_EOP)) {
buffer_info->skb = next_buffer->skb;
@@ -3957,6 +4525,47 @@ send_up:
next_buffer->dma = 0;
goto next_desc;
}
+send_up:
+ /*
+ * If this bit is set, then the RX registers contain
+ * the time stamp. No other packet will be time
+ * stamped until we read these registers, so read the
+ * registers to make them available again. Because
+ * only one packet can be time stamped at a time, we
+ * know that the register values must belong to this
+ * one here and therefore we don't need to compare
+ * any of the additional attributes stored for it.
+ *
+ * If nothing went wrong, then it should have a
+ * skb_shared_tx that we can turn into a
+ * skb_shared_hwtstamps.
+ *
+ * TODO: can time stamping be triggered (thus locking
+ * the registers) without the packet reaching this point
+ * here? In that case RX time stamping would get stuck.
+ *
+ * TODO: in "time stamp all packets" mode this bit is
+ * not set. Need a global flag for this mode and then
+ * always read the registers. Cannot be done without
+ * a race condition.
+ */
+ if (unlikely(staterr & E1000_RXD_STAT_TS)) {
+ u64 regval;
+ u64 ns;
+ struct skb_shared_hwtstamps *shhwtstamps =
+ skb_hwtstamps(skb);
+
+ WARN(!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID),
+ "igb: no RX time stamp available for time stamped packet");
+ regval = rd32(E1000_RXSTMPL);
+ regval |= (u64)rd32(E1000_RXSTMPH) << 32;
+ ns = timecounter_cyc2time(&adapter->clock, regval);
+ timecompare_update(&adapter->compare, ns);
+ memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+ shhwtstamps->syststamp =
+ timecompare_transform(&adapter->compare, ns);
+ }
if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
dev_kfree_skb_irq(skb);
@@ -3984,19 +4593,11 @@ next_desc:
/* use prefetched values */
rx_desc = next_rxd;
buffer_info = next_buffer;
-
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
rx_ring->next_to_clean = i;
- cleaned_count = IGB_DESC_UNUSED(rx_ring);
-
-#ifdef CONFIG_IGB_LRO
- if (rx_ring->lro_used) {
- lro_flush_all(&rx_ring->lro_mgr);
- rx_ring->lro_used = 0;
- }
-#endif
+ cleaned_count = igb_desc_unused(rx_ring);
if (cleaned_count)
igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
@@ -4010,7 +4611,6 @@ next_desc:
return cleaned;
}
-
/**
* igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
* @adapter: address of board private structure
@@ -4025,10 +4625,17 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
struct igb_buffer *buffer_info;
struct sk_buff *skb;
unsigned int i;
+ int bufsz;
i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];
+ if (adapter->rx_ps_hdr_size)
+ bufsz = adapter->rx_ps_hdr_size;
+ else
+ bufsz = adapter->rx_buffer_len;
+ bufsz += NET_IP_ALIGN;
+
while (cleaned_count--) {
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
@@ -4044,23 +4651,14 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
buffer_info->page_offset ^= PAGE_SIZE / 2;
}
buffer_info->page_dma =
- pci_map_page(pdev,
- buffer_info->page,
+ pci_map_page(pdev, buffer_info->page,
buffer_info->page_offset,
PAGE_SIZE / 2,
PCI_DMA_FROMDEVICE);
}
if (!buffer_info->skb) {
- int bufsz;
-
- if (adapter->rx_ps_hdr_size)
- bufsz = adapter->rx_ps_hdr_size;
- else
- bufsz = adapter->rx_buffer_len;
- bufsz += NET_IP_ALIGN;
skb = netdev_alloc_skb(netdev, bufsz);
-
if (!skb) {
adapter->alloc_rx_buff_failed++;
goto no_buffers;
@@ -4076,7 +4674,6 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
buffer_info->dma = pci_map_single(pdev, skb->data,
bufsz,
PCI_DMA_FROMDEVICE);
-
}
/* Refresh the desc even if buffer_addrs didn't change because
* each write-back erases this info. */
@@ -4146,6 +4743,163 @@ static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
/**
+ * igb_hwtstamp_ioctl - control hardware time stamping
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ *
+ * Outgoing time stamping can be enabled and disabled. Play nice and
+ * disable it when requested, although it shouldn't case any overhead
+ * when no packet needs it. At most one packet in the queue may be
+ * marked for time stamping, otherwise it would be impossible to tell
+ * for sure to which packet the hardware time stamp belongs.
+ *
+ * Incoming time stamping has to be configured via the hardware
+ * filters. Not all combinations are supported, in particular event
+ * type has to be specified. Matching the kind of event packet is
+ * not supported, with the exception of "all V2 events regardless of
+ * level 2 or 4".
+ *
+ **/
+static int igb_hwtstamp_ioctl(struct net_device *netdev,
+ struct ifreq *ifr, int cmd)
+{
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct hwtstamp_config config;
+ u32 tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
+ u32 tsync_rx_ctl_bit = E1000_TSYNCRXCTL_ENABLED;
+ u32 tsync_rx_ctl_type = 0;
+ u32 tsync_rx_cfg = 0;
+ int is_l4 = 0;
+ int is_l2 = 0;
+ short port = 319; /* PTP */
+ u32 regval;
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ tsync_tx_ctl_bit = 0;
+ break;
+ case HWTSTAMP_TX_ON:
+ tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ tsync_rx_ctl_bit = 0;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_ALL:
+ /*
+ * register TSYNCRXCFG must be set, therefore it is not
+ * possible to time stamp both Sync and Delay_Req messages
+ * => fall back to time stamping all packets
+ */
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_ALL;
+ config.rx_filter = HWTSTAMP_FILTER_ALL;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
+ is_l4 = 1;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
+ is_l4 = 1;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE;
+ is_l2 = 1;
+ is_l4 = 1;
+ config.rx_filter = HWTSTAMP_FILTER_SOME;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE;
+ is_l2 = 1;
+ is_l4 = 1;
+ config.rx_filter = HWTSTAMP_FILTER_SOME;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_EVENT_V2;
+ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ is_l2 = 1;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ /* enable/disable TX */
+ regval = rd32(E1000_TSYNCTXCTL);
+ regval = (regval & ~E1000_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit;
+ wr32(E1000_TSYNCTXCTL, regval);
+
+ /* enable/disable RX, define which PTP packets are time stamped */
+ regval = rd32(E1000_TSYNCRXCTL);
+ regval = (regval & ~E1000_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit;
+ regval = (regval & ~0xE) | tsync_rx_ctl_type;
+ wr32(E1000_TSYNCRXCTL, regval);
+ wr32(E1000_TSYNCRXCFG, tsync_rx_cfg);
+
+ /*
+ * Ethertype Filter Queue Filter[0][15:0] = 0x88F7
+ * (Ethertype to filter on)
+ * Ethertype Filter Queue Filter[0][26] = 0x1 (Enable filter)
+ * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable Timestamping)
+ */
+ wr32(E1000_ETQF0, is_l2 ? 0x440088f7 : 0);
+
+ /* L4 Queue Filter[0]: only filter by source and destination port */
+ wr32(E1000_SPQF0, htons(port));
+ wr32(E1000_IMIREXT(0), is_l4 ?
+ ((1<<12) | (1<<19) /* bypass size and control flags */) : 0);
+ wr32(E1000_IMIR(0), is_l4 ?
+ (htons(port)
+ | (0<<16) /* immediate interrupt disabled */
+ | 0 /* (1<<17) bit cleared: do not bypass
+ destination port check */)
+ : 0);
+ wr32(E1000_FTQF0, is_l4 ?
+ (0x11 /* UDP */
+ | (1<<15) /* VF not compared */
+ | (1<<27) /* Enable Timestamping */
+ | (7<<28) /* only source port filter enabled,
+ source/target address and protocol
+ masked */)
+ : ((1<<15) | (15<<28) /* all mask bits set = filter not
+ enabled */));
+
+ wrfl();
+
+ adapter->hwtstamp_config = config;
+
+ /* clear TX/RX time stamp registers, just to be sure */
+ regval = rd32(E1000_TXSTMPH);
+ regval = rd32(E1000_RXSTMPH);
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
+/**
* igb_ioctl -
* @netdev:
* @ifreq:
@@ -4158,6 +4912,8 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
case SIOCGMIIREG:
case SIOCSMIIREG:
return igb_mii_ioctl(netdev, ifr, cmd);
+ case SIOCSHWTSTAMP:
+ return igb_hwtstamp_ioctl(netdev, ifr, cmd);
default:
return -EOPNOTSUPP;
}
@@ -4184,8 +4940,6 @@ static void igb_vlan_rx_register(struct net_device *netdev,
rctl &= ~E1000_RCTL_CFIEN;
wr32(E1000_RCTL, rctl);
igb_update_mng_vlan(adapter);
- wr32(E1000_RLPML,
- adapter->max_frame_size + VLAN_TAG_SIZE);
} else {
/* disable VLAN tag insert/strip */
ctrl = rd32(E1000_CTRL);
@@ -4196,10 +4950,10 @@ static void igb_vlan_rx_register(struct net_device *netdev,
igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
}
- wr32(E1000_RLPML,
- adapter->max_frame_size);
}
+ igb_rlpml_set(adapter);
+
if (!test_bit(__IGB_DOWN, &adapter->state))
igb_irq_enable(adapter);
}
@@ -4208,24 +4962,25 @@ static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 vfta, index;
+ int pf_id = adapter->vfs_allocated_count;
- if ((adapter->hw.mng_cookie.status &
+ if ((hw->mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
(vid == adapter->mng_vlan_id))
return;
- /* add VID to filter table */
- index = (vid >> 5) & 0x7F;
- vfta = array_rd32(E1000_VFTA, index);
- vfta |= (1 << (vid & 0x1F));
- igb_write_vfta(&adapter->hw, index, vfta);
+
+ /* add vid to vlvf if sr-iov is enabled,
+ * if that fails add directly to filter table */
+ if (igb_vlvf_set(adapter, vid, true, pf_id))
+ igb_vfta_set(hw, vid, true);
+
}
static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 vfta, index;
+ int pf_id = adapter->vfs_allocated_count;
igb_irq_disable(adapter);
vlan_group_set_device(adapter->vlgrp, vid, NULL);
@@ -4241,11 +4996,10 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
return;
}
- /* remove VID from filter table */
- index = (vid >> 5) & 0x7F;
- vfta = array_rd32(E1000_VFTA, index);
- vfta &= ~(1 << (vid & 0x1F));
- igb_write_vfta(&adapter->hw, index, vfta);
+ /* remove vid from vlvf if sr-iov is enabled,
+ * if not in vlvf remove from vfta */
+ if (igb_vlvf_set(adapter, vid, false, pf_id))
+ igb_vfta_set(hw, vid, false);
}
static void igb_restore_vlan(struct igb_adapter *adapter)
@@ -4302,7 +5056,6 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
return 0;
}
-
static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4394,10 +5147,7 @@ static int igb_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- if (adapter->need_ioport)
- err = pci_enable_device(pdev);
- else
- err = pci_enable_device_mem(pdev);
+ err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
"igb: Cannot enable PCI device from suspend\n");
@@ -4418,6 +5168,11 @@ static int igb_resume(struct pci_dev *pdev)
/* e1000_power_up_phy(adapter); */
igb_reset(adapter);
+
+ /* let the f/w know that the h/w is now under the control of the
+ * driver. */
+ igb_get_hw_control(adapter);
+
wr32(E1000_WUS, ~0);
if (netif_running(netdev)) {
@@ -4428,10 +5183,6 @@ static int igb_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
- /* let the f/w know that the h/w is now under the control of the
- * driver. */
- igb_get_hw_control(adapter);
-
return 0;
}
#endif
@@ -4450,22 +5201,27 @@ static void igb_shutdown(struct pci_dev *pdev)
static void igb_netpoll(struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
int i;
- int work_done = 0;
- igb_irq_disable(adapter);
- adapter->flags |= IGB_FLAG_IN_NETPOLL;
-
- for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_irq(&adapter->tx_ring[i]);
+ if (!adapter->msix_entries) {
+ igb_irq_disable(adapter);
+ napi_schedule(&adapter->rx_ring[0].napi);
+ return;
+ }
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_irq_adv(&adapter->rx_ring[i],
- &work_done,
- adapter->rx_ring[i].napi.weight);
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct igb_ring *tx_ring = &adapter->tx_ring[i];
+ wr32(E1000_EIMC, tx_ring->eims_value);
+ igb_clean_tx_irq(tx_ring);
+ wr32(E1000_EIMS, tx_ring->eims_value);
+ }
- adapter->flags &= ~IGB_FLAG_IN_NETPOLL;
- igb_irq_enable(adapter);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct igb_ring *rx_ring = &adapter->rx_ring[i];
+ wr32(E1000_EIMC, rx_ring->eims_value);
+ napi_schedule(&rx_ring->napi);
+ }
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -4508,12 +5264,7 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
pci_ers_result_t result;
int err;
- if (adapter->need_ioport)
- err = pci_enable_device(pdev);
- else
- err = pci_enable_device_mem(pdev);
-
- if (err) {
+ if (pci_enable_device_mem(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
result = PCI_ERS_RESULT_DISCONNECT;
@@ -4566,4 +5317,172 @@ static void igb_io_resume(struct pci_dev *pdev)
igb_get_hw_control(adapter);
}
+static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn)
+{
+ u32 reg_data;
+
+ reg_data = rd32(E1000_VMOLR(vfn));
+ reg_data |= E1000_VMOLR_BAM | /* Accept broadcast */
+ E1000_VMOLR_ROPE | /* Accept packets matched in UTA */
+ E1000_VMOLR_ROMPE | /* Accept packets matched in MTA */
+ E1000_VMOLR_AUPE | /* Accept untagged packets */
+ E1000_VMOLR_STRVLAN; /* Strip vlan tags */
+ wr32(E1000_VMOLR(vfn), reg_data);
+}
+
+static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
+ int vfn)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 vmolr;
+
+ vmolr = rd32(E1000_VMOLR(vfn));
+ vmolr &= ~E1000_VMOLR_RLPML_MASK;
+ vmolr |= size | E1000_VMOLR_LPE;
+ wr32(E1000_VMOLR(vfn), vmolr);
+
+ return 0;
+}
+
+static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry)
+{
+ u32 reg_data;
+
+ reg_data = rd32(E1000_RAH(entry));
+ reg_data &= ~E1000_RAH_POOL_MASK;
+ reg_data |= E1000_RAH_POOL_1 << pool;;
+ wr32(E1000_RAH(entry), reg_data);
+}
+
+static void igb_set_mc_list_pools(struct igb_adapter *adapter,
+ int entry_count, u16 total_rar_filters)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ int i = adapter->vfs_allocated_count + 1;
+
+ if ((i + entry_count) < total_rar_filters)
+ total_rar_filters = i + entry_count;
+
+ for (; i < total_rar_filters; i++)
+ igb_set_rah_pool(hw, adapter->vfs_allocated_count, i);
+}
+
+static int igb_set_vf_mac(struct igb_adapter *adapter,
+ int vf, unsigned char *mac_addr)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ int rar_entry = vf + 1; /* VF MAC addresses start at entry 1 */
+
+ igb_rar_set(hw, mac_addr, rar_entry);
+
+ memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
+
+ igb_set_rah_pool(hw, vf, rar_entry);
+
+ return 0;
+}
+
+static void igb_vmm_control(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 reg_data;
+
+ if (!adapter->vfs_allocated_count)
+ return;
+
+ /* VF's need PF reset indication before they
+ * can send/receive mail */
+ reg_data = rd32(E1000_CTRL_EXT);
+ reg_data |= E1000_CTRL_EXT_PFRSTD;
+ wr32(E1000_CTRL_EXT, reg_data);
+
+ igb_vmdq_set_loopback_pf(hw, true);
+ igb_vmdq_set_replication_pf(hw, true);
+}
+
+#ifdef CONFIG_PCI_IOV
+static ssize_t igb_show_num_vfs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct igb_adapter *adapter = netdev_priv(to_net_dev(dev));
+
+ return sprintf(buf, "%d\n", adapter->vfs_allocated_count);
+}
+
+static ssize_t igb_set_num_vfs(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct net_device *netdev = to_net_dev(dev);
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+ unsigned int num_vfs, i;
+ unsigned char mac_addr[ETH_ALEN];
+ int err;
+
+ sscanf(buf, "%u", &num_vfs);
+
+ if (num_vfs > 7)
+ num_vfs = 7;
+
+ /* value unchanged do nothing */
+ if (num_vfs == adapter->vfs_allocated_count)
+ return count;
+
+ if (netdev->flags & IFF_UP)
+ igb_close(netdev);
+
+ igb_reset_interrupt_capability(adapter);
+ igb_free_queues(adapter);
+ adapter->tx_ring = NULL;
+ adapter->rx_ring = NULL;
+ adapter->vfs_allocated_count = 0;
+
+ /* reclaim resources allocated to VFs since we are changing count */
+ if (adapter->vf_data) {
+ /* disable iov and allow time for transactions to clear */
+ pci_disable_sriov(pdev);
+ msleep(500);
+
+ kfree(adapter->vf_data);
+ adapter->vf_data = NULL;
+ wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
+ msleep(100);
+ dev_info(&pdev->dev, "IOV Disabled\n");
+ }
+
+ if (num_vfs) {
+ adapter->vf_data = kcalloc(num_vfs,
+ sizeof(struct vf_data_storage),
+ GFP_KERNEL);
+ if (!adapter->vf_data) {
+ dev_err(&pdev->dev, "Could not allocate VF private "
+ "data - IOV enable failed\n");
+ } else {
+ err = pci_enable_sriov(pdev, num_vfs);
+ if (!err) {
+ adapter->vfs_allocated_count = num_vfs;
+ dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs);
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ random_ether_addr(mac_addr);
+ igb_set_vf_mac(adapter, i, mac_addr);
+ }
+ } else {
+ kfree(adapter->vf_data);
+ adapter->vf_data = NULL;
+ }
+ }
+ }
+
+ igb_set_interrupt_capability(adapter);
+ igb_alloc_queues(adapter);
+ igb_reset(adapter);
+
+ if (netdev->flags & IFF_UP)
+ igb_open(netdev);
+
+ return count;
+}
+#endif /* CONFIG_PCI_IOV */
/* igb_main.c */
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 17779f9bffc..ad179558002 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -259,6 +259,20 @@ static void __exit ali_ircc_cleanup(void)
IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __func__);
}
+static const struct net_device_ops ali_ircc_sir_ops = {
+ .ndo_open = ali_ircc_net_open,
+ .ndo_stop = ali_ircc_net_close,
+ .ndo_start_xmit = ali_ircc_sir_hard_xmit,
+ .ndo_do_ioctl = ali_ircc_net_ioctl,
+};
+
+static const struct net_device_ops ali_ircc_fir_ops = {
+ .ndo_open = ali_ircc_net_open,
+ .ndo_stop = ali_ircc_net_close,
+ .ndo_start_xmit = ali_ircc_fir_hard_xmit,
+ .ndo_do_ioctl = ali_ircc_net_ioctl,
+};
+
/*
* Function ali_ircc_open (int i, chipio_t *inf)
*
@@ -361,10 +375,7 @@ static int ali_ircc_open(int i, chipio_t *info)
self->tx_fifo.tail = self->tx_buff.head;
/* Override the network functions we need to use */
- dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
- dev->open = ali_ircc_net_open;
- dev->stop = ali_ircc_net_close;
- dev->do_ioctl = ali_ircc_net_ioctl;
+ dev->netdev_ops = &ali_ircc_sir_ops;
err = register_netdev(dev);
if (err) {
@@ -974,7 +985,7 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud)
ali_ircc_fir_change_speed(self, baud);
/* Install FIR xmit handler*/
- dev->hard_start_xmit = ali_ircc_fir_hard_xmit;
+ dev->netdev_ops = &ali_ircc_fir_ops;
/* Enable Interuupt */
self->ier = IER_EOM; // benjamin 2000/11/20 07:24PM
@@ -988,7 +999,7 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud)
ali_ircc_sir_change_speed(self, baud);
/* Install SIR xmit handler*/
- dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
+ dev->netdev_ops = &ali_ircc_sir_ops;
}
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 3a22dc41b65..006ba23110d 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1401,6 +1401,14 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self)
}
/*------------------------------------------------------------------*/
+static const struct net_device_ops irda_usb_netdev_ops = {
+ .ndo_open = irda_usb_net_open,
+ .ndo_stop = irda_usb_net_close,
+ .ndo_do_ioctl = irda_usb_net_ioctl,
+ .ndo_start_xmit = irda_usb_hard_xmit,
+ .ndo_tx_timeout = irda_usb_net_timeout,
+};
+
/*
* Initialise the network side of the irda-usb instance
* Called when a new USB instance is registered in irda_usb_probe()
@@ -1411,15 +1419,9 @@ static inline int irda_usb_open(struct irda_usb_cb *self)
IRDA_DEBUG(1, "%s()\n", __func__);
- irda_usb_init_qos(self);
+ netdev->netdev_ops = &irda_usb_netdev_ops;
- /* Override the network functions we need to use */
- netdev->hard_start_xmit = irda_usb_hard_xmit;
- netdev->tx_timeout = irda_usb_net_timeout;
- netdev->watchdog_timeo = 250*HZ/1000; /* 250 ms > USB timeout */
- netdev->open = irda_usb_net_open;
- netdev->stop = irda_usb_net_close;
- netdev->do_ioctl = irda_usb_net_ioctl;
+ irda_usb_init_qos(self);
return register_netdev(netdev);
}
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index b4a61717254..9d813bc4502 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -418,6 +418,12 @@ static int kingsun_net_ioctl(struct net_device *netdev, struct ifreq *rq,
return ret;
}
+static const struct net_device_ops kingsun_ops = {
+ .ndo_start_xmit = kingsun_hard_xmit,
+ .ndo_open = kingsun_net_open,
+ .ndo_stop = kingsun_net_close,
+ .ndo_do_ioctl = kingsun_net_ioctl,
+};
/*
* This routine is called by the USB subsystem for each new device
@@ -520,10 +526,7 @@ static int kingsun_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&kingsun->qos);
/* Override the network functions we need to use */
- net->hard_start_xmit = kingsun_hard_xmit;
- net->open = kingsun_net_open;
- net->stop = kingsun_net_close;
- net->do_ioctl = kingsun_net_ioctl;
+ net->netdev_ops = &kingsun_ops;
ret = register_netdev(net);
if (ret != 0)
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c
index 55322fb92cf..b6ffe9715b6 100644
--- a/drivers/net/irda/ks959-sir.c
+++ b/drivers/net/irda/ks959-sir.c
@@ -668,6 +668,12 @@ static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return ret;
}
+static const struct net_device_ops ks959_ops = {
+ .ndo_start_xmit = ks959_hard_xmit,
+ .ndo_open = ks959_net_open,
+ .ndo_stop = ks959_net_close,
+ .ndo_do_ioctl = ks959_net_ioctl,
+};
/*
* This routine is called by the USB subsystem for each new device
* in the system. We need to check if the device is ours, and in
@@ -780,10 +786,7 @@ static int ks959_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&kingsun->qos);
/* Override the network functions we need to use */
- net->hard_start_xmit = ks959_hard_xmit;
- net->open = ks959_net_open;
- net->stop = ks959_net_close;
- net->do_ioctl = ks959_net_ioctl;
+ net->netdev_ops = &ks959_ops;
ret = register_netdev(net);
if (ret != 0)
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c
index 5b327b09acd..64df27f2bfd 100644
--- a/drivers/net/irda/ksdazzle-sir.c
+++ b/drivers/net/irda/ksdazzle-sir.c
@@ -562,6 +562,13 @@ static int ksdazzle_net_ioctl(struct net_device *netdev, struct ifreq *rq,
return ret;
}
+static const struct net_device_ops ksdazzle_ops = {
+ .ndo_start_xmit = ksdazzle_hard_xmit,
+ .ndo_open = ksdazzle_net_open,
+ .ndo_stop = ksdazzle_net_close,
+ .ndo_do_ioctl = ksdazzle_net_ioctl,
+};
+
/*
* This routine is called by the USB subsystem for each new device
* in the system. We need to check if the device is ours, and in
@@ -684,10 +691,7 @@ static int ksdazzle_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&kingsun->qos);
/* Override the network functions we need to use */
- net->hard_start_xmit = ksdazzle_hard_xmit;
- net->open = ksdazzle_net_open;
- net->stop = ksdazzle_net_close;
- net->do_ioctl = ksdazzle_net_ioctl;
+ net->netdev_ops = &ksdazzle_ops;
ret = register_netdev(net);
if (ret != 0)
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 7eafdca19f3..fac504d0cfd 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -585,7 +585,7 @@ static int mcs_speed_change(struct mcs_cb *mcs)
mcs_get_reg(mcs, MCS_RESV_REG, &rval);
} while(cnt++ < 100 && (rval & MCS_IRINTX));
- if(cnt >= 100) {
+ if (cnt > 100) {
IRDA_ERROR("unable to change speed\n");
ret = -EIO;
goto error;
@@ -873,6 +873,13 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
return ret;
}
+static const struct net_device_ops mcs_netdev_ops = {
+ .ndo_open = mcs_net_open,
+ .ndo_stop = mcs_net_close,
+ .ndo_start_xmit = mcs_hard_xmit,
+ .ndo_do_ioctl = mcs_net_ioctl,
+};
+
/*
* This function is called by the USB subsystem for each new device in the
* system. Need to verify the device and if it is, then start handling it.
@@ -919,11 +926,7 @@ static int mcs_probe(struct usb_interface *intf,
/* Speed change work initialisation*/
INIT_WORK(&mcs->work, mcs_speed_work);
- /* Override the network functions we need to use */
- ndev->hard_start_xmit = mcs_hard_xmit;
- ndev->open = mcs_net_open;
- ndev->stop = mcs_net_close;
- ndev->do_ioctl = mcs_net_ioctl;
+ ndev->netdev_ops = &mcs_netdev_ops;
if (!intf->cur_altsetting)
goto error2;
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 61e509cb712..45fd9c1eb34 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -331,6 +331,20 @@ static void __exit nsc_ircc_cleanup(void)
pnp_registered = 0;
}
+static const struct net_device_ops nsc_ircc_sir_ops = {
+ .ndo_open = nsc_ircc_net_open,
+ .ndo_stop = nsc_ircc_net_close,
+ .ndo_start_xmit = nsc_ircc_hard_xmit_sir,
+ .ndo_do_ioctl = nsc_ircc_net_ioctl,
+};
+
+static const struct net_device_ops nsc_ircc_fir_ops = {
+ .ndo_open = nsc_ircc_net_open,
+ .ndo_stop = nsc_ircc_net_close,
+ .ndo_start_xmit = nsc_ircc_hard_xmit_fir,
+ .ndo_do_ioctl = nsc_ircc_net_ioctl,
+};
+
/*
* Function nsc_ircc_open (iobase, irq)
*
@@ -441,10 +455,7 @@ static int __init nsc_ircc_open(chipio_t *info)
self->tx_fifo.tail = self->tx_buff.head;
/* Override the network functions we need to use */
- dev->hard_start_xmit = nsc_ircc_hard_xmit_sir;
- dev->open = nsc_ircc_net_open;
- dev->stop = nsc_ircc_net_close;
- dev->do_ioctl = nsc_ircc_net_ioctl;
+ dev->netdev_ops = &nsc_ircc_sir_ops;
err = register_netdev(dev);
if (err) {
@@ -1320,12 +1331,12 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed)
switch_bank(iobase, BANK0);
if (speed > 115200) {
/* Install FIR xmit handler */
- dev->hard_start_xmit = nsc_ircc_hard_xmit_fir;
+ dev->netdev_ops = &nsc_ircc_fir_ops;
ier = IER_SFIF_IE;
nsc_ircc_dma_receive(self);
} else {
/* Install SIR xmit handler */
- dev->hard_start_xmit = nsc_ircc_hard_xmit_sir;
+ dev->netdev_ops = &nsc_ircc_sir_ops;
ier = IER_RXHDL_IE;
}
/* Set our current interrupt mask */
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 5b5862499de..d940809762e 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -753,7 +753,8 @@ static int sirdev_alloc_buffers(struct sir_dev *dev)
dev->rx_buff.truesize = IRDA_SKB_MAX_MTU;
/* Bootstrap ZeroCopy Rx */
- dev->rx_buff.skb = __dev_alloc_skb(dev->rx_buff.truesize, GFP_KERNEL);
+ dev->rx_buff.skb = __netdev_alloc_skb(dev->netdev, dev->rx_buff.truesize,
+ GFP_KERNEL);
if (dev->rx_buff.skb == NULL)
return -ENOMEM;
skb_reserve(dev->rx_buff.skb, 1);
@@ -779,8 +780,7 @@ static int sirdev_alloc_buffers(struct sir_dev *dev)
static void sirdev_free_buffers(struct sir_dev *dev)
{
- if (dev->rx_buff.skb)
- kfree_skb(dev->rx_buff.skb);
+ kfree_skb(dev->rx_buff.skb);
kfree(dev->tx_buff.head);
dev->rx_buff.head = dev->tx_buff.head = NULL;
dev->rx_buff.skb = NULL;
@@ -865,6 +865,12 @@ out:
return 0;
}
+static const struct net_device_ops sirdev_ops = {
+ .ndo_start_xmit = sirdev_hard_xmit,
+ .ndo_open = sirdev_open,
+ .ndo_stop = sirdev_close,
+ .ndo_do_ioctl = sirdev_ioctl,
+};
/* ----------------------------------------------------------------------------- */
struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *name)
@@ -908,10 +914,7 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n
dev->netdev = ndev;
/* Override the network functions we need to use */
- ndev->hard_start_xmit = sirdev_hard_xmit;
- ndev->open = sirdev_open;
- ndev->stop = sirdev_close;
- ndev->do_ioctl = sirdev_ioctl;
+ ndev->netdev_ops = &sirdev_ops;
if (register_netdev(ndev)) {
IRDA_ERROR("%s(), register_netdev() failed!\n", __func__);
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index dd73cce1099..59d79807b4d 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -486,6 +486,26 @@ static int __init smsc_ircc_init(void)
return ret;
}
+static int smsc_ircc_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct smsc_ircc_cb *self = netdev_priv(dev);
+
+ if (self->io.speed > 115200)
+ return smsc_ircc_hard_xmit_fir(skb, dev);
+ else
+ return smsc_ircc_hard_xmit_sir(skb, dev);
+}
+
+static const struct net_device_ops smsc_ircc_netdev_ops = {
+ .ndo_open = smsc_ircc_net_open,
+ .ndo_stop = smsc_ircc_net_close,
+ .ndo_do_ioctl = smsc_ircc_net_ioctl,
+ .ndo_start_xmit = smsc_ircc_net_xmit,
+#if SMSC_IRCC2_C_NET_TIMEOUT
+ .ndo_tx_timeout = smsc_ircc_timeout,
+#endif
+};
+
/*
* Function smsc_ircc_open (firbase, sirbase, dma, irq)
*
@@ -519,14 +539,10 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
goto err_out1;
}
- dev->hard_start_xmit = smsc_ircc_hard_xmit_sir;
#if SMSC_IRCC2_C_NET_TIMEOUT
- dev->tx_timeout = smsc_ircc_timeout;
dev->watchdog_timeo = HZ * 2; /* Allow enough time for speed change */
#endif
- dev->open = smsc_ircc_net_open;
- dev->stop = smsc_ircc_net_close;
- dev->do_ioctl = smsc_ircc_net_ioctl;
+ dev->netdev_ops = &smsc_ircc_netdev_ops;
self = netdev_priv(dev);
self->netdev = dev;
@@ -995,9 +1011,6 @@ static void smsc_ircc_fir_start(struct smsc_ircc_cb *self)
/* Reset everything */
- /* Install FIR transmit handler */
- dev->hard_start_xmit = smsc_ircc_hard_xmit_fir;
-
/* Clear FIFO */
outb(inb(fir_base + IRCC_LCR_A) | IRCC_LCR_A_FIFO_RESET, fir_base + IRCC_LCR_A);
@@ -1894,7 +1907,6 @@ static void smsc_ircc_sir_start(struct smsc_ircc_cb *self)
IRDA_ASSERT(self != NULL, return;);
dev = self->netdev;
IRDA_ASSERT(dev != NULL, return;);
- dev->hard_start_xmit = &smsc_ircc_hard_xmit_sir;
fir_base = self->io.fir_base;
sir_base = self->io.sir_base;
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 8b1658c6c92..8e5e45caf2f 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -1007,6 +1007,13 @@ static int stir_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return ret;
}
+static const struct net_device_ops stir_netdev_ops = {
+ .ndo_open = stir_net_open,
+ .ndo_stop = stir_net_close,
+ .ndo_start_xmit = stir_hard_xmit,
+ .ndo_do_ioctl = stir_net_ioctl,
+};
+
/*
* This routine is called by the USB subsystem for each new device
* in the system. We need to check if the device is ours, and in
@@ -1054,10 +1061,7 @@ static int stir_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&stir->qos);
/* Override the network functions we need to use */
- net->hard_start_xmit = stir_hard_xmit;
- net->open = stir_net_open;
- net->stop = stir_net_close;
- net->do_ioctl = stir_net_ioctl;
+ net->netdev_ops = &stir_netdev_ops;
ret = register_netdev(net);
if (ret != 0)
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 8b3e545924c..864798502ff 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -310,6 +310,19 @@ static void __exit via_ircc_cleanup(void)
pci_unregister_driver (&via_driver);
}
+static const struct net_device_ops via_ircc_sir_ops = {
+ .ndo_start_xmit = via_ircc_hard_xmit_sir,
+ .ndo_open = via_ircc_net_open,
+ .ndo_stop = via_ircc_net_close,
+ .ndo_do_ioctl = via_ircc_net_ioctl,
+};
+static const struct net_device_ops via_ircc_fir_ops = {
+ .ndo_start_xmit = via_ircc_hard_xmit_fir,
+ .ndo_open = via_ircc_net_open,
+ .ndo_stop = via_ircc_net_close,
+ .ndo_do_ioctl = via_ircc_net_ioctl,
+};
+
/*
* Function via_ircc_open (iobase, irq)
*
@@ -428,10 +441,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
self->tx_fifo.tail = self->tx_buff.head;
/* Override the network functions we need to use */
- dev->hard_start_xmit = via_ircc_hard_xmit_sir;
- dev->open = via_ircc_net_open;
- dev->stop = via_ircc_net_close;
- dev->do_ioctl = via_ircc_net_ioctl;
+ dev->netdev_ops = &via_ircc_sir_ops;
err = register_netdev(dev);
if (err)
@@ -798,11 +808,11 @@ static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 speed)
if (speed > 115200) {
/* Install FIR xmit handler */
- dev->hard_start_xmit = via_ircc_hard_xmit_fir;
+ dev->netdev_ops = &via_ircc_fir_ops;
via_ircc_dma_receive(self);
} else {
/* Install SIR xmit handler */
- dev->hard_start_xmit = via_ircc_hard_xmit_sir;
+ dev->netdev_ops = &via_ircc_sir_ops;
}
netif_wake_queue(dev);
}
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 723c4588c80..1243bc8e003 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -1573,6 +1573,14 @@ static int vlsi_close(struct net_device *ndev)
return 0;
}
+static const struct net_device_ops vlsi_netdev_ops = {
+ .ndo_open = vlsi_open,
+ .ndo_stop = vlsi_close,
+ .ndo_start_xmit = vlsi_hard_start_xmit,
+ .ndo_do_ioctl = vlsi_ioctl,
+ .ndo_tx_timeout = vlsi_tx_timeout,
+};
+
static int vlsi_irda_init(struct net_device *ndev)
{
vlsi_irda_dev_t *idev = netdev_priv(ndev);
@@ -1608,11 +1616,7 @@ static int vlsi_irda_init(struct net_device *ndev)
ndev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA;
ndev->if_port = IF_PORT_UNKNOWN;
- ndev->open = vlsi_open;
- ndev->stop = vlsi_close;
- ndev->hard_start_xmit = vlsi_hard_start_xmit;
- ndev->do_ioctl = vlsi_ioctl;
- ndev->tx_timeout = vlsi_tx_timeout;
+ ndev->netdev_ops = &vlsi_netdev_ops;
ndev->watchdog_timeo = 500*HZ/1000; /* max. allowed turn time for IrLAP */
SET_NETDEV_DEV(ndev, &pdev->dev);
diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
index dc0a2e4d830..d0883835b0c 100644
--- a/drivers/net/irda/w83977af_ir.c
+++ b/drivers/net/irda/w83977af_ir.c
@@ -140,6 +140,13 @@ static void __exit w83977af_cleanup(void)
}
}
+static const struct net_device_ops w83977_netdev_ops = {
+ .ndo_open = w83977af_net_open,
+ .ndo_stop = w83977af_net_close,
+ .ndo_start_xmit = w83977af_hard_xmit,
+ .ndo_do_ioctl = w83977af_net_ioctl,
+};
+
/*
* Function w83977af_open (iobase, irq)
*
@@ -231,11 +238,7 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
self->rx_buff.data = self->rx_buff.head;
self->netdev = dev;
- /* Override the network functions we need to use */
- dev->hard_start_xmit = w83977af_hard_xmit;
- dev->open = w83977af_net_open;
- dev->stop = w83977af_net_close;
- dev->do_ioctl = w83977af_net_ioctl;
+ dev->netdev_ops = &w83977_netdev_ops;
err = register_netdev(dev);
if (err) {
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index eee28d39568..4b0ea66d7a4 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -887,19 +887,13 @@ static void
ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
struct ixgb_buffer *buffer_info)
{
- struct pci_dev *pdev = adapter->pdev;
-
- if (buffer_info->dma)
- pci_unmap_page(pdev, buffer_info->dma, buffer_info->length,
- PCI_DMA_TODEVICE);
-
- /* okay to call kfree_skb here instead of kfree_skb_any because
- * this is never called in interrupt context */
- if (buffer_info->skb)
- dev_kfree_skb(buffer_info->skb);
-
- buffer_info->skb = NULL;
buffer_info->dma = 0;
+ if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
+ dev_kfree_skb_any(buffer_info->skb);
+ buffer_info->skb = NULL;
+ }
buffer_info->time_stamp = 0;
/* these fields must always be initialized in tx
* buffer_info->length = 0;
@@ -1275,17 +1269,23 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
{
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
struct ixgb_buffer *buffer_info;
- int len = skb->len;
+ int len = skb_headlen(skb);
unsigned int offset = 0, size, count = 0, i;
unsigned int mss = skb_shinfo(skb)->gso_size;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
-
- len -= skb->data_len;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+
while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
@@ -1297,7 +1297,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 =
+ buffer_info->dma = map[0] + offset;
pci_map_single(adapter->pdev,
skb->data + offset,
size,
@@ -1307,7 +1307,11 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
len -= size;
offset += size;
count++;
- if (++i == tx_ring->count) i = 0;
+ if (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ }
}
for (f = 0; f < nr_frags; f++) {
@@ -1318,6 +1322,10 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
offset = 0;
while (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
@@ -1329,21 +1337,14 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
- buffer_info->dma =
- pci_map_page(adapter->pdev,
- frag->page,
- frag->page_offset + offset,
- size,
- PCI_DMA_TODEVICE);
+ buffer_info->dma = map[f + 1] + offset;
buffer_info->next_to_watch = 0;
len -= size;
offset += size;
count++;
- if (++i == tx_ring->count) i = 0;
}
}
- i = (i == 0) ? tx_ring->count - 1 : i - 1;
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -1445,6 +1446,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int first;
unsigned int tx_flags = 0;
int vlan_id = 0;
+ int count = 0;
int tso;
if (test_bit(__IXGB_DOWN, &adapter->flags)) {
@@ -1479,13 +1481,19 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
else if (ixgb_tx_csum(adapter, skb))
tx_flags |= IXGB_TX_FLAGS_CSUM;
- ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
- tx_flags);
+ count = ixgb_tx_map(adapter, skb, first);
- netdev->trans_start = jiffies;
+ 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);
- /* Make sure there is space in the ring for the next send. */
- ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
+ } else {
+ dev_kfree_skb_any(skb);
+ adapter->tx_ring.buffer_info[first].time_stamp = 0;
+ adapter->tx_ring.next_to_use = first;
+ }
return NETDEV_TX_OK;
}
@@ -1721,14 +1729,14 @@ ixgb_intr(int irq, void *data)
if (!test_bit(__IXGB_DOWN, &adapter->flags))
mod_timer(&adapter->watchdog_timer, jiffies);
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
/* Disable interrupts and register for poll. The flush
of the posted write is intentionally left out.
*/
IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
}
@@ -1749,7 +1757,7 @@ ixgb_clean(struct napi_struct *napi, int budget)
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
if (!test_bit(__IXGB_DOWN, &adapter->flags))
ixgb_irq_enable(adapter);
}
@@ -1818,7 +1826,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
/* detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = false;
- if (tx_ring->buffer_info[eop].dma &&
+ if (tx_ring->buffer_info[eop].time_stamp &&
time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + HZ)
&& !(IXGB_READ_REG(&adapter->hw, STATUS) &
IXGB_STATUS_TXOFF)) {
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index 6e7ef765bcd..b3f8208ec7b 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -1,7 +1,7 @@
################################################################################
#
# Intel 10 Gigabit PCI Express Linux driver
-# Copyright(c) 1999 - 2007 Intel Corporation.
+# 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,
@@ -33,6 +33,7 @@
obj-$(CONFIG_IXGBE) += ixgbe.o
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
- ixgbe_82598.o ixgbe_phy.o
+ ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o
-ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o ixgbe_dcb_nl.o
+ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
+ ixgbe_dcb_82599.o ixgbe_dcb_nl.o
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index e112008f39c..c26433d1460 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -31,7 +31,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
-#include <linux/inet_lro.h>
#include <linux/aer.h>
#include "ixgbe_type.h"
@@ -72,6 +71,7 @@
#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_MAX_RXBUFFER 16384 /* largest size for a single descriptor */
#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
@@ -88,9 +88,6 @@
#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000
#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
-#define IXGBE_MAX_LRO_DESCRIPTORS 8
-#define IXGBE_MAX_LRO_AGGREGATE 32
-
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct ixgbe_tx_buffer {
@@ -142,21 +139,25 @@ struct ixgbe_ring {
/* cpu for tx queue */
int cpu;
#endif
- struct net_lro_mgr lro_mgr;
- bool lro_used;
struct ixgbe_queue_stats stats;
- u16 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 */
+ 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 rx_buf_len;
};
-#define RING_F_DCB 0
-#define RING_F_VMDQ 1
-#define RING_F_RSS 2
+enum ixgbe_ring_f_enum {
+ RING_F_NONE = 0,
+ RING_F_DCB,
+ RING_F_VMDQ,
+ RING_F_RSS,
+
+ RING_F_ARRAY_SIZE /* must be last in enum set */
+};
+
#define IXGBE_MAX_DCB_INDICES 8
#define IXGBE_MAX_RSS_INDICES 16
#define IXGBE_MAX_VMDQ_INDICES 16
@@ -165,8 +166,8 @@ struct ixgbe_ring_feature {
int mask;
};
-#define MAX_RX_QUEUES 64
-#define MAX_TX_QUEUES 32
+#define MAX_RX_QUEUES 128
+#define MAX_TX_QUEUES 128
#define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \
? 8 : 1)
@@ -188,10 +189,11 @@ struct ixgbe_q_vector {
};
/* Helper macros to switch between ints/sec and what the register uses.
- * And yes, it's the same math going both ways.
+ * And yes, it's the same math going both ways. The lowest value
+ * supported by all of the ixgbe hardware is 8.
*/
#define EITR_INTS_PER_SEC_TO_REG(_eitr) \
- ((_eitr) ? (1000000000 / ((_eitr) * 256)) : 0)
+ ((_eitr) ? (1000000000 / ((_eitr) * 256)) : 8)
#define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG
#define IXGBE_DESC_UNUSED(R) \
@@ -210,9 +212,15 @@ struct ixgbe_q_vector {
#define OTHER_VECTOR 1
#define NON_Q_VECTORS (OTHER_VECTOR)
-#define MAX_MSIX_Q_VECTORS 16
+#define MAX_MSIX_VECTORS_82599 64
+#define MAX_MSIX_Q_VECTORS_82599 64
+#define MAX_MSIX_VECTORS_82598 18
+#define MAX_MSIX_Q_VECTORS_82598 16
+
+#define MAX_MSIX_Q_VECTORS MAX_MSIX_Q_VECTORS_82599
+#define MAX_MSIX_COUNT MAX_MSIX_VECTORS_82599
+
#define MIN_MSIX_Q_VECTORS 2
-#define MAX_MSIX_COUNT (MAX_MSIX_Q_VECTORS + NON_Q_VECTORS)
#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS)
/* board specific private data structure */
@@ -222,7 +230,7 @@ struct ixgbe_adapter {
u16 bd_number;
struct work_struct reset_task;
struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
- char name[MAX_MSIX_COUNT][IFNAMSIZ + 5];
+ char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
struct ixgbe_dcb_config dcb_cfg;
struct ixgbe_dcb_config temp_dcb_cfg;
u8 dcb_set_bitmap;
@@ -247,10 +255,12 @@ struct ixgbe_adapter {
struct ixgbe_ring *rx_ring; /* One per active queue */
int num_rx_queues;
u64 hw_csum_rx_error;
+ u64 hw_rx_no_dma_resources;
u64 hw_csum_rx_good;
u64 non_eop_descs;
int num_msix_vectors;
- struct ixgbe_ring_feature ring_feature[3];
+ int max_msix_q_vectors; /* true count of q_vectors for device */
+ struct ixgbe_ring_feature ring_feature[RING_F_ARRAY_SIZE];
struct msix_entry *msix_entries;
u64 rx_hdr_split;
@@ -274,6 +284,7 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
+#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 14)
#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
@@ -281,7 +292,8 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23)
-#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 24)
+#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 24)
+#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25)
/* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
@@ -301,9 +313,6 @@ struct ixgbe_adapter {
unsigned long state;
u64 tx_busy;
- u64 lro_aggregated;
- u64 lro_flushed;
- u64 lro_no_desc;
unsigned int tx_ring_count;
unsigned int rx_ring_count;
@@ -314,6 +323,10 @@ struct ixgbe_adapter {
struct work_struct watchdog_task;
struct work_struct sfp_task;
struct timer_list sfp_timer;
+ struct work_struct multispeed_fiber_task;
+ struct work_struct sfp_config_module_task;
+ u32 wol;
+ u16 eeprom_version;
};
enum ixbge_state_t {
@@ -325,9 +338,11 @@ enum ixbge_state_t {
enum ixgbe_boards {
board_82598,
+ board_82599,
};
extern struct ixgbe_info ixgbe_82598_info;
+extern struct ixgbe_info ixgbe_82599_info;
#ifdef CONFIG_IXGBE_DCB
extern struct dcbnl_rtnl_ops dcbnl_ops;
extern int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
@@ -352,5 +367,6 @@ 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);
#endif /* _IXGBE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index ad5699d9ab0..ed265a7a898 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -50,6 +50,27 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
u8 *eeprom_data);
/**
+ * ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count
+ * @hw: pointer to hardware structure
+ *
+ * Read PCIe configuration space, and get the MSI-X vector count from
+ * the capabilities table.
+ **/
+static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
+{
+ struct ixgbe_adapter *adapter = hw->back;
+ u16 msix_count;
+ pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82598_CAPS,
+ &msix_count);
+ msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+
+ /* MSI-X count is zero-based in HW, so increment to give proper value */
+ msix_count++;
+
+ return msix_count;
+}
+
+/**
*/
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
@@ -58,6 +79,9 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
s32 ret_val = 0;
u16 list_offset, data_offset;
+ /* Set the bus information prior to PHY identification */
+ mac->ops.get_bus_info(hw);
+
/* Call PHY identify routine to get the phy type */
ixgbe_identify_phy_generic(hw);
@@ -106,6 +130,7 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
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;
@@ -124,18 +149,12 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
bool *autoneg)
{
s32 status = 0;
- s32 autoc_reg;
-
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- if (hw->mac.link_settings_loaded) {
- autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
- autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
- autoc_reg |= hw->mac.link_attach_type;
- autoc_reg |= hw->mac.link_mode_select;
- }
-
- switch (autoc_reg & IXGBE_AUTOC_LMS_MASK) {
+ /*
+ * Determine link capabilities based on the stored value of AUTOC,
+ * which represents EEPROM defaults.
+ */
+ switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = false;
@@ -154,9 +173,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 (autoc_reg & IXGBE_AUTOC_KX4_SUPP)
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (autoc_reg & IXGBE_AUTOC_KX_SUPP)
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = true;
break;
@@ -213,6 +232,10 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
/* Media type for I82598 is based on device ID */
switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598:
+ case IXGBE_DEV_ID_82598_BX:
+ media_type = ixgbe_media_type_backplane;
+ break;
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
case IXGBE_DEV_ID_82598EB_CX4:
@@ -235,104 +258,75 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
}
/**
- * ixgbe_setup_fc_82598 - Configure flow control settings
+ * ixgbe_fc_enable_82598 - Enable flow control
* @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.
+ * Enable flow control according to the current settings.
**/
-static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
{
- u32 frctl_reg;
+ s32 ret_val = 0;
+ u32 fctrl_reg;
u32 rmcs_reg;
+ u32 reg;
- if (packetbuf_num < 0 || packetbuf_num > 7) {
- hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
- " 0-7\n", packetbuf_num);
- }
-
- frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
+ fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
/*
- * 10 gig 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.type == ixgbe_fc_default)
- hw->fc.type = ixgbe_fc_full;
-
- /*
- * We want to save off the original Flow Control configuration just in
- * case we get disconnected and then reconnected into a different hub
- * or switch with different Flow Control capabilities.
- */
- hw->fc.original_type = hw->fc.type;
-
- /*
- * The possible values of the "flow_control" parameter are:
+ * 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)
+ * 1: Rx flow control is enabled (we can receive pause frames,
+ * but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames but
+ * we do not support receiving pause frames).
* 3: Both Rx and Tx flow control (symmetric) are enabled.
* other: Invalid.
*/
- switch (hw->fc.type) {
+ switch (hw->fc.current_mode) {
case ixgbe_fc_none:
+ /* Flow control completely disabled by software override. */
break;
case ixgbe_fc_rx_pause:
/*
- * Rx Flow control is enabled,
- * and Tx Flow control is disabled.
+ * 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.
*/
- frctl_reg |= IXGBE_FCTRL_RFCE;
+ fctrl_reg |= IXGBE_FCTRL_RFCE;
break;
case ixgbe_fc_tx_pause:
/*
- * Tx Flow control is enabled, and Rx Flow control is disabled,
- * by a software over-ride.
+ * Tx Flow control is enabled, and Rx Flow control is
+ * disabled by software override.
*/
rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
break;
case ixgbe_fc_full:
- /*
- * Flow control (both Rx and Tx) is enabled by a software
- * over-ride.
- */
- frctl_reg |= IXGBE_FCTRL_RFCE;
+ /* Flow control (both Rx and Tx) is enabled by SW override. */
+ fctrl_reg |= IXGBE_FCTRL_RFCE;
rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
break;
default:
- /* We should never get here. The value should be 0-3. */
hw_dbg(hw, "Flow control param set incorrectly\n");
+ ret_val = -IXGBE_ERR_CONFIG;
+ goto out;
break;
}
/* Enable 802.3x based flow control settings. */
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
- /*
- * Check for invalid software configuration, zeros are completely
- * invalid for all parameters used past this point, and if we enable
- * flow control with zero water marks, we blast flow control packets.
- */
- if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
- hw_dbg(hw, "Flow control structure initialized incorrectly\n");
- return IXGBE_ERR_INVALID_LINK_SETTINGS;
- }
-
- /*
- * We need to set up the Receive Threshold high and low water
- * marks as well as (optionally) enabling the transmission of
- * XON frames.
- */
- if (hw->fc.type & ixgbe_fc_tx_pause) {
+ /* 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(packetbuf_num),
(hw->fc.low_water | IXGBE_FCRTL_XONE));
@@ -340,14 +334,93 @@ static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
hw->fc.low_water);
}
+
IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
- (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
+ (hw->fc.high_water | IXGBE_FCRTH_FCEN));
}
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
+ /* Configure pause time (2 TCs per register) */
+ reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+ if ((packetbuf_num & 1) == 0)
+ reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
+ else
+ reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+
IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
- return 0;
+out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_setup_fc_82598 - Configure flow control settings
+ * @hw: pointer to hardware structure
+ * @packetbuf_num: packet buffer number (0-7)
+ *
+ * Configures the flow control settings based on SW configuration. This
+ * function is used for 802.3x flow control configuration only.
+ **/
+static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+ s32 ret_val = 0;
+ ixgbe_link_speed speed;
+ bool link_up;
+
+ /* Validate the packetbuf configuration */
+ if (packetbuf_num < 0 || packetbuf_num > 7) {
+ hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
+ " 0-7\n", packetbuf_num);
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * Validate the water mark configuration. Zero water marks are invalid
+ * because it causes the controller to just blast out fc packets.
+ */
+ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+ hw_dbg(hw, "Invalid water mark configuration\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * Validate the requested mode. Strict IEEE mode does not allow
+ * ixgbe_fc_rx_pause because it will cause testing anomalies.
+ */
+ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
+ hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * 10gig parts do not have a word in the EEPROM to determine the
+ * default flow control setting, so we explicitly set it to full.
+ */
+ if (hw->fc.requested_mode == ixgbe_fc_default)
+ hw->fc.requested_mode = ixgbe_fc_full;
+
+ /*
+ * Save off the requested flow control mode for use later. Depending
+ * on the link partner's capabilities, we may or may not use this mode.
+ */
+
+ hw->fc.current_mode = hw->fc.requested_mode;
+
+ /* Decide whether to use autoneg or not. */
+ hw->mac.ops.check_link(hw, &speed, &link_up, false);
+ if (hw->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;
}
/**
@@ -364,27 +437,17 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
u32 i;
s32 status = 0;
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-
- if (hw->mac.link_settings_loaded) {
- autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
- autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
- autoc_reg |= hw->mac.link_attach_type;
- autoc_reg |= hw->mac.link_mode_select;
-
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
- IXGBE_WRITE_FLUSH(hw);
- msleep(50);
- }
-
/* Restart link */
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
/* Only poll for autoneg to complete if specified to do so */
if (hw->phy.autoneg_wait_to_complete) {
- if (hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN ||
- hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
+ if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_AN ||
+ (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
links_reg = 0; /* Just in case Autoneg time = 0 */
for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
@@ -404,7 +467,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
* case we get disconnected and then reconnected into a different hub
* or switch with different Flow Control capabilities.
*/
- hw->fc.original_type = hw->fc.type;
ixgbe_setup_fc_82598(hw, 0);
/* Add delay to filter out noises during initial link setup */
@@ -508,37 +570,43 @@ out:
* Set the link speed in the AUTOC register and restarts link.
**/
static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete)
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete)
{
- s32 status = 0;
+ s32 status = 0;
+ ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+ u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 autoc = curr_autoc;
+ u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
- /* If speed is 10G, then check for CX4 or XAUI. */
- if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
- (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) {
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
- } else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) {
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
- } else if (autoneg) {
- /* BX mode - Autonegotiate 1G */
- if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD))
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN;
- else /* KX/KX4 mode */
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN_1G_AN;
- } else {
+ /* Check to see if speed passed in is supported. */
+ ixgbe_get_link_capabilities_82598(hw, &link_capabilities, &autoneg);
+ speed &= link_capabilities;
+
+ if (speed == IXGBE_LINK_SPEED_UNKNOWN)
status = IXGBE_ERR_LINK_SETUP;
+
+ /* Set KX4/KX support according to speed requested */
+ else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
+ link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
+ autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+ autoc |= IXGBE_AUTOC_KX4_SUPP;
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+ autoc |= IXGBE_AUTOC_KX_SUPP;
+ if (autoc != curr_autoc)
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
}
if (status == 0) {
hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete;
- hw->mac.link_settings_loaded = true;
/*
* Setup and restart the link based on the new values in
* ixgbe_hw This will write the AUTOC register based on the new
* stored values
*/
- ixgbe_setup_mac_link_82598(hw);
+ status = ixgbe_setup_mac_link_82598(hw);
}
return status;
@@ -561,10 +629,6 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
/* Restart autonegotiation on PHY */
status = hw->phy.ops.setup_link(hw);
- /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
- hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
-
/* Set up MAC */
ixgbe_setup_mac_link_82598(hw);
@@ -591,10 +655,6 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
autoneg_wait_to_complete);
- /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
- hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
-
/* Set up MAC */
ixgbe_setup_mac_link_82598(hw);
@@ -694,24 +754,16 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
/*
- * AUTOC register which stores link settings gets cleared
- * and reloaded from EEPROM after reset. We need to restore
- * our stored value from init in case SW changed the attach
- * type or speed. If this is the first time and link settings
- * have not been stored, store default settings from AUTOC.
+ * Store the original AUTOC value if it has not been
+ * stored off yet. Otherwise restore the stored original
+ * AUTOC value since the reset operation sets back to deaults.
*/
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- if (hw->mac.link_settings_loaded) {
- autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE);
- autoc &= ~(IXGBE_AUTOC_LMS_MASK);
- autoc |= hw->mac.link_attach_type;
- autoc |= hw->mac.link_mode_select;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
- } else {
- hw->mac.link_attach_type =
- (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
- hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
- hw->mac.link_settings_loaded = true;
+ if (hw->mac.orig_link_settings_stored == false) {
+ hw->mac.orig_autoc = autoc;
+ hw->mac.orig_link_settings_stored = true;
+ } else if (autoc != hw->mac.orig_autoc) {
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
}
/* Store the permanent mac address */
@@ -997,11 +1049,18 @@ out:
*
* Determines physical layer capabilities of the current configuration.
**/
-static s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
+static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
{
- s32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
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;
@@ -1055,8 +1114,11 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_82598,
.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598,
+ .enable_rx_dma = &ixgbe_enable_rx_dma_generic,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
+ .get_bus_info = &ixgbe_get_bus_info_generic,
+ .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
.read_analog_reg8 = &ixgbe_read_analog_reg8_82598,
.write_analog_reg8 = &ixgbe_write_analog_reg8_82598,
.setup_link = &ixgbe_setup_mac_link_82598,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
new file mode 100644
index 00000000000..beae7e01260
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -0,0 +1,1292 @@
+/*******************************************************************************
+
+ 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 <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+
+#include "ixgbe.h"
+#include "ixgbe_phy.h"
+
+#define IXGBE_82599_MAX_TX_QUEUES 128
+#define IXGBE_82599_MAX_RX_QUEUES 128
+#define IXGBE_82599_RAR_ENTRIES 128
+#define IXGBE_82599_MC_TBL_SIZE 128
+#define IXGBE_82599_VFT_TBL_SIZE 128
+
+s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg);
+enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete);
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw);
+s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *link_up, bool link_up_wait_to_complete);
+s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete);
+static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg);
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw);
+static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete);
+s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
+s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
+s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
+s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan,
+ u32 vind, bool vlan_on);
+s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw);
+s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index);
+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);
+
+void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+ if (hw->phy.multispeed_fiber) {
+ /* Set up dual speed SFP+ support */
+ mac->ops.setup_link =
+ &ixgbe_setup_mac_link_multispeed_fiber;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_mac_link_speed_multispeed_fiber;
+ } else {
+ mac->ops.setup_link =
+ &ixgbe_setup_mac_link_82599;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_mac_link_speed_82599;
+ }
+}
+
+s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
+{
+ s32 ret_val = 0;
+ u16 list_offset, data_offset, data_value;
+
+ if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
+ ixgbe_init_mac_link_ops_82599(hw);
+ ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
+ &data_offset);
+
+ if (ret_val != 0)
+ 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);
+ }
+
+setup_sfp_out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_get_pcie_msix_count_82599 - Gets MSI-X vector count
+ * @hw: pointer to hardware structure
+ *
+ * Read PCIe configuration space, and get the MSI-X vector count from
+ * the capabilities table.
+ **/
+u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
+{
+ struct ixgbe_adapter *adapter = hw->back;
+ u16 msix_count;
+ pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82599_CAPS,
+ &msix_count);
+ msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+
+ /* MSI-X count is zero-based in HW, so increment to give proper value */
+ msix_count++;
+
+ return msix_count;
+}
+
+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);
+
+ /* Call PHY identify routine to get the Cu or SFI phy type */
+ ret_val = phy->ops.identify(hw);
+
+ if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto get_invariants_out;
+
+ ixgbe_init_mac_link_ops_82599(hw);
+
+ /* Setup SFP module if there is one present. */
+ ret_val = mac->ops.setup_sfp(hw);
+
+ /* If copper media, overwrite with copper function pointers */
+ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+ mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_copper_link_speed_82599;
+ mac->ops.get_link_capabilities =
+ &ixgbe_get_copper_link_capabilities_82599;
+ }
+
+ /* PHY Init */
+ 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;
+ 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;
+}
+
+/**
+ * ixgbe_get_link_capabilities_82599 - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @negotiation: true when autoneg or autotry is enabled
+ *
+ * Determines the link capabilities by reading the AUTOC register.
+ **/
+s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *negotiation)
+{
+ s32 status = 0;
+
+ switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+ case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = false;
+ break;
+
+ case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+ *speed = IXGBE_LINK_SPEED_10GB_FULL;
+ *negotiation = false;
+ break;
+
+ case IXGBE_AUTOC_LMS_1G_AN:
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = true;
+ break;
+
+ case IXGBE_AUTOC_LMS_10G_SERIAL:
+ *speed = IXGBE_LINK_SPEED_10GB_FULL;
+ *negotiation = false;
+ break;
+
+ 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)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (hw->mac.orig_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)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ *speed |= IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = true;
+ break;
+
+ case IXGBE_AUTOC_LMS_SGMII_1G_100M:
+ *speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
+ *negotiation = false;
+ break;
+
+ default:
+ status = IXGBE_ERR_LINK_SETUP;
+ goto out;
+ break;
+ }
+
+ if (hw->phy.multispeed_fiber) {
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL |
+ IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = true;
+ }
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_get_copper_link_capabilities_82599 - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @autoneg: boolean auto-negotiation value
+ *
+ * Determines the link capabilities by reading the AUTOC register.
+ **/
+static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
+{
+ s32 status = IXGBE_ERR_LINK_SETUP;
+ u16 speed_ability;
+
+ *speed = 0;
+ *autoneg = true;
+
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &speed_ability);
+
+ if (status == 0) {
+ if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+ *speed |= IXGBE_LINK_SPEED_1GB_FULL;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_get_media_type_82599 - Get media type
+ * @hw: pointer to hardware structure
+ *
+ * Returns the media type (fiber, copper, backplane)
+ **/
+enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
+{
+ enum ixgbe_media_type media_type;
+
+ /* Detect if there is a copper PHY attached. */
+ if (hw->phy.type == ixgbe_phy_cu_unknown ||
+ hw->phy.type == ixgbe_phy_tn) {
+ media_type = ixgbe_media_type_copper;
+ goto out;
+ }
+
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82599:
+ case IXGBE_DEV_ID_82599_KX4:
+ /* Default device ID is mezzanine card KX/KX4 */
+ media_type = ixgbe_media_type_backplane;
+ break;
+ case IXGBE_DEV_ID_82599_SFP:
+ media_type = ixgbe_media_type_fiber;
+ break;
+ default:
+ media_type = ixgbe_media_type_unknown;
+ break;
+ }
+out:
+ return media_type;
+}
+
+/**
+ * ixgbe_setup_mac_link_82599 - Setup MAC link settings
+ * @hw: pointer to hardware structure
+ *
+ * Configures link settings based on values in the ixgbe_hw struct.
+ * Restarts the link. Performs autonegotiation if needed.
+ **/
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
+{
+ u32 autoc_reg;
+ u32 links_reg;
+ u32 i;
+ s32 status = 0;
+
+ /* Restart link */
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+ /* Only poll for autoneg to complete if specified to do so */
+ if (hw->phy.autoneg_wait_to_complete) {
+ if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_KX_KR ||
+ (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+ (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+ links_reg = 0; /* Just in case Autoneg time = 0 */
+ for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
+ links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ if (links_reg & IXGBE_LINKS_KX_AN_COMP)
+ break;
+ msleep(100);
+ }
+ if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
+ status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
+ hw_dbg(hw, "Autoneg did not complete.\n");
+ }
+ }
+ }
+
+ /* Set up flow control */
+ status = ixgbe_setup_fc_generic(hw, 0);
+
+ /* Add delay to filter out noises during initial link setup */
+ msleep(50);
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_mac_link_multispeed_fiber - Setup MAC link settings
+ * @hw: pointer to hardware structure
+ *
+ * Configures link settings based on values in the ixgbe_hw struct.
+ * Restarts the link for multi-speed fiber at 1G speed, if link
+ * fails at 10G.
+ * Performs autonegotiation if needed.
+ **/
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_82599_AUTONEG;
+ status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw, link_speed,
+ true, true);
+ return status;
+}
+
+/**
+ * ixgbe_setup_mac_link_speed_multispeed_fiber - Set MAC link speed
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ * Set the link speed in the AUTOC register and restarts link.
+ **/
+s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete)
+{
+ s32 status = 0;
+ ixgbe_link_speed phy_link_speed;
+ ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
+ u32 speedcnt = 0;
+ u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+ bool link_up = false;
+ bool negotiation;
+
+ /* Mask off requested but non-supported speeds */
+ hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
+ speed &= phy_link_speed;
+
+ /*
+ * Try each speed one by one, highest priority first. We do this in
+ * software because 10gb fiber doesn't support speed autonegotiation.
+ */
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
+ speedcnt++;
+ highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+
+ /* Set hardware SDP's */
+ esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+
+ ixgbe_setup_mac_link_speed_82599(hw,
+ IXGBE_LINK_SPEED_10GB_FULL,
+ autoneg,
+ autoneg_wait_to_complete);
+
+ msleep(50);
+
+ /* 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) {
+ speedcnt++;
+ if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
+ highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
+
+ /* Set hardware SDP's */
+ 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);
+
+ msleep(50);
+
+ /* If we have link, just jump out */
+ hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+ if (link_up)
+ goto out;
+ }
+
+ /*
+ * We didn't get link. Configure back to the highest speed we tried,
+ * (if there was more than one). We call ourselves back with just the
+ * single highest speed that the user requested.
+ */
+ if (speedcnt > 1)
+ status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw,
+ highest_link_speed,
+ autoneg,
+ autoneg_wait_to_complete);
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_check_mac_link_82599 - Determine link and speed status
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @link_up: true when link is up
+ * @link_up_wait_to_complete: bool used to wait for link up or not
+ *
+ * Reads the links register to determine if link is up and the current speed
+ **/
+s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
+ bool *link_up, bool link_up_wait_to_complete)
+{
+ u32 links_reg;
+ u32 i;
+
+ links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ if (link_up_wait_to_complete) {
+ for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
+ if (links_reg & IXGBE_LINKS_UP) {
+ *link_up = true;
+ break;
+ } else {
+ *link_up = false;
+ }
+ msleep(100);
+ links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ }
+ } else {
+ if (links_reg & IXGBE_LINKS_UP)
+ *link_up = true;
+ else
+ *link_up = false;
+ }
+
+ if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
+ IXGBE_LINKS_SPEED_10G_82599)
+ *speed = IXGBE_LINK_SPEED_10GB_FULL;
+ else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
+ IXGBE_LINKS_SPEED_1G_82599)
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ else
+ *speed = IXGBE_LINK_SPEED_100_FULL;
+
+
+ return 0;
+}
+
+/**
+ * ixgbe_setup_mac_link_speed_82599 - Set MAC link speed
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ * Set the link speed in the AUTOC register and restarts link.
+ **/
+s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete)
+{
+ s32 status = 0;
+ u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ 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;
+ u32 links_reg;
+ u32 i;
+ ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+
+ /* Check to see if speed passed in is supported. */
+ hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
+ speed &= link_capabilities;
+
+ 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) {
+ /* 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)
+ autoc |= IXGBE_AUTOC_KX4_SUPP;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ autoc |= IXGBE_AUTOC_KR_SUPP;
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+ autoc |= IXGBE_AUTOC_KX_SUPP;
+ } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) &&
+ (link_mode == IXGBE_AUTOC_LMS_1G_LINK_NO_AN ||
+ link_mode == IXGBE_AUTOC_LMS_1G_AN)) {
+ /* Switch from 1G SFI to 10G SFI if requested */
+ if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
+ (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)) {
+ autoc &= ~IXGBE_AUTOC_LMS_MASK;
+ autoc |= IXGBE_AUTOC_LMS_10G_SERIAL;
+ }
+ } else if ((pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) &&
+ (link_mode == IXGBE_AUTOC_LMS_10G_SERIAL)) {
+ /* Switch from 10G SFI to 1G SFI if requested */
+ if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
+ (pma_pmd_1g == IXGBE_AUTOC_1G_SFI)) {
+ autoc &= ~IXGBE_AUTOC_LMS_MASK;
+ if (autoneg)
+ autoc |= IXGBE_AUTOC_LMS_1G_AN;
+ else
+ autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
+ }
+ }
+
+ if (status == 0) {
+ /* Restart link */
+ autoc |= IXGBE_AUTOC_AN_RESTART;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+
+ /* Only poll for autoneg to complete if specified to do so */
+ if (autoneg_wait_to_complete) {
+ 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) {
+ links_reg = 0; /*Just in case Autoneg time=0*/
+ for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
+ links_reg =
+ IXGBE_READ_REG(hw, IXGBE_LINKS);
+ if (links_reg & IXGBE_LINKS_KX_AN_COMP)
+ break;
+ msleep(100);
+ }
+ if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
+ status =
+ IXGBE_ERR_AUTONEG_NOT_COMPLETE;
+ hw_dbg(hw, "Autoneg did not "
+ "complete.\n");
+ }
+ }
+ }
+
+ /* Set up flow control */
+ status = ixgbe_setup_fc_generic(hw, 0);
+
+ /* Add delay to filter out noises during initial link setup */
+ msleep(50);
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_copper_link_82599 - Setup copper link settings
+ * @hw: pointer to hardware structure
+ *
+ * Restarts the link on PHY and then MAC. Performs autonegotiation if needed.
+ **/
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw)
+{
+ s32 status;
+
+ /* Restart autonegotiation on PHY */
+ status = hw->phy.ops.setup_link(hw);
+
+ /* Set up MAC */
+ ixgbe_setup_mac_link_82599(hw);
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_copper_link_speed_82599 - Set the PHY autoneg advertised field
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true if waiting is needed to complete
+ *
+ * Restarts link on PHY and MAC based on settings passed in.
+ **/
+static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete)
+{
+ s32 status;
+
+ /* Setup the PHY according to input speed */
+ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ autoneg_wait_to_complete);
+ /* Set up MAC */
+ ixgbe_setup_mac_link_82599(hw);
+
+ return status;
+}
+
+/**
+ * ixgbe_reset_hw_82599 - Perform hardware reset
+ * @hw: pointer to hardware structure
+ *
+ * Resets the hardware by resetting the transmit and receive units, masks
+ * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
+ * reset.
+ **/
+s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ u32 ctrl, ctrl_ext;
+ u32 i;
+ u32 autoc;
+ u32 autoc2;
+
+ /* Call adapter stop to disable tx/rx and clear interrupts */
+ hw->mac.ops.stop_adapter(hw);
+
+ /* Reset PHY */
+ 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_ERR_MASTER_REQUESTS_PENDING;
+ hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+ }
+
+ /*
+ * Issue global reset to the MAC. This needs to be a SW reset.
+ * If link reset is used, it might reset the MAC when mng is using it
+ */
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* Poll for reset bit to self-clear indicating reset is complete */
+ for (i = 0; i < 10; i++) {
+ udelay(1);
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ if (!(ctrl & IXGBE_CTRL_RST))
+ break;
+ }
+ if (ctrl & IXGBE_CTRL_RST) {
+ status = IXGBE_ERR_RESET_FAILED;
+ hw_dbg(hw, "Reset polling failed to complete.\n");
+ }
+ /* Clear PF Reset Done bit so PF/VF Mail Ops can work */
+ ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
+ ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+
+ msleep(50);
+
+
+
+ /*
+ * Store the original AUTOC/AUTOC2 values if they have not been
+ * stored off yet. Otherwise restore the stored original
+ * values since the reset operation sets back to defaults.
+ */
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ if (hw->mac.orig_link_settings_stored == false) {
+ hw->mac.orig_autoc = autoc;
+ hw->mac.orig_autoc2 = autoc2;
+ hw->mac.orig_link_settings_stored = true;
+ } else {
+ if (autoc != hw->mac.orig_autoc)
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
+ IXGBE_AUTOC_AN_RESTART));
+
+ if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
+ (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
+ autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
+ autoc2 |= (hw->mac.orig_autoc2 &
+ IXGBE_AUTOC2_UPPER_MASK);
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
+ }
+ }
+
+ /* Store the permanent mac address */
+ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+
+ return status;
+}
+
+/**
+ * ixgbe_clear_vmdq_82599 - Disassociate a VMDq pool index from a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to disassociate
+ * @vmdq: VMDq pool index to remove from the rar
+ **/
+s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+ u32 mpsar_lo, mpsar_hi;
+ u32 rar_entries = hw->mac.num_rar_entries;
+
+ if (rar < rar_entries) {
+ mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
+ mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
+
+ if (!mpsar_lo && !mpsar_hi)
+ goto done;
+
+ if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
+ if (mpsar_lo) {
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
+ mpsar_lo = 0;
+ }
+ if (mpsar_hi) {
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
+ mpsar_hi = 0;
+ }
+ } else if (vmdq < 32) {
+ mpsar_lo &= ~(1 << vmdq);
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
+ } else {
+ mpsar_hi &= ~(1 << (vmdq - 32));
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
+ }
+
+ /* was that the last pool using this rar? */
+ if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
+ hw->mac.ops.clear_rar(hw, rar);
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+ }
+
+done:
+ return 0;
+}
+
+/**
+ * ixgbe_set_vmdq_82599 - Associate a VMDq pool index with a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to associate with a VMDq index
+ * @vmdq: VMDq pool index
+ **/
+s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+ u32 mpsar;
+ u32 rar_entries = hw->mac.num_rar_entries;
+
+ if (rar < rar_entries) {
+ if (vmdq < 32) {
+ mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
+ mpsar |= 1 << vmdq;
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
+ } else {
+ mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
+ mpsar |= 1 << (vmdq - 32);
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
+ }
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+ }
+ return 0;
+}
+
+/**
+ * ixgbe_set_vfta_82599 - Set VLAN filter table
+ * @hw: pointer to hardware structure
+ * @vlan: VLAN id to write to VLAN filter
+ * @vind: VMDq output index that maps queue to VLAN id in VFVFB
+ * @vlan_on: boolean flag to turn on/off VLAN in VFVF
+ *
+ * Turn on/off specified VLAN in the VLAN filter table.
+ **/
+s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+ bool vlan_on)
+{
+ u32 regindex;
+ u32 bitindex;
+ u32 bits;
+ u32 first_empty_slot;
+
+ if (vlan > 4095)
+ return IXGBE_ERR_PARAM;
+
+ /*
+ * this is a 2 part operation - first the VFTA, then the
+ * VLVF and VLVFB if vind is set
+ */
+
+ /* Part 1
+ * The VFTA is a bitstring made up of 128 32-bit registers
+ * that enable the particular VLAN id, much like the MTA:
+ * bits[11-5]: which register
+ * bits[4-0]: which bit in the register
+ */
+ regindex = (vlan >> 5) & 0x7F;
+ bitindex = vlan & 0x1F;
+ bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+ if (vlan_on)
+ bits |= (1 << bitindex);
+ else
+ bits &= ~(1 << bitindex);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
+
+
+ /* Part 2
+ * If the vind is set
+ * Either vlan_on
+ * make sure the vlan is in VLVF
+ * set the vind bit in the matching VLVFB
+ * Or !vlan_on
+ * clear the pool bit and possibly the vind
+ */
+ if (vind) {
+ /* find the vlanid or the first empty slot */
+ first_empty_slot = 0;
+
+ for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+ bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
+ if (!bits && !first_empty_slot)
+ first_empty_slot = regindex;
+ else if ((bits & 0x0FFF) == vlan)
+ break;
+ }
+
+ if (regindex >= IXGBE_VLVF_ENTRIES) {
+ if (first_empty_slot)
+ regindex = first_empty_slot;
+ else {
+ hw_dbg(hw, "No space in VLVF.\n");
+ goto out;
+ }
+ }
+
+ if (vlan_on) {
+ /* set the pool bit */
+ if (vind < 32) {
+ bits = IXGBE_READ_REG(hw,
+ IXGBE_VLVFB(regindex * 2));
+ bits |= (1 << vind);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_VLVFB(regindex * 2), bits);
+ } else {
+ bits = IXGBE_READ_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1));
+ bits |= (1 << vind);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1), bits);
+ }
+ } else {
+ /* clear the pool bit */
+ if (vind < 32) {
+ bits = IXGBE_READ_REG(hw,
+ IXGBE_VLVFB(regindex * 2));
+ bits &= ~(1 << vind);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_VLVFB(regindex * 2), bits);
+ bits |= IXGBE_READ_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1));
+ } else {
+ bits = IXGBE_READ_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1));
+ bits &= ~(1 << vind);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1), bits);
+ bits |= IXGBE_READ_REG(hw,
+ IXGBE_VLVFB(regindex * 2));
+ }
+ }
+
+ if (bits)
+ IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex),
+ (IXGBE_VLVF_VIEN | vlan));
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0);
+ }
+
+out:
+ return 0;
+}
+
+/**
+ * ixgbe_clear_vfta_82599 - Clear VLAN filter table
+ * @hw: pointer to hardware structure
+ *
+ * Clears the VLAN filer table, and the VMDq index associated with the filter
+ **/
+s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw)
+{
+ u32 offset;
+
+ for (offset = 0; offset < hw->mac.vft_size; offset++)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+
+ for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
+ IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0);
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_start_82599 - Blink LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to blink
+ **/
+s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index)
+{
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+ led_reg &= ~IXGBE_LED_MODE_MASK(index);
+ led_reg |= IXGBE_LED_BLINK(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_stop_82599 - Stop blinking LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to stop blinking
+ **/
+s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index)
+{
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+ led_reg &= ~IXGBE_LED_MODE_MASK(index);
+ led_reg &= ~IXGBE_LED_BLINK(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array
+ * @hw: pointer to hardware structure
+ **/
+s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw)
+{
+ int i;
+ hw_dbg(hw, " Clearing UTA\n");
+
+ for (i = 0; i < 128; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0);
+
+ return 0;
+}
+
+/**
+ * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
+ * @hw: pointer to hardware structure
+ * @reg: analog register to read
+ * @val: read value
+ *
+ * Performs read operation to Omer analog register specified.
+ **/
+s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
+{
+ u32 core_ctl;
+
+ IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD |
+ (reg << 8));
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(10);
+ core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL);
+ *val = (u8)core_ctl;
+
+ return 0;
+}
+
+/**
+ * ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
+ * @hw: pointer to hardware structure
+ * @reg: atlas register to write
+ * @val: value to write
+ *
+ * Performs write operation to Omer analog register specified.
+ **/
+s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
+{
+ u32 core_ctl;
+
+ core_ctl = (reg << 8) | val;
+ IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(10);
+
+ return 0;
+}
+
+/**
+ * ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
+ * @hw: pointer to hardware structure
+ *
+ * Starts the hardware using the generic start_hw function.
+ * Then performs device-specific:
+ * Clears the rate limiter registers.
+ **/
+s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
+{
+ u32 q_num;
+
+ ixgbe_start_hw_generic(hw);
+
+ /* Clear the rate limiters */
+ for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
+ IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
+ }
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_identify_phy_82599 - Get physical layer module
+ * @hw: pointer to hardware structure
+ *
+ * Determines the physical layer module found on the current adapter.
+ **/
+s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+{
+ s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+ status = ixgbe_identify_phy_generic(hw);
+ if (status != 0)
+ status = ixgbe_identify_sfp_module_generic(hw);
+ return status;
+}
+
+/**
+ * ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
+ * @hw: pointer to hardware structure
+ *
+ * Determines physical layer capabilities of the current configuration.
+ **/
+u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
+{
+ u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ 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);
+ break;
+ case IXGBE_DEV_ID_82599_SFP:
+ hw->phy.ops.identify_sfp(hw);
+
+ switch (hw->phy.sfp_type) {
+ case ixgbe_sfp_type_da_cu:
+ case ixgbe_sfp_type_da_cu_core0:
+ case ixgbe_sfp_type_da_cu_core1:
+ physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+ break;
+ case ixgbe_sfp_type_sr:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ break;
+ case ixgbe_sfp_type_lr:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ break;
+ case ixgbe_sfp_type_srlr_core0:
+ case ixgbe_sfp_type_srlr_core1:
+ hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_10GBE_COMP_CODES,
+ &comp_codes_10g);
+ if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+ physical_layer =
+ IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+ physical_layer =
+ IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ else
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ default:
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ break;
+ }
+ break;
+ default:
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ break;
+ }
+
+ return physical_layer;
+}
+
+/**
+ * ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
+ * @hw: pointer to hardware structure
+ * @regval: register value to write to RXCTRL
+ *
+ * Enables the Rx DMA unit for 82599
+ **/
+s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
+{
+#define IXGBE_MAX_SECRX_POLL 30
+ int i;
+ int secrxreg;
+
+ /*
+ * Workaround for 82599 silicon errata when enabling the Rx datapath.
+ * If traffic is incoming before we enable the Rx unit, it could hang
+ * the Rx DMA unit. Therefore, make sure the security engine is
+ * completely disabled prior to enabling the Rx unit.
+ */
+ secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+ secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+ for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
+ secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
+ if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
+ break;
+ else
+ udelay(10);
+ }
+
+ /* For informational purposes only */
+ if (i >= IXGBE_MAX_SECRX_POLL)
+ hw_dbg(hw, "Rx unit being enabled before security "
+ "path fully disabled. Continuing with init.\n");
+
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+ secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+ secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+static struct ixgbe_mac_operations mac_ops_82599 = {
+ .init_hw = &ixgbe_init_hw_generic,
+ .reset_hw = &ixgbe_reset_hw_82599,
+ .start_hw = &ixgbe_start_hw_82599,
+ .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
+ .get_media_type = &ixgbe_get_media_type_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,
+ .stop_adapter = &ixgbe_stop_adapter_generic,
+ .get_bus_info = &ixgbe_get_bus_info_generic,
+ .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
+ .read_analog_reg8 = &ixgbe_read_analog_reg8_82599,
+ .write_analog_reg8 = &ixgbe_write_analog_reg8_82599,
+ .setup_link = &ixgbe_setup_mac_link_82599,
+ .setup_link_speed = &ixgbe_setup_mac_link_speed_82599,
+ .check_link = &ixgbe_check_mac_link_82599,
+ .get_link_capabilities = &ixgbe_get_link_capabilities_82599,
+ .led_on = &ixgbe_led_on_generic,
+ .led_off = &ixgbe_led_off_generic,
+ .blink_led_start = &ixgbe_blink_led_start_82599,
+ .blink_led_stop = &ixgbe_blink_led_stop_82599,
+ .set_rar = &ixgbe_set_rar_generic,
+ .clear_rar = &ixgbe_clear_rar_generic,
+ .set_vmdq = &ixgbe_set_vmdq_82599,
+ .clear_vmdq = &ixgbe_clear_vmdq_82599,
+ .init_rx_addrs = &ixgbe_init_rx_addrs_generic,
+ .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic,
+ .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic,
+ .enable_mc = &ixgbe_enable_mc_generic,
+ .disable_mc = &ixgbe_disable_mc_generic,
+ .clear_vfta = &ixgbe_clear_vfta_82599,
+ .set_vfta = &ixgbe_set_vfta_82599,
+ .setup_fc = &ixgbe_setup_fc_generic,
+ .init_uta_tables = &ixgbe_init_uta_tables_82599,
+ .setup_sfp = &ixgbe_setup_sfp_modules_82599,
+};
+
+static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
+ .init_params = &ixgbe_init_eeprom_params_generic,
+ .read = &ixgbe_read_eeprom_generic,
+ .write = &ixgbe_write_eeprom_generic,
+ .validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
+ .update_checksum = &ixgbe_update_eeprom_checksum_generic,
+};
+
+static struct ixgbe_phy_operations phy_ops_82599 = {
+ .identify = &ixgbe_identify_phy_82599,
+ .identify_sfp = &ixgbe_identify_sfp_module_generic,
+ .reset = &ixgbe_reset_phy_generic,
+ .read_reg = &ixgbe_read_phy_reg_generic,
+ .write_reg = &ixgbe_write_phy_reg_generic,
+ .setup_link = &ixgbe_setup_phy_link_generic,
+ .setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
+ .read_i2c_byte = &ixgbe_read_i2c_byte_generic,
+ .write_i2c_byte = &ixgbe_write_i2c_byte_generic,
+ .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
+ .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
+};
+
+struct ixgbe_info ixgbe_82599_info = {
+ .mac = ixgbe_mac_82599EB,
+ .get_invariants = &ixgbe_get_invariants_82599,
+ .mac_ops = &mac_ops_82599,
+ .eeprom_ops = &eeprom_ops_82599,
+ .phy_ops = &phy_ops_82599,
+};
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index f67c68404bb..8cfd3fd309a 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -29,6 +29,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
+#include "ixgbe.h"
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
@@ -80,9 +81,6 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
/* Clear the VLAN filter table */
hw->mac.ops.clear_vfta(hw);
- /* Set up link */
- hw->mac.ops.setup_link(hw);
-
/* Clear statistics registers */
hw->mac.ops.clear_hw_cntrs(hw);
@@ -254,6 +252,81 @@ s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
}
/**
+ * ixgbe_get_bus_info_generic - Generic set PCI bus info
+ * @hw: pointer to hardware structure
+ *
+ * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure
+ **/
+s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
+{
+ struct ixgbe_adapter *adapter = hw->back;
+ struct ixgbe_mac_info *mac = &hw->mac;
+ u16 link_status;
+
+ hw->bus.type = ixgbe_bus_type_pci_express;
+
+ /* Get the negotiated link width and speed from PCI config space */
+ pci_read_config_word(adapter->pdev, IXGBE_PCI_LINK_STATUS,
+ &link_status);
+
+ switch (link_status & IXGBE_PCI_LINK_WIDTH) {
+ case IXGBE_PCI_LINK_WIDTH_1:
+ hw->bus.width = ixgbe_bus_width_pcie_x1;
+ break;
+ case IXGBE_PCI_LINK_WIDTH_2:
+ hw->bus.width = ixgbe_bus_width_pcie_x2;
+ break;
+ case IXGBE_PCI_LINK_WIDTH_4:
+ hw->bus.width = ixgbe_bus_width_pcie_x4;
+ break;
+ case IXGBE_PCI_LINK_WIDTH_8:
+ hw->bus.width = ixgbe_bus_width_pcie_x8;
+ break;
+ default:
+ hw->bus.width = ixgbe_bus_width_unknown;
+ break;
+ }
+
+ switch (link_status & IXGBE_PCI_LINK_SPEED) {
+ case IXGBE_PCI_LINK_SPEED_2500:
+ hw->bus.speed = ixgbe_bus_speed_2500;
+ break;
+ case IXGBE_PCI_LINK_SPEED_5000:
+ hw->bus.speed = ixgbe_bus_speed_5000;
+ break;
+ default:
+ hw->bus.speed = ixgbe_bus_speed_unknown;
+ break;
+ }
+
+ mac->ops.set_lan_id(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
+ * @hw: pointer to the HW structure
+ *
+ * Determines the LAN function id by reading memory-mapped registers
+ * and swaps the port value if requested.
+ **/
+void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
+{
+ struct ixgbe_bus_info *bus = &hw->bus;
+ u32 reg;
+
+ reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
+ bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
+ bus->lan_id = bus->func;
+
+ /* check for a port swap */
+ reg = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+ if (reg & IXGBE_FACTPS_LFS)
+ bus->func ^= 0x1;
+}
+
+/**
* ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
* @hw: pointer to hardware structure
*
@@ -393,6 +466,73 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be written to
+ * @data: 16 bit word to be written to the EEPROM
+ *
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
+ **/
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ s32 status;
+ u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
+ /* Prepare the EEPROM for writing */
+ status = ixgbe_acquire_eeprom(hw);
+
+ if (status == 0) {
+ if (ixgbe_ready_eeprom(hw) != 0) {
+ ixgbe_release_eeprom(hw);
+ status = IXGBE_ERR_EEPROM;
+ }
+ }
+
+ if (status == 0) {
+ ixgbe_standby_eeprom(hw);
+
+ /* Send the WRITE ENABLE command (8 bit opcode ) */
+ ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
+ IXGBE_EEPROM_OPCODE_BITS);
+
+ ixgbe_standby_eeprom(hw);
+
+ /*
+ * Some SPI eeproms use the 8th address bit embedded in the
+ * opcode
+ */
+ if ((hw->eeprom.address_bits == 8) && (offset >= 128))
+ write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the Write command (8-bit opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, write_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
+ hw->eeprom.address_bits);
+
+ /* Send the data */
+ data = (data >> 8) | (data << 8);
+ ixgbe_shift_out_eeprom_bits(hw, data, 16);
+ ixgbe_standby_eeprom(hw);
+
+ msleep(hw->eeprom.semaphore_delay);
+ /* Done with writing - release the EEPROM */
+ ixgbe_release_eeprom(hw);
+ }
+
+out:
+ return status;
+}
+
+/**
* ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
* @hw: pointer to hardware structure
* @offset: offset within the EEPROM to be read
@@ -521,7 +661,7 @@ static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw)
static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
{
s32 status = 0;
- u32 eec;
+ u32 eec = 0;
u32 i;
if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
@@ -1490,6 +1630,326 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_fc_enable - 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 ret_val = 0;
+ u32 mflcn_reg;
+ u32 fccfg_reg;
+ u32 reg;
+
+ mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
+
+ fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+ fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
+
+ /*
+ * 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.
+ */
+ switch (hw->fc.current_mode) {
+ case ixgbe_fc_none:
+ /* Flow control completely disabled by software override. */
+ 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.
+ */
+ mflcn_reg |= IXGBE_MFLCN_RFCE;
+ break;
+ case ixgbe_fc_tx_pause:
+ /*
+ * Tx Flow control is enabled, and Rx Flow control is
+ * disabled by software override.
+ */
+ fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
+ break;
+ case ixgbe_fc_full:
+ /* Flow control (both Rx and Tx) is enabled by SW override. */
+ mflcn_reg |= IXGBE_MFLCN_RFCE;
+ fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
+ 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;
+ }
+
+ /* Enable 802.3x based flow control settings. */
+ 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);
+
+ 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));
+ if ((packetbuf_num & 1) == 0)
+ reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
+ else
+ reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+
+out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_fc_autoneg - Configure flow control
+ * @hw: pointer to hardware structure
+ *
+ * Negotiates flow control capabilities with link partner using autoneg and
+ * applies the results.
+ **/
+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);
+
+ /*
+ * 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.
+ */
+ 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");
+ goto out;
+ }
+
+ /*
+ * Read the AN advertisement and LP ability registers and resolve
+ * local flow control settings accordingly
+ */
+ pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+ pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
+ if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
+ /*
+ * Now we need to check if the user selected Rx ONLY
+ * of pause frames. In this case, we had to advertise
+ * FULL flow control because we could not advertise RX
+ * ONLY. Hence, we must now check to see if we need to
+ * turn OFF the TRANSMISSION of PAUSE frames.
+ */
+ if (hw->fc.requested_mode == ixgbe_fc_full) {
+ hw->fc.current_mode = ixgbe_fc_full;
+ hw_dbg(hw, "Flow Control = FULL.\n");
+ } else {
+ hw->fc.current_mode = ixgbe_fc_rx_pause;
+ hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+ }
+ } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+ hw->fc.current_mode = ixgbe_fc_tx_pause;
+ hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
+ } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+ !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+ hw->fc.current_mode = ixgbe_fc_rx_pause;
+ hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+ } else {
+ hw->fc.current_mode = ixgbe_fc_none;
+ hw_dbg(hw, "Flow Control = NONE.\n");
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_setup_fc_generic - Set up flow control
+ * @hw: pointer to hardware structure
+ *
+ * Sets up flow control.
+ **/
+s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+ s32 ret_val = 0;
+ ixgbe_link_speed speed;
+ bool link_up;
+
+#ifdef CONFIG_DCB
+ if (hw->fc.requested_mode == ixgbe_fc_pfc) {
+ hw->fc.current_mode = hw->fc.requested_mode;
+ goto out;
+ }
+
+#endif
+ /* 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->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(hw, packetbuf_num);
+
+out:
+ return ret_val;
+}
+
+/**
* ixgbe_disable_pcie_master - Disable PCI-express master access
* @hw: pointer to hardware structure
*
@@ -1597,3 +2057,16 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
ixgbe_release_eeprom_semaphore(hw);
}
+/**
+ * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
+ * @hw: pointer to hardware structure
+ * @regval: register value to write to RXCTRL
+ *
+ * Enables the Rx DMA unit
+ **/
+s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
+{
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+
+ return 0;
+}
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 192f8d01291..7e94d6d399a 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -37,12 +37,14 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
+void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data);
@@ -61,6 +63,10 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
u32 addr_count, ixgbe_mc_addr_itr func);
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_fc_autoneg(struct ixgbe_hw *hw);
s32 ixgbe_validate_mac_addr(u8 *mac_addr);
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
@@ -72,6 +78,13 @@ s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
+#ifndef writeq
+#define writeq(val, addr) writel((u32) (val), addr); \
+ writel((u32) (val >> 32), (addr + 4));
+#endif
+
+#define IXGBE_WRITE_REG64(a, reg, value) writeq((value), ((a)->hw_addr + (reg)))
+
#define IXGBE_READ_REG(a, reg) readl((a)->hw_addr + (reg))
#define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) (\
diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c
index e2e28ac63de..a1562287342 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.c
+++ b/drivers/net/ixgbe/ixgbe_dcb.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ 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,
@@ -31,6 +31,7 @@
#include "ixgbe_type.h"
#include "ixgbe_dcb.h"
#include "ixgbe_dcb_82598.h"
+#include "ixgbe_dcb_82599.h"
/**
* ixgbe_dcb_config - Struct containing DCB settings.
@@ -215,6 +216,8 @@ s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
return ret;
}
@@ -232,6 +235,8 @@ s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
return ret;
}
@@ -248,6 +253,8 @@ s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
return ret;
}
@@ -264,6 +271,8 @@ s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
return ret;
}
@@ -280,6 +289,8 @@ s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
return ret;
}
@@ -296,6 +307,8 @@ s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_pfc_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_pfc_82599(hw, dcb_config);
return ret;
}
@@ -311,6 +324,8 @@ s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_tc_stats_82598(hw);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_tc_stats_82599(hw);
return ret;
}
@@ -327,6 +342,8 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_hw_config_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_hw_config_82599(hw, dcb_config);
return ret;
}
diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h
index 75f6efe1e36..64a9fa15c05 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.h
+++ b/drivers/net/ixgbe/ixgbe_dcb.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ 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,
@@ -75,6 +75,26 @@ enum strict_prio_type {
prio_link
};
+/* DCB capability definitions */
+#define IXGBE_DCB_PG_SUPPORT 0x00000001
+#define IXGBE_DCB_PFC_SUPPORT 0x00000002
+#define IXGBE_DCB_BCN_SUPPORT 0x00000004
+#define IXGBE_DCB_UP2TC_SUPPORT 0x00000008
+#define IXGBE_DCB_GSP_SUPPORT 0x00000010
+
+#define IXGBE_DCB_8_TC_SUPPORT 0x80
+
+struct dcb_support {
+ /* DCB capabilities */
+ u32 capabilities;
+
+ /* Each bit represents a number of TCs configurable in the hw.
+ * If 8 traffic classes can be configured, the value is 0x80.
+ */
+ u8 traffic_classes;
+ u8 pfc_traffic_classes;
+};
+
/* Traffic class bandwidth allocation per direction */
struct tc_bw_alloc {
u8 bwg_id; /* Bandwidth Group (BWG) ID */
@@ -108,38 +128,18 @@ enum dcb_rx_pba_cfg {
pba_80_48 /* PBA[0-3] each use 80KB, PBA[4-7] each use 48KB */
};
-/*
- * This structure contains many values encoded as fixed-point
- * numbers, meaning that some of bits are dedicated to the
- * magnitude and others to the fraction part. In the comments
- * this is shown as f=n, where n is the number of fraction bits.
- * These fraction bits are always the low-order bits. The size
- * of the magnitude is not specified.
- */
-struct bcn_config {
- u32 rp_admin_mode[MAX_TRAFFIC_CLASS]; /* BCN enabled, per TC */
- u32 bcna_option[2]; /* BCNA Port + MAC Addr */
- u32 rp_w; /* Derivative Weight, f=3 */
- u32 rp_gi; /* Increase Gain, f=12 */
- u32 rp_gd; /* Decrease Gain, f=12 */
- u32 rp_ru; /* Rate Unit */
- u32 rp_alpha; /* Max Decrease Factor, f=12 */
- u32 rp_beta; /* Max Increase Factor, f=12 */
- u32 rp_ri; /* Initial Rate */
- u32 rp_td; /* Drift Interval Timer */
- u32 rp_rd; /* Drift Increase */
- u32 rp_tmax; /* Severe Congestion Backoff Timer Range */
- u32 rp_rmin; /* Severe Congestion Restart Rate */
- u32 rp_wrtt; /* RTT Moving Average Weight */
+struct dcb_num_tcs {
+ u8 pg_tcs;
+ u8 pfc_tcs;
};
struct ixgbe_dcb_config {
- struct bcn_config bcn;
-
+ struct dcb_support support;
+ struct dcb_num_tcs num_tcs;
struct tc_configuration tc_config[MAX_TRAFFIC_CLASS];
u8 bw_percentage[2][MAX_BW_GROUP]; /* One each for Tx/Rx */
-
- bool round_robin_enable;
+ bool pfc_mode_enable;
+ bool round_robin_enable;
enum dcb_rx_pba_cfg rx_pba_cfg;
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
index 2c046b0b5d2..62206273d88 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ 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,
@@ -298,7 +298,6 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
reg &= ~IXGBE_RMCS_TFCE_802_3X;
/* correct the reporting of our flow control status */
- hw->fc.type = ixgbe_fc_none;
reg |= IXGBE_RMCS_TFCE_PRIORITY;
IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h
index 1e6a313719d..ebbe53c352a 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.h
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ 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,
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
new file mode 100644
index 00000000000..470b676c1da
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -0,0 +1,467 @@
+/*******************************************************************************
+
+ 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 "ixgbe_type.h"
+#include "ixgbe_dcb.h"
+#include "ixgbe_dcb_82599.h"
+
+/**
+ * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class
+ * @hw: pointer to hardware structure
+ * @stats: pointer to statistics structure
+ * @tc_count: Number of elements in bwg_array.
+ *
+ * This function returns the status data for each of the Traffic Classes in use.
+ */
+s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
+ struct ixgbe_hw_stats *stats,
+ u8 tc_count)
+{
+ int tc;
+
+ if (tc_count > MAX_TRAFFIC_CLASS)
+ return DCB_ERR_PARAM;
+ /* Statistics pertaining to each traffic class */
+ for (tc = 0; tc < tc_count; tc++) {
+ /* Transmitted Packets */
+ stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
+ /* Transmitted Bytes */
+ stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
+ /* Received Packets */
+ stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
+ /* Received Bytes */
+ stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data
+ * @hw: pointer to hardware structure
+ * @stats: pointer to statistics structure
+ * @tc_count: Number of elements in bwg_array.
+ *
+ * This function returns the CBFC status data for each of the Traffic Classes.
+ */
+s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
+ struct ixgbe_hw_stats *stats,
+ u8 tc_count)
+{
+ int tc;
+
+ if (tc_count > MAX_TRAFFIC_CLASS)
+ return DCB_ERR_PARAM;
+ for (tc = 0; tc < tc_count; tc++) {
+ /* Priority XOFF Transmitted */
+ stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
+ /* Priority XOFF Received */
+ stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc));
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure packet buffers for DCB mode.
+ */
+s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ s32 ret_val = 0;
+ u32 value = IXGBE_RXPBSIZE_64KB;
+ u8 i = 0;
+
+ /* Setup Rx packet buffer sizes */
+ switch (dcb_config->rx_pba_cfg) {
+ case pba_80_48:
+ /* Setup the first four at 80KB */
+ value = IXGBE_RXPBSIZE_80KB;
+ for (; i < 4; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
+ /* Setup the last four at 48KB...don't re-init i */
+ value = IXGBE_RXPBSIZE_48KB;
+ /* Fall Through */
+ case pba_equal:
+ default:
+ for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
+
+ /* Setup Tx packet buffer sizes */
+ for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
+ IXGBE_TXPBSIZE_20KB);
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i),
+ IXGBE_TXPBTHRESH_DCB);
+ }
+ break;
+ }
+
+ return ret_val;
+}
+
+/**
+ * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Rx Packet Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ struct tc_bw_alloc *p;
+ u32 reg = 0;
+ u32 credit_refill = 0;
+ u32 credit_max = 0;
+ u8 i = 0;
+
+ /* Disable the arbiter before changing parameters */
+ IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, IXGBE_RTRPCS_ARBDIS);
+
+ /* Map all traffic classes to their UP, 1 to 1 */
+ reg = 0;
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ reg |= (i << (i * IXGBE_RTRUP2TC_UP_SHIFT));
+ IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg);
+
+ /* Configure traffic class credits and priority */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG];
+
+ credit_refill = p->data_credits_refill;
+ credit_max = p->data_credits_max;
+ reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT);
+
+ reg |= (u32)(p->bwg_id) << IXGBE_RTRPT4C_BWG_SHIFT;
+
+ if (p->prio_type == prio_link)
+ reg |= IXGBE_RTRPT4C_LSP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg);
+ }
+
+ /*
+ * Configure Rx packet plane (recycle mode; WSP) and
+ * enable arbiter
+ */
+ reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC;
+ IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Tx Descriptor Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ struct tc_bw_alloc *p;
+ u32 reg, max_credits;
+ u8 i;
+
+ /* Disable the arbiter before changing parameters */
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, IXGBE_RTTDCS_ARBDIS);
+
+ /* Clear the per-Tx queue credits; we use per-TC instead */
+ for (i = 0; i < 128; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0);
+ }
+
+ /* Configure traffic class credits and priority */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
+ max_credits = dcb_config->tc_config[i].desc_credits_max;
+ reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT;
+ reg |= p->data_credits_refill;
+ reg |= (u32)(p->bwg_id) << IXGBE_RTTDT2C_BWG_SHIFT;
+
+ if (p->prio_type == prio_group)
+ reg |= IXGBE_RTTDT2C_GSP;
+
+ if (p->prio_type == prio_link)
+ reg |= IXGBE_RTTDT2C_LSP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg);
+ }
+
+ /*
+ * Configure Tx descriptor plane (recycle mode; WSP) and
+ * enable arbiter
+ */
+ reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Tx Packet Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ struct tc_bw_alloc *p;
+ u32 reg;
+ u8 i;
+
+ /* Disable the arbiter before changing parameters */
+ IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, IXGBE_RTTPCS_ARBDIS);
+
+ /* Map all traffic classes to their UP, 1 to 1 */
+ reg = 0;
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ reg |= (i << (i * IXGBE_RTTUP2TC_UP_SHIFT));
+ IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg);
+
+ /* Configure traffic class credits and priority */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
+ reg = p->data_credits_refill;
+ reg |= (u32)(p->data_credits_max) << IXGBE_RTTPT2C_MCL_SHIFT;
+ reg |= (u32)(p->bwg_id) << IXGBE_RTTPT2C_BWG_SHIFT;
+
+ if (p->prio_type == prio_group)
+ reg |= IXGBE_RTTPT2C_GSP;
+
+ if (p->prio_type == prio_link)
+ reg |= IXGBE_RTTPT2C_LSP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg);
+ }
+
+ /*
+ * Configure Tx packet plane (recycle mode; SP; arb delay) and
+ * enable arbiter
+ */
+ reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
+ (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT);
+ IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_pfc_82599 - Configure priority flow control
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Priority Flow Control (PFC) for each traffic class.
+ */
+s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ u32 i, reg;
+
+ /* 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);
+ goto out;
+ }
+
+ /* Configure PFC Tx thresholds per TC */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ /* Config and remember Tx */
+ if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
+ dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) {
+ reg = hw->fc.high_water | IXGBE_FCRTH_FCEN;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
+ reg = hw->fc.low_water | IXGBE_FCRTL_XONE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
+ }
+ }
+
+ /* Configure pause time (2 TCs per register) */
+ reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
+ for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
+
+ /* Configure flow control refresh threshold value */
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
+
+ /* Enable Transmit PFC */
+ reg = IXGBE_FCCFG_TFCE_PRIORITY;
+ IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
+
+ /*
+ * Enable Receive PFC
+ * We will always honor XOFF frames we receive when
+ * we are in PFC mode.
+ */
+ reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ reg &= ~IXGBE_MFLCN_RFCE;
+ reg |= IXGBE_MFLCN_RPFCE;
+ IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
+out:
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics
+ * @hw: pointer to hardware structure
+ *
+ * Configure queue statistics registers, all queues belonging to same traffic
+ * class uses a single set of queue statistics counters.
+ */
+s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw)
+{
+ u32 reg = 0;
+ u8 i = 0;
+
+ /*
+ * Receive Queues stats setting
+ * 32 RQSMR registers, each configuring 4 queues.
+ * Set all 16 queues of each TC to the same stat
+ * with TC 'n' going to stat 'n'.
+ */
+ for (i = 0; i < 32; i++) {
+ reg = 0x01010101 * (i / 4);
+ IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
+ }
+ /*
+ * Transmit Queues stats setting
+ * 32 TQSM registers, each controlling 4 queues.
+ * Set all queues of each TC to the same stat
+ * with TC 'n' going to stat 'n'.
+ * Tx queues are allocated non-uniformly to TCs:
+ * 32, 32, 16, 16, 8, 8, 8, 8.
+ */
+ for (i = 0; i < 32; i++) {
+ if (i < 8)
+ reg = 0x00000000;
+ else if (i < 16)
+ reg = 0x01010101;
+ else if (i < 20)
+ reg = 0x02020202;
+ else if (i < 24)
+ reg = 0x03030303;
+ else if (i < 26)
+ reg = 0x04040404;
+ else if (i < 28)
+ reg = 0x05050505;
+ else if (i < 30)
+ reg = 0x06060606;
+ else
+ reg = 0x07070707;
+ IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_82599 - Configure general DCB parameters
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure general DCB parameters.
+ */
+s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw)
+{
+ u32 reg;
+ u32 q;
+
+ /* Disable the Tx desc arbiter so that MTQC can be changed */
+ reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+ reg |= IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+ /* Enable DCB for Rx with 8 TCs */
+ reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
+ switch (reg & IXGBE_MRQC_MRQE_MASK) {
+ case 0:
+ case IXGBE_MRQC_RT4TCEN:
+ /* RSS disabled cases */
+ reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN;
+ break;
+ case IXGBE_MRQC_RSSEN:
+ case IXGBE_MRQC_RTRSS4TCEN:
+ /* RSS enabled cases */
+ reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RTRSS8TCEN;
+ break;
+ default:
+ /* Unsupported value, assume stale data, overwrite no RSS */
+ reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN;
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_MRQC, reg);
+
+ /* Enable DCB for Tx with 8 TCs */
+ reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ;
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg);
+
+ /* Disable drop for all queues */
+ for (q = 0; q < 128; q++)
+ IXGBE_WRITE_REG(hw, IXGBE_QDE, q << IXGBE_QDE_IDX_SHIFT);
+
+ /* Enable the Tx desc arbiter */
+ reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+ reg &= ~IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_hw_config_82599 - Configure and enable DCB
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure dcb settings and enable dcb mode.
+ */
+s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ ixgbe_dcb_config_packet_buffers_82599(hw, dcb_config);
+ ixgbe_dcb_config_82599(hw);
+ ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
+ ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
+ ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
+ ixgbe_dcb_config_pfc_82599(hw, dcb_config);
+ ixgbe_dcb_config_tc_stats_82599(hw);
+
+ return 0;
+}
+
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h
new file mode 100644
index 00000000000..9e5e2827e4a
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h
@@ -0,0 +1,127 @@
+/*******************************************************************************
+
+ 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 _DCB_82599_CONFIG_H_
+#define _DCB_82599_CONFIG_H_
+
+/* DCB register definitions */
+#define IXGBE_RTTDCS_TDPAC 0x00000001 /* 0 Round Robin,
+ * 1 WSP - Weighted Strict Priority
+ */
+#define IXGBE_RTTDCS_VMPAC 0x00000002 /* 0 Round Robin,
+ * 1 WRR - Weighted Round Robin
+ */
+#define IXGBE_RTTDCS_TDRM 0x00000010 /* Transmit Recycle Mode */
+#define IXGBE_RTTDCS_ARBDIS 0x00000040 /* DCB arbiter disable */
+#define IXGBE_RTTDCS_BDPM 0x00400000 /* Bypass Data Pipe - must clear! */
+#define IXGBE_RTTDCS_BPBFSM 0x00800000 /* Bypass PB Free Space - must
+ * clear!
+ */
+#define IXGBE_RTTDCS_SPEED_CHG 0x80000000 /* Link speed change */
+
+/* Receive UP2TC mapping */
+#define IXGBE_RTRUP2TC_UP_SHIFT 3
+/* Transmit UP2TC mapping */
+#define IXGBE_RTTUP2TC_UP_SHIFT 3
+
+#define IXGBE_RTRPT4C_MCL_SHIFT 12 /* Offset to Max Credit Limit setting */
+#define IXGBE_RTRPT4C_BWG_SHIFT 9 /* Offset to BWG index */
+#define IXGBE_RTRPT4C_GSP 0x40000000 /* GSP enable bit */
+#define IXGBE_RTRPT4C_LSP 0x80000000 /* LSP enable bit */
+
+#define IXGBE_RDRXCTL_MPBEN 0x00000010 /* DMA config for multiple packet
+ * buffers enable
+ */
+#define IXGBE_RDRXCTL_MCEN 0x00000040 /* DMA config for multiple cores
+ * (RSS) enable
+ */
+
+/* RTRPCS Bit Masks */
+#define IXGBE_RTRPCS_RRM 0x00000002 /* Receive Recycle Mode enable */
+/* Receive Arbitration Control: 0 Round Robin, 1 DFP */
+#define IXGBE_RTRPCS_RAC 0x00000004
+#define IXGBE_RTRPCS_ARBDIS 0x00000040 /* Arbitration disable bit */
+
+/* RTTDT2C Bit Masks */
+#define IXGBE_RTTDT2C_MCL_SHIFT 12
+#define IXGBE_RTTDT2C_BWG_SHIFT 9
+#define IXGBE_RTTDT2C_GSP 0x40000000
+#define IXGBE_RTTDT2C_LSP 0x80000000
+
+#define IXGBE_RTTPT2C_MCL_SHIFT 12
+#define IXGBE_RTTPT2C_BWG_SHIFT 9
+#define IXGBE_RTTPT2C_GSP 0x40000000
+#define IXGBE_RTTPT2C_LSP 0x80000000
+
+/* RTTPCS Bit Masks */
+#define IXGBE_RTTPCS_TPPAC 0x00000020 /* 0 Round Robin,
+ * 1 SP - Strict Priority
+ */
+#define IXGBE_RTTPCS_ARBDIS 0x00000040 /* Arbiter disable */
+#define IXGBE_RTTPCS_TPRM 0x00000100 /* Transmit Recycle Mode enable */
+#define IXGBE_RTTPCS_ARBD_SHIFT 22
+#define IXGBE_RTTPCS_ARBD_DCB 0x4 /* Arbitration delay in DCB mode */
+
+#define IXGBE_TXPBSIZE_20KB 0x00005000 /* 20KB Packet Buffer */
+#define IXGBE_TXPBSIZE_40KB 0x0000A000 /* 40KB Packet Buffer */
+#define IXGBE_RXPBSIZE_48KB 0x0000C000 /* 48KB Packet Buffer */
+#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */
+#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */
+#define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */
+
+#define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */
+
+
+/* DCB hardware-specific driver APIs */
+
+/* DCB PFC functions */
+s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
+ struct ixgbe_hw_stats *stats,
+ u8 tc_count);
+
+/* DCB traffic class stats */
+s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw);
+s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
+ struct ixgbe_hw_stats *stats,
+ u8 tc_count);
+
+/* DCB config arbiters */
+s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config);
+
+
+/* DCB hw initialization */
+s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *config);
+
+#endif /* _DCB_82599_CONFIG_H */
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index 4129976953f..0a8731f1f23 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -35,6 +35,7 @@
#define BIT_PG_RX 0x04
#define BIT_PG_TX 0x08
#define BIT_BCN 0x10
+#define BIT_LINKSPEED 0x80
int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max)
@@ -89,25 +90,6 @@ int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
src_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc;
}
- for (i = DCB_BCN_ATTR_RP_0; i < DCB_BCN_ATTR_RP_ALL; i++) {
- dst_dcb_cfg->bcn.rp_admin_mode[i - DCB_BCN_ATTR_RP_0] =
- src_dcb_cfg->bcn.rp_admin_mode[i - DCB_BCN_ATTR_RP_0];
- }
- dst_dcb_cfg->bcn.bcna_option[0] = src_dcb_cfg->bcn.bcna_option[0];
- dst_dcb_cfg->bcn.bcna_option[1] = src_dcb_cfg->bcn.bcna_option[1];
- dst_dcb_cfg->bcn.rp_alpha = src_dcb_cfg->bcn.rp_alpha;
- dst_dcb_cfg->bcn.rp_beta = src_dcb_cfg->bcn.rp_beta;
- dst_dcb_cfg->bcn.rp_gd = src_dcb_cfg->bcn.rp_gd;
- dst_dcb_cfg->bcn.rp_gi = src_dcb_cfg->bcn.rp_gi;
- dst_dcb_cfg->bcn.rp_tmax = src_dcb_cfg->bcn.rp_tmax;
- dst_dcb_cfg->bcn.rp_td = src_dcb_cfg->bcn.rp_td;
- dst_dcb_cfg->bcn.rp_rmin = src_dcb_cfg->bcn.rp_rmin;
- dst_dcb_cfg->bcn.rp_w = src_dcb_cfg->bcn.rp_w;
- dst_dcb_cfg->bcn.rp_rd = src_dcb_cfg->bcn.rp_rd;
- dst_dcb_cfg->bcn.rp_ru = src_dcb_cfg->bcn.rp_ru;
- dst_dcb_cfg->bcn.rp_wrtt = src_dcb_cfg->bcn.rp_wrtt;
- dst_dcb_cfg->bcn.rp_ri = src_dcb_cfg->bcn.rp_ri;
-
return 0;
}
@@ -120,12 +102,6 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
}
-static u16 ixgbe_dcb_select_queue(struct net_device *dev, struct sk_buff *skb)
-{
- /* All traffic should default to class 0 */
- return 0;
-}
-
static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
{
u8 err = 0;
@@ -153,8 +129,8 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
kfree(adapter->rx_ring);
adapter->tx_ring = NULL;
adapter->rx_ring = NULL;
- netdev->select_queue = &ixgbe_dcb_select_queue;
+ adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
ixgbe_init_interrupt_scheme(adapter);
@@ -163,6 +139,7 @@ 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);
@@ -172,7 +149,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
kfree(adapter->rx_ring);
adapter->tx_ring = NULL;
adapter->rx_ring = NULL;
- netdev->select_queue = NULL;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
@@ -444,175 +420,6 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
return;
}
-static void ixgbe_dcbnl_getbcnrp(struct net_device *netdev, int priority,
- u8 *setting)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- *setting = adapter->dcb_cfg.bcn.rp_admin_mode[priority];
-}
-
-
-static void ixgbe_dcbnl_getbcncfg(struct net_device *netdev, int enum_index,
- u32 *setting)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- switch (enum_index) {
- case DCB_BCN_ATTR_BCNA_0:
- *setting = adapter->dcb_cfg.bcn.bcna_option[0];
- break;
- case DCB_BCN_ATTR_BCNA_1:
- *setting = adapter->dcb_cfg.bcn.bcna_option[1];
- break;
- case DCB_BCN_ATTR_ALPHA:
- *setting = adapter->dcb_cfg.bcn.rp_alpha;
- break;
- case DCB_BCN_ATTR_BETA:
- *setting = adapter->dcb_cfg.bcn.rp_beta;
- break;
- case DCB_BCN_ATTR_GD:
- *setting = adapter->dcb_cfg.bcn.rp_gd;
- break;
- case DCB_BCN_ATTR_GI:
- *setting = adapter->dcb_cfg.bcn.rp_gi;
- break;
- case DCB_BCN_ATTR_TMAX:
- *setting = adapter->dcb_cfg.bcn.rp_tmax;
- break;
- case DCB_BCN_ATTR_TD:
- *setting = adapter->dcb_cfg.bcn.rp_td;
- break;
- case DCB_BCN_ATTR_RMIN:
- *setting = adapter->dcb_cfg.bcn.rp_rmin;
- break;
- case DCB_BCN_ATTR_W:
- *setting = adapter->dcb_cfg.bcn.rp_w;
- break;
- case DCB_BCN_ATTR_RD:
- *setting = adapter->dcb_cfg.bcn.rp_rd;
- break;
- case DCB_BCN_ATTR_RU:
- *setting = adapter->dcb_cfg.bcn.rp_ru;
- break;
- case DCB_BCN_ATTR_WRTT:
- *setting = adapter->dcb_cfg.bcn.rp_wrtt;
- break;
- case DCB_BCN_ATTR_RI:
- *setting = adapter->dcb_cfg.bcn.rp_ri;
- break;
- default:
- *setting = -1;
- }
-}
-
-static void ixgbe_dcbnl_setbcnrp(struct net_device *netdev, int priority,
- u8 setting)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- adapter->temp_dcb_cfg.bcn.rp_admin_mode[priority] = setting;
-
- if (adapter->temp_dcb_cfg.bcn.rp_admin_mode[priority] !=
- adapter->dcb_cfg.bcn.rp_admin_mode[priority])
- adapter->dcb_set_bitmap |= BIT_BCN;
-}
-
-static void ixgbe_dcbnl_setbcncfg(struct net_device *netdev, int enum_index,
- u32 setting)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- switch (enum_index) {
- case DCB_BCN_ATTR_BCNA_0:
- adapter->temp_dcb_cfg.bcn.bcna_option[0] = setting;
- if (adapter->temp_dcb_cfg.bcn.bcna_option[0] !=
- adapter->dcb_cfg.bcn.bcna_option[0])
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_BCNA_1:
- adapter->temp_dcb_cfg.bcn.bcna_option[1] = setting;
- if (adapter->temp_dcb_cfg.bcn.bcna_option[1] !=
- adapter->dcb_cfg.bcn.bcna_option[1])
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_ALPHA:
- adapter->temp_dcb_cfg.bcn.rp_alpha = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_alpha !=
- adapter->dcb_cfg.bcn.rp_alpha)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_BETA:
- adapter->temp_dcb_cfg.bcn.rp_beta = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_beta !=
- adapter->dcb_cfg.bcn.rp_beta)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_GD:
- adapter->temp_dcb_cfg.bcn.rp_gd = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_gd !=
- adapter->dcb_cfg.bcn.rp_gd)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_GI:
- adapter->temp_dcb_cfg.bcn.rp_gi = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_gi !=
- adapter->dcb_cfg.bcn.rp_gi)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_TMAX:
- adapter->temp_dcb_cfg.bcn.rp_tmax = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_tmax !=
- adapter->dcb_cfg.bcn.rp_tmax)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_TD:
- adapter->temp_dcb_cfg.bcn.rp_td = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_td !=
- adapter->dcb_cfg.bcn.rp_td)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_RMIN:
- adapter->temp_dcb_cfg.bcn.rp_rmin = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_rmin !=
- adapter->dcb_cfg.bcn.rp_rmin)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_W:
- adapter->temp_dcb_cfg.bcn.rp_w = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_w !=
- adapter->dcb_cfg.bcn.rp_w)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_RD:
- adapter->temp_dcb_cfg.bcn.rp_rd = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_rd !=
- adapter->dcb_cfg.bcn.rp_rd)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_RU:
- adapter->temp_dcb_cfg.bcn.rp_ru = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_ru !=
- adapter->dcb_cfg.bcn.rp_ru)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_WRTT:
- adapter->temp_dcb_cfg.bcn.rp_wrtt = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_wrtt !=
- adapter->dcb_cfg.bcn.rp_wrtt)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_RI:
- adapter->temp_dcb_cfg.bcn.rp_ri = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_ri !=
- adapter->dcb_cfg.bcn.rp_ri)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- default:
- break;
- }
-}
-
struct dcbnl_rtnl_ops dcbnl_ops = {
.getstate = ixgbe_dcbnl_get_state,
.setstate = ixgbe_dcbnl_set_state,
@@ -633,9 +440,5 @@ struct dcbnl_rtnl_ops dcbnl_ops = {
.setnumtcs = ixgbe_dcbnl_setnumtcs,
.getpfcstate = ixgbe_dcbnl_getpfcstate,
.setpfcstate = ixgbe_dcbnl_setpfcstate,
- .getbcncfg = ixgbe_dcbnl_getbcncfg,
- .getbcnrp = ixgbe_dcbnl_getbcnrp,
- .setbcncfg = ixgbe_dcbnl_setbcncfg,
- .setbcnrp = ixgbe_dcbnl_setbcnrp
};
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 67f87a79154..18ecba7f6ec 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -89,8 +89,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_header_split", IXGBE_STAT(rx_hdr_split)},
{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
- {"lro_aggregated", IXGBE_STAT(lro_aggregated)},
- {"lro_flushed", IXGBE_STAT(lro_flushed)},
+ {"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)},
};
#define IXGBE_QUEUE_STATS_LEN \
@@ -132,6 +131,26 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->advertising |= ADVERTISED_1000baseT_Full;
ecmd->port = PORT_TP;
+ } else if (hw->phy.media_type == ixgbe_media_type_backplane) {
+ /* Set as FIBRE until SERDES defined in kernel */
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598:
+ ecmd->supported |= (SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE);
+ ecmd->advertising = (ADVERTISED_10000baseT_Full |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_FIBRE);
+ ecmd->port = PORT_FIBRE;
+ break;
+ case IXGBE_DEV_ID_82598_BX:
+ ecmd->supported = (SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE);
+ ecmd->advertising = (ADVERTISED_1000baseT_Full |
+ ADVERTISED_FIBRE);
+ ecmd->port = PORT_FIBRE;
+ ecmd->autoneg = AUTONEG_DISABLE;
+ break;
+ }
} else {
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising = (ADVERTISED_10000baseT_Full |
@@ -206,13 +225,13 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
- pause->autoneg = (hw->fc.type == ixgbe_fc_full ? 1 : 0);
+ pause->autoneg = (hw->fc.current_mode == ixgbe_fc_full ? 1 : 0);
- if (hw->fc.type == ixgbe_fc_rx_pause) {
+ if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
pause->rx_pause = 1;
- } else if (hw->fc.type == ixgbe_fc_tx_pause) {
+ } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) {
pause->tx_pause = 1;
- } else if (hw->fc.type == ixgbe_fc_full) {
+ } else if (hw->fc.current_mode == ixgbe_fc_full) {
pause->rx_pause = 1;
pause->tx_pause = 1;
}
@@ -226,22 +245,17 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
if ((pause->autoneg == AUTONEG_ENABLE) ||
(pause->rx_pause && pause->tx_pause))
- hw->fc.type = ixgbe_fc_full;
+ hw->fc.requested_mode = ixgbe_fc_full;
else if (pause->rx_pause && !pause->tx_pause)
- hw->fc.type = ixgbe_fc_rx_pause;
+ hw->fc.requested_mode = ixgbe_fc_rx_pause;
else if (!pause->rx_pause && pause->tx_pause)
- hw->fc.type = ixgbe_fc_tx_pause;
+ hw->fc.requested_mode = ixgbe_fc_tx_pause;
else if (!pause->rx_pause && !pause->tx_pause)
- hw->fc.type = ixgbe_fc_none;
+ hw->fc.requested_mode = ixgbe_fc_none;
else
return -EINVAL;
- hw->fc.original_type = hw->fc.type;
-
- if (netif_running(netdev))
- ixgbe_reinit_locked(adapter);
- else
- ixgbe_reset(adapter);
+ hw->mac.ops.setup_fc(hw, 0);
return 0;
}
@@ -456,7 +470,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[825] = IXGBE_READ_REG(hw, IXGBE_IP6AT);
regs_buff[826] = IXGBE_READ_REG(hw, IXGBE_WUPL);
regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
- regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT);
+ regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0));
regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
@@ -661,10 +675,17 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ char firmware_version[32];
strncpy(drvinfo->driver, ixgbe_driver_name, 32);
strncpy(drvinfo->version, ixgbe_driver_version, 32);
- strncpy(drvinfo->fw_version, "N/A", 32);
+
+ sprintf(firmware_version, "%d.%d-%d",
+ (adapter->eeprom_version & 0xF000) >> 12,
+ (adapter->eeprom_version & 0x0FF0) >> 4,
+ adapter->eeprom_version & 0x000F);
+
+ strncpy(drvinfo->fw_version, firmware_version, 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = IXGBE_STATS_LEN;
drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
@@ -808,15 +829,6 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
int j, k;
int i;
- u64 aggregated = 0, flushed = 0, no_desc = 0;
- for (i = 0; i < adapter->num_rx_queues; i++) {
- aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
- flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
- no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
- }
- adapter->lro_aggregated = aggregated;
- adapter->lro_flushed = flushed;
- adapter->lro_no_desc = no_desc;
ixgbe_update_stats(adapter);
for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
@@ -897,12 +909,50 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
static void ixgbe_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
- wol->supported = 0;
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_UCAST | WAKE_MCAST |
+ WAKE_BCAST | WAKE_MAGIC;
wol->wolopts = 0;
+ if (!device_can_wakeup(&adapter->pdev->dev))
+ return;
+
+ if (adapter->wol & IXGBE_WUFC_EX)
+ wol->wolopts |= WAKE_UCAST;
+ if (adapter->wol & IXGBE_WUFC_MC)
+ wol->wolopts |= WAKE_MCAST;
+ if (adapter->wol & IXGBE_WUFC_BC)
+ wol->wolopts |= WAKE_BCAST;
+ if (adapter->wol & IXGBE_WUFC_MAG)
+ wol->wolopts |= WAKE_MAGIC;
+
return;
}
+static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+ return -EOPNOTSUPP;
+
+ adapter->wol = 0;
+
+ if (wol->wolopts & WAKE_UCAST)
+ adapter->wol |= IXGBE_WUFC_EX;
+ if (wol->wolopts & WAKE_MCAST)
+ adapter->wol |= IXGBE_WUFC_MC;
+ if (wol->wolopts & WAKE_BCAST)
+ adapter->wol |= IXGBE_WUFC_BC;
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= IXGBE_WUFC_MAG;
+
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+ return 0;
+}
+
static int ixgbe_nway_reset(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -965,40 +1015,47 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
int i;
if (ec->tx_max_coalesced_frames_irq)
adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq;
if (ec->rx_coalesce_usecs > 1) {
+ /* check the limits */
+ if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) ||
+ (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE))
+ return -EINVAL;
+
/* store the value in ints/second */
adapter->eitr_param = 1000000/ec->rx_coalesce_usecs;
/* static value of interrupt rate */
adapter->itr_setting = adapter->eitr_param;
- /* clear the lower bit */
+ /* clear the lower bit as its used for dynamic state */
adapter->itr_setting &= ~1;
} else if (ec->rx_coalesce_usecs == 1) {
/* 1 means dynamic mode */
adapter->eitr_param = 20000;
adapter->itr_setting = 1;
} else {
- /* any other value means disable eitr, which is best
- * served by setting the interrupt rate very high */
- adapter->eitr_param = 3000000;
+ /*
+ * any other value means disable eitr, which is best
+ * served by setting the interrupt rate very high
+ */
+ adapter->eitr_param = IXGBE_MAX_INT_RATE;
adapter->itr_setting = 0;
}
for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; 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_REG(hw, IXGBE_EITR(i),
- EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+ ixgbe_write_eitr(adapter, i,
+ EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
}
return 0;
@@ -1012,6 +1069,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_regs_len = ixgbe_get_regs_len,
.get_regs = ixgbe_get_regs,
.get_wol = ixgbe_get_wol,
+ .set_wol = ixgbe_set_wol,
.nway_reset = ixgbe_nway_reset,
.get_link = ethtool_op_get_link,
.get_eeprom_len = ixgbe_get_eeprom_len,
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index acef3c65cd2..79aa811c403 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -47,12 +47,13 @@ char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
-#define DRV_VERSION "1.3.30-k2"
+#define DRV_VERSION "2.0.8-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
-static char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation.";
+static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
static const struct ixgbe_info *ixgbe_info_tbl[] = {
[board_82598] = &ixgbe_82598_info,
+ [board_82599] = &ixgbe_82599_info,
};
/* ixgbe_pci_tbl - PCI Device ID Table
@@ -64,6 +65,8 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = {
* Class, Class Mask, private data (not used) }
*/
static struct pci_device_id ixgbe_pci_tbl[] = {
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598),
+ board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT),
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
@@ -82,6 +85,12 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_SFP_LOM),
board_82598 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_BX),
+ board_82598 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4),
+ board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
+ board_82599 },
/* required last entry */
{0, }
@@ -125,17 +134,53 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
}
-static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
- u8 msix_vector)
+/*
+ * ixgbe_set_ivar - set the IVAR registers, mapping interrupt causes to vectors
+ * @adapter: pointer to adapter struct
+ * @direction: 0 for Rx, 1 for Tx, -1 for other causes
+ * @queue: queue to map the corresponding interrupt to
+ * @msix_vector: the vector to map to the corresponding queue
+ *
+ */
+static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
+ u8 queue, u8 msix_vector)
{
u32 ivar, index;
-
- msix_vector |= IXGBE_IVAR_ALLOC_VAL;
- index = (int_alloc_entry >> 2) & 0x1F;
- ivar = IXGBE_READ_REG(&adapter->hw, IXGBE_IVAR(index));
- ivar &= ~(0xFF << (8 * (int_alloc_entry & 0x3)));
- ivar |= (msix_vector << (8 * (int_alloc_entry & 0x3)));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR(index), ivar);
+ struct ixgbe_hw *hw = &adapter->hw;
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+ if (direction == -1)
+ direction = 0;
+ index = (((direction * 64) + queue) >> 2) & 0x1F;
+ ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
+ ivar &= ~(0xFF << (8 * (queue & 0x3)));
+ ivar |= (msix_vector << (8 * (queue & 0x3)));
+ IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+ break;
+ case ixgbe_mac_82599EB:
+ if (direction == -1) {
+ /* other causes */
+ msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+ index = ((queue & 1) * 8);
+ ivar = IXGBE_READ_REG(&adapter->hw, IXGBE_IVAR_MISC);
+ ivar &= ~(0xFF << index);
+ ivar |= (msix_vector << index);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR_MISC, ivar);
+ break;
+ } else {
+ /* tx or rx causes */
+ msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+ index = ((16 * (queue & 1)) + (8 * direction));
+ ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(queue >> 1));
+ ivar &= ~(0xFF << index);
+ ivar |= (msix_vector << index);
+ IXGBE_WRITE_REG(hw, IXGBE_IVAR(queue >> 1), ivar);
+ break;
+ }
+ default:
+ break;
+ }
}
static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
@@ -200,39 +245,39 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
-#define GET_TX_HEAD_FROM_RING(ring) (\
- *(volatile u32 *) \
- ((union ixgbe_adv_tx_desc *)(ring)->desc + (ring)->count))
static void ixgbe_tx_timeout(struct net_device *netdev);
/**
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes
* @adapter: board private structure
* @tx_ring: tx ring to clean
+ *
+ * returns true if transmit work is done
**/
static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring)
{
- union ixgbe_adv_tx_desc *tx_desc;
- struct ixgbe_tx_buffer *tx_buffer_info;
struct net_device *netdev = adapter->netdev;
- struct sk_buff *skb;
- unsigned int i;
- u32 head, oldhead;
- unsigned int count = 0;
+ union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
+ struct ixgbe_tx_buffer *tx_buffer_info;
+ unsigned int i, eop, count = 0;
unsigned int total_bytes = 0, total_packets = 0;
- rmb();
- head = GET_TX_HEAD_FROM_RING(tx_ring);
- head = le32_to_cpu(head);
i = tx_ring->next_to_clean;
- while (1) {
- while (i != head) {
+ eop = tx_ring->tx_buffer_info[i].next_to_watch;
+ eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+
+ while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
+ (count < tx_ring->work_limit)) {
+ bool cleaned = false;
+ for ( ; !cleaned; count++) {
+ struct sk_buff *skb;
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
tx_buffer_info = &tx_ring->tx_buffer_info[i];
+ cleaned = (i == eop);
skb = tx_buffer_info->skb;
- if (skb) {
+ if (cleaned && skb) {
unsigned int segs, bytecount;
/* gso_segs is currently only valid for tcp */
@@ -247,23 +292,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
ixgbe_unmap_and_free_tx_resource(adapter,
tx_buffer_info);
+ tx_desc->wb.status = 0;
+
i++;
if (i == tx_ring->count)
i = 0;
-
- count++;
- if (count == tx_ring->count)
- goto done_cleaning;
}
- oldhead = head;
- rmb();
- head = GET_TX_HEAD_FROM_RING(tx_ring);
- head = le32_to_cpu(head);
- if (head == oldhead)
- goto done_cleaning;
- } /* while (1) */
-
-done_cleaning:
+
+ eop = tx_ring->tx_buffer_info[i].next_to_watch;
+ eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+ }
+
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
@@ -291,17 +330,16 @@ done_cleaning:
}
/* re-arm the interrupt */
- if ((total_packets >= tx_ring->work_limit) ||
- (count == tx_ring->count))
+ if (count >= tx_ring->work_limit)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->v_idx);
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
- tx_ring->stats.bytes += total_bytes;
tx_ring->stats.packets += total_packets;
+ tx_ring->stats.bytes += total_bytes;
adapter->net_stats.tx_bytes += total_bytes;
adapter->net_stats.tx_packets += total_packets;
- return (total_packets ? true : false);
+ return (count < tx_ring->work_limit);
}
#ifdef CONFIG_IXGBE_DCA
@@ -314,10 +352,19 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
if (rx_ring->cpu != cpu) {
rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q));
- rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
- rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
+ rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
+ rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+ IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
+ }
rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
+ rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
+ rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
rx_ring->cpu = cpu;
}
@@ -333,8 +380,14 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
if (tx_ring->cpu != cpu) {
txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q));
- txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
- txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
+ txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
+ txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+ IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+ }
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl);
tx_ring->cpu = cpu;
@@ -400,23 +453,21 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
* @rx_ring: rx descriptor ring (for a specific queue) to setup
* @rx_desc: rx descriptor
**/
-static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
+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;
+ struct napi_struct *napi = &q_vector->napi;
bool is_vlan = (status & IXGBE_RXD_STAT_VP);
u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
- if (adapter->netdev->features & NETIF_F_LRO &&
- skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ skb_record_rx_queue(skb, q_vector - &adapter->q_vector[0]);
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
if (adapter->vlgrp && is_vlan && (tag != 0))
- lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
- adapter->vlgrp, tag,
- rx_desc);
+ vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
else
- lro_receive_skb(&ring->lro_mgr, skb, rx_desc);
- ring->lro_used = true;
+ napi_gro_receive(napi, skb);
} else {
if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
if (adapter->vlgrp && is_vlan && (tag != 0))
@@ -467,6 +518,19 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
adapter->hw_csum_rx_good++;
}
+static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
+ struct ixgbe_ring *rx_ring, u32 val)
+{
+ /*
+ * Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch. (Only
+ * applicable for weak-ordered memory model archs,
+ * such as IA-64).
+ */
+ wmb();
+ IXGBE_WRITE_REG(hw, IXGBE_RDT(rx_ring->reg_idx), val);
+}
+
/**
* ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split
* @adapter: address of board private structure
@@ -479,6 +543,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
union ixgbe_adv_rx_desc *rx_desc;
struct ixgbe_rx_buffer *bi;
unsigned int i;
+ unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN;
i = rx_ring->next_to_use;
bi = &rx_ring->rx_buffer_info[i];
@@ -508,9 +573,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
if (!bi->skb) {
struct sk_buff *skb;
- skb = netdev_alloc_skb(adapter->netdev,
- (rx_ring->rx_buf_len +
- NET_IP_ALIGN));
+ skb = netdev_alloc_skb(adapter->netdev, bufsz);
if (!skb) {
adapter->alloc_rx_buff_failed++;
@@ -525,8 +588,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
skb_reserve(skb, NET_IP_ALIGN);
bi->skb = skb;
- bi->dma = pci_map_single(pdev, skb->data,
- rx_ring->rx_buf_len,
+ bi->dma = pci_map_single(pdev, skb->data, bufsz,
PCI_DMA_FROMDEVICE);
}
/* Refresh the desc even if buffer_addrs didn't change because
@@ -550,14 +612,7 @@ no_buffers:
if (i-- == 0)
i = (rx_ring->count - 1);
- /*
- * Force memory writes to complete before letting h/w
- * know there are new descriptors to fetch. (Only
- * applicable for weak-ordered memory model archs,
- * such as IA-64).
- */
- wmb();
- writel(i, adapter->hw.hw_addr + rx_ring->tail);
+ ixgbe_release_rx_desc(&adapter->hw, rx_ring, i);
}
}
@@ -571,10 +626,11 @@ 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 bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
+static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring,
int *work_done, int work_to_do)
{
+ struct ixgbe_adapter *adapter = q_vector->adapter;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -675,7 +731,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
total_rx_packets++;
skb->protocol = eth_type_trans(skb, adapter->netdev);
- ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
+ ixgbe_receive_skb(q_vector, skb, staterr, rx_desc);
next_desc:
rx_desc->wb.upper.status_error = 0;
@@ -693,11 +749,6 @@ next_desc:
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
- if (rx_ring->lro_used) {
- lro_flush_all(&rx_ring->lro_mgr);
- rx_ring->lro_used = false;
- }
-
rx_ring->next_to_clean = i;
cleaned_count = IXGBE_DESC_UNUSED(rx_ring);
@@ -728,7 +779,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
- /* Populate the IVAR table and set the ITR values to the
+ /*
+ * Populate the IVAR table and set the ITR values to the
* corresponding register.
*/
for (v_idx = 0; v_idx < q_vectors; v_idx++) {
@@ -739,7 +791,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
for (i = 0; i < q_vector->rxr_count; i++) {
j = adapter->rx_ring[r_idx].reg_idx;
- ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(j), v_idx);
+ ixgbe_set_ivar(adapter, 0, j, v_idx);
r_idx = find_next_bit(q_vector->rxr_idx,
adapter->num_rx_queues,
r_idx + 1);
@@ -749,7 +801,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
for (i = 0; i < q_vector->txr_count; i++) {
j = adapter->tx_ring[r_idx].reg_idx;
- ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(j), v_idx);
+ ixgbe_set_ivar(adapter, 1, j, v_idx);
r_idx = find_next_bit(q_vector->txr_idx,
adapter->num_tx_queues,
r_idx + 1);
@@ -758,15 +810,23 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
/* if this is a tx only vector halve the interrupt rate */
if (q_vector->txr_count && !q_vector->rxr_count)
q_vector->eitr = (adapter->eitr_param >> 1);
- else
+ else if (q_vector->rxr_count)
/* 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_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx);
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX,
+ v_idx);
+ else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ ixgbe_set_ivar(adapter, -1, 1, v_idx);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
/* set up to autoclear timer, and the vectors */
@@ -842,10 +902,35 @@ update_itr_done:
return retval;
}
+/**
+ * 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
+ *
+ * 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)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ /* must write high and low 16 bits to reset counter */
+ itr_reg |= (itr_reg << 16);
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ /*
+ * set the WDIS bit to not clear the timer bits and cause an
+ * immediate assertion of the interrupt
+ */
+ itr_reg |= IXGBE_EITR_CNT_WDIS;
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg);
+}
+
static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct ixgbe_hw *hw = &adapter->hw;
u32 new_itr;
u8 current_itr, ret_itr;
int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
@@ -900,14 +985,13 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
if (new_itr != q_vector->eitr) {
u32 itr_reg;
+
+ /* 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);
- q_vector->eitr = new_itr;
itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
- /* must write high and low 16 bits to reset counter */
- DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx,
- itr_reg);
- IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16);
+ ixgbe_write_eitr(adapter, v_idx, itr_reg);
}
return;
@@ -925,6 +1009,24 @@ static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
}
}
+static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (eicr & IXGBE_EICR_GPI_SDP1) {
+ /* Clear the interrupt */
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
+ schedule_work(&adapter->multispeed_fiber_task);
+ } else if (eicr & IXGBE_EICR_GPI_SDP2) {
+ /* Clear the interrupt */
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
+ schedule_work(&adapter->sfp_config_module_task);
+ } else {
+ /* Interrupt isn't for us... */
+ return;
+ }
+}
+
static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -943,13 +1045,25 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
struct net_device *netdev = data;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
- u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
+ u32 eicr;
+
+ /*
+ * Workaround for Silicon errata. Use clear-by-write instead
+ * of clear-by-read. Reading with EICS will return the
+ * interrupt causes without clearing, which later be done
+ * with the write to EICR.
+ */
+ eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
if (eicr & IXGBE_EICR_LSC)
ixgbe_check_lsc(adapter);
- ixgbe_check_fan_failure(adapter, eicr);
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ ixgbe_check_fan_failure(adapter, eicr);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_check_sfp_event(adapter, eicr);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -1012,7 +1126,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
rx_ring = &(adapter->rx_ring[r_idx]);
/* disable interrupts on this vector only */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
- netif_rx_schedule(&q_vector->napi);
+ napi_schedule(&q_vector->napi);
return IRQ_HANDLED;
}
@@ -1049,12 +1163,12 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
ixgbe_update_rx_dca(adapter, rx_ring);
#endif
- ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+ ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
- if (adapter->itr_setting & 3)
+ 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, rx_ring->v_idx);
@@ -1092,7 +1206,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_rx_dca(adapter, rx_ring);
#endif
- ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+ ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
enable_mask |= rx_ring->v_idx;
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
r_idx + 1);
@@ -1102,8 +1216,8 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
rx_ring = &(adapter->rx_ring[r_idx]);
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
- if (adapter->itr_setting & 3)
+ 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);
@@ -1273,7 +1387,6 @@ out:
static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
{
- struct ixgbe_hw *hw = &adapter->hw;
struct ixgbe_q_vector *q_vector = adapter->q_vector;
u8 current_itr;
u32 new_itr = q_vector->eitr;
@@ -1308,35 +1421,19 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
if (new_itr != q_vector->eitr) {
u32 itr_reg;
+
+ /* 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);
- q_vector->eitr = new_itr;
itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
- /* must write high and low 16 bits to reset counter */
- IXGBE_WRITE_REG(hw, IXGBE_EITR(0), itr_reg | (itr_reg)<<16);
+ ixgbe_write_eitr(adapter, 0, itr_reg);
}
return;
}
/**
- * ixgbe_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- **/
-static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
-{
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
- IXGBE_WRITE_FLUSH(&adapter->hw);
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- int i;
- for (i = 0; i < adapter->num_msix_vectors; i++)
- synchronize_irq(adapter->msix_entries[i].vector);
- } else {
- synchronize_irq(adapter->pdev->irq);
- }
-}
-
-/**
* ixgbe_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
**/
@@ -1346,7 +1443,21 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
mask = IXGBE_EIMS_ENABLE_MASK;
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
mask |= IXGBE_EIMS_GPI_SDP1;
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ mask |= IXGBE_EIMS_ECC;
+ mask |= IXGBE_EIMS_GPI_SDP1;
+ mask |= IXGBE_EIMS_GPI_SDP2;
+ }
+
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_WRITE_FLUSH(&adapter->hw);
}
@@ -1362,6 +1473,12 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr;
+ /*
+ * Workaround for silicon errata. Mask the interrupts
+ * before the read of EICR.
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
+
/* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read
* therefore no explict interrupt disable is necessary */
eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
@@ -1376,15 +1493,18 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
if (eicr & IXGBE_EICR_LSC)
ixgbe_check_lsc(adapter);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_check_sfp_event(adapter, eicr);
+
ixgbe_check_fan_failure(adapter, eicr);
- if (netif_rx_schedule_prep(&adapter->q_vector[0].napi)) {
+ if (napi_schedule_prep(&adapter->q_vector[0].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 */
- __netif_rx_schedule(&adapter->q_vector[0].napi);
+ __napi_schedule(&adapter->q_vector[0].napi);
}
return IRQ_HANDLED;
@@ -1456,6 +1576,39 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
}
/**
+ * ixgbe_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ **/
+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) {
+ 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) {
+ int i;
+ for (i = 0; i < adapter->num_msix_vectors; i++)
+ synchronize_irq(adapter->msix_entries[i].vector);
+ } else {
+ synchronize_irq(adapter->pdev->irq);
+ }
+}
+
+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
*
**/
@@ -1466,8 +1619,8 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param));
- ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0);
- ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(0), 0);
+ ixgbe_set_ivar(adapter, 0, 0, 0);
+ ixgbe_set_ivar(adapter, 1, 0, 0);
map_vector_to_rxq(adapter, 0, 0);
map_vector_to_txq(adapter, 0, 0);
@@ -1483,7 +1636,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
**/
static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
{
- u64 tdba, tdwba;
+ u64 tdba;
struct ixgbe_hw *hw = &adapter->hw;
u32 i, j, tdlen, txctrl;
@@ -1496,11 +1649,6 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
(tdba & DMA_32BIT_MASK));
IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
- tdwba = ring->dma +
- (ring->count * sizeof(union ixgbe_adv_tx_desc));
- tdwba |= IXGBE_TDWBAL_HEAD_WB_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_TDWBAL(j), tdwba & DMA_32BIT_MASK);
- IXGBE_WRITE_REG(hw, IXGBE_TDWBAH(j), (tdwba >> 32));
IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
@@ -1513,26 +1661,25 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
}
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ /* We enable 8 traffic classes, DCB only */
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_RT_ENA |
+ IXGBE_MTQC_8TC_8TQ));
+ }
}
-#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
+#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
{
struct ixgbe_ring *rx_ring;
u32 srrctl;
- int queue0;
+ int queue0 = 0;
unsigned long mask;
- /* program one srrctl register per VMDq index */
- if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) {
- long shift, len;
- mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
- len = sizeof(adapter->ring_feature[RING_F_VMDQ].mask) * 8;
- shift = find_first_bit(&mask, len);
- queue0 = index & mask;
- index = (index & mask) >> shift;
- /* program one srrctl per RSS queue since RDRXCTL.MVMEN is enabled */
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ queue0 = index;
} else {
mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
queue0 = index & mask;
@@ -1547,7 +1694,14 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
- srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+ 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;
srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
srrctl |= ((IXGBE_RX_HDR_SIZE <<
IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
@@ -1562,39 +1716,10 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
srrctl |= rx_ring->rx_buf_len >>
IXGBE_SRRCTL_BSIZEPKT_SHIFT;
}
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
-}
-/**
- * ixgbe_get_skb_hdr - helper function for LRO header processing
- * @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to ip header structure
- * @tcph: pointer to tcp header structure
- * @hdr_flags: pointer to header flags
- * @priv: private data
- **/
-static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
- u64 *hdr_flags, void *priv)
-{
- union ixgbe_adv_rx_desc *rx_desc = priv;
-
- /* Verify that this is a valid IPv4 TCP packet */
- if (!((ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_IPV4) &&
- (ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_TCP)))
- return -1;
-
- /* Set network headers */
- skb_reset_network_header(skb);
- skb_set_transport_header(skb, ip_hdrlen(skb));
- *iphdr = ip_hdr(skb);
- *tcph = tcp_hdr(skb);
- *hdr_flags = LRO_IPV4 | LRO_TCP;
- return 0;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
}
-#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
- (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
-
/**
* ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
* @adapter: board private structure
@@ -1613,8 +1738,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
0x6A3E67EA, 0x14364D17, 0x3BED200D};
u32 fctrl, hlreg0;
- u32 pages;
- u32 reta = 0, mrqc;
+ u32 reta = 0, mrqc = 0;
u32 rdrxctl;
int rx_buf_len;
@@ -1624,6 +1748,14 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
/* Set the RX buffer length according to the mode */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
rx_buf_len = IXGBE_RX_HDR_SIZE;
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ /* PSRTYPE must be initialized in 82599 */
+ u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
+ IXGBE_PSRTYPE_UDPHDR |
+ IXGBE_PSRTYPE_IPV4HDR |
+ IXGBE_PSRTYPE_IPV6HDR;
+ IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
+ }
} else {
if (netdev->mtu <= ETH_DATA_LEN)
rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
@@ -1634,6 +1766,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
fctrl |= IXGBE_FCTRL_BAM;
fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
+ fctrl |= IXGBE_FCTRL_PMCF;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
@@ -1643,8 +1776,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
hlreg0 |= IXGBE_HLREG0_JUMBOEN;
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
- pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-
rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
/* disable receives while setting up the descriptors */
rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
@@ -1663,37 +1794,44 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
adapter->rx_ring[i].head = IXGBE_RDH(j);
adapter->rx_ring[i].tail = IXGBE_RDT(j);
adapter->rx_ring[i].rx_buf_len = rx_buf_len;
- /* Intitial LRO Settings */
- adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
- adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
- adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr;
- adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID;
- if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
- adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI;
- adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
- adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
- adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
ixgbe_configure_srrctl(adapter, j);
}
- /*
- * For VMDq support of different descriptor types or
- * buffer sizes through the use of multiple SRRCTL
- * registers, RDRXCTL.MVMEN must be set to 1
- *
- * also, the manual doesn't mention it clearly but DCA hints
- * will only use queue 0's tags unless this bit is set. Side
- * effects of setting this bit are only that SRRCTL must be
- * fully programmed [0..15]
- */
- if (adapter->flags &
- (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_VMDQ_ENABLED)) {
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ /*
+ * For VMDq support of different descriptor types or
+ * buffer sizes through the use of multiple SRRCTL
+ * registers, RDRXCTL.MVMEN must be set to 1
+ *
+ * also, the manual doesn't mention it clearly but DCA hints
+ * will only use queue 0's tags unless this bit is set. Side
+ * effects of setting this bit are only that SRRCTL must be
+ * fully programmed [0..15]
+ */
rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
rdrxctl |= IXGBE_RDRXCTL_MVMEN;
IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
}
+ /* 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
+ );
+
+ 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++) {
@@ -1710,19 +1848,17 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
for (i = 0; i < 10; i++)
IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
- mrqc = IXGBE_MRQC_RSSEN
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ mrqc |= IXGBE_MRQC_RSSEN;
/* Perform hash on these packet types */
- | IXGBE_MRQC_RSS_FIELD_IPV4
- | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX
- | IXGBE_MRQC_RSS_FIELD_IPV6
- | IXGBE_MRQC_RSS_FIELD_IPV6_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6_UDP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP;
- IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
+ mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4
+ | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
+ | IXGBE_MRQC_RSS_FIELD_IPV6
+ | IXGBE_MRQC_RSS_FIELD_IPV6_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
}
+ IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
@@ -1739,38 +1875,12 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
}
IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
-}
-
-static void ixgbe_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u32 ctrl;
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_disable(adapter);
- adapter->vlgrp = grp;
-
- /*
- * For a DCB driver, always enable VLAN tag stripping so we can
- * still receive traffic from a DCB-enabled host even if we're
- * not in DCB mode.
- */
- ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
- ctrl |= IXGBE_VLNCTRL_VME;
- ctrl &= ~IXGBE_VLNCTRL_CFIEN;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
- if (grp) {
- /* enable VLAN tag insert/strip */
- ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
- ctrl |= IXGBE_VLNCTRL_VME;
- ctrl &= ~IXGBE_VLNCTRL_CFIEN;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+ rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+ IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
}
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable(adapter);
}
static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -1799,6 +1909,46 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
}
+static void ixgbe_vlan_rx_register(struct net_device *netdev,
+ struct vlan_group *grp)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ u32 ctrl;
+ int i, j;
+
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_disable(adapter);
+ adapter->vlgrp = grp;
+
+ /*
+ * For a DCB driver, always enable VLAN tag stripping so we can
+ * still receive traffic from a DCB-enabled host even if we're
+ * not in DCB mode.
+ */
+ ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ ctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
+ ctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ ctrl |= IXGBE_VLNCTRL_VFE;
+ /* enable VLAN tag insert/strip */
+ ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
+ ctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ j = adapter->rx_ring[i].reg_idx;
+ ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(j));
+ ctrl |= IXGBE_RXDCTL_VME;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(j), ctrl);
+ }
+ }
+ ixgbe_vlan_rx_add_vid(netdev, 0);
+
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_enable(adapter);
+}
+
static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
{
ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp);
@@ -1956,9 +2106,21 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
}
/* Enable VLAN tag insert/strip */
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
- vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
- vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
+ vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+ } else if (hw->mac.type == ixgbe_mac_82599EB) {
+ vlnctrl |= IXGBE_VLNCTRL_VFE;
+ vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ j = adapter->rx_ring[i].reg_idx;
+ vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
+ vlnctrl |= IXGBE_RXDCTL_VME;
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
+ }
+ }
hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
}
@@ -1989,13 +2151,115 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
(adapter->rx_ring[i].count - 1));
}
+static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
+{
+ switch (hw->phy.type) {
+ case ixgbe_phy_sfp_avago:
+ case ixgbe_phy_sfp_ftl:
+ case ixgbe_phy_sfp_intel:
+ case ixgbe_phy_sfp_unknown:
+ case ixgbe_phy_tw_tyco:
+ case ixgbe_phy_tw_unknown:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * ixgbe_sfp_link_config - set up SFP+ link
+ * @adapter: pointer to private adapter struct
+ **/
+static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (hw->phy.multispeed_fiber) {
+ /*
+ * In multispeed fiber setups, the device may not have
+ * had a physical connection when the driver loaded.
+ * If that's the case, the initial link configuration
+ * couldn't get the MAC into 10G or 1G mode, so we'll
+ * never have a link status change interrupt fire.
+ * We need to try and force an autonegotiation
+ * session, then bring up link.
+ */
+ hw->mac.ops.setup_sfp(hw);
+ if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
+ schedule_work(&adapter->multispeed_fiber_task);
+ } else {
+ /*
+ * Direct Attach Cu and non-multispeed fiber modules
+ * still need to be configured properly prior to
+ * attempting link.
+ */
+ if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK))
+ schedule_work(&adapter->sfp_config_module_task);
+ }
+}
+
+/**
+ * ixgbe_non_sfp_link_config - set up non-SFP+ link
+ * @hw: pointer to private hardware struct
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
+{
+ u32 autoneg;
+ bool link_up = false;
+ u32 ret = IXGBE_ERR_LINK_SETUP;
+
+ if (hw->mac.ops.check_link)
+ ret = hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
+
+ if (ret)
+ goto link_cfg_out;
+
+ if (hw->mac.ops.get_link_capabilities)
+ ret = hw->mac.ops.get_link_capabilities(hw, &autoneg,
+ &hw->mac.autoneg);
+ if (ret)
+ goto link_cfg_out;
+
+ if (hw->mac.ops.setup_link_speed)
+ ret = hw->mac.ops.setup_link_speed(hw, autoneg, true, link_up);
+link_cfg_out:
+ return ret;
+}
+
+#define IXGBE_MAX_RX_DESC_POLL 10
+static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
+ int rxr)
+{
+ int j = adapter->rx_ring[rxr].reg_idx;
+ int k;
+
+ for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) {
+ if (IXGBE_READ_REG(&adapter->hw,
+ IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
+ break;
+ else
+ msleep(1);
+ }
+ if (k >= IXGBE_MAX_RX_DESC_POLL) {
+ DPRINTK(DRV, ERR, "RXDCTL.ENABLE on Rx queue %d "
+ "not set within the polling period\n", rxr);
+ }
+ ixgbe_release_rx_desc(&adapter->hw, &adapter->rx_ring[rxr],
+ (adapter->rx_ring[rxr].count - 1));
+}
+
static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
int i, j = 0;
+ int num_rx_rings = adapter->num_rx_queues;
+ int err;
int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
u32 txdctl, rxdctl, mhadd;
+ u32 dmatxctl;
u32 gpie;
ixgbe_get_hw_control(adapter);
@@ -2027,6 +2291,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
}
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+ gpie |= IXGBE_SDP1_GPIEN;
+ gpie |= IXGBE_SDP2_GPIEN;
+ IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+ }
+
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
mhadd &= ~IXGBE_MHADD_MFS_MASK;
@@ -2040,11 +2311,23 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
/* enable WTHRESH=8 descriptors, to encourage burst writeback */
txdctl |= (8 << 16);
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
+ }
+
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ /* DMATXCTL.EN must be set after all Tx queue config is done */
+ dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+ dmatxctl |= IXGBE_DMATXCTL_TE;
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
+ }
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ j = adapter->tx_ring[i].reg_idx;
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
txdctl |= IXGBE_TXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
}
- for (i = 0; i < adapter->num_rx_queues; i++) {
+ for (i = 0; i < num_rx_rings; i++) {
j = adapter->rx_ring[i].reg_idx;
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
/* enable PTHRESH=32 descriptors (half the internal cache)
@@ -2053,19 +2336,22 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
rxdctl |= 0x0020;
rxdctl |= IXGBE_RXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_rx_desc_queue_enable(adapter, i);
}
/* enable all receives */
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
- rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN);
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxdctl);
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN);
+ else
+ rxdctl |= IXGBE_RXCTRL_RXEN;
+ hw->mac.ops.enable_rx_dma(hw, rxdctl);
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
ixgbe_configure_msix(adapter);
else
ixgbe_configure_msi_and_legacy(adapter);
- ixgbe_napi_add_all(adapter);
-
clear_bit(__IXGBE_DOWN, &adapter->state);
ixgbe_napi_enable_all(adapter);
@@ -2074,6 +2360,31 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
ixgbe_irq_enable(adapter);
+ /*
+ * 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.
+ * If we're not hot-pluggable SFP+, we just need to configure link
+ * and bring it up.
+ */
+ err = hw->phy.ops.identify(hw);
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err);
+ ixgbe_down(adapter);
+ return err;
+ }
+
+ if (ixgbe_is_sfp(hw)) {
+ ixgbe_sfp_link_config(adapter);
+ } else {
+ err = ixgbe_non_sfp_link_config(hw);
+ if (err)
+ DPRINTK(PROBE, ERR, "link_config FAILED %d\n", err);
+ }
+
+ /* enable transmits */
+ netif_tx_start_all_queues(netdev);
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -2097,6 +2408,8 @@ 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);
}
@@ -2158,8 +2471,10 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
- writel(0, adapter->hw.hw_addr + rx_ring->head);
- writel(0, adapter->hw.hw_addr + rx_ring->tail);
+ if (rx_ring->head)
+ writel(0, adapter->hw.hw_addr + rx_ring->head);
+ if (rx_ring->tail)
+ writel(0, adapter->hw.hw_addr + rx_ring->tail);
}
/**
@@ -2190,8 +2505,10 @@ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- writel(0, adapter->hw.hw_addr + tx_ring->head);
- writel(0, adapter->hw.hw_addr + tx_ring->tail);
+ if (tx_ring->head)
+ writel(0, adapter->hw.hw_addr + tx_ring->head);
+ if (tx_ring->tail)
+ writel(0, adapter->hw.hw_addr + tx_ring->tail);
}
/**
@@ -2254,6 +2571,11 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
(txdctl & ~IXGBE_TXDCTL_ENABLE));
}
+ /* Disable the Tx DMA engine on 82599 */
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
+ (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
+ ~IXGBE_DMATXCTL_TE));
netif_carrier_off(netdev);
@@ -2290,10 +2612,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
**/
static int ixgbe_poll(struct napi_struct *napi, int budget)
{
- struct ixgbe_q_vector *q_vector = container_of(napi,
- struct ixgbe_q_vector, napi);
+ struct ixgbe_q_vector *q_vector =
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
- int tx_cleaned, work_done = 0;
+ int tx_clean_complete, work_done = 0;
#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
@@ -2302,19 +2624,19 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
}
#endif
- tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
- ixgbe_clean_rx_irq(adapter, adapter->rx_ring, &work_done, budget);
+ tx_clean_complete = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
+ ixgbe_clean_rx_irq(q_vector, adapter->rx_ring, &work_done, budget);
- if (tx_cleaned)
+ if (!tx_clean_complete)
work_done = budget;
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
- if (adapter->itr_setting & 3)
+ napi_complete(napi);
+ if (adapter->itr_setting & 1)
ixgbe_set_itr(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable(adapter);
+ ixgbe_irq_enable_queues(adapter);
}
return work_done;
}
@@ -2346,68 +2668,76 @@ static void ixgbe_reset_task(struct work_struct *work)
ixgbe_reinit_locked(adapter);
}
-static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+#ifdef CONFIG_IXGBE_DCB
+static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
{
- int nrq = 1, ntq = 1;
- int feature_mask = 0, rss_i, rss_m;
- int dcb_i, dcb_m;
+ bool ret = false;
- /* Number of supported queues */
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- dcb_i = adapter->ring_feature[RING_F_DCB].indices;
- dcb_m = 0;
- rss_i = adapter->ring_feature[RING_F_RSS].indices;
- rss_m = 0;
- feature_mask |= IXGBE_FLAG_RSS_ENABLED;
- feature_mask |= IXGBE_FLAG_DCB_ENABLED;
-
- switch (adapter->flags & feature_mask) {
- case (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_DCB_ENABLED):
- dcb_m = 0x7 << 3;
- rss_i = min(8, rss_i);
- rss_m = 0x7;
- nrq = dcb_i * rss_i;
- ntq = min(MAX_TX_QUEUES, dcb_i * rss_i);
- break;
- case (IXGBE_FLAG_DCB_ENABLED):
- dcb_m = 0x7 << 3;
- nrq = dcb_i;
- ntq = dcb_i;
- break;
- case (IXGBE_FLAG_RSS_ENABLED):
- rss_m = 0xF;
- nrq = rss_i;
- ntq = rss_i;
- break;
- case 0:
- default:
- dcb_i = 0;
- dcb_m = 0;
- rss_i = 0;
- rss_m = 0;
- nrq = 1;
- ntq = 1;
- break;
- }
+ 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;
+ }
- /* Sanity check, we should never have zero queues */
- nrq = (nrq ?:1);
- ntq = (ntq ?:1);
+ return ret;
+}
+#endif
- adapter->ring_feature[RING_F_DCB].indices = dcb_i;
- adapter->ring_feature[RING_F_DCB].mask = dcb_m;
- adapter->ring_feature[RING_F_RSS].indices = rss_i;
- adapter->ring_feature[RING_F_RSS].mask = rss_m;
- break;
- default:
- nrq = 1;
- ntq = 1;
- break;
+/**
+ * ixgbe_set_rss_queues: Allocate queues for RSS
+ * @adapter: board private structure to initialize
+ *
+ * This is our "base" multiqueue mode. RSS (Receive Side Scaling) will try
+ * to allocate one Rx queue per CPU, and if available, one Tx queue per CPU.
+ *
+ **/
+static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
+{
+ bool ret = false;
+
+ 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;
+ ret = true;
+ } else {
+ ret = false;
}
- adapter->num_rx_queues = nrq;
- adapter->num_tx_queues = ntq;
+ return ret;
+}
+
+/*
+ * ixgbe_set_num_queues: Allocate queues for device, feature dependant
+ * @adapter: board private structure to initialize
+ *
+ * This is the top level queue allocation routine. The order here is very
+ * important, starting with the "most" number of features turned on at once,
+ * and ending with the smallest set of features. This way large combinations
+ * can be allocated if they're turned on, and smaller combinations are the
+ * fallthrough conditions.
+ *
+ **/
+static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+{
+ /* Start with base case */
+ adapter->num_rx_queues = 1;
+ adapter->num_tx_queues = 1;
+
+#ifdef CONFIG_IXGBE_DCB
+ if (ixgbe_set_dcb_queues(adapter))
+ return;
+
+#endif
+ if (ixgbe_set_rss_queues(adapter))
+ return;
}
static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
@@ -2453,71 +2783,104 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
ixgbe_set_num_queues(adapter);
} else {
adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
- adapter->num_msix_vectors = vectors;
+ /*
+ * Adjust for only the vectors we'll use, which is minimum
+ * of max_msix_q_vectors + NON_Q_VECTORS, or the number of
+ * vectors we were allocated.
+ */
+ adapter->num_msix_vectors = min(vectors,
+ adapter->max_msix_q_vectors + NON_Q_VECTORS);
}
}
/**
- * ixgbe_cache_ring_register - Descriptor ring to register mapping
+ * ixgbe_cache_ring_rss - Descriptor ring to register mapping for RSS
* @adapter: board private structure to initialize
*
- * Once we know the feature-set enabled for the device, we'll cache
- * the register offset the descriptor ring is assigned to.
+ * Cache the descriptor ring offsets for RSS to the assigned rings.
+ *
**/
-static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
+static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter)
{
- int feature_mask = 0, rss_i;
- int i, txr_idx, rxr_idx;
- int dcb_i;
+ int i;
+ bool ret = false;
- /* Number of supported queues */
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- dcb_i = adapter->ring_feature[RING_F_DCB].indices;
- rss_i = adapter->ring_feature[RING_F_RSS].indices;
- txr_idx = 0;
- rxr_idx = 0;
- feature_mask |= IXGBE_FLAG_DCB_ENABLED;
- feature_mask |= IXGBE_FLAG_RSS_ENABLED;
- switch (adapter->flags & feature_mask) {
- case (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_DCB_ENABLED):
- for (i = 0; i < dcb_i; i++) {
- int j;
- /* Rx first */
- for (j = 0; j < adapter->num_rx_queues; j++) {
- adapter->rx_ring[rxr_idx].reg_idx =
- i << 3 | j;
- rxr_idx++;
- }
- /* Tx now */
- for (j = 0; j < adapter->num_tx_queues; j++) {
- adapter->tx_ring[txr_idx].reg_idx =
- i << 2 | (j >> 1);
- if (j & 1)
- txr_idx++;
- }
- }
- case (IXGBE_FLAG_DCB_ENABLED):
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+ 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;
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_IXGBE_DCB
+/**
+ * ixgbe_cache_ring_dcb - Descriptor ring to register mapping for DCB
+ * @adapter: board private structure to initialize
+ *
+ * Cache the descriptor ring offsets for DCB to the assigned rings.
+ *
+ **/
+static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
+{
+ int i;
+ bool ret = false;
+ int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
/* the number of queues is assumed to be symmetric */
for (i = 0; i < dcb_i; i++) {
adapter->rx_ring[i].reg_idx = i << 3;
adapter->tx_ring[i].reg_idx = i << 2;
}
- break;
- case (IXGBE_FLAG_RSS_ENABLED):
- 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;
- break;
- case 0:
- default:
- break;
+ ret = true;
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ for (i = 0; i < dcb_i; i++) {
+ adapter->rx_ring[i].reg_idx = i << 4;
+ adapter->tx_ring[i].reg_idx = i << 4;
+ }
+ ret = true;
+ } else {
+ ret = false;
}
- break;
- default:
- break;
+ } else {
+ ret = false;
}
+
+ return ret;
+}
+#endif
+
+/**
+ * ixgbe_cache_ring_register - Descriptor ring to register mapping
+ * @adapter: board private structure to initialize
+ *
+ * Once we know the feature-set enabled for the device, we'll cache
+ * the register offset the descriptor ring is assigned to.
+ *
+ * Note, the order the various feature calls is important. It must start with
+ * the "most" features enabled at the same time, then trickle down to the
+ * least amount of features turned on at once.
+ **/
+static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
+{
+ /* start with default case */
+ adapter->rx_ring[0].reg_idx = 0;
+ adapter->tx_ring[0].reg_idx = 0;
+
+#ifdef CONFIG_IXGBE_DCB
+ if (ixgbe_cache_ring_dcb(adapter))
+ return;
+
+#endif
+ if (ixgbe_cache_ring_rss(adapter))
+ return;
}
/**
@@ -2525,7 +2888,8 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
* @adapter: board private structure to initialize
*
* We allocate one ring per queue at run-time since we don't know the
- * number of queues at compile-time.
+ * number of queues at compile-time. The polling_netdev array is
+ * intended for Multiqueue, but should work fine with a single queue.
**/
static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
{
@@ -2704,7 +3068,8 @@ static void ixgbe_sfp_timer(unsigned long data)
{
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
- /* Do the sfp_timer outside of interrupt context due to the
+ /*
+ * Do the sfp_timer outside of interrupt context due to the
* delays that sfp+ detection requires
*/
schedule_work(&adapter->sfp_task);
@@ -2778,6 +3143,10 @@ 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)
+ adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598;
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
#ifdef CONFIG_IXGBE_DCB
/* Configure DCB traffic classes */
@@ -2798,21 +3167,14 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->ring_feature[RING_F_DCB].indices);
#endif
- if (hw->mac.ops.get_media_type &&
- (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper))
- adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
/* default flow control settings */
- hw->fc.original_type = ixgbe_fc_none;
- hw->fc.type = ixgbe_fc_none;
+ hw->fc.requested_mode = ixgbe_fc_none;
hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
hw->fc.send_xon = true;
- /* select 10G link by default */
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
-
/* enable itr by default in dynamic mode */
adapter->itr_setting = 1;
adapter->eitr_param = 20000;
@@ -2859,8 +3221,7 @@ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
memset(tx_ring->tx_buffer_info, 0, size);
/* round up to nearest 4K */
- tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc) +
- sizeof(u32);
+ tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
@@ -2919,12 +3280,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
struct pci_dev *pdev = adapter->pdev;
int size;
- size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS;
- rx_ring->lro_mgr.lro_arr = vmalloc(size);
- if (!rx_ring->lro_mgr.lro_arr)
- return -ENOMEM;
- memset(rx_ring->lro_mgr.lro_arr, 0, size);
-
size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
rx_ring->rx_buffer_info = vmalloc(size);
if (!rx_ring->rx_buffer_info) {
@@ -2953,8 +3308,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
return 0;
alloc_failed:
- vfree(rx_ring->lro_mgr.lro_arr);
- rx_ring->lro_mgr.lro_arr = NULL;
return -ENOMEM;
}
@@ -3017,7 +3370,8 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
+ if (adapter->tx_ring[i].desc)
+ ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
}
/**
@@ -3032,9 +3386,6 @@ void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
{
struct pci_dev *pdev = adapter->pdev;
- vfree(rx_ring->lro_mgr.lro_arr);
- rx_ring->lro_mgr.lro_arr = NULL;
-
ixgbe_clean_rx_ring(adapter, rx_ring);
vfree(rx_ring->rx_buffer_info);
@@ -3056,7 +3407,8 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
+ if (adapter->rx_ring[i].desc)
+ ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
}
/**
@@ -3119,6 +3471,8 @@ 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;
@@ -3173,6 +3527,7 @@ static int ixgbe_close(struct net_device *netdev)
/**
* 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)
@@ -3245,7 +3600,6 @@ static int ixgbe_resume(struct pci_dev *pdev)
return err;
}
- ixgbe_napi_add_all(adapter);
ixgbe_reset(adapter);
if (netif_running(netdev)) {
@@ -3264,6 +3618,9 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 ctrl, fctrl;
+ u32 wufc = adapter->wol;
#ifdef CONFIG_PM
int retval = 0;
#endif
@@ -3286,10 +3643,35 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
retval = pci_save_state(pdev);
if (retval)
return retval;
+
#endif
+ if (wufc) {
+ ixgbe_set_rx_mode(netdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ /* turn on all-multi mode if wake on multicast is enabled */
+ if (wufc & IXGBE_WUFC_MC) {
+ fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ fctrl |= IXGBE_FCTRL_MPE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+ }
+
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ ctrl |= IXGBE_CTRL_GIO_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
+
+ IXGBE_WRITE_REG(hw, IXGBE_WUFC, wufc);
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_WUC, 0);
+ 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);
+ }
ixgbe_release_hw_control(adapter);
@@ -3315,6 +3697,12 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
u64 total_mpc = 0;
u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ for (i = 0; i < 16; i++)
+ adapter->hw_rx_no_dma_resources +=
+ IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ }
+
adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
for (i = 0; i < 8; i++) {
/* for packet buffers not used, the register should read 0 */
@@ -3322,32 +3710,55 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
missed_rx += mpc;
adapter->stats.mpc[i] += mpc;
total_mpc += adapter->stats.mpc[i];
- adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
- adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXONRXC(i));
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
+ IXGBE_PXONRXCNT(i));
+ adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
+ IXGBE_PXOFFRXCNT(i));
+ adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ } else {
+ adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
+ IXGBE_PXONRXC(i));
+ adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
+ IXGBE_PXOFFRXC(i));
+ }
adapter->stats.pxontxc[i] += IXGBE_READ_REG(hw,
IXGBE_PXONTXC(i));
- adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFRXC(i));
adapter->stats.pxofftxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFTXC(i));
+ IXGBE_PXOFFTXC(i));
}
adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
/* work around hardware counting issue */
adapter->stats.gprc -= missed_rx;
/* 82598 hardware only has a 32 bit counter in the high register */
- adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
- adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
- adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
+ IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
+ adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
+ IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */
+ adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
+ IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
+ adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
+ adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+ } else {
+ adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
+ adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+ adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
+ adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
+ adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+ }
bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
adapter->stats.bprc += bprc;
adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
- adapter->stats.mprc -= bprc;
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ adapter->stats.mprc -= bprc;
adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC);
adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
@@ -3356,8 +3767,6 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
- adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
- adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
adapter->stats.lxontxc += lxon;
lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
@@ -3409,17 +3818,54 @@ static void ixgbe_watchdog(unsigned long data)
/* 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;
+
+ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++)
+ eics |= (1 << i);
+
/* Cause software interrupt to ensure rx rings are cleaned */
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- u32 eics =
- (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
- IXGBE_WRITE_REG(hw, IXGBE_EICS, 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));
+ 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,
@@ -3430,6 +3876,55 @@ static void ixgbe_watchdog(unsigned long data)
}
/**
+ * ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_multispeed_fiber_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ multispeed_fiber_task);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 autoneg;
+
+ adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK;
+ if (hw->mac.ops.get_link_capabilities)
+ hw->mac.ops.get_link_capabilities(hw, &autoneg,
+ &hw->mac.autoneg);
+ if (hw->mac.ops.setup_link_speed)
+ hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+ adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK;
+}
+
+/**
+ * ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_sfp_config_module_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ sfp_config_module_task);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 err;
+
+ adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK;
+ err = hw->phy.ops.identify_sfp(hw);
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err);
+ ixgbe_down(adapter);
+ return;
+ }
+ hw->mac.ops.setup_sfp(hw);
+
+ if (!adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)
+ /* This will also work for DA Twinax connections */
+ schedule_work(&adapter->multispeed_fiber_task);
+ adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
+}
+
+/**
* ixgbe_watchdog_task - worker thread to bring link up
* @work: pointer to work_struct containing our data
**/
@@ -3459,10 +3954,20 @@ static void ixgbe_watchdog_task(struct work_struct *work)
if (link_up) {
if (!netif_carrier_ok(netdev)) {
- u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
-#define FLOW_RX (frctl & IXGBE_FCTRL_RFCE)
-#define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X)
+ bool flow_rx, flow_tx;
+
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+ flow_rx = (mflcn & IXGBE_MFLCN_RFCE);
+ flow_tx = (fccfg & IXGBE_FCCFG_TFCE_802_3X);
+ } else {
+ u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
+ flow_rx = (frctl & IXGBE_FCTRL_RFCE);
+ flow_tx = (rmcs & IXGBE_RMCS_TFCE_802_3X);
+ }
+
printk(KERN_INFO "ixgbe: %s NIC Link is Up %s, "
"Flow Control: %s\n",
netdev->name,
@@ -3470,12 +3975,11 @@ static void ixgbe_watchdog_task(struct work_struct *work)
"10 Gbps" :
(link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
"1 Gbps" : "unknown speed")),
- ((FLOW_RX && FLOW_TX) ? "RX/TX" :
- (FLOW_RX ? "RX" :
- (FLOW_TX ? "TX" : "None"))));
+ ((flow_rx && flow_tx) ? "RX/TX" :
+ (flow_rx ? "RX" :
+ (flow_tx ? "TX" : "None"))));
netif_carrier_on(netdev);
- netif_tx_wake_all_queues(netdev);
} else {
/* Force detection of hung controller */
adapter->detect_tx_hung = true;
@@ -3487,7 +3991,6 @@ static void ixgbe_watchdog_task(struct work_struct *work)
printk(KERN_INFO "ixgbe: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
}
}
@@ -3614,13 +4117,13 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
type_tucmd_mlhl |=
IXGBE_ADVTXD_TUCMD_L4T_TCP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
type_tucmd_mlhl |=
@@ -3818,6 +4321,16 @@ static int ixgbe_maybe_stop_tx(struct net_device *netdev,
return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
}
+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_DCB_ENABLED)
+ return 0; /* All traffic should default to class 0 */
+
+ return skb_tx_hash(dev, skb);
+}
+
static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -3943,31 +4456,13 @@ static void ixgbe_netpoll(struct net_device *netdev)
}
#endif
-/**
- * ixgbe_link_config - set up initial link with default speed and duplex
- * @hw: pointer to private hardware struct
- *
- * Returns 0 on success, negative on failure
- **/
-static int ixgbe_link_config(struct ixgbe_hw *hw)
-{
- u32 autoneg = IXGBE_LINK_SPEED_10GB_FULL;
-
- /* must always autoneg for both 1G and 10G link */
- hw->mac.autoneg = true;
-
- if ((hw->mac.type == ixgbe_mac_82598EB) &&
- (hw->phy.media_type == ixgbe_media_type_copper))
- autoneg = IXGBE_LINK_SPEED_82598_AUTONEG;
-
- return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
-}
-
static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
.ndo_start_xmit = ixgbe_xmit_frame,
+ .ndo_select_queue = ixgbe_select_queue,
.ndo_get_stats = ixgbe_get_stats,
+ .ndo_set_rx_mode = ixgbe_set_rx_mode,
.ndo_set_multicast_list = ixgbe_set_rx_mode,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = ixgbe_set_mac,
@@ -4001,7 +4496,7 @@ 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;
- u16 link_status, link_speed, link_width;
+ u16 pm_value = 0;
u32 part_num, eec;
err = pci_enable_device(pdev);
@@ -4100,6 +4595,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
+ /* multispeed fiber has its own tasklet, called from GPI SDP1 context */
+ INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task);
+
+ /* a new SFP+ module arrival, called from GPI SDP2 context */
+ INIT_WORK(&adapter->sfp_config_module_task,
+ ixgbe_sfp_config_module_task);
+
err = ii->get_invariants(hw);
if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
/* start a kernel thread to watch for a module to arrive */
@@ -4136,7 +4638,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
- netdev->features |= NETIF_F_LRO;
+ netdev->features |= NETIF_F_GRO;
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
@@ -4180,26 +4682,41 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_sw_init;
+ switch (pdev->device) {
+ case IXGBE_DEV_ID_82599_KX4:
+#define IXGBE_PCIE_PMCSR 0x44
+ adapter->wol = IXGBE_WUFC_MAG;
+ pci_read_config_word(pdev, IXGBE_PCIE_PMCSR, &pm_value);
+ pci_write_config_word(pdev, IXGBE_PCIE_PMCSR,
+ (pm_value | (1 << 8)));
+ break;
+ default:
+ adapter->wol = 0;
+ break;
+ }
+ device_init_wakeup(&adapter->pdev->dev, true);
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
/* print bus type/speed/width info */
- pci_read_config_word(pdev, IXGBE_PCI_LINK_STATUS, &link_status);
- link_speed = link_status & IXGBE_PCI_LINK_SPEED;
- link_width = link_status & IXGBE_PCI_LINK_WIDTH;
dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n",
- ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
- (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
- "Unknown"),
- ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
- (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
- (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
- (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
+ ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
+ (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"),
+ ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" :
+ (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" :
+ (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
"Unknown"),
netdev->dev_addr);
ixgbe_read_pba_num_generic(hw, &part_num);
- dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
- hw->mac.type, hw->phy.type,
- (part_num >> 8), (part_num & 0xff));
+ if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present)
+ dev_info(&pdev->dev, "MAC: %d, PHY: %d, SFP+: %d, PBA No: %06x-%03x\n",
+ hw->mac.type, hw->phy.type, hw->phy.sfp_type,
+ (part_num >> 8), (part_num & 0xff));
+ else
+ dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
+ hw->mac.type, hw->phy.type,
+ (part_num >> 8), (part_num & 0xff));
- if (link_width <= IXGBE_PCI_LINK_WIDTH_4) {
+ if (hw->bus.width <= ixgbe_bus_width_pcie_x4) {
dev_warn(&pdev->dev, "PCI-Express bandwidth available for "
"this card is not sufficient for optimal "
"performance.\n");
@@ -4207,18 +4724,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
"PCI-Express slot is required.\n");
}
+ /* save off EEPROM version number */
+ hw->eeprom.ops.read(hw, 0x29, &adapter->eeprom_version);
+
/* reset the hardware with the new settings */
hw->mac.ops.start_hw(hw);
- /* link_config depends on start_hw being called at least once */
- err = ixgbe_link_config(hw);
- if (err) {
- dev_err(&pdev->dev, "setup_link_speed FAILED %d\n", err);
- goto err_register;
- }
-
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
@@ -4248,6 +4760,8 @@ err_eeprom:
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
del_timer_sync(&adapter->sfp_timer);
cancel_work_sync(&adapter->sfp_task);
+ cancel_work_sync(&adapter->multispeed_fiber_task);
+ cancel_work_sync(&adapter->sfp_config_module_task);
iounmap(hw->hw_addr);
err_ioremap:
free_netdev(netdev);
@@ -4284,6 +4798,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
del_timer_sync(&adapter->sfp_timer);
cancel_work_sync(&adapter->watchdog_task);
cancel_work_sync(&adapter->sfp_task);
+ cancel_work_sync(&adapter->multispeed_fiber_task);
+ cancel_work_sync(&adapter->sfp_config_module_task);
flush_scheduled_work();
#ifdef CONFIG_IXGBE_DCA
@@ -4367,7 +4883,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D3cold, 0);
ixgbe_reset(adapter);
-
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
result = PCI_ERS_RESULT_RECOVERED;
}
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 5a8669aedf6..14e9606aa3b 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -32,6 +32,18 @@
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
+static void ixgbe_i2c_start(struct ixgbe_hw *hw);
+static void ixgbe_i2c_stop(struct ixgbe_hw *hw);
+static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
+static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
+static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
+static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
+static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
+static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
+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);
@@ -543,8 +555,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
u8 identifier = 0;
u8 comp_codes_1g = 0;
u8 comp_codes_10g = 0;
- u8 oui_bytes[4] = {0, 0, 0, 0};
+ u8 oui_bytes[3] = {0, 0, 0};
u8 transmission_media = 0;
+ u16 enforce_sfp = 0;
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
&identifier);
@@ -564,18 +577,48 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
/* ID Module
* =========
- * 0 SFP_DA_CU
- * 1 SFP_SR
- * 2 SFP_LR
+ * 0 SFP_DA_CU
+ * 1 SFP_SR
+ * 2 SFP_LR
+ * 3 SFP_DA_CORE0 - 82599-specific
+ * 4 SFP_DA_CORE1 - 82599-specific
+ * 5 SFP_SR/LR_CORE0 - 82599-specific
+ * 6 SFP_SR/LR_CORE1 - 82599-specific
*/
- if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
- 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;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_lr;
- else
- hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+ 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;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+ hw->phy.sfp_type = ixgbe_sfp_type_lr;
+ 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 (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_da_cu_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_da_cu_core1;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core1;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core1;
+ else
+ hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ }
/* Determine PHY vendor */
if (hw->phy.type == ixgbe_phy_unknown) {
@@ -607,6 +650,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
case IXGBE_SFF_VENDOR_OUI_AVAGO:
hw->phy.type = ixgbe_phy_sfp_avago;
break;
+ case IXGBE_SFF_VENDOR_OUI_INTEL:
+ hw->phy.type = ixgbe_phy_sfp_intel;
+ break;
default:
if (transmission_media &
IXGBE_SFF_TWIN_AX_CAPABLE)
@@ -616,7 +662,28 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
break;
}
}
- status = 0;
+ 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)) {
+ 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)) {
+ /* 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");
+ status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+ } else {
+ status = 0;
+ }
}
out:
@@ -651,7 +718,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
if ((!*list_offset) || (*list_offset == 0xFFFF))
- return IXGBE_ERR_PHY;
+ return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
/* Shift offset to first ID word */
(*list_offset)++;
@@ -688,6 +755,501 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
}
/**
+ * ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to read
+ * @eeprom_data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *eeprom_data)
+{
+ return hw->phy.ops.read_i2c_byte(hw, byte_offset,
+ IXGBE_I2C_EEPROM_DEV_ADDR,
+ eeprom_data);
+}
+
+/**
+ * ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to write
+ * @eeprom_data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 eeprom_data)
+{
+ return hw->phy.ops.write_i2c_byte(hw, byte_offset,
+ IXGBE_I2C_EEPROM_DEV_ADDR,
+ eeprom_data);
+}
+
+/**
+ * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface at
+ * a specified deivce address.
+ **/
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data)
+{
+ s32 status = 0;
+ u32 max_retry = 1;
+ u32 retry = 0;
+ bool nack = 1;
+
+ do {
+ ixgbe_i2c_start(hw);
+
+ /* Device Address and write indication */
+ status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ ixgbe_i2c_start(hw);
+
+ /* Device Address and read indication */
+ status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_in_i2c_byte(hw, data);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_out_i2c_bit(hw, nack);
+ if (status != 0)
+ goto fail;
+
+ ixgbe_i2c_stop(hw);
+ break;
+
+fail:
+ ixgbe_i2c_bus_clear(hw);
+ retry++;
+ if (retry < max_retry)
+ hw_dbg(hw, "I2C byte read error - Retrying.\n");
+ else
+ hw_dbg(hw, "I2C byte read error.\n");
+
+ } while (retry < max_retry);
+
+ return status;
+}
+
+/**
+ * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data)
+{
+ s32 status = 0;
+ u32 max_retry = 1;
+ u32 retry = 0;
+
+ do {
+ ixgbe_i2c_start(hw);
+
+ status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_out_i2c_byte(hw, data);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ ixgbe_i2c_stop(hw);
+ break;
+
+fail:
+ ixgbe_i2c_bus_clear(hw);
+ retry++;
+ if (retry < max_retry)
+ hw_dbg(hw, "I2C byte write error - Retrying.\n");
+ else
+ hw_dbg(hw, "I2C byte write error.\n");
+ } while (retry < max_retry);
+
+ return status;
+}
+
+/**
+ * ixgbe_i2c_start - Sets I2C start condition
+ * @hw: pointer to hardware structure
+ *
+ * Sets I2C start condition (High -> Low on SDA while SCL is High)
+ **/
+static void ixgbe_i2c_start(struct ixgbe_hw *hw)
+{
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+ /* Start condition must begin with data and clock high */
+ ixgbe_set_i2c_data(hw, &i2cctl, 1);
+ ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Setup time for start condition (4.7us) */
+ udelay(IXGBE_I2C_T_SU_STA);
+
+ ixgbe_set_i2c_data(hw, &i2cctl, 0);
+
+ /* Hold time for start condition (4us) */
+ udelay(IXGBE_I2C_T_HD_STA);
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Minimum low period of clock is 4.7 us */
+ udelay(IXGBE_I2C_T_LOW);
+
+}
+
+/**
+ * ixgbe_i2c_stop - Sets I2C stop condition
+ * @hw: pointer to hardware structure
+ *
+ * Sets I2C stop condition (Low -> High on SDA while SCL is High)
+ **/
+static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
+{
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+ /* Stop condition must begin with data low and clock high */
+ ixgbe_set_i2c_data(hw, &i2cctl, 0);
+ ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Setup time for stop condition (4us) */
+ udelay(IXGBE_I2C_T_SU_STO);
+
+ ixgbe_set_i2c_data(hw, &i2cctl, 1);
+
+ /* bus free time between stop and start (4.7us)*/
+ udelay(IXGBE_I2C_T_BUF);
+}
+
+/**
+ * ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
+ * @hw: pointer to hardware structure
+ * @data: data byte to clock in
+ *
+ * Clocks in one byte data via I2C data/clock
+ **/
+static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
+{
+ s32 status = 0;
+ s32 i;
+ bool bit = 0;
+
+ for (i = 7; i >= 0; i--) {
+ status = ixgbe_clock_in_i2c_bit(hw, &bit);
+ *data |= bit << i;
+
+ if (status != 0)
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
+ * @hw: pointer to hardware structure
+ * @data: data byte clocked out
+ *
+ * Clocks out one byte data via I2C data/clock
+ **/
+static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
+{
+ s32 status = 0;
+ s32 i;
+ u32 i2cctl;
+ bool bit = 0;
+
+ for (i = 7; i >= 0; i--) {
+ bit = (data >> i) & 0x1;
+ status = ixgbe_clock_out_i2c_bit(hw, bit);
+
+ if (status != 0)
+ break;
+ }
+
+ /* Release SDA line (set high) */
+ i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ i2cctl |= IXGBE_I2C_DATA_OUT;
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl);
+
+ return status;
+}
+
+/**
+ * ixgbe_get_i2c_ack - Polls for I2C ACK
+ * @hw: pointer to hardware structure
+ *
+ * Clocks in/out one bit via I2C data/clock
+ **/
+static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u32 i = 0;
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ u32 timeout = 10;
+ bool ack = 1;
+
+ status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ if (status != 0)
+ goto out;
+
+ /* Minimum high period of clock is 4us */
+ udelay(IXGBE_I2C_T_HIGH);
+
+ /* Poll for ACK. Note that ACK in I2C spec is
+ * transition from 1 to 0 */
+ for (i = 0; i < timeout; i++) {
+ i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ ack = ixgbe_get_i2c_data(&i2cctl);
+
+ udelay(1);
+ if (ack == 0)
+ break;
+ }
+
+ if (ack == 1) {
+ hw_dbg(hw, "I2C ack was not received.\n");
+ status = IXGBE_ERR_I2C;
+ }
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Minimum low period of clock is 4.7 us */
+ udelay(IXGBE_I2C_T_LOW);
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
+ * @hw: pointer to hardware structure
+ * @data: read data value
+ *
+ * Clocks in one bit via I2C data/clock
+ **/
+static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
+{
+ s32 status;
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+ status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Minimum high period of clock is 4us */
+ udelay(IXGBE_I2C_T_HIGH);
+
+ i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ *data = ixgbe_get_i2c_data(&i2cctl);
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Minimum low period of clock is 4.7 us */
+ udelay(IXGBE_I2C_T_LOW);
+
+ return status;
+}
+
+/**
+ * ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
+ * @hw: pointer to hardware structure
+ * @data: data value to write
+ *
+ * Clocks out one bit via I2C data/clock
+ **/
+static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
+{
+ s32 status;
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+ status = ixgbe_set_i2c_data(hw, &i2cctl, data);
+ if (status == 0) {
+ status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Minimum high period of clock is 4us */
+ udelay(IXGBE_I2C_T_HIGH);
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Minimum low period of clock is 4.7 us.
+ * This also takes care of the data hold time.
+ */
+ udelay(IXGBE_I2C_T_LOW);
+ } else {
+ status = IXGBE_ERR_I2C;
+ hw_dbg(hw, "I2C data was not set to %X\n", data);
+ }
+
+ return status;
+}
+/**
+ * ixgbe_raise_i2c_clk - Raises the I2C SCL clock
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Raises the I2C clock line '0'->'1'
+ **/
+static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
+{
+ s32 status = 0;
+
+ *i2cctl |= IXGBE_I2C_CLK_OUT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+ /* SCL rise time (1000ns) */
+ udelay(IXGBE_I2C_T_RISE);
+
+ return status;
+}
+
+/**
+ * ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Lowers the I2C clock line '1'->'0'
+ **/
+static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
+{
+
+ *i2cctl &= ~IXGBE_I2C_CLK_OUT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+ /* SCL fall time (300ns) */
+ udelay(IXGBE_I2C_T_FALL);
+}
+
+/**
+ * ixgbe_set_i2c_data - Sets the I2C data bit
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ * @data: I2C data value (0 or 1) to set
+ *
+ * Sets the I2C data bit
+ **/
+static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
+{
+ s32 status = 0;
+
+ if (data)
+ *i2cctl |= IXGBE_I2C_DATA_OUT;
+ else
+ *i2cctl &= ~IXGBE_I2C_DATA_OUT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+ /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
+ udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
+
+ /* Verify data was set correctly */
+ *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ if (data != ixgbe_get_i2c_data(i2cctl)) {
+ status = IXGBE_ERR_I2C;
+ hw_dbg(hw, "Error - I2C data was not set to %X.\n", data);
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_get_i2c_data - Reads the I2C SDA data bit
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Returns the I2C data bit value
+ **/
+static bool ixgbe_get_i2c_data(u32 *i2cctl)
+{
+ bool data;
+
+ if (*i2cctl & IXGBE_I2C_DATA_IN)
+ data = 1;
+ else
+ data = 0;
+
+ return data;
+}
+
+/**
+ * ixgbe_i2c_bus_clear - Clears the I2C bus
+ * @hw: pointer to hardware structure
+ *
+ * Clears the I2C bus by sending nine clock pulses.
+ * Used when data line is stuck low.
+ **/
+static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
+{
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ u32 i;
+
+ ixgbe_set_i2c_data(hw, &i2cctl, 1);
+
+ for (i = 0; i < 9; i++) {
+ ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Min high period of clock is 4us */
+ udelay(IXGBE_I2C_T_HIGH);
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Min low period of clock is 4.7us*/
+ udelay(IXGBE_I2C_T_LOW);
+ }
+
+ /* Put the i2c bus back to default state */
+ ixgbe_i2c_stop(hw);
+}
+
+/**
* ixgbe_check_phy_link_tnx - Determine link and speed status
* @hw: pointer to hardware structure
*
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index 43a97bc420f..cc5f1b3287e 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -54,14 +54,15 @@
#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
/* Bit-shift macros */
-#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 12
-#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 8
-#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 4
+#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24
+#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16
+#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 8
/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
#define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600
#define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500
#define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00
+#define IXGBE_SFF_VENDOR_OUI_INTEL 0x001B2100
/* I2C SDA and SCL timing parameters for standard mode */
#define IXGBE_I2C_T_HD_STA 4
@@ -101,5 +102,12 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
u16 *list_offset,
u16 *data_offset);
-
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data);
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data);
+s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *eeprom_data);
+s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 eeprom_data);
#endif /* _IXGBE_PHY_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 83a11ff9ffd..2b2ecba7b60 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ 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,
@@ -34,6 +34,8 @@
#define IXGBE_INTEL_VENDOR_ID 0x8086
/* Device IDs */
+#define IXGBE_DEV_ID_82598 0x10B6
+#define IXGBE_DEV_ID_82598_BX 0x1508
#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6
#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
#define IXGBE_DEV_ID_82598EB_SFP_LOM 0x10DB
@@ -43,6 +45,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
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -50,9 +55,12 @@
#define IXGBE_CTRL_EXT 0x00018
#define IXGBE_ESDP 0x00020
#define IXGBE_EODSDP 0x00028
+#define IXGBE_I2CCTL 0x00028
#define IXGBE_LEDCTL 0x00200
#define IXGBE_FRTIMER 0x00048
#define IXGBE_TCPTIMER 0x0004C
+#define IXGBE_CORESPARE 0x00600
+#define IXGBE_EXVET 0x05078
/* NVM Registers */
#define IXGBE_EEC 0x10010
@@ -66,6 +74,19 @@
#define IXGBE_FLOP 0x1013C
#define IXGBE_GRC 0x10200
+/* General Receive Control */
+#define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */
+#define IXGBE_GRC_APME 0x00000002 /* Advanced Power Management Enable */
+
+#define IXGBE_VPDDIAG0 0x10204
+#define IXGBE_VPDDIAG1 0x10208
+
+/* I2CCTL Bit Masks */
+#define IXGBE_I2C_CLK_IN 0x00000001
+#define IXGBE_I2C_CLK_OUT 0x00000002
+#define IXGBE_I2C_DATA_IN 0x00000004
+#define IXGBE_I2C_DATA_OUT 0x00000008
+
/* Interrupt Registers */
#define IXGBE_EICR 0x00800
#define IXGBE_EICS 0x00808
@@ -73,28 +94,63 @@
#define IXGBE_EIMC 0x00888
#define IXGBE_EIAC 0x00810
#define IXGBE_EIAM 0x00890
-#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : (0x012300 + ((_i) * 4)))
+#define IXGBE_EICS_EX(_i) (0x00A90 + (_i) * 4)
+#define IXGBE_EIMS_EX(_i) (0x00AA0 + (_i) * 4)
+#define IXGBE_EIMC_EX(_i) (0x00AB0 + (_i) * 4)
+#define IXGBE_EIAM_EX(_i) (0x00AD0 + (_i) * 4)
+/*
+ * 82598 EITR is 16 bits but set the limits based on the max
+ * supported by all ixgbe hardware. 82599 EITR is only 12 bits,
+ * with the lower 3 always zero.
+ */
+#define IXGBE_MAX_INT_RATE 488281
+#define IXGBE_MIN_INT_RATE 956
+#define IXGBE_MAX_EITR 0x00000FF8
+#define IXGBE_MIN_EITR 8
+#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : \
+ (0x012300 + (((_i) - 24) * 4)))
+#define IXGBE_EITR_ITR_INT_MASK 0x00000FF8
+#define IXGBE_EITR_LLI_MOD 0x00008000
+#define IXGBE_EITR_CNT_WDIS 0x80000000
#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
+#define IXGBE_IVAR_MISC 0x00A00 /* misc MSI-X interrupt causes */
+#define IXGBE_EITRSEL 0x00894
#define IXGBE_MSIXT 0x00000 /* MSI-X Table. 0x0000 - 0x01C */
#define IXGBE_MSIXPBA 0x02000 /* MSI-X Pending bit array */
#define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4)))
#define IXGBE_GPIE 0x00898
/* Flow Control Registers */
+#define IXGBE_FCADBUL 0x03210
+#define IXGBE_FCADBUH 0x03214
+#define IXGBE_FCAMACL 0x04328
+#define IXGBE_FCAMACH 0x0432C
+#define IXGBE_FCRTH_82599(_i) (0x03260 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_FCRTL_82599(_i) (0x03220 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_PFCTOP 0x03008
#define IXGBE_FCTTV(_i) (0x03200 + ((_i) * 4)) /* 4 of these (0-3) */
#define IXGBE_FCRTL(_i) (0x03220 + ((_i) * 8)) /* 8 of these (0-7) */
#define IXGBE_FCRTH(_i) (0x03260 + ((_i) * 8)) /* 8 of these (0-7) */
#define IXGBE_FCRTV 0x032A0
+#define IXGBE_FCCFG 0x03D00
#define IXGBE_TFCS 0x0CE00
/* Receive DMA Registers */
-#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : (0x0D000 + ((_i - 64) * 0x40)))
-#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : (0x0D004 + ((_i - 64) * 0x40)))
-#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : (0x0D008 + ((_i - 64) * 0x40)))
-#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : (0x0D010 + ((_i - 64) * 0x40)))
-#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : (0x0D018 + ((_i - 64) * 0x40)))
-#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : (0x0D028 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : \
+ (0x0D000 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : \
+ (0x0D004 + ((_i - 64) * 0x40)))
+#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : \
+ (0x0D008 + ((_i - 64) * 0x40)))
+#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : \
+ (0x0D010 + ((_i - 64) * 0x40)))
+#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : \
+ (0x0D018 + ((_i - 64) * 0x40)))
+#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \
+ (0x0D028 + ((_i - 64) * 0x40)))
+#define IXGBE_RDDCC 0x02F20
+#define IXGBE_RXMEMWRAP 0x03190
+#define IXGBE_STARCTRL 0x03024
/*
* Split and Replication Receive Control Registers
* 00-15 : 0x02100 + n*4
@@ -127,10 +183,15 @@
#define IXGBE_DRECCCTL_DISABLE 0
/* Multicast Table Array - 128 entries */
#define IXGBE_MTA(_i) (0x05200 + ((_i) * 4))
-#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x0A200 + ((_i) * 8)))
-#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x0A204 + ((_i) * 8)))
+#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
+ (0x0A200 + ((_i) * 8)))
+#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
+ (0x0A204 + ((_i) * 8)))
+#define IXGBE_MPSAR_LO(_i) (0x0A600 + ((_i) * 8))
+#define IXGBE_MPSAR_HI(_i) (0x0A604 + ((_i) * 8))
/* Packet split receive type */
-#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : (0x0EA00 + ((_i) * 4)))
+#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : \
+ (0x0EA00 + ((_i) * 4)))
/* array of 4096 1-bit vlan filters */
#define IXGBE_VFTA(_i) (0x0A000 + ((_i) * 4))
/*array of 4096 4-bit vlan vmdq indices */
@@ -139,6 +200,28 @@
#define IXGBE_VLNCTRL 0x05088
#define IXGBE_MCSTCTRL 0x05090
#define IXGBE_MRQC 0x05818
+#define IXGBE_SAQF(_i) (0x0E000 + ((_i) * 4)) /* Source Address Queue Filter */
+#define IXGBE_DAQF(_i) (0x0E200 + ((_i) * 4)) /* Dest. Address Queue Filter */
+#define IXGBE_SDPQF(_i) (0x0E400 + ((_i) * 4)) /* Src Dest. Addr Queue Filter */
+#define IXGBE_FTQF(_i) (0x0E600 + ((_i) * 4)) /* Five Tuple Queue Filter */
+#define IXGBE_ETQF(_i) (0x05128 + ((_i) * 4)) /* EType Queue Filter */
+#define IXGBE_ETQS(_i) (0x0EC00 + ((_i) * 4)) /* EType Queue Select */
+#define IXGBE_SYNQF 0x0EC30 /* SYN Packet Queue Filter */
+#define IXGBE_RQTC 0x0EC70
+#define IXGBE_MTQC 0x08120
+#define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */
+#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */
+#define IXGBE_VT_CTL 0x051B0
+#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4))
+#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4))
+#define IXGBE_QDE 0x2F04
+#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */
+#define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4))
+#define IXGBE_VMRCTL(_i) (0x0F600 + ((_i) * 4))
+#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4))
+#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4))
+#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
+#define IXGBE_LLITHRESH 0x0EC90
#define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIRVP 0x05AC0
@@ -146,7 +229,6 @@
#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
-
/* Transmit DMA registers */
#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/
#define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
@@ -158,7 +240,20 @@
#define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
#define IXGBE_DTXCTL 0x07E00
+#define IXGBE_DMATXCTL 0x04A80
+#define IXGBE_DTXMXSZRQ 0x08100
+#define IXGBE_DTXTCPFLGL 0x04A88
+#define IXGBE_DTXTCPFLGH 0x04A8C
+#define IXGBE_LBDRPEN 0x0CA00
+#define IXGBE_TXPBTHRESH(_i) (0x04950 + ((_i) * 4)) /* 8 of these 0 - 7 */
+
+#define IXGBE_DMATXCTL_TE 0x1 /* Transmit Enable */
+#define IXGBE_DMATXCTL_NS 0x2 /* No Snoop LSO hdr buffer */
+#define IXGBE_DMATXCTL_GDV 0x8 /* Global Double VLAN */
+#define IXGBE_DMATXCTL_VT_SHIFT 16 /* VLAN EtherType */
#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */
+/* Tx DCA Control register : 128 of these (0-127) */
+#define IXGBE_DCA_TXCTRL_82599(_i) (0x0600C + ((_i) * 0x40))
#define IXGBE_TIPG 0x0CB00
#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) * 4)) /* 8 of these */
#define IXGBE_MNGTXMAP 0x0CD10
@@ -175,9 +270,69 @@
#define IXGBE_WUPL 0x05900
#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
-#define IXGBE_FHFT 0x09000 /* Flex host filter table 9000-93FC */
-
-/* Music registers */
+#define IXGBE_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flex host filter table */
+#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100)) /* Ext Flexible Host
+ * Filter Table */
+
+#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4
+#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define IXGBE_FLEXIBLE_FILTER_SIZE_MAX 128
+#define IXGBE_FHFT_LENGTH_OFFSET 0xFC /* Length byte in FHFT */
+#define IXGBE_FHFT_LENGTH_MASK 0x0FF /* Length in lower byte */
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define IXGBE_WUC_PME_EN 0x00000002 /* PME Enable */
+#define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */
+#define IXGBE_WUC_ADVD3WUC 0x00000010 /* D3Cold wake up cap. enable*/
+
+/* Wake Up Filter Control */
+#define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define IXGBE_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
+#define IXGBE_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
+#define IXGBE_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
+#define IXGBE_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
+#define IXGBE_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
+#define IXGBE_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
+#define IXGBE_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
+#define IXGBE_WUFC_MNG 0x00000100 /* Directed Mgmt Packet Wakeup Enable */
+
+#define IXGBE_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
+#define IXGBE_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
+#define IXGBE_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
+#define IXGBE_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
+#define IXGBE_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
+#define IXGBE_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */
+#define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
+#define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */
+#define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 /* Mask for Ext. flex filters */
+#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all 6 wakeup filters*/
+#define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
+
+/* Wake Up Status */
+#define IXGBE_WUS_LNKC IXGBE_WUFC_LNKC
+#define IXGBE_WUS_MAG IXGBE_WUFC_MAG
+#define IXGBE_WUS_EX IXGBE_WUFC_EX
+#define IXGBE_WUS_MC IXGBE_WUFC_MC
+#define IXGBE_WUS_BC IXGBE_WUFC_BC
+#define IXGBE_WUS_ARP IXGBE_WUFC_ARP
+#define IXGBE_WUS_IPV4 IXGBE_WUFC_IPV4
+#define IXGBE_WUS_IPV6 IXGBE_WUFC_IPV6
+#define IXGBE_WUS_MNG IXGBE_WUFC_MNG
+#define IXGBE_WUS_FLX0 IXGBE_WUFC_FLX0
+#define IXGBE_WUS_FLX1 IXGBE_WUFC_FLX1
+#define IXGBE_WUS_FLX2 IXGBE_WUFC_FLX2
+#define IXGBE_WUS_FLX3 IXGBE_WUFC_FLX3
+#define IXGBE_WUS_FLX4 IXGBE_WUFC_FLX4
+#define IXGBE_WUS_FLX5 IXGBE_WUFC_FLX5
+#define IXGBE_WUS_FLX_FILTERS IXGBE_WUFC_FLX_FILTERS
+
+/* Wake Up Packet Length */
+#define IXGBE_WUPL_LENGTH_MASK 0xFFFF
+
+/* DCB registers */
#define IXGBE_RMCS 0x03D00
#define IXGBE_DPMCS 0x07F40
#define IXGBE_PDPMCS 0x0CD00
@@ -190,6 +345,122 @@
#define IXGBE_TDPT2TCSR(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
+/* Security Control Registers */
+#define IXGBE_SECTXCTRL 0x08800
+#define IXGBE_SECTXSTAT 0x08804
+#define IXGBE_SECTXBUFFAF 0x08808
+#define IXGBE_SECTXMINIFG 0x08810
+#define IXGBE_SECTXSTAT 0x08804
+#define IXGBE_SECRXCTRL 0x08D00
+#define IXGBE_SECRXSTAT 0x08D04
+
+/* Security Bit Fields and Masks */
+#define IXGBE_SECTXCTRL_SECTX_DIS 0x00000001
+#define IXGBE_SECTXCTRL_TX_DIS 0x00000002
+#define IXGBE_SECTXCTRL_STORE_FORWARD 0x00000004
+
+#define IXGBE_SECTXSTAT_SECTX_RDY 0x00000001
+#define IXGBE_SECTXSTAT_ECC_TXERR 0x00000002
+
+#define IXGBE_SECRXCTRL_SECRX_DIS 0x00000001
+#define IXGBE_SECRXCTRL_RX_DIS 0x00000002
+
+#define IXGBE_SECRXSTAT_SECRX_RDY 0x00000001
+#define IXGBE_SECRXSTAT_ECC_RXERR 0x00000002
+
+/* LinkSec (MacSec) Registers */
+#define IXGBE_LSECTXCAP 0x08A00
+#define IXGBE_LSECRXCAP 0x08F00
+#define IXGBE_LSECTXCTRL 0x08A04
+#define IXGBE_LSECTXSCL 0x08A08 /* SCI Low */
+#define IXGBE_LSECTXSCH 0x08A0C /* SCI High */
+#define IXGBE_LSECTXSA 0x08A10
+#define IXGBE_LSECTXPN0 0x08A14
+#define IXGBE_LSECTXPN1 0x08A18
+#define IXGBE_LSECTXKEY0(_n) (0x08A1C + (4 * (_n))) /* 4 of these (0-3) */
+#define IXGBE_LSECTXKEY1(_n) (0x08A2C + (4 * (_n))) /* 4 of these (0-3) */
+#define IXGBE_LSECRXCTRL 0x08F04
+#define IXGBE_LSECRXSCL 0x08F08
+#define IXGBE_LSECRXSCH 0x08F0C
+#define IXGBE_LSECRXSA(_i) (0x08F10 + (4 * (_i))) /* 2 of these (0-1) */
+#define IXGBE_LSECRXPN(_i) (0x08F18 + (4 * (_i))) /* 2 of these (0-1) */
+#define IXGBE_LSECRXKEY(_n, _m) (0x08F20 + ((0x10 * (_n)) + (4 * (_m))))
+#define IXGBE_LSECTXUT 0x08A3C /* OutPktsUntagged */
+#define IXGBE_LSECTXPKTE 0x08A40 /* OutPktsEncrypted */
+#define IXGBE_LSECTXPKTP 0x08A44 /* OutPktsProtected */
+#define IXGBE_LSECTXOCTE 0x08A48 /* OutOctetsEncrypted */
+#define IXGBE_LSECTXOCTP 0x08A4C /* OutOctetsProtected */
+#define IXGBE_LSECRXUT 0x08F40 /* InPktsUntagged/InPktsNoTag */
+#define IXGBE_LSECRXOCTD 0x08F44 /* InOctetsDecrypted */
+#define IXGBE_LSECRXOCTV 0x08F48 /* InOctetsValidated */
+#define IXGBE_LSECRXBAD 0x08F4C /* InPktsBadTag */
+#define IXGBE_LSECRXNOSCI 0x08F50 /* InPktsNoSci */
+#define IXGBE_LSECRXUNSCI 0x08F54 /* InPktsUnknownSci */
+#define IXGBE_LSECRXUNCH 0x08F58 /* InPktsUnchecked */
+#define IXGBE_LSECRXDELAY 0x08F5C /* InPktsDelayed */
+#define IXGBE_LSECRXLATE 0x08F60 /* InPktsLate */
+#define IXGBE_LSECRXOK(_n) (0x08F64 + (0x04 * (_n))) /* InPktsOk */
+#define IXGBE_LSECRXINV(_n) (0x08F6C + (0x04 * (_n))) /* InPktsInvalid */
+#define IXGBE_LSECRXNV(_n) (0x08F74 + (0x04 * (_n))) /* InPktsNotValid */
+#define IXGBE_LSECRXUNSA 0x08F7C /* InPktsUnusedSa */
+#define IXGBE_LSECRXNUSA 0x08F80 /* InPktsNotUsingSa */
+
+/* LinkSec (MacSec) Bit Fields and Masks */
+#define IXGBE_LSECTXCAP_SUM_MASK 0x00FF0000
+#define IXGBE_LSECTXCAP_SUM_SHIFT 16
+#define IXGBE_LSECRXCAP_SUM_MASK 0x00FF0000
+#define IXGBE_LSECRXCAP_SUM_SHIFT 16
+
+#define IXGBE_LSECTXCTRL_EN_MASK 0x00000003
+#define IXGBE_LSECTXCTRL_DISABLE 0x0
+#define IXGBE_LSECTXCTRL_AUTH 0x1
+#define IXGBE_LSECTXCTRL_AUTH_ENCRYPT 0x2
+#define IXGBE_LSECTXCTRL_AISCI 0x00000020
+#define IXGBE_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00
+#define IXGBE_LSECTXCTRL_RSV_MASK 0x000000D8
+
+#define IXGBE_LSECRXCTRL_EN_MASK 0x0000000C
+#define IXGBE_LSECRXCTRL_EN_SHIFT 2
+#define IXGBE_LSECRXCTRL_DISABLE 0x0
+#define IXGBE_LSECRXCTRL_CHECK 0x1
+#define IXGBE_LSECRXCTRL_STRICT 0x2
+#define IXGBE_LSECRXCTRL_DROP 0x3
+#define IXGBE_LSECRXCTRL_PLSH 0x00000040
+#define IXGBE_LSECRXCTRL_RP 0x00000080
+#define IXGBE_LSECRXCTRL_RSV_MASK 0xFFFFFF33
+
+/* IpSec Registers */
+#define IXGBE_IPSTXIDX 0x08900
+#define IXGBE_IPSTXSALT 0x08904
+#define IXGBE_IPSTXKEY(_i) (0x08908 + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXIDX 0x08E00
+#define IXGBE_IPSRXIPADDR(_i) (0x08E04 + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXSPI 0x08E14
+#define IXGBE_IPSRXIPIDX 0x08E18
+#define IXGBE_IPSRXKEY(_i) (0x08E1C + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXSALT 0x08E2C
+#define IXGBE_IPSRXMOD 0x08E30
+
+#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4
+
+/* DCB registers */
+#define IXGBE_RTRPCS 0x02430
+#define IXGBE_RTTDCS 0x04900
+#define IXGBE_RTTPCS 0x0CD00
+#define IXGBE_RTRUP2TC 0x03020
+#define IXGBE_RTTUP2TC 0x0C800
+#define IXGBE_RTRPT4C(_i) (0x02140 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTRPT4S(_i) (0x02160 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDT2C(_i) (0x04910 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDT2S(_i) (0x04930 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTPT2C(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTPT2S(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDQSEL 0x04904
+#define IXGBE_RTTDT1C 0x04908
+#define IXGBE_RTTDT1S 0x0490C
+#define IXGBE_RTTDTECC 0x04990
+#define IXGBE_RTTDTECC_NO_BCN 0x00000100
+#define IXGBE_RTTBCNRC 0x04984
/* Stats registers */
#define IXGBE_CRCERRS 0x04000
@@ -204,6 +475,11 @@
#define IXGBE_LXONRXC 0x0CF60
#define IXGBE_LXOFFTXC 0x03F68
#define IXGBE_LXOFFRXC 0x0CF68
+#define IXGBE_LXONRXCNT 0x041A4
+#define IXGBE_LXOFFRXCNT 0x041A8
+#define IXGBE_PXONRXCNT(_i) (0x04140 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_PXOFFRXCNT(_i) (0x04160 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_PXON2OFFCNT(_i) (0x03240 + ((_i) * 4)) /* 8 of these */
#define IXGBE_PXONTXC(_i) (0x03F00 + ((_i) * 4)) /* 8 of these 3F00-3F1C*/
#define IXGBE_PXONRXC(_i) (0x0CF00 + ((_i) * 4)) /* 8 of these CF00-CF1C*/
#define IXGBE_PXOFFTXC(_i) (0x03F20 + ((_i) * 4)) /* 8 of these 3F20-3F3C*/
@@ -243,14 +519,20 @@
#define IXGBE_MPTC 0x040F0
#define IXGBE_BPTC 0x040F4
#define IXGBE_XEC 0x04120
+#define IXGBE_SSVPC 0x08780
-#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) /* 16 of these */
-#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : (0x08600 + ((_i) * 4)))
+#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4))
+#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : \
+ (0x08600 + ((_i) * 4)))
+#define IXGBE_TQSM(_i) (0x08600 + ((_i) * 4))
#define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */
+#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 */
/* Management */
#define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
@@ -263,6 +545,9 @@
#define IXGBE_MMAL(_i) (0x05910 + ((_i) * 8)) /* 4 of these (0-3) */
#define IXGBE_MMAH(_i) (0x05914 + ((_i) * 8)) /* 4 of these (0-3) */
#define IXGBE_FTFT 0x09400 /* 0x9400-0x97FC */
+#define IXGBE_METF(_i) (0x05190 + ((_i) * 4)) /* 4 of these (0-3) */
+#define IXGBE_MDEF_EXT(_i) (0x05160 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_LSWFW 0x15014
/* ARC Subsystem registers */
#define IXGBE_HICR 0x15F00
@@ -295,16 +580,65 @@
#define IXGBE_DCA_ID 0x11070
#define IXGBE_DCA_CTRL 0x11074
+/* PCIe registers 82599-specific */
+#define IXGBE_GCR_EXT 0x11050
+#define IXGBE_GSCL_5_82599 0x11030
+#define IXGBE_GSCL_6_82599 0x11034
+#define IXGBE_GSCL_7_82599 0x11038
+#define IXGBE_GSCL_8_82599 0x1103C
+#define IXGBE_PHYADR_82599 0x11040
+#define IXGBE_PHYDAT_82599 0x11044
+#define IXGBE_PHYCTL_82599 0x11048
+#define IXGBE_PBACLR_82599 0x11068
+#define IXGBE_CIAA_82599 0x11088
+#define IXGBE_CIAD_82599 0x1108C
+#define IXGBE_PCIE_DIAG_0_82599 0x11090
+#define IXGBE_PCIE_DIAG_1_82599 0x11094
+#define IXGBE_PCIE_DIAG_2_82599 0x11098
+#define IXGBE_PCIE_DIAG_3_82599 0x1109C
+#define IXGBE_PCIE_DIAG_4_82599 0x110A0
+#define IXGBE_PCIE_DIAG_5_82599 0x110A4
+#define IXGBE_PCIE_DIAG_6_82599 0x110A8
+#define IXGBE_PCIE_DIAG_7_82599 0x110C0
+#define IXGBE_INTRPT_CSR_82599 0x110B0
+#define IXGBE_INTRPT_MASK_82599 0x110B8
+#define IXGBE_CDQ_MBR_82599 0x110B4
+#define IXGBE_MISC_REG_82599 0x110F0
+#define IXGBE_ECC_CTRL_0_82599 0x11100
+#define IXGBE_ECC_CTRL_1_82599 0x11104
+#define IXGBE_ECC_STATUS_82599 0x110E0
+#define IXGBE_BAR_CTRL_82599 0x110F4
+
+/* Time Sync Registers */
+#define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */
+#define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */
+#define IXGBE_RXSTMPL 0x051E8 /* Rx timestamp Low - RO */
+#define IXGBE_RXSTMPH 0x051A4 /* Rx timestamp High - RO */
+#define IXGBE_RXSATRL 0x051A0 /* Rx timestamp attribute low - RO */
+#define IXGBE_RXSATRH 0x051A8 /* Rx timestamp attribute high - RO */
+#define IXGBE_RXMTRL 0x05120 /* RX message type register low - RW */
+#define IXGBE_TXSTMPL 0x08C04 /* Tx timestamp value Low - RO */
+#define IXGBE_TXSTMPH 0x08C08 /* Tx timestamp value High - RO */
+#define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */
+#define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */
+#define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */
+#define IXGBE_RXUDP 0x08C1C /* Time Sync Rx UDP Port - RW */
+
/* Diagnostic Registers */
#define IXGBE_RDSTATCTL 0x02C20
#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
#define IXGBE_RDHMPN 0x02F08
#define IXGBE_RIC_DW(_i) (0x02F10 + ((_i) * 4))
#define IXGBE_RDPROBE 0x02F20
+#define IXGBE_RDMAM 0x02F30
+#define IXGBE_RDMAD 0x02F34
#define IXGBE_TDSTATCTL 0x07C20
#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
#define IXGBE_TDHMPN 0x07F08
+#define IXGBE_TDHMPN2 0x082FC
+#define IXGBE_TXDESCIC 0x082CC
#define IXGBE_TIC_DW(_i) (0x07F10 + ((_i) * 4))
+#define IXGBE_TIC_DW2(_i) (0x082B0 + ((_i) * 4))
#define IXGBE_TDPROBE 0x07F20
#define IXGBE_TXBUFCTRL 0x0C600
#define IXGBE_TXBUFDATA0 0x0C610
@@ -332,6 +666,8 @@
#define IXGBE_TXDATARDPTR(_i) (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C*/
#define IXGBE_TXDESCRDPTR(_i) (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C*/
#define IXGBE_PCIEECCCTL 0x1106C
+#define IXGBE_PCIEECCCTL0 0x11100
+#define IXGBE_PCIEECCCTL1 0x11104
#define IXGBE_PBTXECC 0x0C300
#define IXGBE_PBRXECC 0x03300
#define IXGBE_GHECCR 0x110B0
@@ -357,24 +693,61 @@
#define IXGBE_MSRWD 0x04260
#define IXGBE_MLADD 0x04264
#define IXGBE_MHADD 0x04268
+#define IXGBE_MAXFRS 0x04268
#define IXGBE_TREG 0x0426C
#define IXGBE_PCSS1 0x04288
#define IXGBE_PCSS2 0x0428C
#define IXGBE_XPCSS 0x04290
+#define IXGBE_MFLCN 0x04294
#define IXGBE_SERDESC 0x04298
#define IXGBE_MACS 0x0429C
#define IXGBE_AUTOC 0x042A0
#define IXGBE_LINKS 0x042A4
+#define IXGBE_LINKS2 0x04324
#define IXGBE_AUTOC2 0x042A8
#define IXGBE_AUTOC3 0x042AC
#define IXGBE_ANLP1 0x042B0
#define IXGBE_ANLP2 0x042B4
#define IXGBE_ATLASCTL 0x04800
+#define IXGBE_MMNGC 0x042D0
+#define IXGBE_ANLPNP1 0x042D4
+#define IXGBE_ANLPNP2 0x042D8
+#define IXGBE_KRPCSFC 0x042E0
+#define IXGBE_KRPCSS 0x042E4
+#define IXGBE_FECS1 0x042E8
+#define IXGBE_FECS2 0x042EC
+#define IXGBE_SMADARCTL 0x14F10
+#define IXGBE_MPVC 0x04318
+#define IXGBE_SGMIIC 0x04314
+
+/* Omer CORECTL */
+#define IXGBE_CORECTL 0x014F00
+/* BARCTRL */
+#define IXGBE_BARCTRL 0x110F4
+#define IXGBE_BARCTRL_FLSIZE 0x0700
+#define IXGBE_BARCTRL_CSRSIZE 0x2000
/* RDRXCTL Bit Masks */
#define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 /* Rx Desc Min Threshold Size */
+#define IXGBE_RDRXCTL_CRCSTRIP 0x00000002 /* CRC Strip */
#define IXGBE_RDRXCTL_MVMEN 0x00000020
#define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */
+#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */
+
+/* RQTC Bit Masks and Shifts */
+#define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4)
+#define IXGBE_RQTC_TC0_MASK (0x7 << 0)
+#define IXGBE_RQTC_TC1_MASK (0x7 << 4)
+#define IXGBE_RQTC_TC2_MASK (0x7 << 8)
+#define IXGBE_RQTC_TC3_MASK (0x7 << 12)
+#define IXGBE_RQTC_TC4_MASK (0x7 << 16)
+#define IXGBE_RQTC_TC5_MASK (0x7 << 20)
+#define IXGBE_RQTC_TC6_MASK (0x7 << 24)
+#define IXGBE_RQTC_TC7_MASK (0x7 << 28)
+
+/* PSRTYPE.RQPL Bit masks and shift */
+#define IXGBE_PSRTYPE_RQPL_MASK 0x7
+#define IXGBE_PSRTYPE_RQPL_SHIFT 29
/* CTRL Bit Masks */
#define IXGBE_CTRL_GIO_DIS 0x00000004 /* Global IO Master Disable bit */
@@ -389,6 +762,7 @@
#define IXGBE_MHADD_MFS_SHIFT 16
/* Extended Device Control */
+#define IXGBE_CTRL_EXT_PFRSTD 0x00004000 /* Physical Function Reset Done */
#define IXGBE_CTRL_EXT_NS_DIS 0x00010000 /* No Snoop disable */
#define IXGBE_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define IXGBE_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
@@ -401,11 +775,18 @@
#define IXGBE_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
#define IXGBE_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
+#define IXGBE_DCA_RXCTRL_CPUID_MASK_82599 0xFF000000 /* Rx CPUID Mask */
+#define IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599 24 /* Rx CPUID Shift */
#define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
#define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
#define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
+#define IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx rd Desc Relax Order */
+#define IXGBE_DCA_RXCTRL_DESC_WRO_EN (1 << 13) /* DCA Rx wr Desc Relax Order */
+#define IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */
#define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
+#define IXGBE_DCA_TXCTRL_CPUID_MASK_82599 0xFF000000 /* Tx CPUID Mask */
+#define IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599 24 /* Tx CPUID Shift */
#define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
#define IXGBE_DCA_MAX_QUEUES_82598 16 /* DCA regs only on 16 queues */
@@ -449,6 +830,8 @@
#define IXGBE_ATLAS_PDN_TX_1G_QL_ALL 0xF0
#define IXGBE_ATLAS_PDN_TX_AN_QL_ALL 0xF0
+/* 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
@@ -476,8 +859,11 @@
#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 Address Reg */
+#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 */
@@ -492,7 +878,7 @@
#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0
#define IXGBE_MAX_PHY_ADDR 32
-/* PHY IDs */
+/* PHY IDs*/
#define TN1010_PHY_ID 0x00A19410
#define TNX_FW_REV 0xB
#define QT2022_PHY_ID 0x0043A400
@@ -512,15 +898,22 @@
#define IXGBE_CONTROL_NL 0x000F
#define IXGBE_CONTROL_EOL_NL 0x0FFF
#define IXGBE_CONTROL_SOL_NL 0x0000
+#define IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET 0x002C
+#define IXGBE_PHY_ALLOW_ANY_SFP 0x1
/* General purpose Interrupt Enable */
#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */
#define IXGBE_SDP1_GPIEN 0x00000002 /* SDP1 */
+#define IXGBE_SDP2_GPIEN 0x00000004 /* SDP2 */
#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */
#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */
#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
#define IXGBE_GPIE_EIAME 0x40000000
#define IXGBE_GPIE_PBA_SUPPORT 0x80000000
+#define IXGBE_GPIE_VTMODE_MASK 0x0000C000 /* VT Mode Mask */
+#define IXGBE_GPIE_VTMODE_16 0x00004000 /* 16 VFs 8 queues per VF */
+#define IXGBE_GPIE_VTMODE_32 0x00008000 /* 32 VFs 4 queues per VF */
+#define IXGBE_GPIE_VTMODE_64 0x0000C000 /* 64 VFs 2 queues per VF */
/* Transmit Flow Control status */
#define IXGBE_TFCS_TXOFF 0x00000001
@@ -561,6 +954,21 @@
#define IXGBE_VMD_CTL_VMDQ_EN 0x00000001
#define IXGBE_VMD_CTL_VMDQ_FILTER 0x00000002
+/* VT_CTL bitmasks */
+#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 */
+
+/* VMOLR bitmasks */
+#define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */
+#define IXGBE_VMOLR_ROMPE 0x02000000 /* accept packets in MTA tbl */
+#define IXGBE_VMOLR_ROPE 0x04000000 /* accept packets in UC tbl */
+#define IXGBE_VMOLR_BAM 0x08000000 /* accept broadcast packets */
+#define IXGBE_VMOLR_MPE 0x10000000 /* multicast promiscuous */
+
+/* VFRE bitmask */
+#define IXGBE_VFRE_ENABLE_ALL 0xFFFFFFFF
+
/* RDHMPN and TDHMPN bitmasks */
#define IXGBE_RDHMPN_RDICADDR 0x007FF800
#define IXGBE_RDHMPN_RDICRDREQ 0x00800000
@@ -569,13 +977,39 @@
#define IXGBE_TDHMPN_TDICRDREQ 0x00800000
#define IXGBE_TDHMPN_TDICADDR_SHIFT 11
+#define IXGBE_RDMAM_MEM_SEL_SHIFT 13
+#define IXGBE_RDMAM_DWORD_SHIFT 9
+#define IXGBE_RDMAM_DESC_COMP_FIFO 1
+#define IXGBE_RDMAM_DFC_CMD_FIFO 2
+#define IXGBE_RDMAM_TCN_STATUS_RAM 4
+#define IXGBE_RDMAM_WB_COLL_FIFO 5
+#define IXGBE_RDMAM_QSC_CNT_RAM 6
+#define IXGBE_RDMAM_QSC_QUEUE_CNT 8
+#define IXGBE_RDMAM_QSC_QUEUE_RAM 0xA
+#define IXGBE_RDMAM_DESC_COM_FIFO_RANGE 135
+#define IXGBE_RDMAM_DESC_COM_FIFO_COUNT 4
+#define IXGBE_RDMAM_DFC_CMD_FIFO_RANGE 48
+#define IXGBE_RDMAM_DFC_CMD_FIFO_COUNT 7
+#define IXGBE_RDMAM_TCN_STATUS_RAM_RANGE 256
+#define IXGBE_RDMAM_TCN_STATUS_RAM_COUNT 9
+#define IXGBE_RDMAM_WB_COLL_FIFO_RANGE 8
+#define IXGBE_RDMAM_WB_COLL_FIFO_COUNT 4
+#define IXGBE_RDMAM_QSC_CNT_RAM_RANGE 64
+#define IXGBE_RDMAM_QSC_CNT_RAM_COUNT 4
+#define IXGBE_RDMAM_QSC_QUEUE_CNT_RANGE 32
+#define IXGBE_RDMAM_QSC_QUEUE_CNT_COUNT 4
+#define IXGBE_RDMAM_QSC_QUEUE_RAM_RANGE 128
+#define IXGBE_RDMAM_QSC_QUEUE_RAM_COUNT 8
+
+#define IXGBE_TXDESCIC_READY 0x80000000
+
/* Receive Checksum Control */
#define IXGBE_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define IXGBE_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* FCRTL Bit Masks */
-#define IXGBE_FCRTL_XONE 0x80000000 /* bit 31, XON enable */
-#define IXGBE_FCRTH_FCEN 0x80000000 /* Rx Flow control enable */
+#define IXGBE_FCRTL_XONE 0x80000000 /* XON enable */
+#define IXGBE_FCRTH_FCEN 0x80000000 /* Packet buffer fc enable */
/* PAP bit masks*/
#define IXGBE_PAP_TXPAUSECNT_MASK 0x0000FFFF /* Pause counter mask */
@@ -585,19 +1019,29 @@
/* Receive Arbitration Control: 0 Round Robin, 1 DFP */
#define IXGBE_RMCS_RAC 0x00000004
#define IXGBE_RMCS_DFP IXGBE_RMCS_RAC /* Deficit Fixed Priority ena */
-#define IXGBE_RMCS_TFCE_802_3X 0x00000008 /* Tx Priority flow control ena */
-#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority flow control ena */
+#define IXGBE_RMCS_TFCE_802_3X 0x00000008 /* Tx Priority FC ena */
+#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority FC ena */
#define IXGBE_RMCS_ARBDIS 0x00000040 /* Arbitration disable bit */
+/* FCCFG Bit Masks */
+#define IXGBE_FCCFG_TFCE_802_3X 0x00000008 /* Tx link FC enable */
+#define IXGBE_FCCFG_TFCE_PRIORITY 0x00000010 /* Tx priority FC enable */
/* Interrupt register bitmasks */
/* Extended Interrupt Cause Read */
#define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */
+#define IXGBE_EICR_FLOW_DIR 0x00010000 /* FDir Exception */
+#define IXGBE_EICR_RX_MISS 0x00020000 /* Packet Buffer Overrun */
+#define IXGBE_EICR_PCI 0x00040000 /* PCI Exception */
+#define IXGBE_EICR_MAILBOX 0x00080000 /* VF to PF Mailbox Interrupt */
#define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */
+#define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */
#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */
#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */
#define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */
+#define IXGBE_EICR_GPI_SDP2 0x04000000 /* Gen Purpose Interrupt on SDP2 */
+#define IXGBE_EICR_ECC 0x10000000 /* ECC Error */
#define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */
#define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */
#define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
@@ -605,10 +1049,16 @@
/* Extended Interrupt Cause Set */
#define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EICS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
+#define IXGBE_EICS_RX_MISS IXGBE_EICR_RX_MISS /* Pkt Buffer Overrun */
+#define IXGBE_EICS_PCI IXGBE_EICR_PCI /* PCI Exception */
+#define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EICS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
+#define IXGBE_EICS_ECC IXGBE_EICR_ECC /* ECC Error */
#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */
#define IXGBE_EICS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -616,10 +1066,16 @@
/* Extended Interrupt Mask Set */
#define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EIMS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
+#define IXGBE_EIMS_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */
+#define IXGBE_EIMS_PCI IXGBE_EICR_PCI /* PCI Exception */
+#define IXGBE_EIMS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
+#define IXGBE_EIMS_ECC IXGBE_EICR_ECC /* ECC Error */
#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
#define IXGBE_EIMS_DHER IXGBE_EICR_DHER /* Descr Handler Error */
#define IXGBE_EIMS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -627,10 +1083,16 @@
/* Extended Interrupt Mask Clear */
#define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EIMC_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
+#define IXGBE_EIMC_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */
+#define IXGBE_EIMC_PCI IXGBE_EICR_PCI /* PCI Exception */
+#define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMC_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
+#define IXGBE_EIMC_ECC IXGBE_EICR_ECC /* ECC Error */
#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Err */
#define IXGBE_EIMC_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -653,6 +1115,33 @@
#define IXGBE_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */
#define IXGBE_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */
#define IXGBE_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of control bits */
+#define IXGBE_IMIR_SIZE_BP_82599 0x00001000 /* Packet size bypass */
+#define IXGBE_IMIR_CTRL_URG_82599 0x00002000 /* Check URG bit in header */
+#define IXGBE_IMIR_CTRL_ACK_82599 0x00004000 /* Check ACK bit in header */
+#define IXGBE_IMIR_CTRL_PSH_82599 0x00008000 /* Check PSH bit in header */
+#define IXGBE_IMIR_CTRL_RST_82599 0x00010000 /* Check RST bit in header */
+#define IXGBE_IMIR_CTRL_SYN_82599 0x00020000 /* Check SYN bit in header */
+#define IXGBE_IMIR_CTRL_FIN_82599 0x00040000 /* Check FIN bit in header */
+#define IXGBE_IMIR_CTRL_BP_82599 0x00080000 /* Bypass check of control bits */
+#define IXGBE_IMIR_LLI_EN_82599 0x00100000 /* Enables low latency Int */
+#define IXGBE_IMIR_RX_QUEUE_MASK_82599 0x0000007F /* Rx Queue Mask */
+#define IXGBE_IMIR_RX_QUEUE_SHIFT_82599 21 /* Rx Queue Shift */
+#define IXGBE_IMIRVP_PRIORITY_MASK 0x00000007 /* VLAN priority mask */
+#define IXGBE_IMIRVP_PRIORITY_EN 0x00000008 /* VLAN priority enable */
+
+#define IXGBE_MAX_FTQF_FILTERS 128
+#define IXGBE_FTQF_PROTOCOL_MASK 0x00000003
+#define IXGBE_FTQF_PROTOCOL_TCP 0x00000000
+#define IXGBE_FTQF_PROTOCOL_UDP 0x00000001
+#define IXGBE_FTQF_PROTOCOL_SCTP 2
+#define IXGBE_FTQF_PRIORITY_MASK 0x00000007
+#define IXGBE_FTQF_PRIORITY_SHIFT 2
+#define IXGBE_FTQF_POOL_MASK 0x0000003F
+#define IXGBE_FTQF_POOL_SHIFT 8
+#define IXGBE_FTQF_5TUPLE_MASK_MASK 0x0000001F
+#define IXGBE_FTQF_5TUPLE_MASK_SHIFT 25
+#define IXGBE_FTQF_POOL_MASK_EN 0x40000000
+#define IXGBE_FTQF_QUEUE_ENABLE 0x80000000
/* Interrupt clear mask */
#define IXGBE_IRQ_CLEAR_MASK 0xFFFFFFFF
@@ -672,6 +1161,31 @@
#define IXGBE_IVAR_ALLOC_VAL 0x80 /* Interrupt Allocation valid */
+/* ETYPE Queue Filter/Select Bit Masks */
+#define IXGBE_MAX_ETQF_FILTERS 8
+#define IXGBE_ETQF_BCN 0x10000000 /* bit 28 */
+#define IXGBE_ETQF_1588 0x40000000 /* bit 30 */
+#define IXGBE_ETQF_FILTER_EN 0x80000000 /* bit 31 */
+#define IXGBE_ETQF_POOL_ENABLE (1 << 26) /* bit 26 */
+
+#define IXGBE_ETQS_RX_QUEUE 0x007F0000 /* bits 22:16 */
+#define IXGBE_ETQS_RX_QUEUE_SHIFT 16
+#define IXGBE_ETQS_LLI 0x20000000 /* bit 29 */
+#define IXGBE_ETQS_QUEUE_EN 0x80000000 /* bit 31 */
+
+/*
+ * ETQF filter list: one static filter per filter consumer. This is
+ * to avoid filter collisions later. Add new filters
+ * here!!
+ *
+ * Current filters:
+ * EAPOL 802.1x (0x888e): Filter 0
+ * BCN (0x8904): Filter 1
+ * 1588 (0x88f7): Filter 3
+ */
+#define IXGBE_ETQF_FILTER_EAPOL 0
+#define IXGBE_ETQF_FILTER_BCN 1
+#define IXGBE_ETQF_FILTER_1588 3
/* VLAN Control Bit Masks */
#define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */
#define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */
@@ -679,21 +1193,28 @@
#define IXGBE_VLNCTRL_VFE 0x40000000 /* bit 30 */
#define IXGBE_VLNCTRL_VME 0x80000000 /* bit 31 */
+/* VLAN pool filtering masks */
+#define IXGBE_VLVF_VIEN 0x80000000 /* filter is valid */
+#define IXGBE_VLVF_ENTRIES 64
#define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */
/* STATUS Bit Masks */
-#define IXGBE_STATUS_LAN_ID 0x0000000C /* LAN ID */
-#define IXGBE_STATUS_GIO 0x00080000 /* GIO Master Enable Status */
+#define IXGBE_STATUS_LAN_ID 0x0000000C /* LAN ID */
+#define IXGBE_STATUS_LAN_ID_SHIFT 2 /* LAN ID Shift*/
+#define IXGBE_STATUS_GIO 0x00080000 /* GIO Master Enable Status */
#define IXGBE_STATUS_LAN_ID_0 0x00000000 /* LAN ID 0 */
#define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */
/* ESDP Bit Masks */
-#define IXGBE_ESDP_SDP4 0x00000001 /* SDP4 Data Value */
-#define IXGBE_ESDP_SDP5 0x00000002 /* SDP5 Data Value */
+#define IXGBE_ESDP_SDP0 0x00000001
+#define IXGBE_ESDP_SDP1 0x00000002
+#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */
+#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
+#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
#define IXGBE_ESDP_SDP4_DIR 0x00000004 /* SDP4 IO direction */
-#define IXGBE_ESDP_SDP5_DIR 0x00000008 /* SDP5 IO direction */
+#define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */
/* LEDCTL Bit Masks */
#define IXGBE_LED_IVRT_BASE 0x00000040
@@ -716,6 +1237,7 @@
#define IXGBE_LED_OFF 0xF
/* AUTOC Bit Masks */
+#define IXGBE_AUTOC_KX4_KX_SUPP_MASK 0xC0000000
#define IXGBE_AUTOC_KX4_SUPP 0x80000000
#define IXGBE_AUTOC_KX_SUPP 0x40000000
#define IXGBE_AUTOC_PAUSE 0x30000000
@@ -724,9 +1246,17 @@
#define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000
#define IXGBE_AUTOC_AN_RX_DRIFT 0x00800000
#define IXGBE_AUTOC_AN_RX_ALIGN 0x007C0000
+#define IXGBE_AUTOC_FECA 0x00040000
+#define IXGBE_AUTOC_FECR 0x00020000
+#define IXGBE_AUTOC_KR_SUPP 0x00010000
#define IXGBE_AUTOC_AN_RESTART 0x00001000
#define IXGBE_AUTOC_FLU 0x00000001
#define IXGBE_AUTOC_LMS_SHIFT 13
+#define IXGBE_AUTOC_LMS_10G_SERIAL (0x3 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR (0x4 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_SGMII_1G_100M (0x5 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII (0x7 << IXGBE_AUTOC_LMS_SHIFT)
#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT)
#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT)
#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT)
@@ -735,15 +1265,24 @@
#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200
-#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180
-#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
-#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
+#define IXGBE_AUTOC_1G_PMA_PMD_MASK 0x00000200
+#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
+#define IXGBE_AUTOC_10G_PMA_PMD_MASK 0x00000180
+#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
#define IXGBE_AUTOC_10G_XAUI (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
#define IXGBE_AUTOC_10G_KX4 (0x1 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
#define IXGBE_AUTOC_10G_CX4 (0x2 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
#define IXGBE_AUTOC_1G_BX (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
#define IXGBE_AUTOC_1G_KX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC_1G_SFI (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC_1G_KX_BX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+
+#define IXGBE_AUTOC2_UPPER_MASK 0xFFFF0000
+#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK 0x00030000
+#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT 16
+#define IXGBE_AUTOC2_10G_KR (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
/* LINKS Bit Masks */
#define IXGBE_LINKS_KX_AN_COMP 0x80000000
@@ -753,6 +1292,7 @@
#define IXGBE_LINKS_RX_MODE 0x06000000
#define IXGBE_LINKS_TX_MODE 0x01800000
#define IXGBE_LINKS_XGXS_EN 0x00400000
+#define IXGBE_LINKS_SGMII_EN 0x02000000
#define IXGBE_LINKS_PCS_1G_EN 0x00200000
#define IXGBE_LINKS_1G_AN_EN 0x00100000
#define IXGBE_LINKS_KX_AN_IDLE 0x00080000
@@ -762,9 +1302,35 @@
#define IXGBE_LINKS_TL_FAULT 0x00001000
#define IXGBE_LINKS_SIGNAL 0x00000F00
+#define IXGBE_LINKS_SPEED_82599 0x30000000
+#define IXGBE_LINKS_SPEED_10G_82599 0x30000000
+#define IXGBE_LINKS_SPEED_1G_82599 0x20000000
+#define IXGBE_LINKS_SPEED_100_82599 0x10000000
#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
+#define FIBER_LINK_UP_LIMIT 50
+
+/* PCS1GLSTA Bit Masks */
+#define IXGBE_PCS1GLSTA_LINK_OK 1
+#define IXGBE_PCS1GLSTA_SYNK_OK 0x10
+#define IXGBE_PCS1GLSTA_AN_COMPLETE 0x10000
+#define IXGBE_PCS1GLSTA_AN_PAGE_RX 0x20000
+#define IXGBE_PCS1GLSTA_AN_TIMED_OUT 0x40000
+#define IXGBE_PCS1GLSTA_AN_REMOTE_FAULT 0x80000
+#define IXGBE_PCS1GLSTA_AN_ERROR_RWS 0x100000
+
+#define IXGBE_PCS1GANA_SYM_PAUSE 0x80
+#define IXGBE_PCS1GANA_ASM_PAUSE 0x100
+
+/* PCS1GLCTL Bit Masks */
+#define IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN 0x00040000 /* PCS 1G autoneg to en */
+#define IXGBE_PCS1GLCTL_FLV_LINK_UP 1
+#define IXGBE_PCS1GLCTL_FORCE_LINK 0x20
+#define IXGBE_PCS1GLCTL_LOW_LINK_LATCH 0x40
+#define IXGBE_PCS1GLCTL_AN_ENABLE 0x10000
+#define IXGBE_PCS1GLCTL_AN_RESTART 0x20000
+
/* SW Semaphore Register bitmasks */
#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
@@ -816,6 +1382,11 @@
#define IXGBE_FW_PTR 0x0F
#define IXGBE_PBANUM0_PTR 0x15
#define IXGBE_PBANUM1_PTR 0x16
+#define IXGBE_PCIE_MSIX_82599_CAPS 0x72
+#define IXGBE_PCIE_MSIX_82598_CAPS 0x62
+
+/* MSI-X capability fields masks */
+#define IXGBE_PCIE_MSIX_TBL_SZ_MASK 0x7FF
/* Legacy EEPROM word offsets */
#define IXGBE_ISCSI_BOOT_CAPS 0x0033
@@ -864,6 +1435,8 @@
#define IXGBE_PCI_LINK_SPEED 0xF
#define IXGBE_PCI_LINK_SPEED_2500 0x1
#define IXGBE_PCI_LINK_SPEED_5000 0x2
+#define IXGBE_PCI_HEADER_TYPE_REGISTER 0x0E
+#define IXGBE_PCI_HEADER_TYPE_MULTIFUNC 0x80
/* Number of 100 microseconds we wait for PCI Express master disable */
#define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800
@@ -916,6 +1489,7 @@
#define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */
#define IXGBE_RXCTRL_DMBYPS 0x00000002 /* Descriptor Monitor Bypass */
#define IXGBE_RXDCTL_ENABLE 0x02000000 /* Enable specific Rx Queue */
+#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */
#define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
#define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
@@ -926,9 +1500,23 @@
/* Receive Priority Flow Control Enable */
#define IXGBE_FCTRL_RPFCE 0x00004000
#define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */
+#define IXGBE_MFLCN_PMCF 0x00000001 /* Pass MAC Control Frames */
+#define IXGBE_MFLCN_DPF 0x00000002 /* Discard Pause Frame */
+#define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */
+#define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */
/* Multiple Receive Queue Control */
#define IXGBE_MRQC_RSSEN 0x00000001 /* RSS Enable */
+#define IXGBE_MRQC_MRQE_MASK 0xF /* Bits 3:0 */
+#define IXGBE_MRQC_RT8TCEN 0x00000002 /* 8 TC no RSS */
+#define IXGBE_MRQC_RT4TCEN 0x00000003 /* 4 TC no RSS */
+#define IXGBE_MRQC_RTRSS8TCEN 0x00000004 /* 8 TC w/ RSS */
+#define IXGBE_MRQC_RTRSS4TCEN 0x00000005 /* 4 TC w/ RSS */
+#define IXGBE_MRQC_VMDQEN 0x00000008 /* VMDq2 64 pools no RSS */
+#define IXGBE_MRQC_VMDQRSS32EN 0x0000000A /* VMDq2 32 pools w/ RSS */
+#define IXGBE_MRQC_VMDQRSS64EN 0x0000000B /* VMDq2 64 pools w/ RSS */
+#define IXGBE_MRQC_VMDQRT8TCEN 0x0000000C /* VMDq2/RT 16 pool 8 TC */
+#define IXGBE_MRQC_VMDQRT4TCEN 0x0000000D /* VMDq2/RT 32 pool 4 TC */
#define IXGBE_MRQC_RSS_FIELD_MASK 0xFFFF0000
#define IXGBE_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define IXGBE_MRQC_RSS_FIELD_IPV4 0x00020000
@@ -939,6 +1527,12 @@
#define IXGBE_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define IXGBE_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
+#define IXGBE_MRQC_L3L4TXSWEN 0x00008000
+
+/* Queue Drop Enable */
+#define IXGBE_QDE_ENABLE 0x00000001
+#define IXGBE_QDE_IDX_MASK 0x00007F00
+#define IXGBE_QDE_IDX_SHIFT 8
#define IXGBE_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
#define IXGBE_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
@@ -950,10 +1544,25 @@
#define IXGBE_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
#define IXGBE_TXD_STAT_DD 0x00000001 /* Descriptor Done */
+#define IXGBE_RXDADV_IPSEC_STATUS_SECP 0x00020000
+#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000
+#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000
+#define IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED 0x18000000
+#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000
+/* Multiple Transmit Queue Command Register */
+#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_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
+
/* Receive Descriptor bit definitions */
#define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */
#define IXGBE_RXD_STAT_EOP 0x02 /* End of Packet */
+#define IXGBE_RXD_STAT_FLM 0x04 /* FDir Match */
#define IXGBE_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
+#define IXGBE_RXDADV_NEXTP_MASK 0x000FFFF0 /* Next Descriptor Index */
+#define IXGBE_RXDADV_NEXTP_SHIFT 0x00000004
#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define IXGBE_RXD_STAT_L4CS 0x20 /* L4 xsum calculated */
#define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
@@ -962,6 +1571,10 @@
#define IXGBE_RXD_STAT_VEXT 0x200 /* 1st VLAN found */
#define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
#define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
+#define IXGBE_RXD_STAT_LLINT 0x800 /* Pkt caused Low Latency Interrupt */
+#define IXGBE_RXD_STAT_TS 0x10000 /* Time Stamp */
+#define IXGBE_RXD_STAT_SECP 0x20000 /* Security Processing */
+#define IXGBE_RXD_STAT_LB 0x40000 /* Loopback Status */
#define IXGBE_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
#define IXGBE_RXD_ERR_CE 0x01 /* CRC Error */
#define IXGBE_RXD_ERR_LE 0x02 /* Length Error */
@@ -970,6 +1583,8 @@
#define IXGBE_RXD_ERR_USE 0x20 /* Undersize Error */
#define IXGBE_RXD_ERR_TCPE 0x40 /* TCP/UDP Checksum Error */
#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_HBO 0x00800000 /*Header Buffer Overflow */
#define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */
#define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */
@@ -984,9 +1599,23 @@
#define IXGBE_RXD_CFI_MASK 0x1000 /* CFI is bit 12 */
#define IXGBE_RXD_CFI_SHIFT 12
+#define IXGBE_RXDADV_STAT_DD IXGBE_RXD_STAT_DD /* Done */
+#define IXGBE_RXDADV_STAT_EOP IXGBE_RXD_STAT_EOP /* End of Packet */
+#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 */
+
+/* PSRTYPE bit definitions */
+#define IXGBE_PSRTYPE_TCPHDR 0x00000010
+#define IXGBE_PSRTYPE_UDPHDR 0x00000020
+#define IXGBE_PSRTYPE_IPV4HDR 0x00000100
+#define IXGBE_PSRTYPE_IPV6HDR 0x00000200
/* SRRCTL bit definitions */
#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
+#define IXGBE_SRRCTL_RDMTS_SHIFT 22
+#define IXGBE_SRRCTL_RDMTS_MASK 0x01C00000
+#define IXGBE_SRRCTL_DROP_EN 0x10000000
#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F
#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00
#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000
@@ -1001,6 +1630,7 @@
#define IXGBE_RXDADV_RSSTYPE_MASK 0x0000000F
#define IXGBE_RXDADV_PKTTYPE_MASK 0x0000FFF0
+#define IXGBE_RXDADV_PKTTYPE_MASK_EX 0x0001FFF0
#define IXGBE_RXDADV_HDRBUFLEN_MASK 0x00007FE0
#define IXGBE_RXDADV_HDRBUFLEN_SHIFT 5
#define IXGBE_RXDADV_SPLITHEADER_EN 0x00001000
@@ -1028,6 +1658,20 @@
#define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */
#define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */
#define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */
+#define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */
+#define IXGBE_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */
+#define IXGBE_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */
+#define IXGBE_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */
+#define IXGBE_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */
+#define IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */
+
+/* Security Processing bit Indication */
+#define IXGBE_RXDADV_LNKSEC_STATUS_SECP 0x00020000
+#define IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000
+
/* Masks to determine if packets should be dropped due to frame errors */
#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
IXGBE_RXD_ERR_CE | \
@@ -1057,6 +1701,14 @@
#define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority in upper 3 of 16 */
#define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT IXGBE_RX_DESC_SPECIAL_PRI_SHIFT
+/* Little Endian defines */
+#ifndef __le32
+#define __le32 u32
+#endif
+#ifndef __le64
+#define __le64 u64
+
+#endif
/* Transmit Descriptor - Legacy */
struct ixgbe_legacy_tx_desc {
@@ -1144,6 +1796,9 @@ struct ixgbe_adv_tx_context_desc {
/* Adv Transmit Descriptor Config Masks */
#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
+#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */
+#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */
+#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */
#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
#define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Desc */
#define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
@@ -1178,6 +1833,9 @@ struct ixgbe_adv_tx_context_desc {
#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
#define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */
#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /*Req requires Markers and CRC*/
+#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_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
@@ -1191,6 +1849,12 @@ typedef u32 ixgbe_link_speed;
#define IXGBE_LINK_SPEED_10GB_FULL 0x0080
#define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
IXGBE_LINK_SPEED_10GB_FULL)
+#define IXGBE_LINK_SPEED_82599_AUTONEG (IXGBE_LINK_SPEED_100_FULL | \
+ IXGBE_LINK_SPEED_1GB_FULL | \
+ IXGBE_LINK_SPEED_10GB_FULL)
+
+#define IXGBE_PCIE_DEV_CTRL_2 0xC8
+#define PCIE_COMPL_TO_VALUE 0x05
/* Physical layer type */
typedef u32 ixgbe_physical_layer;
@@ -1207,7 +1871,6 @@ typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200
#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
-
enum ixgbe_eeprom_type {
ixgbe_eeprom_uninitialized = 0,
ixgbe_eeprom_spi,
@@ -1217,12 +1880,14 @@ enum ixgbe_eeprom_type {
enum ixgbe_mac_type {
ixgbe_mac_unknown = 0,
ixgbe_mac_82598EB,
+ ixgbe_mac_82599EB,
ixgbe_num_macs
};
enum ixgbe_phy_type {
ixgbe_phy_unknown = 0,
ixgbe_phy_tn,
+ ixgbe_phy_cu_unknown,
ixgbe_phy_qt,
ixgbe_phy_xaui,
ixgbe_phy_nl,
@@ -1231,22 +1896,31 @@ enum ixgbe_phy_type {
ixgbe_phy_sfp_avago,
ixgbe_phy_sfp_ftl,
ixgbe_phy_sfp_unknown,
+ ixgbe_phy_sfp_intel,
ixgbe_phy_generic
};
/*
* SFP+ module type IDs:
*
- * ID Module Type
+ * ID Module Type
* =============
- * 0 SFP_DA_CU
- * 1 SFP_SR
- * 2 SFP_LR
+ * 0 SFP_DA_CU
+ * 1 SFP_SR
+ * 2 SFP_LR
+ * 3 SFP_DA_CU_CORE0 - 82599-specific
+ * 4 SFP_DA_CU_CORE1 - 82599-specific
+ * 5 SFP_SR/LR_CORE0 - 82599-specific
+ * 6 SFP_SR/LR_CORE1 - 82599-specific
*/
enum ixgbe_sfp_type {
ixgbe_sfp_type_da_cu = 0,
ixgbe_sfp_type_sr = 1,
ixgbe_sfp_type_lr = 2,
+ ixgbe_sfp_type_da_cu_core0 = 3,
+ ixgbe_sfp_type_da_cu_core1 = 4,
+ ixgbe_sfp_type_srlr_core0 = 5,
+ ixgbe_sfp_type_srlr_core1 = 6,
ixgbe_sfp_type_not_present = 0xFFFE,
ixgbe_sfp_type_unknown = 0xFFFF
};
@@ -1260,14 +1934,51 @@ enum ixgbe_media_type {
};
/* Flow Control Settings */
-enum ixgbe_fc_type {
+enum ixgbe_fc_mode {
ixgbe_fc_none = 0,
ixgbe_fc_rx_pause,
ixgbe_fc_tx_pause,
ixgbe_fc_full,
+#ifdef CONFIG_DCB
+ ixgbe_fc_pfc,
+#endif
ixgbe_fc_default
};
+/* PCI bus types */
+enum ixgbe_bus_type {
+ ixgbe_bus_type_unknown = 0,
+ ixgbe_bus_type_pci,
+ ixgbe_bus_type_pcix,
+ ixgbe_bus_type_pci_express,
+ ixgbe_bus_type_reserved
+};
+
+/* PCI bus speeds */
+enum ixgbe_bus_speed {
+ ixgbe_bus_speed_unknown = 0,
+ ixgbe_bus_speed_33,
+ ixgbe_bus_speed_66,
+ ixgbe_bus_speed_100,
+ ixgbe_bus_speed_120,
+ ixgbe_bus_speed_133,
+ ixgbe_bus_speed_2500,
+ ixgbe_bus_speed_5000,
+ ixgbe_bus_speed_reserved
+};
+
+/* PCI bus widths */
+enum ixgbe_bus_width {
+ ixgbe_bus_width_unknown = 0,
+ ixgbe_bus_width_pcie_x1,
+ ixgbe_bus_width_pcie_x2,
+ ixgbe_bus_width_pcie_x4 = 4,
+ ixgbe_bus_width_pcie_x8 = 8,
+ ixgbe_bus_width_32,
+ ixgbe_bus_width_64,
+ ixgbe_bus_width_reserved
+};
+
struct ixgbe_addr_filter_info {
u32 num_mc_addrs;
u32 rar_used_count;
@@ -1277,6 +1988,16 @@ struct ixgbe_addr_filter_info {
bool user_set_promisc;
};
+/* Bus parameters */
+struct ixgbe_bus_info {
+ enum ixgbe_bus_speed speed;
+ enum ixgbe_bus_width width;
+ enum ixgbe_bus_type type;
+
+ u16 func;
+ u16 lan_id;
+};
+
/* Flow control parameters */
struct ixgbe_fc_info {
u32 high_water; /* Flow Control High-water */
@@ -1284,8 +2005,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 */
- enum ixgbe_fc_type type; /* Type of flow control */
- enum ixgbe_fc_type original_type;
+ enum ixgbe_fc_mode current_mode; /* FC mode in effect */
+ enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */
};
/* Statistics counters collected by the MAC */
@@ -1345,6 +2066,14 @@ struct ixgbe_hw_stats {
u64 qptc[16];
u64 qbrc[16];
u64 qbtc[16];
+ u64 qprdc[16];
+ u64 pxon2offc[8];
+ u64 fdirustat_add;
+ u64 fdirustat_remove;
+ u64 fdirfstat_fadd;
+ u64 fdirfstat_fremove;
+ u64 fdirmatch;
+ u64 fdirmiss;
};
/* forward declaration */
@@ -1369,12 +2098,15 @@ struct ixgbe_mac_operations {
s32 (*start_hw)(struct ixgbe_hw *);
s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
- s32 (*get_supported_physical_layer)(struct ixgbe_hw *);
+ u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
s32 (*stop_adapter)(struct ixgbe_hw *);
s32 (*get_bus_info)(struct ixgbe_hw *);
+ void (*set_lan_id)(struct ixgbe_hw *);
s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*);
s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8);
+ s32 (*setup_sfp)(struct ixgbe_hw *);
+ s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
/* Link */
s32 (*setup_link)(struct ixgbe_hw *);
@@ -1430,7 +2162,7 @@ struct ixgbe_phy_operations {
struct ixgbe_eeprom_info {
struct ixgbe_eeprom_operations ops;
enum ixgbe_eeprom_type type;
- u32 semaphore_delay;
+ u32 semaphore_delay;
u16 word_size;
u16 address_bits;
};
@@ -1446,11 +2178,12 @@ struct ixgbe_mac_info {
u32 num_rar_entries;
u32 max_tx_queues;
u32 max_rx_queues;
- u32 link_attach_type;
- u32 link_mode_select;
- bool link_settings_loaded;
+ u32 max_msix_vectors;
+ u32 orig_autoc;
+ u32 orig_autoc2;
+ bool orig_link_settings_stored;
bool autoneg;
- bool autoneg_failed;
+ bool autoneg_succeeded;
};
struct ixgbe_phy_info {
@@ -1464,6 +2197,7 @@ struct ixgbe_phy_info {
bool reset_disable;
ixgbe_autoneg_advertised autoneg_advertised;
bool autoneg_wait_to_complete;
+ bool multispeed_fiber;
};
struct ixgbe_hw {
@@ -1474,6 +2208,7 @@ struct ixgbe_hw {
struct ixgbe_fc_info fc;
struct ixgbe_phy_info phy;
struct ixgbe_eeprom_info eeprom;
+ struct ixgbe_bus_info bus;
u16 device_id;
u16 vendor_id;
u16 subsystem_device_id;
@@ -1512,6 +2247,7 @@ struct ixgbe_info {
#define IXGBE_ERR_I2C -18
#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_NOT_IMPLEMENTED 0x7FFFFFFF
#endif /* _IXGBE_TYPE_H_ */
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 01474572056..d3bf2f017cc 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -141,7 +141,7 @@ static int ixpdev_poll(struct napi_struct *napi, int budget)
break;
} while (ixp2000_reg_read(IXP2000_IRQ_THD_RAW_STATUS_A_0) & 0x00ff);
- netif_rx_complete(napi);
+ napi_complete(napi);
ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0x00ff);
return rx;
@@ -204,7 +204,7 @@ static irqreturn_t ixpdev_interrupt(int irq, void *dev_id)
ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
if (likely(napi_schedule_prep(&ip->napi))) {
- __netif_rx_schedule(&ip->napi);
+ __napi_schedule(&ip->napi);
} else {
printk(KERN_CRIT "ixp2000: irq while polling!!\n");
}
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 334ff9e12cd..14248cfc3df 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -131,7 +131,8 @@ static int __init sonic_probe1(struct net_device *dev)
if (sonic_debug && version_printed++ == 0)
printk(version);
- printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", lp->device->bus_id, dev->base_addr);
+ printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ",
+ dev_name(lp->device), dev->base_addr);
/*
* Put the sonic into software reset, then
@@ -156,7 +157,8 @@ static int __init sonic_probe1(struct net_device *dev)
if ((lp->descriptors = dma_alloc_coherent(lp->device,
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+ printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+ dev_name(lp->device));
goto out;
}
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 08b34051c64..860dcd98a07 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -429,10 +429,9 @@ jme_check_link(struct net_device *netdev, int testonly)
jme->phylink = phylink;
- ghc = jme->reg_ghc & ~(GHC_SPEED_10M |
- GHC_SPEED_100M |
- GHC_SPEED_1000M |
- GHC_DPX);
+ ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX |
+ GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE |
+ GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY);
switch (phylink & PHY_LINK_SPEED_MASK) {
case PHY_LINK_SPEED_10M:
ghc |= GHC_SPEED_10M |
@@ -957,13 +956,14 @@ jme_process_receive(struct jme_adapter *jme, int limit)
goto out_inc;
i = atomic_read(&rxring->next_to_clean);
- while (limit-- > 0) {
+ while (limit > 0) {
rxdesc = rxring->desc;
rxdesc += i;
if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) ||
!(rxdesc->descwb.desccnt & RXWBDCNT_WBCPL))
goto out;
+ --limit;
desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT;
@@ -1833,7 +1833,7 @@ jme_tx_vlan(struct sk_buff *skb, __le16 *vlan, u8 *flags)
}
static int
-jme_fill_first_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
+jme_fill_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
{
struct jme_ring *txring = jme->txring;
struct txdesc *txdesc;
@@ -1863,6 +1863,7 @@ jme_fill_first_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
if (jme_tx_tso(skb, &txdesc->desc1.mss, &flags))
jme_tx_csum(jme, skb, &flags);
jme_tx_vlan(skb, &txdesc->desc1.vlan, &flags);
+ jme_map_tx_skb(jme, skb, idx);
txdesc->desc1.flags = flags;
/*
* Set tx buffer info after telling NIC to send
@@ -1932,8 +1933,7 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_BUSY;
}
- jme_map_tx_skb(jme, skb, idx);
- jme_fill_first_tx_desc(jme, skb, idx);
+ jme_fill_tx_desc(jme, skb, idx);
jwrite32(jme, JME_TXCS, jme->reg_txcs |
TXCS_SELECT_QUEUE0 |
@@ -2590,6 +2590,16 @@ static const struct ethtool_ops jme_ethtool_ops = {
static int
jme_pci_dma64(struct pci_dev *pdev)
{
+ if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
+ !pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+ if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+ return 1;
+
+ if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
+ !pci_set_dma_mask(pdev, DMA_40BIT_MASK))
+ if (!pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK))
+ return 1;
+
if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
if (!pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
return 0;
@@ -2856,7 +2866,11 @@ jme_init_one(struct pci_dev *pdev,
goto err_out_free_shadow;
}
- msg_probe(jme, "JMC250 gigabit%s ver:%x rev:%x macaddr:%pM\n",
+ msg_probe(jme, "%s%s ver:%x rev:%x macaddr:%pM\n",
+ (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC250) ?
+ "JMC250 Gigabit Ethernet" :
+ (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC260) ?
+ "JMC260 Fast Ethernet" : "Unknown",
(jme->fpgaver != 0) ? " (FPGA)" : "",
(jme->fpgaver != 0) ? jme->fpgaver : jme->chiprev,
jme->rev, netdev->dev_addr);
@@ -3002,7 +3016,7 @@ static struct pci_driver jme_driver = {
static int __init
jme_init_module(void)
{
- printk(KERN_INFO PFX "JMicron JMC250 gigabit ethernet "
+ printk(KERN_INFO PFX "JMicron JMC2XX ethernet "
"driver version %s\n", DRV_VERSION);
return pci_register_driver(&jme_driver);
}
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index 5154411b5e6..0996a069ac7 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -25,7 +25,7 @@
#define __JME_H_INCLUDED__
#define DRV_NAME "jme"
-#define DRV_VERSION "1.0.3"
+#define DRV_VERSION "1.0.4"
#define PFX DRV_NAME ": "
#define PCI_DEVICE_ID_JMICRON_JMC250 0x0250
@@ -398,15 +398,15 @@ struct jme_ring {
#define JME_NAPI_WEIGHT(w) int w
#define JME_NAPI_WEIGHT_VAL(w) w
#define JME_NAPI_WEIGHT_SET(w, r)
-#define JME_RX_COMPLETE(dev, napis) netif_rx_complete(napis)
+#define JME_RX_COMPLETE(dev, napis) napi_complete(napis)
#define JME_NAPI_ENABLE(priv) napi_enable(&priv->napi);
#define JME_NAPI_DISABLE(priv) \
if (!napi_disable_pending(&priv->napi)) \
napi_disable(&priv->napi);
#define JME_RX_SCHEDULE_PREP(priv) \
- netif_rx_schedule_prep(&priv->napi)
+ napi_schedule_prep(&priv->napi)
#define JME_RX_SCHEDULE(priv) \
- __netif_rx_schedule(&priv->napi);
+ __napi_schedule(&priv->napi);
/*
* Jmac Adapter Private data
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 1d6e48e1336..38d6649a29c 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -334,7 +334,7 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
DMA_STAT_HALT | DMA_STAT_ERR),
&lp->rx_dma_regs->dmasm);
- netif_rx_schedule(&lp->napi);
+ napi_schedule(&lp->napi);
if (dmas & DMA_STAT_ERR)
printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name);
@@ -416,6 +416,9 @@ static int korina_rx(struct net_device *dev, int limit)
if (devcs & ETH_RX_MP)
dev->stats.multicast++;
+ /* 16 bit align */
+ skb_reserve(skb_new, 2);
+
lp->rx_skb[lp->rx_next_done] = skb_new;
}
@@ -465,7 +468,7 @@ static int korina_poll(struct napi_struct *napi, int budget)
work_done = korina_rx(dev, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
writel(readl(&lp->rx_dma_regs->dmasm) &
~(DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR),
@@ -740,6 +743,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
static void korina_alloc_ring(struct net_device *dev)
{
struct korina_private *lp = netdev_priv(dev);
+ struct sk_buff *skb;
int i;
/* Initialize the transmit descriptors */
@@ -755,8 +759,6 @@ static void korina_alloc_ring(struct net_device *dev)
/* Initialize the receive descriptors */
for (i = 0; i < KORINA_NUM_RDS; i++) {
- struct sk_buff *skb = lp->rx_skb[i];
-
skb = dev_alloc_skb(KORINA_RBSIZE + 2);
if (!skb)
break;
@@ -769,11 +771,12 @@ static void korina_alloc_ring(struct net_device *dev)
lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]);
}
- /* loop back */
- lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[0]);
- lp->rx_next_done = 0;
+ /* loop back receive descriptors, so the last
+ * descriptor points to the first one */
+ lp->rd_ring[i - 1].link = CPHYSADDR(&lp->rd_ring[0]);
+ lp->rd_ring[i - 1].control |= DMA_DESC_COD;
- lp->rd_ring[i].control |= DMA_DESC_COD;
+ lp->rx_next_done = 0;
lp->rx_chain_head = 0;
lp->rx_chain_tail = 0;
lp->rx_chain_status = desc_empty;
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index d7afb938ea6..d83d4010656 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -391,7 +391,8 @@ MODULE_LICENSE("GPL");
*/
static int __init do_lance_probe(struct net_device *dev)
{
- int *port, result;
+ unsigned int *port;
+ int result;
if (high_memory <= phys_to_virt(16*1024*1024))
lance_need_isa_bounce_buffers = 0;
@@ -456,13 +457,13 @@ out:
static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
{
struct lance_private *lp;
- long dma_channels; /* Mark spuriously-busy DMA channels */
+ unsigned long dma_channels; /* Mark spuriously-busy DMA channels */
int i, reset_val, lance_version;
const char *chipname;
/* Flags for specific chips or boards. */
- unsigned char hpJ2405A = 0; /* HP ISA adaptor */
- int hp_builtin = 0; /* HP on-board ethernet. */
- static int did_version; /* Already printed version info. */
+ unsigned char hpJ2405A = 0; /* HP ISA adaptor */
+ int hp_builtin = 0; /* HP on-board ethernet. */
+ static int did_version; /* Already printed version info. */
unsigned long flags;
int err = -ENOMEM;
void __iomem *bios;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index a04da4ecaa8..f50501013b1 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -211,10 +211,10 @@ static int macb_mii_probe(struct net_device *dev)
/* attach the mac to the phy */
if (pdata && pdata->is_rmii) {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
} else {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
}
@@ -321,6 +321,10 @@ static void macb_tx(struct macb *bp)
printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
bp->dev->name);
+ /* Transfer ongoing, disable transmitter, to avoid confusion */
+ if (status & MACB_BIT(TGO))
+ macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE));
+
head = bp->tx_head;
/*Mark all the buffer as used to avoid sending a lost buffer*/
@@ -343,6 +347,10 @@ static void macb_tx(struct macb *bp)
}
bp->tx_head = bp->tx_tail = 0;
+
+ /* Enable the transmitter again */
+ if (status & MACB_BIT(TGO))
+ macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));
}
if (!(status & MACB_BIT(COMP)))
@@ -505,7 +513,6 @@ static int macb_rx(struct macb *bp, int budget)
static int macb_poll(struct napi_struct *napi, int budget)
{
struct macb *bp = container_of(napi, struct macb, napi);
- struct net_device *dev = bp->dev;
int work_done;
u32 status;
@@ -519,7 +526,7 @@ static int macb_poll(struct napi_struct *napi, int budget)
* this function was called last time, and no packets
* have been received since.
*/
- netif_rx_complete(napi);
+ napi_complete(napi);
goto out;
}
@@ -530,13 +537,13 @@ static int macb_poll(struct napi_struct *napi, int budget)
dev_warn(&bp->pdev->dev,
"No RX buffers complete, status = %02lx\n",
(unsigned long)status);
- netif_rx_complete(napi);
+ napi_complete(napi);
goto out;
}
work_done = macb_rx(bp, budget);
if (work_done < budget)
- netif_rx_complete(napi);
+ napi_complete(napi);
/*
* We've done what we can to clean the buffers. Make sure we
@@ -571,7 +578,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
}
if (status & MACB_RX_INT_FLAGS) {
- if (netif_rx_schedule_prep(&bp->napi)) {
+ if (napi_schedule_prep(&bp->napi)) {
/*
* There's no point taking any more interrupts
* until we have processed the buffers
@@ -579,7 +586,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
dev_dbg(&bp->pdev->dev,
"scheduling RX softirq\n");
- __netif_rx_schedule(&bp->napi);
+ __napi_schedule(&bp->napi);
}
}
@@ -1069,7 +1076,7 @@ static void macb_get_drvinfo(struct net_device *dev,
strcpy(info->driver, bp->pdev->dev.driver->name);
strcpy(info->version, "$Revision: 1.14 $");
- strcpy(info->bus_info, bp->pdev->dev.bus_id);
+ strcpy(info->bus_info, dev_name(&bp->pdev->dev));
}
static struct ethtool_ops macb_ethtool_ops = {
@@ -1226,8 +1233,8 @@ static int __init macb_probe(struct platform_device *pdev)
phydev = bp->phy_dev;
printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
return 0;
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 205bb05c25d..527166e35d5 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -176,7 +176,8 @@ static int __init macsonic_init(struct net_device *dev)
if ((lp->descriptors = dma_alloc_coherent(lp->device,
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+ printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+ dev_name(lp->device));
return -ENOMEM;
}
@@ -337,7 +338,7 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev)
sonic_version_printed = 1;
}
printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n",
- lp->device->bus_id, dev->base_addr);
+ dev_name(lp->device), dev->base_addr);
/* The PowerBook's SONIC is 16 bit always. */
if (macintosh_config->ident == MAC_MODEL_PB520) {
@@ -370,10 +371,10 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev)
}
printk(KERN_INFO
"%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
- lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset);
+ dev_name(lp->device), sr, lp->dma_bitmode?32:16, lp->reg_offset);
#if 0 /* This is sometimes useful to find out how MacOS configured the card. */
- printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+ printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif
@@ -525,12 +526,12 @@ static int __init mac_nubus_sonic_probe(struct net_device *dev)
sonic_version_printed = 1;
}
printk(KERN_INFO "%s: %s in slot %X\n",
- lp->device->bus_id, ndev->board->name, ndev->board->slot);
+ dev_name(lp->device), ndev->board->name, ndev->board->slot);
printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
- lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
+ dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
#if 0 /* This is sometimes useful to find out how MacOS configured the card. */
- printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+ printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 7e24b504868..70d3ef4a2c5 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -60,6 +60,47 @@ static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
return NULL;
}
+static void macvlan_hash_add(struct macvlan_dev *vlan)
+{
+ struct macvlan_port *port = vlan->port;
+ const unsigned char *addr = vlan->dev->dev_addr;
+
+ hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[addr[5]]);
+}
+
+static void macvlan_hash_del(struct macvlan_dev *vlan)
+{
+ hlist_del_rcu(&vlan->hlist);
+ synchronize_rcu();
+}
+
+static void macvlan_hash_change_addr(struct macvlan_dev *vlan,
+ const unsigned char *addr)
+{
+ macvlan_hash_del(vlan);
+ /* Now that we are unhashed it is safe to change the device
+ * address without confusing packet delivery.
+ */
+ memcpy(vlan->dev->dev_addr, addr, ETH_ALEN);
+ macvlan_hash_add(vlan);
+}
+
+static int macvlan_addr_busy(const struct macvlan_port *port,
+ const unsigned char *addr)
+{
+ /* Test to see if the specified multicast address is
+ * currently in use by the underlying device or
+ * another macvlan.
+ */
+ if (memcmp(port->dev->dev_addr, addr, ETH_ALEN) == 0)
+ return 1;
+
+ if (macvlan_hash_lookup(port, addr))
+ return 1;
+
+ return 0;
+}
+
static void macvlan_broadcast(struct sk_buff *skb,
const struct macvlan_port *port)
{
@@ -184,10 +225,13 @@ static const struct header_ops macvlan_hard_header_ops = {
static int macvlan_open(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- struct macvlan_port *port = vlan->port;
struct net_device *lowerdev = vlan->lowerdev;
int err;
+ err = -EBUSY;
+ if (macvlan_addr_busy(vlan->port, dev->dev_addr))
+ goto out;
+
err = dev_unicast_add(lowerdev, dev->dev_addr, ETH_ALEN);
if (err < 0)
goto out;
@@ -196,8 +240,7 @@ static int macvlan_open(struct net_device *dev)
if (err < 0)
goto del_unicast;
}
-
- hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[dev->dev_addr[5]]);
+ macvlan_hash_add(vlan);
return 0;
del_unicast:
@@ -217,8 +260,7 @@ static int macvlan_stop(struct net_device *dev)
dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
- hlist_del_rcu(&vlan->hlist);
- synchronize_rcu();
+ macvlan_hash_del(vlan);
return 0;
}
@@ -232,16 +274,21 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- if (!(dev->flags & IFF_UP))
- goto out;
+ if (!(dev->flags & IFF_UP)) {
+ /* Just copy in the new address */
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ } else {
+ /* Rehash and update the device filters */
+ if (macvlan_addr_busy(vlan->port, addr->sa_data))
+ return -EBUSY;
- err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN);
- if (err < 0)
- return err;
- dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+ if ((err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN)))
+ return err;
-out:
- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+
+ macvlan_hash_change_addr(vlan, addr->sa_data);
+ }
return 0;
}
@@ -461,12 +508,13 @@ static int macvlan_newlink(struct net_device *dev,
if (lowerdev == NULL)
return -ENODEV;
- /* Don't allow macvlans on top of other macvlans - its not really
- * wrong, but lockdep can't handle it and its not useful for anything
- * you couldn't do directly on top of the real device.
+ /* When creating macvlans on top of other macvlans - use
+ * the real device as the lowerdev.
*/
- if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops)
- return -ENODEV;
+ if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops) {
+ struct macvlan_dev *lowervlan = netdev_priv(lowerdev);
+ lowerdev = lowervlan->lowerdev;
+ }
if (!tb[IFLA_MTU])
dev->mtu = lowerdev->mtu;
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 4e7a5faf035..664835b822f 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -237,7 +237,7 @@ static void mipsnet_set_mclist(struct net_device *dev)
{
}
-static int __init mipsnet_probe(struct device *dev)
+static int __init mipsnet_probe(struct platform_device *dev)
{
struct net_device *netdev;
int err;
@@ -248,7 +248,7 @@ static int __init mipsnet_probe(struct device *dev)
goto out;
}
- dev_set_drvdata(dev, netdev);
+ platform_set_drvdata(dev, netdev);
netdev->open = mipsnet_open;
netdev->stop = mipsnet_close;
@@ -293,23 +293,25 @@ out:
return err;
}
-static int __devexit mipsnet_device_remove(struct device *device)
+static int __devexit mipsnet_device_remove(struct platform_device *device)
{
- struct net_device *dev = dev_get_drvdata(device);
+ struct net_device *dev = platform_get_drvdata(device);
unregister_netdev(dev);
release_region(dev->base_addr, sizeof(struct mipsnet_regs));
free_netdev(dev);
- dev_set_drvdata(device, NULL);
+ platform_set_drvdata(device, NULL);
return 0;
}
-static struct device_driver mipsnet_driver = {
- .name = mipsnet_string,
- .bus = &platform_bus_type,
- .probe = mipsnet_probe,
- .remove = __devexit_p(mipsnet_device_remove),
+static struct platform_driver mipsnet_driver = {
+ .driver = {
+ .name = mipsnet_string,
+ .owner = THIS_MODULE,
+ },
+ .probe = mipsnet_probe,
+ .remove = __devexit_p(mipsnet_device_remove),
};
static int __init mipsnet_init_module(void)
@@ -319,7 +321,7 @@ static int __init mipsnet_init_module(void)
printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
"(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
- err = driver_register(&mipsnet_driver);
+ err = platform_driver_register(&mipsnet_driver);
if (err)
printk(KERN_ERR "Driver registration failed\n");
@@ -328,7 +330,7 @@ static int __init mipsnet_init_module(void)
static void __exit mipsnet_exit_module(void)
{
- driver_unregister(&mipsnet_driver);
+ platform_driver_unregister(&mipsnet_driver);
}
module_init(mipsnet_init_module);
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index a7a97bf998f..21040a0d81f 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -1,7 +1,7 @@
obj-$(CONFIG_MLX4_CORE) += mlx4_core.o
mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
- mr.o pd.o port.o profile.o qp.o reset.o srq.o
+ mr.o pd.o port.o profile.o qp.o reset.o sense.o srq.o
obj-$(CONFIG_MLX4_EN) += mlx4_en.o
diff --git a/drivers/net/mlx4/catas.c b/drivers/net/mlx4/catas.c
index f094ee00c41..aa9674b7f19 100644
--- a/drivers/net/mlx4/catas.c
+++ b/drivers/net/mlx4/catas.c
@@ -42,7 +42,6 @@ enum {
static DEFINE_SPINLOCK(catas_lock);
static LIST_HEAD(catas_list);
-static struct workqueue_struct *catas_wq;
static struct work_struct catas_work;
static int internal_err_reset = 1;
@@ -77,7 +76,7 @@ static void poll_catas(unsigned long dev_ptr)
list_add(&priv->catas_err.list, &catas_list);
spin_unlock(&catas_lock);
- queue_work(catas_wq, &catas_work);
+ queue_work(mlx4_wq, &catas_work);
}
} else
mod_timer(&priv->catas_err.timer,
@@ -146,18 +145,7 @@ void mlx4_stop_catas_poll(struct mlx4_dev *dev)
spin_unlock_irq(&catas_lock);
}
-int __init mlx4_catas_init(void)
+void __init mlx4_catas_init(void)
{
INIT_WORK(&catas_work, catas_reset);
-
- catas_wq = create_singlethread_workqueue("mlx4_err");
- if (!catas_wq)
- return -ENOMEM;
-
- return 0;
-}
-
-void mlx4_catas_cleanup(void)
-{
- destroy_workqueue(catas_wq);
}
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index c61b0bdca1a..a4130e76499 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -768,6 +768,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
skb->ip_summed = ip_summed;
skb->protocol = eth_type_trans(skb, dev);
+ skb_record_rx_queue(skb, cq->ring);
/* Push it up the stack */
if (priv->vlgrp && (be32_to_cpu(cqe->vlan_my_qpn) &
@@ -814,7 +815,7 @@ void mlx4_en_rx_irq(struct mlx4_cq *mcq)
struct mlx4_en_priv *priv = netdev_priv(cq->dev);
if (priv->port_up)
- netif_rx_schedule(&cq->napi);
+ napi_schedule(&cq->napi);
else
mlx4_en_arm_cq(priv, cq);
}
@@ -834,7 +835,7 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
INC_PERF_COUNTER(priv->pstats.napi_quota);
else {
/* Done for now */
- netif_rx_complete(napi);
+ napi_complete(napi);
mlx4_en_arm_cq(priv, cq);
}
return done;
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 2c19bff7cba..8830dcb92ec 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -163,6 +163,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
int cqn;
int eqes_found = 0;
int set_ci = 0;
+ int port;
while ((eqe = next_eqe_sw(eq))) {
/*
@@ -203,11 +204,16 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
break;
case MLX4_EVENT_TYPE_PORT_CHANGE:
- mlx4_dispatch_event(dev,
- eqe->subtype == MLX4_PORT_CHANGE_SUBTYPE_ACTIVE ?
- MLX4_DEV_EVENT_PORT_UP :
- MLX4_DEV_EVENT_PORT_DOWN,
- be32_to_cpu(eqe->event.port_change.port) >> 28);
+ port = be32_to_cpu(eqe->event.port_change.port) >> 28;
+ if (eqe->subtype == MLX4_PORT_CHANGE_SUBTYPE_DOWN) {
+ mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_DOWN,
+ port);
+ mlx4_priv(dev)->sense.do_sense_port[port] = 1;
+ } else {
+ mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_UP,
+ port);
+ mlx4_priv(dev)->sense.do_sense_port[port] = 0;
+ }
break;
case MLX4_EVENT_TYPE_CQ_ERROR:
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 6ef2490d5c3..a66f5b2fd28 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -51,6 +51,8 @@ MODULE_DESCRIPTION("Mellanox ConnectX HCA low-level driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);
+struct workqueue_struct *mlx4_wq;
+
#ifdef CONFIG_MLX4_DEBUG
int mlx4_debug_level = 0;
@@ -98,24 +100,23 @@ module_param_named(use_prio, use_prio, bool, 0444);
MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports "
"(0/1, default 0)");
-static int mlx4_check_port_params(struct mlx4_dev *dev,
- enum mlx4_port_type *port_type)
+int mlx4_check_port_params(struct mlx4_dev *dev,
+ enum mlx4_port_type *port_type)
{
int i;
for (i = 0; i < dev->caps.num_ports - 1; i++) {
- if (port_type[i] != port_type[i+1] &&
- !(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
- mlx4_err(dev, "Only same port types supported "
- "on this HCA, aborting.\n");
- return -EINVAL;
+ if (port_type[i] != port_type[i + 1]) {
+ if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+ mlx4_err(dev, "Only same port types supported "
+ "on this HCA, aborting.\n");
+ return -EINVAL;
+ }
+ if (port_type[i] == MLX4_PORT_TYPE_ETH &&
+ port_type[i + 1] == MLX4_PORT_TYPE_IB)
+ return -EINVAL;
}
}
- if ((port_type[0] == MLX4_PORT_TYPE_ETH) &&
- (port_type[1] == MLX4_PORT_TYPE_IB)) {
- mlx4_err(dev, "eth-ib configuration is not supported.\n");
- return -EINVAL;
- }
for (i = 0; i < dev->caps.num_ports; i++) {
if (!(port_type[i] & dev->caps.supported_type[i+1])) {
@@ -225,6 +226,9 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.port_type[i] = MLX4_PORT_TYPE_IB;
else
dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
+ dev->caps.possible_type[i] = dev->caps.port_type[i];
+ mlx4_priv(dev)->sense.sense_allowed[i] =
+ dev->caps.supported_type[i] == MLX4_PORT_TYPE_AUTO;
if (dev->caps.log_num_macs > dev_cap->log_max_macs[i]) {
dev->caps.log_num_macs = dev_cap->log_max_macs[i];
@@ -263,14 +267,16 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
* Change the port configuration of the device.
* Every user of this function must hold the port mutex.
*/
-static int mlx4_change_port_types(struct mlx4_dev *dev,
- enum mlx4_port_type *port_types)
+int mlx4_change_port_types(struct mlx4_dev *dev,
+ enum mlx4_port_type *port_types)
{
int err = 0;
int change = 0;
int port;
for (port = 0; port < dev->caps.num_ports; port++) {
+ /* Change the port type only if the new type is different
+ * from the current, and not set to Auto */
if (port_types[port] != dev->caps.port_type[port + 1]) {
change = 1;
dev->caps.port_type[port + 1] = port_types[port];
@@ -302,10 +308,17 @@ static ssize_t show_port_type(struct device *dev,
struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info,
port_attr);
struct mlx4_dev *mdev = info->dev;
+ char type[8];
+
+ sprintf(type, "%s",
+ (mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_IB) ?
+ "ib" : "eth");
+ if (mdev->caps.possible_type[info->port] == MLX4_PORT_TYPE_AUTO)
+ sprintf(buf, "auto (%s)\n", type);
+ else
+ sprintf(buf, "%s\n", type);
- return sprintf(buf, "%s\n",
- mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_IB ?
- "ib" : "eth");
+ return strlen(buf);
}
static ssize_t set_port_type(struct device *dev,
@@ -317,6 +330,7 @@ static ssize_t set_port_type(struct device *dev,
struct mlx4_dev *mdev = info->dev;
struct mlx4_priv *priv = mlx4_priv(mdev);
enum mlx4_port_type types[MLX4_MAX_PORTS];
+ enum mlx4_port_type new_types[MLX4_MAX_PORTS];
int i;
int err = 0;
@@ -324,26 +338,56 @@ static ssize_t set_port_type(struct device *dev,
info->tmp_type = MLX4_PORT_TYPE_IB;
else if (!strcmp(buf, "eth\n"))
info->tmp_type = MLX4_PORT_TYPE_ETH;
+ else if (!strcmp(buf, "auto\n"))
+ info->tmp_type = MLX4_PORT_TYPE_AUTO;
else {
mlx4_err(mdev, "%s is not supported port type\n", buf);
return -EINVAL;
}
+ mlx4_stop_sense(mdev);
mutex_lock(&priv->port_mutex);
- for (i = 0; i < mdev->caps.num_ports; i++)
+ /* Possible type is always the one that was delivered */
+ mdev->caps.possible_type[info->port] = info->tmp_type;
+
+ for (i = 0; i < mdev->caps.num_ports; i++) {
types[i] = priv->port[i+1].tmp_type ? priv->port[i+1].tmp_type :
- mdev->caps.port_type[i+1];
+ mdev->caps.possible_type[i+1];
+ if (types[i] == MLX4_PORT_TYPE_AUTO)
+ types[i] = mdev->caps.port_type[i+1];
+ }
- err = mlx4_check_port_params(mdev, types);
+ if (!(mdev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+ for (i = 1; i <= mdev->caps.num_ports; i++) {
+ if (mdev->caps.possible_type[i] == MLX4_PORT_TYPE_AUTO) {
+ mdev->caps.possible_type[i] = mdev->caps.port_type[i];
+ err = -EINVAL;
+ }
+ }
+ }
+ if (err) {
+ mlx4_err(mdev, "Auto sensing is not supported on this HCA. "
+ "Set only 'eth' or 'ib' for both ports "
+ "(should be the same)\n");
+ goto out;
+ }
+
+ mlx4_do_sense_ports(mdev, new_types, types);
+
+ err = mlx4_check_port_params(mdev, new_types);
if (err)
goto out;
- for (i = 1; i <= mdev->caps.num_ports; i++)
- priv->port[i].tmp_type = 0;
+ /* We are about to apply the changes after the configuration
+ * was verified, no need to remember the temporary types
+ * any more */
+ for (i = 0; i < mdev->caps.num_ports; i++)
+ priv->port[i + 1].tmp_type = 0;
- err = mlx4_change_port_types(mdev, types);
+ err = mlx4_change_port_types(mdev, new_types);
out:
+ mlx4_start_sense(mdev);
mutex_unlock(&priv->port_mutex);
return err ? err : count;
}
@@ -1117,6 +1161,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto err_port;
+ mlx4_sense_init(dev);
+ mlx4_start_sense(dev);
+
pci_set_drvdata(pdev, dev);
return 0;
@@ -1182,6 +1229,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
int p;
if (dev) {
+ mlx4_stop_sense(dev);
mlx4_unregister_device(dev);
for (p = 1; p <= dev->caps.num_ports; p++) {
@@ -1230,6 +1278,8 @@ static struct pci_device_id mlx4_pci_table[] = {
{ PCI_VDEVICE(MELLANOX, 0x673c) }, /* MT25408 "Hermon" QDR PCIe gen2 */
{ PCI_VDEVICE(MELLANOX, 0x6368) }, /* MT25408 "Hermon" EN 10GigE */
{ PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */
+ { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */
+ { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
{ 0, }
};
@@ -1264,9 +1314,11 @@ static int __init mlx4_init(void)
if (mlx4_verify_params())
return -EINVAL;
- ret = mlx4_catas_init();
- if (ret)
- return ret;
+ mlx4_catas_init();
+
+ mlx4_wq = create_singlethread_workqueue("mlx4");
+ if (!mlx4_wq)
+ return -ENOMEM;
ret = pci_register_driver(&mlx4_driver);
return ret < 0 ? ret : 0;
@@ -1275,7 +1327,7 @@ static int __init mlx4_init(void)
static void __exit mlx4_cleanup(void)
{
pci_unregister_driver(&mlx4_driver);
- mlx4_catas_cleanup();
+ destroy_workqueue(mlx4_wq);
}
module_init(mlx4_init);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index e0213bad61c..5bd79c2b184 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -40,6 +40,7 @@
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/timer.h>
+#include <linux/workqueue.h>
#include <linux/mlx4/device.h>
#include <linux/mlx4/driver.h>
@@ -276,6 +277,13 @@ struct mlx4_port_info {
struct mlx4_vlan_table vlan_table;
};
+struct mlx4_sense {
+ struct mlx4_dev *dev;
+ u8 do_sense_port[MLX4_MAX_PORTS + 1];
+ u8 sense_allowed[MLX4_MAX_PORTS + 1];
+ struct delayed_work sense_poll;
+};
+
struct mlx4_priv {
struct mlx4_dev dev;
@@ -305,6 +313,7 @@ struct mlx4_priv {
struct mlx4_uar driver_uar;
void __iomem *kar;
struct mlx4_port_info port[MLX4_MAX_PORTS + 1];
+ struct mlx4_sense sense;
struct mutex port_mutex;
};
@@ -313,6 +322,10 @@ static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
return container_of(dev, struct mlx4_priv, dev);
}
+#define MLX4_SENSE_RANGE (HZ * 3)
+
+extern struct workqueue_struct *mlx4_wq;
+
u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap);
void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj);
u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align);
@@ -346,8 +359,7 @@ void mlx4_cleanup_mcg_table(struct mlx4_dev *dev);
void mlx4_start_catas_poll(struct mlx4_dev *dev);
void mlx4_stop_catas_poll(struct mlx4_dev *dev);
-int mlx4_catas_init(void);
-void mlx4_catas_cleanup(void);
+void mlx4_catas_init(void);
int mlx4_restart_one(struct pci_dev *pdev);
int mlx4_register_device(struct mlx4_dev *dev);
void mlx4_unregister_device(struct mlx4_dev *dev);
@@ -379,6 +391,17 @@ void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type);
void mlx4_handle_catas_err(struct mlx4_dev *dev);
+void mlx4_do_sense_ports(struct mlx4_dev *dev,
+ enum mlx4_port_type *stype,
+ enum mlx4_port_type *defaults);
+void mlx4_start_sense(struct mlx4_dev *dev);
+void mlx4_stop_sense(struct mlx4_dev *dev);
+void mlx4_sense_init(struct mlx4_dev *dev);
+int mlx4_check_port_params(struct mlx4_dev *dev,
+ enum mlx4_port_type *port_type);
+int mlx4_change_port_types(struct mlx4_dev *dev,
+ enum mlx4_port_type *port_types);
+
void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c
index 0a057e5dc63..7cce3342ef8 100644
--- a/drivers/net/mlx4/port.c
+++ b/drivers/net/mlx4/port.c
@@ -298,20 +298,17 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
{
struct mlx4_cmd_mailbox *mailbox;
int err;
- u8 is_eth = dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH;
mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
return PTR_ERR(mailbox);
memset(mailbox->buf, 0, 256);
- if (is_eth) {
- ((u8 *) mailbox->buf)[3] = 6;
- ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15);
- ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15);
- } else
- ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
- err = mlx4_cmd(dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
+ if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
+ return 0;
+
+ ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
+ err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
MLX4_CMD_TIME_CLASS_B);
mlx4_free_cmd_mailbox(dev, mailbox);
diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c
index 919fb9eb1b6..cebdf3243ca 100644
--- a/drivers/net/mlx4/profile.c
+++ b/drivers/net/mlx4/profile.c
@@ -107,9 +107,9 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
profile[MLX4_RES_AUXC].num = request->num_qp;
profile[MLX4_RES_SRQ].num = request->num_srq;
profile[MLX4_RES_CQ].num = request->num_cq;
- profile[MLX4_RES_EQ].num = min(dev_cap->max_eqs,
- dev_cap->reserved_eqs +
- num_possible_cpus() + 1);
+ profile[MLX4_RES_EQ].num = min_t(unsigned, dev_cap->max_eqs,
+ dev_cap->reserved_eqs +
+ num_possible_cpus() + 1);
profile[MLX4_RES_DMPT].num = request->num_mpt;
profile[MLX4_RES_CMPT].num = MLX4_NUM_CMPTS;
profile[MLX4_RES_MTT].num = request->num_mtt;
diff --git a/drivers/net/mlx4/sense.c b/drivers/net/mlx4/sense.c
new file mode 100644
index 00000000000..6d5089ecb5a
--- /dev/null
+++ b/drivers/net/mlx4/sense.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/if_ether.h>
+
+#include <linux/mlx4/cmd.h>
+
+#include "mlx4.h"
+
+static int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
+ enum mlx4_port_type *type)
+{
+ u64 out_param;
+ int err = 0;
+
+ err = mlx4_cmd_imm(dev, 0, &out_param, port, 0,
+ MLX4_CMD_SENSE_PORT, MLX4_CMD_TIME_CLASS_B);
+ if (err) {
+ mlx4_err(dev, "Sense command failed for port: %d\n", port);
+ return err;
+ }
+
+ if (out_param > 2) {
+ mlx4_err(dev, "Sense returned illegal value: 0x%llx\n", out_param);
+ return EINVAL;
+ }
+
+ *type = out_param;
+ return 0;
+}
+
+void mlx4_do_sense_ports(struct mlx4_dev *dev,
+ enum mlx4_port_type *stype,
+ enum mlx4_port_type *defaults)
+{
+ struct mlx4_sense *sense = &mlx4_priv(dev)->sense;
+ int err;
+ int i;
+
+ for (i = 1; i <= dev->caps.num_ports; i++) {
+ stype[i - 1] = 0;
+ if (sense->do_sense_port[i] && sense->sense_allowed[i] &&
+ dev->caps.possible_type[i] == MLX4_PORT_TYPE_AUTO) {
+ err = mlx4_SENSE_PORT(dev, i, &stype[i - 1]);
+ if (err)
+ stype[i - 1] = defaults[i - 1];
+ } else
+ stype[i - 1] = defaults[i - 1];
+ }
+
+ /*
+ * Adjust port configuration:
+ * If port 1 sensed nothing and port 2 is IB, set both as IB
+ * If port 2 sensed nothing and port 1 is Eth, set both as Eth
+ */
+ if (stype[0] == MLX4_PORT_TYPE_ETH) {
+ for (i = 1; i < dev->caps.num_ports; i++)
+ stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_ETH;
+ }
+ if (stype[dev->caps.num_ports - 1] == MLX4_PORT_TYPE_IB) {
+ for (i = 0; i < dev->caps.num_ports - 1; i++)
+ stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_IB;
+ }
+
+ /*
+ * If sensed nothing, remain in current configuration.
+ */
+ for (i = 0; i < dev->caps.num_ports; i++)
+ stype[i] = stype[i] ? stype[i] : defaults[i];
+
+}
+
+static void mlx4_sense_port(struct work_struct *work)
+{
+ struct delayed_work *delay = container_of(work, struct delayed_work, work);
+ struct mlx4_sense *sense = container_of(delay, struct mlx4_sense,
+ sense_poll);
+ struct mlx4_dev *dev = sense->dev;
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ enum mlx4_port_type stype[MLX4_MAX_PORTS];
+
+ mutex_lock(&priv->port_mutex);
+ mlx4_do_sense_ports(dev, stype, &dev->caps.port_type[1]);
+
+ if (mlx4_check_port_params(dev, stype))
+ goto sense_again;
+
+ if (mlx4_change_port_types(dev, stype))
+ mlx4_err(dev, "Failed to change port_types\n");
+
+sense_again:
+ mutex_unlock(&priv->port_mutex);
+ queue_delayed_work(mlx4_wq , &sense->sense_poll,
+ round_jiffies_relative(MLX4_SENSE_RANGE));
+}
+
+void mlx4_start_sense(struct mlx4_dev *dev)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ struct mlx4_sense *sense = &priv->sense;
+
+ if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP))
+ return;
+
+ queue_delayed_work(mlx4_wq , &sense->sense_poll,
+ round_jiffies_relative(MLX4_SENSE_RANGE));
+}
+
+void mlx4_stop_sense(struct mlx4_dev *dev)
+{
+ cancel_delayed_work_sync(&mlx4_priv(dev)->sense.sense_poll);
+}
+
+void mlx4_sense_init(struct mlx4_dev *dev)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ struct mlx4_sense *sense = &priv->sense;
+ int port;
+
+ sense->dev = dev;
+ for (port = 1; port <= dev->caps.num_ports; port++)
+ sense->do_sense_port[port] = 1;
+
+ INIT_DELAYED_WORK_DEFERRABLE(&sense->sense_poll, mlx4_sense_port);
+}
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 7253a499d9c..a56d9d2df73 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -53,6 +53,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/io.h>
#include <linux/types.h>
+#include <linux/inet_lro.h>
#include <asm/system.h>
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
@@ -136,21 +137,23 @@ static char mv643xx_eth_driver_version[] = "1.4";
/*
* SDMA configuration register.
*/
+#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_16_64BIT | \
- TX_BURST_SIZE_16_64BIT)
+ (RX_BURST_SIZE_4_64BIT | \
+ TX_BURST_SIZE_4_64BIT)
#elif defined(__LITTLE_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
- (RX_BURST_SIZE_16_64BIT | \
- BLM_RX_NO_SWAP | \
- BLM_TX_NO_SWAP | \
- TX_BURST_SIZE_16_64BIT)
+ (RX_BURST_SIZE_4_64BIT | \
+ BLM_RX_NO_SWAP | \
+ BLM_TX_NO_SWAP | \
+ TX_BURST_SIZE_4_64BIT)
#else
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
#endif
@@ -225,6 +228,12 @@ struct tx_desc {
#define RX_ENABLE_INTERRUPT 0x20000000
#define RX_FIRST_DESC 0x08000000
#define RX_LAST_DESC 0x04000000
+#define RX_IP_HDR_OK 0x02000000
+#define RX_PKT_IS_IPV4 0x01000000
+#define RX_PKT_IS_ETHERNETV2 0x00800000
+#define RX_PKT_LAYER4_TYPE_MASK 0x00600000
+#define RX_PKT_LAYER4_TYPE_TCP_IPV4 0x00000000
+#define RX_PKT_IS_VLAN_TAGGED 0x00080000
/* TX descriptor command */
#define TX_ENABLE_INTERRUPT 0x00800000
@@ -284,6 +293,9 @@ struct mv643xx_eth_shared_private {
#define TX_BW_CONTROL_OLD_LAYOUT 1
#define TX_BW_CONTROL_NEW_LAYOUT 2
+static int mv643xx_eth_open(struct net_device *dev);
+static int mv643xx_eth_stop(struct net_device *dev);
+
/* per-port *****************************************************************/
struct mib_counters {
@@ -319,6 +331,12 @@ struct mib_counters {
u32 late_collision;
};
+struct lro_counters {
+ u32 lro_aggregated;
+ u32 lro_flushed;
+ u32 lro_no_desc;
+};
+
struct rx_queue {
int index;
@@ -332,6 +350,9 @@ struct rx_queue {
dma_addr_t rx_desc_dma;
int rx_desc_area_size;
struct sk_buff **rx_skb;
+
+ struct net_lro_mgr lro_mgr;
+ struct net_lro_desc lro_arr[8];
};
struct tx_queue {
@@ -367,6 +388,8 @@ struct mv643xx_eth_private {
spinlock_t mib_counters_lock;
struct mib_counters mib_counters;
+ struct lro_counters lro_counters;
+
struct work_struct tx_timeout_task;
struct napi_struct napi;
@@ -383,7 +406,7 @@ struct mv643xx_eth_private {
/*
* RX state.
*/
- int default_rx_ring_size;
+ int rx_ring_size;
unsigned long rx_desc_sram_addr;
int rx_desc_sram_size;
int rxq_count;
@@ -393,7 +416,7 @@ struct mv643xx_eth_private {
/*
* TX state.
*/
- int default_tx_ring_size;
+ int tx_ring_size;
unsigned long tx_desc_sram_addr;
int tx_desc_sram_size;
int txq_count;
@@ -491,12 +514,40 @@ static void txq_maybe_wake(struct tx_queue *txq)
/* rx napi ******************************************************************/
+static int
+mv643xx_get_skb_header(struct sk_buff *skb, void **iphdr, void **tcph,
+ u64 *hdr_flags, void *priv)
+{
+ unsigned long cmd_sts = (unsigned long)priv;
+
+ /*
+ * Make sure that this packet is Ethernet II, is not VLAN
+ * tagged, is IPv4, has a valid IP header, and is TCP.
+ */
+ if ((cmd_sts & (RX_IP_HDR_OK | RX_PKT_IS_IPV4 |
+ RX_PKT_IS_ETHERNETV2 | RX_PKT_LAYER4_TYPE_MASK |
+ RX_PKT_IS_VLAN_TAGGED)) !=
+ (RX_IP_HDR_OK | RX_PKT_IS_IPV4 |
+ RX_PKT_IS_ETHERNETV2 | RX_PKT_LAYER4_TYPE_TCP_IPV4))
+ return -1;
+
+ skb_reset_network_header(skb);
+ skb_set_transport_header(skb, ip_hdrlen(skb));
+ *iphdr = ip_hdr(skb);
+ *tcph = tcp_hdr(skb);
+ *hdr_flags = LRO_IPV4 | LRO_TCP;
+
+ return 0;
+}
+
static int rxq_process(struct rx_queue *rxq, int budget)
{
struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
struct net_device_stats *stats = &mp->dev->stats;
+ int lro_flush_needed;
int rx;
+ lro_flush_needed = 0;
rx = 0;
while (rx < budget && rxq->rx_desc_count) {
struct rx_desc *rx_desc;
@@ -556,7 +607,13 @@ static int rxq_process(struct rx_queue *rxq, int budget)
if (cmd_sts & LAYER_4_CHECKSUM_OK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->protocol = eth_type_trans(skb, mp->dev);
- netif_receive_skb(skb);
+
+ if (skb->dev->features & NETIF_F_LRO &&
+ skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ lro_receive_skb(&rxq->lro_mgr, skb, (void *)cmd_sts);
+ lro_flush_needed = 1;
+ } else
+ netif_receive_skb(skb);
continue;
@@ -577,6 +634,9 @@ err:
dev_kfree_skb(skb);
}
+ if (lro_flush_needed)
+ lro_flush_all(&rxq->lro_mgr);
+
if (rx < budget)
mp->work_rx &= ~(1 << rxq->index);
@@ -905,7 +965,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
if (skb != NULL) {
if (skb_queue_len(&mp->rx_recycle) <
- mp->default_rx_ring_size &&
+ mp->rx_ring_size &&
skb_recycle_check(skb, mp->skb_size +
dma_get_cache_alignment() - 1))
__skb_queue_head(&mp->rx_recycle, skb);
@@ -1156,6 +1216,26 @@ static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
return stats;
}
+static void mv643xx_eth_grab_lro_stats(struct mv643xx_eth_private *mp)
+{
+ u32 lro_aggregated = 0;
+ u32 lro_flushed = 0;
+ u32 lro_no_desc = 0;
+ int i;
+
+ for (i = 0; i < mp->rxq_count; i++) {
+ struct rx_queue *rxq = mp->rxq + i;
+
+ lro_aggregated += rxq->lro_mgr.stats.aggregated;
+ lro_flushed += rxq->lro_mgr.stats.flushed;
+ lro_no_desc += rxq->lro_mgr.stats.no_desc;
+ }
+
+ mp->lro_counters.lro_aggregated = lro_aggregated;
+ mp->lro_counters.lro_flushed = lro_flushed;
+ mp->lro_counters.lro_no_desc = lro_no_desc;
+}
+
static inline u32 mib_read(struct mv643xx_eth_private *mp, int offset)
{
return rdl(mp, MIB_COUNTERS(mp->port_num) + offset);
@@ -1173,7 +1253,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
{
struct mib_counters *p = &mp->mib_counters;
- spin_lock(&mp->mib_counters_lock);
+ spin_lock_bh(&mp->mib_counters_lock);
p->good_octets_received += mib_read(mp, 0x00);
p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;
p->bad_octets_received += mib_read(mp, 0x08);
@@ -1206,7 +1286,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
p->bad_crc_event += mib_read(mp, 0x74);
p->collision += mib_read(mp, 0x78);
p->late_collision += mib_read(mp, 0x7c);
- spin_unlock(&mp->mib_counters_lock);
+ spin_unlock_bh(&mp->mib_counters_lock);
mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ);
}
@@ -1219,6 +1299,85 @@ static void mib_counters_timer_wrapper(unsigned long _mp)
}
+/* interrupt coalescing *****************************************************/
+/*
+ * Hardware coalescing parameters are set in units of 64 t_clk
+ * cycles. I.e.:
+ *
+ * coal_delay_in_usec = 64000000 * register_value / t_clk_rate
+ *
+ * register_value = coal_delay_in_usec * t_clk_rate / 64000000
+ *
+ * In the ->set*() methods, we round the computed register value
+ * to the nearest integer.
+ */
+static unsigned int get_rx_coal(struct mv643xx_eth_private *mp)
+{
+ u32 val = rdlp(mp, SDMA_CONFIG);
+ u64 temp;
+
+ if (mp->shared->extended_rx_coal_limit)
+ temp = ((val & 0x02000000) >> 10) | ((val & 0x003fff80) >> 7);
+ else
+ temp = (val & 0x003fff00) >> 8;
+
+ temp *= 64000000;
+ do_div(temp, mp->shared->t_clk);
+
+ return (unsigned int)temp;
+}
+
+static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
+{
+ u64 temp;
+ u32 val;
+
+ temp = (u64)usec * mp->shared->t_clk;
+ temp += 31999999;
+ do_div(temp, 64000000);
+
+ val = rdlp(mp, SDMA_CONFIG);
+ if (mp->shared->extended_rx_coal_limit) {
+ if (temp > 0xffff)
+ temp = 0xffff;
+ val &= ~0x023fff80;
+ val |= (temp & 0x8000) << 10;
+ val |= (temp & 0x7fff) << 7;
+ } else {
+ if (temp > 0x3fff)
+ temp = 0x3fff;
+ val &= ~0x003fff00;
+ val |= (temp & 0x3fff) << 8;
+ }
+ wrlp(mp, SDMA_CONFIG, val);
+}
+
+static unsigned int get_tx_coal(struct mv643xx_eth_private *mp)
+{
+ u64 temp;
+
+ temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4;
+ temp *= 64000000;
+ do_div(temp, mp->shared->t_clk);
+
+ return (unsigned int)temp;
+}
+
+static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
+{
+ u64 temp;
+
+ temp = (u64)usec * mp->shared->t_clk;
+ temp += 31999999;
+ do_div(temp, 64000000);
+
+ if (temp > 0x3fff)
+ temp = 0x3fff;
+
+ wrlp(mp, TX_FIFO_URGENT_THRESHOLD, temp << 4);
+}
+
+
/* ethtool ******************************************************************/
struct mv643xx_eth_stats {
char stat_string[ETH_GSTRING_LEN];
@@ -1235,6 +1394,10 @@ struct mv643xx_eth_stats {
{ #m, FIELD_SIZEOF(struct mib_counters, m), \
-1, offsetof(struct mv643xx_eth_private, mib_counters.m) }
+#define LROSTAT(m) \
+ { #m, FIELD_SIZEOF(struct lro_counters, m), \
+ -1, offsetof(struct mv643xx_eth_private, lro_counters.m) }
+
static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
SSTAT(rx_packets),
SSTAT(tx_packets),
@@ -1274,12 +1437,15 @@ static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
MIBSTAT(bad_crc_event),
MIBSTAT(collision),
MIBSTAT(late_collision),
+ LROSTAT(lro_aggregated),
+ LROSTAT(lro_flushed),
+ LROSTAT(lro_no_desc),
};
static int
-mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+mv643xx_eth_get_settings_phy(struct mv643xx_eth_private *mp,
+ struct ethtool_cmd *cmd)
{
- struct mv643xx_eth_private *mp = netdev_priv(dev);
int err;
err = phy_read_status(mp->phy);
@@ -1296,10 +1462,9 @@ mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
static int
-mv643xx_eth_get_settings_phyless(struct net_device *dev,
+mv643xx_eth_get_settings_phyless(struct mv643xx_eth_private *mp,
struct ethtool_cmd *cmd)
{
- struct mv643xx_eth_private *mp = netdev_priv(dev);
u32 port_status;
port_status = rdlp(mp, PORT_STATUS);
@@ -1332,10 +1497,24 @@ mv643xx_eth_get_settings_phyless(struct net_device *dev,
}
static int
+mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ if (mp->phy != NULL)
+ return mv643xx_eth_get_settings_phy(mp, cmd);
+ else
+ return mv643xx_eth_get_settings_phyless(mp, cmd);
+}
+
+static int
mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
+ if (mp->phy == NULL)
+ return -EINVAL;
+
/*
* The MAC does not support 1000baseT_Half.
*/
@@ -1344,13 +1523,6 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return phy_ethtool_sset(mp->phy, cmd);
}
-static int
-mv643xx_eth_set_settings_phyless(struct net_device *dev,
- struct ethtool_cmd *cmd)
-{
- return -EINVAL;
-}
-
static void mv643xx_eth_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
@@ -1365,17 +1537,95 @@ static int mv643xx_eth_nway_reset(struct net_device *dev)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
+ if (mp->phy == NULL)
+ return -EINVAL;
+
return genphy_restart_aneg(mp->phy);
}
-static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)
+static u32 mv643xx_eth_get_link(struct net_device *dev)
{
- return -EINVAL;
+ return !!netif_carrier_ok(dev);
}
-static u32 mv643xx_eth_get_link(struct net_device *dev)
+static int
+mv643xx_eth_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
{
- return !!netif_carrier_ok(dev);
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ ec->rx_coalesce_usecs = get_rx_coal(mp);
+ ec->tx_coalesce_usecs = get_tx_coal(mp);
+
+ return 0;
+}
+
+static int
+mv643xx_eth_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ set_rx_coal(mp, ec->rx_coalesce_usecs);
+ set_tx_coal(mp, ec->tx_coalesce_usecs);
+
+ return 0;
+}
+
+static void
+mv643xx_eth_get_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ er->rx_max_pending = 4096;
+ er->tx_max_pending = 4096;
+ er->rx_mini_max_pending = 0;
+ er->rx_jumbo_max_pending = 0;
+
+ er->rx_pending = mp->rx_ring_size;
+ er->tx_pending = mp->tx_ring_size;
+ er->rx_mini_pending = 0;
+ er->rx_jumbo_pending = 0;
+}
+
+static int
+mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ if (er->rx_mini_pending || er->rx_jumbo_pending)
+ return -EINVAL;
+
+ mp->rx_ring_size = er->rx_pending < 4096 ? er->rx_pending : 4096;
+ mp->tx_ring_size = er->tx_pending < 4096 ? er->tx_pending : 4096;
+
+ if (netif_running(dev)) {
+ mv643xx_eth_stop(dev);
+ if (mv643xx_eth_open(dev)) {
+ dev_printk(KERN_ERR, &dev->dev,
+ "fatal error on re-opening device after "
+ "ring param change\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+static u32
+mv643xx_eth_get_rx_csum(struct net_device *dev)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ return !!(rdlp(mp, PORT_CONFIG) & 0x02000000);
+}
+
+static int
+mv643xx_eth_set_rx_csum(struct net_device *dev, u32 rx_csum)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000);
+
+ return 0;
}
static void mv643xx_eth_get_strings(struct net_device *dev,
@@ -1401,6 +1651,7 @@ static void mv643xx_eth_get_ethtool_stats(struct net_device *dev,
mv643xx_eth_get_stats(dev);
mib_counters_update(mp);
+ mv643xx_eth_grab_lro_stats(mp);
for (i = 0; i < ARRAY_SIZE(mv643xx_eth_stats); i++) {
const struct mv643xx_eth_stats *stat;
@@ -1432,21 +1683,18 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = {
.get_drvinfo = mv643xx_eth_get_drvinfo,
.nway_reset = mv643xx_eth_nway_reset,
.get_link = mv643xx_eth_get_link,
+ .get_coalesce = mv643xx_eth_get_coalesce,
+ .set_coalesce = mv643xx_eth_set_coalesce,
+ .get_ringparam = mv643xx_eth_get_ringparam,
+ .set_ringparam = mv643xx_eth_set_ringparam,
+ .get_rx_csum = mv643xx_eth_get_rx_csum,
+ .set_rx_csum = mv643xx_eth_set_rx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.get_strings = mv643xx_eth_get_strings,
.get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
- .get_sset_count = mv643xx_eth_get_sset_count,
-};
-
-static const struct ethtool_ops mv643xx_eth_ethtool_ops_phyless = {
- .get_settings = mv643xx_eth_get_settings_phyless,
- .set_settings = mv643xx_eth_set_settings_phyless,
- .get_drvinfo = mv643xx_eth_get_drvinfo,
- .nway_reset = mv643xx_eth_nway_reset_phyless,
- .get_link = mv643xx_eth_get_link,
- .set_sg = ethtool_op_set_sg,
- .get_strings = mv643xx_eth_get_strings,
- .get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
+ .get_flags = ethtool_op_get_flags,
+ .set_flags = ethtool_op_set_flags,
.get_sset_count = mv643xx_eth_get_sset_count,
};
@@ -1573,7 +1821,7 @@ oom:
return;
}
- mc_spec = kmalloc(0x200, GFP_KERNEL);
+ mc_spec = kmalloc(0x200, GFP_ATOMIC);
if (mc_spec == NULL)
goto oom;
mc_other = mc_spec + (0x100 >> 2);
@@ -1594,7 +1842,7 @@ oom:
entry = addr_crc(a);
}
- table[entry >> 2] |= 1 << (entry & 3);
+ table[entry >> 2] |= 1 << (8 * (entry & 3));
}
for (i = 0; i < 0x100; i += 4) {
@@ -1635,7 +1883,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index)
rxq->index = index;
- rxq->rx_ring_size = mp->default_rx_ring_size;
+ rxq->rx_ring_size = mp->rx_ring_size;
rxq->rx_desc_count = 0;
rxq->rx_curr_desc = 0;
@@ -1681,6 +1929,19 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index)
nexti * sizeof(struct rx_desc);
}
+ rxq->lro_mgr.dev = mp->dev;
+ memset(&rxq->lro_mgr.stats, 0, sizeof(rxq->lro_mgr.stats));
+ rxq->lro_mgr.features = LRO_F_NAPI;
+ rxq->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+ rxq->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+ rxq->lro_mgr.max_desc = ARRAY_SIZE(rxq->lro_arr);
+ rxq->lro_mgr.max_aggr = 32;
+ rxq->lro_mgr.frag_align_pad = 0;
+ rxq->lro_mgr.lro_arr = rxq->lro_arr;
+ rxq->lro_mgr.get_skb_header = mv643xx_get_skb_header;
+
+ memset(&rxq->lro_arr, 0, sizeof(rxq->lro_arr));
+
return 0;
@@ -1735,7 +1996,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
txq->index = index;
- txq->tx_ring_size = mp->default_tx_ring_size;
+ txq->tx_ring_size = mp->tx_ring_size;
txq->tx_desc_count = 0;
txq->tx_curr_desc = 0;
@@ -2028,11 +2289,6 @@ static void port_start(struct mv643xx_eth_private *mp)
}
/*
- * Add configured unicast address to address filter table.
- */
- mv643xx_eth_program_unicast_filter(mp->dev);
-
- /*
* Receive all unmatched unicast, TCP, UDP, BPDU and broadcast
* frames to RX queue #0, and include the pseudo-header when
* calculating receive checksums.
@@ -2045,6 +2301,11 @@ static void port_start(struct mv643xx_eth_private *mp)
wrlp(mp, PORT_CONFIG_EXT, 0x00000000);
/*
+ * Add configured unicast addresses to address filter table.
+ */
+ mv643xx_eth_program_unicast_filter(mp->dev);
+
+ /*
* Enable the receive queues.
*/
for (i = 0; i < mp->rxq_count; i++) {
@@ -2059,36 +2320,6 @@ static void port_start(struct mv643xx_eth_private *mp)
}
}
-static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
-{
- unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
- u32 val;
-
- val = rdlp(mp, SDMA_CONFIG);
- if (mp->shared->extended_rx_coal_limit) {
- if (coal > 0xffff)
- coal = 0xffff;
- val &= ~0x023fff80;
- val |= (coal & 0x8000) << 10;
- val |= (coal & 0x7fff) << 7;
- } else {
- if (coal > 0x3fff)
- coal = 0x3fff;
- val &= ~0x003fff00;
- val |= (coal & 0x3fff) << 8;
- }
- wrlp(mp, SDMA_CONFIG, val);
-}
-
-static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
-{
- unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
-
- if (coal > 0x3fff)
- coal = 0x3fff;
- wrlp(mp, TX_FIFO_URGENT_THRESHOLD, (coal & 0x3fff) << 4);
-}
-
static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
{
int skb_size;
@@ -2157,13 +2388,8 @@ static int mv643xx_eth_open(struct net_device *dev)
}
}
- netif_carrier_off(dev);
-
port_start(mp);
- set_rx_coal(mp, 0);
- set_tx_coal(mp, 0);
-
wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX);
wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
@@ -2210,11 +2436,10 @@ static int mv643xx_eth_stop(struct net_device *dev)
struct mv643xx_eth_private *mp = netdev_priv(dev);
int i;
+ wrlp(mp, INT_MASK_EXT, 0x00000000);
wrlp(mp, INT_MASK, 0x00000000);
rdlp(mp, INT_MASK);
- del_timer_sync(&mp->mib_counters_timer);
-
napi_disable(&mp->napi);
del_timer_sync(&mp->rx_oom);
@@ -2226,6 +2451,7 @@ static int mv643xx_eth_stop(struct net_device *dev)
port_reset(mp);
mv643xx_eth_get_stats(dev);
mib_counters_update(mp);
+ del_timer_sync(&mp->mib_counters_timer);
skb_queue_purge(&mp->rx_recycle);
@@ -2529,17 +2755,17 @@ static void set_params(struct mv643xx_eth_private *mp,
else
uc_addr_get(mp, dev->dev_addr);
- mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
+ mp->rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
if (pd->rx_queue_size)
- mp->default_rx_ring_size = pd->rx_queue_size;
+ mp->rx_ring_size = pd->rx_queue_size;
mp->rx_desc_sram_addr = pd->rx_sram_addr;
mp->rx_desc_sram_size = pd->rx_sram_size;
mp->rxq_count = pd->rx_queue_count ? : 1;
- mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
+ mp->tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
if (pd->tx_queue_size)
- mp->default_tx_ring_size = pd->tx_queue_size;
+ mp->tx_ring_size = pd->tx_queue_size;
mp->tx_desc_sram_addr = pd->tx_sram_addr;
mp->tx_desc_sram_size = pd->tx_sram_size;
@@ -2586,7 +2812,7 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
phy_reset(mp);
- phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII);
+ phy_attach(mp->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_GMII);
if (speed == 0) {
phy->autoneg = AUTONEG_ENABLE;
@@ -2630,6 +2856,21 @@ static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
wrlp(mp, PORT_SERIAL_CONTROL, pscr);
}
+static const struct net_device_ops mv643xx_eth_netdev_ops = {
+ .ndo_open = mv643xx_eth_open,
+ .ndo_stop = mv643xx_eth_stop,
+ .ndo_start_xmit = mv643xx_eth_xmit,
+ .ndo_set_rx_mode = mv643xx_eth_set_rx_mode,
+ .ndo_set_mac_address = mv643xx_eth_set_mac_address,
+ .ndo_do_ioctl = mv643xx_eth_ioctl,
+ .ndo_change_mtu = mv643xx_eth_change_mtu,
+ .ndo_tx_timeout = mv643xx_eth_tx_timeout,
+ .ndo_get_stats = mv643xx_eth_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = mv643xx_eth_netpoll,
+#endif
+};
+
static int mv643xx_eth_probe(struct platform_device *pdev)
{
struct mv643xx_eth_platform_data *pd;
@@ -2670,12 +2911,10 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
if (pd->phy_addr != MV643XX_ETH_PHY_NONE)
mp->phy = phy_scan(mp, pd->phy_addr);
- if (mp->phy != NULL) {
+ if (mp->phy != NULL)
phy_init(mp, pd->speed, pd->duplex);
- SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
- } else {
- SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);
- }
+
+ SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
init_pscr(mp, pd->speed, pd->duplex);
@@ -2703,18 +2942,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
BUG_ON(!res);
dev->irq = res->start;
- dev->get_stats = mv643xx_eth_get_stats;
- dev->hard_start_xmit = mv643xx_eth_xmit;
- dev->open = mv643xx_eth_open;
- dev->stop = mv643xx_eth_stop;
- dev->set_rx_mode = mv643xx_eth_set_rx_mode;
- dev->set_mac_address = mv643xx_eth_set_mac_address;
- dev->do_ioctl = mv643xx_eth_ioctl;
- dev->change_mtu = mv643xx_eth_change_mtu;
- dev->tx_timeout = mv643xx_eth_tx_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = mv643xx_eth_netpoll;
-#endif
+ dev->netdev_ops = &mv643xx_eth_netdev_ops;
+
dev->watchdog_timeo = 2 * HZ;
dev->base_addr = 0;
@@ -2726,6 +2955,11 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
if (mp->shared->win_protect)
wrl(mp, WINDOW_PROTECT(mp->port_num), mp->shared->win_protect);
+ netif_carrier_off(dev);
+
+ set_rx_coal(mp, 250);
+ set_tx_coal(mp, 0);
+
err = register_netdev(dev);
if (err)
goto out;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 6bb71b687f7..aea9fdaa3cd 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1,7 +1,7 @@
/*************************************************************************
* myri10ge.c: Myricom Myri-10G Ethernet driver.
*
- * Copyright (C) 2005 - 2007 Myricom, Inc.
+ * Copyright (C) 2005 - 2009 Myricom, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -75,7 +75,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.4.4-1.398"
+#define MYRI10GE_VERSION_STR "1.4.4-1.401"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -1324,6 +1324,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
skb_shinfo(skb)->nr_frags = 0;
}
skb->protocol = eth_type_trans(skb, dev);
+ skb_record_rx_queue(skb, ss - &mgp->ss[0]);
if (mgp->csum_flag) {
if ((skb->protocol == htons(ETH_P_IP)) ||
@@ -1514,7 +1515,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
work_done = myri10ge_clean_rx_done(ss, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
put_be32(htonl(3), ss->irq_claim);
}
return work_done;
@@ -1532,7 +1533,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
/* an interrupt on a non-zero receive-only slice is implicitly
* valid since MSI-X irqs are not shared */
if ((mgp->dev->real_num_tx_queues == 1) && (ss != mgp->ss)) {
- netif_rx_schedule(&ss->napi);
+ napi_schedule(&ss->napi);
return (IRQ_HANDLED);
}
@@ -1543,7 +1544,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
/* low bit indicates receives are present, so schedule
* napi poll handler */
if (stats->valid & 1)
- netif_rx_schedule(&ss->napi);
+ napi_schedule(&ss->napi);
if (!mgp->msi_enabled && !mgp->msix_enabled) {
put_be32(0, mgp->irq_deassert);
@@ -3786,7 +3787,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (status != 0) {
dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n",
status);
- goto abort_with_netdev;
+ goto abort_with_enabled;
}
pci_set_master(pdev);
@@ -3801,13 +3802,13 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
if (status != 0) {
dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
- goto abort_with_netdev;
+ goto abort_with_enabled;
}
(void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
&mgp->cmd_bus, GFP_KERNEL);
if (mgp->cmd == NULL)
- goto abort_with_netdev;
+ goto abort_with_enabled;
mgp->board_span = pci_resource_len(pdev, 0);
mgp->iomem_base = pci_resource_start(pdev, 0);
@@ -3943,8 +3944,10 @@ abort_with_mtrr:
dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
mgp->cmd, mgp->cmd_bus);
-abort_with_netdev:
+abort_with_enabled:
+ pci_disable_device(pdev);
+abort_with_netdev:
free_netdev(netdev);
return status;
}
@@ -3990,6 +3993,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
mgp->cmd, mgp->cmd_bus);
free_netdev(netdev);
+ pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}
diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
index caa6cbbb631..62a1cbab603 100644
--- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
+++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
@@ -9,6 +9,7 @@
#define MCP_TYPE_ETH 0x45544820 /* "ETH " */
#define MCP_TYPE_MCP0 0x4d435030 /* "MCP0" */
#define MCP_TYPE_DFLT 0x20202020 /* " " */
+#define MCP_TYPE_ETHZ 0x4554485a /* "ETHZ" */
struct mcp_gen_header {
/* the first 4 fields are filled at compile time */
@@ -43,7 +44,15 @@ struct mcp_gen_header {
unsigned msix_table_addr; /* start address of msix table in firmware */
unsigned bss_addr; /* start of bss */
unsigned features;
+ unsigned ee_hdr_addr;
/* 8 */
};
+struct zmcp_info {
+ unsigned info_len;
+ unsigned zmcp_addr;
+ unsigned zmcp_len;
+ unsigned mcp_edata;
+};
+
#endif /* __MYRI10GE_MCP_GEN_HEADER_H__ */
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 899ed065a14..08534c08d30 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -748,7 +748,7 @@ static int myri_rebuild_header(struct sk_buff *skb)
switch (eth->h_proto)
{
#ifdef CONFIG_INET
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
return arp_find(eth->h_dest, skb);
#endif
@@ -896,6 +896,17 @@ static const struct header_ops myri_header_ops = {
.cache_update = myri_header_cache_update,
};
+static const struct net_device_ops myri_ops = {
+ .ndo_open = myri_open,
+ .ndo_stop = myri_close,
+ .ndo_start_xmit = myri_start_xmit,
+ .ndo_set_multicast_list = myri_set_multicast,
+ .ndo_tx_timeout = myri_tx_timeout,
+ .ndo_change_mtu = myri_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match)
{
struct device_node *dp = op->node;
@@ -1048,13 +1059,9 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
sbus_writel((1 << i), mp->cregs + MYRICTRL_IRQLVL);
mp->dev = dev;
- dev->open = &myri_open;
- dev->stop = &myri_close;
- dev->hard_start_xmit = &myri_start_xmit;
- dev->tx_timeout = &myri_tx_timeout;
dev->watchdog_timeo = 5*HZ;
- dev->set_multicast_list = &myri_set_multicast;
dev->irq = op->irqs[0];
+ dev->netdev_ops = &myri_ops;
/* Register interrupt handler now. */
DET(("Requesting MYRIcom IRQ line.\n"));
@@ -1065,7 +1072,6 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
}
dev->mtu = MYRINET_MTU;
- dev->change_mtu = myri_change_mtu;
dev->header_ops = &myri_header_ops;
dev->hard_header_len = (ETH_HLEN + MYRI_PAD_LEN);
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index c5dec54251b..c9bfe4eea18 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -127,7 +127,7 @@ static int full_duplex[MAX_UNITS];
#define NATSEMI_RX_LIMIT 2046 /* maximum supported by hardware */
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
KERN_INFO DRV_NAME " dp8381x driver, version "
DRV_VERSION ", " DRV_RELDATE "\n"
KERN_INFO " originally by Donald Becker <becker@scyld.com>\n"
@@ -2198,10 +2198,10 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
- if (netif_rx_schedule_prep(&np->napi)) {
+ if (napi_schedule_prep(&np->napi)) {
/* Disable interrupts and register for poll */
natsemi_irq_disable(dev);
- __netif_rx_schedule(&np->napi);
+ __napi_schedule(&np->napi);
} else
printk(KERN_WARNING
"%s: Ignoring interrupt, status %#08x, mask %#08x.\n",
@@ -2253,7 +2253,7 @@ static int natsemi_poll(struct napi_struct *napi, int budget)
np->intr_status = readl(ioaddr + IntrStatus);
} while (np->intr_status);
- netif_rx_complete(napi);
+ napi_complete(napi);
/* Reenable interrupts providing nothing is trying to shut
* the chip down. */
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index f090d3b9ec9..eb66f658f9d 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -62,8 +62,9 @@ static int options[MAX_UNITS];
#include "8390.h"
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " D. Becker/P. Gortmaker\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+ " D. Becker/P. Gortmaker\n";
#if defined(__powerpc__)
#define inl_le(addr) le32_to_cpu(inl(addr))
diff --git a/drivers/net/netxen/Makefile b/drivers/net/netxen/Makefile
index 8e7c4c910d2..cf01a9130c9 100644
--- a/drivers/net/netxen/Makefile
+++ b/drivers/net/netxen/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 2003 - 2006 NetXen, Inc.
+# Copyright (C) 2003 - 2009 NetXen, Inc.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or
@@ -21,11 +21,10 @@
#
# Contact Information:
# info@netxen.com
-# NetXen,
-# 3965 Freedom Circle, Fourth floor,
-# Santa Clara, CA 95054
+# NetXen Inc,
+# 18922 Forge Drive
+# Cupertino, CA 95014-0701
#
-# Makefile for the NetXen NIC Driver
#
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index c11c568fd7d..c40815169f3 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
*/
#ifndef _NETXEN_NIC_H_
@@ -65,8 +66,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 11
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.11"
+#define _NETXEN_NIC_LINUX_SUBVERSION 30
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.30"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c))
@@ -77,19 +78,19 @@
#define PHAN_VENDOR_ID 0x4040
-#define RCV_DESC_RINGSIZE \
- (sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
-#define STATUS_DESC_RINGSIZE \
- (sizeof(struct status_desc)* adapter->max_rx_desc_count)
-#define LRO_DESC_RINGSIZE \
- (sizeof(rcvDesc_t) * adapter->max_lro_rx_desc_count)
-#define TX_RINGSIZE \
- (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
-#define RCV_BUFFSIZE \
- (sizeof(struct netxen_rx_buffer) * rds_ring->max_rx_desc_count)
+#define RCV_DESC_RINGSIZE(rds_ring) \
+ (sizeof(struct rcv_desc) * (rds_ring)->num_desc)
+#define RCV_BUFF_RINGSIZE(rds_ring) \
+ (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 find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
-#define NETXEN_NETDEV_STATUS 0x1
#define NETXEN_RCV_PRODUCER_OFFSET 0
#define NETXEN_RCV_PEG_DB_ID 2
#define NETXEN_HOST_DUMMY_DMA_SIZE 1024
@@ -146,7 +147,7 @@
#define MAX_RX_BUFFER_LENGTH 1760
#define MAX_RX_JUMBO_BUFFER_LENGTH 8062
-#define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512)
+#define MAX_RX_LRO_BUFFER_LENGTH (8062)
#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2)
#define RX_JUMBO_DMA_MAP_LEN \
(MAX_RX_JUMBO_BUFFER_LENGTH - 2)
@@ -188,30 +189,20 @@
/* Host writes the following to notify that it has done the init-handshake */
#define PHAN_INITIALIZE_ACK 0xf00f
-#define NUM_RCV_DESC_RINGS 3 /* No of Rcv Descriptor contexts */
-
-/* descriptor types */
-#define RCV_DESC_NORMAL 0x01
-#define RCV_DESC_JUMBO 0x02
-#define RCV_DESC_LRO 0x04
-#define RCV_DESC_NORMAL_CTXID 0
-#define RCV_DESC_JUMBO_CTXID 1
-#define RCV_DESC_LRO_CTXID 2
+#define NUM_RCV_DESC_RINGS 3
+#define NUM_STS_DESC_RINGS 4
-#define RCV_DESC_TYPE(ID) \
- ((ID == RCV_DESC_JUMBO_CTXID) \
- ? RCV_DESC_JUMBO \
- : ((ID == RCV_DESC_LRO_CTXID) \
- ? RCV_DESC_LRO : \
- (RCV_DESC_NORMAL)))
+#define RCV_RING_NORMAL 0
+#define RCV_RING_JUMBO 1
+#define RCV_RING_LRO 2
#define MAX_CMD_DESCRIPTORS 4096
#define MAX_RCV_DESCRIPTORS 16384
-#define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4)
-#define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4)
-#define MAX_RCV_DESCRIPTORS_10G 8192
+#define MAX_CMD_DESCRIPTORS_HOST 1024
+#define MAX_RCV_DESCRIPTORS_1G 2048
+#define MAX_RCV_DESCRIPTORS_10G 4096
#define MAX_JUMBO_RCV_DESCRIPTORS 1024
-#define MAX_LRO_RCV_DESCRIPTORS 64
+#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
@@ -357,10 +348,7 @@ struct cmd_desc_type0 {
__le64 addr_buffer1;
};
- __le16 buffer1_length;
- __le16 buffer2_length;
- __le16 buffer3_length;
- __le16 buffer4_length;
+ __le16 buffer_length[4];
union {
struct {
@@ -391,11 +379,8 @@ struct rcv_desc {
#define STATUS_CKSUM_OK (2)
/* owner bits of status_desc */
-#define STATUS_OWNER_HOST (0x1)
-#define STATUS_OWNER_PHANTOM (0x2)
-
-#define NETXEN_PROT_IP (1)
-#define NETXEN_PROT_UNKNOWN (0)
+#define STATUS_OWNER_HOST (0x1ULL << 56)
+#define STATUS_OWNER_PHANTOM (0x2ULL << 56)
/* Note: sizeof(status_desc) should always be a mutliple of 2 */
@@ -421,15 +406,6 @@ struct rcv_desc {
#define netxen_get_sts_opcode(sts_data) \
(((sts_data) >> 58) & 0x03F)
-#define netxen_get_sts_owner(status_desc) \
- ((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03)
-#define netxen_set_sts_owner(status_desc, val) { \
- (status_desc)->status_desc_data = \
- ((status_desc)->status_desc_data & \
- ~cpu_to_le64(0x3ULL << 56)) | \
- cpu_to_le64((u64)((val) & 0x3) << 56); \
-}
-
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
@@ -712,6 +688,15 @@ typedef enum {
NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */
} netxen_flash_map_t;
+#define NX_FW_VERSION_OFFSET (NETXEN_USER_START+0x408)
+#define NX_FW_SIZE_OFFSET (NETXEN_USER_START+0x40c)
+#define NX_BIOS_VERSION_OFFSET (NETXEN_USER_START+0x83c)
+#define NX_FW_MAGIC_OFFSET (NETXEN_BRDCFG_START+0x128)
+#define NX_FW_MIN_SIZE (0x3fffff)
+#define NX_P2_MN_ROMIMAGE 0
+#define NX_P3_CT_ROMIMAGE 1
+#define NX_P3_MN_ROMIMAGE 2
+
#define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */
#define NETXEN_FLASH_START (NETXEN_CRBINIT_START)
@@ -739,7 +724,7 @@ extern char netxen_nic_driver_name[];
#endif
/* Number of status descriptors to handle per interrupt */
-#define MAX_STATUS_HANDLE (128)
+#define MAX_STATUS_HANDLE (64)
/*
* netxen_skb_frag{} is to contain mapping info for each SG list. This
@@ -783,9 +768,6 @@ struct netxen_rx_buffer {
u64 dma;
u16 ref_handle;
u16 state;
- u32 lro_expected_frags;
- u32 lro_current_frags;
- u32 lro_length;
};
/* Board types */
@@ -800,21 +782,19 @@ struct netxen_hardware_context {
void __iomem *pci_base0;
void __iomem *pci_base1;
void __iomem *pci_base2;
- unsigned long first_page_group_end;
- unsigned long first_page_group_start;
void __iomem *db_base;
unsigned long db_len;
unsigned long pci_len0;
- u8 cut_through;
int qdr_sn_window;
int ddr_mn_window;
unsigned long mn_win_crb;
unsigned long ms_win_crb;
+ u8 cut_through;
u8 revision_id;
- u16 board_type;
- struct netxen_board_info boardcfg;
+ u16 port_type;
+ int board_type;
u32 linkup;
/* Address of cmd ring in Phantom */
struct cmd_desc_type0 *cmd_desc_head;
@@ -823,8 +803,6 @@ struct netxen_hardware_context {
int pci_func;
};
-#define RCV_RING_LRO RCV_DESC_LRO
-
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
#define ETHERNET_FCS_SIZE 4
@@ -850,16 +828,36 @@ struct netxen_adapter_stats {
* be one Rcv Descriptor for normal packets, one for jumbo and may be others.
*/
struct nx_host_rds_ring {
- u32 flags;
u32 producer;
- dma_addr_t phys_addr;
- u32 crb_rcv_producer; /* reg offset */
- struct rcv_desc *desc_head; /* address of rx ring in Phantom */
- u32 max_rx_desc_count;
+ u32 crb_rcv_producer;
+ u32 num_desc;
u32 dma_size;
u32 skb_size;
- struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */
+ u32 flags;
+ struct rcv_desc *desc_head;
+ struct netxen_rx_buffer *rx_buf_arr;
struct list_head free_list;
+ spinlock_t lock;
+ dma_addr_t phys_addr;
+};
+
+struct nx_host_sds_ring {
+ u32 consumer;
+ u32 crb_sts_consumer;
+ u32 crb_intr_mask;
+ u32 num_desc;
+
+ struct status_desc *desc_head;
+ struct netxen_adapter *adapter;
+ 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];
};
/*
@@ -874,10 +872,7 @@ struct netxen_recv_context {
u16 virt_port;
struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
- u32 status_rx_consumer;
- u32 crb_sts_consumer; /* reg offset */
- dma_addr_t rcv_status_desc_phys_addr;
- struct status_desc *rcv_status_desc_head;
+ struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS];
};
/* New HW context creation */
@@ -1203,13 +1198,13 @@ typedef struct {
#define NETXEN_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
-#define MSIX_ENTRIES_PER_ADAPTER 8
+#define MSIX_ENTRIES_PER_ADAPTER NUM_STS_DESC_RINGS
#define NETXEN_MSIX_TBL_SPACE 8192
#define NETXEN_PCI_REG_MSIX_TBL 0x44
#define NETXEN_DB_MAPSIZE_BYTES 0x1000
-#define NETXEN_NETDEV_WEIGHT 120
+#define NETXEN_NETDEV_WEIGHT 128
#define NETXEN_ADAPTER_UP_MAGIC 777
#define NETXEN_NIC_PEG_TUNE 0
@@ -1224,7 +1219,6 @@ struct netxen_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
int pci_using_dac;
- struct napi_struct napi;
struct net_device_stats net_stats;
int mtu;
int portnum;
@@ -1236,7 +1230,6 @@ struct netxen_adapter {
nx_mac_list_t *mac_list;
struct netxen_legacy_intr_set legacy_intr;
- u32 crb_intr_mask;
struct work_struct watchdog_task;
struct timer_list watchdog_timer;
@@ -1246,20 +1239,20 @@ struct netxen_adapter {
u32 crb_win;
rwlock_t adapter_lock;
- uint64_t dma_mask;
-
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 max_tx_desc_count;
- u32 max_rx_desc_count;
- u32 max_jumbo_rx_desc_count;
- u32 max_lro_rx_desc_count;
+ u32 num_txd;
+ u32 num_rxd;
+ u32 num_jumbo_rxd;
+ u32 num_lro_rxd;
int max_rds_rings;
+ int max_sds_rings;
u32 flags;
u32 irq;
@@ -1267,9 +1260,9 @@ struct netxen_adapter {
u32 temp;
u32 fw_major;
+ u32 fw_version;
- u8 msix_supported;
- u8 max_possible_rss_rings;
+ int msix_supported;
struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
struct netxen_adapter_stats stats;
@@ -1279,7 +1272,6 @@ struct netxen_adapter {
u16 state;
u16 link_autoneg;
int rx_csum;
- int status;
struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */
@@ -1287,7 +1279,7 @@ struct netxen_adapter {
* Receive instances. These can be either one per port,
* or one per peg, etc.
*/
- struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
+ struct netxen_recv_context recv_ctx;
int is_up;
struct netxen_dummy_dma dummy_dma;
@@ -1398,6 +1390,8 @@ 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_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);
@@ -1471,15 +1465,16 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
int netxen_init_firmware(struct netxen_adapter *adapter);
void netxen_nic_clear_stats(struct netxen_adapter *adapter);
void netxen_watchdog_task(struct work_struct *work);
-void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
- u32 ringid);
+void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
+ struct nx_host_rds_ring *rds_ring);
int netxen_process_cmd_ring(struct netxen_adapter *adapter);
-u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
+int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max);
void netxen_p2_nic_set_multi(struct net_device *netdev);
void netxen_p3_nic_set_multi(struct net_device *netdev);
void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
int netxen_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 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
@@ -1595,7 +1590,6 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
}
-int netxen_is_flash_supported(struct netxen_adapter *adapter);
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
extern void netxen_change_ringparam(struct netxen_adapter *adapter);
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 746bdb47041..9234473bc08 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2008 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,9 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -141,7 +141,7 @@ int
nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
{
u32 rcode = NX_RCODE_SUCCESS;
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
rcode = netxen_issue_cmd(adapter,
@@ -169,6 +169,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
nx_cardrsp_rds_ring_t *prsp_rds;
nx_cardrsp_sds_ring_t *prsp_sds;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
u64 phys_addr;
@@ -179,11 +180,10 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
int err;
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- /* only one sds ring for now */
nrds_rings = adapter->max_rds_rings;
- nsds_rings = 1;
+ nsds_rings = adapter->max_sds_rings;
rq_size =
SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
@@ -231,7 +231,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
rds_ring = &recv_ctx->rds_rings[i];
prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
- prq_rds[i].ring_size = cpu_to_le32(rds_ring->max_rx_desc_count);
+ prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
prq_rds[i].ring_kind = cpu_to_le32(i);
prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
}
@@ -239,11 +239,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
prq_sds = (nx_hostrq_sds_ring_t *)(prq->data +
le32_to_cpu(prq->sds_ring_offset));
- prq_sds[0].host_phys_addr =
- cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
- prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count);
- /* only one msix vector for now */
- prq_sds[0].msi_index = cpu_to_le16(0);
+ for (i = 0; i < nsds_rings; i++) {
+
+ sds_ring = &recv_ctx->sds_rings[i];
+
+ prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
+ prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
+ prq_sds[i].msi_index = cpu_to_le16(i);
+ }
phys_addr = hostrq_phys_addr;
err = netxen_issue_cmd(adapter,
@@ -272,11 +275,16 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
prsp_sds = ((nx_cardrsp_sds_ring_t *)
&prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
- reg = le32_to_cpu(prsp_sds[0].host_consumer_crb);
- recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
- reg = le32_to_cpu(prsp_sds[0].interrupt_crb);
- adapter->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+ for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
+ sds_ring = &recv_ctx->sds_rings[i];
+
+ reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
+ sds_ring->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
+
+ reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
+ sds_ring->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+ }
recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
recv_ctx->context_id = le16_to_cpu(prsp->context_id);
@@ -292,7 +300,7 @@ out_free_rq:
static void
nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
{
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
if (netxen_issue_cmd(adapter,
adapter->ahw.pci_func,
@@ -362,7 +370,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
prq_cds->host_phys_addr =
cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
- prq_cds->ring_size = cpu_to_le32(adapter->max_tx_desc_count);
+ prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
phys_addr = rq_phys_addr;
err = netxen_issue_cmd(adapter,
@@ -488,30 +496,28 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
- int ctx, ring;
+ struct nx_host_sds_ring *sds_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->max_tx_desc_count);
+ cpu_to_le32(adapter->num_txd);
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- recv_ctx = &adapter->recv_ctx[ctx];
+ recv_ctx = &adapter->recv_ctx;
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
+ 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 =
- cpu_to_le64(rds_ring->phys_addr);
- adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
- cpu_to_le32(rds_ring->max_rx_desc_count);
- }
- adapter->ctx_desc->sts_ring_addr =
- cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
- adapter->ctx_desc->sts_ring_size =
- cpu_to_le32(adapter->max_rx_desc_count);
+ adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+ cpu_to_le64(rds_ring->phys_addr);
+ adapter->ctx_desc->rcv_ctx[ring].rcv_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));
@@ -533,9 +539,13 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
u32 state = 0;
void *addr;
int err = 0;
- int ctx, ring;
+ int ring;
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
+
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
err = netxen_receive_peg_ready(adapter);
if (err) {
@@ -544,12 +554,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
return err;
}
- addr = pci_alloc_consistent(adapter->pdev,
+ addr = pci_alloc_consistent(pdev,
sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
&adapter->ctx_desc_phys_addr);
if (addr == NULL) {
- DPRINTK(ERR, "failed to allocate hw context\n");
+ dev_err(&pdev->dev, "failed to allocate hw context\n");
return -ENOMEM;
}
memset(addr, 0, sizeof(struct netxen_ring_ctx));
@@ -562,61 +572,57 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
(__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
/* cmd desc ring */
- addr = pci_alloc_consistent(adapter->pdev,
- sizeof(struct cmd_desc_type0) *
- adapter->max_tx_desc_count,
+ addr = pci_alloc_consistent(pdev,
+ TX_DESC_RINGSIZE(adapter),
&hw->cmd_desc_phys_addr);
if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate tx desc ring\n",
- netxen_nic_driver_name);
+ dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
+ netdev->name);
return -ENOMEM;
}
hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- recv_ctx = &adapter->recv_ctx[ctx];
-
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- /* rx desc ring */
- rds_ring = &recv_ctx->rds_rings[ring];
- addr = pci_alloc_consistent(adapter->pdev,
- RCV_DESC_RINGSIZE,
- &rds_ring->phys_addr);
- if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate rx "
- "desc ring[%d]\n",
- netxen_nic_driver_name, ring);
- err = -ENOMEM;
- goto err_out_free;
- }
- rds_ring->desc_head = (struct rcv_desc *)addr;
-
- if (adapter->fw_major < 4)
- rds_ring->crb_rcv_producer =
- recv_crb_registers[adapter->portnum].
- crb_rcv_producer[ring];
- }
+ recv_ctx = &adapter->recv_ctx;
- /* status desc ring */
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
addr = pci_alloc_consistent(adapter->pdev,
- STATUS_DESC_RINGSIZE,
- &recv_ctx->rcv_status_desc_phys_addr);
+ RCV_DESC_RINGSIZE(rds_ring),
+ &rds_ring->phys_addr);
if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate sts desc ring\n",
- netxen_nic_driver_name);
+ dev_err(&pdev->dev,
+ "%s: failed to allocate rds ring [%d]\n",
+ netdev->name, ring);
err = -ENOMEM;
goto err_out_free;
}
- recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
+ rds_ring->desc_head = (struct rcv_desc *)addr;
if (adapter->fw_major < 4)
- recv_ctx->crb_sts_consumer =
+ rds_ring->crb_rcv_producer =
recv_crb_registers[adapter->portnum].
- crb_sts_consumer;
+ crb_rcv_producer[ring];
}
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+
+ addr = pci_alloc_consistent(adapter->pdev,
+ STATUS_DESC_RINGSIZE(sds_ring),
+ &sds_ring->phys_addr);
+ if (addr == NULL) {
+ dev_err(&pdev->dev,
+ "%s: failed to allocate sds ring [%d]\n",
+ netdev->name, ring);
+ err = -ENOMEM;
+ goto err_out_free;
+ }
+ sds_ring->desc_head = (struct status_desc *)addr;
+ }
+
+
if (adapter->fw_major >= 4) {
adapter->intr_scheme = INTR_SCHEME_PERPORT;
adapter->msi_mode = MSI_MODE_MULTIFUNC;
@@ -628,12 +634,16 @@ 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);
- adapter->crb_intr_mask = sw_int_mask[adapter->portnum];
+ recv_ctx->sds_rings[0].crb_intr_mask =
+ sw_int_mask[adapter->portnum];
err = netxen_init_old_ctx(adapter);
if (err) {
@@ -654,7 +664,8 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
- int ctx, ring;
+ struct nx_host_sds_ring *sds_ring;
+ int ring;
if (adapter->fw_major >= 4) {
nx_fw_cmd_destroy_tx_ctx(adapter);
@@ -673,32 +684,34 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
if (adapter->ahw.cmd_desc_head != NULL) {
pci_free_consistent(adapter->pdev,
sizeof(struct cmd_desc_type0) *
- adapter->max_tx_desc_count,
+ adapter->num_txd,
adapter->ahw.cmd_desc_head,
adapter->ahw.cmd_desc_phys_addr);
adapter->ahw.cmd_desc_head = NULL;
}
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- recv_ctx = &adapter->recv_ctx[ctx];
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
-
- if (rds_ring->desc_head != NULL) {
- pci_free_consistent(adapter->pdev,
- RCV_DESC_RINGSIZE,
- rds_ring->desc_head,
- rds_ring->phys_addr);
- rds_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];
+
+ if (rds_ring->desc_head != NULL) {
+ pci_free_consistent(adapter->pdev,
+ RCV_DESC_RINGSIZE(rds_ring),
+ rds_ring->desc_head,
+ rds_ring->phys_addr);
+ rds_ring->desc_head = NULL;
}
+ }
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
- if (recv_ctx->rcv_status_desc_head != NULL) {
+ if (sds_ring->desc_head != NULL) {
pci_free_consistent(adapter->pdev,
- STATUS_DESC_RINGSIZE,
- recv_ctx->rcv_status_desc_head,
- recv_ctx->rcv_status_desc_phys_addr);
- recv_ctx->rcv_status_desc_head = NULL;
+ STATUS_DESC_RINGSIZE(sds_ring),
+ sds_ring->desc_head,
+ sds_ring->phys_addr);
+ sds_ring->desc_head = NULL;
}
}
}
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index c0bd40fcf70..a677ff89518 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * ethtool support for netxen nic
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -118,10 +115,9 @@ static int
netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- struct netxen_board_info *boardinfo = &adapter->ahw.boardcfg;
/* read which mode */
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
@@ -140,7 +136,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->duplex = adapter->link_duplex;
ecmd->autoneg = adapter->link_autoneg;
- } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
u32 val;
adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
@@ -172,7 +168,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->phy_address = adapter->physical_port;
ecmd->transceiver = XCVR_EXTERNAL;
- switch ((netxen_brdtype_t) boardinfo->board_type) {
+ switch ((netxen_brdtype_t)adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
case NETXEN_BRDTYPE_P2_SB31_2G:
case NETXEN_BRDTYPE_P3_REF_QG:
@@ -188,7 +184,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->supported |= SUPPORTED_TP;
ecmd->advertising |= ADVERTISED_TP;
ecmd->port = PORT_TP;
- ecmd->autoneg = (boardinfo->board_type ==
+ ecmd->autoneg = (adapter->ahw.board_type ==
NETXEN_BRDTYPE_P2_SB31_10G_CX4) ?
(AUTONEG_DISABLE) : (adapter->link_autoneg);
break;
@@ -215,7 +211,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->autoneg = AUTONEG_DISABLE;
break;
case NETXEN_BRDTYPE_P3_10G_TP:
- if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
ecmd->advertising |=
@@ -231,7 +227,7 @@ 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) boardinfo->board_type);
+ (netxen_brdtype_t)adapter->ahw.board_type);
return -EIO;
}
@@ -245,7 +241,7 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
__u32 status;
/* read which mode */
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
/* autonegotiation */
if (adapter->phy_write
&& adapter->phy_write(adapter,
@@ -433,7 +429,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
int val;
/* read which mode */
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
if (adapter->phy_read
&& adapter->phy_read(adapter,
NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
@@ -443,7 +439,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
val = netxen_get_phy_link(status);
return !val;
}
- } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
return (val == XG_LINK_UP) ? 0 : 1;
}
@@ -473,95 +469,23 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
return 0;
}
-#if 0
-static int
-netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
- u8 * bytes)
-{
- struct netxen_adapter *adapter = netdev_priv(dev);
- int offset = eeprom->offset;
- static int flash_start;
- static int ready_to_flash;
- int ret;
-
- if (flash_start == 0) {
- netxen_halt_pegs(adapter);
- ret = netxen_flash_unlock(adapter);
- if (ret < 0) {
- printk(KERN_ERR "%s: Flash unlock failed.\n",
- netxen_nic_driver_name);
- return ret;
- }
- printk(KERN_INFO "%s: flash unlocked. \n",
- netxen_nic_driver_name);
- ret = netxen_flash_erase_secondary(adapter);
- if (ret != FLASH_SUCCESS) {
- printk(KERN_ERR "%s: Flash erase failed.\n",
- netxen_nic_driver_name);
- return ret;
- }
- printk(KERN_INFO "%s: secondary flash erased successfully.\n",
- netxen_nic_driver_name);
- flash_start = 1;
- return 0;
- }
-
- if (offset == NETXEN_BOOTLD_START) {
- ret = netxen_flash_erase_primary(adapter);
- if (ret != FLASH_SUCCESS) {
- printk(KERN_ERR "%s: Flash erase failed.\n",
- netxen_nic_driver_name);
- return ret;
- }
-
- ret = netxen_rom_se(adapter, NETXEN_USER_START);
- if (ret != FLASH_SUCCESS)
- return ret;
- ret = netxen_rom_se(adapter, NETXEN_FIXED_START);
- if (ret != FLASH_SUCCESS)
- return ret;
-
- printk(KERN_INFO "%s: primary flash erased successfully\n",
- netxen_nic_driver_name);
-
- ret = netxen_backup_crbinit(adapter);
- if (ret != FLASH_SUCCESS) {
- printk(KERN_ERR "%s: CRBinit backup failed.\n",
- netxen_nic_driver_name);
- return ret;
- }
- printk(KERN_INFO "%s: CRBinit backup done.\n",
- netxen_nic_driver_name);
- ready_to_flash = 1;
- }
-
- if (!ready_to_flash) {
- printk(KERN_ERR "%s: Invalid write sequence, returning...\n",
- netxen_nic_driver_name);
- return -EINVAL;
- }
-
- return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len);
-}
-#endif /* 0 */
-
static void
netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- int i;
ring->rx_pending = 0;
ring->rx_jumbo_pending = 0;
- for (i = 0; i < MAX_RCV_CTX; ++i) {
- ring->rx_pending += adapter->recv_ctx[i].
- rds_rings[RCV_DESC_NORMAL_CTXID].max_rx_desc_count;
- ring->rx_jumbo_pending += adapter->recv_ctx[i].
- rds_rings[RCV_DESC_JUMBO_CTXID].max_rx_desc_count;
- }
- ring->tx_pending = adapter->max_tx_desc_count;
-
- ring->rx_max_pending = MAX_RCV_DESCRIPTORS;
+ ring->rx_pending += adapter->recv_ctx.
+ rds_rings[RCV_RING_NORMAL].num_desc;
+ ring->rx_jumbo_pending += adapter->recv_ctx.
+ rds_rings[RCV_RING_JUMBO].num_desc;
+ ring->tx_pending = adapter->num_txd;
+
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+ ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
+ else
+ ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST;
ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS;
ring->rx_mini_max_pending = 0;
@@ -576,7 +500,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
__u32 val;
int port = adapter->physical_port;
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
return;
/* get flow control settings */
@@ -599,7 +523,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
break;
}
- } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
return;
pause->rx_pause = 1;
@@ -610,7 +534,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
} else {
printk(KERN_ERR"%s: Unknown board type: %x\n",
- netxen_nic_driver_name, adapter->ahw.board_type);
+ netxen_nic_driver_name, adapter->ahw.port_type);
}
}
@@ -622,7 +546,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
__u32 val;
int port = adapter->physical_port;
/* read mode */
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
return -EIO;
/* set flow control */
@@ -666,7 +590,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
break;
}
netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
- } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ } 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);
@@ -685,7 +609,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
} else {
printk(KERN_ERR "%s: Unknown board type: %x\n",
netxen_nic_driver_name,
- adapter->ahw.board_type);
+ adapter->ahw.port_type);
}
return 0;
}
@@ -807,6 +731,53 @@ static int netxen_nic_set_tso(struct net_device *dev, u32 data)
return 0;
}
+static void
+netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct netxen_adapter *adapter = netdev_priv(dev);
+ u32 wol_cfg = 0;
+
+ wol->supported = 0;
+ wol->wolopts = 0;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return;
+
+ wol_cfg = netxen_nic_reg_read(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);
+ if (wol_cfg & (1UL << adapter->portnum))
+ wol->wolopts |= WAKE_MAGIC;
+}
+
+static int
+netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct netxen_adapter *adapter = netdev_priv(dev);
+ u32 wol_cfg = 0;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return -EOPNOTSUPP;
+
+ if (wol->wolopts & ~WAKE_MAGIC)
+ return -EOPNOTSUPP;
+
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ if (!(wol_cfg & (1 << adapter->portnum)))
+ return -EOPNOTSUPP;
+
+ wol_cfg = netxen_nic_reg_read(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);
+
+ return 0;
+}
+
/*
* Set the coalescing parameters. Currently only normal is supported.
* If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
@@ -903,9 +874,6 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_eeprom_len = netxen_nic_get_eeprom_len,
.get_eeprom = netxen_nic_get_eeprom,
-#if 0
- .set_eeprom = netxen_nic_set_eeprom,
-#endif
.get_ringparam = netxen_nic_get_ringparam,
.get_pauseparam = netxen_nic_get_pauseparam,
.set_pauseparam = netxen_nic_set_pauseparam,
@@ -913,6 +881,8 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
.set_sg = ethtool_op_set_sg,
.get_tso = netxen_nic_get_tso,
.set_tso = netxen_nic_set_tso,
+ .get_wol = netxen_nic_get_wol,
+ .set_wol = netxen_nic_set_wol,
.self_test = netxen_nic_diag_test,
.get_strings = netxen_nic_get_strings,
.get_ethtool_stats = netxen_nic_get_ethtool_stats,
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index e80f9e3e597..016c62129c7 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
*/
#ifndef __NETXEN_NIC_HDR_H_
@@ -362,12 +363,6 @@ enum {
#define NETXEN_HW_CRB_HUB_AGT_ADR_LPC \
((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_LPC_CRB_AGT_ADR)
-/*
- * MAX_RCV_CTX : The number of receive contexts that are available on
- * the phantom.
- */
-#define MAX_RCV_CTX 1
-
#define NETXEN_SRE_INT_STATUS (NETXEN_CRB_SRE + 0x00034)
#define NETXEN_SRE_PBI_ACTIVE_STATUS (NETXEN_CRB_SRE + 0x01014)
#define NETXEN_SRE_L1RE_CTL (NETXEN_CRB_SRE + 0x03000)
@@ -858,6 +853,12 @@ enum {
#define NETXEN_PORT_MODE_ADDR (NETXEN_CAM_RAM(0x24))
#define NETXEN_WOL_PORT_MODE (NETXEN_CAM_RAM(0x198))
+#define NETXEN_WOL_CONFIG_NV (NETXEN_CAM_RAM(0x184))
+#define NETXEN_WOL_CONFIG (NETXEN_CAM_RAM(0x188))
+
+#define NX_PEG_TUNE_MN_PRESENT 0x1
+#define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c))
+
#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14)
#define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 821cff68b3f..5026811c04c 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Source file for NIC routines to access the Phantom hardware
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -35,7 +32,7 @@
#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)
@@ -518,7 +515,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
producer = get_next_index(producer,
- adapter->max_tx_desc_count);
+ adapter->num_txd);
i++;
} while (i != nr_elements);
@@ -673,6 +670,53 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
return rv;
}
+#define RSS_HASHTYPE_IP_TCP 0x3
+
+int netxen_config_rss(struct netxen_adapter *adapter, int enable)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int i, rv;
+
+ u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
+ 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+ 0x255b0ec26d5a56daULL };
+
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
+ req.req_hdr = cpu_to_le64(word);
+
+ /*
+ * RSS request:
+ * bits 3-0: hash_method
+ * 5-4: hash_type_ipv4
+ * 7-6: hash_type_ipv6
+ * 8: enable
+ * 9: use indirection table
+ * 47-10: reserved
+ * 63-48: indirection table mask
+ */
+ word = ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
+ ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
+ ((u64)(enable & 0x1) << 8) |
+ ((0x7ULL) << 48);
+ req.words[0] = cpu_to_le64(word);
+ for (i = 0; i < 5; i++)
+ req.words[i+1] = cpu_to_le64(key[i]);
+
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "%s: could not configure RSS\n",
+ adapter->netdev->name);
+ }
+
+ return rv;
+}
+
/*
* netxen_nic_change_mtu - Change the Maximum Transfer Unit
* @returns 0 on success, negative on failure
@@ -706,34 +750,11 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
return rc;
}
-int netxen_is_flash_supported(struct netxen_adapter *adapter)
-{
- const int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 };
- int addr, val01, val02, i, j;
-
- /* if the flash size less than 4Mb, make huge war cry and die */
- for (j = 1; j < 4; j++) {
- addr = j * NETXEN_NIC_WINDOW_MARGIN;
- for (i = 0; i < ARRAY_SIZE(locs); i++) {
- if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0
- && netxen_rom_fast_read(adapter, (addr + locs[i]),
- &val02) == 0) {
- if (val01 == val02)
- return -1;
- } else
- return -1;
- }
- }
-
- return 0;
-}
-
static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
int size, __le32 * buf)
{
- int i, addr;
+ int i, v, addr;
__le32 *ptr32;
- u32 v;
addr = base;
ptr32 = buf;
@@ -936,13 +957,12 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
u32 win_read;
adapter->crb_win = CRB_HI(*off);
- writel(adapter->crb_win, (void *)(CRB_WINDOW_2M +
- adapter->ahw.pci_base0));
+ writel(adapter->crb_win, (adapter->ahw.pci_base0 + CRB_WINDOW_2M));
/*
* Read back value to make sure write has gone through before trying
* to use it.
*/
- win_read = readl((void *)(CRB_WINDOW_2M + adapter->ahw.pci_base0));
+ win_read = readl(adapter->ahw.pci_base0 + CRB_WINDOW_2M);
if (win_read != adapter->crb_win) {
printk(KERN_ERR "%s: Written crbwin (0x%x) != "
"Read crbwin (0x%x), off=0x%lx\n",
@@ -952,24 +972,69 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
(ulong)adapter->ahw.pci_base0;
}
-int netxen_load_firmware(struct netxen_adapter *adapter)
+static int
+netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
+ const struct firmware *fw)
{
- int i;
- u32 data, size = 0;
- u32 flashaddr = NETXEN_BOOTLD_START;
+ u64 *ptr64;
+ u32 i, flashaddr, size;
+ struct pci_dev *pdev = adapter->pdev;
- size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4;
+ 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);
- for (i = 0; i < size; i++) {
- if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0)
- return -EIO;
+ 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;
- adapter->pci_mem_write(adapter, flashaddr, &data, 4);
- flashaddr += 4;
+ flashaddr += 4;
+ }
}
msleep(1);
@@ -986,12 +1051,135 @@ int netxen_load_firmware(struct netxen_adapter *adapter)
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)
{
void __iomem *addr;
+ BUG_ON(len != 4);
+
if (ADDR_IN_WINDOW1(off)) {
addr = NETXEN_CRB_NORMALIZE(adapter, off);
} else { /* Window 0 */
@@ -999,37 +1187,13 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
netxen_nic_pci_change_crbwindow_128M(adapter, 0);
}
- DPRINTK(INFO, "writing to base %lx offset %llx addr %p"
- " data %llx len %d\n",
- pci_base(adapter, off), off, addr,
- *(unsigned long long *)data, len);
if (!addr) {
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
return 1;
}
- switch (len) {
- case 1:
- writeb(*(u8 *) data, addr);
- break;
- case 2:
- writew(*(u16 *) data, addr);
- break;
- case 4:
- writel(*(u32 *) data, addr);
- break;
- case 8:
- writeq(*(u64 *) data, addr);
- break;
- default:
- DPRINTK(INFO,
- "writing data %lx to offset %llx, num words=%d\n",
- *(unsigned long *)data, off, (len >> 3));
+ writel(*(u32 *) data, addr);
- netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
- (len >> 3));
- break;
- }
if (!ADDR_IN_WINDOW1(off))
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1042,6 +1206,8 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
{
void __iomem *addr;
+ BUG_ON(len != 4);
+
if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
addr = NETXEN_CRB_NORMALIZE(adapter, off);
} else { /* Window 0 */
@@ -1049,31 +1215,12 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
netxen_nic_pci_change_crbwindow_128M(adapter, 0);
}
- DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
- pci_base(adapter, off), off, addr);
if (!addr) {
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
return 1;
}
- switch (len) {
- case 1:
- *(u8 *) data = readb(addr);
- break;
- case 2:
- *(u16 *) data = readw(addr);
- break;
- case 4:
- *(u32 *) data = readl(addr);
- break;
- case 8:
- *(u64 *) data = readq(addr);
- break;
- default:
- netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
- (len >> 3));
- break;
- }
- DPRINTK(INFO, "read %lx\n", *(unsigned long *)data);
+
+ *(u32 *)data = readl(addr);
if (!ADDR_IN_WINDOW1(off))
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1088,6 +1235,8 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
unsigned long flags = 0;
int rv;
+ BUG_ON(len != 4);
+
rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
if (rv == -1) {
@@ -1101,34 +1250,12 @@ 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);
- }
-
- DPRINTK(1, INFO, "write data %lx to offset %llx, len=%d\n",
- *(unsigned long *)data, off, len);
-
- switch (len) {
- case 1:
- writeb(*(uint8_t *)data, (void *)off);
- break;
- case 2:
- writew(*(uint16_t *)data, (void *)off);
- break;
- case 4:
- writel(*(uint32_t *)data, (void *)off);
- break;
- case 8:
- writeq(*(uint64_t *)data, (void *)off);
- break;
- default:
- DPRINTK(1, INFO,
- "writing data %lx to offset %llx, num words=%d\n",
- *(unsigned long *)data, off, (len>>3));
- break;
- }
- if (rv == 1) {
+ writel(*(uint32_t *)data, (void __iomem *)off);
crb_win_unlock(adapter);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
- }
+ } else
+ writel(*(uint32_t *)data, (void __iomem *)off);
+
return 0;
}
@@ -1140,6 +1267,8 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
unsigned long flags = 0;
int rv;
+ BUG_ON(len != 4);
+
rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
if (rv == -1) {
@@ -1153,33 +1282,11 @@ 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);
- }
-
- DPRINTK(1, INFO, "read from offset %lx, len=%d\n", off, len);
-
- switch (len) {
- case 1:
- *(uint8_t *)data = readb((void *)off);
- break;
- case 2:
- *(uint16_t *)data = readw((void *)off);
- break;
- case 4:
- *(uint32_t *)data = readl((void *)off);
- break;
- case 8:
- *(uint64_t *)data = readq((void *)off);
- break;
- default:
- break;
- }
-
- DPRINTK(1, INFO, "read %lx\n", *(unsigned long *)data);
-
- if (rv == 1) {
+ *(uint32_t *)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;
}
@@ -1441,10 +1548,9 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
unsigned long flags;
- void *addr;
+ void __iomem *addr, *mem_ptr = NULL;
int ret = 0;
u64 start;
- uint8_t *mem_ptr = NULL;
unsigned long mem_base;
unsigned long mem_page;
@@ -1464,7 +1570,7 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
return -1;
}
- addr = (void *)(pci_base_offset(adapter, start));
+ addr = pci_base_offset(adapter, start);
if (!addr) {
write_unlock_irqrestore(&adapter->adapter_lock, flags);
mem_base = pci_resource_start(adapter->pdev, 0);
@@ -1503,7 +1609,6 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
break;
}
write_unlock_irqrestore(&adapter->adapter_lock, flags);
- DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
if (mem_ptr)
iounmap(mem_ptr);
@@ -1515,10 +1620,9 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
void *data, int size)
{
unsigned long flags;
- void *addr;
+ void __iomem *addr, *mem_ptr = NULL;
int ret = 0;
u64 start;
- uint8_t *mem_ptr = NULL;
unsigned long mem_base;
unsigned long mem_page;
@@ -1538,7 +1642,7 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
return -1;
}
- addr = (void *)(pci_base_offset(adapter, start));
+ addr = pci_base_offset(adapter, start);
if (!addr) {
write_unlock_irqrestore(&adapter->adapter_lock, flags);
mem_base = pci_resource_start(adapter->pdev, 0);
@@ -1575,8 +1679,6 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
break;
}
write_unlock_irqrestore(&adapter->adapter_lock, flags);
- DPRINTK(1, INFO, "writing data %llx to offset %llx\n",
- *(unsigned long long *)data, start);
if (mem_ptr)
iounmap(mem_ptr);
return ret;
@@ -1588,10 +1690,11 @@ int
netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
- unsigned long flags, mem_crb;
+ unsigned long flags;
int i, j, ret = 0, loop, sz[2], off0;
uint32_t temp;
uint64_t off8, tmpw, word[2] = {0, 0};
+ void __iomem *mem_crb;
/*
* If not MN, go check for MS or invalid.
@@ -1605,7 +1708,7 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
sz[0] = (size < (8 - off0)) ? size : (8 - off0);
sz[1] = size - sz[0];
loop = ((off0 + size - 1) >> 3) + 1;
- mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+ mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
if ((size != 8) || (off0 != 0)) {
for (i = 0; i < loop; i++) {
@@ -1643,28 +1746,29 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
for (i = 0; i < loop; i++) {
writel((uint32_t)(off8 + (i << 3)),
- (void *)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+ (mem_crb+MIU_TEST_AGT_ADDR_LO));
writel(0,
- (void *)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+ (mem_crb+MIU_TEST_AGT_ADDR_HI));
writel(word[i] & 0xffffffff,
- (void *)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
+ (mem_crb+MIU_TEST_AGT_WRDATA_LO));
writel((word[i] >> 32) & 0xffffffff,
- (void *)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
+ (mem_crb+MIU_TEST_AGT_WRDATA_HI));
writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
for (j = 0; j < MAX_CTL_CHECK; j++) {
temp = readl(
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
if (j >= MAX_CTL_CHECK) {
- printk("%s: %s Fail to write through agent\n",
- __func__, netxen_nic_driver_name);
+ if (printk_ratelimit())
+ dev_err(&adapter->pdev->dev,
+ "failed to write through agent\n");
ret = -1;
break;
}
@@ -1679,10 +1783,11 @@ int
netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
- unsigned long flags, mem_crb;
+ unsigned long flags;
int i, j = 0, k, start, end, loop, sz[2], off0[2];
uint32_t temp;
uint64_t off8, val, word[2] = {0, 0};
+ void __iomem *mem_crb;
/*
@@ -1697,31 +1802,32 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
sz[1] = size - sz[0];
loop = ((off0[0] + size - 1) >> 3) + 1;
- mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+ mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
write_lock_irqsave(&adapter->adapter_lock, flags);
netxen_nic_pci_change_crbwindow_128M(adapter, 0);
for (i = 0; i < loop; i++) {
writel((uint32_t)(off8 + (i << 3)),
- (void *)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+ (mem_crb+MIU_TEST_AGT_ADDR_LO));
writel(0,
- (void *)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+ (mem_crb+MIU_TEST_AGT_ADDR_HI));
writel(MIU_TA_CTL_ENABLE,
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
for (j = 0; j < MAX_CTL_CHECK; j++) {
temp = readl(
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
if (j >= MAX_CTL_CHECK) {
- printk(KERN_ERR "%s: %s Fail to read through agent\n",
- __func__, netxen_nic_driver_name);
+ if (printk_ratelimit())
+ dev_err(&adapter->pdev->dev,
+ "failed to read through agent\n");
break;
}
@@ -1729,7 +1835,7 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
end = (off0[i] + sz[i] - 1) >> 2;
for (k = start; k <= end; k++) {
word[i] |= ((uint64_t) readl(
- (void *)(mem_crb +
+ (mem_crb +
MIU_TEST_AGT_RDDATA(k))) << (32*k));
}
}
@@ -1761,7 +1867,6 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
*(uint64_t *)data = val;
break;
}
- DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
return 0;
}
@@ -1857,8 +1962,9 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
}
if (j >= MAX_CTL_CHECK) {
- printk(KERN_ERR "%s: Fail to write through agent\n",
- netxen_nic_driver_name);
+ if (printk_ratelimit())
+ dev_err(&adapter->pdev->dev,
+ "failed to write through agent\n");
ret = -1;
break;
}
@@ -1927,8 +2033,9 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
}
if (j >= MAX_CTL_CHECK) {
- printk(KERN_ERR "%s: Fail to read through agent\n",
- netxen_nic_driver_name);
+ if (printk_ratelimit())
+ dev_err(&adapter->pdev->dev,
+ "failed to read through agent\n");
break;
}
@@ -1970,7 +2077,6 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
*(uint64_t *)data = val;
break;
}
- DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
return 0;
}
@@ -2005,62 +2111,46 @@ u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off)
return temp;
}
-#if 0
-int
-netxen_nic_erase_pxe(struct netxen_adapter *adapter)
-{
- if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) {
- printk(KERN_ERR "%s: erase pxe failed\n",
- netxen_nic_driver_name);
- return -1;
- }
- return 0;
-}
-#endif /* 0 */
-
int netxen_nic_get_board_info(struct netxen_adapter *adapter)
{
- int rv = 0;
- int addr = NETXEN_BRDCFG_START;
- struct netxen_board_info *boardinfo;
- int index;
- u32 *ptr32;
-
- boardinfo = &adapter->ahw.boardcfg;
- ptr32 = (u32 *) boardinfo;
-
- for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32);
- index++) {
- if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
- return -EIO;
- }
- ptr32++;
- addr += sizeof(u32);
- }
- if (boardinfo->magic != NETXEN_BDINFO_MAGIC) {
- printk("%s: ERROR reading %s board config."
- " Read %x, expected %x\n", netxen_nic_driver_name,
- netxen_nic_driver_name,
- boardinfo->magic, NETXEN_BDINFO_MAGIC);
- rv = -1;
- }
- if (boardinfo->header_version != NETXEN_BDINFO_VERSION) {
- printk("%s: Unknown board config version."
- " Read %x, expected %x\n", netxen_nic_driver_name,
- boardinfo->header_version, NETXEN_BDINFO_VERSION);
- rv = -1;
+ int offset, board_type, magic, header_version;
+ struct pci_dev *pdev = adapter->pdev;
+
+ offset = NETXEN_BRDCFG_START +
+ offsetof(struct netxen_board_info, magic);
+ if (netxen_rom_fast_read(adapter, offset, &magic))
+ return -EIO;
+
+ offset = NETXEN_BRDCFG_START +
+ offsetof(struct netxen_board_info, header_version);
+ if (netxen_rom_fast_read(adapter, offset, &header_version))
+ return -EIO;
+
+ if (magic != NETXEN_BDINFO_MAGIC ||
+ header_version != NETXEN_BDINFO_VERSION) {
+ dev_err(&pdev->dev,
+ "invalid board config, magic=%08x, version=%08x\n",
+ magic, header_version);
+ return -EIO;
}
- if (boardinfo->board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
+ offset = NETXEN_BRDCFG_START +
+ offsetof(struct netxen_board_info, board_type);
+ if (netxen_rom_fast_read(adapter, offset, &board_type))
+ return -EIO;
+
+ adapter->ahw.board_type = board_type;
+
+ if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
u32 gpio = netxen_nic_reg_read(adapter,
NETXEN_ROMUSB_GLB_PAD_GPIO_I);
if ((gpio & 0x8000) == 0)
- boardinfo->board_type = NETXEN_BRDTYPE_P3_10G_TP;
+ board_type = NETXEN_BRDTYPE_P3_10G_TP;
}
- switch ((netxen_brdtype_t) boardinfo->board_type) {
+ switch ((netxen_brdtype_t)board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
- adapter->ahw.board_type = NETXEN_NIC_GBE;
+ adapter->ahw.port_type = NETXEN_NIC_GBE;
break;
case NETXEN_BRDTYPE_P2_SB31_10G:
case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -2076,7 +2166,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
case NETXEN_BRDTYPE_P3_10G_SFP_QT:
case NETXEN_BRDTYPE_P3_10G_XFP:
case NETXEN_BRDTYPE_P3_10000_BASE_T:
- adapter->ahw.board_type = NETXEN_NIC_XGBE;
+ adapter->ahw.port_type = NETXEN_NIC_XGBE;
break;
case NETXEN_BRDTYPE_P1_BD:
case NETXEN_BRDTYPE_P1_SB:
@@ -2085,20 +2175,19 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
case NETXEN_BRDTYPE_P3_REF_QG:
case NETXEN_BRDTYPE_P3_4_GB:
case NETXEN_BRDTYPE_P3_4_GB_MM:
- adapter->ahw.board_type = NETXEN_NIC_GBE;
+ adapter->ahw.port_type = NETXEN_NIC_GBE;
break;
case NETXEN_BRDTYPE_P3_10G_TP:
- adapter->ahw.board_type = (adapter->portnum < 2) ?
+ adapter->ahw.port_type = (adapter->portnum < 2) ?
NETXEN_NIC_XGBE : NETXEN_NIC_GBE;
break;
default:
- printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
- boardinfo->board_type);
- rv = -ENODEV;
+ dev_err(&pdev->dev, "unknown board type %x\n", board_type);
+ adapter->ahw.port_type = NETXEN_NIC_XGBE;
break;
}
- return rv;
+ return 0;
}
/* NIU access sections */
@@ -2144,7 +2233,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
return;
}
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
adapter->hw_read_wx(adapter,
NETXEN_PORT_MODE_ADDR, &port_mode, 4);
if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
@@ -2199,32 +2288,27 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
}
}
-void netxen_nic_flash_print(struct netxen_adapter *adapter)
+void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
{
- u32 fw_major = 0;
- u32 fw_minor = 0;
- u32 fw_build = 0;
+ u32 fw_major, fw_minor, fw_build;
char brd_name[NETXEN_MAX_SHORT_NAME];
char serial_num[32];
- int i, addr;
- __le32 *ptr32;
-
- struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
+ int i, addr, val;
+ int *ptr32;
+ struct pci_dev *pdev = adapter->pdev;
adapter->driver_mismatch = 0;
- ptr32 = (u32 *)&serial_num;
+ ptr32 = (int *)&serial_num;
addr = NETXEN_USER_START +
offsetof(struct netxen_new_user_info, serial_num);
for (i = 0; i < 8; i++) {
- if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
- printk("%s: ERROR reading %s board userarea.\n",
- netxen_nic_driver_name,
- netxen_nic_driver_name);
+ if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
+ dev_err(&pdev->dev, "error reading board info\n");
adapter->driver_mismatch = 1;
return;
}
- ptr32++;
+ ptr32[i] = cpu_to_le32(val);
addr += sizeof(u32);
}
@@ -2233,23 +2317,48 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
adapter->fw_major = fw_major;
+ adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
if (adapter->portnum == 0) {
- get_brd_name_by_type(board_info->board_type, brd_name);
+ get_brd_name_by_type(adapter->ahw.board_type, brd_name);
printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n",
brd_name, serial_num, adapter->ahw.revision_id);
- printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
- fw_major, fw_minor, fw_build);
}
- if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
- NETXEN_VERSION_CODE(3, 4, 216)) {
+ if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
adapter->driver_mismatch = 1;
- printk(KERN_ERR "%s: firmware version %d.%d.%d unsupported\n",
- netxen_nic_driver_name,
+ dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
fw_major, fw_minor, fw_build);
return;
}
+
+ dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
+ 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);
+ 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");
+ }
}
+int
+netxen_nic_wol_supported(struct netxen_adapter *adapter)
+{
+ u32 wol_cfg;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return 0;
+
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ if (wol_cfg & (1UL << adapter->portnum)) {
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ if (wol_cfg & (1 << adapter->portnum))
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index aae737dc77a..04b47a7993c 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Structures, enums, and macros for the MAC
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -54,37 +51,12 @@ static inline void writeq(u64 val, void __iomem * addr)
}
#endif
-static inline void netxen_nic_hw_block_write64(u64 __iomem * data_ptr,
- u64 __iomem * addr,
- int num_words)
-{
- int num;
- for (num = 0; num < num_words; num++) {
- writeq(readq((void __iomem *)data_ptr), addr);
- addr++;
- data_ptr++;
- }
-}
-
-static inline void netxen_nic_hw_block_read64(u64 __iomem * data_ptr,
- u64 __iomem * addr, int num_words)
-{
- int num;
- for (num = 0; num < num_words; num++) {
- writeq(readq((void __iomem *)addr), data_ptr);
- addr++;
- data_ptr++;
- }
-
-}
-
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);
-void netxen_nic_flash_print(struct netxen_adapter *adapter);
typedef u8 netxen_ethernet_macaddr_t[6];
@@ -148,33 +120,6 @@ typedef enum {
#define netxen_gb_get_soft_reset(config_word) \
_netxen_crb_get_bit((config_word), 31)
-/*
- * NIU GB MAC Config Register 1 (applies to GB0, GB1, GB2, GB3)
- *
- * Bit 0 : duplex => 1:full duplex mode, 0:half duplex
- * Bit 1 : crc_enable => 1:append CRC to xmit frames, 0:dont append
- * Bit 2 : padshort => 1:pad short frames and add CRC, 0:dont pad
- * Bit 4 : checklength => 1:check framelen with actual,0:dont check
- * Bit 5 : hugeframes => 1:allow oversize xmit frames, 0:dont allow
- * Bits 8-9 : intfmode => 01:nibble (10/100), 10:byte (1000)
- * Bits 12-15 : preamblelen => preamble field length in bytes, default 7
- */
-
-#define netxen_gb_set_duplex(config_word) \
- ((config_word) |= 1 << 0)
-#define netxen_gb_set_crc_enable(config_word) \
- ((config_word) |= 1 << 1)
-#define netxen_gb_set_padshort(config_word) \
- ((config_word) |= 1 << 2)
-#define netxen_gb_set_checklength(config_word) \
- ((config_word) |= 1 << 4)
-#define netxen_gb_set_hugeframes(config_word) \
- ((config_word) |= 1 << 5)
-#define netxen_gb_set_preamblelen(config_word, val) \
- ((config_word) |= ((val) << 12) & 0xF000)
-#define netxen_gb_set_intfmode(config_word, val) \
- ((config_word) |= ((val) << 8) & 0x300)
-
#define netxen_gb_get_stationaddress_low(config_word) ((config_word) >> 16)
#define netxen_gb_set_mii_mgmt_clockselect(config_word, val) \
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index ca7c8d8050c..0759c35f16a 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Source file for NIC routines to initialize the Phantom Hardware
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -52,17 +49,9 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
#define NETXEN_NIC_XDMA_RESET 0x8000ff
-static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
- uint32_t ctx, uint32_t ringid);
-
-#if 0
-static void netxen_nic_locked_write_reg(struct netxen_adapter *adapter,
- unsigned long off, int *data)
-{
- void __iomem *addr = pci_base_offset(adapter, off);
- writel(*data, addr);
-}
-#endif /* 0 */
+static void
+netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring);
static void crb_addr_transform_setup(void)
{
@@ -160,23 +149,21 @@ void netxen_release_rx_buffers(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct netxen_rx_buffer *rx_buf;
- int i, ctxid, ring;
-
- for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
- recv_ctx = &adapter->recv_ctx[ctxid];
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
- for (i = 0; i < rds_ring->max_rx_desc_count; ++i) {
- rx_buf = &(rds_ring->rx_buf_arr[i]);
- if (rx_buf->state == NETXEN_BUFFER_FREE)
- continue;
- pci_unmap_single(adapter->pdev,
- rx_buf->dma,
- rds_ring->dma_size,
- PCI_DMA_FROMDEVICE);
- if (rx_buf->skb != NULL)
- dev_kfree_skb_any(rx_buf->skb);
- }
+ int i, ring;
+
+ recv_ctx = &adapter->recv_ctx;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ for (i = 0; i < rds_ring->num_desc; ++i) {
+ rx_buf = &(rds_ring->rx_buf_arr[i]);
+ if (rx_buf->state == NETXEN_BUFFER_FREE)
+ continue;
+ pci_unmap_single(adapter->pdev,
+ rx_buf->dma,
+ rds_ring->dma_size,
+ PCI_DMA_FROMDEVICE);
+ if (rx_buf->skb != NULL)
+ dev_kfree_skb_any(rx_buf->skb);
}
}
}
@@ -188,7 +175,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
int i, j;
cmd_buf = adapter->cmd_buf_arr;
- for (i = 0; i < adapter->max_tx_desc_count; i++) {
+ for (i = 0; i < adapter->num_txd; i++) {
buffrag = cmd_buf->frag_array;
if (buffrag->dma) {
pci_unmap_single(adapter->pdev, buffrag->dma,
@@ -204,7 +191,6 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
buffrag->dma = 0ULL;
}
}
- /* Free the skb we received in netxen_nic_xmit_frame */
if (cmd_buf->skb) {
dev_kfree_skb_any(cmd_buf->skb);
cmd_buf->skb = NULL;
@@ -217,18 +203,17 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
- int ctx, ring;
-
- for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
- recv_ctx = &adapter->recv_ctx[ctx];
- 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;
- }
+ int ring;
+
+ recv_ctx = &adapter->recv_ctx;
+ 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;
}
}
+
if (adapter->cmd_buf_arr)
vfree(adapter->cmd_buf_arr);
return;
@@ -238,90 +223,97 @@ 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 netxen_rx_buffer *rx_buf;
- int ctx, ring, i, num_rx_bufs;
+ int ring, i, num_rx_bufs;
struct netxen_cmd_buffer *cmd_buf_arr;
struct net_device *netdev = adapter->netdev;
- cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
+ cmd_buf_arr =
+ (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter));
if (cmd_buf_arr == NULL) {
printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
netdev->name);
return -ENOMEM;
}
- memset(cmd_buf_arr, 0, TX_RINGSIZE);
+ memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter));
adapter->cmd_buf_arr = cmd_buf_arr;
- for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
- recv_ctx = &adapter->recv_ctx[ctx];
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
- switch (RCV_DESC_TYPE(ring)) {
- case RCV_DESC_NORMAL:
- rds_ring->max_rx_desc_count =
- adapter->max_rx_desc_count;
- rds_ring->flags = RCV_DESC_NORMAL;
- if (adapter->ahw.cut_through) {
- rds_ring->dma_size =
- NX_CT_DEFAULT_RX_BUF_LEN;
- rds_ring->skb_size =
- NX_CT_DEFAULT_RX_BUF_LEN;
- } else {
- rds_ring->dma_size = RX_DMA_MAP_LEN;
- rds_ring->skb_size =
- MAX_RX_BUFFER_LENGTH;
- }
- break;
-
- case RCV_DESC_JUMBO:
- rds_ring->max_rx_desc_count =
- adapter->max_jumbo_rx_desc_count;
- rds_ring->flags = RCV_DESC_JUMBO;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- rds_ring->dma_size =
- NX_P3_RX_JUMBO_BUF_MAX_LEN;
- else
- rds_ring->dma_size =
- NX_P2_RX_JUMBO_BUF_MAX_LEN;
+ recv_ctx = &adapter->recv_ctx;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ switch (ring) {
+ case RCV_RING_NORMAL:
+ rds_ring->num_desc = adapter->num_rxd;
+ if (adapter->ahw.cut_through) {
+ rds_ring->dma_size =
+ NX_CT_DEFAULT_RX_BUF_LEN;
rds_ring->skb_size =
- rds_ring->dma_size + NET_IP_ALIGN;
- break;
+ NX_CT_DEFAULT_RX_BUF_LEN;
+ } else {
+ rds_ring->dma_size = RX_DMA_MAP_LEN;
+ rds_ring->skb_size =
+ MAX_RX_BUFFER_LENGTH;
+ }
+ break;
- case RCV_RING_LRO:
- rds_ring->max_rx_desc_count =
- adapter->max_lro_rx_desc_count;
- rds_ring->flags = RCV_DESC_LRO;
- rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
- rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
- break;
+ case RCV_RING_JUMBO:
+ rds_ring->num_desc = adapter->num_jumbo_rxd;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ rds_ring->dma_size =
+ NX_P3_RX_JUMBO_BUF_MAX_LEN;
+ else
+ rds_ring->dma_size =
+ NX_P2_RX_JUMBO_BUF_MAX_LEN;
+ rds_ring->skb_size =
+ rds_ring->dma_size + NET_IP_ALIGN;
+ break;
- }
- rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
- vmalloc(RCV_BUFFSIZE);
- if (rds_ring->rx_buf_arr == NULL) {
- printk(KERN_ERR "%s: Failed to allocate "
- "rx buffer ring %d\n",
- netdev->name, ring);
- /* free whatever was already allocated */
- goto err_out;
- }
- memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
- INIT_LIST_HEAD(&rds_ring->free_list);
- /*
- * Now go through all of them, set reference handles
- * and put them in the queues.
- */
- num_rx_bufs = rds_ring->max_rx_desc_count;
- rx_buf = rds_ring->rx_buf_arr;
- for (i = 0; i < num_rx_bufs; i++) {
- list_add_tail(&rx_buf->list,
- &rds_ring->free_list);
- rx_buf->ref_handle = i;
- rx_buf->state = NETXEN_BUFFER_FREE;
- rx_buf++;
- }
+ case RCV_RING_LRO:
+ rds_ring->num_desc = adapter->num_lro_rxd;
+ rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
+ rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+ break;
+
+ }
+ rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
+ vmalloc(RCV_BUFF_RINGSIZE(rds_ring));
+ if (rds_ring->rx_buf_arr == NULL) {
+ printk(KERN_ERR "%s: Failed to allocate "
+ "rx buffer ring %d\n",
+ netdev->name, ring);
+ /* free whatever was already allocated */
+ goto err_out;
+ }
+ memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring));
+ INIT_LIST_HEAD(&rds_ring->free_list);
+ /*
+ * 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++) {
+ list_add_tail(&rx_buf->list,
+ &rds_ring->free_list);
+ rx_buf->ref_handle = i;
+ rx_buf->state = NETXEN_BUFFER_FREE;
+ rx_buf++;
}
+ spin_lock_init(&rds_ring->lock);
+ }
+
+ 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;
+
+ for (i = 0; i < NUM_RCV_DESC_RINGS; i++)
+ INIT_LIST_HEAD(&sds_ring->free_list[i]);
}
return 0;
@@ -333,7 +325,7 @@ err_out:
void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
{
- switch (adapter->ahw.board_type) {
+ switch (adapter->ahw.port_type) {
case NETXEN_NIC_GBE:
adapter->enable_phy_interrupts =
netxen_niu_gbe_enable_phy_interrupts;
@@ -399,9 +391,6 @@ static u32 netxen_decode_crb_addr(u32 addr)
static long rom_max_timeout = 100;
static long rom_lock_timeout = 10000;
-#if 0
-static long rom_write_timeout = 700;
-#endif
static int rom_lock(struct netxen_adapter *adapter)
{
@@ -452,38 +441,6 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
return 0;
}
-#if 0
-static int netxen_rom_wren(struct netxen_adapter *adapter)
-{
- /* Set write enable latch in ROM status register */
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
- M25P_INSTR_WREN);
- if (netxen_wait_rom_done(adapter)) {
- return -1;
- }
- return 0;
-}
-
-static unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter,
- unsigned int addr)
-{
- unsigned int data = 0xdeaddead;
- data = netxen_nic_reg_read(adapter, addr);
- return data;
-}
-
-static int netxen_do_rom_rdsr(struct netxen_adapter *adapter)
-{
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
- M25P_INSTR_RDSR);
- if (netxen_wait_rom_done(adapter)) {
- return -1;
- }
- return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA);
-}
-#endif
-
static void netxen_rom_unlock(struct netxen_adapter *adapter)
{
u32 val;
@@ -493,44 +450,6 @@ static void netxen_rom_unlock(struct netxen_adapter *adapter)
}
-#if 0
-static int netxen_rom_wip_poll(struct netxen_adapter *adapter)
-{
- long timeout = 0;
- long wip = 1;
- int val;
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- while (wip != 0) {
- val = netxen_do_rom_rdsr(adapter);
- wip = val & 1;
- timeout++;
- if (timeout > rom_max_timeout) {
- return -1;
- }
- }
- return 0;
-}
-
-static int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
- int data)
-{
- if (netxen_rom_wren(adapter)) {
- return -1;
- }
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
- M25P_INSTR_PP);
- if (netxen_wait_rom_done(adapter)) {
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- return -1;
- }
-
- return netxen_rom_wip_poll(adapter);
-}
-#endif
-
static int do_rom_fast_read(struct netxen_adapter *adapter,
int addr, int *valp)
{
@@ -597,284 +516,6 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
return ret;
}
-#if 0
-int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data)
-{
- int ret = 0;
-
- if (rom_lock(adapter) != 0) {
- return -1;
- }
- ret = do_rom_fast_write(adapter, addr, data);
- netxen_rom_unlock(adapter);
- return ret;
-}
-
-static int do_rom_fast_write_words(struct netxen_adapter *adapter,
- int addr, u8 *bytes, size_t size)
-{
- int addridx = addr;
- int ret = 0;
-
- while (addridx < (addr + size)) {
- int last_attempt = 0;
- int timeout = 0;
- int data;
-
- data = le32_to_cpu((*(__le32*)bytes));
- ret = do_rom_fast_write(adapter, addridx, data);
- if (ret < 0)
- return ret;
-
- while(1) {
- int data1;
-
- ret = do_rom_fast_read(adapter, addridx, &data1);
- if (ret < 0)
- return ret;
-
- if (data1 == data)
- break;
-
- if (timeout++ >= rom_write_timeout) {
- if (last_attempt++ < 4) {
- ret = do_rom_fast_write(adapter,
- addridx, data);
- if (ret < 0)
- return ret;
- }
- else {
- printk(KERN_INFO "Data write did not "
- "succeed at address 0x%x\n", addridx);
- break;
- }
- }
- }
-
- bytes += 4;
- addridx += 4;
- }
-
- return ret;
-}
-
-int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
- u8 *bytes, size_t size)
-{
- int ret = 0;
-
- ret = rom_lock(adapter);
- if (ret < 0)
- return ret;
-
- ret = do_rom_fast_write_words(adapter, addr, bytes, size);
- netxen_rom_unlock(adapter);
-
- return ret;
-}
-
-static int netxen_rom_wrsr(struct netxen_adapter *adapter, int data)
-{
- int ret;
-
- ret = netxen_rom_wren(adapter);
- if (ret < 0)
- return ret;
-
- netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1);
-
- ret = netxen_wait_rom_done(adapter);
- if (ret < 0)
- return ret;
-
- return netxen_rom_wip_poll(adapter);
-}
-
-static int netxen_rom_rdsr(struct netxen_adapter *adapter)
-{
- int ret;
-
- ret = rom_lock(adapter);
- if (ret < 0)
- return ret;
-
- ret = netxen_do_rom_rdsr(adapter);
- netxen_rom_unlock(adapter);
- return ret;
-}
-
-int netxen_backup_crbinit(struct netxen_adapter *adapter)
-{
- int ret = FLASH_SUCCESS;
- int val;
- char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL);
-
- if (!buffer)
- return -ENOMEM;
- /* unlock sector 63 */
- val = netxen_rom_rdsr(adapter);
- val = val & 0xe3;
- ret = netxen_rom_wrsr(adapter, val);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- ret = netxen_rom_wip_poll(adapter);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- /* copy sector 0 to sector 63 */
- ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START,
- buffer, NETXEN_FLASH_SECTOR_SIZE);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START,
- buffer, NETXEN_FLASH_SECTOR_SIZE);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- /* lock sector 63 */
- val = netxen_rom_rdsr(adapter);
- if (!(val & 0x8)) {
- val |= (0x1 << 2);
- /* lock sector 63 */
- if (netxen_rom_wrsr(adapter, val) == 0) {
- ret = netxen_rom_wip_poll(adapter);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- /* lock SR writes */
- ret = netxen_rom_wip_poll(adapter);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
- }
- }
-
-out_kfree:
- kfree(buffer);
- return ret;
-}
-
-static int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
-{
- netxen_rom_wren(adapter);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
- M25P_INSTR_SE);
- if (netxen_wait_rom_done(adapter)) {
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- return -1;
- }
- return netxen_rom_wip_poll(adapter);
-}
-
-static void check_erased_flash(struct netxen_adapter *adapter, int addr)
-{
- int i;
- int val;
- int count = 0, erased_errors = 0;
- int range;
-
- range = (addr == NETXEN_USER_START) ?
- NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE;
-
- for (i = addr; i < range; i += 4) {
- netxen_rom_fast_read(adapter, i, &val);
- if (val != 0xffffffff)
- erased_errors++;
- count++;
- }
-
- if (erased_errors)
- printk(KERN_INFO "0x%x out of 0x%x words fail to be erased "
- "for sector address: %x\n", erased_errors, count, addr);
-}
-
-int netxen_rom_se(struct netxen_adapter *adapter, int addr)
-{
- int ret = 0;
- if (rom_lock(adapter) != 0) {
- return -1;
- }
- ret = netxen_do_rom_se(adapter, addr);
- netxen_rom_unlock(adapter);
- msleep(30);
- check_erased_flash(adapter, addr);
-
- return ret;
-}
-
-static int netxen_flash_erase_sections(struct netxen_adapter *adapter,
- int start, int end)
-{
- int ret = FLASH_SUCCESS;
- int i;
-
- for (i = start; i < end; i++) {
- ret = netxen_rom_se(adapter, i * NETXEN_FLASH_SECTOR_SIZE);
- if (ret)
- break;
- ret = netxen_rom_wip_poll(adapter);
- if (ret < 0)
- return ret;
- }
-
- return ret;
-}
-
-int
-netxen_flash_erase_secondary(struct netxen_adapter *adapter)
-{
- int ret = FLASH_SUCCESS;
- int start, end;
-
- start = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;
- end = NETXEN_USER_START / NETXEN_FLASH_SECTOR_SIZE;
- ret = netxen_flash_erase_sections(adapter, start, end);
-
- return ret;
-}
-
-int
-netxen_flash_erase_primary(struct netxen_adapter *adapter)
-{
- int ret = FLASH_SUCCESS;
- int start, end;
-
- start = NETXEN_PRIMARY_START / NETXEN_FLASH_SECTOR_SIZE;
- end = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;
- ret = netxen_flash_erase_sections(adapter, start, end);
-
- return ret;
-}
-
-void netxen_halt_pegs(struct netxen_adapter *adapter)
-{
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c, 1);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c, 1);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c, 1);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c, 1);
-}
-
-int netxen_flash_unlock(struct netxen_adapter *adapter)
-{
- int ret = 0;
-
- ret = netxen_rom_wrsr(adapter, 0);
- if (ret < 0)
- return ret;
-
- ret = netxen_rom_wren(adapter);
- if (ret < 0)
- return ret;
-
- return ret;
-}
-#endif /* 0 */
-
#define NETXEN_BOARDTYPE 0x4008
#define NETXEN_BOARDNUM 0x400c
#define NETXEN_CHIPNUM 0x4010
@@ -947,8 +588,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
}
for (i = 0; i < n; i++) {
if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
- netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0)
+ netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
+ kfree(buf);
return -EIO;
+ }
buf[i].addr = addr;
buf[i].data = val;
@@ -1166,6 +809,40 @@ int netxen_receive_peg_ready(struct netxen_adapter *adapter)
return 0;
}
+static int
+netxen_alloc_rx_skb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring,
+ struct netxen_rx_buffer *buffer)
+{
+ struct sk_buff *skb;
+ dma_addr_t dma;
+ struct pci_dev *pdev = adapter->pdev;
+
+ buffer->skb = dev_alloc_skb(rds_ring->skb_size);
+ if (!buffer->skb)
+ return 1;
+
+ skb = buffer->skb;
+
+ if (!adapter->ahw.cut_through)
+ skb_reserve(skb, 2);
+
+ dma = pci_map_single(pdev, skb->data,
+ rds_ring->dma_size, PCI_DMA_FROMDEVICE);
+
+ if (pci_dma_mapping_error(pdev, dma)) {
+ dev_kfree_skb_any(skb);
+ buffer->skb = NULL;
+ return 1;
+ }
+
+ buffer->skb = skb;
+ buffer->dma = dma;
+ buffer->state = NETXEN_BUFFER_BUSY;
+
+ return 0;
+}
+
static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum)
{
@@ -1190,164 +867,121 @@ static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
skb->dev = adapter->netdev;
buffer->skb = NULL;
-
no_skb:
buffer->state = NETXEN_BUFFER_FREE;
- buffer->lro_current_frags = 0;
- buffer->lro_expected_frags = 0;
- list_add_tail(&buffer->list, &rds_ring->free_list);
return skb;
}
-/*
- * netxen_process_rcv() send the received packet to the protocol stack.
- * and if the number of receives exceeds RX_BUFFERS_REFILL, then we
- * invoke the routine to send more rx buffers to the Phantom...
- */
-static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
- struct status_desc *desc, struct status_desc *frag_desc)
+static struct netxen_rx_buffer *
+netxen_process_rcv(struct netxen_adapter *adapter,
+ int ring, int index, int length, int cksum, int pkt_offset)
{
struct net_device *netdev = adapter->netdev;
- u64 sts_data = le64_to_cpu(desc->status_desc_data);
- int index = netxen_get_sts_refhandle(sts_data);
- struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
struct netxen_rx_buffer *buffer;
struct sk_buff *skb;
- u32 length = netxen_get_sts_totallength(sts_data);
- u32 desc_ctx;
- u16 pkt_offset = 0, cksum;
- struct nx_host_rds_ring *rds_ring;
+ struct nx_host_rds_ring *rds_ring = &recv_ctx->rds_rings[ring];
- desc_ctx = netxen_get_sts_type(sts_data);
- if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
- printk("%s: %s Bad Rcv descriptor ring\n",
- netxen_nic_driver_name, netdev->name);
- return;
- }
+ if (unlikely(index > rds_ring->num_desc))
+ return NULL;
- rds_ring = &recv_ctx->rds_rings[desc_ctx];
- if (unlikely(index > rds_ring->max_rx_desc_count)) {
- DPRINTK(ERR, "Got a buffer index:%x Max is %x\n",
- index, rds_ring->max_rx_desc_count);
- return;
- }
buffer = &rds_ring->rx_buf_arr[index];
- if (desc_ctx == RCV_DESC_LRO_CTXID) {
- buffer->lro_current_frags++;
- if (netxen_get_sts_desc_lro_last_frag(desc)) {
- buffer->lro_expected_frags =
- netxen_get_sts_desc_lro_cnt(desc);
- buffer->lro_length = length;
- }
- if (buffer->lro_current_frags != buffer->lro_expected_frags) {
- if (buffer->lro_expected_frags != 0) {
- printk("LRO: (refhandle:%x) recv frag. "
- "wait for last. flags: %x expected:%d "
- "have:%d\n", index,
- netxen_get_sts_desc_lro_last_frag(desc),
- buffer->lro_expected_frags,
- buffer->lro_current_frags);
- }
- return;
- }
- }
-
- cksum = netxen_get_sts_status(sts_data);
skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
if (!skb)
- return;
+ return buffer;
- if (desc_ctx == RCV_DESC_LRO_CTXID) {
- /* True length was only available on the last pkt */
- skb_put(skb, buffer->lro_length);
- } else {
- if (length > rds_ring->skb_size)
- skb_put(skb, rds_ring->skb_size);
- else
- skb_put(skb, length);
+ if (length > rds_ring->skb_size)
+ skb_put(skb, rds_ring->skb_size);
+ else
+ skb_put(skb, length);
- pkt_offset = netxen_get_sts_pkt_offset(sts_data);
- if (pkt_offset)
- skb_pull(skb, pkt_offset);
- }
+
+ if (pkt_offset)
+ skb_pull(skb, pkt_offset);
skb->protocol = eth_type_trans(skb, netdev);
- /*
- * rx buffer chaining is disabled, walk and free
- * any spurious rx buffer chain.
- */
- if (frag_desc) {
- u16 i, nr_frags = desc->nr_frags;
+ netif_receive_skb(skb);
- dev_kfree_skb_any(skb);
- for (i = 0; i < nr_frags; i++) {
- index = le16_to_cpu(frag_desc->frag_handles[i]);
- skb = netxen_process_rxbuf(adapter,
- rds_ring, index, cksum);
- if (skb)
- dev_kfree_skb_any(skb);
- }
- adapter->stats.rxdropped++;
- } else {
- netif_receive_skb(skb);
+ adapter->stats.no_rcv++;
+ adapter->stats.rxbytes += length;
- adapter->stats.no_rcv++;
- adapter->stats.rxbytes += length;
- }
+ return buffer;
}
-/* Process Receive status ring */
-u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
+#define netxen_merge_rx_buffers(list, head) \
+ do { list_splice_tail_init(list, head); } while (0);
+
+int
+netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
{
- struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
- struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
- struct status_desc *desc, *frag_desc;
- u32 consumer = recv_ctx->status_rx_consumer;
- int count = 0, ring;
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ struct list_head *cur;
+
+ struct status_desc *desc;
+ struct netxen_rx_buffer *rxbuf;
+
+ u32 consumer = sds_ring->consumer;
+
+ int count = 0;
u64 sts_data;
- u16 opcode;
+ int opcode, ring, index, length, cksum, pkt_offset;
while (count < max) {
- desc = &desc_head[consumer];
- if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) {
- DPRINTK(ERR, "desc %p ownedby %x\n", desc,
- netxen_get_sts_owner(desc));
+ desc = &sds_ring->desc_head[consumer];
+ sts_data = le64_to_cpu(desc->status_desc_data);
+
+ if (!(sts_data & STATUS_OWNER_HOST))
break;
- }
- sts_data = le64_to_cpu(desc->status_desc_data);
+ ring = netxen_get_sts_type(sts_data);
+ if (ring > RCV_RING_JUMBO)
+ continue;
+
opcode = netxen_get_sts_opcode(sts_data);
- frag_desc = NULL;
- if (opcode == NETXEN_NIC_RXPKT_DESC) {
- if (desc->nr_frags) {
- consumer = get_next_index(consumer,
- adapter->max_rx_desc_count);
- frag_desc = &desc_head[consumer];
- netxen_set_sts_owner(frag_desc,
- STATUS_OWNER_PHANTOM);
- }
- }
- netxen_process_rcv(adapter, ctxid, desc, frag_desc);
+ 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);
+
+ if (rxbuf)
+ list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
- netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
+ desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
- consumer = get_next_index(consumer,
- adapter->max_rx_desc_count);
+ consumer = get_next_index(consumer, sds_ring->num_desc);
count++;
}
- for (ring = 0; ring < adapter->max_rds_rings; ring++)
- netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
- /* update the consumer index in phantom */
- if (count) {
- recv_ctx->status_rx_consumer = consumer;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ struct nx_host_rds_ring *rds_ring =
+ &adapter->recv_ctx.rds_rings[ring];
- /* Window = 1 */
+ if (!list_empty(&sds_ring->free_list[ring])) {
+ list_for_each(cur, &sds_ring->free_list[ring]) {
+ rxbuf = list_entry(cur,
+ struct netxen_rx_buffer, list);
+ netxen_alloc_rx_skb(adapter, rds_ring, rxbuf);
+ }
+ spin_lock(&rds_ring->lock);
+ netxen_merge_rx_buffers(&sds_ring->free_list[ring],
+ &rds_ring->free_list);
+ spin_unlock(&rds_ring->lock);
+ }
+
+ netxen_post_rx_buffers_nodb(adapter, rds_ring);
+ }
+
+ if (count) {
+ sds_ring->consumer = consumer;
adapter->pci_write_normalize(adapter,
- recv_ctx->crb_sts_consumer, consumer);
+ sds_ring->crb_sts_consumer, consumer);
}
return count;
@@ -1364,7 +998,11 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
struct netxen_skb_frag *frag;
int done = 0;
+ 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));
while (last_consumer != consumer) {
@@ -1387,7 +1025,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
}
last_consumer = get_next_index(last_consumer,
- adapter->max_tx_desc_count);
+ adapter->num_txd);
if (++count >= MAX_STATUS_HANDLE)
break;
}
@@ -1415,75 +1053,55 @@ 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);
+ spin_unlock(&adapter->tx_clean_lock);
return (done);
}
-/*
- * netxen_post_rx_buffers puts buffer in the Phantom memory
- */
-void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
+void
+netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
+ struct nx_host_rds_ring *rds_ring)
{
- struct pci_dev *pdev = adapter->pdev;
- struct sk_buff *skb;
- struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
- struct nx_host_rds_ring *rds_ring = NULL;
- uint producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
- int count = 0;
+ int producer, count = 0;
netxen_ctx_msg msg = 0;
- dma_addr_t dma;
struct list_head *head;
- rds_ring = &recv_ctx->rds_rings[ringid];
-
producer = rds_ring->producer;
- head = &rds_ring->free_list;
- /* We can start writing rx descriptors into the phantom memory. */
+ spin_lock(&rds_ring->lock);
+ head = &rds_ring->free_list;
while (!list_empty(head)) {
- skb = dev_alloc_skb(rds_ring->skb_size);
- if (unlikely(!skb)) {
- break;
- }
-
- if (!adapter->ahw.cut_through)
- skb_reserve(skb, 2);
+ buffer = list_entry(head->next, struct netxen_rx_buffer, list);
- dma = pci_map_single(pdev, skb->data,
- rds_ring->dma_size, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, dma)) {
- dev_kfree_skb_any(skb);
- break;
+ if (!buffer->skb) {
+ if (netxen_alloc_rx_skb(adapter, rds_ring, buffer))
+ break;
}
count++;
- buffer = list_entry(head->next, struct netxen_rx_buffer, list);
list_del(&buffer->list);
- buffer->skb = skb;
- buffer->state = NETXEN_BUFFER_BUSY;
- buffer->dma = dma;
-
/* make a rcv descriptor */
pdesc = &rds_ring->desc_head[producer];
- pdesc->addr_buffer = cpu_to_le64(dma);
+ pdesc->addr_buffer = cpu_to_le64(buffer->dma);
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
- producer = get_next_index(producer, rds_ring->max_rx_desc_count);
+ producer = get_next_index(producer, rds_ring->num_desc);
}
- /* if we did allocate buffers, then write the count to Phantom */
+ spin_unlock(&rds_ring->lock);
+
if (count) {
rds_ring->producer = producer;
- /* Window = 1 */
adapter->pci_write_normalize(adapter,
rds_ring->crb_rcv_producer,
- (producer-1) & (rds_ring->max_rx_desc_count-1));
+ (producer-1) & (rds_ring->num_desc-1));
if (adapter->fw_major < 4) {
/*
@@ -1494,9 +1112,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
netxen_set_msg_privid(msg);
netxen_set_msg_count(msg,
- ((producer -
- 1) & (rds_ring->
- max_rx_desc_count - 1)));
+ ((producer - 1) &
+ (rds_ring->num_desc - 1)));
netxen_set_msg_ctxid(msg, adapter->portnum);
netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
writel(msg,
@@ -1506,68 +1123,49 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
}
}
-static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
- uint32_t ctx, uint32_t ringid)
+static void
+netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring)
{
- struct pci_dev *pdev = adapter->pdev;
- struct sk_buff *skb;
- struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
- struct nx_host_rds_ring *rds_ring = NULL;
- u32 producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
- int count = 0;
+ int producer, count = 0;
struct list_head *head;
- dma_addr_t dma;
-
- rds_ring = &recv_ctx->rds_rings[ringid];
producer = rds_ring->producer;
+ if (!spin_trylock(&rds_ring->lock))
+ return;
+
head = &rds_ring->free_list;
- /* We can start writing rx descriptors into the phantom memory. */
while (!list_empty(head)) {
- skb = dev_alloc_skb(rds_ring->skb_size);
- if (unlikely(!skb)) {
- break;
- }
-
- if (!adapter->ahw.cut_through)
- skb_reserve(skb, 2);
+ buffer = list_entry(head->next, struct netxen_rx_buffer, list);
- dma = pci_map_single(pdev, skb->data,
- rds_ring->dma_size, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, dma)) {
- dev_kfree_skb_any(skb);
- break;
+ if (!buffer->skb) {
+ if (netxen_alloc_rx_skb(adapter, rds_ring, buffer))
+ break;
}
count++;
- buffer = list_entry(head->next, struct netxen_rx_buffer, list);
list_del(&buffer->list);
- buffer->skb = skb;
- buffer->state = NETXEN_BUFFER_BUSY;
- buffer->dma = dma;
-
/* make a rcv descriptor */
pdesc = &rds_ring->desc_head[producer];
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
pdesc->addr_buffer = cpu_to_le64(buffer->dma);
- producer = get_next_index(producer, rds_ring->max_rx_desc_count);
+ producer = get_next_index(producer, rds_ring->num_desc);
}
- /* if we did allocate buffers, then write the count to Phantom */
if (count) {
rds_ring->producer = producer;
- /* Window = 1 */
adapter->pci_write_normalize(adapter,
rds_ring->crb_rcv_producer,
- (producer-1) & (rds_ring->max_rx_desc_count-1));
+ (producer - 1) & (rds_ring->num_desc - 1));
wmb();
}
+ spin_unlock(&rds_ring->lock);
}
void netxen_nic_clear_stats(struct netxen_adapter *adapter)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 86867405a36..1af47257ba8 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Main source file for NetXen NIC Driver on Linux
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -41,6 +38,7 @@
#include <linux/dma-mapping.h>
#include <linux/if_vlan.h>
#include <net/ip.h>
+#include <linux/ipv6.h>
MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
MODULE_LICENSE("GPL");
@@ -75,6 +73,7 @@ static void netxen_nic_poll_controller(struct net_device *netdev);
#endif
static irqreturn_t netxen_intr(int irq, void *data);
static irqreturn_t netxen_msi_intr(int irq, void *data);
+static irqreturn_t netxen_msix_intr(int irq, void *data);
/* PCI Device ID Table */
#define ENTRY(device) \
@@ -95,20 +94,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
-/*
- * In netxen_nic_down(), we must wait for any pending callback requests into
- * netxen_watchdog_task() to complete; eg otherwise the watchdog_timer could be
- * reenabled right after it is deleted in netxen_nic_down().
- * FLUSH_SCHEDULED_WORK() does this synchronization.
- *
- * Normally, schedule_work()/flush_scheduled_work() could have worked, but
- * netxen_nic_close() is invoked with kernel rtnl lock held. netif_carrier_off()
- * call in netxen_nic_close() triggers a schedule_work(&linkwatch_work), and a
- * subsequent call to flush_scheduled_work() in netxen_nic_down() would cause
- * linkwatch_event() to be executed which also attempts to acquire the rtnl
- * lock thus causing a deadlock.
- */
-
static struct workqueue_struct *netxen_workq;
#define SCHEDULE_WORK(tp) queue_work(netxen_workq, tp)
#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq)
@@ -150,130 +135,148 @@ static uint32_t msi_tgt_status[8] = {
static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
-static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
{
- adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0);
}
-static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
{
- adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ adapter->pci_write_normalize(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 void
+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;
+
+ 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);
+ }
+}
+
+static void
+netxen_napi_enable(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ napi_enable(&sds_ring->napi);
+ netxen_nic_enable_int(sds_ring);
+ }
+}
+
+static void
+netxen_napi_disable(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ 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);
+ }
+}
+
static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
{
struct pci_dev *pdev = adapter->pdev;
- int err;
- uint64_t mask;
-
-#ifdef CONFIG_IA64
- adapter->dma_mask = DMA_32BIT_MASK;
-#else
- if (revision_id >= NX_P3_B0) {
- /* should go to DMA_64BIT_MASK */
- adapter->dma_mask = DMA_39BIT_MASK;
- mask = DMA_39BIT_MASK;
- } else if (revision_id == NX_P3_A2) {
- adapter->dma_mask = DMA_39BIT_MASK;
- mask = DMA_39BIT_MASK;
- } else if (revision_id == NX_P2_C1) {
- adapter->dma_mask = DMA_35BIT_MASK;
- mask = DMA_35BIT_MASK;
- } else {
- adapter->dma_mask = DMA_32BIT_MASK;
- mask = DMA_32BIT_MASK;
- goto set_32_bit_mask;
- }
+ uint64_t mask, cmask;
+
+ adapter->pci_using_dac = 0;
+ mask = DMA_32BIT_MASK;
/*
* Consistent DMA mask is set to 32 bit because it cannot be set to
* 35 bits. For P3 also leave it at 32 bits for now. Only the rings
* come off this pool.
*/
+ cmask = DMA_32BIT_MASK;
+
+#ifndef CONFIG_IA64
+ if (revision_id >= NX_P3_B0)
+ mask = DMA_39BIT_MASK;
+ else if (revision_id == NX_P2_C1)
+ mask = DMA_35BIT_MASK;
+#endif
if (pci_set_dma_mask(pdev, mask) == 0 &&
- pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) == 0) {
+ pci_set_consistent_dma_mask(pdev, cmask) == 0) {
adapter->pci_using_dac = 1;
return 0;
}
-#endif /* CONFIG_IA64 */
-set_32_bit_mask:
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
- if (err) {
- DPRINTK(ERR, "No usable DMA configuration, aborting:%d\n", err);
- return err;
+ return -EIO;
+}
+
+/* Update addressable range if firmware supports it */
+static int
+nx_update_dma_mask(struct netxen_adapter *adapter)
+{
+ int change, shift, err;
+ uint64_t mask, old_mask;
+ struct pci_dev *pdev = adapter->pdev;
+
+ change = 0;
+
+ shift = netxen_nic_reg_read(adapter, CRB_DMA_SHIFT);
+ if (shift >= 32)
+ return 0;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id) && (shift > 9))
+ change = 1;
+ else if ((adapter->ahw.revision_id == NX_P2_C1) && (shift <= 4))
+ change = 1;
+
+ if (change) {
+ old_mask = pdev->dma_mask;
+ mask = (1ULL<<(32+shift)) - 1;
+
+ err = pci_set_dma_mask(pdev, mask);
+ if (err)
+ return pci_set_dma_mask(pdev, old_mask);
}
- adapter->pci_using_dac = 0;
return 0;
}
static void netxen_check_options(struct netxen_adapter *adapter)
{
- switch (adapter->ahw.boardcfg.board_type) {
- case NETXEN_BRDTYPE_P3_HMEZ:
- case NETXEN_BRDTYPE_P3_XG_LOM:
- case NETXEN_BRDTYPE_P3_10G_CX4:
- case NETXEN_BRDTYPE_P3_10G_CX4_LP:
- case NETXEN_BRDTYPE_P3_IMEZ:
- case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
- case NETXEN_BRDTYPE_P3_10G_SFP_QT:
- case NETXEN_BRDTYPE_P3_10G_SFP_CT:
- case NETXEN_BRDTYPE_P3_10G_XFP:
- case NETXEN_BRDTYPE_P3_10000_BASE_T:
- adapter->msix_supported = !!use_msi_x;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- break;
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
+ adapter->num_rxd = MAX_RCV_DESCRIPTORS_10G;
+ else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+ adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
- case NETXEN_BRDTYPE_P2_SB31_10G:
- case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
- case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
- case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
- adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- break;
-
- case NETXEN_BRDTYPE_P3_REF_QG:
- case NETXEN_BRDTYPE_P3_4_GB:
- case NETXEN_BRDTYPE_P3_4_GB_MM:
- adapter->msix_supported = !!use_msi_x;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- case NETXEN_BRDTYPE_P2_SB35_4G:
- case NETXEN_BRDTYPE_P2_SB31_2G:
- adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- case NETXEN_BRDTYPE_P3_10G_TP:
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
adapter->msix_supported = !!use_msi_x;
- if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- else
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- default:
+ else
adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- printk(KERN_WARNING "Unknown board type(0x%x)\n",
- adapter->ahw.boardcfg.board_type);
- break;
- }
+ adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
+ adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
+ adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
- adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
- adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
- adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
-
- adapter->max_possible_rss_rings = 1;
return;
}
@@ -334,7 +337,7 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
{
u32 val, data;
- val = adapter->ahw.boardcfg.board_type;
+ val = adapter->ahw.board_type;
if ((val == NETXEN_BRDTYPE_P3_HMEZ) ||
(val == NETXEN_BRDTYPE_P3_XG_LOM)) {
if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
@@ -370,67 +373,6 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
}
}
-#define PCI_CAP_ID_GEN 0x10
-
-static void netxen_pcie_strap_init(struct netxen_adapter *adapter)
-{
- u32 pdevfuncsave;
- u32 c8c9value = 0;
- u32 chicken = 0;
- u32 control = 0;
- int i, pos;
- struct pci_dev *pdev;
-
- pdev = adapter->pdev;
-
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4);
- /* clear chicken3.25:24 */
- chicken &= 0xFCFFFFFF;
- /*
- * if gen1 and B0, set F1020 - if gen 2, do nothing
- * if gen2 set to F1000
- */
- pos = pci_find_capability(pdev, PCI_CAP_ID_GEN);
- if (pos == 0xC0) {
- pci_read_config_dword(pdev, pos + 0x10, &control);
- if ((control & 0x000F0000) != 0x00020000) {
- /* set chicken3.24 if gen1 */
- chicken |= 0x01000000;
- }
- printk(KERN_INFO "%s Gen2 strapping detected\n",
- netxen_nic_driver_name);
- c8c9value = 0xF1000;
- } else {
- /* set chicken3.24 if gen1 */
- chicken |= 0x01000000;
- printk(KERN_INFO "%s Gen1 strapping detected\n",
- netxen_nic_driver_name);
- if (adapter->ahw.revision_id == NX_P3_B0)
- c8c9value = 0xF1020;
- else
- c8c9value = 0;
-
- }
- adapter->hw_write_wx(adapter,
- NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4);
-
- if (!c8c9value)
- return;
-
- pdevfuncsave = pdev->devfn;
- if (pdevfuncsave & 0x07)
- return;
-
- for (i = 0; i < 8; i++) {
- pci_read_config_dword(pdev, pos + 8, &control);
- pci_read_config_dword(pdev, pos + 8, &control);
- pci_write_config_dword(pdev, pos + 8, c8c9value);
- pdev->devfn++;
- }
- pdev->devfn = pdevfuncsave;
-}
-
static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
{
u32 control;
@@ -464,9 +406,6 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
- if (netxen_is_flash_supported(adapter) != 0)
- return -EIO;
-
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0)
return -EIO;
@@ -516,91 +455,91 @@ static const struct net_device_ops netxen_netdev_ops = {
#endif
};
-/*
- * netxen_nic_probe()
- *
- * The Linux system will invoke this after identifying the vendor ID and
- * device Id in the pci_tbl supported by this module.
- *
- * A quad port card has one operational PCI config space, (function 0),
- * which is used to access all four ports.
- *
- * This routine will initialize the adapter, and setup the global parameters
- * along with the port's specific structure.
- */
-static int __devinit
-netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static void
+netxen_setup_intr(struct netxen_adapter *adapter)
{
- struct net_device *netdev = NULL;
- struct netxen_adapter *adapter = NULL;
- void __iomem *mem_ptr0 = NULL;
- void __iomem *mem_ptr1 = NULL;
- void __iomem *mem_ptr2 = NULL;
- unsigned long first_page_group_end;
- unsigned long first_page_group_start;
+ struct netxen_legacy_intr_set *legacy_intrp;
+ struct pci_dev *pdev = adapter->pdev;
+ adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
+ adapter->intr_scheme = -1;
+ adapter->msi_mode = -1;
- u8 __iomem *db_ptr = NULL;
- unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
- int i = 0, err;
- int first_driver, first_boot;
- u32 val;
- int pci_func_id = PCI_FUNC(pdev->devfn);
- struct netxen_legacy_intr_set *legacy_intrp;
- uint8_t revision_id;
+ if (adapter->ahw.revision_id >= NX_P3_B0)
+ legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
+ else
+ legacy_intrp = &legacy_intr[0];
+ adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
+ adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
+ adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
+ adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
- if (pci_func_id == 0)
- printk(KERN_INFO "%s\n", netxen_nic_driver_string);
+ netxen_set_msix_bit(pdev, 0);
- if (pdev->class != 0x020000) {
- printk(KERN_DEBUG "NetXen function %d, class %x will not "
- "be enabled.\n",pci_func_id, pdev->class);
- return -ENODEV;
- }
+ if (adapter->msix_supported) {
- if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
- printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
- "will not be enabled.\n",
- NX_P3_A0, NX_P3_B1);
- return -ENODEV;
- }
+ netxen_init_msix_entries(adapter);
+ if (pci_enable_msix(pdev, adapter->msix_entries,
+ MSIX_ENTRIES_PER_ADAPTER))
+ goto request_msi;
- if ((err = pci_enable_device(pdev)))
- return err;
+ adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
+ netxen_set_msix_bit(pdev, 1);
+ dev_info(&pdev->dev, "using msi-x interrupts\n");
- if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
- err = -ENODEV;
- goto err_out_disable_pdev;
+ } 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");
+ adapter->msix_entries[0].vector = pdev->irq;
}
+}
- if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
- goto err_out_disable_pdev;
-
- pci_set_master(pdev);
+static void
+netxen_teardown_intr(struct netxen_adapter *adapter)
+{
+ if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+ pci_disable_msix(adapter->pdev);
+ if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+ pci_disable_msi(adapter->pdev);
+}
- netdev = alloc_etherdev(sizeof(struct netxen_adapter));
- if(!netdev) {
- printk(KERN_ERR"%s: Failed to allocate memory for the "
- "device block.Check system memory resource"
- " usage.\n", netxen_nic_driver_name);
- goto err_out_free_res;
- }
+static void
+netxen_cleanup_pci_map(struct netxen_adapter *adapter)
+{
+ if (adapter->ahw.db_base != NULL)
+ iounmap(adapter->ahw.db_base);
+ if (adapter->ahw.pci_base0 != NULL)
+ iounmap(adapter->ahw.pci_base0);
+ if (adapter->ahw.pci_base1 != NULL)
+ iounmap(adapter->ahw.pci_base1);
+ if (adapter->ahw.pci_base2 != NULL)
+ iounmap(adapter->ahw.pci_base2);
+}
- SET_NETDEV_DEV(netdev, &pdev->dev);
+static int
+netxen_setup_pci_map(struct netxen_adapter *adapter)
+{
+ void __iomem *mem_ptr0 = NULL;
+ void __iomem *mem_ptr1 = NULL;
+ void __iomem *mem_ptr2 = NULL;
+ void __iomem *db_ptr = NULL;
- adapter = netdev_priv(netdev);
- adapter->netdev = netdev;
- adapter->pdev = pdev;
- adapter->ahw.pci_func = pci_func_id;
+ unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0;
- revision_id = pdev->revision;
- adapter->ahw.revision_id = revision_id;
+ struct pci_dev *pdev = adapter->pdev;
+ int pci_func = adapter->ahw.pci_func;
- err = nx_set_dma_mask(adapter, revision_id);
- if (err)
- goto err_out_free_netdev;
+ int err = 0;
- rwlock_init(&adapter->adapter_lock);
+ /*
+ * Set the CRB window to invalid. If any register in window 0 is
+ * accessed it should set the window to 0 and then reset it to 1.
+ */
+ adapter->curr_window = 255;
adapter->ahw.qdr_sn_window = -1;
adapter->ahw.ddr_mn_window = -1;
@@ -626,14 +565,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SECOND_PAGE_GROUP_SIZE);
mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
THIRD_PAGE_GROUP_SIZE);
- first_page_group_start = FIRST_PAGE_GROUP_START;
- first_page_group_end = FIRST_PAGE_GROUP_END;
} else if (mem_len == NETXEN_PCI_32MB_SIZE) {
mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
- first_page_group_start = 0;
- first_page_group_end = 0;
} else if (mem_len == NETXEN_PCI_2MB_SIZE) {
adapter->hw_write_wx = netxen_nic_hw_write_wx_2M;
adapter->hw_read_wx = netxen_nic_hw_read_wx_2M;
@@ -647,29 +582,38 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
- mem_ptr0 = ioremap(mem_base, mem_len);
+ mem_ptr0 = pci_ioremap_bar(pdev, 0);
+ if (mem_ptr0 == NULL) {
+ dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+ return -EIO;
+ }
pci_len0 = mem_len;
- first_page_group_start = 0;
- first_page_group_end = 0;
adapter->ahw.ddr_mn_window = 0;
adapter->ahw.qdr_sn_window = 0;
adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
- (pci_func_id * 0x20);
+ (pci_func * 0x20);
adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW;
- if (pci_func_id < 4)
- adapter->ahw.ms_win_crb += (pci_func_id * 0x20);
+ if (pci_func < 4)
+ adapter->ahw.ms_win_crb += (pci_func * 0x20);
else
adapter->ahw.ms_win_crb +=
- 0xA0 + ((pci_func_id - 4) * 0x10);
+ 0xA0 + ((pci_func - 4) * 0x10);
} else {
- err = -EIO;
- goto err_out_free_netdev;
+ return -EIO;
}
dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
+ adapter->ahw.pci_base0 = mem_ptr0;
+ adapter->ahw.pci_len0 = pci_len0;
+ adapter->ahw.pci_base1 = mem_ptr1;
+ adapter->ahw.pci_base2 = mem_ptr2;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ goto skip_doorbell;
+
db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */
db_len = pci_resource_len(pdev, 4);
@@ -677,49 +621,349 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
printk(KERN_ERR "%s: doorbell is disabled\n",
netxen_nic_driver_name);
err = -EIO;
- goto err_out_iounmap;
+ goto err_out;
}
- DPRINTK(INFO, "doorbell ioremap from %lx a size of %lx\n", db_base,
- db_len);
db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
if (!db_ptr) {
printk(KERN_ERR "%s: Failed to allocate doorbell map.",
netxen_nic_driver_name);
err = -EIO;
- goto err_out_iounmap;
+ goto err_out;
}
- DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);
- adapter->ahw.pci_base0 = mem_ptr0;
- adapter->ahw.pci_len0 = pci_len0;
- adapter->ahw.first_page_group_start = first_page_group_start;
- adapter->ahw.first_page_group_end = first_page_group_end;
- adapter->ahw.pci_base1 = mem_ptr1;
- adapter->ahw.pci_base2 = mem_ptr2;
+skip_doorbell:
adapter->ahw.db_base = db_ptr;
adapter->ahw.db_len = db_len;
+ return 0;
- netif_napi_add(netdev, &adapter->napi,
- netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+err_out:
+ netxen_cleanup_pci_map(adapter);
+ return err;
+}
- if (revision_id >= NX_P3_B0)
- legacy_intrp = &legacy_intr[pci_func_id];
+static int
+netxen_start_firmware(struct netxen_adapter *adapter)
+{
+ 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 (!first_driver)
+ return 0;
+
+ first_boot = adapter->pci_read_normalize(adapter,
+ NETXEN_CAM_RAM(0x1fc));
+
+ err = netxen_check_hw_init(adapter, first_boot);
+ if (err) {
+ dev_err(&pdev->dev, "error in init HW init sequence\n");
+ return err;
+ }
+
+ if (first_boot != 0x55555555) {
+ adapter->pci_write_normalize(adapter,
+ CRB_CMDPEG_STATE, 0);
+ netxen_pinit_from_rom(adapter, 0);
+ msleep(1);
+ }
+
+ netxen_nic_reg_write(adapter, CRB_DMA_SHIFT, 0x55555555);
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ netxen_set_port_mode(adapter);
+
+ netxen_load_firmware(adapter);
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+
+ /* Initialize multicast addr pool owners */
+ val = 0x7654;
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
+ val |= 0x0f000000;
+ netxen_crb_writelit_adapter(adapter,
+ NETXEN_MAC_ADDR_CNTL_REG, val);
+
+ }
+
+ err = netxen_initialize_adapter_offload(adapter);
+ if (err)
+ return err;
+
+ /*
+ * Tell the hardware our version number.
+ */
+ val = (_NETXEN_NIC_LINUX_MAJOR << 16)
+ | ((_NETXEN_NIC_LINUX_MINOR << 8))
+ | (_NETXEN_NIC_LINUX_SUBVERSION);
+ adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, val);
+
+ /* Handshake with the card before we register the devices. */
+ err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+ if (err) {
+ netxen_free_adapter_offload(adapter);
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+netxen_nic_request_irq(struct netxen_adapter *adapter)
+{
+ irq_handler_t handler;
+ struct nx_host_sds_ring *sds_ring;
+ int err, ring;
+
+ unsigned long flags = IRQF_SAMPLE_RANDOM;
+ 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)
+ handler = netxen_msi_intr;
+ else {
+ flags |= IRQF_SHARED;
+ handler = netxen_intr;
+ }
+ adapter->irq = netdev->irq;
+
+ 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);
+ err = request_irq(sds_ring->irq, handler,
+ flags, sds_ring->name, sds_ring);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+netxen_nic_free_irq(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ free_irq(sds_ring->irq, sds_ring);
+ }
+}
+
+static int
+netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+ int err;
+
+ err = adapter->init_port(adapter, adapter->physical_port);
+ if (err) {
+ printk(KERN_ERR "%s: Failed to initialize port %d\n",
+ netxen_nic_driver_name, adapter->portnum);
+ return err;
+ }
+ adapter->macaddr_set(adapter, netdev->dev_addr);
+
+ netxen_nic_set_link_parameters(adapter);
+
+ netxen_set_multicast_list(netdev);
+ if (adapter->set_mtu)
+ 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);
+
+ return 0;
+}
+
+static void
+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);
+
+ netxen_release_tx_buffers(adapter);
+
+ FLUSH_SCHEDULED_WORK();
+ del_timer_sync(&adapter->watchdog_timer);
+}
+
+
+static int
+netxen_nic_attach(struct netxen_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ int err, ring;
+ struct nx_host_rds_ring *rds_ring;
+
+ err = netxen_init_firmware(adapter);
+ if (err != 0) {
+ printk(KERN_ERR "Failed to init firmware\n");
+ return -EIO;
+ }
+
+ if (adapter->fw_major < 4)
+ adapter->max_rds_rings = 3;
else
- legacy_intrp = &legacy_intr[0];
+ adapter->max_rds_rings = 2;
- adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
- adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
- adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
- adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
+ err = netxen_alloc_sw_resources(adapter);
+ if (err) {
+ printk(KERN_ERR "%s: Error in setting sw resources\n",
+ netdev->name);
+ return err;
+ }
- /* this will be read from FW later */
- adapter->intr_scheme = -1;
- adapter->msi_mode = -1;
+ netxen_nic_clear_stats(adapter);
+
+ err = netxen_alloc_hw_resources(adapter);
+ if (err) {
+ printk(KERN_ERR "%s: Error in setting hw resources\n",
+ netdev->name);
+ goto err_out_free_sw;
+ }
+
+ 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];
+
+ netxen_nic_update_cmd_producer(adapter, 0);
+ netxen_nic_update_cmd_consumer(adapter, 0);
+ }
+
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &adapter->recv_ctx.rds_rings[ring];
+ netxen_post_rx_buffers(adapter, ring, rds_ring);
+ }
+
+ err = netxen_nic_request_irq(adapter);
+ if (err) {
+ dev_err(&pdev->dev, "%s: failed to setup interrupt\n",
+ netdev->name);
+ goto err_out_free_rxbuf;
+ }
+
+ adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
+ return 0;
+
+err_out_free_rxbuf:
+ netxen_release_rx_buffers(adapter);
+ netxen_free_hw_resources(adapter);
+err_out_free_sw:
+ netxen_free_sw_resources(adapter);
+ return err;
+}
+
+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_free_sw_resources(adapter);
+
+ adapter->is_up = 0;
+}
+
+static int __devinit
+netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct net_device *netdev = NULL;
+ struct netxen_adapter *adapter = NULL;
+ int i = 0, err;
+ int pci_func_id = PCI_FUNC(pdev->devfn);
+ uint8_t revision_id;
+
+ if (pdev->class != 0x020000) {
+ printk(KERN_DEBUG "NetXen function %d, class %x will not "
+ "be enabled.\n",pci_func_id, pdev->class);
+ return -ENODEV;
+ }
+
+ if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
+ printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
+ "will not be enabled.\n",
+ NX_P3_A0, NX_P3_B1);
+ return -ENODEV;
+ }
+
+ if ((err = pci_enable_device(pdev)))
+ return err;
+
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+ err = -ENODEV;
+ goto err_out_disable_pdev;
+ }
+
+ if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
+ goto err_out_disable_pdev;
+
+ pci_set_master(pdev);
+
+ netdev = alloc_etherdev(sizeof(struct netxen_adapter));
+ if(!netdev) {
+ printk(KERN_ERR"%s: Failed to allocate memory for the "
+ "device block.Check system memory resource"
+ " usage.\n", netxen_nic_driver_name);
+ goto err_out_free_res;
+ }
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ adapter = netdev_priv(netdev);
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->ahw.pci_func = pci_func_id;
+
+ revision_id = pdev->revision;
+ adapter->ahw.revision_id = revision_id;
+
+ err = nx_set_dma_mask(adapter, revision_id);
+ if (err)
+ goto err_out_free_netdev;
+
+ rwlock_init(&adapter->adapter_lock);
+ spin_lock_init(&adapter->tx_clean_lock);
+
+ err = netxen_setup_pci_map(adapter);
+ if (err)
+ goto err_out_free_netdev;
/* This will be reset for mezz cards */
adapter->portnum = pci_func_id;
- adapter->status &= ~NETXEN_NETDEV_STATUS;
adapter->rx_csum = 1;
adapter->mc_enabled = 0;
if (NX_IS_REVISION_P3(revision_id))
@@ -734,23 +978,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
- /* ScatterGather support */
- netdev->features = NETIF_F_SG;
- netdev->features |= NETIF_F_IP_CSUM;
- netdev->features |= NETIF_F_TSO;
+ netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+ netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
if (NX_IS_REVISION_P3(revision_id)) {
- netdev->features |= NETIF_F_IPV6_CSUM;
- netdev->features |= NETIF_F_TSO6;
+ netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+ netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
}
- if (adapter->pci_using_dac)
+ if (adapter->pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
-
- /*
- * Set the CRB window to invalid. If any register in window 0 is
- * accessed it should set the window to 0 and then reset it to 1.
- */
- adapter->curr_window = 255;
+ netdev->vlan_features |= NETIF_F_HIGHDMA;
+ }
if (netxen_nic_get_board_info(adapter) != 0) {
printk("%s: Error getting board config info.\n",
@@ -762,7 +1001,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netxen_initialize_adapter_ops(adapter);
/* Mezz cards have PCI function 0,2,3 enabled */
- switch (adapter->ahw.boardcfg.board_type) {
+ switch (adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
if (pci_func_id >= 2)
@@ -772,129 +1011,32 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- /*
- * This call will setup various max rx/tx counts.
- * It must be done before any buffer/ring allocations.
- */
- netxen_check_options(adapter);
-
- first_driver = 0;
- if (NX_IS_REVISION_P3(revision_id)) {
- if (adapter->ahw.pci_func == 0)
- first_driver = 1;
- } else {
- if (adapter->portnum == 0)
- first_driver = 1;
- }
-
- if (first_driver) {
- first_boot = adapter->pci_read_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc));
-
- err = netxen_check_hw_init(adapter, first_boot);
- if (err) {
- printk(KERN_ERR "%s: error in init HW init sequence\n",
- netxen_nic_driver_name);
- goto err_out_iounmap;
- }
-
- if (NX_IS_REVISION_P3(revision_id))
- netxen_set_port_mode(adapter);
-
- if (first_boot != 0x55555555) {
- adapter->pci_write_normalize(adapter,
- CRB_CMDPEG_STATE, 0);
- netxen_pinit_from_rom(adapter, 0);
- msleep(1);
- }
- netxen_load_firmware(adapter);
-
- if (NX_IS_REVISION_P3(revision_id))
- netxen_pcie_strap_init(adapter);
-
- if (NX_IS_REVISION_P2(revision_id)) {
-
- /* Initialize multicast addr pool owners */
- val = 0x7654;
- if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
- val |= 0x0f000000;
- netxen_crb_writelit_adapter(adapter,
- NETXEN_MAC_ADDR_CNTL_REG, val);
-
- }
-
- err = netxen_initialize_adapter_offload(adapter);
- if (err)
- goto err_out_iounmap;
-
- /*
- * Tell the hardware our version number.
- */
- i = (_NETXEN_NIC_LINUX_MAJOR << 16)
- | ((_NETXEN_NIC_LINUX_MINOR << 8))
- | (_NETXEN_NIC_LINUX_SUBVERSION);
- adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i);
-
- /* Handshake with the card before we register the devices. */
- err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
- if (err)
- goto err_out_free_offload;
-
- } /* first_driver */
+ err = netxen_start_firmware(adapter);
+ if (err)
+ goto err_out_iounmap;
- netxen_nic_flash_print(adapter);
+ nx_update_dma_mask(adapter);
- if (NX_IS_REVISION_P3(revision_id)) {
- adapter->hw_read_wx(adapter,
- NETXEN_MIU_MN_CONTROL, &val, 4);
- adapter->ahw.cut_through = (val & 0x4) ? 1 : 0;
- dev_info(&pdev->dev, "firmware running in %s mode\n",
- adapter->ahw.cut_through ? "cut through" : "legacy");
- }
+ netxen_nic_get_firmware_info(adapter);
/*
* See if the firmware gave us a virtual-physical port mapping.
*/
adapter->physical_port = adapter->portnum;
- i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum));
- if (i != 0x55555555)
- adapter->physical_port = i;
-
- adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
-
- netxen_set_msix_bit(pdev, 0);
-
- if (NX_IS_REVISION_P3(revision_id)) {
- if ((mem_len != NETXEN_PCI_128MB_SIZE) &&
- mem_len != NETXEN_PCI_2MB_SIZE)
- adapter->msix_supported = 0;
+ if (adapter->fw_major < 4) {
+ i = adapter->pci_read_normalize(adapter,
+ CRB_V2P(adapter->portnum));
+ if (i != 0x55555555)
+ adapter->physical_port = i;
}
- 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_check_options(adapter);
- adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
- netxen_set_msix_bit(pdev, 1);
- dev_info(&pdev->dev, "using msi-x interrupts\n");
+ netxen_setup_intr(adapter);
- } 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");
- }
+ netdev->irq = adapter->msix_entries[0].vector;
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- netdev->irq = adapter->msix_entries[0].vector;
- else
- netdev->irq = pdev->irq;
+ netxen_napi_add(adapter, netdev);
err = netxen_receive_peg_ready(adapter);
if (err)
@@ -923,7 +1065,7 @@ request_msi:
pci_set_drvdata(pdev, adapter);
- switch (adapter->ahw.board_type) {
+ switch (adapter->ahw.port_type) {
case NETXEN_NIC_GBE:
dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
adapter->netdev->name);
@@ -937,25 +1079,12 @@ request_msi:
return 0;
err_out_disable_msi:
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- pci_disable_msix(pdev);
- if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
- pci_disable_msi(pdev);
+ netxen_teardown_intr(adapter);
-err_out_free_offload:
- if (first_driver)
- netxen_free_adapter_offload(adapter);
+ netxen_free_adapter_offload(adapter);
err_out_iounmap:
- if (db_ptr)
- iounmap(db_ptr);
-
- if (mem_ptr0)
- iounmap(mem_ptr0);
- if (mem_ptr1)
- iounmap(mem_ptr1);
- if (mem_ptr2)
- iounmap(mem_ptr2);
+ netxen_cleanup_pci_map(adapter);
err_out_free_netdev:
free_netdev(netdev);
@@ -983,9 +1112,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
- netxen_free_hw_resources(adapter);
- netxen_release_rx_buffers(adapter);
- netxen_free_sw_resources(adapter);
+ netxen_nic_detach(adapter);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_p3_free_mac_list(adapter);
@@ -994,18 +1121,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->portnum == 0)
netxen_free_adapter_offload(adapter);
- if (adapter->irq)
- free_irq(adapter->irq, adapter);
+ netxen_teardown_intr(adapter);
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- pci_disable_msix(pdev);
- if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
- pci_disable_msi(pdev);
-
- iounmap(adapter->ahw.db_base);
- iounmap(adapter->ahw.pci_base0);
- iounmap(adapter->ahw.pci_base1);
- iounmap(adapter->ahw.pci_base2);
+ netxen_cleanup_pci_map(adapter);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -1014,123 +1132,95 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
free_netdev(netdev);
}
-/*
- * Called when a network interface is made active
- * @returns 0 on success, negative value on failure
- */
-static int netxen_nic_open(struct net_device *netdev)
+static int
+netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct netxen_adapter *adapter = netdev_priv(netdev);
- int err = 0;
- int ctx, ring;
- irq_handler_t handler;
- unsigned long flags = IRQF_SAMPLE_RANDOM;
- if (adapter->driver_mismatch)
- return -EIO;
+ struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
- if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
- err = netxen_init_firmware(adapter);
- if (err != 0) {
- printk(KERN_ERR "Failed to init firmware\n");
- return -EIO;
- }
+ netif_device_detach(netdev);
- if (adapter->fw_major < 4)
- adapter->max_rds_rings = 3;
- else
- adapter->max_rds_rings = 2;
+ if (netif_running(netdev))
+ netxen_nic_down(adapter, netdev);
- err = netxen_alloc_sw_resources(adapter);
- if (err) {
- printk(KERN_ERR "%s: Error in setting sw resources\n",
- netdev->name);
- return err;
- }
+ if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
+ netxen_nic_detach(adapter);
- netxen_nic_clear_stats(adapter);
+ pci_save_state(pdev);
- err = netxen_alloc_hw_resources(adapter);
- if (err) {
- printk(KERN_ERR "%s: Error in setting hw resources\n",
- netdev->name);
- goto err_out_free_sw;
- }
+ if (netxen_nic_wol_supported(adapter)) {
+ pci_enable_wake(pdev, PCI_D3cold, 1);
+ pci_enable_wake(pdev, PCI_D3hot, 1);
+ }
- 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;
- goto err_out_free_hw;
- }
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
- 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];
+ return 0;
+}
- netxen_nic_update_cmd_producer(adapter, 0);
- netxen_nic_update_cmd_consumer(adapter, 0);
- }
+static int
+netxen_nic_resume(struct pci_dev *pdev)
+{
+ struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
+ int err;
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- for (ring = 0; ring < adapter->max_rds_rings; ring++)
- netxen_post_rx_buffers(adapter, ctx, ring);
- }
- if (NETXEN_IS_MSI_FAMILY(adapter))
- handler = netxen_msi_intr;
- else {
- flags |= IRQF_SHARED;
- handler = netxen_intr;
- }
- adapter->irq = netdev->irq;
- err = request_irq(adapter->irq, handler,
- flags, netdev->name, adapter);
- if (err) {
- printk(KERN_ERR "request_irq failed with: %d\n", err);
- goto err_out_free_rxbuf;
- }
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
- adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
- }
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
- /* Done here again so that even if phantom sw overwrote it,
- * we set it */
- err = adapter->init_port(adapter, adapter->physical_port);
+ adapter->curr_window = 255;
+
+ err = netxen_start_firmware(adapter);
if (err) {
- printk(KERN_ERR "%s: Failed to initialize port %d\n",
- netxen_nic_driver_name, adapter->portnum);
- goto err_out_free_irq;
+ dev_err(&pdev->dev, "failed to start firmware\n");
+ return err;
}
- adapter->macaddr_set(adapter, netdev->dev_addr);
- netxen_nic_set_link_parameters(adapter);
+ if (netif_running(netdev)) {
+ err = netxen_nic_attach(adapter);
+ if (err)
+ return err;
- netxen_set_multicast_list(netdev);
- if (adapter->set_mtu)
- adapter->set_mtu(adapter, netdev->mtu);
+ err = netxen_nic_up(adapter, netdev);
+ if (err)
+ return err;
- adapter->ahw.linkup = 0;
- mod_timer(&adapter->watchdog_timer, jiffies);
+ netif_device_attach(netdev);
+ }
+
+ return 0;
+}
+
+static int netxen_nic_open(struct net_device *netdev)
+{
+ struct netxen_adapter *adapter = netdev_priv(netdev);
+ int err = 0;
+
+ if (adapter->driver_mismatch)
+ return -EIO;
+
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
+ err = netxen_nic_attach(adapter);
+ if (err)
+ return err;
+ }
- napi_enable(&adapter->napi);
- netxen_nic_enable_int(adapter);
+ err = netxen_nic_up(adapter, netdev);
+ if (err)
+ goto err_out;
netif_start_queue(netdev);
return 0;
-err_out_free_irq:
- free_irq(adapter->irq, adapter);
-err_out_free_rxbuf:
- netxen_release_rx_buffers(adapter);
-err_out_free_hw:
- netxen_free_hw_resources(adapter);
-err_out_free_sw:
- netxen_free_sw_resources(adapter);
+err_out:
+ netxen_nic_detach(adapter);
return err;
}
@@ -1141,20 +1231,7 @@ static int netxen_nic_close(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- napi_disable(&adapter->napi);
-
- if (adapter->stop_port)
- adapter->stop_port(adapter);
-
- netxen_nic_disable_int(adapter);
-
- netxen_release_tx_buffers(adapter);
-
- FLUSH_SCHEDULED_WORK();
- del_timer_sync(&adapter->watchdog_timer);
-
+ netxen_nic_down(adapter, netdev);
return 0;
}
@@ -1163,6 +1240,14 @@ static bool netxen_tso_check(struct net_device *netdev,
{
bool tso = false;
u8 opcode = TX_ETHER_PKT;
+ __be16 protocol = skb->protocol;
+ u16 flags = 0;
+
+ if (protocol == cpu_to_be16(ETH_P_8021Q)) {
+ struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data;
+ protocol = vh->h_vlan_encapsulated_proto;
+ flags = FLAGS_VLAN_TAGGED;
+ }
if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
skb_shinfo(skb)->gso_size > 0) {
@@ -1171,21 +1256,21 @@ static bool netxen_tso_check(struct net_device *netdev,
desc->total_hdr_length =
skb_transport_offset(skb) + tcp_hdrlen(skb);
- opcode = (skb->protocol == htons(ETH_P_IPV6)) ?
+ opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
TX_TCP_LSO6 : TX_TCP_LSO;
tso = true;
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
u8 l4proto;
- if (skb->protocol == htons(ETH_P_IP)) {
+ if (protocol == cpu_to_be16(ETH_P_IP)) {
l4proto = ip_hdr(skb)->protocol;
if (l4proto == IPPROTO_TCP)
opcode = TX_TCP_PKT;
else if(l4proto == IPPROTO_UDP)
opcode = TX_UDP_PKT;
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ } else if (protocol == cpu_to_be16(ETH_P_IPV6)) {
l4proto = ipv6_hdr(skb)->nexthdr;
if (l4proto == IPPROTO_TCP)
@@ -1196,7 +1281,7 @@ static bool netxen_tso_check(struct net_device *netdev,
}
desc->tcp_hdr_offset = skb_transport_offset(skb);
desc->ip_hdr_offset = skb_network_offset(skb);
- netxen_set_tx_flags_opcode(desc, 0, opcode);
+ netxen_set_tx_flags_opcode(desc, flags, opcode);
return tso;
}
@@ -1218,7 +1303,16 @@ netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
}
}
-static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static inline void
+netxen_clear_cmddesc(u64 *desc)
+{
+ int i;
+ for (i = 0; i < 8; i++)
+ desc[i] = 0ULL;
+}
+
+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;
@@ -1232,7 +1326,7 @@ static int 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->max_tx_desc_count;
+ u32 num_txd = adapter->num_txd;
bool is_tso = false;
frag_count = skb_shinfo(skb)->nr_frags + 1;
@@ -1251,7 +1345,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* Copy the descriptors into the hardware */
hwdesc = &hw->cmd_desc_head[producer];
- memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
+ netxen_clear_cmddesc((u64 *)hwdesc);
/* Take skb->data itself */
pbuf = &adapter->cmd_buf_arr[producer];
@@ -1270,7 +1364,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
netxen_set_tx_port(hwdesc, adapter->portnum);
- hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
+ hwdesc->buffer_length[0] = cpu_to_le16(first_seg_len);
hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
for (i = 1, k = 1; i < frag_count; i++, k++) {
@@ -1283,7 +1377,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
k = 0;
producer = get_next_index(producer, num_txd);
hwdesc = &hw->cmd_desc_head[producer];
- memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
+ netxen_clear_cmddesc((u64 *)hwdesc);
pbuf = &adapter->cmd_buf_arr[producer];
pbuf->skb = NULL;
}
@@ -1303,21 +1397,18 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
buffrag->dma = temp_dma;
buffrag->length = temp_len;
+ hwdesc->buffer_length[k] = cpu_to_le16(temp_len);
switch (k) {
case 0:
- hwdesc->buffer1_length = cpu_to_le16(temp_len);
hwdesc->addr_buffer1 = cpu_to_le64(temp_dma);
break;
case 1:
- hwdesc->buffer2_length = cpu_to_le16(temp_len);
hwdesc->addr_buffer2 = cpu_to_le64(temp_dma);
break;
case 2:
- hwdesc->buffer3_length = cpu_to_le16(temp_len);
hwdesc->addr_buffer3 = cpu_to_le64(temp_dma);
break;
case 3:
- hwdesc->buffer4_length = cpu_to_le16(temp_len);
hwdesc->addr_buffer4 = cpu_to_le64(temp_dma);
break;
}
@@ -1432,7 +1523,7 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
linkup = (val == XG_LINK_UP_P3);
} else {
val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
- if (adapter->ahw.board_type == NETXEN_NIC_GBE)
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE)
linkup = (val >> port) & 1;
else {
val = (val >> port*8) & 0xff;
@@ -1499,13 +1590,11 @@ static void netxen_tx_timeout_task(struct work_struct *work)
printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
netxen_nic_driver_name, adapter->netdev->name);
- netxen_nic_disable_int(adapter);
- napi_disable(&adapter->napi);
+ netxen_napi_disable(adapter);
adapter->netdev->trans_start = jiffies;
- napi_enable(&adapter->napi);
- netxen_nic_enable_int(adapter);
+ netxen_napi_enable(adapter);
netif_wake_queue(adapter->netdev);
}
@@ -1543,7 +1632,8 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
static irqreturn_t netxen_intr(int irq, void *data)
{
- struct netxen_adapter *adapter = data;
+ struct nx_host_sds_ring *sds_ring = data;
+ struct netxen_adapter *adapter = sds_ring->adapter;
u32 status = 0;
status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1574,7 +1664,7 @@ static irqreturn_t netxen_intr(int irq, void *data)
/* clear interrupt */
if (adapter->fw_major < 4)
- netxen_nic_disable_int(adapter);
+ netxen_nic_disable_int(sds_ring);
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_status_reg,
@@ -1583,53 +1673,49 @@ static irqreturn_t netxen_intr(int irq, void *data)
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
- napi_schedule(&adapter->napi);
+ napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
}
static irqreturn_t netxen_msi_intr(int irq, void *data)
{
- struct netxen_adapter *adapter = data;
+ struct nx_host_sds_ring *sds_ring = data;
+ struct netxen_adapter *adapter = sds_ring->adapter;
/* clear interrupt */
adapter->pci_write_immediate(adapter,
msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
- napi_schedule(&adapter->napi);
+ napi_schedule(&sds_ring->napi);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t netxen_msix_intr(int irq, void *data)
+{
+ struct nx_host_sds_ring *sds_ring = data;
+
+ napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
}
static int netxen_nic_poll(struct napi_struct *napi, int budget)
{
- struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi);
+ struct nx_host_sds_ring *sds_ring =
+ container_of(napi, struct nx_host_sds_ring, napi);
+
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
int tx_complete;
- int ctx;
int work_done;
tx_complete = netxen_process_cmd_ring(adapter);
- work_done = 0;
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- /*
- * Fairness issue. This will give undue weight to the
- * receive context 0.
- */
-
- /*
- * To avoid starvation, we give each of our receivers,
- * a fraction of the quota. Sometimes, it might happen that we
- * have enough quota to process every packet, but since all the
- * packets are on one context, it gets only half of the quota,
- * and ends up not processing it.
- */
- work_done += netxen_process_rcv_ring(adapter, ctx,
- budget / MAX_RCV_CTX);
- }
+ work_done = netxen_process_rcv_ring(sds_ring, budget);
if ((work_done < budget) && tx_complete) {
- netif_rx_complete(&adapter->napi);
- netxen_nic_enable_int(adapter);
+ napi_complete(&sds_ring->napi);
+ netxen_nic_enable_int(sds_ring);
}
return work_done;
@@ -1649,13 +1735,17 @@ static struct pci_driver netxen_driver = {
.name = netxen_nic_driver_name,
.id_table = netxen_pci_tbl,
.probe = netxen_nic_probe,
- .remove = __devexit_p(netxen_nic_remove)
+ .remove = __devexit_p(netxen_nic_remove),
+ .suspend = netxen_nic_suspend,
+ .resume = netxen_nic_resume
};
/* Driver Registration on NetXen card */
static int __init netxen_init_module(void)
{
+ printk(KERN_INFO "%s\n", netxen_nic_driver_string);
+
if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
return -ENOMEM;
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index c3b9c83b32f..d85203203d4 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Provides access to the Network Interface Unit h/w block.
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -299,14 +296,6 @@ int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter)
return result;
}
-#if 0
-int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter)
-{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1);
- return 0;
-}
-#endif /* 0 */
-
static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
{
int result = 0;
@@ -467,104 +456,6 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
return 0;
}
-#if 0
-/*
- * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
- * @param enable 0 means don't enable the port
- * 1 means enable (or re-enable) the port
- */
-int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
- int port, long enable)
-{
- int result = 0;
- __u32 int_src;
-
- printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d"
- " (device enable = %d)\n", (int)port, (int)enable);
-
- /*
- * The read of the PHY INT status will clear the pending
- * interrupt status
- */
- if (netxen_niu_gbe_phy_read(adapter,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
- &int_src) != 0)
- result = -EINVAL;
- else {
- printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src);
- if (netxen_get_phy_int_jabber(int_src))
- printk(KERN_INFO PFX "jabber Interrupt ");
- if (netxen_get_phy_int_polarity_changed(int_src))
- printk(KERN_INFO PFX "polarity changed ");
- if (netxen_get_phy_int_energy_detect(int_src))
- printk(KERN_INFO PFX "energy detect \n");
- if (netxen_get_phy_int_downshift(int_src))
- printk(KERN_INFO PFX "downshift \n");
- if (netxen_get_phy_int_mdi_xover_changed(int_src))
- printk(KERN_INFO PFX "mdi_xover_changed ");
- if (netxen_get_phy_int_fifo_over_underflow(int_src))
- printk(KERN_INFO PFX "fifo_over_underflow ");
- if (netxen_get_phy_int_false_carrier(int_src))
- printk(KERN_INFO PFX "false_carrier ");
- if (netxen_get_phy_int_symbol_error(int_src))
- printk(KERN_INFO PFX "symbol_error ");
- if (netxen_get_phy_int_autoneg_completed(int_src))
- printk(KERN_INFO PFX "autoneg_completed ");
- if (netxen_get_phy_int_page_received(int_src))
- printk(KERN_INFO PFX "page_received ");
- if (netxen_get_phy_int_duplex_changed(int_src))
- printk(KERN_INFO PFX "duplex_changed ");
- if (netxen_get_phy_int_autoneg_error(int_src))
- printk(KERN_INFO PFX "autoneg_error ");
- if ((netxen_get_phy_int_speed_changed(int_src))
- || (netxen_get_phy_int_link_status_changed(int_src))) {
- __u32 status;
-
- printk(KERN_INFO PFX
- "speed_changed or link status changed");
- if (netxen_niu_gbe_phy_read
- (adapter,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- &status) == 0) {
- if (netxen_get_phy_speed(status) == 2) {
- printk
- (KERN_INFO PFX "Link speed changed"
- " to 1000 Mbps\n");
- netxen_niu_gbe_set_gmii_mode(adapter,
- port,
- enable);
- } else if (netxen_get_phy_speed(status) == 1) {
- printk
- (KERN_INFO PFX "Link speed changed"
- " to 100 Mbps\n");
- netxen_niu_gbe_set_mii_mode(adapter,
- port,
- enable);
- } else if (netxen_get_phy_speed(status) == 0) {
- printk
- (KERN_INFO PFX "Link speed changed"
- " to 10 Mbps\n");
- netxen_niu_gbe_set_mii_mode(adapter,
- port,
- enable);
- } else {
- printk(KERN_ERR PFX "ERROR reading "
- "PHY status. Invalid speed.\n");
- result = -1;
- }
- } else {
- printk(KERN_ERR PFX
- "ERROR reading PHY status.\n");
- result = -1;
- }
-
- }
- printk(KERN_INFO "\n");
- }
- return result;
-}
-#endif /* 0 */
-
/*
* Return the current station MAC address.
* Note that the passed-in value must already be in network byte order.
@@ -641,86 +532,6 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
return 0;
}
-#if 0
-/* Enable a GbE interface */
-int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
- int port, netxen_niu_gbe_ifmode_t mode)
-{
- __u32 mac_cfg0;
- __u32 mac_cfg1;
- __u32 mii_cfg;
-
- if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
- 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))
- return -EIO;
- mac_cfg0 = 0;
- netxen_gb_enable_tx(mac_cfg0);
- netxen_gb_enable_rx(mac_cfg0);
- netxen_gb_unset_rx_flowctl(mac_cfg0);
- netxen_gb_tx_reset_pb(mac_cfg0);
- netxen_gb_rx_reset_pb(mac_cfg0);
- netxen_gb_tx_reset_mac(mac_cfg0);
- netxen_gb_rx_reset_mac(mac_cfg0);
-
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &mac_cfg0, 4))
- return -EIO;
- mac_cfg1 = 0;
- netxen_gb_set_preamblelen(mac_cfg1, 0xf);
- netxen_gb_set_duplex(mac_cfg1);
- netxen_gb_set_crc_enable(mac_cfg1);
- netxen_gb_set_padshort(mac_cfg1);
- netxen_gb_set_checklength(mac_cfg1);
- netxen_gb_set_hugeframes(mac_cfg1);
-
- if (mode == NETXEN_NIU_10_100_MB) {
- netxen_gb_set_intfmode(mac_cfg1, 1);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_1(port),
- &mac_cfg1, 4))
- return -EIO;
-
- /* set mii mode */
- 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);
-
- } else if (mode == NETXEN_NIU_1000_MB) {
- netxen_gb_set_intfmode(mac_cfg1, 2);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_1(port),
- &mac_cfg1, 4))
- return -EIO;
- /* set gmii mode */
- 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);
- }
- mii_cfg = 0;
- netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
- &mii_cfg, 4))
- return -EIO;
- mac_cfg0 = 0;
- netxen_gb_enable_tx(mac_cfg0);
- netxen_gb_enable_rx(mac_cfg0);
- netxen_gb_unset_rx_flowctl(mac_cfg0);
- netxen_gb_unset_tx_flowctl(mac_cfg0);
-
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &mac_cfg0, 4))
- return -EIO;
- return 0;
-}
-#endif /* 0 */
-
/* Disable a GbE interface */
int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
{
@@ -869,39 +680,6 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
return 0;
}
-#if 0
-/*
- * Return the current station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t * addr)
-{
- int phy = adapter->physical_port;
- u32 stationhigh;
- u32 stationlow;
- u8 val[8];
-
- if (addr == NULL)
- return -EINVAL;
- if (phy != 0)
- return -EINVAL;
-
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
- &stationhigh, 4))
- return -EIO;
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
- &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;
-}
-#endif /* 0 */
-
int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
u32 mode)
{
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index b293adcc95a..50183335e43 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
*/
#ifndef __NIC_PHAN_REG_H_
@@ -90,6 +91,7 @@
#define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0)
#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) /* Multiport Mode */
#define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8)
+#define CRB_DMA_SHIFT NETXEN_NIC_REG(0xcc)
#define CRB_INT_VECTOR NETXEN_NIC_REG(0xd4)
#define CRB_CTX_RESET NETXEN_NIC_REG(0xd8)
#define CRB_HOST_STS_PROD NETXEN_NIC_REG(0xdc)
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 254057275e0..df5f869e8d8 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -481,8 +481,9 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
else {
if(dev->dma == 0) {
/* 'stuck test' from lance.c */
- long dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
- (inb(DMA2_STAT_REG) & 0xf0);
+ unsigned long dma_channels =
+ ((inb(DMA1_STAT_REG) >> 4) & 0x0f)
+ | (inb(DMA2_STAT_REG) & 0xf0);
for(i=1;i<5;i++) {
int dma = dmatab[i];
if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510"))
@@ -897,7 +898,6 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
if(csr0 & CSR0_ERR)
{
- struct priv *p = dev->ml_priv;
if(debuglevel > 1)
printk(KERN_ERR "%s: general error: %04x.\n",dev->name,csr0);
if(csr0 & CSR0_BABL)
@@ -922,8 +922,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
int j;
for(j=0;j<RMDNUM;j++)
{
- struct priv *p = dev->ml_priv;
- int i,k,num1,num2;
+ int i, num2;
for(i=RMDNUM-1;i>0;i--) {
num2 = (p->rmdnum + i) & (RMDNUM-1);
if(!(p->rmdhead[num2].u.s.status & RCV_OWN))
@@ -931,6 +930,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
}
if(i) {
+ int k, num1;
for(k=0;k<RMDNUM;k++) {
num1 = (p->rmdnum + k) & (RMDNUM-1);
if(!(p->rmdhead[num1].u.s.status & RCV_OWN))
@@ -942,7 +942,6 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
if(debuglevel > 0)
{
char buf[256],*buf1;
- int k;
buf1 = buf;
for(k=0;k<RMDNUM;k++) {
sprintf(buf1,"%02x ",(p->rmdhead[k].u.s.status)); /* & RCV_OWN) ); */
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 0c0b752315c..50c11126a3d 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -1115,6 +1115,130 @@ static int link_status_10g_serdes(struct niu *np, int *link_up_p)
return 0;
}
+static int link_status_mii(struct niu *np, int *link_up_p)
+{
+ struct niu_link_config *lp = &np->link_config;
+ int err;
+ int bmsr, advert, ctrl1000, stat1000, lpa, bmcr, estatus;
+ int supported, advertising, active_speed, active_duplex;
+
+ err = mii_read(np, np->phy_addr, MII_BMCR);
+ if (unlikely(err < 0))
+ return err;
+ bmcr = err;
+
+ err = mii_read(np, np->phy_addr, MII_BMSR);
+ if (unlikely(err < 0))
+ return err;
+ bmsr = err;
+
+ err = mii_read(np, np->phy_addr, MII_ADVERTISE);
+ if (unlikely(err < 0))
+ return err;
+ advert = err;
+
+ err = mii_read(np, np->phy_addr, MII_LPA);
+ if (unlikely(err < 0))
+ return err;
+ lpa = err;
+
+ if (likely(bmsr & BMSR_ESTATEN)) {
+ err = mii_read(np, np->phy_addr, MII_ESTATUS);
+ if (unlikely(err < 0))
+ return err;
+ estatus = err;
+
+ err = mii_read(np, np->phy_addr, MII_CTRL1000);
+ if (unlikely(err < 0))
+ return err;
+ ctrl1000 = err;
+
+ err = mii_read(np, np->phy_addr, MII_STAT1000);
+ if (unlikely(err < 0))
+ return err;
+ stat1000 = err;
+ } else
+ estatus = ctrl1000 = stat1000 = 0;
+
+ supported = 0;
+ if (bmsr & BMSR_ANEGCAPABLE)
+ supported |= SUPPORTED_Autoneg;
+ if (bmsr & BMSR_10HALF)
+ supported |= SUPPORTED_10baseT_Half;
+ if (bmsr & BMSR_10FULL)
+ supported |= SUPPORTED_10baseT_Full;
+ if (bmsr & BMSR_100HALF)
+ supported |= SUPPORTED_100baseT_Half;
+ if (bmsr & BMSR_100FULL)
+ supported |= SUPPORTED_100baseT_Full;
+ if (estatus & ESTATUS_1000_THALF)
+ supported |= SUPPORTED_1000baseT_Half;
+ if (estatus & ESTATUS_1000_TFULL)
+ supported |= SUPPORTED_1000baseT_Full;
+ lp->supported = supported;
+
+ advertising = 0;
+ if (advert & ADVERTISE_10HALF)
+ advertising |= ADVERTISED_10baseT_Half;
+ if (advert & ADVERTISE_10FULL)
+ advertising |= ADVERTISED_10baseT_Full;
+ if (advert & ADVERTISE_100HALF)
+ advertising |= ADVERTISED_100baseT_Half;
+ if (advert & ADVERTISE_100FULL)
+ advertising |= ADVERTISED_100baseT_Full;
+ if (ctrl1000 & ADVERTISE_1000HALF)
+ advertising |= ADVERTISED_1000baseT_Half;
+ if (ctrl1000 & ADVERTISE_1000FULL)
+ advertising |= ADVERTISED_1000baseT_Full;
+
+ if (bmcr & BMCR_ANENABLE) {
+ int neg, neg1000;
+
+ lp->active_autoneg = 1;
+ advertising |= ADVERTISED_Autoneg;
+
+ neg = advert & lpa;
+ neg1000 = (ctrl1000 << 2) & stat1000;
+
+ if (neg1000 & (LPA_1000FULL | LPA_1000HALF))
+ active_speed = SPEED_1000;
+ else if (neg & LPA_100)
+ active_speed = SPEED_100;
+ else if (neg & (LPA_10HALF | LPA_10FULL))
+ active_speed = SPEED_10;
+ else
+ active_speed = SPEED_INVALID;
+
+ if ((neg1000 & LPA_1000FULL) || (neg & LPA_DUPLEX))
+ active_duplex = DUPLEX_FULL;
+ else if (active_speed != SPEED_INVALID)
+ active_duplex = DUPLEX_HALF;
+ else
+ active_duplex = DUPLEX_INVALID;
+ } else {
+ lp->active_autoneg = 0;
+
+ if ((bmcr & BMCR_SPEED1000) && !(bmcr & BMCR_SPEED100))
+ active_speed = SPEED_1000;
+ else if (bmcr & BMCR_SPEED100)
+ active_speed = SPEED_100;
+ else
+ active_speed = SPEED_10;
+
+ if (bmcr & BMCR_FULLDPLX)
+ active_duplex = DUPLEX_FULL;
+ else
+ active_duplex = DUPLEX_HALF;
+ }
+
+ lp->active_advertising = advertising;
+ lp->active_speed = active_speed;
+ lp->active_duplex = active_duplex;
+ *link_up_p = !!(bmsr & BMSR_LSTATUS);
+
+ return 0;
+}
+
static int link_status_1g_rgmii(struct niu *np, int *link_up_p)
{
struct niu_link_config *lp = &np->link_config;
@@ -1171,6 +1295,22 @@ out:
return err;
}
+static int link_status_1g(struct niu *np, int *link_up_p)
+{
+ struct niu_link_config *lp = &np->link_config;
+ unsigned long flags;
+ int err;
+
+ spin_lock_irqsave(&np->lock, flags);
+
+ err = link_status_mii(np, link_up_p);
+ lp->supported |= SUPPORTED_TP;
+ lp->active_advertising |= ADVERTISED_TP;
+
+ spin_unlock_irqrestore(&np->lock, flags);
+ return err;
+}
+
static int bcm8704_reset(struct niu *np)
{
int err, limit;
@@ -1676,39 +1816,88 @@ static int mii_init_common(struct niu *np)
return err;
}
- /* XXX configurable XXX */
- /* XXX for now don't advertise half-duplex or asym pause... XXX */
- adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
- if (bmsr & BMSR_10FULL)
- adv |= ADVERTISE_10FULL;
- if (bmsr & BMSR_100FULL)
- adv |= ADVERTISE_100FULL;
- err = mii_write(np, np->phy_addr, MII_ADVERTISE, adv);
- if (err)
- return err;
-
- if (bmsr & BMSR_ESTATEN) {
- u16 ctrl1000 = 0;
-
- if (estat & ESTATUS_1000_TFULL)
- ctrl1000 |= ADVERTISE_1000FULL;
- err = mii_write(np, np->phy_addr, MII_CTRL1000, ctrl1000);
+ if (lp->autoneg) {
+ u16 ctrl1000;
+
+ adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
+ if ((bmsr & BMSR_10HALF) &&
+ (lp->advertising & ADVERTISED_10baseT_Half))
+ adv |= ADVERTISE_10HALF;
+ if ((bmsr & BMSR_10FULL) &&
+ (lp->advertising & ADVERTISED_10baseT_Full))
+ adv |= ADVERTISE_10FULL;
+ if ((bmsr & BMSR_100HALF) &&
+ (lp->advertising & ADVERTISED_100baseT_Half))
+ adv |= ADVERTISE_100HALF;
+ if ((bmsr & BMSR_100FULL) &&
+ (lp->advertising & ADVERTISED_100baseT_Full))
+ adv |= ADVERTISE_100FULL;
+ err = mii_write(np, np->phy_addr, MII_ADVERTISE, adv);
if (err)
return err;
+
+ if (likely(bmsr & BMSR_ESTATEN)) {
+ ctrl1000 = 0;
+ if ((estat & ESTATUS_1000_THALF) &&
+ (lp->advertising & ADVERTISED_1000baseT_Half))
+ ctrl1000 |= ADVERTISE_1000HALF;
+ if ((estat & ESTATUS_1000_TFULL) &&
+ (lp->advertising & ADVERTISED_1000baseT_Full))
+ ctrl1000 |= ADVERTISE_1000FULL;
+ err = mii_write(np, np->phy_addr,
+ MII_CTRL1000, ctrl1000);
+ if (err)
+ return err;
+ }
+
+ bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
+ } else {
+ /* !lp->autoneg */
+ int fulldpx;
+
+ if (lp->duplex == DUPLEX_FULL) {
+ bmcr |= BMCR_FULLDPLX;
+ fulldpx = 1;
+ } else if (lp->duplex == DUPLEX_HALF)
+ fulldpx = 0;
+ else
+ return -EINVAL;
+
+ if (lp->speed == SPEED_1000) {
+ /* if X-full requested while not supported, or
+ X-half requested while not supported... */
+ if ((fulldpx && !(estat & ESTATUS_1000_TFULL)) ||
+ (!fulldpx && !(estat & ESTATUS_1000_THALF)))
+ return -EINVAL;
+ bmcr |= BMCR_SPEED1000;
+ } else if (lp->speed == SPEED_100) {
+ if ((fulldpx && !(bmsr & BMSR_100FULL)) ||
+ (!fulldpx && !(bmsr & BMSR_100HALF)))
+ return -EINVAL;
+ bmcr |= BMCR_SPEED100;
+ } else if (lp->speed == SPEED_10) {
+ if ((fulldpx && !(bmsr & BMSR_10FULL)) ||
+ (!fulldpx && !(bmsr & BMSR_10HALF)))
+ return -EINVAL;
+ } else
+ return -EINVAL;
}
- bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
err = mii_write(np, np->phy_addr, MII_BMCR, bmcr);
if (err)
return err;
+#if 0
err = mii_read(np, np->phy_addr, MII_BMCR);
if (err < 0)
return err;
+ bmcr = err;
+
err = mii_read(np, np->phy_addr, MII_BMSR);
if (err < 0)
return err;
-#if 0
+ bmsr = err;
+
pr_info(PFX "Port %u after MII init bmcr[%04x] bmsr[%04x]\n",
np->port, bmcr, bmsr);
#endif
@@ -2054,87 +2243,6 @@ static int link_status_10g_hotplug(struct niu *np, int *link_up_p)
return err;
}
-static int link_status_1g(struct niu *np, int *link_up_p)
-{
- struct niu_link_config *lp = &np->link_config;
- u16 current_speed, bmsr;
- unsigned long flags;
- u8 current_duplex;
- int err, link_up;
-
- link_up = 0;
- current_speed = SPEED_INVALID;
- current_duplex = DUPLEX_INVALID;
-
- spin_lock_irqsave(&np->lock, flags);
-
- err = -EINVAL;
- if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
- goto out;
-
- err = mii_read(np, np->phy_addr, MII_BMSR);
- if (err < 0)
- goto out;
-
- bmsr = err;
- if (bmsr & BMSR_LSTATUS) {
- u16 adv, lpa, common, estat;
-
- err = mii_read(np, np->phy_addr, MII_ADVERTISE);
- if (err < 0)
- goto out;
- adv = err;
-
- err = mii_read(np, np->phy_addr, MII_LPA);
- if (err < 0)
- goto out;
- lpa = err;
-
- common = adv & lpa;
-
- err = mii_read(np, np->phy_addr, MII_ESTATUS);
- if (err < 0)
- goto out;
- estat = err;
-
- link_up = 1;
- if (estat & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
- current_speed = SPEED_1000;
- if (estat & ESTATUS_1000_TFULL)
- current_duplex = DUPLEX_FULL;
- else
- current_duplex = DUPLEX_HALF;
- } else {
- if (common & ADVERTISE_100BASE4) {
- current_speed = SPEED_100;
- current_duplex = DUPLEX_HALF;
- } else if (common & ADVERTISE_100FULL) {
- current_speed = SPEED_100;
- current_duplex = DUPLEX_FULL;
- } else if (common & ADVERTISE_100HALF) {
- current_speed = SPEED_100;
- current_duplex = DUPLEX_HALF;
- } else if (common & ADVERTISE_10FULL) {
- current_speed = SPEED_10;
- current_duplex = DUPLEX_FULL;
- } else if (common & ADVERTISE_10HALF) {
- current_speed = SPEED_10;
- current_duplex = DUPLEX_HALF;
- } else
- link_up = 0;
- }
- }
- lp->active_speed = current_speed;
- lp->active_duplex = current_duplex;
- err = 0;
-
-out:
- spin_unlock_irqrestore(&np->lock, flags);
-
- *link_up_p = link_up;
- return err;
-}
-
static int niu_link_status(struct niu *np, int *link_up_p)
{
const struct niu_phy_ops *ops = np->phy_ops;
@@ -2284,7 +2392,6 @@ static int serdes_init_10g_serdes(struct niu *np)
struct niu_link_config *lp = &np->link_config;
unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i;
u64 ctrl_val, test_cfg_val, sig, mask, val;
- int err;
u64 reset_val;
switch (np->port) {
@@ -2337,6 +2444,7 @@ static int serdes_init_10g_serdes(struct niu *np)
/* Initialize all 4 lanes of the SERDES. */
for (i = 0; i < 4; i++) {
u32 rxtx_ctrl, glue0;
+ int err;
err = esr_read_rxtx_ctrl(np, i, &rxtx_ctrl);
if (err)
@@ -2456,7 +2564,7 @@ static int niu_determine_phy_disposition(struct niu *np)
case NIU_FLAGS_10G:
/* 10G copper */
- tp = &phy_template_1g_copper;
+ tp = &phy_template_10g_copper;
break;
case NIU_FLAGS_FIBER:
@@ -2873,7 +2981,6 @@ static int tcam_user_ip_class_enable(struct niu *np, unsigned long class,
return 0;
}
-#if 0
static int tcam_user_ip_class_set(struct niu *np, unsigned long class,
int ipv6, u64 protocol_id,
u64 tos_mask, u64 tos_val)
@@ -2901,7 +3008,6 @@ static int tcam_user_ip_class_set(struct niu *np, unsigned long class,
return 0;
}
-#endif
static int tcam_early_init(struct niu *np)
{
@@ -3168,6 +3274,27 @@ static int niu_set_tcam_key(struct niu *np, unsigned long class_code, u64 key)
return 0;
}
+/* Entries for the ports are interleaved in the TCAM */
+static u16 tcam_get_index(struct niu *np, u16 idx)
+{
+ /* One entry reserved for IP fragment rule */
+ if (idx >= (np->clas.tcam_sz - 1))
+ idx = 0;
+ return (np->clas.tcam_top + ((idx+1) * np->parent->num_ports));
+}
+
+static u16 tcam_get_size(struct niu *np)
+{
+ /* One entry reserved for IP fragment rule */
+ return np->clas.tcam_sz - 1;
+}
+
+static u16 tcam_get_valid_entry_cnt(struct niu *np)
+{
+ /* One entry reserved for IP fragment rule */
+ return np->clas.tcam_valid_entries - 1;
+}
+
static void niu_rx_skb_append(struct sk_buff *skb, struct page *page,
u32 offset, u32 size)
{
@@ -3390,6 +3517,7 @@ static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp)
rp->rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, np->dev);
+ skb_record_rx_queue(skb, rp->rx_channel);
netif_receive_skb(skb);
return num_rcr;
@@ -3669,7 +3797,7 @@ static int niu_poll(struct napi_struct *napi, int budget)
work_done = niu_poll_core(np, lp, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
niu_ldg_rearm(np, lp, 1);
}
return work_done;
@@ -4088,12 +4216,12 @@ static void __niu_fastpath_interrupt(struct niu *np, int ldg, u64 v0)
static void niu_schedule_napi(struct niu *np, struct niu_ldg *lp,
u64 v0, u64 v1, u64 v2)
{
- if (likely(netif_rx_schedule_prep(&lp->napi))) {
+ if (likely(napi_schedule_prep(&lp->napi))) {
lp->v0 = v0;
lp->v1 = v1;
lp->v2 = v2;
__niu_fastpath_interrupt(np, lp->ldg_num, v0);
- __netif_rx_schedule(&lp->napi);
+ __napi_schedule(&lp->napi);
}
}
@@ -4890,8 +5018,7 @@ static int niu_set_ip_frag_rule(struct niu *np)
struct niu_tcam_entry *tp;
int index, err;
- /* XXX fix this allocation scheme XXX */
- index = cp->tcam_index;
+ index = cp->tcam_top;
tp = &parent->tcam[index];
/* Note that the noport bit is the same in both ipv4 and
@@ -4908,6 +5035,8 @@ static int niu_set_ip_frag_rule(struct niu *np)
err = tcam_assoc_write(np, index, tp->assoc_data);
if (err)
return err;
+ tp->valid = 1;
+ cp->tcam_valid_entries++;
return 0;
}
@@ -5211,10 +5340,10 @@ static void niu_init_xif_xmac(struct niu *np)
if (np->flags & NIU_FLAGS_10G) {
val |= XMAC_CONFIG_MODE_XGMII;
} else {
- if (lp->active_speed == SPEED_100)
- val |= XMAC_CONFIG_MODE_MII;
- else
+ if (lp->active_speed == SPEED_1000)
val |= XMAC_CONFIG_MODE_GMII;
+ else
+ val |= XMAC_CONFIG_MODE_MII;
}
nw64_mac(XMAC_CONFIG, val);
@@ -6446,11 +6575,11 @@ static u64 niu_compute_tx_flags(struct sk_buff *skb, struct ethhdr *ehdr,
ipv6 = ihl = 0;
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
ip_proto = ip_hdr(skb)->protocol;
ihl = ip_hdr(skb)->ihl;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
ip_proto = ipv6_hdr(skb)->nexthdr;
ihl = (40 >> 2);
ipv6 = 1;
@@ -6702,17 +6831,27 @@ static int niu_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
memset(cmd, 0, sizeof(*cmd));
cmd->phy_address = np->phy_addr;
cmd->supported = lp->supported;
- cmd->advertising = lp->advertising;
- cmd->autoneg = lp->autoneg;
+ cmd->advertising = lp->active_advertising;
+ cmd->autoneg = lp->active_autoneg;
cmd->speed = lp->active_speed;
cmd->duplex = lp->active_duplex;
+ cmd->port = (np->flags & NIU_FLAGS_FIBER) ? PORT_FIBRE : PORT_TP;
+ cmd->transceiver = (np->flags & NIU_FLAGS_XCVR_SERDES) ?
+ XCVR_EXTERNAL : XCVR_INTERNAL;
return 0;
}
static int niu_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- return -EINVAL;
+ struct niu *np = netdev_priv(dev);
+ struct niu_link_config *lp = &np->link_config;
+
+ lp->advertising = cmd->advertising;
+ lp->speed = cmd->speed;
+ lp->duplex = cmd->duplex;
+ lp->autoneg = cmd->autoneg;
+ return niu_init_link(np);
}
static u32 niu_get_msglevel(struct net_device *dev)
@@ -6727,6 +6866,16 @@ static void niu_set_msglevel(struct net_device *dev, u32 value)
np->msg_enable = value;
}
+static int niu_nway_reset(struct net_device *dev)
+{
+ struct niu *np = netdev_priv(dev);
+
+ if (np->link_config.autoneg)
+ return niu_init_link(np);
+
+ return 0;
+}
+
static int niu_get_eeprom_len(struct net_device *dev)
{
struct niu *np = netdev_priv(dev);
@@ -6778,6 +6927,75 @@ static int niu_get_eeprom(struct net_device *dev,
return 0;
}
+static void niu_ethflow_to_l3proto(int flow_type, u8 *pid)
+{
+ switch (flow_type) {
+ case TCP_V4_FLOW:
+ case TCP_V6_FLOW:
+ *pid = IPPROTO_TCP;
+ break;
+ case UDP_V4_FLOW:
+ case UDP_V6_FLOW:
+ *pid = IPPROTO_UDP;
+ break;
+ case SCTP_V4_FLOW:
+ case SCTP_V6_FLOW:
+ *pid = IPPROTO_SCTP;
+ break;
+ case AH_V4_FLOW:
+ case AH_V6_FLOW:
+ *pid = IPPROTO_AH;
+ break;
+ case ESP_V4_FLOW:
+ case ESP_V6_FLOW:
+ *pid = IPPROTO_ESP;
+ break;
+ default:
+ *pid = 0;
+ break;
+ }
+}
+
+static int niu_class_to_ethflow(u64 class, int *flow_type)
+{
+ switch (class) {
+ case CLASS_CODE_TCP_IPV4:
+ *flow_type = TCP_V4_FLOW;
+ break;
+ case CLASS_CODE_UDP_IPV4:
+ *flow_type = UDP_V4_FLOW;
+ break;
+ case CLASS_CODE_AH_ESP_IPV4:
+ *flow_type = AH_V4_FLOW;
+ break;
+ case CLASS_CODE_SCTP_IPV4:
+ *flow_type = SCTP_V4_FLOW;
+ break;
+ case CLASS_CODE_TCP_IPV6:
+ *flow_type = TCP_V6_FLOW;
+ break;
+ case CLASS_CODE_UDP_IPV6:
+ *flow_type = UDP_V6_FLOW;
+ break;
+ case CLASS_CODE_AH_ESP_IPV6:
+ *flow_type = AH_V6_FLOW;
+ break;
+ case CLASS_CODE_SCTP_IPV6:
+ *flow_type = SCTP_V6_FLOW;
+ break;
+ case CLASS_CODE_USER_PROG1:
+ case CLASS_CODE_USER_PROG2:
+ case CLASS_CODE_USER_PROG3:
+ case CLASS_CODE_USER_PROG4:
+ *flow_type = IP_USER_FLOW;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
static int niu_ethflow_to_class(int flow_type, u64 *class)
{
switch (flow_type) {
@@ -6787,7 +7005,8 @@ static int niu_ethflow_to_class(int flow_type, u64 *class)
case UDP_V4_FLOW:
*class = CLASS_CODE_UDP_IPV4;
break;
- case AH_ESP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
*class = CLASS_CODE_AH_ESP_IPV4;
break;
case SCTP_V4_FLOW:
@@ -6799,7 +7018,8 @@ static int niu_ethflow_to_class(int flow_type, u64 *class)
case UDP_V6_FLOW:
*class = CLASS_CODE_UDP_IPV6;
break;
- case AH_ESP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
*class = CLASS_CODE_AH_ESP_IPV6;
break;
case SCTP_V6_FLOW:
@@ -6816,8 +7036,6 @@ static u64 niu_flowkey_to_ethflow(u64 flow_key)
{
u64 ethflow = 0;
- if (flow_key & FLOW_KEY_PORT)
- ethflow |= RXH_DEV_PORT;
if (flow_key & FLOW_KEY_L2DA)
ethflow |= RXH_L2DA;
if (flow_key & FLOW_KEY_VLAN)
@@ -6841,8 +7059,6 @@ static int niu_ethflow_to_flowkey(u64 ethflow, u64 *flow_key)
{
u64 key = 0;
- if (ethflow & RXH_DEV_PORT)
- key |= FLOW_KEY_PORT;
if (ethflow & RXH_L2DA)
key |= FLOW_KEY_L2DA;
if (ethflow & RXH_VLAN)
@@ -6864,41 +7080,279 @@ static int niu_ethflow_to_flowkey(u64 ethflow, u64 *flow_key)
}
-static int niu_get_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
+static int niu_get_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc)
{
- struct niu *np = netdev_priv(dev);
u64 class;
- cmd->data = 0;
+ nfc->data = 0;
- if (!niu_ethflow_to_class(cmd->flow_type, &class))
+ if (!niu_ethflow_to_class(nfc->flow_type, &class))
return -EINVAL;
if (np->parent->tcam_key[class - CLASS_CODE_USER_PROG1] &
TCAM_KEY_DISC)
- cmd->data = RXH_DISCARD;
+ nfc->data = RXH_DISCARD;
else
-
- cmd->data = niu_flowkey_to_ethflow(np->parent->flow_key[class -
+ nfc->data = niu_flowkey_to_ethflow(np->parent->flow_key[class -
CLASS_CODE_USER_PROG1]);
return 0;
}
-static int niu_set_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
+static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp,
+ struct ethtool_rx_flow_spec *fsp)
+{
+
+ fsp->h_u.tcp_ip4_spec.ip4src = (tp->key[3] & TCAM_V4KEY3_SADDR) >>
+ TCAM_V4KEY3_SADDR_SHIFT;
+ fsp->h_u.tcp_ip4_spec.ip4dst = (tp->key[3] & TCAM_V4KEY3_DADDR) >>
+ TCAM_V4KEY3_DADDR_SHIFT;
+ fsp->m_u.tcp_ip4_spec.ip4src = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >>
+ TCAM_V4KEY3_SADDR_SHIFT;
+ fsp->m_u.tcp_ip4_spec.ip4dst = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >>
+ TCAM_V4KEY3_DADDR_SHIFT;
+
+ fsp->h_u.tcp_ip4_spec.ip4src =
+ cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4src);
+ fsp->m_u.tcp_ip4_spec.ip4src =
+ cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4src);
+ fsp->h_u.tcp_ip4_spec.ip4dst =
+ cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4dst);
+ fsp->m_u.tcp_ip4_spec.ip4dst =
+ cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4dst);
+
+ fsp->h_u.tcp_ip4_spec.tos = (tp->key[2] & TCAM_V4KEY2_TOS) >>
+ TCAM_V4KEY2_TOS_SHIFT;
+ fsp->m_u.tcp_ip4_spec.tos = (tp->key_mask[2] & TCAM_V4KEY2_TOS) >>
+ TCAM_V4KEY2_TOS_SHIFT;
+
+ switch (fsp->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ fsp->h_u.tcp_ip4_spec.psrc =
+ ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
+ fsp->h_u.tcp_ip4_spec.pdst =
+ ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+ fsp->m_u.tcp_ip4_spec.psrc =
+ ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
+ fsp->m_u.tcp_ip4_spec.pdst =
+ ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+
+ fsp->h_u.tcp_ip4_spec.psrc =
+ cpu_to_be16(fsp->h_u.tcp_ip4_spec.psrc);
+ fsp->h_u.tcp_ip4_spec.pdst =
+ cpu_to_be16(fsp->h_u.tcp_ip4_spec.pdst);
+ fsp->m_u.tcp_ip4_spec.psrc =
+ cpu_to_be16(fsp->m_u.tcp_ip4_spec.psrc);
+ fsp->m_u.tcp_ip4_spec.pdst =
+ cpu_to_be16(fsp->m_u.tcp_ip4_spec.pdst);
+ break;
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ fsp->h_u.ah_ip4_spec.spi =
+ (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+ fsp->m_u.ah_ip4_spec.spi =
+ (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+
+ fsp->h_u.ah_ip4_spec.spi =
+ cpu_to_be32(fsp->h_u.ah_ip4_spec.spi);
+ fsp->m_u.ah_ip4_spec.spi =
+ cpu_to_be32(fsp->m_u.ah_ip4_spec.spi);
+ break;
+ case IP_USER_FLOW:
+ fsp->h_u.usr_ip4_spec.l4_4_bytes =
+ (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+ fsp->m_u.usr_ip4_spec.l4_4_bytes =
+ (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+
+ fsp->h_u.usr_ip4_spec.l4_4_bytes =
+ cpu_to_be32(fsp->h_u.usr_ip4_spec.l4_4_bytes);
+ fsp->m_u.usr_ip4_spec.l4_4_bytes =
+ cpu_to_be32(fsp->m_u.usr_ip4_spec.l4_4_bytes);
+
+ fsp->h_u.usr_ip4_spec.proto =
+ (tp->key[2] & TCAM_V4KEY2_PROTO) >>
+ TCAM_V4KEY2_PROTO_SHIFT;
+ fsp->m_u.usr_ip4_spec.proto =
+ (tp->key_mask[2] & TCAM_V4KEY2_PROTO) >>
+ TCAM_V4KEY2_PROTO_SHIFT;
+
+ fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
+ break;
+ default:
+ break;
+ }
+}
+
+static int niu_get_ethtool_tcam_entry(struct niu *np,
+ struct ethtool_rxnfc *nfc)
+{
+ struct niu_parent *parent = np->parent;
+ struct niu_tcam_entry *tp;
+ struct ethtool_rx_flow_spec *fsp = &nfc->fs;
+ u16 idx;
+ u64 class;
+ int ret = 0;
+
+ idx = tcam_get_index(np, (u16)nfc->fs.location);
+
+ tp = &parent->tcam[idx];
+ if (!tp->valid) {
+ pr_info(PFX "niu%d: %s entry [%d] invalid for idx[%d]\n",
+ parent->index, np->dev->name, (u16)nfc->fs.location, idx);
+ return -EINVAL;
+ }
+
+ /* fill the flow spec entry */
+ class = (tp->key[0] & TCAM_V4KEY0_CLASS_CODE) >>
+ TCAM_V4KEY0_CLASS_CODE_SHIFT;
+ ret = niu_class_to_ethflow(class, &fsp->flow_type);
+
+ if (ret < 0) {
+ pr_info(PFX "niu%d: %s niu_class_to_ethflow failed\n",
+ parent->index, np->dev->name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (fsp->flow_type == AH_V4_FLOW || fsp->flow_type == AH_V6_FLOW) {
+ u32 proto = (tp->key[2] & TCAM_V4KEY2_PROTO) >>
+ TCAM_V4KEY2_PROTO_SHIFT;
+ if (proto == IPPROTO_ESP) {
+ if (fsp->flow_type == AH_V4_FLOW)
+ fsp->flow_type = ESP_V4_FLOW;
+ else
+ fsp->flow_type = ESP_V6_FLOW;
+ }
+ }
+
+ switch (fsp->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ niu_get_ip4fs_from_tcam_key(tp, fsp);
+ break;
+ case TCP_V6_FLOW:
+ case UDP_V6_FLOW:
+ case SCTP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ /* Not yet implemented */
+ ret = -EINVAL;
+ break;
+ case IP_USER_FLOW:
+ niu_get_ip4fs_from_tcam_key(tp, fsp);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret < 0)
+ goto out;
+
+ if (tp->assoc_data & TCAM_ASSOCDATA_DISC)
+ fsp->ring_cookie = RX_CLS_FLOW_DISC;
+ else
+ fsp->ring_cookie = (tp->assoc_data & TCAM_ASSOCDATA_OFFSET) >>
+ TCAM_ASSOCDATA_OFFSET_SHIFT;
+
+ /* put the tcam size here */
+ nfc->data = tcam_get_size(np);
+out:
+ return ret;
+}
+
+static int niu_get_ethtool_tcam_all(struct niu *np,
+ struct ethtool_rxnfc *nfc,
+ u32 *rule_locs)
+{
+ struct niu_parent *parent = np->parent;
+ struct niu_tcam_entry *tp;
+ int i, idx, cnt;
+ u16 n_entries;
+ unsigned long flags;
+
+
+ /* put the tcam size here */
+ nfc->data = tcam_get_size(np);
+
+ niu_lock_parent(np, flags);
+ n_entries = nfc->rule_cnt;
+ for (cnt = 0, i = 0; i < nfc->data; i++) {
+ idx = tcam_get_index(np, i);
+ tp = &parent->tcam[idx];
+ if (!tp->valid)
+ continue;
+ rule_locs[cnt] = i;
+ cnt++;
+ }
+ niu_unlock_parent(np, flags);
+
+ if (n_entries != cnt) {
+ /* print warning, this should not happen */
+ pr_info(PFX "niu%d: %s In niu_get_ethtool_tcam_all, "
+ "n_entries[%d] != cnt[%d]!!!\n\n",
+ np->parent->index, np->dev->name, n_entries, cnt);
+ }
+
+ return 0;
+}
+
+static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ void *rule_locs)
{
struct niu *np = netdev_priv(dev);
+ int ret = 0;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_GRXFH:
+ ret = niu_get_hash_opts(np, cmd);
+ break;
+ case ETHTOOL_GRXRINGS:
+ cmd->data = np->num_rx_rings;
+ break;
+ case ETHTOOL_GRXCLSRLCNT:
+ cmd->rule_cnt = tcam_get_valid_entry_cnt(np);
+ break;
+ case ETHTOOL_GRXCLSRULE:
+ ret = niu_get_ethtool_tcam_entry(np, cmd);
+ break;
+ case ETHTOOL_GRXCLSRLALL:
+ ret = niu_get_ethtool_tcam_all(np, cmd, (u32 *)rule_locs);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int niu_set_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc)
+{
u64 class;
u64 flow_key = 0;
unsigned long flags;
- if (!niu_ethflow_to_class(cmd->flow_type, &class))
+ if (!niu_ethflow_to_class(nfc->flow_type, &class))
return -EINVAL;
if (class < CLASS_CODE_USER_PROG1 ||
class > CLASS_CODE_SCTP_IPV6)
return -EINVAL;
- if (cmd->data & RXH_DISCARD) {
+ if (nfc->data & RXH_DISCARD) {
niu_lock_parent(np, flags);
flow_key = np->parent->tcam_key[class -
CLASS_CODE_USER_PROG1];
@@ -6923,7 +7377,7 @@ static int niu_set_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
}
}
- if (!niu_ethflow_to_flowkey(cmd->data, &flow_key))
+ if (!niu_ethflow_to_flowkey(nfc->data, &flow_key))
return -EINVAL;
niu_lock_parent(np, flags);
@@ -6934,6 +7388,331 @@ static int niu_set_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
return 0;
}
+static void niu_get_tcamkey_from_ip4fs(struct ethtool_rx_flow_spec *fsp,
+ struct niu_tcam_entry *tp,
+ int l2_rdc_tab, u64 class)
+{
+ u8 pid = 0;
+ u32 sip, dip, sipm, dipm, spi, spim;
+ u16 sport, dport, spm, dpm;
+
+ sip = be32_to_cpu(fsp->h_u.tcp_ip4_spec.ip4src);
+ sipm = be32_to_cpu(fsp->m_u.tcp_ip4_spec.ip4src);
+ dip = be32_to_cpu(fsp->h_u.tcp_ip4_spec.ip4dst);
+ dipm = be32_to_cpu(fsp->m_u.tcp_ip4_spec.ip4dst);
+
+ tp->key[0] = class << TCAM_V4KEY0_CLASS_CODE_SHIFT;
+ tp->key_mask[0] = TCAM_V4KEY0_CLASS_CODE;
+ tp->key[1] = (u64)l2_rdc_tab << TCAM_V4KEY1_L2RDCNUM_SHIFT;
+ tp->key_mask[1] = TCAM_V4KEY1_L2RDCNUM;
+
+ tp->key[3] = (u64)sip << TCAM_V4KEY3_SADDR_SHIFT;
+ tp->key[3] |= dip;
+
+ tp->key_mask[3] = (u64)sipm << TCAM_V4KEY3_SADDR_SHIFT;
+ tp->key_mask[3] |= dipm;
+
+ tp->key[2] |= ((u64)fsp->h_u.tcp_ip4_spec.tos <<
+ TCAM_V4KEY2_TOS_SHIFT);
+ tp->key_mask[2] |= ((u64)fsp->m_u.tcp_ip4_spec.tos <<
+ TCAM_V4KEY2_TOS_SHIFT);
+ switch (fsp->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ sport = be16_to_cpu(fsp->h_u.tcp_ip4_spec.psrc);
+ spm = be16_to_cpu(fsp->m_u.tcp_ip4_spec.psrc);
+ dport = be16_to_cpu(fsp->h_u.tcp_ip4_spec.pdst);
+ dpm = be16_to_cpu(fsp->m_u.tcp_ip4_spec.pdst);
+
+ tp->key[2] |= (((u64)sport << 16) | dport);
+ tp->key_mask[2] |= (((u64)spm << 16) | dpm);
+ niu_ethflow_to_l3proto(fsp->flow_type, &pid);
+ break;
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ spi = be32_to_cpu(fsp->h_u.ah_ip4_spec.spi);
+ spim = be32_to_cpu(fsp->m_u.ah_ip4_spec.spi);
+
+ tp->key[2] |= spi;
+ tp->key_mask[2] |= spim;
+ niu_ethflow_to_l3proto(fsp->flow_type, &pid);
+ break;
+ case IP_USER_FLOW:
+ spi = be32_to_cpu(fsp->h_u.usr_ip4_spec.l4_4_bytes);
+ spim = be32_to_cpu(fsp->m_u.usr_ip4_spec.l4_4_bytes);
+
+ tp->key[2] |= spi;
+ tp->key_mask[2] |= spim;
+ pid = fsp->h_u.usr_ip4_spec.proto;
+ break;
+ default:
+ break;
+ }
+
+ tp->key[2] |= ((u64)pid << TCAM_V4KEY2_PROTO_SHIFT);
+ if (pid) {
+ tp->key_mask[2] |= TCAM_V4KEY2_PROTO;
+ }
+}
+
+static int niu_add_ethtool_tcam_entry(struct niu *np,
+ struct ethtool_rxnfc *nfc)
+{
+ struct niu_parent *parent = np->parent;
+ struct niu_tcam_entry *tp;
+ struct ethtool_rx_flow_spec *fsp = &nfc->fs;
+ struct niu_rdc_tables *rdc_table = &parent->rdc_group_cfg[np->port];
+ int l2_rdc_table = rdc_table->first_table_num;
+ u16 idx;
+ u64 class;
+ unsigned long flags;
+ int err, ret;
+
+ ret = 0;
+
+ idx = nfc->fs.location;
+ if (idx >= tcam_get_size(np))
+ return -EINVAL;
+
+ if (fsp->flow_type == IP_USER_FLOW) {
+ int i;
+ int add_usr_cls = 0;
+ int ipv6 = 0;
+ struct ethtool_usrip4_spec *uspec = &fsp->h_u.usr_ip4_spec;
+ struct ethtool_usrip4_spec *umask = &fsp->m_u.usr_ip4_spec;
+
+ niu_lock_parent(np, flags);
+
+ for (i = 0; i < NIU_L3_PROG_CLS; i++) {
+ if (parent->l3_cls[i]) {
+ if (uspec->proto == parent->l3_cls_pid[i]) {
+ class = parent->l3_cls[i];
+ parent->l3_cls_refcnt[i]++;
+ add_usr_cls = 1;
+ break;
+ }
+ } else {
+ /* Program new user IP class */
+ switch (i) {
+ case 0:
+ class = CLASS_CODE_USER_PROG1;
+ break;
+ case 1:
+ class = CLASS_CODE_USER_PROG2;
+ break;
+ case 2:
+ class = CLASS_CODE_USER_PROG3;
+ break;
+ case 3:
+ class = CLASS_CODE_USER_PROG4;
+ break;
+ default:
+ break;
+ }
+ if (uspec->ip_ver == ETH_RX_NFC_IP6)
+ ipv6 = 1;
+ ret = tcam_user_ip_class_set(np, class, ipv6,
+ uspec->proto,
+ uspec->tos,
+ umask->tos);
+ if (ret)
+ goto out;
+
+ ret = tcam_user_ip_class_enable(np, class, 1);
+ if (ret)
+ goto out;
+ parent->l3_cls[i] = class;
+ parent->l3_cls_pid[i] = uspec->proto;
+ parent->l3_cls_refcnt[i]++;
+ add_usr_cls = 1;
+ break;
+ }
+ }
+ if (!add_usr_cls) {
+ pr_info(PFX "niu%d: %s niu_add_ethtool_tcam_entry: "
+ "Could not find/insert class for pid %d\n",
+ parent->index, np->dev->name, uspec->proto);
+ ret = -EINVAL;
+ goto out;
+ }
+ niu_unlock_parent(np, flags);
+ } else {
+ if (!niu_ethflow_to_class(fsp->flow_type, &class)) {
+ return -EINVAL;
+ }
+ }
+
+ niu_lock_parent(np, flags);
+
+ idx = tcam_get_index(np, idx);
+ tp = &parent->tcam[idx];
+
+ memset(tp, 0, sizeof(*tp));
+
+ /* fill in the tcam key and mask */
+ switch (fsp->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table, class);
+ break;
+ case TCP_V6_FLOW:
+ case UDP_V6_FLOW:
+ case SCTP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ /* Not yet implemented */
+ pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+ "flow %d for IPv6 not implemented\n\n",
+ parent->index, np->dev->name, fsp->flow_type);
+ ret = -EINVAL;
+ goto out;
+ case IP_USER_FLOW:
+ if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) {
+ niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table,
+ class);
+ } else {
+ /* Not yet implemented */
+ pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+ "usr flow for IPv6 not implemented\n\n",
+ parent->index, np->dev->name);
+ ret = -EINVAL;
+ goto out;
+ }
+ break;
+ default:
+ pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+ "Unknown flow type %d\n\n",
+ parent->index, np->dev->name, fsp->flow_type);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* fill in the assoc data */
+ if (fsp->ring_cookie == RX_CLS_FLOW_DISC) {
+ tp->assoc_data = TCAM_ASSOCDATA_DISC;
+ } else {
+ if (fsp->ring_cookie >= np->num_rx_rings) {
+ pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+ "Invalid RX ring %lld\n\n",
+ parent->index, np->dev->name,
+ (long long) fsp->ring_cookie);
+ ret = -EINVAL;
+ goto out;
+ }
+ tp->assoc_data = (TCAM_ASSOCDATA_TRES_USE_OFFSET |
+ (fsp->ring_cookie <<
+ TCAM_ASSOCDATA_OFFSET_SHIFT));
+ }
+
+ err = tcam_write(np, idx, tp->key, tp->key_mask);
+ if (err) {
+ ret = -EINVAL;
+ goto out;
+ }
+ err = tcam_assoc_write(np, idx, tp->assoc_data);
+ if (err) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* validate the entry */
+ tp->valid = 1;
+ np->clas.tcam_valid_entries++;
+out:
+ niu_unlock_parent(np, flags);
+
+ return ret;
+}
+
+static int niu_del_ethtool_tcam_entry(struct niu *np, u32 loc)
+{
+ struct niu_parent *parent = np->parent;
+ struct niu_tcam_entry *tp;
+ u16 idx;
+ unsigned long flags;
+ u64 class;
+ int ret = 0;
+
+ if (loc >= tcam_get_size(np))
+ return -EINVAL;
+
+ niu_lock_parent(np, flags);
+
+ idx = tcam_get_index(np, loc);
+ tp = &parent->tcam[idx];
+
+ /* if the entry is of a user defined class, then update*/
+ class = (tp->key[0] & TCAM_V4KEY0_CLASS_CODE) >>
+ TCAM_V4KEY0_CLASS_CODE_SHIFT;
+
+ if (class >= CLASS_CODE_USER_PROG1 && class <= CLASS_CODE_USER_PROG4) {
+ int i;
+ for (i = 0; i < NIU_L3_PROG_CLS; i++) {
+ if (parent->l3_cls[i] == class) {
+ parent->l3_cls_refcnt[i]--;
+ if (!parent->l3_cls_refcnt[i]) {
+ /* disable class */
+ ret = tcam_user_ip_class_enable(np,
+ class,
+ 0);
+ if (ret)
+ goto out;
+ parent->l3_cls[i] = 0;
+ parent->l3_cls_pid[i] = 0;
+ }
+ break;
+ }
+ }
+ if (i == NIU_L3_PROG_CLS) {
+ pr_info(PFX "niu%d: %s In niu_del_ethtool_tcam_entry,"
+ "Usr class 0x%llx not found \n",
+ parent->index, np->dev->name,
+ (unsigned long long) class);
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ ret = tcam_flush(np, idx);
+ if (ret)
+ goto out;
+
+ /* invalidate the entry */
+ tp->valid = 0;
+ np->clas.tcam_valid_entries--;
+out:
+ niu_unlock_parent(np, flags);
+
+ return ret;
+}
+
+static int niu_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+ struct niu *np = netdev_priv(dev);
+ int ret = 0;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_SRXFH:
+ ret = niu_set_hash_opts(np, cmd);
+ break;
+ case ETHTOOL_SRXCLSRLINS:
+ ret = niu_add_ethtool_tcam_entry(np, cmd);
+ break;
+ case ETHTOOL_SRXCLSRLDEL:
+ ret = niu_del_ethtool_tcam_entry(np, cmd->fs.location);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
static const struct {
const char string[ETH_GSTRING_LEN];
} niu_xmac_stat_keys[] = {
@@ -7158,6 +7937,7 @@ static const struct ethtool_ops niu_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_msglevel = niu_get_msglevel,
.set_msglevel = niu_set_msglevel,
+ .nway_reset = niu_nway_reset,
.get_eeprom_len = niu_get_eeprom_len,
.get_eeprom = niu_get_eeprom,
.get_settings = niu_get_settings,
@@ -7166,8 +7946,8 @@ static const struct ethtool_ops niu_ethtool_ops = {
.get_stats_count = niu_get_stats_count,
.get_ethtool_stats = niu_get_ethtool_stats,
.phys_id = niu_phys_id,
- .get_rxhash = niu_get_hash_opts,
- .set_rxhash = niu_set_hash_opts,
+ .get_rxnfc = niu_get_nfc,
+ .set_rxnfc = niu_set_nfc,
};
static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent,
@@ -8237,7 +9017,8 @@ static int __devinit niu_classifier_swstate_init(struct niu *np)
niudbg(PROBE, "niu_classifier_swstate_init: num_tcam(%d)\n",
np->parent->tcam_num_entries);
- cp->tcam_index = (u16) np->port;
+ cp->tcam_top = (u16) np->port;
+ cp->tcam_sz = np->parent->tcam_num_entries / np->parent->num_ports;
cp->h1_init = 0xffffffff;
cp->h2_init = 0xffff;
@@ -8257,7 +9038,9 @@ static void __devinit niu_link_config_init(struct niu *np)
ADVERTISED_10000baseT_Full |
ADVERTISED_Autoneg);
lp->speed = lp->active_speed = SPEED_INVALID;
- lp->duplex = lp->active_duplex = DUPLEX_INVALID;
+ lp->duplex = DUPLEX_FULL;
+ lp->active_duplex = DUPLEX_INVALID;
+ lp->autoneg = 1;
#if 0
lp->loopback_mode = LOOPBACK_MAC;
lp->active_speed = SPEED_10000;
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index e1a7392e8d7..8754e44cada 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -3004,7 +3004,9 @@ struct niu_classifier {
struct niu_altmac_rdc alt_mac_mappings[16];
struct niu_vlan_rdc vlan_mappings[ENET_VLAN_TBL_NUM_ENTRIES];
- u16 tcam_index;
+ u16 tcam_top;
+ u16 tcam_sz;
+ u16 tcam_valid_entries;
u16 num_alt_mac_mappings;
u32 h1_init;
@@ -3040,6 +3042,7 @@ struct phy_probe_info {
};
struct niu_tcam_entry {
+ u8 valid;
u64 key[4];
u64 key_mask[4];
u64 assoc_data;
@@ -3107,10 +3110,15 @@ struct niu_parent {
struct phy_probe_info phy_probe_info;
struct niu_tcam_entry tcam[NIU_TCAM_ENTRIES_MAX];
- u64 l2_cls[2];
- u64 l3_cls[4];
+
+#define NIU_L2_PROG_CLS 2
+#define NIU_L3_PROG_CLS 4
+ u64 l2_cls[NIU_L2_PROG_CLS];
+ u64 l3_cls[NIU_L3_PROG_CLS];
u64 tcam_key[12];
u64 flow_key[12];
+ u16 l3_cls_refcnt[NIU_L3_PROG_CLS];
+ u8 l3_cls_pid[NIU_L3_PROG_CLS];
};
struct niu_ops {
@@ -3131,16 +3139,19 @@ struct niu_ops {
};
struct niu_link_config {
+ u32 supported;
+
/* Describes what we're trying to get. */
u32 advertising;
- u32 supported;
u16 speed;
u8 duplex;
u8 autoneg;
/* Describes what we actually have. */
+ u32 active_advertising;
u16 active_speed;
u8 active_duplex;
+ u8 active_autoneg;
#define SPEED_INVALID 0xffff
#define DUPLEX_INVALID 0xff
#define AUTONEG_INVALID 0xff
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index e80294d8cc1..221b0c4c824 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -409,7 +409,7 @@ static int lnksts = 0; /* CFG_LNKSTS bit polarity */
struct rx_info {
spinlock_t lock;
int up;
- long idle;
+ unsigned long idle;
struct sk_buff *skbs[NR_RX_DESC];
@@ -822,8 +822,7 @@ static void ns83820_cleanup_rx(struct ns83820 *dev)
struct sk_buff *skb = dev->rx_info.skbs[i];
dev->rx_info.skbs[i] = NULL;
clear_rx_desc(dev, i);
- if (skb)
- kfree_skb(skb);
+ kfree_skb(skb);
}
}
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index d0349e7d73e..5eeb5a87b73 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -970,7 +970,7 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
if (*chan->status & PAS_STATUS_ERROR)
reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
- netif_rx_schedule(&mac->napi);
+ napi_schedule(&mac->napi);
write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg);
@@ -1010,7 +1010,7 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
mod_timer(&txring->clean_timer, jiffies + (TX_CLEAN_INTERVAL)*2);
- netif_rx_schedule(&mac->napi);
+ napi_schedule(&mac->napi);
if (reg)
write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
@@ -1639,7 +1639,7 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
pkts = pasemi_mac_clean_rx(rx_ring(mac), budget);
if (pkts < budget) {
/* all done, no more packets present */
- netif_rx_complete(napi);
+ napi_complete(napi);
pasemi_mac_restart_rx_intr(mac);
pasemi_mac_restart_tx_intr(mac);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index e5cb6b1f0eb..8f3872b8985 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -257,6 +257,18 @@ static void tc574_detach(struct pcmcia_device *p_dev);
local data structures for one device. The device is registered
with Card Services.
*/
+static const struct net_device_ops el3_netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_do_ioctl = el3_ioctl,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int tc574_probe(struct pcmcia_device *link)
{
@@ -284,18 +296,9 @@ static int tc574_probe(struct pcmcia_device *link)
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
- /* The EL3-specific entries in the device structure. */
- dev->hard_start_xmit = &el3_start_xmit;
- dev->get_stats = &el3_get_stats;
- dev->do_ioctl = &el3_ioctl;
+ dev->netdev_ops = &el3_netdev_ops;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->set_multicast_list = &set_rx_mode;
- dev->open = &el3_open;
- dev->stop = &el3_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = el3_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
return tc574_config(link);
} /* tc574_attach */
@@ -1035,7 +1038,8 @@ static int el3_rx(struct net_device *dev, int worklimit)
DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
- (--worklimit >= 0)) {
+ worklimit > 0) {
+ worklimit--;
if (rx_status & 0x4000) { /* Error, update stats. */
short error = rx_status & 0x3800;
dev->stats.rx_errors++;
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 73ecc657999..cdf661a6092 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -169,6 +169,19 @@ static void tc589_detach(struct pcmcia_device *p_dev);
======================================================================*/
+static const struct net_device_ops el3_netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_set_config = el3_config,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int tc589_probe(struct pcmcia_device *link)
{
struct el3_private *lp;
@@ -195,17 +208,9 @@ static int tc589_probe(struct pcmcia_device *link)
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
- /* The EL3-specific entries in the device structure. */
- dev->hard_start_xmit = &el3_start_xmit;
- dev->set_config = &el3_config;
- dev->get_stats = &el3_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->open = &el3_open;
- dev->stop = &el3_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = el3_tx_timeout;
+ dev->netdev_ops = &el3_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
+
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
return tc589_config(link);
@@ -857,7 +862,8 @@ static int el3_rx(struct net_device *dev)
DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) &&
- (--worklimit >= 0)) {
+ worklimit > 0) {
+ worklimit--;
if (rx_status & 0x4000) { /* Error, update stats. */
short error = rx_status & 0x3800;
dev->stats.rx_errors++;
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 0afa7209581..501a8d7ac2b 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/crc32.h>
#include "../8390.h"
@@ -91,6 +92,10 @@ static void axnet_release(struct pcmcia_device *link);
static int axnet_open(struct net_device *dev);
static int axnet_close(struct net_device *dev);
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int axnet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void axnet_tx_timeout(struct net_device *dev);
static const struct ethtool_ops netdev_ethtool_ops;
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
static void ei_watchdog(u_long arg);
@@ -108,7 +113,6 @@ static void block_output(struct net_device *dev, int count,
static void axnet_detach(struct pcmcia_device *p_dev);
-static void axdev_setup(struct net_device *dev);
static void AX88190_init(struct net_device *dev, int startp);
static int ax_open(struct net_device *dev);
static int ax_close(struct net_device *dev);
@@ -134,6 +138,19 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)
return p;
}
+static const struct net_device_ops axnet_netdev_ops = {
+ .ndo_open = axnet_open,
+ .ndo_stop = axnet_close,
+ .ndo_do_ioctl = axnet_ioctl,
+ .ndo_start_xmit = axnet_start_xmit,
+ .ndo_tx_timeout = axnet_tx_timeout,
+ .ndo_get_stats = get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*======================================================================
axnet_attach() creates an "instance" of the driver, allocating
@@ -146,15 +163,17 @@ static int axnet_probe(struct pcmcia_device *link)
{
axnet_dev_t *info;
struct net_device *dev;
+ struct ei_device *ei_local;
DEBUG(0, "axnet_attach()\n");
- dev = alloc_netdev(sizeof(struct ei_device) + sizeof(axnet_dev_t),
- "eth%d", axdev_setup);
-
+ dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
if (!dev)
return -ENOMEM;
+ ei_local = netdev_priv(dev);
+ spin_lock_init(&ei_local->page_lock);
+
info = PRIV(dev);
info->p_dev = link;
link->priv = dev;
@@ -163,10 +182,10 @@ static int axnet_probe(struct pcmcia_device *link)
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
- dev->open = &axnet_open;
- dev->stop = &axnet_close;
- dev->do_ioctl = &axnet_ioctl;
+ dev->netdev_ops = &axnet_netdev_ops;
+
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+ dev->watchdog_timeo = TX_TIMEOUT;
return axnet_config(link);
} /* axnet_attach */
@@ -861,7 +880,7 @@ module_exit(exit_axnet_cs);
*/
-static const char *version_8390 =
+static const char version_8390[] = KERN_INFO \
"8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n";
#include <linux/bitops.h>
@@ -905,14 +924,12 @@ int ei_debug = 1;
/* Index to functions. */
static void ei_tx_intr(struct net_device *dev);
static void ei_tx_err(struct net_device *dev);
-static void axnet_tx_timeout(struct net_device *dev);
static void ei_receive(struct net_device *dev);
static void ei_rx_overrun(struct net_device *dev);
/* Routines generic to NS8390-based boards. */
static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
int start_page);
-static void set_multicast_list(struct net_device *dev);
static void do_set_multicast_list(struct net_device *dev);
/*
@@ -954,15 +971,6 @@ static int ax_open(struct net_device *dev)
unsigned long flags;
struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
-#ifdef HAVE_TX_TIMEOUT
- /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
- wrapper that does e.g. media check & then calls axnet_tx_timeout. */
- if (dev->tx_timeout == NULL)
- dev->tx_timeout = axnet_tx_timeout;
- if (dev->watchdog_timeo <= 0)
- dev->watchdog_timeo = TX_TIMEOUT;
-#endif
-
/*
* Grab the page lock so we own the register set, then call
* the init function.
@@ -1701,30 +1709,6 @@ static void set_multicast_list(struct net_device *dev)
spin_unlock_irqrestore(&dev_lock(dev), flags);
}
-/**
- * axdev_setup - init rest of 8390 device struct
- * @dev: network device structure to init
- *
- * Initialize the rest of the 8390 device structure. Do NOT __init
- * this, as it is used by 8390 based modular drivers too.
- */
-
-static void axdev_setup(struct net_device *dev)
-{
- struct ei_device *ei_local;
- if (ei_debug > 1)
- printk(version_8390);
-
- ei_local = (struct ei_device *)netdev_priv(dev);
- spin_lock_init(&ei_local->page_lock);
-
- dev->hard_start_xmit = &axnet_start_xmit;
- dev->get_stats = get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- ether_setup(dev);
-}
-
/* This page of functions should be 8390 generic */
/* Follow National Semi's recommendations for initializing the "NIC". */
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 69dcfbbabe8..81e6660a433 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -100,7 +100,6 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t fjn_interrupt(int irq, void *dev_id);
static void fjn_rx(struct net_device *dev);
static void fjn_reset(struct net_device *dev);
-static struct net_device_stats *fjn_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);
static void fjn_tx_timeout(struct net_device *dev);
static const struct ethtool_ops netdev_ethtool_ops;
@@ -118,7 +117,6 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN,
typedef struct local_info_t {
struct pcmcia_device *p_dev;
dev_node_t node;
- struct net_device_stats stats;
long open_time;
uint tx_started:1;
uint tx_queue;
@@ -229,6 +227,18 @@ typedef struct local_info_t {
#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */
#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */
+static const struct net_device_ops fjn_netdev_ops = {
+ .ndo_open = fjn_open,
+ .ndo_stop = fjn_close,
+ .ndo_start_xmit = fjn_start_xmit,
+ .ndo_tx_timeout = fjn_tx_timeout,
+ .ndo_set_config = fjn_config,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int fmvj18x_probe(struct pcmcia_device *link)
{
local_info_t *lp;
@@ -260,17 +270,9 @@ static int fmvj18x_probe(struct pcmcia_device *link)
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
- /* The FMVJ18x specific entries in the device structure. */
- dev->hard_start_xmit = &fjn_start_xmit;
- dev->set_config = &fjn_config;
- dev->get_stats = &fjn_get_stats;
- dev->set_multicast_list = &set_rx_mode;
- dev->open = &fjn_open;
- dev->stop = &fjn_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = fjn_tx_timeout;
+ dev->netdev_ops = &fjn_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
+
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
return fmvj18x_config(link);
@@ -793,7 +795,7 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
fjn_rx(dev);
}
if (tx_stat & F_TMT_RDY) {
- lp->stats.tx_packets += lp->sent ;
+ dev->stats.tx_packets += lp->sent ;
lp->sent = 0 ;
if (lp->tx_queue) {
outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
@@ -840,7 +842,7 @@ static void fjn_tx_timeout(struct net_device *dev)
htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
htons(inw(ioaddr +14)));
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* ToDo: We should try to restart the adaptor... */
local_irq_disable();
fjn_reset(dev);
@@ -880,7 +882,7 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
dev->name, (unsigned long)skb->len);
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
/* Disable both interrupts. */
outw(0x0000, ioaddr + TX_INTR);
@@ -1008,7 +1010,6 @@ static void fjn_reset(struct net_device *dev)
static void fjn_rx(struct net_device *dev)
{
- struct local_info_t *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
int boguscount = 10; /* 5 -> 10: by agy 19940922 */
@@ -1027,11 +1028,11 @@ static void fjn_rx(struct net_device *dev)
}
#endif
if ((status & 0xF0) != 0x20) { /* There was an error. */
- lp->stats.rx_errors++;
- if (status & F_LEN_ERR) lp->stats.rx_length_errors++;
- if (status & F_ALG_ERR) lp->stats.rx_frame_errors++;
- if (status & F_CRC_ERR) lp->stats.rx_crc_errors++;
- if (status & F_OVR_FLO) lp->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
+ if (status & F_LEN_ERR) dev->stats.rx_length_errors++;
+ if (status & F_ALG_ERR) dev->stats.rx_frame_errors++;
+ if (status & F_CRC_ERR) dev->stats.rx_crc_errors++;
+ if (status & F_OVR_FLO) dev->stats.rx_over_errors++;
} else {
u_short pkt_len = inw(ioaddr + DATAPORT);
/* Malloc up new buffer. */
@@ -1041,7 +1042,7 @@ static void fjn_rx(struct net_device *dev)
printk(KERN_NOTICE "%s: The FMV-18x claimed a very "
"large packet, size %d.\n", dev->name, pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
}
skb = dev_alloc_skb(pkt_len+2);
@@ -1049,7 +1050,7 @@ static void fjn_rx(struct net_device *dev)
printk(KERN_NOTICE "%s: Memory squeeze, dropping "
"packet (len %d).\n", dev->name, pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
break;
}
@@ -1070,8 +1071,8 @@ static void fjn_rx(struct net_device *dev)
#endif
netif_rx(skb);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
if (--boguscount <= 0)
break;
@@ -1191,14 +1192,6 @@ static int fjn_close(struct net_device *dev)
/*====================================================================*/
-static struct net_device_stats *fjn_get_stats(struct net_device *dev)
-{
- local_info_t *lp = netdev_priv(dev);
- return &lp->stats;
-} /* fjn_get_stats */
-
-/*====================================================================*/
-
/*
Set the multicast/promiscuous mode for this adaptor.
*/
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index ec7c588c9ae..02ef63ed1f9 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -436,6 +436,19 @@ static const struct ethtool_ops netdev_ethtool_ops;
static void nmclan_detach(struct pcmcia_device *p_dev);
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_start_xmit,
+ .ndo_tx_timeout = mace_tx_timeout,
+ .ndo_set_config = mace_config,
+ .ndo_get_stats = mace_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* ----------------------------------------------------------------------------
nmclan_attach
Creates an "instance" of the driver, allocating local data
@@ -474,17 +487,9 @@ static int nmclan_probe(struct pcmcia_device *link)
lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
- dev->hard_start_xmit = &mace_start_xmit;
- dev->set_config = &mace_config;
- dev->get_stats = &mace_get_stats;
- dev->set_multicast_list = &set_multicast_list;
+ dev->netdev_ops = &mace_netdev_ops;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->open = &mace_open;
- dev->stop = &mace_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = mace_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
return nmclan_config(link);
} /* nmclan_attach */
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index c38ed777f0a..2fbf9f9ddd3 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -39,6 +39,7 @@
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/log2.h>
+#include <linux/etherdevice.h>
#include "../8390.h"
#include <pcmcia/cs_types.h>
@@ -233,6 +234,23 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev)
return (pcnet_dev_t *)(p + sizeof(struct ei_device));
}
+static const struct net_device_ops pcnet_netdev_ops = {
+ .ndo_open = pcnet_open,
+ .ndo_stop = pcnet_close,
+ .ndo_set_config = set_config,
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_do_ioctl = ei_ioctl,
+ .ndo_set_multicast_list = ei_set_multicast_list,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ei_poll,
+#endif
+};
+
/*======================================================================
pcnet_attach() creates an "instance" of the driver, allocating
@@ -260,9 +278,7 @@ static int pcnet_probe(struct pcmcia_device *link)
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
- dev->open = &pcnet_open;
- dev->stop = &pcnet_close;
- dev->set_config = &set_config;
+ dev->netdev_ops = &pcnet_netdev_ops;
return pcnet_config(link);
} /* pcnet_attach */
@@ -586,7 +602,7 @@ static int pcnet_config(struct pcmcia_device *link)
}
if ((link->conf.ConfigBase == 0x03c0)
- && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) {
+ && (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
goto failed;
@@ -640,18 +656,12 @@ static int pcnet_config(struct pcmcia_device *link)
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- if (info->flags & (IS_DL10019|IS_DL10022)) {
- dev->do_ioctl = &ei_ioctl;
+ if (info->flags & (IS_DL10019|IS_DL10022))
mii_phy_probe(dev);
- }
link->dev_node = &info->node;
SET_NETDEV_DEV(dev, &handle_to_dev(link));
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
-
if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
link->dev_node = NULL;
@@ -1183,6 +1193,10 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
pcnet_dev_t *info = PRIV(dev);
u16 *data = (u16 *)&rq->ifr_ifru;
unsigned int mii_addr = dev->base_addr + DLINK_GPIO;
+
+ if (!(info->flags & (IS_DL10019|IS_DL10022)))
+ return -EINVAL;
+
switch (cmd) {
case SIOCGMIIPHY:
data[0] = info->phy_id;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index fccd53ef3c6..774232c13b3 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -108,7 +108,7 @@ struct smc_private {
spinlock_t lock;
u_short manfid;
u_short cardid;
- struct net_device_stats stats;
+
dev_node_t node;
struct sk_buff *saved_skb;
int packets_waiting;
@@ -289,7 +289,6 @@ static void smc_tx_timeout(struct net_device *dev);
static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t smc_interrupt(int irq, void *dev_id);
static void smc_rx(struct net_device *dev);
-static struct net_device_stats *smc_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);
static int s9k_config(struct net_device *dev, struct ifmap *map);
static void smc_set_xcvr(struct net_device *dev, int if_port);
@@ -301,6 +300,19 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int value);
static int smc_link_ok(struct net_device *dev);
static const struct ethtool_ops ethtool_ops;
+static const struct net_device_ops smc_netdev_ops = {
+ .ndo_open = smc_open,
+ .ndo_stop = smc_close,
+ .ndo_start_xmit = smc_start_xmit,
+ .ndo_tx_timeout = smc_tx_timeout,
+ .ndo_set_config = s9k_config,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_do_ioctl = &smc_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*======================================================================
smc91c92_attach() creates an "instance" of the driver, allocating
@@ -336,18 +348,9 @@ static int smc91c92_probe(struct pcmcia_device *link)
link->conf.IntType = INT_MEMORY_AND_IO;
/* The SMC91c92-specific entries in the device structure. */
- dev->hard_start_xmit = &smc_start_xmit;
- dev->get_stats = &smc_get_stats;
- dev->set_config = &s9k_config;
- dev->set_multicast_list = &set_rx_mode;
- dev->open = &smc_open;
- dev->stop = &smc_close;
- dev->do_ioctl = &smc_ioctl;
+ dev->netdev_ops = &smc_netdev_ops;
SET_ETHTOOL_OPS(dev, &ethtool_ops);
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = smc_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
smc->mii_if.dev = dev;
smc->mii_if.mdio_read = mdio_read;
@@ -1291,7 +1294,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
return;
}
- smc->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
/* The card should use the just-allocated buffer. */
outw(packet_no, ioaddr + PNR_ARR);
/* point to the beginning of the packet */
@@ -1340,7 +1343,7 @@ static void smc_tx_timeout(struct net_device *dev)
printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
"Tx_status %2.2x status %4.4x.\n",
dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
- smc->stats.tx_errors++;
+ dev->stats.tx_errors++;
smc_reset(dev);
dev->trans_start = jiffies;
smc->saved_skb = NULL;
@@ -1362,7 +1365,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (smc->saved_skb) {
/* THIS SHOULD NEVER HAPPEN. */
- smc->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n",
dev->name);
return 1;
@@ -1375,7 +1378,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
printk(KERN_ERR "%s: Far too big packet error.\n", dev->name);
dev_kfree_skb (skb);
smc->saved_skb = NULL;
- smc->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
return 0; /* Do not re-queue this packet. */
}
/* A packet is now waiting. */
@@ -1433,11 +1436,11 @@ static void smc_tx_err(struct net_device * dev)
tx_status = inw(ioaddr + DATA_1);
- smc->stats.tx_errors++;
- if (tx_status & TS_LOSTCAR) smc->stats.tx_carrier_errors++;
- if (tx_status & TS_LATCOL) smc->stats.tx_window_errors++;
+ dev->stats.tx_errors++;
+ if (tx_status & TS_LOSTCAR) dev->stats.tx_carrier_errors++;
+ if (tx_status & TS_LATCOL) dev->stats.tx_window_errors++;
if (tx_status & TS_16COL) {
- smc->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
smc->tx_err++;
}
@@ -1474,10 +1477,10 @@ static void smc_eph_irq(struct net_device *dev)
/* Could be a counter roll-over warning: update stats. */
card_stats = inw(ioaddr + COUNTER);
/* single collisions */
- smc->stats.collisions += card_stats & 0xF;
+ dev->stats.collisions += card_stats & 0xF;
card_stats >>= 4;
/* multiple collisions */
- smc->stats.collisions += card_stats & 0xF;
+ dev->stats.collisions += card_stats & 0xF;
#if 0 /* These are for when linux supports these statistics */
card_stats >>= 4; /* deferred */
card_stats >>= 4; /* excess deferred */
@@ -1551,7 +1554,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
if (status & IM_TX_EMPTY_INT) {
outw(IM_TX_EMPTY_INT, ioaddr + INTERRUPT);
mask &= ~IM_TX_EMPTY_INT;
- smc->stats.tx_packets += smc->packets_waiting;
+ dev->stats.tx_packets += smc->packets_waiting;
smc->packets_waiting = 0;
}
if (status & IM_ALLOC_INT) {
@@ -1567,8 +1570,8 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
netif_wake_queue(dev);
}
if (status & IM_RX_OVRN_INT) {
- smc->stats.rx_errors++;
- smc->stats.rx_fifo_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_fifo_errors++;
if (smc->duplex)
smc->rx_ovrn = 1; /* need MC_RESET outside smc_interrupt */
outw(IM_RX_OVRN_INT, ioaddr + INTERRUPT);
@@ -1618,7 +1621,6 @@ irq_done:
static void smc_rx(struct net_device *dev)
{
- struct smc_private *smc = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
int rx_status;
int packet_length; /* Caution: not frame length, rather words
@@ -1649,7 +1651,7 @@ static void smc_rx(struct net_device *dev)
if (skb == NULL) {
DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
- smc->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
outw(MC_RELEASE, ioaddr + MMU_CMD);
return;
}
@@ -1662,18 +1664,18 @@ static void smc_rx(struct net_device *dev)
netif_rx(skb);
dev->last_rx = jiffies;
- smc->stats.rx_packets++;
- smc->stats.rx_bytes += packet_length;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += packet_length;
if (rx_status & RS_MULTICAST)
- smc->stats.multicast++;
+ dev->stats.multicast++;
} else {
/* error ... */
- smc->stats.rx_errors++;
+ dev->stats.rx_errors++;
- if (rx_status & RS_ALGNERR) smc->stats.rx_frame_errors++;
+ if (rx_status & RS_ALGNERR) dev->stats.rx_frame_errors++;
if (rx_status & (RS_TOOSHORT | RS_TOOLONG))
- smc->stats.rx_length_errors++;
- if (rx_status & RS_BADCRC) smc->stats.rx_crc_errors++;
+ dev->stats.rx_length_errors++;
+ if (rx_status & RS_BADCRC) dev->stats.rx_crc_errors++;
}
/* Let the MMU free the memory of this packet. */
outw(MC_RELEASE, ioaddr + MMU_CMD);
@@ -1681,15 +1683,6 @@ static void smc_rx(struct net_device *dev)
return;
}
-/*====================================================================*/
-
-static struct net_device_stats *smc_get_stats(struct net_device *dev)
-{
- struct smc_private *smc = netdev_priv(dev);
- /* Nothing to update - the 91c92 is a pretty primative chip. */
- return &smc->stats;
-}
-
/*======================================================================
Calculate values for the hardware multicast filter hash table.
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index fef7e1861d6..a3685c0d22f 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -335,7 +335,7 @@ typedef struct local_info_t {
struct net_device *dev;
struct pcmcia_device *p_dev;
dev_node_t node;
- struct net_device_stats stats;
+
int card_type;
int probe_port;
int silicon; /* silicon revision. 0=old CE2, 1=Scipper, 4=Mohawk */
@@ -355,7 +355,6 @@ typedef struct local_info_t {
static int do_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void xirc_tx_timeout(struct net_device *dev);
static void xirc2ps_tx_timeout_task(struct work_struct *work);
-static struct net_device_stats *do_get_stats(struct net_device *dev);
static void set_addresses(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static int set_card_type(struct pcmcia_device *link, const void *s);
@@ -546,6 +545,19 @@ mii_wr(unsigned int ioaddr, u_char phyaddr, u_char phyreg, unsigned data,
/*============= Main bulk of functions =========================*/
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = do_open,
+ .ndo_stop = do_stop,
+ .ndo_start_xmit = do_start_xmit,
+ .ndo_tx_timeout = xirc_tx_timeout,
+ .ndo_set_config = do_config,
+ .ndo_do_ioctl = do_ioctl,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/****************
* xirc2ps_attach() creates an "instance" of the driver, allocating
* local data structures for one device. The device is registered
@@ -581,19 +593,10 @@ xirc2ps_probe(struct pcmcia_device *link)
link->irq.Instance = dev;
/* Fill in card specific entries */
- dev->hard_start_xmit = &do_start_xmit;
- dev->set_config = &do_config;
- dev->get_stats = &do_get_stats;
- dev->do_ioctl = &do_ioctl;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->set_multicast_list = &set_multicast_list;
- dev->open = &do_open;
- dev->stop = &do_stop;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = xirc_tx_timeout;
+ dev->netdev_ops = &netdev_ops;
+ dev->ethtool_ops = &netdev_ethtool_ops;
dev->watchdog_timeo = TX_TIMEOUT;
INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task);
-#endif
return xirc2ps_config(link);
} /* xirc2ps_attach */
@@ -1172,7 +1175,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
if (bytes_rcvd > maxrx_bytes && (rsr & PktRxOk)) {
/* too many bytes received during this int, drop the rest of the
* packets */
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
DEBUG(2, "%s: RX drop, too much done\n", dev->name);
} else if (rsr & PktRxOk) {
struct sk_buff *skb;
@@ -1186,7 +1189,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
if (!skb) {
printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n",
pktlen);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
} else { /* okay get the packet */
skb_reserve(skb, 2);
if (lp->silicon == 0 ) { /* work around a hardware bug */
@@ -1242,24 +1245,24 @@ xirc2ps_interrupt(int irq, void *dev_id)
}
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pktlen;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pktlen;
if (!(rsr & PhyPkt))
- lp->stats.multicast++;
+ dev->stats.multicast++;
}
} else { /* bad packet */
DEBUG(5, "rsr=%#02x\n", rsr);
}
if (rsr & PktTooLong) {
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
DEBUG(3, "%s: Packet too long\n", dev->name);
}
if (rsr & CRCErr) {
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
DEBUG(3, "%s: CRC error\n", dev->name);
}
if (rsr & AlignErr) {
- lp->stats.rx_fifo_errors++; /* okay ? */
+ dev->stats.rx_fifo_errors++; /* okay ? */
DEBUG(3, "%s: Alignment error\n", dev->name);
}
@@ -1270,7 +1273,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
eth_status = GetByte(XIRCREG_ESR);
}
if (rx_status & 0x10) { /* Receive overrun */
- lp->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
PutByte(XIRCREG_CR, ClearRxOvrun);
DEBUG(3, "receive overrun cleared\n");
}
@@ -1283,11 +1286,11 @@ xirc2ps_interrupt(int irq, void *dev_id)
nn = GetByte(XIRCREG0_PTR);
lp->last_ptr_value = nn;
if (nn < n) /* rollover */
- lp->stats.tx_packets += 256 - n;
+ dev->stats.tx_packets += 256 - n;
else if (n == nn) { /* happens sometimes - don't know why */
DEBUG(0, "PTR not changed?\n");
} else
- lp->stats.tx_packets += lp->last_ptr_value - n;
+ dev->stats.tx_packets += lp->last_ptr_value - n;
netif_wake_queue(dev);
}
if (tx_status & 0x0002) { /* Execessive collissions */
@@ -1295,7 +1298,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
PutByte(XIRCREG_CR, RestartTx); /* restart transmitter process */
}
if (tx_status & 0x0040)
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
/* recalculate our work chunk so that we limit the duration of this
* ISR to about 1/10 of a second.
@@ -1353,7 +1356,7 @@ static void
xirc_tx_timeout(struct net_device *dev)
{
local_info_t *lp = netdev_priv(dev);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
schedule_work(&lp->tx_timeout_task);
}
@@ -1409,20 +1412,11 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb (skb);
dev->trans_start = jiffies;
- lp->stats.tx_bytes += pktlen;
+ dev->stats.tx_bytes += pktlen;
netif_start_queue(dev);
return 0;
}
-static struct net_device_stats *
-do_get_stats(struct net_device *dev)
-{
- local_info_t *lp = netdev_priv(dev);
-
- /* lp->stats.rx_missed_errors = GetByte(?) */
- return &lp->stats;
-}
-
/****************
* Set all addresses: This first one is the individual address,
* the next 9 addresses are taken from the multicast list and
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 665a4286da3..80124fac65f 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1397,7 +1397,7 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
if (work_done < budget) {
spin_lock_irqsave(&lp->lock, flags);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
/* clear interrupt masks */
val = lp->a.read_csr(ioaddr, CSR3);
@@ -2592,14 +2592,14 @@ pcnet32_interrupt(int irq, void *dev_id)
dev->name, csr0);
/* unlike for the lance, there is no restart needed */
}
- if (netif_rx_schedule_prep(&lp->napi)) {
+ if (napi_schedule_prep(&lp->napi)) {
u16 val;
/* set interrupt masks */
val = lp->a.read_csr(ioaddr, CSR3);
val |= 0x5f00;
lp->a.write_csr(ioaddr, CSR3, val);
mmiowb();
- __netif_rx_schedule(&lp->napi);
+ __napi_schedule(&lp->napi);
break;
}
csr0 = lp->a.read_csr(ioaddr, CSR0);
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index a439ebeb431..33984b73723 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -125,6 +125,8 @@ static int __devinit mdio_gpio_bus_init(struct device *dev,
if (gpio_request(bitbang->mdio, "mdio"))
goto out_free_mdc;
+ gpio_direction_output(bitbang->mdc, 0);
+
dev_set_drvdata(dev, new_bus);
ret = mdiobus_register(new_bus);
@@ -200,16 +202,21 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
{
struct device_node *np = NULL;
struct mdio_gpio_platform_data *pdata;
+ int ret;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
- pdata->mdc = of_get_gpio(ofdev->node, 0);
- pdata->mdio = of_get_gpio(ofdev->node, 1);
-
- if (pdata->mdc < 0 || pdata->mdio < 0)
+ ret = of_get_gpio(ofdev->node, 0);
+ if (ret < 0)
goto out_free;
+ pdata->mdc = ret;
+
+ ret = of_get_gpio(ofdev->node, 1);
+ if (ret < 0)
+ goto out_free;
+ pdata->mdio = ret;
while ((np = of_get_next_child(ofdev->node, np)))
if (!strcmp(np->type, "ethernet-phy"))
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 11adf6ed462..b754020cbe7 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
@@ -98,7 +99,7 @@ int mdiobus_register(struct mii_bus *bus)
bus->dev.parent = bus->parent;
bus->dev.class = &mdio_bus_class;
bus->dev.groups = NULL;
- dev_set_name(&bus->dev, bus->id);
+ dev_set_name(&bus->dev, "%s", bus->id);
err = device_register(&bus->dev);
if (err) {
@@ -286,35 +287,58 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv)
(phydev->phy_id & phydrv->phy_id_mask));
}
+static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
+{
+ struct device_driver *drv = phydev->dev.driver;
+ struct phy_driver *phydrv = to_phy_driver(drv);
+ struct net_device *netdev = phydev->attached_dev;
+
+ if (!drv || !phydrv->suspend)
+ return false;
+
+ /* PHY not attached? May suspend. */
+ if (!netdev)
+ return true;
+
+ /*
+ * Don't suspend PHY if the attched netdev parent may wakeup.
+ * The parent may point to a PCI device, as in tg3 driver.
+ */
+ if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
+ return false;
+
+ /*
+ * Also don't suspend PHY if the netdev itself may wakeup. This
+ * is the case for devices w/o underlaying pwr. mgmt. aware bus,
+ * e.g. SoC devices.
+ */
+ if (device_may_wakeup(&netdev->dev))
+ return false;
+
+ return true;
+}
+
/* Suspend and resume. Copied from platform_suspend and
* platform_resume
*/
static int mdio_bus_suspend(struct device * dev, pm_message_t state)
{
- int ret = 0;
- struct device_driver *drv = dev->driver;
- struct phy_driver *phydrv = to_phy_driver(drv);
+ struct phy_driver *phydrv = to_phy_driver(dev->driver);
struct phy_device *phydev = to_phy_device(dev);
- if ((!device_may_wakeup(phydev->dev.parent)) &&
- (phydrv && phydrv->suspend))
- ret = phydrv->suspend(phydev);
-
- return ret;
+ if (!mdio_bus_phy_may_suspend(phydev))
+ return 0;
+ return phydrv->suspend(phydev);
}
static int mdio_bus_resume(struct device * dev)
{
- int ret = 0;
- struct device_driver *drv = dev->driver;
- struct phy_driver *phydrv = to_phy_driver(drv);
+ struct phy_driver *phydrv = to_phy_driver(dev->driver);
struct phy_device *phydev = to_phy_device(dev);
- if ((!device_may_wakeup(phydev->dev.parent)) &&
- (phydrv && phydrv->resume))
- ret = phydrv->resume(phydev);
-
- return ret;
+ if (!mdio_bus_phy_may_suspend(phydev))
+ return 0;
+ return phydrv->resume(phydev);
}
struct bus_type mdio_bus_type = {
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index e4ede6080c9..58b73b08dde 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -414,7 +414,6 @@ EXPORT_SYMBOL(phy_start_aneg);
static void phy_change(struct work_struct *work);
static void phy_state_machine(struct work_struct *work);
-static void phy_timer(unsigned long data);
/**
* phy_start_machine - start PHY state machine tracking
@@ -434,11 +433,8 @@ void phy_start_machine(struct phy_device *phydev,
{
phydev->adjust_state = handler;
- INIT_WORK(&phydev->state_queue, phy_state_machine);
- init_timer(&phydev->phy_timer);
- phydev->phy_timer.function = &phy_timer;
- phydev->phy_timer.data = (unsigned long) phydev;
- mod_timer(&phydev->phy_timer, jiffies + HZ);
+ INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine);
+ schedule_delayed_work(&phydev->state_queue, jiffies + HZ);
}
/**
@@ -451,8 +447,7 @@ void phy_start_machine(struct phy_device *phydev,
*/
void phy_stop_machine(struct phy_device *phydev)
{
- del_timer_sync(&phydev->phy_timer);
- cancel_work_sync(&phydev->state_queue);
+ cancel_delayed_work_sync(&phydev->state_queue);
mutex_lock(&phydev->lock);
if (phydev->state > PHY_UP)
@@ -680,11 +675,9 @@ static void phy_change(struct work_struct *work)
if (err)
goto irq_enable_err;
- /* Stop timer and run the state queue now. The work function for
- * state_queue will start the timer up again.
- */
- del_timer(&phydev->phy_timer);
- schedule_work(&phydev->state_queue);
+ /* reschedule state queue work to run as soon as possible */
+ cancel_delayed_work_sync(&phydev->state_queue);
+ schedule_delayed_work(&phydev->state_queue, 0);
return;
@@ -761,14 +754,13 @@ EXPORT_SYMBOL(phy_start);
/**
* phy_state_machine - Handle the state machine
* @work: work_struct that describes the work to be done
- *
- * Description: Scheduled by the state_queue workqueue each time
- * phy_timer is triggered.
*/
static void phy_state_machine(struct work_struct *work)
{
+ struct delayed_work *dwork =
+ container_of(work, struct delayed_work, work);
struct phy_device *phydev =
- container_of(work, struct phy_device, state_queue);
+ container_of(dwork, struct phy_device, state_queue);
int needs_aneg = 0;
int err = 0;
@@ -946,17 +938,6 @@ static void phy_state_machine(struct work_struct *work)
if (err < 0)
phy_error(phydev);
- mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
-}
-
-/* PHY timer which schedules the state machine work */
-static void phy_timer(unsigned long data)
-{
- struct phy_device *phydev = (struct phy_device *)data;
-
- /*
- * PHY I/O operations can potentially sleep so we ensure that
- * it's done from a process context
- */
- schedule_work(&phydev->state_queue);
+ schedule_delayed_work(&phydev->state_queue,
+ jiffies + PHY_STATE_TIME * HZ);
}
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index c05d38d4635..5123bb954dd 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -81,6 +81,9 @@ static struct phy_driver lan83c185_driver = {
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
.driver = { .owner = THIS_MODULE, }
};
@@ -102,6 +105,9 @@ static struct phy_driver lan8187_driver = {
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
.driver = { .owner = THIS_MODULE, }
};
@@ -123,6 +129,9 @@ static struct phy_driver lan8700_driver = {
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
.driver = { .owner = THIS_MODULE, }
};
@@ -144,6 +153,33 @@ static struct phy_driver lan911x_int_driver = {
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
+ .driver = { .owner = THIS_MODULE, }
+};
+
+static struct phy_driver lan8710_driver = {
+ .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
+ .phy_id_mask = 0xfffffff0,
+ .name = "SMSC LAN8710/LAN8720",
+
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
+ | SUPPORTED_Asym_Pause),
+ .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
+
+ /* basic functions */
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+ .config_init = smsc_phy_config_init,
+
+ /* IRQ related */
+ .ack_interrupt = smsc_phy_ack_interrupt,
+ .config_intr = smsc_phy_config_intr,
+
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
.driver = { .owner = THIS_MODULE, }
};
@@ -167,8 +203,14 @@ static int __init smsc_init(void)
if (ret)
goto err4;
+ ret = phy_driver_register (&lan8710_driver);
+ if (ret)
+ goto err5;
+
return 0;
+err5:
+ phy_driver_unregister (&lan911x_int_driver);
err4:
phy_driver_unregister (&lan8700_driver);
err3:
@@ -181,6 +223,7 @@ err1:
static void __exit smsc_exit(void)
{
+ phy_driver_unregister (&lan8710_driver);
phy_driver_unregister (&lan911x_int_driver);
phy_driver_unregister (&lan8700_driver);
phy_driver_unregister (&lan8187_driver);
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 6567fabd2e1..6de8399d6dd 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -157,6 +157,7 @@ ppp_asynctty_open(struct tty_struct *tty)
{
struct asyncppp *ap;
int err;
+ int speed;
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
@@ -187,6 +188,8 @@ ppp_asynctty_open(struct tty_struct *tty)
ap->chan.private = ap;
ap->chan.ops = &async_ops;
ap->chan.mtu = PPP_MRU;
+ speed = tty_get_baud_rate(tty);
+ ap->chan.speed = speed;
err = ppp_register_channel(&ap->chan);
if (err)
goto out_free;
@@ -233,11 +236,9 @@ ppp_asynctty_close(struct tty_struct *tty)
tasklet_kill(&ap->tsk);
ppp_unregister_channel(&ap->chan);
- if (ap->rpkt)
- kfree_skb(ap->rpkt);
+ kfree_skb(ap->rpkt);
skb_queue_purge(&ap->rqueue);
- if (ap->tpkt)
- kfree_skb(ap->tpkt);
+ kfree_skb(ap->tpkt);
kfree(ap);
}
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 7b2728b8f1b..8ee91421db1 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -49,6 +49,10 @@
#include <net/slhc_vj.h>
#include <asm/atomic.h>
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
#define PPP_VERSION "2.4.2"
/*
@@ -131,6 +135,7 @@ struct ppp {
struct sock_filter *active_filter;/* filter for pkts to reset idle */
unsigned pass_len, active_len;
#endif /* CONFIG_PPP_FILTER */
+ struct net *ppp_net; /* the net we belong to */
};
/*
@@ -155,12 +160,14 @@ struct channel {
struct rw_semaphore chan_sem; /* protects `chan' during chan ioctl */
spinlock_t downl; /* protects `chan', file.xq dequeue */
struct ppp *ppp; /* ppp unit we're connected to */
+ struct net *chan_net; /* the net channel belongs to */
struct list_head clist; /* link in list of channels per unit */
rwlock_t upl; /* protects `ppp' */
#ifdef CONFIG_PPP_MULTILINK
u8 avail; /* flag used in multilink stuff */
u8 had_frag; /* >= 1 fragments have been sent */
u32 lastseq; /* MP: last sequence # received */
+ int speed; /* speed of the corresponding ppp channel*/
#endif /* CONFIG_PPP_MULTILINK */
};
@@ -173,26 +180,35 @@ struct channel {
* channel.downl.
*/
-/*
- * all_ppp_mutex protects the all_ppp_units mapping.
- * It also ensures that finding a ppp unit in the all_ppp_units map
- * and updating its file.refcnt field is atomic.
- */
-static DEFINE_MUTEX(all_ppp_mutex);
static atomic_t ppp_unit_count = ATOMIC_INIT(0);
-static DEFINE_IDR(ppp_units_idr);
-
-/*
- * all_channels_lock protects all_channels and last_channel_index,
- * and the atomicity of find a channel and updating its file.refcnt
- * field.
- */
-static DEFINE_SPINLOCK(all_channels_lock);
-static LIST_HEAD(all_channels);
-static LIST_HEAD(new_channels);
-static int last_channel_index;
static atomic_t channel_count = ATOMIC_INIT(0);
+/* per-net private data for this module */
+static int ppp_net_id;
+struct ppp_net {
+ /* units to ppp mapping */
+ struct idr units_idr;
+
+ /*
+ * all_ppp_mutex protects the units_idr mapping.
+ * It also ensures that finding a ppp unit in the units_idr
+ * map and updating its file.refcnt field is atomic.
+ */
+ struct mutex all_ppp_mutex;
+
+ /* channels */
+ struct list_head all_channels;
+ struct list_head new_channels;
+ int last_channel_index;
+
+ /*
+ * all_channels_lock protects all_channels and
+ * last_channel_index, and the atomicity of find
+ * a channel and updating its file.refcnt field.
+ */
+ spinlock_t all_channels_lock;
+};
+
/* Get the PPP protocol number from a skb */
#define PPP_PROTO(skb) (((skb)->data[0] << 8) + (skb)->data[1])
@@ -216,8 +232,8 @@ static atomic_t channel_count = ATOMIC_INIT(0);
#define seq_after(a, b) ((s32)((a) - (b)) > 0)
/* Prototypes. */
-static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
- unsigned int cmd, unsigned long arg);
+static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
+ struct file *file, unsigned int cmd, unsigned long arg);
static void ppp_xmit_process(struct ppp *ppp);
static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
static void ppp_push(struct ppp *ppp);
@@ -240,12 +256,12 @@ static void ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound);
static void ppp_ccp_closed(struct ppp *ppp);
static struct compressor *find_compressor(int type);
static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st);
-static struct ppp *ppp_create_interface(int unit, int *retp);
+static struct ppp *ppp_create_interface(struct net *net, int unit, int *retp);
static void init_ppp_file(struct ppp_file *pf, int kind);
static void ppp_shutdown_interface(struct ppp *ppp);
static void ppp_destroy_interface(struct ppp *ppp);
-static struct ppp *ppp_find_unit(int unit);
-static struct channel *ppp_find_channel(int unit);
+static struct ppp *ppp_find_unit(struct ppp_net *pn, int unit);
+static struct channel *ppp_find_channel(struct ppp_net *pn, int unit);
static int ppp_connect_channel(struct channel *pch, int unit);
static int ppp_disconnect_channel(struct channel *pch);
static void ppp_destroy_channel(struct channel *pch);
@@ -256,6 +272,14 @@ static void *unit_find(struct idr *p, int n);
static struct class *ppp_class;
+/* per net-namespace data */
+static inline struct ppp_net *ppp_pernet(struct net *net)
+{
+ BUG_ON(!net);
+
+ return net_generic(net, ppp_net_id);
+}
+
/* Translates a PPP protocol number to a NP index (NP == network protocol) */
static inline int proto_to_npindex(int proto)
{
@@ -544,7 +568,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int __user *p = argp;
if (!pf)
- return ppp_unattached_ioctl(pf, file, cmd, arg);
+ return ppp_unattached_ioctl(current->nsproxy->net_ns,
+ pf, file, cmd, arg);
if (cmd == PPPIOCDETACH) {
/*
@@ -763,12 +788,13 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return err;
}
-static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
+ struct file *file, unsigned int cmd, unsigned long arg)
{
int unit, err = -EFAULT;
struct ppp *ppp;
struct channel *chan;
+ struct ppp_net *pn;
int __user *p = (int __user *)arg;
lock_kernel();
@@ -777,7 +803,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
/* Create a new ppp unit */
if (get_user(unit, p))
break;
- ppp = ppp_create_interface(unit, &err);
+ ppp = ppp_create_interface(net, unit, &err);
if (!ppp)
break;
file->private_data = &ppp->file;
@@ -792,29 +818,31 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
/* Attach to an existing ppp unit */
if (get_user(unit, p))
break;
- mutex_lock(&all_ppp_mutex);
err = -ENXIO;
- ppp = ppp_find_unit(unit);
+ pn = ppp_pernet(net);
+ mutex_lock(&pn->all_ppp_mutex);
+ ppp = ppp_find_unit(pn, unit);
if (ppp) {
atomic_inc(&ppp->file.refcnt);
file->private_data = &ppp->file;
err = 0;
}
- mutex_unlock(&all_ppp_mutex);
+ mutex_unlock(&pn->all_ppp_mutex);
break;
case PPPIOCATTCHAN:
if (get_user(unit, p))
break;
- spin_lock_bh(&all_channels_lock);
err = -ENXIO;
- chan = ppp_find_channel(unit);
+ pn = ppp_pernet(net);
+ spin_lock_bh(&pn->all_channels_lock);
+ chan = ppp_find_channel(pn, unit);
if (chan) {
atomic_inc(&chan->file.refcnt);
file->private_data = &chan->file;
err = 0;
}
- spin_unlock_bh(&all_channels_lock);
+ spin_unlock_bh(&pn->all_channels_lock);
break;
default:
@@ -834,6 +862,51 @@ static const struct file_operations ppp_device_fops = {
.release = ppp_release
};
+static __net_init int ppp_init_net(struct net *net)
+{
+ struct ppp_net *pn;
+ int err;
+
+ pn = kzalloc(sizeof(*pn), GFP_KERNEL);
+ if (!pn)
+ return -ENOMEM;
+
+ idr_init(&pn->units_idr);
+ mutex_init(&pn->all_ppp_mutex);
+
+ INIT_LIST_HEAD(&pn->all_channels);
+ INIT_LIST_HEAD(&pn->new_channels);
+
+ spin_lock_init(&pn->all_channels_lock);
+
+ err = net_assign_generic(net, ppp_net_id, pn);
+ if (err) {
+ kfree(pn);
+ return err;
+ }
+
+ return 0;
+}
+
+static __net_exit void ppp_exit_net(struct net *net)
+{
+ struct ppp_net *pn;
+
+ pn = net_generic(net, ppp_net_id);
+ idr_destroy(&pn->units_idr);
+ /*
+ * if someone has cached our net then
+ * further net_generic call will return NULL
+ */
+ net_assign_generic(net, ppp_net_id, NULL);
+ kfree(pn);
+}
+
+static struct pernet_operations ppp_net_ops = {
+ .init = ppp_init_net,
+ .exit = ppp_exit_net,
+};
+
#define PPP_MAJOR 108
/* Called at boot time if ppp is compiled into the kernel,
@@ -843,25 +916,36 @@ static int __init ppp_init(void)
int err;
printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n");
- err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
- if (!err) {
- ppp_class = class_create(THIS_MODULE, "ppp");
- if (IS_ERR(ppp_class)) {
- err = PTR_ERR(ppp_class);
- goto out_chrdev;
- }
- device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL,
- "ppp");
+
+ err = register_pernet_gen_device(&ppp_net_id, &ppp_net_ops);
+ if (err) {
+ printk(KERN_ERR "failed to register PPP pernet device (%d)\n", err);
+ goto out;
}
-out:
- if (err)
+ err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
+ if (err) {
printk(KERN_ERR "failed to register PPP device (%d)\n", err);
- return err;
+ goto out_net;
+ }
+
+ ppp_class = class_create(THIS_MODULE, "ppp");
+ if (IS_ERR(ppp_class)) {
+ err = PTR_ERR(ppp_class);
+ goto out_chrdev;
+ }
+
+ /* not a big deal if we fail here :-) */
+ device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
+
+ return 0;
out_chrdev:
unregister_chrdev(PPP_MAJOR, "ppp");
- goto out;
+out_net:
+ unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
+out:
+ return err;
}
/*
@@ -908,7 +992,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
outf:
kfree_skb(skb);
- ++ppp->dev->stats.tx_dropped;
+ ++dev->stats.tx_dropped;
return 0;
}
@@ -969,6 +1053,7 @@ static void ppp_setup(struct net_device *dev)
dev->tx_queue_len = 3;
dev->type = ARPHRD_PPP;
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
+ dev->features |= NETIF_F_NETNS_LOCAL;
}
/*
@@ -1161,8 +1246,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
return;
drop:
- if (skb)
- kfree_skb(skb);
+ kfree_skb(skb);
++ppp->dev->stats.tx_errors;
}
@@ -1224,138 +1308,181 @@ ppp_push(struct ppp *ppp)
*/
static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
{
- int len, fragsize;
- int i, bits, hdrlen, mtu;
- int flen;
- int navail, nfree;
- int nbigger;
+ int len, totlen;
+ int i, bits, hdrlen, mtu;
+ int flen;
+ int navail, nfree, nzero;
+ int nbigger;
+ int totspeed;
+ int totfree;
unsigned char *p, *q;
struct list_head *list;
struct channel *pch;
struct sk_buff *frag;
struct ppp_channel *chan;
- nfree = 0; /* # channels which have no packet already queued */
+ totspeed = 0; /*total bitrate of the bundle*/
+ nfree = 0; /* # channels which have no packet already queued */
navail = 0; /* total # of usable channels (not deregistered) */
+ nzero = 0; /* number of channels with zero speed associated*/
+ totfree = 0; /*total # of channels available and
+ *having no queued packets before
+ *starting the fragmentation*/
+
hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
- i = 0;
- list_for_each_entry(pch, &ppp->channels, clist) {
+ i = 0;
+ list_for_each_entry(pch, &ppp->channels, clist) {
navail += pch->avail = (pch->chan != NULL);
- if (pch->avail) {
+ pch->speed = pch->chan->speed;
+ if (pch->avail) {
if (skb_queue_empty(&pch->file.xq) ||
- !pch->had_frag) {
- pch->avail = 2;
- ++nfree;
- }
- if (!pch->had_frag && i < ppp->nxchan)
- ppp->nxchan = i;
+ !pch->had_frag) {
+ if (pch->speed == 0)
+ nzero++;
+ else
+ totspeed += pch->speed;
+
+ pch->avail = 2;
+ ++nfree;
+ ++totfree;
+ }
+ if (!pch->had_frag && i < ppp->nxchan)
+ ppp->nxchan = i;
}
++i;
}
-
/*
- * Don't start sending this packet unless at least half of
- * the channels are free. This gives much better TCP
- * performance if we have a lot of channels.
+ * Don't start sending this packet unless at least half of
+ * the channels are free. This gives much better TCP
+ * performance if we have a lot of channels.
*/
- if (nfree == 0 || nfree < navail / 2)
- return 0; /* can't take now, leave it in xmit_pending */
+ if (nfree == 0 || nfree < navail / 2)
+ return 0; /* can't take now, leave it in xmit_pending */
/* Do protocol field compression (XXX this should be optional) */
- p = skb->data;
- len = skb->len;
+ p = skb->data;
+ len = skb->len;
if (*p == 0) {
++p;
--len;
}
- /*
- * Decide on fragment size.
- * We create a fragment for each free channel regardless of
- * how small they are (i.e. even 0 length) in order to minimize
- * the time that it will take to detect when a channel drops
- * a fragment.
- */
- fragsize = len;
- if (nfree > 1)
- fragsize = DIV_ROUND_UP(fragsize, nfree);
- /* nbigger channels get fragsize bytes, the rest get fragsize-1,
- except if nbigger==0, then they all get fragsize. */
- nbigger = len % nfree;
-
- /* skip to the channel after the one we last used
- and start at that one */
+ totlen = len;
+ nbigger = len % nfree;
+
+ /* skip to the channel after the one we last used
+ and start at that one */
list = &ppp->channels;
- for (i = 0; i < ppp->nxchan; ++i) {
+ for (i = 0; i < ppp->nxchan; ++i) {
list = list->next;
- if (list == &ppp->channels) {
- i = 0;
+ if (list == &ppp->channels) {
+ i = 0;
break;
}
}
- /* create a fragment for each channel */
+ /* create a fragment for each channel */
bits = B;
- while (nfree > 0 || len > 0) {
+ while (nfree > 0 && len > 0) {
list = list->next;
- if (list == &ppp->channels) {
- i = 0;
+ if (list == &ppp->channels) {
+ i = 0;
continue;
}
- pch = list_entry(list, struct channel, clist);
+ pch = list_entry(list, struct channel, clist);
++i;
if (!pch->avail)
continue;
/*
- * Skip this channel if it has a fragment pending already and
- * we haven't given a fragment to all of the free channels.
+ * Skip this channel if it has a fragment pending already and
+ * we haven't given a fragment to all of the free channels.
*/
if (pch->avail == 1) {
- if (nfree > 0)
+ if (nfree > 0)
continue;
} else {
- --nfree;
pch->avail = 1;
}
/* check the channel's mtu and whether it is still attached. */
spin_lock_bh(&pch->downl);
if (pch->chan == NULL) {
- /* can't use this channel, it's being deregistered */
+ /* can't use this channel, it's being deregistered */
+ if (pch->speed == 0)
+ nzero--;
+ else
+ totspeed -= pch->speed;
+
spin_unlock_bh(&pch->downl);
pch->avail = 0;
- if (--navail == 0)
+ totlen = len;
+ totfree--;
+ nfree--;
+ if (--navail == 0)
break;
continue;
}
/*
- * Create a fragment for this channel of
- * min(max(mtu+2-hdrlen, 4), fragsize, len) bytes.
- * If mtu+2-hdrlen < 4, that is a ridiculously small
- * MTU, so we use mtu = 2 + hdrlen.
+ *if the channel speed is not set divide
+ *the packet evenly among the free channels;
+ *otherwise divide it according to the speed
+ *of the channel we are going to transmit on
+ */
+ if (pch->speed == 0) {
+ flen = totlen/nfree ;
+ if (nbigger > 0) {
+ flen++;
+ nbigger--;
+ }
+ } else {
+ flen = (((totfree - nzero)*(totlen + hdrlen*totfree)) /
+ ((totspeed*totfree)/pch->speed)) - hdrlen;
+ if (nbigger > 0) {
+ flen += ((totfree - nzero)*pch->speed)/totspeed;
+ nbigger -= ((totfree - nzero)*pch->speed)/
+ totspeed;
+ }
+ }
+ nfree--;
+
+ /*
+ *check if we are on the last channel or
+ *we exceded the lenght of the data to
+ *fragment
*/
- if (fragsize > len)
- fragsize = len;
- flen = fragsize;
- mtu = pch->chan->mtu + 2 - hdrlen;
- if (mtu < 4)
- mtu = 4;
+ if ((nfree == 0) || (flen > len))
+ flen = len;
+ /*
+ *it is not worth to tx on slow channels:
+ *in that case from the resulting flen according to the
+ *above formula will be equal or less than zero.
+ *Skip the channel in this case
+ */
+ if (flen <= 0) {
+ pch->avail = 2;
+ spin_unlock_bh(&pch->downl);
+ continue;
+ }
+
+ mtu = pch->chan->mtu + 2 - hdrlen;
+ if (mtu < 4)
+ mtu = 4;
if (flen > mtu)
flen = mtu;
- if (flen == len && nfree == 0)
- bits |= E;
- frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
+ if (flen == len)
+ bits |= E;
+ frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
if (!frag)
goto noskb;
- q = skb_put(frag, flen + hdrlen);
+ q = skb_put(frag, flen + hdrlen);
- /* make the MP header */
+ /* make the MP header */
q[0] = PPP_MP >> 8;
q[1] = PPP_MP;
if (ppp->flags & SC_MP_XSHORTSEQ) {
- q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
+ q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
q[3] = ppp->nxseq;
} else {
q[2] = bits;
@@ -1364,43 +1491,28 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
q[5] = ppp->nxseq;
}
- /*
- * Copy the data in.
- * Unfortunately there is a bug in older versions of
- * the Linux PPP multilink reconstruction code where it
- * drops 0-length fragments. Therefore we make sure the
- * fragment has at least one byte of data. Any bytes
- * we add in this situation will end up as padding on the
- * end of the reconstructed packet.
- */
- if (flen == 0)
- *skb_put(frag, 1) = 0;
- else
- memcpy(q + hdrlen, p, flen);
+ memcpy(q + hdrlen, p, flen);
/* try to send it down the channel */
chan = pch->chan;
- if (!skb_queue_empty(&pch->file.xq) ||
- !chan->ops->start_xmit(chan, frag))
+ if (!skb_queue_empty(&pch->file.xq) ||
+ !chan->ops->start_xmit(chan, frag))
skb_queue_tail(&pch->file.xq, frag);
- pch->had_frag = 1;
+ pch->had_frag = 1;
p += flen;
- len -= flen;
+ len -= flen;
++ppp->nxseq;
bits = 0;
spin_unlock_bh(&pch->downl);
-
- if (--nbigger == 0 && fragsize > 0)
- --fragsize;
}
- ppp->nxchan = i;
+ ppp->nxchan = i;
return 1;
noskb:
spin_unlock_bh(&pch->downl);
if (ppp->debug & 1)
- printk(KERN_ERR "PPP: no memory (fragment)\n");
+ printk(KERN_ERR "PPP: no memory (fragment)\n");
++ppp->dev->stats.tx_errors;
++ppp->nxseq;
return 1; /* abandon the frame */
@@ -1986,19 +2098,27 @@ ppp_mp_reconstruct(struct ppp *ppp)
* Channel interface.
*/
-/*
- * Create a new, unattached ppp channel.
- */
-int
-ppp_register_channel(struct ppp_channel *chan)
+/* Create a new, unattached ppp channel. */
+int ppp_register_channel(struct ppp_channel *chan)
+{
+ return ppp_register_net_channel(current->nsproxy->net_ns, chan);
+}
+
+/* Create a new, unattached ppp channel for specified net. */
+int ppp_register_net_channel(struct net *net, struct ppp_channel *chan)
{
struct channel *pch;
+ struct ppp_net *pn;
pch = kzalloc(sizeof(struct channel), GFP_KERNEL);
if (!pch)
return -ENOMEM;
+
+ pn = ppp_pernet(net);
+
pch->ppp = NULL;
pch->chan = chan;
+ pch->chan_net = net;
chan->ppp = pch;
init_ppp_file(&pch->file, CHANNEL);
pch->file.hdrlen = chan->hdrlen;
@@ -2008,11 +2128,13 @@ ppp_register_channel(struct ppp_channel *chan)
init_rwsem(&pch->chan_sem);
spin_lock_init(&pch->downl);
rwlock_init(&pch->upl);
- spin_lock_bh(&all_channels_lock);
- pch->file.index = ++last_channel_index;
- list_add(&pch->list, &new_channels);
+
+ spin_lock_bh(&pn->all_channels_lock);
+ pch->file.index = ++pn->last_channel_index;
+ list_add(&pch->list, &pn->new_channels);
atomic_inc(&channel_count);
- spin_unlock_bh(&all_channels_lock);
+ spin_unlock_bh(&pn->all_channels_lock);
+
return 0;
}
@@ -2053,9 +2175,11 @@ void
ppp_unregister_channel(struct ppp_channel *chan)
{
struct channel *pch = chan->ppp;
+ struct ppp_net *pn;
if (!pch)
return; /* should never happen */
+
chan->ppp = NULL;
/*
@@ -2068,9 +2192,12 @@ ppp_unregister_channel(struct ppp_channel *chan)
spin_unlock_bh(&pch->downl);
up_write(&pch->chan_sem);
ppp_disconnect_channel(pch);
- spin_lock_bh(&all_channels_lock);
+
+ pn = ppp_pernet(pch->chan_net);
+ spin_lock_bh(&pn->all_channels_lock);
list_del(&pch->list);
- spin_unlock_bh(&all_channels_lock);
+ spin_unlock_bh(&pn->all_channels_lock);
+
pch->file.dead = 1;
wake_up_interruptible(&pch->file.rwait);
if (atomic_dec_and_test(&pch->file.refcnt))
@@ -2395,9 +2522,10 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
* unit == -1 means allocate a new number.
*/
static struct ppp *
-ppp_create_interface(int unit, int *retp)
+ppp_create_interface(struct net *net, int unit, int *retp)
{
struct ppp *ppp;
+ struct ppp_net *pn;
struct net_device *dev = NULL;
int ret = -ENOMEM;
int i;
@@ -2406,6 +2534,8 @@ ppp_create_interface(int unit, int *retp)
if (!dev)
goto out1;
+ pn = ppp_pernet(net);
+
ppp = netdev_priv(dev);
ppp->dev = dev;
ppp->mru = PPP_MRU;
@@ -2421,17 +2551,23 @@ ppp_create_interface(int unit, int *retp)
skb_queue_head_init(&ppp->mrq);
#endif /* CONFIG_PPP_MULTILINK */
+ /*
+ * drum roll: don't forget to set
+ * the net device is belong to
+ */
+ dev_net_set(dev, net);
+
ret = -EEXIST;
- mutex_lock(&all_ppp_mutex);
+ mutex_lock(&pn->all_ppp_mutex);
if (unit < 0) {
- unit = unit_get(&ppp_units_idr, ppp);
+ unit = unit_get(&pn->units_idr, ppp);
if (unit < 0) {
*retp = unit;
goto out2;
}
} else {
- if (unit_find(&ppp_units_idr, unit))
+ if (unit_find(&pn->units_idr, unit))
goto out2; /* unit already exists */
/*
* if caller need a specified unit number
@@ -2442,7 +2578,7 @@ ppp_create_interface(int unit, int *retp)
* fair but at least pppd will ask us to allocate
* new unit in this case so user is happy :)
*/
- unit = unit_set(&ppp_units_idr, ppp, unit);
+ unit = unit_set(&pn->units_idr, ppp, unit);
if (unit < 0)
goto out2;
}
@@ -2453,20 +2589,22 @@ ppp_create_interface(int unit, int *retp)
ret = register_netdev(dev);
if (ret != 0) {
- unit_put(&ppp_units_idr, unit);
+ unit_put(&pn->units_idr, unit);
printk(KERN_ERR "PPP: couldn't register device %s (%d)\n",
dev->name, ret);
goto out2;
}
+ ppp->ppp_net = net;
+
atomic_inc(&ppp_unit_count);
- mutex_unlock(&all_ppp_mutex);
+ mutex_unlock(&pn->all_ppp_mutex);
*retp = 0;
return ppp;
out2:
- mutex_unlock(&all_ppp_mutex);
+ mutex_unlock(&pn->all_ppp_mutex);
free_netdev(dev);
out1:
*retp = ret;
@@ -2492,7 +2630,11 @@ init_ppp_file(struct ppp_file *pf, int kind)
*/
static void ppp_shutdown_interface(struct ppp *ppp)
{
- mutex_lock(&all_ppp_mutex);
+ struct ppp_net *pn;
+
+ pn = ppp_pernet(ppp->ppp_net);
+ mutex_lock(&pn->all_ppp_mutex);
+
/* This will call dev_close() for us. */
ppp_lock(ppp);
if (!ppp->closing) {
@@ -2502,11 +2644,12 @@ static void ppp_shutdown_interface(struct ppp *ppp)
} else
ppp_unlock(ppp);
- unit_put(&ppp_units_idr, ppp->file.index);
+ unit_put(&pn->units_idr, ppp->file.index);
ppp->file.dead = 1;
ppp->owner = NULL;
wake_up_interruptible(&ppp->file.rwait);
- mutex_unlock(&all_ppp_mutex);
+
+ mutex_unlock(&pn->all_ppp_mutex);
}
/*
@@ -2543,8 +2686,7 @@ static void ppp_destroy_interface(struct ppp *ppp)
ppp->active_filter = NULL;
#endif /* CONFIG_PPP_FILTER */
- if (ppp->xmit_pending)
- kfree_skb(ppp->xmit_pending);
+ kfree_skb(ppp->xmit_pending);
free_netdev(ppp->dev);
}
@@ -2554,9 +2696,9 @@ static void ppp_destroy_interface(struct ppp *ppp)
* The caller should have locked the all_ppp_mutex.
*/
static struct ppp *
-ppp_find_unit(int unit)
+ppp_find_unit(struct ppp_net *pn, int unit)
{
- return unit_find(&ppp_units_idr, unit);
+ return unit_find(&pn->units_idr, unit);
}
/*
@@ -2568,20 +2710,22 @@ ppp_find_unit(int unit)
* when we have a lot of channels in use.
*/
static struct channel *
-ppp_find_channel(int unit)
+ppp_find_channel(struct ppp_net *pn, int unit)
{
struct channel *pch;
- list_for_each_entry(pch, &new_channels, list) {
+ list_for_each_entry(pch, &pn->new_channels, list) {
if (pch->file.index == unit) {
- list_move(&pch->list, &all_channels);
+ list_move(&pch->list, &pn->all_channels);
return pch;
}
}
- list_for_each_entry(pch, &all_channels, list) {
+
+ list_for_each_entry(pch, &pn->all_channels, list) {
if (pch->file.index == unit)
return pch;
}
+
return NULL;
}
@@ -2592,11 +2736,14 @@ static int
ppp_connect_channel(struct channel *pch, int unit)
{
struct ppp *ppp;
+ struct ppp_net *pn;
int ret = -ENXIO;
int hdrlen;
- mutex_lock(&all_ppp_mutex);
- ppp = ppp_find_unit(unit);
+ pn = ppp_pernet(pch->chan_net);
+
+ mutex_lock(&pn->all_ppp_mutex);
+ ppp = ppp_find_unit(pn, unit);
if (!ppp)
goto out;
write_lock_bh(&pch->upl);
@@ -2620,7 +2767,7 @@ ppp_connect_channel(struct channel *pch, int unit)
outl:
write_unlock_bh(&pch->upl);
out:
- mutex_unlock(&all_ppp_mutex);
+ mutex_unlock(&pn->all_ppp_mutex);
return ret;
}
@@ -2677,7 +2824,7 @@ static void __exit ppp_cleanup(void)
unregister_chrdev(PPP_MAJOR, "ppp");
device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
class_destroy(ppp_class);
- idr_destroy(&ppp_units_idr);
+ unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
}
/*
@@ -2743,6 +2890,7 @@ static void *unit_find(struct idr *p, int n)
module_init(ppp_init);
module_exit(ppp_cleanup);
+EXPORT_SYMBOL(ppp_register_net_channel);
EXPORT_SYMBOL(ppp_register_channel);
EXPORT_SYMBOL(ppp_unregister_channel);
EXPORT_SYMBOL(ppp_channel_index);
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 1e892b7b1f8..d2fa2db1358 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -206,6 +206,7 @@ ppp_sync_open(struct tty_struct *tty)
{
struct syncppp *ap;
int err;
+ int speed;
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
@@ -234,6 +235,8 @@ ppp_sync_open(struct tty_struct *tty)
ap->chan.ops = &sync_ops;
ap->chan.mtu = PPP_MRU;
ap->chan.hdrlen = 2; /* for A/C bytes */
+ speed = tty_get_baud_rate(tty);
+ ap->chan.speed = speed;
err = ppp_register_channel(&ap->chan);
if (err)
goto out_free;
@@ -281,8 +284,7 @@ ppp_sync_close(struct tty_struct *tty)
ppp_unregister_channel(&ap->chan);
skb_queue_purge(&ap->rqueue);
- if (ap->tpkt)
- kfree_skb(ap->tpkt);
+ kfree_skb(ap->tpkt);
kfree(ap);
}
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index c22b30533a1..f0031f1f97e 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -78,38 +78,73 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/nsproxy.h>
#include <net/net_namespace.h>
+#include <net/netns/generic.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#define PPPOE_HASH_BITS 4
-#define PPPOE_HASH_SIZE (1<<PPPOE_HASH_BITS)
-
-static struct ppp_channel_ops pppoe_chan_ops;
+#define PPPOE_HASH_SIZE (1 << PPPOE_HASH_BITS)
+#define PPPOE_HASH_MASK (PPPOE_HASH_SIZE - 1)
static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb);
static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
static const struct proto_ops pppoe_ops;
-static DEFINE_RWLOCK(pppoe_hash_lock);
-
static struct ppp_channel_ops pppoe_chan_ops;
+/* per-net private data for this module */
+static int pppoe_net_id;
+struct pppoe_net {
+ /*
+ * we could use _single_ hash table for all
+ * nets by injecting net id into the hash but
+ * it would increase hash chains and add
+ * a few additional math comparations messy
+ * as well, moreover in case of SMP less locking
+ * controversy here
+ */
+ struct pppox_sock *hash_table[PPPOE_HASH_SIZE];
+ rwlock_t hash_lock;
+};
+
+/* to eliminate a race btw pppoe_flush_dev and pppoe_release */
+static DEFINE_SPINLOCK(flush_lock);
+
+/*
+ * PPPoE could be in the following stages:
+ * 1) Discovery stage (to obtain remote MAC and Session ID)
+ * 2) Session stage (MAC and SID are known)
+ *
+ * Ethernet frames have a special tag for this but
+ * we use simplier approach based on session id
+ */
+static inline bool stage_session(__be16 sid)
+{
+ return sid != 0;
+}
+
+static inline struct pppoe_net *pppoe_pernet(struct net *net)
+{
+ BUG_ON(!net);
+
+ return net_generic(net, pppoe_net_id);
+}
+
static inline int cmp_2_addr(struct pppoe_addr *a, struct pppoe_addr *b)
{
- return (a->sid == b->sid &&
- (memcmp(a->remote, b->remote, ETH_ALEN) == 0));
+ return a->sid == b->sid && !memcmp(a->remote, b->remote, ETH_ALEN);
}
static inline int cmp_addr(struct pppoe_addr *a, __be16 sid, char *addr)
{
- return (a->sid == sid &&
- (memcmp(a->remote,addr,ETH_ALEN) == 0));
+ return a->sid == sid && !memcmp(a->remote, addr, ETH_ALEN);
}
-#if 8%PPPOE_HASH_BITS
+#if 8 % PPPOE_HASH_BITS
#error 8 must be a multiple of PPPOE_HASH_BITS
#endif
@@ -118,69 +153,71 @@ static int hash_item(__be16 sid, unsigned char *addr)
unsigned char hash = 0;
unsigned int i;
- for (i = 0 ; i < ETH_ALEN ; i++) {
+ for (i = 0; i < ETH_ALEN; i++)
hash ^= addr[i];
- }
- for (i = 0 ; i < sizeof(sid_t)*8 ; i += 8 ){
- hash ^= (__force __u32)sid>>i;
- }
- for (i = 8 ; (i>>=1) >= PPPOE_HASH_BITS ; ) {
- hash ^= hash>>i;
- }
+ for (i = 0; i < sizeof(sid_t) * 8; i += 8)
+ hash ^= (__force __u32)sid >> i;
+ for (i = 8; (i >>= 1) >= PPPOE_HASH_BITS;)
+ hash ^= hash >> i;
- return hash & ( PPPOE_HASH_SIZE - 1 );
+ return hash & PPPOE_HASH_MASK;
}
-/* zeroed because its in .bss */
-static struct pppox_sock *item_hash_table[PPPOE_HASH_SIZE];
-
/**********************************************************************
*
* Set/get/delete/rehash items (internal versions)
*
**********************************************************************/
-static struct pppox_sock *__get_item(__be16 sid, unsigned char *addr, int ifindex)
+static struct pppox_sock *__get_item(struct pppoe_net *pn, __be16 sid,
+ unsigned char *addr, int ifindex)
{
int hash = hash_item(sid, addr);
struct pppox_sock *ret;
- ret = item_hash_table[hash];
+ ret = pn->hash_table[hash];
+ while (ret) {
+ if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
+ ret->pppoe_ifindex == ifindex)
+ return ret;
- while (ret && !(cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_ifindex == ifindex))
ret = ret->next;
+ }
- return ret;
+ return NULL;
}
-static int __set_item(struct pppox_sock *po)
+static int __set_item(struct pppoe_net *pn, struct pppox_sock *po)
{
int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
struct pppox_sock *ret;
- ret = item_hash_table[hash];
+ ret = pn->hash_table[hash];
while (ret) {
- if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) && ret->pppoe_ifindex == po->pppoe_ifindex)
+ if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) &&
+ ret->pppoe_ifindex == po->pppoe_ifindex)
return -EALREADY;
ret = ret->next;
}
- po->next = item_hash_table[hash];
- item_hash_table[hash] = po;
+ po->next = pn->hash_table[hash];
+ pn->hash_table[hash] = po;
return 0;
}
-static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex)
+static struct pppox_sock *__delete_item(struct pppoe_net *pn, __be16 sid,
+ char *addr, int ifindex)
{
int hash = hash_item(sid, addr);
struct pppox_sock *ret, **src;
- ret = item_hash_table[hash];
- src = &item_hash_table[hash];
+ ret = pn->hash_table[hash];
+ src = &pn->hash_table[hash];
while (ret) {
- if (cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_ifindex == ifindex) {
+ if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
+ ret->pppoe_ifindex == ifindex) {
*src = ret->next;
break;
}
@@ -197,46 +234,54 @@ static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex)
* Set/get/delete/rehash items
*
**********************************************************************/
-static inline struct pppox_sock *get_item(__be16 sid,
- unsigned char *addr, int ifindex)
+static inline struct pppox_sock *get_item(struct pppoe_net *pn, __be16 sid,
+ unsigned char *addr, int ifindex)
{
struct pppox_sock *po;
- read_lock_bh(&pppoe_hash_lock);
- po = __get_item(sid, addr, ifindex);
+ read_lock_bh(&pn->hash_lock);
+ po = __get_item(pn, sid, addr, ifindex);
if (po)
sock_hold(sk_pppox(po));
- read_unlock_bh(&pppoe_hash_lock);
+ read_unlock_bh(&pn->hash_lock);
return po;
}
-static inline struct pppox_sock *get_item_by_addr(struct sockaddr_pppox *sp)
+static inline struct pppox_sock *get_item_by_addr(struct net *net,
+ struct sockaddr_pppox *sp)
{
struct net_device *dev;
+ struct pppoe_net *pn;
+ struct pppox_sock *pppox_sock;
+
int ifindex;
- dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
- if(!dev)
+ dev = dev_get_by_name(net, sp->sa_addr.pppoe.dev);
+ if (!dev)
return NULL;
+
ifindex = dev->ifindex;
+ pn = net_generic(net, pppoe_net_id);
+ pppox_sock = get_item(pn, sp->sa_addr.pppoe.sid,
+ sp->sa_addr.pppoe.remote, ifindex);
dev_put(dev);
- return get_item(sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote, ifindex);
+
+ return pppox_sock;
}
-static inline struct pppox_sock *delete_item(__be16 sid, char *addr, int ifindex)
+static inline struct pppox_sock *delete_item(struct pppoe_net *pn, __be16 sid,
+ char *addr, int ifindex)
{
struct pppox_sock *ret;
- write_lock_bh(&pppoe_hash_lock);
- ret = __delete_item(sid, addr, ifindex);
- write_unlock_bh(&pppoe_hash_lock);
+ write_lock_bh(&pn->hash_lock);
+ ret = __delete_item(pn, sid, addr, ifindex);
+ write_unlock_bh(&pn->hash_lock);
return ret;
}
-
-
/***************************************************************************
*
* Handler for device events.
@@ -246,25 +291,33 @@ static inline struct pppox_sock *delete_item(__be16 sid, char *addr, int ifindex
static void pppoe_flush_dev(struct net_device *dev)
{
- int hash;
+ struct pppoe_net *pn;
+ int i;
+
BUG_ON(dev == NULL);
- write_lock_bh(&pppoe_hash_lock);
- for (hash = 0; hash < PPPOE_HASH_SIZE; hash++) {
- struct pppox_sock *po = item_hash_table[hash];
+ pn = pppoe_pernet(dev_net(dev));
+ if (!pn) /* already freed */
+ return;
+
+ write_lock_bh(&pn->hash_lock);
+ for (i = 0; i < PPPOE_HASH_SIZE; i++) {
+ struct pppox_sock *po = pn->hash_table[i];
while (po != NULL) {
- struct sock *sk = sk_pppox(po);
+ struct sock *sk;
if (po->pppoe_dev != dev) {
po = po->next;
continue;
}
+ sk = sk_pppox(po);
+ spin_lock(&flush_lock);
po->pppoe_dev = NULL;
+ spin_unlock(&flush_lock);
dev_put(dev);
-
/* We always grab the socket lock, followed by the
- * pppoe_hash_lock, in that order. Since we should
+ * hash_lock, in that order. Since we should
* hold the sock lock while doing any unbinding,
* we need to release the lock we're holding.
* Hold a reference to the sock so it doesn't disappear
@@ -273,7 +326,7 @@ static void pppoe_flush_dev(struct net_device *dev)
sock_hold(sk);
- write_unlock_bh(&pppoe_hash_lock);
+ write_unlock_bh(&pn->hash_lock);
lock_sock(sk);
if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
@@ -289,20 +342,17 @@ static void pppoe_flush_dev(struct net_device *dev)
* While the lock was dropped the chain contents may
* have changed.
*/
- write_lock_bh(&pppoe_hash_lock);
- po = item_hash_table[hash];
+ write_lock_bh(&pn->hash_lock);
+ po = pn->hash_table[i];
}
}
- write_unlock_bh(&pppoe_hash_lock);
+ write_unlock_bh(&pn->hash_lock);
}
static int pppoe_device_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
- struct net_device *dev = (struct net_device *) ptr;
-
- if (dev_net(dev) != &init_net)
- return NOTIFY_DONE;
+ struct net_device *dev = (struct net_device *)ptr;
/* Only look at sockets that are using this specific device. */
switch (event) {
@@ -324,12 +374,10 @@ static int pppoe_device_event(struct notifier_block *this,
return NOTIFY_DONE;
}
-
static struct notifier_block pppoe_notifier = {
.notifier_call = pppoe_device_event,
};
-
/************************************************************************
*
* Do the real work of receiving a PPPoE Session frame.
@@ -343,8 +391,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
if (sk->sk_state & PPPOX_BOUND) {
ppp_input(&po->chan, skb);
} else if (sk->sk_state & PPPOX_RELAY) {
- relay_po = get_item_by_addr(&po->pppoe_relay);
-
+ relay_po = get_item_by_addr(dev_net(po->pppoe_dev),
+ &po->pppoe_relay);
if (relay_po == NULL)
goto abort_kfree;
@@ -373,22 +421,18 @@ abort_kfree:
* Receive wrapper called in BH context.
*
***********************************************************************/
-static int pppoe_rcv(struct sk_buff *skb,
- struct net_device *dev,
- struct packet_type *pt,
- struct net_device *orig_dev)
-
+static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt, struct net_device *orig_dev)
{
struct pppoe_hdr *ph;
struct pppox_sock *po;
+ struct pppoe_net *pn;
int len;
- if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (!skb)
goto out;
- if (dev_net(dev) != &init_net)
- goto drop;
-
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
goto drop;
@@ -402,7 +446,8 @@ static int pppoe_rcv(struct sk_buff *skb,
if (pskb_trim_rcsum(skb, len))
goto drop;
- po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
+ pn = pppoe_pernet(dev_net(dev));
+ po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
if (!po)
goto drop;
@@ -420,19 +465,16 @@ out:
* This is solely for detection of PADT frames
*
***********************************************************************/
-static int pppoe_disc_rcv(struct sk_buff *skb,
- struct net_device *dev,
- struct packet_type *pt,
- struct net_device *orig_dev)
+static int pppoe_disc_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt, struct net_device *orig_dev)
{
struct pppoe_hdr *ph;
struct pppox_sock *po;
+ struct pppoe_net *pn;
- if (dev_net(dev) != &init_net)
- goto abort;
-
- if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (!skb)
goto out;
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
@@ -442,7 +484,8 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
if (ph->code != PADT_CODE)
goto abort;
- po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
+ pn = pppoe_pernet(dev_net(dev));
+ po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
if (po) {
struct sock *sk = sk_pppox(po);
@@ -470,17 +513,17 @@ out:
return NET_RX_SUCCESS; /* Lies... :-) */
}
-static struct packet_type pppoes_ptype = {
- .type = __constant_htons(ETH_P_PPP_SES),
+static struct packet_type pppoes_ptype __read_mostly = {
+ .type = cpu_to_be16(ETH_P_PPP_SES),
.func = pppoe_rcv,
};
-static struct packet_type pppoed_ptype = {
- .type = __constant_htons(ETH_P_PPP_DISC),
+static struct packet_type pppoed_ptype __read_mostly = {
+ .type = cpu_to_be16(ETH_P_PPP_DISC),
.func = pppoe_disc_rcv,
};
-static struct proto pppoe_sk_proto = {
+static struct proto pppoe_sk_proto __read_mostly = {
.name = "PPPOE",
.owner = THIS_MODULE,
.obj_size = sizeof(struct pppox_sock),
@@ -493,38 +536,37 @@ static struct proto pppoe_sk_proto = {
**********************************************************************/
static int pppoe_create(struct net *net, struct socket *sock)
{
- int error = -ENOMEM;
struct sock *sk;
sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto);
if (!sk)
- goto out;
+ return -ENOMEM;
sock_init_data(sock, sk);
- sock->state = SS_UNCONNECTED;
- sock->ops = &pppoe_ops;
+ sock->state = SS_UNCONNECTED;
+ sock->ops = &pppoe_ops;
- sk->sk_backlog_rcv = pppoe_rcv_core;
- sk->sk_state = PPPOX_NONE;
- sk->sk_type = SOCK_STREAM;
- sk->sk_family = PF_PPPOX;
- sk->sk_protocol = PX_PROTO_OE;
+ sk->sk_backlog_rcv = pppoe_rcv_core;
+ sk->sk_state = PPPOX_NONE;
+ sk->sk_type = SOCK_STREAM;
+ sk->sk_family = PF_PPPOX;
+ sk->sk_protocol = PX_PROTO_OE;
- error = 0;
-out: return error;
+ return 0;
}
static int pppoe_release(struct socket *sock)
{
struct sock *sk = sock->sk;
struct pppox_sock *po;
+ struct pppoe_net *pn;
if (!sk)
return 0;
lock_sock(sk);
- if (sock_flag(sk, SOCK_DEAD)){
+ if (sock_flag(sk, SOCK_DEAD)) {
release_sock(sk);
return -EBADF;
}
@@ -534,26 +576,39 @@ static int pppoe_release(struct socket *sock)
/* Signal the death of the socket. */
sk->sk_state = PPPOX_DEAD;
+ /*
+ * pppoe_flush_dev could lead to a race with
+ * this routine so we use flush_lock to eliminate
+ * such a case (we only need per-net specific data)
+ */
+ spin_lock(&flush_lock);
+ po = pppox_sk(sk);
+ if (!po->pppoe_dev) {
+ spin_unlock(&flush_lock);
+ goto out;
+ }
+ pn = pppoe_pernet(dev_net(po->pppoe_dev));
+ spin_unlock(&flush_lock);
- /* Write lock on hash lock protects the entire "po" struct from
- * concurrent updates via pppoe_flush_dev. The "po" struct should
- * be considered part of the hash table contents, thus protected
- * by the hash table lock */
- write_lock_bh(&pppoe_hash_lock);
+ /*
+ * protect "po" from concurrent updates
+ * on pppoe_flush_dev
+ */
+ write_lock_bh(&pn->hash_lock);
po = pppox_sk(sk);
- if (po->pppoe_pa.sid) {
- __delete_item(po->pppoe_pa.sid,
- po->pppoe_pa.remote, po->pppoe_ifindex);
- }
+ if (stage_session(po->pppoe_pa.sid))
+ __delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote,
+ po->pppoe_ifindex);
if (po->pppoe_dev) {
dev_put(po->pppoe_dev);
po->pppoe_dev = NULL;
}
- write_unlock_bh(&pppoe_hash_lock);
+ write_unlock_bh(&pn->hash_lock);
+out:
sock_orphan(sk);
sock->sk = NULL;
@@ -564,14 +619,14 @@ static int pppoe_release(struct socket *sock)
return 0;
}
-
static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
int sockaddr_len, int flags)
{
struct sock *sk = sock->sk;
- struct net_device *dev;
- struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ struct sockaddr_pppox *sp = (struct sockaddr_pppox *)uservaddr;
struct pppox_sock *po = pppox_sk(sk);
+ struct net_device *dev;
+ struct pppoe_net *pn;
int error;
lock_sock(sk);
@@ -582,44 +637,45 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
/* Check for already bound sockets */
error = -EBUSY;
- if ((sk->sk_state & PPPOX_CONNECTED) && sp->sa_addr.pppoe.sid)
+ if ((sk->sk_state & PPPOX_CONNECTED) &&
+ stage_session(sp->sa_addr.pppoe.sid))
goto end;
/* Check for already disconnected sockets, on attempts to disconnect */
error = -EALREADY;
- if ((sk->sk_state & PPPOX_DEAD) && !sp->sa_addr.pppoe.sid )
+ if ((sk->sk_state & PPPOX_DEAD) &&
+ !stage_session(sp->sa_addr.pppoe.sid))
goto end;
error = 0;
- if (po->pppoe_pa.sid) {
- pppox_unbind_sock(sk);
-
- /* Delete the old binding */
- delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote,po->pppoe_ifindex);
- if(po->pppoe_dev)
+ /* Delete the old binding */
+ if (stage_session(po->pppoe_pa.sid)) {
+ pppox_unbind_sock(sk);
+ if (po->pppoe_dev) {
+ pn = pppoe_pernet(dev_net(po->pppoe_dev));
+ delete_item(pn, po->pppoe_pa.sid,
+ po->pppoe_pa.remote, po->pppoe_ifindex);
dev_put(po->pppoe_dev);
-
+ }
memset(sk_pppox(po) + 1, 0,
sizeof(struct pppox_sock) - sizeof(struct sock));
-
sk->sk_state = PPPOX_NONE;
}
- /* Don't re-bind if sid==0 */
- if (sp->sa_addr.pppoe.sid != 0) {
- dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
-
+ /* Re-bind in session stage only */
+ if (stage_session(sp->sa_addr.pppoe.sid)) {
error = -ENODEV;
+ dev = dev_get_by_name(sock_net(sk), sp->sa_addr.pppoe.dev);
if (!dev)
goto end;
po->pppoe_dev = dev;
po->pppoe_ifindex = dev->ifindex;
-
- write_lock_bh(&pppoe_hash_lock);
- if (!(dev->flags & IFF_UP)){
- write_unlock_bh(&pppoe_hash_lock);
+ pn = pppoe_pernet(dev_net(dev));
+ write_lock_bh(&pn->hash_lock);
+ if (!(dev->flags & IFF_UP)) {
+ write_unlock_bh(&pn->hash_lock);
goto err_put;
}
@@ -627,8 +683,8 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
&sp->sa_addr.pppoe,
sizeof(struct pppoe_addr));
- error = __set_item(po);
- write_unlock_bh(&pppoe_hash_lock);
+ error = __set_item(pn, po);
+ write_unlock_bh(&pn->hash_lock);
if (error < 0)
goto err_put;
@@ -639,7 +695,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.private = sk;
po->chan.ops = &pppoe_chan_ops;
- error = ppp_register_channel(&po->chan);
+ error = ppp_register_net_channel(dev_net(dev), &po->chan);
if (error)
goto err_put;
@@ -648,7 +704,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->num = sp->sa_addr.pppoe.sid;
- end:
+end:
release_sock(sk);
return error;
err_put:
@@ -659,7 +715,6 @@ err_put:
goto end;
}
-
static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
int *usockaddr_len, int peer)
{
@@ -678,7 +733,6 @@ static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
return 0;
}
-
static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
unsigned long arg)
{
@@ -690,7 +744,6 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
switch (cmd) {
case PPPIOCGMRU:
err = -ENXIO;
-
if (!(sk->sk_state & PPPOX_CONNECTED))
break;
@@ -698,7 +751,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
if (put_user(po->pppoe_dev->mtu -
sizeof(struct pppoe_hdr) -
PPP_HDRLEN,
- (int __user *) arg))
+ (int __user *)arg))
break;
err = 0;
break;
@@ -709,7 +762,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
break;
err = -EFAULT;
- if (get_user(val,(int __user *) arg))
+ if (get_user(val, (int __user *)arg))
break;
if (val < (po->pppoe_dev->mtu
@@ -722,7 +775,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
case PPPIOCSFLAGS:
err = -EFAULT;
- if (get_user(val, (int __user *) arg))
+ if (get_user(val, (int __user *)arg))
break;
err = 0;
break;
@@ -749,13 +802,12 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
err = -EINVAL;
if (po->pppoe_relay.sa_family != AF_PPPOX ||
- po->pppoe_relay.sa_protocol!= PX_PROTO_OE)
+ po->pppoe_relay.sa_protocol != PX_PROTO_OE)
break;
/* Check that the socket referenced by the address
actually exists. */
- relay_po = get_item_by_addr(&po->pppoe_relay);
-
+ relay_po = get_item_by_addr(sock_net(sk), &po->pppoe_relay);
if (!relay_po)
break;
@@ -781,7 +833,6 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
return err;
}
-
static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len)
{
@@ -808,7 +859,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
dev = po->pppoe_dev;
error = -EMSGSIZE;
- if (total_len > (dev->mtu + dev->hard_header_len))
+ if (total_len > (dev->mtu + dev->hard_header_len))
goto end;
@@ -826,13 +877,12 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
skb->dev = dev;
skb->priority = sk->sk_priority;
- skb->protocol = __constant_htons(ETH_P_PPP_SES);
+ skb->protocol = cpu_to_be16(ETH_P_PPP_SES);
- ph = (struct pppoe_hdr *) skb_put(skb, total_len + sizeof(struct pppoe_hdr));
- start = (char *) &ph->tag[0];
+ ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr));
+ start = (char *)&ph->tag[0];
error = memcpy_fromiovec(start, m->msg_iov, total_len);
-
if (error < 0) {
kfree_skb(skb);
goto end;
@@ -853,7 +903,6 @@ end:
return error;
}
-
/************************************************************************
*
* xmit function for internal use.
@@ -888,7 +937,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
ph->sid = po->num;
ph->length = htons(data_len);
- skb->protocol = __constant_htons(ETH_P_PPP_SES);
+ skb->protocol = cpu_to_be16(ETH_P_PPP_SES);
skb->dev = dev;
dev_hard_header(skb, dev, ETH_P_PPP_SES,
@@ -903,7 +952,6 @@ abort:
return 1;
}
-
/************************************************************************
*
* xmit function called by generic PPP driver
@@ -912,11 +960,10 @@ abort:
***********************************************************************/
static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb)
{
- struct sock *sk = (struct sock *) chan->private;
+ struct sock *sk = (struct sock *)chan->private;
return __pppoe_xmit(sk, skb);
}
-
static struct ppp_channel_ops pppoe_chan_ops = {
.start_xmit = pppoe_xmit,
};
@@ -935,7 +982,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &error);
-
if (error < 0)
goto end;
@@ -968,44 +1014,47 @@ static int pppoe_seq_show(struct seq_file *seq, void *v)
dev_name = po->pppoe_pa.dev;
seq_printf(seq, "%08X %pM %8s\n",
- po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name);
+ po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name);
out:
return 0;
}
-static __inline__ struct pppox_sock *pppoe_get_idx(loff_t pos)
+static inline struct pppox_sock *pppoe_get_idx(struct pppoe_net *pn, loff_t pos)
{
struct pppox_sock *po;
- int i = 0;
+ int i;
- for (; i < PPPOE_HASH_SIZE; i++) {
- po = item_hash_table[i];
+ for (i = 0; i < PPPOE_HASH_SIZE; i++) {
+ po = pn->hash_table[i];
while (po) {
if (!pos--)
goto out;
po = po->next;
}
}
+
out:
return po;
}
static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(pppoe_hash_lock)
+ __acquires(pn->hash_lock)
{
+ struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
loff_t l = *pos;
- read_lock_bh(&pppoe_hash_lock);
- return l ? pppoe_get_idx(--l) : SEQ_START_TOKEN;
+ read_lock_bh(&pn->hash_lock);
+ return l ? pppoe_get_idx(pn, --l) : SEQ_START_TOKEN;
}
static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
+ struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
struct pppox_sock *po;
++*pos;
if (v == SEQ_START_TOKEN) {
- po = pppoe_get_idx(0);
+ po = pppoe_get_idx(pn, 0);
goto out;
}
po = v;
@@ -1015,22 +1064,24 @@ static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
while (++hash < PPPOE_HASH_SIZE) {
- po = item_hash_table[hash];
+ po = pn->hash_table[hash];
if (po)
break;
}
}
+
out:
return po;
}
static void pppoe_seq_stop(struct seq_file *seq, void *v)
- __releases(pppoe_hash_lock)
+ __releases(pn->hash_lock)
{
- read_unlock_bh(&pppoe_hash_lock);
+ struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
+ read_unlock_bh(&pn->hash_lock);
}
-static struct seq_operations pppoe_seq_ops = {
+static const struct seq_operations pppoe_seq_ops = {
.start = pppoe_seq_start,
.next = pppoe_seq_next,
.stop = pppoe_seq_stop,
@@ -1039,7 +1090,8 @@ static struct seq_operations pppoe_seq_ops = {
static int pppoe_seq_open(struct inode *inode, struct file *file)
{
- return seq_open(file, &pppoe_seq_ops);
+ return seq_open_net(inode, file, &pppoe_seq_ops,
+ sizeof(struct seq_net_private));
}
static const struct file_operations pppoe_seq_fops = {
@@ -1047,74 +1099,115 @@ static const struct file_operations pppoe_seq_fops = {
.open = pppoe_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = seq_release_net,
};
-static int __init pppoe_proc_init(void)
-{
- struct proc_dir_entry *p;
-
- p = proc_net_fops_create(&init_net, "pppoe", S_IRUGO, &pppoe_seq_fops);
- if (!p)
- return -ENOMEM;
- return 0;
-}
-#else /* CONFIG_PROC_FS */
-static inline int pppoe_proc_init(void) { return 0; }
#endif /* CONFIG_PROC_FS */
static const struct proto_ops pppoe_ops = {
- .family = AF_PPPOX,
- .owner = THIS_MODULE,
- .release = pppoe_release,
- .bind = sock_no_bind,
- .connect = pppoe_connect,
- .socketpair = sock_no_socketpair,
- .accept = sock_no_accept,
- .getname = pppoe_getname,
- .poll = datagram_poll,
- .listen = sock_no_listen,
- .shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
- .sendmsg = pppoe_sendmsg,
- .recvmsg = pppoe_recvmsg,
- .mmap = sock_no_mmap,
- .ioctl = pppox_ioctl,
+ .family = AF_PPPOX,
+ .owner = THIS_MODULE,
+ .release = pppoe_release,
+ .bind = sock_no_bind,
+ .connect = pppoe_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = pppoe_getname,
+ .poll = datagram_poll,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .sendmsg = pppoe_sendmsg,
+ .recvmsg = pppoe_recvmsg,
+ .mmap = sock_no_mmap,
+ .ioctl = pppox_ioctl,
};
static struct pppox_proto pppoe_proto = {
- .create = pppoe_create,
- .ioctl = pppoe_ioctl,
- .owner = THIS_MODULE,
+ .create = pppoe_create,
+ .ioctl = pppoe_ioctl,
+ .owner = THIS_MODULE,
};
+static __net_init int pppoe_init_net(struct net *net)
+{
+ struct pppoe_net *pn;
+ struct proc_dir_entry *pde;
+ int err;
+
+ pn = kzalloc(sizeof(*pn), GFP_KERNEL);
+ if (!pn)
+ return -ENOMEM;
+
+ rwlock_init(&pn->hash_lock);
+
+ err = net_assign_generic(net, pppoe_net_id, pn);
+ if (err)
+ goto out;
+
+ pde = proc_net_fops_create(net, "pppoe", S_IRUGO, &pppoe_seq_fops);
+#ifdef CONFIG_PROC_FS
+ if (!pde) {
+ err = -ENOMEM;
+ goto out;
+ }
+#endif
+
+ return 0;
+
+out:
+ kfree(pn);
+ return err;
+}
+
+static __net_exit void pppoe_exit_net(struct net *net)
+{
+ struct pppoe_net *pn;
+
+ proc_net_remove(net, "pppoe");
+ pn = net_generic(net, pppoe_net_id);
+ /*
+ * if someone has cached our net then
+ * further net_generic call will return NULL
+ */
+ net_assign_generic(net, pppoe_net_id, NULL);
+ kfree(pn);
+}
+
+static struct pernet_operations pppoe_net_ops = {
+ .init = pppoe_init_net,
+ .exit = pppoe_exit_net,
+};
static int __init pppoe_init(void)
{
- int err = proto_register(&pppoe_sk_proto, 0);
+ int err;
+ err = proto_register(&pppoe_sk_proto, 0);
if (err)
goto out;
- err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
+ err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
if (err)
goto out_unregister_pppoe_proto;
- err = pppoe_proc_init();
+ err = register_pernet_gen_device(&pppoe_net_id, &pppoe_net_ops);
if (err)
goto out_unregister_pppox_proto;
dev_add_pack(&pppoes_ptype);
dev_add_pack(&pppoed_ptype);
register_netdevice_notifier(&pppoe_notifier);
-out:
- return err;
+
+ return 0;
+
out_unregister_pppox_proto:
unregister_pppox_proto(PX_PROTO_OE);
out_unregister_pppoe_proto:
proto_unregister(&pppoe_sk_proto);
- goto out;
+out:
+ return err;
}
static void __exit pppoe_exit(void)
@@ -1123,7 +1216,7 @@ static void __exit pppoe_exit(void)
dev_remove_pack(&pppoes_ptype);
dev_remove_pack(&pppoed_ptype);
unregister_netdevice_notifier(&pppoe_notifier);
- remove_proc_entry("pppoe", init_net.proc_net);
+ unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops);
proto_unregister(&pppoe_sk_proto);
}
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index f1a946785c6..5b07dd8e5c0 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -90,7 +90,9 @@
#include <linux/hash.h>
#include <linux/sort.h>
#include <linux/proc_fs.h>
+#include <linux/nsproxy.h>
#include <net/net_namespace.h>
+#include <net/netns/generic.h>
#include <net/dst.h>
#include <net/ip.h>
#include <net/udp.h>
@@ -204,6 +206,7 @@ struct pppol2tp_tunnel
struct sock *sock; /* Parent socket */
struct list_head list; /* Keep a list of all open
* prepared sockets */
+ struct net *pppol2tp_net; /* the net we belong to */
atomic_t ref_count;
};
@@ -227,8 +230,20 @@ static atomic_t pppol2tp_tunnel_count;
static atomic_t pppol2tp_session_count;
static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
static struct proto_ops pppol2tp_ops;
-static LIST_HEAD(pppol2tp_tunnel_list);
-static DEFINE_RWLOCK(pppol2tp_tunnel_list_lock);
+
+/* per-net private data for this module */
+static int pppol2tp_net_id;
+struct pppol2tp_net {
+ struct list_head pppol2tp_tunnel_list;
+ rwlock_t pppol2tp_tunnel_list_lock;
+};
+
+static inline struct pppol2tp_net *pppol2tp_pernet(struct net *net)
+{
+ BUG_ON(!net);
+
+ return net_generic(net, pppol2tp_net_id);
+}
/* Helpers to obtain tunnel/session contexts from sockets.
*/
@@ -321,18 +336,19 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id)
/* Lookup a tunnel by id
*/
-static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
+static struct pppol2tp_tunnel *pppol2tp_tunnel_find(struct net *net, u16 tunnel_id)
{
- struct pppol2tp_tunnel *tunnel = NULL;
+ struct pppol2tp_tunnel *tunnel;
+ struct pppol2tp_net *pn = pppol2tp_pernet(net);
- read_lock_bh(&pppol2tp_tunnel_list_lock);
- list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
+ read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+ list_for_each_entry(tunnel, &pn->pppol2tp_tunnel_list, list) {
if (tunnel->stats.tunnel_id == tunnel_id) {
- read_unlock_bh(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
return tunnel;
}
}
- read_unlock_bh(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
return NULL;
}
@@ -1287,10 +1303,12 @@ again:
*/
static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
{
+ struct pppol2tp_net *pn = pppol2tp_pernet(tunnel->pppol2tp_net);
+
/* Remove from socket list */
- write_lock_bh(&pppol2tp_tunnel_list_lock);
+ write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
list_del_init(&tunnel->list);
- write_unlock_bh(&pppol2tp_tunnel_list_lock);
+ write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
atomic_dec(&pppol2tp_tunnel_count);
kfree(tunnel);
@@ -1444,13 +1462,14 @@ error:
/* Internal function to prepare a tunnel (UDP) socket to have PPPoX
* sockets attached to it.
*/
-static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
- int *error)
+static struct sock *pppol2tp_prepare_tunnel_socket(struct net *net,
+ int fd, u16 tunnel_id, int *error)
{
int err;
struct socket *sock = NULL;
struct sock *sk;
struct pppol2tp_tunnel *tunnel;
+ struct pppol2tp_net *pn;
struct sock *ret = NULL;
/* Get the tunnel UDP socket from the fd, which was opened by
@@ -1524,11 +1543,15 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
/* Misc init */
rwlock_init(&tunnel->hlist_lock);
+ /* The net we belong to */
+ tunnel->pppol2tp_net = net;
+ pn = pppol2tp_pernet(net);
+
/* Add tunnel to our list */
INIT_LIST_HEAD(&tunnel->list);
- write_lock_bh(&pppol2tp_tunnel_list_lock);
- list_add(&tunnel->list, &pppol2tp_tunnel_list);
- write_unlock_bh(&pppol2tp_tunnel_list_lock);
+ write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+ list_add(&tunnel->list, &pn->pppol2tp_tunnel_list);
+ write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
atomic_inc(&pppol2tp_tunnel_count);
/* Bump the reference count. The tunnel context is deleted
@@ -1629,7 +1652,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
* tunnel id.
*/
if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) {
- tunnel_sock = pppol2tp_prepare_tunnel_socket(sp->pppol2tp.fd,
+ tunnel_sock = pppol2tp_prepare_tunnel_socket(sock_net(sk),
+ sp->pppol2tp.fd,
sp->pppol2tp.s_tunnel,
&error);
if (tunnel_sock == NULL)
@@ -1637,7 +1661,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
tunnel = tunnel_sock->sk_user_data;
} else {
- tunnel = pppol2tp_tunnel_find(sp->pppol2tp.s_tunnel);
+ tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
/* Error if we can't find the tunnel */
error = -ENOENT;
@@ -1725,7 +1749,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.ops = &pppol2tp_chan_ops;
po->chan.mtu = session->mtu;
- error = ppp_register_channel(&po->chan);
+ error = ppp_register_net_channel(sock_net(sk), &po->chan);
if (error)
goto end_put_tun;
@@ -2347,8 +2371,9 @@ end:
#include <linux/seq_file.h>
struct pppol2tp_seq_data {
- struct pppol2tp_tunnel *tunnel; /* current tunnel */
- struct pppol2tp_session *session; /* NULL means get first session in tunnel */
+ struct seq_net_private p;
+ struct pppol2tp_tunnel *tunnel; /* current tunnel */
+ struct pppol2tp_session *session; /* NULL means get first session in tunnel */
};
static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, struct pppol2tp_session *curr)
@@ -2384,17 +2409,18 @@ out:
return session;
}
-static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
+static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_net *pn,
+ struct pppol2tp_tunnel *curr)
{
struct pppol2tp_tunnel *tunnel = NULL;
- read_lock_bh(&pppol2tp_tunnel_list_lock);
- if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
+ read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+ if (list_is_last(&curr->list, &pn->pppol2tp_tunnel_list)) {
goto out;
}
tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
out:
- read_unlock_bh(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
return tunnel;
}
@@ -2402,6 +2428,7 @@ out:
static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
{
struct pppol2tp_seq_data *pd = SEQ_START_TOKEN;
+ struct pppol2tp_net *pn;
loff_t pos = *offs;
if (!pos)
@@ -2409,14 +2436,15 @@ static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
BUG_ON(m->private == NULL);
pd = m->private;
+ pn = pppol2tp_pernet(seq_file_net(m));
if (pd->tunnel == NULL) {
- if (!list_empty(&pppol2tp_tunnel_list))
- pd->tunnel = list_entry(pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
+ if (!list_empty(&pn->pppol2tp_tunnel_list))
+ pd->tunnel = list_entry(pn->pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
} else {
pd->session = next_session(pd->tunnel, pd->session);
if (pd->session == NULL) {
- pd->tunnel = next_tunnel(pd->tunnel);
+ pd->tunnel = next_tunnel(pn, pd->tunnel);
}
}
@@ -2517,7 +2545,7 @@ out:
return 0;
}
-static struct seq_operations pppol2tp_seq_ops = {
+static const struct seq_operations pppol2tp_seq_ops = {
.start = pppol2tp_seq_start,
.next = pppol2tp_seq_next,
.stop = pppol2tp_seq_stop,
@@ -2530,51 +2558,18 @@ static struct seq_operations pppol2tp_seq_ops = {
*/
static int pppol2tp_proc_open(struct inode *inode, struct file *file)
{
- struct seq_file *m;
- struct pppol2tp_seq_data *pd;
- int ret = 0;
-
- ret = seq_open(file, &pppol2tp_seq_ops);
- if (ret < 0)
- goto out;
-
- m = file->private_data;
-
- /* Allocate and fill our proc_data for access later */
- ret = -ENOMEM;
- m->private = kzalloc(sizeof(struct pppol2tp_seq_data), GFP_KERNEL);
- if (m->private == NULL)
- goto out;
-
- pd = m->private;
- ret = 0;
-
-out:
- return ret;
-}
-
-/* Called when /proc file access completes.
- */
-static int pppol2tp_proc_release(struct inode *inode, struct file *file)
-{
- struct seq_file *m = (struct seq_file *)file->private_data;
-
- kfree(m->private);
- m->private = NULL;
-
- return seq_release(inode, file);
+ return seq_open_net(inode, file, &pppol2tp_seq_ops,
+ sizeof(struct pppol2tp_seq_data));
}
-static struct file_operations pppol2tp_proc_fops = {
+static const struct file_operations pppol2tp_proc_fops = {
.owner = THIS_MODULE,
.open = pppol2tp_proc_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = pppol2tp_proc_release,
+ .release = seq_release_net,
};
-static struct proc_dir_entry *pppol2tp_proc;
-
#endif /* CONFIG_PROC_FS */
/*****************************************************************************
@@ -2606,6 +2601,57 @@ static struct pppox_proto pppol2tp_proto = {
.ioctl = pppol2tp_ioctl
};
+static __net_init int pppol2tp_init_net(struct net *net)
+{
+ struct pppol2tp_net *pn;
+ struct proc_dir_entry *pde;
+ int err;
+
+ pn = kzalloc(sizeof(*pn), GFP_KERNEL);
+ if (!pn)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list);
+ rwlock_init(&pn->pppol2tp_tunnel_list_lock);
+
+ err = net_assign_generic(net, pppol2tp_net_id, pn);
+ if (err)
+ goto out;
+
+ pde = proc_net_fops_create(net, "pppol2tp", S_IRUGO, &pppol2tp_proc_fops);
+#ifdef CONFIG_PROC_FS
+ if (!pde) {
+ err = -ENOMEM;
+ goto out;
+ }
+#endif
+
+ return 0;
+
+out:
+ kfree(pn);
+ return err;
+}
+
+static __net_exit void pppol2tp_exit_net(struct net *net)
+{
+ struct pppoe_net *pn;
+
+ proc_net_remove(net, "pppol2tp");
+ pn = net_generic(net, pppol2tp_net_id);
+ /*
+ * if someone has cached our net then
+ * further net_generic call will return NULL
+ */
+ net_assign_generic(net, pppol2tp_net_id, NULL);
+ kfree(pn);
+}
+
+static struct pernet_operations pppol2tp_net_ops = {
+ .init = pppol2tp_init_net,
+ .exit = pppol2tp_exit_net,
+};
+
static int __init pppol2tp_init(void)
{
int err;
@@ -2617,23 +2663,17 @@ static int __init pppol2tp_init(void)
if (err)
goto out_unregister_pppol2tp_proto;
-#ifdef CONFIG_PROC_FS
- pppol2tp_proc = proc_net_fops_create(&init_net, "pppol2tp", 0,
- &pppol2tp_proc_fops);
- if (!pppol2tp_proc) {
- err = -ENOMEM;
+ err = register_pernet_gen_device(&pppol2tp_net_id, &pppol2tp_net_ops);
+ if (err)
goto out_unregister_pppox_proto;
- }
-#endif /* CONFIG_PROC_FS */
+
printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
PPPOL2TP_DRV_VERSION);
out:
return err;
-#ifdef CONFIG_PROC_FS
out_unregister_pppox_proto:
unregister_pppox_proto(PX_PROTO_OL2TP);
-#endif
out_unregister_pppol2tp_proto:
proto_unregister(&pppol2tp_sk_proto);
goto out;
@@ -2642,10 +2682,6 @@ out_unregister_pppol2tp_proto:
static void __exit pppol2tp_exit(void)
{
unregister_pppox_proto(PX_PROTO_OL2TP);
-
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("pppol2tp", init_net.proc_net);
-#endif
proto_unregister(&pppol2tp_sk_proto);
}
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index 03aecc97fb4..4f6d33fbc67 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -108,9 +108,6 @@ static int pppox_create(struct net *net, struct socket *sock, int protocol)
{
int rc = -EPROTOTYPE;
- if (net != &init_net)
- return -EAFNOSUPPORT;
-
if (protocol < 0 || protocol > PX_MAX_PROTO)
goto out;
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 4b564eda5bd..30900b30d53 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -745,7 +745,7 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
/* Move the mac addresses to the top of buffer */
memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
- veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
+ veth->h_vlan_proto = cpu_to_be16(ETH_P_8021Q);
veth->h_vlan_TCI = htons(tag);
return skb;
@@ -1403,6 +1403,19 @@ void gelic_net_tx_timeout(struct net_device *netdev)
atomic_dec(&card->tx_timeout_task_counter);
}
+static const struct net_device_ops gelic_netdevice_ops = {
+ .ndo_open = gelic_net_open,
+ .ndo_stop = gelic_net_stop,
+ .ndo_start_xmit = gelic_net_xmit,
+ .ndo_set_multicast_list = gelic_net_set_multi,
+ .ndo_change_mtu = gelic_net_change_mtu,
+ .ndo_tx_timeout = gelic_net_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = gelic_net_poll_controller,
+#endif
+};
+
/**
* gelic_ether_setup_netdev_ops - initialization of net_device operations
* @netdev: net_device structure
@@ -1412,21 +1425,12 @@ void gelic_net_tx_timeout(struct net_device *netdev)
static void gelic_ether_setup_netdev_ops(struct net_device *netdev,
struct napi_struct *napi)
{
- netdev->open = &gelic_net_open;
- netdev->stop = &gelic_net_stop;
- netdev->hard_start_xmit = &gelic_net_xmit;
- netdev->set_multicast_list = &gelic_net_set_multi;
- netdev->change_mtu = &gelic_net_change_mtu;
- /* tx watchdog */
- netdev->tx_timeout = &gelic_net_tx_timeout;
netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
/* NAPI */
netif_napi_add(netdev, napi,
gelic_net_poll, GELIC_NET_NAPI_WEIGHT);
netdev->ethtool_ops = &gelic_ether_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = gelic_net_poll_controller;
-#endif
+ netdev->netdev_ops = &gelic_netdevice_ops;
}
/**
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index ec231424668..a5ac2bd58b5 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2168,7 +2168,7 @@ static void gelic_wl_connected_event(struct gelic_wl_info *wl,
complete(&wl->assoc_done);
netif_carrier_on(port_to_netdev(wl_port(wl)));
} else
- pr_debug("%s: event %#lx under wpa\n",
+ pr_debug("%s: event %#llx under wpa\n",
__func__, event);
}
@@ -2697,6 +2697,19 @@ static int gelic_wl_stop(struct net_device *netdev)
/* -- */
+static const struct net_device_ops gelic_wl_netdevice_ops = {
+ .ndo_open = gelic_wl_open,
+ .ndo_stop = gelic_wl_stop,
+ .ndo_start_xmit = gelic_net_xmit,
+ .ndo_set_multicast_list = gelic_net_set_multi,
+ .ndo_change_mtu = gelic_net_change_mtu,
+ .ndo_tx_timeout = gelic_net_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = gelic_net_poll_controller,
+#endif
+};
+
static struct ethtool_ops gelic_wl_ethtool_ops = {
.get_drvinfo = gelic_net_get_drvinfo,
.get_link = gelic_wl_get_link,
@@ -2711,21 +2724,12 @@ static void gelic_wl_setup_netdev_ops(struct net_device *netdev)
struct gelic_wl_info *wl;
wl = port_wl(netdev_priv(netdev));
BUG_ON(!wl);
- netdev->open = &gelic_wl_open;
- netdev->stop = &gelic_wl_stop;
- netdev->hard_start_xmit = &gelic_net_xmit;
- netdev->set_multicast_list = &gelic_net_set_multi;
- netdev->change_mtu = &gelic_net_change_mtu;
- netdev->wireless_data = &wl->wireless_data;
- netdev->wireless_handlers = &gelic_wl_wext_handler_def;
- /* tx watchdog */
- netdev->tx_timeout = &gelic_net_tx_timeout;
netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
netdev->ethtool_ops = &gelic_wl_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = gelic_net_poll_controller;
-#endif
+ netdev->netdev_ops = &gelic_wl_netdevice_ops;
+ netdev->wireless_data = &wl->wireless_data;
+ netdev->wireless_handlers = &gelic_wl_wext_handler_def;
}
/*
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 189ec29ac7a..8b2823c8dcc 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2292,7 +2292,7 @@ static int ql_poll(struct napi_struct *napi, int budget)
if (tx_cleaned + rx_cleaned != budget) {
spin_lock_irqsave(&qdev->hw_lock, hw_flags);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
ql_update_small_bufq_prod_index(qdev);
ql_update_lrg_bufq_prod_index(qdev);
writel(qdev->rsp_consumer_index,
@@ -2351,8 +2351,8 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id)
spin_unlock(&qdev->adapter_lock);
} else if (value & ISP_IMR_DISABLE_CMPL_INT) {
ql_disable_interrupts(qdev);
- if (likely(netif_rx_schedule_prep(&qdev->napi))) {
- __netif_rx_schedule(&qdev->napi);
+ if (likely(napi_schedule_prep(&qdev->napi))) {
+ __napi_schedule(&qdev->napi);
}
} else {
return IRQ_NONE;
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index c1dadadfab1..fcb159e4df5 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -28,8 +28,8 @@
} while (0)
#define QLGE_VENDOR_ID 0x1077
-#define QLGE_DEVICE_ID 0x8012
-
+#define QLGE_DEVICE_ID_8012 0x8012
+#define QLGE_DEVICE_ID_8000 0x8000
#define MAX_CPUS 8
#define MAX_TX_RINGS MAX_CPUS
#define MAX_RX_RINGS ((MAX_CPUS * 2) + 1)
@@ -164,7 +164,7 @@ enum {
CSR_RP = (1 << 10),
CSR_CMD_PARM_SHIFT = 22,
CSR_CMD_NOP = 0x00000000,
- CSR_CMD_SET_RST = 0x1000000,
+ CSR_CMD_SET_RST = 0x10000000,
CSR_CMD_CLR_RST = 0x20000000,
CSR_CMD_SET_PAUSE = 0x30000000,
CSR_CMD_CLR_PAUSE = 0x40000000,
@@ -424,7 +424,7 @@ enum {
RX_SYMBOL_ERR = 0x00000370,
RX_MAC_ERR = 0x00000378,
RX_CTL_PKTS = 0x00000380,
- RX_PAUSE_PKTS = 0x00000384,
+ RX_PAUSE_PKTS = 0x00000388,
RX_64_PKTS = 0x00000390,
RX_65_TO_127_PKTS = 0x00000398,
RX_128_255_PKTS = 0x000003a0,
@@ -733,6 +733,11 @@ enum {
AEN_LINK_DOWN = 0x00008012,
AEN_IDC_CMPLT = 0x00008100,
AEN_IDC_REQ = 0x00008101,
+ AEN_IDC_EXT = 0x00008102,
+ AEN_DCBX_CHG = 0x00008110,
+ AEN_AEN_LOST = 0x00008120,
+ AEN_AEN_SFP_IN = 0x00008130,
+ AEN_AEN_SFP_OUT = 0x00008131,
AEN_FW_INIT_DONE = 0x00008400,
AEN_FW_INIT_FAIL = 0x00008401,
@@ -742,40 +747,48 @@ enum {
MB_CMD_MB_TEST = 0x00000006,
MB_CMD_CSUM_TEST = 0x00000007, /* Verify Checksum */
MB_CMD_ABOUT_FW = 0x00000008,
+ MB_CMD_COPY_RISC_RAM = 0x0000000a,
MB_CMD_LOAD_RISC_RAM = 0x0000000b,
MB_CMD_DUMP_RISC_RAM = 0x0000000c,
MB_CMD_WRITE_RAM = 0x0000000d,
+ MB_CMD_INIT_RISC_RAM = 0x0000000e,
MB_CMD_READ_RAM = 0x0000000f,
MB_CMD_STOP_FW = 0x00000014,
MB_CMD_MAKE_SYS_ERR = 0x0000002a,
+ MB_CMD_WRITE_SFP = 0x00000030,
+ MB_CMD_READ_SFP = 0x00000031,
MB_CMD_INIT_FW = 0x00000060,
- MB_CMD_GET_INIT_CB = 0x00000061,
+ MB_CMD_GET_IFCB = 0x00000061,
MB_CMD_GET_FW_STATE = 0x00000069,
MB_CMD_IDC_REQ = 0x00000100, /* Inter-Driver Communication */
MB_CMD_IDC_ACK = 0x00000101, /* Inter-Driver Communication */
MB_CMD_SET_WOL_MODE = 0x00000110, /* Wake On Lan */
- MB_WOL_DISABLE = 0x00000000,
- MB_WOL_MAGIC_PKT = 0x00000001,
- MB_WOL_FLTR = 0x00000002,
- MB_WOL_UCAST = 0x00000004,
- MB_WOL_MCAST = 0x00000008,
- MB_WOL_BCAST = 0x00000010,
- MB_WOL_LINK_UP = 0x00000020,
- MB_WOL_LINK_DOWN = 0x00000040,
+ MB_WOL_DISABLE = 0,
+ MB_WOL_MAGIC_PKT = (1 << 1),
+ MB_WOL_FLTR = (1 << 2),
+ MB_WOL_UCAST = (1 << 3),
+ MB_WOL_MCAST = (1 << 4),
+ MB_WOL_BCAST = (1 << 5),
+ MB_WOL_LINK_UP = (1 << 6),
+ MB_WOL_LINK_DOWN = (1 << 7),
MB_CMD_SET_WOL_FLTR = 0x00000111, /* Wake On Lan Filter */
- MB_CMD_CLEAR_WOL_FLTR = 0x00000112, /* Wake On Lan Filter */
+ MB_CMD_CLEAR_WOL_FLTR = 0x00000112, /* Wake On Lan Filter */
MB_CMD_SET_WOL_MAGIC = 0x00000113, /* Wake On Lan Magic Packet */
- MB_CMD_CLEAR_WOL_MAGIC = 0x00000114, /* Wake On Lan Magic Packet */
+ MB_CMD_CLEAR_WOL_MAGIC = 0x00000114,/* Wake On Lan Magic Packet */
+ MB_CMD_SET_WOL_IMMED = 0x00000115,
MB_CMD_PORT_RESET = 0x00000120,
MB_CMD_SET_PORT_CFG = 0x00000122,
MB_CMD_GET_PORT_CFG = 0x00000123,
- MB_CMD_SET_ASIC_VOLTS = 0x00000130,
- MB_CMD_GET_SNS_DATA = 0x00000131, /* Temp and Volt Sense data. */
+ MB_CMD_GET_LINK_STS = 0x00000124,
/* Mailbox Command Status. */
MB_CMD_STS_GOOD = 0x00004000, /* Success. */
MB_CMD_STS_INTRMDT = 0x00001000, /* Intermediate Complete. */
- MB_CMD_STS_ERR = 0x00004005, /* Error. */
+ MB_CMD_STS_INVLD_CMD = 0x00004001, /* Invalid. */
+ MB_CMD_STS_XFC_ERR = 0x00004002, /* Interface Error. */
+ MB_CMD_STS_CSUM_ERR = 0x00004003, /* Csum Error. */
+ MB_CMD_STS_ERR = 0x00004005, /* System Error. */
+ MB_CMD_STS_PARAM_ERR = 0x00004006, /* Parameter Error. */
};
struct mbox_params {
@@ -785,16 +798,53 @@ struct mbox_params {
int out_count;
};
-struct flash_params {
+struct flash_params_8012 {
u8 dev_id_str[4];
- u16 size;
- u16 csum;
- u16 ver;
- u16 sub_dev_id;
+ __le16 size;
+ __le16 csum;
+ __le16 ver;
+ __le16 sub_dev_id;
+ u8 mac_addr[6];
+ __le16 res;
+};
+
+/* 8000 device's flash is a different structure
+ * at a different offset in flash.
+ */
+#define FUNC0_FLASH_OFFSET 0x140200
+#define FUNC1_FLASH_OFFSET 0x140600
+
+/* Flash related data structures. */
+struct flash_params_8000 {
+ u8 dev_id_str[4]; /* "8000" */
+ __le16 ver;
+ __le16 size;
+ __le16 csum;
+ __le16 reserved0;
+ __le16 total_size;
+ __le16 entry_count;
+ u8 data_type0;
+ u8 data_size0;
u8 mac_addr[6];
- u16 res;
+ u8 data_type1;
+ u8 data_size1;
+ u8 mac_addr1[6];
+ u8 data_type2;
+ u8 data_size2;
+ __le16 vlan_id;
+ u8 data_type3;
+ u8 data_size3;
+ __le16 last;
+ u8 reserved1[464];
+ __le16 subsys_ven_id;
+ __le16 subsys_dev_id;
+ u8 reserved2[4];
};
+union flash_params {
+ struct flash_params_8012 flash_params_8012;
+ struct flash_params_8000 flash_params_8000;
+};
/*
* doorbell space for the rx ring context
@@ -927,6 +977,7 @@ struct ib_mac_iocb_rsp {
u8 flags1;
#define IB_MAC_IOCB_RSP_OI 0x01 /* Overide intr delay */
#define IB_MAC_IOCB_RSP_I 0x02 /* Disble Intr Generation */
+#define IB_MAC_CSUM_ERR_MASK 0x1c /* A mask to use for csum errs */
#define IB_MAC_IOCB_RSP_TE 0x04 /* Checksum error */
#define IB_MAC_IOCB_RSP_NU 0x08 /* No checksum rcvd */
#define IB_MAC_IOCB_RSP_IE 0x10 /* IPv4 checksum error */
@@ -967,6 +1018,7 @@ struct ib_mac_iocb_rsp {
__le16 vlan_id; /* 12 bits */
#define IB_MAC_IOCB_RSP_C 0x1000 /* VLAN CFI bit */
#define IB_MAC_IOCB_RSP_COS_SHIFT 12 /* class of service value */
+#define IB_MAC_IOCB_RSP_VLAN_MASK 0x0ffff
__le16 reserved1;
__le32 reserved2[6];
@@ -1032,6 +1084,7 @@ struct wqicb {
#define Q_LEN_CPP_16 0x0001
#define Q_LEN_CPP_32 0x0002
#define Q_LEN_CPP_64 0x0003
+#define Q_LEN_CPP_512 0x0006
__le16 flags;
#define Q_PRI_SHIFT 1
#define Q_FLAGS_LC 0x1000
@@ -1313,27 +1366,49 @@ enum {
QL_DMA64 = (1 << 5),
QL_PROMISCUOUS = (1 << 6),
QL_ALLMULTI = (1 << 7),
+ QL_PORT_CFG = (1 << 8),
+ QL_CAM_RT_SET = (1 << 9),
};
/* link_status bit definitions */
enum {
- LOOPBACK_MASK = 0x00000700,
- LOOPBACK_PCS = 0x00000100,
- LOOPBACK_HSS = 0x00000200,
- LOOPBACK_EXT = 0x00000300,
- PAUSE_MASK = 0x000000c0,
- PAUSE_STD = 0x00000040,
- PAUSE_PRI = 0x00000080,
- SPEED_MASK = 0x00000038,
- SPEED_100Mb = 0x00000000,
- SPEED_1Gb = 0x00000008,
- SPEED_10Gb = 0x00000010,
- LINK_TYPE_MASK = 0x00000007,
- LINK_TYPE_XFI = 0x00000001,
- LINK_TYPE_XAUI = 0x00000002,
- LINK_TYPE_XFI_BP = 0x00000003,
- LINK_TYPE_XAUI_BP = 0x00000004,
- LINK_TYPE_10GBASET = 0x00000005,
+ STS_LOOPBACK_MASK = 0x00000700,
+ STS_LOOPBACK_PCS = 0x00000100,
+ STS_LOOPBACK_HSS = 0x00000200,
+ STS_LOOPBACK_EXT = 0x00000300,
+ STS_PAUSE_MASK = 0x000000c0,
+ STS_PAUSE_STD = 0x00000040,
+ STS_PAUSE_PRI = 0x00000080,
+ STS_SPEED_MASK = 0x00000038,
+ STS_SPEED_100Mb = 0x00000000,
+ STS_SPEED_1Gb = 0x00000008,
+ STS_SPEED_10Gb = 0x00000010,
+ STS_LINK_TYPE_MASK = 0x00000007,
+ STS_LINK_TYPE_XFI = 0x00000001,
+ STS_LINK_TYPE_XAUI = 0x00000002,
+ STS_LINK_TYPE_XFI_BP = 0x00000003,
+ STS_LINK_TYPE_XAUI_BP = 0x00000004,
+ STS_LINK_TYPE_10GBASET = 0x00000005,
+};
+
+/* link_config bit definitions */
+enum {
+ CFG_JUMBO_FRAME_SIZE = 0x00010000,
+ CFG_PAUSE_MASK = 0x00000060,
+ CFG_PAUSE_STD = 0x00000020,
+ CFG_PAUSE_PRI = 0x00000040,
+ CFG_DCBX = 0x00000010,
+ CFG_LOOPBACK_MASK = 0x00000007,
+ CFG_LOOPBACK_PCS = 0x00000002,
+ CFG_LOOPBACK_HSS = 0x00000004,
+ CFG_LOOPBACK_EXT = 0x00000006,
+ CFG_DEFAULT_MAX_FRAME_SIZE = 0x00002580,
+};
+
+struct nic_operations {
+
+ int (*get_flash) (struct ql_adapter *);
+ int (*port_initialize) (struct ql_adapter *);
};
/*
@@ -1376,6 +1451,8 @@ struct ql_adapter {
u32 mailbox_in;
u32 mailbox_out;
+ struct mbox_params idc_mbc;
+ struct mutex mpi_mutex;
int tx_ring_size;
int rx_ring_size;
@@ -1411,8 +1488,10 @@ struct ql_adapter {
u32 port_link_up;
u32 port_init;
u32 link_status;
+ u32 link_config;
+ u32 max_frame_size;
- struct flash_params flash;
+ union flash_params flash;
struct net_device_stats stats;
struct workqueue_struct *q_workqueue;
@@ -1420,6 +1499,11 @@ struct ql_adapter {
struct delayed_work asic_reset_work;
struct delayed_work mpi_reset_work;
struct delayed_work mpi_work;
+ struct delayed_work mpi_port_cfg_work;
+ struct delayed_work mpi_idc_work;
+ struct completion ide_completion;
+ struct nic_operations *nic_ops;
+ u16 device_id;
};
/*
@@ -1492,6 +1576,10 @@ void ql_queue_asic_error(struct ql_adapter *qdev);
u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
void ql_set_ethtool_ops(struct net_device *ndev);
int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data);
+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);
#if 1
#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index 379b895ed6e..40a70c36f5a 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -83,6 +83,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
{
int i;
u32 value[3];
+
+ i = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (i)
+ return;
for (i = 0; i < 4; i++) {
if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) {
printk(KERN_ERR PFX
@@ -111,12 +115,16 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
qdev->ndev->name, i, value[1], value[0]);
}
}
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
void ql_dump_routing_entries(struct ql_adapter *qdev)
{
int i;
u32 value;
+ i = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (i)
+ return;
for (i = 0; i < 16; i++) {
value = 0;
if (ql_get_routing_reg(qdev, i, &value)) {
@@ -131,6 +139,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
qdev->ndev->name, i, value);
}
}
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
}
void ql_dump_regs(struct ql_adapter *qdev)
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 9d922e2ff22..a50078627fb 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -271,7 +271,8 @@ static int ql_get_settings(struct net_device *ndev,
ecmd->advertising = ADVERTISED_10000baseT_Full;
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->transceiver = XCVR_EXTERNAL;
- if ((qdev->link_status & LINK_TYPE_MASK) == LINK_TYPE_10GBASET) {
+ if ((qdev->link_status & STS_LINK_TYPE_MASK) ==
+ STS_LINK_TYPE_10GBASET) {
ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg);
ecmd->port = PORT_TP;
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 45421c8b601..170d3540f9c 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -58,8 +58,8 @@ static const u32 default_msg =
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_TX_QUEUED | */
+/* NETIF_MSG_INTR | NETIF_MSG_TX_DONE | NETIF_MSG_RX_STATUS | */
/* NETIF_MSG_PKTDATA | */
NETIF_MSG_HW | NETIF_MSG_WOL | 0;
@@ -75,7 +75,8 @@ module_param(irq_type, int, MSIX_IRQ);
MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID)},
+ {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
+ {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8000)},
/* required last entry */
{0,}
};
@@ -247,9 +248,6 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index,
u32 offset = 0;
int status;
- status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
- if (status)
- return status;
switch (type) {
case MAC_ADDR_TYPE_MULTI_MAC:
case MAC_ADDR_TYPE_CAM_MAC:
@@ -308,7 +306,6 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index,
status = -EPERM;
}
exit:
- ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
return status;
}
@@ -321,9 +318,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
u32 offset = 0;
int status = 0;
- status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
- if (status)
- return status;
switch (type) {
case MAC_ADDR_TYPE_MULTI_MAC:
case MAC_ADDR_TYPE_CAM_MAC:
@@ -334,7 +328,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
(addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
(addr[5]);
- QPRINTK(qdev, IFUP, INFO,
+ QPRINTK(qdev, IFUP, DEBUG,
"Adding %s address %pM"
" at index %d in the CAM.\n",
((type ==
@@ -415,7 +409,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
status = -EPERM;
}
exit:
- ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
return status;
}
@@ -426,10 +419,6 @@ int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value)
{
int status = 0;
- status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
- if (status)
- goto exit;
-
status = ql_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MW, 0);
if (status)
goto exit;
@@ -441,7 +430,6 @@ int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value)
goto exit;
*value = ql_read32(qdev, RT_DATA);
exit:
- ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
return status;
}
@@ -453,13 +441,9 @@ exit:
static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
int enable)
{
- int status;
+ int status = -EINVAL; /* Return error if no mask match. */
u32 value = 0;
- status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
- if (status)
- return status;
-
QPRINTK(qdev, IFUP, DEBUG,
"%s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s mask %s the routing reg.\n",
(enable ? "Adding" : "Removing"),
@@ -555,7 +539,6 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
ql_write32(qdev, RT_DATA, enable ? mask : 0);
}
exit:
- ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
return status;
}
@@ -604,7 +587,6 @@ u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
{
u32 var = 0;
- unsigned long hw_flags;
struct intr_context *ctx;
/* HW disables for us if we're MSIX multi interrupts and
@@ -614,14 +596,14 @@ static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
return 0;
ctx = qdev->intr_context + intr;
- spin_lock_irqsave(&qdev->hw_lock, hw_flags);
+ spin_lock(&qdev->hw_lock);
if (!atomic_read(&ctx->irq_cnt)) {
ql_write32(qdev, INTR_EN,
ctx->intr_dis_mask);
var = ql_read32(qdev, STS);
}
atomic_inc(&ctx->irq_cnt);
- spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+ spin_unlock(&qdev->hw_lock);
return var;
}
@@ -641,7 +623,29 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev)
}
-static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
+static int ql_validate_flash(struct ql_adapter *qdev, u32 size, const char *str)
+{
+ int status, i;
+ u16 csum = 0;
+ __le16 *flash = (__le16 *)&qdev->flash;
+
+ status = strncmp((char *)&qdev->flash, str, 4);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Invalid flash signature.\n");
+ return status;
+ }
+
+ for (i = 0; i < size; i++)
+ csum += le16_to_cpu(*flash++);
+
+ if (csum)
+ QPRINTK(qdev, IFUP, ERR,
+ "Invalid flash checksum, csum = 0x%.04x.\n", csum);
+
+ return csum;
+}
+
+static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
{
int status = 0;
/* wait for reg to come ready */
@@ -656,29 +660,110 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR);
if (status)
goto exit;
- /* get the data */
- *data = ql_read32(qdev, FLASH_DATA);
+ /* This data is stored on flash as an array of
+ * __le32. Since ql_read32() returns cpu endian
+ * we need to swap it back.
+ */
+ *data = cpu_to_le32(ql_read32(qdev, FLASH_DATA));
exit:
return status;
}
-static int ql_get_flash_params(struct ql_adapter *qdev)
+static int ql_get_8000_flash_params(struct ql_adapter *qdev)
+{
+ u32 i, size;
+ int status;
+ __le32 *p = (__le32 *)&qdev->flash;
+ u32 offset;
+
+ /* Get flash offset for function and adjust
+ * for dword access.
+ */
+ if (!qdev->func)
+ offset = FUNC0_FLASH_OFFSET / sizeof(u32);
+ else
+ offset = FUNC1_FLASH_OFFSET / sizeof(u32);
+
+ if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
+ return -ETIMEDOUT;
+
+ size = sizeof(struct flash_params_8000) / sizeof(u32);
+ for (i = 0; i < size; i++, p++) {
+ status = ql_read_flash_word(qdev, i+offset, p);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
+ goto exit;
+ }
+ }
+
+ status = ql_validate_flash(qdev,
+ sizeof(struct flash_params_8000) / sizeof(u16),
+ "8000");
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (!is_valid_ether_addr(qdev->flash.flash_params_8000.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,
+ qdev->ndev->addr_len);
+
+exit:
+ ql_sem_unlock(qdev, SEM_FLASH_MASK);
+ return status;
+}
+
+static int ql_get_8012_flash_params(struct ql_adapter *qdev)
{
int i;
int status;
- u32 *p = (u32 *)&qdev->flash;
+ __le32 *p = (__le32 *)&qdev->flash;
+ u32 offset = 0;
+ u32 size = sizeof(struct flash_params_8012) / sizeof(u32);
+
+ /* Second function's parameters follow the first
+ * function's.
+ */
+ if (qdev->func)
+ offset = size;
if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
return -ETIMEDOUT;
- for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) {
- status = ql_read_flash_word(qdev, i, p);
+ for (i = 0; i < size; i++, p++) {
+ status = ql_read_flash_word(qdev, i+offset, p);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
goto exit;
}
}
+
+ status = ql_validate_flash(qdev,
+ sizeof(struct flash_params_8012) / sizeof(u16),
+ "8012");
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (!is_valid_ether_addr(qdev->flash.flash_params_8012.mac_addr)) {
+ status = -EINVAL;
+ goto exit;
+ }
+
+ memcpy(qdev->ndev->dev_addr,
+ qdev->flash.flash_params_8012.mac_addr,
+ qdev->ndev->addr_len);
+
exit:
ql_sem_unlock(qdev, SEM_FLASH_MASK);
return status;
@@ -749,13 +834,25 @@ exit:
return status;
}
+static int ql_8000_port_initialize(struct ql_adapter *qdev)
+{
+ int status;
+ status = ql_mb_get_fw_state(qdev);
+ if (status)
+ goto exit;
+ /* Wake up a worker to get/set the TX/RX frame sizes. */
+ queue_delayed_work(qdev->workqueue, &qdev->mpi_port_cfg_work, 0);
+exit:
+ return status;
+}
+
/* Take the MAC Core out of reset.
* Enable statistics counting.
* Take the transmitter/receiver out of reset.
* This functionality may be done in the MPI firmware at a
* later date.
*/
-static int ql_port_initialize(struct ql_adapter *qdev)
+static int ql_8012_port_initialize(struct ql_adapter *qdev)
{
int status = 0;
u32 data;
@@ -871,7 +968,8 @@ static void ql_write_cq_idx(struct rx_ring *rx_ring)
/* Process (refill) a large buffer queue. */
static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
- int clean_idx = rx_ring->lbq_clean_idx;
+ u32 clean_idx = rx_ring->lbq_clean_idx;
+ u32 start_idx = clean_idx;
struct bq_desc *lbq_desc;
u64 map;
int i;
@@ -888,6 +986,7 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
lbq_desc->index);
lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
if (lbq_desc->p.lbq_page == NULL) {
+ rx_ring->lbq_clean_idx = clean_idx;
QPRINTK(qdev, RX_STATUS, ERR,
"Couldn't get a page.\n");
return;
@@ -897,6 +996,9 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
0, PAGE_SIZE,
PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(qdev->pdev, map)) {
+ rx_ring->lbq_clean_idx = clean_idx;
+ put_page(lbq_desc->p.lbq_page);
+ lbq_desc->p.lbq_page = NULL;
QPRINTK(qdev, RX_STATUS, ERR,
"PCI mapping failed.\n");
return;
@@ -914,19 +1016,23 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
rx_ring->lbq_prod_idx += 16;
if (rx_ring->lbq_prod_idx == rx_ring->lbq_len)
rx_ring->lbq_prod_idx = 0;
+ rx_ring->lbq_free_cnt -= 16;
+ }
+
+ if (start_idx != clean_idx) {
QPRINTK(qdev, RX_STATUS, DEBUG,
"lbq: updating prod idx = %d.\n",
rx_ring->lbq_prod_idx);
ql_write_db_reg(rx_ring->lbq_prod_idx,
rx_ring->lbq_prod_idx_db_reg);
- rx_ring->lbq_free_cnt -= 16;
}
}
/* Process (refill) a small buffer queue. */
static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
- int clean_idx = rx_ring->sbq_clean_idx;
+ u32 clean_idx = rx_ring->sbq_clean_idx;
+ u32 start_idx = clean_idx;
struct bq_desc *sbq_desc;
u64 map;
int i;
@@ -958,6 +1064,8 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
if (pci_dma_mapping_error(qdev->pdev, map)) {
QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
rx_ring->sbq_clean_idx = clean_idx;
+ dev_kfree_skb_any(sbq_desc->p.skb);
+ sbq_desc->p.skb = NULL;
return;
}
pci_unmap_addr_set(sbq_desc, mapaddr, map);
@@ -974,13 +1082,15 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
rx_ring->sbq_prod_idx += 16;
if (rx_ring->sbq_prod_idx == rx_ring->sbq_len)
rx_ring->sbq_prod_idx = 0;
+ rx_ring->sbq_free_cnt -= 16;
+ }
+
+ if (start_idx != clean_idx) {
QPRINTK(qdev, RX_STATUS, DEBUG,
"sbq: updating prod idx = %d.\n",
rx_ring->sbq_prod_idx);
ql_write_db_reg(rx_ring->sbq_prod_idx,
rx_ring->sbq_prod_idx_db_reg);
-
- rx_ring->sbq_free_cnt -= 16;
}
}
@@ -1396,6 +1506,8 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
{
struct net_device *ndev = qdev->ndev;
struct sk_buff *skb = NULL;
+ u16 vlan_id = (le16_to_cpu(ib_mac_rsp->vlan_id) &
+ IB_MAC_IOCB_RSP_VLAN_MASK)
QL_DUMP_IB_MAC_RSP(ib_mac_rsp);
@@ -1420,31 +1532,53 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) {
QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n");
}
- if (ib_mac_rsp->flags1 & (IB_MAC_IOCB_RSP_IE | IB_MAC_IOCB_RSP_TE)) {
- QPRINTK(qdev, RX_STATUS, ERR,
- "Bad checksum for this %s packet.\n",
- ((ib_mac_rsp->
- flags2 & IB_MAC_IOCB_RSP_T) ? "TCP" : "UDP"));
- skb->ip_summed = CHECKSUM_NONE;
- } else if (qdev->rx_csum &&
- ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) ||
- ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) &&
- !(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_NU)))) {
- QPRINTK(qdev, RX_STATUS, DEBUG, "RX checksum done!\n");
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ skb->protocol = eth_type_trans(skb, ndev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ /* If rx checksum is on, and there are no
+ * 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) {
+ QPRINTK(qdev, RX_STATUS, DEBUG,
+ "TCP checksum done!\n");
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) &&
+ (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) {
+ /* Unfragmented ipv4 UDP frame. */
+ struct iphdr *iph = (struct iphdr *) skb->data;
+ if (!(iph->frag_off &
+ cpu_to_be16(IP_MF|IP_OFFSET))) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ QPRINTK(qdev, RX_STATUS, DEBUG,
+ "TCP checksum done!\n");
+ }
+ }
}
+
qdev->stats.rx_packets++;
qdev->stats.rx_bytes += skb->len;
- skb->protocol = eth_type_trans(skb, ndev);
- if (qdev->vlgrp && (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V)) {
- QPRINTK(qdev, RX_STATUS, DEBUG,
- "Passing a VLAN packet upstream.\n");
- vlan_hwaccel_rx(skb, qdev->vlgrp,
- le16_to_cpu(ib_mac_rsp->vlan_id));
+ skb_record_rx_queue(skb,
+ rx_ring->cq_id - qdev->rss_ring_first_cq_id);
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ if (qdev->vlgrp &&
+ (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) &&
+ (vlan_id != 0))
+ vlan_gro_receive(&rx_ring->napi, qdev->vlgrp,
+ vlan_id, skb);
+ else
+ napi_gro_receive(&rx_ring->napi, skb);
} else {
- QPRINTK(qdev, RX_STATUS, DEBUG,
- "Passing a normal packet upstream.\n");
- netif_rx(skb);
+ if (qdev->vlgrp &&
+ (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) &&
+ (vlan_id != 0))
+ vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id);
+ else
+ netif_receive_skb(skb);
}
}
@@ -1491,16 +1625,19 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev,
/* Fire up a handler to reset the MPI processor. */
void ql_queue_fw_error(struct ql_adapter *qdev)
{
- netif_stop_queue(qdev->ndev);
netif_carrier_off(qdev->ndev);
queue_delayed_work(qdev->workqueue, &qdev->mpi_reset_work, 0);
}
void ql_queue_asic_error(struct ql_adapter *qdev)
{
- netif_stop_queue(qdev->ndev);
netif_carrier_off(qdev->ndev);
ql_disable_interrupts(qdev);
+ /* Clear adapter up bit to signal the recovery
+ * process that it shouldn't kill the reset worker
+ * thread
+ */
+ clear_bit(QL_ADAPTER_UP, &qdev->flags);
queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
}
@@ -1548,6 +1685,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
struct ob_mac_iocb_rsp *net_rsp = NULL;
int count = 0;
+ struct tx_ring *tx_ring;
/* While there are entries in the completion queue. */
while (prod != rx_ring->cnsmr_idx) {
@@ -1573,15 +1711,16 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
}
ql_write_cq_idx(rx_ring);
- if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) {
- struct tx_ring *tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
+ tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
+ if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) &&
+ net_rsp != NULL) {
if (atomic_read(&tx_ring->queue_stopped) &&
(atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4)))
/*
* The queue got stopped because the tx_ring was full.
* Wake it up, because it's now at least 25% empty.
*/
- netif_wake_queue(qdev->ndev);
+ netif_wake_subqueue(qdev->ndev, tx_ring->wq_id);
}
return count;
@@ -1642,7 +1781,7 @@ static int ql_napi_poll_msix(struct napi_struct *napi, int budget)
rx_ring->cq_id);
if (work_done < budget) {
- __netif_rx_complete(napi);
+ napi_complete(napi);
ql_enable_completion_interrupt(qdev, rx_ring->irq);
}
return work_done;
@@ -1668,19 +1807,29 @@ static void ql_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
{
struct ql_adapter *qdev = netdev_priv(ndev);
u32 enable_bit = MAC_ADDR_E;
+ int status;
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
if (ql_set_mac_addr_reg
(qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n");
}
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
{
struct ql_adapter *qdev = netdev_priv(ndev);
u32 enable_bit = 0;
+ int status;
+
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
if (ql_set_mac_addr_reg
@@ -1688,6 +1837,7 @@ static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n");
}
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
@@ -1727,7 +1877,7 @@ static irqreturn_t qlge_msix_tx_isr(int irq, void *dev_id)
static irqreturn_t qlge_msix_rx_isr(int irq, void *dev_id)
{
struct rx_ring *rx_ring = dev_id;
- netif_rx_schedule(&rx_ring->napi);
+ napi_schedule(&rx_ring->napi);
return IRQ_HANDLED;
}
@@ -1813,7 +1963,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
&rx_ring->rx_work,
0);
else
- netif_rx_schedule(&rx_ring->napi);
+ napi_schedule(&rx_ring->napi);
work_done++;
}
}
@@ -1902,25 +2052,24 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
struct ql_adapter *qdev = netdev_priv(ndev);
int tso;
struct tx_ring *tx_ring;
- u32 tx_ring_idx = (u32) QL_TXQ_IDX(qdev, skb);
+ u32 tx_ring_idx = (u32) skb->queue_mapping;
tx_ring = &qdev->tx_ring[tx_ring_idx];
+ if (skb_padto(skb, ETH_ZLEN))
+ return NETDEV_TX_OK;
+
if (unlikely(atomic_read(&tx_ring->tx_count) < 2)) {
QPRINTK(qdev, TX_QUEUED, INFO,
"%s: shutting down tx queue %d du to lack of resources.\n",
__func__, tx_ring_idx);
- netif_stop_queue(ndev);
+ netif_stop_subqueue(ndev, tx_ring->wq_id);
atomic_inc(&tx_ring->queue_stopped);
return NETDEV_TX_BUSY;
}
tx_ring_desc = &tx_ring->q[tx_ring->prod_idx];
mac_iocb_ptr = tx_ring_desc->queue_entry;
memset((void *)mac_iocb_ptr, 0, sizeof(mac_iocb_ptr));
- if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) != NETDEV_TX_OK) {
- QPRINTK(qdev, TX_QUEUED, ERR, "Could not map the segments.\n");
- return NETDEV_TX_BUSY;
- }
mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB;
mac_iocb_ptr->tid = tx_ring_desc->index;
@@ -1946,6 +2095,12 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
ql_hw_csum_setup(skb,
(struct ob_mac_tso_iocb_req *)mac_iocb_ptr);
}
+ if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) !=
+ NETDEV_TX_OK) {
+ QPRINTK(qdev, TX_QUEUED, ERR,
+ "Could not map the segments.\n");
+ return NETDEV_TX_BUSY;
+ }
QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr);
tx_ring->prod_idx++;
if (tx_ring->prod_idx == tx_ring->wq_len)
@@ -1989,6 +2144,7 @@ static int ql_alloc_shadow_space(struct ql_adapter *qdev)
"Allocation of RX shadow space failed.\n");
return -ENOMEM;
}
+ memset(qdev->rx_ring_shadow_reg_area, 0, PAGE_SIZE);
qdev->tx_ring_shadow_reg_area =
pci_alloc_consistent(qdev->pdev, PAGE_SIZE,
&qdev->tx_ring_shadow_reg_dma);
@@ -1997,6 +2153,7 @@ static int ql_alloc_shadow_space(struct ql_adapter *qdev)
"Allocation of TX shadow space failed.\n");
goto err_wqp_sh_area;
}
+ memset(qdev->tx_ring_shadow_reg_area, 0, PAGE_SIZE);
return 0;
err_wqp_sh_area:
@@ -2081,47 +2238,6 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
}
}
-/*
- * Allocate and map a page for each element of the lbq.
- */
-static int ql_alloc_lbq_buffers(struct ql_adapter *qdev,
- struct rx_ring *rx_ring)
-{
- int i;
- struct bq_desc *lbq_desc;
- u64 map;
- __le64 *bq = rx_ring->lbq_base;
-
- for (i = 0; i < rx_ring->lbq_len; i++) {
- lbq_desc = &rx_ring->lbq[i];
- memset(lbq_desc, 0, sizeof(lbq_desc));
- lbq_desc->addr = bq;
- lbq_desc->index = i;
- lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
- if (unlikely(!lbq_desc->p.lbq_page)) {
- QPRINTK(qdev, IFUP, ERR, "failed alloc_page().\n");
- goto mem_error;
- } else {
- map = pci_map_page(qdev->pdev,
- lbq_desc->p.lbq_page,
- 0, PAGE_SIZE, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(qdev->pdev, map)) {
- QPRINTK(qdev, IFUP, ERR,
- "PCI mapping failed.\n");
- goto mem_error;
- }
- pci_unmap_addr_set(lbq_desc, mapaddr, map);
- pci_unmap_len_set(lbq_desc, maplen, PAGE_SIZE);
- *lbq_desc->addr = cpu_to_le64(map);
- }
- bq++;
- }
- return 0;
-mem_error:
- ql_free_lbq_buffers(qdev, rx_ring);
- return -ENOMEM;
-}
-
static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
int i;
@@ -2144,63 +2260,72 @@ static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
}
}
-/* Allocate and map an skb for each element of the sbq. */
-static int ql_alloc_sbq_buffers(struct ql_adapter *qdev,
+/* Free all large and small rx buffers associated
+ * with the completion queues for this device.
+ */
+static void ql_free_rx_buffers(struct ql_adapter *qdev)
+{
+ int i;
+ struct rx_ring *rx_ring;
+
+ for (i = 0; i < qdev->rx_ring_count; i++) {
+ rx_ring = &qdev->rx_ring[i];
+ if (rx_ring->lbq)
+ ql_free_lbq_buffers(qdev, rx_ring);
+ if (rx_ring->sbq)
+ ql_free_sbq_buffers(qdev, rx_ring);
+ }
+}
+
+static void ql_alloc_rx_buffers(struct ql_adapter *qdev)
+{
+ struct rx_ring *rx_ring;
+ int i;
+
+ for (i = 0; i < qdev->rx_ring_count; i++) {
+ rx_ring = &qdev->rx_ring[i];
+ if (rx_ring->type != TX_Q)
+ ql_update_buffer_queues(qdev, rx_ring);
+ }
+}
+
+static void ql_init_lbq_ring(struct ql_adapter *qdev,
+ struct rx_ring *rx_ring)
+{
+ int i;
+ struct bq_desc *lbq_desc;
+ __le64 *bq = rx_ring->lbq_base;
+
+ memset(rx_ring->lbq, 0, rx_ring->lbq_len * sizeof(struct bq_desc));
+ for (i = 0; i < rx_ring->lbq_len; i++) {
+ lbq_desc = &rx_ring->lbq[i];
+ memset(lbq_desc, 0, sizeof(*lbq_desc));
+ lbq_desc->index = i;
+ lbq_desc->addr = bq;
+ bq++;
+ }
+}
+
+static void ql_init_sbq_ring(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
int i;
struct bq_desc *sbq_desc;
- struct sk_buff *skb;
- u64 map;
__le64 *bq = rx_ring->sbq_base;
+ memset(rx_ring->sbq, 0, rx_ring->sbq_len * sizeof(struct bq_desc));
for (i = 0; i < rx_ring->sbq_len; i++) {
sbq_desc = &rx_ring->sbq[i];
- memset(sbq_desc, 0, sizeof(sbq_desc));
+ memset(sbq_desc, 0, sizeof(*sbq_desc));
sbq_desc->index = i;
sbq_desc->addr = bq;
- skb = netdev_alloc_skb(qdev->ndev, rx_ring->sbq_buf_size);
- if (unlikely(!skb)) {
- /* Better luck next round */
- QPRINTK(qdev, IFUP, ERR,
- "small buff alloc failed for %d bytes at index %d.\n",
- rx_ring->sbq_buf_size, i);
- goto mem_err;
- }
- skb_reserve(skb, QLGE_SB_PAD);
- sbq_desc->p.skb = skb;
- /*
- * Map only half the buffer. Because the
- * other half may get some data copied to it
- * when the completion arrives.
- */
- map = pci_map_single(qdev->pdev,
- skb->data,
- rx_ring->sbq_buf_size / 2,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(qdev->pdev, map)) {
- QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
- goto mem_err;
- }
- pci_unmap_addr_set(sbq_desc, mapaddr, map);
- pci_unmap_len_set(sbq_desc, maplen, rx_ring->sbq_buf_size / 2);
- *sbq_desc->addr = cpu_to_le64(map);
bq++;
}
- return 0;
-mem_err:
- ql_free_sbq_buffers(qdev, rx_ring);
- return -ENOMEM;
}
static void ql_free_rx_resources(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
- if (rx_ring->sbq_len)
- ql_free_sbq_buffers(qdev, rx_ring);
- if (rx_ring->lbq_len)
- ql_free_lbq_buffers(qdev, rx_ring);
-
/* Free the small buffer queue. */
if (rx_ring->sbq_base) {
pci_free_consistent(qdev->pdev,
@@ -2278,11 +2403,7 @@ static int ql_alloc_rx_resources(struct ql_adapter *qdev,
goto err_mem;
}
- if (ql_alloc_sbq_buffers(qdev, rx_ring)) {
- QPRINTK(qdev, IFUP, ERR,
- "Small buffer allocation failed.\n");
- goto err_mem;
- }
+ ql_init_sbq_ring(qdev, rx_ring);
}
if (rx_ring->lbq_len) {
@@ -2310,14 +2431,7 @@ static int ql_alloc_rx_resources(struct ql_adapter *qdev,
goto err_mem;
}
- /*
- * Allocate the buffers.
- */
- if (ql_alloc_lbq_buffers(qdev, rx_ring)) {
- QPRINTK(qdev, IFUP, ERR,
- "Large buffer allocation failed.\n");
- goto err_mem;
- }
+ ql_init_lbq_ring(qdev, rx_ring);
}
return 0;
@@ -2411,6 +2525,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id));
int err = 0;
u16 bq_len;
+ u64 tmp;
/* Set up the shadow registers for this ring. */
rx_ring->prod_idx_sh_reg = shadow_reg;
@@ -2456,7 +2571,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
FLAGS_LI; /* Load irq delay values */
if (rx_ring->lbq_len) {
cqicb->flags |= FLAGS_LL; /* Load lbq values */
- *((u64 *) rx_ring->lbq_base_indirect) = rx_ring->lbq_base_dma;
+ tmp = (u64)rx_ring->lbq_base_dma;;
+ *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp);
cqicb->lbq_addr =
cpu_to_le64(rx_ring->lbq_base_indirect_dma);
bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 :
@@ -2465,25 +2581,26 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
bq_len = (rx_ring->lbq_len == 65536) ? 0 :
(u16) rx_ring->lbq_len;
cqicb->lbq_len = cpu_to_le16(bq_len);
- rx_ring->lbq_prod_idx = rx_ring->lbq_len - 16;
+ rx_ring->lbq_prod_idx = 0;
rx_ring->lbq_curr_idx = 0;
- rx_ring->lbq_clean_idx = rx_ring->lbq_prod_idx;
- rx_ring->lbq_free_cnt = 16;
+ rx_ring->lbq_clean_idx = 0;
+ rx_ring->lbq_free_cnt = rx_ring->lbq_len;
}
if (rx_ring->sbq_len) {
cqicb->flags |= FLAGS_LS; /* Load sbq values */
- *((u64 *) rx_ring->sbq_base_indirect) = rx_ring->sbq_base_dma;
+ tmp = (u64)rx_ring->sbq_base_dma;;
+ *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp);
cqicb->sbq_addr =
cpu_to_le64(rx_ring->sbq_base_indirect_dma);
cqicb->sbq_buf_size =
- cpu_to_le16(((rx_ring->sbq_buf_size / 2) + 8) & 0xfffffff8);
+ cpu_to_le16((u16)(rx_ring->sbq_buf_size/2));
bq_len = (rx_ring->sbq_len == 65536) ? 0 :
(u16) rx_ring->sbq_len;
cqicb->sbq_len = cpu_to_le16(bq_len);
- rx_ring->sbq_prod_idx = rx_ring->sbq_len - 16;
+ rx_ring->sbq_prod_idx = 0;
rx_ring->sbq_curr_idx = 0;
- rx_ring->sbq_clean_idx = rx_ring->sbq_prod_idx;
- rx_ring->sbq_free_cnt = 16;
+ rx_ring->sbq_clean_idx = 0;
+ rx_ring->sbq_free_cnt = rx_ring->sbq_len;
}
switch (rx_ring->type) {
case TX_Q:
@@ -2529,24 +2646,13 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
QPRINTK(qdev, IFUP, DEBUG, "Invalid rx_ring->type = %d.\n",
rx_ring->type);
}
- QPRINTK(qdev, IFUP, INFO, "Initializing rx work queue.\n");
+ QPRINTK(qdev, IFUP, DEBUG, "Initializing rx work queue.\n");
err = ql_write_cfg(qdev, cqicb, sizeof(struct cqicb),
CFG_LCQ, rx_ring->cq_id);
if (err) {
QPRINTK(qdev, IFUP, ERR, "Failed to load CQICB.\n");
return err;
}
- QPRINTK(qdev, IFUP, INFO, "Successfully loaded CQICB.\n");
- /*
- * Advance the producer index for the buffer queues.
- */
- wmb();
- if (rx_ring->lbq_len)
- ql_write_db_reg(rx_ring->lbq_prod_idx,
- rx_ring->lbq_prod_idx_db_reg);
- if (rx_ring->sbq_len)
- ql_write_db_reg(rx_ring->sbq_prod_idx,
- rx_ring->sbq_prod_idx_db_reg);
return err;
}
@@ -2593,7 +2699,7 @@ static int ql_start_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring)
QPRINTK(qdev, IFUP, ERR, "Failed to load tx_ring.\n");
return err;
}
- QPRINTK(qdev, IFUP, INFO, "Successfully loaded WQICB.\n");
+ QPRINTK(qdev, IFUP, DEBUG, "Successfully loaded WQICB.\n");
return err;
}
@@ -2635,7 +2741,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
(qdev->pdev, qdev->msi_x_entry, qdev->rx_ring_count)) {
set_bit(QL_MSIX_ENABLED, &qdev->flags);
qdev->intr_count = qdev->rx_ring_count;
- QPRINTK(qdev, IFUP, INFO,
+ QPRINTK(qdev, IFUP, DEBUG,
"MSI-X Enabled, got %d vectors.\n",
qdev->intr_count);
return;
@@ -2762,11 +2868,11 @@ static void ql_free_irq(struct ql_adapter *qdev)
if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) {
free_irq(qdev->msi_x_entry[i].vector,
&qdev->rx_ring[i]);
- QPRINTK(qdev, IFDOWN, ERR,
+ QPRINTK(qdev, IFDOWN, DEBUG,
"freeing msix interrupt %d.\n", i);
} else {
free_irq(qdev->pdev->irq, &qdev->rx_ring[0]);
- QPRINTK(qdev, IFDOWN, ERR,
+ QPRINTK(qdev, IFDOWN, DEBUG,
"freeing msi interrupt %d.\n", i);
}
}
@@ -2797,7 +2903,7 @@ static int ql_request_irq(struct ql_adapter *qdev)
i);
goto err_irq;
} else {
- QPRINTK(qdev, IFUP, INFO,
+ QPRINTK(qdev, IFUP, DEBUG,
"Hooked intr %d, queue type %s%s%s, with name %s.\n",
i,
qdev->rx_ring[i].type ==
@@ -2863,8 +2969,8 @@ static int ql_start_rss(struct ql_adapter *qdev)
/*
* Fill out the Indirection Table.
*/
- for (i = 0; i < 32; i++)
- hash_id[i] = i & 1;
+ for (i = 0; i < 256; i++)
+ hash_id[i] = i & (qdev->rss_ring_count - 1);
/*
* Random values for the IPv6 and IPv4 Hash Keys.
@@ -2872,14 +2978,14 @@ static int ql_start_rss(struct ql_adapter *qdev)
get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40);
get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16);
- QPRINTK(qdev, IFUP, INFO, "Initializing RSS.\n");
+ QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
status = ql_write_cfg(qdev, ricb, sizeof(ricb), CFG_LR, 0);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Failed to load RICB.\n");
return status;
}
- QPRINTK(qdev, IFUP, INFO, "Successfully loaded RICB.\n");
+ QPRINTK(qdev, IFUP, DEBUG, "Successfully loaded RICB.\n");
return status;
}
@@ -2889,13 +2995,17 @@ static int ql_route_initialize(struct ql_adapter *qdev)
int status = 0;
int i;
+ status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (status)
+ return status;
+
/* Clear all the entries in the routing table. */
for (i = 0; i < 16; i++) {
status = ql_set_routing_reg(qdev, i, 0, 0);
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for CAM packets.\n");
- return status;
+ goto exit;
}
}
@@ -2903,13 +3013,13 @@ static int ql_route_initialize(struct ql_adapter *qdev)
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for error packets.\n");
- return status;
+ goto exit;
}
status = ql_set_routing_reg(qdev, RT_IDX_BCAST_SLOT, RT_IDX_BCAST, 1);
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for broadcast packets.\n");
- return status;
+ goto exit;
}
/* If we have more than one inbound queue, then turn on RSS in the
* routing block.
@@ -2920,17 +3030,39 @@ static int ql_route_initialize(struct ql_adapter *qdev)
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for MATCH RSS packets.\n");
- return status;
+ goto exit;
}
}
status = ql_set_routing_reg(qdev, RT_IDX_CAM_HIT_SLOT,
RT_IDX_CAM_HIT, 1);
- if (status) {
+ if (status)
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for CAM packets.\n");
+exit:
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
+ return status;
+}
+
+int ql_cam_route_initialize(struct ql_adapter *qdev)
+{
+ int status;
+
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return status;
+ status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
+ MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
return status;
}
+
+ status = ql_route_initialize(qdev);
+ if (status)
+ QPRINTK(qdev, IFUP, ERR, "Failed to init routing table.\n");
+
return status;
}
@@ -2947,9 +3079,9 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
mask = value << 16;
ql_write32(qdev, SYS, mask | value);
- /* Set the default queue. */
- value = NIC_RCV_CFG_DFQ;
- mask = NIC_RCV_CFG_DFQ_MASK;
+ /* Set the default queue, and VLAN behavior. */
+ value = NIC_RCV_CFG_DFQ | NIC_RCV_CFG_RV;
+ mask = NIC_RCV_CFG_DFQ_MASK | (NIC_RCV_CFG_RV << 16);
ql_write32(qdev, NIC_RCV_CFG, (mask | value));
/* Set the MPI interrupt to enabled. */
@@ -2998,28 +3130,24 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
}
}
- status = ql_port_initialize(qdev);
- if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
- return status;
- }
-
- status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func);
- if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
- return status;
- }
+ /* Initialize the port and set the max framesize. */
+ status = qdev->nic_ops->port_initialize(qdev);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
+ return status;
+ }
- status = ql_route_initialize(qdev);
+ /* Set up the MAC address and frame routing filter. */
+ status = ql_cam_route_initialize(qdev);
if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to init routing table.\n");
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
return status;
}
/* Start NAPI for the RSS queues. */
for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++) {
- QPRINTK(qdev, IFUP, INFO, "Enabling NAPI for rx_ring[%d].\n",
+ QPRINTK(qdev, IFUP, DEBUG, "Enabling NAPI for rx_ring[%d].\n",
i);
napi_enable(&qdev->rx_ring[i].napi);
}
@@ -3031,36 +3159,23 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
static int ql_adapter_reset(struct ql_adapter *qdev)
{
u32 value;
- int max_wait_time;
int status = 0;
- int resetCnt = 0;
+ unsigned long end_jiffies = jiffies +
+ max((unsigned long)1, usecs_to_jiffies(30));
-#define MAX_RESET_CNT 1
-issueReset:
- resetCnt++;
- QPRINTK(qdev, IFDOWN, DEBUG, "Issue soft reset to chip.\n");
ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
- /* Wait for reset to complete. */
- max_wait_time = 3;
- QPRINTK(qdev, IFDOWN, DEBUG, "Wait %d seconds for reset to complete.\n",
- max_wait_time);
+
do {
value = ql_read32(qdev, RST_FO);
if ((value & RST_FO_FR) == 0)
break;
+ cpu_relax();
+ } while (time_before(jiffies, end_jiffies));
- ssleep(1);
- } while ((--max_wait_time));
if (value & RST_FO_FR) {
QPRINTK(qdev, IFDOWN, ERR,
- "Stuck in SoftReset: FSC_SR:0x%08x\n", value);
- if (resetCnt < MAX_RESET_CNT)
- goto issueReset;
- }
- if (max_wait_time == 0) {
- status = -ETIMEDOUT;
- QPRINTK(qdev, IFDOWN, ERR,
"ETIMEOUT!!! errored out of resetting the chip!\n");
+ status = -ETIMEDOUT;
}
return status;
@@ -3083,16 +3198,20 @@ static void ql_display_dev_info(struct net_device *ndev)
static int ql_adapter_down(struct ql_adapter *qdev)
{
- struct net_device *ndev = qdev->ndev;
int i, status = 0;
struct rx_ring *rx_ring;
- netif_stop_queue(ndev);
- netif_carrier_off(ndev);
+ netif_carrier_off(qdev->ndev);
- cancel_delayed_work_sync(&qdev->asic_reset_work);
+ /* Don't kill the reset worker thread if we
+ * are in the process of recovery.
+ */
+ if (test_bit(QL_ADAPTER_UP, &qdev->flags))
+ cancel_delayed_work_sync(&qdev->asic_reset_work);
cancel_delayed_work_sync(&qdev->mpi_reset_work);
cancel_delayed_work_sync(&qdev->mpi_work);
+ cancel_delayed_work_sync(&qdev->mpi_idc_work);
+ cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
/* The default queue at index 0 is always processed in
* a workqueue.
@@ -3122,6 +3241,13 @@ static int ql_adapter_down(struct ql_adapter *qdev)
ql_tx_ring_clean(qdev);
+ /* Call netif_napi_del() from common point.
+ */
+ for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++)
+ netif_napi_del(&qdev->rx_ring[i].napi);
+
+ ql_free_rx_buffers(qdev);
+
spin_lock(&qdev->hw_lock);
status = ql_adapter_reset(qdev);
if (status)
@@ -3135,21 +3261,19 @@ static int ql_adapter_up(struct ql_adapter *qdev)
{
int err = 0;
- spin_lock(&qdev->hw_lock);
err = ql_adapter_initialize(qdev);
if (err) {
QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n");
spin_unlock(&qdev->hw_lock);
goto err_init;
}
- spin_unlock(&qdev->hw_lock);
set_bit(QL_ADAPTER_UP, &qdev->flags);
+ ql_alloc_rx_buffers(qdev);
+ if ((ql_read32(qdev, STS) & qdev->port_init))
+ netif_carrier_on(qdev->ndev);
ql_enable_interrupts(qdev);
ql_enable_all_completion_interrupts(qdev);
- if ((ql_read32(qdev, STS) & qdev->port_init)) {
- netif_carrier_on(qdev->ndev);
- netif_start_queue(qdev->ndev);
- }
+ netif_tx_start_all_queues(qdev->ndev);
return 0;
err_init:
@@ -3157,28 +3281,6 @@ err_init:
return err;
}
-static int ql_cycle_adapter(struct ql_adapter *qdev)
-{
- int status;
-
- status = ql_adapter_down(qdev);
- if (status)
- goto error;
-
- status = ql_adapter_up(qdev);
- if (status)
- goto error;
-
- return status;
-error:
- QPRINTK(qdev, IFUP, ALERT,
- "Driver up/down cycle failed, closing device\n");
- rtnl_lock();
- dev_close(qdev->ndev);
- rtnl_unlock();
- return status;
-}
-
static void ql_release_adapter_resources(struct ql_adapter *qdev)
{
ql_free_mem_resources(qdev);
@@ -3259,6 +3361,7 @@ 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];
@@ -3365,6 +3468,8 @@ static int qlge_change_mtu(struct net_device *ndev, int new_mtu)
if (ndev->mtu == 1500 && new_mtu == 9000) {
QPRINTK(qdev, IFUP, ERR, "Changing to jumbo MTU.\n");
+ queue_delayed_work(qdev->workqueue,
+ &qdev->mpi_port_cfg_work, 0);
} else if (ndev->mtu == 9000 && new_mtu == 1500) {
QPRINTK(qdev, IFUP, ERR, "Changing to normal MTU.\n");
} else if ((ndev->mtu == 1500 && new_mtu == 1500) ||
@@ -3387,8 +3492,11 @@ static void qlge_set_multicast_list(struct net_device *ndev)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
struct dev_mc_list *mc_ptr;
- int i;
+ int i, status;
+ status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
/*
* Set or clear promiscuous mode if a
@@ -3444,14 +3552,19 @@ static void qlge_set_multicast_list(struct net_device *ndev)
}
if (ndev->mc_count) {
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ goto exit;
for (i = 0, mc_ptr = ndev->mc_list; mc_ptr;
i++, mc_ptr = mc_ptr->next)
if (ql_set_mac_addr_reg(qdev, (u8 *) mc_ptr->dmi_addr,
MAC_ADDR_TYPE_MULTI_MAC, i)) {
QPRINTK(qdev, HW, ERR,
"Failed to loadmulticast address.\n");
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
goto exit;
}
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
if (ql_set_routing_reg
(qdev, RT_IDX_MCAST_MATCH_SLOT, RT_IDX_MCAST_MATCH, 1)) {
QPRINTK(qdev, HW, ERR,
@@ -3462,13 +3575,14 @@ static void qlge_set_multicast_list(struct net_device *ndev)
}
exit:
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
}
static int qlge_set_mac_address(struct net_device *ndev, void *p)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
struct sockaddr *addr = p;
- int ret = 0;
+ int status;
if (netif_running(ndev))
return -EBUSY;
@@ -3477,30 +3591,60 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
return -EADDRNOTAVAIL;
memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return status;
spin_lock(&qdev->hw_lock);
- if (ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func)) {/* Unicast */
- QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
- ret = -1;
- }
+ status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
+ MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
spin_unlock(&qdev->hw_lock);
-
- return ret;
+ if (status)
+ QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+ return status;
}
static void qlge_tx_timeout(struct net_device *ndev)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
- queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
+ ql_queue_asic_error(qdev);
}
static void ql_asic_reset_work(struct work_struct *work)
{
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, asic_reset_work.work);
- ql_cycle_adapter(qdev);
+ int status;
+
+ status = ql_adapter_down(qdev);
+ if (status)
+ goto error;
+
+ status = ql_adapter_up(qdev);
+ if (status)
+ goto error;
+
+ return;
+error:
+ QPRINTK(qdev, IFUP, ALERT,
+ "Driver up/down cycle failed, closing device\n");
+ rtnl_lock();
+ set_bit(QL_ADAPTER_UP, &qdev->flags);
+ dev_close(qdev->ndev);
+ rtnl_unlock();
}
+static struct nic_operations qla8012_nic_ops = {
+ .get_flash = ql_get_8012_flash_params,
+ .port_initialize = ql_8012_port_initialize,
+};
+
+static struct nic_operations qla8000_nic_ops = {
+ .get_flash = ql_get_8000_flash_params,
+ .port_initialize = ql_8000_port_initialize,
+};
+
+
static void ql_get_board_info(struct ql_adapter *qdev)
{
qdev->func =
@@ -3519,6 +3663,11 @@ static void ql_get_board_info(struct ql_adapter *qdev)
qdev->mailbox_out = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC0_MBO;
}
qdev->chip_rev_id = ql_read32(qdev, REV_ID);
+ qdev->device_id = qdev->pdev->device;
+ if (qdev->device_id == QLGE_DEVICE_ID_8012)
+ qdev->nic_ops = &qla8012_nic_ops;
+ else if (qdev->device_id == QLGE_DEVICE_ID_8000)
+ qdev->nic_ops = &qla8000_nic_ops;
}
static void ql_release_all(struct pci_dev *pdev)
@@ -3611,24 +3760,20 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
goto err_out;
}
- ql_get_board_info(qdev);
qdev->ndev = ndev;
qdev->pdev = pdev;
+ ql_get_board_info(qdev);
qdev->msg_enable = netif_msg_init(debug, default_msg);
spin_lock_init(&qdev->hw_lock);
spin_lock_init(&qdev->stats_lock);
/* make sure the EEPROM is good */
- err = ql_get_flash_params(qdev);
+ err = qdev->nic_ops->get_flash(qdev);
if (err) {
dev_err(&pdev->dev, "Invalid FLASH.\n");
goto err_out;
}
- if (!is_valid_ether_addr(qdev->flash.mac_addr))
- goto err_out;
-
- memcpy(ndev->dev_addr, qdev->flash.mac_addr, ndev->addr_len);
memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
/* Set up the default ring sizes. */
@@ -3651,6 +3796,10 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
+ INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work);
+ INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
+ mutex_init(&qdev->mpi_mutex);
+ init_completion(&qdev->ide_completion);
if (!cards_found) {
dev_info(&pdev->dev, "%s\n", DRV_STRING);
@@ -3688,7 +3837,8 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
static int cards_found = 0;
int err = 0;
- ndev = alloc_etherdev(sizeof(struct ql_adapter));
+ ndev = alloc_etherdev_mq(sizeof(struct ql_adapter),
+ min(MAX_CPUS, (int)num_online_cpus()));
if (!ndev)
return -ENOMEM;
@@ -3708,6 +3858,7 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
| NETIF_F_TSO_ECN
| NETIF_F_HW_VLAN_TX
| NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER);
+ ndev->features |= NETIF_F_GRO;
if (test_bit(QL_DMA64, &qdev->flags))
ndev->features |= NETIF_F_HIGHDMA;
@@ -3730,7 +3881,6 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
return err;
}
netif_carrier_off(ndev);
- netif_stop_queue(ndev);
ql_display_dev_info(ndev);
cards_found++;
return 0;
@@ -3784,7 +3934,6 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev)
pci_set_master(pdev);
netif_carrier_off(ndev);
- netif_stop_queue(ndev);
ql_adapter_reset(qdev);
/* Make sure the EEPROM is good */
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index fa31891b6e6..9f81b797f10 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -1,6 +1,26 @@
#include "qlge.h"
-static int ql_read_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
+static void ql_display_mb_sts(struct ql_adapter *qdev,
+ struct mbox_params *mbcp)
+{
+ int i;
+ static char *err_sts[] = {
+ "Command Complete",
+ "Command Not Supported",
+ "Host Interface Error",
+ "Checksum Error",
+ "Unused Completion Status",
+ "Test Failed",
+ "Command Parameter Error"};
+
+ QPRINTK(qdev, DRV, DEBUG, "%s.\n",
+ err_sts[mbcp->mbox_out[0] & 0x0000000f]);
+ for (i = 0; i < mbcp->out_count; i++)
+ QPRINTK(qdev, DRV, DEBUG, "mbox_out[%d] = 0x%.08x.\n",
+ i, mbcp->mbox_out[i]);
+}
+
+int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
{
int status;
/* wait for reg to come ready */
@@ -19,6 +39,32 @@ exit:
return status;
}
+int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data)
+{
+ int status = 0;
+ /* wait for reg to come ready */
+ status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
+ if (status)
+ goto exit;
+ /* write the data to the data reg */
+ ql_write32(qdev, PROC_DATA, data);
+ /* trigger the write */
+ ql_write32(qdev, PROC_ADDR, reg);
+ /* wait for reg to come ready */
+ status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
+ if (status)
+ goto exit;
+exit:
+ return status;
+}
+
+int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
+{
+ int status;
+ status = ql_write_mpi_reg(qdev, 0x00001010, 1);
+ return status;
+}
+
static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int i, status;
@@ -28,7 +74,7 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
return -EBUSY;
for (i = 0; i < mbcp->out_count; i++) {
status =
- ql_read_mbox_reg(qdev, qdev->mailbox_out + i,
+ ql_read_mpi_reg(qdev, qdev->mailbox_out + i,
&mbcp->mbox_out[i]);
if (status) {
QPRINTK(qdev, DRV, ERR, "Failed mailbox read.\n");
@@ -39,102 +85,762 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
return status;
}
+/* Wait for a single mailbox command to complete.
+ * Returns zero on success.
+ */
+static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev)
+{
+ int count = 50; /* TODO: arbitrary for now. */
+ u32 value;
+
+ do {
+ value = ql_read32(qdev, STS);
+ if (value & STS_PI)
+ return 0;
+ udelay(UDELAY_DELAY); /* 10us */
+ } while (--count);
+ return -ETIMEDOUT;
+}
+
+/* Execute a single mailbox command.
+ * Caller must hold PROC_ADDR semaphore.
+ */
+static int ql_exec_mb_cmd(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int i, status;
+
+ /*
+ * Make sure there's nothing pending.
+ * This shouldn't happen.
+ */
+ if (ql_read32(qdev, CSR) & CSR_HRI)
+ return -EIO;
+
+ status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
+ if (status)
+ return status;
+
+ /*
+ * Fill the outbound mailboxes.
+ */
+ for (i = 0; i < mbcp->in_count; i++) {
+ status = ql_write_mpi_reg(qdev, qdev->mailbox_in + i,
+ mbcp->mbox_in[i]);
+ if (status)
+ goto end;
+ }
+ /*
+ * Wake up the MPI firmware.
+ */
+ ql_write32(qdev, CSR, CSR_CMD_SET_H2R_INT);
+end:
+ ql_sem_unlock(qdev, SEM_PROC_REG_MASK);
+ return status;
+}
+
+/* We are being asked by firmware to accept
+ * a change to the port. This is only
+ * a change to max frame sizes (Tx/Rx), pause
+ * paramters, or loopback mode. We wake up a worker
+ * to handler processing this since a mailbox command
+ * will need to be sent to ACK the request.
+ */
+static int ql_idc_req_aen(struct ql_adapter *qdev)
+{
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+
+ QPRINTK(qdev, DRV, ERR, "Enter!\n");
+ /* Get the status data and start up a thread to
+ * handle the request.
+ */
+ mbcp = &qdev->idc_mbc;
+ mbcp->out_count = 4;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting ASIC!\n");
+ ql_queue_asic_error(qdev);
+ } else {
+ /* Begin polled mode early so
+ * we don't get another interrupt
+ * when we leave mpi_worker.
+ */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+ queue_delayed_work(qdev->workqueue, &qdev->mpi_idc_work, 0);
+ }
+ return status;
+}
+
+/* Process an inter-device event completion.
+ * If good, signal the caller's completion.
+ */
+static int ql_idc_cmplt_aen(struct ql_adapter *qdev)
+{
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+ mbcp->out_count = 4;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting RISC!\n");
+ ql_queue_fw_error(qdev);
+ } else
+ /* Wake up the sleeping mpi_idc_work thread that is
+ * waiting for this event.
+ */
+ complete(&qdev->ide_completion);
+
+ return status;
+}
+
static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
+ int status;
mbcp->out_count = 2;
- if (ql_get_mb_sts(qdev, mbcp))
- goto exit;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "%s: Could not get mailbox status.\n", __func__);
+ return;
+ }
qdev->link_status = mbcp->mbox_out[1];
QPRINTK(qdev, DRV, ERR, "Link Up.\n");
- QPRINTK(qdev, DRV, INFO, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
- if (!netif_carrier_ok(qdev->ndev)) {
- QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
- netif_carrier_on(qdev->ndev);
- netif_wake_queue(qdev->ndev);
+
+ /* If we're coming back from an IDC event
+ * then set up the CAM and frame routing.
+ */
+ if (test_bit(QL_CAM_RT_SET, &qdev->flags)) {
+ status = ql_cam_route_initialize(qdev);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
+ return;
+ } else
+ clear_bit(QL_CAM_RT_SET, &qdev->flags);
}
-exit:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+ /* Queue up a worker to check the frame
+ * size information, and fix it if it's not
+ * to our liking.
+ */
+ if (!test_bit(QL_PORT_CFG, &qdev->flags)) {
+ QPRINTK(qdev, DRV, ERR, "Queue Port Config Worker!\n");
+ set_bit(QL_PORT_CFG, &qdev->flags);
+ /* Begin polled mode early so
+ * we don't get another interrupt
+ * when we leave mpi_worker dpc.
+ */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+ queue_delayed_work(qdev->workqueue,
+ &qdev->mpi_port_cfg_work, 0);
+ }
+
+ netif_carrier_on(qdev->ndev);
}
static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
+ int status;
+
mbcp->out_count = 3;
- if (ql_get_mb_sts(qdev, mbcp)) {
- QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
- goto exit;
- }
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "Link down AEN broken!\n");
+
+ netif_carrier_off(qdev->ndev);
+}
+
+static int ql_sfp_in(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 5;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "SFP in AEN broken!\n");
+ else
+ QPRINTK(qdev, DRV, ERR, "SFP insertion detected.\n");
+
+ return status;
+}
+
+static int ql_sfp_out(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 1;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "SFP out AEN broken!\n");
+ else
+ QPRINTK(qdev, DRV, ERR, "SFP removal detected.\n");
+
+ return status;
+}
+
+static int ql_aen_lost(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 6;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "Lost AEN broken!\n");
+ else {
+ int i;
+ QPRINTK(qdev, DRV, ERR, "Lost AEN detected.\n");
+ for (i = 0; i < mbcp->out_count; i++)
+ QPRINTK(qdev, DRV, ERR, "mbox_out[%d] = 0x%.08x.\n",
+ i, mbcp->mbox_out[i]);
- if (netif_carrier_ok(qdev->ndev)) {
- QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
- netif_carrier_off(qdev->ndev);
- netif_stop_queue(qdev->ndev);
}
- QPRINTK(qdev, DRV, ERR, "Link Down.\n");
- QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
-exit:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+ return status;
}
static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
+ int status;
+
mbcp->out_count = 2;
- if (ql_get_mb_sts(qdev, mbcp)) {
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
- goto exit;
+ } else {
+ QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n",
+ mbcp->mbox_out[1]);
+ status = ql_cam_route_initialize(qdev);
+ if (status)
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
}
- QPRINTK(qdev, DRV, ERR, "Firmware initialized!\n");
- QPRINTK(qdev, DRV, ERR, "Firmware status = 0x%.08x.\n",
- mbcp->mbox_out[0]);
- QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n",
- mbcp->mbox_out[1]);
-exit:
- /* Clear the MPI firmware status. */
+}
+
+/* Process an async event and clear it unless it's an
+ * error condition.
+ * This can get called iteratively from the mpi_work thread
+ * when events arrive via an interrupt.
+ * It also gets called when a mailbox command is polling for
+ * it's completion. */
+static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+ int orig_count = mbcp->out_count;
+
+ /* Just get mailbox zero for now. */
+ mbcp->out_count = 1;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting ASIC!\n");
+ ql_queue_asic_error(qdev);
+ goto end;
+ }
+
+ switch (mbcp->mbox_out[0]) {
+
+ /* This case is only active when we arrive here
+ * as a result of issuing a mailbox command to
+ * the firmware.
+ */
+ case MB_CMD_STS_INTRMDT:
+ case MB_CMD_STS_GOOD:
+ case MB_CMD_STS_INVLD_CMD:
+ case MB_CMD_STS_XFC_ERR:
+ case MB_CMD_STS_CSUM_ERR:
+ case MB_CMD_STS_ERR:
+ case MB_CMD_STS_PARAM_ERR:
+ /* We can only get mailbox status if we're polling from an
+ * unfinished command. Get the rest of the status data and
+ * return back to the caller.
+ * We only end up here when we're polling for a mailbox
+ * command completion.
+ */
+ mbcp->out_count = orig_count;
+ status = ql_get_mb_sts(qdev, mbcp);
+ return status;
+
+ /* We are being asked by firmware to accept
+ * a change to the port. This is only
+ * a change to max frame sizes (Tx/Rx), pause
+ * paramters, or loopback mode.
+ */
+ case AEN_IDC_REQ:
+ status = ql_idc_req_aen(qdev);
+ break;
+
+ /* Process and inbound IDC event.
+ * This will happen when we're trying to
+ * change tx/rx max frame size, change pause
+ * paramters or loopback mode.
+ */
+ case AEN_IDC_CMPLT:
+ case AEN_IDC_EXT:
+ status = ql_idc_cmplt_aen(qdev);
+ break;
+
+ case AEN_LINK_UP:
+ ql_link_up(qdev, mbcp);
+ break;
+
+ case AEN_LINK_DOWN:
+ ql_link_down(qdev, mbcp);
+ break;
+
+ case AEN_FW_INIT_DONE:
+ /* If we're in process on executing the firmware,
+ * then convert the status to normal mailbox status.
+ */
+ if (mbcp->mbox_in[0] == MB_CMD_EX_FW) {
+ mbcp->out_count = orig_count;
+ status = ql_get_mb_sts(qdev, mbcp);
+ mbcp->mbox_out[0] = MB_CMD_STS_GOOD;
+ return status;
+ }
+ ql_init_fw_done(qdev, mbcp);
+ break;
+
+ case AEN_AEN_SFP_IN:
+ ql_sfp_in(qdev, mbcp);
+ break;
+
+ case AEN_AEN_SFP_OUT:
+ ql_sfp_out(qdev, mbcp);
+ break;
+
+ /* This event can arrive at boot time or after an
+ * MPI reset if the firmware failed to initialize.
+ */
+ case AEN_FW_INIT_FAIL:
+ /* If we're in process on executing the firmware,
+ * then convert the status to normal mailbox status.
+ */
+ if (mbcp->mbox_in[0] == MB_CMD_EX_FW) {
+ mbcp->out_count = orig_count;
+ status = ql_get_mb_sts(qdev, mbcp);
+ mbcp->mbox_out[0] = MB_CMD_STS_ERR;
+ return status;
+ }
+ QPRINTK(qdev, DRV, ERR,
+ "Firmware initialization failed.\n");
+ status = -EIO;
+ ql_queue_fw_error(qdev);
+ break;
+
+ case AEN_SYS_ERR:
+ QPRINTK(qdev, DRV, ERR,
+ "System Error.\n");
+ ql_queue_fw_error(qdev);
+ status = -EIO;
+ break;
+
+ case AEN_AEN_LOST:
+ ql_aen_lost(qdev, mbcp);
+ break;
+
+ default:
+ QPRINTK(qdev, DRV, ERR,
+ "Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
+ /* Clear the MPI firmware status. */
+ }
+end:
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+ return status;
}
-void ql_mpi_work(struct work_struct *work)
+/* Execute a single mailbox command.
+ * mbcp is a pointer to an array of u32. Each
+ * element in the array contains the value for it's
+ * respective mailbox register.
+ */
+static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status, count;
+
+ mutex_lock(&qdev->mpi_mutex);
+
+ /* Begin polled mode for MPI */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+
+ /* Load the mailbox registers and wake up MPI RISC. */
+ status = ql_exec_mb_cmd(qdev, mbcp);
+ if (status)
+ goto end;
+
+
+ /* If we're generating a system error, then there's nothing
+ * to wait for.
+ */
+ if (mbcp->mbox_in[0] == MB_CMD_MAKE_SYS_ERR)
+ goto end;
+
+ /* Wait for the command to complete. We loop
+ * here because some AEN might arrive while
+ * we're waiting for the mailbox command to
+ * complete. If more than 5 arrive then we can
+ * assume something is wrong. */
+ count = 5;
+ do {
+ /* Wait for the interrupt to come in. */
+ status = ql_wait_mbx_cmd_cmplt(qdev);
+ if (status)
+ goto end;
+
+ /* Process the event. If it's an AEN, it
+ * will be handled in-line or a worker
+ * will be spawned. If it's our completion
+ * we will catch it below.
+ */
+ status = ql_mpi_handler(qdev, mbcp);
+ if (status)
+ goto end;
+
+ /* It's either the completion for our mailbox
+ * command complete or an AEN. If it's our
+ * completion then get out.
+ */
+ if (((mbcp->mbox_out[0] & 0x0000f000) ==
+ MB_CMD_STS_GOOD) ||
+ ((mbcp->mbox_out[0] & 0x0000f000) ==
+ MB_CMD_STS_INTRMDT))
+ break;
+ } while (--count);
+
+ if (!count) {
+ QPRINTK(qdev, DRV, ERR,
+ "Timed out waiting for mailbox complete.\n");
+ status = -ETIMEDOUT;
+ goto end;
+ }
+
+ /* Now we can clear the interrupt condition
+ * and look at our status.
+ */
+ ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+ if (((mbcp->mbox_out[0] & 0x0000f000) !=
+ MB_CMD_STS_GOOD) &&
+ ((mbcp->mbox_out[0] & 0x0000f000) !=
+ MB_CMD_STS_INTRMDT)) {
+ ql_display_mb_sts(qdev, mbcp);
+ status = -EIO;
+ }
+end:
+ mutex_unlock(&qdev->mpi_mutex);
+ /* End polled mode for MPI */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+ return status;
+}
+
+/* Get functional state for MPI firmware.
+ * Returns zero on success.
+ */
+int ql_mb_get_fw_state(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 = 2;
+
+ mbcp->mbox_in[0] = MB_CMD_GET_FW_STATE;
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed Get Firmware State.\n");
+ status = -EIO;
+ }
+
+ /* If bit zero is set in mbx 1 then the firmware is
+ * running, but not initialized. This should never
+ * happen.
+ */
+ if (mbcp->mbox_out[1] & 1) {
+ QPRINTK(qdev, DRV, ERR,
+ "Firmware waiting for initialization.\n");
+ status = -EIO;
+ }
+
+ return status;
+}
+
+/* Send and ACK mailbox command to the firmware to
+ * let it continue with the change.
+ */
+int ql_mb_idc_ack(struct ql_adapter *qdev)
{
- struct ql_adapter *qdev =
- container_of(work, struct ql_adapter, mpi_work.work);
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 5;
mbcp->out_count = 1;
- while (ql_read32(qdev, STS) & STS_PI) {
- if (ql_get_mb_sts(qdev, mbcp)) {
- QPRINTK(qdev, DRV, ERR,
- "Could not read MPI, resetting ASIC!\n");
- ql_queue_asic_error(qdev);
- }
+ mbcp->mbox_in[0] = MB_CMD_IDC_ACK;
+ mbcp->mbox_in[1] = qdev->idc_mbc.mbox_out[1];
+ mbcp->mbox_in[2] = qdev->idc_mbc.mbox_out[2];
+ mbcp->mbox_in[3] = qdev->idc_mbc.mbox_out[3];
+ mbcp->mbox_in[4] = qdev->idc_mbc.mbox_out[4];
- switch (mbcp->mbox_out[0]) {
- case AEN_LINK_UP:
- ql_link_up(qdev, mbcp);
- break;
- case AEN_LINK_DOWN:
- ql_link_down(qdev, mbcp);
- break;
- case AEN_FW_INIT_DONE:
- ql_init_fw_done(qdev, mbcp);
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed IDC ACK send.\n");
+ status = -EIO;
+ }
+ return status;
+}
+
+/* Get link settings and maximum frame size settings
+ * for the current port.
+ * Most likely will block.
+ */
+static int ql_mb_set_port_cfg(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 = 3;
+ mbcp->out_count = 1;
+
+ mbcp->mbox_in[0] = MB_CMD_SET_PORT_CFG;
+ mbcp->mbox_in[1] = qdev->link_config;
+ mbcp->mbox_in[2] = qdev->max_frame_size;
+
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] == MB_CMD_STS_INTRMDT) {
+ QPRINTK(qdev, DRV, ERR,
+ "Port Config sent, wait for IDC.\n");
+ } else if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed Set Port Configuration.\n");
+ status = -EIO;
+ }
+ return status;
+}
+
+/* Get link settings and maximum frame size settings
+ * for the current port.
+ * Most likely will block.
+ */
+static int ql_mb_get_port_cfg(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_GET_PORT_CFG;
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed Get Port Configuration.\n");
+ status = -EIO;
+ } else {
+ QPRINTK(qdev, DRV, DEBUG,
+ "Passed Get Port Configuration.\n");
+ qdev->link_config = mbcp->mbox_out[1];
+ qdev->max_frame_size = mbcp->mbox_out[2];
+ }
+ return status;
+}
+
+/* IDC - Inter Device Communication...
+ * Some firmware commands require consent of adjacent FCOE
+ * function. This function waits for the OK, or a
+ * counter-request for a little more time.i
+ * The firmware will complete the request if the other
+ * function doesn't respond.
+ */
+static int ql_idc_wait(struct ql_adapter *qdev)
+{
+ int status = -ETIMEDOUT;
+ long wait_time = 1 * HZ;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+ do {
+ /* Wait here for the command to complete
+ * via the IDC process.
+ */
+ wait_time =
+ wait_for_completion_timeout(&qdev->ide_completion,
+ wait_time);
+ if (!wait_time) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Timeout.\n");
break;
- case MB_CMD_STS_GOOD:
+ }
+ /* Now examine the response from the IDC process.
+ * We might have a good completion or a request for
+ * more wait time.
+ */
+ if (mbcp->mbox_out[0] == AEN_IDC_EXT) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Time Extension from function.\n");
+ wait_time += (mbcp->mbox_out[1] >> 8) & 0x0000000f;
+ } else if (mbcp->mbox_out[0] == AEN_IDC_CMPLT) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Success.\n");
+ status = 0;
break;
- case AEN_FW_INIT_FAIL:
- case AEN_SYS_ERR:
- case MB_CMD_STS_ERR:
- ql_queue_fw_error(qdev);
- default:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+ } else {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC: Invalid State 0x%.04x.\n",
+ mbcp->mbox_out[0]);
+ status = -EIO;
break;
}
+ } while (wait_time);
+
+ return status;
+}
+
+/* API called in work thread context to set new TX/RX
+ * maximum frame size values to match MTU.
+ */
+static int ql_set_port_cfg(struct ql_adapter *qdev)
+{
+ int status;
+ status = ql_mb_set_port_cfg(qdev);
+ if (status)
+ return status;
+ status = ql_idc_wait(qdev);
+ return status;
+}
+
+/* The following routines are worker threads that process
+ * events that may sleep waiting for completion.
+ */
+
+/* This thread gets the maximum TX and RX frame size values
+ * from the firmware and, if necessary, changes them to match
+ * the MTU setting.
+ */
+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);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: Failed to get port config data.\n");
+ goto err;
+ }
+
+ if (ndev->mtu <= 2500)
+ goto end;
+ else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
+ qdev->max_frame_size ==
+ CFG_DEFAULT_MAX_FRAME_SIZE)
+ goto end;
+
+ qdev->link_config |= CFG_JUMBO_FRAME_SIZE;
+ qdev->max_frame_size = CFG_DEFAULT_MAX_FRAME_SIZE;
+ status = ql_set_port_cfg(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: Failed to set port config data.\n");
+ goto err;
+ }
+end:
+ clear_bit(QL_PORT_CFG, &qdev->flags);
+ return;
+err:
+ ql_queue_fw_error(qdev);
+ goto end;
+}
+
+/* Process an inter-device request. This is issues by
+ * the firmware in response to another function requesting
+ * a change to the port. We set a flag to indicate a change
+ * has been made and then send a mailbox command ACKing
+ * the change request.
+ */
+void ql_mpi_idc_work(struct work_struct *work)
+{
+ struct ql_adapter *qdev =
+ container_of(work, struct ql_adapter, mpi_idc_work.work);
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+ u32 aen;
+
+ aen = mbcp->mbox_out[1] >> 16;
+
+ switch (aen) {
+ default:
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: Unhandled IDC action.\n");
+ break;
+ case MB_CMD_PORT_RESET:
+ case MB_CMD_SET_PORT_CFG:
+ case MB_CMD_STOP_FW:
+ netif_carrier_off(qdev->ndev);
+ /* Signal the resulting link up AEN
+ * that the frame routing and mac addr
+ * needs to be set.
+ * */
+ set_bit(QL_CAM_RT_SET, &qdev->flags);
+ status = ql_mb_idc_ack(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: No pending IDC!\n");
+ }
+ }
+}
+
+void ql_mpi_work(struct work_struct *work)
+{
+ struct ql_adapter *qdev =
+ container_of(work, struct ql_adapter, mpi_work.work);
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+
+ 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);
}
+
+ mutex_unlock(&qdev->mpi_mutex);
ql_enable_completion_interrupt(qdev, 0);
}
@@ -142,9 +848,8 @@ void ql_mpi_reset_work(struct work_struct *work)
{
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, mpi_reset_work.work);
- QPRINTK(qdev, DRV, ERR,
- "Enter, qdev = %p..\n", qdev);
- ql_write32(qdev, CSR, CSR_CMD_SET_RST);
- msleep(50);
- ql_write32(qdev, CSR, CSR_CMD_CLR_RST);
+ cancel_delayed_work_sync(&qdev->mpi_work);
+ cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+ cancel_delayed_work_sync(&qdev->mpi_idc_work);
+ ql_soft_reset_mpi_risc(qdev);
}
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 72fd9e97c19..0a37f9902a0 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -49,12 +49,12 @@
#include <asm/processor.h>
#define DRV_NAME "r6040"
-#define DRV_VERSION "0.21"
-#define DRV_RELDATE "09Jan2009"
+#define DRV_VERSION "0.22"
+#define DRV_RELDATE "25Mar2009"
/* PHY CHIP Address */
#define PHY1_ADDR 1 /* For MAC1 */
-#define PHY2_ADDR 2 /* For MAC2 */
+#define PHY2_ADDR 3 /* For MAC2 */
#define PHY_MODE 0x3100 /* PHY CHIP Register 0 */
#define PHY_CAP 0x01E1 /* PHY CHIP Register 4 */
@@ -438,7 +438,6 @@ static void r6040_down(struct net_device *dev)
{
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
- struct pci_dev *pdev = lp->pdev;
int limit = 2048;
u16 *adrp;
u16 cmd;
@@ -485,12 +484,12 @@ static int r6040_close(struct net_device *dev)
/* Free Descriptor memory */
if (lp->rx_ring) {
pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
- lp->rx_ring = 0;
+ lp->rx_ring = NULL;
}
if (lp->tx_ring) {
pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
- lp->tx_ring = 0;
+ lp->tx_ring = NULL;
}
return 0;
@@ -677,7 +676,7 @@ static int r6040_poll(struct napi_struct *napi, int budget)
work_done = r6040_rx(dev, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* Enable RX interrupt */
iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER);
}
@@ -714,7 +713,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
/* Mask off RX interrupt */
misr &= ~RX_INTS;
- netif_rx_schedule(&lp->napi);
+ napi_schedule(&lp->napi);
}
/* TX interrupt request */
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2c73ca606b3..06c53522266 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -437,6 +437,22 @@ enum features {
RTL_FEATURE_GMII = (1 << 2),
};
+struct rtl8169_counters {
+ __le64 tx_packets;
+ __le64 rx_packets;
+ __le64 tx_errors;
+ __le32 rx_errors;
+ __le16 rx_missed;
+ __le16 align_errors;
+ __le32 tx_one_collision;
+ __le32 tx_multi_collision;
+ __le64 rx_unicast;
+ __le64 rx_broadcast;
+ __le32 rx_multicast;
+ __le16 tx_aborted;
+ __le16 tx_underun;
+};
+
struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
@@ -480,6 +496,7 @@ struct rtl8169_private {
unsigned features;
struct mii_if_info mii;
+ struct rtl8169_counters counters;
};
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -1100,22 +1117,6 @@ static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
"tx_underrun",
};
-struct rtl8169_counters {
- __le64 tx_packets;
- __le64 rx_packets;
- __le64 tx_errors;
- __le32 rx_errors;
- __le16 rx_missed;
- __le16 align_errors;
- __le32 tx_one_collision;
- __le32 tx_multi_collision;
- __le64 rx_unicast;
- __le64 rx_broadcast;
- __le32 rx_multicast;
- __le16 tx_aborted;
- __le16 tx_underun;
-};
-
static int rtl8169_get_sset_count(struct net_device *dev, int sset)
{
switch (sset) {
@@ -1126,16 +1127,21 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset)
}
}
-static void rtl8169_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
+static void rtl8169_update_counters(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
struct rtl8169_counters *counters;
dma_addr_t paddr;
u32 cmd;
+ int wait = 1000;
- ASSERT_RTNL();
+ /*
+ * Some chips are unable to dump tally counters when the receiver
+ * is disabled.
+ */
+ if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0)
+ return;
counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
if (!counters)
@@ -1146,31 +1152,45 @@ static void rtl8169_get_ethtool_stats(struct net_device *dev,
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump);
- while (RTL_R32(CounterAddrLow) & CounterDump) {
- if (msleep_interruptible(1))
+ while (wait--) {
+ if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) {
+ /* copy updated counters */
+ memcpy(&tp->counters, counters, sizeof(*counters));
break;
+ }
+ udelay(10);
}
RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0);
- data[0] = le64_to_cpu(counters->tx_packets);
- data[1] = le64_to_cpu(counters->rx_packets);
- data[2] = le64_to_cpu(counters->tx_errors);
- data[3] = le32_to_cpu(counters->rx_errors);
- data[4] = le16_to_cpu(counters->rx_missed);
- data[5] = le16_to_cpu(counters->align_errors);
- data[6] = le32_to_cpu(counters->tx_one_collision);
- data[7] = le32_to_cpu(counters->tx_multi_collision);
- data[8] = le64_to_cpu(counters->rx_unicast);
- data[9] = le64_to_cpu(counters->rx_broadcast);
- data[10] = le32_to_cpu(counters->rx_multicast);
- data[11] = le16_to_cpu(counters->tx_aborted);
- data[12] = le16_to_cpu(counters->tx_underun);
-
pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
}
+static void rtl8169_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+ ASSERT_RTNL();
+
+ rtl8169_update_counters(dev);
+
+ data[0] = le64_to_cpu(tp->counters.tx_packets);
+ data[1] = le64_to_cpu(tp->counters.rx_packets);
+ data[2] = le64_to_cpu(tp->counters.tx_errors);
+ data[3] = le32_to_cpu(tp->counters.rx_errors);
+ data[4] = le16_to_cpu(tp->counters.rx_missed);
+ data[5] = le16_to_cpu(tp->counters.align_errors);
+ data[6] = le32_to_cpu(tp->counters.tx_one_collision);
+ data[7] = le32_to_cpu(tp->counters.tx_multi_collision);
+ data[8] = le64_to_cpu(tp->counters.rx_unicast);
+ data[9] = le64_to_cpu(tp->counters.rx_broadcast);
+ data[10] = le32_to_cpu(tp->counters.rx_multicast);
+ data[11] = le16_to_cpu(tp->counters.tx_aborted);
+ data[12] = le16_to_cpu(tp->counters.tx_underun);
+}
+
static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
switch(stringset) {
@@ -3233,13 +3253,6 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
opts1 |= FirstFrag;
} else {
len = skb->len;
-
- if (unlikely(len < ETH_ZLEN)) {
- if (skb_padto(skb, ETH_ZLEN))
- goto err_update_stats;
- len = ETH_ZLEN;
- }
-
opts1 |= FirstFrag | LastFrag;
tp->tx_skb[entry].skb = skb;
}
@@ -3277,7 +3290,6 @@ out:
err_stop:
netif_stop_queue(dev);
ret = NETDEV_TX_BUSY;
-err_update_stats:
dev->stats.tx_dropped++;
goto out;
}
@@ -3581,8 +3593,8 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
tp->intr_mask = ~tp->napi_event;
- if (likely(netif_rx_schedule_prep(&tp->napi)))
- __netif_rx_schedule(&tp->napi);
+ if (likely(napi_schedule_prep(&tp->napi)))
+ __napi_schedule(&tp->napi);
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
@@ -3603,7 +3615,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
rtl8169_tx_interrupt(dev, tp, ioaddr);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
tp->intr_mask = 0xffff;
/*
* 20040426: the barrier is not strictly required but the
@@ -3682,6 +3694,9 @@ static int rtl8169_close(struct net_device *dev)
struct rtl8169_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev;
+ /* update counters before going down */
+ rtl8169_update_counters(dev);
+
rtl8169_down(dev);
free_irq(dev->irq, dev);
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index a6fd27a2cc3..ec59e29807a 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -362,8 +362,7 @@ static int rionet_close(struct net_device *ndev)
netif_carrier_off(ndev);
for (i = 0; i < RIONET_RX_RING_SIZE; i++)
- if (rnet->rx_skb[i])
- kfree_skb(rnet->rx_skb[i]);
+ kfree_skb(rnet->rx_skb[i]);
list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
if (rionet_active[peer->rdev->destid]) {
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index f5c57c059bc..16868b7a5d0 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2852,7 +2852,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
s2io_chk_rx_buffers(nic, ring);
if (pkts_processed < budget_org) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/*Re Enable MSI-Rx Vector*/
addr = (u8 __iomem *)&bar0->xmsi_mask_reg;
addr += 7 - ring->ring_no;
@@ -2889,7 +2889,7 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget)
break;
}
if (pkts_processed < budget_org) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* Re enable the Rx interrupts for the ring */
writeq(0, &bar0->rx_traffic_mask);
readl(&bar0->rx_traffic_mask);
@@ -3862,7 +3862,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries);
/* We fail init if error or we get less vectors than min required */
if (ret) {
- DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
+ DBG_PRINT(ERR_DBG, "s2io: Enabling MSI-X failed\n");
kfree(nic->entries);
nic->mac_control.stats_info->sw_stat.mem_freed
+= (nic->num_entries * sizeof(struct msix_entry));
@@ -4342,7 +4342,7 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
val8 = (ring->ring_no == 0) ? 0x7f : 0xff;
writeb(val8, addr);
val8 = readb(addr);
- netif_rx_schedule(&ring->napi);
+ napi_schedule(&ring->napi);
} else {
rx_intr_handler(ring, 0);
s2io_chk_rx_buffers(sp, ring);
@@ -4789,7 +4789,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
if (config->napi) {
if (reason & GEN_INTR_RXTRAFFIC) {
- netif_rx_schedule(&sp->napi);
+ napi_schedule(&sp->napi);
writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask);
writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
readl(&bar0->rx_traffic_int);
@@ -7220,7 +7220,6 @@ static int s2io_card_up(struct s2io_nic * sp)
/* Initialise napi */
if (config->napi) {
- int i;
if (config->intr_type == MSI_X) {
for (i = 0; i < sp->config.rx_ring_num; i++)
napi_enable(&sp->mac_control.rings[i].napi);
@@ -7542,6 +7541,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
send_up:
+ skb_record_rx_queue(skb, ring_no);
queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2));
aggregate:
sp->mac_control.rings[ring_no].rx_bufs_left -= 1;
@@ -8009,8 +8009,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
if (ret) {
DBG_PRINT(ERR_DBG,
- "%s: MSI-X requested but failed to enable\n",
- dev->name);
+ "s2io: MSI-X requested but failed to enable\n");
sp->config.intr_type = INTA;
}
}
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 31e38fae017..88dd2e09832 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2039,9 +2039,9 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance)
sbdma_tx_process(sc,&(sc->sbm_txdma), 0);
if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
- if (netif_rx_schedule_prep(&sc->napi)) {
+ if (napi_schedule_prep(&sc->napi)) {
__raw_writeq(0, sc->sbm_imr);
- __netif_rx_schedule(&sc->napi);
+ __napi_schedule(&sc->napi);
/* Depend on the exit from poll to reenable intr */
}
else {
@@ -2478,7 +2478,7 @@ static int sbmac_mii_probe(struct net_device *dev)
return -ENXIO;
}
- phy_dev = phy_connect(dev, phy_dev->dev.bus_id, &sbmac_mii_poll, 0,
+ phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &sbmac_mii_poll, 0,
PHY_INTERFACE_MODE_GMII);
if (IS_ERR(phy_dev)) {
printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
@@ -2500,7 +2500,7 @@ static int sbmac_mii_probe(struct net_device *dev)
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
dev->name, phy_dev->drv->name,
- phy_dev->dev.bus_id, phy_dev->irq);
+ dev_name(&phy_dev->dev), phy_dev->irq);
sc->phy_dev = phy_dev;
@@ -2667,7 +2667,7 @@ static int sbmac_poll(struct napi_struct *napi, int budget)
sbdma_tx_process(sc, &(sc->sbm_txdma), 1);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
#ifdef CONFIG_SBMAC_COALESCE
__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
@@ -2697,7 +2697,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
sbm_base = ioremap_nocache(res->start, res->end - res->start + 1);
if (!sbm_base) {
printk(KERN_ERR "%s: unable to map device registers\n",
- pldev->dev.bus_id);
+ dev_name(&pldev->dev));
err = -ENOMEM;
goto out_out;
}
@@ -2708,7 +2708,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
* If we find a zero, skip this MAC.
*/
sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR);
- pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", pldev->dev.bus_id,
+ pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", dev_name(&pldev->dev),
sbmac_orig_hwaddr ? "" : "not ", (long long)res->start);
if (sbmac_orig_hwaddr == 0) {
err = 0;
@@ -2721,7 +2721,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
dev = alloc_etherdev(sizeof(struct sbmac_softc));
if (!dev) {
printk(KERN_ERR "%s: unable to allocate etherdev\n",
- pldev->dev.bus_id);
+ dev_name(&pldev->dev));
err = -ENOMEM;
goto out_unmap;
}
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 8b75bef4a84..c13cbf099b8 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -13,6 +13,9 @@
* Both are almost identical and seem to be based on pci-skeleton.c
*
* Rewritten for 2.6 by Cesar Eduardo Barros
+ *
+ * A datasheet for this chip can be found at
+ * http://www.silan.com.cn/english/products/pdf/SC92031AY.pdf
*/
/* Note about set_mac_address: I don't know how to change the hardware
@@ -31,13 +34,7 @@
#include <asm/irq.h>
-#define PCI_VENDOR_ID_SILAN 0x1904
-#define PCI_DEVICE_ID_SILAN_SC92031 0x2031
-#define PCI_DEVICE_ID_SILAN_8139D 0x8139
-
#define SC92031_NAME "sc92031"
-#define SC92031_DESCRIPTION "Silan SC92031 PCI Fast Ethernet Adapter driver"
-#define SC92031_VERSION "2.0c"
/* BAR 0 is MMIO, BAR 1 is PIO */
#ifndef SC92031_USE_BAR
@@ -1264,7 +1261,6 @@ static void sc92031_ethtool_get_drvinfo(struct net_device *dev,
struct pci_dev *pdev = priv->pdev;
strcpy(drvinfo->driver, SC92031_NAME);
- strcpy(drvinfo->version, SC92031_VERSION);
strcpy(drvinfo->bus_info, pci_name(pdev));
}
@@ -1423,6 +1419,7 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
struct net_device *dev;
struct sc92031_priv *priv;
u32 mac0, mac1;
+ unsigned long base_addr;
err = pci_enable_device(pdev);
if (unlikely(err < 0))
@@ -1497,6 +1494,14 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
if (err < 0)
goto out_register_netdev;
+#if SC92031_USE_BAR == 0
+ base_addr = dev->mem_start;
+#elif SC92031_USE_BAR == 1
+ base_addr = dev->base_addr;
+#endif
+ printk(KERN_INFO "%s: SC92031 at 0x%lx, %pM, IRQ %d\n", dev->name,
+ base_addr, dev->dev_addr, dev->irq);
+
return 0;
out_register_netdev:
@@ -1586,8 +1591,8 @@ out:
}
static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = {
- { PCI_DEVICE(PCI_VENDOR_ID_SILAN, PCI_DEVICE_ID_SILAN_SC92031) },
- { PCI_DEVICE(PCI_VENDOR_ID_SILAN, PCI_DEVICE_ID_SILAN_8139D) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table);
@@ -1603,7 +1608,6 @@ static struct pci_driver sc92031_pci_driver = {
static int __init sc92031_init(void)
{
- printk(KERN_INFO SC92031_DESCRIPTION " " SC92031_VERSION "\n");
return pci_register_driver(&sc92031_pci_driver);
}
@@ -1617,5 +1621,4 @@ module_exit(sc92031_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Cesar Eduardo Barros <cesarb@cesarb.net>");
-MODULE_DESCRIPTION(SC92031_DESCRIPTION);
-MODULE_VERSION(SC92031_VERSION);
+MODULE_DESCRIPTION("Silan SC92031 PCI Fast Ethernet Adapter driver");
diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig
index c535408ad6b..12a82966b57 100644
--- a/drivers/net/sfc/Kconfig
+++ b/drivers/net/sfc/Kconfig
@@ -2,7 +2,6 @@ config SFC
tristate "Solarflare Solarstorm SFC4000 support"
depends on PCI && INET
select MII
- select INET_LRO
select CRC32
select I2C
select I2C_ALGOBIT
diff --git a/drivers/net/sfc/bitfield.h b/drivers/net/sfc/bitfield.h
index d95c2182801..d54d84c267b 100644
--- a/drivers/net/sfc/bitfield.h
+++ b/drivers/net/sfc/bitfield.h
@@ -543,7 +543,7 @@ typedef union efx_oword {
/* Static initialiser */
#define EFX_OWORD32(a, b, c, d) \
- { .u32 = { __constant_cpu_to_le32(a), __constant_cpu_to_le32(b), \
- __constant_cpu_to_le32(c), __constant_cpu_to_le32(d) } }
+ { .u32 = { cpu_to_le32(a), cpu_to_le32(b), \
+ cpu_to_le32(c), cpu_to_le32(d) } }
#endif /* EFX_BITFIELD_H */
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 64903496aa9..5182ac5a103 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -26,7 +26,7 @@ static void blink_led_timer(unsigned long context)
{
struct efx_nic *efx = (struct efx_nic *)context;
struct efx_blinker *bl = &efx->board_info.blinker;
- efx->board_info.set_fault_led(efx, bl->state);
+ efx->board_info.set_id_led(efx, bl->state);
bl->state = !bl->state;
if (bl->resubmit)
mod_timer(&bl->timer, jiffies + BLINK_INTERVAL);
@@ -48,7 +48,7 @@ static void board_blink(struct efx_nic *efx, bool blink)
blinker->resubmit = false;
if (blinker->timer.function)
del_timer_sync(&blinker->timer);
- efx->board_info.set_fault_led(efx, false);
+ efx->board_info.init_leds(efx);
}
}
@@ -185,7 +185,7 @@ static struct i2c_board_info sfe4002_hwmon_info = {
#define SFE4002_RX_LED (0) /* Green */
#define SFE4002_TX_LED (1) /* Amber */
-static int sfe4002_init_leds(struct efx_nic *efx)
+static void sfe4002_init_leds(struct efx_nic *efx)
{
/* Set the TX and RX LEDs to reflect status and activity, and the
* fault LED off */
@@ -194,11 +194,9 @@ static int sfe4002_init_leds(struct efx_nic *efx)
xfp_set_led(efx, SFE4002_RX_LED,
QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
- efx->board_info.blinker.led_num = SFE4002_FAULT_LED;
- return 0;
}
-static void sfe4002_fault_led(struct efx_nic *efx, bool state)
+static void sfe4002_set_id_led(struct efx_nic *efx, bool state)
{
xfp_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON :
QUAKE_LED_OFF);
@@ -222,7 +220,67 @@ static int sfe4002_init(struct efx_nic *efx)
return rc;
efx->board_info.monitor = sfe4002_check_hw;
efx->board_info.init_leds = sfe4002_init_leds;
- efx->board_info.set_fault_led = sfe4002_fault_led;
+ efx->board_info.set_id_led = sfe4002_set_id_led;
+ efx->board_info.blink = board_blink;
+ efx->board_info.fini = efx_fini_lm87;
+ return 0;
+}
+
+/*****************************************************************************
+ * Support for the SFN4112F
+ *
+ */
+static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
+
+static const u8 sfn4112f_lm87_regs[] = {
+ LM87_IN_LIMITS(0, 0x83, 0x91), /* 2.5V: 1.8V +/- 5% */
+ LM87_IN_LIMITS(1, 0x51, 0x5a), /* Vccp1: 1.2V +/- 5% */
+ LM87_IN_LIMITS(2, 0xb6, 0xca), /* 3.3V: 3.3V +/- 5% */
+ LM87_IN_LIMITS(4, 0xb0, 0xe0), /* 12V: 11-14V */
+ LM87_IN_LIMITS(5, 0x44, 0x4b), /* Vccp2: 1.0V +/- 5% */
+ LM87_AIN_LIMITS(1, 0x91, 0xa1), /* AIN2: 1.5V +/- 5% */
+ LM87_TEMP_INT_LIMITS(10, 60), /* board */
+ LM87_TEMP_EXT1_LIMITS(10, 70), /* Falcon */
+ 0
+};
+
+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
+#define SFN4112F_LINK_LED 1
+
+static void sfn4112f_init_leds(struct efx_nic *efx)
+{
+ xfp_set_led(efx, SFN4112F_ACT_LED,
+ QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT);
+ xfp_set_led(efx, SFN4112F_LINK_LED,
+ QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT);
+}
+
+static void sfn4112f_set_id_led(struct efx_nic *efx, bool state)
+{
+ xfp_set_led(efx, SFN4112F_LINK_LED,
+ state ? QUAKE_LED_ON : QUAKE_LED_OFF);
+}
+
+static int sfn4112f_check_hw(struct efx_nic *efx)
+{
+ /* Mask out unused sensors */
+ return efx_check_lm87(efx, ~0x48);
+}
+
+static int sfn4112f_init(struct efx_nic *efx)
+{
+ int rc = efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
+ if (rc)
+ return rc;
+ efx->board_info.monitor = sfn4112f_check_hw;
+ efx->board_info.init_leds = sfn4112f_init_leds;
+ efx->board_info.set_id_led = sfn4112f_set_id_led;
efx->board_info.blink = board_blink;
efx->board_info.fini = efx_fini_lm87;
return 0;
@@ -243,6 +301,8 @@ static struct efx_board_data board_data[] = {
{ EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init },
{ EFX_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter",
sfn4111t_init },
+ { EFX_BOARD_SFN4112F, "SFN4112F", "SFP+ adapter",
+ sfn4112f_init },
};
void efx_set_board_info(struct efx_nic *efx, u16 revision_info)
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
index d93c6c6a754..44942de0e08 100644
--- a/drivers/net/sfc/boards.h
+++ b/drivers/net/sfc/boards.h
@@ -15,6 +15,7 @@ enum efx_board_type {
EFX_BOARD_SFE4001 = 1,
EFX_BOARD_SFE4002 = 2,
EFX_BOARD_SFN4111T = 0x51,
+ EFX_BOARD_SFN4112F = 0x52,
};
extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info);
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7673fd92eaf..6eff9ca6c6c 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -133,6 +133,16 @@ static int phy_flash_cfg;
module_param(phy_flash_cfg, int, 0644);
MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially");
+static unsigned irq_adapt_low_thresh = 10000;
+module_param(irq_adapt_low_thresh, uint, 0644);
+MODULE_PARM_DESC(irq_adapt_low_thresh,
+ "Threshold score for reducing IRQ moderation");
+
+static unsigned irq_adapt_high_thresh = 20000;
+module_param(irq_adapt_high_thresh, uint, 0644);
+MODULE_PARM_DESC(irq_adapt_high_thresh,
+ "Threshold score for increasing IRQ moderation");
+
/**************************************************************************
*
* Utility functions and prototypes
@@ -182,7 +192,6 @@ static int efx_process_channel(struct efx_channel *channel, int rx_quota)
channel->rx_pkt = NULL;
}
- efx_flush_lro(channel);
efx_rx_strategy(channel);
efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
@@ -224,12 +233,41 @@ static int efx_poll(struct napi_struct *napi, int budget)
rx_packets = efx_process_channel(channel, budget);
if (rx_packets < budget) {
+ struct efx_nic *efx = channel->efx;
+
+ if (channel->used_flags & EFX_USED_BY_RX &&
+ efx->irq_rx_adaptive &&
+ unlikely(++channel->irq_count == 1000)) {
+ unsigned old_irq_moderation = channel->irq_moderation;
+
+ if (unlikely(channel->irq_mod_score <
+ irq_adapt_low_thresh)) {
+ channel->irq_moderation =
+ max_t(int,
+ channel->irq_moderation -
+ FALCON_IRQ_MOD_RESOLUTION,
+ FALCON_IRQ_MOD_RESOLUTION);
+ } else if (unlikely(channel->irq_mod_score >
+ irq_adapt_high_thresh)) {
+ channel->irq_moderation =
+ min(channel->irq_moderation +
+ FALCON_IRQ_MOD_RESOLUTION,
+ efx->irq_rx_moderation);
+ }
+
+ if (channel->irq_moderation != old_irq_moderation)
+ falcon_set_int_moderation(channel);
+
+ channel->irq_count = 0;
+ channel->irq_mod_score = 0;
+ }
+
/* There is no race here; although napi_disable() will
- * only wait for netif_rx_complete(), this isn't a problem
+ * only wait for napi_complete(), this isn't a problem
* since efx_channel_processed() will have no effect if
* interrupts have already been disabled.
*/
- netif_rx_complete(napi);
+ napi_complete(napi);
efx_channel_processed(channel);
}
@@ -558,6 +596,8 @@ static void efx_link_status_changed(struct efx_nic *efx)
}
+static void efx_fini_port(struct efx_nic *efx);
+
/* This call reinitialises the MAC to pick up new PHY settings. The
* caller must hold the mac_lock */
void __efx_reconfigure_port(struct efx_nic *efx)
@@ -593,8 +633,8 @@ void __efx_reconfigure_port(struct efx_nic *efx)
fail:
EFX_ERR(efx, "failed to reconfigure MAC\n");
- efx->phy_op->fini(efx);
- efx->port_initialized = false;
+ efx->port_enabled = false;
+ efx_fini_port(efx);
}
/* Reinitialise the MAC to pick up new PHY settings, even if the port is
@@ -676,9 +716,8 @@ static int efx_init_port(struct efx_nic *efx)
rc = efx->phy_op->init(efx);
if (rc)
return rc;
- efx->phy_op->reconfigure(efx);
-
mutex_lock(&efx->mac_lock);
+ efx->phy_op->reconfigure(efx);
rc = falcon_switch_mac(efx);
mutex_unlock(&efx->mac_lock);
if (rc)
@@ -686,7 +725,7 @@ static int efx_init_port(struct efx_nic *efx)
efx->mac_op->reconfigure(efx);
efx->port_initialized = true;
- efx->stats_enabled = true;
+ efx_stats_enable(efx);
return 0;
fail:
@@ -735,6 +774,7 @@ static void efx_fini_port(struct efx_nic *efx)
if (!efx->port_initialized)
return;
+ efx_stats_disable(efx);
efx->phy_op->fini(efx);
efx->port_initialized = false;
@@ -990,7 +1030,7 @@ static int efx_probe_nic(struct efx_nic *efx)
efx_set_channels(efx);
/* Initialise the interrupt moderation settings */
- efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec);
+ efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true);
return 0;
}
@@ -1187,7 +1227,8 @@ void efx_flush_queues(struct efx_nic *efx)
**************************************************************************/
/* Set interrupt moderation parameters */
-void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs)
+void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
+ bool rx_adaptive)
{
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
@@ -1197,6 +1238,8 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs)
efx_for_each_tx_queue(tx_queue, efx)
tx_queue->channel->irq_moderation = tx_usecs;
+ efx->irq_rx_adaptive = rx_adaptive;
+ efx->irq_rx_moderation = rx_usecs;
efx_for_each_rx_queue(rx_queue, efx)
rx_queue->channel->irq_moderation = rx_usecs;
}
@@ -1269,18 +1312,11 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
static int efx_init_napi(struct efx_nic *efx)
{
struct efx_channel *channel;
- int rc;
efx_for_each_channel(channel, efx) {
channel->napi_dev = efx->net_dev;
- rc = efx_lro_init(&channel->lro_mgr, efx);
- if (rc)
- goto err;
}
return 0;
- err:
- efx_fini_napi(efx);
- return rc;
}
static void efx_fini_napi(struct efx_nic *efx)
@@ -1288,7 +1324,6 @@ static void efx_fini_napi(struct efx_nic *efx)
struct efx_channel *channel;
efx_for_each_channel(channel, efx) {
- efx_lro_fini(&channel->lro_mgr);
channel->napi_dev = NULL;
}
}
@@ -1361,6 +1396,20 @@ static int efx_net_stop(struct net_device *net_dev)
return 0;
}
+void efx_stats_disable(struct efx_nic *efx)
+{
+ spin_lock(&efx->stats_lock);
+ ++efx->stats_disable_count;
+ spin_unlock(&efx->stats_lock);
+}
+
+void efx_stats_enable(struct efx_nic *efx)
+{
+ spin_lock(&efx->stats_lock);
+ --efx->stats_disable_count;
+ spin_unlock(&efx->stats_lock);
+}
+
/* Context: process, dev_base_lock or RTNL held, non-blocking. */
static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
{
@@ -1369,12 +1418,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
struct net_device_stats *stats = &net_dev->stats;
/* Update stats if possible, but do not wait if another thread
- * is updating them (or resetting the NIC); slightly stale
- * stats are acceptable.
+ * is updating them or if MAC stats fetches are temporarily
+ * disabled; slightly stale stats are acceptable.
*/
if (!spin_trylock(&efx->stats_lock))
return stats;
- if (efx->stats_enabled) {
+ if (!efx->stats_disable_count) {
efx->mac_op->update_stats(efx);
falcon_update_nic_stats(efx);
}
@@ -1622,16 +1671,12 @@ static void efx_unregister_netdev(struct efx_nic *efx)
/* Tears down the entire software state and most of the hardware state
* before reset. */
-void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd)
{
EFX_ASSERT_RESET_SERIALISED(efx);
- /* The net_dev->get_stats handler is quite slow, and will fail
- * if a fetch is pending over reset. Serialise against it. */
- spin_lock(&efx->stats_lock);
- efx->stats_enabled = false;
- spin_unlock(&efx->stats_lock);
-
+ efx_stats_disable(efx);
efx_stop_all(efx);
mutex_lock(&efx->mac_lock);
mutex_lock(&efx->spi_lock);
@@ -1639,6 +1684,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
efx->phy_op->get_settings(efx, ecmd);
efx_fini_channels(efx);
+ if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
+ efx->phy_op->fini(efx);
}
/* This function will always ensure that the locks acquired in
@@ -1646,7 +1693,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
* that we were unable to reinitialise the hardware, and the
* driver should be disabled. If ok is false, then the rx and tx
* engines are not restarted, pending a RESET_DISABLE. */
-int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
+int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd, bool ok)
{
int rc;
@@ -1658,6 +1706,16 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
ok = false;
}
+ if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) {
+ if (ok) {
+ rc = efx->phy_op->init(efx);
+ if (rc)
+ ok = false;
+ }
+ if (!ok)
+ efx->port_initialized = false;
+ }
+
if (ok) {
efx_init_channels(efx);
@@ -1670,7 +1728,7 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
if (ok) {
efx_start_all(efx);
- efx->stats_enabled = true;
+ efx_stats_enable(efx);
}
return rc;
}
@@ -1702,7 +1760,7 @@ static int efx_reset(struct efx_nic *efx)
EFX_INFO(efx, "resetting (%d)\n", method);
- efx_reset_down(efx, &ecmd);
+ efx_reset_down(efx, method, &ecmd);
rc = falcon_reset_hw(efx, method);
if (rc) {
@@ -1721,10 +1779,10 @@ static int efx_reset(struct efx_nic *efx)
/* Leave device stopped if necessary */
if (method == RESET_TYPE_DISABLE) {
- efx_reset_up(efx, &ecmd, false);
+ efx_reset_up(efx, method, &ecmd, false);
rc = -EIO;
} else {
- rc = efx_reset_up(efx, &ecmd, true);
+ rc = efx_reset_up(efx, method, &ecmd, true);
}
out_disable:
@@ -1835,8 +1893,8 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
static struct efx_board efx_dummy_board_info = {
.init = efx_port_dummy_op_int,
- .init_leds = efx_port_dummy_op_int,
- .set_fault_led = efx_port_dummy_op_blink,
+ .init_leds = efx_port_dummy_op_void,
+ .set_id_led = efx_port_dummy_op_blink,
.monitor = efx_port_dummy_op_int,
.blink = efx_port_dummy_op_blink,
.fini = efx_port_dummy_op_void,
@@ -1876,6 +1934,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
efx->rx_checksum_enabled = true;
spin_lock_init(&efx->netif_stop_lock);
spin_lock_init(&efx->stats_lock);
+ efx->stats_disable_count = 1;
mutex_init(&efx->mac_lock);
efx->mac_op = &efx_dummy_mac_operations;
efx->phy_op = &efx_dummy_phy_operations;
@@ -2097,7 +2156,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_TSO);
if (lro)
- net_dev->features |= NETIF_F_LRO;
+ net_dev->features |= 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/efx.h b/drivers/net/sfc/efx.h
index 0dd7a532c78..da157aa74b8 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -36,20 +36,23 @@ extern void efx_process_channel_now(struct efx_channel *channel);
extern void efx_flush_queues(struct efx_nic *efx);
/* Ports */
+extern void efx_stats_disable(struct efx_nic *efx);
+extern void efx_stats_enable(struct efx_nic *efx);
extern void efx_reconfigure_port(struct efx_nic *efx);
extern void __efx_reconfigure_port(struct efx_nic *efx);
/* Reset handling */
-extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd);
-extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
- bool ok);
+extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd);
+extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd, bool ok);
/* Global */
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
extern void efx_suspend(struct efx_nic *efx);
extern void efx_resume(struct efx_nic *efx);
extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs,
- int rx_usecs);
+ int rx_usecs, bool rx_adaptive);
extern int efx_request_power(struct efx_nic *efx, int mw, const char *name);
extern void efx_hex_dump(const u8 *, unsigned int, const char *);
@@ -77,7 +80,7 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
channel->channel, raw_smp_processor_id());
channel->work_pending = true;
- netif_rx_schedule(&channel->napi_str);
+ napi_schedule(&channel->napi_str);
}
#endif /* EFX_EFX_H */
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 53d259e9018..64309f4e8b1 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -219,9 +219,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);
int rc;
- if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg)
- return -EINVAL;
-
/* Falcon GMAC does not support 1000Mbps HD */
if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
@@ -532,7 +529,14 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
- return mii_nway_restart(&efx->mii);
+ 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;
}
static u32 efx_ethtool_get_link(struct net_device *net_dev)
@@ -600,7 +604,6 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev,
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
struct efx_channel *channel;
memset(coalesce, 0, sizeof(*coalesce));
@@ -618,14 +621,8 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev,
}
}
- /* Find lowest IRQ moderation across all used RX queues */
- coalesce->rx_coalesce_usecs_irq = ~((u32) 0);
- efx_for_each_rx_queue(rx_queue, efx) {
- channel = rx_queue->channel;
- if (channel->irq_moderation < coalesce->rx_coalesce_usecs_irq)
- coalesce->rx_coalesce_usecs_irq =
- channel->irq_moderation;
- }
+ coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive;
+ coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation;
return 0;
}
@@ -639,10 +636,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
- unsigned tx_usecs, rx_usecs;
+ unsigned tx_usecs, rx_usecs, adaptive;
- if (coalesce->use_adaptive_rx_coalesce ||
- coalesce->use_adaptive_tx_coalesce)
+ if (coalesce->use_adaptive_tx_coalesce)
return -EOPNOTSUPP;
if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) {
@@ -653,6 +649,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
rx_usecs = coalesce->rx_coalesce_usecs_irq;
tx_usecs = coalesce->tx_coalesce_usecs_irq;
+ adaptive = coalesce->use_adaptive_rx_coalesce;
/* If the channel is shared only allow RX parameters to be set */
efx_for_each_tx_queue(tx_queue, efx) {
@@ -664,7 +661,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
}
}
- efx_init_irq_moderation(efx, tx_usecs, rx_usecs);
+ efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive);
/* Reset channel to pick up new moderation value. Note that
* this may change the value of the irq_moderation field
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 5b9f2d9cc4e..23a1b148d5b 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -39,11 +39,16 @@
* @next_buffer_table: First available buffer table id
* @pci_dev2: The secondary PCI device if present
* @i2c_data: Operations and state for I2C bit-bashing algorithm
+ * @int_error_count: Number of internal errors seen recently
+ * @int_error_expire: Time at which error count will be expired
*/
struct falcon_nic_data {
unsigned next_buffer_table;
struct pci_dev *pci_dev2;
struct i2c_algo_bit_data i2c_data;
+
+ unsigned int_error_count;
+ unsigned long int_error_expire;
};
/**************************************************************************
@@ -119,8 +124,12 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
#define FALCON_EVQ_SIZE 4096
#define FALCON_EVQ_MASK (FALCON_EVQ_SIZE - 1)
-/* Max number of internal errors. After this resets will not be performed */
-#define FALCON_MAX_INT_ERRORS 4
+/* If FALCON_MAX_INT_ERRORS internal errors occur within
+ * FALCON_INT_ERROR_EXPIRE seconds, we consider the NIC broken and
+ * disable it.
+ */
+#define FALCON_INT_ERROR_EXPIRE 3600
+#define FALCON_MAX_INT_ERRORS 5
/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times
*/
@@ -146,13 +155,6 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
/* Dummy SRAM size code */
#define SRM_NB_BSZ_ONCHIP_ONLY (-1)
-/* Be nice if these (or equiv.) were in linux/pci_regs.h, but they're not. */
-#define PCI_EXP_DEVCAP_PWR_VAL_LBN 18
-#define PCI_EXP_DEVCAP_PWR_SCL_LBN 26
-#define PCI_EXP_DEVCTL_PAYLOAD_LBN 5
-#define PCI_EXP_LNKSTA_LNK_WID 0x3f0
-#define PCI_EXP_LNKSTA_LNK_WID_LBN 4
-
#define FALCON_IS_DUAL_FUNC(efx) \
(falcon_rev(efx) < FALCON_REV_B0)
@@ -727,6 +729,9 @@ static void falcon_handle_tx_event(struct efx_channel *channel,
tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, TX_EV_DESC_PTR);
tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL);
tx_queue = &efx->tx_queue[tx_ev_q_label];
+ channel->irq_mod_score +=
+ (tx_ev_desc_ptr - tx_queue->read_count) &
+ efx->type->txd_ring_mask;
efx_xmit_done(tx_queue, tx_ev_desc_ptr);
} else if (EFX_QWORD_FIELD(*event, TX_EV_WQ_FF_FULL)) {
/* Rewrite the FIFO write pointer */
@@ -824,10 +829,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
rx_ev_pause_frm ? " [PAUSE]" : "");
}
#endif
-
- if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) &&
- efx->phy_type == PHY_TYPE_SFX7101))
- tenxpress_crc_err(efx);
}
/* Handle receive events that are not in-order. */
@@ -900,6 +901,8 @@ static void falcon_handle_rx_event(struct efx_channel *channel,
discard = true;
}
+ channel->irq_mod_score += 2;
+
/* Handle received packet */
efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt,
checksummed, discard);
@@ -1077,14 +1080,15 @@ void falcon_set_int_moderation(struct efx_channel *channel)
* program is based at 0. So actual interrupt moderation
* achieved is ((x + 1) * res).
*/
- unsigned int res = 5;
- channel->irq_moderation -= (channel->irq_moderation % res);
- if (channel->irq_moderation < res)
- channel->irq_moderation = res;
+ channel->irq_moderation -= (channel->irq_moderation %
+ FALCON_IRQ_MOD_RESOLUTION);
+ if (channel->irq_moderation < FALCON_IRQ_MOD_RESOLUTION)
+ channel->irq_moderation = FALCON_IRQ_MOD_RESOLUTION;
EFX_POPULATE_DWORD_2(timer_cmd,
TIMER_MODE, TIMER_MODE_INT_HLDOFF,
TIMER_VAL,
- (channel->irq_moderation / res) - 1);
+ channel->irq_moderation /
+ FALCON_IRQ_MOD_RESOLUTION - 1);
} else {
EFX_POPULATE_DWORD_2(timer_cmd,
TIMER_MODE, TIMER_MODE_DIS,
@@ -1191,31 +1195,29 @@ static void falcon_poll_flush_events(struct efx_nic *efx)
struct efx_channel *channel = &efx->channel[0];
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
- unsigned int read_ptr, i;
+ unsigned int read_ptr = channel->eventq_read_ptr;
+ unsigned int end_ptr = (read_ptr - 1) & FALCON_EVQ_MASK;
- read_ptr = channel->eventq_read_ptr;
- for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
+ do {
efx_qword_t *event = falcon_event(channel, read_ptr);
int ev_code, ev_sub_code, ev_queue;
bool ev_failed;
+
if (!falcon_event_present(event))
break;
ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
- if (ev_code != DRIVER_EV_DECODE)
- continue;
-
ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
- switch (ev_sub_code) {
- case TX_DESCQ_FLS_DONE_EV_DECODE:
+ if (ev_code == DRIVER_EV_DECODE &&
+ ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) {
ev_queue = EFX_QWORD_FIELD(*event,
DRIVER_EV_TX_DESCQ_ID);
if (ev_queue < EFX_TX_QUEUE_COUNT) {
tx_queue = efx->tx_queue + ev_queue;
tx_queue->flushed = true;
}
- break;
- case RX_DESCQ_FLS_DONE_EV_DECODE:
+ } else if (ev_code == DRIVER_EV_DECODE &&
+ ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) {
ev_queue = EFX_QWORD_FIELD(*event,
DRIVER_EV_RX_DESCQ_ID);
ev_failed = EFX_QWORD_FIELD(*event,
@@ -1229,11 +1231,10 @@ static void falcon_poll_flush_events(struct efx_nic *efx)
else
rx_queue->flushed = true;
}
- break;
}
read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
- }
+ } while (read_ptr != end_ptr);
}
/* Handle tx and rx flushes at the same time, since they run in
@@ -1381,7 +1382,6 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx)
efx_oword_t *int_ker = efx->irq_status.addr;
efx_oword_t fatal_intr;
int error, mem_perr;
- static int n_int_errors;
falcon_read(efx, &fatal_intr, FATAL_INTR_REG_KER);
error = EFX_OWORD_FIELD(fatal_intr, INT_KER_ERROR);
@@ -1408,7 +1408,14 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx)
pci_clear_master(nic_data->pci_dev2);
falcon_disable_interrupts(efx);
- if (++n_int_errors < FALCON_MAX_INT_ERRORS) {
+ /* Count errors and reset or disable the NIC accordingly */
+ if (nic_data->int_error_count == 0 ||
+ time_after(jiffies, nic_data->int_error_expire)) {
+ nic_data->int_error_count = 0;
+ nic_data->int_error_expire =
+ jiffies + FALCON_INT_ERROR_EXPIRE * HZ;
+ }
+ if (++nic_data->int_error_count < FALCON_MAX_INT_ERRORS) {
EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n");
efx_schedule_reset(efx, RESET_TYPE_INT_ERROR);
} else {
@@ -1427,6 +1434,7 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id)
{
struct efx_nic *efx = dev_id;
efx_oword_t *int_ker = efx->irq_status.addr;
+ irqreturn_t result = IRQ_NONE;
struct efx_channel *channel;
efx_dword_t reg;
u32 queues;
@@ -1441,23 +1449,24 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id)
if (unlikely(syserr))
return falcon_fatal_interrupt(efx);
- if (queues == 0)
- return IRQ_NONE;
-
- efx->last_irq_cpu = raw_smp_processor_id();
- EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
- irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
-
/* Schedule processing of any interrupting queues */
- channel = &efx->channel[0];
- while (queues) {
- if (queues & 0x01)
+ efx_for_each_channel(channel, efx) {
+ if ((queues & 1) ||
+ falcon_event_present(
+ falcon_event(channel, channel->eventq_read_ptr))) {
efx_schedule_channel(channel);
- channel++;
+ result = IRQ_HANDLED;
+ }
queues >>= 1;
}
- return IRQ_HANDLED;
+ if (result == IRQ_HANDLED) {
+ efx->last_irq_cpu = raw_smp_processor_id();
+ EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
+ irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
+ }
+
+ return result;
}
@@ -1887,7 +1896,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
/* MAC stats will fail whilst the TX fifo is draining. Serialise
* the drain sequence with the statistics fetch */
- spin_lock(&efx->stats_lock);
+ efx_stats_disable(efx);
falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1);
@@ -1917,7 +1926,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
udelay(10);
}
- spin_unlock(&efx->stats_lock);
+ efx_stats_enable(efx);
/* If we've reset the EM block and the link is up, then
* we'll have to kick the XAUI link so the PHY can recover */
@@ -2253,6 +2262,7 @@ static int falcon_probe_phy(struct efx_nic *efx)
efx->phy_op = &falcon_sft9001_phy_ops;
break;
case PHY_TYPE_QT2022C2:
+ case PHY_TYPE_QT2025C:
efx->phy_op = &falcon_xfp_phy_ops;
break;
default:
@@ -2277,6 +2287,10 @@ int falcon_switch_mac(struct efx_nic *efx)
struct efx_mac_operations *old_mac_op = efx->mac_op;
efx_oword_t nic_stat;
unsigned strap_val;
+ int rc = 0;
+
+ /* Don't try to fetch MAC stats while we're switching MACs */
+ efx_stats_disable(efx);
/* Internal loopbacks override the phy speed setting */
if (efx->loopback_mode == LOOPBACK_GMAC) {
@@ -2287,16 +2301,12 @@ int falcon_switch_mac(struct efx_nic *efx)
efx->link_fd = true;
}
+ WARN_ON(!mutex_is_locked(&efx->mac_lock));
efx->mac_op = (EFX_IS10G(efx) ?
&falcon_xmac_operations : &falcon_gmac_operations);
- if (old_mac_op == efx->mac_op)
- return 0;
-
- WARN_ON(!mutex_is_locked(&efx->mac_lock));
-
- /* Not all macs support a mac-level link state */
- efx->mac_up = true;
+ /* Always push the NIC_STAT_REG setting even if the mac hasn't
+ * changed, because this function is run post online reset */
falcon_read(efx, &nic_stat, NIC_STAT_REG);
strap_val = EFX_IS10G(efx) ? 5 : 3;
if (falcon_rev(efx) >= FALCON_REV_B0) {
@@ -2309,9 +2319,17 @@ int falcon_switch_mac(struct efx_nic *efx)
BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val);
}
+ if (old_mac_op == efx->mac_op)
+ goto out;
EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
- return falcon_reset_macs(efx);
+ /* Not all macs support a mac-level link state */
+ efx->mac_up = true;
+
+ rc = falcon_reset_macs(efx);
+out:
+ efx_stats_enable(efx);
+ return rc;
}
/* This call is responsible for hooking in the MAC and PHY operations */
@@ -3109,8 +3127,10 @@ void falcon_remove_nic(struct efx_nic *efx)
struct falcon_nic_data *nic_data = efx->nic_data;
int rc;
+ /* Remove I2C adapter and clear it in preparation for a retry */
rc = i2c_del_adapter(&efx->i2c_adap);
BUG_ON(rc);
+ memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap));
falcon_remove_spi_devices(efx);
falcon_free_buffer(efx, &efx->irq_status);
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 7869c3d7438..77f2e0db7ca 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -85,6 +85,8 @@ extern void falcon_set_int_moderation(struct efx_channel *channel);
extern void falcon_disable_interrupts(struct efx_nic *efx);
extern void falcon_fini_interrupt(struct efx_nic *efx);
+#define FALCON_IRQ_MOD_RESOLUTION 5
+
/* Global Resources */
extern int falcon_probe_nic(struct efx_nic *efx);
extern int falcon_probe_resources(struct efx_nic *efx);
diff --git a/drivers/net/sfc/falcon_io.h b/drivers/net/sfc/falcon_io.h
index c16da3149fa..8883092dae9 100644
--- a/drivers/net/sfc/falcon_io.h
+++ b/drivers/net/sfc/falcon_io.h
@@ -238,18 +238,21 @@ static inline void falcon_writel_page(struct efx_nic *efx, efx_dword_t *value,
/* Write dword to Falcon page-mapped register with an extra lock.
*
* As for falcon_writel_page(), but for a register that suffers from
- * SFC bug 3181. Take out a lock so the BIU collector cannot be
- * confused. */
+ * SFC bug 3181. If writing to page 0, take out a lock so the BIU
+ * collector cannot be confused.
+ */
static inline void falcon_writel_page_locked(struct efx_nic *efx,
efx_dword_t *value,
unsigned int reg,
unsigned int page)
{
- unsigned long flags;
+ unsigned long flags = 0;
- spin_lock_irqsave(&efx->biu_lock, flags);
+ if (page == 0)
+ spin_lock_irqsave(&efx->biu_lock, flags);
falcon_writel(efx, value, FALCON_PAGED_REG(page, reg));
- spin_unlock_irqrestore(&efx->biu_lock, flags);
+ if (page == 0)
+ spin_unlock_irqrestore(&efx->biu_lock, flags);
}
#endif /* EFX_FALCON_IO_H */
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index f6a16428113..9f5ec3eb341 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -15,6 +15,22 @@
#include "net_driver.h"
#include "mdio_10g.h"
#include "boards.h"
+#include "workarounds.h"
+
+unsigned mdio_id_oui(u32 id)
+{
+ unsigned oui = 0;
+ int i;
+
+ /* The bits of the OUI are designated a..x, with a=0 and b variable.
+ * In the id register c is the MSB but the OUI is conventionally
+ * written as bytes h..a, p..i, x..q. Reorder the bits accordingly. */
+ for (i = 0; i < 22; ++i)
+ if (id & (1 << (i + 10)))
+ oui |= 1 << (i ^ 7);
+
+ return oui;
+}
int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
int spins, int spintime)
@@ -124,24 +140,25 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
int mdio_clause45_check_mmds(struct efx_nic *efx,
unsigned int mmd_mask, unsigned int fatal_mask)
{
+ int mmd = 0, probe_mmd, devs0, devs1;
u32 devices;
- int mmd = 0, probe_mmd;
/* 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 :
__ffs(mmd_mask);
- devices = (mdio_clause45_read(efx, efx->mii.phy_id,
- probe_mmd, MDIO_MMDREG_DEVS0) |
- mdio_clause45_read(efx, efx->mii.phy_id,
- probe_mmd, MDIO_MMDREG_DEVS1) << 16);
/* Check all the expected MMDs are present */
- if (devices < 0) {
+ 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) {
EFX_ERR(efx, "failed to read devices present\n");
return -EIO;
}
+ devices = devs0 | (devs1 << 16);
if ((devices & mmd_mask) != mmd_mask) {
EFX_ERR(efx, "required MMDs not present: got %x, "
"wanted %x\n", devices, mmd_mask);
@@ -179,17 +196,12 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
return false;
else if (efx_phy_mode_disabled(efx->phy_mode))
return false;
- else if (efx->loopback_mode == LOOPBACK_PHYXS) {
+ 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);
- if (!mmd_mask) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
- MDIO_PHYXS_STATUS2);
- return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
- }
- } else if (efx->loopback_mode == LOOPBACK_PCS)
+ else if (efx->loopback_mode == LOOPBACK_PCS)
mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
MDIO_MMDREG_DEVS_PMAPMD |
MDIO_MMDREG_DEVS_AN);
@@ -197,6 +209,13 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
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));
+ }
+
while (mmd_mask) {
if (mmd_mask & 1) {
/* Double reads because link state is latched, and a
@@ -263,7 +282,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
}
}
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
+static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
{
int phy_id = efx->mii.phy_id;
u32 result = 0;
@@ -278,9 +297,6 @@ static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
result |= ADVERTISED_100baseT_Half;
if (reg & ADVERTISE_100FULL)
result |= ADVERTISED_100baseT_Full;
- if (reg & LPA_RESV)
- result |= xnp;
-
return result;
}
@@ -310,7 +326,7 @@ void mdio_clause45_get_settings(struct efx_nic *efx,
*/
void mdio_clause45_get_settings_ext(struct efx_nic *efx,
struct ethtool_cmd *ecmd,
- u32 xnp, u32 xnp_lpa)
+ u32 npage_adv, u32 npage_lpa)
{
int phy_id = efx->mii.phy_id;
int reg;
@@ -361,8 +377,8 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->advertising |=
ADVERTISED_Autoneg |
- mdio_clause45_get_an(efx,
- MDIO_AN_ADVERTISE, xnp);
+ mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
+ npage_adv;
} else
ecmd->autoneg = AUTONEG_DISABLE;
} else
@@ -371,27 +387,30 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
if (ecmd->autoneg) {
/* If AN is complete, report best common mode,
* otherwise report best advertised mode. */
- u32 common = ecmd->advertising;
+ u32 modes = 0;
if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_STAT1) &
- (1 << MDIO_AN_STATUS_AN_DONE_LBN)) {
- common &= mdio_clause45_get_an(efx, MDIO_AN_LPA,
- xnp_lpa);
- }
- if (common & ADVERTISED_10000baseT_Full) {
+ (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 (common & (ADVERTISED_1000baseT_Full |
- ADVERTISED_1000baseT_Half)) {
+ } else if (modes & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseT_Half)) {
ecmd->speed = SPEED_1000;
- ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full);
- } else if (common & (ADVERTISED_100baseT_Full |
- ADVERTISED_100baseT_Half)) {
+ ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
+ } else if (modes & (ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half)) {
ecmd->speed = SPEED_100;
- ecmd->duplex = !!(common & ADVERTISED_100baseT_Full);
+ ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
} else {
ecmd->speed = SPEED_10;
- ecmd->duplex = !!(common & ADVERTISED_10baseT_Full);
+ ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
}
} else {
/* Report forced settings */
@@ -415,7 +434,7 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
int phy_id = efx->mii.phy_id;
struct ethtool_cmd prev;
u32 required;
- int ctrl1_bits, reg;
+ int reg;
efx->phy_op->get_settings(efx, &prev);
@@ -430,99 +449,83 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
if (prev.port != PORT_TP || ecmd->port != PORT_TP)
return -EINVAL;
- /* Check that PHY supports these settings and work out the
- * basic control bits */
- if (ecmd->duplex) {
+ /* Check that PHY supports these settings */
+ if (ecmd->autoneg) {
+ required = SUPPORTED_Autoneg;
+ } else if (ecmd->duplex) {
switch (ecmd->speed) {
- case SPEED_10:
- ctrl1_bits = BMCR_FULLDPLX;
- required = SUPPORTED_10baseT_Full;
- break;
- case SPEED_100:
- ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX;
- required = SUPPORTED_100baseT_Full;
- break;
- case SPEED_1000:
- ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX;
- required = SUPPORTED_1000baseT_Full;
- break;
- case SPEED_10000:
- ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 |
- BMCR_FULLDPLX);
- required = SUPPORTED_10000baseT_Full;
- break;
- default:
- return -EINVAL;
+ case SPEED_10: required = SUPPORTED_10baseT_Full; break;
+ case SPEED_100: required = SUPPORTED_100baseT_Full; break;
+ default: return -EINVAL;
}
} else {
switch (ecmd->speed) {
- case SPEED_10:
- ctrl1_bits = 0;
- required = SUPPORTED_10baseT_Half;
- break;
- case SPEED_100:
- ctrl1_bits = BMCR_SPEED100;
- required = SUPPORTED_100baseT_Half;
- break;
- case SPEED_1000:
- ctrl1_bits = BMCR_SPEED1000;
- required = SUPPORTED_1000baseT_Half;
- break;
- default:
- return -EINVAL;
+ case SPEED_10: required = SUPPORTED_10baseT_Half; break;
+ case SPEED_100: required = SUPPORTED_100baseT_Half; break;
+ default: return -EINVAL;
}
}
- if (ecmd->autoneg)
- required |= SUPPORTED_Autoneg;
required |= ecmd->advertising;
if (required & ~prev.supported)
return -EINVAL;
- /* 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 |= ctrl1_bits;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1,
- reg);
-
- /* Set the AN registers */
- if (ecmd->autoneg != prev.autoneg ||
- ecmd->advertising != prev.advertising) {
- bool xnp = false;
-
- if (efx->phy_op->set_xnp_advertise)
- xnp = efx->phy_op->set_xnp_advertise(efx,
- ecmd->advertising);
-
- if (ecmd->autoneg) {
- reg = 0;
- if (ecmd->advertising & ADVERTISED_10baseT_Half)
- reg |= ADVERTISE_10HALF;
- if (ecmd->advertising & ADVERTISED_10baseT_Full)
- reg |= ADVERTISE_10FULL;
- if (ecmd->advertising & ADVERTISED_100baseT_Half)
- reg |= ADVERTISE_100HALF;
- if (ecmd->advertising & ADVERTISED_100baseT_Full)
- reg |= ADVERTISE_100FULL;
- if (xnp)
- reg |= ADVERTISE_RESV;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE, reg);
- }
+ if (ecmd->autoneg) {
+ bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full
+ || EFX_WORKAROUND_13204(efx));
+
+ /* Set up the base page */
+ reg = ADVERTISE_CSMA;
+ if (ecmd->advertising & ADVERTISED_10baseT_Half)
+ reg |= ADVERTISE_10HALF;
+ if (ecmd->advertising & ADVERTISED_10baseT_Full)
+ reg |= ADVERTISE_10FULL;
+ if (ecmd->advertising & ADVERTISED_100baseT_Half)
+ reg |= ADVERTISE_100HALF;
+ if (ecmd->advertising & ADVERTISED_100baseT_Full)
+ reg |= ADVERTISE_100FULL;
+ if (xnp)
+ reg |= ADVERTISE_RESV;
+ 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);
+ /* 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);
- if (ecmd->autoneg)
- reg |= BMCR_ANENABLE | BMCR_ANRESTART;
- else
- reg &= ~BMCR_ANENABLE;
+ reg |= BMCR_ANENABLE;
+ if (!(EFX_WORKAROUND_15195(efx) &&
+ LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
+ reg |= BMCR_ANRESTART;
if (xnp)
reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
else
reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_CTRL1, reg);
+ } else {
+ /* Disable AN */
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+ MDIO_MMDREG_CTRL1,
+ __ffs(BMCR_ANENABLE), 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);
+ if (ecmd->speed == SPEED_100)
+ reg |= BMCR_SPEED100;
+ if (ecmd->duplex)
+ reg |= BMCR_FULLDPLX;
+ mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
+ MDIO_MMDREG_CTRL1, reg);
}
return 0;
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 09bf801d056..7014d2279c2 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -70,10 +70,10 @@
#define MDIO_MMDREG_STAT1_LPABLE_LBN (1)
#define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1)
-/* Bits in ID reg */
-#define MDIO_ID_REV(_id32) (_id32 & 0xf)
-#define MDIO_ID_MODEL(_id32) ((_id32 >> 4) & 0x3f)
-#define MDIO_ID_OUI(_id32) (_id32 >> 10)
+/* 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
@@ -155,7 +155,8 @@
#define MDIO_AN_XNP 22
#define MDIO_AN_LPA_XNP 25
-#define MDIO_AN_10GBT_ADVERTISE 32
+#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 */
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c
index 665cafb88d6..820c233c3ea 100644
--- a/drivers/net/sfc/mtd.c
+++ b/drivers/net/sfc/mtd.c
@@ -15,6 +15,7 @@
#define EFX_DRIVER_NAME "sfc_mtd"
#include "net_driver.h"
#include "spi.h"
+#include "efx.h"
#define EFX_SPI_VERIFY_BUF_LEN 16
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 5f255f75754..e169e5dcd1e 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -25,15 +25,11 @@
#include <linux/device.h>
#include <linux/highmem.h>
#include <linux/workqueue.h>
-#include <linux/inet_lro.h>
#include <linux/i2c.h>
#include "enum.h"
#include "bitfield.h"
-#define EFX_MAX_LRO_DESCRIPTORS 8
-#define EFX_MAX_LRO_AGGR MAX_SKB_FRAGS
-
/**************************************************************************
*
* Build definitions
@@ -340,13 +336,12 @@ enum efx_rx_alloc_method {
* @eventq_read_ptr: Event queue read pointer
* @last_eventq_read_ptr: Last event queue read pointer value.
* @eventq_magic: Event queue magic value for driver-generated test events
- * @lro_mgr: LRO state
+ * @irq_count: Number of IRQs since last adaptive moderation decision
+ * @irq_mod_score: IRQ moderation score
* @rx_alloc_level: Watermark based heuristic counter for pushing descriptors
* and diagnostic counters
* @rx_alloc_push_pages: RX allocation method currently in use for pushing
* descriptors
- * @rx_alloc_pop_pages: RX allocation method currently in use for popping
- * descriptors
* @n_rx_tobe_disc: Count of RX_TOBE_DISC errors
* @n_rx_ip_frag_err: Count of RX IP fragment errors
* @n_rx_ip_hdr_chksum_err: Count of RX IP header checksum errors
@@ -371,10 +366,11 @@ struct efx_channel {
unsigned int last_eventq_read_ptr;
unsigned int eventq_magic;
- struct net_lro_mgr lro_mgr;
+ unsigned int irq_count;
+ unsigned int irq_mod_score;
+
int rx_alloc_level;
int rx_alloc_push_pages;
- int rx_alloc_pop_pages;
unsigned n_rx_tobe_disc;
unsigned n_rx_ip_frag_err;
@@ -394,13 +390,11 @@ struct efx_channel {
/**
* struct efx_blinker - S/W LED blinking context
- * @led_num: LED ID (board-specific meaning)
* @state: Current state - on or off
* @resubmit: Timer resubmission flag
* @timer: Control timer for blinking
*/
struct efx_blinker {
- int led_num;
bool state;
bool resubmit;
struct timer_list timer;
@@ -413,8 +407,8 @@ struct efx_blinker {
* @major: Major rev. ('A', 'B' ...)
* @minor: Minor rev. (0, 1, ...)
* @init: Initialisation function
- * @init_leds: Sets up board LEDs
- * @set_fault_led: Turns the fault LED on or off
+ * @init_leds: Sets up board LEDs. May be called repeatedly.
+ * @set_id_led: Turns the identification LED on or off
* @blink: Starts/stops blinking
* @monitor: Board-specific health check function
* @fini: Cleanup function
@@ -430,9 +424,9 @@ struct efx_board {
/* As the LEDs are typically attached to the PHY, LEDs
* have a separate init callback that happens later than
* board init. */
- int (*init_leds)(struct efx_nic *efx);
+ void (*init_leds)(struct efx_nic *efx);
+ void (*set_id_led) (struct efx_nic *efx, bool state);
int (*monitor) (struct efx_nic *nic);
- void (*set_fault_led) (struct efx_nic *efx, bool state);
void (*blink) (struct efx_nic *efx, bool start);
void (*fini) (struct efx_nic *nic);
struct efx_blinker blinker;
@@ -459,6 +453,7 @@ enum phy_type {
PHY_TYPE_QT2022C2 = 4,
PHY_TYPE_PM8358 = 6,
PHY_TYPE_SFT9001A = 8,
+ PHY_TYPE_QT2025C = 9,
PHY_TYPE_SFT9001B = 10,
PHY_TYPE_MAX /* Insert any new items before this */
};
@@ -566,7 +561,7 @@ struct efx_mac_operations {
* @poll: Poll for hardware state. Serialised by the mac_lock.
* @get_settings: Get ethtool settings. Serialised by the mac_lock.
* @set_settings: Set ethtool settings. Serialised by the mac_lock.
- * @set_xnp_advertise: Set abilities advertised in Extended Next Page
+ * @set_npage_adv: Set abilities advertised in (Extended) Next Page
* (only needed where AN bit is set in mmds)
* @num_tests: Number of PHY-specific tests/results
* @test_names: Names of the tests/results
@@ -586,7 +581,7 @@ struct efx_phy_operations {
struct ethtool_cmd *ecmd);
int (*set_settings) (struct efx_nic *efx,
struct ethtool_cmd *ecmd);
- bool (*set_xnp_advertise) (struct efx_nic *efx, u32);
+ void (*set_npage_adv) (struct efx_nic *efx, u32);
u32 num_tests;
const char *const *test_names;
int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags);
@@ -713,6 +708,8 @@ union efx_multicast_hash {
* @membase: Memory BAR value
* @biu_lock: BIU (bus interface unit) lock
* @interrupt_mode: Interrupt mode
+ * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
+ * @irq_rx_moderation: IRQ moderation time for RX event queues
* @i2c_adap: I2C adapter
* @board_info: Board-level information
* @state: Device state flag. Serialised by the rtnl_lock.
@@ -754,8 +751,7 @@ union efx_multicast_hash {
* &struct net_device_stats.
* @stats_buffer: DMA buffer for statistics
* @stats_lock: Statistics update lock. Serialises statistics fetches
- * @stats_enabled: Temporarily disable statistics fetches.
- * Serialised by @stats_lock
+ * @stats_disable_count: Nest count for disabling statistics fetches
* @mac_op: MAC interface
* @mac_address: Permanent MAC address
* @phy_type: PHY type
@@ -795,6 +791,8 @@ struct efx_nic {
void __iomem *membase;
spinlock_t biu_lock;
enum efx_int_mode interrupt_mode;
+ bool irq_rx_adaptive;
+ unsigned int irq_rx_moderation;
struct i2c_adapter i2c_adap;
struct efx_board board_info;
@@ -837,7 +835,7 @@ struct efx_nic {
struct efx_mac_stats mac_stats;
struct efx_buffer stats_buffer;
spinlock_t stats_lock;
- bool stats_enabled;
+ unsigned int stats_disable_count;
struct efx_mac_operations *mac_op;
unsigned char mac_address[ETH_ALEN];
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 58c493ef81b..c1cff9c0c17 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -17,14 +17,17 @@ extern struct efx_phy_operations falcon_sfx7101_phy_ops;
extern struct efx_phy_operations falcon_sft9001_phy_ops;
extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
-extern void tenxpress_crc_err(struct efx_nic *efx);
+
+/* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed
+ * to boot due to corrupt flash, or some other negative error code. */
+extern int sft9001_wait_boot(struct efx_nic *efx);
/****************************************************************************
- * Exported functions from the driver for XFP optical PHYs
+ * AMCC/Quake QT20xx PHYs
*/
extern struct efx_phy_operations falcon_xfp_phy_ops;
-/* The QUAKE XFP PHY provides various H/W control states for LEDs */
+/* These PHYs provide various H/W control states for LEDs */
#define QUAKE_LED_LINK_INVAL (0)
#define QUAKE_LED_LINK_STAT (1)
#define QUAKE_LED_LINK_ACT (2)
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index b8ba4bbad88..66d7fe3db3e 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -99,109 +99,6 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
}
-/**************************************************************************
- *
- * Linux generic LRO handling
- *
- **************************************************************************
- */
-
-static int efx_lro_get_skb_hdr(struct sk_buff *skb, void **ip_hdr,
- void **tcpudp_hdr, u64 *hdr_flags, void *priv)
-{
- struct efx_channel *channel = priv;
- struct iphdr *iph;
- struct tcphdr *th;
-
- iph = (struct iphdr *)skb->data;
- if (skb->protocol != htons(ETH_P_IP) || iph->protocol != IPPROTO_TCP)
- goto fail;
-
- th = (struct tcphdr *)(skb->data + iph->ihl * 4);
-
- *tcpudp_hdr = th;
- *ip_hdr = iph;
- *hdr_flags = LRO_IPV4 | LRO_TCP;
-
- channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
- return 0;
-fail:
- channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
- return -1;
-}
-
-static int efx_get_frag_hdr(struct skb_frag_struct *frag, void **mac_hdr,
- void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags,
- void *priv)
-{
- struct efx_channel *channel = priv;
- struct ethhdr *eh;
- struct iphdr *iph;
-
- /* We support EtherII and VLAN encapsulated IPv4 */
- eh = page_address(frag->page) + frag->page_offset;
- *mac_hdr = eh;
-
- if (eh->h_proto == htons(ETH_P_IP)) {
- iph = (struct iphdr *)(eh + 1);
- } else {
- struct vlan_ethhdr *veh = (struct vlan_ethhdr *)eh;
- if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
- goto fail;
-
- iph = (struct iphdr *)(veh + 1);
- }
- *ip_hdr = iph;
-
- /* We can only do LRO over TCP */
- if (iph->protocol != IPPROTO_TCP)
- goto fail;
-
- *hdr_flags = LRO_IPV4 | LRO_TCP;
- *tcpudp_hdr = (struct tcphdr *)((u8 *) iph + iph->ihl * 4);
-
- channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
- return 0;
- fail:
- channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
- return -1;
-}
-
-int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx)
-{
- size_t s = sizeof(struct net_lro_desc) * EFX_MAX_LRO_DESCRIPTORS;
- struct net_lro_desc *lro_arr;
-
- /* Allocate the LRO descriptors structure */
- lro_arr = kzalloc(s, GFP_KERNEL);
- if (lro_arr == NULL)
- return -ENOMEM;
-
- lro_mgr->lro_arr = lro_arr;
- lro_mgr->max_desc = EFX_MAX_LRO_DESCRIPTORS;
- lro_mgr->max_aggr = EFX_MAX_LRO_AGGR;
- lro_mgr->frag_align_pad = EFX_PAGE_SKB_ALIGN;
-
- lro_mgr->get_skb_header = efx_lro_get_skb_hdr;
- lro_mgr->get_frag_header = efx_get_frag_hdr;
- lro_mgr->dev = efx->net_dev;
-
- lro_mgr->features = LRO_F_NAPI;
-
- /* We can pass packets up with the checksum intact */
- lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
-
- lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
-
- return 0;
-}
-
-void efx_lro_fini(struct net_lro_mgr *lro_mgr)
-{
- kfree(lro_mgr->lro_arr);
- lro_mgr->lro_arr = NULL;
-}
-
/**
* efx_init_rx_buffer_skb - create new RX buffer using skb-based allocation
*
@@ -549,77 +446,31 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
static void efx_rx_packet_lro(struct efx_channel *channel,
struct efx_rx_buffer *rx_buf)
{
- struct net_lro_mgr *lro_mgr = &channel->lro_mgr;
- void *priv = channel;
+ struct napi_struct *napi = &channel->napi_str;
/* Pass the skb/page into the LRO engine */
if (rx_buf->page) {
- struct skb_frag_struct frags;
+ struct napi_gro_fraginfo info;
- frags.page = rx_buf->page;
- frags.page_offset = efx_rx_buf_offset(rx_buf);
- frags.size = rx_buf->len;
+ 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;
- lro_receive_frags(lro_mgr, &frags, rx_buf->len,
- rx_buf->len, priv, 0);
+ napi_gro_frags(napi, &info);
EFX_BUG_ON_PARANOID(rx_buf->skb);
rx_buf->page = NULL;
} else {
EFX_BUG_ON_PARANOID(!rx_buf->skb);
- lro_receive_skb(lro_mgr, rx_buf->skb, priv);
+ napi_gro_receive(napi, rx_buf->skb);
rx_buf->skb = NULL;
}
}
-/* Allocate and construct an SKB around a struct page.*/
-static struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf,
- struct efx_nic *efx,
- int hdr_len)
-{
- struct sk_buff *skb;
-
- /* Allocate an SKB to store the headers */
- skb = netdev_alloc_skb(efx->net_dev, hdr_len + EFX_PAGE_SKB_ALIGN);
- if (unlikely(skb == NULL)) {
- EFX_ERR_RL(efx, "RX out of memory for skb\n");
- return NULL;
- }
-
- EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags);
- EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len);
-
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- skb_reserve(skb, EFX_PAGE_SKB_ALIGN);
-
- skb->len = rx_buf->len;
- skb->truesize = rx_buf->len + sizeof(struct sk_buff);
- memcpy(skb->data, rx_buf->data, hdr_len);
- skb->tail += hdr_len;
-
- /* Append the remaining page onto the frag list */
- if (unlikely(rx_buf->len > hdr_len)) {
- struct skb_frag_struct *frag = skb_shinfo(skb)->frags;
- frag->page = rx_buf->page;
- frag->page_offset = efx_rx_buf_offset(rx_buf) + hdr_len;
- frag->size = skb->len - hdr_len;
- skb_shinfo(skb)->nr_frags = 1;
- skb->data_len = frag->size;
- } else {
- __free_pages(rx_buf->page, efx->rx_buffer_order);
- skb->data_len = 0;
- }
-
- /* Ownership has transferred from the rx_buf to skb */
- rx_buf->page = NULL;
-
- /* Move past the ethernet header */
- skb->protocol = eth_type_trans(skb, efx->net_dev);
-
- return skb;
-}
-
void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int len, bool checksummed, bool discard)
{
@@ -687,7 +538,6 @@ void __efx_rx_packet(struct efx_channel *channel,
{
struct efx_nic *efx = channel->efx;
struct sk_buff *skb;
- bool lro = !!(efx->net_dev->features & NETIF_F_LRO);
/* If we're in loopback test, then pass the packet directly to the
* loopback layer, and free the rx_buf here
@@ -709,41 +559,23 @@ void __efx_rx_packet(struct efx_channel *channel,
efx->net_dev);
}
- /* Both our generic-LRO and SFC-SSR support skb and page based
- * allocation, but neither support switching from one to the
- * other on the fly. If we spot that the allocation mode has
- * changed, then flush the LRO state.
- */
- if (unlikely(channel->rx_alloc_pop_pages != (rx_buf->page != NULL))) {
- efx_flush_lro(channel);
- channel->rx_alloc_pop_pages = (rx_buf->page != NULL);
- }
- if (likely(checksummed && lro)) {
+ if (likely(checksummed || rx_buf->page)) {
efx_rx_packet_lro(channel, rx_buf);
goto done;
}
- /* Form an skb if required */
- if (rx_buf->page) {
- int hdr_len = min(rx_buf->len, EFX_SKB_HEADERS);
- skb = efx_rx_mk_skb(rx_buf, efx, hdr_len);
- if (unlikely(skb == NULL)) {
- efx_free_rx_buffer(efx, rx_buf);
- goto done;
- }
- } else {
- /* We now own the SKB */
- skb = rx_buf->skb;
- rx_buf->skb = NULL;
- }
+ /* We now own the SKB */
+ skb = rx_buf->skb;
+ rx_buf->skb = NULL;
EFX_BUG_ON_PARANOID(rx_buf->page);
EFX_BUG_ON_PARANOID(rx_buf->skb);
EFX_BUG_ON_PARANOID(!skb);
/* Set the SKB flags */
- if (unlikely(!checksummed || !efx->rx_checksum_enabled))
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = CHECKSUM_NONE;
+
+ skb_record_rx_queue(skb, channel->channel);
/* Pass the packet up */
netif_receive_skb(skb);
@@ -760,7 +592,7 @@ void efx_rx_strategy(struct efx_channel *channel)
enum efx_rx_alloc_method method = rx_alloc_method;
/* Only makes sense to use page based allocation if LRO is enabled */
- if (!(channel->efx->net_dev->features & NETIF_F_LRO)) {
+ if (!(channel->efx->net_dev->features & NETIF_F_GRO)) {
method = RX_ALLOC_METHOD_SKB;
} else if (method == RX_ALLOC_METHOD_AUTO) {
/* Constrain the rx_alloc_level */
@@ -865,11 +697,6 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue)
rx_queue->buffer = NULL;
}
-void efx_flush_lro(struct efx_channel *channel)
-{
- lro_flush_all(&channel->lro_mgr);
-}
-
module_param(rx_alloc_method, int, 0644);
MODULE_PARM_DESC(rx_alloc_method, "Allocation method used for RX buffers");
diff --git a/drivers/net/sfc/rx.h b/drivers/net/sfc/rx.h
index 0e88a9ddc1c..42ee7555a80 100644
--- a/drivers/net/sfc/rx.h
+++ b/drivers/net/sfc/rx.h
@@ -17,9 +17,6 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
-int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx);
-void efx_lro_fini(struct net_lro_mgr *lro_mgr);
-void efx_flush_lro(struct efx_channel *channel);
void efx_rx_strategy(struct efx_channel *channel);
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
void efx_rx_work(struct work_struct *data);
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index dba0d64d50c..0a598084c51 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -665,6 +665,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
{
enum efx_loopback_mode loopback_mode = efx->loopback_mode;
int phy_mode = efx->phy_mode;
+ enum reset_type reset_method = RESET_TYPE_INVISIBLE;
struct ethtool_cmd ecmd;
struct efx_channel *channel;
int rc_test = 0, rc_reset = 0, rc;
@@ -718,21 +719,21 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
mutex_unlock(&efx->mac_lock);
/* free up all consumers of SRAM (including all the queues) */
- efx_reset_down(efx, &ecmd);
+ efx_reset_down(efx, reset_method, &ecmd);
rc = efx_test_chip(efx, tests);
if (rc && !rc_test)
rc_test = rc;
/* reset the chip to recover from the register test */
- rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL);
+ rc_reset = falcon_reset_hw(efx, reset_method);
/* Ensure that the phy is powered and out of loopback
* for the bist and loopback tests */
efx->phy_mode &= ~PHY_MODE_LOW_POWER;
efx->loopback_mode = LOOPBACK_NONE;
- rc = efx_reset_up(efx, &ecmd, rc_reset == 0);
+ rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0);
if (rc && !rc_reset)
rc_reset = rc;
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 16b80acb999..4eac5da81e5 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -24,6 +24,7 @@
*/
#include <linux/delay.h>
+#include <linux/rtnetlink.h>
#include "net_driver.h"
#include "efx.h"
#include "phy.h"
@@ -186,19 +187,22 @@ static int sfn4111t_reset(struct efx_nic *efx)
{
efx_oword_t reg;
- /* GPIO pins are also used for I2C, so block that temporarily */
+ /* GPIO 3 and the GPIO register are shared with I2C, so block that */
mutex_lock(&efx->i2c_adap.bus_lock);
+ /* Pull RST_N (GPIO 2) low then let it up again, setting the
+ * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the
+ * output enables; the output levels should always be 0 (low)
+ * and we rely on external pull-ups. */
falcon_read(efx, &reg, GPIO_CTL_REG_KER);
EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
- EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false);
falcon_write(efx, &reg, GPIO_CTL_REG_KER);
msleep(1000);
- EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true);
- EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true);
- EFX_SET_OWORD_FIELD(reg, GPIO3_OUT,
- !(efx->phy_mode & PHY_MODE_SPECIAL));
+ EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false);
+ EFX_SET_OWORD_FIELD(reg, GPIO3_OEN,
+ !!(efx->phy_mode & PHY_MODE_SPECIAL));
falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+ msleep(1);
mutex_unlock(&efx->i2c_adap.bus_lock);
@@ -232,12 +236,18 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
err = -EBUSY;
} else {
+ /* Reset the PHY, reconfigure the MAC and enable/disable
+ * MAC stats accordingly. */
efx->phy_mode = new_mode;
+ if (new_mode & PHY_MODE_SPECIAL)
+ efx_stats_disable(efx);
if (efx->board_info.type == EFX_BOARD_SFE4001)
err = sfe4001_poweron(efx);
else
err = sfn4111t_reset(efx);
efx_reconfigure_port(efx);
+ if (!(new_mode & PHY_MODE_SPECIAL))
+ efx_stats_enable(efx);
}
rtnl_unlock();
@@ -326,6 +336,11 @@ int sfe4001_init(struct efx_nic *efx)
efx->board_info.monitor = sfe4001_check_hw;
efx->board_info.fini = sfe4001_fini;
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
+ * will fail. */
+ efx_stats_disable(efx);
+ }
rc = sfe4001_poweron(efx);
if (rc)
goto fail_ioexp;
@@ -372,17 +387,26 @@ static void sfn4111t_fini(struct efx_nic *efx)
i2c_unregister_device(efx->board_info.hwmon_client);
}
-static struct i2c_board_info sfn4111t_hwmon_info = {
+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)
{
+ int i = 0;
int rc;
efx->board_info.hwmon_client =
- i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info);
+ i2c_new_device(&efx->i2c_adap,
+ (efx->board_info.minor < 5) ?
+ &sfn4111t_a0_hwmon_info :
+ &sfn4111t_r5_hwmon_info);
if (!efx->board_info.hwmon_client)
return -EIO;
@@ -394,11 +418,20 @@ int sfn4111t_init(struct efx_nic *efx)
if (rc)
goto fail_hwmon;
- if (efx->phy_mode & PHY_MODE_SPECIAL)
- sfn4111t_reset(efx);
-
- return 0;
+ do {
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ /* PHY may not generate a 156.25 MHz clock and MAC
+ * stats fetch will fail. */
+ efx_stats_disable(efx);
+ sfn4111t_reset(efx);
+ }
+ rc = sft9001_wait_boot(efx);
+ if (rc == 0)
+ return 0;
+ efx->phy_mode = PHY_MODE_SPECIAL;
+ } while (rc == -EINVAL && ++i < 2);
+ device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
fail_hwmon:
i2c_unregister_device(efx->board_info.hwmon_client);
return rc;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 9ecb77da954..e61dc4d4741 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -8,6 +8,7 @@
*/
#include <linux/delay.h>
+#include <linux/rtnetlink.h>
#include <linux/seq_file.h>
#include "efx.h"
#include "mdio_10g.h"
@@ -67,6 +68,8 @@
#define PMA_PMD_EXT_CLK312_WIDTH 1
#define PMA_PMD_EXT_LPOWER_LBN 12
#define PMA_PMD_EXT_LPOWER_WIDTH 1
+#define PMA_PMD_EXT_ROBUST_LBN 14
+#define PMA_PMD_EXT_ROBUST_WIDTH 1
#define PMA_PMD_EXT_SSR_LBN 15
#define PMA_PMD_EXT_SSR_WIDTH 1
@@ -155,14 +158,16 @@
#define PCS_10GBASET_BLKLK_WIDTH 1
/* Boot status register */
-#define PCS_BOOT_STATUS_REG 53248
-#define PCS_BOOT_FATAL_ERR_LBN (0)
-#define PCS_BOOT_PROGRESS_LBN (1)
-#define PCS_BOOT_PROGRESS_WIDTH (2)
-#define PCS_BOOT_COMPLETE_LBN (3)
-
-#define PCS_BOOT_MAX_DELAY (100)
-#define PCS_BOOT_POLL_DELAY (10)
+#define PCS_BOOT_STATUS_REG 53248
+#define PCS_BOOT_FATAL_ERROR_LBN 0
+#define PCS_BOOT_PROGRESS_LBN 1
+#define PCS_BOOT_PROGRESS_WIDTH 2
+#define PCS_BOOT_PROGRESS_INIT 0
+#define PCS_BOOT_PROGRESS_WAIT_MDIO 1
+#define PCS_BOOT_PROGRESS_CHECKSUM 2
+#define PCS_BOOT_PROGRESS_JUMP 3
+#define PCS_BOOT_DOWNLOAD_WAIT_LBN 3
+#define PCS_BOOT_CODE_STARTED_LBN 4
/* 100M/1G PHY registers */
#define GPHY_XCONTROL_REG 49152
@@ -177,35 +182,24 @@
#define C22EXT_STATUS_LINK_LBN 2
#define C22EXT_STATUS_LINK_WIDTH 1
-#define C22EXT_MSTSLV_REG 49162
-#define C22EXT_MSTSLV_1000_HD_LBN 10
-#define C22EXT_MSTSLV_1000_HD_WIDTH 1
-#define C22EXT_MSTSLV_1000_FD_LBN 11
-#define C22EXT_MSTSLV_1000_FD_WIDTH 1
+#define C22EXT_MSTSLV_CTRL 49161
+#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8
+#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9
+
+#define C22EXT_MSTSLV_STATUS 49162
+#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10
+#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11
/* Time to wait between powering down the LNPGA and turning off the power
* rails */
#define LNPGA_PDOWN_WAIT (HZ / 5)
-static int crc_error_reset_threshold = 100;
-module_param(crc_error_reset_threshold, int, 0644);
-MODULE_PARM_DESC(crc_error_reset_threshold,
- "Max number of CRC errors before XAUI reset");
-
struct tenxpress_phy_data {
enum efx_loopback_mode loopback_mode;
- atomic_t bad_crc_count;
enum efx_phy_mode phy_mode;
int bad_lp_tries;
};
-void tenxpress_crc_err(struct efx_nic *efx)
-{
- struct tenxpress_phy_data *phy_data = efx->phy_data;
- if (phy_data != NULL)
- atomic_inc(&phy_data->bad_crc_count);
-}
-
static ssize_t show_phy_short_reach(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -238,40 +232,62 @@ static ssize_t set_phy_short_reach(struct device *dev,
static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
set_phy_short_reach);
-/* Check that the C166 has booted successfully */
-static int tenxpress_phy_check(struct efx_nic *efx)
+int sft9001_wait_boot(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
- int count = PCS_BOOT_MAX_DELAY / PCS_BOOT_POLL_DELAY;
+ unsigned long timeout = jiffies + HZ + 1;
int boot_stat;
- /* Wait for the boot to complete (or not) */
- while (count) {
- boot_stat = mdio_clause45_read(efx, phy_id,
+ for (;;) {
+ boot_stat = mdio_clause45_read(efx, efx->mii.phy_id,
MDIO_MMD_PCS,
PCS_BOOT_STATUS_REG);
- if (boot_stat & (1 << PCS_BOOT_COMPLETE_LBN))
- break;
- count--;
- udelay(PCS_BOOT_POLL_DELAY);
- }
+ if (boot_stat >= 0) {
+ EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat);
+ switch (boot_stat &
+ ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (3 << PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN))) {
+ case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (PCS_BOOT_PROGRESS_CHECKSUM <<
+ PCS_BOOT_PROGRESS_LBN)):
+ case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (PCS_BOOT_PROGRESS_INIT <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
+ return -EINVAL;
+ case ((PCS_BOOT_PROGRESS_WAIT_MDIO <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
+ return (efx->phy_mode & PHY_MODE_SPECIAL) ?
+ 0 : -EIO;
+ case ((PCS_BOOT_PROGRESS_JUMP <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN)):
+ case ((PCS_BOOT_PROGRESS_JUMP <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN)):
+ return (efx->phy_mode & PHY_MODE_SPECIAL) ?
+ -EIO : 0;
+ default:
+ if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN))
+ return -EIO;
+ break;
+ }
+ }
- if (!count) {
- EFX_ERR(efx, "%s: PHY boot timed out. Last status "
- "%x\n", __func__,
- (boot_stat >> PCS_BOOT_PROGRESS_LBN) &
- ((1 << PCS_BOOT_PROGRESS_WIDTH) - 1));
- return -ETIMEDOUT;
- }
+ if (time_after_eq(jiffies, timeout))
+ return -ETIMEDOUT;
- return 0;
+ msleep(50);
+ }
}
static int tenxpress_init(struct efx_nic *efx)
{
int phy_id = efx->mii.phy_id;
int reg;
- int rc;
if (efx->phy_type == PHY_TYPE_SFX7101) {
/* Enable 312.5 MHz clock */
@@ -284,7 +300,9 @@ static int tenxpress_init(struct efx_nic *efx)
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_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,
@@ -292,10 +310,6 @@ static int tenxpress_init(struct efx_nic *efx)
false);
}
- rc = tenxpress_phy_check(efx);
- if (rc < 0)
- return rc;
-
/* 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,
@@ -306,7 +320,7 @@ static int tenxpress_init(struct efx_nic *efx)
PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
}
- return rc;
+ return 0;
}
static int tenxpress_phy_init(struct efx_nic *efx)
@@ -346,6 +360,7 @@ 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,
@@ -376,8 +391,8 @@ static int tenxpress_special_reset(struct efx_nic *efx)
/* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
* a special software reset can glitch the XGMAC sufficiently for stats
- * requests to fail. Since we don't often special_reset, just lock. */
- spin_lock(&efx->stats_lock);
+ * requests to fail. */
+ efx_stats_disable(efx);
/* Initiate reset */
reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -392,17 +407,17 @@ static int tenxpress_special_reset(struct efx_nic *efx)
rc = mdio_clause45_wait_reset_mmds(efx,
TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
- goto unlock;
+ goto out;
/* Try and reconfigure the device */
rc = tenxpress_init(efx);
if (rc < 0)
- goto unlock;
+ goto out;
/* Wait for the XGXS state machine to churn */
mdelay(10);
-unlock:
- spin_unlock(&efx->stats_lock);
+out:
+ efx_stats_enable(efx);
return rc;
}
@@ -520,7 +535,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
struct ethtool_cmd ecmd;
- bool phy_mode_change, loop_reset, loop_toggle, loopback;
+ bool phy_mode_change, loop_reset;
if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
phy_data->phy_mode = efx->phy_mode;
@@ -531,12 +546,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
phy_data->phy_mode != PHY_MODE_NORMAL);
- loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks;
- loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks);
loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
- if (loop_reset || loop_toggle || loopback || phy_mode_change) {
+ if (loop_reset || phy_mode_change) {
int rc;
efx->phy_op->get_settings(efx, &ecmd);
@@ -551,20 +564,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
falcon_reset_xaui(efx);
}
- if (efx->phy_type != PHY_TYPE_SFX7101) {
- /* Only change autoneg once, on coming out or
- * going into loopback */
- if (loop_toggle)
- ecmd.autoneg = !loopback;
- if (loopback) {
- ecmd.duplex = DUPLEX_FULL;
- if (efx->loopback_mode == LOOPBACK_GPHY)
- ecmd.speed = SPEED_1000;
- else
- ecmd.speed = SPEED_10000;
- }
- }
-
rc = efx->phy_op->set_settings(efx, &ecmd);
WARN_ON(rc);
}
@@ -593,15 +592,14 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
static void tenxpress_phy_poll(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
- bool change = false, link_ok;
- unsigned link_fc;
+ bool change = false;
if (efx->phy_type == PHY_TYPE_SFX7101) {
- link_ok = sfx7101_link_ok(efx);
+ bool link_ok = sfx7101_link_ok(efx);
if (link_ok != efx->link_up) {
change = true;
} else {
- link_fc = mdio_clause45_get_pause(efx);
+ unsigned int link_fc = mdio_clause45_get_pause(efx);
if (link_fc != efx->link_fc)
change = true;
}
@@ -623,13 +621,6 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
if (phy_data->phy_mode != PHY_MODE_NORMAL)
return;
-
- if (EFX_WORKAROUND_10750(efx) &&
- atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
- EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n");
- falcon_reset_xaui(efx);
- atomic_set(&phy_data->bad_crc_count, 0);
- }
}
static void tenxpress_phy_fini(struct efx_nic *efx)
@@ -708,12 +699,10 @@ 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, res_reg;
-
- if (!(flags & ETH_TEST_FL_OFFLINE))
- return 0;
+ int rc = 0, rc2, i, ctrl_reg, res_reg;
- efx->phy_op->get_settings(efx, &ecmd);
+ if (flags & ETH_TEST_FL_OFFLINE)
+ efx->phy_op->get_settings(efx, &ecmd);
/* Initialise cable diagnostic results to unknown failure */
for (i = 1; i < 9; ++i)
@@ -721,18 +710,22 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
/* Run cable diagnostics; wait up to 5 seconds for them to complete.
* A cable fault is not a self-test failure, but a timeout is. */
+ ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) |
+ (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+ if (flags & ETH_TEST_FL_OFFLINE) {
+ /* Break the link in order to run full diagnostics. We
+ * must reset the PHY to resume normal service. */
+ ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
+ }
mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_CTRL_REG,
- (1 << CDIAG_CTRL_IMMED_LBN) |
- (1 << CDIAG_CTRL_BRK_LINK_LBN) |
- (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+ PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
i = 0;
while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
PMA_PMD_CDIAG_CTRL_REG) &
(1 << CDIAG_CTRL_IN_PROG_LBN)) {
if (++i == 50) {
rc = -ETIMEDOUT;
- goto reset;
+ goto out;
}
msleep(100);
}
@@ -757,122 +750,92 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
results[5 + i] = len_reg;
}
- /* We must reset to exit cable diagnostic mode. The BIST will
- * also run when we do this. */
-reset:
- rc2 = tenxpress_special_reset(efx);
- results[0] = rc2 ? -1 : 1;
- if (!rc)
- rc = rc2;
-
- rc2 = efx->phy_op->set_settings(efx, &ecmd);
- if (!rc)
- rc = rc2;
+out:
+ if (flags & ETH_TEST_FL_OFFLINE) {
+ /* Reset, running the BIST and then resuming normal service. */
+ rc2 = tenxpress_special_reset(efx);
+ results[0] = rc2 ? -1 : 1;
+ if (!rc)
+ rc = rc2;
+
+ rc2 = efx->phy_op->set_settings(efx, &ecmd);
+ if (!rc)
+ rc = rc2;
+ }
return rc;
}
-static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx)
+static void
+tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy = efx->mii.phy_id;
- u32 lpa = 0;
+ 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, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_REG);
- if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN))
+ reg = mdio_clause45_read(efx, phy_id, 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);
+ if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
lpa |= ADVERTISED_1000baseT_Half;
- if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN))
+ if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
lpa |= ADVERTISED_1000baseT_Full;
}
- reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS);
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL);
+ if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+ 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))
lpa |= ADVERTISED_10000baseT_Full;
- return lpa;
-}
-static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
- mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full,
- tenxpress_get_xnp_lpa(efx));
- ecmd->supported |= SUPPORTED_10000baseT_Full;
- ecmd->advertising |= ADVERTISED_10000baseT_Full;
+ mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
+
+ if (efx->phy_type != PHY_TYPE_SFX7101)
+ ecmd->supported |= (SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full);
+
+ /* In loopback, the PHY automatically brings up the correct interface,
+ * but doesn't advertise the correct speed. So override it */
+ if (efx->loopback_mode == LOOPBACK_GPHY)
+ ecmd->speed = SPEED_1000;
+ else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
+ ecmd->speed = SPEED_10000;
}
-static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
- u32 xnp_adv = 0;
- int reg;
-
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG);
- if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN)))
- xnp_adv |= ADVERTISED_100baseT_Full;
- if (reg & (1 << PMA_PMD_1000T_ADV_LBN))
- xnp_adv |= ADVERTISED_1000baseT_Full;
- if (reg & (1 << PMA_PMD_10000T_ADV_LBN))
- xnp_adv |= ADVERTISED_10000baseT_Full;
+ if (!ecmd->autoneg)
+ return -EINVAL;
- mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv,
- tenxpress_get_xnp_lpa(efx));
-
- ecmd->supported |= (SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full);
-
- /* Use the vendor defined C22ext register for duplex settings */
- if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG);
- ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
- DUPLEX_FULL : DUPLEX_HALF);
- }
+ return mdio_clause45_set_settings(efx, ecmd);
}
-static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- int phy_id = efx->mii.phy_id;
- int rc;
-
- rc = mdio_clause45_set_settings(efx, ecmd);
- if (rc)
- return rc;
-
- if (ecmd->speed != SPEED_10000 && !ecmd->autoneg)
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN,
- ecmd->duplex == DUPLEX_FULL);
-
- return rc;
+ 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);
}
-static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising)
+static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- int phy = efx->mii.phy_id;
- int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG);
- bool enabled;
-
- reg &= ~((1 << 2) | (1 << 3));
- if (EFX_WORKAROUND_13204(efx) &&
- (advertising & ADVERTISED_100baseT_Full))
- reg |= 1 << PMA_PMD_100TX_ADV_LBN;
- if (advertising & ADVERTISED_1000baseT_Full)
- reg |= 1 << PMA_PMD_1000T_ADV_LBN;
- if (advertising & ADVERTISED_10000baseT_Full)
- reg |= 1 << PMA_PMD_10000T_ADV_LBN;
- mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG, reg);
-
- enabled = (advertising &
- (ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_10000baseT_Full));
- if (EFX_WORKAROUND_13204(efx))
- enabled |= (advertising & ADVERTISED_100baseT_Full);
- return enabled;
+ 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);
}
struct efx_phy_operations falcon_sfx7101_phy_ops = {
@@ -882,8 +845,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
.poll = tenxpress_phy_poll,
.fini = tenxpress_phy_fini,
.clear_interrupt = efx_port_dummy_op_void,
- .get_settings = sfx7101_get_settings,
- .set_settings = mdio_clause45_set_settings,
+ .get_settings = tenxpress_get_settings,
+ .set_settings = tenxpress_set_settings,
+ .set_npage_adv = sfx7101_set_npage_adv,
.num_tests = ARRAY_SIZE(sfx7101_test_names),
.test_names = sfx7101_test_names,
.run_tests = sfx7101_run_tests,
@@ -898,9 +862,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
.poll = tenxpress_phy_poll,
.fini = tenxpress_phy_fini,
.clear_interrupt = efx_port_dummy_op_void,
- .get_settings = sft9001_get_settings,
- .set_settings = sft9001_set_settings,
- .set_xnp_advertise = sft9001_set_xnp_advertise,
+ .get_settings = tenxpress_get_settings,
+ .set_settings = tenxpress_set_settings,
+ .set_npage_adv = sft9001_set_npage_adv,
.num_tests = ARRAY_SIZE(sft9001_test_names),
.test_names = sft9001_test_names,
.run_tests = sft9001_run_tests,
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index da3e9ff339f..d6681edb701 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -162,6 +162,14 @@ static int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
/* Get size of the initial fragment */
len = skb_headlen(skb);
+ /* Pad if necessary */
+ if (EFX_WORKAROUND_15592(efx) && skb->len <= 32) {
+ EFX_BUG_ON_PARANOID(skb->data_len);
+ len = 32 + 1;
+ if (skb_pad(skb, len - skb->len))
+ return NETDEV_TX_OK;
+ }
+
fill_level = tx_queue->insert_count - tx_queue->old_read_count;
q_space = efx->type->txd_ring_mask - 1 - fill_level;
@@ -376,6 +384,9 @@ int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_tx_queue *tx_queue;
+ if (unlikely(efx->port_inhibited))
+ return NETDEV_TX_BUSY;
+
if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM];
else
@@ -397,7 +408,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
* separates the update of read_count from the test of
* stopped. */
smp_mb();
- if (unlikely(tx_queue->stopped)) {
+ if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) {
fill_level = tx_queue->insert_count - tx_queue->read_count;
if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) {
EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 82e03e1d737..c821c15445a 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -18,8 +18,8 @@
#define EFX_WORKAROUND_ALWAYS(efx) 1
#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
-#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101)
-#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
+#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
+ (efx)->phy_type == PHY_TYPE_SFT9001B)
/* XAUI resets if link not detected */
#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -29,8 +29,6 @@
#define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G
/* TX pkt parser problem with <= 16 byte TXes */
#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
-/* Low rate CRC errors require XAUI reset */
-#define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101
/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
* or a PCIe error (bug 11028) */
#define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
@@ -38,6 +36,8 @@
#define EFX_WORKAROUND_11482 EFX_WORKAROUND_ALWAYS
/* Flush events can take a very long time to appear */
#define EFX_WORKAROUND_11557 EFX_WORKAROUND_ALWAYS
+/* Truncated IPv4 packets can confuse the TX packet parser */
+#define EFX_WORKAROUND_15592 EFX_WORKAROUND_ALWAYS
/* Spurious parity errors in TSORT buffers */
#define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A
@@ -55,8 +55,8 @@
#define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A
/* Need to send XNP pages for 100BaseT */
-#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A
-/* Need to keep AN enabled */
-#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
+#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001
+/* Don't restart AN in near-side loopback */
+#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
#endif /* EFX_WORKAROUNDS_H */
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index 2d50b6ecf5f..bb1ef77d5f5 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -7,8 +7,8 @@
* by the Free Software Foundation, incorporated herein by reference.
*/
/*
- * Driver for XFP optical PHYs (plus some support specific to the Quake 2022/32)
- * See www.amcc.com for details (search for qt2032)
+ * Driver for SFP+ and XFP optical PHYs plus some support specific to the
+ * AMCC QT20xx adapters; see www.amcc.com for details
*/
#include <linux/timer.h>
@@ -31,6 +31,21 @@
/* Quake-specific MDIO registers */
#define MDIO_QUAKE_LED0_REG (0xD006)
+/* QT2025C only */
+#define PCS_FW_HEARTBEAT_REG 0xd7ee
+#define PCS_FW_HEARTB_LBN 0
+#define PCS_FW_HEARTB_WIDTH 8
+#define PCS_UC8051_STATUS_REG 0xd7fd
+#define PCS_UC_STATUS_LBN 0
+#define PCS_UC_STATUS_WIDTH 8
+#define PCS_UC_STATUS_FW_SAVE 0x20
+#define PMA_PMD_FTX_CTRL2_REG 0xc309
+#define PMA_PMD_FTX_STATIC_LBN 13
+#define PMA_PMD_VEND1_REG 0xc001
+#define PMA_PMD_VEND1_LBTXD_LBN 15
+#define PCS_VEND1_REG 0xc000
+#define PCS_VEND1_LBTXD_LBN 5
+
void xfp_set_led(struct efx_nic *p, int led, int mode)
{
int addr = MDIO_QUAKE_LED0_REG + led;
@@ -45,7 +60,49 @@ struct xfp_phy_data {
#define XFP_MAX_RESET_TIME 500
#define XFP_RESET_WAIT 10
-/* Reset the PHYXS MMD. This is documented (for the Quake PHY) as doing
+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);
+ if (reg < 0)
+ return reg;
+ counter = ((reg >> PCS_FW_HEARTB_LBN) &
+ ((1 << PCS_FW_HEARTB_WIDTH) - 1));
+ if (old_counter == 0)
+ old_counter = counter;
+ else if (counter != old_counter)
+ break;
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ msleep(10);
+ }
+
+ /* Wait for firmware status to look good */
+ for (;;) {
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
+ PCS_UC8051_STATUS_REG);
+ if (reg < 0)
+ return reg;
+ if ((reg &
+ ((1 << PCS_UC_STATUS_WIDTH) - 1) << PCS_UC_STATUS_LBN) >=
+ PCS_UC_STATUS_FW_SAVE)
+ break;
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ msleep(100);
+ }
+
+ return 0;
+}
+
+/* Reset the PHYXS MMD. This is documented (for the Quake PHYs) as doing
* a complete soft reset.
*/
static int xfp_reset_phy(struct efx_nic *efx)
@@ -58,6 +115,12 @@ static int xfp_reset_phy(struct efx_nic *efx)
if (rc < 0)
goto fail;
+ if (efx->phy_type == PHY_TYPE_QT2025C) {
+ rc = qt2025c_wait_reset(efx);
+ if (rc < 0)
+ goto fail;
+ }
+
/* Wait 250ms for the PHY to complete bootup */
msleep(250);
@@ -73,7 +136,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
return rc;
fail:
- EFX_ERR(efx, "XFP: reset timed out!\n");
+ EFX_ERR(efx, "PHY reset timed out\n");
return rc;
}
@@ -88,15 +151,15 @@ static int xfp_phy_init(struct efx_nic *efx)
return -ENOMEM;
efx->phy_data = phy_data;
- EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision"
- " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
- MDIO_ID_REV(devid));
+ 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));
phy_data->phy_mode = efx->phy_mode;
rc = xfp_reset_phy(efx);
- EFX_INFO(efx, "XFP: PHY init %s.\n",
+ EFX_INFO(efx, "PHY init %s.\n",
rc ? "failed" : "successful");
if (rc < 0)
goto fail;
@@ -131,12 +194,28 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
{
struct xfp_phy_data *phy_data = efx->phy_data;
- /* Reset the PHY when moving from tx off to tx on */
- if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
- (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
- xfp_reset_phy(efx);
+ if (efx->phy_type == PHY_TYPE_QT2025C) {
+ /* There are several different register bits which can
+ * disable TX (and save power) on direct-attach cables
+ * 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,
+ efx->phy_mode & PHY_MODE_TX_DISABLED ||
+ efx->phy_mode & PHY_MODE_LOW_POWER ||
+ efx->loopback_mode == LOOPBACK_PCS ||
+ efx->loopback_mode == LOOPBACK_PMAPMD);
+ } else {
+ /* Reset the PHY when moving from tx off to tx on */
+ if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
+ (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
+ xfp_reset_phy(efx);
+
+ mdio_clause45_transmit_disable(efx);
+ }
- mdio_clause45_transmit_disable(efx);
mdio_clause45_phy_reconfigure(efx);
phy_data->phy_mode = efx->phy_mode;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 7f8e514eb5e..7b1882765a0 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -687,6 +687,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
{
struct net_device *ndev = netdev;
struct sh_eth_private *mdp = netdev_priv(ndev);
+ irqreturn_t ret = IRQ_NONE;
u32 ioaddr, boguscnt = RX_RING_SIZE;
u32 intr_status = 0;
@@ -696,7 +697,13 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
/* Get interrpt stat */
intr_status = ctrl_inl(ioaddr + EESR);
/* Clear interrupt */
- ctrl_outl(intr_status, ioaddr + EESR);
+ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
+ EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
+ TX_CHECK | EESR_ERR_CHECK)) {
+ ctrl_outl(intr_status, ioaddr + EESR);
+ ret = IRQ_HANDLED;
+ } else
+ goto other_irq;
if (intr_status & (EESR_FRC | /* Frame recv*/
EESR_RMAF | /* Multi cast address recv*/
@@ -723,9 +730,10 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
ndev->name, intr_status);
}
+other_irq:
spin_unlock(&mdp->lock);
- return IRQ_HANDLED;
+ return ret;
}
static void sh_eth_timer(unsigned long data)
@@ -844,7 +852,13 @@ static int sh_eth_open(struct net_device *ndev)
int ret = 0;
struct sh_eth_private *mdp = netdev_priv(ndev);
- ret = request_irq(ndev->irq, &sh_eth_interrupt, 0, ndev->name, ndev);
+ ret = request_irq(ndev->irq, &sh_eth_interrupt,
+#if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764)
+ IRQF_SHARED,
+#else
+ 0,
+#endif
+ ndev->name, ndev);
if (ret) {
printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME);
return ret;
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 73bc7181cc1..1537e13e623 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -43,8 +43,8 @@
#define SH7763_SKB_ALIGN 32
/* Chip Base Address */
-# define SH_TSU_ADDR 0xFFE01800
-# define ARSTR 0xFFE01800
+# define SH_TSU_ADDR 0xFEE01800
+# define ARSTR SH_TSU_ADDR
/* Chip Registers */
/* E-DMAC */
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index be4465bc0a6..8a70de72ea2 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -80,8 +80,8 @@
#define SIS900_MODULE_NAME "sis900"
#define SIS900_DRV_VERSION "v1.08.10 Apr. 2 2006"
-static char version[] __devinitdata =
-KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
+static const char version[] __devinitconst =
+ KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
static int max_interrupt_work = 40;
static int multicast_filter_limit = 128;
diff --git a/drivers/net/skfp/h/smc.h b/drivers/net/skfp/h/smc.h
index 94325915e0d..1758d954836 100644
--- a/drivers/net/skfp/h/smc.h
+++ b/drivers/net/skfp/h/smc.h
@@ -467,5 +467,22 @@ struct s_smc {
#endif /* DEBUG_BRD && DEBUG */
} ;
+extern const struct fddi_addr fddi_broadcast;
+
+extern void all_selection_criteria(struct s_smc *smc);
+extern void card_stop(struct s_smc *smc);
+extern void init_board(struct s_smc *smc, u_char *mac_addr);
+extern int init_fplus(struct s_smc *smc);
+extern void init_plc(struct s_smc *smc);
+extern int init_smt(struct s_smc *smc, u_char * mac_addr);
+extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
+extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
+extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
+extern int pcm_status_twisted(struct s_smc *smc);
+extern void plc1_irq(struct s_smc *smc);
+extern void plc2_irq(struct s_smc *smc);
+extern void read_address(struct s_smc *smc, u_char * mac_addr);
+extern void timer_irq(struct s_smc *smc);
+
#endif /* _SCMECM_ */
diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c
index 4218e97033c..d322f1b702a 100644
--- a/drivers/net/skfp/hwmtm.c
+++ b/drivers/net/skfp/hwmtm.c
@@ -97,23 +97,15 @@ static void mac_drv_clear_txd(struct s_smc *smc);
extern void* mac_drv_get_space(struct s_smc *smc, unsigned int size);
extern void* mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size);
-extern void init_board(struct s_smc *smc, u_char *mac_addr);
extern void mac_drv_fill_rxd(struct s_smc *smc);
-extern void plc1_irq(struct s_smc *smc);
extern void mac_drv_tx_complete(struct s_smc *smc,
volatile struct s_smt_fp_txd *txd);
-extern void plc2_irq(struct s_smc *smc);
-extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
-extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
-extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
-extern void timer_irq(struct s_smc *smc);
extern void mac_drv_rx_complete(struct s_smc *smc,
volatile struct s_smt_fp_rxd *rxd,
int frag_count, int len);
extern void mac_drv_requeue_rxd(struct s_smc *smc,
volatile struct s_smt_fp_rxd *rxd,
int frag_count);
-extern void init_plc(struct s_smc *smc);
extern void mac_drv_clear_rxd(struct s_smc *smc,
volatile struct s_smt_fp_rxd *rxd, int frag_count);
@@ -136,7 +128,6 @@ extern void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr,
int flag);
#endif
-extern int init_fplus(struct s_smc *smc);
extern int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead,
int la_len);
diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c
index 74e129f3ce9..f1df2ec8ad4 100644
--- a/drivers/net/skfp/pcmplc.c
+++ b/drivers/net/skfp/pcmplc.c
@@ -198,9 +198,6 @@ static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
static const int plc_imsk_act = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR;
-/* external functions */
-void all_selection_criteria(struct s_smc *smc);
-
/* internal functions */
static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd);
static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy);
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 607efeaf0bc..e14aec0a733 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -135,14 +135,11 @@ void dump_data(unsigned char *Data, int length);
// External functions from the hardware module
extern u_int mac_drv_check_space(void);
-extern void read_address(struct s_smc *smc, u_char * mac_addr);
-extern void card_stop(struct s_smc *smc);
extern int mac_drv_init(struct s_smc *smc);
extern void hwm_tx_frag(struct s_smc *smc, char far * virt, u_long phys,
int len, int frame_status);
extern int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count,
int frame_len, int frame_status);
-extern int init_smt(struct s_smc *smc, u_char * mac_addr);
extern void fddi_isr(struct s_smc *smc);
extern void hwm_rx_frag(struct s_smc *smc, char far * virt, u_long phys,
int len, int frame_status);
@@ -1003,9 +1000,9 @@ static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
break;
case SKFP_CLR_STATS: /* Zero out the driver statistics */
if (!capable(CAP_NET_ADMIN)) {
- memset(&lp->MacStat, 0, sizeof(lp->MacStat));
- } else {
status = -EPERM;
+ } else {
+ memset(&lp->MacStat, 0, sizeof(lp->MacStat));
}
break;
default:
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index 805383b33d3..83d16fecfac 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -55,16 +55,6 @@ static const struct fddi_addr SMT_Unknown = {
} ;
/*
- * external variables
- */
-extern const struct fddi_addr fddi_broadcast ;
-
-/*
- * external functions
- */
-int pcm_status_twisted(struct s_smc *smc);
-
-/*
* function prototypes
*/
#ifdef LITTLE_ENDIAN
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index c9dbb06f8c9..952d37ffee5 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3214,7 +3214,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
unsigned long flags;
spin_lock_irqsave(&hw->hw_lock, flags);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
hw->intr_mask |= napimask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
skge_read32(hw, B0_IMSK);
@@ -3377,7 +3377,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
if (status & (IS_XA1_F|IS_R1_F)) {
struct skge_port *skge = netdev_priv(hw->dev[0]);
hw->intr_mask &= ~(IS_XA1_F|IS_R1_F);
- netif_rx_schedule(&skge->napi);
+ napi_schedule(&skge->napi);
}
if (status & IS_PA_TO_TX1)
@@ -3397,7 +3397,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
if (status & (IS_XA2_F|IS_R2_F)) {
hw->intr_mask &= ~(IS_XA2_F|IS_R2_F);
- netif_rx_schedule(&skge->napi);
+ napi_schedule(&skge->napi);
}
if (status & IS_PA_TO_RX2) {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 3668e81e474..d01c56eb962 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1068,13 +1068,16 @@ static void sky2_rx_submit(struct sky2_port *sky2,
}
-static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
+static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
unsigned size)
{
struct sk_buff *skb = re->skb;
int i;
re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(pdev, re->data_addr)))
+ return -EIO;
+
pci_unmap_len_set(re, data_size, size);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
@@ -1083,6 +1086,7 @@ static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
skb_shinfo(skb)->frags[i].page_offset,
skb_shinfo(skb)->frags[i].size,
PCI_DMA_FROMDEVICE);
+ return 0;
}
static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
@@ -1354,7 +1358,12 @@ static int sky2_rx_start(struct sky2_port *sky2)
if (!re->skb)
goto nomem;
- sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size);
+ if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) {
+ dev_kfree_skb(re->skb);
+ re->skb = NULL;
+ goto nomem;
+ }
+
sky2_rx_submit(sky2, re);
}
@@ -1403,9 +1412,6 @@ static int sky2_up(struct net_device *dev)
}
- if (netif_msg_ifup(sky2))
- printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
-
netif_carrier_off(dev);
/* must be power of 2 */
@@ -1484,6 +1490,9 @@ static int sky2_up(struct net_device *dev)
sky2_write32(hw, B0_IMSK, imask);
sky2_set_multicast(dev);
+
+ if (netif_msg_ifup(sky2))
+ printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
return 0;
err_out:
@@ -1547,7 +1556,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
struct sky2_hw *hw = sky2->hw;
struct sky2_tx_le *le = NULL;
struct tx_ring_info *re;
- unsigned i, len;
+ unsigned i, len, first_slot;
dma_addr_t mapping;
u16 mss;
u8 ctrl;
@@ -1555,13 +1564,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
return NETDEV_TX_BUSY;
- if (unlikely(netif_msg_tx_queued(sky2)))
- printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
- dev->name, sky2->tx_prod, skb->len);
-
len = skb_headlen(skb);
mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(hw->pdev, mapping))
+ goto mapping_error;
+
+ first_slot = sky2->tx_prod;
+ if (unlikely(netif_msg_tx_queued(sky2)))
+ printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
+ dev->name, first_slot, skb->len);
+
/* Send high bits if needed */
if (sizeof(dma_addr_t) > sizeof(u32)) {
le = get_tx_le(sky2);
@@ -1648,6 +1661,9 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
frag->size, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(hw->pdev, mapping))
+ goto mapping_unwind;
+
if (sizeof(dma_addr_t) > sizeof(u32)) {
le = get_tx_le(sky2);
le->addr = cpu_to_le32(upper_32_bits(mapping));
@@ -1676,6 +1692,34 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
return NETDEV_TX_OK;
+
+mapping_unwind:
+ for (i = first_slot; i != sky2->tx_prod; i = RING_NEXT(i, TX_RING_SIZE)) {
+ le = sky2->tx_le + i;
+ re = sky2->tx_ring + i;
+
+ switch(le->opcode & ~HW_OWNER) {
+ case OP_LARGESEND:
+ case OP_PACKET:
+ pci_unmap_single(hw->pdev,
+ pci_unmap_addr(re, mapaddr),
+ pci_unmap_len(re, maplen),
+ PCI_DMA_TODEVICE);
+ break;
+ case OP_BUFFER:
+ pci_unmap_page(hw->pdev, pci_unmap_addr(re, mapaddr),
+ pci_unmap_len(re, maplen),
+ PCI_DMA_TODEVICE);
+ break;
+ }
+ }
+
+ sky2->tx_prod = first_slot;
+mapping_error:
+ if (net_ratelimit())
+ dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
}
/*
@@ -2191,7 +2235,11 @@ static struct sk_buff *receive_new(struct sky2_port *sky2,
prefetch(skb->data);
re->skb = nskb;
- sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space);
+ if (sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space)) {
+ dev_kfree_skb(nskb);
+ re->skb = skb;
+ return NULL;
+ }
if (skb_shinfo(skb)->nr_frags)
skb_put_frags(skb, hdr_space, length);
@@ -2687,13 +2735,6 @@ static int sky2_poll(struct napi_struct *napi, int work_limit)
goto done;
}
- /* Bug/Errata workaround?
- * Need to kick the TX irq moderation timer.
- */
- if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
- sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
- sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
- }
napi_complete(napi);
sky2_read32(hw, B0_Y2_SP_LISR);
done:
@@ -3864,6 +3905,86 @@ static const struct ethtool_ops sky2_ethtool_ops = {
static struct dentry *sky2_debug;
+
+/*
+ * Read and parse the first part of Vital Product Data
+ */
+#define VPD_SIZE 128
+#define VPD_MAGIC 0x82
+
+static const struct vpd_tag {
+ char tag[2];
+ char *label;
+} vpd_tags[] = {
+ { "PN", "Part Number" },
+ { "EC", "Engineering Level" },
+ { "MN", "Manufacturer" },
+ { "SN", "Serial Number" },
+ { "YA", "Asset Tag" },
+ { "VL", "First Error Log Message" },
+ { "VF", "Second Error Log Message" },
+ { "VB", "Boot Agent ROM Configuration" },
+ { "VE", "EFI UNDI Configuration" },
+};
+
+static void sky2_show_vpd(struct seq_file *seq, struct sky2_hw *hw)
+{
+ size_t vpd_size;
+ loff_t offs;
+ u8 len;
+ unsigned char *buf;
+ u16 reg2;
+
+ reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
+ vpd_size = 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+
+ seq_printf(seq, "%s Product Data\n", pci_name(hw->pdev));
+ buf = kmalloc(vpd_size, GFP_KERNEL);
+ if (!buf) {
+ seq_puts(seq, "no memory!\n");
+ return;
+ }
+
+ if (pci_read_vpd(hw->pdev, 0, vpd_size, buf) < 0) {
+ seq_puts(seq, "VPD read failed\n");
+ goto out;
+ }
+
+ if (buf[0] != VPD_MAGIC) {
+ seq_printf(seq, "VPD tag mismatch: %#x\n", buf[0]);
+ goto out;
+ }
+ len = buf[1];
+ if (len == 0 || len > vpd_size - 4) {
+ seq_printf(seq, "Invalid id length: %d\n", len);
+ goto out;
+ }
+
+ seq_printf(seq, "%.*s\n", len, buf + 3);
+ offs = len + 3;
+
+ while (offs < vpd_size - 4) {
+ int i;
+
+ if (!memcmp("RW", buf + offs, 2)) /* end marker */
+ break;
+ len = buf[offs + 2];
+ if (offs + len + 3 >= vpd_size)
+ break;
+
+ for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
+ if (!memcmp(vpd_tags[i].tag, buf + offs, 2)) {
+ seq_printf(seq, " %s: %.*s\n",
+ vpd_tags[i].label, len, buf + offs + 3);
+ break;
+ }
+ }
+ offs += len + 3;
+ }
+out:
+ kfree(buf);
+}
+
static int sky2_debug_show(struct seq_file *seq, void *v)
{
struct net_device *dev = seq->private;
@@ -3873,14 +3994,18 @@ static int sky2_debug_show(struct seq_file *seq, void *v)
unsigned idx, last;
int sop;
- if (!netif_running(dev))
- return -ENETDOWN;
+ sky2_show_vpd(seq, hw);
- seq_printf(seq, "IRQ src=%x mask=%x control=%x\n",
+ seq_printf(seq, "\nIRQ src=%x mask=%x control=%x\n",
sky2_read32(hw, B0_ISRC),
sky2_read32(hw, B0_IMSK),
sky2_read32(hw, B0_Y2_SP_ICR));
+ if (!netif_running(dev)) {
+ seq_printf(seq, "network not running\n");
+ return 0;
+ }
+
napi_disable(&hw->napi);
last = sky2_read16(hw, STAT_PUT_IDX);
@@ -4204,69 +4329,6 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
return err;
}
-/*
- * Read and parse the first part of Vital Product Data
- */
-#define VPD_SIZE 128
-#define VPD_MAGIC 0x82
-
-static void __devinit sky2_vpd_info(struct sky2_hw *hw)
-{
- int cap = pci_find_capability(hw->pdev, PCI_CAP_ID_VPD);
- const u8 *p;
- u8 *vpd_buf = NULL;
- u16 len;
- static struct vpd_tag {
- char tag[2];
- char *label;
- } vpd_tags[] = {
- { "PN", "Part Number" },
- { "EC", "Engineering Level" },
- { "MN", "Manufacturer" },
- };
-
- if (!cap)
- goto out;
-
- vpd_buf = kmalloc(VPD_SIZE, GFP_KERNEL);
- if (!vpd_buf)
- goto out;
-
- if (sky2_vpd_read(hw, cap, vpd_buf, 0, VPD_SIZE))
- goto out;
-
- if (vpd_buf[0] != VPD_MAGIC)
- goto out;
- len = vpd_buf[1];
- if (len == 0 || len > VPD_SIZE - 4)
- goto out;
- p = vpd_buf + 3;
- dev_info(&hw->pdev->dev, "%.*s\n", len, p);
- p += len;
-
- while (p < vpd_buf + VPD_SIZE - 4) {
- int i;
-
- if (!memcmp("RW", p, 2)) /* end marker */
- break;
-
- len = p[2];
- if (len > (p - vpd_buf) - 4)
- break;
-
- for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
- if (!memcmp(vpd_tags[i].tag, p, 2)) {
- printk(KERN_DEBUG " %s: %.*s\n",
- vpd_tags[i].label, len, p + 3);
- break;
- }
- }
- p += len + 3;
- }
-out:
- kfree(vpd_buf);
-}
-
/* This driver supports yukon2 chipset only */
static const char *sky2_name(u8 chipid, char *buf, int sz)
{
@@ -4294,6 +4356,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
struct net_device *dev;
struct sky2_hw *hw;
int err, using_dac = 0, wol_default;
+ u32 reg;
char buf1[16];
err = pci_enable_device(pdev);
@@ -4327,6 +4390,34 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
}
}
+ /* Get configuration information
+ * Note: only regular PCI config access once to test for HW issues
+ * other PCI access through shared memory for speed and to
+ * avoid MMCONFIG problems.
+ */
+ err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+ if (err) {
+ dev_err(&pdev->dev, "PCI read config failed\n");
+ goto err_out_free_regions;
+ }
+
+ /* size of available VPD, only impact sysfs */
+ err = pci_vpd_truncate(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8));
+ if (err)
+ dev_warn(&pdev->dev, "Can't set VPD size\n");
+
+#ifdef __BIG_ENDIAN
+ /* The sk98lin vendor driver uses hardware byte swapping but
+ * this driver uses software swapping.
+ */
+ reg &= ~PCI_REV_DESC;
+ err = pci_write_config_dword(pdev,PCI_DEV_REG2, reg);
+ if (err) {
+ dev_err(&pdev->dev, "PCI write config failed\n");
+ goto err_out_free_regions;
+ }
+#endif
+
wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
err = -ENOMEM;
@@ -4344,18 +4435,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out_free_hw;
}
-#ifdef __BIG_ENDIAN
- /* The sk98lin vendor driver uses hardware byte swapping but
- * this driver uses software swapping.
- */
- {
- u32 reg;
- reg = sky2_pci_read32(hw, PCI_DEV_REG2);
- reg &= ~PCI_REV_DESC;
- sky2_pci_write32(hw, PCI_DEV_REG2, reg);
- }
-#endif
-
/* ring for status responses */
hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma);
if (!hw->st_le)
@@ -4370,8 +4449,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
sky2_reset(hw);
- sky2_vpd_info(hw);
-
dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
if (!dev) {
err = -ENOMEM;
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index bf3aa2a1eff..293610334a7 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -220,9 +220,9 @@ static void smc911x_reset(struct net_device *dev)
/* make sure EEPROM has finished loading before setting GPIO_CFG */
timeout=1000;
- while ( timeout-- && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) {
+ while (--timeout && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_))
udelay(10);
- }
+
if (timeout == 0){
PRINTK("%s: smc911x_reset timeout waiting for EEPROM busy\n", dev->name);
return;
@@ -1545,7 +1545,7 @@ smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strncpy(info->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version));
- strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+ strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}
static int smc911x_ethtool_nwayreset(struct net_device *dev)
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 870b4c33f10..a45952e7201 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -42,6 +42,16 @@
#define SMC_USE_16BIT 0
#define SMC_USE_32BIT 1
#define SMC_IRQ_SENSE IRQF_TRIGGER_LOW
+#elif defined(CONFIG_ARCH_OMAP34XX)
+ #define SMC_USE_16BIT 0
+ #define SMC_USE_32BIT 1
+ #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW
+ #define SMC_MEM_RESERVED 1
+#elif defined(CONFIG_ARCH_OMAP24XX)
+ #define SMC_USE_16BIT 0
+ #define SMC_USE_32BIT 1
+ #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW
+ #define SMC_MEM_RESERVED 1
#else
/*
* Default configuration
@@ -675,6 +685,7 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
#define CHIP_9116 0x0116
#define CHIP_9117 0x0117
#define CHIP_9118 0x0118
+#define CHIP_9211 0x9211
#define CHIP_9215 0x115A
#define CHIP_9217 0x117A
#define CHIP_9218 0x118A
@@ -689,6 +700,7 @@ static const struct chip_id chip_ids[] = {
{ CHIP_9116, "LAN9116" },
{ CHIP_9117, "LAN9117" },
{ CHIP_9118, "LAN9118" },
+ { CHIP_9211, "LAN9211" },
{ CHIP_9215, "LAN9215" },
{ CHIP_9217, "LAN9217" },
{ CHIP_9218, "LAN9218" },
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index b215a8d85e6..fdcbaf8dfa7 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1614,7 +1614,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strncpy(info->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version));
- strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+ strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}
static int smc_ethtool_nwayreset(struct net_device *dev)
@@ -1643,6 +1643,117 @@ static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level)
lp->msg_enable = level;
}
+static int smc_write_eeprom_word(struct net_device *dev, u16 addr, u16 word)
+{
+ u16 ctl;
+ struct smc_local *lp = netdev_priv(dev);
+ void __iomem *ioaddr = lp->base;
+
+ spin_lock_irq(&lp->lock);
+ /* load word into GP register */
+ SMC_SELECT_BANK(lp, 1);
+ SMC_SET_GP(lp, word);
+ /* set the address to put the data in EEPROM */
+ SMC_SELECT_BANK(lp, 2);
+ SMC_SET_PTR(lp, addr);
+ /* tell it to write */
+ SMC_SELECT_BANK(lp, 1);
+ ctl = SMC_GET_CTL(lp);
+ SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_STORE));
+ /* wait for it to finish */
+ do {
+ udelay(1);
+ } while (SMC_GET_CTL(lp) & CTL_STORE);
+ /* clean up */
+ SMC_SET_CTL(lp, ctl);
+ SMC_SELECT_BANK(lp, 2);
+ spin_unlock_irq(&lp->lock);
+ return 0;
+}
+
+static int smc_read_eeprom_word(struct net_device *dev, u16 addr, u16 *word)
+{
+ u16 ctl;
+ struct smc_local *lp = netdev_priv(dev);
+ void __iomem *ioaddr = lp->base;
+
+ spin_lock_irq(&lp->lock);
+ /* set the EEPROM address to get the data from */
+ SMC_SELECT_BANK(lp, 2);
+ SMC_SET_PTR(lp, addr | PTR_READ);
+ /* tell it to load */
+ SMC_SELECT_BANK(lp, 1);
+ SMC_SET_GP(lp, 0xffff); /* init to known */
+ ctl = SMC_GET_CTL(lp);
+ SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_RELOAD));
+ /* wait for it to finish */
+ do {
+ udelay(1);
+ } while (SMC_GET_CTL(lp) & CTL_RELOAD);
+ /* read word from GP register */
+ *word = SMC_GET_GP(lp);
+ /* clean up */
+ SMC_SET_CTL(lp, ctl);
+ SMC_SELECT_BANK(lp, 2);
+ spin_unlock_irq(&lp->lock);
+ return 0;
+}
+
+static int smc_ethtool_geteeprom_len(struct net_device *dev)
+{
+ return 0x23 * 2;
+}
+
+static int smc_ethtool_geteeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int i;
+ int imax;
+
+ DBG(1, "Reading %d bytes at %d(0x%x)\n",
+ eeprom->len, eeprom->offset, eeprom->offset);
+ imax = smc_ethtool_geteeprom_len(dev);
+ for (i = 0; i < eeprom->len; i += 2) {
+ int ret;
+ u16 wbuf;
+ int offset = i + eeprom->offset;
+ if (offset > imax)
+ break;
+ ret = smc_read_eeprom_word(dev, offset >> 1, &wbuf);
+ if (ret != 0)
+ return ret;
+ DBG(2, "Read 0x%x from 0x%x\n", wbuf, offset >> 1);
+ data[i] = (wbuf >> 8) & 0xff;
+ data[i+1] = wbuf & 0xff;
+ }
+ return 0;
+}
+
+static int smc_ethtool_seteeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int i;
+ int imax;
+
+ DBG(1, "Writing %d bytes to %d(0x%x)\n",
+ eeprom->len, eeprom->offset, eeprom->offset);
+ imax = smc_ethtool_geteeprom_len(dev);
+ for (i = 0; i < eeprom->len; i += 2) {
+ int ret;
+ u16 wbuf;
+ int offset = i + eeprom->offset;
+ if (offset > imax)
+ break;
+ wbuf = (data[i] << 8) | data[i + 1];
+ DBG(2, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1);
+ ret = smc_write_eeprom_word(dev, offset >> 1, wbuf);
+ if (ret != 0)
+ return ret;
+ }
+ return 0;
+}
+
+
static const struct ethtool_ops smc_ethtool_ops = {
.get_settings = smc_ethtool_getsettings,
.set_settings = smc_ethtool_setsettings,
@@ -1652,8 +1763,22 @@ static const struct ethtool_ops smc_ethtool_ops = {
.set_msglevel = smc_ethtool_setmsglevel,
.nway_reset = smc_ethtool_nwayreset,
.get_link = ethtool_op_get_link,
-// .get_eeprom = smc_ethtool_geteeprom,
-// .set_eeprom = smc_ethtool_seteeprom,
+ .get_eeprom_len = smc_ethtool_geteeprom_len,
+ .get_eeprom = smc_ethtool_geteeprom,
+ .set_eeprom = smc_ethtool_seteeprom,
+};
+
+static const struct net_device_ops smc_netdev_ops = {
+ .ndo_open = smc_open,
+ .ndo_stop = smc_close,
+ .ndo_start_xmit = smc_hard_start_xmit,
+ .ndo_tx_timeout = smc_timeout,
+ .ndo_set_multicast_list = smc_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = smc_poll_controller,
+#endif
};
/*
@@ -1865,16 +1990,9 @@ static int __devinit smc_probe(struct net_device *dev, void __iomem *ioaddr,
/* Fill in the fields of the device structure with ethernet values. */
ether_setup(dev);
- dev->open = smc_open;
- dev->stop = smc_close;
- dev->hard_start_xmit = smc_hard_start_xmit;
- dev->tx_timeout = smc_timeout;
dev->watchdog_timeo = msecs_to_jiffies(watchdog);
- dev->set_multicast_list = smc_set_multicast_list;
+ dev->netdev_ops = &smc_netdev_ops;
dev->ethtool_ops = &smc_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = smc_poll_controller;
-#endif
tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
INIT_WORK(&lp->phy_configure, smc_phy_configure);
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index c4ccd121bc9..ed9ae43523a 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -1141,6 +1141,16 @@ static const char * chip_ids[ 16 ] = {
#define SMC_GET_MII(lp) SMC_inw(ioaddr, MII_REG(lp))
+#define SMC_GET_GP(lp) SMC_inw(ioaddr, GP_REG(lp))
+
+#define SMC_SET_GP(lp, x) \
+ do { \
+ if (SMC_MUST_ALIGN_WRITE(lp)) \
+ SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 1)); \
+ else \
+ SMC_outw(x, ioaddr, GP_REG(lp)); \
+ } while (0)
+
#define SMC_SET_MII(lp, x) SMC_outw(x, ioaddr, MII_REG(lp))
#define SMC_GET_MIR(lp) SMC_inw(ioaddr, MIR_REG(lp))
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index f513bdf1c88..ad3cbc91a8f 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -368,48 +368,53 @@ out:
return reg;
}
-/* Autodetects and initialises external phy for SMSC9115 and SMSC9117 flavors.
- * If something goes wrong, returns -ENODEV to revert back to internal phy.
- * Performed at initialisation only, so interrupts are enabled */
-static int smsc911x_phy_initialise_external(struct smsc911x_data *pdata)
+/* Switch to external phy. Assumes tx and rx are stopped. */
+static void smsc911x_phy_enable_external(struct smsc911x_data *pdata)
{
unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
- /* External phy is requested, supported, and detected */
- if (hwcfg & HW_CFG_EXT_PHY_DET_) {
+ /* Disable phy clocks to the MAC */
+ hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
+ hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
+ smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+ udelay(10); /* Enough time for clocks to stop */
- /* Switch to external phy. Assuming tx and rx are stopped
- * because smsc911x_phy_initialise is called before
- * smsc911x_rx_initialise and tx_initialise. */
+ /* Switch to external phy */
+ hwcfg |= HW_CFG_EXT_PHY_EN_;
+ smsc911x_reg_write(pdata, HW_CFG, hwcfg);
- /* Disable phy clocks to the MAC */
- hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
- hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
- smsc911x_reg_write(pdata, HW_CFG, hwcfg);
- udelay(10); /* Enough time for clocks to stop */
+ /* Enable phy clocks to the MAC */
+ hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
+ hwcfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
+ smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+ udelay(10); /* Enough time for clocks to restart */
- /* Switch to external phy */
- hwcfg |= HW_CFG_EXT_PHY_EN_;
- smsc911x_reg_write(pdata, HW_CFG, hwcfg);
-
- /* Enable phy clocks to the MAC */
- hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
- hwcfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
- smsc911x_reg_write(pdata, HW_CFG, hwcfg);
- udelay(10); /* Enough time for clocks to restart */
+ hwcfg |= HW_CFG_SMI_SEL_;
+ smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+}
- hwcfg |= HW_CFG_SMI_SEL_;
- smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+/* Autodetects and enables external phy if present on supported chips.
+ * autodetection can be overridden by specifying SMSC911X_FORCE_INTERNAL_PHY
+ * or SMSC911X_FORCE_EXTERNAL_PHY in the platform_data flags. */
+static void smsc911x_phy_initialise_external(struct smsc911x_data *pdata)
+{
+ unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
- SMSC_TRACE(HW, "Successfully switched to external PHY");
+ if (pdata->config.flags & SMSC911X_FORCE_INTERNAL_PHY) {
+ SMSC_TRACE(HW, "Forcing internal PHY");
+ pdata->using_extphy = 0;
+ } else if (pdata->config.flags & SMSC911X_FORCE_EXTERNAL_PHY) {
+ SMSC_TRACE(HW, "Forcing external PHY");
+ smsc911x_phy_enable_external(pdata);
+ pdata->using_extphy = 1;
+ } else if (hwcfg & HW_CFG_EXT_PHY_DET_) {
+ SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET set, using external PHY");
+ smsc911x_phy_enable_external(pdata);
pdata->using_extphy = 1;
} else {
- SMSC_WARNING(HW, "No external PHY detected, "
- "Using internal PHY instead.");
- /* Use internal phy */
- return -ENODEV;
+ SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET clear, using internal PHY");
+ pdata->using_extphy = 0;
}
- return 0;
}
/* Fetches a tx status out of the status fifo */
@@ -769,7 +774,7 @@ static int smsc911x_mii_probe(struct net_device *dev)
return -ENODEV;
}
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&smsc911x_phy_adjust_link, 0, pdata->config.phy_interface);
if (IS_ERR(phydev)) {
@@ -778,7 +783,8 @@ static int smsc911x_mii_probe(struct net_device *dev)
}
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ dev->name, phydev->drv->name,
+ dev_name(&phydev->dev), phydev->irq);
/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -824,22 +830,18 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
pdata->mii_bus->parent = &pdev->dev;
- pdata->using_extphy = 0;
-
switch (pdata->idrev & 0xFFFF0000) {
case 0x01170000:
case 0x01150000:
case 0x117A0000:
case 0x115A0000:
/* External PHY supported, try to autodetect */
- if (smsc911x_phy_initialise_external(pdata) < 0) {
- SMSC_TRACE(HW, "No external PHY detected, "
- "using internal PHY");
- }
+ smsc911x_phy_initialise_external(pdata);
break;
default:
SMSC_TRACE(HW, "External PHY is not supported, "
"using internal PHY");
+ pdata->using_extphy = 0;
break;
}
@@ -893,22 +895,22 @@ static void smsc911x_tx_update_txcounters(struct net_device *dev)
SMSC_WARNING(HW,
"Packet tag reserved bit is high");
} else {
- if (unlikely(tx_stat & 0x00008000)) {
+ if (unlikely(tx_stat & TX_STS_ES_)) {
dev->stats.tx_errors++;
} else {
dev->stats.tx_packets++;
dev->stats.tx_bytes += (tx_stat >> 16);
}
- if (unlikely(tx_stat & 0x00000100)) {
+ if (unlikely(tx_stat & TX_STS_EXCESS_COL_)) {
dev->stats.collisions += 16;
dev->stats.tx_aborted_errors += 1;
} else {
dev->stats.collisions +=
((tx_stat >> 3) & 0xF);
}
- if (unlikely(tx_stat & 0x00000800))
+ if (unlikely(tx_stat & TX_STS_LOST_CARRIER_))
dev->stats.tx_carrier_errors += 1;
- if (unlikely(tx_stat & 0x00000200)) {
+ if (unlikely(tx_stat & TX_STS_LATE_COL_)) {
dev->stats.collisions++;
dev->stats.tx_aborted_errors++;
}
@@ -922,19 +924,17 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)
{
int crc_err = 0;
- if (unlikely(rxstat & 0x00008000)) {
+ if (unlikely(rxstat & RX_STS_ES_)) {
dev->stats.rx_errors++;
- if (unlikely(rxstat & 0x00000002)) {
+ if (unlikely(rxstat & RX_STS_CRC_ERR_)) {
dev->stats.rx_crc_errors++;
crc_err = 1;
}
}
if (likely(!crc_err)) {
- if (unlikely((rxstat & 0x00001020) == 0x00001020)) {
- /* Frame type indicates length,
- * and length error is set */
+ if (unlikely((rxstat & RX_STS_FRAME_TYPE_) &&
+ (rxstat & RX_STS_LENGTH_ERR_)))
dev->stats.rx_length_errors++;
- }
if (rxstat & RX_STS_MCAST_)
dev->stats.multicast++;
}
@@ -953,7 +953,7 @@ smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
do {
udelay(1);
val = smsc911x_reg_read(pdata, RX_DP_CTRL);
- } while (timeout-- && (val & RX_DP_CTRL_RX_FFWD_));
+ } while ((val & RX_DP_CTRL_RX_FFWD_) && --timeout);
if (unlikely(timeout == 0))
SMSC_WARNING(HW, "Timed out waiting for "
@@ -984,7 +984,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
/* We processed all packets available. Tell NAPI it can
* stop polling then re-enable rx interrupts */
smsc911x_reg_write(pdata, INT_STS, INT_STS_RSFL_);
- netif_rx_complete(napi);
+ napi_complete(napi);
temp = smsc911x_reg_read(pdata, INT_EN);
temp |= INT_EN_RSFL_EN_;
smsc911x_reg_write(pdata, INT_EN, temp);
@@ -1119,7 +1119,7 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata)
/* Sets the device MAC address to dev_addr, called with mac_lock held */
static void
-smsc911x_set_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
+smsc911x_set_hw_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
{
u32 mac_high16 = (dev_addr[5] << 8) | dev_addr[4];
u32 mac_low32 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
@@ -1160,8 +1160,8 @@ static int smsc911x_open(struct net_device *dev)
/* Make sure EEPROM has finished loading before setting GPIO_CFG */
timeout = 50;
- while ((timeout--) &&
- (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
+ while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) &&
+ --timeout) {
udelay(10);
}
@@ -1174,7 +1174,7 @@ static int smsc911x_open(struct net_device *dev)
/* The soft reset above cleared the device's MAC address,
* restore it from local copy (set in probe) */
spin_lock_irq(&pdata->mac_lock);
- smsc911x_set_mac_address(pdata, dev->dev_addr);
+ smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
spin_unlock_irq(&pdata->mac_lock);
/* Initialise irqs, but leave all sources disabled */
@@ -1225,6 +1225,10 @@ static int smsc911x_open(struct net_device *dev)
dev_info(&dev->dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n",
(unsigned long)pdata->ioaddr, dev->irq);
+ /* Reset the last known duplex and carrier */
+ pdata->last_duplex = -1;
+ pdata->last_carrier = -1;
+
/* Bring the PHY up */
phy_start(pdata->phy_dev);
@@ -1246,7 +1250,7 @@ static int smsc911x_open(struct net_device *dev)
napi_enable(&pdata->napi);
temp = smsc911x_reg_read(pdata, INT_EN);
- temp |= (INT_EN_TDFA_EN_ | INT_EN_RSFL_EN_);
+ temp |= (INT_EN_TDFA_EN_ | INT_EN_RSFL_EN_ | INT_EN_RXSTOP_INT_EN_);
smsc911x_reg_write(pdata, INT_EN, temp);
spin_lock_irq(&pdata->mac_lock);
@@ -1418,11 +1422,6 @@ static void smsc911x_set_multicast_list(struct net_device *dev)
/* Request the hardware to stop, then perform the
* update when we get an RX_STOP interrupt */
- smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
- temp = smsc911x_reg_read(pdata, INT_EN);
- temp |= INT_EN_RXSTOP_INT_EN_;
- smsc911x_reg_write(pdata, INT_EN, temp);
-
temp = smsc911x_mac_read(pdata, MAC_CR);
temp &= ~(MAC_CR_RXEN_);
smsc911x_mac_write(pdata, MAC_CR, temp);
@@ -1461,11 +1460,9 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id)
/* Called when there is a multicast update scheduled and
* it is now safe to complete the update */
SMSC_TRACE(INTR, "RX Stop interrupt");
- temp = smsc911x_reg_read(pdata, INT_EN);
- temp &= (~INT_EN_RXSTOP_INT_EN_);
- smsc911x_reg_write(pdata, INT_EN, temp);
smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
- smsc911x_rx_multicast_update_workaround(pdata);
+ if (pdata->multicast_update_pending)
+ smsc911x_rx_multicast_update_workaround(pdata);
serviced = IRQ_HANDLED;
}
@@ -1485,16 +1482,16 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id)
}
if (likely(intsts & inten & INT_STS_RSFL_)) {
- if (likely(netif_rx_schedule_prep(&pdata->napi))) {
+ if (likely(napi_schedule_prep(&pdata->napi))) {
/* Disable Rx interrupts */
temp = smsc911x_reg_read(pdata, INT_EN);
temp &= (~INT_EN_RSFL_EN_);
smsc911x_reg_write(pdata, INT_EN, temp);
/* Schedule a NAPI poll */
- __netif_rx_schedule(&pdata->napi);
+ __napi_schedule(&pdata->napi);
} else {
SMSC_WARNING(RX_ERR,
- "netif_rx_schedule_prep failed");
+ "napi_schedule_prep failed");
}
serviced = IRQ_HANDLED;
}
@@ -1511,6 +1508,31 @@ static void smsc911x_poll_controller(struct net_device *dev)
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
+static int smsc911x_set_mac_address(struct net_device *dev, void *p)
+{
+ struct smsc911x_data *pdata = netdev_priv(dev);
+ struct sockaddr *addr = p;
+
+ /* On older hardware revisions we cannot change the mac address
+ * registers while receiving data. Newer devices can safely change
+ * this at any time. */
+ if (pdata->generation <= 1 && netif_running(dev))
+ return -EBUSY;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+ spin_lock_irq(&pdata->mac_lock);
+ smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
+ spin_unlock_irq(&pdata->mac_lock);
+
+ dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
+
+ return 0;
+}
+
/* Standard ioctls for mii-tool */
static int smsc911x_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
@@ -1545,7 +1567,7 @@ static void smsc911x_ethtool_getdrvinfo(struct net_device *dev,
{
strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver));
strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, dev->dev.parent->bus_id,
+ strlcpy(info->bus_info, dev_name(dev->dev.parent),
sizeof(info->bus_info));
}
@@ -1624,7 +1646,7 @@ static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op)
do {
msleep(1);
e2cmd = smsc911x_reg_read(pdata, E2P_CMD);
- } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--));
+ } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout));
if (!timeout) {
SMSC_TRACE(DRV, "TIMED OUT");
@@ -1741,12 +1763,27 @@ static const struct net_device_ops smsc911x_netdev_ops = {
.ndo_set_multicast_list = smsc911x_set_multicast_list,
.ndo_do_ioctl = smsc911x_do_ioctl,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = smsc911x_set_mac_address,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = smsc911x_poll_controller,
#endif
};
+/* copies the current mac address from hardware to dev->dev_addr */
+static void __devinit smsc911x_read_mac_address(struct net_device *dev)
+{
+ struct smsc911x_data *pdata = netdev_priv(dev);
+ u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
+ u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
+
+ dev->dev_addr[0] = (u8)(mac_low32);
+ dev->dev_addr[1] = (u8)(mac_low32 >> 8);
+ dev->dev_addr[2] = (u8)(mac_low32 >> 16);
+ dev->dev_addr[3] = (u8)(mac_low32 >> 24);
+ dev->dev_addr[4] = (u8)(mac_high16);
+ dev->dev_addr[5] = (u8)(mac_high16 >> 8);
+}
+
/* Initializing private device structures, only called from probe */
static int __devinit smsc911x_init(struct net_device *dev)
{
@@ -1834,6 +1871,12 @@ static int __devinit smsc911x_init(struct net_device *dev)
SMSC_WARNING(PROBE,
"This driver is not intended for this chip revision");
+ /* workaround for platforms without an eeprom, where the mac address
+ * is stored elsewhere and set by the bootloader. This saves the
+ * mac address before resetting the device */
+ if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS)
+ smsc911x_read_mac_address(dev);
+
/* Reset the LAN911x */
if (smsc911x_soft_reset(pdata))
return -ENODEV;
@@ -1892,11 +1935,10 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
struct net_device *dev;
struct smsc911x_data *pdata;
struct smsc911x_platform_config *config = pdev->dev.platform_data;
- struct resource *res;
+ struct resource *res, *irq_res;
unsigned int intcfg = 0;
- int res_size;
+ int res_size, irq_flags;
int retval;
- DECLARE_MAC_BUF(mac);
pr_info("%s: Driver version %s.\n", SMSC_CHIPNAME, SMSC_DRV_VERSION);
@@ -1919,6 +1961,14 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
}
res_size = res->end - res->start;
+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq_res) {
+ pr_warning("%s: Could not allocate irq resource.\n",
+ SMSC_CHIPNAME);
+ retval = -ENODEV;
+ goto out_0;
+ }
+
if (!request_mem_region(res->start, res_size, SMSC_CHIPNAME)) {
retval = -EBUSY;
goto out_0;
@@ -1935,7 +1985,8 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
pdata = netdev_priv(dev);
- dev->irq = platform_get_irq(pdev, 0);
+ dev->irq = irq_res->start;
+ irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
pdata->ioaddr = ioremap_nocache(res->start, res_size);
/* copy config parameters across to pdata */
@@ -1968,8 +2019,8 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
smsc911x_reg_write(pdata, INT_EN, 0);
smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
- retval = request_irq(dev->irq, smsc911x_irqhandler, IRQF_DISABLED,
- dev->name, dev);
+ retval = request_irq(dev->irq, smsc911x_irqhandler,
+ irq_flags | IRQF_SHARED, dev->name, dev);
if (retval) {
SMSC_WARNING(PROBE,
"Unable to claim requested irq: %d", dev->irq);
@@ -2000,19 +2051,12 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
/* Check if mac address has been specified when bringing interface up */
if (is_valid_ether_addr(dev->dev_addr)) {
- smsc911x_set_mac_address(pdata, dev->dev_addr);
+ smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
SMSC_TRACE(PROBE, "MAC Address is specified by configuration");
} else {
/* Try reading mac address from device. if EEPROM is present
* it will already have been set */
- u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
- u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
- dev->dev_addr[0] = (u8)(mac_low32);
- dev->dev_addr[1] = (u8)(mac_low32 >> 8);
- dev->dev_addr[2] = (u8)(mac_low32 >> 16);
- dev->dev_addr[3] = (u8)(mac_low32 >> 24);
- dev->dev_addr[4] = (u8)(mac_high16);
- dev->dev_addr[5] = (u8)(mac_high16 >> 8);
+ smsc911x_read_mac_address(dev);
if (is_valid_ether_addr(dev->dev_addr)) {
/* eeprom values are valid so use them */
@@ -2021,7 +2065,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
} else {
/* eeprom values are invalid, generate random MAC */
random_ether_addr(dev->dev_addr);
- smsc911x_set_mac_address(pdata, dev->dev_addr);
+ smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
SMSC_TRACE(PROBE,
"MAC Address is set to random_ether_addr");
}
@@ -2029,8 +2073,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
spin_unlock_irq(&pdata->mac_lock);
- dev_info(&dev->dev, "MAC Address: %s\n",
- print_mac(mac, dev->dev_addr));
+ dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
return 0;
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h
index 2b76654bb95..b5716bd8a59 100644
--- a/drivers/net/smsc911x.h
+++ b/drivers/net/smsc911x.h
@@ -81,12 +81,19 @@
#define RX_STATUS_FIFO 0x40
#define RX_STS_ES_ 0x00008000
+#define RX_STS_LENGTH_ERR_ 0x00001000
#define RX_STS_MCAST_ 0x00000400
+#define RX_STS_FRAME_TYPE_ 0x00000020
+#define RX_STS_CRC_ERR_ 0x00000002
#define RX_STATUS_FIFO_PEEK 0x44
#define TX_STATUS_FIFO 0x48
#define TX_STS_ES_ 0x00008000
+#define TX_STS_LOST_CARRIER_ 0x00000800
+#define TX_STS_NO_CARRIER_ 0x00000400
+#define TX_STS_LATE_COL_ 0x00000200
+#define TX_STS_EXCESS_COL_ 0x00000100
#define TX_STATUS_FIFO_PEEK 0x4C
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index c14a4c6452c..5959ae86e57 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -341,7 +341,7 @@ static int smsc9420_eeprom_send_cmd(struct smsc9420_pdata *pd, u32 op)
do {
msleep(1);
e2cmd = smsc9420_reg_read(pd, E2P_CMD);
- } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--));
+ } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout));
if (!timeout) {
smsc_info(HW, "TIMED OUT");
@@ -413,6 +413,7 @@ static int smsc9420_ethtool_get_eeprom(struct net_device *dev,
}
memcpy(data, &eeprom_data[eeprom->offset], len);
+ eeprom->magic = SMSC9420_EEPROM_MAGIC;
eeprom->len = len;
return 0;
}
@@ -423,6 +424,9 @@ static int smsc9420_ethtool_set_eeprom(struct net_device *dev,
struct smsc9420_pdata *pd = netdev_priv(dev);
int ret;
+ if (eeprom->magic != SMSC9420_EEPROM_MAGIC)
+ return -EINVAL;
+
smsc9420_eeprom_enable_access(pd);
smsc9420_eeprom_send_cmd(pd, E2P_CMD_EPC_CMD_EWEN_);
ret = smsc9420_eeprom_write_location(pd, eeprom->offset, *data);
@@ -498,7 +502,7 @@ static void smsc9420_check_mac_address(struct net_device *dev)
static void smsc9420_stop_tx(struct smsc9420_pdata *pd)
{
u32 dmac_control, mac_cr, dma_intr_ena;
- int timeOut = 1000;
+ int timeout = 1000;
/* disable TX DMAC */
dmac_control = smsc9420_reg_read(pd, DMAC_CONTROL);
@@ -506,13 +510,13 @@ static void smsc9420_stop_tx(struct smsc9420_pdata *pd)
smsc9420_reg_write(pd, DMAC_CONTROL, dmac_control);
/* Wait max 10ms for transmit process to stop */
- while (timeOut--) {
+ while (--timeout) {
if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_TS_)
break;
udelay(10);
}
- if (!timeOut)
+ if (!timeout)
smsc_warn(IFDOWN, "TX DMAC failed to stop");
/* ACK Tx DMAC stop bit */
@@ -596,7 +600,7 @@ static void smsc9420_free_rx_ring(struct smsc9420_pdata *pd)
static void smsc9420_stop_rx(struct smsc9420_pdata *pd)
{
- int timeOut = 1000;
+ int timeout = 1000;
u32 mac_cr, dmac_control, dma_intr_ena;
/* mask RX DMAC interrupts */
@@ -617,13 +621,13 @@ static void smsc9420_stop_rx(struct smsc9420_pdata *pd)
smsc9420_pci_flush_write(pd);
/* wait up to 10ms for receive to stop */
- while (timeOut--) {
+ while (--timeout) {
if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_RS_)
break;
udelay(10);
}
- if (!timeOut)
+ if (!timeout)
smsc_warn(IFDOWN, "RX DMAC did not stop! timeout.");
/* ACK the Rx DMAC stop bit */
@@ -666,7 +670,7 @@ static irqreturn_t smsc9420_isr(int irq, void *dev_id)
smsc9420_pci_flush_write(pd);
ints_to_clear |= (DMAC_STS_RX_ | DMAC_STS_NIS_);
- netif_rx_schedule(&pd->napi);
+ napi_schedule(&pd->napi);
}
if (ints_to_clear)
@@ -803,7 +807,7 @@ static void smsc9420_rx_handoff(struct smsc9420_pdata *pd, const int index,
if (pd->rx_csum) {
u16 hw_csum = get_unaligned_le16(skb_tail_pointer(skb) +
NET_IP_ALIGN + packet_length + 4);
- put_unaligned_le16(cpu_to_le16(hw_csum), &skb->csum);
+ put_unaligned_le16(hw_csum, &skb->csum);
skb->ip_summed = CHECKSUM_COMPLETE;
}
@@ -889,7 +893,7 @@ static int smsc9420_rx_poll(struct napi_struct *napi, int budget)
smsc9420_pci_flush_write(pd);
if (work_done < budget) {
- netif_rx_complete(&pd->napi);
+ napi_complete(&pd->napi);
/* re-enable RX DMA interrupts */
dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
@@ -1156,7 +1160,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
smsc_info(PROBE, "PHY addr %d, phy_id 0x%08X", phydev->addr,
phydev->phy_id);
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
@@ -1165,7 +1169,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
}
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ dev->name, phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -1378,6 +1382,7 @@ static int smsc9420_open(struct net_device *dev)
/* test the IRQ connection to the ISR */
smsc_dbg(IFUP, "Testing ISR using IRQ %d", dev->irq);
+ pd->software_irq_signal = false;
spin_lock_irqsave(&pd->int_lock, flags);
/* configure interrupt deassertion timer and enable interrupts */
@@ -1393,8 +1398,6 @@ static int smsc9420_open(struct net_device *dev)
smsc9420_pci_flush_write(pd);
timeout = 1000;
- pd->software_irq_signal = false;
- smp_wmb();
while (timeout--) {
if (pd->software_irq_signal)
break;
diff --git a/drivers/net/smsc9420.h b/drivers/net/smsc9420.h
index 69c351f93f8..e441402f77a 100644
--- a/drivers/net/smsc9420.h
+++ b/drivers/net/smsc9420.h
@@ -44,6 +44,7 @@
#define LAN_REGISTER_EXTENT (0x400)
#define SMSC9420_EEPROM_SIZE ((u32)11)
+#define SMSC9420_EEPROM_MAGIC (0x9420)
#define PKT_BUF_SZ (VLAN_ETH_FRAME_LEN + NET_IP_ALIGN + 4)
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 88d2c67788d..90e663f4515 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1301,7 +1301,7 @@ static int spider_net_poll(struct napi_struct *napi, int budget)
/* if all packets are in the stack, enable interrupts and return 0 */
/* if not, return 1 */
if (packets_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
spider_net_rx_irq_on(card);
card->ignore_rx_ramfull = 0;
}
@@ -1528,7 +1528,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
}
show_error = 0;
break;
@@ -1548,7 +1548,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
show_error = 0;
break;
@@ -1562,7 +1562,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
show_error = 0;
break;
@@ -1656,11 +1656,11 @@ spider_net_interrupt(int irq, void *ptr)
if (status_reg & SPIDER_NET_RXINT ) {
spider_net_rx_irq_off(card);
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
card->num_rx_ints ++;
}
if (status_reg & SPIDER_NET_TXINT)
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
if (status_reg & SPIDER_NET_LINKINT)
spider_net_link_reset(netdev);
@@ -2259,6 +2259,23 @@ spider_net_tx_timeout(struct net_device *netdev)
card->spider_stats.tx_timeouts++;
}
+static const struct net_device_ops spider_net_ops = {
+ .ndo_open = spider_net_open,
+ .ndo_stop = spider_net_stop,
+ .ndo_start_xmit = spider_net_xmit,
+ .ndo_set_multicast_list = spider_net_set_multi,
+ .ndo_set_mac_address = spider_net_set_mac,
+ .ndo_change_mtu = spider_net_change_mtu,
+ .ndo_do_ioctl = spider_net_do_ioctl,
+ .ndo_tx_timeout = spider_net_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ /* HW VLAN */
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ /* poll controller */
+ .ndo_poll_controller = spider_net_poll_controller,
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+};
+
/**
* spider_net_setup_netdev_ops - initialization of net_device operations
* @netdev: net_device structure
@@ -2268,21 +2285,8 @@ spider_net_tx_timeout(struct net_device *netdev)
static void
spider_net_setup_netdev_ops(struct net_device *netdev)
{
- netdev->open = &spider_net_open;
- netdev->stop = &spider_net_stop;
- netdev->hard_start_xmit = &spider_net_xmit;
- netdev->set_multicast_list = &spider_net_set_multi;
- netdev->set_mac_address = &spider_net_set_mac;
- netdev->change_mtu = &spider_net_change_mtu;
- netdev->do_ioctl = &spider_net_do_ioctl;
- /* tx watchdog */
- netdev->tx_timeout = &spider_net_tx_timeout;
+ netdev->netdev_ops = &spider_net_ops;
netdev->watchdog_timeo = SPIDER_NET_WATCHDOG_TIMEOUT;
- /* HW VLAN */
-#ifdef CONFIG_NET_POLL_CONTROLLER
- /* poll controller */
- netdev->poll_controller = &spider_net_poll_controller;
-#endif /* CONFIG_NET_POLL_CONTROLLER */
/* ethtool ops */
netdev->ethtool_ops = &spider_net_ethtool_ops;
}
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index da3a76b18ef..fcb943fca4f 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -178,7 +178,7 @@ static int full_duplex[MAX_UNITS] = {0, };
#define FIRMWARE_TX "adaptec/starfire_tx.bin"
/* These identify the driver base version and may not be removed. */
-static char version[] =
+static const char version[] __devinitconst =
KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n"
KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
@@ -1342,8 +1342,8 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
if (intr_status & (IntrRxDone | IntrRxEmpty)) {
u32 enable;
- if (likely(netif_rx_schedule_prep(&np->napi))) {
- __netif_rx_schedule(&np->napi);
+ if (likely(napi_schedule_prep(&np->napi))) {
+ __napi_schedule(&np->napi);
enable = readl(ioaddr + IntrEnable);
enable &= ~(IntrRxDone | IntrRxEmpty);
writel(enable, ioaddr + IntrEnable);
@@ -1587,7 +1587,7 @@ static int netdev_poll(struct napi_struct *napi, int budget)
intr_status = readl(ioaddr + IntrStatus);
} while (intr_status & (IntrRxDone | IntrRxEmpty));
- netif_rx_complete(napi);
+ napi_complete(napi);
intr_status = readl(ioaddr + IntrEnable);
intr_status |= IntrRxDone | IntrRxEmpty;
writel(intr_status, ioaddr + IntrEnable);
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 4bb8f72c65c..e5beb299cbd 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -428,7 +428,7 @@ static int lance_open( struct net_device *dev )
while (--i > 0)
if (DREG & CSR0_IDON)
break;
- if (i < 0 || (DREG & CSR0_ERR)) {
+ if (i <= 0 || (DREG & CSR0_ERR)) {
DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
dev->name, i, DREG ));
DREG = CSR0_STOP;
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 7f69c7f176c..5017d7fcb40 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -1074,6 +1074,18 @@ static const struct ethtool_ops bigmac_ethtool_ops = {
.get_link = bigmac_get_link,
};
+static const struct net_device_ops bigmac_ops = {
+ .ndo_open = bigmac_open,
+ .ndo_stop = bigmac_close,
+ .ndo_start_xmit = bigmac_start_xmit,
+ .ndo_get_stats = bigmac_get_stats,
+ .ndo_set_multicast_list = bigmac_set_multicast,
+ .ndo_tx_timeout = bigmac_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit bigmac_ether_init(struct of_device *op,
struct of_device *qec_op)
{
@@ -1187,16 +1199,8 @@ static int __devinit bigmac_ether_init(struct of_device *op,
bp->dev = dev;
/* Set links to our BigMAC open and close routines. */
- dev->open = &bigmac_open;
- dev->stop = &bigmac_close;
- dev->hard_start_xmit = &bigmac_start_xmit;
dev->ethtool_ops = &bigmac_ethtool_ops;
-
- /* Set links to BigMAC statistic and multi-cast loading code. */
- dev->get_stats = &bigmac_get_stats;
- dev->set_multicast_list = &bigmac_set_multicast;
-
- dev->tx_timeout = &bigmac_tx_timeout;
+ dev->netdev_ops = &bigmac_ops;
dev->watchdog_timeo = 5*HZ;
/* Finish net device registration. */
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index feaf0e0577d..c399b1955c1 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -109,8 +109,9 @@ static char *media[MAX_UNITS];
#endif
/* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+ " Written by Donald Becker\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
@@ -909,7 +910,7 @@ static void check_duplex(struct net_device *dev)
printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
"negotiated capability %4.4x.\n", dev->name,
duplex ? "full" : "half", np->phys[0], negotiated);
- iowrite16(ioread16(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0);
+ iowrite16(ioread16(ioaddr + MACCtrl0) | (duplex ? 0x20 : 0), ioaddr + MACCtrl0);
}
}
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 86c765d83de..c024352c92f 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -148,7 +148,7 @@ static u16 __phy_read(struct gem *gp, int phy_addr, int reg)
cmd |= (MIF_FRAME_TAMSB);
writel(cmd, gp->regs + MIF_FRAME);
- while (limit--) {
+ while (--limit) {
cmd = readl(gp->regs + MIF_FRAME);
if (cmd & MIF_FRAME_TALSB)
break;
@@ -921,7 +921,7 @@ static int gem_poll(struct napi_struct *napi, int budget)
gp->status = readl(gp->regs + GREG_STAT);
} while (gp->status & GREG_STAT_NAPI);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
gem_enable_ints(gp);
spin_unlock_irqrestore(&gp->lock, flags);
@@ -944,7 +944,7 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id)
spin_lock_irqsave(&gp->lock, flags);
- if (netif_rx_schedule_prep(&gp->napi)) {
+ if (napi_schedule_prep(&gp->napi)) {
u32 gem_status = readl(gp->regs + GREG_STAT);
if (gem_status == 0) {
@@ -954,7 +954,7 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id)
}
gp->status = gem_status;
gem_disable_ints(gp);
- __netif_rx_schedule(&gp->napi);
+ __napi_schedule(&gp->napi);
}
spin_unlock_irqrestore(&gp->lock, flags);
@@ -1157,7 +1157,7 @@ static void gem_pcs_reset(struct gem *gp)
if (limit-- <= 0)
break;
}
- if (limit <= 0)
+ if (limit < 0)
printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
gp->dev->name);
}
@@ -1229,7 +1229,7 @@ static void gem_reset(struct gem *gp)
break;
} while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST));
- if (limit <= 0)
+ if (limit < 0)
printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name);
if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes)
@@ -2221,6 +2221,8 @@ static int gem_do_start(struct net_device *dev)
gp->running = 1;
+ napi_enable(&gp->napi);
+
if (gp->lstate == link_up) {
netif_carrier_on(gp->dev);
gem_set_link_modes(gp);
@@ -2238,6 +2240,8 @@ static int gem_do_start(struct net_device *dev)
spin_lock_irqsave(&gp->lock, flags);
spin_lock(&gp->tx_lock);
+ napi_disable(&gp->napi);
+
gp->running = 0;
gem_reset(gp);
gem_clean_rings(gp);
@@ -2338,8 +2342,6 @@ static int gem_open(struct net_device *dev)
if (!gp->asleep)
rc = gem_do_start(dev);
gp->opened = (rc == 0);
- if (gp->opened)
- napi_enable(&gp->napi);
mutex_unlock(&gp->pm_mutex);
@@ -2476,8 +2478,6 @@ static int gem_resume(struct pci_dev *pdev)
/* Re-attach net device */
netif_device_attach(dev);
-
- napi_enable(&gp->napi);
}
spin_lock_irqsave(&gp->lock, flags);
@@ -2998,8 +2998,11 @@ static const struct net_device_ops gem_netdev_ops = {
.ndo_do_ioctl = gem_ioctl,
.ndo_tx_timeout = gem_tx_timeout,
.ndo_change_mtu = gem_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = gem_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = gem_poll_controller,
+#endif
};
static int __devinit gem_init_one(struct pci_dev *pdev,
@@ -3161,10 +3164,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
dev->watchdog_timeo = 5 * HZ;
dev->irq = pdev->irq;
dev->dma = 0;
- dev->set_mac_address = gem_set_mac_address;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = gem_poll_controller;
-#endif
/* Set that now, in case PM kicks in now */
pci_set_drvdata(pdev, dev);
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 61843fd5752..78f8cee5fd7 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -79,7 +79,7 @@ static int reset_one_mii_phy(struct mii_phy* phy, int phy_id)
udelay(100);
- while (limit--) {
+ while (--limit) {
val = __phy_read(phy, phy_id, MII_BMCR);
if ((val & BMCR_RESET) == 0)
break;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 7a72a3112f0..4e9bd380a5c 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2543,25 +2543,36 @@ static struct quattro * __devinit quattro_sbus_find(struct of_device *child)
}
/* After all quattro cards have been probed, we call these functions
- * to register the IRQ handlers.
+ * to register the IRQ handlers for the cards that have been
+ * successfully probed and skip the cards that failed to initialize
*/
-static void __init quattro_sbus_register_irqs(void)
+static int __init quattro_sbus_register_irqs(void)
{
struct quattro *qp;
for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
struct of_device *op = qp->quattro_dev;
- int err;
+ int err, qfe_slot, skip = 0;
+
+ for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
+ if (!qp->happy_meals[qfe_slot])
+ skip = 1;
+ }
+ if (skip)
+ continue;
err = request_irq(op->irqs[0],
quattro_sbus_interrupt,
IRQF_SHARED, "Quattro",
qp);
if (err != 0) {
- printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err);
- panic("QFE request irq");
+ printk(KERN_ERR "Quattro HME: IRQ registration "
+ "error %d.\n", err);
+ return err;
}
}
+
+ return 0;
}
static void quattro_sbus_free_irqs(void)
@@ -2570,6 +2581,14 @@ static void quattro_sbus_free_irqs(void)
for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
struct of_device *op = qp->quattro_dev;
+ int qfe_slot, skip = 0;
+
+ for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
+ if (!qp->happy_meals[qfe_slot])
+ skip = 1;
+ }
+ if (skip)
+ continue;
free_irq(op->irqs[0], qp);
}
@@ -2629,6 +2648,12 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
int i, qfe_slot = -1;
int err = -ENODEV;
+ sbus_dp = to_of_device(op->dev.parent)->node;
+
+ /* We can match PCI devices too, do not accept those here. */
+ if (strcmp(sbus_dp->name, "sbus"))
+ return err;
+
if (is_qfe) {
qp = quattro_sbus_find(op);
if (qp == NULL)
@@ -2734,10 +2759,6 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
if (qp != NULL)
hp->happy_flags |= HFLAG_QUATTRO;
- sbus_dp = to_of_device(op->dev.parent)->node;
- if (is_qfe)
- sbus_dp = to_of_device(op->dev.parent->parent)->node;
-
/* Get the supported DVMA burst sizes from our Happy SBUS. */
hp->happy_bursts = of_getintprop_default(sbus_dp,
"burst-sizes", 0x00);
@@ -2824,6 +2845,9 @@ err_out_iounmap:
if (hp->tcvregs)
of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
+ if (qp)
+ qp->happy_meals[qfe_slot] = NULL;
+
err_out_free_netdev:
free_netdev(dev);
@@ -3281,7 +3305,7 @@ static int __init happy_meal_sbus_init(void)
err = of_register_driver(&hme_sbus_driver, &of_bus_type);
if (!err)
- quattro_sbus_register_irqs();
+ err = quattro_sbus_register_irqs();
return err;
}
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 28137328175..afc7b351e5e 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -343,7 +343,7 @@ static void lance_init_ring_dvma(struct net_device *dev)
ib->phys_addr [5] = dev->dev_addr [4];
/* Setup the Tx ring entries */
- for (i = 0; i <= TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
leptr = LANCE_ADDR(aib + libbuff_offset(tx_buf, i));
ib->btx_ring [i].tmd0 = leptr;
ib->btx_ring [i].tmd1_hadr = leptr >> 16;
@@ -399,7 +399,7 @@ static void lance_init_ring_pio(struct net_device *dev)
sbus_writeb(dev->dev_addr[4], &ib->phys_addr[5]);
/* Setup the Tx ring entries */
- for (i = 0; i <= TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
leptr = libbuff_offset(tx_buf, i);
sbus_writew(leptr, &ib->btx_ring [i].tmd0);
sbus_writeb(leptr >> 16,&ib->btx_ring [i].tmd1_hadr);
@@ -1311,6 +1311,17 @@ static const struct ethtool_ops sparc_lance_ethtool_ops = {
.get_link = sparc_lance_get_link,
};
+static const struct net_device_ops sparc_lance_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_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_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit sparc_lance_probe_one(struct of_device *op,
struct of_device *ledma,
struct of_device *lebuffer)
@@ -1462,13 +1473,9 @@ no_link_test:
lp->dev = dev;
SET_NETDEV_DEV(dev, &op->dev);
- dev->open = &lance_open;
- dev->stop = &lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->tx_timeout = &lance_tx_timeout;
dev->watchdog_timeo = 5*HZ;
- dev->set_multicast_list = &lance_set_multicast;
dev->ethtool_ops = &sparc_lance_ethtool_ops;
+ dev->netdev_ops = &sparc_lance_ops;
dev->irq = op->irqs[0];
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 6e8f377355f..c6ec61e0acc 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -227,7 +227,7 @@ static int qe_init(struct sunqe *qep, int from_irq)
if (!(sbus_readb(mregs + MREGS_PHYCONFIG) & MREGS_PHYCONFIG_LTESTDIS)) {
int tries = 50;
- while (tries--) {
+ while (--tries) {
u8 tmp;
mdelay(5);
@@ -829,6 +829,17 @@ fail:
return NULL;
}
+static const struct net_device_ops qec_ops = {
+ .ndo_open = qe_open,
+ .ndo_stop = qe_close,
+ .ndo_start_xmit = qe_start_xmit,
+ .ndo_set_multicast_list = qe_set_multicast,
+ .ndo_tx_timeout = qe_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit qec_ether_init(struct of_device *op)
{
static unsigned version_printed;
@@ -893,15 +904,11 @@ static int __devinit qec_ether_init(struct of_device *op)
SET_NETDEV_DEV(dev, &op->dev);
- dev->open = qe_open;
- dev->stop = qe_close;
- dev->hard_start_xmit = qe_start_xmit;
- dev->set_multicast_list = qe_set_multicast;
- dev->tx_timeout = qe_tx_timeout;
dev->watchdog_timeo = 5*HZ;
dev->irq = op->irqs[0];
dev->dma = 0;
dev->ethtool_ops = &qe_ethtool_ops;
+ dev->netdev_ops = &qec_ops;
res = register_netdev(dev);
if (res)
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index 611230fef2b..a82fb2aca4c 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -1012,6 +1012,16 @@ err_out:
static LIST_HEAD(vnet_list);
static DEFINE_MUTEX(vnet_list_mutex);
+static const struct net_device_ops vnet_ops = {
+ .ndo_open = vnet_open,
+ .ndo_stop = vnet_close,
+ .ndo_set_multicast_list = vnet_set_rx_mode,
+ .ndo_set_mac_address = vnet_set_mac_addr,
+ .ndo_tx_timeout = vnet_tx_timeout,
+ .ndo_change_mtu = vnet_change_mtu,
+ .ndo_start_xmit = vnet_start_xmit,
+};
+
static struct vnet * __devinit vnet_new(const u64 *local_mac)
{
struct net_device *dev;
@@ -1040,15 +1050,9 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
INIT_LIST_HEAD(&vp->list);
vp->local_mac = *local_mac;
- dev->open = vnet_open;
- dev->stop = vnet_close;
- dev->set_multicast_list = vnet_set_rx_mode;
- dev->set_mac_address = vnet_set_mac_addr;
- dev->tx_timeout = vnet_tx_timeout;
+ dev->netdev_ops = &vnet_ops;
dev->ethtool_ops = &vnet_ethtool_ops;
dev->watchdog_timeo = VNET_TX_TIMEOUT;
- dev->change_mtu = vnet_change_mtu;
- dev->hard_start_xmit = vnet_start_xmit;
err = register_netdev(dev);
if (err) {
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index bcd0e60cbda..b52a1c088f3 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -725,7 +725,7 @@ static int tc_mii_probe(struct net_device *dev)
}
/* attach the mac to the phy */
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&tc_handle_link_change, 0,
lp->chiptype == TC35815_TX4939 ?
PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII);
@@ -735,7 +735,7 @@ static int tc_mii_probe(struct net_device *dev)
}
printk(KERN_INFO "%s: attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, id=%x)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id,
+ dev->name, phydev->drv->name, dev_name(&phydev->dev),
phydev->phy_id);
/* mask with MAC supported features */
@@ -1609,8 +1609,8 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
if (!(dmactl & DMA_IntMask)) {
/* disable interrupts */
tc_writel(dmactl | DMA_IntMask, &tr->DMA_Ctl);
- if (netif_rx_schedule_prep(&lp->napi))
- __netif_rx_schedule(&lp->napi);
+ if (napi_schedule_prep(&lp->napi))
+ __napi_schedule(&lp->napi);
else {
printk(KERN_ERR "%s: interrupt taken in poll\n",
dev->name);
@@ -1919,7 +1919,7 @@ static int tc35815_poll(struct napi_struct *napi, int budget)
spin_unlock(&lp->lock);
if (received < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* enable interrupts */
tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl);
}
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index a7a4dc4d631..7debd1e4e1f 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -63,7 +63,6 @@
*/
#include "tehuti.h"
-#include "tehuti_fw.h"
static struct pci_device_id __devinitdata bdx_pci_tbl[] = {
{0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -265,8 +264,8 @@ static irqreturn_t bdx_isr_napi(int irq, void *dev)
bdx_isr_extra(priv, isr);
if (isr & (IR_RX_DESC_0 | IR_TX_FREE_0)) {
- if (likely(netif_rx_schedule_prep(&priv->napi))) {
- __netif_rx_schedule(&priv->napi);
+ if (likely(napi_schedule_prep(&priv->napi))) {
+ __napi_schedule(&priv->napi);
RET(IRQ_HANDLED);
} else {
/* NOTE: we get here if intr has slipped into window
@@ -302,7 +301,7 @@ static int bdx_poll(struct napi_struct *napi, int budget)
* device lock and allow waiting tasks (eg rmmod) to advance) */
priv->napi_stop = 0;
- netif_rx_complete(napi);
+ napi_complete(napi);
bdx_enable_interrupts(priv);
}
return work_done;
@@ -318,28 +317,41 @@ static int bdx_poll(struct napi_struct *napi, int budget)
static int bdx_fw_load(struct bdx_priv *priv)
{
+ const struct firmware *fw = NULL;
int master, i;
+ int rc;
ENTER;
master = READ_REG(priv, regINIT_SEMAPHORE);
if (!READ_REG(priv, regINIT_STATUS) && master) {
- bdx_tx_push_desc_safe(priv, s_firmLoad, sizeof(s_firmLoad));
+ rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev);
+ if (rc)
+ goto out;
+ bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size);
mdelay(100);
}
for (i = 0; i < 200; i++) {
- if (READ_REG(priv, regINIT_STATUS))
- break;
+ if (READ_REG(priv, regINIT_STATUS)) {
+ rc = 0;
+ goto out;
+ }
mdelay(2);
}
+ rc = -EIO;
+out:
if (master)
WRITE_REG(priv, regINIT_SEMAPHORE, 1);
+ if (fw)
+ release_firmware(fw);
- if (i == 200) {
+ if (rc) {
ERR("%s: firmware loading failed\n", priv->ndev->name);
- DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
- READ_REG(priv, regVPC),
- READ_REG(priv, regVIC), READ_REG(priv, regINIT_STATUS), i);
- RET(-EIO);
+ if (rc == -EIO)
+ DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
+ READ_REG(priv, regVPC),
+ READ_REG(priv, regVIC),
+ READ_REG(priv, regINIT_STATUS), i);
+ RET(rc);
} else {
DBG("%s: firmware loading success\n", priv->ndev->name);
RET(0);
@@ -617,13 +629,6 @@ err:
RET(rc);
}
-static void __init bdx_firmware_endianess(void)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(s_firmLoad); i++)
- s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]);
-}
-
static int bdx_range_check(struct bdx_priv *priv, u32 offset)
{
return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ?
@@ -2501,7 +2506,6 @@ static void __init print_driver_id(void)
static int __init bdx_module_init(void)
{
ENTER;
- bdx_firmware_endianess();
init_txd_sizes();
print_driver_id();
RET(pci_register_driver(&bdx_pci_driver));
@@ -2521,3 +2525,4 @@ module_exit(bdx_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(BDX_DRV_DESC);
+MODULE_FIRMWARE("tehuti/firmware.bin");
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index efaf84d9757..dec67e0a9ca 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -29,6 +29,7 @@
#include <linux/if_vlan.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
+#include <linux/firmware.h>
#include <asm/byteorder.h>
/* Compile Time Switches */
diff --git a/drivers/net/tehuti_fw.h b/drivers/net/tehuti_fw.h
deleted file mode 100644
index 2c603a8a438..00000000000
--- a/drivers/net/tehuti_fw.h
+++ /dev/null
@@ -1,10712 +0,0 @@
-/*
- * Tehuti Networks(R) Network Driver
- * Copyright (C) 2007 Tehuti Networks Ltd. All rights reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-/* Loading Firmware */
-/* INT_MEM Ver */
-static u32 s_firmLoad[] = {
- 0x000f0002,
- 0x40718000,
- 0x0000002d,
- 0xc0000000,
- 0x000f0002,
- 0x00718001,
- 0x0000002d,
- 0xc0800000,
- 0x000f0002,
- 0x00718002,
- 0x0000002d,
- 0xc1000000,
- 0x000f0002,
- 0x00718003,
- 0x0000002d,
- 0xc1800000,
- 0x000f0002,
- 0x00718004,
- 0x0000002d,
- 0xc2000000,
- 0x000f0002,
- 0x00718005,
- 0x0000002d,
- 0xc2800000,
- 0x000f0002,
- 0x00718006,
- 0x0000002d,
- 0xc3000000,
- 0x000f0002,
- 0x00718007,
- 0x0000002d,
- 0xc3800000,
- 0x000f0002,
- 0x00718008,
- 0x0000002d,
- 0xc4000000,
- 0x000f0002,
- 0x00718009,
- 0x0000002d,
- 0xc4800000,
- 0x000f0002,
- 0x0071800a,
- 0x0000002d,
- 0xc5000000,
- 0x000f0002,
- 0x0071800b,
- 0x0000002d,
- 0xc5800000,
- 0x000f0002,
- 0x0071800c,
- 0x0000002d,
- 0xc6000000,
- 0x000f0002,
- 0x0071800d,
- 0x0000002d,
- 0xc6800000,
- 0x000f0002,
- 0x0071800e,
- 0x0000002d,
- 0xc7000000,
- 0x000f0002,
- 0x0071800f,
- 0x0000002d,
- 0xc7800000,
- 0x000f0002,
- 0x00718010,
- 0x0000002d,
- 0xc8000000,
- 0x000f0002,
- 0x00718011,
- 0x0000002d,
- 0xc8800000,
- 0x000f0002,
- 0x00718012,
- 0x0000002d,
- 0xc9000000,
- 0x000f0002,
- 0x00718013,
- 0x0000002d,
- 0xc9800000,
- 0x000f0002,
- 0x00718014,
- 0x0000002d,
- 0xca000000,
- 0x000f0002,
- 0x00718015,
- 0x0000002d,
- 0xca800000,
- 0x000f0002,
- 0x00718016,
- 0x0000002d,
- 0xcb000000,
- 0x000f0002,
- 0x00718017,
- 0x0000002d,
- 0xcb800000,
- 0x000f0002,
- 0x00718018,
- 0x0000002d,
- 0xcc000000,
- 0x000f0002,
- 0x00718019,
- 0x0000002d,
- 0xcc800000,
- 0x000f0002,
- 0x0071801a,
- 0x0000002d,
- 0xcd000000,
- 0x000f0002,
- 0x0071801b,
- 0x0000002d,
- 0xcd800000,
- 0x000f0002,
- 0x0071801c,
- 0x0000002d,
- 0xce000000,
- 0x000f0002,
- 0x0071801d,
- 0x0000002d,
- 0xce800000,
- 0x000f0002,
- 0x0071801e,
- 0x0000002d,
- 0xcf000000,
- 0x000f0002,
- 0x0071801f,
- 0x0000002d,
- 0xcf800000,
- 0x000f0002,
- 0x00718020,
- 0x0000002d,
- 0xd0000000,
- 0x000f0002,
- 0x00718021,
- 0x0000002d,
- 0xd0800000,
- 0x000f0002,
- 0x00718022,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x00718023,
- 0x0000002d,
- 0xd1800000,
- 0x000f0002,
- 0x00718024,
- 0x0000002d,
- 0xd2000000,
- 0x000f0002,
- 0x00718025,
- 0x0000002d,
- 0xd2800000,
- 0x000f0002,
- 0x00718026,
- 0x0000002d,
- 0xd3000000,
- 0x000f0002,
- 0x00718027,
- 0x0000002d,
- 0xd3800000,
- 0x000f0002,
- 0x00718028,
- 0x0000002d,
- 0xd4000000,
- 0x000f0002,
- 0x00718029,
- 0x0000002d,
- 0xd4800000,
- 0x000f0002,
- 0x0071802a,
- 0x0000002d,
- 0xd5000000,
- 0x000f0002,
- 0x0071802b,
- 0x0000002d,
- 0xd5800000,
- 0x000f0002,
- 0x0071802c,
- 0x0000002d,
- 0xd6000000,
- 0x000f0002,
- 0x0071802d,
- 0x0000002d,
- 0xd6800000,
- 0x000f0002,
- 0x0071802e,
- 0x0000002d,
- 0xd7000000,
- 0x000f0002,
- 0x0071802f,
- 0x0000002d,
- 0xd7800000,
- 0x000f0002,
- 0x00718030,
- 0x0000002d,
- 0xd8000000,
- 0x000f0002,
- 0x00718031,
- 0x0000002d,
- 0xd8800000,
- 0x000f0002,
- 0x00718032,
- 0x0000002d,
- 0xd9000000,
- 0x000f0002,
- 0x00718033,
- 0x0000002d,
- 0xd9800000,
- 0x000f0002,
- 0x00718034,
- 0x0000002d,
- 0xda000000,
- 0x000f0002,
- 0x00718035,
- 0x0000002d,
- 0xda800000,
- 0x000f0002,
- 0x00718036,
- 0x0000002d,
- 0xdb000000,
- 0x000f0002,
- 0x00718037,
- 0x0000002d,
- 0xdb800000,
- 0x000f0002,
- 0x00718038,
- 0x0000007b,
- 0xdd608000,
- 0x000f0002,
- 0x00718039,
- 0x0000002d,
- 0xdd000000,
- 0x000f0002,
- 0x0071803a,
- 0x0000002d,
- 0xdb800000,
- 0x000f0002,
- 0x0071803b,
- 0x0000002d,
- 0xdd000000,
- 0x000f0002,
- 0x0071803c,
- 0x0000002d,
- 0xdd000000,
- 0x000f0002,
- 0x0071803d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718040,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718041,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718042,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718043,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718044,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718045,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718046,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718047,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718048,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718049,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718050,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718051,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718052,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718053,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718054,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718055,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718056,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718057,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718058,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718059,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718060,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718061,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718062,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718063,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718064,
- 0x0000002d,
- 0xdb000000,
- 0x000f0002,
- 0x00718065,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718066,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718067,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718068,
- 0x0000003f,
- 0xdd000804,
- 0x000f0002,
- 0x00718069,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071806a,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x0071806b,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071806c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071806d,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071806e,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071806f,
- 0x0000003f,
- 0xdd003d04,
- 0x000f0002,
- 0x00718070,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718071,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718072,
- 0x0000003f,
- 0xdd000704,
- 0x000f0002,
- 0x00718073,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718074,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x00718075,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718076,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718077,
- 0x0000003f,
- 0xdd003704,
- 0x000f0002,
- 0x00718078,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718079,
- 0x0000003f,
- 0xdd002904,
- 0x000f0002,
- 0x0071807a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071807b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071807c,
- 0x0000003f,
- 0xdd04aa04,
- 0x000f0002,
- 0x0071807d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071807e,
- 0x0000003f,
- 0xdd002804,
- 0x000f0002,
- 0x0071807f,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718080,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718081,
- 0x0000003f,
- 0xdd003104,
- 0x000f0002,
- 0x00718082,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718083,
- 0x0000003f,
- 0xdd002b84,
- 0x000f0002,
- 0x00718084,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718085,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718086,
- 0x0000003f,
- 0xdd01e404,
- 0x000f0002,
- 0x00718087,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718088,
- 0x0000003f,
- 0xd7800084,
- 0x000f0002,
- 0x00718089,
- 0x0000003f,
- 0xd7980001,
- 0x000f0002,
- 0x0071808a,
- 0x00000059,
- 0xd78037ef,
- 0x000f0002,
- 0x0071808b,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071808c,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071808d,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071808e,
- 0x0000002d,
- 0xd7d6027f,
- 0x000f0002,
- 0x0071808f,
- 0x00000018,
- 0x17ff0081,
- 0x000f0002,
- 0x00718090,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718091,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718092,
- 0x0000002d,
- 0xd7d800b8,
- 0x000f0002,
- 0x00718093,
- 0x00000018,
- 0x17eb0081,
- 0x000f0002,
- 0x00718094,
- 0x0000003f,
- 0xdd002904,
- 0x000f0002,
- 0x00718095,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718096,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718097,
- 0x0000003f,
- 0xdd04aa84,
- 0x000f0002,
- 0x00718098,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718099,
- 0x0000003f,
- 0xdd002b04,
- 0x000f0002,
- 0x0071809a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071809b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071809c,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071809d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071809e,
- 0x0000003f,
- 0xdd002984,
- 0x000f0002,
- 0x0071809f,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180a0,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180a1,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180a2,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180a3,
- 0x0000003f,
- 0xdd002a04,
- 0x000f0002,
- 0x007180a4,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180a5,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180a6,
- 0x0000003f,
- 0xdd009184,
- 0x000f0002,
- 0x007180a7,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180a8,
- 0x0000003f,
- 0xd6801984,
- 0x000f0002,
- 0x007180a9,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180aa,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180ab,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180ac,
- 0x0000003f,
- 0xdd002b04,
- 0x000f0002,
- 0x007180ad,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180ae,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180af,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180b0,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180b1,
- 0x0000003f,
- 0xdd002a84,
- 0x000f0002,
- 0x007180b2,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180b3,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180b4,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180b5,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180b6,
- 0x0000003f,
- 0xd6800c84,
- 0x000f0002,
- 0x007180b7,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180b8,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180b9,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180ba,
- 0x0000003f,
- 0xdd002a84,
- 0x000f0002,
- 0x007180bb,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180bc,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180bd,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180be,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180bf,
- 0x0000003f,
- 0xd6800f84,
- 0x000f0002,
- 0x007180c0,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180c1,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180c2,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180c3,
- 0x0000003f,
- 0xdd002a04,
- 0x000f0002,
- 0x007180c4,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180c5,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180c6,
- 0x0000003f,
- 0xdd001184,
- 0x000f0002,
- 0x007180c7,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180c8,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x007180c9,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180ca,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180cb,
- 0x0000003f,
- 0xdd003784,
- 0x000f0002,
- 0x007180cc,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180cd,
- 0x0000002d,
- 0xd3800000,
- 0x000f0002,
- 0x007180ce,
- 0x0000003f,
- 0xd2003780,
- 0x000f0002,
- 0x007180cf,
- 0x0000003f,
- 0xd1800404,
- 0x000f0002,
- 0x007180d0,
- 0x0000003f,
- 0xd1840001,
- 0x000f0002,
- 0x007180d1,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d2,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d3,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d4,
- 0x0000003f,
- 0xd17fff84,
- 0x000f0002,
- 0x007180d5,
- 0x0000003f,
- 0xd17fff81,
- 0x000f0002,
- 0x007180d6,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d7,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d8,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d9,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180da,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180db,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180dc,
- 0x0000003f,
- 0xd6800784,
- 0x000f0002,
- 0x007180dd,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180de,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180df,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180e0,
- 0x00000049,
- 0xdd003b63,
- 0x000f0002,
- 0x007180e1,
- 0x00000059,
- 0xdd003b76,
- 0x000f0002,
- 0x007180e2,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180e3,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180e4,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180e5,
- 0x0000002d,
- 0xdd06027f,
- 0x000f0002,
- 0x007180e6,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x007180e7,
- 0x00000045,
- 0xdd003139,
- 0x000f0002,
- 0x007180e8,
- 0x00000094,
- 0x000b313b,
- 0x000f0002,
- 0x007180e9,
- 0x00000094,
- 0x0009313d,
- 0x000f0002,
- 0x007180ea,
- 0x00000094,
- 0x0007313f,
- 0x000f0002,
- 0x007180eb,
- 0x00000094,
- 0x00053b76,
- 0x000f0002,
- 0x007180ec,
- 0x00000009,
- 0xc1ed3d7a,
- 0x000f0002,
- 0x007180ed,
- 0x0000003f,
- 0xd200b780,
- 0x000f0002,
- 0x007180ee,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x007180ef,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180f0,
- 0x00000069,
- 0xdd003264,
- 0x000f0002,
- 0x007180f1,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180f2,
- 0x0000003f,
- 0xd6800784,
- 0x000f0002,
- 0x007180f3,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180f4,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180f5,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180f6,
- 0x00000049,
- 0xdd003b63,
- 0x000f0002,
- 0x007180f7,
- 0x00000059,
- 0xdd003b76,
- 0x000f0002,
- 0x007180f8,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180f9,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180fa,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180fb,
- 0x0000002d,
- 0xdd06027f,
- 0x000f0002,
- 0x007180fc,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x007180fd,
- 0x00000045,
- 0xdd00313a,
- 0x000f0002,
- 0x007180fe,
- 0x00000018,
- 0x1d2d3b76,
- 0x000f0002,
- 0x007180ff,
- 0x00000045,
- 0xdd00313c,
- 0x000f0002,
- 0x00718100,
- 0x00000018,
- 0x1d133b76,
- 0x000f0002,
- 0x00718101,
- 0x00000045,
- 0xdd00313e,
- 0x000f0002,
- 0x00718102,
- 0x00000018,
- 0x1d1b3b76,
- 0x000f0002,
- 0x00718103,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x00718104,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718105,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718106,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718107,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718108,
- 0x00000009,
- 0xc52d3d7a,
- 0x000f0002,
- 0x00718109,
- 0x00000029,
- 0xd2010064,
- 0x000f0002,
- 0x0071810a,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x0071810b,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071810c,
- 0x00000069,
- 0xdd003264,
- 0x000f0002,
- 0x0071810d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071810e,
- 0x00000009,
- 0xc2293d7a,
- 0x000f0002,
- 0x0071810f,
- 0x00000029,
- 0xd2000064,
- 0x000f0002,
- 0x00718110,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x00718111,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718112,
- 0x00000069,
- 0xdd003264,
- 0x000f0002,
- 0x00718113,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718114,
- 0x00000049,
- 0xdd003b63,
- 0x000f0002,
- 0x00718115,
- 0x00000059,
- 0xdd003b76,
- 0x000f0002,
- 0x00718116,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718117,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718118,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718119,
- 0x0000002d,
- 0xdd06027f,
- 0x000f0002,
- 0x0071811a,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x0071811b,
- 0x00000045,
- 0xdd00313a,
- 0x000f0002,
- 0x0071811c,
- 0x00000018,
- 0x1d0f3b76,
- 0x000f0002,
- 0x0071811d,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x0071811e,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071811f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718120,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718121,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718122,
- 0x00000009,
- 0xc52d3d7a,
- 0x000f0002,
- 0x00718123,
- 0x0000002d,
- 0xd1080082,
- 0x000f0002,
- 0x00718124,
- 0x00000008,
- 0x23c33d7a,
- 0x000f0002,
- 0x00718125,
- 0x00000049,
- 0xd6003b0a,
- 0x000f0002,
- 0x00718126,
- 0x0000003f,
- 0xd3000004,
- 0x000f0002,
- 0x00718127,
- 0x0000003f,
- 0xd3040001,
- 0x000f0002,
- 0x00718128,
- 0x0000002f,
- 0xd6814085,
- 0x000f0002,
- 0x00718129,
- 0x0000003f,
- 0xd4ffff84,
- 0x000f0002,
- 0x0071812a,
- 0x0000003f,
- 0xd4800781,
- 0x000f0002,
- 0x0071812b,
- 0x0000003f,
- 0xd1ffff84,
- 0x000f0002,
- 0x0071812c,
- 0x0000003f,
- 0xd1800001,
- 0x000f0002,
- 0x0071812d,
- 0x00000049,
- 0xdd003666,
- 0x000f0002,
- 0x0071812e,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x0071812f,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718130,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718131,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x00718132,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718133,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718134,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718135,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x00718136,
- 0x00000061,
- 0xf600046c,
- 0x000f0002,
- 0x00718137,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718138,
- 0x00000018,
- 0x3d6b0081,
- 0x000f0002,
- 0x00718139,
- 0x00000049,
- 0xd600058b,
- 0x000f0002,
- 0x0071813a,
- 0x0000002f,
- 0xd6810106,
- 0x000f0002,
- 0x0071813b,
- 0x0000002d,
- 0xd2000000,
- 0x000f0002,
- 0x0071813c,
- 0x00000021,
- 0xd20000e4,
- 0x000f0002,
- 0x0071813d,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071813e,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x0071813f,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718140,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718141,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718142,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718143,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718144,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x00718145,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x00718146,
- 0x00000049,
- 0xd17a33e4,
- 0x000f0002,
- 0x00718147,
- 0x0000002f,
- 0xd1710162,
- 0x000f0002,
- 0x00718148,
- 0x0000002f,
- 0xd1610162,
- 0x000f0002,
- 0x00718149,
- 0x00000049,
- 0xd14033e3,
- 0x000f0002,
- 0x0071814a,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071814b,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x0071814c,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x0071814d,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x0071814e,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071814f,
- 0x00000069,
- 0xd8003162,
- 0x000f0002,
- 0x00718150,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718151,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x00718152,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718153,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718154,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718155,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718156,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718157,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718158,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718159,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071815a,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x0071815b,
- 0x0000002d,
- 0xd16c07e4,
- 0x000f0002,
- 0x0071815c,
- 0x00000049,
- 0xd14033e3,
- 0x000f0002,
- 0x0071815d,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071815e,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x0071815f,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718160,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718161,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718162,
- 0x00000069,
- 0xd8003162,
- 0x000f0002,
- 0x00718163,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718164,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x00718165,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718166,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718167,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718168,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718169,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071816a,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071816b,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x0071816c,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071816d,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x0071816e,
- 0x00000049,
- 0xd17833e4,
- 0x000f0002,
- 0x0071816f,
- 0x0000002f,
- 0xd1710162,
- 0x000f0002,
- 0x00718170,
- 0x0000002f,
- 0xd1610162,
- 0x000f0002,
- 0x00718171,
- 0x00000049,
- 0xd14033e3,
- 0x000f0002,
- 0x00718172,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718173,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718174,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718175,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718176,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718177,
- 0x00000069,
- 0xd8003162,
- 0x000f0002,
- 0x00718178,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718179,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071817a,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071817b,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x0071817c,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x0071817d,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x0071817e,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071817f,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718180,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718181,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x00718182,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x00718183,
- 0x0000002d,
- 0xd16807e4,
- 0x000f0002,
- 0x00718184,
- 0x00000049,
- 0xd14033e3,
- 0x000f0002,
- 0x00718185,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718186,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718187,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718188,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718189,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071818a,
- 0x00000069,
- 0xd8003162,
- 0x000f0002,
- 0x0071818b,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x0071818c,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071818d,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x0071818e,
- 0x00000008,
- 0x22790081,
- 0x000f0002,
- 0x0071818f,
- 0x00000049,
- 0xd600060c,
- 0x000f0002,
- 0x00718190,
- 0x0000002f,
- 0xd6810106,
- 0x000f0002,
- 0x00718191,
- 0x0000003f,
- 0xd4800002,
- 0x000f0002,
- 0x00718192,
- 0x0000003f,
- 0xd4800084,
- 0x000f0002,
- 0x00718193,
- 0x0000003f,
- 0xd5000102,
- 0x000f0002,
- 0x00718194,
- 0x0000003f,
- 0xd5000184,
- 0x000f0002,
- 0x00718195,
- 0x0000003f,
- 0xd5800202,
- 0x000f0002,
- 0x00718196,
- 0x0000003f,
- 0xd5800204,
- 0x000f0002,
- 0x00718197,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718198,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718199,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x0071819a,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x0071819b,
- 0x00000069,
- 0xd80034e9,
- 0x000f0002,
- 0x0071819c,
- 0x00000069,
- 0xd800356a,
- 0x000f0002,
- 0x0071819d,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x0071819e,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071819f,
- 0x00000041,
- 0xd48034eb,
- 0x000f0002,
- 0x007181a0,
- 0x00000041,
- 0xd500356b,
- 0x000f0002,
- 0x007181a1,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181a2,
- 0x00000018,
- 0x37eb0081,
- 0x000f0002,
- 0x007181a3,
- 0x00000049,
- 0xd6003b0d,
- 0x000f0002,
- 0x007181a4,
- 0x00000049,
- 0xd6803b07,
- 0x000f0002,
- 0x007181a5,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x007181a6,
- 0x00000049,
- 0xdd003666,
- 0x000f0002,
- 0x007181a7,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181a8,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181a9,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181aa,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181ab,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181ac,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181ad,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181ae,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181af,
- 0x00000061,
- 0xf600046c,
- 0x000f0002,
- 0x007181b0,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181b1,
- 0x00000018,
- 0x37eb0081,
- 0x000f0002,
- 0x007181b2,
- 0x00000049,
- 0xd6003b0e,
- 0x000f0002,
- 0x007181b3,
- 0x00000049,
- 0xd6803b08,
- 0x000f0002,
- 0x007181b4,
- 0x00000049,
- 0xd5803b09,
- 0x000f0002,
- 0x007181b5,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181b6,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x007181b7,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x007181b8,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x007181b9,
- 0x00000069,
- 0xd80035eb,
- 0x000f0002,
- 0x007181ba,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x007181bb,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x007181bc,
- 0x00000041,
- 0xd60007ec,
- 0x000f0002,
- 0x007181bd,
- 0x00000041,
- 0xd580086b,
- 0x000f0002,
- 0x007181be,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181bf,
- 0x00000018,
- 0x37ed0081,
- 0x000f0002,
- 0x007181c0,
- 0x0000003f,
- 0xd4ffff80,
- 0x000f0002,
- 0x007181c1,
- 0x0000003f,
- 0xd5020004,
- 0x000f0002,
- 0x007181c2,
- 0x0000003f,
- 0xd5180001,
- 0x000f0002,
- 0x007181c3,
- 0x00000049,
- 0xdd003b6a,
- 0x000f0002,
- 0x007181c4,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x007181c5,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x007181c6,
- 0x00000021,
- 0xd50000ea,
- 0x000f0002,
- 0x007181c7,
- 0x00000049,
- 0xdd0e3b6a,
- 0x000f0002,
- 0x007181c8,
- 0x00000035,
- 0xd104007a,
- 0x000f0002,
- 0x007181c9,
- 0x00000018,
- 0x37f50081,
- 0x000f0002,
- 0x007181ca,
- 0x0000003f,
- 0xd4ffff80,
- 0x000f0002,
- 0x007181cb,
- 0x0000003f,
- 0xd5040004,
- 0x000f0002,
- 0x007181cc,
- 0x0000003f,
- 0xd5180001,
- 0x000f0002,
- 0x007181cd,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x007181ce,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x007181cf,
- 0x00000049,
- 0xdd003b6a,
- 0x000f0002,
- 0x007181d0,
- 0x00000051,
- 0xf50000ea,
- 0x000f0002,
- 0x007181d1,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181d2,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181d3,
- 0x00000049,
- 0xdd0e3b6a,
- 0x000f0002,
- 0x007181d4,
- 0x00000035,
- 0xd104807a,
- 0x000f0002,
- 0x007181d5,
- 0x00000018,
- 0x37f50081,
- 0x000f0002,
- 0x007181d6,
- 0x0000003f,
- 0xc77f7f04,
- 0x000f0002,
- 0x007181d7,
- 0x0000003f,
- 0xc77f7f01,
- 0x000f0002,
- 0x007181d8,
- 0x0000003f,
- 0xd6804000,
- 0x000f0002,
- 0x007181d9,
- 0x0000003f,
- 0xd103c000,
- 0x000f0002,
- 0x007181da,
- 0x00000025,
- 0xde2000e2,
- 0x000f0002,
- 0x007181db,
- 0x00000049,
- 0xde80274e,
- 0x000f0002,
- 0x007181dc,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181dd,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181de,
- 0x00000035,
- 0xd10000e2,
- 0x000f0002,
- 0x007181df,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181e0,
- 0x00000018,
- 0x37f50081,
- 0x000f0002,
- 0x007181e1,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x007181e2,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007181e3,
- 0x00000069,
- 0xdd001d3a,
- 0x000f0002,
- 0x007181e4,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007181e5,
- 0x0000007d,
- 0xc760a713,
- 0x000f0002,
- 0x007181e6,
- 0x00000031,
- 0xc0800041,
- 0x000f0002,
- 0x007181e7,
- 0x00000031,
- 0xc4000048,
- 0x000f0002,
- 0x007181e8,
- 0x00000031,
- 0xc2800045,
- 0x000f0002,
- 0x007181e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f4,
- 0x0000002d,
- 0xdb000000,
- 0x000f0002,
- 0x007181f5,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x007181f6,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007181f7,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007181f8,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007181f9,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007181fa,
- 0x0000002d,
- 0xd3800000,
- 0x000f0002,
- 0x007181fb,
- 0x0000003f,
- 0xdd000404,
- 0x000f0002,
- 0x007181fc,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007181fd,
- 0x00000069,
- 0xdd000a14,
- 0x000f0002,
- 0x007181fe,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007181ff,
- 0x00000049,
- 0xd1043394,
- 0x000f0002,
- 0x00718200,
- 0x0000003f,
- 0xdd000484,
- 0x000f0002,
- 0x00718201,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718202,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x00718203,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718204,
- 0x0000003f,
- 0xdd000504,
- 0x000f0002,
- 0x00718205,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718206,
- 0x00000069,
- 0xdd000a95,
- 0x000f0002,
- 0x00718207,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718208,
- 0x00000049,
- 0xd1043395,
- 0x000f0002,
- 0x00718209,
- 0x0000003f,
- 0xdd000584,
- 0x000f0002,
- 0x0071820a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071820b,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x0071820c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071820d,
- 0x0000003f,
- 0xdd000604,
- 0x000f0002,
- 0x0071820e,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071820f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718210,
- 0x0000003f,
- 0xdd000084,
- 0x000f0002,
- 0x00718211,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718212,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718213,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718214,
- 0x00000069,
- 0xdd000b16,
- 0x000f0002,
- 0x00718215,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718216,
- 0x0000003f,
- 0xdd001004,
- 0x000f0002,
- 0x00718217,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718218,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718219,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071821a,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071821b,
- 0x0000003f,
- 0xdd001084,
- 0x000f0002,
- 0x0071821c,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071821d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071821e,
- 0x0000003f,
- 0xdd018004,
- 0x000f0002,
- 0x0071821f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718220,
- 0x0000003f,
- 0xdd001104,
- 0x000f0002,
- 0x00718221,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718222,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718223,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718224,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718225,
- 0x0000003f,
- 0xdd001184,
- 0x000f0002,
- 0x00718226,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718227,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718228,
- 0x0000003f,
- 0xdd160004,
- 0x000f0002,
- 0x00718229,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071822a,
- 0x0000003f,
- 0xdd001204,
- 0x000f0002,
- 0x0071822b,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071822c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071822d,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071822e,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071822f,
- 0x0000003f,
- 0xdd001284,
- 0x000f0002,
- 0x00718230,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718231,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718232,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718233,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718234,
- 0x0000003f,
- 0xdd001304,
- 0x000f0002,
- 0x00718235,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718236,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718237,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718238,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718239,
- 0x0000003f,
- 0xdd001384,
- 0x000f0002,
- 0x0071823a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071823b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071823c,
- 0x0000003f,
- 0xdd050004,
- 0x000f0002,
- 0x0071823d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071823e,
- 0x0000003f,
- 0xdd002004,
- 0x000f0002,
- 0x0071823f,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718240,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718241,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718242,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718243,
- 0x0000003f,
- 0xdd002084,
- 0x000f0002,
- 0x00718244,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718245,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718246,
- 0x0000003f,
- 0xdd019004,
- 0x000f0002,
- 0x00718247,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718248,
- 0x0000003f,
- 0xdd002104,
- 0x000f0002,
- 0x00718249,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071824a,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071824b,
- 0x0000003f,
- 0xdd000084,
- 0x000f0002,
- 0x0071824c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071824d,
- 0x0000003f,
- 0xdd002184,
- 0x000f0002,
- 0x0071824e,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071824f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718250,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718251,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718252,
- 0x0000003f,
- 0xdd002204,
- 0x000f0002,
- 0x00718253,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718254,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718255,
- 0x0000003f,
- 0xdd000284,
- 0x000f0002,
- 0x00718256,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718257,
- 0x0000003f,
- 0xdd002284,
- 0x000f0002,
- 0x00718258,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718259,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071825a,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071825b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071825c,
- 0x0000003f,
- 0xdd002304,
- 0x000f0002,
- 0x0071825d,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071825e,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071825f,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718260,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718261,
- 0x0000003f,
- 0xdd001804,
- 0x000f0002,
- 0x00718262,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718263,
- 0x00000069,
- 0xdd000b97,
- 0x000f0002,
- 0x00718264,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718265,
- 0x00000049,
- 0xd1043397,
- 0x000f0002,
- 0x00718266,
- 0x0000003f,
- 0xdd001884,
- 0x000f0002,
- 0x00718267,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718268,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x00718269,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071826a,
- 0x0000003f,
- 0xdd001904,
- 0x000f0002,
- 0x0071826b,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071826c,
- 0x00000069,
- 0xdd000c18,
- 0x000f0002,
- 0x0071826d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071826e,
- 0x00000049,
- 0xd1043398,
- 0x000f0002,
- 0x0071826f,
- 0x0000003f,
- 0xdd001984,
- 0x000f0002,
- 0x00718270,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718271,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x00718272,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718273,
- 0x0000003f,
- 0xdd001a04,
- 0x000f0002,
- 0x00718274,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718275,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718276,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718277,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718278,
- 0x0000003f,
- 0xdd001a84,
- 0x000f0002,
- 0x00718279,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071827a,
- 0x00000069,
- 0xdd000b16,
- 0x000f0002,
- 0x0071827b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071827c,
- 0x0000003f,
- 0xdd001c04,
- 0x000f0002,
- 0x0071827d,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071827e,
- 0x00000069,
- 0xdd000c99,
- 0x000f0002,
- 0x0071827f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718280,
- 0x0000003f,
- 0xdd001c84,
- 0x000f0002,
- 0x00718281,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718282,
- 0x00000069,
- 0xdd000d1a,
- 0x000f0002,
- 0x00718283,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718284,
- 0x0000003f,
- 0xdd001d04,
- 0x000f0002,
- 0x00718285,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718286,
- 0x00000069,
- 0xdd000d9b,
- 0x000f0002,
- 0x00718287,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718288,
- 0x00000049,
- 0xd104339b,
- 0x000f0002,
- 0x00718289,
- 0x0000003f,
- 0xdd001d84,
- 0x000f0002,
- 0x0071828a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071828b,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x0071828c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071828d,
- 0x0000003f,
- 0xdd001e04,
- 0x000f0002,
- 0x0071828e,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071828f,
- 0x00000069,
- 0xdd000e1c,
- 0x000f0002,
- 0x00718290,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718291,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718292,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718293,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718294,
- 0x0000003f,
- 0xdd000f04,
- 0x000f0002,
- 0x00718295,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718296,
- 0x0000007d,
- 0xc760a713,
- 0x000f0002,
- 0x00718297,
- 0x00000031,
- 0xc0800041,
- 0x000f0002,
- 0x00718298,
- 0x00000031,
- 0xc4000048,
- 0x000f0002,
- 0x00718299,
- 0x00000031,
- 0xc2800045,
- 0x000f0002,
- 0x0071829a,
- 0x00000031,
- 0xd680006d,
-/* BRDX_INIT_SDRAM */
- 0x000f000f,
- 0x00700064,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000040,
- 0x00000100,
- 0x00000400,
- 0x00000064,
- 0x00000054,
- 0x00000000,
- 0x00002400,
- 0x00002800,
- 0x00000400,
- 0x00002880,
- 0x00000180,
- 0x00000003,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000051,
- 0x0000017d,
- 0x00000008,
- 0x00000051,
- 0x0000005d,
- 0x00000000,
- 0x00000009,
- 0x00005000,
- 0x00000000,
- 0x00000000,
-/* BRDX_INIT */
- 0x000f000f,
- 0x007001f4,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000040,
- 0x00000100,
- 0x00000400,
- 0x00000064,
- 0x00000054,
- 0x00000000,
- 0x00002400,
- 0x00002800,
- 0x00000400,
- 0x00002880,
- 0x00000180,
- 0x00000003,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000051,
- 0x0000017d,
- 0x00000008,
- 0x00000051,
- 0x0000005d,
- 0x00000000,
- 0x00000009,
- 0x00005000,
- 0x00000000,
- 0x00000000,
-/* ZERO_INIT */
- 0x000f0002,
- 0x00700000,
- 0x00000001,
- 0x00000000,
-/* ZERO_INIT */
- 0x000f0002,
- 0x00700000,
- 0x00000001,
- 0x00000000,
-/* Loading operational Firmware */
- 0x000f0002,
- 0x00718000,
- 0x00000025,
- 0xdd0e0002,
- 0x000f0002,
- 0x00718001,
- 0x00000004,
- 0x01d13b76,
- 0x000f0002,
- 0x00718002,
- 0x00000025,
- 0xdd0e0082,
- 0x000f0002,
- 0x00718003,
- 0x00000004,
- 0x02893b76,
- 0x000f0002,
- 0x00718004,
- 0x00000025,
- 0xdd0e0102,
- 0x000f0002,
- 0x00718005,
- 0x00000004,
- 0x02853b76,
- 0x000f0002,
- 0x00718006,
- 0x00000025,
- 0xdd0e0182,
- 0x000f0002,
- 0x00718007,
- 0x00000004,
- 0x03fd3b76,
- 0x000f0002,
- 0x00718008,
- 0x00000009,
- 0xcf813b76,
- 0x000f0002,
- 0x00718009,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718010,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718011,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718012,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718013,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718014,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718015,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718016,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718017,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718018,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718019,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718020,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718021,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718022,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718023,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718024,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718025,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718026,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718027,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718028,
- 0x00000049,
- 0xc0003b00,
- 0x000f0002,
- 0x00718029,
- 0x00000049,
- 0xc0803b02,
- 0x000f0002,
- 0x0071802a,
- 0x00000049,
- 0xc1003b03,
- 0x000f0002,
- 0x0071802b,
- 0x00000049,
- 0xc1803b04,
- 0x000f0002,
- 0x0071802c,
- 0x00000029,
- 0xdf600076,
- 0x000f0002,
- 0x0071802d,
- 0x00000049,
- 0xdf443b7d,
- 0x000f0002,
- 0x0071802e,
- 0x00000079,
- 0xfd609076,
- 0x000f0002,
- 0x0071802f,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718030,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718031,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718032,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718033,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718034,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718035,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718036,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718037,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718038,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718039,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718040,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718041,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718042,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718043,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718044,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718045,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718046,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718047,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718048,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718049,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718050,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718051,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718052,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718053,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718054,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718055,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718056,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718057,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718058,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718059,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718060,
- 0x0000003f,
- 0xdf000003,
- 0x000f0002,
- 0x00718061,
- 0x0000002d,
- 0xdde00f81,
- 0x000f0002,
- 0x00718062,
- 0x0000003f,
- 0xdd800283,
- 0x000f0002,
- 0x00718063,
- 0x0000002d,
- 0xdd040180,
- 0x000f0002,
- 0x00718064,
- 0x0000007d,
- 0xfd150080,
- 0x000f0002,
- 0x00718065,
- 0x0000007a,
- 0x10203b76,
- 0x000f0002,
- 0x00718066,
- 0x0000007a,
- 0x30207b76,
- 0x000f0002,
- 0x00718067,
- 0x00000021,
- 0xd0240060,
- 0x000f0002,
- 0x00718068,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718069,
- 0x0000003f,
- 0xdd400281,
- 0x000f0002,
- 0x0071806a,
- 0x00000079,
- 0xdd31bb03,
- 0x000f0002,
- 0x0071806b,
- 0x00000079,
- 0xdd31fb04,
- 0x000f0002,
- 0x0071806c,
- 0x00000079,
- 0xdd31bb76,
- 0x000f0002,
- 0x0071806d,
- 0x00000079,
- 0xdd31fb76,
- 0x000f0002,
- 0x0071806e,
- 0x00000079,
- 0xfd210101,
- 0x000f0002,
- 0x0071806f,
- 0x0000007d,
- 0xfd2b4081,
- 0x000f0002,
- 0x00718070,
- 0x00000040,
- 0x3d003002,
- 0x000f0002,
- 0x00718071,
- 0x00000048,
- 0x1d003b02,
- 0x000f0002,
- 0x00718072,
- 0x00000079,
- 0xdd217b76,
- 0x000f0002,
- 0x00718073,
- 0x0000002d,
- 0xdd04057f,
- 0x000f0002,
- 0x00718074,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x00718075,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718076,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718077,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718078,
- 0x00000021,
- 0xe3371f76,
- 0x000f0002,
- 0x00718079,
- 0x00000049,
- 0xdd003b79,
- 0x000f0002,
- 0x0071807a,
- 0x00000079,
- 0xdd21bb76,
- 0x000f0002,
- 0x0071807b,
- 0x00000049,
- 0xdd003b79,
- 0x000f0002,
- 0x0071807c,
- 0x00000079,
- 0xdd21bb76,
- 0x000f0002,
- 0x0071807d,
- 0x00000049,
- 0xdd003b79,
- 0x000f0002,
- 0x0071807e,
- 0x00000079,
- 0xdd21bb76,
- 0x000f0002,
- 0x0071807f,
- 0x00000079,
- 0xfd609076,
- 0x000f0002,
- 0x00718080,
- 0x00000079,
- 0xdd21fb76,
- 0x000f0002,
- 0x00718081,
- 0x0000003f,
- 0xdf000083,
- 0x000f0002,
- 0x00718082,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718083,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718084,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718085,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718086,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718087,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718088,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718089,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718090,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718091,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718092,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718093,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718094,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718095,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718096,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718097,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718098,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718099,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180a0,
- 0x0000002d,
- 0xd0080803,
- 0x000f0002,
- 0x007180a1,
- 0x00000008,
- 0x21b5fb76,
- 0x000f0002,
- 0x007180a2,
- 0x00000079,
- 0xdd010081,
- 0x000f0002,
- 0x007180a3,
- 0x00000079,
- 0xdd018102,
- 0x000f0002,
- 0x007180a4,
- 0x0000007d,
- 0xfd018083,
- 0x000f0002,
- 0x007180a5,
- 0x00000079,
- 0xd0903b76,
- 0x000f0002,
- 0x007180a6,
- 0x00000049,
- 0xd0583b7a,
- 0x000f0002,
- 0x007180a7,
- 0x00000049,
- 0xd2043b00,
- 0x000f0002,
- 0x007180a8,
- 0x0000003d,
- 0xdd400003,
- 0x000f0002,
- 0x007180a9,
- 0x00000024,
- 0x32000264,
- 0x000f0002,
- 0x007180aa,
- 0x0000003d,
- 0xdd7ff803,
- 0x000f0002,
- 0x007180ab,
- 0x00000029,
- 0xd020017a,
- 0x000f0002,
- 0x007180ac,
- 0x00000049,
- 0xd0a43b0e,
- 0x000f0002,
- 0x007180ad,
- 0x0000002d,
- 0xdd0442ff,
- 0x000f0002,
- 0x007180ae,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x007180af,
- 0x0000002d,
- 0xdd060082,
- 0x000f0002,
- 0x007180b0,
- 0x00000038,
- 0x300001e0,
- 0x000f0002,
- 0x007180b1,
- 0x00000039,
- 0xd0000160,
- 0x000f0002,
- 0x007180b2,
- 0x00000079,
- 0xd1b13b7c,
- 0x000f0002,
- 0x007180b3,
- 0x0000002d,
- 0xdde00fe3,
- 0x000f0002,
- 0x007180b4,
- 0x00000049,
- 0xd08030e4,
- 0x000f0002,
- 0x007180b5,
- 0x00000079,
- 0xdd317b7c,
- 0x000f0002,
- 0x007180b6,
- 0x00000079,
- 0xdd313b7c,
- 0x000f0002,
- 0x007180b7,
- 0x0000007d,
- 0xfd374082,
- 0x000f0002,
- 0x007180b8,
- 0x00000008,
- 0x017d3b76,
- 0x000f0002,
- 0x007180b9,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180ba,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180bb,
- 0x00000049,
- 0xdd000387,
- 0x000f0002,
- 0x007180bc,
- 0x00000079,
- 0xdd310408,
- 0x000f0002,
- 0x007180bd,
- 0x00000079,
- 0xdd317d7a,
- 0x000f0002,
- 0x007180be,
- 0x00000049,
- 0xd3003b7c,
- 0x000f0002,
- 0x007180bf,
- 0x00000079,
- 0xd381bb7c,
- 0x000f0002,
- 0x007180c0,
- 0x0000007f,
- 0xd101b27c,
- 0x000f0002,
- 0x007180c1,
- 0x00000048,
- 0x51003264,
- 0x000f0002,
- 0x007180c2,
- 0x0000003d,
- 0xdd400003,
- 0x000f0002,
- 0x007180c3,
- 0x00000008,
- 0x01953162,
- 0x000f0002,
- 0x007180c4,
- 0x00000021,
- 0xd3000666,
- 0x000f0002,
- 0x007180c5,
- 0x00000020,
- 0x538000e7,
- 0x000f0002,
- 0x007180c6,
- 0x0000003f,
- 0xdd000800,
- 0x000f0002,
- 0x007180c7,
- 0x00000079,
- 0xdd01b366,
- 0x000f0002,
- 0x007180c8,
- 0x00000079,
- 0xdd01b3e7,
- 0x000f0002,
- 0x007180c9,
- 0x00000075,
- 0xf1018662,
- 0x000f0002,
- 0x007180ca,
- 0x00000075,
- 0xd201b164,
- 0x000f0002,
- 0x007180cb,
- 0x00000078,
- 0x1d007b76,
- 0x000f0002,
- 0x007180cc,
- 0x00000025,
- 0xdd0001e3,
- 0x000f0002,
- 0x007180cd,
- 0x00000008,
- 0x01b13162,
- 0x000f0002,
- 0x007180ce,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180cf,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180d0,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180d1,
- 0x00000021,
- 0xe3379f63,
- 0x000f0002,
- 0x007180d2,
- 0x00000049,
- 0xd3003b7c,
- 0x000f0002,
- 0x007180d3,
- 0x00000079,
- 0xd381bb7c,
- 0x000f0002,
- 0x007180d4,
- 0x0000007f,
- 0xd101b27c,
- 0x000f0002,
- 0x007180d5,
- 0x00000048,
- 0x51003264,
- 0x000f0002,
- 0x007180d6,
- 0x00000075,
- 0xd201b164,
- 0x000f0002,
- 0x007180d7,
- 0x00000078,
- 0x1d007b76,
- 0x000f0002,
- 0x007180d8,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180d9,
- 0x00000079,
- 0xdd01c081,
- 0x000f0002,
- 0x007180da,
- 0x00000079,
- 0xfd609076,
- 0x000f0002,
- 0x007180db,
- 0x0000002d,
- 0xdd080803,
- 0x000f0002,
- 0x007180dc,
- 0x00000078,
- 0x3d01c081,
- 0x000f0002,
- 0x007180dd,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e8,
- 0x00000049,
- 0xd18e3b03,
- 0x000f0002,
- 0x007180e9,
- 0x0000002f,
- 0xd18100e3,
- 0x000f0002,
- 0x007180ea,
- 0x0000003f,
- 0xd1801803,
- 0x000f0002,
- 0x007180eb,
- 0x00000049,
- 0xd1043b03,
- 0x000f0002,
- 0x007180ec,
- 0x0000003f,
- 0xdd800203,
- 0x000f0002,
- 0x007180ed,
- 0x00000049,
- 0xd2043b02,
- 0x000f0002,
- 0x007180ee,
- 0x00000049,
- 0xd2843b00,
- 0x000f0002,
- 0x007180ef,
- 0x00000025,
- 0xdd0000e2,
- 0x000f0002,
- 0x007180f0,
- 0x00000094,
- 0x00134162,
- 0x000f0002,
- 0x007180f1,
- 0x00000094,
- 0x000b4362,
- 0x000f0002,
- 0x007180f2,
- 0x00000094,
- 0x001548e2,
- 0x000f0002,
- 0x007180f3,
- 0x00000094,
- 0x001b4962,
- 0x000f0002,
- 0x007180f4,
- 0x00000094,
- 0x002f4076,
- 0x000f0002,
- 0x007180f5,
- 0x00000009,
- 0xcf813d7a,
- 0x000f0002,
- 0x007180f6,
- 0x0000001d,
- 0xfd2b80e5,
- 0x000f0002,
- 0x007180f7,
- 0x00000030,
- 0x31838063,
- 0x000f0002,
- 0x007180f8,
- 0x00000030,
- 0x11828063,
- 0x000f0002,
- 0x007180f9,
- 0x0000001d,
- 0xfd2580e5,
- 0x000f0002,
- 0x007180fa,
- 0x00000030,
- 0x31830063,
- 0x000f0002,
- 0x007180fb,
- 0x00000030,
- 0x11820063,
- 0x000f0002,
- 0x007180fc,
- 0x0000002f,
- 0xd18100e3,
- 0x000f0002,
- 0x007180fd,
- 0x0000001d,
- 0xfd0980e5,
- 0x000f0002,
- 0x007180fe,
- 0x00000030,
- 0x3183d363,
- 0x000f0002,
- 0x007180ff,
- 0x00000030,
- 0x1183d263,
- 0x000f0002,
- 0x00718100,
- 0x0000002f,
- 0xd18100e3,
- 0x000f0002,
- 0x00718101,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718102,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718103,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718104,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x00718105,
- 0x00000025,
- 0xd2000264,
- 0x000f0002,
- 0x00718106,
- 0x00000018,
- 0x7d77fd7a,
- 0x000f0002,
- 0x00718107,
- 0x00000049,
- 0xde203b63,
- 0x000f0002,
- 0x00718108,
- 0x00000049,
- 0xde803b79,
- 0x000f0002,
- 0x00718109,
- 0x00000021,
- 0xd18000e3,
- 0x000f0002,
- 0x0071810a,
- 0x00000009,
- 0xcf813d7a,
- 0x000f0002,
- 0x0071810b,
- 0x00000049,
- 0xdd0031e3,
- 0x000f0002,
- 0x0071810c,
- 0x00000069,
- 0xdd0e3b78,
- 0x000f0002,
- 0x0071810d,
- 0x00000061,
- 0xdd003b76,
- 0x000f0002,
- 0x0071810e,
- 0x0000003f,
- 0xdd000184,
- 0x000f0002,
- 0x0071810f,
- 0x0000003f,
- 0xdd000001,
- 0x000f0002,
- 0x00718110,
- 0x00000035,
- 0xdd0000fa,
- 0x000f0002,
- 0x00718111,
- 0x00000018,
- 0x3b7f3b76,
- 0x000f0002,
- 0x00718112,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718113,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718114,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718115,
- 0x00000021,
- 0xd18000e3,
- 0x000f0002,
- 0x00718116,
- 0x00000069,
- 0xdd043b79,
- 0x000f0002,
- 0x00718117,
- 0x00000061,
- 0xf18000e3,
- 0x000f0002,
- 0x00718118,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718119,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x0071811a,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x0071811b,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x0071811c,
- 0x00000025,
- 0xd2000264,
- 0x000f0002,
- 0x0071811d,
- 0x00000098,
- 0x605dbb76,
- 0x000f0002,
- 0x0071811e,
- 0x00000009,
- 0xcf813d7a,
- 0x000f0002,
- 0x0071811f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718120,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718121,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718122,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718123,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718124,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718125,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718126,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718127,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718128,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718129,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718130,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718131,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718132,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718133,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718134,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718135,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718136,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718137,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718138,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718139,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718140,
- 0x00000049,
- 0xd4083b01,
- 0x000f0002,
- 0x00718141,
- 0x00000009,
- 0xc28b3d7a,
- 0x000f0002,
- 0x00718142,
- 0x0000003f,
- 0xd4000380,
- 0x000f0002,
- 0x00718143,
- 0x00000009,
- 0xc28b3d7a,
- 0x000f0002,
- 0x00718144,
- 0x00000049,
- 0xd40e3b03,
- 0x000f0002,
- 0x00718145,
- 0x0000003f,
- 0xd6420000,
- 0x000f0002,
- 0x00718146,
- 0x0000002f,
- 0xd2814080,
- 0x000f0002,
- 0x00718147,
- 0x0000002d,
- 0xd2840365,
- 0x000f0002,
- 0x00718148,
- 0x0000003f,
- 0xd6800080,
- 0x000f0002,
- 0x00718149,
- 0x0000003f,
- 0xdd040004,
- 0x000f0002,
- 0x0071814a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071814b,
- 0x00000069,
- 0xdd003b6d,
- 0x000f0002,
- 0x0071814c,
- 0x00000069,
- 0xdd003b6d,
- 0x000f0002,
- 0x0071814d,
- 0x00000031,
- 0xd303d265,
- 0x000f0002,
- 0x0071814e,
- 0x00000049,
- 0xde403b66,
- 0x000f0002,
- 0x0071814f,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718150,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718151,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718152,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x00718153,
- 0x00000049,
- 0xd5803b7e,
- 0x000f0002,
- 0x00718154,
- 0x00000021,
- 0xde4000e6,
- 0x000f0002,
- 0x00718155,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718156,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718157,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718158,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x00718159,
- 0x00000049,
- 0xd5003b7e,
- 0x000f0002,
- 0x0071815a,
- 0x00000079,
- 0xdd013b76,
- 0x000f0002,
- 0x0071815b,
- 0x0000002d,
- 0xdd04407f,
- 0x000f0002,
- 0x0071815c,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x0071815d,
- 0x00000079,
- 0xdd01bb76,
- 0x000f0002,
- 0x0071815e,
- 0x00000075,
- 0xfd0180e8,
- 0x000f0002,
- 0x0071815f,
- 0x00000094,
- 0x00154168,
- 0x000f0002,
- 0x00718160,
- 0x00000094,
- 0x002544e8,
- 0x000f0002,
- 0x00718161,
- 0x00000094,
- 0x002341e8,
- 0x000f0002,
- 0x00718162,
- 0x00000094,
- 0x00174568,
- 0x000f0002,
- 0x00718163,
- 0x00000094,
- 0x00154268,
- 0x000f0002,
- 0x00718164,
- 0x00000094,
- 0x002742e8,
- 0x000f0002,
- 0x00718165,
- 0x00000094,
- 0x002d4368,
- 0x000f0002,
- 0x00718166,
- 0x00000094,
- 0x002d4468,
- 0x000f0002,
- 0x00718167,
- 0x00000094,
- 0x003343e8,
- 0x000f0002,
- 0x00718168,
- 0x00000004,
- 0x03973b76,
- 0x000f0002,
- 0x00718169,
- 0x0000000d,
- 0xe30dc165,
- 0x000f0002,
- 0x0071816a,
- 0x00000030,
- 0x32030076,
- 0x000f0002,
- 0x0071816b,
- 0x00000030,
- 0x12020076,
- 0x000f0002,
- 0x0071816c,
- 0x0000003f,
- 0xd4800000,
- 0x000f0002,
- 0x0071816d,
- 0x0000003f,
- 0xd1808000,
- 0x000f0002,
- 0x0071816e,
- 0x0000000d,
- 0xe33fc165,
- 0x000f0002,
- 0x0071816f,
- 0x00000030,
- 0x32046076,
- 0x000f0002,
- 0x00718170,
- 0x00000030,
- 0x12044076,
- 0x000f0002,
- 0x00718171,
- 0x0000003f,
- 0xd4828000,
- 0x000f0002,
- 0x00718172,
- 0x0000003f,
- 0xd1808000,
- 0x000f0002,
- 0x00718173,
- 0x0000000d,
- 0xe33fc165,
- 0x000f0002,
- 0x00718174,
- 0x00000030,
- 0x32042076,
- 0x000f0002,
- 0x00718175,
- 0x00000030,
- 0x12040076,
- 0x000f0002,
- 0x00718176,
- 0x0000003f,
- 0xd4820000,
- 0x000f0002,
- 0x00718177,
- 0x0000000d,
- 0xe363c165,
- 0x000f0002,
- 0x00718178,
- 0x00000030,
- 0x32032076,
- 0x000f0002,
- 0x00718179,
- 0x00000030,
- 0x12030076,
- 0x000f0002,
- 0x0071817a,
- 0x0000003f,
- 0xd4830000,
- 0x000f0002,
- 0x0071817b,
- 0x00000049,
- 0xd2803b76,
- 0x000f0002,
- 0x0071817c,
- 0x0000000d,
- 0xe30dc165,
- 0x000f0002,
- 0x0071817d,
- 0x00000030,
- 0x32038076,
- 0x000f0002,
- 0x0071817e,
- 0x00000030,
- 0x12028076,
- 0x000f0002,
- 0x0071817f,
- 0x0000003f,
- 0xd4810000,
- 0x000f0002,
- 0x00718180,
- 0x0000003f,
- 0xd6020000,
- 0x000f0002,
- 0x00718181,
- 0x0000003f,
- 0xd1810000,
- 0x000f0002,
- 0x00718182,
- 0x0000000d,
- 0xe33fc165,
- 0x000f0002,
- 0x00718183,
- 0x00000030,
- 0x32042076,
- 0x000f0002,
- 0x00718184,
- 0x00000030,
- 0x12040076,
- 0x000f0002,
- 0x00718185,
- 0x0000003f,
- 0xd4820000,
- 0x000f0002,
- 0x00718186,
- 0x00000041,
- 0xd48034eb,
- 0x000f0002,
- 0x00718187,
- 0x00000079,
- 0xdd01bb6a,
- 0x000f0002,
- 0x00718188,
- 0x00000079,
- 0xdd01bb76,
- 0x000f0002,
- 0x00718189,
- 0x0000003f,
- 0xd2001803,
- 0x000f0002,
- 0x0071818a,
- 0x0000003f,
- 0xd1810000,
- 0x000f0002,
- 0x0071818b,
- 0x00000075,
- 0xfd018063,
- 0x000f0002,
- 0x0071818c,
- 0x00000098,
- 0x80693b64,
- 0x000f0002,
- 0x0071818d,
- 0x00000051,
- 0xf20000e4,
- 0x000f0002,
- 0x0071818e,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x0071818f,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718190,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718191,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x00718192,
- 0x0000002d,
- 0xdd04407f,
- 0x000f0002,
- 0x00718193,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x00718194,
- 0x00000049,
- 0xd3c03b38,
- 0x000f0002,
- 0x00718195,
- 0x00000049,
- 0xdd003b64,
- 0x000f0002,
- 0x00718196,
- 0x00000051,
- 0xf20000e4,
- 0x000f0002,
- 0x00718197,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718198,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718199,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x0071819a,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x0071819b,
- 0x00000049,
- 0xd3a03b38,
- 0x000f0002,
- 0x0071819c,
- 0x00000019,
- 0xdd61bb76,
- 0x000f0002,
- 0x0071819d,
- 0x00000049,
- 0xdd003b67,
- 0x000f0002,
- 0x0071819e,
- 0x00000075,
- 0xf1818263,
- 0x000f0002,
- 0x0071819f,
- 0x00000041,
- 0xd48034eb,
- 0x000f0002,
- 0x007181a0,
- 0x00000079,
- 0xdd01bb6a,
- 0x000f0002,
- 0x007181a1,
- 0x00000079,
- 0xdd01bb76,
- 0x000f0002,
- 0x007181a2,
- 0x0000003f,
- 0xd2001803,
- 0x000f0002,
- 0x007181a3,
- 0x0000003f,
- 0xd1808000,
- 0x000f0002,
- 0x007181a4,
- 0x00000075,
- 0xfd018063,
- 0x000f0002,
- 0x007181a5,
- 0x00000098,
- 0x80373b64,
- 0x000f0002,
- 0x007181a6,
- 0x00000051,
- 0xf20000e4,
- 0x000f0002,
- 0x007181a7,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x007181a8,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007181a9,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181aa,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007181ab,
- 0x0000002d,
- 0xdd04407f,
- 0x000f0002,
- 0x007181ac,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x007181ad,
- 0x00000049,
- 0xd3803b38,
- 0x000f0002,
- 0x007181ae,
- 0x00000019,
- 0xdd6fbb76,
- 0x000f0002,
- 0x007181af,
- 0x00000049,
- 0xdd003b67,
- 0x000f0002,
- 0x007181b0,
- 0x00000075,
- 0xf1818263,
- 0x000f0002,
- 0x007181b1,
- 0x00000041,
- 0xd48034eb,
- 0x000f0002,
- 0x007181b2,
- 0x00000079,
- 0xdd01bb6a,
- 0x000f0002,
- 0x007181b3,
- 0x00000079,
- 0xdd01bb63,
- 0x000f0002,
- 0x007181b4,
- 0x00000075,
- 0xfd018063,
- 0x000f0002,
- 0x007181b5,
- 0x00000098,
- 0x80173b64,
- 0x000f0002,
- 0x007181b6,
- 0x00000049,
- 0xde403b64,
- 0x000f0002,
- 0x007181b7,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x007181b8,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007181b9,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181ba,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007181bb,
- 0x0000002d,
- 0xdd04407f,
- 0x000f0002,
- 0x007181bc,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x007181bd,
- 0x00000021,
- 0xd20000e4,
- 0x000f0002,
- 0x007181be,
- 0x00000019,
- 0xd3ef7b7e,
- 0x000f0002,
- 0x007181bf,
- 0x00000075,
- 0xf1818263,
- 0x000f0002,
- 0x007181c0,
- 0x0000003f,
- 0xd6800000,
- 0x000f0002,
- 0x007181c1,
- 0x0000003f,
- 0xdd040004,
- 0x000f0002,
- 0x007181c2,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007181c3,
- 0x00000069,
- 0xdd003b6d,
- 0x000f0002,
- 0x007181c4,
- 0x00000069,
- 0xdd003b6d,
- 0x000f0002,
- 0x007181c5,
- 0x0000003f,
- 0xdd000000,
- 0x000f0002,
- 0x007181c6,
- 0x0000002d,
- 0xdd540180,
- 0x000f0002,
- 0x007181c7,
- 0x00000079,
- 0xf3e08076,
- 0x000f0002,
- 0x007181c8,
- 0x00000049,
- 0xd600367a,
- 0x000f0002,
- 0x007181c9,
- 0x00000079,
- 0xdd01fb76,
- 0x000f0002,
- 0x007181ca,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181cb,
- 0x00000049,
- 0xdd003b03,
- 0x000f0002,
- 0x007181cc,
- 0x00000059,
- 0xfd003b76,
- 0x000f0002,
- 0x007181cd,
- 0x0000003f,
- 0xdd801c03,
- 0x000f0002,
- 0x007181ce,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181cf,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181d0,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181d1,
- 0x0000002d,
- 0xdd06027f,
- 0x000f0002,
- 0x007181d2,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x007181d3,
- 0x00000031,
- 0xd483886b,
- 0x000f0002,
- 0x007181d4,
- 0x00000079,
- 0xdd01bb6a,
- 0x000f0002,
- 0x007181d5,
- 0x00000079,
- 0xf1819076,
- 0x000f0002,
- 0x007181d6,
- 0x00000075,
- 0xfd018063,
- 0x000f0002,
- 0x007181d7,
- 0x00000098,
- 0x8053bb76,
- 0x000f0002,
- 0x007181d8,
- 0x00000019,
- 0xdd7f7b79,
- 0x000f0002,
- 0x007181d9,
- 0x00000075,
- 0xf1818263,
- 0x000f0002,
- 0x007181da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fe,
- 0x0000003f,
- 0xdd800203,
- 0x000f0002,
- 0x007181ff,
- 0x00000049,
- 0xd1843b02,
- 0x000f0002,
- 0x00718200,
- 0x00000049,
- 0xdd003b03,
- 0x000f0002,
- 0x00718201,
- 0x00000069,
- 0xdd003b7a,
- 0x000f0002,
- 0x00718202,
- 0x00000049,
- 0xdd003b79,
- 0x000f0002,
- 0x00718203,
- 0x00000065,
- 0xf1800263,
- 0x000f0002,
- 0x00718204,
- 0x00000018,
- 0x7d7d3b76,
- 0x000f0002,
- 0x00718205,
- 0x00000009,
- 0xcf813d7a,
- 0x000f0002,
- 0x00718206,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718207,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718208,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718209,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718210,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718211,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718212,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718213,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718214,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718215,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718216,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718217,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718218,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718219,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718220,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718221,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718222,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718223,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718224,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718225,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718226,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718227,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718228,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718229,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718230,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718231,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718232,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718233,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718234,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718235,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718236,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718237,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718238,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718239,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718240,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718241,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718242,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718243,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718244,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718245,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718246,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718247,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718248,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718249,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718250,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718251,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718252,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718253,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718254,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718255,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718256,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718257,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718258,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718259,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718260,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718261,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718262,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718263,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718264,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718265,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718266,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718267,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718268,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718269,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718270,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718271,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718272,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718273,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718274,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718275,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718276,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718277,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718278,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718279,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718280,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718281,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718282,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718283,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718284,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718285,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718286,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718287,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718288,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718289,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718290,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718291,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718292,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718293,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718294,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718295,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718296,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718297,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718298,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718299,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718300,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718301,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718302,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718303,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718304,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718305,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718306,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718307,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718308,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718309,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718310,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718311,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718312,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718313,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718314,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718315,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718316,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718317,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718318,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718319,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718320,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718321,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718322,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718323,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718324,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718325,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718326,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718327,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718328,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718329,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718330,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718331,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718332,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718333,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718334,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718335,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718336,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718337,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718338,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718339,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718340,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718341,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718342,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718343,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718344,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718345,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718346,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718347,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718348,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718349,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718350,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718351,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718352,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718353,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718354,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718355,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718356,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718357,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718358,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718359,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718360,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718361,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718362,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718363,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718364,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718365,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718366,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718367,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718368,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718369,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718370,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718371,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718372,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718373,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718374,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718375,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718376,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718377,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718378,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718379,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718380,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718381,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718382,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718383,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718384,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718385,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718386,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718387,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718388,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718389,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718390,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718391,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718392,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718393,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718394,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718395,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718396,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718397,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718398,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718399,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718400,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718401,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718402,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718403,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718404,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718405,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718406,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718407,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718408,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718409,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718410,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718411,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718412,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718413,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718414,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718415,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718416,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718417,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718418,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718419,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718420,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718421,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718422,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718423,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718424,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718425,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718426,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718427,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718428,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718429,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718430,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718431,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718432,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718433,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718434,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718435,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718436,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718437,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718438,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718439,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718440,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718441,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718442,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718443,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718444,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718445,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718446,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718447,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718448,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718449,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718450,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718451,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718452,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718453,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718454,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718455,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718456,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718457,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718458,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718459,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718460,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718461,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718462,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718463,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718464,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718465,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718466,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718467,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718468,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718469,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718470,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718471,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718472,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718473,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718474,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718475,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718476,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718477,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718478,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718479,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718480,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718481,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718482,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718483,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718484,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718485,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718486,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718487,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718488,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718489,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718490,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718491,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718492,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718493,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718494,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718495,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718496,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718497,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718498,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718499,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718500,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718501,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718502,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718503,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718504,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718505,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718506,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718507,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718508,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718509,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718510,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718511,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718512,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718513,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718514,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718515,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718516,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718517,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718518,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718519,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718520,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718521,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718522,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718523,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718524,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718525,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718526,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718527,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718528,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718529,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718530,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718531,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718532,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718533,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718534,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718535,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718536,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718537,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718538,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718539,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718540,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718541,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718542,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718543,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718544,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718545,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718546,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718547,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718548,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718549,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718550,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718551,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718552,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718553,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718554,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718555,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718556,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718557,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718558,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718559,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718560,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718561,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718562,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718563,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718564,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718565,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718566,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718567,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718568,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718569,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718570,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718571,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718572,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718573,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718574,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718575,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718576,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718577,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718578,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718579,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718580,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718581,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718582,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718583,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718584,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718585,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718586,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718587,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718588,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718589,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718590,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718591,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718592,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718593,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718594,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718595,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718596,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718597,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718598,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718599,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718600,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718601,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718602,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718603,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718604,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718605,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718606,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718607,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718608,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718609,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718610,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718611,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718612,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718613,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718614,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718615,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718616,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718617,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718618,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718619,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718620,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718621,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718622,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718623,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718624,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718625,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718626,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718627,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718628,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718629,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718630,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718631,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718632,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718633,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718634,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718635,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718636,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718637,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718638,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718639,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718640,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718641,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718642,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718643,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718644,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718645,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718646,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718647,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718648,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718649,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718650,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718651,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718652,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718653,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718654,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718655,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718656,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718657,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718658,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718659,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718660,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718661,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718662,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718663,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718664,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718665,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718666,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718667,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718668,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718669,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718670,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718671,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718672,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718673,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718674,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718675,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718676,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718677,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718678,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718679,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718680,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718681,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718682,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718683,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718684,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718685,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718686,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718687,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718688,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718689,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718690,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718691,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718692,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718693,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718694,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718695,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718696,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718697,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718698,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718699,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718700,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718701,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718702,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718703,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718704,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718705,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718706,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718707,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718708,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718709,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718710,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718711,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718712,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718713,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718714,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718715,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718716,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718717,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718718,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718719,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718720,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718721,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718722,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718723,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718724,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718725,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718726,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718727,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718728,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718729,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718730,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718731,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718732,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718733,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718734,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718735,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718736,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718737,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718738,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718739,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718740,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718741,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718742,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718743,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718744,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718745,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718746,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718747,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718748,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718749,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718750,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718751,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718752,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718753,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718754,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718755,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718756,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718757,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718758,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718759,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718760,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718761,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718762,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718763,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718764,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718765,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718766,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718767,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718768,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718769,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718770,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718771,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718772,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718773,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718774,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718775,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718776,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718777,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718778,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718779,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718780,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718781,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718782,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718783,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718784,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718785,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718786,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718787,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718788,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718789,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718790,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718791,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718792,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718793,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718794,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718795,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718796,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718797,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718798,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718799,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187c0,
- 0x00000079,
- 0xfd609076,
- 0x000f0002,
- 0x007187c1,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007187c2,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007187c3,
- 0x0000003d,
- 0xf780006f,
-/* FINISH INIT Descriptor */
- 0x000f0002,
- 0x807187c4,
- 0x0000003d,
- 0xf780006f,
-};
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5e2dbaee125..f7efcecc410 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4,7 +4,7 @@
* Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
* Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
* Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2005-2007 Broadcom Corporation.
+ * Copyright (C) 2005-2009 Broadcom Corporation.
*
* Firmware is:
* Derived from proprietary unpublished source code,
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.97"
-#define DRV_MODULE_RELDATE "December 10, 2008"
+#define DRV_MODULE_VERSION "3.98"
+#define DRV_MODULE_RELDATE "February 25, 2009"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -852,7 +852,7 @@ static int tg3_bmcr_reset(struct tg3 *tp)
}
udelay(10);
}
- if (limit <= 0)
+ if (limit < 0)
return -EBUSY;
return 0;
@@ -860,7 +860,7 @@ static int tg3_bmcr_reset(struct tg3 *tp)
static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
{
- struct tg3 *tp = (struct tg3 *)bp->priv;
+ struct tg3 *tp = bp->priv;
u32 val;
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
@@ -874,7 +874,7 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
{
- struct tg3 *tp = (struct tg3 *)bp->priv;
+ struct tg3 *tp = bp->priv;
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
return -EAGAIN;
@@ -1473,7 +1473,8 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable)
{
u32 reg;
- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
return;
reg = MII_TG3_MISC_SHDW_WREN |
@@ -1603,7 +1604,7 @@ static int tg3_wait_macro_done(struct tg3 *tp)
break;
}
}
- if (limit <= 0)
+ if (limit < 0)
return -EBUSY;
return 0;
@@ -2049,8 +2050,6 @@ static int tg3_setup_phy(struct tg3 *, int);
static void tg3_write_sig_post_reset(struct tg3 *, int);
static int tg3_halt_cpu(struct tg3 *, u32);
-static int tg3_nvram_lock(struct tg3 *);
-static void tg3_nvram_unlock(struct tg3 *);
static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
{
@@ -2107,6 +2106,194 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
}
/* tp->lock is held. */
+static int tg3_nvram_lock(struct tg3 *tp)
+{
+ if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+ int i;
+
+ if (tp->nvram_lock_cnt == 0) {
+ tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+ for (i = 0; i < 8000; i++) {
+ if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+ break;
+ udelay(20);
+ }
+ if (i == 8000) {
+ tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
+ return -ENODEV;
+ }
+ }
+ tp->nvram_lock_cnt++;
+ }
+ return 0;
+}
+
+/* tp->lock is held. */
+static void tg3_nvram_unlock(struct tg3 *tp)
+{
+ if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+ if (tp->nvram_lock_cnt > 0)
+ tp->nvram_lock_cnt--;
+ if (tp->nvram_lock_cnt == 0)
+ tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
+ }
+}
+
+/* tp->lock is held. */
+static void tg3_enable_nvram_access(struct tg3 *tp)
+{
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+ u32 nvaccess = tr32(NVRAM_ACCESS);
+
+ tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+ }
+}
+
+/* tp->lock is held. */
+static void tg3_disable_nvram_access(struct tg3 *tp)
+{
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+ u32 nvaccess = tr32(NVRAM_ACCESS);
+
+ tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
+ }
+}
+
+static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
+ u32 offset, u32 *val)
+{
+ u32 tmp;
+ int i;
+
+ if (offset > EEPROM_ADDR_ADDR_MASK || (offset % 4) != 0)
+ return -EINVAL;
+
+ tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
+ EEPROM_ADDR_DEVID_MASK |
+ EEPROM_ADDR_READ);
+ tw32(GRC_EEPROM_ADDR,
+ tmp |
+ (0 << EEPROM_ADDR_DEVID_SHIFT) |
+ ((offset << EEPROM_ADDR_ADDR_SHIFT) &
+ EEPROM_ADDR_ADDR_MASK) |
+ EEPROM_ADDR_READ | EEPROM_ADDR_START);
+
+ for (i = 0; i < 1000; i++) {
+ tmp = tr32(GRC_EEPROM_ADDR);
+
+ if (tmp & EEPROM_ADDR_COMPLETE)
+ break;
+ msleep(1);
+ }
+ if (!(tmp & EEPROM_ADDR_COMPLETE))
+ return -EBUSY;
+
+ *val = tr32(GRC_EEPROM_DATA);
+ return 0;
+}
+
+#define NVRAM_CMD_TIMEOUT 10000
+
+static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
+{
+ int i;
+
+ tw32(NVRAM_CMD, nvram_cmd);
+ for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
+ udelay(10);
+ if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
+ udelay(10);
+ break;
+ }
+ }
+
+ if (i == NVRAM_CMD_TIMEOUT)
+ return -EBUSY;
+
+ return 0;
+}
+
+static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
+{
+ if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+ (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+ (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+ !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+ (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+ addr = ((addr / tp->nvram_pagesize) <<
+ ATMEL_AT45DB0X1B_PAGE_POS) +
+ (addr % tp->nvram_pagesize);
+
+ return addr;
+}
+
+static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
+{
+ if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+ (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+ (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+ !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+ (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+ addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
+ tp->nvram_pagesize) +
+ (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
+
+ return addr;
+}
+
+/* NOTE: Data read in from NVRAM is byteswapped according to
+ * the byteswapping settings for all other register accesses.
+ * tg3 devices are BE devices, so on a BE machine, the data
+ * returned will be exactly as it is seen in NVRAM. On a LE
+ * machine, the 32-bit value will be byteswapped.
+ */
+static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+ int ret;
+
+ if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
+ return tg3_nvram_read_using_eeprom(tp, offset, val);
+
+ offset = tg3_nvram_phys_addr(tp, offset);
+
+ if (offset > NVRAM_ADDR_MSK)
+ return -EINVAL;
+
+ ret = tg3_nvram_lock(tp);
+ if (ret)
+ return ret;
+
+ tg3_enable_nvram_access(tp);
+
+ tw32(NVRAM_ADDR, offset);
+ ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
+ NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+ if (ret == 0)
+ *val = tr32(NVRAM_RDDATA);
+
+ tg3_disable_nvram_access(tp);
+
+ tg3_nvram_unlock(tp);
+
+ return ret;
+}
+
+/* Ensures NVRAM data is in bytestream format. */
+static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val)
+{
+ u32 v;
+ int res = tg3_nvram_read(tp, offset, &v);
+ if (!res)
+ *val = cpu_to_be32(v);
+ return res;
+}
+
+/* tp->lock is held. */
static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
{
u32 addr_high, addr_low;
@@ -2237,8 +2424,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
if (phyid != TG3_PHY_ID_BCMAC131) {
phyid &= TG3_PHY_OUI_MASK;
- if (phyid == TG3_PHY_OUI_1 &&
- phyid == TG3_PHY_OUI_2 &&
+ if (phyid == TG3_PHY_OUI_1 ||
+ phyid == TG3_PHY_OUI_2 ||
phyid == TG3_PHY_OUI_3)
do_low_power = true;
}
@@ -4338,6 +4525,13 @@ static int tg3_rx(struct tg3 *tp, int budget)
skb->ip_summed = CHECKSUM_NONE;
skb->protocol = eth_type_trans(skb, tp->dev);
+
+ if (len > (tp->dev->mtu + ETH_HLEN) &&
+ skb->protocol != htons(ETH_P_8021Q)) {
+ dev_kfree_skb(skb);
+ goto next_pkt;
+ }
+
#if TG3_VLAN_TAG_USED
if (tp->vlgrp != NULL &&
desc->type_flags & RXD_FLAG_VLAN) {
@@ -4460,7 +4654,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(!tg3_has_work(tp))) {
- netif_rx_complete(napi);
+ napi_complete(napi);
tg3_restart_ints(tp);
break;
}
@@ -4470,7 +4664,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
tx_recovery:
/* work_done is guaranteed to be less than budget. */
- netif_rx_complete(napi);
+ napi_complete(napi);
schedule_work(&tp->reset_task);
return work_done;
}
@@ -4519,7 +4713,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
if (likely(!tg3_irq_sync(tp)))
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
return IRQ_HANDLED;
}
@@ -4544,7 +4738,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
if (likely(!tg3_irq_sync(tp)))
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
return IRQ_RETVAL(1);
}
@@ -4586,7 +4780,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp))) {
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
} else {
/* No work, shared interrupt perhaps? re-enable
* interrupts, and flush that PCI write
@@ -4632,7 +4826,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
if (tg3_irq_sync(tp))
goto out;
- if (netif_rx_schedule_prep(&tp->napi)) {
+ 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
@@ -4640,7 +4834,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* if tg3_poll() is not scheduled.
*/
tp->last_tag = sblk->status_tag;
- __netif_rx_schedule(&tp->napi);
+ __napi_schedule(&tp->napi);
}
out:
return IRQ_RETVAL(handled);
@@ -5630,62 +5824,6 @@ static int tg3_abort_hw(struct tg3 *tp, int silent)
return err;
}
-/* tp->lock is held. */
-static int tg3_nvram_lock(struct tg3 *tp)
-{
- if (tp->tg3_flags & TG3_FLAG_NVRAM) {
- int i;
-
- if (tp->nvram_lock_cnt == 0) {
- tw32(NVRAM_SWARB, SWARB_REQ_SET1);
- for (i = 0; i < 8000; i++) {
- if (tr32(NVRAM_SWARB) & SWARB_GNT1)
- break;
- udelay(20);
- }
- if (i == 8000) {
- tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
- return -ENODEV;
- }
- }
- tp->nvram_lock_cnt++;
- }
- return 0;
-}
-
-/* tp->lock is held. */
-static void tg3_nvram_unlock(struct tg3 *tp)
-{
- if (tp->tg3_flags & TG3_FLAG_NVRAM) {
- if (tp->nvram_lock_cnt > 0)
- tp->nvram_lock_cnt--;
- if (tp->nvram_lock_cnt == 0)
- tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
- }
-}
-
-/* tp->lock is held. */
-static void tg3_enable_nvram_access(struct tg3 *tp)
-{
- if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
- !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
- }
-}
-
-/* tp->lock is held. */
-static void tg3_disable_nvram_access(struct tg3 *tp)
-{
- if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
- !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
- }
-}
-
static void tg3_ape_send_event(struct tg3 *tp, u32 event)
{
int i;
@@ -6823,7 +6961,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
__tg3_set_mac_addr(tp, 0);
/* MTU + ethernet header + FCS + optional VLAN tag */
- tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8);
+ tw32(MAC_RX_MTU_SIZE,
+ tp->dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
/* The slot time is changed by tg3_setup_phy if we
* run at gigabit with half duplex.
@@ -7535,11 +7674,58 @@ static int tg3_test_msi(struct tg3 *tp)
return err;
}
+static int tg3_request_firmware(struct tg3 *tp)
+{
+ const __be32 *fw_data;
+
+ if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) {
+ printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+ tp->dev->name, tp->fw_needed);
+ return -ENOENT;
+ }
+
+ fw_data = (void *)tp->fw->data;
+
+ /* Firmware blob starts with version numbers, followed by
+ * start address and _full_ length including BSS sections
+ * (which must be longer than the actual data, of course
+ */
+
+ tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */
+ if (tp->fw_len < (tp->fw->size - 12)) {
+ printk(KERN_ERR "%s: bogus length %d in \"%s\"\n",
+ tp->dev->name, tp->fw_len, tp->fw_needed);
+ release_firmware(tp->fw);
+ tp->fw = NULL;
+ return -EINVAL;
+ }
+
+ /* We no longer need firmware; we have it. */
+ tp->fw_needed = NULL;
+ return 0;
+}
+
static int tg3_open(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
int err;
+ if (tp->fw_needed) {
+ err = tg3_request_firmware(tp);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
+ if (err)
+ return err;
+ } else if (err) {
+ printk(KERN_WARNING "%s: TSO capability disabled.\n",
+ tp->dev->name);
+ tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
+ } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
+ printk(KERN_NOTICE "%s: TSO capability restored.\n",
+ tp->dev->name);
+ tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+ }
+ }
+
netif_carrier_off(tp->dev);
err = tg3_set_power_state(tp, PCI_D0);
@@ -8338,17 +8524,13 @@ static int tg3_get_eeprom_len(struct net_device *dev)
return tp->nvram_size;
}
-static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val);
-static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val);
-static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val);
-
static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
{
struct tg3 *tp = netdev_priv(dev);
int ret;
u8 *pd;
u32 i, offset, len, b_offset, b_count;
- __le32 val;
+ __be32 val;
if (tp->link_config.phy_is_low_power)
return -EAGAIN;
@@ -8367,7 +8549,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
/* i.e. offset=1 len=2 */
b_count = len;
}
- ret = tg3_nvram_read_le(tp, offset-b_offset, &val);
+ ret = tg3_nvram_read_be32(tp, offset-b_offset, &val);
if (ret)
return ret;
memcpy(data, ((char*)&val) + b_offset, b_count);
@@ -8379,7 +8561,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
/* read bytes upto the last 4 byte boundary */
pd = &data[eeprom->len];
for (i = 0; i < (len - (len & 3)); i += 4) {
- ret = tg3_nvram_read_le(tp, offset + i, &val);
+ ret = tg3_nvram_read_be32(tp, offset + i, &val);
if (ret) {
eeprom->len += i;
return ret;
@@ -8393,7 +8575,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
pd = &data[eeprom->len];
b_count = len & 3;
b_offset = offset + len - b_count;
- ret = tg3_nvram_read_le(tp, b_offset, &val);
+ ret = tg3_nvram_read_be32(tp, b_offset, &val);
if (ret)
return ret;
memcpy(pd, &val, b_count);
@@ -8410,7 +8592,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
int ret;
u32 offset, len, b_offset, odd_len;
u8 *buf;
- __le32 start, end;
+ __be32 start, end;
if (tp->link_config.phy_is_low_power)
return -EAGAIN;
@@ -8423,7 +8605,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
if ((b_offset = (offset & 3))) {
/* adjustments to start on required 4 byte boundary */
- ret = tg3_nvram_read_le(tp, offset-b_offset, &start);
+ ret = tg3_nvram_read_be32(tp, offset-b_offset, &start);
if (ret)
return ret;
len += b_offset;
@@ -8437,7 +8619,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
/* adjustments to end on required 4 byte boundary */
odd_len = 1;
len = (len + 3) & ~3;
- ret = tg3_nvram_read_le(tp, offset+len-4, &end);
+ ret = tg3_nvram_read_be32(tp, offset+len-4, &end);
if (ret)
return ret;
}
@@ -8496,7 +8678,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->duplex = tp->link_config.active_duplex;
}
cmd->phy_address = PHY_ADDR;
- cmd->transceiver = 0;
+ cmd->transceiver = XCVR_INTERNAL;
cmd->autoneg = tp->link_config.autoneg;
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
@@ -8513,26 +8695,58 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
}
- if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
- /* These are the only valid advertisement bits allowed. */
- if (cmd->autoneg == AUTONEG_ENABLE &&
- (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_Autoneg |
- ADVERTISED_FIBRE)))
- return -EINVAL;
- /* Fiber can only do SPEED_1000. */
- else if ((cmd->autoneg != AUTONEG_ENABLE) &&
- (cmd->speed != SPEED_1000))
- return -EINVAL;
- /* Copper cannot force SPEED_1000. */
- } else if ((cmd->autoneg != AUTONEG_ENABLE) &&
- (cmd->speed == SPEED_1000))
+ if (cmd->autoneg != AUTONEG_ENABLE &&
+ cmd->autoneg != AUTONEG_DISABLE)
return -EINVAL;
- else if ((cmd->speed == SPEED_1000) &&
- (tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+
+ if (cmd->autoneg == AUTONEG_DISABLE &&
+ cmd->duplex != DUPLEX_FULL &&
+ cmd->duplex != DUPLEX_HALF)
return -EINVAL;
+ if (cmd->autoneg == AUTONEG_ENABLE) {
+ u32 mask = ADVERTISED_Autoneg |
+ ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause;
+
+ if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+ mask |= ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full;
+
+ if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+ mask |= ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_TP;
+ else
+ mask |= ADVERTISED_FIBRE;
+
+ if (cmd->advertising & ~mask)
+ return -EINVAL;
+
+ mask &= (ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full);
+
+ cmd->advertising &= mask;
+ } else {
+ if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
+ if (cmd->speed != SPEED_1000)
+ return -EINVAL;
+
+ if (cmd->duplex != DUPLEX_FULL)
+ return -EINVAL;
+ } else {
+ if (cmd->speed != SPEED_100 &&
+ cmd->speed != SPEED_10)
+ return -EINVAL;
+ }
+ }
+
tg3_full_lock(tp, 0);
tp->link_config.autoneg = cmd->autoneg;
@@ -8977,10 +9191,10 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
static int tg3_test_nvram(struct tg3 *tp)
{
u32 csum, magic;
- __le32 *buf;
+ __be32 *buf;
int i, j, k, err = 0, size;
- if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+ if (tg3_nvram_read(tp, 0, &magic) != 0)
return -EIO;
if (magic == TG3_EEPROM_MAGIC)
@@ -9014,14 +9228,15 @@ static int tg3_test_nvram(struct tg3 *tp)
err = -EIO;
for (i = 0, j = 0; i < size; i += 4, j++) {
- if ((err = tg3_nvram_read_le(tp, i, &buf[j])) != 0)
+ err = tg3_nvram_read_be32(tp, i, &buf[j]);
+ if (err)
break;
}
if (i < size)
goto out;
/* Selfboot format */
- magic = swab32(le32_to_cpu(buf[0]));
+ magic = be32_to_cpu(buf[0]);
if ((magic & TG3_EEPROM_MAGIC_FW_MSK) ==
TG3_EEPROM_MAGIC_FW) {
u8 *buf8 = (u8 *) buf, csum8 = 0;
@@ -9050,7 +9265,7 @@ static int tg3_test_nvram(struct tg3 *tp)
if ((magic & TG3_EEPROM_MAGIC_HW_MSK) ==
TG3_EEPROM_MAGIC_HW) {
u8 data[NVRAM_SELFBOOT_DATA_SIZE];
- u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
+ u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
u8 *buf8 = (u8 *) buf;
/* Separate the parity bits and the data bytes. */
@@ -9093,13 +9308,13 @@ static int tg3_test_nvram(struct tg3 *tp)
/* Bootstrap checksum at offset 0x10 */
csum = calc_crc((unsigned char *) buf, 0x10);
- if(csum != le32_to_cpu(buf[0x10/4]))
+ if (csum != be32_to_cpu(buf[0x10/4]))
goto out;
/* Manufacturing block starts at offset 0x74, checksum at 0xfc */
csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88);
- if (csum != le32_to_cpu(buf[0xfc/4]))
- goto out;
+ if (csum != be32_to_cpu(buf[0xfc/4]))
+ goto out;
err = 0;
@@ -9808,8 +10023,12 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{
struct tg3 *tp = netdev_priv(dev);
- if (netif_running(dev))
- tg3_netif_stop(tp);
+ if (!netif_running(dev)) {
+ tp->vlgrp = grp;
+ return;
+ }
+
+ tg3_netif_stop(tp);
tg3_full_lock(tp, 0);
@@ -9818,8 +10037,7 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
/* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
__tg3_set_rx_mode(dev);
- if (netif_running(dev))
- tg3_netif_start(tp);
+ tg3_netif_start(tp);
tg3_full_unlock(tp);
}
@@ -9926,7 +10144,7 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
tp->nvram_size = EEPROM_CHIP_SIZE;
- if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+ if (tg3_nvram_read(tp, 0, &magic) != 0)
return;
if ((magic != TG3_EEPROM_MAGIC) &&
@@ -9942,7 +10160,7 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
cursize = 0x10;
while (cursize < tp->nvram_size) {
- if (tg3_nvram_read_swab(tp, cursize, &val) != 0)
+ if (tg3_nvram_read(tp, cursize, &val) != 0)
return;
if (val == magic)
@@ -9958,7 +10176,7 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
{
u32 val;
- if (tg3_nvram_read_swab(tp, 0, &val) != 0)
+ if (tg3_nvram_read(tp, 0, &val) != 0)
return;
/* Selfboot format */
@@ -9969,7 +10187,18 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
if (val != 0) {
- tp->nvram_size = (val >> 16) * 1024;
+ /* This is confusing. We want to operate on the
+ * 16-bit value at offset 0xf2. The tg3_nvram_read()
+ * call will read from NVRAM and byteswap the data
+ * according to the byteswapping settings for all
+ * other register accesses. This ensures the data we
+ * want will always reside in the lower 16-bits.
+ * However, the data in NVRAM is in LE format, which
+ * means the data from the NVRAM read will always be
+ * opposite the endianness of the CPU. The 16-bit
+ * byteswap then brings the data to CPU endianness.
+ */
+ tp->nvram_size = swab16((u16)(val & 0x0000ffff)) * 1024;
return;
}
}
@@ -10420,141 +10649,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
}
}
-static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
- u32 offset, u32 *val)
-{
- u32 tmp;
- int i;
-
- if (offset > EEPROM_ADDR_ADDR_MASK ||
- (offset % 4) != 0)
- return -EINVAL;
-
- tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
- EEPROM_ADDR_DEVID_MASK |
- EEPROM_ADDR_READ);
- tw32(GRC_EEPROM_ADDR,
- tmp |
- (0 << EEPROM_ADDR_DEVID_SHIFT) |
- ((offset << EEPROM_ADDR_ADDR_SHIFT) &
- EEPROM_ADDR_ADDR_MASK) |
- EEPROM_ADDR_READ | EEPROM_ADDR_START);
-
- for (i = 0; i < 1000; i++) {
- tmp = tr32(GRC_EEPROM_ADDR);
-
- if (tmp & EEPROM_ADDR_COMPLETE)
- break;
- msleep(1);
- }
- if (!(tmp & EEPROM_ADDR_COMPLETE))
- return -EBUSY;
-
- *val = tr32(GRC_EEPROM_DATA);
- return 0;
-}
-
-#define NVRAM_CMD_TIMEOUT 10000
-
-static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
-{
- int i;
-
- tw32(NVRAM_CMD, nvram_cmd);
- for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
- udelay(10);
- if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
- udelay(10);
- break;
- }
- }
- if (i == NVRAM_CMD_TIMEOUT) {
- return -EBUSY;
- }
- return 0;
-}
-
-static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
-{
- if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
- (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
- (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
- !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
- (tp->nvram_jedecnum == JEDEC_ATMEL))
-
- addr = ((addr / tp->nvram_pagesize) <<
- ATMEL_AT45DB0X1B_PAGE_POS) +
- (addr % tp->nvram_pagesize);
-
- return addr;
-}
-
-static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
-{
- if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
- (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
- (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
- !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
- (tp->nvram_jedecnum == JEDEC_ATMEL))
-
- addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
- tp->nvram_pagesize) +
- (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
-
- return addr;
-}
-
-static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
-{
- int ret;
-
- if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
- return tg3_nvram_read_using_eeprom(tp, offset, val);
-
- offset = tg3_nvram_phys_addr(tp, offset);
-
- if (offset > NVRAM_ADDR_MSK)
- return -EINVAL;
-
- ret = tg3_nvram_lock(tp);
- if (ret)
- return ret;
-
- tg3_enable_nvram_access(tp);
-
- tw32(NVRAM_ADDR, offset);
- ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
- NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
-
- if (ret == 0)
- *val = swab32(tr32(NVRAM_RDDATA));
-
- tg3_disable_nvram_access(tp);
-
- tg3_nvram_unlock(tp);
-
- return ret;
-}
-
-static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val)
-{
- u32 v;
- int res = tg3_nvram_read(tp, offset, &v);
- if (!res)
- *val = cpu_to_le32(v);
- return res;
-}
-
-static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val)
-{
- int err;
- u32 tmp;
-
- err = tg3_nvram_read(tp, offset, &tmp);
- *val = swab32(tmp);
- return err;
-}
-
static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
u32 offset, u32 len, u8 *buf)
{
@@ -10563,13 +10657,13 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
for (i = 0; i < len; i += 4) {
u32 addr;
- __le32 data;
+ __be32 data;
addr = offset + i;
memcpy(&data, buf + i, 4);
- tw32(GRC_EEPROM_DATA, le32_to_cpu(data));
+ tw32(GRC_EEPROM_DATA, be32_to_cpu(data));
val = tr32(GRC_EEPROM_ADDR);
tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
@@ -10619,8 +10713,9 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
phy_addr = offset & ~pagemask;
for (j = 0; j < pagesize; j += 4) {
- if ((ret = tg3_nvram_read_le(tp, phy_addr + j,
- (__le32 *) (tmp + j))))
+ ret = tg3_nvram_read_be32(tp, phy_addr + j,
+ (__be32 *) (tmp + j));
+ if (ret)
break;
}
if (ret)
@@ -10667,7 +10762,7 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
__be32 data;
data = *((__be32 *) (tmp + j));
- /* swab32(le32_to_cpu(data)), actually */
+
tw32(NVRAM_WRDATA, be32_to_cpu(data));
tw32(NVRAM_ADDR, phy_addr + j);
@@ -11253,24 +11348,25 @@ skip_phy_reset:
static void __devinit tg3_read_partno(struct tg3 *tp)
{
- unsigned char vpd_data[256];
+ unsigned char vpd_data[256]; /* in little-endian format */
unsigned int i;
u32 magic;
- if (tg3_nvram_read_swab(tp, 0x0, &magic))
+ if (tg3_nvram_read(tp, 0x0, &magic))
goto out_not_found;
if (magic == TG3_EEPROM_MAGIC) {
for (i = 0; i < 256; i += 4) {
u32 tmp;
- if (tg3_nvram_read(tp, 0x100 + i, &tmp))
+ /* The data is in little-endian format in NVRAM.
+ * Use the big-endian read routines to preserve
+ * the byte order as it exists in NVRAM.
+ */
+ if (tg3_nvram_read_be32(tp, 0x100 + i, &tmp))
goto out_not_found;
- vpd_data[i + 0] = ((tmp >> 0) & 0xff);
- vpd_data[i + 1] = ((tmp >> 8) & 0xff);
- vpd_data[i + 2] = ((tmp >> 16) & 0xff);
- vpd_data[i + 3] = ((tmp >> 24) & 0xff);
+ memcpy(&vpd_data[i], &tmp, sizeof(tmp));
}
} else {
int vpd_cap;
@@ -11296,7 +11392,7 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
&tmp);
v = cpu_to_le32(tmp);
- memcpy(&vpd_data[i], &v, 4);
+ memcpy(&vpd_data[i], &v, sizeof(v));
}
}
@@ -11356,15 +11452,79 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
{
u32 val;
- if (tg3_nvram_read_swab(tp, offset, &val) ||
+ if (tg3_nvram_read(tp, offset, &val) ||
(val & 0xfc000000) != 0x0c000000 ||
- tg3_nvram_read_swab(tp, offset + 4, &val) ||
+ tg3_nvram_read(tp, offset + 4, &val) ||
val != 0)
return 0;
return 1;
}
+static void __devinit tg3_read_bc_ver(struct tg3 *tp)
+{
+ u32 val, offset, start, ver_offset;
+ int i;
+ bool newver = false;
+
+ if (tg3_nvram_read(tp, 0xc, &offset) ||
+ tg3_nvram_read(tp, 0x4, &start))
+ return;
+
+ offset = tg3_nvram_logical_addr(tp, offset);
+
+ if (tg3_nvram_read(tp, offset, &val))
+ return;
+
+ if ((val & 0xfc000000) == 0x0c000000) {
+ if (tg3_nvram_read(tp, offset + 4, &val))
+ return;
+
+ if (val == 0)
+ newver = true;
+ }
+
+ if (newver) {
+ if (tg3_nvram_read(tp, offset + 8, &ver_offset))
+ return;
+
+ offset = offset + ver_offset - start;
+ for (i = 0; i < 16; i += 4) {
+ __be32 v;
+ if (tg3_nvram_read_be32(tp, offset + i, &v))
+ return;
+
+ memcpy(tp->fw_ver + i, &v, sizeof(v));
+ }
+ } else {
+ u32 major, minor;
+
+ if (tg3_nvram_read(tp, TG3_NVM_PTREV_BCVER, &ver_offset))
+ return;
+
+ major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >>
+ TG3_NVM_BCVER_MAJSFT;
+ minor = ver_offset & TG3_NVM_BCVER_MINMSK;
+ snprintf(&tp->fw_ver[0], 32, "v%d.%02d", major, minor);
+ }
+}
+
+static void __devinit tg3_read_hwsb_ver(struct tg3 *tp)
+{
+ u32 val, major, minor;
+
+ /* Use native endian representation */
+ if (tg3_nvram_read(tp, TG3_NVM_HWSB_CFG1, &val))
+ return;
+
+ major = (val & TG3_NVM_HWSB_CFG1_MAJMSK) >>
+ TG3_NVM_HWSB_CFG1_MAJSFT;
+ minor = (val & TG3_NVM_HWSB_CFG1_MINMSK) >>
+ TG3_NVM_HWSB_CFG1_MINSFT;
+
+ snprintf(&tp->fw_ver[0], 32, "sb v%d.%02d", major, minor);
+}
+
static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
{
u32 offset, major, minor, build;
@@ -11390,7 +11550,7 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
return;
}
- if (tg3_nvram_read_swab(tp, offset, &val))
+ if (tg3_nvram_read(tp, offset, &val))
return;
build = (val & TG3_EEPROM_SB_EDH_BLD_MASK) >>
@@ -11410,49 +11570,15 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
}
}
-static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+static void __devinit tg3_read_mgmtfw_ver(struct tg3 *tp)
{
u32 val, offset, start;
- u32 ver_offset;
- int i, bcnt;
-
- if (tg3_nvram_read_swab(tp, 0, &val))
- return;
-
- if (val != TG3_EEPROM_MAGIC) {
- if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
- tg3_read_sb_ver(tp, val);
-
- return;
- }
-
- if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
- tg3_nvram_read_swab(tp, 0x4, &start))
- return;
-
- offset = tg3_nvram_logical_addr(tp, offset);
-
- if (!tg3_fw_img_is_valid(tp, offset) ||
- tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
- return;
-
- offset = offset + ver_offset - start;
- for (i = 0; i < 16; i += 4) {
- __le32 v;
- if (tg3_nvram_read_le(tp, offset + i, &v))
- return;
-
- memcpy(tp->fw_ver + i, &v, 4);
- }
-
- if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
- (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
- return;
+ int i, vlen;
for (offset = TG3_NVM_DIR_START;
offset < TG3_NVM_DIR_END;
offset += TG3_NVM_DIRENT_SIZE) {
- if (tg3_nvram_read_swab(tp, offset, &val))
+ if (tg3_nvram_read(tp, offset, &val))
return;
if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI)
@@ -11464,36 +11590,87 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
start = 0x08000000;
- else if (tg3_nvram_read_swab(tp, offset - 4, &start))
+ else if (tg3_nvram_read(tp, offset - 4, &start))
return;
- if (tg3_nvram_read_swab(tp, offset + 4, &offset) ||
+ if (tg3_nvram_read(tp, offset + 4, &offset) ||
!tg3_fw_img_is_valid(tp, offset) ||
- tg3_nvram_read_swab(tp, offset + 8, &val))
+ tg3_nvram_read(tp, offset + 8, &val))
return;
offset += val - start;
- bcnt = strlen(tp->fw_ver);
+ vlen = strlen(tp->fw_ver);
- tp->fw_ver[bcnt++] = ',';
- tp->fw_ver[bcnt++] = ' ';
+ tp->fw_ver[vlen++] = ',';
+ tp->fw_ver[vlen++] = ' ';
for (i = 0; i < 4; i++) {
- __le32 v;
- if (tg3_nvram_read_le(tp, offset, &v))
+ __be32 v;
+ if (tg3_nvram_read_be32(tp, offset, &v))
return;
offset += sizeof(v);
- if (bcnt > TG3_VER_SIZE - sizeof(v)) {
- memcpy(&tp->fw_ver[bcnt], &v, TG3_VER_SIZE - bcnt);
+ if (vlen > TG3_VER_SIZE - sizeof(v)) {
+ memcpy(&tp->fw_ver[vlen], &v, TG3_VER_SIZE - vlen);
break;
}
- memcpy(&tp->fw_ver[bcnt], &v, sizeof(v));
- bcnt += sizeof(v);
+ memcpy(&tp->fw_ver[vlen], &v, sizeof(v));
+ vlen += sizeof(v);
}
+}
+
+static void __devinit tg3_read_dash_ver(struct tg3 *tp)
+{
+ int vlen;
+ u32 apedata;
+
+ if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) ||
+ !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ return;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
+ if (apedata != APE_SEG_SIG_MAGIC)
+ return;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+ if (!(apedata & APE_FW_STATUS_READY))
+ return;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
+
+ vlen = strlen(tp->fw_ver);
+
+ snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " DASH v%d.%d.%d.%d",
+ (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT,
+ (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT,
+ (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT,
+ (apedata & APE_FW_VERSION_BLDMSK));
+}
+
+static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+{
+ u32 val;
+
+ if (tg3_nvram_read(tp, 0, &val))
+ return;
+
+ if (val == TG3_EEPROM_MAGIC)
+ tg3_read_bc_ver(tp);
+ else if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
+ tg3_read_sb_ver(tp, val);
+ else if ((val & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
+ tg3_read_hwsb_ver(tp);
+ else
+ return;
+
+ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+ (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+ return;
+
+ tg3_read_mgmtfw_ver(tp);
tp->fw_ver[TG3_VER_SIZE - 1] = 0;
}
@@ -12264,14 +12441,10 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
}
if (!addr_ok) {
/* Next, try NVRAM. */
- if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
- !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
- dev->dev_addr[0] = ((hi >> 16) & 0xff);
- dev->dev_addr[1] = ((hi >> 24) & 0xff);
- dev->dev_addr[2] = ((lo >> 0) & 0xff);
- dev->dev_addr[3] = ((lo >> 8) & 0xff);
- dev->dev_addr[4] = ((lo >> 16) & 0xff);
- dev->dev_addr[5] = ((lo >> 24) & 0xff);
+ if (!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));
}
/* Finally just fetch it out of the MAC control regs. */
else {
@@ -12934,7 +13107,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
struct net_device *dev;
struct tg3 *tp;
int err, pm_cap;
- const char *fw_name = NULL;
char str[40];
u64 dma_mask, persist_dma_mask;
@@ -13091,7 +13263,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tg3_init_bufmgr_config(tp);
if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
- fw_name = FIRMWARE_TG3;
+ tp->fw_needed = FIRMWARE_TG3;
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
@@ -13104,37 +13276,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
} else {
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
- }
- if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
- fw_name = FIRMWARE_TG3TSO5;
+ tp->fw_needed = FIRMWARE_TG3TSO5;
else
- fw_name = FIRMWARE_TG3TSO;
- }
-
- if (fw_name) {
- const __be32 *fw_data;
-
- err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev);
- if (err) {
- printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n",
- fw_name);
- goto err_out_iounmap;
- }
-
- fw_data = (void *)tp->fw->data;
-
- /* Firmware blob starts with version numbers, followed by
- start address and _full_ length including BSS sections
- (which must be longer than the actual data, of course */
-
- tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */
- if (tp->fw_len < (tp->fw->size - 12)) {
- printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n",
- tp->fw_len, fw_name);
- err = -EINVAL;
- goto err_out_fw;
- }
+ tp->fw_needed = FIRMWARE_TG3TSO;
}
/* TSO is on by default on chips that support hardware TSO.
@@ -13180,6 +13325,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
}
tg3_ape_lock_init(tp);
+
+ if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+ tg3_read_dash_ver(tp);
}
/*
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index ae5da603c6a..cb4c62abdd2 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1719,6 +1719,12 @@
#define TG3_OTP_DEFAULT 0x286c1640
+/* Hardware Selfboot NVRAM layout */
+#define TG3_NVM_HWSB_CFG1 0x00000004
+#define TG3_NVM_HWSB_CFG1_MAJMSK 0xf8000000
+#define TG3_NVM_HWSB_CFG1_MAJSFT 27
+#define TG3_NVM_HWSB_CFG1_MINMSK 0x07c00000
+#define TG3_NVM_HWSB_CFG1_MINSFT 22
#define TG3_EEPROM_MAGIC 0x669955aa
#define TG3_EEPROM_MAGIC_FW 0xa5000000
@@ -1737,6 +1743,10 @@
#define TG3_NVM_DIRENT_SIZE 0xc
#define TG3_NVM_DIRTYPE_SHIFT 24
#define TG3_NVM_DIRTYPE_ASFINI 1
+#define TG3_NVM_PTREV_BCVER 0x94
+#define TG3_NVM_BCVER_MAJMSK 0x0000ff00
+#define TG3_NVM_BCVER_MAJSFT 8
+#define TG3_NVM_BCVER_MINMSK 0x000000ff
#define TG3_EEPROM_SB_F1R0_EDH_OFF 0x10
#define TG3_EEPROM_SB_F1R2_EDH_OFF 0x14
@@ -1967,6 +1977,14 @@
/* APE shared memory. Accessible through BAR1 */
#define TG3_APE_FW_STATUS 0x400c
#define APE_FW_STATUS_READY 0x00000100
+#define TG3_APE_FW_VERSION 0x4018
+#define APE_FW_VERSION_MAJMSK 0xff000000
+#define APE_FW_VERSION_MAJSFT 24
+#define APE_FW_VERSION_MINMSK 0x00ff0000
+#define APE_FW_VERSION_MINSFT 16
+#define APE_FW_VERSION_REVMSK 0x0000ff00
+#define APE_FW_VERSION_REVSFT 8
+#define APE_FW_VERSION_BLDMSK 0x000000ff
#define TG3_APE_HOST_SEG_SIG 0x4200
#define APE_HOST_SEG_SIG_MAGIC 0x484f5354
#define TG3_APE_HOST_SEG_LEN 0x4204
@@ -2764,6 +2782,7 @@ struct tg3 {
struct ethtool_coalesce coal;
/* firmware info */
+ const char *fw_needed;
const struct firmware *fw;
u32 fw_len; /* includes BSS */
};
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 43853e3b210..4a65fc2dd92 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -274,6 +274,15 @@ static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value)
return ;
}
+
+static const struct net_device_ops xl_netdev_ops = {
+ .ndo_open = xl_open,
+ .ndo_stop = xl_close,
+ .ndo_start_xmit = xl_xmit,
+ .ndo_change_mtu = xl_change_mtu,
+ .ndo_set_multicast_list = xl_set_rx_mode,
+ .ndo_set_mac_address = xl_set_mac_address,
+};
static int __devinit xl_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -337,13 +346,7 @@ static int __devinit xl_probe(struct pci_dev *pdev,
return i ;
}
- dev->open=&xl_open;
- dev->hard_start_xmit=&xl_xmit;
- dev->change_mtu=&xl_change_mtu;
- dev->stop=&xl_close;
- dev->do_ioctl=NULL;
- dev->set_multicast_list=&xl_set_rx_mode;
- dev->set_mac_address=&xl_set_mac_address ;
+ dev->netdev_ops = &xl_netdev_ops;
SET_NETDEV_DEV(dev, &pdev->dev);
pci_set_drvdata(pdev,dev) ;
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
index b566d6d79ec..b9db1b5a58a 100644
--- a/drivers/net/tokenring/abyss.c
+++ b/drivers/net/tokenring/abyss.c
@@ -92,6 +92,8 @@ static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned
outw(val, dev->base_addr + reg);
}
+static struct net_device_ops abyss_netdev_ops;
+
static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int versionprinted;
@@ -157,8 +159,7 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_
memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1);
- dev->open = abyss_open;
- dev->stop = abyss_close;
+ dev->netdev_ops = &abyss_netdev_ops;
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -450,6 +451,11 @@ static struct pci_driver abyss_driver = {
static int __init abyss_init (void)
{
+ abyss_netdev_ops = tms380tr_netdev_ops;
+
+ abyss_netdev_ops.ndo_open = abyss_open;
+ abyss_netdev_ops.ndo_stop = abyss_close;
+
return pci_register_driver(&abyss_driver);
}
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index fa7bce6e0c6..9d896116cf7 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -200,7 +200,6 @@ static void tr_rx(struct net_device *dev);
static void ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);
static void tok_rerun(unsigned long dev_addr);
static void ibmtr_readlog(struct net_device *dev);
-static struct net_device_stats *tok_get_stats(struct net_device *dev);
static int ibmtr_change_mtu(struct net_device *dev, int mtu);
static void find_turbo_adapters(int *iolist);
@@ -816,18 +815,21 @@ static unsigned char __devinit get_sram_size(struct tok_info *adapt_info)
/*****************************************************************************/
+static const struct net_device_ops trdev_netdev_ops = {
+ .ndo_open = tok_open,
+ .ndo_stop = tok_close,
+ .ndo_start_xmit = tok_send_packet,
+ .ndo_set_multicast_list = tok_set_multicast_list,
+ .ndo_change_mtu = ibmtr_change_mtu,
+};
+
static int __devinit trdev_init(struct net_device *dev)
{
struct tok_info *ti = netdev_priv(dev);
SET_PAGE(ti->srb_page);
ti->open_failure = NO ;
- dev->open = tok_open;
- dev->stop = tok_close;
- dev->hard_start_xmit = tok_send_packet;
- dev->get_stats = tok_get_stats;
- dev->set_multicast_list = tok_set_multicast_list;
- dev->change_mtu = ibmtr_change_mtu;
+ dev->netdev_ops = &trdev_netdev_ops;
return 0;
}
@@ -1460,7 +1462,7 @@ static irqreturn_t tok_interrupt(int irq, void *dev_id)
"%02X\n",
(int)retcode, (int)readb(ti->ssb + 6));
else
- ti->tr_stats.tx_packets++;
+ dev->stats.tx_packets++;
break;
case XMIT_XID_CMD:
DPRINTK("xmit xid ret_code: %02X\n",
@@ -1646,7 +1648,7 @@ static void tr_tx(struct net_device *dev)
break;
}
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- ti->tr_stats.tx_bytes += ti->current_skb->len;
+ dev->stats.tx_bytes += ti->current_skb->len;
dev_kfree_skb_irq(ti->current_skb);
ti->current_skb = NULL;
netif_wake_queue(dev);
@@ -1722,7 +1724,7 @@ static void tr_rx(struct net_device *dev)
if (readb(llc + offsetof(struct trllc, llc)) != UI_CMD) {
SET_PAGE(ti->asb_page);
writeb(DATA_LOST, ti->asb + RETCODE_OFST);
- ti->tr_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
return;
}
@@ -1757,7 +1759,7 @@ static void tr_rx(struct net_device *dev)
if (!(skb = dev_alloc_skb(skb_size))) {
DPRINTK("out of memory. frame dropped.\n");
- ti->tr_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
SET_PAGE(ti->asb_page);
writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
@@ -1813,8 +1815,8 @@ static void tr_rx(struct net_device *dev)
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- ti->tr_stats.rx_bytes += skb->len;
- ti->tr_stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
skb->protocol = tr_type_trans(skb, dev);
if (IPv4_p) {
@@ -1876,21 +1878,6 @@ static void ibmtr_readlog(struct net_device *dev)
/*****************************************************************************/
-/* tok_get_stats(): Basically a scaffold routine which will return
- the address of the tr_statistics structure associated with
- this device -- the tr.... structure is an ethnet look-alike
- so at least for this iteration may suffice. */
-
-static struct net_device_stats *tok_get_stats(struct net_device *dev)
-{
-
- struct tok_info *toki;
- toki = netdev_priv(dev);
- return (struct net_device_stats *) &toki->tr_stats;
-}
-
-/*****************************************************************************/
-
static int ibmtr_change_mtu(struct net_device *dev, int mtu)
{
struct tok_info *ti = netdev_priv(dev);
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index 239c75217b1..f309b8f703b 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -207,7 +207,6 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev);
static int streamer_close(struct net_device *dev);
static void streamer_set_rx_mode(struct net_device *dev);
static irqreturn_t streamer_interrupt(int irq, void *dev_id);
-static struct net_device_stats *streamer_get_stats(struct net_device *dev);
static int streamer_set_mac_address(struct net_device *dev, void *addr);
static void streamer_arb_cmd(struct net_device *dev);
static int streamer_change_mtu(struct net_device *dev, int mtu);
@@ -222,6 +221,18 @@ struct streamer_private *dev_streamer=NULL;
#endif
#endif
+static const struct net_device_ops streamer_netdev_ops = {
+ .ndo_open = streamer_open,
+ .ndo_stop = streamer_close,
+ .ndo_start_xmit = streamer_xmit,
+ .ndo_change_mtu = streamer_change_mtu,
+#if STREAMER_IOCTL
+ .ndo_do_ioctl = streamer_ioctl,
+#endif
+ .ndo_set_multicast_list = streamer_set_rx_mode,
+ .ndo_set_mac_address = streamer_set_mac_address,
+};
+
static int __devinit streamer_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -321,18 +332,7 @@ static int __devinit streamer_init_one(struct pci_dev *pdev,
init_waitqueue_head(&streamer_priv->srb_wait);
init_waitqueue_head(&streamer_priv->trb_wait);
- dev->open = &streamer_open;
- dev->hard_start_xmit = &streamer_xmit;
- dev->change_mtu = &streamer_change_mtu;
- dev->stop = &streamer_close;
-#if STREAMER_IOCTL
- dev->do_ioctl = &streamer_ioctl;
-#else
- dev->do_ioctl = NULL;
-#endif
- dev->set_multicast_list = &streamer_set_rx_mode;
- dev->get_stats = &streamer_get_stats;
- dev->set_mac_address = &streamer_set_mac_address;
+ dev->netdev_ops = &streamer_netdev_ops;
dev->irq = pdev->irq;
dev->base_addr=pio_start;
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -616,8 +616,6 @@ static int streamer_open(struct net_device *dev)
printk("SISR Mask = %04x\n", readw(streamer_mmio + SISR_MASK));
#endif
do {
- int i;
-
for (i = 0; i < SRB_COMMAND_SIZE; i += 2) {
writew(0, streamer_mmio + LAPDINC);
}
@@ -937,7 +935,7 @@ static void streamer_rx(struct net_device *dev)
if (skb == NULL)
{
printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n", dev->name);
- streamer_priv->streamer_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
} else { /* we allocated an skb OK */
if (buffer_cnt == 1) {
/* release the DMA mapping */
@@ -1009,8 +1007,8 @@ static void streamer_rx(struct net_device *dev)
/* send up to the protocol */
netif_rx(skb);
}
- streamer_priv->streamer_stats.rx_packets++;
- streamer_priv->streamer_stats.rx_bytes += length;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length;
} /* if skb == null */
} /* end received without errors */
@@ -1053,8 +1051,8 @@ static irqreturn_t streamer_interrupt(int irq, void *dev_id)
while(streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) {
streamer_priv->tx_ring_last_status = (streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1);
streamer_priv->free_tx_ring_entries++;
- streamer_priv->streamer_stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
- streamer_priv->streamer_stats.tx_packets++;
+ dev->stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
+ dev->stats.tx_packets++;
dev_kfree_skb_irq(streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]);
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buffer = 0xdeadbeef;
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].status = 0;
@@ -1484,13 +1482,6 @@ static void streamer_srb_bh(struct net_device *dev)
} /* switch srb[0] */
}
-static struct net_device_stats *streamer_get_stats(struct net_device *dev)
-{
- struct streamer_private *streamer_priv;
- streamer_priv = netdev_priv(dev);
- return (struct net_device_stats *) &streamer_priv->streamer_stats;
-}
-
static int streamer_set_mac_address(struct net_device *dev, void *addr)
{
struct sockaddr *saddr = addr;
diff --git a/drivers/net/tokenring/lanstreamer.h b/drivers/net/tokenring/lanstreamer.h
index 13ccee6449c..3c58d6a3fbc 100644
--- a/drivers/net/tokenring/lanstreamer.h
+++ b/drivers/net/tokenring/lanstreamer.h
@@ -299,7 +299,6 @@ struct streamer_private {
int tx_ring_free, tx_ring_last_status, rx_ring_last_received,
free_tx_ring_entries;
- struct net_device_stats streamer_stats;
__u16 streamer_lan_status;
__u8 streamer_ring_speed;
__u16 pkt_buf_sz;
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
index 917b4d201e0..193308118f9 100644
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -692,8 +692,6 @@ static int madgemc_mcaproc(char *buf, int slot, void *d)
len += sprintf(buf+len, "-------\n");
if (curcard) {
- struct net_local *tp = netdev_priv(dev);
-
len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev);
len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize);
len += sprintf(buf+len, "Cable type: %s\n", (curcard->cabletype)?"STP/DB9":"UTP/RJ-45");
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index ecb5c7c9691..d068a9d3688 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -187,7 +187,6 @@ static int olympic_close(struct net_device *dev);
static void olympic_set_rx_mode(struct net_device *dev);
static void olympic_freemem(struct net_device *dev) ;
static irqreturn_t olympic_interrupt(int irq, void *dev_id);
-static struct net_device_stats * olympic_get_stats(struct net_device *dev);
static int olympic_set_mac_address(struct net_device *dev, void *addr) ;
static void olympic_arb_cmd(struct net_device *dev);
static int olympic_change_mtu(struct net_device *dev, int mtu);
@@ -195,6 +194,15 @@ static void olympic_srb_bh(struct net_device *dev) ;
static void olympic_asb_bh(struct net_device *dev) ;
static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ;
+static const struct net_device_ops olympic_netdev_ops = {
+ .ndo_open = olympic_open,
+ .ndo_stop = olympic_close,
+ .ndo_start_xmit = olympic_xmit,
+ .ndo_change_mtu = olympic_change_mtu,
+ .ndo_set_multicast_list = olympic_set_rx_mode,
+ .ndo_set_mac_address = olympic_set_mac_address,
+};
+
static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *dev ;
@@ -253,14 +261,7 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device
goto op_free_iomap;
}
- dev->open=&olympic_open;
- dev->hard_start_xmit=&olympic_xmit;
- dev->change_mtu=&olympic_change_mtu;
- dev->stop=&olympic_close;
- dev->do_ioctl=NULL;
- dev->set_multicast_list=&olympic_set_rx_mode;
- dev->get_stats=&olympic_get_stats ;
- dev->set_mac_address=&olympic_set_mac_address ;
+ dev->netdev_ops = &olympic_netdev_ops;
SET_NETDEV_DEV(dev, &pdev->dev);
pci_set_drvdata(pdev,dev) ;
@@ -698,7 +699,6 @@ static int olympic_open(struct net_device *dev)
if (olympic_priv->olympic_network_monitor) {
u8 __iomem *oat;
u8 __iomem *opt;
- int i;
u8 addr[6];
oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr);
opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr);
@@ -785,7 +785,7 @@ static void olympic_rx(struct net_device *dev)
}
olympic_priv->rx_ring_last_received += i ;
olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
- olympic_priv->olympic_stats.rx_errors++;
+ dev->stats.rx_errors++;
} else {
if (buffer_cnt == 1) {
@@ -796,7 +796,7 @@ static void olympic_rx(struct net_device *dev)
if (skb == NULL) {
printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n",dev->name) ;
- olympic_priv->olympic_stats.rx_dropped++ ;
+ dev->stats.rx_dropped++;
/* Update counters even though we don't transfer the frame */
olympic_priv->rx_ring_last_received += i ;
olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
@@ -862,8 +862,8 @@ static void olympic_rx(struct net_device *dev)
skb->protocol = tr_type_trans(skb,dev);
netif_rx(skb) ;
}
- olympic_priv->olympic_stats.rx_packets++ ;
- olympic_priv->olympic_stats.rx_bytes += length ;
+ dev->stats.rx_packets++ ;
+ dev->stats.rx_bytes += length ;
} /* if skb == null */
} /* If status & 0x3b */
@@ -971,8 +971,8 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id)
olympic_priv->tx_ring_last_status++;
olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
olympic_priv->free_tx_ring_entries++;
- olympic_priv->olympic_stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
- olympic_priv->olympic_stats.tx_packets++ ;
+ dev->stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
+ dev->stats.tx_packets++ ;
pci_unmap_single(olympic_priv->pdev,
le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer),
olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);
@@ -1344,13 +1344,6 @@ static void olympic_srb_bh(struct net_device *dev)
}
-static struct net_device_stats * olympic_get_stats(struct net_device *dev)
-{
- struct olympic_private *olympic_priv ;
- olympic_priv=netdev_priv(dev);
- return (struct net_device_stats *) &olympic_priv->olympic_stats;
-}
-
static int olympic_set_mac_address (struct net_device *dev, void *addr)
{
struct sockaddr *saddr = addr ;
diff --git a/drivers/net/tokenring/olympic.h b/drivers/net/tokenring/olympic.h
index 10fbba08978..30631bae4c9 100644
--- a/drivers/net/tokenring/olympic.h
+++ b/drivers/net/tokenring/olympic.h
@@ -275,7 +275,6 @@ struct olympic_private {
struct sk_buff *tx_ring_skb[OLYMPIC_TX_RING_SIZE], *rx_ring_skb[OLYMPIC_RX_RING_SIZE];
int tx_ring_free, tx_ring_last_status, rx_ring_last_received,rx_status_last_received, free_tx_ring_entries;
- struct net_device_stats olympic_stats ;
u16 olympic_lan_status ;
u8 olympic_ring_speed ;
u16 pkt_buf_sz ;
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index 50eb29ce3c8..9d7db2c8d66 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -61,7 +61,8 @@
#include "smctr.h" /* Our Stuff */
-static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
+static const char version[] __initdata =
+ KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
static const char cardname[] = "smctr";
@@ -4392,52 +4393,42 @@ static int smctr_ring_status_chg(struct net_device *dev)
{
case RING_RECOVERY:
printk(KERN_INFO "%s: Ring Recovery\n", dev->name);
- tp->current_ring_status |= RING_RECOVERY;
break;
case SINGLE_STATION:
printk(KERN_INFO "%s: Single Statinon\n", dev->name);
- tp->current_ring_status |= SINGLE_STATION;
break;
case COUNTER_OVERFLOW:
printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
- tp->current_ring_status |= COUNTER_OVERFLOW;
break;
case REMOVE_RECEIVED:
printk(KERN_INFO "%s: Remove Received\n", dev->name);
- tp->current_ring_status |= REMOVE_RECEIVED;
break;
case AUTO_REMOVAL_ERROR:
printk(KERN_INFO "%s: Auto Remove Error\n", dev->name);
- tp->current_ring_status |= AUTO_REMOVAL_ERROR;
break;
case LOBE_WIRE_FAULT:
printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name);
- tp->current_ring_status |= LOBE_WIRE_FAULT;
break;
case TRANSMIT_BEACON:
printk(KERN_INFO "%s: Transmit Beacon\n", dev->name);
- tp->current_ring_status |= TRANSMIT_BEACON;
break;
case SOFT_ERROR:
printk(KERN_INFO "%s: Soft Error\n", dev->name);
- tp->current_ring_status |= SOFT_ERROR;
break;
case HARD_ERROR:
printk(KERN_INFO "%s: Hard Error\n", dev->name);
- tp->current_ring_status |= HARD_ERROR;
break;
case SIGNAL_LOSS:
printk(KERN_INFO "%s: Signal Loss\n", dev->name);
- tp->current_ring_status |= SIGNAL_LOSS;
break;
default:
diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h
index 52df7dd815c..6e5700ab4fc 100644
--- a/drivers/net/tokenring/smctr.h
+++ b/drivers/net/tokenring/smctr.h
@@ -977,7 +977,6 @@ typedef struct net_local {
__u8 monitor_state_ready;
__u16 ring_status;
__u8 ring_status_flags;
- __u8 current_ring_status;
__u8 state;
__u8 join_state;
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 5be34c2fd48..b11bb72dc7a 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -2330,6 +2330,17 @@ void tmsdev_term(struct net_device *dev)
DMA_BIDIRECTIONAL);
}
+const struct net_device_ops tms380tr_netdev_ops = {
+ .ndo_open = tms380tr_open,
+ .ndo_stop = tms380tr_close,
+ .ndo_start_xmit = tms380tr_send_packet,
+ .ndo_tx_timeout = tms380tr_timeout,
+ .ndo_get_stats = tms380tr_get_stats,
+ .ndo_set_multicast_list = tms380tr_set_multicast_list,
+ .ndo_set_mac_address = tms380tr_set_mac_address,
+};
+EXPORT_SYMBOL(tms380tr_netdev_ops);
+
int tmsdev_init(struct net_device *dev, struct device *pdev)
{
struct net_local *tms_local;
@@ -2353,16 +2364,8 @@ int tmsdev_init(struct net_device *dev, struct device *pdev)
return -ENOMEM;
}
- /* These can be overridden by the card driver if needed */
- dev->open = tms380tr_open;
- dev->stop = tms380tr_close;
- dev->do_ioctl = NULL;
- dev->hard_start_xmit = tms380tr_send_packet;
- dev->tx_timeout = tms380tr_timeout;
+ dev->netdev_ops = &tms380tr_netdev_ops;
dev->watchdog_timeo = HZ;
- dev->get_stats = tms380tr_get_stats;
- dev->set_multicast_list = &tms380tr_set_multicast_list;
- dev->set_mac_address = tms380tr_set_mac_address;
return 0;
}
diff --git a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h
index 7af76d70884..60b30ee38dc 100644
--- a/drivers/net/tokenring/tms380tr.h
+++ b/drivers/net/tokenring/tms380tr.h
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
/* module prototypes */
+extern const struct net_device_ops tms380tr_netdev_ops;
int tms380tr_open(struct net_device *dev);
int tms380tr_close(struct net_device *dev);
irqreturn_t tms380tr_interrupt(int irq, void *dev_id);
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
index 5f601773c26..f92fe86fdca 100644
--- a/drivers/net/tokenring/tmspci.c
+++ b/drivers/net/tokenring/tmspci.c
@@ -121,11 +121,6 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic
goto err_out_trdev;
}
- ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED,
- dev->name, dev);
- if (ret)
- goto err_out_region;
-
dev->base_addr = pci_ioaddr;
dev->irq = pci_irq_line;
dev->dma = 0;
@@ -142,7 +137,7 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic
ret = tmsdev_init(dev, &pdev->dev);
if (ret) {
printk("%s: unable to get memory for dev->priv.\n", dev->name);
- goto err_out_irq;
+ goto err_out_region;
}
tp = netdev_priv(dev);
@@ -157,22 +152,27 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic
tp->tmspriv = cardinfo;
- dev->open = tms380tr_open;
- dev->stop = tms380tr_close;
+ dev->netdev_ops = &tms380tr_netdev_ops;
+
+ ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (ret)
+ goto err_out_tmsdev;
+
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
ret = register_netdev(dev);
if (ret)
- goto err_out_tmsdev;
+ goto err_out_irq;
return 0;
+err_out_irq:
+ free_irq(pdev->irq, dev);
err_out_tmsdev:
pci_set_drvdata(pdev, NULL);
tmsdev_term(dev);
-err_out_irq:
- free_irq(pdev->irq, dev);
err_out_region:
release_region(pci_ioaddr, TMS_PCI_IO_EXTENT);
err_out_trdev:
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 75461dbd487..bb43e7fb2a5 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -888,7 +888,7 @@ static int tsi108_poll(struct napi_struct *napi, int budget)
if (num_received < budget) {
data->rxpending = 0;
- netif_rx_complete(napi);
+ napi_complete(napi);
TSI_WRITE(TSI108_EC_INTMASK,
TSI_READ(TSI108_EC_INTMASK)
@@ -915,11 +915,11 @@ static void tsi108_rx_int(struct net_device *dev)
*
* This can happen if this code races with tsi108_poll(), which masks
* the interrupts after tsi108_irq_one() read the mask, but before
- * netif_rx_schedule is called. It could also happen due to calls
+ * napi_schedule is called. It could also happen due to calls
* from tsi108_check_rxring().
*/
- if (netif_rx_schedule_prep(&data->napi)) {
+ if (napi_schedule_prep(&data->napi)) {
/* Mask, rather than ack, the receive interrupts. The ack
* will happen in tsi108_poll().
*/
@@ -930,7 +930,7 @@ static void tsi108_rx_int(struct net_device *dev)
| TSI108_INT_RXTHRESH |
TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR |
TSI108_INT_RXWAIT);
- __netif_rx_schedule(&data->napi);
+ __napi_schedule(&data->napi);
} else {
if (!netif_running(dev)) {
/* This can happen if an interrupt occurs while the
@@ -1237,7 +1237,7 @@ static void tsi108_init_phy(struct net_device *dev)
spin_lock_irqsave(&phy_lock, flags);
tsi108_write_mii(data, MII_BMCR, BMCR_RESET);
- while (i--){
+ while (--i) {
if(!(tsi108_read_mii(data, MII_BMCR) & BMCR_RESET))
break;
udelay(10);
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index 1210fb3748a..db7d5e11855 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -9,6 +9,11 @@
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
for more information on this driver.
+
+ DC21143 manual "21143 PCI/CardBus 10/100Mb/s Ethernet LAN Controller
+ Hardware Reference Manual" is currently available at :
+ http://developer.intel.com/design/network/manuals/278074.htm
+
Please submit bugs to http://bugzilla.kernel.org/ .
*/
@@ -32,7 +37,11 @@ void t21142_media_task(struct work_struct *work)
int csr12 = ioread32(ioaddr + CSR12);
int next_tick = 60*HZ;
int new_csr6 = 0;
+ int csr14 = ioread32(ioaddr + CSR14);
+ /* CSR12[LS10,LS100] are not reliable during autonegotiation */
+ if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
+ csr12 |= 6;
if (tulip_debug > 2)
printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
dev->name, csr12, medianame[dev->if_port]);
@@ -76,7 +85,7 @@ void t21142_media_task(struct work_struct *work)
new_csr6 = 0x83860000;
dev->if_port = 3;
iowrite32(0, ioaddr + CSR13);
- iowrite32(0x0003FF7F, ioaddr + CSR14);
+ iowrite32(0x0003FFFF, ioaddr + CSR14);
iowrite16(8, ioaddr + CSR15);
iowrite32(1, ioaddr + CSR13);
}
@@ -132,10 +141,14 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
struct tulip_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->base_addr;
int csr12 = ioread32(ioaddr + CSR12);
+ int csr14 = ioread32(ioaddr + CSR14);
+ /* CSR12[LS10,LS100] are not reliable during autonegotiation */
+ if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
+ csr12 |= 6;
if (tulip_debug > 1)
printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, "
- "%8.8x.\n", dev->name, csr12, csr5, ioread32(ioaddr + CSR14));
+ "%8.8x.\n", dev->name, csr12, csr5, csr14);
/* If NWay finished and we have a negotiated partner capability. */
if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) {
@@ -143,7 +156,9 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
int negotiated = tp->sym_advertise & (csr12 >> 16);
tp->lpar = csr12 >> 16;
tp->nwayset = 1;
- if (negotiated & 0x0100) dev->if_port = 5;
+ /* If partner cannot negotiate, it is 10Mbps Half Duplex */
+ if (!(csr12 & 0x8000)) dev->if_port = 0;
+ else if (negotiated & 0x0100) dev->if_port = 5;
else if (negotiated & 0x0080) dev->if_port = 3;
else if (negotiated & 0x0040) dev->if_port = 4;
else if (negotiated & 0x0020) dev->if_port = 0;
@@ -214,7 +229,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
tp->timer.expires = RUN_AT(3*HZ);
add_timer(&tp->timer);
} else if (dev->if_port == 5)
- iowrite32(ioread32(ioaddr + CSR14) & ~0x080, ioaddr + CSR14);
+ iowrite32(csr14 & ~0x080, ioaddr + CSR14);
} else if (dev->if_port == 0 || dev->if_port == 4) {
if ((csr12 & 4) == 0)
printk(KERN_INFO"%s: 21143 10baseT link beat good.\n",
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index d5d53b633cf..d4c5ecc51f7 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -392,7 +392,7 @@ static void de_rx (struct de_private *de)
unsigned drop = 0;
int rc;
- while (rx_work--) {
+ while (--rx_work) {
u32 status, len;
dma_addr_t mapping;
struct sk_buff *skb, *copy_skb;
@@ -464,13 +464,14 @@ static void de_rx (struct de_private *de)
drop = 1;
rx_next:
- de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn);
if (rx_tail == (DE_RX_RING_SIZE - 1))
de->rx_ring[rx_tail].opts2 =
cpu_to_le32(RingEnd | de->rx_buf_sz);
else
de->rx_ring[rx_tail].opts2 = cpu_to_le32(de->rx_buf_sz);
de->rx_ring[rx_tail].addr1 = cpu_to_le32(mapping);
+ wmb();
+ de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn);
rx_tail = NEXT_RX(rx_tail);
}
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 6418f74415d..f9491bd787d 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -479,7 +479,8 @@
#include "de4x5.h"
-static char version[] __devinitdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
+static const char version[] __devinitconst =
+ KERN_INFO "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
#define c_char const char
@@ -3941,8 +3942,8 @@ PCI_signature(char *name, struct de4x5_private *lp)
strcpy(name, "DE434/5");
return status;
} else { /* Search for a DEC name in the SROM */
- int i = *((char *)&lp->srom + 19) * 3;
- strncpy(name, (char *)&lp->srom + 26 + i, 8);
+ int tmp = *((char *)&lp->srom + 19) * 3;
+ strncpy(name, (char *)&lp->srom + 26 + tmp, 8);
}
name[8] = '\0';
for (i=0; i<siglen; i++) {
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 2e5c99941f3..e2c9d0f5a75 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -288,7 +288,7 @@ enum dmfe_CR6_bits {
/* Global variable declaration ----------------------------- */
static int __devinitdata printed_version;
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
KERN_INFO DRV_NAME ": Davicom DM9xxx net driver, version "
DRV_VERSION " (" DRV_RELDATE ")\n";
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 6c3428a37c0..c8d220cf2cc 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -103,7 +103,7 @@ void oom_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct tulip_private *tp = netdev_priv(dev);
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
}
int tulip_poll(struct napi_struct *napi, int budget)
@@ -140,6 +140,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
/* If we own the next entry, it is a new packet. Send it up. */
while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+ short pkt_len;
if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
break;
@@ -151,8 +152,28 @@ int tulip_poll(struct napi_struct *napi, int budget)
if (++work_done >= budget)
goto not_done;
- if ((status & 0x38008300) != 0x0300) {
- if ((status & 0x38000300) != 0x0300) {
+ /*
+ * Omit the four octet CRC from the length.
+ * (May not be considered valid until we have
+ * checked status for RxLengthOver2047 bits)
+ */
+ pkt_len = ((status >> 16) & 0x7ff) - 4;
+
+ /*
+ * Maximum pkt_len is 1518 (1514 + vlan header)
+ * Anything higher than this is always invalid
+ * regardless of RxLengthOver2047 bits
+ */
+
+ if ((status & (RxLengthOver2047 |
+ RxDescCRCError |
+ RxDescCollisionSeen |
+ RxDescRunt |
+ RxDescDescErr |
+ RxWholePkt)) != RxWholePkt
+ || pkt_len > 1518) {
+ if ((status & (RxLengthOver2047 |
+ RxWholePkt)) != RxWholePkt) {
/* Ingore earlier buffers. */
if ((status & 0xffff) != 0x7fff) {
if (tulip_debug > 1)
@@ -161,30 +182,23 @@ int tulip_poll(struct napi_struct *napi, int budget)
dev->name, status);
tp->stats.rx_length_errors++;
}
- } else if (status & RxDescFatalErr) {
+ } else {
/* There was a fatal error. */
if (tulip_debug > 2)
printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
dev->name, status);
tp->stats.rx_errors++; /* end of a packet.*/
- if (status & 0x0890) tp->stats.rx_length_errors++;
+ if (pkt_len > 1518 ||
+ (status & RxDescRunt))
+ tp->stats.rx_length_errors++;
+
if (status & 0x0004) tp->stats.rx_frame_errors++;
if (status & 0x0002) tp->stats.rx_crc_errors++;
if (status & 0x0001) tp->stats.rx_fifo_errors++;
}
} else {
- /* Omit the four octet CRC from the length. */
- short pkt_len = ((status >> 16) & 0x7ff) - 4;
struct sk_buff *skb;
-#ifndef final_version
- if (pkt_len > 1518) {
- printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
- dev->name, pkt_len, pkt_len);
- pkt_len = 1518;
- tp->stats.rx_length_errors++;
- }
-#endif
/* Check if the packet is long enough to accept without copying
to a minimally-sized skbuff. */
if (pkt_len < tulip_rx_copybreak
@@ -300,7 +314,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
/* Remove us from polling list and enable RX intr. */
- netif_rx_complete(napi);
+ napi_complete(napi);
iowrite32(tulip_tbl[tp->chip_id].valid_intrs, tp->base_addr+CSR7);
/* The last op happens after poll completion. Which means the following:
@@ -333,10 +347,10 @@ int tulip_poll(struct napi_struct *napi, int budget)
/* Think: timer_pending() was an explicit signature of bug.
* Timer can be pending now but fired and completed
- * before we did netif_rx_complete(). See? We would lose it. */
+ * before we did napi_complete(). See? We would lose it. */
/* remove ourselves from the polling list */
- netif_rx_complete(napi);
+ napi_complete(napi);
return work_done;
}
@@ -356,14 +370,35 @@ static int tulip_rx(struct net_device *dev)
/* If we own the next entry, it is a new packet. Send it up. */
while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+ short pkt_len;
if (tulip_debug > 5)
printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
dev->name, entry, status);
if (--rx_work_limit < 0)
break;
- if ((status & 0x38008300) != 0x0300) {
- if ((status & 0x38000300) != 0x0300) {
+
+ /*
+ Omit the four octet CRC from the length.
+ (May not be considered valid until we have
+ checked status for RxLengthOver2047 bits)
+ */
+ pkt_len = ((status >> 16) & 0x7ff) - 4;
+ /*
+ Maximum pkt_len is 1518 (1514 + vlan header)
+ Anything higher than this is always invalid
+ regardless of RxLengthOver2047 bits
+ */
+
+ if ((status & (RxLengthOver2047 |
+ RxDescCRCError |
+ RxDescCollisionSeen |
+ RxDescRunt |
+ RxDescDescErr |
+ RxWholePkt)) != RxWholePkt
+ || pkt_len > 1518) {
+ if ((status & (RxLengthOver2047 |
+ RxWholePkt)) != RxWholePkt) {
/* Ingore earlier buffers. */
if ((status & 0xffff) != 0x7fff) {
if (tulip_debug > 1)
@@ -372,31 +407,22 @@ static int tulip_rx(struct net_device *dev)
dev->name, status);
tp->stats.rx_length_errors++;
}
- } else if (status & RxDescFatalErr) {
+ } else {
/* There was a fatal error. */
if (tulip_debug > 2)
printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
dev->name, status);
tp->stats.rx_errors++; /* end of a packet.*/
- if (status & 0x0890) tp->stats.rx_length_errors++;
+ if (pkt_len > 1518 ||
+ (status & RxDescRunt))
+ tp->stats.rx_length_errors++;
if (status & 0x0004) tp->stats.rx_frame_errors++;
if (status & 0x0002) tp->stats.rx_crc_errors++;
if (status & 0x0001) tp->stats.rx_fifo_errors++;
}
} else {
- /* Omit the four octet CRC from the length. */
- short pkt_len = ((status >> 16) & 0x7ff) - 4;
struct sk_buff *skb;
-#ifndef final_version
- if (pkt_len > 1518) {
- printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
- dev->name, pkt_len, pkt_len);
- pkt_len = 1518;
- tp->stats.rx_length_errors++;
- }
-#endif
-
/* Check if the packet is long enough to accept without copying
to a minimally-sized skbuff. */
if (pkt_len < tulip_rx_copybreak
@@ -519,7 +545,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
rxd++;
/* Mask RX intrs and add the device to poll list. */
iowrite32(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
break;
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index 91cf9c86391..daddfa51853 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -69,11 +69,10 @@ int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
spin_lock_irqsave(&tp->mii_lock, flags);
if (tp->chip_id == LC82C168) {
- int i = 1000;
iowrite32(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
ioread32(ioaddr + 0xA0);
ioread32(ioaddr + 0xA0);
- while (--i > 0) {
+ for (i = 1000; i >= 0; --i) {
barrier();
if ( ! ((retval = ioread32(ioaddr + 0xA0)) & 0x80000000))
break;
@@ -131,13 +130,12 @@ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val)
spin_lock_irqsave(&tp->mii_lock, flags);
if (tp->chip_id == LC82C168) {
- int i = 1000;
iowrite32(cmd, ioaddr + 0xA0);
- do {
+ for (i = 1000; i >= 0; --i) {
barrier();
if ( ! (ioread32(ioaddr + 0xA0) & 0x80000000))
break;
- } while (--i > 0);
+ }
spin_unlock_irqrestore(&tp->mii_lock, flags);
return;
}
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 19abbc36b60..0afa2d4f947 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -201,8 +201,38 @@ enum desc_status_bits {
DescStartPkt = 0x20000000,
DescEndRing = 0x02000000,
DescUseLink = 0x01000000,
- RxDescFatalErr = 0x008000,
+
+ /*
+ * Error summary flag is logical or of 'CRC Error', 'Collision Seen',
+ * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated
+ * within tulip chip.
+ */
+ RxDescErrorSummary = 0x8000,
+ RxDescCRCError = 0x0002,
+ RxDescCollisionSeen = 0x0040,
+
+ /*
+ * 'Frame Too Long' flag is set if packet length including CRC exceeds
+ * 1518. However, a full sized VLAN tagged frame is 1522 bytes
+ * including CRC.
+ *
+ * The tulip chip does not block oversized frames, and if this flag is
+ * set on a receive descriptor it does not indicate the frame has been
+ * truncated. The receive descriptor also includes the actual length.
+ * Therefore we can safety ignore this flag and check the length
+ * ourselves.
+ */
+ RxDescFrameTooLong = 0x0080,
+ RxDescRunt = 0x0800,
+ RxDescDescErr = 0x4000,
RxWholePkt = 0x00000300,
+ /*
+ * Top three bits of 14 bit frame length (status bits 27-29) should
+ * never be set as that would make frame over 2047 bytes. The Receive
+ * Watchdog flag (bit 4) may indicate the length is over 2048 and the
+ * length field is invalid.
+ */
+ RxLengthOver2047 = 0x38000010
};
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index bee75fa87a9..2abb5d3becc 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -255,6 +255,7 @@ const char tulip_media_cap[32] =
static void tulip_tx_timeout(struct net_device *dev);
static void tulip_init_ring(struct net_device *dev);
+static void tulip_free_ring(struct net_device *dev);
static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int tulip_open(struct net_device *dev);
static int tulip_close(struct net_device *dev);
@@ -502,16 +503,21 @@ tulip_open(struct net_device *dev)
{
int retval;
- if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev)))
- return retval;
-
tulip_init_ring (dev);
+ retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev);
+ if (retval)
+ goto free_ring;
+
tulip_up (dev);
netif_start_queue (dev);
return 0;
+
+free_ring:
+ tulip_free_ring (dev);
+ return retval;
}
@@ -768,23 +774,11 @@ static void tulip_down (struct net_device *dev)
tulip_set_power_state (tp, 0, 1);
}
-
-static int tulip_close (struct net_device *dev)
+static void tulip_free_ring (struct net_device *dev)
{
struct tulip_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->base_addr;
int i;
- netif_stop_queue (dev);
-
- tulip_down (dev);
-
- if (tulip_debug > 1)
- printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, ioread32 (ioaddr + CSR5));
-
- free_irq (dev->irq, dev);
-
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb = tp->rx_buffers[i].skb;
@@ -803,6 +797,7 @@ static int tulip_close (struct net_device *dev)
dev_kfree_skb (skb);
}
}
+
for (i = 0; i < TX_RING_SIZE; i++) {
struct sk_buff *skb = tp->tx_buffers[i].skb;
@@ -814,6 +809,24 @@ static int tulip_close (struct net_device *dev)
tp->tx_buffers[i].skb = NULL;
tp->tx_buffers[i].mapping = 0;
}
+}
+
+static int tulip_close (struct net_device *dev)
+{
+ struct tulip_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->base_addr;
+
+ netif_stop_queue (dev);
+
+ tulip_down (dev);
+
+ if (tulip_debug > 1)
+ printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
+ dev->name, ioread32 (ioaddr + CSR5));
+
+ free_irq (dev->irq, dev);
+
+ tulip_free_ring (dev);
return 0;
}
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 030e02e6302..c227db07962 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -200,7 +200,7 @@ enum uli526x_CR6_bits {
/* Global variable declaration ----------------------------- */
static int __devinitdata printed_version;
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
KERN_INFO DRV_NAME ": ULi M5261/M5263 net driver, version "
DRV_VERSION " (" DRV_RELDATE ")\n";
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index f467bf87817..c61a01b029a 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -139,9 +139,10 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
/* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " DRV_RELDATE " Donald Becker <becker@scyld.com>\n"
-KERN_INFO " http://www.scyld.com/network/drivers.html\n";
+static const char version[] __initconst =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) "
+ DRV_RELDATE " Donald Becker <becker@scyld.com>\n"
+ KERN_INFO " http://www.scyld.com/network/drivers.html\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver");
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index d7b81e4fdd5..a1b0697340b 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -63,6 +63,8 @@
#include <linux/virtio_net.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
+#include <net/rtnetlink.h>
+#include <net/sock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -87,26 +89,127 @@ struct tap_filter {
unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN];
};
+struct tun_file {
+ atomic_t count;
+ struct tun_struct *tun;
+ struct net *net;
+ wait_queue_head_t read_wait;
+};
+
+struct tun_sock;
+
struct tun_struct {
- struct list_head list;
+ struct tun_file *tfile;
unsigned int flags;
- int attached;
uid_t owner;
gid_t group;
- wait_queue_head_t read_wait;
struct sk_buff_head readq;
struct net_device *dev;
struct fasync_struct *fasync;
struct tap_filter txflt;
+ struct sock *sk;
+ struct socket socket;
#ifdef TUN_DEBUG
int debug;
#endif
};
+struct tun_sock {
+ struct sock sk;
+ struct tun_struct *tun;
+};
+
+static inline struct tun_sock *tun_sk(struct sock *sk)
+{
+ return container_of(sk, struct tun_sock, sk);
+}
+
+static int tun_attach(struct tun_struct *tun, struct file *file)
+{
+ struct tun_file *tfile = file->private_data;
+ const struct cred *cred = current_cred();
+ int err;
+
+ ASSERT_RTNL();
+
+ /* Check permissions */
+ if (((tun->owner != -1 && cred->euid != tun->owner) ||
+ (tun->group != -1 && !in_egroup_p(tun->group))) &&
+ !capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ netif_tx_lock_bh(tun->dev);
+
+ err = -EINVAL;
+ if (tfile->tun)
+ goto out;
+
+ err = -EBUSY;
+ if (tun->tfile)
+ goto out;
+
+ err = 0;
+ tfile->tun = tun;
+ tun->tfile = tfile;
+ dev_hold(tun->dev);
+ atomic_inc(&tfile->count);
+
+out:
+ netif_tx_unlock_bh(tun->dev);
+ return err;
+}
+
+static void __tun_detach(struct tun_struct *tun)
+{
+ struct tun_file *tfile = tun->tfile;
+
+ /* Detach from net device */
+ netif_tx_lock_bh(tun->dev);
+ tfile->tun = NULL;
+ tun->tfile = NULL;
+ netif_tx_unlock_bh(tun->dev);
+
+ /* Drop read queue */
+ skb_queue_purge(&tun->readq);
+
+ /* Drop the extra count on the net device */
+ dev_put(tun->dev);
+}
+
+static void tun_detach(struct tun_struct *tun)
+{
+ rtnl_lock();
+ __tun_detach(tun);
+ rtnl_unlock();
+}
+
+static struct tun_struct *__tun_get(struct tun_file *tfile)
+{
+ struct tun_struct *tun = NULL;
+
+ if (atomic_inc_not_zero(&tfile->count))
+ tun = tfile->tun;
+
+ return tun;
+}
+
+static struct tun_struct *tun_get(struct file *file)
+{
+ return __tun_get(file->private_data);
+}
+
+static void tun_put(struct tun_struct *tun)
+{
+ struct tun_file *tfile = tun->tfile;
+
+ if (atomic_dec_and_test(&tfile->count))
+ tun_detach(tfile->tun);
+}
+
/* TAP filterting */
static void addr_hash_set(u32 *mask, const u8 *addr)
{
@@ -157,10 +260,16 @@ static int update_filter(struct tap_filter *filter, void __user *arg)
nexact = n;
- /* The rest is hashed */
+ /* Remaining multicast addresses are hashed,
+ * unicast will leave the filter disabled. */
memset(filter->mask, 0, sizeof(filter->mask));
- for (; n < uf.count; n++)
+ for (; n < uf.count; n++) {
+ if (!is_multicast_ether_addr(addr[n].u)) {
+ err = 0; /* no filter */
+ goto done;
+ }
addr_hash_set(filter->mask, addr[n].u);
+ }
/* For ALLMULTI just set the mask to all ones.
* This overrides the mask populated above. */
@@ -213,13 +322,23 @@ static int check_filter(struct tap_filter *filter, const struct sk_buff *skb)
/* Network device part of the driver */
-static int tun_net_id;
-struct tun_net {
- struct list_head dev_list;
-};
-
static const struct ethtool_ops tun_ethtool_ops;
+/* Net device detach from fd. */
+static void tun_net_uninit(struct net_device *dev)
+{
+ struct tun_struct *tun = netdev_priv(dev);
+ struct tun_file *tfile = tun->tfile;
+
+ /* Inform the methods they need to stop using the dev.
+ */
+ if (tfile) {
+ wake_up_all(&tfile->read_wait);
+ if (atomic_dec_and_test(&tfile->count))
+ __tun_detach(tun);
+ }
+}
+
/* Net device open. */
static int tun_net_open(struct net_device *dev)
{
@@ -242,7 +361,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len);
/* Drop packet if interface is not attached */
- if (!tun->attached)
+ if (!tun->tfile)
goto drop;
/* Drop if the filter does not like it.
@@ -274,7 +393,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
/* Notify and wake up reader process */
if (tun->flags & TUN_FASYNC)
kill_fasync(&tun->fasync, SIGIO, POLL_IN);
- wake_up_interruptible(&tun->read_wait);
+ wake_up_interruptible(&tun->tfile->read_wait);
return 0;
drop:
@@ -306,6 +425,7 @@ tun_net_change_mtu(struct net_device *dev, int new_mtu)
}
static const struct net_device_ops tun_netdev_ops = {
+ .ndo_uninit = tun_net_uninit,
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
@@ -313,6 +433,7 @@ static const struct net_device_ops tun_netdev_ops = {
};
static const struct net_device_ops tap_netdev_ops = {
+ .ndo_uninit = tun_net_uninit,
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
@@ -359,86 +480,66 @@ static void tun_net_init(struct net_device *dev)
/* Poll */
static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
{
- struct tun_struct *tun = file->private_data;
- unsigned int mask = POLLOUT | POLLWRNORM;
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun = __tun_get(tfile);
+ struct sock *sk = tun->sk;
+ unsigned int mask = 0;
if (!tun)
- return -EBADFD;
+ return POLLERR;
DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
- poll_wait(file, &tun->read_wait, wait);
+ poll_wait(file, &tfile->read_wait, wait);
if (!skb_queue_empty(&tun->readq))
mask |= POLLIN | POLLRDNORM;
+ if (sock_writeable(sk) ||
+ (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
+ sock_writeable(sk)))
+ mask |= POLLOUT | POLLWRNORM;
+
+ if (tun->dev->reg_state != NETREG_REGISTERED)
+ mask = POLLERR;
+
+ tun_put(tun);
return mask;
}
/* prepad is the amount to reserve at front. len is length after that.
* linear is a hint as to how much to copy (usually headers). */
-static struct sk_buff *tun_alloc_skb(size_t prepad, size_t len, size_t linear,
- gfp_t gfp)
+static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
+ size_t prepad, size_t len,
+ size_t linear, int noblock)
{
+ struct sock *sk = tun->sk;
struct sk_buff *skb;
- unsigned int i;
-
- skb = alloc_skb(prepad + len, gfp|__GFP_NOWARN);
- if (skb) {
- skb_reserve(skb, prepad);
- skb_put(skb, len);
- return skb;
- }
+ int err;
/* Under a page? Don't bother with paged skb. */
if (prepad + len < PAGE_SIZE)
- return NULL;
+ linear = len;
- /* Start with a normal skb, and add pages. */
- skb = alloc_skb(prepad + linear, gfp);
+ skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
+ &err);
if (!skb)
- return NULL;
+ return ERR_PTR(err);
skb_reserve(skb, prepad);
skb_put(skb, linear);
-
- len -= linear;
-
- for (i = 0; i < MAX_SKB_FRAGS; i++) {
- skb_frag_t *f = &skb_shinfo(skb)->frags[i];
-
- f->page = alloc_page(gfp|__GFP_ZERO);
- if (!f->page)
- break;
-
- f->page_offset = 0;
- f->size = PAGE_SIZE;
-
- skb->data_len += PAGE_SIZE;
- skb->len += PAGE_SIZE;
- skb->truesize += PAGE_SIZE;
- skb_shinfo(skb)->nr_frags++;
-
- if (len < PAGE_SIZE) {
- len = 0;
- break;
- }
- len -= PAGE_SIZE;
- }
-
- /* Too large, or alloc fail? */
- if (unlikely(len)) {
- kfree_skb(skb);
- skb = NULL;
- }
+ skb->data_len = len - linear;
+ skb->len += len - linear;
return skb;
}
/* Get packet from user space buffer */
-static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
+static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
+ struct iovec *iv, size_t count,
+ int noblock)
{
- struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
+ 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 };
@@ -468,9 +569,11 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
return -EINVAL;
}
- if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) {
- tun->dev->stats.rx_dropped++;
- return -ENOMEM;
+ skb = tun_alloc_skb(tun, align, len, gso.hdr_len, noblock);
+ if (IS_ERR(skb)) {
+ if (PTR_ERR(skb) != -EAGAIN)
+ tun->dev->stats.rx_dropped++;
+ return PTR_ERR(skb);
}
if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
@@ -556,14 +659,20 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
unsigned long count, loff_t pos)
{
- struct tun_struct *tun = iocb->ki_filp->private_data;
+ struct file *file = iocb->ki_filp;
+ struct tun_struct *tun = tun_get(file);
+ ssize_t result;
if (!tun)
return -EBADFD;
DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
- return tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count));
+ result = tun_get_user(tun, (struct iovec *)iv, iov_length(iv, count),
+ file->f_flags & O_NONBLOCK);
+
+ tun_put(tun);
+ return result;
}
/* Put packet to the user space buffer */
@@ -636,7 +745,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
unsigned long count, loff_t pos)
{
struct file *file = iocb->ki_filp;
- struct tun_struct *tun = file->private_data;
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun = __tun_get(tfile);
DECLARE_WAITQUEUE(wait, current);
struct sk_buff *skb;
ssize_t len, ret = 0;
@@ -647,10 +757,12 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
len = iov_length(iv, count);
- if (len < 0)
- return -EINVAL;
+ if (len < 0) {
+ ret = -EINVAL;
+ goto out;
+ }
- add_wait_queue(&tun->read_wait, &wait);
+ add_wait_queue(&tfile->read_wait, &wait);
while (len) {
current->state = TASK_INTERRUPTIBLE;
@@ -664,6 +776,10 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
ret = -ERESTARTSYS;
break;
}
+ if (tun->dev->reg_state != NETREG_REGISTERED) {
+ ret = -EIO;
+ break;
+ }
/* Nothing to read, let's sleep */
schedule();
@@ -677,8 +793,10 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
}
current->state = TASK_RUNNING;
- remove_wait_queue(&tun->read_wait, &wait);
+ remove_wait_queue(&tfile->read_wait, &wait);
+out:
+ tun_put(tun);
return ret;
}
@@ -687,54 +805,78 @@ static void tun_setup(struct net_device *dev)
struct tun_struct *tun = netdev_priv(dev);
skb_queue_head_init(&tun->readq);
- init_waitqueue_head(&tun->read_wait);
tun->owner = -1;
tun->group = -1;
dev->ethtool_ops = &tun_ethtool_ops;
dev->destructor = free_netdev;
- dev->features |= NETIF_F_NETNS_LOCAL;
}
-static struct tun_struct *tun_get_by_name(struct tun_net *tn, const char *name)
+/* Trivial set of netlink ops to allow deleting tun or tap
+ * device with netlink.
+ */
+static int tun_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+ return -EINVAL;
+}
+
+static struct rtnl_link_ops tun_link_ops __read_mostly = {
+ .kind = DRV_NAME,
+ .priv_size = sizeof(struct tun_struct),
+ .setup = tun_setup,
+ .validate = tun_validate,
+};
+
+static void tun_sock_write_space(struct sock *sk)
{
struct tun_struct *tun;
- ASSERT_RTNL();
- list_for_each_entry(tun, &tn->dev_list, list) {
- if (!strncmp(tun->dev->name, name, IFNAMSIZ))
- return tun;
- }
+ if (!sock_writeable(sk))
+ return;
+
+ if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ wake_up_interruptible_sync(sk->sk_sleep);
- return NULL;
+ if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
+ return;
+
+ tun = container_of(sk, struct tun_sock, sk)->tun;
+ kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
+}
+
+static void tun_sock_destruct(struct sock *sk)
+{
+ dev_put(container_of(sk, struct tun_sock, sk)->tun->dev);
}
+static struct proto tun_proto = {
+ .name = "tun",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct tun_sock),
+};
+
static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
{
- struct tun_net *tn;
+ struct sock *sk;
struct tun_struct *tun;
struct net_device *dev;
- const struct cred *cred = current_cred();
+ struct tun_file *tfile = file->private_data;
int err;
- tn = net_generic(net, tun_net_id);
- tun = tun_get_by_name(tn, ifr->ifr_name);
- if (tun) {
- if (tun->attached)
- return -EBUSY;
-
- /* Check permissions */
- if (((tun->owner != -1 &&
- cred->euid != tun->owner) ||
- (tun->group != -1 &&
- cred->egid != tun->group)) &&
- !capable(CAP_NET_ADMIN)) {
- return -EPERM;
- }
+ dev = __dev_get_by_name(net, ifr->ifr_name);
+ if (dev) {
+ 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)
+ tun = netdev_priv(dev);
+ else
+ return -EINVAL;
+
+ err = tun_attach(tun, file);
+ if (err < 0)
+ return err;
}
- else if (__dev_get_by_name(net, ifr->ifr_name))
- return -EINVAL;
else {
char *name;
unsigned long flags = 0;
@@ -765,25 +907,45 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return -ENOMEM;
dev_net_set(dev, net);
+ dev->rtnl_link_ops = &tun_link_ops;
tun = netdev_priv(dev);
tun->dev = dev;
tun->flags = flags;
tun->txflt.count = 0;
+ err = -ENOMEM;
+ sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
+ if (!sk)
+ goto err_free_dev;
+
+ /* This ref count is for tun->sk. */
+ dev_hold(dev);
+ sock_init_data(&tun->socket, sk);
+ sk->sk_write_space = tun_sock_write_space;
+ sk->sk_destruct = tun_sock_destruct;
+ sk->sk_sndbuf = INT_MAX;
+ sk->sk_sleep = &tfile->read_wait;
+
+ tun->sk = sk;
+ container_of(sk, struct tun_sock, sk)->tun = tun;
+
tun_net_init(dev);
if (strchr(dev->name, '%')) {
err = dev_alloc_name(dev, dev->name);
if (err < 0)
- goto err_free_dev;
+ goto err_free_sk;
}
+ err = -EINVAL;
err = register_netdevice(tun->dev);
if (err < 0)
goto err_free_dev;
- list_add(&tun->list, &tn->dev_list);
+ err = tun_attach(tun, file);
+ if (err < 0)
+ goto err_free_dev;
}
DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name);
@@ -803,10 +965,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
else
tun->flags &= ~TUN_VNET_HDR;
- file->private_data = tun;
- tun->attached = 1;
- get_net(dev_net(tun->dev));
-
/* Make sure persistent devices do not get stuck in
* xoff state.
*/
@@ -816,6 +974,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
strcpy(ifr->ifr_name, tun->dev->name);
return 0;
+ err_free_sk:
+ sock_put(sk);
err_free_dev:
free_netdev(dev);
failed:
@@ -824,7 +984,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
{
- struct tun_struct *tun = file->private_data;
+ struct tun_struct *tun = tun_get(file);
if (!tun)
return -EBADFD;
@@ -849,6 +1009,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
if (tun->flags & TUN_VNET_HDR)
ifr->ifr_flags |= IFF_VNET_HDR;
+ tun_put(tun);
return 0;
}
@@ -895,22 +1056,34 @@ static int set_offload(struct net_device *dev, unsigned long arg)
static int tun_chr_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct tun_struct *tun = file->private_data;
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun;
void __user* argp = (void __user*)arg;
struct ifreq ifr;
+ int sndbuf;
int ret;
if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
if (copy_from_user(&ifr, argp, sizeof ifr))
return -EFAULT;
+ if (cmd == TUNGETFEATURES) {
+ /* Currently this just means: "what IFF flags are valid?".
+ * This is needed because we never checked for invalid flags on
+ * TUNSETIFF. */
+ return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
+ IFF_VNET_HDR,
+ (unsigned int __user*)argp);
+ }
+
+ tun = __tun_get(tfile);
if (cmd == TUNSETIFF && !tun) {
int err;
ifr.ifr_name[IFNAMSIZ-1] = '\0';
rtnl_lock();
- err = tun_set_iff(current->nsproxy->net_ns, file, &ifr);
+ err = tun_set_iff(tfile->net, file, &ifr);
rtnl_unlock();
if (err)
@@ -921,28 +1094,21 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
return 0;
}
- if (cmd == TUNGETFEATURES) {
- /* Currently this just means: "what IFF flags are valid?".
- * This is needed because we never checked for invalid flags on
- * TUNSETIFF. */
- return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
- IFF_VNET_HDR,
- (unsigned int __user*)argp);
- }
if (!tun)
return -EBADFD;
DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
+ ret = 0;
switch (cmd) {
case TUNGETIFF:
ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
if (ret)
- return ret;
+ break;
if (copy_to_user(argp, &ifr, sizeof(ifr)))
- return -EFAULT;
+ ret = -EFAULT;
break;
case TUNSETNOCSUM:
@@ -994,7 +1160,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
ret = 0;
}
rtnl_unlock();
- return ret;
+ break;
#ifdef TUN_DEBUG
case TUNSETDEBUG:
@@ -1005,24 +1171,25 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
rtnl_lock();
ret = set_offload(tun->dev, arg);
rtnl_unlock();
- return ret;
+ break;
case TUNSETTXFILTER:
/* Can be set only for TAPs */
+ ret = -EINVAL;
if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
- return -EINVAL;
+ break;
rtnl_lock();
ret = update_filter(&tun->txflt, (void __user *)arg);
rtnl_unlock();
- return ret;
+ break;
case SIOCGIFHWADDR:
/* Get hw addres */
memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
ifr.ifr_hwaddr.sa_family = tun->dev->type;
if (copy_to_user(argp, &ifr, sizeof ifr))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ break;
case SIOCSIFHWADDR:
/* Set hw address */
@@ -1032,18 +1199,35 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
rtnl_lock();
ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
rtnl_unlock();
- return ret;
+ break;
+
+ case TUNGETSNDBUF:
+ sndbuf = tun->sk->sk_sndbuf;
+ if (copy_to_user(argp, &sndbuf, sizeof(sndbuf)))
+ ret = -EFAULT;
+ break;
+
+ case TUNSETSNDBUF:
+ if (copy_from_user(&sndbuf, argp, sizeof(sndbuf))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ tun->sk->sk_sndbuf = sndbuf;
+ break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ break;
};
- return 0;
+ tun_put(tun);
+ return ret;
}
static int tun_chr_fasync(int fd, struct file *file, int on)
{
- struct tun_struct *tun = file->private_data;
+ struct tun_struct *tun = tun_get(file);
int ret;
if (!tun)
@@ -1065,42 +1249,50 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
ret = 0;
out:
unlock_kernel();
+ tun_put(tun);
return ret;
}
static int tun_chr_open(struct inode *inode, struct file * file)
{
+ struct tun_file *tfile;
cycle_kernel_lock();
DBG1(KERN_INFO "tunX: tun_chr_open\n");
- file->private_data = NULL;
+
+ tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
+ if (!tfile)
+ return -ENOMEM;
+ atomic_set(&tfile->count, 0);
+ tfile->tun = NULL;
+ tfile->net = get_net(current->nsproxy->net_ns);
+ init_waitqueue_head(&tfile->read_wait);
+ file->private_data = tfile;
return 0;
}
static int tun_chr_close(struct inode *inode, struct file *file)
{
- struct tun_struct *tun = file->private_data;
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun = __tun_get(tfile);
- if (!tun)
- return 0;
-
- DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
- rtnl_lock();
+ if (tun) {
+ DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
- /* Detach from net device */
- file->private_data = NULL;
- tun->attached = 0;
- put_net(dev_net(tun->dev));
+ rtnl_lock();
+ __tun_detach(tun);
- /* Drop read queue */
- skb_queue_purge(&tun->readq);
+ /* If desireable, unregister the netdevice. */
+ if (!(tun->flags & TUN_PERSIST)) {
+ sock_put(tun->sk);
+ unregister_netdevice(tun->dev);
+ }
- if (!(tun->flags & TUN_PERSIST)) {
- list_del(&tun->list);
- unregister_netdevice(tun->dev);
+ rtnl_unlock();
}
- rtnl_unlock();
+ put_net(tfile->net);
+ kfree(tfile);
return 0;
}
@@ -1181,7 +1373,7 @@ static void tun_set_msglevel(struct net_device *dev, u32 value)
static u32 tun_get_link(struct net_device *dev)
{
struct tun_struct *tun = netdev_priv(dev);
- return tun->attached;
+ return !!tun->tfile;
}
static u32 tun_get_rx_csum(struct net_device *dev)
@@ -1210,45 +1402,6 @@ static const struct ethtool_ops tun_ethtool_ops = {
.set_rx_csum = tun_set_rx_csum
};
-static int tun_init_net(struct net *net)
-{
- struct tun_net *tn;
-
- tn = kmalloc(sizeof(*tn), GFP_KERNEL);
- if (tn == NULL)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&tn->dev_list);
-
- if (net_assign_generic(net, tun_net_id, tn)) {
- kfree(tn);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void tun_exit_net(struct net *net)
-{
- struct tun_net *tn;
- struct tun_struct *tun, *nxt;
-
- tn = net_generic(net, tun_net_id);
-
- rtnl_lock();
- list_for_each_entry_safe(tun, nxt, &tn->dev_list, list) {
- DBG(KERN_INFO "%s cleaned up\n", tun->dev->name);
- unregister_netdevice(tun->dev);
- }
- rtnl_unlock();
-
- kfree(tn);
-}
-
-static struct pernet_operations tun_net_ops = {
- .init = tun_init_net,
- .exit = tun_exit_net,
-};
static int __init tun_init(void)
{
@@ -1257,10 +1410,10 @@ static int __init tun_init(void)
printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
- ret = register_pernet_gen_device(&tun_net_id, &tun_net_ops);
+ ret = rtnl_link_register(&tun_link_ops);
if (ret) {
- printk(KERN_ERR "tun: Can't register pernet ops\n");
- goto err_pernet;
+ printk(KERN_ERR "tun: Can't register link_ops\n");
+ goto err_linkops;
}
ret = misc_register(&tun_miscdev);
@@ -1268,18 +1421,17 @@ static int __init tun_init(void)
printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
goto err_misc;
}
- return 0;
-
+ return 0;
err_misc:
- unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
-err_pernet:
+ rtnl_link_unregister(&tun_link_ops);
+err_linkops:
return ret;
}
static void tun_cleanup(void)
{
misc_deregister(&tun_miscdev);
- unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
+ rtnl_link_unregister(&tun_link_ops);
}
module_init(tun_init);
diff --git a/drivers/net/typhoon-firmware.h b/drivers/net/typhoon-firmware.h
deleted file mode 100644
index 182d69e99fc..00000000000
--- a/drivers/net/typhoon-firmware.h
+++ /dev/null
@@ -1,3778 +0,0 @@
-/*
- * Copyright 1999-2004 3Com Corporation. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms of the 3c990img.h
- * microcode software are permitted provided that the following conditions
- * are met:
- * 1. Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistribution 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. The name of 3Com may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY 3COM ``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 AUTHOR 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.
- *
- * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3c990img.h
- * MICROCODE SOFTWARE WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY
- * IMPLICATION, ESTOPPEL, OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS
- * (PATENT, COPYRIGHT, TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT)
- * EMBODIED IN ANY OTHER 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN
- * COMBINATION WITH THE 3c990img.h MICROCODE SOFTWARE
- */
-
- /* ver 03.001.008 */
-static const u8 typhoon_firmware_image[] = {
-0x54, 0x59, 0x50, 0x48, 0x4f, 0x4f, 0x4e, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x99, 0xb1, 0xd4,
-0x4c, 0xb8, 0xd0, 0x4b, 0x32, 0x02, 0xd4, 0xee, 0x73, 0x7e, 0x0b, 0x13,
-0x9b, 0xc0, 0xae, 0xf4, 0x40, 0x01, 0x00, 0x00, 0xe8, 0xfc, 0x00, 0x00,
-0x00, 0x00, 0xff, 0xff, 0x39, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00, 0xea,
-0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
-0x01, 0x00, 0x00, 0xea, 0x32, 0x02, 0x00, 0xea, 0xc5, 0x14, 0x00, 0xea,
-0x07, 0x00, 0x2d, 0xe9, 0x0e, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0x0f, 0xe1,
-0xd0, 0x20, 0x9f, 0xe5, 0x12, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea,
-0x01, 0x00, 0x80, 0xe0, 0x04, 0x20, 0x81, 0xe4, 0x01, 0x00, 0x50, 0xe1,
-0xfc, 0xff, 0xff, 0x1a, 0x0e, 0xf0, 0xa0, 0xe1, 0x00, 0xa0, 0xa0, 0xe1,
-0x0e, 0xb0, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0xa8, 0x10, 0x9f, 0xe5,
-0x00, 0x00, 0x81, 0xe5, 0xa4, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x81, 0xe5,
-0x01, 0x16, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x80, 0xe3,
-0x00, 0x00, 0x81, 0xe5, 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x88, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x7c, 0xd0, 0x9f, 0xe5, 0xd2, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x74, 0xd0, 0x9f, 0xe5, 0xd1, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x6c, 0xd0, 0x9f, 0xe5, 0x9b, 0x14, 0x00, 0xeb, 0xd3, 0x00, 0xa0, 0xe3,
-0x00, 0xf0, 0x21, 0xe1, 0x60, 0xd0, 0x9f, 0xe5, 0x60, 0x00, 0x9f, 0xe5,
-0x60, 0x10, 0x9f, 0xe5, 0x60, 0x20, 0x9f, 0xe5, 0xdb, 0xff, 0xff, 0xeb,
-0x5c, 0x00, 0x9f, 0xe5, 0x5c, 0x10, 0x9f, 0xe5, 0x00, 0x20, 0xa0, 0xe3,
-0xd7, 0xff, 0xff, 0xeb, 0x54, 0x00, 0x9f, 0xe5, 0x54, 0x10, 0x9f, 0xe5,
-0xd4, 0xff, 0xff, 0xeb, 0x0a, 0x00, 0xa0, 0xe1, 0x0b, 0xf0, 0xa0, 0xe1,
-0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0xd4, 0xff, 0xff, 0xeb,
-0x3c, 0xa0, 0x9f, 0xe5, 0x1a, 0xff, 0x2f, 0xe1, 0xc6, 0xff, 0xff, 0xea,
-0x15, 0x21, 0xff, 0xff, 0x0c, 0x00, 0x10, 0x00, 0x1c, 0x00, 0x10, 0x00,
-0x3c, 0x38, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80,
-0x7c, 0x34, 0x00, 0x80, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80,
-0xad, 0xde, 0xad, 0xde, 0xb0, 0xbb, 0x00, 0x00, 0x24, 0xab, 0x20, 0x40,
-0x48, 0x29, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80, 0xbd, 0xba, 0x21, 0x40,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x58, 0x57, 0x00, 0x00, 0x86, 0x4b, 0x00, 0x00, 0x60, 0x01, 0xff, 0xff,
-0xb0, 0xb5, 0x07, 0x1c, 0x12, 0x4d, 0x00, 0x24, 0x28, 0x68, 0x00, 0x28,
-0x1e, 0xd0, 0x38, 0x1c, 0x10, 0x49, 0x04, 0xf0, 0x7b, 0xfd, 0x29, 0x68,
-0xc0, 0x46, 0x08, 0x60, 0x00, 0x28, 0x15, 0xd0, 0x38, 0x01, 0x0d, 0x49,
-0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x80, 0x29,
-0x0c, 0xd2, 0x01, 0x31, 0x41, 0x63, 0x28, 0x68, 0xc1, 0x69, 0xc0, 0x46,
-0x29, 0x60, 0x39, 0x07, 0x41, 0x60, 0x04, 0x62, 0xc7, 0x62, 0xb0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, 0xe8, 0x17, 0x00, 0x80,
-0xee, 0x05, 0x00, 0x00, 0xa0, 0x1c, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68,
-0xc0, 0x46, 0xc2, 0x61, 0x08, 0x60, 0x70, 0x47,
-0xe8, 0x17, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00,
-0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe1, 0x00, 0x10, 0xa0, 0xe1,
-0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1,
-0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1,
-0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1,
-0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0x40, 0x00, 0x80, 0xe3,
-0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1,
-0x80, 0x00, 0x10, 0xe3, 0x80, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x00, 0x00, 0x00, 0x12, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x50, 0xe3,
-0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0x13, 0x00, 0xf0, 0x21, 0xe1,
-0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3,
-0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x91, 0x00, 0x00, 0xe0,
-0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x20, 0x80, 0xe0, 0x01, 0x00, 0x80, 0xe0,
-0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x08, 0x4f, 0x64, 0x28, 0x04, 0xd3,
-0x64, 0x20, 0x38, 0x63, 0x00, 0x20, 0xc0, 0x43, 0x03, 0xe0, 0x38, 0x63,
-0x04, 0x49, 0x05, 0xf0, 0x01, 0xfb, 0x78, 0x63, 0xb8, 0x63, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x88, 0x13, 0x00, 0x00,
-0x80, 0xb4, 0x10, 0x4b, 0x00, 0x22, 0x1f, 0x6b, 0x64, 0x2f, 0x03, 0xd2,
-0x09, 0x68, 0x09, 0x68, 0x49, 0x08, 0x02, 0xd2, 0x10, 0x1c, 0x80, 0xbc,
-0x70, 0x47, 0x19, 0x1c, 0xdb, 0x6b, 0x4f, 0x6b, 0xbb, 0x42, 0x05, 0xd2,
-0x40, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x18, 0x18, 0xc8, 0x63, 0xf1, 0xe7,
-0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x04, 0x48, 0xc1, 0x6b,
-0x01, 0x31, 0xc1, 0x63, 0x02, 0x20, 0xe8, 0xe7, 0x68, 0x0e, 0x00, 0x80,
-0x00, 0x00, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c,
-0x15, 0x4c, 0x00, 0x20, 0x21, 0x6b, 0x64, 0x29, 0x0b, 0xd2, 0xb9, 0x6e,
-0x49, 0x08, 0x08, 0xd3, 0x21, 0x6c, 0xa2, 0x6b, 0x91, 0x42, 0x07, 0xd2,
-0xfa, 0x1d, 0x39, 0x32, 0x52, 0x8b, 0x89, 0x18, 0x21, 0x64, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62,
-0x38, 0x6b, 0x02, 0xf0, 0x2d, 0xfe, 0x38, 0x1c, 0x02, 0xf0, 0xe8, 0xfa,
-0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x73, 0x05, 0x49,
-0x0a, 0x6c, 0x12, 0x18, 0x0a, 0x64, 0x04, 0x49, 0x8a, 0x6d, 0x12, 0x18,
-0x8a, 0x65, 0xe4, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80,
-0xa4, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x0a, 0x48, 0xc0, 0x6d, 0x02, 0x23,
-0x18, 0x40, 0x09, 0x4a, 0x00, 0x21, 0x00, 0x28, 0x03, 0xd0, 0xd1, 0x63,
-0x11, 0x64, 0x80, 0xbc, 0x70, 0x47, 0x06, 0x48, 0x07, 0x68, 0x7b, 0x1c,
-0x03, 0x60, 0x0a, 0x2f, 0xf7, 0xd3, 0x01, 0x60, 0xf3, 0xe7, 0x00, 0x00,
-0xa4, 0x2a, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0xe0, 0x01, 0x00, 0x80,
-0x70, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x00, 0x0c, 0x10, 0x18, 0x0a, 0x04,
-0x12, 0x0c, 0x09, 0x0c, 0x51, 0x18, 0x08, 0x18, 0x01, 0x0c, 0x05, 0xd0,
-0x01, 0x04, 0x09, 0x0c, 0x00, 0x0c, 0x08, 0x18, 0x01, 0x0c, 0xf9, 0xd1,
-0x00, 0x04, 0x00, 0x0c, 0x70, 0x47, 0x80, 0xb4, 0x00, 0x22, 0x00, 0x29,
-0x18, 0xd0, 0x4f, 0x08, 0x7b, 0x1e, 0x00, 0x2f,
-0x06, 0xd0, 0x07, 0x88, 0xba, 0x18, 0x02, 0x30, 0x1f, 0x1c, 0x01, 0x3b,
-0x00, 0x2f, 0xf8, 0xd1, 0x49, 0x08, 0x03, 0xd3, 0x00, 0x88, 0x00, 0x06,
-0x00, 0x0e, 0x82, 0x18, 0x10, 0x0c, 0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c,
-0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c,
-0x80, 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x83, 0x89, 0xc7, 0x89, 0xfb, 0x18,
-0x07, 0x8a, 0xfb, 0x18, 0x47, 0x8a, 0xfb, 0x18, 0x40, 0x7a, 0x00, 0x02,
-0xc7, 0x18, 0x38, 0x0c, 0x05, 0xd0, 0x38, 0x04, 0x00, 0x0c, 0x3b, 0x0c,
-0xc7, 0x18, 0x38, 0x0c, 0xf9, 0xd1, 0x08, 0x1c, 0x11, 0x1c, 0xff, 0xf7,
-0xc8, 0xff, 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0xb0, 0xff, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x02, 0x23, 0x82, 0x68, 0x1a, 0x40,
-0x00, 0x27, 0x00, 0x2a, 0x0f, 0xd0, 0x0a, 0x4a, 0x93, 0x69, 0x01, 0x33,
-0x93, 0x61, 0x0a, 0x68, 0x8b, 0x68, 0x9a, 0x18, 0x00, 0x68, 0x1c, 0x18,
-0x57, 0x81, 0x09, 0x69, 0x10, 0x1c, 0xff, 0xf7, 0xac, 0xff, 0xc0, 0x43,
-0x60, 0x81, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x23, 0x82, 0x68, 0x1a, 0x40,
-0x00, 0x27, 0x00, 0x2a, 0x11, 0xd0, 0x4a, 0x68, 0x52, 0x09, 0x0e, 0xd3,
-0x09, 0x4a, 0x13, 0x6a, 0x01, 0x33, 0x13, 0x62, 0xcb, 0x68, 0x02, 0x68,
-0x9c, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, 0x1a, 0x43, 0x12, 0x68,
-0x00, 0xf0, 0x2e, 0xf8, 0x20, 0x82, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x80, 0x23,
-0x82, 0x68, 0x1a, 0x40, 0x00, 0x24, 0x00, 0x2a, 0x15, 0xd0, 0x4a, 0x68,
-0x92, 0x09, 0x12, 0xd3, 0x0b, 0x4a, 0xd3, 0x69, 0x01, 0x33, 0xd3, 0x61,
-0xcb, 0x68, 0x02, 0x68, 0x9f, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a,
-0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x0e, 0xf8, 0x00, 0x28, 0x00, 0xd1,
-0x04, 0x48, 0xc0, 0x46, 0xf8, 0x80, 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00,
-0xb0, 0xb5, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0x1c, 0x38, 0x69, 0xb9, 0x68,
-0x41, 0x18, 0x38, 0x68, 0xff, 0xf7, 0x53, 0xff, 0xc0, 0x43, 0x01, 0x04,
-0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x39, 0xff, 0x04, 0x1c, 0xb8, 0x68,
-0x79, 0x69, 0x40, 0x18, 0x69, 0x68, 0x88, 0x42, 0x0c, 0xd2, 0x2a, 0x68,
-0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 0x05, 0xf9, 0xc0, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x26, 0xff, 0x04, 0x1c,
-0xe0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0xc0, 0x08, 0x1a, 0xd3, 0xb8, 0x6a,
-0xf9, 0x6b, 0x40, 0x18, 0x79, 0x6c, 0x00, 0xf0, 0xed, 0xf8, 0xc0, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x0a, 0x48, 0x07, 0xd0, 0x20, 0x23, 0xb9, 0x69,
-0x19, 0x43, 0xb9, 0x61, 0x01, 0x6b, 0x01, 0x31, 0x01, 0x63, 0x07, 0xe0,
-0xff, 0x23, 0x01, 0x33, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x41, 0x6a,
-0x01, 0x31, 0x41, 0x62, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x0c, 0x2b, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0x41, 0x09,
-0x1c, 0xd3, 0xc0, 0x08, 0x1a, 0xd3, 0xf8, 0x1d, 0x39, 0x30, 0x00, 0x7b,
-0x06, 0x28, 0x15, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 0x53, 0xf8, 0x01, 0x1c,
-0x0a, 0x48, 0x07, 0xd0, 0x40, 0x23, 0xb9, 0x69,
-0x19, 0x43, 0xb9, 0x61, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x07, 0xe0,
-0x01, 0x23, 0x9b, 0x02, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0xc1, 0x6a,
-0x01, 0x31, 0xc1, 0x62, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x0c, 0x2b, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0x81, 0x09,
-0x2c, 0xd3, 0xc0, 0x08, 0x2a, 0xd3, 0xf8, 0x1d, 0x39, 0x30, 0x00, 0x7b,
-0x11, 0x28, 0x25, 0xd1, 0xb8, 0x6a, 0x39, 0x6c, 0x40, 0x18, 0x01, 0x23,
-0x9b, 0x07, 0x06, 0x30, 0x18, 0x43, 0x00, 0x68, 0x05, 0x04, 0x2d, 0x0c,
-0x0f, 0x4c, 0x11, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0x00, 0x28,
-0x0c, 0xd0, 0xa8, 0x42, 0x02, 0xd1, 0x0c, 0x4b, 0x98, 0x42, 0x07, 0xd0,
-0x80, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0x60, 0x6b, 0x01, 0x30,
-0x60, 0x63, 0x07, 0xe0, 0x01, 0x23, 0x5b, 0x02, 0xb8, 0x69, 0x18, 0x43,
-0xb8, 0x61, 0xa0, 0x6a, 0x01, 0x30, 0xa0, 0x62, 0x00, 0x20, 0xb0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00,
-0xf0, 0xb5, 0xff, 0xb0, 0x99, 0xb0, 0x04, 0x1c, 0xe0, 0x6b, 0x61, 0x6c,
-0x09, 0x18, 0x03, 0xaa, 0x85, 0x18, 0xa3, 0x6a, 0x00, 0x20, 0x8a, 0x08,
-0x01, 0x32, 0x97, 0x92, 0x07, 0xd0, 0x82, 0x00, 0x9f, 0x58, 0x03, 0xae,
-0xb7, 0x50, 0x97, 0x9a, 0x01, 0x30, 0x82, 0x42, 0xf7, 0xd8, 0x60, 0x6a,
-0x01, 0x23, 0x9b, 0x07, 0x04, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46,
-0x02, 0x90, 0x02, 0xaf, 0x3f, 0x88, 0x03, 0xa8, 0xff, 0xf7, 0x87, 0xfe,
-0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 0x6d, 0xfe,
-0x07, 0x1c, 0xe0, 0x6b, 0xa1, 0x6c, 0x40, 0x18, 0x61, 0x6a, 0x01, 0x23,
-0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x01, 0x91,
-0x01, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x88, 0x42, 0x0c, 0xd2, 0xa2, 0x6a,
-0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 0x2f, 0xf8, 0xc0, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0x07, 0x1c,
-0xa8, 0x89, 0xe9, 0x89, 0x08, 0x18, 0x29, 0x8a, 0x08, 0x18, 0x69, 0x8a,
-0x08, 0x18, 0x69, 0x7a, 0x09, 0x02, 0x08, 0x18, 0xa1, 0x6c, 0x62, 0x6c,
-0x89, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 0x12, 0x0a, 0x11, 0x43,
-0x09, 0x04, 0x09, 0x0c, 0x09, 0x18, 0x08, 0x0c, 0x05, 0xd0, 0x08, 0x04,
-0x00, 0x0c, 0x09, 0x0c, 0x41, 0x18, 0x08, 0x0c, 0xf9, 0xd1, 0x38, 0x1c,
-0xff, 0xf7, 0x2f, 0xfe, 0xc0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x7f, 0xb0,
-0x19, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb4, 0x00, 0x22,
-0x00, 0x29, 0x2e, 0xd0, 0x83, 0x07, 0x9b, 0x0f, 0xdc, 0x00, 0x47, 0x18,
-0x04, 0x25, 0xef, 0x1b, 0xbf, 0x07, 0xbf, 0x0f, 0xff, 0x00, 0x80, 0x08,
-0x80, 0x00, 0x59, 0x18, 0x03, 0x31, 0x89, 0x08, 0x4d, 0x1e, 0x02, 0xc8,
-0xe1, 0x40, 0xa1, 0x40, 0x6b, 0x1e, 0x00, 0x2d, 0x09, 0xd0, 0x0c, 0x04,
-0x24, 0x0c, 0xa2, 0x18, 0x09, 0x0c, 0x8a, 0x18, 0x02, 0xc8, 0x1c, 0x1c,
-0x01, 0x3b, 0x00, 0x2c, 0xf5, 0xd1, 0xb9, 0x40, 0x08, 0x1c, 0xf8, 0x40,
-0x01, 0x04, 0x09, 0x0c, 0x89, 0x18, 0x00, 0x0c, 0x42, 0x18, 0x10, 0x0c,
-0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c,
-0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00,
-0x90, 0xb4, 0x00, 0x20, 0x01, 0x27, 0x11, 0x49, 0x42, 0x00, 0x12, 0x18,
-0xd2, 0x00, 0x53, 0x18, 0x9c, 0x68, 0x01, 0x23,
-0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x03, 0x1b, 0x0b, 0x8a, 0x58,
-0x12, 0x03, 0x12, 0x0b, 0x93, 0x42, 0x0c, 0xd1, 0x01, 0x30, 0x04, 0x28,
-0xec, 0xd3, 0x08, 0x48, 0xc0, 0x6a, 0x01, 0x03, 0x09, 0x0b, 0x07, 0x48,
-0x00, 0x6f, 0x00, 0x03, 0x00, 0x0b, 0x81, 0x42, 0x02, 0xd0, 0x38, 0x1c,
-0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0xa8, 0x03, 0x00, 0x80,
-0x00, 0x40, 0x14, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x98, 0xb4, 0x14, 0x4a,
-0xc0, 0x46, 0x00, 0x92, 0x83, 0x00, 0x13, 0x48, 0xc0, 0x58, 0x07, 0x03,
-0x3f, 0x0b, 0x12, 0x48, 0xc0, 0x58, 0x02, 0x03, 0x12, 0x0b, 0x11, 0x48,
-0xc0, 0x58, 0x00, 0x03, 0x00, 0x0b, 0x10, 0x4c, 0xe4, 0x58, 0x01, 0x23,
-0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x9b, 0x00, 0xcc, 0x00, 0x01, 0x21,
-0x98, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x09, 0xe0, 0x98, 0x42, 0x03, 0xd9,
-0x10, 0x1a, 0xda, 0x1b, 0x80, 0x18, 0x00, 0xe0, 0x18, 0x1a, 0x84, 0x42,
-0xf4, 0xd3, 0x00, 0x20, 0x98, 0xbc, 0x70, 0x47, 0x55, 0x55, 0x55, 0x55,
-0x20, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x80, 0x08, 0x04, 0x00, 0x80,
-0x18, 0x04, 0x00, 0x80, 0x80, 0xb4, 0x13, 0x04, 0x00, 0xd0, 0x01, 0x3a,
-0x80, 0x00, 0x0b, 0x1c, 0x13, 0x49, 0x0f, 0x58, 0xc0, 0x46, 0x3b, 0x60,
-0x0b, 0x58, 0xc0, 0x46, 0x5a, 0x60, 0x0a, 0x58, 0x08, 0x32, 0x10, 0x4b,
-0x1b, 0x58, 0x9a, 0x42, 0x01, 0xd3, 0x0f, 0x4a, 0x12, 0x58, 0x0f, 0x4b,
-0x1f, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 0x1b, 0x68, 0x9b, 0x00,
-0x17, 0x03, 0x3f, 0x0b, 0x9f, 0x42, 0x06, 0xd1, 0x0a, 0x48, 0xc1, 0x68,
-0x01, 0x31, 0xc1, 0x60, 0x01, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x08, 0x4b,
-0x1b, 0x58, 0xc0, 0x46, 0x1a, 0x60, 0x0a, 0x50, 0x00, 0x20, 0xf6, 0xe7,
-0x08, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x80, 0x20, 0x04, 0x00, 0x80,
-0x18, 0x04, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x10, 0x04, 0x00, 0x80,
-0xff, 0x5f, 0x2d, 0xe9, 0x48, 0xfe, 0xff, 0xeb, 0x01, 0xb6, 0xa0, 0xe3,
-0x01, 0xb1, 0x8b, 0xe2, 0x02, 0x8a, 0xa0, 0xe3, 0x01, 0x7a, 0xa0, 0xe3,
-0x01, 0xa9, 0xa0, 0xe3, 0x01, 0x56, 0xa0, 0xe3, 0xc8, 0x60, 0x9f, 0xe5,
-0xc8, 0x90, 0x9f, 0xe5, 0x14, 0x40, 0x9b, 0xe5, 0x00, 0x00, 0x54, 0xe3,
-0x2c, 0x00, 0x00, 0x0a, 0x03, 0x0a, 0x14, 0xe3, 0x11, 0x00, 0x00, 0x0a,
-0x0c, 0x00, 0x96, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x21, 0x00, 0x00, 0x0a,
-0x01, 0x0a, 0x14, 0xe3, 0x05, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5,
-0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5,
-0x14, 0x70, 0x85, 0xe5, 0x06, 0x00, 0x00, 0xea, 0x02, 0x0a, 0x14, 0xe3,
-0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 0x02, 0x0a, 0xc0, 0xe3,
-0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 0x14, 0x80, 0x85, 0xe5,
-0x01, 0x09, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5,
-0x01, 0x09, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5,
-0x14, 0xa0, 0x85, 0xe5, 0x02, 0x00, 0x14, 0xe3, 0x40, 0x00, 0x00, 0x1b,
-0x01, 0x00, 0x14, 0xe3, 0x54, 0x00, 0x00, 0x1b, 0x02, 0x0b, 0x14, 0xe3,
-0x67, 0x00, 0x00, 0x1b, 0x01, 0x0b, 0x14, 0xe3, 0x20, 0x00, 0x00, 0x1b,
-0x18, 0x00, 0x99, 0xe5, 0x01, 0x00, 0x80, 0xe2, 0x18, 0x00, 0x89, 0xe5,
-0xd5, 0xff, 0xff, 0xea, 0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3,
-0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5,
-0x14, 0x70, 0x85, 0xe5, 0xe1, 0xff, 0xff, 0xea, 0xff, 0x5f, 0xbd, 0xe8,
-0x04, 0xf0, 0x5e, 0xe2, 0x68, 0x0e, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40,
-0x10, 0x10, 0x1f, 0xe5, 0x14, 0x30, 0x91, 0xe5, 0x00, 0x20, 0xc3, 0xe1,
-0x14, 0x20, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x0c, 0x20, 0x81, 0xe5,
-0x0b, 0x12, 0xa0, 0xe3, 0x00, 0x00, 0x81, 0xe5, 0x18, 0x10, 0x9f, 0xe5,
-0xb0, 0x24, 0xd1, 0xe1, 0x01, 0x20, 0x82, 0xe2, 0xb0, 0x24, 0xc1, 0xe1,
-0x3c, 0x20, 0x91, 0xe5, 0x00, 0x00, 0x82, 0xe1, 0x3c, 0x00, 0x81, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xa0, 0x82, 0x20, 0x40, 0xff, 0xff, 0xff, 0xea,
-0xfe, 0xff, 0xff, 0xea, 0x01, 0x0b, 0xa0, 0xe3, 0x01, 0x16, 0xa0, 0xe3,
-0x14, 0x00, 0x81, 0xe5, 0x00, 0x1a, 0x81, 0xe1, 0x24, 0x20, 0x91, 0xe5,
-0x70, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x24, 0x20, 0x80, 0xe5,
-0x28, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0x80, 0xe5,
-0x2c, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, 0x2c, 0x20, 0x80, 0xe5,
-0x3f, 0x00, 0x01, 0xe2, 0x3f, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11,
-0x18, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x10, 0x81, 0xe2,
-0x00, 0x10, 0x80, 0xe5, 0x02, 0x18, 0xa0, 0xe3, 0x0b, 0x02, 0xa0, 0xe3,
-0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x04, 0x00, 0x80,
-0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5,
-0x01, 0x08, 0x11, 0xe3, 0x0b, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2,
-0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1,
-0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3,
-0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3, 0x4c, 0x11, 0x80, 0xe5,
-0x03, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0x00,
-0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
-0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2,
-0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 0x0c, 0x10, 0xa0, 0xe3,
-0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5,
-0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5,
-0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3,
-0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 0x4c, 0x00, 0x1f, 0xe5,
-0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea,
-0xfe, 0xff, 0xff, 0xea, 0x02, 0x1b, 0xa0, 0xe3, 0x01, 0x06, 0xa0, 0xe3,
-0x14, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x21, 0x1f, 0xe5,
-0x14, 0x30, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0xe5,
-0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x14, 0x10, 0x82, 0xe5, 0x01, 0x06, 0xa0, 0xe3,
-0x1c, 0x10, 0x82, 0xe5, 0x0c, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x92, 0xe5,
-0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
-0xc0, 0x21, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x82, 0xe5,
-0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x82, 0xe5, 0x0c, 0x00, 0x81, 0xe5,
-0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x81, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0,
-0x17, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c,
-0x00, 0xf0, 0x92, 0xf8, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x00, 0x28,
-0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x84, 0xf8, 0x00, 0x20, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb4, 0x07, 0x68, 0x3a, 0x78, 0xd2, 0x07,
-0xd2, 0x0f, 0x00, 0x24, 0x00, 0x2a, 0x03, 0xd0, 0xff, 0x22, 0x01, 0x32,
-0x42, 0x60, 0x00, 0xe0, 0x44, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02,
-0x1a, 0x43, 0x81, 0x2a, 0x08, 0xd1, 0x01, 0x23, 0x5b, 0x02, 0x42, 0x68,
-0x1a, 0x43, 0x42, 0x60, 0x04, 0x22, 0xbf, 0x18, 0x82, 0x60, 0x00, 0xe0,
-0x84, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x08, 0x2a,
-0x06, 0xd1, 0x06, 0x23, 0x41, 0x68, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68,
-0x0e, 0x31, 0x3c, 0xe0, 0xc1, 0x23, 0xdb, 0x00, 0x9a, 0x42, 0x03, 0xd1,
-0x41, 0x68, 0x24, 0x4b, 0x19, 0x43, 0x3e, 0xe0, 0x23, 0x4b, 0x9a, 0x42,
-0x04, 0xd1, 0x01, 0x23, 0x1b, 0x03, 0x41, 0x68, 0x19, 0x43, 0x36, 0xe0,
-0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04,
-0x12, 0x0c, 0x2e, 0x3a, 0x1c, 0x4b, 0x9a, 0x42, 0x2d, 0xd8, 0x01, 0x25,
-0x42, 0x68, 0x15, 0x43, 0x45, 0x60, 0xba, 0x7b, 0xfb, 0x7b, 0x1b, 0x02,
-0x1a, 0x43, 0x18, 0x4b, 0x9a, 0x42, 0x22, 0xd1, 0xfb, 0x1d, 0x09, 0x33,
-0x44, 0xcb, 0x9b, 0x07, 0xdb, 0x0e, 0xda, 0x40, 0x5b, 0x42, 0x20, 0x33,
-0x9e, 0x40, 0x16, 0x43, 0x03, 0x2e, 0x18, 0xd1, 0x39, 0x7d, 0x7b, 0x7d,
-0x1b, 0x02, 0x19, 0x43, 0x08, 0x29, 0x07, 0xd1, 0x04, 0x21, 0x29, 0x43,
-0x41, 0x60, 0x81, 0x68, 0x16, 0x31, 0x81, 0x60, 0x01, 0x21, 0x0a, 0xe0,
-0xc1, 0x23, 0xdb, 0x00, 0x99, 0x42, 0x04, 0xd1, 0x01, 0x21, 0x89, 0x03,
-0x29, 0x43, 0x41, 0x60, 0x00, 0xe0, 0x84, 0x60, 0x00, 0x21, 0x08, 0x1c,
-0xf0, 0xbc, 0x70, 0x47, 0x02, 0x40, 0x00, 0x00, 0x81, 0x80, 0x00, 0x00,
-0xae, 0x05, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x80, 0xb4, 0x42, 0x68,
-0xd1, 0x08, 0x3f, 0xd3, 0x01, 0x68, 0x83, 0x68, 0x59, 0x18, 0x02, 0x39,
-0x8f, 0x78, 0x3f, 0x07, 0x3f, 0x0f, 0x05, 0x2f, 0x03, 0xd1, 0xda, 0x1d,
-0x0d, 0x32, 0xc2, 0x60, 0x05, 0xe0, 0xbf, 0x00, 0xdb, 0x19, 0xc3, 0x60,
-0x08, 0x23, 0x1a, 0x43, 0x42, 0x60, 0x8a, 0x78, 0x12, 0x07, 0x12, 0x0f,
-0x92, 0x00, 0x02, 0x61, 0x0a, 0x79, 0x4b, 0x79, 0x1b, 0x02, 0x1a, 0x43,
-0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04,
-0x12, 0x0c, 0x42, 0x61, 0xca, 0x7a, 0x06, 0x2a, 0x03, 0xd1, 0x10, 0x23,
-0x42, 0x68, 0x1a, 0x43, 0x10, 0xe0, 0x11, 0x2a, 0x03, 0xd1, 0x20, 0x23,
-0x42, 0x68, 0x1a, 0x43, 0x0a, 0xe0, 0x33, 0x2a, 0x03, 0xd1, 0x40, 0x23,
-0x42, 0x68, 0x1a, 0x43, 0x04, 0xe0, 0x32, 0x2a, 0x03, 0xd1, 0x80, 0x23,
-0x42, 0x68, 0x1a, 0x43, 0x42, 0x60, 0xc9, 0x7a, 0xc0, 0x46, 0x01, 0x76,
-0x80, 0xbc, 0x70, 0x47, 0x0a, 0x78, 0xc0, 0x46, 0x02, 0x60, 0x4b, 0x78,
-0x1b, 0x02, 0x1a, 0x43, 0x02, 0x60, 0x8b, 0x78, 0x1b, 0x04, 0x1a, 0x43,
-0x02, 0x60, 0xc9, 0x78, 0x09, 0x06, 0x11, 0x43, 0x01, 0x60, 0x70, 0x47,
-0x80, 0xb5, 0x07, 0x1c, 0x48, 0x68, 0x80, 0x09, 0x26, 0xd3, 0xb8, 0x6a,
-0xc9, 0x68, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x02, 0x30, 0x18, 0x43,
-0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x11, 0x23, 0x9b, 0x02, 0x98, 0x42,
-0x18, 0xd1, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46,
-0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xda, 0xf8, 0x38, 0x1c, 0x01, 0xf0,
-0x95, 0xfd, 0x01, 0x20, 0x07, 0x49, 0xc0, 0x46, 0xc8, 0x73, 0x07, 0x49,
-0x4a, 0x6c, 0x12, 0x18, 0x4a, 0x64, 0x06, 0x49, 0x8a, 0x6d, 0x12, 0x18,
-0x8a, 0x65, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0xfa, 0xe7,
-0x18, 0x1a, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80,
-0x81, 0x07, 0x19, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x01, 0x23, 0x9b, 0x07,
-0x01, 0x1d, 0x18, 0x43, 0x00, 0x68, 0x19, 0x43, 0x09, 0x68, 0x02, 0x02,
-0x12, 0x0e, 0x12, 0x06, 0x00, 0x0a, 0xff, 0x23, 0x1b, 0x04, 0x18, 0x40,
-0x10, 0x43, 0x0a, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x10, 0x43, 0x09, 0x02,
-0x1b, 0x0a, 0x19, 0x40, 0x08, 0x43, 0x70, 0x47, 0x01, 0x23, 0x9b, 0x07,
-0x18, 0x43, 0x00, 0x68, 0x01, 0x06, 0x02, 0x02, 0xff, 0x23, 0x1b, 0x04,
-0x1a, 0x40, 0x11, 0x43, 0x02, 0x0a, 0x1b, 0x0a, 0x1a, 0x40, 0x11, 0x43,
-0x00, 0x0e, 0x08, 0x43, 0xed, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x23,
-0x81, 0x6b, 0x19, 0x40, 0x00, 0x22, 0x00, 0x29, 0x46, 0xd0, 0xc7, 0x1d,
-0x39, 0x37, 0x39, 0x7b, 0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x3f, 0xd1,
-0x01, 0x6b, 0xc0, 0x46, 0x4a, 0x65, 0xc4, 0x1d, 0x2d, 0x34, 0xcd, 0x1d,
-0x2d, 0x35, 0x00, 0x22, 0x93, 0x00, 0xe6, 0x58, 0xc0, 0x46, 0xee, 0x50,
-0x01, 0x32, 0x07, 0x2a, 0xf8, 0xd3, 0x82, 0x6a, 0xc0, 0x46, 0x4a, 0x63,
-0x82, 0x6a, 0xc0, 0x46, 0x8a, 0x62, 0x7a, 0x8b, 0xcb, 0x1d, 0x39, 0x33,
-0x5a, 0x83, 0x40, 0x6a, 0xc0, 0x46, 0x48, 0x62, 0x12, 0x48, 0x01, 0x27,
-0x42, 0x68, 0x00, 0x2a, 0x10, 0xd1, 0xc2, 0x68, 0x00, 0x2a, 0x13, 0xd1,
-0x42, 0x69, 0x00, 0x2a, 0x0d, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x01, 0x6a,
-0x02, 0x29, 0x02, 0xd3, 0x20, 0x30, 0x07, 0x71, 0x0c, 0xe0, 0x00, 0xf0,
-0x13, 0xf8, 0x09, 0xe0, 0xc2, 0x68, 0x00, 0x2a, 0x02, 0xd1, 0x01, 0x61,
-0xc1, 0x60, 0x03, 0xe0, 0x02, 0x69, 0xc0, 0x46, 0x51, 0x65, 0x01, 0x61,
-0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7,
-0x6c, 0x06, 0x00, 0x80, 0x80, 0xb5, 0x1e, 0x49, 0x00, 0x22, 0xcb, 0x68,
-0x00, 0x2b, 0x34, 0xd0, 0xc8, 0x1d, 0xf9, 0x30, 0x83, 0x62, 0xcb, 0x68,
-0x9b, 0x6a, 0xc0, 0x46, 0xc3, 0x62, 0xcf, 0x69, 0x7b, 0x00, 0xdf, 0x19,
-0x7f, 0x02, 0x17, 0x4b, 0xff, 0x18, 0xff, 0x37, 0x65, 0x37, 0x83, 0x63,
-0x07, 0x63, 0xcb, 0x1d, 0xff, 0x33, 0x5a, 0x33, 0x1a, 0x72, 0xcb, 0x69,
-0x00, 0x2b, 0x01, 0xd0, 0xca, 0x61, 0x01, 0xe0, 0x01, 0x23, 0xcb, 0x61,
-0x0f, 0x1c, 0xc9, 0x68, 0x49, 0x6a, 0x09, 0x89, 0x01, 0x31, 0x41, 0x63,
-0xf8, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x42, 0x60, 0x02, 0x82, 0x82, 0x60,
-0xc2, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0xce, 0xfa, 0x38, 0x6a, 0x01, 0x30,
-0x38, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x0a, 0xf8, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0xac, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xf9, 0x31,
-0x88, 0x6a, 0xc2, 0x1d, 0x2d, 0x32, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x32,
-0x1a, 0x43, 0xc8, 0x6a, 0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x80, 0x18,
-0x82, 0x79, 0xc3, 0x79, 0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a,
-0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x02, 0x38,
-0x92, 0x04, 0x92, 0x0c, 0x00, 0x26, 0x25, 0x4d,
-0xec, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x00, 0x2a, 0x04, 0xd0, 0x20, 0x8a,
-0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x2b, 0xe0, 0x01, 0x23, 0x9b, 0x07,
-0xc2, 0x1d, 0x0d, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x12, 0x04, 0x12, 0x30,
-0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x10, 0x43, 0x03, 0x1c,
-0xf8, 0x1d, 0xff, 0x30, 0x4a, 0x30, 0x82, 0x78, 0xc8, 0x6b, 0x19, 0x1c,
-0x02, 0xf0, 0x02, 0xf8, 0x00, 0x28, 0x04, 0xda, 0x20, 0x8a, 0xff, 0x23,
-0x01, 0x33, 0x18, 0x43, 0x0e, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31,
-0x08, 0x60, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0x00, 0xf0, 0x1c, 0xf8,
-0x00, 0x28, 0x14, 0xd1, 0x20, 0x8a, 0x01, 0x23, 0x5b, 0x02, 0x18, 0x43,
-0x20, 0x82, 0x21, 0x8a, 0x38, 0x1c, 0x00, 0xf0, 0xa2, 0xfb, 0xe8, 0x68,
-0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46,
-0xe8, 0x60, 0x30, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20,
-0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c,
-0xfc, 0x1d, 0xf9, 0x34, 0xa0, 0x6b, 0xa6, 0x6a, 0xc5, 0x1d, 0x0d, 0x35,
-0x38, 0x48, 0xc0, 0x6a, 0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x42, 0x18,
-0x01, 0x20, 0x80, 0x07, 0x10, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c,
-0x00, 0x90, 0x01, 0x23, 0x9b, 0x07, 0xd0, 0x1d, 0x05, 0x30, 0x18, 0x43,
-0x00, 0x68, 0x38, 0x1c, 0x29, 0x1c, 0x00, 0xf0, 0xc2, 0xfa, 0xa8, 0x88,
-0x41, 0x07, 0x01, 0xd0, 0x00, 0x20, 0x51, 0xe0, 0x29, 0x89, 0x09, 0x18,
-0x60, 0x6b, 0x81, 0x42, 0xf8, 0xd8, 0x69, 0x89, 0xea, 0x88, 0x89, 0x18,
-0x81, 0x42, 0xf3, 0xd8, 0x00, 0x98, 0x01, 0x28, 0x25, 0xd1, 0xe0, 0x6a,
-0xf1, 0x6b, 0x40, 0x18, 0x71, 0x6c, 0xfa, 0x1d, 0xcd, 0x32, 0x01, 0xf0,
-0x33, 0xf9, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0xe0, 0x6a, 0x51, 0x69,
-0x40, 0x18, 0xc3, 0x1d, 0x03, 0x33, 0x00, 0x20, 0x81, 0x00, 0x5e, 0x58,
-0xc9, 0x19, 0xff, 0x31, 0x01, 0x31, 0x4e, 0x61, 0x01, 0x30, 0x04, 0x28,
-0xf6, 0xd3, 0xe0, 0x6a, 0x51, 0x69, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31,
-0x00, 0x20, 0x00, 0x22, 0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28,
-0xfa, 0xd3, 0x29, 0x1c, 0x11, 0x4a, 0x00, 0x20, 0xff, 0xf7, 0xae, 0xfb,
-0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 0x01, 0x20, 0x21, 0x6b,
-0xff, 0xf7, 0xa6, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43,
-0x00, 0x20, 0xe1, 0x6a, 0xff, 0xf7, 0x9e, 0xfb, 0xa1, 0x6b, 0x08, 0x4a,
-0x01, 0x20, 0xff, 0xf7, 0x99, 0xfb, 0x03, 0x20, 0x06, 0x49, 0xc0, 0x46,
-0x48, 0x62, 0x01, 0x20, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x4c, 0x2a, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 0x14, 0x00, 0x0f, 0x00,
-0x6c, 0x07, 0x00, 0x80, 0xf0, 0xb5, 0x8d, 0xb0, 0x00, 0x20, 0xb5, 0x4a,
-0xd5, 0x1d, 0xf9, 0x35, 0x68, 0x62, 0x01, 0x20, 0x00, 0x05, 0xb3, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0xa8, 0x6a, 0xc4, 0x1d, 0x2d, 0x34, 0xb1, 0x48,
-0xc0, 0x6a, 0xd7, 0x1d, 0xff, 0x37, 0x3a, 0x37, 0x39, 0x68, 0x4b, 0x00,
-0x59, 0x18, 0x49, 0x01, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d,
-0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68,
-0xc0, 0x46, 0x09, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x18, 0x40, 0x00, 0x0a,
-0x0a, 0x90, 0x0a, 0x98, 0xa4, 0x4e, 0x01, 0x28, 0x59, 0xd1, 0x28, 0x6b,
-0xa2, 0x68, 0x80, 0x18, 0xa2, 0x4a, 0x21, 0x69,
-0x09, 0x04, 0x09, 0x0c, 0x01, 0xf0, 0x26, 0xf9, 0x28, 0x6b, 0x79, 0x69,
-0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x82, 0x00, 0x98, 0x4b,
-0xd3, 0x18, 0xff, 0x33, 0x01, 0x33, 0x5b, 0x69, 0xc0, 0x46, 0x8b, 0x50,
-0x01, 0x30, 0x04, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x31, 0x1c, 0x82, 0x00,
-0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae,
-0xb3, 0x50, 0x01, 0x30, 0x03, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x08, 0x90,
-0x90, 0x49, 0x42, 0x00, 0x8b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 0x13, 0xd0,
-0x8e, 0x48, 0xc1, 0x89, 0x01, 0x31, 0xc1, 0x81, 0xb8, 0x68, 0x00, 0x28,
-0x03, 0xd1, 0x38, 0x8a, 0x10, 0x23, 0x18, 0x43, 0x71, 0xe0, 0x38, 0x8a,
-0x40, 0x23, 0x18, 0x43, 0x6d, 0xe0, 0x00, 0xf0, 0x11, 0xf9, 0x01, 0xf0,
-0x67, 0xff, 0xf5, 0xe0, 0x01, 0x30, 0x06, 0x28, 0xe3, 0xd3, 0x08, 0x98,
-0x00, 0x28, 0x0c, 0xd1, 0xb8, 0x68, 0x41, 0x1c, 0xb9, 0x60, 0x00, 0x28,
-0x03, 0xd1, 0x38, 0x8a, 0x01, 0x23, 0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a,
-0x04, 0x23, 0x18, 0x43, 0x38, 0x82, 0x78, 0x68, 0x01, 0x30, 0x78, 0x60,
-0x62, 0xe0, 0x0a, 0x98, 0x02, 0x28, 0x5f, 0xd1, 0x09, 0x98, 0x40, 0x0c,
-0x73, 0xd3, 0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43,
-0x00, 0x68, 0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18,
-0x0c, 0x38, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x21, 0x8a, 0x00, 0x6b, 0x4b,
-0xd6, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae,
-0xb3, 0x50, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, 0x00, 0x21, 0x83, 0x1e,
-0x0c, 0x93, 0x68, 0x4a, 0x16, 0x6b, 0xc0, 0x46, 0x0b, 0x96, 0x8a, 0x00,
-0x0c, 0x9b, 0x9b, 0x18, 0x0b, 0x9e, 0x9e, 0x19, 0x01, 0x23, 0x9b, 0x07,
-0x33, 0x43, 0x1b, 0x68, 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x31, 0x04, 0x29,
-0xf1, 0xd3, 0x69, 0x46, 0x8b, 0x1c, 0x07, 0x93, 0x00, 0x21, 0x08, 0x91,
-0x04, 0xae, 0x4a, 0x00, 0x07, 0x9b, 0x9b, 0x5a, 0xb2, 0x5a, 0x93, 0x42,
-0x11, 0xd0, 0x58, 0x48, 0xc1, 0x89, 0x01, 0x31, 0xc1, 0x81, 0xf8, 0x68,
-0x41, 0x1c, 0xf9, 0x60, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x8a, 0x20, 0x23,
-0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a, 0x80, 0x23, 0x18, 0x43, 0x38, 0x82,
-0x8f, 0xe7, 0x01, 0x31, 0x06, 0x29, 0xe4, 0xd3, 0x08, 0x99, 0x00, 0x29,
-0x0d, 0xd1, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0x04, 0xd1,
-0x39, 0x8a, 0x02, 0x23, 0x19, 0x43, 0x03, 0xe0, 0x0c, 0xe0, 0x39, 0x8a,
-0x08, 0x23, 0x19, 0x43, 0x39, 0x82, 0x29, 0x6b, 0x08, 0x18, 0x01, 0x23,
-0x9b, 0x07, 0x01, 0x38, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0x20, 0x76,
-0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x11, 0x30, 0x18, 0x43, 0x00, 0x68,
-0x01, 0x06, 0x09, 0x0e, 0x00, 0xe0, 0x19, 0xe0, 0x35, 0x48, 0x2a, 0x6b,
-0xc0, 0x46, 0xea, 0x62, 0x04, 0x29, 0x4f, 0xd1, 0x01, 0x21, 0xc6, 0x1d,
-0xff, 0x36, 0x5a, 0x36, 0x31, 0x72, 0x0a, 0x99, 0x02, 0x29, 0x1e, 0xd1,
-0x09, 0x99, 0x09, 0x0e, 0x49, 0x06, 0x1a, 0xd1, 0xe1, 0x1d, 0x05, 0x31,
-0x19, 0x43, 0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x39, 0x1a, 0xe0,
-0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68,
-0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18, 0x00, 0x04,
-0x00, 0x0c, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0xbc, 0xd1,
-0xb6, 0xe7, 0x01, 0x23, 0x9b, 0x07, 0xe1, 0x1d,
-0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0xa1, 0x60,
-0xe8, 0x6a, 0xc0, 0x46, 0x20, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0x88, 0xfc,
-0x20, 0x7e, 0x33, 0x28, 0x01, 0xd0, 0x32, 0x28, 0x11, 0xd1, 0x01, 0x21,
-0x14, 0x4c, 0xc0, 0x46, 0xf9, 0x60, 0xb9, 0x60, 0x20, 0x1c, 0x00, 0xf0,
-0x85, 0xf8, 0x28, 0x6b, 0xa9, 0x6a, 0xc0, 0x46, 0x88, 0x62, 0x20, 0x1c,
-0xff, 0xf7, 0xc0, 0xfd, 0x00, 0x28, 0x11, 0xd1, 0x0e, 0xe0, 0x00, 0x20,
-0x30, 0x72, 0x11, 0xe0, 0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x0d, 0xd1,
-0x07, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0xb0, 0xfd,
-0x00, 0x28, 0x01, 0xd1, 0x01, 0xf0, 0x70, 0xfe, 0x0d, 0xb0, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xf0, 0x12, 0xf8, 0xf6, 0xe7, 0x00, 0x00,
-0x6c, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0x4c, 0x2a, 0x00, 0x80,
-0xac, 0xab, 0x20, 0x40, 0x40, 0x07, 0x00, 0x80, 0x82, 0x07, 0x00, 0x80,
-0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x07, 0x00, 0x80, 0xf0, 0xb5, 0x25, 0x48,
-0x41, 0x68, 0x01, 0x31, 0x41, 0x60, 0x24, 0x4f, 0xf9, 0x1d, 0xf9, 0x31,
-0x00, 0x24, 0x88, 0x6a, 0xfa, 0x68, 0xc0, 0x46, 0x94, 0x61, 0x04, 0x22,
-0xfb, 0x68, 0xc0, 0x46, 0xda, 0x60, 0x10, 0x22, 0xfb, 0x68, 0xc0, 0x46,
-0x9a, 0x61, 0xfa, 0x1d, 0xff, 0x32, 0x5a, 0x32, 0x13, 0x7a, 0x1b, 0x4a,
-0x00, 0x2b, 0x0b, 0xd0, 0x15, 0x8a, 0x2e, 0x0a, 0x36, 0x02, 0x33, 0x23,
-0x2b, 0x40, 0x9b, 0x00, 0x1e, 0x43, 0xcc, 0x23, 0x2b, 0x40, 0x9b, 0x08,
-0x33, 0x43, 0x13, 0x82, 0x12, 0x8a, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x83,
-0x4a, 0x6b, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x81, 0x0a, 0x6b, 0xc0, 0x46,
-0x82, 0x62, 0xc4, 0x62, 0xc3, 0x1d, 0x39, 0x33, 0x4a, 0x6b, 0xc0, 0x46,
-0x5a, 0x83, 0x04, 0x23, 0x02, 0x68, 0x1a, 0x43, 0x02, 0x60, 0x88, 0x6a,
-0x01, 0xf0, 0x32, 0xfa, 0xf8, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x54, 0x30,
-0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x60, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80,
-0xac, 0x07, 0x00, 0x80, 0x80, 0xb5, 0xc1, 0x1d, 0xf9, 0x31, 0x8a, 0x6a,
-0x01, 0x23, 0x9b, 0x07, 0xd1, 0x1d, 0x45, 0x31, 0x19, 0x43, 0x09, 0x68,
-0x0b, 0x06, 0x1b, 0x0e, 0x01, 0x27, 0xc1, 0x1d, 0xff, 0x31, 0x4a, 0x31,
-0x33, 0x2b, 0x05, 0xd1, 0x8b, 0x70, 0x01, 0x1c, 0x10, 0x1c, 0x00, 0xf0,
-0x0f, 0xf8, 0x06, 0xe0, 0x32, 0x2b, 0x08, 0xd1, 0x8b, 0x70, 0x01, 0x1c,
-0x10, 0x1c, 0x00, 0xf0, 0x3c, 0xf8, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x20, 0x88, 0x70, 0xf9, 0xe7, 0x90, 0xb4, 0xca, 0x1d,
-0xf9, 0x32, 0x33, 0x27, 0xcc, 0x1d, 0xff, 0x34, 0x4a, 0x34, 0xd3, 0x6a,
-0xc0, 0x46, 0xa7, 0x70, 0xff, 0x31, 0x41, 0x31, 0x07, 0x6c, 0xc0, 0x46,
-0x4f, 0x61, 0xfb, 0x18, 0x39, 0x1c, 0x9f, 0x1e, 0x01, 0x23, 0x9b, 0x07,
-0xfc, 0x1c, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x9b, 0x00,
-0x1b, 0x04, 0x1b, 0x0c, 0xc9, 0x18, 0x08, 0x31, 0x01, 0x64, 0x01, 0x23,
-0x9b, 0x07, 0xb9, 0x1c, 0x19, 0x43, 0x09, 0x68, 0x34, 0x30, 0x01, 0x76,
-0xf8, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1d,
-0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43,
-0xd0, 0x63, 0x90, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xca, 0x1d, 0xf9, 0x32,
-0xc5, 0x1d, 0x2d, 0x35, 0x32, 0x20, 0xcf, 0x1d,
-0xff, 0x37, 0x4a, 0x37, 0xd3, 0x6a, 0xc0, 0x46, 0xb8, 0x70, 0xcc, 0x1d,
-0xff, 0x34, 0x3a, 0x34, 0xe8, 0x68, 0xc0, 0x46, 0x60, 0x61, 0x10, 0x30,
-0xe8, 0x60, 0x60, 0x69, 0xc0, 0x18, 0x87, 0x1e, 0x01, 0x23, 0x9b, 0x07,
-0x38, 0x1d, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1c, 0x19, 0x43,
-0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63,
-0xf8, 0x1d, 0x03, 0x30, 0xff, 0xf7, 0xfc, 0xfb, 0x20, 0x62, 0xf8, 0x1d,
-0x07, 0x30, 0xff, 0xf7, 0xf7, 0xfb, 0x60, 0x62, 0x00, 0x20, 0x28, 0x76,
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, 0x81, 0xb0, 0x01, 0x98,
-0xc7, 0x1d, 0xf9, 0x37, 0xb8, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d,
-0x05, 0x34, 0x23, 0x43, 0x1c, 0x68, 0xff, 0x23, 0xfe, 0x33, 0x23, 0x40,
-0x7f, 0x6b, 0x3f, 0x04, 0x3b, 0x43, 0x0b, 0x60, 0x34, 0x30, 0x1c, 0x1c,
-0x80, 0x23, 0x23, 0x40, 0x01, 0x9f, 0xff, 0x37, 0x41, 0x37, 0x00, 0x2b,
-0x3c, 0xd0, 0x0c, 0x23, 0x00, 0x93, 0x00, 0x23, 0x9d, 0x00, 0xae, 0x18,
-0x36, 0x69, 0x6d, 0x18, 0x6e, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3,
-0x00, 0x23, 0x9d, 0x00, 0xae, 0x18, 0x76, 0x6a, 0x6d, 0x18, 0xae, 0x62,
-0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 0x01, 0x9b, 0xff, 0x33, 0x51, 0x33,
-0x9b, 0x78, 0x33, 0x2b, 0x0e, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xc5, 0x1d,
-0x01, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x4b, 0x81, 0x01, 0x23,
-0x9b, 0x07, 0xc5, 0x1d, 0x0d, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0x16, 0xe0,
-0x7b, 0x69, 0xc0, 0x46, 0x4b, 0x81, 0x01, 0x23, 0x9b, 0x07, 0xc5, 0x1d,
-0x0d, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0x7d, 0x69, 0x5d, 0x1b, 0x01, 0x23,
-0x9b, 0x07, 0xc6, 0x1d, 0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0xeb, 0x18,
-0x0c, 0x3b, 0x02, 0xe0, 0x00, 0x23, 0x00, 0x93, 0x4b, 0x81, 0xcb, 0x80,
-0x63, 0x09, 0x49, 0xd3, 0x01, 0x23, 0x9b, 0x07, 0xc4, 0x1d, 0x05, 0x34,
-0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x81, 0x01, 0x23, 0x9b, 0x07,
-0xc4, 0x1d, 0x0d, 0x34, 0x23, 0x43, 0x1b, 0x68, 0x0c, 0x89, 0x1b, 0x1b,
-0x00, 0x9c, 0x1c, 0x1b, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30, 0x18, 0x43,
-0x00, 0x68, 0x20, 0x18, 0x88, 0x80, 0x38, 0x6a, 0x04, 0x0e, 0xff, 0x23,
-0x1b, 0x04, 0x03, 0x40, 0x1b, 0x0a, 0x1c, 0x43, 0xff, 0x23, 0x1b, 0x02,
-0x03, 0x40, 0x1b, 0x02, 0x23, 0x43, 0x00, 0x06, 0x18, 0x43, 0xc8, 0x60,
-0x78, 0x6a, 0x07, 0x0e, 0xff, 0x23, 0x1b, 0x04, 0x03, 0x40, 0x1b, 0x0a,
-0x1f, 0x43, 0xff, 0x23, 0x1b, 0x02, 0x03, 0x40, 0x1b, 0x02, 0x3b, 0x43,
-0x00, 0x06, 0x18, 0x43, 0x08, 0x61, 0xd0, 0x6b, 0xc0, 0x46, 0xc8, 0x63,
-0x90, 0x6b, 0xc0, 0x46, 0x08, 0x64, 0x50, 0x6c, 0xc0, 0x46, 0x48, 0x64,
-0x10, 0x6c, 0xc0, 0x46, 0x88, 0x64, 0xd0, 0x6c, 0xc0, 0x46, 0xc8, 0x64,
-0x90, 0x6c, 0xc0, 0x46, 0x08, 0x65, 0x02, 0xe0, 0x00, 0x23, 0x0b, 0x81,
-0x8b, 0x80, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0x0f, 0x4a, 0x93, 0x89, 0x01, 0x33, 0x93, 0x81, 0xc2, 0x1d, 0xf9, 0x32,
-0x04, 0x23, 0x90, 0x6a, 0xc0, 0x46, 0xc3, 0x60, 0x10, 0x23, 0x83, 0x61,
-0xcb, 0x0a, 0x01, 0xd3, 0x18, 0x23, 0x83, 0x61, 0xc1, 0x83, 0x51, 0x6b,
-0xc0, 0x46, 0xc1, 0x81, 0x51, 0x6b, 0xc2, 0x1d, 0x39, 0x32, 0x51, 0x83,
-0x04, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x01, 0xf0, 0xc2, 0xf8,
-0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80,
-0xb0, 0xb5, 0x1b, 0x4c, 0x20, 0x6a, 0x02, 0x28, 0x1b, 0xd2, 0x00, 0x20,
-0xe7, 0x1d, 0x19, 0x37, 0x38, 0x71, 0xe1, 0x68, 0xe0, 0x1d, 0xf9, 0x30,
-0x00, 0x29, 0x15, 0xd0, 0x42, 0x6a, 0x00, 0x2a, 0x12, 0xd1, 0x01, 0x25,
-0x0a, 0xe0, 0xff, 0xf7, 0x89, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x20, 0x6a,
-0x02, 0x28, 0x00, 0xd3, 0x3d, 0x71, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0,
-0x38, 0x79, 0x00, 0x28, 0xf1, 0xd0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x40, 0x6a, 0x00, 0x28, 0xf9, 0xd1, 0x00, 0x29, 0xf7, 0xd1, 0x60, 0x69,
-0x00, 0x28, 0x04, 0xd0, 0x06, 0x48, 0x00, 0x68, 0x03, 0xf0, 0xa8, 0xfc,
-0xef, 0xe7, 0x60, 0x68, 0x00, 0x28, 0xec, 0xd0, 0x00, 0xf0, 0x5a, 0xf8,
-0xe9, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0x34, 0x04, 0x00, 0x80,
-0xb0, 0xb5, 0x07, 0x1c, 0x20, 0x23, 0xb8, 0x68, 0x18, 0x40, 0x01, 0x24,
-0x00, 0x25, 0x00, 0x28, 0x0b, 0xd1, 0x38, 0x6a, 0x00, 0x28, 0x03, 0xd1,
-0x28, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x1f, 0x48, 0x01, 0x6e,
-0x01, 0x31, 0x01, 0x66, 0x03, 0xe0, 0x48, 0x68, 0xc4, 0x23, 0x18, 0x40,
-0x03, 0xd1, 0x38, 0x6a, 0x00, 0xf0, 0x0c, 0xfc, 0x2f, 0xe0, 0x38, 0x1c,
-0x00, 0xf0, 0x1c, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x7b, 0xfa, 0xb8, 0x68,
-0xc0, 0x08, 0x02, 0xd3, 0x38, 0x6a, 0x00, 0xf0, 0xd1, 0xfb, 0xb8, 0x68,
-0x39, 0x6a, 0xc0, 0x46, 0x88, 0x60, 0x38, 0x6a, 0xc0, 0x46, 0xc5, 0x60,
-0x10, 0x48, 0x41, 0x68, 0x00, 0x29, 0x11, 0xd1, 0xc1, 0x68, 0x00, 0x29,
-0x09, 0xd1, 0x41, 0x69, 0x00, 0x29, 0x06, 0xd1, 0x39, 0x6a, 0xc0, 0x46,
-0x81, 0x60, 0x41, 0x60, 0x00, 0xf0, 0x14, 0xf8, 0x0b, 0xe0, 0x39, 0x6a,
-0xc0, 0x46, 0x81, 0x60, 0x41, 0x60, 0x06, 0xe0, 0x39, 0x6a, 0x82, 0x68,
-0xc0, 0x46, 0xd1, 0x60, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 0x20, 0x1c,
-0xbd, 0xe7, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80,
-0x90, 0xb5, 0x0b, 0x4c, 0x67, 0x68, 0x00, 0x2f, 0x0f, 0xd0, 0x38, 0x1c,
-0x00, 0xf0, 0x12, 0xf8, 0x00, 0x28, 0x0a, 0xd1, 0x60, 0x68, 0xc0, 0x68,
-0xc0, 0x46, 0x60, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0xc3, 0xfb, 0x00, 0x20,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0xfa, 0xe7, 0x00, 0x00,
-0x6c, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 0xfe, 0x1d, 0x49, 0x36,
-0x30, 0x78, 0x40, 0x00, 0xc0, 0x19, 0x85, 0x8b, 0x33, 0x4c, 0x34, 0x4b,
-0x9d, 0x42, 0x3c, 0xd0, 0x38, 0x1c, 0x21, 0x1c, 0x2a, 0x1c, 0x00, 0xf0,
-0x1d, 0xf9, 0x31, 0x48, 0x80, 0x6a, 0x58, 0x21, 0x69, 0x43, 0x40, 0x18,
-0x01, 0x23, 0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c,
-0x2c, 0x4d, 0x01, 0x28, 0x1a, 0xd1, 0x30, 0x78, 0xc0, 0x19, 0xc1, 0x1d,
-0x19, 0x31, 0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x09, 0x7b, 0xea, 0x1d,
-0x21, 0x32, 0x00, 0xf0, 0xe3, 0xfc, 0x30, 0x78, 0xc0, 0x19, 0x20, 0x30,
-0x00, 0x79, 0x39, 0x68, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20,
-0x00, 0x23, 0x42, 0x00, 0x8b, 0x52, 0x01, 0x30, 0x06, 0x28, 0xfa, 0xd3,
-0xa0, 0x88, 0x41, 0x07, 0x0b, 0xd1, 0x21, 0x89, 0x09, 0x18, 0x78, 0x68,
-0x00, 0x04, 0x00, 0x0c, 0x81, 0x42, 0x04, 0xd8, 0x61, 0x89, 0xe2, 0x88,
-0x89, 0x18, 0x81, 0x42, 0x03, 0xd9, 0x00, 0x20, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x21, 0x1c, 0x14, 0x4a, 0x00, 0x20, 0xfe, 0xf7, 0x5a, 0xff,
-0x01, 0x22, 0x52, 0x04, 0x78, 0x68, 0x02, 0x43,
-0x01, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x52, 0xff, 0x01, 0x22, 0x52, 0x04,
-0x78, 0x68, 0x02, 0x43, 0x00, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x4a, 0xff,
-0x0b, 0x49, 0x0c, 0x4a, 0x01, 0x20, 0xfe, 0xf7, 0x45, 0xff, 0x01, 0x20,
-0xe9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x02, 0x21, 0xea, 0x1d, 0xf9, 0x32,
-0x51, 0x62, 0xd9, 0xe7, 0x28, 0xac, 0x20, 0x40, 0xff, 0xff, 0x00, 0x00,
-0x4c, 0x2a, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00,
-0x14, 0xac, 0x20, 0x40, 0x14, 0x00, 0x07, 0x00, 0xf0, 0xb5, 0x83, 0xb0,
-0x00, 0x21, 0x4f, 0x48, 0xc2, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0x01, 0x21,
-0xc9, 0x04, 0x4d, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0xc1, 0x1d, 0x19, 0x31,
-0x49, 0x79, 0x00, 0x29, 0x04, 0xd1, 0x4a, 0x48, 0x00, 0x68, 0x03, 0xf0,
-0x9b, 0xfb, 0x87, 0xe0, 0x45, 0x48, 0x47, 0x68, 0xfc, 0x1d, 0x49, 0x34,
-0x21, 0x78, 0x48, 0x00, 0xc0, 0x19, 0x80, 0x8b, 0x44, 0x4a, 0x92, 0x6a,
-0x58, 0x23, 0x58, 0x43, 0x15, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xea, 0x1d,
-0x05, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x08, 0x35, 0x2b, 0x43, 0x1d, 0x68,
-0xff, 0x23, 0x1b, 0x02, 0x2b, 0x40, 0x1b, 0x0a, 0x3c, 0x4d, 0x01, 0x2b,
-0x24, 0xd1, 0xc8, 0x19, 0xc1, 0x1d, 0x19, 0x31, 0x08, 0x7a, 0x3a, 0x68,
-0x80, 0x18, 0x39, 0x4a, 0x09, 0x7b, 0x00, 0xf0, 0xc5, 0xfc, 0x20, 0x78,
-0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, 0x41, 0x18, 0x00, 0x20,
-0x82, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x30,
-0x03, 0x28, 0xf7, 0xd3, 0xca, 0x1d, 0x05, 0x32, 0x69, 0x46, 0x00, 0x20,
-0x43, 0x00, 0xcd, 0x5a, 0xc0, 0x46, 0xd5, 0x52, 0x01, 0x30, 0x06, 0x28,
-0xf8, 0xd3, 0x2d, 0xe0, 0x02, 0x2b, 0x2b, 0xd1, 0x11, 0x0a, 0x29, 0xd3,
-0x00, 0x21, 0x8a, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, 0xb3, 0x50,
-0x01, 0x31, 0x03, 0x29, 0xf7, 0xd3, 0x21, 0x78, 0x49, 0x00, 0xc9, 0x19,
-0x09, 0x8f, 0x3a, 0x68, 0x8b, 0x18, 0x6a, 0x46, 0x00, 0x21, 0x4d, 0x00,
-0x56, 0x5b, 0xc0, 0x46, 0x5e, 0x53, 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3,
-0x19, 0x49, 0x8a, 0x6a, 0x13, 0x18, 0x1a, 0x6d, 0x00, 0x9d, 0x55, 0x40,
-0x19, 0x4a, 0xd6, 0x68, 0x75, 0x40, 0x1d, 0x65, 0x89, 0x6a, 0x08, 0x18,
-0x41, 0x6d, 0x02, 0x9b, 0x59, 0x40, 0x92, 0x69, 0x51, 0x40, 0x41, 0x65,
-0x20, 0x78, 0x41, 0x1e, 0x21, 0x70, 0x00, 0x28, 0x0d, 0xd0, 0x38, 0x1c,
-0xff, 0xf7, 0xf4, 0xfe, 0x00, 0x28, 0x0d, 0xd1, 0x08, 0x4a, 0x50, 0x68,
-0xc0, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0xa4, 0xfa,
-0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x73, 0xfa, 0x01, 0xf0, 0xde, 0xfa,
-0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x6c, 0x06, 0x00, 0x80,
-0x00, 0x00, 0x00, 0xb0, 0x38, 0x04, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80,
-0xac, 0xab, 0x20, 0x40, 0x94, 0x06, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40,
-0xf0, 0xb5, 0x82, 0xb0, 0x69, 0x4b, 0x9f, 0x6a, 0x58, 0x23, 0x5a, 0x43,
-0xba, 0x18, 0xc3, 0x1d, 0x49, 0x33, 0x1f, 0x78, 0x01, 0x23, 0x9b, 0x07,
-0xd4, 0x1d, 0x01, 0x34, 0x23, 0x43, 0x1d, 0x68, 0x43, 0x68, 0x1c, 0x04,
-0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x05, 0x36, 0x33, 0x43, 0x1b, 0x68,
-0x1c, 0x43, 0x42, 0x23, 0x1c, 0x43, 0x0c, 0x60, 0xff, 0x26, 0x36, 0x02,
-0x2e, 0x40, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x74, 0xd1, 0x6b, 0x0c,
-0x2b, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79,
-0xc0, 0x46, 0x4b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x4c, 0x89,
-0x1b, 0x1b, 0xcb, 0x80, 0x00, 0x24, 0xa6, 0x00, 0x01, 0x96, 0xb3, 0x18,
-0xde, 0x1d, 0x09, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68,
-0x01, 0x9e, 0x76, 0x18, 0x73, 0x61, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3,
-0x00, 0x24, 0xa6, 0x00, 0x00, 0x96, 0xb3, 0x18, 0xde, 0x1d, 0x1d, 0x36,
-0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0x76, 0x18,
-0xb3, 0x62, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 0x06, 0xe0, 0x00, 0x23,
-0x4b, 0x81, 0xcb, 0x80, 0x40, 0x23, 0x9c, 0x43, 0x0c, 0x60, 0x23, 0x1c,
-0x6b, 0x0e, 0x4a, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79, 0x10, 0x33,
-0x0b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x0f, 0x89, 0xdb, 0x1b,
-0x8b, 0x80, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x35, 0x34, 0x23, 0x43,
-0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x63, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d,
-0x31, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x64, 0xab, 0x0e,
-0x21, 0xd2, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x3d, 0x34, 0x23, 0x43,
-0x1b, 0x68, 0xc0, 0x46, 0x4b, 0x64, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d,
-0x39, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x8b, 0x64, 0x01, 0x23,
-0x9b, 0x07, 0xd4, 0x1d, 0x45, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46,
-0xcb, 0x64, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x41, 0x34, 0x23, 0x43,
-0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x65, 0x00, 0xe0, 0x0f, 0xe0, 0xfb, 0x1f,
-0x01, 0x3b, 0x1b, 0x04, 0x1b, 0x0c, 0x07, 0x68, 0xff, 0x18, 0x03, 0x69,
-0x08, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x34, 0xf8, 0x2c, 0xe0, 0x00, 0x23,
-0x0b, 0x81, 0x8b, 0x80, 0x28, 0xe0, 0x00, 0x23, 0x8b, 0x80, 0x0b, 0x81,
-0xc3, 0x19, 0x20, 0x33, 0x1b, 0x7a, 0xc0, 0x46, 0x4b, 0x81, 0x7b, 0x00,
-0x18, 0x18, 0x00, 0x8e, 0xc0, 0x46, 0xc8, 0x80, 0x00, 0x20, 0x87, 0x00,
-0xbb, 0x18, 0xdc, 0x1d, 0x09, 0x34, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43,
-0x1b, 0x68, 0x7f, 0x18, 0x7b, 0x61, 0x01, 0x30, 0x05, 0x28, 0xf2, 0xd3,
-0x00, 0x20, 0x87, 0x00, 0xbb, 0x18, 0xdc, 0x1d, 0x1d, 0x34, 0x01, 0x23,
-0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x7f, 0x18, 0xbb, 0x62, 0x01, 0x30,
-0x05, 0x28, 0xf2, 0xd3, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x4c, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x1f, 0x1c, 0x3b, 0x0c, 0x18, 0xd2,
-0x17, 0x6d, 0x11, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x52, 0x6d, 0xc0, 0x46,
-0x1a, 0x61, 0xc7, 0x60, 0x1a, 0x69, 0xc0, 0x46, 0x02, 0x61, 0xd8, 0x68,
-0xc0, 0x46, 0x08, 0x80, 0xd8, 0x68, 0x00, 0x0c, 0x48, 0x80, 0x18, 0x69,
-0xc0, 0x46, 0x88, 0x80, 0x18, 0x69, 0x00, 0x0c, 0xc8, 0x80, 0x80, 0xbc,
-0x70, 0x47, 0x4a, 0x88, 0x12, 0x04, 0x0b, 0x88, 0x1a, 0x43, 0xc2, 0x60,
-0x8a, 0x88, 0xc9, 0x88, 0x09, 0x04, 0x11, 0x43, 0x01, 0x61, 0xf2, 0xe7,
-0x2c, 0x07, 0x00, 0x80, 0xf1, 0xb5, 0x88, 0xb0, 0x00, 0x22, 0x08, 0x98,
-0x00, 0x6a, 0x08, 0x9b, 0x99, 0x68, 0x49, 0x0a, 0x02, 0xd3, 0x01, 0x27,
-0xff, 0x03, 0x00, 0xe0, 0x00, 0x27, 0x03, 0x8b, 0x00, 0x2b, 0x19, 0xd0,
-0xa3, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 0xc9, 0x18,
-0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68, 0x09, 0x04,
-0x09, 0x0c, 0x02, 0x29, 0x02, 0xd1, 0x08, 0x23, 0x1f, 0x43, 0x07, 0xe0,
-0x41, 0x8b, 0x00, 0x29, 0x02, 0xd0, 0x0c, 0x23,
-0x1f, 0x43, 0x01, 0xe0, 0x04, 0x23, 0x1f, 0x43, 0x83, 0x8a, 0x00, 0x2b,
-0x18, 0xd0, 0x95, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43,
-0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68,
-0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x01, 0xd1, 0x0f, 0x43, 0x07, 0xe0,
-0xc1, 0x8a, 0x00, 0x29, 0x02, 0xd0, 0x03, 0x23, 0x1f, 0x43, 0x01, 0xe0,
-0x01, 0x23, 0x1f, 0x43, 0xc1, 0x1d, 0x39, 0x31, 0x07, 0x91, 0x4b, 0x89,
-0x0c, 0x89, 0x1c, 0x19, 0x24, 0x04, 0x24, 0x0c, 0x08, 0x9d, 0x2d, 0x68,
-0xc0, 0x46, 0x01, 0x95, 0xc9, 0x88, 0x7d, 0x08, 0x1a, 0xd3, 0x1a, 0x1c,
-0xc3, 0x1d, 0x19, 0x33, 0x1a, 0x72, 0x07, 0x9a, 0x92, 0x89, 0xc0, 0x46,
-0x1a, 0x73, 0x07, 0x9a, 0x12, 0x89, 0xc0, 0x46, 0x02, 0x86, 0x04, 0x87,
-0x82, 0x8a, 0x01, 0x3a, 0x82, 0x83, 0x01, 0x22, 0x19, 0x71, 0x08, 0x9b,
-0x1b, 0x68, 0x5b, 0x18, 0x5b, 0x78, 0x9b, 0x00, 0x1b, 0x04, 0x1b, 0x0c,
-0x08, 0x33, 0x59, 0x18, 0xbb, 0x08, 0x47, 0xd3, 0x07, 0x9b, 0x5b, 0x89,
-0x85, 0x18, 0x06, 0x95, 0x20, 0x35, 0x2b, 0x72, 0x07, 0x9b, 0x9b, 0x89,
-0xc0, 0x46, 0x2b, 0x73, 0x07, 0x9b, 0x1b, 0x89, 0x2e, 0x1c, 0x55, 0x00,
-0x2d, 0x18, 0x05, 0x95, 0x2b, 0x86, 0x00, 0x2a, 0x01, 0xd0, 0xc3, 0x8a,
-0x00, 0xe0, 0x83, 0x8a, 0x01, 0x3b, 0x05, 0x9d, 0xc0, 0x46, 0xab, 0x83,
-0x31, 0x71, 0x65, 0x4b, 0x9d, 0x6a, 0x05, 0x9b, 0x9e, 0x8b, 0x58, 0x23,
-0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, 0x01, 0x23, 0x9b, 0x07,
-0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, 0x01, 0xd1, 0x08, 0x31,
-0x00, 0xe0, 0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, 0x1d, 0x40, 0x9d, 0x42,
-0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, 0x1c, 0x04, 0x24, 0x0c, 0x05, 0x9b,
-0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b,
-0x9b, 0x7b, 0x06, 0x9d, 0x40, 0x35, 0x2b, 0x70, 0x2b, 0x78, 0x02, 0x33,
-0xe3, 0x1a, 0x1c, 0x04, 0x24, 0x0c, 0x01, 0x32, 0xbb, 0x08, 0x9b, 0x07,
-0x6d, 0xd0, 0x83, 0x18, 0x20, 0x33, 0x04, 0x93, 0x19, 0x72, 0x01, 0x9b,
-0x5d, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1b, 0x68, 0x1b, 0x07,
-0x1b, 0x0f, 0x9b, 0x00, 0x04, 0x9e, 0xc0, 0x46, 0x33, 0x73, 0x00, 0x95,
-0x2b, 0x78, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x04, 0x9d, 0xc0, 0x46,
-0x2b, 0x73, 0x00, 0x9d, 0xeb, 0x78, 0xad, 0x78, 0x1b, 0x02, 0x1d, 0x43,
-0x2b, 0x02, 0x2d, 0x0a, 0x2d, 0x06, 0x2d, 0x0e, 0x2b, 0x43, 0x55, 0x00,
-0x2d, 0x18, 0x2b, 0x86, 0x04, 0x9b, 0xc0, 0x46, 0x59, 0x72, 0x04, 0x9b,
-0x1b, 0x7b, 0x2e, 0x1c, 0x04, 0x9d, 0xc0, 0x46, 0x6b, 0x73, 0x33, 0x8e,
-0xc0, 0x46, 0x73, 0x86, 0x00, 0x9d, 0x2b, 0x78, 0x1b, 0x07, 0x1b, 0x0f,
-0x9b, 0x00, 0x1b, 0x04, 0x1b, 0x0c, 0x59, 0x18, 0x04, 0x25, 0x3d, 0x40,
-0x0e, 0xd0, 0x34, 0x87, 0x03, 0x8b, 0x01, 0x3b, 0xb3, 0x83, 0x13, 0x1c,
-0x1b, 0x18, 0x20, 0x33, 0x19, 0x71, 0x01, 0x9b, 0x5b, 0x18, 0x5b, 0x78,
-0x9b, 0x00, 0x59, 0x18, 0x08, 0x31, 0x01, 0x32, 0x3b, 0x09, 0x37, 0xd3,
-0x00, 0x2d, 0x01, 0xd0, 0x43, 0x8b, 0x00, 0xe0, 0x03, 0x8b, 0x55, 0x00,
-0x2d, 0x18, 0x01, 0x3b, 0xab, 0x83, 0x83, 0x18, 0x03, 0x93, 0x20, 0x33,
-0x19, 0x71, 0x20, 0x4b, 0x9d, 0x6a, 0x53, 0x00, 0x1b, 0x18, 0x02, 0x93,
-0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35,
-0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68,
-0x2b, 0x0e, 0x5b, 0x06, 0x02, 0xd1, 0x08, 0x31, 0x01, 0xe0, 0x15, 0xe0,
-0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, 0x1d, 0x40, 0x9d, 0x42, 0x03, 0xd1,
-0xe3, 0x1f, 0x05, 0x3b, 0x1c, 0x04, 0x24, 0x0c, 0x02, 0x9b, 0xc0, 0x46,
-0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b,
-0x03, 0x9c, 0x40, 0x34, 0x23, 0x70, 0x01, 0x32, 0x07, 0x9b, 0xc0, 0x46,
-0xd9, 0x80, 0x51, 0x1e, 0xc3, 0x1d, 0x49, 0x33, 0x19, 0x70, 0x07, 0x61,
-0x04, 0x2a, 0x06, 0xd2, 0x06, 0x49, 0x53, 0x00, 0x1b, 0x18, 0x99, 0x83,
-0x01, 0x32, 0x04, 0x2a, 0xf9, 0xd3, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00,
-0x70, 0x47, 0x80, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, 0x12, 0x48, 0x01, 0x68,
-0x01, 0x31, 0x01, 0x60, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x78, 0x68,
-0xc0, 0x46, 0x01, 0x90, 0xb8, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x0d, 0x48,
-0x41, 0x68, 0xc9, 0x68, 0xc0, 0x46, 0x41, 0x60, 0x38, 0x1c, 0x00, 0xf0,
-0x4f, 0xf8, 0xb8, 0x68, 0x40, 0x09, 0x06, 0xd3, 0x10, 0x23, 0x02, 0x98,
-0x18, 0x43, 0x02, 0x90, 0x68, 0x46, 0x02, 0xf0, 0xe1, 0xff, 0x68, 0x46,
-0x02, 0xf0, 0x9a, 0xfe, 0x0c, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 0x00, 0xb5, 0x8c, 0xb0,
-0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43,
-0x01, 0x91, 0x00, 0xf0, 0x2f, 0xf8, 0x68, 0x46, 0x02, 0xf0, 0x84, 0xfe,
-0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
-0x02, 0x6a, 0x03, 0x68, 0xc0, 0x46, 0x13, 0x60, 0x40, 0x68, 0xc0, 0x46,
-0x50, 0x60, 0x40, 0x32, 0x48, 0x68, 0xc0, 0x46, 0x90, 0x80, 0xc8, 0x68,
-0xc0, 0x46, 0xd0, 0x80, 0x48, 0x69, 0xc0, 0x46, 0x10, 0x81, 0x88, 0x68,
-0xc0, 0x46, 0x50, 0x81, 0x08, 0x7e, 0xc0, 0x46, 0x90, 0x73, 0x08, 0x69,
-0xc0, 0x46, 0x90, 0x81, 0x70, 0x47, 0x04, 0x49, 0x08, 0x68, 0x00, 0x28,
-0x00, 0xd1, 0x70, 0x47, 0xc2, 0x68, 0xc0, 0x46, 0x0a, 0x60, 0xfa, 0xe7,
-0x6c, 0x06, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, 0xc0, 0x46, 0xc2, 0x60,
-0x08, 0x60, 0x70, 0x47, 0x6c, 0x06, 0x00, 0x80, 0xb0, 0xb4, 0x00, 0x22,
-0x12, 0x4f, 0x7c, 0x7f, 0x01, 0x34, 0x7c, 0x77, 0x03, 0x23, 0xfc, 0x1d,
-0x19, 0x34, 0x38, 0x62, 0x79, 0x62, 0x23, 0x72, 0x0e, 0x4c, 0x25, 0x68,
-0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x10, 0xd1, 0x24, 0x68,
-0xa3, 0x0a, 0x0d, 0xd3, 0x01, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0xfb, 0x62,
-0x09, 0x4f, 0x0a, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x99, 0x60, 0x58, 0x60,
-0x10, 0x1c, 0x18, 0x60, 0x01, 0x32, 0xfb, 0xe7, 0x10, 0x1c, 0x38, 0x64,
-0x01, 0x32, 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40,
-0xc0, 0x00, 0x18, 0x00, 0x02, 0x81, 0x00, 0x00, 0x40, 0x01, 0x18, 0x00,
-0xf0, 0xb5, 0x47, 0x4f, 0x38, 0x68, 0x47, 0x4e, 0x47, 0x4d, 0x07, 0x23,
-0x5b, 0x02, 0xec, 0x18, 0x00, 0x28, 0x1d, 0xd1, 0x20, 0x6b, 0x01, 0x30,
-0x20, 0x63, 0x44, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x43, 0x48, 0x41, 0x69,
-0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 0x00, 0x29,
-0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 0x09, 0x68,
-0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c,
-0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x50, 0xfe,
-0x38, 0x68, 0x01, 0x28, 0x17, 0xd1, 0x37, 0x48, 0x41, 0x69, 0x00, 0x29,
-0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, 0x0e, 0xd0,
-0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46,
-0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, 0x01, 0x31,
-0xf1, 0x64, 0x01, 0xf0, 0x35, 0xfe, 0x38, 0x68, 0x02, 0x28, 0x2f, 0xd1,
-0xbb, 0x23, 0x1b, 0x01, 0xee, 0x18, 0x70, 0x7b, 0x00, 0x28, 0x03, 0xd0,
-0x00, 0x20, 0x70, 0x73, 0x00, 0xf0, 0x4a, 0xfd, 0x30, 0x7b, 0x00, 0x28,
-0x02, 0xd0, 0x78, 0x68, 0x02, 0xf0, 0xaa, 0xff, 0x1b, 0x23, 0xdb, 0x01,
-0xe8, 0x18, 0xc0, 0x8b, 0x04, 0x26, 0x06, 0x40, 0xe0, 0x6a, 0xb0, 0x42,
-0x14, 0xd0, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x19, 0x28, 0x11, 0xd3,
-0x1b, 0x48, 0x01, 0x7b, 0x00, 0x29, 0x0d, 0xd1, 0xff, 0x30, 0x41, 0x30,
-0x40, 0x78, 0x00, 0x28, 0x08, 0xd1, 0xb8, 0x68, 0x02, 0xf0, 0x90, 0xff,
-0x00, 0x20, 0xf8, 0x60, 0xe6, 0x62, 0x01, 0xe0, 0x00, 0x20, 0xf8, 0x60,
-0x38, 0x68, 0x03, 0x28, 0x0b, 0xd1, 0xec, 0x1d, 0x79, 0x34, 0xe0, 0x6b,
-0x80, 0x08, 0x02, 0xd3, 0x02, 0x20, 0x02, 0xf0, 0x07, 0xfc, 0x02, 0x23,
-0xe0, 0x6b, 0x98, 0x43, 0xe0, 0x63, 0x38, 0x68, 0x01, 0x30, 0x38, 0x60,
-0x03, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x38, 0x60, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 0x64, 0x2d, 0x00, 0x80,
-0xe4, 0x2c, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, 0xb0, 0xb4, 0x1d, 0x48,
-0x84, 0x8a, 0x1d, 0x4a, 0x13, 0x8a, 0xc1, 0x1d, 0x09, 0x31, 0x01, 0x27,
-0x9c, 0x42, 0x03, 0xd1, 0x43, 0x8a, 0x54, 0x8a, 0xa3, 0x42, 0x10, 0xd0,
-0x0b, 0x78, 0x00, 0x2b, 0x0d, 0xd0, 0x4b, 0x78, 0x00, 0x2b, 0x0a, 0xd0,
-0x44, 0x8b, 0x93, 0x8a, 0x9c, 0x42, 0x04, 0xdc, 0x13, 0x4b, 0xc0, 0x46,
-0x5f, 0x60, 0x97, 0x82, 0x01, 0xe0, 0x01, 0x33, 0x93, 0x82, 0xc3, 0x8b,
-0x5c, 0x1c, 0xc4, 0x83, 0x84, 0x8b, 0xa3, 0x42, 0x0e, 0xdb, 0x84, 0x8a,
-0x05, 0x8b, 0x00, 0x23, 0xac, 0x42, 0x05, 0xda, 0x44, 0x8a, 0xc5, 0x8a,
-0xac, 0x42, 0x01, 0xda, 0x4b, 0x70, 0x00, 0xe0, 0x4f, 0x70, 0x43, 0x82,
-0x83, 0x82, 0xc3, 0x83, 0x41, 0x8a, 0xc0, 0x46, 0x51, 0x82, 0x80, 0x8a,
-0xc0, 0x46, 0x10, 0x82, 0xb0, 0xbc, 0x70, 0x47, 0xe8, 0x0e, 0x00, 0x80,
-0x3c, 0x04, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 0xf7, 0xb5, 0x91, 0xb0,
-0x6b, 0x46, 0x84, 0x1e, 0x12, 0x99, 0x14, 0x29, 0x1a, 0xd9, 0x00, 0x20,
-0x81, 0x00, 0x67, 0x58, 0xc0, 0x46, 0x57, 0x50, 0x01, 0x30, 0x00, 0x06,
-0x00, 0x0e, 0x10, 0x28, 0xf6, 0xd3, 0x00, 0x21, 0x05, 0x20, 0x87, 0x00,
-0xd6, 0x59, 0x4f, 0x1c, 0x3d, 0x06, 0x2d, 0x0e, 0x0f, 0x1c, 0xbf, 0x00,
-0xde, 0x51, 0x29, 0x1c, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28,
-0xf1, 0xd3, 0x09, 0xe0, 0x00, 0x20, 0x81, 0x00, 0x63, 0x58, 0xc0, 0x46,
-0x53, 0x50, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x06, 0x28, 0xf6, 0xd3,
-0x00, 0x20, 0xe0, 0x70, 0x20, 0x72, 0x60, 0x72, 0xa0, 0x72, 0x20, 0x73,
-0x60, 0x73, 0x12, 0x99, 0x14, 0x29, 0x37, 0xd9, 0x69, 0x46, 0x8e, 0x1c,
-0x91, 0x78, 0x09, 0x07, 0x09, 0x0f, 0x89, 0x00, 0x14, 0x39, 0x0d, 0x06,
-0x2d, 0x16, 0x00, 0x27, 0x00, 0x2d, 0x1b, 0xdd, 0xf0, 0x19, 0x10, 0xa9,
-0x00, 0xf0, 0x3d, 0xf8, 0x00, 0x28, 0x0e, 0xd0,
-0x00, 0x20, 0x10, 0xa9, 0x09, 0x78, 0x00, 0x29, 0x09, 0xdd, 0x00, 0x22,
-0x39, 0x18, 0x72, 0x54, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0xa9,
-0x09, 0x78, 0x88, 0x42, 0xf6, 0xdb, 0x10, 0xa8, 0x00, 0x78, 0x38, 0x18,
-0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 0xe3, 0xdb, 0x68, 0x46, 0xe2, 0x1d,
-0x0d, 0x32, 0x00, 0x21, 0xab, 0x08, 0x5f, 0x1c, 0x08, 0xd0, 0x8b, 0x00,
-0xc4, 0x58, 0xc0, 0x46, 0xd4, 0x50, 0x01, 0x31, 0x09, 0x06, 0x09, 0x0e,
-0x8f, 0x42, 0xf6, 0xd8, 0x14, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x90, 0xb4, 0x87, 0x1e, 0x00, 0x20, 0x89, 0x08, 0x4b, 0x1c, 0x08, 0xd0,
-0x81, 0x00, 0x54, 0x58, 0xc0, 0x46, 0x7c, 0x50, 0x01, 0x30, 0x00, 0x06,
-0x00, 0x0e, 0x83, 0x42, 0xf6, 0xd8, 0x90, 0xbc, 0x70, 0x47, 0x80, 0xb4,
-0x02, 0x78, 0xd2, 0x06, 0xd2, 0x0e, 0x00, 0x23, 0x01, 0x27, 0x01, 0x2a,
-0x01, 0xdc, 0x0f, 0x70, 0x11, 0xe0, 0x40, 0x78, 0xc0, 0x46, 0x08, 0x70,
-0x14, 0x2a, 0x04, 0xd1, 0x08, 0x48, 0x01, 0x7a, 0x01, 0x31, 0x01, 0x72,
-0x07, 0xe0, 0x02, 0x2a, 0x05, 0xd0, 0x05, 0x2a, 0x03, 0xd0, 0x06, 0x2a,
-0x01, 0xd0, 0x15, 0x2a, 0x02, 0xd1, 0x18, 0x1c, 0x80, 0xbc, 0x70, 0x47,
-0x38, 0x1c, 0xfb, 0xe7, 0xe0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x0f, 0x48,
-0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 0x41, 0x61,
-0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, 0x19, 0x1c,
-0x09, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18,
-0x80, 0x69, 0x00, 0x28, 0x03, 0xd0, 0x02, 0xf0, 0x61, 0xfe, 0x08, 0xbc,
-0x18, 0x47, 0x04, 0x48, 0x41, 0x88, 0x01, 0x31, 0x41, 0x80, 0xf8, 0xe7,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xe0, 0x82, 0x20, 0x40,
-0x70, 0x47, 0x00, 0x00, 0xf0, 0xb5, 0x86, 0xb0, 0x95, 0x4a, 0xd0, 0x68,
-0xd7, 0x1d, 0x79, 0x37, 0x01, 0x28, 0x09, 0xd1, 0x38, 0x89, 0x00, 0x28,
-0x06, 0xd1, 0xd0, 0x6f, 0x02, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60,
-0x14, 0x20, 0x38, 0x81, 0x8e, 0x4c, 0x61, 0x6a, 0x8e, 0x48, 0xc3, 0x6b,
-0x59, 0x18, 0xc1, 0x63, 0xa0, 0x6a, 0x19, 0x23, 0xdb, 0x01, 0xd4, 0x18,
-0xa0, 0x62, 0x21, 0x6a, 0x09, 0x03, 0x09, 0x0b, 0x81, 0x42, 0x05, 0xd1,
-0x01, 0x20, 0x40, 0x04, 0x87, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xf3, 0xe0,
-0xbb, 0x8a, 0x58, 0x1c, 0xb8, 0x82, 0x3d, 0x8b, 0x01, 0x20, 0x00, 0x21,
-0xab, 0x42, 0x04, 0xdb, 0xd3, 0x1d, 0x89, 0x33, 0x58, 0x70, 0xb9, 0x82,
-0xf9, 0x83, 0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x05, 0x93, 0x5b, 0x69,
-0x0f, 0x2b, 0x73, 0xd2, 0x00, 0x21, 0x7c, 0x4f, 0xc0, 0x46, 0x39, 0x61,
-0x21, 0x6a, 0x8a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x4b, 0x68, 0x1e, 0x0c,
-0x36, 0x04, 0xfd, 0x1f, 0x09, 0x3d, 0x00, 0x2e, 0x05, 0xd1, 0x3b, 0x2a,
-0x03, 0xd3, 0x01, 0x23, 0xdb, 0x02, 0x9a, 0x42, 0x01, 0xd9, 0xa8, 0x73,
-0xc8, 0xe0, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68,
-0xc0, 0x46, 0x03, 0x91, 0x03, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x09, 0x04,
-0x09, 0x0c, 0x79, 0x82, 0x49, 0x09, 0x05, 0x31, 0x09, 0x06, 0x09, 0x0e,
-0x69, 0x4e, 0xc0, 0x46, 0x02, 0x96, 0x69, 0x48, 0x43, 0x6a, 0xc0, 0x46,
-0x01, 0x93, 0x83, 0x6a, 0xc0, 0x46, 0x00, 0x93, 0xc2, 0x1d, 0x11, 0x32,
-0x80, 0x69, 0x00, 0x03, 0x00, 0x0b, 0x92, 0x68, 0xb3, 0x07, 0x1a, 0x43,
-0x12, 0x68, 0x90, 0x42, 0x01, 0xd1, 0x01, 0x20,
-0x0d, 0xe0, 0x90, 0x42, 0x05, 0xd9, 0x00, 0x9b, 0x18, 0x1a, 0x01, 0x9b,
-0xd2, 0x1a, 0x82, 0x18, 0x00, 0xe0, 0x12, 0x1a, 0x01, 0x20, 0x09, 0x01,
-0x91, 0x42, 0x00, 0xd3, 0x00, 0x20, 0x01, 0x28, 0x65, 0xd1, 0x51, 0x49,
-0x20, 0x69, 0x00, 0x28, 0x62, 0xd0, 0x05, 0x99, 0x48, 0x69, 0x01, 0x30,
-0x48, 0x61, 0x02, 0x20, 0x21, 0x6a, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0,
-0xa7, 0xfc, 0x78, 0x63, 0xbe, 0x60, 0x49, 0x49, 0x22, 0x6a, 0xa3, 0x6b,
-0xd3, 0x18, 0x66, 0x6b, 0xb3, 0x42, 0x00, 0xd9, 0x22, 0x6b, 0xc0, 0x46,
-0xba, 0x62, 0xba, 0x6a, 0x0c, 0x32, 0xfa, 0x62, 0x00, 0x22, 0xfa, 0x61,
-0x03, 0xaa, 0x52, 0x88, 0xd2, 0x09, 0x03, 0xd3, 0x01, 0x22, 0x00, 0xe0,
-0x7b, 0xe0, 0x00, 0xe0, 0x00, 0x22, 0x7a, 0x60, 0x7a, 0x68, 0xc0, 0x46,
-0x02, 0x60, 0x78, 0x8a, 0x41, 0x4e, 0x60, 0x28, 0x04, 0xdc, 0xb0, 0x83,
-0x78, 0x8a, 0xc0, 0x46, 0xf0, 0x83, 0x08, 0xe0, 0x60, 0x20, 0xb0, 0x83,
-0x79, 0x8a, 0xf8, 0x6a, 0x42, 0x18, 0x63, 0x6b, 0x9a, 0x42, 0x03, 0xd8,
-0xf1, 0x83, 0x00, 0x22, 0x3a, 0x63, 0x05, 0xe0, 0x21, 0x6b, 0xc0, 0x46,
-0x39, 0x63, 0x61, 0x6b, 0x08, 0x1a, 0xf0, 0x83, 0x2d, 0x49, 0x78, 0x6b,
-0x42, 0x68, 0xc0, 0x46, 0xba, 0x60, 0x82, 0x68, 0xc0, 0x46, 0xfa, 0x60,
-0x02, 0x69, 0xc0, 0x46, 0x7a, 0x61, 0x40, 0x69, 0xc0, 0x46, 0xb8, 0x61,
-0x2e, 0x4b, 0xc8, 0x18, 0x04, 0x90, 0x00, 0xf0, 0x37, 0xf9, 0x04, 0x98,
-0x00, 0xf0, 0x88, 0xf8, 0x00, 0xf0, 0xf6, 0xfa, 0x78, 0x8a, 0xf1, 0x8b,
-0x88, 0x42, 0x04, 0xd1, 0xf9, 0x6a, 0x08, 0x18, 0x04, 0xe0, 0x38, 0xe0,
-0x32, 0xe0, 0x3a, 0x6b, 0x10, 0x18, 0x40, 0x1a, 0x81, 0x07, 0x02, 0xd0,
-0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x61, 0x6b, 0x09, 0x1a, 0xa2, 0x6b,
-0x91, 0x42, 0x00, 0xd2, 0x20, 0x6b, 0xc0, 0x46, 0x20, 0x62, 0xe8, 0x7b,
-0x00, 0x28, 0x08, 0xd0, 0x00, 0x22, 0xea, 0x73, 0x05, 0x99, 0x48, 0x69,
-0x01, 0x38, 0x48, 0x61, 0x78, 0x6b, 0x00, 0xf0, 0x73, 0xfa, 0x18, 0x48,
-0x80, 0x6a, 0x80, 0x06, 0x80, 0x0e, 0x01, 0x28, 0x0a, 0xd1, 0x20, 0x6a,
-0x00, 0x03, 0x00, 0x0b, 0x0b, 0x4c, 0xa1, 0x6a, 0x88, 0x42, 0x03, 0xd0,
-0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0x40, 0x04,
-0x08, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x06, 0xe0, 0xe0, 0x68, 0x00, 0x28,
-0x01, 0xd0, 0x00, 0xf0, 0xb5, 0xfa, 0x01, 0x20, 0xa8, 0x73, 0xed, 0xe7,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x40, 0x14, 0x40, 0xa4, 0x2a, 0x00, 0x80,
-0x00, 0x00, 0x00, 0xb0, 0x28, 0x1a, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55,
-0xa8, 0x03, 0x00, 0x80, 0x68, 0x1a, 0x00, 0x80, 0xc4, 0x0b, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0x80, 0xb5, 0x07, 0x1c, 0x78, 0x6a, 0x40, 0x89,
-0xff, 0x21, 0x01, 0x31, 0x01, 0x40, 0x10, 0x48, 0x02, 0xd1, 0x81, 0x6c,
-0x01, 0x31, 0x81, 0x64, 0x79, 0x6a, 0x49, 0x89, 0x49, 0x0b, 0x02, 0xd2,
-0x41, 0x6c, 0x01, 0x31, 0x41, 0x64, 0x0b, 0x48, 0x41, 0x6a, 0x01, 0x31,
-0x41, 0x62, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b,
-0x00, 0xf0, 0xf8, 0xfb, 0x38, 0x1c, 0x00, 0xf0, 0xb3, 0xf8, 0x01, 0x20,
-0x04, 0x49, 0xc0, 0x46, 0xc8, 0x73, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xa4, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x18, 0x1a, 0x00, 0x80,
-0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x22, 0xf9, 0x1d, 0x61, 0x31, 0x0d, 0x1c,
-0x78, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x40, 0x89,
-0x03, 0x0c, 0x01, 0xd2, 0x40, 0x0a, 0x03, 0xd2, 0x38, 0x1c, 0xff, 0xf7,
-0xc1, 0xff, 0x67, 0xe0, 0x35, 0x48, 0xc0, 0x6b, 0x00, 0x09, 0x1f, 0xd3,
-0x08, 0x78, 0x40, 0x08, 0x1c, 0xd2, 0x00, 0x20, 0x43, 0x00, 0xcc, 0x5a,
-0x31, 0x4e, 0x9e, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0x1b, 0x88,
-0x9c, 0x42, 0x0e, 0xd0, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61,
-0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x38, 0x1c, 0x00, 0xf0,
-0x27, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x74, 0xf8, 0x46, 0xe0, 0x01, 0x30,
-0x03, 0x28, 0xe3, 0xdb, 0x02, 0x20, 0x43, 0x00, 0x5c, 0x18, 0xe4, 0x88,
-0x22, 0x4e, 0x9e, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0x1b, 0x88,
-0x9c, 0x42, 0x03, 0xd1, 0x01, 0x23, 0x01, 0x38, 0xd8, 0x42, 0xf0, 0xdc,
-0x01, 0x23, 0xd8, 0x42, 0xc4, 0xd0, 0x1b, 0x4e, 0x0b, 0x23, 0x1b, 0x02,
-0xf0, 0x18, 0x40, 0x69, 0x00, 0x28, 0x24, 0xd0, 0x7d, 0x63, 0x00, 0x98,
-0x40, 0x89, 0x00, 0x0c, 0x1f, 0xd2, 0x00, 0x24, 0x2d, 0x23, 0x9b, 0x01,
-0xf0, 0x18, 0xc0, 0x6b, 0x35, 0x1c, 0x00, 0x28, 0x17, 0xd0, 0xfe, 0x1d,
-0x2d, 0x36, 0xa2, 0x00, 0x52, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xd2, 0x18,
-0xd2, 0x6b, 0x38, 0x1c, 0x31, 0x1c, 0x02, 0xf0, 0x7b, 0xfc, 0x01, 0x28,
-0x0e, 0xd0, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x2d, 0x23, 0x9b, 0x01,
-0xc0, 0x18, 0xc0, 0x6b, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, 0x01, 0x2a,
-0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 0xf8, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80,
-0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61,
-0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x78, 0x6a, 0x40, 0x89,
-0x01, 0x0c, 0x0e, 0xd2, 0x40, 0x0a, 0x0c, 0xd3, 0x38, 0x68, 0x40, 0x08,
-0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x0c, 0xfc, 0x38, 0x1c, 0x00, 0xf0,
-0xbb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 0x02, 0xe0, 0x38, 0x1c,
-0xff, 0xf7, 0x30, 0xff, 0x01, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x01, 0x21, 0x00, 0x6b, 0x40, 0x6a, 0xc0, 0x46, 0x01, 0x60, 0x70, 0x47,
-0xb0, 0xb4, 0xc1, 0x1d, 0x39, 0x31, 0x09, 0x8b, 0x89, 0x08, 0x09, 0x04,
-0x09, 0x0c, 0x84, 0x6a, 0xc2, 0x1d, 0x61, 0x32, 0x00, 0x20, 0x00, 0x29,
-0x0c, 0xdd, 0x87, 0x00, 0x3d, 0x19, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43,
-0x1b, 0x68, 0xc0, 0x46, 0xd3, 0x51, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c,
-0x88, 0x42, 0xf2, 0xdb, 0xb0, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xa0, 0xb0,
-0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x21, 0x31, 0x19, 0x43, 0x09, 0x68,
-0xc0, 0x46, 0x0b, 0x91, 0xc1, 0x1d, 0x53, 0x31, 0x19, 0x43, 0x1f, 0x91,
-0x09, 0x68, 0x01, 0xaf, 0xfa, 0x1d, 0x39, 0x32, 0x1e, 0x92, 0x17, 0xab,
-0x59, 0x80, 0x3a, 0x49, 0x01, 0x23, 0x9b, 0x07, 0x0a, 0x6a, 0x13, 0x43,
-0xcc, 0x1d, 0x11, 0x34, 0x89, 0x69, 0x09, 0x03, 0x09, 0x0b, 0x22, 0x69,
-0xe5, 0x68, 0xc0, 0x46, 0x1d, 0x95, 0xfc, 0x1d, 0x39, 0x34, 0x64, 0x8b,
-0x64, 0x09, 0x05, 0x34, 0x24, 0x06, 0x24, 0x0e, 0x1c, 0x94, 0x56, 0x1a,
-0x1b, 0x96, 0x1c, 0x9c, 0x2e, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x26,
-0x1d, 0x9d, 0x1a, 0x68, 0x91, 0x42, 0x01, 0xd1, 0x32, 0x1c, 0x0b, 0xe0,
-0x91, 0x42, 0x03, 0xd9, 0x52, 0x1b, 0x1b, 0x9e, 0xb5, 0x18, 0x00, 0xe0,
-0x55, 0x1a, 0x01, 0x22, 0x24, 0x01, 0xac, 0x42,
-0x00, 0xd3, 0x00, 0x22, 0x01, 0x2a, 0xe6, 0xd1, 0x91, 0x07, 0x01, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0x39, 0x60, 0x93, 0x07, 0x01, 0x1d, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0x79, 0x60, 0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0x1f, 0x99, 0x09, 0x68, 0x1e, 0x9a,
-0xc0, 0x46, 0x51, 0x83, 0xc1, 0x1d, 0x1d, 0x31, 0x19, 0x43, 0x09, 0x68,
-0xc0, 0x46, 0x38, 0x63, 0x79, 0x62, 0xc1, 0x1d, 0x11, 0x31, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0xb9, 0x61, 0xc1, 0x1d, 0x05, 0x31, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0xc1, 0x1d, 0x17, 0x31, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0xf9, 0x83, 0x0e, 0x30, 0x18, 0x43, 0x00, 0x68,
-0xc0, 0x46, 0xf8, 0x81, 0x38, 0x68, 0x40, 0x08, 0x02, 0xd3, 0x38, 0x1c,
-0x02, 0xf0, 0x5c, 0xfb, 0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xf8, 0x38, 0x1c,
-0xff, 0xf7, 0x58, 0xff, 0x20, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xa8, 0x03, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55, 0xf8, 0xb5, 0x07, 0x1c,
-0xf8, 0x1d, 0x39, 0x30, 0x41, 0x8b, 0x39, 0x4a, 0x91, 0x42, 0x00, 0xdd,
-0x42, 0x83, 0x42, 0x8b, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x20, 0x3a, 0x1d,
-0x06, 0xca, 0xbb, 0x6a, 0x02, 0xf0, 0x0e, 0xff, 0x33, 0x4a, 0xc0, 0x46,
-0x00, 0x92, 0x33, 0x4e, 0x30, 0x6a, 0x33, 0x4c, 0xe1, 0x6d, 0x41, 0x18,
-0x38, 0x6b, 0xc3, 0x1d, 0x05, 0x33, 0x01, 0x20, 0x72, 0x6a, 0x02, 0xf0,
-0xfb, 0xfe, 0xe0, 0x6d, 0x18, 0x30, 0x00, 0x25, 0xb1, 0x6a, 0x81, 0x42,
-0x01, 0xd8, 0xe5, 0x65, 0x00, 0xe0, 0xe0, 0x65, 0x2f, 0x23, 0x9b, 0x01,
-0x20, 0x1c, 0xe1, 0x6d, 0xe4, 0x18, 0x22, 0x68, 0x92, 0x00, 0x27, 0x4b,
-0xc0, 0x46, 0x99, 0x50, 0x26, 0x48, 0xc1, 0x6b, 0x4a, 0x08, 0x05, 0xd3,
-0x49, 0x08, 0x49, 0x00, 0xc1, 0x63, 0x01, 0x20, 0x01, 0xf0, 0xd6, 0xff,
-0x22, 0x4a, 0x1f, 0x48, 0xc1, 0x1d, 0x89, 0x31, 0x0b, 0x78, 0x00, 0x2b,
-0x02, 0xd0, 0x49, 0x78, 0x00, 0x29, 0x00, 0xd1, 0x1e, 0x4a, 0xc0, 0x46,
-0x00, 0x92, 0x20, 0x68, 0x80, 0x00, 0x19, 0x4b, 0xc3, 0x18, 0x05, 0xce,
-0xc1, 0x1d, 0x11, 0x31, 0x01, 0x20, 0x02, 0xf0, 0xc7, 0xfe, 0x14, 0x48,
-0x21, 0x68, 0x01, 0x31, 0x21, 0x60, 0x17, 0x29, 0x00, 0xd3, 0x25, 0x60,
-0x39, 0x6b, 0xc0, 0x46, 0x0d, 0x65, 0x79, 0x6a, 0x3a, 0x6b, 0xc0, 0x46,
-0x51, 0x62, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x68, 0x00, 0x29,
-0x03, 0xd1, 0x39, 0x6b, 0xc0, 0x46, 0x81, 0x60, 0x04, 0xe0, 0x39, 0x6b,
-0xc2, 0x68, 0xc0, 0x46, 0x11, 0x65, 0x39, 0x6b, 0xc0, 0x46, 0xc1, 0x60,
-0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00,
-0x18, 0x00, 0x14, 0x02, 0x7c, 0x29, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80,
-0x44, 0x82, 0x20, 0x40, 0xe8, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x00, 0x02,
-0x04, 0x00, 0x00, 0x03, 0xf0, 0xb5, 0x11, 0x4e, 0xff, 0x25, 0x01, 0x35,
-0x10, 0x4f, 0xc0, 0x46, 0x35, 0x60, 0x78, 0x69, 0x01, 0x38, 0x78, 0x61,
-0xbc, 0x68, 0x00, 0x2c, 0x10, 0xd0, 0x20, 0x6d, 0xc0, 0x46, 0xb8, 0x60,
-0x20, 0x1c, 0x00, 0xf0, 0x21, 0xf8, 0x20, 0x1c, 0x00, 0xf0, 0x04, 0xfa,
-0x08, 0x48, 0x80, 0x6a, 0x00, 0x0c, 0x00, 0x07, 0xe9, 0xd1, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x05, 0x48, 0xc1, 0x79, 0x01, 0x31, 0xc1, 0x71,
-0xf7, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x28, 0x1b, 0x00, 0x80,
-0x00, 0x00, 0x10, 0x40, 0xa0, 0x82, 0x20, 0x40,
-0x01, 0x20, 0x80, 0x03, 0x01, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x70, 0x47,
-0x00, 0x00, 0x00, 0xb0, 0x90, 0xb5, 0x07, 0x1c, 0x38, 0x68, 0xc0, 0x08,
-0x09, 0xd3, 0x1d, 0x48, 0x01, 0x6a, 0x01, 0x39, 0x01, 0x62, 0x20, 0x30,
-0x00, 0x79, 0x00, 0x28, 0x01, 0xd0, 0xfe, 0xf7, 0xe9, 0xfd, 0x01, 0x23,
-0x9b, 0x07, 0xf8, 0x1d, 0x1d, 0x30, 0x18, 0x43, 0x00, 0x68, 0x16, 0x4c,
-0x61, 0x6a, 0x81, 0x42, 0x21, 0xd1, 0x01, 0x1c, 0x19, 0x43, 0x09, 0x68,
-0x09, 0x04, 0x09, 0x0c, 0x01, 0x29, 0x1a, 0xd1, 0x00, 0xf0, 0x22, 0xf8,
-0x60, 0x62, 0x60, 0x6a, 0x21, 0x6a, 0x88, 0x42, 0x05, 0xd0, 0x01, 0x21,
-0x89, 0x07, 0x01, 0x43, 0x09, 0x68, 0x09, 0x04, 0xf2, 0xd0, 0x51, 0x21,
-0x89, 0x03, 0x62, 0x6a, 0x23, 0x6b, 0x9a, 0x42, 0x02, 0xd1, 0x60, 0x6b,
-0xa2, 0x6b, 0x80, 0x1a, 0x04, 0x38, 0xc8, 0x60, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x20, 0x79, 0x6a, 0xc0, 0x46, 0x08, 0x60, 0xf7, 0xe7,
-0x6c, 0x06, 0x00, 0x80, 0xe8, 0x1a, 0x00, 0x80, 0x01, 0x23, 0x9b, 0x07,
-0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c,
-0x08, 0x18, 0x0d, 0x30, 0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00,
-0x04, 0x30, 0x04, 0x49, 0x8a, 0x6b, 0x12, 0x18, 0x4b, 0x6b, 0x9a, 0x42,
-0x00, 0xd9, 0x08, 0x6b, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80,
-0x00, 0xb5, 0x04, 0x48, 0xc0, 0x68, 0x10, 0x28, 0x01, 0xd3, 0x00, 0xf0,
-0x05, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80,
-0x88, 0xb5, 0x0c, 0x4f, 0x38, 0x79, 0x00, 0x28, 0x11, 0xd1, 0x0b, 0x49,
-0x10, 0x20, 0x02, 0xf0, 0xf5, 0xfd, 0x00, 0x28, 0x0b, 0xd0, 0x01, 0x20,
-0x38, 0x71, 0x08, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x07, 0x48, 0x42, 0x68,
-0x07, 0x4b, 0x01, 0x68, 0x00, 0x20, 0x02, 0xf0, 0xdf, 0xfd, 0x88, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0xf8, 0x1a, 0x00, 0x80, 0xf5, 0x2c, 0xff, 0xff,
-0x10, 0x00, 0x35, 0x02, 0x7c, 0x29, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40,
-0x90, 0xb5, 0x01, 0x20, 0x40, 0x02, 0x10, 0x49, 0xc0, 0x46, 0x08, 0x60,
-0x0f, 0x4f, 0x10, 0x21, 0xf8, 0x1d, 0x3d, 0x30, 0x02, 0xf0, 0x4c, 0xfc,
-0x19, 0x23, 0xdb, 0x01, 0xfc, 0x18, 0xe0, 0x68, 0x00, 0x28, 0x01, 0xd0,
-0x00, 0xf0, 0x14, 0xf8, 0x00, 0x20, 0xc9, 0x23, 0x1b, 0x01, 0xf9, 0x18,
-0x08, 0x71, 0xe0, 0x68, 0x10, 0x28, 0x04, 0xd3, 0x01, 0x20, 0xbb, 0x23,
-0x1b, 0x01, 0xf9, 0x18, 0x48, 0x73, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 0xf8, 0xb5, 0x37, 0x48,
-0x19, 0x23, 0xdb, 0x01, 0xc1, 0x18, 0xc9, 0x68, 0x35, 0x4d, 0x10, 0x29,
-0x00, 0xd9, 0x10, 0x21, 0x69, 0x62, 0x32, 0x48, 0xc1, 0x6c, 0x00, 0x6e,
-0x81, 0x42, 0x07, 0xd9, 0x08, 0x1a, 0x07, 0x09, 0x00, 0x24, 0x68, 0x6a,
-0xb8, 0x42, 0x12, 0xd2, 0x07, 0x1c, 0x10, 0xe0, 0x81, 0x42, 0x2a, 0xd2,
-0x2c, 0x4a, 0x52, 0x6b, 0x10, 0x1a, 0x07, 0x09, 0x68, 0x6a, 0xb8, 0x42,
-0x05, 0xd9, 0x0c, 0x09, 0x39, 0x19, 0x88, 0x42, 0x03, 0xd2, 0xc4, 0x1b,
-0x01, 0xe0, 0x00, 0x24, 0x07, 0x1c, 0x3e, 0x19, 0x30, 0x01, 0x25, 0x49,
-0x02, 0xf0, 0x84, 0xfd, 0x00, 0x28, 0x3d, 0xd0, 0x23, 0x48, 0x00, 0x2c,
-0x1a, 0xd1, 0x1e, 0x49, 0x3a, 0x01, 0x6f, 0x62, 0x09, 0x6e, 0x8c, 0x18,
-0x1d, 0x4d, 0x6b, 0x6b, 0xa3, 0x42, 0x00, 0xd8, 0xe4, 0x1a, 0x1e, 0x4b,
-0x1a, 0x43, 0x00, 0x92, 0xea, 0x6a, 0x51, 0x18,
-0x2a, 0x6b, 0x03, 0x1c, 0x20, 0xe0, 0x1b, 0x48, 0x01, 0x6b, 0x01, 0x31,
-0x01, 0x63, 0x00, 0x20, 0x68, 0x62, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x10, 0x49, 0x24, 0x01, 0x3f, 0x01, 0x11, 0x22, 0x52, 0x05, 0x3a, 0x43,
-0x6e, 0x62, 0x00, 0x92, 0x0e, 0x4d, 0xea, 0x6a, 0x09, 0x6e, 0x51, 0x18,
-0x03, 0x1c, 0x06, 0x1c, 0x00, 0x20, 0x2a, 0x6b, 0x02, 0xf0, 0x4a, 0xfd,
-0x0c, 0x4a, 0x22, 0x43, 0x00, 0x92, 0xbb, 0x19, 0xe9, 0x6a, 0x2a, 0x6b,
-0x00, 0x20, 0x02, 0xf0, 0x41, 0xfd, 0x03, 0x48, 0xc0, 0x46, 0x04, 0x66,
-0x00, 0xf0, 0x10, 0xf8, 0x01, 0x20, 0xda, 0xe7, 0x68, 0x0e, 0x00, 0x80,
-0x28, 0x1b, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 0x5d, 0x2e, 0xff, 0xff,
-0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x36, 0x02, 0xa0, 0x82, 0x20, 0x40,
-0x04, 0x48, 0x01, 0x6e, 0x04, 0x4a, 0x80, 0x30, 0xd1, 0x60, 0x02, 0x23,
-0xc1, 0x6b, 0x19, 0x43, 0xc1, 0x63, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x90, 0xee, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 0x01, 0x20, 0x80, 0x02,
-0x1c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x27, 0x1b, 0x4e, 0x33, 0x23,
-0x9b, 0x01, 0xf5, 0x18, 0x68, 0x6a, 0x00, 0x28, 0x1d, 0xd9, 0x19, 0x4c,
-0x68, 0x46, 0x10, 0x21, 0x02, 0xf0, 0x90, 0xfb, 0x68, 0x46, 0x00, 0xf0,
-0x33, 0xf8, 0x00, 0x28, 0x04, 0xd0, 0x15, 0x49, 0x48, 0x69, 0x01, 0x30,
-0x48, 0x61, 0x0a, 0xe0, 0x13, 0x49, 0x60, 0x7b, 0x01, 0x30, 0x60, 0x73,
-0x88, 0x79, 0x01, 0x30, 0x88, 0x71, 0x11, 0x48, 0x00, 0x68, 0x02, 0xf0,
-0x65, 0xf9, 0x68, 0x6a, 0x01, 0x37, 0xb8, 0x42, 0xe2, 0xd8, 0xbb, 0x23,
-0x1b, 0x01, 0xf0, 0x18, 0x81, 0x7b, 0x00, 0x29, 0x03, 0xd0, 0x00, 0x21,
-0x81, 0x73, 0xff, 0xf7, 0x05, 0xfb, 0xff, 0xf7, 0xe3, 0xfe, 0x04, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0,
-0x68, 0x0e, 0x00, 0x80, 0xb0, 0x82, 0x20, 0x40, 0x08, 0x83, 0x20, 0x40,
-0xa0, 0x82, 0x20, 0x40, 0x58, 0x04, 0x00, 0x80, 0x90, 0xb4, 0x17, 0x4f,
-0x19, 0x23, 0xdb, 0x01, 0xf9, 0x18, 0x00, 0x22, 0xcb, 0x68, 0x00, 0x2b,
-0x23, 0xd0, 0x01, 0x3b, 0xcb, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xff, 0x18,
-0xbb, 0x69, 0x1c, 0x6d, 0xc0, 0x46, 0xbc, 0x61, 0x04, 0x68, 0xc0, 0x46,
-0x5c, 0x60, 0x44, 0x68, 0xc0, 0x46, 0x9c, 0x60, 0x84, 0x68, 0xc0, 0x46,
-0x1c, 0x61, 0xc0, 0x68, 0xc0, 0x46, 0x58, 0x61, 0x1a, 0x65, 0x08, 0x69,
-0x42, 0x1c, 0x0a, 0x61, 0x00, 0x28, 0x03, 0xd0, 0x38, 0x6a, 0xc0, 0x46,
-0x03, 0x65, 0x00, 0xe0, 0xfb, 0x61, 0x3b, 0x62, 0x18, 0x1c, 0x90, 0xbc,
-0x70, 0x47, 0x10, 0x1c, 0xfb, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x0a, 0x4a, 0x33, 0x23, 0x9b, 0x01, 0xd1, 0x18, 0xc8, 0x69, 0x19, 0x23,
-0xdb, 0x01, 0xd2, 0x18, 0x13, 0x69, 0x00, 0x2b, 0x06, 0xd0, 0x01, 0x3b,
-0x13, 0x61, 0xca, 0x69, 0x12, 0x6d, 0xc0, 0x46, 0xca, 0x61, 0x70, 0x47,
-0x00, 0x21, 0x11, 0x61, 0xfb, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x06, 0x4a, 0x11, 0x69, 0x4b, 0x1c, 0x13, 0x61, 0x40, 0x32, 0x00, 0x29,
-0x01, 0xd0, 0xd1, 0x69, 0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0xd0, 0x61,
-0x70, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, 0x06, 0x4a, 0xd1, 0x68,
-0x4b, 0x1c, 0xd3, 0x60, 0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x91, 0x69,
-0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0x90, 0x61, 0x70, 0x47, 0x00, 0x00,
-0xe8, 0x1a, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21,
-0x0f, 0x4a, 0x97, 0x89, 0x92, 0x6a, 0x4b, 0x00, 0x1b, 0x18, 0x9b, 0x8a,
-0x00, 0x2b, 0x12, 0xd0, 0xbb, 0x42, 0x10, 0xdc, 0x1c, 0x1c, 0x58, 0x23,
-0x63, 0x43, 0xd3, 0x18, 0xdc, 0x1f, 0x49, 0x3c, 0x01, 0x23, 0x9b, 0x07,
-0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, 0x02, 0xd0,
-0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x31, 0x04, 0x29, 0xe4, 0xd3,
-0x01, 0x20, 0xf8, 0xe7, 0x4c, 0x2a, 0x00, 0x80, 0xf7, 0xb5, 0x86, 0xb0,
-0x3d, 0x4a, 0x07, 0x1c, 0xd1, 0x69, 0x8f, 0x40, 0x03, 0x1c, 0x14, 0x6a,
-0xe3, 0x40, 0x5f, 0x40, 0x07, 0x9e, 0x8e, 0x40, 0x77, 0x40, 0xcf, 0x40,
-0x94, 0x69, 0xc0, 0x46, 0x05, 0x94, 0x03, 0x1c, 0xa3, 0x40, 0x00, 0x25,
-0x14, 0x69, 0xc0, 0x46, 0x04, 0x94, 0x00, 0x2c, 0x5d, 0xd9, 0x1c, 0x1c,
-0x32, 0x4e, 0x26, 0x43, 0x94, 0x69, 0xe6, 0x40, 0x33, 0x1c, 0x03, 0x96,
-0x53, 0x6a, 0xc0, 0x46, 0x02, 0x93, 0xd2, 0x6a, 0xc0, 0x46, 0x01, 0x92,
-0xbb, 0x00, 0x02, 0x9a, 0xd2, 0x58, 0x13, 0x1c, 0x05, 0x9c, 0xe3, 0x40,
-0x03, 0x9c, 0xa3, 0x42, 0x3e, 0xd1, 0x8a, 0x40, 0xca, 0x40, 0x14, 0x1c,
-0x63, 0x00, 0x1b, 0x19, 0x5b, 0x01, 0x01, 0x9a, 0xd2, 0x18, 0x01, 0x23,
-0x9b, 0x07, 0xd6, 0x1d, 0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06,
-0x1b, 0x0e, 0x03, 0x2b, 0x2c, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d,
-0x51, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x07, 0x9e, 0x1e, 0x40, 0x00, 0x96,
-0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x49, 0x36, 0x33, 0x43, 0x1b, 0x68,
-0x83, 0x42, 0x1b, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x4d, 0x36,
-0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0xb3, 0x42, 0x12, 0xd1, 0x01, 0x23,
-0x9b, 0x07, 0x1a, 0x43, 0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x08, 0x9b,
-0x32, 0x2b, 0x04, 0xd1, 0x02, 0x2a, 0x07, 0xd1, 0x20, 0x04, 0x00, 0x14,
-0x0f, 0xe0, 0x08, 0x9b, 0x33, 0x2b, 0x01, 0xd1, 0x01, 0x2a, 0xf7, 0xd0,
-0x04, 0x9a, 0x01, 0x37, 0x97, 0x42, 0x00, 0xd3, 0x00, 0x27, 0x04, 0x9a,
-0x01, 0x35, 0xaa, 0x42, 0xae, 0xd8, 0x00, 0x20, 0xc0, 0x43, 0x09, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80,
-0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x27, 0x4d, 0x68, 0x69, 0x00, 0x28,
-0x06, 0xd0, 0x26, 0x48, 0x00, 0x68, 0x02, 0xf0, 0x2b, 0xf8, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x23, 0x4c, 0x00, 0x26, 0xa0, 0x68, 0x23, 0x4f,
-0x00, 0x28, 0x16, 0xd0, 0x0f, 0xe0, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3,
-0x01, 0x20, 0x38, 0x71, 0x0f, 0xe0, 0xa6, 0x60, 0xfd, 0xf7, 0xde, 0xfe,
-0x00, 0x28, 0xea, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20,
-0x38, 0x71, 0xe8, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28,
-0xe9, 0xd0, 0x68, 0x68, 0x00, 0x28, 0x1b, 0xd0, 0x01, 0x20, 0xa0, 0x60,
-0xfe, 0xf7, 0xbc, 0xfb, 0x00, 0x28, 0xd6, 0xd1, 0x68, 0x68, 0x00, 0x28,
-0xf6, 0xd1, 0x11, 0xe0, 0x00, 0x28, 0xd0, 0xd1, 0x28, 0x6a, 0x02, 0x28,
-0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xca, 0xe7, 0xa6, 0x60, 0xfd, 0xf7,
-0xb9, 0xfe, 0x00, 0x28, 0xc5, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3,
-0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, 0x00, 0x28, 0xbd, 0xd0, 0x38, 0x79,
-0x00, 0x28, 0xe7, 0xd0, 0xb9, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0x5c, 0x04, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80, 0x8c, 0x06, 0x00, 0x80,
-0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00,
-0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x40, 0x20, 0x1d, 0x49, 0xc0, 0x46,
-0x08, 0x60, 0x01, 0xf0, 0x9d, 0xfc, 0x03, 0x23, 0x1b, 0x07, 0x41, 0x68,
-0x19, 0x40, 0x0c, 0x0f, 0x61, 0x01, 0x09, 0x1b, 0x89, 0x00, 0x18, 0x4a,
-0x8f, 0x18, 0x01, 0x21, 0x39, 0x80, 0x81, 0x6a, 0xc0, 0x46, 0x79, 0x65,
-0x41, 0x6a, 0xc0, 0x46, 0x79, 0x67, 0xb9, 0x6c, 0xfa, 0x6c, 0x89, 0x18,
-0xb9, 0x64, 0x00, 0x21, 0xf9, 0x64, 0xba, 0x6b, 0x3b, 0x6d, 0xd2, 0x18,
-0xba, 0x63, 0x39, 0x65, 0x42, 0x6a, 0x20, 0x32, 0x51, 0x71, 0x79, 0x6d,
-0x7a, 0x6f, 0xd2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 0xfc, 0xf7, 0xca, 0xff,
-0x20, 0x01, 0x09, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18,
-0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0x78, 0x6f, 0x01, 0xf0, 0xc6, 0xfb,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0,
-0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80, 0xf0, 0xb5, 0x40, 0x20,
-0x12, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, 0x59, 0xfc, 0x07, 0x1c,
-0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x06, 0x0f, 0x70, 0x01,
-0x80, 0x1b, 0x80, 0x00, 0x0c, 0x49, 0x44, 0x18, 0xb8, 0x6a, 0xc0, 0x46,
-0x60, 0x65, 0x78, 0x6a, 0xc0, 0x46, 0x60, 0x67, 0x80, 0x6f, 0x05, 0x1d,
-0xe5, 0x63, 0xb9, 0x69, 0x28, 0x1c, 0x02, 0xf0, 0x89, 0xf9, 0x38, 0x1c,
-0x21, 0x1c, 0x32, 0x1c, 0x2b, 0x1c, 0x00, 0xf0, 0x20, 0xf8, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x5c, 0x2b, 0x00, 0x80,
-0xf0, 0xb5, 0x4b, 0x6f, 0x9b, 0x6f, 0x1f, 0x1d, 0xcf, 0x63, 0x05, 0x68,
-0x00, 0x23, 0x84, 0x69, 0xa4, 0x08, 0x08, 0xd0, 0x9c, 0x00, 0x2e, 0x59,
-0xc0, 0x46, 0x3e, 0x51, 0x84, 0x69, 0xa4, 0x08, 0x01, 0x33, 0x9c, 0x42,
-0xf6, 0xd8, 0x3b, 0x1c, 0x00, 0xf0, 0x03, 0xf8, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0xff, 0xb5, 0x81, 0xb0, 0x04, 0x1c, 0x1d, 0x1c, 0x0f, 0x1c,
-0x46, 0x48, 0x01, 0x69, 0x01, 0x31, 0x01, 0x61, 0xf9, 0x1d, 0x51, 0x31,
-0xbd, 0x65, 0x00, 0x91, 0x20, 0x1c, 0xfd, 0xf7, 0x5d, 0xfc, 0xf8, 0x6d,
-0x40, 0x09, 0x36, 0xd2, 0xb8, 0x6d, 0x06, 0x7b, 0x43, 0x7b, 0x1b, 0x02,
-0x1e, 0x43, 0x17, 0x21, 0x49, 0x02, 0x01, 0x73, 0x0b, 0x0a, 0x43, 0x73,
-0x00, 0x99, 0x20, 0x1c, 0xfd, 0xf7, 0x4c, 0xfc, 0xb8, 0x6d, 0xc0, 0x46,
-0x06, 0x73, 0x33, 0x0a, 0x43, 0x73, 0xf8, 0x6d, 0x40, 0x09, 0x20, 0xd2,
-0x60, 0x68, 0x01, 0x04, 0x09, 0x0c, 0x03, 0x98, 0x01, 0xf0, 0xcc, 0xfc,
-0x60, 0x68, 0x32, 0x4b, 0x18, 0x43, 0x60, 0x60, 0x20, 0x1c, 0x01, 0xf0,
-0x35, 0xfd, 0x00, 0x25, 0x7d, 0x60, 0xbd, 0x60, 0x3d, 0x64, 0x7d, 0x64,
-0x20, 0x1c, 0xfc, 0xf7, 0x31, 0xff, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43,
-0x38, 0x80, 0x7d, 0x62, 0x29, 0x48, 0xc0, 0x46, 0xb8, 0x62, 0x38, 0x1c,
-0x00, 0xf0, 0xa0, 0xfb, 0x44, 0xe0, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07,
-0x08, 0x38, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0x78, 0x64, 0x60, 0x68,
-0x02, 0x04, 0x12, 0x0c, 0x78, 0x6e, 0x01, 0x26, 0xc1, 0x1d, 0x0d, 0x31,
-0x8a, 0x42, 0x02, 0xd2, 0x3a, 0x64, 0x08, 0x1c, 0x0e, 0xe0, 0x41, 0x19,
-0x89, 0x89, 0xf0, 0x23, 0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18,
-0xf8, 0x60, 0xf9, 0x61, 0x61, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x81, 0x42,
-0x16, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a,
-0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61,
-0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b,
-0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x7e, 0x80, 0x20, 0x1c, 0x00, 0xf0,
-0xbf, 0xfb, 0x0b, 0xe0, 0xb9, 0x68, 0x08, 0x1a, 0x00, 0x25, 0x78, 0x62,
-0xbd, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x3c, 0xfc, 0x20, 0x1c, 0x39, 0x1c,
-0x00, 0xf0, 0x64, 0xf8, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x0c, 0x2b, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0,
-0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x38, 0x6c, 0xf9, 0x6b, 0x0d, 0x18,
-0x21, 0x68, 0x41, 0x18, 0x00, 0x20, 0xa2, 0x69, 0x00, 0x2a, 0x0b, 0xd9,
-0x82, 0x00, 0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68,
-0xc0, 0x46, 0xab, 0x50, 0xa2, 0x69, 0x01, 0x30, 0x82, 0x42, 0xf3, 0xd8,
-0x78, 0x6e, 0xf9, 0x6b, 0x09, 0x18, 0x89, 0x89, 0xf0, 0x23, 0x19, 0x40,
-0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, 0x20, 0x68,
-0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 0x01, 0x68, 0x78, 0x6c,
-0xfc, 0xf7, 0x95, 0xff, 0x78, 0x64, 0x60, 0x68, 0x01, 0x04, 0x09, 0x0c,
-0xf8, 0x68, 0x81, 0x42, 0x19, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04,
-0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61,
-0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b,
-0x38, 0x1c, 0x00, 0xf0, 0x56, 0xfa, 0x01, 0x20, 0x78, 0x80, 0x20, 0x1c,
-0x00, 0xf0, 0x5e, 0xfb, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb9, 0x68,
-0x08, 0x1a, 0x78, 0x62, 0x00, 0x20, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0,
-0xd9, 0xfb, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x01, 0xf8, 0xef, 0xe7,
-0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, 0x8e, 0x48, 0x41, 0x69,
-0x01, 0x31, 0x41, 0x61, 0x03, 0x20, 0x00, 0x07, 0x61, 0x68, 0x08, 0x40,
-0x06, 0x0f, 0x0a, 0x04, 0x12, 0x0c, 0x20, 0x68, 0x11, 0x18, 0xfb, 0x68,
-0xd2, 0x1a, 0x7b, 0x68, 0x9d, 0x1a, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c,
-0x2a, 0x1c, 0x00, 0xf0, 0x26, 0xfa, 0x00, 0x20, 0x78, 0x80, 0x20, 0x1c,
-0x00, 0xf0, 0x2e, 0xfb, 0x60, 0x68, 0x40, 0x19, 0x01, 0x04, 0x09, 0x0c,
-0x60, 0x60, 0x30, 0x1c, 0x01, 0xf0, 0xe0, 0xfb, 0x7d, 0x4e, 0x0b, 0x23,
-0x1b, 0x02, 0xf0, 0x18, 0x00, 0x69, 0x00, 0x28, 0x19, 0xd0, 0x00, 0x25,
-0x2d, 0x23, 0x9b, 0x01, 0xf0, 0x18, 0xc0, 0x68, 0x00, 0x28, 0x12, 0xd0,
-0xaa, 0x00, 0x92, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0xd2, 0x68,
-0x20, 0x1c, 0x39, 0x1c, 0x01, 0xf0, 0x1c, 0xfe, 0x01, 0x35, 0xa8, 0x00,
-0x80, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0xc0, 0x68, 0x00, 0x28,
-0xec, 0xd1, 0xf8, 0x6b, 0x01, 0x1f, 0x8a, 0x1c, 0xfa, 0x63, 0xfa, 0x68,
-0x7d, 0x6c, 0x00, 0xf0, 0xbb, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c,
-0x28, 0x1c, 0xfc, 0xf7, 0x10, 0xff, 0x03, 0x90, 0xf9, 0x6b, 0x3a, 0x6e,
-0x8e, 0x18, 0x20, 0x68, 0x12, 0x18, 0x01, 0x92, 0x7a, 0x6e, 0x8d, 0x18,
-0x11, 0x18, 0x02, 0x91, 0xc8, 0x1d, 0x09, 0x30, 0xe0, 0x60, 0xb1, 0x88,
-0x08, 0x02, 0x09, 0x0a, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x00, 0x04,
-0x00, 0x0c, 0x78, 0x61, 0x68, 0x68, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04,
-0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40,
-0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x08, 0x43, 0x38, 0x61, 0xa8, 0x89,
-0x09, 0x23, 0x1b, 0x02, 0x18, 0x40, 0xb8, 0x61,
-0xa8, 0x89, 0x98, 0x43, 0xa8, 0x81, 0xa8, 0x89, 0x02, 0x99, 0xc0, 0x46,
-0x88, 0x81, 0x00, 0x20, 0x70, 0x80, 0xb0, 0x80, 0x70, 0x81, 0x68, 0x60,
-0x28, 0x82, 0xb9, 0x6e, 0x30, 0x1c, 0xfc, 0xf7, 0xe8, 0xfe, 0x38, 0x86,
-0xfa, 0x69, 0x30, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0x03, 0xff, 0x78, 0x86,
-0x3d, 0x8e, 0x78, 0x8e, 0x03, 0x99, 0xfc, 0xf7, 0xc8, 0xfe, 0x00, 0x90,
-0x60, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x39, 0x6e, 0x41, 0x1a, 0x09, 0x04,
-0x09, 0x0c, 0x7a, 0x6e, 0x82, 0x1a, 0x13, 0x04, 0x1b, 0x0c, 0x1a, 0x02,
-0x1b, 0x0a, 0x1a, 0x43, 0x16, 0x04, 0x36, 0x0c, 0xba, 0x68, 0x82, 0x42,
-0x01, 0xd2, 0x00, 0x20, 0x00, 0xe0, 0x10, 0x1a, 0xb8, 0x60, 0x08, 0x02,
-0x09, 0x12, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c,
-0x01, 0x98, 0xc0, 0x46, 0x41, 0x80, 0x28, 0x1c, 0xfc, 0xf7, 0xa3, 0xfe,
-0x05, 0x1c, 0x00, 0x98, 0x31, 0x1c, 0xfc, 0xf7, 0x9e, 0xfe, 0x06, 0x1c,
-0x78, 0x69, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x02, 0x00, 0x0a, 0x08, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x28, 0x1c,
-0xfc, 0xf7, 0x8f, 0xfe, 0x79, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x79, 0x61,
-0x01, 0x9a, 0xc0, 0x46, 0x50, 0x81, 0x38, 0x69, 0x01, 0x0e, 0xff, 0x22,
-0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02,
-0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 0x30, 0x1c,
-0xfc, 0xf7, 0x77, 0xfe, 0x39, 0x69, 0x7a, 0x68, 0x89, 0x18, 0x39, 0x61,
-0xb9, 0x68, 0x00, 0x29, 0x09, 0xd1, 0x02, 0x99, 0x89, 0x89, 0xba, 0x69,
-0x11, 0x43, 0x02, 0x9a, 0xc0, 0x46, 0x91, 0x81, 0xb9, 0x69, 0xfc, 0xf7,
-0x66, 0xfe, 0x20, 0x82, 0x00, 0x20, 0x60, 0x82, 0xf8, 0x6d, 0x41, 0x08,
-0x16, 0xd3, 0x80, 0x0a, 0x0a, 0xd3, 0x60, 0x68, 0x10, 0x38, 0x01, 0x04,
-0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 0xc0, 0x46,
-0x08, 0x82, 0x09, 0xe0, 0x60, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c,
-0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x88, 0x81,
-0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0xf1, 0xb5, 0x84, 0xb0, 0x6e, 0x4d, 0x28, 0x69,
-0x01, 0x22, 0x04, 0x99, 0x8a, 0x40, 0x90, 0x43, 0x28, 0x61, 0x04, 0x98,
-0x43, 0x01, 0x18, 0x1a, 0x80, 0x00, 0x16, 0x1c, 0x69, 0x49, 0x44, 0x18,
-0xe0, 0x6b, 0xc0, 0x46, 0x00, 0x90, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd1,
-0x00, 0x26, 0x26, 0xe0, 0x65, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61,
-0x04, 0x98, 0xfc, 0xf7, 0x09, 0xfd, 0x07, 0x1c, 0x03, 0xd1, 0x28, 0x69,
-0x30, 0x43, 0x28, 0x61, 0xb5, 0xe0, 0xa0, 0x68, 0x65, 0x68, 0xa8, 0x42,
-0x00, 0xd2, 0x05, 0x1c, 0xa1, 0x6c, 0xa9, 0x42, 0x16, 0xd2, 0x40, 0x1a,
-0x62, 0x6a, 0x10, 0x1a, 0x00, 0x26, 0x60, 0x62, 0xa6, 0x60, 0xa6, 0x62,
-0x20, 0x88, 0x48, 0x23, 0x18, 0x43, 0x20, 0x80, 0x0d, 0x1c, 0x09, 0xd1,
-0x38, 0x1c, 0xfc, 0xf7, 0x19, 0xfd, 0x03, 0x20, 0x60, 0x80, 0x66, 0x60,
-0x20, 0x1c, 0x00, 0xf0, 0x8d, 0xf9, 0x96, 0xe0, 0xe1, 0x68, 0x38, 0x68,
-0x09, 0x18, 0xc3, 0x1f, 0x05, 0x3b, 0x20, 0x1c, 0x02, 0x39, 0x2a, 0x1c,
-0x00, 0xf0, 0xcd, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0xd7, 0xf9, 0xe0, 0x68,
-0x46, 0x19, 0x78, 0x68, 0x30, 0x43, 0x78, 0x60, 0x04, 0x98, 0x31, 0x1c,
-0x01, 0xf0, 0x88, 0xfa, 0x21, 0x6e, 0x00, 0x98,
-0x08, 0x18, 0x01, 0x90, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x61, 0x6e,
-0x71, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 0x12, 0x0a, 0x11, 0x43,
-0x09, 0x04, 0x09, 0x0c, 0x02, 0x91, 0x01, 0x02, 0x00, 0x0a, 0x08, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 0x41, 0x80, 0x20, 0x8e,
-0xfc, 0xf7, 0xcb, 0xfd, 0x06, 0x1c, 0x60, 0x8e, 0x02, 0x99, 0xfc, 0xf7,
-0xc6, 0xfd, 0x03, 0x90, 0x60, 0x69, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02,
-0x09, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46,
-0x81, 0x80, 0x30, 0x1c, 0xfc, 0xf7, 0xb7, 0xfd, 0x61, 0x69, 0x01, 0x31,
-0xc0, 0x43, 0x61, 0x61, 0x01, 0x99, 0xc0, 0x46, 0x48, 0x81, 0x60, 0x6e,
-0x00, 0x99, 0x46, 0x18, 0x20, 0x69, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04,
-0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40,
-0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 0x71, 0x60, 0x03, 0x98,
-0xfc, 0xf7, 0x9b, 0xfd, 0x21, 0x69, 0x49, 0x19, 0x21, 0x61, 0xa1, 0x68,
-0x49, 0x1b, 0xa1, 0x60, 0x06, 0xd1, 0xb1, 0x89, 0xa2, 0x69, 0x11, 0x43,
-0xb1, 0x81, 0xa1, 0x69, 0xfc, 0xf7, 0x8d, 0xfd, 0x38, 0x82, 0x61, 0x6e,
-0x38, 0x68, 0x09, 0x18, 0x0e, 0x31, 0xf9, 0x60, 0xe2, 0x68, 0x00, 0x99,
-0x04, 0x38, 0x00, 0xf0, 0x4c, 0xf8, 0x02, 0x20, 0x78, 0x82, 0xe0, 0x6d,
-0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, 0x0a, 0xd3, 0x78, 0x68, 0x10, 0x38,
-0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x39, 0x68,
-0xc0, 0x46, 0xc8, 0x81, 0x09, 0xe0, 0x78, 0x68, 0x0c, 0x38, 0x01, 0x04,
-0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46,
-0x48, 0x81, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0xd0, 0x2c, 0x00, 0x80, 0x5c, 0x2b, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80,
-0xf7, 0xb5, 0x03, 0x1c, 0x0f, 0x1c, 0x00, 0x20, 0x1c, 0x68, 0x26, 0x04,
-0x31, 0x1c, 0x1d, 0x1d, 0xfc, 0xf7, 0x51, 0xfd, 0x40, 0xc7, 0x02, 0x9a,
-0xd1, 0x1c, 0x89, 0x08, 0x01, 0x39, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29,
-0x0d, 0xd0, 0x21, 0x0c, 0x10, 0xcd, 0x22, 0x04, 0x0a, 0x43, 0x11, 0x1c,
-0x16, 0x1c, 0xfc, 0xf7, 0x40, 0xfd, 0x40, 0xc7, 0x02, 0x99, 0x4a, 0x1e,
-0x02, 0x92, 0x00, 0x29, 0xf1, 0xd1, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x80, 0x08, 0x80, 0x00, 0x89, 0x08, 0x89, 0x00, 0x03, 0x32,
-0x93, 0x08, 0x5a, 0x1e, 0x00, 0x2b, 0x05, 0xd0, 0x08, 0xc9, 0x08, 0xc0,
-0x13, 0x1c, 0x01, 0x3a, 0x00, 0x2b, 0xf9, 0xd1, 0x70, 0x47, 0xff, 0xb5,
-0x86, 0xb0, 0x17, 0x1c, 0x00, 0x26, 0x06, 0x98, 0x80, 0x6c, 0xc0, 0x1b,
-0x06, 0x99, 0xc0, 0x46, 0x88, 0x64, 0x01, 0x20, 0xc0, 0x05, 0x06, 0x99,
-0x89, 0x6b, 0xc0, 0x46, 0x01, 0x91, 0x06, 0x99, 0x4c, 0x6b, 0x67, 0xe0,
-0x21, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x61, 0x68, 0xc0, 0x46, 0x03, 0x91,
-0xa1, 0x68, 0xc0, 0x46, 0x04, 0x91, 0x02, 0xa9, 0x49, 0x88, 0xb9, 0x42,
-0x08, 0xd2, 0x02, 0xad, 0x6d, 0x88, 0x02, 0xa9, 0x49, 0x88, 0x7f, 0x1a,
-0x00, 0x21, 0x02, 0xab, 0x59, 0x80, 0x19, 0xe0, 0x02, 0xa9, 0x49, 0x88,
-0xc9, 0x1b, 0x02, 0xab, 0x59, 0x80, 0x3d, 0x1c, 0x00, 0x27, 0x01, 0x21,
-0x49, 0x06, 0x07, 0x9b, 0x9a, 0x07, 0x92, 0x0f, 0x0d, 0xd0, 0xeb, 0x06,
-0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b, 0x08, 0xd3, 0x1e, 0x2b, 0x02, 0xd1,
-0x03, 0x2a, 0x04, 0xd1, 0x01, 0xe0, 0x02, 0x2a,
-0x01, 0xd3, 0x01, 0x26, 0x00, 0x21, 0x29, 0x43, 0x01, 0x43, 0x0a, 0x1c,
-0x00, 0x91, 0x00, 0x20, 0x03, 0x99, 0x04, 0x9a, 0x07, 0x9b, 0x01, 0xf0,
-0x5b, 0xff, 0x07, 0x99, 0x49, 0x19, 0x07, 0x91, 0x00, 0x2e, 0x0a, 0xd0,
-0x1d, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x1d, 0x48, 0x01, 0x6d, 0x42, 0x6d,
-0x00, 0x20, 0x07, 0x9b, 0x01, 0xf0, 0x4c, 0xff, 0x00, 0x26, 0x02, 0xa8,
-0x40, 0x88, 0x00, 0x28, 0x0c, 0xd0, 0x03, 0x98, 0x40, 0x19, 0x03, 0x90,
-0x02, 0x98, 0xc0, 0x46, 0x20, 0x60, 0x03, 0x98, 0xc0, 0x46, 0x60, 0x60,
-0x04, 0x98, 0xc0, 0x46, 0xa0, 0x60, 0x03, 0xe0, 0x01, 0x98, 0x01, 0x38,
-0x01, 0x90, 0x10, 0x34, 0x06, 0x98, 0xc0, 0x46, 0x44, 0x63, 0x01, 0x98,
-0x06, 0x99, 0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 0x00, 0x2f, 0x02, 0xd0,
-0x01, 0x99, 0x00, 0x29, 0x92, 0xd1, 0x09, 0x4a, 0xc0, 0x46, 0x00, 0x92,
-0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x09, 0x9b, 0x01, 0xf0,
-0x1f, 0xff, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x01, 0x00, 0x00, 0x02, 0x7c, 0x29, 0x00, 0x80, 0x04, 0x00, 0x53, 0x02,
-0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, 0x38, 0x68, 0x01, 0x23, 0x9b, 0x07,
-0x08, 0x38, 0x18, 0x43, 0x01, 0x68, 0x38, 0x8a, 0xfc, 0xf7, 0x85, 0xfc,
-0xc0, 0x43, 0xf9, 0x68, 0xc0, 0x46, 0x08, 0x80, 0x78, 0x8a, 0x39, 0x68,
-0x08, 0x1a, 0x38, 0x60, 0x38, 0x1c, 0x01, 0xf0, 0x8b, 0xf9, 0x38, 0x1c,
-0xfc, 0xf7, 0x8c, 0xfb, 0x20, 0x1c, 0xff, 0xf7, 0x33, 0xfe, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x01, 0x88, 0x8a, 0x09, 0x21, 0xd3,
-0xca, 0x09, 0x1f, 0xd2, 0x8a, 0x08, 0x1d, 0xd3, 0x00, 0x21, 0x01, 0x80,
-0x41, 0x80, 0x47, 0x6f, 0x40, 0x6d, 0xfa, 0x1d, 0x19, 0x32, 0x51, 0x71,
-0xfa, 0x6d, 0xc0, 0x46, 0x10, 0x60, 0x3a, 0x6e, 0xc0, 0x46, 0x10, 0x60,
-0x0c, 0x48, 0xc0, 0x46, 0x81, 0x63, 0xc1, 0x6b, 0x49, 0x08, 0x49, 0x00,
-0xc1, 0x63, 0x01, 0x20, 0x00, 0xf0, 0xcc, 0xff, 0x38, 0x1c, 0x00, 0xf0,
-0x6b, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0x19, 0x43,
-0x01, 0x80, 0x01, 0x88, 0x49, 0x09, 0xf6, 0xd2, 0x00, 0xf0, 0xb0, 0xf8,
-0xf3, 0xe7, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c,
-0x10, 0x1c, 0x0d, 0x1c, 0x00, 0x24, 0x5e, 0x1e, 0x00, 0x2b, 0x19, 0xd0,
-0x01, 0x68, 0xc0, 0x46, 0x39, 0x60, 0x41, 0x88, 0x0c, 0x19, 0x41, 0x68,
-0xc0, 0x46, 0x79, 0x60, 0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0xc1, 0x68,
-0xc0, 0x46, 0xf9, 0x60, 0x10, 0x30, 0x10, 0x37, 0xe9, 0x6a, 0x81, 0x42,
-0x02, 0xd8, 0x28, 0x1c, 0x00, 0xf0, 0xec, 0xff, 0x31, 0x1c, 0x01, 0x3e,
-0x00, 0x29, 0xe5, 0xd1, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x0a, 0x68, 0x00, 0x2a, 0x01, 0xd1,
-0x08, 0x60, 0x02, 0xe0, 0x4a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x48, 0x60,
-0x70, 0x47, 0x00, 0x00, 0xd0, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x08, 0x68,
-0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 0x0a, 0x60, 0x70, 0x47,
-0xd0, 0x2c, 0x00, 0x80, 0x00, 0x21, 0x81, 0x67, 0x05, 0x49, 0x8a, 0x68,
-0x00, 0x2a, 0x01, 0xd1, 0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46,
-0x90, 0x67, 0xc8, 0x60, 0x70, 0x47, 0x00, 0x00, 0xd0, 0x2c, 0x00, 0x80,
-0x03, 0x49, 0x88, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x82, 0x6f, 0xc0, 0x46,
-0x8a, 0x60, 0x70, 0x47, 0xd0, 0x2c, 0x00, 0x80,
-0x00, 0xb5, 0x80, 0x20, 0x13, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xff, 0xf7,
-0xd5, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x03, 0x23, 0x1b, 0x07, 0x41, 0x68,
-0x19, 0x40, 0x0a, 0x0f, 0x51, 0x01, 0x89, 0x1a, 0x89, 0x00, 0x0d, 0x4b,
-0xc9, 0x18, 0x4b, 0x88, 0x00, 0x2b, 0x04, 0xd1, 0x11, 0x1c, 0xff, 0xf7,
-0x3b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x2b, 0x02, 0xd1, 0xff, 0xf7,
-0x05, 0xfc, 0xf8, 0xe7, 0x02, 0x2b, 0xf6, 0xd1, 0xff, 0xf7, 0x4e, 0xfb,
-0xf3, 0xe7, 0x04, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 0xee, 0xe7,
-0x00, 0x00, 0x00, 0xb0, 0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40,
-0x00, 0xb5, 0x20, 0x20, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xff, 0xf7,
-0xbf, 0xff, 0x00, 0x28, 0x0e, 0xd0, 0x01, 0x88, 0x20, 0x23, 0x19, 0x43,
-0x01, 0x80, 0x01, 0x88, 0x10, 0x23, 0x99, 0x43, 0x01, 0x80, 0x01, 0x88,
-0x09, 0x0a, 0x01, 0xd3, 0xff, 0xf7, 0x2e, 0xff, 0x08, 0xbc, 0x18, 0x47,
-0x03, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 0xf8, 0xe7, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xb0, 0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x07, 0x1c,
-0x22, 0x48, 0xc0, 0x46, 0x00, 0x90, 0x22, 0x48, 0xc3, 0x1d, 0x41, 0x33,
-0x41, 0x6d, 0x82, 0x6d, 0x80, 0x6c, 0x00, 0x03, 0x00, 0x0b, 0x9c, 0x68,
-0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x98, 0x42, 0x00, 0xd1,
-0x0c, 0xe0, 0x98, 0x42, 0x03, 0xd9, 0x10, 0x1a, 0x59, 0x1a, 0x41, 0x18,
-0x00, 0xe0, 0x19, 0x1a, 0x01, 0x20, 0x10, 0x29, 0x00, 0xd8, 0x00, 0x20,
-0x00, 0x28, 0x1f, 0xd0, 0x78, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x08, 0x60,
-0xb8, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x48, 0x60, 0x10, 0x4a, 0xc0, 0x46,
-0x00, 0x92, 0xfb, 0x6a, 0x0f, 0x48, 0x42, 0x6d, 0x03, 0x20, 0x39, 0x6a,
-0x01, 0xf0, 0xe2, 0xfd, 0x38, 0x88, 0x10, 0x23, 0x18, 0x43, 0x38, 0x80,
-0x38, 0x88, 0x40, 0x23, 0x98, 0x43, 0x38, 0x80, 0x38, 0x1c, 0xff, 0xf7,
-0x55, 0xff, 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x88, 0x40, 0x23,
-0x18, 0x43, 0x38, 0x80, 0xf7, 0xe7, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55,
-0xa8, 0x03, 0x00, 0x80, 0x08, 0x00, 0x11, 0x02, 0x7c, 0x29, 0x00, 0x80,
-0xb0, 0xb5, 0x40, 0x20, 0x2c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0,
-0xfd, 0xfe, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40,
-0x05, 0x0f, 0x68, 0x01, 0x40, 0x1b, 0x80, 0x00, 0x26, 0x49, 0x44, 0x18,
-0x20, 0x88, 0x02, 0x23, 0x18, 0x43, 0x20, 0x80, 0x20, 0x88, 0x41, 0x08,
-0x34, 0xd3, 0x40, 0x08, 0x40, 0x00, 0x20, 0x80, 0xa0, 0x6c, 0xe1, 0x6c,
-0x40, 0x18, 0xa0, 0x64, 0x00, 0x20, 0xe0, 0x64, 0xa1, 0x6b, 0x22, 0x6d,
-0x89, 0x18, 0xa1, 0x63, 0x20, 0x65, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65,
-0x03, 0x23, 0x1b, 0x07, 0x78, 0x68, 0x18, 0x40, 0x78, 0x60, 0x61, 0x68,
-0x36, 0x31, 0x94, 0x29, 0x04, 0xd8, 0x38, 0x23, 0x18, 0x43, 0x78, 0x60,
-0x38, 0x20, 0x03, 0xe0, 0x94, 0x23, 0x18, 0x43, 0x78, 0x60, 0x94, 0x20,
-0xb8, 0x61, 0x39, 0x68, 0x78, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x20, 0x1c,
-0xcb, 0x1f, 0x05, 0x3b, 0xff, 0xf7, 0xd7, 0xfd, 0x02, 0x20, 0x60, 0x80,
-0x38, 0x1c, 0xff, 0xf7, 0xdf, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x38, 0x1c, 0xfc, 0xf7, 0x07, 0xfa, 0x28, 0x01, 0x06, 0x49, 0x40, 0x18,
-0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63,
-0xef, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0,
-0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80, 0x90, 0xb5, 0x00, 0x27,
-0x0f, 0x4c, 0x0d, 0xe0, 0x42, 0x6b, 0x01, 0x3a, 0x42, 0x63, 0x00, 0x2a,
-0x05, 0xdc, 0x02, 0x6b, 0xc0, 0x46, 0x42, 0x63, 0xc0, 0x6a, 0x01, 0xf0,
-0xc6, 0xf9, 0x01, 0x37, 0x0b, 0x2f, 0x07, 0xd2, 0x38, 0x01, 0x00, 0x19,
-0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x6a, 0x00, 0x29, 0xe9, 0xd1,
-0x01, 0x20, 0x40, 0x06, 0x03, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0,
-0x10, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 0x0f, 0x49, 0xc8, 0x68,
-0x01, 0x28, 0x17, 0xd1, 0xc8, 0x1d, 0x79, 0x30, 0x02, 0x89, 0x00, 0x2a,
-0x12, 0xd0, 0x01, 0x3a, 0x02, 0x81, 0x02, 0x89, 0x00, 0x2a, 0x0d, 0xd1,
-0x42, 0x89, 0x00, 0x2a, 0x08, 0xd1, 0xc9, 0x6f, 0x02, 0x23, 0x0a, 0x68,
-0x1a, 0x43, 0x0a, 0x60, 0x04, 0x21, 0x01, 0x81, 0x01, 0x21, 0x00, 0xe0,
-0x00, 0x21, 0x41, 0x81, 0x70, 0x47, 0x00, 0x00, 0x08, 0x83, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 0x01, 0x23, 0xf8, 0x1d,
-0x69, 0x30, 0x03, 0x73, 0x1e, 0x48, 0xc2, 0x1d, 0x79, 0x32, 0x54, 0x8a,
-0x61, 0x1c, 0x51, 0x82, 0xd5, 0x8a, 0x00, 0x21, 0xac, 0x42, 0x04, 0xdb,
-0xc4, 0x1d, 0x89, 0x34, 0x63, 0x70, 0x51, 0x82, 0xd1, 0x83, 0x01, 0x23,
-0x9b, 0x07, 0x3a, 0x6d, 0x1a, 0x43, 0x12, 0x68, 0xc0, 0x46, 0xba, 0x61,
-0xfb, 0x69, 0x9a, 0x42, 0x06, 0xd1, 0xf8, 0x6c, 0x12, 0x49, 0xc0, 0x46,
-0x08, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x79, 0x61, 0x41, 0x69,
-0xfa, 0x6c, 0x91, 0x43, 0x41, 0x61, 0x01, 0x20, 0x00, 0x05, 0xc1, 0x60,
-0x38, 0x69, 0x02, 0x28, 0xf1, 0xd0, 0xb8, 0x69, 0xf9, 0x69, 0x41, 0x1a,
-0x01, 0xd5, 0x78, 0x6d, 0x41, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8,
-0xf9, 0x69, 0x09, 0x18, 0xf9, 0x61, 0x78, 0x6d, 0x81, 0x42, 0xe2, 0xd3,
-0x08, 0x1a, 0xf8, 0x61, 0xdf, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x00, 0x00, 0x00, 0xb0, 0xf8, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0xff, 0x23,
-0x21, 0x33, 0x9f, 0x42, 0x01, 0xd9, 0xff, 0x27, 0x21, 0x37, 0xe1, 0x6e,
-0x38, 0x1c, 0x01, 0xf0, 0xcb, 0xfc, 0x2d, 0x4d, 0x00, 0x28, 0x13, 0xd1,
-0xe0, 0x1d, 0x49, 0x30, 0x01, 0x7a, 0x01, 0x23, 0x19, 0x43, 0x01, 0x72,
-0x29, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x29, 0x48, 0x01, 0x6d, 0x42, 0x6d,
-0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0xb0, 0xfc, 0x00, 0x20, 0xf8, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x20, 0x69, 0x01, 0x30, 0x20, 0x61, 0x23, 0x49,
-0xc8, 0x1d, 0xb9, 0x30, 0x02, 0x6b, 0x92, 0x00, 0x51, 0x18, 0xc0, 0x31,
-0x0f, 0x61, 0x01, 0x6b, 0x01, 0x31, 0x89, 0x07, 0x89, 0x0f, 0x01, 0x63,
-0x20, 0x6b, 0xc2, 0x19, 0x61, 0x6d, 0x8a, 0x42, 0x03, 0xd8, 0x23, 0x22,
-0x12, 0x05, 0x3a, 0x43, 0x05, 0xe0, 0x09, 0x1a, 0x7e, 0x1a, 0x07, 0xd1,
-0x23, 0x22, 0x12, 0x05, 0x0a, 0x43, 0x00, 0x92, 0x61, 0x6e, 0x09, 0x18,
-0xa2, 0x6e, 0x10, 0xe0, 0x11, 0x22, 0x52, 0x05, 0x0a, 0x43, 0x00, 0x92,
-0x61, 0x6e, 0x09, 0x18, 0x00, 0x20, 0xa2, 0x6e, 0x2b, 0x1c, 0x01, 0xf0,
-0x7d, 0xfc, 0x23, 0x22, 0x12, 0x05, 0x32, 0x43, 0x00, 0x92, 0x61, 0x6e,
-0xa2, 0x6e, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0x73, 0xfc, 0x20, 0x6b,
-0xc0, 0x19, 0x00, 0x09, 0x00, 0x01, 0x61, 0x6d, 0x81, 0x42, 0x00, 0xd8,
-0x40, 0x1a, 0x20, 0x63, 0x38, 0x1c, 0xb8, 0xe7,
-0x44, 0x80, 0x20, 0x40, 0x04, 0x00, 0x1b, 0x02, 0x7c, 0x29, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x01, 0x20, 0xc0, 0x03, 0x0d, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0x0c, 0x49, 0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a,
-0x00, 0x27, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7,
-0x37, 0xff, 0x08, 0x49, 0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x2a,
-0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7, 0x2d, 0xff, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x64, 0x2d, 0x00, 0x80,
-0xe4, 0x2c, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, 0x10, 0x20, 0x18, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x16, 0x48,
-0xc4, 0x1d, 0xb9, 0x34, 0x61, 0x6b, 0x89, 0x00, 0x09, 0x18, 0xc0, 0x31,
-0x09, 0x69, 0x7a, 0x68, 0x92, 0x00, 0xd2, 0x19, 0x51, 0x64, 0x61, 0x6b,
-0x89, 0x00, 0x08, 0x18, 0xc0, 0x30, 0x01, 0x69, 0x78, 0x68, 0x80, 0x00,
-0xc0, 0x19, 0xc0, 0x6b, 0x01, 0xf0, 0xa2, 0xfa, 0x01, 0x23, 0x78, 0x68,
-0x58, 0x40, 0x78, 0x60, 0x60, 0x6b, 0x01, 0x30, 0x80, 0x07, 0x80, 0x0f,
-0x60, 0x63, 0xf8, 0x1d, 0x19, 0x30, 0x40, 0x79, 0x00, 0x28, 0x02, 0xd1,
-0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c,
-0x39, 0x48, 0xc0, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xb8, 0x6a, 0xc0, 0x68,
-0x80, 0x09, 0x01, 0xd3, 0x02, 0x20, 0x00, 0xe0, 0x78, 0x6f, 0xfc, 0xf7,
-0x59, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x01, 0x20, 0xf9, 0x1d, 0x19, 0x31,
-0x08, 0x71, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0x6c, 0x2f, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0xba, 0x6a, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0,
-0x59, 0xf8, 0x67, 0x62, 0x00, 0x28, 0x03, 0xd1, 0x20, 0x1c, 0x00, 0xf0,
-0x0b, 0xfd, 0xec, 0xe7, 0xf9, 0x6d, 0x09, 0x68, 0x09, 0x18, 0x09, 0x09,
-0x09, 0x01, 0x7a, 0x6d, 0x8a, 0x42, 0x00, 0xd8, 0x89, 0x1a, 0xa1, 0x62,
-0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x4a, 0x6c, 0x00, 0x2a, 0x07, 0xd0,
-0x4a, 0x6c, 0x12, 0x1a, 0x4a, 0x64, 0x80, 0x08, 0x80, 0x00, 0xb9, 0x6a,
-0x08, 0x18, 0xb8, 0x62, 0x38, 0x68, 0xb9, 0x6a, 0x80, 0x00, 0xc0, 0x19,
-0x42, 0x6b, 0x91, 0x42, 0x0e, 0xd3, 0x00, 0x21, 0x41, 0x64, 0xb8, 0x6a,
-0x39, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x49, 0x6b, 0x40, 0x1a, 0xb8, 0x62,
-0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0xc9, 0x6b, 0x40, 0x18, 0xb8, 0x62,
-0xb8, 0x68, 0x81, 0x00, 0xc9, 0x19, 0x49, 0x6c, 0x00, 0x29, 0xb8, 0xd1,
-0xb9, 0x6a, 0xfa, 0x6b, 0x91, 0x42, 0xb4, 0xd0, 0x3a, 0x6c, 0x91, 0x42,
-0xb1, 0xd0, 0x01, 0x23, 0x58, 0x40, 0xb8, 0x60, 0x80, 0x00, 0xc0, 0x19,
-0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf8, 0x68, 0x00, 0x28, 0x01, 0xd0,
-0x01, 0x38, 0xf8, 0x60, 0x38, 0x69, 0x00, 0x28, 0xa1, 0xd0, 0x01, 0x38,
-0x38, 0x61, 0x9e, 0xe7, 0x68, 0x19, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0,
-0xf7, 0xb5, 0x90, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x00, 0x20, 0x05, 0x90,
-0x02, 0x90, 0x00, 0x22, 0x01, 0x92, 0xf9, 0x48, 0xc0, 0x6a, 0xc0, 0x46,
-0xa8, 0x61, 0xa0, 0x68, 0x81, 0x00, 0x09, 0x19, 0x49, 0x6b, 0xc0, 0x46,
-0x20, 0x60, 0xe1, 0x62, 0x12, 0x9a, 0xd0, 0x68, 0xc0, 0x46, 0xa8, 0x60,
-0x12, 0x9a, 0x51, 0x78, 0xc0, 0x46, 0x0c, 0x91, 0xf0, 0x48, 0xc0, 0x46,
-0x03, 0x90, 0xd7, 0x1d, 0x09, 0x37, 0xe0, 0x6a,
-0xc1, 0x1b, 0x09, 0x09, 0xe3, 0x1d, 0x19, 0x33, 0x0c, 0x9a, 0xc0, 0x46,
-0x0f, 0x93, 0xeb, 0x4b, 0xc0, 0x46, 0x0e, 0x93, 0x91, 0x42, 0x01, 0xd3,
-0xb8, 0x42, 0x21, 0xd8, 0xe1, 0x68, 0x02, 0x29, 0x1e, 0xd2, 0x01, 0x20,
-0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x00, 0x20, 0x03, 0x99, 0x01, 0xf0,
-0x57, 0xfb, 0x00, 0x28, 0x03, 0xd1, 0x0e, 0x9b, 0xd8, 0x6b, 0x01, 0x30,
-0xd8, 0x63, 0x01, 0x20, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61,
-0xdd, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xdd, 0x48, 0x01, 0x6d, 0x42, 0x6d,
-0xdc, 0x4b, 0x00, 0x20, 0x01, 0xf0, 0x3a, 0xfb, 0x38, 0x1c, 0x5c, 0xe3,
-0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x7b, 0xfc, 0x07, 0x1c,
-0xd7, 0x48, 0xc0, 0x68, 0x00, 0x28, 0x64, 0xd0, 0x38, 0x78, 0x40, 0x07,
-0x40, 0x0f, 0x03, 0x28, 0x60, 0xd1, 0x05, 0x98, 0x01, 0x30, 0x00, 0x06,
-0x00, 0x0e, 0x05, 0x90, 0x38, 0x78, 0xf0, 0x23, 0x18, 0x40, 0x58, 0xd1,
-0xe0, 0x6a, 0xc0, 0x1b, 0x00, 0x09, 0x0c, 0x99, 0x88, 0x42, 0x02, 0xd2,
-0xe0, 0x68, 0x02, 0x28, 0x05, 0xd3, 0xcb, 0x49, 0x88, 0x68, 0x00, 0xf0,
-0x83, 0xff, 0x06, 0x1c, 0x06, 0xd1, 0x03, 0x9b, 0x28, 0x1c, 0x39, 0x1c,
-0x22, 0x1c, 0x00, 0xf0, 0x8b, 0xfc, 0x16, 0xe1, 0x2e, 0x62, 0xf8, 0x68,
-0x00, 0x28, 0x0d, 0xd0, 0xb8, 0x89, 0x00, 0x28, 0x03, 0xd0, 0xc1, 0x49,
-0xc9, 0x68, 0x00, 0xf0, 0x70, 0xff, 0xf8, 0x89, 0x00, 0x28, 0x03, 0xd0,
-0xbd, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x69, 0xff, 0x7a, 0x68, 0xc0, 0x46,
-0x72, 0x61, 0xb9, 0x68, 0xc0, 0x46, 0xb1, 0x61, 0x30, 0x1c, 0xb8, 0x49,
-0x09, 0x68, 0x00, 0xf0, 0x5e, 0xff, 0x00, 0x28, 0x17, 0xd1, 0x30, 0x1c,
-0xb4, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x57, 0xff, 0x10, 0x37, 0xe0, 0x6a,
-0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x27, 0xfc, 0x07, 0x1c,
-0x68, 0x68, 0xaf, 0x4b, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61,
-0xac, 0x23, 0xa8, 0x68, 0x98, 0x43, 0xa8, 0x60, 0xb0, 0xe0, 0xa8, 0x69,
-0xa8, 0x28, 0x01, 0xd2, 0xa8, 0x20, 0xa8, 0x61, 0x10, 0x37, 0xe0, 0x6a,
-0xb8, 0x42, 0x6c, 0xd8, 0x9c, 0xe0, 0xa5, 0xe0, 0xa4, 0xe0, 0x10, 0x28,
-0x68, 0xd1, 0x03, 0x23, 0x1b, 0x07, 0x68, 0x68, 0x18, 0x40, 0x01, 0x0f,
-0x48, 0x01, 0x40, 0x1a, 0x80, 0x00, 0xa0, 0x4a, 0x82, 0x18, 0x01, 0x92,
-0x78, 0x88, 0x42, 0x0b, 0x31, 0xd3, 0x82, 0x0b, 0x2f, 0xd3, 0x9d, 0x48,
-0xc0, 0x46, 0x03, 0x90, 0x02, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x10, 0x80,
-0x78, 0x88, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60,
-0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a,
-0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64,
-0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x8f, 0x49, 0x40, 0x18,
-0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x01, 0x9a, 0x50, 0x68, 0x36, 0x30,
-0x94, 0x28, 0x01, 0xd8, 0x38, 0x20, 0x00, 0xe0, 0x94, 0x20, 0xa8, 0x61,
-0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x28, 0xd8, 0x58, 0xe0, 0x7a, 0x88,
-0x92, 0x0b, 0x03, 0xd3, 0x85, 0x48, 0xc0, 0x46, 0x03, 0x90, 0x23, 0xe0,
-0x01, 0x22, 0x12, 0x03, 0x02, 0x40, 0x83, 0x4b, 0x1d, 0xd0, 0x03, 0x93,
-0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, 0xb8, 0x68,
-0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, 0xc0, 0x46,
-0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46,
-0x90, 0x64, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x75, 0x49,
-0x40, 0x18, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x02, 0xe0, 0x33, 0xe0,
-0x2a, 0xe0, 0x03, 0x93, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71,
-0x12, 0x9a, 0x50, 0x78, 0x05, 0x99, 0x43, 0x1a, 0x0b, 0x93, 0x10, 0x37,
-0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x92, 0xfb,
-0x07, 0x1c, 0x01, 0x9a, 0x50, 0x6b, 0x91, 0x6b, 0x09, 0x01, 0x40, 0x18,
-0x0b, 0x9b, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, 0x7d, 0xfb, 0x01, 0x9a,
-0xc0, 0x46, 0xd0, 0x64, 0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x13, 0x65,
-0x01, 0x23, 0x5b, 0x06, 0x68, 0x68, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20,
-0xa8, 0x61, 0x0d, 0xe0, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8,
-0x20, 0x1c, 0x00, 0xf0, 0x71, 0xfb, 0x07, 0x1c, 0x38, 0x78, 0x40, 0x07,
-0x40, 0x0f, 0x03, 0x28, 0x00, 0xd1, 0xf8, 0xe6, 0xa8, 0x69, 0x03, 0x99,
-0x01, 0xf0, 0x26, 0xfa, 0x00, 0x28, 0x2a, 0xd1, 0x38, 0x1c, 0x21, 0x1c,
-0x00, 0xf0, 0x79, 0xfb, 0xa8, 0x68, 0x80, 0x09, 0x04, 0xd3, 0x30, 0x1c,
-0x49, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x81, 0xfe, 0x41, 0x49, 0x00, 0x20,
-0x01, 0xf0, 0x14, 0xfa, 0x00, 0x28, 0x04, 0xd1, 0x0e, 0x9b, 0xd8, 0x6b,
-0x01, 0x30, 0xd8, 0x63, 0x11, 0xe0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46,
-0x48, 0x71, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0x3a, 0x4a,
-0xc0, 0x46, 0x00, 0x92, 0x39, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x39, 0x4b,
-0x00, 0x20, 0x01, 0xf0, 0xf3, 0xf9, 0x00, 0x20, 0x15, 0xe2, 0x05, 0x98,
-0x0c, 0x99, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x0c, 0x90, 0x0b, 0x90,
-0x0c, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46,
-0x48, 0x71, 0x28, 0x68, 0xc0, 0x46, 0x04, 0x90, 0x00, 0x26, 0x00, 0x20,
-0x08, 0x90, 0x00, 0x22, 0x0a, 0x92, 0x0c, 0x98, 0x01, 0x38, 0x0d, 0x90,
-0xa3, 0xe0, 0x78, 0x88, 0x8a, 0x1b, 0x12, 0x04, 0x12, 0x0c, 0x90, 0x42,
-0x05, 0xdd, 0x07, 0x92, 0x80, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x90,
-0x00, 0xe0, 0x07, 0x90, 0x08, 0x98, 0x00, 0x28, 0x07, 0xd1, 0x0d, 0x98,
-0x0a, 0x9a, 0x90, 0x42, 0x07, 0xdd, 0x07, 0x98, 0x30, 0x18, 0x88, 0x42,
-0x03, 0xd8, 0x01, 0x20, 0x40, 0x05, 0x06, 0x90, 0x1c, 0xe0, 0x11, 0x20,
-0x40, 0x05, 0x06, 0x90, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd1,
-0x20, 0x48, 0xc0, 0x46, 0x06, 0x90, 0xb1, 0x07, 0x89, 0x0f, 0x0f, 0xd0,
-0x07, 0x98, 0xc0, 0x06, 0xc0, 0x0e, 0x08, 0xd0, 0x1e, 0x28, 0x09, 0xdb,
-0x1e, 0x28, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, 0x02, 0x29,
-0x02, 0xd3, 0x01, 0x20, 0x02, 0x90, 0xde, 0xe7, 0x0a, 0x9a, 0x00, 0x2a,
-0x04, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x06, 0x98, 0x18, 0x43, 0x06, 0x90,
-0x07, 0x98, 0x06, 0x99, 0x08, 0x43, 0x02, 0x1c, 0x00, 0x90, 0x04, 0x98,
-0x83, 0x19, 0x1d, 0xe0, 0xe8, 0x0e, 0x00, 0x80, 0x01, 0x49, 0xff, 0xff,
-0x28, 0x0f, 0x00, 0x80, 0x04, 0x00, 0x12, 0x02, 0x7c, 0x29, 0x00, 0x80,
-0x44, 0x80, 0x20, 0x40, 0x68, 0x19, 0x00, 0x80, 0x60, 0x04, 0x00, 0x80,
-0x00, 0x00, 0x00, 0x80, 0x5c, 0x2b, 0x00, 0x80, 0x55, 0x32, 0xff, 0xff,
-0xac, 0x5e, 0x21, 0x40, 0x0d, 0x3d, 0xff, 0xff, 0xcd, 0x31, 0xff, 0xff,
-0x00, 0x00, 0x32, 0x02, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0,
-0x6b, 0xf9, 0x07, 0x98, 0x36, 0x18, 0x02, 0x98,
-0x00, 0x28, 0x16, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x04, 0xd1,
-0x09, 0x23, 0x5b, 0x04, 0x06, 0x98, 0x18, 0x43, 0x06, 0x90, 0x06, 0x98,
-0xc2, 0x4a, 0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0xc1, 0x48,
-0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0x51, 0xf9, 0x00, 0x20,
-0x02, 0x90, 0x08, 0x98, 0x00, 0x28, 0x0b, 0xd1, 0x0b, 0x9b, 0x01, 0x3b,
-0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x0c, 0xd8, 0x20, 0x1c,
-0x00, 0xf0, 0x8a, 0xfa, 0x07, 0x1c, 0x07, 0xe0, 0x78, 0x68, 0x07, 0x9a,
-0x80, 0x18, 0x78, 0x60, 0x78, 0x88, 0x07, 0x9a, 0x80, 0x1a, 0x78, 0x80,
-0x0a, 0x9a, 0x50, 0x1c, 0x02, 0x04, 0x12, 0x0c, 0x0a, 0x92, 0x0c, 0x98,
-0x0a, 0x9a, 0x82, 0x42, 0x03, 0xda, 0xa9, 0x69, 0xb1, 0x42, 0x00, 0xd9,
-0x53, 0xe7, 0xa8, 0x69, 0xb0, 0x42, 0x6b, 0xd1, 0xa8, 0x68, 0x01, 0x09,
-0x69, 0xd2, 0x08, 0x9a, 0x00, 0x2a, 0x56, 0xd0, 0x0c, 0x99, 0x0a, 0x9a,
-0x8a, 0x42, 0x3e, 0xdb, 0xb1, 0x07, 0x89, 0x0f, 0x0c, 0xd0, 0x08, 0x9a,
-0xd2, 0x06, 0xd2, 0x0e, 0x0b, 0xd0, 0x1e, 0x2a, 0x06, 0xdb, 0x1e, 0x2a,
-0x02, 0xd1, 0x03, 0x29, 0x05, 0xd0, 0x01, 0xe0, 0x02, 0x29, 0x02, 0xd2,
-0x02, 0x99, 0x00, 0x29, 0x21, 0xd0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92,
-0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0,
-0x01, 0xf9, 0x08, 0x98, 0x36, 0x18, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40,
-0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x92, 0x48, 0x01, 0x22,
-0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x8e, 0x48, 0x01, 0x6d,
-0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0xec, 0xf8, 0x00, 0x20, 0x02, 0x90,
-0x15, 0xe0, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 0x40, 0x06,
-0x00, 0xe0, 0x88, 0x48, 0x08, 0x9a, 0x02, 0x43, 0x00, 0xe0, 0x08, 0x9a,
-0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d,
-0x06, 0xca, 0x01, 0xf0, 0xd5, 0xf8, 0x08, 0x98, 0x36, 0x18, 0x10, 0x37,
-0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x14, 0xfa,
-0x07, 0x1c, 0x68, 0x68, 0x80, 0x0e, 0x6b, 0xd2, 0x0a, 0x98, 0xc0, 0x46,
-0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 0x5c, 0xda, 0x0d, 0x98, 0x09, 0x99,
-0x88, 0x42, 0x03, 0xd0, 0x7a, 0x88, 0x1e, 0xe0, 0x5f, 0xe0, 0x5e, 0xe0,
-0x78, 0x88, 0x01, 0x22, 0x52, 0x06, 0x02, 0x43, 0xa9, 0x68, 0x8c, 0x23,
-0x19, 0x40, 0x02, 0xd1, 0x09, 0x23, 0x5b, 0x04, 0x1a, 0x43, 0xb1, 0x07,
-0x89, 0x0f, 0x0e, 0xd0, 0xc3, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b,
-0x09, 0xdb, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0,
-0x02, 0x29, 0x02, 0xd3, 0x01, 0x21, 0x02, 0x91, 0x02, 0x1c, 0x09, 0x98,
-0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x1a, 0x43, 0x00, 0x92,
-0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0,
-0x8f, 0xf8, 0x78, 0x88, 0x86, 0x19, 0x10, 0x37, 0x02, 0x98, 0x00, 0x28,
-0x14, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20,
-0x40, 0x06, 0x00, 0xe0, 0x57, 0x48, 0x01, 0x22, 0x02, 0x43, 0x00, 0x92,
-0x04, 0x98, 0x83, 0x19, 0x53, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20,
-0x01, 0xf0, 0x76, 0xf8, 0x00, 0x20, 0x02, 0x90, 0xe0, 0x6a, 0xb8, 0x42,
-0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9, 0x07, 0x1c, 0x09, 0x98,
-0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x90,
-0x0c, 0x99, 0x88, 0x42, 0xa2, 0xdb, 0x68, 0x68, 0x30, 0x43, 0x01, 0x04,
-0x09, 0x0c, 0x68, 0x60, 0xe8, 0x6a, 0x00, 0xf0, 0x7b, 0xfa, 0x28, 0xe0,
-0x27, 0xe0, 0xa8, 0x68, 0x00, 0x09, 0x14, 0xd3, 0x68, 0x68, 0x80, 0x0e,
-0x15, 0xd2, 0x01, 0x9a, 0x00, 0x2a, 0x12, 0xd0, 0x01, 0x9a, 0x50, 0x6b,
-0x0b, 0x9b, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, 0x89, 0xf9, 0x01, 0x9a,
-0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x93, 0x63,
-0x03, 0xe0, 0xe8, 0x6a, 0x31, 0x1c, 0x00, 0xf0, 0x5d, 0xfa, 0x68, 0x68,
-0x30, 0x43, 0x68, 0x60, 0xa8, 0x69, 0xb0, 0x42, 0x05, 0xd9, 0x00, 0x04,
-0x00, 0x0c, 0x80, 0x1b, 0x00, 0xf0, 0xee, 0xf9, 0xae, 0x61, 0xa8, 0x68,
-0x8c, 0x23, 0x18, 0x40, 0x0b, 0xd0, 0x2f, 0x4a, 0xc0, 0x46, 0x00, 0x92,
-0x04, 0x98, 0xc3, 0x1f, 0x05, 0x3b, 0x2a, 0x48, 0x01, 0x6d, 0x42, 0x6d,
-0x00, 0x20, 0x01, 0xf0, 0x23, 0xf8, 0x01, 0x23, 0x9b, 0x07, 0x20, 0x6d,
-0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61, 0xe1, 0x69, 0x81, 0x42,
-0x12, 0xd0, 0x22, 0x69, 0x02, 0x2a, 0x0f, 0xd2, 0x41, 0x1a, 0x01, 0xd5,
-0x60, 0x6d, 0x41, 0x18, 0x20, 0x1c, 0xff, 0xf7, 0x3f, 0xfb, 0xe1, 0x69,
-0x40, 0x18, 0xe0, 0x61, 0x61, 0x6d, 0x88, 0x42, 0x24, 0xd3, 0x40, 0x1a,
-0xe0, 0x61, 0x21, 0xe0, 0x81, 0x42, 0x1f, 0xd1, 0x20, 0x69, 0x02, 0x28,
-0x1c, 0xd2, 0x01, 0x20, 0x60, 0x61, 0x18, 0x48, 0x41, 0x69, 0xe2, 0x6c,
-0x0a, 0x43, 0x42, 0x61, 0x81, 0x69, 0xe3, 0x6c, 0x99, 0x43, 0x81, 0x61,
-0x01, 0x21, 0x09, 0x05, 0xca, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x08, 0x61,
-0x8b, 0x02, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61,
-0xe1, 0x69, 0x81, 0x42, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 0xcc, 0xfa,
-0x28, 0x1c, 0x00, 0xf0, 0x0f, 0xf9, 0x0c, 0x98, 0x05, 0x99, 0x40, 0x18,
-0x00, 0x01, 0x10, 0x30, 0x68, 0x61, 0x13, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x7c, 0x29, 0x00, 0x80,
-0x00, 0x00, 0x12, 0x02, 0x04, 0x00, 0x52, 0x02, 0x68, 0x0e, 0x00, 0x80,
-0xf0, 0xb5, 0x40, 0x20, 0x2d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0,
-0x03, 0xf9, 0x07, 0x1c, 0x81, 0x69, 0x44, 0x6a, 0xa0, 0x6f, 0x00, 0xf0,
-0x45, 0xfe, 0x00, 0x20, 0xe1, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x79, 0x68,
-0xc9, 0x0e, 0x09, 0xd3, 0xf8, 0x6a, 0x00, 0x01, 0x24, 0x49, 0x40, 0x18,
-0x24, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, 0x39, 0x01, 0x60, 0x36, 0xe0,
-0xe1, 0x6d, 0x09, 0x68, 0x22, 0x6e, 0xc0, 0x46, 0x11, 0x60, 0x20, 0x4e,
-0xf5, 0x1d, 0x79, 0x35, 0x01, 0x23, 0xe9, 0x6b, 0x19, 0x43, 0xe9, 0x63,
-0xb9, 0x6a, 0xe2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 0xb9, 0x6a, 0x22, 0x6e,
-0xc0, 0x46, 0x11, 0x60, 0x61, 0x69, 0x00, 0x29, 0x04, 0xd1, 0xa9, 0x6b,
-0x01, 0x31, 0xa9, 0x63, 0x08, 0x29, 0x07, 0xd3, 0xa8, 0x63, 0x01, 0x20,
-0x00, 0xf0, 0x86, 0xf8, 0xe8, 0x6b, 0x40, 0x08, 0x40, 0x00, 0xe8, 0x63,
-0x78, 0x68, 0x81, 0x0e, 0x0f, 0xd2, 0x0b, 0x23, 0x1b, 0x02, 0xf1, 0x18,
-0xc9, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x00, 0x08, 0x04, 0xd2, 0x20, 0x1c,
-0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0,
-0x05, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0x06, 0xfc, 0x20, 0x1c, 0x00, 0xf0,
-0x0b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0,
-0xa0, 0x1c, 0x00, 0x80, 0xb4, 0x0c, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x19, 0x30,
-0x01, 0x79, 0x00, 0x29, 0x04, 0xd0, 0x00, 0x21, 0x01, 0x71, 0x38, 0x1c,
-0xff, 0xf7, 0x56, 0xfb, 0xf8, 0x68, 0x02, 0x28, 0x0d, 0xd0, 0xb8, 0x68,
-0x80, 0x00, 0xc2, 0x19, 0x50, 0x6c, 0x00, 0x28, 0x11, 0xd0, 0xb8, 0x6a,
-0x41, 0x78, 0x09, 0x01, 0x10, 0x31, 0x52, 0x6b, 0x10, 0x1a, 0x88, 0x42,
-0x05, 0xd3, 0x38, 0x1c, 0xff, 0xf7, 0x42, 0xfb, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x28, 0xfa, 0xf8, 0xe7, 0x78, 0x68,
-0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf1, 0xe7,
-0xb0, 0xb5, 0x87, 0xb0, 0x0f, 0x1c, 0x80, 0x6f, 0xc0, 0x46, 0x00, 0x90,
-0x00, 0x24, 0x13, 0x4d, 0x0b, 0x23, 0x1b, 0x02, 0xe8, 0x18, 0x80, 0x69,
-0x00, 0x28, 0x17, 0xd0, 0x69, 0x46, 0xa2, 0x00, 0x52, 0x19, 0x0b, 0x23,
-0x1b, 0x02, 0xd2, 0x18, 0x92, 0x69, 0x38, 0x1c, 0x00, 0xf0, 0x92, 0xfb,
-0x00, 0x28, 0x09, 0xd1, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x0b, 0x23,
-0x1b, 0x02, 0xc0, 0x18, 0x80, 0x69, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0,
-0x01, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x9d, 0xf9, 0x07, 0xb0,
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0xb8, 0xb5, 0xc2, 0x07, 0xd2, 0x0f, 0x16, 0x4c, 0x16, 0x49, 0x01, 0xd0,
-0x08, 0x22, 0x08, 0xe0, 0x82, 0x08, 0x05, 0xd3, 0x0c, 0x22, 0xa4, 0x18,
-0x0b, 0x68, 0xdf, 0x1d, 0x15, 0x37, 0x03, 0xe0, 0x1c, 0x22, 0x0b, 0x68,
-0xdf, 0x1d, 0x09, 0x37, 0x0f, 0x4b, 0x1d, 0x78, 0x00, 0x2d, 0x13, 0xd0,
-0x5b, 0x78, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x23, 0x5b, 0x06, 0x1a, 0x43,
-0x00, 0x28, 0x01, 0xd1, 0x5b, 0x08, 0x1a, 0x43, 0x00, 0x92, 0x4a, 0x68,
-0x01, 0x20, 0x39, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0xdf, 0xfe, 0xb8, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x03, 0x23, 0x1b, 0x06, 0x1a, 0x43, 0xf1, 0xe7,
-0x90, 0xee, 0x20, 0x40, 0x7c, 0x29, 0x00, 0x80, 0xf8, 0x0e, 0x00, 0x80,
-0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x8a, 0x68, 0x00, 0x2a, 0x01, 0xd1,
-0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0xc8, 0x60,
-0x70, 0x47, 0x00, 0x00, 0x28, 0x0f, 0x00, 0x80, 0x03, 0x49, 0x88, 0x68,
-0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 0x8a, 0x60, 0x70, 0x47,
-0x28, 0x0f, 0x00, 0x80, 0x01, 0x1c, 0x01, 0x23, 0x88, 0x68, 0x58, 0x40,
-0x88, 0x60, 0xca, 0x68, 0x01, 0x3a, 0xca, 0x60, 0x0a, 0x69, 0x01, 0x3a,
-0x80, 0x00, 0x0a, 0x61, 0x42, 0x18, 0xd0, 0x6b, 0x53, 0x6b, 0xc0, 0x46,
-0xcb, 0x62, 0x0b, 0x68, 0x9b, 0x00, 0x59, 0x18, 0x49, 0x6c, 0x53, 0x6c,
-0xc9, 0x18, 0x51, 0x64, 0x70, 0x47, 0x8a, 0x68, 0x92, 0x00, 0x52, 0x18,
-0xd3, 0x6b, 0x83, 0x42, 0x17, 0xd1, 0xd0, 0x1d, 0x3d, 0x30, 0x0a, 0x68,
-0x92, 0x00, 0x52, 0x18, 0x52, 0x6c, 0x03, 0x68, 0x9a, 0x1a, 0x02, 0x60,
-0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 0xca, 0x68, 0x01, 0x32,
-0xca, 0x60, 0x0a, 0x69, 0x01, 0x32, 0x80, 0x00, 0x40, 0x18, 0x0a, 0x61,
-0x40, 0x6b, 0xc0, 0x46, 0xc8, 0x62, 0x70, 0x47, 0xb8, 0xb5, 0x04, 0x1c,
-0x1d, 0x1c, 0x17, 0x1c, 0x08, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0xd9, 0xff,
-0x00, 0x20, 0x29, 0x1c, 0x00, 0xf0, 0x7c, 0xfe, 0x01, 0x20, 0xf9, 0x1d,
-0x19, 0x31, 0x48, 0x71, 0x80, 0x06, 0x60, 0x60, 0x00, 0x20, 0xa0, 0x61,
-0x06, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48,
-0x01, 0x6d, 0x42, 0x6d, 0x05, 0x4b, 0x00, 0x20, 0x00, 0xf0, 0x62, 0xfe,
-0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x04, 0x00, 0x12, 0x02,
-0x7c, 0x29, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x06, 0x49, 0x0a, 0x68,
-0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9,
-0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00,
-0xe4, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x80, 0x08, 0x80, 0x00,
-0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02,
-0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71,
-0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40,
-0x03, 0x30, 0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18,
-0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49,
-0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0xe4, 0x2d, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x02, 0x48, 0x41, 0x79, 0x01, 0x31, 0x41, 0x71,
-0x70, 0x47, 0x00, 0x00, 0xa0, 0x82, 0x20, 0x40, 0x90, 0xb4, 0x82, 0x00,
-0x17, 0x4b, 0x9a, 0x58, 0x8b, 0x07, 0x02, 0xd0, 0x89, 0x08, 0x0b, 0x1d,
-0x01, 0xe0, 0x89, 0x08, 0xcb, 0x1c, 0x11, 0x69, 0xd7, 0x68, 0x12, 0x4c,
-0x80, 0x00, 0x20, 0x58, 0x40, 0x68, 0xb9, 0x42, 0x03, 0xd1, 0x81, 0x42,
-0x19, 0xd9, 0x11, 0x68, 0x17, 0xe0, 0x00, 0x24, 0xb9, 0x42, 0x09, 0xd9,
-0x81, 0x42, 0x12, 0xd9, 0x11, 0x68, 0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30,
-0x80, 0x10, 0x98, 0x42, 0x0b, 0xd8, 0x07, 0xe0, 0x81, 0x42, 0x05, 0xd8,
-0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 0x98, 0x42, 0x02, 0xd8,
-0x20, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0xc8, 0x1d, 0x05, 0x30, 0xfa, 0xe7,
-0x70, 0x04, 0x00, 0x80, 0x80, 0xb5, 0x80, 0x00, 0x0f, 0x4a, 0x17, 0x58,
-0x88, 0x07, 0x02, 0xd0, 0x88, 0x08, 0x04, 0x30, 0x01, 0xe0, 0x88, 0x08,
-0x03, 0x30, 0x39, 0x69, 0x7a, 0x68, 0x91, 0x42, 0x09, 0xd9, 0x39, 0x68,
-0xc0, 0x46, 0x39, 0x61, 0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9,
-0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, 0x38, 0x69, 0x00, 0xf0,
-0xd1, 0xfd, 0x38, 0x61, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x70, 0x04, 0x00, 0x80, 0x90, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x01, 0x40,
-0x0c, 0x0f, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x22, 0x92, 0x07, 0x02, 0x40,
-0xa3, 0x00, 0x1c, 0x4f, 0xff, 0x58, 0x89, 0x07, 0x89, 0x0f, 0x00, 0x04,
-0x00, 0x0c, 0x80, 0x08, 0x00, 0x29, 0x00, 0xd0, 0x01, 0x30, 0x00, 0x2a,
-0x01, 0xd0, 0x02, 0x30, 0x00, 0xe0, 0x03, 0x30, 0xf9, 0x68, 0x7a, 0x68,
-0x91, 0x42, 0x02, 0xd9, 0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00,
-0xf8, 0x68, 0x00, 0xf0, 0xa5, 0xfd, 0xf8, 0x60, 0x0f, 0x48, 0x00, 0x69,
-0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x40, 0x02, 0xd0, 0x20, 0x1c,
-0xfe, 0xf7, 0xca, 0xfc, 0x0b, 0x49, 0xc8, 0x1d, 0x19, 0x30, 0x03, 0x79,
-0x00, 0x22, 0x00, 0x2b, 0x05, 0xd1, 0x09, 0x49, 0xc8, 0x1d, 0x19, 0x30,
-0x03, 0x79, 0x00, 0x2b, 0x03, 0xd0, 0x02, 0x71, 0x08, 0x1c, 0xff, 0xf7,
-0x79, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x04, 0x00, 0x80,
-0xd0, 0x2c, 0x00, 0x80, 0x64, 0x2d, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80,
-0xb0, 0xb5, 0x2b, 0x49, 0x09, 0x79, 0x00, 0x29, 0x03, 0xd1, 0x41, 0x68,
-0x29, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68,
-0x49, 0x08, 0x02, 0xd3, 0x09, 0x21, 0x09, 0x04, 0x01, 0xe0, 0x0d, 0x21,
-0x09, 0x04, 0x0c, 0xc8, 0x08, 0x38, 0x19, 0x43, 0x87, 0x68, 0xbb, 0x0a,
-0x03, 0xd3, 0x43, 0x68, 0x5b, 0x08, 0x00, 0xd3, 0x01, 0x31, 0x40, 0x68,
-0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x07, 0x0f, 0xf8, 0x00, 0x1d, 0x4c,
-0x00, 0x19, 0x23, 0x68, 0xc0, 0x18, 0x50, 0x30, 0x00, 0x79, 0x01, 0x28,
-0x10, 0xd1, 0x60, 0x68, 0x01, 0x28, 0x0d, 0xd0, 0x10, 0x1c, 0x00, 0xf0,
-0x71, 0xf8, 0x38, 0x01, 0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18,
-0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x38, 0x01, 0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x03, 0x6b,
-0x5d, 0x1c, 0x05, 0x63, 0xbd, 0x02, 0x2d, 0x19, 0xdb, 0x00, 0xeb, 0x18,
-0x80, 0x33, 0x19, 0x63, 0xda, 0x62, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63,
-0x01, 0x21, 0xb9, 0x40, 0x22, 0x68, 0x11, 0x43, 0x21, 0x60, 0x01, 0x6b,
-0x80, 0x29, 0xe2, 0xd3, 0x00, 0x21, 0x01, 0x63, 0xdf, 0xe7, 0x00, 0x00,
-0x28, 0x0f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80,
-0xf0, 0xb5, 0x1f, 0x4e, 0x70, 0x68, 0x00, 0x28, 0x36, 0xd1, 0x00, 0x24,
-0xb1, 0x68, 0x48, 0x1c, 0xc9, 0x00, 0x89, 0x19, 0xb0, 0x60, 0x32, 0x68,
-0x89, 0x18, 0x60, 0x31, 0x0d, 0x7b, 0x08, 0x28, 0x00, 0xd3, 0xb4, 0x60,
-0x28, 0x01, 0x80, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x87, 0x6b,
-0x00, 0x2f, 0x21, 0xd0, 0xc1, 0x6a, 0x4b, 0x1c, 0xaa, 0x02, 0x92, 0x19,
-0xc9, 0x00, 0x51, 0x18, 0x80, 0x31, 0xc3, 0x62, 0xca, 0x6a, 0x09, 0x6b,
-0x01, 0x3f, 0x87, 0x63, 0x80, 0x2b, 0x00, 0xd3, 0xc4, 0x62, 0x00, 0x2f,
-0x06, 0xd1, 0x01, 0x27, 0xaf, 0x40, 0x3b, 0x1c, 0xdb, 0x43, 0x37, 0x68,
-0x3b, 0x40, 0x33, 0x60, 0x43, 0x6b, 0x01, 0x3b, 0x43, 0x63, 0x10, 0x1c,
-0x37, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x78, 0x68, 0x00, 0x28, 0xc9, 0xd0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa0, 0x1c, 0x00, 0x80,
-0xf0, 0xb5, 0xcd, 0x0f, 0xed, 0x07, 0x01, 0x24, 0x00, 0x27, 0x2e, 0x4b,
-0x2e, 0x4a, 0x00, 0x2d, 0x1d, 0xd0, 0xd8, 0x6a, 0x01, 0x30, 0xd8, 0x62,
-0x10, 0x1c, 0x52, 0x69, 0x00, 0x2a, 0x12, 0xd0, 0x02, 0x69, 0x53, 0x1c,
-0x92, 0x00, 0x12, 0x18, 0x03, 0x61, 0x91, 0x61, 0x41, 0x69, 0x01, 0x31,
-0x41, 0x61, 0x02, 0x69, 0x0f, 0x2a, 0x00, 0xd3, 0x07, 0x61, 0x0f, 0x29,
-0x00, 0xd3, 0x44, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x1c,
-0xff, 0xf7, 0xee, 0xfe, 0xf8, 0xe7, 0x15, 0x69, 0x6e, 0x1c, 0xad, 0x00,
-0xad, 0x18, 0x16, 0x61, 0xa9, 0x61, 0x55, 0x69, 0x01, 0x35, 0x55, 0x61,
-0x16, 0x69, 0x0f, 0x2e, 0x00, 0xd3, 0x17, 0x61, 0x0f, 0x2d, 0x00, 0xd3,
-0x54, 0x60, 0x8c, 0x02, 0xa4, 0x0a, 0x16, 0x4f, 0x3a, 0x6f, 0xfd, 0x68,
-0xf9, 0x1d, 0x79, 0x31, 0x01, 0x2d, 0x0c, 0xd1, 0xdb, 0x6d, 0x5b, 0x08,
-0x09, 0xd3, 0x0b, 0x89, 0x00, 0x2b, 0x06, 0xd1, 0xfd, 0x6f, 0x03, 0x3b,
-0x2e, 0x68, 0x33, 0x40, 0x2b, 0x60, 0x14, 0x23, 0x0b, 0x81, 0x10, 0x60,
-0x80, 0x07, 0x80, 0x0a, 0x20, 0x43, 0x03, 0x04, 0x00, 0xd0, 0x01, 0x38,
-0x50, 0x60, 0x09, 0x6a, 0x08, 0x32, 0x91, 0x42, 0x00, 0xd8, 0x07, 0x4a,
-0x00, 0x0d, 0x02, 0xd3, 0x51, 0x20, 0x80, 0x03, 0x82, 0x61, 0x3a, 0x67,
-0xbe, 0xe7, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40,
-0xb0, 0xb5, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x20, 0xc0, 0x05, 0x16, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0x15, 0x4c, 0x00, 0x25, 0x67, 0x69, 0x00, 0x2f,
-0x16, 0xd0, 0xe0, 0x68, 0x41, 0x1c, 0x80, 0x00, 0x00, 0x19, 0xe1, 0x60,
-0x80, 0x69, 0x01, 0x3f, 0xff, 0xf7, 0x94, 0xfe, 0xe0, 0x68, 0x0f, 0x28,
-0x00, 0xd3, 0xe5, 0x60, 0xe0, 0x68, 0x80, 0x00, 0x00, 0x19, 0x80, 0x69,
-0x00, 0x08, 0x01, 0xd3, 0x00, 0x2f, 0xea, 0xd1, 0x67, 0x61, 0x03, 0xe0,
-0x08, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 0x65, 0x60, 0x20, 0x68,
-0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x26, 0xff, 0xb0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa0, 0x1c, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x00, 0x20, 0x70, 0x47, 0xb0, 0xb4, 0x10, 0x23,
-0x82, 0x68, 0x13, 0x40, 0x00, 0x21, 0x00, 0x2b, 0x15, 0xd0, 0x0c, 0x4b,
-0x1a, 0x40, 0x12, 0x01, 0x81, 0x24, 0x14, 0x43, 0x02, 0x68, 0x15, 0x68,
-0x13, 0x1d, 0x80, 0xcb, 0x1b, 0x68, 0x04, 0x3a, 0x02, 0x60, 0x20, 0xc2,
-0x80, 0xc2, 0x08, 0xc2, 0x14, 0x60, 0x42, 0x68, 0x01, 0x23, 0x9b, 0x07,
-0x04, 0x32, 0x1a, 0x43, 0x42, 0x60, 0x08, 0x1c, 0xb0, 0xbc, 0x70, 0x47,
-0x00, 0xf0, 0xff, 0x0f, 0xf0, 0xb4, 0x82, 0x68, 0x53, 0x09, 0x34, 0xd3,
-0x1b, 0x4b, 0x1a, 0x40, 0x12, 0x01, 0x81, 0x26, 0x16, 0x43, 0x03, 0x68,
-0x1d, 0x68, 0x1f, 0x1d, 0x10, 0xcf, 0x3f, 0x68, 0x04, 0x3b, 0x03, 0x60,
-0x20, 0xc3, 0x10, 0xc3, 0x80, 0xc3, 0x1e, 0x60, 0x43, 0x68, 0x1f, 0x1d,
-0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 0x43, 0x60, 0xcb, 0x6b, 0x18, 0x1f,
-0xc8, 0x63, 0x80, 0xcb, 0x80, 0xc0, 0x1c, 0x68, 0x1f, 0x1d, 0x03, 0x1d,
-0x04, 0x60, 0x38, 0x1c, 0x3f, 0x68, 0xc0, 0x46, 0x1f, 0x60, 0x1f, 0x1d,
-0x43, 0x68, 0x1c, 0x04, 0x24, 0x0c, 0x81, 0x23, 0x23, 0x43, 0x3b, 0x60,
-0x40, 0x68, 0x00, 0x0c, 0x00, 0x04, 0x10, 0x43, 0x78, 0x60, 0x08, 0x6e,
-0x04, 0x30, 0x08, 0x66, 0x48, 0x6e, 0x04, 0x30, 0x48, 0x66, 0x00, 0x20,
-0xf0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, 0x80, 0xb4, 0x81, 0x6a,
-0x01, 0x23, 0x9b, 0x07, 0xca, 0x1d, 0x05, 0x32, 0x1a, 0x43, 0x12, 0x68,
-0xcf, 0x1d, 0x01, 0x37, 0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x60,
-0x01, 0x23, 0x9b, 0x07, 0x0f, 0x1d, 0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46,
-0x8b, 0x60, 0x01, 0x23, 0x9b, 0x07, 0x0b, 0x43, 0x1b, 0x68, 0x0c, 0xc1,
-0x02, 0x62, 0x01, 0x6b, 0xc0, 0x46, 0x0a, 0x62, 0x04, 0x23, 0x81, 0x69,
-0x19, 0x43, 0x81, 0x61, 0x02, 0x6b, 0xc0, 0x46, 0x91, 0x61, 0x81, 0x6a,
-0x04, 0x31, 0x81, 0x62, 0x02, 0x6b, 0xc0, 0x46, 0x91, 0x62, 0xc1, 0x1d,
-0x39, 0x31, 0x4a, 0x8b, 0x04, 0x3a, 0x4a, 0x83, 0x49, 0x8b, 0x02, 0x6b,
-0x40, 0x32, 0x51, 0x83, 0xc1, 0x89, 0x04, 0x39, 0xc1, 0x81, 0xc1, 0x68,
-0x00, 0x6b, 0xc0, 0x46, 0xc1, 0x60, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47,
-0x00, 0x47, 0x08, 0x47, 0x10, 0x47, 0x18, 0x47, 0x20, 0x47, 0x28, 0x47,
-0x30, 0x47, 0x38, 0x47, 0x30, 0x40, 0x2d, 0xe9, 0x0c, 0xc0, 0x9d, 0xe5,
-0x0c, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xb0, 0xe1, 0x1e, 0x00, 0x00, 0x0a,
-0x01, 0xc0, 0x4c, 0xe2, 0x18, 0x40, 0xa0, 0xe3, 0x64, 0x51, 0x9f, 0xe5,
-0x94, 0x50, 0x20, 0xe0, 0x00, 0x50, 0x90, 0xe5, 0x14, 0x40, 0x90, 0xe5,
-0x00, 0x30, 0x85, 0xe5, 0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5,
-0x0c, 0x20, 0x85, 0xe5, 0x10, 0x10, 0x90, 0xe5,
-0x10, 0x50, 0x85, 0xe2, 0x01, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55,
-0x04, 0x00, 0x55, 0xe1, 0x05, 0x00, 0x00, 0x0a, 0x04, 0x10, 0x90, 0xe5,
-0x00, 0x50, 0x80, 0xe5, 0x00, 0x50, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
-0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x30, 0x93, 0xe5,
-0x08, 0x20, 0x90, 0xe5, 0x01, 0x31, 0x83, 0xe3, 0x02, 0x36, 0x83, 0xe3,
-0x03, 0x00, 0x55, 0xe1, 0x14, 0x30, 0x80, 0xe5, 0xf2, 0xff, 0xff, 0x1a,
-0x01, 0x00, 0xa0, 0xe3, 0xf4, 0xff, 0xff, 0xea, 0x01, 0x06, 0x1c, 0xe3,
-0xf1, 0xff, 0xff, 0x0a, 0xec, 0x10, 0x9f, 0xe5, 0x02, 0xc6, 0xcc, 0xe3,
-0x54, 0x20, 0x91, 0xe5, 0xe4, 0x30, 0x9f, 0xe5, 0x50, 0x10, 0x91, 0xe5,
-0xd9, 0xff, 0xff, 0xea, 0xf0, 0x47, 0x2d, 0xe9, 0x20, 0xc0, 0x9d, 0xe5,
-0x0c, 0x68, 0xa0, 0xe1, 0x26, 0x68, 0xb0, 0xe1, 0x25, 0x00, 0x00, 0x0a,
-0x18, 0x40, 0xa0, 0xe3, 0xb8, 0x50, 0x9f, 0xe5, 0x94, 0x00, 0x00, 0xe0,
-0x05, 0x00, 0x80, 0xe0, 0x08, 0x40, 0x90, 0xe5, 0x04, 0x80, 0x90, 0xe5,
-0x00, 0x70, 0xa0, 0xe3, 0x1f, 0xc0, 0xa0, 0xe3, 0x02, 0xc4, 0x8c, 0xe3,
-0x00, 0x50, 0x90, 0xe5, 0x10, 0x90, 0x90, 0xe5, 0x14, 0xa0, 0x90, 0xe5,
-0x00, 0x30, 0x85, 0xe5, 0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5,
-0x0c, 0x20, 0x85, 0xe5, 0x10, 0x50, 0x85, 0xe2, 0x09, 0x00, 0x55, 0xe1,
-0x0c, 0x50, 0x90, 0x55, 0x0a, 0x00, 0x55, 0xe1, 0x15, 0x00, 0x00, 0x0a,
-0x03, 0x70, 0x17, 0xe2, 0x20, 0x10, 0x81, 0xe2, 0x20, 0x30, 0x83, 0xe2,
-0x0a, 0x00, 0x00, 0x0a, 0x00, 0x60, 0x96, 0xe2, 0x01, 0x70, 0x87, 0xe2,
-0x09, 0x00, 0x00, 0x0a, 0x20, 0x60, 0x46, 0xe2, 0x20, 0x00, 0x56, 0xe3,
-0xec, 0xff, 0xff, 0xca, 0x00, 0x70, 0xa0, 0xe3, 0x01, 0xc0, 0x46, 0xe2,
-0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x60, 0xa0, 0xe3, 0xe7, 0xff, 0xff, 0xea,
-0x00, 0x50, 0x88, 0xe5, 0xf2, 0xff, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x50, 0x80, 0xe5, 0x01, 0x00, 0xa0, 0xe1, 0xf0, 0x47, 0xbd, 0xe8,
-0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xa0, 0x94, 0xe5, 0x0a, 0x00, 0x55, 0xe1,
-0x14, 0xa0, 0x80, 0xe5, 0xe5, 0xff, 0xff, 0x1a, 0x01, 0x10, 0xa0, 0xe3,
-0xf5, 0xff, 0xff, 0xea, 0xa8, 0x03, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80,
-0x00, 0x80, 0x20, 0x40, 0x68, 0x82, 0x9f, 0xe5, 0x0b, 0x92, 0xa0, 0xe3,
-0x64, 0xa2, 0x9f, 0xe5, 0x58, 0xb0, 0x9a, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1,
-0x54, 0xb0, 0x9a, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x3f, 0x40, 0x2d, 0xe9,
-0x00, 0x00, 0x4f, 0xe1, 0x1f, 0x00, 0x00, 0xe2, 0x12, 0x00, 0x50, 0xe3,
-0x54, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3,
-0x00, 0xf0, 0x21, 0xe1, 0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x99, 0xe5,
-0x09, 0x00, 0x00, 0xea, 0x02, 0x00, 0x14, 0xe3, 0x53, 0x00, 0x00, 0x1b,
-0x80, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x20, 0x00, 0x14, 0xe3,
-0x59, 0x00, 0x00, 0x1b, 0x02, 0x07, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b,
-0x01, 0x06, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x08, 0x00, 0x14, 0xe3,
-0x45, 0x00, 0x00, 0x1b, 0x02, 0x05, 0x14, 0xe3, 0x4a, 0x00, 0x00, 0x1b,
-0x02, 0x08, 0x14, 0xe3, 0x4b, 0x00, 0x00, 0x1b, 0xe5, 0x0e, 0x14, 0xe3,
-0x07, 0x00, 0x00, 0x0a, 0x04, 0x20, 0x98, 0xe5, 0x0c, 0x10, 0x98, 0xe5,
-0x04, 0x30, 0x52, 0xe2, 0x3c, 0x30, 0xa0, 0xb3, 0x04, 0x30, 0x88, 0xe5,
-0x02, 0x00, 0x91, 0xe7, 0x0f, 0xe0, 0xa0, 0xe1,
-0x10, 0xff, 0x2f, 0xe1, 0x01, 0x50, 0x55, 0xe2, 0x03, 0x00, 0x00, 0x0a,
-0x00, 0x40, 0x99, 0xe5, 0x0c, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1,
-0x1b, 0xff, 0x2f, 0x11, 0x08, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1,
-0x0b, 0x00, 0x00, 0x0a, 0x01, 0x0c, 0x14, 0xe3, 0x98, 0x01, 0x9f, 0x15,
-0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11, 0x02, 0x04, 0x14, 0xe3,
-0x8c, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11,
-0x01, 0x09, 0x14, 0xe3, 0x80, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11,
-0x10, 0xff, 0x2f, 0x11, 0x04, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1,
-0x16, 0x00, 0x00, 0x0a, 0x54, 0xe0, 0x8f, 0xe2, 0x04, 0x00, 0x14, 0xe3,
-0x40, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x02, 0x0a, 0x14, 0xe3,
-0x44, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x02, 0x09, 0x14, 0xe3,
-0x48, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x01, 0x02, 0x14, 0xe3,
-0x4c, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x01, 0x04, 0x14, 0xe3,
-0x50, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x01, 0x0a, 0x14, 0xe3,
-0x21, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x14, 0xe3, 0x0e, 0x00, 0x00, 0x1b,
-0x10, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1, 0x1c, 0x00, 0x00, 0x1b,
-0x00, 0x40, 0x99, 0xe5, 0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x94, 0xe2,
-0x1b, 0xff, 0x2f, 0x11, 0x3f, 0x40, 0xbd, 0xe8, 0x04, 0xf0, 0x5e, 0xe2,
-0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x61, 0xe1, 0xfa, 0xff, 0xff, 0xea,
-0x18, 0x00, 0x9a, 0xe5, 0x1c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1,
-0x54, 0xb0, 0x9a, 0xe5, 0x1c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5,
-0x11, 0xff, 0x2f, 0xe1, 0x20, 0x10, 0x9a, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
-0x11, 0xff, 0x2f, 0xe1, 0x24, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1,
-0x28, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x2c, 0x10, 0x9a, 0xe5,
-0x11, 0xff, 0x2f, 0xe1, 0x30, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1,
-0x34, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea,
-0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5, 0x18, 0x00, 0x9a, 0xe5,
-0x11, 0xff, 0x2f, 0xe1, 0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5,
-0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x64, 0x20, 0x9f, 0xe5,
-0x00, 0x30, 0x92, 0xe5, 0x00, 0x30, 0x53, 0xe0, 0x0a, 0x00, 0x00, 0xba,
-0x00, 0x30, 0x82, 0xe5, 0x0c, 0x00, 0x92, 0xe5, 0x08, 0x30, 0x92, 0xe5,
-0x00, 0x10, 0x91, 0xe2, 0x03, 0x00, 0x00, 0x0a, 0x03, 0x10, 0x80, 0xe7,
-0x04, 0x30, 0x53, 0xe2, 0x3c, 0x30, 0xa0, 0xb3, 0x08, 0x30, 0x82, 0xe5,
-0x01, 0x00, 0xa0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1, 0x3c, 0x10, 0x9f, 0xe5,
-0x00, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x80, 0xe2, 0x00, 0x00, 0x81, 0xe5,
-0x00, 0x00, 0xa0, 0xe3, 0xf8, 0xff, 0xff, 0xea, 0x10, 0x00, 0x9f, 0xe5,
-0x08, 0x10, 0x90, 0xe5, 0x04, 0x10, 0x51, 0xe2, 0x3c, 0x10, 0xa0, 0xb3,
-0x08, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xe4, 0x2d, 0x00, 0x80,
-0xcc, 0x04, 0x00, 0x80, 0x71, 0x2b, 0xff, 0xff, 0xd1, 0x3d, 0xff, 0xff,
-0xc9, 0x2b, 0xff, 0xff, 0xa0, 0x82, 0x20, 0x40, 0xc9, 0x1c, 0x89, 0x08,
-0x89, 0x00, 0x01, 0x23, 0x85, 0x4a, 0x5b, 0x07, 0x18, 0x43, 0x13, 0x68,
-0x5b, 0x18, 0x13, 0x60, 0x00, 0x1f, 0x81, 0xa3, 0x5b, 0x1a, 0x18, 0x47,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xe4, 0x2d, 0x00, 0x80,
-0x98, 0x00, 0x9f, 0xe5, 0x98, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0,
-0x94, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1,
-0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2,
-0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 0x78, 0x00, 0x9f, 0xe5,
-0x00, 0x20, 0x80, 0xe5, 0x74, 0x00, 0x9f, 0xe5, 0x74, 0x10, 0x9f, 0xe5,
-0x01, 0x20, 0x40, 0xe0, 0x60, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5,
-0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2,
-0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea,
-0x50, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x4c, 0x00, 0x9f, 0xe5,
-0x4c, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x2c, 0x30, 0x9f, 0xe5,
-0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a,
-0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a,
-0xf8, 0xff, 0xff, 0xea, 0x28, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0x7c, 0x34, 0x00, 0x80, 0x80, 0x30, 0x00, 0x80,
-0xad, 0xde, 0xad, 0xde, 0xc0, 0x04, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80,
-0x80, 0x34, 0x00, 0x80, 0xc4, 0x04, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80,
-0x40, 0x38, 0x00, 0x80, 0xc8, 0x04, 0x00, 0x80, 0x78, 0x47, 0x00, 0x00,
-0x71, 0xea, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x39, 0xfe, 0xff, 0xea,
-0x78, 0x47, 0x00, 0x00, 0x63, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00,
-0x1b, 0xff, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x6b, 0xea, 0xff, 0xea,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0x28, 0x04, 0x00, 0x00, 0xf8, 0x3d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80,
-0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x0b, 0xff, 0xff,
-0x00, 0x00, 0x00, 0x00, 0xd5, 0x0b, 0xff, 0xff, 0x03, 0xff, 0x06, 0x54,
-0x03, 0x00, 0x00, 0x00, 0x75, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
-0xa1, 0x05, 0xff, 0xff, 0x04, 0xff, 0x07, 0x54, 0x03, 0x00, 0x00, 0x00,
-0xb5, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x05, 0xff, 0xff,
-0x05, 0xff, 0x05, 0x54, 0x03, 0x00, 0x00, 0x00, 0x39, 0x04, 0xff, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x55, 0x05, 0xff, 0xff, 0x01, 0xff, 0x04, 0x00,
-0x03, 0x00, 0x00, 0x00, 0x41, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
-0x61, 0x0e, 0xff, 0xff, 0x02, 0xff, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
-0xa1, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x02, 0xff, 0xff,
-0xff, 0xff, 0x01, 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x9d, 0x0d, 0xff, 0xff, 0x06, 0x00, 0xff, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x3d, 0x50, 0xff, 0xff, 0x81, 0x50, 0xff, 0xff,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x48, 0x05, 0x00, 0x80, 0x11, 0x75, 0x21, 0x40, 0x1b, 0x75, 0x21, 0x40,
-0x31, 0x75, 0x21, 0x40, 0x49, 0x75, 0x21, 0x40,
-0x55, 0x75, 0x21, 0x40, 0x63, 0x75, 0x21, 0x40, 0x7d, 0x75, 0x21, 0x40,
-0xa9, 0x75, 0x21, 0x40, 0x6d, 0x76, 0x21, 0x40, 0xc5, 0x76, 0x21, 0x40,
-0xd3, 0x76, 0x21, 0x40, 0xdd, 0x76, 0x21, 0x40, 0xe7, 0x76, 0x21, 0x40,
-0x99, 0x77, 0x21, 0x40, 0xa7, 0x77, 0x21, 0x40, 0xb5, 0x77, 0x21, 0x40,
-0x61, 0x78, 0x21, 0x40, 0x5f, 0x7c, 0x21, 0x40, 0xe9, 0x7c, 0x21, 0x40,
-0x89, 0x7d, 0x21, 0x40, 0xbd, 0x7e, 0x21, 0x40, 0xc9, 0x7e, 0x21, 0x40,
-0x29, 0x7f, 0x21, 0x40, 0x8d, 0x7f, 0x21, 0x40, 0xb9, 0x7f, 0x21, 0x40,
-0xdd, 0x7f, 0x21, 0x40, 0x1d, 0x80, 0x21, 0x40, 0x45, 0x80, 0x21, 0x40,
-0x8d, 0x80, 0x21, 0x40, 0x9d, 0x80, 0x21, 0x40, 0xc5, 0x80, 0x21, 0x40,
-0xd5, 0x80, 0x21, 0x40, 0x1d, 0x81, 0x21, 0x40, 0x5b, 0x81, 0x21, 0x40,
-0xb1, 0x81, 0x21, 0x40, 0x11, 0x82, 0x21, 0x40, 0x1b, 0x82, 0x21, 0x40,
-0x1f, 0x82, 0x21, 0x40, 0x8d, 0x82, 0x21, 0x40, 0xd9, 0x82, 0x21, 0x40,
-0x31, 0x83, 0x21, 0x40, 0x6d, 0x83, 0x21, 0x40, 0xd1, 0x83, 0x21, 0x40,
-0x09, 0x84, 0x21, 0x40, 0x19, 0x84, 0x21, 0x40, 0x51, 0x84, 0x21, 0x40,
-0x61, 0x84, 0x21, 0x40, 0x75, 0x84, 0x21, 0x40, 0x9d, 0x84, 0x21, 0x40,
-0xa7, 0x84, 0x21, 0x40, 0xb1, 0x84, 0x21, 0x40, 0x15, 0x85, 0x21, 0x40,
-0x45, 0x85, 0x21, 0x40, 0x51, 0x85, 0x21, 0x40, 0xc5, 0x85, 0x21, 0x40,
-0xcf, 0x85, 0x21, 0x40, 0xd9, 0x85, 0x21, 0x40, 0xe3, 0x85, 0x21, 0x40,
-0xed, 0x85, 0x21, 0x40, 0xf7, 0x85, 0x21, 0x40, 0x01, 0x86, 0x21, 0x40,
-0x0b, 0x86, 0x21, 0x40, 0x15, 0x86, 0x21, 0x40, 0x01, 0x89, 0x21, 0x40,
-0x1f, 0x86, 0x21, 0x40, 0x29, 0x86, 0x21, 0x40, 0x33, 0x86, 0x21, 0x40,
-0x3d, 0x86, 0x21, 0x40, 0x65, 0x86, 0x21, 0x40, 0x6f, 0x86, 0x21, 0x40,
-0xd1, 0x86, 0x21, 0x40, 0xdb, 0x86, 0x21, 0x40, 0xe5, 0x86, 0x21, 0x40,
-0xef, 0x86, 0x21, 0x40, 0xf9, 0x86, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x03, 0x87, 0x21, 0x40, 0x69, 0x87, 0x21, 0x40, 0xb5, 0x87, 0x21, 0x40,
-0xf9, 0x87, 0x21, 0x40, 0x09, 0x88, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x55, 0x88, 0x21, 0x40, 0x59, 0x88, 0x21, 0x40, 0x5d, 0x88, 0x21, 0x40,
-0xb5, 0x88, 0x21, 0x40, 0xdd, 0x88, 0x21, 0x40, 0xe9, 0x88, 0x21, 0x40,
-0xed, 0x88, 0x21, 0x40, 0xf1, 0x88, 0x21, 0x40, 0xf5, 0x88, 0x21, 0x40,
-0xf9, 0x88, 0x21, 0x40, 0xfd, 0x88, 0x21, 0x40, 0x2d, 0x85, 0x21, 0x40,
-0x89, 0x85, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x0d, 0x89, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40, 0xe1, 0x74, 0x21, 0x40,
-0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x6b, 0x78, 0x21, 0x40, 0xf5, 0x7b, 0x21, 0x40, 0x31, 0x7c, 0x21, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x18, 0x40, 0x58, 0x01, 0x18, 0x40,
-0x24, 0xa3, 0x20, 0x40, 0x24, 0xa7, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x18, 0x40, 0x68, 0x01, 0x18, 0x40,
-0x24, 0x83, 0x20, 0x40, 0x24, 0xa3, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x18, 0x40, 0x78, 0x01, 0x18, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x8c, 0x01, 0x18, 0x40,
-0x88, 0x01, 0x18, 0x40, 0x24, 0xa9, 0x20, 0x40, 0x24, 0xab, 0x20, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x08, 0x00, 0x12, 0x00, 0x18, 0x00, 0x12, 0x00, 0x0c, 0x00, 0x12, 0x00,
-0x1c, 0x00, 0x12, 0x00, 0x24, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40,
-0xa4, 0xa8, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-0xd1, 0xa8, 0x21, 0x40, 0x2d, 0xaa, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x89, 0x70, 0x21, 0x40, 0xc9, 0xa1, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x57, 0x89, 0x21, 0x40, 0xd1, 0xa8, 0x21, 0x40, 0xc5, 0x2f, 0xff, 0xff,
-0x05, 0x21, 0xff, 0xff, 0xef, 0x20, 0xff, 0xff, 0x59, 0xa7, 0x21, 0x40,
-0x34, 0x2e, 0x00, 0x80, 0x48, 0x2e, 0x00, 0x80, 0x5c, 0x2e, 0x00, 0x80,
-0x30, 0x33, 0x3a, 0x31, 0x31, 0x3a, 0x31, 0x31, 0x00, 0x30, 0x37, 0x2f,
-0x32, 0x33, 0x2f, 0x30, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x31, 0x35,
-0x36, 0x39, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74,
-0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x31, 0x20, 0x33, 0x43,
-0x6f, 0x6d, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69,
-0x6f, 0x6e, 0x0a, 0x00, 0x08, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x53, 0xff, 0xff,
-0x27, 0xf0, 0x7d, 0xfd, 0x00, 0x01, 0x00, 0x02, 0xda, 0x0e, 0x82, 0x00,
-0x01, 0x40, 0x64, 0x04, 0x64, 0x2d, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80,
-0x69, 0x3e, 0xff, 0xff, 0xc9, 0x4f, 0xff, 0xff, 0xd5, 0x24, 0xff, 0xff,
-0xc9, 0x3b, 0xff, 0xff, 0x29, 0x3c, 0xff, 0xff, 0x19, 0x1a, 0xff, 0xff,
-0x65, 0x11, 0xff, 0xff, 0xcc, 0x53, 0xff, 0xff, 0x21, 0x40, 0xff, 0xff,
-0x89, 0x70, 0x21, 0x40, 0x49, 0x72, 0x21, 0x40, 0xd9, 0x3f, 0xff, 0xff,
-0x21, 0x9a, 0x21, 0x40, 0x85, 0x24, 0xff, 0xff, 0x64, 0x53, 0xff, 0xff,
-0x8c, 0x53, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x80, 0x30, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x00, 0x00, 0x20, 0x40, 0xb0, 0x50, 0x00, 0x00, 0x7b, 0x0e, 0x00, 0x00,
-0x00, 0x6e, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xed, 0x89, 0x21, 0x40, 0x8b, 0x89, 0x21, 0x40, 0xa5, 0x8c, 0x21, 0x40,
-0x05, 0x8d, 0x21, 0x40, 0xcd, 0x8d, 0x21, 0x40, 0x8b, 0x8b, 0x21, 0x40,
-0xa9, 0x8e, 0x21, 0x40, 0x15, 0x8f, 0x21, 0x40, 0x69, 0x8b, 0x21, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x59, 0xbd, 0x21, 0x40, 0xc1, 0xbd, 0x21, 0x40, 0x2d, 0xbe, 0x21, 0x40,
-0x00, 0x20, 0x0a, 0x4a, 0x0b, 0x23, 0x1b, 0x02, 0xd1, 0x18, 0x2d, 0x23,
-0x9b, 0x01, 0xd3, 0x18, 0x88, 0x61, 0xd8, 0x60, 0xd8, 0x63, 0x80, 0x32,
-0xc8, 0x60, 0x08, 0x61, 0x48, 0x61, 0xd0, 0x62, 0x03, 0x48, 0xc0, 0x46,
-0x48, 0x60, 0x88, 0x60, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0xfe, 0x03, 0x00, 0x00, 0xf0, 0xb5, 0x84, 0xb0, 0x0c, 0x1c, 0x05, 0x1c,
-0x00, 0x23, 0x00, 0x93, 0xff, 0xf7, 0xde, 0xff, 0x68, 0x49, 0x0b, 0x23,
-0x1b, 0x02, 0xcf, 0x18, 0x78, 0x68, 0x28, 0x40,
-0x00, 0x22, 0xf8, 0x60, 0x3a, 0x61, 0xba, 0x68, 0x22, 0x40, 0x7a, 0x61,
-0x0c, 0x1c, 0x41, 0x09, 0x03, 0xd2, 0x51, 0x09, 0x01, 0xd2, 0x80, 0x0a,
-0x02, 0xd3, 0x60, 0x48, 0x00, 0xf0, 0xc2, 0xf8, 0x01, 0x20, 0xf9, 0x68,
-0x49, 0x09, 0x03, 0xd2, 0x79, 0x69, 0x49, 0x09, 0x00, 0xd2, 0x00, 0x20,
-0x00, 0x06, 0x00, 0x0e, 0x03, 0xf0, 0xd4, 0xfa, 0xf8, 0x68, 0x00, 0x28,
-0x70, 0xd0, 0x00, 0x23, 0x02, 0x93, 0x01, 0x93, 0x54, 0x4a, 0x01, 0x23,
-0x18, 0x43, 0xf8, 0x60, 0x00, 0x20, 0xd5, 0x1d, 0x79, 0x35, 0x03, 0x95,
-0x01, 0x24, 0x00, 0x21, 0x4f, 0x4d, 0xfa, 0x68, 0x22, 0x40, 0x39, 0xd0,
-0x8a, 0x00, 0x52, 0x18, 0x92, 0x00, 0x4e, 0x4b, 0x9b, 0x5c, 0x1e, 0x1c,
-0x83, 0x42, 0x04, 0xd0, 0x4b, 0x4b, 0xd3, 0x18, 0x5b, 0x78, 0x83, 0x42,
-0x2c, 0xd1, 0x49, 0x4b, 0xd2, 0x18, 0xd3, 0x78, 0x03, 0x9d, 0xed, 0x6a,
-0xab, 0x42, 0x02, 0xd9, 0x03, 0x9d, 0xc0, 0x46, 0xeb, 0x62, 0x53, 0x68,
-0x5b, 0x08, 0x01, 0xd3, 0x01, 0x23, 0x00, 0x93, 0x86, 0x42, 0x0a, 0xd1,
-0x95, 0x68, 0x02, 0x9b, 0x5e, 0x1c, 0x02, 0x96, 0x9b, 0x00, 0x3c, 0x4e,
-0x9e, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xf3, 0x18, 0x9d, 0x61, 0x53, 0x78,
-0x83, 0x42, 0x0d, 0xd1, 0xd2, 0x68, 0x01, 0x9b, 0x5d, 0x1c, 0x01, 0x95,
-0x9b, 0x00, 0x35, 0x4d, 0x5d, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xeb, 0x18,
-0xda, 0x60, 0x3a, 0x69, 0x01, 0x32, 0x3a, 0x61, 0x64, 0x00, 0x01, 0x31,
-0x0b, 0x29, 0xbd, 0xd3, 0x01, 0x30, 0x09, 0x28, 0xb8, 0xd3, 0x00, 0x20,
-0x02, 0x9b, 0x99, 0x00, 0x2b, 0x4a, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02,
-0xc9, 0x18, 0x88, 0x61, 0x01, 0x9b, 0x99, 0x00, 0x89, 0x18, 0x2d, 0x23,
-0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x60, 0x00, 0x9b, 0x00, 0x2b, 0x0c, 0xd1,
-0x81, 0x00, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, 0xc9, 0x18, 0xcb, 0x69,
-0xc0, 0x46, 0x8b, 0x61, 0x01, 0x30, 0x0b, 0x28, 0xf4, 0xd3, 0x08, 0xe0,
-0x07, 0xe0, 0x03, 0x9d, 0xe8, 0x6a, 0x30, 0x28, 0x03, 0xd2, 0x30, 0x20,
-0x03, 0x9d, 0xc0, 0x46, 0xe8, 0x62, 0x19, 0x4a, 0x78, 0x69, 0x00, 0x28,
-0x2a, 0xd0, 0x00, 0x21, 0x01, 0x23, 0x18, 0x43, 0x78, 0x61, 0x00, 0x20,
-0x01, 0x24, 0x00, 0x22, 0x13, 0x4e, 0x7b, 0x69, 0x23, 0x40, 0x10, 0xd0,
-0x93, 0x00, 0x9b, 0x18, 0x9b, 0x00, 0x12, 0x4d, 0x5b, 0x19, 0x9d, 0x78,
-0x85, 0x42, 0x08, 0xd1, 0x1d, 0x69, 0x0b, 0x1c, 0x9b, 0x00, 0x9e, 0x19,
-0x2d, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0xdd, 0x63, 0x01, 0x31, 0x64, 0x00,
-0x01, 0x32, 0x0b, 0x2a, 0xe6, 0xd3, 0x01, 0x30, 0x09, 0x28, 0xe1, 0xd3,
-0x00, 0x20, 0x89, 0x00, 0x04, 0x4a, 0x89, 0x18, 0x2d, 0x23, 0x9b, 0x01,
-0xc9, 0x18, 0xc8, 0x63, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x30, 0x53, 0xff, 0xff, 0x00, 0x01, 0x00, 0x80,
-0x00, 0x47, 0x08, 0x47, 0x10, 0x47, 0x18, 0x47, 0x78, 0x47, 0xc0, 0x46,
-0x18, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46,
-0x10, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46,
-0x08, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x38, 0x52, 0xff, 0xff,
-0x88, 0x51, 0xff, 0xff, 0xd5, 0xb0, 0x21, 0x40, 0xf0, 0xb5, 0x04, 0x20,
-0x1a, 0x49, 0x01, 0x25, 0x08, 0x60, 0x1a, 0x4f, 0xbb, 0x23, 0x1b, 0x01,
-0xf8, 0x18, 0x05, 0x73, 0x18, 0x48, 0x41, 0x6b, 0x2c, 0x05, 0x00, 0x20,
-0x7a, 0x6e, 0x17, 0x4b, 0x8a, 0x42, 0x1d, 0xd0,
-0x19, 0x7b, 0x00, 0x29, 0x17, 0xd1, 0xd9, 0x1d, 0xff, 0x31, 0x3a, 0x31,
-0x49, 0x78, 0x1e, 0x1c, 0x00, 0x29, 0x10, 0xd1, 0xb0, 0x60, 0x10, 0x20,
-0x70, 0x60, 0x10, 0x4a, 0x10, 0x49, 0xff, 0xf7, 0xc3, 0xff, 0x00, 0x28,
-0x07, 0xd0, 0x35, 0x73, 0x04, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61,
-0x20, 0x61, 0x00, 0xf0, 0x17, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x18, 0x73, 0x04, 0x23, 0xb8, 0x69, 0x98, 0x43, 0xb8, 0x61, 0x20, 0x61,
-0xf5, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80,
-0x00, 0x01, 0x18, 0x40, 0x28, 0x05, 0x00, 0x80, 0x20, 0x55, 0xff, 0xff,
-0x7d, 0x71, 0x21, 0x40, 0xf8, 0xb5, 0x15, 0x4f, 0x39, 0x6c, 0x15, 0x48,
-0x40, 0x6e, 0x0c, 0x1a, 0x14, 0x4e, 0x71, 0x68, 0x14, 0x4d, 0xa1, 0x42,
-0x06, 0xd8, 0x14, 0x4a, 0x0a, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18,
-0xfa, 0x6b, 0x11, 0xe0, 0x11, 0x22, 0x52, 0x05, 0x22, 0x43, 0x00, 0x92,
-0xb9, 0x6b, 0x09, 0x18, 0x00, 0x20, 0xfa, 0x6b, 0x2b, 0x1c, 0xff, 0xf7,
-0x8d, 0xff, 0x70, 0x68, 0x00, 0x1b, 0x0a, 0x4a, 0x02, 0x43, 0x00, 0x92,
-0xb9, 0x6b, 0xfa, 0x6b, 0x00, 0x20, 0x2b, 0x1c, 0xff, 0xf7, 0x82, 0xff,
-0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x7c, 0x29, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40,
-0x00, 0x00, 0x37, 0x02, 0xf0, 0xb5, 0x2b, 0x4f, 0xb8, 0x68, 0x79, 0x68,
-0xc0, 0x19, 0x20, 0x30, 0x29, 0x4a, 0xff, 0xf7, 0x63, 0xff, 0x01, 0x20,
-0xc0, 0x02, 0x28, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xb9, 0x68, 0x38, 0x1c,
-0x26, 0x4d, 0x00, 0x24, 0x26, 0x4e, 0xef, 0x1d, 0x79, 0x37, 0x00, 0x29,
-0x31, 0xd1, 0x31, 0x68, 0x0a, 0x78, 0x12, 0x0a, 0x03, 0xd2, 0x04, 0x73,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x49, 0x78, 0x00, 0x29, 0x0c, 0xd1,
-0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0, 0x3e, 0xf9, 0x30, 0x68, 0x00, 0xf0,
-0x67, 0xf8, 0x00, 0x28, 0x26, 0xd1, 0x2c, 0x73, 0xff, 0xf7, 0x58, 0xff,
-0x22, 0xe0, 0x09, 0x01, 0x07, 0x1c, 0x41, 0x60, 0x08, 0x1c, 0x17, 0x4a,
-0x17, 0x49, 0xff, 0xf7, 0x35, 0xff, 0x00, 0x28, 0x07, 0xd1, 0x3c, 0x73,
-0x04, 0x23, 0xa8, 0x69, 0x98, 0x43, 0x99, 0x04, 0xa8, 0x61, 0x08, 0x61,
-0xda, 0xe7, 0x10, 0x20, 0x00, 0xf0, 0x20, 0xf9, 0x10, 0x20, 0xb8, 0x60,
-0xff, 0xf7, 0x82, 0xff, 0xd2, 0xe7, 0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0,
-0x17, 0xf9, 0x30, 0x68, 0x00, 0xf0, 0x40, 0xf8, 0x00, 0x28, 0xd8, 0xd0,
-0x02, 0x23, 0xf8, 0x6b, 0x18, 0x43, 0xf8, 0x63, 0xc4, 0xe7, 0x00, 0x00,
-0x28, 0x05, 0x00, 0x80, 0xa5, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb0,
-0x68, 0x0e, 0x00, 0x80, 0xe4, 0x01, 0x00, 0x80, 0x20, 0x55, 0xff, 0xff,
-0x7d, 0x71, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x20, 0x40, 0x03, 0x10, 0x49,
-0x00, 0x27, 0x08, 0x60, 0x0f, 0x4c, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30,
-0x47, 0x70, 0xe0, 0x69, 0x80, 0x00, 0x00, 0x19, 0x00, 0x69, 0x00, 0xf0,
-0xd7, 0xf8, 0xe0, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xe7, 0x61, 0x01, 0xe0,
-0x01, 0x20, 0xe0, 0x61, 0x07, 0x48, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43,
-0xc1, 0x63, 0x27, 0x73, 0xff, 0xf7, 0x00, 0xff, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x28, 0x05, 0x00, 0x80,
-0xe8, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x78, 0x88,
-0x6d, 0x28, 0x03, 0xdb, 0x38, 0x1c, 0x00, 0xf0,
-0xf7, 0xf8, 0x17, 0xe0, 0x80, 0x00, 0x0d, 0x49, 0x09, 0x58, 0x38, 0x1c,
-0xff, 0xf7, 0xcb, 0xfe, 0x00, 0x28, 0x0f, 0xd1, 0x39, 0x78, 0xc9, 0x09,
-0x0c, 0xd3, 0x69, 0x46, 0x38, 0x1c, 0x00, 0xf0, 0xcf, 0xf8, 0x68, 0x46,
-0x00, 0x21, 0x00, 0xf0, 0x0b, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20,
-0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xe8, 0x01, 0x00, 0x80, 0xf0, 0xb5, 0x82, 0xb0, 0x02, 0x1c, 0x41, 0x4b,
-0xdd, 0x1d, 0xff, 0x35, 0x3a, 0x35, 0x2f, 0x78, 0x00, 0x2f, 0x01, 0xd0,
-0x00, 0x27, 0x00, 0xe0, 0x01, 0x27, 0x2f, 0x70, 0x2f, 0x78, 0xfb, 0x00,
-0xdb, 0x19, 0x5b, 0x01, 0x3a, 0x4f, 0xdc, 0x19, 0x40, 0x78, 0x00, 0x01,
-0xc7, 0x1d, 0x09, 0x37, 0x00, 0x20, 0x83, 0x00, 0xd6, 0x58, 0xc0, 0x46,
-0xe6, 0x50, 0x01, 0x30, 0x04, 0x28, 0xf8, 0xd3, 0x00, 0x29, 0x0f, 0xd0,
-0x00, 0x22, 0xbb, 0x08, 0x01, 0x93, 0x83, 0x42, 0x0b, 0xd9, 0x13, 0x1c,
-0x9b, 0x00, 0xcb, 0x58, 0x86, 0x00, 0xa3, 0x51, 0x01, 0x9b, 0x01, 0x30,
-0x01, 0x32, 0x83, 0x42, 0xf5, 0xd8, 0x00, 0xe0, 0x10, 0x27, 0x2b, 0x48,
-0x02, 0x6d, 0x80, 0x6e, 0x2a, 0x49, 0x82, 0x42, 0x03, 0xd8, 0x82, 0x1a,
-0xcb, 0x6c, 0x9a, 0x1a, 0x00, 0xe0, 0x12, 0x1a, 0xba, 0x42, 0x05, 0xd8,
-0x26, 0x48, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x01, 0x20, 0x37, 0xe0,
-0xc3, 0x19, 0xca, 0x6c, 0x93, 0x42, 0x08, 0xd8, 0x22, 0x4a, 0x3a, 0x43,
-0x00, 0x92, 0x0a, 0x1c, 0x49, 0x6c, 0x09, 0x18, 0x92, 0x6c, 0x23, 0x1c,
-0x12, 0xe0, 0x16, 0x1a, 0x00, 0x96, 0x1b, 0x49, 0x49, 0x6c, 0x09, 0x18,
-0x19, 0x48, 0x82, 0x6c, 0x03, 0x20, 0x23, 0x1c, 0xff, 0xf7, 0x5e, 0xfe,
-0xb8, 0x1b, 0x18, 0x4a, 0x02, 0x43, 0x00, 0x92, 0xa3, 0x19, 0x14, 0x48,
-0x82, 0x6c, 0x41, 0x6c, 0x03, 0x20, 0xff, 0xf7, 0x53, 0xfe, 0x01, 0x20,
-0x0d, 0x49, 0xc0, 0x46, 0x68, 0x70, 0x8a, 0x69, 0x92, 0x00, 0x52, 0x18,
-0x17, 0x61, 0x8a, 0x69, 0x00, 0x2a, 0x02, 0xd0, 0x00, 0x27, 0x8f, 0x61,
-0x00, 0xe0, 0x88, 0x61, 0x0c, 0x48, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43,
-0xc1, 0x63, 0x00, 0x20, 0x01, 0x27, 0x0a, 0x49, 0xc0, 0x46, 0x4f, 0x73,
-0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x05, 0x00, 0x80,
-0x50, 0xba, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x00, 0x00, 0x19, 0x02, 0xe8, 0x0e, 0x00, 0x80,
-0x18, 0x1a, 0x00, 0x80, 0x07, 0x49, 0x8a, 0x6e, 0x10, 0x18, 0x07, 0x4a,
-0xd2, 0x6c, 0x13, 0x04, 0x1b, 0x0c, 0x83, 0x42, 0x00, 0xd8, 0x80, 0x1a,
-0x88, 0x66, 0x88, 0x6e, 0x03, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x70, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 0x90, 0xee, 0x20, 0x40,
-0x06, 0x49, 0x4a, 0x6e, 0x10, 0x18, 0x06, 0x4a, 0x12, 0x6c, 0x82, 0x42,
-0x00, 0xd8, 0x80, 0x1a, 0x48, 0x66, 0x48, 0x6e, 0x03, 0x49, 0xc0, 0x46,
-0x08, 0x61, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80,
-0x90, 0xee, 0x20, 0x40, 0x05, 0x22, 0x0a, 0x60, 0x82, 0x88, 0xc0, 0x46,
-0x8a, 0x80, 0x00, 0x22, 0x4a, 0x70, 0x40, 0x88, 0xc0, 0x46, 0x48, 0x80,
-0xca, 0x80, 0x8a, 0x60, 0xca, 0x60, 0x70, 0x47, 0x05, 0x22, 0x02, 0x60,
-0x00, 0x22, 0x82, 0x80, 0x42, 0x70, 0x41, 0x80, 0xc2, 0x80, 0x82, 0x60,
-0xc2, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x0e, 0x48,
-0x41, 0x6b, 0x01, 0x31, 0x41, 0x63, 0x69, 0x46,
-0x38, 0x1c, 0xff, 0xf7, 0xdd, 0xff, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90,
-0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x01, 0x27, 0xdf, 0x80, 0x68, 0x46,
-0x00, 0x21, 0xff, 0xf7, 0x11, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x38, 0x1c,
-0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xa0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x09, 0x4a,
-0xc0, 0x46, 0x91, 0x81, 0x69, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x01, 0x20,
-0x40, 0x02, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7,
-0xf5, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0xe8, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0xff, 0xf7, 0xc3, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x01, 0x20, 0x03, 0x49, 0xc0, 0x46, 0x08, 0x71, 0xa1, 0x21,
-0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0x28, 0x0f, 0x00, 0x80,
-0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, 0x08, 0x71, 0xff, 0x21, 0xa1, 0x22,
-0x52, 0x03, 0x01, 0x31, 0x91, 0x60, 0x70, 0x47, 0x28, 0x0f, 0x00, 0x80,
-0x02, 0x20, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47,
-0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20,
-0x70, 0x47, 0xc0, 0x88, 0xc0, 0x06, 0xc0, 0x0e, 0xa1, 0x21, 0x49, 0x03,
-0x48, 0x61, 0x02, 0x49, 0xc0, 0x46, 0xc8, 0x63, 0x00, 0x20, 0x70, 0x47,
-0xe8, 0x1a, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0x0f, 0x6b,
-0x69, 0x46, 0xff, 0xf7, 0x71, 0xff, 0xf8, 0x06, 0xc0, 0x0e, 0x01, 0xab,
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xa9, 0xfe, 0x01, 0x20,
-0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x00, 0x14, 0x40,
-0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7,
-0x5b, 0xff, 0xf8, 0x88, 0x04, 0xa9, 0x03, 0xf0, 0xc9, 0xff, 0x01, 0xab,
-0x58, 0x80, 0x01, 0xa8, 0x40, 0x88, 0x00, 0x28, 0x0f, 0xd0, 0x01, 0xa8,
-0x40, 0x88, 0x80, 0x08, 0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x04, 0x3b,
-0x58, 0x70, 0x04, 0x98, 0x01, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x40, 0x68,
-0xc0, 0x46, 0x03, 0x90, 0x05, 0xe0, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23,
-0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x04, 0x98, 0xc1, 0x1d, 0x01, 0x31,
-0x68, 0x46, 0xff, 0xf7, 0x75, 0xfe, 0x01, 0x20, 0x05, 0xb0, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x14, 0x4f, 0x39, 0x7b,
-0x00, 0x29, 0x20, 0xd1, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78,
-0x00, 0x29, 0x1a, 0xd1, 0x10, 0x49, 0x05, 0x22, 0x00, 0x92, 0x08, 0x22,
-0x00, 0xab, 0x5a, 0x80, 0x98, 0x80, 0x06, 0x20, 0x00, 0xab, 0x58, 0x70,
-0x00, 0x24, 0xdc, 0x80, 0x08, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x48, 0x68,
-0xc0, 0x46, 0x03, 0x90, 0x01, 0x20, 0x38, 0x73, 0x68, 0x46, 0x08, 0x31,
-0xff, 0xf7, 0x4c, 0xfe, 0x00, 0x28, 0x00, 0xd0, 0x3c, 0x73, 0x04, 0xb0,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80,
-0xa4, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46,
-0x38, 0x1c, 0xff, 0xf7, 0xf9, 0xfe, 0xba, 0x68, 0x0d, 0x4c, 0x0e, 0x48,
-0x00, 0x2a, 0x05, 0xd1, 0x0d, 0x49, 0xff, 0xf7, 0xe4, 0xfc, 0x00, 0x28,
-0x0c, 0xda, 0x05, 0xe0, 0xb9, 0x88, 0x0b, 0x4b, 0xff, 0xf7, 0xdf, 0xfc,
-0x00, 0x28, 0x05, 0xda, 0x01, 0xab, 0x5c, 0x80, 0x68, 0x46, 0x00, 0x21,
-0xff, 0xf7, 0x22, 0xfe, 0x00, 0x20, 0x04, 0xb0,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x0d, 0x76, 0x21, 0x40, 0xc1, 0xbd, 0x21, 0x40, 0x59, 0xbd, 0x21, 0x40,
-0x00, 0xb5, 0xc0, 0x88, 0x03, 0xf0, 0x2e, 0xff, 0x00, 0x20, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xe2, 0xfe, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0xff, 0xf7, 0xdd, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0x01, 0x1c, 0x02, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 0x18, 0x47,
-0xb0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0x08, 0x1c, 0x69, 0x46, 0xff, 0xf7,
-0xb5, 0xfe, 0x21, 0x48, 0xff, 0xf7, 0xa4, 0xfc, 0x04, 0x1c, 0x20, 0x4a,
-0x00, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xa0, 0xfc, 0x00, 0x28, 0x27, 0xd0,
-0x04, 0xa9, 0x1d, 0x4a, 0x38, 0x1c, 0xff, 0xf7, 0x99, 0xfc, 0x04, 0xa8,
-0x00, 0x23, 0x01, 0x2f, 0x06, 0xd1, 0x0c, 0xaa, 0x02, 0x32, 0x00, 0x21,
-0x13, 0x60, 0x01, 0x31, 0x10, 0x29, 0xfb, 0xd3, 0x01, 0x68, 0x04, 0x29,
-0x04, 0xd9, 0x89, 0x08, 0x03, 0x39, 0x89, 0x08, 0x01, 0x31, 0x00, 0xe0,
-0x19, 0x1c, 0x00, 0xab, 0x59, 0x70, 0x06, 0xa9, 0x09, 0x78, 0xc0, 0x46,
-0xd9, 0x80, 0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x98, 0xc0, 0x46,
-0x03, 0x90, 0x04, 0x33, 0x08, 0xad, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab,
-0x18, 0x70, 0x09, 0x49, 0x20, 0x1c, 0xff, 0xf7, 0x6e, 0xfc, 0x68, 0x46,
-0x29, 0x1c, 0xff, 0xf7, 0xb7, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xb0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x59, 0xb1, 0x21, 0x40,
-0x9d, 0xaf, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x01, 0x1c,
-0x02, 0x20, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0x01, 0x1c, 0x01, 0x20, 0xff, 0xf7, 0xa2, 0xff, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0x01, 0x1c, 0x01, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc,
-0x18, 0x47, 0xf0, 0xb5, 0xc7, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, 0x38, 0x1c,
-0x01, 0xa9, 0xff, 0xf7, 0x4d, 0xfe, 0x21, 0x48, 0xff, 0xf7, 0x3c, 0xfc,
-0x00, 0x90, 0x78, 0x78, 0x00, 0x01, 0xba, 0x68, 0x04, 0x30, 0xfc, 0x2a,
-0x25, 0xd8, 0xff, 0x23, 0x09, 0x33, 0x98, 0x42, 0x21, 0xd8, 0x19, 0x2c,
-0x1f, 0xd8, 0xfd, 0x88, 0xf8, 0x68, 0xc0, 0x46, 0x05, 0x90, 0xf9, 0x1d,
-0x09, 0x31, 0x06, 0xab, 0x00, 0x20, 0x7e, 0x78, 0x00, 0x2e, 0x0d, 0xdd,
-0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3,
-0x40, 0xc9, 0x40, 0xc3, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x7e, 0x78,
-0x86, 0x42, 0xf1, 0xdc, 0x20, 0x1c, 0x05, 0xa9, 0x2b, 0x1c, 0xff, 0xf7,
-0x21, 0xfc, 0x00, 0x28, 0x05, 0xd0, 0x01, 0xa8, 0x00, 0x78, 0x40, 0x23,
-0x18, 0x43, 0x01, 0xab, 0x18, 0x70, 0x07, 0x49, 0x00, 0x98, 0xff, 0xf7,
-0x06, 0xfc, 0x00, 0x21, 0x01, 0xa8, 0xff, 0xf7, 0x4f, 0xfd, 0x01, 0x20,
-0x47, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff,
-0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 0x1b, 0xfe, 0x08, 0xbc,
-0x18, 0x47, 0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0xfc, 0x88, 0x25, 0x4d,
-0x68, 0x68, 0x01, 0x30, 0x69, 0x46, 0x68, 0x60, 0x38, 0x1c, 0xff, 0xf7,
-0xf5, 0xfd, 0x10, 0x2c, 0x08, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23,
-0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x17, 0xe0,
-0x78, 0x78, 0x82, 0x00, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x20, 0xb9, 0x68,
-0x00, 0x2a, 0x15, 0xd9, 0x40, 0xcb, 0x0f, 0x1c,
-0x01, 0x31, 0xbe, 0x42, 0x0d, 0xd0, 0x00, 0xaa, 0x12, 0x78, 0x40, 0x23,
-0x1a, 0x43, 0x00, 0xab, 0x1a, 0x70, 0x04, 0x22, 0xda, 0x80, 0x02, 0x90,
-0x03, 0x91, 0x04, 0x33, 0x68, 0x46, 0x00, 0x21, 0x15, 0xe0, 0x01, 0x30,
-0x90, 0x42, 0xe9, 0xd3, 0x00, 0xab, 0x5c, 0x70, 0x02, 0x94, 0x69, 0x68,
-0xc0, 0x46, 0x03, 0x91, 0xa2, 0x00, 0x00, 0x20, 0x10, 0x33, 0x00, 0x2a,
-0x05, 0xd9, 0x0f, 0x1c, 0x80, 0xc3, 0x01, 0x30, 0x01, 0x31, 0x90, 0x42,
-0xf9, 0xd3, 0x68, 0x46, 0x04, 0xa9, 0xff, 0xf7, 0xf7, 0xfc, 0x01, 0x20,
-0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x9c, 0x03, 0x00, 0x80,
-0x90, 0xb4, 0x23, 0x48, 0x00, 0x68, 0x01, 0x21, 0x42, 0x09, 0x00, 0xd3,
-0x00, 0x21, 0x00, 0x27, 0x3a, 0x1c, 0x43, 0x0b, 0x00, 0xd2, 0x02, 0x22,
-0x11, 0x43, 0x1e, 0x4a, 0x20, 0x24, 0xd3, 0x68, 0x01, 0x2b, 0x2e, 0xd1,
-0x80, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 0x1b, 0x23,
-0xdb, 0x01, 0xd1, 0x18, 0x89, 0x8b, 0x09, 0x0b, 0x00, 0xd2, 0x04, 0x27,
-0x38, 0x43, 0xd1, 0x6f, 0x09, 0x68, 0x09, 0x0a, 0x07, 0xd2, 0xd1, 0x1d,
-0x79, 0x31, 0x09, 0x68, 0x09, 0x68, 0x09, 0x0a, 0x01, 0xd3, 0x08, 0x23,
-0x18, 0x43, 0xe3, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x89, 0x79, 0x03, 0x29,
-0x02, 0xd1, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 0x0b, 0x49, 0x09, 0x6a,
-0x10, 0x22, 0x4b, 0x0a, 0x00, 0xd2, 0x00, 0x22, 0x10, 0x43, 0x89, 0x07,
-0x89, 0x0f, 0x89, 0x01, 0x08, 0x43, 0x90, 0xbc, 0x70, 0x47, 0x40, 0x0c,
-0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 0xec, 0xe7, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0x68, 0x0e, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40,
-0xf0, 0xb5, 0x3a, 0x4c, 0x20, 0x1c, 0x04, 0xf0, 0x07, 0xfa, 0x39, 0x48,
-0xe3, 0x23, 0x1b, 0x01, 0xc7, 0x18, 0xb9, 0x79, 0x37, 0x4e, 0xc5, 0x1d,
-0x79, 0x35, 0x06, 0x29, 0x62, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, 0x5b, 0x00,
-0x9f, 0x44, 0x00, 0x1c, 0x03, 0x0e, 0x1e, 0x37, 0x4e, 0x55, 0x01, 0x20,
-0xb8, 0x71, 0x00, 0x20, 0xb0, 0x60, 0xff, 0xf7, 0x95, 0xff, 0x05, 0x23,
-0x98, 0x43, 0x00, 0xf0, 0x6f, 0xf8, 0x0c, 0xe0, 0xff, 0xf7, 0x8e, 0xff,
-0xc0, 0x08, 0x06, 0xd3, 0xb0, 0x68, 0x41, 0x1c, 0xb1, 0x60, 0x0a, 0x28,
-0x03, 0xd9, 0x04, 0x20, 0x00, 0xe0, 0x02, 0x20, 0xb8, 0x71, 0x64, 0x22,
-0x20, 0x1c, 0x2b, 0xe0, 0x06, 0x1c, 0xc0, 0x6f, 0x80, 0x23, 0x01, 0x68,
-0x19, 0x43, 0x01, 0x60, 0x03, 0x20, 0xb8, 0x71, 0x20, 0x1c, 0x20, 0x4a,
-0x00, 0x21, 0x04, 0xf0, 0x99, 0xf9, 0xf0, 0x6f, 0x04, 0x23, 0x01, 0x68,
-0x99, 0x43, 0x01, 0x60, 0x28, 0x68, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x05, 0x21, 0xb9, 0x71, 0x29, 0x68,
-0x04, 0x23, 0x0a, 0x68, 0x9a, 0x43, 0x0a, 0x60, 0xc0, 0x6f, 0x01, 0x68,
-0x19, 0x43, 0x01, 0x60, 0xff, 0xf7, 0x5a, 0xff, 0x08, 0x23, 0x18, 0x43,
-0x00, 0xf0, 0x34, 0xf8, 0x20, 0x1c, 0x10, 0x4a, 0x00, 0x21, 0x04, 0xf0,
-0x77, 0xf9, 0xe5, 0xe7, 0xff, 0xf7, 0x4e, 0xff, 0x04, 0x23, 0x18, 0x43,
-0x00, 0xf0, 0x28, 0xf8, 0xde, 0xe7, 0x00, 0x20, 0x29, 0x68, 0x60, 0x23,
-0x0a, 0x68, 0x9a, 0x43, 0x0a, 0x60, 0xff, 0xf7, 0xe3, 0xfa, 0xd5, 0xe7,
-0x06, 0x20, 0xb8, 0x71, 0xd2, 0xe7, 0x00, 0x00, 0xa9, 0x79, 0x21, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x9c, 0x03, 0x00, 0x80, 0x30, 0x75, 0x00, 0x00,
-0x10, 0x27, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x20,
-0x04, 0x49, 0xc0, 0x46, 0x88, 0x71, 0x04, 0x48, 0x01, 0x22, 0x00, 0x21,
-0x04, 0xf0, 0x4e, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x98, 0x1c, 0x00, 0x80,
-0xa9, 0x79, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, 0x31, 0x48, 0x00, 0x68,
-0x79, 0x08, 0x03, 0xd3, 0x10, 0x23, 0x01, 0x1c, 0x99, 0x43, 0x01, 0xe0,
-0x10, 0x21, 0x01, 0x43, 0x2d, 0x4c, 0xe2, 0x68, 0x01, 0x2a, 0x05, 0xd1,
-0x22, 0x79, 0x00, 0x2a, 0x02, 0xd0, 0x01, 0x23, 0x9b, 0x02, 0x19, 0x43,
-0x81, 0x42, 0x02, 0xd0, 0x01, 0x20, 0x00, 0x05, 0x01, 0x60, 0xe0, 0x68,
-0x01, 0x28, 0x20, 0xd1, 0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0x80, 0x8b,
-0xf9, 0x08, 0x04, 0xd3, 0x01, 0x23, 0xdb, 0x02, 0x01, 0x1c, 0x99, 0x43,
-0x01, 0xe0, 0x01, 0x21, 0xc9, 0x02, 0x81, 0x42, 0x02, 0xd0, 0x00, 0x20,
-0x02, 0xf0, 0x1a, 0xfb, 0x38, 0x09, 0x07, 0xd3, 0xe0, 0x6f, 0x80, 0x23,
-0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0xe0, 0x18, 0x00, 0x68, 0x00, 0xe0,
-0xe0, 0x6f, 0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x15, 0x48,
-0x01, 0x6a, 0x78, 0x09, 0x03, 0xd3, 0xff, 0x20, 0x01, 0x30, 0x08, 0x43,
-0x03, 0xe0, 0xff, 0x23, 0x08, 0x1c, 0x01, 0x33, 0x98, 0x43, 0x80, 0x08,
-0x80, 0x00, 0xba, 0x09, 0x92, 0x07, 0x92, 0x0f, 0x10, 0x43, 0x88, 0x42,
-0x02, 0xd0, 0x0c, 0x49, 0xc0, 0x46, 0x08, 0x62, 0xe1, 0x68, 0x01, 0x29,
-0x08, 0xd1, 0x79, 0x0a, 0x06, 0xd3, 0xff, 0x23, 0x04, 0x33, 0x18, 0x40,
-0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x8e, 0xff, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x68, 0x0e, 0x00, 0x80,
-0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x80, 0xb5, 0xff, 0xf7,
-0xb1, 0xfe, 0x80, 0x09, 0x1b, 0xd2, 0x0f, 0x48, 0xe3, 0x23, 0x1b, 0x01,
-0xc1, 0x18, 0x4a, 0x79, 0x00, 0x2a, 0x14, 0xd1, 0x01, 0x22, 0x4a, 0x71,
-0x00, 0x27, 0x80, 0x30, 0x00, 0x68, 0x60, 0x23, 0x01, 0x68, 0x99, 0x43,
-0x01, 0x60, 0x08, 0x48, 0x06, 0xe0, 0x02, 0x20, 0x02, 0xf0, 0x8c, 0xfc,
-0x07, 0x20, 0x02, 0xf0, 0x5b, 0xfc, 0x38, 0x1c, 0xff, 0xf7, 0x36, 0xfa,
-0xf5, 0xe7, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0xf4, 0x01, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7,
-0x37, 0xfc, 0xff, 0xf7, 0x85, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x08, 0x48,
-0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x48, 0x00, 0x6a, 0xc0, 0x46,
-0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x67, 0xfb, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40,
-0xc0, 0x00, 0x18, 0x40, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46,
-0x38, 0x1c, 0xff, 0xf7, 0x17, 0xfc, 0xf8, 0x88, 0xff, 0xf7, 0x42, 0xff,
-0xff, 0xf7, 0x62, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21,
-0xff, 0xf7, 0x4c, 0xfb, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 0xc7, 0x88, 0x69, 0x46, 0xff, 0xf7,
-0x01, 0xfc, 0x01, 0x24, 0x1a, 0x4b, 0x9f, 0x42, 0x0a, 0xd9, 0x00, 0xa8,
-0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20,
-0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x20, 0xe0, 0x14, 0x48, 0xff, 0xf7,
-0xe1, 0xf9, 0x05, 0x1c, 0x13, 0x4a, 0x38, 0x1c, 0x04, 0xa9, 0xff, 0xf7,
-0xdd, 0xf9, 0x12, 0x49, 0x28, 0x1c, 0xff, 0xf7, 0xd8, 0xf9, 0x01, 0x2f,
-0x06, 0xd1, 0x0c, 0xa9, 0x00, 0x20, 0x00, 0x22,
-0x0a, 0x60, 0x01, 0x30, 0x10, 0x28, 0xfb, 0xd3, 0x10, 0x20, 0x00, 0xab,
-0x58, 0x70, 0x04, 0x98, 0xc0, 0x46, 0x02, 0x90, 0x05, 0x98, 0xc0, 0x46,
-0x03, 0x90, 0x68, 0x46, 0x06, 0xa9, 0xff, 0xf7, 0x0f, 0xfb, 0x20, 0x1c,
-0x46, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0x01, 0x00, 0x00,
-0x24, 0x02, 0xff, 0xff, 0x9d, 0xaf, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff,
-0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7,
-0xbb, 0xfb, 0xfc, 0x88, 0x78, 0x78, 0x01, 0x25, 0x10, 0x28, 0x01, 0xd1,
-0x19, 0x2c, 0x09, 0xd9, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43,
-0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x04, 0x33, 0x27, 0xe0,
-0xb8, 0x68, 0xc0, 0x46, 0x04, 0x90, 0xf8, 0x68, 0xc0, 0x46, 0x05, 0x90,
-0x06, 0xaa, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x21, 0x78, 0x78, 0x00, 0x28,
-0x0d, 0xdd, 0x00, 0x20, 0x40, 0xcb, 0x40, 0xc2, 0x01, 0x30, 0x00, 0x04,
-0x00, 0x0c, 0x04, 0x28, 0xf8, 0xdb, 0x48, 0x1c, 0x01, 0x04, 0x09, 0x0c,
-0x78, 0x78, 0x88, 0x42, 0xf1, 0xdc, 0x0b, 0x48, 0xff, 0xf7, 0x7e, 0xf9,
-0x07, 0x1c, 0x0a, 0x4a, 0x20, 0x1c, 0x04, 0xa9, 0xff, 0xf7, 0x7a, 0xf9,
-0x08, 0x49, 0x38, 0x1c, 0xff, 0xf7, 0x75, 0xf9, 0x68, 0x46, 0x00, 0x21,
-0xff, 0xf7, 0xbe, 0xfa, 0x28, 0x1c, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 0xc5, 0xaf, 0x21, 0x40,
-0x3c, 0x02, 0xff, 0xff, 0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x00, 0x27,
-0xe6, 0x88, 0xa2, 0x68, 0x47, 0x49, 0x08, 0x79, 0x00, 0x28, 0x08, 0xd0,
-0x00, 0x2e, 0x01, 0xd0, 0x01, 0x2e, 0x01, 0xd1, 0x01, 0x27, 0x01, 0xe0,
-0x04, 0x2e, 0x00, 0xd1, 0x03, 0x26, 0x01, 0x25, 0x41, 0x48, 0x05, 0x2e,
-0x66, 0xd2, 0x02, 0xa3, 0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c,
-0x03, 0x06, 0x08, 0x0c, 0x10, 0x00, 0x05, 0x80, 0x00, 0x23, 0x03, 0xe0,
-0x05, 0x80, 0x05, 0xe0, 0x00, 0x23, 0x03, 0x80, 0x43, 0x80, 0x06, 0xe0,
-0x00, 0x23, 0x03, 0x80, 0x45, 0x80, 0x02, 0xe0, 0xff, 0x23, 0x01, 0x33,
-0x03, 0x80, 0xcb, 0x1d, 0x79, 0x33, 0x9e, 0x89, 0x01, 0x23, 0x5b, 0x02,
-0x9e, 0x42, 0x02, 0xdb, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xe0, 0x01, 0x22,
-0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x89, 0x88, 0xff, 0x23, 0xe1, 0x33,
-0x99, 0x43, 0x01, 0x23, 0x19, 0x43, 0x06, 0x88, 0xff, 0x33, 0x9e, 0x42,
-0x0d, 0xd1, 0xff, 0x20, 0xe1, 0x30, 0x08, 0x43, 0x00, 0x2a, 0x04, 0xd1,
-0x01, 0x23, 0x9b, 0x02, 0x98, 0x43, 0x01, 0x1c, 0x20, 0xe0, 0x01, 0x21,
-0x89, 0x02, 0x01, 0x43, 0x1c, 0xe0, 0x01, 0x2e, 0x0a, 0xd1, 0x40, 0x88,
-0x01, 0x28, 0x04, 0xd1, 0x60, 0x23, 0x19, 0x43, 0x00, 0x2a, 0x13, 0xd0,
-0x0c, 0xe0, 0x20, 0x23, 0x19, 0x43, 0x0f, 0xe0, 0x00, 0x2e, 0x0d, 0xd1,
-0x40, 0x88, 0x01, 0x28, 0x08, 0xd1, 0xff, 0x23, 0x81, 0x33, 0x19, 0x43,
-0x00, 0x2a, 0x05, 0xd0, 0x01, 0x23, 0x9b, 0x02, 0x19, 0x43, 0x01, 0xe0,
-0x80, 0x23, 0x19, 0x43, 0x04, 0x20, 0x02, 0xf0, 0x75, 0xf9, 0x09, 0x21,
-0x49, 0x02, 0x00, 0x20, 0x02, 0xf0, 0x70, 0xf9, 0x00, 0x2f, 0x02, 0xd1,
-0x00, 0x20, 0x12, 0xe0, 0xff, 0xe7, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7,
-0xef, 0xfa, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab,
-0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x04, 0x33,
-0xff, 0xf7, 0x22, 0xfa, 0x28, 0x1c, 0x04, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x88, 0x1c, 0x00, 0x80, 0xc0, 0x88, 0x51, 0x21, 0x89, 0x03, 0x08, 0x62,
-0x00, 0x20, 0x70, 0x47, 0x80, 0xb5, 0x16, 0x4f, 0xf8, 0x68, 0x01, 0x28,
-0x07, 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x40, 0x8a, 0x80, 0x21,
-0x01, 0x43, 0x1b, 0x20, 0x07, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18,
-0x80, 0x8b, 0x01, 0x21, 0x49, 0x03, 0x01, 0x43, 0x10, 0x20, 0x02, 0xf0,
-0x33, 0xf9, 0x01, 0x20, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 0x08, 0x80,
-0x48, 0x80, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x80, 0x8b, 0x01, 0x23,
-0x1b, 0x03, 0x98, 0x43, 0x41, 0x21, 0x09, 0x02, 0x01, 0x43, 0x00, 0x20,
-0x02, 0xf0, 0x20, 0xf9, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x17, 0x4f, 0xf8, 0x68, 0x01, 0x28,
-0x08, 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x40, 0x8a, 0x80, 0x23,
-0x98, 0x43, 0x01, 0x1c, 0x1b, 0x20, 0x08, 0xe0, 0x6d, 0x23, 0x5b, 0x01,
-0xf8, 0x18, 0x80, 0x8b, 0x01, 0x23, 0x5b, 0x03, 0x98, 0x43, 0x01, 0x1c,
-0x10, 0x20, 0x02, 0xf0, 0x01, 0xf9, 0xff, 0x20, 0x71, 0x23, 0x5b, 0x01,
-0xf9, 0x18, 0x01, 0x30, 0x08, 0x80, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18,
-0x80, 0x8b, 0x41, 0x23, 0x1b, 0x02, 0x98, 0x43, 0x09, 0x21, 0x49, 0x02,
-0x01, 0x43, 0x00, 0x20, 0x02, 0xf0, 0xee, 0xf8, 0x00, 0x20, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0,
-0x08, 0x49, 0xcf, 0x6a, 0x69, 0x46, 0xff, 0xf7, 0x69, 0xfa, 0xb8, 0x05,
-0x80, 0x0d, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7,
-0xa1, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x40, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x9f, 0x23, 0x18, 0x40, 0x05, 0x49,
-0xc9, 0x6a, 0x1b, 0x23, 0x5b, 0x01, 0x19, 0x40, 0x08, 0x43, 0x03, 0x49,
-0xc0, 0x46, 0xc8, 0x62, 0x00, 0x20, 0x70, 0x47, 0x40, 0x00, 0x14, 0x40,
-0x40, 0x00, 0x14, 0x00, 0x80, 0xb5, 0x84, 0xb0, 0x0d, 0x49, 0x0f, 0x6a,
-0x01, 0x2f, 0x01, 0xd1, 0xff, 0x03, 0x07, 0xe0, 0x02, 0x2f, 0x01, 0xd1,
-0x3f, 0x03, 0x03, 0xe0, 0x00, 0x2f, 0x01, 0xd1, 0x01, 0x27, 0xff, 0x02,
-0x69, 0x46, 0xff, 0xf7, 0x35, 0xfa, 0x01, 0xab, 0x5f, 0x80, 0x68, 0x46,
-0x00, 0x21, 0xff, 0xf7, 0x6f, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x14, 0x40, 0xc2, 0x88, 0xa1, 0x20,
-0x40, 0x03, 0x00, 0x21, 0x01, 0x23, 0x5b, 0x03, 0x9a, 0x42, 0x01, 0xd1,
-0x02, 0x22, 0x04, 0xe0, 0x01, 0x23, 0xdb, 0x03, 0x9a, 0x42, 0x02, 0xd1,
-0x01, 0x22, 0x02, 0x62, 0x00, 0xe0, 0x01, 0x62, 0x08, 0x1c, 0x70, 0x47,
-0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x02, 0xf0, 0x9f, 0xf8, 0x69, 0x46,
-0x04, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x0a, 0xfa, 0x01, 0xab, 0x5c, 0x80,
-0x09, 0x4f, 0xf8, 0x6d, 0xc0, 0x46, 0x02, 0x90, 0x68, 0x46, 0x00, 0x21,
-0xff, 0xf7, 0x40, 0xf9, 0xf8, 0x6d, 0xc0, 0x07, 0xc0, 0x0f, 0x05, 0x49,
-0xc0, 0x46, 0xc8, 0x62, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 0x68, 0x1c, 0x00, 0x80,
-0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x00, 0x20, 0x70, 0x47,
-0x80, 0x00, 0x14, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7,
-0xe3, 0xf9, 0x06, 0x48, 0xc0, 0x68, 0x01, 0xab,
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x1b, 0xf9, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40,
-0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x70, 0x47,
-0x80, 0x00, 0x14, 0x00, 0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0x87, 0x68,
-0xff, 0xf7, 0xc6, 0xf9, 0x20, 0x2f, 0x07, 0xd2, 0x78, 0x00, 0x0c, 0x49,
-0x40, 0x18, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x80, 0x8b, 0x06, 0xe0,
-0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70,
-0x02, 0x20, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7,
-0xef, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x82, 0x68,
-0x20, 0x2a, 0x04, 0xd2, 0x10, 0x1c, 0x02, 0xf0, 0x17, 0xf8, 0x00, 0x20,
-0x10, 0xe0, 0x69, 0x46, 0xff, 0xf7, 0x9a, 0xf9, 0x00, 0xa8, 0x00, 0x78,
-0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80,
-0x68, 0x46, 0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0xcd, 0xf8, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0xc7, 0x88,
-0x69, 0x46, 0xff, 0xf7, 0x83, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0x72, 0xff,
-0x02, 0x20, 0x39, 0x1c, 0x02, 0xf0, 0xf2, 0xff, 0x00, 0x28, 0x06, 0xd0,
-0x02, 0x20, 0x39, 0x1c, 0x02, 0xf0, 0x36, 0xff, 0x01, 0xab, 0x58, 0x80,
-0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 0x20, 0x1c,
-0xfe, 0xf7, 0x5f, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xa8, 0xf8,
-0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0xb0, 0xb5, 0x84, 0xb0,
-0xc7, 0x88, 0x69, 0x46, 0x84, 0x68, 0xff, 0xf7, 0x57, 0xf9, 0x10, 0x48,
-0xfe, 0xf7, 0x46, 0xff, 0x0f, 0x4a, 0x02, 0x20, 0x39, 0x1c, 0xfe, 0xf7,
-0x43, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x0d, 0x4b, 0x02, 0x20, 0x39, 0x1c,
-0x22, 0x1c, 0xfe, 0xf7, 0x3c, 0xff, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab,
-0x18, 0x70, 0x09, 0x49, 0x28, 0x1c, 0xfe, 0xf7, 0x32, 0xff, 0x68, 0x46,
-0x00, 0x21, 0xff, 0xf7, 0x7b, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x59, 0xb1, 0x21, 0x40,
-0x59, 0xb0, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7,
-0x43, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x80, 0xb4,
-0xc2, 0x88, 0x19, 0x4b, 0xa1, 0x21, 0x49, 0x03, 0x00, 0x2a, 0x03, 0xd1,
-0x18, 0x6b, 0x10, 0x23, 0x98, 0x43, 0x04, 0xe0, 0x01, 0x2a, 0x04, 0xd1,
-0x18, 0x6b, 0x10, 0x23, 0x18, 0x43, 0x48, 0x61, 0x1f, 0xe0, 0x02, 0x2a,
-0x1d, 0xd1, 0xc2, 0x68, 0x87, 0x68, 0x00, 0x20, 0x3b, 0x1c, 0xc3, 0x40,
-0xdb, 0x07, 0xdb, 0x0f, 0x9b, 0x02, 0x03, 0x43, 0x0b, 0x61, 0x01, 0x30,
-0x00, 0x04, 0x00, 0x0c, 0x20, 0x28, 0xf3, 0xdb, 0x00, 0x20, 0x13, 0x1c,
-0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, 0x9b, 0x02, 0xc7, 0x1d, 0x19, 0x37,
-0x3b, 0x43, 0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x20, 0x28,
-0xf1, 0xdb, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x40,
-0x80, 0xb4, 0xc2, 0x88, 0x81, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x10, 0x43,
-0x02, 0x04, 0x12, 0x0c, 0x0c, 0x48, 0xc0, 0x46, 0x02, 0x60, 0x0c, 0x4b,
-0xc0, 0x46, 0x1a, 0x80, 0x0a, 0x0c, 0x17, 0x02,
-0x12, 0x12, 0x3a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x60, 0x5a, 0x80,
-0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x0a, 0x11, 0x43, 0x09, 0x04,
-0x09, 0x0c, 0x81, 0x60, 0x99, 0x80, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47,
-0x40, 0x00, 0x14, 0x00, 0x28, 0x1b, 0x00, 0x80, 0xb0, 0xb5, 0x84, 0xb0,
-0x13, 0x49, 0x0a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x13, 0x02, 0x12, 0x12,
-0x13, 0x43, 0x4a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x1f, 0x1c, 0x13, 0x02,
-0x12, 0x12, 0x13, 0x43, 0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02,
-0x09, 0x12, 0x11, 0x43, 0x0c, 0x04, 0x24, 0x0c, 0x69, 0x46, 0x1d, 0x1c,
-0xff, 0xf7, 0xae, 0xf8, 0x01, 0xab, 0x5f, 0x80, 0x28, 0x04, 0x20, 0x43,
-0x02, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xe5, 0xff, 0x01, 0x20,
-0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40,
-0xc1, 0x88, 0x82, 0x68, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x00, 0x04,
-0x00, 0x0c, 0x0a, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x10, 0x0c, 0x03, 0x02,
-0x00, 0x12, 0x18, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x61, 0x10, 0x04,
-0x00, 0x0c, 0x02, 0x02, 0x00, 0x0a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x0c,
-0x48, 0x61, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00,
-0x90, 0xb5, 0x84, 0xb0, 0x16, 0x4b, 0xd9, 0x68, 0x09, 0x04, 0x09, 0x0c,
-0x0a, 0x02, 0x09, 0x12, 0x11, 0x43, 0x1a, 0x69, 0x12, 0x04, 0x12, 0x0c,
-0x17, 0x02, 0x12, 0x12, 0x3a, 0x43, 0x5b, 0x69, 0x1b, 0x04, 0x1b, 0x0c,
-0x1f, 0x02, 0x1b, 0x12, 0x3b, 0x43, 0x1f, 0x04, 0x3f, 0x0c, 0x05, 0x23,
-0x00, 0x93, 0x84, 0x88, 0x01, 0xab, 0x1c, 0x80, 0x00, 0x24, 0x04, 0x3b,
-0x5c, 0x70, 0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xd9, 0x80, 0x10, 0x04,
-0x38, 0x43, 0x02, 0x90, 0x03, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7,
-0x95, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x40, 0x00, 0x14, 0x40, 0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x8a, 0x6a,
-0x05, 0x21, 0x00, 0x91, 0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21,
-0x04, 0x3b, 0x59, 0x70, 0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80,
-0x02, 0x91, 0x03, 0x91, 0x68, 0x46, 0xfe, 0xf7, 0x79, 0xff, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40,
-0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x88, 0x62, 0x00, 0x20, 0x70, 0x47,
-0xc0, 0x00, 0x14, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x0a, 0x6a,
-0x05, 0x21, 0x00, 0x91, 0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21,
-0x04, 0x3b, 0x59, 0x70, 0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80,
-0x02, 0x91, 0x03, 0x91, 0x68, 0x46, 0xfe, 0xf7, 0x55, 0xff, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40,
-0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47,
-0xc0, 0x00, 0x14, 0x00, 0x00, 0xb5, 0xc0, 0x88, 0x02, 0x49, 0xfe, 0xf7,
-0xf4, 0xfd, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x75, 0x02, 0xff, 0xff,
-0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7, 0xf7, 0xff, 0x06, 0x48,
-0x00, 0x6b, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7,
-0x2f, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0xfd, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xf8, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xf3, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0x10, 0x48, 0xfe, 0xf7, 0xc6, 0xfd,
-0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x21,
-0x0c, 0x48, 0xc0, 0x46, 0x01, 0x71, 0x0c, 0x48, 0x02, 0x68, 0x52, 0x0c,
-0x05, 0xd2, 0x02, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a,
-0x03, 0xd3, 0x08, 0x48, 0xc0, 0x46, 0xc7, 0x60, 0x02, 0xe0, 0x07, 0x48,
-0xc0, 0x46, 0x07, 0x64, 0x08, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xd5, 0x94, 0x21, 0x40, 0x28, 0x0f, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40,
-0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x20,
-0x03, 0x49, 0xc0, 0x46, 0x08, 0x72, 0x12, 0x20, 0xff, 0xf7, 0xcb, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x88, 0x1c, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x20,
-0x03, 0x49, 0xc0, 0x46, 0x48, 0x72, 0x15, 0x20, 0xff, 0xf7, 0xbf, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x88, 0x1c, 0x00, 0x80, 0x00, 0xb5, 0x01, 0xf0,
-0xf9, 0xff, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0,
-0x07, 0x1c, 0xf8, 0x88, 0x02, 0xf0, 0xfe, 0xf8, 0x00, 0x28, 0x0c, 0xd1,
-0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x82, 0xff, 0x06, 0x48, 0x01, 0xab,
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xbb, 0xfe, 0x01, 0x20,
-0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7,
-0x6d, 0xff, 0x01, 0x27, 0x01, 0xab, 0x5f, 0x80, 0x09, 0x48, 0x81, 0x89,
-0x09, 0x04, 0xc2, 0x89, 0x11, 0x43, 0x02, 0x91, 0x81, 0x88, 0x09, 0x04,
-0xc0, 0x88, 0x08, 0x43, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7,
-0x9b, 0xfe, 0x38, 0x1c, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x4c, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0x69, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x64, 0xff, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0xfe, 0xf7, 0x5f, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0xfe, 0xf7, 0x5a, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7,
-0x55, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x50, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x4b, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x46, 0xff, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0xfe, 0xf7, 0x41, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0xfe, 0xf7, 0x3c, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7,
-0x37, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x32, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x8c, 0xb0, 0x08, 0xa9, 0xfe, 0xf7,
-0x13, 0xff, 0x69, 0x46, 0x08, 0xa8, 0x02, 0xf0, 0xa9, 0xff, 0x02, 0x20,
-0x08, 0xab, 0x58, 0x70, 0x69, 0x46, 0x08, 0xa8, 0xfe, 0xf7, 0x48, 0xfe,
-0x01, 0x20, 0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7,
-0x19, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c,
-0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xf8, 0xfe, 0xfa, 0x88, 0x12, 0x49,
-0x01, 0x24, 0xc8, 0x1d, 0x89, 0x30, 0x00, 0x2a, 0x0f, 0xd0, 0x04, 0x70,
-0x44, 0x70, 0xb8, 0x68, 0x00, 0x0c, 0x80, 0x31, 0xc8, 0x82, 0xb8, 0x68,
-0xc0, 0x46, 0x08, 0x83, 0xf8, 0x68, 0x00, 0x0c, 0x48, 0x83, 0xf8, 0x68,
-0xc0, 0x46, 0x88, 0x83, 0x02, 0xe0, 0x00, 0x21,
-0x01, 0x70, 0x41, 0x70, 0x06, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46,
-0x00, 0x21, 0xfe, 0xf7, 0x17, 0xfe, 0x20, 0x1c, 0x04, 0xb0, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00,
-0x00, 0xb5, 0xfe, 0xf7, 0xe3, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0xfe, 0xf7, 0xde, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7,
-0xd9, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xd4, 0xfe,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xcf, 0xfe, 0x08, 0xbc,
-0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c,
-0xfe, 0xf7, 0xae, 0xfe, 0xf8, 0x88, 0x03, 0x24, 0xe4, 0x04, 0x04, 0x43,
-0x03, 0x23, 0xdb, 0x04, 0x9c, 0x42, 0x02, 0xd3, 0x0f, 0x4b, 0x9c, 0x42,
-0x06, 0xd9, 0x0f, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21,
-0xfe, 0xf7, 0xdc, 0xfd, 0x01, 0x20, 0x80, 0x07, 0x20, 0x43, 0x00, 0x68,
-0x00, 0x21, 0x00, 0xab, 0x59, 0x70, 0xfa, 0x88, 0xc0, 0x46, 0xda, 0x80,
-0x02, 0x90, 0x03, 0x91, 0x68, 0x46, 0x04, 0x33, 0xfe, 0xf7, 0xcc, 0xfd,
-0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x84, 0xb0,
-0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x7b, 0xfe, 0xf8, 0x88,
-0x03, 0x23, 0xdb, 0x04, 0x18, 0x43, 0x98, 0x42, 0x02, 0xd3, 0x0a, 0x4b,
-0x98, 0x42, 0x08, 0xd9, 0x09, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46,
-0x00, 0x21, 0xfe, 0xf7, 0xab, 0xfd, 0x01, 0x20, 0x03, 0xe0, 0xb9, 0x68,
-0xc0, 0x46, 0x01, 0x60, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x80, 0xb5, 0x86, 0xb0, 0x02, 0xa9, 0xfe, 0xf7, 0x57, 0xfe, 0x01, 0x27,
-0x02, 0xab, 0x5f, 0x70, 0x00, 0x20, 0xd8, 0x80, 0x0a, 0x48, 0x41, 0x68,
-0xc0, 0x46, 0x04, 0x91, 0x81, 0x68, 0xc0, 0x46, 0x05, 0x91, 0xc1, 0x68,
-0xc0, 0x46, 0x00, 0x91, 0x40, 0x69, 0xc0, 0x46, 0x01, 0x90, 0x69, 0x46,
-0x02, 0xa8, 0xfe, 0xf7, 0x81, 0xfd, 0x38, 0x1c, 0x06, 0xb0, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x19, 0x00, 0x80, 0x00, 0xb5, 0xc1, 0x68,
-0x80, 0x68, 0xfe, 0xf7, 0x47, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c,
-0x68, 0x46, 0x50, 0x21, 0xfe, 0xf7, 0x36, 0xfe, 0x01, 0xab, 0x5c, 0x80,
-0x02, 0x97, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x61, 0xfd, 0x04, 0xb0,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c,
-0x68, 0x46, 0x51, 0x21, 0xfe, 0xf7, 0x24, 0xfe, 0x01, 0xab, 0x5f, 0x80,
-0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x50, 0xfd, 0x04, 0xb0, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47,
-0x90, 0xb5, 0x84, 0xb0, 0x00, 0x27, 0x12, 0x49, 0x09, 0x68, 0x12, 0x4a,
-0x12, 0x6b, 0x10, 0x23, 0x1a, 0x40, 0x01, 0x24, 0x00, 0x2a, 0x00, 0xd0,
-0x01, 0x27, 0x8a, 0x0c, 0x03, 0xd3, 0x3a, 0x04, 0x12, 0x0c, 0x02, 0x27,
-0x17, 0x43, 0xc9, 0x0c, 0x03, 0xd3, 0x39, 0x04, 0x09, 0x0c, 0x04, 0x27,
-0x0f, 0x43, 0x69, 0x46, 0xfe, 0xf7, 0xec, 0xfd, 0x01, 0xab, 0x5f, 0x80,
-0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x26, 0xfd, 0x20, 0x1c, 0x04, 0xb0,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x40, 0x00, 0xb5, 0x84, 0xb0,
-0x69, 0x46, 0xfe, 0xf7, 0xd7, 0xfd, 0x06, 0x48, 0xc0, 0x6d, 0x01, 0xab,
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x0f, 0xfd, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80,
-0x00, 0xb5, 0xfe, 0xf7, 0xdd, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47,
-0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47,
-0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47,
-0x00, 0xb5, 0xfe, 0xf7, 0xcb, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x80, 0xb5, 0x85, 0xb0, 0x01, 0xa9, 0xfe, 0xf7, 0xab, 0xfd, 0x00, 0x20,
-0x01, 0xab, 0x58, 0x70, 0x0c, 0x49, 0xc9, 0x68, 0x01, 0x27, 0x01, 0x29,
-0x02, 0xd1, 0x03, 0x97, 0x04, 0x97, 0x01, 0xe0, 0x03, 0x97, 0x04, 0x90,
-0x68, 0x46, 0x01, 0xf0, 0x33, 0xfd, 0x02, 0xab, 0x00, 0x98, 0xc0, 0x46,
-0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfe, 0xf7, 0xd3, 0xfc, 0x38, 0x1c,
-0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x70, 0x47, 0x04, 0x49, 0x00, 0x20, 0x00, 0x22, 0x0a, 0x70, 0x01, 0x30,
-0x01, 0x31, 0x68, 0x28, 0xfa, 0xd3, 0x70, 0x47, 0xa0, 0x82, 0x20, 0x40,
-0x00, 0x22, 0x88, 0x42, 0x03, 0xd3, 0x40, 0x1a, 0x01, 0x32, 0x88, 0x42,
-0xfb, 0xd2, 0x10, 0x1c, 0x70, 0x47, 0x88, 0x42, 0x02, 0xd3, 0x40, 0x1a,
-0x88, 0x42, 0xfc, 0xd2, 0x70, 0x47, 0x90, 0xb4, 0x01, 0x1c, 0xff, 0x27,
-0x04, 0x29, 0x27, 0xda, 0x00, 0x20, 0x14, 0x4a, 0x43, 0x00, 0x1b, 0x18,
-0xdb, 0x00, 0xd4, 0x58, 0x63, 0x0c, 0x1a, 0xd2, 0x4b, 0x00, 0x59, 0x18,
-0xc9, 0x00, 0x57, 0x58, 0x43, 0x00, 0x1b, 0x18, 0xdb, 0x00, 0xd7, 0x50,
-0x89, 0x18, 0x9a, 0x18, 0x4f, 0x68, 0xc0, 0x46, 0x57, 0x60, 0x8b, 0x68,
-0xc0, 0x46, 0x93, 0x60, 0x0b, 0x69, 0xc0, 0x46, 0x13, 0x61, 0x4b, 0x69,
-0xc0, 0x46, 0x53, 0x61, 0xc9, 0x68, 0xc0, 0x46, 0xd1, 0x60, 0x90, 0xbc,
-0x70, 0x47, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x04, 0x28, 0xd9, 0xdb,
-0x38, 0x1c, 0xf6, 0xe7, 0x40, 0xab, 0x20, 0x40, 0xf7, 0xb5, 0xc4, 0xb0,
-0x04, 0x1c, 0x00, 0x20, 0x46, 0x9a, 0x11, 0x21, 0x11, 0x40, 0x6e, 0xd0,
-0x00, 0x27, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x57, 0x4a, 0x51, 0x58,
-0x49, 0x0c, 0x03, 0xd2, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x04, 0xe0,
-0x79, 0x1c, 0x0f, 0x06, 0x3f, 0x0e, 0x04, 0x2f, 0xef, 0xdb, 0x00, 0x28,
-0x5b, 0xd0, 0x00, 0x26, 0x00, 0x22, 0x00, 0x92, 0x40, 0x23, 0x00, 0x21,
-0x00, 0x20, 0x02, 0xaa, 0x00, 0xf0, 0x88, 0xfa, 0x04, 0xa9, 0x00, 0x20,
-0x82, 0x00, 0x8a, 0x58, 0x12, 0x06, 0x12, 0x0e, 0xa2, 0x42, 0x03, 0xd1,
-0x72, 0x1c, 0x16, 0x06, 0x36, 0x0e, 0x04, 0xe0, 0x01, 0x30, 0x00, 0x06,
-0x00, 0x0e, 0x10, 0x28, 0xf0, 0xdb, 0x00, 0x2e, 0x3d, 0xd0, 0x04, 0x2c,
-0x3e, 0xd1, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x80, 0x0d, 0x00, 0x22,
-0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x02, 0xaa, 0x00, 0xf0, 0x68, 0xfa,
-0x00, 0x21, 0x01, 0x91, 0x02, 0xa8, 0x05, 0x99, 0x49, 0x0c, 0x89, 0x05,
-0x29, 0xd0, 0xc1, 0x68, 0x0a, 0x06, 0x12, 0x0e, 0x45, 0x9b, 0x9a, 0x42,
-0x11, 0xd1, 0xc0, 0x68, 0x40, 0x01, 0x86, 0x0d, 0x00, 0x22, 0x00, 0x92,
-0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0, 0x50, 0xfa,
-0x01, 0x99, 0x02, 0x9d, 0x48, 0x1c, 0x01, 0x06,
-0x09, 0x0e, 0x01, 0x91, 0x0e, 0xe0, 0x48, 0x01, 0x86, 0x0d, 0x00, 0x22,
-0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0,
-0x3f, 0xfa, 0x02, 0xa8, 0x05, 0x99, 0x49, 0x0c, 0x89, 0x05, 0xd8, 0xd1,
-0x01, 0x99, 0x00, 0x29, 0x0f, 0xd1, 0xff, 0x20, 0x3d, 0xe0, 0x40, 0xe0,
-0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x86, 0x0d, 0x00, 0x22, 0x00, 0x92,
-0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0, 0x28, 0xfa,
-0x02, 0x9d, 0x01, 0x20, 0x00, 0x04, 0x46, 0x9a, 0x10, 0x43, 0x79, 0x00,
-0xc9, 0x19, 0xc9, 0x00, 0x17, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0x30, 0x1c,
-0x8e, 0x18, 0x70, 0x60, 0x10, 0x20, 0x04, 0x2c, 0x00, 0xd0, 0x0c, 0x20,
-0x04, 0x1c, 0xb0, 0x60, 0x00, 0x20, 0x20, 0x21, 0x46, 0x9a, 0x11, 0x40,
-0x20, 0x29, 0x00, 0xd0, 0x28, 0x1c, 0x30, 0x61, 0x28, 0x19, 0xff, 0x21,
-0xff, 0x30, 0x08, 0x30, 0x09, 0x31, 0xff, 0xf7, 0x19, 0xff, 0x43, 0x01,
-0x18, 0x18, 0xc0, 0x00, 0x00, 0x1b, 0x70, 0x61, 0x00, 0x20, 0x50, 0x21,
-0x46, 0x9a, 0x11, 0x40, 0x50, 0x29, 0x00, 0xd1, 0x28, 0x1c, 0xf0, 0x60,
-0x38, 0x1c, 0x47, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0x20,
-0xf9, 0xe7, 0x00, 0x00, 0x40, 0xab, 0x20, 0x40, 0x80, 0xb4, 0x00, 0x23,
-0x00, 0x22, 0x00, 0x29, 0x06, 0xd9, 0x87, 0x5c, 0x7b, 0x40, 0x1b, 0x06,
-0x1b, 0x0e, 0x01, 0x32, 0x8a, 0x42, 0xf8, 0xd3, 0xd8, 0x43, 0x00, 0x06,
-0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xc6, 0xb0, 0x04, 0x28,
-0x07, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 0x45, 0x91, 0x41, 0x4a,
-0x51, 0x58, 0x4b, 0x0c, 0x02, 0xd2, 0x00, 0x20, 0xc0, 0x43, 0x76, 0xe0,
-0x01, 0x23, 0x5b, 0x04, 0x19, 0x40, 0x43, 0x00, 0x18, 0x18, 0xc0, 0x00,
-0x3a, 0x4a, 0x14, 0x18, 0x00, 0x29, 0x61, 0xd0, 0x00, 0x21, 0x02, 0x91,
-0x20, 0x69, 0xa1, 0x68, 0x45, 0x18, 0x30, 0xd0, 0xff, 0x21, 0x68, 0x1e,
-0x09, 0x31, 0xff, 0xf7, 0xcd, 0xfe, 0x61, 0x68, 0x40, 0x18, 0x01, 0x90,
-0x01, 0x98, 0x81, 0x42, 0x02, 0xd1, 0xa6, 0x68, 0xaf, 0x1b, 0x09, 0xe0,
-0x00, 0x26, 0xff, 0x21, 0x28, 0x1c, 0x09, 0x31, 0xff, 0xf7, 0xc7, 0xfe,
-0x07, 0x1c, 0x01, 0xd1, 0xff, 0x27, 0x09, 0x37, 0x00, 0x22, 0x00, 0x92,
-0x01, 0x98, 0x31, 0x1c, 0x03, 0xaa, 0x3b, 0x1c, 0x00, 0xf0, 0x9e, 0xf9,
-0x03, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 0xac, 0xff, 0xc0, 0x43, 0x02, 0x99,
-0x48, 0x40, 0x01, 0x06, 0x09, 0x0e, 0x02, 0x91, 0xed, 0x1b, 0xa0, 0x68,
-0xa8, 0x42, 0x00, 0xd1, 0x00, 0x25, 0x00, 0x2d, 0xce, 0xd8, 0x02, 0x99,
-0xcf, 0x43, 0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68,
-0x03, 0xaa, 0x00, 0xf0, 0x83, 0xf9, 0x20, 0x69, 0xc0, 0x46, 0x03, 0x90,
-0x05, 0x98, 0x00, 0x0a, 0x00, 0x02, 0x39, 0x06, 0x09, 0x0e, 0x08, 0x43,
-0x05, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x98, 0x43, 0x05, 0x90, 0x0c, 0x21,
-0x03, 0xa8, 0xff, 0xf7, 0x83, 0xff, 0xff, 0x23, 0x1b, 0x02, 0x05, 0x99,
-0x99, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x02, 0x08, 0x43, 0x05, 0x90,
-0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, 0xca, 0xf9,
-0x00, 0x20, 0x45, 0x99, 0x06, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0xc1, 0x43,
-0x61, 0x60, 0xa1, 0x60, 0xe1, 0x60, 0x21, 0x61, 0x61, 0x61, 0x46, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x40, 0xab, 0x20, 0x40,
-0xb0, 0xb4, 0x4c, 0x42, 0x00, 0x29, 0x00, 0xdb,
-0x0c, 0x1c, 0x00, 0x27, 0xff, 0x43, 0x04, 0x28, 0x21, 0xda, 0x12, 0x4d,
-0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 0x40, 0x19, 0x01, 0x2a, 0x05, 0xd0,
-0x02, 0x2a, 0x09, 0xd0, 0x03, 0x2a, 0x16, 0xd1, 0x01, 0x69, 0x0b, 0xe0,
-0x00, 0x29, 0x12, 0xdb, 0x02, 0x69, 0x8a, 0x42, 0x0f, 0xd3, 0x05, 0xe0,
-0x00, 0x29, 0x07, 0xda, 0xc1, 0x68, 0xa1, 0x42, 0x09, 0xd3, 0x09, 0x1b,
-0xc1, 0x60, 0xc0, 0x68, 0xb0, 0xbc, 0x70, 0x47, 0xc1, 0x68, 0x09, 0x19,
-0x02, 0x69, 0x91, 0x42, 0xf6, 0xd9, 0x38, 0x1c, 0xf6, 0xe7, 0x00, 0x00,
-0x40, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 0x17, 0x1c, 0x0d, 0x1c,
-0x00, 0x21, 0x02, 0x91, 0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x2c, 0x49,
-0x8b, 0x58, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x93, 0x00, 0x23, 0xdb, 0x43,
-0x04, 0x28, 0x02, 0xda, 0x01, 0x98, 0x40, 0x08, 0x01, 0xd2, 0x18, 0x1c,
-0x46, 0xe0, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 0x21, 0x69, 0x8a, 0x42,
-0x00, 0xd9, 0x0f, 0x1a, 0x00, 0x2f, 0x3c, 0xd9, 0xa0, 0x68, 0xe1, 0x68,
-0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0x0d, 0xfe, 0x61, 0x68,
-0x46, 0x18, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31,
-0xff, 0xf7, 0x0d, 0xfe, 0xc2, 0x19, 0xff, 0x21, 0x09, 0x31, 0x8a, 0x42,
-0x14, 0xd9, 0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x0b, 0x1a, 0x03, 0x93,
-0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 0xe1, 0xf8, 0xe0, 0x68,
-0x03, 0x9b, 0xc0, 0x18, 0xe0, 0x60, 0x03, 0x9b, 0x5d, 0x19, 0xff, 0x1a,
-0x02, 0x98, 0x18, 0x18, 0x02, 0x90, 0x10, 0xe0, 0x01, 0x9a, 0xc0, 0x46,
-0x00, 0x92, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x00, 0xf0,
-0xcd, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 0xe0, 0x60, 0x02, 0x98,
-0xc0, 0x19, 0x02, 0x90, 0x00, 0x27, 0x00, 0x2f, 0xc2, 0xd8, 0x02, 0x98,
-0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0xab, 0x20, 0x40,
-0xf0, 0xb5, 0x83, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, 0x00, 0x21, 0x01, 0x91,
-0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x02, 0x92, 0x30, 0x49, 0x8a, 0x58,
-0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0xe4, 0x43, 0x04, 0x28, 0x01, 0xda,
-0x50, 0x09, 0x01, 0xd2, 0x20, 0x1c, 0x51, 0xe0, 0x02, 0x9a, 0x54, 0x18,
-0xe0, 0x68, 0xc2, 0x19, 0x60, 0x69, 0x82, 0x42, 0x01, 0xd9, 0x22, 0x69,
-0x87, 0x1a, 0x00, 0x2f, 0x45, 0xd9, 0x25, 0x4e, 0xa0, 0x68, 0xe1, 0x68,
-0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0xa7, 0xfd, 0x61, 0x68,
-0x40, 0x18, 0x00, 0x90, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21,
-0x09, 0x31, 0xff, 0xf7, 0xa6, 0xfd, 0x02, 0x9a, 0xb1, 0x58, 0x01, 0x23,
-0x5b, 0x04, 0x19, 0x43, 0xb1, 0x50, 0xc1, 0x19, 0xff, 0x22, 0x09, 0x32,
-0x91, 0x42, 0x13, 0xd9, 0x13, 0x1a, 0x01, 0x1c, 0x00, 0x98, 0x2a, 0x1c,
-0x1e, 0x1c, 0x00, 0xf0, 0xdf, 0xf8, 0xe0, 0x68, 0x80, 0x19, 0x75, 0x19,
-0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0xbf, 0x1b,
-0x01, 0x98, 0x30, 0x18, 0x01, 0x90, 0x12, 0xe0, 0x01, 0x1c, 0x00, 0x9e,
-0x30, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x00, 0xf0, 0xcb, 0xf8, 0xe0, 0x68,
-0xc0, 0x19, 0xed, 0x19, 0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9,
-0x20, 0x61, 0x01, 0x98, 0xc0, 0x19, 0x01, 0x90, 0x00, 0x27, 0x00, 0x2f,
-0xb9, 0xd8, 0x01, 0x98, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x40, 0xab, 0x20, 0x40, 0xb0, 0xb5, 0xc3, 0xb0,
-0x0c, 0x1c, 0x00, 0x27, 0xfa, 0x43, 0x04, 0x28, 0x06, 0xda, 0x41, 0x00,
-0x09, 0x18, 0xc9, 0x00, 0x14, 0x48, 0x45, 0x58, 0x6b, 0x0c, 0x04, 0xd2,
-0x10, 0x1c, 0x43, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x62, 0x09,
-0x1b, 0xd3, 0x00, 0x22, 0x00, 0x92, 0x08, 0x18, 0x40, 0x68, 0x0c, 0x23,
-0x00, 0x21, 0x01, 0xaa, 0x00, 0xf0, 0x30, 0xf8, 0x11, 0x2c, 0x0d, 0xd0,
-0x12, 0x2c, 0x0d, 0xd0, 0x13, 0x2c, 0x05, 0xd0, 0x14, 0x2c, 0x0a, 0xd1,
-0x03, 0x98, 0x00, 0x04, 0x07, 0x0e, 0x06, 0xe0, 0x03, 0x98, 0x07, 0x06,
-0x3f, 0x0e, 0x02, 0xe0, 0x01, 0x9f, 0x00, 0xe0, 0x02, 0x9f, 0x38, 0x1c,
-0xdb, 0xe7, 0x00, 0x00, 0x40, 0xab, 0x20, 0x40, 0x03, 0x49, 0x00, 0x20,
-0x00, 0x22, 0x0a, 0x54, 0x01, 0x30, 0x60, 0x28, 0xfb, 0xd3, 0x70, 0x47,
-0x40, 0xab, 0x20, 0x40, 0x00, 0xb5, 0x02, 0xf0, 0x6f, 0xfa, 0x57, 0x20,
-0x02, 0xf0, 0xcc, 0xf9, 0x02, 0xf0, 0x40, 0xf9, 0x00, 0x0a, 0xfb, 0xd3,
-0x02, 0xf0, 0x4e, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x82, 0xb0,
-0x07, 0x9d, 0x14, 0x1c, 0x1f, 0x1c, 0x30, 0x4a, 0xd2, 0x6f, 0x20, 0x23,
-0x16, 0x68, 0x9e, 0x43, 0x16, 0x60, 0x33, 0x1c, 0xff, 0x22, 0x01, 0x32,
-0x2a, 0x40, 0x40, 0x02, 0x08, 0x43, 0x05, 0x0a, 0x06, 0x1c, 0x00, 0x0c,
-0x01, 0x90, 0x00, 0x2a, 0x20, 0xd0, 0x02, 0xf0, 0x4b, 0xfa, 0x53, 0x20,
-0x02, 0xf0, 0xa8, 0xf9, 0x01, 0x98, 0xc0, 0x46, 0x00, 0x90, 0x02, 0xf0,
-0xa3, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0xa0, 0xf9, 0x30, 0x1c, 0x02, 0xf0,
-0x9d, 0xf9, 0x02, 0xf0, 0x23, 0xfa, 0xff, 0xf7, 0xc7, 0xff, 0x02, 0xf0,
-0x37, 0xfa, 0x54, 0x20, 0x02, 0xf0, 0x94, 0xf9, 0x00, 0x98, 0x02, 0xf0,
-0x91, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x8e, 0xf9, 0x30, 0x1c, 0x14, 0xe0,
-0x02, 0xf0, 0x2a, 0xfa, 0x52, 0x20, 0x02, 0xf0, 0x87, 0xf9, 0x01, 0x98,
-0x02, 0xf0, 0x84, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x81, 0xf9, 0x30, 0x1c,
-0x02, 0xf0, 0x7e, 0xf9, 0x00, 0x20, 0x02, 0xf0, 0x7b, 0xf9, 0x00, 0x20,
-0x02, 0xf0, 0x78, 0xf9, 0x00, 0x20, 0x02, 0xf0, 0x75, 0xf9, 0x00, 0x20,
-0x02, 0xf0, 0x72, 0xf9, 0x00, 0x2f, 0x05, 0xd9, 0x02, 0xf0, 0xe4, 0xf8,
-0x20, 0x70, 0x01, 0x34, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0xf0, 0xf9,
-0x04, 0x4a, 0xd0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60,
-0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x42, 0x02, 0x0a, 0x43,
-0x15, 0x1c, 0x01, 0x28, 0x54, 0xd0, 0x2c, 0x49, 0xc8, 0x6f, 0x20, 0x23,
-0x02, 0x68, 0x9a, 0x43, 0x02, 0x60, 0xc8, 0x6f, 0x40, 0x23, 0x01, 0x68,
-0x19, 0x43, 0x01, 0x60, 0x02, 0xf0, 0xe6, 0xf9, 0x53, 0x20, 0x02, 0xf0,
-0x43, 0xf9, 0x28, 0x0c, 0x06, 0x1c, 0x02, 0xf0, 0x3f, 0xf9, 0x28, 0x0a,
-0x01, 0x90, 0x00, 0x90, 0x02, 0xf0, 0x3a, 0xf9, 0x28, 0x1c, 0x02, 0xf0,
-0x37, 0xf9, 0x02, 0xf0, 0xbd, 0xf9, 0xff, 0xf7, 0x61, 0xff, 0x02, 0xf0,
-0xd1, 0xf9, 0x84, 0x20, 0x02, 0xf0, 0x2e, 0xf9, 0x30, 0x1c, 0x02, 0xf0,
-0x2b, 0xf9, 0x00, 0x98, 0x02, 0xf0, 0x28, 0xf9, 0x28, 0x1c, 0x02, 0xf0,
-0x25, 0xf9, 0x00, 0x2f, 0x05, 0xd9, 0x20, 0x78, 0x01, 0x34, 0x02, 0xf0,
-0x1f, 0xf9, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0xa3, 0xf9, 0x02, 0xf0,
-0xb9, 0xf9, 0x83, 0x20, 0x02, 0xf0, 0x16, 0xf9, 0x30, 0x1c, 0x02, 0xf0,
-0x13, 0xf9, 0x01, 0x98, 0x02, 0xf0, 0x10, 0xf9,
-0x28, 0x1c, 0x02, 0xf0, 0x0d, 0xf9, 0x02, 0xf0, 0x93, 0xf9, 0xff, 0xf7,
-0x37, 0xff, 0x07, 0x49, 0xc8, 0x6f, 0x40, 0x23, 0x02, 0x68, 0x9a, 0x43,
-0x02, 0x60, 0xc8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60,
-0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x70, 0x47, 0x00, 0x00, 0x80, 0xb5, 0x01, 0xf0, 0x8f, 0xf8, 0x06, 0x4f,
-0xc0, 0x46, 0xf8, 0x60, 0x01, 0xf0, 0xf2, 0xf8, 0x78, 0x80, 0x01, 0xf0,
-0xb1, 0xf8, 0x38, 0x71, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0x01, 0xf0, 0x05, 0xf9, 0x02, 0x49,
-0xc0, 0x46, 0x08, 0x80, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x0b, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x11, 0xd1, 0xc1, 0x6f, 0x02, 0x23,
-0x0a, 0x68, 0x1a, 0x43, 0x0a, 0x60, 0xc1, 0x6f, 0x80, 0x23, 0x0a, 0x68,
-0x1a, 0x43, 0x0a, 0x60, 0xc1, 0x18, 0x08, 0x68, 0x82, 0x23, 0x02, 0x68,
-0x1a, 0x43, 0x02, 0x60, 0x00, 0x20, 0x08, 0x81, 0x70, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb4, 0x4a, 0x49, 0xca, 0x1d, 0x9d, 0x32,
-0x00, 0x20, 0x00, 0x27, 0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x17, 0x28,
-0xfa, 0xd3, 0x46, 0x4c, 0x00, 0x20, 0x82, 0x00, 0xa7, 0x50, 0x01, 0x30,
-0x20, 0x28, 0xfa, 0xd3, 0x43, 0x4a, 0x00, 0x20, 0x83, 0x00, 0xd7, 0x50,
-0x01, 0x30, 0x20, 0x28, 0xfa, 0xd3, 0xa7, 0x61, 0x97, 0x61, 0x4f, 0x65,
-0x8f, 0x65, 0x3f, 0x4d, 0xc0, 0x46, 0x2f, 0x60, 0x6f, 0x60, 0xaf, 0x60,
-0xaf, 0x61, 0xef, 0x60, 0x2f, 0x61, 0x6f, 0x61, 0x00, 0x20, 0xc1, 0x00,
-0x09, 0x18, 0x49, 0x01, 0x35, 0x4b, 0xc9, 0x18, 0x86, 0x00, 0xcb, 0x1d,
-0xf9, 0x33, 0x34, 0x4c, 0x34, 0x19, 0xe3, 0x63, 0x11, 0x23, 0x5b, 0x01,
-0xcb, 0x18, 0x63, 0x63, 0x0d, 0x23, 0x9b, 0x01, 0xcb, 0x18, 0xb4, 0x18,
-0xe3, 0x63, 0x23, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x61, 0x63, 0x01, 0x30,
-0x02, 0x28, 0xe4, 0xdb, 0x29, 0x48, 0xc1, 0x1d, 0xf9, 0x31, 0x29, 0x4c,
-0xc0, 0x46, 0xa1, 0x62, 0x61, 0x6b, 0x0d, 0x23, 0x9b, 0x01, 0xe1, 0x62,
-0xc1, 0x18, 0x91, 0x62, 0x51, 0x6b, 0xc0, 0x46, 0xd1, 0x62, 0x08, 0x21,
-0xe1, 0x64, 0x25, 0x49, 0xc0, 0x46, 0x21, 0x65, 0x24, 0x49, 0x0b, 0x69,
-0xc0, 0x46, 0x63, 0x65, 0xc3, 0x1d, 0x4d, 0x33, 0xe3, 0x65, 0x25, 0x66,
-0x8b, 0x68, 0xc0, 0x46, 0x63, 0x66, 0xcb, 0x68, 0xc0, 0x46, 0xa3, 0x66,
-0x1e, 0x4b, 0xc0, 0x46, 0xe3, 0x66, 0x27, 0x67, 0x0b, 0x23, 0xdb, 0x01,
-0xc3, 0x18, 0xa3, 0x67, 0x67, 0x67, 0x01, 0x26, 0xe3, 0x1d, 0x69, 0x33,
-0x66, 0x61, 0xe7, 0x61, 0x1f, 0x73, 0x02, 0x23, 0xd3, 0x64, 0x17, 0x4b,
-0xc0, 0x46, 0x13, 0x65, 0xcb, 0x69, 0xc0, 0x46, 0x53, 0x65, 0xc3, 0x1d,
-0x51, 0x33, 0xd3, 0x65, 0x2b, 0x1d, 0x13, 0x66, 0x4b, 0x69, 0xc0, 0x46,
-0x53, 0x66, 0x89, 0x69, 0xc0, 0x46, 0x91, 0x66, 0x0f, 0x49, 0xc0, 0x46,
-0xd1, 0x66, 0x16, 0x67, 0x0f, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x90, 0x67,
-0x56, 0x67, 0xd7, 0x61, 0xd0, 0x1d, 0x69, 0x30, 0x56, 0x61, 0x07, 0x73,
-0xf0, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80,
-0x64, 0x2d, 0x00, 0x80, 0x90, 0xee, 0x20, 0x40, 0x30, 0x01, 0x18, 0x00,
-0x7c, 0x29, 0x00, 0x80, 0x00, 0x55, 0xff, 0xff, 0x38, 0x01, 0x18, 0x00,
-0x10, 0x55, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x21, 0x1e, 0x4a, 0xbb, 0x23,
-0x1b, 0x01, 0xd7, 0x18, 0xf9, 0x73, 0x19, 0x23,
-0xdb, 0x01, 0xd0, 0x18, 0x01, 0x24, 0xcd, 0x23, 0x1b, 0x01, 0xd3, 0x18,
-0xc1, 0x61, 0x1c, 0x70, 0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x99, 0x60,
-0xb9, 0x73, 0x59, 0x61, 0x2f, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x19, 0x60,
-0x13, 0x4b, 0x51, 0x27, 0xbf, 0x03, 0x03, 0x63, 0x3b, 0x60, 0x84, 0x69,
-0xe4, 0x18, 0x44, 0x63, 0x04, 0x3c, 0x7c, 0x60, 0x01, 0x24, 0xe4, 0x02,
-0x84, 0x63, 0x0e, 0x4c, 0xc0, 0x46, 0xbc, 0x60, 0x04, 0x6b, 0xc0, 0x46,
-0x44, 0x62, 0x84, 0x69, 0xe4, 0x18, 0x0b, 0x4b, 0xe3, 0x18, 0xfb, 0x60,
-0x03, 0x6b, 0xc0, 0x46, 0x83, 0x62, 0x43, 0x6a, 0xc0, 0x46, 0x03, 0x62,
-0xc1, 0x63, 0x51, 0x64, 0x91, 0x64, 0xd1, 0x65, 0xd1, 0x66, 0x90, 0xbc,
-0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40,
-0xfc, 0x07, 0x00, 0x00, 0xfc, 0xf7, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x22,
-0x1b, 0x49, 0xc9, 0x23, 0x1b, 0x01, 0xc8, 0x18, 0x02, 0x71, 0x01, 0x20,
-0xbb, 0x23, 0x1b, 0x01, 0xcb, 0x18, 0x58, 0x73, 0x17, 0x48, 0x03, 0x1c,
-0x00, 0x27, 0xdc, 0x1d, 0xc1, 0x34, 0x1c, 0x65, 0x23, 0x1c, 0x01, 0x37,
-0x3f, 0x2f, 0xf8, 0xd3, 0x1a, 0x65, 0x19, 0x23, 0xdb, 0x01, 0xcf, 0x18,
-0x33, 0x23, 0x9b, 0x01, 0xcb, 0x18, 0x3a, 0x61, 0x98, 0x61, 0x40, 0x20,
-0xf8, 0x60, 0xda, 0x61, 0x1a, 0x62, 0xca, 0x64, 0x0a, 0x66, 0x0c, 0x48,
-0xc0, 0x46, 0xc2, 0x60, 0x0b, 0x48, 0x00, 0x6b, 0xc0, 0x06, 0xc0, 0x0e,
-0xf8, 0x63, 0x0a, 0x48, 0x01, 0x68, 0xc0, 0x46, 0x19, 0x80, 0x41, 0x68,
-0xc0, 0x46, 0x59, 0x80, 0x80, 0x68, 0xc0, 0x46, 0x98, 0x80, 0x90, 0xbc,
-0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x90, 0xbc, 0x20, 0x40,
-0x90, 0xee, 0x20, 0x40, 0x80, 0x00, 0x14, 0x40, 0x40, 0x00, 0x14, 0x40,
-0x00, 0x20, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x73, 0xcb, 0x1d, 0xff, 0x33,
-0x3a, 0x33, 0x88, 0x61, 0xc8, 0x61, 0x18, 0x70, 0x06, 0x4a, 0xc0, 0x46,
-0x10, 0x65, 0x50, 0x66, 0x90, 0x66, 0x08, 0x70, 0x58, 0x70, 0xbb, 0x23,
-0x1b, 0x01, 0xd1, 0x18, 0x08, 0x73, 0x70, 0x47, 0x28, 0x05, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb4, 0x2f, 0x49, 0x2f, 0x4a, 0xc0, 0x46,
-0x11, 0x61, 0x01, 0x23, 0x9b, 0x02, 0xc8, 0x18, 0x50, 0x61, 0x2d, 0x48,
-0xc0, 0x46, 0x10, 0x62, 0xdb, 0x00, 0xc3, 0x18, 0x53, 0x62, 0x00, 0x23,
-0x13, 0x63, 0x53, 0x63, 0x29, 0x4a, 0x2a, 0x4f, 0xd4, 0x1d, 0xff, 0x34,
-0xfa, 0x34, 0x14, 0xc7, 0x08, 0x3f, 0x3b, 0x61, 0x1c, 0x1f, 0x7c, 0x61,
-0x26, 0x4f, 0xc0, 0x46, 0x39, 0x60, 0xb8, 0x61, 0x79, 0x61, 0xf8, 0x62,
-0x3b, 0x63, 0x7b, 0x64, 0xba, 0x64, 0xfa, 0x65, 0x22, 0x4f, 0xfe, 0x1d,
-0xf9, 0x36, 0x22, 0x4d, 0xec, 0x1d, 0x79, 0x34, 0x26, 0x62, 0x51, 0x26,
-0xb6, 0x03, 0x37, 0x61, 0x24, 0x6a, 0xc0, 0x46, 0x74, 0x61, 0x2f, 0x67,
-0x1d, 0x4d, 0x09, 0x27, 0x7f, 0x04, 0xec, 0x1d, 0x75, 0x34, 0x7c, 0x60,
-0x3d, 0x60, 0x1b, 0x4c, 0xc0, 0x46, 0x3c, 0x61, 0xe6, 0x1d, 0x75, 0x36,
-0x7e, 0x61, 0x19, 0x4f, 0xc0, 0x46, 0x7c, 0x60, 0x3d, 0x60, 0x0f, 0x1c,
-0x00, 0x21, 0xff, 0x24, 0x01, 0x34, 0x1d, 0x1c, 0x8b, 0x00, 0xfd, 0x50,
-0x01, 0x31, 0xa1, 0x42, 0xfa, 0xd3, 0x01, 0x1c, 0x00, 0x20, 0x01, 0x27,
-0xff, 0x02, 0x83, 0x00, 0xcd, 0x50, 0x01, 0x30, 0xb8, 0x42, 0xfa, 0xd3,
-0x00, 0x20, 0x81, 0x00, 0x55, 0x50, 0x01, 0x30, 0x80, 0x28, 0xfa, 0xd3,
-0xf0, 0xbc, 0x70, 0x47, 0x24, 0xa3, 0x20, 0x40,
-0x40, 0x01, 0x18, 0x00, 0x24, 0x83, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40,
-0x80, 0x01, 0x18, 0x00, 0xa8, 0x03, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x24, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40,
-0x08, 0x04, 0x00, 0x80, 0xb8, 0xb5, 0x2c, 0x48, 0xfd, 0xf7, 0xba, 0xfd,
-0x01, 0x20, 0x2b, 0x49, 0x0a, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x0a, 0x68,
-0x12, 0x0c, 0x02, 0xd1, 0x0a, 0x68, 0x92, 0x0a, 0x00, 0xd2, 0x00, 0x20,
-0x04, 0x06, 0x24, 0x0e, 0x25, 0x4a, 0xd7, 0x1d, 0x0d, 0x37, 0x00, 0x23,
-0x00, 0x20, 0x9d, 0x00, 0x78, 0x51, 0x01, 0x33, 0x04, 0x2b, 0xfa, 0xd3,
-0x01, 0x27, 0x3f, 0x05, 0x50, 0x61, 0xf8, 0x60, 0xd0, 0x61, 0xf8, 0x61,
-0x00, 0x23, 0xdb, 0x43, 0x93, 0x61, 0x3b, 0x61, 0x13, 0x62, 0x3b, 0x62,
-0x00, 0x27, 0x1b, 0x4b, 0x8d, 0x68, 0xc0, 0x46, 0x00, 0x95, 0x8d, 0x69,
-0xc0, 0x46, 0x00, 0x95, 0x00, 0x2c, 0x0b, 0xd0, 0xdd, 0x6b, 0xc0, 0x46,
-0x00, 0x95, 0x9d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x5d, 0x6b, 0xc0, 0x46,
-0x00, 0x95, 0x1d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x01, 0x37, 0x40, 0x2f,
-0xe8, 0xd3, 0x00, 0x27, 0x6c, 0x46, 0x01, 0x23, 0x5b, 0x07, 0x1c, 0x43,
-0x01, 0xe0, 0x20, 0x60, 0x01, 0x37, 0x0d, 0x68, 0x2b, 0x09, 0x02, 0xd2,
-0x80, 0x2f, 0xf8, 0xd3, 0x01, 0xe0, 0x80, 0x2f, 0x03, 0xd3, 0x08, 0x49,
-0x4b, 0x6e, 0x01, 0x33, 0x4b, 0x66, 0xd0, 0x62, 0xb8, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0xf4, 0x01, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x01, 0x18, 0x40, 0xa0, 0x82, 0x20, 0x40,
-0x90, 0xb4, 0x00, 0x21, 0x0e, 0x4f, 0x0f, 0x4a, 0x00, 0x20, 0x4c, 0x01,
-0x64, 0x1a, 0xa4, 0x00, 0xa3, 0x18, 0x58, 0x60, 0x98, 0x60, 0x18, 0x64,
-0x58, 0x64, 0x10, 0x53, 0x58, 0x80, 0xcc, 0x00, 0xe4, 0x19, 0x98, 0x67,
-0xdc, 0x62, 0x01, 0x31, 0x03, 0x29, 0xee, 0xd3, 0x06, 0x49, 0xc0, 0x46,
-0x08, 0x60, 0x48, 0x60, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0xbc,
-0x70, 0x47, 0x00, 0x00, 0xac, 0x66, 0x21, 0x40, 0x5c, 0x2b, 0x00, 0x80,
-0xd0, 0x2c, 0x00, 0x80, 0x64, 0x21, 0x05, 0x48, 0xc0, 0x46, 0x01, 0x63,
-0x00, 0x21, 0xc9, 0x43, 0x41, 0x63, 0x81, 0x63, 0x00, 0x21, 0xc1, 0x63,
-0x01, 0x64, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb4, 0x01, 0x20,
-0x40, 0x02, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x3c, 0x20, 0x48, 0x60,
-0x88, 0x60, 0x08, 0x48, 0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x07, 0x4a,
-0x87, 0x00, 0xcb, 0x68, 0xc0, 0x46, 0xda, 0x51, 0x01, 0x30, 0x10, 0x28,
-0xf8, 0xd3, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80,
-0xf4, 0x2d, 0x00, 0x80, 0x5d, 0x4c, 0xff, 0xff, 0x12, 0x49, 0x13, 0x48,
-0x67, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x11, 0x4b,
-0xca, 0x18, 0xc1, 0x60, 0x82, 0x60, 0x01, 0x61, 0x0f, 0x49, 0x10, 0x48,
-0xa7, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x0e, 0x4b,
-0xca, 0x18, 0xc1, 0x60, 0x82, 0x60, 0x01, 0x61, 0x0c, 0x48, 0x0d, 0x49,
-0x67, 0x23, 0x9b, 0x01, 0xc2, 0x18, 0x05, 0xc1, 0x08, 0x39, 0x05, 0x4b,
-0xc2, 0x18, 0xc8, 0x60, 0x8a, 0x60, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00,
-0xac, 0x1e, 0x21, 0x40, 0x48, 0x2e, 0x00, 0x80, 0xfc, 0x1f, 0x00, 0x00,
-0xac, 0xee, 0x20, 0x40, 0x34, 0x2e, 0x00, 0x80, 0xfc, 0x2f, 0x00, 0x00,
-0xac, 0x3e, 0x21, 0x40, 0x5c, 0x2e, 0x00, 0x80,
-0x90, 0xb4, 0x00, 0x21, 0x40, 0x4c, 0x00, 0x20, 0x0a, 0x01, 0x12, 0x19,
-0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 0xd0, 0x62, 0x10, 0x63, 0x50, 0x63,
-0x90, 0x63, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, 0x3a, 0x49, 0xc0, 0x46,
-0x08, 0x63, 0x48, 0x63, 0x88, 0x63, 0x20, 0x60, 0x01, 0x21, 0xe3, 0x1d,
-0x59, 0x33, 0x60, 0x60, 0x19, 0x71, 0x18, 0x72, 0x98, 0x71, 0x98, 0x72,
-0x59, 0x71, 0x58, 0x72, 0xd8, 0x71, 0xd8, 0x72, 0xe2, 0x1d, 0x49, 0x32,
-0x11, 0x73, 0x19, 0x70, 0x90, 0x73, 0x98, 0x70, 0x51, 0x73, 0x59, 0x70,
-0xd0, 0x73, 0xd8, 0x70, 0x11, 0x71, 0x11, 0x72, 0x90, 0x71, 0x90, 0x72,
-0x50, 0x71, 0x50, 0x72, 0xd0, 0x71, 0xd0, 0x72, 0x18, 0x73, 0x02, 0x22,
-0xe7, 0x1d, 0x69, 0x37, 0x3a, 0x70, 0x99, 0x73, 0xba, 0x70, 0x58, 0x73,
-0x78, 0x70, 0xd8, 0x73, 0xf8, 0x70, 0x39, 0x71, 0x3a, 0x72, 0xb9, 0x71,
-0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, 0xf9, 0x72, 0x39, 0x73,
-0xe3, 0x1d, 0x79, 0x33, 0x1a, 0x70, 0xb9, 0x73, 0x99, 0x70, 0x78, 0x73,
-0x5a, 0x70, 0xf9, 0x73, 0xd9, 0x70, 0x1a, 0x71, 0x1a, 0x72, 0x99, 0x71,
-0x9a, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, 0xda, 0x72, 0x19, 0x73,
-0xe7, 0x1d, 0x89, 0x37, 0x3a, 0x70, 0x99, 0x73, 0xb9, 0x70, 0x58, 0x73,
-0x7a, 0x70, 0xd9, 0x73, 0xf9, 0x70, 0x39, 0x71, 0x3a, 0x72, 0xb9, 0x71,
-0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, 0xf9, 0x72, 0x3a, 0x73,
-0xe3, 0x1d, 0x99, 0x33, 0x1a, 0x70, 0xb9, 0x73, 0x9a, 0x70, 0x78, 0x73,
-0x5a, 0x70, 0xf9, 0x73, 0xda, 0x70, 0x19, 0x71, 0x1a, 0x72, 0x99, 0x71,
-0x99, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, 0xd9, 0x72, 0x20, 0x61,
-0xe0, 0x60, 0x60, 0x61, 0xa0, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00,
-0xa0, 0x1c, 0x00, 0x80, 0xe8, 0x19, 0x00, 0x80, 0x81, 0x20, 0x00, 0x02,
-0x01, 0x49, 0xc0, 0x46, 0x88, 0x62, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00,
-0x09, 0x49, 0x0a, 0x4b, 0xc8, 0x18, 0x04, 0x3b, 0xc9, 0x18, 0x08, 0x60,
-0x00, 0x21, 0xc2, 0x1d, 0x29, 0x32, 0xc2, 0x61, 0x10, 0x1c, 0x01, 0x31,
-0x08, 0x29, 0xf8, 0xd3, 0xc1, 0x1f, 0x29, 0x39, 0x00, 0x20, 0xc8, 0x61,
-0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x84, 0x09, 0x00, 0x00,
-0x06, 0x48, 0x07, 0x49, 0xc0, 0x46, 0x08, 0x80, 0x48, 0x80, 0x00, 0x20,
-0x88, 0x80, 0xc8, 0x80, 0x88, 0x60, 0x04, 0x49, 0xc0, 0x46, 0x48, 0x61,
-0x88, 0x61, 0x70, 0x47, 0xff, 0xff, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80,
-0x6c, 0x06, 0x00, 0x80, 0x00, 0x21, 0x06, 0x48, 0xc2, 0x1d, 0x19, 0x32,
-0xc1, 0x60, 0x01, 0x61, 0xc1, 0x61, 0x01, 0x62, 0x11, 0x71, 0xff, 0x30,
-0x01, 0x30, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0x09, 0x48, 0x0a, 0x4b, 0xc0, 0x46, 0x18, 0x60, 0x00, 0x21, 0xc2, 0x1d,
-0x4d, 0x32, 0xc2, 0x60, 0x10, 0x1c, 0x01, 0x31, 0x14, 0x29, 0xf8, 0xd3,
-0xc1, 0x1f, 0x4d, 0x39, 0x00, 0x20, 0xc8, 0x60, 0x58, 0x60, 0x98, 0x60,
-0x70, 0x47, 0x00, 0x00, 0xd8, 0x07, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80,
-0x00, 0xb5, 0x0b, 0x49, 0x0b, 0x48, 0xfd, 0xf7, 0xea, 0xfb, 0x0b, 0x48,
-0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 0x98, 0x43, 0x09, 0x49, 0xc0, 0x46,
-0x08, 0x62, 0x09, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x04, 0xd1, 0xc0, 0x6f,
-0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x08, 0xbc, 0x18, 0x47,
-0xc1, 0xbd, 0x21, 0x40, 0x75, 0x98, 0x21, 0x40,
-0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x00, 0xb5, 0x0f, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x04, 0xd1, 0xc0, 0x6f,
-0x80, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0x0b, 0x4b, 0x0c, 0x48,
-0x0c, 0x4a, 0x00, 0x21, 0xfd, 0xf7, 0xbf, 0xfb, 0x0b, 0x48, 0x41, 0x8d,
-0x01, 0x31, 0x41, 0x85, 0x00, 0x21, 0xc1, 0x85, 0x09, 0x48, 0x00, 0x6a,
-0x01, 0x23, 0xdb, 0x03, 0x18, 0x43, 0x08, 0x49, 0xc0, 0x46, 0x08, 0x62,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x59, 0xbd, 0x21, 0x40,
-0x75, 0x98, 0x21, 0x40, 0xb8, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0xf0, 0xb5, 0x1b, 0x4c,
-0x10, 0x26, 0xe0, 0x68, 0x01, 0x28, 0x08, 0xd1, 0x60, 0x88, 0x00, 0x28,
-0x05, 0xd1, 0x20, 0x79, 0x00, 0x28, 0x02, 0xd1, 0x19, 0x20, 0xa0, 0x67,
-0x00, 0xe0, 0xa6, 0x67, 0x00, 0x20, 0x07, 0x23, 0x5b, 0x02, 0xe5, 0x18,
-0xc1, 0x43, 0xe8, 0x61, 0x69, 0x62, 0x59, 0x08, 0xa1, 0x27, 0x7f, 0x03,
-0x79, 0x60, 0x0f, 0x21, 0x79, 0x60, 0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x71,
-0x01, 0x20, 0xb8, 0x60, 0x40, 0x02, 0xb8, 0x60, 0x00, 0xf0, 0x4c, 0xfa,
-0x00, 0xf0, 0xf0, 0xfa, 0x04, 0x20, 0xb8, 0x60, 0x07, 0x20, 0x78, 0x61,
-0x7e, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0xc0, 0x8b, 0x04, 0x23,
-0x18, 0x40, 0xe8, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0x90, 0xb4, 0x02, 0x1c, 0x00, 0x20, 0xff, 0x23,
-0x01, 0x33, 0x9a, 0x42, 0x08, 0xd0, 0x01, 0x29, 0x00, 0xd1, 0x01, 0x20,
-0x00, 0x2a, 0x01, 0xd1, 0x02, 0x23, 0x18, 0x43, 0x90, 0xbc, 0x70, 0x47,
-0x1b, 0x4a, 0xd7, 0x68, 0x1a, 0x4b, 0x19, 0x79, 0x1c, 0x1c, 0x37, 0x23,
-0x9b, 0x01, 0xe3, 0x18, 0x01, 0x2f, 0x0d, 0xd1, 0x57, 0x88, 0x00, 0x2f,
-0x0a, 0xd1, 0x00, 0x29, 0x0a, 0xd1, 0x59, 0x8b, 0x0a, 0x09, 0x00, 0xd3,
-0x02, 0x20, 0x49, 0x09, 0xe8, 0xd3, 0x01, 0x23, 0x18, 0x43, 0xe5, 0xe7,
-0x00, 0x29, 0x03, 0xd0, 0x98, 0x8a, 0x80, 0x07, 0x80, 0x0f, 0xdf, 0xe7,
-0x6d, 0x23, 0x5b, 0x01, 0xd1, 0x18, 0x8a, 0x88, 0xff, 0x27, 0x01, 0x37,
-0x17, 0x40, 0x0a, 0x49, 0xc9, 0x88, 0x03, 0xd0, 0x4b, 0x0a, 0x01, 0xd3,
-0x03, 0x20, 0xd1, 0xe7, 0x13, 0x0a, 0x03, 0xd3, 0x0b, 0x0a, 0x01, 0xd3,
-0x02, 0x20, 0xcb, 0xe7, 0xd2, 0x09, 0xc9, 0xd3, 0xc9, 0x09, 0xc7, 0xd3,
-0x01, 0x20, 0xc5, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x08, 0x1c, 0x00, 0x80,
-0xf0, 0xb5, 0xc1, 0xb0, 0x01, 0x20, 0x00, 0x07, 0x52, 0x49, 0xc0, 0x46,
-0x08, 0x60, 0x52, 0x48, 0x42, 0x69, 0x40, 0x0d, 0xa1, 0x21, 0x49, 0x03,
-0x48, 0x60, 0x50, 0x48, 0xc0, 0x6a, 0x50, 0x4b, 0x18, 0x43, 0x00, 0x21,
-0x03, 0x03, 0x1b, 0x0b, 0x4e, 0x4c, 0x27, 0x6f, 0x3d, 0x03, 0x2d, 0x0b,
-0xe7, 0x1d, 0x79, 0x37, 0xab, 0x42, 0x1c, 0xd0, 0xe3, 0x1d, 0x79, 0x33,
-0x1b, 0x6a, 0xc0, 0x46, 0x40, 0x93, 0x01, 0x23, 0x9b, 0x07, 0x03, 0x43,
-0x1b, 0x68, 0xcc, 0x00, 0x6e, 0x46, 0x33, 0x51, 0x01, 0x23, 0x9b, 0x07,
-0x06, 0x1d, 0x33, 0x43, 0x1b, 0x68, 0x6c, 0x44, 0x63, 0x60, 0x08, 0x30,
-0x01, 0x31, 0x40, 0x9b, 0x83, 0x42, 0x00, 0xd8, 0x3f, 0x48, 0x03, 0x03,
-0x1b, 0x0b, 0xab, 0x42, 0xe7, 0xd1, 0x00, 0x20, 0x01, 0x23, 0x1b, 0x03,
-0x13, 0x40, 0x3c, 0x4c, 0x03, 0xd0, 0x63, 0x6a, 0x01, 0x33, 0x63, 0x62,
-0x09, 0xe0, 0x13, 0x0b, 0x03, 0xd3, 0x23, 0x6a,
-0x01, 0x33, 0x23, 0x62, 0x03, 0xe0, 0x37, 0x4b, 0x5c, 0x6d, 0x01, 0x34,
-0x5c, 0x65, 0x00, 0x29, 0x09, 0xd0, 0x03, 0x1c, 0xdc, 0x00, 0x23, 0x1c,
-0x6b, 0x44, 0x5c, 0x68, 0x01, 0x30, 0x23, 0x0d, 0x01, 0xd2, 0x88, 0x42,
-0xf5, 0xd1, 0x30, 0x4c, 0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68,
-0x1b, 0x0c, 0x08, 0xd1, 0x24, 0x68, 0xa3, 0x0a, 0x05, 0xd3, 0x20, 0x24,
-0x2b, 0x4b, 0xc0, 0x46, 0x5c, 0x62, 0x00, 0x24, 0x5c, 0x62, 0x25, 0x4b,
-0x23, 0x4c, 0x51, 0x26, 0xb6, 0x03, 0x23, 0x67, 0x33, 0x61, 0x3d, 0x6a,
-0xc0, 0x46, 0x75, 0x61, 0x02, 0x25, 0xa1, 0x26, 0x76, 0x03, 0x75, 0x60,
-0x01, 0x25, 0xb5, 0x60, 0xe6, 0x1d, 0xb9, 0x36, 0x35, 0x71, 0x88, 0x42,
-0x21, 0xd0, 0x25, 0x1c, 0xc3, 0x00, 0x6c, 0x46, 0xe4, 0x58, 0x2e, 0x6f,
-0x6b, 0x44, 0x34, 0x60, 0x5b, 0x68, 0x2c, 0x6f, 0xc0, 0x46, 0x63, 0x60,
-0x2b, 0x6f, 0x08, 0x33, 0x2b, 0x67, 0x3c, 0x6a, 0xa3, 0x42, 0x02, 0xd3,
-0x12, 0x4b, 0xc0, 0x46, 0x2b, 0x67, 0x03, 0x1c, 0xdb, 0x00, 0x6b, 0x44,
-0x5c, 0x68, 0x01, 0x30, 0x23, 0x0d, 0x04, 0xd3, 0x51, 0x24, 0xa4, 0x03,
-0x2b, 0x6f, 0xc0, 0x46, 0xa3, 0x61, 0x88, 0x42, 0xde, 0xd1, 0x10, 0x0b,
-0x03, 0xd3, 0x0e, 0x49, 0x01, 0x20, 0xfd, 0xf7, 0x74, 0xfa, 0x41, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0,
-0x00, 0x01, 0x14, 0x40, 0x00, 0x40, 0x14, 0x40, 0x00, 0x00, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40, 0xa4, 0x2a, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00,
-0xc9, 0x4f, 0xff, 0xff, 0xf0, 0xb4, 0x00, 0x21, 0x00, 0x23, 0x07, 0x22,
-0x06, 0x24, 0x47, 0x4f, 0xc0, 0x46, 0x3c, 0x61, 0x3a, 0x61, 0x01, 0x33,
-0x20, 0x2b, 0xf9, 0xd3, 0x04, 0x25, 0x3d, 0x61, 0x05, 0x23, 0x3b, 0x61,
-0x3c, 0x61, 0x3a, 0x61, 0x3c, 0x61, 0x3a, 0x61, 0x3d, 0x61, 0x3b, 0x61,
-0x3f, 0x4d, 0xab, 0x6f, 0xde, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23,
-0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f,
-0x9e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61,
-0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5e, 0x08, 0x02, 0x23,
-0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43,
-0x3b, 0x61, 0x02, 0x23, 0xae, 0x6f, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43,
-0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5d, 0x00,
-0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23,
-0x2b, 0x43, 0x3b, 0x61, 0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23,
-0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x85, 0x08,
-0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23,
-0x2b, 0x43, 0x3b, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23,
-0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x02, 0x25,
-0x05, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43,
-0x3b, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x04, 0x23, 0x03, 0x43,
-0x3b, 0x61, 0x05, 0x23, 0x18, 0x43, 0x38, 0x61, 0x00, 0x25, 0x3d, 0x61,
-0x01, 0x23, 0x3b, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x00, 0x20, 0x3d, 0x61,
-0x0d, 0x4b, 0x1b, 0x69, 0x49, 0x00, 0x1e, 0x1c, 0x02, 0x23, 0x33, 0x40,
-0x19, 0x43, 0x01, 0x23, 0x3b, 0x61, 0x01, 0x30,
-0x10, 0x28, 0xf2, 0xd3, 0x02, 0x20, 0x38, 0x61, 0x03, 0x20, 0x38, 0x61,
-0x3c, 0x61, 0x3a, 0x61, 0x3c, 0x61, 0x3a, 0x61, 0x38, 0x61, 0x48, 0x08,
-0xf0, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x80, 0x00, 0x14, 0x40, 0xf0, 0xb4, 0x00, 0x24, 0x07, 0x23, 0x06, 0x27,
-0x44, 0x4a, 0xc0, 0x46, 0x17, 0x61, 0x13, 0x61, 0x01, 0x34, 0x20, 0x2c,
-0xf9, 0xd3, 0x04, 0x26, 0x16, 0x61, 0x05, 0x24, 0x14, 0x61, 0x17, 0x61,
-0x07, 0x23, 0x13, 0x61, 0x16, 0x61, 0x14, 0x61, 0x17, 0x61, 0x13, 0x61,
-0x3c, 0x4b, 0x9b, 0x6f, 0xdd, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c,
-0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x37, 0x4b, 0x9b, 0x6f,
-0x9d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61,
-0x25, 0x43, 0x15, 0x61, 0x32, 0x4b, 0x9b, 0x6f, 0x5d, 0x08, 0x02, 0x23,
-0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61,
-0x2d, 0x4b, 0x9d, 0x6f, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43,
-0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x29, 0x4b, 0x9b, 0x6f, 0x5d, 0x00,
-0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43,
-0x15, 0x61, 0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43,
-0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40,
-0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x45, 0x08,
-0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43,
-0x15, 0x61, 0x02, 0x25, 0x05, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61,
-0x25, 0x43, 0x15, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x03, 0x1c,
-0x33, 0x43, 0x13, 0x61, 0x20, 0x43, 0x10, 0x61, 0x17, 0x61, 0x07, 0x23,
-0x13, 0x61, 0x16, 0x61, 0x14, 0x61, 0x4c, 0x00, 0x00, 0x20, 0x0f, 0x21,
-0x25, 0x1c, 0xcd, 0x40, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43,
-0x13, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x13, 0x61, 0x01, 0x30, 0x01, 0x39,
-0x10, 0x28, 0xf1, 0xd3, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x17, 0x61,
-0x13, 0x61, 0x03, 0x20, 0x10, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00,
-0x80, 0x00, 0x14, 0x00, 0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x4f, 0x4d,
-0x08, 0x21, 0x02, 0x20, 0x2a, 0x1c, 0xfd, 0xf7, 0x27, 0xf9, 0x4d, 0x4c,
-0x71, 0x23, 0x5b, 0x01, 0xe7, 0x18, 0x38, 0x80, 0x1a, 0x21, 0x02, 0x20,
-0x2a, 0x1c, 0xfd, 0xf7, 0x1d, 0xf9, 0x78, 0x80, 0x20, 0x79, 0x00, 0x28,
-0x0b, 0xd0, 0x00, 0x20, 0x38, 0x80, 0xe0, 0x68, 0x01, 0x28, 0x10, 0xd1,
-0x44, 0x48, 0x00, 0x68, 0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x99, 0x02,
-0x08, 0x60, 0xe0, 0x68, 0x01, 0x28, 0x06, 0xd1, 0x60, 0x88, 0x00, 0x28,
-0x03, 0xd1, 0xf9, 0x21, 0x12, 0x20, 0xff, 0xf7, 0x43, 0xff, 0x01, 0x21,
-0xc9, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x3e, 0xff, 0x00, 0x25, 0x7d, 0x26,
-0xf6, 0x00, 0x00, 0xe0, 0x01, 0x35, 0x00, 0x20, 0xff, 0xf7, 0x9c, 0xfe,
-0x00, 0x0c, 0x01, 0xd3, 0xb5, 0x42, 0xf7, 0xd3, 0x00, 0x25, 0x05, 0xe0,
-0x03, 0x21, 0x09, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x2b, 0xff, 0x01, 0x35,
-0x00, 0x20, 0xff, 0xf7, 0x8d, 0xfe, 0x40, 0x0b, 0x01, 0xd2, 0xb5, 0x42,
-0xf2, 0xd3, 0x04, 0x20, 0xff, 0xf7, 0x86, 0xfe, 0xff, 0x23, 0xe1, 0x33,
-0x98, 0x43, 0x01, 0x21, 0x01, 0x43, 0x38, 0x88, 0xff, 0x23, 0x01, 0x33,
-0x98, 0x42, 0x03, 0xd1, 0x2f, 0x23, 0x5b, 0x01,
-0x19, 0x43, 0x16, 0xe0, 0x01, 0x28, 0x09, 0xd1, 0x78, 0x88, 0x01, 0x28,
-0x03, 0xd1, 0x23, 0x23, 0x5b, 0x01, 0x19, 0x43, 0x0d, 0xe0, 0x20, 0x23,
-0x19, 0x43, 0x0a, 0xe0, 0x00, 0x28, 0x08, 0xd1, 0x78, 0x88, 0x01, 0x28,
-0x03, 0xd1, 0x0b, 0x23, 0xdb, 0x01, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23,
-0x19, 0x43, 0x04, 0x20, 0xff, 0xf7, 0xf8, 0xfe, 0x09, 0x21, 0x49, 0x02,
-0x00, 0x20, 0xff, 0xf7, 0xf3, 0xfe, 0xe0, 0x68, 0x00, 0x28, 0x0c, 0xd1,
-0x00, 0x21, 0x1b, 0x20, 0xff, 0xf7, 0xec, 0xfe, 0x1a, 0x20, 0xff, 0xf7,
-0x4f, 0xfe, 0x01, 0x21, 0xc9, 0x03, 0x01, 0x43, 0x1a, 0x20, 0xff, 0xf7,
-0xe3, 0xfe, 0x00, 0x27, 0x03, 0xe0, 0x08, 0x2f, 0x01, 0xd3, 0x0f, 0x2f,
-0x08, 0xd9, 0x38, 0x1c, 0xff, 0xf7, 0x40, 0xfe, 0x79, 0x00, 0x09, 0x19,
-0x1b, 0x23, 0xdb, 0x01, 0xc9, 0x18, 0x88, 0x83, 0x01, 0x37, 0x20, 0x2f,
-0xef, 0xd3, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xed, 0xaf, 0x21, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb0, 0x13, 0x48,
-0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x00, 0x91,
-0x81, 0x68, 0xc0, 0x46, 0x00, 0x91, 0xc1, 0x68, 0xc0, 0x46, 0x00, 0x91,
-0x01, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x69, 0xc0, 0x46, 0x00, 0x91,
-0x81, 0x69, 0xc0, 0x46, 0x00, 0x91, 0xc1, 0x69, 0xc0, 0x46, 0x00, 0x91,
-0x01, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x6a, 0xc0, 0x46, 0x00, 0x91,
-0x81, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0xc0, 0x6a, 0xc0, 0x46, 0x00, 0x90,
-0x01, 0xb0, 0x70, 0x47, 0x00, 0x08, 0x14, 0x40, 0xf0, 0xb5, 0x83, 0xb0,
-0x68, 0x4d, 0x1b, 0x23, 0xdb, 0x01, 0xef, 0x18, 0xf8, 0x8b, 0x04, 0x22,
-0x02, 0x40, 0x02, 0x92, 0x71, 0x23, 0x5b, 0x01, 0xe8, 0x18, 0x01, 0x88,
-0xc0, 0x46, 0x01, 0x91, 0x40, 0x88, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x24,
-0x03, 0xe0, 0x08, 0x2c, 0x01, 0xd3, 0x0f, 0x2c, 0x08, 0xd9, 0x20, 0x1c,
-0xff, 0xf7, 0xe8, 0xfd, 0x61, 0x00, 0x49, 0x19, 0x1b, 0x23, 0xdb, 0x01,
-0xc9, 0x18, 0x88, 0x83, 0x01, 0x34, 0x20, 0x2c, 0xef, 0xd3, 0x58, 0x4c,
-0xe0, 0x69, 0x00, 0x28, 0x15, 0xd0, 0x57, 0x4e, 0x20, 0x25, 0x01, 0x3d,
-0x53, 0x49, 0xe0, 0x69, 0x30, 0x40, 0x0b, 0xd0, 0x68, 0x00, 0x40, 0x18,
-0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x8b, 0x28, 0x1c, 0xff, 0xf7,
-0x65, 0xfe, 0xe0, 0x69, 0xb0, 0x43, 0xe0, 0x61, 0x76, 0x08, 0x00, 0x2d,
-0xeb, 0xd1, 0x01, 0x20, 0xff, 0xf7, 0xc2, 0xfd, 0x48, 0x49, 0xc0, 0x46,
-0xf8, 0x83, 0xf8, 0x8b, 0xc2, 0x08, 0x25, 0xd3, 0xca, 0x68, 0x01, 0x2a,
-0x13, 0xd1, 0x0a, 0x79, 0x00, 0x2a, 0x1f, 0xd1, 0x49, 0x88, 0x00, 0x29,
-0x1c, 0xd1, 0x01, 0x99, 0x43, 0x4a, 0x00, 0x29, 0x05, 0xd0, 0x01, 0x29,
-0x16, 0xd1, 0x51, 0x8b, 0xc9, 0x08, 0x13, 0xd2, 0x0f, 0xe0, 0x51, 0x8b,
-0x09, 0x09, 0x0f, 0xd2, 0x0b, 0xe0, 0x0a, 0x79, 0x00, 0x2a, 0x0b, 0xd1,
-0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x8a, 0x88, 0xc9, 0x88, 0x11, 0x40,
-0x49, 0x09, 0x09, 0x07, 0x02, 0xd1, 0x04, 0x23, 0x98, 0x43, 0xf8, 0x83,
-0xf8, 0x8b, 0x04, 0x21, 0x01, 0x40, 0x02, 0x9a, 0x1f, 0xd0, 0xb9, 0x8b,
-0x4a, 0x0b, 0x27, 0xd3, 0x80, 0x09, 0x25, 0xd3, 0xff, 0x23, 0x01, 0x98,
-0x01, 0x33, 0x98, 0x42, 0x20, 0xd0, 0x00, 0x25, 0x00, 0x98, 0x01, 0x28,
-0x00, 0xd1, 0x05, 0x02, 0x01, 0x98, 0x00, 0x28, 0x02, 0xd1, 0x01, 0x23,
-0x5b, 0x03, 0x1d, 0x43, 0xa9, 0x42, 0x13, 0xd0,
-0x00, 0x20, 0x29, 0x1c, 0xff, 0xf7, 0x10, 0xfe, 0xbd, 0x83, 0x00, 0x20,
-0xc0, 0x43, 0x60, 0x62, 0x0a, 0xe0, 0xb8, 0x8b, 0x40, 0x0b, 0x07, 0xd2,
-0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0xff, 0xf7, 0x03, 0xfe, 0x09, 0x20,
-0x40, 0x02, 0xb8, 0x83, 0xf8, 0x8b, 0xc0, 0x08, 0x2d, 0xd3, 0x1d, 0x48,
-0xc7, 0x6a, 0x01, 0x98, 0x00, 0x99, 0xff, 0xf7, 0x51, 0xfc, 0xc2, 0x07,
-0xd2, 0x0f, 0x1a, 0x49, 0x03, 0xd0, 0x04, 0x23, 0xcd, 0x6d, 0x2b, 0x43,
-0x03, 0xe0, 0x04, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65,
-0x83, 0x08, 0x03, 0xd3, 0x02, 0x23, 0xcd, 0x6d, 0x2b, 0x43, 0x03, 0xe0,
-0x02, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, 0x61, 0x6a,
-0x81, 0x42, 0x0c, 0xd0, 0x60, 0x62, 0x0e, 0x48, 0x00, 0x2a, 0x03, 0xd0,
-0xff, 0x21, 0x21, 0x31, 0x39, 0x43, 0x03, 0xe0, 0xff, 0x23, 0x21, 0x33,
-0x9f, 0x43, 0x39, 0x1c, 0xc1, 0x62, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x68, 0x1c, 0x00, 0x80,
-0x00, 0x00, 0x00, 0x80, 0x28, 0x1c, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40,
-0xa4, 0x2a, 0x00, 0x80, 0x40, 0x00, 0x14, 0x00, 0x90, 0xb4, 0x01, 0x22,
-0x20, 0x28, 0x0f, 0xd2, 0x43, 0x00, 0x0f, 0x1c, 0x07, 0x49, 0x5c, 0x18,
-0x37, 0x23, 0x9b, 0x01, 0xe3, 0x18, 0x9f, 0x83, 0x82, 0x40, 0x07, 0x23,
-0x5b, 0x02, 0xc9, 0x18, 0x10, 0x1c, 0xca, 0x69, 0x10, 0x43, 0xc8, 0x61,
-0x90, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x0b, 0x48, 0x40, 0x69,
-0x0b, 0x49, 0xc9, 0x8b, 0x04, 0x22, 0x0a, 0x40, 0x0a, 0x49, 0x06, 0xd0,
-0x01, 0x23, 0xdb, 0x02, 0x98, 0x43, 0x01, 0x23, 0xca, 0x6d, 0x1a, 0x43,
-0x05, 0xe0, 0x01, 0x23, 0xdb, 0x02, 0x18, 0x43, 0xca, 0x6d, 0x52, 0x08,
-0x52, 0x00, 0xca, 0x65, 0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40,
-0xe8, 0x1b, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0,
-0xff, 0xf7, 0xde, 0xff, 0x01, 0x1c, 0x05, 0x20, 0x00, 0x90, 0x00, 0x20,
-0x01, 0xab, 0x18, 0x80, 0x04, 0x3b, 0x58, 0x70, 0x1b, 0x22, 0x00, 0xab,
-0x5a, 0x80, 0xd9, 0x80, 0x05, 0x49, 0xc9, 0x6d, 0xc0, 0x46, 0x02, 0x91,
-0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfd, 0xf7, 0x79, 0xf8, 0x04, 0xb0,
-0x08, 0xbc, 0x18, 0x47, 0xa4, 0x2a, 0x00, 0x80, 0x0f, 0x48, 0x01, 0x68,
-0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68,
-0x80, 0x0a, 0x03, 0xd3, 0x0b, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0,
-0x0a, 0x48, 0x80, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x4b, 0x98, 0x42,
-0x05, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x02, 0xd0, 0x07, 0x4b, 0x98, 0x42,
-0x01, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80,
-0x04, 0x99, 0x00, 0x00, 0x07, 0x99, 0x00, 0x00, 0x90, 0xb4, 0x01, 0x24,
-0x21, 0x1c, 0x18, 0x48, 0x02, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x02, 0x68,
-0x12, 0x0c, 0x02, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x21,
-0x09, 0x06, 0x09, 0x0e, 0x12, 0x4f, 0x13, 0x4a, 0x02, 0xd0, 0x38, 0x68,
-0x00, 0x0c, 0x00, 0xe0, 0x90, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x10, 0x4b,
-0x98, 0x42, 0x08, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x05, 0xd0, 0x0e, 0x4b,
-0x98, 0x42, 0x02, 0xd0, 0x02, 0x3b, 0x98, 0x42, 0x0c, 0xd1, 0x00, 0x29,
-0x02, 0xd0, 0xf8, 0x6a, 0x00, 0x0c, 0x00, 0xe0,
-0xd0, 0x6c, 0x40, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x20, 0x06, 0x00, 0x0e,
-0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, 0x10, 0x40,
-0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0x04, 0x99, 0x00, 0x00,
-0x07, 0x99, 0x00, 0x00, 0x0c, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2,
-0x01, 0x68, 0x09, 0x0c, 0x05, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x02, 0xd3,
-0x08, 0x48, 0x80, 0x68, 0x01, 0xe0, 0x08, 0x48, 0x40, 0x6c, 0x00, 0x04,
-0x00, 0x0c, 0x00, 0x21, 0x03, 0x28, 0x03, 0xd0, 0x40, 0x08, 0x01, 0xd3,
-0x01, 0x20, 0x70, 0x47, 0x08, 0x1c, 0xfc, 0xe7, 0x00, 0x00, 0x10, 0x40,
-0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x01, 0x27,
-0x1a, 0x4c, 0x25, 0x68, 0xff, 0xf7, 0x72, 0xff, 0x03, 0x1c, 0x19, 0x4a,
-0x02, 0x21, 0x01, 0x26, 0x18, 0x48, 0x01, 0x2b, 0x1b, 0xd1, 0xcb, 0x04,
-0x1e, 0x60, 0x55, 0x23, 0x03, 0x60, 0x00, 0x23, 0x43, 0x60, 0x06, 0x68,
-0x55, 0x2e, 0x1b, 0xd1, 0xaa, 0x26, 0x06, 0x60, 0x43, 0x60, 0x03, 0x68,
-0xaa, 0x2b, 0x15, 0xd1, 0x09, 0x23, 0x03, 0x60, 0x05, 0x23, 0x0f, 0x4f,
-0xc0, 0x46, 0x3b, 0x60, 0x03, 0x23, 0x0e, 0x4f, 0xc0, 0x46, 0x3b, 0x60,
-0x11, 0x60, 0x07, 0x68, 0x08, 0xe0, 0x08, 0x23, 0x23, 0x60, 0x04, 0x23,
-0x0a, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 0x06, 0x60, 0x27, 0x68,
-0xc0, 0x46, 0x25, 0x60, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x22, 0x40,
-0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x28, 0x40,
-0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0x30, 0xff, 0x01, 0x28, 0x05, 0xd1,
-0x19, 0x48, 0x00, 0x68, 0x19, 0x49, 0x49, 0x6b, 0x08, 0x40, 0x22, 0xe0,
-0x18, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c,
-0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 0x14, 0x48, 0x00, 0x68,
-0x00, 0x0c, 0x01, 0xe0, 0x13, 0x48, 0x80, 0x6c, 0x00, 0x04, 0x00, 0x0c,
-0x12, 0x4b, 0xc0, 0x18, 0x08, 0x28, 0x0b, 0xd2, 0x01, 0xa3, 0x1b, 0x5c,
-0x5b, 0x00, 0x9f, 0x44, 0x05, 0x03, 0x07, 0x03, 0x07, 0x07, 0x05, 0x03,
-0x03, 0x20, 0x02, 0xe0, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x01, 0x21,
-0x38, 0x60, 0x80, 0x07, 0x00, 0xd1, 0x00, 0x21, 0x08, 0x06, 0x00, 0x0e,
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x34, 0x6e, 0x21, 0x40,
-0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40,
-0x00, 0x00, 0x00, 0x80, 0xfe, 0x66, 0xff, 0xff, 0xf0, 0xb5, 0x82, 0xb0,
-0x07, 0x1c, 0x01, 0x20, 0x01, 0x90, 0xff, 0xf7, 0xe7, 0xfe, 0x01, 0x28,
-0x13, 0xd1, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x07, 0xd1, 0x00, 0x26,
-0xf6, 0x43, 0x34, 0x1c, 0xa8, 0x2f, 0x02, 0xd1, 0x30, 0x1c, 0x00, 0x96,
-0x35, 0x1c, 0x11, 0x20, 0x00, 0x04, 0x06, 0x62, 0x44, 0x62, 0x85, 0x62,
-0x00, 0x99, 0xc0, 0x46, 0xc1, 0x62, 0x00, 0x21, 0x08, 0x48, 0xc0, 0x46,
-0x01, 0x60, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x05, 0xd1, 0x01, 0x21,
-0x01, 0x60, 0xa8, 0x2f, 0x01, 0xd1, 0x03, 0x21, 0x01, 0x60, 0x01, 0x98,
-0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x34, 0x6e, 0x21, 0x40,
-0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c,
-0x12, 0x4c, 0x21, 0x68, 0x12, 0x48, 0x81, 0x42, 0x0b, 0xd0, 0x00, 0x23,
-0x21, 0x1c, 0xe2, 0x1d, 0xc1, 0x32, 0x00, 0xe0,
-0x08, 0xc1, 0x91, 0x42, 0xfc, 0xd3, 0x20, 0x60, 0xc8, 0x20, 0xa0, 0x80,
-0x67, 0x72, 0x38, 0x01, 0x00, 0xf0, 0x18, 0xf8, 0x27, 0x72, 0x0a, 0x48,
-0xc0, 0x46, 0xe0, 0x60, 0x09, 0x2f, 0x00, 0xdb, 0x00, 0x27, 0xe0, 0x19,
-0x01, 0x7d, 0x01, 0x31, 0x01, 0x75, 0xe0, 0x88, 0x01, 0x30, 0xe0, 0x80,
-0x01, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x80,
-0xee, 0xff, 0xc0, 0xd0, 0x08, 0x10, 0x00, 0x03, 0x80, 0xb4, 0x08, 0x4a,
-0xd1, 0x1d, 0x89, 0x31, 0x0b, 0x7a, 0x20, 0x2b, 0x01, 0xd3, 0x00, 0x23,
-0x0b, 0x72, 0x07, 0x1c, 0x08, 0x7a, 0x43, 0x1c, 0x0b, 0x72, 0x80, 0x18,
-0x90, 0x30, 0x47, 0x72, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x80,
-0x07, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x01, 0x20,
-0x00, 0x2a, 0x06, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x09, 0x68,
-0x89, 0x0a, 0x00, 0xd2, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40,
-0x90, 0xb5, 0x07, 0x1c, 0x09, 0x4c, 0x38, 0x1c, 0x21, 0x1c, 0xfc, 0xf7,
-0x91, 0xff, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 0x01, 0x23, 0xd8, 0x42,
-0x01, 0xd1, 0x00, 0x0c, 0xe0, 0x80, 0x00, 0x21, 0x20, 0x1c, 0xfc, 0xf7,
-0xc5, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc4, 0x66, 0x21, 0x40,
-0xf8, 0xb5, 0x07, 0x1c, 0x79, 0x7a, 0x76, 0x48, 0x00, 0x23, 0x76, 0x4c,
-0x01, 0x29, 0x5d, 0xd1, 0xa2, 0x88, 0xc0, 0x46, 0x00, 0x92, 0xa1, 0x89,
-0x8a, 0x42, 0x74, 0xda, 0xfa, 0x7a, 0x00, 0x2a, 0x15, 0xd0, 0x7a, 0x6c,
-0x00, 0x2a, 0x12, 0xd0, 0x8a, 0x42, 0x10, 0xd8, 0x00, 0x9a, 0x51, 0x1c,
-0xa1, 0x80, 0xa1, 0x88, 0xc0, 0x46, 0x41, 0x81, 0x78, 0x6c, 0x6b, 0x4e,
-0xc0, 0x46, 0xf0, 0x80, 0xa0, 0x6a, 0x58, 0x23, 0x79, 0x6c, 0x59, 0x43,
-0x40, 0x18, 0xc1, 0x1a, 0x28, 0xe0, 0x22, 0x88, 0x01, 0x32, 0x12, 0x04,
-0x12, 0x0c, 0x22, 0x80, 0x8a, 0x42, 0x00, 0xdb, 0x23, 0x80, 0x00, 0x22,
-0x00, 0x29, 0x69, 0xdd, 0x5f, 0x4c, 0xa4, 0x6a, 0x5e, 0x4b, 0x1d, 0x88,
-0x58, 0x23, 0x6b, 0x43, 0xe3, 0x18, 0xde, 0x1d, 0x01, 0x36, 0x01, 0x23,
-0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x15, 0xd1, 0x58, 0x49,
-0x00, 0x9a, 0x01, 0x32, 0x8a, 0x80, 0x8a, 0x88, 0xc0, 0x46, 0x42, 0x81,
-0x08, 0x88, 0x01, 0x30, 0x54, 0x4e, 0xc0, 0x46, 0xf0, 0x80, 0x58, 0x20,
-0x68, 0x43, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x39, 0xfb, 0xf0, 0x88,
-0x00, 0x04, 0x00, 0x14, 0x95, 0xe0, 0x4d, 0x4b, 0x01, 0x35, 0x2d, 0x04,
-0x2d, 0x0c, 0x1d, 0x80, 0x8d, 0x42, 0x01, 0xdb, 0x00, 0x25, 0x1d, 0x80,
-0x01, 0x32, 0x12, 0x04, 0x12, 0x14, 0x91, 0x42, 0xce, 0xdc, 0x81, 0xe0,
-0xe1, 0x88, 0xe2, 0x89, 0x91, 0x42, 0x18, 0xda, 0xf9, 0x7a, 0x00, 0x29,
-0x2f, 0xd0, 0x79, 0x6c, 0x49, 0x04, 0x49, 0x0c, 0x79, 0x64, 0x2a, 0xd0,
-0xe2, 0x89, 0x91, 0x42, 0x27, 0xd8, 0xe1, 0x88, 0x01, 0x31, 0xe1, 0x80,
-0xe1, 0x88, 0xc0, 0x46, 0x81, 0x81, 0x01, 0x23, 0xdb, 0x03, 0x78, 0x6c,
-0x18, 0x43, 0x3a, 0x4e, 0xc0, 0x46, 0xf0, 0x80, 0x00, 0xe0, 0x63, 0xe0,
-0xe0, 0x6a, 0x79, 0x6c, 0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x40, 0x18,
-0xc1, 0x1f, 0x59, 0x39, 0x38, 0x1c, 0x00, 0xf0, 0x0f, 0xfb, 0xe0, 0x6a,
-0x79, 0x6c, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0x80, 0x18, 0x01, 0x39,
-0x09, 0x04, 0x09, 0x0c, 0x60, 0x38, 0x00, 0xf0, 0x89, 0xfb, 0xb6, 0xe7,
-0x4a, 0xe0, 0x61, 0x88, 0x01, 0x31, 0x09, 0x04,
-0x09, 0x0c, 0x61, 0x80, 0xe2, 0x89, 0x91, 0x42, 0x00, 0xdb, 0x63, 0x80,
-0x00, 0x21, 0x00, 0x2a, 0x3e, 0xdd, 0x24, 0x4c, 0xe4, 0x6a, 0x23, 0x4b,
-0x5d, 0x88, 0x6b, 0x00, 0x5b, 0x19, 0x5b, 0x01, 0xe3, 0x18, 0xde, 0x1d,
-0x01, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06,
-0x20, 0xd1, 0x1c, 0x4e, 0xf1, 0x88, 0x01, 0x31, 0xf1, 0x80, 0xf1, 0x88,
-0xc0, 0x46, 0x81, 0x81, 0x70, 0x88, 0x01, 0x23, 0xdb, 0x03, 0x01, 0x30,
-0x18, 0x43, 0x17, 0x49, 0xc0, 0x46, 0xc8, 0x80, 0x68, 0x00, 0x40, 0x19,
-0x40, 0x01, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0xcf, 0xfa, 0x71, 0x88,
-0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0xf0, 0x6a, 0x80, 0x18, 0x00, 0xf0,
-0x4d, 0xfb, 0x0e, 0x49, 0xc8, 0x88, 0x79, 0xe7, 0x0b, 0x4b, 0x01, 0x35,
-0x2d, 0x04, 0x2d, 0x0c, 0x5d, 0x80, 0x95, 0x42, 0x01, 0xdb, 0x00, 0x25,
-0x5d, 0x80, 0x01, 0x31, 0x09, 0x04, 0x09, 0x14, 0x8a, 0x42, 0xc2, 0xdc,
-0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x00, 0x20, 0xc0, 0x43, 0xf8, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x4c, 0x2b, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80,
-0xc4, 0x66, 0x21, 0x40, 0xf0, 0xb4, 0x06, 0x1c, 0x01, 0x23, 0xdb, 0x03,
-0x33, 0x40, 0x01, 0x24, 0x44, 0x4f, 0x00, 0x20, 0x44, 0x4a, 0x45, 0x4d,
-0xd1, 0x1d, 0x39, 0x31, 0x00, 0x2b, 0x41, 0xd0, 0xe3, 0x03, 0xf3, 0x1a,
-0x73, 0xd0, 0xee, 0x89, 0x9e, 0x42, 0x71, 0xd3, 0xee, 0x88, 0x00, 0x2e,
-0x6d, 0xd0, 0xed, 0x6a, 0x5e, 0x1e, 0x73, 0x00, 0x9b, 0x19, 0x5b, 0x01,
-0xed, 0x18, 0xae, 0x68, 0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0,
-0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0x40, 0x35, 0xad, 0x8b, 0xad, 0x00,
-0x35, 0x4e, 0x76, 0x6a, 0xc0, 0x46, 0x70, 0x51, 0x55, 0x89, 0x01, 0x35,
-0x55, 0x81, 0x32, 0x4e, 0xf2, 0x6a, 0xd2, 0x18, 0x90, 0x60, 0xf2, 0x6a,
-0xd2, 0x18, 0x90, 0x63, 0xf2, 0x6a, 0xd2, 0x18, 0xd0, 0x63, 0xf2, 0x6a,
-0xd2, 0x18, 0x10, 0x64, 0xf2, 0x6a, 0xd2, 0x18, 0x50, 0x64, 0xf2, 0x6a,
-0xd2, 0x18, 0x90, 0x64, 0xf2, 0x6a, 0xd2, 0x18, 0xd0, 0x64, 0xf0, 0x88,
-0x01, 0x38, 0xf0, 0x80, 0xf0, 0x88, 0xc0, 0x46, 0x88, 0x81, 0x24, 0x49,
-0x00, 0x28, 0x39, 0xd1, 0x4f, 0x80, 0x37, 0xe0, 0x00, 0x2e, 0x38, 0xd9,
-0xab, 0x89, 0xb3, 0x42, 0x30, 0xd3, 0xab, 0x88, 0x00, 0x2b, 0x2c, 0xd0,
-0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x2a, 0x1c, 0xad, 0x6a, 0x58, 0x23,
-0x01, 0x3e, 0x73, 0x43, 0xed, 0x18, 0xae, 0x68, 0x36, 0x06, 0x36, 0x0e,
-0x03, 0x2e, 0x02, 0xd0, 0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0xa8, 0x60,
-0x95, 0x6a, 0xed, 0x18, 0xa8, 0x63, 0x95, 0x6a, 0xed, 0x18, 0xe8, 0x63,
-0x95, 0x6a, 0xed, 0x18, 0x28, 0x64, 0x95, 0x6a, 0xed, 0x18, 0x68, 0x64,
-0x95, 0x6a, 0xed, 0x18, 0xa8, 0x64, 0x95, 0x6a, 0xeb, 0x18, 0xd8, 0x64,
-0x90, 0x88, 0x01, 0x38, 0x90, 0x80, 0x90, 0x88, 0xc0, 0x46, 0x48, 0x81,
-0x00, 0x28, 0x03, 0xd1, 0x01, 0xe0, 0x04, 0xe0, 0x03, 0xe0, 0x17, 0x80,
-0x20, 0x1c, 0xf0, 0xbc, 0x70, 0x47, 0xca, 0x89, 0x01, 0x32, 0xca, 0x81,
-0xf9, 0xe7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80,
-0x4c, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x00, 0x21, 0x41, 0x60, 0x10, 0x49,
-0x4a, 0x68, 0x00, 0x2a, 0x10, 0xd1, 0xca, 0x68, 0x00, 0x2a, 0x04, 0xd0,
-0xca, 0x1d, 0x19, 0x32, 0x12, 0x79, 0x00, 0x2a, 0x08, 0xd0, 0x4a, 0x69,
-0x00, 0x2a, 0x0b, 0xd1, 0x88, 0x61, 0x48, 0x61,
-0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x4a, 0x69, 0x00, 0x2a,
-0x02, 0xd1, 0x88, 0x61, 0x48, 0x61, 0xf7, 0xe7, 0x8a, 0x69, 0xc0, 0x46,
-0x50, 0x60, 0x88, 0x61, 0xf2, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0xb0, 0xb5, 0x2a, 0x48, 0x40, 0x69, 0x00, 0x28, 0x4c, 0xd0, 0x08, 0x22,
-0xc1, 0x68, 0x0a, 0x40, 0x00, 0x27, 0x27, 0x4b, 0xd9, 0x1d, 0xb9, 0x31,
-0x00, 0x2a, 0x11, 0xd0, 0x04, 0x22, 0x25, 0x4c, 0xc0, 0x46, 0x0c, 0x61,
-0x24, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x24, 0x4c, 0xc0, 0x46, 0x8c, 0x62,
-0x23, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x23, 0x4c, 0xc0, 0x46, 0x0c, 0x63,
-0x4f, 0x63, 0x12, 0xe0, 0x05, 0x22, 0x21, 0x4c, 0xc0, 0x46, 0x0c, 0x61,
-0x20, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x20, 0x4c, 0xc0, 0x46, 0x8c, 0x62,
-0x1f, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x1f, 0x4c, 0xc0, 0x46, 0x0c, 0x63,
-0x1e, 0x4c, 0xc0, 0x46, 0x4c, 0x63, 0x40, 0x24, 0xcc, 0x82, 0x4f, 0x83,
-0x1c, 0x4f, 0x00, 0x21, 0x00, 0x2a, 0x0c, 0xd9, 0x8c, 0x00, 0x05, 0x19,
-0x6d, 0x6a, 0x7d, 0x40, 0xe4, 0x18, 0xff, 0x34, 0x01, 0x34, 0x65, 0x62,
-0x01, 0x31, 0x91, 0x42, 0xf4, 0xd3, 0x10, 0x29, 0x07, 0xd2, 0x8a, 0x00,
-0xd2, 0x18, 0xff, 0x32, 0x01, 0x32, 0x57, 0x62, 0x01, 0x31, 0x10, 0x29,
-0xf7, 0xd3, 0x11, 0x49, 0x00, 0xf0, 0x22, 0xf8, 0xb0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0xac, 0xab, 0x20, 0x40,
-0x28, 0x01, 0x40, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
-0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x20, 0x01, 0x40, 0x00,
-0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe,
-0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, 0x36, 0x36, 0x36, 0x36,
-0x30, 0x80, 0x20, 0x40, 0xb0, 0xb5, 0x0f, 0x1c, 0x15, 0x4d, 0xe9, 0x1d,
-0xc9, 0x31, 0x15, 0x4c, 0x23, 0x1c, 0x15, 0x4a, 0x00, 0x20, 0xfc, 0xf7,
-0x44, 0xfb, 0xe9, 0x1d, 0xff, 0x31, 0x1e, 0x31, 0x23, 0x1c, 0x0d, 0x1c,
-0x11, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x3b, 0xfb, 0x29, 0x1c, 0x23, 0x1c,
-0x0e, 0x4a, 0x00, 0x20, 0xfc, 0xf7, 0x35, 0xfb, 0x39, 0x1c, 0x23, 0x1c,
-0x0c, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x2f, 0xfb, 0x00, 0x21, 0x0b, 0x48,
-0xc2, 0x1d, 0x19, 0x32, 0x51, 0x71, 0x01, 0x21, 0xff, 0x30, 0x01, 0x30,
-0x41, 0x62, 0x08, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0xac, 0xab, 0x20, 0x40, 0x75, 0x08, 0xff, 0xff, 0x28, 0x00, 0x03, 0x00,
-0x40, 0x00, 0x02, 0x00, 0x14, 0x00, 0x07, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0xf0, 0xb5, 0x37, 0x4a, 0x50, 0x69, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30,
-0x18, 0x43, 0x00, 0x68, 0x01, 0x06, 0x09, 0x0e, 0x33, 0x4b, 0x01, 0x29,
-0x49, 0xd1, 0x1f, 0x68, 0x19, 0x1c, 0x32, 0x4b, 0x9f, 0x42, 0x04, 0xd1,
-0xff, 0xf7, 0x3e, 0xff, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23,
-0x9f, 0x00, 0xcc, 0x59, 0x55, 0x69, 0xef, 0x19, 0x3c, 0x61, 0x01, 0x33,
-0x05, 0x2b, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 0x02, 0x23, 0x18, 0x43,
-0x53, 0x69, 0xc0, 0x46, 0x98, 0x60, 0x50, 0x69, 0x08, 0x23, 0xc2, 0x68,
-0x13, 0x40, 0x25, 0x4f, 0xfa, 0x1d, 0xb9, 0x32, 0x00, 0x2b, 0x02, 0xd0,
-0x04, 0x23, 0x23, 0x4c, 0x01, 0xe0, 0x05, 0x23, 0x22, 0x4c, 0xc0, 0x46,
-0x14, 0x61, 0x40, 0x24, 0xd4, 0x82, 0x00, 0x24, 0x54, 0x83, 0x20, 0x4c,
-0x00, 0x22, 0x00, 0x2b, 0x0c, 0xd9, 0x95, 0x00,
-0x46, 0x19, 0x76, 0x6a, 0x66, 0x40, 0xed, 0x19, 0xff, 0x35, 0x01, 0x35,
-0x6e, 0x62, 0x01, 0x32, 0x9a, 0x42, 0xf4, 0xd3, 0x10, 0x2a, 0x07, 0xd2,
-0x93, 0x00, 0xdb, 0x19, 0xff, 0x33, 0x01, 0x33, 0x5c, 0x62, 0x01, 0x32,
-0x10, 0x2a, 0xf7, 0xd3, 0xff, 0xf7, 0x70, 0xff, 0xbc, 0xe7, 0x00, 0x21,
-0x8f, 0x00, 0xdc, 0x59, 0x55, 0x69, 0xef, 0x19, 0x7c, 0x62, 0x01, 0x31,
-0x05, 0x29, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 0x03, 0x23, 0x18, 0x43,
-0x51, 0x69, 0xc0, 0x46, 0x88, 0x60, 0x50, 0x69, 0x40, 0x68, 0xc0, 0x46,
-0x50, 0x61, 0x09, 0x48, 0xfc, 0xf7, 0xa4, 0xfa, 0xa4, 0xe7, 0x00, 0x00,
-0x6c, 0x06, 0x00, 0x80, 0x30, 0x80, 0x20, 0x40, 0x67, 0x45, 0x23, 0x01,
-0xac, 0xab, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 0x20, 0x01, 0x40, 0x00,
-0x5c, 0x5c, 0x5c, 0x5c, 0x11, 0x31, 0xff, 0xff, 0xf0, 0xb5, 0x07, 0x1c,
-0x3b, 0x48, 0x3c, 0x4c, 0x08, 0x21, 0x20, 0x60, 0xa1, 0x80, 0x00, 0x20,
-0x20, 0x81, 0xe1, 0x80, 0x60, 0x81, 0x39, 0x48, 0xc0, 0x46, 0xe0, 0x60,
-0x38, 0x48, 0xc0, 0x46, 0x20, 0x61, 0x38, 0x48, 0xc0, 0x46, 0x60, 0x61,
-0x37, 0x48, 0xc0, 0x46, 0xa0, 0x61, 0x37, 0x48, 0xc0, 0x46, 0xe0, 0x61,
-0x36, 0x48, 0xc0, 0x46, 0x20, 0x62, 0x36, 0x48, 0xc0, 0x46, 0x60, 0x62,
-0x35, 0x48, 0xc0, 0x46, 0xa0, 0x62, 0x35, 0x48, 0xc0, 0x46, 0xe0, 0x62,
-0x34, 0x48, 0xc0, 0x46, 0x20, 0x63, 0x34, 0x48, 0xc0, 0x46, 0x60, 0x63,
-0x33, 0x48, 0xc0, 0x46, 0xa0, 0x63, 0x33, 0x48, 0xc0, 0x46, 0xe0, 0x63,
-0x32, 0x48, 0xc0, 0x46, 0x20, 0x64, 0x32, 0x48, 0xc0, 0x46, 0x60, 0x64,
-0x31, 0x48, 0xc0, 0x46, 0xa0, 0x64, 0x31, 0x48, 0xc0, 0x46, 0xe0, 0x64,
-0x30, 0x48, 0xc0, 0x46, 0x20, 0x65, 0x30, 0x49, 0xc8, 0x68, 0x02, 0x04,
-0x89, 0x69, 0x4a, 0x40, 0xe3, 0x1d, 0x79, 0x33, 0x09, 0x04, 0xc9, 0x43,
-0xc0, 0x43, 0x48, 0x40, 0xe1, 0x1d, 0xb9, 0x31, 0xda, 0x63, 0x08, 0x60,
-0x29, 0x4d, 0x21, 0x1c, 0x2b, 0x1c, 0x29, 0x4a, 0x00, 0x20, 0xfc, 0xf7,
-0x3e, 0xfa, 0x28, 0x4a, 0xe1, 0x1d, 0xb5, 0x31, 0x01, 0x20, 0x2b, 0x1c,
-0x0e, 0x1c, 0xfc, 0xf7, 0x36, 0xfa, 0x24, 0x4a, 0x00, 0x20, 0x31, 0x1c,
-0x2b, 0x1c, 0xfc, 0xf7, 0x30, 0xfa, 0xe1, 0x1d, 0x4d, 0x31, 0x2b, 0x1c,
-0x20, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x29, 0xfa, 0xe0, 0x1d, 0x5d, 0x30,
-0x01, 0x68, 0x00, 0x29, 0xfc, 0xd0, 0x60, 0x6d, 0xc0, 0x46, 0x38, 0x65,
-0x20, 0x6e, 0xc0, 0x46, 0x78, 0x65, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x80, 0x00, 0x08, 0x00, 0x8c, 0xb9, 0x20, 0x40, 0x81, 0x81, 0x48, 0xbd,
-0x79, 0x56, 0x23, 0x8c, 0x93, 0x0c, 0x82, 0x95, 0x1d, 0x0e, 0x12, 0xcf,
-0x9b, 0x3b, 0xc0, 0xe9, 0xe6, 0x55, 0x7c, 0x82, 0x99, 0xf6, 0x78, 0x02,
-0xd1, 0xd7, 0x25, 0x73, 0x72, 0x8c, 0x33, 0x10, 0xf7, 0x03, 0xf1, 0x42,
-0x6c, 0x9b, 0x4a, 0xa7, 0x82, 0x8e, 0x23, 0xa9, 0x90, 0xb1, 0x82, 0x8e,
-0xdc, 0x3f, 0xfb, 0x29, 0x00, 0x62, 0x22, 0x45, 0x88, 0x2b, 0xf1, 0x85,
-0x12, 0x61, 0xd1, 0x73, 0x6e, 0xb1, 0x11, 0x16, 0x08, 0x83, 0x20, 0x40,
-0x75, 0x08, 0xff, 0xff, 0x54, 0x00, 0x03, 0x00, 0x08, 0x00, 0x02, 0x00,
-0x14, 0x00, 0x03, 0x00, 0x80, 0xb5, 0x0f, 0x1c, 0x39, 0x1c, 0x00, 0xf0,
-0x33, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0x4c, 0xff, 0x03, 0x48, 0x01, 0x89,
-0x01, 0x31, 0x01, 0x81, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c,
-0x0f, 0x1c, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0xe0, 0x68,
-0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43,
-0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06,
-0x08, 0x43, 0x38, 0x65, 0x20, 0x69, 0xc0, 0x46, 0x78, 0x65, 0x60, 0x69,
-0xc0, 0x46, 0xb8, 0x65, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80,
-0x90, 0xb5, 0x00, 0x22, 0x93, 0x00, 0x1f, 0x18, 0xbf, 0x69, 0x5b, 0x18,
-0x5f, 0x62, 0x01, 0x32, 0x05, 0x2a, 0xf7, 0xd3, 0x07, 0x7a, 0xfb, 0x08,
-0x03, 0xd3, 0x00, 0x23, 0x92, 0x00, 0x52, 0x18, 0x13, 0x62, 0x07, 0x6b,
-0xc0, 0x46, 0x8f, 0x63, 0xc7, 0x6a, 0xc0, 0x46, 0xcf, 0x63, 0x87, 0x6b,
-0xc0, 0x46, 0x0f, 0x64, 0x47, 0x6b, 0xc0, 0x46, 0x4f, 0x64, 0x07, 0x6c,
-0xc0, 0x46, 0x8f, 0x64, 0xc2, 0x6b, 0xc0, 0x46, 0xca, 0x64, 0xc2, 0x88,
-0xc0, 0x46, 0x0a, 0x80, 0x82, 0x7a, 0x12, 0x06, 0x03, 0x7a, 0x1b, 0x04,
-0x1a, 0x43, 0xc3, 0x88, 0x1b, 0x02, 0x1a, 0x43, 0x43, 0x7a, 0xdb, 0x07,
-0x1a, 0x43, 0x8a, 0x60, 0x17, 0x1c, 0x83, 0x7a, 0x5a, 0x08, 0x05, 0xd3,
-0x14, 0x22, 0x1c, 0x1c, 0xa3, 0x08, 0x02, 0xd2, 0x15, 0x22, 0x00, 0xe0,
-0x00, 0x22, 0x00, 0x7a, 0x43, 0x08, 0x10, 0xd3, 0xc0, 0x08, 0x02, 0xd3,
-0x88, 0x20, 0x10, 0x43, 0x01, 0xe0, 0x80, 0x20, 0x10, 0x43, 0x3a, 0x0a,
-0x12, 0x02, 0x01, 0x23, 0x1a, 0x43, 0xc8, 0x60, 0x8a, 0x60, 0x08, 0x1c,
-0xff, 0xf7, 0x78, 0xfd, 0x05, 0xe0, 0x38, 0x0a, 0x00, 0x02, 0x03, 0x23,
-0x18, 0x43, 0x88, 0x60, 0xca, 0x60, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31,
-0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80,
-0xf0, 0xb4, 0x02, 0x6d, 0x14, 0x4c, 0x15, 0x1c, 0xe7, 0x69, 0xbd, 0x40,
-0x13, 0x1c, 0x26, 0x6a, 0xf3, 0x40, 0x5d, 0x40, 0x2e, 0x1c, 0x45, 0x6d,
-0xbd, 0x40, 0x6e, 0x40, 0x2b, 0x1c, 0x35, 0x1c, 0xfd, 0x40, 0x2f, 0x1c,
-0xbb, 0x00, 0x65, 0x6a, 0xeb, 0x58, 0x00, 0x2b, 0x08, 0xd0, 0x23, 0x69,
-0x01, 0x37, 0x9f, 0x42, 0x00, 0xd3, 0x00, 0x27, 0xbe, 0x00, 0xae, 0x59,
-0x00, 0x2e, 0xf7, 0xd1, 0xa4, 0x69, 0xa2, 0x40, 0x11, 0x43, 0x05, 0x4b,
-0x19, 0x43, 0xba, 0x00, 0xa9, 0x50, 0x40, 0x30, 0x87, 0x83, 0xf0, 0xbc,
-0x70, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
-0x80, 0xb4, 0x00, 0x22, 0x00, 0x23, 0x00, 0x29, 0x05, 0xd9, 0x07, 0x78,
-0x7a, 0x40, 0x01, 0x30, 0x01, 0x33, 0x8b, 0x42, 0xf9, 0xd3, 0xd0, 0x43,
-0x00, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0x07, 0x1c,
-0x00, 0x24, 0xff, 0x26, 0x09, 0x36, 0x20, 0x1c, 0x00, 0xf0, 0x9a, 0xf8,
-0x00, 0xf0, 0xb8, 0xf9, 0x05, 0x1c, 0x00, 0xf0, 0xc7, 0xfa, 0x3d, 0x70,
-0x28, 0x1c, 0x01, 0x37, 0x01, 0x34, 0xb4, 0x42, 0xf1, 0xd3, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x00, 0xf0, 0x93, 0xf8, 0x00, 0xf0,
-0xa7, 0xf9, 0x07, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x38, 0x0a, 0xf6, 0xd3,
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x82, 0xb0, 0x02, 0x98,
-0x41, 0x02, 0x53, 0x20, 0x00, 0xf0, 0x64, 0xf8, 0x00, 0xf0, 0xa8, 0xfa,
-0xff, 0xf7, 0xe8, 0xff, 0x00, 0x24, 0x00, 0x20, 0x01, 0x90, 0x2e, 0x20,
-0x00, 0x90, 0x00, 0x25, 0x00, 0x27, 0x02, 0x98, 0x01, 0x28, 0x04, 0xd1,
-0x00, 0x98, 0x84, 0x42, 0x01, 0xd3, 0x00, 0x26,
-0x09, 0xe0, 0x01, 0x98, 0x41, 0x1c, 0x01, 0x91, 0x00, 0xf0, 0x60, 0xf8,
-0x00, 0xf0, 0x7e, 0xf9, 0x06, 0x1c, 0x00, 0xf0, 0x8d, 0xfa, 0xf8, 0x00,
-0x86, 0x40, 0x35, 0x43, 0x01, 0x34, 0x01, 0x37, 0x04, 0x2f, 0xe6, 0xd3,
-0x03, 0x99, 0x20, 0xc1, 0x03, 0x91, 0xff, 0x23, 0x09, 0x33, 0x9c, 0x42,
-0xdd, 0xd3, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5,
-0x04, 0x1c, 0x0f, 0x1c, 0x01, 0x2c, 0x2a, 0xd0, 0x16, 0x48, 0xc0, 0x6f,
-0x40, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x00, 0x26, 0x20, 0xcf,
-0xb1, 0x00, 0x84, 0x20, 0x00, 0xf0, 0x24, 0xf8, 0x28, 0x1c, 0x00, 0xf0,
-0xdf, 0xf9, 0x28, 0x0a, 0x00, 0xf0, 0xdc, 0xf9, 0x28, 0x0c, 0x00, 0xf0,
-0xd9, 0xf9, 0x28, 0x0e, 0x00, 0xf0, 0xd6, 0xf9, 0x00, 0xf0, 0x5c, 0xfa,
-0x01, 0x36, 0x42, 0x2e, 0xe9, 0xd3, 0x61, 0x02, 0x83, 0x20, 0x00, 0xf0,
-0x0f, 0xf8, 0x00, 0xf0, 0x53, 0xfa, 0xff, 0xf7, 0x93, 0xff, 0x04, 0x48,
-0xc0, 0x6f, 0x40, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c,
-0x0f, 0x1c, 0x00, 0xf0, 0x59, 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9,
-0x38, 0x0c, 0x00, 0xf0, 0xb3, 0xf9, 0x38, 0x0a, 0x00, 0xf0, 0xb0, 0xf9,
-0x38, 0x1c, 0x00, 0xf0, 0xad, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0x01, 0x1c, 0x54, 0x20, 0xff, 0xf7, 0xe7, 0xff, 0x00, 0x20,
-0x00, 0xf0, 0xa2, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0,
-0x3d, 0xfa, 0x57, 0x20, 0x00, 0xf0, 0x9a, 0xf9, 0x08, 0xbc, 0x18, 0x47,
-0x90, 0xb5, 0x08, 0x4f, 0xfa, 0x6f, 0x20, 0x23, 0x14, 0x68, 0x9c, 0x43,
-0x14, 0x60, 0x23, 0x1c, 0xff, 0xf7, 0x65, 0xff, 0xf8, 0x6f, 0x20, 0x23,
-0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x90, 0xb5, 0x08, 0x4f, 0xfa, 0x6f, 0x20, 0x23,
-0x14, 0x68, 0x9c, 0x43, 0x14, 0x60, 0x23, 0x1c, 0xff, 0xf7, 0x87, 0xff,
-0xf8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x04, 0x1c,
-0x0f, 0x1c, 0x18, 0x4e, 0xf0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x99, 0x43,
-0x01, 0x60, 0x61, 0x02, 0x53, 0x20, 0xff, 0xf7, 0xa5, 0xff, 0x00, 0xf0,
-0xe9, 0xf9, 0xff, 0xf7, 0x29, 0xff, 0xf8, 0x1d, 0x05, 0x30, 0x01, 0x2c,
-0x03, 0xd1, 0x22, 0x2f, 0x01, 0xd3, 0x00, 0x27, 0x0f, 0xe0, 0x44, 0x1c,
-0xff, 0xf7, 0xaa, 0xff, 0x00, 0xf0, 0xc8, 0xf8, 0x07, 0x1c, 0x00, 0xf0,
-0xd7, 0xf9, 0x20, 0x1c, 0xff, 0xf7, 0xa2, 0xff, 0x00, 0xf0, 0xc0, 0xf8,
-0x05, 0x1c, 0x00, 0xf0, 0xcf, 0xf9, 0xf0, 0x6f, 0x20, 0x23, 0x01, 0x68,
-0x19, 0x43, 0x01, 0x60, 0x28, 0x02, 0x38, 0x43, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0xc2, 0xb0,
-0x14, 0x1c, 0x0d, 0x1c, 0x07, 0x1c, 0x01, 0x2f, 0x2f, 0xd0, 0x79, 0x02,
-0x19, 0x4e, 0xf0, 0x6f, 0x20, 0x23, 0x02, 0x68, 0x9a, 0x43, 0x02, 0x60,
-0x53, 0x20, 0xff, 0xf7, 0x6b, 0xff, 0x00, 0xf0, 0xaf, 0xf9, 0xff, 0xf7,
-0xef, 0xfe, 0x68, 0x46, 0xff, 0xf7, 0xd6, 0xfe, 0x6a, 0x46, 0xe8, 0x1d,
-0x05, 0x30, 0x14, 0x54, 0x21, 0x0a, 0x68, 0x44, 0x41, 0x70, 0x68, 0x46,
-0x00, 0x99, 0x0c, 0x30, 0xff, 0xf7, 0xba, 0xfe, 0x02, 0xab, 0x18, 0x70,
-0x00, 0x20, 0x58, 0x70, 0x68, 0x46, 0x0c, 0x21,
-0xff, 0xf7, 0xb2, 0xfe, 0x02, 0xab, 0x58, 0x70, 0x69, 0x46, 0x38, 0x1c,
-0xff, 0xf7, 0x15, 0xff, 0xf0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43,
-0x01, 0x60, 0x42, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0xff, 0xb5, 0xc2, 0xb0, 0x07, 0x1c, 0x01, 0x2f,
-0x01, 0xd1, 0x01, 0x20, 0x36, 0xe0, 0x6b, 0x46, 0x00, 0x20, 0xc4, 0x43,
-0x10, 0xc3, 0x01, 0x30, 0x42, 0x28, 0xfb, 0xd3, 0x68, 0x46, 0x0c, 0x30,
-0x03, 0x1c, 0x00, 0x24, 0x00, 0x2a, 0x0a, 0xd9, 0x0e, 0x88, 0xc0, 0x46,
-0x06, 0x70, 0x0e, 0x88, 0x36, 0x12, 0x46, 0x70, 0x02, 0x30, 0x02, 0x31,
-0x02, 0x34, 0x94, 0x42, 0xf4, 0xd3, 0x00, 0x92, 0x18, 0x1c, 0x11, 0x1c,
-0xff, 0xf7, 0x7c, 0xfe, 0x04, 0x1c, 0x00, 0x20, 0x01, 0x90, 0x02, 0xab,
-0x1c, 0x70, 0x58, 0x70, 0x9d, 0x70, 0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7,
-0x71, 0xfe, 0x02, 0xab, 0x58, 0x70, 0x45, 0x9b, 0x1d, 0x06, 0x2d, 0x0e,
-0xac, 0x42, 0x03, 0xd1, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x3e, 0xff,
-0x01, 0x20, 0xac, 0x42, 0x00, 0xd1, 0x00, 0x20, 0x46, 0xb0, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc2, 0xb0, 0x0f, 0x1c, 0x41, 0x02,
-0x14, 0x4c, 0xe0, 0x6f, 0x20, 0x23, 0x02, 0x68, 0x9a, 0x43, 0x02, 0x60,
-0x53, 0x20, 0xff, 0xf7, 0xef, 0xfe, 0x00, 0xf0, 0x33, 0xf9, 0xff, 0xf7,
-0x73, 0xfe, 0x68, 0x46, 0xff, 0xf7, 0x5a, 0xfe, 0xe0, 0x6f, 0x20, 0x23,
-0x01, 0x68, 0x19, 0x43, 0x02, 0xad, 0x01, 0x60, 0x6d, 0x78, 0x00, 0x24,
-0x02, 0xab, 0x5c, 0x70, 0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7, 0x3c, 0xfe,
-0xa8, 0x42, 0x02, 0xd1, 0x00, 0x98, 0x87, 0x42, 0x01, 0xd3, 0x20, 0x1c,
-0x00, 0xe0, 0x01, 0x20, 0x42, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0xfc, 0x46, 0x60, 0x47, 0x00, 0x00, 0xa0, 0xe3,
-0xb4, 0x22, 0x9f, 0xe5, 0xb4, 0x32, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5,
-0x81, 0x03, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x01, 0x03, 0x80, 0xe1,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x93, 0xe5, 0x81, 0x02, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5,
-0x01, 0x02, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x81, 0x01, 0x80, 0xe1,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x93, 0xe5, 0x01, 0x01, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5,
-0x81, 0x00, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5,
-0x01, 0x00, 0x80, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47,
-0xa4, 0x21, 0x9f, 0xe5, 0xa8, 0x31, 0x9f, 0xe5, 0xa0, 0x13, 0xa0, 0xe1,
-0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x20, 0x13, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0xa0, 0x12, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x20, 0x12, 0xa0, 0xe1,
-0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0xa0, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x20, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0xa0, 0x10, 0xa0, 0xe1,
-0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47, 0xa0, 0x30, 0x9f, 0xe5,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47, 0x70, 0x30, 0x9f, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47, 0x34, 0x20, 0x9f, 0xe5,
-0x3c, 0x30, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf8, 0x00, 0x18, 0x40,
-0x04, 0x01, 0x18, 0x40, 0x00, 0x01, 0x18, 0x40, 0xfc, 0x00, 0x18, 0x40,
-0x80, 0xb5, 0x00, 0xf0, 0x0c, 0xf8, 0x00, 0x27, 0x38, 0x1c, 0x00, 0xf0,
-0x47, 0xf8, 0x78, 0x1c, 0x07, 0x04, 0x3f, 0x0c, 0x0c, 0x2f, 0xf7, 0xdd,
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x1d, 0x48,
-0x02, 0x68, 0x1d, 0x49, 0x8b, 0x69, 0xd2, 0x18, 0x02, 0x60, 0x02, 0x66,
-0x8a, 0x6a, 0x43, 0x68, 0x9b, 0x18, 0x43, 0x60, 0x93, 0x42, 0x02, 0xd2,
-0x82, 0x68, 0x01, 0x32, 0x82, 0x60, 0xc2, 0x68, 0x0b, 0x6a, 0xd2, 0x18,
-0xc2, 0x60, 0x42, 0x69, 0xcb, 0x68, 0xd2, 0x18, 0x42, 0x61, 0xc2, 0x69,
-0x8b, 0x68, 0xd2, 0x18, 0xc2, 0x61, 0x02, 0x69, 0x0b, 0x69, 0xd2, 0x18,
-0x02, 0x61, 0x82, 0x69, 0x0b, 0x68, 0xd2, 0x18, 0x82, 0x61, 0x02, 0x6b,
-0xcb, 0x69, 0xd2, 0x18, 0x02, 0x63, 0x4a, 0x6a, 0x43, 0x6b, 0x9b, 0x18,
-0x43, 0x63, 0x93, 0x42, 0x02, 0xd2, 0x82, 0x6b, 0x01, 0x32, 0x82, 0x63,
-0xc2, 0x6b, 0x4b, 0x69, 0xd2, 0x18, 0xc2, 0x63, 0x02, 0x6c, 0xc9, 0x6a,
-0x51, 0x18, 0x01, 0x64, 0x70, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80,
-0x00, 0x08, 0x14, 0x40, 0x88, 0xb5, 0x69, 0x46, 0x00, 0xf0, 0x17, 0xf8,
-0x81, 0x08, 0x0a, 0xd0, 0x00, 0x20, 0x00, 0x29, 0x07, 0xd9, 0x00, 0x22,
-0x83, 0x00, 0x00, 0x9f, 0xc0, 0x46, 0xfa, 0x50, 0x01, 0x30, 0x88, 0x42,
-0xf8, 0xd3, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0,
-0x04, 0xf8, 0x00, 0x04, 0x00, 0x0c, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22,
-0x00, 0x28, 0x0a, 0xd0, 0x01, 0x28, 0x0a, 0xd0, 0x02, 0x28, 0x0c, 0xd0,
-0x03, 0x28, 0x02, 0xd1, 0x07, 0x48, 0x1c, 0x22, 0x08, 0x60, 0x10, 0x1c,
-0x70, 0x47, 0x06, 0x48, 0x04, 0xe0, 0x06, 0x48, 0x50, 0x22, 0x08, 0x60,
-0xf7, 0xe7, 0x05, 0x48, 0x68, 0x22, 0x08, 0x60, 0xf3, 0xe7, 0x00, 0x00,
-0x08, 0x83, 0x20, 0x40, 0xa4, 0x2a, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x80, 0xb4, 0x03, 0x22, 0xc2, 0x80, 0x15, 0x4a,
-0xc0, 0x46, 0x82, 0x60, 0x14, 0x4a, 0x12, 0x88, 0x01, 0x32, 0xc2, 0x60,
-0x00, 0x20, 0x13, 0x4a, 0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30,
-0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x20, 0x22, 0x0a, 0x70, 0x01, 0x31,
-0x00, 0x20, 0x0e, 0x4b, 0x1f, 0x5c, 0xc0, 0x46, 0x0f, 0x70, 0x01, 0x30,
-0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20,
-0x09, 0x4a, 0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31,
-0x08, 0x28, 0xf8, 0xd3, 0x00, 0x20, 0x08, 0x70, 0x80, 0xbc, 0x70, 0x47,
-0x08, 0x10, 0x00, 0x03, 0x68, 0x0e, 0x00, 0x80, 0x7c, 0x04, 0x00, 0x80,
-0x85, 0x04, 0x00, 0x80, 0x8e, 0x04, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x23,
-0x0a, 0x48, 0xc1, 0x1d, 0x89, 0x31, 0x4b, 0x70, 0x00, 0x22, 0x0a, 0x70,
-0x64, 0x21, 0x80, 0x30, 0xc1, 0x82, 0x01, 0x83, 0x43, 0x83, 0x7d, 0x21,
-0xc9, 0x00, 0x81, 0x83, 0xc2, 0x83, 0x04, 0x48, 0x01, 0x22, 0x00, 0x21,
-0x00, 0xf0, 0x8e, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0xb5, 0x22, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 0xe1, 0xff, 0x13, 0x48,
-0x02, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x80, 0xfb, 0x01, 0x23, 0xd8, 0x42,
-0x0a, 0xd1, 0x10, 0x48, 0xc1, 0x1d, 0x39, 0x31, 0xca, 0x88, 0x01, 0x32,
-0xca, 0x80, 0x81, 0x79, 0x01, 0x31, 0x81, 0x71, 0xfd, 0xf7, 0x70, 0xf9,
-0x0b, 0x48, 0xc0, 0x68, 0x01, 0x28, 0x05, 0xd1, 0x0a, 0x48, 0x7d, 0x22,
-0xd2, 0x00, 0x00, 0x21, 0x00, 0xf0, 0x68, 0xfb, 0x08, 0x48, 0xfb, 0xf7,
-0xe1, 0xfc, 0x08, 0x48, 0x28, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x60, 0xfb,
-0x08, 0xbc, 0x18, 0x47, 0x79, 0x21, 0xff, 0xff, 0xa0, 0x82, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0xa5, 0x7b, 0x21, 0x40,
-0x95, 0x2c, 0xff, 0xff, 0x59, 0x03, 0xff, 0xff, 0x00, 0xb5, 0x10, 0x20,
-0x0f, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4a, 0x0f, 0x48, 0x64, 0x21,
-0xfb, 0xf7, 0xc6, 0xfc, 0x0e, 0x48, 0x01, 0x22, 0x12, 0x04, 0x01, 0x68,
-0x0a, 0x40, 0x08, 0x21, 0x00, 0x2a, 0x05, 0xd1, 0x02, 0x68, 0x12, 0x0c,
-0x07, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x04, 0xd3, 0x08, 0x48, 0xc0, 0x46,
-0xc1, 0x60, 0x08, 0xbc, 0x18, 0x47, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x64,
-0xf9, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa5, 0x55, 0xff, 0xff,
-0x7c, 0x29, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x80, 0xf8, 0xb5, 0x27, 0x48, 0x01, 0x22, 0x12, 0x04,
-0x01, 0x68, 0x0a, 0x40, 0x07, 0x21, 0x00, 0x2a, 0x05, 0xd1, 0x02, 0x68,
-0x12, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 0x21, 0x48,
-0xc0, 0x46, 0xc1, 0x60, 0x02, 0xe0, 0x20, 0x48, 0xc0, 0x46, 0x01, 0x64,
-0x1f, 0x48, 0xfb, 0xf7, 0x87, 0xfc, 0x1f, 0x48, 0xc1, 0x6b, 0xff, 0x29,
-0xfc, 0xd1, 0x81, 0x6b, 0x42, 0x6b, 0x16, 0x1c, 0x0f, 0x1c, 0x1c, 0x4c,
-0x10, 0x23, 0x60, 0x69, 0x18, 0x43, 0x60, 0x61, 0xa1, 0x69, 0x99, 0x43,
-0x1d, 0x04, 0xa1, 0x61, 0xe8, 0x60, 0xa0, 0x69, 0xc0, 0x46, 0x28, 0x61,
-0x16, 0x4a, 0x17, 0x49, 0x64, 0x20, 0xfb, 0xf7, 0x6f, 0xfc, 0x16, 0x4a,
-0xc0, 0x46, 0x00, 0x92, 0x15, 0x4b, 0x00, 0x20, 0x39, 0x1c, 0x32, 0x1c,
-0xfb, 0xf7, 0x6e, 0xfc, 0x13, 0x48, 0xc1, 0x68, 0x08, 0x29, 0xfc, 0xd1,
-0x12, 0x48, 0xfb, 0xf7, 0x5d, 0xfc, 0x10, 0x23, 0x60, 0x69, 0x98, 0x43,
-0x60, 0x61, 0xe8, 0x60, 0x01, 0x20, 0xe3, 0x23, 0x1b, 0x01, 0xe1, 0x18,
-0xc8, 0x71, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x40,
-0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x02, 0xff, 0xff,
-0x00, 0x01, 0x18, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x20, 0x55, 0xff, 0xff,
-0xb5, 0xb6, 0x21, 0x40, 0x64, 0x00, 0x30, 0x02, 0x44, 0x80, 0x20, 0x40,
-0x40, 0x01, 0x18, 0x40, 0xf4, 0x01, 0xff, 0xff, 0x00, 0xb5, 0xfd, 0xf7,
-0x01, 0xff, 0x06, 0x48, 0xfb, 0xf7, 0x32, 0xfc, 0xfd, 0xf7, 0xd6, 0xfe,
-0xfe, 0xf7, 0x04, 0xf8, 0xfe, 0xf7, 0x16, 0xf8, 0xfe, 0xf7, 0x24, 0xf8,
-0x08, 0xbc, 0x18, 0x47, 0x91, 0x03, 0xff, 0xff, 0x90, 0xb5, 0xfd, 0xf7,
-0x6b, 0xfc, 0x34, 0x4f, 0x00, 0x24, 0xf9, 0x68, 0xf8, 0x1d, 0x79, 0x30,
-0x01, 0x29, 0x0f, 0xd1, 0x31, 0x49, 0xc0, 0x46, 0xf9, 0x67, 0x31, 0x49,
-0xc0, 0x46, 0x01, 0x60, 0x30, 0x49, 0xc0, 0x46, 0x0c, 0x60, 0x4c, 0x60,
-0x8c, 0x60, 0xcc, 0x60, 0x0c, 0x61, 0x4c, 0x61, 0x8c, 0x61, 0x04, 0xe0,
-0xf9, 0x1d, 0x7d, 0x31, 0xf9, 0x67, 0x12, 0xc0, 0x08, 0x38, 0x00, 0x68,
-0x60, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0xf8, 0x6f, 0x20, 0x23,
-0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0xf8, 0x6f, 0x40, 0x23, 0x01, 0x68,
-0x99, 0x43, 0x01, 0x60, 0x00, 0xf0, 0x54, 0xf8, 0xfd, 0xf7, 0x4e, 0xfc,
-0x00, 0xf0, 0x5e, 0xf9, 0xfd, 0xf7, 0x73, 0xf8, 0xff, 0xf7, 0x0c, 0xfe,
-0xfd, 0xf7, 0x2e, 0xfe, 0xfd, 0xf7, 0xb6, 0xfd, 0xfd, 0xf7, 0xc2, 0xfe,
-0xfd, 0xf7, 0x54, 0xfd, 0xfd, 0xf7, 0x0a, 0xfd, 0xfd, 0xf7, 0x94, 0xfd,
-0x00, 0xf0, 0x1a, 0xfa, 0xfd, 0xf7, 0x9c, 0xff, 0xfd, 0xf7, 0x0a, 0xff,
-0xfd, 0xf7, 0xd2, 0xfe, 0xfd, 0xf7, 0x3c, 0xfc, 0xfb, 0xf7, 0xdc, 0xfa,
-0xff, 0xf7, 0x9c, 0xff, 0x71, 0x23, 0x5b, 0x01,
-0xf8, 0x18, 0x04, 0x72, 0x44, 0x72, 0x07, 0x23, 0x5b, 0x02, 0xf8, 0x18,
-0x04, 0x63, 0xf8, 0x68, 0x01, 0x28, 0x02, 0xd1, 0xa8, 0x20, 0xfe, 0xf7,
-0xb1, 0xfd, 0x09, 0x48, 0xc0, 0x46, 0x44, 0x62, 0x00, 0xf0, 0x18, 0xfa,
-0x07, 0x48, 0xfb, 0xf7, 0xbd, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x01, 0x11, 0x40, 0x04, 0x01, 0x11, 0x40,
-0x00, 0x01, 0x11, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x15, 0x8f, 0x21, 0x40,
-0x00, 0xb5, 0x04, 0x48, 0xfb, 0xf7, 0xaa, 0xfb, 0xfd, 0xf7, 0x5e, 0xff,
-0xfd, 0xf7, 0x24, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x15, 0x99, 0x21, 0x40,
-0xfa, 0x21, 0x03, 0x48, 0xc0, 0x46, 0x41, 0x62, 0x40, 0x21, 0x41, 0x62,
-0x70, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x07, 0x48, 0x41, 0x69,
-0x07, 0x4b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 0x9a, 0x43, 0x82, 0x61,
-0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61,
-0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0xfe, 0xaf, 0x9a, 0x10,
-0x00, 0xb5, 0x02, 0x48, 0xfb, 0xf7, 0x80, 0xfb, 0x08, 0xbc, 0x18, 0x47,
-0xc8, 0x57, 0xff, 0xff, 0xf0, 0xb5, 0x24, 0x4c, 0x01, 0x21, 0x09, 0x04,
-0x20, 0x68, 0x01, 0x40, 0x09, 0x20, 0x22, 0x4e, 0x22, 0x4d, 0x00, 0x29,
-0x05, 0xd1, 0x21, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x21, 0x68, 0x89, 0x0a,
-0x01, 0xd3, 0xf0, 0x60, 0x00, 0xe0, 0x28, 0x64, 0x1d, 0x48, 0xfb, 0xf7,
-0x65, 0xfb, 0x1d, 0x4f, 0x1d, 0x49, 0x88, 0x69, 0x01, 0x30, 0x88, 0x61,
-0x38, 0x7a, 0x00, 0x28, 0x02, 0xd1, 0x78, 0x7a, 0x00, 0x28, 0x1f, 0xd0,
-0x19, 0x48, 0xfb, 0xf7, 0x57, 0xfb, 0x19, 0x48, 0xfb, 0xf7, 0x54, 0xfb,
-0x00, 0x28, 0xfa, 0xd1, 0x38, 0x7a, 0x00, 0x28, 0x02, 0xd0, 0x16, 0x48,
-0xfb, 0xf7, 0x4c, 0xfb, 0x01, 0x21, 0x09, 0x04, 0x20, 0x68, 0x01, 0x40,
-0x14, 0x20, 0x00, 0x29, 0x05, 0xd1, 0x21, 0x68, 0x09, 0x0c, 0x04, 0xd1,
-0x21, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xf0, 0x60, 0x01, 0xe0, 0x28, 0x64,
-0xff, 0xe7, 0xfe, 0xe7, 0xff, 0xf7, 0x65, 0xfd, 0x0b, 0x48, 0xfb, 0xf7,
-0x35, 0xfb, 0xff, 0xf7, 0xaf, 0xff, 0xcd, 0xe7, 0x00, 0x00, 0x10, 0x40,
-0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x02, 0xff, 0xff,
-0x88, 0x1c, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40, 0xf4, 0x01, 0xff, 0xff,
-0xb5, 0x07, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x99, 0x9f, 0x21, 0x40,
-0x00, 0x20, 0x07, 0x4a, 0x01, 0x21, 0x09, 0x05, 0x50, 0x61, 0xc8, 0x60,
-0xd0, 0x61, 0xc8, 0x61, 0x03, 0x23, 0xdb, 0x04, 0x03, 0x4a, 0x01, 0x21,
-0xd1, 0x63, 0x58, 0x60, 0xfc, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0xc0, 0x00, 0x18, 0x00, 0x80, 0xb5, 0xc0, 0xb0, 0x01, 0x22, 0x00, 0x21,
-0x0a, 0x20, 0xfc, 0xf7, 0xd1, 0xff, 0x07, 0x1c, 0xff, 0x2f, 0x28, 0xd0,
-0x69, 0x46, 0xff, 0x22, 0x38, 0x1c, 0x01, 0x32, 0xfd, 0xf7, 0x54, 0xf9,
-0xff, 0x23, 0x01, 0x33, 0x98, 0x42, 0x1b, 0xd1, 0x0d, 0x98, 0x00, 0x09,
-0x18, 0xd3, 0x38, 0x1c, 0xfd, 0xf7, 0x8d, 0xf8, 0x0e, 0x49, 0x01, 0x22,
-0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x0d, 0x48, 0x05, 0xd1, 0x0a, 0x68,
-0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, 0x89, 0x0a, 0x03, 0xd3, 0x0a, 0x49,
-0xc0, 0x46, 0xc8, 0x60, 0x02, 0xe0, 0x09, 0x49, 0xc0, 0x46, 0x08, 0x64,
-0xff, 0xf7, 0xbc, 0xff, 0x38, 0x1c, 0xfd, 0xf7, 0x74, 0xf8, 0x40, 0xb0,
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0x07, 0x80, 0x00, 0x00, 0x40, 0x01, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x17, 0x49, 0x01, 0x22, 0x12, 0x04,
-0x08, 0x68, 0x02, 0x40, 0x06, 0x20, 0x00, 0x2a, 0x05, 0xd1, 0x0a, 0x68,
-0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, 0x89, 0x0a, 0x03, 0xd3, 0x11, 0x49,
-0xc0, 0x46, 0xc8, 0x60, 0x02, 0xe0, 0x10, 0x49, 0xc0, 0x46, 0x08, 0x64,
-0x03, 0x20, 0xfe, 0xf7, 0xd3, 0xfc, 0xfb, 0xf7, 0x0d, 0xff, 0x01, 0x23,
-0x18, 0x43, 0xfb, 0xf7, 0xe7, 0xff, 0xff, 0xf7, 0x83, 0xfe, 0xff, 0xf7,
-0x9d, 0xff, 0xff, 0xf7, 0x05, 0xfe, 0xff, 0xf7, 0xf5, 0xfe, 0xff, 0xf7,
-0x09, 0xff, 0xff, 0xf7, 0x9b, 0xfd, 0xff, 0xf7, 0x21, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x80, 0xf0, 0xb4, 0x46, 0x4a, 0x01, 0x21, 0xc9, 0x03,
-0x45, 0x4d, 0x19, 0x23, 0xdb, 0x01, 0xec, 0x18, 0xa1, 0x61, 0x28, 0x88,
-0x40, 0x04, 0x43, 0x4b, 0xc0, 0x18, 0x87, 0x1a, 0x04, 0x20, 0xaf, 0x60,
-0x41, 0x4e, 0xc0, 0x46, 0xb0, 0x61, 0x08, 0x20, 0xc8, 0x23, 0x43, 0x43,
-0xbb, 0x42, 0x21, 0xd9, 0x41, 0x00, 0x3d, 0x4e, 0xc0, 0x46, 0x31, 0x61,
-0xb6, 0x69, 0x20, 0x23, 0x9b, 0x1b, 0x3a, 0x4e, 0xc0, 0x46, 0xf3, 0x61,
-0x10, 0x3b, 0x33, 0x62, 0x8b, 0x00, 0xff, 0x1a, 0x40, 0x08, 0x81, 0x42,
-0x17, 0xd3, 0xb8, 0x23, 0x43, 0x43, 0xbb, 0x42, 0x08, 0xd9, 0x41, 0x1e,
-0x32, 0x4b, 0xc0, 0x46, 0x99, 0x81, 0xd9, 0x81, 0x40, 0x00, 0x02, 0x38,
-0x58, 0x61, 0x0a, 0xe0, 0x01, 0x30, 0x81, 0x42, 0xef, 0xd2, 0x06, 0xe0,
-0x2c, 0x4e, 0xb3, 0x69, 0x01, 0x33, 0xb3, 0x61, 0x40, 0x00, 0x88, 0x42,
-0xd2, 0xd9, 0x2a, 0x49, 0x00, 0x20, 0xa3, 0x69, 0x9b, 0x08, 0x07, 0xd0,
-0x28, 0x4b, 0x87, 0x00, 0xcb, 0x51, 0xa7, 0x69, 0xbf, 0x08, 0x01, 0x30,
-0x87, 0x42, 0xf8, 0xd8, 0x22, 0x49, 0xc0, 0x46, 0x8a, 0x62, 0x8c, 0x89,
-0x58, 0x20, 0x60, 0x43, 0x87, 0x18, 0x00, 0x20, 0x00, 0x22, 0x00, 0x2c,
-0x0a, 0xdd, 0x58, 0x23, 0x43, 0x43, 0x8c, 0x6a, 0xe3, 0x18, 0x01, 0x30,
-0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 0x8b, 0x89, 0x83, 0x42, 0xf4, 0xdc,
-0xcf, 0x62, 0xcc, 0x89, 0x60, 0x00, 0x00, 0x19, 0x40, 0x01, 0xc7, 0x19,
-0x00, 0x20, 0x00, 0x2c, 0x0b, 0xdd, 0x43, 0x00, 0x1b, 0x18, 0x5b, 0x01,
-0xcc, 0x6a, 0xe3, 0x18, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60,
-0xcb, 0x89, 0x83, 0x42, 0xf3, 0xdc, 0x4f, 0x62, 0x00, 0x20, 0x0b, 0x69,
-0x00, 0x2b, 0x07, 0xd9, 0x87, 0x00, 0x4b, 0x6a, 0xc0, 0x46, 0xda, 0x51,
-0x0b, 0x69, 0x01, 0x30, 0x83, 0x42, 0xf7, 0xd8, 0x49, 0x6a, 0x80, 0x00,
-0x08, 0x18, 0x04, 0x38, 0x28, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00,
-0xb0, 0xbe, 0x21, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40,
-0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0xad, 0xde, 0x00,
-0x0a, 0x48, 0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 0x1a, 0x09,
-0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x91, 0x61,
-0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x81, 0x61, 0x01, 0x20, 0x00, 0x06,
-0x59, 0x05, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x80, 0xb4, 0x02, 0x1c, 0x0b, 0x48, 0x1b, 0x23, 0xdb, 0x01, 0xc3, 0x18,
-0x9a, 0x61, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x69, 0x1a, 0x43, 0x42, 0x61,
-0x87, 0x69, 0x9f, 0x43, 0x01, 0x23, 0x1b, 0x05,
-0x87, 0x61, 0xda, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x18, 0x61, 0xa1, 0x20,
-0x40, 0x03, 0x81, 0x61, 0x80, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x80, 0xb5, 0xff, 0xf7, 0xc9, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x20, 0xf8,
-0x00, 0x20, 0x09, 0x49, 0x00, 0x22, 0x03, 0x01, 0x5f, 0x18, 0x33, 0x23,
-0x9b, 0x01, 0xfb, 0x18, 0x9a, 0x62, 0x01, 0x30, 0x0b, 0x28, 0xf6, 0xd3,
-0x04, 0x48, 0x01, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x33, 0xf8, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x1d, 0x3e, 0xff, 0xff,
-0x00, 0xb5, 0x02, 0x48, 0x00, 0xf0, 0x04, 0xf8, 0x08, 0xbc, 0x18, 0x47,
-0xa8, 0x61, 0x00, 0x00, 0x80, 0xb4, 0x01, 0x22, 0x12, 0x05, 0x0f, 0x4b,
-0xa1, 0x21, 0x49, 0x03, 0x00, 0x28, 0x0e, 0xd0, 0xc8, 0x61, 0x18, 0x1c,
-0x59, 0x69, 0x53, 0x01, 0x19, 0x43, 0x41, 0x61, 0x87, 0x69, 0x9f, 0x43,
-0x87, 0x61, 0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x80, 0xbc,
-0x70, 0x47, 0x18, 0x1c, 0x5f, 0x69, 0x01, 0x23, 0x5b, 0x06, 0x9f, 0x43,
-0x47, 0x61, 0xd7, 0x60, 0x00, 0x20, 0xc8, 0x61, 0xf3, 0xe7, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb4, 0x07, 0x1c, 0x00, 0x20, 0x17, 0x4c,
-0x03, 0x01, 0x1d, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x9d, 0x6a,
-0xbd, 0x42, 0x05, 0xd1, 0x1d, 0x6b, 0x95, 0x42, 0x02, 0xd1, 0xdb, 0x6a,
-0x8b, 0x42, 0x1c, 0xd0, 0x01, 0x30, 0x0b, 0x28, 0xee, 0xd3, 0x00, 0x20,
-0x03, 0x01, 0x1d, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x9b, 0x6a,
-0x00, 0x2b, 0x09, 0xd1, 0x03, 0x01, 0x1c, 0x19, 0x33, 0x23, 0x9b, 0x01,
-0xe3, 0x18, 0x1a, 0x63, 0xd9, 0x62, 0x5a, 0x63, 0x9f, 0x62, 0x02, 0xe0,
-0x01, 0x30, 0x0b, 0x28, 0xea, 0xd3, 0x0b, 0x28, 0x01, 0xd1, 0x00, 0x20,
-0xc0, 0x43, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x90, 0xb4, 0x01, 0x1c, 0x00, 0x22, 0x01, 0x20, 0x16, 0x4f, 0x01, 0xe0,
-0x00, 0x2a, 0x07, 0xd1, 0x03, 0x01, 0xdc, 0x19, 0x33, 0x23, 0x9b, 0x01,
-0xe3, 0x18, 0x9b, 0x69, 0x8b, 0x42, 0x11, 0xd1, 0x02, 0x01, 0xd2, 0x19,
-0x33, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x93, 0x6a, 0xc0, 0x46, 0x93, 0x61,
-0xd3, 0x6a, 0xc0, 0x46, 0xd3, 0x61, 0x13, 0x6b, 0xc0, 0x46, 0x13, 0x62,
-0x53, 0x6b, 0xc0, 0x46, 0x53, 0x62, 0x01, 0x22, 0x01, 0x30, 0x0b, 0x28,
-0xe0, 0xd3, 0x07, 0x4b, 0x00, 0x2a, 0x02, 0xd1, 0x9a, 0x68, 0x8a, 0x42,
-0x03, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20,
-0xc0, 0x43, 0xfa, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80,
-0x0b, 0x28, 0x17, 0xda, 0x0c, 0x49, 0x01, 0x23, 0x5b, 0x06, 0x8a, 0x69,
-0x13, 0x43, 0x01, 0x22, 0x12, 0x05, 0x8b, 0x61, 0x13, 0x61, 0x00, 0x01,
-0x40, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x03, 0x6b, 0xc0, 0x46,
-0x43, 0x63, 0x53, 0x01, 0x88, 0x69, 0x98, 0x43, 0x88, 0x61, 0x10, 0x61,
-0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x68, 0x0e, 0x00, 0x80,
-0x90, 0xb4, 0x08, 0x4a, 0xd0, 0x69, 0x00, 0x21, 0x07, 0x4f, 0xd3, 0x69,
-0x83, 0x42, 0x02, 0xd9, 0xfc, 0x1a, 0x20, 0x18, 0x00, 0xe0, 0xc0, 0x1a,
-0x09, 0x18, 0x18, 0x1c, 0xb9, 0x42, 0xf4, 0xd9, 0x90, 0xbc, 0x70, 0x47,
-0x00, 0x20, 0x14, 0x40, 0xa8, 0x61, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c,
-0x00, 0x24, 0x00, 0x2f, 0x04, 0xd3, 0xff, 0xf7, 0xe3, 0xff, 0x01, 0x34,
-0xbc, 0x42, 0xfa, 0xd9, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00,
-};
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 3af9a9516cc..9dd4f76a2ff 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -100,10 +100,11 @@ static const int multicast_filter_limit = 32;
#define PKT_BUF_SZ 1536
#define DRV_MODULE_NAME "typhoon"
-#define DRV_MODULE_VERSION "1.5.8"
-#define DRV_MODULE_RELDATE "06/11/09"
+#define DRV_MODULE_VERSION "1.5.9"
+#define DRV_MODULE_RELDATE "Mar 2, 2009"
#define PFX DRV_MODULE_NAME ": "
#define ERR_PFX KERN_ERR PFX
+#define FIRMWARE_NAME "3com/typhoon.bin"
#include <linux/module.h>
#include <linux/kernel.h>
@@ -129,9 +130,9 @@ static const int multicast_filter_limit = 32;
#include <asm/uaccess.h>
#include <linux/in6.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include "typhoon.h"
-#include "typhoon-firmware.h"
static char version[] __devinitdata =
"typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -139,6 +140,7 @@ static char version[] __devinitdata =
MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE_NAME);
MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
MODULE_PARM_DESC(rx_copybreak, "Packets smaller than this are copied and "
"the buffer given back to the NIC. Default "
@@ -1344,14 +1346,74 @@ typhoon_init_rings(struct typhoon *tp)
tp->txHiRing.lastRead = 0;
}
+static const struct firmware *typhoon_fw;
+
+static int
+typhoon_request_firmware(struct typhoon *tp)
+{
+ const struct typhoon_file_header *fHdr;
+ const struct typhoon_section_header *sHdr;
+ const u8 *image_data;
+ u32 numSections;
+ u32 section_len;
+ u32 remaining;
+ int err;
+
+ if (typhoon_fw)
+ return 0;
+
+ err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev);
+ if (err) {
+ printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+ tp->name, FIRMWARE_NAME);
+ return err;
+ }
+
+ image_data = (u8 *) typhoon_fw->data;
+ remaining = typhoon_fw->size;
+ if (remaining < sizeof(struct typhoon_file_header))
+ goto invalid_fw;
+
+ fHdr = (struct typhoon_file_header *) image_data;
+ if (memcmp(fHdr->tag, "TYPHOON", 8))
+ goto invalid_fw;
+
+ numSections = le32_to_cpu(fHdr->numSections);
+ image_data += sizeof(struct typhoon_file_header);
+ remaining -= sizeof(struct typhoon_file_header);
+
+ while (numSections--) {
+ if (remaining < sizeof(struct typhoon_section_header))
+ goto invalid_fw;
+
+ sHdr = (struct typhoon_section_header *) image_data;
+ image_data += sizeof(struct typhoon_section_header);
+ section_len = le32_to_cpu(sHdr->len);
+
+ if (remaining < section_len)
+ goto invalid_fw;
+
+ image_data += section_len;
+ remaining -= section_len;
+ }
+
+ return 0;
+
+invalid_fw:
+ printk(KERN_ERR "%s: Invalid firmware image\n", tp->name);
+ release_firmware(typhoon_fw);
+ typhoon_fw = NULL;
+ return -EINVAL;
+}
+
static int
typhoon_download_firmware(struct typhoon *tp)
{
void __iomem *ioaddr = tp->ioaddr;
struct pci_dev *pdev = tp->pdev;
- struct typhoon_file_header *fHdr;
- struct typhoon_section_header *sHdr;
- u8 *image_data;
+ const struct typhoon_file_header *fHdr;
+ const struct typhoon_section_header *sHdr;
+ const u8 *image_data;
void *dpage;
dma_addr_t dpage_dma;
__sum16 csum;
@@ -1365,20 +1427,12 @@ typhoon_download_firmware(struct typhoon *tp)
int i;
int err;
- err = -EINVAL;
- fHdr = (struct typhoon_file_header *) typhoon_firmware_image;
- image_data = (u8 *) fHdr;
-
- if(memcmp(fHdr->tag, "TYPHOON", 8)) {
- printk(KERN_ERR "%s: Invalid firmware image!\n", tp->name);
- goto err_out;
- }
+ image_data = (u8 *) typhoon_fw->data;
+ fHdr = (struct typhoon_file_header *) image_data;
/* Cannot just map the firmware image using pci_map_single() as
- * the firmware is part of the kernel/module image, so we allocate
- * some consistent memory to copy the sections into, as it is simpler,
- * and short-lived. If we ever split out and require a userland
- * firmware loader, then we can revisit this.
+ * the firmware is vmalloc()'d and may not be physically contiguous,
+ * so we allocate some consistent memory to copy the sections into.
*/
err = -ENOMEM;
dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
@@ -1783,7 +1837,7 @@ typhoon_poll(struct napi_struct *napi, int budget)
}
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
iowrite32(TYPHOON_INTR_NONE,
tp->ioaddr + TYPHOON_REG_INTR_MASK);
typhoon_post_pci_writes(tp->ioaddr);
@@ -1806,10 +1860,10 @@ typhoon_interrupt(int irq, void *dev_instance)
iowrite32(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
- if (netif_rx_schedule_prep(&tp->napi)) {
+ if (napi_schedule_prep(&tp->napi)) {
iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
typhoon_post_pci_writes(ioaddr);
- __netif_rx_schedule(&tp->napi);
+ __napi_schedule(&tp->napi);
} else {
printk(KERN_ERR "%s: Error, poll already scheduled\n",
dev->name);
@@ -1944,7 +1998,7 @@ typhoon_start_runtime(struct typhoon *tp)
goto error_out;
INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_VLAN_TYPE_WRITE);
- xp_cmd.parm1 = __constant_cpu_to_le16(ETH_P_8021Q);
+ xp_cmd.parm1 = cpu_to_le16(ETH_P_8021Q);
err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
if(err < 0)
goto error_out;
@@ -2086,6 +2140,10 @@ typhoon_open(struct net_device *dev)
struct typhoon *tp = netdev_priv(dev);
int err;
+ err = typhoon_request_firmware(tp);
+ if (err)
+ goto out;
+
err = typhoon_wakeup(tp, WaitSleep);
if(err < 0) {
printk(KERN_ERR "%s: unable to wakeup device\n", dev->name);
@@ -2624,6 +2682,8 @@ typhoon_init(void)
static void __exit
typhoon_cleanup(void)
{
+ if (typhoon_fw)
+ release_firmware(typhoon_fw);
pci_unregister_driver(&typhoon_driver);
}
diff --git a/drivers/net/typhoon.h b/drivers/net/typhoon.h
index dd7022ca735..673fd512591 100644
--- a/drivers/net/typhoon.h
+++ b/drivers/net/typhoon.h
@@ -174,18 +174,18 @@ struct tx_desc {
u64 tx_addr; /* opaque for hardware, for TX_DESC */
};
__le32 processFlags;
-#define TYPHOON_TX_PF_NO_CRC __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_TX_PF_IP_CHKSUM __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_TX_PF_TCP_CHKSUM __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_TX_PF_TCP_SEGMENT __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_TX_PF_INSERT_VLAN __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_TX_PF_IPSEC __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_TX_PF_VLAN_PRIORITY __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_TX_PF_UDP_CHKSUM __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_TX_PF_PAD_FRAME __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_TX_PF_RESERVED __constant_cpu_to_le32(0x00000e00)
-#define TYPHOON_TX_PF_VLAN_MASK __constant_cpu_to_le32(0x0ffff000)
-#define TYPHOON_TX_PF_INTERNAL __constant_cpu_to_le32(0xf0000000)
+#define TYPHOON_TX_PF_NO_CRC cpu_to_le32(0x00000001)
+#define TYPHOON_TX_PF_IP_CHKSUM cpu_to_le32(0x00000002)
+#define TYPHOON_TX_PF_TCP_CHKSUM cpu_to_le32(0x00000004)
+#define TYPHOON_TX_PF_TCP_SEGMENT cpu_to_le32(0x00000008)
+#define TYPHOON_TX_PF_INSERT_VLAN cpu_to_le32(0x00000010)
+#define TYPHOON_TX_PF_IPSEC cpu_to_le32(0x00000020)
+#define TYPHOON_TX_PF_VLAN_PRIORITY cpu_to_le32(0x00000040)
+#define TYPHOON_TX_PF_UDP_CHKSUM cpu_to_le32(0x00000080)
+#define TYPHOON_TX_PF_PAD_FRAME cpu_to_le32(0x00000100)
+#define TYPHOON_TX_PF_RESERVED cpu_to_le32(0x00000e00)
+#define TYPHOON_TX_PF_VLAN_MASK cpu_to_le32(0x0ffff000)
+#define TYPHOON_TX_PF_INTERNAL cpu_to_le32(0xf0000000)
#define TYPHOON_TX_PF_VLAN_TAG_SHIFT 12
} __attribute__ ((packed));
@@ -203,8 +203,8 @@ struct tcpopt_desc {
u8 flags;
u8 numDesc;
__le16 mss_flags;
-#define TYPHOON_TSO_FIRST __constant_cpu_to_le16(0x1000)
-#define TYPHOON_TSO_LAST __constant_cpu_to_le16(0x2000)
+#define TYPHOON_TSO_FIRST cpu_to_le16(0x1000)
+#define TYPHOON_TSO_LAST cpu_to_le16(0x2000)
__le32 respAddrLo;
__le32 bytesTx;
__le32 status;
@@ -222,8 +222,8 @@ struct ipsec_desc {
u8 flags;
u8 numDesc;
__le16 ipsecFlags;
-#define TYPHOON_IPSEC_GEN_IV __constant_cpu_to_le16(0x0000)
-#define TYPHOON_IPSEC_USE_IV __constant_cpu_to_le16(0x0001)
+#define TYPHOON_IPSEC_GEN_IV cpu_to_le16(0x0000)
+#define TYPHOON_IPSEC_USE_IV cpu_to_le16(0x0001)
__le32 sa1;
__le32 sa2;
__le32 reserved;
@@ -248,41 +248,41 @@ struct rx_desc {
u32 addr; /* opaque, comes from virtAddr */
u32 addrHi; /* opaque, comes from virtAddrHi */
__le32 rxStatus;
-#define TYPHOON_RX_ERR_INTERNAL __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_RX_ERR_FIFO_UNDERRUN __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_RX_ERR_BAD_SSD __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_RX_ERR_RUNT __constant_cpu_to_le32(0x00000003)
-#define TYPHOON_RX_ERR_CRC __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_RX_ERR_OVERSIZE __constant_cpu_to_le32(0x00000005)
-#define TYPHOON_RX_ERR_ALIGN __constant_cpu_to_le32(0x00000006)
-#define TYPHOON_RX_ERR_DRIBBLE __constant_cpu_to_le32(0x00000007)
-#define TYPHOON_RX_PROTO_MASK __constant_cpu_to_le32(0x00000003)
-#define TYPHOON_RX_PROTO_UNKNOWN __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_RX_PROTO_IP __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_RX_PROTO_IPX __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_RX_VLAN __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_RX_IP_FRAG __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_RX_IPSEC __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_RX_IP_CHK_FAIL __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_RX_TCP_CHK_FAIL __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_RX_UDP_CHK_FAIL __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_RX_IP_CHK_GOOD __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_RX_TCP_CHK_GOOD __constant_cpu_to_le32(0x00000200)
-#define TYPHOON_RX_UDP_CHK_GOOD __constant_cpu_to_le32(0x00000400)
+#define TYPHOON_RX_ERR_INTERNAL cpu_to_le32(0x00000000)
+#define TYPHOON_RX_ERR_FIFO_UNDERRUN cpu_to_le32(0x00000001)
+#define TYPHOON_RX_ERR_BAD_SSD cpu_to_le32(0x00000002)
+#define TYPHOON_RX_ERR_RUNT cpu_to_le32(0x00000003)
+#define TYPHOON_RX_ERR_CRC cpu_to_le32(0x00000004)
+#define TYPHOON_RX_ERR_OVERSIZE cpu_to_le32(0x00000005)
+#define TYPHOON_RX_ERR_ALIGN cpu_to_le32(0x00000006)
+#define TYPHOON_RX_ERR_DRIBBLE cpu_to_le32(0x00000007)
+#define TYPHOON_RX_PROTO_MASK cpu_to_le32(0x00000003)
+#define TYPHOON_RX_PROTO_UNKNOWN cpu_to_le32(0x00000000)
+#define TYPHOON_RX_PROTO_IP cpu_to_le32(0x00000001)
+#define TYPHOON_RX_PROTO_IPX cpu_to_le32(0x00000002)
+#define TYPHOON_RX_VLAN cpu_to_le32(0x00000004)
+#define TYPHOON_RX_IP_FRAG cpu_to_le32(0x00000008)
+#define TYPHOON_RX_IPSEC cpu_to_le32(0x00000010)
+#define TYPHOON_RX_IP_CHK_FAIL cpu_to_le32(0x00000020)
+#define TYPHOON_RX_TCP_CHK_FAIL cpu_to_le32(0x00000040)
+#define TYPHOON_RX_UDP_CHK_FAIL cpu_to_le32(0x00000080)
+#define TYPHOON_RX_IP_CHK_GOOD cpu_to_le32(0x00000100)
+#define TYPHOON_RX_TCP_CHK_GOOD cpu_to_le32(0x00000200)
+#define TYPHOON_RX_UDP_CHK_GOOD cpu_to_le32(0x00000400)
__le16 filterResults;
-#define TYPHOON_RX_FILTER_MASK __constant_cpu_to_le16(0x7fff)
-#define TYPHOON_RX_FILTERED __constant_cpu_to_le16(0x8000)
+#define TYPHOON_RX_FILTER_MASK cpu_to_le16(0x7fff)
+#define TYPHOON_RX_FILTERED cpu_to_le16(0x8000)
__le16 ipsecResults;
-#define TYPHOON_RX_OUTER_AH_GOOD __constant_cpu_to_le16(0x0001)
-#define TYPHOON_RX_OUTER_ESP_GOOD __constant_cpu_to_le16(0x0002)
-#define TYPHOON_RX_INNER_AH_GOOD __constant_cpu_to_le16(0x0004)
-#define TYPHOON_RX_INNER_ESP_GOOD __constant_cpu_to_le16(0x0008)
-#define TYPHOON_RX_OUTER_AH_FAIL __constant_cpu_to_le16(0x0010)
-#define TYPHOON_RX_OUTER_ESP_FAIL __constant_cpu_to_le16(0x0020)
-#define TYPHOON_RX_INNER_AH_FAIL __constant_cpu_to_le16(0x0040)
-#define TYPHOON_RX_INNER_ESP_FAIL __constant_cpu_to_le16(0x0080)
-#define TYPHOON_RX_UNKNOWN_SA __constant_cpu_to_le16(0x0100)
-#define TYPHOON_RX_ESP_FORMAT_ERR __constant_cpu_to_le16(0x0200)
+#define TYPHOON_RX_OUTER_AH_GOOD cpu_to_le16(0x0001)
+#define TYPHOON_RX_OUTER_ESP_GOOD cpu_to_le16(0x0002)
+#define TYPHOON_RX_INNER_AH_GOOD cpu_to_le16(0x0004)
+#define TYPHOON_RX_INNER_ESP_GOOD cpu_to_le16(0x0008)
+#define TYPHOON_RX_OUTER_AH_FAIL cpu_to_le16(0x0010)
+#define TYPHOON_RX_OUTER_ESP_FAIL cpu_to_le16(0x0020)
+#define TYPHOON_RX_INNER_AH_FAIL cpu_to_le16(0x0040)
+#define TYPHOON_RX_INNER_ESP_FAIL cpu_to_le16(0x0080)
+#define TYPHOON_RX_UNKNOWN_SA cpu_to_le16(0x0100)
+#define TYPHOON_RX_ESP_FORMAT_ERR cpu_to_le16(0x0200)
__be32 vlanTag;
} __attribute__ ((packed));
@@ -318,31 +318,31 @@ struct cmd_desc {
u8 flags;
u8 numDesc;
__le16 cmd;
-#define TYPHOON_CMD_TX_ENABLE __constant_cpu_to_le16(0x0001)
-#define TYPHOON_CMD_TX_DISABLE __constant_cpu_to_le16(0x0002)
-#define TYPHOON_CMD_RX_ENABLE __constant_cpu_to_le16(0x0003)
-#define TYPHOON_CMD_RX_DISABLE __constant_cpu_to_le16(0x0004)
-#define TYPHOON_CMD_SET_RX_FILTER __constant_cpu_to_le16(0x0005)
-#define TYPHOON_CMD_READ_STATS __constant_cpu_to_le16(0x0007)
-#define TYPHOON_CMD_XCVR_SELECT __constant_cpu_to_le16(0x0013)
-#define TYPHOON_CMD_SET_MAX_PKT_SIZE __constant_cpu_to_le16(0x001a)
-#define TYPHOON_CMD_READ_MEDIA_STATUS __constant_cpu_to_le16(0x001b)
-#define TYPHOON_CMD_GOTO_SLEEP __constant_cpu_to_le16(0x0023)
-#define TYPHOON_CMD_SET_MULTICAST_HASH __constant_cpu_to_le16(0x0025)
-#define TYPHOON_CMD_SET_MAC_ADDRESS __constant_cpu_to_le16(0x0026)
-#define TYPHOON_CMD_READ_MAC_ADDRESS __constant_cpu_to_le16(0x0027)
-#define TYPHOON_CMD_VLAN_TYPE_WRITE __constant_cpu_to_le16(0x002b)
-#define TYPHOON_CMD_CREATE_SA __constant_cpu_to_le16(0x0034)
-#define TYPHOON_CMD_DELETE_SA __constant_cpu_to_le16(0x0035)
-#define TYPHOON_CMD_READ_VERSIONS __constant_cpu_to_le16(0x0043)
-#define TYPHOON_CMD_IRQ_COALESCE_CTRL __constant_cpu_to_le16(0x0045)
-#define TYPHOON_CMD_ENABLE_WAKE_EVENTS __constant_cpu_to_le16(0x0049)
-#define TYPHOON_CMD_SET_OFFLOAD_TASKS __constant_cpu_to_le16(0x004f)
-#define TYPHOON_CMD_HELLO_RESP __constant_cpu_to_le16(0x0057)
-#define TYPHOON_CMD_HALT __constant_cpu_to_le16(0x005d)
-#define TYPHOON_CMD_READ_IPSEC_INFO __constant_cpu_to_le16(0x005e)
-#define TYPHOON_CMD_GET_IPSEC_ENABLE __constant_cpu_to_le16(0x0067)
-#define TYPHOON_CMD_GET_CMD_LVL __constant_cpu_to_le16(0x0069)
+#define TYPHOON_CMD_TX_ENABLE cpu_to_le16(0x0001)
+#define TYPHOON_CMD_TX_DISABLE cpu_to_le16(0x0002)
+#define TYPHOON_CMD_RX_ENABLE cpu_to_le16(0x0003)
+#define TYPHOON_CMD_RX_DISABLE cpu_to_le16(0x0004)
+#define TYPHOON_CMD_SET_RX_FILTER cpu_to_le16(0x0005)
+#define TYPHOON_CMD_READ_STATS cpu_to_le16(0x0007)
+#define TYPHOON_CMD_XCVR_SELECT cpu_to_le16(0x0013)
+#define TYPHOON_CMD_SET_MAX_PKT_SIZE cpu_to_le16(0x001a)
+#define TYPHOON_CMD_READ_MEDIA_STATUS cpu_to_le16(0x001b)
+#define TYPHOON_CMD_GOTO_SLEEP cpu_to_le16(0x0023)
+#define TYPHOON_CMD_SET_MULTICAST_HASH cpu_to_le16(0x0025)
+#define TYPHOON_CMD_SET_MAC_ADDRESS cpu_to_le16(0x0026)
+#define TYPHOON_CMD_READ_MAC_ADDRESS cpu_to_le16(0x0027)
+#define TYPHOON_CMD_VLAN_TYPE_WRITE cpu_to_le16(0x002b)
+#define TYPHOON_CMD_CREATE_SA cpu_to_le16(0x0034)
+#define TYPHOON_CMD_DELETE_SA cpu_to_le16(0x0035)
+#define TYPHOON_CMD_READ_VERSIONS cpu_to_le16(0x0043)
+#define TYPHOON_CMD_IRQ_COALESCE_CTRL cpu_to_le16(0x0045)
+#define TYPHOON_CMD_ENABLE_WAKE_EVENTS cpu_to_le16(0x0049)
+#define TYPHOON_CMD_SET_OFFLOAD_TASKS cpu_to_le16(0x004f)
+#define TYPHOON_CMD_HELLO_RESP cpu_to_le16(0x0057)
+#define TYPHOON_CMD_HALT cpu_to_le16(0x005d)
+#define TYPHOON_CMD_READ_IPSEC_INFO cpu_to_le16(0x005e)
+#define TYPHOON_CMD_GET_IPSEC_ENABLE cpu_to_le16(0x0067)
+#define TYPHOON_CMD_GET_CMD_LVL cpu_to_le16(0x0069)
u16 seqNo;
__le16 parm1;
__le32 parm2;
@@ -380,11 +380,11 @@ struct resp_desc {
/* TYPHOON_CMD_SET_RX_FILTER filter bits (cmd.parm1)
*/
-#define TYPHOON_RX_FILTER_DIRECTED __constant_cpu_to_le16(0x0001)
-#define TYPHOON_RX_FILTER_ALL_MCAST __constant_cpu_to_le16(0x0002)
-#define TYPHOON_RX_FILTER_BROADCAST __constant_cpu_to_le16(0x0004)
-#define TYPHOON_RX_FILTER_PROMISCOUS __constant_cpu_to_le16(0x0008)
-#define TYPHOON_RX_FILTER_MCAST_HASH __constant_cpu_to_le16(0x0010)
+#define TYPHOON_RX_FILTER_DIRECTED cpu_to_le16(0x0001)
+#define TYPHOON_RX_FILTER_ALL_MCAST cpu_to_le16(0x0002)
+#define TYPHOON_RX_FILTER_BROADCAST cpu_to_le16(0x0004)
+#define TYPHOON_RX_FILTER_PROMISCOUS cpu_to_le16(0x0008)
+#define TYPHOON_RX_FILTER_MCAST_HASH cpu_to_le16(0x0010)
/* TYPHOON_CMD_READ_STATS response format
*/
@@ -416,40 +416,40 @@ struct stats_resp {
__le32 rxOverflow;
__le32 rxFiltered;
__le32 linkStatus;
-#define TYPHOON_LINK_STAT_MASK __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_LINK_GOOD __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_LINK_BAD __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_LINK_SPEED_MASK __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_LINK_100MBPS __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_LINK_10MBPS __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_LINK_DUPLEX_MASK __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_LINK_FULL_DUPLEX __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_LINK_HALF_DUPLEX __constant_cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_STAT_MASK cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_GOOD cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_BAD cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_SPEED_MASK cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_100MBPS cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_10MBPS cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_DUPLEX_MASK cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_FULL_DUPLEX cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_HALF_DUPLEX cpu_to_le32(0x00000000)
__le32 unused2;
__le32 unused3;
} __attribute__ ((packed));
/* TYPHOON_CMD_XCVR_SELECT xcvr values (resp.parm1)
*/
-#define TYPHOON_XCVR_10HALF __constant_cpu_to_le16(0x0000)
-#define TYPHOON_XCVR_10FULL __constant_cpu_to_le16(0x0001)
-#define TYPHOON_XCVR_100HALF __constant_cpu_to_le16(0x0002)
-#define TYPHOON_XCVR_100FULL __constant_cpu_to_le16(0x0003)
-#define TYPHOON_XCVR_AUTONEG __constant_cpu_to_le16(0x0004)
+#define TYPHOON_XCVR_10HALF cpu_to_le16(0x0000)
+#define TYPHOON_XCVR_10FULL cpu_to_le16(0x0001)
+#define TYPHOON_XCVR_100HALF cpu_to_le16(0x0002)
+#define TYPHOON_XCVR_100FULL cpu_to_le16(0x0003)
+#define TYPHOON_XCVR_AUTONEG cpu_to_le16(0x0004)
/* TYPHOON_CMD_READ_MEDIA_STATUS (resp.parm1)
*/
-#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE __constant_cpu_to_le16(0x0004)
-#define TYPHOON_MEDIA_STAT_COLLISION_DETECT __constant_cpu_to_le16(0x0010)
-#define TYPHOON_MEDIA_STAT_CARRIER_SENSE __constant_cpu_to_le16(0x0020)
-#define TYPHOON_MEDIA_STAT_POLARITY_REV __constant_cpu_to_le16(0x0400)
-#define TYPHOON_MEDIA_STAT_NO_LINK __constant_cpu_to_le16(0x0800)
+#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE cpu_to_le16(0x0004)
+#define TYPHOON_MEDIA_STAT_COLLISION_DETECT cpu_to_le16(0x0010)
+#define TYPHOON_MEDIA_STAT_CARRIER_SENSE cpu_to_le16(0x0020)
+#define TYPHOON_MEDIA_STAT_POLARITY_REV cpu_to_le16(0x0400)
+#define TYPHOON_MEDIA_STAT_NO_LINK cpu_to_le16(0x0800)
/* TYPHOON_CMD_SET_MULTICAST_HASH enable values (cmd.parm1)
*/
-#define TYPHOON_MCAST_HASH_DISABLE __constant_cpu_to_le16(0x0000)
-#define TYPHOON_MCAST_HASH_ENABLE __constant_cpu_to_le16(0x0001)
-#define TYPHOON_MCAST_HASH_SET __constant_cpu_to_le16(0x0002)
+#define TYPHOON_MCAST_HASH_DISABLE cpu_to_le16(0x0000)
+#define TYPHOON_MCAST_HASH_ENABLE cpu_to_le16(0x0001)
+#define TYPHOON_MCAST_HASH_SET cpu_to_le16(0x0002)
/* TYPHOON_CMD_CREATE_SA descriptor and settings
*/
@@ -459,9 +459,9 @@ struct sa_descriptor {
u16 cmd;
u16 seqNo;
u16 mode;
-#define TYPHOON_SA_MODE_NULL __constant_cpu_to_le16(0x0000)
-#define TYPHOON_SA_MODE_AH __constant_cpu_to_le16(0x0001)
-#define TYPHOON_SA_MODE_ESP __constant_cpu_to_le16(0x0002)
+#define TYPHOON_SA_MODE_NULL cpu_to_le16(0x0000)
+#define TYPHOON_SA_MODE_AH cpu_to_le16(0x0001)
+#define TYPHOON_SA_MODE_ESP cpu_to_le16(0x0002)
u8 hashFlags;
#define TYPHOON_SA_HASH_ENABLE 0x01
#define TYPHOON_SA_HASH_SHA1 0x02
@@ -493,22 +493,22 @@ struct sa_descriptor {
/* TYPHOON_CMD_SET_OFFLOAD_TASKS bits (cmd.parm2 (Tx) & cmd.parm3 (Rx))
* This is all for IPv4.
*/
-#define TYPHOON_OFFLOAD_TCP_CHKSUM __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_OFFLOAD_UDP_CHKSUM __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_OFFLOAD_IP_CHKSUM __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_OFFLOAD_IPSEC __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_OFFLOAD_BCAST_THROTTLE __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_OFFLOAD_DHCP_PREVENT __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_OFFLOAD_VLAN __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_OFFLOAD_FILTERING __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_OFFLOAD_TCP_SEGMENT __constant_cpu_to_le32(0x00000200)
+#define TYPHOON_OFFLOAD_TCP_CHKSUM cpu_to_le32(0x00000002)
+#define TYPHOON_OFFLOAD_UDP_CHKSUM cpu_to_le32(0x00000004)
+#define TYPHOON_OFFLOAD_IP_CHKSUM cpu_to_le32(0x00000008)
+#define TYPHOON_OFFLOAD_IPSEC cpu_to_le32(0x00000010)
+#define TYPHOON_OFFLOAD_BCAST_THROTTLE cpu_to_le32(0x00000020)
+#define TYPHOON_OFFLOAD_DHCP_PREVENT cpu_to_le32(0x00000040)
+#define TYPHOON_OFFLOAD_VLAN cpu_to_le32(0x00000080)
+#define TYPHOON_OFFLOAD_FILTERING cpu_to_le32(0x00000100)
+#define TYPHOON_OFFLOAD_TCP_SEGMENT cpu_to_le32(0x00000200)
/* TYPHOON_CMD_ENABLE_WAKE_EVENTS bits (cmd.parm1)
*/
-#define TYPHOON_WAKE_MAGIC_PKT __constant_cpu_to_le16(0x01)
-#define TYPHOON_WAKE_LINK_EVENT __constant_cpu_to_le16(0x02)
-#define TYPHOON_WAKE_ICMP_ECHO __constant_cpu_to_le16(0x04)
-#define TYPHOON_WAKE_ARP __constant_cpu_to_le16(0x08)
+#define TYPHOON_WAKE_MAGIC_PKT cpu_to_le16(0x01)
+#define TYPHOON_WAKE_LINK_EVENT cpu_to_le16(0x02)
+#define TYPHOON_WAKE_ICMP_ECHO cpu_to_le16(0x04)
+#define TYPHOON_WAKE_ARP cpu_to_le16(0x08)
/* These are used to load the firmware image on the NIC
*/
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 11441225bf4..a110326dce6 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -39,7 +39,7 @@
#include <asm/ucc_fast.h>
#include "ucc_geth.h"
-#include "ucc_geth_mii.h"
+#include "fsl_pq_mdio.h"
#undef DEBUG
@@ -1536,17 +1536,15 @@ static void adjust_link(struct net_device *dev)
static int init_phy(struct net_device *dev)
{
struct ucc_geth_private *priv = netdev_priv(dev);
+ struct ucc_geth_info *ug_info = priv->ug_info;
struct phy_device *phydev;
- char phy_id[BUS_ID_SIZE];
priv->oldlink = 0;
priv->oldspeed = 0;
priv->oldduplex = -1;
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->ug_info->mdio_bus,
- priv->ug_info->phy_address);
-
- phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface);
+ phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0,
+ priv->phy_interface);
if (IS_ERR(phydev)) {
printk("%s: Could not attach to PHY\n", dev->name);
@@ -3251,7 +3249,7 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
howmany += ucc_geth_rx(ugeth, i, budget - howmany);
if (howmany < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS);
}
@@ -3282,10 +3280,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
/* check for receive events that require processing */
if (ucce & UCCE_RX_EVENTS) {
- if (netif_rx_schedule_prep(&ugeth->napi)) {
+ if (napi_schedule_prep(&ugeth->napi)) {
uccm &= ~UCCE_RX_EVENTS;
out_be32(uccf->p_uccm, uccm);
- __netif_rx_schedule(&ugeth->napi);
+ __napi_schedule(&ugeth->napi);
}
}
@@ -3503,6 +3501,20 @@ static phy_interface_t to_phy_interface(const char *phy_connection_type)
return PHY_INTERFACE_MODE_MII;
}
+static const struct net_device_ops ucc_geth_netdev_ops = {
+ .ndo_open = ucc_geth_open,
+ .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_change_mtu = eth_change_mtu,
+ .ndo_set_multicast_list = ucc_geth_set_multi,
+ .ndo_tx_timeout = ucc_geth_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ucc_netpoll,
+#endif
+};
+
static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match)
{
struct device *device = &ofdev->dev;
@@ -3614,10 +3626,12 @@ 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->mdio_bus, MII_BUS_ID_SIZE, "0");
- ug_info->phy_address = fixed_link[0];
+ 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);
@@ -3628,7 +3642,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
prop = of_get_property(phy, "reg", NULL);
if (prop == NULL)
return -1;
- ug_info->phy_address = *prop;
/* Set the bus id */
mdio = of_get_parent(phy);
@@ -3642,7 +3655,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
if (err)
return -1;
- snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "%x", res.start);
+ fsl_pq_mdio_bus_name(bus_name, mdio);
+ snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
+ "%s:%02x", bus_name, *prop);
}
/* get the phy interface type, or default to MII */
@@ -3715,19 +3730,11 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
/* Fill in the dev structure */
uec_set_ethtool_ops(dev);
- dev->open = ucc_geth_open;
- dev->hard_start_xmit = ucc_geth_start_xmit;
- dev->tx_timeout = ucc_geth_timeout;
+ 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);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ucc_netpoll;
-#endif
- dev->stop = ucc_geth_close;
-// dev->change_mtu = ucc_geth_change_mtu;
dev->mtu = 1500;
- dev->set_multicast_list = ucc_geth_set_multi;
ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
ugeth->phy_interface = phy_interface;
@@ -3748,6 +3755,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ugeth->ug_info = ug_info;
ugeth->dev = dev;
+ ugeth->node = np;
return 0;
}
@@ -3787,11 +3795,6 @@ static int __init ucc_geth_init(void)
{
int i, ret;
- ret = uec_mdio_init();
-
- if (ret)
- return ret;
-
if (netif_msg_drv(&debug))
printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
for (i = 0; i < 8; i++)
@@ -3800,16 +3803,12 @@ static int __init ucc_geth_init(void)
ret = of_register_platform_driver(&ucc_geth_driver);
- if (ret)
- uec_mdio_exit();
-
return ret;
}
static void __exit ucc_geth_exit(void)
{
of_unregister_platform_driver(&ucc_geth_driver);
- uec_mdio_exit();
}
module_init(ucc_geth_init);
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 8f699cb773e..e3a25e64a65 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -28,8 +28,6 @@
#include <asm/ucc.h>
#include <asm/ucc_fast.h>
-#include "ucc_geth_mii.h"
-
#define DRV_DESC "QE UCC Gigabit Ethernet Controller"
#define DRV_NAME "ucc_geth"
#define DRV_VERSION "1.1"
@@ -184,6 +182,18 @@ struct ucc_geth {
#define UCCE_RX_EVENTS (UCCE_RXF | UCC_GETH_UCCE_BSY)
#define UCCE_TX_EVENTS (UCCE_TXB | UCC_GETH_UCCE_TXE)
+/* TBI defines */
+#define ENET_TBI_MII_CR 0x00 /* Control */
+#define ENET_TBI_MII_SR 0x01 /* Status */
+#define ENET_TBI_MII_ANA 0x04 /* AN advertisement */
+#define ENET_TBI_MII_ANLPBPA 0x05 /* AN link partner base page ability */
+#define ENET_TBI_MII_ANEX 0x06 /* AN expansion */
+#define ENET_TBI_MII_ANNPT 0x07 /* AN next page transmit */
+#define ENET_TBI_MII_ANLPANP 0x08 /* AN link partner ability next page */
+#define ENET_TBI_MII_EXST 0x0F /* Extended status */
+#define ENET_TBI_MII_JD 0x10 /* Jitter diagnostics */
+#define ENET_TBI_MII_TBICON 0x11 /* TBI control */
+
/* UCC GETH MACCFG1 (MAC Configuration 1 Register) */
#define MACCFG1_FLOW_RX 0x00000020 /* Flow Control
Rx */
@@ -1091,8 +1101,7 @@ struct ucc_geth_info {
u32 eventRegMask;
u16 pausePeriod;
u16 extensionField;
- u8 phy_address;
- char mdio_bus[MII_BUS_ID_SIZE];
+ char phy_bus_id[BUS_ID_SIZE];
u8 weightfactor[NUM_TX_QUEUES];
u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES];
u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX];
@@ -1186,6 +1195,8 @@ struct ucc_geth_private {
int oldspeed;
int oldduplex;
int oldlink;
+
+ struct device_node *node;
};
void uec_set_ethtool_ops(struct net_device *netdev);
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 68a7f541413..a755bea559b 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -39,7 +39,6 @@
#include <asm/types.h>
#include "ucc_geth.h"
-#include "ucc_geth_mii.h"
static char hw_stat_gstrings[][ETH_GSTRING_LEN] = {
"tx-64-frames",
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
deleted file mode 100644
index c001d261366..00000000000
--- a/drivers/net/ucc_geth_mii.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * drivers/net/ucc_geth_mii.c
- *
- * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
- * Provides Bus interface for MII Management regs in the UCC register space
- *
- * Copyright (C) 2007 Freescale Semiconductor, Inc.
- *
- * Authors: Li Yang <leoli@freescale.com>
- * Kim Phillips <kim.phillips@freescale.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/fsl_devices.h>
-#include <linux/of_platform.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/ucc.h>
-
-#include "ucc_geth_mii.h"
-#include "ucc_geth.h"
-
-#define DEBUG
-#ifdef DEBUG
-#define vdbg(format, arg...) printk(KERN_DEBUG , format "\n" , ## arg)
-#else
-#define vdbg(format, arg...) do {} while(0)
-#endif
-
-#define MII_DRV_DESC "QE UCC Ethernet Controller MII Bus"
-#define MII_DRV_NAME "fsl-uec_mdio"
-
-/* Write value to the PHY for this device to the register at regnum, */
-/* waiting until the write is done before it returns. All PHY */
-/* configuration has to be done through the master UEC MIIM regs */
-int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
-{
- struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
-
- /* Setting up the MII Mangement Address Register */
- out_be32(&regs->miimadd,
- (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
-
- /* Setting up the MII Mangement Control Register with the value */
- out_be32(&regs->miimcon, value);
-
- /* Wait till MII management write is complete */
- while ((in_be32(&regs->miimind)) & MIIMIND_BUSY)
- cpu_relax();
-
- return 0;
-}
-
-/* Reads from register regnum in the PHY for device dev, */
-/* returning the value. Clears miimcom first. All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-{
- struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
- u16 value;
-
- /* Setting up the MII Mangement Address Register */
- out_be32(&regs->miimadd,
- (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
-
- /* Clear miimcom, perform an MII management read cycle */
- out_be32(&regs->miimcom, 0);
- out_be32(&regs->miimcom, MIIMCOM_READ_CYCLE);
-
- /* Wait till MII management write is complete */
- while ((in_be32(&regs->miimind)) & (MIIMIND_BUSY | MIIMIND_NOT_VALID))
- cpu_relax();
-
- /* Read MII management status */
- value = in_be32(&regs->miimstat);
-
- return value;
-}
-
-/* Reset the MIIM registers, and wait for the bus to free */
-static int uec_mdio_reset(struct mii_bus *bus)
-{
- struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
- unsigned int timeout = PHY_INIT_TIMEOUT;
-
- mutex_lock(&bus->mdio_lock);
-
- /* Reset the management interface */
- out_be32(&regs->miimcfg, MIIMCFG_RESET_MANAGEMENT);
-
- /* Setup the MII Mgmt clock speed */
- out_be32(&regs->miimcfg, MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112);
-
- /* Wait until the bus is free */
- while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
- cpu_relax();
-
- mutex_unlock(&bus->mdio_lock);
-
- if (timeout <= 0) {
- printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name);
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *match)
-{
- struct device *device = &ofdev->dev;
- struct device_node *np = ofdev->node, *tempnp = NULL;
- struct device_node *child = NULL;
- struct ucc_mii_mng __iomem *regs;
- struct mii_bus *new_bus;
- struct resource res;
- int k, err = 0;
-
- new_bus = mdiobus_alloc();
- if (NULL == new_bus)
- return -ENOMEM;
-
- new_bus->name = "UCC Ethernet Controller MII Bus";
- new_bus->read = &uec_mdio_read;
- new_bus->write = &uec_mdio_write;
- new_bus->reset = &uec_mdio_reset;
-
- memset(&res, 0, sizeof(res));
-
- err = of_address_to_resource(np, 0, &res);
- if (err)
- goto reg_map_fail;
-
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
-
- new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL);
-
- if (NULL == new_bus->irq) {
- err = -ENOMEM;
- goto reg_map_fail;
- }
-
- for (k = 0; k < 32; k++)
- new_bus->irq[k] = 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);
- new_bus->irq[*id] = irq;
- }
- }
-
- /* Set the base address */
- regs = ioremap(res.start, sizeof(struct ucc_mii_mng));
-
- if (NULL == regs) {
- err = -ENOMEM;
- goto ioremap_fail;
- }
-
- new_bus->priv = (void __force *)regs;
-
- new_bus->parent = device;
- dev_set_drvdata(device, new_bus);
-
- /* Read MII management master from device tree */
- while ((tempnp = of_find_compatible_node(tempnp, "network", "ucc_geth"))
- != NULL) {
- struct resource tempres;
-
- err = of_address_to_resource(tempnp, 0, &tempres);
- if (err)
- goto bus_register_fail;
-
- /* if our mdio regs fall within this UCC regs range */
- if ((res.start >= tempres.start) &&
- (res.end <= tempres.end)) {
- /* set this UCC to be the MII master */
- const u32 *id;
-
- id = of_get_property(tempnp, "cell-index", NULL);
- if (!id) {
- id = of_get_property(tempnp, "device-id", NULL);
- if (!id)
- goto bus_register_fail;
- }
-
- ucc_set_qe_mux_mii_mng(*id - 1);
-
- /* assign the TBI an address which won't
- * conflict with the PHYs */
- out_be32(&regs->utbipar, UTBIPAR_INIT_TBIPA);
- break;
- }
- }
-
- err = mdiobus_register(new_bus);
- if (0 != err) {
- printk(KERN_ERR "%s: Cannot register as MDIO bus\n",
- new_bus->name);
- goto bus_register_fail;
- }
-
- return 0;
-
-bus_register_fail:
- iounmap(regs);
-ioremap_fail:
- kfree(new_bus->irq);
-reg_map_fail:
- mdiobus_free(new_bus);
-
- return err;
-}
-
-static int uec_mdio_remove(struct of_device *ofdev)
-{
- struct device *device = &ofdev->dev;
- struct mii_bus *bus = dev_get_drvdata(device);
-
- mdiobus_unregister(bus);
-
- dev_set_drvdata(device, NULL);
-
- iounmap((void __iomem *)bus->priv);
- bus->priv = NULL;
- mdiobus_free(bus);
-
- return 0;
-}
-
-static struct of_device_id uec_mdio_match[] = {
- {
- .type = "mdio",
- .compatible = "ucc_geth_phy",
- },
- {
- .compatible = "fsl,ucc-mdio",
- },
- {},
-};
-
-static struct of_platform_driver uec_mdio_driver = {
- .name = MII_DRV_NAME,
- .probe = uec_mdio_probe,
- .remove = uec_mdio_remove,
- .match_table = uec_mdio_match,
-};
-
-int __init uec_mdio_init(void)
-{
- return of_register_platform_driver(&uec_mdio_driver);
-}
-
-/* called from __init ucc_geth_init, therefore can not be __exit */
-void uec_mdio_exit(void)
-{
- of_unregister_platform_driver(&uec_mdio_driver);
-}
diff --git a/drivers/net/ucc_geth_mii.h b/drivers/net/ucc_geth_mii.h
deleted file mode 100644
index 1e45b2028a5..00000000000
--- a/drivers/net/ucc_geth_mii.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * drivers/net/ucc_geth_mii.h
- *
- * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
- * Provides Bus interface for MII Management regs in the UCC register space
- *
- * Copyright (C) 2007 Freescale Semiconductor, Inc.
- *
- * Authors: Li Yang <leoli@freescale.com>
- * Kim Phillips <kim.phillips@freescale.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.
- *
- */
-#ifndef __UEC_MII_H
-#define __UEC_MII_H
-
-/* UCC GETH MIIMCFG (MII Management Configuration Register) */
-#define MIIMCFG_RESET_MANAGEMENT 0x80000000 /* Reset
- management */
-#define MIIMCFG_NO_PREAMBLE 0x00000010 /* Preamble
- suppress */
-#define MIIMCFG_CLOCK_DIVIDE_SHIFT (31 - 31) /* clock divide
- << shift */
-#define MIIMCFG_CLOCK_DIVIDE_MAX 0xf /* max clock divide */
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_2 0x00000000
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4 0x00000001
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6 0x00000002
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8 0x00000003
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10 0x00000004
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14 0x00000005
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_16 0x00000008
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20 0x00000006
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28 0x00000007
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_32 0x00000009
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_48 0x0000000a
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_64 0x0000000b
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_80 0x0000000c
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112 0x0000000d
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_160 0x0000000e
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_224 0x0000000f
-
-/* UCC GETH MIIMCOM (MII Management Command Register) */
-#define MIIMCOM_SCAN_CYCLE 0x00000002 /* Scan cycle */
-#define MIIMCOM_READ_CYCLE 0x00000001 /* Read cycle */
-
-/* UCC GETH MIIMADD (MII Management Address Register) */
-#define MIIMADD_PHY_ADDRESS_SHIFT (31 - 23) /* PHY Address
- << shift */
-#define MIIMADD_PHY_REGISTER_SHIFT (31 - 31) /* PHY Register
- << shift */
-
-/* UCC GETH MIIMCON (MII Management Control Register) */
-#define MIIMCON_PHY_CONTROL_SHIFT (31 - 31) /* PHY Control
- << shift */
-#define MIIMCON_PHY_STATUS_SHIFT (31 - 31) /* PHY Status
- << shift */
-
-/* UCC GETH MIIMIND (MII Management Indicator Register) */
-#define MIIMIND_NOT_VALID 0x00000004 /* Not valid */
-#define MIIMIND_SCAN 0x00000002 /* Scan in
- progress */
-#define MIIMIND_BUSY 0x00000001
-
-/* Initial TBI Physical Address */
-#define UTBIPAR_INIT_TBIPA 0x1f
-
-struct ucc_mii_mng {
- u32 miimcfg; /* MII management configuration reg */
- u32 miimcom; /* MII management command reg */
- u32 miimadd; /* MII management address reg */
- u32 miimcon; /* MII management control reg */
- u32 miimstat; /* MII management status reg */
- u32 miimind; /* MII management indication reg */
- u8 notcare[28]; /* Space holder */
- u32 utbipar; /* TBI phy address reg */
-} __attribute__ ((packed));
-
-/* TBI / MII Set Register */
-enum enet_tbi_mii_reg {
- ENET_TBI_MII_CR = 0x00, /* Control */
- ENET_TBI_MII_SR = 0x01, /* Status */
- ENET_TBI_MII_ANA = 0x04, /* AN advertisement */
- ENET_TBI_MII_ANLPBPA = 0x05, /* AN link partner base page ability */
- ENET_TBI_MII_ANEX = 0x06, /* AN expansion */
- ENET_TBI_MII_ANNPT = 0x07, /* AN next page transmit */
- ENET_TBI_MII_ANLPANP = 0x08, /* AN link partner ability next page */
- ENET_TBI_MII_EXST = 0x0F, /* Extended status */
- ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics */
- ENET_TBI_MII_TBICON = 0x11 /* TBI control */
-};
-
-int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
-int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
-int __init uec_mdio_init(void);
-void uec_mdio_exit(void);
-#endif /* __UEC_MII_H */
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index e009481c606..87b4a028991 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -807,6 +807,18 @@ static int ax88172_link_reset(struct usbnet *dev)
return 0;
}
+static const struct net_device_ops ax88172_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_do_ioctl = asix_ioctl,
+ .ndo_set_multicast_list = ax88172_set_multicast,
+};
+
static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret = 0;
@@ -846,9 +858,8 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
dev->mii.phy_id_mask = 0x3f;
dev->mii.reg_num_mask = 0x1f;
dev->mii.phy_id = asix_get_phy_addr(dev);
- dev->net->do_ioctl = asix_ioctl;
- dev->net->set_multicast_list = ax88172_set_multicast;
+ dev->net->netdev_ops = &ax88172_netdev_ops;
dev->net->ethtool_ops = &ax88172_ethtool_ops;
asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
@@ -898,6 +909,18 @@ static int ax88772_link_reset(struct usbnet *dev)
return 0;
}
+static const struct net_device_ops ax88772_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_do_ioctl = asix_ioctl,
+ .ndo_set_multicast_list = asix_set_multicast,
+};
+
static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret, embd_phy;
@@ -962,7 +985,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
dev->mii.mdio_write = asix_mdio_write;
dev->mii.phy_id_mask = 0x1f;
dev->mii.reg_num_mask = 0x1f;
- dev->net->do_ioctl = asix_ioctl;
dev->mii.phy_id = asix_get_phy_addr(dev);
phyid = asix_get_phyid(dev);
@@ -978,7 +1000,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
msleep(150);
- dev->net->set_multicast_list = asix_set_multicast;
+ dev->net->netdev_ops = &ax88772_netdev_ops;
dev->net->ethtool_ops = &ax88772_ethtool_ops;
asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
@@ -1181,6 +1203,18 @@ static int ax88178_change_mtu(struct net_device *net, int new_mtu)
return 0;
}
+static const struct net_device_ops ax88178_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 = asix_set_multicast,
+ .ndo_do_ioctl = asix_ioctl,
+ .ndo_change_mtu = ax88178_change_mtu,
+};
+
static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
{
struct asix_data *data = (struct asix_data *)&dev->data;
@@ -1247,11 +1281,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
dev->mii.phy_id_mask = 0x1f;
dev->mii.reg_num_mask = 0xff;
dev->mii.supports_gmii = 1;
- dev->net->do_ioctl = asix_ioctl;
dev->mii.phy_id = asix_get_phy_addr(dev);
- dev->net->set_multicast_list = asix_set_multicast;
+
+ dev->net->netdev_ops = &ax88178_netdev_ops;
dev->net->ethtool_ops = &ax88178_ethtool_ops;
- dev->net->change_mtu = &ax88178_change_mtu;
phyid = asix_get_phyid(dev);
dbg("PHYID=0x%08x", phyid);
@@ -1451,6 +1484,14 @@ static const struct usb_device_id products [] = {
// Cables-to-Go USB Ethernet Adapter
USB_DEVICE(0x0b95, 0x772a),
.driver_info = (unsigned long) &ax88772_info,
+}, {
+ // ABOCOM for pci
+ USB_DEVICE(0x14ea, 0xab11),
+ .driver_info = (unsigned long) &ax88178_info,
+}, {
+ // ASIX 88772a
+ USB_DEVICE(0x0db0, 0xa877),
+ .driver_info = (unsigned long) &ax88772_info,
},
{ }, // END
};
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index cb7acbbb279..b9dd4257428 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -163,7 +163,6 @@ struct catc {
struct net_device *netdev;
struct usb_device *usbdev;
- struct net_device_stats stats;
unsigned long flags;
unsigned int tx_ptr, tx_idx;
@@ -245,8 +244,8 @@ static void catc_rx_done(struct urb *urb)
if(!catc->is_f5u011) {
pkt_len = le16_to_cpup((__le16*)pkt_start);
if (pkt_len > urb->actual_length) {
- catc->stats.rx_length_errors++;
- catc->stats.rx_errors++;
+ catc->netdev->stats.rx_length_errors++;
+ catc->netdev->stats.rx_errors++;
break;
}
} else {
@@ -262,8 +261,8 @@ static void catc_rx_done(struct urb *urb)
skb->protocol = eth_type_trans(skb, catc->netdev);
netif_rx(skb);
- catc->stats.rx_packets++;
- catc->stats.rx_bytes += pkt_len;
+ catc->netdev->stats.rx_packets++;
+ catc->netdev->stats.rx_bytes += pkt_len;
/* F5U011 only does one packet per RX */
if (catc->is_f5u011)
@@ -386,7 +385,7 @@ static void catc_tx_done(struct urb *urb)
dbg("Tx Reset.");
urb->status = 0;
catc->netdev->trans_start = jiffies;
- catc->stats.tx_errors++;
+ catc->netdev->stats.tx_errors++;
clear_bit(TX_RUNNING, &catc->flags);
netif_wake_queue(catc->netdev);
return;
@@ -412,7 +411,7 @@ static void catc_tx_done(struct urb *urb)
spin_unlock_irqrestore(&catc->tx_lock, flags);
}
-static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static int catc_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct catc *catc = netdev_priv(netdev);
unsigned long flags;
@@ -443,8 +442,8 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
spin_unlock_irqrestore(&catc->tx_lock, flags);
if (r >= 0) {
- catc->stats.tx_bytes += skb->len;
- catc->stats.tx_packets++;
+ catc->netdev->stats.tx_bytes += skb->len;
+ catc->netdev->stats.tx_packets++;
}
dev_kfree_skb(skb);
@@ -588,15 +587,15 @@ static void catc_stats_done(struct catc *catc, struct ctrl_queue *q)
switch (index) {
case TxSingleColl:
case TxMultiColl:
- catc->stats.collisions += data - last;
+ catc->netdev->stats.collisions += data - last;
break;
case TxExcessColl:
- catc->stats.tx_aborted_errors += data - last;
- catc->stats.tx_errors += data - last;
+ catc->netdev->stats.tx_aborted_errors += data - last;
+ catc->netdev->stats.tx_errors += data - last;
break;
case RxFramErr:
- catc->stats.rx_frame_errors += data - last;
- catc->stats.rx_errors += data - last;
+ catc->netdev->stats.rx_frame_errors += data - last;
+ catc->netdev->stats.rx_errors += data - last;
break;
}
@@ -614,12 +613,6 @@ static void catc_stats_timer(unsigned long data)
mod_timer(&catc->timer, jiffies + STATS_UPDATE);
}
-static struct net_device_stats *catc_get_stats(struct net_device *netdev)
-{
- struct catc *catc = netdev_priv(netdev);
- return &catc->stats;
-}
-
/*
* Receive modes. Broadcast, Multicast, Promisc.
*/
@@ -750,6 +743,18 @@ static int catc_stop(struct net_device *netdev)
return 0;
}
+static const struct net_device_ops catc_netdev_ops = {
+ .ndo_open = catc_open,
+ .ndo_stop = catc_stop,
+ .ndo_start_xmit = catc_start_xmit,
+
+ .ndo_tx_timeout = catc_tx_timeout,
+ .ndo_set_multicast_list = catc_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* USB probe, disconnect.
*/
@@ -774,13 +779,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
catc = netdev_priv(netdev);
- netdev->open = catc_open;
- netdev->hard_start_xmit = catc_hard_start_xmit;
- netdev->stop = catc_stop;
- netdev->get_stats = catc_get_stats;
- netdev->tx_timeout = catc_tx_timeout;
+ netdev->netdev_ops = &catc_netdev_ops;
netdev->watchdog_timeo = TX_TIMEOUT;
- netdev->set_multicast_list = catc_set_multicast_list;
SET_ETHTOOL_OPS(netdev, &ops);
catc->usbdev = usbdev;
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 0e061dfea78..55e8ecc3a9e 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -559,6 +559,11 @@ static const struct usb_device_id products [] = {
USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &cdc_info,
+}, {
+ /* Ericsson F3507g */
+ USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
},
{ }, // END
};
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 5b67bbf1987..6fc4f82b0be 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -419,6 +419,18 @@ static int dm9601_set_mac_address(struct net_device *net, void *p)
return 0;
}
+static const struct net_device_ops dm9601_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_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = dm9601_ioctl,
+ .ndo_set_multicast_list = dm9601_set_multicast,
+ .ndo_set_mac_address = dm9601_set_mac_address,
+};
+
static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret;
@@ -428,9 +440,7 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
if (ret)
goto out;
- dev->net->do_ioctl = dm9601_ioctl;
- dev->net->set_multicast_list = dm9601_set_multicast;
- dev->net->set_mac_address = dm9601_set_mac_address;
+ dev->net->netdev_ops = &dm9601_netdev_ops;
dev->net->ethtool_ops = &dm9601_ethtool_ops;
dev->net->hard_header_len += DM_TX_OVERHEAD;
dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
@@ -635,6 +645,10 @@ static const struct usb_device_id products[] = {
USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */
.driver_info = (unsigned long)&dm9601_info,
},
+ {
+ USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */
+ .driver_info = (unsigned long)&dm9601_info,
+ },
{}, // END
};
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 0d0fa91c025..cde423c6d04 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -455,6 +455,7 @@ static const struct usb_device_id hso_ids[] = {
{icon321_port_device(0x0af0, 0xd033)}, /* Icon-322 */
{USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */
{USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */
+ {USB_DEVICE(0x0af0, 0x7381)}, /* GE40x */
{USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */
{USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */
{USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */
@@ -462,7 +463,8 @@ static const struct usb_device_id hso_ids[] = {
{USB_DEVICE(0x0af0, 0x7801)},
{USB_DEVICE(0x0af0, 0x7901)},
{USB_DEVICE(0x0af0, 0x7361)},
- {icon321_port_device(0x0af0, 0xd051)},
+ {USB_DEVICE(0x0af0, 0xd057)},
+ {USB_DEVICE(0x0af0, 0xd055)},
{}
};
MODULE_DEVICE_TABLE(usb, hso_ids);
@@ -934,8 +936,7 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
if (!odev->rx_buf_missing) {
/* Packet is complete. Inject into stack. */
/* We have IP packet here */
- odev->skb_rx_buf->protocol =
- __constant_htons(ETH_P_IP);
+ odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
/* don't check it */
odev->skb_rx_buf->ip_summed =
CHECKSUM_UNNECESSARY;
@@ -1245,7 +1246,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
* This needs to be a tasklet otherwise we will
* end up recursively calling this function.
*/
-void hso_unthrottle_tasklet(struct hso_serial *serial)
+static void hso_unthrottle_tasklet(struct hso_serial *serial)
{
unsigned long flags;
@@ -1264,7 +1265,7 @@ static void hso_unthrottle(struct tty_struct *tty)
tasklet_hi_schedule(&serial->unthrottle_tasklet);
}
-void hso_unthrottle_workfunc(struct work_struct *work)
+static void hso_unthrottle_workfunc(struct work_struct *work)
{
struct hso_serial *serial =
container_of(work, struct hso_serial,
@@ -1463,9 +1464,9 @@ static int hso_serial_chars_in_buffer(struct tty_struct *tty)
return chars;
}
-int tiocmget_submit_urb(struct hso_serial *serial,
- struct hso_tiocmget *tiocmget,
- struct usb_device *usb)
+static int tiocmget_submit_urb(struct hso_serial *serial,
+ struct hso_tiocmget *tiocmget,
+ struct usb_device *usb)
{
int result;
@@ -2362,12 +2363,6 @@ exit:
return -1;
}
-/* Frees a general hso device */
-static void hso_free_device(struct hso_device *hso_dev)
-{
- kfree(hso_dev);
-}
-
/* Creates a general hso device */
static struct hso_device *hso_create_device(struct usb_interface *intf,
int port_spec)
@@ -2430,9 +2425,16 @@ static void hso_free_net_device(struct hso_device *hso_dev)
free_netdev(hso_net->net);
}
- hso_free_device(hso_dev);
+ kfree(hso_dev);
}
+static const struct net_device_ops hso_netdev_ops = {
+ .ndo_open = hso_net_open,
+ .ndo_stop = hso_net_close,
+ .ndo_start_xmit = hso_net_start_xmit,
+ .ndo_tx_timeout = hso_net_tx_timeout,
+};
+
/* initialize the network interface */
static void hso_net_init(struct net_device *net)
{
@@ -2441,10 +2443,7 @@ static void hso_net_init(struct net_device *net)
D1("sizeof hso_net is %d", (int)sizeof(*hso_net));
/* fill in the other fields */
- net->open = hso_net_open;
- net->stop = hso_net_close;
- net->hard_start_xmit = hso_net_start_xmit;
- net->tx_timeout = hso_net_tx_timeout;
+ net->netdev_ops = &hso_netdev_ops;
net->watchdog_timeo = HSO_NET_TX_TIMEOUT;
net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
net->type = ARPHRD_NONE;
@@ -2644,7 +2643,7 @@ static void hso_free_serial_device(struct hso_device *hso_dev)
}
hso_free_tiomget(serial);
kfree(serial);
- hso_free_device(hso_dev);
+ kfree(hso_dev);
}
/* Creates a bulk AT channel */
@@ -2725,7 +2724,7 @@ exit2:
exit:
hso_free_tiomget(serial);
kfree(serial);
- hso_free_device(hso_dev);
+ kfree(hso_dev);
return NULL;
}
@@ -2784,7 +2783,7 @@ exit:
kfree(serial);
}
if (hso_dev)
- hso_free_device(hso_dev);
+ kfree(hso_dev);
return NULL;
}
@@ -2977,8 +2976,6 @@ static int hso_probe(struct usb_interface *interface,
goto exit;
}
- usb_driver_claim_interface(&hso_driver, interface, hso_dev);
-
/* save our data pointer in this device */
usb_set_intfdata(interface, hso_dev);
@@ -2996,8 +2993,6 @@ static void hso_disconnect(struct usb_interface *interface)
/* remove reference of our private data */
usb_set_intfdata(interface, NULL);
-
- usb_driver_release_interface(&hso_driver, interface);
}
static void async_get_intf(struct work_struct *data)
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 5385d66b306..7ae9afe99a4 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -94,10 +94,18 @@ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data)
{
struct usb_device *xdev = dev->udev;
int ret;
+ void *buffer;
+
+ buffer = kmalloc(size, GFP_NOIO);
+ if (buffer == NULL)
+ return -ENOMEM;
ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ,
- MCS7830_RD_BMREQ, 0x0000, index, data,
+ MCS7830_RD_BMREQ, 0x0000, index, buffer,
size, MCS7830_CTRL_TIMEOUT);
+ memcpy(data, buffer, size);
+ kfree(buffer);
+
return ret;
}
@@ -105,10 +113,18 @@ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data)
{
struct usb_device *xdev = dev->udev;
int ret;
+ void *buffer;
+
+ buffer = kmalloc(size, GFP_NOIO);
+ if (buffer == NULL)
+ return -ENOMEM;
+
+ memcpy(buffer, data, size);
ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ,
- MCS7830_WR_BMREQ, 0x0000, index, data,
+ MCS7830_WR_BMREQ, 0x0000, index, buffer,
size, MCS7830_CTRL_TIMEOUT);
+ kfree(buffer);
return ret;
}
@@ -470,6 +486,18 @@ static int mcs7830_set_mac_address(struct net_device *netdev, void *p)
return 0;
}
+static const struct net_device_ops mcs7830_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_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = mcs7830_ioctl,
+ .ndo_set_multicast_list = mcs7830_set_multicast,
+ .ndo_set_mac_address = mcs7830_set_mac_address,
+};
+
static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
{
struct net_device *net = dev->net;
@@ -479,11 +507,9 @@ static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
if (ret)
goto out;
- net->do_ioctl = mcs7830_ioctl;
net->ethtool_ops = &mcs7830_ethtool_ops;
- net->set_multicast_list = mcs7830_set_multicast;
+ net->netdev_ops = &mcs7830_netdev_ops;
mcs7830_set_multicast(net);
- net->set_mac_address = mcs7830_set_mac_address;
/* reserve space for the status byte on rx */
dev->rx_urb_size = ETH_FRAME_LEN + 1;
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index bcd858c567e..1bf243ef950 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -169,7 +169,7 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
struct rndis_keepalive_c *msg = (void *)buf;
msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
- msg->msg_len = ccpu2(sizeof *msg);
+ msg->msg_len = cpu_to_le32(sizeof *msg);
msg->status = RNDIS_STATUS_SUCCESS;
retval = usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, 0),
@@ -237,7 +237,7 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
u.get->oid = oid;
u.get->len = cpu_to_le32(in_len);
- u.get->offset = ccpu2(20);
+ u.get->offset = cpu_to_le32(20);
retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
if (unlikely(retval < 0)) {
@@ -266,6 +266,16 @@ response_error:
return -EDOM;
}
+/* same as usbnet_netdev_ops but MTU change not allowed */
+static const struct net_device_ops rndis_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,
+};
+
int
generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
{
@@ -297,9 +307,9 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
goto fail;
u.init->msg_type = RNDIS_MSG_INIT;
- u.init->msg_len = ccpu2(sizeof *u.init);
- u.init->major_version = ccpu2(1);
- u.init->minor_version = ccpu2(0);
+ u.init->msg_len = cpu_to_le32(sizeof *u.init);
+ u.init->major_version = cpu_to_le32(1);
+ u.init->minor_version = cpu_to_le32(0);
/* max transfer (in spec) is 0x4000 at full speed, but for
* TX we'll stick to one Ethernet packet plus RNDIS framing.
@@ -327,7 +337,8 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
dev->rx_urb_size &= ~(dev->maxpacket - 1);
u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
- net->change_mtu = NULL;
+ net->netdev_ops = &rndis_netdev_ops;
+
retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
if (unlikely(retval < 0)) {
/* it might not even be an RNDIS device!! */
@@ -403,10 +414,10 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
/* set a nonzero filter to enable data transfers */
memset(u.set, 0, sizeof *u.set);
u.set->msg_type = RNDIS_MSG_SET;
- u.set->msg_len = ccpu2(4 + sizeof *u.set);
+ u.set->msg_len = cpu_to_le32(4 + sizeof *u.set);
u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
- u.set->len = ccpu2(4);
- u.set->offset = ccpu2((sizeof *u.set) - 8);
+ u.set->len = cpu_to_le32(4);
+ u.set->offset = cpu_to_le32((sizeof *u.set) - 8);
*(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
@@ -423,7 +434,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
halt_fail_and_release:
memset(u.halt, 0, sizeof *u.halt);
u.halt->msg_type = RNDIS_MSG_HALT;
- u.halt->msg_len = ccpu2(sizeof *u.halt);
+ u.halt->msg_len = cpu_to_le32(sizeof *u.halt);
(void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
fail_and_release:
usb_set_intfdata(info->data, NULL);
@@ -448,7 +459,7 @@ void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
if (halt) {
halt->msg_type = RNDIS_MSG_HALT;
- halt->msg_len = ccpu2(sizeof *halt);
+ halt->msg_len = cpu_to_le32(sizeof *halt);
(void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
kfree(halt);
}
@@ -543,7 +554,7 @@ fill:
memset(hdr, 0, sizeof *hdr);
hdr->msg_type = RNDIS_MSG_PACKET;
hdr->msg_len = cpu_to_le32(skb->len);
- hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
+ hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8);
hdr->data_len = cpu_to_le32(len);
/* FIXME make the last packet always be short ... */
@@ -562,9 +573,6 @@ static const struct driver_info rndis_info = {
.tx_fixup = rndis_tx_fixup,
};
-#undef ccpu2
-
-
/*-------------------------------------------------------------------------*/
static const struct usb_device_id products [] = {
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index d8664bf18c0..f9fb454ffa8 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -155,7 +155,6 @@ struct rtl8150 {
unsigned long flags;
struct usb_device *udev;
struct tasklet_struct tl;
- struct net_device_stats stats;
struct net_device *netdev;
struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
struct sk_buff *tx_skb, *rx_skb;
@@ -463,8 +462,8 @@ static void read_bulk_callback(struct urb *urb)
skb_put(dev->rx_skb, pkt_len);
dev->rx_skb->protocol = eth_type_trans(dev->rx_skb, netdev);
netif_rx(dev->rx_skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += pkt_len;
spin_lock(&dev->rx_pool_lock);
skb = pull_skb(dev);
@@ -573,13 +572,13 @@ static void intr_callback(struct urb *urb)
d = urb->transfer_buffer;
if (d[0] & TSR_ERRORS) {
- dev->stats.tx_errors++;
+ dev->netdev->stats.tx_errors++;
if (d[INT_TSR] & (TSR_ECOL | TSR_JBR))
- dev->stats.tx_aborted_errors++;
+ dev->netdev->stats.tx_aborted_errors++;
if (d[INT_TSR] & TSR_LCOL)
- dev->stats.tx_window_errors++;
+ dev->netdev->stats.tx_window_errors++;
if (d[INT_TSR] & TSR_LOSS_CRS)
- dev->stats.tx_carrier_errors++;
+ dev->netdev->stats.tx_carrier_errors++;
}
/* Report link status changes to the network stack */
if ((d[INT_MSR] & MSR_LINK) == 0) {
@@ -697,17 +696,12 @@ static void disable_net_traffic(rtl8150_t * dev)
set_registers(dev, CR, 1, &cr);
}
-static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev)
-{
- return &((rtl8150_t *)netdev_priv(dev))->stats;
-}
-
static void rtl8150_tx_timeout(struct net_device *netdev)
{
rtl8150_t *dev = netdev_priv(netdev);
dev_warn(&netdev->dev, "Tx timeout.\n");
usb_unlink_urb(dev->tx_urb);
- dev->stats.tx_errors++;
+ netdev->stats.tx_errors++;
}
static void rtl8150_set_multicast(struct net_device *netdev)
@@ -747,12 +741,12 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
netif_device_detach(dev->netdev);
else {
dev_warn(&netdev->dev, "failed tx_urb %d\n", res);
- dev->stats.tx_errors++;
+ netdev->stats.tx_errors++;
netif_start_queue(netdev);
}
} else {
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += skb->len;
netdev->trans_start = jiffies;
}
@@ -897,6 +891,19 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return res;
}
+static const struct net_device_ops rtl8150_netdev_ops = {
+ .ndo_open = rtl8150_open,
+ .ndo_stop = rtl8150_close,
+ .ndo_do_ioctl = rtl8150_ioctl,
+ .ndo_start_xmit = rtl8150_start_xmit,
+ .ndo_tx_timeout = rtl8150_tx_timeout,
+ .ndo_set_multicast_list = rtl8150_set_multicast,
+ .ndo_set_mac_address = rtl8150_set_mac_address,
+
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int rtl8150_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -923,15 +930,8 @@ static int rtl8150_probe(struct usb_interface *intf,
dev->udev = udev;
dev->netdev = netdev;
- netdev->open = rtl8150_open;
- netdev->stop = rtl8150_close;
- netdev->do_ioctl = rtl8150_ioctl;
+ netdev->netdev_ops = &rtl8150_netdev_ops;
netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
- netdev->tx_timeout = rtl8150_tx_timeout;
- netdev->hard_start_xmit = rtl8150_start_xmit;
- netdev->set_multicast_list = rtl8150_set_multicast;
- netdev->set_mac_address = rtl8150_set_mac_address;
- netdev->get_stats = rtl8150_netdev_stats;
SET_ETHTOOL_OPS(netdev, &ops);
dev->intr_interval = 100; /* 100ms */
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 5574abe29c7..dc166532659 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -55,11 +55,10 @@ struct smsc95xx_priv {
struct usb_context {
struct usb_ctrlrequest req;
- struct completion notify;
struct usbnet *dev;
};
-int turbo_mode = true;
+static int turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
@@ -307,7 +306,7 @@ static int smsc95xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
return 0;
}
-static void smsc95xx_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
+static void smsc95xx_async_cmd_callback(struct urb *urb)
{
struct usb_context *usb_context = urb->context;
struct usbnet *dev = usb_context->dev;
@@ -316,8 +315,6 @@ static void smsc95xx_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
if (status < 0)
devwarn(dev, "async callback failed with %d", status);
- complete(&usb_context->notify);
-
kfree(usb_context);
usb_free_urb(urb);
}
@@ -348,11 +345,10 @@ static int smsc95xx_write_reg_async(struct usbnet *dev, u16 index, u32 *data)
usb_context->req.wValue = 00;
usb_context->req.wIndex = cpu_to_le16(index);
usb_context->req.wLength = cpu_to_le16(size);
- init_completion(&usb_context->notify);
usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
(void *)&usb_context->req, data, size,
- (usb_complete_t)smsc95xx_async_cmd_callback,
+ smsc95xx_async_cmd_callback,
(void *)usb_context);
status = usb_submit_urb(urb, GFP_ATOMIC);
@@ -1012,6 +1008,18 @@ static int smsc95xx_reset(struct usbnet *dev)
return 0;
}
+static const struct net_device_ops smsc95xx_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_do_ioctl = smsc95xx_ioctl,
+ .ndo_set_multicast_list = smsc95xx_set_multicast,
+};
+
static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
{
struct smsc95xx_priv *pdata = NULL;
@@ -1042,9 +1050,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
/* Init all registers */
ret = smsc95xx_reset(dev);
- dev->net->do_ioctl = smsc95xx_ioctl;
+ dev->net->netdev_ops = &smsc95xx_netdev_ops;
dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
- dev->net->set_multicast_list = smsc95xx_set_multicast;
dev->net->flags |= IFF_MULTICAST;
dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD;
return 0;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index aa314907888..659654f4588 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -223,7 +223,7 @@ EXPORT_SYMBOL_GPL(usbnet_skb_return);
*
*-------------------------------------------------------------------------*/
-static int usbnet_change_mtu (struct net_device *net, int new_mtu)
+int usbnet_change_mtu (struct net_device *net, int new_mtu)
{
struct usbnet *dev = netdev_priv(net);
int ll_mtu = new_mtu + net->hard_header_len;
@@ -246,14 +246,7 @@ static int usbnet_change_mtu (struct net_device *net, int new_mtu)
return 0;
}
-
-/*-------------------------------------------------------------------------*/
-
-static struct net_device_stats *usbnet_get_stats (struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- return &dev->stats;
-}
+EXPORT_SYMBOL_GPL(usbnet_change_mtu);
/*-------------------------------------------------------------------------*/
@@ -548,7 +541,7 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
// precondition: never called in_interrupt
-static int usbnet_stop (struct net_device *net)
+int usbnet_stop (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
int temp;
@@ -592,6 +585,7 @@ static int usbnet_stop (struct net_device *net)
return 0;
}
+EXPORT_SYMBOL_GPL(usbnet_stop);
/*-------------------------------------------------------------------------*/
@@ -599,7 +593,7 @@ static int usbnet_stop (struct net_device *net)
// precondition: never called in_interrupt
-static int usbnet_open (struct net_device *net)
+int usbnet_open (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
int retval;
@@ -674,6 +668,7 @@ done:
done_nopm:
return retval;
}
+EXPORT_SYMBOL_GPL(usbnet_open);
/*-------------------------------------------------------------------------*/
@@ -723,8 +718,8 @@ u32 usbnet_get_link (struct net_device *net)
if (dev->mii.mdio_read)
return mii_link_ok(&dev->mii);
- /* Otherwise, say we're up (to avoid breaking scripts) */
- return 1;
+ /* Otherwise, dtrt for drivers calling netif_carrier_{on,off} */
+ return ethtool_op_get_link(net);
}
EXPORT_SYMBOL_GPL(usbnet_get_link);
@@ -908,7 +903,7 @@ static void tx_complete (struct urb *urb)
/*-------------------------------------------------------------------------*/
-static void usbnet_tx_timeout (struct net_device *net)
+void usbnet_tx_timeout (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
@@ -917,10 +912,11 @@ static void usbnet_tx_timeout (struct net_device *net)
// FIXME: device recovery -- reset?
}
+EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
/*-------------------------------------------------------------------------*/
-static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
+int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
int length;
@@ -1003,7 +999,7 @@ drop:
}
return retval;
}
-
+EXPORT_SYMBOL_GPL(usbnet_start_xmit);
/*-------------------------------------------------------------------------*/
@@ -1110,6 +1106,15 @@ void usbnet_disconnect (struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(usbnet_disconnect);
+static const struct net_device_ops usbnet_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,
+};
/*-------------------------------------------------------------------------*/
@@ -1179,13 +1184,14 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
net->features |= NETIF_F_HIGHDMA;
#endif
- net->change_mtu = usbnet_change_mtu;
- net->get_stats = usbnet_get_stats;
+ 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->watchdog_timeo = TX_TIMEOUT_JIFFIES;
net->tx_timeout = usbnet_tx_timeout;
+#endif
+ net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
net->ethtool_ops = &usbnet_ethtool_ops;
// allow device-specific bind/init procedures
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c
index e24f7b3ace4..04882c8f9bf 100644
--- a/drivers/net/usb/zaurus.c
+++ b/drivers/net/usb/zaurus.c
@@ -341,6 +341,11 @@ static const struct usb_device_id products [] = {
USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &bogus_mdlm_info,
+}, {
+ /* Motorola MOTOMAGX phones */
+ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &bogus_mdlm_info,
},
/* Olympus has some models with a Zaurus-compatible option.
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 852d0e7c4e6..015db1cece7 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -19,12 +19,17 @@
#define DRV_NAME "veth"
#define DRV_VERSION "1.0"
+#define MIN_MTU 68 /* Min L3 MTU */
+#define MAX_MTU 65535 /* Max L3 MTU (arbitrary) */
+#define MTU_PAD (ETH_HLEN + 4) /* Max difference between L2 and L3 size MTU */
+
struct veth_net_stats {
unsigned long rx_packets;
unsigned long tx_packets;
unsigned long rx_bytes;
unsigned long tx_bytes;
unsigned long tx_dropped;
+ unsigned long rx_dropped;
};
struct veth_priv {
@@ -147,7 +152,7 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct net_device *rcv = NULL;
struct veth_priv *priv, *rcv_priv;
- struct veth_net_stats *stats;
+ struct veth_net_stats *stats, *rcv_stats;
int length, cpu;
skb_orphan(skb);
@@ -158,9 +163,13 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
cpu = smp_processor_id();
stats = per_cpu_ptr(priv->stats, cpu);
+ rcv_stats = per_cpu_ptr(rcv_priv->stats, cpu);
if (!(rcv->flags & IFF_UP))
- goto outf;
+ goto tx_drop;
+
+ if (skb->len > (rcv->mtu + MTU_PAD))
+ goto rx_drop;
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, rcv);
@@ -178,17 +187,21 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
stats->tx_bytes += length;
stats->tx_packets++;
- stats = per_cpu_ptr(rcv_priv->stats, cpu);
- stats->rx_bytes += length;
- stats->rx_packets++;
+ rcv_stats->rx_bytes += length;
+ rcv_stats->rx_packets++;
netif_rx(skb);
return 0;
-outf:
+tx_drop:
kfree_skb(skb);
stats->tx_dropped++;
return 0;
+
+rx_drop:
+ kfree_skb(skb);
+ rcv_stats->rx_dropped++;
+ return 0;
}
/*
@@ -210,6 +223,7 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev)
dev_stats->rx_bytes = 0;
dev_stats->tx_bytes = 0;
dev_stats->tx_dropped = 0;
+ dev_stats->rx_dropped = 0;
for_each_online_cpu(cpu) {
stats = per_cpu_ptr(priv->stats, cpu);
@@ -219,6 +233,7 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev)
dev_stats->rx_bytes += stats->rx_bytes;
dev_stats->tx_bytes += stats->tx_bytes;
dev_stats->tx_dropped += stats->tx_dropped;
+ dev_stats->rx_dropped += stats->rx_dropped;
}
return dev_stats;
@@ -239,6 +254,29 @@ static int veth_open(struct net_device *dev)
return 0;
}
+static int veth_close(struct net_device *dev)
+{
+ struct veth_priv *priv = netdev_priv(dev);
+
+ netif_carrier_off(dev);
+ netif_carrier_off(priv->peer);
+
+ return 0;
+}
+
+static int is_valid_veth_mtu(int new_mtu)
+{
+ return (new_mtu >= MIN_MTU && new_mtu <= MAX_MTU);
+}
+
+static int veth_change_mtu(struct net_device *dev, int new_mtu)
+{
+ if (!is_valid_veth_mtu(new_mtu))
+ return -EINVAL;
+ dev->mtu = new_mtu;
+ return 0;
+}
+
static int veth_dev_init(struct net_device *dev)
{
struct veth_net_stats *stats;
@@ -263,10 +301,13 @@ static void veth_dev_free(struct net_device *dev)
}
static const struct net_device_ops veth_netdev_ops = {
- .ndo_init = veth_dev_init,
- .ndo_open = veth_open,
- .ndo_start_xmit = veth_xmit,
- .ndo_get_stats = veth_get_stats,
+ .ndo_init = veth_dev_init,
+ .ndo_open = veth_open,
+ .ndo_stop = veth_close,
+ .ndo_start_xmit = veth_xmit,
+ .ndo_change_mtu = veth_change_mtu,
+ .ndo_get_stats = veth_get_stats,
+ .ndo_set_mac_address = eth_mac_addr,
};
static void veth_setup(struct net_device *dev)
@@ -279,44 +320,6 @@ static void veth_setup(struct net_device *dev)
dev->destructor = veth_dev_free;
}
-static void veth_change_state(struct net_device *dev)
-{
- struct net_device *peer;
- struct veth_priv *priv;
-
- priv = netdev_priv(dev);
- peer = priv->peer;
-
- if (netif_carrier_ok(peer)) {
- if (!netif_carrier_ok(dev))
- netif_carrier_on(dev);
- } else {
- if (netif_carrier_ok(dev))
- netif_carrier_off(dev);
- }
-}
-
-static int veth_device_event(struct notifier_block *unused,
- unsigned long event, void *ptr)
-{
- struct net_device *dev = ptr;
-
- if (dev->netdev_ops->ndo_open != veth_open)
- goto out;
-
- switch (event) {
- case NETDEV_CHANGE:
- veth_change_state(dev);
- break;
- }
-out:
- return NOTIFY_DONE;
-}
-
-static struct notifier_block veth_notifier_block __read_mostly = {
- .notifier_call = veth_device_event,
-};
-
/*
* netlink interface
*/
@@ -329,6 +332,10 @@ static int veth_validate(struct nlattr *tb[], struct nlattr *data[])
if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
return -EADDRNOTAVAIL;
}
+ if (tb[IFLA_MTU]) {
+ if (!is_valid_veth_mtu(nla_get_u32(tb[IFLA_MTU])))
+ return -EINVAL;
+ }
return 0;
}
@@ -467,14 +474,12 @@ static struct rtnl_link_ops veth_link_ops = {
static __init int veth_init(void)
{
- register_netdevice_notifier(&veth_notifier_block);
return rtnl_link_register(&veth_link_ops);
}
static __exit void veth_exit(void)
{
rtnl_link_unregister(&veth_link_ops);
- unregister_netdevice_notifier(&veth_notifier_block);
}
module_init(veth_init);
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 3b8e6325427..880eaf07413 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -109,8 +109,9 @@ static const int multicast_filter_limit = 32;
#include <linux/dmi.h>
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE
+ " Written by Donald Becker\n";
/* This driver was written to use PCI memory space. Some early versions
of the Rhine may only work correctly with I/O space accesses. */
@@ -589,7 +590,7 @@ static int rhine_napipoll(struct napi_struct *napi, int budget)
work_done = rhine_rx(dev, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
@@ -1319,7 +1320,7 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
IntrPCIErr | IntrStatsMax | IntrLinkChange,
ioaddr + IntrEnable);
- netif_rx_schedule(&rp->napi);
+ napi_schedule(&rp->napi);
}
if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index a75f91dc315..fb53ef872df 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1302,7 +1302,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
static int velocity_init_td_ring(struct velocity_info *vptr)
{
dma_addr_t curr;
- unsigned int j;
+ int j;
/* Init the TD ring entries */
for (j = 0; j < vptr->tx.numq; j++) {
@@ -1838,17 +1838,19 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_
{
struct sk_buff *skb = tdinfo->skb;
int i;
+ int pktlen;
/*
* Don't unmap the pre-allocated tx_bufs
*/
if (tdinfo->skb_dma) {
+ pktlen = (skb->len > ETH_ZLEN ? : ETH_ZLEN);
for (i = 0; i < tdinfo->nskb_dma; i++) {
#ifdef VELOCITY_ZERO_COPY_SUPPORT
pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], le16_to_cpu(td->tdesc1.len), PCI_DMA_TODEVICE);
#else
- pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], skb->len, PCI_DMA_TODEVICE);
+ pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], pktlen, PCI_DMA_TODEVICE);
#endif
tdinfo->skb_dma[i] = 0;
}
@@ -2080,17 +2082,14 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
struct tx_desc *td_ptr;
struct velocity_td_info *tdinfo;
unsigned long flags;
- int pktlen = skb->len;
+ int pktlen;
__le16 len;
int index;
-
- if (skb->len < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
- goto out;
- pktlen = ETH_ZLEN;
- }
+ if (skb_padto(skb, ETH_ZLEN))
+ goto out;
+ pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
len = cpu_to_le16(pktlen);
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 29a33090d3d..ea43e1832af 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -183,7 +183,7 @@ struct rdesc1 {
};
enum {
- RX_INTEN = __constant_cpu_to_le16(0x8000)
+ RX_INTEN = cpu_to_le16(0x8000)
};
struct rx_desc {
@@ -210,7 +210,7 @@ struct tdesc1 {
} __attribute__ ((__packed__));
enum {
- TD_QUEUE = __constant_cpu_to_le16(0x8000)
+ TD_QUEUE = cpu_to_le16(0x8000)
};
struct td_buf {
@@ -242,7 +242,7 @@ struct velocity_td_info {
enum velocity_owner {
OWNED_BY_HOST = 0,
- OWNED_BY_NIC = __constant_cpu_to_le16(0x8000)
+ OWNED_BY_NIC = cpu_to_le16(0x8000)
};
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 43f6523c40b..a6f1e19159d 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -24,6 +24,7 @@
#include <linux/virtio.h>
#include <linux/virtio_net.h>
#include <linux/scatterlist.h>
+#include <linux/if_vlan.h>
static int napi_weight = 128;
module_param(napi_weight, int, 0444);
@@ -33,15 +34,18 @@ module_param(csum, bool, 0444);
module_param(gso, bool, 0444);
/* FIXME: MTU in config. */
-#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
+#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
#define GOOD_COPY_LEN 128
+#define VIRTNET_SEND_COMMAND_SG_MAX 2
+
struct virtnet_info
{
struct virtio_device *vdev;
- struct virtqueue *rvq, *svq;
+ struct virtqueue *rvq, *svq, *cvq;
struct net_device *dev;
struct napi_struct napi;
+ unsigned int status;
/* The skb we couldn't send because buffers were full. */
struct sk_buff *last_xmit_skb;
@@ -286,7 +290,7 @@ static void try_fill_recv_maxbufs(struct virtnet_info *vi)
skb_put(skb, MAX_PACKET_LEN);
hdr = skb_vnet_hdr(skb);
- sg_init_one(sg, hdr, sizeof(*hdr));
+ sg_set_buf(sg, hdr, sizeof(*hdr));
if (vi->big_packets) {
for (i = 0; i < MAX_SKB_FRAGS; i++) {
@@ -374,9 +378,9 @@ static void skb_recv_done(struct virtqueue *rvq)
{
struct virtnet_info *vi = rvq->vdev->priv;
/* Schedule NAPI, Suppress further interrupts if successful. */
- if (netif_rx_schedule_prep(&vi->napi)) {
+ if (napi_schedule_prep(&vi->napi)) {
rvq->vq_ops->disable_cb(rvq);
- __netif_rx_schedule(&vi->napi);
+ __napi_schedule(&vi->napi);
}
}
@@ -402,11 +406,11 @@ again:
/* Out of packets? */
if (received < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq))
&& napi_schedule_prep(napi)) {
vi->rvq->vq_ops->disable_cb(vi->rvq);
- __netif_rx_schedule(napi);
+ __napi_schedule(napi);
goto again;
}
}
@@ -487,9 +491,9 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
/* Encode metadata header at front. */
if (vi->mergeable_rx_bufs)
- sg_init_one(sg, mhdr, sizeof(*mhdr));
+ sg_set_buf(sg, mhdr, sizeof(*mhdr));
else
- sg_init_one(sg, hdr, sizeof(*hdr));
+ sg_set_buf(sg, hdr, sizeof(*hdr));
num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
@@ -561,6 +565,22 @@ stop_queue:
goto done;
}
+static int virtnet_set_mac_address(struct net_device *dev, void *p)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct virtio_device *vdev = vi->vdev;
+ int ret;
+
+ ret = eth_mac_addr(dev, p);
+ if (ret)
+ return ret;
+
+ vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
+ dev->dev_addr, dev->addr_len);
+
+ return 0;
+}
+
#ifdef CONFIG_NET_POLL_CONTROLLER
static void virtnet_netpoll(struct net_device *dev)
{
@@ -580,13 +600,60 @@ static int virtnet_open(struct net_device *dev)
* won't get another interrupt, so process any outstanding packets
* now. virtnet_poll wants re-enable the queue, so we disable here.
* We synchronize against interrupts via NAPI_STATE_SCHED */
- if (netif_rx_schedule_prep(&vi->napi)) {
+ if (napi_schedule_prep(&vi->napi)) {
vi->rvq->vq_ops->disable_cb(vi->rvq);
- __netif_rx_schedule(&vi->napi);
+ __napi_schedule(&vi->napi);
}
return 0;
}
+/*
+ * Send command via the control virtqueue and check status. Commands
+ * supported by the hypervisor, as indicated by feature bits, should
+ * never fail unless improperly formated.
+ */
+static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
+ struct scatterlist *data, int out, int in)
+{
+ struct scatterlist sg[VIRTNET_SEND_COMMAND_SG_MAX + 2];
+ struct virtio_net_ctrl_hdr ctrl;
+ virtio_net_ctrl_ack status = ~0;
+ unsigned int tmp;
+
+ 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);
+
+ out++; /* Add header */
+ in++; /* Add return status */
+
+ ctrl.class = class;
+ ctrl.cmd = cmd;
+
+ sg_init_table(sg, out + in);
+
+ sg_set_buf(&sg[0], &ctrl, sizeof(ctrl));
+ memcpy(&sg[1], data, sizeof(struct scatterlist) * (out + in - 2));
+ 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();
+
+ vi->cvq->vq_ops->kick(vi->cvq);
+
+ /*
+ * Spin for a response, the kick causes an ioport write, trapping
+ * into the hypervisor, so the request should be handled immediately.
+ */
+ while (!vi->cvq->vq_ops->get_buf(vi->cvq, &tmp))
+ cpu_relax();
+
+ return status == VIRTIO_NET_OK;
+}
+
static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -607,10 +674,104 @@ static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
return ethtool_op_set_tx_hw_csum(dev, data);
}
+static void virtnet_set_rx_mode(struct net_device *dev)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct scatterlist sg[2];
+ u8 promisc, allmulti;
+ struct virtio_net_ctrl_mac *mac_data;
+ struct dev_addr_list *addr;
+ void *buf;
+ int i;
+
+ /* We can't dynamicaly set ndo_set_rx_mode, so return gracefully */
+ if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
+ return;
+
+ promisc = ((dev->flags & IFF_PROMISC) != 0);
+ allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
+
+ sg_set_buf(sg, &promisc, sizeof(promisc));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
+ VIRTIO_NET_CTRL_RX_PROMISC,
+ sg, 1, 0))
+ dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
+ promisc ? "en" : "dis");
+
+ sg_set_buf(sg, &allmulti, sizeof(allmulti));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
+ VIRTIO_NET_CTRL_RX_ALLMULTI,
+ sg, 1, 0))
+ dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
+ allmulti ? "en" : "dis");
+
+ /* MAC filter - use one buffer for both lists */
+ mac_data = buf = kzalloc(((dev->uc_count + dev->mc_count) * ETH_ALEN) +
+ (2 * sizeof(mac_data->entries)), GFP_ATOMIC);
+ if (!buf) {
+ dev_warn(&dev->dev, "No memory for MAC address buffer\n");
+ return;
+ }
+
+ /* 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);
+
+ sg_set_buf(&sg[0], mac_data,
+ sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN));
+
+ /* multicast list and count fill the end */
+ mac_data = (void *)&mac_data->macs[dev->uc_count][0];
+
+ mac_data->entries = dev->mc_count;
+ addr = dev->mc_list;
+ for (i = 0; i < dev->mc_count; i++, addr = addr->next)
+ memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN);
+
+ sg_set_buf(&sg[1], mac_data,
+ sizeof(mac_data->entries) + (dev->mc_count * ETH_ALEN));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
+ VIRTIO_NET_CTRL_MAC_TABLE_SET,
+ sg, 2, 0))
+ dev_warn(&dev->dev, "Failed to set MAC fitler table.\n");
+
+ kfree(buf);
+}
+
+static void virnet_vlan_rx_add_vid(struct net_device *dev, u16 vid)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct scatterlist sg;
+
+ sg_set_buf(&sg, &vid, sizeof(vid));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
+ VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0))
+ dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid);
+}
+
+static void virnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct scatterlist sg;
+
+ sg_set_buf(&sg, &vid, sizeof(vid));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
+ VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0))
+ dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid);
+}
+
static struct ethtool_ops virtnet_ethtool_ops = {
.set_tx_csum = virtnet_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.set_tso = ethtool_op_set_tso,
+ .get_link = ethtool_op_get_link,
};
#define MIN_MTU 68
@@ -629,13 +790,51 @@ static const struct net_device_ops virtnet_netdev = {
.ndo_stop = virtnet_close,
.ndo_start_xmit = start_xmit,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = virtnet_set_mac_address,
+ .ndo_set_rx_mode = virtnet_set_rx_mode,
.ndo_change_mtu = virtnet_change_mtu,
+ .ndo_vlan_rx_add_vid = virnet_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = virnet_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = virtnet_netpoll,
#endif
};
+static void virtnet_update_status(struct virtnet_info *vi)
+{
+ u16 v;
+
+ if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS))
+ return;
+
+ vi->vdev->config->get(vi->vdev,
+ offsetof(struct virtio_net_config, status),
+ &v, sizeof(v));
+
+ /* Ignore unknown (future) status bits */
+ v &= VIRTIO_NET_S_LINK_UP;
+
+ if (vi->status == v)
+ return;
+
+ vi->status = v;
+
+ if (vi->status & VIRTIO_NET_S_LINK_UP) {
+ netif_carrier_on(vi->dev);
+ netif_wake_queue(vi->dev);
+ } else {
+ netif_carrier_off(vi->dev);
+ netif_stop_queue(vi->dev);
+ }
+}
+
+static void virtnet_config_changed(struct virtio_device *vdev)
+{
+ struct virtnet_info *vi = vdev->priv;
+
+ virtnet_update_status(vi);
+}
+
static int virtnet_probe(struct virtio_device *vdev)
{
int err;
@@ -677,8 +876,11 @@ static int virtnet_probe(struct virtio_device *vdev)
vdev->config->get(vdev,
offsetof(struct virtio_net_config, mac),
dev->dev_addr, dev->addr_len);
- } else
+ } else {
random_ether_addr(dev->dev_addr);
+ vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
+ dev->dev_addr, dev->addr_len);
+ }
/* Set up our device-specific information */
vi = netdev_priv(dev);
@@ -714,6 +916,17 @@ static int virtnet_probe(struct virtio_device *vdev)
goto free_recv;
}
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
+ vi->cvq = vdev->config->find_vq(vdev, 2, NULL);
+ if (IS_ERR(vi->cvq)) {
+ err = PTR_ERR(vi->svq);
+ goto free_send;
+ }
+
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN))
+ dev->features |= NETIF_F_HW_VLAN_FILTER;
+ }
+
/* Initialize our empty receive and send queues. */
skb_queue_head_init(&vi->recv);
skb_queue_head_init(&vi->send);
@@ -726,7 +939,7 @@ static int virtnet_probe(struct virtio_device *vdev)
err = register_netdev(dev);
if (err) {
pr_debug("virtio_net: registering device failed\n");
- goto free_send;
+ goto free_ctrl;
}
/* Last of all, set up some receive buffers. */
@@ -738,11 +951,18 @@ static int virtnet_probe(struct virtio_device *vdev)
goto unregister;
}
+ vi->status = VIRTIO_NET_S_LINK_UP;
+ virtnet_update_status(vi);
+ netif_carrier_on(dev);
+
pr_debug("virtnet: registered device %s\n", dev->name);
return 0;
unregister:
unregister_netdev(dev);
+free_ctrl:
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
+ vdev->config->del_vq(vi->cvq);
free_send:
vdev->config->del_vq(vi->svq);
free_recv:
@@ -774,6 +994,8 @@ static void virtnet_remove(struct virtio_device *vdev)
vdev->config->del_vq(vi->svq);
vdev->config->del_vq(vi->rvq);
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
+ vdev->config->del_vq(vi->cvq);
unregister_netdev(vi->dev);
while (vi->pages)
@@ -793,7 +1015,8 @@ static unsigned int features[] = {
VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */
- VIRTIO_NET_F_MRG_RXBUF,
+ VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
+ VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
VIRTIO_F_NOTIFY_ON_EMPTY,
};
@@ -805,6 +1028,7 @@ static struct virtio_driver virtio_net = {
.id_table = id_table,
.probe = virtnet_probe,
.remove = __devexit_p(virtnet_remove),
+ .config_changed = virtnet_config_changed,
};
static int __init init(void)
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index b46897996f7..9693b0fd323 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -296,7 +296,13 @@ static void c101_destroy_card(card_t *card)
kfree(card);
}
-
+static const struct net_device_ops c101_ops = {
+ .ndo_open = c101_open,
+ .ndo_stop = c101_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = c101_ioctl,
+};
static int __init c101_run(unsigned long irq, unsigned long winbase)
{
@@ -367,9 +373,7 @@ static int __init c101_run(unsigned long irq, unsigned long winbase)
dev->mem_start = winbase;
dev->mem_end = winbase + C101_MAPPED_RAM_SIZE - 1;
dev->tx_queue_len = 50;
- dev->do_ioctl = c101_ioctl;
- dev->open = c101_open;
- dev->stop = c101_close;
+ dev->netdev_ops = &c101_ops;
hdlc->attach = sca_attach;
hdlc->xmit = sca_xmit;
card->settings.clock_type = CLOCK_EXT;
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index d80b72e22de..61581ee5f08 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -427,6 +427,15 @@ static void __exit cosa_exit(void)
}
module_exit(cosa_exit);
+static const struct net_device_ops cosa_ops = {
+ .ndo_open = cosa_net_open,
+ .ndo_stop = cosa_net_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = cosa_net_ioctl,
+ .ndo_tx_timeout = cosa_net_timeout,
+};
+
static int cosa_probe(int base, int irq, int dma)
{
struct cosa_data *cosa = cosa_cards+nr_cards;
@@ -575,10 +584,7 @@ static int cosa_probe(int base, int irq, int dma)
}
dev_to_hdlc(chan->netdev)->attach = cosa_net_attach;
dev_to_hdlc(chan->netdev)->xmit = cosa_net_tx;
- chan->netdev->open = cosa_net_open;
- chan->netdev->stop = cosa_net_close;
- chan->netdev->do_ioctl = cosa_net_ioctl;
- chan->netdev->tx_timeout = cosa_net_timeout;
+ chan->netdev->netdev_ops = &cosa_ops;
chan->netdev->watchdog_timeo = TX_TIMEOUT;
chan->netdev->base_addr = chan->cosa->datareg;
chan->netdev->irq = chan->cosa->irq;
@@ -725,8 +731,7 @@ static char *cosa_net_setup_rx(struct channel_data *chan, int size)
* We can safely fall back to non-dma-able memory, because we have
* the cosa->bouncebuf pre-allocated.
*/
- if (chan->rx_skb)
- kfree_skb(chan->rx_skb);
+ kfree_skb(chan->rx_skb);
chan->rx_skb = dev_alloc_skb(size);
if (chan->rx_skb == NULL) {
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet\n",
@@ -993,8 +998,8 @@ static struct fasync_struct *fasync[256] = { NULL, };
static int cosa_fasync(struct inode *inode, struct file *file, int on)
{
int port = iminor(inode);
- int rv = fasync_helper(inode, file, on, &fasync[port]);
- return rv < 0 ? rv : 0;
+
+ return fasync_helper(inode, file, on, &fasync[port]);
}
#endif
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 5fa52923efa..35dea3bea95 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -355,12 +355,6 @@ static int cycx_wan_update(struct wan_device *wandev)
return 0;
}
-/* callback to initialize device */
-static void cycx_x25_chan_setup(struct net_device *dev)
-{
- dev->init = cycx_netdevice_init;
-}
-
/* Create new logical channel.
* This routine is called by the router when ROUTER_IFNEW IOCTL is being
* handled.
@@ -476,6 +470,27 @@ static const struct header_ops cycx_header_ops = {
.rebuild = cycx_netdevice_rebuild_header,
};
+static const struct net_device_ops cycx_netdev_ops = {
+ .ndo_init = cycx_netdevice_init,
+ .ndo_open = cycx_netdevice_open,
+ .ndo_stop = cycx_netdevice_stop,
+ .ndo_start_xmit = cycx_netdevice_hard_start_xmit,
+ .ndo_get_stats = cycx_netdevice_get_stats,
+};
+
+static void cycx_x25_chan_setup(struct net_device *dev)
+{
+ /* Initialize device driver entry points */
+ dev->netdev_ops = &cycx_netdev_ops;
+ dev->header_ops = &cycx_header_ops;
+
+ /* Initialize media-specific parameters */
+ dev->mtu = CYCX_X25_CHAN_MTU;
+ dev->type = ARPHRD_HWX25; /* ARP h/w type */
+ dev->hard_header_len = 0; /* media header length */
+ dev->addr_len = 0; /* hardware address length */
+}
+
/* Initialize Linux network interface.
*
* This routine is called only once for each interface, during Linux network
@@ -487,20 +502,6 @@ static int cycx_netdevice_init(struct net_device *dev)
struct cycx_device *card = chan->card;
struct wan_device *wandev = &card->wandev;
- /* Initialize device driver entry points */
- dev->open = cycx_netdevice_open;
- dev->stop = cycx_netdevice_stop;
- dev->header_ops = &cycx_header_ops;
-
- dev->hard_start_xmit = cycx_netdevice_hard_start_xmit;
- dev->get_stats = cycx_netdevice_get_stats;
-
- /* Initialize media-specific parameters */
- dev->mtu = CYCX_X25_CHAN_MTU;
- dev->type = ARPHRD_HWX25; /* ARP h/w type */
- dev->hard_header_len = 0; /* media header length */
- dev->addr_len = 0; /* hardware address length */
-
if (!chan->svc)
*(__be16*)dev->dev_addr = htons(chan->lcn);
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index a297e3efa05..e8d155c3e59 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -114,7 +114,7 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
if (!pskb_may_pull(skb, sizeof(*hdr))) {
printk(KERN_NOTICE "%s: invalid data no header\n",
dev->name);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
kfree_skb(skb);
return;
}
@@ -127,7 +127,7 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
if (hdr->control != FRAD_I_UI)
{
printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
else
switch(hdr->IP_NLPID)
@@ -136,14 +136,14 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
if (hdr->NLPID != FRAD_P_SNAP)
{
printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
}
if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0)
{
printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
}
@@ -164,12 +164,12 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
case FRAD_P_Q933:
case FRAD_P_CLNP:
printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
default:
printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
}
@@ -178,9 +178,9 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
/* we've set up the protocol, so discard the header */
skb_reset_mac_header(skb);
skb_pull(skb, header);
- dlp->stats.rx_bytes += skb->len;
+ dev->stats.rx_bytes += skb->len;
netif_rx(skb);
- dlp->stats.rx_packets++;
+ dev->stats.rx_packets++;
}
else
dev_kfree_skb(skb);
@@ -200,19 +200,19 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
- ret = dlp->slave->hard_start_xmit(skb, dlp->slave);
+ ret = dlp->slave->netdev_ops->ndo_start_xmit(skb, dlp->slave);
switch (ret)
{
case DLCI_RET_OK:
- dlp->stats.tx_packets++;
+ dev->stats.tx_packets++;
ret = 0;
break;
case DLCI_RET_ERR:
- dlp->stats.tx_errors++;
+ dev->stats.tx_errors++;
ret = 0;
break;
case DLCI_RET_DROP:
- dlp->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
ret = 1;
break;
}
@@ -295,11 +295,9 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int dlci_change_mtu(struct net_device *dev, int new_mtu)
{
- struct dlci_local *dlp;
-
- dlp = netdev_priv(dev);
+ struct dlci_local *dlp = netdev_priv(dev);
- return((*dlp->slave->change_mtu)(dlp->slave, new_mtu));
+ return dev_set_mtu(dlp->slave, new_mtu);
}
static int dlci_open(struct net_device *dev)
@@ -342,15 +340,6 @@ static int dlci_close(struct net_device *dev)
return 0;
}
-static struct net_device_stats *dlci_get_stats(struct net_device *dev)
-{
- struct dlci_local *dlp;
-
- dlp = netdev_priv(dev);
-
- return(&dlp->stats);
-}
-
static int dlci_add(struct dlci_add *dlci)
{
struct net_device *master, *slave;
@@ -488,18 +477,21 @@ static const struct header_ops dlci_header_ops = {
.create = dlci_header,
};
+static const struct net_device_ops dlci_netdev_ops = {
+ .ndo_open = dlci_open,
+ .ndo_stop = dlci_close,
+ .ndo_do_ioctl = dlci_dev_ioctl,
+ .ndo_start_xmit = dlci_transmit,
+ .ndo_change_mtu = dlci_change_mtu,
+};
+
static void dlci_setup(struct net_device *dev)
{
struct dlci_local *dlp = netdev_priv(dev);
dev->flags = 0;
- dev->open = dlci_open;
- dev->stop = dlci_close;
- dev->do_ioctl = dlci_dev_ioctl;
- dev->hard_start_xmit = dlci_transmit;
dev->header_ops = &dlci_header_ops;
- dev->get_stats = dlci_get_stats;
- dev->change_mtu = dlci_change_mtu;
+ dev->netdev_ops = &dlci_netdev_ops;
dev->destructor = free_netdev;
dlp->receive = dlci_receive;
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 888025db2f0..8face5db8f3 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -883,6 +883,15 @@ static inline int dscc4_set_quartz(struct dscc4_dev_priv *dpriv, int hz)
return ret;
}
+static const struct net_device_ops dscc4_ops = {
+ .ndo_open = dscc4_open,
+ .ndo_stop = dscc4_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = dscc4_ioctl,
+ .ndo_tx_timeout = dscc4_tx_timeout,
+};
+
static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr)
{
struct dscc4_pci_priv *ppriv;
@@ -916,13 +925,8 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr)
hdlc_device *hdlc = dev_to_hdlc(d);
d->base_addr = (unsigned long)ioaddr;
- d->init = NULL;
d->irq = pdev->irq;
- d->open = dscc4_open;
- d->stop = dscc4_close;
- d->set_multicast_list = NULL;
- d->do_ioctl = dscc4_ioctl;
- d->tx_timeout = dscc4_tx_timeout;
+ d->netdev_ops = &dscc4_ops;
d->watchdog_timeo = TX_TIMEOUT;
SET_NETDEV_DEV(d, &pdev->dev);
@@ -1048,7 +1052,7 @@ static int dscc4_open(struct net_device *dev)
struct dscc4_pci_priv *ppriv;
int ret = -EAGAIN;
- if ((dscc4_loopback_check(dpriv) < 0) || !dev->hard_start_xmit)
+ if ((dscc4_loopback_check(dpriv) < 0))
goto err;
if ((ret = hdlc_open(dev)))
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 48a2c9d2895..00945f7c1e9 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2424,6 +2424,15 @@ fst_init_card(struct fst_card_info *card)
type_strings[card->type], card->irq, card->nports);
}
+static const struct net_device_ops fst_ops = {
+ .ndo_open = fst_open,
+ .ndo_stop = fst_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = fst_ioctl,
+ .ndo_tx_timeout = fst_tx_timeout,
+};
+
/*
* Initialise card when detected.
* Returns 0 to indicate success, or errno otherwise.
@@ -2565,12 +2574,9 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->base_addr = card->pci_conf;
dev->irq = card->irq;
- dev->tx_queue_len = FST_TX_QUEUE_LEN;
- dev->open = fst_open;
- dev->stop = fst_close;
- dev->do_ioctl = fst_ioctl;
- dev->watchdog_timeo = FST_TX_TIMEOUT;
- dev->tx_timeout = fst_tx_timeout;
+ dev->netdev_ops = &fst_ops;
+ dev->tx_queue_len = FST_TX_QUEUE_LEN;
+ dev->watchdog_timeo = FST_TX_TIMEOUT;
hdlc->attach = fst_attach;
hdlc->xmit = fst_start_xmit;
}
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c
index 08b3536944f..497b003d723 100644
--- a/drivers/net/wan/hd64572.c
+++ b/drivers/net/wan/hd64572.c
@@ -341,7 +341,7 @@ static int sca_poll(struct napi_struct *napi, int budget)
received = sca_rx_done(port, budget);
if (received < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
enable_intr(port);
}
@@ -359,7 +359,7 @@ static irqreturn_t sca_intr(int irq, void *dev_id)
if (port && (isr0 & (i ? 0x08002200 : 0x00080022))) {
handled = 1;
disable_intr(port);
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
}
}
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 1f2a140c9f7..7596eae1b35 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -44,7 +44,7 @@ static const char* version = "HDLC support module revision 1.22";
static struct hdlc_proto *first_proto;
-static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
+int hdlc_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
return -EINVAL;
@@ -52,15 +52,6 @@ static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-
-
-static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
-
-
static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *p, struct net_device *orig_dev)
{
@@ -75,7 +66,15 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
return hdlc->proto->netif_rx(skb);
}
+int hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ hdlc_device *hdlc = dev_to_hdlc(dev);
+
+ if (hdlc->proto->xmit)
+ return hdlc->proto->xmit(skb, dev);
+ return hdlc->xmit(skb, dev); /* call hardware driver directly */
+}
static inline void hdlc_proto_start(struct net_device *dev)
{
@@ -102,11 +101,11 @@ static int hdlc_device_event(struct notifier_block *this, unsigned long event,
hdlc_device *hdlc;
unsigned long flags;
int on;
-
+
if (dev_net(dev) != &init_net)
return NOTIFY_DONE;
- if (dev->get_stats != hdlc_get_stats)
+ if (!(dev->priv_flags & IFF_WAN_HDLC))
return NOTIFY_DONE; /* not an HDLC device */
if (event != NETDEV_CHANGE)
@@ -233,15 +232,13 @@ static void hdlc_setup_dev(struct net_device *dev)
/* Re-init all variables changed by HDLC protocol drivers,
* including ether_setup() called from hdlc_raw_eth.c.
*/
- dev->get_stats = hdlc_get_stats;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->priv_flags = IFF_WAN_HDLC;
dev->mtu = HDLC_MAX_MTU;
dev->type = ARPHRD_RAWHDLC;
dev->hard_header_len = 16;
dev->addr_len = 0;
dev->header_ops = &hdlc_null_ops;
-
- dev->change_mtu = hdlc_change_mtu;
}
static void hdlc_setup(struct net_device *dev)
@@ -339,6 +336,8 @@ MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
MODULE_DESCRIPTION("HDLC support module");
MODULE_LICENSE("GPL v2");
+EXPORT_SYMBOL(hdlc_change_mtu);
+EXPORT_SYMBOL(hdlc_start_xmit);
EXPORT_SYMBOL(hdlc_open);
EXPORT_SYMBOL(hdlc_close);
EXPORT_SYMBOL(hdlc_ioctl);
@@ -349,8 +348,8 @@ EXPORT_SYMBOL(unregister_hdlc_protocol);
EXPORT_SYMBOL(attach_hdlc_protocol);
EXPORT_SYMBOL(detach_hdlc_protocol);
-static struct packet_type hdlc_packet_type = {
- .type = __constant_htons(ETH_P_HDLC),
+static struct packet_type hdlc_packet_type __read_mostly = {
+ .type = cpu_to_be16(ETH_P_HDLC),
.func = hdlc_rcv,
};
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 44e64b15dbd..cf5fd17ad70 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -117,7 +117,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
data->type = htonl(type);
data->par1 = par1;
data->par2 = par2;
- data->rel = __constant_htons(0xFFFF);
+ data->rel = cpu_to_be16(0xFFFF);
/* we will need do_div here if 1000 % HZ != 0 */
data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ));
@@ -136,20 +136,20 @@ static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
struct hdlc_header *data = (struct hdlc_header*)skb->data;
if (skb->len < sizeof(struct hdlc_header))
- return __constant_htons(ETH_P_HDLC);
+ return cpu_to_be16(ETH_P_HDLC);
if (data->address != CISCO_MULTICAST &&
data->address != CISCO_UNICAST)
- return __constant_htons(ETH_P_HDLC);
+ return cpu_to_be16(ETH_P_HDLC);
switch(data->protocol) {
- case __constant_htons(ETH_P_IP):
- case __constant_htons(ETH_P_IPX):
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IPX):
+ case cpu_to_be16(ETH_P_IPV6):
skb_pull(skb, sizeof(struct hdlc_header));
return data->protocol;
default:
- return __constant_htons(ETH_P_HDLC);
+ return cpu_to_be16(ETH_P_HDLC);
}
}
@@ -194,7 +194,7 @@ static int cisco_rx(struct sk_buff *skb)
case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
in_dev = dev->ip_ptr;
addr = 0;
- mask = __constant_htonl(~0); /* is the mask correct? */
+ mask = ~cpu_to_be32(0); /* is the mask correct? */
if (in_dev != NULL) {
struct in_ifaddr **ifap = &in_dev->ifa_list;
@@ -382,7 +382,6 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
memcpy(&state(hdlc)->settings, &new_settings, size);
spin_lock_init(&state(hdlc)->lock);
- dev->hard_start_xmit = hdlc->xmit;
dev->header_ops = &cisco_header_ops;
dev->type = ARPHRD_CISCO;
netif_dormant_on(dev);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index f1ddd7c3459..80053010109 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -278,31 +278,31 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
struct sk_buff *skb = *skb_p;
switch (skb->protocol) {
- case __constant_htons(NLPID_CCITT_ANSI_LMI):
+ case cpu_to_be16(NLPID_CCITT_ANSI_LMI):
head_len = 4;
skb_push(skb, head_len);
skb->data[3] = NLPID_CCITT_ANSI_LMI;
break;
- case __constant_htons(NLPID_CISCO_LMI):
+ case cpu_to_be16(NLPID_CISCO_LMI):
head_len = 4;
skb_push(skb, head_len);
skb->data[3] = NLPID_CISCO_LMI;
break;
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
head_len = 4;
skb_push(skb, head_len);
skb->data[3] = NLPID_IP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
head_len = 4;
skb_push(skb, head_len);
skb->data[3] = NLPID_IPV6;
break;
- case __constant_htons(ETH_P_802_3):
+ case cpu_to_be16(ETH_P_802_3):
head_len = 10;
if (skb_headroom(skb) < head_len) {
struct sk_buff *skb2 = skb_realloc_headroom(skb,
@@ -426,7 +426,7 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
skb_put(skb, pad);
memset(skb->data + len, 0, pad);
}
- skb->protocol = __constant_htons(ETH_P_802_3);
+ skb->protocol = cpu_to_be16(ETH_P_802_3);
}
if (!fr_hard_header(&skb, pvc->dlci)) {
dev->stats.tx_bytes += skb->len;
@@ -444,18 +444,6 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-
-
-static int pvc_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
-
-
static inline void fr_log_dlci_active(pvc_device *pvc)
{
printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n",
@@ -508,10 +496,10 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
memset(skb->data, 0, len);
skb_reserve(skb, 4);
if (lmi == LMI_CISCO) {
- skb->protocol = __constant_htons(NLPID_CISCO_LMI);
+ skb->protocol = cpu_to_be16(NLPID_CISCO_LMI);
fr_hard_header(&skb, LMI_CISCO_DLCI);
} else {
- skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI);
+ skb->protocol = cpu_to_be16(NLPID_CCITT_ANSI_LMI);
fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI);
}
data = skb_tail_pointer(skb);
@@ -1068,6 +1056,14 @@ static void pvc_setup(struct net_device *dev)
dev->addr_len = 2;
}
+static const struct net_device_ops pvc_ops = {
+ .ndo_open = pvc_open,
+ .ndo_stop = pvc_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = pvc_xmit,
+ .ndo_do_ioctl = pvc_ioctl,
+};
+
static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
{
hdlc_device *hdlc = dev_to_hdlc(frad);
@@ -1104,11 +1100,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
*(__be16*)dev->dev_addr = htons(dlci);
dlci_to_q922(dev->broadcast, dlci);
}
- dev->hard_start_xmit = pvc_xmit;
- dev->open = pvc_open;
- dev->stop = pvc_close;
- dev->do_ioctl = pvc_ioctl;
- dev->change_mtu = pvc_change_mtu;
+ dev->netdev_ops = &pvc_ops;
dev->mtu = HDLC_MAX_MTU;
dev->tx_queue_len = 0;
dev->ml_priv = pvc;
@@ -1260,8 +1252,6 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
state(hdlc)->dce_pvc_count = 0;
}
memcpy(&state(hdlc)->settings, &new_settings, size);
-
- dev->hard_start_xmit = hdlc->xmit;
dev->type = ARPHRD_FRAD;
return 0;
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 57fe714c1c7..72a7cdab424 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -150,11 +150,11 @@ static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev)
return htons(ETH_P_HDLC);
switch (data->protocol) {
- case __constant_htons(PID_IP):
+ case cpu_to_be16(PID_IP):
skb_pull(skb, sizeof(struct hdlc_header));
return htons(ETH_P_IP);
- case __constant_htons(PID_IPV6):
+ case cpu_to_be16(PID_IPV6):
skb_pull(skb, sizeof(struct hdlc_header));
return htons(ETH_P_IPV6);
@@ -558,7 +558,6 @@ out:
return NET_RX_DROP;
}
-
static void ppp_timer(unsigned long arg)
{
struct proto *proto = (struct proto *)arg;
@@ -679,7 +678,6 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
ppp->keepalive_interval = 10;
ppp->keepalive_timeout = 60;
- dev->hard_start_xmit = hdlc->xmit;
dev->hard_header_len = sizeof(struct hdlc_header);
dev->header_ops = &ppp_header_ops;
dev->type = ARPHRD_PPP;
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index 8612311748f..19f51fdd552 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -27,11 +27,9 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
{
- return __constant_htons(ETH_P_IP);
+ return cpu_to_be16(ETH_P_IP);
}
-
-
static struct hdlc_proto proto = {
.type_trans = raw_type_trans,
.ioctl = raw_ioctl,
@@ -86,7 +84,6 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
if (result)
return result;
memcpy(hdlc->state, &new_settings, size);
- dev->hard_start_xmit = hdlc->xmit;
dev->type = ARPHRD_RAWHDLC;
netif_dormant_off(dev);
return 0;
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index a13fc320752..49e68f5ca5f 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -45,6 +45,7 @@ static int eth_tx(struct sk_buff *skb, struct net_device *dev)
static struct hdlc_proto proto = {
.type_trans = eth_type_trans,
+ .xmit = eth_tx,
.ioctl = raw_eth_ioctl,
.module = THIS_MODULE,
};
@@ -56,9 +57,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
const size_t size = sizeof(raw_hdlc_proto);
raw_hdlc_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
- int result;
- int (*old_ch_mtu)(struct net_device *, int);
- int old_qlen;
+ int result, old_qlen;
switch (ifr->ifr_settings.type) {
case IF_GET_PROTO:
@@ -99,11 +98,8 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
if (result)
return result;
memcpy(hdlc->state, &new_settings, size);
- dev->hard_start_xmit = eth_tx;
- old_ch_mtu = dev->change_mtu;
old_qlen = dev->tx_queue_len;
ether_setup(dev);
- dev->change_mtu = old_ch_mtu;
dev->tx_queue_len = old_qlen;
random_ether_addr(dev->dev_addr);
netif_dormant_off(dev);
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index cbcbf6f0414..b1dc29ed158 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -184,6 +184,7 @@ static struct hdlc_proto proto = {
.close = x25_close,
.ioctl = x25_ioctl,
.netif_rx = x25_rx,
+ .xmit = x25_xmit,
.module = THIS_MODULE,
};
@@ -213,7 +214,6 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
if ((result = attach_hdlc_protocol(dev, &proto, 0)))
return result;
- dev->hard_start_xmit = x25_xmit;
dev->type = ARPHRD_X25;
netif_dormant_off(dev);
return 0;
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index af54f0cf1b3..567d4f5062d 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -173,6 +173,14 @@ static int hostess_attach(struct net_device *dev, unsigned short encoding,
* Description block for a Comtrol Hostess SV11 card
*/
+static const struct net_device_ops hostess_ops = {
+ .ndo_open = hostess_open,
+ .ndo_stop = hostess_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hostess_ioctl,
+};
+
static struct z8530_dev *sv11_init(int iobase, int irq)
{
struct z8530_dev *sv;
@@ -267,9 +275,7 @@ static struct z8530_dev *sv11_init(int iobase, int irq)
dev_to_hdlc(netdev)->attach = hostess_attach;
dev_to_hdlc(netdev)->xmit = hostess_queue_xmit;
- netdev->open = hostess_open;
- netdev->stop = hostess_close;
- netdev->do_ioctl = hostess_ioctl;
+ netdev->netdev_ops = &hostess_ops;
netdev->base_addr = iobase;
netdev->irq = irq;
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 0dbd85b0162..3bf7d3f447d 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -622,7 +622,7 @@ static void hss_hdlc_rx_irq(void *pdev)
printk(KERN_DEBUG "%s: hss_hdlc_rx_irq\n", dev->name);
#endif
qmgr_disable_irq(queue_ids[port->id].rx);
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
}
static int hss_hdlc_poll(struct napi_struct *napi, int budget)
@@ -649,15 +649,15 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget)
if ((n = queue_get_desc(rxq, port, 0)) < 0) {
#if DEBUG_RX
printk(KERN_DEBUG "%s: hss_hdlc_poll"
- " netif_rx_complete\n", dev->name);
+ " napi_complete\n", dev->name);
#endif
- netif_rx_complete(napi);
+ napi_complete(napi);
qmgr_enable_irq(rxq);
if (!qmgr_stat_empty(rxq) &&
- netif_rx_reschedule(napi)) {
+ napi_reschedule(napi)) {
#if DEBUG_RX
printk(KERN_DEBUG "%s: hss_hdlc_poll"
- " netif_rx_reschedule succeeded\n",
+ " napi_reschedule succeeded\n",
dev->name);
#endif
qmgr_disable_irq(rxq);
@@ -1069,7 +1069,7 @@ static int hss_hdlc_open(struct net_device *dev)
hss_start_hdlc(port);
/* we may already have RX data, enables IRQ */
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
return 0;
err_unlock:
@@ -1230,6 +1230,14 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
* initialization
****************************************************************************/
+static const struct net_device_ops hss_hdlc_ops = {
+ .ndo_open = hss_hdlc_open,
+ .ndo_stop = hss_hdlc_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hss_hdlc_ioctl,
+};
+
static int __devinit hss_init_one(struct platform_device *pdev)
{
struct port *port;
@@ -1254,9 +1262,7 @@ static int __devinit hss_init_one(struct platform_device *pdev)
hdlc = dev_to_hdlc(dev);
hdlc->attach = hss_hdlc_attach;
hdlc->xmit = hss_hdlc_xmit;
- dev->open = hss_hdlc_open;
- dev->stop = hss_hdlc_close;
- dev->do_ioctl = hss_hdlc_ioctl;
+ dev->netdev_ops = &hss_hdlc_ops;
dev->tx_queue_len = 100;
port->clock_type = CLOCK_EXT;
port->clock_rate = 2048000;
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 5b61b3eef45..2dd78d20eb0 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -55,7 +55,6 @@ struct lapbethdev {
struct list_head node;
struct net_device *ethdev; /* link to ethernet device */
struct net_device *axdev; /* lapbeth device (lapb#) */
- struct net_device_stats stats; /* some statistics */
};
static LIST_HEAD(lapbeth_devices);
@@ -107,10 +106,9 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
if (!netif_running(lapbeth->axdev))
goto drop_unlock;
- lapbeth->stats.rx_packets++;
-
len = skb->data[0] + skb->data[1] * 256;
- lapbeth->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
skb_pull(skb, 2); /* Remove the length bytes */
skb_trim(skb, len); /* Set the length of the data */
@@ -210,8 +208,8 @@ static void lapbeth_data_transmit(struct net_device *ndev, struct sk_buff *skb)
*ptr++ = size % 256;
*ptr++ = size / 256;
- lapbeth->stats.tx_packets++;
- lapbeth->stats.tx_bytes += size;
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += size;
skb->dev = dev = lapbeth->ethdev;
@@ -255,15 +253,6 @@ static void lapbeth_disconnected(struct net_device *dev, int reason)
}
/*
- * Statistics
- */
-static struct net_device_stats *lapbeth_get_stats(struct net_device *dev)
-{
- struct lapbethdev *lapbeth = netdev_priv(dev);
- return &lapbeth->stats;
-}
-
-/*
* Set AX.25 callsign
*/
static int lapbeth_set_mac_address(struct net_device *dev, void *addr)
@@ -314,14 +303,17 @@ static int lapbeth_close(struct net_device *dev)
/* ------------------------------------------------------------------------ */
+static const struct net_device_ops lapbeth_netdev_ops = {
+ .ndo_open = lapbeth_open,
+ .ndo_stop = lapbeth_close,
+ .ndo_start_xmit = lapbeth_xmit,
+ .ndo_set_mac_address = lapbeth_set_mac_address,
+};
+
static void lapbeth_setup(struct net_device *dev)
{
- dev->hard_start_xmit = lapbeth_xmit;
- dev->open = lapbeth_open;
- dev->stop = lapbeth_close;
+ dev->netdev_ops = &lapbeth_netdev_ops;
dev->destructor = free_netdev;
- dev->set_mac_address = lapbeth_set_mac_address;
- dev->get_stats = lapbeth_get_stats;
dev->type = ARPHRD_X25;
dev->hard_header_len = 3;
dev->mtu = 1000;
@@ -421,8 +413,8 @@ static int lapbeth_device_event(struct notifier_block *this,
/* ------------------------------------------------------------------------ */
-static struct packet_type lapbeth_packet_type = {
- .type = __constant_htons(ETH_P_DEC),
+static struct packet_type lapbeth_packet_type __read_mostly = {
+ .type = cpu_to_be16(ETH_P_DEC),
.func = lapbeth_rcv,
};
@@ -430,7 +422,8 @@ static struct notifier_block lapbeth_dev_notifier = {
.notifier_call = lapbeth_device_event,
};
-static char banner[] __initdata = KERN_INFO "LAPB Ethernet driver version 0.02\n";
+static const char banner[] __initconst =
+ KERN_INFO "LAPB Ethernet driver version 0.02\n";
static int __init lapbeth_init_driver(void)
{
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index feac3b99f8f..45b1822c962 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -806,6 +806,16 @@ static int lmc_attach(struct net_device *dev, unsigned short encoding,
return -EINVAL;
}
+static const struct net_device_ops lmc_ops = {
+ .ndo_open = lmc_open,
+ .ndo_stop = lmc_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = lmc_ioctl,
+ .ndo_tx_timeout = lmc_driver_timeout,
+ .ndo_get_stats = lmc_get_stats,
+};
+
static int __devinit lmc_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -849,11 +859,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
dev->type = ARPHRD_HDLC;
dev_to_hdlc(dev)->xmit = lmc_start_xmit;
dev_to_hdlc(dev)->attach = lmc_attach;
- dev->open = lmc_open;
- dev->stop = lmc_close;
- dev->get_stats = lmc_get_stats;
- dev->do_ioctl = lmc_ioctl;
- dev->tx_timeout = lmc_driver_timeout;
+ dev->netdev_ops = &lmc_ops;
dev->watchdog_timeo = HZ; /* 1 second */
dev->tx_queue_len = 100;
sc->lmc_device = dev;
@@ -1059,9 +1065,6 @@ static int lmc_open(struct net_device *dev)
if ((err = lmc_proto_open(sc)) != 0)
return err;
- dev->do_ioctl = lmc_ioctl;
-
-
netif_start_queue(dev);
sc->extra_stats.tx_tbusy0++;
diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
index 94b4c208b01..044a48175c4 100644
--- a/drivers/net/wan/lmc/lmc_proto.c
+++ b/drivers/net/wan/lmc/lmc_proto.c
@@ -51,30 +51,15 @@
void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
{
lmc_trace(sc->lmc_device, "lmc_proto_attach in");
- switch(sc->if_type){
- case LMC_PPP:
- {
- struct net_device *dev = sc->lmc_device;
- dev->do_ioctl = lmc_ioctl;
- }
- break;
- case LMC_NET:
- {
+ if (sc->if_type == LMC_NET) {
struct net_device *dev = sc->lmc_device;
/*
* They set a few basics because they don't use HDLC
*/
dev->flags |= IFF_POINTOPOINT;
-
dev->hard_header_len = 0;
dev->addr_len = 0;
}
- case LMC_RAW: /* Setup the task queue, maybe we should notify someone? */
- {
- }
- default:
- break;
- }
lmc_trace(sc->lmc_device, "lmc_proto_attach out");
}
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 697715ae80f..83da596e205 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -324,7 +324,13 @@ static void n2_destroy_card(card_t *card)
kfree(card);
}
-
+static const struct net_device_ops n2_ops = {
+ .ndo_open = n2_open,
+ .ndo_stop = n2_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = n2_ioctl,
+};
static int __init n2_run(unsigned long io, unsigned long irq,
unsigned long winbase, long valid0, long valid1)
@@ -460,9 +466,7 @@ static int __init n2_run(unsigned long io, unsigned long irq,
dev->mem_start = winbase;
dev->mem_end = winbase + USE_WINDOWSIZE - 1;
dev->tx_queue_len = 50;
- dev->do_ioctl = n2_ioctl;
- dev->open = n2_open;
- dev->stop = n2_close;
+ dev->netdev_ops = &n2_ops;
hdlc->attach = sca_attach;
hdlc->xmit = sca_xmit;
port->settings.clock_type = CLOCK_EXT;
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
index f247e5d9002..60ece54bdd9 100644
--- a/drivers/net/wan/pc300too.c
+++ b/drivers/net/wan/pc300too.c
@@ -287,7 +287,13 @@ static void pc300_pci_remove_one(struct pci_dev *pdev)
kfree(card);
}
-
+static const struct net_device_ops pc300_ops = {
+ .ndo_open = pc300_open,
+ .ndo_stop = pc300_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = pc300_ioctl,
+};
static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -448,9 +454,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
dev->mem_start = ramphys;
dev->mem_end = ramphys + ramsize - 1;
dev->tx_queue_len = 50;
- dev->do_ioctl = pc300_ioctl;
- dev->open = pc300_open;
- dev->stop = pc300_close;
+ dev->netdev_ops = &pc300_ops;
hdlc->attach = sca_attach;
hdlc->xmit = sca_xmit;
port->settings.clock_type = CLOCK_EXT;
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index 1104d3a692f..e035d8c57e1 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -265,7 +265,13 @@ static void pci200_pci_remove_one(struct pci_dev *pdev)
kfree(card);
}
-
+static const struct net_device_ops pci200_ops = {
+ .ndo_open = pci200_open,
+ .ndo_stop = pci200_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = pci200_ioctl,
+};
static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -395,9 +401,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
dev->mem_start = ramphys;
dev->mem_end = ramphys + ramsize - 1;
dev->tx_queue_len = 50;
- dev->do_ioctl = pci200_ioctl;
- dev->open = pci200_open;
- dev->stop = pci200_close;
+ dev->netdev_ops = &pci200_ops;
hdlc->attach = sca_attach;
hdlc->xmit = sca_xmit;
port->settings.clock_type = CLOCK_EXT;
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 0aa28e1d436..f4211fe0f44 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -68,7 +68,6 @@
/* device private data */
struct net_local {
- struct net_device_stats stats;
struct timer_list watchdog;
spinlock_t lock;
@@ -117,7 +116,6 @@ static int sbni_open( struct net_device * );
static int sbni_close( struct net_device * );
static int sbni_start_xmit( struct sk_buff *, struct net_device * );
static int sbni_ioctl( struct net_device *, struct ifreq *, int );
-static struct net_device_stats *sbni_get_stats( struct net_device * );
static void set_multicast_list( struct net_device * );
static irqreturn_t sbni_interrupt( int, void * );
@@ -208,15 +206,21 @@ sbni_isa_probe( struct net_device *dev )
}
}
+static const struct net_device_ops sbni_netdev_ops = {
+ .ndo_open = sbni_open,
+ .ndo_stop = sbni_close,
+ .ndo_start_xmit = sbni_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_do_ioctl = sbni_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static void __init sbni_devsetup(struct net_device *dev)
{
ether_setup( dev );
- dev->open = &sbni_open;
- dev->stop = &sbni_close;
- dev->hard_start_xmit = &sbni_start_xmit;
- dev->get_stats = &sbni_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &sbni_ioctl;
+ dev->netdev_ops = &sbni_netdev_ops;
}
int __init sbni_probe(int unit)
@@ -229,6 +233,8 @@ int __init sbni_probe(int unit)
if (!dev)
return -ENOMEM;
+ dev->netdev_ops = &sbni_netdev_ops;
+
sprintf(dev->name, "sbni%d", unit);
netdev_boot_setup_check(dev);
@@ -723,13 +729,11 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno,
nl->wait_frameno = 0,
nl->inppos = 0,
#ifdef CONFIG_SBNI_MULTILINE
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.rx_errors++,
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.rx_missed_errors++;
+ nl->master->stats.rx_errors++,
+ nl->master->stats.rx_missed_errors++;
#else
- nl->stats.rx_errors++,
- nl->stats.rx_missed_errors++;
+ dev->stats.rx_errors++,
+ dev->stats.rx_missed_errors++;
#endif
/* now skip all frames until is_first != 0 */
} else
@@ -742,13 +746,11 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno,
*/
nl->wait_frameno = 0,
#ifdef CONFIG_SBNI_MULTILINE
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.rx_errors++,
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.rx_crc_errors++;
+ nl->master->stats.rx_errors++,
+ nl->master->stats.rx_crc_errors++;
#else
- nl->stats.rx_errors++,
- nl->stats.rx_crc_errors++;
+ dev->stats.rx_errors++,
+ dev->stats.rx_crc_errors++;
#endif
return frame_ok;
@@ -756,15 +758,16 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno,
static inline void
-send_complete( struct net_local *nl )
+send_complete( struct net_device *dev )
{
+ struct net_local *nl = netdev_priv(dev);
+
#ifdef CONFIG_SBNI_MULTILINE
- ((struct net_local *)netdev_priv(nl->master))->stats.tx_packets++;
- ((struct net_local *)netdev_priv(nl->master))->stats.tx_bytes
- += nl->tx_buf_p->len;
+ nl->master->stats.tx_packets++;
+ nl->master->stats.tx_bytes += nl->tx_buf_p->len;
#else
- nl->stats.tx_packets++;
- nl->stats.tx_bytes += nl->tx_buf_p->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += nl->tx_buf_p->len;
#endif
dev_kfree_skb_irq( nl->tx_buf_p );
@@ -792,7 +795,7 @@ interpret_ack( struct net_device *dev, unsigned ack )
nl->maxframe,
nl->tx_buf_p->len - nl->outpos);
else
- send_complete( nl ),
+ send_complete( dev ),
#ifdef CONFIG_SBNI_MULTILINE
netif_wake_queue( nl->master );
#else
@@ -881,13 +884,11 @@ drop_xmit_queue( struct net_device *dev )
dev_kfree_skb_any( nl->tx_buf_p ),
nl->tx_buf_p = NULL,
#ifdef CONFIG_SBNI_MULTILINE
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.tx_errors++,
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.tx_carrier_errors++;
+ nl->master->stats.tx_errors++,
+ nl->master->stats.tx_carrier_errors++;
#else
- nl->stats.tx_errors++,
- nl->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++,
+ dev->stats.tx_carrier_errors++;
#endif
nl->tx_frameno = 0;
@@ -1017,14 +1018,13 @@ indicate_pkt( struct net_device *dev )
#ifdef CONFIG_SBNI_MULTILINE
skb->protocol = eth_type_trans( skb, nl->master );
netif_rx( skb );
- ++((struct net_local *)netdev_priv(nl->master))->stats.rx_packets;
- ((struct net_local *)netdev_priv(nl->master))->stats.rx_bytes +=
- nl->inppos;
+ ++nl->master->stats.rx_packets;
+ nl->master->stats.rx_bytes += nl->inppos;
#else
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
- ++nl->stats.rx_packets;
- nl->stats.rx_bytes += nl->inppos;
+ ++dev->stats.rx_packets;
+ dev->stats.rx_bytes += nl->inppos;
#endif
nl->rx_buf_p = NULL; /* protocol driver will clear this sk_buff */
}
@@ -1197,7 +1197,7 @@ sbni_open( struct net_device *dev )
handler_attached:
spin_lock( &nl->lock );
- memset( &nl->stats, 0, sizeof(struct net_device_stats) );
+ memset( &dev->stats, 0, sizeof(struct net_device_stats) );
memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
card_start( dev );
@@ -1413,7 +1413,7 @@ enslave( struct net_device *dev, struct net_device *slave_dev )
/* Summary statistics of MultiLine operation will be stored
in master's counters */
- memset( &snl->stats, 0, sizeof(struct net_device_stats) );
+ memset( &slave_dev->stats, 0, sizeof(struct net_device_stats) );
netif_stop_queue( slave_dev );
netif_wake_queue( dev ); /* Now we are able to transmit */
@@ -1464,14 +1464,6 @@ emancipate( struct net_device *dev )
#endif
-
-static struct net_device_stats *
-sbni_get_stats( struct net_device *dev )
-{
- return &((struct net_local *)netdev_priv(dev))->stats;
-}
-
-
static void
set_multicast_list( struct net_device *dev )
{
@@ -1520,17 +1512,18 @@ int __init init_module( void )
}
void
-cleanup_module( void )
+cleanup_module(void)
{
- struct net_device *dev;
- int num;
+ int i;
- for( num = 0; num < SBNI_MAX_NUM_CARDS; ++num )
- if( (dev = sbni_cards[ num ]) != NULL ) {
- unregister_netdev( dev );
- release_region( dev->base_addr, SBNI_IO_EXTENT );
- free_netdev( dev );
+ for (i = 0; i < SBNI_MAX_NUM_CARDS; ++i) {
+ struct net_device *dev = sbni_cards[i];
+ if (dev != NULL) {
+ unregister_netdev(dev);
+ release_region(dev->base_addr, SBNI_IO_EXTENT);
+ free_netdev(dev);
}
+ }
}
#else /* MODULE */
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 0941a26f6e3..23b26902745 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -169,6 +169,14 @@ static int sealevel_attach(struct net_device *dev, unsigned short encoding,
return -EINVAL;
}
+static const struct net_device_ops sealevel_ops = {
+ .ndo_open = sealevel_open,
+ .ndo_stop = sealevel_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = sealevel_ioctl,
+};
+
static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
{
struct net_device *dev = alloc_hdlcdev(sv);
@@ -177,9 +185,7 @@ static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
dev_to_hdlc(dev)->attach = sealevel_attach;
dev_to_hdlc(dev)->xmit = sealevel_queue_xmit;
- dev->open = sealevel_open;
- dev->stop = sealevel_close;
- dev->do_ioctl = sealevel_ioctl;
+ dev->netdev_ops = &sealevel_ops;
dev->base_addr = iobase;
dev->irq = irq;
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index 4bffb67ebca..887acb0dc80 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -547,6 +547,15 @@ static void wanxl_pci_remove_one(struct pci_dev *pdev)
#include "wanxlfw.inc"
+static const struct net_device_ops wanxl_ops = {
+ .ndo_open = wanxl_open,
+ .ndo_stop = wanxl_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = wanxl_ioctl,
+ .ndo_get_stats = wanxl_get_stats,
+};
+
static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -777,12 +786,9 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
hdlc = dev_to_hdlc(dev);
spin_lock_init(&port->lock);
dev->tx_queue_len = 50;
- dev->do_ioctl = wanxl_ioctl;
- dev->open = wanxl_open;
- dev->stop = wanxl_close;
+ dev->netdev_ops = &wanxl_ops;
hdlc->attach = wanxl_attach;
hdlc->xmit = wanxl_xmit;
- dev->get_stats = wanxl_get_stats;
port->card = card;
port->node = i;
get_status(port)->clocking = CLOCK_EXT;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index e6e2ce3e7bc..d67e208ab37 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -142,7 +142,7 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
memcpy(sl->xbuff, sl->xhead, sl->xleft);
} else {
sl->xleft = 0;
- sl->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
sl->xhead = sl->xbuff;
@@ -153,7 +153,7 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
memcpy(sl->rbuff, rbuff, sl->rcount);
} else {
sl->rcount = 0;
- sl->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
@@ -188,18 +188,19 @@ static inline void x25_asy_unlock(struct x25_asy *sl)
static void x25_asy_bump(struct x25_asy *sl)
{
+ struct net_device *dev = sl->dev;
struct sk_buff *skb;
int count;
int err;
count = sl->rcount;
- sl->stats.rx_bytes += count;
+ dev->stats.rx_bytes += count;
skb = dev_alloc_skb(count+1);
if (skb == NULL) {
printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n",
sl->dev->name);
- sl->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_push(skb, 1); /* LAPB internal control */
@@ -211,7 +212,7 @@ static void x25_asy_bump(struct x25_asy *sl)
printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
} else {
netif_rx(skb);
- sl->stats.rx_packets++;
+ dev->stats.rx_packets++;
}
}
@@ -226,7 +227,7 @@ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
len = mtu;
printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n",
sl->dev->name);
- sl->stats.tx_dropped++;
+ sl->dev->stats.tx_dropped++;
x25_asy_unlock(sl);
return;
}
@@ -266,7 +267,7 @@ static void x25_asy_write_wakeup(struct tty_struct *tty)
if (sl->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
- sl->stats.tx_packets++;
+ sl->dev->stats.tx_packets++;
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
x25_asy_unlock(sl);
return;
@@ -383,7 +384,7 @@ static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
/* We were not busy, so we are now... :-) */
if (skb != NULL) {
x25_asy_lock(sl);
- sl->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
x25_asy_encaps(sl, skb->data, skb->len);
dev_kfree_skb(skb);
}
@@ -533,7 +534,7 @@ static void x25_asy_receive_buf(struct tty_struct *tty,
while (count--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
- sl->stats.rx_errors++;
+ sl->dev->stats.rx_errors++;
cp++;
continue;
}
@@ -608,14 +609,6 @@ static void x25_asy_close_tty(struct tty_struct *tty)
x25_asy_free(sl);
}
-
-static struct net_device_stats *x25_asy_get_stats(struct net_device *dev)
-{
- struct x25_asy *sl = netdev_priv(dev);
- return &sl->stats;
-}
-
-
/************************************************************************
* STANDARD X.25 ENCAPSULATION *
************************************************************************/
@@ -682,7 +675,7 @@ static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
sl->rbuff[sl->rcount++] = s;
return;
}
- sl->stats.rx_over_errors++;
+ sl->dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
@@ -719,6 +712,14 @@ static int x25_asy_open_dev(struct net_device *dev)
return 0;
}
+static const struct net_device_ops x25_asy_netdev_ops = {
+ .ndo_open = x25_asy_open_dev,
+ .ndo_stop = x25_asy_close,
+ .ndo_start_xmit = x25_asy_xmit,
+ .ndo_tx_timeout = x25_asy_timeout,
+ .ndo_change_mtu = x25_asy_change_mtu,
+};
+
/* Initialise the X.25 driver. Called by the device init code */
static void x25_asy_setup(struct net_device *dev)
{
@@ -734,13 +735,8 @@ static void x25_asy_setup(struct net_device *dev)
*/
dev->mtu = SL_MTU;
- dev->hard_start_xmit = x25_asy_xmit;
- dev->tx_timeout = x25_asy_timeout;
+ dev->netdev_ops = &x25_asy_netdev_ops;
dev->watchdog_timeo = HZ*20;
- dev->open = x25_asy_open_dev;
- dev->stop = x25_asy_close;
- dev->get_stats = x25_asy_get_stats;
- dev->change_mtu = x25_asy_change_mtu;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->type = ARPHRD_X25;
diff --git a/drivers/net/wan/x25_asy.h b/drivers/net/wan/x25_asy.h
index 41770200ceb..8f0fc2e57e2 100644
--- a/drivers/net/wan/x25_asy.h
+++ b/drivers/net/wan/x25_asy.h
@@ -28,10 +28,6 @@ struct x25_asy {
unsigned char *xbuff; /* transmitter buffer */
unsigned char *xhead; /* pointer to next byte to XMIT */
int xleft; /* bytes left in XMIT queue */
-
- /* X.25 interface statistics. */
- struct net_device_stats stats;
-
int buffsize; /* Max buffers sizes */
unsigned long flags; /* Flag values/ mode etc */
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 3d00971fe5e..ad4e79c4c5c 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -1775,7 +1775,8 @@ EXPORT_SYMBOL(z8530_queue_xmit);
/*
* Module support
*/
-static char banner[] __initdata = KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
+static const char banner[] __initdata =
+ KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
static int __init z85230_init_driver(void)
{
diff --git a/drivers/net/wimax/i2400m/Makefile b/drivers/net/wimax/i2400m/Makefile
index 1696e936cf5..5d9e018d31a 100644
--- a/drivers/net/wimax/i2400m/Makefile
+++ b/drivers/net/wimax/i2400m/Makefile
@@ -8,6 +8,7 @@ i2400m-y := \
driver.o \
fw.o \
op-rfkill.o \
+ sysfs.o \
netdev.o \
tx.o \
rx.o
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index d3d37fed689..b3cadb626fe 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -52,7 +52,6 @@
*
* i2400m_dev_initalize() Called by i2400m_dev_start()
* i2400m_set_init_config()
- * i2400m_firmware_check()
* i2400m_cmd_get_state()
* i2400m_dev_shutdown() Called by i2400m_dev_stop()
* i2400m->bus_reset()
@@ -609,7 +608,7 @@ void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code)
spin_lock_irqsave(&i2400m->rx_lock, flags);
ack_skb = i2400m->ack_skb;
if (ack_skb && !IS_ERR(ack_skb))
- kfree(ack_skb);
+ kfree_skb(ack_skb);
i2400m->ack_skb = ERR_PTR(code);
spin_unlock_irqrestore(&i2400m->rx_lock, flags);
}
@@ -942,8 +941,8 @@ error_cmd_failed:
/* Firmware interface versions we support */
enum {
I2400M_HDIv_MAJOR = 9,
- I2400M_HDIv_MAJOR_2 = 8,
I2400M_HDIv_MINOR = 1,
+ I2400M_HDIv_MINOR_2 = 2,
};
@@ -959,6 +958,10 @@ enum {
* Long function, but quite simple; first chunk launches the command
* and double checks the reply for the right TLV. Then we process the
* TLV (where the meat is).
+ *
+ * Once we process the TLV that gives us the firmware's interface
+ * version, we encode it and save it in i2400m->fw_version for future
+ * reference.
*/
int i2400m_firmware_check(struct i2400m *i2400m)
{
@@ -1009,22 +1012,20 @@ int i2400m_firmware_check(struct i2400m *i2400m)
minor = le16_to_cpu(l4mv->minor);
branch = le16_to_cpu(l4mv->branch);
result = -EINVAL;
- if (major != I2400M_HDIv_MAJOR
- && major != I2400M_HDIv_MAJOR_2) {
- dev_err(dev, "unsupported major fw interface version "
+ if (major != I2400M_HDIv_MAJOR) {
+ dev_err(dev, "unsupported major fw version "
"%u.%u.%u\n", major, minor, branch);
goto error_bad_major;
}
- if (major == I2400M_HDIv_MAJOR_2)
- dev_err(dev, "deprecated major fw interface version "
- "%u.%u.%u\n", major, minor, branch);
result = 0;
- if (minor != I2400M_HDIv_MINOR)
- dev_warn(dev, "untested minor fw firmware version %u.%u.%u\n",
+ if (minor < I2400M_HDIv_MINOR_2 && minor > I2400M_HDIv_MINOR)
+ dev_warn(dev, "untested minor fw version %u.%u.%u\n",
major, minor, branch);
-error_bad_major:
+ /* Yes, we ignore the branch -- we don't have to track it */
+ i2400m->fw_version = major << 16 | minor;
dev_info(dev, "firmware interface version %u.%u.%u\n",
major, minor, branch);
+error_bad_major:
error_no_tlv:
error_cmd_failed:
kfree_skb(ack_skb);
@@ -1221,6 +1222,77 @@ EXPORT_SYMBOL_GPL(i2400m_set_init_config);
/**
+ * i2400m_set_idle_timeout - Set the device's idle mode timeout
+ *
+ * @i2400m: i2400m device descriptor
+ *
+ * @msecs: milliseconds for the timeout to enter idle mode. Between
+ * 100 to 300000 (5m); 0 to disable. In increments of 100.
+ *
+ * After this @msecs of the link being idle (no data being sent or
+ * received), the device will negotiate with the basestation entering
+ * idle mode for saving power. The connection is maintained, but
+ * getting out of it (done in tx.c) will require some negotiation,
+ * possible crypto re-handshake and a possible DHCP re-lease.
+ *
+ * Only available if fw_version >= 0x00090002.
+ *
+ * Returns: 0 if ok, < 0 errno code on error.
+ */
+int i2400m_set_idle_timeout(struct i2400m *i2400m, unsigned msecs)
+{
+ int result;
+ struct device *dev = i2400m_dev(i2400m);
+ struct sk_buff *ack_skb;
+ struct {
+ struct i2400m_l3l4_hdr hdr;
+ struct i2400m_tlv_config_idle_timeout cit;
+ } *cmd;
+ const struct i2400m_l3l4_hdr *ack;
+ size_t ack_len;
+ char strerr[32];
+
+ result = -ENOSYS;
+ if (i2400m_le_v1_3(i2400m))
+ goto error_alloc;
+ result = -ENOMEM;
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ goto error_alloc;
+ cmd->hdr.type = cpu_to_le16(I2400M_MT_GET_STATE);
+ cmd->hdr.length = cpu_to_le16(sizeof(*cmd) - sizeof(cmd->hdr));
+ cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION);
+
+ cmd->cit.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT);
+ cmd->cit.hdr.length = cpu_to_le16(sizeof(cmd->cit.timeout));
+ cmd->cit.timeout = cpu_to_le32(msecs);
+
+ ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd));
+ if (IS_ERR(ack_skb)) {
+ dev_err(dev, "Failed to issue 'set idle timeout' command: "
+ "%ld\n", PTR_ERR(ack_skb));
+ result = PTR_ERR(ack_skb);
+ goto error_msg_to_dev;
+ }
+ ack = wimax_msg_data_len(ack_skb, &ack_len);
+ result = i2400m_msg_check_status(ack, strerr, sizeof(strerr));
+ if (result < 0) {
+ dev_err(dev, "'set idle timeout' (0x%04x) command failed: "
+ "%d - %s\n", I2400M_MT_GET_STATE, result, strerr);
+ goto error_cmd_failed;
+ }
+ result = 0;
+ kfree_skb(ack_skb);
+error_cmd_failed:
+error_msg_to_dev:
+ kfree(cmd);
+error_alloc:
+ return result;
+}
+
+
+/**
* i2400m_dev_initialize - Initialize the device once communications are ready
*
* @i2400m: device descriptor
@@ -1238,26 +1310,55 @@ int i2400m_dev_initialize(struct i2400m *i2400m)
int result;
struct device *dev = i2400m_dev(i2400m);
struct i2400m_tlv_config_idle_parameters idle_params;
+ struct i2400m_tlv_config_idle_timeout idle_timeout;
+ struct i2400m_tlv_config_d2h_data_format df;
+ struct i2400m_tlv_config_dl_host_reorder dlhr;
const struct i2400m_tlv_hdr *args[9];
unsigned argc = 0;
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
- /* Useless for now...might change */
+ /* Disable idle mode? (enabled by default) */
if (i2400m_idle_mode_disabled) {
- idle_params.hdr.type =
- cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS);
- idle_params.hdr.length = cpu_to_le16(
- sizeof(idle_params) - sizeof(idle_params.hdr));
- idle_params.idle_timeout = 0;
- idle_params.idle_paging_interval = 0;
- args[argc++] = &idle_params.hdr;
+ if (i2400m_le_v1_3(i2400m)) {
+ idle_params.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS);
+ idle_params.hdr.length = cpu_to_le16(
+ sizeof(idle_params) - sizeof(idle_params.hdr));
+ idle_params.idle_timeout = 0;
+ idle_params.idle_paging_interval = 0;
+ args[argc++] = &idle_params.hdr;
+ } else {
+ idle_timeout.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT);
+ idle_timeout.hdr.length = cpu_to_le16(
+ sizeof(idle_timeout) - sizeof(idle_timeout.hdr));
+ idle_timeout.timeout = 0;
+ args[argc++] = &idle_timeout.hdr;
+ }
+ }
+ if (i2400m_ge_v1_4(i2400m)) {
+ /* Enable extended RX data format? */
+ df.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_D2H_DATA_FORMAT);
+ df.hdr.length = cpu_to_le16(
+ sizeof(df) - sizeof(df.hdr));
+ df.format = 1;
+ args[argc++] = &df.hdr;
+
+ /* Enable RX data reordering?
+ * (switch flipped in rx.c:i2400m_rx_setup() after fw upload) */
+ if (i2400m->rx_reorder) {
+ dlhr.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_DL_HOST_REORDER);
+ dlhr.hdr.length = cpu_to_le16(
+ sizeof(dlhr) - sizeof(dlhr.hdr));
+ dlhr.reorder = 1;
+ args[argc++] = &dlhr.hdr;
+ }
}
result = i2400m_set_init_config(i2400m, args, argc);
if (result < 0)
goto error;
- result = i2400m_firmware_check(i2400m); /* fw versions ok? */
- if (result < 0)
- goto error;
/*
* Update state: Here it just calls a get state; parsing the
* result (System State TLV and RF Status TLV [done in the rx
@@ -1266,6 +1367,8 @@ int i2400m_dev_initialize(struct i2400m *i2400m)
*/
result = i2400m_cmd_get_state(i2400m);
error:
+ if (result < 0)
+ dev_err(dev, "failed to initialize the device: %d\n", result);
d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
return result;
}
diff --git a/drivers/net/wimax/i2400m/debug-levels.h b/drivers/net/wimax/i2400m/debug-levels.h
index 3183baa16a5..48fbfaa0d40 100644
--- a/drivers/net/wimax/i2400m/debug-levels.h
+++ b/drivers/net/wimax/i2400m/debug-levels.h
@@ -38,6 +38,7 @@ enum d_module {
D_SUBMODULE_DECLARE(netdev),
D_SUBMODULE_DECLARE(rfkill),
D_SUBMODULE_DECLARE(rx),
+ D_SUBMODULE_DECLARE(sysfs),
D_SUBMODULE_DECLARE(tx),
};
diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c
index 62663298597..9b81af3f80a 100644
--- a/drivers/net/wimax/i2400m/debugfs.c
+++ b/drivers/net/wimax/i2400m/debugfs.c
@@ -234,20 +234,6 @@ struct dentry *debugfs_create_i2400m_reset(
&fops_i2400m_reset);
}
-/*
- * Debug levels control; see debug.h
- */
-struct d_level D_LEVEL[] = {
- D_SUBMODULE_DEFINE(control),
- D_SUBMODULE_DEFINE(driver),
- D_SUBMODULE_DEFINE(debugfs),
- D_SUBMODULE_DEFINE(fw),
- D_SUBMODULE_DEFINE(netdev),
- D_SUBMODULE_DEFINE(rfkill),
- D_SUBMODULE_DEFINE(rx),
- D_SUBMODULE_DEFINE(tx),
-};
-size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
#define __debugfs_register(prefix, name, parent) \
do { \
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 5f98047e18c..07a54bad237 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -48,6 +48,7 @@
* i2400m_dev_bootstrap()
* i2400m_tx_setup()
* i2400m->bus_dev_start()
+ * i2400m_firmware_check()
* i2400m_check_mac_addr()
* wimax_dev_add()
*
@@ -75,6 +76,11 @@ MODULE_PARM_DESC(idle_mode_disabled,
"If true, the device will not enable idle mode negotiation "
"with the base station (when connected) to save power.");
+int i2400m_rx_reorder_disabled; /* 0 (rx reorder enabled) by default */
+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.");
+
/**
* i2400m_queue_work - schedule work on a i2400m's queue
*
@@ -395,6 +401,9 @@ retry:
result = i2400m_tx_setup(i2400m);
if (result < 0)
goto error_tx_setup;
+ 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;
@@ -404,6 +413,9 @@ retry:
dev_err(dev, "cannot create workqueue\n");
goto error_create_workqueue;
}
+ result = i2400m_firmware_check(i2400m); /* fw versions ok? */
+ if (result < 0)
+ goto error_fw_check;
/* At this point is ok to send commands to the device */
result = i2400m_check_mac_addr(i2400m);
if (result < 0)
@@ -421,10 +433,13 @@ 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:
+ i2400m_rx_release(i2400m);
+error_rx_setup:
i2400m_tx_release(i2400m);
error_tx_setup:
error_bootstrap:
@@ -472,6 +487,7 @@ void __i2400m_dev_stop(struct i2400m *i2400m)
i2400m->ready = 0;
destroy_workqueue(i2400m->work_queue);
i2400m->bus_dev_stop(i2400m);
+ i2400m_rx_release(i2400m);
i2400m_tx_release(i2400m);
wimax_state_change(wimax_dev, WIMAX_ST_DOWN);
d_fnend(3, dev, "(i2400m %p) = 0\n", i2400m);
@@ -613,7 +629,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
snprintf(wimax_dev->name, sizeof(wimax_dev->name),
- "i2400m-%s:%s", dev->bus->name, dev->bus_id);
+ "i2400m-%s:%s", dev->bus->name, dev_name(dev));
i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
if (i2400m->bm_cmd_buf == NULL) {
@@ -657,6 +673,11 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED);
/* Now setup all that requires a registered net and wimax device. */
+ result = sysfs_create_group(&net_dev->dev.kobj, &i2400m_dev_attr_group);
+ if (result < 0) {
+ dev_err(dev, "cannot setup i2400m's sysfs: %d\n", result);
+ goto error_sysfs_setup;
+ }
result = i2400m_debugfs_add(i2400m);
if (result < 0) {
dev_err(dev, "cannot setup i2400m's debugfs: %d\n", result);
@@ -666,6 +687,9 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
return result;
error_debugfs_setup:
+ sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
+ &i2400m_dev_attr_group);
+error_sysfs_setup:
wimax_dev_rm(&i2400m->wimax_dev);
error_wimax_dev_add:
i2400m_dev_stop(i2400m);
@@ -697,6 +721,8 @@ void i2400m_release(struct i2400m *i2400m)
netif_stop_queue(i2400m->wimax_dev.net_dev);
i2400m_debugfs_rm(i2400m);
+ sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
+ &i2400m_dev_attr_group);
wimax_dev_rm(&i2400m->wimax_dev);
i2400m_dev_stop(i2400m);
unregister_netdev(i2400m->wimax_dev.net_dev);
@@ -707,6 +733,22 @@ void i2400m_release(struct i2400m *i2400m)
EXPORT_SYMBOL_GPL(i2400m_release);
+/*
+ * Debug levels control; see debug.h
+ */
+struct d_level D_LEVEL[] = {
+ D_SUBMODULE_DEFINE(control),
+ D_SUBMODULE_DEFINE(driver),
+ D_SUBMODULE_DEFINE(debugfs),
+ D_SUBMODULE_DEFINE(fw),
+ D_SUBMODULE_DEFINE(netdev),
+ D_SUBMODULE_DEFINE(rfkill),
+ D_SUBMODULE_DEFINE(rx),
+ D_SUBMODULE_DEFINE(tx),
+};
+size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
+
+
static
int __init i2400m_driver_init(void)
{
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c
index 1d8271f34c3..675c6ce810c 100644
--- a/drivers/net/wimax/i2400m/fw.c
+++ b/drivers/net/wimax/i2400m/fw.c
@@ -140,10 +140,10 @@
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)
+ cpu_to_le32(I2400M_ACK_BARKER),
+ cpu_to_le32(I2400M_ACK_BARKER),
+ cpu_to_le32(I2400M_ACK_BARKER),
+ cpu_to_le32(I2400M_ACK_BARKER)
};
@@ -483,7 +483,7 @@ ssize_t i2400m_dnload_bcf(struct i2400m *i2400m,
if (offset + section_size > bcf_len) {
dev_err(dev, "fw %s: bad section #%zu, "
"end (@%zu) beyond EOF (@%zu)\n",
- i2400m->bus_fw_name, section,
+ i2400m->fw_name, section,
offset + section_size, bcf_len);
ret = -EINVAL;
goto error_section_beyond_eof;
@@ -493,7 +493,7 @@ ssize_t i2400m_dnload_bcf(struct i2400m *i2400m,
&ack, sizeof(ack), I2400M_BM_CMD_RAW);
if (ret < 0) {
dev_err(dev, "fw %s: section #%zu (@%zu %zu B) "
- "failed %d\n", i2400m->bus_fw_name, section,
+ "failed %d\n", i2400m->fw_name, section,
offset, sizeof(*bh) + data_size, (int) ret);
goto error_send;
}
@@ -771,8 +771,8 @@ static
int i2400m_dnload_init_nonsigned(struct i2400m *i2400m)
{
#define POKE(a, d) { \
- .address = __constant_cpu_to_le32(a), \
- .data = __constant_cpu_to_le32(d) \
+ .address = cpu_to_le32(a), \
+ .data = cpu_to_le32(d) \
}
static const struct {
__le32 address;
@@ -874,7 +874,7 @@ int i2400m_dnload_init(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf)
if (result < 0)
dev_err(dev, "fw %s: non-signed download "
"initialization failed: %d\n",
- i2400m->bus_fw_name, result);
+ i2400m->fw_name, result);
} else if (i2400m->sboot == 0
&& (module_id & I2400M_BCF_MOD_ID_POKES)) {
/* non-signed boot process with pokes, nothing to do */
@@ -886,7 +886,7 @@ int i2400m_dnload_init(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf)
if (result < 0)
dev_err(dev, "fw %s: signed boot download "
"initialization failed: %d\n",
- i2400m->bus_fw_name, result);
+ i2400m->fw_name, result);
}
return result;
}
@@ -915,7 +915,7 @@ int i2400m_fw_check(struct i2400m *i2400m,
if (bcf_size < sizeof(*bcf)) { /* big enough header? */
dev_err(dev, "firmware %s too short: "
"%zu B vs %zu (at least) expected\n",
- i2400m->bus_fw_name, bcf_size, sizeof(*bcf));
+ i2400m->fw_name, bcf_size, sizeof(*bcf));
goto error;
}
@@ -931,7 +931,7 @@ int i2400m_fw_check(struct i2400m *i2400m,
if (bcf_size != size) { /* annoyingly paranoid */
dev_err(dev, "firmware %s: bad size, got "
"%zu B vs %u expected\n",
- i2400m->bus_fw_name, bcf_size, size);
+ i2400m->fw_name, bcf_size, size);
goto error;
}
@@ -943,7 +943,7 @@ int i2400m_fw_check(struct i2400m *i2400m,
if (module_type != 6) { /* built for the right hardware? */
dev_err(dev, "bad fw %s: unexpected module type 0x%x; "
- "aborting\n", i2400m->bus_fw_name, module_type);
+ "aborting\n", i2400m->fw_name, module_type);
goto error;
}
@@ -951,10 +951,10 @@ int i2400m_fw_check(struct i2400m *i2400m,
result = 0;
if (module_vendor != 0x8086)
dev_err(dev, "bad fw %s? unexpected vendor 0x%04x\n",
- i2400m->bus_fw_name, module_vendor);
+ i2400m->fw_name, module_vendor);
if (date < 0x20080300)
dev_err(dev, "bad fw %s? build date too old %08x\n",
- i2400m->bus_fw_name, date);
+ i2400m->fw_name, date);
error:
return result;
}
@@ -1016,7 +1016,7 @@ hw_reboot:
goto error_dev_rebooted;
if (ret < 0) {
dev_err(dev, "fw %s: download failed: %d\n",
- i2400m->bus_fw_name, ret);
+ i2400m->fw_name, ret);
goto error_dnload_bcf;
}
@@ -1026,12 +1026,12 @@ hw_reboot:
if (ret < 0) {
dev_err(dev, "fw %s: "
"download finalization failed: %d\n",
- i2400m->bus_fw_name, ret);
+ i2400m->fw_name, ret);
goto error_dnload_finalize;
}
d_printf(2, dev, "fw %s successfully uploaded\n",
- i2400m->bus_fw_name);
+ i2400m->fw_name);
i2400m->boot_mode = 0;
error_dnload_finalize:
error_dnload_bcf:
@@ -1067,28 +1067,41 @@ error_dev_rebooted:
*/
int i2400m_dev_bootstrap(struct i2400m *i2400m, enum i2400m_bri flags)
{
- int ret = 0;
+ int ret = 0, itr = 0;
struct device *dev = i2400m_dev(i2400m);
const struct firmware *fw;
const struct i2400m_bcf_hdr *bcf; /* Firmware data */
+ const char *fw_name;
d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
+
/* Load firmware files to memory. */
- ret = request_firmware(&fw, i2400m->bus_fw_name, dev);
- if (ret) {
- dev_err(dev, "fw %s: request failed: %d\n",
- i2400m->bus_fw_name, ret);
- goto error_fw_req;
+ itr = 0;
+ while(1) {
+ fw_name = i2400m->bus_fw_names[itr];
+ if (fw_name == NULL) {
+ dev_err(dev, "Could not find a usable firmware image\n");
+ ret = -ENOENT;
+ goto error_no_fw;
+ }
+ ret = request_firmware(&fw, fw_name, dev);
+ if (ret == 0)
+ break; /* got it */
+ if (ret < 0)
+ dev_err(dev, "fw %s: cannot load file: %d\n",
+ fw_name, ret);
+ itr++;
}
- bcf = (void *) fw->data;
+ bcf = (void *) fw->data;
+ i2400m->fw_name = fw_name;
ret = i2400m_fw_check(i2400m, bcf, fw->size);
if (ret < 0)
goto error_fw_bad;
ret = i2400m_fw_dnload(i2400m, bcf, fw->size, flags);
error_fw_bad:
release_firmware(fw);
-error_fw_req:
+error_no_fw:
d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
return ret;
}
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 067c871cc22..3ae2df38b59 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -156,10 +156,6 @@ enum {
};
-/* Firmware version we request when pulling the fw image file */
-#define I2400M_FW_VERSION "1.3"
-
-
/**
* i2400m_reset_type - methods to reset a device
*
@@ -178,6 +174,7 @@ enum i2400m_reset_type {
};
struct i2400m_reset_ctx;
+struct i2400m_roq;
/**
* struct i2400m - descriptor for an Intel 2400m
@@ -242,10 +239,14 @@ struct i2400m_reset_ctx;
* The caller to this function will check if the response is a
* barker that indicates the device going into reset mode.
*
- * @bus_fw_name: [fill] name of the firmware image (in most cases,
- * they are all the same for a single release, except that they
- * have the type of the bus embedded in the name (eg:
- * i2400m-fw-X-VERSION.sbcf, where X is the bus name).
+ * @bus_fw_names: [fill] a NULL-terminated array with the names of the
+ * firmware images to try loading. This is made a list so we can
+ * support backward compatibility of firmware releases (eg: if we
+ * can't find the default v1.4, we try v1.3). In general, the name
+ * should be i2400m-fw-X-VERSION.sbcf, where X is the bus name.
+ * The list is tried in order and the first one that loads is
+ * used. The fw loader will set i2400m->fw_name to point to the
+ * active firmware image.
*
* @bus_bm_mac_addr_impaired: [fill] Set to true if the device's MAC
* address provided in boot mode is kind of broken and needs to
@@ -257,6 +258,9 @@ struct i2400m_reset_ctx;
* force this to be the first field so that we can get from
* netdev_priv() the right pointer.
*
+ * @rx_reorder: 1 if RX reordering is enabled; this can only be
+ * set at probe time.
+ *
* @state: device's state (as reported by it)
*
* @state_wq: waitqueue that is woken up whenever the state changes
@@ -313,6 +317,12 @@ struct i2400m_reset_ctx;
*
* @rx_size_max: buggest RX message received.
*
+ * @rx_roq: RX ReOrder queues. (fw >= v1.4) When packets are received
+ * out of order, the device will ask the driver to hold certain
+ * packets until the ones that are received out of order can be
+ * delivered. Then the driver can release them to the host. See
+ * drivers/net/i2400m/rx.c for details.
+ *
* @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
@@ -364,6 +374,11 @@ struct i2400m_reset_ctx;
* These have to be in a separate directory, a child of
* (wimax_dev->debugfs_dentry) so they can be removed when the
* module unloads, as we don't keep each dentry.
+ *
+ * @fw_name: name of the firmware image that is currently being used.
+ *
+ * @fw_version: version of the firmware interface, Major.minor,
+ * encoded in the high word and low word (major << 16 | minor).
*/
struct i2400m {
struct wimax_dev wimax_dev; /* FIRST! See doc */
@@ -372,6 +387,7 @@ struct i2400m {
unsigned boot_mode:1; /* is the device in boot mode? */
unsigned sboot:1; /* signed or unsigned fw boot */
unsigned ready:1; /* all probing steps done */
+ unsigned rx_reorder:1; /* RX reorder is enabled */
u8 trace_msg_from_user; /* echo rx msgs to 'trace' pipe */
/* typed u8 so debugfs/u8 can tweak */
enum i2400m_system_state state;
@@ -388,7 +404,7 @@ struct i2400m {
size_t, int flags);
ssize_t (*bus_bm_wait_for_ack)(struct i2400m *,
struct i2400m_bootrom_header *, size_t);
- const char *bus_fw_name;
+ const char **bus_fw_names;
unsigned bus_bm_mac_addr_impaired:1;
spinlock_t tx_lock; /* protect TX state */
@@ -400,10 +416,11 @@ struct i2400m {
unsigned tx_pl_num, tx_pl_max, tx_pl_min,
tx_num, tx_size_acc, tx_size_min, tx_size_max;
- /* RX stats */
+ /* RX stuff */
spinlock_t rx_lock; /* protect RX state */
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! */
struct mutex msg_mutex; /* serialize command execution */
struct completion msg_completion;
@@ -421,6 +438,8 @@ struct i2400m {
struct sk_buff *wake_tx_skb;
struct dentry *debugfs_dentry;
+ const char *fw_name; /* name of the current firmware image */
+ unsigned long fw_version; /* version of the firmware interface */
};
@@ -435,6 +454,7 @@ void i2400m_init(struct i2400m *i2400m)
wimax_dev_init(&i2400m->wimax_dev);
i2400m->boot_mode = 1;
+ i2400m->rx_reorder = 1;
init_waitqueue_head(&i2400m->state_wq);
spin_lock_init(&i2400m->tx_lock);
@@ -578,12 +598,19 @@ unsigned i2400m_brh_get_signature(const struct i2400m_bootrom_header *hdr)
* Driver / device setup and internal functions
*/
extern void i2400m_netdev_setup(struct net_device *net_dev);
+extern int i2400m_sysfs_setup(struct device_driver *);
+extern void i2400m_sysfs_release(struct device_driver *);
extern int i2400m_tx_setup(struct i2400m *);
extern void i2400m_wake_tx_work(struct work_struct *);
extern void i2400m_tx_release(struct i2400m *);
+extern int i2400m_rx_setup(struct i2400m *);
+extern void i2400m_rx_release(struct i2400m *);
+
extern void i2400m_net_rx(struct i2400m *, struct sk_buff *, unsigned,
const void *, int);
+extern void i2400m_net_erx(struct i2400m *, struct sk_buff *,
+ enum i2400m_cs);
enum i2400m_pt;
extern int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt);
@@ -664,17 +691,17 @@ extern struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *, size_t *);
extern void i2400m_tx_msg_sent(struct i2400m *);
static const __le32 i2400m_NBOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_NBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_NBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_NBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_NBOOT_BARKER)
+ cpu_to_le32(I2400M_NBOOT_BARKER),
+ cpu_to_le32(I2400M_NBOOT_BARKER),
+ cpu_to_le32(I2400M_NBOOT_BARKER),
+ cpu_to_le32(I2400M_NBOOT_BARKER)
};
static const __le32 i2400m_SBOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_SBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_SBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_SBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_SBOOT_BARKER)
+ cpu_to_le32(I2400M_SBOOT_BARKER),
+ cpu_to_le32(I2400M_SBOOT_BARKER),
+ cpu_to_le32(I2400M_SBOOT_BARKER),
+ cpu_to_le32(I2400M_SBOOT_BARKER)
};
@@ -721,6 +748,7 @@ extern struct sk_buff *i2400m_get_device_info(struct i2400m *);
extern int i2400m_firmware_check(struct i2400m *);
extern int i2400m_set_init_config(struct i2400m *,
const struct i2400m_tlv_hdr **, size_t);
+extern int i2400m_set_idle_timeout(struct i2400m *, unsigned);
static inline
struct usb_endpoint_descriptor *usb_get_epd(struct usb_interface *iface, int ep)
@@ -733,6 +761,32 @@ extern int i2400m_op_rfkill_sw_toggle(struct wimax_dev *,
extern void i2400m_report_tlv_rf_switches_status(
struct i2400m *, const struct i2400m_tlv_rf_switches_status *);
+/*
+ * Helpers for firmware backwards compability
+ *
+ * As we aim to support at least the firmware version that was
+ * released with the previous kernel/driver release, some code will be
+ * conditionally executed depending on the firmware version. On each
+ * release, the code to support fw releases past the last two ones
+ * will be purged.
+ *
+ * By making it depend on this macros, it is easier to keep it a tab
+ * on what has to go and what not.
+ */
+static inline
+unsigned i2400m_le_v1_3(struct i2400m *i2400m)
+{
+ /* running fw is lower or v1.3 */
+ return i2400m->fw_version <= 0x00090001;
+}
+
+static inline
+unsigned i2400m_ge_v1_4(struct i2400m *i2400m)
+{
+ /* running fw is higher or v1.4 */
+ return i2400m->fw_version >= 0x00090002;
+}
+
/*
* Do a millisecond-sleep for allowing wireshark to dump all the data
@@ -750,6 +804,7 @@ void __i2400m_msleep(unsigned ms)
/* Module parameters */
extern int i2400m_idle_mode_disabled;
+extern int i2400m_rx_reorder_disabled;
#endif /* #ifndef __I2400M_H__ */
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 63fe708e8a3..6b1fe7a81f2 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -28,13 +28,12 @@
* space and from the other side. The world is (sadly) configured to
* take in only Ethernet devices...
*
- * Because of this, currently there is an copy-each-rxed-packet
- * overhead on the RX path. Each IP packet has to be reallocated to
- * add an ethernet header (as there is no space in what we get from
- * the device). This is a known drawback and coming versions of the
- * device's firmware are being changed to add header space that can be
- * used to insert the ethernet header without having to reallocate and
- * copy.
+ * Because of this, when using firmwares <= v1.3, there is an
+ * copy-each-rxed-packet overhead on the RX path. Each IP packet has
+ * to be reallocated to add an ethernet header (as there is no space
+ * in what we get from the device). This is a known drawback and
+ * firmwares >= 1.4 add header space that can be used to insert the
+ * ethernet header without having to reallocate and copy.
*
* TX error handling is tricky; because we have to FIFO/queue the
* buffers for transmission (as the hardware likes it aggregated), we
@@ -67,7 +66,9 @@
* i2400m_tx_timeout Called when the device times out
*
* i2400m_net_rx Called by the RX code when a data frame is
- * available.
+ * available (firmware <= 1.3)
+ * i2400m_net_erx Called by the RX code when a data frame is
+ * available (firmware >= 1.4).
* i2400m_netdev_setup Called to setup all the netdev stuff from
* alloc_netdev.
*/
@@ -396,30 +397,18 @@ void i2400m_tx_timeout(struct net_device *net_dev)
* Create a fake ethernet header
*
* For emulating an ethernet device, every received IP header has to
- * be prefixed with an ethernet header.
- *
- * What we receive has (potentially) many IP packets concatenated with
- * no ETH_HLEN bytes prefixed. Thus there is no space for an eth
- * header.
- *
- * We would have to reallocate or do ugly fragment tricks in order to
- * add it.
- *
- * But what we do is use the header space of the RX transaction
- * (*msg_hdr) as we don't need it anymore; then we'll point all the
- * data skbs there, as they share the same backing store.
- *
- * We only support IPv4 for v3 firmware.
+ * be prefixed with an ethernet header. Fake it with the given
+ * protocol.
*/
static
void i2400m_rx_fake_eth_header(struct net_device *net_dev,
- void *_eth_hdr)
+ void *_eth_hdr, __be16 protocol)
{
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));
- eth_hdr->h_proto = __constant_cpu_to_be16(ETH_P_IP);
+ eth_hdr->h_proto = protocol;
}
@@ -432,6 +421,13 @@ void i2400m_rx_fake_eth_header(struct net_device *net_dev,
* @buf: pointer to the buffer containing the data
* @len: buffer's length
*
+ * This is only used now for the v1.3 firmware. It will be deprecated
+ * in >= 2.6.31.
+ *
+ * Note that due to firmware limitations, we don't have space to add
+ * an ethernet header, so we need to copy each packet. Firmware
+ * versions >= v1.4 fix this [see i2400m_net_erx()].
+ *
* We just clone the skb and set it up so that it's skb->data pointer
* points to "buf" and it's length.
*
@@ -478,7 +474,8 @@ void i2400m_net_rx(struct i2400m *i2400m, struct sk_buff *skb_rx,
memcpy(skb_put(skb, buf_len), buf, buf_len);
}
i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev,
- skb->data - ETH_HLEN);
+ skb->data - ETH_HLEN,
+ cpu_to_be16(ETH_P_IP));
skb_set_mac_header(skb, -ETH_HLEN);
skb->dev = i2400m->wimax_dev.net_dev;
skb->protocol = htons(ETH_P_IP);
@@ -494,6 +491,73 @@ error_skb_realloc:
}
+/*
+ * i2400m_net_erx - pass a network packet to the stack (extended version)
+ *
+ * @i2400m: device descriptor
+ * @skb: the skb where the packet is - the skb should be set to point
+ * at the IP packet; this function will add ethernet headers if
+ * needed.
+ * @cs: packet type
+ *
+ * This is only used now for firmware >= v1.4. Note it is quite
+ * similar to i2400m_net_rx() (used only for v1.3 firmware).
+ *
+ * This function is normally run from a thread context. However, we
+ * still use netif_rx() instead of netif_receive_skb() as was
+ * recommended in the mailing list. Reason is in some stress tests
+ * when sending/receiving a lot of data we seem to hit a softlock in
+ * the kernel's TCP implementation [aroudn tcp_delay_timer()]. Using
+ * netif_rx() took care of the issue.
+ *
+ * This is, of course, still open to do more research on why running
+ * with netif_receive_skb() hits this softlock. FIXME.
+ */
+void i2400m_net_erx(struct i2400m *i2400m, struct sk_buff *skb,
+ enum i2400m_cs cs)
+{
+ struct net_device *net_dev = i2400m->wimax_dev.net_dev;
+ struct device *dev = i2400m_dev(i2400m);
+ int protocol;
+
+ d_fnstart(2, dev, "(i2400m %p skb %p [%u] cs %d)\n",
+ i2400m, skb, skb->len, cs);
+ switch(cs) {
+ case I2400M_CS_IPV4_0:
+ case I2400M_CS_IPV4:
+ protocol = ETH_P_IP;
+ i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev,
+ skb->data - ETH_HLEN,
+ cpu_to_be16(ETH_P_IP));
+ skb_set_mac_header(skb, -ETH_HLEN);
+ skb->dev = i2400m->wimax_dev.net_dev;
+ skb->protocol = htons(ETH_P_IP);
+ net_dev->stats.rx_packets++;
+ net_dev->stats.rx_bytes += skb->len;
+ break;
+ default:
+ dev_err(dev, "ERX: BUG? CS type %u unsupported\n", cs);
+ goto error;
+
+ }
+ d_printf(3, dev, "ERX: receiving %d bytes to the network stack\n",
+ skb->len);
+ d_dump(4, dev, skb->data, skb->len);
+ netif_rx_ni(skb); /* see notes in function header */
+error:
+ d_fnend(2, dev, "(i2400m %p skb %p [%u] cs %d) = void\n",
+ i2400m, skb, skb->len, cs);
+}
+
+static const struct net_device_ops i2400m_netdev_ops = {
+ .ndo_open = i2400m_open,
+ .ndo_stop = i2400m_stop,
+ .ndo_start_xmit = i2400m_hard_start_xmit,
+ .ndo_tx_timeout = i2400m_tx_timeout,
+ .ndo_change_mtu = i2400m_change_mtu,
+};
+
+
/**
* i2400m_netdev_setup - Setup setup @net_dev's i2400m private data
*
@@ -513,11 +577,7 @@ void i2400m_netdev_setup(struct net_device *net_dev)
& (~IFF_BROADCAST /* i2400m is P2P */
& ~IFF_MULTICAST);
net_dev->watchdog_timeo = I2400M_TX_TIMEOUT;
- net_dev->open = i2400m_open;
- net_dev->stop = i2400m_stop;
- net_dev->hard_start_xmit = i2400m_hard_start_xmit;
- net_dev->change_mtu = i2400m_change_mtu;
- net_dev->tx_timeout = i2400m_tx_timeout;
+ net_dev->netdev_ops = &i2400m_netdev_ops;
d_fnend(3, NULL, "(net_dev %p) = void\n", net_dev);
}
EXPORT_SYMBOL_GPL(i2400m_netdev_setup);
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index 6922022710a..02419bfd64b 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -39,7 +39,7 @@
* - Use skb_clone(), break up processing in chunks
* - Split transport/device specific
* - Make buffer size dynamic to exert less memory pressure
- *
+ * - RX reorder support
*
* This handles the RX path.
*
@@ -69,6 +69,50 @@
* See tx.c for a deeper description on alignment requirements and
* other fun facts of it.
*
+ * DATA PACKETS
+ *
+ * In firmwares <= v1.3, data packets have no header for RX, but they
+ * do for TX (currently unused).
+ *
+ * In firmware >= 1.4, RX packets have an extended header (16
+ * bytes). This header conveys information for management of host
+ * reordering of packets (the device offloads storage of the packets
+ * for reordering to the host). Read below for more information.
+ *
+ * The header is used as dummy space to emulate an ethernet header and
+ * thus be able to act as an ethernet device without having to reallocate.
+ *
+ * DATA RX REORDERING
+ *
+ * Starting in firmware v1.4, the device can deliver packets for
+ * delivery with special reordering information; this allows it to
+ * more effectively do packet management when some frames were lost in
+ * the radio traffic.
+ *
+ * Thus, for RX packets that come out of order, the device gives the
+ * driver enough information to queue them properly and then at some
+ * point, the signal to deliver the whole (or part) of the queued
+ * packets to the networking stack. There are 16 such queues.
+ *
+ * This only happens when a packet comes in with the "need reorder"
+ * flag set in the RX header. When such bit is set, the following
+ * operations might be indicated:
+ *
+ * - reset queue: send all queued packets to the OS
+ *
+ * - queue: queue a packet
+ *
+ * - update ws: update the queue's window start and deliver queued
+ * packets that meet the criteria
+ *
+ * - queue & update ws: queue a packet, update the window start and
+ * deliver queued packets that meet the criteria
+ *
+ * (delivery criteria: the packet's [normalized] sequence number is
+ * lower than the new [normalized] window start).
+ *
+ * See the i2400m_roq_*() functions for details.
+ *
* ROADMAP
*
* i2400m_rx
@@ -76,6 +120,19 @@
* i2400m_rx_pl_descr_check
* i2400m_rx_payload
* i2400m_net_rx
+ * i2400m_rx_edata
+ * i2400m_net_erx
+ * i2400m_roq_reset
+ * i2400m_net_erx
+ * i2400m_roq_queue
+ * __i2400m_roq_queue
+ * i2400m_roq_update_ws
+ * __i2400m_roq_update_ws
+ * i2400m_net_erx
+ * i2400m_roq_queue_update_ws
+ * __i2400m_roq_queue
+ * __i2400m_roq_update_ws
+ * i2400m_net_erx
* i2400m_rx_ctl
* i2400m_msg_size_check
* i2400m_report_hook_work [in a workqueue]
@@ -177,8 +234,7 @@ void i2400m_rx_ctl_ack(struct i2400m *i2400m,
return;
error_waiter_cancelled:
- if (ack_skb)
- kfree_skb(ack_skb);
+ kfree_skb(ack_skb);
error_no_waiter:
spin_unlock_irqrestore(&i2400m->rx_lock, flags);
return;
@@ -265,8 +321,6 @@ error_check:
}
-
-
/*
* Receive and send up a trace
*
@@ -317,30 +371,628 @@ error_check:
/*
+ * Reorder queue data stored on skb->cb while the skb is queued in the
+ * reorder queues.
+ */
+struct i2400m_roq_data {
+ unsigned sn; /* Serial number for the skb */
+ enum i2400m_cs cs; /* packet type for the skb */
+};
+
+
+/*
+ * ReOrder Queue
+ *
+ * @ws: Window Start; sequence number where the current window start
+ * is for this queue
+ * @queue: the skb queue itself
+ * @log: circular ring buffer used to log information about the
+ * reorder process in this queue that can be displayed in case of
+ * error to help diagnose it.
+ *
+ * This is the head for a list of skbs. In the skb->cb member of the
+ * skb when queued here contains a 'struct i2400m_roq_data' were we
+ * store the sequence number (sn) and the cs (packet type) coming from
+ * the RX payload header from the device.
+ */
+struct i2400m_roq
+{
+ unsigned ws;
+ struct sk_buff_head queue;
+ struct i2400m_roq_log *log;
+};
+
+
+static
+void __i2400m_roq_init(struct i2400m_roq *roq)
+{
+ roq->ws = 0;
+ skb_queue_head_init(&roq->queue);
+}
+
+
+static
+unsigned __i2400m_roq_index(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+ return ((unsigned long) roq - (unsigned long) i2400m->rx_roq)
+ / sizeof(*roq);
+}
+
+
+/*
+ * Normalize a sequence number based on the queue's window start
+ *
+ * nsn = (sn - ws) % 2048
+ *
+ * Note that if @sn < @roq->ws, we still need a positive number; %'s
+ * sign is implementation specific, so we normalize it by adding 2048
+ * to bring it to be positive.
+ */
+static
+unsigned __i2400m_roq_nsn(struct i2400m_roq *roq, unsigned sn)
+{
+ int r;
+ r = ((int) sn - (int) roq->ws) % 2048;
+ if (r < 0)
+ r += 2048;
+ return r;
+}
+
+
+/*
+ * Circular buffer to keep the last N reorder operations
+ *
+ * In case something fails, dumb then to try to come up with what
+ * happened.
+ */
+enum {
+ I2400M_ROQ_LOG_LENGTH = 32,
+};
+
+struct i2400m_roq_log {
+ struct i2400m_roq_log_entry {
+ enum i2400m_ro_type type;
+ unsigned ws, count, sn, nsn, new_ws;
+ } entry[I2400M_ROQ_LOG_LENGTH];
+ unsigned in, out;
+};
+
+
+/* Print a log entry */
+static
+void i2400m_roq_log_entry_print(struct i2400m *i2400m, unsigned index,
+ unsigned e_index,
+ struct i2400m_roq_log_entry *e)
+{
+ struct device *dev = i2400m_dev(i2400m);
+
+ switch(e->type) {
+ case I2400M_RO_TYPE_RESET:
+ dev_err(dev, "q#%d reset ws %u cnt %u sn %u/%u"
+ " - new nws %u\n",
+ index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+ break;
+ case I2400M_RO_TYPE_PACKET:
+ dev_err(dev, "q#%d queue ws %u cnt %u sn %u/%u\n",
+ index, e->ws, e->count, e->sn, e->nsn);
+ break;
+ case I2400M_RO_TYPE_WS:
+ dev_err(dev, "q#%d update_ws ws %u cnt %u sn %u/%u"
+ " - new nws %u\n",
+ index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+ break;
+ case I2400M_RO_TYPE_PACKET_WS:
+ dev_err(dev, "q#%d queue_update_ws ws %u cnt %u sn %u/%u"
+ " - new nws %u\n",
+ index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+ break;
+ default:
+ dev_err(dev, "q#%d BUG? entry %u - unknown type %u\n",
+ index, e_index, e->type);
+ break;
+ }
+}
+
+
+static
+void i2400m_roq_log_add(struct i2400m *i2400m,
+ struct i2400m_roq *roq, enum i2400m_ro_type type,
+ unsigned ws, unsigned count, unsigned sn,
+ unsigned nsn, unsigned new_ws)
+{
+ struct i2400m_roq_log_entry *e;
+ unsigned cnt_idx;
+ int index = __i2400m_roq_index(i2400m, roq);
+
+ /* if we run out of space, we eat from the end */
+ if (roq->log->in - roq->log->out == I2400M_ROQ_LOG_LENGTH)
+ roq->log->out++;
+ cnt_idx = roq->log->in++ % I2400M_ROQ_LOG_LENGTH;
+ e = &roq->log->entry[cnt_idx];
+
+ e->type = type;
+ e->ws = ws;
+ e->count = count;
+ e->sn = sn;
+ e->nsn = nsn;
+ e->new_ws = new_ws;
+
+ if (d_test(1))
+ i2400m_roq_log_entry_print(i2400m, index, cnt_idx, e);
+}
+
+
+/* Dump all the entries in the FIFO and reinitialize it */
+static
+void i2400m_roq_log_dump(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+ unsigned cnt, cnt_idx;
+ struct i2400m_roq_log_entry *e;
+ int index = __i2400m_roq_index(i2400m, roq);
+
+ BUG_ON(roq->log->out > roq->log->in);
+ for (cnt = roq->log->out; cnt < roq->log->in; cnt++) {
+ cnt_idx = cnt % I2400M_ROQ_LOG_LENGTH;
+ e = &roq->log->entry[cnt_idx];
+ i2400m_roq_log_entry_print(i2400m, index, cnt_idx, e);
+ memset(e, 0, sizeof(*e));
+ }
+ roq->log->in = roq->log->out = 0;
+}
+
+
+/*
+ * Backbone for the queuing of an skb (by normalized sequence number)
+ *
+ * @i2400m: device descriptor
+ * @roq: reorder queue where to add
+ * @skb: the skb to add
+ * @sn: the sequence number of the skb
+ * @nsn: the normalized sequence number of the skb (pre-computed by the
+ * caller from the @sn and @roq->ws).
+ *
+ * We try first a couple of quick cases:
+ *
+ * - the queue is empty
+ * - the skb would be appended to the queue
+ *
+ * These will be the most common operations.
+ *
+ * If these fail, then we have to do a sorted insertion in the queue,
+ * which is the slowest path.
+ *
+ * We don't have to acquire a reference count as we are going to own it.
+ */
+static
+void __i2400m_roq_queue(struct i2400m *i2400m, struct i2400m_roq *roq,
+ struct sk_buff *skb, unsigned sn, unsigned nsn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ struct sk_buff *skb_itr;
+ struct i2400m_roq_data *roq_data_itr, *roq_data;
+ unsigned nsn_itr;
+
+ d_fnstart(4, dev, "(i2400m %p roq %p skb %p sn %u nsn %u)\n",
+ i2400m, roq, skb, sn, nsn);
+
+ roq_data = (struct i2400m_roq_data *) &skb->cb;
+ BUILD_BUG_ON(sizeof(*roq_data) > sizeof(skb->cb));
+ roq_data->sn = sn;
+ d_printf(3, dev, "ERX: roq %p [ws %u] nsn %d sn %u\n",
+ roq, roq->ws, nsn, roq_data->sn);
+
+ /* Queues will be empty on not-so-bad environments, so try
+ * that first */
+ if (skb_queue_empty(&roq->queue)) {
+ d_printf(2, dev, "ERX: roq %p - first one\n", roq);
+ __skb_queue_head(&roq->queue, skb);
+ goto out;
+ }
+ /* Now try append, as most of the operations will be that */
+ skb_itr = skb_peek_tail(&roq->queue);
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+ /* NSN bounds assumed correct (checked when it was queued) */
+ if (nsn >= nsn_itr) {
+ d_printf(2, dev, "ERX: roq %p - appended after %p (nsn %d sn %u)\n",
+ roq, skb_itr, nsn_itr, roq_data_itr->sn);
+ __skb_queue_tail(&roq->queue, skb);
+ goto out;
+ }
+ /* None of the fast paths option worked. Iterate to find the
+ * right spot where to insert the packet; we know the queue is
+ * not empty, so we are not the first ones; we also know we
+ * are not going to be the last ones. The list is sorted, so
+ * we have to insert before the the first guy with an nsn_itr
+ * greater that our nsn. */
+ skb_queue_walk(&roq->queue, skb_itr) {
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+ /* NSN bounds assumed correct (checked when it was queued) */
+ if (nsn_itr > nsn) {
+ d_printf(2, dev, "ERX: roq %p - queued before %p "
+ "(nsn %d sn %u)\n", roq, skb_itr, nsn_itr,
+ roq_data_itr->sn);
+ __skb_queue_before(&roq->queue, skb_itr, skb);
+ goto out;
+ }
+ }
+ /* If we get here, that is VERY bad -- print info to help
+ * diagnose and crash it */
+ dev_err(dev, "SW BUG? failed to insert packet\n");
+ dev_err(dev, "ERX: roq %p [ws %u] skb %p nsn %d sn %u\n",
+ roq, roq->ws, skb, nsn, roq_data->sn);
+ skb_queue_walk(&roq->queue, skb_itr) {
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+ /* NSN bounds assumed correct (checked when it was queued) */
+ dev_err(dev, "ERX: roq %p skb_itr %p nsn %d sn %u\n",
+ roq, skb_itr, nsn_itr, roq_data_itr->sn);
+ }
+ BUG();
+out:
+ d_fnend(4, dev, "(i2400m %p roq %p skb %p sn %u nsn %d) = void\n",
+ i2400m, roq, skb, sn, nsn);
+ return;
+}
+
+
+/*
+ * Backbone for the update window start operation
+ *
+ * @i2400m: device descriptor
+ * @roq: Reorder queue
+ * @sn: New sequence number
+ *
+ * Updates the window start of a queue; when doing so, it must deliver
+ * to the networking stack all the queued skb's whose normalized
+ * sequence number is lower than the new normalized window start.
+ */
+static
+unsigned __i2400m_roq_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+ unsigned sn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ struct sk_buff *skb_itr, *tmp_itr;
+ struct i2400m_roq_data *roq_data_itr;
+ unsigned new_nws, nsn_itr;
+
+ new_nws = __i2400m_roq_nsn(roq, sn);
+ if (unlikely(new_nws >= 1024) && d_test(1)) {
+ dev_err(dev, "SW BUG? __update_ws new_nws %u (sn %u ws %u)\n",
+ new_nws, sn, roq->ws);
+ WARN_ON(1);
+ i2400m_roq_log_dump(i2400m, roq);
+ }
+ skb_queue_walk_safe(&roq->queue, skb_itr, tmp_itr) {
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+ /* NSN bounds assumed correct (checked when it was queued) */
+ if (nsn_itr < new_nws) {
+ d_printf(2, dev, "ERX: roq %p - release skb %p "
+ "(nsn %u/%u new nws %u)\n",
+ roq, skb_itr, nsn_itr, roq_data_itr->sn,
+ new_nws);
+ __skb_unlink(skb_itr, &roq->queue);
+ i2400m_net_erx(i2400m, skb_itr, roq_data_itr->cs);
+ }
+ else
+ break; /* rest of packets all nsn_itr > nws */
+ }
+ roq->ws = sn;
+ return new_nws;
+}
+
+
+/*
+ * Reset a queue
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ *
+ * Deliver all the packets and reset the window-start to zero. Name is
+ * kind of misleading.
+ */
+static
+void i2400m_roq_reset(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ struct sk_buff *skb_itr, *tmp_itr;
+ struct i2400m_roq_data *roq_data_itr;
+
+ d_fnstart(2, dev, "(i2400m %p roq %p)\n", i2400m, roq);
+ i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_RESET,
+ roq->ws, skb_queue_len(&roq->queue),
+ ~0, ~0, 0);
+ skb_queue_walk_safe(&roq->queue, skb_itr, tmp_itr) {
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ d_printf(2, dev, "ERX: roq %p - release skb %p (sn %u)\n",
+ roq, skb_itr, roq_data_itr->sn);
+ __skb_unlink(skb_itr, &roq->queue);
+ i2400m_net_erx(i2400m, skb_itr, roq_data_itr->cs);
+ }
+ roq->ws = 0;
+ d_fnend(2, dev, "(i2400m %p roq %p) = void\n", i2400m, roq);
+ return;
+}
+
+
+/*
+ * Queue a packet
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ * @skb: containing the packet data
+ * @fbn: First block number of the packet in @skb
+ * @lbn: Last block number of the packet in @skb
+ *
+ * The hardware is asking the driver to queue a packet for later
+ * delivery to the networking stack.
+ */
+static
+void i2400m_roq_queue(struct i2400m *i2400m, struct i2400m_roq *roq,
+ struct sk_buff * skb, unsigned lbn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ unsigned nsn, len;
+
+ d_fnstart(2, dev, "(i2400m %p roq %p skb %p lbn %u) = void\n",
+ i2400m, roq, skb, lbn);
+ len = skb_queue_len(&roq->queue);
+ nsn = __i2400m_roq_nsn(roq, lbn);
+ if (unlikely(nsn >= 1024)) {
+ dev_err(dev, "SW BUG? queue nsn %d (lbn %u ws %u)\n",
+ nsn, lbn, roq->ws);
+ i2400m_roq_log_dump(i2400m, roq);
+ i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+ } else {
+ __i2400m_roq_queue(i2400m, roq, skb, lbn, nsn);
+ i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET,
+ roq->ws, len, lbn, nsn, ~0);
+ }
+ d_fnend(2, dev, "(i2400m %p roq %p skb %p lbn %u) = void\n",
+ i2400m, roq, skb, lbn);
+ return;
+}
+
+
+/*
+ * Update the window start in a reorder queue and deliver all skbs
+ * with a lower window start
+ *
+ * @i2400m: device descriptor
+ * @roq: Reorder queue
+ * @sn: New sequence number
+ */
+static
+void i2400m_roq_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+ unsigned sn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ unsigned old_ws, nsn, len;
+
+ d_fnstart(2, dev, "(i2400m %p roq %p sn %u)\n", i2400m, roq, sn);
+ old_ws = roq->ws;
+ len = skb_queue_len(&roq->queue);
+ nsn = __i2400m_roq_update_ws(i2400m, roq, sn);
+ i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_WS,
+ old_ws, len, sn, nsn, roq->ws);
+ d_fnstart(2, dev, "(i2400m %p roq %p sn %u) = void\n", i2400m, roq, sn);
+ return;
+}
+
+
+/*
+ * Queue a packet and update the window start
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ * @skb: containing the packet data
+ * @fbn: First block number of the packet in @skb
+ * @sn: Last block number of the packet in @skb
+ *
+ * Note that unlike i2400m_roq_update_ws(), which sets the new window
+ * start to @sn, in here we'll set it to @sn + 1.
+ */
+static
+void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+ struct sk_buff * skb, unsigned sn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ unsigned nsn, old_ws, len;
+
+ d_fnstart(2, dev, "(i2400m %p roq %p skb %p sn %u)\n",
+ i2400m, roq, skb, sn);
+ len = skb_queue_len(&roq->queue);
+ nsn = __i2400m_roq_nsn(roq, sn);
+ old_ws = roq->ws;
+ if (unlikely(nsn >= 1024)) {
+ dev_err(dev, "SW BUG? queue_update_ws nsn %u (sn %u ws %u)\n",
+ nsn, sn, roq->ws);
+ i2400m_roq_log_dump(i2400m, roq);
+ i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+ } else {
+ /* if the queue is empty, don't bother as we'd queue
+ * it and inmediately unqueue it -- just deliver it */
+ if (len == 0) {
+ struct i2400m_roq_data *roq_data;
+ roq_data = (struct i2400m_roq_data *) &skb->cb;
+ i2400m_net_erx(i2400m, skb, roq_data->cs);
+ }
+ else {
+ __i2400m_roq_queue(i2400m, roq, skb, sn, nsn);
+ __i2400m_roq_update_ws(i2400m, roq, sn + 1);
+ }
+ i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET_WS,
+ old_ws, len, sn, nsn, roq->ws);
+ }
+ d_fnend(2, dev, "(i2400m %p roq %p skb %p sn %u) = void\n",
+ i2400m, roq, skb, sn);
+ return;
+}
+
+
+/*
+ * Receive and send up an extended data packet
+ *
+ * @i2400m: device descriptor
+ * @skb_rx: skb that contains the extended data packet
+ * @single_last: 1 if the payload is the only one or the last one of
+ * the skb.
+ * @payload: pointer to the packet's data inside the skb
+ * @size: size of the payload
+ *
+ * Starting in v1.4 of the i2400m's firmware, the device can send data
+ * packets to the host in an extended format that; this incudes a 16
+ * byte header (struct i2400m_pl_edata_hdr). Using this header's space
+ * we can fake ethernet headers for ethernet device emulation without
+ * having to copy packets around.
+ *
+ * This function handles said path.
+ *
+ *
+ * Receive and send up an extended data packet that requires no reordering
+ *
+ * @i2400m: device descriptor
+ * @skb_rx: skb that contains the extended data packet
+ * @single_last: 1 if the payload is the only one or the last one of
+ * the skb.
+ * @payload: pointer to the packet's data (past the actual extended
+ * data payload header).
+ * @size: size of the payload
+ *
+ * Pass over to the networking stack a data packet that might have
+ * reordering requirements.
+ *
+ * This needs to the decide if the skb in which the packet is
+ * contained can be reused or if it needs to be cloned. Then it has to
+ * be trimmed in the edges so that the beginning is the space for eth
+ * header and then pass it to i2400m_net_erx() for the stack
+ *
+ * Assumes the caller has verified the sanity of the payload (size,
+ * etc) already.
+ */
+static
+void i2400m_rx_edata(struct i2400m *i2400m, struct sk_buff *skb_rx,
+ unsigned single_last, const void *payload, size_t size)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ const struct i2400m_pl_edata_hdr *hdr = payload;
+ struct net_device *net_dev = i2400m->wimax_dev.net_dev;
+ struct sk_buff *skb;
+ enum i2400m_cs cs;
+ u32 reorder;
+ unsigned ro_needed, ro_type, ro_cin, ro_sn;
+ struct i2400m_roq *roq;
+ struct i2400m_roq_data *roq_data;
+
+ BUILD_BUG_ON(ETH_HLEN > sizeof(*hdr));
+
+ d_fnstart(2, dev, "(i2400m %p skb_rx %p single %u payload %p "
+ "size %zu)\n", i2400m, skb_rx, single_last, payload, size);
+ if (size < sizeof(*hdr)) {
+ dev_err(dev, "ERX: HW BUG? message with short header (%zu "
+ "vs %zu bytes expected)\n", size, sizeof(*hdr));
+ goto error;
+ }
+
+ if (single_last) {
+ skb = skb_get(skb_rx);
+ d_printf(3, dev, "ERX: skb %p reusing\n", skb);
+ } else {
+ skb = skb_clone(skb_rx, GFP_KERNEL);
+ if (skb == NULL) {
+ dev_err(dev, "ERX: no memory to clone skb\n");
+ net_dev->stats.rx_dropped++;
+ goto error_skb_clone;
+ }
+ d_printf(3, dev, "ERX: skb %p cloned from %p\n", skb, skb_rx);
+ }
+ /* now we have to pull and trim so that the skb points to the
+ * beginning of the IP packet; the netdev part will add the
+ * ethernet header as needed - we know there is enough space
+ * because we checked in i2400m_rx_edata(). */
+ skb_pull(skb, payload + sizeof(*hdr) - (void *) skb->data);
+ skb_trim(skb, (void *) skb_end_pointer(skb) - payload - sizeof(*hdr));
+
+ reorder = le32_to_cpu(hdr->reorder);
+ ro_needed = reorder & I2400M_RO_NEEDED;
+ cs = hdr->cs;
+ if (ro_needed) {
+ ro_type = (reorder >> I2400M_RO_TYPE_SHIFT) & I2400M_RO_TYPE;
+ ro_cin = (reorder >> I2400M_RO_CIN_SHIFT) & I2400M_RO_CIN;
+ ro_sn = (reorder >> I2400M_RO_SN_SHIFT) & I2400M_RO_SN;
+
+ roq = &i2400m->rx_roq[ro_cin];
+ roq_data = (struct i2400m_roq_data *) &skb->cb;
+ roq_data->sn = ro_sn;
+ roq_data->cs = cs;
+ d_printf(2, dev, "ERX: reorder needed: "
+ "type %u cin %u [ws %u] sn %u/%u len %zuB\n",
+ ro_type, ro_cin, roq->ws, ro_sn,
+ __i2400m_roq_nsn(roq, ro_sn), size);
+ d_dump(2, dev, payload, size);
+ switch(ro_type) {
+ case I2400M_RO_TYPE_RESET:
+ i2400m_roq_reset(i2400m, roq);
+ kfree_skb(skb); /* no data here */
+ break;
+ case I2400M_RO_TYPE_PACKET:
+ i2400m_roq_queue(i2400m, roq, skb, ro_sn);
+ break;
+ case I2400M_RO_TYPE_WS:
+ i2400m_roq_update_ws(i2400m, roq, ro_sn);
+ kfree_skb(skb); /* no data here */
+ break;
+ case I2400M_RO_TYPE_PACKET_WS:
+ i2400m_roq_queue_update_ws(i2400m, roq, skb, ro_sn);
+ break;
+ default:
+ dev_err(dev, "HW BUG? unknown reorder type %u\n", ro_type);
+ }
+ }
+ else
+ i2400m_net_erx(i2400m, skb, cs);
+error_skb_clone:
+error:
+ d_fnend(2, dev, "(i2400m %p skb_rx %p single %u payload %p "
+ "size %zu) = void\n", i2400m, skb_rx, single_last, payload, size);
+ return;
+}
+
+
+/*
* Act on a received payload
*
* @i2400m: device instance
* @skb_rx: skb where the transaction was received
- * @single: 1 if there is only one payload, 0 otherwise
+ * @single_last: 1 this is the only payload or the last one (so the
+ * skb can be reused instead of cloned).
* @pld: payload descriptor
* @payload: payload data
*
* Upon reception of a payload, look at its guts in the payload
- * descriptor and decide what to do with it.
+ * descriptor and decide what to do with it. If it is a single payload
+ * skb or if the last skb is a data packet, the skb will be referenced
+ * and modified (so it doesn't have to be cloned).
*/
static
void i2400m_rx_payload(struct i2400m *i2400m, struct sk_buff *skb_rx,
- unsigned single, const struct i2400m_pld *pld,
+ unsigned single_last, const struct i2400m_pld *pld,
const void *payload)
{
struct device *dev = i2400m_dev(i2400m);
size_t pl_size = i2400m_pld_size(pld);
enum i2400m_pt pl_type = i2400m_pld_type(pld);
+ d_printf(7, dev, "RX: received payload type %u, %zu bytes\n",
+ pl_type, pl_size);
+ d_dump(8, dev, payload, pl_size);
+
switch (pl_type) {
case I2400M_PT_DATA:
d_printf(3, dev, "RX: data payload %zu bytes\n", pl_size);
- i2400m_net_rx(i2400m, skb_rx, single, payload, pl_size);
+ i2400m_net_rx(i2400m, skb_rx, single_last, payload, pl_size);
break;
case I2400M_PT_CTRL:
i2400m_rx_ctl(i2400m, skb_rx, payload, pl_size);
@@ -348,6 +1000,10 @@ void i2400m_rx_payload(struct i2400m *i2400m, struct sk_buff *skb_rx,
case I2400M_PT_TRACE:
i2400m_rx_trace(i2400m, payload, pl_size);
break;
+ case I2400M_PT_EDATA:
+ d_printf(3, dev, "ERX: data payload %zu bytes\n", pl_size);
+ i2400m_rx_edata(i2400m, skb_rx, single_last, payload, pl_size);
+ break;
default: /* Anything else shouldn't come to the host */
if (printk_ratelimit())
dev_err(dev, "RX: HW BUG? unexpected payload type %u\n",
@@ -475,7 +1131,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
const struct i2400m_msg_hdr *msg_hdr;
size_t pl_itr, pl_size, skb_len;
unsigned long flags;
- unsigned num_pls;
+ unsigned num_pls, single_last;
skb_len = skb->len;
d_fnstart(4, dev, "(i2400m %p skb %p [size %zu])\n",
@@ -504,7 +1160,8 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
pl_itr, skb->len);
if (result < 0)
goto error_pl_descr_check;
- i2400m_rx_payload(i2400m, skb, num_pls == 1, &msg_hdr->pld[i],
+ 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);
cond_resched(); /* Don't monopolize */
@@ -532,3 +1189,73 @@ error_msg_hdr_check:
return result;
}
EXPORT_SYMBOL_GPL(i2400m_rx);
+
+
+/*
+ * Initialize the RX queue and infrastructure
+ *
+ * This sets up all the RX reordering infrastructures, which will not
+ * be used if reordering is not enabled or if the firmware does not
+ * support it. The device is told to do reordering in
+ * i2400m_dev_initialize(), where it also looks at the value of the
+ * i2400m->rx_reorder switch before taking a decission.
+ *
+ * Note we allocate the roq queues in one chunk and the actual logging
+ * support for it (logging) in another one and then we setup the
+ * pointers from the first to the last.
+ */
+int i2400m_rx_setup(struct i2400m *i2400m)
+{
+ int result = 0;
+ struct device *dev = i2400m_dev(i2400m);
+
+ i2400m->rx_reorder = i2400m_rx_reorder_disabled? 0 : 1;
+ if (i2400m->rx_reorder) {
+ unsigned itr;
+ size_t size;
+ struct i2400m_roq_log *rd;
+
+ result = -ENOMEM;
+
+ size = sizeof(i2400m->rx_roq[0]) * (I2400M_RO_CIN + 1);
+ i2400m->rx_roq = kzalloc(size, GFP_KERNEL);
+ if (i2400m->rx_roq == NULL) {
+ dev_err(dev, "RX: cannot allocate %zu bytes for "
+ "reorder queues\n", size);
+ goto error_roq_alloc;
+ }
+
+ size = sizeof(*i2400m->rx_roq[0].log) * (I2400M_RO_CIN + 1);
+ rd = kzalloc(size, GFP_KERNEL);
+ if (rd == NULL) {
+ dev_err(dev, "RX: cannot allocate %zu bytes for "
+ "reorder queues log areas\n", size);
+ result = -ENOMEM;
+ goto error_roq_log_alloc;
+ }
+
+ for(itr = 0; itr < I2400M_RO_CIN + 1; itr++) {
+ __i2400m_roq_init(&i2400m->rx_roq[itr]);
+ i2400m->rx_roq[itr].log = &rd[itr];
+ }
+ }
+ return 0;
+
+error_roq_log_alloc:
+ kfree(i2400m->rx_roq);
+error_roq_alloc:
+ return result;
+}
+
+
+/* Tear down the RX queue and infrastructure */
+void i2400m_rx_release(struct i2400m *i2400m)
+{
+ if (i2400m->rx_reorder) {
+ unsigned itr;
+ for(itr = 0; itr < I2400M_RO_CIN + 1; itr++)
+ __skb_queue_purge(&i2400m->rx_roq[itr].queue);
+ kfree(i2400m->rx_roq[0].log);
+ kfree(i2400m->rx_roq);
+ }
+}
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 1bfa283bbd8..5ac5e76701c 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -70,8 +70,13 @@
static int ioe_timeout = 2;
module_param(ioe_timeout, int, 0);
-/* Our firmware file name */
-#define I2400MS_FW_FILE_NAME "i2400m-fw-sdio-" I2400M_FW_VERSION ".sbcf"
+/* Our firmware file name list */
+static const char *i2400ms_bus_fw_names[] = {
+#define I2400MS_FW_FILE_NAME "i2400m-fw-sdio-1.3.sbcf"
+ I2400MS_FW_FILE_NAME,
+ NULL
+};
+
/*
* Enable the SDIO function
@@ -255,16 +260,16 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
container_of(i2400m, struct i2400ms, i2400m);
struct device *dev = i2400m_dev(i2400m);
static const __le32 i2400m_WARM_BOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
};
static const __le32 i2400m_COLD_BOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
};
if (rt == I2400M_RT_WARM)
@@ -401,7 +406,7 @@ int i2400ms_probe(struct sdio_func *func,
i2400m->bus_reset = i2400ms_bus_reset;
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_name = I2400MS_FW_FILE_NAME;
+ i2400m->bus_fw_names = i2400ms_bus_fw_names;
i2400m->bus_bm_mac_addr_impaired = 1;
result = i2400ms_enable_function(i2400ms->func);
diff --git a/drivers/net/wimax/i2400m/sysfs.c b/drivers/net/wimax/i2400m/sysfs.c
new file mode 100644
index 00000000000..1237109f251
--- /dev/null
+++ b/drivers/net/wimax/i2400m/sysfs.c
@@ -0,0 +1,80 @@
+/*
+ * Intel Wireless WiMAX Connection 2400m
+ * Sysfs interfaces to show driver and device information
+ *
+ *
+ * Copyright (C) 2007 Intel Corporation <linux-wimax@intel.com>
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include "i2400m.h"
+
+
+#define D_SUBMODULE sysfs
+#include "debug-levels.h"
+
+
+/*
+ * Set the idle timeout (msecs)
+ *
+ * FIXME: eventually this should be a common WiMAX stack method, but
+ * would like to wait to see how other devices manage it.
+ */
+static
+ssize_t i2400m_idle_timeout_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ ssize_t result;
+ struct i2400m *i2400m = net_dev_to_i2400m(to_net_dev(dev));
+ unsigned val;
+
+ result = -EINVAL;
+ if (sscanf(buf, "%u\n", &val) != 1)
+ goto error_no_unsigned;
+ if (val != 0 && (val < 100 || val > 300000 || val % 100 != 0)) {
+ dev_err(dev, "idle_timeout: %u: invalid msecs specification; "
+ "valid values are 0, 100-300000 in 100 increments\n",
+ val);
+ goto error_bad_value;
+ }
+ result = i2400m_set_idle_timeout(i2400m, val);
+ if (result >= 0)
+ result = size;
+error_no_unsigned:
+error_bad_value:
+ return result;
+}
+
+static
+DEVICE_ATTR(i2400m_idle_timeout, S_IWUSR,
+ NULL, i2400m_idle_timeout_store);
+
+static
+struct attribute *i2400m_dev_attrs[] = {
+ &dev_attr_i2400m_idle_timeout.attr,
+ NULL,
+};
+
+struct attribute_group i2400m_dev_attr_group = {
+ .name = NULL, /* we want them in the same directory */
+ .attrs = i2400m_dev_attrs,
+};
diff --git a/drivers/net/wimax/i2400m/usb-notif.c b/drivers/net/wimax/i2400m/usb-notif.c
index 9702c22b249..6add27c3f35 100644
--- a/drivers/net/wimax/i2400m/usb-notif.c
+++ b/drivers/net/wimax/i2400m/usb-notif.c
@@ -102,7 +102,7 @@ int i2400mu_notification_grok(struct i2400mu *i2400mu, const void *buf,
dev_err(dev, "HW BUG? Unknown/unexpected data in notification "
"message (%zu bytes)\n", buf_len);
snprintf(prefix, sizeof(prefix), "%s %s: ",
- dev_driver_string(dev) , dev->bus_id);
+ dev_driver_string(dev), dev_name(dev));
if (buf_len > 64) {
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
8, 4, buf, 64, 0);
diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c
index 074cc1f8985..a314799967c 100644
--- a/drivers/net/wimax/i2400m/usb-rx.c
+++ b/drivers/net/wimax/i2400m/usb-rx.c
@@ -184,6 +184,8 @@ void i2400mu_rx_size_maybe_shrink(struct i2400mu *i2400mu)
* NOTE: this function might realloc the skb (if it is too small),
* so always update with the one returned.
* ERR_PTR() is < 0 on error.
+ * Will return NULL if it cannot reallocate -- this can be
+ * considered a transient retryable error.
*/
static
struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb)
@@ -243,8 +245,8 @@ retry:
if (printk_ratelimit())
dev_err(dev, "RX: Can't reallocate skb to %d; "
"RX dropped\n", rx_size);
- kfree(rx_skb);
- result = 0;
+ kfree_skb(rx_skb);
+ rx_skb = NULL;
goto out; /* drop it...*/
}
kfree_skb(rx_skb);
@@ -344,7 +346,8 @@ int i2400mu_rxd(void *_i2400mu)
if (IS_ERR(rx_skb))
goto out;
atomic_dec(&i2400mu->rx_pending_count);
- if (rx_skb->len == 0) { /* some ignorable condition */
+ if (rx_skb == NULL || rx_skb->len == 0) {
+ /* some "ignorable" condition */
kfree_skb(rx_skb);
continue;
}
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index c6d93465c7e..ca4151a9e22 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -73,7 +73,14 @@
/* Our firmware file name */
-#define I2400MU_FW_FILE_NAME "i2400m-fw-usb-" I2400M_FW_VERSION ".sbcf"
+static const char *i2400mu_bus_fw_names[] = {
+#define I2400MU_FW_FILE_NAME_v1_4 "i2400m-fw-usb-1.4.sbcf"
+ I2400MU_FW_FILE_NAME_v1_4,
+#define I2400MU_FW_FILE_NAME_v1_3 "i2400m-fw-usb-1.3.sbcf"
+ I2400MU_FW_FILE_NAME_v1_3,
+ NULL,
+};
+
static
int i2400mu_bus_dev_start(struct i2400m *i2400m)
@@ -211,16 +218,16 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
container_of(i2400m, struct i2400mu, i2400m);
struct device *dev = i2400m_dev(i2400m);
static const __le32 i2400m_WARM_BOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
};
static const __le32 i2400m_COLD_BOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
};
d_fnstart(3, dev, "(i2400m %p rt %u)\n", i2400m, rt);
@@ -394,7 +401,7 @@ int i2400mu_probe(struct usb_interface *iface,
i2400m->bus_reset = i2400mu_bus_reset;
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_name = I2400MU_FW_FILE_NAME;
+ i2400m->bus_fw_names = i2400mu_bus_fw_names;
i2400m->bus_bm_mac_addr_impaired = 0;
#ifdef CONFIG_PM
@@ -594,4 +601,5 @@ module_exit(i2400mu_driver_exit);
MODULE_AUTHOR("Intel Corporation <linux-wimax@intel.com>");
MODULE_DESCRIPTION("Intel 2400M WiMAX networking for USB");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(I2400MU_FW_FILE_NAME);
+MODULE_FIRMWARE(I2400MU_FW_FILE_NAME_v1_4);
+MODULE_FIRMWARE(I2400MU_FW_FILE_NAME_v1_3);
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index e4f9f747de8..612fffe100a 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -151,6 +151,12 @@ config LIBERTAS_SDIO
---help---
A driver for Marvell Libertas 8385 and 8686 SDIO devices.
+config LIBERTAS_SPI
+ tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
+ depends on LIBERTAS && SPI && GENERIC_GPIO
+ ---help---
+ A driver for Marvell Libertas 8686 SPI devices.
+
config LIBERTAS_DEBUG
bool "Enable full debugging output in the Libertas module."
depends on LIBERTAS
@@ -188,127 +194,6 @@ config AIRO
The driver can be compiled as a module and will be named "airo".
-config HERMES
- tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
- depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
- select WIRELESS_EXT
- select FW_LOADER
- select CRYPTO
- select CRYPTO_MICHAEL_MIC
- ---help---
- A driver for 802.11b wireless cards based on the "Hermes" or
- Intersil HFA384x (Prism 2) MAC controller. This includes the vast
- majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
- - except for the Cisco/Aironet cards. Cards supported include the
- Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
- Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
- IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
- MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
- IPW2011, and Symbol Spectrum24 High Rate amongst others.
-
- This option includes the guts of the driver, but in order to
- actually use a card you will also need to enable support for PCMCIA
- Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
-
- You will also very likely also need the Wireless Tools in order to
- configure your card and that /etc/pcmcia/wireless.opts works :
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
-
-config HERMES_CACHE_FW_ON_INIT
- bool "Cache Hermes firmware on driver initialisation"
- depends on HERMES
- default y
- ---help---
- Say Y to cache any firmware required by the Hermes drivers
- on startup. The firmware will remain cached until the
- driver is unloaded. The cache uses 64K of RAM.
-
- Otherwise load the firmware from userspace as required. In
- this case the driver should be unloaded and restarted
- whenever the firmware is changed.
-
- If you are not sure, say Y.
-
-config APPLE_AIRPORT
- tristate "Apple Airport support (built-in)"
- depends on PPC_PMAC && HERMES
- help
- Say Y here to support the Airport 802.11b wireless Ethernet hardware
- built into the Macintosh iBook and other recent PowerPC-based
- Macintosh machines. This is essentially a Lucent Orinoco card with
- a non-standard interface.
-
- This driver does not support the Airport Extreme (802.11b/g). Use
- the BCM43xx driver for Airport Extreme cards.
-
-config PLX_HERMES
- tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
- depends on PCI && HERMES
- help
- Enable support for PCMCIA cards supported by the "Hermes" (aka
- orinoco) driver when used in PLX9052 based PCI adaptors. These
- adaptors are not a full PCMCIA controller but act as a more limited
- PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
- 802.11b PCMCIA cards can be used in desktop machines. The Netgear
- MA301 is such an adaptor.
-
-config TMD_HERMES
- tristate "Hermes in TMD7160 based PCI adaptor support"
- depends on PCI && HERMES
- help
- Enable support for PCMCIA cards supported by the "Hermes" (aka
- orinoco) driver when used in TMD7160 based PCI adaptors. These
- adaptors are not a full PCMCIA controller but act as a more limited
- PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
- 802.11b PCMCIA cards can be used in desktop machines.
-
-config NORTEL_HERMES
- tristate "Nortel emobility PCI adaptor support"
- depends on PCI && HERMES
- help
- Enable support for PCMCIA cards supported by the "Hermes" (aka
- orinoco) driver when used in Nortel emobility PCI adaptors. These
- adaptors are not full PCMCIA controllers, but act as a more limited
- PCI <-> PCMCIA bridge.
-
-config PCI_HERMES
- tristate "Prism 2.5 PCI 802.11b adaptor support"
- depends on PCI && HERMES
- help
- Enable support for PCI and mini-PCI 802.11b wireless NICs based on
- the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
- PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
- common. Some of the built-in wireless adaptors in laptops are of
- this variety.
-
-config PCMCIA_HERMES
- tristate "Hermes PCMCIA card support"
- depends on PCMCIA && HERMES
- ---help---
- A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
- as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
- EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and
- others). It should also be usable on various Prism II based cards
- such as the Linksys, D-Link and Farallon Skyline. It should also
- work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN.
-
- You will very likely need the Wireless Tools in order to
- configure your card and that /etc/pcmcia/wireless.opts works:
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
-
-config PCMCIA_SPECTRUM
- tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
- depends on PCMCIA && HERMES
- ---help---
-
- This is a driver for 802.11b cards using RAM-loadable Symbol
- firmware, such as Symbol Wireless Networker LA4100, CompactFlash
- cards by Socket Communications and Intel PRO/Wireless 2011B.
-
- This driver requires firmware download on startup. Utilities
- for downloading Symbol firmware are available at
- <http://sourceforge.net/projects/orinoco/>
-
config ATMEL
tristate "Atmel at76c50x chipset 802.11b support"
depends on (PCI || PCMCIA) && WLAN_80211
@@ -343,6 +228,14 @@ config PCMCIA_ATMEL
Enable support for PCMCIA cards containing the
Atmel at76c502 and at76c504 chips.
+config AT76C50X_USB
+ tristate "Atmel at76c503/at76c505/at76c505a USB cards"
+ depends on MAC80211 && WLAN_80211 && USB
+ select FW_LOADER
+ ---help---
+ Enable support for USB Wireless devices using Atmel at76c503,
+ at76c505 or at76c505a chips.
+
config AIRO_CS
tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
depends on PCMCIA && (BROKEN || !M32R) && WLAN_80211
@@ -580,6 +473,15 @@ config MAC80211_HWSIM
To compile this driver as a module, choose M here: the module will be
called mac80211_hwsim. If unsure, say N.
+config MWL8K
+ tristate "Marvell 88W8xxx PCI/PCIe Wireless support"
+ depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
+ ---help---
+ This driver supports Marvell TOPDOG 802.11 wireless cards.
+
+ To compile this driver as a module, choose M here: the module
+ 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"
@@ -590,5 +492,6 @@ source "drivers/net/wireless/b43/Kconfig"
source "drivers/net/wireless/b43legacy/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
+source "drivers/net/wireless/orinoco/Kconfig"
endmenu
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index ac590e1ca8b..d780487c420 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -24,6 +24,8 @@ obj-$(CONFIG_ATMEL) += atmel.o
obj-$(CONFIG_PCI_ATMEL) += atmel_pci.o
obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
+obj-$(CONFIG_AT76C50X_USB) += at76c50x-usb.o
+
obj-$(CONFIG_PRISM54) += prism54/
obj-$(CONFIG_HOSTAP) += hostap/
@@ -46,6 +48,8 @@ obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/
obj-$(CONFIG_ADM8211) += adm8211.o
+obj-$(CONFIG_MWL8K) += mwl8k.o
+
obj-$(CONFIG_IWLWIFI) += iwlwifi/
obj-$(CONFIG_RT2X00) += rt2x00/
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index fc4322ca669..7e80aba8a14 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -496,39 +496,41 @@ typedef struct {
* so all rid access should use the read/writeXXXRid routines.
*/
-/* This is redundant for x86 archs, but it seems necessary for ARM */
-#pragma pack(1)
-
/* This structure came from an email sent to me from an engineer at
aironet for inclusion into this driver */
-typedef struct {
+typedef struct WepKeyRid WepKeyRid;
+struct WepKeyRid {
__le16 len;
__le16 kindex;
u8 mac[ETH_ALEN];
__le16 klen;
u8 key[16];
-} WepKeyRid;
+} __attribute__ ((packed));
/* These structures are from the Aironet's PC4500 Developers Manual */
-typedef struct {
+typedef struct Ssid Ssid;
+struct Ssid {
__le16 len;
u8 ssid[32];
-} Ssid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct SsidRid SsidRid;
+struct SsidRid {
__le16 len;
Ssid ssids[3];
-} SsidRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct ModulationRid ModulationRid;
+struct ModulationRid {
__le16 len;
__le16 modulation;
#define MOD_DEFAULT cpu_to_le16(0)
#define MOD_CCK cpu_to_le16(1)
#define MOD_MOK cpu_to_le16(2)
-} ModulationRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct ConfigRid ConfigRid;
+struct ConfigRid {
__le16 len; /* sizeof(ConfigRid) */
__le16 opmode; /* operating mode */
#define MODE_STA_IBSS cpu_to_le16(0)
@@ -649,9 +651,10 @@ typedef struct {
#define MAGIC_STAY_IN_CAM (1<<10)
u8 magicControl;
__le16 autoWake;
-} ConfigRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct StatusRid StatusRid;
+struct StatusRid {
__le16 len;
u8 mac[ETH_ALEN];
__le16 mode;
@@ -707,21 +710,23 @@ typedef struct {
#define STAT_LEAPFAILED 91
#define STAT_LEAPTIMEDOUT 92
#define STAT_LEAPCOMPLETE 93
-} StatusRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct StatsRid StatsRid;
+struct StatsRid {
__le16 len;
__le16 spacer;
__le32 vals[100];
-} StatsRid;
-
+} __attribute__ ((packed));
-typedef struct {
+typedef struct APListRid APListRid;
+struct APListRid {
__le16 len;
u8 ap[4][ETH_ALEN];
-} APListRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct CapabilityRid CapabilityRid;
+struct CapabilityRid {
__le16 len;
char oui[3];
char zero;
@@ -748,17 +753,18 @@ typedef struct {
__le16 bootBlockVer;
__le16 requiredHard;
__le16 extSoftCap;
-} CapabilityRid;
-
+} __attribute__ ((packed));
/* Only present on firmware >= 5.30.17 */
-typedef struct {
+typedef struct BSSListRidExtra BSSListRidExtra;
+struct BSSListRidExtra {
__le16 unknown[4];
u8 fixed[12]; /* WLAN management frame */
u8 iep[624];
-} BSSListRidExtra;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct BSSListRid BSSListRid;
+struct BSSListRid {
__le16 len;
__le16 index; /* First is 0 and 0xffff means end of list */
#define RADIO_FH 1 /* Frequency hopping radio type */
@@ -789,33 +795,37 @@ typedef struct {
/* Only present on firmware >= 5.30.17 */
BSSListRidExtra extra;
-} BSSListRid;
+} __attribute__ ((packed));
typedef struct {
BSSListRid bss;
struct list_head list;
} BSSListElement;
-typedef struct {
+typedef struct tdsRssiEntry tdsRssiEntry;
+struct tdsRssiEntry {
u8 rssipct;
u8 rssidBm;
-} tdsRssiEntry;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct tdsRssiRid tdsRssiRid;
+struct tdsRssiRid {
u16 len;
tdsRssiEntry x[256];
-} tdsRssiRid;
+} __attribute__ ((packed));
-typedef struct {
- u16 len;
- u16 state;
- u16 multicastValid;
+typedef struct MICRid MICRid;
+struct MICRid {
+ __le16 len;
+ __le16 state;
+ __le16 multicastValid;
u8 multicast[16];
- u16 unicastValid;
+ __le16 unicastValid;
u8 unicast[16];
-} MICRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct MICBuffer MICBuffer;
+struct MICBuffer {
__be16 typelen;
union {
@@ -830,15 +840,13 @@ typedef struct {
} u;
__be32 mic;
__be32 seq;
-} MICBuffer;
+} __attribute__ ((packed));
typedef struct {
u8 da[ETH_ALEN];
u8 sa[ETH_ALEN];
} etherHead;
-#pragma pack()
-
#define TXCTL_TXOK (1<<1) /* report if tx is ok */
#define TXCTL_TXEX (1<<2) /* report if tx fails */
#define TXCTL_802_3 (0<<3) /* 802.3 packet */
@@ -981,6 +989,14 @@ typedef struct {
dma_addr_t host_addr;
} TxFid;
+struct rx_hdr {
+ __le16 status, len;
+ u8 rssi[2];
+ u8 rate;
+ u8 freq;
+ __le16 tmp[4];
+} __attribute__ ((packed));
+
typedef struct {
unsigned int ctl: 15;
unsigned int rdy: 1;
@@ -1070,10 +1086,6 @@ static WifiCtlHdr wifictlhdr8023 = {
}
};
-// Frequency list (map channels to frequencies)
-static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
// A few details needed for WEP (Wireless Equivalent Privacy)
#define MAX_KEY_SIZE 13 // 128 (?) bits
#define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP
@@ -1082,12 +1094,6 @@ typedef struct wep_key_t {
u8 key[16]; /* 40-bit and 104-bit keys */
} wep_key_t;
-/* Backward compatibility */
-#ifndef IW_ENCODE_NOKEY
-#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
-#define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
-#endif /* IW_ENCODE_NOKEY */
-
/* List of Wireless Handlers (new API) */
static const struct iw_handler_def airo_handler_def;
@@ -1155,7 +1161,7 @@ struct airo_info {
use the high bit to mark whether it is in use. */
#define MAX_FIDS 6
#define MPI_MAX_FIDS 1
- int fids[MAX_FIDS];
+ u32 fids[MAX_FIDS];
ConfigRid config;
char keyindex; // Used with auto wep
char defindex; // Used with auto wep
@@ -1229,6 +1235,9 @@ struct airo_info {
#define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
char proc_name[IFNAMSIZ];
+ int wep_capable;
+ int max_wep_idx;
+
/* WPA-related stuff */
unsigned int bssListFirst;
unsigned int bssListNext;
@@ -1287,6 +1296,29 @@ static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
static void emmh32_final(emmh32_context *context, u8 digest[4]);
static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
+static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len,
+ struct crypto_cipher *tfm)
+{
+ /* If the current MIC context is valid and its key is the same as
+ * the MIC register, there's nothing to do.
+ */
+ if (cur->valid && (memcmp(cur->key, key, key_len) == 0))
+ return;
+
+ /* Age current mic Context */
+ memcpy(old, cur, sizeof(*cur));
+
+ /* Initialize new context */
+ memcpy(cur->key, key, key_len);
+ cur->window = 33; /* Window always points to the middle */
+ cur->rx = 0; /* Rx Sequence numbers */
+ cur->tx = 0; /* Tx sequence numbers */
+ cur->valid = 1; /* Key is now valid */
+
+ /* Give key to mic seed */
+ emmh32_setseed(&cur->seed, key, key_len, tfm);
+}
+
/* micinit - Initialize mic seed */
static void micinit(struct airo_info *ai)
@@ -1297,49 +1329,26 @@ static void micinit(struct airo_info *ai)
PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
up(&ai->sem);
- ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0;
-
- if (ai->micstats.enabled) {
- /* Key must be valid and different */
- if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid ||
- (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast,
- sizeof(ai->mod[0].mCtx.key)) != 0))) {
- /* Age current mic Context */
- memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx));
- /* Initialize new context */
- memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast));
- ai->mod[0].mCtx.window = 33; //Window always points to the middle
- ai->mod[0].mCtx.rx = 0; //Rx Sequence numbers
- ai->mod[0].mCtx.tx = 0; //Tx sequence numbers
- ai->mod[0].mCtx.valid = 1; //Key is now valid
-
- /* Give key to mic seed */
- emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm);
- }
-
- /* Key must be valid and different */
- if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid ||
- (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast,
- sizeof(ai->mod[0].uCtx.key)) != 0))) {
- /* Age current mic Context */
- memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx));
- /* Initialize new context */
- memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast));
-
- ai->mod[0].uCtx.window = 33; //Window always points to the middle
- ai->mod[0].uCtx.rx = 0; //Rx Sequence numbers
- ai->mod[0].uCtx.tx = 0; //Tx sequence numbers
- ai->mod[0].uCtx.valid = 1; //Key is now valid
-
- //Give key to mic seed
- emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm);
- }
- } else {
- /* So next time we have a valid key and mic is enabled, we will update
- * the sequence number if the key is the same as before.
- */
+ ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
+ if (!ai->micstats.enabled) {
+ /* So next time we have a valid key and mic is enabled, we will
+ * update the sequence number if the key is the same as before.
+ */
ai->mod[0].uCtx.valid = 0;
ai->mod[0].mCtx.valid = 0;
+ return;
+ }
+
+ if (mic_rid.multicastValid) {
+ age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx,
+ mic_rid.multicast, sizeof(mic_rid.multicast),
+ ai->tfm);
+ }
+
+ if (mic_rid.unicastValid) {
+ age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx,
+ mic_rid.unicast, sizeof(mic_rid.unicast),
+ ai->tfm);
}
}
@@ -2637,17 +2646,21 @@ static const struct header_ops airo_header_ops = {
.parse = wll_header_parse,
};
+static const struct net_device_ops airo11_netdev_ops = {
+ .ndo_open = airo_open,
+ .ndo_stop = airo_close,
+ .ndo_start_xmit = airo_start_xmit11,
+ .ndo_get_stats = airo_get_stats,
+ .ndo_set_mac_address = airo_set_mac_address,
+ .ndo_do_ioctl = airo_ioctl,
+ .ndo_change_mtu = airo_change_mtu,
+};
+
static void wifi_setup(struct net_device *dev)
{
+ dev->netdev_ops = &airo11_netdev_ops;
dev->header_ops = &airo_header_ops;
- dev->hard_start_xmit = &airo_start_xmit11;
- dev->get_stats = &airo_get_stats;
- dev->set_mac_address = &airo_set_mac_address;
- dev->do_ioctl = &airo_ioctl;
dev->wireless_handlers = &airo_handler_def;
- dev->change_mtu = &airo_change_mtu;
- dev->open = &airo_open;
- dev->stop = &airo_close;
dev->type = ARPHRD_IEEE80211;
dev->hard_header_len = ETH_HLEN;
@@ -2730,27 +2743,32 @@ static void airo_networks_initialize(struct airo_info *ai)
&ai->network_free_list);
}
-static int airo_test_wpa_capable(struct airo_info *ai)
-{
- int status;
- CapabilityRid cap_rid;
-
- status = readCapabilityRid(ai, &cap_rid, 1);
- if (status != SUCCESS) return 0;
+static const struct net_device_ops airo_netdev_ops = {
+ .ndo_open = airo_open,
+ .ndo_stop = airo_close,
+ .ndo_start_xmit = airo_start_xmit,
+ .ndo_get_stats = airo_get_stats,
+ .ndo_set_multicast_list = airo_set_multicast_list,
+ .ndo_set_mac_address = airo_set_mac_address,
+ .ndo_do_ioctl = airo_ioctl,
+ .ndo_change_mtu = airo_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
- /* Only firmware versions 5.30.17 or better can do WPA */
- if (le16_to_cpu(cap_rid.softVer) > 0x530
- || (le16_to_cpu(cap_rid.softVer) == 0x530
- && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
- airo_print_info("", "WPA is supported.");
- return 1;
- }
+static const struct net_device_ops mpi_netdev_ops = {
+ .ndo_open = airo_open,
+ .ndo_stop = airo_close,
+ .ndo_start_xmit = mpi_start_xmit,
+ .ndo_get_stats = airo_get_stats,
+ .ndo_set_multicast_list = airo_set_multicast_list,
+ .ndo_set_mac_address = airo_set_mac_address,
+ .ndo_do_ioctl = airo_ioctl,
+ .ndo_change_mtu = airo_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
- /* No WPA support */
- airo_print_info("", "WPA unsupported (only firmware versions 5.30.17"
- " and greater support WPA. Detected %s)", cap_rid.prodVer);
- return 0;
-}
static struct net_device *_init_airo_card( unsigned short irq, int port,
int is_pcmcia, struct pci_dev *pci,
@@ -2759,6 +2777,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
struct net_device *dev;
struct airo_info *ai;
int i, rc;
+ CapabilityRid cap_rid;
/* Create the network device object. */
dev = alloc_netdev(sizeof(*ai), "", ether_setup);
@@ -2788,22 +2807,16 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
goto err_out_free;
airo_networks_initialize (ai);
+ skb_queue_head_init (&ai->txq);
+
/* The Airo-specific entries in the device structure. */
- if (test_bit(FLAG_MPI,&ai->flags)) {
- skb_queue_head_init (&ai->txq);
- dev->hard_start_xmit = &mpi_start_xmit;
- } else
- dev->hard_start_xmit = &airo_start_xmit;
- dev->get_stats = &airo_get_stats;
- dev->set_multicast_list = &airo_set_multicast_list;
- dev->set_mac_address = &airo_set_mac_address;
- dev->do_ioctl = &airo_ioctl;
+ if (test_bit(FLAG_MPI,&ai->flags))
+ dev->netdev_ops = &mpi_netdev_ops;
+ else
+ dev->netdev_ops = &airo_netdev_ops;
dev->wireless_handlers = &airo_handler_def;
ai->wireless_data.spy_data = &ai->spy_data;
dev->wireless_data = &ai->wireless_data;
- dev->change_mtu = &airo_change_mtu;
- dev->open = &airo_open;
- dev->stop = &airo_close;
dev->irq = irq;
dev->base_addr = port;
@@ -2828,7 +2841,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
}
if (probe) {
- if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
+ if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
airo_print_err(dev->name, "MAC could not be enabled" );
rc = -EIO;
goto err_out_map;
@@ -2838,28 +2851,50 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
set_bit(FLAG_FLASHING, &ai->flags);
}
+ strcpy(dev->name, "eth%d");
+ rc = register_netdev(dev);
+ if (rc) {
+ airo_print_err(dev->name, "Couldn't register_netdev");
+ goto err_out_map;
+ }
+ ai->wifidev = init_wifidev(ai, dev);
+ if (!ai->wifidev)
+ goto err_out_reg;
+
+ rc = readCapabilityRid(ai, &cap_rid, 1);
+ if (rc != SUCCESS) {
+ rc = -EIO;
+ goto err_out_wifi;
+ }
+ /* WEP capability discovery */
+ ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
+ ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
+
+ airo_print_info(dev->name, "Firmware version %x.%x.%02x",
+ ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
+ (le16_to_cpu(cap_rid.softVer) & 0xFF),
+ le16_to_cpu(cap_rid.softSubVer));
+
/* Test for WPA support */
- if (airo_test_wpa_capable(ai)) {
+ /* Only firmware versions 5.30.17 or better can do WPA */
+ if (le16_to_cpu(cap_rid.softVer) > 0x530
+ || (le16_to_cpu(cap_rid.softVer) == 0x530
+ && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
+ airo_print_info(ai->dev->name, "WPA supported.");
+
set_bit(FLAG_WPA_CAPABLE, &ai->flags);
ai->bssListFirst = RID_WPA_BSSLISTFIRST;
ai->bssListNext = RID_WPA_BSSLISTNEXT;
ai->bssListRidLen = sizeof(BSSListRid);
} else {
+ airo_print_info(ai->dev->name, "WPA unsupported with firmware "
+ "versions older than 5.30.17.");
+
ai->bssListFirst = RID_BSSLISTFIRST;
ai->bssListNext = RID_BSSLISTNEXT;
ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
}
- strcpy(dev->name, "eth%d");
- rc = register_netdev(dev);
- if (rc) {
- airo_print_err(dev->name, "Couldn't register_netdev");
- goto err_out_map;
- }
- ai->wifidev = init_wifidev(ai, dev);
- if (!ai->wifidev)
- goto err_out_reg;
-
set_bit(FLAG_REGISTERED,&ai->flags);
airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
@@ -3127,314 +3162,354 @@ static int header_len(__le16 ctl)
return 24;
}
-static irqreturn_t airo_interrupt(int irq, void *dev_id)
+static void airo_handle_cisco_mic(struct airo_info *ai)
{
- struct net_device *dev = dev_id;
+ if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
+ set_bit(JOB_MIC, &ai->jobs);
+ wake_up_interruptible(&ai->thr_wait);
+ }
+}
+
+/* Airo Status codes */
+#define STAT_NOBEACON 0x8000 /* Loss of sync - missed beacons */
+#define STAT_MAXRETRIES 0x8001 /* Loss of sync - max retries */
+#define STAT_MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
+#define STAT_FORCELOSS 0x8003 /* Loss of sync - host request */
+#define STAT_TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
+#define STAT_DEAUTH 0x8100 /* low byte is 802.11 reason code */
+#define STAT_DISASSOC 0x8200 /* low byte is 802.11 reason code */
+#define STAT_ASSOC_FAIL 0x8400 /* low byte is 802.11 reason code */
+#define STAT_AUTH_FAIL 0x0300 /* low byte is 802.11 reason code */
+#define STAT_ASSOC 0x0400 /* Associated */
+#define STAT_REASSOC 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
+
+static void airo_print_status(const char *devname, u16 status)
+{
+ u8 reason = status & 0xFF;
+
+ switch (status) {
+ case STAT_NOBEACON:
+ airo_print_dbg(devname, "link lost (missed beacons)");
+ break;
+ case STAT_MAXRETRIES:
+ case STAT_MAXARL:
+ airo_print_dbg(devname, "link lost (max retries)");
+ break;
+ case STAT_FORCELOSS:
+ airo_print_dbg(devname, "link lost (local choice)");
+ break;
+ case STAT_TSFSYNC:
+ airo_print_dbg(devname, "link lost (TSF sync lost)");
+ break;
+ case STAT_DEAUTH:
+ airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
+ break;
+ case STAT_DISASSOC:
+ airo_print_dbg(devname, "disassociated (reason: %d)", reason);
+ break;
+ case STAT_ASSOC_FAIL:
+ airo_print_dbg(devname, "association failed (reason: %d)",
+ reason);
+ break;
+ case STAT_AUTH_FAIL:
+ airo_print_dbg(devname, "authentication failed (reason: %d)",
+ reason);
+ break;
+ default:
+ break;
+ }
+}
+
+static void airo_handle_link(struct airo_info *ai)
+{
+ union iwreq_data wrqu;
+ int scan_forceloss = 0;
u16 status;
- u16 fid;
- struct airo_info *apriv = dev->ml_priv;
- u16 savedInterrupts = 0;
- int handled = 0;
- if (!netif_device_present(dev))
- return IRQ_NONE;
+ /* Get new status and acknowledge the link change */
+ status = le16_to_cpu(IN4500(ai, LINKSTAT));
+ OUT4500(ai, EVACK, EV_LINK);
- for (;;) {
- status = IN4500( apriv, EVSTAT );
- if ( !(status & STATUS_INTS) || status == 0xffff ) break;
+ if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
+ scan_forceloss = 1;
- handled = 1;
+ airo_print_status(ai->dev->name, status);
- if ( status & EV_AWAKE ) {
- OUT4500( apriv, EVACK, EV_AWAKE );
- OUT4500( apriv, EVACK, EV_AWAKE );
- }
+ if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
+ if (auto_wep)
+ ai->expires = 0;
+ if (ai->list_bss_task)
+ wake_up_process(ai->list_bss_task);
+ set_bit(FLAG_UPDATE_UNI, &ai->flags);
+ set_bit(FLAG_UPDATE_MULTI, &ai->flags);
- if (!savedInterrupts) {
- savedInterrupts = IN4500( apriv, EVINTEN );
- OUT4500( apriv, EVINTEN, 0 );
+ if (down_trylock(&ai->sem) != 0) {
+ set_bit(JOB_EVENT, &ai->jobs);
+ wake_up_interruptible(&ai->thr_wait);
+ } else
+ airo_send_event(ai->dev);
+ } else if (!scan_forceloss) {
+ if (auto_wep && !ai->expires) {
+ ai->expires = RUN_AT(3*HZ);
+ wake_up_interruptible(&ai->thr_wait);
}
- if ( status & EV_MIC ) {
- OUT4500( apriv, EVACK, EV_MIC );
- if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
- set_bit(JOB_MIC, &apriv->jobs);
- wake_up_interruptible(&apriv->thr_wait);
- }
- }
- if ( status & EV_LINK ) {
- union iwreq_data wrqu;
- int scan_forceloss = 0;
- /* The link status has changed, if you want to put a
- monitor hook in, do it here. (Remember that
- interrupts are still disabled!)
- */
- u16 newStatus = IN4500(apriv, LINKSTAT);
- OUT4500( apriv, EVACK, EV_LINK);
- /* Here is what newStatus means: */
-#define NOBEACON 0x8000 /* Loss of sync - missed beacons */
-#define MAXRETRIES 0x8001 /* Loss of sync - max retries */
-#define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
-#define FORCELOSS 0x8003 /* Loss of sync - host request */
-#define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
-#define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
-#define DISASS 0x8200 /* Disassociation (low byte is reason code) */
-#define ASSFAIL 0x8400 /* Association failure (low byte is reason
- code) */
-#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
- code) */
-#define ASSOCIATED 0x0400 /* Associated */
-#define REASSOCIATED 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
-#define RC_RESERVED 0 /* Reserved return code */
-#define RC_NOREASON 1 /* Unspecified reason */
-#define RC_AUTHINV 2 /* Previous authentication invalid */
-#define RC_DEAUTH 3 /* Deauthenticated because sending station is
- leaving */
-#define RC_NOACT 4 /* Disassociated due to inactivity */
-#define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
- all currently associated stations */
-#define RC_BADCLASS2 6 /* Class 2 frame received from
- non-Authenticated station */
-#define RC_BADCLASS3 7 /* Class 3 frame received from
- non-Associated station */
-#define RC_STATLEAVE 8 /* Disassociated because sending station is
- leaving BSS */
-#define RC_NOAUTH 9 /* Station requesting (Re)Association is not
- Authenticated with the responding station */
- if (newStatus == FORCELOSS && apriv->scan_timeout > 0)
- scan_forceloss = 1;
- if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
- if (auto_wep)
- apriv->expires = 0;
- if (apriv->list_bss_task)
- wake_up_process(apriv->list_bss_task);
- set_bit(FLAG_UPDATE_UNI, &apriv->flags);
- set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
-
- if (down_trylock(&apriv->sem) != 0) {
- set_bit(JOB_EVENT, &apriv->jobs);
- wake_up_interruptible(&apriv->thr_wait);
- } else
- airo_send_event(dev);
- } else if (!scan_forceloss) {
- if (auto_wep && !apriv->expires) {
- apriv->expires = RUN_AT(3*HZ);
- wake_up_interruptible(&apriv->thr_wait);
- }
+ /* Send event to user space */
+ memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
+ }
+}
- /* Send event to user space */
- memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
- }
- }
+static void airo_handle_rx(struct airo_info *ai)
+{
+ struct sk_buff *skb = NULL;
+ __le16 fc, v, *buffer, tmpbuf[4];
+ u16 len, hdrlen = 0, gap, fid;
+ struct rx_hdr hdr;
+ int success = 0;
- /* Check to see if there is something to receive */
- if ( status & EV_RX ) {
- struct sk_buff *skb = NULL;
- __le16 fc, v;
- u16 len, hdrlen = 0;
-#pragma pack(1)
- struct {
- __le16 status, len;
- u8 rssi[2];
- u8 rate;
- u8 freq;
- __le16 tmp[4];
- } hdr;
-#pragma pack()
- u16 gap;
- __le16 tmpbuf[4];
- __le16 *buffer;
-
- if (test_bit(FLAG_MPI,&apriv->flags)) {
- if (test_bit(FLAG_802_11, &apriv->flags))
- mpi_receive_802_11(apriv);
- else
- mpi_receive_802_3(apriv);
- OUT4500(apriv, EVACK, EV_RX);
- goto exitrx;
- }
+ if (test_bit(FLAG_MPI, &ai->flags)) {
+ if (test_bit(FLAG_802_11, &ai->flags))
+ mpi_receive_802_11(ai);
+ else
+ mpi_receive_802_3(ai);
+ OUT4500(ai, EVACK, EV_RX);
+ return;
+ }
- fid = IN4500( apriv, RXFID );
-
- /* Get the packet length */
- if (test_bit(FLAG_802_11, &apriv->flags)) {
- bap_setup (apriv, fid, 4, BAP0);
- bap_read (apriv, (__le16*)&hdr, sizeof(hdr), BAP0);
- /* Bad CRC. Ignore packet */
- if (le16_to_cpu(hdr.status) & 2)
- hdr.len = 0;
- if (apriv->wifidev == NULL)
- hdr.len = 0;
- } else {
- bap_setup (apriv, fid, 0x36, BAP0);
- bap_read (apriv, &hdr.len, 2, BAP0);
- }
- len = le16_to_cpu(hdr.len);
+ fid = IN4500(ai, RXFID);
- if (len > AIRO_DEF_MTU) {
- airo_print_err(apriv->dev->name, "Bad size %d", len);
- goto badrx;
- }
- if (len == 0)
- goto badrx;
+ /* Get the packet length */
+ if (test_bit(FLAG_802_11, &ai->flags)) {
+ bap_setup (ai, fid, 4, BAP0);
+ bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
+ /* Bad CRC. Ignore packet */
+ if (le16_to_cpu(hdr.status) & 2)
+ hdr.len = 0;
+ if (ai->wifidev == NULL)
+ hdr.len = 0;
+ } else {
+ bap_setup(ai, fid, 0x36, BAP0);
+ bap_read(ai, &hdr.len, 2, BAP0);
+ }
+ len = le16_to_cpu(hdr.len);
- if (test_bit(FLAG_802_11, &apriv->flags)) {
- bap_read (apriv, &fc, sizeof(fc), BAP0);
- hdrlen = header_len(fc);
- } else
- hdrlen = ETH_ALEN * 2;
+ if (len > AIRO_DEF_MTU) {
+ airo_print_err(ai->dev->name, "Bad size %d", len);
+ goto done;
+ }
+ if (len == 0)
+ goto done;
- skb = dev_alloc_skb( len + hdrlen + 2 + 2 );
- if ( !skb ) {
- dev->stats.rx_dropped++;
- goto badrx;
- }
- skb_reserve(skb, 2); /* This way the IP header is aligned */
- buffer = (__le16*)skb_put (skb, len + hdrlen);
- if (test_bit(FLAG_802_11, &apriv->flags)) {
- buffer[0] = fc;
- bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
- if (hdrlen == 24)
- bap_read (apriv, tmpbuf, 6, BAP0);
-
- bap_read (apriv, &v, sizeof(v), BAP0);
- gap = le16_to_cpu(v);
- if (gap) {
- if (gap <= 8) {
- bap_read (apriv, tmpbuf, gap, BAP0);
- } else {
- airo_print_err(apriv->dev->name, "gaplen too "
- "big. Problems will follow...");
- }
- }
- bap_read (apriv, buffer + hdrlen/2, len, BAP0);
+ if (test_bit(FLAG_802_11, &ai->flags)) {
+ bap_read(ai, &fc, sizeof (fc), BAP0);
+ hdrlen = header_len(fc);
+ } else
+ hdrlen = ETH_ALEN * 2;
+
+ skb = dev_alloc_skb(len + hdrlen + 2 + 2);
+ if (!skb) {
+ ai->dev->stats.rx_dropped++;
+ goto done;
+ }
+
+ skb_reserve(skb, 2); /* This way the IP header is aligned */
+ buffer = (__le16 *) skb_put(skb, len + hdrlen);
+ if (test_bit(FLAG_802_11, &ai->flags)) {
+ buffer[0] = fc;
+ bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
+ if (hdrlen == 24)
+ bap_read(ai, tmpbuf, 6, BAP0);
+
+ bap_read(ai, &v, sizeof(v), BAP0);
+ gap = le16_to_cpu(v);
+ if (gap) {
+ if (gap <= 8) {
+ bap_read(ai, tmpbuf, gap, BAP0);
} else {
- MICBuffer micbuf;
- bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
- if (apriv->micstats.enabled) {
- bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0);
- if (ntohs(micbuf.typelen) > 0x05DC)
- bap_setup (apriv, fid, 0x44, BAP0);
- else {
- if (len <= sizeof(micbuf))
- goto badmic;
-
- len -= sizeof(micbuf);
- skb_trim (skb, len + hdrlen);
- }
- }
- bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
- if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
-badmic:
- dev_kfree_skb_irq (skb);
-badrx:
- OUT4500( apriv, EVACK, EV_RX);
- goto exitrx;
+ airo_print_err(ai->dev->name, "gaplen too "
+ "big. Problems will follow...");
+ }
+ }
+ bap_read(ai, buffer + hdrlen/2, len, BAP0);
+ } else {
+ MICBuffer micbuf;
+
+ bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
+ if (ai->micstats.enabled) {
+ bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
+ if (ntohs(micbuf.typelen) > 0x05DC)
+ bap_setup(ai, fid, 0x44, BAP0);
+ else {
+ if (len <= sizeof (micbuf)) {
+ dev_kfree_skb_irq(skb);
+ goto done;
}
+
+ len -= sizeof(micbuf);
+ skb_trim(skb, len + hdrlen);
}
+ }
+
+ bap_read(ai, buffer + ETH_ALEN, len, BAP0);
+ if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
+ dev_kfree_skb_irq (skb);
+ else
+ success = 1;
+ }
+
#ifdef WIRELESS_SPY
- if (apriv->spy_data.spy_number > 0) {
- char *sa;
- struct iw_quality wstats;
- /* Prepare spy data : addr + qual */
- if (!test_bit(FLAG_802_11, &apriv->flags)) {
- sa = (char*)buffer + 6;
- bap_setup (apriv, fid, 8, BAP0);
- bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0);
- } else
- sa = (char*)buffer + 10;
- wstats.qual = hdr.rssi[0];
- if (apriv->rssi)
- wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
- else
- wstats.level = (hdr.rssi[1] + 321) / 2;
- wstats.noise = apriv->wstats.qual.noise;
- wstats.updated = IW_QUAL_LEVEL_UPDATED
- | IW_QUAL_QUAL_UPDATED
- | IW_QUAL_DBM;
- /* Update spy records */
- wireless_spy_update(dev, sa, &wstats);
- }
+ if (success && (ai->spy_data.spy_number > 0)) {
+ char *sa;
+ struct iw_quality wstats;
+
+ /* Prepare spy data : addr + qual */
+ if (!test_bit(FLAG_802_11, &ai->flags)) {
+ sa = (char *) buffer + 6;
+ bap_setup(ai, fid, 8, BAP0);
+ bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
+ } else
+ sa = (char *) buffer + 10;
+ wstats.qual = hdr.rssi[0];
+ if (ai->rssi)
+ wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
+ else
+ wstats.level = (hdr.rssi[1] + 321) / 2;
+ wstats.noise = ai->wstats.qual.noise;
+ wstats.updated = IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_DBM;
+ /* Update spy records */
+ wireless_spy_update(ai->dev, sa, &wstats);
+ }
#endif /* WIRELESS_SPY */
- OUT4500( apriv, EVACK, EV_RX);
- if (test_bit(FLAG_802_11, &apriv->flags)) {
- skb_reset_mac_header(skb);
- skb->pkt_type = PACKET_OTHERHOST;
- skb->dev = apriv->wifidev;
- skb->protocol = htons(ETH_P_802_2);
- } else
- skb->protocol = eth_type_trans(skb,dev);
- skb->ip_summed = CHECKSUM_NONE;
+done:
+ OUT4500(ai, EVACK, EV_RX);
+
+ if (success) {
+ if (test_bit(FLAG_802_11, &ai->flags)) {
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->dev = ai->wifidev;
+ skb->protocol = htons(ETH_P_802_2);
+ } else
+ skb->protocol = eth_type_trans(skb, ai->dev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ netif_rx(skb);
+ }
+}
+
+static void airo_handle_tx(struct airo_info *ai, u16 status)
+{
+ int i, len = 0, index = -1;
+ u16 fid;
- netif_rx( skb );
+ if (test_bit(FLAG_MPI, &ai->flags)) {
+ unsigned long flags;
+
+ if (status & EV_TXEXC)
+ get_tx_error(ai, -1);
+
+ spin_lock_irqsave(&ai->aux_lock, flags);
+ if (!skb_queue_empty(&ai->txq)) {
+ spin_unlock_irqrestore(&ai->aux_lock,flags);
+ mpi_send_packet(ai->dev);
+ } else {
+ clear_bit(FLAG_PENDING_XMIT, &ai->flags);
+ spin_unlock_irqrestore(&ai->aux_lock,flags);
+ netif_wake_queue(ai->dev);
}
-exitrx:
+ OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
+ return;
+ }
- /* Check to see if a packet has been transmitted */
- if ( status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {
- int i;
- int len = 0;
- int index = -1;
-
- if (test_bit(FLAG_MPI,&apriv->flags)) {
- unsigned long flags;
-
- if (status & EV_TXEXC)
- get_tx_error(apriv, -1);
- spin_lock_irqsave(&apriv->aux_lock, flags);
- if (!skb_queue_empty(&apriv->txq)) {
- spin_unlock_irqrestore(&apriv->aux_lock,flags);
- mpi_send_packet (dev);
- } else {
- clear_bit(FLAG_PENDING_XMIT, &apriv->flags);
- spin_unlock_irqrestore(&apriv->aux_lock,flags);
- netif_wake_queue (dev);
- }
- OUT4500( apriv, EVACK,
- status & (EV_TX|EV_TXCPY|EV_TXEXC));
- goto exittx;
- }
+ fid = IN4500(ai, TXCOMPLFID);
+
+ for(i = 0; i < MAX_FIDS; i++) {
+ if ((ai->fids[i] & 0xffff) == fid) {
+ len = ai->fids[i] >> 16;
+ index = i;
+ }
+ }
- fid = IN4500(apriv, TXCOMPLFID);
+ if (index != -1) {
+ if (status & EV_TXEXC)
+ get_tx_error(ai, index);
- for( i = 0; i < MAX_FIDS; i++ ) {
- if ( ( apriv->fids[i] & 0xffff ) == fid ) {
- len = apriv->fids[i] >> 16;
- index = i;
- }
- }
- if (index != -1) {
- if (status & EV_TXEXC)
- get_tx_error(apriv, index);
- OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
- /* Set up to be used again */
- apriv->fids[index] &= 0xffff;
- if (index < MAX_FIDS / 2) {
- if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))
- netif_wake_queue(dev);
- } else {
- if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))
- netif_wake_queue(apriv->wifidev);
- }
- } else {
- OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
- airo_print_err(apriv->dev->name, "Unallocated FID was "
- "used to xmit" );
- }
+ OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
+
+ /* Set up to be used again */
+ ai->fids[index] &= 0xffff;
+ if (index < MAX_FIDS / 2) {
+ if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
+ netif_wake_queue(ai->dev);
+ } else {
+ if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
+ netif_wake_queue(ai->wifidev);
+ }
+ } else {
+ OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
+ airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
+ }
+}
+
+static irqreturn_t airo_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ u16 status, savedInterrupts = 0;
+ struct airo_info *ai = dev->ml_priv;
+ int handled = 0;
+
+ if (!netif_device_present(dev))
+ return IRQ_NONE;
+
+ for (;;) {
+ status = IN4500(ai, EVSTAT);
+ if (!(status & STATUS_INTS) || (status == 0xffff))
+ break;
+
+ handled = 1;
+
+ if (status & EV_AWAKE) {
+ OUT4500(ai, EVACK, EV_AWAKE);
+ OUT4500(ai, EVACK, EV_AWAKE);
+ }
+
+ if (!savedInterrupts) {
+ savedInterrupts = IN4500(ai, EVINTEN);
+ OUT4500(ai, EVINTEN, 0);
+ }
+
+ if (status & EV_MIC) {
+ OUT4500(ai, EVACK, EV_MIC);
+ airo_handle_cisco_mic(ai);
}
-exittx:
- if ( status & ~STATUS_INTS & ~IGNORE_INTS )
- airo_print_warn(apriv->dev->name, "Got weird status %x",
+
+ if (status & EV_LINK) {
+ /* Link status changed */
+ airo_handle_link(ai);
+ }
+
+ /* Check to see if there is something to receive */
+ if (status & EV_RX)
+ airo_handle_rx(ai);
+
+ /* Check to see if a packet has been transmitted */
+ if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
+ airo_handle_tx(ai, status);
+
+ if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
+ airo_print_warn(ai->dev->name, "Got weird status %x",
status & ~STATUS_INTS & ~IGNORE_INTS );
+ }
}
if (savedInterrupts)
- OUT4500( apriv, EVINTEN, savedInterrupts );
+ OUT4500(ai, EVINTEN, savedInterrupts);
- /* done.. */
return IRQ_RETVAL(handled);
}
@@ -3613,18 +3688,10 @@ static void mpi_receive_802_11(struct airo_info *ai)
struct sk_buff *skb = NULL;
u16 len, hdrlen = 0;
__le16 fc;
-#pragma pack(1)
- struct {
- __le16 status, len;
- u8 rssi[2];
- u8 rate;
- u8 freq;
- __le16 tmp[4];
- } hdr;
-#pragma pack()
+ struct rx_hdr hdr;
u16 gap;
u16 *buffer;
- char *ptr = ai->rxfids[0].virtual_host_addr+4;
+ char *ptr = ai->rxfids[0].virtual_host_addr + 4;
memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
memcpy ((char *)&hdr, ptr, sizeof(hdr));
@@ -3691,6 +3758,7 @@ static void mpi_receive_802_11(struct airo_info *ai)
skb->protocol = htons(ETH_P_802_2);
skb->ip_summed = CHECKSUM_NONE;
netif_rx( skb );
+
badrx:
if (rxd.valid == 0) {
rxd.valid = 1;
@@ -3705,7 +3773,6 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
Cmd cmd;
Resp rsp;
int status;
- int i;
SsidRid mySsid;
__le16 lastindex;
WepKeyRid wkr;
@@ -3747,6 +3814,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
if (lock)
up(&ai->sem);
if (ai->config.len == 0) {
+ int i;
tdsRssiRid rssi_rid;
CapabilityRid cap_rid;
@@ -3794,14 +3862,12 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
/* Check to see if there are any insmod configured
rates to add */
if ( rates[0] ) {
- int i = 0;
memset(ai->config.rates,0,sizeof(ai->config.rates));
for( i = 0; i < 8 && rates[i]; i++ ) {
ai->config.rates[i] = rates[i];
}
}
if ( basic_rate > 0 ) {
- int i;
for( i = 0; i < 8; i++ ) {
if ( ai->config.rates[i] == basic_rate ||
!ai->config.rates ) {
@@ -4686,7 +4752,7 @@ static int proc_stats_rid_open( struct inode *inode,
StatsRid stats;
int i, j;
__le32 *vals = stats.vals;
- int len = le16_to_cpu(stats.len);
+ int len;
if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
@@ -4697,6 +4763,7 @@ static int proc_stats_rid_open( struct inode *inode,
}
readStatsRid(apriv, &stats, rid, 1);
+ len = le16_to_cpu(stats.len);
j = 0;
for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
@@ -5131,55 +5198,98 @@ static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
return rc;
}
-/* Returns the length of the key at the index. If index == 0xffff
- * the index of the transmit key is returned. If the key doesn't exist,
- * -1 will be returned.
+/* Returns the WEP key at the specified index, or -1 if that key does
+ * not exist. The buffer is assumed to be at least 16 bytes in length.
*/
-static int get_wep_key(struct airo_info *ai, u16 index) {
+static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
+{
WepKeyRid wkr;
int rc;
__le16 lastindex;
rc = readWepKeyRid(ai, &wkr, 1, 1);
- if (rc == SUCCESS) do {
+ if (rc != SUCCESS)
+ return -1;
+ do {
lastindex = wkr.kindex;
- if (wkr.kindex == cpu_to_le16(index)) {
- if (index == 0xffff) {
- return wkr.mac[0];
- }
- return le16_to_cpu(wkr.klen);
+ if (le16_to_cpu(wkr.kindex) == index) {
+ int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
+ memcpy(buf, wkr.key, klen);
+ return klen;
}
- readWepKeyRid(ai, &wkr, 0, 1);
+ rc = readWepKeyRid(ai, &wkr, 0, 1);
+ if (rc != SUCCESS)
+ return -1;
} while (lastindex != wkr.kindex);
return -1;
}
-static int set_wep_key(struct airo_info *ai, u16 index,
- const char *key, u16 keylen, int perm, int lock )
+static int get_wep_tx_idx(struct airo_info *ai)
+{
+ WepKeyRid wkr;
+ int rc;
+ __le16 lastindex;
+
+ rc = readWepKeyRid(ai, &wkr, 1, 1);
+ if (rc != SUCCESS)
+ return -1;
+ do {
+ lastindex = wkr.kindex;
+ if (wkr.kindex == cpu_to_le16(0xffff))
+ return wkr.mac[0];
+ rc = readWepKeyRid(ai, &wkr, 0, 1);
+ if (rc != SUCCESS)
+ return -1;
+ } while (lastindex != wkr.kindex);
+ return -1;
+}
+
+static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
+ u16 keylen, int perm, int lock)
{
static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
WepKeyRid wkr;
+ int rc;
- memset(&wkr, 0, sizeof(wkr));
if (keylen == 0) {
-// We are selecting which key to use
- wkr.len = cpu_to_le16(sizeof(wkr));
- wkr.kindex = cpu_to_le16(0xffff);
- wkr.mac[0] = (char)index;
- if (perm) ai->defindex = (char)index;
- } else {
-// We are actually setting the key
- wkr.len = cpu_to_le16(sizeof(wkr));
- wkr.kindex = cpu_to_le16(index);
- wkr.klen = cpu_to_le16(keylen);
- memcpy( wkr.key, key, keylen );
- memcpy( wkr.mac, macaddr, ETH_ALEN );
+ airo_print_err(ai->dev->name, "%s: key length to set was zero",
+ __func__);
+ return -1;
}
+ memset(&wkr, 0, sizeof(wkr));
+ wkr.len = cpu_to_le16(sizeof(wkr));
+ wkr.kindex = cpu_to_le16(index);
+ wkr.klen = cpu_to_le16(keylen);
+ memcpy(wkr.key, key, keylen);
+ memcpy(wkr.mac, macaddr, ETH_ALEN);
+
if (perm) disable_MAC(ai, lock);
- writeWepKeyRid(ai, &wkr, perm, lock);
+ rc = writeWepKeyRid(ai, &wkr, perm, lock);
if (perm) enable_MAC(ai, lock);
- return 0;
+ return rc;
+}
+
+static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
+{
+ WepKeyRid wkr;
+ int rc;
+
+ memset(&wkr, 0, sizeof(wkr));
+ wkr.len = cpu_to_le16(sizeof(wkr));
+ wkr.kindex = cpu_to_le16(0xffff);
+ wkr.mac[0] = (char)index;
+
+ if (perm) {
+ ai->defindex = (char)index;
+ disable_MAC(ai, lock);
+ }
+
+ rc = writeWepKeyRid(ai, &wkr, perm, lock);
+
+ if (perm)
+ enable_MAC(ai, lock);
+ return rc;
}
static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
@@ -5187,7 +5297,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
struct proc_dir_entry *dp = PDE(inode);
struct net_device *dev = dp->data;
struct airo_info *ai = dev->ml_priv;
- int i;
+ int i, rc;
char key[16];
u16 index = 0;
int j = 0;
@@ -5201,7 +5311,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
(data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
index = data->wbuffer[0] - '0';
if (data->wbuffer[1] == '\n') {
- set_wep_key(ai, index, NULL, 0, 1, 1);
+ rc = set_wep_tx_idx(ai, index, 1, 1);
+ if (rc < 0) {
+ airo_print_err(ai->dev->name, "failed to set "
+ "WEP transmit index to %d: %d.",
+ index, rc);
+ }
return;
}
j = 2;
@@ -5220,7 +5335,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
break;
}
}
- set_wep_key(ai, index, key, i/3, 1, 1);
+
+ rc = set_wep_key(ai, index, key, i/3, 1, 1);
+ if (rc < 0) {
+ airo_print_err(ai->dev->name, "failed to set WEP key at index "
+ "%d: %d.", index, rc);
+ }
}
static int proc_wepkey_open( struct inode *inode, struct file *file )
@@ -5451,13 +5571,13 @@ static void timer_func( struct net_device *dev ) {
break;
case AUTH_SHAREDKEY:
if (apriv->keyindex < auto_wep) {
- set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0);
+ set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
apriv->config.authType = AUTH_SHAREDKEY;
apriv->keyindex++;
} else {
/* Drop to ENCRYPT */
apriv->keyindex = 0;
- set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0);
+ set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
apriv->config.authType = AUTH_ENCRYPT;
}
break;
@@ -5725,16 +5845,12 @@ static int airo_set_freq(struct net_device *dev,
int rc = -EINPROGRESS; /* Call commit handler */
/* If setting by frequency, convert to a channel */
- if((fwrq->e == 1) &&
- (fwrq->m >= (int) 2.412e8) &&
- (fwrq->m <= (int) 2.487e8)) {
+ if(fwrq->e == 1) {
int f = fwrq->m / 100000;
- int c = 0;
- while((c < 14) && (f != frequency_list[c]))
- c++;
+
/* Hack to fall through... */
fwrq->e = 0;
- fwrq->m = c + 1;
+ fwrq->m = ieee80211_freq_to_dsss_chan(f);
}
/* Setting by channel number */
if((fwrq->m > 1000) || (fwrq->e > 0))
@@ -5778,7 +5894,7 @@ static int airo_get_freq(struct net_device *dev,
ch = le16_to_cpu(status_rid.channel);
if((ch > 0) && (ch < 15)) {
- fwrq->m = frequency_list[ch - 1] * 100000;
+ fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000;
fwrq->e = 1;
} else {
fwrq->m = ch;
@@ -6234,11 +6350,9 @@ static int airo_get_mode(struct net_device *dev,
return 0;
}
-static inline int valid_index(CapabilityRid *p, int index)
+static inline int valid_index(struct airo_info *ai, int index)
{
- if (index < 0)
- return 0;
- return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
+ return (index >= 0) && (index <= ai->max_wep_idx);
}
/*------------------------------------------------------------------*/
@@ -6251,16 +6365,13 @@ static int airo_set_encode(struct net_device *dev,
char *extra)
{
struct airo_info *local = dev->ml_priv;
- CapabilityRid cap_rid; /* Card capability info */
- int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
+ int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
__le16 currentAuthType = local->config.authType;
+ int rc = 0;
- /* Is WEP supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- /* Older firmware doesn't support this...
- if(!(cap_rid.softCap & cpu_to_le16(2))) {
+ if (!local->wep_capable)
return -EOPNOTSUPP;
- } */
+
readConfigRid(local, 1);
/* Basic checking: do we have a key to set ?
@@ -6272,14 +6383,21 @@ static int airo_set_encode(struct net_device *dev,
if (dwrq->length > 0) {
wep_key_t key;
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- int current_index = get_wep_key(local, 0xffff);
+ int current_index;
+
/* Check the size of the key */
if (dwrq->length > MAX_KEY_SIZE) {
return -EINVAL;
}
+
+ current_index = get_wep_tx_idx(local);
+ if (current_index < 0)
+ current_index = 0;
+
/* Check the index (none -> use current) */
- if (!valid_index(&cap_rid, index))
+ if (!valid_index(local, index))
index = current_index;
+
/* Set the length */
if (dwrq->length > MIN_KEY_SIZE)
key.len = MAX_KEY_SIZE;
@@ -6296,7 +6414,13 @@ static int airo_set_encode(struct net_device *dev,
/* Copy the key in the driver */
memcpy(key.key, extra, dwrq->length);
/* Send the key to the card */
- set_wep_key(local, index, key.key, key.len, perm, 1);
+ rc = set_wep_key(local, index, key.key, key.len, perm, 1);
+ if (rc < 0) {
+ airo_print_err(local->dev->name, "failed to set"
+ " WEP key at index %d: %d.",
+ index, rc);
+ return rc;
+ }
}
/* WE specify that if a valid key is set, encryption
* should be enabled (user may turn it off later)
@@ -6308,12 +6432,19 @@ static int airo_set_encode(struct net_device *dev,
} else {
/* Do we want to just set the transmit key index ? */
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- if (valid_index(&cap_rid, index)) {
- set_wep_key(local, index, NULL, 0, perm, 1);
- } else
+ if (valid_index(local, index)) {
+ rc = set_wep_tx_idx(local, index, perm, 1);
+ if (rc < 0) {
+ airo_print_err(local->dev->name, "failed to set"
+ " WEP transmit index to %d: %d.",
+ index, rc);
+ return rc;
+ }
+ } else {
/* Don't complain if only change the mode */
if (!(dwrq->flags & IW_ENCODE_MODE))
return -EINVAL;
+ }
}
/* Read the flags */
if(dwrq->flags & IW_ENCODE_DISABLED)
@@ -6339,14 +6470,13 @@ static int airo_get_encode(struct net_device *dev,
{
struct airo_info *local = dev->ml_priv;
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- CapabilityRid cap_rid; /* Card capability info */
+ u8 buf[16];
- /* Is it supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- if(!(cap_rid.softCap & cpu_to_le16(2))) {
+ if (!local->wep_capable)
return -EOPNOTSUPP;
- }
+
readConfigRid(local, 1);
+
/* Check encryption mode */
switch(local->config.authType) {
case AUTH_ENCRYPT:
@@ -6365,14 +6495,17 @@ static int airo_get_encode(struct net_device *dev,
memset(extra, 0, 16);
/* Which key do we want ? -1 -> tx index */
- if (!valid_index(&cap_rid, index))
- index = get_wep_key(local, 0xffff);
+ if (!valid_index(local, index)) {
+ index = get_wep_tx_idx(local);
+ if (index < 0)
+ index = 0;
+ }
dwrq->flags |= index + 1;
+
/* Copy the key to the user buffer */
- dwrq->length = get_wep_key(local, index);
- if (dwrq->length > 16) {
- dwrq->length=0;
- }
+ dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf));
+ memcpy(extra, buf, dwrq->length);
+
return 0;
}
@@ -6388,28 +6521,27 @@ static int airo_set_encodeext(struct net_device *dev,
struct airo_info *local = dev->ml_priv;
struct iw_point *encoding = &wrqu->encoding;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- CapabilityRid cap_rid; /* Card capability info */
int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
__le16 currentAuthType = local->config.authType;
- int idx, key_len, alg = ext->alg, set_key = 1;
+ int idx, key_len, alg = ext->alg, set_key = 1, rc;
wep_key_t key;
- /* Is WEP supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- /* Older firmware doesn't support this...
- if(!(cap_rid.softCap & cpu_to_le16(2))) {
+ if (!local->wep_capable)
return -EOPNOTSUPP;
- } */
+
readConfigRid(local, 1);
/* Determine and validate the key index */
idx = encoding->flags & IW_ENCODE_INDEX;
if (idx) {
- if (!valid_index(&cap_rid, idx - 1))
+ if (!valid_index(local, idx - 1))
return -EINVAL;
idx--;
- } else
- idx = get_wep_key(local, 0xffff);
+ } else {
+ idx = get_wep_tx_idx(local);
+ if (idx < 0)
+ idx = 0;
+ }
if (encoding->flags & IW_ENCODE_DISABLED)
alg = IW_ENCODE_ALG_NONE;
@@ -6418,7 +6550,13 @@ static int airo_set_encodeext(struct net_device *dev,
/* Only set transmit key index here, actual
* key is set below if needed.
*/
- set_wep_key(local, idx, NULL, 0, perm, 1);
+ rc = set_wep_tx_idx(local, idx, perm, 1);
+ if (rc < 0) {
+ airo_print_err(local->dev->name, "failed to set "
+ "WEP transmit index to %d: %d.",
+ idx, rc);
+ return rc;
+ }
set_key = ext->key_len > 0 ? 1 : 0;
}
@@ -6444,7 +6582,12 @@ static int airo_set_encodeext(struct net_device *dev,
return -EINVAL;
}
/* Send the key to the card */
- set_wep_key(local, idx, key.key, key.len, perm, 1);
+ rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
+ if (rc < 0) {
+ airo_print_err(local->dev->name, "failed to set WEP key"
+ " at index %d: %d.", idx, rc);
+ return rc;
+ }
}
/* Read the flags */
@@ -6474,14 +6617,12 @@ static int airo_get_encodeext(struct net_device *dev,
struct airo_info *local = dev->ml_priv;
struct iw_point *encoding = &wrqu->encoding;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- CapabilityRid cap_rid; /* Card capability info */
int idx, max_key_len;
+ u8 buf[16];
- /* Is it supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- if(!(cap_rid.softCap & cpu_to_le16(2))) {
+ if (!local->wep_capable)
return -EOPNOTSUPP;
- }
+
readConfigRid(local, 1);
max_key_len = encoding->length - sizeof(*ext);
@@ -6490,11 +6631,14 @@ static int airo_get_encodeext(struct net_device *dev,
idx = encoding->flags & IW_ENCODE_INDEX;
if (idx) {
- if (!valid_index(&cap_rid, idx - 1))
+ if (!valid_index(local, idx - 1))
return -EINVAL;
idx--;
- } else
- idx = get_wep_key(local, 0xffff);
+ } else {
+ idx = get_wep_tx_idx(local);
+ if (idx < 0)
+ idx = 0;
+ }
encoding->flags = idx + 1;
memset(ext, 0, sizeof(*ext));
@@ -6517,10 +6661,8 @@ static int airo_get_encodeext(struct net_device *dev,
memset(extra, 0, 16);
/* Copy the key to the user buffer */
- ext->key_len = get_wep_key(local, idx);
- if (ext->key_len > 16) {
- ext->key_len=0;
- }
+ ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
+ memcpy(extra, buf, ext->key_len);
return 0;
}
@@ -6795,8 +6937,8 @@ static int airo_get_range(struct net_device *dev,
k = 0;
for(i = 0; i < 14; i++) {
range->freq[k].i = i + 1; /* List index */
- range->freq[k].m = frequency_list[i] * 100000;
- range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
+ range->freq[k].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
+ range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
}
range->num_frequency = k;
@@ -7031,11 +7173,15 @@ static int airo_get_aplist(struct net_device *dev,
{
struct airo_info *local = dev->ml_priv;
struct sockaddr *address = (struct sockaddr *) extra;
- struct iw_quality qual[IW_MAX_AP];
+ struct iw_quality *qual;
BSSListRid BSSList;
int i;
int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
+ qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
+ if (!qual)
+ return -ENOMEM;
+
for (i = 0; i < IW_MAX_AP; i++) {
u16 dBm;
if (readBSSListRid(local, loseSync, &BSSList))
@@ -7090,6 +7236,7 @@ static int airo_get_aplist(struct net_device *dev,
}
dwrq->length = i;
+ kfree(qual);
return 0;
}
@@ -7189,10 +7336,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Add frequency */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
- /* iwe.u.freq.m containt the channel (starting 1), our
- * frequency_list array start at index 0...
- */
- iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
+ iwe.u.freq.m = ieee80211_dsss_chan_to_freq(iwe.u.freq.m) * 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_FREQ_LEN);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 27696c20f4c..d0593ed9170 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -16,8 +16,8 @@
In addition this module was derived from dummy_cs.
The initial developer of dummy_cs is David A. Hinds
<dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
======================================================================*/
#ifdef __IN_PCMCIA_PACKAGE__
@@ -38,7 +38,7 @@
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/system.h>
#include "airo.h"
@@ -54,7 +54,7 @@
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
static char *version = "$Revision: 1.2 $";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
+#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
#else
#define DEBUG(n, args...)
#endif
@@ -62,9 +62,9 @@ static char *version = "$Revision: 1.2 $";
/*====================================================================*/
MODULE_AUTHOR("Benjamin Reed");
-MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
- cards. This is the module that links the PCMCIA card \
- with the airo module.");
+MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet "
+ "cards. This is the module that links the PCMCIA card "
+ "with the airo module.");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
@@ -76,7 +76,7 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card
insertion and ejection events. They are invoked from the airo_cs
- event handler.
+ event handler.
*/
static int airo_config(struct pcmcia_device *link);
@@ -103,8 +103,9 @@ static void airo_detach(struct pcmcia_device *p_dev);
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
- memory card driver uses an array of struct pcmcia_device pointers, where minor
- device numbers are used to derive the corresponding array index.
+ memory card driver uses an array of struct pcmcia_device pointers,
+ where minor device numbers are used to derive the corresponding
+ array index.
*/
/*
@@ -122,22 +123,22 @@ static void airo_detach(struct pcmcia_device *p_dev);
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
*/
-
+
typedef struct local_info_t {
dev_node_t node;
struct net_device *eth_dev;
} local_info_t;
/*======================================================================
-
+
airo_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
-
+
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
-
+
======================================================================*/
static int airo_probe(struct pcmcia_device *p_dev)
@@ -150,7 +151,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
p_dev->irq.Handler = NULL;
-
+
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
@@ -160,7 +161,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
*/
p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
-
+
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
@@ -173,12 +174,12 @@ static int airo_probe(struct pcmcia_device *p_dev)
} /* airo_attach */
/*======================================================================
-
+
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
-
+
======================================================================*/
static void airo_detach(struct pcmcia_device *link)
@@ -187,20 +188,20 @@ static void airo_detach(struct pcmcia_device *link)
airo_release(link);
- if ( ((local_info_t*)link->priv)->eth_dev ) {
- stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
+ if (((local_info_t *)link->priv)->eth_dev) {
+ stop_airo_card(((local_info_t *)link->priv)->eth_dev, 0);
}
- ((local_info_t*)link->priv)->eth_dev = NULL;
+ ((local_info_t *)link->priv)->eth_dev = NULL;
kfree(link->priv);
} /* airo_detach */
/*======================================================================
-
+
airo_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
-
+
======================================================================*/
#define CS_CHECK(fn, ret) \
@@ -325,26 +326,28 @@ static int airo_config(struct pcmcia_device *link)
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-
+
/*
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
- ((local_info_t*)link->priv)->eth_dev =
- init_airo_card( link->irq.AssignedIRQ,
- link->io.BasePort1, 1, &handle_to_dev(link) );
- if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
-
+ CS_CHECK(RequestConfiguration,
+ pcmcia_request_configuration(link, &link->conf));
+ ((local_info_t *)link->priv)->eth_dev =
+ init_airo_card(link->irq.AssignedIRQ,
+ link->io.BasePort1, 1, &handle_to_dev(link));
+ if (!((local_info_t *)link->priv)->eth_dev)
+ goto cs_failed;
+
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev_node.
*/
- strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
+ strcpy(dev->node.dev_name, ((local_info_t *)link->priv)->eth_dev->name);
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
-
+
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: ",
dev->node.dev_name, link->conf.ConfigIndex);
@@ -374,11 +377,11 @@ static int airo_config(struct pcmcia_device *link)
} /* airo_config */
/*======================================================================
-
+
After a card is removed, airo_release() will unregister the
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
-
+
======================================================================*/
static void airo_release(struct pcmcia_device *link)
@@ -475,7 +478,7 @@ static void airo_cs_cleanup(void)
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.
+ POSSIBILITY OF SUCH DAMAGE.
*/
module_init(airo_cs_init);
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
new file mode 100644
index 00000000000..0c02f1c2bd9
--- /dev/null
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -0,0 +1,2501 @@
+/*
+ * at76c503/at76c505 USB driver
+ *
+ * Copyright (c) 2002 - 2003 Oliver Kurth
+ * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
+ * Copyright (c) 2004 Nick Jones
+ * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
+ * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
+ * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.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 the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This file is part of the Berlios driver for WLAN USB devices based on the
+ * Atmel AT76C503A/505/505A.
+ *
+ * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
+ *
+ * TODO list is at the wiki:
+ *
+ * http://wireless.kernel.org/en/users/Drivers/at76c50x-usb#TODO
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211_radiotap.h>
+#include <linux/firmware.h>
+#include <linux/leds.h>
+#include <net/mac80211.h>
+
+#include "at76c50x-usb.h"
+
+/* Version information */
+#define DRIVER_NAME "at76c50x-usb"
+#define DRIVER_VERSION "0.17"
+#define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver"
+
+/* at76_debug bits */
+#define DBG_PROGRESS 0x00000001 /* authentication/accociation */
+#define DBG_BSS_TABLE 0x00000002 /* show BSS table after scans */
+#define DBG_IOCTL 0x00000004 /* ioctl calls / settings */
+#define DBG_MAC_STATE 0x00000008 /* MAC state transitions */
+#define DBG_TX_DATA 0x00000010 /* tx header */
+#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */
+#define DBG_TX_MGMT 0x00000040 /* tx management */
+#define DBG_RX_DATA 0x00000080 /* rx data header */
+#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */
+#define DBG_RX_MGMT 0x00000200 /* rx mgmt frame headers */
+#define DBG_RX_BEACON 0x00000400 /* rx beacon */
+#define DBG_RX_CTRL 0x00000800 /* rx control */
+#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */
+#define DBG_RX_FRAGS 0x00002000 /* rx data fragment handling */
+#define DBG_DEVSTART 0x00004000 /* fw download, device start */
+#define DBG_URB 0x00008000 /* rx urb status, ... */
+#define DBG_RX_ATMEL_HDR 0x00010000 /* Atmel-specific Rx headers */
+#define DBG_PROC_ENTRY 0x00020000 /* procedure entries/exits */
+#define DBG_PM 0x00040000 /* power management settings */
+#define DBG_BSS_MATCH 0x00080000 /* BSS match failures */
+#define DBG_PARAMS 0x00100000 /* show configured parameters */
+#define DBG_WAIT_COMPLETE 0x00200000 /* command completion */
+#define DBG_RX_FRAGS_SKB 0x00400000 /* skb header of Rx fragments */
+#define DBG_BSS_TABLE_RM 0x00800000 /* purging bss table entries */
+#define DBG_MONITOR_MODE 0x01000000 /* monitor mode */
+#define DBG_MIB 0x02000000 /* dump all MIBs on startup */
+#define DBG_MGMT_TIMER 0x04000000 /* dump mgmt_timer ops */
+#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
+#define DBG_FW 0x10000000 /* firmware download */
+#define DBG_DFU 0x20000000 /* device firmware upgrade */
+#define DBG_CMD 0x40000000
+#define DBG_MAC80211 0x80000000
+
+#define DBG_DEFAULTS 0
+
+/* Use our own dbg macro */
+#define at76_dbg(bits, format, arg...) \
+ do { \
+ if (at76_debug & (bits)) \
+ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
+ ## arg); \
+ } while (0)
+
+#define at76_dbg_dump(bits, buf, len, format, arg...) \
+ do { \
+ if (at76_debug & (bits)) { \
+ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
+ ## arg); \
+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, \
+ buf, len); \
+ } \
+ } while (0)
+
+static uint at76_debug = DBG_DEFAULTS;
+
+/* Protect against concurrent firmware loading and parsing */
+static struct mutex fw_mutex;
+
+static struct fwentry firmwares[] = {
+ [0] = { "" },
+ [BOARD_503_ISL3861] = { "atmel_at76c503-i3861.bin" },
+ [BOARD_503_ISL3863] = { "atmel_at76c503-i3863.bin" },
+ [BOARD_503] = { "atmel_at76c503-rfmd.bin" },
+ [BOARD_503_ACC] = { "atmel_at76c503-rfmd-acc.bin" },
+ [BOARD_505] = { "atmel_at76c505-rfmd.bin" },
+ [BOARD_505_2958] = { "atmel_at76c505-rfmd2958.bin" },
+ [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" },
+ [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" },
+};
+
+#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
+
+static struct usb_device_id dev_table[] = {
+ /*
+ * at76c503-i3861
+ */
+ /* Generic AT76C503/3861 device */
+ { USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Linksys WUSB11 v2.1/v2.6 */
+ { USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Netgear MA101 rev. A */
+ { USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Tekram U300C / Allnet ALL0193 */
+ { USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* HP HN210W J7801A */
+ { USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Sitecom/Z-Com/Zyxel M4Y-750 */
+ { USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Dynalink/Askey WLL013 (intersil) */
+ { USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
+ { USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* BenQ AWL300 */
+ { USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Addtron AWU-120, Compex WLU11 */
+ { USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Intel AP310 AnyPoint II USB */
+ { USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Dynalink L11U */
+ { USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Arescom WL-210, FCC id 07J-GL2411USB */
+ { USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* I-O DATA WN-B11/USB */
+ { USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* BT Voyager 1010 */
+ { USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /*
+ * at76c503-i3863
+ */
+ /* Generic AT76C503/3863 device */
+ { USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ /* Samsung SWL-2100U */
+ { USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ /*
+ * at76c503-rfmd
+ */
+ /* Generic AT76C503/RFMD device */
+ { USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ /* Dynalink/Askey WLL013 (rfmd) */
+ { USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) },
+ /* Linksys WUSB11 v2.6 */
+ { USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) },
+ /* Network Everywhere NWU11B */
+ { USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) },
+ /* Netgear MA101 rev. B */
+ { USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ /* D-Link DWL-120 rev. E */
+ { USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) },
+ /* Actiontec 802UAT1, HWU01150-01UK */
+ { USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ /* AirVast W-Buddie WN210 */
+ { USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ /* Dick Smith Electronics XH1153 802.11b USB adapter */
+ { USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) },
+ /* CNet CNUSB611 */
+ { USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) },
+ /* FiberLine FL-WL200U */
+ { USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) },
+ /* BenQ AWL400 USB stick */
+ { USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) },
+ /* 3Com 3CRSHEW696 */
+ { USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) },
+ /* Siemens Santis ADSL WLAN USB adapter WLL 013 */
+ { USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) },
+ /* Belkin F5D6050, version 2 */
+ { USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) },
+ /* iBlitzz, BWU613 (not *B or *SB) */
+ { USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) },
+ /* Gigabyte GN-WLBM101 */
+ { USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) },
+ /* Planex GW-US11S */
+ { USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) },
+ /* Internal WLAN adapter in h5[4,5]xx series iPAQs */
+ { USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) },
+ /* Corega Wireless LAN USB-11 mini */
+ { USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) },
+ /* Corega Wireless LAN USB-11 mini2 */
+ { USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) },
+ /* Uniden PCW100 */
+ { USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) },
+ /*
+ * at76c503-rfmd-acc
+ */
+ /* SMC2664W */
+ { USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) },
+ /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
+ { USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) },
+ /*
+ * at76c505-rfmd
+ */
+ /* Generic AT76C505/RFMD */
+ { USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) },
+ /*
+ * at76c505-rfmd2958
+ */
+ /* Generic AT76C505/RFMD, OvisLink WL-1130USB */
+ { USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Fiberline FL-WL240U */
+ { USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* CNet CNUSB-611G */
+ { USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Linksys WUSB11 v2.8 */
+ { USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
+ { USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Corega WLAN USB Stick 11 */
+ { USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Microstar MSI Box MS6978 */
+ { USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) },
+ /*
+ * at76c505a-rfmd2958
+ */
+ /* Generic AT76C505A device */
+ { USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) },
+ /* Generic AT76C505AS device */
+ { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
+ /* Siemens Gigaset USB WLAN Adapter 11 */
+ { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
+ /*
+ * at76c505amx-rfmd
+ */
+ /* Generic AT76C505AMX device */
+ { USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(usb, dev_table);
+
+/* Supported rates of this hardware, bit 7 marks basic rates */
+static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
+
+static const char *const preambles[] = { "long", "short", "auto" };
+
+/* Firmware download */
+/* DFU states */
+#define STATE_IDLE 0x00
+#define STATE_DETACH 0x01
+#define STATE_DFU_IDLE 0x02
+#define STATE_DFU_DOWNLOAD_SYNC 0x03
+#define STATE_DFU_DOWNLOAD_BUSY 0x04
+#define STATE_DFU_DOWNLOAD_IDLE 0x05
+#define STATE_DFU_MANIFEST_SYNC 0x06
+#define STATE_DFU_MANIFEST 0x07
+#define STATE_DFU_MANIFEST_WAIT_RESET 0x08
+#define STATE_DFU_UPLOAD_IDLE 0x09
+#define STATE_DFU_ERROR 0x0a
+
+/* DFU commands */
+#define DFU_DETACH 0
+#define DFU_DNLOAD 1
+#define DFU_UPLOAD 2
+#define DFU_GETSTATUS 3
+#define DFU_CLRSTATUS 4
+#define DFU_GETSTATE 5
+#define DFU_ABORT 6
+
+#define FW_BLOCK_SIZE 1024
+
+struct dfu_status {
+ unsigned char status;
+ unsigned char poll_timeout[3];
+ unsigned char state;
+ unsigned char string;
+} __attribute__((packed));
+
+static inline int at76_is_intersil(enum board_type board)
+{
+ return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
+}
+
+static inline int at76_is_503rfmd(enum board_type board)
+{
+ return (board == BOARD_503 || board == BOARD_503_ACC);
+}
+
+static inline int at76_is_505a(enum board_type board)
+{
+ return (board == BOARD_505A || board == BOARD_505AMX);
+}
+
+/* Load a block of the first (internal) part of the firmware */
+static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
+ void *block, int size)
+{
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD,
+ USB_TYPE_CLASS | USB_DIR_OUT |
+ USB_RECIP_INTERFACE, blockno, 0, block, size,
+ USB_CTRL_GET_TIMEOUT);
+}
+
+static int at76_dfu_get_status(struct usb_device *udev,
+ struct dfu_status *status)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS,
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, 0, status, sizeof(struct dfu_status),
+ USB_CTRL_GET_TIMEOUT);
+ return ret;
+}
+
+static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE,
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, 0, state, 1, USB_CTRL_GET_TIMEOUT);
+ return ret;
+}
+
+/* Convert timeout from the DFU status to jiffies */
+static inline unsigned long at76_get_timeout(struct dfu_status *s)
+{
+ return msecs_to_jiffies((s->poll_timeout[2] << 16)
+ | (s->poll_timeout[1] << 8)
+ | (s->poll_timeout[0]));
+}
+
+/* Load internal firmware from the buffer. If manifest_sync_timeout > 0, use
+ * its value in jiffies in the MANIFEST_SYNC state. */
+static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
+ int manifest_sync_timeout)
+{
+ u8 *block;
+ struct dfu_status dfu_stat_buf;
+ int ret = 0;
+ int need_dfu_state = 1;
+ int is_done = 0;
+ u8 dfu_state = 0;
+ u32 dfu_timeout = 0;
+ int bsize = 0;
+ int blockno = 0;
+
+ at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
+ manifest_sync_timeout);
+
+ if (!size) {
+ dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
+ return -EINVAL;
+ }
+
+ block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
+ if (!block)
+ return -ENOMEM;
+
+ do {
+ if (need_dfu_state) {
+ ret = at76_dfu_get_state(udev, &dfu_state);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "cannot get DFU state: %d\n", ret);
+ goto exit;
+ }
+ need_dfu_state = 0;
+ }
+
+ switch (dfu_state) {
+ case STATE_DFU_DOWNLOAD_SYNC:
+ at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
+ ret = at76_dfu_get_status(udev, &dfu_stat_buf);
+ if (ret >= 0) {
+ dfu_state = dfu_stat_buf.state;
+ dfu_timeout = at76_get_timeout(&dfu_stat_buf);
+ need_dfu_state = 0;
+ } else
+ dev_printk(KERN_ERR, &udev->dev,
+ "at76_dfu_get_status returned %d\n",
+ ret);
+ break;
+
+ case STATE_DFU_DOWNLOAD_BUSY:
+ at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
+ need_dfu_state = 1;
+
+ at76_dbg(DBG_DFU, "DFU: Resetting device");
+ schedule_timeout_interruptible(dfu_timeout);
+ break;
+
+ case STATE_DFU_DOWNLOAD_IDLE:
+ at76_dbg(DBG_DFU, "DOWNLOAD...");
+ /* fall through */
+ case STATE_DFU_IDLE:
+ at76_dbg(DBG_DFU, "DFU IDLE");
+
+ bsize = min_t(int, size, FW_BLOCK_SIZE);
+ memcpy(block, buf, bsize);
+ at76_dbg(DBG_DFU, "int fw, size left = %5d, "
+ "bsize = %4d, blockno = %2d", size, bsize,
+ blockno);
+ ret =
+ at76_load_int_fw_block(udev, blockno, block, bsize);
+ buf += bsize;
+ size -= bsize;
+ blockno++;
+
+ if (ret != bsize)
+ dev_printk(KERN_ERR, &udev->dev,
+ "at76_load_int_fw_block "
+ "returned %d\n", ret);
+ need_dfu_state = 1;
+ break;
+
+ case STATE_DFU_MANIFEST_SYNC:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
+
+ ret = at76_dfu_get_status(udev, &dfu_stat_buf);
+ if (ret < 0)
+ break;
+
+ dfu_state = dfu_stat_buf.state;
+ dfu_timeout = at76_get_timeout(&dfu_stat_buf);
+ need_dfu_state = 0;
+
+ /* override the timeout from the status response,
+ needed for AT76C505A */
+ if (manifest_sync_timeout > 0)
+ dfu_timeout = manifest_sync_timeout;
+
+ at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
+ schedule_timeout_interruptible(dfu_timeout);
+ break;
+
+ case STATE_DFU_MANIFEST:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
+ is_done = 1;
+ break;
+
+ case STATE_DFU_MANIFEST_WAIT_RESET:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
+ is_done = 1;
+ break;
+
+ case STATE_DFU_UPLOAD_IDLE:
+ at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
+ break;
+
+ case STATE_DFU_ERROR:
+ at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
+ ret = -EPIPE;
+ break;
+
+ default:
+ at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
+ ret = -EINVAL;
+ break;
+ }
+ } while (!is_done && (ret >= 0));
+
+exit:
+ kfree(block);
+ if (ret >= 0)
+ ret = 0;
+
+ return ret;
+}
+
+#define HEX2STR_BUFFERS 4
+#define HEX2STR_MAX_LEN 64
+#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
+
+/* Convert binary data into hex string */
+static char *hex2str(void *buf, int len)
+{
+ static atomic_t a = ATOMIC_INIT(0);
+ static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
+ char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
+ char *obuf = ret;
+ u8 *ibuf = buf;
+
+ if (len > HEX2STR_MAX_LEN)
+ len = HEX2STR_MAX_LEN;
+
+ if (len <= 0) {
+ ret[0] = '\0';
+ return ret;
+ }
+
+ while (len--) {
+ *obuf++ = BIN2HEX(*ibuf >> 4);
+ *obuf++ = BIN2HEX(*ibuf & 0xf);
+ *obuf++ = '-';
+ ibuf++;
+ }
+ *(--obuf) = '\0';
+
+ return ret;
+}
+
+#define MAC2STR_BUFFERS 4
+
+static inline char *mac2str(u8 *mac)
+{
+ static atomic_t a = ATOMIC_INIT(0);
+ static char bufs[MAC2STR_BUFFERS][6 * 3];
+ char *str;
+
+ str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)];
+ sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ return str;
+}
+
+/* LED trigger */
+static int tx_activity;
+static void at76_ledtrig_tx_timerfunc(unsigned long data);
+static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0);
+DEFINE_LED_TRIGGER(ledtrig_tx);
+
+static void at76_ledtrig_tx_timerfunc(unsigned long data)
+{
+ static int tx_lastactivity;
+
+ if (tx_lastactivity != tx_activity) {
+ tx_lastactivity = tx_activity;
+ led_trigger_event(ledtrig_tx, LED_FULL);
+ mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
+ } else
+ led_trigger_event(ledtrig_tx, LED_OFF);
+}
+
+static void at76_ledtrig_tx_activity(void)
+{
+ tx_activity++;
+ if (!timer_pending(&ledtrig_tx_timer))
+ mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
+}
+
+static int at76_remap(struct usb_device *udev)
+{
+ int ret;
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a,
+ USB_TYPE_VENDOR | USB_DIR_OUT |
+ USB_RECIP_INTERFACE, 0, 0, NULL, 0,
+ USB_CTRL_GET_TIMEOUT);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int at76_get_op_mode(struct usb_device *udev)
+{
+ int ret;
+ u8 saved;
+ u8 *op_mode;
+
+ op_mode = kmalloc(1, GFP_NOIO);
+ if (!op_mode)
+ return -ENOMEM;
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
+ USB_CTRL_GET_TIMEOUT);
+ saved = *op_mode;
+ kfree(op_mode);
+
+ if (ret < 0)
+ return ret;
+ else if (ret < 1)
+ return -EIO;
+ else
+ return saved;
+}
+
+/* Load a block of the second ("external") part of the firmware */
+static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
+ void *block, int size)
+{
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+ 0x0802, blockno, block, size,
+ USB_CTRL_GET_TIMEOUT);
+}
+
+static inline int at76_get_hw_cfg(struct usb_device *udev,
+ union at76_hwcfg *buf, int buf_size)
+{
+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x0a02, 0,
+ buf, buf_size, USB_CTRL_GET_TIMEOUT);
+}
+
+/* Intersil boards use a different "value" for GetHWConfig requests */
+static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
+ union at76_hwcfg *buf, int buf_size)
+{
+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x0902, 0,
+ buf, buf_size, USB_CTRL_GET_TIMEOUT);
+}
+
+/* Get the hardware configuration for the adapter and put it to the appropriate
+ * fields of 'priv' (the GetHWConfig request and interpretation of the result
+ * depends on the board type) */
+static int at76_get_hw_config(struct at76_priv *priv)
+{
+ int ret;
+ union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
+
+ if (!hwcfg)
+ return -ENOMEM;
+
+ if (at76_is_intersil(priv->board_type)) {
+ ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg,
+ sizeof(hwcfg->i));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->i.regulatory_domain;
+ } else if (at76_is_503rfmd(priv->board_type)) {
+ ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->r3.regulatory_domain;
+ } else {
+ ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->r5.regulatory_domain;
+ }
+
+exit:
+ kfree(hwcfg);
+ if (ret < 0)
+ printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static struct reg_domain const *at76_get_reg_domain(u16 code)
+{
+ int i;
+ static struct reg_domain const fd_tab[] = {
+ { 0x10, "FCC (USA)", 0x7ff }, /* ch 1-11 */
+ { 0x20, "IC (Canada)", 0x7ff }, /* ch 1-11 */
+ { 0x30, "ETSI (most of Europe)", 0x1fff }, /* ch 1-13 */
+ { 0x31, "Spain", 0x600 }, /* ch 10-11 */
+ { 0x32, "France", 0x1e00 }, /* ch 10-13 */
+ { 0x40, "MKK (Japan)", 0x2000 }, /* ch 14 */
+ { 0x41, "MKK1 (Japan)", 0x3fff }, /* ch 1-14 */
+ { 0x50, "Israel", 0x3fc }, /* ch 3-9 */
+ { 0x00, "<unknown>", 0xffffffff } /* ch 1-32 */
+ };
+
+ /* Last entry is fallback for unknown domain code */
+ for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++)
+ if (code == fd_tab[i].code)
+ break;
+
+ return &fd_tab[i];
+}
+
+static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
+ int buf_size)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size,
+ USB_CTRL_GET_TIMEOUT);
+ if (ret >= 0 && ret != buf_size)
+ return -EIO;
+ return ret;
+}
+
+/* Return positive number for status, negative for an error */
+static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
+{
+ u8 *stat_buf;
+ int ret;
+
+ stat_buf = kmalloc(40, GFP_NOIO);
+ if (!stat_buf)
+ return -ENOMEM;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, cmd, 0, stat_buf,
+ 40, USB_CTRL_GET_TIMEOUT);
+ if (ret >= 0)
+ ret = stat_buf[5];
+ kfree(stat_buf);
+
+ return ret;
+}
+
+#define MAKE_CMD_CASE(c) case (c): return #c
+static const char *at76_get_cmd_string(u8 cmd_status)
+{
+ switch (cmd_status) {
+ MAKE_CMD_CASE(CMD_SET_MIB);
+ MAKE_CMD_CASE(CMD_GET_MIB);
+ MAKE_CMD_CASE(CMD_SCAN);
+ MAKE_CMD_CASE(CMD_JOIN);
+ MAKE_CMD_CASE(CMD_START_IBSS);
+ MAKE_CMD_CASE(CMD_RADIO_ON);
+ MAKE_CMD_CASE(CMD_RADIO_OFF);
+ MAKE_CMD_CASE(CMD_STARTUP);
+ }
+
+ return "UNKNOWN";
+}
+
+static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
+ int buf_size)
+{
+ int ret;
+ struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
+ buf_size, GFP_KERNEL);
+
+ if (!cmd_buf)
+ return -ENOMEM;
+
+ cmd_buf->cmd = cmd;
+ cmd_buf->reserved = 0;
+ cmd_buf->size = cpu_to_le16(buf_size);
+ memcpy(cmd_buf->data, buf, buf_size);
+
+ at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size,
+ "issuing command %s (0x%02x)",
+ at76_get_cmd_string(cmd), cmd);
+
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+ 0, 0, cmd_buf,
+ sizeof(struct at76_command) + buf_size,
+ USB_CTRL_GET_TIMEOUT);
+ kfree(cmd_buf);
+ return ret;
+}
+
+#define MAKE_CMD_STATUS_CASE(c) case (c): return #c
+static const char *at76_get_cmd_status_string(u8 cmd_status)
+{
+ switch (cmd_status) {
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
+ }
+
+ return "UNKNOWN";
+}
+
+/* Wait until the command is completed */
+static int at76_wait_completion(struct at76_priv *priv, int cmd)
+{
+ int status = 0;
+ unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
+
+ do {
+ status = at76_get_cmd_status(priv->udev, cmd);
+ if (status < 0) {
+ printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
+ wiphy_name(priv->hw->wiphy), status);
+ break;
+ }
+
+ at76_dbg(DBG_WAIT_COMPLETE,
+ "%s: Waiting on cmd %d, status = %d (%s)",
+ wiphy_name(priv->hw->wiphy), cmd, status,
+ at76_get_cmd_status_string(status));
+
+ if (status != CMD_STATUS_IN_PROGRESS
+ && status != CMD_STATUS_IDLE)
+ break;
+
+ schedule_timeout_interruptible(HZ / 10); /* 100 ms */
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_ERR
+ "%s: completion timeout for command %d\n",
+ wiphy_name(priv->hw->wiphy), cmd);
+ status = -ETIMEDOUT;
+ break;
+ }
+ } while (1);
+
+ return status;
+}
+
+static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
+{
+ int ret;
+
+ ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf,
+ offsetof(struct set_mib_buffer,
+ data) + buf->size);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_wait_completion(priv, CMD_SET_MIB);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_INFO
+ "%s: set_mib: at76_wait_completion failed "
+ "with %d\n", wiphy_name(priv->hw->wiphy), ret);
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
+static int at76_set_radio(struct at76_priv *priv, int enable)
+{
+ int ret;
+ int cmd;
+
+ if (priv->radio_on == enable)
+ return 0;
+
+ cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
+
+ ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
+ if (ret < 0)
+ printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), cmd, ret);
+ else
+ ret = 1;
+
+ priv->radio_on = enable;
+ return ret;
+}
+
+/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
+static int at76_set_pm_mode(struct at76_priv *priv)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode);
+ priv->mib_buf.data.byte = priv->pm_mode;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static int at76_set_preamble(struct at76_priv *priv, u8 type)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, preamble_type);
+ priv->mib_buf.data.byte = type;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static int at76_set_frag(struct at76_priv *priv, u16 size)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold);
+ priv->mib_buf.data.word = cpu_to_le16(size);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static int at76_set_rts(struct at76_priv *priv, u16 size)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold);
+ priv->mib_buf.data.word = cpu_to_le16(size);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback);
+ priv->mib_buf.data.byte = onoff;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static void at76_dump_mib_mac_addr(struct at76_priv *priv)
+{
+ int i;
+ int ret;
+ struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
+ GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
+ sizeof(struct mib_mac_addr));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
+ wiphy_name(priv->hw->wiphy),
+ mac2str(m->mac_addr), m->res[0], m->res[1]);
+ for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
+ at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
+ "status %d", wiphy_name(priv->hw->wiphy), i,
+ mac2str(m->group_addr[i]), m->group_addr_status[i]);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac_wep(struct at76_priv *priv)
+{
+ int i;
+ int ret;
+ int key_len;
+ struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
+ sizeof(struct mib_mac_wep));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
+ "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
+ "encr_level %u key %d", wiphy_name(priv->hw->wiphy),
+ m->privacy_invoked, m->wep_default_key_id,
+ m->wep_key_mapping_len, m->exclude_unencrypted,
+ le32_to_cpu(m->wep_icv_error_count),
+ le32_to_cpu(m->wep_excluded_count), m->encryption_level,
+ m->wep_default_key_id);
+
+ key_len = (m->encryption_level == 1) ?
+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+
+ for (i = 0; i < WEP_KEYS; i++)
+ at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
+ wiphy_name(priv->hw->wiphy), i,
+ hex2str(m->wep_default_keyvalue[i], key_len));
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
+ GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
+ "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
+ "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
+ "current_bssid %s current_essid %s current_bss_type %d "
+ "pm_mode %d ibss_change %d res %d "
+ "multi_domain_capability_implemented %d "
+ "international_roaming %d country_string %.3s",
+ wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period),
+ le16_to_cpu(m->CFP_max_duration),
+ le16_to_cpu(m->medium_occupancy_limit),
+ le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
+ m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
+ m->CFP_period, mac2str(m->current_bssid),
+ hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
+ m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
+ m->res, m->multi_domain_capability_implemented,
+ m->multi_domain_capability_enabled, m->country_string);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d "
+ "max_rx_lifetime %d frag_threshold %d rts_threshold %d "
+ "cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
+ "scan_type %d scan_channel %d probe_delay %u "
+ "min_channel_time %d max_channel_time %d listen_int %d "
+ "desired_ssid %s desired_bssid %s desired_bsstype %d",
+ wiphy_name(priv->hw->wiphy),
+ le32_to_cpu(m->max_tx_msdu_lifetime),
+ le32_to_cpu(m->max_rx_lifetime),
+ le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
+ le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
+ m->short_retry_time, m->long_retry_time, m->scan_type,
+ m->scan_channel, le16_to_cpu(m->probe_delay),
+ le16_to_cpu(m->min_channel_time),
+ le16_to_cpu(m->max_channel_time),
+ le16_to_cpu(m->listen_interval),
+ hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
+ mac2str(m->desired_bssid), m->desired_bsstype);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_phy(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d "
+ "sifs_time %d preamble_length %d plcp_header_length %d "
+ "mpdu_max_length %d cca_mode_supported %d operation_rate_set "
+ "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
+ "phy_type %d current_reg_domain %d",
+ wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold),
+ le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
+ le16_to_cpu(m->preamble_length),
+ le16_to_cpu(m->plcp_header_length),
+ le16_to_cpu(m->mpdu_max_length),
+ le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0],
+ m->operation_rate_set[1], m->operation_rate_set[2],
+ m->operation_rate_set[3], m->channel_id, m->current_cca_mode,
+ m->phy_type, m->current_reg_domain);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_local(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
+ "txautorate_fallback %d ssid_size %d promiscuous_mode %d "
+ "preamble_type %d", wiphy_name(priv->hw->wiphy),
+ m->beacon_enable,
+ m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
+ m->preamble_type);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mdomain(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
+ sizeof(struct mib_mdomain));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
+ wiphy_name(priv->hw->wiphy),
+ hex2str(m->channel_list, sizeof(m->channel_list)));
+
+ at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
+ wiphy_name(priv->hw->wiphy),
+ hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
+exit:
+ kfree(m);
+}
+
+/* Enable monitor mode */
+static int at76_start_monitor(struct at76_priv *priv)
+{
+ struct at76_req_scan scan;
+ int ret;
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xff, ETH_ALEN);
+
+ scan.channel = priv->channel;
+ scan.scan_type = SCAN_TYPE_PASSIVE;
+ scan.international_scan = 0;
+
+ ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+ if (ret >= 0)
+ ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
+
+ return ret;
+}
+
+/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
+ likely to compensate a flaw in the AT76C503A USB part ... */
+static inline int at76_calc_padding(int wlen)
+{
+ /* add the USB TX header */
+ wlen += AT76_TX_HDRLEN;
+
+ wlen = wlen % 64;
+
+ if (wlen < 50)
+ return 50 - wlen;
+
+ if (wlen >= 61)
+ return 64 + 50 - wlen;
+
+ return 0;
+}
+
+static void at76_rx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+
+ priv->rx_tasklet.data = (unsigned long)urb;
+ tasklet_schedule(&priv->rx_tasklet);
+ return;
+}
+
+static int at76_submit_rx_urb(struct at76_priv *priv)
+{
+ int ret;
+ int size;
+ struct sk_buff *skb = priv->rx_skb;
+
+ if (!priv->rx_urb) {
+ printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
+ wiphy_name(priv->hw->wiphy), __func__);
+ return -EFAULT;
+ }
+
+ if (!skb) {
+ skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
+ if (!skb) {
+ printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
+ wiphy_name(priv->hw->wiphy));
+ ret = -ENOMEM;
+ goto exit;
+ }
+ priv->rx_skb = skb;
+ } else {
+ skb_push(skb, skb_headroom(skb));
+ skb_trim(skb, 0);
+ }
+
+ size = skb_tailroom(skb);
+ usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe,
+ skb_put(skb, size), size, at76_rx_callback, priv);
+ ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC);
+ if (ret < 0) {
+ if (ret == -ENODEV)
+ at76_dbg(DBG_DEVSTART,
+ "usb_submit_urb returned -ENODEV");
+ else
+ printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ }
+
+exit:
+ if (ret < 0 && ret != -ENODEV)
+ printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
+ "driver and/or power cycle the device\n",
+ wiphy_name(priv->hw->wiphy));
+
+ return ret;
+}
+
+/* Download external firmware */
+static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
+{
+ int ret;
+ int op_mode;
+ int blockno = 0;
+ int bsize;
+ u8 *block;
+ u8 *buf = fwe->extfw;
+ int size = fwe->extfw_size;
+
+ if (!buf || !size)
+ return -ENOENT;
+
+ op_mode = at76_get_op_mode(udev);
+ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+ if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+ dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
+ op_mode);
+ return -EINVAL;
+ }
+
+ block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
+ if (!block)
+ return -ENOMEM;
+
+ at76_dbg(DBG_DEVSTART, "downloading external firmware");
+
+ /* for fw >= 0.100, the device needs an extra empty block */
+ do {
+ bsize = min_t(int, size, FW_BLOCK_SIZE);
+ memcpy(block, buf, bsize);
+ at76_dbg(DBG_DEVSTART,
+ "ext fw, size left = %5d, bsize = %4d, blockno = %2d",
+ size, bsize, blockno);
+ ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
+ if (ret != bsize) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "loading %dth firmware block failed: %d\n",
+ blockno, ret);
+ goto exit;
+ }
+ buf += bsize;
+ size -= bsize;
+ blockno++;
+ } while (bsize > 0);
+
+ if (at76_is_505a(fwe->board_type)) {
+ at76_dbg(DBG_DEVSTART, "200 ms delay for 505a");
+ schedule_timeout_interruptible(HZ / 5 + 1);
+ }
+
+exit:
+ kfree(block);
+ if (ret < 0)
+ dev_printk(KERN_ERR, &udev->dev,
+ "downloading external firmware failed: %d\n", ret);
+ return ret;
+}
+
+/* Download internal firmware */
+static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
+{
+ int ret;
+ int need_remap = !at76_is_505a(fwe->board_type);
+
+ ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size,
+ need_remap ? 0 : 2 * HZ);
+
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "downloading internal fw failed with %d\n", ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_DEVSTART, "sending REMAP");
+
+ /* no REMAP for 505A (see SF driver) */
+ if (need_remap) {
+ ret = at76_remap(udev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "sending REMAP failed with %d\n", ret);
+ goto exit;
+ }
+ }
+
+ at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds");
+ schedule_timeout_interruptible(2 * HZ + 1);
+ usb_reset_device(udev);
+
+exit:
+ return ret;
+}
+
+static int at76_startup_device(struct at76_priv *priv)
+{
+ struct at76_card_config *ccfg = &priv->card_config;
+ int ret;
+
+ at76_dbg(DBG_PARAMS,
+ "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
+ "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size,
+ priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE),
+ priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
+ priv->channel, priv->wep_enabled ? "enabled" : "disabled",
+ priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
+ at76_dbg(DBG_PARAMS,
+ "%s param: preamble %s rts %d retry %d frag %d "
+ "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy),
+ preambles[priv->preamble_type], priv->rts_threshold,
+ priv->short_retry_limit, priv->frag_threshold,
+ priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
+ TX_RATE_2MBIT ? "2MBit" : priv->txrate ==
+ TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate ==
+ TX_RATE_11MBIT ? "11MBit" : priv->txrate ==
+ TX_RATE_AUTO ? "auto" : "<invalid>", priv->auth_mode);
+ at76_dbg(DBG_PARAMS,
+ "%s param: pm_mode %d pm_period %d auth_mode %s "
+ "scan_times %d %d scan_mode %s",
+ wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period,
+ priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
+ priv->scan_min_time, priv->scan_max_time,
+ priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
+
+ memset(ccfg, 0, sizeof(struct at76_card_config));
+ ccfg->promiscuous_mode = 0;
+ ccfg->short_retry_limit = priv->short_retry_limit;
+
+ if (priv->wep_enabled) {
+ if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN)
+ ccfg->encryption_type = 2;
+ else
+ ccfg->encryption_type = 1;
+
+ /* jal: always exclude unencrypted if WEP is active */
+ ccfg->exclude_unencrypted = 1;
+ } else {
+ ccfg->exclude_unencrypted = 0;
+ ccfg->encryption_type = 0;
+ }
+
+ ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold);
+ ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold);
+
+ memcpy(ccfg->basic_rate_set, hw_rates, 4);
+ /* jal: really needed, we do a set_mib for autorate later ??? */
+ ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0);
+ ccfg->channel = priv->channel;
+ ccfg->privacy_invoked = priv->wep_enabled;
+ memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE);
+ ccfg->ssid_len = priv->essid_size;
+
+ ccfg->wep_default_key_id = priv->wep_key_id;
+ memcpy(ccfg->wep_default_key_value, priv->wep_keys,
+ sizeof(priv->wep_keys));
+
+ ccfg->short_preamble = priv->preamble_type;
+ ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
+
+ ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
+ sizeof(struct at76_card_config));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ return ret;
+ }
+
+ at76_wait_completion(priv, CMD_STARTUP);
+
+ /* remove BSSID from previous run */
+ memset(priv->bssid, 0, ETH_ALEN);
+
+ if (at76_set_radio(priv, 1) == 1)
+ at76_wait_completion(priv, CMD_RADIO_ON);
+
+ ret = at76_set_preamble(priv, priv->preamble_type);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_frag(priv, priv->frag_threshold);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_rts(priv, priv->rts_threshold);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_autorate_fallback(priv,
+ priv->txrate == TX_RATE_AUTO ? 1 : 0);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_pm_mode(priv);
+ if (ret < 0)
+ return ret;
+
+ if (at76_debug & DBG_MIB) {
+ at76_dump_mib_mac(priv);
+ at76_dump_mib_mac_addr(priv);
+ at76_dump_mib_mac_mgmt(priv);
+ at76_dump_mib_mac_wep(priv);
+ at76_dump_mib_mdomain(priv);
+ at76_dump_mib_phy(priv);
+ at76_dump_mib_local(priv);
+ }
+
+ return 0;
+}
+
+/* Enable or disable promiscuous mode */
+static void at76_work_set_promisc(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_set_promisc);
+ int ret = 0;
+
+ if (priv->device_unplugged)
+ return;
+
+ mutex_lock(&priv->mtx);
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
+ priv->mib_buf.data.byte = priv->promisc ? 1 : 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ mutex_unlock(&priv->mtx);
+}
+
+/* Submit Rx urb back to the device */
+static void at76_work_submit_rx(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_submit_rx);
+
+ mutex_lock(&priv->mtx);
+ at76_submit_rx_urb(priv);
+ mutex_unlock(&priv->mtx);
+}
+
+static void at76_rx_tasklet(unsigned long param)
+{
+ struct urb *urb = (struct urb *)param;
+ struct at76_priv *priv = urb->context;
+ struct at76_rx_buffer *buf;
+ struct ieee80211_rx_status rx_status = { 0 };
+
+ if (priv->device_unplugged) {
+ at76_dbg(DBG_DEVSTART, "device unplugged");
+ if (urb)
+ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ return;
+ }
+
+ if (!priv->rx_skb || !priv->rx_skb->data)
+ return;
+
+ buf = (struct at76_rx_buffer *)priv->rx_skb->data;
+
+ if (urb->status != 0) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET)
+ at76_dbg(DBG_URB,
+ "%s %s: - nonzero Rx bulk status received: %d",
+ __func__, wiphy_name(priv->hw->wiphy),
+ urb->status);
+ return;
+ }
+
+ at76_dbg(DBG_RX_ATMEL_HDR,
+ "%s: rx frame: rate %d rssi %d noise %d link %d",
+ wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi,
+ buf->noise_level, buf->link_quality);
+
+ skb_pull(priv->rx_skb, AT76_RX_HDRLEN);
+ skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength));
+ at76_dbg_dump(DBG_RX_DATA, priv->rx_skb->data,
+ priv->rx_skb->len, "RX: len=%d", priv->rx_skb->len);
+
+ rx_status.signal = buf->rssi;
+ rx_status.flag |= RX_FLAG_DECRYPTED;
+ rx_status.flag |= RX_FLAG_IV_STRIPPED;
+
+ at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
+ priv->rx_skb->len, priv->rx_skb->data_len);
+ ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
+
+ /* Use a new skb for the next receive */
+ priv->rx_skb = NULL;
+
+ at76_submit_rx_urb(priv);
+}
+
+/* Load firmware into kernel memory and parse it */
+static struct fwentry *at76_load_firmware(struct usb_device *udev,
+ enum board_type board_type)
+{
+ int ret;
+ char *str;
+ struct at76_fw_header *fwh;
+ struct fwentry *fwe = &firmwares[board_type];
+
+ mutex_lock(&fw_mutex);
+
+ if (fwe->loaded) {
+ at76_dbg(DBG_FW, "re-using previously loaded fw");
+ goto exit;
+ }
+
+ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
+ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
+ fwe->fwname);
+ dev_printk(KERN_ERR, &udev->dev,
+ "you may need to download the firmware from "
+ "http://developer.berlios.de/projects/at76c503a/\n");
+ goto exit;
+ }
+
+ at76_dbg(DBG_FW, "got it.");
+ fwh = (struct at76_fw_header *)(fwe->fw->data);
+
+ if (fwe->fw->size <= sizeof(*fwh)) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "firmware is too short (0x%zx)\n", fwe->fw->size);
+ goto exit;
+ }
+
+ /* CRC currently not checked */
+ fwe->board_type = le32_to_cpu(fwh->board_type);
+ if (fwe->board_type != board_type) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "board type mismatch, requested %u, got %u\n",
+ board_type, fwe->board_type);
+ goto exit;
+ }
+
+ fwe->fw_version.major = fwh->major;
+ fwe->fw_version.minor = fwh->minor;
+ fwe->fw_version.patch = fwh->patch;
+ fwe->fw_version.build = fwh->build;
+
+ str = (char *)fwh + le32_to_cpu(fwh->str_offset);
+ fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
+ fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
+ fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
+ fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
+
+ fwe->loaded = 1;
+
+ dev_printk(KERN_DEBUG, &udev->dev,
+ "using firmware %s (version %d.%d.%d-%d)\n",
+ fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
+
+ at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
+ le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
+ le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
+ at76_dbg(DBG_DEVSTART, "firmware id %s", str);
+
+exit:
+ mutex_unlock(&fw_mutex);
+
+ if (fwe->loaded)
+ return fwe;
+ else
+ return NULL;
+}
+
+static void at76_mac80211_tx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ break;
+ case -ENOENT:
+ case -ECONNRESET:
+ /* fail, urb has been unlinked */
+ /* FIXME: add error message */
+ break;
+ default:
+ at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
+ __func__, urb->status);
+ break;
+ }
+
+ memset(&info->status, 0, sizeof(info->status));
+
+ ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
+
+ priv->tx_skb = NULL;
+
+ ieee80211_wake_queues(priv->hw);
+}
+
+static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct at76_priv *priv = hw->priv;
+ struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ int padding, submit_len, ret;
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ if (priv->tx_urb->status == -EINPROGRESS) {
+ printk(KERN_ERR "%s: %s called while tx urb is pending\n",
+ wiphy_name(priv->hw->wiphy), __func__);
+ return NETDEV_TX_BUSY;
+ }
+
+ ieee80211_stop_queues(hw);
+
+ at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+
+ WARN_ON(priv->tx_skb != NULL);
+
+ priv->tx_skb = skb;
+ padding = at76_calc_padding(skb->len);
+ submit_len = AT76_TX_HDRLEN + skb->len + padding;
+
+ /* setup 'Atmel' header */
+ memset(tx_buffer, 0, sizeof(*tx_buffer));
+ tx_buffer->padding = padding;
+ tx_buffer->wlength = cpu_to_le16(skb->len);
+ tx_buffer->tx_rate = ieee80211_get_tx_rate(hw, info)->hw_value;
+ memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
+ memcpy(tx_buffer->packet, skb->data, skb->len);
+
+ at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr",
+ wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength),
+ tx_buffer->padding, tx_buffer->tx_rate);
+
+ /* send stuff */
+ at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len,
+ "%s(): tx_buffer %d bytes:", __func__, submit_len);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
+ submit_len, at76_mac80211_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret) {
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ if (ret == -EINVAL)
+ printk(KERN_ERR
+ "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
+ wiphy_name(priv->hw->wiphy), priv->tx_urb,
+ priv->tx_urb->hcpriv, priv->tx_urb->complete);
+ }
+
+ return 0;
+}
+
+static int at76_mac80211_start(struct ieee80211_hw *hw)
+{
+ struct at76_priv *priv = hw->priv;
+ int ret;
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ mutex_lock(&priv->mtx);
+
+ ret = at76_submit_rx_urb(priv);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto error;
+ }
+
+ at76_startup_device(priv);
+
+ at76_start_monitor(priv);
+
+error:
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+static void at76_mac80211_stop(struct ieee80211_hw *hw)
+{
+ struct at76_priv *priv = hw->priv;
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ mutex_lock(&priv->mtx);
+
+ if (!priv->device_unplugged) {
+ /* We are called by "ifconfig ethX down", not because the
+ * device is not available anymore. */
+ at76_set_radio(priv, 0);
+
+ /* We unlink rx_urb because at76_open() re-submits it.
+ * If unplugged, at76_delete_device() takes care of it. */
+ usb_kill_urb(priv->rx_urb);
+ }
+
+ mutex_unlock(&priv->mtx);
+}
+
+static int at76_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct at76_priv *priv = hw->priv;
+ int ret = 0;
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ mutex_lock(&priv->mtx);
+
+ switch (conf->type) {
+ case NL80211_IFTYPE_STATION:
+ priv->iw_mode = IW_MODE_INFRA;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ goto exit;
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+
+ return ret;
+}
+
+static void at76_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+}
+
+static int at76_join(struct at76_priv *priv)
+{
+ struct at76_req_join join;
+ int ret;
+
+ memset(&join, 0, sizeof(struct at76_req_join));
+ memcpy(join.essid, priv->essid, priv->essid_size);
+ join.essid_size = priv->essid_size;
+ memcpy(join.bssid, priv->bssid, ETH_ALEN);
+ join.bss_type = INFRASTRUCTURE_MODE;
+ join.channel = priv->channel;
+ join.timeout = cpu_to_le16(2000);
+
+ at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
+ ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
+ sizeof(struct at76_req_join));
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ return 0;
+ }
+
+ ret = at76_wait_completion(priv, CMD_JOIN);
+ at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ return 0;
+ }
+
+ at76_set_pm_mode(priv);
+
+ return 0;
+}
+
+static void at76_dwork_hw_scan(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_hw_scan.work);
+ int ret;
+
+ if (priv->device_unplugged)
+ return;
+
+ mutex_lock(&priv->mtx);
+
+ ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
+ at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret);
+
+ /* FIXME: add maximum time for scan to complete */
+
+ if (ret != CMD_STATUS_COMPLETE) {
+ queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
+ SCAN_POLL_INTERVAL);
+ goto exit;
+ }
+
+ ieee80211_scan_completed(priv->hw, false);
+
+ if (is_valid_ether_addr(priv->bssid))
+ at76_join(priv);
+
+ ieee80211_wake_queues(priv->hw);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+static int at76_hw_scan(struct ieee80211_hw *hw,
+ struct cfg80211_scan_request *req)
+{
+ struct at76_priv *priv = hw->priv;
+ struct at76_req_scan scan;
+ u8 *ssid = NULL;
+ int ret, len = 0;
+
+ at76_dbg(DBG_MAC80211, "%s():", __func__);
+
+ if (priv->device_unplugged)
+ return 0;
+
+ mutex_lock(&priv->mtx);
+
+ ieee80211_stop_queues(hw);
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xFF, ETH_ALEN);
+
+ if (req->n_ssids) {
+ scan.scan_type = SCAN_TYPE_ACTIVE;
+ ssid = req->ssids[0].ssid;
+ len = req->ssids[0].ssid_len;
+ } else {
+ scan.scan_type = SCAN_TYPE_PASSIVE;
+ }
+
+ if (len) {
+ memcpy(scan.essid, ssid, len);
+ scan.essid_size = len;
+ }
+
+ scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
+ scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
+ scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
+ scan.international_scan = 0;
+
+ at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__);
+ ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+
+ if (ret < 0) {
+ err("CMD_SCAN failed: %d", ret);
+ goto exit;
+ }
+
+ queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
+ SCAN_POLL_INTERVAL);
+
+exit:
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+static int at76_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct at76_priv *priv = hw->priv;
+
+ at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
+ __func__, hw->conf.channel->hw_value,
+ hw->conf.radio_enabled);
+ at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
+
+ mutex_lock(&priv->mtx);
+
+ priv->channel = hw->conf.channel->hw_value;
+
+ if (is_valid_ether_addr(priv->bssid))
+ at76_join(priv);
+ else
+ at76_start_monitor(priv);
+
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+static int at76_config_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_if_conf *conf)
+{
+ struct at76_priv *priv = hw->priv;
+
+ at76_dbg(DBG_MAC80211, "%s():", __func__);
+ at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
+
+ mutex_lock(&priv->mtx);
+
+ memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+
+ if (is_valid_ether_addr(priv->bssid))
+ /* mac80211 is joining a bss */
+ at76_join(priv);
+
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+/* must be atomic */
+static void at76_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags, int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct at76_priv *priv = hw->priv;
+ int flags;
+
+ at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
+ "total_flags=0x%08x mc_count=%d",
+ __func__, changed_flags, *total_flags, mc_count);
+
+ flags = changed_flags & AT76_SUPPORTED_FILTERS;
+ *total_flags = AT76_SUPPORTED_FILTERS;
+
+ /* Bail out after updating flags to prevent a WARN_ON in mac80211. */
+ if (priv->device_unplugged)
+ return;
+
+ /* FIXME: access to priv->promisc should be protected with
+ * priv->mtx, but it's impossible because this function needs to be
+ * atomic */
+
+ if (flags && !priv->promisc) {
+ /* mac80211 wants us to enable promiscuous mode */
+ priv->promisc = 1;
+ } else if (!flags && priv->promisc) {
+ /* we need to disable promiscuous mode */
+ priv->promisc = 0;
+ } else
+ return;
+
+ queue_work(hw->workqueue, &priv->work_set_promisc);
+}
+
+static int at76_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 at76_priv *priv = hw->priv;
+
+ int i;
+
+ at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
+ "key->keylen %d",
+ __func__, cmd, key->alg, key->keyidx, key->keylen);
+
+ if (key->alg != ALG_WEP)
+ return -EOPNOTSUPP;
+
+ key->hw_key_idx = key->keyidx;
+
+ mutex_lock(&priv->mtx);
+
+ switch (cmd) {
+ case SET_KEY:
+ memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen);
+ priv->wep_keys_len[key->keyidx] = key->keylen;
+
+ /* FIXME: find out how to do this properly */
+ priv->wep_key_id = key->keyidx;
+
+ break;
+ case DISABLE_KEY:
+ default:
+ priv->wep_keys_len[key->keyidx] = 0;
+ break;
+ }
+
+ priv->wep_enabled = 0;
+
+ for (i = 0; i < WEP_KEYS; i++) {
+ if (priv->wep_keys_len[i] != 0)
+ priv->wep_enabled = 1;
+ }
+
+ at76_startup_device(priv);
+
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+static const struct ieee80211_ops at76_ops = {
+ .tx = at76_mac80211_tx,
+ .add_interface = at76_add_interface,
+ .remove_interface = at76_remove_interface,
+ .config = at76_config,
+ .config_interface = at76_config_interface,
+ .configure_filter = at76_configure_filter,
+ .start = at76_mac80211_start,
+ .stop = at76_mac80211_stop,
+ .hw_scan = at76_hw_scan,
+ .set_key = at76_set_key,
+};
+
+/* Allocate network device and initialize private data */
+static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
+{
+ struct ieee80211_hw *hw;
+ struct at76_priv *priv;
+
+ hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops);
+ if (!hw) {
+ printk(KERN_ERR DRIVER_NAME ": could not register"
+ " ieee80211_hw\n");
+ return NULL;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+
+ priv->udev = udev;
+
+ mutex_init(&priv->mtx);
+ INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
+ INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
+ INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
+
+ tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0);
+
+ priv->pm_mode = AT76_PM_OFF;
+ priv->pm_period = 0;
+
+ /* unit us */
+ priv->hw->channel_change_time = 100000;
+
+ return priv;
+}
+
+static int at76_alloc_urbs(struct at76_priv *priv,
+ struct usb_interface *interface)
+{
+ struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out;
+ int i;
+ int buffer_size;
+ struct usb_host_interface *iface_desc;
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
+
+ at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__,
+ interface->altsetting[0].desc.bNumEndpoints);
+
+ ep_in = NULL;
+ ep_out = NULL;
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x",
+ __func__, i, endpoint->bEndpointAddress,
+ endpoint->bmAttributes);
+
+ if (!ep_in && usb_endpoint_is_bulk_in(endpoint))
+ ep_in = endpoint;
+
+ if (!ep_out && usb_endpoint_is_bulk_out(endpoint))
+ ep_out = endpoint;
+ }
+
+ if (!ep_in || !ep_out) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "bulk endpoints missing\n");
+ return -ENXIO;
+ }
+
+ priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress);
+ priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress);
+
+ priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!priv->rx_urb || !priv->tx_urb) {
+ dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
+ return -ENOMEM;
+ }
+
+ buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
+ priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!priv->bulk_out_buffer) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot allocate output buffer\n");
+ return -ENOMEM;
+ }
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+
+ return 0;
+}
+
+static struct ieee80211_rate at76_rates[] = {
+ { .bitrate = 10, .hw_value = TX_RATE_1MBIT, },
+ { .bitrate = 20, .hw_value = TX_RATE_2MBIT, },
+ { .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, },
+ { .bitrate = 110, .hw_value = TX_RATE_11MBIT, },
+};
+
+static struct ieee80211_channel at76_channels[] = {
+ { .center_freq = 2412, .hw_value = 1 },
+ { .center_freq = 2417, .hw_value = 2 },
+ { .center_freq = 2422, .hw_value = 3 },
+ { .center_freq = 2427, .hw_value = 4 },
+ { .center_freq = 2432, .hw_value = 5 },
+ { .center_freq = 2437, .hw_value = 6 },
+ { .center_freq = 2442, .hw_value = 7 },
+ { .center_freq = 2447, .hw_value = 8 },
+ { .center_freq = 2452, .hw_value = 9 },
+ { .center_freq = 2457, .hw_value = 10 },
+ { .center_freq = 2462, .hw_value = 11 },
+ { .center_freq = 2467, .hw_value = 12 },
+ { .center_freq = 2472, .hw_value = 13 },
+ { .center_freq = 2484, .hw_value = 14 }
+};
+
+static struct ieee80211_supported_band at76_supported_band = {
+ .channels = at76_channels,
+ .n_channels = ARRAY_SIZE(at76_channels),
+ .bitrates = at76_rates,
+ .n_bitrates = ARRAY_SIZE(at76_rates),
+};
+
+/* Register network device and initialize the hardware */
+static int at76_init_new_device(struct at76_priv *priv,
+ struct usb_interface *interface)
+{
+ int ret;
+
+ /* set up the endpoint information */
+ /* check out the endpoints */
+
+ at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints",
+ interface->cur_altsetting->desc.bNumEndpoints);
+
+ ret = at76_alloc_urbs(priv, interface);
+ if (ret < 0)
+ goto exit;
+
+ /* MAC address */
+ ret = at76_get_hw_config(priv);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot get MAC address\n");
+ goto exit;
+ }
+
+ priv->domain = at76_get_reg_domain(priv->regulatory_domain);
+
+ priv->channel = DEF_CHANNEL;
+ priv->iw_mode = IW_MODE_INFRA;
+ priv->rts_threshold = DEF_RTS_THRESHOLD;
+ priv->frag_threshold = DEF_FRAG_THRESHOLD;
+ priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
+ priv->txrate = TX_RATE_AUTO;
+ priv->preamble_type = PREAMBLE_TYPE_LONG;
+ priv->beacon_period = 100;
+ priv->auth_mode = WLAN_AUTH_OPEN;
+ priv->scan_min_time = DEF_SCAN_MIN_TIME;
+ priv->scan_max_time = DEF_SCAN_MAX_TIME;
+ priv->scan_mode = SCAN_TYPE_ACTIVE;
+ priv->device_unplugged = 0;
+
+ /* mac80211 initialisation */
+ priv->hw->wiphy->max_scan_ssids = 1;
+ 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 |
+ IEEE80211_HW_SIGNAL_UNSPEC;
+ priv->hw->max_signal = 100;
+
+ SET_IEEE80211_DEV(priv->hw, &interface->dev);
+ SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+
+ ret = ieee80211_register_hw(priv->hw);
+ if (ret) {
+ printk(KERN_ERR "cannot register mac80211 hw (status %d)!\n",
+ ret);
+ goto exit;
+ }
+
+ priv->mac80211_registered = 1;
+
+ printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
+ wiphy_name(priv->hw->wiphy),
+ dev_name(&interface->dev), mac2str(priv->mac_addr),
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+ printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n",
+ wiphy_name(priv->hw->wiphy),
+ priv->regulatory_domain, priv->domain->name);
+
+exit:
+ return ret;
+}
+
+static void at76_delete_device(struct at76_priv *priv)
+{
+ at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
+
+ /* The device is gone, don't bother turning it off */
+ priv->device_unplugged = 1;
+
+ tasklet_kill(&priv->rx_tasklet);
+
+ if (priv->mac80211_registered) {
+ cancel_delayed_work(&priv->dwork_hw_scan);
+ flush_workqueue(priv->hw->workqueue);
+ ieee80211_unregister_hw(priv->hw);
+ }
+
+ if (priv->tx_urb) {
+ usb_kill_urb(priv->tx_urb);
+ usb_free_urb(priv->tx_urb);
+ }
+ if (priv->rx_urb) {
+ usb_kill_urb(priv->rx_urb);
+ usb_free_urb(priv->rx_urb);
+ }
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
+
+ kfree(priv->bulk_out_buffer);
+
+ del_timer_sync(&ledtrig_tx_timer);
+
+ if (priv->rx_skb)
+ kfree_skb(priv->rx_skb);
+
+ usb_put_dev(priv->udev);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw",
+ __func__);
+ ieee80211_free_hw(priv->hw);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+}
+
+static int at76_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ int ret;
+ struct at76_priv *priv;
+ struct fwentry *fwe;
+ struct usb_device *udev;
+ int op_mode;
+ int need_ext_fw = 0;
+ struct mib_fw_version fwv;
+ int board_type = (int)id->driver_info;
+
+ udev = usb_get_dev(interface_to_usbdev(interface));
+
+ /* Load firmware into kernel memory */
+ fwe = at76_load_firmware(udev, board_type);
+ if (!fwe) {
+ ret = -ENOENT;
+ goto error;
+ }
+
+ op_mode = at76_get_op_mode(udev);
+
+ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+ /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
+ we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
+
+ if (op_mode == OPMODE_HW_CONFIG_MODE) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot handle a device in HW_CONFIG_MODE\n");
+ ret = -EBUSY;
+ goto error;
+ }
+
+ if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
+ && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+ /* download internal firmware part */
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading internal firmware\n");
+ ret = at76_load_internal_fw(udev, fwe);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d downloading internal firmware\n",
+ ret);
+ goto error;
+ }
+ usb_put_dev(udev);
+ return ret;
+ }
+
+ /* Internal firmware already inside the device. Get firmware
+ * version to test if external firmware is loaded.
+ * This works only for newer firmware, e.g. the Intersil 0.90.x
+ * says "control timeout on ep0in" and subsequent
+ * at76_get_op_mode() fail too :-( */
+
+ /* if version >= 0.100.x.y or device with built-in flash we can
+ * query the device for the fw version */
+ if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
+ || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
+ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+ if (ret < 0 || (fwv.major | fwv.minor) == 0)
+ need_ext_fw = 1;
+ } else
+ /* No way to check firmware version, reload to be sure */
+ need_ext_fw = 1;
+
+ if (need_ext_fw) {
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading external firmware\n");
+
+ ret = at76_load_external_fw(udev, fwe);
+ if (ret)
+ goto error;
+
+ /* Re-check firmware version */
+ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d getting firmware version\n", ret);
+ goto error;
+ }
+ }
+
+ priv = at76_alloc_new_device(udev);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ usb_set_intfdata(interface, priv);
+
+ memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
+ priv->board_type = board_type;
+
+ ret = at76_init_new_device(priv, interface);
+ if (ret < 0)
+ at76_delete_device(priv);
+
+ return ret;
+
+error:
+ usb_put_dev(udev);
+ return ret;
+}
+
+static void at76_disconnect(struct usb_interface *interface)
+{
+ struct at76_priv *priv;
+
+ priv = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ /* Disconnect after loading internal firmware */
+ if (!priv)
+ return;
+
+ printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
+ at76_delete_device(priv);
+ dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
+}
+
+/* Structure for registering this driver with the USB subsystem */
+static struct usb_driver at76_driver = {
+ .name = DRIVER_NAME,
+ .probe = at76_probe,
+ .disconnect = at76_disconnect,
+ .id_table = dev_table,
+};
+
+static int __init at76_mod_init(void)
+{
+ int result;
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
+
+ mutex_init(&fw_mutex);
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&at76_driver);
+ if (result < 0)
+ printk(KERN_ERR DRIVER_NAME
+ ": usb_register failed (status %d)\n", result);
+
+ led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
+ return result;
+}
+
+static void __exit at76_mod_exit(void)
+{
+ int i;
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
+ usb_deregister(&at76_driver);
+ for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
+ if (firmwares[i].fw)
+ release_firmware(firmwares[i].fw);
+ }
+ led_trigger_unregister_simple(ledtrig_tx);
+}
+
+module_param_named(debug, at76_debug, uint, 0600);
+MODULE_PARM_DESC(debug, "Debugging level");
+
+module_init(at76_mod_init);
+module_exit(at76_mod_exit);
+
+MODULE_AUTHOR("Oliver Kurth <oku@masqmail.cx>");
+MODULE_AUTHOR("Joerg Albert <joerg.albert@gmx.de>");
+MODULE_AUTHOR("Alex <alex@foogod.com>");
+MODULE_AUTHOR("Nick Jones");
+MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
+MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/at76c50x-usb.h b/drivers/net/wireless/at76c50x-usb.h
new file mode 100644
index 00000000000..1ec5ccffdbc
--- /dev/null
+++ b/drivers/net/wireless/at76c50x-usb.h
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2002,2003 Oliver Kurth
+ * (c) 2003,2004 Joerg Albert <joerg.albert@gmx.de>
+ * (c) 2007 Guido Guenther <agx@sigxcpu.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This driver was based on information from the Sourceforge driver
+ * released and maintained by Atmel:
+ *
+ * http://sourceforge.net/projects/atmelwlandriver/
+ *
+ * Although the code was completely re-written,
+ * it would have been impossible without Atmel's decision to
+ * release an Open Source driver (unfortunately the firmware was
+ * kept binary only). Thanks for that decision to Atmel!
+ */
+
+#ifndef _AT76_USB_H
+#define _AT76_USB_H
+
+/* Board types */
+enum board_type {
+ BOARD_503_ISL3861 = 1,
+ BOARD_503_ISL3863 = 2,
+ BOARD_503 = 3,
+ BOARD_503_ACC = 4,
+ BOARD_505 = 5,
+ BOARD_505_2958 = 6,
+ BOARD_505A = 7,
+ BOARD_505AMX = 8
+};
+
+#define CMD_STATUS_IDLE 0x00
+#define CMD_STATUS_COMPLETE 0x01
+#define CMD_STATUS_UNKNOWN 0x02
+#define CMD_STATUS_INVALID_PARAMETER 0x03
+#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
+#define CMD_STATUS_TIME_OUT 0x07
+#define CMD_STATUS_IN_PROGRESS 0x08
+#define CMD_STATUS_HOST_FAILURE 0xff
+#define CMD_STATUS_SCAN_FAILED 0xf0
+
+/* answers to get op mode */
+#define OPMODE_NONE 0x00
+#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01
+#define OPMODE_HW_CONFIG_MODE 0x02
+#define OPMODE_DFU_MODE_WITH_FLASH 0x03
+#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04
+
+#define CMD_SET_MIB 0x01
+#define CMD_GET_MIB 0x02
+#define CMD_SCAN 0x03
+#define CMD_JOIN 0x04
+#define CMD_START_IBSS 0x05
+#define CMD_RADIO_ON 0x06
+#define CMD_RADIO_OFF 0x07
+#define CMD_STARTUP 0x0B
+
+#define MIB_LOCAL 0x01
+#define MIB_MAC_ADDR 0x02
+#define MIB_MAC 0x03
+#define MIB_MAC_MGMT 0x05
+#define MIB_MAC_WEP 0x06
+#define MIB_PHY 0x07
+#define MIB_FW_VERSION 0x08
+#define MIB_MDOMAIN 0x09
+
+#define ADHOC_MODE 1
+#define INFRASTRUCTURE_MODE 2
+
+/* values for struct mib_local, field preamble_type */
+#define PREAMBLE_TYPE_LONG 0
+#define PREAMBLE_TYPE_SHORT 1
+#define PREAMBLE_TYPE_AUTO 2
+
+/* values for tx_rate */
+#define TX_RATE_1MBIT 0
+#define TX_RATE_2MBIT 1
+#define TX_RATE_5_5MBIT 2
+#define TX_RATE_11MBIT 3
+#define TX_RATE_AUTO 4
+
+/* power management modes */
+#define AT76_PM_OFF 1
+#define AT76_PM_ON 2
+#define AT76_PM_SMART 3
+
+struct hwcfg_r505 {
+ u8 cr39_values[14];
+ u8 reserved1[14];
+ u8 bb_cr[14];
+ u8 pidvid[4];
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+ u8 reserved2[14];
+ u8 cr15_values[14];
+ u8 reserved3[3];
+} __attribute__((packed));
+
+struct hwcfg_rfmd {
+ u8 cr20_values[14];
+ u8 cr21_values[14];
+ u8 bb_cr[14];
+ u8 pidvid[4];
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+ u8 low_power_values[14];
+ u8 normal_power_values[14];
+ u8 reserved1[3];
+} __attribute__((packed));
+
+struct hwcfg_intersil {
+ u8 mac_addr[ETH_ALEN];
+ u8 cr31_values[14];
+ u8 cr58_values[14];
+ u8 pidvid[4];
+ u8 regulatory_domain;
+ u8 reserved[1];
+} __attribute__((packed));
+
+union at76_hwcfg {
+ struct hwcfg_intersil i;
+ struct hwcfg_rfmd r3;
+ struct hwcfg_r505 r5;
+};
+
+#define WEP_SMALL_KEY_LEN (40 / 8)
+#define WEP_LARGE_KEY_LEN (104 / 8)
+#define WEP_KEYS (4)
+
+struct at76_card_config {
+ u8 exclude_unencrypted;
+ u8 promiscuous_mode;
+ u8 short_retry_limit;
+ u8 encryption_type;
+ __le16 rts_threshold;
+ __le16 fragmentation_threshold; /* 256..2346 */
+ u8 basic_rate_set[4];
+ u8 auto_rate_fallback; /* 0,1 */
+ u8 channel;
+ u8 privacy_invoked;
+ u8 wep_default_key_id; /* 0..3 */
+ u8 current_ssid[32];
+ u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN];
+ u8 ssid_len;
+ u8 short_preamble;
+ __le16 beacon_period;
+} __attribute__((packed));
+
+struct at76_command {
+ u8 cmd;
+ u8 reserved;
+ __le16 size;
+ u8 data[0];
+} __attribute__((packed));
+
+/* Length of Atmel-specific Rx header before 802.11 frame */
+#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet)
+
+struct at76_rx_buffer {
+ __le16 wlength;
+ u8 rx_rate;
+ u8 newbss;
+ u8 fragmentation;
+ u8 rssi;
+ u8 link_quality;
+ u8 noise_level;
+ __le32 rx_time;
+ u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+} __attribute__((packed));
+
+/* Length of Atmel-specific Tx header before 802.11 frame */
+#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet)
+
+struct at76_tx_buffer {
+ __le16 wlength;
+ u8 tx_rate;
+ u8 padding;
+ u8 reserved[4];
+ u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+} __attribute__((packed));
+
+/* defines for scan_type below */
+#define SCAN_TYPE_ACTIVE 0
+#define SCAN_TYPE_PASSIVE 1
+
+struct at76_req_scan {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 scan_type;
+ u8 channel;
+ __le16 probe_delay;
+ __le16 min_channel_time;
+ __le16 max_channel_time;
+ u8 essid_size;
+ u8 international_scan;
+} __attribute__((packed));
+
+struct at76_req_ibss {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 bss_type;
+ u8 channel;
+ u8 essid_size;
+ u8 reserved[3];
+} __attribute__((packed));
+
+struct at76_req_join {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 bss_type;
+ u8 channel;
+ __le16 timeout;
+ u8 essid_size;
+ u8 reserved;
+} __attribute__((packed));
+
+struct set_mib_buffer {
+ u8 type;
+ u8 size;
+ u8 index;
+ u8 reserved;
+ union {
+ u8 byte;
+ __le16 word;
+ u8 addr[ETH_ALEN];
+ } data;
+} __attribute__((packed));
+
+struct mib_local {
+ u16 reserved0;
+ u8 beacon_enable;
+ u8 txautorate_fallback;
+ u8 reserved1;
+ u8 ssid_size;
+ u8 promiscuous_mode;
+ u16 reserved2;
+ u8 preamble_type;
+ u16 reserved3;
+} __attribute__((packed));
+
+struct mib_mac_addr {
+ u8 mac_addr[ETH_ALEN];
+ u8 res[2]; /* ??? */
+ u8 group_addr[4][ETH_ALEN];
+ u8 group_addr_status[4];
+} __attribute__((packed));
+
+struct mib_mac {
+ __le32 max_tx_msdu_lifetime;
+ __le32 max_rx_lifetime;
+ __le16 frag_threshold;
+ __le16 rts_threshold;
+ __le16 cwmin;
+ __le16 cwmax;
+ u8 short_retry_time;
+ u8 long_retry_time;
+ u8 scan_type; /* active or passive */
+ u8 scan_channel;
+ __le16 probe_delay; /* delay before ProbeReq in active scan, RO */
+ __le16 min_channel_time;
+ __le16 max_channel_time;
+ __le16 listen_interval;
+ u8 desired_ssid[32];
+ u8 desired_bssid[ETH_ALEN];
+ u8 desired_bsstype; /* ad-hoc or infrastructure */
+ u8 reserved2;
+} __attribute__((packed));
+
+struct mib_mac_mgmt {
+ __le16 beacon_period;
+ __le16 CFP_max_duration;
+ __le16 medium_occupancy_limit;
+ __le16 station_id; /* assoc id */
+ __le16 ATIM_window;
+ u8 CFP_mode;
+ u8 privacy_option_implemented;
+ u8 DTIM_period;
+ u8 CFP_period;
+ u8 current_bssid[ETH_ALEN];
+ u8 current_essid[32];
+ u8 current_bss_type;
+ u8 power_mgmt_mode;
+ /* rfmd and 505 */
+ u8 ibss_change;
+ u8 res;
+ u8 multi_domain_capability_implemented;
+ u8 multi_domain_capability_enabled;
+ u8 country_string[3];
+ u8 reserved[3];
+} __attribute__((packed));
+
+struct mib_mac_wep {
+ u8 privacy_invoked; /* 0 disable encr., 1 enable encr */
+ u8 wep_default_key_id;
+ u8 wep_key_mapping_len;
+ u8 exclude_unencrypted;
+ __le32 wep_icv_error_count;
+ __le32 wep_excluded_count;
+ u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN];
+ u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
+} __attribute__((packed));
+
+struct mib_phy {
+ __le32 ed_threshold;
+
+ __le16 slot_time;
+ __le16 sifs_time;
+ __le16 preamble_length;
+ __le16 plcp_header_length;
+ __le16 mpdu_max_length;
+ __le16 cca_mode_supported;
+
+ u8 operation_rate_set[4];
+ u8 channel_id;
+ u8 current_cca_mode;
+ u8 phy_type;
+ u8 current_reg_domain;
+} __attribute__((packed));
+
+struct mib_fw_version {
+ u8 major;
+ u8 minor;
+ u8 patch;
+ u8 build;
+} __attribute__((packed));
+
+struct mib_mdomain {
+ u8 tx_powerlevel[14];
+ u8 channel_list[14]; /* 0 for invalid channels */
+} __attribute__((packed));
+
+struct at76_fw_header {
+ __le32 crc; /* CRC32 of the whole image */
+ __le32 board_type; /* firmware compatibility code */
+ u8 build; /* firmware build number */
+ u8 patch; /* firmware patch level */
+ u8 minor; /* firmware minor version */
+ u8 major; /* firmware major version */
+ __le32 str_offset; /* offset of the copyright string */
+ __le32 int_fw_offset; /* internal firmware image offset */
+ __le32 int_fw_len; /* internal firmware image length */
+ __le32 ext_fw_offset; /* external firmware image offset */
+ __le32 ext_fw_len; /* external firmware image length */
+} __attribute__((packed));
+
+/* a description of a regulatory domain and the allowed channels */
+struct reg_domain {
+ u16 code;
+ char const *name;
+ u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
+};
+
+/* Data for one loaded firmware file */
+struct fwentry {
+ const char *const fwname;
+ const struct firmware *fw;
+ int extfw_size;
+ int intfw_size;
+ /* pointer to loaded firmware, no need to free */
+ u8 *extfw; /* external firmware, extfw_size bytes long */
+ u8 *intfw; /* internal firmware, intfw_size bytes long */
+ enum board_type board_type; /* board type */
+ struct mib_fw_version fw_version;
+ int loaded; /* Loaded and parsed successfully */
+};
+
+struct at76_priv {
+ struct usb_device *udev; /* USB device pointer */
+
+ struct sk_buff *rx_skb; /* skbuff for receiving data */
+ struct sk_buff *tx_skb; /* skbuff for transmitting data */
+ void *bulk_out_buffer; /* buffer for sending data */
+
+ struct urb *tx_urb; /* URB for sending data */
+ struct urb *rx_urb; /* URB for receiving data */
+
+ unsigned int tx_pipe; /* bulk out pipe */
+ unsigned int rx_pipe; /* bulk in pipe */
+
+ struct mutex mtx; /* locks this structure */
+
+ /* work queues */
+ struct work_struct work_set_promisc;
+ struct work_struct work_submit_rx;
+ struct delayed_work dwork_hw_scan;
+
+ struct tasklet_struct rx_tasklet;
+
+ /* the WEP stuff */
+ int wep_enabled; /* 1 if WEP is enabled */
+ int wep_key_id; /* key id to be used */
+ u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN]; /* WEP keys */
+ u8 wep_keys_len[WEP_KEYS]; /* length of WEP keys */
+
+ int channel;
+ int iw_mode;
+ u8 bssid[ETH_ALEN];
+ u8 essid[IW_ESSID_MAX_SIZE];
+ int essid_size;
+ int radio_on;
+ int promisc;
+
+ int preamble_type; /* 0 - long, 1 - short, 2 - auto */
+ int auth_mode; /* authentication type: 0 open, 1 shared key */
+ int txrate; /* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */
+ int frag_threshold; /* threshold for fragmentation of tx packets */
+ int rts_threshold; /* threshold for RTS mechanism */
+ int short_retry_limit;
+
+ int scan_min_time; /* scan min channel time */
+ int scan_max_time; /* scan max channel time */
+ int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
+ int scan_need_any; /* if set, need to scan for any ESSID */
+
+ u16 assoc_id; /* current association ID, if associated */
+
+ u8 pm_mode; /* power management mode */
+ u32 pm_period; /* power management period in microseconds */
+
+ struct reg_domain const *domain; /* reg domain description */
+
+ /* These fields contain HW config provided by the device (not all of
+ * these fields are used by all board types) */
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+
+ struct at76_card_config card_config;
+
+ enum board_type board_type;
+ struct mib_fw_version fw_version;
+
+ unsigned int device_unplugged:1;
+ unsigned int netdev_registered:1;
+ struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
+
+ int beacon_period; /* period of mgmt beacons, Kus */
+
+ struct ieee80211_hw *hw;
+ int mac80211_registered;
+};
+
+#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS
+
+#define SCAN_POLL_INTERVAL (HZ / 4)
+
+#define CMD_COMPLETION_TIMEOUT (5 * HZ)
+
+#define DEF_RTS_THRESHOLD 1536
+#define DEF_FRAG_THRESHOLD 1536
+#define DEF_SHORT_RETRY_LIMIT 8
+#define DEF_CHANNEL 10
+#define DEF_SCAN_MIN_TIME 10
+#define DEF_SCAN_MAX_TIME 120
+
+/* the max padding size for tx in bytes (see calc_padding) */
+#define MAX_PADDING_SIZE 53
+
+#endif /* _AT76_USB_H */
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile
index 719cfaef708..84a74c5248e 100644
--- a/drivers/net/wireless/ath5k/Makefile
+++ b/drivers/net/wireless/ath5k/Makefile
@@ -10,5 +10,6 @@ ath5k-y += phy.o
ath5k-y += reset.o
ath5k-y += attach.o
ath5k-y += base.o
+ath5k-y += led.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 183ffc8e62c..0dc2c7321c8 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -165,9 +165,6 @@
#define AR5K_INI_VAL_XR 0
#define AR5K_INI_VAL_MAX 5
-#define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
-#define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
-
/* Used for BSSID etc manipulation */
#define AR5K_LOW_ID(_a)( \
(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
@@ -225,6 +222,7 @@
#endif
/* Initial values */
+#define AR5K_INIT_CYCRSSI_THR1 2
#define AR5K_INIT_TX_LATENCY 502
#define AR5K_INIT_USEC 39
#define AR5K_INIT_USEC_TURBO 79
@@ -316,7 +314,7 @@ struct ath5k_srev_name {
#define AR5K_SREV_AR5424 0x90 /* Condor */
#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */
#define AR5K_SREV_AR5414 0xa0 /* Eagle */
-#define AR5K_SREV_AR2415 0xb0 /* Cobra */
+#define AR5K_SREV_AR2415 0xb0 /* Talon */
#define AR5K_SREV_AR5416 0xc0 /* PCI-E */
#define AR5K_SREV_AR5418 0xca /* PCI-E */
#define AR5K_SREV_AR2425 0xe0 /* Swan */
@@ -334,7 +332,7 @@ struct ath5k_srev_name {
#define AR5K_SREV_RAD_2112B 0x46
#define AR5K_SREV_RAD_2413 0x50
#define AR5K_SREV_RAD_5413 0x60
-#define AR5K_SREV_RAD_2316 0x70
+#define AR5K_SREV_RAD_2316 0x70 /* Cobra SoC */
#define AR5K_SREV_RAD_2317 0x80
#define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */
#define AR5K_SREV_RAD_2425 0xa2
@@ -342,7 +340,8 @@ struct ath5k_srev_name {
#define AR5K_SREV_PHY_5211 0x30
#define AR5K_SREV_PHY_5212 0x41
-#define AR5K_SREV_PHY_2112B 0x43
+#define AR5K_SREV_PHY_5212A 0x42
+#define AR5K_SREV_PHY_5212B 0x43
#define AR5K_SREV_PHY_2413 0x45
#define AR5K_SREV_PHY_5413 0x61
#define AR5K_SREV_PHY_2425 0x70
@@ -649,49 +648,21 @@ struct ath5k_beacon_state {
enum ath5k_rfgain {
AR5K_RFGAIN_INACTIVE = 0,
+ AR5K_RFGAIN_ACTIVE,
AR5K_RFGAIN_READ_REQUESTED,
AR5K_RFGAIN_NEED_CHANGE,
};
-#define AR5K_GAIN_CRN_FIX_BITS_5111 4
-#define AR5K_GAIN_CRN_FIX_BITS_5112 7
-#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
-#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
-#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
-#define AR5K_GAIN_CCK_PROBE_CORR 5
-#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
-#define AR5K_GAIN_STEP_COUNT 10
-#define AR5K_GAIN_PARAM_TX_CLIP 0
-#define AR5K_GAIN_PARAM_PD_90 1
-#define AR5K_GAIN_PARAM_PD_84 2
-#define AR5K_GAIN_PARAM_GAIN_SEL 3
-#define AR5K_GAIN_PARAM_MIX_ORN 0
-#define AR5K_GAIN_PARAM_PD_138 1
-#define AR5K_GAIN_PARAM_PD_137 2
-#define AR5K_GAIN_PARAM_PD_136 3
-#define AR5K_GAIN_PARAM_PD_132 4
-#define AR5K_GAIN_PARAM_PD_131 5
-#define AR5K_GAIN_PARAM_PD_130 6
-#define AR5K_GAIN_CHECK_ADJUST(_g) \
- ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
-
-struct ath5k_gain_opt_step {
- s16 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
- s32 gos_gain;
-};
-
struct ath5k_gain {
- u32 g_step_idx;
- u32 g_current;
- u32 g_target;
- u32 g_low;
- u32 g_high;
- u32 g_f_corr;
- u32 g_active;
- const struct ath5k_gain_opt_step *g_step;
+ u8 g_step_idx;
+ u8 g_current;
+ u8 g_target;
+ u8 g_low;
+ u8 g_high;
+ u8 g_f_corr;
+ u8 g_state;
};
-
/********************\
COMMON DEFINITIONS
\********************/
@@ -1053,7 +1024,6 @@ struct ath5k_hw {
bool ah_running;
bool ah_single_chip;
bool ah_combined_mic;
- enum ath5k_rfgain ah_rf_gain;
u32 ah_mac_srev;
u16 ah_mac_version;
@@ -1061,7 +1031,6 @@ struct ath5k_hw {
u16 ah_phy_revision;
u16 ah_radio_5ghz_revision;
u16 ah_radio_2ghz_revision;
- u32 ah_phy_spending;
enum ath5k_version ah_version;
enum ath5k_radio ah_radio;
@@ -1112,8 +1081,9 @@ struct ath5k_hw {
u32 ah_txq_isr;
u32 *ah_rf_banks;
size_t ah_rf_banks_size;
+ size_t ah_rf_regs_count;
struct ath5k_gain ah_gain;
- u32 ah_offset[AR5K_MAX_RF_BANKS];
+ u8 ah_offset[AR5K_MAX_RF_BANKS];
struct {
u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE];
@@ -1159,6 +1129,12 @@ struct ath5k_hw {
extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
extern void ath5k_hw_detach(struct ath5k_hw *ah);
+/* LED functions */
+extern int ath5k_init_leds(struct ath5k_softc *sc);
+extern void ath5k_led_enable(struct ath5k_softc *sc);
+extern void ath5k_led_off(struct ath5k_softc *sc);
+extern void ath5k_unregister_leds(struct ath5k_softc *sc);
+
/* Reset Functions */
extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
@@ -1186,6 +1162,7 @@ extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_l
/* EEPROM access functions */
extern int ath5k_eeprom_init(struct ath5k_hw *ah);
extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
+extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
/* Protocol Control Unit Functions */
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
@@ -1206,6 +1183,7 @@ extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
/* Beacon control functions */
extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
+extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
#if 0
@@ -1260,10 +1238,12 @@ extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
/* Initialize RF */
-extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode);
-extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq);
-extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah);
-extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah);
+extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel,
+ unsigned int mode);
+extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
+extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
+extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
/* PHY/RF channel functions */
extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
@@ -1285,6 +1265,7 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
/*
* Translate usec to hw clock units
+ * TODO: Half/quarter rate
*/
static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
{
@@ -1293,6 +1274,7 @@ static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
/*
* Translate hw clock units to usec
+ * TODO: Half/quarter rate
*/
static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
{
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c
index dea378f7673..656cb9dc833 100644
--- a/drivers/net/wireless/ath5k/attach.c
+++ b/drivers/net/wireless/ath5k/attach.c
@@ -34,14 +34,14 @@
static int ath5k_hw_post(struct ath5k_hw *ah)
{
- int i, c;
- u16 cur_reg;
- u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
- u32 var_pattern;
- u32 static_pattern[4] = {
+ static const u32 static_pattern[4] = {
0x55555555, 0xaaaaaaaa,
0x66666666, 0x99999999
};
+ static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
+ int i, c;
+ u16 cur_reg;
+ u32 var_pattern;
u32 init_val;
u32 cur_val;
@@ -106,7 +106,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
{
struct ath5k_hw *ah;
struct pci_dev *pdev = sc->pdev;
- u8 mac[ETH_ALEN] = {};
int ret;
u32 srev;
@@ -169,7 +168,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
ah->ah_single_chip = false;
ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
CHANNEL_2GHZ);
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
break;
case AR5K_SREV_RAD_5112:
case AR5K_SREV_RAD_2112:
@@ -177,38 +175,31 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
ah->ah_single_chip = false;
ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
CHANNEL_2GHZ);
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
break;
case AR5K_SREV_RAD_2413:
ah->ah_radio = AR5K_RF2413;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
break;
case AR5K_SREV_RAD_5413:
ah->ah_radio = AR5K_RF5413;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
break;
case AR5K_SREV_RAD_2316:
ah->ah_radio = AR5K_RF2316;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
break;
case AR5K_SREV_RAD_2317:
ah->ah_radio = AR5K_RF2317;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317;
break;
case AR5K_SREV_RAD_5424:
if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
ah->ah_mac_version == AR5K_SREV_AR2417){
ah->ah_radio = AR5K_RF2425;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
} else {
ah->ah_radio = AR5K_RF5413;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
}
break;
default:
@@ -227,29 +218,25 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
ah->ah_radio = AR5K_RF2425;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
} else if (srev == AR5K_SREV_AR5213A &&
- ah->ah_phy_revision == AR5K_SREV_PHY_2112B) {
+ ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
ah->ah_radio = AR5K_RF5112;
ah->ah_single_chip = false;
- ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B;
+ ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
} else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
ah->ah_radio = AR5K_RF2316;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
} else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
ah->ah_radio = AR5K_RF5413;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
} else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
ah->ah_radio = AR5K_RF2413;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
} else {
ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
ret = -ENODEV;
@@ -324,14 +311,14 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
}
/* MAC address is cleared until add_interface */
- ath5k_hw_set_lladdr(ah, mac);
+ ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
memset(ah->ah_bssid, 0xff, ETH_ALEN);
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
ath5k_hw_set_opmode(ah);
- ath5k_hw_set_rfgain_opt(ah);
+ ath5k_hw_rfgain_opt_init(ah);
return ah;
err_free:
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 8ef87356e08..cad3ccf61b0 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -79,7 +79,7 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
/* Known PCI ids */
-static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
+static const struct pci_device_id ath5k_pci_id_table[] = {
{ PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
{ PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
{ PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
@@ -103,7 +103,7 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
/* Known SREVs */
-static struct ath5k_srev_name srev_names[] = {
+static const struct ath5k_srev_name srev_names[] = {
{ "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },
{ "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },
{ "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },
@@ -142,7 +142,7 @@ static struct ath5k_srev_name srev_names[] = {
{ "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
};
-static struct ieee80211_rate ath5k_rates[] = {
+static const struct ieee80211_rate ath5k_rates[] = {
{ .bitrate = 10,
.hw_value = ATH5K_RATE_CODE_1M, },
{ .bitrate = 20,
@@ -232,13 +232,14 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
int mc_count, struct dev_mc_list *mclist);
static int ath5k_set_key(struct ieee80211_hw *hw,
enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key);
static int ath5k_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats);
static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
+static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
static void ath5k_reset_tsf(struct ieee80211_hw *hw);
static int ath5k_beacon_update(struct ath5k_softc *sc,
struct sk_buff *skb);
@@ -247,7 +248,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
-static struct ieee80211_ops ath5k_hw_ops = {
+static const struct ieee80211_ops ath5k_hw_ops = {
.tx = ath5k_tx,
.start = ath5k_start,
.stop = ath5k_stop,
@@ -261,6 +262,7 @@ static struct ieee80211_ops ath5k_hw_ops = {
.conf_tx = NULL,
.get_tx_stats = ath5k_get_tx_stats,
.get_tsf = ath5k_get_tsf,
+ .set_tsf = ath5k_set_tsf,
.reset_tsf = ath5k_reset_tsf,
.bss_info_changed = ath5k_bss_info_changed,
};
@@ -308,6 +310,19 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
bf->skb = NULL;
}
+static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
+ struct ath5k_buf *bf)
+{
+ BUG_ON(!bf);
+ if (!bf->skb)
+ return;
+ pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+ PCI_DMA_FROMDEVICE);
+ dev_kfree_skb_any(bf->skb);
+ bf->skb = NULL;
+}
+
+
/* Queues setup */
static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
int qtype, int subtype);
@@ -335,6 +350,7 @@ static int ath5k_beacon_setup(struct ath5k_softc *sc,
static void ath5k_beacon_send(struct ath5k_softc *sc);
static void ath5k_beacon_config(struct ath5k_softc *sc);
static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
+static void ath5k_tasklet_beacon(unsigned long data);
static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
{
@@ -347,18 +363,13 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
}
/* Interrupt handling */
-static int ath5k_init(struct ath5k_softc *sc, bool is_resume);
+static int ath5k_init(struct ath5k_softc *sc);
static int ath5k_stop_locked(struct ath5k_softc *sc);
-static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
+static int ath5k_stop_hw(struct ath5k_softc *sc);
static irqreturn_t ath5k_intr(int irq, void *dev_id);
static void ath5k_tasklet_reset(unsigned long data);
static void ath5k_calibrate(unsigned long data);
-/* LED functions */
-static int ath5k_init_leds(struct ath5k_softc *sc);
-static void ath5k_led_enable(struct ath5k_softc *sc);
-static void ath5k_led_off(struct ath5k_softc *sc);
-static void ath5k_unregister_leds(struct ath5k_softc *sc);
/*
* Module init/exit functions
@@ -653,8 +664,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
ath5k_led_off(sc);
- ath5k_stop_hw(sc, true);
-
free_irq(pdev->irq, sc);
pci_save_state(pdev);
pci_disable_device(pdev);
@@ -689,14 +698,9 @@ ath5k_pci_resume(struct pci_dev *pdev)
goto err_no_irq;
}
- err = ath5k_init(sc, true);
- if (err)
- goto err_irq;
ath5k_led_enable(sc);
-
return 0;
-err_irq:
- free_irq(pdev->irq, sc);
+
err_no_irq:
pci_disable_device(pdev);
return err;
@@ -781,6 +785,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
+ tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
ret = ath5k_eeprom_read_mac(ah, mac);
@@ -1028,6 +1033,8 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
* it's done by reseting the chip. To accomplish this we must
* first cleanup any pending DMA, then restart stuff after a la
* ath5k_init.
+ *
+ * Called with sc->lock.
*/
static int
ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
@@ -1088,7 +1095,8 @@ ath5k_mode_setup(struct ath5k_softc *sc)
static inline int
ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
{
- WARN_ON(hw_rix < 0 || hw_rix > AR5K_MAX_RATES);
+ WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
+ "hw_rix out of bounds: %x\n", hw_rix);
return sc->rate_idx[sc->curband->band][hw_rix];
}
@@ -1096,6 +1104,42 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
* Buffers setup *
\***************/
+static
+struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
+{
+ struct sk_buff *skb;
+ unsigned int off;
+
+ /*
+ * Allocate buffer with headroom_needed space for the
+ * fake physical layer header at the start.
+ */
+ skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
+
+ if (!skb) {
+ ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
+ sc->rxbufsize + sc->cachelsz - 1);
+ return NULL;
+ }
+ /*
+ * Cache-line-align. This is important (for the
+ * 5210 at least) as not doing so causes bogus data
+ * in rx'd frames.
+ */
+ off = ((unsigned long)skb->data) % sc->cachelsz;
+ if (off != 0)
+ skb_reserve(skb, sc->cachelsz - off);
+
+ *skb_addr = pci_map_single(sc->pdev,
+ skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
+ ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
+ dev_kfree_skb(skb);
+ return NULL;
+ }
+ return skb;
+}
+
static int
ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
{
@@ -1103,37 +1147,11 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct sk_buff *skb = bf->skb;
struct ath5k_desc *ds;
- if (likely(skb == NULL)) {
- unsigned int off;
-
- /*
- * Allocate buffer with headroom_needed space for the
- * fake physical layer header at the start.
- */
- skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
- if (unlikely(skb == NULL)) {
- ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
- sc->rxbufsize + sc->cachelsz - 1);
+ if (!skb) {
+ skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
+ if (!skb)
return -ENOMEM;
- }
- /*
- * Cache-line-align. This is important (for the
- * 5210 at least) as not doing so causes bogus data
- * in rx'd frames.
- */
- off = ((unsigned long)skb->data) % sc->cachelsz;
- if (off != 0)
- skb_reserve(skb, sc->cachelsz - off);
-
bf->skb = skb;
- bf->skbaddr = pci_map_single(sc->pdev,
- skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) {
- ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
- dev_kfree_skb(skb);
- bf->skb = NULL;
- return -ENOMEM;
- }
}
/*
@@ -1176,6 +1194,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct ieee80211_rate *rate;
unsigned int mrr_rate[3], mrr_tries[3];
int i, ret;
+ u16 hw_rate;
+ u16 cts_rate = 0;
+ u16 duration = 0;
+ u8 rc_flags;
flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
@@ -1183,20 +1205,39 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE);
+ rate = ieee80211_get_tx_rate(sc->hw, info);
+
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
flags |= AR5K_TXDESC_NOACK;
+ rc_flags = info->control.rates[0].flags;
+ hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+ rate->hw_value_short : rate->hw_value;
+
pktlen = skb->len;
if (info->control.hw_key) {
keyidx = info->control.hw_key->hw_key_idx;
pktlen += info->control.hw_key->icv_len;
}
+ if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+ flags |= AR5K_TXDESC_RTSENA;
+ cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+ duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
+ sc->vif, pktlen, info));
+ }
+ if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ flags |= AR5K_TXDESC_CTSENA;
+ cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+ duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
+ sc->vif, pktlen, info));
+ }
ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
(sc->power_level * 2),
- ieee80211_get_tx_rate(sc->hw, info)->hw_value,
- info->control.rates[0].count, keyidx, 0, flags, 0, 0);
+ hw_rate,
+ info->control.rates[0].count, keyidx, 0, flags,
+ cts_rate, duration);
if (ret)
goto err_unmap;
@@ -1312,7 +1353,7 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
list_for_each_entry(bf, &sc->txbuf, list)
ath5k_txbuf_free(sc, bf);
list_for_each_entry(bf, &sc->rxbuf, list)
- ath5k_txbuf_free(sc, bf);
+ ath5k_rxbuf_free(sc, bf);
/* Free memory associated with all descriptors */
pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
@@ -1656,13 +1697,42 @@ 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)
{
struct ieee80211_rx_status rxs = {};
struct ath5k_rx_status rs = {};
- struct sk_buff *skb;
+ struct sk_buff *skb, *next_skb;
+ dma_addr_t next_skb_addr;
struct ath5k_softc *sc = (void *)data;
struct ath5k_buf *bf, *bf_last;
struct ath5k_desc *ds;
@@ -1747,10 +1817,17 @@ ath5k_tasklet_rx(unsigned long data)
goto next;
}
accept:
+ next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
+
+ /*
+ * If we can't replace bf->skb with a new skb under memory
+ * pressure, just skip this packet
+ */
+ if (!next_skb)
+ goto next;
+
pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
PCI_DMA_FROMDEVICE);
- bf->skb = NULL;
-
skb_put(skb, rs.rs_datalen);
/* The MAC header is padded to have 32-bit boundary if the
@@ -1823,6 +1900,9 @@ accept:
ath5k_check_ibss_tsf(sc, skb, &rxs);
__ieee80211_rx(sc->hw, skb, &rxs);
+
+ bf->skb = next_skb;
+ bf->skbaddr = next_skb_addr;
next:
list_move_tail(&bf->list, &sc->rxbuf);
} while (ath5k_rxbuf_setup(sc, bf) == 0);
@@ -1985,9 +2065,8 @@ err_unmap:
* frame contents are done as needed and the slot time is
* also adjusted based on current state.
*
- * this is usually called from interrupt context (ath5k_intr())
- * but also from ath5k_beacon_config() in IBSS mode which in turn
- * can be called from a tasklet and user context
+ * This is called from software irq context (beacontq or restq
+ * tasklets) or user context from ath5k_beacon_config.
*/
static void
ath5k_beacon_send(struct ath5k_softc *sc)
@@ -2154,10 +2233,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
*
* @sc: struct ath5k_softc pointer we are operating on
*
- * When operating in station mode we want to receive a BMISS interrupt when we
- * stop seeing beacons from the AP we've associated with so we can look for
- * another AP to associate with.
- *
* In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
* interrupts to detect TSF updates only.
*/
@@ -2165,14 +2240,13 @@ static void
ath5k_beacon_config(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
+ unsigned long flags;
ath5k_hw_set_imr(ah, 0);
sc->bmisscount = 0;
sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
- if (sc->opmode == NL80211_IFTYPE_STATION) {
- sc->imask |= AR5K_INT_BMISS;
- } else if (sc->opmode == NL80211_IFTYPE_ADHOC ||
+ if (sc->opmode == NL80211_IFTYPE_ADHOC ||
sc->opmode == NL80211_IFTYPE_MESH_POINT ||
sc->opmode == NL80211_IFTYPE_AP) {
/*
@@ -2188,9 +2262,9 @@ ath5k_beacon_config(struct ath5k_softc *sc)
if (sc->opmode == NL80211_IFTYPE_ADHOC) {
if (ath5k_hw_hasveol(ah)) {
- spin_lock(&sc->block);
+ spin_lock_irqsave(&sc->block, flags);
ath5k_beacon_send(sc);
- spin_unlock(&sc->block);
+ spin_unlock_irqrestore(&sc->block, flags);
}
} else
ath5k_beacon_update_timers(sc, -1);
@@ -2205,18 +2279,13 @@ ath5k_beacon_config(struct ath5k_softc *sc)
\********************/
static int
-ath5k_init(struct ath5k_softc *sc, bool is_resume)
+ath5k_init(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
int ret, i;
mutex_lock(&sc->lock);
- if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
- goto out_ok;
-
- __clear_bit(ATH_STAT_STARTED, sc->status);
-
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
/*
@@ -2248,15 +2317,12 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
ath5k_hw_reset_key(ah, i);
- __set_bit(ATH_STAT_STARTED, sc->status);
-
/* Set ack to be sent at low bit-rates */
ath5k_hw_set_ack_bitrate_high(ah, false);
mod_timer(&sc->calib_tim, round_jiffies(jiffies +
msecs_to_jiffies(ath5k_calinterval * 1000)));
-out_ok:
ret = 0;
done:
mmiowb();
@@ -2311,7 +2377,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
* stop is preempted).
*/
static int
-ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
+ath5k_stop_hw(struct ath5k_softc *sc)
{
int ret;
@@ -2342,8 +2408,6 @@ ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
}
}
ath5k_txbuf_free(sc, sc->bbuf);
- if (!is_suspend)
- __clear_bit(ATH_STAT_STARTED, sc->status);
mmiowb();
mutex_unlock(&sc->lock);
@@ -2352,6 +2416,7 @@ ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
tasklet_kill(&sc->rxtq);
tasklet_kill(&sc->txtq);
tasklet_kill(&sc->restq);
+ tasklet_kill(&sc->beacontq);
return ret;
}
@@ -2369,16 +2434,9 @@ ath5k_intr(int irq, void *dev_id)
return IRQ_NONE;
do {
- /*
- * Figure out the reason(s) for the interrupt. Note
- * that get_isr returns a pseudo-ISR that may include
- * bits we haven't explicitly enabled so we mask the
- * value to insure we only process bits we requested.
- */
ath5k_hw_get_isr(ah, &status); /* NB: clears IRQ too */
ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
status, sc->imask);
- status &= sc->imask; /* discard unasked for bits */
if (unlikely(status & AR5K_INT_FATAL)) {
/*
* Fatal errors are unrecoverable.
@@ -2389,32 +2447,7 @@ ath5k_intr(int irq, void *dev_id)
tasklet_schedule(&sc->restq);
} else {
if (status & AR5K_INT_SWBA) {
- /*
- * Software beacon alert--time to send a beacon.
- * Handle beacon transmission directly; deferring
- * this is too slow to meet timing constraints
- * under load.
- *
- * In IBSS mode we use this interrupt just to
- * keep track of the next TBTT (target beacon
- * transmission time) in order to detect wether
- * automatic TSF updates happened.
- */
- if (sc->opmode == NL80211_IFTYPE_ADHOC) {
- /* XXX: only if VEOL suppported */
- u64 tsf = ath5k_hw_get_tsf64(ah);
- sc->nexttbtt += sc->bintval;
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
- "SWBA nexttbtt: %x hw_tu: %x "
- "TSF: %llx\n",
- sc->nexttbtt,
- TSF_TO_TU(tsf),
- (unsigned long long) tsf);
- } else {
- spin_lock(&sc->block);
- ath5k_beacon_send(sc);
- spin_unlock(&sc->block);
- }
+ tasklet_schedule(&sc->beacontq);
}
if (status & AR5K_INT_RXEOL) {
/*
@@ -2434,6 +2467,7 @@ ath5k_intr(int irq, void *dev_id)
| AR5K_INT_TXERR | AR5K_INT_TXEOL))
tasklet_schedule(&sc->txtq);
if (status & AR5K_INT_BMISS) {
+ /* TODO */
}
if (status & AR5K_INT_MIB) {
/*
@@ -2473,7 +2507,7 @@ ath5k_calibrate(unsigned long data)
ieee80211_frequency_to_channel(sc->curchan->center_freq),
sc->curchan->hw_value);
- if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) {
+ if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
/*
* Rfgain is out of bounds, reset the chip
* to load new gain values.
@@ -2491,130 +2525,6 @@ ath5k_calibrate(unsigned long data)
}
-
-/***************\
-* LED functions *
-\***************/
-
-static void
-ath5k_led_enable(struct ath5k_softc *sc)
-{
- if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
- ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
- ath5k_led_off(sc);
- }
-}
-
-static void
-ath5k_led_on(struct ath5k_softc *sc)
-{
- if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
- return;
- ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
-}
-
-static void
-ath5k_led_off(struct ath5k_softc *sc)
-{
- if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
- return;
- ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
-}
-
-static void
-ath5k_led_brightness_set(struct led_classdev *led_dev,
- enum led_brightness brightness)
-{
- struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
- led_dev);
-
- if (brightness == LED_OFF)
- ath5k_led_off(led->sc);
- else
- ath5k_led_on(led->sc);
-}
-
-static int
-ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
- const char *name, char *trigger)
-{
- int err;
-
- led->sc = sc;
- strncpy(led->name, name, sizeof(led->name));
- led->led_dev.name = led->name;
- led->led_dev.default_trigger = trigger;
- led->led_dev.brightness_set = ath5k_led_brightness_set;
-
- err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
- if (err) {
- ATH5K_WARN(sc, "could not register LED %s\n", name);
- led->sc = NULL;
- }
- return err;
-}
-
-static void
-ath5k_unregister_led(struct ath5k_led *led)
-{
- if (!led->sc)
- return;
- led_classdev_unregister(&led->led_dev);
- ath5k_led_off(led->sc);
- led->sc = NULL;
-}
-
-static void
-ath5k_unregister_leds(struct ath5k_softc *sc)
-{
- ath5k_unregister_led(&sc->rx_led);
- ath5k_unregister_led(&sc->tx_led);
-}
-
-
-static int
-ath5k_init_leds(struct ath5k_softc *sc)
-{
- int ret = 0;
- struct ieee80211_hw *hw = sc->hw;
- struct pci_dev *pdev = sc->pdev;
- char name[ATH5K_LED_MAX_NAME_LEN + 1];
-
- /*
- * Auto-enable soft led processing for IBM cards and for
- * 5211 minipci cards.
- */
- if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
- pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
- __set_bit(ATH_STAT_LEDSOFT, sc->status);
- sc->led_pin = 0;
- sc->led_on = 0; /* active low */
- }
- /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
- if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
- __set_bit(ATH_STAT_LEDSOFT, sc->status);
- sc->led_pin = 1;
- sc->led_on = 1; /* active high */
- }
- if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
- goto out;
-
- ath5k_led_enable(sc);
-
- snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
- ret = ath5k_register_led(sc, &sc->rx_led, name,
- ieee80211_get_rx_led_name(hw));
- if (ret)
- goto out;
-
- snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
- ret = ath5k_register_led(sc, &sc->tx_led, name,
- ieee80211_get_tx_led_name(hw));
-out:
- return ret;
-}
-
-
/********************\
* Mac80211 functions *
\********************/
@@ -2743,12 +2653,12 @@ ath5k_reset_wake(struct ath5k_softc *sc)
static int ath5k_start(struct ieee80211_hw *hw)
{
- return ath5k_init(hw->priv, false);
+ return ath5k_init(hw->priv);
}
static void ath5k_stop(struct ieee80211_hw *hw)
{
- ath5k_stop_hw(hw->priv, false);
+ ath5k_stop_hw(hw->priv);
}
static int ath5k_add_interface(struct ieee80211_hw *hw,
@@ -2814,11 +2724,17 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
{
struct ath5k_softc *sc = hw->priv;
struct ieee80211_conf *conf = &hw->conf;
+ int ret;
+
+ mutex_lock(&sc->lock);
sc->bintval = conf->beacon_int;
sc->power_level = conf->power_level;
- return ath5k_chan_set(sc, conf->channel);
+ ret = ath5k_chan_set(sc, conf->channel);
+
+ mutex_unlock(&sc->lock);
+ return ret;
}
static int
@@ -2827,7 +2743,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
- int ret;
+ int ret = 0;
mutex_lock(&sc->lock);
if (sc->vif != vif) {
@@ -2853,9 +2769,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
ath5k_beacon_update(sc, beacon);
}
- mutex_unlock(&sc->lock);
- return ath5k_reset_wake(sc);
unlock:
mutex_unlock(&sc->lock);
return ret;
@@ -2991,8 +2905,8 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
static int
ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct ath5k_softc *sc = hw->priv;
int ret = 0;
@@ -3015,7 +2929,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
switch (cmd) {
case SET_KEY:
- ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr);
+ ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
+ sta ? sta->addr : NULL);
if (ret) {
ATH5K_ERR(sc, "can't set the key\n");
goto unlock;
@@ -3075,6 +2990,14 @@ ath5k_get_tsf(struct ieee80211_hw *hw)
}
static void
+ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ ath5k_hw_set_tsf64(sc->ah, tsf);
+}
+
+static void
ath5k_reset_tsf(struct ieee80211_hw *hw)
{
struct ath5k_softc *sc = hw->priv;
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
index facc60ddada..20e0d14b41e 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -148,8 +148,7 @@ struct ath5k_softc {
u8 bssidmask[ETH_ALEN];
unsigned int led_pin, /* GPIO pin for driving LED */
- led_on, /* pin setting for LED on */
- led_off; /* off time for current blink */
+ led_on; /* pin setting for LED on */
struct tasklet_struct restq; /* reset tasklet */
@@ -170,6 +169,7 @@ struct ath5k_softc {
struct ath5k_led tx_led; /* tx led */
spinlock_t block; /* protects beacon */
+ struct tasklet_struct beacontq; /* beacon intr tasklet */
struct ath5k_buf *bbuf; /* beacon buffer */
unsigned int bhalq, /* SW q for outgoing beacons */
bmisscount, /* missed beacon transmits */
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath5k/caps.c
index 150f5ed204a..367a6c7d3cc 100644
--- a/drivers/net/wireless/ath5k/caps.c
+++ b/drivers/net/wireless/ath5k/caps.c
@@ -85,7 +85,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
/* Enable 802.11b if a 2GHz capable radio (2111/5112) is
* connected */
if (AR5K_EEPROM_HDR_11B(ee_header) ||
- AR5K_EEPROM_HDR_11G(ee_header)) {
+ (AR5K_EEPROM_HDR_11G(ee_header) &&
+ ah->ah_version != AR5K_AR5211)) {
/* 2312 */
ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
@@ -94,7 +95,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
__set_bit(AR5K_MODE_11B,
ah->ah_capabilities.cap_mode);
- if (AR5K_EEPROM_HDR_11G(ee_header))
+ if (AR5K_EEPROM_HDR_11G(ee_header) &&
+ ah->ah_version != AR5K_AR5211)
__set_bit(AR5K_MODE_11G,
ah->ah_capabilities.cap_mode);
}
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
index ccaeb5c219d..9770bb3d40f 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -82,14 +82,14 @@ static int ath5k_debugfs_open(struct inode *inode, struct file *file)
/* debugfs: registers */
struct reg {
- char *name;
+ const char *name;
int addr;
};
#define REG_STRUCT_INIT(r) { #r, r }
/* just a few random registers, might want to add more */
-static struct reg regs[] = {
+static const struct reg regs[] = {
REG_STRUCT_INIT(AR5K_CR),
REG_STRUCT_INIT(AR5K_RXDP),
REG_STRUCT_INIT(AR5K_CFG),
@@ -142,7 +142,7 @@ static struct reg regs[] = {
static void *reg_start(struct seq_file *seq, loff_t *pos)
{
- return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
+ return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
}
static void reg_stop(struct seq_file *seq, void *p)
@@ -153,7 +153,7 @@ static void reg_stop(struct seq_file *seq, void *p)
static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
{
++*pos;
- return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
+ return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
}
static int reg_show(struct seq_file *seq, void *p)
@@ -165,7 +165,7 @@ static int reg_show(struct seq_file *seq, void *p)
return 0;
}
-static struct seq_operations register_seq_ops = {
+static const struct seq_operations register_seq_ops = {
.start = reg_start,
.next = reg_next,
.stop = reg_stop,
@@ -193,43 +193,6 @@ static const struct file_operations fops_registers = {
};
-/* debugfs: TSF */
-
-static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath5k_softc *sc = file->private_data;
- char buf[100];
- snprintf(buf, sizeof(buf), "0x%016llx\n",
- (unsigned long long)ath5k_hw_get_tsf64(sc->ah));
- return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
-}
-
-static ssize_t write_file_tsf(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct ath5k_softc *sc = file->private_data;
- char buf[20];
-
- if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
- return -EFAULT;
-
- if (strncmp(buf, "reset", 5) == 0) {
- ath5k_hw_reset_tsf(sc->ah);
- printk(KERN_INFO "debugfs reset TSF\n");
- }
- return count;
-}
-
-static const struct file_operations fops_tsf = {
- .read = read_file_tsf,
- .write = write_file_tsf,
- .open = ath5k_debugfs_open,
- .owner = THIS_MODULE,
-};
-
-
/* debugfs: beacons */
static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
@@ -327,7 +290,7 @@ static const struct file_operations fops_reset = {
/* debugfs: debug level */
-static struct {
+static const struct {
enum ath5k_debug_level level;
const char *name;
const char *desc;
@@ -423,9 +386,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO,
sc->debug.debugfs_phydir, sc, &fops_registers);
- sc->debug.debugfs_tsf = debugfs_create_file("tsf", S_IWUSR | S_IRUGO,
- sc->debug.debugfs_phydir, sc, &fops_tsf);
-
sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO,
sc->debug.debugfs_phydir, sc, &fops_beacon);
@@ -444,7 +404,6 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
{
debugfs_remove(sc->debug.debugfs_debug);
debugfs_remove(sc->debug.debugfs_registers);
- debugfs_remove(sc->debug.debugfs_tsf);
debugfs_remove(sc->debug.debugfs_beacon);
debugfs_remove(sc->debug.debugfs_reset);
debugfs_remove(sc->debug.debugfs_phydir);
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
index ffc52939330..66f69f04e55 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath5k/debug.h
@@ -72,7 +72,6 @@ struct ath5k_dbg_info {
struct dentry *debugfs_phydir;
struct dentry *debugfs_debug;
struct dentry *debugfs_registers;
- struct dentry *debugfs_tsf;
struct dentry *debugfs_beacon;
struct dentry *debugfs_reset;
};
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c
index 1cb7edfae62..ac45ca47ca8 100644
--- a/drivers/net/wireless/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath5k/eeprom.c
@@ -137,6 +137,18 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
+
+ /* XXX: Don't know which versions include these two */
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
+
+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
+
+ if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
+ }
}
if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
@@ -192,7 +204,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
/* Get antenna modes */
ah->ah_antenna[mode][0] =
- (ee->ee_ant_control[mode][0] << 4) | 0x1;
+ (ee->ee_ant_control[mode][0] << 4);
ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
ee->ee_ant_control[mode][1] |
(ee->ee_ant_control[mode][2] << 6) |
@@ -213,7 +225,8 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
}
/*
- * Read supported modes from eeprom
+ * Read supported modes and some mode-specific calibration data
+ * from eeprom
*/
static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
unsigned int mode)
@@ -315,6 +328,9 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
goto done;
+ /* Note: >= v5 have bg freq piers on another location
+ * so these freq piers are ignored for >= v5 (should be 0xff
+ * anyway) */
switch(mode) {
case AR5K_EEPROM_MODE_11A:
if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
@@ -442,7 +458,7 @@ ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
return 0;
}
-
+/* Read mode-specific data (except power calibration data) */
static int
ath5k_eeprom_init_modes(struct ath5k_hw *ah)
{
@@ -488,12 +504,22 @@ ath5k_eeprom_init_modes(struct ath5k_hw *ah)
return 0;
}
+/* Used to match PCDAC steps with power values on RF5111 chips
+ * (eeprom versions < 4). For RF5111 we have 10 pre-defined PCDAC
+ * steps that match with the power values we read from eeprom. On
+ * older eeprom versions (< 3.2) these steps are equaly spaced at
+ * 10% of the pcdac curve -until the curve reaches it's maximum-
+ * (10 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
+ * these 10 steps are spaced in a different way. This function returns
+ * the pcdac steps based on eeprom version and curve min/max so that we
+ * can have pcdac/pwr points.
+ */
static inline void
ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
{
- const static u16 intercepts3[] =
+ 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;
@@ -507,37 +533,48 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
*vp++ = (ip[i] * max + (100 - ip[i]) * min) / 100;
}
+/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
+ * frequency mask) */
static inline int
ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
- struct ath5k_chan_pcal_info *pc, u8 *count)
+ struct ath5k_chan_pcal_info *pc, unsigned int mode)
{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
int o = *offset;
int i = 0;
- u8 f1, f2;
+ u8 freq1, freq2;
int ret;
u16 val;
while(i < max) {
AR5K_EEPROM_READ(o++, val);
- f1 = (val >> 8) & 0xff;
- f2 = val & 0xff;
+ freq1 = (val >> 8) & 0xff;
+ freq2 = val & 0xff;
- if (f1)
- pc[i++].freq = f1;
+ if (freq1) {
+ pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+ freq1, mode);
+ ee->ee_n_piers[mode]++;
+ }
- if (f2)
- pc[i++].freq = f2;
+ if (freq2) {
+ pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+ freq2, mode);
+ ee->ee_n_piers[mode]++;
+ }
- if (!f1 || !f2)
+ if (!freq1 || !freq2)
break;
}
+
+ /* return new offset */
*offset = o;
- *count = i;
return 0;
}
+/* Read frequency piers for 802.11a */
static int
ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
{
@@ -550,7 +587,7 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
ath5k_eeprom_read_freq_list(ah, &offset,
AR5K_EEPROM_N_5GHZ_CHAN, pcal,
- &ee->ee_n_piers[AR5K_EEPROM_MODE_11A]);
+ AR5K_EEPROM_MODE_11A);
} else {
mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
@@ -577,23 +614,25 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
AR5K_EEPROM_READ(offset++, val);
pcal[9].freq |= (val >> 10) & 0x3f;
+
+ /* Fixed number of piers */
ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
- }
- for(i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i += 1) {
- pcal[i].freq = ath5k_eeprom_bin2freq(ee,
+ for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
+ pcal[i].freq = ath5k_eeprom_bin2freq(ee,
pcal[i].freq, AR5K_EEPROM_MODE_11A);
+ }
}
return 0;
}
+/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
static inline int
ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
struct ath5k_chan_pcal_info *pcal;
- int i;
switch(mode) {
case AR5K_EEPROM_MODE_11B:
@@ -608,23 +647,25 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
ath5k_eeprom_read_freq_list(ah, &offset,
AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
- &ee->ee_n_piers[mode]);
- for(i = 0; i < AR5K_EEPROM_N_2GHZ_CHAN_2413; i += 1) {
- pcal[i].freq = ath5k_eeprom_bin2freq(ee,
- pcal[i].freq, mode);
- }
+ mode);
return 0;
}
-
+/* Read power calibration for RF5111 chips
+ * For RF5111 we have an XPD -eXternal Power Detector- curve
+ * for each calibrated channel. Each curve has PCDAC steps on
+ * x axis and power on y axis and looks like a logarithmic
+ * function. To recreate the curve and pass the power values
+ * on the pcdac table, we read 10 points here and interpolate later.
+ */
static int
ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
struct ath5k_chan_pcal_info *pcal;
int offset, ret;
- int i, j;
+ int i;
u16 val;
offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
@@ -704,16 +745,22 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
cdata->pcdac_max, cdata->pcdac);
-
- for (j = 0; j < AR5K_EEPROM_N_PCDAC; j++) {
- cdata->pwr[j] = (u16)
- (AR5K_EEPROM_POWER_STEP * cdata->pwr[j]);
- }
}
return 0;
}
+/* Read power calibration for RF5112 chips
+ * For RF5112 we have 4 XPD -eXternal Power Detector- curves
+ * for each calibrated channel on 0, -6, -12 and -18dbm but we only
+ * use the higher (3) and the lower (0) curves. Each curve has PCDAC
+ * steps on x axis and power on y axis and looks like a linear
+ * function. To recreate the curve and pass the power values
+ * on the pcdac table, we read 4 points for xpd 0 and 3 points
+ * for xpd 3 here and interpolate later.
+ *
+ * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
+ */
static int
ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
{
@@ -790,7 +837,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
/* PCDAC steps
* corresponding to the above power
- * measurements (static) */
+ * measurements (fixed) */
chan_pcal_info->pcdac_x3[0] = 20;
chan_pcal_info->pcdac_x3[1] = 35;
chan_pcal_info->pcdac_x3[2] = 63;
@@ -814,6 +861,13 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
return 0;
}
+/* For RF2413 power calibration data doesn't start on a fixed location and
+ * if a mode is not supported, it's section is missing -not zeroed-.
+ * So we need to calculate the starting offset for each section by using
+ * these two functions */
+
+/* Return the size of each section based on the mode and the number of pd
+ * gains available (maximum 4). */
static inline unsigned int
ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
{
@@ -826,6 +880,8 @@ ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
return sz;
}
+/* Return the starting offset for a section based on the modes supported
+ * and each section's size. */
static unsigned int
ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
{
@@ -834,11 +890,13 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
switch(mode) {
case AR5K_EEPROM_MODE_11G:
if (AR5K_EEPROM_HDR_11B(ee->ee_header))
- offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) + 2;
+ offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) +
+ AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
/* fall through */
case AR5K_EEPROM_MODE_11B:
if (AR5K_EEPROM_HDR_11A(ee->ee_header))
- offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) + 5;
+ offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) +
+ AR5K_EEPROM_N_5GHZ_CHAN / 2;
/* fall through */
case AR5K_EEPROM_MODE_11A:
break;
@@ -849,6 +907,17 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
return offset;
}
+/* Read power calibration for RF2413 chips
+ * For RF2413 we have a PDDAC table (Power Detector) instead
+ * of a PCDAC and 4 pd gain curves for each calibrated channel.
+ * Each curve has PDDAC steps on x axis and power on y axis and
+ * looks like an exponential function. To recreate the curves
+ * we read here the points and interpolate later. Note that
+ * in most cases only higher and lower curves are used (like
+ * RF5112) but vendors have the oportunity to include all 4
+ * curves on eeprom. The final curve (higher power) has an extra
+ * point for better accuracy like RF5112.
+ */
static int
ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
{
@@ -868,6 +937,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
ee->ee_pd_gains[mode] = pd_gains;
offset = ath5k_cal_data_offset_2413(ee, mode);
+ ee->ee_n_piers[mode] = 0;
switch (mode) {
case AR5K_EEPROM_MODE_11A:
if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
@@ -1163,6 +1233,20 @@ static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned
return 0;
}
+/*
+ * Read per channel calibration info from EEPROM
+ *
+ * This info is used to calibrate the baseband power table. Imagine
+ * that for each channel there is a power curve that's hw specific
+ * (depends on amplifier etc) and we try to "correct" this curve using
+ * offests we pass on to phy chip (baseband -> before amplifier) so that
+ * it can use accurate power values when setting tx power (takes amplifier's
+ * performance on each channel into account).
+ *
+ * EEPROM provides us with the offsets for some pre-calibrated channels
+ * and we have to interpolate to create the full table for these channels and
+ * also the table for any channel.
+ */
static int
ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
{
@@ -1193,7 +1277,7 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
return 0;
}
-/* Read conformance test limits */
+/* Read conformance test limits used for regulatory control */
static int
ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
{
@@ -1328,19 +1412,17 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
return 0;
}
+
/*
* Read the MAC address from eeprom
*/
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
{
- u8 mac_d[ETH_ALEN];
+ u8 mac_d[ETH_ALEN] = {};
u32 total, offset;
u16 data;
int octet, ret;
- memset(mac, 0, ETH_ALEN);
- memset(mac_d, 0, ETH_ALEN);
-
ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
if (ret)
return ret;
@@ -1356,11 +1438,22 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
octet += 2;
}
- memcpy(mac, mac_d, ETH_ALEN);
-
if (!total || total == 3 * 0xffff)
return -EINVAL;
+ memcpy(mac, mac_d, ETH_ALEN);
+
return 0;
}
+bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
+{
+ u16 data;
+
+ ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
+
+ if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
+ return true;
+ else
+ return false;
+}
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h
index 09eb7d0176a..1deebc0257d 100644
--- a/drivers/net/wireless/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath5k/eeprom.h
@@ -25,6 +25,7 @@
#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
+#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath5k/gpio.c
index b77205adc18..64a27e73d02 100644
--- a/drivers/net/wireless/ath5k/gpio.c
+++ b/drivers/net/wireless/ath5k/gpio.c
@@ -83,7 +83,7 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return -EINVAL;
ath5k_hw_reg_write(ah,
@@ -99,7 +99,7 @@ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return -EINVAL;
ath5k_hw_reg_write(ah,
@@ -115,7 +115,7 @@ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return 0xffffffff;
/* GPIO input magic */
@@ -131,7 +131,7 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
u32 data;
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return -EINVAL;
/* GPIO output magic */
@@ -154,7 +154,7 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
u32 data;
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return;
/*
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
index 450bd6e945f..44886434187 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -2,7 +2,7 @@
* Initial register settings functions
*
* Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -340,7 +340,7 @@ static const struct ath5k_ini ar5211_ini[] = {
* common on all cards/modes.
* Note: Table is rewritten during
* txpower setup later using calibration
- * data etc. so next write is non-common
+ * data etc. so next write is non-common */
{ AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
{ AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
{ AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
@@ -371,7 +371,7 @@ static const struct ath5k_ini ar5211_ini[] = {
{ AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
{ AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
{ AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
- { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },*/
+ { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },
{ AR5K_PHY_CCKTXCTL, 0x00000000 },
{ AR5K_PHY(642), 0x503e4646 },
{ AR5K_PHY_GAIN_2GHZ, 0x6480416c },
@@ -386,85 +386,85 @@ static const struct ath5k_ini ar5211_ini[] = {
};
/* Initial mode-specific settings for AR5211
- * XXX: how about g / gTurbo ? RF5111 supports it, how about AR5211 ?
- * Maybe 5211 supports OFDM-only g but we need to test it !
+ * 5211 supports OFDM-only g (draft g) but we
+ * need to test it !
*/
static const struct ath5k_ini_mode ar5211_ini_mode[] = {
{ AR5K_TXCFG,
- /* a aTurbo b */
- { 0x00000015, 0x00000015, 0x0000001d } },
+ /* a aTurbo b g (OFDM) */
+ { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_DCU_GBL_IFS_SLOT,
- { 0x00000168, 0x000001e0, 0x000001b8 } },
+ { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
{ AR5K_DCU_GBL_IFS_SIFS,
- { 0x00000230, 0x000001e0, 0x000000b0 } },
+ { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
{ AR5K_DCU_GBL_IFS_EIFS,
- { 0x00000d98, 0x00001180, 0x00001f48 } },
+ { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
{ AR5K_DCU_GBL_IFS_MISC,
- { 0x0000a0e0, 0x00014068, 0x00005880 } },
+ { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
{ AR5K_TIME_OUT,
- { 0x04000400, 0x08000800, 0x20003000 } },
+ { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
{ AR5K_USEC_5211,
- { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95 } },
+ { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
{ AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003, 0x00000000 } },
+ { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
{ AR5K_PHY(8),
- { 0x02020200, 0x02020200, 0x02010200 } },
+ { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
{ AR5K_PHY(9),
- { 0x00000e0e, 0x00000e0e, 0x00000707 } },
+ { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
{ AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05010000 } },
+ { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
{ AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b } },
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
{ AR5K_PHY(17),
- { 0x1372169c, 0x137216a5, 0x137216a8 } },
+ { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
{ AR5K_PHY(18),
- { 0x0018ba67, 0x0018ba67, 0x0018ba69 } },
+ { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
{ AR5K_PHY(20),
- { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
+ { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x31375d5e, 0x31375d5e, 0x313a5d5e } },
+ { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
{ AR5K_PHY_AGCCTL,
- { 0x0000bd10, 0x0000bd10, 0x0000bd38 } },
+ { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
{ AR5K_PHY_NF,
- { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00002710, 0x00002710, 0x0000157c } },
+ { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
{ AR5K_PHY(70),
- { 0x00000190, 0x00000190, 0x00000084 } },
+ { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0x6fe01020, 0x6fe01020, 0x6fe00920 } },
- { AR5K_PHY_PCDAC_TXPOWER_BASE_5211,
- { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff } },
+ { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
+ { AR5K_PHY_PCDAC_TXPOWER_BASE,
+ { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
{ AR5K_RF_BUFFER_CONTROL_4,
- { 0x00000010, 0x00000014, 0x00000010 } },
+ { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
};
/* Initial register settings for AR5212 */
-static const struct ath5k_ini ar5212_ini[] = {
+static const struct ath5k_ini ar5212_ini_common_start[] = {
{ AR5K_RXDP, 0x00000000 },
{ AR5K_RXCFG, 0x00000005 },
{ AR5K_MIBC, 0x00000000 },
@@ -485,91 +485,83 @@ static const struct ath5k_ini ar5212_ini[] = {
{ AR5K_QUEUE_TXDP(9), 0x00000000 },
{ AR5K_DCU_FP, 0x00000000 },
{ AR5K_DCU_TXP, 0x00000000 },
- { AR5K_DCU_TX_FILTER_0_BASE, 0x00000000 },
- /* Unknown table */
- { 0x1078, 0x00000000 },
- { 0x10b8, 0x00000000 },
- { 0x10f8, 0x00000000 },
- { 0x1138, 0x00000000 },
- { 0x1178, 0x00000000 },
- { 0x11b8, 0x00000000 },
- { 0x11f8, 0x00000000 },
- { 0x1238, 0x00000000 },
- { 0x1278, 0x00000000 },
- { 0x12b8, 0x00000000 },
- { 0x12f8, 0x00000000 },
- { 0x1338, 0x00000000 },
- { 0x1378, 0x00000000 },
- { 0x13b8, 0x00000000 },
- { 0x13f8, 0x00000000 },
- { 0x1438, 0x00000000 },
- { 0x1478, 0x00000000 },
- { 0x14b8, 0x00000000 },
- { 0x14f8, 0x00000000 },
- { 0x1538, 0x00000000 },
- { 0x1578, 0x00000000 },
- { 0x15b8, 0x00000000 },
- { 0x15f8, 0x00000000 },
- { 0x1638, 0x00000000 },
- { 0x1678, 0x00000000 },
- { 0x16b8, 0x00000000 },
- { 0x16f8, 0x00000000 },
- { 0x1738, 0x00000000 },
- { 0x1778, 0x00000000 },
- { 0x17b8, 0x00000000 },
- { 0x17f8, 0x00000000 },
- { 0x103c, 0x00000000 },
- { 0x107c, 0x00000000 },
- { 0x10bc, 0x00000000 },
- { 0x10fc, 0x00000000 },
- { 0x113c, 0x00000000 },
- { 0x117c, 0x00000000 },
- { 0x11bc, 0x00000000 },
- { 0x11fc, 0x00000000 },
- { 0x123c, 0x00000000 },
- { 0x127c, 0x00000000 },
- { 0x12bc, 0x00000000 },
- { 0x12fc, 0x00000000 },
- { 0x133c, 0x00000000 },
- { 0x137c, 0x00000000 },
- { 0x13bc, 0x00000000 },
- { 0x13fc, 0x00000000 },
- { 0x143c, 0x00000000 },
- { 0x147c, 0x00000000 },
+ /* Tx filter table 0 (32 entries) */
+ { AR5K_DCU_TX_FILTER_0(0), 0x00000000 }, /* DCU 0 */
+ { AR5K_DCU_TX_FILTER_0(1), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(2), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(3), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(4), 0x00000000 }, /* DCU 1 */
+ { AR5K_DCU_TX_FILTER_0(5), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(6), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(7), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(8), 0x00000000 }, /* DCU 2 */
+ { AR5K_DCU_TX_FILTER_0(9), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(10), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(11), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */
+ { AR5K_DCU_TX_FILTER_0(13), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(14), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(15), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */
+ { AR5K_DCU_TX_FILTER_0(17), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(18), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(19), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */
+ { AR5K_DCU_TX_FILTER_0(21), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(22), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(23), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */
+ { AR5K_DCU_TX_FILTER_0(25), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(26), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(27), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */
+ { AR5K_DCU_TX_FILTER_0(29), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(30), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(31), 0x00000000 },
+ /* Tx filter table 1 (16 entries) */
+ { AR5K_DCU_TX_FILTER_1(0), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(1), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(2), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(3), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(4), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(5), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(6), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(7), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(8), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(9), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(10), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(11), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(12), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(13), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(14), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
+ { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
{ AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
{ AR5K_DCU_TX_FILTER_SET, 0x00000000 },
{ AR5K_STA_ID1, 0x00000000 },
{ AR5K_BSS_ID0, 0x00000000 },
{ AR5K_BSS_ID1, 0x00000000 },
- /*{ AR5K_RSSI_THR, 0x00000000 },*/ /* Found on SuperAG cards */
- { AR5K_BEACON_5211, 0x00000000 }, /* Found on SuperAG cards */
- { AR5K_CFP_PERIOD_5211, 0x00000000 }, /* Found on SuperAG cards */
- { AR5K_TIMER0_5211, 0x00000030 }, /* Found on SuperAG cards */
- { AR5K_TIMER1_5211, 0x0007ffff }, /* Found on SuperAG cards */
- { AR5K_TIMER2_5211, 0x01ffffff }, /* Found on SuperAG cards */
- { AR5K_TIMER3_5211, 0x00000031 }, /* Found on SuperAG cards */
- { AR5K_CFP_DUR_5211, 0x00000000 }, /* Found on SuperAG cards */
+ { AR5K_BEACON_5211, 0x00000000 },
+ { AR5K_CFP_PERIOD_5211, 0x00000000 },
+ { AR5K_TIMER0_5211, 0x00000030 },
+ { AR5K_TIMER1_5211, 0x0007ffff },
+ { AR5K_TIMER2_5211, 0x01ffffff },
+ { AR5K_TIMER3_5211, 0x00000031 },
+ { AR5K_CFP_DUR_5211, 0x00000000 },
{ AR5K_RX_FILTER_5211, 0x00000000 },
{ AR5K_DIAG_SW_5211, 0x00000000 },
{ AR5K_ADDAC_TEST, 0x00000000 },
{ AR5K_DEFAULT_ANTENNA, 0x00000000 },
- { 0x8080, 0x00000000 },
- /*{ 0x805c, 0xffffc7ff },*/ /* Old value */
- { 0x805c, 0x000fc78f },
- { AR5K_NAV_5211, 0x00000000 }, /* Not found on recent */
- { AR5K_RTS_OK_5211, 0x00000000 }, /* dumps but it makes */
- { AR5K_RTS_FAIL_5211, 0x00000000 }, /* sense to reset counters */
- { AR5K_ACK_FAIL_5211, 0x00000000 }, /* since pcu registers */
- { AR5K_FCS_FAIL_5211, 0x00000000 }, /* are skiped during chan*/
- { AR5K_BEACON_CNT_5211, 0x00000000 }, /* change */
+ { AR5K_FRAME_CTL_QOSM, 0x000fc78f },
{ AR5K_XRMODE, 0x2a82301a },
{ AR5K_XRDELAY, 0x05dc01e0 },
{ AR5K_XRTIMEOUT, 0x1f402710 },
{ AR5K_XRCHIRP, 0x01f40000 },
{ AR5K_XRSTOMP, 0x00001e1c },
- { AR5K_SLEEP0, 0x0002aaaa }, /* Found on SuperAG cards */
- { AR5K_SLEEP1, 0x02005555 }, /* Found on SuperAG cards */
- { AR5K_SLEEP2, 0x00000000 }, /* Found on SuperAG cards */
+ { AR5K_SLEEP0, 0x0002aaaa },
+ { AR5K_SLEEP1, 0x02005555 },
+ { AR5K_SLEEP2, 0x00000000 },
{ AR5K_BSS_IDM0, 0xffffffff },
{ AR5K_BSS_IDM1, 0x0000ffff },
{ AR5K_TXPC, 0x00000000 },
@@ -577,7 +569,8 @@ static const struct ath5k_ini ar5212_ini[] = {
{ AR5K_PROFCNT_RX, 0x00000000 },
{ AR5K_PROFCNT_RXCLR, 0x00000000 },
{ AR5K_PROFCNT_CYCLE, 0x00000000 },
- { 0x80fc, 0x00000088 },
+ { AR5K_QUIET_CTL1, 0x00000088 },
+ /* Initial rate duration table (32 entries )*/
{ AR5K_RATE_DUR(0), 0x00000000 },
{ AR5K_RATE_DUR(1), 0x0000008c },
{ AR5K_RATE_DUR(2), 0x000000e4 },
@@ -610,881 +603,625 @@ static const struct ath5k_ini ar5212_ini[] = {
{ AR5K_RATE_DUR(29), 0x0000007f },
{ AR5K_RATE_DUR(30), 0x000000a2 },
{ AR5K_RATE_DUR(31), 0x00000000 },
- { 0x8100, 0x00010002},
+ { AR5K_QUIET_CTL2, 0x00010002 },
{ AR5K_TSF_PARM, 0x00000001 },
- { 0x8108, 0x000000c0 },
+ { AR5K_QOS_NOACK, 0x000000c0 },
{ AR5K_PHY_ERR_FIL, 0x00000000 },
- { 0x8110, 0x00000168 },
- { 0x8114, 0x00000000 },
- /* Some kind of table
- * also notice ...03<-02<-01<-00) */
- { 0x87c0, 0x03020100 },
- { 0x87c4, 0x07060504 },
- { 0x87c8, 0x0b0a0908 },
- { 0x87cc, 0x0f0e0d0c },
- { 0x87d0, 0x13121110 },
- { 0x87d4, 0x17161514 },
- { 0x87d8, 0x1b1a1918 },
- { 0x87dc, 0x1f1e1d1c },
- /* loop ? */
- { 0x87e0, 0x03020100 },
- { 0x87e4, 0x07060504 },
- { 0x87e8, 0x0b0a0908 },
- { 0x87ec, 0x0f0e0d0c },
- { 0x87f0, 0x13121110 },
- { 0x87f4, 0x17161514 },
- { 0x87f8, 0x1b1a1918 },
- { 0x87fc, 0x1f1e1d1c },
- /* PHY registers */
- /*{ AR5K_PHY_AGC, 0x00000000 },*/
- { AR5K_PHY(3), 0xad848e19 },
- { AR5K_PHY(4), 0x7d28e000 },
- { AR5K_PHY_TIMING_3, 0x9c0a9f6b },
- { AR5K_PHY_ACT, 0x00000000 },
- /*{ AR5K_PHY(11), 0x00022ffe },*/
- /*{ AR5K_PHY(15), 0x00020100 },*/
- { AR5K_PHY(16), 0x206a017a },
- /*{ AR5K_PHY(19), 0x1284613c },*/
- { AR5K_PHY(21), 0x00000859 },
- { AR5K_PHY(64), 0x00000000 },
- { AR5K_PHY(65), 0x00000000 },
- { AR5K_PHY(66), 0x00000000 },
- { AR5K_PHY(67), 0x00800000 },
- { AR5K_PHY(68), 0x00000001 },
+ { AR5K_XRLAT_TX, 0x00000168 },
+ { AR5K_ACKSIFS, 0x00000000 },
+ /* Rate -> db table
+ * notice ...03<-02<-01<-00 ! */
+ { AR5K_RATE2DB(0), 0x03020100 },
+ { AR5K_RATE2DB(1), 0x07060504 },
+ { AR5K_RATE2DB(2), 0x0b0a0908 },
+ { AR5K_RATE2DB(3), 0x0f0e0d0c },
+ { AR5K_RATE2DB(4), 0x13121110 },
+ { AR5K_RATE2DB(5), 0x17161514 },
+ { AR5K_RATE2DB(6), 0x1b1a1918 },
+ { AR5K_RATE2DB(7), 0x1f1e1d1c },
+ /* Db -> Rate table */
+ { AR5K_DB2RATE(0), 0x03020100 },
+ { AR5K_DB2RATE(1), 0x07060504 },
+ { AR5K_DB2RATE(2), 0x0b0a0908 },
+ { AR5K_DB2RATE(3), 0x0f0e0d0c },
+ { AR5K_DB2RATE(4), 0x13121110 },
+ { AR5K_DB2RATE(5), 0x17161514 },
+ { AR5K_DB2RATE(6), 0x1b1a1918 },
+ { AR5K_DB2RATE(7), 0x1f1e1d1c },
+ /* PHY registers (Common settings
+ * for all chips/modes) */
+ { AR5K_PHY(3), 0xad848e19 },
+ { AR5K_PHY(4), 0x7d28e000 },
+ { AR5K_PHY_TIMING_3, 0x9c0a9f6b },
+ { AR5K_PHY_ACT, 0x00000000 },
+ { AR5K_PHY(16), 0x206a017a },
+ { AR5K_PHY(21), 0x00000859 },
+ { AR5K_PHY_BIN_MASK_1, 0x00000000 },
+ { AR5K_PHY_BIN_MASK_2, 0x00000000 },
+ { AR5K_PHY_BIN_MASK_3, 0x00000000 },
+ { AR5K_PHY_BIN_MASK_CTL, 0x00800000 },
+ { AR5K_PHY_ANT_CTL, 0x00000001 },
/*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
- { AR5K_PHY(71), 0x00000c80 },
- { AR5K_PHY_IQ, 0x05100000 },
- { AR5K_PHY(74), 0x00000001 },
- { AR5K_PHY(75), 0x00000004 },
+ { AR5K_PHY_MAX_RX_LEN, 0x00000c80 },
+ { AR5K_PHY_IQ, 0x05100000 },
+ { AR5K_PHY_WARM_RESET, 0x00000001 },
+ { AR5K_PHY_CTL, 0x00000004 },
{ AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
{ AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
{ AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
- /*{ AR5K_PHY(80), 0x00000004 },*/
- { AR5K_PHY(82), 0x9280b212 },
- { AR5K_PHY_RADAR, 0x5d50e188 },
+ { AR5K_PHY(82), 0x9280b212 },
+ { AR5K_PHY_RADAR, 0x5d50e188 },
/*{ AR5K_PHY(86), 0x000000ff },*/
- { AR5K_PHY(87), 0x004b6a8e },
- { AR5K_PHY(90), 0x000003ce },
- { AR5K_PHY(92), 0x192fb515 },
- /*{ AR5K_PHY(93), 0x00000000 },*/
- { AR5K_PHY(94), 0x00000001 },
- { AR5K_PHY(95), 0x00000000 },
+ { AR5K_PHY(87), 0x004b6a8e },
+ { AR5K_PHY_NFTHRES, 0x000003ce },
+ { AR5K_PHY_RESTART, 0x192fb515 },
+ { AR5K_PHY(94), 0x00000001 },
+ { AR5K_PHY_RFBUS_REQ, 0x00000000 },
/*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
/*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
- { AR5K_PHY(644), 0x00806333 },
- { AR5K_PHY(645), 0x00106c10 },
- { AR5K_PHY(646), 0x009c4060 },
- { AR5K_PHY(647), 0x1483800a },
- /* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413/2425 */
- { AR5K_PHY(648), 0x01831061 },
- { AR5K_PHY(649), 0x00000400 },
+ { AR5K_PHY(644), 0x00806333 },
+ { AR5K_PHY(645), 0x00106c10 },
+ { AR5K_PHY(646), 0x009c4060 },
+ /* { AR5K_PHY(647), 0x1483800a }, */
+ /* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */
+ { AR5K_PHY(648), 0x018830c6 },
+ { AR5K_PHY(649), 0x00000400 },
/*{ AR5K_PHY(650), 0x000001b5 },*/
- { AR5K_PHY(651), 0x00000000 },
+ { AR5K_PHY(651), 0x00000000 },
{ AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
{ AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
/*{ AR5K_PHY(655), 0x13c889af },*/
- { AR5K_PHY(656), 0x38490a20 },
- { AR5K_PHY(657), 0x00007bb6 },
- { AR5K_PHY(658), 0x0fff3ffc },
- /*{ AR5K_PHY_CCKTXCTL, 0x00000000 },*/
+ { AR5K_PHY(656), 0x38490a20 },
+ { AR5K_PHY(657), 0x00007bb6 },
+ { AR5K_PHY(658), 0x0fff3ffc },
};
/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
- { AR5K_PHY(640),
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000008, 0x00000008, 0x0000000b, 0x0000000e, 0x0000000e } },
- { AR5K_PHY(0),
- { 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_DCU_GBL_IFS_SIFS,
- { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
+ { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
{ AR5K_DCU_GBL_IFS_SLOT,
- { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
+ { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
{ AR5K_DCU_GBL_IFS_EIFS,
- { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
+ { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
{ AR5K_DCU_GBL_IFS_MISC,
- { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
+ { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
{ AR5K_TIME_OUT,
- { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
+ { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
{ AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
+ { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
{ AR5K_PHY(8),
- { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
- { AR5K_PHY(9),
- { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(17),
- { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
+ { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
+ { AR5K_PHY_RF_CTL2,
+ { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_SETTLING,
+ { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
{ AR5K_PHY_AGCCTL,
- { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
+ { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
{ AR5K_PHY_NF,
- { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
- { AR5K_PHY(26),
- { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { AR5K_PHY_WEAK_OFDM_HIGH_THR,
+ { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
{ AR5K_PHY(70),
- { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
- { AR5K_PHY(73),
- { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+ { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+ { AR5K_PHY_OFDM_SELFCORR,
+ { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
{ 0xa230,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
};
/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
-/* New dump pending */
-static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = {
- { AR5K_PHY(640), /* This one differs from ar5212_ini_mode_start ! */
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000000, 0x00000000, 0x00000003, 0x00000006, 0x00000006 } },
+static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
{ AR5K_TXCFG,
- { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
{ AR5K_USEC_5211,
- { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
- { AR5K_PHY(18),
- { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
- { AR5K_PHY(20),
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_GAIN,
+ { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
+ { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
+ { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
+ { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
- { 0xa21c,
- { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
- { AR5K_DCU_FP,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
- { AR5K_PHY(15),
- { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
- { AR5K_PHY(19),
- { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
- { AR5K_PHY_PAPD_PROBE,
- { 0x00004883, 0x00004883, 0x00004883, 0x00004883, 0x00004883 } },
- { AR5K_PHY(80),
- { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
- { AR5K_PHY(86),
- { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY(93),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_SPENDING,
- { 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0x00000018 } },
- { AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(642),
- { 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
- { 0xa228,
- { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
- { 0xa23c,
- { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+ { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5111_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x00022ffe },
+ { 0x983c, 0x00020100 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
+ { AR5K_PHY_PAPD_PROBE, 0x00004883 },
+ { 0x9940, 0x00000004 },
+ { 0x9958, 0x000000ff },
+ { 0x9974, 0x00000000 },
+ { AR5K_PHY_SPENDING, 0x00000018 },
+ { AR5K_PHY_CCKTXCTL, 0x00000000 },
+ { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
+ { 0xa23c, 0x13c889af },
};
/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, but i found settings from old values so it should be ok */
-static const struct ath5k_ini_mode ar5212_rf5112_ini_mode_end[] = {
+static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
- { AR5K_PHY(18),
- { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
- { AR5K_PHY(20),
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_GAIN,
+ { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
+ { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
- { AR5K_PHY(642),
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
+ { AR5K_PHY_CCK_CROSSCORR,
+ { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
- { 0xa21c,
- { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
- { AR5K_DCU_FP,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
- { AR5K_PHY(15),
- { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
- { AR5K_PHY(19),
- { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
- { AR5K_PHY_PAPD_PROBE,
- { 0x00004882, 0x00004882, 0x00004882, 0x00004882, 0x00004882 } },
- { AR5K_PHY(80),
- { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
- { AR5K_PHY(86),
- { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY(93),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa228,
- { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
- { 0xa23c,
- { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+ { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5112_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x00022ffe },
+ { 0x983c, 0x00020100 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
+ { AR5K_PHY_PAPD_PROBE, 0x00004882 },
+ { 0x9940, 0x00000004 },
+ { 0x9958, 0x000000ff },
+ { 0x9974, 0x00000000 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
+ { 0xa23c, 0x13c889af },
};
/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g gTurbo */
- { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
- { AR5K_PHY(18),
- { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
- { AR5K_PHY(20),
- { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+ { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_GAIN,
+ { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(642),
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { AR5K_PHY_CCK_CROSSCORR,
+ { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
- { 0xa21c,
- { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+ { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
{ 0xa300,
- { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
+ { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
{ 0xa304,
- { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
+ { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
{ 0xa308,
- { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
+ { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
{ 0xa30c,
- { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
+ { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
{ 0xa310,
- { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
+ { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
{ 0xa314,
- { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
+ { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
{ 0xa318,
- { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
+ { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
{ 0xa31c,
- { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
+ { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
{ 0xa320,
- { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
+ { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
{ 0xa324,
- { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
+ { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
{ 0xa328,
- { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
+ { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
{ 0xa32c,
- { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
+ { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
{ 0xa330,
- { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
+ { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
{ 0xa334,
- { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
- { AR5K_DCU_FP,
- { 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0 } },
- { 0x4068,
- { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
- { 0x8060,
- { 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f } },
- { 0x809c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x80a0,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8118,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x811c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8120,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8124,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8128,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x812c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8130,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8134,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8138,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x813c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8140,
- { 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9 } },
- { 0x8144,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
- { AR5K_PHY(15),
- { 0x00200400, 0x00200400, 0x00200400, 0x00200400, 0x00200400 } },
- { AR5K_PHY(19),
- { 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c } },
- { AR5K_PHY_SCR,
- { 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f } },
- { AR5K_PHY_SLMT,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { AR5K_PHY_SCAL,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
- { AR5K_PHY(86),
- { 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff } },
- { AR5K_PHY(96),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(97),
- { 0x02800000, 0x02800000, 0x02800000, 0x02800000, 0x02800000 } },
- { AR5K_PHY(104),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(120),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(121),
- { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
- { AR5K_PHY(122),
- { 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478 } },
- { AR5K_PHY(123),
- { 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa } },
- { AR5K_PHY_SCLOCK,
- { 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c } },
- { AR5K_PHY_SDELAY,
- { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY_SPENDING,
- { 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000014 } },
- { 0xa228,
- { 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5 } },
- { 0xa23c,
- { 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af } },
- { 0xa24c,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 0xa250,
- { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
- { 0xa254,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa258,
- { 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
- { 0xa25c,
- { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
- { 0xa260,
- { 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
- { 0xa264,
- { 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11 } },
- { 0xa268,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa26c,
- { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
- { 0xa270,
- { 0x00820820, 0x00820820, 0x00820820, 0x00820820, 0x00820820 } },
- { 0xa274,
- { 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa } },
- { 0xa278,
- { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
- { 0xa27c,
- { 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce } },
- { 0xa338,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa33c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa340,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa344,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa348,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa34c,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa350,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa354,
- { 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff } },
- { 0xa358,
- { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
- { 0xa35c,
- { 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f } },
- { 0xa360,
- { 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207 } },
- { 0xa364,
- { 0x17601685, 0x17601685, 0x17601685, 0x17601685, 0x17601685 } },
- { 0xa368,
- { 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104 } },
- { 0xa36c,
- { 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
- { 0xa370,
- { 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
- { 0xa374,
- { 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803 } },
- { 0xa378,
- { 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
- { 0xa37c,
- { 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
- { 0xa380,
- { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
- { 0xa384,
- { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
+ { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
+};
+
+static const struct ath5k_ini rf5413_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x000003e0 },
+ { AR5K_5414_CBCFG, 0x00000010 },
+ { AR5K_SEQ_MASK, 0x0000000f },
+ { 0x809c, 0x00000000 },
+ { 0x80a0, 0x00000000 },
+ { AR5K_MIC_QOS_CTL, 0x00000000 },
+ { AR5K_MIC_QOS_SEL, 0x00000000 },
+ { AR5K_MISC_MODE, 0x00000000 },
+ { AR5K_OFDM_FIL_CNT, 0x00000000 },
+ { AR5K_CCK_FIL_CNT, 0x00000000 },
+ { AR5K_PHYERR_CNT1, 0x00000000 },
+ { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+ { AR5K_PHYERR_CNT2, 0x00000000 },
+ { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+ { AR5K_TSF_THRES, 0x00000000 },
+ { 0x8140, 0x800003f9 },
+ { 0x8144, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x0000a000 },
+ { 0x983c, 0x00200400 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+ { AR5K_PHY_SCR, 0x0000001f },
+ { AR5K_PHY_SLMT, 0x00000080 },
+ { AR5K_PHY_SCAL, 0x0000000e },
+ { 0x9958, 0x00081fff },
+ { AR5K_PHY_TIMING_7, 0x00000000 },
+ { AR5K_PHY_TIMING_8, 0x02800000 },
+ { AR5K_PHY_TIMING_11, 0x00000000 },
+ { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+ { 0x99e4, 0xaaaaaaaa },
+ { 0x99e8, 0x3c466478 },
+ { 0x99ec, 0x000000aa },
+ { AR5K_PHY_SCLOCK, 0x0000000c },
+ { AR5K_PHY_SDELAY, 0x000000ff },
+ { AR5K_PHY_SPENDING, 0x00000014 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+ { 0xa23c, 0x93c889af },
+ { AR5K_PHY_FAST_ADC, 0x00000001 },
+ { 0xa250, 0x0000a000 },
+ { AR5K_PHY_BLUETOOTH, 0x00000000 },
+ { AR5K_PHY_TPC_RG1, 0x0cc75380 },
+ { 0xa25c, 0x0f0f0f01 },
+ { 0xa260, 0x5f690f01 },
+ { 0xa264, 0x00418a11 },
+ { 0xa268, 0x00000000 },
+ { AR5K_PHY_TPC_RG5, 0x0c30c16a },
+ { 0xa270, 0x00820820 },
+ { 0xa274, 0x081b7caa },
+ { 0xa278, 0x1ce739ce },
+ { 0xa27c, 0x051701ce },
+ { 0xa338, 0x00000000 },
+ { 0xa33c, 0x00000000 },
+ { 0xa340, 0x00000000 },
+ { 0xa344, 0x00000000 },
+ { 0xa348, 0x3fffffff },
+ { 0xa34c, 0x3fffffff },
+ { 0xa350, 0x3fffffff },
+ { 0xa354, 0x0003ffff },
+ { 0xa358, 0x79a8aa1f },
+ { 0xa35c, 0x066c420f },
+ { 0xa360, 0x0f282207 },
+ { 0xa364, 0x17601685 },
+ { 0xa368, 0x1f801104 },
+ { 0xa36c, 0x37a00c03 },
+ { 0xa370, 0x3fc40883 },
+ { 0xa374, 0x57c00803 },
+ { 0xa378, 0x5fd80682 },
+ { 0xa37c, 0x7fe00482 },
+ { 0xa380, 0x7f3c7bba },
+ { 0xa384, 0xf3307ff0 },
};
/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
+/* XXX: a mode ? */
static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* b g gTurbo */
- { 0x00000015, 0x00000015, 0x00000015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x04e01395, 0x12e013ab, 0x098813cf } },
- { AR5K_PHY(10),
- { 0x05020000, 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e00, 0x00000e00, 0x00000e00 } },
- { AR5K_PHY(14),
- { 0x0000000a, 0x0000000a, 0x0000000a } },
- { AR5K_PHY(18),
- { 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
- { AR5K_PHY(20),
- { 0x0de8b0da, 0x0c98b0da, 0x0c98b0da } },
+ { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
+ { AR5K_PHY_GAIN,
+ { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
{ AR5K_PHY_SIG,
- { 0x7ee80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3139605e, 0x3139605e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(642),
- { 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { AR5K_PHY_CCK_CROSSCORR,
+ { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x0042c140, 0x0042c140, 0x0042c140 } },
- { 0xa21c,
- { 0x1863800a, 0x1883800a, 0x1883800a } },
- { AR5K_DCU_FP,
- { 0x000003e0, 0x000003e0, 0x000003e0 } },
- { 0x8060,
- { 0x0000000f, 0x0000000f, 0x0000000f } },
- { 0x8118,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x811c,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8120,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8124,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8128,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x812c,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8130,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8134,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8138,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x813c,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8140,
- { 0x800000a8, 0x800000a8, 0x800000a8 } },
- { 0x8144,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x0000a000, 0x0000a000, 0x0000a000 } },
- { AR5K_PHY(15),
- { 0x00200400, 0x00200400, 0x00200400 } },
- { AR5K_PHY(19),
- { 0x1284233c, 0x1284233c, 0x1284233c } },
- { AR5K_PHY_SCR,
- { 0x0000001f, 0x0000001f, 0x0000001f } },
- { AR5K_PHY_SLMT,
- { 0x00000080, 0x00000080, 0x00000080 } },
- { AR5K_PHY_SCAL,
- { 0x0000000e, 0x0000000e, 0x0000000e } },
- { AR5K_PHY(86),
- { 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY(96),
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(97),
- { 0x02800000, 0x02800000, 0x02800000 } },
- { AR5K_PHY(104),
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(120),
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(121),
- { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
- { AR5K_PHY(122),
- { 0x3c466478, 0x3c466478, 0x3c466478 } },
- { AR5K_PHY(123),
- { 0x000000aa, 0x000000aa, 0x000000aa } },
- { AR5K_PHY_SCLOCK,
- { 0x0000000c, 0x0000000c, 0x0000000c } },
- { AR5K_PHY_SDELAY,
- { 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY_SPENDING,
- { 0x00000014, 0x00000014, 0x00000014 } },
- { 0xa228,
- { 0x000009b5, 0x000009b5, 0x000009b5 } },
- { 0xa23c,
- { 0x93c889af, 0x93c889af, 0x93c889af } },
- { 0xa24c,
- { 0x00000001, 0x00000001, 0x00000001 } },
- { 0xa250,
- { 0x0000a000, 0x0000a000, 0x0000a000 } },
- { 0xa254,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa258,
- { 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
- { 0xa25c,
- { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
- { 0xa260,
- { 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
- { 0xa264,
- { 0x00418a11, 0x00418a11, 0x00418a11 } },
- { 0xa268,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa26c,
- { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
- { 0xa270,
- { 0x00820820, 0x00820820, 0x00820820 } },
- { 0xa274,
- { 0x001b7caa, 0x001b7caa, 0x001b7caa } },
- { 0xa278,
- { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
- { 0xa27c,
- { 0x051701ce, 0x051701ce, 0x051701ce } },
- { 0xa300,
- { 0x18010000, 0x18010000, 0x18010000 } },
- { 0xa304,
- { 0x30032602, 0x30032602, 0x30032602 } },
- { 0xa308,
- { 0x48073e06, 0x48073e06, 0x48073e06 } },
- { 0xa30c,
- { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
- { 0xa310,
- { 0x641a600f, 0x641a600f, 0x641a600f } },
- { 0xa314,
- { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
- { 0xa318,
- { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
- { 0xa31c,
- { 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
- { 0xa320,
- { 0x9d4f970f, 0x9d4f970f, 0x9d4f970f } },
- { 0xa324,
- { 0xa5cfa18f, 0xa5cfa18f, 0xa5cfa18f } },
- { 0xa328,
- { 0xb55faf1f, 0xb55faf1f, 0xb55faf1f } },
- { 0xa32c,
- { 0xbddfb99f, 0xbddfb99f, 0xbddfb99f } },
- { 0xa330,
- { 0xcd7fc73f, 0xcd7fc73f, 0xcd7fc73f } },
- { 0xa334,
- { 0xd5ffd1bf, 0xd5ffd1bf, 0xd5ffd1bf } },
- { 0xa338,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa33c,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa340,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa344,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa348,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa34c,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa350,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa354,
- { 0x0003ffff, 0x0003ffff, 0x0003ffff } },
- { 0xa358,
- { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
- { 0xa35c,
- { 0x066c420f, 0x066c420f, 0x066c420f } },
- { 0xa360,
- { 0x0f282207, 0x0f282207, 0x0f282207 } },
- { 0xa364,
- { 0x17601685, 0x17601685, 0x17601685 } },
- { 0xa368,
- { 0x1f801104, 0x1f801104, 0x1f801104 } },
- { 0xa36c,
- { 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
- { 0xa370,
- { 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
- { 0xa374,
- { 0x57c00803, 0x57c00803, 0x57c00803 } },
- { 0xa378,
- { 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
- { 0xa37c,
- { 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
- { 0xa380,
- { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
- { 0xa384,
- { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
+ { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf2413_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x000003e0 },
+ { AR5K_SEQ_MASK, 0x0000000f },
+ { AR5K_MIC_QOS_CTL, 0x00000000 },
+ { AR5K_MIC_QOS_SEL, 0x00000000 },
+ { AR5K_MISC_MODE, 0x00000000 },
+ { AR5K_OFDM_FIL_CNT, 0x00000000 },
+ { AR5K_CCK_FIL_CNT, 0x00000000 },
+ { AR5K_PHYERR_CNT1, 0x00000000 },
+ { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+ { AR5K_PHYERR_CNT2, 0x00000000 },
+ { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+ { AR5K_TSF_THRES, 0x00000000 },
+ { 0x8140, 0x800000a8 },
+ { 0x8144, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x0000a000 },
+ { 0x983c, 0x00200400 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+ { AR5K_PHY_SCR, 0x0000001f },
+ { AR5K_PHY_SLMT, 0x00000080 },
+ { AR5K_PHY_SCAL, 0x0000000e },
+ { 0x9958, 0x000000ff },
+ { AR5K_PHY_TIMING_7, 0x00000000 },
+ { AR5K_PHY_TIMING_8, 0x02800000 },
+ { AR5K_PHY_TIMING_11, 0x00000000 },
+ { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+ { 0x99e4, 0xaaaaaaaa },
+ { 0x99e8, 0x3c466478 },
+ { 0x99ec, 0x000000aa },
+ { AR5K_PHY_SCLOCK, 0x0000000c },
+ { AR5K_PHY_SDELAY, 0x000000ff },
+ { AR5K_PHY_SPENDING, 0x00000014 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+ { 0xa23c, 0x93c889af },
+ { AR5K_PHY_FAST_ADC, 0x00000001 },
+ { 0xa250, 0x0000a000 },
+ { AR5K_PHY_BLUETOOTH, 0x00000000 },
+ { AR5K_PHY_TPC_RG1, 0x0cc75380 },
+ { 0xa25c, 0x0f0f0f01 },
+ { 0xa260, 0x5f690f01 },
+ { 0xa264, 0x00418a11 },
+ { 0xa268, 0x00000000 },
+ { AR5K_PHY_TPC_RG5, 0x0c30c16a },
+ { 0xa270, 0x00820820 },
+ { 0xa274, 0x001b7caa },
+ { 0xa278, 0x1ce739ce },
+ { 0xa27c, 0x051701ce },
+ { 0xa300, 0x18010000 },
+ { 0xa304, 0x30032602 },
+ { 0xa308, 0x48073e06 },
+ { 0xa30c, 0x560b4c0a },
+ { 0xa310, 0x641a600f },
+ { 0xa314, 0x784f6e1b },
+ { 0xa318, 0x868f7c5a },
+ { 0xa31c, 0x8ecf865b },
+ { 0xa320, 0x9d4f970f },
+ { 0xa324, 0xa5cfa18f },
+ { 0xa328, 0xb55faf1f },
+ { 0xa32c, 0xbddfb99f },
+ { 0xa330, 0xcd7fc73f },
+ { 0xa334, 0xd5ffd1bf },
+ { 0xa338, 0x00000000 },
+ { 0xa33c, 0x00000000 },
+ { 0xa340, 0x00000000 },
+ { 0xa344, 0x00000000 },
+ { 0xa348, 0x3fffffff },
+ { 0xa34c, 0x3fffffff },
+ { 0xa350, 0x3fffffff },
+ { 0xa354, 0x0003ffff },
+ { 0xa358, 0x79a8aa1f },
+ { 0xa35c, 0x066c420f },
+ { 0xa360, 0x0f282207 },
+ { 0xa364, 0x17601685 },
+ { 0xa368, 0x1f801104 },
+ { 0xa36c, 0x37a00c03 },
+ { 0xa370, 0x3fc40883 },
+ { 0xa374, 0x57c00803 },
+ { 0xa378, 0x5fd80682 },
+ { 0xa37c, 0x7fe00482 },
+ { 0xa380, 0x7f3c7bba },
+ { 0xa384, 0xf3307ff0 },
};
/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
+/* XXX: a mode ? */
static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* g gTurbo */
- { 0x00000015, 0x00000015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x12e013ab, 0x098813cf } },
+ { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
{ AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003 } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x0000000b, 0x0000000b } },
- { AR5K_PHY(17),
- { 0x13721422, 0x13721422 } },
- { AR5K_PHY(18),
- { 0x00199a65, 0x00199a65 } },
- { AR5K_PHY(20),
- { 0x0c98b0da, 0x0c98b0da } },
+ { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_SETTLING,
+ { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
+ { AR5K_PHY_GAIN,
+ { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3139605e, 0x3139605e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081 } },
+ { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(642),
- { 0xd03e6788, 0xd03e6788 } },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { AR5K_PHY_CCK_CROSSCORR,
+ { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x0052c140, 0x0052c140 } },
- { 0xa21c,
- { 0x1883800a, 0x1883800a } },
+ { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
{ 0xa324,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa328,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa32c,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa330,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa334,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
- { AR5K_DCU_FP,
- { 0x000003e0, 0x000003e0 } },
- { 0x8060,
- { 0x0000000f, 0x0000000f } },
- { 0x809c,
- { 0x00000000, 0x00000000 } },
- { 0x80a0,
- { 0x00000000, 0x00000000 } },
- { 0x8118,
- { 0x00000000, 0x00000000 } },
- { 0x811c,
- { 0x00000000, 0x00000000 } },
- { 0x8120,
- { 0x00000000, 0x00000000 } },
- { 0x8124,
- { 0x00000000, 0x00000000 } },
- { 0x8128,
- { 0x00000000, 0x00000000 } },
- { 0x812c,
- { 0x00000000, 0x00000000 } },
- { 0x8130,
- { 0x00000000, 0x00000000 } },
- { 0x8134,
- { 0x00000000, 0x00000000 } },
- { 0x8138,
- { 0x00000000, 0x00000000 } },
- { 0x813c,
- { 0x00000000, 0x00000000 } },
- { 0x8140,
- { 0x800003f9, 0x800003f9 } },
- { 0x8144,
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x0000a000, 0x0000a000 } },
- { AR5K_PHY(15),
- { 0x00200400, 0x00200400 } },
- { AR5K_PHY(19),
- { 0x1284233c, 0x1284233c } },
- { AR5K_PHY_SCR,
- { 0x0000001f, 0x0000001f } },
- { AR5K_PHY_SLMT,
- { 0x00000080, 0x00000080 } },
- { AR5K_PHY_SCAL,
- { 0x0000000e, 0x0000000e } },
- { AR5K_PHY(86),
- { 0x00081fff, 0x00081fff } },
- { AR5K_PHY(96),
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(97),
- { 0x02800000, 0x02800000 } },
- { AR5K_PHY(104),
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(119),
- { 0xfebadbe8, 0xfebadbe8 } },
- { AR5K_PHY(120),
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(121),
- { 0xaaaaaaaa, 0xaaaaaaaa } },
- { AR5K_PHY(122),
- { 0x3c466478, 0x3c466478 } },
- { AR5K_PHY(123),
- { 0x000000aa, 0x000000aa } },
- { AR5K_PHY_SCLOCK,
- { 0x0000000c, 0x0000000c } },
- { AR5K_PHY_SDELAY,
- { 0x000000ff, 0x000000ff } },
- { AR5K_PHY_SPENDING,
- { 0x00000014, 0x00000014 } },
- { 0xa228,
- { 0x000009b5, 0x000009b5 } },
- { AR5K_PHY_TXPOWER_RATE3,
- { 0x20202020, 0x20202020 } },
- { AR5K_PHY_TXPOWER_RATE4,
- { 0x20202020, 0x20202020 } },
- { 0xa23c,
- { 0x93c889af, 0x93c889af } },
- { 0xa24c,
- { 0x00000001, 0x00000001 } },
- { 0xa250,
- { 0x0000a000, 0x0000a000 } },
- { 0xa254,
- { 0x00000000, 0x00000000 } },
- { 0xa258,
- { 0x0cc75380, 0x0cc75380 } },
- { 0xa25c,
- { 0x0f0f0f01, 0x0f0f0f01 } },
- { 0xa260,
- { 0x5f690f01, 0x5f690f01 } },
- { 0xa264,
- { 0x00418a11, 0x00418a11 } },
- { 0xa268,
- { 0x00000000, 0x00000000 } },
- { 0xa26c,
- { 0x0c30c166, 0x0c30c166 } },
- { 0xa270,
- { 0x00820820, 0x00820820 } },
- { 0xa274,
- { 0x081a3caa, 0x081a3caa } },
- { 0xa278,
- { 0x1ce739ce, 0x1ce739ce } },
- { 0xa27c,
- { 0x051701ce, 0x051701ce } },
- { 0xa300,
- { 0x16010000, 0x16010000 } },
- { 0xa304,
- { 0x2c032402, 0x2c032402 } },
- { 0xa308,
- { 0x48433e42, 0x48433e42 } },
- { 0xa30c,
- { 0x5a0f500b, 0x5a0f500b } },
- { 0xa310,
- { 0x6c4b624a, 0x6c4b624a } },
- { 0xa314,
- { 0x7e8b748a, 0x7e8b748a } },
- { 0xa318,
- { 0x96cf8ccb, 0x96cf8ccb } },
- { 0xa31c,
- { 0xa34f9d0f, 0xa34f9d0f } },
- { 0xa320,
- { 0xa7cfa58f, 0xa7cfa58f } },
- { 0xa348,
- { 0x3fffffff, 0x3fffffff } },
- { 0xa34c,
- { 0x3fffffff, 0x3fffffff } },
- { 0xa350,
- { 0x3fffffff, 0x3fffffff } },
- { 0xa354,
- { 0x0003ffff, 0x0003ffff } },
- { 0xa358,
- { 0x79a8aa1f, 0x79a8aa1f } },
- { 0xa35c,
- { 0x066c420f, 0x066c420f } },
- { 0xa360,
- { 0x0f282207, 0x0f282207 } },
- { 0xa364,
- { 0x17601685, 0x17601685 } },
- { 0xa368,
- { 0x1f801104, 0x1f801104 } },
- { 0xa36c,
- { 0x37a00c03, 0x37a00c03 } },
- { 0xa370,
- { 0x3fc40883, 0x3fc40883 } },
- { 0xa374,
- { 0x57c00803, 0x57c00803 } },
- { 0xa378,
- { 0x5fd80682, 0x5fd80682 } },
- { 0xa37c,
- { 0x7fe00482, 0x7fe00482 } },
- { 0xa380,
- { 0x7f3c7bba, 0x7f3c7bba } },
- { 0xa384,
- { 0xf3307ff0, 0xf3307ff0 } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+};
+
+static const struct ath5k_ini rf2425_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x000003e0 },
+ { AR5K_SEQ_MASK, 0x0000000f },
+ { 0x809c, 0x00000000 },
+ { 0x80a0, 0x00000000 },
+ { AR5K_MIC_QOS_CTL, 0x00000000 },
+ { AR5K_MIC_QOS_SEL, 0x00000000 },
+ { AR5K_MISC_MODE, 0x00000000 },
+ { AR5K_OFDM_FIL_CNT, 0x00000000 },
+ { AR5K_CCK_FIL_CNT, 0x00000000 },
+ { AR5K_PHYERR_CNT1, 0x00000000 },
+ { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+ { AR5K_PHYERR_CNT2, 0x00000000 },
+ { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+ { AR5K_TSF_THRES, 0x00000000 },
+ { 0x8140, 0x800003f9 },
+ { 0x8144, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x0000a000 },
+ { 0x983c, 0x00200400 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+ { AR5K_PHY_SCR, 0x0000001f },
+ { AR5K_PHY_SLMT, 0x00000080 },
+ { AR5K_PHY_SCAL, 0x0000000e },
+ { 0x9958, 0x00081fff },
+ { AR5K_PHY_TIMING_7, 0x00000000 },
+ { AR5K_PHY_TIMING_8, 0x02800000 },
+ { AR5K_PHY_TIMING_11, 0x00000000 },
+ { 0x99dc, 0xfebadbe8 },
+ { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+ { 0x99e4, 0xaaaaaaaa },
+ { 0x99e8, 0x3c466478 },
+ { 0x99ec, 0x000000aa },
+ { AR5K_PHY_SCLOCK, 0x0000000c },
+ { AR5K_PHY_SDELAY, 0x000000ff },
+ { AR5K_PHY_SPENDING, 0x00000014 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+ { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
+ { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
+ { 0xa23c, 0x93c889af },
+ { AR5K_PHY_FAST_ADC, 0x00000001 },
+ { 0xa250, 0x0000a000 },
+ { AR5K_PHY_BLUETOOTH, 0x00000000 },
+ { AR5K_PHY_TPC_RG1, 0x0cc75380 },
+ { 0xa25c, 0x0f0f0f01 },
+ { 0xa260, 0x5f690f01 },
+ { 0xa264, 0x00418a11 },
+ { 0xa268, 0x00000000 },
+ { AR5K_PHY_TPC_RG5, 0x0c30c166 },
+ { 0xa270, 0x00820820 },
+ { 0xa274, 0x081a3caa },
+ { 0xa278, 0x1ce739ce },
+ { 0xa27c, 0x051701ce },
+ { 0xa300, 0x16010000 },
+ { 0xa304, 0x2c032402 },
+ { 0xa308, 0x48433e42 },
+ { 0xa30c, 0x5a0f500b },
+ { 0xa310, 0x6c4b624a },
+ { 0xa314, 0x7e8b748a },
+ { 0xa318, 0x96cf8ccb },
+ { 0xa31c, 0xa34f9d0f },
+ { 0xa320, 0xa7cfa58f },
+ { 0xa348, 0x3fffffff },
+ { 0xa34c, 0x3fffffff },
+ { 0xa350, 0x3fffffff },
+ { 0xa354, 0x0003ffff },
+ { 0xa358, 0x79a8aa1f },
+ { 0xa35c, 0x066c420f },
+ { 0xa360, 0x0f282207 },
+ { 0xa364, 0x17601685 },
+ { 0xa368, 0x1f801104 },
+ { 0xa36c, 0x37a00c03 },
+ { 0xa370, 0x3fc40883 },
+ { 0xa374, 0x57c00803 },
+ { 0xa378, 0x5fd80682 },
+ { 0xa37c, 0x7fe00482 },
+ { 0xa380, 0x7f3c7bba },
+ { 0xa384, 0xf3307ff0 },
};
/*
@@ -1560,7 +1297,7 @@ static const struct ath5k_ini rf5111_ini_bbgain[] = {
{ AR5K_BB_GAIN(63), 0x00000016 },
};
-/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414) */
+/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */
static const struct ath5k_ini rf5112_ini_bbgain[] = {
{ AR5K_BB_GAIN(0), 0x00000000 },
{ AR5K_BB_GAIN(1), 0x00000001 },
@@ -1691,87 +1428,97 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
/*
* Write initial settings common for all modes
*/
- ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini),
- ar5212_ini, change_channel);
+ ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
+ ar5212_ini_common_start, change_channel);
/* Second set of mode-specific settings */
- if (ah->ah_radio == AR5K_RF5111) {
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
ath5k_hw_ini_mode_registers(ah,
- ARRAY_SIZE(ar5212_rf5111_ini_mode_end),
- ar5212_rf5111_ini_mode_end, mode);
+ ARRAY_SIZE(rf5111_ini_mode_end),
+ rf5111_ini_mode_end, mode);
+
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5111_ini_common_end),
+ rf5111_ini_common_end, change_channel);
/* Baseband gain table */
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5111_ini_bbgain),
rf5111_ini_bbgain, change_channel);
- } else if (ah->ah_radio == AR5K_RF5112) {
+ break;
+ case AR5K_RF5112:
ath5k_hw_ini_mode_registers(ah,
- ARRAY_SIZE(ar5212_rf5112_ini_mode_end),
- ar5212_rf5112_ini_mode_end, mode);
+ ARRAY_SIZE(rf5112_ini_mode_end),
+ rf5112_ini_mode_end, mode);
+
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5112_ini_common_end),
+ rf5112_ini_common_end, change_channel);
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
rf5112_ini_bbgain, change_channel);
- } else if (ah->ah_radio == AR5K_RF5413) {
+ break;
+ case AR5K_RF5413:
ath5k_hw_ini_mode_registers(ah,
ARRAY_SIZE(rf5413_ini_mode_end),
rf5413_ini_mode_end, mode);
ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5413_ini_common_end),
+ rf5413_ini_common_end, change_channel);
+
+ ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
rf5112_ini_bbgain, change_channel);
- } else if (ah->ah_radio == AR5K_RF2413) {
-
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc,
- "unsupported channel mode: %d\n", mode);
- return -EINVAL;
- }
- mode = mode - 2;
-
- /* Override a setting from ar5212_ini */
- ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
+ break;
+ case AR5K_RF2316:
+ case AR5K_RF2413:
ath5k_hw_ini_mode_registers(ah,
ARRAY_SIZE(rf2413_ini_mode_end),
rf2413_ini_mode_end, mode);
- /* Baseband gain table */
ath5k_hw_ini_registers(ah,
- ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
-
- } else if (ah->ah_radio == AR5K_RF2425) {
+ ARRAY_SIZE(rf2413_ini_common_end),
+ rf2413_ini_common_end, change_channel);
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc,
- "unsupported channel mode: %d\n", mode);
- return -EINVAL;
+ /* Override settings from rf2413_ini_common_end */
+ if (ah->ah_radio == AR5K_RF2316) {
+ ath5k_hw_reg_write(ah, 0x00004000,
+ AR5K_PHY_AGC);
+ ath5k_hw_reg_write(ah, 0x081b7caa,
+ 0xa274);
}
- /* Map b to g */
- if (mode == 2)
- mode = 0;
- else
- mode = mode - 3;
-
- /* Override a setting from ar5212_ini */
- ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5112_ini_bbgain),
+ rf5112_ini_bbgain, change_channel);
+ break;
+ case AR5K_RF2317:
+ case AR5K_RF2425:
ath5k_hw_ini_mode_registers(ah,
ARRAY_SIZE(rf2425_ini_mode_end),
rf2425_ini_mode_end, mode);
- /* Baseband gain table */
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf2413_ini_common_end),
+ rf2413_ini_common_end, change_channel);
+
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
rf5112_ini_bbgain, change_channel);
+ break;
+ default:
+ return -EINVAL;
}
diff --git a/drivers/net/wireless/ath5k/led.c b/drivers/net/wireless/ath5k/led.c
new file mode 100644
index 00000000000..0686e12738b
--- /dev/null
+++ b/drivers/net/wireless/ath5k/led.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2009 Bob Copeland <me@bobcopeland.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/pci.h>
+#include "ath5k.h"
+#include "base.h"
+
+#define ATH_SDEVICE(subv,subd) \
+ .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
+ .subvendor = (subv), .subdevice = (subd)
+
+#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
+#define ATH_PIN(data) ((data) >> 8)
+#define ATH_POLARITY(data) ((data) & 0xff)
+
+/* Devices we match on for LED config info (typically laptops) */
+static const struct pci_device_id ath5k_led_devices[] = {
+ /* IBM-specific AR5212 */
+ { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
+ /* AR5211 */
+ { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
+ /* HP Compaq nc6xx, nc4000, nx6000 */
+ { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
+ /* Acer Aspire One A150 (maximlevitsky@gmail.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
+ /* Acer Ferrari 5000 (russ.dill@gmail.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
+ /* E-machines E510 (tuliom@gmail.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
+ { }
+};
+
+void ath5k_led_enable(struct ath5k_softc *sc)
+{
+ if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+ ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
+ ath5k_led_off(sc);
+ }
+}
+
+void ath5k_led_on(struct ath5k_softc *sc)
+{
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+ return;
+ ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
+}
+
+void ath5k_led_off(struct ath5k_softc *sc)
+{
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+ return;
+ ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
+}
+
+static void
+ath5k_led_brightness_set(struct led_classdev *led_dev,
+ enum led_brightness brightness)
+{
+ struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
+ led_dev);
+
+ if (brightness == LED_OFF)
+ ath5k_led_off(led->sc);
+ else
+ ath5k_led_on(led->sc);
+}
+
+static int
+ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
+ const char *name, char *trigger)
+{
+ int err;
+
+ led->sc = sc;
+ strncpy(led->name, name, sizeof(led->name));
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = trigger;
+ led->led_dev.brightness_set = ath5k_led_brightness_set;
+
+ err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
+ if (err) {
+ ATH5K_WARN(sc, "could not register LED %s\n", name);
+ led->sc = NULL;
+ }
+ return err;
+}
+
+static void
+ath5k_unregister_led(struct ath5k_led *led)
+{
+ if (!led->sc)
+ return;
+ led_classdev_unregister(&led->led_dev);
+ ath5k_led_off(led->sc);
+ led->sc = NULL;
+}
+
+void ath5k_unregister_leds(struct ath5k_softc *sc)
+{
+ ath5k_unregister_led(&sc->rx_led);
+ ath5k_unregister_led(&sc->tx_led);
+}
+
+int ath5k_init_leds(struct ath5k_softc *sc)
+{
+ int ret = 0;
+ struct ieee80211_hw *hw = sc->hw;
+ struct pci_dev *pdev = sc->pdev;
+ char name[ATH5K_LED_MAX_NAME_LEN + 1];
+ const struct pci_device_id *match;
+
+ match = pci_match_id(&ath5k_led_devices[0], pdev);
+ if (match) {
+ __set_bit(ATH_STAT_LEDSOFT, sc->status);
+ sc->led_pin = ATH_PIN(match->driver_data);
+ sc->led_on = ATH_POLARITY(match->driver_data);
+ }
+
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+ goto out;
+
+ ath5k_led_enable(sc);
+
+ snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
+ ret = ath5k_register_led(sc, &sc->rx_led, name,
+ ieee80211_get_rx_led_name(hw));
+ if (ret)
+ goto out;
+
+ snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
+ ret = ath5k_register_led(sc, &sc->tx_led, name,
+ ieee80211_get_tx_led_name(hw));
+out:
+ return ret;
+}
+
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c
index 75eb9f43c74..55122f1e198 100644
--- a/drivers/net/wireless/ath5k/pcu.c
+++ b/drivers/net/wireless/ath5k/pcu.c
@@ -646,6 +646,22 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
}
/**
+ * ath5k_hw_set_tsf64 - Set a new 64bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ * @tsf64: The new 64bit TSF
+ *
+ * Sets the new TSF
+ */
+void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
+{
+ ATH5K_TRACE(ah->ah_sc);
+
+ ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
+ ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
+}
+
+/**
* ath5k_hw_reset_tsf - Force a TSF reset
*
* @ah: The &struct ath5k_hw
@@ -1026,6 +1042,9 @@ int ath5k_keycache_type(const struct ieee80211_key_conf *key)
return AR5K_KEYTABLE_TYPE_40;
else if (key->keylen == LEN_WEP104)
return AR5K_KEYTABLE_TYPE_104;
+ return -EINVAL;
+ default:
+ return -EINVAL;
}
return -EINVAL;
}
@@ -1041,7 +1060,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
__le32 key_v[5] = {};
__le32 key0 = 0, key1 = 0;
__le32 *rxmic, *txmic;
- u32 keytype;
+ int keytype;
u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
bool is_tkip;
const u8 *key_ptr;
@@ -1139,7 +1158,7 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
/* MAC may be NULL if it's a broadcast key. In this case no need to
* to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
- if (unlikely(mac == NULL)) {
+ if (!mac) {
low_id = 0xffffffff;
high_id = 0xffff | AR5K_KEYTABLE_VALID;
} else {
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 7ba18e09463..81f5bebc48b 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -2,7 +2,7 @@
* PHY functions
*
* Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -26,1138 +26,191 @@
#include "ath5k.h"
#include "reg.h"
#include "base.h"
-
-/* Struct to hold initial RF register values (RF Banks) */
-struct ath5k_ini_rf {
- u8 rf_bank; /* check out ath5k_reg.h */
- u16 rf_register; /* register address */
- u32 rf_value[5]; /* register value for different modes (above) */
-};
-
-/*
- * Mode-specific RF Gain table (64bytes) for RF5111/5112
- * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
- * RF Gain values are included in AR5K_AR5210_INI)
- */
-struct ath5k_ini_rfgain {
- u16 rfg_register; /* RF Gain register address */
- u32 rfg_value[2]; /* [freq (see below)] */
-};
-
-struct ath5k_gain_opt {
- u32 go_default;
- u32 go_steps_count;
- const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT];
-};
-
-/* RF5111 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5111[] = {
- { 0, 0x989c,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
- { 0, 0x989c,
- { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
- { 0, 0x98d4,
- { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
- { 1, 0x98d4,
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d4,
- { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
- { 3, 0x98d8,
- { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
- { 6, 0x989c,
- { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
- { 6, 0x989c,
- { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
- { 6, 0x989c,
- { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
- { 6, 0x989c,
- { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
- { 6, 0x98d4,
- { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
- { 7, 0x989c,
- { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
- { 7, 0x989c,
- { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
- { 7, 0x989c,
- { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
- { 7, 0x989c,
- { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
- { 7, 0x989c,
- { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
- { 7, 0x989c,
- { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
- { 7, 0x989c,
- { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
-};
-
-/* Initial RF Gain settings for RF5111 */
-static const struct ath5k_ini_rfgain rfgain_5111[] = {
- /* 5Ghz 2Ghz */
- { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } },
- { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } },
- { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } },
- { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } },
- { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } },
- { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } },
- { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } },
- { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } },
- { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } },
- { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } },
- { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } },
- { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } },
- { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } },
- { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } },
- { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } },
- { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } },
- { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } },
- { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } },
- { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } },
- { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } },
- { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } },
- { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } },
- { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } },
- { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } },
- { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } },
- { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } },
- { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } },
- { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } },
- { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } },
- { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } },
- { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } },
- { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } },
- { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } },
- { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } },
- { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } },
- { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } },
- { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } },
- { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } },
- { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } },
- { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } },
- { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } },
- { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } },
- { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } },
- { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } },
- { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } },
- { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } },
- { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } },
- { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } },
- { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } },
- { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } },
- { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } },
-};
-
-static const struct ath5k_gain_opt rfgain_opt_5111 = {
- 4,
- 9,
- {
- { { 4, 1, 1, 1 }, 6 },
- { { 4, 0, 1, 1 }, 4 },
- { { 3, 1, 1, 1 }, 3 },
- { { 4, 0, 0, 1 }, 1 },
- { { 4, 1, 1, 0 }, 0 },
- { { 4, 0, 1, 0 }, -2 },
- { { 3, 1, 1, 0 }, -3 },
- { { 4, 0, 0, 0 }, -4 },
- { { 2, 1, 1, 0 }, -6 }
- }
-};
-
-/* RF5112 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5112[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
- { 3, 0x98dc,
- { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
- { 6, 0x989c,
- { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
- { 6, 0x989c,
- { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
- { 6, 0x989c,
- { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
- { 6, 0x989c,
- { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
- { 6, 0x989c,
- { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
- { 6, 0x989c,
- { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
- { 6, 0x989c,
- { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
- { 6, 0x989c,
- { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
- { 6, 0x989c,
- { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
- { 6, 0x989c,
- { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
- { 6, 0x989c,
- { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
- { 6, 0x989c,
- { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
- { 6, 0x989c,
- { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
- { 6, 0x989c,
- { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
- { 6, 0x989c,
- { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
- { 6, 0x989c,
- { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
- { 6, 0x989c,
- { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
- { 6, 0x989c,
- { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
- { 6, 0x989c,
- { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
- { 6, 0x989c,
- { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
- { 6, 0x989c,
- { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
- { 6, 0x98d0,
- { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
- { 7, 0x989c,
- { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
- { 7, 0x989c,
- { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
- { 7, 0x989c,
- { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
- { 7, 0x989c,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { 7, 0x989c,
- { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
- { 7, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 7, 0x989c,
- { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, 0x989c,
- { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
- { 7, 0x989c,
- { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
- { 7, 0x989c,
- { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, 0x989c,
- { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, 0x989c,
- { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, 0x98c4,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-/* RF5112A mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5112a[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
- { 3, 0x98dc,
- { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
- { 6, 0x989c,
- { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
- { 6, 0x989c,
- { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
- { 6, 0x989c,
- { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
- { 6, 0x989c,
- { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
- { 6, 0x989c,
- { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
- { 6, 0x989c,
- { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
- { 6, 0x989c,
- { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00190000, 0x00190000, 0x00190000, 0x00190000, 0x00190000 } },
- { 6, 0x989c,
- { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
- { 6, 0x989c,
- { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
- { 6, 0x989c,
- { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
- { 6, 0x989c,
- { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
- { 6, 0x989c,
- { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
- { 6, 0x989c,
- { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
- { 6, 0x989c,
- { 0x00020080, 0x00020080, 0x00020080, 0x00020080, 0x00020080 } },
- { 6, 0x989c,
- { 0x00080009, 0x00080009, 0x00080009, 0x00080009, 0x00080009 } },
- { 6, 0x989c,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
- { 6, 0x989c,
- { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
- { 6, 0x989c,
- { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
- { 6, 0x989c,
- { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
- { 6, 0x989c,
- { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
- { 6, 0x98d8,
- { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
- { 7, 0x989c,
- { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
- { 7, 0x989c,
- { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
- { 7, 0x989c,
- { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
- { 7, 0x989c,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { 7, 0x989c,
- { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
- { 7, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 7, 0x989c,
- { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, 0x989c,
- { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
- { 7, 0x989c,
- { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
- { 7, 0x989c,
- { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, 0x989c,
- { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, 0x989c,
- { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, 0x98c4,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-
-static const struct ath5k_ini_rf rfregs_2112a[] = {
- { 1, AR5K_RF_BUFFER_CONTROL_4,
- /* mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020 } },
- { 2, AR5K_RF_BUFFER_CONTROL_3,
- { 0x03060408, 0x03060408, 0x03070408 } },
- { 3, AR5K_RF_BUFFER_CONTROL_6,
- { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0a000000, 0x0a000000, 0x0a000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00800000, 0x00800000, 0x00800000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00010000, 0x00010000, 0x00010000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00180000, 0x00180000, 0x00180000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x006e0000, 0x006e0000, 0x006e0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00c70000, 0x00c70000, 0x00c70000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x004b0000, 0x004b0000, 0x004b0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x04480000, 0x04480000, 0x04480000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00e40000, 0x00e40000, 0x00e40000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x043f0000, 0x043f0000, 0x043f0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0c0c0000, 0x0c0c0000, 0x0c0c0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x02190000, 0x02190000, 0x02190000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00240000, 0x00240000, 0x00240000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00b40000, 0x00b40000, 0x00b40000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00990000, 0x00990000, 0x00990000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00500000, 0x00500000, 0x00500000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00120000, 0x00120000, 0x00120000 } },
- { 6, AR5K_RF_BUFFER,
- { 0xc0320000, 0xc0320000, 0xc0320000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x01740000, 0x01740000, 0x01740000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00110000, 0x00110000, 0x00110000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x86280000, 0x86280000, 0x86280000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x31840000, 0x31840000, 0x31840000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00f20080, 0x00f20080, 0x00f20080 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00070019, 0x00070019, 0x00070019 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x000000b2, 0x000000b2, 0x000000b2 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00b02184, 0x00b02184, 0x00b02184 } },
- { 6, AR5K_RF_BUFFER,
- { 0x004125a4, 0x004125a4, 0x004125a4 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00119220, 0x00119220, 0x00119220 } },
- { 6, AR5K_RF_BUFFER,
- { 0x001a4800, 0x001a4800, 0x001a4800 } },
- { 6, AR5K_RF_BUFFER_CONTROL_5,
- { 0x000b0230, 0x000b0230, 0x000b0230 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000094, 0x00000094, 0x00000094 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000091, 0x00000091, 0x00000091 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000012, 0x00000012, 0x00000012 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000080, 0x00000080, 0x00000080 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000000d9, 0x000000d9, 0x000000d9 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000060, 0x00000060, 0x00000060 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000000a2, 0x000000a2, 0x000000a2 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000052, 0x00000052, 0x00000052 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, AR5K_RF_BUFFER,
- { 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, AR5K_RF_BUFFER_CONTROL_1,
- { 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-/* RF5413/5414 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5413[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
- { 3, 0x98dc,
- { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
- { 6, 0x989c,
- { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
- { 6, 0x989c,
- { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
- { 6, 0x989c,
- { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
- { 6, 0x989c,
- { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
- { 6, 0x989c,
- { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
- { 6, 0x989c,
- { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
- { 6, 0x989c,
- { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
- { 6, 0x989c,
- { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
- { 6, 0x989c,
- { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
- { 6, 0x989c,
- { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
- { 6, 0x989c,
- { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
- { 6, 0x989c,
- { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
- { 6, 0x989c,
- { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
- { 6, 0x989c,
- { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
- { 6, 0x989c,
- { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
- { 6, 0x989c,
- { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
- { 6, 0x989c,
- { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
- { 6, 0x989c,
- { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
- { 6, 0x989c,
- { 0x00510040, 0x00510040, 0x005100a0, 0x005100a0, 0x005100a0 } },
- { 6, 0x989c,
- { 0x0050006a, 0x0050006a, 0x005000dd, 0x005000dd, 0x005000dd } },
- { 6, 0x989c,
- { 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
- { 6, 0x989c,
- { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00003600 } },
- { 6, 0x98c8,
- { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-/* RF2413/2414 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_2413[] = {
- { 1, AR5K_RF_BUFFER_CONTROL_4,
- /* mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020 } },
- { 2, AR5K_RF_BUFFER_CONTROL_3,
- { 0x02001408, 0x02001408, 0x02001408 } },
- { 3, AR5K_RF_BUFFER_CONTROL_6,
- { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, AR5K_RF_BUFFER,
- { 0xf0000000, 0xf0000000, 0xf0000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x03000000, 0x03000000, 0x03000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x40400000, 0x40400000, 0x40400000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x65050000, 0x65050000, 0x65050000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00420000, 0x00420000, 0x00420000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00b50000, 0x00b50000, 0x00b50000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00030000, 0x00030000, 0x00030000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00f70000, 0x00f70000, 0x00f70000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x009d0000, 0x009d0000, 0x009d0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00220000, 0x00220000, 0x00220000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x04220000, 0x04220000, 0x04220000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00230018, 0x00230018, 0x00230018 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00280050, 0x00280050, 0x00280050 } },
- { 6, AR5K_RF_BUFFER,
- { 0x005000c3, 0x005000c3, 0x005000c3 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0004007f, 0x0004007f, 0x0004007f } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000458, 0x00000458, 0x00000458 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0000c000, 0x0000c000, 0x0000c000 } },
- { 6, AR5K_RF_BUFFER_CONTROL_5,
- { 0x00400230, 0x00400230, 0x00400230 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00006400, 0x00006400, 0x00006400 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000800, 0x00000800, 0x00000800 } },
- { 7, AR5K_RF_BUFFER_CONTROL_2,
- { 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-/* RF2425 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_2425[] = {
- { 1, AR5K_RF_BUFFER_CONTROL_4,
- /* mode g mode gTurbo */
- { 0x00000020, 0x00000020 } },
- { 2, AR5K_RF_BUFFER_CONTROL_3,
- { 0x02001408, 0x02001408 } },
- { 3, AR5K_RF_BUFFER_CONTROL_6,
- { 0x00e020c0, 0x00e020c0 } },
- { 6, AR5K_RF_BUFFER,
- { 0x10000000, 0x10000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x002a0000, 0x002a0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00100000, 0x00100000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00020000, 0x00020000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00730000, 0x00730000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00f80000, 0x00f80000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00e70000, 0x00e70000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00140000, 0x00140000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00910040, 0x00910040 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0007001a, 0x0007001a } },
- { 6, AR5K_RF_BUFFER,
- { 0x00410000, 0x00410000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00810060, 0x00810060 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00020803, 0x00020803 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00001660, 0x00001660 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00001688, 0x00001688 } },
- { 6, AR5K_RF_BUFFER_CONTROL_1,
- { 0x00000001, 0x00000001 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00006400, 0x00006400 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000800, 0x00000800 } },
- { 7, AR5K_RF_BUFFER_CONTROL_2,
- { 0x0000000e, 0x0000000e } },
-};
-
-/* Initial RF Gain settings for RF5112 */
-static const struct ath5k_ini_rfgain rfgain_5112[] = {
- /* 5Ghz 2Ghz */
- { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } },
- { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } },
- { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } },
- { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } },
- { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } },
- { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } },
- { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } },
- { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } },
- { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } },
- { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } },
- { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } },
- { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } },
- { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } },
- { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } },
- { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } },
- { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } },
- { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } },
- { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } },
- { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } },
- { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } },
- { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } },
- { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } },
- { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } },
- { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } },
- { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } },
- { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } },
- { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } },
- { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } },
- { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } },
- { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } },
- { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } },
- { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } },
- { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } },
- { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } },
- { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } },
- { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } },
- { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } },
- { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } },
- { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } },
- { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } },
- { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } },
- { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } },
- { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } },
- { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } },
- { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } },
- { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } },
- { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } },
- { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } },
- { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } },
- { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } },
- { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } },
- { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } },
- { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } },
- { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } },
- { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } },
-};
-
-/* Initial RF Gain settings for RF5413 */
-static const struct ath5k_ini_rfgain rfgain_5413[] = {
- /* 5Ghz 2Ghz */
- { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
- { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } },
- { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } },
- { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } },
- { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } },
- { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } },
- { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } },
- { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } },
- { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } },
- { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } },
- { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } },
- { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } },
- { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } },
- { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } },
- { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } },
- { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } },
- { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } },
- { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } },
- { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } },
- { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } },
- { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } },
- { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } },
- { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } },
- { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } },
- { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } },
- { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } },
- { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } },
- { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } },
- { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } },
- { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } },
- { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } },
- { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } },
- { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } },
- { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } },
- { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } },
- { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } },
- { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } },
- { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } },
- { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } },
- { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
-};
-
-/* Initial RF Gain settings for RF2413 */
-static const struct ath5k_ini_rfgain rfgain_2413[] = {
- { AR5K_RF_GAIN(0), { 0x00000000 } },
- { AR5K_RF_GAIN(1), { 0x00000040 } },
- { AR5K_RF_GAIN(2), { 0x00000080 } },
- { AR5K_RF_GAIN(3), { 0x00000181 } },
- { AR5K_RF_GAIN(4), { 0x000001c1 } },
- { AR5K_RF_GAIN(5), { 0x00000001 } },
- { AR5K_RF_GAIN(6), { 0x00000041 } },
- { AR5K_RF_GAIN(7), { 0x00000081 } },
- { AR5K_RF_GAIN(8), { 0x00000168 } },
- { AR5K_RF_GAIN(9), { 0x000001a8 } },
- { AR5K_RF_GAIN(10), { 0x000001e8 } },
- { AR5K_RF_GAIN(11), { 0x00000028 } },
- { AR5K_RF_GAIN(12), { 0x00000068 } },
- { AR5K_RF_GAIN(13), { 0x00000189 } },
- { AR5K_RF_GAIN(14), { 0x000001c9 } },
- { AR5K_RF_GAIN(15), { 0x00000009 } },
- { AR5K_RF_GAIN(16), { 0x00000049 } },
- { AR5K_RF_GAIN(17), { 0x00000089 } },
- { AR5K_RF_GAIN(18), { 0x00000190 } },
- { AR5K_RF_GAIN(19), { 0x000001d0 } },
- { AR5K_RF_GAIN(20), { 0x00000010 } },
- { AR5K_RF_GAIN(21), { 0x00000050 } },
- { AR5K_RF_GAIN(22), { 0x00000090 } },
- { AR5K_RF_GAIN(23), { 0x00000191 } },
- { AR5K_RF_GAIN(24), { 0x000001d1 } },
- { AR5K_RF_GAIN(25), { 0x00000011 } },
- { AR5K_RF_GAIN(26), { 0x00000051 } },
- { AR5K_RF_GAIN(27), { 0x00000091 } },
- { AR5K_RF_GAIN(28), { 0x00000178 } },
- { AR5K_RF_GAIN(29), { 0x000001b8 } },
- { AR5K_RF_GAIN(30), { 0x000001f8 } },
- { AR5K_RF_GAIN(31), { 0x00000038 } },
- { AR5K_RF_GAIN(32), { 0x00000078 } },
- { AR5K_RF_GAIN(33), { 0x00000199 } },
- { AR5K_RF_GAIN(34), { 0x000001d9 } },
- { AR5K_RF_GAIN(35), { 0x00000019 } },
- { AR5K_RF_GAIN(36), { 0x00000059 } },
- { AR5K_RF_GAIN(37), { 0x00000099 } },
- { AR5K_RF_GAIN(38), { 0x000000d9 } },
- { AR5K_RF_GAIN(39), { 0x000000f9 } },
- { AR5K_RF_GAIN(40), { 0x000000f9 } },
- { AR5K_RF_GAIN(41), { 0x000000f9 } },
- { AR5K_RF_GAIN(42), { 0x000000f9 } },
- { AR5K_RF_GAIN(43), { 0x000000f9 } },
- { AR5K_RF_GAIN(44), { 0x000000f9 } },
- { AR5K_RF_GAIN(45), { 0x000000f9 } },
- { AR5K_RF_GAIN(46), { 0x000000f9 } },
- { AR5K_RF_GAIN(47), { 0x000000f9 } },
- { AR5K_RF_GAIN(48), { 0x000000f9 } },
- { AR5K_RF_GAIN(49), { 0x000000f9 } },
- { AR5K_RF_GAIN(50), { 0x000000f9 } },
- { AR5K_RF_GAIN(51), { 0x000000f9 } },
- { AR5K_RF_GAIN(52), { 0x000000f9 } },
- { AR5K_RF_GAIN(53), { 0x000000f9 } },
- { AR5K_RF_GAIN(54), { 0x000000f9 } },
- { AR5K_RF_GAIN(55), { 0x000000f9 } },
- { AR5K_RF_GAIN(56), { 0x000000f9 } },
- { AR5K_RF_GAIN(57), { 0x000000f9 } },
- { AR5K_RF_GAIN(58), { 0x000000f9 } },
- { AR5K_RF_GAIN(59), { 0x000000f9 } },
- { AR5K_RF_GAIN(60), { 0x000000f9 } },
- { AR5K_RF_GAIN(61), { 0x000000f9 } },
- { AR5K_RF_GAIN(62), { 0x000000f9 } },
- { AR5K_RF_GAIN(63), { 0x000000f9 } },
-};
-
-/* Initial RF Gain settings for RF2425 */
-static const struct ath5k_ini_rfgain rfgain_2425[] = {
- { AR5K_RF_GAIN(0), { 0x00000000 } },
- { AR5K_RF_GAIN(1), { 0x00000040 } },
- { AR5K_RF_GAIN(2), { 0x00000080 } },
- { AR5K_RF_GAIN(3), { 0x00000181 } },
- { AR5K_RF_GAIN(4), { 0x000001c1 } },
- { AR5K_RF_GAIN(5), { 0x00000001 } },
- { AR5K_RF_GAIN(6), { 0x00000041 } },
- { AR5K_RF_GAIN(7), { 0x00000081 } },
- { AR5K_RF_GAIN(8), { 0x00000188 } },
- { AR5K_RF_GAIN(9), { 0x000001c8 } },
- { AR5K_RF_GAIN(10), { 0x00000008 } },
- { AR5K_RF_GAIN(11), { 0x00000048 } },
- { AR5K_RF_GAIN(12), { 0x00000088 } },
- { AR5K_RF_GAIN(13), { 0x00000189 } },
- { AR5K_RF_GAIN(14), { 0x000001c9 } },
- { AR5K_RF_GAIN(15), { 0x00000009 } },
- { AR5K_RF_GAIN(16), { 0x00000049 } },
- { AR5K_RF_GAIN(17), { 0x00000089 } },
- { AR5K_RF_GAIN(18), { 0x000001b0 } },
- { AR5K_RF_GAIN(19), { 0x000001f0 } },
- { AR5K_RF_GAIN(20), { 0x00000030 } },
- { AR5K_RF_GAIN(21), { 0x00000070 } },
- { AR5K_RF_GAIN(22), { 0x00000171 } },
- { AR5K_RF_GAIN(23), { 0x000001b1 } },
- { AR5K_RF_GAIN(24), { 0x000001f1 } },
- { AR5K_RF_GAIN(25), { 0x00000031 } },
- { AR5K_RF_GAIN(26), { 0x00000071 } },
- { AR5K_RF_GAIN(27), { 0x000001b8 } },
- { AR5K_RF_GAIN(28), { 0x000001f8 } },
- { AR5K_RF_GAIN(29), { 0x00000038 } },
- { AR5K_RF_GAIN(30), { 0x00000078 } },
- { AR5K_RF_GAIN(31), { 0x000000b8 } },
- { AR5K_RF_GAIN(32), { 0x000001b9 } },
- { AR5K_RF_GAIN(33), { 0x000001f9 } },
- { AR5K_RF_GAIN(34), { 0x00000039 } },
- { AR5K_RF_GAIN(35), { 0x00000079 } },
- { AR5K_RF_GAIN(36), { 0x000000b9 } },
- { AR5K_RF_GAIN(37), { 0x000000f9 } },
- { AR5K_RF_GAIN(38), { 0x000000f9 } },
- { AR5K_RF_GAIN(39), { 0x000000f9 } },
- { AR5K_RF_GAIN(40), { 0x000000f9 } },
- { AR5K_RF_GAIN(41), { 0x000000f9 } },
- { AR5K_RF_GAIN(42), { 0x000000f9 } },
- { AR5K_RF_GAIN(43), { 0x000000f9 } },
- { AR5K_RF_GAIN(44), { 0x000000f9 } },
- { AR5K_RF_GAIN(45), { 0x000000f9 } },
- { AR5K_RF_GAIN(46), { 0x000000f9 } },
- { AR5K_RF_GAIN(47), { 0x000000f9 } },
- { AR5K_RF_GAIN(48), { 0x000000f9 } },
- { AR5K_RF_GAIN(49), { 0x000000f9 } },
- { AR5K_RF_GAIN(50), { 0x000000f9 } },
- { AR5K_RF_GAIN(51), { 0x000000f9 } },
- { AR5K_RF_GAIN(52), { 0x000000f9 } },
- { AR5K_RF_GAIN(53), { 0x000000f9 } },
- { AR5K_RF_GAIN(54), { 0x000000f9 } },
- { AR5K_RF_GAIN(55), { 0x000000f9 } },
- { AR5K_RF_GAIN(56), { 0x000000f9 } },
- { AR5K_RF_GAIN(57), { 0x000000f9 } },
- { AR5K_RF_GAIN(58), { 0x000000f9 } },
- { AR5K_RF_GAIN(59), { 0x000000f9 } },
- { AR5K_RF_GAIN(60), { 0x000000f9 } },
- { AR5K_RF_GAIN(61), { 0x000000f9 } },
- { AR5K_RF_GAIN(62), { 0x000000f9 } },
- { AR5K_RF_GAIN(63), { 0x000000f9 } },
-};
-
-static const struct ath5k_gain_opt rfgain_opt_5112 = {
- 1,
- 8,
- {
- { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
- { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
- { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
- { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
- { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
- { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
- { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
- { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
- }
-};
+#include "rfbuffer.h"
+#include "rfgain.h"
/*
* Used to modify RF Banks before writing them to AR5K_RF_BUFFER
*/
-static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
- u32 first, u32 col, bool set)
+static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
+ const struct ath5k_rf_reg *rf_regs,
+ u32 val, u8 reg_id, bool set)
{
- u32 mask, entry, last, data, shift, position;
- s32 left;
+ const struct ath5k_rf_reg *rfreg = NULL;
+ u8 offset, bank, num_bits, col, position;
+ u16 entry;
+ u32 mask, data, last_bit, bits_shifted, first_bit;
+ u32 *rfb;
+ s32 bits_left;
int i;
data = 0;
+ rfb = ah->ah_rf_banks;
- if (rf == NULL)
+ for (i = 0; i < ah->ah_rf_regs_count; i++) {
+ if (rf_regs[i].index == reg_id) {
+ rfreg = &rf_regs[i];
+ break;
+ }
+ }
+
+ if (rfb == NULL || rfreg == NULL) {
+ ATH5K_PRINTF("Rf register not found!\n");
/* should not happen */
return 0;
+ }
+
+ bank = rfreg->bank;
+ num_bits = rfreg->field.len;
+ first_bit = rfreg->field.pos;
+ col = rfreg->field.col;
+
+ /* first_bit is an offset from bank's
+ * start. Since we have all banks on
+ * the same array, we use this offset
+ * to mark each bank's start */
+ offset = ah->ah_offset[bank];
- if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
+ /* Boundary check */
+ if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
ATH5K_PRINTF("invalid values at offset %u\n", offset);
return 0;
}
- entry = ((first - 1) / 8) + offset;
- position = (first - 1) % 8;
+ entry = ((first_bit - 1) / 8) + offset;
+ position = (first_bit - 1) % 8;
if (set)
- data = ath5k_hw_bitswap(reg, bits);
+ data = ath5k_hw_bitswap(val, num_bits);
+
+ for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
+ position = 0, entry++) {
+
+ last_bit = (position + bits_left > 8) ? 8 :
+ position + bits_left;
- for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
- last = (position + left > 8) ? 8 : position + left;
- mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
+ mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
+ (col * 8);
if (set) {
- rf[entry] &= ~mask;
- rf[entry] |= ((data << position) << (col * 8)) & mask;
+ rfb[entry] &= ~mask;
+ rfb[entry] |= ((data << position) << (col * 8)) & mask;
data >>= (8 - position);
} else {
- data = (((rf[entry] & mask) >> (col * 8)) >> position)
- << shift;
- shift += last - position;
+ data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
+ << bits_shifted;
+ bits_shifted += last_bit - position;
}
- left -= 8 - position;
+ bits_left -= 8 - position;
}
- data = set ? 1 : ath5k_hw_bitswap(data, bits);
+ data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
return data;
}
-static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
+/**********************\
+* RF Gain optimization *
+\**********************/
+
+/*
+ * This code is used to optimize rf gain on different environments
+ * (temprature mostly) based on feedback from a power detector.
+ *
+ * It's only used on RF5111 and RF5112, later RF chips seem to have
+ * auto adjustment on hw -notice they have a much smaller BANK 7 and
+ * no gain optimization ladder-.
+ *
+ * For more infos check out this patent doc
+ * http://www.freepatentsonline.com/7400691.html
+ *
+ * This paper describes power drops as seen on the receiver due to
+ * probe packets
+ * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
+ * %20of%20Power%20Control.pdf
+ *
+ * And this is the MadWiFi bug entry related to the above
+ * http://madwifi-project.org/ticket/1659
+ * with various measurements and diagrams
+ *
+ * TODO: Deal with power drops due to probes by setting an apropriate
+ * tx power on the probe packets ! Make this part of the calibration process.
+ */
+
+/* Initialize ah_gain durring attach */
+int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
+{
+ /* Initialize the gain optimization values */
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
+ ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
+ ah->ah_gain.g_low = 20;
+ ah->ah_gain.g_high = 35;
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+ break;
+ case AR5K_RF5112:
+ ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
+ ah->ah_gain.g_low = 20;
+ ah->ah_gain.g_high = 85;
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Schedule a gain probe check on the next transmited packet.
+ * That means our next packet is going to be sent with lower
+ * tx power and a Peak to Average Power Detector (PAPD) will try
+ * to measure the gain.
+ *
+ * TODO: Use propper tx power setting for the probe packet so
+ * that we don't observe a serious power drop on the receiver
+ *
+ * XXX: How about forcing a tx packet (bypassing PCU arbitrator etc)
+ * just after we enable the probe so that we don't mess with
+ * standard traffic ? Maybe it's time to use sw interrupts and
+ * a probe tasklet !!!
+ */
+static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
+{
+
+ /* Skip if gain calibration is inactive or
+ * we already handle a probe request */
+ if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
+ return;
+
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
+ AR5K_PHY_PAPD_PROBE_TXPOWER) |
+ AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
+
+ ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
+
+}
+
+/* Calculate gain_F measurement correction
+ * based on the current step for RF5112 rev. 2 */
+static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
{
u32 mix, step;
u32 *rf;
+ const struct ath5k_gain_opt *go;
+ const struct ath5k_gain_opt_step *g_step;
+ const struct ath5k_rf_reg *rf_regs;
+
+ /* Only RF5112 Rev. 2 supports it */
+ if ((ah->ah_radio != AR5K_RF5112) ||
+ (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
+ return 0;
+
+ go = &rfgain_opt_5112;
+ rf_regs = rf_regs_5112a;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+
+ g_step = &go->go_step[ah->ah_gain.g_step_idx];
if (ah->ah_rf_banks == NULL)
return 0;
@@ -1165,11 +218,15 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
rf = ah->ah_rf_banks;
ah->ah_gain.g_f_corr = 0;
- if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1)
+ /* No VGA (Variable Gain Amplifier) override, skip */
+ if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
return 0;
- step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false);
- mix = ah->ah_gain.g_step->gos_param[0];
+ /* Mix gain stepping */
+ step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
+
+ /* Mix gain override */
+ mix = g_step->gos_param[0];
switch (mix) {
case 3:
@@ -1189,9 +246,14 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
return ah->ah_gain.g_f_corr;
}
-static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
+/* Check if current gain_F measurement is in the range of our
+ * power detector windows. If we get a measurement outside range
+ * we know it's not accurate (detectors can't measure anything outside
+ * their detection window) so we must ignore it */
+static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
{
- u32 step, mix, level[4];
+ const struct ath5k_rf_reg *rf_regs;
+ u32 step, mix_ovr, level[4];
u32 *rf;
if (ah->ah_rf_banks == NULL)
@@ -1200,23 +262,33 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
rf = ah->ah_rf_banks;
if (ah->ah_radio == AR5K_RF5111) {
- step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0,
- false);
+
+ rf_regs = rf_regs_5111;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+
+ step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
+ false);
+
level[0] = 0;
- level[1] = (step == 0x3f) ? 0x32 : step + 4;
- level[2] = (step != 0x3f) ? 0x40 : level[0];
- level[3] = level[2] + 0x32;
+ level[1] = (step == 63) ? 50 : step + 4;
+ level[2] = (step != 63) ? 64 : level[0];
+ level[3] = level[2] + 50 ;
ah->ah_gain.g_high = level[3] -
- (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
+ (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
ah->ah_gain.g_low = level[0] +
- (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
+ (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
} else {
- mix = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0,
- false);
+
+ rf_regs = rf_regs_5112;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+
+ mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
+ false);
+
level[0] = level[2] = 0;
- if (mix == 1) {
+ if (mix_ovr == 1) {
level[1] = level[3] = 83;
} else {
level[1] = level[3] = 107;
@@ -1230,9 +302,12 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
ah->ah_gain.g_current <= level[3]);
}
-static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
+/* Perform gain_F adjustment by choosing the right set
+ * of parameters from rf gain optimization ladder */
+static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
{
const struct ath5k_gain_opt *go;
+ const struct ath5k_gain_opt_step *g_step;
int ret = 0;
switch (ah->ah_radio) {
@@ -1246,35 +321,39 @@ static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
return 0;
}
- ah->ah_gain.g_step = &go->go_step[ah->ah_gain.g_step_idx];
+ g_step = &go->go_step[ah->ah_gain.g_step_idx];
if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
+
+ /* Reached maximum */
if (ah->ah_gain.g_step_idx == 0)
return -1;
+
for (ah->ah_gain.g_target = ah->ah_gain.g_current;
ah->ah_gain.g_target >= ah->ah_gain.g_high &&
ah->ah_gain.g_step_idx > 0;
- ah->ah_gain.g_step =
- &go->go_step[ah->ah_gain.g_step_idx])
+ g_step = &go->go_step[ah->ah_gain.g_step_idx])
ah->ah_gain.g_target -= 2 *
(go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
- ah->ah_gain.g_step->gos_gain);
+ g_step->gos_gain);
ret = 1;
goto done;
}
if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
+
+ /* Reached minimum */
if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
return -2;
+
for (ah->ah_gain.g_target = ah->ah_gain.g_current;
ah->ah_gain.g_target <= ah->ah_gain.g_low &&
ah->ah_gain.g_step_idx < go->go_steps_count-1;
- ah->ah_gain.g_step =
- &go->go_step[ah->ah_gain.g_step_idx])
+ g_step = &go->go_step[ah->ah_gain.g_step_idx])
ah->ah_gain.g_target -= 2 *
(go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
- ah->ah_gain.g_step->gos_gain);
+ g_step->gos_gain);
ret = 2;
goto done;
@@ -1289,468 +368,449 @@ done:
return ret;
}
-/*
- * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111
- */
-static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, unsigned int mode)
+/* Main callback for thermal rf gain calibration engine
+ * Check for a new gain reading and schedule an adjustment
+ * if needed.
+ *
+ * TODO: Use sw interrupt to schedule reset if gain_F needs
+ * adjustment */
+enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
{
+ u32 data, type;
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- u32 *rf;
- const unsigned int rf_size = ARRAY_SIZE(rfregs_5111);
- unsigned int i;
- int obdb = -1, bank = -1;
- u32 ee_mode;
-
- AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
-
- rf = ah->ah_rf_banks;
- /* Copy values to modify them */
- for (i = 0; i < rf_size; i++) {
- if (rfregs_5111[i].rf_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) {
- ATH5K_ERR(ah->ah_sc, "invalid bank\n");
- return -EINVAL;
- }
-
- if (bank != rfregs_5111[i].rf_bank) {
- bank = rfregs_5111[i].rf_bank;
- ah->ah_offset[bank] = i;
- }
+ ATH5K_TRACE(ah->ah_sc);
- rf[i] = rfregs_5111[i].rf_value[mode];
- }
+ if (ah->ah_rf_banks == NULL ||
+ ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
+ return AR5K_RFGAIN_INACTIVE;
- /* Modify bank 0 */
- if (channel->hw_value & CHANNEL_2GHZ) {
- if (channel->hw_value & CHANNEL_CCK)
- ee_mode = AR5K_EEPROM_MODE_11B;
- else
- ee_mode = AR5K_EEPROM_MODE_11G;
- obdb = 0;
+ /* No check requested, either engine is inactive
+ * or an adjustment is already requested */
+ if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
+ goto done;
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
- ee->ee_ob[ee_mode][obdb], 3, 119, 0, true))
- return -EINVAL;
+ /* Read the PAPD (Peak to Average Power Detector)
+ * register */
+ data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
- ee->ee_ob[ee_mode][obdb], 3, 122, 0, true))
- return -EINVAL;
+ /* No probe is scheduled, read gain_F measurement */
+ if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
+ ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
+ type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
- obdb = 1;
- /* Modify bank 6 */
- } else {
- /* For 11a, Turbo and XR */
- ee_mode = AR5K_EEPROM_MODE_11A;
- obdb = channel->center_freq >= 5725 ? 3 :
- (channel->center_freq >= 5500 ? 2 :
- (channel->center_freq >= 5260 ? 1 :
- (channel->center_freq > 4000 ? 0 : -1)));
+ /* If tx packet is CCK correct the gain_F measurement
+ * by cck ofdm gain delta */
+ if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
+ if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
+ ah->ah_gain.g_current +=
+ ee->ee_cck_ofdm_gain_delta;
+ else
+ ah->ah_gain.g_current +=
+ AR5K_GAIN_CCK_PROBE_CORR;
+ }
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_pwd_84, 1, 51, 3, true))
- return -EINVAL;
+ /* Further correct gain_F measurement for
+ * RF5112A radios */
+ if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+ ath5k_hw_rf_gainf_corr(ah);
+ ah->ah_gain.g_current =
+ ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
+ (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
+ 0;
+ }
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_pwd_90, 1, 45, 3, true))
- return -EINVAL;
+ /* Check if measurement is ok and if we need
+ * to adjust gain, schedule a gain adjustment,
+ * else switch back to the acive state */
+ if (ath5k_hw_rf_check_gainf_readback(ah) &&
+ AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
+ ath5k_hw_rf_gainf_adjust(ah)) {
+ ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
+ } else {
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+ }
}
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- !ee->ee_xpd[ee_mode], 1, 95, 0, true))
- return -EINVAL;
-
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_x_gain[ee_mode], 4, 96, 0, true))
- return -EINVAL;
-
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
- ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true))
- return -EINVAL;
+done:
+ return ah->ah_gain.g_state;
+}
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
- ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true))
- return -EINVAL;
+/* Write initial rf gain table to set the RF sensitivity
+ * this one works on all RF chips and has nothing to do
+ * with gain_F calibration */
+int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
+{
+ const struct ath5k_ini_rfgain *ath5k_rfg;
+ unsigned int i, size;
- /* Modify bank 7 */
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
- ee->ee_i_gain[ee_mode], 6, 29, 0, true))
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
+ ath5k_rfg = rfgain_5111;
+ size = ARRAY_SIZE(rfgain_5111);
+ break;
+ case AR5K_RF5112:
+ ath5k_rfg = rfgain_5112;
+ size = ARRAY_SIZE(rfgain_5112);
+ break;
+ case AR5K_RF2413:
+ ath5k_rfg = rfgain_2413;
+ size = ARRAY_SIZE(rfgain_2413);
+ break;
+ case AR5K_RF2316:
+ ath5k_rfg = rfgain_2316;
+ size = ARRAY_SIZE(rfgain_2316);
+ break;
+ case AR5K_RF5413:
+ ath5k_rfg = rfgain_5413;
+ size = ARRAY_SIZE(rfgain_5413);
+ break;
+ case AR5K_RF2317:
+ case AR5K_RF2425:
+ ath5k_rfg = rfgain_2425;
+ size = ARRAY_SIZE(rfgain_2425);
+ break;
+ default:
return -EINVAL;
+ }
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
- ee->ee_xpd[ee_mode], 1, 4, 0, true))
+ switch (freq) {
+ case AR5K_INI_RFGAIN_2GHZ:
+ case AR5K_INI_RFGAIN_5GHZ:
+ break;
+ default:
return -EINVAL;
+ }
- /* Write RF values */
- for (i = 0; i < rf_size; i++) {
+ for (i = 0; i < size; i++) {
AR5K_REG_WAIT(i);
- ath5k_hw_reg_write(ah, rf[i], rfregs_5111[i].rf_register);
+ ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
+ (u32)ath5k_rfg[i].rfg_register);
}
return 0;
}
+
+
+/********************\
+* RF Registers setup *
+\********************/
+
+
/*
- * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112
+ * Setup RF registers by writing rf buffer on hw
*/
-static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, unsigned int mode)
+int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ unsigned int mode)
{
- const struct ath5k_ini_rf *rf_ini;
+ const struct ath5k_rf_reg *rf_regs;
+ const struct ath5k_ini_rfbuffer *ini_rfb;
+ const struct ath5k_gain_opt *go = NULL;
+ const struct ath5k_gain_opt_step *g_step;
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- u32 *rf;
- unsigned int rf_size, i;
- int obdb = -1, bank = -1;
- u32 ee_mode;
-
- AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
+ u8 ee_mode = 0;
+ u32 *rfb;
+ int i, obdb = -1, bank = -1;
- rf = ah->ah_rf_banks;
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
+ rf_regs = rf_regs_5111;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+ ini_rfb = rfb_5111;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
+ go = &rfgain_opt_5111;
+ break;
+ case AR5K_RF5112:
+ if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+ rf_regs = rf_regs_5112a;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+ ini_rfb = rfb_5112a;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
+ } else {
+ rf_regs = rf_regs_5112;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+ ini_rfb = rfb_5112;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
+ }
+ go = &rfgain_opt_5112;
+ break;
+ case AR5K_RF2413:
+ rf_regs = rf_regs_2413;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
+ ini_rfb = rfb_2413;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
+ break;
+ case AR5K_RF2316:
+ rf_regs = rf_regs_2316;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
+ ini_rfb = rfb_2316;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
+ break;
+ case AR5K_RF5413:
+ rf_regs = rf_regs_5413;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
+ ini_rfb = rfb_5413;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
+ break;
+ case AR5K_RF2317:
+ rf_regs = rf_regs_2425;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+ ini_rfb = rfb_2317;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
+ break;
+ case AR5K_RF2425:
+ rf_regs = rf_regs_2425;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+ if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
+ ini_rfb = rfb_2425;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
+ } else {
+ ini_rfb = rfb_2417;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
- if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A
- && !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) {
- rf_ini = rfregs_2112a;
- rf_size = ARRAY_SIZE(rfregs_5112a);
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc, "invalid channel mode: %i\n",
- mode);
- return -EINVAL;
+ /* If it's the first time we set rf buffer, allocate
+ * ah->ah_rf_banks based on ah->ah_rf_banks_size
+ * we set above */
+ if (ah->ah_rf_banks == NULL) {
+ ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
+ GFP_KERNEL);
+ if (ah->ah_rf_banks == NULL) {
+ ATH5K_ERR(ah->ah_sc, "out of memory\n");
+ return -ENOMEM;
}
- mode = mode - 2; /*no a/turboa modes for 2112*/
- } else if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
- rf_ini = rfregs_5112a;
- rf_size = ARRAY_SIZE(rfregs_5112a);
- } else {
- rf_ini = rfregs_5112;
- rf_size = ARRAY_SIZE(rfregs_5112);
}
/* Copy values to modify them */
- for (i = 0; i < rf_size; i++) {
- if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
+ rfb = ah->ah_rf_banks;
+
+ for (i = 0; i < ah->ah_rf_banks_size; i++) {
+ if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
ATH5K_ERR(ah->ah_sc, "invalid bank\n");
return -EINVAL;
}
- if (bank != rf_ini[i].rf_bank) {
- bank = rf_ini[i].rf_bank;
+ /* Bank changed, write down the offset */
+ if (bank != ini_rfb[i].rfb_bank) {
+ bank = ini_rfb[i].rfb_bank;
ah->ah_offset[bank] = i;
}
- rf[i] = rf_ini[i].rf_value[mode];
+ rfb[i] = ini_rfb[i].rfb_mode_data[mode];
}
- /* Modify bank 6 */
+ /* Set Output and Driver bias current (OB/DB) */
if (channel->hw_value & CHANNEL_2GHZ) {
- if (channel->hw_value & CHANNEL_OFDM)
+
+ if (channel->hw_value & CHANNEL_CCK)
+ ee_mode = AR5K_EEPROM_MODE_11B;
+ else
ee_mode = AR5K_EEPROM_MODE_11G;
+
+ /* For RF511X/RF211X combination we
+ * use b_OB and b_DB parameters stored
+ * in eeprom on ee->ee_ob[ee_mode][0]
+ *
+ * For all other chips we use OB/DB for 2Ghz
+ * stored in the b/g modal section just like
+ * 802.11a on ee->ee_ob[ee_mode][1] */
+ if ((ah->ah_radio == AR5K_RF5111) ||
+ (ah->ah_radio == AR5K_RF5112))
+ obdb = 0;
else
- ee_mode = AR5K_EEPROM_MODE_11B;
- obdb = 0;
+ obdb = 1;
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 287, 0, true))
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+ AR5K_RF_OB_2GHZ, true);
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 290, 0, true))
- return -EINVAL;
- } else {
- /* For 11a, Turbo and XR */
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+ AR5K_RF_DB_2GHZ, true);
+
+ /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
+ } else if ((channel->hw_value & CHANNEL_5GHZ) ||
+ (ah->ah_radio == AR5K_RF5111)) {
+
+ /* For 11a, Turbo and XR we need to choose
+ * OB/DB based on frequency range */
ee_mode = AR5K_EEPROM_MODE_11A;
- obdb = channel->center_freq >= 5725 ? 3 :
- (channel->center_freq >= 5500 ? 2 :
+ obdb = channel->center_freq >= 5725 ? 3 :
+ (channel->center_freq >= 5500 ? 2 :
(channel->center_freq >= 5260 ? 1 :
- (channel->center_freq > 4000 ? 0 : -1)));
+ (channel->center_freq > 4000 ? 0 : -1)));
- if (obdb == -1)
+ if (obdb < 0)
return -EINVAL;
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 279, 0, true))
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+ AR5K_RF_OB_5GHZ, true);
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 282, 0, true))
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+ AR5K_RF_DB_5GHZ, true);
}
- ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_x_gain[ee_mode], 2, 270, 0, true);
- ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_x_gain[ee_mode], 2, 257, 0, true);
+ g_step = &go->go_step[ah->ah_gain.g_step_idx];
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_xpd[ee_mode], 1, 302, 0, true))
- return -EINVAL;
+ /* Bank Modifications (chip-specific) */
+ if (ah->ah_radio == AR5K_RF5111) {
- /* Modify bank 7 */
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
- ee->ee_i_gain[ee_mode], 6, 14, 0, true))
- return -EINVAL;
+ /* Set gain_F settings according to current step */
+ if (channel->hw_value & CHANNEL_OFDM) {
- /* Write RF values */
- for (i = 0; i < rf_size; i++)
- ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
+ AR5K_PHY_FRAME_CTL_TX_CLIP,
+ g_step->gos_param[0]);
- return 0;
-}
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+ AR5K_RF_PWD_90, true);
-/*
- * Initialize RF5413/5414 and future chips
- * (until we come up with a better solution)
- */
-static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, unsigned int mode)
-{
- const struct ath5k_ini_rf *rf_ini;
- u32 *rf;
- unsigned int rf_size, i;
- int bank = -1;
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+ AR5K_RF_PWD_84, true);
- AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
-
- rf = ah->ah_rf_banks;
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+ AR5K_RF_RFGAIN_SEL, true);
- switch (ah->ah_radio) {
- case AR5K_RF5413:
- rf_ini = rfregs_5413;
- rf_size = ARRAY_SIZE(rfregs_5413);
- break;
- case AR5K_RF2413:
- rf_ini = rfregs_2413;
- rf_size = ARRAY_SIZE(rfregs_2413);
+ /* We programmed gain_F parameters, switch back
+ * to active state */
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc,
- "invalid channel mode: %i\n", mode);
- return -EINVAL;
}
- mode = mode - 2;
- break;
- case AR5K_RF2425:
- rf_ini = rfregs_2425;
- rf_size = ARRAY_SIZE(rfregs_2425);
+ /* Bank 6/7 setup */
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc,
- "invalid channel mode: %i\n", mode);
- return -EINVAL;
- }
+ ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
+ AR5K_RF_PWD_XPD, true);
- /* Map b to g */
- if (mode == 2)
- mode = 0;
- else
- mode = mode - 3;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
+ AR5K_RF_XPD_GAIN, true);
- break;
- default:
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+ AR5K_RF_GAIN_I, true);
+
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+ AR5K_RF_PLO_SEL, true);
+
+ /* TODO: Half/quarter channel support */
}
- /* Copy values to modify them */
- for (i = 0; i < rf_size; i++) {
- if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
- ATH5K_ERR(ah->ah_sc, "invalid bank\n");
- return -EINVAL;
- }
+ if (ah->ah_radio == AR5K_RF5112) {
- if (bank != rf_ini[i].rf_bank) {
- bank = rf_ini[i].rf_bank;
- ah->ah_offset[bank] = i;
- }
+ /* Set gain_F settings according to current step */
+ if (channel->hw_value & CHANNEL_OFDM) {
- rf[i] = rf_ini[i].rf_value[mode];
- }
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
+ AR5K_RF_MIXGAIN_OVR, true);
- /*
- * After compairing dumps from different cards
- * we get the same RF_BUFFER settings (diff returns
- * 0 lines). It seems that RF_BUFFER settings are static
- * and are written unmodified (no EEPROM stuff
- * is used because calibration data would be
- * different between different cards and would result
- * different RF_BUFFER settings)
- */
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+ AR5K_RF_PWD_138, true);
- /* Write RF values */
- for (i = 0; i < rf_size; i++)
- ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+ AR5K_RF_PWD_137, true);
- return 0;
-}
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+ AR5K_RF_PWD_136, true);
-/*
- * Initialize RF
- */
-int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- unsigned int mode)
-{
- int (*func)(struct ath5k_hw *, struct ieee80211_channel *, unsigned int);
- int ret;
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
+ AR5K_RF_PWD_132, true);
- switch (ah->ah_radio) {
- case AR5K_RF5111:
- ah->ah_rf_banks_size = sizeof(rfregs_5111);
- func = ath5k_hw_rf5111_rfregs;
- break;
- case AR5K_RF5112:
- if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
- ah->ah_rf_banks_size = sizeof(rfregs_5112a);
- else
- ah->ah_rf_banks_size = sizeof(rfregs_5112);
- func = ath5k_hw_rf5112_rfregs;
- break;
- case AR5K_RF5413:
- ah->ah_rf_banks_size = sizeof(rfregs_5413);
- func = ath5k_hw_rf5413_rfregs;
- break;
- case AR5K_RF2413:
- ah->ah_rf_banks_size = sizeof(rfregs_2413);
- func = ath5k_hw_rf5413_rfregs;
- break;
- case AR5K_RF2425:
- ah->ah_rf_banks_size = sizeof(rfregs_2425);
- func = ath5k_hw_rf5413_rfregs;
- break;
- default:
- return -EINVAL;
- }
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
+ AR5K_RF_PWD_131, true);
- if (ah->ah_rf_banks == NULL) {
- /* XXX do extra checks? */
- ah->ah_rf_banks = kmalloc(ah->ah_rf_banks_size, GFP_KERNEL);
- if (ah->ah_rf_banks == NULL) {
- ATH5K_ERR(ah->ah_sc, "out of memory\n");
- return -ENOMEM;
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
+ AR5K_RF_PWD_130, true);
+
+ /* We programmed gain_F parameters, switch back
+ * to active state */
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
}
- }
- ret = func(ah, channel, mode);
- if (!ret)
- ah->ah_rf_gain = AR5K_RFGAIN_INACTIVE;
+ /* Bank 6/7 setup */
- return ret;
-}
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+ AR5K_RF_XPD_SEL, true);
-int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
-{
- const struct ath5k_ini_rfgain *ath5k_rfg;
- unsigned int i, size;
+ if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
+ /* Rev. 1 supports only one xpd */
+ ath5k_hw_rfb_op(ah, rf_regs,
+ ee->ee_x_gain[ee_mode],
+ AR5K_RF_XPD_GAIN, true);
- switch (ah->ah_radio) {
- case AR5K_RF5111:
- ath5k_rfg = rfgain_5111;
- size = ARRAY_SIZE(rfgain_5111);
- break;
- case AR5K_RF5112:
- ath5k_rfg = rfgain_5112;
- size = ARRAY_SIZE(rfgain_5112);
- break;
- case AR5K_RF5413:
- ath5k_rfg = rfgain_5413;
- size = ARRAY_SIZE(rfgain_5413);
- break;
- case AR5K_RF2413:
- ath5k_rfg = rfgain_2413;
- size = ARRAY_SIZE(rfgain_2413);
- freq = 0; /* only 2Ghz */
- break;
- case AR5K_RF2425:
- ath5k_rfg = rfgain_2425;
- size = ARRAY_SIZE(rfgain_2425);
- freq = 0; /* only 2Ghz */
- break;
- default:
- return -EINVAL;
- }
+ } else {
+ /* TODO: Set high and low gain bits */
+ ath5k_hw_rfb_op(ah, rf_regs,
+ ee->ee_x_gain[ee_mode],
+ AR5K_RF_PD_GAIN_LO, true);
+ ath5k_hw_rfb_op(ah, rf_regs,
+ ee->ee_x_gain[ee_mode],
+ AR5K_RF_PD_GAIN_HI, true);
- switch (freq) {
- case AR5K_INI_RFGAIN_2GHZ:
- case AR5K_INI_RFGAIN_5GHZ:
- break;
- default:
- return -EINVAL;
- }
+ /* Lower synth voltage on Rev 2 */
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_HIGH_VC_CP, true);
- for (i = 0; i < size; i++) {
- AR5K_REG_WAIT(i);
- ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
- (u32)ath5k_rfg[i].rfg_register);
- }
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_MID_VC_CP, true);
- return 0;
-}
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_LOW_VC_CP, true);
-enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah)
-{
- u32 data, type;
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_PUSH_UP, true);
- ATH5K_TRACE(ah->ah_sc);
+ /* Decrease power consumption on 5213+ BaseBand */
+ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_PAD2GND, true);
- if (ah->ah_rf_banks == NULL || !ah->ah_gain.g_active ||
- ah->ah_version <= AR5K_AR5211)
- return AR5K_RFGAIN_INACTIVE;
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_XB2_LVL, true);
- if (ah->ah_rf_gain != AR5K_RFGAIN_READ_REQUESTED)
- goto done;
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_XB5_LVL, true);
- data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_PWD_167, true);
- if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
- ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
- type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_PWD_166, true);
+ }
+ }
- if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK)
- ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+ AR5K_RF_GAIN_I, true);
- if (ah->ah_radio >= AR5K_RF5112) {
- ath5k_hw_rfregs_gainf_corr(ah);
- ah->ah_gain.g_current =
- ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
- (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
- 0;
- }
+ /* TODO: Half/quarter channel support */
- if (ath5k_hw_rfregs_gain_readback(ah) &&
- AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
- ath5k_hw_rfregs_gain_adjust(ah))
- ah->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE;
}
-done:
- return ah->ah_rf_gain;
-}
+ if (ah->ah_radio == AR5K_RF5413 &&
+ channel->hw_value & CHANNEL_2GHZ) {
+
+ ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
+ true);
+
+ /* Set optimum value for early revisions (on pci-e chips) */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
+ ah->ah_mac_srev < AR5K_SREV_AR5413)
+ ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
+ AR5K_RF_PWD_ICLOBUF_2G, true);
-int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah)
-{
- /* Initialize the gain optimization values */
- switch (ah->ah_radio) {
- case AR5K_RF5111:
- ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
- ah->ah_gain.g_step =
- &rfgain_opt_5111.go_step[ah->ah_gain.g_step_idx];
- ah->ah_gain.g_low = 20;
- ah->ah_gain.g_high = 35;
- ah->ah_gain.g_active = 1;
- break;
- case AR5K_RF5112:
- ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
- ah->ah_gain.g_step =
- &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
- ah->ah_gain.g_low = 20;
- ah->ah_gain.g_high = 85;
- ah->ah_gain.g_active = 1;
- break;
- default:
- return -EINVAL;
+ }
+
+ /* Write RF banks on hw */
+ for (i = 0; i < ah->ah_rf_banks_size; i++) {
+ AR5K_REG_WAIT(i);
+ ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
}
return 0;
}
+
/**************************\
PHY/RF channel functions
\**************************/
@@ -2271,13 +1331,8 @@ done:
* as often as I/Q calibration.*/
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
- /* Request RF gain */
- if (channel->hw_value & CHANNEL_5GHZ) {
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
- AR5K_PHY_PAPD_PROBE_TXPOWER) |
- AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
- ah->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED;
- }
+ /* Initiate a gain_F calibration */
+ ath5k_hw_request_rfgain_probe(ah);
return 0;
}
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c
index 1b7bc50ea8e..5094c394a4b 100644
--- a/drivers/net/wireless/ath5k/qcu.c
+++ b/drivers/net/wireless/ath5k/qcu.c
@@ -148,6 +148,7 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
*/
u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
{
+ u32 pending;
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
@@ -159,7 +160,15 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
if (ah->ah_version == AR5K_AR5210)
return false;
- return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
+ pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT);
+
+ /* It's possible to have no frames pending even if TXE
+ * is set. To indicate that q has not stopped return
+ * true */
+ if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+ return true;
+
+ return pending;
}
/*
@@ -324,8 +333,18 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
/*
* Set misc registers
*/
- ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
- AR5K_QUEUE_MISC(queue));
+ /* Enable DCU early termination for this queue */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_DCU_EARLY);
+
+ /* Enable DCU to wait for next fragment from QCU */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ AR5K_DCU_MISC_FRAG_WAIT);
+
+ /* On Maui and Spirit use the global seqnum on DCU */
+ if (ah->ah_mac_version < AR5K_SREV_AR5211)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ AR5K_DCU_MISC_SEQNUM_CTL);
if (tq->tqi_cbr_period) {
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
@@ -341,7 +360,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_QCU_MISC_CBR_THRES_ENABLE);
}
- if (tq->tqi_ready_time)
+ if (tq->tqi_ready_time &&
+ (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
AR5K_QCU_RDYTIMECFG_INTVAL) |
AR5K_QCU_RDYTIMECFG_ENABLE,
@@ -383,13 +403,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_DCU_MISC_ARBLOCK_CTL_S) |
AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
AR5K_DCU_MISC_BCN_ENABLE);
-
- ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
- (AR5K_TUNE_SW_BEACON_RESP -
- AR5K_TUNE_DMA_BEACON_RESP) -
- AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
- AR5K_QCU_RDYTIMECFG_ENABLE,
- AR5K_QUEUE_RDYTIMECFG(queue));
break;
case AR5K_TX_QUEUE_CAB:
@@ -398,6 +411,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_QCU_MISC_CBREXP_DIS |
AR5K_QCU_MISC_CBREXP_BCN_DIS);
+ ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
+ (AR5K_TUNE_SW_BEACON_RESP -
+ AR5K_TUNE_DMA_BEACON_RESP) -
+ AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
+ AR5K_QCU_RDYTIMECFG_ENABLE,
+ AR5K_QUEUE_RDYTIMECFG(queue));
+
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
AR5K_DCU_MISC_ARBLOCK_CTL_S));
@@ -413,6 +433,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
break;
}
+ /* TODO: Handle frame compression */
+
/*
* Enable interrupts for this tx queue
* in the secondary interrupt mask registers
@@ -483,6 +505,9 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
* by setting AR5K_TXNOFRM to zero */
if (ah->ah_txq_imr_nofrm == 0)
ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
+
+ /* Set QCU mask for this DCU to save power */
+ AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
}
return 0;
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 9189ab13286..2dc008e1022 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -187,6 +187,7 @@
#define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */
#define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */
#define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */
+#define AR5K_TXCFG_DCU_DBL_BUF_DIS 0x00008000 /* Disable double buffering on DCU */
#define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */
/*
@@ -753,7 +754,7 @@
*/
#define AR5K_DCU_SEQNUM_BASE 0x1140
#define AR5K_DCU_SEQNUM_M 0x00000fff
-#define AR5K_QUEUE_DFS_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
+#define AR5K_QUEUE_DCU_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
/*
* DCU global IFS SIFS register
@@ -811,6 +812,8 @@
/*
* DCU transmit filter table 0 (32 entries)
+ * each entry contains a 32bit slice of the
+ * 128bit tx filter for each DCU (4 slices per DCU)
*/
#define AR5K_DCU_TX_FILTER_0_BASE 0x1038
#define AR5K_DCU_TX_FILTER_0(_n) (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
@@ -819,7 +822,7 @@
* DCU transmit filter table 1 (16 entries)
*/
#define AR5K_DCU_TX_FILTER_1_BASE 0x103c
-#define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + ((_n - 32) * 64))
+#define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
/*
* DCU clear transmit filter register
@@ -1447,7 +1450,7 @@
AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
/*
- * Last beacon timestamp register
+ * Last beacon timestamp register (Read Only)
*/
#define AR5K_LAST_TSTP 0x8080
@@ -1465,7 +1468,7 @@
#define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */
#define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */
#define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */
-#define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* Test ARM (Adaptive Radio Mode ?) */
+#define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* ARM rx buffer for capture */
/*
* Default antenna register [5211+]
@@ -1677,7 +1680,7 @@
* TSF parameter register
*/
#define AR5K_TSF_PARM 0x8104 /* Register Address */
-#define AR5K_TSF_PARM_INC_M 0x000000ff /* Mask for TSF increment */
+#define AR5K_TSF_PARM_INC 0x000000ff /* Mask for TSF increment */
#define AR5K_TSF_PARM_INC_S 0
/*
@@ -1689,7 +1692,7 @@
#define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */
#define AR5K_QOS_NOACK_BIT_OFFSET_S 4
#define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */
-#define AR5K_QOS_NOACK_BYTE_OFFSET_S 8
+#define AR5K_QOS_NOACK_BYTE_OFFSET_S 7
/*
* PHY error filter register
@@ -1848,15 +1851,14 @@
* TST_2 (Misc config parameters)
*/
#define AR5K_PHY_TST2 0x9800 /* Register Address */
-#define AR5K_PHY_TST2_TRIG_SEL 0x00000001 /* Trigger select (?) (field ?) */
-#define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) (field ?) */
-#define AR5K_PHY_TST2_CBUS_MODE 0x00000100 /* Cardbus mode (?) */
-/* bit reserved */
+#define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/
+#define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */
+#define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */
#define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */
#define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */
#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */
#define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */
-#define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch) */
+#define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch ?) */
#define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */
#define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */
#define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */
@@ -1926,8 +1928,8 @@
#define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0
#define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */
-#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000000f /* TX end to XLNA on */
-#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 0
+#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000ff00 /* TX end to XLNA on */
+#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 8
#define AR5K_PHY_ADC_CTL 0x982c
#define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003
@@ -1961,7 +1963,7 @@
#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */
#define AR5K_PHY_SETTLING_AGC_S 0
#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */
-#define AR5K_PHY_SETTLINK_SWITCH_S 7
+#define AR5K_PHY_SETTLING_SWITCH_S 7
/*
* PHY Gain registers
@@ -2067,14 +2069,14 @@
* PHY sleep registers [5112+]
*/
#define AR5K_PHY_SCR 0x9870
-#define AR5K_PHY_SCR_32MHZ 0x0000001f
#define AR5K_PHY_SLMT 0x9874
#define AR5K_PHY_SLMT_32MHZ 0x0000007f
#define AR5K_PHY_SCAL 0x9878
#define AR5K_PHY_SCAL_32MHZ 0x0000000e
-
+#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a
+#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032
/*
* PHY PLL (Phase Locked Loop) control register
@@ -2101,34 +2103,10 @@
/*
* RF Buffer register
*
- * There are some special control registers on the RF chip
- * that hold various operation settings related mostly to
- * the analog parts (channel, gain adjustment etc).
- *
- * We don't write on those registers directly but
- * we send a data packet on the buffer register and
- * then write on another special register to notify hw
- * to apply the settings. This is done so that control registers
- * can be dynamicaly programmed during operation and the settings
- * are applied faster on the hw.
- *
- * We sent such data packets during rf initialization and channel change
- * through ath5k_hw_rf*_rfregs and ath5k_hw_rf*_channel functions.
- *
- * The data packets we send during initializadion are inside ath5k_ini_rf
- * struct (see ath5k_hw.h) and each one is related to an "rf register bank".
- * We use *rfregs functions to modify them acording to current operation
- * mode and eeprom values and pass them all together to the chip.
- *
* It's obvious from the code that 0x989c is the buffer register but
* for the other special registers that we write to after sending each
* packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
* for now. It's interesting that they are also used for some other operations.
- *
- * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
- * registers and control registers):
- *
- * http://www.google.com/patents?id=qNURAAAAEBAJ
*/
#define AR5K_RF_BUFFER 0x989c
@@ -2178,7 +2156,8 @@
#define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */
#define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */
#define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */
-#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x00000010 /* Switch table idle (?) */
+#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x000003f0 /* Switch table idle (?) */
+#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4
/*
* PHY receiver delay register [5111+]
@@ -2218,7 +2197,7 @@
#define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */
#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */
#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */
-#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 0
+#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 1
#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */
#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */
#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */
@@ -2243,9 +2222,7 @@
#define AR5K_PHY_CTL_LOW_FREQ_SLE_EN 0x00000080 /* Enable low freq sleep */
/*
- * PHY PAPD probe register [5111+ (?)]
- * Is this only present in 5212 ?
- * Because it's always 0 in 5211 initialization code
+ * PHY PAPD probe register [5111+]
*/
#define AR5K_PHY_PAPD_PROBE 0x9930
#define AR5K_PHY_PAPD_PROBE_SH_HI_PAR 0x00000001
@@ -2303,6 +2280,15 @@
AR5K_PHY_FRAME_CTL_TIMING_ERR
/*
+ * PHY Tx Power adjustment register [5212A+]
+ */
+#define AR5K_PHY_TX_PWR_ADJ 0x994c
+#define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA 0x00000fc0
+#define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S 6
+#define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX 0x00fc0000
+#define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S 18
+
+/*
* PHY radar detection register [5111+]
*/
#define AR5K_PHY_RADAR 0x9954
@@ -2355,7 +2341,7 @@
#define AR5K_PHY_SIGMA_DELTA_FILT2_S 3
#define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00
#define AR5K_PHY_SIGMA_DELTA_FILT1_S 8
-#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ff3000
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000
#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13
/*
@@ -2387,21 +2373,21 @@
#define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff
#define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0
-#define AR_PHY_TIMING_9 0x9998
-#define AR_PHY_TIMING_10 0x999c
-#define AR_PHY_TIMING_10_PILOT_MASK_2 0x000fffff
-#define AR_PHY_TIMING_10_PILOT_MASK_2_S 0
+#define AR5K_PHY_TIMING_9 0x9998
+#define AR5K_PHY_TIMING_10 0x999c
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2 0x000fffff
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S 0
/*
* Spur mitigation control
*/
-#define AR_PHY_TIMING_11 0x99a0 /* Register address */
-#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */
-#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0
-#define AR_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */
-#define AR_PHY_TIMING_11_SPUR_FREQ_SD_S 20
-#define AR_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */
-#define AR_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */
+#define AR5K_PHY_TIMING_11 0x99a0 /* Register address */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S 20
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */
/*
* Gain tables
@@ -2483,17 +2469,7 @@
#define AR5K_PHY_SDELAY 0x99f4
#define AR5K_PHY_SDELAY_32MHZ 0x000000ff
#define AR5K_PHY_SPENDING 0x99f8
-#define AR5K_PHY_SPENDING_14 0x00000014
-#define AR5K_PHY_SPENDING_18 0x00000018
-#define AR5K_PHY_SPENDING_RF5111 0x00000018
-#define AR5K_PHY_SPENDING_RF5112 0x00000014
-/* #define AR5K_PHY_SPENDING_RF5112A 0x0000000e */
-/* #define AR5K_PHY_SPENDING_RF5424 0x00000012 */
-#define AR5K_PHY_SPENDING_RF5413 0x00000018
-#define AR5K_PHY_SPENDING_RF2413 0x00000018
-#define AR5K_PHY_SPENDING_RF2316 0x00000018
-#define AR5K_PHY_SPENDING_RF2317 0x00000018
-#define AR5K_PHY_SPENDING_RF2425 0x00000014
+
/*
* PHY PAPD I (power?) table (?)
@@ -2505,11 +2481,7 @@
/*
* PHY PCDAC TX power table
*/
-#define AR5K_PHY_PCDAC_TXPOWER_BASE_5211 0xa180
-#define AR5K_PHY_PCDAC_TXPOWER_BASE_2413 0xa280
-#define AR5K_PHY_PCDAC_TXPOWER_BASE (ah->ah_radio >= AR5K_RF2413 ? \
- AR5K_PHY_PCDAC_TXPOWER_BASE_2413 :\
- AR5K_PHY_PCDAC_TXPOWER_BASE_5211)
+#define AR5K_PHY_PCDAC_TXPOWER_BASE 0xa180
#define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
/*
@@ -2590,3 +2562,9 @@
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22
+
+/*
+ * PHY PDADC Tx power table
+ */
+#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280
+#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
index dc2d7d8bdb7..685dc213eda 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -25,7 +25,8 @@
Reset functions and helpers
\*****************************/
-#include <linux/pci.h>
+#include <linux/pci.h> /* To determine if a card is pci-e */
+#include <linux/bitops.h> /* For get_bitmask_order */
#include "ath5k.h"
#include "reg.h"
#include "base.h"
@@ -37,10 +38,14 @@
* @ah: the &struct ath5k_hw
* @channel: the currently set channel upon reset
*
- * Write the OFDM timings for the AR5212 upon reset. This is a helper for
- * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
- * depending on the bandwidth of the channel.
+ * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
+ * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
*
+ * Since delta slope is floating point we split it on its exponent and
+ * mantissa and provide these values on hw.
+ *
+ * For more infos i think this patent is related
+ * http://www.freepatentsonline.com/7184495.html
*/
static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
struct ieee80211_channel *channel)
@@ -53,23 +58,34 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
!(channel->hw_value & CHANNEL_OFDM))
BUG();
- /* Seems there are two PLLs, one for baseband sampling and one
- * for tuning. Tuning basebands are 40 MHz or 80MHz when in
- * turbo. */
- clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
- coef_scaled = ((5 * (clock << 24)) / 2) /
- channel->center_freq;
+ /* Get coefficient
+ * ALGO: coef = (5 * clock * carrier_freq) / 2)
+ * we scale coef by shifting clock value by 24 for
+ * better precision since we use integers */
+ /* TODO: Half/quarter rate */
+ clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
- for (coef_exp = 31; coef_exp > 0; coef_exp--)
- if ((coef_scaled >> coef_exp) & 0x1)
- break;
+ coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
+
+ /* Get exponent
+ * ALGO: coef_exp = 14 - highest set bit position */
+ coef_exp = get_bitmask_order(coef_scaled);
+ /* Doesn't make sense if it's zero*/
if (!coef_exp)
return -EINVAL;
+ /* Note: we've shifted coef_scaled by 24 */
coef_exp = 14 - (coef_exp - 24);
+
+
+ /* Get mantissa (significant digits)
+ * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
coef_man = coef_scaled +
(1 << (24 - coef_exp - 1));
+
+ /* Calculate delta slope coefficient exponent
+ * and mantissa (remove scaling) and set them on hw */
ds_coef_man = coef_man >> (24 - coef_exp);
ds_coef_exp = coef_exp - 16;
@@ -86,20 +102,27 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
* index into rates for control rates, we can set it up like this because
* this is only used for AR5212 and we know it supports G mode
*/
-static int control_rates[] =
+static const unsigned int control_rates[] =
{ 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
/**
- * ath5k_hw_write_rate_duration - set rate duration during hw resets
+ * ath5k_hw_write_rate_duration - fill rate code to duration table
*
* @ah: the &struct ath5k_hw
* @mode: one of enum ath5k_driver_mode
*
- * Write the rate duration table upon hw reset. This is a helper for
- * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for
- * the hardware for the current mode for each rate. The rates which are capable
- * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another
- * register for the short preamble ACK timeout calculation.
+ * Write the rate code to duration table upon hw reset. This is a helper for
+ * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
+ * the hardware, based on current mode, for each rate. The rates which are
+ * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
+ * different rate code so we write their value twice (one for long preample
+ * and one for short).
+ *
+ * Note: Band doesn't matter here, if we set the values for OFDM it works
+ * on both a and g modes. So all we have to do is set values for all g rates
+ * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
+ * quarter rate mode, we need to use another set of bitrates (that's why we
+ * need the mode parameter) but we don't handle these proprietary modes yet.
*/
static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
unsigned int mode)
@@ -275,7 +298,8 @@ commit:
}
/*
- * Bring up MAC + PHY Chips
+ * Bring up MAC + PHY Chips and program PLL
+ * TODO: Half/Quarter rate support
*/
int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
{
@@ -333,7 +357,11 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
}
} else if (flags & CHANNEL_5GHZ) {
mode |= AR5K_PHY_MODE_FREQ_5GHZ;
- clock |= AR5K_PHY_PLL_40MHZ;
+
+ if (ah->ah_radio == AR5K_RF5413)
+ clock |= AR5K_PHY_PLL_40MHZ_5413;
+ else
+ clock |= AR5K_PHY_PLL_40MHZ;
if (flags & CHANNEL_OFDM)
mode |= AR5K_PHY_MODE_MOD_OFDM;
@@ -391,10 +419,14 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
}
if (ah->ah_version != AR5K_AR5210) {
- /* ...set the PHY operating mode */
- ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
- udelay(300);
+ /* ...update PLL if needed */
+ if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
+ ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
+ udelay(300);
+ }
+
+ /* ...set the PHY operating mode */
ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
}
@@ -403,22 +435,393 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
}
/*
+ * If there is an external 32KHz crystal available, use it
+ * as ref. clock instead of 32/40MHz clock and baseband clocks
+ * to save power during sleep or restore normal 32/40MHz
+ * operation.
+ *
+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,
+ * 123 - 127) require delay on access.
+ */
+static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u32 scal, spending, usec32;
+
+ /* Only set 32KHz settings if we have an external
+ * 32KHz crystal present */
+ if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
+ AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
+ enable) {
+
+ /* 1 usec/cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
+ /* Set up tsf increment on each cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
+
+ /* Set baseband sleep control registers
+ * and sleep control rate */
+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ spending = 0x14;
+ else
+ spending = 0x18;
+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
+ ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
+ } else {
+ ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
+ ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
+ }
+
+ /* Enable sleep clock operation */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+ } else {
+
+ /* Disable sleep clock operation and
+ * restore default parameters */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
+
+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
+
+ if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+ scal = AR5K_PHY_SCAL_32MHZ_2417;
+ else if (ath5k_eeprom_is_hb63(ah))
+ scal = AR5K_PHY_SCAL_32MHZ_HB63;
+ else
+ scal = AR5K_PHY_SCAL_32MHZ;
+ ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+
+ ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ spending = 0x14;
+ else
+ spending = 0x18;
+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413))
+ usec32 = 39;
+ else
+ usec32 = 31;
+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
+ }
+ return;
+}
+
+static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ u8 refclk_freq;
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ refclk_freq = 40;
+ else
+ refclk_freq = 32;
+
+ if ((channel->center_freq % refclk_freq != 0) &&
+ ((channel->center_freq % refclk_freq < 10) ||
+ (channel->center_freq % refclk_freq > 22)))
+ return true;
+ else
+ return false;
+}
+
+/* TODO: Half/Quarter rate */
+static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ if (ah->ah_version == AR5K_AR5212 &&
+ ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+
+ /* Setup ADC control */
+ ath5k_hw_reg_write(ah,
+ (AR5K_REG_SM(2,
+ AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
+ AR5K_REG_SM(2,
+ AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
+ AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
+ AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
+ AR5K_PHY_ADC_CTL);
+
+
+
+ /* Disable barker RSSI threshold */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+ AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+ AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
+
+ /* Set the mute mask */
+ ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
+ }
+
+ /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */
+ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
+
+ /* Enable DCU double buffering */
+ if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
+ AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_DCU_DBL_BUF_DIS);
+
+ /* Set DAC/ADC delays */
+ if (ah->ah_version == AR5K_AR5212) {
+ u32 scal;
+ if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+ scal = AR5K_PHY_SCAL_32MHZ_2417;
+ else if (ath5k_eeprom_is_hb63(ah))
+ scal = AR5K_PHY_SCAL_32MHZ_HB63;
+ else
+ scal = AR5K_PHY_SCAL_32MHZ;
+ ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+ }
+
+ /* Set fast ADC */
+ if ((ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ u32 fast_adc = true;
+
+ if (channel->center_freq == 2462 ||
+ channel->center_freq == 2467)
+ fast_adc = 0;
+
+ /* Only update if needed */
+ if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
+ ath5k_hw_reg_write(ah, fast_adc,
+ AR5K_PHY_FAST_ADC);
+ }
+
+ /* Fix for first revision of the RF5112 RF chipset */
+ if (ah->ah_radio == AR5K_RF5112 &&
+ ah->ah_radio_5ghz_revision <
+ AR5K_SREV_RAD_5112A) {
+ u32 data;
+ ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
+ AR5K_PHY_CCKTXCTL);
+ if (channel->hw_value & CHANNEL_5GHZ)
+ data = 0xffb81020;
+ else
+ data = 0xffb80d20;
+ ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
+ }
+
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+ u32 usec_reg;
+ /* 5311 has different tx/rx latency masks
+ * from 5211, since we deal 5311 the same
+ * as 5211 when setting initvals, shift
+ * values here to their proper locations */
+ usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
+ ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
+ AR5K_USEC_32 |
+ AR5K_USEC_TX_LATENCY_5211 |
+ AR5K_REG_SM(29,
+ AR5K_USEC_RX_LATENCY_5210)),
+ AR5K_USEC_5211);
+ /* Clear QCU/DCU clock gating register */
+ ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
+ /* Set DAC/ADC delays */
+ ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
+ /* Enable PCU FIFO corruption ECO */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
+ AR5K_DIAG_SW_ECO_ENABLE);
+ }
+}
+
+static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+
+ /* Set CCK to OFDM power delta */
+ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+ int16_t cck_ofdm_pwr_delta;
+
+ /* Adjust power delta for channel 14 */
+ if (channel->center_freq == 2484)
+ cck_ofdm_pwr_delta =
+ ((ee->ee_cck_ofdm_power_delta -
+ ee->ee_scaled_cck_delta) * 2) / 10;
+ else
+ cck_ofdm_pwr_delta =
+ (ee->ee_cck_ofdm_power_delta * 2) / 10;
+
+ if (channel->hw_value == CHANNEL_G)
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM((ee->ee_cck_ofdm_power_delta * -1),
+ AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
+ AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
+ AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
+ AR5K_PHY_TX_PWR_ADJ);
+ else
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
+ }
+
+ /* Set antenna idle switch table */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
+ AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
+ (ah->ah_antenna[ee_mode][0] |
+ AR5K_PHY_ANT_CTL_TXRX_EN));
+
+ /* Set antenna switch table */
+ ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
+ AR5K_PHY_ANT_SWITCH_TABLE_0);
+ ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
+ AR5K_PHY_ANT_SWITCH_TABLE_1);
+
+ /* Noise floor threshold */
+ ath5k_hw_reg_write(ah,
+ AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
+ AR5K_PHY_NFTHRES);
+
+ if ((channel->hw_value & CHANNEL_TURBO) &&
+ (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
+ /* Switch settling time (Turbo) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+ AR5K_PHY_SETTLING_SWITCH,
+ ee->ee_switch_settling_turbo[ee_mode]);
+
+ /* Tx/Rx attenuation (Turbo) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+ AR5K_PHY_GAIN_TXRX_ATTEN,
+ ee->ee_atn_tx_rx_turbo[ee_mode]);
+
+ /* ADC/PGA desired size (Turbo) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+ AR5K_PHY_DESIRED_SIZE_ADC,
+ ee->ee_adc_desired_size_turbo[ee_mode]);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+ AR5K_PHY_DESIRED_SIZE_PGA,
+ ee->ee_pga_desired_size_turbo[ee_mode]);
+
+ /* Tx/Rx margin (Turbo) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+ AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+ ee->ee_margin_tx_rx_turbo[ee_mode]);
+
+ } else {
+ /* Switch settling time */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+ AR5K_PHY_SETTLING_SWITCH,
+ ee->ee_switch_settling[ee_mode]);
+
+ /* Tx/Rx attenuation */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+ AR5K_PHY_GAIN_TXRX_ATTEN,
+ ee->ee_atn_tx_rx[ee_mode]);
+
+ /* ADC/PGA desired size */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+ AR5K_PHY_DESIRED_SIZE_ADC,
+ ee->ee_adc_desired_size[ee_mode]);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+ AR5K_PHY_DESIRED_SIZE_PGA,
+ ee->ee_pga_desired_size[ee_mode]);
+
+ /* Tx/Rx margin */
+ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+ AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+ ee->ee_margin_tx_rx[ee_mode]);
+ }
+
+ /* XPA delays */
+ ath5k_hw_reg_write(ah,
+ (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
+ (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
+ (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
+ (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
+
+ /* XLNA delay */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
+ AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
+ ee->ee_tx_end2xlna_enable[ee_mode]);
+
+ /* Thresh64 (ANI) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
+ AR5K_PHY_NF_THRESH62,
+ ee->ee_thr_62[ee_mode]);
+
+
+ /* False detect backoff for channels
+ * that have spur noise. Write the new
+ * cyclic power RSSI threshold. */
+ if (ath5k_hw_chan_has_spur_noise(ah, channel))
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+ AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+ AR5K_INIT_CYCRSSI_THR1 +
+ ee->ee_false_detect[ee_mode]);
+ else
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+ AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+ AR5K_INIT_CYCRSSI_THR1);
+
+ /* I/Q correction
+ * TODO: Per channel i/q infos ? */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_CORR_ENABLE |
+ (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
+ ee->ee_q_cal[ee_mode]);
+
+ /* Heavy clipping -disable for now */
+ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
+
+ return;
+}
+
+/*
* Main reset function
*/
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
struct ieee80211_channel *channel, bool change_channel)
{
- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- struct pci_dev *pdev = ah->ah_sc->pdev;
- u32 data, s_seq, s_ant, s_led[3], dma_size;
- unsigned int i, mode, freq, ee_mode, ant[2];
- int ret;
+ u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
+ u32 phy_tst1;
+ u8 mode, freq, ee_mode, ant[2];
+ int i, ret;
ATH5K_TRACE(ah->ah_sc);
- s_seq = 0;
s_ant = 0;
ee_mode = 0;
+ staid1_flags = 0;
+ tsf_up = 0;
+ tsf_lo = 0;
freq = 0;
mode = 0;
@@ -427,48 +830,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*/
/*DCU/Antenna selection not available on 5210*/
if (ah->ah_version != AR5K_AR5210) {
- if (change_channel) {
- /* Seq number for queue 0 -do this for all queues ? */
- s_seq = ath5k_hw_reg_read(ah,
- AR5K_QUEUE_DFS_SEQNUM(0));
- /*Default antenna*/
- s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
- }
- }
-
- /*GPIOs*/
- s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
- s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
- s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
-
- if (change_channel && ah->ah_rf_banks != NULL)
- ath5k_hw_get_rf_gain(ah);
-
-
- /*Wakeup the device*/
- ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
- if (ret)
- return ret;
-
- /*
- * Initialize operating mode
- */
- ah->ah_op_mode = op_mode;
-
- /*
- * 5111/5112 Settings
- * 5210 only comes with RF5110
- */
- if (ah->ah_version != AR5K_AR5210) {
- if (ah->ah_radio != AR5K_RF5111 &&
- ah->ah_radio != AR5K_RF5112 &&
- ah->ah_radio != AR5K_RF5413 &&
- ah->ah_radio != AR5K_RF2413 &&
- ah->ah_radio != AR5K_RF2425) {
- ATH5K_ERR(ah->ah_sc,
- "invalid phy radio: %u\n", ah->ah_radio);
- return -EINVAL;
- }
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
@@ -491,8 +852,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
freq = AR5K_INI_RFGAIN_5GHZ;
ee_mode = AR5K_EEPROM_MODE_11A;
break;
- /*Is this ok on 5211 too ?*/
case CHANNEL_TG:
+ if (ah->ah_version == AR5K_AR5211) {
+ ATH5K_ERR(ah->ah_sc,
+ "TurboG mode not available on 5211");
+ return -EINVAL;
+ }
mode = AR5K_MODE_11G_TURBO;
freq = AR5K_INI_RFGAIN_2GHZ;
ee_mode = AR5K_EEPROM_MODE_11G;
@@ -513,11 +878,93 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
return -EINVAL;
}
- /* PHY access enable */
- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+ if (change_channel) {
+ /*
+ * Save frame sequence count
+ * For revs. after Oahu, only save
+ * seq num for DCU 0 (Global seq num)
+ */
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+
+ for (i = 0; i < 10; i++)
+ s_seq[i] = ath5k_hw_reg_read(ah,
+ AR5K_QUEUE_DCU_SEQNUM(i));
+
+ } else {
+ s_seq[0] = ath5k_hw_reg_read(ah,
+ AR5K_QUEUE_DCU_SEQNUM(0));
+ }
+
+ /* TSF accelerates on AR5211 durring reset
+ * As a workaround save it here and restore
+ * it later so that it's back in time after
+ * reset. This way it'll get re-synced on the
+ * next beacon without breaking ad-hoc.
+ *
+ * On AR5212 TSF is almost preserved across a
+ * reset so it stays back in time anyway and
+ * we don't have to save/restore it.
+ *
+ * XXX: Since this breaks power saving we have
+ * to disable power saving until we receive the
+ * next beacon, so we can resync beacon timers */
+ if (ah->ah_version == AR5K_AR5211) {
+ tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+ }
+ }
+
+ /* Save default antenna */
+ s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
+ if (ah->ah_version == AR5K_AR5212) {
+ /* Restore normal 32/40MHz clock operation
+ * to avoid register access delay on certain
+ * PHY registers */
+ ath5k_hw_set_sleep_clock(ah, false);
+
+ /* Since we are going to write rf buffer
+ * check if we have any pending gain_F
+ * optimization settings */
+ if (change_channel && ah->ah_rf_banks != NULL)
+ ath5k_hw_gainf_calibrate(ah);
+ }
}
+ /*GPIOs*/
+ s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
+ AR5K_PCICFG_LEDSTATE;
+ s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
+ s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
+
+ /* AR5K_STA_ID1 flags, only preserve antenna
+ * settings and ack/cts rate mode */
+ staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
+ (AR5K_STA_ID1_DEFAULT_ANTENNA |
+ AR5K_STA_ID1_DESC_ANTENNA |
+ AR5K_STA_ID1_RTS_DEF_ANTENNA |
+ AR5K_STA_ID1_ACKCTS_6MB |
+ AR5K_STA_ID1_BASE_RATE_11B |
+ AR5K_STA_ID1_SELFGEN_DEF_ANT);
+
+ /* Wakeup the device */
+ ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
+ if (ret)
+ return ret;
+
+ /*
+ * Initialize operating mode
+ */
+ ah->ah_op_mode = op_mode;
+
+ /* PHY access enable */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+ else
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
+ AR5K_PHY(0));
+
+ /* Write initial settings */
ret = ath5k_hw_write_initvals(ah, mode, change_channel);
if (ret)
return ret;
@@ -526,64 +973,23 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
* 5211/5212 Specific
*/
if (ah->ah_version != AR5K_AR5210) {
+
/*
* Write initial RF gain settings
* This should work for both 5111/5112
*/
- ret = ath5k_hw_rfgain(ah, freq);
+ ret = ath5k_hw_rfgain_init(ah, freq);
if (ret)
return ret;
mdelay(1);
/*
- * Write some more initial register settings for revised chips
+ * Tweak initval settings for revised
+ * chipsets and add some more config
+ * bits
*/
- if (ah->ah_version == AR5K_AR5212 &&
- ah->ah_phy_revision > 0x41) {
- ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
-
- if (channel->hw_value == CHANNEL_G)
- if (ah->ah_mac_srev < AR5K_SREV_AR2413)
- ath5k_hw_reg_write(ah, 0x00f80d80,
- 0x994c);
- else if (ah->ah_mac_srev < AR5K_SREV_AR5424)
- ath5k_hw_reg_write(ah, 0x00380140,
- 0x994c);
- else if (ah->ah_mac_srev < AR5K_SREV_AR2425)
- ath5k_hw_reg_write(ah, 0x00fc0ec0,
- 0x994c);
- else /* 2425 */
- ath5k_hw_reg_write(ah, 0x00fc0fc0,
- 0x994c);
- else
- ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
-
- /* Got this from legacy-hal */
- AR5K_REG_DISABLE_BITS(ah, 0xa228, 0x200);
-
- AR5K_REG_MASKED_BITS(ah, 0xa228, 0x800, 0xfffe03ff);
-
- /* Just write 0x9b5 ? */
- /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
- ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
- ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
- ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
- }
-
- /* Fix for first revision of the RF5112 RF chipset */
- if (ah->ah_radio >= AR5K_RF5112 &&
- ah->ah_radio_5ghz_revision <
- AR5K_SREV_RAD_5112A) {
- ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
- AR5K_PHY_CCKTXCTL);
- if (channel->hw_value & CHANNEL_5GHZ)
- data = 0xffb81020;
- else
- data = 0xffb80d20;
- ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
- data = 0;
- }
+ ath5k_hw_tweak_initval_settings(ah, channel);
/*
* Set TX power (FIXME)
@@ -601,15 +1007,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_write_rate_duration(ah, mode);
/*
- * Write RF registers
+ * Write RF buffer
*/
- ret = ath5k_hw_rfregs(ah, channel, mode);
+ ret = ath5k_hw_rfregs_init(ah, channel, mode);
if (ret)
return ret;
- /*
- * Configure additional registers
- */
/* Write OFDM timings on 5212*/
if (ah->ah_version == AR5K_AR5212 &&
@@ -631,17 +1034,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}
/*
- * Set channel and calibrate the PHY
- */
- ret = ath5k_hw_channel(ah, channel);
- if (ret)
- return ret;
-
- /* Set antenna mode */
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
- ah->ah_antenna[ee_mode][0], 0xfffffc06);
-
- /*
* In case a fixed antenna was set as default
* write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
* registers.
@@ -656,54 +1048,16 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ant[1] = AR5K_ANT_FIXED_B;
}
- ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
- AR5K_PHY_ANT_SWITCH_TABLE_0);
- ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
- AR5K_PHY_ANT_SWITCH_TABLE_1);
-
/* Commit values from EEPROM */
- if (ah->ah_radio == AR5K_RF5111)
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
- AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
-
- ath5k_hw_reg_write(ah,
- AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
- AR5K_PHY_NFTHRES);
-
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
- (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
- 0xffffc07f);
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
- (ee->ee_atn_tx_rx[ee_mode] << 12) & 0x3f000,
- 0xfffc0fff);
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
- (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
- ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
- 0xffff0000);
-
- ath5k_hw_reg_write(ah,
- (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
- (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
- (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
- (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
-
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
- ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
- (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
-
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_CORR_ENABLE |
- (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
- ee->ee_q_cal[ee_mode]);
-
- if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
- AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
- ee->ee_margin_tx_rx[ee_mode]);
+ ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
} else {
+ /*
+ * For 5210 we do all initialization using
+ * initvals, so we don't have to modify
+ * any settings (5210 also only supports
+ * a/aturbo modes)
+ */
mdelay(1);
/* Disable phy and wait */
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
@@ -713,100 +1067,154 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/*
* Restore saved values
*/
+
/*DCU/Antenna selection not available on 5210*/
if (ah->ah_version != AR5K_AR5210) {
- ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
+
+ if (change_channel) {
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+ for (i = 0; i < 10; i++)
+ ath5k_hw_reg_write(ah, s_seq[i],
+ AR5K_QUEUE_DCU_SEQNUM(i));
+ } else {
+ ath5k_hw_reg_write(ah, s_seq[0],
+ AR5K_QUEUE_DCU_SEQNUM(0));
+ }
+
+
+ if (ah->ah_version == AR5K_AR5211) {
+ ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
+ ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
+ }
+ }
+
ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
}
+
+ /* Ledstate */
AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
+
+ /* Gpio settings */
ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
+ /* Restore sta_id flags and preserve our mac address*/
+ ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
+ AR5K_STA_ID0);
+ ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
+ AR5K_STA_ID1);
+
+
/*
- * Misc
+ * Configure PCU
*/
+
+ /* Restore bssid and bssid mask */
/* XXX: add ah->aid once mac80211 gives this to us */
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+ /* Set PCU config */
ath5k_hw_set_opmode(ah);
- /*PISR/SISR Not available on 5210*/
- if (ah->ah_version != AR5K_AR5210) {
+
+ /* Clear any pending interrupts
+ * PISR/SISR Not available on 5210 */
+ if (ah->ah_version != AR5K_AR5210)
ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
- /* If we later allow tuning for this, store into sc structure */
- data = AR5K_TUNE_RSSI_THRES |
- AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
- ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
+
+ /* Set RSSI/BRSSI thresholds
+ *
+ * Note: If we decide to set this value
+ * dynamicaly, have in mind that when AR5K_RSSI_THR
+ * register is read it might return 0x40 if we haven't
+ * wrote anything to it plus BMISS RSSI threshold is zeroed.
+ * So doing a save/restore procedure here isn't the right
+ * choice. Instead store it on ath5k_hw */
+ ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
+ AR5K_TUNE_BMISS_THRES <<
+ AR5K_RSSI_THR_BMISS_S),
+ AR5K_RSSI_THR);
+
+ /* MIC QoS support */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
+ ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
+ ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
}
+ /* QoS NOACK Policy */
+ if (ah->ah_version == AR5K_AR5212) {
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
+ AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
+ AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
+ AR5K_QOS_NOACK);
+ }
+
+
/*
- * Set Rx/Tx DMA Configuration
- *
- * Set maximum DMA size (512) except for PCI-E cards since
- * it causes rx overruns and tx errors (tested on 5424 but since
- * rx overruns also occur on 5416/5418 with madwifi we set 128
- * for all PCI-E cards to be safe).
- *
- * In dumps this is 128 for allchips.
- *
- * XXX: need to check 5210 for this
- * TODO: Check out tx triger level, it's always 64 on dumps but I
- * guess we can tweak it and see how it goes ;-)
+ * Configure PHY
*/
- dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
- if (ah->ah_version != AR5K_AR5210) {
- AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_SDMAMR, dma_size);
- AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
- AR5K_RXCFG_SDMAMW, dma_size);
- }
+
+ /* Set channel on PHY */
+ ret = ath5k_hw_channel(ah, channel);
+ if (ret)
+ return ret;
/*
* Enable the PHY and wait until completion
+ * This includes BaseBand and Synthesizer
+ * activation.
*/
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
/*
* On 5211+ read activation -> rx delay
* and use it.
+ *
+ * TODO: Half/quarter rate support
*/
if (ah->ah_version != AR5K_AR5210) {
- data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+ u32 delay;
+ delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
AR5K_PHY_RX_DELAY_M;
- data = (channel->hw_value & CHANNEL_CCK) ?
- ((data << 2) / 22) : (data / 10);
+ delay = (channel->hw_value & CHANNEL_CCK) ?
+ ((delay << 2) / 22) : (delay / 10);
- udelay(100 + (2 * data));
- data = 0;
+ udelay(100 + (2 * delay));
} else {
mdelay(1);
}
/*
- * Perform ADC test (?)
+ * Perform ADC test to see if baseband is ready
+ * Set tx hold and check adc test register
*/
- data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
for (i = 0; i <= 20; i++) {
if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
break;
udelay(200);
}
- ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
- data = 0;
+ ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
/*
- * Start automatic gain calibration
+ * Start automatic gain control calibration
*
* During AGC calibration RX path is re-routed to
- * a signal detector so we don't receive anything.
+ * a power detector so we don't receive anything.
*
* This method is used to calibrate some static offsets
* used together with on-the fly I/Q calibration (the
* one performed via ath5k_hw_phy_calibrate), that doesn't
* interrupt rx path.
*
+ * While rx path is re-routed to the power detector we also
+ * start a noise floor calibration, to measure the
+ * card's noise floor (the noise we measure when we are not
+ * transmiting or receiving anything).
+ *
* If we are in a noisy environment AGC calibration may time
- * out.
+ * out and/or noise floor calibration might timeout.
*/
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
AR5K_PHY_AGCCTL_CAL);
@@ -828,30 +1236,37 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
AR5K_PHY_AGCCTL_CAL, 0, false)) {
ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
channel->center_freq);
- return -EAGAIN;
}
/*
- * Start noise floor calibration
- *
* If we run NF calibration before AGC, it always times out.
* Binary HAL starts NF and AGC calibration at the same time
- * and only waits for AGC to finish. I believe that's wrong because
- * during NF calibration, rx path is also routed to a detector, so if
- * it doesn't finish we won't have RX.
- *
- * XXX: Find an interval that's OK for all cards...
+ * and only waits for AGC to finish. Also if AGC or NF cal.
+ * times out, reset doesn't fail on binary HAL. I believe
+ * that's wrong because since rx path is routed to a detector,
+ * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
+ * enables noise floor calibration after offset calibration and if noise
+ * floor calibration fails, reset fails. I believe that's
+ * a better approach, we just need to find a polling interval
+ * that suits best, even if reset continues we need to make
+ * sure that rx path is ready.
*/
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+
+ /*
+ * Configure QCUs/DCUs
+ */
+
+ /* TODO: HW Compression support for data queues */
+ /* TODO: Burst prefetch for data queues */
+
/*
* Reset queues and start beacon timers at the end of the reset routine
+ * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
+ * Note: If we want we can assign multiple qcus on one dcu.
*/
for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
- /*No QCU on 5210*/
- if (ah->ah_version != AR5K_AR5210)
- AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
-
ret = ath5k_hw_reset_tx_queue(ah, i);
if (ret) {
ATH5K_ERR(ah->ah_sc,
@@ -860,14 +1275,40 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}
}
+
+ /*
+ * Configure DMA/Interrupts
+ */
+
+ /*
+ * Set Rx/Tx DMA Configuration
+ *
+ * Set standard DMA size (128). Note that
+ * a DMA size of 512 causes rx overruns and tx errors
+ * on pci-e cards (tested on 5424 but since rx overruns
+ * also occur on 5416/5418 with madwifi we set 128
+ * for all PCI-E cards to be safe).
+ *
+ * XXX: need to check 5210 for this
+ * TODO: Check out tx triger level, it's always 64 on dumps but I
+ * guess we can tweak it and see how it goes ;-)
+ */
+ if (ah->ah_version != AR5K_AR5210) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+ }
+
/* Pre-enable interrupts on 5211/5212*/
if (ah->ah_version != AR5K_AR5210)
ath5k_hw_set_imr(ah, ah->ah_imr);
/*
- * Set RF kill flags if supported by the device (read from the EEPROM)
- * Disable gpio_intr for now since it results system hang.
- * TODO: Handle this in ath5k_intr
+ * 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)) {
@@ -880,33 +1321,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}
#endif
- /*
- * Set the 32MHz reference clock on 5212 phy clock sleep register
- *
- * TODO: Find out how to switch to external 32Khz clock to save power
- */
- if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
- ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
- ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
- ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
- ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
-
- data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
- data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
- 0x00000f80 : 0x00001380 ;
- ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
- data = 0;
- }
-
- if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
- ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
- ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
- if (ah->ah_mac_srev >= AR5K_SREV_AR2413)
- ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
- }
+ /* Enable 32KHz clock function for AR5212+ chips
+ * Set clocks to 32KHz operation and use an
+ * external 32KHz crystal when sleeping if one
+ * exists */
+ if (ah->ah_version == AR5K_AR5212)
+ ath5k_hw_set_sleep_clock(ah, true);
/*
* Disable beacons and reset the register
diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath5k/rfbuffer.h
new file mode 100644
index 00000000000..e50baff6617
--- /dev/null
+++ b/drivers/net/wireless/ath5k/rfbuffer.h
@@ -0,0 +1,1181 @@
+/*
+ * RF Buffer handling functions
+ *
+ * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+
+/*
+ * There are some special registers on the RF chip
+ * that control various operation settings related mostly to
+ * the analog parts (channel, gain adjustment etc).
+ *
+ * We don't write on those registers directly but
+ * we send a data packet on the chip, using a special register,
+ * that holds all the settings we need. After we 've sent the
+ * data packet, we write on another special register to notify hw
+ * to apply the settings. This is done so that control registers
+ * can be dynamicaly programmed during operation and the settings
+ * are applied faster on the hw.
+ *
+ * We call each data packet an "RF Bank" and all the data we write
+ * (all RF Banks) "RF Buffer". This file holds initial RF Buffer
+ * data for the different RF chips, and various info to match RF
+ * Buffer offsets with specific RF registers so that we can access
+ * them. We tweak these settings on rfregs_init function.
+ *
+ * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
+ * registers and control registers):
+ *
+ * http://www.google.com/patents?id=qNURAAAAEBAJ
+ */
+
+
+/*
+ * Struct to hold default mode specific RF
+ * register values (RF Banks)
+ */
+struct ath5k_ini_rfbuffer {
+ u8 rfb_bank; /* RF Bank number */
+ u16 rfb_ctrl_register; /* RF Buffer control register */
+ u32 rfb_mode_data[5]; /* RF Buffer data for each mode */
+};
+
+/*
+ * Struct to hold RF Buffer field
+ * infos used to access certain RF
+ * analog registers
+ */
+struct ath5k_rfb_field {
+ u8 len; /* Field length */
+ u16 pos; /* Offset on the raw packet */
+ u8 col; /* Column -used for shifting */
+};
+
+/*
+ * RF analog register definition
+ */
+struct ath5k_rf_reg {
+ u8 bank; /* RF Buffer Bank number */
+ u8 index; /* Register's index on rf_regs_idx */
+ struct ath5k_rfb_field field; /* RF Buffer field for this register */
+};
+
+/* Map RF registers to indexes
+ * We do this to handle common bits and make our
+ * life easier by using an index for each register
+ * instead of a full rfb_field */
+enum ath5k_rf_regs_idx {
+ /* BANK 6 */
+ AR5K_RF_OB_2GHZ = 0,
+ AR5K_RF_OB_5GHZ,
+ AR5K_RF_DB_2GHZ,
+ AR5K_RF_DB_5GHZ,
+ AR5K_RF_FIXED_BIAS_A,
+ AR5K_RF_FIXED_BIAS_B,
+ AR5K_RF_PWD_XPD,
+ AR5K_RF_XPD_SEL,
+ AR5K_RF_XPD_GAIN,
+ AR5K_RF_PD_GAIN_LO,
+ AR5K_RF_PD_GAIN_HI,
+ AR5K_RF_HIGH_VC_CP,
+ AR5K_RF_MID_VC_CP,
+ AR5K_RF_LOW_VC_CP,
+ AR5K_RF_PUSH_UP,
+ AR5K_RF_PAD2GND,
+ AR5K_RF_XB2_LVL,
+ AR5K_RF_XB5_LVL,
+ AR5K_RF_PWD_ICLOBUF_2G,
+ AR5K_RF_PWD_84,
+ AR5K_RF_PWD_90,
+ AR5K_RF_PWD_130,
+ AR5K_RF_PWD_131,
+ AR5K_RF_PWD_132,
+ AR5K_RF_PWD_136,
+ AR5K_RF_PWD_137,
+ AR5K_RF_PWD_138,
+ AR5K_RF_PWD_166,
+ AR5K_RF_PWD_167,
+ AR5K_RF_DERBY_CHAN_SEL_MODE,
+ /* BANK 7 */
+ AR5K_RF_GAIN_I,
+ AR5K_RF_PLO_SEL,
+ AR5K_RF_RFGAIN_SEL,
+ AR5K_RF_RFGAIN_STEP,
+ AR5K_RF_WAIT_S,
+ AR5K_RF_WAIT_I,
+ AR5K_RF_MAX_TIME,
+ AR5K_RF_MIXVGA_OVR,
+ AR5K_RF_MIXGAIN_OVR,
+ AR5K_RF_MIXGAIN_STEP,
+ AR5K_RF_PD_DELAY_A,
+ AR5K_RF_PD_DELAY_B,
+ AR5K_RF_PD_DELAY_XR,
+ AR5K_RF_PD_PERIOD_A,
+ AR5K_RF_PD_PERIOD_B,
+ AR5K_RF_PD_PERIOD_XR,
+};
+
+
+/*******************\
+* RF5111 (Sombrero) *
+\*******************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 }
+#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 }
+
+#define AR5K_RF5111_OB_5GHZ { 3, 104, 0 }
+#define AR5K_RF5111_DB_5GHZ { 3, 107, 0 }
+
+#define AR5K_RF5111_PWD_XPD { 1, 95, 0 }
+#define AR5K_RF5111_XPD_GAIN { 4, 96, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5111_PWD(_n) { 1, (135 - _n), 3 }
+
+/* BANK 7 len pos col */
+#define AR5K_RF5111_GAIN_I { 6, 29, 0 }
+#define AR5K_RF5111_PLO_SEL { 1, 4, 0 }
+#define AR5K_RF5111_RFGAIN_SEL { 1, 36, 0 }
+#define AR5K_RF5111_RFGAIN_STEP { 6, 37, 0 }
+/* Only on AR5212 BaseBand and up */
+#define AR5K_RF5111_WAIT_S { 5, 19, 0 }
+#define AR5K_RF5111_WAIT_I { 5, 24, 0 }
+#define AR5K_RF5111_MAX_TIME { 2, 49, 0 }
+
+static const struct ath5k_rf_reg rf_regs_5111[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ},
+ {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ},
+ {6, AR5K_RF_DB_5GHZ, AR5K_RF5111_DB_5GHZ},
+ {6, AR5K_RF_PWD_XPD, AR5K_RF5111_PWD_XPD},
+ {6, AR5K_RF_XPD_GAIN, AR5K_RF5111_XPD_GAIN},
+ {6, AR5K_RF_PWD_84, AR5K_RF5111_PWD(84)},
+ {6, AR5K_RF_PWD_90, AR5K_RF5111_PWD(90)},
+ {7, AR5K_RF_GAIN_I, AR5K_RF5111_GAIN_I},
+ {7, AR5K_RF_PLO_SEL, AR5K_RF5111_PLO_SEL},
+ {7, AR5K_RF_RFGAIN_SEL, AR5K_RF5111_RFGAIN_SEL},
+ {7, AR5K_RF_RFGAIN_STEP, AR5K_RF5111_RFGAIN_STEP},
+ {7, AR5K_RF_WAIT_S, AR5K_RF5111_WAIT_S},
+ {7, AR5K_RF_WAIT_I, AR5K_RF5111_WAIT_I},
+ {7, AR5K_RF_MAX_TIME, AR5K_RF5111_MAX_TIME}
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5111[] = {
+ { 0, 0x989c,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
+ { 0, 0x989c,
+ { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
+ { 0, 0x98d4,
+ { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
+ { 1, 0x98d4,
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d4,
+ { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
+ { 3, 0x98d8,
+ { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c,
+ { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
+ { 6, 0x989c,
+ { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
+ { 6, 0x989c,
+ { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
+ { 6, 0x989c,
+ { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
+ { 6, 0x989c,
+ { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
+ { 6, 0x98d4,
+ { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
+ { 7, 0x989c,
+ { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
+ { 7, 0x989c,
+ { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
+ { 7, 0x989c,
+ { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+ { 7, 0x989c,
+ { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
+ { 7, 0x989c,
+ { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
+ { 7, 0x989c,
+ { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
+ { 7, 0x989c,
+ { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***********************\
+* RF5112/RF2112 (Derby) *
+\***********************/
+
+/* BANK 7 (Common) len pos col */
+#define AR5K_RF5112X_GAIN_I { 6, 14, 0 }
+#define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 }
+#define AR5K_RF5112X_MIXGAIN_OVR { 2, 37, 0 }
+#define AR5K_RF5112X_MIXGAIN_STEP { 4, 32, 0 }
+#define AR5K_RF5112X_PD_DELAY_A { 4, 58, 0 }
+#define AR5K_RF5112X_PD_DELAY_B { 4, 62, 0 }
+#define AR5K_RF5112X_PD_DELAY_XR { 4, 66, 0 }
+#define AR5K_RF5112X_PD_PERIOD_A { 4, 70, 0 }
+#define AR5K_RF5112X_PD_PERIOD_B { 4, 74, 0 }
+#define AR5K_RF5112X_PD_PERIOD_XR { 4, 78, 0 }
+
+/* RFX112 (Derby 1) */
+
+/* BANK 6 len pos col */
+#define AR5K_RF5112_OB_2GHZ { 3, 269, 0 }
+#define AR5K_RF5112_DB_2GHZ { 3, 272, 0 }
+
+#define AR5K_RF5112_OB_5GHZ { 3, 261, 0 }
+#define AR5K_RF5112_DB_5GHZ { 3, 264, 0 }
+
+#define AR5K_RF5112_FIXED_BIAS_A { 1, 260, 0 }
+#define AR5K_RF5112_FIXED_BIAS_B { 1, 259, 0 }
+
+#define AR5K_RF5112_XPD_SEL { 1, 284, 0 }
+#define AR5K_RF5112_XPD_GAIN { 2, 252, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 }
+
+static const struct ath5k_rf_reg rf_regs_5112[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ},
+ {6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ},
+ {6, AR5K_RF_DB_5GHZ, AR5K_RF5112_DB_5GHZ},
+ {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112_FIXED_BIAS_A},
+ {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112_FIXED_BIAS_B},
+ {6, AR5K_RF_XPD_SEL, AR5K_RF5112_XPD_SEL},
+ {6, AR5K_RF_XPD_GAIN, AR5K_RF5112_XPD_GAIN},
+ {6, AR5K_RF_PWD_130, AR5K_RF5112_PWD(130)},
+ {6, AR5K_RF_PWD_131, AR5K_RF5112_PWD(131)},
+ {6, AR5K_RF_PWD_132, AR5K_RF5112_PWD(132)},
+ {6, AR5K_RF_PWD_136, AR5K_RF5112_PWD(136)},
+ {6, AR5K_RF_PWD_137, AR5K_RF5112_PWD(137)},
+ {6, AR5K_RF_PWD_138, AR5K_RF5112_PWD(138)},
+ {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I},
+ {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR},
+ {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR},
+ {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP},
+ {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A},
+ {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B},
+ {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR},
+ {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A},
+ {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B},
+ {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+ { 3, 0x98dc,
+ { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
+ { 6, 0x989c,
+ { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
+ { 6, 0x989c,
+ { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
+ { 6, 0x989c,
+ { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
+ { 6, 0x989c,
+ { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
+ { 6, 0x989c,
+ { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c,
+ { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c,
+ { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
+ { 6, 0x989c,
+ { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
+ { 6, 0x989c,
+ { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c,
+ { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+ { 6, 0x989c,
+ { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
+ { 6, 0x989c,
+ { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
+ { 6, 0x989c,
+ { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+ { 6, 0x989c,
+ { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
+ { 6, 0x989c,
+ { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c,
+ { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c,
+ { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
+ { 6, 0x989c,
+ { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
+ { 6, 0x989c,
+ { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+ { 6, 0x989c,
+ { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
+ { 6, 0x989c,
+ { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
+ { 6, 0x989c,
+ { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
+ { 6, 0x989c,
+ { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
+ { 6, 0x989c,
+ { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
+ { 6, 0x989c,
+ { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
+ { 6, 0x989c,
+ { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
+ { 6, 0x989c,
+ { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
+ { 6, 0x989c,
+ { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
+ { 6, 0x989c,
+ { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
+ { 6, 0x98d0,
+ { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
+ { 7, 0x989c,
+ { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+ { 7, 0x989c,
+ { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+ { 7, 0x989c,
+ { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
+ { 7, 0x989c,
+ { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+ { 7, 0x989c,
+ { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
+ { 7, 0x989c,
+ { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+ { 7, 0x989c,
+ { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+ { 7, 0x989c,
+ { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
+ { 7, 0x989c,
+ { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
+ { 7, 0x989c,
+ { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+ { 7, 0x989c,
+ { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+ { 7, 0x989c,
+ { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+ { 7, 0x98c4,
+ { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+/* RFX112A (Derby 2) */
+
+/* BANK 6 len pos col */
+#define AR5K_RF5112A_OB_2GHZ { 3, 287, 0 }
+#define AR5K_RF5112A_DB_2GHZ { 3, 290, 0 }
+
+#define AR5K_RF5112A_OB_5GHZ { 3, 279, 0 }
+#define AR5K_RF5112A_DB_5GHZ { 3, 282, 0 }
+
+#define AR5K_RF5112A_FIXED_BIAS_A { 1, 278, 0 }
+#define AR5K_RF5112A_FIXED_BIAS_B { 1, 277, 0 }
+
+#define AR5K_RF5112A_XPD_SEL { 1, 302, 0 }
+#define AR5K_RF5112A_PDGAINLO { 2, 270, 0 }
+#define AR5K_RF5112A_PDGAINHI { 2, 257, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112A_PWD(_n) { 1, (306 - _n), 3 }
+
+/* Voltage regulators */
+#define AR5K_RF5112A_HIGH_VC_CP { 2, 90, 2 }
+#define AR5K_RF5112A_MID_VC_CP { 2, 92, 2 }
+#define AR5K_RF5112A_LOW_VC_CP { 2, 94, 2 }
+#define AR5K_RF5112A_PUSH_UP { 1, 254, 2 }
+
+/* Power consumption */
+#define AR5K_RF5112A_PAD2GND { 1, 281, 1 }
+#define AR5K_RF5112A_XB2_LVL { 2, 1, 3 }
+#define AR5K_RF5112A_XB5_LVL { 2, 3, 3 }
+
+static const struct ath5k_rf_reg rf_regs_5112a[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ},
+ {6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ},
+ {6, AR5K_RF_DB_5GHZ, AR5K_RF5112A_DB_5GHZ},
+ {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112A_FIXED_BIAS_A},
+ {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112A_FIXED_BIAS_B},
+ {6, AR5K_RF_XPD_SEL, AR5K_RF5112A_XPD_SEL},
+ {6, AR5K_RF_PD_GAIN_LO, AR5K_RF5112A_PDGAINLO},
+ {6, AR5K_RF_PD_GAIN_HI, AR5K_RF5112A_PDGAINHI},
+ {6, AR5K_RF_PWD_130, AR5K_RF5112A_PWD(130)},
+ {6, AR5K_RF_PWD_131, AR5K_RF5112A_PWD(131)},
+ {6, AR5K_RF_PWD_132, AR5K_RF5112A_PWD(132)},
+ {6, AR5K_RF_PWD_136, AR5K_RF5112A_PWD(136)},
+ {6, AR5K_RF_PWD_137, AR5K_RF5112A_PWD(137)},
+ {6, AR5K_RF_PWD_138, AR5K_RF5112A_PWD(138)},
+ {6, AR5K_RF_PWD_166, AR5K_RF5112A_PWD(166)},
+ {6, AR5K_RF_PWD_167, AR5K_RF5112A_PWD(167)},
+ {6, AR5K_RF_HIGH_VC_CP, AR5K_RF5112A_HIGH_VC_CP},
+ {6, AR5K_RF_MID_VC_CP, AR5K_RF5112A_MID_VC_CP},
+ {6, AR5K_RF_LOW_VC_CP, AR5K_RF5112A_LOW_VC_CP},
+ {6, AR5K_RF_PUSH_UP, AR5K_RF5112A_PUSH_UP},
+ {6, AR5K_RF_PAD2GND, AR5K_RF5112A_PAD2GND},
+ {6, AR5K_RF_XB2_LVL, AR5K_RF5112A_XB2_LVL},
+ {6, AR5K_RF_XB5_LVL, AR5K_RF5112A_XB5_LVL},
+ {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I},
+ {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR},
+ {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR},
+ {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP},
+ {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A},
+ {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B},
+ {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR},
+ {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A},
+ {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B},
+ {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
+ { 6, 0x989c,
+ { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
+ { 6, 0x989c,
+ { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
+ { 6, 0x989c,
+ { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
+ { 6, 0x989c,
+ { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
+ { 6, 0x989c,
+ { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
+ { 6, 0x989c,
+ { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
+ { 6, 0x989c,
+ { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c,
+ { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
+ { 6, 0x989c,
+ { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+ { 6, 0x989c,
+ { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
+ { 6, 0x989c,
+ { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
+ { 6, 0x989c,
+ { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c,
+ { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
+ { 6, 0x989c,
+ { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
+ { 6, 0x989c,
+ { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c,
+ { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
+ { 6, 0x989c,
+ { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
+ { 6, 0x989c,
+ { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
+ { 6, 0x989c,
+ { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
+ { 6, 0x989c,
+ { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
+ { 6, 0x989c,
+ { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
+ { 6, 0x989c,
+ { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
+ { 6, 0x989c,
+ { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
+ { 6, 0x989c,
+ { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
+ { 6, 0x98d8,
+ { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
+ { 7, 0x989c,
+ { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+ { 7, 0x989c,
+ { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+ { 7, 0x989c,
+ { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
+ { 7, 0x989c,
+ { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+ { 7, 0x989c,
+ { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
+ { 7, 0x989c,
+ { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+ { 7, 0x989c,
+ { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+ { 7, 0x989c,
+ { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
+ { 7, 0x989c,
+ { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
+ { 7, 0x989c,
+ { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+ { 7, 0x989c,
+ { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+ { 7, 0x989c,
+ { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+ { 7, 0x98c4,
+ { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+
+
+/******************\
+* RF2413 (Griffin) *
+\******************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF2413_OB_2GHZ { 3, 168, 0 }
+#define AR5K_RF2413_DB_2GHZ { 3, 165, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2413[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ???
+ */
+static const struct ath5k_ini_rfbuffer rfb_2413[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
+ { 6, 0x989c,
+ { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
+ { 6, 0x989c,
+ { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
+ { 6, 0x989c,
+ { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
+ { 6, 0x989c,
+ { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
+ { 6, 0x989c,
+ { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
+ { 6, 0x989c,
+ { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
+ { 6, 0x989c,
+ { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
+ { 6, 0x989c,
+ { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
+ { 6, 0x989c,
+ { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
+ { 6, 0x989c,
+ { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
+ { 6, 0x989c,
+ { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
+ { 6, 0x989c,
+ { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
+ { 6, 0x98d8,
+ { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2315/RF2316 (Cobra SoC) *
+\***************************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF2316_OB_2GHZ { 3, 178, 0 }
+#define AR5K_RF2316_DB_2GHZ { 3, 175, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2316[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_2316[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
+ { 6, 0x989c,
+ { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+ { 6, 0x989c,
+ { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
+ { 6, 0x989c,
+ { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
+ { 6, 0x989c,
+ { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
+ { 6, 0x989c,
+ { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
+ { 6, 0x989c,
+ { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
+ { 6, 0x989c,
+ { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+ { 6, 0x989c,
+ { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
+ { 6, 0x989c,
+ { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
+ { 6, 0x989c,
+ { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
+ { 6, 0x989c,
+ { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
+ { 6, 0x989c,
+ { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
+ { 6, 0x989c,
+ { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
+ { 6, 0x989c,
+ { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+ { 6, 0x989c,
+ { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+ { 6, 0x989c,
+ { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
+ { 6, 0x989c,
+ { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
+ { 6, 0x98c0,
+ { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/******************************\
+* RF5413/RF5424 (Eagle/Condor) *
+\******************************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF5413_OB_2GHZ { 3, 241, 0 }
+#define AR5K_RF5413_DB_2GHZ { 3, 238, 0 }
+
+#define AR5K_RF5413_OB_5GHZ { 3, 247, 0 }
+#define AR5K_RF5413_DB_5GHZ { 3, 244, 0 }
+
+#define AR5K_RF5413_PWD_ICLOBUF2G { 3, 131, 3 }
+#define AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 }
+
+static const struct ath5k_rf_reg rf_regs_5413[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF5413_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF5413_DB_2GHZ},
+ {6, AR5K_RF_OB_5GHZ, AR5K_RF5413_OB_5GHZ},
+ {6, AR5K_RF_DB_5GHZ, AR5K_RF5413_DB_5GHZ},
+ {6, AR5K_RF_PWD_ICLOBUF_2G, AR5K_RF5413_PWD_ICLOBUF2G},
+ {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5413[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+ { 3, 0x98dc,
+ { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
+ { 6, 0x989c,
+ { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
+ { 6, 0x989c,
+ { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
+ { 6, 0x989c,
+ { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
+ { 6, 0x989c,
+ { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+ { 6, 0x989c,
+ { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+ { 6, 0x989c,
+ { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
+ { 6, 0x989c,
+ { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
+ { 6, 0x989c,
+ { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
+ { 6, 0x989c,
+ { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
+ { 6, 0x989c,
+ { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
+ { 6, 0x989c,
+ { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
+ { 6, 0x989c,
+ { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+ { 6, 0x989c,
+ { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
+ { 6, 0x989c,
+ { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+ { 6, 0x989c,
+ { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
+ { 6, 0x989c,
+ { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
+ { 6, 0x989c,
+ { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
+ { 6, 0x989c,
+ { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
+ { 6, 0x989c,
+ { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
+ { 6, 0x989c,
+ { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
+ { 6, 0x989c,
+ { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
+ { 6, 0x98c8,
+ { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2425/RF2417 (Swan/Nala) *
+* AR2317 (Spider SoC) *
+\***************************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF2425_OB_2GHZ { 3, 193, 0 }
+#define AR5K_RF2425_DB_2GHZ { 3, 190, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2425[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2425[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c,
+ { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c,
+ { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c,
+ { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c,
+ { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+ { 6, 0x989c,
+ { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+ { 6, 0x989c,
+ { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c,
+ { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+ { 6, 0x989c,
+ { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c,
+ { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+ { 6, 0x989c,
+ { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c,
+ { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+ { 6, 0x98c4,
+ { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ */
+static const struct ath5k_ini_rfbuffer rfb_2317[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c,
+ { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c,
+ { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c,
+ { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c,
+ { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+ { 6, 0x989c,
+ { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
+ { 6, 0x989c,
+ { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c,
+ { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+ { 6, 0x989c,
+ { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c,
+ { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+ { 6, 0x989c,
+ { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c,
+ { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
+ { 6, 0x98c4,
+ { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2417[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c,
+ { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c,
+ { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c,
+ { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c,
+ { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
+ { 6, 0x989c,
+ { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+ { 6, 0x989c,
+ { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c,
+ { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
+ { 6, 0x989c,
+ { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c,
+ { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+ { 6, 0x989c,
+ { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c,
+ { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+ { 6, 0x98c4,
+ { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
diff --git a/drivers/net/wireless/ath5k/rfgain.h b/drivers/net/wireless/ath5k/rfgain.h
new file mode 100644
index 00000000000..1354d8c392c
--- /dev/null
+++ b/drivers/net/wireless/ath5k/rfgain.h
@@ -0,0 +1,516 @@
+/*
+ * RF Gain optimization
+ *
+ * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * Mode-specific RF Gain table (64bytes) for RF5111/5112
+ * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
+ * RF Gain values are included in AR5K_AR5210_INI)
+ */
+struct ath5k_ini_rfgain {
+ u16 rfg_register; /* RF Gain register address */
+ u32 rfg_value[2]; /* [freq (see below)] */
+};
+
+/* Initial RF Gain settings for RF5111 */
+static const struct ath5k_ini_rfgain rfgain_5111[] = {
+ /* 5Ghz 2Ghz */
+ { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } },
+ { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } },
+ { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } },
+ { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } },
+ { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } },
+ { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } },
+ { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } },
+ { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } },
+ { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } },
+ { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } },
+ { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } },
+ { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } },
+ { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } },
+ { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } },
+ { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } },
+ { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } },
+ { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } },
+ { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } },
+ { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } },
+ { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } },
+ { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } },
+ { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } },
+ { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } },
+ { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } },
+ { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } },
+ { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } },
+ { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } },
+ { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } },
+ { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } },
+ { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } },
+ { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } },
+ { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } },
+ { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } },
+ { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } },
+ { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } },
+ { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } },
+ { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } },
+ { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } },
+ { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } },
+ { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } },
+ { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } },
+ { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } },
+ { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } },
+ { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } },
+ { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } },
+ { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } },
+ { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } },
+ { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } },
+};
+
+/* Initial RF Gain settings for RF5112 */
+static const struct ath5k_ini_rfgain rfgain_5112[] = {
+ /* 5Ghz 2Ghz */
+ { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } },
+ { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } },
+ { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } },
+ { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } },
+ { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } },
+ { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } },
+ { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } },
+ { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } },
+ { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } },
+ { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } },
+ { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } },
+ { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } },
+ { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } },
+ { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } },
+ { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } },
+ { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } },
+ { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } },
+ { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } },
+ { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } },
+ { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } },
+ { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } },
+ { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } },
+ { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } },
+ { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } },
+ { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } },
+ { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } },
+ { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } },
+ { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } },
+ { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } },
+ { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } },
+ { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } },
+ { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } },
+ { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } },
+ { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } },
+ { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } },
+ { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } },
+ { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } },
+ { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } },
+ { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } },
+ { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } },
+ { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } },
+ { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } },
+ { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } },
+ { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } },
+ { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } },
+ { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } },
+ { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } },
+ { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } },
+ { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } },
+ { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } },
+ { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } },
+ { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } },
+ { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } },
+ { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } },
+ { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } },
+};
+
+/* Initial RF Gain settings for RF2413 */
+static const struct ath5k_ini_rfgain rfgain_2413[] = {
+ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } },
+ { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } },
+ { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } },
+ { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } },
+ { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } },
+ { AR5K_RF_GAIN(8), { 0x00000000, 0x00000168 } },
+ { AR5K_RF_GAIN(9), { 0x00000000, 0x000001a8 } },
+ { AR5K_RF_GAIN(10), { 0x00000000, 0x000001e8 } },
+ { AR5K_RF_GAIN(11), { 0x00000000, 0x00000028 } },
+ { AR5K_RF_GAIN(12), { 0x00000000, 0x00000068 } },
+ { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } },
+ { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } },
+ { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } },
+ { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } },
+ { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } },
+ { AR5K_RF_GAIN(18), { 0x00000000, 0x00000190 } },
+ { AR5K_RF_GAIN(19), { 0x00000000, 0x000001d0 } },
+ { AR5K_RF_GAIN(20), { 0x00000000, 0x00000010 } },
+ { AR5K_RF_GAIN(21), { 0x00000000, 0x00000050 } },
+ { AR5K_RF_GAIN(22), { 0x00000000, 0x00000090 } },
+ { AR5K_RF_GAIN(23), { 0x00000000, 0x00000191 } },
+ { AR5K_RF_GAIN(24), { 0x00000000, 0x000001d1 } },
+ { AR5K_RF_GAIN(25), { 0x00000000, 0x00000011 } },
+ { AR5K_RF_GAIN(26), { 0x00000000, 0x00000051 } },
+ { AR5K_RF_GAIN(27), { 0x00000000, 0x00000091 } },
+ { AR5K_RF_GAIN(28), { 0x00000000, 0x00000178 } },
+ { AR5K_RF_GAIN(29), { 0x00000000, 0x000001b8 } },
+ { AR5K_RF_GAIN(30), { 0x00000000, 0x000001f8 } },
+ { AR5K_RF_GAIN(31), { 0x00000000, 0x00000038 } },
+ { AR5K_RF_GAIN(32), { 0x00000000, 0x00000078 } },
+ { AR5K_RF_GAIN(33), { 0x00000000, 0x00000199 } },
+ { AR5K_RF_GAIN(34), { 0x00000000, 0x000001d9 } },
+ { AR5K_RF_GAIN(35), { 0x00000000, 0x00000019 } },
+ { AR5K_RF_GAIN(36), { 0x00000000, 0x00000059 } },
+ { AR5K_RF_GAIN(37), { 0x00000000, 0x00000099 } },
+ { AR5K_RF_GAIN(38), { 0x00000000, 0x000000d9 } },
+ { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } },
+};
+
+/* Initial RF Gain settings for AR2316 */
+static const struct ath5k_ini_rfgain rfgain_2316[] = {
+ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x00000000, 0x000000c0 } },
+ { AR5K_RF_GAIN(4), { 0x00000000, 0x000000e0 } },
+ { AR5K_RF_GAIN(5), { 0x00000000, 0x000000e0 } },
+ { AR5K_RF_GAIN(6), { 0x00000000, 0x00000128 } },
+ { AR5K_RF_GAIN(7), { 0x00000000, 0x00000128 } },
+ { AR5K_RF_GAIN(8), { 0x00000000, 0x00000128 } },
+ { AR5K_RF_GAIN(9), { 0x00000000, 0x00000168 } },
+ { AR5K_RF_GAIN(10), { 0x00000000, 0x000001a8 } },
+ { AR5K_RF_GAIN(11), { 0x00000000, 0x000001e8 } },
+ { AR5K_RF_GAIN(12), { 0x00000000, 0x00000028 } },
+ { AR5K_RF_GAIN(13), { 0x00000000, 0x00000068 } },
+ { AR5K_RF_GAIN(14), { 0x00000000, 0x000000a8 } },
+ { AR5K_RF_GAIN(15), { 0x00000000, 0x000000e8 } },
+ { AR5K_RF_GAIN(16), { 0x00000000, 0x000000e8 } },
+ { AR5K_RF_GAIN(17), { 0x00000000, 0x00000130 } },
+ { AR5K_RF_GAIN(18), { 0x00000000, 0x00000130 } },
+ { AR5K_RF_GAIN(19), { 0x00000000, 0x00000170 } },
+ { AR5K_RF_GAIN(20), { 0x00000000, 0x000001b0 } },
+ { AR5K_RF_GAIN(21), { 0x00000000, 0x000001f0 } },
+ { AR5K_RF_GAIN(22), { 0x00000000, 0x00000030 } },
+ { AR5K_RF_GAIN(23), { 0x00000000, 0x00000070 } },
+ { AR5K_RF_GAIN(24), { 0x00000000, 0x000000b0 } },
+ { AR5K_RF_GAIN(25), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(26), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(27), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(28), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(29), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(30), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(31), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(32), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(33), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(34), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(35), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(36), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f0 } },
+};
+
+
+/* Initial RF Gain settings for RF5413 */
+static const struct ath5k_ini_rfgain rfgain_5413[] = {
+ /* 5Ghz 2Ghz */
+ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } },
+ { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } },
+ { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } },
+ { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } },
+ { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } },
+ { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } },
+ { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } },
+ { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } },
+ { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } },
+ { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } },
+ { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } },
+ { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } },
+ { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } },
+ { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } },
+ { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } },
+ { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } },
+ { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } },
+ { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } },
+ { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } },
+ { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } },
+ { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } },
+ { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } },
+ { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } },
+ { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } },
+ { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } },
+ { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } },
+ { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } },
+ { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } },
+ { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } },
+ { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } },
+ { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } },
+ { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } },
+ { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } },
+ { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } },
+ { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } },
+ { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } },
+ { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
+};
+
+
+/* Initial RF Gain settings for RF2425 */
+static const struct ath5k_ini_rfgain rfgain_2425[] = {
+ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } },
+ { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } },
+ { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } },
+ { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } },
+ { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } },
+ { AR5K_RF_GAIN(8), { 0x00000000, 0x00000188 } },
+ { AR5K_RF_GAIN(9), { 0x00000000, 0x000001c8 } },
+ { AR5K_RF_GAIN(10), { 0x00000000, 0x00000008 } },
+ { AR5K_RF_GAIN(11), { 0x00000000, 0x00000048 } },
+ { AR5K_RF_GAIN(12), { 0x00000000, 0x00000088 } },
+ { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } },
+ { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } },
+ { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } },
+ { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } },
+ { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } },
+ { AR5K_RF_GAIN(18), { 0x00000000, 0x000001b0 } },
+ { AR5K_RF_GAIN(19), { 0x00000000, 0x000001f0 } },
+ { AR5K_RF_GAIN(20), { 0x00000000, 0x00000030 } },
+ { AR5K_RF_GAIN(21), { 0x00000000, 0x00000070 } },
+ { AR5K_RF_GAIN(22), { 0x00000000, 0x00000171 } },
+ { AR5K_RF_GAIN(23), { 0x00000000, 0x000001b1 } },
+ { AR5K_RF_GAIN(24), { 0x00000000, 0x000001f1 } },
+ { AR5K_RF_GAIN(25), { 0x00000000, 0x00000031 } },
+ { AR5K_RF_GAIN(26), { 0x00000000, 0x00000071 } },
+ { AR5K_RF_GAIN(27), { 0x00000000, 0x000001b8 } },
+ { AR5K_RF_GAIN(28), { 0x00000000, 0x000001f8 } },
+ { AR5K_RF_GAIN(29), { 0x00000000, 0x00000038 } },
+ { AR5K_RF_GAIN(30), { 0x00000000, 0x00000078 } },
+ { AR5K_RF_GAIN(31), { 0x00000000, 0x000000b8 } },
+ { AR5K_RF_GAIN(32), { 0x00000000, 0x000001b9 } },
+ { AR5K_RF_GAIN(33), { 0x00000000, 0x000001f9 } },
+ { AR5K_RF_GAIN(34), { 0x00000000, 0x00000039 } },
+ { AR5K_RF_GAIN(35), { 0x00000000, 0x00000079 } },
+ { AR5K_RF_GAIN(36), { 0x00000000, 0x000000b9 } },
+ { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } },
+};
+
+#define AR5K_GAIN_CRN_FIX_BITS_5111 4
+#define AR5K_GAIN_CRN_FIX_BITS_5112 7
+#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
+#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
+#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
+#define AR5K_GAIN_CCK_PROBE_CORR 5
+#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
+#define AR5K_GAIN_STEP_COUNT 10
+
+/* Check if our current measurement is inside our
+ * current variable attenuation window */
+#define AR5K_GAIN_CHECK_ADJUST(_g) \
+ ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
+
+struct ath5k_gain_opt_step {
+ s8 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
+ s8 gos_gain;
+};
+
+struct ath5k_gain_opt {
+ u8 go_default;
+ u8 go_steps_count;
+ const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT];
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Tx clip PHY register
+ * 2) PWD 90 RF register
+ * 3) PWD 84 RF register
+ * 4) RFGainSel RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5111 = {
+ 4,
+ 9,
+ {
+ { { 4, 1, 1, 1 }, 6 },
+ { { 4, 0, 1, 1 }, 4 },
+ { { 3, 1, 1, 1 }, 3 },
+ { { 4, 0, 0, 1 }, 1 },
+ { { 4, 1, 1, 0 }, 0 },
+ { { 4, 0, 1, 0 }, -2 },
+ { { 3, 1, 1, 0 }, -3 },
+ { { 4, 0, 0, 0 }, -4 },
+ { { 2, 1, 1, 0 }, -6 }
+ }
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Mixgain ovr RF register
+ * 2) PWD 138 RF register
+ * 3) PWD 137 RF register
+ * 4) PWD 136 RF register
+ * 5) PWD 132 RF register
+ * 6) PWD 131 RF register
+ * 7) PWD 130 RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5112 = {
+ 1,
+ 8,
+ {
+ { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
+ { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
+ { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
+ { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
+ { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
+ { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
+ { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
+ { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
+ }
+};
+
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile
index 1209d14613a..1a4d4eab6fe 100644
--- a/drivers/net/wireless/ath9k/Makefile
+++ b/drivers/net/wireless/ath9k/Makefile
@@ -9,8 +9,11 @@ ath9k-y += hw.o \
main.o \
recv.o \
xmit.o \
+ virtual.o \
rc.o
+ath9k-$(CONFIG_PCI) += pci.o
+ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
obj-$(CONFIG_ATH9K) += ath9k.o
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c
new file mode 100644
index 00000000000..00cc7bb01f2
--- /dev/null
+++ b/drivers/net/wireless/ath9k/ahb.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+#include "ath9k.h"
+
+/* return bus cachesize in 4B word units */
+static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
+{
+ *csz = L1_CACHE_BYTES >> 2;
+}
+
+static void ath_ahb_cleanup(struct ath_softc *sc)
+{
+ iounmap(sc->mem);
+}
+
+static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+ struct ath_softc *sc = ah->ah_sc;
+ struct platform_device *pdev = to_platform_device(sc->dev);
+ struct ath9k_platform_data *pdata;
+
+ pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
+ if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "%s: flash read failed, offset %08x is out of range\n",
+ __func__, off);
+ return false;
+ }
+
+ *data = pdata->eeprom_data[off];
+ return true;
+}
+
+static struct ath_bus_ops ath_ahb_bus_ops = {
+ .read_cachesize = ath_ahb_read_cachesize,
+ .cleanup = ath_ahb_cleanup,
+
+ .eeprom_read = ath_ahb_eeprom_read,
+};
+
+static int ath_ahb_probe(struct platform_device *pdev)
+{
+ void __iomem *mem;
+ struct ath_wiphy *aphy;
+ struct ath_softc *sc;
+ struct ieee80211_hw *hw;
+ struct resource *res;
+ int irq;
+ int ret = 0;
+ struct ath_hw *ah;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "no platform data specified\n");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no memory resource found\n");
+ ret = -ENXIO;
+ goto err_out;
+ }
+
+ mem = ioremap_nocache(res->start, res->end - res->start + 1);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no IRQ resource found\n");
+ ret = -ENXIO;
+ goto err_iounmap;
+ }
+
+ irq = res->start;
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+ sizeof(struct ath_softc), &ath9k_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+ ret = -ENOMEM;
+ goto err_iounmap;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ platform_set_drvdata(pdev, hw);
+
+ aphy = hw->priv;
+ sc = (struct ath_softc *) (aphy + 1);
+ aphy->sc = sc;
+ aphy->hw = hw;
+ sc->pri_wiphy = aphy;
+ sc->hw = hw;
+ sc->dev = &pdev->dev;
+ sc->mem = mem;
+ sc->bus_ops = &ath_ahb_bus_ops;
+ sc->irq = irq;
+
+ ret = ath_attach(AR5416_AR9100_DEVID, sc);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
+ ret = -ENODEV;
+ goto err_free_hw;
+ }
+
+ ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret);
+ ret = -EIO;
+ goto err_detach;
+ }
+
+ ah = sc->sc_ah;
+ printk(KERN_INFO
+ "%s: Atheros AR%s MAC/BB Rev:%x, "
+ "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
+ wiphy_name(hw->wiphy),
+ ath_mac_bb_name(ah->hw_version.macVersion),
+ ah->hw_version.macRev,
+ ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+ ah->hw_version.phyRev,
+ (unsigned long)mem, irq);
+
+ return 0;
+
+ err_detach:
+ ath_detach(sc);
+ err_free_hw:
+ ieee80211_free_hw(hw);
+ platform_set_drvdata(pdev, NULL);
+ err_iounmap:
+ iounmap(mem);
+ err_out:
+ return ret;
+}
+
+static int ath_ahb_remove(struct platform_device *pdev)
+{
+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+
+ if (hw) {
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ ath_cleanup(sc);
+ platform_set_drvdata(pdev, NULL);
+ }
+
+ return 0;
+}
+
+static struct platform_driver ath_ahb_driver = {
+ .probe = ath_ahb_probe,
+ .remove = ath_ahb_remove,
+ .driver = {
+ .name = "ath9k",
+ .owner = THIS_MODULE,
+ },
+};
+
+int ath_ahb_init(void)
+{
+ return platform_driver_register(&ath_ahb_driver);
+}
+
+void ath_ahb_exit(void)
+{
+ platform_driver_unregister(&ath_ahb_driver);
+}
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c
index 251e2d9a7a4..a39eb760cbb 100644
--- a/drivers/net/wireless/ath9k/ani.c
+++ b/drivers/net/wireless/ath9k/ani.c
@@ -14,23 +14,19 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
-static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
+static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
- for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
- if (ahp->ah_ani[i].c.channel == chan->channel)
+ for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+ if (ah->ani[i].c &&
+ ah->ani[i].c->channel == chan->channel)
return i;
- if (ahp->ah_ani[i].c.channel == 0) {
- ahp->ah_ani[i].c.channel = chan->channel;
- ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
+ if (ah->ani[i].c == NULL) {
+ ah->ani[i].c = chan;
return i;
}
}
@@ -41,41 +37,40 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
return 0;
}
-static bool ath9k_hw_ani_control(struct ath_hal *ah,
+static bool ath9k_hw_ani_control(struct ath_hw *ah,
enum ath9k_ani_cmd cmd, int param)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416AniState *aniState = ahp->ah_curani;
+ struct ar5416AniState *aniState = ah->curani;
- switch (cmd & ahp->ah_ani_function) {
+ switch (cmd & ah->ani_function) {
case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
u32 level = param;
- if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
+ if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"level out of range (%u > %u)\n",
level,
- (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired));
+ (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
return false;
}
REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
AR_PHY_DESIRED_SZ_TOT_DES,
- ahp->ah_totalSizeDesired[level]);
+ ah->totalSizeDesired[level]);
REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
AR_PHY_AGC_CTL1_COARSE_LOW,
- ahp->ah_coarseLow[level]);
+ ah->coarse_low[level]);
REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
AR_PHY_AGC_CTL1_COARSE_HIGH,
- ahp->ah_coarseHigh[level]);
+ ah->coarse_high[level]);
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
AR_PHY_FIND_SIG_FIRPWR,
- ahp->ah_firpwr[level]);
+ ah->firpwr[level]);
if (level > aniState->noiseImmunityLevel)
- ahp->ah_stats.ast_ani_niup++;
+ ah->stats.ast_ani_niup++;
else if (level < aniState->noiseImmunityLevel)
- ahp->ah_stats.ast_ani_nidown++;
+ ah->stats.ast_ani_nidown++;
aniState->noiseImmunityLevel = level;
break;
}
@@ -129,9 +124,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
if (!on != aniState->ofdmWeakSigDetectOff) {
if (on)
- ahp->ah_stats.ast_ani_ofdmon++;
+ ah->stats.ast_ani_ofdmon++;
else
- ahp->ah_stats.ast_ani_ofdmoff++;
+ ah->stats.ast_ani_ofdmoff++;
aniState->ofdmWeakSigDetectOff = !on;
}
break;
@@ -145,9 +140,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
weakSigThrCck[high]);
if (high != aniState->cckWeakSigThreshold) {
if (high)
- ahp->ah_stats.ast_ani_cckhigh++;
+ ah->stats.ast_ani_cckhigh++;
else
- ahp->ah_stats.ast_ani_ccklow++;
+ ah->stats.ast_ani_ccklow++;
aniState->cckWeakSigThreshold = high;
}
break;
@@ -167,9 +162,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
AR_PHY_FIND_SIG_FIRSTEP,
firstep[level]);
if (level > aniState->firstepLevel)
- ahp->ah_stats.ast_ani_stepup++;
+ ah->stats.ast_ani_stepup++;
else if (level < aniState->firstepLevel)
- ahp->ah_stats.ast_ani_stepdown++;
+ ah->stats.ast_ani_stepdown++;
aniState->firstepLevel = level;
break;
}
@@ -190,9 +185,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
AR_PHY_TIMING5_CYCPWR_THR1,
cycpwrThr1[level]);
if (level > aniState->spurImmunityLevel)
- ahp->ah_stats.ast_ani_spurup++;
+ ah->stats.ast_ani_spurup++;
else if (level < aniState->spurImmunityLevel)
- ahp->ah_stats.ast_ani_spurdown++;
+ ah->stats.ast_ani_spurdown++;
aniState->spurImmunityLevel = level;
break;
}
@@ -223,7 +218,7 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
return true;
}
-static void ath9k_hw_update_mibstats(struct ath_hal *ah,
+static void ath9k_hw_update_mibstats(struct ath_hw *ah,
struct ath9k_mib_stats *stats)
{
stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
@@ -233,18 +228,17 @@ static void ath9k_hw_update_mibstats(struct ath_hal *ah,
stats->beacons += REG_READ(ah, AR_BEACON_CNT);
}
-static void ath9k_ani_restart(struct ath_hal *ah)
+static void ath9k_ani_restart(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
if (!DO_ANI(ah))
return;
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
aniState->listenTime = 0;
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
aniState->ofdmPhyErrBase = 0;
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
@@ -270,24 +264,22 @@ static void ath9k_ani_restart(struct ath_hal *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
}
aniState->ofdmPhyErrCount = 0;
aniState->cckPhyErrCount = 0;
}
-static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
struct ar5416AniState *aniState;
- enum wireless_mode mode;
int32_t rssi;
if (!DO_ANI(ah))
return;
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
@@ -303,14 +295,14 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
}
}
- if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+ if (ah->opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1);
}
return;
}
- rssi = BEACON_RSSI(ahp);
+ rssi = BEACON_RSSI(ah);
if (rssi > aniState->rssiThrHigh) {
if (!aniState->ofdmWeakSigDetectOff) {
if (ath9k_hw_ani_control(ah,
@@ -336,8 +328,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
aniState->firstepLevel + 1);
return;
} else {
- mode = ath9k_hw_chan2wmode(ah, chan);
- if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+ if (conf->channel->band == IEEE80211_BAND_2GHZ) {
if (!aniState->ofdmWeakSigDetectOff)
ath9k_hw_ani_control(ah,
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@@ -350,39 +341,36 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
}
}
-static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
struct ar5416AniState *aniState;
- enum wireless_mode mode;
int32_t rssi;
if (!DO_ANI(ah))
return;
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1)) {
return;
}
}
- if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+ if (ah->opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1);
}
return;
}
- rssi = BEACON_RSSI(ahp);
+ rssi = BEACON_RSSI(ah);
if (rssi > aniState->rssiThrLow) {
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1);
} else {
- mode = ath9k_hw_chan2wmode(ah, chan);
- if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+ if (conf->channel->band == IEEE80211_BAND_2GHZ) {
if (aniState->firstepLevel > 0)
ath9k_hw_ani_control(ah,
ATH9K_ANI_FIRSTEP_LEVEL, 0);
@@ -390,22 +378,21 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
}
}
-static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
+static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
int32_t rssi;
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
- if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+ if (ah->opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel > 0) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel - 1))
return;
}
} else {
- rssi = BEACON_RSSI(ahp);
+ rssi = BEACON_RSSI(ah);
if (rssi > aniState->rssiThrHigh) {
/* XXX: Handle me */
} else if (rssi > aniState->rssiThrLow) {
@@ -444,9 +431,8 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
}
}
-static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
+static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
u32 txFrameCount, rxFrameCount, cycleCount;
int32_t listenTime;
@@ -455,11 +441,11 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
rxFrameCount = REG_READ(ah, AR_RFCNT);
cycleCount = REG_READ(ah, AR_CCCNT);
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
listenTime = 0;
- ahp->ah_stats.ast_ani_lzero++;
+ ah->stats.ast_ani_lzero++;
} else {
int32_t ccdelta = cycleCount - aniState->cycleCount;
int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
@@ -473,25 +459,24 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
return listenTime;
}
-void ath9k_ani_reset(struct ath_hal *ah)
+void ath9k_ani_reset(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ath9k_channel *chan = ah->curchan;
int index;
if (!DO_ANI(ah))
return;
index = ath9k_hw_get_ani_channel_idx(ah, chan);
- aniState = &ahp->ah_ani[index];
- ahp->ah_curani = aniState;
+ aniState = &ah->ani[index];
+ ah->curani = aniState;
- if (DO_ANI(ah) && ah->ah_opmode != NL80211_IFTYPE_STATION
- && ah->ah_opmode != NL80211_IFTYPE_ADHOC) {
+ if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
+ && ah->opmode != NL80211_IFTYPE_ADHOC) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
- "Reset ANI state opmode %u\n", ah->ah_opmode);
- ahp->ah_stats.ast_ani_reset++;
+ "Reset ANI state opmode %u\n", ah->opmode);
+ ah->stats.ast_ani_reset++;
ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
@@ -504,15 +489,15 @@ void ath9k_ani_reset(struct ath_hal *ah)
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
ATH9K_RX_FILTER_PHYERR);
- if (ah->ah_opmode == NL80211_IFTYPE_AP) {
- ahp->ah_curani->ofdmTrigHigh =
- ah->ah_config.ofdm_trig_high;
- ahp->ah_curani->ofdmTrigLow =
- ah->ah_config.ofdm_trig_low;
- ahp->ah_curani->cckTrigHigh =
- ah->ah_config.cck_trig_high;
- ahp->ah_curani->cckTrigLow =
- ah->ah_config.cck_trig_low;
+ if (ah->opmode == NL80211_IFTYPE_AP) {
+ ah->curani->ofdmTrigHigh =
+ ah->config.ofdm_trig_high;
+ ah->curani->ofdmTrigLow =
+ ah->config.ofdm_trig_low;
+ ah->curani->cckTrigHigh =
+ ah->config.cck_trig_high;
+ ah->curani->cckTrigLow =
+ ah->config.cck_trig_low;
}
ath9k_ani_restart(ah);
return;
@@ -533,7 +518,7 @@ void ath9k_ani_reset(struct ath_hal *ah)
if (aniState->firstepLevel != 0)
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel);
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
~ATH9K_RX_FILTER_PHYERR);
ath9k_ani_restart(ah);
@@ -547,31 +532,33 @@ void ath9k_ani_reset(struct ath_hal *ah)
}
}
-void ath9k_hw_ani_monitor(struct ath_hal *ah,
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
const struct ath9k_node_stats *stats,
struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
int32_t listenTime;
- aniState = ahp->ah_curani;
- ahp->ah_stats.ast_nodestats = *stats;
+ if (!DO_ANI(ah))
+ return;
+
+ aniState = ah->curani;
+ ah->stats.ast_nodestats = *stats;
listenTime = ath9k_hw_ani_get_listen_time(ah);
if (listenTime < 0) {
- ahp->ah_stats.ast_ani_lneg++;
+ ah->stats.ast_ani_lneg++;
ath9k_ani_restart(ah);
return;
}
aniState->listenTime += listenTime;
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
u32 phyCnt1, phyCnt2;
u32 ofdmPhyErrCnt, cckPhyErrCnt;
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
@@ -604,27 +591,24 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah,
}
ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
- ahp->ah_stats.ast_ani_ofdmerrs +=
+ ah->stats.ast_ani_ofdmerrs +=
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
- ahp->ah_stats.ast_ani_cckerrs +=
+ ah->stats.ast_ani_cckerrs +=
cckPhyErrCnt - aniState->cckPhyErrCount;
aniState->cckPhyErrCount = cckPhyErrCnt;
}
- if (!DO_ANI(ah))
- return;
-
- if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
+ if (aniState->listenTime > 5 * ah->aniperiod) {
if (aniState->ofdmPhyErrCount <= aniState->listenTime *
aniState->ofdmTrigLow / 1000 &&
aniState->cckPhyErrCount <= aniState->listenTime *
aniState->cckTrigLow / 1000)
ath9k_hw_ani_lower_immunity(ah);
ath9k_ani_restart(ah);
- } else if (aniState->listenTime > ahp->ah_aniPeriod) {
+ } else if (aniState->listenTime > ah->aniperiod) {
if (aniState->ofdmPhyErrCount > aniState->listenTime *
aniState->ofdmTrigHigh / 1000) {
ath9k_hw_ani_ofdm_err_trigger(ah);
@@ -638,20 +622,16 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah,
}
}
-bool ath9k_hw_phycounters(struct ath_hal *ah)
+bool ath9k_hw_phycounters(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- return ahp->ah_hasHwPhyCounters ? true : false;
+ return ah->has_hw_phycounters ? true : false;
}
-void ath9k_enable_mib_counters(struct ath_hal *ah)
+void ath9k_enable_mib_counters(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
REG_WRITE(ah, AR_FILT_OFDM, 0);
REG_WRITE(ah, AR_FILT_CCK, 0);
@@ -662,21 +642,18 @@ void ath9k_enable_mib_counters(struct ath_hal *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
}
-void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
+/* Freeze the MIB counters, get the stats and then clear them */
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
-
- REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
-
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
-
+ REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+ REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
REG_WRITE(ah, AR_FILT_OFDM, 0);
REG_WRITE(ah, AR_FILT_CCK, 0);
}
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
u32 *rxc_pcnt,
u32 *rxf_pcnt,
u32 *txf_pcnt)
@@ -721,10 +698,9 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
* any of the MIB counters overflow/trigger so don't assume we're
* here because a PHY error counter triggered.
*/
-void ath9k_hw_procmibevent(struct ath_hal *ah,
+void ath9k_hw_procmibevent(struct ath_hw *ah,
const struct ath9k_node_stats *stats)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 phyCnt1, phyCnt2;
/* Reset these counters regardless */
@@ -734,8 +710,8 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
/* Clear the mib counters and save them in the stats */
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
- ahp->ah_stats.ast_nodestats = *stats;
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+ ah->stats.ast_nodestats = *stats;
if (!DO_ANI(ah))
return;
@@ -745,17 +721,17 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
- struct ar5416AniState *aniState = ahp->ah_curani;
+ struct ar5416AniState *aniState = ah->curani;
u32 ofdmPhyErrCnt, cckPhyErrCnt;
/* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
- ahp->ah_stats.ast_ani_ofdmerrs +=
+ ah->stats.ast_ani_ofdmerrs +=
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
- ahp->ah_stats.ast_ani_cckerrs +=
+ ah->stats.ast_ani_cckerrs +=
cckPhyErrCnt - aniState->cckPhyErrCount;
aniState->cckPhyErrCount = cckPhyErrCnt;
@@ -774,9 +750,8 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
}
}
-void ath9k_hw_ani_setup(struct ath_hal *ah)
+void ath9k_hw_ani_setup(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
@@ -785,66 +760,63 @@ void ath9k_hw_ani_setup(struct ath_hal *ah)
const int firpwr[] = { -78, -78, -78, -78, -80 };
for (i = 0; i < 5; i++) {
- ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
- ahp->ah_coarseHigh[i] = coarseHigh[i];
- ahp->ah_coarseLow[i] = coarseLow[i];
- ahp->ah_firpwr[i] = firpwr[i];
+ ah->totalSizeDesired[i] = totalSizeDesired[i];
+ ah->coarse_high[i] = coarseHigh[i];
+ ah->coarse_low[i] = coarseLow[i];
+ ah->firpwr[i] = firpwr[i];
}
}
-void ath9k_hw_ani_attach(struct ath_hal *ah)
+void ath9k_hw_ani_attach(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
- ahp->ah_hasHwPhyCounters = 1;
-
- memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
- for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
- ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
- ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
- ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
- ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
- ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
- ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
- ahp->ah_ani[i].ofdmWeakSigDetectOff =
+ ah->has_hw_phycounters = 1;
+
+ memset(ah->ani, 0, sizeof(ah->ani));
+ for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+ ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
+ ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
+ ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
+ ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
+ ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+ ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+ ah->ani[i].ofdmWeakSigDetectOff =
!ATH9K_ANI_USE_OFDM_WEAK_SIG;
- ahp->ah_ani[i].cckWeakSigThreshold =
+ ah->ani[i].cckWeakSigThreshold =
ATH9K_ANI_CCK_WEAK_SIG_THR;
- ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
- ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
- if (ahp->ah_hasHwPhyCounters) {
- ahp->ah_ani[i].ofdmPhyErrBase =
+ ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+ ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+ if (ah->has_hw_phycounters) {
+ ah->ani[i].ofdmPhyErrBase =
AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
- ahp->ah_ani[i].cckPhyErrBase =
+ ah->ani[i].cckPhyErrBase =
AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
}
}
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Setting OfdmErrBase = 0x%08x\n",
- ahp->ah_ani[0].ofdmPhyErrBase);
+ ah->ani[0].ofdmPhyErrBase);
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
- ahp->ah_ani[0].cckPhyErrBase);
+ ah->ani[0].cckPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
+ REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
+ REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
ath9k_enable_mib_counters(ah);
}
- ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
- if (ah->ah_config.enable_ani)
- ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
+ ah->aniperiod = ATH9K_ANI_PERIOD;
+ if (ah->config.enable_ani)
+ ah->proc_phyerr |= HAL_PROCESS_ANI;
}
-void ath9k_hw_ani_detach(struct ath_hal *ah)
+void ath9k_hw_ani_detach(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
ath9k_hw_disable_mib_counters(ah);
REG_WRITE(ah, AR_PHY_ERR_1, 0);
REG_WRITE(ah, AR_PHY_ERR_2, 0);
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath9k/ani.h
new file mode 100644
index 00000000000..7315761f6d7
--- /dev/null
+++ b/drivers/net/wireless/ath9k/ani.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ANI_H
+#define ANI_H
+
+#define HAL_PROCESS_ANI 0x00000001
+#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
+
+#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
+
+#define HAL_EP_RND(x, mul) \
+ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define BEACON_RSSI(ahp) \
+ HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi, \
+ ATH9K_RSSI_EP_MULTIPLIER)
+
+#define ATH9K_ANI_OFDM_TRIG_HIGH 500
+#define ATH9K_ANI_OFDM_TRIG_LOW 200
+#define ATH9K_ANI_CCK_TRIG_HIGH 200
+#define ATH9K_ANI_CCK_TRIG_LOW 100
+#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
+#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
+#define ATH9K_ANI_CCK_WEAK_SIG_THR false
+#define ATH9K_ANI_SPUR_IMMUNE_LVL 7
+#define ATH9K_ANI_FIRSTEP_LVL 0
+#define ATH9K_ANI_RSSI_THR_HIGH 40
+#define ATH9K_ANI_RSSI_THR_LOW 7
+#define ATH9K_ANI_PERIOD 100
+
+#define HAL_NOISE_IMMUNE_MAX 4
+#define HAL_SPUR_IMMUNE_MAX 7
+#define HAL_FIRST_STEP_MAX 2
+
+enum ath9k_ani_cmd {
+ ATH9K_ANI_PRESENT = 0x1,
+ ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
+ ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
+ ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
+ ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
+ ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
+ ATH9K_ANI_MODE = 0x40,
+ ATH9K_ANI_PHYERR_RESET = 0x80,
+ ATH9K_ANI_ALL = 0xff
+};
+
+struct ath9k_mib_stats {
+ u32 ackrcv_bad;
+ u32 rts_bad;
+ u32 rts_good;
+ u32 fcs_bad;
+ u32 beacons;
+};
+
+struct ath9k_node_stats {
+ u32 ns_avgbrssi;
+ u32 ns_avgrssi;
+ u32 ns_avgtxrssi;
+ u32 ns_avgtxrate;
+};
+
+struct ar5416AniState {
+ struct ath9k_channel *c;
+ u8 noiseImmunityLevel;
+ u8 spurImmunityLevel;
+ u8 firstepLevel;
+ u8 ofdmWeakSigDetectOff;
+ u8 cckWeakSigThreshold;
+ u32 listenTime;
+ u32 ofdmTrigHigh;
+ u32 ofdmTrigLow;
+ int32_t cckTrigHigh;
+ int32_t cckTrigLow;
+ int32_t rssiThrLow;
+ int32_t rssiThrHigh;
+ u32 noiseFloor;
+ u32 txFrameCount;
+ u32 rxFrameCount;
+ u32 cycleCount;
+ u32 ofdmPhyErrCount;
+ u32 cckPhyErrCount;
+ u32 ofdmPhyErrBase;
+ u32 cckPhyErrBase;
+ int16_t pktRssi[2];
+ int16_t ofdmErrRssi[2];
+ int16_t cckErrRssi[2];
+};
+
+struct ar5416Stats {
+ u32 ast_ani_niup;
+ u32 ast_ani_nidown;
+ u32 ast_ani_spurup;
+ u32 ast_ani_spurdown;
+ u32 ast_ani_ofdmon;
+ u32 ast_ani_ofdmoff;
+ u32 ast_ani_cckhigh;
+ u32 ast_ani_ccklow;
+ u32 ast_ani_stepup;
+ u32 ast_ani_stepdown;
+ u32 ast_ani_ofdmerrs;
+ u32 ast_ani_cckerrs;
+ u32 ast_ani_reset;
+ u32 ast_ani_lzero;
+ u32 ast_ani_lneg;
+ struct ath9k_mib_stats ast_mibstats;
+ struct ath9k_node_stats ast_nodestats;
+};
+#define ah_mibStats stats.ast_mibstats
+
+void ath9k_ani_reset(struct ath_hw *ah);
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
+ const struct ath9k_node_stats *stats,
+ struct ath9k_channel *chan);
+bool ath9k_hw_phycounters(struct ath_hw *ah);
+void ath9k_enable_mib_counters(struct ath_hw *ah);
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
+ u32 *rxf_pcnt, u32 *txf_pcnt);
+void ath9k_hw_procmibevent(struct ath_hw *ah,
+ const struct ath9k_node_stats *stats);
+void ath9k_hw_ani_setup(struct ath_hw *ah);
+void ath9k_hw_ani_attach(struct ath_hw *ah);
+void ath9k_hw_ani_detach(struct ath_hw *ah);
+
+#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index d2781350295..b64be8e9a69 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -17,1041 +17,744 @@
#ifndef ATH9K_H
#define ATH9K_H
-#include <linux/io.h>
-
-#define ATHEROS_VENDOR_ID 0x168c
-
-#define AR5416_DEVID_PCI 0x0023
-#define AR5416_DEVID_PCIE 0x0024
-#define AR9160_DEVID_PCI 0x0027
-#define AR9280_DEVID_PCI 0x0029
-#define AR9280_DEVID_PCIE 0x002a
-#define AR9285_DEVID_PCIE 0x002b
-
-#define AR5416_AR9100_DEVID 0x000b
-
-#define AR_SUBVENDOR_ID_NOG 0x0e11
-#define AR_SUBVENDOR_ID_NEW_A 0x7065
-
-#define ATH9K_TXERR_XRETRY 0x01
-#define ATH9K_TXERR_FILT 0x02
-#define ATH9K_TXERR_FIFO 0x04
-#define ATH9K_TXERR_XTXOP 0x08
-#define ATH9K_TXERR_TIMER_EXPIRED 0x10
-
-#define ATH9K_TX_BA 0x01
-#define ATH9K_TX_PWRMGMT 0x02
-#define ATH9K_TX_DESC_CFG_ERR 0x04
-#define ATH9K_TX_DATA_UNDERRUN 0x08
-#define ATH9K_TX_DELIM_UNDERRUN 0x10
-#define ATH9K_TX_SW_ABORTED 0x40
-#define ATH9K_TX_SW_FILTERED 0x80
-
-#define NBBY 8
-
-struct ath_tx_status {
- u32 ts_tstamp;
- u16 ts_seqnum;
- u8 ts_status;
- u8 ts_ratecode;
- u8 ts_rateindex;
- int8_t ts_rssi;
- u8 ts_shortretry;
- u8 ts_longretry;
- u8 ts_virtcol;
- u8 ts_antenna;
- u8 ts_flags;
- int8_t ts_rssi_ctl0;
- int8_t ts_rssi_ctl1;
- int8_t ts_rssi_ctl2;
- int8_t ts_rssi_ext0;
- int8_t ts_rssi_ext1;
- int8_t ts_rssi_ext2;
- u8 pad[3];
- u32 ba_low;
- u32 ba_high;
- u32 evm0;
- u32 evm1;
- u32 evm2;
-};
-
-struct ath_rx_status {
- u32 rs_tstamp;
- u16 rs_datalen;
- u8 rs_status;
- u8 rs_phyerr;
- int8_t rs_rssi;
- u8 rs_keyix;
- u8 rs_rate;
- u8 rs_antenna;
- u8 rs_more;
- int8_t rs_rssi_ctl0;
- int8_t rs_rssi_ctl1;
- int8_t rs_rssi_ctl2;
- int8_t rs_rssi_ext0;
- int8_t rs_rssi_ext1;
- int8_t rs_rssi_ext2;
- u8 rs_isaggr;
- u8 rs_moreaggr;
- u8 rs_num_delims;
- u8 rs_flags;
- u32 evm0;
- u32 evm1;
- u32 evm2;
-};
-
-#define ATH9K_RXERR_CRC 0x01
-#define ATH9K_RXERR_PHY 0x02
-#define ATH9K_RXERR_FIFO 0x04
-#define ATH9K_RXERR_DECRYPT 0x08
-#define ATH9K_RXERR_MIC 0x10
-
-#define ATH9K_RX_MORE 0x01
-#define ATH9K_RX_MORE_AGGR 0x02
-#define ATH9K_RX_GI 0x04
-#define ATH9K_RX_2040 0x08
-#define ATH9K_RX_DELIM_CRC_PRE 0x10
-#define ATH9K_RX_DELIM_CRC_POST 0x20
-#define ATH9K_RX_DECRYPT_BUSY 0x40
-
-#define ATH9K_RXKEYIX_INVALID ((u8)-1)
-#define ATH9K_TXKEYIX_INVALID ((u32)-1)
-
-struct ath_desc {
- u32 ds_link;
- u32 ds_data;
- u32 ds_ctl0;
- u32 ds_ctl1;
- u32 ds_hw[20];
- union {
- struct ath_tx_status tx;
- struct ath_rx_status rx;
- void *stats;
- } ds_us;
- void *ds_vdata;
-} __packed;
-
-#define ds_txstat ds_us.tx
-#define ds_rxstat ds_us.rx
-#define ds_stat ds_us.stats
-
-#define ATH9K_TXDESC_CLRDMASK 0x0001
-#define ATH9K_TXDESC_NOACK 0x0002
-#define ATH9K_TXDESC_RTSENA 0x0004
-#define ATH9K_TXDESC_CTSENA 0x0008
-/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
- * the descriptor its marked on. We take a tx interrupt to reap
- * descriptors when the h/w hits an EOL condition or
- * when the descriptor is specifically marked to generate
- * an interrupt with this flag. Descriptors should be
- * marked periodically to insure timely replenishing of the
- * supply needed for sending frames. Defering interrupts
- * reduces system load and potentially allows more concurrent
- * work to be done but if done to aggressively can cause
- * senders to backup. When the hardware queue is left too
- * large rate control information may also be too out of
- * date. An Alternative for this is TX interrupt mitigation
- * but this needs more testing. */
-#define ATH9K_TXDESC_INTREQ 0x0010
-#define ATH9K_TXDESC_VEOL 0x0020
-#define ATH9K_TXDESC_EXT_ONLY 0x0040
-#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
-#define ATH9K_TXDESC_VMF 0x0100
-#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
-#define ATH9K_TXDESC_CAB 0x0400
-
-#define ATH9K_RXDESC_INTREQ 0x0020
-
-enum wireless_mode {
- ATH9K_MODE_11A = 0,
- ATH9K_MODE_11B = 2,
- ATH9K_MODE_11G = 3,
- ATH9K_MODE_11NA_HT20 = 6,
- ATH9K_MODE_11NG_HT20 = 7,
- ATH9K_MODE_11NA_HT40PLUS = 8,
- ATH9K_MODE_11NA_HT40MINUS = 9,
- ATH9K_MODE_11NG_HT40PLUS = 10,
- ATH9K_MODE_11NG_HT40MINUS = 11,
- ATH9K_MODE_MAX
-};
-
-enum ath9k_hw_caps {
- ATH9K_HW_CAP_CHAN_SPREAD = BIT(0),
- ATH9K_HW_CAP_MIC_AESCCM = BIT(1),
- ATH9K_HW_CAP_MIC_CKIP = BIT(2),
- ATH9K_HW_CAP_MIC_TKIP = BIT(3),
- ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4),
- ATH9K_HW_CAP_CIPHER_CKIP = BIT(5),
- ATH9K_HW_CAP_CIPHER_TKIP = BIT(6),
- ATH9K_HW_CAP_VEOL = BIT(7),
- ATH9K_HW_CAP_BSSIDMASK = BIT(8),
- ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9),
- ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10),
- ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11),
- ATH9K_HW_CAP_HT = BIT(12),
- ATH9K_HW_CAP_GTT = BIT(13),
- ATH9K_HW_CAP_FASTCC = BIT(14),
- ATH9K_HW_CAP_RFSILENT = BIT(15),
- ATH9K_HW_CAP_WOW = BIT(16),
- ATH9K_HW_CAP_CST = BIT(17),
- ATH9K_HW_CAP_ENHANCEDPM = BIT(18),
- ATH9K_HW_CAP_AUTOSLEEP = BIT(19),
- ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20),
- ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21),
-};
-
-enum ath9k_capability_type {
- ATH9K_CAP_CIPHER = 0,
- ATH9K_CAP_TKIP_MIC,
- ATH9K_CAP_TKIP_SPLIT,
- ATH9K_CAP_PHYCOUNTERS,
- ATH9K_CAP_DIVERSITY,
- ATH9K_CAP_TXPOW,
- ATH9K_CAP_PHYDIAG,
- ATH9K_CAP_MCAST_KEYSRCH,
- ATH9K_CAP_TSF_ADJUST,
- ATH9K_CAP_WME_TKIPMIC,
- ATH9K_CAP_RFSILENT,
- ATH9K_CAP_ANT_CFG_2GHZ,
- ATH9K_CAP_ANT_CFG_5GHZ
-};
-
-struct ath9k_hw_capabilities {
- u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
- DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
- u16 total_queues;
- u16 keycache_size;
- u16 low_5ghz_chan, high_5ghz_chan;
- u16 low_2ghz_chan, high_2ghz_chan;
- u16 num_mr_retries;
- u16 rts_aggr_limit;
- u8 tx_chainmask;
- u8 rx_chainmask;
- u16 tx_triglevel_max;
- u16 reg_cap;
- u8 num_gpio_pins;
- u8 num_antcfg_2ghz;
- u8 num_antcfg_5ghz;
-};
-
-struct ath9k_ops_config {
- int dma_beacon_response_time;
- int sw_beacon_response_time;
- int additional_swba_backoff;
- int ack_6mb;
- int cwm_ignore_extcca;
- u8 pcie_powersave_enable;
- u8 pcie_l1skp_enable;
- u8 pcie_clock_req;
- u32 pcie_waen;
- int pcie_power_reset;
- u8 pcie_restore;
- u8 analog_shiftreg;
- u8 ht_enable;
- u32 ofdm_trig_low;
- u32 ofdm_trig_high;
- u32 cck_trig_high;
- u32 cck_trig_low;
- u32 enable_ani;
- u8 noise_immunity_level;
- u32 ofdm_weaksignal_det;
- u32 cck_weaksignal_thr;
- u8 spur_immunity_level;
- u8 firstep_level;
- int8_t rssi_thr_high;
- int8_t rssi_thr_low;
- u16 diversity_control;
- u16 antenna_switch_swap;
- int serialize_regmode;
- int intr_mitigation;
-#define SPUR_DISABLE 0
-#define SPUR_ENABLE_IOCTL 1
-#define SPUR_ENABLE_EEPROM 2
-#define AR_EEPROM_MODAL_SPURS 5
-#define AR_SPUR_5413_1 1640
-#define AR_SPUR_5413_2 1200
-#define AR_NO_SPUR 0x8000
-#define AR_BASE_FREQ_2GHZ 2300
-#define AR_BASE_FREQ_5GHZ 4900
-#define AR_SPUR_FEEQ_BOUND_HT40 19
-#define AR_SPUR_FEEQ_BOUND_HT20 10
- int spurmode;
- u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
-};
-
-enum ath9k_tx_queue {
- ATH9K_TX_QUEUE_INACTIVE = 0,
- ATH9K_TX_QUEUE_DATA,
- ATH9K_TX_QUEUE_BEACON,
- ATH9K_TX_QUEUE_CAB,
- ATH9K_TX_QUEUE_UAPSD,
- ATH9K_TX_QUEUE_PSPOLL
-};
-
-#define ATH9K_NUM_TX_QUEUES 10
-
-enum ath9k_tx_queue_subtype {
- ATH9K_WME_AC_BK = 0,
- ATH9K_WME_AC_BE,
- ATH9K_WME_AC_VI,
- ATH9K_WME_AC_VO,
- ATH9K_WME_UPSD
-};
-
-enum ath9k_tx_queue_flags {
- TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
- TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
- TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
- TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
- TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
- TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
- TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
- TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
- TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
-};
-
-#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
-
-#define ATH9K_DECOMP_MASK_SIZE 128
-#define ATH9K_READY_TIME_LO_BOUND 50
-#define ATH9K_READY_TIME_HI_BOUND 96
-
-enum ath9k_pkt_type {
- ATH9K_PKT_TYPE_NORMAL = 0,
- ATH9K_PKT_TYPE_ATIM,
- ATH9K_PKT_TYPE_PSPOLL,
- ATH9K_PKT_TYPE_BEACON,
- ATH9K_PKT_TYPE_PROBE_RESP,
- ATH9K_PKT_TYPE_CHIRP,
- ATH9K_PKT_TYPE_GRP_POLL,
-};
-
-struct ath9k_tx_queue_info {
- u32 tqi_ver;
- enum ath9k_tx_queue tqi_type;
- enum ath9k_tx_queue_subtype tqi_subtype;
- enum ath9k_tx_queue_flags tqi_qflags;
- u32 tqi_priority;
- u32 tqi_aifs;
- u32 tqi_cwmin;
- u32 tqi_cwmax;
- u16 tqi_shretry;
- u16 tqi_lgretry;
- u32 tqi_cbrPeriod;
- u32 tqi_cbrOverflowLimit;
- u32 tqi_burstTime;
- u32 tqi_readyTime;
- u32 tqi_physCompBuf;
- u32 tqi_intFlags;
-};
-
-enum ath9k_rx_filter {
- ATH9K_RX_FILTER_UCAST = 0x00000001,
- ATH9K_RX_FILTER_MCAST = 0x00000002,
- ATH9K_RX_FILTER_BCAST = 0x00000004,
- ATH9K_RX_FILTER_CONTROL = 0x00000008,
- ATH9K_RX_FILTER_BEACON = 0x00000010,
- ATH9K_RX_FILTER_PROM = 0x00000020,
- ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
- ATH9K_RX_FILTER_PSPOLL = 0x00004000,
- ATH9K_RX_FILTER_PHYERR = 0x00000100,
- ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
-};
-
-enum ath9k_int {
- ATH9K_INT_RX = 0x00000001,
- ATH9K_INT_RXDESC = 0x00000002,
- ATH9K_INT_RXNOFRM = 0x00000008,
- ATH9K_INT_RXEOL = 0x00000010,
- ATH9K_INT_RXORN = 0x00000020,
- ATH9K_INT_TX = 0x00000040,
- ATH9K_INT_TXDESC = 0x00000080,
- ATH9K_INT_TIM_TIMER = 0x00000100,
- ATH9K_INT_TXURN = 0x00000800,
- ATH9K_INT_MIB = 0x00001000,
- ATH9K_INT_RXPHY = 0x00004000,
- ATH9K_INT_RXKCM = 0x00008000,
- ATH9K_INT_SWBA = 0x00010000,
- ATH9K_INT_BMISS = 0x00040000,
- ATH9K_INT_BNR = 0x00100000,
- ATH9K_INT_TIM = 0x00200000,
- ATH9K_INT_DTIM = 0x00400000,
- ATH9K_INT_DTIMSYNC = 0x00800000,
- ATH9K_INT_GPIO = 0x01000000,
- ATH9K_INT_CABEND = 0x02000000,
- ATH9K_INT_CST = 0x10000000,
- ATH9K_INT_GTT = 0x20000000,
- ATH9K_INT_FATAL = 0x40000000,
- ATH9K_INT_GLOBAL = 0x80000000,
- ATH9K_INT_BMISC = ATH9K_INT_TIM |
- ATH9K_INT_DTIM |
- ATH9K_INT_DTIMSYNC |
- ATH9K_INT_CABEND,
- ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
- ATH9K_INT_RXDESC |
- ATH9K_INT_RXEOL |
- ATH9K_INT_RXORN |
- ATH9K_INT_TXURN |
- ATH9K_INT_TXDESC |
- ATH9K_INT_MIB |
- ATH9K_INT_RXPHY |
- ATH9K_INT_RXKCM |
- ATH9K_INT_SWBA |
- ATH9K_INT_BMISS |
- ATH9K_INT_GPIO,
- ATH9K_INT_NOCARD = 0xffffffff
-};
-
-#define ATH9K_RATESERIES_RTS_CTS 0x0001
-#define ATH9K_RATESERIES_2040 0x0002
-#define ATH9K_RATESERIES_HALFGI 0x0004
-
-struct ath9k_11n_rate_series {
- u32 Tries;
- u32 Rate;
- u32 PktDuration;
- u32 ChSel;
- u32 RateFlags;
-};
+#include <linux/etherdevice.h>
+#include <linux/device.h>
+#include <net/mac80211.h>
+#include <linux/leds.h>
+#include <linux/rfkill.h>
+
+#include "hw.h"
+#include "rc.h"
+#include "debug.h"
+
+struct ath_node;
+
+/* Macro to expand scalars to 64-bit objects */
+
+#define ito64(x) (sizeof(x) == 8) ? \
+ (((unsigned long long int)(x)) & (0xff)) : \
+ (sizeof(x) == 16) ? \
+ (((unsigned long long int)(x)) & 0xffff) : \
+ ((sizeof(x) == 32) ? \
+ (((unsigned long long int)(x)) & 0xffffffff) : \
+ (unsigned long long int)(x))
+
+/* increment with wrap-around */
+#define INCR(_l, _sz) do { \
+ (_l)++; \
+ (_l) &= ((_sz) - 1); \
+ } while (0)
+
+/* decrement with wrap-around */
+#define DECR(_l, _sz) do { \
+ (_l)--; \
+ (_l) &= ((_sz) - 1); \
+ } while (0)
+
+#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define ASSERT(exp) do { \
+ if (unlikely(!(exp))) { \
+ BUG(); \
+ } \
+ } while (0)
+
+#define TSF_TO_TU(_h,_l) \
+ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
+
+#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
+
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+struct ath_config {
+ u32 ath_aggr_prot;
+ u16 txpowlimit;
+ u8 cabqReadytime;
+ u8 swBeaconProcess;
+};
+
+/*************************/
+/* Descriptor Management */
+/*************************/
+
+#define ATH_TXBUF_RESET(_bf) do { \
+ (_bf)->bf_status = 0; \
+ (_bf)->bf_lastbf = NULL; \
+ (_bf)->bf_next = NULL; \
+ memset(&((_bf)->bf_state), 0, \
+ sizeof(struct ath_buf_state)); \
+ } while (0)
+
+/**
+ * enum buffer_type - Buffer type flags
+ *
+ * @BUF_HT: Send this buffer using HT capabilities
+ * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
+ * @BUF_AGGR: Indicates whether the buffer can be aggregated
+ * (used in aggregation scheduling)
+ * @BUF_RETRY: Indicates whether the buffer is retried
+ * @BUF_XRETRY: To denote excessive retries of the buffer
+ */
+enum buffer_type {
+ BUF_HT = BIT(1),
+ BUF_AMPDU = BIT(2),
+ BUF_AGGR = BIT(3),
+ BUF_RETRY = BIT(4),
+ BUF_XRETRY = BIT(5),
+};
+
+struct ath_buf_state {
+ int bfs_nframes;
+ u16 bfs_al;
+ u16 bfs_frmlen;
+ int bfs_seqno;
+ int bfs_tidno;
+ int bfs_retries;
+ u32 bf_type;
+ u32 bfs_keyix;
+ enum ath9k_key_type bfs_keytype;
+};
+
+#define bf_nframes bf_state.bfs_nframes
+#define bf_al bf_state.bfs_al
+#define bf_frmlen bf_state.bfs_frmlen
+#define bf_retries bf_state.bfs_retries
+#define bf_seqno bf_state.bfs_seqno
+#define bf_tidno bf_state.bfs_tidno
+#define bf_keyix bf_state.bfs_keyix
+#define bf_keytype bf_state.bfs_keytype
+#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
+#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
+#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
+#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
+#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
+
+struct ath_buf {
+ struct list_head list;
+ struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
+ an aggregate) */
+ struct ath_buf *bf_next; /* next subframe in the aggregate */
+ void *bf_mpdu; /* enclosing frame structure */
+ struct ath_desc *bf_desc; /* virtual addr of desc */
+ dma_addr_t bf_daddr; /* physical addr of desc */
+ dma_addr_t bf_buf_addr; /* physical addr of data buffer */
+ u32 bf_status;
+ u16 bf_flags;
+ struct ath_buf_state bf_state;
+ dma_addr_t bf_dmacontext;
+};
+
+#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
+#define ATH_BUFSTATUS_STALE 0x00000002
+
+struct ath_descdma {
+ const char *dd_name;
+ struct ath_desc *dd_desc;
+ dma_addr_t dd_desc_paddr;
+ u32 dd_desc_len;
+ struct ath_buf *dd_bufptr;
+ dma_addr_t dd_dmacontext;
+};
+
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+ struct list_head *head, const char *name,
+ int nbuf, int ndesc);
+void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
+ struct list_head *head);
+
+/***********/
+/* RX / TX */
+/***********/
+
+#define ATH_MAX_ANTENNA 3
+#define ATH_RXBUF 512
+#define WME_NUM_TID 16
+#define ATH_TXBUF 512
+#define ATH_TXMAXTRY 13
+#define ATH_11N_TXMAXTRY 10
+#define ATH_MGT_TXMAXTRY 4
+#define WME_BA_BMP_SIZE 64
+#define WME_MAX_BA WME_BA_BMP_SIZE
+#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
+
+#define TID_TO_WME_AC(_tid) \
+ ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
+ (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
+ (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
+ WME_AC_VO)
+
+#define WME_AC_BE 0
+#define WME_AC_BK 1
+#define WME_AC_VI 2
+#define WME_AC_VO 3
+#define WME_NUM_AC 4
+
+#define ADDBA_EXCHANGE_ATTEMPTS 10
+#define ATH_AGGR_DELIM_SZ 4
+#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
+/* number of delimiters for encryption padding */
+#define ATH_AGGR_ENCRYPTDELIM 10
+/* minimum h/w qdepth to be sustained to maximize aggregation */
+#define ATH_AGGR_MIN_QDEPTH 2
+#define ATH_AMPDU_SUBFRAME_DEFAULT 32
+#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
+#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
+
+#define IEEE80211_SEQ_SEQ_SHIFT 4
+#define IEEE80211_SEQ_MAX 4096
+#define IEEE80211_MIN_AMPDU_BUF 0x8
+#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
+#define IEEE80211_WEP_IVLEN 3
+#define IEEE80211_WEP_KIDLEN 1
+#define IEEE80211_WEP_CRCLEN 4
+#define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \
+ (IEEE80211_WEP_IVLEN + \
+ IEEE80211_WEP_KIDLEN + \
+ IEEE80211_WEP_CRCLEN))
+
+/* return whether a bit at index _n in bitmap _bm is set
+ * _sz is the size of the bitmap */
+#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
+ ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
+
+/* return block-ack bitmap index given sequence and starting sequence */
+#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
+
+/* returns delimiter padding required given the packet length */
+#define ATH_AGGR_GET_NDELIM(_len) \
+ (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
+ (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
+
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+ ((((_seqno) - (_start)) & 4095) < (_bawsz))
+
+#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
+#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
+#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
+#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
+
+enum ATH_AGGR_STATUS {
+ ATH_AGGR_DONE,
+ ATH_AGGR_BAW_CLOSED,
+ ATH_AGGR_LIMITED,
+};
+
+struct ath_txq {
+ u32 axq_qnum;
+ u32 *axq_link;
+ struct list_head axq_q;
+ spinlock_t axq_lock;
+ u32 axq_depth;
+ u8 axq_aggr_depth;
+ u32 axq_totalqueued;
+ bool stopped;
+ struct ath_buf *axq_linkbuf;
+
+ /* first desc of the last descriptor that contains CTS */
+ struct ath_desc *axq_lastdsWithCTS;
+
+ /* final desc of the gating desc that determines whether
+ lastdsWithCTS has been DMA'ed or not */
+ struct ath_desc *axq_gatingds;
+
+ struct list_head axq_acq;
+};
+
+#define AGGR_CLEANUP BIT(1)
+#define AGGR_ADDBA_COMPLETE BIT(2)
+#define AGGR_ADDBA_PROGRESS BIT(3)
+
+struct ath_atx_tid {
+ struct list_head list;
+ struct list_head buf_q;
+ struct ath_node *an;
+ struct ath_atx_ac *ac;
+ struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
+ u16 seq_start;
+ u16 seq_next;
+ u16 baw_size;
+ int tidno;
+ int baw_head; /* first un-acked tx buffer */
+ int baw_tail; /* next unused tx buffer slot */
+ int sched;
+ int paused;
+ u8 state;
+ int addba_exchangeattempts;
+};
+
+struct ath_atx_ac {
+ int sched;
+ int qnum;
+ struct list_head list;
+ struct list_head tid_q;
+};
+
+struct ath_tx_control {
+ struct ath_txq *txq;
+ int if_id;
+ enum ath9k_internal_frame_type frame_type;
+};
+
+struct ath_xmit_status {
+ int retries;
+ int flags;
+#define ATH_TX_ERROR 0x01
+#define ATH_TX_XRETRY 0x02
+#define ATH_TX_BAR 0x04
+};
+
+/* All RSSI values are noise floor adjusted */
+struct ath_tx_stat {
+ int rssi;
+ int rssictl[ATH_MAX_ANTENNA];
+ int rssiextn[ATH_MAX_ANTENNA];
+ int rateieee;
+ int rateKbps;
+ int ratecode;
+ int flags;
+ u32 airtime; /* time on air per final tx rate */
+};
+
+struct aggr_rifs_param {
+ int param_max_frames;
+ int param_max_len;
+ int param_rl;
+ int param_al;
+ struct ath_rc_series *param_rcs;
+};
+
+struct ath_node {
+ struct ath_softc *an_sc;
+ struct ath_atx_tid tid[WME_NUM_TID];
+ struct ath_atx_ac ac[WME_NUM_AC];
+ u16 maxampdu;
+ u8 mpdudensity;
+};
+
+struct ath_tx {
+ u16 seq_no;
+ u32 txqsetup;
+ int hwq_map[ATH9K_WME_AC_VO+1];
+ spinlock_t txbuflock;
+ struct list_head txbuf;
+ struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
+ struct ath_descdma txdma;
+};
+
+struct ath_rx {
+ u8 defant;
+ u8 rxotherant;
+ u32 *rxlink;
+ int bufsize;
+ unsigned int rxfilter;
+ spinlock_t rxflushlock;
+ spinlock_t rxbuflock;
+ struct list_head rxbuf;
+ struct ath_descdma rxdma;
+};
+
+int ath_startrecv(struct ath_softc *sc);
+bool ath_stoprecv(struct ath_softc *sc);
+void ath_flushrecv(struct ath_softc *sc);
+u32 ath_calcrxfilter(struct ath_softc *sc);
+int ath_rx_init(struct ath_softc *sc, int nbufs);
+void ath_rx_cleanup(struct ath_softc *sc);
+int ath_rx_tasklet(struct ath_softc *sc, int flush);
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_setup(struct ath_softc *sc, int haltype);
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+void ath_draintxq(struct ath_softc *sc,
+ struct ath_txq *txq, bool retry_tx);
+void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_init(struct ath_softc *sc, int nbufs);
+int ath_tx_cleanup(struct ath_softc *sc);
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
+int ath_txq_update(struct ath_softc *sc, int qnum,
+ struct ath9k_tx_queue_info *q);
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct ath_tx_control *txctl);
+void ath_tx_tasklet(struct ath_softc *sc);
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn);
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+
+/********/
+/* VIFs */
+/********/
+
+struct ath_vif {
+ int av_bslot;
+ enum nl80211_iftype av_opmode;
+ struct ath_buf *av_bcbuf;
+ struct ath_tx_control av_btxctl;
+ u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
+};
+
+/*******************/
+/* Beacon Handling */
+/*******************/
-#define CHANNEL_CW_INT 0x00002
-#define CHANNEL_CCK 0x00020
-#define CHANNEL_OFDM 0x00040
-#define CHANNEL_2GHZ 0x00080
-#define CHANNEL_5GHZ 0x00100
-#define CHANNEL_PASSIVE 0x00200
-#define CHANNEL_DYN 0x00400
-#define CHANNEL_HALF 0x04000
-#define CHANNEL_QUARTER 0x08000
-#define CHANNEL_HT20 0x10000
-#define CHANNEL_HT40PLUS 0x20000
-#define CHANNEL_HT40MINUS 0x40000
-
-#define CHANNEL_INTERFERENCE 0x01
-#define CHANNEL_DFS 0x02
-#define CHANNEL_4MS_LIMIT 0x04
-#define CHANNEL_DFS_CLEAR 0x08
-#define CHANNEL_DISALLOW_ADHOC 0x10
-#define CHANNEL_PER_11D_ADHOC 0x20
-
-#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
-#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
-#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
-#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
-#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
-#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
-#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
-#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
-#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
-#define CHANNEL_ALL \
- (CHANNEL_OFDM| \
- CHANNEL_CCK| \
- CHANNEL_2GHZ | \
- CHANNEL_5GHZ | \
- CHANNEL_HT20 | \
- CHANNEL_HT40PLUS | \
- CHANNEL_HT40MINUS)
-
-struct ath9k_channel {
- u16 channel;
- u32 channelFlags;
- u8 privFlags;
- int8_t maxRegTxPower;
- int8_t maxTxPower;
- int8_t minTxPower;
- u32 chanmode;
- int32_t CalValid;
- bool oneTimeCalsDone;
- int8_t iCoff;
- int8_t qCoff;
- int16_t rawNoiseFloor;
- int8_t antennaMax;
- u32 regDmnFlags;
- u32 conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */
-#ifdef ATH_NF_PER_CHAN
- struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-#endif
-};
+/*
+ * Regardless of the number of beacons we stagger, (i.e. regardless of the
+ * number of BSSIDs) if a given beacon does not go out even after waiting this
+ * number of beacon intervals, the game's up.
+ */
+#define BSTUCK_THRESH (9 * ATH_BCBUF)
+#define ATH_BCBUF 1
+#define ATH_DEFAULT_BINTVAL 100 /* TU */
+#define ATH_DEFAULT_BMISS_LIMIT 10
+#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
+
+struct ath_beacon_config {
+ u16 beacon_interval;
+ u16 listen_interval;
+ u16 dtim_period;
+ u16 bmiss_timeout;
+ u8 dtim_count;
+};
+
+struct ath_beacon {
+ enum {
+ OK, /* no change needed */
+ UPDATE, /* update pending */
+ COMMIT /* beacon sent, commit change */
+ } updateslot; /* slot time update fsm */
+
+ u32 beaconq;
+ u32 bmisscnt;
+ u32 ast_be_xmit;
+ u64 bc_tstamp;
+ struct ieee80211_vif *bslot[ATH_BCBUF];
+ struct ath_wiphy *bslot_aphy[ATH_BCBUF];
+ int slottime;
+ int slotupdate;
+ struct ath9k_tx_queue_info beacon_qi;
+ struct ath_descdma bdma;
+ struct ath_txq *cabq;
+ struct list_head bbuf;
+};
+
+void ath_beacon_tasklet(unsigned long data);
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
+int ath_beaconq_setup(struct ath_hw *ah);
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
+
+/*******/
+/* ANI */
+/*******/
-#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
- (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
- (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
- (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
-#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
- (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
- (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
- (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
-#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
-#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
-#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
-#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
-#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
-#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
-
-/* These macros check chanmode and not channelFlags */
-#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
-#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
- ((_c)->chanmode == CHANNEL_G_HT20))
-#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
- ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
- ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
- ((_c)->chanmode == CHANNEL_G_HT40MINUS))
-#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
-
-#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)
-#define IS_CHAN_A_5MHZ_SPACED(_c) \
- ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
- (((_c)->channel % 20) != 0) && \
- (((_c)->channel % 10) != 0))
-
-struct ath9k_keyval {
- u8 kv_type;
- u8 kv_pad;
- u16 kv_len;
- u8 kv_val[16];
- u8 kv_mic[8];
- u8 kv_txmic[8];
-};
+#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
+#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */
+#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
+#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
+#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
-enum ath9k_key_type {
- ATH9K_KEY_TYPE_CLEAR,
- ATH9K_KEY_TYPE_WEP,
- ATH9K_KEY_TYPE_AES,
- ATH9K_KEY_TYPE_TKIP,
+struct ath_ani {
+ bool caldone;
+ int16_t noise_floor;
+ unsigned int longcal_timer;
+ unsigned int shortcal_timer;
+ unsigned int resetcal_timer;
+ unsigned int checkani_timer;
+ struct timer_list timer;
};
-enum ath9k_cipher {
- ATH9K_CIPHER_WEP = 0,
- ATH9K_CIPHER_AES_OCB = 1,
- ATH9K_CIPHER_AES_CCM = 2,
- ATH9K_CIPHER_CKIP = 3,
- ATH9K_CIPHER_TKIP = 4,
- ATH9K_CIPHER_CLR = 5,
- ATH9K_CIPHER_MIC = 127
-};
+/********************/
+/* LED Control */
+/********************/
-#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
-#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
-#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004
-#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
-#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
-#define AR_EEPROM_EEPCAP_MAXQCU_S 4
-#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
-#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
-#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
-
-#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080
-#define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100
-#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400
-#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800
-
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000
-#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
-
-#define 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 AR_EEPROM_MAC(i) (0x1d+(i))
-
-#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
-#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
-#define AR_EEPROM_RFSILENT_POLARITY 0x0002
-#define AR_EEPROM_RFSILENT_POLARITY_S 1
-
-#define CTRY_DEBUG 0x1ff
-#define CTRY_DEFAULT 0
-
-enum reg_ext_bitmap {
- REG_EXT_JAPAN_MIDBAND = 1,
- REG_EXT_FCC_DFS_HT40 = 2,
- REG_EXT_JAPAN_NONDFS_HT40 = 3,
- REG_EXT_JAPAN_DFS_HT40 = 4
-};
+#define ATH_LED_PIN 1
+#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
+#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
-struct ath9k_country_entry {
- u16 countryCode;
- u16 regDmnEnum;
- u16 regDmn5G;
- u16 regDmn2G;
- u8 isMultidomain;
- u8 iso[3];
+enum ath_led_type {
+ ATH_LED_RADIO,
+ ATH_LED_ASSOC,
+ ATH_LED_TX,
+ ATH_LED_RX
};
-#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg)
-#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg)
-
-#define SM(_v, _f) (((_v) << _f##_S) & _f)
-#define MS(_v, _f) (((_v) & _f) >> _f##_S)
-#define REG_RMW(_a, _r, _set, _clr) \
- REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
-#define REG_RMW_FIELD(_a, _r, _f, _v) \
- REG_WRITE(_a, _r, \
- (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
-#define REG_SET_BIT(_a, _r, _f) \
- REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
-#define REG_CLR_BIT(_a, _r, _f) \
- REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
-
-#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
-
-#define INIT_AIFS 2
-#define INIT_CWMIN 15
-#define INIT_CWMIN_11B 31
-#define INIT_CWMAX 1023
-#define INIT_SH_RETRY 10
-#define INIT_LG_RETRY 10
-#define INIT_SSH_RETRY 32
-#define INIT_SLG_RETRY 32
-
-#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
-
-#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
-#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
-
-#define IEEE80211_WEP_IVLEN 3
-#define IEEE80211_WEP_KIDLEN 1
-#define IEEE80211_WEP_CRCLEN 4
-#define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \
- (IEEE80211_WEP_IVLEN + \
- IEEE80211_WEP_KIDLEN + \
- IEEE80211_WEP_CRCLEN))
-#define MAX_RATE_POWER 63
-
-enum ath9k_power_mode {
- ATH9K_PM_AWAKE = 0,
- ATH9K_PM_FULL_SLEEP,
- ATH9K_PM_NETWORK_SLEEP,
- ATH9K_PM_UNDEFINED
+struct ath_led {
+ struct ath_softc *sc;
+ struct led_classdev led_cdev;
+ enum ath_led_type led_type;
+ char name[32];
+ bool registered;
};
-struct ath9k_mib_stats {
- u32 ackrcv_bad;
- u32 rts_bad;
- u32 rts_good;
- u32 fcs_bad;
- u32 beacons;
-};
+/* Rfkill */
+#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
-enum ath9k_ant_setting {
- ATH9K_ANT_VARIABLE = 0,
- ATH9K_ANT_FIXED_A,
- ATH9K_ANT_FIXED_B
+struct ath_rfkill {
+ struct rfkill *rfkill;
+ struct delayed_work rfkill_poll;
+ char rfkill_name[32];
};
-#define ATH9K_SLOT_TIME_6 6
-#define ATH9K_SLOT_TIME_9 9
-#define ATH9K_SLOT_TIME_20 20
-
-enum ath9k_ht_macmode {
- ATH9K_HT_MACMODE_20 = 0,
- ATH9K_HT_MACMODE_2040 = 1,
-};
+/********************/
+/* Main driver core */
+/********************/
-enum ath9k_ht_extprotspacing {
- ATH9K_HT_EXTPROTSPACING_20 = 0,
- ATH9K_HT_EXTPROTSPACING_25 = 1,
-};
+/*
+ * Default cache line size, in bytes.
+ * Used when PCI device not fully initialized by bootrom/BIOS
+*/
+#define DEFAULT_CACHELINE 32
+#define ATH_DEFAULT_NOISE_FLOOR -95
+#define ATH_REGCLASSIDS_MAX 10
+#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
+#define ATH_MAX_SW_RETRIES 10
+#define ATH_CHAN_MAX 255
+#define IEEE80211_WEP_NKID 4 /* number of key ids */
-struct ath9k_ht_cwm {
- enum ath9k_ht_macmode ht_macmode;
+/*
+ * The key cache is used for h/w cipher state and also for
+ * tracking station state such as the current tx antenna.
+ * We also setup a mapping table between key cache slot indices
+ * and station state to short-circuit node lookups on rx.
+ * Different parts have different size key caches. We handle
+ * up to ATH_KEYMAX entries (could dynamically allocate state).
+ */
+#define ATH_KEYMAX 128 /* max key cache size we handle */
+
+#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
+#define ATH_RSSI_DUMMY_MARKER 0x127
+#define ATH_RATE_DUMMY_MARKER 0
+
+#define SC_OP_INVALID BIT(0)
+#define SC_OP_BEACONS BIT(1)
+#define SC_OP_RXAGGR BIT(2)
+#define SC_OP_TXAGGR BIT(3)
+#define SC_OP_CHAINMASK_UPDATE BIT(4)
+#define SC_OP_FULL_RESET BIT(5)
+#define SC_OP_PREAMBLE_SHORT BIT(6)
+#define SC_OP_PROTECT_ENABLE BIT(7)
+#define SC_OP_RXFLUSH BIT(8)
+#define SC_OP_LED_ASSOCIATED BIT(9)
+#define SC_OP_RFKILL_REGISTERED BIT(10)
+#define SC_OP_RFKILL_SW_BLOCKED BIT(11)
+#define SC_OP_RFKILL_HW_BLOCKED BIT(12)
+#define SC_OP_WAIT_FOR_BEACON BIT(13)
+#define SC_OP_LED_ON BIT(14)
+#define SC_OP_SCANNING BIT(15)
+#define SC_OP_TSF_RESET BIT(16)
+
+struct ath_bus_ops {
+ void (*read_cachesize)(struct ath_softc *sc, int *csz);
+ void (*cleanup)(struct ath_softc *sc);
+ bool (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
+};
+
+struct ath_wiphy;
+
+struct ath_softc {
+ struct ieee80211_hw *hw;
+ struct device *dev;
+
+ spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
+ struct ath_wiphy *pri_wiphy;
+ struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
+ * have NULL entries */
+ int num_sec_wiphy; /* number of sec_wiphy pointers in the array */
+ int chan_idx;
+ int chan_is_ht;
+ struct ath_wiphy *next_wiphy;
+ struct work_struct chan_work;
+ int wiphy_select_failures;
+ unsigned long wiphy_select_first_fail;
+ struct delayed_work wiphy_work;
+ unsigned long wiphy_scheduler_int;
+ int wiphy_scheduler_index;
+
+ struct tasklet_struct intr_tq;
+ struct tasklet_struct bcon_tasklet;
+ struct ath_hw *sc_ah;
+ void __iomem *mem;
+ int irq;
+ spinlock_t sc_resetlock;
+ spinlock_t sc_serial_rw;
+ struct mutex mutex;
+
+ u8 curbssid[ETH_ALEN];
+ u8 bssidmask[ETH_ALEN];
+ u32 intrstatus;
+ u32 sc_flags; /* SC_OP_* */
+ u16 curtxpow;
+ u16 curaid;
+ u16 cachelsz;
+ u8 nbcnvifs;
+ u16 nvifs;
+ u8 tx_chainmask;
+ u8 rx_chainmask;
+ u32 keymax;
+ DECLARE_BITMAP(keymap, ATH_KEYMAX);
+ u8 splitmic;
+ atomic_t ps_usecount;
+ enum ath9k_int imask;
enum ath9k_ht_extprotspacing ht_extprotspacing;
-};
-
-enum ath9k_ani_cmd {
- ATH9K_ANI_PRESENT = 0x1,
- ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
- ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
- ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
- ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
- ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
- ATH9K_ANI_MODE = 0x40,
- ATH9K_ANI_PHYERR_RESET = 0x80,
- ATH9K_ANI_ALL = 0xff
-};
-
-enum {
- WLAN_RC_PHY_OFDM,
- WLAN_RC_PHY_CCK,
- WLAN_RC_PHY_HT_20_SS,
- WLAN_RC_PHY_HT_20_DS,
- WLAN_RC_PHY_HT_40_SS,
- WLAN_RC_PHY_HT_40_DS,
- WLAN_RC_PHY_HT_20_SS_HGI,
- WLAN_RC_PHY_HT_20_DS_HGI,
- WLAN_RC_PHY_HT_40_SS_HGI,
- WLAN_RC_PHY_HT_40_DS_HGI,
- WLAN_RC_PHY_MAX
-};
-
-enum ath9k_tp_scale {
- ATH9K_TP_SCALE_MAX = 0,
- ATH9K_TP_SCALE_50,
- ATH9K_TP_SCALE_25,
- ATH9K_TP_SCALE_12,
- ATH9K_TP_SCALE_MIN
-};
-
-enum ser_reg_mode {
- SER_REG_MODE_OFF = 0,
- SER_REG_MODE_ON = 1,
- SER_REG_MODE_AUTO = 2,
-};
-
-#define AR_PHY_CCA_MAX_GOOD_VALUE -85
-#define AR_PHY_CCA_MAX_HIGH_VALUE -62
-#define AR_PHY_CCA_MIN_BAD_VALUE -121
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
-
-#define ATH9K_NF_CAL_HIST_MAX 5
-#define NUM_NF_READINGS 6
-
-struct ath9k_nfcal_hist {
- int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
- u8 currIndex;
- int16_t privNF;
- u8 invalidNFcount;
-};
-
-struct ath9k_beacon_state {
- u32 bs_nexttbtt;
- u32 bs_nextdtim;
- u32 bs_intval;
-#define ATH9K_BEACON_PERIOD 0x0000ffff
-#define ATH9K_BEACON_ENA 0x00800000
-#define ATH9K_BEACON_RESET_TSF 0x01000000
- u32 bs_dtimperiod;
- u16 bs_cfpperiod;
- u16 bs_cfpmaxduration;
- u32 bs_cfpnext;
- u16 bs_timoffset;
- u16 bs_bmissthreshold;
- u32 bs_sleepduration;
-};
-
-struct ath9k_node_stats {
- u32 ns_avgbrssi;
- u32 ns_avgrssi;
- u32 ns_avgtxrssi;
- u32 ns_avgtxrate;
-};
-
-#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
-
-#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
-#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
-#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
-
-enum {
- ATH9K_RESET_POWER_ON,
- ATH9K_RESET_WARM,
- ATH9K_RESET_COLD,
-};
-
-#define AH_USE_EEPROM 0x1
-
-struct ath_hal {
- u32 ah_magic;
- u16 ah_devid;
- u16 ah_subvendorid;
- u32 ah_macVersion;
- u16 ah_macRev;
- u16 ah_phyRev;
- u16 ah_analog5GhzRev;
- u16 ah_analog2GhzRev;
-
- void __iomem *ah_sh;
- struct ath_softc *ah_sc;
-
- enum nl80211_iftype ah_opmode;
- struct ath9k_ops_config ah_config;
- struct ath9k_hw_capabilities ah_caps;
-
- u16 ah_countryCode;
- u32 ah_flags;
- int16_t ah_powerLimit;
- u16 ah_maxPowerLevel;
- u32 ah_tpScale;
- u16 ah_currentRD;
- u16 ah_currentRDExt;
- u16 ah_currentRDInUse;
- u16 ah_currentRD5G;
- u16 ah_currentRD2G;
- char ah_iso[4];
-
- struct ath9k_channel ah_channels[150];
- struct ath9k_channel *ah_curchan;
- u32 ah_nchan;
-
- bool ah_isPciExpress;
- u16 ah_txTrigLevel;
- u16 ah_rfsilent;
- u32 ah_rfkill_gpio;
- u32 ah_rfkill_polarity;
-
-#ifndef ATH_NF_PER_CHAN
- struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+ enum ath9k_ht_macmode tx_chan_width;
+
+ struct ath_config config;
+ struct ath_rx rx;
+ struct ath_tx tx;
+ struct ath_beacon beacon;
+ struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
+ struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
+ struct ath_rate_table *cur_rate_table;
+ struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+
+ struct ath_led radio_led;
+ struct ath_led assoc_led;
+ struct ath_led tx_led;
+ struct ath_led rx_led;
+ struct delayed_work ath_led_blink_work;
+ int led_on_duration;
+ int led_off_duration;
+ int led_on_cnt;
+ int led_off_cnt;
+
+ struct ath_rfkill rf_kill;
+ struct ath_ani ani;
+ struct ath9k_node_stats nodestats;
+#ifdef CONFIG_ATH9K_DEBUG
+ struct ath9k_debug debug;
+#endif
+ struct ath_bus_ops *bus_ops;
+};
+
+struct ath_wiphy {
+ struct ath_softc *sc; /* shared for all virtual wiphys */
+ struct ieee80211_hw *hw;
+ enum ath_wiphy_state {
+ ATH_WIPHY_INACTIVE,
+ ATH_WIPHY_ACTIVE,
+ ATH_WIPHY_PAUSING,
+ ATH_WIPHY_PAUSED,
+ ATH_WIPHY_SCAN,
+ } state;
+ int chan_idx;
+ int chan_is_ht;
+};
+
+int ath_reset(struct ath_softc *sc, bool retry_tx);
+int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
+int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
+int ath_cabq_update(struct ath_softc *);
+
+static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
+{
+ sc->bus_ops->read_cachesize(sc, csz);
+}
+
+static inline void ath_bus_cleanup(struct ath_softc *sc)
+{
+ sc->bus_ops->cleanup(sc);
+}
+
+extern struct ieee80211_ops ath9k_ops;
+
+irqreturn_t ath_isr(int irq, void *dev);
+void ath_cleanup(struct ath_softc *sc);
+int ath_attach(u16 devid, struct ath_softc *sc);
+void ath_detach(struct ath_softc *sc);
+const char *ath_mac_bb_name(u32 mac_bb_version);
+const char *ath_rf_name(u16 rf_version);
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+ struct ath9k_channel *ichan);
+void ath_update_chainmask(struct ath_softc *sc, int is_ht);
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+ struct ath9k_channel *hchan);
+void ath_radio_enable(struct ath_softc *sc);
+void ath_radio_disable(struct ath_softc *sc);
+
+#ifdef CONFIG_PCI
+int ath_pci_init(void);
+void ath_pci_exit(void);
+#else
+static inline int ath_pci_init(void) { return 0; };
+static inline void ath_pci_exit(void) {};
#endif
-};
-
-struct chan_centers {
- u16 synth_center;
- u16 ctl_center;
- u16 ext_center;
-};
-struct ath_rate_table;
-
-/* Helpers */
-
-enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
- const struct ath9k_channel *chan);
-bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val);
-u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-bool ath9k_get_channel_edges(struct ath_hal *ah,
- u16 flags, u16 *low,
- u16 *high);
-u16 ath9k_hw_computetxtime(struct ath_hal *ah,
- struct ath_rate_table *rates,
- u32 frameLen, u16 rateix,
- bool shortPreamble);
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
-void ath9k_hw_get_channel_centers(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct chan_centers *centers);
-
-/* Attach, Detach */
-
-const char *ath9k_hw_probe(u16 vendorid, u16 devid);
-void ath9k_hw_detach(struct ath_hal *ah);
-struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
- void __iomem *mem, int *error);
-void ath9k_hw_rfdetach(struct ath_hal *ah);
-
-
-/* HW Reset */
-
-bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
- enum ath9k_ht_macmode macmode,
- u8 txchainmask, u8 rxchainmask,
- enum ath9k_ht_extprotspacing extprotspacing,
- bool bChannelChange, int *status);
-
-/* Key Cache Management */
-
-bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry);
-bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac);
-bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
- const struct ath9k_keyval *k,
- const u8 *mac, int xorKey);
-bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry);
-
-/* Power Management */
-
-bool ath9k_hw_setpower(struct ath_hal *ah,
- enum ath9k_power_mode mode);
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
-
-/* Beacon timers */
-
-void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period);
-void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
- const struct ath9k_beacon_state *bs);
-/* HW Capabilities */
-
-bool ath9k_hw_fill_cap_info(struct ath_hal *ah);
-bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
- u32 capability, u32 *result);
-bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
- u32 capability, u32 setting, int *status);
-
-/* GPIO / RFKILL / Antennae */
-
-void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio);
-u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio);
-void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
- u32 ah_signal_type);
-void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val);
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hal *ah);
+#ifdef CONFIG_ATHEROS_AR71XX
+int ath_ahb_init(void);
+void ath_ahb_exit(void);
+#else
+static inline int ath_ahb_init(void) { return 0; };
+static inline void ath_ahb_exit(void) {};
#endif
-int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg);
-u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna);
-bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
- enum ath9k_ant_setting settings,
- struct ath9k_channel *chan,
- u8 *tx_chainmask,
- u8 *rx_chainmask,
- u8 *antenna_cfgd);
-
-/* General Operation */
-
-u32 ath9k_hw_getrxfilter(struct ath_hal *ah);
-void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits);
-bool ath9k_hw_phy_disable(struct ath_hal *ah);
-bool ath9k_hw_disable(struct ath_hal *ah);
-bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit);
-void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac);
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac);
-void ath9k_hw_setopmode(struct ath_hal *ah);
-void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1);
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask);
-bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask);
-void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId);
-u64 ath9k_hw_gettsf64(struct ath_hal *ah);
-void ath9k_hw_reset_tsf(struct ath_hal *ah);
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting);
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
-void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
-
-/* Regulatory */
-
-bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah);
-struct ath9k_channel* ath9k_regd_check_channel(struct ath_hal *ah,
- const struct ath9k_channel *c);
-u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
-u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
- struct ath9k_channel *chan);
-bool ath9k_regd_init_channels(struct ath_hal *ah,
- u32 maxchans, u32 *nchans, u8 *regclassids,
- u32 maxregids, u32 *nregids, u16 cc,
- bool enableOutdoor, bool enableExtendedChannels);
-/* ANI */
+static inline void ath9k_ps_wakeup(struct ath_softc *sc)
+{
+ if (atomic_inc_return(&sc->ps_usecount) == 1)
+ if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) {
+ sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+ }
+}
+
+static inline void ath9k_ps_restore(struct ath_softc *sc)
+{
+ if (atomic_dec_and_test(&sc->ps_usecount))
+ if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
+ !(sc->sc_flags & SC_OP_WAIT_FOR_BEACON))
+ ath9k_hw_setpower(sc->sc_ah,
+ sc->sc_ah->restore_mode);
+}
+
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
+int ath9k_wiphy_add(struct ath_softc *sc);
+int ath9k_wiphy_del(struct ath_wiphy *aphy);
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ath9k_wiphy_pause(struct ath_wiphy *aphy);
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+int ath9k_wiphy_select(struct ath_wiphy *aphy);
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int);
+void ath9k_wiphy_chan_work(struct work_struct *work);
+bool ath9k_wiphy_started(struct ath_softc *sc);
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+ struct ath_wiphy *selected);
+bool ath9k_wiphy_scanning(struct ath_softc *sc);
+void ath9k_wiphy_work(struct work_struct *work);
-void ath9k_ani_reset(struct ath_hal *ah);
-void ath9k_hw_ani_monitor(struct ath_hal *ah,
- const struct ath9k_node_stats *stats,
- struct ath9k_channel *chan);
-bool ath9k_hw_phycounters(struct ath_hal *ah);
-void ath9k_enable_mib_counters(struct ath_hal *ah);
-void ath9k_hw_disable_mib_counters(struct ath_hal *ah);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
- u32 *rxc_pcnt,
- u32 *rxf_pcnt,
- u32 *txf_pcnt);
-void ath9k_hw_procmibevent(struct ath_hal *ah,
- const struct ath9k_node_stats *stats);
-void ath9k_hw_ani_setup(struct ath_hal *ah);
-void ath9k_hw_ani_attach(struct ath_hal *ah);
-void ath9k_hw_ani_detach(struct ath_hal *ah);
-
-/* Calibration */
-
-void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
- bool *isCalDone);
-void ath9k_hw_start_nfcal(struct ath_hal *ah);
-void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan);
-int16_t ath9k_hw_getnf(struct ath_hal *ah,
- struct ath9k_channel *chan);
-void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah);
-s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan);
-bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
- u8 rxchainmask, bool longcal,
- bool *isCalDone);
-bool ath9k_hw_init_cal(struct ath_hal *ah,
- struct ath9k_channel *chan);
-
-
-/* EEPROM */
-
-int ath9k_hw_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit);
-void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan);
-bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *ratesArray,
- u16 cfgCtl,
- u8 AntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit);
-bool ath9k_hw_set_power_cal_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset);
-bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
- struct ath9k_channel *chan);
-int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u8 index, u16 *config);
-u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
- enum ieee80211_band freq_band);
-u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz);
-int ath9k_hw_eeprom_attach(struct ath_hal *ah);
-
-/* Interrupt Handling */
-
-bool ath9k_hw_intrpend(struct ath_hal *ah);
-bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
-enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints);
-
-/* MAC (PCU/QCU) */
-
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp);
-bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q);
-bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel);
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q);
-bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 segLen, bool firstSeg,
- bool lastSeg, const struct ath_desc *ds0);
-void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
-int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
- u32 keyIx, enum ath9k_key_type keyType, u32 flags);
-void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
- struct ath_desc *lastds,
- u32 durUpdateEn, u32 rtsctsRate,
- u32 rtsctsDuration,
- struct ath9k_11n_rate_series series[],
- u32 nseries, u32 flags);
-void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
- u32 aggrLen);
-void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
- u32 numDelims);
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
- u32 burstDuration);
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
- u32 vmf);
-void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs);
-bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
- const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
- struct ath9k_tx_queue_info *qinfo);
-int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
- const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q);
-bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q);
-int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 pa, struct ath_desc *nds, u64 tsf);
-bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 size, u32 flags);
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set);
-void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp);
-void ath9k_hw_rxena(struct ath_hal *ah);
-void ath9k_hw_startpcureceive(struct ath_hal *ah);
-void ath9k_hw_stoppcurecv(struct ath_hal *ah);
-bool ath9k_hw_stopdmarecv(struct ath_hal *ah);
+/*
+ * 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.
+ */
-#endif
+static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
+{
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+}
+
+static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
+{
+ u32 val;
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ return val;
+}
+
+#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 3ab0b43aaf9..039c78136c5 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -14,7 +14,9 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
+#include "ath9k.h"
+
+#define FUDGE 2
/*
* This function will modify certain transmit queue properties depending on
@@ -23,11 +25,11 @@
*/
static int ath_beaconq_config(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath9k_tx_queue_info qi;
ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
/* Always burst out beacon and CAB traffic. */
qi.tqi_aifs = 1;
qi.tqi_cwmin = 0;
@@ -44,46 +46,32 @@ static int ath_beaconq_config(struct ath_softc *sc)
"unable to update h/w beacon queue parameters\n");
return 0;
} else {
- ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); /* push to h/w */
+ ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
return 1;
}
}
-static void ath_bstuck_process(struct ath_softc *sc)
-{
- DPRINTF(sc, ATH_DBG_BEACON,
- "stuck beacon; resetting (bmiss count %u)\n",
- sc->beacon.bmisscnt);
- ath_reset(sc, false);
-}
-
/*
* Associates the beacon frame buffer with a transmit descriptor. Will set
* up all required antenna switch parameters, rate codes, and channel flags.
* Beacons are always sent out at the lowest rate, and are not retried.
*/
-static void ath_beacon_setup(struct ath_softc *sc,
- struct ath_vap *avp, struct ath_buf *bf)
+static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
+ struct ath_buf *bf)
{
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_desc *ds;
struct ath9k_11n_rate_series series[4];
struct ath_rate_table *rt;
- int flags, antenna;
- u8 rix, rate;
- int ctsrate = 0;
- int ctsduration = 0;
-
- DPRINTF(sc, ATH_DBG_BEACON, "m %p len %u\n", skb, skb->len);
+ int flags, antenna, ctsrate = 0, ctsduration = 0;
+ u8 rate;
- /* setup descriptors */
ds = bf->bf_desc;
-
flags = ATH9K_TXDESC_NOACK;
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC &&
- (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC &&
+ (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
ds->ds_link = bf->bf_daddr; /* self-linked */
flags |= ATH9K_TXDESC_VEOL;
/* Let hardware handle antenna switching. */
@@ -92,65 +80,53 @@ static void ath_beacon_setup(struct ath_softc *sc,
ds->ds_link = 0;
/*
* Switch antenna every beacon.
- * Should only switch every beacon period, not for every
- * SWBA's
- * XXX assumes two antenna
+ * Should only switch every beacon period, not for every SWBA
+ * XXX assumes two antennae
*/
- antenna = ((sc->beacon.ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
+ antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
}
ds->ds_data = bf->bf_buf_addr;
- /*
- * Calculate rate code.
- * XXX everything at min xmit rate
- */
- rix = 0;
rt = sc->cur_rate_table;
- rate = rt->info[rix].ratecode;
+ rate = rt->info[0].ratecode;
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
- rate |= rt->info[rix].short_preamble;
-
- ath9k_hw_set11n_txdesc(ah, ds,
- skb->len + FCS_LEN, /* frame length */
- ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */
- MAX_RATE_POWER, /* FIXME */
- ATH9K_TXKEYIX_INVALID, /* no encryption */
- ATH9K_KEY_TYPE_CLEAR, /* no encryption */
- flags /* no ack,
- veol for beacons */
- );
+ rate |= rt->info[0].short_preamble;
+
+ ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
+ ATH9K_PKT_TYPE_BEACON,
+ MAX_RATE_POWER,
+ ATH9K_TXKEYIX_INVALID,
+ ATH9K_KEY_TYPE_CLEAR,
+ flags);
/* NB: beacon's BufLen must be a multiple of 4 bytes */
- ath9k_hw_filltxdesc(ah, ds,
- roundup(skb->len, 4), /* buffer length */
- true, /* first segment */
- true, /* last segment */
- ds /* first descriptor */
- );
+ ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
+ true, true, ds);
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
series[0].Tries = 1;
series[0].Rate = rate;
- series[0].ChSel = sc->sc_tx_chainmask;
+ series[0].ChSel = sc->tx_chainmask;
series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
- ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
- ctsrate, ctsduration, series, 4, 0);
+ ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
+ series, 4, 0);
}
-/* Generate beacon frame and queue cab data for a vap */
-static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
+static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ath_buf *bf;
- struct ath_vap *avp;
+ struct ath_vif *avp;
struct sk_buff *skb;
struct ath_txq *cabq;
- struct ieee80211_vif *vif;
struct ieee80211_tx_info *info;
int cabq_depth;
- vif = sc->sc_vaps[if_id];
- ASSERT(vif);
+ if (aphy->state != ATH_WIPHY_ACTIVE)
+ return NULL;
avp = (void *)vif->drv_priv;
cabq = sc->beacon.cabq;
@@ -161,16 +137,19 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
return NULL;
}
+ /* Release the old beacon first */
+
bf = avp->av_bcbuf;
skb = (struct sk_buff *)bf->bf_mpdu;
if (skb) {
- pci_unmap_single(sc->pdev, bf->bf_dmacontext,
- skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
}
- skb = ieee80211_beacon_get(sc->hw, vif);
+ /* Get a new beacon from mac80211 */
+
+ skb = ieee80211_beacon_get(hw, vif);
bf->bf_mpdu = skb;
if (skb == NULL)
return NULL;
@@ -188,54 +167,42 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
}
bf->bf_buf_addr = bf->bf_dmacontext =
- pci_map_single(sc->pdev, skb->data,
- skb->len,
- PCI_DMA_TODEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) {
+ dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on beaconing\n");
+ DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
return NULL;
}
- skb = ieee80211_get_buffered_bc(sc->hw, vif);
+ skb = ieee80211_get_buffered_bc(hw, vif);
/*
* if the CABQ traffic from previous DTIM is pending and the current
* beacon is also a DTIM.
- * 1) if there is only one vap let the cab traffic continue.
- * 2) if there are more than one vap and we are using staggered
+ * 1) if there is only one vif let the cab traffic continue.
+ * 2) if there are more than one vif and we are using staggered
* beacons, then drain the cabq by dropping all the frames in
- * the cabq so that the current vaps cab traffic can be scheduled.
+ * the cabq so that the current vifs cab traffic can be scheduled.
*/
spin_lock_bh(&cabq->axq_lock);
cabq_depth = cabq->axq_depth;
spin_unlock_bh(&cabq->axq_lock);
if (skb && cabq_depth) {
- /*
- * Unlock the cabq lock as ath_tx_draintxq acquires
- * the lock again which is a common function and that
- * acquires txq lock inside.
- */
- if (sc->sc_nvaps > 1) {
- ath_tx_draintxq(sc, cabq, false);
+ if (sc->nvifs > 1) {
DPRINTF(sc, ATH_DBG_BEACON,
- "flush previous cabq traffic\n");
+ "Flushing previous cabq traffic\n");
+ ath_draintxq(sc, cabq, false);
}
}
- /* Construct tx descriptor. */
ath_beacon_setup(sc, avp, bf);
- /*
- * Enable the CAB queue before the beacon queue to
- * insure cab frames are triggered by this beacon.
- */
while (skb) {
- ath_tx_cabq(sc, skb);
- skb = ieee80211_get_buffered_bc(sc->hw, vif);
+ ath_tx_cabq(hw, skb);
+ skb = ieee80211_get_buffered_bc(hw, vif);
}
return bf;
@@ -245,28 +212,22 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
* Startup beacon transmission for adhoc mode when they are sent entirely
* by the hardware using the self-linked descriptor + veol trick.
*/
-static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
+static void ath_beacon_start_adhoc(struct ath_softc *sc,
+ struct ieee80211_vif *vif)
{
- struct ieee80211_vif *vif;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_buf *bf;
- struct ath_vap *avp;
+ struct ath_vif *avp;
struct sk_buff *skb;
- vif = sc->sc_vaps[if_id];
- ASSERT(vif);
-
avp = (void *)vif->drv_priv;
- if (avp->av_bcbuf == NULL) {
- DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
- avp, avp != NULL ? avp->av_bcbuf : NULL);
+ if (avp->av_bcbuf == NULL)
return;
- }
+
bf = avp->av_bcbuf;
skb = (struct sk_buff *) bf->bf_mpdu;
- /* Construct tx descriptor. */
ath_beacon_setup(sc, avp, bf);
/* NB: caller is known to have already stopped tx dma */
@@ -276,7 +237,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
}
-int ath_beaconq_setup(struct ath_hal *ah)
+int ath_beaconq_setup(struct ath_hw *ah)
{
struct ath9k_tx_queue_info qi;
@@ -288,18 +249,15 @@ int ath_beaconq_setup(struct ath_hal *ah)
return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
}
-int ath_beacon_alloc(struct ath_softc *sc, int if_id)
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
{
- struct ieee80211_vif *vif;
- struct ath_vap *avp;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_vif *avp;
struct ieee80211_hdr *hdr;
struct ath_buf *bf;
struct sk_buff *skb;
__le64 tstamp;
- vif = sc->sc_vaps[if_id];
- ASSERT(vif);
-
avp = (void *)vif->drv_priv;
/* Allocate a beacon descriptor if we haven't done so. */
@@ -310,51 +268,46 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
struct ath_buf, list);
list_del(&avp->av_bcbuf->list);
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
- !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
+ !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
int slot;
/*
- * Assign the vap to a beacon xmit slot. As
+ * Assign the vif to a beacon xmit slot. As
* above, this cannot fail to find one.
*/
avp->av_bslot = 0;
for (slot = 0; slot < ATH_BCBUF; slot++)
- if (sc->beacon.bslot[slot] == ATH_IF_ID_ANY) {
+ if (sc->beacon.bslot[slot] == NULL) {
/*
* XXX hack, space out slots to better
* deal with misses
*/
if (slot+1 < ATH_BCBUF &&
- sc->beacon.bslot[slot+1] ==
- ATH_IF_ID_ANY) {
+ sc->beacon.bslot[slot+1] == NULL) {
avp->av_bslot = slot+1;
break;
}
avp->av_bslot = slot;
/* NB: keep looking for a double slot */
}
- BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY);
- sc->beacon.bslot[avp->av_bslot] = if_id;
- sc->sc_nbcnvaps++;
+ BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
+ sc->beacon.bslot[avp->av_bslot] = vif;
+ sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
+ sc->nbcnvifs++;
}
}
- /* release the previous beacon frame , if it already exists. */
+ /* 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;
- pci_unmap_single(sc->pdev, bf->bf_dmacontext,
- skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
- /*
- * NB: the beacon data buffer must be 32-bit aligned.
- * FIXME: Fill avp->av_btxctl.txpower and
- * avp->av_btxctl.shortPreamble
- */
+ /* NB: the beacon data buffer must be 32-bit aligned. */
skb = ieee80211_beacon_get(sc->hw, vif);
if (skb == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
@@ -384,8 +337,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
* timestamp then convert to TSF units and handle
* byte swapping before writing it in the frame.
* The hardware will then add this each time a beacon
- * frame is sent. Note that we align vap's 1..N
- * and leave vap 0 untouched. This means vap 0
+ * frame is sent. Note that we align vif's 1..N
+ * and leave vif 0 untouched. This means vap 0
* has a timestamp in one beacon interval while the
* others get a timestamp aligned to the next interval.
*/
@@ -402,36 +355,35 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
bf->bf_mpdu = skb;
bf->bf_buf_addr = bf->bf_dmacontext =
- pci_map_single(sc->pdev, skb->data,
- skb->len,
- PCI_DMA_TODEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) {
+ dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on beacon alloc\n");
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "dma_mapping_error on beacon alloc\n");
return -ENOMEM;
}
return 0;
}
-void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
{
if (avp->av_bcbuf != NULL) {
struct ath_buf *bf;
if (avp->av_bslot != -1) {
- sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY;
- sc->sc_nbcnvaps--;
+ sc->beacon.bslot[avp->av_bslot] = NULL;
+ sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
+ sc->nbcnvifs--;
}
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
- pci_unmap_single(sc->pdev, bf->bf_dmacontext,
- skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
@@ -441,92 +393,45 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
}
}
-void ath9k_beacon_tasklet(unsigned long data)
+void ath_beacon_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_buf *bf = NULL;
- int slot, if_id;
- u32 bfaddr;
- u32 rx_clear = 0, rx_frame = 0, tx_frame = 0;
- u32 show_cycles = 0;
- u32 bc = 0; /* beacon count */
+ struct ieee80211_vif *vif;
+ struct ath_wiphy *aphy;
+ int slot;
+ u32 bfaddr, bc = 0, tsftu;
u64 tsf;
- u32 tsftu;
u16 intval;
- if (sc->sc_flags & SC_OP_NO_RESET) {
- show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
- &rx_clear, &rx_frame, &tx_frame);
- }
-
/*
* Check if the previous beacon has gone out. If
* not don't try to post another, skip this period
* and wait for the next. Missed beacons indicate
* a problem and should not occur. If we miss too
* many consecutive beacons reset the device.
- *
- * FIXME: Clean up this mess !!
*/
if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
sc->beacon.bmisscnt++;
- /* XXX: doth needs the chanchange IE countdown decremented.
- * We should consider adding a mac80211 call to indicate
- * a beacon miss so appropriate action could be taken
- * (in that layer).
- */
+
if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
- if (sc->sc_flags & SC_OP_NO_RESET) {
- DPRINTF(sc, ATH_DBG_BEACON,
- "missed %u consecutive beacons\n",
- sc->beacon.bmisscnt);
- if (show_cycles) {
- /*
- * Display cycle counter stats from HW
- * to aide in debug of stickiness.
- */
- DPRINTF(sc, ATH_DBG_BEACON,
- "busy times: rx_clear=%d, "
- "rx_frame=%d, tx_frame=%d\n",
- rx_clear, rx_frame,
- tx_frame);
- } else {
- DPRINTF(sc, ATH_DBG_BEACON,
- "unable to obtain "
- "busy times\n");
- }
- } else {
- DPRINTF(sc, ATH_DBG_BEACON,
- "missed %u consecutive beacons\n",
- sc->beacon.bmisscnt);
- }
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "missed %u consecutive beacons\n",
+ sc->beacon.bmisscnt);
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
- if (sc->sc_flags & SC_OP_NO_RESET) {
- if (sc->beacon.bmisscnt == BSTUCK_THRESH) {
- DPRINTF(sc, ATH_DBG_BEACON,
- "beacon is officially "
- "stuck\n");
- }
- } else {
- DPRINTF(sc, ATH_DBG_BEACON,
- "beacon is officially stuck\n");
- ath_bstuck_process(sc);
- }
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "beacon is officially stuck\n");
+ ath_reset(sc, false);
}
+
return;
}
if (sc->beacon.bmisscnt != 0) {
- if (sc->sc_flags & SC_OP_NO_RESET) {
- DPRINTF(sc, ATH_DBG_BEACON,
- "resume beacon xmit after %u misses\n",
- sc->beacon.bmisscnt);
- } else {
- DPRINTF(sc, ATH_DBG_BEACON,
- "resume beacon xmit after %u misses\n",
- sc->beacon.bmisscnt);
- }
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "resume beacon xmit after %u misses\n",
+ sc->beacon.bmisscnt);
sc->beacon.bmisscnt = 0;
}
@@ -542,21 +447,22 @@ void ath9k_beacon_tasklet(unsigned long data)
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf);
slot = ((tsftu % intval) * ATH_BCBUF) / intval;
- if_id = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
+ vif = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
+ aphy = sc->beacon.bslot_aphy[(slot + 1) % ATH_BCBUF];
DPRINTF(sc, ATH_DBG_BEACON,
- "slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
- slot, (unsigned long long)tsf, tsftu,
- intval, if_id);
+ "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+ slot, tsf, tsftu, intval, vif);
bfaddr = 0;
- if (if_id != ATH_IF_ID_ANY) {
- bf = ath_beacon_generate(sc, if_id);
+ if (vif) {
+ bf = ath_beacon_generate(aphy->hw, vif);
if (bf != NULL) {
bfaddr = bf->bf_daddr;
bc = 1;
}
}
+
/*
* Handle slot time change when a non-ERP station joins/leaves
* an 11g network. The 802.11 layer notifies us via callback,
@@ -573,7 +479,6 @@ void ath9k_beacon_tasklet(unsigned long data)
* interval has passed. When bursting slot is always left
* set to ATH_BCBUF so this check is a noop.
*/
- /* XXX locking */
if (sc->beacon.updateslot == UPDATE) {
sc->beacon.updateslot = COMMIT; /* commit next beacon */
sc->beacon.slotupdate = slot;
@@ -590,265 +495,250 @@ void ath9k_beacon_tasklet(unsigned long data)
if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
DPRINTF(sc, ATH_DBG_FATAL,
"beacon queue %u did not stop?\n", sc->beacon.beaconq);
- /* NB: the HAL still stops DMA, so proceed */
}
/* NB: cabq traffic should already be queued and primed */
ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
ath9k_hw_txstart(ah, sc->beacon.beaconq);
- sc->beacon.ast_be_xmit += bc; /* XXX per-vap? */
+ sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */
}
}
/*
- * Configure the beacon and sleep timers.
- *
- * When operating as an AP this resets the TSF and sets
- * up the hardware to notify us when we need to issue beacons.
- *
- * When operating in station mode this sets up the beacon
- * timers according to the timestamp of the last received
- * beacon and the current TSF, configures PCF and DTIM
- * handling, programs the sleep registers so the hardware
- * will wakeup in time to receive beacons, and configures
- * the beacon miss handling so we'll receive a BMISS
- * interrupt when we stop seeing beacons from the AP
- * we've associated with.
+ * For multi-bss ap support beacons are either staggered evenly over N slots or
+ * burst together. For the former arrange for the SWBA to be delivered for each
+ * slot. Slots that are not occupied will generate nothing.
*/
-void ath_beacon_config(struct ath_softc *sc, int if_id)
+static void ath_beacon_config_ap(struct ath_softc *sc,
+ struct ath_beacon_config *conf,
+ struct ath_vif *avp)
{
- struct ieee80211_vif *vif;
- struct ath_hal *ah = sc->sc_ah;
- struct ath_beacon_config conf;
- struct ath_vap *avp;
- enum nl80211_iftype opmode;
u32 nexttbtt, intval;
- if (if_id != ATH_IF_ID_ANY) {
- vif = sc->sc_vaps[if_id];
- ASSERT(vif);
- avp = (void *)vif->drv_priv;
- opmode = avp->av_opmode;
- } else {
- opmode = sc->sc_ah->ah_opmode;
- }
+ /* Configure the timers only when the TSF has to be reset */
- memset(&conf, 0, sizeof(struct ath_beacon_config));
+ if (!(sc->sc_flags & SC_OP_TSF_RESET))
+ return;
- 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;
+ /* NB: the beacon interval is kept internally in TU's */
+ intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+ intval /= ATH_BCBUF; /* for staggered beacons */
+ nexttbtt = intval;
+ intval |= ATH9K_BEACON_RESET_TSF;
- /* extract tstamp from last beacon and convert to TU */
- nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+ /*
+ * In AP mode we enable the beacon timers and SWBA interrupts to
+ * prepare beacon frames.
+ */
+ intval |= ATH9K_BEACON_ENA;
+ sc->imask |= ATH9K_INT_SWBA;
+ ath_beaconq_config(sc);
- /* XXX conditionalize multi-bss support? */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
- /*
- * For multi-bss ap support beacons are either staggered
- * evenly over N slots or burst together. For the former
- * arrange for the SWBA to be delivered for each slot.
- * Slots that are not occupied will generate nothing.
- */
- /* NB: the beacon interval is kept internally in TU's */
- intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
- intval /= ATH_BCBUF; /* for staggered beacons */
- } else {
- intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
- }
+ /* Set the computed AP beacon timers */
- if (nexttbtt == 0) /* e.g. for ap mode */
- nexttbtt = intval;
- else if (intval) /* NB: can be 0 for monitor mode */
- nexttbtt = roundup(nexttbtt, intval);
+ ath9k_hw_set_interrupts(sc->sc_ah, 0);
+ ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+ sc->beacon.bmisscnt = 0;
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
- DPRINTF(sc, ATH_DBG_BEACON, "nexttbtt %u intval %u (%u)\n",
- nexttbtt, intval, conf.beacon_interval);
+ /* Clear the reset TSF flag, so that subsequent beacon updation
+ will not reset the HW TSF. */
- /* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) {
- struct ath9k_beacon_state bs;
- u64 tsf;
- u32 tsftu;
- int dtimperiod, dtimcount, sleepduration;
- int cfpperiod, cfpcount;
+ sc->sc_flags &= ~SC_OP_TSF_RESET;
+}
- /*
- * Setup dtim and cfp parameters according to
- * last beacon we received (which may be none).
- */
- dtimperiod = conf.dtim_period;
- if (dtimperiod <= 0) /* NB: 0 if not known */
- dtimperiod = 1;
- dtimcount = conf.dtim_count;
- if (dtimcount >= dtimperiod) /* NB: sanity check */
- dtimcount = 0;
- cfpperiod = 1; /* NB: no PCF support yet */
- cfpcount = 0;
-
- sleepduration = conf.listen_interval * intval;
- if (sleepduration <= 0)
- sleepduration = intval;
+/*
+ * This sets up the beacon timers according to the timestamp of the last
+ * received beacon and the current TSF, configures PCF and DTIM
+ * handling, programs the sleep registers so the hardware will wakeup in
+ * time to receive beacons, and configures the beacon miss handling so
+ * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
+ * we've associated with.
+ */
+static void ath_beacon_config_sta(struct ath_softc *sc,
+ struct ath_beacon_config *conf,
+ struct ath_vif *avp)
+{
+ struct ath9k_beacon_state bs;
+ int dtimperiod, dtimcount, sleepduration;
+ int cfpperiod, cfpcount;
+ u32 nexttbtt = 0, intval, tsftu;
+ u64 tsf;
-#define FUDGE 2
- /*
- * Pull nexttbtt forward to reflect the current
- * TSF and calculate dtim+cfp state for the result.
- */
- tsf = ath9k_hw_gettsf64(ah);
- tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
- do {
- nexttbtt += intval;
- if (--dtimcount < 0) {
- dtimcount = dtimperiod - 1;
- if (--cfpcount < 0)
- cfpcount = cfpperiod - 1;
- }
- } while (nexttbtt < tsftu);
-#undef FUDGE
- memset(&bs, 0, sizeof(bs));
- bs.bs_intval = intval;
- bs.bs_nexttbtt = nexttbtt;
- bs.bs_dtimperiod = dtimperiod*intval;
- bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
- bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
- bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
- bs.bs_cfpmaxduration = 0;
+ memset(&bs, 0, sizeof(bs));
+ intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
- /*
- * Calculate the number of consecutive beacons to miss
- * before taking a BMISS interrupt. The configuration
- * is specified in TU so we only need calculate based
- * on the beacon interval. Note that we clamp the
- * result to at most 15 beacons.
- */
- if (sleepduration > intval) {
- bs.bs_bmissthreshold = conf.listen_interval *
- ATH_DEFAULT_BMISS_LIMIT / 2;
- } else {
- bs.bs_bmissthreshold =
- DIV_ROUND_UP(conf.bmiss_timeout, intval);
- if (bs.bs_bmissthreshold > 15)
- bs.bs_bmissthreshold = 15;
- else if (bs.bs_bmissthreshold <= 0)
- bs.bs_bmissthreshold = 1;
- }
+ /*
+ * Setup dtim and cfp parameters according to
+ * last beacon we received (which may be none).
+ */
+ dtimperiod = conf->dtim_period;
+ if (dtimperiod <= 0) /* NB: 0 if not known */
+ dtimperiod = 1;
+ dtimcount = conf->dtim_count;
+ if (dtimcount >= dtimperiod) /* NB: sanity check */
+ dtimcount = 0;
+ cfpperiod = 1; /* NB: no PCF support yet */
+ cfpcount = 0;
+
+ sleepduration = conf->listen_interval * intval;
+ if (sleepduration <= 0)
+ sleepduration = intval;
- /*
- * Calculate sleep duration. The configuration is
- * given in ms. We insure a multiple of the beacon
- * period is used. Also, if the sleep duration is
- * greater than the DTIM period then it makes senses
- * to make it a multiple of that.
- *
- * XXX fixed at 100ms
- */
+ /*
+ * Pull nexttbtt forward to reflect the current
+ * TSF and calculate dtim+cfp state for the result.
+ */
+ tsf = ath9k_hw_gettsf64(sc->sc_ah);
+ tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
+ do {
+ nexttbtt += intval;
+ if (--dtimcount < 0) {
+ dtimcount = dtimperiod - 1;
+ if (--cfpcount < 0)
+ cfpcount = cfpperiod - 1;
+ }
+ } while (nexttbtt < tsftu);
- bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100),
- sleepduration);
- if (bs.bs_sleepduration > bs.bs_dtimperiod)
- bs.bs_sleepduration = bs.bs_dtimperiod;
+ bs.bs_intval = intval;
+ bs.bs_nexttbtt = nexttbtt;
+ bs.bs_dtimperiod = dtimperiod*intval;
+ bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
+ bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
+ bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
+ bs.bs_cfpmaxduration = 0;
- DPRINTF(sc, ATH_DBG_BEACON,
- "tsf %llu "
- "tsf:tu %u "
- "intval %u "
- "nexttbtt %u "
- "dtim %u "
- "nextdtim %u "
- "bmiss %u "
- "sleep %u "
- "cfp:period %u "
- "maxdur %u "
- "next %u "
- "timoffset %u\n",
- (unsigned long long)tsf, tsftu,
- bs.bs_intval,
- bs.bs_nexttbtt,
- bs.bs_dtimperiod,
- bs.bs_nextdtim,
- bs.bs_bmissthreshold,
- bs.bs_sleepduration,
- bs.bs_cfpperiod,
- bs.bs_cfpmaxduration,
- bs.bs_cfpnext,
- bs.bs_timoffset
- );
-
- ath9k_hw_set_interrupts(ah, 0);
- ath9k_hw_set_sta_beacon_timers(ah, &bs);
- sc->sc_imask |= ATH9K_INT_BMISS;
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ /*
+ * Calculate the number of consecutive beacons to miss* before taking
+ * a BMISS interrupt. The configuration is specified in TU so we only
+ * need calculate based on the beacon interval. Note that we clamp the
+ * result to at most 15 beacons.
+ */
+ if (sleepduration > intval) {
+ bs.bs_bmissthreshold = conf->listen_interval *
+ ATH_DEFAULT_BMISS_LIMIT / 2;
} else {
- u64 tsf;
- u32 tsftu;
- ath9k_hw_set_interrupts(ah, 0);
- if (nexttbtt == intval)
- intval |= ATH9K_BEACON_RESET_TSF;
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
- /*
- * Pull nexttbtt forward to reflect the current
- * TSF
- */
-#define FUDGE 2
- if (!(intval & ATH9K_BEACON_RESET_TSF)) {
- tsf = ath9k_hw_gettsf64(ah);
- tsftu = TSF_TO_TU((u32)(tsf>>32),
- (u32)tsf) + FUDGE;
- do {
- nexttbtt += intval;
- } while (nexttbtt < tsftu);
- }
-#undef FUDGE
- DPRINTF(sc, ATH_DBG_BEACON,
- "IBSS nexttbtt %u intval %u (%u)\n",
- nexttbtt,
- intval & ~ATH9K_BEACON_RESET_TSF,
- conf.beacon_interval);
-
- /*
- * In IBSS mode enable the beacon timers but only
- * enable SWBA interrupts if we need to manually
- * prepare beacon frames. Otherwise we use a
- * self-linked tx descriptor and let the hardware
- * deal with things.
- */
- intval |= ATH9K_BEACON_ENA;
- if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
- sc->sc_imask |= ATH9K_INT_SWBA;
- ath_beaconq_config(sc);
- } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
- /*
- * In AP mode we enable the beacon timers and
- * SWBA interrupts to prepare beacon frames.
- */
- intval |= ATH9K_BEACON_ENA;
- sc->sc_imask |= ATH9K_INT_SWBA; /* beacon prepare */
- ath_beaconq_config(sc);
- }
- ath9k_hw_beaconinit(ah, nexttbtt, intval);
- sc->beacon.bmisscnt = 0;
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
- /*
- * When using a self-linked beacon descriptor in
- * ibss mode load it once here.
- */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC &&
- (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
- ath_beacon_start_adhoc(sc, 0);
+ bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval);
+ if (bs.bs_bmissthreshold > 15)
+ bs.bs_bmissthreshold = 15;
+ else if (bs.bs_bmissthreshold <= 0)
+ bs.bs_bmissthreshold = 1;
}
+
+ /*
+ * Calculate sleep duration. The configuration is given in ms.
+ * We ensure a multiple of the beacon period is used. Also, if the sleep
+ * duration is greater than the DTIM period then it makes senses
+ * to make it a multiple of that.
+ *
+ * XXX fixed at 100ms
+ */
+
+ bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
+ if (bs.bs_sleepduration > bs.bs_dtimperiod)
+ bs.bs_sleepduration = bs.bs_dtimperiod;
+
+ /* TSF out of range threshold fixed at 1 second */
+ bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
+
+ DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+ bs.bs_bmissthreshold, bs.bs_sleepduration,
+ bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+
+ /* Set the computed STA beacon timers */
+
+ ath9k_hw_set_interrupts(sc->sc_ah, 0);
+ ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
+ sc->imask |= ATH9K_INT_BMISS;
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
}
-void ath_beacon_sync(struct ath_softc *sc, int if_id)
+static void ath_beacon_config_adhoc(struct ath_softc *sc,
+ struct ath_beacon_config *conf,
+ struct ath_vif *avp,
+ struct ieee80211_vif *vif)
{
+ u64 tsf;
+ u32 tsftu, intval, nexttbtt;
+
+ intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+
+ /* Pull nexttbtt forward to reflect the current TSF */
+
+ nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+ if (nexttbtt == 0)
+ nexttbtt = intval;
+ else if (intval)
+ nexttbtt = roundup(nexttbtt, intval);
+
+ tsf = ath9k_hw_gettsf64(sc->sc_ah);
+ tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
+ do {
+ nexttbtt += intval;
+ } while (nexttbtt < tsftu);
+
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "IBSS nexttbtt %u intval %u (%u)\n",
+ nexttbtt, intval, conf->beacon_interval);
+
/*
- * Resync beacon timers using the tsf of the
- * beacon frame we just received.
+ * In IBSS mode enable the beacon timers but only enable SWBA interrupts
+ * if we need to manually prepare beacon frames. Otherwise we use a
+ * self-linked tx descriptor and let the hardware deal with things.
*/
- ath_beacon_config(sc, if_id);
- sc->sc_flags |= SC_OP_BEACONS;
+ intval |= ATH9K_BEACON_ENA;
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
+ sc->imask |= ATH9K_INT_SWBA;
+
+ ath_beaconq_config(sc);
+
+ /* Set the computed ADHOC beacon timers */
+
+ ath9k_hw_set_interrupts(sc->sc_ah, 0);
+ ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+ sc->beacon.bmisscnt = 0;
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
+ ath_beacon_start_adhoc(sc, vif);
+}
+
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+ struct ath_beacon_config conf;
+
+ /* Setup the beacon configuration parameters */
+
+ memset(&conf, 0, sizeof(struct ath_beacon_config));
+ conf.beacon_interval = sc->hw->conf.beacon_int ?
+ sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+ conf.listen_interval = 1;
+ conf.dtim_period = conf.beacon_interval;
+ conf.dtim_count = 1;
+ conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
+
+ if (vif) {
+ struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
+
+ switch(avp->av_opmode) {
+ case NL80211_IFTYPE_AP:
+ ath_beacon_config_ap(sc, &conf, avp);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ath_beacon_config_adhoc(sc, &conf, avp, vif);
+ break;
+ case NL80211_IFTYPE_STATION:
+ ath_beacon_config_sta(sc, &conf, avp);
+ break;
+ default:
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "Unsupported beaconing mode\n");
+ return;
+ }
+
+ sc->sc_flags |= SC_OP_BEACONS;
+ }
}
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
index 3c7454fc51b..c9446fb6b15 100644
--- a/drivers/net/wireless/ath9k/calib.c
+++ b/drivers/net/wireless/ath9k/calib.c
@@ -14,12 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
-
-static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
+#include "ath9k.h"
/* We can tune this as we go by monitoring really low values */
#define ATH9K_NF_TOO_LOW -60
@@ -28,7 +23,7 @@ static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
* is incorrect and we should use the static NF value. Later we can try to
* find out why they are reporting these values */
-static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
+static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
{
if (nf > ATH9K_NF_TOO_LOW) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
@@ -91,7 +86,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
return;
}
-static void ath9k_hw_do_getnf(struct ath_hal *ah,
+static void ath9k_hw_do_getnf(struct ath_hw *ah,
int16_t nfarray[NUM_NF_READINGS])
{
int16_t nf;
@@ -107,27 +102,29 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
"NF calibrated [ctl] [chain 0] is %d\n", nf);
nfarray[0] = nf;
- if (AR_SREV_9280_10_OR_LATER(ah))
- nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
- AR9280_PHY_CH1_MINCCA_PWR);
- else
- nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
- AR_PHY_CH1_MINCCA_PWR);
-
- if (nf & 0x100)
- nf = 0 - ((nf ^ 0x1ff) + 1);
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "NF calibrated [ctl] [chain 1] is %d\n", nf);
- nfarray[1] = nf;
+ if (!AR_SREV_9285(ah)) {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+ AR9280_PHY_CH1_MINCCA_PWR);
+ else
+ nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+ AR_PHY_CH1_MINCCA_PWR);
- if (!AR_SREV_9280(ah)) {
- nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
- AR_PHY_CH2_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "NF calibrated [ctl] [chain 2] is %d\n", nf);
- nfarray[2] = nf;
+ "NF calibrated [ctl] [chain 1] is %d\n", nf);
+ nfarray[1] = nf;
+
+ if (!AR_SREV_9280(ah)) {
+ nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
+ AR_PHY_CH2_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+ "NF calibrated [ctl] [chain 2] is %d\n", nf);
+ nfarray[2] = nf;
+ }
}
if (AR_SREV_9280_10_OR_LATER(ah))
@@ -143,58 +140,52 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
"NF calibrated [ext] [chain 0] is %d\n", nf);
nfarray[3] = nf;
- if (AR_SREV_9280_10_OR_LATER(ah))
- nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
- AR9280_PHY_CH1_EXT_MINCCA_PWR);
- else
- nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
- AR_PHY_CH1_EXT_MINCCA_PWR);
-
- if (nf & 0x100)
- nf = 0 - ((nf ^ 0x1ff) + 1);
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "NF calibrated [ext] [chain 1] is %d\n", nf);
- nfarray[4] = nf;
+ if (!AR_SREV_9285(ah)) {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+ AR9280_PHY_CH1_EXT_MINCCA_PWR);
+ else
+ nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+ AR_PHY_CH1_EXT_MINCCA_PWR);
- if (!AR_SREV_9280(ah)) {
- nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
- AR_PHY_CH2_EXT_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "NF calibrated [ext] [chain 2] is %d\n", nf);
- nfarray[5] = nf;
+ "NF calibrated [ext] [chain 1] is %d\n", nf);
+ nfarray[4] = nf;
+
+ if (!AR_SREV_9280(ah)) {
+ nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
+ AR_PHY_CH2_EXT_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+ "NF calibrated [ext] [chain 2] is %d\n", nf);
+ nfarray[5] = nf;
+ }
}
}
-static bool getNoiseFloorThresh(struct ath_hal *ah,
- const struct ath9k_channel *chan,
+static bool getNoiseFloorThresh(struct ath_hw *ah,
+ enum ieee80211_band band,
int16_t *nft)
{
- switch (chan->chanmode) {
- case CHANNEL_A:
- case CHANNEL_A_HT20:
- case CHANNEL_A_HT40PLUS:
- case CHANNEL_A_HT40MINUS:
- *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
+ switch (band) {
+ case IEEE80211_BAND_5GHZ:
+ *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
break;
- case CHANNEL_B:
- case CHANNEL_G:
- case CHANNEL_G_HT20:
- case CHANNEL_G_HT40PLUS:
- case CHANNEL_G_HT40MINUS:
- *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
+ case IEEE80211_BAND_2GHZ:
+ *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel flags 0x%x\n", chan->channelFlags);
+ BUG_ON(1);
return false;
}
return true;
}
-static void ath9k_hw_setup_calibration(struct ath_hal *ah,
+static void ath9k_hw_setup_calibration(struct ath_hw *ah,
struct hal_cal_list *currCal)
{
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
@@ -228,10 +219,9 @@ static void ath9k_hw_setup_calibration(struct ath_hal *ah,
AR_PHY_TIMING_CTRL4_DO_CAL);
}
-static void ath9k_hw_reset_calibration(struct ath_hal *ah,
+static void ath9k_hw_reset_calibration(struct ath_hw *ah,
struct hal_cal_list *currCal)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
ath9k_hw_setup_calibration(ah, currCal);
@@ -239,23 +229,21 @@ static void ath9k_hw_reset_calibration(struct ath_hal *ah,
currCal->calState = CAL_RUNNING;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ahp->ah_Meas0.sign[i] = 0;
- ahp->ah_Meas1.sign[i] = 0;
- ahp->ah_Meas2.sign[i] = 0;
- ahp->ah_Meas3.sign[i] = 0;
+ ah->meas0.sign[i] = 0;
+ ah->meas1.sign[i] = 0;
+ ah->meas2.sign[i] = 0;
+ ah->meas3.sign[i] = 0;
}
- ahp->ah_CalSamples = 0;
+ ah->cal_samples = 0;
}
-static void ath9k_hw_per_calibration(struct ath_hal *ah,
+static void ath9k_hw_per_calibration(struct ath_hw *ah,
struct ath9k_channel *ichan,
u8 rxchainmask,
struct hal_cal_list *currCal,
bool *isCalDone)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
*isCalDone = false;
if (currCal->calState == CAL_RUNNING) {
@@ -263,9 +251,9 @@ static void ath9k_hw_per_calibration(struct ath_hal *ah,
AR_PHY_TIMING_CTRL4_DO_CAL)) {
currCal->calData->calCollect(ah);
- ahp->ah_CalSamples++;
+ ah->cal_samples++;
- if (ahp->ah_CalSamples >= currCal->calData->calNumSamples) {
+ if (ah->cal_samples >= currCal->calData->calNumSamples) {
int i, numChains = 0;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (rxchainmask & (1 << i))
@@ -285,113 +273,105 @@ static void ath9k_hw_per_calibration(struct ath_hal *ah,
}
}
-static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
- struct ath9k_channel *chan,
+/* Assumes you are talking about the currently configured channel */
+static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
enum hal_cal_types calType)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- bool retval = false;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
- switch (calType & ahp->ah_suppCals) {
- case IQ_MISMATCH_CAL:
- if (!IS_CHAN_B(chan))
- retval = true;
- break;
+ switch (calType & ah->supp_cals) {
+ case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
+ return true;
case ADC_GAIN_CAL:
case ADC_DC_CAL:
- if (!IS_CHAN_B(chan)
- && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
- retval = true;
+ if (conf->channel->band == IEEE80211_BAND_5GHZ &&
+ conf_is_ht20(conf))
+ return true;
break;
}
-
- return retval;
+ return false;
}
-static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
+static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ahp->ah_totalPowerMeasI[i] +=
+ ah->totalPowerMeasI[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
- ahp->ah_totalPowerMeasQ[i] +=
+ ah->totalPowerMeasQ[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
- ahp->ah_totalIqCorrMeas[i] +=
+ ah->totalIqCorrMeas[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
- ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
- ahp->ah_totalPowerMeasQ[i],
- ahp->ah_totalIqCorrMeas[i]);
+ ah->cal_samples, i, ah->totalPowerMeasI[i],
+ ah->totalPowerMeasQ[i],
+ ah->totalIqCorrMeas[i]);
}
}
-static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
+static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ahp->ah_totalAdcIOddPhase[i] +=
+ ah->totalAdcIOddPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
- ahp->ah_totalAdcIEvenPhase[i] +=
+ ah->totalAdcIEvenPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
- ahp->ah_totalAdcQOddPhase[i] +=
+ ah->totalAdcQOddPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ahp->ah_totalAdcQEvenPhase[i] +=
+ ah->totalAdcQEvenPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
"oddq=0x%08x; evenq=0x%08x;\n",
- ahp->ah_CalSamples, i,
- ahp->ah_totalAdcIOddPhase[i],
- ahp->ah_totalAdcIEvenPhase[i],
- ahp->ah_totalAdcQOddPhase[i],
- ahp->ah_totalAdcQEvenPhase[i]);
+ ah->cal_samples, i,
+ ah->totalAdcIOddPhase[i],
+ ah->totalAdcIEvenPhase[i],
+ ah->totalAdcQOddPhase[i],
+ ah->totalAdcQEvenPhase[i]);
}
}
-static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
+static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
+ ah->totalAdcDcOffsetIOddPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
- ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
+ ah->totalAdcDcOffsetIEvenPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
- ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
+ ah->totalAdcDcOffsetQOddPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
+ ah->totalAdcDcOffsetQEvenPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
"oddq=0x%08x; evenq=0x%08x;\n",
- ahp->ah_CalSamples, i,
- ahp->ah_totalAdcDcOffsetIOddPhase[i],
- ahp->ah_totalAdcDcOffsetIEvenPhase[i],
- ahp->ah_totalAdcDcOffsetQOddPhase[i],
- ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
+ ah->cal_samples, i,
+ ah->totalAdcDcOffsetIOddPhase[i],
+ ah->totalAdcDcOffsetIEvenPhase[i],
+ ah->totalAdcDcOffsetQOddPhase[i],
+ ah->totalAdcDcOffsetQEvenPhase[i]);
}
}
-static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 powerMeasQ, powerMeasI, iqCorrMeas;
u32 qCoffDenom, iCoffDenom;
int32_t qCoff, iCoff;
int iqCorrNeg, i;
for (i = 0; i < numChains; i++) {
- powerMeasI = ahp->ah_totalPowerMeasI[i];
- powerMeasQ = ahp->ah_totalPowerMeasQ[i];
- iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
+ powerMeasI = ah->totalPowerMeasI[i];
+ powerMeasQ = ah->totalPowerMeasQ[i];
+ iqCorrMeas = ah->totalIqCorrMeas[i];
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Starting IQ Cal and Correction for Chain %d\n",
@@ -399,7 +379,7 @@ static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Orignal: Chn %diq_corr_meas = 0x%08x\n",
- i, ahp->ah_totalIqCorrMeas[i]);
+ i, ah->totalIqCorrMeas[i]);
iqCorrNeg = 0;
@@ -457,17 +437,16 @@ static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
}
-static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
u32 qGainMismatch, iGainMismatch, val, i;
for (i = 0; i < numChains; i++) {
- iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
- iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
- qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
- qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
+ iOddMeasOffset = ah->totalAdcIOddPhase[i];
+ iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
+ qOddMeasOffset = ah->totalAdcQOddPhase[i];
+ qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Starting ADC Gain Cal for Chain %d\n", i);
@@ -515,21 +494,20 @@ static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
}
-static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 iOddMeasOffset, iEvenMeasOffset, val, i;
int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
const struct hal_percal_data *calData =
- ahp->ah_cal_list_curr->calData;
+ ah->cal_list_curr->calData;
u32 numSamples =
(1 << (calData->calCountMax + 5)) * calData->calNumSamples;
for (i = 0; i < numChains; i++) {
- iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
- iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
- qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
- qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
+ iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
+ iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
+ qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
+ qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Starting ADC DC Offset Cal for Chain %d\n", i);
@@ -573,53 +551,42 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
}
-void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
- bool *isCalDone)
+/* This is done for the currently configured channel */
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *ichan =
- ath9k_regd_check_channel(ah, chan);
- struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+ struct hal_cal_list *currCal = ah->cal_list_curr;
- *isCalDone = true;
+ if (!ah->curchan)
+ return true;
if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
- return;
+ return true;
if (currCal == NULL)
- return;
-
- if (ichan == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "invalid channel %u/0x%x; no mapping\n",
- chan->channel, chan->channelFlags);
- return;
- }
-
+ return true;
if (currCal->calState != CAL_DONE) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Calibration state incorrect, %d\n",
currCal->calState);
- return;
+ return true;
}
-
- if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
- return;
+ if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
+ return true;
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "Resetting Cal %d state for channel %u/0x%x\n",
- currCal->calData->calType, chan->channel,
- chan->channelFlags);
+ "Resetting Cal %d state for channel %u\n",
+ currCal->calData->calType, conf->channel->center_freq);
- ichan->CalValid &= ~currCal->calData->calType;
+ ah->curchan->CalValid &= ~currCal->calData->calType;
currCal->calState = CAL_WAITING;
- *isCalDone = false;
+ return false;
}
-void ath9k_hw_start_nfcal(struct ath_hal *ah)
+void ath9k_hw_start_nfcal(struct ath_hw *ah)
{
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_ENABLE_NF);
@@ -628,7 +595,7 @@ void ath9k_hw_start_nfcal(struct ath_hal *ah)
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
}
-void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
{
struct ath9k_nfcal_hist *h;
int i, j;
@@ -643,16 +610,14 @@ void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
};
u8 chainmask;
- if (AR_SREV_9280(ah))
+ if (AR_SREV_9285(ah))
+ chainmask = 0x9;
+ else if (AR_SREV_9280(ah))
chainmask = 0x1B;
else
chainmask = 0x3F;
-#ifdef ATH_NF_PER_CHAN
- h = chan->nfCalHist;
-#else
h = ah->nfCalHist;
-#endif
for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) {
@@ -686,18 +651,13 @@ void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
}
}
-int16_t ath9k_hw_getnf(struct ath_hal *ah,
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
struct ath9k_channel *chan)
{
int16_t nf, nfThresh;
int16_t nfarray[NUM_NF_READINGS] = { 0 };
struct ath9k_nfcal_hist *h;
- u8 chainmask;
-
- if (AR_SREV_9280(ah))
- chainmask = 0x1B;
- else
- chainmask = 0x3F;
+ struct ieee80211_channel *c = chan->chan;
chan->channelFlags &= (~CHANNEL_CW_INT);
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
@@ -709,7 +669,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
} else {
ath9k_hw_do_getnf(ah, nfarray);
nf = nfarray[0];
- if (getNoiseFloorThresh(ah, chan, &nfThresh)
+ if (getNoiseFloorThresh(ah, c->band, &nfThresh)
&& nf > nfThresh) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"noise floor failed detected; "
@@ -719,11 +679,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
}
}
-#ifdef ATH_NF_PER_CHAN
- h = chan->nfCalHist;
-#else
h = ah->nfCalHist;
-#endif
ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
chan->rawNoiseFloor = h[0].privNF;
@@ -731,7 +687,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
return chan->rawNoiseFloor;
}
-void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
{
int i, j;
@@ -745,26 +701,16 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
AR_PHY_CCA_MAX_GOOD_VALUE;
}
}
- return;
}
-s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
{
- struct ath9k_channel *ichan;
s16 nf;
- ichan = ath9k_regd_check_channel(ah, chan);
- if (ichan == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "invalid channel %u/0x%x; no mapping\n",
- chan->channel, chan->channelFlags);
- return ATH_DEFAULT_NOISE_FLOOR;
- }
- if (ichan->rawNoiseFloor == 0) {
- enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
- nf = NOISE_FLOOR[mode];
- } else
- nf = ichan->rawNoiseFloor;
+ if (chan->rawNoiseFloor == 0)
+ nf = -96;
+ else
+ nf = chan->rawNoiseFloor;
if (!ath9k_hw_nf_in_range(ah, nf))
nf = ATH_DEFAULT_NOISE_FLOOR;
@@ -772,53 +718,34 @@ s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
return nf;
}
-bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
- u8 rxchainmask, bool longcal,
- bool *isCalDone)
+static void ath9k_olc_temp_compensation(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
- struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+ u32 rddata, i;
+ int delta, currPDADC, regval;
- *isCalDone = true;
+ rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
- if (ichan == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; no mapping\n",
- chan->channel, chan->channelFlags);
- return false;
- }
+ currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
- if (currCal &&
- (currCal->calState == CAL_RUNNING ||
- currCal->calState == CAL_WAITING)) {
- ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
- isCalDone);
- if (*isCalDone) {
- ahp->ah_cal_list_curr = currCal = currCal->calNext;
-
- if (currCal->calState == CAL_WAITING) {
- *isCalDone = false;
- ath9k_hw_reset_calibration(ah, currCal);
- }
- }
- }
+ if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+ delta = (currPDADC - ah->initPDADC + 4) / 8;
+ else
+ delta = (currPDADC - ah->initPDADC + 5) / 10;
- if (longcal) {
- ath9k_hw_getnf(ah, ichan);
- ath9k_hw_loadnf(ah, ah->ah_curchan);
- ath9k_hw_start_nfcal(ah);
+ if (delta != ah->PDADCdelta) {
+ ah->PDADCdelta = delta;
+ for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+ regval = ah->originalGain[i] - delta;
+ if (regval < 0)
+ regval = 0;
- if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
- chan->channelFlags |= CHANNEL_CW_INT;
- ichan->channelFlags &= ~CHANNEL_CW_INT;
+ REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
+ AR_PHY_TX_GAIN, regval);
}
}
-
- return true;
}
-static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah)
+static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
{
u32 regVal;
@@ -913,59 +840,171 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah)
}
-bool ath9k_hw_init_cal(struct ath_hal *ah,
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+ u8 rxchainmask, bool longcal,
+ bool *isCalDone)
+{
+ struct hal_cal_list *currCal = ah->cal_list_curr;
+
+ *isCalDone = true;
+
+ if (currCal &&
+ (currCal->calState == CAL_RUNNING ||
+ currCal->calState == CAL_WAITING)) {
+ ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
+ isCalDone);
+ if (*isCalDone) {
+ ah->cal_list_curr = currCal = currCal->calNext;
+
+ if (currCal->calState == CAL_WAITING) {
+ *isCalDone = false;
+ ath9k_hw_reset_calibration(ah, currCal);
+ }
+ }
+ }
+
+ if (longcal) {
+ if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+ ath9k_hw_9285_pa_cal(ah);
+
+ if (OLC_FOR_AR9280_20_LATER)
+ ath9k_olc_temp_compensation(ah);
+ ath9k_hw_getnf(ah, chan);
+ ath9k_hw_loadnf(ah, ah->curchan);
+ ath9k_hw_start_nfcal(ah);
+
+ if (chan->channelFlags & CHANNEL_CW_INT)
+ chan->channelFlags &= ~CHANNEL_CW_INT;
+ }
+
+ return true;
+}
+
+static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ if (chan->channelFlags & CHANNEL_HT20) {
+ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+ REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_FLTR_CAL);
+ REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
+ "calibration failed to complete in "
+ "1ms; noisy ??\n");
+ return false;
+ }
+ REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+ REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+ REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ }
+ REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+ 0, AH_WAIT_TIMEOUT)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
+ "failed to complete in 1ms; noisy ??\n");
+ return false;
+ }
+
+ REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+ return true;
+}
+
+bool ath9k_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+ if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
+ if (!ar9285_clc(ah, chan))
+ return false;
+ } else if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+
+ /* Kick off the cal */
+ REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+ REG_READ(ah, AR_PHY_AGC_CONTROL) |
+ AR_PHY_AGC_CONTROL_CAL);
+
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_CAL, 0,
+ AH_WAIT_TIMEOUT)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; "
+ "noisy environment?\n");
+ return false;
+ }
+
+ REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ }
+ /* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_CAL);
+ 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)) {
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+ 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"offset calibration failed to complete in 1ms; "
"noisy environment?\n");
return false;
}
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ }
+
+ /* Do PA Calibration */
if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
ath9k_hw_9285_pa_cal(ah);
+ /* Do NF Calibration */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_NF);
+ REG_READ(ah, AR_PHY_AGC_CONTROL) |
+ AR_PHY_AGC_CONTROL_NF);
- ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
+ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
- if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
- INIT_CAL(&ahp->ah_adcGainCalData);
- INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
+ 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, chan, ADC_DC_CAL)) {
- INIT_CAL(&ahp->ah_adcDcCalData);
- INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
+ 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, chan, IQ_MISMATCH_CAL)) {
- INIT_CAL(&ahp->ah_iqCalData);
- INSERT_CAL(ahp, &ahp->ah_iqCalData);
+ 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");
}
- ahp->ah_cal_list_curr = ahp->ah_cal_list;
+ ah->cal_list_curr = ah->cal_list;
- if (ahp->ah_cal_list_curr)
- ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr);
+ if (ah->cal_list_curr)
+ ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
}
- ichan->CalValid = 0;
+ chan->CalValid = 0;
return true;
}
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath9k/calib.h
new file mode 100644
index 00000000000..32589e0c501
--- /dev/null
+++ b/drivers/net/wireless/ath9k/calib.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef CALIB_H
+#define CALIB_H
+
+extern const struct hal_percal_data iq_cal_multi_sample;
+extern const struct hal_percal_data iq_cal_single_sample;
+extern const struct hal_percal_data adc_gain_cal_multi_sample;
+extern const struct hal_percal_data adc_gain_cal_single_sample;
+extern const struct hal_percal_data adc_dc_cal_multi_sample;
+extern const struct hal_percal_data adc_dc_cal_single_sample;
+extern const struct hal_percal_data adc_init_dc_cal;
+
+#define AR_PHY_CCA_MAX_GOOD_VALUE -85
+#define AR_PHY_CCA_MAX_HIGH_VALUE -62
+#define AR_PHY_CCA_MIN_BAD_VALUE -140
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
+
+#define NUM_NF_READINGS 6
+#define ATH9K_NF_CAL_HIST_MAX 5
+
+struct ar5416IniArray {
+ u32 *ia_array;
+ u32 ia_rows;
+ u32 ia_columns;
+};
+
+#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
+ (iniarray)->ia_array = (u32 *)(array); \
+ (iniarray)->ia_rows = (rows); \
+ (iniarray)->ia_columns = (columns); \
+ } while (0)
+
+#define INI_RA(iniarray, row, column) \
+ (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
+
+#define INIT_CAL(_perCal) do { \
+ (_perCal)->calState = CAL_WAITING; \
+ (_perCal)->calNext = NULL; \
+ } while (0)
+
+#define INSERT_CAL(_ahp, _perCal) \
+ do { \
+ if ((_ahp)->cal_list_last == NULL) { \
+ (_ahp)->cal_list = \
+ (_ahp)->cal_list_last = (_perCal); \
+ ((_ahp)->cal_list_last)->calNext = (_perCal); \
+ } else { \
+ ((_ahp)->cal_list_last)->calNext = (_perCal); \
+ (_ahp)->cal_list_last = (_perCal); \
+ (_perCal)->calNext = (_ahp)->cal_list; \
+ } \
+ } while (0)
+
+enum hal_cal_types {
+ ADC_DC_INIT_CAL = 0x1,
+ ADC_GAIN_CAL = 0x2,
+ ADC_DC_CAL = 0x4,
+ IQ_MISMATCH_CAL = 0x8
+};
+
+enum hal_cal_state {
+ CAL_INACTIVE,
+ CAL_WAITING,
+ CAL_RUNNING,
+ CAL_DONE
+};
+
+#define MIN_CAL_SAMPLES 1
+#define MAX_CAL_SAMPLES 64
+#define INIT_LOG_COUNT 5
+#define PER_MIN_LOG_COUNT 2
+#define PER_MAX_LOG_COUNT 10
+
+struct hal_percal_data {
+ enum hal_cal_types calType;
+ u32 calNumSamples;
+ u32 calCountMax;
+ void (*calCollect) (struct ath_hw *);
+ void (*calPostProc) (struct ath_hw *, u8);
+};
+
+struct hal_cal_list {
+ const struct hal_percal_data *calData;
+ enum hal_cal_state calState;
+ struct hal_cal_list *calNext;
+};
+
+struct ath9k_nfcal_hist {
+ int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
+ u8 currIndex;
+ int16_t privNF;
+ u8 invalidNFcount;
+};
+
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
+void ath9k_hw_start_nfcal(struct ath_hw *ah);
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
+ struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+ u8 rxchainmask, bool longcal,
+ bool *isCalDone);
+bool ath9k_hw_init_cal(struct ath_hw *ah,
+ struct ath9k_channel *chan);
+
+#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
deleted file mode 100644
index 4ca2aed236e..00000000000
--- a/drivers/net/wireless/ath9k/core.h
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * Copyright (c) 2008 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef CORE_H
-#define CORE_H
-
-#include <linux/etherdevice.h>
-#include <linux/pci.h>
-#include <net/mac80211.h>
-#include <linux/leds.h>
-#include <linux/rfkill.h>
-
-#include "ath9k.h"
-#include "rc.h"
-
-struct ath_node;
-
-/* Macro to expand scalars to 64-bit objects */
-
-#define ito64(x) (sizeof(x) == 8) ? \
- (((unsigned long long int)(x)) & (0xff)) : \
- (sizeof(x) == 16) ? \
- (((unsigned long long int)(x)) & 0xffff) : \
- ((sizeof(x) == 32) ? \
- (((unsigned long long int)(x)) & 0xffffffff) : \
- (unsigned long long int)(x))
-
-/* increment with wrap-around */
-#define INCR(_l, _sz) do { \
- (_l)++; \
- (_l) &= ((_sz) - 1); \
- } while (0)
-
-/* decrement with wrap-around */
-#define DECR(_l, _sz) do { \
- (_l)--; \
- (_l) &= ((_sz) - 1); \
- } while (0)
-
-#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
-
-#define ASSERT(exp) do { \
- if (unlikely(!(exp))) { \
- BUG(); \
- } \
- } while (0)
-
-#define TSF_TO_TU(_h,_l) \
- ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
-
-#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
-
-static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-enum ATH_DEBUG {
- ATH_DBG_RESET = 0x00000001,
- ATH_DBG_REG_IO = 0x00000002,
- ATH_DBG_QUEUE = 0x00000004,
- ATH_DBG_EEPROM = 0x00000008,
- ATH_DBG_CALIBRATE = 0x00000010,
- ATH_DBG_CHANNEL = 0x00000020,
- ATH_DBG_INTERRUPT = 0x00000040,
- ATH_DBG_REGULATORY = 0x00000080,
- ATH_DBG_ANI = 0x00000100,
- ATH_DBG_POWER_MGMT = 0x00000200,
- ATH_DBG_XMIT = 0x00000400,
- ATH_DBG_BEACON = 0x00001000,
- ATH_DBG_CONFIG = 0x00002000,
- ATH_DBG_KEYCACHE = 0x00004000,
- ATH_DBG_FATAL = 0x00008000,
- ATH_DBG_ANY = 0xffffffff
-};
-
-#define DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH9K_DEBUG
-
-/**
- * struct ath_interrupt_stats - Contains statistics about interrupts
- * @total: Total no. of interrupts generated so far
- * @rxok: RX with no errors
- * @rxeol: RX with no more RXDESC available
- * @rxorn: RX FIFO overrun
- * @txok: TX completed at the requested rate
- * @txurn: TX FIFO underrun
- * @mib: MIB regs reaching its threshold
- * @rxphyerr: RX with phy errors
- * @rx_keycache_miss: RX with key cache misses
- * @swba: Software Beacon Alert
- * @bmiss: Beacon Miss
- * @bnr: Beacon Not Ready
- * @cst: Carrier Sense TImeout
- * @gtt: Global TX Timeout
- * @tim: RX beacon TIM occurrence
- * @cabend: RX End of CAB traffic
- * @dtimsync: DTIM sync lossage
- * @dtim: RX Beacon with DTIM
- */
-struct ath_interrupt_stats {
- u32 total;
- u32 rxok;
- u32 rxeol;
- u32 rxorn;
- u32 txok;
- u32 txeol;
- u32 txurn;
- u32 mib;
- u32 rxphyerr;
- u32 rx_keycache_miss;
- u32 swba;
- u32 bmiss;
- u32 bnr;
- u32 cst;
- u32 gtt;
- u32 tim;
- u32 cabend;
- u32 dtimsync;
- u32 dtim;
-};
-
-struct ath_stats {
- struct ath_interrupt_stats istats;
-};
-
-struct ath9k_debug {
- int debug_mask;
- struct dentry *debugfs_root;
- struct dentry *debugfs_phy;
- struct dentry *debugfs_dma;
- struct dentry *debugfs_interrupt;
- struct ath_stats stats;
-};
-
-void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
-int ath9k_init_debug(struct ath_softc *sc);
-void ath9k_exit_debug(struct ath_softc *sc);
-void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-
-#else
-
-static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
- const char *fmt, ...)
-{
-}
-
-static inline int ath9k_init_debug(struct ath_softc *sc)
-{
- return 0;
-}
-
-static inline void ath9k_exit_debug(struct ath_softc *sc)
-{
-}
-
-static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
- enum ath9k_int status)
-{
-}
-
-#endif /* CONFIG_ATH9K_DEBUG */
-
-struct ath_config {
- u32 ath_aggr_prot;
- u16 txpowlimit;
- u16 txpowlimit_override;
- u8 cabqReadytime;
- u8 swBeaconProcess;
-};
-
-/*************************/
-/* Descriptor Management */
-/*************************/
-
-#define ATH_TXBUF_RESET(_bf) do { \
- (_bf)->bf_status = 0; \
- (_bf)->bf_lastbf = NULL; \
- (_bf)->bf_lastfrm = NULL; \
- (_bf)->bf_next = NULL; \
- memset(&((_bf)->bf_state), 0, \
- sizeof(struct ath_buf_state)); \
- } while (0)
-
-enum buffer_type {
- BUF_DATA = BIT(0),
- BUF_AGGR = BIT(1),
- BUF_AMPDU = BIT(2),
- BUF_HT = BIT(3),
- BUF_RETRY = BIT(4),
- BUF_XRETRY = BIT(5),
- BUF_SHORT_PREAMBLE = BIT(6),
- BUF_BAR = BIT(7),
- BUF_PSPOLL = BIT(8),
- BUF_AGGR_BURST = BIT(9),
- BUF_CALC_AIRTIME = BIT(10),
-};
-
-struct ath_buf_state {
- int bfs_nframes; /* # frames in aggregate */
- u16 bfs_al; /* length of aggregate */
- u16 bfs_frmlen; /* length of frame */
- int bfs_seqno; /* sequence number */
- int bfs_tidno; /* tid of this frame */
- int bfs_retries; /* current retries */
- u32 bf_type; /* BUF_* (enum buffer_type) */
- u32 bfs_keyix;
- enum ath9k_key_type bfs_keytype;
-};
-
-#define bf_nframes bf_state.bfs_nframes
-#define bf_al bf_state.bfs_al
-#define bf_frmlen bf_state.bfs_frmlen
-#define bf_retries bf_state.bfs_retries
-#define bf_seqno bf_state.bfs_seqno
-#define bf_tidno bf_state.bfs_tidno
-#define bf_rcs bf_state.bfs_rcs
-#define bf_keyix bf_state.bfs_keyix
-#define bf_keytype bf_state.bfs_keytype
-#define bf_isdata(bf) (bf->bf_state.bf_type & BUF_DATA)
-#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
-#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
-#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
-#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
-#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
-#define bf_isshpreamble(bf) (bf->bf_state.bf_type & BUF_SHORT_PREAMBLE)
-#define bf_isbar(bf) (bf->bf_state.bf_type & BUF_BAR)
-#define bf_ispspoll(bf) (bf->bf_state.bf_type & BUF_PSPOLL)
-#define bf_isaggrburst(bf) (bf->bf_state.bf_type & BUF_AGGR_BURST)
-
-/*
- * Abstraction of a contiguous buffer to transmit/receive. There is only
- * a single hw descriptor encapsulated here.
- */
-struct ath_buf {
- struct list_head list;
- struct list_head *last;
- struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
- an aggregate) */
- struct ath_buf *bf_lastfrm; /* last buf of this frame */
- struct ath_buf *bf_next; /* next subframe in the aggregate */
- void *bf_mpdu; /* enclosing frame structure */
- struct ath_desc *bf_desc; /* virtual addr of desc */
- dma_addr_t bf_daddr; /* physical addr of desc */
- dma_addr_t bf_buf_addr; /* physical addr of data buffer */
- u32 bf_status;
- u16 bf_flags; /* tx descriptor flags */
- struct ath_buf_state bf_state; /* buffer state */
- dma_addr_t bf_dmacontext;
-};
-
-#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
-
-/* hw processing complete, desc processed by hal */
-#define ATH_BUFSTATUS_DONE 0x00000001
-/* hw processing complete, desc hold for hw */
-#define ATH_BUFSTATUS_STALE 0x00000002
-/* Rx-only: OS is done with this packet and it's ok to queued it to hw */
-#define ATH_BUFSTATUS_FREE 0x00000004
-
-/* DMA state for tx/rx descriptors */
-
-struct ath_descdma {
- const char *dd_name;
- struct ath_desc *dd_desc; /* descriptors */
- dma_addr_t dd_desc_paddr; /* physical addr of dd_desc */
- u32 dd_desc_len; /* size of dd_desc */
- struct ath_buf *dd_bufptr; /* associated buffers */
- dma_addr_t dd_dmacontext;
-};
-
-int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
- struct list_head *head, const char *name,
- int nbuf, int ndesc);
-void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
- struct list_head *head);
-
-/***********/
-/* RX / TX */
-/***********/
-
-#define ATH_MAX_ANTENNA 3
-#define ATH_RXBUF 512
-#define WME_NUM_TID 16
-#define ATH_TXBUF 512
-#define ATH_TXMAXTRY 13
-#define ATH_11N_TXMAXTRY 10
-#define ATH_MGT_TXMAXTRY 4
-#define WME_BA_BMP_SIZE 64
-#define WME_MAX_BA WME_BA_BMP_SIZE
-#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
-
-#define TID_TO_WME_AC(_tid) \
- ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
- (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
- (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
- WME_AC_VO)
-
-#define WME_AC_BE 0
-#define WME_AC_BK 1
-#define WME_AC_VI 2
-#define WME_AC_VO 3
-#define WME_NUM_AC 4
-
-#define ADDBA_EXCHANGE_ATTEMPTS 10
-#define ATH_AGGR_DELIM_SZ 4
-#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
-/* number of delimiters for encryption padding */
-#define ATH_AGGR_ENCRYPTDELIM 10
-/* minimum h/w qdepth to be sustained to maximize aggregation */
-#define ATH_AGGR_MIN_QDEPTH 2
-#define ATH_AMPDU_SUBFRAME_DEFAULT 32
-#define IEEE80211_SEQ_SEQ_SHIFT 4
-#define IEEE80211_SEQ_MAX 4096
-#define IEEE80211_MIN_AMPDU_BUF 0x8
-#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
-
-/* return whether a bit at index _n in bitmap _bm is set
- * _sz is the size of the bitmap */
-#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
- ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
-
-/* return block-ack bitmap index given sequence and starting sequence */
-#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
-
-/* returns delimiter padding required given the packet length */
-#define ATH_AGGR_GET_NDELIM(_len) \
- (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
- (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
-
-#define BAW_WITHIN(_start, _bawsz, _seqno) \
- ((((_seqno) - (_start)) & 4095) < (_bawsz))
-
-#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
-#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
-#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
-#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
-
-enum ATH_AGGR_STATUS {
- ATH_AGGR_DONE,
- ATH_AGGR_BAW_CLOSED,
- ATH_AGGR_LIMITED,
- ATH_AGGR_SHORTPKT,
- ATH_AGGR_8K_LIMITED,
-};
-
-struct ath_txq {
- u32 axq_qnum; /* hardware q number */
- u32 *axq_link; /* link ptr in last TX desc */
- struct list_head axq_q; /* transmit queue */
- spinlock_t axq_lock;
- unsigned long axq_lockflags; /* intr state when must cli */
- u32 axq_depth; /* queue depth */
- u8 axq_aggr_depth; /* aggregates queued */
- u32 axq_totalqueued; /* total ever queued */
- bool stopped; /* Is mac80211 queue stopped ? */
- struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/
-
- /* first desc of the last descriptor that contains CTS */
- struct ath_desc *axq_lastdsWithCTS;
-
- /* final desc of the gating desc that determines whether
- lastdsWithCTS has been DMA'ed or not */
- struct ath_desc *axq_gatingds;
-
- struct list_head axq_acq;
-};
-
-#define AGGR_CLEANUP BIT(1)
-#define AGGR_ADDBA_COMPLETE BIT(2)
-#define AGGR_ADDBA_PROGRESS BIT(3)
-
-/* per TID aggregate tx state for a destination */
-struct ath_atx_tid {
- struct list_head list; /* round-robin tid entry */
- struct list_head buf_q; /* pending buffers */
- struct ath_node *an;
- struct ath_atx_ac *ac;
- struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; /* active tx frames */
- u16 seq_start;
- u16 seq_next;
- u16 baw_size;
- int tidno;
- int baw_head; /* first un-acked tx buffer */
- int baw_tail; /* next unused tx buffer slot */
- int sched;
- int paused;
- u8 state;
- int addba_exchangeattempts;
-};
-
-/* per access-category aggregate tx state for a destination */
-struct ath_atx_ac {
- int sched; /* dest-ac is scheduled */
- int qnum; /* H/W queue number associated
- with this AC */
- struct list_head list; /* round-robin txq entry */
- struct list_head tid_q; /* queue of TIDs with buffers */
-};
-
-/* per-frame tx control block */
-struct ath_tx_control {
- struct ath_txq *txq;
- int if_id;
-};
-
-/* per frame tx status block */
-struct ath_xmit_status {
- int retries; /* number of retries to successufully
- transmit this frame */
- int flags; /* status of transmit */
-#define ATH_TX_ERROR 0x01
-#define ATH_TX_XRETRY 0x02
-#define ATH_TX_BAR 0x04
-};
-
-/* All RSSI values are noise floor adjusted */
-struct ath_tx_stat {
- int rssi;
- int rssictl[ATH_MAX_ANTENNA];
- int rssiextn[ATH_MAX_ANTENNA];
- int rateieee;
- int rateKbps;
- int ratecode;
- int flags;
- u32 airtime; /* time on air per final tx rate */
-};
-
-struct aggr_rifs_param {
- int param_max_frames;
- int param_max_len;
- int param_rl;
- int param_al;
- struct ath_rc_series *param_rcs;
-};
-
-struct ath_node {
- struct ath_softc *an_sc;
- struct ath_atx_tid tid[WME_NUM_TID];
- struct ath_atx_ac ac[WME_NUM_AC];
- u16 maxampdu;
- u8 mpdudensity;
-};
-
-struct ath_tx {
- u16 seq_no;
- u32 txqsetup;
- int hwq_map[ATH9K_WME_AC_VO+1];
- spinlock_t txbuflock;
- struct list_head txbuf;
- struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
- struct ath_descdma txdma;
-};
-
-struct ath_rx {
- u8 defant;
- u8 rxotherant;
- u32 *rxlink;
- int bufsize;
- unsigned int rxfilter;
- spinlock_t rxflushlock;
- spinlock_t rxbuflock;
- struct list_head rxbuf;
- struct ath_descdma rxdma;
-};
-
-int ath_startrecv(struct ath_softc *sc);
-bool ath_stoprecv(struct ath_softc *sc);
-void ath_flushrecv(struct ath_softc *sc);
-u32 ath_calcrxfilter(struct ath_softc *sc);
-int ath_rx_init(struct ath_softc *sc, int nbufs);
-void ath_rx_cleanup(struct ath_softc *sc);
-int ath_rx_tasklet(struct ath_softc *sc, int flush);
-struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_draintxq(struct ath_softc *sc, bool retry_tx);
-void ath_tx_draintxq(struct ath_softc *sc,
- struct ath_txq *txq, bool retry_tx);
-void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_free(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);
-int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
-struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
-int ath_txq_update(struct ath_softc *sc, int qnum,
- struct ath9k_tx_queue_info *q);
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_tx_control *txctl);
-void ath_tx_tasklet(struct ath_softc *sc);
-u32 ath_txq_depth(struct ath_softc *sc, int qnum);
-u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
-void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
-void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
- u16 tid, u16 *ssn);
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-
-/********/
-/* VAPs */
-/********/
-
-/*
- * Define the scheme that we select MAC address for multiple
- * BSS on the same radio. The very first VAP will just use the MAC
- * address from the EEPROM. For the next 3 VAPs, we set the
- * U/L bit (bit 1) in MAC address, and use the next two bits as the
- * index of the VAP.
- */
-
-#define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
- ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
-
-struct ath_vap {
- int av_bslot;
- enum nl80211_iftype av_opmode;
- struct ath_buf *av_bcbuf;
- struct ath_tx_control av_btxctl;
-};
-
-/*******************/
-/* Beacon Handling */
-/*******************/
-
-/*
- * Regardless of the number of beacons we stagger, (i.e. regardless of the
- * number of BSSIDs) if a given beacon does not go out even after waiting this
- * number of beacon intervals, the game's up.
- */
-#define BSTUCK_THRESH (9 * ATH_BCBUF)
-#define ATH_BCBUF 1
-#define ATH_DEFAULT_BINTVAL 100 /* TU */
-#define ATH_DEFAULT_BMISS_LIMIT 10
-#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
-
-struct ath_beacon_config {
- u16 beacon_interval;
- u16 listen_interval;
- u16 dtim_period;
- u16 bmiss_timeout;
- u8 dtim_count;
- u8 tim_offset;
- union {
- u64 last_tsf;
- u8 last_tstamp[8];
- } u; /* last received beacon/probe response timestamp of this BSS. */
-};
-
-struct ath_beacon {
- enum {
- OK, /* no change needed */
- UPDATE, /* update pending */
- COMMIT /* beacon sent, commit change */
- } updateslot; /* slot time update fsm */
-
- u32 beaconq;
- u32 bmisscnt;
- u32 ast_be_xmit;
- u64 bc_tstamp;
- int bslot[ATH_BCBUF];
- int slottime;
- int slotupdate;
- struct ath9k_tx_queue_info beacon_qi;
- struct ath_descdma bdma;
- struct ath_txq *cabq;
- struct list_head bbuf;
-};
-
-void ath9k_beacon_tasklet(unsigned long data);
-void ath_beacon_config(struct ath_softc *sc, int if_id);
-int ath_beaconq_setup(struct ath_hal *ah);
-int ath_beacon_alloc(struct ath_softc *sc, int if_id);
-void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp);
-void ath_beacon_sync(struct ath_softc *sc, int if_id);
-
-/*******/
-/* ANI */
-/*******/
-
-/* ANI values for STA only.
- FIXME: Add appropriate values for AP later */
-
-#define ATH_ANI_POLLINTERVAL 100 /* 100 milliseconds between ANI poll */
-#define ATH_SHORT_CALINTERVAL 1000 /* 1 second between calibrations */
-#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds between calibrations */
-#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */
-
-struct ath_ani {
- bool sc_caldone;
- int16_t sc_noise_floor;
- unsigned int sc_longcal_timer;
- unsigned int sc_shortcal_timer;
- unsigned int sc_resetcal_timer;
- unsigned int sc_checkani_timer;
- struct timer_list timer;
-};
-
-/********************/
-/* LED Control */
-/********************/
-
-#define ATH_LED_PIN 1
-
-enum ath_led_type {
- ATH_LED_RADIO,
- ATH_LED_ASSOC,
- ATH_LED_TX,
- ATH_LED_RX
-};
-
-struct ath_led {
- struct ath_softc *sc;
- struct led_classdev led_cdev;
- enum ath_led_type led_type;
- char name[32];
- bool registered;
-};
-
-/* Rfkill */
-#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
-
-struct ath_rfkill {
- struct rfkill *rfkill;
- struct delayed_work rfkill_poll;
- char rfkill_name[32];
-};
-
-/********************/
-/* Main driver core */
-/********************/
-
-/*
- * Default cache line size, in bytes.
- * Used when PCI device not fully initialized by bootrom/BIOS
-*/
-#define DEFAULT_CACHELINE 32
-#define ATH_DEFAULT_NOISE_FLOOR -95
-#define ATH_REGCLASSIDS_MAX 10
-#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
-#define ATH_MAX_SW_RETRIES 10
-#define ATH_CHAN_MAX 255
-#define IEEE80211_WEP_NKID 4 /* number of key ids */
-#define IEEE80211_RATE_VAL 0x7f
-/*
- * The key cache is used for h/w cipher state and also for
- * tracking station state such as the current tx antenna.
- * We also setup a mapping table between key cache slot indices
- * and station state to short-circuit node lookups on rx.
- * Different parts have different size key caches. We handle
- * up to ATH_KEYMAX entries (could dynamically allocate state).
- */
-#define ATH_KEYMAX 128 /* max key cache size we handle */
-
-#define ATH_IF_ID_ANY 0xff
-#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
-#define ATH_RSSI_DUMMY_MARKER 0x127
-#define ATH_RATE_DUMMY_MARKER 0
-
-enum PROT_MODE {
- PROT_M_NONE = 0,
- PROT_M_RTSCTS,
- PROT_M_CTSONLY
-};
-
-#define SC_OP_INVALID BIT(0)
-#define SC_OP_BEACONS BIT(1)
-#define SC_OP_RXAGGR BIT(2)
-#define SC_OP_TXAGGR BIT(3)
-#define SC_OP_CHAINMASK_UPDATE BIT(4)
-#define SC_OP_FULL_RESET BIT(5)
-#define SC_OP_NO_RESET BIT(6)
-#define SC_OP_PREAMBLE_SHORT BIT(7)
-#define SC_OP_PROTECT_ENABLE BIT(8)
-#define SC_OP_RXFLUSH BIT(9)
-#define SC_OP_LED_ASSOCIATED BIT(10)
-#define SC_OP_RFKILL_REGISTERED BIT(11)
-#define SC_OP_RFKILL_SW_BLOCKED BIT(12)
-#define SC_OP_RFKILL_HW_BLOCKED BIT(13)
-
-struct ath_softc {
- struct ieee80211_hw *hw;
- struct pci_dev *pdev;
- struct tasklet_struct intr_tq;
- struct tasklet_struct bcon_tasklet;
- struct ath_hal *sc_ah;
- void __iomem *mem;
- spinlock_t sc_resetlock;
- struct mutex mutex;
-
- u8 sc_curbssid[ETH_ALEN];
- u8 sc_myaddr[ETH_ALEN];
- u8 sc_bssidmask[ETH_ALEN];
- u32 sc_intrstatus;
- u32 sc_flags; /* SC_OP_* */
- u16 sc_curtxpow;
- u16 sc_curaid;
- u16 sc_cachelsz;
- u8 sc_nbcnvaps;
- u16 sc_nvaps;
- u8 sc_tx_chainmask;
- u8 sc_rx_chainmask;
- u32 sc_keymax;
- DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
- u8 sc_splitmic;
- u8 sc_protrix;
- enum ath9k_int sc_imask;
- enum PROT_MODE sc_protmode;
- enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
- enum ath9k_ht_macmode tx_chan_width;
-
- struct ath_config sc_config;
- struct ath_rx rx;
- struct ath_tx tx;
- struct ath_beacon beacon;
- struct ieee80211_vif *sc_vaps[ATH_BCBUF];
- struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
- struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
- struct ath_rate_table *cur_rate_table;
- struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
- struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
- struct ath_led radio_led;
- struct ath_led assoc_led;
- struct ath_led tx_led;
- struct ath_led rx_led;
- struct ath_rfkill rf_kill;
- struct ath_ani sc_ani;
- struct ath9k_node_stats sc_halstats;
-#ifdef CONFIG_ATH9K_DEBUG
- struct ath9k_debug sc_debug;
-#endif
-};
-
-int ath_reset(struct ath_softc *sc, bool retry_tx);
-int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
-int ath_cabq_update(struct ath_softc *);
-
-#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c
index a80ed576830..82573cadb1a 100644
--- a/drivers/net/wireless/ath9k/debug.c
+++ b/drivers/net/wireless/ath9k/debug.c
@@ -14,19 +14,21 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "reg.h"
-#include "hw.h"
+#include <asm/unaligned.h>
+
+#include "ath9k.h"
static unsigned int ath9k_debug = DBG_DEFAULT;
module_param_named(debug, ath9k_debug, uint, 0);
+static struct dentry *ath9k_debugfs_root;
+
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
{
if (!sc)
return;
- if (sc->sc_debug.debug_mask & dbg_mask) {
+ if (sc->debug.debug_mask & dbg_mask) {
va_list args;
va_start(args, fmt);
@@ -46,7 +48,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
char buf[1024];
unsigned int len = 0;
u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
@@ -132,41 +134,41 @@ static const struct file_operations fops_dma = {
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
{
if (status)
- sc->sc_debug.stats.istats.total++;
+ sc->debug.stats.istats.total++;
if (status & ATH9K_INT_RX)
- sc->sc_debug.stats.istats.rxok++;
+ sc->debug.stats.istats.rxok++;
if (status & ATH9K_INT_RXEOL)
- sc->sc_debug.stats.istats.rxeol++;
+ sc->debug.stats.istats.rxeol++;
if (status & ATH9K_INT_RXORN)
- sc->sc_debug.stats.istats.rxorn++;
+ sc->debug.stats.istats.rxorn++;
if (status & ATH9K_INT_TX)
- sc->sc_debug.stats.istats.txok++;
+ sc->debug.stats.istats.txok++;
if (status & ATH9K_INT_TXURN)
- sc->sc_debug.stats.istats.txurn++;
+ sc->debug.stats.istats.txurn++;
if (status & ATH9K_INT_MIB)
- sc->sc_debug.stats.istats.mib++;
+ sc->debug.stats.istats.mib++;
if (status & ATH9K_INT_RXPHY)
- sc->sc_debug.stats.istats.rxphyerr++;
+ sc->debug.stats.istats.rxphyerr++;
if (status & ATH9K_INT_RXKCM)
- sc->sc_debug.stats.istats.rx_keycache_miss++;
+ sc->debug.stats.istats.rx_keycache_miss++;
if (status & ATH9K_INT_SWBA)
- sc->sc_debug.stats.istats.swba++;
+ sc->debug.stats.istats.swba++;
if (status & ATH9K_INT_BMISS)
- sc->sc_debug.stats.istats.bmiss++;
+ sc->debug.stats.istats.bmiss++;
if (status & ATH9K_INT_BNR)
- sc->sc_debug.stats.istats.bnr++;
+ sc->debug.stats.istats.bnr++;
if (status & ATH9K_INT_CST)
- sc->sc_debug.stats.istats.cst++;
+ sc->debug.stats.istats.cst++;
if (status & ATH9K_INT_GTT)
- sc->sc_debug.stats.istats.gtt++;
+ sc->debug.stats.istats.gtt++;
if (status & ATH9K_INT_TIM)
- sc->sc_debug.stats.istats.tim++;
+ sc->debug.stats.istats.tim++;
if (status & ATH9K_INT_CABEND)
- sc->sc_debug.stats.istats.cabend++;
+ sc->debug.stats.istats.cabend++;
if (status & ATH9K_INT_DTIMSYNC)
- sc->sc_debug.stats.istats.dtimsync++;
+ sc->debug.stats.istats.dtimsync++;
if (status & ATH9K_INT_DTIM)
- sc->sc_debug.stats.istats.dtim++;
+ sc->debug.stats.istats.dtim++;
}
static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
@@ -177,41 +179,41 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
unsigned int len = 0;
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RX", sc->sc_debug.stats.istats.rxok);
+ "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RXEOL", sc->sc_debug.stats.istats.rxeol);
+ "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RXORN", sc->sc_debug.stats.istats.rxorn);
+ "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "TX", sc->sc_debug.stats.istats.txok);
+ "%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "TXURN", sc->sc_debug.stats.istats.txurn);
+ "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "MIB", sc->sc_debug.stats.istats.mib);
+ "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RXPHY", sc->sc_debug.stats.istats.rxphyerr);
+ "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RXKCM", sc->sc_debug.stats.istats.rx_keycache_miss);
+ "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "SWBA", sc->sc_debug.stats.istats.swba);
+ "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "BMISS", sc->sc_debug.stats.istats.bmiss);
+ "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "BNR", sc->sc_debug.stats.istats.bnr);
+ "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "CST", sc->sc_debug.stats.istats.cst);
+ "%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "GTT", sc->sc_debug.stats.istats.gtt);
+ "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "TIM", sc->sc_debug.stats.istats.tim);
+ "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "CABEND", sc->sc_debug.stats.istats.cabend);
+ "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "DTIMSYNC", sc->sc_debug.stats.istats.dtimsync);
+ "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "DTIM", sc->sc_debug.stats.istats.dtim);
+ "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "TOTAL", sc->sc_debug.stats.istats.total);
+ "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -222,29 +224,308 @@ static const struct file_operations fops_interrupt = {
.owner = THIS_MODULE
};
-int ath9k_init_debug(struct ath_softc *sc)
+static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
{
- sc->sc_debug.debug_mask = ath9k_debug;
+ 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;
- sc->sc_debug.debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
- if (!sc->sc_debug.debugfs_root)
- goto err;
+ tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+ final_ts_idx = tx_info_priv->tx.ts_rateindex;
+ idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
+
+ sc->debug.stats.n_rcstats[idx].success++;
+}
+
+static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+ struct ath_tx_info_priv *tx_info_priv = NULL;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_rate *rates = tx_info->status.rates;
+ int final_ts_idx, idx;
+
+ tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+ final_ts_idx = tx_info_priv->tx.ts_rateindex;
+ idx = rates[final_ts_idx].idx;
+
+ sc->debug.stats.legacy_rcstats[idx].success++;
+}
+
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+ if (conf_is_ht(&sc->hw->conf))
+ ath_debug_stat_11n_rc(sc, skb);
+ else
+ ath_debug_stat_legacy_rc(sc, skb);
+}
+
+/* FIXME: legacy rates, later on .. */
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+ int xretries, int retries, u8 per)
+{
+ if (conf_is_ht(&sc->hw->conf)) {
+ int idx = sc->cur_rate_table->info[rix].dot11rate;
+
+ sc->debug.stats.n_rcstats[idx].xretries += xretries;
+ sc->debug.stats.n_rcstats[idx].retries += retries;
+ sc->debug.stats.n_rcstats[idx].per = per;
+ }
+}
+
+static ssize_t ath_read_file_stat_11n_rc(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[1024];
+ unsigned int len = 0;
+ int i = 0;
+
+ len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success",
+ "Retries", "XRetries", "PER");
+
+ for (i = 0; i <= 15; i++) {
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
+ sc->debug.stats.n_rcstats[i].success,
+ sc->debug.stats.n_rcstats[i].retries,
+ sc->debug.stats.n_rcstats[i].xretries,
+ sc->debug.stats.n_rcstats[i].per);
+ }
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[512];
+ unsigned int len = 0;
+ int i = 0;
+
+ len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success");
- sc->sc_debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
- sc->sc_debug.debugfs_root);
- if (!sc->sc_debug.debugfs_phy)
+ for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
+ len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
+ sc->cur_rate_table->info[i].ratekbps / 1000,
+ sc->debug.stats.legacy_rcstats[i].success);
+ }
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+
+ if (sc->cur_rate_table == NULL)
+ return 0;
+
+ if (conf_is_ht(&sc->hw->conf))
+ return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
+ else
+ return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
+}
+
+static const struct file_operations fops_rcstat = {
+ .read = read_file_rcstat,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE
+};
+
+static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
+{
+ switch (state) {
+ case ATH_WIPHY_INACTIVE:
+ return "INACTIVE";
+ case ATH_WIPHY_ACTIVE:
+ return "ACTIVE";
+ case ATH_WIPHY_PAUSING:
+ return "PAUSING";
+ case ATH_WIPHY_PAUSED:
+ return "PAUSED";
+ case ATH_WIPHY_SCAN:
+ return "SCAN";
+ }
+ return "?";
+}
+
+static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[512];
+ unsigned int len = 0;
+ int i;
+ u8 addr[ETH_ALEN];
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "primary: %s (%s chan=%d ht=%d)\n",
+ wiphy_name(sc->pri_wiphy->hw->wiphy),
+ ath_wiphy_state_str(sc->pri_wiphy->state),
+ sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy == NULL)
+ continue;
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "secondary: %s (%s chan=%d ht=%d)\n",
+ wiphy_name(aphy->hw->wiphy),
+ ath_wiphy_state_str(aphy->state),
+ aphy->chan_idx, aphy->chan_is_ht);
+ }
+
+ put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr);
+ put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "addr: %pM\n", addr);
+ put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr);
+ put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "addrmask: %pM\n", addr);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name)
+{
+ int i;
+ if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0)
+ return sc->pri_wiphy;
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0)
+ return aphy;
+ }
+ return NULL;
+}
+
+static int del_wiphy(struct ath_softc *sc, const char *name)
+{
+ struct ath_wiphy *aphy = get_wiphy(sc, name);
+ if (!aphy)
+ return -ENOENT;
+ return ath9k_wiphy_del(aphy);
+}
+
+static int pause_wiphy(struct ath_softc *sc, const char *name)
+{
+ struct ath_wiphy *aphy = get_wiphy(sc, name);
+ if (!aphy)
+ return -ENOENT;
+ return ath9k_wiphy_pause(aphy);
+}
+
+static int unpause_wiphy(struct ath_softc *sc, const char *name)
+{
+ struct ath_wiphy *aphy = get_wiphy(sc, name);
+ if (!aphy)
+ return -ENOENT;
+ return ath9k_wiphy_unpause(aphy);
+}
+
+static int select_wiphy(struct ath_softc *sc, const char *name)
+{
+ struct ath_wiphy *aphy = get_wiphy(sc, name);
+ if (!aphy)
+ return -ENOENT;
+ return ath9k_wiphy_select(aphy);
+}
+
+static int schedule_wiphy(struct ath_softc *sc, const char *msec)
+{
+ ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0));
+ return 0;
+}
+
+static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[50];
+ size_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+ buf[len] = '\0';
+ if (len > 0 && buf[len - 1] == '\n')
+ buf[len - 1] = '\0';
+
+ if (strncmp(buf, "add", 3) == 0) {
+ int res = ath9k_wiphy_add(sc);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "del=", 4) == 0) {
+ int res = del_wiphy(sc, buf + 4);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "pause=", 6) == 0) {
+ int res = pause_wiphy(sc, buf + 6);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "unpause=", 8) == 0) {
+ int res = unpause_wiphy(sc, buf + 8);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "select=", 7) == 0) {
+ int res = select_wiphy(sc, buf + 7);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "schedule=", 9) == 0) {
+ int res = schedule_wiphy(sc, buf + 9);
+ if (res < 0)
+ return res;
+ } else
+ return -EOPNOTSUPP;
+
+ return count;
+}
+
+static const struct file_operations fops_wiphy = {
+ .read = read_file_wiphy,
+ .write = write_file_wiphy,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE
+};
+
+
+int ath9k_init_debug(struct ath_softc *sc)
+{
+ sc->debug.debug_mask = ath9k_debug;
+
+ sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
+ ath9k_debugfs_root);
+ if (!sc->debug.debugfs_phy)
goto err;
- sc->sc_debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
- sc->sc_debug.debugfs_phy, sc, &fops_dma);
- if (!sc->sc_debug.debugfs_dma)
+ sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
+ sc->debug.debugfs_phy, sc, &fops_dma);
+ if (!sc->debug.debugfs_dma)
goto err;
- sc->sc_debug.debugfs_interrupt = debugfs_create_file("interrupt",
+ sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
S_IRUGO,
- sc->sc_debug.debugfs_phy,
+ sc->debug.debugfs_phy,
sc, &fops_interrupt);
- if (!sc->sc_debug.debugfs_interrupt)
+ if (!sc->debug.debugfs_interrupt)
+ goto err;
+
+ sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
+ S_IRUGO,
+ sc->debug.debugfs_phy,
+ sc, &fops_rcstat);
+ if (!sc->debug.debugfs_rcstat)
+ goto err;
+
+ sc->debug.debugfs_wiphy = debugfs_create_file(
+ "wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc,
+ &fops_wiphy);
+ if (!sc->debug.debugfs_wiphy)
goto err;
return 0;
@@ -255,8 +536,24 @@ err:
void ath9k_exit_debug(struct ath_softc *sc)
{
- debugfs_remove(sc->sc_debug.debugfs_interrupt);
- debugfs_remove(sc->sc_debug.debugfs_dma);
- debugfs_remove(sc->sc_debug.debugfs_phy);
- debugfs_remove(sc->sc_debug.debugfs_root);
+ debugfs_remove(sc->debug.debugfs_wiphy);
+ debugfs_remove(sc->debug.debugfs_rcstat);
+ debugfs_remove(sc->debug.debugfs_interrupt);
+ debugfs_remove(sc->debug.debugfs_dma);
+ debugfs_remove(sc->debug.debugfs_phy);
+}
+
+int ath9k_debug_create_root(void)
+{
+ ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+ if (!ath9k_debugfs_root)
+ return -ENOENT;
+
+ return 0;
+}
+
+void ath9k_debug_remove_root(void)
+{
+ debugfs_remove(ath9k_debugfs_root);
+ ath9k_debugfs_root = NULL;
}
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath9k/debug.h
new file mode 100644
index 00000000000..065268b8568
--- /dev/null
+++ b/drivers/net/wireless/ath9k/debug.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+enum ATH_DEBUG {
+ ATH_DBG_RESET = 0x00000001,
+ ATH_DBG_REG_IO = 0x00000002,
+ ATH_DBG_QUEUE = 0x00000004,
+ ATH_DBG_EEPROM = 0x00000008,
+ ATH_DBG_CALIBRATE = 0x00000010,
+ ATH_DBG_CHANNEL = 0x00000020,
+ ATH_DBG_INTERRUPT = 0x00000040,
+ ATH_DBG_REGULATORY = 0x00000080,
+ ATH_DBG_ANI = 0x00000100,
+ ATH_DBG_POWER_MGMT = 0x00000200,
+ ATH_DBG_XMIT = 0x00000400,
+ ATH_DBG_BEACON = 0x00001000,
+ ATH_DBG_CONFIG = 0x00002000,
+ ATH_DBG_KEYCACHE = 0x00004000,
+ ATH_DBG_FATAL = 0x00008000,
+ ATH_DBG_ANY = 0xffffffff
+};
+
+#define DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH9K_DEBUG
+
+/**
+ * struct ath_interrupt_stats - Contains statistics about interrupts
+ * @total: Total no. of interrupts generated so far
+ * @rxok: RX with no errors
+ * @rxeol: RX with no more RXDESC available
+ * @rxorn: RX FIFO overrun
+ * @txok: TX completed at the requested rate
+ * @txurn: TX FIFO underrun
+ * @mib: MIB regs reaching its threshold
+ * @rxphyerr: RX with phy errors
+ * @rx_keycache_miss: RX with key cache misses
+ * @swba: Software Beacon Alert
+ * @bmiss: Beacon Miss
+ * @bnr: Beacon Not Ready
+ * @cst: Carrier Sense TImeout
+ * @gtt: Global TX Timeout
+ * @tim: RX beacon TIM occurrence
+ * @cabend: RX End of CAB traffic
+ * @dtimsync: DTIM sync lossage
+ * @dtim: RX Beacon with DTIM
+ */
+struct ath_interrupt_stats {
+ u32 total;
+ u32 rxok;
+ u32 rxeol;
+ u32 rxorn;
+ u32 txok;
+ u32 txeol;
+ u32 txurn;
+ u32 mib;
+ u32 rxphyerr;
+ u32 rx_keycache_miss;
+ u32 swba;
+ u32 bmiss;
+ u32 bnr;
+ u32 cst;
+ u32 gtt;
+ u32 tim;
+ u32 cabend;
+ u32 dtimsync;
+ u32 dtim;
+};
+
+struct ath_legacy_rc_stats {
+ u32 success;
+};
+
+struct ath_11n_rc_stats {
+ u32 success;
+ u32 retries;
+ u32 xretries;
+ u8 per;
+};
+
+struct ath_stats {
+ struct ath_interrupt_stats istats;
+ struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */
+ struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */
+};
+
+struct ath9k_debug {
+ int debug_mask;
+ struct dentry *debugfs_phy;
+ struct dentry *debugfs_dma;
+ struct dentry *debugfs_interrupt;
+ struct dentry *debugfs_rcstat;
+ struct dentry *debugfs_wiphy;
+ struct ath_stats stats;
+};
+
+void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
+int ath9k_init_debug(struct ath_softc *sc);
+void ath9k_exit_debug(struct ath_softc *sc);
+int ath9k_debug_create_root(void);
+void ath9k_debug_remove_root(void);
+void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+ int xretries, int retries, u8 per);
+
+#else
+
+static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
+ const char *fmt, ...)
+{
+}
+
+static inline int ath9k_init_debug(struct ath_softc *sc)
+{
+ return 0;
+}
+
+static inline void ath9k_exit_debug(struct ath_softc *sc)
+{
+}
+
+static inline int ath9k_debug_create_root(void)
+{
+ return 0;
+}
+
+static inline void ath9k_debug_remove_root(void)
+{
+}
+
+static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
+ enum ath9k_int status)
+{
+}
+
+static inline void ath_debug_stat_rc(struct ath_softc *sc,
+ struct sk_buff *skb)
+{
+}
+
+static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+ int xretries, int retries, u8 per)
+{
+}
+
+#endif /* CONFIG_ATH9K_DEBUG */
+
+#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
index acd6c5374d4..183c949bcca 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath9k/eeprom.c
@@ -14,12 +14,9 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
-static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
+static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
u32 reg, u32 mask,
u32 shift, u32 val)
{
@@ -30,7 +27,7 @@ static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
REG_WRITE(ah, reg, regVal);
- if (ah->ah_config.analog_shiftreg)
+ if (ah->config.analog_shiftreg)
udelay(100);
return;
@@ -91,254 +88,290 @@ static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
return false;
}
-static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
+static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
{
- (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+ struct ath_softc *sc = ah->ah_sc;
- if (!ath9k_hw_wait(ah,
- AR_EEPROM_STATUS_DATA,
- AR_EEPROM_STATUS_DATA_BUSY |
- AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
- return false;
- }
-
- *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
- AR_EEPROM_STATUS_DATA_VAL);
-
- return true;
+ return sc->bus_ops->eeprom_read(ah, off, data);
}
-static int ath9k_hw_flash_map(struct ath_hal *ah)
+static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+ u8 *pVpdList, u16 numIntercepts,
+ u8 *pRetVpdList)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
+ u16 i, k;
+ u8 currPwr = pwrMin;
+ u16 idxL = 0, idxR = 0;
- if (!ahp->ah_cal_mem) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "cannot remap eeprom region \n");
- return -EIO;
+ for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
+ ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
+ numIntercepts, &(idxL),
+ &(idxR));
+ if (idxR < 1)
+ idxR = 1;
+ if (idxL == numIntercepts - 1)
+ idxL = (u16) (numIntercepts - 2);
+ if (pPwrList[idxL] == pPwrList[idxR])
+ k = pVpdList[idxL];
+ else
+ k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
+ (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
+ (pPwrList[idxR] - pPwrList[idxL]));
+ pRetVpdList[i] = (u8) k;
+ currPwr += 2;
}
- return 0;
-}
-
-static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- *data = ioread16(ahp->ah_cal_mem + off);
-
return true;
}
-static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
-{
- if (ath9k_hw_use_flash(ah))
- return ath9k_hw_flash_read(ah, off, data);
- else
- return ath9k_hw_eeprom_read(ah, off, data);
-}
-
-static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
+static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct cal_target_power_leg *powInfo,
+ u16 numChannels,
+ struct cal_target_power_leg *pNewPower,
+ u16 numRates, bool isExtTarget)
{
-#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- u16 *eep_data;
- int addr, eep_start_loc = 0;
+ struct chan_centers centers;
+ u16 clo, chi;
+ int i;
+ int matchIndex = -1, lowIndex = -1;
+ u16 freq;
- eep_start_loc = 64;
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+ freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
- if (!ath9k_hw_use_flash(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Reading from EEPROM, not flash\n");
+ if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
+ IS_CHAN_2GHZ(chan))) {
+ matchIndex = 0;
+ } else {
+ for (i = 0; (i < numChannels) &&
+ (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+ if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+ IS_CHAN_2GHZ(chan))) {
+ matchIndex = i;
+ break;
+ } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+ IS_CHAN_2GHZ(chan))) &&
+ (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+ IS_CHAN_2GHZ(chan)))) {
+ lowIndex = i - 1;
+ break;
+ }
+ }
+ if ((matchIndex == -1) && (lowIndex == -1))
+ matchIndex = i - 1;
}
- eep_data = (u16 *)eep;
+ if (matchIndex != -1) {
+ *pNewPower = powInfo[matchIndex];
+ } else {
+ clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+ IS_CHAN_2GHZ(chan));
+ chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+ IS_CHAN_2GHZ(chan));
- for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
- if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Unable to read eeprom region \n");
- return false;
+ for (i = 0; i < numRates; i++) {
+ pNewPower->tPow2x[i] =
+ (u8)ath9k_hw_interpolate(freq, clo, chi,
+ powInfo[lowIndex].tPow2x[i],
+ powInfo[lowIndex + 1].tPow2x[i]);
}
- eep_data++;
}
- return true;
-#undef SIZE_EEPROM_4K
}
-static bool ath9k_hw_fill_def_eeprom(struct ath_hal *ah)
+static void ath9k_get_txgain_index(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct calDataPerFreqOpLoop *rawDatasetOpLoop,
+ u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx)
{
-#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
- u16 *eep_data;
- int addr, ar5416_eep_start_loc = 0x100;
+ u8 pcdac, i = 0;
+ u16 idxL = 0, idxR = 0, numPiers;
+ bool match;
+ struct chan_centers centers;
- eep_data = (u16 *)eep;
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
- for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
- if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
- eep_data)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Unable to read eeprom region\n");
- return false;
- }
- eep_data++;
- }
- return true;
-#undef SIZE_EEPROM_DEF
-}
+ for (numPiers = 0; numPiers < availPiers; numPiers++)
+ if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
+ break;
-static bool (*ath9k_fill_eeprom[]) (struct ath_hal *) = {
- ath9k_hw_fill_def_eeprom,
- ath9k_hw_fill_4k_eeprom
-};
+ match = ath9k_hw_get_lower_upper_index(
+ (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+ calChans, numPiers, &idxL, &idxR);
+ if (match) {
+ pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
+ *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
+ } else {
+ pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
+ *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
+ rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+ }
-static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ while (pcdac > ah->originalGain[i] &&
+ i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
+ i++;
- return ath9k_fill_eeprom[ahp->ah_eep_map](ah);
+ *pcdacIdx = i;
+ return;
}
-static int ath9k_hw_check_def_eeprom(struct ath_hal *ah)
+static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
+ u32 initTxGain,
+ int txPower,
+ u8 *pPDADCValues)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep =
- (struct ar5416_eeprom_def *) &ahp->ah_eeprom.def;
- u16 *eepdata, temp, magic, magic2;
- u32 sum = 0, el;
- bool need_swap = false;
- int i, addr, size;
+ u32 i;
+ u32 offset;
- if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
- &magic)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Reading Magic # failed\n");
- return false;
- }
+ REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
+ AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+ REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
+ AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
- if (!ath9k_hw_use_flash(ah)) {
+ REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
+ AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ offset = txPower;
+ for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
+ if (i < offset)
+ pPDADCValues[i] = 0x0;
+ else
+ pPDADCValues[i] = 0xFF;
+}
- if (magic != AR5416_EEPROM_MAGIC) {
- magic2 = swab16(magic);
- if (magic2 == AR5416_EEPROM_MAGIC) {
- size = sizeof(struct ar5416_eeprom_def);
- need_swap = true;
- eepdata = (u16 *) (&ahp->ah_eeprom);
- for (addr = 0; addr < size / sizeof(u16); addr++) {
- temp = swab16(*eepdata);
- *eepdata = temp;
- eepdata++;
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "0x%04X ", *eepdata);
+static void ath9k_hw_get_target_powers(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct cal_target_power_ht *powInfo,
+ u16 numChannels,
+ struct cal_target_power_ht *pNewPower,
+ u16 numRates, bool isHt40Target)
+{
+ struct chan_centers centers;
+ u16 clo, chi;
+ int i;
+ int matchIndex = -1, lowIndex = -1;
+ u16 freq;
- if (((addr + 1) % 6) == 0)
- DPRINTF(ah->ah_sc,
- ATH_DBG_EEPROM, "\n");
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+ freq = isHt40Target ? centers.synth_center : centers.ctl_center;
+
+ if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+ matchIndex = 0;
+ } else {
+ for (i = 0; (i < numChannels) &&
+ (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+ if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+ IS_CHAN_2GHZ(chan))) {
+ matchIndex = i;
+ break;
+ } else
+ if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+ IS_CHAN_2GHZ(chan))) &&
+ (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+ IS_CHAN_2GHZ(chan)))) {
+ lowIndex = i - 1;
+ break;
}
- } else {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Invalid EEPROM Magic. "
- "endianness mismatch.\n");
- return -EINVAL;
- }
}
+ if ((matchIndex == -1) && (lowIndex == -1))
+ matchIndex = i - 1;
}
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
- need_swap ? "True" : "False");
-
- if (need_swap)
- el = swab16(ahp->ah_eeprom.def.baseEepHeader.length);
- else
- el = ahp->ah_eeprom.def.baseEepHeader.length;
-
- if (el > sizeof(struct ar5416_eeprom_def))
- el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
- else
- el = el / sizeof(u16);
-
- eepdata = (u16 *)(&ahp->ah_eeprom);
-
- for (i = 0; i < el; i++)
- sum ^= *eepdata++;
-
- if (need_swap) {
- u32 integer, j;
- u16 word;
+ if (matchIndex != -1) {
+ *pNewPower = powInfo[matchIndex];
+ } else {
+ clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+ IS_CHAN_2GHZ(chan));
+ chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+ IS_CHAN_2GHZ(chan));
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "EEPROM Endianness is not native.. Changing \n");
+ for (i = 0; i < numRates; i++) {
+ pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
+ clo, chi,
+ powInfo[lowIndex].tPow2x[i],
+ powInfo[lowIndex + 1].tPow2x[i]);
+ }
+ }
+}
- word = swab16(eep->baseEepHeader.length);
- eep->baseEepHeader.length = word;
+static u16 ath9k_hw_get_max_edge_power(u16 freq,
+ struct cal_ctl_edges *pRdEdgesPower,
+ bool is2GHz, int num_band_edges)
+{
+ u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ int i;
- word = swab16(eep->baseEepHeader.checksum);
- eep->baseEepHeader.checksum = word;
+ for (i = 0; (i < num_band_edges) &&
+ (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+ if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
+ twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+ break;
+ } else if ((i > 0) &&
+ (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
+ is2GHz))) {
+ if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
+ is2GHz) < freq &&
+ pRdEdgesPower[i - 1].flag) {
+ twiceMaxEdgePower =
+ pRdEdgesPower[i - 1].tPower;
+ }
+ break;
+ }
+ }
- word = swab16(eep->baseEepHeader.version);
- eep->baseEepHeader.version = word;
+ return twiceMaxEdgePower;
+}
- word = swab16(eep->baseEepHeader.regDmn[0]);
- eep->baseEepHeader.regDmn[0] = word;
+/****************************************/
+/* EEPROM Operations for 4K sized cards */
+/****************************************/
- word = swab16(eep->baseEepHeader.regDmn[1]);
- eep->baseEepHeader.regDmn[1] = word;
+static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
+{
+ return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
+}
- word = swab16(eep->baseEepHeader.rfSilent);
- eep->baseEepHeader.rfSilent = word;
+static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
+{
+ return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
+}
- word = swab16(eep->baseEepHeader.blueToothOptions);
- eep->baseEepHeader.blueToothOptions = word;
+static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ u16 *eep_data;
+ int addr, eep_start_loc = 0;
- word = swab16(eep->baseEepHeader.deviceCap);
- eep->baseEepHeader.deviceCap = word;
+ eep_start_loc = 64;
- for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
- struct modal_eep_header *pModal =
- &eep->modalHeader[j];
- integer = swab32(pModal->antCtrlCommon);
- pModal->antCtrlCommon = integer;
+ if (!ath9k_hw_use_flash(ah)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Reading from EEPROM, not flash\n");
+ }
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- integer = swab32(pModal->antCtrlChain[i]);
- pModal->antCtrlChain[i] = integer;
- }
+ eep_data = (u16 *)eep;
- for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
- word = swab16(pModal->spurChans[i].spurChan);
- pModal->spurChans[i].spurChan = word;
- }
+ for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+ if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Unable to read eeprom region \n");
+ return false;
}
+ eep_data++;
}
-
- if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
- ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
- sum, ar5416_get_eep_ver(ahp));
- return -EINVAL;
- }
-
- return 0;
+ return true;
+#undef SIZE_EEPROM_4K
}
-static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
+static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
{
#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416_eeprom_4k *eep =
- (struct ar5416_eeprom_4k *) &ahp->ah_eeprom.map4k;
+ (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
u16 *eepdata, temp, magic, magic2;
u32 sum = 0, el;
bool need_swap = false;
@@ -362,7 +395,7 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
if (magic2 == AR5416_EEPROM_MAGIC) {
need_swap = true;
- eepdata = (u16 *) (&ahp->ah_eeprom);
+ eepdata = (u16 *) (&ah->eeprom);
for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
temp = swab16(*eepdata);
@@ -389,16 +422,16 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
need_swap ? "True" : "False");
if (need_swap)
- el = swab16(ahp->ah_eeprom.map4k.baseEepHeader.length);
+ el = swab16(ah->eeprom.map4k.baseEepHeader.length);
else
- el = ahp->ah_eeprom.map4k.baseEepHeader.length;
+ el = ah->eeprom.map4k.baseEepHeader.length;
if (el > sizeof(struct ar5416_eeprom_def))
el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
else
el = el / sizeof(u16);
- eepdata = (u16 *)(&ahp->ah_eeprom);
+ eepdata = (u16 *)(&ah->eeprom);
for (i = 0; i < el; i++)
sum ^= *eepdata++;
@@ -448,11 +481,11 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
}
}
- if (sum != 0xffff || ar5416_get_eep4k_ver(ahp) != AR5416_EEP_VER ||
- ar5416_get_eep4k_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
+ if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+ ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
- sum, ar5416_get_eep4k_ver(ahp));
+ sum, ah->eep_ops->get_eeprom_ver(ah));
return -EINVAL;
}
@@ -460,48 +493,50 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
#undef EEPROM_4K_SIZE
}
-static int (*ath9k_check_eeprom[]) (struct ath_hal *) = {
- ath9k_hw_check_def_eeprom,
- ath9k_hw_check_4k_eeprom
-};
-
-static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- return ath9k_check_eeprom[ahp->ah_eep_map](ah);
-}
-
-static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
- u8 *pVpdList, u16 numIntercepts,
- u8 *pRetVpdList)
+static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
+ enum eeprom_param param)
{
- u16 i, k;
- u8 currPwr = pwrMin;
- u16 idxL = 0, idxR = 0;
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &eep->modalHeader;
+ struct base_eep_header_4k *pBase = &eep->baseEepHeader;
- for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
- ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
- numIntercepts, &(idxL),
- &(idxR));
- if (idxR < 1)
- idxR = 1;
- if (idxL == numIntercepts - 1)
- idxL = (u16) (numIntercepts - 2);
- if (pPwrList[idxL] == pPwrList[idxR])
- k = pVpdList[idxL];
- else
- k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
- (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
- (pPwrList[idxR] - pPwrList[idxL]));
- pRetVpdList[i] = (u8) k;
- currPwr += 2;
+ switch (param) {
+ case EEP_NFTHRESH_2:
+ return pModal->noiseFloorThreshCh[0];
+ case AR_EEPROM_MAC(0):
+ return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+ case AR_EEPROM_MAC(1):
+ return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+ case AR_EEPROM_MAC(2):
+ return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+ case EEP_REG_0:
+ return pBase->regDmn[0];
+ case EEP_REG_1:
+ return pBase->regDmn[1];
+ case EEP_OP_CAP:
+ return pBase->deviceCap;
+ case EEP_OP_MODE:
+ return pBase->opCapFlags;
+ case EEP_RF_SILENT:
+ return pBase->rfSilent;
+ case EEP_OB_2:
+ return pModal->ob_01;
+ case EEP_DB_2:
+ return pModal->db1_01;
+ case EEP_MINOR_REV:
+ return pBase->version & AR5416_EEP_VER_MINOR_MASK;
+ case EEP_TX_MASK:
+ return pBase->txMask;
+ case EEP_RX_MASK:
+ return pBase->rxMask;
+ case EEP_FRAC_N_5G:
+ return 0;
+ default:
+ return 0;
}
-
- return true;
}
-static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
+static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
struct ath9k_channel *chan,
struct cal_data_per_freq_4k *pRawDataSet,
u8 *bChans, u16 availPiers,
@@ -605,7 +640,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
pPdGainBoundaries[i] =
min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
- if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
+ if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
minDelta = pPdGainBoundaries[0] - 23;
pPdGainBoundaries[0] = 23;
} else {
@@ -644,7 +679,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
vpdTableI[i][sizeCurrVpdTable - 2]);
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
- if (tgtIndex > maxIndex) {
+ if (tgtIndex >= maxIndex) {
while ((ss <= tgtIndex) &&
(k < (AR5416_NUM_PDADC_VALUES - 1))) {
tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
@@ -669,451 +704,20 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
#undef TMP_VAL_VPD_TABLE
}
-static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct cal_data_per_freq *pRawDataSet,
- u8 *bChans, u16 availPiers,
- u16 tPdGainOverlap, int16_t *pMinCalPower,
- u16 *pPdGainBoundaries, u8 *pPDADCValues,
- u16 numXpdGains)
-{
- int i, j, k;
- int16_t ss;
- u16 idxL = 0, idxR = 0, numPiers;
- static u8 vpdTableL[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableR[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableI[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
- u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
- u8 minPwrT4[AR5416_NUM_PD_GAINS];
- u8 maxPwrT4[AR5416_NUM_PD_GAINS];
- int16_t vpdStep;
- int16_t tmpVal;
- u16 sizeCurrVpdTable, maxIndex, tgtIndex;
- bool match;
- int16_t minDelta = 0;
- struct chan_centers centers;
-
- ath9k_hw_get_channel_centers(ah, chan, &centers);
-
- for (numPiers = 0; numPiers < availPiers; numPiers++) {
- if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
- break;
- }
-
- match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
- IS_CHAN_2GHZ(chan)),
- bChans, numPiers, &idxL, &idxR);
-
- if (match) {
- for (i = 0; i < numXpdGains; i++) {
- minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
- maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pRawDataSet[idxL].pwrPdg[i],
- pRawDataSet[idxL].vpdPdg[i],
- AR5416_PD_GAIN_ICEPTS,
- vpdTableI[i]);
- }
- } else {
- for (i = 0; i < numXpdGains; i++) {
- pVpdL = pRawDataSet[idxL].vpdPdg[i];
- pPwrL = pRawDataSet[idxL].pwrPdg[i];
- pVpdR = pRawDataSet[idxR].vpdPdg[i];
- pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
- minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
- maxPwrT4[i] =
- min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
- pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
-
-
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrL, pVpdL,
- AR5416_PD_GAIN_ICEPTS,
- vpdTableL[i]);
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrR, pVpdR,
- AR5416_PD_GAIN_ICEPTS,
- vpdTableR[i]);
-
- for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
- vpdTableI[i][j] =
- (u8)(ath9k_hw_interpolate((u16)
- FREQ2FBIN(centers.
- synth_center,
- IS_CHAN_2GHZ
- (chan)),
- bChans[idxL], bChans[idxR],
- vpdTableL[i][j], vpdTableR[i][j]));
- }
- }
- }
-
- *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
-
- k = 0;
-
- for (i = 0; i < numXpdGains; i++) {
- if (i == (numXpdGains - 1))
- pPdGainBoundaries[i] =
- (u16)(maxPwrT4[i] / 2);
- else
- pPdGainBoundaries[i] =
- (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
- pPdGainBoundaries[i] =
- min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
- if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
- minDelta = pPdGainBoundaries[0] - 23;
- pPdGainBoundaries[0] = 23;
- } else {
- minDelta = 0;
- }
-
- if (i == 0) {
- if (AR_SREV_9280_10_OR_LATER(ah))
- ss = (int16_t)(0 - (minPwrT4[i] / 2));
- else
- ss = 0;
- } else {
- ss = (int16_t)((pPdGainBoundaries[i - 1] -
- (minPwrT4[i] / 2)) -
- tPdGainOverlap + 1 + minDelta);
- }
- vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
- pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
- ss++;
- }
-
- sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
- tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
- (minPwrT4[i] / 2));
- maxIndex = (tgtIndex < sizeCurrVpdTable) ?
- tgtIndex : sizeCurrVpdTable;
-
- while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- pPDADCValues[k++] = vpdTableI[i][ss++];
- }
-
- vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
- vpdTableI[i][sizeCurrVpdTable - 2]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- if (tgtIndex > maxIndex) {
- while ((ss <= tgtIndex) &&
- (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
- (ss - maxIndex + 1) * vpdStep));
- pPDADCValues[k++] = (u8)((tmpVal > 255) ?
- 255 : tmpVal);
- ss++;
- }
- }
- }
-
- while (i < AR5416_PD_GAINS_IN_MASK) {
- pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
- i++;
- }
-
- while (k < AR5416_NUM_PDADC_VALUES) {
- pPDADCValues[k] = pPDADCValues[k - 1];
- k++;
- }
-
- return;
-}
-
-static void ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct cal_target_power_leg *powInfo,
- u16 numChannels,
- struct cal_target_power_leg *pNewPower,
- u16 numRates, bool isExtTarget)
-{
- struct chan_centers centers;
- u16 clo, chi;
- int i;
- int matchIndex = -1, lowIndex = -1;
- u16 freq;
-
- ath9k_hw_get_channel_centers(ah, chan, &centers);
- freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
-
- if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
- IS_CHAN_2GHZ(chan))) {
- matchIndex = 0;
- } else {
- for (i = 0; (i < numChannels) &&
- (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
- if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
- IS_CHAN_2GHZ(chan))) {
- matchIndex = i;
- break;
- } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
- IS_CHAN_2GHZ(chan))) &&
- (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
- IS_CHAN_2GHZ(chan)))) {
- lowIndex = i - 1;
- break;
- }
- }
- if ((matchIndex == -1) && (lowIndex == -1))
- matchIndex = i - 1;
- }
-
- if (matchIndex != -1) {
- *pNewPower = powInfo[matchIndex];
- } else {
- clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
- IS_CHAN_2GHZ(chan));
- chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
- IS_CHAN_2GHZ(chan));
-
- for (i = 0; i < numRates; i++) {
- pNewPower->tPow2x[i] =
- (u8)ath9k_hw_interpolate(freq, clo, chi,
- powInfo[lowIndex].tPow2x[i],
- powInfo[lowIndex + 1].tPow2x[i]);
- }
- }
-}
-
-static void ath9k_hw_get_target_powers(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct cal_target_power_ht *powInfo,
- u16 numChannels,
- struct cal_target_power_ht *pNewPower,
- u16 numRates, bool isHt40Target)
-{
- struct chan_centers centers;
- u16 clo, chi;
- int i;
- int matchIndex = -1, lowIndex = -1;
- u16 freq;
-
- ath9k_hw_get_channel_centers(ah, chan, &centers);
- freq = isHt40Target ? centers.synth_center : centers.ctl_center;
-
- if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
- matchIndex = 0;
- } else {
- for (i = 0; (i < numChannels) &&
- (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
- if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
- IS_CHAN_2GHZ(chan))) {
- matchIndex = i;
- break;
- } else
- if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
- IS_CHAN_2GHZ(chan))) &&
- (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
- IS_CHAN_2GHZ(chan)))) {
- lowIndex = i - 1;
- break;
- }
- }
- if ((matchIndex == -1) && (lowIndex == -1))
- matchIndex = i - 1;
- }
-
- if (matchIndex != -1) {
- *pNewPower = powInfo[matchIndex];
- } else {
- clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
- IS_CHAN_2GHZ(chan));
- chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
- IS_CHAN_2GHZ(chan));
-
- for (i = 0; i < numRates; i++) {
- pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
- clo, chi,
- powInfo[lowIndex].tPow2x[i],
- powInfo[lowIndex + 1].tPow2x[i]);
- }
- }
-}
-
-static u16 ath9k_hw_get_max_edge_power(u16 freq,
- struct cal_ctl_edges *pRdEdgesPower,
- bool is2GHz, int num_band_edges)
-{
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- int i;
-
- for (i = 0; (i < num_band_edges) &&
- (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
- if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
- twiceMaxEdgePower = pRdEdgesPower[i].tPower;
- break;
- } else if ((i > 0) &&
- (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
- is2GHz))) {
- if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
- is2GHz) < freq &&
- pRdEdgesPower[i - 1].flag) {
- twiceMaxEdgePower =
- pRdEdgesPower[i - 1].tPower;
- }
- break;
- }
- }
-
- return twiceMaxEdgePower;
-}
-
-static bool ath9k_hw_set_def_power_cal_table(struct ath_hal *ah,
+static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *pTxPowerIndexOffset)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
- struct cal_data_per_freq *pRawDataset;
- u8 *pCalBChans = NULL;
- u16 pdGainOverlap_t2;
- static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
- u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
- u16 numPiers, i, j;
- int16_t tMinCalPower;
- u16 numXpdGain, xpdMask;
- u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
- u32 reg32, regOffset, regChainOffset;
- int16_t modalIdx;
-
- modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
- xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
-
- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
- pdGainOverlap_t2 =
- pEepData->modalHeader[modalIdx].pdGainOverlap;
- } else {
- pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
- AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
- }
-
- if (IS_CHAN_2GHZ(chan)) {
- pCalBChans = pEepData->calFreqPier2G;
- numPiers = AR5416_NUM_2G_CAL_PIERS;
- } else {
- pCalBChans = pEepData->calFreqPier5G;
- numPiers = AR5416_NUM_5G_CAL_PIERS;
- }
-
- numXpdGain = 0;
-
- for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
- if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
- if (numXpdGain >= AR5416_NUM_PD_GAINS)
- break;
- xpdGainValues[numXpdGain] =
- (u16)(AR5416_PD_GAINS_IN_MASK - i);
- numXpdGain++;
- }
- }
-
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
- (numXpdGain - 1) & 0x3);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
- xpdGainValues[0]);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
- xpdGainValues[1]);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
- xpdGainValues[2]);
-
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- if (AR_SREV_5416_V20_OR_LATER(ah) &&
- (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
- (i != 0)) {
- regChainOffset = (i == 1) ? 0x2000 : 0x1000;
- } else
- regChainOffset = i * 0x1000;
-
- if (pEepData->baseEepHeader.txMask & (1 << i)) {
- if (IS_CHAN_2GHZ(chan))
- pRawDataset = pEepData->calPierData2G[i];
- else
- pRawDataset = pEepData->calPierData5G[i];
-
- ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
- pRawDataset, pCalBChans,
- numPiers, pdGainOverlap_t2,
- &tMinCalPower, gainBoundaries,
- pdadcValues, numXpdGain);
-
- if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
- REG_WRITE(ah,
- AR_PHY_TPCRG5 + regChainOffset,
- SM(pdGainOverlap_t2,
- AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
- | SM(gainBoundaries[0],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
- | SM(gainBoundaries[1],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
- | SM(gainBoundaries[2],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
- | SM(gainBoundaries[3],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
- }
-
- regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
- for (j = 0; j < 32; j++) {
- reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
- ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
- ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
- ((pdadcValues[4 * j + 3] & 0xFF) << 24);
- REG_WRITE(ah, regOffset, reg32);
-
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "PDADC (%d,%4x): %4.4x %8.8x\n",
- i, regChainOffset, regOffset,
- reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "PDADC: Chain %d | PDADC %3d "
- "Value %3d | PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | PDADC %3d "
- "Value %3d |\n",
- i, 4 * j, pdadcValues[4 * j],
- 4 * j + 1, pdadcValues[4 * j + 1],
- 4 * j + 2, pdadcValues[4 * j + 2],
- 4 * j + 3,
- pdadcValues[4 * j + 3]);
-
- regOffset += 4;
- }
- }
- }
-
- *pTxPowerIndexOffset = 0;
-
- return true;
-}
-
-static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+ struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
struct cal_data_per_freq_4k *pRawDataset;
u8 *pCalBChans = NULL;
u16 pdGainOverlap_t2;
static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
- u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+ u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
u16 numPiers, i, j;
int16_t tMinCalPower;
u16 numXpdGain, xpdMask;
- u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+ u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
u32 reg32, regOffset, regChainOffset;
xpdMask = pEepData->modalHeader.xpdGain;
@@ -1128,16 +732,16 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
}
pCalBChans = pEepData->calFreqPier2G;
- numPiers = AR5416_NUM_2G_CAL_PIERS;
+ numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
numXpdGain = 0;
- for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
- if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
- if (numXpdGain >= AR5416_NUM_PD_GAINS)
+ for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
break;
xpdGainValues[numXpdGain] =
- (u16)(AR5416_PD_GAINS_IN_MASK - i);
+ (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
numXpdGain++;
}
}
@@ -1148,12 +752,11 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
xpdGainValues[0]);
REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
xpdGainValues[1]);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
- xpdGainValues[2]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- if (AR_SREV_5416_V20_OR_LATER(ah) &&
- (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+ for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+ if (AR_SREV_5416_20_OR_LATER(ah) &&
+ (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
(i != 0)) {
regChainOffset = (i == 1) ? 0x2000 : 0x1000;
} else
@@ -1168,7 +771,7 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
&tMinCalPower, gainBoundaries,
pdadcValues, numXpdGain);
- if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+ if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
SM(pdGainOverlap_t2,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
@@ -1216,298 +819,7 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
return true;
}
-static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *ratesArray,
- u16 cfgCtl,
- u16 AntennaReduction,
- u16 twiceMaxRegulatoryPower,
- u16 powerLimit)
-{
-#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
-#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
-
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- static const u16 tpScaleReductionTable[5] =
- { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
- int i;
- int16_t twiceLargestAntenna;
- struct cal_ctl_data *rep;
- struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
- 0, { 0, 0, 0, 0}
- };
- struct cal_target_power_leg targetPowerOfdmExt = {
- 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
- 0, { 0, 0, 0, 0 }
- };
- struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
- 0, {0, 0, 0, 0}
- };
- u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 ctlModesFor11a[] =
- { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
- u16 ctlModesFor11g[] =
- { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
- CTL_2GHT40
- };
- u16 numCtlModes, *pCtlMode, ctlMode, freq;
- struct chan_centers centers;
- int tx_chainmask;
- u16 twiceMinEdgePower;
-
- tx_chainmask = ahp->ah_txchainmask;
-
- ath9k_hw_get_channel_centers(ah, chan, &centers);
-
- twiceLargestAntenna = max(
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
-
- twiceLargestAntenna = max((u8)twiceLargestAntenna,
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
-
- twiceLargestAntenna = (int16_t)min(AntennaReduction -
- twiceLargestAntenna, 0);
-
- maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
- if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
- maxRegAllowedPower -=
- (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
- }
-
- scaledPower = min(powerLimit, maxRegAllowedPower);
-
- switch (ar5416_get_ntxchains(tx_chainmask)) {
- case 1:
- break;
- case 2:
- scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
- break;
- case 3:
- scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
- break;
- }
-
- scaledPower = max((u16)0, scaledPower);
-
- if (IS_CHAN_2GHZ(chan)) {
- numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
- SUB_NUM_CTL_MODES_AT_2G_40;
- pCtlMode = ctlModesFor11g;
-
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPowerCck,
- AR5416_NUM_2G_CCK_TARGET_POWERS,
- &targetPowerCck, 4, false);
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPower2G,
- AR5416_NUM_2G_20_TARGET_POWERS,
- &targetPowerOfdm, 4, false);
- ath9k_hw_get_target_powers(ah, chan,
- pEepData->calTargetPower2GHT20,
- AR5416_NUM_2G_20_TARGET_POWERS,
- &targetPowerHt20, 8, false);
-
- if (IS_CHAN_HT40(chan)) {
- numCtlModes = ARRAY_SIZE(ctlModesFor11g);
- ath9k_hw_get_target_powers(ah, chan,
- pEepData->calTargetPower2GHT40,
- AR5416_NUM_2G_40_TARGET_POWERS,
- &targetPowerHt40, 8, true);
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPowerCck,
- AR5416_NUM_2G_CCK_TARGET_POWERS,
- &targetPowerCckExt, 4, true);
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPower2G,
- AR5416_NUM_2G_20_TARGET_POWERS,
- &targetPowerOfdmExt, 4, true);
- }
- } else {
- numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
- SUB_NUM_CTL_MODES_AT_5G_40;
- pCtlMode = ctlModesFor11a;
-
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPower5G,
- AR5416_NUM_5G_20_TARGET_POWERS,
- &targetPowerOfdm, 4, false);
- ath9k_hw_get_target_powers(ah, chan,
- pEepData->calTargetPower5GHT20,
- AR5416_NUM_5G_20_TARGET_POWERS,
- &targetPowerHt20, 8, false);
-
- if (IS_CHAN_HT40(chan)) {
- numCtlModes = ARRAY_SIZE(ctlModesFor11a);
- ath9k_hw_get_target_powers(ah, chan,
- pEepData->calTargetPower5GHT40,
- AR5416_NUM_5G_40_TARGET_POWERS,
- &targetPowerHt40, 8, true);
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPower5G,
- AR5416_NUM_5G_20_TARGET_POWERS,
- &targetPowerOfdmExt, 4, true);
- }
- }
-
- for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
- bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
- (pCtlMode[ctlMode] == CTL_2GHT40);
- if (isHt40CtlMode)
- freq = centers.synth_center;
- else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
- freq = centers.ext_center;
- else
- freq = centers.ctl_center;
-
- if (ar5416_get_eep_ver(ahp) == 14 && ar5416_get_eep_rev(ahp) <= 2)
- twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
- "EXT_ADDITIVE %d\n",
- ctlMode, numCtlModes, isHt40CtlMode,
- (pCtlMode[ctlMode] & EXT_ADDITIVE));
-
- for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
- "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
- "chan %d\n",
- i, cfgCtl, pCtlMode[ctlMode],
- pEepData->ctlIndex[i], chan->channel);
-
- if ((((cfgCtl & ~CTL_MODE_M) |
- (pCtlMode[ctlMode] & CTL_MODE_M)) ==
- pEepData->ctlIndex[i]) ||
- (((cfgCtl & ~CTL_MODE_M) |
- (pCtlMode[ctlMode] & CTL_MODE_M)) ==
- ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
- rep = &(pEepData->ctlData[i]);
-
- twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
- rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
- IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
-
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- " MATCH-EE_IDX %d: ch %d is2 %d "
- "2xMinEdge %d chainmask %d chains %d\n",
- i, freq, IS_CHAN_2GHZ(chan),
- twiceMinEdgePower, tx_chainmask,
- ar5416_get_ntxchains
- (tx_chainmask));
- if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
- twiceMaxEdgePower = min(twiceMaxEdgePower,
- twiceMinEdgePower);
- } else {
- twiceMaxEdgePower = twiceMinEdgePower;
- break;
- }
- }
- }
-
- minCtlPower = min(twiceMaxEdgePower, scaledPower);
-
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- " SEL-Min ctlMode %d pCtlMode %d "
- "2xMaxEdge %d sP %d minCtlPwr %d\n",
- ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
- scaledPower, minCtlPower);
-
- switch (pCtlMode[ctlMode]) {
- case CTL_11B:
- for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
- targetPowerCck.tPow2x[i] =
- min((u16)targetPowerCck.tPow2x[i],
- minCtlPower);
- }
- break;
- case CTL_11A:
- case CTL_11G:
- for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
- targetPowerOfdm.tPow2x[i] =
- min((u16)targetPowerOfdm.tPow2x[i],
- minCtlPower);
- }
- break;
- case CTL_5GHT20:
- case CTL_2GHT20:
- for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
- targetPowerHt20.tPow2x[i] =
- min((u16)targetPowerHt20.tPow2x[i],
- minCtlPower);
- }
- break;
- case CTL_11B_EXT:
- targetPowerCckExt.tPow2x[0] = min((u16)
- targetPowerCckExt.tPow2x[0],
- minCtlPower);
- break;
- case CTL_11A_EXT:
- case CTL_11G_EXT:
- targetPowerOfdmExt.tPow2x[0] = min((u16)
- targetPowerOfdmExt.tPow2x[0],
- minCtlPower);
- break;
- case CTL_5GHT40:
- case CTL_2GHT40:
- for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
- targetPowerHt40.tPow2x[i] =
- min((u16)targetPowerHt40.tPow2x[i],
- minCtlPower);
- }
- break;
- default:
- break;
- }
- }
-
- ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
- ratesArray[rate18mb] = ratesArray[rate24mb] =
- targetPowerOfdm.tPow2x[0];
- ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
- ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
- ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
- ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
-
- for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
- ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
-
- if (IS_CHAN_2GHZ(chan)) {
- ratesArray[rate1l] = targetPowerCck.tPow2x[0];
- ratesArray[rate2s] = ratesArray[rate2l] =
- targetPowerCck.tPow2x[1];
- ratesArray[rate5_5s] = ratesArray[rate5_5l] =
- targetPowerCck.tPow2x[2];
- ;
- ratesArray[rate11s] = ratesArray[rate11l] =
- targetPowerCck.tPow2x[3];
- ;
- }
- if (IS_CHAN_HT40(chan)) {
- for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
- ratesArray[rateHt40_0 + i] =
- targetPowerHt40.tPow2x[i];
- }
- ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
- ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
- ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
- if (IS_CHAN_2GHZ(chan)) {
- ratesArray[rateExtCck] =
- targetPowerCckExt.tPow2x[0];
- }
- }
- return true;
-}
-
-static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
+static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *ratesArray,
u16 cfgCtl,
@@ -1515,8 +827,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
u16 twiceMaxRegulatoryPower,
u16 powerLimit)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+ struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
static const u16 tpScaleReductionTable[5] =
{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
@@ -1544,7 +855,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
int tx_chainmask;
u16 twiceMinEdgePower;
- tx_chainmask = ahp->ah_txchainmask;
+ tx_chainmask = ah->txchainmask;
ath9k_hw_get_channel_centers(ah, chan, &centers);
@@ -1555,9 +866,9 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
- if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
+ if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
maxRegAllowedPower -=
- (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
+ (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
}
scaledPower = min(powerLimit, maxRegAllowedPower);
@@ -1605,8 +916,8 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
else
freq = centers.ctl_center;
- if (ar5416_get_eep_ver(ahp) == 14 &&
- ar5416_get_eep_rev(ahp) <= 2)
+ if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+ ah->eep_ops->get_eeprom_rev(ah) <= 2)
twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
@@ -1743,17 +1054,15 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
return true;
}
-static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ u16 cfgCtl,
+ u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower,
+ u8 powerLimit)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
- struct modal_eep_header *pModal =
- &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+ struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
int16_t ratesArray[Ar5416RateSize];
int16_t txPowerIndexOffset = 0;
u8 ht40PowerIncForPdadc = 2;
@@ -1766,7 +1075,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
- if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+ if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
&ratesArray[0], cfgCtl,
twiceAntennaReduction,
twiceMaxRegulatoryPower,
@@ -1777,7 +1086,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
return -EIO;
}
- if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+ 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;
@@ -1856,10 +1165,6 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
}
- REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
- ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
- | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
-
i = rate6mb;
if (IS_CHAN_HT40(chan))
@@ -1868,272 +1173,533 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
i = rateHt20_0;
if (AR_SREV_9280_10_OR_LATER(ah))
- ah->ah_maxPowerLevel =
+ ah->regulatory.max_power_level =
ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
else
- ah->ah_maxPowerLevel = ratesArray[i];
+ ah->regulatory.max_power_level = ratesArray[i];
return 0;
}
-static int ath9k_hw_4k_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
- struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
- int16_t ratesArray[Ar5416RateSize];
- int16_t txPowerIndexOffset = 0;
- u8 ht40PowerIncForPdadc = 2;
- int i;
+ struct modal_eep_4k_header *pModal;
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ u8 biaslevel;
- memset(ratesArray, 0, sizeof(ratesArray));
+ if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+ return;
- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
- ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+ if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+ return;
+
+ pModal = &eep->modalHeader;
+
+ if (pModal->xpaBiasLvl != 0xff) {
+ biaslevel = pModal->xpaBiasLvl;
+ INI_RA(&ah->iniAddac, 7, 1) =
+ (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
}
+}
- if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
- &ratesArray[0], cfgCtl,
- twiceAntennaReduction,
- twiceMaxRegulatoryPower,
- powerLimit)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set "
- "tx power per rate table\n");
- return -EIO;
+static bool ath9k_hw_4k_set_board_values(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ struct modal_eep_4k_header *pModal;
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ int regChainOffset;
+ u8 txRxAttenLocal;
+ u8 ob[5], db1[5], db2[5];
+ u8 ant_div_control1, ant_div_control2;
+ u32 regVal;
+
+
+ pModal = &eep->modalHeader;
+
+ txRxAttenLocal = 23;
+
+ REG_WRITE(ah, AR_PHY_SWITCH_COM,
+ ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+ regChainOffset = 0;
+ REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+ pModal->antCtrlChain[0]);
+
+ REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+ (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+ ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+ SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+ SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_3) {
+ txRxAttenLocal = pModal->txRxAttenCh[0];
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+ pModal->xatten2Margin[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
}
- if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+ REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+ REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+
+ if (AR_SREV_9285_11(ah))
+ REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+
+ /* Initialize Ant Diversity settings from EEPROM */
+ if (pModal->version == 3) {
+ ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
+ ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
+ regVal = REG_READ(ah, 0x99ac);
+ regVal &= (~(0x7f000000));
+ regVal |= ((ant_div_control1 & 0x1) << 24);
+ regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
+ regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
+ regVal |= ((ant_div_control2 & 0x3) << 25);
+ regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
+ REG_WRITE(ah, 0x99ac, regVal);
+ regVal = REG_READ(ah, 0x99ac);
+ regVal = REG_READ(ah, 0xa208);
+ regVal &= (~(0x1 << 13));
+ regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
+ REG_WRITE(ah, 0xa208, regVal);
+ regVal = REG_READ(ah, 0xa208);
+ }
+
+ if (pModal->version >= 2) {
+ ob[0] = (pModal->ob_01 & 0xf);
+ ob[1] = (pModal->ob_01 >> 4) & 0xf;
+ ob[2] = (pModal->ob_234 & 0xf);
+ ob[3] = ((pModal->ob_234 >> 4) & 0xf);
+ ob[4] = ((pModal->ob_234 >> 8) & 0xf);
+
+ db1[0] = (pModal->db1_01 & 0xf);
+ db1[1] = ((pModal->db1_01 >> 4) & 0xf);
+ db1[2] = (pModal->db1_234 & 0xf);
+ db1[3] = ((pModal->db1_234 >> 4) & 0xf);
+ db1[4] = ((pModal->db1_234 >> 8) & 0xf);
+
+ db2[0] = (pModal->db2_01 & 0xf);
+ db2[1] = ((pModal->db2_01 >> 4) & 0xf);
+ db2[2] = (pModal->db2_234 & 0xf);
+ db2[3] = ((pModal->db2_234 >> 4) & 0xf);
+ db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+
+ } else if (pModal->version == 1) {
+
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set power table\n");
- return -EIO;
+ "EEPROM Model version is set to 1 \n");
+ ob[0] = (pModal->ob_01 & 0xf);
+ ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
+ db1[0] = (pModal->db1_01 & 0xf);
+ db1[1] = db1[2] = db1[3] =
+ db1[4] = ((pModal->db1_01 >> 4) & 0xf);
+ db2[0] = (pModal->db2_01 & 0xf);
+ db2[1] = db2[2] = db2[3] =
+ db2[4] = ((pModal->db2_01 >> 4) & 0xf);
+ } else {
+ int i;
+ for (i = 0; i < 5; i++) {
+ ob[i] = pModal->ob_01;
+ db1[i] = pModal->db1_01;
+ db2[i] = pModal->db1_01;
+ }
}
- for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
- ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
- if (ratesArray[i] > AR5416_MAX_RATE_POWER)
- ratesArray[i] = AR5416_MAX_RATE_POWER;
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
+
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
+
+
+ if (AR_SREV_9285_11(ah))
+ REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+ REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+ pModal->switchSettling);
+ REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+ pModal->adcDesiredSize);
+
+ REG_WRITE(ah, AR_PHY_RF_CTL4,
+ SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+ SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+ SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
+ SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+ pModal->txEndToRxOn);
+ REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+ pModal->thresh62);
+ REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
+ pModal->thresh62);
+
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
+ pModal->txFrameToDataStart);
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+ pModal->txFrameToPaOn);
}
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- for (i = 0; i < Ar5416RateSize; i++)
- ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_3) {
+ if (IS_CHAN_HT40(chan))
+ REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+ AR_PHY_SETTLING_SWITCH,
+ pModal->swSettleHt40);
}
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
- ATH9K_POW_SM(ratesArray[rate18mb], 24)
- | ATH9K_POW_SM(ratesArray[rate12mb], 16)
- | ATH9K_POW_SM(ratesArray[rate9mb], 8)
- | ATH9K_POW_SM(ratesArray[rate6mb], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
- ATH9K_POW_SM(ratesArray[rate54mb], 24)
- | ATH9K_POW_SM(ratesArray[rate48mb], 16)
- | ATH9K_POW_SM(ratesArray[rate36mb], 8)
- | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+ return true;
+}
- if (IS_CHAN_2GHZ(chan)) {
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
- ATH9K_POW_SM(ratesArray[rate2s], 24)
- | ATH9K_POW_SM(ratesArray[rate2l], 16)
- | ATH9K_POW_SM(ratesArray[rateXr], 8)
- | ATH9K_POW_SM(ratesArray[rate1l], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
- ATH9K_POW_SM(ratesArray[rate11s], 24)
- | ATH9K_POW_SM(ratesArray[rate11l], 16)
- | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
- | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
- }
+static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &eep->modalHeader;
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
- ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
- | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
- | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
- | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
- ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
- | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
- | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
- | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+ return pModal->antCtrlCommon & 0xFFFF;
+}
- if (IS_CHAN_HT40(chan)) {
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
- ATH9K_POW_SM(ratesArray[rateHt40_3] +
- ht40PowerIncForPdadc, 24)
- | ATH9K_POW_SM(ratesArray[rateHt40_2] +
- ht40PowerIncForPdadc, 16)
- | ATH9K_POW_SM(ratesArray[rateHt40_1] +
- ht40PowerIncForPdadc, 8)
- | ATH9K_POW_SM(ratesArray[rateHt40_0] +
- ht40PowerIncForPdadc, 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
- ATH9K_POW_SM(ratesArray[rateHt40_7] +
- ht40PowerIncForPdadc, 24)
- | ATH9K_POW_SM(ratesArray[rateHt40_6] +
- ht40PowerIncForPdadc, 16)
- | ATH9K_POW_SM(ratesArray[rateHt40_5] +
- ht40PowerIncForPdadc, 8)
- | ATH9K_POW_SM(ratesArray[rateHt40_4] +
- ht40PowerIncForPdadc, 0));
+static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
+ enum ieee80211_band freq_band)
+{
+ return 1;
+}
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
- ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
- | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
- | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
- | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
- }
+static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_MAP4K_SPURCHAN \
+ (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
- i = rate6mb;
+ u16 spur_val = AR_NO_SPUR;
- if (IS_CHAN_HT40(chan))
- i = rateHt40_0;
- else if (IS_CHAN_HT20(chan))
- i = rateHt20_0;
+ DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+ "Getting spur idx %d is2Ghz. %d val %x\n",
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
- if (AR_SREV_9280_10_OR_LATER(ah))
- ah->ah_maxPowerLevel =
- ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
- else
- ah->ah_maxPowerLevel = ratesArray[i];
+ switch (ah->config.spurmode) {
+ case SPUR_DISABLE:
+ break;
+ case SPUR_ENABLE_IOCTL:
+ spur_val = ah->config.spurchans[i][is2GHz];
+ DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+ "Getting spur val from new loc. %d\n", spur_val);
+ break;
+ case SPUR_ENABLE_EEPROM:
+ spur_val = EEP_MAP4K_SPURCHAN;
+ break;
+ }
- return 0;
+ return spur_val;
+
+#undef EEP_MAP4K_SPURCHAN
}
-static int (*ath9k_set_txpower[]) (struct ath_hal *,
- struct ath9k_channel *,
- u16, u8, u8, u8) = {
- ath9k_hw_def_set_txpower,
- ath9k_hw_4k_set_txpower
+static struct eeprom_ops eep_4k_ops = {
+ .check_eeprom = ath9k_hw_4k_check_eeprom,
+ .get_eeprom = ath9k_hw_4k_get_eeprom,
+ .fill_eeprom = ath9k_hw_4k_fill_eeprom,
+ .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
+ .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
+ .get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
+ .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
+ .set_board_values = ath9k_hw_4k_set_board_values,
+ .set_addac = ath9k_hw_4k_set_addac,
+ .set_txpower = ath9k_hw_4k_set_txpower,
+ .get_spur_channel = ath9k_hw_4k_get_spur_channel
};
-int ath9k_hw_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+/************************************************/
+/* EEPROM Operations for non-4K (Default) cards */
+/************************************************/
+
+static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
+}
- return ath9k_set_txpower[ahp->ah_eep_map](ah, chan, cfgCtl,
- twiceAntennaReduction, twiceMaxRegulatoryPower,
- powerLimit);
+static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
+{
+ return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
}
-static void ath9k_hw_set_def_addac(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
{
-#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
- struct modal_eep_header *pModal;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
- u8 biaslevel;
+#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ u16 *eep_data;
+ int addr, ar5416_eep_start_loc = 0x100;
- if (ah->ah_macVersion != AR_SREV_VERSION_9160)
- return;
+ eep_data = (u16 *)eep;
- if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
- return;
+ for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+ if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+ eep_data)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Unable to read eeprom region\n");
+ return false;
+ }
+ eep_data++;
+ }
+ return true;
+#undef SIZE_EEPROM_DEF
+}
- pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
+{
+ struct ar5416_eeprom_def *eep =
+ (struct ar5416_eeprom_def *) &ah->eeprom.def;
+ u16 *eepdata, temp, magic, magic2;
+ u32 sum = 0, el;
+ bool need_swap = false;
+ int i, addr, size;
- if (pModal->xpaBiasLvl != 0xff) {
- biaslevel = pModal->xpaBiasLvl;
- } else {
- u16 resetFreqBin, freqBin, freqCount = 0;
- struct chan_centers centers;
+ if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+ &magic)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Reading Magic # failed\n");
+ return false;
+ }
- ath9k_hw_get_channel_centers(ah, chan, &centers);
+ if (!ath9k_hw_use_flash(ah)) {
- resetFreqBin = FREQ2FBIN(centers.synth_center,
- IS_CHAN_2GHZ(chan));
- freqBin = XPA_LVL_FREQ(0) & 0xff;
- biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
- freqCount++;
+ if (magic != AR5416_EEPROM_MAGIC) {
+ magic2 = swab16(magic);
- while (freqCount < 3) {
- if (XPA_LVL_FREQ(freqCount) == 0x0)
- break;
+ if (magic2 == AR5416_EEPROM_MAGIC) {
+ size = sizeof(struct ar5416_eeprom_def);
+ need_swap = true;
+ eepdata = (u16 *) (&ah->eeprom);
- freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
- if (resetFreqBin >= freqBin)
- biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
- else
- break;
- freqCount++;
+ for (addr = 0; addr < size / sizeof(u16); addr++) {
+ temp = swab16(*eepdata);
+ *eepdata = temp;
+ eepdata++;
+
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "0x%04X ", *eepdata);
+
+ if (((addr + 1) % 6) == 0)
+ DPRINTF(ah->ah_sc,
+ ATH_DBG_EEPROM, "\n");
+ }
+ } else {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Invalid EEPROM Magic. "
+ "endianness mismatch.\n");
+ return -EINVAL;
+ }
}
}
- if (IS_CHAN_2GHZ(chan)) {
- INI_RA(&ahp->ah_iniAddac, 7, 1) = (INI_RA(&ahp->ah_iniAddac,
- 7, 1) & (~0x18)) | biaslevel << 3;
- } else {
- INI_RA(&ahp->ah_iniAddac, 6, 1) = (INI_RA(&ahp->ah_iniAddac,
- 6, 1) & (~0xc0)) | biaslevel << 6;
- }
-#undef XPA_LVL_FREQ
-}
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
-static void ath9k_hw_set_4k_addac(struct ath_hal *ah,
- struct ath9k_channel *chan)
-{
- struct modal_eep_4k_header *pModal;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- u8 biaslevel;
+ if (need_swap)
+ el = swab16(ah->eeprom.def.baseEepHeader.length);
+ else
+ el = ah->eeprom.def.baseEepHeader.length;
- if (ah->ah_macVersion != AR_SREV_VERSION_9160)
- return;
+ if (el > sizeof(struct ar5416_eeprom_def))
+ el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
+ else
+ el = el / sizeof(u16);
- if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
- return;
+ eepdata = (u16 *)(&ah->eeprom);
- pModal = &eep->modalHeader;
+ for (i = 0; i < el; i++)
+ sum ^= *eepdata++;
- if (pModal->xpaBiasLvl != 0xff) {
- biaslevel = pModal->xpaBiasLvl;
- INI_RA(&ahp->ah_iniAddac, 7, 1) =
- (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
- }
-}
+ if (need_swap) {
+ u32 integer, j;
+ u16 word;
-static void (*ath9k_set_addac[]) (struct ath_hal *, struct ath9k_channel *) = {
- ath9k_hw_set_def_addac,
- ath9k_hw_set_4k_addac
-};
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "EEPROM Endianness is not native.. Changing \n");
-void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ word = swab16(eep->baseEepHeader.length);
+ eep->baseEepHeader.length = word;
+
+ word = swab16(eep->baseEepHeader.checksum);
+ eep->baseEepHeader.checksum = word;
- ath9k_set_addac[ahp->ah_eep_map](ah, chan);
+ word = swab16(eep->baseEepHeader.version);
+ eep->baseEepHeader.version = word;
+
+ word = swab16(eep->baseEepHeader.regDmn[0]);
+ eep->baseEepHeader.regDmn[0] = word;
+
+ word = swab16(eep->baseEepHeader.regDmn[1]);
+ eep->baseEepHeader.regDmn[1] = word;
+
+ word = swab16(eep->baseEepHeader.rfSilent);
+ eep->baseEepHeader.rfSilent = word;
+
+ word = swab16(eep->baseEepHeader.blueToothOptions);
+ eep->baseEepHeader.blueToothOptions = word;
+
+ word = swab16(eep->baseEepHeader.deviceCap);
+ eep->baseEepHeader.deviceCap = word;
+
+ for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
+ struct modal_eep_header *pModal =
+ &eep->modalHeader[j];
+ integer = swab32(pModal->antCtrlCommon);
+ pModal->antCtrlCommon = integer;
+
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ integer = swab32(pModal->antCtrlChain[i]);
+ pModal->antCtrlChain[i] = integer;
+ }
+
+ for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+ word = swab16(pModal->spurChans[i].spurChan);
+ pModal->spurChans[i].spurChan = word;
+ }
+ }
+ }
+
+ if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+ ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ sum, ah->eep_ops->get_eeprom_ver(ah));
+ return -EINVAL;
+ }
+
+ return 0;
}
+static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
+ enum eeprom_param param)
+{
+#define AR5416_VER_MASK (pBase->version & AR5416_EEP_VER_MINOR_MASK)
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ struct modal_eep_header *pModal = eep->modalHeader;
+ struct base_eep_header *pBase = &eep->baseEepHeader;
+ switch (param) {
+ case EEP_NFTHRESH_5:
+ return pModal[0].noiseFloorThreshCh[0];
+ case EEP_NFTHRESH_2:
+ return pModal[1].noiseFloorThreshCh[0];
+ case AR_EEPROM_MAC(0):
+ return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+ case AR_EEPROM_MAC(1):
+ return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+ case AR_EEPROM_MAC(2):
+ return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+ case EEP_REG_0:
+ return pBase->regDmn[0];
+ case EEP_REG_1:
+ return pBase->regDmn[1];
+ case EEP_OP_CAP:
+ return pBase->deviceCap;
+ case EEP_OP_MODE:
+ return pBase->opCapFlags;
+ case EEP_RF_SILENT:
+ return pBase->rfSilent;
+ case EEP_OB_5:
+ return pModal[0].ob;
+ case EEP_DB_5:
+ return pModal[0].db;
+ case EEP_OB_2:
+ return pModal[1].ob;
+ case EEP_DB_2:
+ return pModal[1].db;
+ case EEP_MINOR_REV:
+ return AR5416_VER_MASK;
+ case EEP_TX_MASK:
+ return pBase->txMask;
+ case EEP_RX_MASK:
+ return pBase->rxMask;
+ case EEP_RXGAIN_TYPE:
+ return pBase->rxGainType;
+ case EEP_TXGAIN_TYPE:
+ return pBase->txGainType;
+ case EEP_OL_PWRCTRL:
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ return pBase->openLoopPwrCntl ? true : false;
+ else
+ return false;
+ case EEP_RC_CHAIN_MASK:
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ return pBase->rcChainMask;
+ else
+ return 0;
+ case EEP_DAC_HPWR_5G:
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
+ return pBase->dacHiPwrMode_5G;
+ else
+ return 0;
+ case EEP_FRAC_N_5G:
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
+ return pBase->frac_n_5g;
+ else
+ return 0;
+ default:
+ return 0;
+ }
+#undef AR5416_VER_MASK
+}
/* XXX: Clean me up, make me more legible */
-static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
+#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
struct modal_eep_header *pModal;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
int i, regChainOffset;
u8 txRxAttenLocal;
- u16 ant_config;
pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
- ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
- REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+ REG_WRITE(ah, AR_PHY_SWITCH_COM,
+ ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (AR_SREV_9280(ah)) {
@@ -2141,8 +1707,8 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
break;
}
- if (AR_SREV_5416_V20_OR_LATER(ah) &&
- (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
+ if (AR_SREV_5416_20_OR_LATER(ah) &&
+ (ah->rxchainmask == 5 || ah->txchainmask == 5)
&& (i != 0))
regChainOffset = (i == 1) ? 0x2000 : 0x1000;
else
@@ -2162,10 +1728,8 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
SM(pModal->iqCalQCh[i],
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
- if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
- if ((eep->baseEepHeader.version &
- AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
+ if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
txRxAttenLocal = pModal->txRxAttenCh[i];
if (AR_SREV_9280_10_OR_LATER(ah)) {
REG_RMW_FIELD(ah,
@@ -2332,8 +1896,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
pModal->thresh62);
}
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
AR_PHY_TX_END_DATA_START,
pModal->txFrameToDataStart);
@@ -2341,296 +1904,883 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
pModal->txFrameToPaOn);
}
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
if (IS_CHAN_HT40(chan))
REG_RMW_FIELD(ah, AR_PHY_SETTLING,
AR_PHY_SETTLING_SWITCH,
pModal->swSettleHt40);
}
+ if (AR_SREV_9280_20_OR_LATER(ah) &&
+ AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
+ AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
+ pModal->miscBits);
+
+
+ if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
+ if (IS_CHAN_2GHZ(chan))
+ REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+ eep->baseEepHeader.dacLpMode);
+ else if (eep->baseEepHeader.dacHiPwrMode_5G)
+ REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
+ else
+ REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+ eep->baseEepHeader.dacLpMode);
+
+ REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
+ pModal->miscBits >> 2);
+
+ REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
+ AR_PHY_TX_DESIRED_SCALE_CCK,
+ eep->baseEepHeader.desiredScaleCCK);
+ }
+
return true;
+#undef AR5416_VER_MASK
}
-static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static void ath9k_hw_def_set_addac(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
- struct modal_eep_4k_header *pModal;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- int regChainOffset;
- u8 txRxAttenLocal;
- u16 ant_config = 0;
- u8 ob[5], db1[5], db2[5];
- u8 ant_div_control1, ant_div_control2;
- u32 regVal;
+#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+ struct modal_eep_header *pModal;
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ u8 biaslevel;
+ if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+ return;
- pModal = &eep->modalHeader;
+ if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+ return;
- txRxAttenLocal = 23;
+ pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
- ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
- REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+ if (pModal->xpaBiasLvl != 0xff) {
+ biaslevel = pModal->xpaBiasLvl;
+ } else {
+ u16 resetFreqBin, freqBin, freqCount = 0;
+ struct chan_centers centers;
- regChainOffset = 0;
- REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
- pModal->antCtrlChain[0]);
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
- REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
- (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
- ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
- AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
- SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
- SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+ resetFreqBin = FREQ2FBIN(centers.synth_center,
+ IS_CHAN_2GHZ(chan));
+ freqBin = XPA_LVL_FREQ(0) & 0xff;
+ biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
- txRxAttenLocal = pModal->txRxAttenCh[0];
- REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
- REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
- REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
- pModal->xatten2Margin[0]);
- REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
- }
+ freqCount++;
- REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
- AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
- REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
- AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+ while (freqCount < 3) {
+ if (XPA_LVL_FREQ(freqCount) == 0x0)
+ break;
- if (AR_SREV_9285_11(ah))
- REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+ freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+ if (resetFreqBin >= freqBin)
+ biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
+ else
+ break;
+ freqCount++;
+ }
+ }
- /* Initialize Ant Diversity settings from EEPROM */
- if (pModal->version == 3) {
- ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
- ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
- regVal = REG_READ(ah, 0x99ac);
- regVal &= (~(0x7f000000));
- regVal |= ((ant_div_control1 & 0x1) << 24);
- regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
- regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
- regVal |= ((ant_div_control2 & 0x3) << 25);
- regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
- REG_WRITE(ah, 0x99ac, regVal);
- regVal = REG_READ(ah, 0x99ac);
- regVal = REG_READ(ah, 0xa208);
- regVal &= (~(0x1 << 13));
- regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
- REG_WRITE(ah, 0xa208, regVal);
- regVal = REG_READ(ah, 0xa208);
+ if (IS_CHAN_2GHZ(chan)) {
+ INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
+ 7, 1) & (~0x18)) | biaslevel << 3;
+ } else {
+ INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
+ 6, 1) & (~0xc0)) | biaslevel << 6;
}
+#undef XPA_LVL_FREQ
+}
- if (pModal->version >= 2) {
- ob[0] = (pModal->ob_01 & 0xf);
- ob[1] = (pModal->ob_01 >> 4) & 0xf;
- ob[2] = (pModal->ob_234 & 0xf);
- ob[3] = ((pModal->ob_234 >> 4) & 0xf);
- ob[4] = ((pModal->ob_234 >> 8) & 0xf);
+static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct cal_data_per_freq *pRawDataSet,
+ u8 *bChans, u16 availPiers,
+ u16 tPdGainOverlap, int16_t *pMinCalPower,
+ u16 *pPdGainBoundaries, u8 *pPDADCValues,
+ u16 numXpdGains)
+{
+ int i, j, k;
+ int16_t ss;
+ u16 idxL = 0, idxR = 0, numPiers;
+ static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+ static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+ static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- db1[0] = (pModal->db1_01 & 0xf);
- db1[1] = ((pModal->db1_01 >> 4) & 0xf);
- db1[2] = (pModal->db1_234 & 0xf);
- db1[3] = ((pModal->db1_234 >> 4) & 0xf);
- db1[4] = ((pModal->db1_234 >> 8) & 0xf);
+ u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+ u8 minPwrT4[AR5416_NUM_PD_GAINS];
+ u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+ int16_t vpdStep;
+ int16_t tmpVal;
+ u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+ bool match;
+ int16_t minDelta = 0;
+ struct chan_centers centers;
- db2[0] = (pModal->db2_01 & 0xf);
- db2[1] = ((pModal->db2_01 >> 4) & 0xf);
- db2[2] = (pModal->db2_234 & 0xf);
- db2[3] = ((pModal->db2_234 >> 4) & 0xf);
- db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
- } else if (pModal->version == 1) {
+ for (numPiers = 0; numPiers < availPiers; numPiers++) {
+ if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+ break;
+ }
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "EEPROM Model version is set to 1 \n");
- ob[0] = (pModal->ob_01 & 0xf);
- ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
- db1[0] = (pModal->db1_01 & 0xf);
- db1[1] = db1[2] = db1[3] =
- db1[4] = ((pModal->db1_01 >> 4) & 0xf);
- db2[0] = (pModal->db2_01 & 0xf);
- db2[1] = db2[2] = db2[3] =
- db2[4] = ((pModal->db2_01 >> 4) & 0xf);
+ match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
+ IS_CHAN_2GHZ(chan)),
+ bChans, numPiers, &idxL, &idxR);
+
+ if (match) {
+ for (i = 0; i < numXpdGains; i++) {
+ minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+ maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pRawDataSet[idxL].pwrPdg[i],
+ pRawDataSet[idxL].vpdPdg[i],
+ AR5416_PD_GAIN_ICEPTS,
+ vpdTableI[i]);
+ }
} else {
- int i;
- for (i = 0; i < 5; i++) {
- ob[i] = pModal->ob_01;
- db1[i] = pModal->db1_01;
- db2[i] = pModal->db1_01;
+ for (i = 0; i < numXpdGains; i++) {
+ pVpdL = pRawDataSet[idxL].vpdPdg[i];
+ pPwrL = pRawDataSet[idxL].pwrPdg[i];
+ pVpdR = pRawDataSet[idxR].vpdPdg[i];
+ pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+ minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+ maxPwrT4[i] =
+ min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
+ pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
+
+
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pPwrL, pVpdL,
+ AR5416_PD_GAIN_ICEPTS,
+ vpdTableL[i]);
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pPwrR, pVpdR,
+ AR5416_PD_GAIN_ICEPTS,
+ vpdTableR[i]);
+
+ for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+ vpdTableI[i][j] =
+ (u8)(ath9k_hw_interpolate((u16)
+ FREQ2FBIN(centers.
+ synth_center,
+ IS_CHAN_2GHZ
+ (chan)),
+ bChans[idxL], bChans[idxR],
+ vpdTableL[i][j], vpdTableR[i][j]));
+ }
}
}
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
+ *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+ k = 0;
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
+ for (i = 0; i < numXpdGains; i++) {
+ if (i == (numXpdGains - 1))
+ pPdGainBoundaries[i] =
+ (u16)(maxPwrT4[i] / 2);
+ else
+ pPdGainBoundaries[i] =
+ (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+ pPdGainBoundaries[i] =
+ min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
- if (AR_SREV_9285_11(ah))
- REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+ if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+ minDelta = pPdGainBoundaries[0] - 23;
+ pPdGainBoundaries[0] = 23;
+ } else {
+ minDelta = 0;
+ }
- REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
- pModal->switchSettling);
- REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
- pModal->adcDesiredSize);
+ if (i == 0) {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ss = (int16_t)(0 - (minPwrT4[i] / 2));
+ else
+ ss = 0;
+ } else {
+ ss = (int16_t)((pPdGainBoundaries[i - 1] -
+ (minPwrT4[i] / 2)) -
+ tPdGainOverlap + 1 + minDelta);
+ }
+ vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+ vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
- REG_WRITE(ah, AR_PHY_RF_CTL4,
- SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
- SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
- SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
- SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+ while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+ pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+ ss++;
+ }
- REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
- pModal->txEndToRxOn);
- REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
- pModal->thresh62);
- REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
- pModal->thresh62);
+ sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+ tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+ (minPwrT4[i] / 2));
+ maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+ tgtIndex : sizeCurrVpdTable;
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
- REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
- pModal->txFrameToDataStart);
- REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
- pModal->txFrameToPaOn);
+ while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ pPDADCValues[k++] = vpdTableI[i][ss++];
+ }
+
+ vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+ vpdTableI[i][sizeCurrVpdTable - 2]);
+ vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+ if (tgtIndex > maxIndex) {
+ while ((ss <= tgtIndex) &&
+ (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+ (ss - maxIndex + 1) * vpdStep));
+ pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+ 255 : tmpVal);
+ ss++;
+ }
+ }
}
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
- if (IS_CHAN_HT40(chan))
- REG_RMW_FIELD(ah, AR_PHY_SETTLING,
- AR_PHY_SETTLING_SWITCH,
- pModal->swSettleHt40);
+ while (i < AR5416_PD_GAINS_IN_MASK) {
+ pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
+ i++;
}
- return true;
-}
+ while (k < AR5416_NUM_PDADC_VALUES) {
+ pPDADCValues[k] = pPDADCValues[k - 1];
+ k++;
+ }
-static bool (*ath9k_eeprom_set_board_values[])(struct ath_hal *,
- struct ath9k_channel *) = {
- ath9k_hw_eeprom_set_def_board_values,
- ath9k_hw_eeprom_set_4k_board_values
-};
+ return;
+}
-bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ int16_t *pTxPowerIndexOffset)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
+#define SM_PDGAIN_B(x, y) \
+ SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
+
+ struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+ struct cal_data_per_freq *pRawDataset;
+ u8 *pCalBChans = NULL;
+ u16 pdGainOverlap_t2;
+ static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+ u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+ u16 numPiers, i, j;
+ int16_t tMinCalPower;
+ u16 numXpdGain, xpdMask;
+ u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+ u32 reg32, regOffset, regChainOffset;
+ int16_t modalIdx;
+
+ modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+ xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
- return ath9k_eeprom_set_board_values[ahp->ah_eep_map](ah, chan);
+ if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ pdGainOverlap_t2 =
+ pEepData->modalHeader[modalIdx].pdGainOverlap;
+ } else {
+ pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+ }
+
+ if (IS_CHAN_2GHZ(chan)) {
+ pCalBChans = pEepData->calFreqPier2G;
+ numPiers = AR5416_NUM_2G_CAL_PIERS;
+ } else {
+ pCalBChans = pEepData->calFreqPier5G;
+ numPiers = AR5416_NUM_5G_CAL_PIERS;
+ }
+
+ if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
+ pRawDataset = pEepData->calPierData2G[0];
+ ah->initPDADC = ((struct calDataPerFreqOpLoop *)
+ pRawDataset)->vpdPdg[0][0];
+ }
+
+ numXpdGain = 0;
+
+ for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_NUM_PD_GAINS)
+ break;
+ xpdGainValues[numXpdGain] =
+ (u16)(AR5416_PD_GAINS_IN_MASK - i);
+ numXpdGain++;
+ }
+ }
+
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+ (numXpdGain - 1) & 0x3);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+ xpdGainValues[0]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+ xpdGainValues[1]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+ xpdGainValues[2]);
+
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ if (AR_SREV_5416_20_OR_LATER(ah) &&
+ (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+ (i != 0)) {
+ regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+ } else
+ regChainOffset = i * 0x1000;
+
+ if (pEepData->baseEepHeader.txMask & (1 << i)) {
+ if (IS_CHAN_2GHZ(chan))
+ pRawDataset = pEepData->calPierData2G[i];
+ else
+ pRawDataset = pEepData->calPierData5G[i];
+
+
+ if (OLC_FOR_AR9280_20_LATER) {
+ u8 pcdacIdx;
+ u8 txPower;
+
+ ath9k_get_txgain_index(ah, chan,
+ (struct calDataPerFreqOpLoop *)pRawDataset,
+ pCalBChans, numPiers, &txPower, &pcdacIdx);
+ ath9k_olc_get_pdadcs(ah, pcdacIdx,
+ txPower/2, pdadcValues);
+ } else {
+ ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
+ chan, pRawDataset,
+ pCalBChans, numPiers,
+ pdGainOverlap_t2,
+ &tMinCalPower,
+ gainBoundaries,
+ pdadcValues,
+ numXpdGain);
+ }
+
+ if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+ if (OLC_FOR_AR9280_20_LATER) {
+ REG_WRITE(ah,
+ AR_PHY_TPCRG5 + regChainOffset,
+ SM(0x6,
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+ SM_PD_GAIN(1) | SM_PD_GAIN(2) |
+ SM_PD_GAIN(3) | SM_PD_GAIN(4));
+ } else {
+ REG_WRITE(ah,
+ AR_PHY_TPCRG5 + regChainOffset,
+ SM(pdGainOverlap_t2,
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
+ SM_PDGAIN_B(0, 1) |
+ SM_PDGAIN_B(1, 2) |
+ SM_PDGAIN_B(2, 3) |
+ SM_PDGAIN_B(3, 4));
+ }
+ }
+
+ regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+ for (j = 0; j < 32; j++) {
+ reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+ ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+ ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+ ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+ REG_WRITE(ah, regOffset, reg32);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "PDADC (%d,%4x): %4.4x %8.8x\n",
+ i, regChainOffset, regOffset,
+ reg32);
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "PDADC: Chain %d | PDADC %3d "
+ "Value %3d | PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | PDADC %3d "
+ "Value %3d |\n",
+ i, 4 * j, pdadcValues[4 * j],
+ 4 * j + 1, pdadcValues[4 * j + 1],
+ 4 * j + 2, pdadcValues[4 * j + 2],
+ 4 * j + 3,
+ pdadcValues[4 * j + 3]);
+
+ regOffset += 4;
+ }
+ }
+ }
+
+ *pTxPowerIndexOffset = 0;
+
+ return true;
+#undef SM_PD_GAIN
+#undef SM_PDGAIN_B
}
-static int ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u8 index, u16 *config)
+static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ int16_t *ratesArray,
+ u16 cfgCtl,
+ u16 AntennaReduction,
+ u16 twiceMaxRegulatoryPower,
+ u16 powerLimit)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
- struct modal_eep_header *pModal =
- &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
- struct base_eep_header *pBase = &eep->baseEepHeader;
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
- switch (index) {
- case 0:
- *config = pModal->antCtrlCommon & 0xFFFF;
- return 0;
+ struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+ u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ static const u16 tpScaleReductionTable[5] =
+ { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+ int i;
+ int16_t twiceLargestAntenna;
+ struct cal_ctl_data *rep;
+ struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+ 0, { 0, 0, 0, 0}
+ };
+ struct cal_target_power_leg targetPowerOfdmExt = {
+ 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+ 0, { 0, 0, 0, 0 }
+ };
+ struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+ 0, {0, 0, 0, 0}
+ };
+ u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+ u16 ctlModesFor11a[] =
+ { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
+ u16 ctlModesFor11g[] =
+ { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+ CTL_2GHT40
+ };
+ u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ struct chan_centers centers;
+ int tx_chainmask;
+ u16 twiceMinEdgePower;
+
+ tx_chainmask = ah->txchainmask;
+
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+ twiceLargestAntenna = max(
+ pEepData->modalHeader
+ [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+ pEepData->modalHeader
+ [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+
+ twiceLargestAntenna = max((u8)twiceLargestAntenna,
+ pEepData->modalHeader
+ [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+ twiceLargestAntenna = (int16_t)min(AntennaReduction -
+ twiceLargestAntenna, 0);
+
+ maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+ if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
+ maxRegAllowedPower -=
+ (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
+ }
+
+ scaledPower = min(powerLimit, maxRegAllowedPower);
+
+ switch (ar5416_get_ntxchains(tx_chainmask)) {
case 1:
- if (pBase->version >= 0x0E0D) {
- if (pModal->useAnt1) {
- *config =
- ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
- return 0;
- }
- }
break;
- default:
+ case 2:
+ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
break;
+ case 3:
+ scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+ break;
+ }
+
+ scaledPower = max((u16)0, scaledPower);
+
+ if (IS_CHAN_2GHZ(chan)) {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
+ SUB_NUM_CTL_MODES_AT_2G_40;
+ pCtlMode = ctlModesFor11g;
+
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPowerCck,
+ AR5416_NUM_2G_CCK_TARGET_POWERS,
+ &targetPowerCck, 4, false);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower2G,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerOfdm, 4, false);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower2GHT20,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerHt20, 8, false);
+
+ if (IS_CHAN_HT40(chan)) {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower2GHT40,
+ AR5416_NUM_2G_40_TARGET_POWERS,
+ &targetPowerHt40, 8, true);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPowerCck,
+ AR5416_NUM_2G_CCK_TARGET_POWERS,
+ &targetPowerCckExt, 4, true);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower2G,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerOfdmExt, 4, true);
+ }
+ } else {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+ SUB_NUM_CTL_MODES_AT_5G_40;
+ pCtlMode = ctlModesFor11a;
+
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower5G,
+ AR5416_NUM_5G_20_TARGET_POWERS,
+ &targetPowerOfdm, 4, false);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower5GHT20,
+ AR5416_NUM_5G_20_TARGET_POWERS,
+ &targetPowerHt20, 8, false);
+
+ if (IS_CHAN_HT40(chan)) {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower5GHT40,
+ AR5416_NUM_5G_40_TARGET_POWERS,
+ &targetPowerHt40, 8, true);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower5G,
+ AR5416_NUM_5G_20_TARGET_POWERS,
+ &targetPowerOfdmExt, 4, true);
+ }
+ }
+
+ for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+ bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+ (pCtlMode[ctlMode] == CTL_2GHT40);
+ if (isHt40CtlMode)
+ freq = centers.synth_center;
+ else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+ freq = centers.ext_center;
+ else
+ freq = centers.ctl_center;
+
+ if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+ ah->eep_ops->get_eeprom_rev(ah) <= 2)
+ twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+ "EXT_ADDITIVE %d\n",
+ ctlMode, numCtlModes, isHt40CtlMode,
+ (pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+ for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+ "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+ "chan %d\n",
+ i, cfgCtl, pCtlMode[ctlMode],
+ pEepData->ctlIndex[i], chan->channel);
+
+ if ((((cfgCtl & ~CTL_MODE_M) |
+ (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ pEepData->ctlIndex[i]) ||
+ (((cfgCtl & ~CTL_MODE_M) |
+ (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+ rep = &(pEepData->ctlData[i]);
+
+ twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
+ rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
+ IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " MATCH-EE_IDX %d: ch %d is2 %d "
+ "2xMinEdge %d chainmask %d chains %d\n",
+ i, freq, IS_CHAN_2GHZ(chan),
+ twiceMinEdgePower, tx_chainmask,
+ ar5416_get_ntxchains
+ (tx_chainmask));
+ if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+ twiceMaxEdgePower = min(twiceMaxEdgePower,
+ twiceMinEdgePower);
+ } else {
+ twiceMaxEdgePower = twiceMinEdgePower;
+ break;
+ }
+ }
+ }
+
+ minCtlPower = min(twiceMaxEdgePower, scaledPower);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " SEL-Min ctlMode %d pCtlMode %d "
+ "2xMaxEdge %d sP %d minCtlPwr %d\n",
+ ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+ scaledPower, minCtlPower);
+
+ switch (pCtlMode[ctlMode]) {
+ case CTL_11B:
+ for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+ targetPowerCck.tPow2x[i] =
+ min((u16)targetPowerCck.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_11A:
+ case CTL_11G:
+ for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+ targetPowerOfdm.tPow2x[i] =
+ min((u16)targetPowerOfdm.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_5GHT20:
+ case CTL_2GHT20:
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+ targetPowerHt20.tPow2x[i] =
+ min((u16)targetPowerHt20.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_11B_EXT:
+ targetPowerCckExt.tPow2x[0] = min((u16)
+ targetPowerCckExt.tPow2x[0],
+ minCtlPower);
+ break;
+ case CTL_11A_EXT:
+ case CTL_11G_EXT:
+ targetPowerOfdmExt.tPow2x[0] = min((u16)
+ targetPowerOfdmExt.tPow2x[0],
+ minCtlPower);
+ break;
+ case CTL_5GHT40:
+ case CTL_2GHT40:
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+ targetPowerHt40.tPow2x[i] =
+ min((u16)targetPowerHt40.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ default:
+ break;
+ }
}
- return -EINVAL;
+ ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+ ratesArray[rate18mb] = ratesArray[rate24mb] =
+ targetPowerOfdm.tPow2x[0];
+ ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+ ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+ ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+ ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+ ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+ if (IS_CHAN_2GHZ(chan)) {
+ ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+ ratesArray[rate2s] = ratesArray[rate2l] =
+ targetPowerCck.tPow2x[1];
+ ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+ targetPowerCck.tPow2x[2];
+ ;
+ ratesArray[rate11s] = ratesArray[rate11l] =
+ targetPowerCck.tPow2x[3];
+ ;
+ }
+ if (IS_CHAN_HT40(chan)) {
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+ ratesArray[rateHt40_0 + i] =
+ targetPowerHt40.tPow2x[i];
+ }
+ ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+ ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+ ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+ if (IS_CHAN_2GHZ(chan)) {
+ ratesArray[rateExtCck] =
+ targetPowerCckExt.tPow2x[0];
+ }
+ }
+ return true;
}
-static int ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah,
+static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan,
- u8 index, u16 *config)
+ u16 cfgCtl,
+ u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower,
+ u8 powerLimit)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- struct modal_eep_4k_header *pModal = &eep->modalHeader;
+#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
+ struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+ struct modal_eep_header *pModal =
+ &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+ int16_t ratesArray[Ar5416RateSize];
+ int16_t txPowerIndexOffset = 0;
+ u8 ht40PowerIncForPdadc = 2;
+ int i, cck_ofdm_delta = 0;
- switch (index) {
- case 0:
- *config = pModal->antCtrlCommon & 0xFFFF;
- return 0;
- default:
- break;
+ memset(ratesArray, 0, sizeof(ratesArray));
+
+ if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
- return -EINVAL;
-}
+ if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+ &ratesArray[0], cfgCtl,
+ twiceAntennaReduction,
+ twiceMaxRegulatoryPower,
+ powerLimit)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "ath9k_hw_set_txpower: unable to set "
+ "tx power per rate table\n");
+ return -EIO;
+ }
-static int (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hal *,
- struct ath9k_channel *,
- u8, u16 *) = {
- ath9k_hw_get_def_eeprom_antenna_cfg,
- ath9k_hw_get_4k_eeprom_antenna_cfg
-};
+ 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;
+ }
-int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u8 index, u16 *config)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+ ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+ if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+ ratesArray[i] = AR5416_MAX_RATE_POWER;
+ }
- return ath9k_get_eeprom_antenna_cfg[ahp->ah_eep_map](ah, chan,
- index, config);
-}
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ for (i = 0; i < Ar5416RateSize; i++)
+ ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+ }
-static u8 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah,
- enum ieee80211_band freq_band)
-{
- return 1;
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+ ATH9K_POW_SM(ratesArray[rate18mb], 24)
+ | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+ | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+ | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+ ATH9K_POW_SM(ratesArray[rate54mb], 24)
+ | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+ | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+ | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+ if (IS_CHAN_2GHZ(chan)) {
+ if (OLC_FOR_AR9280_20_LATER) {
+ cck_ofdm_delta = 2;
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+ ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
+ | ATH9K_POW_SM(ratesArray[rateXr], 8)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+ ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
+ } else {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+ ATH9K_POW_SM(ratesArray[rate2s], 24)
+ | ATH9K_POW_SM(ratesArray[rate2l], 16)
+ | ATH9K_POW_SM(ratesArray[rateXr], 8)
+ | ATH9K_POW_SM(ratesArray[rate1l], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+ ATH9K_POW_SM(ratesArray[rate11s], 24)
+ | ATH9K_POW_SM(ratesArray[rate11l], 16)
+ | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+ | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+ }
+ }
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+ ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+ | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+ | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+ | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+ ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+ | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+ | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+ | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+ if (IS_CHAN_HT40(chan)) {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+ ATH9K_POW_SM(ratesArray[rateHt40_3] +
+ ht40PowerIncForPdadc, 24)
+ | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+ ht40PowerIncForPdadc, 16)
+ | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+ ht40PowerIncForPdadc, 8)
+ | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+ ht40PowerIncForPdadc, 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+ ATH9K_POW_SM(ratesArray[rateHt40_7] +
+ ht40PowerIncForPdadc, 24)
+ | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+ ht40PowerIncForPdadc, 16)
+ | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+ ht40PowerIncForPdadc, 8)
+ | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+ ht40PowerIncForPdadc, 0));
+ if (OLC_FOR_AR9280_20_LATER) {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+ ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+ | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
+ | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+ | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
+ } else {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+ ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+ | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+ | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+ | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+ }
+ }
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+ ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
+ | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+ i = rate6mb;
+
+ if (IS_CHAN_HT40(chan))
+ i = rateHt40_0;
+ else if (IS_CHAN_HT20(chan))
+ i = rateHt20_0;
+
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ah->regulatory.max_power_level =
+ ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+ else
+ ah->regulatory.max_power_level = ratesArray[i];
+
+ switch(ar5416_get_ntxchains(ah->txchainmask)) {
+ case 1:
+ break;
+ case 2:
+ ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+ break;
+ case 3:
+ ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+ break;
+ default:
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Invalid chainmask configuration\n");
+ break;
+ }
+
+ return 0;
}
-static u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
+static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
enum ieee80211_band freq_band)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
struct modal_eep_header *pModal =
&(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
struct base_eep_header *pBase = &eep->baseEepHeader;
@@ -2645,180 +2795,75 @@ static u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
return num_ant_config;
}
-static u8 (*ath9k_get_num_ant_config[])(struct ath_hal *,
- enum ieee80211_band) = {
- ath9k_hw_get_def_num_ant_config,
- ath9k_hw_get_4k_num_ant_config
-};
-
-u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
- enum ieee80211_band freq_band)
+static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ struct modal_eep_header *pModal =
+ &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
- return ath9k_get_num_ant_config[ahp->ah_eep_map](ah, freq_band);
+ return pModal->antCtrlCommon & 0xFFFF;
}
-u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz)
+static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
{
-#define EEP_MAP4K_SPURCHAN \
- (ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
#define EEP_DEF_SPURCHAN \
- (ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
- struct ath_hal_5416 *ahp = AH5416(ah);
+ (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+
u16 spur_val = AR_NO_SPUR;
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Getting spur idx %d is2Ghz. %d val %x\n",
- i, is2GHz, ah->ah_config.spurchans[i][is2GHz]);
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
- switch (ah->ah_config.spurmode) {
+ switch (ah->config.spurmode) {
case SPUR_DISABLE:
break;
case SPUR_ENABLE_IOCTL:
- spur_val = ah->ah_config.spurchans[i][is2GHz];
+ spur_val = ah->config.spurchans[i][is2GHz];
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
- if (ahp->ah_eep_map == EEP_MAP_4KBITS)
- spur_val = EEP_MAP4K_SPURCHAN;
- else
- spur_val = EEP_DEF_SPURCHAN;
+ spur_val = EEP_DEF_SPURCHAN;
break;
-
}
return spur_val;
-#undef EEP_DEF_SPURCHAN
-#undef EEP_MAP4K_SPURCHAN
-}
-
-static u32 ath9k_hw_get_eeprom_4k(struct ath_hal *ah,
- enum eeprom_param param)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- struct modal_eep_4k_header *pModal = &eep->modalHeader;
- struct base_eep_header_4k *pBase = &eep->baseEepHeader;
- switch (param) {
- case EEP_NFTHRESH_2:
- return pModal[1].noiseFloorThreshCh[0];
- case AR_EEPROM_MAC(0):
- return pBase->macAddr[0] << 8 | pBase->macAddr[1];
- case AR_EEPROM_MAC(1):
- return pBase->macAddr[2] << 8 | pBase->macAddr[3];
- case AR_EEPROM_MAC(2):
- return pBase->macAddr[4] << 8 | pBase->macAddr[5];
- case EEP_REG_0:
- return pBase->regDmn[0];
- case EEP_REG_1:
- return pBase->regDmn[1];
- case EEP_OP_CAP:
- return pBase->deviceCap;
- case EEP_OP_MODE:
- return pBase->opCapFlags;
- case EEP_RF_SILENT:
- return pBase->rfSilent;
- case EEP_OB_2:
- return pModal->ob_01;
- case EEP_DB_2:
- return pModal->db1_01;
- case EEP_MINOR_REV:
- return pBase->version & AR5416_EEP_VER_MINOR_MASK;
- case EEP_TX_MASK:
- return pBase->txMask;
- case EEP_RX_MASK:
- return pBase->rxMask;
- default:
- return 0;
- }
-}
-
-static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah,
- enum eeprom_param param)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
- struct modal_eep_header *pModal = eep->modalHeader;
- struct base_eep_header *pBase = &eep->baseEepHeader;
-
- switch (param) {
- case EEP_NFTHRESH_5:
- return pModal[0].noiseFloorThreshCh[0];
- case EEP_NFTHRESH_2:
- return pModal[1].noiseFloorThreshCh[0];
- case AR_EEPROM_MAC(0):
- return pBase->macAddr[0] << 8 | pBase->macAddr[1];
- case AR_EEPROM_MAC(1):
- return pBase->macAddr[2] << 8 | pBase->macAddr[3];
- case AR_EEPROM_MAC(2):
- return pBase->macAddr[4] << 8 | pBase->macAddr[5];
- case EEP_REG_0:
- return pBase->regDmn[0];
- case EEP_REG_1:
- return pBase->regDmn[1];
- case EEP_OP_CAP:
- return pBase->deviceCap;
- case EEP_OP_MODE:
- return pBase->opCapFlags;
- case EEP_RF_SILENT:
- return pBase->rfSilent;
- case EEP_OB_5:
- return pModal[0].ob;
- case EEP_DB_5:
- return pModal[0].db;
- case EEP_OB_2:
- return pModal[1].ob;
- case EEP_DB_2:
- return pModal[1].db;
- case EEP_MINOR_REV:
- return pBase->version & AR5416_EEP_VER_MINOR_MASK;
- case EEP_TX_MASK:
- return pBase->txMask;
- case EEP_RX_MASK:
- return pBase->rxMask;
- case EEP_RXGAIN_TYPE:
- return pBase->rxGainType;
- case EEP_TXGAIN_TYPE:
- return pBase->txGainType;
-
- default:
- return 0;
- }
+#undef EEP_DEF_SPURCHAN
}
-static u32 (*ath9k_get_eeprom[])(struct ath_hal *, enum eeprom_param) = {
- ath9k_hw_get_eeprom_def,
- ath9k_hw_get_eeprom_4k
+static struct eeprom_ops eep_def_ops = {
+ .check_eeprom = ath9k_hw_def_check_eeprom,
+ .get_eeprom = ath9k_hw_def_get_eeprom,
+ .fill_eeprom = ath9k_hw_def_fill_eeprom,
+ .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
+ .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
+ .get_num_ant_config = ath9k_hw_def_get_num_ant_config,
+ .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
+ .set_board_values = ath9k_hw_def_set_board_values,
+ .set_addac = ath9k_hw_def_set_addac,
+ .set_txpower = ath9k_hw_def_set_txpower,
+ .get_spur_channel = ath9k_hw_def_get_spur_channel
};
-u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
- enum eeprom_param param)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- return ath9k_get_eeprom[ahp->ah_eep_map](ah, param);
-}
-
-int ath9k_hw_eeprom_attach(struct ath_hal *ah)
+int ath9k_hw_eeprom_attach(struct ath_hw *ah)
{
int status;
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (ath9k_hw_use_flash(ah))
- ath9k_hw_flash_map(ah);
- if (AR_SREV_9285(ah))
- ahp->ah_eep_map = EEP_MAP_4KBITS;
- else
- ahp->ah_eep_map = EEP_MAP_DEFAULT;
+ if (AR_SREV_9285(ah)) {
+ ah->eep_map = EEP_MAP_4KBITS;
+ ah->eep_ops = &eep_4k_ops;
+ } else {
+ ah->eep_map = EEP_MAP_DEFAULT;
+ ah->eep_ops = &eep_def_ops;
+ }
- if (!ath9k_hw_fill_eeprom(ah))
+ if (!ah->eep_ops->fill_eeprom(ah))
return -EIO;
- status = ath9k_hw_check_eeprom(ah);
+ status = ah->eep_ops->check_eeprom(ah);
return status;
}
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath9k/eeprom.h
new file mode 100644
index 00000000000..d6f6108f63c
--- /dev/null
+++ b/drivers/net/wireless/ath9k/eeprom.h
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef EEPROM_H
+#define EEPROM_H
+
+#define AH_USE_EEPROM 0x1
+
+#ifdef __BIG_ENDIAN
+#define AR5416_EEPROM_MAGIC 0x5aa5
+#else
+#define AR5416_EEPROM_MAGIC 0xa55a
+#endif
+
+#define CTRY_DEBUG 0x1ff
+#define CTRY_DEFAULT 0
+
+#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
+#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
+#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004
+#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
+#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
+#define AR_EEPROM_EEPCAP_MAXQCU_S 4
+#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
+#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
+#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
+
+#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080
+#define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100
+#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800
+
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
+
+#define AR5416_EEPROM_MAGIC_OFFSET 0x0
+#define AR5416_EEPROM_S 2
+#define AR5416_EEPROM_OFFSET 0x2000
+#define AR5416_EEPROM_MAX 0xae0
+
+#define AR5416_EEPROM_START_ADDR \
+ (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
+
+#define SD_NO_CTL 0xE0
+#define NO_CTL 0xff
+#define CTL_MODE_M 7
+#define CTL_11A 0
+#define CTL_11B 1
+#define CTL_11G 2
+#define CTL_2GHT20 5
+#define CTL_5GHT20 6
+#define CTL_2GHT40 7
+#define CTL_5GHT40 8
+
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+
+#define SUB_NUM_CTL_MODES_AT_5G_40 2
+#define SUB_NUM_CTL_MODES_AT_2G_40 3
+
+#define INCREASE_MAXPOW_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
+#define INCREASE_MAXPOW_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
+
+/*
+ * For AR9285 and later chipsets, the following bits are not being programmed
+ * in EEPROM and so need to be enabled always.
+ *
+ * Bit 0: en_fcc_mid
+ * Bit 1: en_jap_mid
+ * Bit 2: en_fcc_dfs_ht40
+ * Bit 3: en_jap_ht40
+ * Bit 4: en_jap_dfs_ht40
+ */
+#define AR9285_RDEXT_DEFAULT 0x1F
+
+#define AR_EEPROM_MAC(i) (0x1d+(i))
+#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
+#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
+#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM))
+
+#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
+ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+
+#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
+#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
+#define AR_EEPROM_RFSILENT_POLARITY 0x0002
+#define AR_EEPROM_RFSILENT_POLARITY_S 1
+
+#define EEP_RFSILENT_ENABLED 0x0001
+#define EEP_RFSILENT_ENABLED_S 0
+#define EEP_RFSILENT_POLARITY 0x0002
+#define EEP_RFSILENT_POLARITY_S 1
+#define EEP_RFSILENT_GPIO_SEL 0x001c
+#define EEP_RFSILENT_GPIO_SEL_S 2
+
+#define AR5416_OPFLAGS_11A 0x01
+#define AR5416_OPFLAGS_11G 0x02
+#define AR5416_OPFLAGS_N_5G_HT40 0x04
+#define AR5416_OPFLAGS_N_2G_HT40 0x08
+#define AR5416_OPFLAGS_N_5G_HT20 0x10
+#define AR5416_OPFLAGS_N_2G_HT20 0x20
+
+#define AR5416_EEP_NO_BACK_VER 0x1
+#define AR5416_EEP_VER 0xE
+#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
+#define AR5416_EEP_MINOR_VER_2 0x2
+#define AR5416_EEP_MINOR_VER_3 0x3
+#define AR5416_EEP_MINOR_VER_7 0x7
+#define AR5416_EEP_MINOR_VER_9 0x9
+#define AR5416_EEP_MINOR_VER_16 0x10
+#define AR5416_EEP_MINOR_VER_17 0x11
+#define AR5416_EEP_MINOR_VER_19 0x13
+#define AR5416_EEP_MINOR_VER_20 0x14
+#define AR5416_EEP_MINOR_VER_22 0x16
+
+#define AR5416_NUM_5G_CAL_PIERS 8
+#define AR5416_NUM_2G_CAL_PIERS 4
+#define AR5416_NUM_5G_20_TARGET_POWERS 8
+#define AR5416_NUM_5G_40_TARGET_POWERS 8
+#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_NUM_2G_20_TARGET_POWERS 4
+#define AR5416_NUM_2G_40_TARGET_POWERS 4
+#define AR5416_NUM_CTLS 24
+#define AR5416_NUM_BAND_EDGES 8
+#define AR5416_NUM_PD_GAINS 4
+#define AR5416_PD_GAINS_IN_MASK 4
+#define AR5416_PD_GAIN_ICEPTS 5
+#define AR5416_EEPROM_MODAL_SPURS 5
+#define AR5416_MAX_RATE_POWER 63
+#define AR5416_NUM_PDADC_VALUES 128
+#define AR5416_BCHAN_UNUSED 0xFF
+#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
+#define AR5416_MAX_CHAINS 3
+#define AR5416_PWR_TABLE_OFFSET -5
+
+/* Rx gain type values */
+#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0
+#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1
+#define AR5416_EEP_RXGAIN_ORIG 2
+
+/* Tx gain type values */
+#define AR5416_EEP_TXGAIN_ORIGINAL 0
+#define AR5416_EEP_TXGAIN_HIGH_POWER 1
+
+#define AR5416_EEP4K_START_LOC 64
+#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
+#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_CTLS 12
+#define AR5416_EEP4K_NUM_BAND_EDGES 4
+#define AR5416_EEP4K_NUM_PD_GAINS 2
+#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
+#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
+#define AR5416_EEP4K_MAX_CHAINS 1
+
+#define AR9280_TX_GAIN_TABLE_SIZE 22
+
+enum eeprom_param {
+ EEP_NFTHRESH_5,
+ EEP_NFTHRESH_2,
+ EEP_MAC_MSW,
+ EEP_MAC_MID,
+ EEP_MAC_LSW,
+ EEP_REG_0,
+ EEP_REG_1,
+ EEP_OP_CAP,
+ EEP_OP_MODE,
+ EEP_RF_SILENT,
+ EEP_OB_5,
+ EEP_DB_5,
+ EEP_OB_2,
+ EEP_DB_2,
+ EEP_MINOR_REV,
+ EEP_TX_MASK,
+ EEP_RX_MASK,
+ EEP_RXGAIN_TYPE,
+ EEP_TXGAIN_TYPE,
+ EEP_OL_PWRCTRL,
+ EEP_RC_CHAIN_MASK,
+ EEP_DAC_HPWR_5G,
+ EEP_FRAC_N_5G
+};
+
+enum ar5416_rates {
+ rate6mb, rate9mb, rate12mb, rate18mb,
+ rate24mb, rate36mb, rate48mb, rate54mb,
+ rate1l, rate2l, rate2s, rate5_5l,
+ rate5_5s, rate11l, rate11s, rateXr,
+ rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
+ rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
+ rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
+ rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
+ rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
+ Ar5416RateSize
+};
+
+enum ath9k_hal_freq_band {
+ ATH9K_HAL_FREQ_BAND_5GHZ = 0,
+ ATH9K_HAL_FREQ_BAND_2GHZ = 1
+};
+
+struct base_eep_header {
+ u16 length;
+ u16 checksum;
+ u16 version;
+ u8 opCapFlags;
+ u8 eepMisc;
+ u16 regDmn[2];
+ u8 macAddr[6];
+ u8 rxMask;
+ u8 txMask;
+ u16 rfSilent;
+ u16 blueToothOptions;
+ u16 deviceCap;
+ u32 binBuildNumber;
+ u8 deviceType;
+ u8 pwdclkind;
+ u8 futureBase_1[2];
+ u8 rxGainType;
+ u8 dacHiPwrMode_5G;
+ u8 openLoopPwrCntl;
+ u8 dacLpMode;
+ u8 txGainType;
+ u8 rcChainMask;
+ u8 desiredScaleCCK;
+ u8 power_table_offset;
+ u8 frac_n_5g;
+ u8 futureBase_3[21];
+} __packed;
+
+struct base_eep_header_4k {
+ u16 length;
+ u16 checksum;
+ u16 version;
+ u8 opCapFlags;
+ u8 eepMisc;
+ u16 regDmn[2];
+ u8 macAddr[6];
+ u8 rxMask;
+ u8 txMask;
+ u16 rfSilent;
+ u16 blueToothOptions;
+ u16 deviceCap;
+ u32 binBuildNumber;
+ u8 deviceType;
+ u8 txGainType;
+} __packed;
+
+
+struct spur_chan {
+ u16 spurChan;
+ u8 spurRangeLow;
+ u8 spurRangeHigh;
+} __packed;
+
+struct modal_eep_header {
+ u32 antCtrlChain[AR5416_MAX_CHAINS];
+ u32 antCtrlCommon;
+ u8 antennaGainCh[AR5416_MAX_CHAINS];
+ u8 switchSettling;
+ u8 txRxAttenCh[AR5416_MAX_CHAINS];
+ u8 rxTxMarginCh[AR5416_MAX_CHAINS];
+ u8 adcDesiredSize;
+ u8 pgaDesiredSize;
+ u8 xlnaGainCh[AR5416_MAX_CHAINS];
+ u8 txEndToXpaOff;
+ u8 txEndToRxOn;
+ u8 txFrameToXpaOn;
+ u8 thresh62;
+ u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
+ u8 xpdGain;
+ u8 xpd;
+ u8 iqCalICh[AR5416_MAX_CHAINS];
+ u8 iqCalQCh[AR5416_MAX_CHAINS];
+ u8 pdGainOverlap;
+ u8 ob;
+ u8 db;
+ u8 xpaBiasLvl;
+ u8 pwrDecreaseFor2Chain;
+ u8 pwrDecreaseFor3Chain;
+ u8 txFrameToDataStart;
+ u8 txFrameToPaOn;
+ u8 ht40PowerIncForPdadc;
+ u8 bswAtten[AR5416_MAX_CHAINS];
+ u8 bswMargin[AR5416_MAX_CHAINS];
+ u8 swSettleHt40;
+ u8 xatten2Db[AR5416_MAX_CHAINS];
+ u8 xatten2Margin[AR5416_MAX_CHAINS];
+ u8 ob_ch1;
+ u8 db_ch1;
+ u8 useAnt1:1,
+ force_xpaon:1,
+ local_bias:1,
+ femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+ u8 miscBits;
+ u16 xpaBiasLvlFreq[3];
+ u8 futureModal[6];
+
+ struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+struct calDataPerFreqOpLoop {
+ u8 pwrPdg[2][5];
+ u8 vpdPdg[2][5];
+ u8 pcdac[2][5];
+ u8 empty[2][5];
+} __packed;
+
+struct modal_eep_4k_header {
+ u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+ u32 antCtrlCommon;
+ u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 switchSettling;
+ u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 adcDesiredSize;
+ u8 pgaDesiredSize;
+ u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 txEndToXpaOff;
+ u8 txEndToRxOn;
+ u8 txFrameToXpaOn;
+ u8 thresh62;
+ u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 xpdGain;
+ u8 xpd;
+ u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+ u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 pdGainOverlap;
+ u8 ob_01;
+ u8 db1_01;
+ u8 xpaBiasLvl;
+ u8 txFrameToDataStart;
+ u8 txFrameToPaOn;
+ u8 ht40PowerIncForPdadc;
+ u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
+ u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
+ u8 swSettleHt40;
+ u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+ u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+ u8 db2_01;
+ u8 version;
+ u16 ob_234;
+ u16 db1_234;
+ u16 db2_234;
+ u8 futureModal[4];
+
+ struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+
+struct cal_data_per_freq {
+ u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+ u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_data_per_freq_4k {
+ u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+ u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_target_power_leg {
+ u8 bChannel;
+ u8 tPow2x[4];
+} __packed;
+
+struct cal_target_power_ht {
+ u8 bChannel;
+ u8 tPow2x[8];
+} __packed;
+
+
+#ifdef __BIG_ENDIAN_BITFIELD
+struct cal_ctl_edges {
+ u8 bChannel;
+ u8 flag:2, tPower:6;
+} __packed;
+#else
+struct cal_ctl_edges {
+ u8 bChannel;
+ u8 tPower:6, flag:2;
+} __packed;
+#endif
+
+struct cal_ctl_data {
+ struct cal_ctl_edges
+ ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+struct cal_ctl_data_4k {
+ struct cal_ctl_edges
+ ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
+} __packed;
+
+struct ar5416_eeprom_def {
+ struct base_eep_header baseEepHeader;
+ u8 custData[64];
+ struct modal_eep_header modalHeader[2];
+ u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
+ u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
+ struct cal_data_per_freq
+ calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
+ struct cal_data_per_freq
+ calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+ struct cal_target_power_leg
+ calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
+ struct cal_target_power_leg
+ calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
+ struct cal_target_power_leg
+ calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
+ u8 ctlIndex[AR5416_NUM_CTLS];
+ struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
+ u8 padding;
+} __packed;
+
+struct ar5416_eeprom_4k {
+ struct base_eep_header_4k baseEepHeader;
+ u8 custData[20];
+ struct modal_eep_4k_header modalHeader;
+ u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
+ struct cal_data_per_freq_4k
+ calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
+ struct cal_target_power_leg
+ calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
+ struct cal_target_power_leg
+ calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
+ u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
+ struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
+ u8 padding;
+} __packed;
+
+enum reg_ext_bitmap {
+ REG_EXT_JAPAN_MIDBAND = 1,
+ REG_EXT_FCC_DFS_HT40 = 2,
+ REG_EXT_JAPAN_NONDFS_HT40 = 3,
+ REG_EXT_JAPAN_DFS_HT40 = 4
+};
+
+struct ath9k_country_entry {
+ u16 countryCode;
+ u16 regDmnEnum;
+ u16 regDmn5G;
+ u16 regDmn2G;
+ u8 isMultidomain;
+ u8 iso[3];
+};
+
+enum ath9k_eep_map {
+ EEP_MAP_DEFAULT = 0x0,
+ EEP_MAP_4KBITS,
+ EEP_MAP_MAX
+};
+
+struct eeprom_ops {
+ int (*check_eeprom)(struct ath_hw *hw);
+ u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
+ bool (*fill_eeprom)(struct ath_hw *hw);
+ int (*get_eeprom_ver)(struct ath_hw *hw);
+ int (*get_eeprom_rev)(struct ath_hw *hw);
+ u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
+ u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
+ struct ath9k_channel *chan);
+ bool (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
+ void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
+ int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+ u16 cfgCtl, u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower, u8 powerLimit);
+ u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
+};
+
+#define ar5416_get_ntxchains(_txchainmask) \
+ (((_txchainmask >> 2) & 1) + \
+ ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+
+int ath9k_hw_eeprom_attach(struct ath_hw *ah);
+
+#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 34474edefc9..d494e98ba97 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -17,88 +17,80 @@
#include <linux/io.h>
#include <asm/unaligned.h>
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
#include "initvals.h"
-static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
+static int btcoex_enable;
+module_param(btcoex_enable, bool, 0);
+MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
-extern struct hal_percal_data iq_cal_multi_sample;
-extern struct hal_percal_data iq_cal_single_sample;
-extern struct hal_percal_data adc_gain_cal_multi_sample;
-extern struct hal_percal_data adc_gain_cal_single_sample;
-extern struct hal_percal_data adc_dc_cal_multi_sample;
-extern struct hal_percal_data adc_dc_cal_single_sample;
-extern struct hal_percal_data adc_init_dc_cal;
+#define ATH9K_CLOCK_RATE_CCK 22
+#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
+#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
-static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode);
-static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value);
-static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
-static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
/********************/
/* Helper Functions */
/********************/
-static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
+static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
{
- if (ah->ah_curchan != NULL)
- return clks / CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
- else
- return clks / CLOCK_RATE[ATH9K_MODE_11B];
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+ if (!ah->curchan) /* should really check for CCK instead */
+ return clks / ATH9K_CLOCK_RATE_CCK;
+ if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
+
+ return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
}
-static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
+static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
{
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
- if (chan && IS_CHAN_HT40(chan))
+ if (conf_is_ht40(conf))
return ath9k_hw_mac_usec(ah, clks) / 2;
else
return ath9k_hw_mac_usec(ah, clks);
}
-static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
+static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
{
- if (ah->ah_curchan != NULL)
- return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
- ah->ah_curchan)];
- else
- return usecs * CLOCK_RATE[ATH9K_MODE_11B];
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+ if (!ah->curchan) /* should really check for CCK instead */
+ return usecs *ATH9K_CLOCK_RATE_CCK;
+ if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
+ return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
}
-static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
+static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
{
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
- if (chan && IS_CHAN_HT40(chan))
+ if (conf_is_ht40(conf))
return ath9k_hw_mac_clks(ah, usecs) * 2;
else
return ath9k_hw_mac_clks(ah, usecs);
}
-enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
- const struct ath9k_channel *chan)
-{
- if (IS_CHAN_B(chan))
- return ATH9K_MODE_11B;
- if (IS_CHAN_G(chan))
- return ATH9K_MODE_11G;
-
- return ATH9K_MODE_11A;
-}
-
-bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val)
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
{
int i;
- for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
+ BUG_ON(timeout < AH_TIME_QUANTUM);
+
+ for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
if ((REG_READ(ah, reg) & mask) == val)
return true;
@@ -106,8 +98,8 @@ bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val)
}
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
- reg, REG_READ(ah, reg), mask, val);
+ "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+ timeout, reg, REG_READ(ah, reg), mask, val);
return false;
}
@@ -124,11 +116,11 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n)
return retval;
}
-bool ath9k_get_channel_edges(struct ath_hal *ah,
+bool ath9k_get_channel_edges(struct ath_hw *ah,
u16 flags, u16 *low,
u16 *high)
{
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
if (flags & CHANNEL_5GHZ) {
*low = pCap->low_5ghz_chan;
@@ -143,7 +135,7 @@ bool ath9k_get_channel_edges(struct ath_hal *ah,
return false;
}
-u16 ath9k_hw_computetxtime(struct ath_hal *ah,
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
struct ath_rate_table *rates,
u32 frameLen, u16 rateix,
bool shortPreamble)
@@ -165,15 +157,15 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah,
txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
break;
case WLAN_RC_PHY_OFDM:
- if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
+ if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
numBits = OFDM_PLCP_BITS + (frameLen << 3);
numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
txTime = OFDM_SIFS_TIME_QUARTER
+ OFDM_PREAMBLE_TIME_QUARTER
+ (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
- } else if (ah->ah_curchan &&
- IS_CHAN_HALF_RATE(ah->ah_curchan)) {
+ } else if (ah->curchan &&
+ IS_CHAN_HALF_RATE(ah->curchan)) {
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
numBits = OFDM_PLCP_BITS + (frameLen << 3);
numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
@@ -199,52 +191,11 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah,
return txTime;
}
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
-{
- if (flags & CHANNEL_2GHZ) {
- if (freq == 2484)
- return 14;
- if (freq < 2484)
- return (freq - 2407) / 5;
- else
- return 15 + ((freq - 2512) / 20);
- } else if (flags & CHANNEL_5GHZ) {
- if (ath9k_regd_is_public_safety_sku(ah) &&
- IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
- return ((freq * 10) +
- (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
- } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
- return (freq - 4000) / 5;
- } else {
- return (freq - 5000) / 5;
- }
- } else {
- if (freq == 2484)
- return 14;
- if (freq < 2484)
- return (freq - 2407) / 5;
- if (freq < 5000) {
- if (ath9k_regd_is_public_safety_sku(ah)
- && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
- return ((freq * 10) +
- (((freq % 5) ==
- 2) ? 5 : 0) - 49400) / 5;
- } else if (freq > 4900) {
- return (freq - 4000) / 5;
- } else {
- return 15 + ((freq - 2512) / 20);
- }
- }
- return (freq - 5000) / 5;
- }
-}
-
-void ath9k_hw_get_channel_centers(struct ath_hal *ah,
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
struct ath9k_channel *chan,
struct chan_centers *centers)
{
int8_t extoff;
- struct ath_hal_5416 *ahp = AH5416(ah);
if (!IS_CHAN_HT40(chan)) {
centers->ctl_center = centers->ext_center =
@@ -267,16 +218,15 @@ void ath9k_hw_get_channel_centers(struct ath_hal *ah,
centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
centers->ext_center =
centers->synth_center + (extoff *
- ((ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
+ ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
HT40_CHANNEL_CENTER_SHIFT : 15));
-
}
/******************/
/* Chip Revisions */
/******************/
-static void ath9k_hw_read_revisions(struct ath_hal *ah)
+static void ath9k_hw_read_revisions(struct ath_hw *ah)
{
u32 val;
@@ -284,21 +234,22 @@ static void ath9k_hw_read_revisions(struct ath_hal *ah)
if (val == 0xFF) {
val = REG_READ(ah, AR_SREV);
- ah->ah_macVersion = (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
- ah->ah_macRev = MS(val, AR_SREV_REVISION2);
- ah->ah_isPciExpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+ ah->hw_version.macVersion =
+ (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
+ ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+ ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
} else {
if (!AR_SREV_9100(ah))
- ah->ah_macVersion = MS(val, AR_SREV_VERSION);
+ ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
- ah->ah_macRev = val & AR_SREV_REVISION;
+ ah->hw_version.macRev = val & AR_SREV_REVISION;
- if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
- ah->ah_isPciExpress = true;
+ if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
+ ah->is_pciexpress = true;
}
}
-static int ath9k_hw_get_radiorev(struct ath_hal *ah)
+static int ath9k_hw_get_radiorev(struct ath_hw *ah)
{
u32 val;
int i;
@@ -317,9 +268,9 @@ static int ath9k_hw_get_radiorev(struct ath_hal *ah)
/* HW Attach, Detach, Init Routines */
/************************************/
-static void ath9k_hw_disablepcie(struct ath_hal *ah)
+static void ath9k_hw_disablepcie(struct ath_hw *ah)
{
- if (!AR_SREV_9100(ah))
+ if (AR_SREV_9100(ah))
return;
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
@@ -335,7 +286,7 @@ static void ath9k_hw_disablepcie(struct ath_hal *ah)
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
}
-static bool ath9k_hw_chip_test(struct ath_hal *ah)
+static bool ath9k_hw_chip_test(struct ath_hw *ah)
{
u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
u32 regHold[2];
@@ -377,6 +328,7 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah)
REG_WRITE(ah, regAddr[i], regHold[i]);
}
udelay(100);
+
return true;
}
@@ -389,6 +341,8 @@ static const char *ath9k_hw_devname(u16 devid)
return "Atheros 5418";
case AR9160_DEVID_PCI:
return "Atheros 9160";
+ case AR5416_AR9100_DEVID:
+ return "Atheros 9100";
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
return "Atheros 9280";
@@ -399,99 +353,110 @@ static const char *ath9k_hw_devname(u16 devid)
return NULL;
}
-static void ath9k_hw_set_defaults(struct ath_hal *ah)
+static void ath9k_hw_set_defaults(struct ath_hw *ah)
{
int i;
- ah->ah_config.dma_beacon_response_time = 2;
- ah->ah_config.sw_beacon_response_time = 10;
- ah->ah_config.additional_swba_backoff = 0;
- ah->ah_config.ack_6mb = 0x0;
- ah->ah_config.cwm_ignore_extcca = 0;
- ah->ah_config.pcie_powersave_enable = 0;
- ah->ah_config.pcie_l1skp_enable = 0;
- ah->ah_config.pcie_clock_req = 0;
- ah->ah_config.pcie_power_reset = 0x100;
- ah->ah_config.pcie_restore = 0;
- ah->ah_config.pcie_waen = 0;
- ah->ah_config.analog_shiftreg = 1;
- ah->ah_config.ht_enable = 1;
- ah->ah_config.ofdm_trig_low = 200;
- ah->ah_config.ofdm_trig_high = 500;
- ah->ah_config.cck_trig_high = 200;
- ah->ah_config.cck_trig_low = 100;
- ah->ah_config.enable_ani = 1;
- ah->ah_config.noise_immunity_level = 4;
- ah->ah_config.ofdm_weaksignal_det = 1;
- ah->ah_config.cck_weaksignal_thr = 0;
- ah->ah_config.spur_immunity_level = 2;
- ah->ah_config.firstep_level = 0;
- ah->ah_config.rssi_thr_high = 40;
- ah->ah_config.rssi_thr_low = 7;
- ah->ah_config.diversity_control = 0;
- ah->ah_config.antenna_switch_swap = 0;
+ ah->config.dma_beacon_response_time = 2;
+ ah->config.sw_beacon_response_time = 10;
+ ah->config.additional_swba_backoff = 0;
+ ah->config.ack_6mb = 0x0;
+ ah->config.cwm_ignore_extcca = 0;
+ ah->config.pcie_powersave_enable = 0;
+ ah->config.pcie_l1skp_enable = 0;
+ ah->config.pcie_clock_req = 0;
+ ah->config.pcie_power_reset = 0x100;
+ ah->config.pcie_restore = 0;
+ ah->config.pcie_waen = 0;
+ ah->config.analog_shiftreg = 1;
+ ah->config.ht_enable = 1;
+ ah->config.ofdm_trig_low = 200;
+ ah->config.ofdm_trig_high = 500;
+ ah->config.cck_trig_high = 200;
+ ah->config.cck_trig_low = 100;
+ ah->config.enable_ani = 1;
+ ah->config.noise_immunity_level = 4;
+ ah->config.ofdm_weaksignal_det = 1;
+ ah->config.cck_weaksignal_thr = 0;
+ ah->config.spur_immunity_level = 2;
+ ah->config.firstep_level = 0;
+ ah->config.rssi_thr_high = 40;
+ ah->config.rssi_thr_low = 7;
+ ah->config.diversity_control = 0;
+ ah->config.antenna_switch_swap = 0;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
- ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
+ ah->config.spurchans[i][0] = AR_NO_SPUR;
+ ah->config.spurchans[i][1] = AR_NO_SPUR;
}
- ah->ah_config.intr_mitigation = 1;
+ ah->config.intr_mitigation = 1;
+
+ /*
+ * We need this for PCI devices only (Cardbus, PCI, miniPCI)
+ * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
+ * This means we use it for all AR5416 devices, and the few
+ * minor PCI AR9280 devices out there.
+ *
+ * Serialization is required because these devices do not handle
+ * well the case of two concurrent reads/writes due to the latency
+ * involved. During one read/write another read/write can be issued
+ * on another CPU while the previous read/write may still be working
+ * on our hardware, if we hit this case the hardware poops in a loop.
+ * We prevent this by serializing reads and writes.
+ *
+ * This issue is not present on PCI-Express devices or pre-AR5416
+ * devices (legacy, 802.11abg).
+ */
+ if (num_possible_cpus() > 1)
+ ah->config.serialize_regmode = SER_REG_MODE_AUTO;
}
-static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
- struct ath_softc *sc,
- void __iomem *mem,
- int *status)
+static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
+ int *status)
{
- static const u8 defbssidmask[ETH_ALEN] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- struct ath_hal_5416 *ahp;
- struct ath_hal *ah;
+ struct ath_hw *ah;
- ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
- if (ahp == NULL) {
+ ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
+ if (ah == NULL) {
DPRINTF(sc, ATH_DBG_FATAL,
"Cannot allocate memory for state block\n");
*status = -ENOMEM;
return NULL;
}
- ah = &ahp->ah;
ah->ah_sc = sc;
- ah->ah_sh = mem;
- ah->ah_magic = AR5416_MAGIC;
- ah->ah_countryCode = CTRY_DEFAULT;
- ah->ah_devid = devid;
- ah->ah_subvendorid = 0;
+ ah->hw_version.magic = AR5416_MAGIC;
+ ah->regulatory.country_code = CTRY_DEFAULT;
+ ah->hw_version.devid = devid;
+ ah->hw_version.subvendorid = 0;
ah->ah_flags = 0;
if ((devid == AR5416_AR9100_DEVID))
- ah->ah_macVersion = AR_SREV_VERSION_9100;
+ ah->hw_version.macVersion = AR_SREV_VERSION_9100;
if (!AR_SREV_9100(ah))
ah->ah_flags = AH_USE_EEPROM;
- ah->ah_powerLimit = MAX_RATE_POWER;
- ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
- ahp->ah_atimWindow = 0;
- ahp->ah_diversityControl = ah->ah_config.diversity_control;
- ahp->ah_antennaSwitchSwap =
- ah->ah_config.antenna_switch_swap;
- ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
- ahp->ah_beaconInterval = 100;
- ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
- ahp->ah_slottime = (u32) -1;
- ahp->ah_acktimeout = (u32) -1;
- ahp->ah_ctstimeout = (u32) -1;
- ahp->ah_globaltxtimeout = (u32) -1;
- memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
-
- ahp->ah_gBeaconRate = 0;
+ ah->regulatory.power_limit = MAX_RATE_POWER;
+ ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
+ ah->atim_window = 0;
+ ah->diversity_control = ah->config.diversity_control;
+ ah->antenna_switch_swap =
+ ah->config.antenna_switch_swap;
+ ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
+ ah->beacon_interval = 100;
+ ah->enable_32kHz_clock = DONT_USE_32KHZ;
+ ah->slottime = (u32) -1;
+ ah->acktimeout = (u32) -1;
+ ah->ctstimeout = (u32) -1;
+ ah->globaltxtimeout = (u32) -1;
+
+ ah->gbeacon_rate = 0;
- return ahp;
+ return ah;
}
-static int ath9k_hw_rfattach(struct ath_hal *ah)
+static int ath9k_hw_rfattach(struct ath_hw *ah)
{
bool rfStatus = false;
int ecode = 0;
@@ -506,7 +471,7 @@ static int ath9k_hw_rfattach(struct ath_hal *ah)
return 0;
}
-static int ath9k_hw_rf_claim(struct ath_hal *ah)
+static int ath9k_hw_rf_claim(struct ath_hw *ah)
{
u32 val;
@@ -526,88 +491,87 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah)
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"5G Radio Chip Rev 0x%02X is not "
"supported by this driver\n",
- ah->ah_analog5GhzRev);
+ ah->hw_version.analog5GhzRev);
return -EOPNOTSUPP;
}
- ah->ah_analog5GhzRev = val;
+ ah->hw_version.analog5GhzRev = val;
return 0;
}
-static int ath9k_hw_init_macaddr(struct ath_hal *ah)
+static int ath9k_hw_init_macaddr(struct ath_hw *ah)
{
u32 sum;
int i;
u16 eeval;
- struct ath_hal_5416 *ahp = AH5416(ah);
sum = 0;
for (i = 0; i < 3; i++) {
- eeval = ath9k_hw_get_eeprom(ah, AR_EEPROM_MAC(i));
+ eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
sum += eeval;
- ahp->ah_macaddr[2 * i] = eeval >> 8;
- ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
+ 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",
- ahp->ah_macaddr);
+ ah->macaddr);
return -EADDRNOTAVAIL;
}
return 0;
}
-static void ath9k_hw_init_rxgain_ini(struct ath_hal *ah)
+static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
{
u32 rxgain_type;
- struct ath_hal_5416 *ahp = AH5416(ah);
- if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
- rxgain_type = ath9k_hw_get_eeprom(ah, EEP_RXGAIN_TYPE);
+ if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
+ rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
- INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9280Modes_backoff_13db_rxgain_9280_2,
ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
- INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9280Modes_backoff_23db_rxgain_9280_2,
ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
else
- INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9280Modes_original_rxgain_9280_2,
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
- } else
- INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+ } else {
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9280Modes_original_rxgain_9280_2,
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+ }
}
-static void ath9k_hw_init_txgain_ini(struct ath_hal *ah)
+static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
{
u32 txgain_type;
- struct ath_hal_5416 *ahp = AH5416(ah);
- if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
- txgain_type = ath9k_hw_get_eeprom(ah, EEP_TXGAIN_TYPE);
+ if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
+ txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
- INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9280Modes_high_power_tx_gain_9280_2,
ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
else
- INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9280Modes_original_tx_gain_9280_2,
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
- } else
- INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+ } else {
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9280Modes_original_tx_gain_9280_2,
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+ }
}
-static int ath9k_hw_post_attach(struct ath_hal *ah)
+static int ath9k_hw_post_attach(struct ath_hw *ah)
{
int ecode;
@@ -636,237 +600,229 @@ static int ath9k_hw_post_attach(struct ath_hal *ah)
return 0;
}
-static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
- void __iomem *mem, int *status)
+static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
+ int *status)
{
- struct ath_hal_5416 *ahp;
- struct ath_hal *ah;
+ struct ath_hw *ah;
int ecode;
u32 i, j;
- ahp = ath9k_hw_newstate(devid, sc, mem, status);
- if (ahp == NULL)
+ ah = ath9k_hw_newstate(devid, sc, status);
+ if (ah == NULL)
return NULL;
- ah = &ahp->ah;
-
ath9k_hw_set_defaults(ah);
- if (ah->ah_config.intr_mitigation != 0)
- ahp->ah_intrMitigation = true;
+ if (ah->config.intr_mitigation != 0)
+ ah->intr_mitigation = true;
if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't reset chip\n");
+ DPRINTF(sc, ATH_DBG_RESET, "Couldn't reset chip\n");
ecode = -EIO;
goto bad;
}
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
+ DPRINTF(sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
ecode = -EIO;
goto bad;
}
- if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
- if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
- ah->ah_config.serialize_regmode =
+ if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+ if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+ (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
+ ah->config.serialize_regmode =
SER_REG_MODE_ON;
} else {
- ah->ah_config.serialize_regmode =
+ ah->config.serialize_regmode =
SER_REG_MODE_OFF;
}
}
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
- "serialize_regmode is %d\n",
- ah->ah_config.serialize_regmode);
+ DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
+ ah->config.serialize_regmode);
- if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
- (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
- (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
+ if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
+ (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
+ (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
(!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+ DPRINTF(sc, ATH_DBG_RESET,
"Mac Chip Rev 0x%02x.%x is not supported by "
- "this driver\n", ah->ah_macVersion, ah->ah_macRev);
+ "this driver\n", ah->hw_version.macVersion,
+ ah->hw_version.macRev);
ecode = -EOPNOTSUPP;
goto bad;
}
if (AR_SREV_9100(ah)) {
- ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
- ahp->ah_suppCals = IQ_MISMATCH_CAL;
- ah->ah_isPciExpress = false;
+ ah->iq_caldata.calData = &iq_cal_multi_sample;
+ ah->supp_cals = IQ_MISMATCH_CAL;
+ ah->is_pciexpress = false;
}
- ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
+ ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
if (AR_SREV_9160_10_OR_LATER(ah)) {
if (AR_SREV_9280_10_OR_LATER(ah)) {
- ahp->ah_iqCalData.calData = &iq_cal_single_sample;
- ahp->ah_adcGainCalData.calData =
+ ah->iq_caldata.calData = &iq_cal_single_sample;
+ ah->adcgain_caldata.calData =
&adc_gain_cal_single_sample;
- ahp->ah_adcDcCalData.calData =
+ ah->adcdc_caldata.calData =
&adc_dc_cal_single_sample;
- ahp->ah_adcDcCalInitData.calData =
+ ah->adcdc_calinitdata.calData =
&adc_init_dc_cal;
} else {
- ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
- ahp->ah_adcGainCalData.calData =
+ ah->iq_caldata.calData = &iq_cal_multi_sample;
+ ah->adcgain_caldata.calData =
&adc_gain_cal_multi_sample;
- ahp->ah_adcDcCalData.calData =
+ ah->adcdc_caldata.calData =
&adc_dc_cal_multi_sample;
- ahp->ah_adcDcCalInitData.calData =
+ ah->adcdc_calinitdata.calData =
&adc_init_dc_cal;
}
- ahp->ah_suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+ ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
}
- if (AR_SREV_9160(ah)) {
- ah->ah_config.enable_ani = 1;
- ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
- ATH9K_ANI_FIRSTEP_LEVEL);
- } else {
- ahp->ah_ani_function = ATH9K_ANI_ALL;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- ahp->ah_ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
- }
- }
+ ah->ani_function = ATH9K_ANI_ALL;
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+ DPRINTF(sc, ATH_DBG_RESET,
"This Mac Chip Rev 0x%02x.%x is \n",
- ah->ah_macVersion, ah->ah_macRev);
+ ah->hw_version.macVersion, ah->hw_version.macRev);
if (AR_SREV_9285_12_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2,
+
+ INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2,
+ INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
ARRAY_SIZE(ar9285Common_9285_1_2), 2);
- if (ah->ah_config.pcie_clock_req) {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ if (ah->config.pcie_clock_req) {
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_off_L1_9285_1_2,
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
2);
}
} else if (AR_SREV_9285_10_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285,
+ INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
ARRAY_SIZE(ar9285Modes_9285), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285,
+ INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
ARRAY_SIZE(ar9285Common_9285), 2);
- if (ah->ah_config.pcie_clock_req) {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ if (ah->config.pcie_clock_req) {
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_off_L1_9285,
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_always_on_L1_9285,
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
}
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
+ INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
ARRAY_SIZE(ar9280Modes_9280_2), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
+ INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
ARRAY_SIZE(ar9280Common_9280_2), 2);
- if (ah->ah_config.pcie_clock_req) {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ if (ah->config.pcie_clock_req) {
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_off_L1_9280,
ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_always_on_L1_9280,
ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
}
- INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
+ INIT_INI_ARRAY(&ah->iniModesAdditional,
ar9280Modes_fast_clock_9280_2,
ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
} else if (AR_SREV_9280_10_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
+ INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
ARRAY_SIZE(ar9280Modes_9280), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
+ INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
ARRAY_SIZE(ar9280Common_9280), 2);
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
+ INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
ARRAY_SIZE(ar5416Modes_9160), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
+ INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
ARRAY_SIZE(ar5416Common_9160), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
+ INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
ARRAY_SIZE(ar5416Bank0_9160), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
+ INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
+ INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
ARRAY_SIZE(ar5416Bank1_9160), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
+ INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
ARRAY_SIZE(ar5416Bank2_9160), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
+ INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
ARRAY_SIZE(ar5416Bank3_9160), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
+ INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
ARRAY_SIZE(ar5416Bank6_9160), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
+ INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
+ INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
ARRAY_SIZE(ar5416Bank7_9160), 2);
if (AR_SREV_9160_11(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniAddac,
+ INIT_INI_ARRAY(&ah->iniAddac,
ar5416Addac_91601_1,
ARRAY_SIZE(ar5416Addac_91601_1), 2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
+ INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
ARRAY_SIZE(ar5416Addac_9160), 2);
}
} else if (AR_SREV_9100_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
+ INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
ARRAY_SIZE(ar5416Modes_9100), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
+ INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
ARRAY_SIZE(ar5416Common_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
+ INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
ARRAY_SIZE(ar5416Bank0_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
+ INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
+ INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
ARRAY_SIZE(ar5416Bank1_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
+ INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
ARRAY_SIZE(ar5416Bank2_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
+ INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
ARRAY_SIZE(ar5416Bank3_9100), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
+ INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
ARRAY_SIZE(ar5416Bank6_9100), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
+ INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
+ INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
ARRAY_SIZE(ar5416Bank7_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
+ INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
ARRAY_SIZE(ar5416Addac_9100), 2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
+ INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
ARRAY_SIZE(ar5416Modes), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
+ INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
ARRAY_SIZE(ar5416Common), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
+ INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
ARRAY_SIZE(ar5416Bank0), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
+ INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
ARRAY_SIZE(ar5416BB_RfGain), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
+ INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
ARRAY_SIZE(ar5416Bank1), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
+ INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
ARRAY_SIZE(ar5416Bank2), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
+ INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
ARRAY_SIZE(ar5416Bank3), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
+ INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
ARRAY_SIZE(ar5416Bank6), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
+ INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
ARRAY_SIZE(ar5416Bank6TPC), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
+ INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
ARRAY_SIZE(ar5416Bank7), 2);
- INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
+ INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
ARRAY_SIZE(ar5416Addac), 2);
}
- if (ah->ah_isPciExpress)
+ if (ah->is_pciexpress)
ath9k_hw_configpcipowersave(ah, 0);
else
ath9k_hw_disablepcie(ah);
@@ -875,6 +831,22 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (ecode != 0)
goto bad;
+ if (AR_SREV_9285_12_OR_LATER(ah)) {
+ u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+ /* txgain table */
+ if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9285Modes_high_power_tx_gain_9285_1_2,
+ ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
+ } else {
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9285Modes_original_tx_gain_9285_1_2,
+ ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
+ }
+
+ }
+
/* rxgain table */
if (AR_SREV_9280_20(ah))
ath9k_hw_init_rxgain_ini(ah);
@@ -883,53 +855,55 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (AR_SREV_9280_20(ah))
ath9k_hw_init_txgain_ini(ah);
- if (ah->ah_devid == AR9280_DEVID_PCI) {
- for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
- u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
+ if (!ath9k_hw_fill_cap_info(ah)) {
+ DPRINTF(sc, ATH_DBG_RESET, "failed ath9k_hw_fill_cap_info\n");
+ ecode = -EINVAL;
+ goto bad;
+ }
+
+ if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
+ test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
- for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
- u32 val = INI_RA(&ahp->ah_iniModes, i, j);
+ /* EEPROM Fixup */
+ for (i = 0; i < ah->iniModes.ia_rows; i++) {
+ u32 reg = INI_RA(&ah->iniModes, i, 0);
- INI_RA(&ahp->ah_iniModes, i, j) =
+ for (j = 1; j < ah->iniModes.ia_columns; j++) {
+ u32 val = INI_RA(&ah->iniModes, i, j);
+
+ INI_RA(&ah->iniModes, i, j) =
ath9k_hw_ini_fixup(ah,
- &ahp->ah_eeprom.def,
+ &ah->eeprom.def,
reg, val);
}
}
}
- if (!ath9k_hw_fill_cap_info(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
- "failed ath9k_hw_fill_cap_info\n");
- ecode = -EINVAL;
- goto bad;
- }
-
ecode = ath9k_hw_init_macaddr(ah);
if (ecode != 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+ DPRINTF(sc, ATH_DBG_RESET,
"failed initializing mac address\n");
goto bad;
}
if (AR_SREV_9285(ah))
- ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
+ ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
else
- ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
+ ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
ath9k_init_nfcal_hist_buffer(ah);
return ah;
bad:
- if (ahp)
- ath9k_hw_detach((struct ath_hal *) ahp);
+ if (ah)
+ ath9k_hw_detach(ah);
if (status)
*status = ecode;
return NULL;
}
-static void ath9k_hw_init_bb(struct ath_hal *ah,
+static void ath9k_hw_init_bb(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u32 synthDelay;
@@ -945,7 +919,7 @@ static void ath9k_hw_init_bb(struct ath_hal *ah,
udelay(synthDelay + BASE_ACTIVATE_DELAY);
}
-static void ath9k_hw_init_qos(struct ath_hal *ah)
+static void ath9k_hw_init_qos(struct ath_hw *ah)
{
REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
@@ -962,7 +936,7 @@ static void ath9k_hw_init_qos(struct ath_hal *ah)
REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
}
-static void ath9k_hw_init_pll(struct ath_hal *ah,
+static void ath9k_hw_init_pll(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u32 pll;
@@ -1023,27 +997,26 @@ static void ath9k_hw_init_pll(struct ath_hal *ah,
pll |= SM(0xb, AR_RTC_PLL_DIV);
}
}
- REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
udelay(RTC_PLL_SETTLE_DELAY);
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
}
-static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
+static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int rx_chainmask, tx_chainmask;
- rx_chainmask = ahp->ah_rxchainmask;
- tx_chainmask = ahp->ah_txchainmask;
+ rx_chainmask = ah->rxchainmask;
+ tx_chainmask = ah->txchainmask;
switch (rx_chainmask) {
case 0x5:
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
case 0x3:
- if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
+ if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
break;
@@ -1068,28 +1041,26 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
}
-static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
+static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
enum nl80211_iftype opmode)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- ahp->ah_maskReg = AR_IMR_TXERR |
+ ah->mask_reg = AR_IMR_TXERR |
AR_IMR_TXURN |
AR_IMR_RXERR |
AR_IMR_RXORN |
AR_IMR_BCNMISC;
- if (ahp->ah_intrMitigation)
- ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+ if (ah->intr_mitigation)
+ ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
else
- ahp->ah_maskReg |= AR_IMR_RXOK;
+ ah->mask_reg |= AR_IMR_RXOK;
- ahp->ah_maskReg |= AR_IMR_TXOK;
+ ah->mask_reg |= AR_IMR_TXOK;
if (opmode == NL80211_IFTYPE_AP)
- ahp->ah_maskReg |= AR_IMR_MIB;
+ ah->mask_reg |= AR_IMR_MIB;
- REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
+ REG_WRITE(ah, AR_IMR, ah->mask_reg);
REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
if (!AR_SREV_9100(ah)) {
@@ -1099,72 +1070,64 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
}
}
-static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
+static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us);
- ahp->ah_acktimeout = (u32) -1;
+ ah->acktimeout = (u32) -1;
return false;
} else {
REG_RMW_FIELD(ah, AR_TIME_OUT,
AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
- ahp->ah_acktimeout = us;
+ ah->acktimeout = us;
return true;
}
}
-static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
+static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us);
- ahp->ah_ctstimeout = (u32) -1;
+ ah->ctstimeout = (u32) -1;
return false;
} else {
REG_RMW_FIELD(ah, AR_TIME_OUT,
AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
- ahp->ah_ctstimeout = us;
+ ah->ctstimeout = us;
return true;
}
}
-static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah, u32 tu)
+static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (tu > 0xFFFF) {
DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
"bad global tx timeout %u\n", tu);
- ahp->ah_globaltxtimeout = (u32) -1;
+ ah->globaltxtimeout = (u32) -1;
return false;
} else {
REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
- ahp->ah_globaltxtimeout = tu;
+ ah->globaltxtimeout = tu;
return true;
}
}
-static void ath9k_hw_init_user_settings(struct ath_hal *ah)
+static void ath9k_hw_init_user_settings(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ahp->ah_miscMode 0x%x\n",
- ahp->ah_miscMode);
+ DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+ ah->misc_mode);
- if (ahp->ah_miscMode != 0)
+ if (ah->misc_mode != 0)
REG_WRITE(ah, AR_PCU_MISC,
- REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
- if (ahp->ah_slottime != (u32) -1)
- ath9k_hw_setslottime(ah, ahp->ah_slottime);
- if (ahp->ah_acktimeout != (u32) -1)
- ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
- if (ahp->ah_ctstimeout != (u32) -1)
- ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
- if (ahp->ah_globaltxtimeout != (u32) -1)
- ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
+ REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
+ if (ah->slottime != (u32) -1)
+ ath9k_hw_setslottime(ah, ah->slottime);
+ if (ah->acktimeout != (u32) -1)
+ ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
+ if (ah->ctstimeout != (u32) -1)
+ ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
+ if (ah->globaltxtimeout != (u32) -1)
+ ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
}
const char *ath9k_hw_probe(u16 vendorid, u16 devid)
@@ -1173,7 +1136,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid)
ath9k_hw_devname(devid) : NULL;
}
-void ath9k_hw_detach(struct ath_hal *ah)
+void ath9k_hw_detach(struct ath_hw *ah)
{
if (!AR_SREV_9100(ah))
ath9k_hw_ani_detach(ah);
@@ -1183,19 +1146,19 @@ void ath9k_hw_detach(struct ath_hal *ah)
kfree(ah);
}
-struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
- void __iomem *mem, int *error)
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
{
- struct ath_hal *ah = NULL;
+ struct ath_hw *ah = NULL;
switch (devid) {
case AR5416_DEVID_PCI:
case AR5416_DEVID_PCIE:
+ case AR5416_AR9100_DEVID:
case AR9160_DEVID_PCI:
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
case AR9285_DEVID_PCIE:
- ah = ath9k_hw_do_attach(devid, sc, mem, error);
+ ah = ath9k_hw_do_attach(devid, sc, error);
break;
default:
*error = -ENXIO;
@@ -1209,7 +1172,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
/* INI */
/*******/
-static void ath9k_hw_override_ini(struct ath_hal *ah,
+static void ath9k_hw_override_ini(struct ath_hw *ah,
struct ath9k_channel *chan)
{
/*
@@ -1220,20 +1183,20 @@ static void ath9k_hw_override_ini(struct ath_hal *ah,
REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
- if (!AR_SREV_5416_V20_OR_LATER(ah) ||
+ if (!AR_SREV_5416_20_OR_LATER(ah) ||
AR_SREV_9280_10_OR_LATER(ah))
return;
REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
}
-static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
+static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value)
{
struct base_eep_header *pBase = &(pEepData->baseEepHeader);
- switch (ah->ah_devid) {
+ switch (ah->hw_version.devid) {
case AR9280_DEVID_PCI:
if (reg == 0x7894) {
DPRINTF(ah->ah_sc, ATH_DBG_ANY,
@@ -1261,24 +1224,33 @@ static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
return value;
}
-static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+ if (ah->eep_map == EEP_MAP_4KBITS)
return value;
else
return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
}
-static int ath9k_hw_process_ini(struct ath_hal *ah,
+static void ath9k_olc_init(struct ath_hw *ah)
+{
+ u32 i;
+
+ for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
+ ah->originalGain[i] =
+ MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
+ AR_PHY_TX_GAIN);
+ ah->PDADCdelta = 0;
+}
+
+static int ath9k_hw_process_ini(struct ath_hw *ah,
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
int i, regWrites = 0;
- struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ieee80211_channel *channel = chan->chan;
u32 modesIndex, freqIndex;
int status;
@@ -1310,40 +1282,38 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
}
REG_WRITE(ah, AR_PHY(0), 0x00000007);
-
REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+ ah->eep_ops->set_addac(ah, chan);
- ath9k_hw_set_addac(ah, chan);
-
- if (AR_SREV_5416_V22_OR_LATER(ah)) {
- REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
+ if (AR_SREV_5416_22_OR_LATER(ah)) {
+ REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
} else {
struct ar5416IniArray temp;
u32 addacSize =
- sizeof(u32) * ahp->ah_iniAddac.ia_rows *
- ahp->ah_iniAddac.ia_columns;
+ sizeof(u32) * ah->iniAddac.ia_rows *
+ ah->iniAddac.ia_columns;
- memcpy(ahp->ah_addac5416_21,
- ahp->ah_iniAddac.ia_array, addacSize);
+ memcpy(ah->addac5416_21,
+ ah->iniAddac.ia_array, addacSize);
- (ahp->ah_addac5416_21)[31 * ahp->ah_iniAddac.ia_columns + 1] = 0;
+ (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
- temp.ia_array = ahp->ah_addac5416_21;
- temp.ia_columns = ahp->ah_iniAddac.ia_columns;
- temp.ia_rows = ahp->ah_iniAddac.ia_rows;
+ temp.ia_array = ah->addac5416_21;
+ temp.ia_columns = ah->iniAddac.ia_columns;
+ temp.ia_rows = ah->iniAddac.ia_rows;
REG_WRITE_ARRAY(&temp, 1, regWrites);
}
REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
- for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
- u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
- u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
+ for (i = 0; i < ah->iniModes.ia_rows; i++) {
+ u32 reg = INI_RA(&ah->iniModes, i, 0);
+ u32 val = INI_RA(&ah->iniModes, i, modesIndex);
REG_WRITE(ah, reg, val);
if (reg >= 0x7800 && reg < 0x78a0
- && ah->ah_config.analog_shiftreg) {
+ && ah->config.analog_shiftreg) {
udelay(100);
}
@@ -1351,19 +1321,20 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
}
if (AR_SREV_9280(ah))
- REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites);
+ REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
- if (AR_SREV_9280(ah))
- REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites);
+ if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
+ AR_SREV_9285_12_OR_LATER(ah)))
+ REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
- for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
- u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
- u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
+ for (i = 0; i < ah->iniCommon.ia_rows; i++) {
+ u32 reg = INI_RA(&ah->iniCommon, i, 0);
+ u32 val = INI_RA(&ah->iniCommon, i, 1);
REG_WRITE(ah, reg, val);
if (reg >= 0x7800 && reg < 0x78a0
- && ah->ah_config.analog_shiftreg) {
+ && ah->config.analog_shiftreg) {
udelay(100);
}
@@ -1373,7 +1344,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
- REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
+ REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
regWrites);
}
@@ -1381,13 +1352,15 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
ath9k_hw_set_regs(ah, chan, macmode);
ath9k_hw_init_chain_masks(ah);
- status = ath9k_hw_set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- ath9k_regd_get_antenna_allowed(ah,
- chan),
- chan->maxRegTxPower * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->ah_powerLimit));
+ 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");
@@ -1407,7 +1380,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
/* Reset and Channel Switching Routines */
/****************************************/
-static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
{
u32 rfMode = 0;
@@ -1427,12 +1400,12 @@ static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
REG_WRITE(ah, AR_PHY_MODE, rfMode);
}
-static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
+static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
{
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
}
-static inline void ath9k_hw_set_dma(struct ath_hal *ah)
+static inline void ath9k_hw_set_dma(struct ath_hw *ah)
{
u32 regval;
@@ -1442,7 +1415,7 @@ static inline void ath9k_hw_set_dma(struct ath_hal *ah)
regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
- REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
+ REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
@@ -1458,7 +1431,7 @@ static inline void ath9k_hw_set_dma(struct ath_hal *ah)
}
}
-static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
+static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
{
u32 val;
@@ -1482,7 +1455,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
}
}
-static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
+static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
u32 coef_scaled,
u32 *coef_mantissa,
u32 *coef_exponent)
@@ -1501,7 +1474,7 @@ static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
*coef_exponent = coef_exp - 16;
}
-static void ath9k_hw_set_delta_slope(struct ath_hal *ah,
+static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u32 coef_scaled, ds_coef_exp, ds_coef_man;
@@ -1535,11 +1508,19 @@ static void ath9k_hw_set_delta_slope(struct ath_hal *ah,
AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
}
-static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
+static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
{
u32 rst_flags;
u32 tmpReg;
+ if (AR_SREV_9100(ah)) {
+ u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
+ val &= ~AR_RTC_DERIVED_CLK_PERIOD;
+ val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
+ (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
+ }
+
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
AR_RTC_FORCE_WAKE_ON_INT);
@@ -1562,11 +1543,11 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
rst_flags |= AR_RTC_RC_MAC_COLD;
}
- REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
+ REG_WRITE(ah, AR_RTC_RC, rst_flags);
udelay(50);
- REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
- if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
+ REG_WRITE(ah, AR_RTC_RC, 0);
+ if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
"RTC stuck in MAC reset\n");
return false;
@@ -1583,18 +1564,20 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
return true;
}
-static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
+static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
{
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
AR_RTC_FORCE_WAKE_ON_INT);
- REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
- REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
+ REG_WRITE(ah, AR_RTC_RESET, 0);
+ udelay(2);
+ REG_WRITE(ah, AR_RTC_RESET, 1);
if (!ath9k_hw_wait(ah,
AR_RTC_STATUS,
AR_RTC_STATUS_M,
- AR_RTC_STATUS_ON)) {
+ AR_RTC_STATUS_ON,
+ AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n");
return false;
}
@@ -1604,7 +1587,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
}
-static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type)
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
{
REG_WRITE(ah, AR_RTC_FORCE_WAKE,
AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
@@ -1622,12 +1605,11 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type)
}
}
-static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
u32 phymode;
u32 enableDacFifo = 0;
- struct ath_hal_5416 *ahp = AH5416(ah);
if (AR_SREV_9285_10_OR_LATER(ah))
enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
@@ -1643,7 +1625,7 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
(chan->chanmode == CHANNEL_G_HT40PLUS))
phymode |= AR_PHY_FC_DYN2040_PRI_CH;
- if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
+ if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
phymode |= AR_PHY_FC_DYN2040_EXT_CH;
}
REG_WRITE(ah, AR_PHY_TURBO, phymode);
@@ -1654,54 +1636,30 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
}
-static bool ath9k_hw_chip_reset(struct ath_hal *ah,
+static bool ath9k_hw_chip_reset(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+ if (OLC_FOR_AR9280_20_LATER) {
+ if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
+ return false;
+ } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
return false;
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return false;
- ahp->ah_chipFullSleep = false;
-
+ ah->chip_fullsleep = false;
ath9k_hw_init_pll(ah, chan);
-
ath9k_hw_set_rfmode(ah, chan);
return true;
}
-static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
- struct ath9k_channel *chan)
-{
- if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; not marked as "
- "2GHz or 5GHz\n", chan->channel, chan->channelFlags);
- return NULL;
- }
-
- if (!IS_CHAN_OFDM(chan) &&
- !IS_CHAN_B(chan) &&
- !IS_CHAN_HT20(chan) &&
- !IS_CHAN_HT40(chan)) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; not marked as "
- "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
- chan->channel, chan->channelFlags);
- return NULL;
- }
-
- return ath9k_regd_check_channel(ah, chan);
-}
-
-static bool ath9k_hw_channel_change(struct ath_hal *ah,
+static bool ath9k_hw_channel_change(struct ath_hw *ah,
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
+ struct ieee80211_channel *channel = chan->chan;
u32 synthDelay, qnum;
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1714,7 +1672,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *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)) {
+ AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"Could not kill baseband RX\n");
return false;
@@ -1736,12 +1694,12 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
}
}
- if (ath9k_hw_set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- ath9k_regd_get_antenna_allowed(ah, chan),
- chan->maxRegTxPower * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->ah_powerLimit)) != 0) {
+ if (ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(ah, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit)) != 0) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"error init'ing transmit power\n");
return false;
@@ -1771,7 +1729,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
return true;
}
-static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
{
int bb_spur = AR_NO_SPUR;
int freq;
@@ -1805,9 +1763,9 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel
ath9k_hw_get_channel_centers(ah, chan, &centers);
freq = centers.synth_center;
- ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
+ ah->config.spurmode = SPUR_ENABLE_EEPROM;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+ cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
if (is2GHz)
cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
@@ -1918,9 +1876,9 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
/* workaround for gcc bug #37014 */
- volatile int tmp = abs(cur_vit_mask - bin);
+ volatile int tmp_v = abs(cur_vit_mask - bin);
- if (tmp < 75)
+ if (tmp_v < 75)
mask_amt = 1;
else
mask_amt = 0;
@@ -2021,7 +1979,7 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
}
-static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
{
int bb_spur = AR_NO_SPUR;
int bin, cur_bin;
@@ -2050,7 +2008,7 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
memset(&mask_p, 0, sizeof(int8_t) * 123);
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+ cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
if (AR_NO_SPUR == cur_bb_spur)
break;
cur_bb_spur = cur_bb_spur - (chan->channel * 10);
@@ -2119,9 +2077,9 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
/* workaround for gcc bug #37014 */
- volatile int tmp = abs(cur_vit_mask - bin);
+ volatile int tmp_v = abs(cur_vit_mask - bin);
- if (tmp < 75)
+ if (tmp_v < 75)
mask_amt = 1;
else
mask_amt = 0;
@@ -2222,58 +2180,47 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
}
-bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
- enum ath9k_ht_macmode macmode,
- u8 txchainmask, u8 rxchainmask,
- enum ath9k_ht_extprotspacing extprotspacing,
- bool bChannelChange, int *status)
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+ bool bChannelChange)
{
u32 saveLedState;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *curchan = ah->ah_curchan;
+ struct ath_softc *sc = ah->ah_sc;
+ struct ath9k_channel *curchan = ah->curchan;
u32 saveDefAntenna;
u32 macStaId1;
- int ecode;
- int i, rx_chainmask;
+ int i, rx_chainmask, r;
- ahp->ah_extprotspacing = extprotspacing;
- ahp->ah_txchainmask = txchainmask;
- ahp->ah_rxchainmask = rxchainmask;
+ ah->extprotspacing = sc->ht_extprotspacing;
+ ah->txchainmask = sc->tx_chainmask;
+ ah->rxchainmask = sc->rx_chainmask;
- if (AR_SREV_9280(ah)) {
- ahp->ah_txchainmask &= 0x3;
- ahp->ah_rxchainmask &= 0x3;
- }
-
- if (ath9k_hw_check_chan(ah, chan) == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; no mapping\n",
- chan->channel, chan->channelFlags);
- ecode = -EINVAL;
- goto bad;
+ 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)) {
- ecode = -EIO;
- goto bad;
- }
+ if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+ return -EIO;
if (curchan)
ath9k_hw_getnf(ah, curchan);
if (bChannelChange &&
- (ahp->ah_chipFullSleep != true) &&
- (ah->ah_curchan != NULL) &&
- (chan->channel != ah->ah_curchan->channel) &&
+ (ah->chip_fullsleep != true) &&
+ (ah->curchan != NULL) &&
+ (chan->channel != ah->curchan->channel) &&
((chan->channelFlags & CHANNEL_ALL) ==
- (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
+ (ah->curchan->channelFlags & CHANNEL_ALL)) &&
(!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
- !IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) {
+ !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
- if (ath9k_hw_channel_change(ah, chan, macmode)) {
- ath9k_hw_loadnf(ah, ah->ah_curchan);
+ if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
+ ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
- return true;
+ return 0;
}
}
@@ -2291,28 +2238,32 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
if (!ath9k_hw_chip_reset(ah, chan)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
- ecode = -EINVAL;
- goto bad;
+ return -EINVAL;
}
- if (AR_SREV_9280(ah)) {
- REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
- AR_GPIO_JTAG_DISABLE);
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
- if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
- if (IS_CHAN_5GHZ(chan))
- ath9k_hw_set_gpio(ah, 9, 0);
- else
- ath9k_hw_set_gpio(ah, 9, 1);
- }
- ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- }
+ r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
+ if (r)
+ return r;
- ecode = ath9k_hw_process_ini(ah, chan, macmode);
- if (ecode != 0) {
- ecode = -EINVAL;
- goto bad;
- }
+ /* Setup MFP options for CCMP */
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
+ /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+ * frames when constructing CCMP AAD. */
+ REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+ 0xc7ff);
+ ah->sw_mgmt_crypto = false;
+ } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+ /* Disable hardware crypto for management frames */
+ REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+ REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+ ah->sw_mgmt_crypto = true;
+ } else
+ ah->sw_mgmt_crypto = true;
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
ath9k_hw_set_delta_slope(ah, chan);
@@ -2322,61 +2273,56 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
else
ath9k_hw_spur_mitigate(ah, chan);
- if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
+ if (!ah->eep_ops->set_board_values(ah, chan)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"error setting board options\n");
- ecode = -EIO;
- goto bad;
+ return -EIO;
}
ath9k_hw_decrease_chain_power(ah, chan);
- REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
- REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
+ REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
+ REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
| macStaId1
| AR_STA_ID1_RTS_USE_DEF
- | (ah->ah_config.
+ | (ah->config.
ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
- | ahp->ah_staId1Defaults);
- ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+ | ah->sta_id1_defaults);
+ ath9k_hw_set_operating_mode(ah, ah->opmode);
- REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
- REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
+ REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+ REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
- REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
- REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
- ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+ REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
+ REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
+ ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
REG_WRITE(ah, AR_ISR, ~0);
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
- ecode = -EIO;
- goto bad;
- }
+ if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
+ return -EIO;
} else {
- if (!(ath9k_hw_set_channel(ah, chan))) {
- ecode = -EIO;
- goto bad;
- }
+ 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);
- ahp->ah_intrTxqs = 0;
- for (i = 0; i < ah->ah_caps.total_queues; i++)
+ ah->intr_txqs = 0;
+ for (i = 0; i < ah->caps.total_queues; i++)
ath9k_hw_resettxqueue(ah, i);
- ath9k_hw_init_interrupt_masks(ah, ah->ah_opmode);
+ ath9k_hw_init_interrupt_masks(ah, ah->opmode);
ath9k_hw_init_qos(ah);
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
ath9k_enable_rfkill(ah);
#endif
ath9k_hw_init_user_settings(ah);
@@ -2388,7 +2334,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_OBS, 8);
- if (ahp->ah_intrMitigation) {
+ if (ah->intr_mitigation) {
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
@@ -2396,12 +2342,10 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
ath9k_hw_init_bb(ah, chan);
- if (!ath9k_hw_init_cal(ah, chan)){
- ecode = -EIO;;
- goto bad;
- }
+ if (!ath9k_hw_init_cal(ah, chan))
+ return -EIO;;
- rx_chainmask = ahp->ah_rxchainmask;
+ rx_chainmask = ah->rxchainmask;
if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
@@ -2428,22 +2372,18 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
#endif
}
- return true;
-bad:
- if (status)
- *status = ecode;
- return false;
+ return 0;
}
/************************/
/* Key Cache Management */
/************************/
-bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
{
u32 keyType;
- if (entry >= ah->ah_caps.keycache_size) {
+ if (entry >= ah->caps.keycache_size) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
"entry %u out of range\n", entry);
return false;
@@ -2470,17 +2410,17 @@ bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
}
- if (ah->ah_curchan == NULL)
+ if (ah->curchan == NULL)
return true;
return true;
}
-bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac)
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
{
u32 macHi, macLo;
- if (entry >= ah->ah_caps.keycache_size) {
+ if (entry >= ah->caps.keycache_size) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
"entry %u out of range\n", entry);
return false;
@@ -2504,17 +2444,13 @@ bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac)
return true;
}
-bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
const struct ath9k_keyval *k,
- const u8 *mac, int xorKey)
+ const u8 *mac)
{
- const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ const struct ath9k_hw_capabilities *pCap = &ah->caps;
u32 key0, key1, key2, key3, key4;
u32 keyType;
- u32 xorMask = xorKey ?
- (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
- | ATH9K_KEY_XOR) : 0;
- struct ath_hal_5416 *ahp = AH5416(ah);
if (entry >= pCap->keycache_size) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
@@ -2530,7 +2466,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
"AES-CCM not supported by mac rev 0x%x\n",
- ah->ah_macRev);
+ ah->hw_version.macRev);
return false;
}
keyType = AR_KEYTABLE_TYPE_CCM;
@@ -2566,26 +2502,57 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
return false;
}
- key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
- key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
- key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
- key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
- key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
+ key0 = get_unaligned_le32(k->kv_val + 0);
+ key1 = get_unaligned_le16(k->kv_val + 4);
+ key2 = get_unaligned_le32(k->kv_val + 6);
+ key3 = get_unaligned_le16(k->kv_val + 10);
+ key4 = get_unaligned_le32(k->kv_val + 12);
if (k->kv_len <= LEN_WEP104)
key4 &= 0xff;
+ /*
+ * Note: Key cache registers access special memory area that requires
+ * two 32-bit writes to actually update the values in the internal
+ * memory. Consequently, the exact order and pairs used here must be
+ * maintained.
+ */
+
if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
u16 micentry = entry + 64;
+ /*
+ * Write inverted key[47:0] first to avoid Michael MIC errors
+ * on frames that could be sent or received at the same time.
+ * The correct key will be written in the end once everything
+ * else is ready.
+ */
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
+
+ /* Write key[95:48] */
REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+ /* Write key[127:96] and key type */
REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+ /* Write MAC address for the entry */
(void) ath9k_hw_keysetmac(ah, entry, mac);
- if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
+ if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
+ /*
+ * TKIP uses two key cache entries:
+ * Michael MIC TX/RX keys in the same key cache entry
+ * (idx = main index + 64):
+ * key0 [31:0] = RX key [31:0]
+ * key1 [15:0] = TX key [31:16]
+ * key1 [31:16] = reserved
+ * key2 [31:0] = RX key [63:32]
+ * key3 [15:0] = TX key [15:0]
+ * key3 [31:16] = reserved
+ * key4 [31:0] = TX key [63:32]
+ */
u32 mic0, mic1, mic2, mic3, mic4;
mic0 = get_unaligned_le32(k->kv_mic + 0);
@@ -2593,51 +2560,90 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
mic4 = get_unaligned_le32(k->kv_txmic + 4);
+
+ /* Write RX[31:0] and TX[31:16] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
+
+ /* Write RX[63:32] and TX[15:0] */
REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
+
+ /* Write TX[63:32] and keyType(reserved) */
REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
AR_KEYTABLE_TYPE_CLR);
} else {
+ /*
+ * TKIP uses four key cache entries (two for group
+ * keys):
+ * Michael MIC TX/RX keys are in different key cache
+ * entries (idx = main index + 64 for TX and
+ * main index + 32 + 96 for RX):
+ * key0 [31:0] = TX/RX MIC key [31:0]
+ * key1 [31:0] = reserved
+ * key2 [31:0] = TX/RX MIC key [63:32]
+ * key3 [31:0] = reserved
+ * key4 [31:0] = reserved
+ *
+ * Upper layer code will call this function separately
+ * for TX and RX keys when these registers offsets are
+ * used.
+ */
u32 mic0, mic2;
mic0 = get_unaligned_le32(k->kv_mic + 0);
mic2 = get_unaligned_le32(k->kv_mic + 4);
+
+ /* Write MIC key[31:0] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+
+ /* Write MIC key[63:32] */
REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+ /* Write TX[63:32] and keyType(reserved) */
REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
AR_KEYTABLE_TYPE_CLR);
}
+
+ /* MAC address registers are reserved for the MIC entry */
REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
+
+ /*
+ * Write the correct (un-inverted) key[47:0] last to enable
+ * TKIP now that all other registers are set with correct
+ * values.
+ */
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
} else {
+ /* Write key[47:0] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+
+ /* Write key[95:48] */
REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+ /* Write key[127:96] and key type */
REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+ /* Write MAC address for the entry */
(void) ath9k_hw_keysetmac(ah, entry, mac);
}
- if (ah->ah_curchan == NULL)
- return true;
-
return true;
}
-bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
{
- if (entry < ah->ah_caps.keycache_size) {
+ if (entry < ah->caps.keycache_size) {
u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
if (val & AR_KEYTABLE_VALID)
return true;
@@ -2649,7 +2655,7 @@ bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
/* Power Management (Chipset) */
/******************************/
-static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
+static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
{
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
if (setChip) {
@@ -2658,16 +2664,16 @@ static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
if (!AR_SREV_9100(ah))
REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
- REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
+ REG_CLR_BIT(ah, (AR_RTC_RESET),
AR_RTC_RESET_EN);
}
}
-static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
+static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
{
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
if (setChip) {
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
REG_WRITE(ah, AR_RTC_FORCE_WAKE,
@@ -2679,8 +2685,7 @@ static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
}
}
-static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
- int setChip)
+static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
{
u32 val;
int i;
@@ -2721,20 +2726,18 @@ static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
return true;
}
-bool ath9k_hw_setpower(struct ath_hal *ah,
- enum ath9k_power_mode mode)
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ int status = true, setChip = true;
static const char *modes[] = {
"AWAKE",
"FULL-SLEEP",
"NETWORK SLEEP",
"UNDEFINED"
};
- int status = true, setChip = true;
DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n",
- modes[ahp->ah_powerMode], modes[mode],
+ modes[ah->power_mode], modes[mode],
setChip ? "set chip " : "");
switch (mode) {
@@ -2743,7 +2746,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah,
break;
case ATH9K_PM_FULL_SLEEP:
ath9k_set_power_sleep(ah, setChip);
- ahp->ah_chipFullSleep = true;
+ ah->chip_fullsleep = true;
break;
case ATH9K_PM_NETWORK_SLEEP:
ath9k_set_power_network_sleep(ah, setChip);
@@ -2753,41 +2756,57 @@ bool ath9k_hw_setpower(struct ath_hal *ah,
"Unknown power mode %u\n", mode);
return false;
}
- ahp->ah_powerMode = mode;
+ ah->power_mode = mode;
return status;
}
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers. Hence the 9 writes.
+ */
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u8 i;
- if (ah->ah_isPciExpress != true)
+ if (ah->is_pciexpress != true)
return;
- if (ah->ah_config.pcie_powersave_enable == 2)
+ /* Do not touch SerDes registers */
+ if (ah->config.pcie_powersave_enable == 2)
return;
+ /* Nothing to do on restore for 11N */
if (restore)
return;
if (AR_SREV_9280_20_OR_LATER(ah)) {
- for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
- REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
- INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
+ /*
+ * AR9280 2.0 or later chips use SerDes values from the
+ * initvals.h initialized depending on chipset during
+ * ath9k_hw_do_attach()
+ */
+ for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
+ REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
+ INI_RA(&ah->iniPcieSerdes, i, 1));
}
- udelay(1000);
} else if (AR_SREV_9280(ah) &&
- (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
+ (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+ /* RX shut off when elecidle is asserted */
REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
- if (ah->ah_config.pcie_clock_req)
+ /* Shut off CLKREQ active in L1 */
+ if (ah->config.pcie_clock_req)
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
else
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
@@ -2796,42 +2815,59 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
+ /* Load the new settings */
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
- udelay(1000);
} else {
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+ /* RX shut off when elecidle is asserted */
REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+
+ /*
+ * Ignore ah->ah_config.pcie_clock_req setting for
+ * pre-AR9280 11n
+ */
REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
+
REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
+
+ /* Load the new settings */
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
}
+ udelay(1000);
+
+ /* set bit 19 to allow forcing of pcie core into L1 state */
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
- if (ah->ah_config.pcie_waen) {
- REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
+ /* Several PCIe massages to ensure proper behaviour */
+ if (ah->config.pcie_waen) {
+ REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
} else {
if (AR_SREV_9285(ah))
REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
+ /*
+ * On AR9280 chips bit 22 of 0x4004 needs to be set to
+ * otherwise card may disappear.
+ */
else if (AR_SREV_9280(ah))
REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
else
REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
}
-
}
/**********************/
/* Interrupt Handling */
/**********************/
-bool ath9k_hw_intrpend(struct ath_hal *ah)
+bool ath9k_hw_intrpend(struct ath_hw *ah)
{
u32 host_isr;
@@ -2850,14 +2886,13 @@ bool ath9k_hw_intrpend(struct ath_hal *ah)
return false;
}
-bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
{
u32 isr = 0;
u32 mask2 = 0;
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
u32 sync_cause = 0;
bool fatal_int = false;
- struct ath_hal_5416 *ahp = AH5416(ah);
if (!AR_SREV_9100(ah)) {
if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
@@ -2895,6 +2930,8 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
mask2 |= ATH9K_INT_GTT;
if (isr2 & AR_ISR_S2_CST)
mask2 |= ATH9K_INT_CST;
+ if (isr2 & AR_ISR_S2_TSFOOR)
+ mask2 |= ATH9K_INT_TSFOOR;
}
isr = REG_READ(ah, AR_ISR_RAC);
@@ -2905,7 +2942,7 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
*masked = isr & ATH9K_INT_COMMON;
- if (ahp->ah_intrMitigation) {
+ if (ah->intr_mitigation) {
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
*masked |= ATH9K_INT_RX;
}
@@ -2920,12 +2957,12 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
*masked |= ATH9K_INT_TX;
s0_s = REG_READ(ah, AR_ISR_S0_S);
- ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
- ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+ ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+ ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
s1_s = REG_READ(ah, AR_ISR_S1_S);
- ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
- ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+ ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+ ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
}
if (isr & AR_ISR_RXORN) {
@@ -2982,17 +3019,16 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
return true;
}
-enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
{
- return AH5416(ah)->ah_maskReg;
+ return ah->mask_reg;
}
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- u32 omask = ahp->ah_maskReg;
+ u32 omask = ah->mask_reg;
u32 mask, mask2;
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
@@ -3013,18 +3049,18 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
mask2 = 0;
if (ints & ATH9K_INT_TX) {
- if (ahp->ah_txOkInterruptMask)
+ if (ah->txok_interrupt_mask)
mask |= AR_IMR_TXOK;
- if (ahp->ah_txDescInterruptMask)
+ if (ah->txdesc_interrupt_mask)
mask |= AR_IMR_TXDESC;
- if (ahp->ah_txErrInterruptMask)
+ if (ah->txerr_interrupt_mask)
mask |= AR_IMR_TXERR;
- if (ahp->ah_txEolInterruptMask)
+ if (ah->txeol_interrupt_mask)
mask |= AR_IMR_TXEOL;
}
if (ints & ATH9K_INT_RX) {
mask |= AR_IMR_RXERR;
- if (ahp->ah_intrMitigation)
+ if (ah->intr_mitigation)
mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
else
mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -3041,7 +3077,9 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
if (ints & ATH9K_INT_DTIMSYNC)
mask2 |= AR_IMR_S2_DTIMSYNC;
if (ints & ATH9K_INT_CABEND)
- mask2 |= (AR_IMR_S2_CABEND);
+ mask2 |= AR_IMR_S2_CABEND;
+ if (ints & ATH9K_INT_TSFOOR)
+ mask2 |= AR_IMR_S2_TSFOOR;
}
if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
@@ -3062,7 +3100,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
AR_IMR_S2_TSFOOR |
AR_IMR_S2_GTT | AR_IMR_S2_CST);
REG_WRITE(ah, AR_IMR_S2, mask | mask2);
- ahp->ah_maskReg = ints;
+ ah->mask_reg = ints;
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
if (ints & ATH9K_INT_TIM_TIMER)
@@ -3096,14 +3134,13 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
/* Beacon Handling */
/*******************/
-void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int flags = 0;
- ahp->ah_beaconInterval = beacon_period;
+ ah->beacon_interval = beacon_period;
- switch (ah->ah_opmode) {
+ switch (ah->opmode) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_MONITOR:
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
@@ -3116,18 +3153,18 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
REG_WRITE(ah, AR_NEXT_NDP_TIMER,
TU_TO_USEC(next_beacon +
- (ahp->ah_atimWindow ? ahp->
- ah_atimWindow : 1)));
+ (ah->atim_window ? ah->
+ atim_window : 1)));
flags |= AR_NDP_TIMER_EN;
case NL80211_IFTYPE_AP:
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
TU_TO_USEC(next_beacon -
- ah->ah_config.
+ ah->config.
dma_beacon_response_time));
REG_WRITE(ah, AR_NEXT_SWBA,
TU_TO_USEC(next_beacon -
- ah->ah_config.
+ ah->config.
sw_beacon_response_time));
flags |=
AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
@@ -3135,7 +3172,7 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
default:
DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
"%s: unsupported opmode: %d\n",
- __func__, ah->ah_opmode);
+ __func__, ah->opmode);
return;
break;
}
@@ -3154,11 +3191,11 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
REG_SET_BIT(ah, AR_TIMER_MODE, flags);
}
-void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
+void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
const struct ath9k_beacon_state *bs)
{
u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
@@ -3212,43 +3249,46 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
AR_DTIM_TIMER_EN);
+ /* TSF Out of Range Threshold */
+ REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
}
/*******************/
/* HW Capabilities */
/*******************/
-bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
+bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
u16 capField = 0, eeval;
- eeval = ath9k_hw_get_eeprom(ah, EEP_REG_0);
+ eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
+ ah->regulatory.current_rd = eeval;
- ah->ah_currentRD = eeval;
-
- eeval = ath9k_hw_get_eeprom(ah, EEP_REG_1);
- ah->ah_currentRDExt = eeval;
-
- capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP);
-
- if (ah->ah_opmode != NL80211_IFTYPE_AP &&
- ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
- if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
- ah->ah_currentRD += 5;
- else if (ah->ah_currentRD == 0x41)
- ah->ah_currentRD = 0x43;
+ eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ eeval |= AR9285_RDEXT_DEFAULT;
+ ah->regulatory.current_rd_ext = eeval;
+
+ capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
+
+ if (ah->opmode != NL80211_IFTYPE_AP &&
+ ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+ if (ah->regulatory.current_rd == 0x64 ||
+ ah->regulatory.current_rd == 0x65)
+ ah->regulatory.current_rd += 5;
+ else if (ah->regulatory.current_rd == 0x41)
+ ah->regulatory.current_rd = 0x43;
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "regdomain mapped to 0x%x\n", ah->ah_currentRD);
+ "regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
}
- eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE);
+ eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
if (eeval & AR5416_OPFLAGS_11A) {
set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
- if (ah->ah_config.ht_enable) {
+ if (ah->config.ht_enable) {
if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
set_bit(ATH9K_MODE_11NA_HT20,
pCap->wireless_modes);
@@ -3264,7 +3304,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
if (eeval & AR5416_OPFLAGS_11G) {
set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
- if (ah->ah_config.ht_enable) {
+ if (ah->config.ht_enable) {
if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
set_bit(ATH9K_MODE_11NG_HT20,
pCap->wireless_modes);
@@ -3277,18 +3317,15 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
}
}
- pCap->tx_chainmask = ath9k_hw_get_eeprom(ah, EEP_TX_MASK);
- if ((ah->ah_isPciExpress)
- || (eeval & AR5416_OPFLAGS_11A)) {
- pCap->rx_chainmask =
- ath9k_hw_get_eeprom(ah, EEP_RX_MASK);
- } else {
- pCap->rx_chainmask =
- (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
- }
+ pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
+ if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
+ !(eeval & AR5416_OPFLAGS_11A))
+ pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+ else
+ pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
- if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
- ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
+ if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
+ ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
pCap->low_2ghz_chan = 2312;
pCap->high_2ghz_chan = 2732;
@@ -3306,7 +3343,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
- if (ah->ah_config.ht_enable)
+ if (ah->config.ht_enable)
pCap->hw_caps |= ATH9K_HW_CAP_HT;
else
pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
@@ -3332,7 +3369,9 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->num_mr_retries = 4;
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ pCap->num_gpio_pins = AR9285_NUM_GPIO;
+ else if (AR_SREV_9280_10_OR_LATER(ah))
pCap->num_gpio_pins = AR928X_NUM_GPIO;
else
pCap->num_gpio_pins = AR_NUM_GPIO;
@@ -3355,22 +3394,22 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- ah->ah_rfsilent = ath9k_hw_get_eeprom(ah, EEP_RF_SILENT);
- if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
- ah->ah_rfkill_gpio =
- MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
- ah->ah_rfkill_polarity =
- MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
+ ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
+ if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
+ ah->rfkill_gpio =
+ MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
+ ah->rfkill_polarity =
+ MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
}
#endif
- if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
- (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
- (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
- (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
- (ah->ah_macVersion == AR_SREV_VERSION_9280))
+ if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9280))
pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
else
pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
@@ -3380,7 +3419,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
else
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
- if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
+ if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
pCap->reg_cap =
AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
@@ -3395,19 +3434,22 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
pCap->num_antcfg_5ghz =
- ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
+ ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
pCap->num_antcfg_2ghz =
- ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
+ ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
+
+ if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
+ pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
+ ah->btactive_gpio = 6;
+ ah->wlanactive_gpio = 5;
+ }
return true;
}
-bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
u32 capability, u32 *result)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-
switch (type) {
case ATH9K_CAP_CIPHER:
switch (capability) {
@@ -3426,23 +3468,17 @@ bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
case 0:
return true;
case 1:
- return (ahp->ah_staId1Defaults &
+ return (ah->sta_id1_defaults &
AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
false;
}
case ATH9K_CAP_TKIP_SPLIT:
- return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
+ return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
false : true;
- case ATH9K_CAP_WME_TKIPMIC:
- return 0;
- case ATH9K_CAP_PHYCOUNTERS:
- return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
case ATH9K_CAP_DIVERSITY:
return (REG_READ(ah, AR_PHY_CCK_DETECT) &
AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
true : false;
- case ATH9K_CAP_PHYDIAG:
- return true;
case ATH9K_CAP_MCAST_KEYSRCH:
switch (capability) {
case 0:
@@ -3451,57 +3487,48 @@ bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
return false;
} else {
- return (ahp->ah_staId1Defaults &
+ return (ah->sta_id1_defaults &
AR_STA_ID1_MCAST_KSRCH) ? true :
false;
}
}
return false;
- case ATH9K_CAP_TSF_ADJUST:
- return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
- true : false;
- case ATH9K_CAP_RFSILENT:
- if (capability == 3)
- return false;
- case ATH9K_CAP_ANT_CFG_2GHZ:
- *result = pCap->num_antcfg_2ghz;
- return true;
- case ATH9K_CAP_ANT_CFG_5GHZ:
- *result = pCap->num_antcfg_5ghz;
- return true;
case ATH9K_CAP_TXPOW:
switch (capability) {
case 0:
return 0;
case 1:
- *result = ah->ah_powerLimit;
+ *result = ah->regulatory.power_limit;
return 0;
case 2:
- *result = ah->ah_maxPowerLevel;
+ *result = ah->regulatory.max_power_level;
return 0;
case 3:
- *result = ah->ah_tpScale;
+ *result = ah->regulatory.tp_scale;
return 0;
}
return false;
+ case ATH9K_CAP_DS:
+ return (AR_SREV_9280_20_OR_LATER(ah) &&
+ (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
+ ? false : true;
default:
return false;
}
}
-bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
u32 capability, u32 setting, int *status)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 v;
switch (type) {
case ATH9K_CAP_TKIP_MIC:
if (setting)
- ahp->ah_staId1Defaults |=
+ ah->sta_id1_defaults |=
AR_STA_ID1_CRPT_MIC_ENABLE;
else
- ahp->ah_staId1Defaults &=
+ ah->sta_id1_defaults &=
~AR_STA_ID1_CRPT_MIC_ENABLE;
return true;
case ATH9K_CAP_DIVERSITY:
@@ -3514,15 +3541,9 @@ bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
return true;
case ATH9K_CAP_MCAST_KEYSRCH:
if (setting)
- ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
+ ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
else
- ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
- return true;
- case ATH9K_CAP_TSF_ADJUST:
- if (setting)
- ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
- else
- ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+ ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
return true;
default:
return false;
@@ -3533,7 +3554,7 @@ bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
/* GPIO / RFKILL / Antennae */
/****************************/
-static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
u32 gpio, u32 type)
{
int addr;
@@ -3561,11 +3582,11 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
}
}
-void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
{
u32 gpio_shift;
- ASSERT(gpio < ah->ah_caps.num_gpio_pins);
+ ASSERT(gpio < ah->caps.num_gpio_pins);
gpio_shift = gpio << 1;
@@ -3575,22 +3596,23 @@ void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
(AR_GPIO_OE_OUT_DRV << gpio_shift));
}
-u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
{
- if (gpio >= ah->ah_caps.num_gpio_pins)
+#define MS_REG_READ(x, y) \
+ (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
+
+ if (gpio >= ah->caps.num_gpio_pins)
return 0xffffffff;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- return (MS
- (REG_READ(ah, AR_GPIO_IN_OUT),
- AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
- } else {
- return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
- AR_GPIO_BIT(gpio)) != 0;
- }
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ return MS_REG_READ(AR9285, gpio) != 0;
+ else if (AR_SREV_9280_10_OR_LATER(ah))
+ return MS_REG_READ(AR928X, gpio) != 0;
+ else
+ return MS_REG_READ(AR, gpio) != 0;
}
-void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
u32 ah_signal_type)
{
u32 gpio_shift;
@@ -3605,14 +3627,14 @@ void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
(AR_GPIO_OE_OUT_DRV << gpio_shift));
}
-void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val)
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
{
REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
AR_GPIO_BIT(gpio));
}
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hal *ah)
+void ath9k_enable_rfkill(struct ath_hw *ah)
{
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
@@ -3620,50 +3642,28 @@ void ath9k_enable_rfkill(struct ath_hal *ah)
REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
AR_GPIO_INPUT_MUX2_RFSILENT);
- ath9k_hw_cfg_gpio_input(ah, ah->ah_rfkill_gpio);
+ ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
}
#endif
-int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
-{
- struct ath9k_channel *chan = ah->ah_curchan;
- const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
- u16 ant_config;
- u32 halNumAntConfig;
-
- halNumAntConfig = IS_CHAN_2GHZ(chan) ?
- pCap->num_antcfg_2ghz : pCap->num_antcfg_5ghz;
-
- if (cfg < halNumAntConfig) {
- if (!ath9k_hw_get_eeprom_antenna_cfg(ah, chan,
- cfg, &ant_config)) {
- REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
{
return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
}
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
{
REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
}
-bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
+bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
enum ath9k_ant_setting settings,
struct ath9k_channel *chan,
u8 *tx_chainmask,
u8 *rx_chainmask,
u8 *antenna_cfgd)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
static u8 tx_chainmask_cfg, rx_chainmask_cfg;
if (AR_SREV_9280(ah)) {
@@ -3680,7 +3680,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
*antenna_cfgd = true;
break;
case ATH9K_ANT_FIXED_B:
- if (ah->ah_caps.tx_chainmask >
+ if (ah->caps.tx_chainmask >
ATH9K_ANTENNA1_CHAINMASK) {
*tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
}
@@ -3696,7 +3696,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
break;
}
} else {
- ahp->ah_diversityControl = settings;
+ ah->diversity_control = settings;
}
return true;
@@ -3706,7 +3706,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
/* General Operation */
/*********************/
-u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
{
u32 bits = REG_READ(ah, AR_RX_FILTER);
u32 phybits = REG_READ(ah, AR_PHY_ERR);
@@ -3719,7 +3719,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
return bits;
}
-void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
{
u32 phybits;
@@ -3739,12 +3739,12 @@ void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
}
-bool ath9k_hw_phy_disable(struct ath_hal *ah)
+bool ath9k_hw_phy_disable(struct ath_hw *ah)
{
return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
}
-bool ath9k_hw_disable(struct ath_hal *ah)
+bool ath9k_hw_disable(struct ath_hw *ah)
{
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return false;
@@ -3752,82 +3752,54 @@ bool ath9k_hw_disable(struct ath_hal *ah)
return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
}
-bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
+bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
{
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ath9k_channel *chan = ah->curchan;
+ struct ieee80211_channel *channel = chan->chan;
- ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
+ ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
- if (ath9k_hw_set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- ath9k_regd_get_antenna_allowed(ah, chan),
- chan->maxRegTxPower * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->ah_powerLimit)) != 0)
+ if (ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(ah, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit)) != 0)
return false;
return true;
}
-void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
-}
-
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
-
- return true;
+ memcpy(ah->macaddr, mac, ETH_ALEN);
}
-void ath9k_hw_setopmode(struct ath_hal *ah)
+void ath9k_hw_setopmode(struct ath_hw *ah)
{
- ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+ ath9k_hw_set_operating_mode(ah, ah->opmode);
}
-void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1)
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
{
REG_WRITE(ah, AR_MCAST_FIL0, filter0);
REG_WRITE(ah, AR_MCAST_FIL1, filter1);
}
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
+void ath9k_hw_setbssidmask(struct ath_softc *sc)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
+ REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+ REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
}
-bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
+void ath9k_hw_write_associd(struct ath_softc *sc)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
-
- REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
- REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
-
- return true;
-}
-
-void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
- ahp->ah_assocId = assocId;
-
- REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
- REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
- ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+ REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
+ REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
+ ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
}
-u64 ath9k_hw_gettsf64(struct ath_hal *ah)
+u64 ath9k_hw_gettsf64(struct ath_hw *ah)
{
u64 tsf;
@@ -3837,7 +3809,13 @@ u64 ath9k_hw_gettsf64(struct ath_hal *ah)
return tsf;
}
-void ath9k_hw_reset_tsf(struct ath_hal *ah)
+void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
+{
+ REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
+ REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
+}
+
+void ath9k_hw_reset_tsf(struct ath_hw *ah)
{
int count;
@@ -3854,42 +3832,65 @@ void ath9k_hw_reset_tsf(struct ath_hal *ah)
REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
}
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (setting)
- ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+ ah->misc_mode |= AR_PCU_TX_ADD_TSF;
else
- ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+ ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
return true;
}
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us);
- ahp->ah_slottime = (u32) -1;
+ ah->slottime = (u32) -1;
return false;
} else {
REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
- ahp->ah_slottime = us;
+ ah->slottime = us;
return true;
}
}
-void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
{
u32 macmode;
if (mode == ATH9K_HT_MACMODE_2040 &&
- !ah->ah_config.cwm_ignore_extcca)
+ !ah->config.cwm_ignore_extcca)
macmode = AR_2040_JOINED_RX_CLEAR;
else
macmode = 0;
REG_WRITE(ah, AR_2040_MODE, macmode);
}
+
+/***************************/
+/* Bluetooth Coexistence */
+/***************************/
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
+ /* connect bt_active to baseband */
+ REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+ (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+ AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+
+ REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+ AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+
+ /* Set input mux for bt_active to gpio pin */
+ REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+ AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+ ah->btactive_gpio);
+
+ /* Configure the desired gpio port for input */
+ ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
+
+ /* Configure the desired GPIO port for TX_FRAME output */
+ ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
+ AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
index 91d8f594af8..dc681f011fd 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -19,1062 +19,629 @@
#include <linux/if_ether.h>
#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "mac.h"
+#include "ani.h"
+#include "eeprom.h"
+#include "calib.h"
+#include "regd.h"
+#include "reg.h"
+#include "phy.h"
+
+#define ATHEROS_VENDOR_ID 0x168c
+#define AR5416_DEVID_PCI 0x0023
+#define AR5416_DEVID_PCIE 0x0024
+#define AR9160_DEVID_PCI 0x0027
+#define AR9280_DEVID_PCI 0x0029
+#define AR9280_DEVID_PCIE 0x002a
+#define AR9285_DEVID_PCIE 0x002b
+#define AR5416_AR9100_DEVID 0x000b
+#define AR_SUBVENDOR_ID_NOG 0x0e11
+#define AR_SUBVENDOR_ID_NEW_A 0x7065
+#define AR5416_MAGIC 0x19641014
+
+/* Register read/write primitives */
+#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
+#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
+
+#define SM(_v, _f) (((_v) << _f##_S) & _f)
+#define MS(_v, _f) (((_v) & _f) >> _f##_S)
+#define REG_RMW(_a, _r, _set, _clr) \
+ REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
+#define REG_RMW_FIELD(_a, _r, _f, _v) \
+ REG_WRITE(_a, _r, \
+ (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+#define REG_SET_BIT(_a, _r, _f) \
+ REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
+#define REG_CLR_BIT(_a, _r, _f) \
+ REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
-struct ar5416_desc {
- u32 ds_link;
- u32 ds_data;
- u32 ds_ctl0;
- u32 ds_ctl1;
- union {
- struct {
- u32 ctl2;
- u32 ctl3;
- u32 ctl4;
- u32 ctl5;
- u32 ctl6;
- u32 ctl7;
- u32 ctl8;
- u32 ctl9;
- u32 ctl10;
- u32 ctl11;
- u32 status0;
- u32 status1;
- u32 status2;
- u32 status3;
- u32 status4;
- u32 status5;
- u32 status6;
- u32 status7;
- u32 status8;
- u32 status9;
- } tx;
- struct {
- u32 status0;
- u32 status1;
- u32 status2;
- u32 status3;
- u32 status4;
- u32 status5;
- u32 status6;
- u32 status7;
- u32 status8;
- } rx;
- } u;
-} __packed;
-
-#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
-#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
-
-#define ds_ctl2 u.tx.ctl2
-#define ds_ctl3 u.tx.ctl3
-#define ds_ctl4 u.tx.ctl4
-#define ds_ctl5 u.tx.ctl5
-#define ds_ctl6 u.tx.ctl6
-#define ds_ctl7 u.tx.ctl7
-#define ds_ctl8 u.tx.ctl8
-#define ds_ctl9 u.tx.ctl9
-#define ds_ctl10 u.tx.ctl10
-#define ds_ctl11 u.tx.ctl11
-
-#define ds_txstatus0 u.tx.status0
-#define ds_txstatus1 u.tx.status1
-#define ds_txstatus2 u.tx.status2
-#define ds_txstatus3 u.tx.status3
-#define ds_txstatus4 u.tx.status4
-#define ds_txstatus5 u.tx.status5
-#define ds_txstatus6 u.tx.status6
-#define ds_txstatus7 u.tx.status7
-#define ds_txstatus8 u.tx.status8
-#define ds_txstatus9 u.tx.status9
-
-#define ds_rxstatus0 u.rx.status0
-#define ds_rxstatus1 u.rx.status1
-#define ds_rxstatus2 u.rx.status2
-#define ds_rxstatus3 u.rx.status3
-#define ds_rxstatus4 u.rx.status4
-#define ds_rxstatus5 u.rx.status5
-#define ds_rxstatus6 u.rx.status6
-#define ds_rxstatus7 u.rx.status7
-#define ds_rxstatus8 u.rx.status8
-
-#define AR_FrameLen 0x00000fff
-#define AR_VirtMoreFrag 0x00001000
-#define AR_TxCtlRsvd00 0x0000e000
-#define AR_XmitPower 0x003f0000
-#define AR_XmitPower_S 16
-#define AR_RTSEnable 0x00400000
-#define AR_VEOL 0x00800000
-#define AR_ClrDestMask 0x01000000
-#define AR_TxCtlRsvd01 0x1e000000
-#define AR_TxIntrReq 0x20000000
-#define AR_DestIdxValid 0x40000000
-#define AR_CTSEnable 0x80000000
-
-#define AR_BufLen 0x00000fff
-#define AR_TxMore 0x00001000
-#define AR_DestIdx 0x000fe000
-#define AR_DestIdx_S 13
-#define AR_FrameType 0x00f00000
-#define AR_FrameType_S 20
-#define AR_NoAck 0x01000000
-#define AR_InsertTS 0x02000000
-#define AR_CorruptFCS 0x04000000
-#define AR_ExtOnly 0x08000000
-#define AR_ExtAndCtl 0x10000000
-#define AR_MoreAggr 0x20000000
-#define AR_IsAggr 0x40000000
-
-#define AR_BurstDur 0x00007fff
-#define AR_BurstDur_S 0
-#define AR_DurUpdateEna 0x00008000
-#define AR_XmitDataTries0 0x000f0000
-#define AR_XmitDataTries0_S 16
-#define AR_XmitDataTries1 0x00f00000
-#define AR_XmitDataTries1_S 20
-#define AR_XmitDataTries2 0x0f000000
-#define AR_XmitDataTries2_S 24
-#define AR_XmitDataTries3 0xf0000000
-#define AR_XmitDataTries3_S 28
-
-#define AR_XmitRate0 0x000000ff
-#define AR_XmitRate0_S 0
-#define AR_XmitRate1 0x0000ff00
-#define AR_XmitRate1_S 8
-#define AR_XmitRate2 0x00ff0000
-#define AR_XmitRate2_S 16
-#define AR_XmitRate3 0xff000000
-#define AR_XmitRate3_S 24
-
-#define AR_PacketDur0 0x00007fff
-#define AR_PacketDur0_S 0
-#define AR_RTSCTSQual0 0x00008000
-#define AR_PacketDur1 0x7fff0000
-#define AR_PacketDur1_S 16
-#define AR_RTSCTSQual1 0x80000000
-
-#define AR_PacketDur2 0x00007fff
-#define AR_PacketDur2_S 0
-#define AR_RTSCTSQual2 0x00008000
-#define AR_PacketDur3 0x7fff0000
-#define AR_PacketDur3_S 16
-#define AR_RTSCTSQual3 0x80000000
-
-#define AR_AggrLen 0x0000ffff
-#define AR_AggrLen_S 0
-#define AR_TxCtlRsvd60 0x00030000
-#define AR_PadDelim 0x03fc0000
-#define AR_PadDelim_S 18
-#define AR_EncrType 0x0c000000
-#define AR_EncrType_S 26
-#define AR_TxCtlRsvd61 0xf0000000
-
-#define AR_2040_0 0x00000001
-#define AR_GI0 0x00000002
-#define AR_ChainSel0 0x0000001c
-#define AR_ChainSel0_S 2
-#define AR_2040_1 0x00000020
-#define AR_GI1 0x00000040
-#define AR_ChainSel1 0x00000380
-#define AR_ChainSel1_S 7
-#define AR_2040_2 0x00000400
-#define AR_GI2 0x00000800
-#define AR_ChainSel2 0x00007000
-#define AR_ChainSel2_S 12
-#define AR_2040_3 0x00008000
-#define AR_GI3 0x00010000
-#define AR_ChainSel3 0x000e0000
-#define AR_ChainSel3_S 17
-#define AR_RTSCTSRate 0x0ff00000
-#define AR_RTSCTSRate_S 20
-#define AR_TxCtlRsvd70 0xf0000000
-
-#define AR_TxRSSIAnt00 0x000000ff
-#define AR_TxRSSIAnt00_S 0
-#define AR_TxRSSIAnt01 0x0000ff00
-#define AR_TxRSSIAnt01_S 8
-#define AR_TxRSSIAnt02 0x00ff0000
-#define AR_TxRSSIAnt02_S 16
-#define AR_TxStatusRsvd00 0x3f000000
-#define AR_TxBaStatus 0x40000000
-#define AR_TxStatusRsvd01 0x80000000
-
-#define AR_FrmXmitOK 0x00000001
-#define AR_ExcessiveRetries 0x00000002
-#define AR_FIFOUnderrun 0x00000004
-#define AR_Filtered 0x00000008
-#define AR_RTSFailCnt 0x000000f0
-#define AR_RTSFailCnt_S 4
-#define AR_DataFailCnt 0x00000f00
-#define AR_DataFailCnt_S 8
-#define AR_VirtRetryCnt 0x0000f000
-#define AR_VirtRetryCnt_S 12
-#define AR_TxDelimUnderrun 0x00010000
-#define AR_TxDataUnderrun 0x00020000
-#define AR_DescCfgErr 0x00040000
-#define AR_TxTimerExpired 0x00080000
-#define AR_TxStatusRsvd10 0xfff00000
-
-#define AR_SendTimestamp ds_txstatus2
-#define AR_BaBitmapLow ds_txstatus3
-#define AR_BaBitmapHigh ds_txstatus4
-
-#define AR_TxRSSIAnt10 0x000000ff
-#define AR_TxRSSIAnt10_S 0
-#define AR_TxRSSIAnt11 0x0000ff00
-#define AR_TxRSSIAnt11_S 8
-#define AR_TxRSSIAnt12 0x00ff0000
-#define AR_TxRSSIAnt12_S 16
-#define AR_TxRSSICombined 0xff000000
-#define AR_TxRSSICombined_S 24
-
-#define AR_TxEVM0 ds_txstatus5
-#define AR_TxEVM1 ds_txstatus6
-#define AR_TxEVM2 ds_txstatus7
-
-#define AR_TxDone 0x00000001
-#define AR_SeqNum 0x00001ffe
-#define AR_SeqNum_S 1
-#define AR_TxStatusRsvd80 0x0001e000
-#define AR_TxOpExceeded 0x00020000
-#define AR_TxStatusRsvd81 0x001c0000
-#define AR_FinalTxIdx 0x00600000
-#define AR_FinalTxIdx_S 21
-#define AR_TxStatusRsvd82 0x01800000
-#define AR_PowerMgmt 0x02000000
-#define AR_TxStatusRsvd83 0xfc000000
-
-#define AR_RxCTLRsvd00 0xffffffff
-
-#define AR_BufLen 0x00000fff
-#define AR_RxCtlRsvd00 0x00001000
-#define AR_RxIntrReq 0x00002000
-#define AR_RxCtlRsvd01 0xffffc000
-
-#define AR_RxRSSIAnt00 0x000000ff
-#define AR_RxRSSIAnt00_S 0
-#define AR_RxRSSIAnt01 0x0000ff00
-#define AR_RxRSSIAnt01_S 8
-#define AR_RxRSSIAnt02 0x00ff0000
-#define AR_RxRSSIAnt02_S 16
-#define AR_RxRate 0xff000000
-#define AR_RxRate_S 24
-#define AR_RxStatusRsvd00 0xff000000
-
-#define AR_DataLen 0x00000fff
-#define AR_RxMore 0x00001000
-#define AR_NumDelim 0x003fc000
-#define AR_NumDelim_S 14
-#define AR_RxStatusRsvd10 0xff800000
-
-#define AR_RcvTimestamp ds_rxstatus2
-
-#define AR_GI 0x00000001
-#define AR_2040 0x00000002
-#define AR_Parallel40 0x00000004
-#define AR_Parallel40_S 2
-#define AR_RxStatusRsvd30 0x000000f8
-#define AR_RxAntenna 0xffffff00
-#define AR_RxAntenna_S 8
-
-#define AR_RxRSSIAnt10 0x000000ff
-#define AR_RxRSSIAnt10_S 0
-#define AR_RxRSSIAnt11 0x0000ff00
-#define AR_RxRSSIAnt11_S 8
-#define AR_RxRSSIAnt12 0x00ff0000
-#define AR_RxRSSIAnt12_S 16
-#define AR_RxRSSICombined 0xff000000
-#define AR_RxRSSICombined_S 24
-
-#define AR_RxEVM0 ds_rxstatus4
-#define AR_RxEVM1 ds_rxstatus5
-#define AR_RxEVM2 ds_rxstatus6
-
-#define AR_RxDone 0x00000001
-#define AR_RxFrameOK 0x00000002
-#define AR_CRCErr 0x00000004
-#define AR_DecryptCRCErr 0x00000008
-#define AR_PHYErr 0x00000010
-#define AR_MichaelErr 0x00000020
-#define AR_PreDelimCRCErr 0x00000040
-#define AR_RxStatusRsvd70 0x00000080
-#define AR_RxKeyIdxValid 0x00000100
-#define AR_KeyIdx 0x0000fe00
-#define AR_KeyIdx_S 9
-#define AR_PHYErrCode 0x0000ff00
-#define AR_PHYErrCode_S 8
-#define AR_RxMoreAggr 0x00010000
-#define AR_RxAggr 0x00020000
-#define AR_PostDelimCRCErr 0x00040000
-#define AR_RxStatusRsvd71 0x3ff80000
-#define AR_DecryptBusyErr 0x40000000
-#define AR_KeyMiss 0x80000000
-
-#define AR5416_MAGIC 0x19641014
-
-#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
- MS(ads->ds_rxstatus0, AR_RxRate) : \
- (ads->ds_rxstatus3 >> 2) & 0xFF)
-
-#define set11nTries(_series, _index) \
- (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
-
-#define set11nRate(_series, _index) \
- (SM((_series)[_index].Rate, AR_XmitRate##_index))
-
-#define set11nPktDurRTSCTS(_series, _index) \
- (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
- ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
- AR_RTSCTSQual##_index : 0))
+#define DO_DELAY(x) do { \
+ if ((++(x) % 64) == 0) \
+ udelay(1); \
+ } while (0)
-#define set11nRateFlags(_series, _index) \
- (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
- AR_2040_##_index : 0) \
- |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
- AR_GI##_index : 0) \
- |SM((_series)[_index].ChSel, AR_ChainSel##_index))
+#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
+ int r; \
+ for (r = 0; r < ((iniarray)->ia_rows); r++) { \
+ REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
+ INI_RA((iniarray), r, (column))); \
+ DO_DELAY(regWr); \
+ } \
+ } while (0)
-#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100)
+#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
+#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME 3
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
-#define INIT_CONFIG_STATUS 0x00000000
-#define INIT_RSSI_THR 0x00000700
-#define INIT_BCON_CNTRL_REG 0x00000000
+#define AR_GPIOD_MASK 0x00001FFF
+#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
-#define MIN_TX_FIFO_THRESHOLD 0x1
-#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
-#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
+#define BASE_ACTIVATE_DELAY 100
+#define RTC_PLL_SETTLE_DELAY 1000
+#define COEF_SCALE_S 24
+#define HT40_CHANNEL_CENTER_SHIFT 10
-struct ar5416AniState {
- struct ath9k_channel c;
- u8 noiseImmunityLevel;
- u8 spurImmunityLevel;
- u8 firstepLevel;
- u8 ofdmWeakSigDetectOff;
- u8 cckWeakSigThreshold;
- u32 listenTime;
- u32 ofdmTrigHigh;
- u32 ofdmTrigLow;
- int32_t cckTrigHigh;
- int32_t cckTrigLow;
- int32_t rssiThrLow;
- int32_t rssiThrHigh;
- u32 noiseFloor;
- u32 txFrameCount;
- u32 rxFrameCount;
- u32 cycleCount;
- u32 ofdmPhyErrCount;
- u32 cckPhyErrCount;
- u32 ofdmPhyErrBase;
- u32 cckPhyErrBase;
- int16_t pktRssi[2];
- int16_t ofdmErrRssi[2];
- int16_t cckErrRssi[2];
+#define ATH9K_ANTENNA0_CHAINMASK 0x1
+#define ATH9K_ANTENNA1_CHAINMASK 0x2
+
+#define ATH9K_NUM_DMA_DEBUG_REGS 8
+#define ATH9K_NUM_QUEUES 10
+
+#define MAX_RATE_POWER 63
+#define AH_WAIT_TIMEOUT 100000 /* (us) */
+#define AH_TIME_QUANTUM 10
+#define AR_KEYTABLE_SIZE 128
+#define POWER_UP_TIME 200000
+#define SPUR_RSSI_THRESH 40
+
+#define CAB_TIMEOUT_VAL 10
+#define BEACON_TIMEOUT_VAL 10
+#define MIN_BEACON_TIMEOUT_VAL 1
+#define SLEEP_SLOP 3
+
+#define INIT_CONFIG_STATUS 0x00000000
+#define INIT_RSSI_THR 0x00000700
+#define INIT_BCON_CNTRL_REG 0x00000000
+
+#define TU_TO_USEC(_tu) ((_tu) << 10)
+
+enum wireless_mode {
+ ATH9K_MODE_11A = 0,
+ ATH9K_MODE_11B = 2,
+ ATH9K_MODE_11G = 3,
+ ATH9K_MODE_11NA_HT20 = 6,
+ ATH9K_MODE_11NG_HT20 = 7,
+ ATH9K_MODE_11NA_HT40PLUS = 8,
+ ATH9K_MODE_11NA_HT40MINUS = 9,
+ ATH9K_MODE_11NG_HT40PLUS = 10,
+ ATH9K_MODE_11NG_HT40MINUS = 11,
+ ATH9K_MODE_MAX
};
-#define HAL_PROCESS_ANI 0x00000001
-#define DO_ANI(ah) \
- ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
-
-struct ar5416Stats {
- u32 ast_ani_niup;
- u32 ast_ani_nidown;
- u32 ast_ani_spurup;
- u32 ast_ani_spurdown;
- u32 ast_ani_ofdmon;
- u32 ast_ani_ofdmoff;
- u32 ast_ani_cckhigh;
- u32 ast_ani_ccklow;
- u32 ast_ani_stepup;
- u32 ast_ani_stepdown;
- u32 ast_ani_ofdmerrs;
- u32 ast_ani_cckerrs;
- u32 ast_ani_reset;
- u32 ast_ani_lzero;
- u32 ast_ani_lneg;
- struct ath9k_mib_stats ast_mibstats;
- struct ath9k_node_stats ast_nodestats;
+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)
};
-#define AR5416_OPFLAGS_11A 0x01
-#define AR5416_OPFLAGS_11G 0x02
-#define AR5416_OPFLAGS_N_5G_HT40 0x04
-#define AR5416_OPFLAGS_N_2G_HT40 0x08
-#define AR5416_OPFLAGS_N_5G_HT20 0x10
-#define AR5416_OPFLAGS_N_2G_HT20 0x20
-
-#define EEP_RFSILENT_ENABLED 0x0001
-#define EEP_RFSILENT_ENABLED_S 0
-#define EEP_RFSILENT_POLARITY 0x0002
-#define EEP_RFSILENT_POLARITY_S 1
-#define EEP_RFSILENT_GPIO_SEL 0x001c
-#define EEP_RFSILENT_GPIO_SEL_S 2
-
-#define AR5416_EEP_NO_BACK_VER 0x1
-#define AR5416_EEP_VER 0xE
-#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
-#define AR5416_EEP_MINOR_VER_2 0x2
-#define AR5416_EEP_MINOR_VER_3 0x3
-#define AR5416_EEP_MINOR_VER_7 0x7
-#define AR5416_EEP_MINOR_VER_9 0x9
-#define AR5416_EEP_MINOR_VER_16 0x10
-#define AR5416_EEP_MINOR_VER_17 0x11
-#define AR5416_EEP_MINOR_VER_19 0x13
-
-#define AR5416_NUM_5G_CAL_PIERS 8
-#define AR5416_NUM_2G_CAL_PIERS 4
-#define AR5416_NUM_5G_20_TARGET_POWERS 8
-#define AR5416_NUM_5G_40_TARGET_POWERS 8
-#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
-#define AR5416_NUM_2G_20_TARGET_POWERS 4
-#define AR5416_NUM_2G_40_TARGET_POWERS 4
-#define AR5416_NUM_CTLS 24
-#define AR5416_NUM_BAND_EDGES 8
-#define AR5416_NUM_PD_GAINS 4
-#define AR5416_PD_GAINS_IN_MASK 4
-#define AR5416_PD_GAIN_ICEPTS 5
-#define AR5416_EEPROM_MODAL_SPURS 5
-#define AR5416_MAX_RATE_POWER 63
-#define AR5416_NUM_PDADC_VALUES 128
-#define AR5416_BCHAN_UNUSED 0xFF
-#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
-#define AR5416_MAX_CHAINS 3
-#define AR5416_PWR_TABLE_OFFSET -5
-
-/* Rx gain type values */
-#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0
-#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1
-#define AR5416_EEP_RXGAIN_ORIG 2
-
-/* Tx gain type values */
-#define AR5416_EEP_TXGAIN_ORIGINAL 0
-#define AR5416_EEP_TXGAIN_HIGH_POWER 1
-
-#define AR5416_EEP4K_START_LOC 64
-#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
-#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
-#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3
-#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3
-#define AR5416_EEP4K_NUM_CTLS 12
-#define AR5416_EEP4K_NUM_BAND_EDGES 4
-#define AR5416_EEP4K_NUM_PD_GAINS 2
-#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
-#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
-#define AR5416_EEP4K_MAX_CHAINS 1
-
-enum eeprom_param {
- EEP_NFTHRESH_5,
- EEP_NFTHRESH_2,
- EEP_MAC_MSW,
- EEP_MAC_MID,
- EEP_MAC_LSW,
- EEP_REG_0,
- EEP_REG_1,
- EEP_OP_CAP,
- EEP_OP_MODE,
- EEP_RF_SILENT,
- EEP_OB_5,
- EEP_DB_5,
- EEP_OB_2,
- EEP_DB_2,
- EEP_MINOR_REV,
- EEP_TX_MASK,
- EEP_RX_MASK,
- EEP_RXGAIN_TYPE,
- EEP_TXGAIN_TYPE,
+enum ath9k_capability_type {
+ ATH9K_CAP_CIPHER = 0,
+ ATH9K_CAP_TKIP_MIC,
+ ATH9K_CAP_TKIP_SPLIT,
+ ATH9K_CAP_DIVERSITY,
+ ATH9K_CAP_TXPOW,
+ ATH9K_CAP_MCAST_KEYSRCH,
+ ATH9K_CAP_DS
};
-enum ar5416_rates {
- rate6mb, rate9mb, rate12mb, rate18mb,
- rate24mb, rate36mb, rate48mb, rate54mb,
- rate1l, rate2l, rate2s, rate5_5l,
- rate5_5s, rate11l, rate11s, rateXr,
- rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
- rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
- rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
- rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
- rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
- Ar5416RateSize
+struct ath9k_hw_capabilities {
+ u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
+ DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
+ u16 total_queues;
+ u16 keycache_size;
+ u16 low_5ghz_chan, high_5ghz_chan;
+ u16 low_2ghz_chan, high_2ghz_chan;
+ u16 num_mr_retries;
+ u16 rts_aggr_limit;
+ u8 tx_chainmask;
+ u8 rx_chainmask;
+ u16 tx_triglevel_max;
+ u16 reg_cap;
+ u8 num_gpio_pins;
+ u8 num_antcfg_2ghz;
+ u8 num_antcfg_5ghz;
};
-enum ath9k_hal_freq_band {
- ATH9K_HAL_FREQ_BAND_5GHZ = 0,
- ATH9K_HAL_FREQ_BAND_2GHZ = 1
+struct ath9k_ops_config {
+ int dma_beacon_response_time;
+ int sw_beacon_response_time;
+ int additional_swba_backoff;
+ int ack_6mb;
+ int cwm_ignore_extcca;
+ u8 pcie_powersave_enable;
+ u8 pcie_l1skp_enable;
+ u8 pcie_clock_req;
+ u32 pcie_waen;
+ int pcie_power_reset;
+ u8 pcie_restore;
+ u8 analog_shiftreg;
+ u8 ht_enable;
+ u32 ofdm_trig_low;
+ u32 ofdm_trig_high;
+ u32 cck_trig_high;
+ u32 cck_trig_low;
+ u32 enable_ani;
+ u8 noise_immunity_level;
+ u32 ofdm_weaksignal_det;
+ u32 cck_weaksignal_thr;
+ u8 spur_immunity_level;
+ u8 firstep_level;
+ int8_t rssi_thr_high;
+ int8_t rssi_thr_low;
+ u16 diversity_control;
+ u16 antenna_switch_swap;
+ int serialize_regmode;
+ int intr_mitigation;
+#define SPUR_DISABLE 0
+#define SPUR_ENABLE_IOCTL 1
+#define SPUR_ENABLE_EEPROM 2
+#define AR_EEPROM_MODAL_SPURS 5
+#define AR_SPUR_5413_1 1640
+#define AR_SPUR_5413_2 1200
+#define AR_NO_SPUR 0x8000
+#define AR_BASE_FREQ_2GHZ 2300
+#define AR_BASE_FREQ_5GHZ 4900
+#define AR_SPUR_FEEQ_BOUND_HT40 19
+#define AR_SPUR_FEEQ_BOUND_HT20 10
+ int spurmode;
+ u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
};
-struct base_eep_header {
- u16 length;
- u16 checksum;
- u16 version;
- u8 opCapFlags;
- u8 eepMisc;
- u16 regDmn[2];
- u8 macAddr[6];
- u8 rxMask;
- u8 txMask;
- u16 rfSilent;
- u16 blueToothOptions;
- u16 deviceCap;
- u32 binBuildNumber;
- u8 deviceType;
- u8 pwdclkind;
- u8 futureBase_1[2];
- u8 rxGainType;
- u8 futureBase_2[3];
- u8 txGainType;
- u8 futureBase_3[25];
-} __packed;
-
-struct base_eep_header_4k {
- u16 length;
- u16 checksum;
- u16 version;
- u8 opCapFlags;
- u8 eepMisc;
- u16 regDmn[2];
- u8 macAddr[6];
- u8 rxMask;
- u8 txMask;
- u16 rfSilent;
- u16 blueToothOptions;
- u16 deviceCap;
- u32 binBuildNumber;
- u8 deviceType;
- u8 futureBase[1];
-} __packed;
-
-
-struct spur_chan {
- u16 spurChan;
- u8 spurRangeLow;
- u8 spurRangeHigh;
-} __packed;
-
-struct modal_eep_header {
- u32 antCtrlChain[AR5416_MAX_CHAINS];
- u32 antCtrlCommon;
- u8 antennaGainCh[AR5416_MAX_CHAINS];
- u8 switchSettling;
- u8 txRxAttenCh[AR5416_MAX_CHAINS];
- u8 rxTxMarginCh[AR5416_MAX_CHAINS];
- u8 adcDesiredSize;
- u8 pgaDesiredSize;
- u8 xlnaGainCh[AR5416_MAX_CHAINS];
- u8 txEndToXpaOff;
- u8 txEndToRxOn;
- u8 txFrameToXpaOn;
- u8 thresh62;
- u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
- u8 xpdGain;
- u8 xpd;
- u8 iqCalICh[AR5416_MAX_CHAINS];
- u8 iqCalQCh[AR5416_MAX_CHAINS];
- u8 pdGainOverlap;
- u8 ob;
- u8 db;
- u8 xpaBiasLvl;
- u8 pwrDecreaseFor2Chain;
- u8 pwrDecreaseFor3Chain;
- u8 txFrameToDataStart;
- u8 txFrameToPaOn;
- u8 ht40PowerIncForPdadc;
- u8 bswAtten[AR5416_MAX_CHAINS];
- u8 bswMargin[AR5416_MAX_CHAINS];
- u8 swSettleHt40;
- u8 xatten2Db[AR5416_MAX_CHAINS];
- u8 xatten2Margin[AR5416_MAX_CHAINS];
- u8 ob_ch1;
- u8 db_ch1;
- u8 useAnt1:1,
- force_xpaon:1,
- local_bias:1,
- femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
- u8 futureModalar9280;
- u16 xpaBiasLvlFreq[3];
- u8 futureModal[6];
-
- struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-struct modal_eep_4k_header {
- u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
- u32 antCtrlCommon;
- u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
- u8 switchSettling;
- u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
- u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
- u8 adcDesiredSize;
- u8 pgaDesiredSize;
- u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
- u8 txEndToXpaOff;
- u8 txEndToRxOn;
- u8 txFrameToXpaOn;
- u8 thresh62;
- u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
- u8 xpdGain;
- u8 xpd;
- u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
- u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
- u8 pdGainOverlap;
- u8 ob_01;
- u8 db1_01;
- u8 xpaBiasLvl;
- u8 txFrameToDataStart;
- u8 txFrameToPaOn;
- u8 ht40PowerIncForPdadc;
- u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
- u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
- u8 swSettleHt40;
- u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
- u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
- u8 db2_01;
- u8 version;
- u16 ob_234;
- u16 db1_234;
- u16 db2_234;
- u8 futureModal[4];
-
- struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-
-struct cal_data_per_freq {
- u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
- u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_data_per_freq_4k {
- u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
- u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_target_power_leg {
- u8 bChannel;
- u8 tPow2x[4];
-} __packed;
-
-struct cal_target_power_ht {
- u8 bChannel;
- u8 tPow2x[8];
-} __packed;
-
-
-#ifdef __BIG_ENDIAN_BITFIELD
-struct cal_ctl_edges {
- u8 bChannel;
- u8 flag:2, tPower:6;
-} __packed;
-#else
-struct cal_ctl_edges {
- u8 bChannel;
- u8 tPower:6, flag:2;
-} __packed;
-#endif
-
-struct cal_ctl_data {
- struct cal_ctl_edges
- ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
-
-struct cal_ctl_data_4k {
- struct cal_ctl_edges
- ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
-} __packed;
-
-struct ar5416_eeprom_def {
- struct base_eep_header baseEepHeader;
- u8 custData[64];
- struct modal_eep_header modalHeader[2];
- u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
- u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
- struct cal_data_per_freq
- calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
- struct cal_data_per_freq
- calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
- struct cal_target_power_leg
- calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
- struct cal_target_power_leg
- calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
- struct cal_target_power_leg
- calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
- u8 ctlIndex[AR5416_NUM_CTLS];
- struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
- u8 padding;
-} __packed;
-
-struct ar5416_eeprom_4k {
- struct base_eep_header_4k baseEepHeader;
- u8 custData[20];
- struct modal_eep_4k_header modalHeader;
- u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
- struct cal_data_per_freq_4k
- calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
- struct cal_target_power_leg
- calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
- struct cal_target_power_leg
- calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
- u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
- struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
- u8 padding;
-} __packed;
-
-struct ar5416IniArray {
- u32 *ia_array;
- u32 ia_rows;
- u32 ia_columns;
+enum ath9k_int {
+ ATH9K_INT_RX = 0x00000001,
+ ATH9K_INT_RXDESC = 0x00000002,
+ ATH9K_INT_RXNOFRM = 0x00000008,
+ ATH9K_INT_RXEOL = 0x00000010,
+ ATH9K_INT_RXORN = 0x00000020,
+ ATH9K_INT_TX = 0x00000040,
+ ATH9K_INT_TXDESC = 0x00000080,
+ ATH9K_INT_TIM_TIMER = 0x00000100,
+ ATH9K_INT_TXURN = 0x00000800,
+ ATH9K_INT_MIB = 0x00001000,
+ ATH9K_INT_RXPHY = 0x00004000,
+ ATH9K_INT_RXKCM = 0x00008000,
+ ATH9K_INT_SWBA = 0x00010000,
+ ATH9K_INT_BMISS = 0x00040000,
+ ATH9K_INT_BNR = 0x00100000,
+ ATH9K_INT_TIM = 0x00200000,
+ ATH9K_INT_DTIM = 0x00400000,
+ ATH9K_INT_DTIMSYNC = 0x00800000,
+ ATH9K_INT_GPIO = 0x01000000,
+ ATH9K_INT_CABEND = 0x02000000,
+ ATH9K_INT_TSFOOR = 0x04000000,
+ ATH9K_INT_CST = 0x10000000,
+ ATH9K_INT_GTT = 0x20000000,
+ ATH9K_INT_FATAL = 0x40000000,
+ ATH9K_INT_GLOBAL = 0x80000000,
+ ATH9K_INT_BMISC = ATH9K_INT_TIM |
+ ATH9K_INT_DTIM |
+ ATH9K_INT_DTIMSYNC |
+ ATH9K_INT_TSFOOR |
+ ATH9K_INT_CABEND,
+ ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
+ ATH9K_INT_RXDESC |
+ ATH9K_INT_RXEOL |
+ ATH9K_INT_RXORN |
+ ATH9K_INT_TXURN |
+ ATH9K_INT_TXDESC |
+ ATH9K_INT_MIB |
+ ATH9K_INT_RXPHY |
+ ATH9K_INT_RXKCM |
+ ATH9K_INT_SWBA |
+ ATH9K_INT_BMISS |
+ ATH9K_INT_GPIO,
+ ATH9K_INT_NOCARD = 0xffffffff
};
-#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
- (iniarray)->ia_array = (u32 *)(array); \
- (iniarray)->ia_rows = (rows); \
- (iniarray)->ia_columns = (columns); \
- } while (0)
-
-#define INI_RA(iniarray, row, column) \
- (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
+#define CHANNEL_CW_INT 0x00002
+#define CHANNEL_CCK 0x00020
+#define CHANNEL_OFDM 0x00040
+#define CHANNEL_2GHZ 0x00080
+#define CHANNEL_5GHZ 0x00100
+#define CHANNEL_PASSIVE 0x00200
+#define CHANNEL_DYN 0x00400
+#define CHANNEL_HALF 0x04000
+#define CHANNEL_QUARTER 0x08000
+#define CHANNEL_HT20 0x10000
+#define CHANNEL_HT40PLUS 0x20000
+#define CHANNEL_HT40MINUS 0x40000
+
+#define CHANNEL_INTERFERENCE 0x01
+#define CHANNEL_DFS 0x02
+#define CHANNEL_4MS_LIMIT 0x04
+#define CHANNEL_DFS_CLEAR 0x08
+#define CHANNEL_DISALLOW_ADHOC 0x10
+#define CHANNEL_PER_11D_ADHOC 0x20
+
+#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
+#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
+#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
+#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
+#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
+#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_ALL \
+ (CHANNEL_OFDM| \
+ CHANNEL_CCK| \
+ CHANNEL_2GHZ | \
+ CHANNEL_5GHZ | \
+ CHANNEL_HT20 | \
+ CHANNEL_HT40PLUS | \
+ CHANNEL_HT40MINUS)
+
+struct ath9k_channel {
+ struct ieee80211_channel *chan;
+ u16 channel;
+ u32 channelFlags;
+ u32 chanmode;
+ int32_t CalValid;
+ bool oneTimeCalsDone;
+ int8_t iCoff;
+ int8_t qCoff;
+ int16_t rawNoiseFloor;
+};
-#define INIT_CAL(_perCal) do { \
- (_perCal)->calState = CAL_WAITING; \
- (_perCal)->calNext = NULL; \
- } while (0)
+#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
+ (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
+ (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
+ (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
+#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
+ (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
+ (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
+ (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
+#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
+#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
+#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
+#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
+#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
+#define IS_CHAN_A_5MHZ_SPACED(_c) \
+ ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
+ (((_c)->channel % 20) != 0) && \
+ (((_c)->channel % 10) != 0))
+
+/* These macros check chanmode and not channelFlags */
+#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
+#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
+ ((_c)->chanmode == CHANNEL_G_HT20))
+#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
+ ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
+ ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
+ ((_c)->chanmode == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
+
+enum ath9k_power_mode {
+ ATH9K_PM_AWAKE = 0,
+ ATH9K_PM_FULL_SLEEP,
+ ATH9K_PM_NETWORK_SLEEP,
+ ATH9K_PM_UNDEFINED
+};
-#define INSERT_CAL(_ahp, _perCal) \
- do { \
- if ((_ahp)->ah_cal_list_last == NULL) { \
- (_ahp)->ah_cal_list = \
- (_ahp)->ah_cal_list_last = (_perCal); \
- ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
- } else { \
- ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
- (_ahp)->ah_cal_list_last = (_perCal); \
- (_perCal)->calNext = (_ahp)->ah_cal_list; \
- } \
- } while (0)
+enum ath9k_ant_setting {
+ ATH9K_ANT_VARIABLE = 0,
+ ATH9K_ANT_FIXED_A,
+ ATH9K_ANT_FIXED_B
+};
-enum hal_cal_types {
- ADC_DC_INIT_CAL = 0x1,
- ADC_GAIN_CAL = 0x2,
- ADC_DC_CAL = 0x4,
- IQ_MISMATCH_CAL = 0x8
+enum ath9k_tp_scale {
+ ATH9K_TP_SCALE_MAX = 0,
+ ATH9K_TP_SCALE_50,
+ ATH9K_TP_SCALE_25,
+ ATH9K_TP_SCALE_12,
+ ATH9K_TP_SCALE_MIN
};
-enum hal_cal_state {
- CAL_INACTIVE,
- CAL_WAITING,
- CAL_RUNNING,
- CAL_DONE
+enum ser_reg_mode {
+ SER_REG_MODE_OFF = 0,
+ SER_REG_MODE_ON = 1,
+ SER_REG_MODE_AUTO = 2,
};
-#define MIN_CAL_SAMPLES 1
-#define MAX_CAL_SAMPLES 64
-#define INIT_LOG_COUNT 5
-#define PER_MIN_LOG_COUNT 2
-#define PER_MAX_LOG_COUNT 10
+struct ath9k_beacon_state {
+ u32 bs_nexttbtt;
+ u32 bs_nextdtim;
+ u32 bs_intval;
+#define ATH9K_BEACON_PERIOD 0x0000ffff
+#define ATH9K_BEACON_ENA 0x00800000
+#define ATH9K_BEACON_RESET_TSF 0x01000000
+#define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */
+ u32 bs_dtimperiod;
+ u16 bs_cfpperiod;
+ u16 bs_cfpmaxduration;
+ u32 bs_cfpnext;
+ u16 bs_timoffset;
+ u16 bs_bmissthreshold;
+ u32 bs_sleepduration;
+ u32 bs_tsfoor_threshold;
+};
-struct hal_percal_data {
- enum hal_cal_types calType;
- u32 calNumSamples;
- u32 calCountMax;
- void (*calCollect) (struct ath_hal *);
- void (*calPostProc) (struct ath_hal *, u8);
+struct chan_centers {
+ u16 synth_center;
+ u16 ctl_center;
+ u16 ext_center;
};
-struct hal_cal_list {
- const struct hal_percal_data *calData;
- enum hal_cal_state calState;
- struct hal_cal_list *calNext;
+enum {
+ ATH9K_RESET_POWER_ON,
+ ATH9K_RESET_WARM,
+ ATH9K_RESET_COLD,
};
-/*
- * Enum to indentify the eeprom mappings
- */
-enum hal_eep_map {
- EEP_MAP_DEFAULT = 0x0,
- EEP_MAP_4KBITS,
- EEP_MAP_MAX
+struct ath9k_hw_version {
+ u32 magic;
+ u16 devid;
+ u16 subvendorid;
+ u32 macVersion;
+ u16 macRev;
+ u16 phyRev;
+ u16 analog5GhzRev;
+ u16 analog2GhzRev;
};
+struct ath_hw {
+ struct ath_softc *ah_sc;
+ struct ath9k_hw_version hw_version;
+ struct ath9k_ops_config config;
+ struct ath9k_hw_capabilities caps;
+ struct ath9k_regulatory regulatory;
+ struct ath9k_channel channels[38];
+ struct ath9k_channel *curchan;
-struct ath_hal_5416 {
- struct ath_hal ah;
union {
struct ar5416_eeprom_def def;
struct ar5416_eeprom_4k map4k;
- } ah_eeprom;
- struct ar5416Stats ah_stats;
- struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
- void __iomem *ah_cal_mem;
-
- u8 ah_macaddr[ETH_ALEN];
- u8 ah_bssid[ETH_ALEN];
- u8 ah_bssidmask[ETH_ALEN];
- u16 ah_assocId;
-
- int16_t ah_curchanRadIndex;
- u32 ah_maskReg;
- u32 ah_txOkInterruptMask;
- u32 ah_txErrInterruptMask;
- u32 ah_txDescInterruptMask;
- u32 ah_txEolInterruptMask;
- u32 ah_txUrnInterruptMask;
- bool ah_chipFullSleep;
- u32 ah_atimWindow;
- u16 ah_antennaSwitchSwap;
- enum ath9k_power_mode ah_powerMode;
- enum ath9k_ant_setting ah_diversityControl;
+ } eeprom;
+ const struct eeprom_ops *eep_ops;
+ enum ath9k_eep_map eep_map;
+
+ bool sw_mgmt_crypto;
+ bool is_pciexpress;
+ u8 macaddr[ETH_ALEN];
+ u16 tx_trig_level;
+ u16 rfsilent;
+ u32 rfkill_gpio;
+ u32 rfkill_polarity;
+ u32 btactive_gpio;
+ u32 wlanactive_gpio;
+ u32 ah_flags;
+
+ enum nl80211_iftype opmode;
+ enum ath9k_power_mode power_mode;
+ enum ath9k_power_mode restore_mode;
+
+ struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+ struct ar5416Stats stats;
+ struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
+
+ int16_t curchan_rad_index;
+ u32 mask_reg;
+ u32 txok_interrupt_mask;
+ u32 txerr_interrupt_mask;
+ u32 txdesc_interrupt_mask;
+ u32 txeol_interrupt_mask;
+ u32 txurn_interrupt_mask;
+ bool chip_fullsleep;
+ u32 atim_window;
+ u16 antenna_switch_swap;
+ enum ath9k_ant_setting diversity_control;
/* Calibration */
- enum hal_cal_types ah_suppCals;
- struct hal_cal_list ah_iqCalData;
- struct hal_cal_list ah_adcGainCalData;
- struct hal_cal_list ah_adcDcCalInitData;
- struct hal_cal_list ah_adcDcCalData;
- struct hal_cal_list *ah_cal_list;
- struct hal_cal_list *ah_cal_list_last;
- struct hal_cal_list *ah_cal_list_curr;
-#define ah_totalPowerMeasI ah_Meas0.unsign
-#define ah_totalPowerMeasQ ah_Meas1.unsign
-#define ah_totalIqCorrMeas ah_Meas2.sign
-#define ah_totalAdcIOddPhase ah_Meas0.unsign
-#define ah_totalAdcIEvenPhase ah_Meas1.unsign
-#define ah_totalAdcQOddPhase ah_Meas2.unsign
-#define ah_totalAdcQEvenPhase ah_Meas3.unsign
-#define ah_totalAdcDcOffsetIOddPhase ah_Meas0.sign
-#define ah_totalAdcDcOffsetIEvenPhase ah_Meas1.sign
-#define ah_totalAdcDcOffsetQOddPhase ah_Meas2.sign
-#define ah_totalAdcDcOffsetQEvenPhase ah_Meas3.sign
+ enum hal_cal_types supp_cals;
+ struct hal_cal_list iq_caldata;
+ struct hal_cal_list adcgain_caldata;
+ struct hal_cal_list adcdc_calinitdata;
+ struct hal_cal_list adcdc_caldata;
+ struct hal_cal_list *cal_list;
+ struct hal_cal_list *cal_list_last;
+ struct hal_cal_list *cal_list_curr;
+#define totalPowerMeasI meas0.unsign
+#define totalPowerMeasQ meas1.unsign
+#define totalIqCorrMeas meas2.sign
+#define totalAdcIOddPhase meas0.unsign
+#define totalAdcIEvenPhase meas1.unsign
+#define totalAdcQOddPhase meas2.unsign
+#define totalAdcQEvenPhase meas3.unsign
+#define totalAdcDcOffsetIOddPhase meas0.sign
+#define totalAdcDcOffsetIEvenPhase meas1.sign
+#define totalAdcDcOffsetQOddPhase meas2.sign
+#define totalAdcDcOffsetQEvenPhase meas3.sign
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
- } ah_Meas0;
+ } meas0;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
- } ah_Meas1;
+ } meas1;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
- } ah_Meas2;
+ } meas2;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
- } ah_Meas3;
- u16 ah_CalSamples;
+ } meas3;
+ u16 cal_samples;
- u32 ah_staId1Defaults;
- u32 ah_miscMode;
+ u32 sta_id1_defaults;
+ u32 misc_mode;
enum {
AUTO_32KHZ,
USE_32KHZ,
DONT_USE_32KHZ,
- } ah_enable32kHzClock;
+ } enable_32kHz_clock;
/* RF */
- u32 *ah_analogBank0Data;
- u32 *ah_analogBank1Data;
- u32 *ah_analogBank2Data;
- u32 *ah_analogBank3Data;
- u32 *ah_analogBank6Data;
- u32 *ah_analogBank6TPCData;
- u32 *ah_analogBank7Data;
- u32 *ah_addac5416_21;
- u32 *ah_bank6Temp;
-
- int16_t ah_txPowerIndexOffset;
- u32 ah_beaconInterval;
- u32 ah_slottime;
- u32 ah_acktimeout;
- u32 ah_ctstimeout;
- u32 ah_globaltxtimeout;
- u8 ah_gBeaconRate;
- u32 ah_gpioSelect;
- u32 ah_polarity;
- u32 ah_gpioBit;
+ u32 *analogBank0Data;
+ u32 *analogBank1Data;
+ u32 *analogBank2Data;
+ u32 *analogBank3Data;
+ u32 *analogBank6Data;
+ u32 *analogBank6TPCData;
+ u32 *analogBank7Data;
+ u32 *addac5416_21;
+ u32 *bank6Temp;
+
+ int16_t txpower_indexoffset;
+ u32 beacon_interval;
+ u32 slottime;
+ u32 acktimeout;
+ u32 ctstimeout;
+ u32 globaltxtimeout;
+ u8 gbeacon_rate;
/* ANI */
- u32 ah_procPhyErr;
- bool ah_hasHwPhyCounters;
- u32 ah_aniPeriod;
- struct ar5416AniState *ah_curani;
- struct ar5416AniState ah_ani[255];
- int ah_totalSizeDesired[5];
- int ah_coarseHigh[5];
- int ah_coarseLow[5];
- int ah_firpwr[5];
- enum ath9k_ani_cmd ah_ani_function;
-
- u32 ah_intrTxqs;
- bool ah_intrMitigation;
- enum ath9k_ht_extprotspacing ah_extprotspacing;
- u8 ah_txchainmask;
- u8 ah_rxchainmask;
-
- struct ar5416IniArray ah_iniModes;
- struct ar5416IniArray ah_iniCommon;
- struct ar5416IniArray ah_iniBank0;
- struct ar5416IniArray ah_iniBB_RfGain;
- struct ar5416IniArray ah_iniBank1;
- struct ar5416IniArray ah_iniBank2;
- struct ar5416IniArray ah_iniBank3;
- struct ar5416IniArray ah_iniBank6;
- struct ar5416IniArray ah_iniBank6TPC;
- struct ar5416IniArray ah_iniBank7;
- struct ar5416IniArray ah_iniAddac;
- struct ar5416IniArray ah_iniPcieSerdes;
- struct ar5416IniArray ah_iniModesAdditional;
- struct ar5416IniArray ah_iniModesRxGain;
- struct ar5416IniArray ah_iniModesTxGain;
- /* To indicate EEPROM mapping used */
- enum hal_eep_map ah_eep_map;
+ u32 proc_phyerr;
+ bool has_hw_phycounters;
+ u32 aniperiod;
+ struct ar5416AniState *curani;
+ struct ar5416AniState ani[255];
+ int totalSizeDesired[5];
+ int coarse_high[5];
+ int coarse_low[5];
+ int firpwr[5];
+ enum ath9k_ani_cmd ani_function;
+
+ u32 intr_txqs;
+ bool intr_mitigation;
+ enum ath9k_ht_extprotspacing extprotspacing;
+ u8 txchainmask;
+ u8 rxchainmask;
+
+ u32 originalGain[22];
+ int initPDADC;
+ int PDADCdelta;
+
+ struct ar5416IniArray iniModes;
+ struct ar5416IniArray iniCommon;
+ struct ar5416IniArray iniBank0;
+ struct ar5416IniArray iniBB_RfGain;
+ struct ar5416IniArray iniBank1;
+ struct ar5416IniArray iniBank2;
+ struct ar5416IniArray iniBank3;
+ struct ar5416IniArray iniBank6;
+ struct ar5416IniArray iniBank6TPC;
+ struct ar5416IniArray iniBank7;
+ struct ar5416IniArray iniAddac;
+ struct ar5416IniArray iniPcieSerdes;
+ struct ar5416IniArray iniModesAdditional;
+ struct ar5416IniArray iniModesRxGain;
+ struct ar5416IniArray iniModesTxGain;
};
-#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
-
-#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
-
-#define ar5416RfDetach(ah) do { \
- if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \
- AH5416(ah)->ah_rfHal.rfDetach(ah); \
- } while (0)
-
-#define ath9k_hw_use_flash(_ah) \
- (!(_ah->ah_flags & AH_USE_EEPROM))
-
-
-#define DO_DELAY(x) do { \
- if ((++(x) % 64) == 0) \
- udelay(1); \
- } while (0)
-
-#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
- int r; \
- for (r = 0; r < ((iniarray)->ia_rows); r++) { \
- REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
- INI_RA((iniarray), r, (column))); \
- DO_DELAY(regWr); \
- } \
- } while (0)
-
-#define BASE_ACTIVATE_DELAY 100
-#define RTC_PLL_SETTLE_DELAY 1000
-#define COEF_SCALE_S 24
-#define HT40_CHANNEL_CENTER_SHIFT 10
-
-#define AR5416_EEPROM_MAGIC_OFFSET 0x0
-
-#define AR5416_EEPROM_S 2
-#define AR5416_EEPROM_OFFSET 0x2000
-#define AR5416_EEPROM_START_ADDR \
- (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
-#define AR5416_EEPROM_MAX 0xae0
-#define ar5416_get_eep_ver(_ahp) \
- (((_ahp)->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF)
-#define ar5416_get_eep_rev(_ahp) \
- (((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF)
-#define ar5416_get_ntxchains(_txchainmask) \
- (((_txchainmask >> 2) & 1) + \
- ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
-/* EEPROM 4K bit map definations */
-#define ar5416_get_eep4k_ver(_ahp) \
- (((_ahp)->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF)
-#define ar5416_get_eep4k_rev(_ahp) \
- (((_ahp)->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF)
-
-
-#ifdef __BIG_ENDIAN
-#define AR5416_EEPROM_MAGIC 0x5aa5
-#else
-#define AR5416_EEPROM_MAGIC 0xa55a
+/* Attach, Detach, Reset */
+const char *ath9k_hw_probe(u16 vendorid, u16 devid);
+void ath9k_hw_detach(struct ath_hw *ah);
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
+void ath9k_hw_rfdetach(struct ath_hw *ah);
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+ bool bChannelChange);
+bool ath9k_hw_fill_cap_info(struct ath_hw *ah);
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+ u32 capability, u32 *result);
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+ u32 capability, u32 setting, int *status);
+
+/* Key Cache Management */
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac);
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
+ const struct ath9k_keyval *k,
+ const u8 *mac);
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry);
+
+/* GPIO / RFKILL / Antennae */
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+ u32 ah_signal_type);
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+void ath9k_enable_rfkill(struct ath_hw *ah);
#endif
-
-#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
-
-#define ATH9K_ANTENNA0_CHAINMASK 0x1
-#define ATH9K_ANTENNA1_CHAINMASK 0x2
-
-#define ATH9K_NUM_DMA_DEBUG_REGS 8
-#define ATH9K_NUM_QUEUES 10
-
-#define HAL_NOISE_IMMUNE_MAX 4
-#define HAL_SPUR_IMMUNE_MAX 7
-#define HAL_FIRST_STEP_MAX 2
-
-#define ATH9K_ANI_OFDM_TRIG_HIGH 500
-#define ATH9K_ANI_OFDM_TRIG_LOW 200
-#define ATH9K_ANI_CCK_TRIG_HIGH 200
-#define ATH9K_ANI_CCK_TRIG_LOW 100
-#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
-#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
-#define ATH9K_ANI_CCK_WEAK_SIG_THR false
-#define ATH9K_ANI_SPUR_IMMUNE_LVL 7
-#define ATH9K_ANI_FIRSTEP_LVL 0
-#define ATH9K_ANI_RSSI_THR_HIGH 40
-#define ATH9K_ANI_RSSI_THR_LOW 7
-#define ATH9K_ANI_PERIOD 100
-
-#define AR_GPIOD_MASK 0x00001FFF
-#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
-
-#define HAL_EP_RND(x, mul) \
- ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
-#define BEACON_RSSI(ahp) \
- HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \
- ATH9K_RSSI_EP_MULTIPLIER)
-
-#define ah_mibStats ah_stats.ast_mibstats
-
-#define AH_TIMEOUT 100000
-#define AH_TIME_QUANTUM 10
-
-#define AR_KEYTABLE_SIZE 128
-#define POWER_UP_TIME 200000
-
-#define EXT_ADDITIVE (0x8000)
-#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
-#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
-#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
-
-#define SUB_NUM_CTL_MODES_AT_5G_40 2
-#define SUB_NUM_CTL_MODES_AT_2G_40 3
-#define SPUR_RSSI_THRESH 40
-
-#define TU_TO_USEC(_tu) ((_tu) << 10)
-
-#define CAB_TIMEOUT_VAL 10
-#define BEACON_TIMEOUT_VAL 10
-#define MIN_BEACON_TIMEOUT_VAL 1
-#define SLEEP_SLOP 3
-
-#define CCK_SIFS_TIME 10
-#define CCK_PREAMBLE_BITS 144
-#define CCK_PLCP_BITS 48
-
-#define OFDM_SIFS_TIME 16
-#define OFDM_PREAMBLE_TIME 20
-#define OFDM_PLCP_BITS 22
-#define OFDM_SYMBOL_TIME 4
-
-#define OFDM_SIFS_TIME_HALF 32
-#define OFDM_PREAMBLE_TIME_HALF 40
-#define OFDM_PLCP_BITS_HALF 22
-#define OFDM_SYMBOL_TIME_HALF 8
-
-#define OFDM_SIFS_TIME_QUARTER 64
-#define OFDM_PREAMBLE_TIME_QUARTER 80
-#define OFDM_PLCP_BITS_QUARTER 22
-#define OFDM_SYMBOL_TIME_QUARTER 16
-
-u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
- enum eeprom_param param);
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
+bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
+ enum ath9k_ant_setting settings,
+ struct ath9k_channel *chan,
+ u8 *tx_chainmask, u8 *rx_chainmask,
+ u8 *antenna_cfgd);
+
+/* General Operation */
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
+u32 ath9k_hw_reverse_bits(u32 val, u32 n);
+bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
+u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates,
+ u32 frameLen, u16 rateix, bool shortPreamble);
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct chan_centers *centers);
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
+bool ath9k_hw_phy_disable(struct ath_hw *ah);
+bool ath9k_hw_disable(struct ath_hw *ah);
+bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
+void ath9k_hw_setopmode(struct ath_hw *ah);
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
+void ath9k_hw_setbssidmask(struct ath_softc *sc);
+void ath9k_hw_write_associd(struct ath_softc *sc);
+u64 ath9k_hw_gettsf64(struct ath_hw *ah);
+void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
+void ath9k_hw_reset_tsf(struct ath_hw *ah);
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
+void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
+ const struct ath9k_beacon_state *bs);
+bool ath9k_hw_setpower(struct ath_hw *ah,
+ enum ath9k_power_mode mode);
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
+
+/* Interrupt Handling */
+bool ath9k_hw_intrpend(struct ath_hw *ah);
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah);
#endif
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h
index f3cfa16525e..1d60c3706f1 100644
--- a/drivers/net/wireless/ath9k/initvals.h
+++ b/drivers/net/wireless/ath9k/initvals.h
@@ -14,8 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* AR5416 to Fowl ar5146.ini */
-static const u32 ar5416Modes_9100[][6] = {
+static const u32 ar5416Modes[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -79,7 +78,7 @@ static const u32 ar5416Modes_9100[][6] = {
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
};
-static const u32 ar5416Common_9100[][2] = {
+static const u32 ar5416Common[][2] = {
{ 0x0000000c, 0x00000000 },
{ 0x00000030, 0x00020015 },
{ 0x00000034, 0x00000005 },
@@ -457,12 +456,12 @@ static const u32 ar5416Common_9100[][2] = {
{ 0x0000a3e0, 0x000001ce },
};
-static const u32 ar5416Bank0_9100[][2] = {
+static const u32 ar5416Bank0[][2] = {
{ 0x000098b0, 0x1e5795e5 },
{ 0x000098e0, 0x02008020 },
};
-static const u32 ar5416BB_RfGain_9100[][3] = {
+static const u32 ar5416BB_RfGain[][3] = {
{ 0x00009a00, 0x00000000, 0x00000000 },
{ 0x00009a04, 0x00000040, 0x00000040 },
{ 0x00009a08, 0x00000080, 0x00000080 },
@@ -529,21 +528,21 @@ static const u32 ar5416BB_RfGain_9100[][3] = {
{ 0x00009afc, 0x000000f9, 0x000000f9 },
};
-static const u32 ar5416Bank1_9100[][2] = {
+static const u32 ar5416Bank1[][2] = {
{ 0x000098b0, 0x02108421 },
{ 0x000098ec, 0x00000008 },
};
-static const u32 ar5416Bank2_9100[][2] = {
+static const u32 ar5416Bank2[][2] = {
{ 0x000098b0, 0x0e73ff17 },
{ 0x000098e0, 0x00000420 },
};
-static const u32 ar5416Bank3_9100[][3] = {
+static const u32 ar5416Bank3[][3] = {
{ 0x000098f0, 0x01400018, 0x01c00018 },
};
-static const u32 ar5416Bank6_9100[][3] = {
+static const u32 ar5416Bank6[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@@ -580,7 +579,7 @@ static const u32 ar5416Bank6_9100[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
-static const u32 ar5416Bank6TPC_9100[][3] = {
+static const u32 ar5416Bank6TPC[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@@ -616,13 +615,13 @@ static const u32 ar5416Bank6TPC_9100[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
-static const u32 ar5416Bank7_9100[][2] = {
+static const u32 ar5416Bank7[][2] = {
{ 0x0000989c, 0x00000500 },
{ 0x0000989c, 0x00000800 },
{ 0x000098cc, 0x0000000e },
};
-static const u32 ar5416Addac_9100[][2] = {
+static const u32 ar5416Addac[][2] = {
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000003 },
{0x0000989c, 0x00000000 },
@@ -659,11 +658,10 @@ static const u32 ar5416Addac_9100[][2] = {
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
- {0x000098c4, 0x00000000 },
+ {0x000098cc, 0x00000000 },
};
-/* ar5416 - howl ar5416_howl.ini */
-static const u32 ar5416Modes[][6] = {
+static const u32 ar5416Modes_9100[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -737,7 +735,7 @@ static const u32 ar5416Modes[][6] = {
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
};
-static const u32 ar5416Common[][2] = {
+static const u32 ar5416Common_9100[][2] = {
{ 0x0000000c, 0x00000000 },
{ 0x00000030, 0x00020015 },
{ 0x00000034, 0x00000005 },
@@ -1111,12 +1109,12 @@ static const u32 ar5416Common[][2] = {
{ 0x0000a3e0, 0x000001ce },
};
-static const u32 ar5416Bank0[][2] = {
+static const u32 ar5416Bank0_9100[][2] = {
{ 0x000098b0, 0x1e5795e5 },
{ 0x000098e0, 0x02008020 },
};
-static const u32 ar5416BB_RfGain[][3] = {
+static const u32 ar5416BB_RfGain_9100[][3] = {
{ 0x00009a00, 0x00000000, 0x00000000 },
{ 0x00009a04, 0x00000040, 0x00000040 },
{ 0x00009a08, 0x00000080, 0x00000080 },
@@ -1183,21 +1181,21 @@ static const u32 ar5416BB_RfGain[][3] = {
{ 0x00009afc, 0x000000f9, 0x000000f9 },
};
-static const u32 ar5416Bank1[][2] = {
+static const u32 ar5416Bank1_9100[][2] = {
{ 0x000098b0, 0x02108421},
{ 0x000098ec, 0x00000008},
};
-static const u32 ar5416Bank2[][2] = {
+static const u32 ar5416Bank2_9100[][2] = {
{ 0x000098b0, 0x0e73ff17},
{ 0x000098e0, 0x00000420},
};
-static const u32 ar5416Bank3[][3] = {
+static const u32 ar5416Bank3_9100[][3] = {
{ 0x000098f0, 0x01400018, 0x01c00018 },
};
-static const u32 ar5416Bank6[][3] = {
+static const u32 ar5416Bank6_9100[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@@ -1235,7 +1233,7 @@ static const u32 ar5416Bank6[][3] = {
};
-static const u32 ar5416Bank6TPC[][3] = {
+static const u32 ar5416Bank6TPC_9100[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@@ -1272,13 +1270,13 @@ static const u32 ar5416Bank6TPC[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
-static const u32 ar5416Bank7[][2] = {
+static const u32 ar5416Bank7_9100[][2] = {
{ 0x0000989c, 0x00000500 },
{ 0x0000989c, 0x00000800 },
{ 0x000098cc, 0x0000000e },
};
-static const u32 ar5416Addac[][2] = {
+static const u32 ar5416Addac_9100[][2] = {
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
@@ -1313,7 +1311,6 @@ static const u32 ar5416Addac[][2] = {
{0x000098cc, 0x00000000 },
};
-/* AR5416 9160 Sowl ar5416_sowl.ini */
static const u32 ar5416Modes_9160[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -2549,6 +2546,8 @@ static const u32 ar9280Modes_9280_2[][6] = {
{ 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
{ 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+ { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+ { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
{ 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
@@ -2587,7 +2586,6 @@ static const u32 ar9280Modes_9280_2[][6] = {
{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
{ 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 },
- { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
{ 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
{ 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
@@ -2719,7 +2717,6 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x00008110, 0x00000168 },
{ 0x00008118, 0x000100aa },
{ 0x0000811c, 0x00003210 },
- { 0x00008120, 0x08f04800 },
{ 0x00008124, 0x00000000 },
{ 0x00008128, 0x00000000 },
{ 0x0000812c, 0x00000000 },
@@ -2735,7 +2732,6 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x00008178, 0x00000100 },
{ 0x0000817c, 0x00000000 },
{ 0x000081c0, 0x00000000 },
- { 0x000081d0, 0x00003210 },
{ 0x000081ec, 0x00000000 },
{ 0x000081f0, 0x00000000 },
{ 0x000081f4, 0x00000000 },
@@ -2817,7 +2813,7 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x00009958, 0x2108ecff },
{ 0x00009940, 0x14750604 },
{ 0x0000c95c, 0x004b6a8e },
- { 0x00009968, 0x000003ce },
+ { 0x0000c968, 0x000003ce },
{ 0x00009970, 0x190fb515 },
{ 0x00009974, 0x00000000 },
{ 0x00009978, 0x00000001 },
@@ -2909,16 +2905,12 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x0000780c, 0x21084210 },
{ 0x00007810, 0x6d801300 },
{ 0x00007818, 0x07e41000 },
- { 0x0000781c, 0x00392000 },
- { 0x00007820, 0x92592480 },
{ 0x00007824, 0x00040000 },
{ 0x00007828, 0xdb005012 },
{ 0x0000782c, 0x04924914 },
{ 0x00007830, 0x21084210 },
{ 0x00007834, 0x6d801300 },
{ 0x0000783c, 0x07e40000 },
- { 0x00007840, 0x00392000 },
- { 0x00007844, 0x92592480 },
{ 0x00007848, 0x00100000 },
{ 0x0000784c, 0x773f0567 },
{ 0x00007850, 0x54214514 },
@@ -2954,7 +2946,6 @@ static const u32 ar9280Modes_fast_clock_9280_2[][3] = {
{ 0x00009844, 0x03721821, 0x03721821 },
{ 0x00009914, 0x00000898, 0x00001130 },
{ 0x00009918, 0x0000000b, 0x00000016 },
- { 0x00009944, 0xdfbc1210, 0xdfbc1210 },
};
static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
@@ -3366,21 +3357,26 @@ static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
{ 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a },
{ 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 },
{ 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
- { 0x0000a324, 0x00020092, 0x00020092, 0x00022411, 0x00022411, 0x00022411 },
- { 0x0000a328, 0x0002410a, 0x0002410a, 0x00025413, 0x00025413, 0x00025413 },
- { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00029811, 0x00029811, 0x00029811 },
- { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002c813, 0x0002c813, 0x0002c813 },
- { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
- { 0x0000a338, 0x000321ec, 0x000321ec, 0x00035a50, 0x00035a50, 0x00035a50 },
- { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
- { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
- { 0x0000a344, 0x000321ec, 0x000321ec, 0x00042e92, 0x00042e92, 0x00042e92 },
- { 0x0000a348, 0x000321ec, 0x000321ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
- { 0x0000a34c, 0x000321ec, 0x000321ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
- { 0x0000a350, 0x000321ec, 0x000321ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
- { 0x0000a354, 0x000321ec, 0x000321ec, 0x00053fd5, 0x00053fd5, 0x00053fd5 },
+ { 0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 },
+ { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 },
+ { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 },
+ { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 },
+ { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
+ { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 },
+ { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
+ { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
+ { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 },
+ { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
+ { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
+ { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
+ { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 },
{ 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
{ 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
+ { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+ { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+ { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
+ { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
+ { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
{ 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce },
};
@@ -3409,6 +3405,11 @@ static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
{ 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
{ 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
{ 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
+ { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+ { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+ { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
+ { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
+ { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
{ 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
};
@@ -4120,6 +4121,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
{0x00004044, 0x00000000 },
};
+/* AR9285 v1_2 PCI Register Writes. Created: 03/04/09 */
static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -4135,11 +4137,11 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
{ 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
- { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 },
- { 0x00009848, 0x00001066, 0x00001066, 0x00000057, 0x00000057, 0x00001059 },
+ { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
+ { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
{ 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
{ 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
- { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e },
+ { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
{ 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
{ 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
{ 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
@@ -4154,291 +4156,272 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
{ 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
- { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+ { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
- { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
- { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
- { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
- { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
- { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
- { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
- { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
- { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 },
- { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
- { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
- { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
- { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
- { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
- { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
- { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
- { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
- { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
- { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 },
- { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 },
- { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 },
- { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
- { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
- { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 },
- { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
- { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
- { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 },
- { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 },
+ { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+ { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+ { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+ { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+ { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+ { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+ { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+ { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+ { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+ { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+ { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+ { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+ { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+ { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+ { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+ { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+ { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+ { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+ { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+ { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+ { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+ { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+ { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+ { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+ { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+ { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+ { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+ { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
{ 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
{ 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
{ 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
{ 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
{ 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
{ 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
- { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 },
- { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
- { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
- { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 },
- { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 },
- { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 },
- { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 },
- { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 },
- { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 },
- { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 },
- { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
- { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
- { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 },
- { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 },
- { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 },
- { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 },
- { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
- { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
- { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 },
- { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 },
- { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 },
- { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 },
- { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
- { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
- { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 },
- { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 },
- { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 },
- { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 },
- { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 },
- { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 },
- { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
- { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
- { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 },
- { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
- { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
- { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
- { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 },
- { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
- { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
- { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 },
- { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 },
- { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
- { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
- { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 },
- { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
- { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
- { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
- { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
- { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
- { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
- { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
- { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 },
- { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
- { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 },
- { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 },
- { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
- { 0x0000aa04, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
- { 0x0000aa08, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
- { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 },
- { 0x0000aa10, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
- { 0x0000aa14, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
- { 0x0000aa18, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
- { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
- { 0x0000aa20, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
- { 0x0000aa24, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
- { 0x0000aa28, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
- { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
- { 0x0000aa30, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
- { 0x0000aa34, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
- { 0x0000aa38, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
- { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
- { 0x0000aa40, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
- { 0x0000aa44, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
- { 0x0000aa48, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
- { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
- { 0x0000aa50, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
- { 0x0000aa54, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
- { 0x0000aa58, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 },
- { 0x0000aa5c, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 },
- { 0x0000aa60, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 },
- { 0x0000aa64, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
- { 0x0000aa68, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
- { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
- { 0x0000aa70, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
- { 0x0000aa74, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 },
- { 0x0000aa78, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 },
- { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 },
- { 0x0000aa80, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 },
- { 0x0000aa84, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 },
- { 0x0000aa88, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 },
- { 0x0000aa8c, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 },
- { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 },
- { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 },
- { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 },
- { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 },
- { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 },
- { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 },
- { 0x0000aaa8, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 },
- { 0x0000aaac, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 },
- { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 },
- { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 },
- { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 },
- { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
- { 0x0000aac0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
- { 0x0000aac4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
- { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 },
- { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
- { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
- { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 },
- { 0x0000aad8, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 },
- { 0x0000aadc, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 },
- { 0x0000aae0, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 },
- { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
- { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
- { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 },
- { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 },
- { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 },
- { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 },
- { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 },
- { 0x0000ab00, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 },
- { 0x0000ab04, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 },
- { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 },
- { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
- { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
- { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
- { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
- { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
- { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 },
- { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 },
- { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
- { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
- { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
- { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
- { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 },
- { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
- { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 },
- { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
- { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
- { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 },
- { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
- { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
- { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
- { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
- { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
- { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
- { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
- { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+ { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+ { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+ { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+ { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+ { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+ { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+ { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+ { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+ { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+ { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+ { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+ { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+ { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+ { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+ { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+ { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+ { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+ { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+ { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+ { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+ { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+ { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+ { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+ { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+ { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+ { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+ { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+ { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+ { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+ { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+ { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+ { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+ { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+ { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+ { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+ { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+ { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+ { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+ { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+ { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+ { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+ { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+ { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+ { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+ { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+ { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+ { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+ { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+ { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+ { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+ { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+ { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+ { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+ { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+ { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+ { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+ { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+ { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+ { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+ { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+ { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+ { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+ { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+ { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+ { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+ { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+ { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+ { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+ { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+ { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+ { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+ { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+ { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+ { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+ { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+ { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+ { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+ { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+ { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+ { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+ { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+ { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
+ { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+ { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+ { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+ { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+ { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+ { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+ { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+ { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+ { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+ { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+ { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+ { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+ { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+ { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+ { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+ { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+ { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+ { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+ { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+ { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+ { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+ { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+ { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+ { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+ { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+ { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+ { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+ { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+ { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+ { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+ { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+ { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+ { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+ { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+ { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+ { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+ { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+ { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+ { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+ { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+ { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+ { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+ { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+ { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+ { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+ { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+ { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+ { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+ { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+ { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+ { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+ { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+ { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+ { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+ { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+ { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+ { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+ { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+ { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+ { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+ { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+ { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
{ 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
- { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 },
+ { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
{ 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
- { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
- { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
- { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
- { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
- { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
- { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
- { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
- { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
- { 0x0000a320, 0x00000000, 0x00000000, 0x0002b89a, 0x0002b89a, 0x00000000 },
- { 0x0000a324, 0x00000000, 0x00000000, 0x0002d89b, 0x0002d89b, 0x00000000 },
- { 0x0000a328, 0x00000000, 0x00000000, 0x0002f89c, 0x0002f89c, 0x00000000 },
- { 0x0000a32c, 0x00000000, 0x00000000, 0x0003189d, 0x0003189d, 0x00000000 },
- { 0x0000a330, 0x00000000, 0x00000000, 0x0003389e, 0x0003389e, 0x00000000 },
- { 0x0000a334, 0x00000000, 0x00000000, 0x000368de, 0x000368de, 0x00000000 },
- { 0x0000a338, 0x00000000, 0x00000000, 0x0003891e, 0x0003891e, 0x00000000 },
- { 0x0000a33c, 0x00000000, 0x00000000, 0x0003a95e, 0x0003a95e, 0x00000000 },
- { 0x0000a340, 0x00000000, 0x00000000, 0x0003e9df, 0x0003e9df, 0x00000000 },
- { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
};
@@ -4568,7 +4551,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00008110, 0x00000168 },
{ 0x00008118, 0x000100aa },
{ 0x0000811c, 0x00003210 },
- { 0x00008120, 0x08f04800 },
+ { 0x00008120, 0x08f04810 },
{ 0x00008124, 0x00000000 },
{ 0x00008128, 0x00000000 },
{ 0x0000812c, 0x00000000 },
@@ -4584,7 +4567,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00008178, 0x00000100 },
{ 0x0000817c, 0x00000000 },
{ 0x000081c0, 0x00000000 },
- { 0x000081d0, 0x00003210 },
+ { 0x000081d0, 0x0000320a },
{ 0x000081ec, 0x00000000 },
{ 0x000081f0, 0x00000000 },
{ 0x000081f4, 0x00000000 },
@@ -4679,7 +4662,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x000099a0, 0x00000000 },
{ 0x000099a4, 0x00000001 },
{ 0x000099a8, 0x201fff00 },
- { 0x000099ac, 0x2def1000 },
+ { 0x000099ac, 0x2def0400 },
{ 0x000099b0, 0x03051000 },
{ 0x000099b4, 0x00000820 },
{ 0x000099dc, 0x00000000 },
@@ -4688,7 +4671,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x000099e8, 0x3c466478 },
{ 0x000099ec, 0x0cc80caa },
{ 0x000099f0, 0x00000000 },
- { 0x0000a208, 0x803e6788 },
+ { 0x0000a208, 0x803e68c8 },
{ 0x0000a210, 0x4080a333 },
{ 0x0000a214, 0x00206c10 },
{ 0x0000a218, 0x009c4060 },
@@ -4708,8 +4691,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a268, 0x00000000 },
{ 0x0000a26c, 0x0ebae9e6 },
{ 0x0000d270, 0x0d820820 },
- { 0x0000a278, 0x318c6318 },
- { 0x0000a27c, 0x050c0318 },
{ 0x0000d35c, 0x07ffffef },
{ 0x0000d360, 0x0fffffe7 },
{ 0x0000d364, 0x17ffffe5 },
@@ -4724,8 +4705,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a388, 0x0c000000 },
{ 0x0000a38c, 0x20202020 },
{ 0x0000a390, 0x20202020 },
- { 0x0000a394, 0x318c6318 },
- { 0x0000a398, 0x00000318 },
{ 0x0000a39c, 0x00000001 },
{ 0x0000a3a0, 0x00000000 },
{ 0x0000a3a4, 0x00000000 },
@@ -4740,8 +4719,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a3cc, 0x20202020 },
{ 0x0000a3d0, 0x20202020 },
{ 0x0000a3d4, 0x20202020 },
- { 0x0000a3dc, 0x318c6318 },
- { 0x0000a3e0, 0x00000318 },
{ 0x0000a3e4, 0x00000000 },
{ 0x0000a3e8, 0x18c43433 },
{ 0x0000a3ec, 0x00f70081 },
@@ -4752,13 +4729,11 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00007810, 0x71c0d388 },
{ 0x00007814, 0x924934a8 },
{ 0x0000781c, 0x00000000 },
- { 0x00007820, 0x00000c04 },
{ 0x00007824, 0x00d86fff },
{ 0x00007828, 0x26d2491b },
{ 0x0000782c, 0x6e36d97b },
{ 0x00007830, 0xedb6d96e },
{ 0x00007834, 0x71400087 },
- { 0x00007838, 0xfac68801 },
{ 0x0000783c, 0x0001fffe },
{ 0x00007840, 0xffeb1a20 },
{ 0x00007844, 0x000c0db6 },
@@ -4771,10 +4746,81 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00007860, 0x21084210 },
{ 0x00007864, 0xf7d7ffde },
{ 0x00007868, 0xc2034080 },
- { 0x0000786c, 0x48609eb4 },
{ 0x00007870, 0x10142c00 },
};
+static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
+ /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
+ { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
+ { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+ { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
+ { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
+ { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
+ { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
+ { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
+ { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
+ { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
+ { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
+ { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
+ { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
+ { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
+ { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+ { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+ { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
+ { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
+ { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
+ { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+ { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+ { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
+ { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+ { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+ { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+ { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+};
+
+static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
+ /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
+ { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
+ { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
+ { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
+ { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
+ { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
+ { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
+ { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
+ { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
+ { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
+ { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
+ { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
+ { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
+ { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
+ { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+ { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+ { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
+ { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
+ { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
+ { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+ { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+ { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
+ { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+ { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+ { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+ { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+};
+
static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
{0x00004040, 0x9248fd00 },
{0x00004040, 0x24924924 },
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c
index af32d091dc3..f757bc7eec6 100644
--- a/drivers/net/wireless/ath9k/mac.c
+++ b/drivers/net/wireless/ath9k/mac.c
@@ -14,45 +14,40 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
-static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
+static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
struct ath9k_tx_queue_info *qi)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
"tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
- ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
- ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
- ahp->ah_txUrnInterruptMask);
+ ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
+ ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
+ ah->txurn_interrupt_mask);
REG_WRITE(ah, AR_IMR_S0,
- SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
- | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
+ SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
+ | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
REG_WRITE(ah, AR_IMR_S1,
- SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
- | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
+ SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
+ | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
REG_RMW_FIELD(ah, AR_IMR_S2,
- AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
+ AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);
}
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
{
return REG_READ(ah, AR_QTXDP(q));
}
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp)
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
{
REG_WRITE(ah, AR_QTXDP(q), txdp);
return true;
}
-bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
{
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
@@ -61,7 +56,7 @@ bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
return true;
}
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
{
u32 npend;
@@ -75,16 +70,15 @@ u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
return npend;
}
-bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 txcfg, curLevel, newLevel;
enum ath9k_int omask;
- if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
+ if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
return false;
- omask = ath9k_hw_set_interrupts(ah, ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
+ omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
txcfg = REG_READ(ah, AR_TXCFG);
curLevel = MS(txcfg, AR_FTRIG);
@@ -100,21 +94,38 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
ath9k_hw_set_interrupts(ah, omask);
- ah->ah_txTrigLevel = newLevel;
+ ah->tx_trig_level = newLevel;
return newLevel != curLevel;
}
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
{
+#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */
+#define ATH9K_TIME_QUANTUM 100 /* usec */
+
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
+ struct ath9k_tx_queue_info *qi;
u32 tsfLow, j, wait;
+ u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
+
+ if (q >= pCap->total_queues) {
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ return false;
+ }
+
+ qi = &ah->txq[q];
+ if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+ return false;
+ }
REG_WRITE(ah, AR_Q_TXD, 1 << q);
- for (wait = 1000; wait != 0; wait--) {
+ for (wait = wait_time; wait != 0; wait--) {
if (ath9k_hw_numtxpending(ah, q) == 0)
break;
- udelay(100);
+ udelay(ATH9K_TIME_QUANTUM);
}
if (ath9k_hw_numtxpending(ah, q)) {
@@ -144,8 +155,7 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
udelay(200);
REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
- wait = 1000;
-
+ wait = wait_time;
while (ath9k_hw_numtxpending(ah, q)) {
if ((--wait) == 0) {
DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
@@ -153,18 +163,20 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
"msec after killing last frame\n");
break;
}
- udelay(100);
+ udelay(ATH9K_TIME_QUANTUM);
}
REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
}
REG_WRITE(ah, AR_Q_TXD, 0);
-
return wait != 0;
+
+#undef ATH9K_TX_STOP_DMA_TIMEOUT
+#undef ATH9K_TIME_QUANTUM
}
-bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 segLen, bool firstSeg,
bool lastSeg, const struct ath_desc *ds0)
{
@@ -192,7 +204,7 @@ bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
return true;
}
-void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -203,7 +215,7 @@ void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
}
-int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -273,19 +285,18 @@ int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
- ds->ds_txstat.ts_antenna = 1;
+ ds->ds_txstat.ts_antenna = 0;
return 0;
}
-void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
u32 keyIx, enum ath9k_key_type keyType, u32 flags)
{
struct ar5416_desc *ads = AR5416DESC(ds);
- struct ath_hal_5416 *ahp = AH5416(ah);
- txPower += ahp->ah_txPowerIndexOffset;
+ txPower += ah->txpower_indexoffset;
if (txPower > 63)
txPower = 63;
@@ -314,7 +325,7 @@ void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
}
}
-void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
struct ath_desc *lastds,
u32 durUpdateEn, u32 rtsctsRate,
u32 rtsctsDuration,
@@ -325,9 +336,6 @@ void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
struct ar5416_desc *last_ads = AR5416DESC(lastds);
u32 ds_ctl0;
- (void) nseries;
- (void) rtsctsDuration;
-
if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
ds_ctl0 = ads->ds_ctl0;
@@ -372,7 +380,7 @@ void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
last_ads->ds_ctl3 = ads->ds_ctl3;
}
-void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
u32 aggrLen)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -382,7 +390,7 @@ void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
}
-void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
u32 numDelims)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -396,7 +404,7 @@ void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl6 = ctl6;
}
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -405,14 +413,14 @@ void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
ads->ds_ctl6 &= ~AR_PadDelim;
}
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
{
struct ar5416_desc *ads = AR5416DESC(ds);
ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
}
-void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
u32 burstDuration)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -421,7 +429,7 @@ void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
}
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
u32 vmf)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -432,20 +440,17 @@ void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl0 &= ~AR_VirtMoreFrag;
}
-void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- *txqs &= ahp->ah_intrTxqs;
- ahp->ah_intrTxqs &= ~(*txqs);
+ *txqs &= ah->intr_txqs;
+ ah->intr_txqs &= ~(*txqs);
}
-bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
const struct ath9k_tx_queue_info *qinfo)
{
u32 cw;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
@@ -453,7 +458,7 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
return false;
}
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
return false;
@@ -509,11 +514,10 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
return true;
}
-bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qinfo)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
@@ -521,7 +525,7 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
return false;
}
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
return false;
@@ -545,12 +549,11 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
return true;
}
-int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
const struct ath9k_tx_queue_info *qinfo)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ath9k_tx_queue_info *qi;
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
int q;
switch (type) {
@@ -568,7 +571,7 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
break;
case ATH9K_TX_QUEUE_DATA:
for (q = 0; q < pCap->total_queues; q++)
- if (ahp->ah_txq[q].tqi_type ==
+ if (ah->txq[q].tqi_type ==
ATH9K_TX_QUEUE_INACTIVE)
break;
if (q == pCap->total_queues) {
@@ -584,7 +587,7 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
- qi = &ahp->ah_txq[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);
@@ -611,17 +614,16 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
return q;
}
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
return false;
}
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
return false;
@@ -630,21 +632,20 @@ bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
- ahp->ah_txOkInterruptMask &= ~(1 << q);
- ahp->ah_txErrInterruptMask &= ~(1 << q);
- ahp->ah_txDescInterruptMask &= ~(1 << q);
- ahp->ah_txEolInterruptMask &= ~(1 << q);
- ahp->ah_txUrnInterruptMask &= ~(1 << q);
+ ah->txok_interrupt_mask &= ~(1 << q);
+ ah->txerr_interrupt_mask &= ~(1 << q);
+ ah->txdesc_interrupt_mask &= ~(1 << q);
+ ah->txeol_interrupt_mask &= ~(1 << q);
+ ah->txurn_interrupt_mask &= ~(1 << q);
ath9k_hw_set_txq_interrupts(ah, qi);
return true;
}
-bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
+ struct ath9k_channel *chan = ah->curchan;
struct ath9k_tx_queue_info *qi;
u32 cwMin, chanCwMin, value;
@@ -653,7 +654,7 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
return false;
}
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
return true;
@@ -741,9 +742,9 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
| AR_Q_MISC_CBR_INCR_DIS1
| AR_Q_MISC_CBR_INCR_DIS0);
value = (qi->tqi_readyTime -
- (ah->ah_config.sw_beacon_response_time -
- ah->ah_config.dma_beacon_response_time) -
- ah->ah_config.additional_swba_backoff) * 1024;
+ (ah->config.sw_beacon_response_time -
+ ah->config.dma_beacon_response_time) -
+ ah->config.additional_swba_backoff) * 1024;
REG_WRITE(ah, AR_QRDYTIMECFG(q),
value | AR_Q_RDYTIMECFG_EN);
REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
@@ -771,31 +772,31 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
}
if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
- ahp->ah_txOkInterruptMask |= 1 << q;
+ ah->txok_interrupt_mask |= 1 << q;
else
- ahp->ah_txOkInterruptMask &= ~(1 << q);
+ ah->txok_interrupt_mask &= ~(1 << q);
if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
- ahp->ah_txErrInterruptMask |= 1 << q;
+ ah->txerr_interrupt_mask |= 1 << q;
else
- ahp->ah_txErrInterruptMask &= ~(1 << q);
+ ah->txerr_interrupt_mask &= ~(1 << q);
if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
- ahp->ah_txDescInterruptMask |= 1 << q;
+ ah->txdesc_interrupt_mask |= 1 << q;
else
- ahp->ah_txDescInterruptMask &= ~(1 << q);
+ ah->txdesc_interrupt_mask &= ~(1 << q);
if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
- ahp->ah_txEolInterruptMask |= 1 << q;
+ ah->txeol_interrupt_mask |= 1 << q;
else
- ahp->ah_txEolInterruptMask &= ~(1 << q);
+ ah->txeol_interrupt_mask &= ~(1 << q);
if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
- ahp->ah_txUrnInterruptMask |= 1 << q;
+ ah->txurn_interrupt_mask |= 1 << q;
else
- ahp->ah_txUrnInterruptMask &= ~(1 << q);
+ ah->txurn_interrupt_mask &= ~(1 << q);
ath9k_hw_set_txq_interrupts(ah, qi);
return true;
}
-int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 pa, struct ath_desc *nds, u64 tsf)
{
struct ar5416_desc ads;
@@ -860,11 +861,11 @@ int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
return 0;
}
-bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 size, u32 flags)
{
struct ar5416_desc *ads = AR5416DESC(ds);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
ads->ds_ctl1 = size & AR_BufLen;
if (flags & ATH9K_RXDESC_INTREQ)
@@ -877,7 +878,7 @@ bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
return true;
}
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
{
u32 reg;
@@ -885,7 +886,8 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
REG_SET_BIT(ah, AR_DIAG_SW,
(AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
- if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
+ if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
+ 0, AH_WAIT_TIMEOUT)) {
REG_CLR_BIT(ah, AR_DIAG_SW,
(AR_DIAG_RX_DIS |
AR_DIAG_RX_ABORT));
@@ -904,17 +906,17 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
return true;
}
-void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
{
REG_WRITE(ah, AR_RXDP, rxdp);
}
-void ath9k_hw_rxena(struct ath_hal *ah)
+void ath9k_hw_rxena(struct ath_hw *ah)
{
REG_WRITE(ah, AR_CR, AR_CR_RXE);
}
-void ath9k_hw_startpcureceive(struct ath_hal *ah)
+void ath9k_hw_startpcureceive(struct ath_hw *ah)
{
ath9k_enable_mib_counters(ah);
@@ -923,24 +925,41 @@ void ath9k_hw_startpcureceive(struct ath_hal *ah)
REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
}
-void ath9k_hw_stoppcurecv(struct ath_hal *ah)
+void ath9k_hw_stoppcurecv(struct ath_hw *ah)
{
REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
ath9k_hw_disable_mib_counters(ah);
}
-bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
{
+#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
+#define AH_RX_TIME_QUANTUM 100 /* usec */
+
+ int i;
+
REG_WRITE(ah, AR_CR, AR_CR_RXD);
- if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
+ /* Wait for rx enable bit to go low */
+ for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
+ if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
+ break;
+ udelay(AH_TIME_QUANTUM);
+ }
+
+ if (i == 0) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "dma failed to stop in 10ms\n"
- "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
- REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
+ "dma failed to stop in %d ms "
+ "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+ AH_RX_STOP_DMA_TIMEOUT / 1000,
+ REG_READ(ah, AR_CR),
+ REG_READ(ah, AR_DIAG_SW));
return false;
} else {
return true;
}
+
+#undef AH_RX_TIME_QUANTUM
+#undef AH_RX_STOP_DMA_TIMEOUT
}
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath9k/mac.h
new file mode 100644
index 00000000000..a75f65dae1d
--- /dev/null
+++ b/drivers/net/wireless/ath9k/mac.h
@@ -0,0 +1,680 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MAC_H
+#define MAC_H
+
+#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ? \
+ MS(ads->ds_rxstatus0, AR_RxRate) : \
+ (ads->ds_rxstatus3 >> 2) & 0xFF)
+
+#define set11nTries(_series, _index) \
+ (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
+
+#define set11nRate(_series, _index) \
+ (SM((_series)[_index].Rate, AR_XmitRate##_index))
+
+#define set11nPktDurRTSCTS(_series, _index) \
+ (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
+ ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
+ AR_RTSCTSQual##_index : 0))
+
+#define set11nRateFlags(_series, _index) \
+ (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
+ AR_2040_##_index : 0) \
+ |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
+ AR_GI##_index : 0) \
+ |SM((_series)[_index].ChSel, AR_ChainSel##_index))
+
+#define CCK_SIFS_TIME 10
+#define CCK_PREAMBLE_BITS 144
+#define CCK_PLCP_BITS 48
+
+#define OFDM_SIFS_TIME 16
+#define OFDM_PREAMBLE_TIME 20
+#define OFDM_PLCP_BITS 22
+#define OFDM_SYMBOL_TIME 4
+
+#define OFDM_SIFS_TIME_HALF 32
+#define OFDM_PREAMBLE_TIME_HALF 40
+#define OFDM_PLCP_BITS_HALF 22
+#define OFDM_SYMBOL_TIME_HALF 8
+
+#define OFDM_SIFS_TIME_QUARTER 64
+#define OFDM_PREAMBLE_TIME_QUARTER 80
+#define OFDM_PLCP_BITS_QUARTER 22
+#define OFDM_SYMBOL_TIME_QUARTER 16
+
+#define INIT_AIFS 2
+#define INIT_CWMIN 15
+#define INIT_CWMIN_11B 31
+#define INIT_CWMAX 1023
+#define INIT_SH_RETRY 10
+#define INIT_LG_RETRY 10
+#define INIT_SSH_RETRY 32
+#define INIT_SLG_RETRY 32
+
+#define ATH9K_SLOT_TIME_6 6
+#define ATH9K_SLOT_TIME_9 9
+#define ATH9K_SLOT_TIME_20 20
+
+#define ATH9K_TXERR_XRETRY 0x01
+#define ATH9K_TXERR_FILT 0x02
+#define ATH9K_TXERR_FIFO 0x04
+#define ATH9K_TXERR_XTXOP 0x08
+#define ATH9K_TXERR_TIMER_EXPIRED 0x10
+
+#define ATH9K_TX_BA 0x01
+#define ATH9K_TX_PWRMGMT 0x02
+#define ATH9K_TX_DESC_CFG_ERR 0x04
+#define ATH9K_TX_DATA_UNDERRUN 0x08
+#define ATH9K_TX_DELIM_UNDERRUN 0x10
+#define ATH9K_TX_SW_ABORTED 0x40
+#define ATH9K_TX_SW_FILTERED 0x80
+
+#define MIN_TX_FIFO_THRESHOLD 0x1
+#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
+#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
+
+struct ath_tx_status {
+ u32 ts_tstamp;
+ u16 ts_seqnum;
+ u8 ts_status;
+ u8 ts_ratecode;
+ u8 ts_rateindex;
+ int8_t ts_rssi;
+ u8 ts_shortretry;
+ u8 ts_longretry;
+ u8 ts_virtcol;
+ u8 ts_antenna;
+ u8 ts_flags;
+ int8_t ts_rssi_ctl0;
+ int8_t ts_rssi_ctl1;
+ int8_t ts_rssi_ctl2;
+ int8_t ts_rssi_ext0;
+ int8_t ts_rssi_ext1;
+ int8_t ts_rssi_ext2;
+ u8 pad[3];
+ u32 ba_low;
+ u32 ba_high;
+ u32 evm0;
+ u32 evm1;
+ u32 evm2;
+};
+
+struct ath_rx_status {
+ u32 rs_tstamp;
+ u16 rs_datalen;
+ u8 rs_status;
+ u8 rs_phyerr;
+ int8_t rs_rssi;
+ u8 rs_keyix;
+ u8 rs_rate;
+ u8 rs_antenna;
+ u8 rs_more;
+ int8_t rs_rssi_ctl0;
+ int8_t rs_rssi_ctl1;
+ int8_t rs_rssi_ctl2;
+ int8_t rs_rssi_ext0;
+ int8_t rs_rssi_ext1;
+ int8_t rs_rssi_ext2;
+ u8 rs_isaggr;
+ u8 rs_moreaggr;
+ u8 rs_num_delims;
+ u8 rs_flags;
+ u32 evm0;
+ u32 evm1;
+ u32 evm2;
+};
+
+#define ATH9K_RXERR_CRC 0x01
+#define ATH9K_RXERR_PHY 0x02
+#define ATH9K_RXERR_FIFO 0x04
+#define ATH9K_RXERR_DECRYPT 0x08
+#define ATH9K_RXERR_MIC 0x10
+
+#define ATH9K_RX_MORE 0x01
+#define ATH9K_RX_MORE_AGGR 0x02
+#define ATH9K_RX_GI 0x04
+#define ATH9K_RX_2040 0x08
+#define ATH9K_RX_DELIM_CRC_PRE 0x10
+#define ATH9K_RX_DELIM_CRC_POST 0x20
+#define ATH9K_RX_DECRYPT_BUSY 0x40
+
+#define ATH9K_RXKEYIX_INVALID ((u8)-1)
+#define ATH9K_TXKEYIX_INVALID ((u32)-1)
+
+struct ath_desc {
+ u32 ds_link;
+ u32 ds_data;
+ u32 ds_ctl0;
+ u32 ds_ctl1;
+ u32 ds_hw[20];
+ union {
+ struct ath_tx_status tx;
+ struct ath_rx_status rx;
+ void *stats;
+ } ds_us;
+ void *ds_vdata;
+} __packed;
+
+#define ds_txstat ds_us.tx
+#define ds_rxstat ds_us.rx
+#define ds_stat ds_us.stats
+
+#define ATH9K_TXDESC_CLRDMASK 0x0001
+#define ATH9K_TXDESC_NOACK 0x0002
+#define ATH9K_TXDESC_RTSENA 0x0004
+#define ATH9K_TXDESC_CTSENA 0x0008
+/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
+ * the descriptor its marked on. We take a tx interrupt to reap
+ * descriptors when the h/w hits an EOL condition or
+ * when the descriptor is specifically marked to generate
+ * an interrupt with this flag. Descriptors should be
+ * marked periodically to insure timely replenishing of the
+ * supply needed for sending frames. Defering interrupts
+ * reduces system load and potentially allows more concurrent
+ * work to be done but if done to aggressively can cause
+ * senders to backup. When the hardware queue is left too
+ * large rate control information may also be too out of
+ * date. An Alternative for this is TX interrupt mitigation
+ * but this needs more testing. */
+#define ATH9K_TXDESC_INTREQ 0x0010
+#define ATH9K_TXDESC_VEOL 0x0020
+#define ATH9K_TXDESC_EXT_ONLY 0x0040
+#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
+#define ATH9K_TXDESC_VMF 0x0100
+#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
+#define ATH9K_TXDESC_CAB 0x0400
+
+#define ATH9K_RXDESC_INTREQ 0x0020
+
+struct ar5416_desc {
+ u32 ds_link;
+ u32 ds_data;
+ u32 ds_ctl0;
+ u32 ds_ctl1;
+ union {
+ struct {
+ u32 ctl2;
+ u32 ctl3;
+ u32 ctl4;
+ u32 ctl5;
+ u32 ctl6;
+ u32 ctl7;
+ u32 ctl8;
+ u32 ctl9;
+ u32 ctl10;
+ u32 ctl11;
+ u32 status0;
+ u32 status1;
+ u32 status2;
+ u32 status3;
+ u32 status4;
+ u32 status5;
+ u32 status6;
+ u32 status7;
+ u32 status8;
+ u32 status9;
+ } tx;
+ struct {
+ u32 status0;
+ u32 status1;
+ u32 status2;
+ u32 status3;
+ u32 status4;
+ u32 status5;
+ u32 status6;
+ u32 status7;
+ u32 status8;
+ } rx;
+ } u;
+} __packed;
+
+#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
+#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
+
+#define ds_ctl2 u.tx.ctl2
+#define ds_ctl3 u.tx.ctl3
+#define ds_ctl4 u.tx.ctl4
+#define ds_ctl5 u.tx.ctl5
+#define ds_ctl6 u.tx.ctl6
+#define ds_ctl7 u.tx.ctl7
+#define ds_ctl8 u.tx.ctl8
+#define ds_ctl9 u.tx.ctl9
+#define ds_ctl10 u.tx.ctl10
+#define ds_ctl11 u.tx.ctl11
+
+#define ds_txstatus0 u.tx.status0
+#define ds_txstatus1 u.tx.status1
+#define ds_txstatus2 u.tx.status2
+#define ds_txstatus3 u.tx.status3
+#define ds_txstatus4 u.tx.status4
+#define ds_txstatus5 u.tx.status5
+#define ds_txstatus6 u.tx.status6
+#define ds_txstatus7 u.tx.status7
+#define ds_txstatus8 u.tx.status8
+#define ds_txstatus9 u.tx.status9
+
+#define ds_rxstatus0 u.rx.status0
+#define ds_rxstatus1 u.rx.status1
+#define ds_rxstatus2 u.rx.status2
+#define ds_rxstatus3 u.rx.status3
+#define ds_rxstatus4 u.rx.status4
+#define ds_rxstatus5 u.rx.status5
+#define ds_rxstatus6 u.rx.status6
+#define ds_rxstatus7 u.rx.status7
+#define ds_rxstatus8 u.rx.status8
+
+#define AR_FrameLen 0x00000fff
+#define AR_VirtMoreFrag 0x00001000
+#define AR_TxCtlRsvd00 0x0000e000
+#define AR_XmitPower 0x003f0000
+#define AR_XmitPower_S 16
+#define AR_RTSEnable 0x00400000
+#define AR_VEOL 0x00800000
+#define AR_ClrDestMask 0x01000000
+#define AR_TxCtlRsvd01 0x1e000000
+#define AR_TxIntrReq 0x20000000
+#define AR_DestIdxValid 0x40000000
+#define AR_CTSEnable 0x80000000
+
+#define AR_BufLen 0x00000fff
+#define AR_TxMore 0x00001000
+#define AR_DestIdx 0x000fe000
+#define AR_DestIdx_S 13
+#define AR_FrameType 0x00f00000
+#define AR_FrameType_S 20
+#define AR_NoAck 0x01000000
+#define AR_InsertTS 0x02000000
+#define AR_CorruptFCS 0x04000000
+#define AR_ExtOnly 0x08000000
+#define AR_ExtAndCtl 0x10000000
+#define AR_MoreAggr 0x20000000
+#define AR_IsAggr 0x40000000
+
+#define AR_BurstDur 0x00007fff
+#define AR_BurstDur_S 0
+#define AR_DurUpdateEna 0x00008000
+#define AR_XmitDataTries0 0x000f0000
+#define AR_XmitDataTries0_S 16
+#define AR_XmitDataTries1 0x00f00000
+#define AR_XmitDataTries1_S 20
+#define AR_XmitDataTries2 0x0f000000
+#define AR_XmitDataTries2_S 24
+#define AR_XmitDataTries3 0xf0000000
+#define AR_XmitDataTries3_S 28
+
+#define AR_XmitRate0 0x000000ff
+#define AR_XmitRate0_S 0
+#define AR_XmitRate1 0x0000ff00
+#define AR_XmitRate1_S 8
+#define AR_XmitRate2 0x00ff0000
+#define AR_XmitRate2_S 16
+#define AR_XmitRate3 0xff000000
+#define AR_XmitRate3_S 24
+
+#define AR_PacketDur0 0x00007fff
+#define AR_PacketDur0_S 0
+#define AR_RTSCTSQual0 0x00008000
+#define AR_PacketDur1 0x7fff0000
+#define AR_PacketDur1_S 16
+#define AR_RTSCTSQual1 0x80000000
+
+#define AR_PacketDur2 0x00007fff
+#define AR_PacketDur2_S 0
+#define AR_RTSCTSQual2 0x00008000
+#define AR_PacketDur3 0x7fff0000
+#define AR_PacketDur3_S 16
+#define AR_RTSCTSQual3 0x80000000
+
+#define AR_AggrLen 0x0000ffff
+#define AR_AggrLen_S 0
+#define AR_TxCtlRsvd60 0x00030000
+#define AR_PadDelim 0x03fc0000
+#define AR_PadDelim_S 18
+#define AR_EncrType 0x0c000000
+#define AR_EncrType_S 26
+#define AR_TxCtlRsvd61 0xf0000000
+
+#define AR_2040_0 0x00000001
+#define AR_GI0 0x00000002
+#define AR_ChainSel0 0x0000001c
+#define AR_ChainSel0_S 2
+#define AR_2040_1 0x00000020
+#define AR_GI1 0x00000040
+#define AR_ChainSel1 0x00000380
+#define AR_ChainSel1_S 7
+#define AR_2040_2 0x00000400
+#define AR_GI2 0x00000800
+#define AR_ChainSel2 0x00007000
+#define AR_ChainSel2_S 12
+#define AR_2040_3 0x00008000
+#define AR_GI3 0x00010000
+#define AR_ChainSel3 0x000e0000
+#define AR_ChainSel3_S 17
+#define AR_RTSCTSRate 0x0ff00000
+#define AR_RTSCTSRate_S 20
+#define AR_TxCtlRsvd70 0xf0000000
+
+#define AR_TxRSSIAnt00 0x000000ff
+#define AR_TxRSSIAnt00_S 0
+#define AR_TxRSSIAnt01 0x0000ff00
+#define AR_TxRSSIAnt01_S 8
+#define AR_TxRSSIAnt02 0x00ff0000
+#define AR_TxRSSIAnt02_S 16
+#define AR_TxStatusRsvd00 0x3f000000
+#define AR_TxBaStatus 0x40000000
+#define AR_TxStatusRsvd01 0x80000000
+
+#define AR_FrmXmitOK 0x00000001
+#define AR_ExcessiveRetries 0x00000002
+#define AR_FIFOUnderrun 0x00000004
+#define AR_Filtered 0x00000008
+#define AR_RTSFailCnt 0x000000f0
+#define AR_RTSFailCnt_S 4
+#define AR_DataFailCnt 0x00000f00
+#define AR_DataFailCnt_S 8
+#define AR_VirtRetryCnt 0x0000f000
+#define AR_VirtRetryCnt_S 12
+#define AR_TxDelimUnderrun 0x00010000
+#define AR_TxDataUnderrun 0x00020000
+#define AR_DescCfgErr 0x00040000
+#define AR_TxTimerExpired 0x00080000
+#define AR_TxStatusRsvd10 0xfff00000
+
+#define AR_SendTimestamp ds_txstatus2
+#define AR_BaBitmapLow ds_txstatus3
+#define AR_BaBitmapHigh ds_txstatus4
+
+#define AR_TxRSSIAnt10 0x000000ff
+#define AR_TxRSSIAnt10_S 0
+#define AR_TxRSSIAnt11 0x0000ff00
+#define AR_TxRSSIAnt11_S 8
+#define AR_TxRSSIAnt12 0x00ff0000
+#define AR_TxRSSIAnt12_S 16
+#define AR_TxRSSICombined 0xff000000
+#define AR_TxRSSICombined_S 24
+
+#define AR_TxEVM0 ds_txstatus5
+#define AR_TxEVM1 ds_txstatus6
+#define AR_TxEVM2 ds_txstatus7
+
+#define AR_TxDone 0x00000001
+#define AR_SeqNum 0x00001ffe
+#define AR_SeqNum_S 1
+#define AR_TxStatusRsvd80 0x0001e000
+#define AR_TxOpExceeded 0x00020000
+#define AR_TxStatusRsvd81 0x001c0000
+#define AR_FinalTxIdx 0x00600000
+#define AR_FinalTxIdx_S 21
+#define AR_TxStatusRsvd82 0x01800000
+#define AR_PowerMgmt 0x02000000
+#define AR_TxStatusRsvd83 0xfc000000
+
+#define AR_RxCTLRsvd00 0xffffffff
+
+#define AR_BufLen 0x00000fff
+#define AR_RxCtlRsvd00 0x00001000
+#define AR_RxIntrReq 0x00002000
+#define AR_RxCtlRsvd01 0xffffc000
+
+#define AR_RxRSSIAnt00 0x000000ff
+#define AR_RxRSSIAnt00_S 0
+#define AR_RxRSSIAnt01 0x0000ff00
+#define AR_RxRSSIAnt01_S 8
+#define AR_RxRSSIAnt02 0x00ff0000
+#define AR_RxRSSIAnt02_S 16
+#define AR_RxRate 0xff000000
+#define AR_RxRate_S 24
+#define AR_RxStatusRsvd00 0xff000000
+
+#define AR_DataLen 0x00000fff
+#define AR_RxMore 0x00001000
+#define AR_NumDelim 0x003fc000
+#define AR_NumDelim_S 14
+#define AR_RxStatusRsvd10 0xff800000
+
+#define AR_RcvTimestamp ds_rxstatus2
+
+#define AR_GI 0x00000001
+#define AR_2040 0x00000002
+#define AR_Parallel40 0x00000004
+#define AR_Parallel40_S 2
+#define AR_RxStatusRsvd30 0x000000f8
+#define AR_RxAntenna 0xffffff00
+#define AR_RxAntenna_S 8
+
+#define AR_RxRSSIAnt10 0x000000ff
+#define AR_RxRSSIAnt10_S 0
+#define AR_RxRSSIAnt11 0x0000ff00
+#define AR_RxRSSIAnt11_S 8
+#define AR_RxRSSIAnt12 0x00ff0000
+#define AR_RxRSSIAnt12_S 16
+#define AR_RxRSSICombined 0xff000000
+#define AR_RxRSSICombined_S 24
+
+#define AR_RxEVM0 ds_rxstatus4
+#define AR_RxEVM1 ds_rxstatus5
+#define AR_RxEVM2 ds_rxstatus6
+
+#define AR_RxDone 0x00000001
+#define AR_RxFrameOK 0x00000002
+#define AR_CRCErr 0x00000004
+#define AR_DecryptCRCErr 0x00000008
+#define AR_PHYErr 0x00000010
+#define AR_MichaelErr 0x00000020
+#define AR_PreDelimCRCErr 0x00000040
+#define AR_RxStatusRsvd70 0x00000080
+#define AR_RxKeyIdxValid 0x00000100
+#define AR_KeyIdx 0x0000fe00
+#define AR_KeyIdx_S 9
+#define AR_PHYErrCode 0x0000ff00
+#define AR_PHYErrCode_S 8
+#define AR_RxMoreAggr 0x00010000
+#define AR_RxAggr 0x00020000
+#define AR_PostDelimCRCErr 0x00040000
+#define AR_RxStatusRsvd71 0x3ff80000
+#define AR_DecryptBusyErr 0x40000000
+#define AR_KeyMiss 0x80000000
+
+enum ath9k_tx_queue {
+ ATH9K_TX_QUEUE_INACTIVE = 0,
+ ATH9K_TX_QUEUE_DATA,
+ ATH9K_TX_QUEUE_BEACON,
+ ATH9K_TX_QUEUE_CAB,
+ ATH9K_TX_QUEUE_UAPSD,
+ ATH9K_TX_QUEUE_PSPOLL
+};
+
+#define ATH9K_NUM_TX_QUEUES 10
+
+enum ath9k_tx_queue_subtype {
+ ATH9K_WME_AC_BK = 0,
+ ATH9K_WME_AC_BE,
+ ATH9K_WME_AC_VI,
+ ATH9K_WME_AC_VO,
+ ATH9K_WME_UPSD
+};
+
+enum ath9k_tx_queue_flags {
+ TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
+ TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
+ TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
+ TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
+ TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
+ TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
+ TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
+ TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
+ TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
+};
+
+#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
+#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
+
+#define ATH9K_DECOMP_MASK_SIZE 128
+#define ATH9K_READY_TIME_LO_BOUND 50
+#define ATH9K_READY_TIME_HI_BOUND 96
+
+enum ath9k_pkt_type {
+ ATH9K_PKT_TYPE_NORMAL = 0,
+ ATH9K_PKT_TYPE_ATIM,
+ ATH9K_PKT_TYPE_PSPOLL,
+ ATH9K_PKT_TYPE_BEACON,
+ ATH9K_PKT_TYPE_PROBE_RESP,
+ ATH9K_PKT_TYPE_CHIRP,
+ ATH9K_PKT_TYPE_GRP_POLL,
+};
+
+struct ath9k_tx_queue_info {
+ u32 tqi_ver;
+ enum ath9k_tx_queue tqi_type;
+ enum ath9k_tx_queue_subtype tqi_subtype;
+ enum ath9k_tx_queue_flags tqi_qflags;
+ u32 tqi_priority;
+ u32 tqi_aifs;
+ u32 tqi_cwmin;
+ u32 tqi_cwmax;
+ u16 tqi_shretry;
+ u16 tqi_lgretry;
+ u32 tqi_cbrPeriod;
+ u32 tqi_cbrOverflowLimit;
+ u32 tqi_burstTime;
+ u32 tqi_readyTime;
+ u32 tqi_physCompBuf;
+ u32 tqi_intFlags;
+};
+
+enum ath9k_rx_filter {
+ ATH9K_RX_FILTER_UCAST = 0x00000001,
+ ATH9K_RX_FILTER_MCAST = 0x00000002,
+ ATH9K_RX_FILTER_BCAST = 0x00000004,
+ ATH9K_RX_FILTER_CONTROL = 0x00000008,
+ ATH9K_RX_FILTER_BEACON = 0x00000010,
+ ATH9K_RX_FILTER_PROM = 0x00000020,
+ ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
+ ATH9K_RX_FILTER_PHYERR = 0x00000100,
+ ATH9K_RX_FILTER_MYBEACON = 0x00000200,
+ ATH9K_RX_FILTER_PSPOLL = 0x00004000,
+ ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+ ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
+};
+
+#define ATH9K_RATESERIES_RTS_CTS 0x0001
+#define ATH9K_RATESERIES_2040 0x0002
+#define ATH9K_RATESERIES_HALFGI 0x0004
+
+struct ath9k_11n_rate_series {
+ u32 Tries;
+ u32 Rate;
+ u32 PktDuration;
+ u32 ChSel;
+ u32 RateFlags;
+};
+
+struct ath9k_keyval {
+ u8 kv_type;
+ u8 kv_pad;
+ u16 kv_len;
+ u8 kv_val[16]; /* TK */
+ u8 kv_mic[8]; /* Michael MIC key */
+ u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+ * supports both MIC keys in the same key cache entry;
+ * in that case, kv_mic is the RX key) */
+};
+
+enum ath9k_key_type {
+ ATH9K_KEY_TYPE_CLEAR,
+ ATH9K_KEY_TYPE_WEP,
+ ATH9K_KEY_TYPE_AES,
+ ATH9K_KEY_TYPE_TKIP,
+};
+
+enum ath9k_cipher {
+ ATH9K_CIPHER_WEP = 0,
+ ATH9K_CIPHER_AES_OCB = 1,
+ ATH9K_CIPHER_AES_CCM = 2,
+ ATH9K_CIPHER_CKIP = 3,
+ ATH9K_CIPHER_TKIP = 4,
+ ATH9K_CIPHER_CLR = 5,
+ ATH9K_CIPHER_MIC = 127
+};
+
+enum ath9k_ht_macmode {
+ ATH9K_HT_MACMODE_20 = 0,
+ ATH9K_HT_MACMODE_2040 = 1,
+};
+
+enum ath9k_ht_extprotspacing {
+ ATH9K_HT_EXTPROTSPACING_20 = 0,
+ ATH9K_HT_EXTPROTSPACING_25 = 1,
+};
+
+struct ath_hw;
+struct ath9k_channel;
+struct ath_rate_table;
+
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+ u32 segLen, bool firstSeg,
+ bool lastSeg, const struct ath_desc *ds0);
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
+ u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+ u32 keyIx, enum ath9k_key_type keyType, u32 flags);
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
+ struct ath_desc *lastds,
+ u32 durUpdateEn, u32 rtsctsRate,
+ u32 rtsctsDuration,
+ struct ath9k_11n_rate_series series[],
+ u32 nseries, u32 flags);
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
+ u32 aggrLen);
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
+ u32 numDelims);
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
+ u32 burstDuration);
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
+ u32 vmf);
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+ const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
+ struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+ const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+ u32 pa, struct ath_desc *nds, u64 tsf);
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+ u32 size, u32 flags);
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
+void ath9k_hw_rxena(struct ath_hw *ah);
+void ath9k_hw_startpcureceive(struct ath_hw *ah);
+void ath9k_hw_stoppcurecv(struct ath_hw *ah);
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
+
+#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 727f067aca4..8db75f6de53 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -15,9 +15,7 @@
*/
#include <linux/nl80211.h>
-#include "core.h"
-#include "reg.h"
-#include "hw.h"
+#include "ath9k.h"
#define ATH_PCI_VERSION "0.1"
@@ -28,84 +26,129 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");
-static struct pci_device_id ath_pci_id_table[] __devinitdata = {
- { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
- { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
- { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
- { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
- { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
- { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
- { 0 }
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
+
+/* We use the hw_value as an index into our private channel structure */
+
+#define CHAN2G(_freq, _idx) { \
+ .center_freq = (_freq), \
+ .hw_value = (_idx), \
+ .max_power = 30, \
+}
+
+#define CHAN5G(_freq, _idx) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_idx), \
+ .max_power = 30, \
+}
+
+/* Some 2 GHz radios are actually tunable on 2312-2732
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_2ghz_chantable[] = {
+ CHAN2G(2412, 0), /* Channel 1 */
+ CHAN2G(2417, 1), /* Channel 2 */
+ CHAN2G(2422, 2), /* Channel 3 */
+ CHAN2G(2427, 3), /* Channel 4 */
+ CHAN2G(2432, 4), /* Channel 5 */
+ CHAN2G(2437, 5), /* Channel 6 */
+ CHAN2G(2442, 6), /* Channel 7 */
+ CHAN2G(2447, 7), /* Channel 8 */
+ CHAN2G(2452, 8), /* Channel 9 */
+ CHAN2G(2457, 9), /* Channel 10 */
+ CHAN2G(2462, 10), /* Channel 11 */
+ CHAN2G(2467, 11), /* Channel 12 */
+ CHAN2G(2472, 12), /* Channel 13 */
+ CHAN2G(2484, 13), /* Channel 14 */
};
-static void ath_detach(struct ath_softc *sc);
-
-/* return bus cachesize in 4B word units */
-
-static void bus_read_cachesize(struct ath_softc *sc, int *csz)
-{
- u8 u8tmp;
-
- pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
- *csz = (int)u8tmp;
-
- /*
- * This check was put in to avoid "unplesant" consequences if
- * the bootrom has not fully initialized all PCI devices.
- * Sometimes the cache line size register is not set
- */
-
- if (*csz == 0)
- *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
-}
-
-static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
-{
- sc->cur_rate_table = sc->hw_rate_table[mode];
- /*
- * All protection frames are transmited at 2Mb/s for
- * 11g, otherwise at 1Mb/s.
- * XXX select protection rate index from rate table.
- */
- sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0);
-}
+/* Some 5 GHz radios are actually tunable on XXXX-YYYY
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_5ghz_chantable[] = {
+ /* _We_ call this UNII 1 */
+ CHAN5G(5180, 14), /* Channel 36 */
+ CHAN5G(5200, 15), /* Channel 40 */
+ CHAN5G(5220, 16), /* Channel 44 */
+ CHAN5G(5240, 17), /* Channel 48 */
+ /* _We_ call this UNII 2 */
+ CHAN5G(5260, 18), /* Channel 52 */
+ CHAN5G(5280, 19), /* Channel 56 */
+ CHAN5G(5300, 20), /* Channel 60 */
+ CHAN5G(5320, 21), /* Channel 64 */
+ /* _We_ call this "Middle band" */
+ CHAN5G(5500, 22), /* Channel 100 */
+ CHAN5G(5520, 23), /* Channel 104 */
+ CHAN5G(5540, 24), /* Channel 108 */
+ CHAN5G(5560, 25), /* Channel 112 */
+ CHAN5G(5580, 26), /* Channel 116 */
+ CHAN5G(5600, 27), /* Channel 120 */
+ CHAN5G(5620, 28), /* Channel 124 */
+ CHAN5G(5640, 29), /* Channel 128 */
+ CHAN5G(5660, 30), /* Channel 132 */
+ CHAN5G(5680, 31), /* Channel 136 */
+ CHAN5G(5700, 32), /* Channel 140 */
+ /* _We_ call this UNII 3 */
+ CHAN5G(5745, 33), /* Channel 149 */
+ CHAN5G(5765, 34), /* Channel 153 */
+ CHAN5G(5785, 35), /* Channel 157 */
+ CHAN5G(5805, 36), /* Channel 161 */
+ CHAN5G(5825, 37), /* Channel 165 */
+};
-static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
+static void ath_cache_conf_rate(struct ath_softc *sc,
+ struct ieee80211_conf *conf)
{
- if (chan->chanmode == CHANNEL_A)
- return ATH9K_MODE_11A;
- else if (chan->chanmode == CHANNEL_G)
- return ATH9K_MODE_11G;
- else if (chan->chanmode == CHANNEL_B)
- return ATH9K_MODE_11B;
- else if (chan->chanmode == CHANNEL_A_HT20)
- return ATH9K_MODE_11NA_HT20;
- else if (chan->chanmode == CHANNEL_G_HT20)
- return ATH9K_MODE_11NG_HT20;
- else if (chan->chanmode == CHANNEL_A_HT40PLUS)
- return ATH9K_MODE_11NA_HT40PLUS;
- else if (chan->chanmode == CHANNEL_A_HT40MINUS)
- return ATH9K_MODE_11NA_HT40MINUS;
- else if (chan->chanmode == CHANNEL_G_HT40PLUS)
- return ATH9K_MODE_11NG_HT40PLUS;
- else if (chan->chanmode == CHANNEL_G_HT40MINUS)
- return ATH9K_MODE_11NG_HT40MINUS;
-
- WARN_ON(1); /* should not get here */
-
- return ATH9K_MODE_11B;
+ switch (conf->channel->band) {
+ case IEEE80211_BAND_2GHZ:
+ if (conf_is_ht20(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
+ else if (conf_is_ht40_minus(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+ else if (conf_is_ht40_plus(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+ else
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11G];
+ break;
+ case IEEE80211_BAND_5GHZ:
+ if (conf_is_ht20(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
+ else if (conf_is_ht40_minus(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+ else if (conf_is_ht40_plus(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+ else
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11A];
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
}
static void ath_update_txpow(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
u32 txpow;
- if (sc->sc_curtxpow != sc->sc_config.txpowlimit) {
- ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit);
+ if (sc->curtxpow != sc->config.txpowlimit) {
+ ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
/* read back in case value is clamped */
ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
- sc->sc_curtxpow = txpow;
+ sc->curtxpow = txpow;
}
}
@@ -176,150 +219,87 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
for (i = 0; i < maxrates; i++) {
rate[i].bitrate = rate_table->info[i].ratekbps / 100;
rate[i].hw_value = rate_table->info[i].ratecode;
+ if (rate_table->info[i].short_preamble) {
+ rate[i].hw_value_short = rate_table->info[i].ratecode |
+ rate_table->info[i].short_preamble;
+ rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE;
+ }
sband->n_bitrates++;
+
DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n",
rate[i].bitrate / 10, rate[i].hw_value);
}
}
-static int ath_setup_channels(struct ath_softc *sc)
-{
- struct ath_hal *ah = sc->sc_ah;
- int nchan, i, a = 0, b = 0;
- u8 regclassids[ATH_REGCLASSIDS_MAX];
- u32 nregclass = 0;
- struct ieee80211_supported_band *band_2ghz;
- struct ieee80211_supported_band *band_5ghz;
- struct ieee80211_channel *chan_2ghz;
- struct ieee80211_channel *chan_5ghz;
- struct ath9k_channel *c;
-
- /* Fill in ah->ah_channels */
- if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan,
- regclassids, ATH_REGCLASSIDS_MAX,
- &nregclass, CTRY_DEFAULT, false, 1)) {
- u32 rd = ah->ah_currentRD;
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to collect channel list; "
- "regdomain likely %u country code %u\n",
- rd, CTRY_DEFAULT);
- return -EINVAL;
- }
-
- band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
- band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
- chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ];
- chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ];
-
- for (i = 0; i < nchan; i++) {
- c = &ah->ah_channels[i];
- if (IS_CHAN_2GHZ(c)) {
- chan_2ghz[a].band = IEEE80211_BAND_2GHZ;
- chan_2ghz[a].center_freq = c->channel;
- chan_2ghz[a].max_power = c->maxTxPower;
-
- if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
- chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS;
- if (c->channelFlags & CHANNEL_PASSIVE)
- chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- band_2ghz->n_channels = ++a;
-
- DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, "
- "channelFlags: 0x%x\n",
- c->channel, c->channelFlags);
- } else if (IS_CHAN_5GHZ(c)) {
- chan_5ghz[b].band = IEEE80211_BAND_5GHZ;
- chan_5ghz[b].center_freq = c->channel;
- chan_5ghz[b].max_power = c->maxTxPower;
-
- if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
- chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS;
- if (c->channelFlags & CHANNEL_PASSIVE)
- chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- band_5ghz->n_channels = ++b;
-
- DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, "
- "channelFlags: 0x%x\n",
- c->channel, c->channelFlags);
- }
- }
-
- return 0;
-}
-
/*
* Set/change channels. If the channel is really being changed, it's done
* by reseting the chip. To accomplish this we must first cleanup any pending
* DMA, then restart stuff.
*/
-static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+ struct ath9k_channel *hchan)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
bool fastcc = true, stopped;
+ struct ieee80211_channel *channel = hw->conf.channel;
+ int r;
if (sc->sc_flags & SC_OP_INVALID)
return -EIO;
- if (hchan->channel != sc->sc_ah->ah_curchan->channel ||
- hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags ||
- (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
- (sc->sc_flags & SC_OP_FULL_RESET)) {
- int status;
- /*
- * This is only performed if the channel settings have
- * actually changed.
- *
- * To switch channels clear any pending DMA operations;
- * wait long enough for the RX fifo to drain, reset the
- * hardware at the new frequency, and then re-enable
- * the relevant bits of the h/w.
- */
- ath9k_hw_set_interrupts(ah, 0);
- ath_draintxq(sc, false);
- stopped = ath_stoprecv(sc);
-
- /* XXX: do not flush receive queue here. We don't want
- * to flush data frames already in queue because of
- * changing channel. */
-
- if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
- fastcc = false;
-
- DPRINTF(sc, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n",
- sc->sc_ah->ah_curchan->channel,
- hchan->channel, hchan->channelFlags, sc->tx_chan_width);
-
- spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width,
- sc->sc_tx_chainmask, sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing, fastcc, &status)) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset channel %u (%uMhz) "
- "flags 0x%x hal status %u\n",
- ath9k_hw_mhz2ieee(ah, hchan->channel,
- hchan->channelFlags),
- hchan->channel, hchan->channelFlags, status);
- spin_unlock_bh(&sc->sc_resetlock);
- return -EIO;
- }
- spin_unlock_bh(&sc->sc_resetlock);
+ ath9k_ps_wakeup(sc);
- sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
- sc->sc_flags &= ~SC_OP_FULL_RESET;
+ /*
+ * This is only performed if the channel settings have
+ * actually changed.
+ *
+ * To switch channels clear any pending DMA operations;
+ * wait long enough for the RX fifo to drain, reset the
+ * hardware at the new frequency, and then re-enable
+ * the relevant bits of the h/w.
+ */
+ ath9k_hw_set_interrupts(ah, 0);
+ ath_drain_all_txq(sc, false);
+ stopped = ath_stoprecv(sc);
- if (ath_startrecv(sc) != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to restart recv logic\n");
- return -EIO;
- }
+ /* XXX: do not flush receive queue here. We don't want
+ * to flush data frames already in queue because of
+ * changing channel. */
+
+ if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
+ fastcc = false;
+
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "(%u MHz) -> (%u MHz), chanwidth: %d\n",
+ sc->sc_ah->curchan->channel,
+ channel->center_freq, sc->tx_chan_width);
+
+ spin_lock_bh(&sc->sc_resetlock);
+
+ r = ath9k_hw_reset(ah, hchan, fastcc);
+ if (r) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Unable to reset channel (%u Mhz) "
+ "reset status %u\n",
+ channel->center_freq, r);
+ spin_unlock_bh(&sc->sc_resetlock);
+ return r;
+ }
+ spin_unlock_bh(&sc->sc_resetlock);
- ath_setcurmode(sc, ath_chan2mode(hchan));
- ath_update_txpow(sc);
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
+ sc->sc_flags &= ~SC_OP_FULL_RESET;
+
+ if (ath_startrecv(sc) != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Unable to restart recv logic\n");
+ return -EIO;
}
+
+ ath_cache_conf_rate(sc, &hw->conf);
+ ath_update_txpow(sc);
+ ath9k_hw_set_interrupts(ah, sc->imask);
+ ath9k_ps_restore(sc);
return 0;
}
@@ -332,123 +312,122 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
*/
static void ath_ani_calibrate(unsigned long data)
{
- struct ath_softc *sc;
- struct ath_hal *ah;
+ struct ath_softc *sc = (struct ath_softc *)data;
+ struct ath_hw *ah = sc->sc_ah;
bool longcal = false;
bool shortcal = false;
bool aniflag = false;
unsigned int timestamp = jiffies_to_msecs(jiffies);
- u32 cal_interval;
+ u32 cal_interval, short_cal_interval;
- sc = (struct ath_softc *)data;
- ah = sc->sc_ah;
+ short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
+ ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
/*
* don't calibrate when we're scanning.
* we are most likely not on our home channel.
*/
- if (sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)
- return;
+ if (sc->sc_flags & SC_OP_SCANNING)
+ goto set_timer;
/* Long calibration runs independently of short calibration. */
- if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) {
+ if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
longcal = true;
DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
- sc->sc_ani.sc_longcal_timer = timestamp;
+ sc->ani.longcal_timer = timestamp;
}
- /* Short calibration applies only while sc_caldone is false */
- if (!sc->sc_ani.sc_caldone) {
- if ((timestamp - sc->sc_ani.sc_shortcal_timer) >=
- ATH_SHORT_CALINTERVAL) {
+ /* Short calibration applies only while caldone is false */
+ if (!sc->ani.caldone) {
+ if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) {
shortcal = true;
DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
- sc->sc_ani.sc_shortcal_timer = timestamp;
- sc->sc_ani.sc_resetcal_timer = timestamp;
+ sc->ani.shortcal_timer = timestamp;
+ sc->ani.resetcal_timer = timestamp;
}
} else {
- if ((timestamp - sc->sc_ani.sc_resetcal_timer) >=
+ if ((timestamp - sc->ani.resetcal_timer) >=
ATH_RESTART_CALINTERVAL) {
- ath9k_hw_reset_calvalid(ah, ah->ah_curchan,
- &sc->sc_ani.sc_caldone);
- if (sc->sc_ani.sc_caldone)
- sc->sc_ani.sc_resetcal_timer = timestamp;
+ sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
+ if (sc->ani.caldone)
+ sc->ani.resetcal_timer = timestamp;
}
}
/* Verify whether we must check ANI */
- if ((timestamp - sc->sc_ani.sc_checkani_timer) >=
- ATH_ANI_POLLINTERVAL) {
+ if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
aniflag = true;
- sc->sc_ani.sc_checkani_timer = timestamp;
+ sc->ani.checkani_timer = timestamp;
}
/* Skip all processing if there's nothing to do. */
if (longcal || shortcal || aniflag) {
/* Call ANI routine if necessary */
if (aniflag)
- ath9k_hw_ani_monitor(ah, &sc->sc_halstats,
- ah->ah_curchan);
+ ath9k_hw_ani_monitor(ah, &sc->nodestats, ah->curchan);
/* Perform calibration if necessary */
if (longcal || shortcal) {
bool iscaldone = false;
- if (ath9k_hw_calibrate(ah, ah->ah_curchan,
- sc->sc_rx_chainmask, longcal,
+ if (ath9k_hw_calibrate(ah, ah->curchan,
+ sc->rx_chainmask, longcal,
&iscaldone)) {
if (longcal)
- sc->sc_ani.sc_noise_floor =
+ sc->ani.noise_floor =
ath9k_hw_getchan_noise(ah,
- ah->ah_curchan);
+ ah->curchan);
DPRINTF(sc, ATH_DBG_ANI,
"calibrate chan %u/%x nf: %d\n",
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags,
- sc->sc_ani.sc_noise_floor);
+ ah->curchan->channel,
+ ah->curchan->channelFlags,
+ sc->ani.noise_floor);
} else {
DPRINTF(sc, ATH_DBG_ANY,
"calibrate chan %u/%x failed\n",
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags);
+ ah->curchan->channel,
+ ah->curchan->channelFlags);
}
- sc->sc_ani.sc_caldone = iscaldone;
+ sc->ani.caldone = iscaldone;
}
}
+set_timer:
/*
* Set timer interval based on previous results.
* The interval must be the shortest necessary to satisfy ANI,
* short calibration and long calibration.
*/
cal_interval = ATH_LONG_CALINTERVAL;
- if (sc->sc_ah->ah_config.enable_ani)
+ if (sc->sc_ah->config.enable_ani)
cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
- if (!sc->sc_ani.sc_caldone)
- cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL);
+ if (!sc->ani.caldone)
+ cal_interval = min(cal_interval, (u32)short_cal_interval);
- mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+ mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
}
/*
* Update tx/rx chainmask. For legacy association,
* hard code chainmask to 1x1, for 11n association, use
- * the chainmask configuration.
+ * the chainmask configuration, for bt coexistence, use
+ * the chainmask configuration even in legacy mode.
*/
-static void ath_update_chainmask(struct ath_softc *sc, int is_ht)
+void ath_update_chainmask(struct ath_softc *sc, int is_ht)
{
sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
- if (is_ht) {
- sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask;
- sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask;
+ if (is_ht ||
+ (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
+ sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
+ sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
} else {
- sc->sc_tx_chainmask = 1;
- sc->sc_rx_chainmask = 1;
+ sc->tx_chainmask = 1;
+ sc->rx_chainmask = 1;
}
DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
- sc->sc_tx_chainmask, sc->sc_rx_chainmask);
+ sc->tx_chainmask, sc->rx_chainmask);
}
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
@@ -476,7 +455,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
static void ath9k_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
- u32 status = sc->sc_intrstatus;
+ u32 status = sc->intrstatus;
if (status & ATH9K_INT_FATAL) {
/* need a chip reset */
@@ -496,13 +475,13 @@ static void ath9k_tasklet(unsigned long data)
}
/* re-enable hardware interrupt */
- ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
}
-static irqreturn_t ath_isr(int irq, void *dev)
+irqreturn_t ath_isr(int irq, void *dev)
{
struct ath_softc *sc = dev;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
enum ath9k_int status;
bool sched = false;
@@ -527,7 +506,7 @@ static irqreturn_t ath_isr(int irq, void *dev)
*/
ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
- status &= sc->sc_imask; /* discard unasked-for bits */
+ status &= sc->imask; /* discard unasked-for bits */
/*
* If there are no status bits set, then this interrupt was not
@@ -536,7 +515,8 @@ static irqreturn_t ath_isr(int irq, void *dev)
if (!status)
return IRQ_NONE;
- sc->sc_intrstatus = status;
+ sc->intrstatus = status;
+ ath9k_ps_wakeup(sc);
if (status & ATH9K_INT_FATAL) {
/* need a chip reset */
@@ -583,45 +563,39 @@ static irqreturn_t ath_isr(int irq, void *dev)
* it will clear whatever condition caused
* the interrupt.
*/
- ath9k_hw_procmibevent(ah, &sc->sc_halstats);
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ ath9k_hw_procmibevent(ah, &sc->nodestats);
+ ath9k_hw_set_interrupts(ah, sc->imask);
}
if (status & ATH9K_INT_TIM_TIMER) {
- if (!(ah->ah_caps.hw_caps &
+ if (!(ah->caps.hw_caps &
ATH9K_HW_CAP_AUTOSLEEP)) {
/* Clear RxAbort bit so that we can
* receive frames */
+ ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
ath9k_hw_setrxabort(ah, 0);
sched = true;
+ sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
}
}
+ if (status & ATH9K_INT_TSFOOR) {
+ /* FIXME: Handle this interrupt for power save */
+ sched = true;
+ }
}
+ ath9k_ps_restore(sc);
} while (0);
ath_debug_stat_interrupt(sc, status);
if (sched) {
/* turn off every interrupt except SWBA */
- ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA));
+ ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA));
tasklet_schedule(&sc->intr_tq);
}
return IRQ_HANDLED;
}
-static int ath_get_channel(struct ath_softc *sc,
- struct ieee80211_channel *chan)
-{
- int i;
-
- for (i = 0; i < sc->sc_ah->ah_nchan; i++) {
- if (sc->sc_ah->ah_channels[i].channel == chan->center_freq)
- return i;
- }
-
- return -1;
-}
-
static u32 ath_get_extchanmode(struct ath_softc *sc,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
@@ -664,20 +638,9 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
return chanmode;
}
-static int ath_keyset(struct ath_softc *sc, u16 keyix,
- struct ath9k_keyval *hk, const u8 mac[ETH_ALEN])
-{
- bool status;
-
- status = ath9k_hw_set_keycache_entry(sc->sc_ah,
- keyix, hk, mac, false);
-
- return status != false;
-}
-
static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
- struct ath9k_keyval *hk,
- const u8 *addr)
+ struct ath9k_keyval *hk, const u8 *addr,
+ bool authenticator)
{
const u8 *key_rxmic;
const u8 *key_txmic;
@@ -686,26 +649,33 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
if (addr == NULL) {
- /* Group key installation */
- memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
- return ath_keyset(sc, keyix, hk, addr);
- }
- if (!sc->sc_splitmic) {
/*
- * data key goes at first index,
- * the hal handles the MIC keys at index+64.
+ * Group key installation - only two key cache entries are used
+ * regardless of splitmic capability since group key is only
+ * used either for TX or RX.
*/
+ if (authenticator) {
+ memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
+ } else {
+ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
+ }
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
+ }
+ if (!sc->splitmic) {
+ /* TX and RX keys share the same key cache entry. */
memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
- return ath_keyset(sc, keyix, hk, addr);
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
}
- /*
- * TX key goes at first index, RX key at +32.
- * The hal handles the MIC keys at index+64.
- */
+
+ /* Separate key cache entries for TX and RX */
+
+ /* TX key goes at first index, RX key at +32. */
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
- if (!ath_keyset(sc, keyix, hk, NULL)) {
- /* Txmic entry failed. No need to proceed further */
+ if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
+ /* TX MIC entry failed. No need to proceed further */
DPRINTF(sc, ATH_DBG_KEYCACHE,
"Setting TX MIC Key Failed\n");
return 0;
@@ -713,20 +683,20 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
/* XXX delete tx key on failure? */
- return ath_keyset(sc, keyix + 32, hk, addr);
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
}
static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
{
int i;
- for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) {
- if (test_bit(i, sc->sc_keymap) ||
- test_bit(i + 64, sc->sc_keymap))
+ for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+ if (test_bit(i, sc->keymap) ||
+ test_bit(i + 64, sc->keymap))
continue; /* At least one part of TKIP key allocated */
- if (sc->sc_splitmic &&
- (test_bit(i + 32, sc->sc_keymap) ||
- test_bit(i + 64 + 32, sc->sc_keymap)))
+ if (sc->splitmic &&
+ (test_bit(i + 32, sc->keymap) ||
+ test_bit(i + 64 + 32, sc->keymap)))
continue; /* At least one part of TKIP key allocated */
/* Found a free slot for a TKIP key */
@@ -740,55 +710,55 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc)
int i;
/* First, try to find slots that would not be available for TKIP. */
- if (sc->sc_splitmic) {
- for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 4; i++) {
- if (!test_bit(i, sc->sc_keymap) &&
- (test_bit(i + 32, sc->sc_keymap) ||
- test_bit(i + 64, sc->sc_keymap) ||
- test_bit(i + 64 + 32, sc->sc_keymap)))
+ if (sc->splitmic) {
+ for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) {
+ if (!test_bit(i, sc->keymap) &&
+ (test_bit(i + 32, sc->keymap) ||
+ test_bit(i + 64, sc->keymap) ||
+ test_bit(i + 64 + 32, sc->keymap)))
return i;
- if (!test_bit(i + 32, sc->sc_keymap) &&
- (test_bit(i, sc->sc_keymap) ||
- test_bit(i + 64, sc->sc_keymap) ||
- test_bit(i + 64 + 32, sc->sc_keymap)))
+ if (!test_bit(i + 32, sc->keymap) &&
+ (test_bit(i, sc->keymap) ||
+ test_bit(i + 64, sc->keymap) ||
+ test_bit(i + 64 + 32, sc->keymap)))
return i + 32;
- if (!test_bit(i + 64, sc->sc_keymap) &&
- (test_bit(i , sc->sc_keymap) ||
- test_bit(i + 32, sc->sc_keymap) ||
- test_bit(i + 64 + 32, sc->sc_keymap)))
+ if (!test_bit(i + 64, sc->keymap) &&
+ (test_bit(i , sc->keymap) ||
+ test_bit(i + 32, sc->keymap) ||
+ test_bit(i + 64 + 32, sc->keymap)))
return i + 64;
- if (!test_bit(i + 64 + 32, sc->sc_keymap) &&
- (test_bit(i, sc->sc_keymap) ||
- test_bit(i + 32, sc->sc_keymap) ||
- test_bit(i + 64, sc->sc_keymap)))
+ if (!test_bit(i + 64 + 32, sc->keymap) &&
+ (test_bit(i, sc->keymap) ||
+ test_bit(i + 32, sc->keymap) ||
+ test_bit(i + 64, sc->keymap)))
return i + 64 + 32;
}
} else {
- for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) {
- if (!test_bit(i, sc->sc_keymap) &&
- test_bit(i + 64, sc->sc_keymap))
+ for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+ if (!test_bit(i, sc->keymap) &&
+ test_bit(i + 64, sc->keymap))
return i;
- if (test_bit(i, sc->sc_keymap) &&
- !test_bit(i + 64, sc->sc_keymap))
+ if (test_bit(i, sc->keymap) &&
+ !test_bit(i + 64, sc->keymap))
return i + 64;
}
}
/* No partially used TKIP slots, pick any available slot */
- for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax; i++) {
+ for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) {
/* Do not allow slots that could be needed for TKIP group keys
* to be used. This limitation could be removed if we know that
* TKIP will not be used. */
if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
continue;
- if (sc->sc_splitmic) {
+ if (sc->splitmic) {
if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
continue;
if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
continue;
}
- if (!test_bit(i, sc->sc_keymap))
+ if (!test_bit(i, sc->keymap))
return i; /* Found a free slot for a key */
}
@@ -797,7 +767,8 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc)
}
static int ath_key_config(struct ath_softc *sc,
- const u8 *addr,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct ath9k_keyval hk;
@@ -818,7 +789,7 @@ static int ath_key_config(struct ath_softc *sc,
hk.kv_type = ATH9K_CIPHER_AES_CCM;
break;
default:
- return -EINVAL;
+ return -EOPNOTSUPP;
}
hk.kv_len = key->keylen;
@@ -829,10 +800,10 @@ static int ath_key_config(struct ath_softc *sc,
* need to change with virtual interfaces. */
idx = key->keyidx;
} else if (key->keyidx) {
- struct ieee80211_vif *vif;
+ if (WARN_ON(!sta))
+ return -EOPNOTSUPP;
+ mac = sta->addr;
- mac = addr;
- vif = sc->sc_vaps[0];
if (vif->type != NL80211_IFTYPE_AP) {
/* Only keyidx 0 should be used with unicast key, but
* allow this for client mode for now. */
@@ -840,29 +811,33 @@ static int ath_key_config(struct ath_softc *sc,
} else
return -EIO;
} else {
- mac = addr;
+ if (WARN_ON(!sta))
+ return -EOPNOTSUPP;
+ mac = sta->addr;
+
if (key->alg == ALG_TKIP)
idx = ath_reserve_key_cache_slot_tkip(sc);
else
idx = ath_reserve_key_cache_slot(sc);
if (idx < 0)
- return -EIO; /* no free key cache entries */
+ return -ENOSPC; /* no free key cache entries */
}
if (key->alg == ALG_TKIP)
- ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac);
+ ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
+ vif->type == NL80211_IFTYPE_AP);
else
- ret = ath_keyset(sc, idx, &hk, mac);
+ ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
if (!ret)
return -EIO;
- set_bit(idx, sc->sc_keymap);
+ set_bit(idx, sc->keymap);
if (key->alg == ALG_TKIP) {
- set_bit(idx + 64, sc->sc_keymap);
- if (sc->sc_splitmic) {
- set_bit(idx + 32, sc->sc_keymap);
- set_bit(idx + 64 + 32, sc->sc_keymap);
+ set_bit(idx + 64, sc->keymap);
+ if (sc->splitmic) {
+ set_bit(idx + 32, sc->keymap);
+ set_bit(idx + 64 + 32, sc->keymap);
}
}
@@ -875,18 +850,19 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
if (key->hw_key_idx < IEEE80211_WEP_NKID)
return;
- clear_bit(key->hw_key_idx, sc->sc_keymap);
+ clear_bit(key->hw_key_idx, sc->keymap);
if (key->alg != ALG_TKIP)
return;
- clear_bit(key->hw_key_idx + 64, sc->sc_keymap);
- if (sc->sc_splitmic) {
- clear_bit(key->hw_key_idx + 32, sc->sc_keymap);
- clear_bit(key->hw_key_idx + 64 + 32, sc->sc_keymap);
+ clear_bit(key->hw_key_idx + 64, sc->keymap);
+ if (sc->splitmic) {
+ clear_bit(key->hw_key_idx + 32, sc->keymap);
+ clear_bit(key->hw_key_idx + 64 + 32, sc->keymap);
}
}
-static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
+static void setup_ht_cap(struct ath_softc *sc,
+ struct ieee80211_sta_ht_cap *ht_info)
{
#define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
#define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
@@ -899,10 +875,23 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
+
/* set up supported mcs set */
memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
- ht_info->mcs.rx_mask[0] = 0xff;
- ht_info->mcs.rx_mask[1] = 0xff;
+
+ switch(sc->rx_chainmask) {
+ case 1:
+ ht_info->mcs.rx_mask[0] = 0xff;
+ break;
+ case 3:
+ case 5:
+ case 7:
+ default:
+ ht_info->mcs.rx_mask[0] = 0xff;
+ ht_info->mcs.rx_mask[1] = 0xff;
+ break;
+ }
+
ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
}
@@ -910,36 +899,33 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf)
{
- struct ath_vap *avp = (void *)vif->drv_priv;
+ struct ath_vif *avp = (void *)vif->drv_priv;
if (bss_conf->assoc) {
DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
- bss_conf->aid, sc->sc_curbssid);
+ bss_conf->aid, sc->curbssid);
/* New association, store aid */
if (avp->av_opmode == NL80211_IFTYPE_STATION) {
- sc->sc_curaid = bss_conf->aid;
- ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
- sc->sc_curaid);
+ sc->curaid = bss_conf->aid;
+ ath9k_hw_write_associd(sc);
}
/* Configure the beacon */
- ath_beacon_config(sc, 0);
- sc->sc_flags |= SC_OP_BEACONS;
+ ath_beacon_config(sc, vif);
/* Reset rssi stats */
- sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
- sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
- sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
- sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
+ sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
+ sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
+ sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
+ sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
/* Start ANI */
- mod_timer(&sc->sc_ani.timer,
- jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
-
+ mod_timer(&sc->ani.timer,
+ jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
} else {
DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
- sc->sc_curaid = 0;
+ sc->curaid = 0;
}
}
@@ -947,6 +933,32 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
/* LED functions */
/********************************/
+static void ath_led_blink_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc,
+ ath_led_blink_work.work);
+
+ if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
+ return;
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+ (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
+
+ queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
+ (sc->sc_flags & SC_OP_LED_ON) ?
+ msecs_to_jiffies(sc->led_off_duration) :
+ msecs_to_jiffies(sc->led_on_duration));
+
+ sc->led_on_duration =
+ max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25);
+ sc->led_off_duration =
+ max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10);
+ sc->led_on_cnt = sc->led_off_cnt = 0;
+ if (sc->sc_flags & SC_OP_LED_ON)
+ sc->sc_flags &= ~SC_OP_LED_ON;
+ else
+ sc->sc_flags |= SC_OP_LED_ON;
+}
+
static void ath_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
@@ -956,16 +968,27 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
switch (brightness) {
case LED_OFF:
if (led->led_type == ATH_LED_ASSOC ||
- led->led_type == ATH_LED_RADIO)
+ led->led_type == ATH_LED_RADIO) {
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+ (led->led_type == ATH_LED_RADIO));
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
- (led->led_type == ATH_LED_RADIO) ? 1 :
- !!(sc->sc_flags & SC_OP_LED_ASSOCIATED));
+ if (led->led_type == ATH_LED_RADIO)
+ sc->sc_flags &= ~SC_OP_LED_ON;
+ } else {
+ sc->led_off_cnt++;
+ }
break;
case LED_FULL:
- if (led->led_type == ATH_LED_ASSOC)
+ if (led->led_type == ATH_LED_ASSOC) {
sc->sc_flags |= SC_OP_LED_ASSOCIATED;
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+ queue_delayed_work(sc->hw->workqueue,
+ &sc->ath_led_blink_work, 0);
+ } else if (led->led_type == ATH_LED_RADIO) {
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+ sc->sc_flags |= SC_OP_LED_ON;
+ } else {
+ sc->led_on_cnt++;
+ }
break;
default:
break;
@@ -1001,6 +1024,7 @@ static void ath_unregister_led(struct ath_led *led)
static void ath_deinit_leds(struct ath_softc *sc)
{
+ cancel_delayed_work_sync(&sc->ath_led_blink_work);
ath_unregister_led(&sc->assoc_led);
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
ath_unregister_led(&sc->tx_led);
@@ -1020,9 +1044,11 @@ static void ath_init_leds(struct ath_softc *sc)
/* LED off, active low */
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+ INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
+
trigger = ieee80211_get_radio_led_name(sc->hw);
snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
- "ath9k-%s:radio", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->radio_led, trigger);
sc->radio_led.led_type = ATH_LED_RADIO;
if (ret)
@@ -1030,7 +1056,7 @@ static void ath_init_leds(struct ath_softc *sc)
trigger = ieee80211_get_assoc_led_name(sc->hw);
snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
- "ath9k-%s:assoc", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->assoc_led, trigger);
sc->assoc_led.led_type = ATH_LED_ASSOC;
if (ret)
@@ -1038,7 +1064,7 @@ static void ath_init_leds(struct ath_softc *sc)
trigger = ieee80211_get_tx_led_name(sc->hw);
snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
- "ath9k-%s:tx", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->tx_led, trigger);
sc->tx_led.led_type = ATH_LED_TX;
if (ret)
@@ -1046,7 +1072,7 @@ static void ath_init_leds(struct ath_softc *sc)
trigger = ieee80211_get_rx_led_name(sc->hw);
snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
- "ath9k-%s:rx", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->rx_led, trigger);
sc->rx_led.led_type = ATH_LED_RX;
if (ret)
@@ -1058,32 +1084,22 @@ fail:
ath_deinit_leds(sc);
}
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-
-/*******************/
-/* Rfkill */
-/*******************/
-
-static void ath_radio_enable(struct ath_softc *sc)
+void ath_radio_enable(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
- int status;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ieee80211_channel *channel = sc->hw->conf.channel;
+ int r;
+ ath9k_ps_wakeup(sc);
spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah, ah->ah_curchan,
- sc->tx_chan_width,
- sc->sc_tx_chainmask,
- sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing,
- false, &status)) {
+
+ r = ath9k_hw_reset(ah, ah->curchan, false);
+
+ if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset channel %u (%uMhz) "
- "flags 0x%x hal status %u\n",
- ath9k_hw_mhz2ieee(ah,
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags),
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags, status);
+ "Unable to reset channel %u (%uMhz) ",
+ "reset status %u\n",
+ channel->center_freq, r);
}
spin_unlock_bh(&sc->sc_resetlock);
@@ -1095,10 +1111,10 @@ static void ath_radio_enable(struct ath_softc *sc)
}
if (sc->sc_flags & SC_OP_BEACONS)
- ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
+ ath_beacon_config(sc, NULL); /* restart beacons */
/* Re-Enable interrupts */
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ ath9k_hw_set_interrupts(ah, sc->imask);
/* Enable LED */
ath9k_hw_cfg_output(ah, ATH_LED_PIN,
@@ -1106,14 +1122,16 @@ static void ath_radio_enable(struct ath_softc *sc)
ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
ieee80211_wake_queues(sc->hw);
+ ath9k_ps_restore(sc);
}
-static void ath_radio_disable(struct ath_softc *sc)
+void ath_radio_disable(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
- int status;
-
+ struct ath_hw *ah = sc->sc_ah;
+ struct ieee80211_channel *channel = sc->hw->conf.channel;
+ int r;
+ ath9k_ps_wakeup(sc);
ieee80211_stop_queues(sc->hw);
/* Disable LED */
@@ -1123,38 +1141,37 @@ static void ath_radio_disable(struct ath_softc *sc)
/* Disable interrupts */
ath9k_hw_set_interrupts(ah, 0);
- ath_draintxq(sc, false); /* clear pending tx frames */
+ ath_drain_all_txq(sc, false); /* clear pending tx frames */
ath_stoprecv(sc); /* turn off frame recv */
ath_flushrecv(sc); /* flush recv queue */
spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah, ah->ah_curchan,
- sc->tx_chan_width,
- sc->sc_tx_chainmask,
- sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing,
- false, &status)) {
+ r = ath9k_hw_reset(ah, ah->curchan, false);
+ if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) "
- "flags 0x%x hal status %u\n",
- ath9k_hw_mhz2ieee(ah,
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags),
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags, status);
+ "reset status %u\n",
+ channel->center_freq, r);
}
spin_unlock_bh(&sc->sc_resetlock);
ath9k_hw_phy_disable(ah);
ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+ ath9k_ps_restore(sc);
}
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+
+/*******************/
+/* Rfkill */
+/*******************/
+
static bool ath_is_rfkill_set(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
- return ath9k_hw_gpio_get(ah, ah->ah_rfkill_gpio) ==
- ah->ah_rfkill_polarity;
+ return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
+ ah->rfkill_polarity;
}
/* h/w rfkill poll function */
@@ -1238,7 +1255,7 @@ static int ath_init_sw_rfkill(struct ath_softc *sc)
}
snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
- "ath9k-%s:rfkill", wiphy_name(sc->hw->wiphy));
+ "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;
@@ -1251,7 +1268,7 @@ static int ath_init_sw_rfkill(struct ath_softc *sc)
/* Deinitialize rfkill */
static void ath_deinit_rfkill(struct ath_softc *sc)
{
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ 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) {
@@ -1263,7 +1280,7 @@ static void ath_deinit_rfkill(struct ath_softc *sc)
static int ath_start_rfkill_poll(struct ath_softc *sc)
{
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
queue_delayed_work(sc->hw->workqueue,
&sc->rf_kill.rfkill_poll, 0);
@@ -1274,13 +1291,7 @@ static int ath_start_rfkill_poll(struct ath_softc *sc)
rfkill_free(sc->rf_kill.rfkill);
/* Deinitialize the device */
- ath_detach(sc);
- if (sc->pdev->irq)
- free_irq(sc->pdev->irq, sc);
- pci_iounmap(sc->pdev, sc->mem);
- pci_release_region(sc->pdev, 0);
- pci_disable_device(sc->pdev);
- ieee80211_free_hw(sc->hw);
+ ath_cleanup(sc);
return -EIO;
} else {
sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
@@ -1291,18 +1302,39 @@ static int ath_start_rfkill_poll(struct ath_softc *sc)
}
#endif /* CONFIG_RFKILL */
-static void ath_detach(struct ath_softc *sc)
+void ath_cleanup(struct ath_softc *sc)
+{
+ ath_detach(sc);
+ free_irq(sc->irq, sc);
+ ath_bus_cleanup(sc);
+ kfree(sc->sec_wiphy);
+ ieee80211_free_hw(sc->hw);
+}
+
+void ath_detach(struct ath_softc *sc)
{
struct ieee80211_hw *hw = sc->hw;
int i = 0;
+ ath9k_ps_wakeup(sc);
+
DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
ath_deinit_rfkill(sc);
#endif
ath_deinit_leds(sc);
+ cancel_work_sync(&sc->chan_work);
+ cancel_delayed_work_sync(&sc->wiphy_work);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy == NULL)
+ continue;
+ sc->sec_wiphy[i] = NULL;
+ ieee80211_unregister_hw(aphy->hw);
+ ieee80211_free_hw(aphy->hw);
+ }
ieee80211_unregister_hw(hw);
ath_rx_cleanup(sc);
ath_tx_cleanup(sc);
@@ -1320,11 +1352,12 @@ static void ath_detach(struct ath_softc *sc)
ath9k_hw_detach(sc->sc_ah);
ath9k_exit_debug(sc);
+ ath9k_ps_restore(sc);
}
static int ath_init(u16 devid, struct ath_softc *sc)
{
- struct ath_hal *ah = NULL;
+ struct ath_hw *ah = NULL;
int status;
int error = 0, i;
int csz = 0;
@@ -1335,54 +1368,52 @@ static int ath_init(u16 devid, struct ath_softc *sc)
if (ath9k_init_debug(sc) < 0)
printk(KERN_ERR "Unable to create debugfs files\n");
+ spin_lock_init(&sc->wiphy_lock);
spin_lock_init(&sc->sc_resetlock);
+ spin_lock_init(&sc->sc_serial_rw);
mutex_init(&sc->mutex);
tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
- tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
+ tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
(unsigned long)sc);
/*
* Cache line size is used to size and align various
* structures used to communicate with the hardware.
*/
- bus_read_cachesize(sc, &csz);
+ ath_read_cachesize(sc, &csz);
/* XXX assert csz is non-zero */
- sc->sc_cachelsz = csz << 2; /* convert to bytes */
+ sc->cachelsz = csz << 2; /* convert to bytes */
- ah = ath9k_hw_attach(devid, sc, sc->mem, &status);
+ ah = ath9k_hw_attach(devid, sc, &status);
if (ah == NULL) {
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to attach hardware; HAL status %u\n", status);
+ "Unable to attach hardware; HAL status %d\n", status);
error = -ENXIO;
goto bad;
}
sc->sc_ah = ah;
/* Get the hardware key cache size. */
- sc->sc_keymax = ah->ah_caps.keycache_size;
- if (sc->sc_keymax > ATH_KEYMAX) {
+ sc->keymax = ah->caps.keycache_size;
+ if (sc->keymax > ATH_KEYMAX) {
DPRINTF(sc, ATH_DBG_KEYCACHE,
"Warning, using only %u entries in %u key cache\n",
- ATH_KEYMAX, sc->sc_keymax);
- sc->sc_keymax = ATH_KEYMAX;
+ ATH_KEYMAX, sc->keymax);
+ sc->keymax = ATH_KEYMAX;
}
/*
* Reset the key cache since some parts do not
* reset the contents on initial power up.
*/
- for (i = 0; i < sc->sc_keymax; i++)
+ for (i = 0; i < sc->keymax; i++)
ath9k_hw_keyreset(ah, (u16) i);
- /* Collect the channel list using the default country code */
-
- error = ath_setup_channels(sc);
- if (error)
+ if (ath9k_regd_init(sc->sc_ah))
goto bad;
/* default to MONITOR mode */
- sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR;
-
+ sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
/* Setup rate tables */
@@ -1411,7 +1442,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
goto bad2;
}
- sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
+ sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
ath_cabq_update(sc);
for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
@@ -1448,8 +1479,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
/* Initializes the noise floor to a reasonable default value.
* Later on this will be updated during ANI processing. */
- sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR;
- setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc);
+ sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+ setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
ATH9K_CIPHER_TKIP, NULL)) {
@@ -1475,60 +1506,62 @@ static int ath_init(u16 devid, struct ath_softc *sc)
ATH9K_CIPHER_MIC, NULL)
&& ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
0, NULL))
- sc->sc_splitmic = 1;
+ sc->splitmic = 1;
/* turn on mcast key search if possible */
if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
(void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
1, NULL);
- sc->sc_config.txpowlimit = ATH_TXPOWER_MAX;
- sc->sc_config.txpowlimit_override = 0;
+ sc->config.txpowlimit = ATH_TXPOWER_MAX;
/* 11n Capabilities */
- if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
sc->sc_flags |= SC_OP_TXAGGR;
sc->sc_flags |= SC_OP_RXAGGR;
}
- sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
- sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
+ sc->tx_chainmask = ah->caps.tx_chainmask;
+ sc->rx_chainmask = ah->caps.rx_chainmask;
ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
sc->rx.defant = ath9k_hw_getdefantenna(ah);
- ath9k_hw_getmac(ah, sc->sc_myaddr);
- if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
- ath9k_hw_getbssidmask(ah, sc->sc_bssidmask);
- ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask);
- ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
- }
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+ memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
/* initialize beacon slots */
- for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
- sc->beacon.bslot[i] = ATH_IF_ID_ANY;
+ for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+ sc->beacon.bslot[i] = NULL;
+ sc->beacon.bslot_aphy[i] = NULL;
+ }
/* save MISC configurations */
- sc->sc_config.swBeaconProcess = 1;
+ sc->config.swBeaconProcess = 1;
/* setup channels and rates */
- sc->sbands[IEEE80211_BAND_2GHZ].channels =
- sc->channels[IEEE80211_BAND_2GHZ];
+ sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
sc->rates[IEEE80211_BAND_2GHZ];
sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
+ sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
+ ARRAY_SIZE(ath9k_2ghz_chantable);
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
- sc->sbands[IEEE80211_BAND_5GHZ].channels =
- sc->channels[IEEE80211_BAND_5GHZ];
+ if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
+ sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
sc->rates[IEEE80211_BAND_5GHZ];
sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
+ sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
+ ARRAY_SIZE(ath9k_5ghz_chantable);
}
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
+ ath9k_hw_btcoex_enable(sc->sc_ah);
+
return 0;
bad2:
/* cleanup tx queues */
@@ -1538,104 +1571,156 @@ bad2:
bad:
if (ah)
ath9k_hw_detach(ah);
+ ath9k_exit_debug(sc);
return error;
}
-static int ath_attach(u16 devid, struct ath_softc *sc)
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
{
- struct ieee80211_hw *hw = sc->hw;
- int error = 0;
-
- DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
-
- error = ath_init(devid, sc);
- if (error != 0)
- return error;
-
- /* get mac address from hardware and set in mac80211 */
-
- SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
-
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_SIGNAL_DBM |
- IEEE80211_HW_AMPDU_AGGREGATION;
+ IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ IEEE80211_HW_SPECTRUM_MGMT;
+
+ if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
+ hw->flags |= IEEE80211_HW_MFP_CAPABLE;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
+ hw->wiphy->reg_notifier = ath9k_reg_notifier;
+ hw->wiphy->strict_regulatory = true;
+
hw->queues = 4;
hw->max_rates = 4;
+ hw->channel_change_time = 5000;
+ hw->max_listen_interval = 10;
hw->max_rate_tries = ATH_11N_TXMAXTRY;
hw->sta_data_size = sizeof(struct ath_node);
- hw->vif_data_size = sizeof(struct ath_vap);
+ hw->vif_data_size = sizeof(struct ath_vif);
hw->rate_control_algorithm = "ath9k_rate_control";
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
- setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
- setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
- }
-
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ];
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &sc->sbands[IEEE80211_BAND_2GHZ];
+ if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&sc->sbands[IEEE80211_BAND_5GHZ];
+}
+
+int ath_attach(u16 devid, struct ath_softc *sc)
+{
+ struct ieee80211_hw *hw = sc->hw;
+ const struct ieee80211_regdomain *regd;
+ int error = 0, i;
+
+ DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
+
+ error = ath_init(devid, sc);
+ if (error != 0)
+ return error;
+
+ /* get mac address from hardware and set in mac80211 */
+
+ SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
+
+ ath_set_hw_capab(sc, hw);
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+ setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
+ if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+ setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
+ }
/* initialize tx/rx engine */
error = ath_tx_init(sc, ATH_TXBUF);
if (error != 0)
- goto detach;
+ goto error_attach;
error = ath_rx_init(sc, ATH_RXBUF);
if (error != 0)
- goto detach;
+ goto error_attach;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
/* Initialze h/w Rfkill */
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ 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 */
- if (ath_init_sw_rfkill(sc))
- goto detach;
+ error = ath_init_sw_rfkill(sc);
+ if (error)
+ goto error_attach;
#endif
+ if (ath9k_is_world_regd(sc->sc_ah)) {
+ /* Anything applied here (prior to wiphy registration) gets
+ * saved on the wiphy orig_* parameters */
+ regd = ath9k_world_regdomain(sc->sc_ah);
+ hw->wiphy->custom_regulatory = true;
+ hw->wiphy->strict_regulatory = false;
+ } else {
+ /* This gets applied in the case of the absense of CRDA,
+ * it's our own custom world regulatory domain, similar to
+ * cfg80211's but we enable passive scanning */
+ regd = ath9k_default_world_regdomain();
+ }
+ wiphy_apply_custom_regulatory(hw->wiphy, regd);
+ ath9k_reg_apply_radar_flags(hw->wiphy);
+ ath9k_reg_apply_world_flags(hw->wiphy, NL80211_REGDOM_SET_BY_DRIVER);
+
+ INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
+ INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
+ sc->wiphy_scheduler_int = msecs_to_jiffies(500);
+
error = ieee80211_register_hw(hw);
+ if (!ath9k_is_world_regd(sc->sc_ah)) {
+ error = regulatory_hint(hw->wiphy,
+ sc->sc_ah->regulatory.alpha2);
+ if (error)
+ goto error_attach;
+ }
+
/* Initialize LED control */
ath_init_leds(sc);
+
return 0;
-detach:
- ath_detach(sc);
+
+error_attach:
+ /* cleanup tx queues */
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+ if (ATH_TXQ_SETUP(sc, i))
+ ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+ ath9k_hw_detach(sc->sc_ah);
+ ath9k_exit_debug(sc);
+
return error;
}
int ath_reset(struct ath_softc *sc, bool retry_tx)
{
- struct ath_hal *ah = sc->sc_ah;
- int status;
- int error = 0;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ieee80211_hw *hw = sc->hw;
+ int r;
ath9k_hw_set_interrupts(ah, 0);
- ath_draintxq(sc, retry_tx);
+ ath_drain_all_txq(sc, retry_tx);
ath_stoprecv(sc);
ath_flushrecv(sc);
spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan,
- sc->tx_chan_width,
- sc->sc_tx_chainmask, sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing, false, &status)) {
+ r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
+ if (r)
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; hal status %u\n", status);
- error = -EIO;
- }
+ "Unable to reset hardware; reset status %u\n", r);
spin_unlock_bh(&sc->sc_resetlock);
if (ath_startrecv(sc) != 0)
@@ -1646,14 +1731,14 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
* that changes the channel so update any state that
* might change as a result.
*/
- ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan));
+ ath_cache_conf_rate(sc, &hw->conf);
ath_update_txpow(sc);
if (sc->sc_flags & SC_OP_BEACONS)
- ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
+ ath_beacon_config(sc, NULL); /* restart beacons */
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ ath9k_hw_set_interrupts(ah, sc->imask);
if (retry_tx) {
int i;
@@ -1666,7 +1751,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
}
}
- return error;
+ return r;
}
/*
@@ -1690,6 +1775,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
name, nbuf, ndesc);
+ INIT_LIST_HEAD(head);
/* ath_desc must be a multiple of DWORDs */
if ((sizeof(struct ath_desc) % 4) != 0) {
DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n");
@@ -1706,7 +1792,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
* descriptors that cross the 4K page boundary. Assume
* one skipped descriptor per 4K page.
*/
- if (!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
u32 ndesc_skipped =
ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
u32 dma_len;
@@ -1720,9 +1806,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
}
/* allocate descriptors */
- dd->dd_desc = pci_alloc_consistent(sc->pdev,
- dd->dd_desc_len,
- &dd->dd_desc_paddr);
+ dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
+ &dd->dd_desc_paddr, GFP_KERNEL);
if (dd->dd_desc == NULL) {
error = -ENOMEM;
goto fail;
@@ -1734,20 +1819,18 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
/* allocate buffers */
bsize = sizeof(struct ath_buf) * nbuf;
- bf = kmalloc(bsize, GFP_KERNEL);
+ bf = kzalloc(bsize, GFP_KERNEL);
if (bf == NULL) {
error = -ENOMEM;
goto fail2;
}
- memset(bf, 0, bsize);
dd->dd_bufptr = bf;
- INIT_LIST_HEAD(head);
for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
- if (!(sc->sc_ah->ah_caps.hw_caps &
+ if (!(sc->sc_ah->caps.hw_caps &
ATH9K_HW_CAP_4KB_SPLITTRANS)) {
/*
* Skip descriptor addresses which can cause 4KB
@@ -1768,8 +1851,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
}
return 0;
fail2:
- pci_free_consistent(sc->pdev,
- dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
+ dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+ dd->dd_desc_paddr);
fail:
memset(dd, 0, sizeof(*dd));
return error;
@@ -1782,8 +1865,8 @@ void ath_descdma_cleanup(struct ath_softc *sc,
struct ath_descdma *dd,
struct list_head *head)
{
- pci_free_consistent(sc->pdev,
- dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
+ dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+ dd->dd_desc_paddr);
INIT_LIST_HEAD(head);
kfree(dd->dd_bufptr);
@@ -1840,33 +1923,81 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
return qnum;
}
+/* XXX: Remove me once we don't depend on ath9k_channel for all
+ * this redundant data */
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+ struct ath9k_channel *ichan)
+{
+ struct ieee80211_channel *chan = hw->conf.channel;
+ struct ieee80211_conf *conf = &hw->conf;
+
+ ichan->channel = chan->center_freq;
+ ichan->chan = chan;
+
+ if (chan->band == IEEE80211_BAND_2GHZ) {
+ ichan->chanmode = CHANNEL_G;
+ ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
+ } else {
+ ichan->chanmode = CHANNEL_A;
+ ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
+ }
+
+ sc->tx_chan_width = ATH9K_HT_MACMODE_20;
+
+ if (conf_is_ht(conf)) {
+ if (conf_is_ht40(conf))
+ sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
+
+ ichan->chanmode = ath_get_extchanmode(sc, chan,
+ conf->channel_type);
+ }
+}
+
/**********************/
/* mac80211 callbacks */
/**********************/
static int ath9k_start(struct ieee80211_hw *hw)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ieee80211_channel *curchan = hw->conf.channel;
struct ath9k_channel *init_channel;
- int error = 0, pos, status;
+ int r, pos;
DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
"initial channel: %d MHz\n", curchan->center_freq);
- /* setup initial channel */
+ mutex_lock(&sc->mutex);
- pos = ath_get_channel(sc, curchan);
- if (pos == -1) {
- DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq);
- error = -EINVAL;
- goto error;
+ if (ath9k_wiphy_started(sc)) {
+ if (sc->chan_idx == curchan->hw_value) {
+ /*
+ * Already on the operational channel, the new wiphy
+ * can be marked active.
+ */
+ aphy->state = ATH_WIPHY_ACTIVE;
+ ieee80211_wake_queues(hw);
+ } else {
+ /*
+ * Another wiphy is on another channel, start the new
+ * wiphy in paused state.
+ */
+ aphy->state = ATH_WIPHY_PAUSED;
+ ieee80211_stop_queues(hw);
+ }
+ mutex_unlock(&sc->mutex);
+ return 0;
}
+ aphy->state = ATH_WIPHY_ACTIVE;
- sc->tx_chan_width = ATH9K_HT_MACMODE_20;
- sc->sc_ah->ah_channels[pos].chanmode =
- (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
- init_channel = &sc->sc_ah->ah_channels[pos];
+ /* setup initial channel */
+
+ pos = curchan->hw_value;
+
+ sc->chan_idx = pos;
+ init_channel = &sc->sc_ah->channels[pos];
+ ath9k_update_ichannel(sc, hw, init_channel);
/* Reset SERDES registers */
ath9k_hw_configpcipowersave(sc->sc_ah, 0);
@@ -1879,17 +2010,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
* and then setup of the interrupt mask.
*/
spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(sc->sc_ah, init_channel,
- sc->tx_chan_width,
- sc->sc_tx_chainmask, sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing, false, &status)) {
+ r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
+ if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; hal status %u "
- "(freq %u flags 0x%x)\n", status,
- init_channel->channel, init_channel->channelFlags);
- error = -EIO;
+ "Unable to reset hardware; reset status %u "
+ "(freq %u MHz)\n", r,
+ curchan->center_freq);
spin_unlock_bh(&sc->sc_resetlock);
- goto error;
+ goto mutex_unlock;
}
spin_unlock_bh(&sc->sc_resetlock);
@@ -1909,66 +2037,56 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ath_startrecv(sc) != 0) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to start recv logic\n");
- error = -EIO;
- goto error;
+ r = -EIO;
+ goto mutex_unlock;
}
/* Setup our intr mask. */
- sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX
+ sc->imask = ATH9K_INT_RX | ATH9K_INT_TX
| ATH9K_INT_RXEOL | ATH9K_INT_RXORN
| ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_GTT)
- sc->sc_imask |= ATH9K_INT_GTT;
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
+ sc->imask |= ATH9K_INT_GTT;
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
- sc->sc_imask |= ATH9K_INT_CST;
-
- /*
- * Enable MIB interrupts when there are hardware phy counters.
- * Note we only do this (at the moment) for station mode.
- */
- if (ath9k_hw_phycounters(sc->sc_ah) &&
- ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) ||
- (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)))
- sc->sc_imask |= ATH9K_INT_MIB;
- /*
- * 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->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
- (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) &&
- !sc->sc_config.swBeaconProcess)
- sc->sc_imask |= ATH9K_INT_TIM;
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
+ sc->imask |= ATH9K_INT_CST;
- ath_setcurmode(sc, ath_chan2mode(init_channel));
+ ath_cache_conf_rate(sc, &hw->conf);
sc->sc_flags &= ~SC_OP_INVALID;
/* Disable BMISS interrupt when we're not associated */
- sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
- ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
+ sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
- ieee80211_wake_queues(sc->hw);
+ ieee80211_wake_queues(hw);
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- error = ath_start_rfkill_poll(sc);
+ r = ath_start_rfkill_poll(sc);
#endif
-error:
- return error;
+mutex_unlock:
+ mutex_unlock(&sc->mutex);
+
+ return r;
}
static int ath9k_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ath_tx_control txctl;
int hdrlen, padsize;
+ if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
+ printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
+ "%d\n", wiphy_name(hw->wiphy), aphy->state);
+ goto exit;
+ }
+
memset(&txctl, 0, sizeof(struct ath_tx_control));
/*
@@ -2002,7 +2120,7 @@ static int ath9k_tx(struct ieee80211_hw *hw,
DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
- if (ath_tx_start(sc, skb, &txctl) != 0) {
+ if (ath_tx_start(hw, skb, &txctl) != 0) {
DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n");
goto exit;
}
@@ -2015,30 +2133,38 @@ exit:
static void ath9k_stop(struct ieee80211_hw *hw)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ aphy->state = ATH_WIPHY_INACTIVE;
if (sc->sc_flags & SC_OP_INVALID) {
DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
return;
}
- DPRINTF(sc, ATH_DBG_CONFIG, "Cleaning up\n");
+ mutex_lock(&sc->mutex);
- ieee80211_stop_queues(sc->hw);
+ ieee80211_stop_queues(hw);
+
+ if (ath9k_wiphy_started(sc)) {
+ mutex_unlock(&sc->mutex);
+ return; /* another wiphy still in use */
+ }
/* make sure h/w will not generate any interrupt
* before setting the invalid flag. */
ath9k_hw_set_interrupts(sc->sc_ah, 0);
if (!(sc->sc_flags & SC_OP_INVALID)) {
- ath_draintxq(sc, false);
+ ath_drain_all_txq(sc, false);
ath_stoprecv(sc);
ath9k_hw_phy_disable(sc->sc_ah);
} else
sc->rx.rxlink = NULL;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
#endif
/* disable HAL and put h/w to sleep */
@@ -2047,136 +2173,227 @@ static void ath9k_stop(struct ieee80211_hw *hw)
sc->sc_flags |= SC_OP_INVALID;
+ mutex_unlock(&sc->mutex);
+
DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
}
static int ath9k_add_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct ath_softc *sc = hw->priv;
- struct ath_vap *avp = (void *)conf->vif->drv_priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_vif *avp = (void *)conf->vif->drv_priv;
enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
+ int ret = 0;
- /* Support only vap for now */
+ mutex_lock(&sc->mutex);
- if (sc->sc_nvaps)
- return -ENOBUFS;
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
+ sc->nvifs > 0) {
+ ret = -ENOBUFS;
+ goto out;
+ }
switch (conf->type) {
case NL80211_IFTYPE_STATION:
ic_opmode = NL80211_IFTYPE_STATION;
break;
case NL80211_IFTYPE_ADHOC:
+ if (sc->nbcnvifs >= ATH_BCBUF) {
+ ret = -ENOBUFS;
+ goto out;
+ }
ic_opmode = NL80211_IFTYPE_ADHOC;
break;
case NL80211_IFTYPE_AP:
+ if (sc->nbcnvifs >= ATH_BCBUF) {
+ ret = -ENOBUFS;
+ goto out;
+ }
ic_opmode = NL80211_IFTYPE_AP;
break;
default:
DPRINTF(sc, ATH_DBG_FATAL,
"Interface type %d not yet supported\n", conf->type);
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ goto out;
}
- DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VAP of type: %d\n", ic_opmode);
+ DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
- /* Set the VAP opmode */
+ /* Set the VIF opmode */
avp->av_opmode = ic_opmode;
avp->av_bslot = -1;
- if (ic_opmode == NL80211_IFTYPE_AP)
- ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+ sc->nvifs++;
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+ ath9k_set_bssid_mask(hw);
- sc->sc_vaps[0] = conf->vif;
- sc->sc_nvaps++;
+ if (sc->nvifs > 1)
+ goto out; /* skip global settings for secondary vif */
+
+ if (ic_opmode == NL80211_IFTYPE_AP) {
+ ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+ sc->sc_flags |= SC_OP_TSF_RESET;
+ }
/* Set the device opmode */
- sc->sc_ah->ah_opmode = ic_opmode;
+ sc->sc_ah->opmode = ic_opmode;
+
+ /*
+ * Enable MIB interrupts when there are hardware phy counters.
+ * Note we only do this (at the moment) for station mode.
+ */
+ if ((conf->type == NL80211_IFTYPE_STATION) ||
+ (conf->type == NL80211_IFTYPE_ADHOC)) {
+ if (ath9k_hw_phycounters(sc->sc_ah))
+ sc->imask |= ATH9K_INT_MIB;
+ sc->imask |= ATH9K_INT_TSFOOR;
+ }
+
+ /*
+ * Some hardware processes the TIM IE and fires an
+ * interrupt when the TIM bit is set. For hardware
+ * that does, if not overridden by configuration,
+ * enable the TIM interrupt when operating as station.
+ */
+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
+ (conf->type == NL80211_IFTYPE_STATION) &&
+ !sc->config.swBeaconProcess)
+ sc->imask |= ATH9K_INT_TIM;
+
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
if (conf->type == NL80211_IFTYPE_AP) {
/* TODO: is this a suitable place to start ANI for AP mode? */
/* Start ANI */
- mod_timer(&sc->sc_ani.timer,
+ mod_timer(&sc->ani.timer,
jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
}
- return 0;
+out:
+ mutex_unlock(&sc->mutex);
+ return ret;
}
static void ath9k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct ath_softc *sc = hw->priv;
- struct ath_vap *avp = (void *)conf->vif->drv_priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_vif *avp = (void *)conf->vif->drv_priv;
+ int i;
DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
+ mutex_lock(&sc->mutex);
+
/* Stop ANI */
- del_timer_sync(&sc->sc_ani.timer);
+ del_timer_sync(&sc->ani.timer);
/* Reclaim beacon resources */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
- sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
+ sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) {
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
ath_beacon_return(sc, avp);
}
sc->sc_flags &= ~SC_OP_BEACONS;
- sc->sc_vaps[0] = NULL;
- sc->sc_nvaps--;
+ for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+ if (sc->beacon.bslot[i] == conf->vif) {
+ printk(KERN_DEBUG "%s: vif had allocated beacon "
+ "slot\n", __func__);
+ sc->beacon.bslot[i] = NULL;
+ sc->beacon.bslot_aphy[i] = NULL;
+ }
+ }
+
+ sc->nvifs--;
+
+ mutex_unlock(&sc->mutex);
}
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ieee80211_conf *conf = &hw->conf;
mutex_lock(&sc->mutex);
- if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
- IEEE80211_CONF_CHANGE_HT)) {
- struct ieee80211_channel *curchan = hw->conf.channel;
- int pos;
-
- DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
- curchan->center_freq);
- pos = ath_get_channel(sc, curchan);
- if (pos == -1) {
- DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n",
- curchan->center_freq);
- mutex_unlock(&sc->mutex);
- return -EINVAL;
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if (conf->flags & IEEE80211_CONF_PS) {
+ if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
+ sc->imask |= ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
+ ath9k_hw_setrxabort(sc->sc_ah, 1);
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+ } else {
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+ ath9k_hw_setrxabort(sc->sc_ah, 0);
+ sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+ if (sc->imask & ATH9K_INT_TIM_TIMER) {
+ sc->imask &= ~ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
}
+ }
- sc->tx_chan_width = ATH9K_HT_MACMODE_20;
- sc->sc_ah->ah_channels[pos].chanmode =
- (curchan->band == IEEE80211_BAND_2GHZ) ?
- CHANNEL_G : CHANNEL_A;
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ struct ieee80211_channel *curchan = hw->conf.channel;
+ int pos = curchan->hw_value;
- if (conf->ht.enabled) {
- if (conf->ht.channel_type == NL80211_CHAN_HT40PLUS ||
- conf->ht.channel_type == NL80211_CHAN_HT40MINUS)
- sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
+ aphy->chan_idx = pos;
+ aphy->chan_is_ht = conf_is_ht(conf);
- sc->sc_ah->ah_channels[pos].chanmode =
- ath_get_extchanmode(sc, curchan,
- conf->ht.channel_type);
+ if (aphy->state == ATH_WIPHY_SCAN ||
+ aphy->state == ATH_WIPHY_ACTIVE)
+ ath9k_wiphy_pause_all_forced(sc, aphy);
+ else {
+ /*
+ * Do not change operational channel based on a paused
+ * wiphy changes.
+ */
+ goto skip_chan_change;
}
- ath_update_chainmask(sc, conf->ht.enabled);
+ DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+ curchan->center_freq);
+
+ /* XXX: remove me eventualy */
+ ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
- if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) {
+ ath_update_chainmask(sc, conf_is_ht(conf));
+
+ if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
mutex_unlock(&sc->mutex);
return -EINVAL;
}
}
+skip_chan_change:
if (changed & IEEE80211_CONF_CHANGE_POWER)
- sc->sc_config.txpowlimit = 2 * conf->power_level;
+ 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;
}
@@ -2184,19 +2401,24 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf)
{
- struct ath_softc *sc = hw->priv;
- struct ath_hal *ah = sc->sc_ah;
- struct ath_vap *avp = (void *)vif->drv_priv;
+ 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->ah_opmode != NL80211_IFTYPE_AP) {
- ah->ah_opmode = NL80211_IFTYPE_STATION;
+ ah->opmode != NL80211_IFTYPE_AP) {
+ ah->opmode = NL80211_IFTYPE_STATION;
ath9k_hw_setopmode(ah);
- ath9k_hw_write_associd(ah, sc->sc_myaddr, 0);
+ 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;
}
@@ -2207,17 +2429,17 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
/* Set BSSID */
- memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN);
- sc->sc_curaid = 0;
- ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
- sc->sc_curaid);
+ 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->sc_config.ath_aggr_prot = 0;
+ sc->config.ath_aggr_prot = 0;
DPRINTF(sc, ATH_DBG_CONFIG,
"RX filter 0x%x bssid %pM aid 0x%x\n",
- rfilt, sc->sc_curbssid, sc->sc_curaid);
+ rfilt, sc->curbssid, sc->curaid);
/* need to reconfigure the beacon */
sc->sc_flags &= ~SC_OP_BEACONS ;
@@ -2228,24 +2450,29 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
}
}
- if ((conf->changed & IEEE80211_IFCC_BEACON) &&
- ((vif->type == NL80211_IFTYPE_ADHOC) ||
- (vif->type == NL80211_IFTYPE_AP))) {
- /*
- * 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);
+ if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+ (vif->type == NL80211_IFTYPE_AP)) {
+ 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(sc, 0);
- if (error != 0)
- return error;
+ error = ath_beacon_alloc(aphy, vif);
+ if (error != 0) {
+ mutex_unlock(&sc->mutex);
+ return error;
+ }
- ath_beacon_sync(sc, 0);
+ ath_beacon_config(sc, vif);
+ }
}
/* Check for WLAN_CAPABILITY_PRIVACY ? */
@@ -2254,13 +2481,15 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
ath9k_hw_keysetmac(sc->sc_ah,
(u16)i,
- sc->sc_curbssid);
+ sc->curbssid);
}
/* Only legacy IBSS for now */
if (vif->type == NL80211_IFTYPE_ADHOC)
ath_update_chainmask(sc, 0);
+ mutex_unlock(&sc->mutex);
+
return 0;
}
@@ -2279,7 +2508,8 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
int mc_count,
struct dev_mc_list *mclist)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
u32 rfilt;
changed_flags &= SUPPORTED_FILTERS;
@@ -2289,11 +2519,6 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
- ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0);
- }
-
DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
}
@@ -2302,7 +2527,8 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
enum sta_notify_cmd cmd,
struct ieee80211_sta *sta)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
switch (cmd) {
case STA_NOTIFY_ADD:
@@ -2316,17 +2542,19 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
}
}
-static int ath9k_conf_tx(struct ieee80211_hw *hw,
- u16 queue,
+static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ath9k_tx_queue_info qi;
int ret = 0, qnum;
if (queue >= WME_NUM_AC)
return 0;
+ mutex_lock(&sc->mutex);
+
qi.tqi_aifs = params->aifs;
qi.tqi_cwmin = params->cw_min;
qi.tqi_cwmax = params->cw_max;
@@ -2343,29 +2571,39 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
if (ret)
DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
+ mutex_unlock(&sc->mutex);
+
return ret;
}
static int ath9k_set_key(struct ieee80211_hw *hw,
enum set_key_cmd cmd,
- const u8 *local_addr,
- const u8 *addr,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
int ret = 0;
+ if (modparam_nohwcrypt)
+ return -ENOSPC;
+
+ mutex_lock(&sc->mutex);
+ ath9k_ps_wakeup(sc);
DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n");
switch (cmd) {
case SET_KEY:
- ret = ath_key_config(sc, addr, key);
+ ret = ath_key_config(sc, vif, sta, key);
if (ret >= 0) {
key->hw_key_idx = ret;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
if (key->alg == ALG_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
ret = 0;
}
break;
@@ -2376,6 +2614,9 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
ret = -EINVAL;
}
+ ath9k_ps_restore(sc);
+ mutex_unlock(&sc->mutex);
+
return ret;
}
@@ -2384,7 +2625,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ mutex_lock(&sc->mutex);
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
@@ -2410,33 +2654,50 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->assoc);
ath9k_bss_assoc_info(sc, vif, bss_conf);
}
+
+ mutex_unlock(&sc->mutex);
}
static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
{
u64 tsf;
- struct ath_softc *sc = hw->priv;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
- tsf = ath9k_hw_gettsf64(ah);
+ mutex_lock(&sc->mutex);
+ tsf = ath9k_hw_gettsf64(sc->sc_ah);
+ mutex_unlock(&sc->mutex);
return tsf;
}
+static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ mutex_lock(&sc->mutex);
+ ath9k_hw_settsf64(sc->sc_ah, tsf);
+ mutex_unlock(&sc->mutex);
+}
+
static void ath9k_reset_tsf(struct ieee80211_hw *hw)
{
- struct ath_softc *sc = hw->priv;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
- ath9k_hw_reset_tsf(ah);
+ mutex_lock(&sc->mutex);
+ ath9k_hw_reset_tsf(sc->sc_ah);
+ mutex_unlock(&sc->mutex);
}
static int ath9k_ampdu_action(struct ieee80211_hw *hw,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta,
- u16 tid, u16 *ssn)
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
int ret = 0;
switch (action) {
@@ -2472,7 +2733,41 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
-static struct ieee80211_ops ath9k_ops = {
+static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ if (ath9k_wiphy_scanning(sc)) {
+ printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
+ "same time\n");
+ /*
+ * Do not allow the concurrent scanning state for now. This
+ * could be improved with scanning control moved into ath9k.
+ */
+ return;
+ }
+
+ aphy->state = ATH_WIPHY_SCAN;
+ ath9k_wiphy_pause_all_forced(sc, aphy);
+
+ mutex_lock(&sc->mutex);
+ sc->sc_flags |= SC_OP_SCANNING;
+ mutex_unlock(&sc->mutex);
+}
+
+static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ mutex_lock(&sc->mutex);
+ aphy->state = ATH_WIPHY_ACTIVE;
+ sc->sc_flags &= ~SC_OP_SCANNING;
+ mutex_unlock(&sc->mutex);
+}
+
+struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx,
.start = ath9k_start,
.stop = ath9k_stop,
@@ -2486,8 +2781,11 @@ static struct ieee80211_ops ath9k_ops = {
.bss_info_changed = ath9k_bss_info_changed,
.set_key = ath9k_set_key,
.get_tsf = ath9k_get_tsf,
+ .set_tsf = ath9k_set_tsf,
.reset_tsf = ath9k_reset_tsf,
.ampdu_action = ath9k_ampdu_action,
+ .sw_scan_start = ath9k_sw_scan_start,
+ .sw_scan_complete = ath9k_sw_scan_complete,
};
static struct {
@@ -2516,7 +2814,7 @@ static struct {
/*
* Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
*/
-static const char *
+const char *
ath_mac_bb_name(u32 mac_bb_version)
{
int i;
@@ -2533,7 +2831,7 @@ ath_mac_bb_name(u32 mac_bb_version)
/*
* Return the RF name. "????" is returned if the RF is unknown.
*/
-static const char *
+const char *
ath_rf_name(u16 rf_version)
{
int i;
@@ -2547,254 +2845,62 @@ ath_rf_name(u16 rf_version)
return "????";
}
-static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- void __iomem *mem;
- struct ath_softc *sc;
- struct ieee80211_hw *hw;
- u8 csz;
- u32 val;
- int ret = 0;
- struct ath_hal *ah;
-
- if (pci_enable_device(pdev))
- return -EIO;
-
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-
- if (ret) {
- printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
- goto bad;
- }
-
- ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-
- if (ret) {
- printk(KERN_ERR "ath9k: 32-bit DMA consistent "
- "DMA enable failed\n");
- goto bad;
- }
-
- /*
- * Cache line size is used to size and align various
- * structures used to communicate with the hardware.
- */
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
- if (csz == 0) {
- /*
- * Linux 2.4.18 (at least) writes the cache line size
- * register as a 16-bit wide register which is wrong.
- * We must have this setup properly for rx buffer
- * DMA to work so force a reasonable value here if it
- * comes up zero.
- */
- csz = L1_CACHE_BYTES / sizeof(u32);
- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
- }
- /*
- * The default setting of latency timer yields poor results,
- * set it to the value used by other systems. It may be worth
- * tweaking this setting more.
- */
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
- pci_set_master(pdev);
-
- /*
- * Disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state.
- */
- pci_read_config_dword(pdev, 0x40, &val);
- if ((val & 0x0000ff00) != 0)
- pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
- ret = pci_request_region(pdev, 0, "ath9k");
- if (ret) {
- dev_err(&pdev->dev, "PCI memory region reserve error\n");
- ret = -ENODEV;
- goto bad;
- }
-
- mem = pci_iomap(pdev, 0, 0);
- if (!mem) {
- printk(KERN_ERR "PCI memory map error\n") ;
- ret = -EIO;
- goto bad1;
- }
-
- hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
- if (hw == NULL) {
- printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
- goto bad2;
- }
-
- SET_IEEE80211_DEV(hw, &pdev->dev);
- pci_set_drvdata(pdev, hw);
-
- sc = hw->priv;
- sc->hw = hw;
- sc->pdev = pdev;
- sc->mem = mem;
-
- if (ath_attach(id->device, sc) != 0) {
- ret = -ENODEV;
- goto bad3;
- }
-
- /* setup interrupt service routine */
-
- if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
- printk(KERN_ERR "%s: request_irq failed\n",
- wiphy_name(hw->wiphy));
- ret = -EIO;
- goto bad4;
- }
-
- ah = sc->sc_ah;
- printk(KERN_INFO
- "%s: Atheros AR%s MAC/BB Rev:%x "
- "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
- wiphy_name(hw->wiphy),
- ath_mac_bb_name(ah->ah_macVersion),
- ah->ah_macRev,
- ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
- ah->ah_phyRev,
- (unsigned long)mem, pdev->irq);
-
- return 0;
-bad4:
- ath_detach(sc);
-bad3:
- ieee80211_free_hw(hw);
-bad2:
- pci_iounmap(pdev, mem);
-bad1:
- pci_release_region(pdev, 0);
-bad:
- pci_disable_device(pdev);
- return ret;
-}
-
-static void ath_pci_remove(struct pci_dev *pdev)
-{
- struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- struct ath_softc *sc = hw->priv;
-
- ath_detach(sc);
- if (pdev->irq)
- free_irq(pdev->irq, sc);
- pci_iounmap(pdev, sc->mem);
- pci_release_region(pdev, 0);
- pci_disable_device(pdev);
- ieee80211_free_hw(hw);
-}
-
-#ifdef CONFIG_PM
-
-static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- struct ath_softc *sc = hw->priv;
-
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- if (sc->sc_ah->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, 3);
-
- return 0;
-}
-
-static int ath_pci_resume(struct pci_dev *pdev)
-{
- struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- struct ath_softc *sc = hw->priv;
- u32 val;
- int err;
-
- err = pci_enable_device(pdev);
- if (err)
- return err;
- pci_restore_state(pdev);
- /*
- * Suspend/Resume resets the PCI configuration space, so we have to
- * re-disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state
- */
- pci_read_config_dword(pdev, 0x40, &val);
- if ((val & 0x0000ff00) != 0)
- pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
- /* Enable LED */
- ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- /*
- * check the h/w rfkill state on resume
- * and start the rfkill poll timer
- */
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- queue_delayed_work(sc->hw->workqueue,
- &sc->rf_kill.rfkill_poll, 0);
-#endif
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
-
-static struct pci_driver ath_pci_driver = {
- .name = "ath9k",
- .id_table = ath_pci_id_table,
- .probe = ath_pci_probe,
- .remove = ath_pci_remove,
-#ifdef CONFIG_PM
- .suspend = ath_pci_suspend,
- .resume = ath_pci_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init init_ath_pci(void)
+static int __init ath9k_init(void)
{
int error;
- printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION);
-
/* Register rate control algorithm */
error = ath_rate_control_register();
if (error != 0) {
printk(KERN_ERR
- "Unable to register rate control algorithm: %d\n",
+ "ath9k: Unable to register rate control "
+ "algorithm: %d\n",
error);
- ath_rate_control_unregister();
- return error;
+ goto err_out;
}
- if (pci_register_driver(&ath_pci_driver) < 0) {
+ error = ath9k_debug_create_root();
+ if (error) {
printk(KERN_ERR
- "ath_pci: No devices found, driver not installed.\n");
- ath_rate_control_unregister();
- pci_unregister_driver(&ath_pci_driver);
- return -ENODEV;
+ "ath9k: Unable to create debugfs root: %d\n",
+ error);
+ goto err_rate_unregister;
+ }
+
+ error = ath_pci_init();
+ if (error < 0) {
+ printk(KERN_ERR
+ "ath9k: No PCI devices found, driver not installed.\n");
+ error = -ENODEV;
+ goto err_remove_root;
+ }
+
+ error = ath_ahb_init();
+ if (error < 0) {
+ error = -ENODEV;
+ goto err_pci_exit;
}
return 0;
+
+ err_pci_exit:
+ ath_pci_exit();
+
+ err_remove_root:
+ ath9k_debug_remove_root();
+ err_rate_unregister:
+ ath_rate_control_unregister();
+ err_out:
+ return error;
}
-module_init(init_ath_pci);
+module_init(ath9k_init);
-static void __exit exit_ath_pci(void)
+static void __exit ath9k_exit(void)
{
+ ath_ahb_exit();
+ ath_pci_exit();
+ ath9k_debug_remove_root();
ath_rate_control_unregister();
- pci_unregister_driver(&ath_pci_driver);
printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
}
-module_exit(exit_ath_pci);
+module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
new file mode 100644
index 00000000000..9a58baabb9c
--- /dev/null
+++ b/drivers/net/wireless/ath9k/pci.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/pci.h>
+#include "ath9k.h"
+
+static struct pci_device_id ath_pci_id_table[] __devinitdata = {
+ { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
+ { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
+ { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
+ { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
+ { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
+ { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
+ { 0 }
+};
+
+/* return bus cachesize in 4B word units */
+static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
+{
+ u8 u8tmp;
+
+ pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
+ (u8 *)&u8tmp);
+ *csz = (int)u8tmp;
+
+ /*
+ * This check was put in to avoid "unplesant" consequences if
+ * the bootrom has not fully initialized all PCI devices.
+ * Sometimes the cache line size register is not set
+ */
+
+ if (*csz == 0)
+ *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
+}
+
+static void ath_pci_cleanup(struct ath_softc *sc)
+{
+ struct pci_dev *pdev = to_pci_dev(sc->dev);
+
+ pci_iounmap(pdev, sc->mem);
+ pci_disable_device(pdev);
+ pci_release_region(pdev, 0);
+}
+
+static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+ (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+
+ if (!ath9k_hw_wait(ah,
+ AR_EEPROM_STATUS_DATA,
+ AR_EEPROM_STATUS_DATA_BUSY |
+ AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+ AH_WAIT_TIMEOUT)) {
+ return false;
+ }
+
+ *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+ AR_EEPROM_STATUS_DATA_VAL);
+
+ return true;
+}
+
+static struct ath_bus_ops ath_pci_bus_ops = {
+ .read_cachesize = ath_pci_read_cachesize,
+ .cleanup = ath_pci_cleanup,
+ .eeprom_read = ath_pci_eeprom_read,
+};
+
+static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ void __iomem *mem;
+ struct ath_wiphy *aphy;
+ struct ath_softc *sc;
+ struct ieee80211_hw *hw;
+ u8 csz;
+ u32 val;
+ int ret = 0;
+ struct ath_hw *ah;
+
+ if (pci_enable_device(pdev))
+ return -EIO;
+
+ ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+
+ if (ret) {
+ printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
+ goto bad;
+ }
+
+ ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+
+ if (ret) {
+ printk(KERN_ERR "ath9k: 32-bit DMA consistent "
+ "DMA enable failed\n");
+ goto bad;
+ }
+
+ /*
+ * Cache line size is used to size and align various
+ * structures used to communicate with the hardware.
+ */
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+ if (csz == 0) {
+ /*
+ * Linux 2.4.18 (at least) writes the cache line size
+ * register as a 16-bit wide register which is wrong.
+ * We must have this setup properly for rx buffer
+ * DMA to work so force a reasonable value here if it
+ * comes up zero.
+ */
+ csz = L1_CACHE_BYTES / sizeof(u32);
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+ }
+ /*
+ * The default setting of latency timer yields poor results,
+ * set it to the value used by other systems. It may be worth
+ * tweaking this setting more.
+ */
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+ pci_set_master(pdev);
+
+ /*
+ * Disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state.
+ */
+ pci_read_config_dword(pdev, 0x40, &val);
+ if ((val & 0x0000ff00) != 0)
+ pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+
+ ret = pci_request_region(pdev, 0, "ath9k");
+ if (ret) {
+ dev_err(&pdev->dev, "PCI memory region reserve error\n");
+ ret = -ENODEV;
+ goto bad;
+ }
+
+ mem = pci_iomap(pdev, 0, 0);
+ if (!mem) {
+ printk(KERN_ERR "PCI memory map error\n") ;
+ ret = -EIO;
+ goto bad1;
+ }
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+ sizeof(struct ath_softc), &ath9k_ops);
+ if (hw == NULL) {
+ printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
+ goto bad2;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
+
+ aphy = hw->priv;
+ sc = (struct ath_softc *) (aphy + 1);
+ aphy->sc = sc;
+ aphy->hw = hw;
+ sc->pri_wiphy = aphy;
+ sc->hw = hw;
+ sc->dev = &pdev->dev;
+ sc->mem = mem;
+ sc->bus_ops = &ath_pci_bus_ops;
+
+ if (ath_attach(id->device, sc) != 0) {
+ ret = -ENODEV;
+ goto bad3;
+ }
+
+ /* setup interrupt service routine */
+
+ if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
+ printk(KERN_ERR "%s: request_irq failed\n",
+ wiphy_name(hw->wiphy));
+ ret = -EIO;
+ goto bad4;
+ }
+
+ sc->irq = pdev->irq;
+
+ ah = sc->sc_ah;
+ printk(KERN_INFO
+ "%s: Atheros AR%s MAC/BB Rev:%x "
+ "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
+ wiphy_name(hw->wiphy),
+ ath_mac_bb_name(ah->hw_version.macVersion),
+ ah->hw_version.macRev,
+ ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+ ah->hw_version.phyRev,
+ (unsigned long)mem, pdev->irq);
+
+ return 0;
+bad4:
+ ath_detach(sc);
+bad3:
+ ieee80211_free_hw(hw);
+bad2:
+ pci_iounmap(pdev, mem);
+bad1:
+ pci_release_region(pdev, 0);
+bad:
+ pci_disable_device(pdev);
+ return ret;
+}
+
+static void ath_pci_remove(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ ath_cleanup(sc);
+}
+
+#ifdef CONFIG_PM
+
+static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
+#endif
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int ath_pci_resume(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ u32 val;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+ pci_restore_state(pdev);
+ /*
+ * Suspend/Resume resets the PCI configuration space, so we have to
+ * re-disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state
+ */
+ pci_read_config_dword(pdev, 0x40, &val);
+ if ((val & 0x0000ff00) != 0)
+ pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+
+ /* Enable LED */
+ ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+ /*
+ * check the h/w rfkill state on resume
+ * and start the rfkill poll timer
+ */
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ queue_delayed_work(sc->hw->workqueue,
+ &sc->rf_kill.rfkill_poll, 0);
+#endif
+
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+
+MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
+
+static struct pci_driver ath_pci_driver = {
+ .name = "ath9k",
+ .id_table = ath_pci_id_table,
+ .probe = ath_pci_probe,
+ .remove = ath_pci_remove,
+#ifdef CONFIG_PM
+ .suspend = ath_pci_suspend,
+ .resume = ath_pci_resume,
+#endif /* CONFIG_PM */
+};
+
+int ath_pci_init(void)
+{
+ return pci_register_driver(&ath_pci_driver);
+}
+
+void ath_pci_exit(void)
+{
+ pci_unregister_driver(&ath_pci_driver);
+}
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
index 766982a8196..e1494bae0f9 100644
--- a/drivers/net/wireless/ath9k/phy.c
+++ b/drivers/net/wireless/ath9k/phy.c
@@ -14,22 +14,17 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
void
-ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, u32 freqIndex,
+ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
int regWrites)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
+ REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
}
bool
-ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
+ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
{
u32 channelSel = 0;
u32 bModeSynth = 0;
@@ -95,15 +90,14 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
REG_WRITE(ah, AR_PHY(0x37), reg32);
- ah->ah_curchan = chan;
-
- AH5416(ah)->ah_curchanRadIndex = -1;
+ ah->curchan = chan;
+ ah->curchan_rad_index = -1;
return true;
}
bool
-ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
+ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u16 bMode, fracMode, aModeRefSel = 0;
@@ -138,20 +132,27 @@ ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
bMode = 0;
fracMode = 0;
- if ((freq % 20) == 0) {
- aModeRefSel = 3;
- } else if ((freq % 10) == 0) {
- aModeRefSel = 2;
- } else {
+ switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
+ case 0:
+ if ((freq % 20) == 0) {
+ aModeRefSel = 3;
+ } else if ((freq % 10) == 0) {
+ aModeRefSel = 2;
+ }
+ if (aModeRefSel)
+ break;
+ case 1:
+ default:
aModeRefSel = 0;
-
fracMode = 1;
refDivA = 1;
channelSel = (freq * 0x8000) / 15;
REG_RMW_FIELD(ah, AR_AN_SYNTH9,
AR_AN_SYNTH9_REFDIVA, refDivA);
+
}
+
if (!fracMode) {
ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
channelSel = ndiv & 0x1ff;
@@ -166,9 +167,8 @@ ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
- ah->ah_curchan = chan;
-
- AH5416(ah)->ah_curchanRadIndex = -1;
+ ah->curchan = chan;
+ ah->curchan_rad_index = -1;
return true;
}
@@ -201,11 +201,9 @@ ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
}
bool
-ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
u16 modesIndex)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
u32 eepMinorRev;
u32 ob5GHz = 0, db5GHz = 0;
u32 ob2GHz = 0, db2GHz = 0;
@@ -214,161 +212,156 @@ ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
if (AR_SREV_9280_10_OR_LATER(ah))
return true;
- eepMinorRev = ath9k_hw_get_eeprom(ah, EEP_MINOR_REV);
+ eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
- RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
+ RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
- RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1);
+ RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
- RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1);
+ RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
- RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3,
+ RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
modesIndex);
{
int i;
- for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) {
- ahp->ah_analogBank6Data[i] =
- INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex);
+ for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
+ ah->analogBank6Data[i] =
+ INI_RA(&ah->iniBank6TPC, i, modesIndex);
}
}
if (eepMinorRev >= 2) {
if (IS_CHAN_2GHZ(chan)) {
- ob2GHz = ath9k_hw_get_eeprom(ah, EEP_OB_2);
- db2GHz = ath9k_hw_get_eeprom(ah, EEP_DB_2);
- ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+ ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
+ db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
+ ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
ob2GHz, 3, 197, 0);
- ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+ ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
db2GHz, 3, 194, 0);
} else {
- ob5GHz = ath9k_hw_get_eeprom(ah, EEP_OB_5);
- db5GHz = ath9k_hw_get_eeprom(ah, EEP_DB_5);
- ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+ ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
+ db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
+ ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
ob5GHz, 3, 203, 0);
- ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+ ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
db5GHz, 3, 200, 0);
}
}
- RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1);
+ RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
regWrites);
return true;
}
void
-ath9k_hw_rfdetach(struct ath_hal *ah)
+ath9k_hw_rfdetach(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (ahp->ah_analogBank0Data != NULL) {
- kfree(ahp->ah_analogBank0Data);
- ahp->ah_analogBank0Data = NULL;
+ if (ah->analogBank0Data != NULL) {
+ kfree(ah->analogBank0Data);
+ ah->analogBank0Data = NULL;
}
- if (ahp->ah_analogBank1Data != NULL) {
- kfree(ahp->ah_analogBank1Data);
- ahp->ah_analogBank1Data = NULL;
+ if (ah->analogBank1Data != NULL) {
+ kfree(ah->analogBank1Data);
+ ah->analogBank1Data = NULL;
}
- if (ahp->ah_analogBank2Data != NULL) {
- kfree(ahp->ah_analogBank2Data);
- ahp->ah_analogBank2Data = NULL;
+ if (ah->analogBank2Data != NULL) {
+ kfree(ah->analogBank2Data);
+ ah->analogBank2Data = NULL;
}
- if (ahp->ah_analogBank3Data != NULL) {
- kfree(ahp->ah_analogBank3Data);
- ahp->ah_analogBank3Data = NULL;
+ if (ah->analogBank3Data != NULL) {
+ kfree(ah->analogBank3Data);
+ ah->analogBank3Data = NULL;
}
- if (ahp->ah_analogBank6Data != NULL) {
- kfree(ahp->ah_analogBank6Data);
- ahp->ah_analogBank6Data = NULL;
+ if (ah->analogBank6Data != NULL) {
+ kfree(ah->analogBank6Data);
+ ah->analogBank6Data = NULL;
}
- if (ahp->ah_analogBank6TPCData != NULL) {
- kfree(ahp->ah_analogBank6TPCData);
- ahp->ah_analogBank6TPCData = NULL;
+ if (ah->analogBank6TPCData != NULL) {
+ kfree(ah->analogBank6TPCData);
+ ah->analogBank6TPCData = NULL;
}
- if (ahp->ah_analogBank7Data != NULL) {
- kfree(ahp->ah_analogBank7Data);
- ahp->ah_analogBank7Data = NULL;
+ if (ah->analogBank7Data != NULL) {
+ kfree(ah->analogBank7Data);
+ ah->analogBank7Data = NULL;
}
- if (ahp->ah_addac5416_21 != NULL) {
- kfree(ahp->ah_addac5416_21);
- ahp->ah_addac5416_21 = NULL;
+ if (ah->addac5416_21 != NULL) {
+ kfree(ah->addac5416_21);
+ ah->addac5416_21 = NULL;
}
- if (ahp->ah_bank6Temp != NULL) {
- kfree(ahp->ah_bank6Temp);
- ahp->ah_bank6Temp = NULL;
+ if (ah->bank6Temp != NULL) {
+ kfree(ah->bank6Temp);
+ ah->bank6Temp = NULL;
}
}
-bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
+bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (!AR_SREV_9280_10_OR_LATER(ah)) {
-
- ahp->ah_analogBank0Data =
+ ah->analogBank0Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank0.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank1Data =
+ ah->iniBank0.ia_rows), GFP_KERNEL);
+ ah->analogBank1Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank1.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank2Data =
+ ah->iniBank1.ia_rows), GFP_KERNEL);
+ ah->analogBank2Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank2.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank3Data =
+ ah->iniBank2.ia_rows), GFP_KERNEL);
+ ah->analogBank3Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank3.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank6Data =
+ ah->iniBank3.ia_rows), GFP_KERNEL);
+ ah->analogBank6Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank6TPCData =
+ ah->iniBank6.ia_rows), GFP_KERNEL);
+ ah->analogBank6TPCData =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank6TPC.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank7Data =
+ ah->iniBank6TPC.ia_rows), GFP_KERNEL);
+ ah->analogBank7Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank7.ia_rows), GFP_KERNEL);
-
- if (ahp->ah_analogBank0Data == NULL
- || ahp->ah_analogBank1Data == NULL
- || ahp->ah_analogBank2Data == NULL
- || ahp->ah_analogBank3Data == NULL
- || ahp->ah_analogBank6Data == NULL
- || ahp->ah_analogBank6TPCData == NULL
- || ahp->ah_analogBank7Data == NULL) {
+ ah->iniBank7.ia_rows), GFP_KERNEL);
+
+ if (ah->analogBank0Data == NULL
+ || ah->analogBank1Data == NULL
+ || ah->analogBank2Data == NULL
+ || ah->analogBank3Data == NULL
+ || ah->analogBank6Data == NULL
+ || ah->analogBank6TPCData == NULL
+ || ah->analogBank7Data == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Cannot allocate RF banks\n");
*status = -ENOMEM;
return false;
}
- ahp->ah_addac5416_21 =
+ ah->addac5416_21 =
kzalloc((sizeof(u32) *
- ahp->ah_iniAddac.ia_rows *
- ahp->ah_iniAddac.ia_columns), GFP_KERNEL);
- if (ahp->ah_addac5416_21 == NULL) {
+ ah->iniAddac.ia_rows *
+ ah->iniAddac.ia_columns), GFP_KERNEL);
+ if (ah->addac5416_21 == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
- "Cannot allocate ah_addac5416_21\n");
+ "Cannot allocate addac5416_21\n");
*status = -ENOMEM;
return false;
}
- ahp->ah_bank6Temp =
+ ah->bank6Temp =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
- if (ahp->ah_bank6Temp == NULL) {
+ ah->iniBank6.ia_rows), GFP_KERNEL);
+ if (ah->bank6Temp == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
- "Cannot allocate ah_bank6Temp\n");
+ "Cannot allocate bank6Temp\n");
*status = -ENOMEM;
return false;
}
@@ -378,24 +371,23 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
}
void
-ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
+ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
{
int i, regWrites = 0;
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 bank6SelMask;
- u32 *bank6Temp = ahp->ah_bank6Temp;
+ u32 *bank6Temp = ah->bank6Temp;
- switch (ahp->ah_diversityControl) {
+ switch (ah->diversity_control) {
case ATH9K_ANT_FIXED_A:
bank6SelMask =
- (ahp->
- ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
+ (ah->
+ antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
REDUCE_CHAIN_1;
break;
case ATH9K_ANT_FIXED_B:
bank6SelMask =
- (ahp->
- ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
+ (ah->
+ antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
REDUCE_CHAIN_0;
break;
case ATH9K_ANT_VARIABLE:
@@ -406,8 +398,8 @@ ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
break;
}
- for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++)
- bank6Temp[i] = ahp->ah_analogBank6Data[i];
+ for (i = 0; i < ah->iniBank6.ia_rows; i++)
+ bank6Temp[i] = ah->analogBank6Data[i];
REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
@@ -421,7 +413,7 @@ ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites);
+ REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
#ifdef ALTER_SWITCH
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
index 3a406a5c059..1eac8c70734 100644
--- a/drivers/net/wireless/ath9k/phy.h
+++ b/drivers/net/wireless/ath9k/phy.h
@@ -17,19 +17,19 @@
#ifndef PHY_H
#define PHY_H
-bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
+bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
struct ath9k_channel
*chan);
-bool ath9k_hw_set_channel(struct ath_hal *ah,
+bool ath9k_hw_set_channel(struct ath_hw *ah,
struct ath9k_channel *chan);
-void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex,
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
u32 freqIndex, int regWrites);
-bool ath9k_hw_set_rf_regs(struct ath_hal *ah,
+bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
struct ath9k_channel *chan,
u16 modesIndex);
-void ath9k_hw_decrease_chain_power(struct ath_hal *ah,
+void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
struct ath9k_channel *chan);
-bool ath9k_hw_init_rf(struct ath_hal *ah,
+bool ath9k_hw_init_rf(struct ath_hw *ah,
int *status);
#define AR_PHY_BASE 0x9800
@@ -387,6 +387,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
#define AR_PHY_CCK_TX_CTRL 0xA204
#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
#define AR_PHY_CCK_DETECT 0xA208
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
@@ -444,6 +446,32 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_TX_PWRCTRL4 0xa264
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
+
+#define AR_PHY_TX_PWRCTRL6_0 0xa270
+#define AR_PHY_TX_PWRCTRL6_1 0xb270
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
+
+#define AR_PHY_TX_PWRCTRL7 0xa274
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
+
+#define AR_PHY_TX_PWRCTRL9 0xa27C
+#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
+
+#define AR_PHY_TX_GAIN_TBL1 0xa300
+#define AR_PHY_TX_GAIN 0x0007F000
+#define AR_PHY_TX_GAIN_S 12
+
#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
#define AR_PHY_MASK2_M_31_45 0xa3a4
#define AR_PHY_MASK2_M_16_30 0xa3a8
@@ -485,6 +513,11 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR_PHY_CL_CAL_CTL 0xA358
+#define AR_PHY_CL_CAL_ENABLE 0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
+
#define AR_PHY_POWER_TX_RATE5 0xA38C
#define AR_PHY_POWER_TX_RATE6 0xA390
@@ -530,10 +563,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
} \
} while (0)
-#define ATH9K_KEY_XOR 0xaa
-
#define ATH9K_IS_MIC_ENABLED(ah) \
- (AH5416(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
+ ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
#define ANTSWAP_AB 0x0001
#define REDUCE_CHAIN_0 0x00000050
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 04ab457a8fa..832735677a4 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -15,16 +15,15 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
+#include "ath9k.h"
static struct ath_rate_table ar5416_11na_ratetable = {
42,
- {0},
{
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
5400, 0x0b, 0x00, 12,
0, 2, 1, 0, 0, 0, 0, 0 },
- { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+ { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
7800, 0x0f, 0x00, 18,
0, 3, 1, 1, 1, 1, 1, 0 },
{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
@@ -158,7 +157,6 @@ static struct ath_rate_table ar5416_11na_ratetable = {
static struct ath_rate_table ar5416_11ng_ratetable = {
46,
- {0},
{
{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
900, 0x1b, 0x00, 2,
@@ -306,7 +304,6 @@ static struct ath_rate_table ar5416_11ng_ratetable = {
static struct ath_rate_table ar5416_11a_ratetable = {
8,
- {0},
{
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
5400, 0x0b, 0x00, (0x80|12),
@@ -340,7 +337,6 @@ static struct ath_rate_table ar5416_11a_ratetable = {
static struct ath_rate_table ar5416_11g_ratetable = {
12,
- {0},
{
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
900, 0x1b, 0x00, 2,
@@ -386,7 +382,6 @@ static struct ath_rate_table ar5416_11g_ratetable = {
static struct ath_rate_table ar5416_11b_ratetable = {
4,
- {0},
{
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
900, 0x1b, 0x00, (0x80|2),
@@ -490,7 +485,7 @@ static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
{
- if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG))
+ if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
return 0;
if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
return 0;
@@ -636,8 +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,
- int probe_allowed, int *is_probing,
- int is_retry)
+ int *is_probing)
{
u32 dt, best_thruput, this_thruput, now_msec;
u8 rate, next_rate, best_rate, maxindex, minindex;
@@ -719,13 +713,6 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
}
rate = best_rate;
-
- /* if we are retrying for more than half the number
- * of max retries, use the min rate for the next retry
- */
- if (is_retry)
- rate = ath_rc_priv->valid_rate_index[minindex];
-
ath_rc_priv->rssi_last_lookup = rssi_last;
/*
@@ -733,13 +720,12 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
* non-monoticity of 11g's rate table
*/
- if (rate >= ath_rc_priv->rate_max_phy && probe_allowed) {
+ if (rate >= ath_rc_priv->rate_max_phy) {
rate = ath_rc_priv->rate_max_phy;
/* Probe the next allowed phy state */
- /* FIXME:XXXX Check to make sure ratMax is checked properly */
if (ath_rc_get_nextvalid_txrate(rate_table,
- ath_rc_priv, rate, &next_rate) &&
+ ath_rc_priv, rate, &next_rate) &&
(now_msec - ath_rc_priv->probe_time >
rate_table->probe_interval) &&
(ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
@@ -761,14 +747,17 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
return rate;
}
-static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
+static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate,
+ struct ieee80211_tx_rate_control *txrc,
u8 tries, u8 rix, int rtsctsenable)
{
rate->count = tries;
rate->idx = rix;
- if (rtsctsenable)
+ if (txrc->short_preamble)
+ rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
+ if (txrc->rts || rtsctsenable)
rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
@@ -778,6 +767,43 @@ static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
rate->flags |= IEEE80211_TX_RC_MCS;
}
+static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
+ struct ath_rate_table *rate_table,
+ struct ieee80211_tx_info *tx_info)
+{
+ struct ieee80211_tx_rate *rates = tx_info->control.rates;
+ int i = 0, rix = 0, cix, enable_g_protection = 0;
+
+ /* get the cix for the lowest valid rix */
+ for (i = 3; i >= 0; i--) {
+ if (rates[i].count && (rates[i].idx >= 0)) {
+ rix = rates[i].idx;
+ break;
+ }
+ }
+ cix = rate_table->info[rix].ctrl_rate;
+
+ /* All protection frames are transmited at 2Mb/s for 802.11g,
+ * otherwise we transmit them at 1Mb/s */
+ if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
+ !conf_is_ht(&sc->hw->conf))
+ enable_g_protection = 1;
+
+ /*
+ * If 802.11g protection is enabled, determine whether to use RTS/CTS or
+ * just CTS. Note that this is only done for OFDM/HT unicast frames.
+ */
+ if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
+ !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
+ WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
+ rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
+ cix = rate_table->info[enable_g_protection].ctrl_rate;
+ }
+
+ tx_info->control.rts_cts_rate_idx = cix;
+}
+
static u8 ath_rc_rate_getidx(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ath_rate_table *rate_table,
@@ -809,54 +835,56 @@ static u8 ath_rc_rate_getidx(struct ath_softc *sc,
static void ath_rc_ratefind(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
- int num_tries, int num_rates,
- struct ieee80211_tx_info *tx_info, int *is_probe,
- int is_retry)
+ struct ieee80211_tx_rate_control *txrc)
{
- u8 try_per_rate = 0, i = 0, rix, nrix;
struct ath_rate_table *rate_table;
+ struct sk_buff *skb = txrc->skb;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->control.rates;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ __le16 fc = hdr->frame_control;
+ u8 try_per_rate = 0, i = 0, rix, nrix;
+ int is_probe = 0;
rate_table = sc->cur_rate_table;
- rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1,
- is_probe, is_retry);
+ rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
nrix = rix;
- if (*is_probe) {
+ if (is_probe) {
/* set one try for probe rates. For the
* probes don't enable rts */
- ath_rc_rate_set_series(rate_table,
- &rates[i++], 1, nrix, 0);
+ ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+ 1, nrix, 0);
- try_per_rate = (num_tries/num_rates);
+ try_per_rate = (ATH_11N_TXMAXTRY/4);
/* Get the next tried/allowed rate. No RTS for the next series
* after the probe rate
*/
- nrix = ath_rc_rate_getidx(sc,
- ath_rc_priv, rate_table, nrix, 1, 0);
- ath_rc_rate_set_series(rate_table,
- &rates[i++], try_per_rate, nrix, 0);
+ nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
+ rate_table, nrix, 1, 0);
+ ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+ try_per_rate, nrix, 0);
} else {
- try_per_rate = (num_tries/num_rates);
+ try_per_rate = (ATH_11N_TXMAXTRY/4);
/* Set the choosen rate. No RTS for first series entry. */
- ath_rc_rate_set_series(rate_table,
- &rates[i++], try_per_rate, nrix, 0);
+ ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+ try_per_rate, nrix, 0);
}
/* Fill in the other rates for multirate retry */
- for ( ; i < num_rates; i++) {
+ for ( ; i < 4; i++) {
u8 try_num;
u8 min_rate;
- try_num = ((i + 1) == num_rates) ?
- num_tries - (try_per_rate * i) : try_per_rate ;
- min_rate = (((i + 1) == num_rates) && 0);
+ try_num = ((i + 1) == 4) ?
+ ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
+ min_rate = (((i + 1) == 4) && 0);
nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
rate_table, nrix, 1, min_rate);
/* All other rates in the series have RTS enabled */
- ath_rc_rate_set_series(rate_table,
- &rates[i], try_num, nrix, 1);
+ ath_rc_rate_set_series(rate_table, &rates[i], txrc,
+ try_num, nrix, 1);
}
/*
@@ -875,7 +903,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
* above conditions.
*/
if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
- (sc->hw->conf.ht.enabled)) {
+ (conf_is_ht(&sc->hw->conf))) {
u8 dot11rate = rate_table->info[rix].dot11rate;
u8 phy = rate_table->info[rix].phy;
if (i == 4 &&
@@ -885,6 +913,24 @@ static void ath_rc_ratefind(struct ath_softc *sc,
rates[3].flags = rates[2].flags;
}
}
+
+ /*
+ * Force hardware to use computed duration for next
+ * fragment by disabling multi-rate retry, which
+ * updates duration based on the multi-rate duration table.
+ *
+ * FIXME: Fix duration
+ */
+ if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (ieee80211_has_morefrags(fc) ||
+ (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
+ rates[1].count = rates[2].count = rates[3].count = 0;
+ rates[1].idx = rates[2].idx = rates[3].idx = 0;
+ rates[0].count = ATH_TXMAXTRY;
+ }
+
+ /* Setup RTS/CTS */
+ ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
}
static bool ath_rc_update_per(struct ath_softc *sc,
@@ -1221,6 +1267,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
ath_rc_priv->per_down_time = now_msec;
}
+ ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+ ath_rc_priv->state[tx_rate].per);
+
#undef CHK_RSSI
}
@@ -1338,36 +1387,18 @@ static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
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 ieee80211_sta *sta,
+ struct ath_rate_table *rate_table)
{
- struct ath_rate_table *rate_table = NULL;
struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
u8 i, j, k, hi = 0, hthi = 0;
- /* FIXME: Adhoc */
- if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) ||
- (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)) {
- bool is_cw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
- rate_table = ath_choose_rate_table(sc, sband->band,
- sta->ht_cap.ht_supported,
- is_cw_40);
- } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
- /* cur_rate_table would be set on init through config() */
- rate_table = sc->cur_rate_table;
- }
-
if (!rate_table) {
DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
return;
}
- if (sta->ht_cap.ht_supported) {
- ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG);
- if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
- ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG;
- }
-
/* Initial rate table size. Will change depending
* on the working rate set */
ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
@@ -1387,7 +1418,7 @@ 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);
+ 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;
@@ -1395,16 +1426,16 @@ static void ath_rc_init(struct ath_softc *sc,
if (!rateset->rs_nrates) {
/* No working rate, just initialize valid rates */
hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
- ath_rc_priv->ht_cap);
+ ath_rc_priv->ht_cap);
} else {
/* Use intersection of working rates and valid rates */
hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
- rateset, ath_rc_priv->ht_cap);
+ rateset, ath_rc_priv->ht_cap);
if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
hthi = ath_rc_setvalid_htrates(ath_rc_priv,
- rate_table,
- ht_mcs,
- ath_rc_priv->ht_cap);
+ rate_table,
+ ht_mcs,
+ ath_rc_priv->ht_cap);
}
hi = A_MAX(hi, hthi);
}
@@ -1432,9 +1463,34 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_sort_validrates(rate_table, ath_rc_priv);
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
sc->cur_rate_table = rate_table;
+
+ DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n",
+ ath_rc_priv->ht_cap);
}
-/* Rate Control callbacks */
+static u8 ath_rc_build_ht_caps(struct ath_softc *sc, bool is_ht, bool is_cw40,
+ bool is_sgi40)
+{
+ u8 caps = 0;
+
+ if (is_ht) {
+ caps = WLAN_RC_HT_FLAG;
+ if (sc->sc_ah->caps.tx_chainmask != 1 &&
+ ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL))
+ caps |= WLAN_RC_DS_FLAG;
+ if (is_cw40)
+ caps |= WLAN_RC_40_FLAG;
+ if (is_sgi40)
+ caps |= WLAN_RC_SGI_FLAG;
+ }
+
+ return caps;
+}
+
+/***********************************/
+/* mac80211 Rate Control callbacks */
+/***********************************/
+
static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb)
@@ -1467,7 +1523,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
*/
if (tx_info_priv->tx.ts_flags &
(ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
- ((sc->sc_ah->ah_txTrigLevel) >= ath_rc_priv->tx_triglevel_max)) {
+ ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
tx_status = 1;
is_underrun = 1;
}
@@ -1480,6 +1536,23 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
(is_underrun) ? ATH_11N_TXMAXTRY :
tx_info_priv->tx.ts_longretry);
+ /* Check if aggregation has to be enabled for this tid */
+ if (conf_is_ht(&sc->hw->conf) &&
+ !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+ if (ieee80211_is_data_qos(fc)) {
+ u8 *qc, tid;
+ struct ath_node *an;
+
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+ an = (struct ath_node *)sta->drv_priv;
+
+ if(ath_tx_aggr_check(sc, an, tid))
+ ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid);
+ }
+ }
+
+ ath_debug_stat_rc(sc, skb);
exit:
kfree(tx_info_priv);
}
@@ -1490,11 +1563,9 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct ieee80211_supported_band *sband = txrc->sband;
struct sk_buff *skb = txrc->skb;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_softc *sc = priv;
- struct ieee80211_hw *hw = sc->hw;
struct ath_rate_priv *ath_rc_priv = priv_sta;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- int is_probe = 0;
__le16 fc = hdr->frame_control;
/* lowest rate for management and multicast/broadcast frames */
@@ -1507,23 +1578,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
}
/* Find tx rate for unicast frames */
- ath_rc_ratefind(sc, ath_rc_priv, ATH_11N_TXMAXTRY, 4,
- tx_info, &is_probe, false);
-
- /* Check if aggregation has to be enabled for this tid */
- if (hw->conf.ht.enabled) {
- if (ieee80211_is_data_qos(fc)) {
- u8 *qc, tid;
- struct ath_node *an;
-
- qc = ieee80211_get_qos_ctl(hdr);
- tid = qc[0] & 0xf;
- an = (struct ath_node *)sta->drv_priv;
-
- if(ath_tx_aggr_check(sc, an, tid))
- ieee80211_start_tx_ba_session(hw, hdr->addr1, tid);
- }
- }
+ ath_rc_ratefind(sc, ath_rc_priv, txrc);
}
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1531,6 +1586,8 @@ 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;
+ bool is_cw40, is_sgi40;
int i, j = 0;
for (i = 0; i < sband->n_bitrates; i++) {
@@ -1552,12 +1609,72 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
ath_rc_priv->neg_ht_rates.rs_nrates = j;
}
- ath_rc_init(sc, priv_sta, sband, sta);
+ is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+
+ /* Choose rate table first */
+
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
+ (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
+ rate_table = ath_choose_rate_table(sc, sband->band,
+ sta->ht_cap.ht_supported,
+ is_cw40);
+ } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
+ /* cur_rate_table would be set on init through config() */
+ rate_table = sc->cur_rate_table;
+ }
+
+ ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta->ht_cap.ht_supported,
+ is_cw40, is_sgi40);
+ ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+}
+
+static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ u32 changed)
+{
+ struct ath_softc *sc = priv;
+ struct ath_rate_priv *ath_rc_priv = priv_sta;
+ struct ath_rate_table *rate_table = NULL;
+ bool oper_cw40 = false, oper_sgi40;
+ bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
+ true : false;
+ bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
+ true : false;
+
+ /* FIXME: Handle AP mode later when we support CWM */
+
+ if (changed & IEEE80211_RC_HT_CHANGED) {
+ if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
+ sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
+ oper_cw40 = true;
+
+ oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+ true : false;
+
+ if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
+ rate_table = ath_choose_rate_table(sc, sband->band,
+ sta->ht_cap.ht_supported,
+ oper_cw40);
+ ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc,
+ sta->ht_cap.ht_supported,
+ oper_cw40, oper_sgi40);
+ ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "Operating HT Bandwidth changed to: %d\n",
+ sc->hw->conf.channel_type);
+ }
+ }
}
static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
{
- return hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ return aphy->sc;
}
static void ath_rate_free(void *priv)
@@ -1578,7 +1695,7 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
}
rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
- rate_priv->tx_triglevel_max = sc->sc_ah->ah_caps.tx_triglevel_max;
+ rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
return rate_priv;
}
@@ -1596,41 +1713,13 @@ static struct rate_control_ops ath_rate_ops = {
.tx_status = ath_tx_status,
.get_rate = ath_get_rate,
.rate_init = ath_rate_init,
+ .rate_update = ath_rate_update,
.alloc = ath_rate_alloc,
.free = ath_rate_free,
.alloc_sta = ath_rate_alloc_sta,
.free_sta = ath_rate_free_sta,
};
-static void ath_setup_rate_table(struct ath_softc *sc,
- struct ath_rate_table *rate_table)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- rate_table->rateCodeToIndex[i] = (u8)-1;
-
- for (i = 0; i < rate_table->rate_cnt; i++) {
- u8 code = rate_table->info[i].ratecode;
- u8 cix = rate_table->info[i].ctrl_rate;
- u8 sh = rate_table->info[i].short_preamble;
-
- rate_table->rateCodeToIndex[code] = i;
- rate_table->rateCodeToIndex[code | sh] = i;
-
- rate_table->info[i].lpAckDuration =
- ath9k_hw_computetxtime(sc->sc_ah, rate_table,
- WLAN_CTRL_FRAME_SIZE,
- cix,
- false);
- rate_table->info[i].spAckDuration =
- ath9k_hw_computetxtime(sc->sc_ah, rate_table,
- WLAN_CTRL_FRAME_SIZE,
- cix,
- true);
- }
-}
-
void ath_rate_attach(struct ath_softc *sc)
{
sc->hw_rate_table[ATH9K_MODE_11B] =
@@ -1651,12 +1740,6 @@ void ath_rate_attach(struct ath_softc *sc)
&ar5416_11ng_ratetable;
sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
&ar5416_11ng_ratetable;
-
- ath_setup_rate_table(sc, &ar5416_11b_ratetable);
- ath_setup_rate_table(sc, &ar5416_11a_ratetable);
- ath_setup_rate_table(sc, &ar5416_11g_ratetable);
- ath_setup_rate_table(sc, &ar5416_11na_ratetable);
- ath_setup_rate_table(sc, &ar5416_11ng_ratetable);
}
int ath_rate_control_register(void)
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
index 97c60d12e8a..db9b0b9a343 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -19,13 +19,12 @@
#ifndef RC_H
#define RC_H
-#include "ath9k.h"
-
struct ath_softc;
#define ATH_RATE_MAX 30
#define RATE_TABLE_SIZE 64
#define MAX_TX_RATE_PHY 48
+#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
/* VALID_ALL - valid for 20/40/Legacy,
* VALID - Legacy only,
@@ -39,6 +38,20 @@ struct ath_softc;
#define VALID_2040 (VALID_20|VALID_40)
#define VALID_ALL (VALID_2040|VALID)
+enum {
+ WLAN_RC_PHY_OFDM,
+ WLAN_RC_PHY_CCK,
+ WLAN_RC_PHY_HT_20_SS,
+ WLAN_RC_PHY_HT_20_DS,
+ WLAN_RC_PHY_HT_40_SS,
+ WLAN_RC_PHY_HT_40_DS,
+ WLAN_RC_PHY_HT_20_SS_HGI,
+ WLAN_RC_PHY_HT_20_DS_HGI,
+ WLAN_RC_PHY_HT_40_SS_HGI,
+ WLAN_RC_PHY_HT_40_DS_HGI,
+ WLAN_RC_PHY_MAX
+};
+
#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
@@ -90,7 +103,6 @@ struct ath_softc;
*/
struct ath_rate_table {
int rate_cnt;
- u8 rateCodeToIndex[256];
struct {
int valid;
int valid_single_stream;
@@ -108,8 +120,6 @@ struct ath_rate_table {
u8 sgi_index;
u8 ht_index;
u32 max_4ms_framelen;
- u16 lpAckDuration;
- u16 spAckDuration;
} info[RATE_TABLE_SIZE];
u32 probe_interval;
u32 rssi_reduce_interval;
@@ -184,11 +194,19 @@ struct ath_rate_priv {
struct ath_rate_softc *asc;
};
+enum ath9k_internal_frame_type {
+ ATH9K_NOT_INTERNAL,
+ ATH9K_INT_PAUSE,
+ ATH9K_INT_UNPAUSE
+};
+
struct ath_tx_info_priv {
+ struct ath_wiphy *aphy;
struct ath_tx_status tx;
int n_frames;
int n_bad_frames;
bool update_rc;
+ enum ath9k_internal_frame_type frame_type;
};
#define ATH_TX_INFO_PRIV(tx_info) \
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 462e08c3d09..0bba17662a1 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -14,7 +14,28 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
+#include "ath9k.h"
+
+static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
+ struct ieee80211_hdr *hdr)
+{
+ struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+ int i;
+
+ spin_lock_bh(&sc->wiphy_lock);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy == NULL)
+ continue;
+ if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr)
+ == 0) {
+ hw = aphy->hw;
+ break;
+ }
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+ return hw;
+}
/*
* Setup and link descriptors.
@@ -26,7 +47,7 @@
*/
static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_desc *ds;
struct sk_buff *skb;
@@ -79,7 +100,7 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
return (tsf & ~0x7fff) | rstamp;
}
-static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
+static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
{
struct sk_buff *skb;
u32 off;
@@ -97,11 +118,11 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
* Unfortunately this means we may get 8 KB here from the
* kernel... and that is actually what is observed on some
* systems :( */
- skb = dev_alloc_skb(len + sc->sc_cachelsz - 1);
+ skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
if (skb != NULL) {
- off = ((unsigned long) skb->data) % sc->sc_cachelsz;
+ off = ((unsigned long) skb->data) % sc->cachelsz;
if (off != 0)
- skb_reserve(skb, sc->sc_cachelsz - off);
+ skb_reserve(skb, sc->cachelsz - off);
} else {
DPRINTF(sc, ATH_DBG_FATAL,
"skbuff alloc of size %u failed\n", len);
@@ -123,10 +144,12 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
struct ieee80211_hdr *hdr;
u8 ratecode;
__le16 fc;
+ struct ieee80211_hw *hw;
hdr = (struct ieee80211_hdr *)skb->data;
fc = hdr->frame_control;
memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
+ hw = ath_get_virt_hw(sc, hdr);
if (ds->ds_rxstat.rs_more) {
/*
@@ -135,7 +158,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
* discard the frame. Enable this if you want to see
* error frames in Monitor mode.
*/
- if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_MONITOR)
+ if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
goto rx_next;
} else if (ds->ds_rxstat.rs_status != 0) {
if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
@@ -161,7 +184,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
* decryption and MIC failures. For monitor mode,
* we also ignore the CRC error.
*/
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR) {
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
if (ds->ds_rxstat.rs_status &
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
ATH9K_RXERR_CRC))
@@ -186,7 +209,6 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
rx_status->rate_idx = ratecode & 0x7f;
} else {
int i = 0, cur_band, n_rates;
- struct ieee80211_hw *hw = sc->hw;
cur_band = hw->conf.channel->band;
n_rates = sc->sbands[cur_band].n_bitrates;
@@ -208,9 +230,9 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
}
rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
- rx_status->band = sc->hw->conf.channel->band;
- rx_status->freq = sc->hw->conf.channel->center_freq;
- rx_status->noise = sc->sc_ani.sc_noise_floor;
+ rx_status->band = hw->conf.channel->band;
+ rx_status->freq = hw->conf.channel->center_freq;
+ rx_status->noise = sc->ani.noise_floor;
rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
rx_status->antenna = ds->ds_rxstat.rs_antenna;
@@ -233,7 +255,7 @@ rx_next:
static void ath_opmode_init(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
u32 rfilt, mfilt[2];
/* configure rx filter */
@@ -241,14 +263,14 @@ static void ath_opmode_init(struct ath_softc *sc)
ath9k_hw_setrxfilter(ah, rfilt);
/* configure bssid mask */
- if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+ ath9k_hw_setbssidmask(sc);
/* configure operational mode */
ath9k_hw_setopmode(ah);
/* Handle any link-level address change. */
- ath9k_hw_setmac(ah, sc->sc_myaddr);
+ ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
/* calculate and install multicast filter */
mfilt[0] = mfilt[1] = ~0;
@@ -267,11 +289,11 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
spin_lock_init(&sc->rx.rxbuflock);
sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
- min(sc->sc_cachelsz,
+ min(sc->cachelsz,
(u16)64));
DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
- sc->sc_cachelsz, sc->rx.bufsize);
+ sc->cachelsz, sc->rx.bufsize);
/* Initialize rx descriptors */
@@ -284,22 +306,22 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
}
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
- skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
+ skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
if (skb == NULL) {
error = -ENOMEM;
break;
}
bf->bf_mpdu = skb;
- bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
+ bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
sc->rx.bufsize,
- PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev,
+ 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,
- "pci_dma_mapping_error() on RX init\n");
+ "dma_mapping_error() on RX init\n");
error = -ENOMEM;
break;
}
@@ -360,26 +382,39 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
| ATH9K_RX_FILTER_MCAST;
/* If not a STA, enable processing of Probe Requests */
- if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_STATION)
+ if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
rfilt |= ATH9K_RX_FILTER_PROBEREQ;
- /* Can't set HOSTAP into promiscous mode */
- if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) &&
+ /*
+ * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
+ * mode interface or when in monitor mode. AP mode does not need this
+ * since it receives all in-BSS frames anyway.
+ */
+ if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
(sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
- (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) {
+ (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
rfilt |= ATH9K_RX_FILTER_PROM;
- /* ??? To prevent from sending ACK */
- rfilt &= ~ATH9K_RX_FILTER_UCAST;
- }
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION ||
- sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)
+ if (sc->rx.rxfilter & FIF_CONTROL)
+ rfilt |= ATH9K_RX_FILTER_CONTROL;
+
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+ !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
+ rfilt |= ATH9K_RX_FILTER_MYBEACON;
+ else
rfilt |= ATH9K_RX_FILTER_BEACON;
- /* If in HOSTAP mode, want to enable reception of PSPOLL frames
- & beacon frames */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP)
- rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
+ /* If in HOSTAP mode, want to enable reception of PSPOLL frames */
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
+ rfilt |= ATH9K_RX_FILTER_PSPOLL;
+
+ if (sc->sec_wiphy) {
+ /* TODO: only needed if more than one BSSID is in use in
+ * station/adhoc mode */
+ /* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM
+ */
+ rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
+ }
return rfilt;
@@ -388,7 +423,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
int ath_startrecv(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_buf *bf, *tbf;
spin_lock_bh(&sc->rx.rxbuflock);
@@ -418,13 +453,12 @@ start_recv:
bool ath_stoprecv(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
bool stopped;
ath9k_hw_stoppcurecv(ah);
ath9k_hw_setrxfilter(ah, 0);
stopped = ath9k_hw_stopdmarecv(ah);
- mdelay(3); /* 3ms is long enough for 1 frame */
sc->rx.rxlink = NULL;
return stopped;
@@ -449,7 +483,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
struct ath_desc *ds;
struct sk_buff *skb = NULL, *requeue_skb;
struct ieee80211_rx_status rx_status;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ieee80211_hdr *hdr;
int hdrlen, padsize, retval;
bool decrypt_error = false;
@@ -524,9 +558,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
* 1. accessing the frame
* 2. requeueing the same buffer to h/w
*/
- pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
+ dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
sc->rx.bufsize,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
/*
* If we're asked to flush receive queue, directly
@@ -547,7 +581,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
/* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */
- requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
+ requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
/* If there is no memory we ignore the current RX'd frame,
* tell hardware it can give us a new frame using the old
@@ -557,9 +591,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
goto requeue;
/* Unmap the frame */
- pci_unmap_single(sc->pdev, bf->bf_buf_addr,
+ dma_unmap_single(sc->dev, bf->bf_buf_addr,
sc->rx.bufsize,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
skb_put(skb, ds->ds_rxstat.rs_datalen);
skb->protocol = cpu_to_be16(ETH_P_CONTROL);
@@ -590,24 +624,52 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
&& !decrypt_error && skb->len >= hdrlen + 4) {
keyix = skb->data[hdrlen + 3] >> 6;
- if (test_bit(keyix, sc->sc_keymap))
+ if (test_bit(keyix, sc->keymap))
rx_status.flag |= RX_FLAG_DECRYPTED;
}
+ if (ah->sw_mgmt_crypto &&
+ (rx_status.flag & RX_FLAG_DECRYPTED) &&
+ ieee80211_is_mgmt(hdr->frame_control)) {
+ /* Use software decrypt for management frames. */
+ rx_status.flag &= ~RX_FLAG_DECRYPTED;
+ }
/* Send the frame to mac80211 */
- __ieee80211_rx(sc->hw, skb, &rx_status);
+ 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 = pci_map_single(sc->pdev, requeue_skb->data,
+ bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
sc->rx.bufsize,
- PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev,
bf->bf_buf_addr))) {
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on RX\n");
+ "dma_mapping_error() on RX\n");
break;
}
bf->bf_dmacontext = bf->bf_buf_addr;
@@ -622,6 +684,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
} else {
sc->rx.rxotherant = 0;
}
+
+ if (ieee80211_is_beacon(hdr->frame_control) &&
+ (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
+ sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+ }
requeue:
list_move_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_buf_link(sc, bf);
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
index 9fedb4911bc..d86e90e3817 100644
--- a/drivers/net/wireless/ath9k/reg.h
+++ b/drivers/net/wireless/ath9k/reg.h
@@ -67,7 +67,7 @@
#define AR_DMASIZE_512B 0x00000007
#define AR_TXCFG 0x0030
-#define AR_TXCFG_DMASZ_MASK 0x00000003
+#define AR_TXCFG_DMASZ_MASK 0x00000007
#define AR_TXCFG_DMASZ_4B 0
#define AR_TXCFG_DMASZ_8B 1
#define AR_TXCFG_DMASZ_16B 2
@@ -158,13 +158,6 @@
#define AR_CST_TIMEOUT_LIMIT 0xFFFF0000
#define AR_CST_TIMEOUT_LIMIT_S 16
-#define AR_SREV_VERSION_9100 0x014
-
-#define AR_SREV_5416_V20_OR_LATER(_ah) \
- (AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah))
-#define AR_SREV_5416_V22_OR_LATER(_ah) \
- (AR_SREV_9100((_ah)) || AR_SREV_5416_22_OR_LATER(_ah))
-
#define AR_ISR 0x0080
#define AR_ISR_RXOK 0x00000001
#define AR_ISR_RXDESC 0x00000002
@@ -733,6 +726,7 @@
#define AR_SREV_REVISION_5416_10 0
#define AR_SREV_REVISION_5416_20 1
#define AR_SREV_REVISION_5416_22 2
+#define AR_SREV_VERSION_9100 0x14
#define AR_SREV_VERSION_9160 0x40
#define AR_SREV_REVISION_9160_10 0
#define AR_SREV_REVISION_9160_11 1
@@ -745,45 +739,60 @@
#define AR_SREV_REVISION_9285_11 1
#define AR_SREV_REVISION_9285_12 2
-#define AR_SREV_9100_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
+#define AR_SREV_5416(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
+ ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
#define AR_SREV_5416_20_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
- ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_20))
+ (((AR_SREV_5416(_ah)) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
+ ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
#define AR_SREV_5416_22_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
- ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_22))
+ (((AR_SREV_5416(_ah)) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
+ ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9100(ah) \
+ ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
+#define AR_SREV_9100_OR_LATER(_ah) \
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
#define AR_SREV_9160(_ah) \
- (((_ah)->ah_macVersion == AR_SREV_VERSION_9160))
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
#define AR_SREV_9160_10_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160))
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
#define AR_SREV_9160_11(_ah) \
- (AR_SREV_9160(_ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9160_11))
+ (AR_SREV_9160(_ah) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
#define AR_SREV_9280(_ah) \
- (((_ah)->ah_macVersion == AR_SREV_VERSION_9280))
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
#define AR_SREV_9280_10_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9280))
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
#define AR_SREV_9280_20(_ah) \
- (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
- ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20))
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
#define AR_SREV_9280_20_OR_LATER(_ah) \
- (((_ah)->ah_macVersion > AR_SREV_VERSION_9280) || \
- (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
- ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20)))
+ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
-#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
+#define AR_SREV_9285(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
#define AR_SREV_9285_10_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9285))
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
#define AR_SREV_9285_11(_ah) \
- (AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_11))
+ (AR_SREV_9285(ah) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
#define AR_SREV_9285_11_OR_LATER(_ah) \
- (((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
- (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_11)))
+ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+ (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+ AR_SREV_REVISION_9285_11)))
#define AR_SREV_9285_12(_ah) \
- (AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_12))
+ (AR_SREV_9285(ah) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
#define AR_SREV_9285_12_OR_LATER(_ah) \
- (((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
- (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_12)))
+ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+ (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+ AR_SREV_REVISION_9285_12)))
#define AR_RADIO_SREV_MAJOR 0xf0
#define AR_RAD5133_SREV_MAJOR 0xc0
@@ -875,12 +884,15 @@ enum {
#define AR_NUM_GPIO 14
#define AR928X_NUM_GPIO 10
+#define AR9285_NUM_GPIO 12
#define AR_GPIO_IN_OUT 0x4048
#define AR_GPIO_IN_VAL 0x0FFFC000
#define AR_GPIO_IN_VAL_S 14
#define AR928X_GPIO_IN_VAL 0x000FFC00
#define AR928X_GPIO_IN_VAL_S 10
+#define AR9285_GPIO_IN_VAL 0x00FFF000
+#define AR9285_GPIO_IN_VAL_S 12
#define AR_GPIO_OE_OUT 0x404c
#define AR_GPIO_OE_OUT_DRV 0x3
@@ -894,14 +906,24 @@ enum {
#define AR_GPIO_INTR_POL_VAL_S 0
#define AR_GPIO_INPUT_EN_VAL 0x4054
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S 3
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF 0x00000010
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S 4
#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080
#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S 12
#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000
#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15
#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
#define AR_GPIO_JTAG_DISABLE 0x00020000
#define AR_GPIO_INPUT_MUX1 0x4058
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
#define AR_GPIO_INPUT_MUX2 0x405c
#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
@@ -940,7 +962,7 @@ enum {
#define AR_RTC_BASE 0x00020000
#define AR_RTC_RC \
- (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000
+ ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000)
#define AR_RTC_RC_M 0x00000003
#define AR_RTC_RC_MAC_WARM 0x00000001
#define AR_RTC_RC_MAC_COLD 0x00000002
@@ -948,7 +970,7 @@ enum {
#define AR_RTC_RC_WARM_RESET 0x00000008
#define AR_RTC_PLL_CONTROL \
- (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014
+ ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
#define AR_RTC_PLL_DIV 0x0000001f
#define AR_RTC_PLL_DIV_S 0
@@ -957,8 +979,6 @@ enum {
#define AR_RTC_PLL_CLKSEL 0x00000300
#define AR_RTC_PLL_CLKSEL_S 8
-
-
#define AR_RTC_RESET \
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
#define AR_RTC_RESET_EN (0x00000001)
@@ -995,6 +1015,12 @@ enum {
#define AR_RTC_INTR_MASK \
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
+/* RTC_DERIVED_* - only for AR9100 */
+
+#define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe
+#define AR_RTC_DERIVED_CLK_PERIOD_S 1
+
#define AR_SEQ_MASK 0x8060
#define AR_AN_RF2G1_CH0 0x7810
@@ -1021,6 +1047,10 @@ enum {
#define AR_AN_RF5G1_CH1_DB5 0x00380000
#define AR_AN_RF5G1_CH1_DB5_S 19
+#define AR_AN_TOP1 0x7890
+#define AR_AN_TOP1_DACIPMODE 0x00040000
+#define AR_AN_TOP1_DACIPMODE_S 18
+
#define AR_AN_TOP2 0x7894
#define AR_AN_TOP2_XPABIAS_LVL 0xC0000000
#define AR_AN_TOP2_XPABIAS_LVL_S 30
@@ -1181,18 +1211,7 @@ enum {
#define AR_CFP_VAL 0x0000FFFF
#define AR_RX_FILTER 0x803C
-#define AR_RX_FILTER_ALL 0x00000000
-#define AR_RX_UCAST 0x00000001
-#define AR_RX_MCAST 0x00000002
-#define AR_RX_BCAST 0x00000004
-#define AR_RX_CONTROL 0x00000008
-#define AR_RX_BEACON 0x00000010
-#define AR_RX_PROM 0x00000020
-#define AR_RX_PROBE_REQ 0x00000080
-#define AR_RX_MY_BEACON 0x00000200
#define AR_RX_COMPR_BAR 0x00000400
-#define AR_RX_COMPR_BA 0x00000800
-#define AR_RX_UNCOM_BA_BAR 0x00001000
#define AR_MCAST_FIL0 0x8040
#define AR_MCAST_FIL1 0x8044
@@ -1236,6 +1255,8 @@ enum {
#define AR_AES_MUTE_MASK1 0x8060
#define AR_AES_MUTE_MASK1_SEQ 0x0000FFFF
+#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
#define AR_GATED_CLKS 0x8064
#define AR_GATED_CLKS_TX 0x00000002
@@ -1370,8 +1391,8 @@ enum {
#define AR_PHY_COUNTMAX (3 << 22)
#define AR_MIBCNT_INTRMASK (3 << 22)
-#define AR_TSF_THRESHOLD 0x813c
-#define AR_TSF_THRESHOLD_VAL 0x0000FFFF
+#define AR_TSFOOR_THRESHOLD 0x813c
+#define AR_TSFOOR_THRESHOLD_VAL 0x0000FFFF
#define AR_PHY_ERR_EIFS_MASK 8144
@@ -1460,6 +1481,10 @@ enum {
#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
+#define AR_PCU_MISC_MODE2 0x8344
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004
+
#define AR_KEYTABLE_0 0x8800
#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
#define AR_KEY_CACHE_SIZE 128
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index 64043e99fac..b8f9b6d6bec 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -16,998 +16,504 @@
#include <linux/kernel.h>
#include <linux/slab.h>
-#include "core.h"
-#include "hw.h"
-#include "regd.h"
+#include "ath9k.h"
#include "regd_common.h"
-static int ath9k_regd_chansort(const void *a, const void *b)
-{
- const struct ath9k_channel *ca = a;
- const struct ath9k_channel *cb = b;
+/*
+ * This is a set of common rules used by our world regulatory domains.
+ * We have 12 world regulatory domains. To save space we consolidate
+ * the regulatory domains in 5 structures by frequency and change
+ * the flags on our reg_notifier() on a case by case basis.
+ */
- return (ca->channel == cb->channel) ?
- (ca->channelFlags & CHAN_FLAGS) -
- (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel;
+/* Only these channels all allow active scan on all world regulatory domains */
+#define ATH9K_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
+
+/* We enable active scan on these a case by case basis by regulatory domain */
+#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
+ NL80211_RRF_PASSIVE_SCAN)
+#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
+
+/* We allow IBSS on these on a case by case basis by regulatory domain */
+#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 40, 0, 30,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 40, 0, 30,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+
+#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \
+ ATH9K_2GHZ_CH12_13, \
+ ATH9K_2GHZ_CH14
+
+#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \
+ ATH9K_5GHZ_5470_5850
+/* This one skips what we call "mid band" */
+#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
+ ATH9K_5GHZ_5725_5850
+
+/* Can be used for:
+ * 0x60, 0x61, 0x62 */
+static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
+ .n_reg_rules = 5,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_ALL,
+ ATH9K_5GHZ_ALL,
+ }
+};
+
+/* Can be used by 0x63 and 0x65 */
+static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_2GHZ_CH12_13,
+ ATH9K_5GHZ_NO_MIDBAND,
+ }
+};
+
+/* Can be used by 0x64 only */
+static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_5GHZ_NO_MIDBAND,
+ }
+};
+
+/* Can be used by 0x66 and 0x69 */
+static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_5GHZ_ALL,
+ }
+};
+
+/* Can be used by 0x67, 0x6A and 0x68 */
+static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_2GHZ_CH12_13,
+ ATH9K_5GHZ_ALL,
+ }
+};
+
+static inline bool is_wwr_sku(u16 regd)
+{
+ return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
+ (regd == WORLD);
}
-static void
-ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp)
+static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah)
{
- u8 *aa = a;
- u8 *ai, *t;
-
- for (ai = aa + size; --n >= 1; ai += size)
- for (t = ai; t > aa; t -= size) {
- u8 *u = t - size;
- if (cmp(u, t) <= 0)
- break;
- swap_array(u, t, size);
- }
+ return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG;
}
-static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah)
+bool ath9k_is_world_regd(struct ath_hw *ah)
{
- return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG;
+ return is_wwr_sku(ath9k_regd_get_eepromRD(ah));
}
-static bool ath9k_regd_is_chan_bm_zero(u64 *bitmask)
+const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
{
- int i;
-
- for (i = 0; i < BMLEN; i++) {
- if (bitmask[i] != 0)
- return false;
- }
- return true;
+ /* this is the most restrictive */
+ return &ath9k_world_regdom_64;
}
-static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah)
+const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
{
- u16 rd = ath9k_regd_get_eepromRD(ah);
- int i;
-
- if (rd & COUNTRY_ERD_FLAG) {
- u16 cc = rd & ~COUNTRY_ERD_FLAG;
- for (i = 0; i < ARRAY_SIZE(allCountries); i++)
- if (allCountries[i].countryCode == cc)
- return true;
- } else {
- for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
- if (regDomainPairs[i].regDmnEnum == rd)
- return true;
+ switch (ah->regulatory.regpair->regDmnEnum) {
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ return &ath9k_world_regdom_60_61_62;
+ case 0x63:
+ case 0x65:
+ return &ath9k_world_regdom_63_65;
+ case 0x64:
+ return &ath9k_world_regdom_64;
+ case 0x66:
+ case 0x69:
+ return &ath9k_world_regdom_66_69;
+ case 0x67:
+ case 0x68:
+ case 0x6A:
+ return &ath9k_world_regdom_67_68_6A;
+ default:
+ WARN_ON(1);
+ return ath9k_default_world_regdomain();
}
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "invalid regulatory domain/country code 0x%x\n", rd);
- return false;
}
-static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah)
+/* Frequency is one where radar detection is required */
+static bool ath9k_is_radar_freq(u16 center_freq)
{
- u32 regcap;
-
- regcap = ah->ah_caps.reg_cap;
-
- if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND)
- return true;
- else
- return false;
+ return (center_freq >= 5260 && center_freq <= 5700);
}
-static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah,
- u16 cc)
+/*
+ * N.B: These exception rules do not apply radar freqs.
+ *
+ * - We enable adhoc (or beaconing) if allowed by 11d
+ * - We enable active scan if the channel is allowed by 11d
+ * - If no country IE has been processed and a we determine we have
+ * received a beacon on a channel we can enable active scan and
+ * adhoc (or beaconing).
+ */
+static void ath9k_reg_apply_beaconing_flags(
+ struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
- u16 rd;
- int i;
+ enum ieee80211_band band;
+ struct ieee80211_supported_band *sband;
+ const struct ieee80211_reg_rule *reg_rule;
+ struct ieee80211_channel *ch;
+ unsigned int i;
+ u32 bandwidth = 0;
+ int r;
- if (cc == CTRY_DEFAULT)
- return true;
- if (cc == CTRY_DEBUG)
- return true;
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
- rd = ath9k_regd_get_eepromRD(ah);
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd);
-
- if (rd & COUNTRY_ERD_FLAG) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "EEPROM setting is country code %u\n",
- rd & ~COUNTRY_ERD_FLAG);
- return cc == (rd & ~COUNTRY_ERD_FLAG);
- }
+ if (!wiphy->bands[band])
+ continue;
- for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
- if (cc == allCountries[i].countryCode) {
-#ifdef AH_SUPPORT_11D
- if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)
- return true;
-#endif
- if (allCountries[i].regDmnEnum == rd ||
- rd == DEBUG_REG_DMN || rd == NO_ENUMRD)
- return true;
+ sband = wiphy->bands[band];
+
+ for (i = 0; i < sband->n_channels; i++) {
+
+ ch = &sband->channels[i];
+
+ if (ath9k_is_radar_freq(ch->center_freq) ||
+ (ch->flags & IEEE80211_CHAN_RADAR))
+ continue;
+
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+ r = freq_reg_info(wiphy, ch->center_freq,
+ &bandwidth, &reg_rule);
+ if (r)
+ continue;
+ /*
+ * If 11d had a rule for this channel ensure
+ * we enable adhoc/beaconing if it allows us to
+ * use it. Note that we would have disabled it
+ * by applying our static world regdomain by
+ * default during init, prior to calling our
+ * regulatory_hint().
+ */
+ if (!(reg_rule->flags &
+ NL80211_RRF_NO_IBSS))
+ ch->flags &=
+ ~IEEE80211_CHAN_NO_IBSS;
+ if (!(reg_rule->flags &
+ NL80211_RRF_PASSIVE_SCAN))
+ ch->flags &=
+ ~IEEE80211_CHAN_PASSIVE_SCAN;
+ } else {
+ if (ch->beacon_found)
+ ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN);
+ }
}
}
- return false;
-}
-
-static void
-ath9k_regd_get_wmodes_nreg(struct ath_hal *ah,
- struct country_code_to_enum_rd *country,
- struct regDomain *rd5GHz,
- unsigned long *modes_allowed)
-{
- bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX);
-
- if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) &&
- (!country->allow11g))
- clear_bit(ATH9K_MODE_11G, modes_allowed);
- if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) &&
- (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a)))
- clear_bit(ATH9K_MODE_11A, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes)
- && (!country->allow11ng20))
- clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes)
- && (!country->allow11na20))
- clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) &&
- (!country->allow11ng40))
- clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) &&
- (!country->allow11ng40))
- clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) &&
- (!country->allow11na40))
- clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) &&
- (!country->allow11na40))
- clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed);
}
-bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah)
+/* 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)
{
- u16 rd;
-
- rd = ath9k_regd_get_eepromRD(ah);
-
- switch (rd) {
- case FCC4_FCCA:
- case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG):
- return true;
- case DEBUG_REG_DMN:
- case NO_ENUMRD:
- if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49)
- return true;
- break;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ const struct ieee80211_reg_rule *reg_rule;
+ u32 bandwidth = 0;
+ int r;
+
+ sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+
+ /*
+ * If no country IE has been received always enable active scan
+ * on these channels. This is only done for specific regulatory SKUs
+ */
+ if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+ ch = &sband->channels[11]; /* CH 12 */
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ ch = &sband->channels[12]; /* CH 13 */
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ return;
}
- return false;
-}
-static struct country_code_to_enum_rd*
-ath9k_regd_find_country(u16 countryCode)
-{
- int i;
+ /*
+ * If a country IE has been recieved check its rule for this
+ * channel first before enabling active scan. The passive scan
+ * would have been enforced by the initial processing of our
+ * custom regulatory domain.
+ */
- for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
- if (allCountries[i].countryCode == countryCode)
- return &allCountries[i];
+ ch = &sband->channels[11]; /* CH 12 */
+ r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
+ if (!r) {
+ if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
}
- return NULL;
-}
-
-static u16 ath9k_regd_get_default_country(struct ath_hal *ah)
-{
- u16 rd;
- int i;
-
- rd = ath9k_regd_get_eepromRD(ah);
- if (rd & COUNTRY_ERD_FLAG) {
- struct country_code_to_enum_rd *country = NULL;
- u16 cc = rd & ~COUNTRY_ERD_FLAG;
- country = ath9k_regd_find_country(cc);
- if (country != NULL)
- return cc;
+ ch = &sband->channels[12]; /* CH 13 */
+ r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
+ if (!r) {
+ if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
}
-
- for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
- if (regDomainPairs[i].regDmnEnum == rd) {
- if (regDomainPairs[i].singleCC != 0)
- return regDomainPairs[i].singleCC;
- else
- i = ARRAY_SIZE(regDomainPairs);
- }
- return CTRY_DEFAULT;
}
-static bool ath9k_regd_is_valid_reg_domain(int regDmn,
- struct regDomain *rd)
+/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
+void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
{
- int i;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ unsigned int i;
- for (i = 0; i < ARRAY_SIZE(regDomains); i++) {
- if (regDomains[i].regDmnEnum == regDmn) {
- if (rd != NULL) {
- memcpy(rd, &regDomains[i],
- sizeof(struct regDomain));
- }
- return true;
- }
- }
- return false;
-}
+ if (!wiphy->bands[IEEE80211_BAND_5GHZ])
+ return;
-static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair)
-{
- int i;
+ sband = wiphy->bands[IEEE80211_BAND_5GHZ];
- if (regDmnPair == NO_ENUMRD)
- return false;
- for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
- if (regDomainPairs[i].regDmnEnum == regDmnPair)
- return true;
+ for (i = 0; i < sband->n_channels; i++) {
+ ch = &sband->channels[i];
+ if (!ath9k_is_radar_freq(ch->center_freq))
+ continue;
+ /* We always enable radar detection/DFS on this
+ * frequency range. Additionally we also apply on
+ * this frequency range:
+ * - If STA mode does not yet have DFS supports disable
+ * active scanning
+ * - If adhoc mode does not support DFS yet then
+ * disable adhoc in the frequency.
+ * - If AP mode does not yet support radar detection/DFS
+ * do not allow AP mode
+ */
+ if (!(ch->flags & IEEE80211_CHAN_DISABLED))
+ ch->flags |= IEEE80211_CHAN_RADAR |
+ IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN;
}
- return false;
}
-static bool
-ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
- u16 channelFlag, struct regDomain *rd)
+void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
- int i, found;
- u64 flags = NO_REQ;
- struct reg_dmn_pair_mapping *regPair = NULL;
- int regOrg;
-
- regOrg = regDmn;
- if (regDmn == CTRY_DEFAULT) {
- u16 rdnum;
- rdnum = ath9k_regd_get_eepromRD(ah);
-
- if (!(rdnum & COUNTRY_ERD_FLAG)) {
- if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) ||
- ath9k_regd_is_valid_reg_domainPair(rdnum)) {
- regDmn = rdnum;
- }
- }
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
+
+ switch (ah->regulatory.regpair->regDmnEnum) {
+ case 0x60:
+ case 0x63:
+ case 0x66:
+ case 0x67:
+ ath9k_reg_apply_beaconing_flags(wiphy, initiator);
+ break;
+ case 0x68:
+ ath9k_reg_apply_beaconing_flags(wiphy, initiator);
+ ath9k_reg_apply_active_scan_flags(wiphy, initiator);
+ break;
}
+ return;
+}
- if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
- for (i = 0, found = 0;
- (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) {
- if (regDomainPairs[i].regDmnEnum == regDmn) {
- regPair = &regDomainPairs[i];
- found = 1;
- }
- }
- if (!found) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Failed to find reg domain pair %u\n", regDmn);
- return false;
- }
- if (!(channelFlag & CHANNEL_2GHZ)) {
- regDmn = regPair->regDmn5GHz;
- flags = regPair->flags5GHz;
- }
- if (channelFlag & CHANNEL_2GHZ) {
- regDmn = regPair->regDmn2GHz;
- flags = regPair->flags2GHz;
- }
- }
+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;
- found = ath9k_regd_is_valid_reg_domain(regDmn, rd);
- if (!found) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Failed to find unitary reg domain %u\n", regDmn);
- return false;
- } else {
- rd->pscan &= regPair->pscanMask;
- if (((regOrg & MULTI_DOMAIN_MASK) == 0) &&
- (flags != NO_REQ)) {
- rd->flags = flags;
- }
+ /* We always apply this */
+ ath9k_reg_apply_radar_flags(wiphy);
- rd->flags &= (channelFlag & CHANNEL_2GHZ) ?
- REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK;
- return true;
+ switch (request->initiator) {
+ case NL80211_REGDOM_SET_BY_DRIVER:
+ case NL80211_REGDOM_SET_BY_CORE:
+ case NL80211_REGDOM_SET_BY_USER:
+ break;
+ case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+ if (ath9k_is_world_regd(sc->sc_ah))
+ ath9k_reg_apply_world_flags(wiphy, request->initiator);
+ break;
}
-}
-static bool ath9k_regd_is_bit_set(int bit, u64 *bitmask)
-{
- int byteOffset, bitnum;
- u64 val;
-
- byteOffset = bit / 64;
- bitnum = bit - byteOffset * 64;
- val = ((u64) 1) << bitnum;
- if (bitmask[byteOffset] & val)
- return true;
- else
- return false;
+ return 0;
}
-static void
-ath9k_regd_add_reg_classid(u8 *regclassids, u32 maxregids,
- u32 *nregids, u8 regclassid)
+bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
{
+ u16 rd = ath9k_regd_get_eepromRD(ah);
int i;
- if (regclassid == 0)
- return;
-
- for (i = 0; i < maxregids; i++) {
- if (regclassids[i] == regclassid)
- return;
- if (regclassids[i] == 0)
- break;
- }
-
- if (i == maxregids)
- return;
- else {
- regclassids[i] = regclassid;
- *nregids += 1;
+ if (rd & COUNTRY_ERD_FLAG) {
+ /* EEPROM value is a country code */
+ u16 cc = rd & ~COUNTRY_ERD_FLAG;
+ for (i = 0; i < ARRAY_SIZE(allCountries); i++)
+ if (allCountries[i].countryCode == cc)
+ return true;
+ } else {
+ /* EEPROM value is a regpair value */
+ for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
+ if (regDomainPairs[i].regDmnEnum == rd)
+ return true;
}
-
- return;
+ DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+ "invalid regulatory domain/country code 0x%x\n", rd);
+ return false;
}
-static bool
-ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah,
- enum reg_ext_bitmap bit)
+/* EEPROM country code to regpair mapping */
+static struct country_code_to_enum_rd*
+ath9k_regd_find_country(u16 countryCode)
{
- return (ah->ah_currentRDExt & (1 << bit)) ? true : false;
-}
-
-#ifdef ATH_NF_PER_CHAN
+ int i;
-static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans,
- int nchans)
-{
- int i, j, next;
-
- for (next = 0; next < nchans; next++) {
- for (i = 0; i < NUM_NF_READINGS; i++) {
- ichans[next].nfCalHist[i].currIndex = 0;
- ichans[next].nfCalHist[i].privNF =
- AR_PHY_CCA_MAX_GOOD_VALUE;
- ichans[next].nfCalHist[i].invalidNFcount =
- AR_PHY_CCA_FILTERWINDOW_LENGTH;
- for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
- ichans[next].nfCalHist[i].nfCalBuffer[j] =
- AR_PHY_CCA_MAX_GOOD_VALUE;
- }
- }
+ for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+ if (allCountries[i].countryCode == countryCode)
+ return &allCountries[i];
}
+ return NULL;
}
-#endif
-static int ath9k_regd_is_chan_present(struct ath_hal *ah,
- u16 c)
+/* EEPROM rd code to regpair mapping */
+static struct country_code_to_enum_rd*
+ath9k_regd_find_country_by_rd(int regdmn)
{
int i;
- for (i = 0; i < 150; i++) {
- if (!ah->ah_channels[i].channel)
- return -1;
- else if (ah->ah_channels[i].channel == c)
- return i;
+ for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+ if (allCountries[i].regDmnEnum == regdmn)
+ return &allCountries[i];
}
-
- return -1;
+ return NULL;
}
-static bool
-ath9k_regd_add_channel(struct ath_hal *ah,
- u16 c,
- u16 c_lo,
- u16 c_hi,
- u16 maxChan,
- u8 ctl,
- int pos,
- struct regDomain rd5GHz,
- struct RegDmnFreqBand *fband,
- struct regDomain *rd,
- const struct cmode *cm,
- struct ath9k_channel *ichans,
- bool enableExtendedChannels)
+/* Returns the map of the EEPROM set RD to a country code */
+static u16 ath9k_regd_get_default_country(u16 rd)
{
- struct ath9k_channel *chan;
- int ret;
- u32 channelFlags = 0;
- u8 privFlags = 0;
-
- if (!(c_lo <= c && c <= c_hi)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "c %u out of range [%u..%u]\n",
- c, c_lo, c_hi);
- return false;
- }
- if ((fband->channelBW == CHANNEL_HALF_BW) &&
- !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping %u half rate channel\n", c);
- return false;
- }
-
- if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
- !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping %u quarter rate channel\n", c);
- return false;
- }
-
- if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "c %u > maxChan %u\n", c, maxChan);
- return false;
- }
-
- if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping ecm channel\n");
- return false;
- }
-
- if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping HOSTAP channel\n");
- return false;
- }
-
- if (IS_HT40_MODE(cm->mode) &&
- !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) &&
- (fband->useDfs) &&
- (rd->conformanceTestLimit != MKK)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n");
- return false;
- }
-
- if (IS_HT40_MODE(cm->mode) &&
- !(ath9k_regd_get_eeprom_reg_ext_bits(ah,
- REG_EXT_JAPAN_NONDFS_HT40)) &&
- !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping HT40 channel (en_jap_ht40 = 0)\n");
- return false;
- }
-
- if (IS_HT40_MODE(cm->mode) &&
- !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) &&
- (fband->useDfs) &&
- (rd->conformanceTestLimit == MKK)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n");
- return false;
- }
-
- /* Calculate channel flags */
-
- channelFlags = cm->flags;
-
- switch (fband->channelBW) {
- case CHANNEL_HALF_BW:
- channelFlags |= CHANNEL_HALF;
- break;
- case CHANNEL_QUARTER_BW:
- channelFlags |= CHANNEL_QUARTER;
- break;
- }
-
- if (fband->usePassScan & rd->pscan)
- channelFlags |= CHANNEL_PASSIVE;
- else
- channelFlags &= ~CHANNEL_PASSIVE;
- if (fband->useDfs & rd->dfsMask)
- privFlags = CHANNEL_DFS;
- else
- privFlags = 0;
- if (rd->flags & LIMIT_FRAME_4MS)
- privFlags |= CHANNEL_4MS_LIMIT;
- if (privFlags & CHANNEL_DFS)
- privFlags |= CHANNEL_DISALLOW_ADHOC;
- if (rd->flags & ADHOC_PER_11D)
- privFlags |= CHANNEL_PER_11D_ADHOC;
-
- if (channelFlags & CHANNEL_PASSIVE) {
- if ((c < 2412) || (c > 2462)) {
- if (rd5GHz.regDmnEnum == MKK1 ||
- rd5GHz.regDmnEnum == MKK2) {
- u32 regcap = ah->ah_caps.reg_cap;
- if (!(regcap &
- (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
- AR_EEPROM_EEREGCAP_EN_KK_U2 |
- AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) &&
- isUNII1OddChan(c)) {
- channelFlags &= ~CHANNEL_PASSIVE;
- } else {
- privFlags |= CHANNEL_DISALLOW_ADHOC;
- }
- } else {
- privFlags |= CHANNEL_DISALLOW_ADHOC;
- }
- }
- }
-
- if ((cm->mode == ATH9K_MODE_11A) ||
- (cm->mode == ATH9K_MODE_11NA_HT20) ||
- (cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
- (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) {
- if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
- privFlags |= CHANNEL_DISALLOW_ADHOC;
- }
+ if (rd & COUNTRY_ERD_FLAG) {
+ struct country_code_to_enum_rd *country = NULL;
+ u16 cc = rd & ~COUNTRY_ERD_FLAG;
- /* Fill in channel details */
-
- ret = ath9k_regd_is_chan_present(ah, c);
- if (ret == -1) {
- chan = &ah->ah_channels[pos];
- chan->channel = c;
- chan->maxRegTxPower = fband->powerDfs;
- chan->antennaMax = fband->antennaMax;
- chan->regDmnFlags = rd->flags;
- chan->maxTxPower = AR5416_MAX_RATE_POWER;
- chan->minTxPower = AR5416_MAX_RATE_POWER;
- chan->channelFlags = channelFlags;
- chan->privFlags = privFlags;
- } else {
- chan = &ah->ah_channels[ret];
- chan->channelFlags |= channelFlags;
- chan->privFlags |= privFlags;
+ country = ath9k_regd_find_country(cc);
+ if (country != NULL)
+ return cc;
}
- /* Set CTLs */
-
- if ((cm->flags & CHANNEL_ALL) == CHANNEL_A)
- chan->conformanceTestLimit[0] = ctl;
- else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B)
- chan->conformanceTestLimit[1] = ctl;
- else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G)
- chan->conformanceTestLimit[2] = ctl;
-
- return (ret == -1) ? true : false;
+ return CTRY_DEFAULT;
}
-static bool ath9k_regd_japan_check(struct ath_hal *ah,
- int b,
- struct regDomain *rd5GHz)
+static struct reg_dmn_pair_mapping*
+ath9k_get_regpair(int regdmn)
{
- bool skipband = false;
int i;
- u32 regcap;
-
- for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) {
- if (j_bandcheck[i].freqbandbit == b) {
- regcap = ah->ah_caps.reg_cap;
- if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) {
- skipband = true;
- } else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) ||
- (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) {
- rd5GHz->dfsMask |= DFS_MKK4;
- rd5GHz->pscan |= PSCAN_MKK3;
- }
- break;
- }
- }
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping %d freq band\n", j_bandcheck[i].freqbandbit);
-
- return skipband;
+ if (regdmn == NO_ENUMRD)
+ return NULL;
+ for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
+ if (regDomainPairs[i].regDmnEnum == regdmn)
+ return &regDomainPairs[i];
+ }
+ return NULL;
}
-bool
-ath9k_regd_init_channels(struct ath_hal *ah,
- u32 maxchans,
- u32 *nchans, u8 *regclassids,
- u32 maxregids, u32 *nregids, u16 cc,
- bool enableOutdoor,
- bool enableExtendedChannels)
+int ath9k_regd_init(struct ath_hw *ah)
{
- u16 maxChan = 7000;
struct country_code_to_enum_rd *country = NULL;
- struct regDomain rd5GHz, rd2GHz;
- const struct cmode *cm;
- struct ath9k_channel *ichans = &ah->ah_channels[0];
- int next = 0, b;
- u8 ctl;
- int regdmn;
- u16 chanSep;
- unsigned long *modes_avail;
- DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX);
-
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc,
- enableOutdoor ? "Enable outdoor" : "",
- enableExtendedChannels ? "Enable ecm" : "");
-
- if (!ath9k_regd_is_ccode_valid(ah, cc)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Invalid country code %d\n", cc);
- return false;
- }
+ u16 regdmn;
if (!ath9k_regd_is_eeprom_valid(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Invalid EEPROM contents\n");
- return false;
+ return -EINVAL;
}
- ah->ah_countryCode = ath9k_regd_get_default_country(ah);
+ regdmn = ath9k_regd_get_eepromRD(ah);
+ ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn);
- if (ah->ah_countryCode == CTRY_DEFAULT) {
- ah->ah_countryCode = cc & COUNTRY_CODE_MASK;
- if ((ah->ah_countryCode == CTRY_DEFAULT) &&
- (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) {
- ah->ah_countryCode = CTRY_UNITED_STATES;
- }
- }
+ if (ah->regulatory.country_code == CTRY_DEFAULT &&
+ regdmn == CTRY_DEFAULT)
+ ah->regulatory.country_code = CTRY_UNITED_STATES;
-#ifdef AH_SUPPORT_11D
- if (ah->ah_countryCode == CTRY_DEFAULT) {
- regdmn = ath9k_regd_get_eepromRD(ah);
+ if (ah->regulatory.country_code == CTRY_DEFAULT) {
country = NULL;
} else {
-#endif
- country = ath9k_regd_find_country(ah->ah_countryCode);
+ country = ath9k_regd_find_country(ah->regulatory.country_code);
if (country == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Country is NULL!!!!, cc= %d\n",
- ah->ah_countryCode);
- return false;
- } else {
+ ah->regulatory.country_code);
+ return -EINVAL;
+ } else
regdmn = country->regDmnEnum;
-#ifdef AH_SUPPORT_11D
- if (((ath9k_regd_get_eepromRD(ah) &
- WORLD_SKU_MASK) == WORLD_SKU_PREFIX) &&
- (cc == CTRY_UNITED_STATES)) {
- if (!isWwrSKU_NoMidband(ah)
- && ath9k_regd_is_fcc_midband_supported(ah))
- regdmn = FCC3_FCCA;
- else
- regdmn = FCC1_FCCA;
- }
-#endif
- }
-#ifdef AH_SUPPORT_11D
- }
-#endif
- if (!ath9k_regd_get_wmode_regdomain(ah,
- regdmn,
- ~CHANNEL_2GHZ,
- &rd5GHz)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Couldn't find unitary "
- "5GHz reg domain for country %u\n",
- ah->ah_countryCode);
- return false;
- }
- if (!ath9k_regd_get_wmode_regdomain(ah,
- regdmn,
- CHANNEL_2GHZ,
- &rd2GHz)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Couldn't find unitary 2GHz "
- "reg domain for country %u\n",
- ah->ah_countryCode);
- return false;
- }
-
- if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) ||
- (rd5GHz.regDmnEnum == FCC2))) {
- if (ath9k_regd_is_fcc_midband_supported(ah)) {
- if (!ath9k_regd_get_wmode_regdomain(ah,
- FCC3_FCCA,
- ~CHANNEL_2GHZ,
- &rd5GHz)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Couldn't find unitary 5GHz "
- "reg domain for country %u\n",
- ah->ah_countryCode);
- return false;
- }
- }
- }
-
- if (country == NULL) {
- modes_avail = ah->ah_caps.wireless_modes;
- } else {
- ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed);
- modes_avail = modes_allowed;
-
- if (!enableOutdoor)
- maxChan = country->outdoorChanStart;
- }
-
- next = 0;
-
- if (maxchans > ARRAY_SIZE(ah->ah_channels))
- maxchans = ARRAY_SIZE(ah->ah_channels);
-
- for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) {
- u16 c, c_hi, c_lo;
- u64 *channelBM = NULL;
- struct regDomain *rd = NULL;
- struct RegDmnFreqBand *fband = NULL, *freqs;
- int8_t low_adj = 0, hi_adj = 0;
-
- if (!test_bit(cm->mode, modes_avail)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "!avail mode %d flags 0x%x\n",
- cm->mode, cm->flags);
- continue;
- }
- if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "channels 0x%x not supported "
- "by hardware\n", cm->flags);
- continue;
- }
-
- switch (cm->mode) {
- case ATH9K_MODE_11A:
- case ATH9K_MODE_11NA_HT20:
- case ATH9K_MODE_11NA_HT40PLUS:
- case ATH9K_MODE_11NA_HT40MINUS:
- rd = &rd5GHz;
- channelBM = rd->chan11a;
- freqs = &regDmn5GhzFreq[0];
- ctl = rd->conformanceTestLimit;
- break;
- case ATH9K_MODE_11B:
- rd = &rd2GHz;
- channelBM = rd->chan11b;
- freqs = &regDmn2GhzFreq[0];
- ctl = rd->conformanceTestLimit | CTL_11B;
- break;
- case ATH9K_MODE_11G:
- case ATH9K_MODE_11NG_HT20:
- case ATH9K_MODE_11NG_HT40PLUS:
- case ATH9K_MODE_11NG_HT40MINUS:
- rd = &rd2GHz;
- channelBM = rd->chan11g;
- freqs = &regDmn2Ghz11gFreq[0];
- ctl = rd->conformanceTestLimit | CTL_11G;
- break;
- default:
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Unknown HAL mode 0x%x\n", cm->mode);
- continue;
- }
-
- if (ath9k_regd_is_chan_bm_zero(channelBM))
- continue;
-
- if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
- (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) {
- hi_adj = -20;
- }
-
- if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) ||
- (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) {
- low_adj = 20;
- }
-
- /* XXX: Add a helper here instead */
- for (b = 0; b < 64 * BMLEN; b++) {
- if (ath9k_regd_is_bit_set(b, channelBM)) {
- fband = &freqs[b];
- if (rd5GHz.regDmnEnum == MKK1
- || rd5GHz.regDmnEnum == MKK2) {
- if (ath9k_regd_japan_check(ah,
- b,
- &rd5GHz))
- continue;
- }
-
- ath9k_regd_add_reg_classid(regclassids,
- maxregids,
- nregids,
- fband->
- regClassId);
-
- if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) {
- chanSep = 40;
- if (fband->lowChannel == 5280)
- low_adj += 20;
-
- if (fband->lowChannel == 5170)
- continue;
- } else
- chanSep = fband->channelSep;
-
- for (c = fband->lowChannel + low_adj;
- ((c <= (fband->highChannel + hi_adj)) &&
- (c >= (fband->lowChannel + low_adj)));
- c += chanSep) {
- if (next >= maxchans) {
- DPRINTF(ah->ah_sc,
- ATH_DBG_REGULATORY,
- "too many channels "
- "for channel table\n");
- goto done;
- }
- if (ath9k_regd_add_channel(ah,
- c, c_lo, c_hi,
- maxChan, ctl,
- next,
- rd5GHz,
- fband, rd, cm,
- ichans,
- enableExtendedChannels))
- next++;
- }
- if (IS_HT40_MODE(cm->mode) &&
- (fband->lowChannel == 5280)) {
- low_adj -= 20;
- }
- }
- }
}
-done:
- if (next != 0) {
- int i;
- if (next > ARRAY_SIZE(ah->ah_channels)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "too many channels %u; truncating to %u\n",
- next, (int) ARRAY_SIZE(ah->ah_channels));
- next = ARRAY_SIZE(ah->ah_channels);
- }
-#ifdef ATH_NF_PER_CHAN
- ath9k_regd_init_rf_buffer(ichans, next);
-#endif
- ath9k_regd_sort(ichans, next,
- sizeof(struct ath9k_channel),
- ath9k_regd_chansort);
+ ah->regulatory.regpair = ath9k_get_regpair(regdmn);
- ah->ah_nchan = next;
-
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n");
- for (i = 0; i < next; i++) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "chan: %d flags: 0x%x\n",
- ah->ah_channels[i].channel,
- ah->ah_channels[i].channelFlags);
- }
+ if (!ah->regulatory.regpair) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "No regulatory domain pair found, cannot continue\n");
+ return -EINVAL;
}
- *nchans = next;
- ah->ah_countryCode = ah->ah_countryCode;
+ if (!country)
+ country = ath9k_regd_find_country_by_rd(regdmn);
- ah->ah_currentRDInUse = regdmn;
- ah->ah_currentRD5G = rd5GHz.regDmnEnum;
- ah->ah_currentRD2G = rd2GHz.regDmnEnum;
- if (country == NULL) {
- ah->ah_iso[0] = 0;
- ah->ah_iso[1] = 0;
+ if (country) {
+ ah->regulatory.alpha2[0] = country->isoName[0];
+ ah->regulatory.alpha2[1] = country->isoName[1];
} else {
- ah->ah_iso[0] = country->isoName[0];
- ah->ah_iso[1] = country->isoName[1];
+ ah->regulatory.alpha2[0] = '0';
+ ah->regulatory.alpha2[1] = '0';
}
- return next != 0;
-}
-
-struct ath9k_channel*
-ath9k_regd_check_channel(struct ath_hal *ah,
- const struct ath9k_channel *c)
-{
- struct ath9k_channel *base, *cc;
-
- int flags = c->channelFlags & CHAN_FLAGS;
- int n, lim;
-
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "channel %u/0x%x (0x%x) requested\n",
- c->channel, c->channelFlags, flags);
-
- cc = ah->ah_curchan;
- if (cc != NULL && cc->channel == c->channel &&
- (cc->channelFlags & CHAN_FLAGS) == flags) {
- if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
- (cc->privFlags & CHANNEL_DFS))
- return NULL;
- else
- return cc;
- }
+ "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);
- base = ah->ah_channels;
- n = ah->ah_nchan;
-
- for (lim = n; lim != 0; lim >>= 1) {
- int d;
- cc = &base[lim >> 1];
- d = c->channel - cc->channel;
- if (d == 0) {
- if ((cc->channelFlags & CHAN_FLAGS) == flags) {
- if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
- (cc->privFlags & CHANNEL_DFS))
- return NULL;
- else
- return cc;
- }
- d = flags - (cc->channelFlags & CHAN_FLAGS);
- }
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "channel %u/0x%x d %d\n",
- cc->channel, cc->channelFlags, d);
- if (d > 0) {
- base = cc + 1;
- lim--;
- }
- }
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n",
- c->channel, c->channelFlags);
- return NULL;
-}
-
-u32
-ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
- struct ath9k_channel *chan)
-{
- struct ath9k_channel *ichan = NULL;
-
- ichan = ath9k_regd_check_channel(ah, chan);
- if (!ichan)
- return 0;
-
- return ichan->antennaMax;
+ return 0;
}
-u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan)
+u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
{
u32 ctl = NO_CTL;
- struct ath9k_channel *ichan;
- if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
+ 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;
- } else {
- ichan = ath9k_regd_check_channel(ah, chan);
- if (ichan != NULL) {
- /* FIXME */
- if (IS_CHAN_A(ichan))
- ctl = ichan->conformanceTestLimit[0];
- else if (IS_CHAN_B(ichan))
- ctl = ichan->conformanceTestLimit[1];
- else if (IS_CHAN_G(ichan))
- ctl = ichan->conformanceTestLimit[2];
-
- if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B)
- ctl = (ctl & ~0xf) | CTL_11G;
- }
+ return ctl;
}
- return ctl;
-}
-void ath9k_regd_get_current_country(struct ath_hal *ah,
- struct ath9k_country_entry *ctry)
-{
- u16 rd = ath9k_regd_get_eepromRD(ah);
+ 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;
- ctry->isMultidomain = false;
- if (rd == CTRY_DEFAULT)
- ctry->isMultidomain = true;
- else if (!(rd & COUNTRY_ERD_FLAG))
- ctry->isMultidomain = isWwrSKU(ah);
-
- ctry->countryCode = ah->ah_countryCode;
- ctry->regDmnEnum = ah->ah_currentRD;
- ctry->regDmn5G = ah->ah_currentRD5G;
- ctry->regDmn2G = ah->ah_currentRD2G;
- ctry->iso[0] = ah->ah_iso[0];
- ctry->iso[1] = ah->ah_iso[1];
- ctry->iso[2] = ah->ah_iso[2];
+ return ctl;
}
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
index 512d990aa7e..8f885f3bc8d 100644
--- a/drivers/net/wireless/ath9k/regd.h
+++ b/drivers/net/wireless/ath9k/regd.h
@@ -17,127 +17,8 @@
#ifndef REGD_H
#define REGD_H
-#include "ath9k.h"
-
-#define BMLEN 2
-#define BMZERO {(u64) 0, (u64) 0}
-
-#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
- {((((_fa >= 0) && (_fa < 64)) ? \
- (((u64) 1) << _fa) : (u64) 0) | \
- (((_fb >= 0) && (_fb < 64)) ? \
- (((u64) 1) << _fb) : (u64) 0) | \
- (((_fc >= 0) && (_fc < 64)) ? \
- (((u64) 1) << _fc) : (u64) 0) | \
- (((_fd >= 0) && (_fd < 64)) ? \
- (((u64) 1) << _fd) : (u64) 0) | \
- (((_fe >= 0) && (_fe < 64)) ? \
- (((u64) 1) << _fe) : (u64) 0) | \
- (((_ff >= 0) && (_ff < 64)) ? \
- (((u64) 1) << _ff) : (u64) 0) | \
- (((_fg >= 0) && (_fg < 64)) ? \
- (((u64) 1) << _fg) : (u64) 0) | \
- (((_fh >= 0) && (_fh < 64)) ? \
- (((u64) 1) << _fh) : (u64) 0) | \
- (((_fi >= 0) && (_fi < 64)) ? \
- (((u64) 1) << _fi) : (u64) 0) | \
- (((_fj >= 0) && (_fj < 64)) ? \
- (((u64) 1) << _fj) : (u64) 0) | \
- (((_fk >= 0) && (_fk < 64)) ? \
- (((u64) 1) << _fk) : (u64) 0) | \
- (((_fl >= 0) && (_fl < 64)) ? \
- (((u64) 1) << _fl) : (u64) 0) | \
- ((((_fa > 63) && (_fa < 128)) ? \
- (((u64) 1) << (_fa - 64)) : (u64) 0) | \
- (((_fb > 63) && (_fb < 128)) ? \
- (((u64) 1) << (_fb - 64)) : (u64) 0) | \
- (((_fc > 63) && (_fc < 128)) ? \
- (((u64) 1) << (_fc - 64)) : (u64) 0) | \
- (((_fd > 63) && (_fd < 128)) ? \
- (((u64) 1) << (_fd - 64)) : (u64) 0) | \
- (((_fe > 63) && (_fe < 128)) ? \
- (((u64) 1) << (_fe - 64)) : (u64) 0) | \
- (((_ff > 63) && (_ff < 128)) ? \
- (((u64) 1) << (_ff - 64)) : (u64) 0) | \
- (((_fg > 63) && (_fg < 128)) ? \
- (((u64) 1) << (_fg - 64)) : (u64) 0) | \
- (((_fh > 63) && (_fh < 128)) ? \
- (((u64) 1) << (_fh - 64)) : (u64) 0) | \
- (((_fi > 63) && (_fi < 128)) ? \
- (((u64) 1) << (_fi - 64)) : (u64) 0) | \
- (((_fj > 63) && (_fj < 128)) ? \
- (((u64) 1) << (_fj - 64)) : (u64) 0) | \
- (((_fk > 63) && (_fk < 128)) ? \
- (((u64) 1) << (_fk - 64)) : (u64) 0) | \
- (((_fl > 63) && (_fl < 128)) ? \
- (((u64) 1) << (_fl - 64)) : (u64) 0)))}
-
-#define DEF_REGDMN FCC1_FCCA
-#define DEF_DMN_5 FCC1
-#define DEF_DMN_2 FCCA
#define COUNTRY_ERD_FLAG 0x8000
#define WORLDWIDE_ROAMING_FLAG 0x4000
-#define SUPER_DOMAIN_MASK 0x0fff
-#define COUNTRY_CODE_MASK 0x3fff
-#define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT)
-#define CHANNEL_14 (2484)
-#define IS_11G_CH14(_ch,_cf) \
- (((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G))
-
-#define NO_PSCAN 0x0ULL
-#define PSCAN_FCC 0x0000000000000001ULL
-#define PSCAN_FCC_T 0x0000000000000002ULL
-#define PSCAN_ETSI 0x0000000000000004ULL
-#define PSCAN_MKK1 0x0000000000000008ULL
-#define PSCAN_MKK2 0x0000000000000010ULL
-#define PSCAN_MKKA 0x0000000000000020ULL
-#define PSCAN_MKKA_G 0x0000000000000040ULL
-#define PSCAN_ETSIA 0x0000000000000080ULL
-#define PSCAN_ETSIB 0x0000000000000100ULL
-#define PSCAN_ETSIC 0x0000000000000200ULL
-#define PSCAN_WWR 0x0000000000000400ULL
-#define PSCAN_MKKA1 0x0000000000000800ULL
-#define PSCAN_MKKA1_G 0x0000000000001000ULL
-#define PSCAN_MKKA2 0x0000000000002000ULL
-#define PSCAN_MKKA2_G 0x0000000000004000ULL
-#define PSCAN_MKK3 0x0000000000008000ULL
-#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
-#define IS_ECM_CHAN 0x8000000000000000ULL
-
-#define isWwrSKU(_ah) \
- (((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \
- WORLD_SKU_PREFIX) || \
- (ath9k_regd_get_eepromRD(_ah) == WORLD))
-
-#define isWwrSKU_NoMidband(_ah) \
- ((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \
- (ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \
- (ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC))
-
-#define isUNII1OddChan(ch) \
- ((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
-
-#define IS_HT40_MODE(_mode) \
- (((_mode == ATH9K_MODE_11NA_HT40PLUS || \
- _mode == ATH9K_MODE_11NG_HT40PLUS || \
- _mode == ATH9K_MODE_11NA_HT40MINUS || \
- _mode == ATH9K_MODE_11NG_HT40MINUS) ? true : false))
-
-#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
-
-#define swap_array(_a, _b, _size) { \
- u8 *s = _b; \
- int i = _size; \
- do { \
- u8 tmp = *_a; \
- *_a++ = *s; \
- *s++ = tmp; \
- } while (--i); \
- _a -= _size; \
-}
-
-
-#define HALF_MAXCHANBW 10
#define MULTI_DOMAIN_MASK 0xFF00
@@ -147,81 +28,27 @@
#define CHANNEL_HALF_BW 10
#define CHANNEL_QUARTER_BW 5
-typedef int ath_hal_cmp_t(const void *, const void *);
-
struct reg_dmn_pair_mapping {
u16 regDmnEnum;
- u16 regDmn5GHz;
- u16 regDmn2GHz;
- u32 flags5GHz;
- u32 flags2GHz;
- u64 pscanMask;
- u16 singleCC;
-};
-
-struct ccmap {
- char isoName[3];
- u16 countryCode;
+ u16 reg_5ghz_ctl;
+ u16 reg_2ghz_ctl;
};
struct country_code_to_enum_rd {
u16 countryCode;
u16 regDmnEnum;
const char *isoName;
- const char *name;
- bool allow11g;
- bool allow11aTurbo;
- bool allow11gTurbo;
- bool allow11ng20;
- bool allow11ng40;
- bool allow11na20;
- bool allow11na40;
- u16 outdoorChanStart;
-};
-
-struct RegDmnFreqBand {
- u16 lowChannel;
- u16 highChannel;
- u8 powerDfs;
- u8 antennaMax;
- u8 channelBW;
- u8 channelSep;
- u64 useDfs;
- u64 usePassScan;
- u8 regClassId;
-};
-
-struct regDomain {
- u16 regDmnEnum;
- u8 conformanceTestLimit;
- u64 dfsMask;
- u64 pscan;
- u32 flags;
- u64 chan11a[BMLEN];
- u64 chan11a_turbo[BMLEN];
- u64 chan11a_dyn_turbo[BMLEN];
- u64 chan11b[BMLEN];
- u64 chan11g[BMLEN];
- u64 chan11g_turbo[BMLEN];
-};
-
-struct cmode {
- u32 mode;
- u32 flags;
-};
-
-#define YES true
-#define NO false
-
-struct japan_bandcheck {
- u16 freqbandbit;
- u32 eepromflagtocheck;
};
-struct common_mode_power {
- u16 lchan;
- u16 hchan;
- u8 pwrlvl;
+struct ath9k_regulatory {
+ char alpha2[2];
+ u16 country_code;
+ u16 max_power_level;
+ u32 tp_scale;
+ u16 current_rd;
+ u16 current_rd_ext;
+ int16_t power_limit;
+ struct reg_dmn_pair_mapping *regpair;
};
enum CountryCode {
@@ -406,7 +233,15 @@ enum CountryCode {
CTRY_BELGIUM2 = 5002
};
-void ath9k_regd_get_current_country(struct ath_hal *ah,
- struct ath9k_country_entry *ctry);
+bool ath9k_is_world_regd(struct ath_hw *ah);
+const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
+const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
+void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator);
+void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
+int ath9k_regd_init(struct ath_hw *ah);
+bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);
+u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan);
+int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
#endif
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h
index 9112c030b1e..b41d0002f3f 100644
--- a/drivers/net/wireless/ath9k/regd_common.h
+++ b/drivers/net/wireless/ath9k/regd_common.h
@@ -150,1766 +150,324 @@ enum EnumRd {
MKK9_MKKC = 0xFE,
MKK9_MKKA2 = 0xFF,
- APL1 = 0x0150,
- APL2 = 0x0250,
- APL3 = 0x0350,
- APL4 = 0x0450,
- APL5 = 0x0550,
- APL6 = 0x0650,
- APL7 = 0x0750,
- APL8 = 0x0850,
- APL9 = 0x0950,
- APL10 = 0x1050,
-
- ETSI1 = 0x0130,
- ETSI2 = 0x0230,
- ETSI3 = 0x0330,
- ETSI4 = 0x0430,
- ETSI5 = 0x0530,
- ETSI6 = 0x0630,
- ETSIA = 0x0A30,
- ETSIB = 0x0B30,
- ETSIC = 0x0C30,
-
- FCC1 = 0x0110,
- FCC2 = 0x0120,
- FCC3 = 0x0160,
- FCC4 = 0x0165,
- FCC5 = 0x0510,
- FCC6 = 0x0610,
- FCCA = 0x0A10,
-
- APLD = 0x0D50,
-
- MKK1 = 0x0140,
- MKK2 = 0x0240,
- MKK3 = 0x0340,
- MKK4 = 0x0440,
- MKK5 = 0x0540,
- MKK6 = 0x0640,
- MKK7 = 0x0740,
- MKK8 = 0x0840,
- MKK9 = 0x0940,
- MKK10 = 0x0B40,
- MKK11 = 0x1140,
- MKK12 = 0x1240,
- MKK13 = 0x0C40,
- MKK14 = 0x1440,
- MKK15 = 0x1540,
- MKKA = 0x0A40,
- MKKC = 0x0A50,
-
- NULL1 = 0x0198,
WORLD = 0x0199,
DEBUG_REG_DMN = 0x01ff,
};
-enum {
- FCC = 0x10,
- MKK = 0x40,
- ETSI = 0x30,
-};
-
-enum {
- NO_REQ = 0x00000000,
- DISALLOW_ADHOC_11A = 0x00000001,
- DISALLOW_ADHOC_11A_TURB = 0x00000002,
- NEED_NFC = 0x00000004,
-
- ADHOC_PER_11D = 0x00000008,
- ADHOC_NO_11A = 0x00000010,
-
- PUBLIC_SAFETY_DOMAIN = 0x00000020,
- LIMIT_FRAME_4MS = 0x00000040,
-
- NO_HOSTAP = 0x00000080,
-
- REQ_MASK = 0x000000FF,
+enum ctl_group {
+ CTL_FCC = 0x10,
+ CTL_MKK = 0x40,
+ CTL_ETSI = 0x30,
};
-#define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \
- (!(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
-#define REG_DOMAIN_5GHZ_MASK REQ_MASK
-
+/* Regpair to CTL band mapping */
static struct reg_dmn_pair_mapping regDomainPairs[] = {
- {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ,
- PSCAN_DEFER, 0},
- {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
- {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC4_FCCA, FCC4, FCCA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
- {ETSI1_WORLD, ETSI1, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI2_WORLD, ETSI2, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI3_WORLD, ETSI3, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI4_WORLD, ETSI4, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI5_WORLD, ETSI5, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI6_WORLD, ETSI6, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
-
- {ETSI3_ETSIA, ETSI3, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
- {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
- {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER,},
-
- {MKK1_MKKA, MKK1, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN},
- {MKK1_MKKB, MKK1, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN1},
- {MKK1_FCCA, MKK1, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1, CTRY_JAPAN2},
- {MKK1_MKKA1, MKK1, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4},
- {MKK1_MKKA2, MKK1, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5},
- {MKK1_MKKC, MKK1, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1, CTRY_JAPAN6},
-
- {MKK2_MKKA, MKK2, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN3},
-
- {MKK3_MKKA, MKK3, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA, CTRY_JAPAN25},
- {MKK3_MKKB, MKK3, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN7},
- {MKK3_MKKA1, MKK3, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26},
- {MKK3_MKKA2, MKK3, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8},
- {MKK3_MKKC, MKK3, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN9},
- {MKK3_FCCA, MKK3, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN27},
-
- {MKK4_MKKA, MKK4, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN36},
- {MKK4_MKKB, MKK4, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN10},
- {MKK4_MKKA1, MKK4, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28},
- {MKK4_MKKA2, MKK4, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11},
- {MKK4_MKKC, MKK4, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN12},
- {MKK4_FCCA, MKK4, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN29},
-
- {MKK5_MKKB, MKK5, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN13},
- {MKK5_MKKA2, MKK5, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14},
- {MKK5_MKKC, MKK5, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN15},
-
- {MKK6_MKKB, MKK6, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16},
- {MKK6_MKKA1, MKK6, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30},
- {MKK6_MKKA2, MKK6, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17},
- {MKK6_MKKC, MKK6, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1, CTRY_JAPAN18},
- {MKK6_FCCA, MKK6, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN31},
-
- {MKK7_MKKB, MKK7, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN19},
- {MKK7_MKKA1, MKK7, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32},
- {MKK7_MKKA2, MKK7, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
- CTRY_JAPAN20},
- {MKK7_MKKC, MKK7, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21},
- {MKK7_FCCA, MKK7, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33},
-
- {MKK8_MKKB, MKK8, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN22},
- {MKK8_MKKA2, MKK8, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
- CTRY_JAPAN23},
- {MKK8_MKKC, MKK8, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN24},
-
- {MKK9_MKKA, MKK9, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK2 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN34},
- {MKK9_FCCA, MKK9, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN37},
- {MKK9_MKKA1, MKK9, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38},
- {MKK9_MKKA2, MKK9, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40},
- {MKK9_MKKC, MKK9, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN39},
-
- {MKK10_MKKA, MKK10, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKK3, CTRY_JAPAN35},
- {MKK10_FCCA, MKK10, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN41},
- {MKK10_MKKA1, MKK10, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42},
- {MKK10_MKKA2, MKK10, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44},
- {MKK10_MKKC, MKK10, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN43},
-
- {MKK11_MKKA, MKK11, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN45},
- {MKK11_FCCA, MKK11, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN46},
- {MKK11_MKKA1, MKK11, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47},
- {MKK11_MKKA2, MKK11, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49},
- {MKK11_MKKC, MKK11, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN48},
-
- {MKK12_MKKA, MKK12, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50},
- {MKK12_FCCA, MKK12, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51},
- {MKK12_MKKA1, MKK12, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G,
- CTRY_JAPAN52},
- {MKK12_MKKA2, MKK12, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
- CTRY_JAPAN54},
- {MKK12_MKKC, MKK12, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53},
-
- {MKK13_MKKB, MKK13, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN57},
-
- {MKK14_MKKA1, MKK14, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58},
- {MKK15_MKKA1, MKK15, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59},
-
- {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB,
- NO_REQ, PSCAN_DEFER, 0},
- {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ,
- PSCAN_DEFER, 0},
- {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ,
- PSCAN_DEFER, 0},
- {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WORA_WORLD, WORA_WORLD, WORA_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WORB_WORLD, WORB_WORLD, WORB_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
+ /* regpair, 5 GHz CTL, 2 GHz CTL */
+ {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN},
+ {NULL1_WORLD, NO_CTL, CTL_ETSI},
+ {NULL1_ETSIB, NO_CTL, CTL_ETSI},
+ {NULL1_ETSIC, NO_CTL, CTL_ETSI},
+
+ {FCC2_FCCA, CTL_FCC, CTL_FCC},
+ {FCC2_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC2_ETSIC, CTL_FCC, CTL_ETSI},
+ {FCC3_FCCA, CTL_FCC, CTL_FCC},
+ {FCC3_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC4_FCCA, CTL_FCC, CTL_FCC},
+ {FCC5_FCCA, CTL_FCC, CTL_FCC},
+ {FCC6_FCCA, CTL_FCC, CTL_FCC},
+ {FCC6_WORLD, CTL_FCC, CTL_ETSI},
+
+ {ETSI1_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI2_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI3_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
+
+ /* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
+ {ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
+ {FRANCE_RES, CTL_ETSI, CTL_ETSI},
+
+ {FCC1_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC1_FCCA, CTL_FCC, CTL_FCC},
+ {APL1_WORLD, CTL_FCC, CTL_ETSI},
+ {APL2_WORLD, CTL_FCC, CTL_ETSI},
+ {APL3_WORLD, CTL_FCC, CTL_ETSI},
+ {APL4_WORLD, CTL_FCC, CTL_ETSI},
+ {APL5_WORLD, CTL_FCC, CTL_ETSI},
+ {APL6_WORLD, CTL_ETSI, CTL_ETSI},
+ {APL8_WORLD, CTL_ETSI, CTL_ETSI},
+ {APL9_WORLD, CTL_ETSI, CTL_ETSI},
+
+ {APL3_FCCA, CTL_FCC, CTL_FCC},
+ {APL1_ETSIC, CTL_FCC, CTL_ETSI},
+ {APL2_ETSIC, CTL_FCC, CTL_ETSI},
+ {APL2_APLD, CTL_FCC, NO_CTL},
+
+ {MKK1_MKKA, CTL_MKK, CTL_MKK},
+ {MKK1_MKKB, CTL_MKK, CTL_MKK},
+ {MKK1_FCCA, CTL_MKK, CTL_FCC},
+ {MKK1_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK1_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK1_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK2_MKKA, CTL_MKK, CTL_MKK},
+ {MKK3_MKKA, CTL_MKK, CTL_MKK},
+ {MKK3_MKKB, CTL_MKK, CTL_MKK},
+ {MKK3_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK3_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK3_MKKC, CTL_MKK, CTL_MKK},
+ {MKK3_FCCA, CTL_MKK, CTL_FCC},
+
+ {MKK4_MKKA, CTL_MKK, CTL_MKK},
+ {MKK4_MKKB, CTL_MKK, CTL_MKK},
+ {MKK4_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK4_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK4_MKKC, CTL_MKK, CTL_MKK},
+ {MKK4_FCCA, CTL_MKK, CTL_FCC},
+
+ {MKK5_MKKB, CTL_MKK, CTL_MKK},
+ {MKK5_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK5_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK6_MKKB, CTL_MKK, CTL_MKK},
+ {MKK6_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK6_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK6_MKKC, CTL_MKK, CTL_MKK},
+ {MKK6_FCCA, CTL_MKK, CTL_FCC},
+
+ {MKK7_MKKB, CTL_MKK, CTL_MKK},
+ {MKK7_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK7_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK7_MKKC, CTL_MKK, CTL_MKK},
+ {MKK7_FCCA, CTL_MKK, CTL_FCC},
+
+ {MKK8_MKKB, CTL_MKK, CTL_MKK},
+ {MKK8_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK8_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK9_MKKA, CTL_MKK, CTL_MKK},
+ {MKK9_FCCA, CTL_MKK, CTL_FCC},
+ {MKK9_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK9_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK9_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK10_MKKA, CTL_MKK, CTL_MKK},
+ {MKK10_FCCA, CTL_MKK, CTL_FCC},
+ {MKK10_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK10_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK10_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK11_MKKA, CTL_MKK, CTL_MKK},
+ {MKK11_FCCA, CTL_MKK, CTL_FCC},
+ {MKK11_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK11_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK11_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK12_MKKA, CTL_MKK, CTL_MKK},
+ {MKK12_FCCA, CTL_MKK, CTL_FCC},
+ {MKK12_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK12_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK12_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK13_MKKB, CTL_MKK, CTL_MKK},
+ {MKK14_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK15_MKKA1, CTL_MKK, CTL_MKK},
+
+ {WOR0_WORLD, NO_CTL, NO_CTL},
+ {WOR1_WORLD, NO_CTL, NO_CTL},
+ {WOR2_WORLD, NO_CTL, NO_CTL},
+ {WOR3_WORLD, NO_CTL, NO_CTL},
+ {WOR4_WORLD, NO_CTL, NO_CTL},
+ {WOR5_ETSIC, NO_CTL, NO_CTL},
+ {WOR01_WORLD, NO_CTL, NO_CTL},
+ {WOR02_WORLD, NO_CTL, NO_CTL},
+ {EU1_WORLD, NO_CTL, NO_CTL},
+ {WOR9_WORLD, NO_CTL, NO_CTL},
+ {WORA_WORLD, NO_CTL, NO_CTL},
+ {WORB_WORLD, NO_CTL, NO_CTL},
};
-#define NO_INTERSECT_REQ 0xFFFFFFFF
-#define NO_UNION_REQ 0
-
static struct country_code_to_enum_rd allCountries[] = {
- {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, NO,
- NO, NO, 7000},
- {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, NO,
- NO, NO, 7000},
- {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES,
- NO, YES, NO, 7000},
- {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_BELGIUM2, ETSI4_WORLD, "BL", "BELGIUM", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA_HERZGOWINA", YES, NO,
- YES, YES, YES, YES, NO, 7000},
- {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, NO,
- YES, NO, 7000},
- {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM",
- YES, YES, YES, YES, YES, YES, YES, 7000},
- {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_CANADA, FCC2_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES,
- YES, YES, YES, NO, 7000},
- {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC",
- YES, YES, YES, YES, YES, YES, YES, 7000},
- {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES,
- YES, NO, 7000},
- {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES,
- YES, YES, YES, NO, 7000},
- {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES,
- YES, 7000},
- {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
-
- {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES,
- YES, 7000},
- {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES,
- YES, YES, NO, NO, 7000},
- {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO,
- YES, YES, YES, YES, 7000},
- {CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO,
- YES, NO, YES, NO, 7000},
- {CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2", YES, NO, NO,
- YES, NO, YES, NO, 7000},
- {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO,
- YES, NO, YES, NO, 7000},
- {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO,
- YES, YES, YES, YES, YES, 7000},
- {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, NO,
- YES, NO, 7000},
- {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN",
- "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, YES, YES, 7000},
- {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES,
- YES, YES, YES, NO, 7000},
- {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES,
- NO, 7000},
- {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES,
- YES, YES, YES, YES, YES, YES, 7000},
- {CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES,
- NO, 7000},
- {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO,
- YES, YES, YES, NO, NO, 7000},
- {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO",
- YES, NO, YES, YES, YES, YES, YES, 7000},
- {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES,
- YES, YES, YES, NO, 7000},
- {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO",
- YES, NO, YES, YES, YES, YES, NO, 7000},
- {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES,
- YES, YES, NO, NO, 7000},
- {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO,
- YES, YES, YES, YES, YES, 7000},
- {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES,
- YES, YES, YES, YES, YES, 5825},
- {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS",
- "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES,
- YES, 7000},
- {CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES,
- YES, NO, NO, 7000}
-};
-
-enum {
- NO_DFS = 0x0000000000000000ULL,
- DFS_FCC3 = 0x0000000000000001ULL,
- DFS_ETSI = 0x0000000000000002ULL,
- DFS_MKK4 = 0x0000000000000004ULL,
-};
-
-enum {
- F1_4915_4925,
- F1_4935_4945,
- F1_4920_4980,
- F1_4942_4987,
- F1_4945_4985,
- F1_4950_4980,
- F1_5035_5040,
- F1_5040_5080,
- F1_5055_5055,
-
- F1_5120_5240,
-
- F1_5170_5230,
- F2_5170_5230,
-
- F1_5180_5240,
- F2_5180_5240,
- F3_5180_5240,
- F4_5180_5240,
- F5_5180_5240,
- F6_5180_5240,
- F7_5180_5240,
- F8_5180_5240,
-
- F1_5180_5320,
-
- F1_5240_5280,
-
- F1_5260_5280,
-
- F1_5260_5320,
- F2_5260_5320,
- F3_5260_5320,
- F4_5260_5320,
- F5_5260_5320,
- F6_5260_5320,
-
- F1_5260_5700,
-
- F1_5280_5320,
-
- F1_5500_5580,
-
- F1_5500_5620,
-
- F1_5500_5700,
- F2_5500_5700,
- F3_5500_5700,
- F4_5500_5700,
- F5_5500_5700,
-
- F1_5660_5700,
-
- F1_5745_5805,
- F2_5745_5805,
- F3_5745_5805,
-
- F1_5745_5825,
- F2_5745_5825,
- F3_5745_5825,
- F4_5745_5825,
- F5_5745_5825,
- F6_5745_5825,
-
- W1_4920_4980,
- W1_5040_5080,
- W1_5170_5230,
- W1_5180_5240,
- W1_5260_5320,
- W1_5745_5825,
- W1_5500_5700,
- A_DEMO_ALL_CHANNELS
-};
-
-static struct RegDmnFreqBand regDmn5GhzFreq[] = {
- {4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
- {4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
- {4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7},
- {4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0},
- {4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0},
- {4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0},
- {5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
- {5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2},
- {5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
-
- {5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
- {5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
- {5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
-
- {5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
- {5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1},
- {5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
- {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
- {5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
- {5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0},
- {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0},
- {5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
- {5180, 5320, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
-
- {5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0},
-
- {5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 0},
-
- {5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 0},
-
- {5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
- PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3, 0},
-
-
- {5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 2},
- {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2},
- {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
- {5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
-
- {5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0},
-
- {5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
-
- {5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
-
- {5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
-
- {5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4},
- {5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 0},
- {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 0},
- {5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
- PSCAN_MKK3 | PSCAN_FCC, 0},
- {5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
-
- {5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
-
- {5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
- {5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3},
- {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
-
- {4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
- {5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
- {4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-};
-
-enum {
- T1_5130_5650,
- T1_5150_5670,
-
- T1_5200_5200,
- T2_5200_5200,
- T3_5200_5200,
- T4_5200_5200,
- T5_5200_5200,
- T6_5200_5200,
- T7_5200_5200,
- T8_5200_5200,
-
- T1_5200_5280,
- T2_5200_5280,
- T3_5200_5280,
- T4_5200_5280,
- T5_5200_5280,
- T6_5200_5280,
-
- T1_5200_5240,
- T1_5210_5210,
- T2_5210_5210,
- T3_5210_5210,
- T4_5210_5210,
- T5_5210_5210,
- T6_5210_5210,
- T7_5210_5210,
- T8_5210_5210,
- T9_5210_5210,
- T10_5210_5210,
- T1_5240_5240,
-
- T1_5210_5250,
- T1_5210_5290,
- T2_5210_5290,
- T3_5210_5290,
-
- T1_5280_5280,
- T2_5280_5280,
- T1_5290_5290,
- T2_5290_5290,
- T3_5290_5290,
- T1_5250_5290,
- T2_5250_5290,
- T3_5250_5290,
- T4_5250_5290,
-
- T1_5540_5660,
- T2_5540_5660,
- T3_5540_5660,
- T1_5760_5800,
- T2_5760_5800,
- T3_5760_5800,
- T4_5760_5800,
- T5_5760_5800,
- T6_5760_5800,
- T7_5760_5800,
-
- T1_5765_5805,
- T2_5765_5805,
- T3_5765_5805,
- T4_5765_5805,
- T5_5765_5805,
- T6_5765_5805,
- T7_5765_5805,
- T8_5765_5805,
- T9_5765_5805,
-
- WT1_5210_5250,
- WT1_5290_5290,
- WT1_5540_5660,
- WT1_5760_5800,
-};
-
-enum {
- F1_2312_2372,
- F2_2312_2372,
-
- F1_2412_2472,
- F2_2412_2472,
- F3_2412_2472,
-
- F1_2412_2462,
- F2_2412_2462,
-
- F1_2432_2442,
-
- F1_2457_2472,
-
- F1_2467_2472,
-
- F1_2484_2484,
- F2_2484_2484,
-
- F1_2512_2732,
-
- W1_2312_2372,
- W1_2412_2412,
- W1_2417_2432,
- W1_2437_2442,
- W1_2447_2457,
- W1_2462_2462,
- W1_2467_2467,
- W2_2467_2467,
- W1_2472_2472,
- W2_2472_2472,
- W1_2484_2484,
- W2_2484_2484,
-};
-
-static struct RegDmnFreqBand regDmn2GhzFreq[] = {
- {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
- {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
-
- {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
-
- {2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2484, 2484, 20, 0, 20, 5, NO_DFS,
- PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
-
- {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
- {2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
- {2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
- {2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
- {2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
- {2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
-};
-
-enum {
- G1_2312_2372,
- G2_2312_2372,
-
- G1_2412_2472,
- G2_2412_2472,
- G3_2412_2472,
-
- G1_2412_2462,
- G2_2412_2462,
-
- G1_2432_2442,
-
- G1_2457_2472,
-
- G1_2512_2732,
-
- G1_2467_2472,
-
- WG1_2312_2372,
- WG1_2412_2462,
- WG1_2467_2472,
- WG2_2467_2472,
- G_DEMO_ALL_CHANNELS
-};
-
-static struct RegDmnFreqBand regDmn2Ghz11gFreq[] = {
- {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
- {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
-
- {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
-
- {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
- {2467, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
- {2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-};
-
-enum {
- T1_2312_2372,
- T1_2437_2437,
- T2_2437_2437,
- T3_2437_2437,
- T1_2512_2732
+ {CTRY_DEBUG, NO_ENUMRD, "DB"},
+ {CTRY_DEFAULT, FCC1_FCCA, "CO"},
+ {CTRY_ALBANIA, NULL1_WORLD, "AL"},
+ {CTRY_ALGERIA, NULL1_WORLD, "DZ"},
+ {CTRY_ARGENTINA, APL3_WORLD, "AR"},
+ {CTRY_ARMENIA, ETSI4_WORLD, "AM"},
+ {CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
+ {CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
+ {CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
+ {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
+ {CTRY_BAHRAIN, APL6_WORLD, "BH"},
+ {CTRY_BELARUS, ETSI1_WORLD, "BY"},
+ {CTRY_BELGIUM, ETSI1_WORLD, "BE"},
+ {CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
+ {CTRY_BELIZE, APL1_ETSIC, "BZ"},
+ {CTRY_BOLIVIA, APL1_ETSIC, "BO"},
+ {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
+ {CTRY_BRAZIL, FCC3_WORLD, "BR"},
+ {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
+ {CTRY_BULGARIA, ETSI6_WORLD, "BG"},
+ {CTRY_CANADA, FCC2_FCCA, "CA"},
+ {CTRY_CANADA2, FCC6_FCCA, "CA"},
+ {CTRY_CHILE, APL6_WORLD, "CL"},
+ {CTRY_CHINA, APL1_WORLD, "CN"},
+ {CTRY_COLOMBIA, FCC1_FCCA, "CO"},
+ {CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
+ {CTRY_CROATIA, ETSI3_WORLD, "HR"},
+ {CTRY_CYPRUS, ETSI1_WORLD, "CY"},
+ {CTRY_CZECH, ETSI3_WORLD, "CZ"},
+ {CTRY_DENMARK, ETSI1_WORLD, "DK"},
+ {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
+ {CTRY_ECUADOR, FCC1_WORLD, "EC"},
+ {CTRY_EGYPT, ETSI3_WORLD, "EG"},
+ {CTRY_EL_SALVADOR, FCC1_WORLD, "SV"},
+ {CTRY_ESTONIA, ETSI1_WORLD, "EE"},
+ {CTRY_FINLAND, ETSI1_WORLD, "FI"},
+ {CTRY_FRANCE, ETSI1_WORLD, "FR"},
+ {CTRY_GEORGIA, ETSI4_WORLD, "GE"},
+ {CTRY_GERMANY, ETSI1_WORLD, "DE"},
+ {CTRY_GREECE, ETSI1_WORLD, "GR"},
+ {CTRY_GUATEMALA, FCC1_FCCA, "GT"},
+ {CTRY_HONDURAS, NULL1_WORLD, "HN"},
+ {CTRY_HONG_KONG, FCC2_WORLD, "HK"},
+ {CTRY_HUNGARY, ETSI1_WORLD, "HU"},
+ {CTRY_ICELAND, ETSI1_WORLD, "IS"},
+ {CTRY_INDIA, APL6_WORLD, "IN"},
+ {CTRY_INDONESIA, APL1_WORLD, "ID"},
+ {CTRY_IRAN, APL1_WORLD, "IR"},
+ {CTRY_IRELAND, ETSI1_WORLD, "IE"},
+ {CTRY_ISRAEL, NULL1_WORLD, "IL"},
+ {CTRY_ITALY, ETSI1_WORLD, "IT"},
+ {CTRY_JAMAICA, ETSI1_WORLD, "JM"},
+
+ {CTRY_JAPAN, MKK1_MKKA, "JP"},
+ {CTRY_JAPAN1, MKK1_MKKB, "JP"},
+ {CTRY_JAPAN2, MKK1_FCCA, "JP"},
+ {CTRY_JAPAN3, MKK2_MKKA, "JP"},
+ {CTRY_JAPAN4, MKK1_MKKA1, "JP"},
+ {CTRY_JAPAN5, MKK1_MKKA2, "JP"},
+ {CTRY_JAPAN6, MKK1_MKKC, "JP"},
+ {CTRY_JAPAN7, MKK3_MKKB, "JP"},
+ {CTRY_JAPAN8, MKK3_MKKA2, "JP"},
+ {CTRY_JAPAN9, MKK3_MKKC, "JP"},
+ {CTRY_JAPAN10, MKK4_MKKB, "JP"},
+ {CTRY_JAPAN11, MKK4_MKKA2, "JP"},
+ {CTRY_JAPAN12, MKK4_MKKC, "JP"},
+ {CTRY_JAPAN13, MKK5_MKKB, "JP"},
+ {CTRY_JAPAN14, MKK5_MKKA2, "JP"},
+ {CTRY_JAPAN15, MKK5_MKKC, "JP"},
+ {CTRY_JAPAN16, MKK6_MKKB, "JP"},
+ {CTRY_JAPAN17, MKK6_MKKA2, "JP"},
+ {CTRY_JAPAN18, MKK6_MKKC, "JP"},
+ {CTRY_JAPAN19, MKK7_MKKB, "JP"},
+ {CTRY_JAPAN20, MKK7_MKKA2, "JP"},
+ {CTRY_JAPAN21, MKK7_MKKC, "JP"},
+ {CTRY_JAPAN22, MKK8_MKKB, "JP"},
+ {CTRY_JAPAN23, MKK8_MKKA2, "JP"},
+ {CTRY_JAPAN24, MKK8_MKKC, "JP"},
+ {CTRY_JAPAN25, MKK3_MKKA, "JP"},
+ {CTRY_JAPAN26, MKK3_MKKA1, "JP"},
+ {CTRY_JAPAN27, MKK3_FCCA, "JP"},
+ {CTRY_JAPAN28, MKK4_MKKA1, "JP"},
+ {CTRY_JAPAN29, MKK4_FCCA, "JP"},
+ {CTRY_JAPAN30, MKK6_MKKA1, "JP"},
+ {CTRY_JAPAN31, MKK6_FCCA, "JP"},
+ {CTRY_JAPAN32, MKK7_MKKA1, "JP"},
+ {CTRY_JAPAN33, MKK7_FCCA, "JP"},
+ {CTRY_JAPAN34, MKK9_MKKA, "JP"},
+ {CTRY_JAPAN35, MKK10_MKKA, "JP"},
+ {CTRY_JAPAN36, MKK4_MKKA, "JP"},
+ {CTRY_JAPAN37, MKK9_FCCA, "JP"},
+ {CTRY_JAPAN38, MKK9_MKKA1, "JP"},
+ {CTRY_JAPAN39, MKK9_MKKC, "JP"},
+ {CTRY_JAPAN40, MKK9_MKKA2, "JP"},
+ {CTRY_JAPAN41, MKK10_FCCA, "JP"},
+ {CTRY_JAPAN42, MKK10_MKKA1, "JP"},
+ {CTRY_JAPAN43, MKK10_MKKC, "JP"},
+ {CTRY_JAPAN44, MKK10_MKKA2, "JP"},
+ {CTRY_JAPAN45, MKK11_MKKA, "JP"},
+ {CTRY_JAPAN46, MKK11_FCCA, "JP"},
+ {CTRY_JAPAN47, MKK11_MKKA1, "JP"},
+ {CTRY_JAPAN48, MKK11_MKKC, "JP"},
+ {CTRY_JAPAN49, MKK11_MKKA2, "JP"},
+ {CTRY_JAPAN50, MKK12_MKKA, "JP"},
+ {CTRY_JAPAN51, MKK12_FCCA, "JP"},
+ {CTRY_JAPAN52, MKK12_MKKA1, "JP"},
+ {CTRY_JAPAN53, MKK12_MKKC, "JP"},
+ {CTRY_JAPAN54, MKK12_MKKA2, "JP"},
+ {CTRY_JAPAN57, MKK13_MKKB, "JP"},
+ {CTRY_JAPAN58, MKK14_MKKA1, "JP"},
+ {CTRY_JAPAN59, MKK15_MKKA1, "JP"},
+
+ {CTRY_JORDAN, ETSI2_WORLD, "JO"},
+ {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
+ {CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
+ {CTRY_KOREA_ROC, APL9_WORLD, "KR"},
+ {CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
+ {CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
+ {CTRY_KUWAIT, NULL1_WORLD, "KW"},
+ {CTRY_LATVIA, ETSI1_WORLD, "LV"},
+ {CTRY_LEBANON, NULL1_WORLD, "LB"},
+ {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
+ {CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
+ {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
+ {CTRY_MACAU, FCC2_WORLD, "MO"},
+ {CTRY_MACEDONIA, NULL1_WORLD, "MK"},
+ {CTRY_MALAYSIA, APL8_WORLD, "MY"},
+ {CTRY_MALTA, ETSI1_WORLD, "MT"},
+ {CTRY_MEXICO, FCC1_FCCA, "MX"},
+ {CTRY_MONACO, ETSI4_WORLD, "MC"},
+ {CTRY_MOROCCO, NULL1_WORLD, "MA"},
+ {CTRY_NEPAL, APL1_WORLD, "NP"},
+ {CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
+ {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
+ {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
+ {CTRY_NORWAY, ETSI1_WORLD, "NO"},
+ {CTRY_OMAN, APL6_WORLD, "OM"},
+ {CTRY_PAKISTAN, NULL1_WORLD, "PK"},
+ {CTRY_PANAMA, FCC1_FCCA, "PA"},
+ {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
+ {CTRY_PERU, APL1_WORLD, "PE"},
+ {CTRY_PHILIPPINES, APL1_WORLD, "PH"},
+ {CTRY_POLAND, ETSI1_WORLD, "PL"},
+ {CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
+ {CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
+ {CTRY_QATAR, NULL1_WORLD, "QA"},
+ {CTRY_ROMANIA, NULL1_WORLD, "RO"},
+ {CTRY_RUSSIA, NULL1_WORLD, "RU"},
+ {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
+ {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
+ {CTRY_SINGAPORE, APL6_WORLD, "SG"},
+ {CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
+ {CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
+ {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
+ {CTRY_SPAIN, ETSI1_WORLD, "ES"},
+ {CTRY_SRI_LANKA, FCC3_WORLD, "LK"},
+ {CTRY_SWEDEN, ETSI1_WORLD, "SE"},
+ {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
+ {CTRY_SYRIA, NULL1_WORLD, "SY"},
+ {CTRY_TAIWAN, APL3_FCCA, "TW"},
+ {CTRY_THAILAND, NULL1_WORLD, "TH"},
+ {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
+ {CTRY_TUNISIA, ETSI3_WORLD, "TN"},
+ {CTRY_TURKEY, ETSI3_WORLD, "TR"},
+ {CTRY_UKRAINE, NULL1_WORLD, "UA"},
+ {CTRY_UAE, NULL1_WORLD, "AE"},
+ {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
+ {CTRY_UNITED_STATES, FCC3_FCCA, "US"},
+ /* This "PS" is for US public safety actually... to support this we
+ * would need to assign new special alpha2 to CRDA db as with the world
+ * regdomain and use another alpha2 */
+ {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"},
+ {CTRY_URUGUAY, APL2_WORLD, "UY"},
+ {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"},
+ {CTRY_VENEZUELA, APL2_ETSIC, "VE"},
+ {CTRY_VIET_NAM, NULL1_WORLD, "VN"},
+ {CTRY_YEMEN, NULL1_WORLD, "YE"},
+ {CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
};
-static struct regDomain regDomains[] = {
-
- {DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ,
- BM(A_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5130_5650, T1_5150_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(G_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1,
- -1, -1, -1, -1)},
-
- {APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC, NO_REQ,
- BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL7, ETSI, DFS_ETSI, PSCAN_ETSI, NO_REQ,
- BM(F1_5280_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL8, ETSI, NO_DFS, NO_PSCAN,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL9, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL10, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F1_5180_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
- BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
- BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ,
- BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700,
- F6_5745_5825, -1, -1, -1, -1, -1, -1, -1),
- BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
- BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
- F2_5260_5320, F4_5500_5700, -1, -1),
- BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
- BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1),
- BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1,
- -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320,
- F4_5500_5700, -1, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
- F2_5260_5320, F4_5500_5700, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F1_5170_5230, F7_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, -1, -1,
- -1, -1),
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK15, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240,
- F2_5260_5320, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO},
-
- {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {MKKA, MKK, NO_DFS,
- PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G |
- PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
- -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
- ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
- W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
- ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472,
- W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
- -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
- -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
- W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
- W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO}
-};
-
-static const struct cmode modes[] = {
- {ATH9K_MODE_11A, CHANNEL_A},
- {ATH9K_MODE_11B, CHANNEL_B},
- {ATH9K_MODE_11G, CHANNEL_G},
- {ATH9K_MODE_11NG_HT20, CHANNEL_G_HT20},
- {ATH9K_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
- {ATH9K_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
- {ATH9K_MODE_11NA_HT20, CHANNEL_A_HT20},
- {ATH9K_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
- {ATH9K_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
-};
-
-static struct japan_bandcheck j_bandcheck[] = {
- {F1_5170_5230, AR_EEPROM_EEREGCAP_EN_KK_U1_ODD},
- {F4_5180_5240, AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN},
- {F2_5260_5320, AR_EEPROM_EEREGCAP_EN_KK_U2},
- {F4_5500_5700, AR_EEPROM_EEREGCAP_EN_KK_MIDBAND}
-};
-
-
#endif
diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath9k/virtual.c
new file mode 100644
index 00000000000..1ff429b027d
--- /dev/null
+++ b/drivers/net/wireless/ath9k/virtual.c
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+
+struct ath9k_vif_iter_data {
+ int count;
+ u8 *addr;
+};
+
+static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct ath9k_vif_iter_data *iter_data = data;
+ u8 *nbuf;
+
+ nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
+ GFP_ATOMIC);
+ if (nbuf == NULL)
+ return;
+
+ memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
+ iter_data->addr = nbuf;
+ iter_data->count++;
+}
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath9k_vif_iter_data iter_data;
+ int i, j;
+ u8 mask[ETH_ALEN];
+
+ /*
+ * Add primary MAC address even if it is not in active use since it
+ * will be configured to the hardware as the starting point and the
+ * BSSID mask will need to be changed if another address is active.
+ */
+ iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
+ if (iter_data.addr) {
+ memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN);
+ iter_data.count = 1;
+ } else
+ iter_data.count = 0;
+
+ /* Get list of all active MAC addresses */
+ spin_lock_bh(&sc->wiphy_lock);
+ ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
+ &iter_data);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] == NULL)
+ continue;
+ ieee80211_iterate_active_interfaces_atomic(
+ sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data);
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+
+ /* Generate an address mask to cover all active addresses */
+ memset(mask, 0, ETH_ALEN);
+ for (i = 0; i < iter_data.count; i++) {
+ u8 *a1 = iter_data.addr + i * ETH_ALEN;
+ for (j = i + 1; j < iter_data.count; j++) {
+ u8 *a2 = iter_data.addr + j * ETH_ALEN;
+ mask[0] |= a1[0] ^ a2[0];
+ mask[1] |= a1[1] ^ a2[1];
+ mask[2] |= a1[2] ^ a2[2];
+ mask[3] |= a1[3] ^ a2[3];
+ mask[4] |= a1[4] ^ a2[4];
+ mask[5] |= a1[5] ^ a2[5];
+ }
+ }
+
+ kfree(iter_data.addr);
+
+ /* Invert the mask and configure hardware */
+ sc->bssidmask[0] = ~mask[0];
+ sc->bssidmask[1] = ~mask[1];
+ sc->bssidmask[2] = ~mask[2];
+ sc->bssidmask[3] = ~mask[3];
+ sc->bssidmask[4] = ~mask[4];
+ sc->bssidmask[5] = ~mask[5];
+
+ ath9k_hw_setbssidmask(sc);
+}
+
+int ath9k_wiphy_add(struct ath_softc *sc)
+{
+ int i, error;
+ struct ath_wiphy *aphy;
+ struct ieee80211_hw *hw;
+ u8 addr[ETH_ALEN];
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
+ if (hw == NULL)
+ return -ENOMEM;
+
+ spin_lock_bh(&sc->wiphy_lock);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] == NULL)
+ break;
+ }
+
+ if (i == sc->num_sec_wiphy) {
+ /* No empty slot available; increase array length */
+ struct ath_wiphy **n;
+ n = krealloc(sc->sec_wiphy,
+ (sc->num_sec_wiphy + 1) *
+ sizeof(struct ath_wiphy *),
+ GFP_ATOMIC);
+ if (n == NULL) {
+ spin_unlock_bh(&sc->wiphy_lock);
+ ieee80211_free_hw(hw);
+ return -ENOMEM;
+ }
+ n[i] = NULL;
+ sc->sec_wiphy = n;
+ sc->num_sec_wiphy++;
+ }
+
+ SET_IEEE80211_DEV(hw, sc->dev);
+
+ aphy = hw->priv;
+ aphy->sc = sc;
+ aphy->hw = hw;
+ sc->sec_wiphy[i] = aphy;
+ spin_unlock_bh(&sc->wiphy_lock);
+
+ memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
+ addr[0] |= 0x02; /* Locally managed address */
+ /*
+ * XOR virtual wiphy index into the least significant bits to generate
+ * a different MAC address for each virtual wiphy.
+ */
+ addr[5] ^= i & 0xff;
+ addr[4] ^= (i & 0xff00) >> 8;
+ addr[3] ^= (i & 0xff0000) >> 16;
+
+ SET_IEEE80211_PERM_ADDR(hw, addr);
+
+ ath_set_hw_capab(sc, hw);
+
+ error = ieee80211_register_hw(hw);
+
+ if (error == 0) {
+ /* Make sure wiphy scheduler is started (if enabled) */
+ ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
+ }
+
+ return error;
+}
+
+int ath9k_wiphy_del(struct ath_wiphy *aphy)
+{
+ struct ath_softc *sc = aphy->sc;
+ int i;
+
+ spin_lock_bh(&sc->wiphy_lock);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (aphy == sc->sec_wiphy[i]) {
+ sc->sec_wiphy[i] = NULL;
+ spin_unlock_bh(&sc->wiphy_lock);
+ ieee80211_unregister_hw(aphy->hw);
+ ieee80211_free_hw(aphy->hw);
+ return 0;
+ }
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+ return -ENOENT;
+}
+
+static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
+ struct ieee80211_vif *vif, const u8 *bssid,
+ int ps)
+{
+ struct ath_softc *sc = aphy->sc;
+ struct ath_tx_control txctl;
+ struct sk_buff *skb;
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+ struct ieee80211_tx_info *info;
+
+ skb = dev_alloc_skb(24);
+ if (skb == NULL)
+ return -ENOMEM;
+ hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
+ memset(hdr, 0, 24);
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+ IEEE80211_FCTL_TODS);
+ if (ps)
+ fc |= cpu_to_le16(IEEE80211_FCTL_PM);
+ hdr->frame_control = fc;
+ memcpy(hdr->addr1, bssid, ETH_ALEN);
+ memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN);
+ memcpy(hdr->addr3, bssid, ETH_ALEN);
+
+ info = IEEE80211_SKB_CB(skb);
+ memset(info, 0, sizeof(*info));
+ info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS;
+ info->control.vif = vif;
+ info->control.rates[0].idx = 0;
+ info->control.rates[0].count = 4;
+ info->control.rates[1].idx = -1;
+
+ memset(&txctl, 0, sizeof(struct ath_tx_control));
+ txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
+ txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE;
+
+ if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
+ goto exit;
+
+ return 0;
+exit:
+ dev_kfree_skb_any(skb);
+ return -1;
+}
+
+static bool __ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+ int i;
+ if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING)
+ return true;
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING)
+ return true;
+ }
+ return false;
+}
+
+static bool ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+ bool ret;
+ spin_lock_bh(&sc->wiphy_lock);
+ ret = __ath9k_wiphy_pausing(sc);
+ spin_unlock_bh(&sc->wiphy_lock);
+ return ret;
+}
+
+static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+ int i;
+ if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
+ return true;
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
+ return true;
+ }
+ return false;
+}
+
+bool ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+ bool ret;
+ spin_lock_bh(&sc->wiphy_lock);
+ ret = __ath9k_wiphy_scanning(sc);
+ spin_unlock_bh(&sc->wiphy_lock);
+ return ret;
+}
+
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy)
+{
+ if (aphy == NULL)
+ return;
+ if (aphy->chan_idx != aphy->sc->chan_idx)
+ return; /* wiphy not on the selected channel */
+ __ath9k_wiphy_unpause(aphy);
+}
+
+static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
+{
+ int i;
+ spin_lock_bh(&sc->wiphy_lock);
+ __ath9k_wiphy_unpause_ch(sc->pri_wiphy);
+ for (i = 0; i < sc->num_sec_wiphy; i++)
+ __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]);
+ spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_chan_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+ struct ath_wiphy *aphy = sc->next_wiphy;
+
+ if (aphy == NULL)
+ return;
+
+ /*
+ * All pending interfaces paused; ready to change
+ * channels.
+ */
+
+ /* Change channels */
+ mutex_lock(&sc->mutex);
+ /* XXX: remove me eventually */
+ ath9k_update_ichannel(sc, aphy->hw,
+ &sc->sc_ah->channels[sc->chan_idx]);
+ ath_update_chainmask(sc, sc->chan_is_ht);
+ if (ath_set_channel(sc, aphy->hw,
+ &sc->sc_ah->channels[sc->chan_idx]) < 0) {
+ printk(KERN_DEBUG "ath9k: Failed to set channel for new "
+ "virtual wiphy\n");
+ mutex_unlock(&sc->mutex);
+ return;
+ }
+ mutex_unlock(&sc->mutex);
+
+ ath9k_wiphy_unpause_channel(sc);
+}
+
+/*
+ * ath9k version of ieee80211_tx_status() for TX frames that are generated
+ * internally in the driver.
+ */
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+
+ if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE &&
+ aphy->state == ATH_WIPHY_PAUSING) {
+ if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
+ printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
+ "frame\n", wiphy_name(hw->wiphy));
+ /*
+ * The AP did not reply; ignore this to allow us to
+ * continue.
+ */
+ }
+ aphy->state = ATH_WIPHY_PAUSED;
+ if (!ath9k_wiphy_pausing(aphy->sc)) {
+ /*
+ * Drop from tasklet to work to allow mutex for channel
+ * change.
+ */
+ queue_work(aphy->sc->hw->workqueue,
+ &aphy->sc->chan_work);
+ }
+ }
+
+ kfree(tx_info_priv);
+ tx_info->rate_driver_data[0] = NULL;
+
+ dev_kfree_skb(skb);
+}
+
+static void ath9k_mark_paused(struct ath_wiphy *aphy)
+{
+ struct ath_softc *sc = aphy->sc;
+ aphy->state = ATH_WIPHY_PAUSED;
+ if (!__ath9k_wiphy_pausing(sc))
+ queue_work(sc->hw->workqueue, &sc->chan_work);
+}
+
+static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct ath_wiphy *aphy = data;
+ struct ath_vif *avp = (void *) vif->drv_priv;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ if (!vif->bss_conf.assoc) {
+ ath9k_mark_paused(aphy);
+ break;
+ }
+ /* TODO: could avoid this if already in PS mode */
+ if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) {
+ printk(KERN_DEBUG "%s: failed to send PS nullfunc\n",
+ __func__);
+ ath9k_mark_paused(aphy);
+ }
+ break;
+ case NL80211_IFTYPE_AP:
+ /* Beacon transmission is paused by aphy->state change */
+ ath9k_mark_paused(aphy);
+ break;
+ default:
+ break;
+ }
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+ ieee80211_stop_queues(aphy->hw);
+ aphy->state = ATH_WIPHY_PAUSING;
+ /*
+ * TODO: handle PAUSING->PAUSED for the case where there are multiple
+ * active vifs (now we do it on the first vif getting ready; should be
+ * on the last)
+ */
+ ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter,
+ aphy);
+ return 0;
+}
+
+int ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+ int ret;
+ spin_lock_bh(&aphy->sc->wiphy_lock);
+ ret = __ath9k_wiphy_pause(aphy);
+ spin_unlock_bh(&aphy->sc->wiphy_lock);
+ return ret;
+}
+
+static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct ath_wiphy *aphy = data;
+ struct ath_vif *avp = (void *) vif->drv_priv;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ if (!vif->bss_conf.assoc)
+ break;
+ ath9k_send_nullfunc(aphy, vif, avp->bssid, 0);
+ break;
+ case NL80211_IFTYPE_AP:
+ /* Beacon transmission is re-enabled by aphy->state change */
+ break;
+ default:
+ break;
+ }
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+ ieee80211_iterate_active_interfaces_atomic(aphy->hw,
+ ath9k_unpause_iter, aphy);
+ aphy->state = ATH_WIPHY_ACTIVE;
+ ieee80211_wake_queues(aphy->hw);
+ return 0;
+}
+
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+ int ret;
+ spin_lock_bh(&aphy->sc->wiphy_lock);
+ ret = __ath9k_wiphy_unpause(aphy);
+ spin_unlock_bh(&aphy->sc->wiphy_lock);
+ return ret;
+}
+
+static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc)
+{
+ int i;
+ if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE)
+ sc->pri_wiphy->state = ATH_WIPHY_PAUSED;
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE)
+ sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED;
+ }
+}
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_pause_all(struct ath_softc *sc)
+{
+ int i;
+ if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+ __ath9k_wiphy_pause(sc->pri_wiphy);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+ __ath9k_wiphy_pause(sc->sec_wiphy[i]);
+ }
+}
+
+int ath9k_wiphy_select(struct ath_wiphy *aphy)
+{
+ struct ath_softc *sc = aphy->sc;
+ bool now;
+
+ spin_lock_bh(&sc->wiphy_lock);
+ if (__ath9k_wiphy_scanning(sc)) {
+ /*
+ * For now, we are using mac80211 sw scan and it expects to
+ * have full control over channel changes, so avoid wiphy
+ * scheduling during a scan. This could be optimized if the
+ * scanning control were moved into the driver.
+ */
+ spin_unlock_bh(&sc->wiphy_lock);
+ return -EBUSY;
+ }
+ if (__ath9k_wiphy_pausing(sc)) {
+ if (sc->wiphy_select_failures == 0)
+ sc->wiphy_select_first_fail = jiffies;
+ sc->wiphy_select_failures++;
+ if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
+ {
+ printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
+ "out; disable/enable hw to recover\n");
+ __ath9k_wiphy_mark_all_paused(sc);
+ /*
+ * TODO: this workaround to fix hardware is unlikely to
+ * be specific to virtual wiphy changes. It can happen
+ * on normal channel change, too, and as such, this
+ * should really be made more generic. For example,
+ * tricker radio disable/enable on GTT interrupt burst
+ * (say, 10 GTT interrupts received without any TX
+ * frame being completed)
+ */
+ spin_unlock_bh(&sc->wiphy_lock);
+ ath_radio_disable(sc);
+ ath_radio_enable(sc);
+ queue_work(aphy->sc->hw->workqueue,
+ &aphy->sc->chan_work);
+ return -EBUSY; /* previous select still in progress */
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+ return -EBUSY; /* previous select still in progress */
+ }
+ sc->wiphy_select_failures = 0;
+
+ /* Store the new channel */
+ sc->chan_idx = aphy->chan_idx;
+ sc->chan_is_ht = aphy->chan_is_ht;
+ sc->next_wiphy = aphy;
+
+ __ath9k_wiphy_pause_all(sc);
+ now = !__ath9k_wiphy_pausing(aphy->sc);
+ spin_unlock_bh(&sc->wiphy_lock);
+
+ if (now) {
+ /* Ready to request channel change immediately */
+ queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
+ }
+
+ /*
+ * wiphys will be unpaused in ath9k_tx_status() once channel has been
+ * changed if any wiphy needs time to become paused.
+ */
+
+ return 0;
+}
+
+bool ath9k_wiphy_started(struct ath_softc *sc)
+{
+ int i;
+ spin_lock_bh(&sc->wiphy_lock);
+ if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+ spin_unlock_bh(&sc->wiphy_lock);
+ return true;
+ }
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
+ spin_unlock_bh(&sc->wiphy_lock);
+ return true;
+ }
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+ return false;
+}
+
+static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
+ struct ath_wiphy *selected)
+{
+ if (selected->state == ATH_WIPHY_SCAN) {
+ if (aphy == selected)
+ return;
+ /*
+ * Pause all other wiphys for the duration of the scan even if
+ * they are on the current channel now.
+ */
+ } else if (aphy->chan_idx == selected->chan_idx)
+ return;
+ aphy->state = ATH_WIPHY_PAUSED;
+ ieee80211_stop_queues(aphy->hw);
+}
+
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+ struct ath_wiphy *selected)
+{
+ int i;
+ spin_lock_bh(&sc->wiphy_lock);
+ if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+ ath9k_wiphy_pause_chan(sc->pri_wiphy, selected);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+ ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected);
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc,
+ wiphy_work.work);
+ struct ath_wiphy *aphy = NULL;
+ bool first = true;
+
+ spin_lock_bh(&sc->wiphy_lock);
+
+ if (sc->wiphy_scheduler_int == 0) {
+ /* wiphy scheduler is disabled */
+ spin_unlock_bh(&sc->wiphy_lock);
+ return;
+ }
+
+try_again:
+ sc->wiphy_scheduler_index++;
+ while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) {
+ aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1];
+ if (aphy && aphy->state != ATH_WIPHY_INACTIVE)
+ break;
+
+ sc->wiphy_scheduler_index++;
+ aphy = NULL;
+ }
+ if (aphy == NULL) {
+ sc->wiphy_scheduler_index = 0;
+ if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) {
+ if (first) {
+ first = false;
+ goto try_again;
+ }
+ /* No wiphy is ready to be scheduled */
+ } else
+ aphy = sc->pri_wiphy;
+ }
+
+ spin_unlock_bh(&sc->wiphy_lock);
+
+ if (aphy &&
+ aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN &&
+ ath9k_wiphy_select(aphy)) {
+ printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy "
+ "change\n");
+ }
+
+ queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+ sc->wiphy_scheduler_int);
+}
+
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
+{
+ cancel_delayed_work_sync(&sc->wiphy_work);
+ sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
+ if (sc->wiphy_scheduler_int)
+ queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+ sc->wiphy_scheduler_int);
+}
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index c92f0c6e4ad..e3f376611f8 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
+#include "ath9k.h"
#define BITS_PER_BYTE 8
#define OFDM_PLCP_BITS 22
@@ -55,94 +55,19 @@ static u32 bits_per_symbol[][2] = {
#define IS_HT_RATE(_rate) ((_rate) & 0x80)
-/*
- * Insert a chain of ath_buf (descriptors) on a txq and
- * assume the descriptors are already chained together by caller.
- * NB: must be called with txq lock held
- */
-
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid,
+ struct list_head *bf_head);
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+ struct list_head *bf_q,
+ int txok, int sendbar);
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
- struct list_head *head)
-{
- struct ath_hal *ah = sc->sc_ah;
- struct ath_buf *bf;
-
- /*
- * Insert the frame on the outbound list and
- * pass it on to the hardware.
- */
-
- if (list_empty(head))
- return;
-
- bf = list_first_entry(head, struct ath_buf, list);
-
- list_splice_tail_init(head, &txq->axq_q);
- txq->axq_depth++;
- txq->axq_totalqueued++;
- txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
-
- DPRINTF(sc, ATH_DBG_QUEUE,
- "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
-
- if (txq->axq_link == NULL) {
- ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
- DPRINTF(sc, ATH_DBG_XMIT,
- "TXDP[%u] = %llx (%p)\n",
- txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
- } else {
- *txq->axq_link = bf->bf_daddr;
- DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
- txq->axq_qnum, txq->axq_link,
- ito64(bf->bf_daddr), bf->bf_desc);
- }
- txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
- ath9k_hw_txstart(ah, txq->axq_qnum);
-}
-
-static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_xmit_status *tx_status)
-{
- struct ieee80211_hw *hw = sc->hw;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
- int hdrlen, padsize;
-
- DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
-
- if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
- tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
- kfree(tx_info_priv);
- tx_info->rate_driver_data[0] = NULL;
- }
-
- if (tx_status->flags & ATH_TX_BAR) {
- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
- tx_status->flags &= ~ATH_TX_BAR;
- }
-
- if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
- /* Frame was ACKed */
- tx_info->flags |= IEEE80211_TX_STAT_ACK;
- }
-
- tx_info->status.rates[0].count = tx_status->retries + 1;
-
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- padsize = hdrlen & 3;
- if (padsize && hdrlen >= 24) {
- /*
- * Remove MAC header padding before giving the frame back to
- * mac80211.
- */
- memmove(skb->data + padsize, skb->data, hdrlen);
- skb_pull(skb, padsize);
- }
-
- ieee80211_tx_status(hw, skb);
-}
+ struct list_head *head);
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
-/* Check if it's okay to send out aggregates */
+/*********************/
+/* Aggregation logic */
+/*********************/
static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
{
@@ -156,232 +81,19 @@ static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
return 0;
}
-static void ath_get_beaconconfig(struct ath_softc *sc, int if_id,
- struct ath_beacon_config *conf)
-{
- struct ieee80211_hw *hw = sc->hw;
-
- /* fill in beacon config data */
-
- conf->beacon_interval = hw->conf.beacon_int;
- conf->listen_interval = 100;
- conf->dtim_count = 1;
- conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
-}
-
-/* Calculate Atheros packet type from IEEE80211 packet header */
-
-static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
- enum ath9k_pkt_type htype;
- __le16 fc;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
-
- if (ieee80211_is_beacon(fc))
- htype = ATH9K_PKT_TYPE_BEACON;
- else if (ieee80211_is_probe_resp(fc))
- htype = ATH9K_PKT_TYPE_PROBE_RESP;
- else if (ieee80211_is_atim(fc))
- htype = ATH9K_PKT_TYPE_ATIM;
- else if (ieee80211_is_pspoll(fc))
- htype = ATH9K_PKT_TYPE_PSPOLL;
- else
- htype = ATH9K_PKT_TYPE_NORMAL;
-
- return htype;
-}
-
-static bool is_pae(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
- __le16 fc;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
-
- if (ieee80211_is_data(fc)) {
- if (ieee80211_is_nullfunc(fc) ||
- /* Port Access Entity (IEEE 802.1X) */
- (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- return true;
- }
- }
-
- return false;
-}
-
-static int get_hw_crypto_keytype(struct sk_buff *skb)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-
- if (tx_info->control.hw_key) {
- if (tx_info->control.hw_key->alg == ALG_WEP)
- return ATH9K_KEY_TYPE_WEP;
- else if (tx_info->control.hw_key->alg == ALG_TKIP)
- return ATH9K_KEY_TYPE_TKIP;
- else if (tx_info->control.hw_key->alg == ALG_CCMP)
- return ATH9K_KEY_TYPE_AES;
- }
-
- return ATH9K_KEY_TYPE_CLEAR;
-}
-
-/* Called only when tx aggregation is enabled and HT is supported */
-
-static void assign_aggr_tid_seqno(struct sk_buff *skb,
- struct ath_buf *bf)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr;
- struct ath_node *an;
- struct ath_atx_tid *tid;
- __le16 fc;
- u8 *qc;
-
- if (!tx_info->control.sta)
- return;
-
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
-
- /* Get tidno */
-
- if (ieee80211_is_data_qos(fc)) {
- qc = ieee80211_get_qos_ctl(hdr);
- bf->bf_tidno = qc[0] & 0xf;
- }
-
- /* Get seqno */
- /* For HT capable stations, we save tidno for later use.
- * We also override seqno set by upper layer with the one
- * in tx aggregation state.
- *
- * If fragmentation is on, the sequence number is
- * not overridden, since it has been
- * incremented by the fragmentation routine.
- *
- * FIXME: check if the fragmentation threshold exceeds
- * IEEE80211 max.
- */
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
- hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
- IEEE80211_SEQ_SEQ_SHIFT);
- bf->bf_seqno = tid->seq_next;
- INCR(tid->seq_next, IEEE80211_SEQ_MAX);
-}
-
-static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_txq *txq)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- int flags = 0;
-
- flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
- flags |= ATH9K_TXDESC_INTREQ;
-
- if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
- flags |= ATH9K_TXDESC_NOACK;
- if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
- flags |= ATH9K_TXDESC_RTSENA;
-
- return flags;
-}
-
-static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
-{
- struct ath_buf *bf = NULL;
-
- spin_lock_bh(&sc->tx.txbuflock);
-
- if (unlikely(list_empty(&sc->tx.txbuf))) {
- spin_unlock_bh(&sc->tx.txbuflock);
- return NULL;
- }
-
- bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
- list_del(&bf->list);
-
- spin_unlock_bh(&sc->tx.txbuflock);
-
- return bf;
-}
-
-/* To complete a chain of buffers associated a frame */
-
-static void ath_tx_complete_buf(struct ath_softc *sc,
- struct ath_buf *bf,
- struct list_head *bf_q,
- int txok, int sendbar)
-{
- struct sk_buff *skb = bf->bf_mpdu;
- struct ath_xmit_status tx_status;
- unsigned long flags;
-
- /*
- * Set retry information.
- * NB: Don't use the information in the descriptor, because the frame
- * could be software retried.
- */
- tx_status.retries = bf->bf_retries;
- tx_status.flags = 0;
-
- if (sendbar)
- tx_status.flags = ATH_TX_BAR;
-
- if (!txok) {
- tx_status.flags |= ATH_TX_ERROR;
-
- if (bf_isxretried(bf))
- tx_status.flags |= ATH_TX_XRETRY;
- }
-
- /* Unmap this frame */
- pci_unmap_single(sc->pdev,
- bf->bf_dmacontext,
- skb->len,
- PCI_DMA_TODEVICE);
- /* complete this frame */
- ath_tx_complete(sc, skb, &tx_status);
-
- /*
- * Return the list of ath_buf of this mpdu to free queue
- */
- spin_lock_irqsave(&sc->tx.txbuflock, flags);
- list_splice_tail_init(bf_q, &sc->tx.txbuf);
- spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
-}
-
-/*
- * queue up a dest/ac pair for tx scheduling
- * NB: must be called with txq lock held
- */
-
static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
{
struct ath_atx_ac *ac = tid->ac;
- /*
- * if tid is paused, hold off
- */
if (tid->paused)
return;
- /*
- * add tid to ac atmost once
- */
if (tid->sched)
return;
tid->sched = true;
list_add_tail(&tid->list, &ac->tid_q);
- /*
- * add node ac to txq atmost once
- */
if (ac->sched)
return;
@@ -389,22 +101,16 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
list_add_tail(&ac->list, &txq->axq_acq);
}
-/* pause a tid */
-
static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
spin_lock_bh(&txq->axq_lock);
-
tid->paused++;
-
spin_unlock_bh(&txq->axq_lock);
}
-/* resume a tid and schedule aggregate */
-
-void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
@@ -419,63 +125,39 @@ void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
if (list_empty(&tid->buf_q))
goto unlock;
- /*
- * Add this TID to scheduler and try to send out aggregates
- */
ath_tx_queue_tid(txq, tid);
ath_txq_schedule(sc, txq);
unlock:
spin_unlock_bh(&txq->axq_lock);
}
-/* Compute the number of bad frames */
-
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
- int txok)
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_buf *bf_last = bf->bf_lastbf;
- struct ath_desc *ds = bf_last->bf_desc;
- u16 seq_st = 0;
- u32 ba[WME_BA_BMP_SIZE >> 5];
- int ba_index;
- int nbad = 0;
- int isaggr = 0;
-
- if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
- return 0;
+ struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+ struct ath_buf *bf;
+ struct list_head bf_head;
+ INIT_LIST_HEAD(&bf_head);
- isaggr = bf_isaggr(bf);
- if (isaggr) {
- seq_st = ATH_DS_BA_SEQ(ds);
- memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
- }
+ ASSERT(tid->paused > 0);
+ spin_lock_bh(&txq->axq_lock);
- while (bf) {
- ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
- if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
- nbad++;
+ tid->paused--;
- bf = bf->bf_next;
+ if (tid->paused > 0) {
+ spin_unlock_bh(&txq->axq_lock);
+ return;
}
- return nbad;
-}
-
-static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
-{
- struct sk_buff *skb;
- struct ieee80211_hdr *hdr;
-
- bf->bf_state.bf_type |= BUF_RETRY;
- bf->bf_retries++;
+ while (!list_empty(&tid->buf_q)) {
+ bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+ ASSERT(!bf_isretried(bf));
+ list_move_tail(&bf->list, &bf_head);
+ ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+ }
- skb = bf->bf_mpdu;
- hdr = (struct ieee80211_hdr *)skb->data;
- hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
+ spin_unlock_bh(&txq->axq_lock);
}
-/* Update block ack window */
-
static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
int seqno)
{
@@ -492,290 +174,142 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
}
}
-/*
- * ath_pkt_dur - compute packet duration (NB: not NAV)
- *
- * rix - rate index
- * pktlen - total bytes (delims + data + fcs + pads + pad delims)
- * width - 0 for 20 MHz, 1 for 40 MHz
- * half_gi - to use 4us v/s 3.6 us for symbol time
- */
-static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
- int width, int half_gi, bool shortPreamble)
+static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+ struct ath_buf *bf)
{
- struct ath_rate_table *rate_table = sc->cur_rate_table;
- u32 nbits, nsymbits, duration, nsymbols;
- u8 rc;
- int streams, pktlen;
-
- pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
- rc = rate_table->info[rix].ratecode;
-
- /* for legacy rates, use old function to compute packet duration */
- if (!IS_HT_RATE(rc))
- return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
- rix, shortPreamble);
+ int index, cindex;
- /* find number of symbols: PLCP + data */
- nbits = (pktlen << 3) + OFDM_PLCP_BITS;
- nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
- nsymbols = (nbits + nsymbits - 1) / nsymbits;
+ if (bf_isretried(bf))
+ return;
- if (!half_gi)
- duration = SYMBOL_TIME(nsymbols);
- else
- duration = SYMBOL_TIME_HALFGI(nsymbols);
+ index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
+ cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
- /* addup duration for legacy/ht training and signal fields */
- streams = HT_RC_2_STREAMS(rc);
- duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+ ASSERT(tid->tx_buf[cindex] == NULL);
+ tid->tx_buf[cindex] = bf;
- return duration;
+ if (index >= ((tid->baw_tail - tid->baw_head) &
+ (ATH_TID_MAX_BUFS - 1))) {
+ tid->baw_tail = cindex;
+ INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
+ }
}
-/* Rate module function to set rate related fields in tx descriptor */
+/*
+ * TODO: For frame(s) that are in the retry state, we will reuse the
+ * sequence number(s) without setting the retry bit. The
+ * alternative is to give up on these and BAR the receiver's window
+ * forward.
+ */
+static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid)
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_hal *ah = sc->sc_ah;
- struct ath_rate_table *rt;
- struct ath_desc *ds = bf->bf_desc;
- struct ath_desc *lastds = bf->bf_lastbf->bf_desc;
- struct ath9k_11n_rate_series series[4];
- struct sk_buff *skb;
- struct ieee80211_tx_info *tx_info;
- struct ieee80211_tx_rate *rates;
- struct ieee80211_hdr *hdr;
- int i, flags, rtsctsena = 0;
- u32 ctsduration = 0;
- u8 rix = 0, cix, ctsrate = 0;
- __le16 fc;
-
- memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
-
- skb = (struct sk_buff *)bf->bf_mpdu;
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
- tx_info = IEEE80211_SKB_CB(skb);
- rates = tx_info->control.rates;
-
- if (ieee80211_has_morefrags(fc) ||
- (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
- rates[1].count = rates[2].count = rates[3].count = 0;
- rates[1].idx = rates[2].idx = rates[3].idx = 0;
- rates[0].count = ATH_TXMAXTRY;
- }
+ struct ath_buf *bf;
+ struct list_head bf_head;
+ INIT_LIST_HEAD(&bf_head);
- /* get the cix for the lowest valid rix */
- rt = sc->cur_rate_table;
- for (i = 3; i >= 0; i--) {
- if (rates[i].count && (rates[i].idx >= 0)) {
- rix = rates[i].idx;
+ for (;;) {
+ if (list_empty(&tid->buf_q))
break;
- }
- }
-
- flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA));
- cix = rt->info[rix].ctrl_rate;
- /*
- * If 802.11g protection is enabled, determine whether to use RTS/CTS or
- * just CTS. Note that this is only done for OFDM/HT unicast frames.
- */
- if (sc->sc_protmode != PROT_M_NONE && !(bf->bf_flags & ATH9K_TXDESC_NOACK)
- && (rt->info[rix].phy == WLAN_RC_PHY_OFDM ||
- WLAN_RC_PHY_HT(rt->info[rix].phy))) {
- if (sc->sc_protmode == PROT_M_RTSCTS)
- flags = ATH9K_TXDESC_RTSENA;
- else if (sc->sc_protmode == PROT_M_CTSONLY)
- flags = ATH9K_TXDESC_CTSENA;
-
- cix = rt->info[sc->sc_protrix].ctrl_rate;
- rtsctsena = 1;
- }
-
- /* For 11n, the default behavior is to enable RTS for hw retried frames.
- * We enable the global flag here and let rate series flags determine
- * which rates will actually use RTS.
- */
- if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) {
- /* 802.11g protection not needed, use our default behavior */
- if (!rtsctsena)
- flags = ATH9K_TXDESC_RTSENA;
- }
-
- /* Set protection if aggregate protection on */
- if (sc->sc_config.ath_aggr_prot &&
- (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
- flags = ATH9K_TXDESC_RTSENA;
- cix = rt->info[sc->sc_protrix].ctrl_rate;
- rtsctsena = 1;
- }
-
- /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
- if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit))
- flags &= ~(ATH9K_TXDESC_RTSENA);
-
- /*
- * CTS transmit rate is derived from the transmit rate by looking in the
- * h/w rate table. We must also factor in whether or not a short
- * preamble is to be used. NB: cix is set above where RTS/CTS is enabled
- */
- ctsrate = rt->info[cix].ratecode |
- (bf_isshpreamble(bf) ? rt->info[cix].short_preamble : 0);
-
- for (i = 0; i < 4; i++) {
- if (!rates[i].count || (rates[i].idx < 0))
- continue;
-
- rix = rates[i].idx;
-
- series[i].Rate = rt->info[rix].ratecode |
- (bf_isshpreamble(bf) ? rt->info[rix].short_preamble : 0);
-
- series[i].Tries = rates[i].count;
-
- series[i].RateFlags = (
- (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) ?
- ATH9K_RATESERIES_RTS_CTS : 0) |
- ((rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ?
- ATH9K_RATESERIES_2040 : 0) |
- ((rates[i].flags & IEEE80211_TX_RC_SHORT_GI) ?
- ATH9K_RATESERIES_HALFGI : 0);
-
- series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
- (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
- (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
- bf_isshpreamble(bf));
+ bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+ list_move_tail(&bf->list, &bf_head);
- series[i].ChSel = sc->sc_tx_chainmask;
+ if (bf_isretried(bf))
+ ath_tx_update_baw(sc, tid, bf->bf_seqno);
- if (rtsctsena)
- series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+ spin_unlock(&txq->axq_lock);
+ ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+ spin_lock(&txq->axq_lock);
}
- /* set dur_update_en for l-sig computation except for PS-Poll frames */
- ath9k_hw_set11n_ratescenario(ah, ds, lastds, !bf_ispspoll(bf),
- ctsrate, ctsduration,
- series, 4, flags);
-
- if (sc->sc_config.ath_aggr_prot && flags)
- ath9k_hw_set11n_burstduration(ah, ds, 8192);
+ tid->seq_next = tid->seq_start;
+ tid->baw_tail = tid->baw_head;
}
-/*
- * Function to send a normal HT (non-AMPDU) frame
- * NB: must be called with txq lock held
- */
-static int ath_tx_send_normal(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_atx_tid *tid,
- struct list_head *bf_head)
+static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_buf *bf;
-
- BUG_ON(list_empty(bf_head));
-
- bf = list_first_entry(bf_head, struct ath_buf, list);
- bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */
-
- /* update starting sequence number for subsequent ADDBA request */
- INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+ struct sk_buff *skb;
+ struct ieee80211_hdr *hdr;
- /* Queue to h/w without aggregation */
- bf->bf_nframes = 1;
- bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txq, bf_head);
+ bf->bf_state.bf_type |= BUF_RETRY;
+ bf->bf_retries++;
- return 0;
+ skb = bf->bf_mpdu;
+ hdr = (struct ieee80211_hdr *)skb->data;
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
}
-/* flush tid's software queue and send frames as non-ampdu's */
-
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
- struct ath_buf *bf;
- struct list_head bf_head;
- INIT_LIST_HEAD(&bf_head);
+ struct ath_buf *tbf;
- ASSERT(tid->paused > 0);
- spin_lock_bh(&txq->axq_lock);
+ spin_lock_bh(&sc->tx.txbuflock);
+ ASSERT(!list_empty((&sc->tx.txbuf)));
+ tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+ list_del(&tbf->list);
+ spin_unlock_bh(&sc->tx.txbuflock);
- tid->paused--;
+ ATH_TXBUF_RESET(tbf);
- if (tid->paused > 0) {
- spin_unlock_bh(&txq->axq_lock);
- return;
- }
-
- while (!list_empty(&tid->buf_q)) {
- bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
- ASSERT(!bf_isretried(bf));
- list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
- ath_tx_send_normal(sc, txq, tid, &bf_head);
- }
+ tbf->bf_mpdu = bf->bf_mpdu;
+ tbf->bf_buf_addr = bf->bf_buf_addr;
+ *(tbf->bf_desc) = *(bf->bf_desc);
+ tbf->bf_state = bf->bf_state;
+ tbf->bf_dmacontext = bf->bf_dmacontext;
- spin_unlock_bh(&txq->axq_lock);
+ return tbf;
}
-/* Completion routine of an aggregate */
-
-static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_buf *bf,
- struct list_head *bf_q,
- int txok)
+static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_buf *bf, struct list_head *bf_q,
+ int txok)
{
struct ath_node *an = NULL;
struct sk_buff *skb;
- struct ieee80211_tx_info *tx_info;
+ struct ieee80211_sta *sta;
+ struct ieee80211_hdr *hdr;
struct ath_atx_tid *tid = NULL;
- struct ath_buf *bf_last = bf->bf_lastbf;
+ struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
struct ath_desc *ds = bf_last->bf_desc;
- struct ath_buf *bf_next, *bf_lastq = NULL;
struct list_head bf_head, bf_pending;
u16 seq_st = 0;
u32 ba[WME_BA_BMP_SIZE >> 5];
int isaggr, txfail, txpending, sendbar = 0, needreset = 0;
skb = (struct sk_buff *)bf->bf_mpdu;
- tx_info = IEEE80211_SKB_CB(skb);
+ hdr = (struct ieee80211_hdr *)skb->data;
- if (tx_info->control.sta) {
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ rcu_read_lock();
+
+ sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+ if (!sta) {
+ rcu_read_unlock();
+ return;
}
+ an = (struct ath_node *)sta->drv_priv;
+ tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
isaggr = bf_isaggr(bf);
- if (isaggr) {
- if (txok) {
- if (ATH_DS_TX_BA(ds)) {
- /*
- * extract starting sequence and
- * block-ack bitmap
- */
- seq_st = ATH_DS_BA_SEQ(ds);
- memcpy(ba,
- ATH_DS_BA_BITMAP(ds),
- WME_BA_BMP_SIZE >> 3);
- } else {
- memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+ memset(ba, 0, WME_BA_BMP_SIZE >> 3);
- /*
- * AR5416 can become deaf/mute when BA
- * issue happens. Chip needs to be reset.
- * But AP code may have sychronization issues
- * when perform internal reset in this routine.
- * Only enable reset in STA mode for now.
- */
- if (sc->sc_ah->ah_opmode ==
- NL80211_IFTYPE_STATION)
- needreset = 1;
- }
+ if (isaggr && txok) {
+ if (ATH_DS_TX_BA(ds)) {
+ seq_st = ATH_DS_BA_SEQ(ds);
+ memcpy(ba, ATH_DS_BA_BITMAP(ds),
+ WME_BA_BMP_SIZE >> 3);
} else {
- memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+ /*
+ * AR5416 can become deaf/mute when BA
+ * issue happens. Chip needs to be reset.
+ * But AP code may have sychronization issues
+ * when perform internal reset in this routine.
+ * Only enable reset in STA mode for now.
+ */
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION)
+ needreset = 1;
}
}
@@ -792,7 +326,6 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
} else if (!isaggr && txok) {
/* transmit completion */
} else {
-
if (!(tid->state & AGGR_CLEANUP) &&
ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
@@ -811,37 +344,12 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
txfail = 1;
}
}
- /*
- * Remove ath_buf's of this sub-frame from aggregate queue.
- */
- if (bf_next == NULL) { /* last subframe in the aggregate */
- ASSERT(bf->bf_lastfrm == bf_last);
-
- /*
- * The last descriptor of the last sub frame could be
- * a holding descriptor for h/w. If that's the case,
- * bf->bf_lastfrm won't be in the bf_q.
- * Make sure we handle bf_q properly here.
- */
- if (!list_empty(bf_q)) {
- bf_lastq = list_entry(bf_q->prev,
- struct ath_buf, list);
- list_cut_position(&bf_head,
- bf_q, &bf_lastq->list);
- } else {
- /*
- * XXX: if the last subframe only has one
- * descriptor which is also being used as
- * a holding descriptor. Then the ath_buf
- * is not in the bf_q at all.
- */
- INIT_LIST_HEAD(&bf_head);
- }
+ if (bf_next == NULL) {
+ INIT_LIST_HEAD(&bf_head);
} else {
ASSERT(!list_empty(bf_q));
- list_cut_position(&bf_head,
- bf_q, &bf->bf_lastfrm->list);
+ list_move_tail(&bf->list, &bf_head);
}
if (!txpending) {
@@ -853,62 +361,22 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
ath_tx_update_baw(sc, tid, bf->bf_seqno);
spin_unlock_bh(&txq->axq_lock);
- /* complete this sub-frame */
ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
} else {
- /*
- * retry the un-acked ones
- */
- /*
- * XXX: if the last descriptor is holding descriptor,
- * in order to requeue the frame to software queue, we
- * need to allocate a new descriptor and
- * copy the content of holding descriptor to it.
- */
+ /* retry the un-acked ones */
if (bf->bf_next == NULL &&
bf_last->bf_status & ATH_BUFSTATUS_STALE) {
struct ath_buf *tbf;
- /* allocate new descriptor */
- spin_lock_bh(&sc->tx.txbuflock);
- ASSERT(!list_empty((&sc->tx.txbuf)));
- tbf = list_first_entry(&sc->tx.txbuf,
- struct ath_buf, list);
- list_del(&tbf->list);
- spin_unlock_bh(&sc->tx.txbuflock);
-
- ATH_TXBUF_RESET(tbf);
-
- /* copy descriptor content */
- tbf->bf_mpdu = bf_last->bf_mpdu;
- tbf->bf_buf_addr = bf_last->bf_buf_addr;
- *(tbf->bf_desc) = *(bf_last->bf_desc);
-
- /* link it to the frame */
- if (bf_lastq) {
- bf_lastq->bf_desc->ds_link =
- tbf->bf_daddr;
- bf->bf_lastfrm = tbf;
- ath9k_hw_cleartxdesc(sc->sc_ah,
- bf->bf_lastfrm->bf_desc);
- } else {
- tbf->bf_state = bf_last->bf_state;
- tbf->bf_lastfrm = tbf;
- ath9k_hw_cleartxdesc(sc->sc_ah,
- tbf->bf_lastfrm->bf_desc);
-
- /* copy the DMA context */
- tbf->bf_dmacontext =
- bf_last->bf_dmacontext;
- }
+ tbf = ath_clone_txbuf(sc, bf_last);
+ ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
list_add_tail(&tbf->list, &bf_head);
} else {
/*
* Clear descriptor status words for
* software retry
*/
- ath9k_hw_cleartxdesc(sc->sc_ah,
- bf->bf_lastfrm->bf_desc);
+ ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
}
/*
@@ -922,332 +390,33 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
}
if (tid->state & AGGR_CLEANUP) {
- /* check to see if we're done with cleaning the h/w queue */
- spin_lock_bh(&txq->axq_lock);
-
if (tid->baw_head == tid->baw_tail) {
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->addba_exchangeattempts = 0;
- spin_unlock_bh(&txq->axq_lock);
-
tid->state &= ~AGGR_CLEANUP;
/* send buffered frames as singles */
ath_tx_flush_tid(sc, tid);
- } else
- spin_unlock_bh(&txq->axq_lock);
-
+ }
+ rcu_read_unlock();
return;
}
- /*
- * prepend un-acked frames to the beginning of the pending frame queue
- */
+ /* prepend un-acked frames to the beginning of the pending frame queue */
if (!list_empty(&bf_pending)) {
spin_lock_bh(&txq->axq_lock);
- /* Note: we _prepend_, we _do_not_ at to
- * the end of the queue ! */
list_splice(&bf_pending, &tid->buf_q);
ath_tx_queue_tid(txq, tid);
spin_unlock_bh(&txq->axq_lock);
}
+ rcu_read_unlock();
+
if (needreset)
ath_reset(sc, false);
-
- return;
-}
-
-static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad)
-{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-
- tx_info_priv->update_rc = false;
- if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
- tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-
- if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
- (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
- if (bf_isdata(bf)) {
- memcpy(&tx_info_priv->tx, &ds->ds_txstat,
- sizeof(tx_info_priv->tx));
- tx_info_priv->n_frames = bf->bf_nframes;
- tx_info_priv->n_bad_frames = nbad;
- tx_info_priv->update_rc = true;
- }
- }
-}
-
-/* Process completed xmit descriptors from the specified queue */
-
-static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
-{
- struct ath_hal *ah = sc->sc_ah;
- struct ath_buf *bf, *lastbf, *bf_held = NULL;
- struct list_head bf_head;
- struct ath_desc *ds;
- int txok, nbad = 0;
- int status;
-
- DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
- txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
- txq->axq_link);
-
- for (;;) {
- spin_lock_bh(&txq->axq_lock);
- if (list_empty(&txq->axq_q)) {
- txq->axq_link = NULL;
- txq->axq_linkbuf = NULL;
- spin_unlock_bh(&txq->axq_lock);
- break;
- }
- bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
-
- /*
- * There is a race condition that a BH gets scheduled
- * after sw writes TxE and before hw re-load the last
- * descriptor to get the newly chained one.
- * Software must keep the last DONE descriptor as a
- * holding descriptor - software does so by marking
- * it with the STALE flag.
- */
- bf_held = NULL;
- if (bf->bf_status & ATH_BUFSTATUS_STALE) {
- bf_held = bf;
- if (list_is_last(&bf_held->list, &txq->axq_q)) {
- /* FIXME:
- * The holding descriptor is the last
- * descriptor in queue. It's safe to remove
- * the last holding descriptor in BH context.
- */
- spin_unlock_bh(&txq->axq_lock);
- break;
- } else {
- /* Lets work with the next buffer now */
- bf = list_entry(bf_held->list.next,
- struct ath_buf, list);
- }
- }
-
- lastbf = bf->bf_lastbf;
- ds = lastbf->bf_desc; /* NB: last decriptor */
-
- status = ath9k_hw_txprocdesc(ah, ds);
- if (status == -EINPROGRESS) {
- spin_unlock_bh(&txq->axq_lock);
- break;
- }
- if (bf->bf_desc == txq->axq_lastdsWithCTS)
- txq->axq_lastdsWithCTS = NULL;
- if (ds == txq->axq_gatingds)
- txq->axq_gatingds = NULL;
-
- /*
- * Remove ath_buf's of the same transmit unit from txq,
- * however leave the last descriptor back as the holding
- * descriptor for hw.
- */
- lastbf->bf_status |= ATH_BUFSTATUS_STALE;
- INIT_LIST_HEAD(&bf_head);
-
- if (!list_is_singular(&lastbf->list))
- list_cut_position(&bf_head,
- &txq->axq_q, lastbf->list.prev);
-
- txq->axq_depth--;
-
- if (bf_isaggr(bf))
- txq->axq_aggr_depth--;
-
- txok = (ds->ds_txstat.ts_status == 0);
-
- spin_unlock_bh(&txq->axq_lock);
-
- if (bf_held) {
- list_del(&bf_held->list);
- spin_lock_bh(&sc->tx.txbuflock);
- list_add_tail(&bf_held->list, &sc->tx.txbuf);
- spin_unlock_bh(&sc->tx.txbuflock);
- }
-
- if (!bf_isampdu(bf)) {
- /*
- * This frame is sent out as a single frame.
- * Use hardware retry status for this frame.
- */
- bf->bf_retries = ds->ds_txstat.ts_longretry;
- if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
- bf->bf_state.bf_type |= BUF_XRETRY;
- nbad = 0;
- } else {
- nbad = ath_tx_num_badfrms(sc, bf, txok);
- }
-
- ath_tx_rc_status(bf, ds, nbad);
-
- /*
- * Complete this transmit unit
- */
- if (bf_isampdu(bf))
- ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok);
- else
- ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
-
- /* Wake up mac80211 queue */
-
- spin_lock_bh(&txq->axq_lock);
- if (txq->stopped && ath_txq_depth(sc, txq->axq_qnum) <=
- (ATH_TXBUF - 20)) {
- int qnum;
- qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
- if (qnum != -1) {
- ieee80211_wake_queue(sc->hw, qnum);
- txq->stopped = 0;
- }
-
- }
-
- /*
- * schedule any pending packets if aggregation is enabled
- */
- if (sc->sc_flags & SC_OP_TXAGGR)
- ath_txq_schedule(sc, txq);
- spin_unlock_bh(&txq->axq_lock);
- }
-}
-
-static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
-{
- struct ath_hal *ah = sc->sc_ah;
-
- (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum);
- DPRINTF(sc, ATH_DBG_XMIT, "tx queue [%u] %x, link %p\n",
- txq->axq_qnum, ath9k_hw_gettxbuf(ah, txq->axq_qnum),
- txq->axq_link);
-}
-
-/* Drain only the data queues */
-
-static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
-{
- struct ath_hal *ah = sc->sc_ah;
- int i, status, npend = 0;
-
- if (!(sc->sc_flags & SC_OP_INVALID)) {
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (ATH_TXQ_SETUP(sc, i)) {
- ath_tx_stopdma(sc, &sc->tx.txq[i]);
- /* The TxDMA may not really be stopped.
- * Double check the hal tx pending count */
- npend += ath9k_hw_numtxpending(ah,
- sc->tx.txq[i].axq_qnum);
- }
- }
- }
-
- if (npend) {
- /* TxDMA not stopped, reset the hal */
- DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
-
- spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah,
- sc->sc_ah->ah_curchan,
- sc->tx_chan_width,
- sc->sc_tx_chainmask, sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing, true, &status)) {
-
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; hal status %u\n",
- status);
- }
- spin_unlock_bh(&sc->sc_resetlock);
- }
-
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (ATH_TXQ_SETUP(sc, i))
- ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx);
- }
-}
-
-/* Add a sub-frame to block ack window */
-
-static void ath_tx_addto_baw(struct ath_softc *sc,
- struct ath_atx_tid *tid,
- struct ath_buf *bf)
-{
- int index, cindex;
-
- if (bf_isretried(bf))
- return;
-
- index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
- cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-
- ASSERT(tid->tx_buf[cindex] == NULL);
- tid->tx_buf[cindex] = bf;
-
- if (index >= ((tid->baw_tail - tid->baw_head) &
- (ATH_TID_MAX_BUFS - 1))) {
- tid->baw_tail = cindex;
- INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
- }
-}
-
-/*
- * Function to send an A-MPDU
- * NB: must be called with txq lock held
- */
-static int ath_tx_send_ampdu(struct ath_softc *sc,
- struct ath_atx_tid *tid,
- struct list_head *bf_head,
- struct ath_tx_control *txctl)
-{
- struct ath_buf *bf;
-
- BUG_ON(list_empty(bf_head));
-
- bf = list_first_entry(bf_head, struct ath_buf, list);
- bf->bf_state.bf_type |= BUF_AMPDU;
-
- /*
- * Do not queue to h/w when any of the following conditions is true:
- * - there are pending frames in software queue
- * - the TID is currently paused for ADDBA/BAR request
- * - seqno is not within block-ack window
- * - h/w queue depth exceeds low water mark
- */
- if (!list_empty(&tid->buf_q) || tid->paused ||
- !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
- txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
- /*
- * Add this frame to software queue for scheduling later
- * for aggregation.
- */
- list_splice_tail_init(bf_head, &tid->buf_q);
- ath_tx_queue_tid(txctl->txq, tid);
- return 0;
- }
-
- /* Add sub-frame to BAW */
- ath_tx_addto_baw(sc, tid, bf);
-
- /* Queue to h/w without aggregation */
- bf->bf_nframes = 1;
- bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
-
- return 0;
}
-/*
- * looks up the rate
- * returns aggr limit based on lowest of the rates
- */
-static u32 ath_lookup_rate(struct ath_softc *sc,
- struct ath_buf *bf,
+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;
@@ -1255,15 +424,14 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates;
struct ath_tx_info_priv *tx_info_priv;
- u32 max_4ms_framelen, frame_length;
+ u32 max_4ms_framelen, frmlen;
u16 aggr_limit, legacy = 0, maxampdu;
int i;
skb = (struct sk_buff *)bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
rates = tx_info->control.rates;
- tx_info_priv =
- (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
/*
* Find the lowest frame length among the rate series that will have a
@@ -1279,9 +447,8 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
break;
}
- frame_length =
- rate_table->info[rates[i].idx].max_4ms_framelen;
- max_4ms_framelen = min(max_4ms_framelen, frame_length);
+ frmlen = rate_table->info[rates[i].idx].max_4ms_framelen;
+ max_4ms_framelen = min(max_4ms_framelen, frmlen);
}
}
@@ -1293,8 +460,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
return 0;
- aggr_limit = min(max_4ms_framelen,
- (u32)ATH_AMPDU_LIMIT_DEFAULT);
+ aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT);
/*
* h/w can accept aggregates upto 16 bit lengths (65535).
@@ -1309,14 +475,12 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
}
/*
- * returns the number of delimiters to be added to
+ * Returns the number of delimiters to be added to
* meet the minimum required mpdudensity.
- * caller should make sure that the rate is HT rate .
+ * caller should make sure that the rate is HT rate .
*/
-static int ath_compute_num_delims(struct ath_softc *sc,
- struct ath_atx_tid *tid,
- struct ath_buf *bf,
- u16 frmlen)
+static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
+ struct ath_buf *bf, u16 frmlen)
{
struct ath_rate_table *rt = sc->cur_rate_table;
struct sk_buff *skb = bf->bf_mpdu;
@@ -1370,9 +534,7 @@ static int ath_compute_num_delims(struct ath_softc *sc,
nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
- /* Is frame shorter than required minimum length? */
if (frmlen < minlen) {
- /* Get the minimum number of delimiters required. */
mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
ndelim = max(mindelim, ndelim);
}
@@ -1380,37 +542,23 @@ static int ath_compute_num_delims(struct ath_softc *sc,
return ndelim;
}
-/*
- * For aggregation from software buffer queue.
- * NB: must be called with txq lock held
- */
static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
- struct ath_atx_tid *tid,
- struct list_head *bf_q,
- struct ath_buf **bf_last,
- struct aggr_rifs_param *param,
- int *prev_frames)
+ struct ath_atx_tid *tid,
+ struct list_head *bf_q)
{
#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
- struct ath_buf *bf, *tbf, *bf_first, *bf_prev = NULL;
- struct list_head bf_head;
- int rl = 0, nframes = 0, ndelim;
+ struct ath_buf *bf, *bf_first, *bf_prev = NULL;
+ int rl = 0, nframes = 0, ndelim, prev_al = 0;
u16 aggr_limit = 0, al = 0, bpad = 0,
al_delta, h_baw = tid->baw_size / 2;
enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
- int prev_al = 0;
- INIT_LIST_HEAD(&bf_head);
-
- BUG_ON(list_empty(&tid->buf_q));
bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
do {
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
- /*
- * do not step over block-ack window
- */
+ /* do not step over block-ack window */
if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
status = ATH_AGGR_BAW_CLOSED;
break;
@@ -1421,29 +569,23 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
rl = 1;
}
- /*
- * do not exceed aggregation limit
- */
+ /* do not exceed aggregation limit */
al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
- if (nframes && (aggr_limit <
- (al + bpad + al_delta + prev_al))) {
+ if (nframes &&
+ (aggr_limit < (al + bpad + al_delta + prev_al))) {
status = ATH_AGGR_LIMITED;
break;
}
- /*
- * do not exceed subframe limit
- */
- if ((nframes + *prev_frames) >=
- min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
+ /* do not exceed subframe limit */
+ if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
status = ATH_AGGR_LIMITED;
break;
}
+ nframes++;
- /*
- * add padding for previous frame to aggregation length
- */
+ /* add padding for previous frame to aggregation length */
al += bpad + al_delta;
/*
@@ -1451,69 +593,35 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
* density for this node.
*/
ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
-
bpad = PADBYTES(al_delta) + (ndelim << 2);
bf->bf_next = NULL;
- bf->bf_lastfrm->bf_desc->ds_link = 0;
+ bf->bf_desc->ds_link = 0;
- /*
- * this packet is part of an aggregate
- * - remove all descriptors belonging to this frame from
- * software queue
- * - add it to block ack window
- * - set up descriptors for aggregation
- */
- list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
+ /* link buffers of this frame to the aggregate */
ath_tx_addto_baw(sc, tid, bf);
-
- list_for_each_entry(tbf, &bf_head, list) {
- ath9k_hw_set11n_aggr_middle(sc->sc_ah,
- tbf->bf_desc, ndelim);
- }
-
- /*
- * link buffers of this frame to the aggregate
- */
- list_splice_tail_init(&bf_head, bf_q);
- nframes++;
-
+ ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
+ list_move_tail(&bf->list, bf_q);
if (bf_prev) {
bf_prev->bf_next = bf;
- bf_prev->bf_lastfrm->bf_desc->ds_link = bf->bf_daddr;
+ bf_prev->bf_desc->ds_link = bf->bf_daddr;
}
bf_prev = bf;
-
-#ifdef AGGR_NOSHORT
- /*
- * terminate aggregation on a small packet boundary
- */
- if (bf->bf_frmlen < ATH_AGGR_MINPLEN) {
- status = ATH_AGGR_SHORTPKT;
- break;
- }
-#endif
} while (!list_empty(&tid->buf_q));
bf_first->bf_al = al;
bf_first->bf_nframes = nframes;
- *bf_last = bf_prev;
+
return status;
#undef PADBYTES
}
-/*
- * process pending frames possibly doing a-mpdu aggregation
- * NB: must be called with txq lock held
- */
-static void ath_tx_sched_aggr(struct ath_softc *sc,
- struct ath_txq *txq, struct ath_atx_tid *tid)
+static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid)
{
- struct ath_buf *bf, *tbf, *bf_last, *bf_lastaggr = NULL;
+ struct ath_buf *bf;
enum ATH_AGGR_STATUS status;
struct list_head bf_q;
- struct aggr_rifs_param param = {0, 0, 0, 0, NULL};
- int prev_frames = 0;
do {
if (list_empty(&tid->buf_q))
@@ -1521,382 +629,169 @@ static void ath_tx_sched_aggr(struct ath_softc *sc,
INIT_LIST_HEAD(&bf_q);
- status = ath_tx_form_aggr(sc, tid, &bf_q, &bf_lastaggr, &param,
- &prev_frames);
+ status = ath_tx_form_aggr(sc, tid, &bf_q);
/*
- * no frames picked up to be aggregated; block-ack
- * window is not open
+ * no frames picked up to be aggregated;
+ * block-ack window is not open.
*/
if (list_empty(&bf_q))
break;
bf = list_first_entry(&bf_q, struct ath_buf, list);
- bf_last = list_entry(bf_q.prev, struct ath_buf, list);
- bf->bf_lastbf = bf_last;
+ bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
- /*
- * if only one frame, send as non-aggregate
- */
+ /* if only one frame, send as non-aggregate */
if (bf->bf_nframes == 1) {
- ASSERT(bf->bf_lastfrm == bf_last);
-
bf->bf_state.bf_type &= ~BUF_AGGR;
- /*
- * clear aggr bits for every descriptor
- * XXX TODO: is there a way to optimize it?
- */
- list_for_each_entry(tbf, &bf_q, list) {
- ath9k_hw_clr11n_aggr(sc->sc_ah, tbf->bf_desc);
- }
-
+ ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
ath_buf_set_rate(sc, bf);
ath_tx_txqaddbuf(sc, txq, &bf_q);
continue;
}
- /*
- * setup first desc with rate and aggr info
- */
+ /* setup first desc of aggregate */
bf->bf_state.bf_type |= BUF_AGGR;
ath_buf_set_rate(sc, bf);
ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
- /*
- * anchor last frame of aggregate correctly
- */
- ASSERT(bf_lastaggr);
- ASSERT(bf_lastaggr->bf_lastfrm == bf_last);
- tbf = bf_lastaggr;
- ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
-
- /* XXX: We don't enter into this loop, consider removing this */
- while (!list_empty(&bf_q) && !list_is_last(&tbf->list, &bf_q)) {
- tbf = list_entry(tbf->list.next, struct ath_buf, list);
- ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
- }
+ /* anchor last desc of aggregate */
+ ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
txq->axq_aggr_depth++;
-
- /*
- * Normal aggregate, queue to hardware
- */
ath_tx_txqaddbuf(sc, txq, &bf_q);
} while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
status != ATH_AGGR_BAW_CLOSED);
}
-/* Called with txq lock held */
-
-static void ath_tid_drain(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_atx_tid *tid)
-
-{
- struct ath_buf *bf;
- struct list_head bf_head;
- INIT_LIST_HEAD(&bf_head);
-
- for (;;) {
- if (list_empty(&tid->buf_q))
- break;
- bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-
- list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
-
- /* update baw for software retried frame */
- if (bf_isretried(bf))
- ath_tx_update_baw(sc, tid, bf->bf_seqno);
-
- /*
- * do not indicate packets while holding txq spinlock.
- * unlock is intentional here
- */
- spin_unlock(&txq->axq_lock);
-
- /* complete this sub-frame */
- ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-
- spin_lock(&txq->axq_lock);
- }
-
- /*
- * TODO: For frame(s) that are in the retry state, we will reuse the
- * sequence number(s) without setting the retry bit. The
- * alternative is to give up on these and BAR the receiver's window
- * forward.
- */
- tid->seq_next = tid->seq_start;
- tid->baw_tail = tid->baw_head;
-}
-
-/*
- * Drain all pending buffers
- * NB: must be called with txq lock held
- */
-static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
- struct ath_txq *txq)
-{
- struct ath_atx_ac *ac, *ac_tmp;
- struct ath_atx_tid *tid, *tid_tmp;
-
- list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
- list_del(&ac->list);
- ac->sched = false;
- list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
- list_del(&tid->list);
- tid->sched = false;
- ath_tid_drain(sc, txq, tid);
- }
- }
-}
-
-static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
- struct sk_buff *skb,
- struct ath_tx_control *txctl)
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn)
{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ath_tx_info_priv *tx_info_priv;
- int hdrlen;
- __le16 fc;
-
- tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
- if (unlikely(!tx_info_priv))
- return -ENOMEM;
- tx_info->rate_driver_data[0] = tx_info_priv;
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- fc = hdr->frame_control;
-
- ATH_TXBUF_RESET(bf);
-
- /* Frame type */
-
- bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
-
- ieee80211_is_data(fc) ?
- (bf->bf_state.bf_type |= BUF_DATA) :
- (bf->bf_state.bf_type &= ~BUF_DATA);
- ieee80211_is_back_req(fc) ?
- (bf->bf_state.bf_type |= BUF_BAR) :
- (bf->bf_state.bf_type &= ~BUF_BAR);
- ieee80211_is_pspoll(fc) ?
- (bf->bf_state.bf_type |= BUF_PSPOLL) :
- (bf->bf_state.bf_type &= ~BUF_PSPOLL);
- (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ?
- (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) :
- (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE);
- (sc->hw->conf.ht.enabled && !is_pae(skb) &&
- (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) ?
- (bf->bf_state.bf_type |= BUF_HT) :
- (bf->bf_state.bf_type &= ~BUF_HT);
-
- bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
-
- /* Crypto */
-
- bf->bf_keytype = get_hw_crypto_keytype(skb);
-
- if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
- bf->bf_frmlen += tx_info->control.hw_key->icv_len;
- bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
- } else {
- bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
- }
-
- /* Assign seqno, tidno */
-
- if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
- assign_aggr_tid_seqno(skb, bf);
+ struct ath_atx_tid *txtid;
+ struct ath_node *an;
- /* DMA setup */
- bf->bf_mpdu = skb;
+ an = (struct ath_node *)sta->drv_priv;
- bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data,
- skb->len, PCI_DMA_TODEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_dmacontext))) {
- bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on TX\n");
- return -ENOMEM;
+ if (sc->sc_flags & SC_OP_TXAGGR) {
+ txtid = ATH_AN_2_TID(an, tid);
+ txtid->state |= AGGR_ADDBA_PROGRESS;
+ ath_tx_pause_tid(sc, txtid);
+ *ssn = txtid->seq_start;
}
- bf->bf_buf_addr = bf->bf_dmacontext;
return 0;
}
-/* FIXME: tx power */
-static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
- struct ath_tx_control *txctl)
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ath_node *an = NULL;
+ struct ath_node *an = (struct ath_node *)sta->drv_priv;
+ struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
+ struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
+ struct ath_buf *bf;
struct list_head bf_head;
- struct ath_desc *ds;
- struct ath_atx_tid *tid;
- struct ath_hal *ah = sc->sc_ah;
- int frm_type;
-
- frm_type = get_hw_packet_type(skb);
-
INIT_LIST_HEAD(&bf_head);
- list_add_tail(&bf->list, &bf_head);
-
- /* setup descriptor */
-
- ds = bf->bf_desc;
- ds->ds_link = 0;
- ds->ds_data = bf->bf_buf_addr;
-
- /* Formulate first tx descriptor with tx controls */
-
- ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
- bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
-
- ath9k_hw_filltxdesc(ah, ds,
- skb->len, /* segment length */
- true, /* first segment */
- true, /* last segment */
- ds); /* first descriptor */
- bf->bf_lastfrm = bf;
+ if (txtid->state & AGGR_CLEANUP)
+ return 0;
- spin_lock_bh(&txctl->txq->axq_lock);
+ if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+ txtid->addba_exchangeattempts = 0;
+ return 0;
+ }
- if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
- tx_info->control.sta) {
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ ath_tx_pause_tid(sc, txtid);
- if (ath_aggr_query(sc, an, bf->bf_tidno)) {
- /*
- * Try aggregation if it's a unicast data frame
- * and the destination is HT capable.
- */
- ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
- } else {
+ /* drop all software retried frames and mark this TID */
+ spin_lock_bh(&txq->axq_lock);
+ while (!list_empty(&txtid->buf_q)) {
+ bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
+ if (!bf_isretried(bf)) {
/*
- * Send this frame as regular when ADDBA
- * exchange is neither complete nor pending.
+ * NB: it's based on the assumption that
+ * software retried frame will always stay
+ * at the head of software queue.
*/
- ath_tx_send_normal(sc, txctl->txq,
- tid, &bf_head);
+ break;
}
- } else {
- bf->bf_lastbf = bf;
- bf->bf_nframes = 1;
+ list_move_tail(&bf->list, &bf_head);
+ ath_tx_update_baw(sc, txtid, bf->bf_seqno);
+ ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+ }
+ spin_unlock_bh(&txq->axq_lock);
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
+ if (txtid->baw_head != txtid->baw_tail) {
+ txtid->state |= AGGR_CLEANUP;
+ } else {
+ txtid->state &= ~AGGR_ADDBA_COMPLETE;
+ txtid->addba_exchangeattempts = 0;
+ ath_tx_flush_tid(sc, txtid);
}
- spin_unlock_bh(&txctl->txq->axq_lock);
+ return 0;
}
-/* Upon failure caller should free skb */
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_tx_control *txctl)
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
{
- struct ath_buf *bf;
- int r;
-
- /* Check if a tx buffer is available */
-
- bf = ath_tx_get_buffer(sc);
- if (!bf) {
- DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
- return -1;
- }
-
- r = ath_tx_setup_buffer(sc, bf, skb, txctl);
- if (unlikely(r)) {
- struct ath_txq *txq = txctl->txq;
-
- DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
-
- /* upon ath_tx_processq() this TX queue will be resumed, we
- * guarantee this will happen by knowing beforehand that
- * we will at least have to run TX completionon one buffer
- * on the queue */
- spin_lock_bh(&txq->axq_lock);
- if (ath_txq_depth(sc, txq->axq_qnum) > 1) {
- ieee80211_stop_queue(sc->hw,
- skb_get_queue_mapping(skb));
- txq->stopped = 1;
- }
- spin_unlock_bh(&txq->axq_lock);
+ struct ath_atx_tid *txtid;
+ struct ath_node *an;
- spin_lock_bh(&sc->tx.txbuflock);
- list_add_tail(&bf->list, &sc->tx.txbuf);
- spin_unlock_bh(&sc->tx.txbuflock);
+ an = (struct ath_node *)sta->drv_priv;
- return r;
+ if (sc->sc_flags & SC_OP_TXAGGR) {
+ txtid = ATH_AN_2_TID(an, tid);
+ txtid->baw_size =
+ IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+ txtid->state |= AGGR_ADDBA_COMPLETE;
+ txtid->state &= ~AGGR_ADDBA_PROGRESS;
+ ath_tx_resume_tid(sc, txtid);
}
-
- ath_tx_start_dma(sc, bf, txctl);
-
- return 0;
}
-/* Initialize TX queue and h/w */
-
-int ath_tx_init(struct ath_softc *sc, int nbufs)
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
{
- int error = 0;
+ struct ath_atx_tid *txtid;
- do {
- spin_lock_init(&sc->tx.txbuflock);
+ if (!(sc->sc_flags & SC_OP_TXAGGR))
+ return false;
- /* Setup tx descriptors */
- 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;
- }
+ txtid = ATH_AN_2_TID(an, tidno);
- /* XXX allocate beacon state together with vap */
- 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;
+ if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+ if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
+ (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
+ txtid->addba_exchangeattempts++;
+ return true;
}
+ }
- } while (0);
-
- if (error != 0)
- ath_tx_cleanup(sc);
-
- return error;
+ return false;
}
-/* Reclaim all tx queue resources */
+/********************/
+/* Queue Management */
+/********************/
-int ath_tx_cleanup(struct ath_softc *sc)
+static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
+ struct ath_txq *txq)
{
- /* cleanup beacon descriptors */
- if (sc->beacon.bdma.dd_desc_len != 0)
- ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
-
- /* cleanup tx descriptors */
- if (sc->tx.txdma.dd_desc_len != 0)
- ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+ struct ath_atx_ac *ac, *ac_tmp;
+ struct ath_atx_tid *tid, *tid_tmp;
- return 0;
+ list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
+ list_del(&ac->list);
+ ac->sched = false;
+ list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
+ list_del(&tid->list);
+ tid->sched = false;
+ ath_tid_drain(sc, txq, tid);
+ }
+ }
}
-/* Setup a h/w transmit queue */
-
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath9k_tx_queue_info qi;
int qnum;
@@ -1959,43 +854,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
return &sc->tx.txq[qnum];
}
-/* Reclaim resources for a setup queue */
-
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
-{
- ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
- sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
-}
-
-/*
- * Setup a hardware data transmit queue for the specified
- * access control. The hal may not support all requested
- * queues in which case it will return a reference to a
- * previously setup queue. We record the mapping from ac's
- * to h/w queues for use by ath_tx_start and also track
- * the set of h/w queues being used to optimize work in the
- * transmit interrupt handler and related routines.
- */
-
-int ath_tx_setup(struct ath_softc *sc, int haltype)
-{
- struct ath_txq *txq;
-
- if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "HAL AC %u out of range, max %zu!\n",
- haltype, ARRAY_SIZE(sc->tx.hwq_map));
- return 0;
- }
- txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
- if (txq != NULL) {
- sc->tx.hwq_map[haltype] = txq->axq_qnum;
- return 1;
- } else
- return 0;
-}
-
-int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
+static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
{
int qnum;
@@ -2021,8 +880,6 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
return qnum;
}
-/* Get a transmit queue, if available */
-
struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
{
struct ath_txq *txq = NULL;
@@ -2033,9 +890,8 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
spin_lock_bh(&txq->axq_lock);
- /* Try to avoid running out of descriptors */
if (txq->axq_depth >= (ATH_TXBUF - 20)) {
- DPRINTF(sc, ATH_DBG_FATAL,
+ DPRINTF(sc, ATH_DBG_XMIT,
"TX queue: %d is full, depth: %d\n",
qnum, txq->axq_depth);
ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
@@ -2049,12 +905,10 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
return txq;
}
-/* Update parameters for a transmit queue */
-
int ath_txq_update(struct ath_softc *sc, int qnum,
struct ath9k_tx_queue_info *qinfo)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
int error = 0;
struct ath9k_tx_queue_info qi;
@@ -2082,7 +936,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
"Unable to update hardware queue %u!\n", qnum);
error = -EIO;
} else {
- ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */
+ ath9k_hw_resettxqueue(ah, qnum);
}
return error;
@@ -2092,55 +946,36 @@ int ath_cabq_update(struct ath_softc *sc)
{
struct ath9k_tx_queue_info qi;
int qnum = sc->beacon.cabq->axq_qnum;
- struct ath_beacon_config conf;
ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
/*
* Ensure the readytime % is within the bounds.
*/
- if (sc->sc_config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
- sc->sc_config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
- else if (sc->sc_config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
- sc->sc_config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
-
- ath_get_beaconconfig(sc, ATH_IF_ID_ANY, &conf);
- qi.tqi_readyTime =
- (conf.beacon_interval * sc->sc_config.cabqReadytime) / 100;
+ if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
+ sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
+ else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
+ sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
+
+ qi.tqi_readyTime = (sc->hw->conf.beacon_int *
+ sc->config.cabqReadytime) / 100;
ath_txq_update(sc, qnum, &qi);
return 0;
}
-/* Deferred processing of transmit interrupt */
-
-void ath_tx_tasklet(struct ath_softc *sc)
-{
- int i;
- u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
-
- ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
-
- /*
- * Process each active queue.
- */
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
- ath_tx_processq(sc, &sc->tx.txq[i]);
- }
-}
-
-void ath_tx_draintxq(struct ath_softc *sc,
- struct ath_txq *txq, bool retry_tx)
+/*
+ * Drain a given TX queue (could be Beacon or Data)
+ *
+ * This assumes output has been stopped and
+ * we do not need to block ath_tx_tasklet.
+ */
+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
{
struct ath_buf *bf, *lastbf;
struct list_head bf_head;
INIT_LIST_HEAD(&bf_head);
- /*
- * NB: this assumes output has been stopped and
- * we do not need to block ath_tx_tasklet
- */
for (;;) {
spin_lock_bh(&txq->axq_lock);
@@ -2175,7 +1010,7 @@ void ath_tx_draintxq(struct ath_softc *sc,
spin_unlock_bh(&txq->axq_lock);
if (bf_isampdu(bf))
- ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0);
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
else
ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
}
@@ -2190,44 +1025,285 @@ void ath_tx_draintxq(struct ath_softc *sc,
}
}
-/* Drain the transmit queues and reclaim resources */
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_txq *txq;
+ int i, npend = 0;
-void ath_draintxq(struct ath_softc *sc, bool retry_tx)
+ if (sc->sc_flags & SC_OP_INVALID)
+ return;
+
+ /* Stop beacon queue */
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+
+ /* Stop data queues */
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+ if (ATH_TXQ_SETUP(sc, i)) {
+ txq = &sc->tx.txq[i];
+ ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+ npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
+ }
+ }
+
+ if (npend) {
+ int r;
+
+ DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
+
+ spin_lock_bh(&sc->sc_resetlock);
+ r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+ if (r)
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Unable to reset hardware; reset status %u\n",
+ r);
+ spin_unlock_bh(&sc->sc_resetlock);
+ }
+
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+ if (ATH_TXQ_SETUP(sc, i))
+ ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
+ }
+}
+
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
{
- /* stop beacon queue. The beacon will be freed when
- * we go to INIT state */
- if (!(sc->sc_flags & SC_OP_INVALID)) {
- (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
- DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n",
- ath9k_hw_gettxbuf(sc->sc_ah, sc->beacon.beaconq));
+ ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
+ sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
+}
+
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+{
+ struct ath_atx_ac *ac;
+ struct ath_atx_tid *tid;
+
+ if (list_empty(&txq->axq_acq))
+ return;
+
+ ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
+ list_del(&ac->list);
+ ac->sched = false;
+
+ do {
+ if (list_empty(&ac->tid_q))
+ return;
+
+ tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
+ list_del(&tid->list);
+ tid->sched = false;
+
+ if (tid->paused)
+ continue;
+
+ if ((txq->axq_depth % 2) == 0)
+ ath_tx_sched_aggr(sc, txq, tid);
+
+ /*
+ * add tid to round-robin queue if more frames
+ * are pending for the tid
+ */
+ if (!list_empty(&tid->buf_q))
+ ath_tx_queue_tid(txq, tid);
+
+ break;
+ } while (!list_empty(&ac->tid_q));
+
+ if (!list_empty(&ac->tid_q)) {
+ if (!ac->sched) {
+ ac->sched = true;
+ list_add_tail(&ac->list, &txq->axq_acq);
+ }
}
+}
- ath_drain_txdataq(sc, retry_tx);
+int ath_tx_setup(struct ath_softc *sc, int haltype)
+{
+ struct ath_txq *txq;
+
+ if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "HAL AC %u out of range, max %zu!\n",
+ haltype, ARRAY_SIZE(sc->tx.hwq_map));
+ return 0;
+ }
+ txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
+ if (txq != NULL) {
+ sc->tx.hwq_map[haltype] = txq->axq_qnum;
+ return 1;
+ } else
+ return 0;
}
-u32 ath_txq_depth(struct ath_softc *sc, int qnum)
+/***********/
+/* TX, DMA */
+/***********/
+
+/*
+ * Insert a chain of ath_buf (descriptors) on a txq and
+ * assume the descriptors are already chained together by caller.
+ */
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+ struct list_head *head)
{
- return sc->tx.txq[qnum].axq_depth;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_buf *bf;
+
+ /*
+ * Insert the frame on the outbound list and
+ * pass it on to the hardware.
+ */
+
+ if (list_empty(head))
+ return;
+
+ bf = list_first_entry(head, struct ath_buf, list);
+
+ list_splice_tail_init(head, &txq->axq_q);
+ txq->axq_depth++;
+ txq->axq_totalqueued++;
+ txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
+
+ DPRINTF(sc, ATH_DBG_QUEUE,
+ "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
+
+ if (txq->axq_link == NULL) {
+ ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+ DPRINTF(sc, ATH_DBG_XMIT,
+ "TXDP[%u] = %llx (%p)\n",
+ txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+ } else {
+ *txq->axq_link = bf->bf_daddr;
+ DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
+ txq->axq_qnum, txq->axq_link,
+ ito64(bf->bf_daddr), bf->bf_desc);
+ }
+ txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
+ ath9k_hw_txstart(ah, txq->axq_qnum);
}
-u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
{
- return sc->tx.txq[qnum].axq_aggr_depth;
+ struct ath_buf *bf = NULL;
+
+ spin_lock_bh(&sc->tx.txbuflock);
+
+ if (unlikely(list_empty(&sc->tx.txbuf))) {
+ spin_unlock_bh(&sc->tx.txbuflock);
+ return NULL;
+ }
+
+ bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+ list_del(&bf->list);
+
+ spin_unlock_bh(&sc->tx.txbuflock);
+
+ return bf;
}
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
+static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
+ struct list_head *bf_head,
+ struct ath_tx_control *txctl)
{
- struct ath_atx_tid *txtid;
+ struct ath_buf *bf;
- if (!(sc->sc_flags & SC_OP_TXAGGR))
- return false;
+ bf = list_first_entry(bf_head, struct ath_buf, list);
+ bf->bf_state.bf_type |= BUF_AMPDU;
- txtid = ATH_AN_2_TID(an, tidno);
+ /*
+ * Do not queue to h/w when any of the following conditions is true:
+ * - there are pending frames in software queue
+ * - the TID is currently paused for ADDBA/BAR request
+ * - seqno is not within block-ack window
+ * - h/w queue depth exceeds low water mark
+ */
+ if (!list_empty(&tid->buf_q) || tid->paused ||
+ !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
+ txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+ /*
+ * Add this frame to software queue for scheduling later
+ * for aggregation.
+ */
+ list_move_tail(&bf->list, &tid->buf_q);
+ ath_tx_queue_tid(txctl->txq, tid);
+ return;
+ }
- if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
- if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
- (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
- txtid->addba_exchangeattempts++;
+ /* Add sub-frame to BAW */
+ ath_tx_addto_baw(sc, tid, bf);
+
+ /* Queue to h/w without aggregation */
+ bf->bf_nframes = 1;
+ bf->bf_lastbf = bf;
+ ath_buf_set_rate(sc, bf);
+ ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
+}
+
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid,
+ struct list_head *bf_head)
+{
+ struct ath_buf *bf;
+
+ bf = list_first_entry(bf_head, struct ath_buf, list);
+ bf->bf_state.bf_type &= ~BUF_AMPDU;
+
+ /* update starting sequence number for subsequent ADDBA request */
+ INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+
+ bf->bf_nframes = 1;
+ bf->bf_lastbf = bf;
+ ath_buf_set_rate(sc, bf);
+ ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct list_head *bf_head)
+{
+ struct ath_buf *bf;
+
+ bf = list_first_entry(bf_head, struct ath_buf, list);
+
+ bf->bf_lastbf = bf;
+ bf->bf_nframes = 1;
+ ath_buf_set_rate(sc, bf);
+ ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+ enum ath9k_pkt_type htype;
+ __le16 fc;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+ fc = hdr->frame_control;
+
+ if (ieee80211_is_beacon(fc))
+ htype = ATH9K_PKT_TYPE_BEACON;
+ else if (ieee80211_is_probe_resp(fc))
+ htype = ATH9K_PKT_TYPE_PROBE_RESP;
+ else if (ieee80211_is_atim(fc))
+ htype = ATH9K_PKT_TYPE_ATIM;
+ else if (ieee80211_is_pspoll(fc))
+ htype = ATH9K_PKT_TYPE_PSPOLL;
+ else
+ htype = ATH9K_PKT_TYPE_NORMAL;
+
+ return htype;
+}
+
+static bool is_pae(struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+ fc = hdr->frame_control;
+
+ if (ieee80211_is_data(fc)) {
+ if (ieee80211_is_nullfunc(fc) ||
+ /* Port Access Entity (IEEE 802.1X) */
+ (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
return true;
}
}
@@ -2235,175 +1311,768 @@ bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
return false;
}
-/* Start TX aggregation */
+static int get_hw_crypto_keytype(struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
- u16 tid, u16 *ssn)
+ if (tx_info->control.hw_key) {
+ if (tx_info->control.hw_key->alg == ALG_WEP)
+ return ATH9K_KEY_TYPE_WEP;
+ else if (tx_info->control.hw_key->alg == ALG_TKIP)
+ return ATH9K_KEY_TYPE_TKIP;
+ else if (tx_info->control.hw_key->alg == ALG_CCMP)
+ return ATH9K_KEY_TYPE_AES;
+ }
+
+ return ATH9K_KEY_TYPE_CLEAR;
+}
+
+static void assign_aggr_tid_seqno(struct sk_buff *skb,
+ struct ath_buf *bf)
{
- struct ath_atx_tid *txtid;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr;
struct ath_node *an;
+ struct ath_atx_tid *tid;
+ __le16 fc;
+ u8 *qc;
- an = (struct ath_node *)sta->drv_priv;
+ if (!tx_info->control.sta)
+ return;
- if (sc->sc_flags & SC_OP_TXAGGR) {
- txtid = ATH_AN_2_TID(an, tid);
- txtid->state |= AGGR_ADDBA_PROGRESS;
- ath_tx_pause_tid(sc, txtid);
+ an = (struct ath_node *)tx_info->control.sta->drv_priv;
+ hdr = (struct ieee80211_hdr *)skb->data;
+ fc = hdr->frame_control;
+
+ if (ieee80211_is_data_qos(fc)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ bf->bf_tidno = qc[0] & 0xf;
}
- return 0;
+ /*
+ * For HT capable stations, we save tidno for later use.
+ * We also override seqno set by upper layer with the one
+ * in tx aggregation state.
+ *
+ * If fragmentation is on, the sequence number is
+ * not overridden, since it has been
+ * incremented by the fragmentation routine.
+ *
+ * FIXME: check if the fragmentation threshold exceeds
+ * IEEE80211 max.
+ */
+ tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
+ IEEE80211_SEQ_SEQ_SHIFT);
+ bf->bf_seqno = tid->seq_next;
+ INCR(tid->seq_next, IEEE80211_SEQ_MAX);
}
-/* Stop tx aggregation */
-
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
+ struct ath_txq *txq)
{
- struct ath_node *an = (struct ath_node *)sta->drv_priv;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ int flags = 0;
- ath_tx_aggr_teardown(sc, an, tid);
- return 0;
+ flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
+ flags |= ATH9K_TXDESC_INTREQ;
+
+ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
+ flags |= ATH9K_TXDESC_NOACK;
+
+ return flags;
}
-/* Resume tx aggregation */
+/*
+ * rix - rate index
+ * pktlen - total bytes (delims + data + fcs + pads + pad delims)
+ * width - 0 for 20 MHz, 1 for 40 MHz
+ * half_gi - to use 4us v/s 3.6 us for symbol time
+ */
+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
+ int width, int half_gi, bool shortPreamble)
+{
+ struct ath_rate_table *rate_table = sc->cur_rate_table;
+ u32 nbits, nsymbits, duration, nsymbols;
+ u8 rc;
+ int streams, pktlen;
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+ pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
+ rc = rate_table->info[rix].ratecode;
+
+ /* for legacy rates, use old function to compute packet duration */
+ if (!IS_HT_RATE(rc))
+ return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
+ rix, shortPreamble);
+
+ /* find number of symbols: PLCP + data */
+ nbits = (pktlen << 3) + OFDM_PLCP_BITS;
+ nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
+ nsymbols = (nbits + nsymbits - 1) / nsymbits;
+
+ if (!half_gi)
+ duration = SYMBOL_TIME(nsymbols);
+ else
+ duration = SYMBOL_TIME_HALFGI(nsymbols);
+
+ /* addup duration for legacy/ht training and signal fields */
+ streams = HT_RC_2_STREAMS(rc);
+ duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+
+ return duration;
+}
+
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_atx_tid *txtid;
- struct ath_node *an;
+ struct ath_rate_table *rt = sc->cur_rate_table;
+ struct ath9k_11n_rate_series series[4];
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_tx_rate *rates;
+ struct ieee80211_hdr *hdr;
+ int i, flags = 0;
+ u8 rix = 0, ctsrate = 0;
+ bool is_pspoll;
- an = (struct ath_node *)sta->drv_priv;
+ memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
- if (sc->sc_flags & SC_OP_TXAGGR) {
- txtid = ATH_AN_2_TID(an, tid);
- txtid->baw_size =
- IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
- txtid->state |= AGGR_ADDBA_COMPLETE;
- txtid->state &= ~AGGR_ADDBA_PROGRESS;
- ath_tx_resume_tid(sc, txtid);
+ skb = (struct sk_buff *)bf->bf_mpdu;
+ tx_info = IEEE80211_SKB_CB(skb);
+ rates = tx_info->control.rates;
+ hdr = (struct ieee80211_hdr *)skb->data;
+ is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
+
+ /*
+ * We check if Short Preamble is needed for the CTS rate by
+ * checking the BSS's global flag.
+ * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
+ */
+ if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+ ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode |
+ rt->info[tx_info->control.rts_cts_rate_idx].short_preamble;
+ else
+ ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode;
+
+ /*
+ * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
+ * Check the first rate in the series to decide whether RTS/CTS
+ * or CTS-to-self has to be used.
+ */
+ if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+ flags = ATH9K_TXDESC_CTSENA;
+ else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+ flags = ATH9K_TXDESC_RTSENA;
+
+ /* FIXME: Handle aggregation protection */
+ if (sc->config.ath_aggr_prot &&
+ (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
+ flags = ATH9K_TXDESC_RTSENA;
}
+
+ /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
+ if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
+ flags &= ~(ATH9K_TXDESC_RTSENA);
+
+ for (i = 0; i < 4; i++) {
+ if (!rates[i].count || (rates[i].idx < 0))
+ continue;
+
+ rix = rates[i].idx;
+ series[i].Tries = rates[i].count;
+ series[i].ChSel = sc->tx_chainmask;
+
+ if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ series[i].Rate = rt->info[rix].ratecode |
+ rt->info[rix].short_preamble;
+ else
+ series[i].Rate = rt->info[rix].ratecode;
+
+ if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+ series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+ if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ series[i].RateFlags |= ATH9K_RATESERIES_2040;
+ if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
+ series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
+
+ series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
+ (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
+ (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
+ (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE));
+ }
+
+ /* set dur_update_en for l-sig computation except for PS-Poll frames */
+ ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
+ bf->bf_lastbf->bf_desc,
+ !is_pspoll, ctsrate,
+ 0, series, 4, flags);
+
+ if (sc->config.ath_aggr_prot && flags)
+ ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
}
-/*
- * Performs transmit side cleanup when TID changes from aggregated to
- * unaggregated.
- * - Pause the TID and mark cleanup in progress
- * - Discard all retry frames from the s/w queue.
- */
+static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
+ struct sk_buff *skb,
+ struct ath_tx_control *txctl)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ath_tx_info_priv *tx_info_priv;
+ int hdrlen;
+ __le16 fc;
+
+ tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
+ if (unlikely(!tx_info_priv))
+ return -ENOMEM;
+ tx_info->rate_driver_data[0] = tx_info_priv;
+ tx_info_priv->aphy = aphy;
+ tx_info_priv->frame_type = txctl->frame_type;
+ hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ fc = hdr->frame_control;
+
+ ATH_TXBUF_RESET(bf);
+
+ bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
+
+ if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+ bf->bf_state.bf_type |= BUF_HT;
+
+ bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+
+ bf->bf_keytype = get_hw_crypto_keytype(skb);
+ if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
+ bf->bf_frmlen += tx_info->control.hw_key->icv_len;
+ bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
+ } else {
+ bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
+ }
+
+ if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
+ assign_aggr_tid_seqno(skb, bf);
+
+ bf->bf_mpdu = skb;
+
+ bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+ bf->bf_mpdu = NULL;
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "dma_mapping_error() on TX\n");
+ return -ENOMEM;
+ }
+
+ bf->bf_buf_addr = bf->bf_dmacontext;
+ return 0;
+}
-void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid)
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_control *txctl)
{
- struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
- struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
- struct ath_buf *bf;
+ struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ath_node *an = NULL;
struct list_head bf_head;
+ struct ath_desc *ds;
+ struct ath_atx_tid *tid;
+ struct ath_hw *ah = sc->sc_ah;
+ int frm_type;
+ __le16 fc;
+
+ frm_type = get_hw_packet_type(skb);
+ fc = hdr->frame_control;
+
INIT_LIST_HEAD(&bf_head);
+ list_add_tail(&bf->list, &bf_head);
- if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */
- return;
+ ds = bf->bf_desc;
+ ds->ds_link = 0;
+ ds->ds_data = bf->bf_buf_addr;
- if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
- txtid->addba_exchangeattempts = 0;
- return;
- }
+ ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
+ bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
- /* TID must be paused first */
- ath_tx_pause_tid(sc, txtid);
+ ath9k_hw_filltxdesc(ah, ds,
+ skb->len, /* segment length */
+ true, /* first segment */
+ true, /* last segment */
+ ds); /* first descriptor */
- /* drop all software retried frames and mark this TID */
- spin_lock_bh(&txq->axq_lock);
- while (!list_empty(&txtid->buf_q)) {
- bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
- if (!bf_isretried(bf)) {
+ spin_lock_bh(&txctl->txq->axq_lock);
+
+ if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
+ tx_info->control.sta) {
+ an = (struct ath_node *)tx_info->control.sta->drv_priv;
+ tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
+ if (!ieee80211_is_data_qos(fc)) {
+ ath_tx_send_normal(sc, txctl->txq, &bf_head);
+ goto tx_done;
+ }
+
+ if (ath_aggr_query(sc, an, bf->bf_tidno)) {
/*
- * NB: it's based on the assumption that
- * software retried frame will always stay
- * at the head of software queue.
+ * Try aggregation if it's a unicast data frame
+ * and the destination is HT capable.
*/
- break;
+ ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
+ } else {
+ /*
+ * Send this frame as regular when ADDBA
+ * exchange is neither complete nor pending.
+ */
+ ath_tx_send_ht_normal(sc, txctl->txq,
+ tid, &bf_head);
}
- list_cut_position(&bf_head,
- &txtid->buf_q, &bf->bf_lastfrm->list);
- ath_tx_update_baw(sc, txtid, bf->bf_seqno);
+ } else {
+ ath_tx_send_normal(sc, txctl->txq, &bf_head);
+ }
- /* complete this sub-frame */
- ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+tx_done:
+ spin_unlock_bh(&txctl->txq->axq_lock);
+}
+
+/* Upon failure caller should free skb */
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct ath_tx_control *txctl)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_buf *bf;
+ int r;
+
+ bf = ath_tx_get_buffer(sc);
+ if (!bf) {
+ DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
+ return -1;
}
- if (txtid->baw_head != txtid->baw_tail) {
- spin_unlock_bh(&txq->axq_lock);
- txtid->state |= AGGR_CLEANUP;
- } else {
- txtid->state &= ~AGGR_ADDBA_COMPLETE;
- txtid->addba_exchangeattempts = 0;
+ r = ath_tx_setup_buffer(hw, bf, skb, txctl);
+ if (unlikely(r)) {
+ struct ath_txq *txq = txctl->txq;
+
+ DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
+
+ /* upon ath_tx_processq() this TX queue will be resumed, we
+ * guarantee this will happen by knowing beforehand that
+ * we will at least have to run TX completionon one buffer
+ * on the queue */
+ spin_lock_bh(&txq->axq_lock);
+ if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
+ ieee80211_stop_queue(sc->hw,
+ skb_get_queue_mapping(skb));
+ txq->stopped = 1;
+ }
spin_unlock_bh(&txq->axq_lock);
- ath_tx_flush_tid(sc, txtid);
+
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_add_tail(&bf->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
+
+ return r;
}
-}
-/*
- * Tx scheduling logic
- * NB: must be called with txq lock held
- */
+ ath_tx_start_dma(sc, bf, txctl);
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+ return 0;
+}
+
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct ath_atx_ac *ac;
- struct ath_atx_tid *tid;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ int hdrlen, padsize;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_control txctl;
- /* nothing to schedule */
- if (list_empty(&txq->axq_acq))
- return;
- /*
- * get the first node/ac pair on the queue
- */
- ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
- list_del(&ac->list);
- ac->sched = false;
+ memset(&txctl, 0, sizeof(struct ath_tx_control));
/*
- * process a single tid per destination
+ * As a temporary workaround, assign seq# here; this will likely need
+ * to be cleaned up to work better with Beacon transmission and virtual
+ * BSSes.
*/
- do {
- /* nothing to schedule */
- if (list_empty(&ac->tid_q))
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+ sc->tx.seq_no += 0x10;
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+ }
+
+ /* Add the padding after the header if this is not already done */
+ hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ if (hdrlen & 3) {
+ padsize = hdrlen % 4;
+ if (skb_headroom(skb) < padsize) {
+ DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
+ dev_kfree_skb_any(skb);
return;
+ }
+ skb_push(skb, padsize);
+ memmove(skb->data, skb->data + padsize, hdrlen);
+ }
- tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
- list_del(&tid->list);
- tid->sched = false;
+ txctl.txq = sc->beacon.cabq;
- if (tid->paused) /* check next tid to keep h/w busy */
- continue;
+ DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
- if ((txq->axq_depth % 2) == 0)
- ath_tx_sched_aggr(sc, txq, tid);
+ if (ath_tx_start(hw, skb, &txctl) != 0) {
+ DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
+ goto exit;
+ }
+
+ return;
+exit:
+ dev_kfree_skb_any(skb);
+}
+
+/*****************/
+/* TX Completion */
+/*****************/
+
+static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
+ struct ath_xmit_status *tx_status)
+{
+ struct ieee80211_hw *hw = sc->hw;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+ int hdrlen, padsize;
+ int frame_type = ATH9K_NOT_INTERNAL;
+
+ DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
+
+ if (tx_info_priv) {
+ hw = tx_info_priv->aphy->hw;
+ frame_type = tx_info_priv->frame_type;
+ }
+
+ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
+ tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
+ kfree(tx_info_priv);
+ tx_info->rate_driver_data[0] = NULL;
+ }
+
+ if (tx_status->flags & ATH_TX_BAR) {
+ tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+ tx_status->flags &= ~ATH_TX_BAR;
+ }
+
+ if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
+ /* Frame was ACKed */
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
+ }
+
+ tx_info->status.rates[0].count = tx_status->retries + 1;
+ hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ padsize = hdrlen & 3;
+ if (padsize && hdrlen >= 24) {
/*
- * add tid to round-robin queue if more frames
- * are pending for the tid
+ * Remove MAC header padding before giving the frame back to
+ * mac80211.
*/
- if (!list_empty(&tid->buf_q))
- ath_tx_queue_tid(txq, tid);
+ memmove(skb->data + padsize, skb->data, hdrlen);
+ skb_pull(skb, padsize);
+ }
- /* only schedule one TID at a time */
- break;
- } while (!list_empty(&ac->tid_q));
+ if (frame_type == ATH9K_NOT_INTERNAL)
+ ieee80211_tx_status(hw, skb);
+ else
+ ath9k_tx_status(hw, skb);
+}
+
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+ struct list_head *bf_q,
+ int txok, int sendbar)
+{
+ struct sk_buff *skb = bf->bf_mpdu;
+ struct ath_xmit_status tx_status;
+ unsigned long flags;
/*
- * schedule AC if more TIDs need processing
+ * Set retry information.
+ * NB: Don't use the information in the descriptor, because the frame
+ * could be software retried.
*/
- if (!list_empty(&ac->tid_q)) {
+ tx_status.retries = bf->bf_retries;
+ tx_status.flags = 0;
+
+ if (sendbar)
+ tx_status.flags = ATH_TX_BAR;
+
+ if (!txok) {
+ tx_status.flags |= ATH_TX_ERROR;
+
+ if (bf_isxretried(bf))
+ tx_status.flags |= ATH_TX_XRETRY;
+ }
+
+ dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
+ ath_tx_complete(sc, skb, &tx_status);
+
+ /*
+ * Return the list of ath_buf of this mpdu to free queue
+ */
+ spin_lock_irqsave(&sc->tx.txbuflock, flags);
+ list_splice_tail_init(bf_q, &sc->tx.txbuf);
+ spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
+}
+
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+ int txok)
+{
+ struct ath_buf *bf_last = bf->bf_lastbf;
+ struct ath_desc *ds = bf_last->bf_desc;
+ u16 seq_st = 0;
+ u32 ba[WME_BA_BMP_SIZE >> 5];
+ int ba_index;
+ int nbad = 0;
+ int isaggr = 0;
+
+ if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
+ return 0;
+
+ isaggr = bf_isaggr(bf);
+ if (isaggr) {
+ seq_st = ATH_DS_BA_SEQ(ds);
+ memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
+ }
+
+ while (bf) {
+ ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
+ if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
+ nbad++;
+
+ bf = bf->bf_next;
+ }
+
+ return nbad;
+}
+
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad)
+{
+ struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+
+ tx_info_priv->update_rc = false;
+ if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
+ tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+
+ if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
+ (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
+ if (ieee80211_is_data(hdr->frame_control)) {
+ memcpy(&tx_info_priv->tx, &ds->ds_txstat,
+ sizeof(tx_info_priv->tx));
+ tx_info_priv->n_frames = bf->bf_nframes;
+ tx_info_priv->n_bad_frames = nbad;
+ tx_info_priv->update_rc = true;
+ }
+ }
+}
+
+static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+{
+ int qnum;
+
+ spin_lock_bh(&txq->axq_lock);
+ if (txq->stopped &&
+ sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
+ qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
+ if (qnum != -1) {
+ ieee80211_wake_queue(sc->hw, qnum);
+ txq->stopped = 0;
+ }
+ }
+ spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_buf *bf, *lastbf, *bf_held = NULL;
+ struct list_head bf_head;
+ struct ath_desc *ds;
+ int txok, nbad = 0;
+ int status;
+
+ DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
+ txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
+ txq->axq_link);
+
+ for (;;) {
+ spin_lock_bh(&txq->axq_lock);
+ if (list_empty(&txq->axq_q)) {
+ txq->axq_link = NULL;
+ txq->axq_linkbuf = NULL;
+ spin_unlock_bh(&txq->axq_lock);
+ break;
+ }
+ bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+
/*
- * add dest ac to txq if not already added
+ * There is a race condition that a BH gets scheduled
+ * after sw writes TxE and before hw re-load the last
+ * descriptor to get the newly chained one.
+ * Software must keep the last DONE descriptor as a
+ * holding descriptor - software does so by marking
+ * it with the STALE flag.
*/
- if (!ac->sched) {
- ac->sched = true;
- list_add_tail(&ac->list, &txq->axq_acq);
+ bf_held = NULL;
+ if (bf->bf_status & ATH_BUFSTATUS_STALE) {
+ bf_held = bf;
+ if (list_is_last(&bf_held->list, &txq->axq_q)) {
+ txq->axq_link = NULL;
+ txq->axq_linkbuf = NULL;
+ spin_unlock_bh(&txq->axq_lock);
+
+ /*
+ * The holding descriptor is the last
+ * descriptor in queue. It's safe to remove
+ * the last holding descriptor in BH context.
+ */
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_move_tail(&bf_held->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
+
+ break;
+ } else {
+ bf = list_entry(bf_held->list.next,
+ struct ath_buf, list);
+ }
}
+
+ lastbf = bf->bf_lastbf;
+ ds = lastbf->bf_desc;
+
+ status = ath9k_hw_txprocdesc(ah, ds);
+ if (status == -EINPROGRESS) {
+ spin_unlock_bh(&txq->axq_lock);
+ break;
+ }
+ if (bf->bf_desc == txq->axq_lastdsWithCTS)
+ txq->axq_lastdsWithCTS = NULL;
+ if (ds == txq->axq_gatingds)
+ txq->axq_gatingds = NULL;
+
+ /*
+ * Remove ath_buf's of the same transmit unit from txq,
+ * however leave the last descriptor back as the holding
+ * descriptor for hw.
+ */
+ lastbf->bf_status |= ATH_BUFSTATUS_STALE;
+ INIT_LIST_HEAD(&bf_head);
+ if (!list_is_singular(&lastbf->list))
+ list_cut_position(&bf_head,
+ &txq->axq_q, lastbf->list.prev);
+
+ txq->axq_depth--;
+ if (bf_isaggr(bf))
+ txq->axq_aggr_depth--;
+
+ txok = (ds->ds_txstat.ts_status == 0);
+ spin_unlock_bh(&txq->axq_lock);
+
+ if (bf_held) {
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_move_tail(&bf_held->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
+ }
+
+ if (!bf_isampdu(bf)) {
+ /*
+ * This frame is sent out as a single frame.
+ * Use hardware retry status for this frame.
+ */
+ bf->bf_retries = ds->ds_txstat.ts_longretry;
+ if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
+ bf->bf_state.bf_type |= BUF_XRETRY;
+ nbad = 0;
+ } else {
+ nbad = ath_tx_num_badfrms(sc, bf, txok);
+ }
+
+ ath_tx_rc_status(bf, ds, nbad);
+
+ if (bf_isampdu(bf))
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
+ else
+ ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
+
+ ath_wake_mac80211_queue(sc, txq);
+
+ spin_lock_bh(&txq->axq_lock);
+ if (sc->sc_flags & SC_OP_TXAGGR)
+ ath_txq_schedule(sc, txq);
+ spin_unlock_bh(&txq->axq_lock);
}
}
-/* Initialize per-node transmit state */
+
+void ath_tx_tasklet(struct ath_softc *sc)
+{
+ int i;
+ u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
+
+ ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
+
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+ if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
+ ath_tx_processq(sc, &sc->tx.txq[i]);
+ }
+}
+
+/*****************/
+/* Init, Cleanup */
+/*****************/
+
+int ath_tx_init(struct ath_softc *sc, int nbufs)
+{
+ int error = 0;
+
+ do {
+ spin_lock_init(&sc->tx.txbuflock);
+
+ error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
+ "tx", nbufs, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to allocate tx descriptors: %d\n",
+ error);
+ break;
+ }
+
+ error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
+ "beacon", ATH_BCBUF, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to allocate beacon descriptors: %d\n",
+ error);
+ break;
+ }
+
+ } while (0);
+
+ if (error != 0)
+ ath_tx_cleanup(sc);
+
+ return error;
+}
+
+int ath_tx_cleanup(struct ath_softc *sc)
+{
+ if (sc->beacon.bdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
+
+ if (sc->tx.txdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+
+ return 0;
+}
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
{
@@ -2411,9 +2080,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
struct ath_atx_ac *ac;
int tidno, acno;
- /*
- * Init per tid tx state
- */
for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID;
tidno++, tid++) {
@@ -2423,22 +2089,16 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
tid->baw_size = WME_MAX_BA;
tid->baw_head = tid->baw_tail = 0;
tid->sched = false;
- tid->paused = false;
+ tid->paused = false;
tid->state &= ~AGGR_CLEANUP;
INIT_LIST_HEAD(&tid->buf_q);
-
acno = TID_TO_WME_AC(tidno);
tid->ac = &an->ac[acno];
-
- /* ADDBA state */
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->state &= ~AGGR_ADDBA_PROGRESS;
tid->addba_exchangeattempts = 0;
}
- /*
- * Init per ac tx state
- */
for (acno = 0, ac = &an->ac[acno];
acno < WME_NUM_AC; acno++, ac++) {
ac->sched = false;
@@ -2465,14 +2125,13 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
}
}
-/* Cleanupthe pending buffers for the node. */
-
void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{
int i;
struct ath_atx_ac *ac, *ac_tmp;
struct ath_atx_tid *tid, *tid_tmp;
struct ath_txq *txq;
+
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) {
txq = &sc->tx.txq[i];
@@ -2503,51 +2162,3 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
}
}
}
-
-void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
-{
- int hdrlen, padsize;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ath_tx_control txctl;
-
- memset(&txctl, 0, sizeof(struct ath_tx_control));
-
- /*
- * As a temporary workaround, assign seq# here; this will likely need
- * to be cleaned up to work better with Beacon transmission and virtual
- * BSSes.
- */
- if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- sc->tx.seq_no += 0x10;
- hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
- }
-
- /* Add the padding after the header if this is not already done */
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- if (hdrlen & 3) {
- padsize = hdrlen % 4;
- if (skb_headroom(skb) < padsize) {
- DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
- dev_kfree_skb_any(skb);
- return;
- }
- skb_push(skb, padsize);
- memmove(skb->data, skb->data + padsize, hdrlen);
- }
-
- txctl.txq = sc->beacon.cabq;
-
- DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
-
- if (ath_tx_start(sc, skb, &txctl) != 0) {
- DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
- goto exit;
- }
-
- return;
-exit:
- dev_kfree_skb_any(skb);
-}
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 4223672c443..857d84148b1 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2,8 +2,8 @@
Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
- Copyright 2000-2001 ATMEL Corporation.
- Copyright 2003-2004 Simon Kelley.
+ Copyright 2000-2001 ATMEL Corporation.
+ Copyright 2003-2004 Simon Kelley.
This code was developed from version 2.1.1 of the Atmel drivers,
released by Atmel corp. under the GPL in December 2002. It also
@@ -89,15 +89,15 @@ static struct {
const char *fw_file;
const char *fw_file_ext;
} fw_table[] = {
- { ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
- { ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
- { ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
- { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
- { ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
- { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
- { ATMEL_FW_TYPE_504A_2958,"atmel_at76c504a_2958","bin" },
- { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
- { ATMEL_FW_TYPE_NONE, NULL, NULL }
+ { ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
+ { ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
+ { ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
+ { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
+ { ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
+ { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
+ { ATMEL_FW_TYPE_504A_2958, "atmel_at76c504a_2958", "bin" },
+ { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
+ { ATMEL_FW_TYPE_NONE, NULL, NULL }
};
#define MAX_SSID_LENGTH 32
@@ -106,60 +106,60 @@ static struct {
#define MAX_BSS_ENTRIES 64
/* registers */
-#define GCR 0x00 // (SIR0) General Configuration Register
-#define BSR 0x02 // (SIR1) Bank Switching Select Register
+#define GCR 0x00 /* (SIR0) General Configuration Register */
+#define BSR 0x02 /* (SIR1) Bank Switching Select Register */
#define AR 0x04
#define DR 0x08
-#define MR1 0x12 // Mirror Register 1
-#define MR2 0x14 // Mirror Register 2
-#define MR3 0x16 // Mirror Register 3
-#define MR4 0x18 // Mirror Register 4
+#define MR1 0x12 /* Mirror Register 1 */
+#define MR2 0x14 /* Mirror Register 2 */
+#define MR3 0x16 /* Mirror Register 3 */
+#define MR4 0x18 /* Mirror Register 4 */
#define GPR1 0x0c
#define GPR2 0x0e
#define GPR3 0x10
-//
-// Constants for the GCR register.
-//
-#define GCR_REMAP 0x0400 // Remap internal SRAM to 0
-#define GCR_SWRES 0x0080 // BIU reset (ARM and PAI are NOT reset)
-#define GCR_CORES 0x0060 // Core Reset (ARM and PAI are reset)
-#define GCR_ENINT 0x0002 // Enable Interrupts
-#define GCR_ACKINT 0x0008 // Acknowledge Interrupts
-
-#define BSS_SRAM 0x0200 // AMBA module selection --> SRAM
-#define BSS_IRAM 0x0100 // AMBA module selection --> IRAM
-//
-// Constants for the MR registers.
-//
-#define MAC_INIT_COMPLETE 0x0001 // MAC init has been completed
-#define MAC_BOOT_COMPLETE 0x0010 // MAC boot has been completed
-#define MAC_INIT_OK 0x0002 // MAC boot has been completed
+/*
+ * Constants for the GCR register.
+ */
+#define GCR_REMAP 0x0400 /* Remap internal SRAM to 0 */
+#define GCR_SWRES 0x0080 /* BIU reset (ARM and PAI are NOT reset) */
+#define GCR_CORES 0x0060 /* Core Reset (ARM and PAI are reset) */
+#define GCR_ENINT 0x0002 /* Enable Interrupts */
+#define GCR_ACKINT 0x0008 /* Acknowledge Interrupts */
+
+#define BSS_SRAM 0x0200 /* AMBA module selection --> SRAM */
+#define BSS_IRAM 0x0100 /* AMBA module selection --> IRAM */
+/*
+ *Constants for the MR registers.
+ */
+#define MAC_INIT_COMPLETE 0x0001 /* MAC init has been completed */
+#define MAC_BOOT_COMPLETE 0x0010 /* MAC boot has been completed */
+#define MAC_INIT_OK 0x0002 /* MAC boot has been completed */
#define MIB_MAX_DATA_BYTES 212
#define MIB_HEADER_SIZE 4 /* first four fields */
struct get_set_mib {
- u8 type;
- u8 size;
- u8 index;
- u8 reserved;
- u8 data[MIB_MAX_DATA_BYTES];
+ u8 type;
+ u8 size;
+ u8 index;
+ u8 reserved;
+ u8 data[MIB_MAX_DATA_BYTES];
};
struct rx_desc {
- u32 Next;
- u16 MsduPos;
- u16 MsduSize;
-
- u8 State;
- u8 Status;
- u8 Rate;
- u8 Rssi;
- u8 LinkQuality;
- u8 PreambleType;
- u16 Duration;
- u32 RxTime;
+ u32 Next;
+ u16 MsduPos;
+ u16 MsduSize;
+
+ u8 State;
+ u8 Status;
+ u8 Rate;
+ u8 Rssi;
+ u8 LinkQuality;
+ u8 PreambleType;
+ u16 Duration;
+ u32 RxTime;
};
#define RX_DESC_FLAG_VALID 0x80
@@ -192,7 +192,7 @@ struct tx_desc {
u8 KeyIndex;
u8 ChiperType;
u8 ChipreLength;
- u8 Reserved1;
+ u8 Reserved1;
u8 Reserved;
u8 PacketType;
@@ -212,9 +212,9 @@ struct tx_desc {
#define TX_DESC_PACKET_TYPE_OFFSET 17
#define TX_DESC_HOST_LENGTH_OFFSET 18
-///////////////////////////////////////////////////////
-// Host-MAC interface
-///////////////////////////////////////////////////////
+/*
+ * Host-MAC interface
+ */
#define TX_STATUS_SUCCESS 0x00
@@ -226,14 +226,14 @@ struct tx_desc {
#define TX_PACKET_TYPE_DATA 0x01
#define TX_PACKET_TYPE_MGMT 0x02
-#define ISR_EMPTY 0x00 // no bits set in ISR
-#define ISR_TxCOMPLETE 0x01 // packet transmitted
-#define ISR_RxCOMPLETE 0x02 // packet received
-#define ISR_RxFRAMELOST 0x04 // Rx Frame lost
-#define ISR_FATAL_ERROR 0x08 // Fatal error
-#define ISR_COMMAND_COMPLETE 0x10 // command completed
-#define ISR_OUT_OF_RANGE 0x20 // command completed
-#define ISR_IBSS_MERGE 0x40 // (4.1.2.30): IBSS merge
+#define ISR_EMPTY 0x00 /* no bits set in ISR */
+#define ISR_TxCOMPLETE 0x01 /* packet transmitted */
+#define ISR_RxCOMPLETE 0x02 /* packet received */
+#define ISR_RxFRAMELOST 0x04 /* Rx Frame lost */
+#define ISR_FATAL_ERROR 0x08 /* Fatal error */
+#define ISR_COMMAND_COMPLETE 0x10 /* command completed */
+#define ISR_OUT_OF_RANGE 0x20 /* command completed */
+#define ISR_IBSS_MERGE 0x40 /* (4.1.2.30): IBSS merge */
#define ISR_GENERIC_IRQ 0x80
#define Local_Mib_Type 0x01
@@ -311,22 +311,22 @@ struct tx_desc {
#define MAX_ENCRYPTION_KEYS 4
#define MAX_ENCRYPTION_KEY_SIZE 40
-///////////////////////////////////////////////////////////////////////////
-// 802.11 related definitions
-///////////////////////////////////////////////////////////////////////////
+/*
+ * 802.11 related definitions
+ */
-//
-// Regulatory Domains
-//
+/*
+ * Regulatory Domains
+ */
-#define REG_DOMAIN_FCC 0x10 //Channels 1-11 USA
-#define REG_DOMAIN_DOC 0x20 //Channel 1-11 Canada
-#define REG_DOMAIN_ETSI 0x30 //Channel 1-13 Europe (ex Spain/France)
-#define REG_DOMAIN_SPAIN 0x31 //Channel 10-11 Spain
-#define REG_DOMAIN_FRANCE 0x32 //Channel 10-13 France
-#define REG_DOMAIN_MKK 0x40 //Channel 14 Japan
-#define REG_DOMAIN_MKK1 0x41 //Channel 1-14 Japan(MKK1)
-#define REG_DOMAIN_ISRAEL 0x50 //Channel 3-9 ISRAEL
+#define REG_DOMAIN_FCC 0x10 /* Channels 1-11 USA */
+#define REG_DOMAIN_DOC 0x20 /* Channel 1-11 Canada */
+#define REG_DOMAIN_ETSI 0x30 /* Channel 1-13 Europe (ex Spain/France) */
+#define REG_DOMAIN_SPAIN 0x31 /* Channel 10-11 Spain */
+#define REG_DOMAIN_FRANCE 0x32 /* Channel 10-13 France */
+#define REG_DOMAIN_MKK 0x40 /* Channel 14 Japan */
+#define REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan(MKK1) */
+#define REG_DOMAIN_ISRAEL 0x50 /* Channel 3-9 ISRAEL */
#define BSS_TYPE_AD_HOC 1
#define BSS_TYPE_INFRASTRUCTURE 2
@@ -364,13 +364,13 @@ struct tx_desc {
#define CIPHER_SUITE_CCX 4
#define CIPHER_SUITE_WEP_128 5
-//
-// IFACE MACROS & definitions
-//
-//
+/*
+ * IFACE MACROS & definitions
+ */
-// FuncCtrl field:
-//
+/*
+ * FuncCtrl field:
+ */
#define FUNC_CTRL_TxENABLE 0x10
#define FUNC_CTRL_RxENABLE 0x20
#define FUNC_CTRL_INIT_COMPLETE 0x01
@@ -378,48 +378,48 @@ struct tx_desc {
/* A stub firmware image which reads the MAC address from NVRAM on the card.
For copyright information and source see the end of this file. */
static u8 mac_reader[] = {
- 0x06,0x00,0x00,0xea,0x04,0x00,0x00,0xea,0x03,0x00,0x00,0xea,0x02,0x00,0x00,0xea,
- 0x01,0x00,0x00,0xea,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xea,0xfe,0xff,0xff,0xea,
- 0xd3,0x00,0xa0,0xe3,0x00,0xf0,0x21,0xe1,0x0e,0x04,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
- 0x81,0x11,0xa0,0xe1,0x00,0x10,0x81,0xe3,0x00,0x10,0x80,0xe5,0x1c,0x10,0x90,0xe5,
- 0x10,0x10,0xc1,0xe3,0x1c,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,0x08,0x10,0x80,0xe5,
- 0x02,0x03,0xa0,0xe3,0x00,0x10,0xa0,0xe3,0xb0,0x10,0xc0,0xe1,0xb4,0x10,0xc0,0xe1,
- 0xb8,0x10,0xc0,0xe1,0xbc,0x10,0xc0,0xe1,0x56,0xdc,0xa0,0xe3,0x21,0x00,0x00,0xeb,
- 0x0a,0x00,0xa0,0xe3,0x1a,0x00,0x00,0xeb,0x10,0x00,0x00,0xeb,0x07,0x00,0x00,0xeb,
- 0x02,0x03,0xa0,0xe3,0x02,0x14,0xa0,0xe3,0xb4,0x10,0xc0,0xe1,0x4c,0x10,0x9f,0xe5,
- 0xbc,0x10,0xc0,0xe1,0x10,0x10,0xa0,0xe3,0xb8,0x10,0xc0,0xe1,0xfe,0xff,0xff,0xea,
- 0x00,0x40,0x2d,0xe9,0x00,0x20,0xa0,0xe3,0x02,0x3c,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
- 0x28,0x00,0x9f,0xe5,0x37,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
- 0x00,0x40,0x2d,0xe9,0x12,0x2e,0xa0,0xe3,0x06,0x30,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
- 0x02,0x04,0xa0,0xe3,0x2f,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
- 0x00,0x02,0x00,0x02,0x80,0x01,0x90,0xe0,0x01,0x00,0x00,0x0a,0x01,0x00,0x50,0xe2,
- 0xfc,0xff,0xff,0xea,0x1e,0xff,0x2f,0xe1,0x80,0x10,0xa0,0xe3,0xf3,0x06,0xa0,0xe3,
- 0x00,0x10,0x80,0xe5,0x00,0x10,0xa0,0xe3,0x00,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,
- 0x04,0x10,0x80,0xe5,0x00,0x10,0x80,0xe5,0x0e,0x34,0xa0,0xe3,0x1c,0x10,0x93,0xe5,
- 0x02,0x1a,0x81,0xe3,0x1c,0x10,0x83,0xe5,0x58,0x11,0x9f,0xe5,0x30,0x10,0x80,0xe5,
- 0x54,0x11,0x9f,0xe5,0x34,0x10,0x80,0xe5,0x38,0x10,0x80,0xe5,0x3c,0x10,0x80,0xe5,
- 0x10,0x10,0x90,0xe5,0x08,0x00,0x90,0xe5,0x1e,0xff,0x2f,0xe1,0xf3,0x16,0xa0,0xe3,
- 0x08,0x00,0x91,0xe5,0x05,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,0x10,0x00,0x91,0xe5,
- 0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0xff,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,
- 0x10,0x00,0x91,0xe5,0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
- 0x10,0x00,0x91,0xe5,0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
- 0xff,0x00,0x00,0xe2,0x1e,0xff,0x2f,0xe1,0x30,0x40,0x2d,0xe9,0x00,0x50,0xa0,0xe1,
- 0x03,0x40,0xa0,0xe1,0xa2,0x02,0xa0,0xe1,0x08,0x00,0x00,0xe2,0x03,0x00,0x80,0xe2,
- 0xd8,0x10,0x9f,0xe5,0x00,0x00,0xc1,0xe5,0x01,0x20,0xc1,0xe5,0xe2,0xff,0xff,0xeb,
- 0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x1a,0x14,0x00,0xa0,0xe3,0xc4,0xff,0xff,0xeb,
- 0x04,0x20,0xa0,0xe1,0x05,0x10,0xa0,0xe1,0x02,0x00,0xa0,0xe3,0x01,0x00,0x00,0xeb,
- 0x30,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x70,0x40,0x2d,0xe9,0xf3,0x46,0xa0,0xe3,
- 0x00,0x30,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x08,0x00,0x00,0x9a,0x8c,0x50,0x9f,0xe5,
- 0x03,0x60,0xd5,0xe7,0x0c,0x60,0x84,0xe5,0x10,0x60,0x94,0xe5,0x02,0x00,0x16,0xe3,
- 0xfc,0xff,0xff,0x0a,0x01,0x30,0x83,0xe2,0x00,0x00,0x53,0xe1,0xf7,0xff,0xff,0x3a,
- 0xff,0x30,0xa0,0xe3,0x0c,0x30,0x84,0xe5,0x08,0x00,0x94,0xe5,0x10,0x00,0x94,0xe5,
- 0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x94,0xe5,0x00,0x00,0xa0,0xe3,
- 0x00,0x00,0x52,0xe3,0x0b,0x00,0x00,0x9a,0x10,0x50,0x94,0xe5,0x02,0x00,0x15,0xe3,
- 0xfc,0xff,0xff,0x0a,0x0c,0x30,0x84,0xe5,0x10,0x50,0x94,0xe5,0x01,0x00,0x15,0xe3,
- 0xfc,0xff,0xff,0x0a,0x08,0x50,0x94,0xe5,0x01,0x50,0xc1,0xe4,0x01,0x00,0x80,0xe2,
- 0x02,0x00,0x50,0xe1,0xf3,0xff,0xff,0x3a,0xc8,0x00,0xa0,0xe3,0x98,0xff,0xff,0xeb,
- 0x70,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x01,0x0c,0x00,0x02,0x01,0x02,0x00,0x02,
- 0x00,0x01,0x00,0x02
+ 0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
+ 0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
+ 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+ 0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
+ 0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
+ 0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
+ 0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
+ 0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
+ 0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
+ 0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
+ 0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+ 0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+ 0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
+ 0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
+ 0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
+ 0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
+ 0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
+ 0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
+ 0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
+ 0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
+ 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
+ 0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
+ 0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
+ 0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
+ 0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
+ 0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
+ 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
+ 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
+ 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
+ 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
+ 0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
+ 0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
+ 0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
+ 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
+ 0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
+ 0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
+ 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
+ 0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
+ 0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
+ 0x00, 0x01, 0x00, 0x02
};
struct atmel_private {
@@ -433,7 +433,7 @@ struct atmel_private {
struct net_device *dev;
struct device *sys_dev;
struct iw_statistics wstats;
- spinlock_t irqlock, timerlock; // spinlocks
+ spinlock_t irqlock, timerlock; /* spinlocks */
enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
enum {
CARD_TYPE_PARALLEL_FLASH,
@@ -541,7 +541,7 @@ struct atmel_private {
u8 rx_buf[MAX_WIRELESS_BODY];
};
-static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
+static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
static const struct {
int reg_domain;
@@ -1283,17 +1283,17 @@ static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
static int atmel_change_mtu(struct net_device *dev, int new_mtu)
{
- if ((new_mtu < 68) || (new_mtu > 2312))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
+ if ((new_mtu < 68) || (new_mtu > 2312))
+ return -EINVAL;
+ dev->mtu = new_mtu;
+ return 0;
}
static int atmel_set_mac_address(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
- memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
+ memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
return atmel_open(dev);
}
@@ -1420,10 +1420,17 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
priv->firmware_id);
switch (priv->card_type) {
- case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
- case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
- case CARD_TYPE_EEPROM: c = "EEPROM"; break;
- default: c = "<unknown>";
+ case CARD_TYPE_PARALLEL_FLASH:
+ c = "Parallel flash";
+ break;
+ case CARD_TYPE_SPI_FLASH:
+ c = "SPI flash\n";
+ break;
+ case CARD_TYPE_EEPROM:
+ c = "EEPROM";
+ break;
+ default:
+ c = "<unknown>";
}
r = "<unknown>";
@@ -1439,16 +1446,33 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
priv->use_wpa ? "Yes" : "No");
}
- switch(priv->station_state) {
- case STATION_STATE_SCANNING: s = "Scanning"; break;
- case STATION_STATE_JOINNING: s = "Joining"; break;
- case STATION_STATE_AUTHENTICATING: s = "Authenticating"; break;
- case STATION_STATE_ASSOCIATING: s = "Associating"; break;
- case STATION_STATE_READY: s = "Ready"; break;
- case STATION_STATE_REASSOCIATING: s = "Reassociating"; break;
- case STATION_STATE_MGMT_ERROR: s = "Management error"; break;
- case STATION_STATE_DOWN: s = "Down"; break;
- default: s = "<unknown>";
+ switch (priv->station_state) {
+ case STATION_STATE_SCANNING:
+ s = "Scanning";
+ break;
+ case STATION_STATE_JOINNING:
+ s = "Joining";
+ break;
+ case STATION_STATE_AUTHENTICATING:
+ s = "Authenticating";
+ break;
+ case STATION_STATE_ASSOCIATING:
+ s = "Associating";
+ break;
+ case STATION_STATE_READY:
+ s = "Ready";
+ break;
+ case STATION_STATE_REASSOCIATING:
+ s = "Reassociating";
+ break;
+ case STATION_STATE_MGMT_ERROR:
+ s = "Management error";
+ break;
+ case STATION_STATE_DOWN:
+ s = "Down";
+ break;
+ default:
+ s = "<unknown>";
}
p += sprintf(p, "Current state:\t\t%s\n", s);
@@ -1458,16 +1482,30 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
static int atmel_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- struct atmel_private *priv = data;
+ struct atmel_private *priv = data;
int len = atmel_proc_output (page, priv);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ if (len <= off+count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
}
+static const struct net_device_ops atmel_netdev_ops = {
+ .ndo_open = atmel_open,
+ .ndo_stop = atmel_close,
+ .ndo_change_mtu = atmel_change_mtu,
+ .ndo_set_mac_address = atmel_set_mac_address,
+ .ndo_start_xmit = start_tx,
+ .ndo_do_ioctl = atmel_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
const AtmelFWType fw_type,
struct device *sys_dev,
@@ -1479,11 +1517,11 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
int rc;
/* Create the network device object. */
- dev = alloc_etherdev(sizeof(*priv));
- if (!dev) {
+ dev = alloc_etherdev(sizeof(*priv));
+ if (!dev) {
printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
return NULL;
- }
+ }
if (dev_alloc_name(dev, dev->name) < 0) {
printk(KERN_ERR "atmel: Couldn't get name!\n");
goto err_out_free;
@@ -1552,13 +1590,8 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
priv->management_timer.function = atmel_management_timer;
priv->management_timer.data = (unsigned long) dev;
- dev->open = atmel_open;
- dev->stop = atmel_close;
- dev->change_mtu = atmel_change_mtu;
- dev->set_mac_address = atmel_set_mac_address;
- dev->hard_start_xmit = start_tx;
- dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def;
- dev->do_ioctl = atmel_ioctl;
+ dev->netdev_ops = &atmel_netdev_ops;
+ dev->wireless_handlers = &atmel_handler_def;
dev->irq = irq;
dev->base_addr = port;
@@ -1577,7 +1610,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
if (register_netdev(dev))
goto err_out_res;
- if (!probe_atmel_card(dev)){
+ if (!probe_atmel_card(dev)) {
unregister_netdev(dev);
goto err_out_res;
}
@@ -1594,7 +1627,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
return dev;
err_out_res:
- release_region( dev->base_addr, 32);
+ release_region(dev->base_addr, 32);
err_out_irq:
free_irq(dev->irq, dev);
err_out_free:
@@ -1632,7 +1665,7 @@ static int atmel_set_essid(struct net_device *dev,
struct atmel_private *priv = netdev_priv(dev);
/* Check if we asked for `any' */
- if(dwrq->flags == 0) {
+ if (dwrq->flags == 0) {
priv->connect_to_any_BSS = 1;
} else {
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
@@ -1768,7 +1801,7 @@ static int atmel_set_encode(struct net_device *dev,
}
if (dwrq->flags & IW_ENCODE_RESTRICTED)
priv->exclude_unencrypted = 1;
- if(dwrq->flags & IW_ENCODE_OPEN)
+ if (dwrq->flags & IW_ENCODE_OPEN)
priv->exclude_unencrypted = 0;
return -EINPROGRESS; /* Call commit handler */
@@ -1797,7 +1830,7 @@ static int atmel_get_encode(struct net_device *dev,
/* Copy the key to the user buffer */
dwrq->length = priv->wep_key_len[index];
if (dwrq->length > 16) {
- dwrq->length=0;
+ dwrq->length = 0;
} else {
memset(extra, 0, 16);
memcpy(extra, priv->wep_keys[index], dwrq->length);
@@ -2013,11 +2046,20 @@ static int atmel_set_rate(struct net_device *dev,
} else {
/* Setting by frequency value */
switch (vwrq->value) {
- case 1000000: priv->tx_rate = 0; break;
- case 2000000: priv->tx_rate = 1; break;
- case 5500000: priv->tx_rate = 2; break;
- case 11000000: priv->tx_rate = 3; break;
- default: return -EINVAL;
+ case 1000000:
+ priv->tx_rate = 0;
+ break;
+ case 2000000:
+ priv->tx_rate = 1;
+ break;
+ case 5500000:
+ priv->tx_rate = 2;
+ break;
+ case 11000000:
+ priv->tx_rate = 3;
+ break;
+ default:
+ return -EINVAL;
}
}
}
@@ -2062,11 +2104,19 @@ static int atmel_get_rate(struct net_device *dev,
vwrq->value = 11000000;
} else {
vwrq->fixed = 1;
- switch(priv->tx_rate) {
- case 0: vwrq->value = 1000000; break;
- case 1: vwrq->value = 2000000; break;
- case 2: vwrq->value = 5500000; break;
- case 3: vwrq->value = 11000000; break;
+ switch (priv->tx_rate) {
+ case 0:
+ vwrq->value = 1000000;
+ break;
+ case 1:
+ vwrq->value = 2000000;
+ break;
+ case 2:
+ vwrq->value = 5500000;
+ break;
+ case 3:
+ vwrq->value = 11000000;
+ break;
}
}
return 0;
@@ -2204,9 +2254,6 @@ static int atmel_get_frag(struct net_device *dev,
return 0;
}
-static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
static int atmel_set_freq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *fwrq,
@@ -2216,16 +2263,12 @@ static int atmel_set_freq(struct net_device *dev,
int rc = -EINPROGRESS; /* Call commit handler */
/* If setting by frequency, convert to a channel */
- if ((fwrq->e == 1) &&
- (fwrq->m >= (int) 241200000) &&
- (fwrq->m <= (int) 248700000)) {
+ if (fwrq->e == 1) {
int f = fwrq->m / 100000;
- int c = 0;
- while ((c < 14) && (f != frequency_list[c]))
- c++;
+
/* Hack to fall through... */
fwrq->e = 0;
- fwrq->m = c + 1;
+ fwrq->m = ieee80211_freq_to_dsss_chan(f);
}
/* Setting by channel number */
if ((fwrq->m > 1000) || (fwrq->e > 0))
@@ -2384,8 +2427,11 @@ static int atmel_get_range(struct net_device *dev,
if (range->num_channels != 0) {
for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
range->freq[k].i = i; /* List index */
- range->freq[k].m = frequency_list[i - 1] * 100000;
- range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
+
+ /* Values in MHz -> * 10^5 * 10 */
+ range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) *
+ 100000);
+ range->freq[k++].e = 1;
}
range->num_frequency = k;
}
@@ -2580,8 +2626,7 @@ static const struct iw_priv_args atmel_private_args[] = {
},
};
-static const struct iw_handler_def atmel_handler_def =
-{
+static const struct iw_handler_def atmel_handler_def = {
.num_standard = ARRAY_SIZE(atmel_handler),
.num_private = ARRAY_SIZE(atmel_private_handler),
.num_private_args = ARRAY_SIZE(atmel_private_args),
@@ -2838,7 +2883,7 @@ static void send_authentication_request(struct atmel_private *priv, u16 system,
if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
/* no WEP for authentication frames with TrSeqNo 1 */
- header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+ header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
auth.alg = cpu_to_le16(system);
@@ -2973,7 +3018,7 @@ static void store_bss_info(struct atmel_private *priv,
if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
index = i;
- /* If we process a probe and an entry from this BSS exists
+ /* If we process a probe and an entry from this BSS exists
we will update the BSS entry with the info from this BSS.
If we process a beacon we will only update RSSI */
@@ -2999,7 +3044,7 @@ static void store_bss_info(struct atmel_private *priv,
if (capability & WLAN_CAPABILITY_IBSS)
priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
else if (capability & WLAN_CAPABILITY_ESS)
- priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
+ priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
SHORT_PREAMBLE : LONG_PREAMBLE;
@@ -3046,7 +3091,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
}
if (should_associate) {
- if(priv->station_was_associated) {
+ if (priv->station_was_associated) {
atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
send_association_request(priv, 1);
return;
@@ -3067,8 +3112,8 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
priv->exclude_unencrypted = 1;
send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
return;
- } else if ( system == WLAN_AUTH_SHARED_KEY
- && priv->wep_is_on) {
+ } else if (system == WLAN_AUTH_SHARED_KEY
+ && priv->wep_is_on) {
priv->CurrentAuthentTransactionSeqNum = 0x001;
priv->exclude_unencrypted = 0;
send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
@@ -3256,11 +3301,11 @@ static void smooth_rssi(struct atmel_private *priv, u8 rssi)
u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
switch (priv->firmware_type) {
- case ATMEL_FW_TYPE_502E:
- max_rssi = 63; /* 502-rmfd-reve max by experiment */
- break;
- default:
- break;
+ case ATMEL_FW_TYPE_502E:
+ max_rssi = 63; /* 502-rmfd-reve max by experiment */
+ break;
+ default:
+ break;
}
rssi = rssi * 100 / max_rssi;
@@ -3477,8 +3522,7 @@ static void atmel_command_irq(struct atmel_private *priv)
status == CMD_STATUS_IN_PROGRESS)
return;
- switch (command){
-
+ switch (command) {
case CMD_Start:
if (status == CMD_STATUS_COMPLETE) {
priv->station_was_associated = priv->station_is_associated;
@@ -3713,7 +3757,7 @@ static int probe_atmel_card(struct net_device *dev)
if (rc) {
if (dev->dev_addr[0] == 0xFF) {
- u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
+ u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00};
printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
memcpy(dev->dev_addr, default_mac, 6);
}
@@ -3807,7 +3851,7 @@ static void build_wpa_mib(struct atmel_private *priv)
} else {
mib.group_key = i;
priv->group_cipher_suite = priv->pairwise_cipher_suite;
- mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
+ mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
}
}
@@ -3917,7 +3961,7 @@ static int reset_atmel_card(struct net_device *dev)
len = fw_entry->size;
}
- if (len <= 0x6000) {
+ if (len <= 0x6000) {
atmel_write16(priv->dev, BSR, BSS_IRAM);
atmel_copy_to_card(priv->dev, 0, fw, len);
atmel_set_gcr(priv->dev, GCR_REMAP);
@@ -3946,7 +3990,7 @@ static int reset_atmel_card(struct net_device *dev)
priv->use_wpa = (priv->host_info.major_version == 4);
priv->radio_on_broken = (priv->host_info.major_version == 5);
- /* unmask all irq sources */
+ /* unmask all irq sources */
atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
/* int Tx system and enable Tx */
@@ -3979,7 +4023,7 @@ static int reset_atmel_card(struct net_device *dev)
CMD_STATUS_REJECTED_RADIO_OFF) {
printk(KERN_INFO "%s: cannot turn the radio on.\n",
dev->name);
- return -EIO;
+ return -EIO;
}
}
@@ -4003,8 +4047,7 @@ static int reset_atmel_card(struct net_device *dev)
else
build_wep_mib(priv);
- if (old_state == STATION_STATE_READY)
- {
+ if (old_state == STATION_STATE_READY) {
union iwreq_data wrqu;
wrqu.data.length = 0;
@@ -4281,24 +4324,24 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
.set NVRAM_LENGTH, 0x0200
.set MAC_ADDRESS_MIB, SRAM_BASE
.set MAC_ADDRESS_LENGTH, 6
- .set MAC_BOOT_FLAG, 0x10
+ .set MAC_BOOT_FLAG, 0x10
.set MR1, 0
.set MR2, 4
.set MR3, 8
.set MR4, 0xC
RESET_VECTOR:
- b RESET_HANDLER
+ b RESET_HANDLER
UNDEF_VECTOR:
- b HALT1
+ b HALT1
SWI_VECTOR:
- b HALT1
+ b HALT1
IABORT_VECTOR:
- b HALT1
+ b HALT1
DABORT_VECTOR:
RESERVED_VECTOR:
- b HALT1
+ b HALT1
IRQ_VECTOR:
- b HALT1
+ b HALT1
FIQ_VECTOR:
b HALT1
HALT1: b HALT1
@@ -4310,7 +4353,7 @@ RESET_HANDLER:
ldr r0, =SPI_CGEN_BASE
mov r1, #0
mov r1, r1, lsl #3
- orr r1,r1, #0
+ orr r1, r1, #0
str r1, [r0]
ldr r1, [r0, #28]
bic r1, r1, #16
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 1f81d36f87c..aab71a70ba7 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -110,10 +110,18 @@ config B43_DEBUG
bool "Broadcom 43xx debugging"
depends on B43
---help---
- Broadcom 43xx debugging messages.
+ Broadcom 43xx debugging.
- Say Y, if you want to find out why the driver does not
- work for you.
+ This adds additional runtime sanity checks and statistics to the driver.
+ These checks and statistics might me expensive and hurt runtime performance
+ of your system.
+ This also adds the b43 debugfs interface.
+
+ Do not enable this, unless you are debugging the driver.
+
+ Say N, if you are a distributor or user building a release kernel
+ for production use.
+ Only say Y, if you are debugging a problem in the b43 driver sourcecode.
config B43_FORCE_PIO
bool "Force usage of PIO instead of DMA"
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 14a02b3aea5..281ef831035 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -6,6 +6,7 @@ b43-y += phy_g.o
b43-y += phy_a.o
b43-$(CONFIG_B43_NPHY) += phy_n.o
b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
+b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o
b43-y += sysfs.o
b43-y += xmit.o
b43-y += lo.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index a53c378e748..beaf18d6e8a 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -120,6 +120,9 @@
#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
#define B43_MMIO_POWERUP_DELAY 0x6A8
+#define B43_MMIO_BTCOEX_CTL 0x6B4 /* Bluetooth Coexistence Control */
+#define B43_MMIO_BTCOEX_STAT 0x6B6 /* Bluetooth Coexistence Status */
+#define B43_MMIO_BTCOEX_TXCTL 0x6B8 /* Bluetooth Coexistence Transmit Control */
/* SPROM boardflags_lo values */
#define B43_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
@@ -547,9 +550,6 @@ struct b43_noise_calculation {
struct b43_stats {
u8 link_noise;
- /* Store the last TX/RX times here for updating the leds. */
- unsigned long last_tx;
- unsigned long last_rx;
};
struct b43_key {
@@ -655,10 +655,39 @@ struct b43_wl {
struct work_struct txpower_adjust_work;
};
+/* The type of the firmware file. */
+enum b43_firmware_file_type {
+ B43_FWTYPE_PROPRIETARY,
+ B43_FWTYPE_OPENSOURCE,
+ B43_NR_FWTYPES,
+};
+
+/* Context data for fetching firmware. */
+struct b43_request_fw_context {
+ /* The device we are requesting the fw for. */
+ struct b43_wldev *dev;
+ /* The type of firmware to request. */
+ enum b43_firmware_file_type req_type;
+ /* Error messages for each firmware type. */
+ char errors[B43_NR_FWTYPES][128];
+ /* Temporary buffer for storing the firmware name. */
+ char fwname[64];
+ /* A fatal error occured while requesting. Firmware reqest
+ * can not continue, as any other reqest will also fail. */
+ int fatal_failure;
+};
+
/* In-memory representation of a cached microcode file. */
struct b43_firmware_file {
const char *filename;
const struct firmware *data;
+ /* Type of the firmware file name. Note that this does only indicate
+ * the type by the firmware name. NOT the file contents.
+ * If you want to check for proprietary vs opensource, use (struct b43_firmware)->opensource
+ * instead! The (struct b43_firmware)->opensource flag is derived from the actual firmware
+ * binary code, not just the filename.
+ */
+ enum b43_firmware_file_type type;
};
/* Pointers to the firmware data and meta information about it. */
@@ -677,7 +706,8 @@ struct b43_firmware {
/* Firmware patchlevel */
u16 patch;
- /* Set to true, if we are using an opensource firmware. */
+ /* Set to true, if we are using an opensource firmware.
+ * Use this to check for proprietary vs opensource. */
bool opensource;
/* Set to true, if the core needs a PCM firmware, but
* we failed to load one. This is always false for
@@ -848,12 +878,9 @@ void b43err(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
void b43warn(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
-#if B43_DEBUG
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
-#else /* DEBUG */
-# define b43dbg(wl, fmt...) do { /* nothing */ } while (0)
-#endif /* DEBUG */
+
/* A WARN_ON variant that vanishes when b43 debugging is disabled.
* This _also_ evaluates the arg with debugging disabled. */
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index e04fc91f569..45e3d6af69f 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -51,8 +51,8 @@ struct b43_debugfs_fops {
};
static inline
-struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
- const struct b43_debugfs_fops *dfops)
+struct b43_dfs_file *fops_to_dfs_file(struct b43_wldev *dev,
+ const struct b43_debugfs_fops *dfops)
{
void *p;
@@ -367,34 +367,6 @@ static int mmio32write__write_file(struct b43_wldev *dev,
return 0;
}
-/* wl->irq_lock is locked */
-static ssize_t tsf_read_file(struct b43_wldev *dev,
- char *buf, size_t bufsize)
-{
- ssize_t count = 0;
- u64 tsf;
-
- b43_tsf_read(dev, &tsf);
- fappend("0x%08x%08x\n",
- (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
- (unsigned int)(tsf & 0xFFFFFFFFULL));
-
- return count;
-}
-
-/* wl->irq_lock is locked */
-static int tsf_write_file(struct b43_wldev *dev,
- const char *buf, size_t count)
-{
- u64 tsf;
-
- if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1)
- return -EINVAL;
- b43_tsf_write(dev, tsf);
-
- return 0;
-}
-
static ssize_t txstat_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
@@ -691,15 +663,23 @@ B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
-B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
-int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
+bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
{
- return !!(dev->dfsentry && dev->dfsentry->dyn_debug[feature]);
+ bool enabled;
+
+ enabled = (dev->dfsentry && dev->dfsentry->dyn_debug[feature]);
+ if (unlikely(enabled)) {
+ /* Force full debugging messages, if the user enabled
+ * some dynamic debugging feature. */
+ b43_modparam_verbose = B43_VERBOSITY_MAX;
+ }
+
+ return enabled;
}
static void b43_remove_dynamic_debug(struct b43_wldev *dev)
@@ -805,7 +785,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
ADD_FILE(mmio16write, 0200);
ADD_FILE(mmio32read, 0600);
ADD_FILE(mmio32write, 0200);
- ADD_FILE(tsf, 0600);
ADD_FILE(txstat, 0400);
ADD_FILE(restart, 0200);
ADD_FILE(loctls, 0400);
@@ -834,7 +813,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
debugfs_remove(e->file_mmio16write.dentry);
debugfs_remove(e->file_mmio32read.dentry);
debugfs_remove(e->file_mmio32write.dentry);
- debugfs_remove(e->file_tsf.dentry);
debugfs_remove(e->file_txstat.dentry);
debugfs_remove(e->file_restart.dentry);
debugfs_remove(e->file_loctls.dentry);
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index 7886cbe2d1d..b9d4de4a979 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -46,7 +46,6 @@ struct b43_dfsentry {
struct b43_dfs_file file_mmio16write;
struct b43_dfs_file file_mmio32read;
struct b43_dfs_file file_mmio32write;
- struct b43_dfs_file file_tsf;
struct b43_dfs_file file_txstat;
struct b43_dfs_file file_txpower_g;
struct b43_dfs_file file_restart;
@@ -72,7 +71,7 @@ struct b43_dfsentry {
struct dentry *dyn_debug_dentries[__B43_NR_DYNDBG];
};
-int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature);
+bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature);
void b43_debugfs_init(void);
void b43_debugfs_exit(void);
@@ -83,7 +82,7 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev,
#else /* CONFIG_B43_DEBUG */
-static inline int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
+static inline bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
{
return 0;
}
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 6d65a02b705..0cc804d0a21 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -41,6 +41,12 @@
#include <asm/div64.h>
+/* Required number of TX DMA slots per TX frame.
+ * This currently is 2, because we put the header and the ieee80211 frame
+ * into separate slots. */
+#define TX_SLOTS_PER_FRAME 2
+
+
/* 32bit DMA ops. */
static
struct b43_dmadesc_generic *op32_idx2desc(struct b43_dmaring *ring,
@@ -74,8 +80,7 @@ static void op32_fill_descriptor(struct b43_dmaring *ring,
addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK)
>> SSB_DMA_TRANSLATION_SHIFT;
addr |= ssb_dma_translation(ring->dev->dev);
- ctl = (bufsize - ring->frameoffset)
- & B43_DMA32_DCTL_BYTECNT;
+ ctl = bufsize & B43_DMA32_DCTL_BYTECNT;
if (slot == ring->nr_slots - 1)
ctl |= B43_DMA32_DCTL_DTABLEEND;
if (start)
@@ -177,8 +182,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring,
ctl0 |= B43_DMA64_DCTL0_FRAMEEND;
if (irq)
ctl0 |= B43_DMA64_DCTL0_IRQ;
- ctl1 |= (bufsize - ring->frameoffset)
- & B43_DMA64_DCTL1_BYTECNT;
+ ctl1 |= bufsize & B43_DMA64_DCTL1_BYTECNT;
ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT)
& B43_DMA64_DCTL1_ADDREXT_MASK;
@@ -576,12 +580,11 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
return -ENOMEM;
dmaaddr = map_descbuffer(ring, skb->data,
ring->rx_buffersize, 0);
- }
-
- if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
- b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
- dev_kfree_skb_any(skb);
- return -EIO;
+ if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
+ b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
+ dev_kfree_skb_any(skb);
+ return -EIO;
+ }
}
meta->skb = skb;
@@ -830,9 +833,6 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
if (ring->index == 0) {
ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE;
ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET;
- } else if (ring->index == 3) {
- ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE;
- ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET;
} else
B43_WARN_ON(1);
}
@@ -842,7 +842,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
#endif
if (for_tx) {
- ring->txhdr_cache = kcalloc(ring->nr_slots,
+ /* Assumption: B43_TXRING_SLOTS can be divided by TX_SLOTS_PER_FRAME */
+ BUILD_BUG_ON(B43_TXRING_SLOTS % TX_SLOTS_PER_FRAME != 0);
+
+ ring->txhdr_cache = kcalloc(ring->nr_slots / TX_SLOTS_PER_FRAME,
b43_txhdr_size(dev),
GFP_KERNEL);
if (!ring->txhdr_cache)
@@ -858,7 +861,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
b43_txhdr_size(dev), 1)) {
/* ugh realloc */
kfree(ring->txhdr_cache);
- ring->txhdr_cache = kcalloc(ring->nr_slots,
+ ring->txhdr_cache = kcalloc(ring->nr_slots / TX_SLOTS_PER_FRAME,
b43_txhdr_size(dev),
GFP_KERNEL | GFP_DMA);
if (!ring->txhdr_cache)
@@ -1149,7 +1152,10 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
u16 cookie;
size_t hdrsize = b43_txhdr_size(ring->dev);
-#define SLOTS_PER_PACKET 2
+ /* Important note: If the number of used DMA slots per TX frame
+ * is changed here, the TX_SLOTS_PER_FRAME definition at the top of
+ * the file has to be updated, too!
+ */
old_top_slot = ring->current_slot;
old_used_slots = ring->used_slots;
@@ -1159,7 +1165,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
desc = ops->idx2desc(ring, slot, &meta_hdr);
memset(meta_hdr, 0, sizeof(*meta_hdr));
- header = &(ring->txhdr_cache[slot * hdrsize]);
+ header = &(ring->txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]);
cookie = generate_cookie(ring, slot);
err = b43_generate_txhdr(ring->dev, header,
skb->data, skb->len, info, cookie);
@@ -1254,8 +1260,8 @@ static inline int should_inject_overflow(struct b43_dmaring *ring)
}
/* Static mapping of mac80211's queues (priorities) to b43 DMA rings. */
-static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
- u8 queue_prio)
+static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev,
+ u8 queue_prio)
{
struct b43_dmaring *ring;
@@ -1306,17 +1312,19 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
}
spin_lock_irqsave(&ring->lock, flags);
+
B43_WARN_ON(!ring->tx);
- if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
- b43warn(dev->wl, "DMA queue overflow\n");
- err = -ENOSPC;
- goto out_unlock;
- }
/* Check if the queue was stopped in mac80211,
* but we got called nevertheless.
* That would be a mac80211 bug. */
B43_WARN_ON(ring->stopped);
+ if (unlikely(free_slots(ring) < TX_SLOTS_PER_FRAME)) {
+ b43warn(dev->wl, "DMA queue overflow\n");
+ err = -ENOSPC;
+ goto out_unlock;
+ }
+
/* Assign the queue number to the ring (if not already done before)
* so TX status handling can use it. The queue to ring mapping is
* static, so we don't need to store it per frame. */
@@ -1335,7 +1343,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
goto out_unlock;
}
ring->nr_tx_packets++;
- if ((free_slots(ring) < SLOTS_PER_PACKET) ||
+ if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
should_inject_overflow(ring)) {
/* This TX ring is full. */
ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
@@ -1417,9 +1425,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
break;
slot = next_slot(ring, slot);
}
- dev->stats.last_tx = jiffies;
if (ring->stopped) {
- B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
+ B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
ring->stopped = 0;
if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
@@ -1442,8 +1449,8 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
ring = select_ring_by_priority(dev, i);
spin_lock_irqsave(&ring->lock, flags);
- stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
- stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
+ stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
+ stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
stats[i].count = ring->nr_tx_packets;
spin_unlock_irqrestore(&ring->lock, flags);
}
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index d1eb5c0848a..05dde646d83 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -1,14 +1,12 @@
#ifndef B43_DMA_H_
#define B43_DMA_H_
-#include <linux/list.h>
+#include <linux/ieee80211.h>
#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/linkage.h>
-#include <asm/atomic.h>
#include "b43.h"
+
/* DMA-Interrupt reasons. */
#define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
| (1 << 14) | (1 << 15))
@@ -161,14 +159,13 @@ struct b43_dmadesc_generic {
/* Misc DMA constants */
#define B43_DMA_RINGMEMSIZE PAGE_SIZE
-#define B43_DMA0_RX_FRAMEOFFSET 30
-#define B43_DMA3_RX_FRAMEOFFSET 0
+#define B43_DMA0_RX_FRAMEOFFSET 30
/* DMA engine tuning knobs */
-#define B43_TXRING_SLOTS 128
+#define B43_TXRING_SLOTS 256
#define B43_RXRING_SLOTS 64
-#define B43_DMA0_RX_BUFFERSIZE (2304 + 100)
-#define B43_DMA3_RX_BUFFERSIZE 16
+#define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN
+
struct sk_buff;
struct b43_private;
@@ -215,7 +212,7 @@ struct b43_dmaring {
void *descbase;
/* Meta data about all descriptors. */
struct b43_dmadesc_meta *meta;
- /* Cache of TX headers for each slot.
+ /* Cache of TX headers for each TX frame.
* This is to avoid an allocation on each TX.
* This is NULL for an RX ring.
*/
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 6a18a147046..22d0fbd83a6 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -36,8 +36,8 @@
#include <linux/sched.h>
-static struct b43_lo_calib * b43_find_lo_calib(struct b43_txpower_lo_control *lo,
- const struct b43_bbatt *bbatt,
+static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo,
+ const struct b43_bbatt *bbatt,
const struct b43_rfatt *rfatt)
{
struct b43_lo_calib *c;
@@ -138,7 +138,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev,
* "pad_mix_gain" is the PAD Mixer Gain.
*/
static u16 lo_txctl_register_table(struct b43_wldev *dev,
- u16 * value, u16 * pad_mix_gain)
+ u16 *value, u16 *pad_mix_gain)
{
struct b43_phy *phy = &dev->phy;
u16 reg, v, padmix;
@@ -225,14 +225,12 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
radio_pctl_reg = tmp;
}
}
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | radio_pctl_reg);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, radio_pctl_reg);
b43_gphy_set_baseband_attenuation(dev, 2);
reg = lo_txctl_register_table(dev, &mask, NULL);
mask = ~mask;
- b43_radio_write16(dev, reg, b43_radio_read16(dev, reg)
- & mask);
+ b43_radio_mask(dev, reg, mask);
if (has_tx_magnification(phy)) {
int i, j;
@@ -242,14 +240,10 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
for (i = 0; i < ARRAY_SIZE(tx_magn_values); i++) {
tx_magn = tx_magn_values[i];
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52)
- & 0xFF0F) | tx_magn);
+ b43_radio_maskset(dev, 0x52, 0xFF0F, tx_magn);
for (j = 0; j < ARRAY_SIZE(tx_bias_values); j++) {
tx_bias = tx_bias_values[j];
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52)
- & 0xFFF0) | tx_bias);
+ b43_radio_maskset(dev, 0x52, 0xFFF0, tx_bias);
feedthrough =
lo_measure_feedthrough(dev, 0, pga,
trsw_rx);
@@ -269,8 +263,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
} else {
lo->tx_magn = 0;
lo->tx_bias = 0;
- b43_radio_write16(dev, 0x52, b43_radio_read16(dev, 0x52)
- & 0xFFF0); /* TX bias == 0 */
+ b43_radio_mask(dev, 0x52, 0xFFF0); /* TX bias == 0 */
}
lo->txctl_measured_time = jiffies;
}
@@ -406,18 +399,10 @@ static void lo_measure_setup(struct b43_wldev *dev,
sav->phy_cck_14 = b43_phy_read(dev, B43_PHY_CCK(0x14));
sav->phy_hpwr_tssictl = b43_phy_read(dev, B43_PHY_HPWR_TSSICTL);
- b43_phy_write(dev, B43_PHY_HPWR_TSSICTL,
- b43_phy_read(dev, B43_PHY_HPWR_TSSICTL)
- | 0x100);
- b43_phy_write(dev, B43_PHY_EXTG(0x01),
- b43_phy_read(dev, B43_PHY_EXTG(0x01))
- | 0x40);
- b43_phy_write(dev, B43_PHY_DACCTL,
- b43_phy_read(dev, B43_PHY_DACCTL)
- | 0x40);
- b43_phy_write(dev, B43_PHY_CCK(0x14),
- b43_phy_read(dev, B43_PHY_CCK(0x14))
- | 0x200);
+ b43_phy_set(dev, B43_PHY_HPWR_TSSICTL, 0x100);
+ b43_phy_set(dev, B43_PHY_EXTG(0x01), 0x40);
+ b43_phy_set(dev, B43_PHY_DACCTL, 0x40);
+ b43_phy_set(dev, B43_PHY_CCK(0x14), 0x200);
}
if (phy->type == B43_PHYTYPE_B &&
phy->radio_ver == 0x2050 && phy->radio_rev < 6) {
@@ -434,17 +419,10 @@ static void lo_measure_setup(struct b43_wldev *dev,
sav->phy_cck_3E = b43_phy_read(dev, B43_PHY_CCK(0x3E));
sav->phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
- b43_phy_write(dev, B43_PHY_CLASSCTL,
- b43_phy_read(dev, B43_PHY_CLASSCTL)
- & 0xFFFC);
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0x7FFF);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER)
- | 0x0003);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
- & 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CLASSCTL, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x7FFF);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0003);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFC);
if (phy->type == B43_PHYTYPE_G) {
if ((phy->rev >= 7) &&
(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
@@ -558,8 +536,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
b43_radio_write16(dev, 0x7A, sav->radio_7A);
if (!has_tx_magnification(phy)) {
tmp = sav->radio_52;
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & 0xFF0F) | tmp);
+ b43_radio_maskset(dev, 0x52, 0xFF0F, tmp);
}
b43_write16(dev, 0x3E2, sav->reg_3E2);
if (phy->type == B43_PHYTYPE_B &&
@@ -754,9 +731,9 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
}
static
-struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
- const struct b43_bbatt *bbatt,
- const struct b43_rfatt *rfatt)
+struct b43_lo_calib *b43_calibrate_lo_setting(struct b43_wldev *dev,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_g *gphy = phy->g;
@@ -778,12 +755,8 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
txctl_reg = lo_txctl_register_table(dev, &txctl_value, &pad_mix_gain);
- b43_radio_write16(dev, 0x43,
- (b43_radio_read16(dev, 0x43) & 0xFFF0)
- | rfatt->att);
- b43_radio_write16(dev, txctl_reg,
- (b43_radio_read16(dev, txctl_reg) & ~txctl_value)
- | (rfatt->with_padmix) ? txctl_value : 0);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, rfatt->att);
+ b43_radio_maskset(dev, txctl_reg, ~txctl_value, (rfatt->with_padmix ? txctl_value :0));
max_rx_gain = rfatt->att * 2;
max_rx_gain += bbatt->att / 2;
@@ -824,9 +797,9 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
/* Get a calibrated LO setting for the given attenuation values.
* Might return a NULL pointer under OOM! */
static
-struct b43_lo_calib * b43_get_calib_lo_settings(struct b43_wldev *dev,
- const struct b43_bbatt *bbatt,
- const struct b43_rfatt *rfatt)
+struct b43_lo_calib *b43_get_calib_lo_settings(struct b43_wldev *dev,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
{
struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
struct b43_lo_calib *c;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c788bad1066..b72ef3fd315 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4,7 +4,7 @@
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
- Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
+ Copyright (c) 2005-2009 Michael Buesch <mb@bu3sch.de>
Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -88,6 +88,10 @@ static int modparam_btcoex = 1;
module_param_named(btcoex, modparam_btcoex, int, 0444);
MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)");
+int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
+module_param_named(verbose, b43_modparam_verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
+
static const struct ssb_device_id b43_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -97,6 +101,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
SSB_DEVTABLE_END
};
@@ -298,6 +304,8 @@ void b43info(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_INFO)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -311,6 +319,8 @@ void b43err(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_ERROR)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -324,6 +334,8 @@ void b43warn(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_WARN)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -333,18 +345,18 @@ void b43warn(struct b43_wl *wl, const char *fmt, ...)
va_end(args);
}
-#if B43_DEBUG
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
+ return;
va_start(args, fmt);
printk(KERN_DEBUG "b43-%s debug: ",
(wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
vprintk(fmt, args);
va_end(args);
}
-#endif /* DEBUG */
static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val)
{
@@ -500,7 +512,7 @@ void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
}
/* Read HostFlags */
-u64 b43_hf_read(struct b43_wldev * dev)
+u64 b43_hf_read(struct b43_wldev *dev)
{
u64 ret;
@@ -526,52 +538,20 @@ void b43_hf_write(struct b43_wldev *dev, u64 value)
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi);
}
-void b43_tsf_read(struct b43_wldev *dev, u64 * tsf)
+void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
{
- /* We need to be careful. As we read the TSF from multiple
- * registers, we should take care of register overflows.
- * In theory, the whole tsf read process should be atomic.
- * We try to be atomic here, by restaring the read process,
- * if any of the high registers changed (overflew).
- */
- if (dev->dev->id.revision >= 3) {
- u32 low, high, high2;
+ u32 low, high;
- do {
- high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
- high2 = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- } while (unlikely(high != high2));
-
- *tsf = high;
- *tsf <<= 32;
- *tsf |= low;
- } else {
- u64 tmp;
- u16 v0, v1, v2, v3;
- u16 test1, test2, test3;
+ B43_WARN_ON(dev->dev->id.revision < 3);
- do {
- v3 = b43_read16(dev, B43_MMIO_TSF_3);
- v2 = b43_read16(dev, B43_MMIO_TSF_2);
- v1 = b43_read16(dev, B43_MMIO_TSF_1);
- v0 = b43_read16(dev, B43_MMIO_TSF_0);
+ /* The hardware guarantees us an atomic read, if we
+ * read the low register first. */
+ low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
+ high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- test3 = b43_read16(dev, B43_MMIO_TSF_3);
- test2 = b43_read16(dev, B43_MMIO_TSF_2);
- test1 = b43_read16(dev, B43_MMIO_TSF_1);
- } while (v3 != test3 || v2 != test2 || v1 != test1);
-
- *tsf = v3;
- *tsf <<= 48;
- tmp = v2;
- tmp <<= 32;
- *tsf |= tmp;
- tmp = v1;
- tmp <<= 16;
- *tsf |= tmp;
- *tsf |= v0;
- }
+ *tsf = high;
+ *tsf <<= 32;
+ *tsf |= low;
}
static void b43_time_lock(struct b43_wldev *dev)
@@ -598,35 +578,18 @@ static void b43_time_unlock(struct b43_wldev *dev)
static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)
{
- /* Be careful with the in-progress timer.
- * First zero out the low register, so we have a full
- * register-overflow duration to complete the operation.
- */
- if (dev->dev->id.revision >= 3) {
- u32 lo = (tsf & 0x00000000FFFFFFFFULL);
- u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
+ u32 low, high;
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, 0);
- mmiowb();
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, hi);
- mmiowb();
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, lo);
- } else {
- u16 v0 = (tsf & 0x000000000000FFFFULL);
- u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
- u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
- u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
+ B43_WARN_ON(dev->dev->id.revision < 3);
- b43_write16(dev, B43_MMIO_TSF_0, 0);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_3, v3);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_2, v2);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_1, v1);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_0, v0);
- }
+ low = tsf;
+ high = (tsf >> 32);
+ /* The hardware guarantees us an atomic write, if we
+ * write the low register first. */
+ b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, low);
+ mmiowb();
+ b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, high);
+ mmiowb();
}
void b43_tsf_write(struct b43_wldev *dev, u64 tsf)
@@ -637,7 +600,7 @@ void b43_tsf_write(struct b43_wldev *dev, u64 tsf)
}
static
-void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 * mac)
+void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 *mac)
{
static const u8 zero_addr[ETH_ALEN] = { 0 };
u16 data;
@@ -827,7 +790,7 @@ void b43_dummy_transmission(struct b43_wldev *dev)
}
static void key_write(struct b43_wldev *dev,
- u8 index, u8 algorithm, const u8 * key)
+ u8 index, u8 algorithm, const u8 *key)
{
unsigned int i;
u32 offset;
@@ -849,7 +812,7 @@ static void key_write(struct b43_wldev *dev,
}
}
-static void keymac_write(struct b43_wldev *dev, u8 index, const u8 * addr)
+static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
{
u32 addrtmp[2] = { 0, 0, };
u8 per_sta_keys_start = 8;
@@ -899,7 +862,7 @@ static void keymac_write(struct b43_wldev *dev, u8 index, const u8 * addr)
static void do_key_write(struct b43_wldev *dev,
u8 index, u8 algorithm,
- const u8 * key, size_t key_len, const u8 * mac_addr)
+ const u8 *key, size_t key_len, const u8 *mac_addr)
{
u8 buf[B43_SEC_KEYSIZE] = { 0, };
u8 per_sta_keys_start = 8;
@@ -923,8 +886,8 @@ static void do_key_write(struct b43_wldev *dev,
static int b43_key_write(struct b43_wldev *dev,
int index, u8 algorithm,
- const u8 * key, size_t key_len,
- const u8 * mac_addr,
+ const u8 *key, size_t key_len,
+ const u8 *mac_addr,
struct ieee80211_key_conf *keyconf)
{
int i;
@@ -937,8 +900,7 @@ static int b43_key_write(struct b43_wldev *dev,
B43_WARN_ON(dev->key[i].keyconf == keyconf);
}
if (index < 0) {
- /* Either pairwise key or address is 00:00:00:00:00:00
- * for transmit-only keys. Search the index. */
+ /* Pairwise key. Get an empty slot for the key. */
if (b43_new_kidx_api(dev))
sta_keys_start = 4;
else
@@ -951,7 +913,7 @@ static int b43_key_write(struct b43_wldev *dev,
}
}
if (index < 0) {
- b43err(dev->wl, "Out of hardware key memory\n");
+ b43warn(dev->wl, "Out of hardware key memory\n");
return -ENOSPC;
}
} else
@@ -1324,7 +1286,7 @@ static void handle_irq_pmq(struct b43_wldev *dev)
}
static void b43_write_template_common(struct b43_wldev *dev,
- const u8 * data, u16 size,
+ const u8 *data, u16 size,
u16 ram_offset,
u16 shm_size_offset, u8 rate)
{
@@ -1514,9 +1476,9 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
* 2) Patching duration field
* 3) Stripping TIM
*/
-static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
- u16 *dest_size,
- struct ieee80211_rate *rate)
+static const u8 *b43_generate_probe_resp(struct b43_wldev *dev,
+ u16 *dest_size,
+ struct ieee80211_rate *rate)
{
const u8 *src_data;
u8 *dest_data;
@@ -1982,7 +1944,7 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
return ret;
}
-static void do_release_fw(struct b43_firmware_file *fw)
+void b43_do_release_fw(struct b43_firmware_file *fw)
{
release_firmware(fw->data);
fw->data = NULL;
@@ -1991,31 +1953,30 @@ static void do_release_fw(struct b43_firmware_file *fw)
static void b43_release_firmware(struct b43_wldev *dev)
{
- do_release_fw(&dev->fw.ucode);
- do_release_fw(&dev->fw.pcm);
- do_release_fw(&dev->fw.initvals);
- do_release_fw(&dev->fw.initvals_band);
+ b43_do_release_fw(&dev->fw.ucode);
+ b43_do_release_fw(&dev->fw.pcm);
+ b43_do_release_fw(&dev->fw.initvals);
+ b43_do_release_fw(&dev->fw.initvals_band);
}
static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
{
- const char *text;
+ const char text[] =
+ "You must go to " \
+ "http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware " \
+ "and download the correct firmware for this driver version. " \
+ "Please carefully read all instructions on this website.\n";
- text = "You must go to "
- "http://linuxwireless.org/en/users/Drivers/b43#devicefirmware "
- "and download the latest firmware (version 4).\n";
if (error)
b43err(wl, text);
else
b43warn(wl, text);
}
-static int do_request_fw(struct b43_wldev *dev,
- const char *name,
- struct b43_firmware_file *fw,
- bool silent)
+int b43_do_request_fw(struct b43_request_fw_context *ctx,
+ const char *name,
+ struct b43_firmware_file *fw)
{
- char path[sizeof(modparam_fwpostfix) + 32];
const struct firmware *blob;
struct b43_fw_header *hdr;
u32 size;
@@ -2023,29 +1984,49 @@ static int do_request_fw(struct b43_wldev *dev,
if (!name) {
/* Don't fetch anything. Free possibly cached firmware. */
- do_release_fw(fw);
+ /* FIXME: We should probably keep it anyway, to save some headache
+ * on suspend/resume with multiband devices. */
+ b43_do_release_fw(fw);
return 0;
}
if (fw->filename) {
- if (strcmp(fw->filename, name) == 0)
+ if ((fw->type == ctx->req_type) &&
+ (strcmp(fw->filename, name) == 0))
return 0; /* Already have this fw. */
/* Free the cached firmware first. */
- do_release_fw(fw);
+ /* FIXME: We should probably do this later after we successfully
+ * got the new fw. This could reduce headache with multiband devices.
+ * We could also redesign this to cache the firmware for all possible
+ * bands all the time. */
+ b43_do_release_fw(fw);
+ }
+
+ switch (ctx->req_type) {
+ case B43_FWTYPE_PROPRIETARY:
+ snprintf(ctx->fwname, sizeof(ctx->fwname),
+ "b43%s/%s.fw",
+ modparam_fwpostfix, name);
+ break;
+ case B43_FWTYPE_OPENSOURCE:
+ snprintf(ctx->fwname, sizeof(ctx->fwname),
+ "b43-open%s/%s.fw",
+ modparam_fwpostfix, name);
+ break;
+ default:
+ B43_WARN_ON(1);
+ return -ENOSYS;
}
-
- snprintf(path, ARRAY_SIZE(path),
- "b43%s/%s.fw",
- modparam_fwpostfix, name);
- err = request_firmware(&blob, path, dev->dev->dev);
+ err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
if (err == -ENOENT) {
- if (!silent) {
- b43err(dev->wl, "Firmware file \"%s\" not found\n",
- path);
- }
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" not found\n", ctx->fwname);
return err;
} else if (err) {
- b43err(dev->wl, "Firmware file \"%s\" request failed (err=%d)\n",
- path, err);
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" request failed (err=%d)\n",
+ ctx->fwname, err);
return err;
}
if (blob->size < sizeof(struct b43_fw_header))
@@ -2068,20 +2049,24 @@ static int do_request_fw(struct b43_wldev *dev,
fw->data = blob;
fw->filename = name;
+ fw->type = ctx->req_type;
return 0;
err_format:
- b43err(dev->wl, "Firmware file \"%s\" format error.\n", path);
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" format error.\n", ctx->fwname);
release_firmware(blob);
return -EPROTO;
}
-static int b43_request_firmware(struct b43_wldev *dev)
+static int b43_try_request_fw(struct b43_request_fw_context *ctx)
{
- struct b43_firmware *fw = &dev->fw;
- const u8 rev = dev->dev->id.revision;
+ struct b43_wldev *dev = ctx->dev;
+ struct b43_firmware *fw = &ctx->dev->fw;
+ const u8 rev = ctx->dev->dev->id.revision;
const char *filename;
u32 tmshigh;
int err;
@@ -2096,7 +2081,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
filename = "ucode13";
else
goto err_no_ucode;
- err = do_request_fw(dev, filename, &fw->ucode, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->ucode);
if (err)
goto err_load;
@@ -2108,7 +2093,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
else
goto err_no_pcm;
fw->pcm_request_failed = 0;
- err = do_request_fw(dev, filename, &fw->pcm, 1);
+ err = b43_do_request_fw(ctx, filename, &fw->pcm);
if (err == -ENOENT) {
/* We did not find a PCM file? Not fatal, but
* core rev <= 10 must do without hwcrypto then. */
@@ -2144,7 +2129,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
default:
goto err_no_initvals;
}
- err = do_request_fw(dev, filename, &fw->initvals, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->initvals);
if (err)
goto err_load;
@@ -2178,30 +2163,34 @@ static int b43_request_firmware(struct b43_wldev *dev)
default:
goto err_no_initvals;
}
- err = do_request_fw(dev, filename, &fw->initvals_band, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->initvals_band);
if (err)
goto err_load;
return 0;
-err_load:
- b43_print_fw_helptext(dev->wl, 1);
- goto error;
-
err_no_ucode:
- err = -ENODEV;
- b43err(dev->wl, "No microcode available for core rev %u\n", rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (ucode) "
+ "is required for your device (wl-core rev %u)\n", rev);
goto error;
err_no_pcm:
- err = -ENODEV;
- b43err(dev->wl, "No PCM available for core rev %u\n", rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (PCM) "
+ "is required for your device (wl-core rev %u)\n", rev);
goto error;
err_no_initvals:
- err = -ENODEV;
- b43err(dev->wl, "No Initial Values firmware file for PHY %u, "
- "core rev %u\n", dev->phy.type, rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (initvals) "
+ "is required for your device (wl-core rev %u)\n", rev);
+ goto error;
+
+err_load:
+ /* We failed to load this firmware image. The error message
+ * already is in ctx->errors. Return and let our caller decide
+ * what to do. */
goto error;
error:
@@ -2209,6 +2198,48 @@ error:
return err;
}
+static int b43_request_firmware(struct b43_wldev *dev)
+{
+ struct b43_request_fw_context *ctx;
+ unsigned int i;
+ int err;
+ const char *errmsg;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->dev = dev;
+
+ ctx->req_type = B43_FWTYPE_PROPRIETARY;
+ err = b43_try_request_fw(ctx);
+ if (!err)
+ goto out; /* Successfully loaded it. */
+ err = ctx->fatal_failure;
+ if (err)
+ goto out;
+
+ ctx->req_type = B43_FWTYPE_OPENSOURCE;
+ err = b43_try_request_fw(ctx);
+ if (!err)
+ goto out; /* Successfully loaded it. */
+ err = ctx->fatal_failure;
+ if (err)
+ goto out;
+
+ /* Could not find a usable firmware. Print the errors. */
+ for (i = 0; i < B43_NR_FWTYPES; i++) {
+ errmsg = ctx->errors[i];
+ if (strlen(errmsg))
+ b43err(dev->wl, errmsg);
+ }
+ b43_print_fw_helptext(dev->wl, 1);
+ err = -ENOENT;
+
+out:
+ kfree(ctx);
+ return err;
+}
+
static int b43_upload_microcode(struct b43_wldev *dev)
{
const size_t hdr_len = sizeof(struct b43_fw_header);
@@ -2319,8 +2350,11 @@ static int b43_upload_microcode(struct b43_wldev *dev)
}
if (b43_is_old_txhdr_format(dev)) {
+ /* We're over the deadline, but we keep support for old fw
+ * until it turns out to be in major conflict with something new. */
b43warn(dev->wl, "You are using an old firmware image. "
- "Support for old firmware will be removed in July 2008.\n");
+ "Support for old firmware will be removed soon "
+ "(official deadline was July 2008).\n");
b43_print_fw_helptext(dev->wl, 0);
}
@@ -2946,7 +2980,7 @@ static void b43_security_init(struct b43_wldev *dev)
b43_clear_keys(dev);
}
-static int b43_rng_read(struct hwrng *rng, u32 * data)
+static int b43_rng_read(struct hwrng *rng, u32 *data)
{
struct b43_wl *wl = (struct b43_wl *)rng->priv;
unsigned long flags;
@@ -3221,6 +3255,43 @@ static int b43_op_get_stats(struct ieee80211_hw *hw,
return 0;
}
+static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+ u64 tsf;
+
+ mutex_lock(&wl->mutex);
+ spin_lock_irq(&wl->irq_lock);
+ dev = wl->current_dev;
+
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
+ b43_tsf_read(dev, &tsf);
+ else
+ tsf = 0;
+
+ spin_unlock_irq(&wl->irq_lock);
+ mutex_unlock(&wl->mutex);
+
+ return tsf;
+}
+
+static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ spin_lock_irq(&wl->irq_lock);
+ dev = wl->current_dev;
+
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
+ b43_tsf_write(dev, tsf);
+
+ spin_unlock_irq(&wl->irq_lock);
+ mutex_unlock(&wl->mutex);
+}
+
static void b43_put_phy_into_reset(struct b43_wldev *dev)
{
struct ssb_device *sdev = dev->dev;
@@ -3240,7 +3311,7 @@ static void b43_put_phy_into_reset(struct b43_wldev *dev)
msleep(1);
}
-static const char * band_to_string(enum ieee80211_band band)
+static const char *band_to_string(enum ieee80211_band band)
{
switch (band) {
case IEEE80211_BAND_5GHZ:
@@ -3442,7 +3513,7 @@ out_unlock_mutex:
return err;
}
-static void b43_update_basic_rates(struct b43_wldev *dev, u64 brates)
+static void b43_update_basic_rates(struct b43_wldev *dev, u32 brates)
{
struct ieee80211_supported_band *sband =
dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)];
@@ -3520,21 +3591,29 @@ out_unlock_mutex:
}
static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
- unsigned long flags;
u8 algorithm;
u8 index;
int err;
+ static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
if (modparam_nohwcrypt)
return -ENOSPC; /* User disabled HW-crypto */
mutex_lock(&wl->mutex);
- spin_lock_irqsave(&wl->irq_lock, flags);
+ spin_lock_irq(&wl->irq_lock);
+ write_lock(&wl->tx_lock);
+ /* Why do we need all this locking here?
+ * mutex -> Every config operation must take it.
+ * irq_lock -> We modify the dev->key array, which is accessed
+ * in the IRQ handlers.
+ * tx_lock -> We modify the dev->key array, which is accessed
+ * in the TX handler.
+ */
dev = wl->current_dev;
err = -ENODEV;
@@ -3551,7 +3630,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 == 5)
+ if (key->keylen == LEN_WEP40)
algorithm = B43_SEC_ALGO_WEP40;
else
algorithm = B43_SEC_ALGO_WEP104;
@@ -3578,17 +3657,19 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
goto out_unlock;
}
- if (is_broadcast_ether_addr(addr)) {
- /* addr is FF:FF:FF:FF:FF:FF for default keys */
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+ if (WARN_ON(!sta)) {
+ err = -EOPNOTSUPP;
+ goto out_unlock;
+ }
+ /* Pairwise key with an assigned MAC address. */
+ err = b43_key_write(dev, -1, algorithm,
+ key->key, key->keylen,
+ sta->addr, key);
+ } else {
+ /* Group key */
err = b43_key_write(dev, index, algorithm,
key->key, key->keylen, NULL, key);
- } else {
- /*
- * either pairwise key or address is 00:00:00:00:00:00
- * for transmit-only keys
- */
- err = b43_key_write(dev, -1, algorithm,
- key->key, key->keylen, addr, key);
}
if (err)
goto out_unlock;
@@ -3617,10 +3698,11 @@ out_unlock:
b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
"mac: %pM\n",
cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
- addr);
+ sta ? sta->addr : bcast_addr);
b43_dump_keymemory(dev);
}
- spin_unlock_irqrestore(&wl->irq_lock, flags);
+ write_unlock(&wl->tx_lock);
+ spin_unlock_irq(&wl->irq_lock);
mutex_unlock(&wl->mutex);
return err;
@@ -3796,6 +3878,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
break;
#ifdef CONFIG_B43_NPHY
case B43_PHYTYPE_N:
+ if (phy_rev > 4)
+ unsupported = 1;
+ break;
+#endif
+#ifdef CONFIG_B43_PHY_LP
+ case B43_PHYTYPE_LP:
if (phy_rev > 1)
unsupported = 1;
break;
@@ -3849,7 +3937,11 @@ static int b43_phy_versioning(struct b43_wldev *dev)
unsupported = 1;
break;
case B43_PHYTYPE_N:
- if (radio_ver != 0x2055)
+ if (radio_ver != 0x2055 && radio_ver != 0x2056)
+ unsupported = 1;
+ break;
+ case B43_PHYTYPE_LP:
+ if (radio_ver != 0x2062)
unsupported = 1;
break;
default:
@@ -4078,11 +4170,21 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
hf |= B43_HF_GDCW;
if (sprom->boardflags_lo & B43_BFL_PACTRL)
hf |= B43_HF_OFDMPABOOST;
- } else if (phy->type == B43_PHYTYPE_B) {
- hf |= B43_HF_SYMW;
- if (phy->rev >= 2 && phy->radio_ver == 0x2050)
- hf &= ~B43_HF_GDCW;
}
+ if (phy->radio_ver == 0x2050) {
+ if (phy->radio_rev == 6)
+ hf |= B43_HF_4318TSSI;
+ if (phy->radio_rev < 6)
+ hf |= B43_HF_VCORECALC;
+ }
+ if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
+ hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+ if ((bus->bustype == SSB_BUSTYPE_PCI) &&
+ (bus->pcicore.dev->id.revision <= 10))
+ hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */
+#endif
+ hf &= ~B43_HF_SKCFPUP;
b43_hf_write(dev, hf);
b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT,
@@ -4121,7 +4223,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
b43_set_synth_pu_delay(dev, 1);
b43_bluetooth_coext_enable(dev);
- ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
+ ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
b43_upload_card_macaddress(dev);
b43_security_init(dev);
if (!dev->suspend_in_progress)
@@ -4305,6 +4407,34 @@ static void b43_op_sta_notify(struct ieee80211_hw *hw,
B43_WARN_ON(!vif || wl->vif != vif);
}
+static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
+ /* Disable CFP update during scan on other channels. */
+ b43_hf_write(dev, b43_hf_read(dev) | B43_HF_SKCFPUP);
+ }
+ mutex_unlock(&wl->mutex);
+}
+
+static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
+ /* Re-enable CFP update. */
+ b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_SKCFPUP);
+ }
+ mutex_unlock(&wl->mutex);
+}
+
static const struct ieee80211_ops b43_hw_ops = {
.tx = b43_op_tx,
.conf_tx = b43_op_conf_tx,
@@ -4317,10 +4447,14 @@ static const struct ieee80211_ops b43_hw_ops = {
.set_key = b43_op_set_key,
.get_stats = b43_op_get_stats,
.get_tx_stats = b43_op_get_tx_stats,
+ .get_tsf = b43_op_get_tsf,
+ .set_tsf = b43_op_set_tsf,
.start = b43_op_start,
.stop = b43_op_stop,
.set_tim = b43_op_beacon_set_tim,
.sta_notify = b43_op_sta_notify,
+ .sw_scan_start = b43_op_sw_scan_start_notifier,
+ .sw_scan_complete = b43_op_sw_scan_complete_notifier,
};
/* Hard-reset the chip. Do not call this directly.
@@ -4446,6 +4580,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
break;
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
+ case B43_PHYTYPE_LP:
have_2ghz_phy = 1;
break;
default:
@@ -4657,9 +4792,10 @@ static int b43_wireless_init(struct ssb_device *dev)
INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
ssb_set_devtypedata(dev, wl);
- b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
+ b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
+ dev->bus->chip_id, dev->id.revision);
err = 0;
- out:
+out:
return err;
}
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index f871a252cb5..40abcf5d1b4 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -40,6 +40,24 @@
extern int b43_modparam_qos;
+extern int b43_modparam_verbose;
+
+/* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if
+ * you add or remove levels. */
+enum b43_verbosity {
+ B43_VERBOSITY_ERROR,
+ B43_VERBOSITY_WARN,
+ B43_VERBOSITY_INFO,
+ B43_VERBOSITY_DEBUG,
+ __B43_VERBOSITY_AFTERLAST, /* keep last */
+
+ B43_VERBOSITY_MAX = __B43_VERBOSITY_AFTERLAST - 1,
+#if B43_DEBUG
+ B43_VERBOSITY_DEFAULT = B43_VERBOSITY_DEBUG,
+#else
+ B43_VERBOSITY_DEFAULT = B43_VERBOSITY_INFO,
+#endif
+};
/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
@@ -121,4 +139,11 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
void b43_mac_suspend(struct b43_wldev *dev);
void b43_mac_enable(struct b43_wldev *dev);
+
+struct b43_request_fw_context;
+int b43_do_request_fw(struct b43_request_fw_context *ctx,
+ const char *name,
+ struct b43_firmware_file *fw);
+void b43_do_release_fw(struct b43_firmware_file *fw);
+
#endif /* B43_MAIN_H_ */
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 7fe9d170162..c836c077d51 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -121,27 +121,18 @@ static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
b43_radio_write16(dev, 0x0007, (r8 << 4) | r8);
b43_radio_write16(dev, 0x0020, (r8 << 4) | r8);
b43_radio_write16(dev, 0x0021, (r8 << 4) | r8);
- b43_radio_write16(dev, 0x0022, (b43_radio_read16(dev, 0x0022)
- & 0x000F) | (r8 << 4));
+ b43_radio_maskset(dev, 0x0022, 0x000F, (r8 << 4));
b43_radio_write16(dev, 0x002A, (r8 << 4));
b43_radio_write16(dev, 0x002B, (r8 << 4));
- b43_radio_write16(dev, 0x0008, (b43_radio_read16(dev, 0x0008)
- & 0x00F0) | (r8 << 4));
- b43_radio_write16(dev, 0x0029, (b43_radio_read16(dev, 0x0029)
- & 0xFF0F) | 0x00B0);
+ b43_radio_maskset(dev, 0x0008, 0x00F0, (r8 << 4));
+ b43_radio_maskset(dev, 0x0029, 0xFF0F, 0x00B0);
b43_radio_write16(dev, 0x0035, 0x00AA);
b43_radio_write16(dev, 0x0036, 0x0085);
- b43_radio_write16(dev, 0x003A, (b43_radio_read16(dev, 0x003A)
- & 0xFF20) |
- freq_r3A_value(freq));
- b43_radio_write16(dev, 0x003D,
- b43_radio_read16(dev, 0x003D) & 0x00FF);
- b43_radio_write16(dev, 0x0081, (b43_radio_read16(dev, 0x0081)
- & 0xFF7F) | 0x0080);
- b43_radio_write16(dev, 0x0035,
- b43_radio_read16(dev, 0x0035) & 0xFFEF);
- b43_radio_write16(dev, 0x0035, (b43_radio_read16(dev, 0x0035)
- & 0xFFEF) | 0x0010);
+ b43_radio_maskset(dev, 0x003A, 0xFF20, freq_r3A_value(freq));
+ b43_radio_mask(dev, 0x003D, 0x00FF);
+ b43_radio_maskset(dev, 0x0081, 0xFF7F, 0x0080);
+ b43_radio_mask(dev, 0x0035, 0xFFEF);
+ b43_radio_maskset(dev, 0x0035, 0xFFEF, 0x0010);
b43_radio_set_tx_iq(dev);
//TODO: TSSI2dbm workaround
//FIXME b43_phy_xmitpower(dev);
@@ -160,23 +151,20 @@ static void b43_radio_init2060(struct b43_wldev *dev)
b43_radio_write16(dev, 0x0082, 0x0080);
b43_radio_write16(dev, 0x0080, 0x0000);
b43_radio_write16(dev, 0x003F, 0x00DA);
- b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0010);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
+ b43_radio_mask(dev, 0x0005, ~0x0008);
+ b43_radio_mask(dev, 0x0081, ~0x0010);
+ b43_radio_mask(dev, 0x0081, ~0x0020);
+ b43_radio_mask(dev, 0x0081, ~0x0020);
msleep(1); /* delay 400usec */
- b43_radio_write16(dev, 0x0081,
- (b43_radio_read16(dev, 0x0081) & ~0x0020) | 0x0010);
+ b43_radio_maskset(dev, 0x0081, ~0x0020, 0x0010);
msleep(1); /* delay 400usec */
- b43_radio_write16(dev, 0x0005,
- (b43_radio_read16(dev, 0x0005) & ~0x0008) | 0x0008);
- b43_radio_write16(dev, 0x0085, b43_radio_read16(dev, 0x0085) & ~0x0010);
- b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0040);
- b43_radio_write16(dev, 0x0081,
- (b43_radio_read16(dev, 0x0081) & ~0x0040) | 0x0040);
+ b43_radio_maskset(dev, 0x0005, ~0x0008, 0x0008);
+ b43_radio_mask(dev, 0x0085, ~0x0010);
+ b43_radio_mask(dev, 0x0005, ~0x0008);
+ b43_radio_mask(dev, 0x0081, ~0x0040);
+ b43_radio_maskset(dev, 0x0081, ~0x0040, 0x0040);
b43_radio_write16(dev, 0x0005,
(b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
b43_phy_write(dev, 0x0063, 0xDDC6);
@@ -224,22 +212,16 @@ static void b43_phy_ww(struct b43_wldev *dev)
u16 b, curr_s, best_s = 0xFFFF;
int i;
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN);
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000);
- b43_phy_write(dev, B43_PHY_OFDM(0x82),
- (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300);
- b43_radio_write16(dev, 0x0009,
- b43_radio_read16(dev, 0x0009) | 0x0080);
- b43_radio_write16(dev, 0x0012,
- (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002);
+ b43_phy_mask(dev, B43_PHY_CRS0, ~B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_OFDM(0x1B), 0x1000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x82), 0xF0FF, 0x0300);
+ b43_radio_set(dev, 0x0009, 0x0080);
+ b43_radio_maskset(dev, 0x0012, 0xFFFC, 0x0002);
b43_wa_initgains(dev);
b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
b = b43_phy_read(dev, B43_PHY_PWRDOWN);
b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
- b43_radio_write16(dev, 0x0004,
- b43_radio_read16(dev, 0x0004) | 0x0004);
+ b43_radio_set(dev, 0x0004, 0x0004);
for (i = 0x10; i <= 0x20; i++) {
b43_radio_write16(dev, 0x0013, i);
curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
@@ -252,8 +234,7 @@ static void b43_phy_ww(struct b43_wldev *dev)
best_s = curr_s;
}
b43_phy_write(dev, B43_PHY_PWRDOWN, b);
- b43_radio_write16(dev, 0x0004,
- b43_radio_read16(dev, 0x0004) & 0xFFFB);
+ b43_radio_mask(dev, 0x0004, 0xFFFB);
b43_radio_write16(dev, 0x0013, best_s);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
@@ -261,14 +242,10 @@ static void b43_phy_ww(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
- b43_phy_write(dev, B43_PHY_OFDM(0xBB),
- (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053);
- b43_phy_write(dev, B43_PHY_OFDM61,
- (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120);
- b43_phy_write(dev, B43_PHY_OFDM(0x13),
- (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000);
- b43_phy_write(dev, B43_PHY_OFDM(0x14),
- (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xBB), 0xF000, 0x0053);
+ b43_phy_maskset(dev, B43_PHY_OFDM61, 0xFE1F, 0x0120);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x13), 0x0FFF, 0x3000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x14), 0x0FFF, 0x3000);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
for (i = 0; i < 6; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
@@ -276,8 +253,7 @@ static void b43_phy_ww(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
}
static void hardware_pctl_init_aphy(struct b43_wldev *dev)
@@ -300,26 +276,21 @@ void b43_phy_inita(struct b43_wldev *dev)
if (phy->rev >= 6) {
if (phy->type == B43_PHYTYPE_A)
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x1000);
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
- b43_phy_write(dev, B43_PHY_ENCORE,
- b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010);
+ b43_phy_set(dev, B43_PHY_ENCORE, 0x0010);
else
- b43_phy_write(dev, B43_PHY_ENCORE,
- b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010);
+ b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010);
}
b43_wa_all(dev);
if (phy->type == B43_PHYTYPE_A) {
if (phy->gmode && (phy->rev < 3))
- b43_phy_write(dev, 0x0034,
- b43_phy_read(dev, 0x0034) | 0x0001);
+ b43_phy_set(dev, 0x0034, 0x0001);
b43_phy_rssiagc(dev, 0);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
b43_radio_init2060(dev);
@@ -339,9 +310,7 @@ void b43_phy_inita(struct b43_wldev *dev)
if ((phy->type == B43_PHYTYPE_G) &&
(dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
- b43_phy_write(dev, B43_PHY_OFDM(0x6E),
- (b43_phy_read(dev, B43_PHY_OFDM(0x6E))
- & 0xE000) | 0x3CF);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
}
}
@@ -520,14 +489,14 @@ static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
return;
b43_radio_write16(dev, 0x0004, 0x00C0);
b43_radio_write16(dev, 0x0005, 0x0008);
- b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) & 0xFFF7);
- b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) & 0xFFF7);
+ b43_phy_mask(dev, 0x0010, 0xFFF7);
+ b43_phy_mask(dev, 0x0011, 0xFFF7);
b43_radio_init2060(dev);
} else {
b43_radio_write16(dev, 0x0004, 0x00FF);
b43_radio_write16(dev, 0x0005, 0x00FB);
- b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008);
- b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
+ b43_phy_set(dev, 0x0010, 0x0008);
+ b43_phy_set(dev, 0x0011, 0x0008);
}
}
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index caac4a45f0b..e7b98f013b0 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -204,13 +204,9 @@ void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev,
& 0xFFF0) |
baseband_attenuation);
} else if (phy->analog > 1) {
- b43_phy_write(dev, B43_PHY_DACCTL,
- (b43_phy_read(dev, B43_PHY_DACCTL)
- & 0xFFC3) | (baseband_attenuation << 2));
+ b43_phy_maskset(dev, B43_PHY_DACCTL, 0xFFC3, (baseband_attenuation << 2));
} else {
- b43_phy_write(dev, B43_PHY_DACCTL,
- (b43_phy_read(dev, B43_PHY_DACCTL)
- & 0xFF87) | (baseband_attenuation << 3));
+ b43_phy_maskset(dev, B43_PHY_DACCTL, 0xFF87, (baseband_attenuation << 3));
}
}
@@ -252,17 +248,13 @@ static void b43_set_txpower_g(struct b43_wldev *dev,
b43_radio_write16(dev, 0x43,
(rf & 0x000F) | (tx_control & 0x0070));
} else {
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | (rf & 0x000F));
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & ~0x0070) | (tx_control &
- 0x0070));
+ b43_radio_maskset(dev, 0x43, 0xFFF0, (rf & 0x000F));
+ b43_radio_maskset(dev, 0x52, ~0x0070, (tx_control & 0x0070));
}
if (has_tx_magnification(phy)) {
b43_radio_write16(dev, 0x52, tx_magn | tx_bias);
} else {
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & 0xFFF0) | (tx_bias & 0x000F));
+ b43_radio_maskset(dev, 0x52, 0xFFF0, (tx_bias & 0x000F));
}
b43_lo_g_adjust(dev);
}
@@ -337,12 +329,9 @@ static void b43_set_all_gains(struct b43_wldev *dev,
if (third != -1) {
tmp = ((u16) third << 14) | ((u16) third << 6);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xBFBF) | tmp);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xBFBF) | tmp);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xBFBF) | tmp);
+ b43_phy_maskset(dev, 0x04A0, 0xBFBF, tmp);
+ b43_phy_maskset(dev, 0x04A1, 0xBFBF, tmp);
+ b43_phy_maskset(dev, 0x04A2, 0xBFBF, tmp);
}
b43_dummy_transmission(dev);
}
@@ -373,12 +362,9 @@ static void b43_set_original_gains(struct b43_wldev *dev)
for (i = start; i < end; i++)
b43_ofdmtab_write16(dev, table, i, i - start);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xBFBF) | 0x4040);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xBFBF) | 0x4040);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xBFBF) | 0x4000);
+ b43_phy_maskset(dev, 0x04A0, 0xBFBF, 0x4040);
+ b43_phy_maskset(dev, 0x04A1, 0xBFBF, 0x4040);
+ b43_phy_maskset(dev, 0x04A2, 0xBFBF, 0x4000);
b43_dummy_transmission(dev);
}
@@ -454,13 +440,11 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
backup[10] = b43_radio_read16(dev, 0x007A);
backup[11] = b43_radio_read16(dev, 0x0043);
- b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) & 0x7FFF);
- b43_phy_write(dev, 0x0001,
- (b43_phy_read(dev, 0x0001) & 0x3FFF) | 0x4000);
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFF3) | 0x0004);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & ~(0x1 | 0x2));
+ b43_phy_mask(dev, 0x0429, 0x7FFF);
+ b43_phy_maskset(dev, 0x0001, 0x3FFF, 0x4000);
+ b43_phy_set(dev, 0x0811, 0x000C);
+ b43_phy_maskset(dev, 0x0812, 0xFFF3, 0x0004);
+ b43_phy_mask(dev, 0x0802, ~(0x1 | 0x2));
if (phy->rev >= 6) {
backup[12] = b43_phy_read(dev, 0x002E);
backup[13] = b43_phy_read(dev, 0x002F);
@@ -475,13 +459,13 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
b43_phy_write(dev, 0x002F, 0);
b43_phy_write(dev, 0x080F, 0);
b43_phy_write(dev, 0x0810, 0);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478) | 0x0100);
- b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801) | 0x0040);
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) | 0x0040);
- b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014) | 0x0200);
+ b43_phy_set(dev, 0x0478, 0x0100);
+ b43_phy_set(dev, 0x0801, 0x0040);
+ b43_phy_set(dev, 0x0060, 0x0040);
+ b43_phy_set(dev, 0x0014, 0x0200);
}
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0070);
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0080);
+ b43_radio_set(dev, 0x007A, 0x0070);
+ b43_radio_set(dev, 0x007A, 0x0080);
udelay(30);
v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
@@ -501,40 +485,31 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
if (saved == 0xFFFF)
saved = 4;
} else {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x007F);
+ b43_radio_mask(dev, 0x007A, 0x007F);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, 0x0814,
- b43_phy_read(dev, 0x0814) | 0x0001);
- b43_phy_write(dev, 0x0815,
- b43_phy_read(dev, 0x0815) & 0xFFFE);
+ b43_phy_set(dev, 0x0814, 0x0001);
+ b43_phy_mask(dev, 0x0815, 0xFFFE);
}
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
- b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x000C);
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x0030);
- b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x0030);
+ b43_phy_set(dev, 0x0811, 0x000C);
+ b43_phy_set(dev, 0x0812, 0x000C);
+ b43_phy_set(dev, 0x0811, 0x0030);
+ b43_phy_set(dev, 0x0812, 0x0030);
b43_phy_write(dev, 0x005A, 0x0480);
b43_phy_write(dev, 0x0059, 0x0810);
b43_phy_write(dev, 0x0058, 0x000D);
if (phy->rev == 0) {
b43_phy_write(dev, 0x0003, 0x0122);
} else {
- b43_phy_write(dev, 0x000A, b43_phy_read(dev, 0x000A)
- | 0x2000);
+ b43_phy_set(dev, 0x000A, 0x2000);
}
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, 0x0814,
- b43_phy_read(dev, 0x0814) | 0x0004);
- b43_phy_write(dev, 0x0815,
- b43_phy_read(dev, 0x0815) & 0xFFFB);
+ b43_phy_set(dev, 0x0814, 0x0004);
+ b43_phy_mask(dev, 0x0815, 0xFFFB);
}
- b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003) & 0xFF9F)
- | 0x0040);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x000F);
+ b43_phy_maskset(dev, 0x0003, 0xFF9F, 0x0040);
+ b43_radio_set(dev, 0x007A, 0x000F);
b43_set_all_gains(dev, 3, 0, 1);
- b43_radio_write16(dev, 0x0043, (b43_radio_read16(dev, 0x0043)
- & 0x00F0) | 0x000F);
+ b43_radio_maskset(dev, 0x0043, 0x00F0, 0x000F);
udelay(30);
v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
if (v47F >= 0x20)
@@ -576,7 +551,7 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
b43_radio_write16(dev, 0x0043, backup[11]);
b43_radio_write16(dev, 0x007A, backup[10]);
b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x1 | 0x2);
- b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) | 0x8000);
+ b43_phy_set(dev, 0x0429, 0x8000);
b43_set_original_gains(dev);
if (phy->rev >= 6) {
b43_phy_write(dev, 0x0801, backup[16]);
@@ -604,9 +579,8 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
if (phy->radio_rev == 8)
b43_calc_nrssi_offset(dev);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF);
+ b43_phy_mask(dev, 0x0802, 0xFFFC);
backup[7] = b43_read16(dev, 0x03E2);
b43_write16(dev, 0x03E2, b43_read16(dev, 0x03E2) | 0x8000);
backup[0] = b43_radio_read16(dev, 0x007A);
@@ -633,66 +607,44 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
case 4:
case 6:
case 7:
- b43_phy_write(dev, 0x0478,
- b43_phy_read(dev, 0x0478)
- | 0x0100);
- b43_phy_write(dev, 0x0801,
- b43_phy_read(dev, 0x0801)
- | 0x0040);
+ b43_phy_set(dev, 0x0478, 0x0100);
+ b43_phy_set(dev, 0x0801, 0x0040);
break;
case 3:
case 5:
- b43_phy_write(dev, 0x0801,
- b43_phy_read(dev, 0x0801)
- & 0xFFBF);
+ b43_phy_mask(dev, 0x0801, 0xFFBF);
break;
}
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060)
- | 0x0040);
- b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014)
- | 0x0200);
+ b43_phy_set(dev, 0x0060, 0x0040);
+ b43_phy_set(dev, 0x0014, 0x0200);
}
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0070);
+ b43_radio_set(dev, 0x007A, 0x0070);
b43_set_all_gains(dev, 0, 8, 0);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x00F7);
+ b43_radio_mask(dev, 0x007A, 0x00F7);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0811,
- (b43_phy_read(dev, 0x0811) & 0xFFCF) |
- 0x0030);
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFCF) |
- 0x0010);
+ b43_phy_maskset(dev, 0x0811, 0xFFCF, 0x0030);
+ b43_phy_maskset(dev, 0x0812, 0xFFCF, 0x0010);
}
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0080);
+ b43_radio_set(dev, 0x007A, 0x0080);
udelay(20);
nrssi0 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
if (nrssi0 >= 0x0020)
nrssi0 -= 0x0040;
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x007F);
+ b43_radio_mask(dev, 0x007A, 0x007F);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003)
- & 0xFF9F) | 0x0040);
+ b43_phy_maskset(dev, 0x0003, 0xFF9F, 0x0040);
}
b43_write16(dev, B43_MMIO_CHANNEL_EXT,
b43_read16(dev, B43_MMIO_CHANNEL_EXT)
| 0x2000);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x000F);
+ b43_radio_set(dev, 0x007A, 0x000F);
b43_phy_write(dev, 0x0015, 0xF330);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFCF) |
- 0x0020);
- b43_phy_write(dev, 0x0811,
- (b43_phy_read(dev, 0x0811) & 0xFFCF) |
- 0x0020);
+ b43_phy_maskset(dev, 0x0812, 0xFFCF, 0x0020);
+ b43_phy_maskset(dev, 0x0811, 0xFFCF, 0x0020);
}
b43_set_all_gains(dev, 3, 0, 1);
@@ -726,10 +678,8 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_G_LO_CONTROL, backup[13]);
}
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0812,
- b43_phy_read(dev, 0x0812) & 0xFFCF);
- b43_phy_write(dev, 0x0811,
- b43_phy_read(dev, 0x0811) & 0xFFCF);
+ b43_phy_mask(dev, 0x0812, 0xFFCF);
+ b43_phy_mask(dev, 0x0811, 0xFFCF);
}
b43_radio_write16(dev, 0x007A, backup[0]);
@@ -743,11 +693,9 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
b43_phy_write(dev, 0x0059, backup[5]);
b43_phy_write(dev, 0x0058, backup[6]);
b43_synth_pu_workaround(dev, phy->channel);
- b43_phy_write(dev, 0x0802,
- b43_phy_read(dev, 0x0802) | (0x0001 | 0x0002));
+ b43_phy_set(dev, 0x0802, (0x0001 | 0x0002));
b43_set_original_gains(dev);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x8000);
if (phy->rev >= 3) {
b43_phy_write(dev, 0x0801, backup[14]);
b43_phy_write(dev, 0x0060, backup[15]);
@@ -774,13 +722,9 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
if (tmp16 >= 0x20)
tmp16 -= 0x40;
if (tmp16 < 3) {
- b43_phy_write(dev, 0x048A,
- (b43_phy_read(dev, 0x048A)
- & 0xF000) | 0x09EB);
+ b43_phy_maskset(dev, 0x048A, 0xF000, 0x09EB);
} else {
- b43_phy_write(dev, 0x048A,
- (b43_phy_read(dev, 0x048A)
- & 0xF000) | 0x0AED);
+ b43_phy_maskset(dev, 0x048A, 0xF000, 0x0AED);
}
} else {
if (gphy->interfmode == B43_INTERFMODE_NONWLAN) {
@@ -823,7 +767,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
* interference mitigation code.
* It is save to restore values in random order.
*/
-static void _stack_save(u32 * _stackptr, size_t * stackidx,
+static void _stack_save(u32 *_stackptr, size_t *stackidx,
u8 id, u16 offset, u16 value)
{
u32 *stackptr = &(_stackptr[*stackidx]);
@@ -837,7 +781,7 @@ static void _stack_save(u32 * _stackptr, size_t * stackidx,
B43_WARN_ON(*stackidx >= B43_INTERFSTACK_SIZE);
}
-static u16 _stack_restore(u32 * stackptr, u8 id, u16 offset)
+static u16 _stack_restore(u32 *stackptr, u8 id, u16 offset)
{
size_t i;
@@ -901,11 +845,8 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
switch (mode) {
case B43_INTERFMODE_NONWLAN:
if (phy->rev != 1) {
- b43_phy_write(dev, 0x042B,
- b43_phy_read(dev, 0x042B) | 0x0800);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev,
- B43_PHY_G_CRS) & ~0x4000);
+ b43_phy_set(dev, 0x042B, 0x0800);
+ b43_phy_mask(dev, B43_PHY_G_CRS, ~0x4000);
break;
}
radio_stacksave(0x0078);
@@ -924,26 +865,19 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
phy_stacksave(0x0406);
b43_phy_write(dev, 0x0406, 0x7E28);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x0800);
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev,
- B43_PHY_RADIO_BITFIELD) | 0x1000);
+ b43_phy_set(dev, 0x042B, 0x0800);
+ b43_phy_set(dev, B43_PHY_RADIO_BITFIELD, 0x1000);
phy_stacksave(0x04A0);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xC0C0) | 0x0008);
+ b43_phy_maskset(dev, 0x04A0, 0xC0C0, 0x0008);
phy_stacksave(0x04A1);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xC0C0) | 0x0605);
+ b43_phy_maskset(dev, 0x04A1, 0xC0C0, 0x0605);
phy_stacksave(0x04A2);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xC0C0) | 0x0204);
+ b43_phy_maskset(dev, 0x04A2, 0xC0C0, 0x0204);
phy_stacksave(0x04A8);
- b43_phy_write(dev, 0x04A8,
- (b43_phy_read(dev, 0x04A8) & 0xC0C0) | 0x0803);
+ b43_phy_maskset(dev, 0x04A8, 0xC0C0, 0x0803);
phy_stacksave(0x04AB);
- b43_phy_write(dev, 0x04AB,
- (b43_phy_read(dev, 0x04AB) & 0xC0C0) | 0x0605);
+ b43_phy_maskset(dev, 0x04AB, 0xC0C0, 0x0605);
phy_stacksave(0x04A7);
b43_phy_write(dev, 0x04A7, 0x0002);
@@ -999,12 +933,8 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
phy_stacksave(0x042B);
phy_stacksave(0x048C);
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
- & ~0x1000);
- b43_phy_write(dev, B43_PHY_G_CRS,
- (b43_phy_read(dev, B43_PHY_G_CRS)
- & 0xFFFC) | 0x0002);
+ b43_phy_mask(dev, B43_PHY_RADIO_BITFIELD, ~0x1000);
+ b43_phy_maskset(dev, B43_PHY_G_CRS, 0xFFFC, 0x0002);
b43_phy_write(dev, 0x0033, 0x0800);
b43_phy_write(dev, 0x04A3, 0x2027);
@@ -1013,8 +943,7 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
b43_phy_write(dev, 0x04AA, 0x1CA8);
b43_phy_write(dev, 0x04AC, 0x287A);
- b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
- & 0xFFC0) | 0x001A);
+ b43_phy_maskset(dev, 0x04A0, 0xFFC0, 0x001A);
b43_phy_write(dev, 0x04A7, 0x000D);
if (phy->rev < 2) {
@@ -1027,65 +956,41 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
b43_phy_write(dev, 0x04C1, 0x0059);
}
- b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
- & 0xC0FF) | 0x1800);
- b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
- & 0xFFC0) | 0x0015);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xCFFF) | 0x1000);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xF0FF) | 0x0A00);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xCFFF) | 0x1000);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xF0FF) | 0x0800);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xFFCF) | 0x0010);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xFFF0) | 0x0005);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xFFCF) | 0x0010);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xFFF0) | 0x0006);
- b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
- & 0xF0FF) | 0x0800);
- b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
- & 0xF0FF) | 0x0500);
- b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
- & 0xFFF0) | 0x000B);
+ b43_phy_maskset(dev, 0x04A1, 0xC0FF, 0x1800);
+ b43_phy_maskset(dev, 0x04A1, 0xFFC0, 0x0015);
+ b43_phy_maskset(dev, 0x04A8, 0xCFFF, 0x1000);
+ b43_phy_maskset(dev, 0x04A8, 0xF0FF, 0x0A00);
+ b43_phy_maskset(dev, 0x04AB, 0xCFFF, 0x1000);
+ b43_phy_maskset(dev, 0x04AB, 0xF0FF, 0x0800);
+ b43_phy_maskset(dev, 0x04AB, 0xFFCF, 0x0010);
+ b43_phy_maskset(dev, 0x04AB, 0xFFF0, 0x0005);
+ b43_phy_maskset(dev, 0x04A8, 0xFFCF, 0x0010);
+ b43_phy_maskset(dev, 0x04A8, 0xFFF0, 0x0006);
+ b43_phy_maskset(dev, 0x04A2, 0xF0FF, 0x0800);
+ b43_phy_maskset(dev, 0x04A0, 0xF0FF, 0x0500);
+ b43_phy_maskset(dev, 0x04A2, 0xFFF0, 0x000B);
if (phy->rev >= 3) {
- b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
- & ~0x8000);
- b43_phy_write(dev, 0x0415, (b43_phy_read(dev, 0x0415)
- & 0x8000) | 0x36D8);
- b43_phy_write(dev, 0x0416, (b43_phy_read(dev, 0x0416)
- & 0x8000) | 0x36D8);
- b43_phy_write(dev, 0x0417, (b43_phy_read(dev, 0x0417)
- & 0xFE00) | 0x016D);
+ b43_phy_mask(dev, 0x048A, (u16)~0x8000);
+ b43_phy_maskset(dev, 0x0415, 0x8000, 0x36D8);
+ b43_phy_maskset(dev, 0x0416, 0x8000, 0x36D8);
+ b43_phy_maskset(dev, 0x0417, 0xFE00, 0x016D);
} else {
- b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
- | 0x1000);
- b43_phy_write(dev, 0x048A, (b43_phy_read(dev, 0x048A)
- & 0x9FFF) | 0x2000);
+ b43_phy_set(dev, 0x048A, 0x1000);
+ b43_phy_maskset(dev, 0x048A, 0x9FFF, 0x2000);
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ACIW);
}
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B)
- | 0x0800);
+ b43_phy_set(dev, 0x042B, 0x0800);
}
- b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
- & 0xF0FF) | 0x0200);
+ b43_phy_maskset(dev, 0x048C, 0xF0FF, 0x0200);
if (phy->rev == 2) {
- b43_phy_write(dev, 0x04AE, (b43_phy_read(dev, 0x04AE)
- & 0xFF00) | 0x007F);
- b43_phy_write(dev, 0x04AD, (b43_phy_read(dev, 0x04AD)
- & 0x00FF) | 0x1300);
+ b43_phy_maskset(dev, 0x04AE, 0xFF00, 0x007F);
+ b43_phy_maskset(dev, 0x04AD, 0x00FF, 0x1300);
} else if (phy->rev >= 6) {
b43_ofdmtab_write16(dev, 0x1A00, 0x3, 0x007F);
b43_ofdmtab_write16(dev, 0x1A00, 0x2, 0x007F);
- b43_phy_write(dev, 0x04AD, b43_phy_read(dev, 0x04AD)
- & 0x00FF);
+ b43_phy_mask(dev, 0x04AD, 0x00FF);
}
b43_calc_nrssi_slope(dev);
break;
@@ -1104,24 +1009,18 @@ b43_radio_interference_mitigation_disable(struct b43_wldev *dev, int mode)
switch (mode) {
case B43_INTERFMODE_NONWLAN:
if (phy->rev != 1) {
- b43_phy_write(dev, 0x042B,
- b43_phy_read(dev, 0x042B) & ~0x0800);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev,
- B43_PHY_G_CRS) | 0x4000);
+ b43_phy_mask(dev, 0x042B, ~0x0800);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x4000);
break;
}
radio_stackrestore(0x0078);
b43_calc_nrssi_threshold(dev);
phy_stackrestore(0x0406);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) & ~0x0800);
+ b43_phy_mask(dev, 0x042B, ~0x0800);
if (!dev->bad_frames_preempt) {
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
- & ~(1 << 11));
+ b43_phy_mask(dev, B43_PHY_RADIO_BITFIELD, ~(1 << 11));
}
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x4000);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x4000);
phy_stackrestore(0x04A0);
phy_stackrestore(0x04A1);
phy_stackrestore(0x04A2);
@@ -1389,17 +1288,10 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
sav.phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
sav.phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER)
- | 0x0003);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
- & 0xFFFC);
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0x7FFF);
- b43_phy_write(dev, B43_PHY_CLASSCTL,
- b43_phy_read(dev, B43_PHY_CLASSCTL)
- & 0xFFFC);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0003);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x7FFF);
+ b43_phy_mask(dev, B43_PHY_CLASSCTL, 0xFFFC);
if (has_loopback_gain(phy)) {
sav.phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
sav.phy_lo_ctl = b43_phy_read(dev, B43_PHY_LO_CTL);
@@ -1420,8 +1312,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2) | 0x8000);
sav.phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL);
- b43_phy_write(dev, B43_PHY_SYNCCTL, b43_phy_read(dev, B43_PHY_SYNCCTL)
- & 0xFF7F);
+ b43_phy_mask(dev, B43_PHY_SYNCCTL, 0xFF7F);
sav.reg_3E6 = b43_read16(dev, 0x3E6);
sav.reg_3F4 = b43_read16(dev, 0x3F4);
@@ -1429,9 +1320,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
b43_write16(dev, 0x03E6, 0x0122);
} else {
if (phy->analog >= 2) {
- b43_phy_write(dev, B43_PHY_CCK(0x03),
- (b43_phy_read(dev, B43_PHY_CCK(0x03))
- & 0xFFBF) | 0x40);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x03), 0xFFBF, 0x40);
}
b43_write16(dev, B43_MMIO_CHANNEL_EXT,
(b43_read16(dev, B43_MMIO_CHANNEL_EXT) | 0x2000));
@@ -1454,14 +1343,12 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
LPD(0, 0, 1)));
}
b43_phy_write(dev, B43_PHY_PGACTL, 0xBFA0);
- b43_radio_write16(dev, 0x51, b43_radio_read16(dev, 0x51)
- | 0x0004);
+ b43_radio_set(dev, 0x51, 0x0004);
if (phy->radio_rev == 8) {
b43_radio_write16(dev, 0x43, 0x1F);
} else {
b43_radio_write16(dev, 0x52, 0);
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | 0x0009);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, 0x0009);
}
b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
@@ -1610,8 +1497,7 @@ static void b43_phy_initb5(struct b43_wldev *dev)
u8 old_channel;
if (phy->analog == 1) {
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)
- | 0x0050);
+ b43_radio_set(dev, 0x007A, 0x0050);
}
if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
(bus->boardinfo.type != SSB_BOARD_BU4306)) {
@@ -1621,39 +1507,29 @@ static void b43_phy_initb5(struct b43_wldev *dev)
value += 0x202;
}
}
- b43_phy_write(dev, 0x0035, (b43_phy_read(dev, 0x0035) & 0xF0FF)
- | 0x0700);
+ b43_phy_maskset(dev, 0x0035, 0xF0FF, 0x0700);
if (phy->radio_ver == 0x2050)
b43_phy_write(dev, 0x0038, 0x0667);
if (phy->gmode || phy->rev >= 2) {
if (phy->radio_ver == 0x2050) {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A)
- | 0x0020);
- b43_radio_write16(dev, 0x0051,
- b43_radio_read16(dev, 0x0051)
- | 0x0004);
+ b43_radio_set(dev, 0x007A, 0x0020);
+ b43_radio_set(dev, 0x0051, 0x0004);
}
b43_write16(dev, B43_MMIO_PHY_RADIO, 0x0000);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
+ b43_phy_set(dev, 0x0802, 0x0100);
+ b43_phy_set(dev, 0x042B, 0x2000);
b43_phy_write(dev, 0x001C, 0x186A);
- b43_phy_write(dev, 0x0013,
- (b43_phy_read(dev, 0x0013) & 0x00FF) | 0x1900);
- b43_phy_write(dev, 0x0035,
- (b43_phy_read(dev, 0x0035) & 0xFFC0) | 0x0064);
- b43_phy_write(dev, 0x005D,
- (b43_phy_read(dev, 0x005D) & 0xFF80) | 0x000A);
+ b43_phy_maskset(dev, 0x0013, 0x00FF, 0x1900);
+ b43_phy_maskset(dev, 0x0035, 0xFFC0, 0x0064);
+ b43_phy_maskset(dev, 0x005D, 0xFF80, 0x000A);
}
if (dev->bad_frames_preempt) {
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev,
- B43_PHY_RADIO_BITFIELD) | (1 << 11));
+ b43_phy_set(dev, B43_PHY_RADIO_BITFIELD, (1 << 11));
}
if (phy->analog == 1) {
@@ -1695,7 +1571,7 @@ static void b43_phy_initb5(struct b43_wldev *dev)
b43_radio_write16(dev, 0x005B, 0x007B);
b43_radio_write16(dev, 0x005C, 0x00B0);
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0007);
+ b43_radio_set(dev, 0x007A, 0x0007);
b43_gphy_channel_switch(dev, old_channel, 0);
@@ -1771,12 +1647,10 @@ static void b43_phy_initb6(struct b43_wldev *dev)
val += 0x0202;
}
if (phy->type == B43_PHYTYPE_G) {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0020);
- b43_radio_write16(dev, 0x0051,
- b43_radio_read16(dev, 0x0051) | 0x0004);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
+ b43_radio_set(dev, 0x007A, 0x0020);
+ b43_radio_set(dev, 0x0051, 0x0004);
+ b43_phy_set(dev, 0x0802, 0x0100);
+ b43_phy_set(dev, 0x042B, 0x2000);
b43_phy_write(dev, 0x5B, 0);
b43_phy_write(dev, 0x5C, 0);
}
@@ -1801,8 +1675,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_radio_write16(dev, 0x5B, 0x7B);
b43_radio_write16(dev, 0x5C, 0xB0);
}
- b43_radio_write16(dev, 0x007A,
- (b43_radio_read16(dev, 0x007A) & 0x00F8) | 0x0007);
+ b43_radio_maskset(dev, 0x007A, 0x00F8, 0x0007);
b43_gphy_channel_switch(dev, old_channel, 0);
@@ -1814,19 +1687,16 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_phy_write(dev, 0x0038, 0x0668);
b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
if (phy->radio_rev <= 5) {
- b43_phy_write(dev, 0x5D, (b43_phy_read(dev, 0x5D)
- & 0xFF80) | 0x0003);
+ b43_phy_maskset(dev, 0x5D, 0xFF80, 0x0003);
}
if (phy->radio_rev <= 2)
b43_radio_write16(dev, 0x005D, 0x000D);
if (phy->analog == 4) {
b43_write16(dev, 0x3E4, 9);
- b43_phy_write(dev, 0x61, b43_phy_read(dev, 0x61)
- & 0x0FFF);
+ b43_phy_mask(dev, 0x61, 0x0FFF);
} else {
- b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0)
- | 0x0004);
+ b43_phy_maskset(dev, 0x0002, 0xFFC0, 0x0004);
}
if (phy->type == B43_PHYTYPE_B)
B43_WARN_ON(1);
@@ -1868,63 +1738,39 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
backup_radio[1] = b43_radio_read16(dev, 0x43);
backup_radio[2] = b43_radio_read16(dev, 0x7A);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) & 0x3FFF);
- b43_phy_write(dev, B43_PHY_CCKBBANDCFG,
- b43_phy_read(dev, B43_PHY_CCKBBANDCFG) | 0x8000);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0002);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFD);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0001);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFE);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x3FFF);
+ b43_phy_set(dev, B43_PHY_CCKBBANDCFG, 0x8000);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0002);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xFFFD);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0001);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xFFFE);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0001);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFE);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0002);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFD);
- }
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x000C);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x000C);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0030);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xFFCF) | 0x10);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0001);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFE);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0002);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFD);
+ }
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x000C);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x000C);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0030);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xFFCF, 0x10);
b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780);
b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
- b43_phy_write(dev, B43_PHY_CCK(0x0A),
- b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000);
+ b43_phy_set(dev, B43_PHY_CCK(0x0A), 0x2000);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFB);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0004);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFB);
}
- b43_phy_write(dev, B43_PHY_CCK(0x03),
- (b43_phy_read(dev, B43_PHY_CCK(0x03))
- & 0xFF9F) | 0x40);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x03), 0xFF9F, 0x40);
if (phy->radio_rev == 8) {
b43_radio_write16(dev, 0x43, 0x000F);
} else {
b43_radio_write16(dev, 0x52, 0);
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | 0x9);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, 0x9);
}
b43_gphy_set_baseband_attenuation(dev, 11);
@@ -1934,45 +1780,28 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
b43_phy_write(dev, B43_PHY_LO_CTL, 0);
- b43_phy_write(dev, B43_PHY_CCK(0x2B),
- (b43_phy_read(dev, B43_PHY_CCK(0x2B))
- & 0xFFC0) | 0x01);
- b43_phy_write(dev, B43_PHY_CCK(0x2B),
- (b43_phy_read(dev, B43_PHY_CCK(0x2B))
- & 0xC0FF) | 0x800);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x2B), 0xFFC0, 0x01);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x2B), 0xC0FF, 0x800);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0100);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0100);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF);
if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
if (phy->rev >= 7) {
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER)
- | 0x0800);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL)
- | 0x8000);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0800);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000);
}
}
- b43_radio_write16(dev, 0x7A, b43_radio_read16(dev, 0x7A)
- & 0x00F7);
+ b43_radio_mask(dev, 0x7A, 0x00F7);
j = 0;
loop_i_max = (phy->radio_rev == 8) ? 15 : 9;
for (i = 0; i < loop_i_max; i++) {
for (j = 0; j < 16; j++) {
b43_radio_write16(dev, 0x43, i);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xF0FF) | (j << 8));
- b43_phy_write(dev, B43_PHY_PGACTL,
- (b43_phy_read(dev, B43_PHY_PGACTL)
- & 0x0FFF) | 0xA000);
- b43_phy_write(dev, B43_PHY_PGACTL,
- b43_phy_read(dev, B43_PHY_PGACTL)
- | 0xF000);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xF0FF, (j << 8));
+ b43_phy_maskset(dev, B43_PHY_PGACTL, 0x0FFF, 0xA000);
+ b43_phy_set(dev, B43_PHY_PGACTL, 0xF000);
udelay(20);
if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
goto exit_loop1;
@@ -1982,20 +1811,12 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
loop1_outer_done = i;
loop1_inner_done = j;
if (j >= 8) {
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL)
- | 0x30);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x30);
trsw_rx = 0x1B;
for (j = j - 8; j < 16; j++) {
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xF0FF) | (j << 8));
- b43_phy_write(dev, B43_PHY_PGACTL,
- (b43_phy_read(dev, B43_PHY_PGACTL)
- & 0x0FFF) | 0xA000);
- b43_phy_write(dev, B43_PHY_PGACTL,
- b43_phy_read(dev, B43_PHY_PGACTL)
- | 0xF000);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xF0FF, (j << 8));
+ b43_phy_maskset(dev, B43_PHY_PGACTL, 0x0FFF, 0xA000);
+ b43_phy_set(dev, B43_PHY_PGACTL, 0xF000);
udelay(20);
trsw_rx -= 3;
if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
@@ -2046,34 +1867,24 @@ static void b43_hardware_pctl_early_init(struct b43_wldev *dev)
return;
}
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036) & 0xFEFF);
+ b43_phy_mask(dev, 0x0036, 0xFEFF);
b43_phy_write(dev, 0x002F, 0x0202);
- b43_phy_write(dev, 0x047C, b43_phy_read(dev, 0x047C) | 0x0002);
- b43_phy_write(dev, 0x047A, b43_phy_read(dev, 0x047A) | 0xF000);
+ b43_phy_set(dev, 0x047C, 0x0002);
+ b43_phy_set(dev, 0x047A, 0xF000);
if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
- b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
- & 0xFF0F) | 0x0010);
- b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
- | 0x8000);
- b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
- & 0xFFC0) | 0x0010);
+ b43_phy_maskset(dev, 0x047A, 0xFF0F, 0x0010);
+ b43_phy_set(dev, 0x005D, 0x8000);
+ b43_phy_maskset(dev, 0x004E, 0xFFC0, 0x0010);
b43_phy_write(dev, 0x002E, 0xC07F);
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0400);
+ b43_phy_set(dev, 0x0036, 0x0400);
} else {
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0200);
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0400);
- b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
- & 0x7FFF);
- b43_phy_write(dev, 0x004F, b43_phy_read(dev, 0x004F)
- & 0xFFFE);
- b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
- & 0xFFC0) | 0x0010);
+ b43_phy_set(dev, 0x0036, 0x0200);
+ b43_phy_set(dev, 0x0036, 0x0400);
+ b43_phy_mask(dev, 0x005D, 0x7FFF);
+ b43_phy_mask(dev, 0x004F, 0xFFFE);
+ b43_phy_maskset(dev, 0x004E, 0xFFC0, 0x0010);
b43_phy_write(dev, 0x002E, 0xC07F);
- b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
- & 0xFF0F) | 0x0010);
+ b43_phy_maskset(dev, 0x047A, 0xFF0F, 0x0010);
}
}
@@ -2089,22 +1900,17 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
return;
}
- b43_phy_write(dev, 0x0036, (b43_phy_read(dev, 0x0036) & 0xFFC0)
- | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
- b43_phy_write(dev, 0x0478, (b43_phy_read(dev, 0x0478) & 0xFF00)
- | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
+ b43_phy_maskset(dev, 0x0036, 0xFFC0, (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
+ b43_phy_maskset(dev, 0x0478, 0xFF00, (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
b43_gphy_tssi_power_lt_init(dev);
b43_gphy_gain_lt_init(dev);
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) & 0xFFBF);
+ b43_phy_mask(dev, 0x0060, 0xFFBF);
b43_phy_write(dev, 0x0014, 0x0000);
B43_WARN_ON(phy->rev < 6);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
- | 0x0800);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
- & 0xFEFF);
- b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)
- & 0xFFBF);
+ b43_phy_set(dev, 0x0478, 0x0800);
+ b43_phy_mask(dev, 0x0478, 0xFEFF);
+ b43_phy_mask(dev, 0x0801, 0xFFBF);
b43_gphy_dc_lt_init(dev, 1);
@@ -2139,9 +1945,7 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
b43_hardware_pctl_early_init(dev);
if (gphy->cur_idle_tssi == 0) {
if (phy->radio_ver == 0x2050 && phy->analog == 0) {
- b43_radio_write16(dev, 0x0076,
- (b43_radio_read16(dev, 0x0076)
- & 0x00F7) | 0x0084);
+ b43_radio_maskset(dev, 0x0076, 0x00F7, 0x0084);
} else {
struct b43_rfatt rfatt;
struct b43_bbatt bbatt;
@@ -2174,9 +1978,7 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
}
}
if (phy->radio_ver == 0x2050 && phy->analog == 0) {
- b43_radio_write16(dev, 0x0076,
- b43_radio_read16(dev, 0x0076)
- & 0xFF7B);
+ b43_radio_mask(dev, 0x0076, 0xFF7B);
} else {
b43_set_txpower_g(dev, &old_bbatt,
&old_rfatt, old_tx_control);
@@ -2220,20 +2022,14 @@ static void b43_phy_initg(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_OFDM(0xC3), 0x8006);
}
if (tmp == 5) {
- b43_phy_write(dev, B43_PHY_OFDM(0xCC),
- (b43_phy_read(dev, B43_PHY_OFDM(0xCC))
- & 0x00FF) | 0x1F00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xCC), 0x00FF, 0x1F00);
}
}
if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
b43_phy_write(dev, B43_PHY_OFDM(0x7E), 0x78);
if (phy->radio_rev == 8) {
- b43_phy_write(dev, B43_PHY_EXTG(0x01),
- b43_phy_read(dev, B43_PHY_EXTG(0x01))
- | 0x80);
- b43_phy_write(dev, B43_PHY_OFDM(0x3E),
- b43_phy_read(dev, B43_PHY_OFDM(0x3E))
- | 0x4);
+ b43_phy_set(dev, B43_PHY_EXTG(0x01), 0x80);
+ b43_phy_set(dev, B43_PHY_OFDM(0x3E), 0x4);
}
if (has_loopback_gain(phy))
b43_calc_loopback_gain(dev);
@@ -2251,15 +2047,10 @@ static void b43_phy_initg(struct b43_wldev *dev)
| gphy->lo_control->tx_bias | gphy->
lo_control->tx_magn);
} else {
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52) & 0xFFF0)
- | gphy->lo_control->tx_bias);
+ b43_radio_maskset(dev, 0x52, 0xFFF0, gphy->lo_control->tx_bias);
}
if (phy->rev >= 6) {
- b43_phy_write(dev, B43_PHY_CCK(0x36),
- (b43_phy_read(dev, B43_PHY_CCK(0x36))
- & 0x0FFF) | (gphy->lo_control->
- tx_bias << 12));
+ b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12));
}
if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
@@ -2298,11 +2089,8 @@ static void b43_phy_initg(struct b43_wldev *dev)
but OFDM is legal everywhere */
if ((dev->dev->bus->chip_id == 0x4306
&& dev->dev->bus->chip_package == 2) || 0) {
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0xBFFF);
- b43_phy_write(dev, B43_PHY_OFDM(0xC3),
- b43_phy_read(dev, B43_PHY_OFDM(0xC3))
- & 0x7FFF);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF);
+ b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF);
}
}
@@ -2504,9 +2292,8 @@ static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
b43_phy_lock(dev);
b43_radio_lock(dev);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
+ b43_phy_mask(dev, 0x0802, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF);
b43_set_all_gains(dev, 3, 8, 1);
start = (channel - 5 > 0) ? channel - 5 : 1;
@@ -2517,11 +2304,9 @@ static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
ret[i - 1] = b43_gphy_aci_detect(dev, i);
}
b43_switch_channel(dev, channel);
- b43_phy_write(dev, 0x0802,
- (b43_phy_read(dev, 0x0802) & 0xFFFC) | 0x0003);
- b43_phy_write(dev, 0x0403, b43_phy_read(dev, 0x0403) & 0xFFF8);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
+ b43_phy_maskset(dev, 0x0802, 0xFFFC, 0x0003);
+ b43_phy_mask(dev, 0x0403, 0xFFF8);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x8000);
b43_set_original_gains(dev);
for (i = 0; i < 13; i++) {
if (!ret[i])
@@ -2565,8 +2350,8 @@ static s8 b43_tssi2dbm_entry(s8 entry[], u8 index,
return 0;
}
-u8 * b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
- s16 pab0, s16 pab1, s16 pab2)
+u8 *b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
+ s16 pab0, s16 pab1, s16 pab2)
{
unsigned int i;
u8 *tab;
@@ -3191,6 +2976,7 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
* Baseband attennuation. Subtract it. */
bbatt_delta -= 4 * rfatt_delta;
+#if B43_DEBUG
if (b43_debug(dev, B43_DBG_XMITPOWER)) {
int dbm = pwr_adjust < 0 ? -pwr_adjust : pwr_adjust;
b43dbg(dev->wl,
@@ -3199,6 +2985,8 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
(pwr_adjust < 0 ? "-" : ""), Q52_ARG(dbm),
bbatt_delta, rfatt_delta);
}
+#endif /* DEBUG */
+
/* So do we finally need to adjust something in hardware? */
if ((rfatt_delta == 0) && (bbatt_delta == 0))
goto no_adjustment_needed;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index c5d9dc3667c..58e319d6b1e 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -3,7 +3,7 @@
Broadcom B43 wireless driver
IEEE 802.11g LP-PHY driver
- Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
+ Copyright (c) 2008-2009 Michael Buesch <mb@bu3sch.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,8 +23,10 @@
*/
#include "b43.h"
+#include "main.h"
#include "phy_lp.h"
#include "phy_common.h"
+#include "tables_lpphy.h"
static int b43_lpphy_op_allocate(struct b43_wldev *dev)
@@ -57,9 +59,394 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
dev->phy.lp = NULL;
}
-static int b43_lpphy_op_init(struct b43_wldev *dev)
+static void lpphy_table_init(struct b43_wldev *dev)
+{
+ //TODO
+}
+
+static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
+{
+ B43_WARN_ON(1);//TODO rev < 2 not supported, yet.
+}
+
+static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
+{
+ struct ssb_bus *bus = dev->dev->bus;
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+
+ b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL, 0x8800);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVR, 0);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0);
+ b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, 0);
+ b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF9), 0);
+ b43_phy_write(dev, B43_LPPHY_TR_LOOKUP_1, 0);
+ b43_phy_set(dev, B43_LPPHY_ADC_COMPENSATION_CTL, 0x10);
+ b43_phy_maskset(dev, B43_LPPHY_OFDMSYNCTHRESH0, 0xFF00, 0x78);
+ b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xF8FF, 0x200);
+ b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xFF00, 0x7F);
+ b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xFF0F, 0x40);
+ b43_phy_maskset(dev, B43_LPPHY_PREAMBLECONFIRMTO, 0xFF00, 0x2);
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000);
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000);
+ b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x10);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0xFF00, 0xF4);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0x00FF, 0xF100);
+ b43_phy_write(dev, B43_LPPHY_CLIPTHRESH, 0x48);
+ b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0xFF00, 0x46);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xE4), 0xFF00, 0x10);
+ b43_phy_maskset(dev, B43_LPPHY_PWR_THRESH1, 0xFFF0, 0x9);
+ b43_phy_mask(dev, B43_LPPHY_GAINDIRECTMISMATCH, ~0xF);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5500);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xF81F, 0xA0);
+ b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300);
+ b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00);
+ if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+ b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA);
+ } else {
+ b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x1E00);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xD);
+ }
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFE), 0xFFE0, 0x1F);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x100), 0xFF00, 0x19);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0x03FF, 0x3C00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFE), 0xFC1F, 0x3E0);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x100), 0x00FF, 0x1900);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0x83FF, 0x5800);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12);
+ b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000);
+
+ b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
+ b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x40);
+ b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xF0FF, 0xB00);
+ b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x6);
+ b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0x9D00);
+ b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0xFF00, 0xA1);
+ } else /* 5GHz */
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x40);
+
+ b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0xFF00, 0xB3);
+ b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00);
+ b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB, 0xFF00, lpphy->rx_pwr_offset);
+ b43_phy_set(dev, B43_LPPHY_RESET_CTL, 0x44);
+ b43_phy_write(dev, B43_LPPHY_RESET_CTL, 0x80);
+ b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, 0xA954);
+ b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_1,
+ 0x2000 | ((u16)lpphy->rssi_gs << 10) |
+ ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf);
+}
+
+static void lpphy_baseband_init(struct b43_wldev *dev)
+{
+ lpphy_table_init(dev);
+ if (dev->phy.rev >= 2)
+ lpphy_baseband_rev2plus_init(dev);
+ else
+ lpphy_baseband_rev0_1_init(dev);
+}
+
+struct b2062_freqdata {
+ u16 freq;
+ u8 data[6];
+};
+
+/* Initialize the 2062 radio. */
+static void lpphy_2062_init(struct b43_wldev *dev)
+{
+ struct ssb_bus *bus = dev->dev->bus;
+ u32 crystalfreq, pdiv, tmp, ref;
+ unsigned int i;
+ const struct b2062_freqdata *fd = NULL;
+
+ static const struct b2062_freqdata freqdata_tab[] = {
+ { .freq = 12000, .data[0] = 6, .data[1] = 6, .data[2] = 6,
+ .data[3] = 6, .data[4] = 10, .data[5] = 6, },
+ { .freq = 13000, .data[0] = 4, .data[1] = 4, .data[2] = 4,
+ .data[3] = 4, .data[4] = 11, .data[5] = 7, },
+ { .freq = 14400, .data[0] = 3, .data[1] = 3, .data[2] = 3,
+ .data[3] = 3, .data[4] = 12, .data[5] = 7, },
+ { .freq = 16200, .data[0] = 3, .data[1] = 3, .data[2] = 3,
+ .data[3] = 3, .data[4] = 13, .data[5] = 8, },
+ { .freq = 18000, .data[0] = 2, .data[1] = 2, .data[2] = 2,
+ .data[3] = 2, .data[4] = 14, .data[5] = 8, },
+ { .freq = 19200, .data[0] = 1, .data[1] = 1, .data[2] = 1,
+ .data[3] = 1, .data[4] = 14, .data[5] = 9, },
+ };
+
+ b2062_upload_init_table(dev);
+
+ b43_radio_write(dev, B2062_N_TX_CTL3, 0);
+ b43_radio_write(dev, B2062_N_TX_CTL4, 0);
+ b43_radio_write(dev, B2062_N_TX_CTL5, 0);
+ b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40);
+ b43_radio_write(dev, B2062_N_PDN_CTL0, 0);
+ b43_radio_write(dev, B2062_N_CALIB_TS, 0x10);
+ b43_radio_write(dev, B2062_N_CALIB_TS, 0);
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1);
+ else
+ b43_radio_mask(dev, B2062_N_TSSI_CTL0, ~0x1);
+
+ /* Get the crystal freq, in Hz. */
+ crystalfreq = bus->chipco.pmu.crystalfreq * 1000;
+
+ B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU));
+ B43_WARN_ON(crystalfreq == 0);
+
+ if (crystalfreq >= 30000000) {
+ pdiv = 1;
+ b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB);
+ } else {
+ pdiv = 2;
+ b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4);
+ }
+
+ tmp = (800000000 * pdiv + crystalfreq) / (32000000 * pdiv);
+ tmp = (tmp - 1) & 0xFF;
+ b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp);
+
+ tmp = (2 * crystalfreq + 1000000 * pdiv) / (2000000 * pdiv);
+ tmp = ((tmp & 0xFF) - 1) & 0xFFFF;
+ b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp);
+
+ ref = (1000 * pdiv + 2 * crystalfreq) / (2000 * pdiv);
+ ref &= 0xFFFF;
+ for (i = 0; i < ARRAY_SIZE(freqdata_tab); i++) {
+ if (ref < freqdata_tab[i].freq) {
+ fd = &freqdata_tab[i];
+ break;
+ }
+ }
+ if (!fd)
+ fd = &freqdata_tab[ARRAY_SIZE(freqdata_tab) - 1];
+ b43dbg(dev->wl, "b2062: Using crystal tab entry %u kHz.\n",
+ fd->freq); /* FIXME: Keep this printk until the code is fully debugged. */
+
+ b43_radio_write(dev, B2062_S_RFPLL_CTL8,
+ ((u16)(fd->data[1]) << 4) | fd->data[0]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL9,
+ ((u16)(fd->data[3]) << 4) | fd->data[2]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL10, fd->data[4]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL11, fd->data[5]);
+}
+
+/* Initialize the 2063 radio. */
+static void lpphy_2063_init(struct b43_wldev *dev)
{
//TODO
+}
+
+static void lpphy_sync_stx(struct b43_wldev *dev)
+{
+ //TODO
+}
+
+static void lpphy_radio_init(struct b43_wldev *dev)
+{
+ /* The radio is attached through the 4wire bus. */
+ b43_phy_set(dev, B43_LPPHY_FOURWIRE_CTL, 0x2);
+ udelay(1);
+ b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD);
+ udelay(1);
+
+ if (dev->phy.rev < 2) {
+ lpphy_2062_init(dev);
+ } else {
+ lpphy_2063_init(dev);
+ lpphy_sync_stx(dev);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
+ //TODO Do something on the backplane
+ }
+}
+
+/* Read the TX power control mode from hardware. */
+static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u16 ctl;
+
+ ctl = b43_phy_read(dev, B43_LPPHY_TX_PWR_CTL_CMD);
+ switch (ctl & B43_LPPHY_TX_PWR_CTL_CMD_MODE) {
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_OFF;
+ break;
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_SW;
+ break;
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_HW;
+ break;
+ default:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_UNKNOWN;
+ B43_WARN_ON(1);
+ break;
+ }
+}
+
+/* Set the TX power control mode in hardware. */
+static void lpphy_write_tx_pctl_mode_to_hardware(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u16 ctl;
+
+ switch (lpphy->txpctl_mode) {
+ case B43_LPPHY_TXPCTL_OFF:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF;
+ break;
+ case B43_LPPHY_TXPCTL_HW:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW;
+ break;
+ case B43_LPPHY_TXPCTL_SW:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW;
+ break;
+ default:
+ ctl = 0;
+ B43_WARN_ON(1);
+ }
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+ (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, ctl);
+}
+
+static void lpphy_set_tx_power_control(struct b43_wldev *dev,
+ enum b43_lpphy_txpctl_mode mode)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ enum b43_lpphy_txpctl_mode oldmode;
+
+ oldmode = lpphy->txpctl_mode;
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ if (lpphy->txpctl_mode == mode)
+ return;
+ lpphy->txpctl_mode = mode;
+
+ if (oldmode == B43_LPPHY_TXPCTL_HW) {
+ //TODO Update TX Power NPT
+ //TODO Clear all TX Power offsets
+ } else {
+ if (mode == B43_LPPHY_TXPCTL_HW) {
+ //TODO Recalculate target TX power
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+ 0xFF80, lpphy->tssi_idx);
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM,
+ 0x8FFF, ((u16)lpphy->tssi_npt << 16));
+ //TODO Set "TSSI Transmit Count" variable to total transmitted frame count
+ //TODO Disable TX gain override
+ lpphy->tx_pwr_idx_over = -1;
+ }
+ }
+ if (dev->phy.rev >= 2) {
+ if (mode == B43_LPPHY_TXPCTL_HW)
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0x2);
+ else
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0);
+ }
+ lpphy_write_tx_pctl_mode_to_hardware(dev);
+}
+
+static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+
+ lpphy->tx_pwr_idx_over = index;
+ if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF)
+ lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW);
+
+ //TODO
+}
+
+static void lpphy_btcoex_override(struct b43_wldev *dev)
+{
+ b43_write16(dev, B43_MMIO_BTCOEX_CTL, 0x3);
+ b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF);
+}
+
+static void lpphy_pr41573_workaround(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u32 *saved_tab;
+ const unsigned int saved_tab_size = 256;
+ enum b43_lpphy_txpctl_mode txpctl_mode;
+ s8 tx_pwr_idx_over;
+ u16 tssi_npt, tssi_idx;
+
+ saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL);
+ if (!saved_tab) {
+ b43err(dev->wl, "PR41573 failed. Out of memory!\n");
+ return;
+ }
+
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ txpctl_mode = lpphy->txpctl_mode;
+ tx_pwr_idx_over = lpphy->tx_pwr_idx_over;
+ tssi_npt = lpphy->tssi_npt;
+ tssi_idx = lpphy->tssi_idx;
+
+ if (dev->phy.rev < 2) {
+ b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140),
+ saved_tab_size, saved_tab);
+ } else {
+ b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140),
+ saved_tab_size, saved_tab);
+ }
+ //TODO
+
+ kfree(saved_tab);
+}
+
+static void lpphy_calibration(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ enum b43_lpphy_txpctl_mode saved_pctl_mode;
+
+ b43_mac_suspend(dev);
+
+ lpphy_btcoex_override(dev);
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ saved_pctl_mode = lpphy->txpctl_mode;
+ lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
+ //TODO Perform transmit power table I/Q LO calibration
+ if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF))
+ lpphy_pr41573_workaround(dev);
+ //TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration
+ lpphy_set_tx_power_control(dev, saved_pctl_mode);
+ //TODO Perform I/Q calibration with a single control value set
+
+ b43_mac_enable(dev);
+}
+
+/* Initialize TX power control */
+static void lpphy_tx_pctl_init(struct b43_wldev *dev)
+{
+ if (0/*FIXME HWPCTL capable */) {
+ //TODO
+ } else { /* This device is only software TX power control capable. */
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ //TODO
+ } else {
+ //TODO
+ }
+ //TODO set BB multiplier to 0x0096
+ }
+}
+
+static int b43_lpphy_op_init(struct b43_wldev *dev)
+{
+ /* TODO: band SPROM */
+ lpphy_baseband_init(dev);
+ lpphy_radio_init(dev);
+ //TODO calibrate RC
+ //TODO set channel
+ lpphy_tx_pctl_init(dev);
+ //TODO full calib
return 0;
}
@@ -115,7 +502,9 @@ static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
{
- return 1; /* Default to channel 1 */
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ return 1;
+ return 36;
}
static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index b0b5357abf9..18370b4ac38 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -4,8 +4,285 @@
/* Definitions for the LP-PHY */
+/* The CCK PHY register range. */
+#define B43_LPPHY_B_VERSION B43_PHY_CCK(0x00) /* B PHY version */
+#define B43_LPPHY_B_BBCONFIG B43_PHY_CCK(0x01) /* B PHY BBConfig */
+#define B43_LPPHY_B_RX_STAT0 B43_PHY_CCK(0x04) /* B PHY RX Status0 */
+#define B43_LPPHY_B_RX_STAT1 B43_PHY_CCK(0x05) /* B PHY RX Status1 */
+#define B43_LPPHY_B_CRS_THRESH B43_PHY_CCK(0x06) /* B PHY CRS Thresh */
+#define B43_LPPHY_B_TXERROR B43_PHY_CCK(0x07) /* B PHY TxError */
+#define B43_LPPHY_B_CHANNEL B43_PHY_CCK(0x08) /* B PHY Channel */
+#define B43_LPPHY_B_WORKAROUND B43_PHY_CCK(0x09) /* B PHY workaround */
+#define B43_LPPHY_B_TEST B43_PHY_CCK(0x0A) /* B PHY Test */
+#define B43_LPPHY_B_FOURWIRE_ADDR B43_PHY_CCK(0x0B) /* B PHY Fourwire Address */
+#define B43_LPPHY_B_FOURWIRE_DATA_HI B43_PHY_CCK(0x0C) /* B PHY Fourwire Data Hi */
+#define B43_LPPHY_B_FOURWIRE_DATA_LO B43_PHY_CCK(0x0D) /* B PHY Fourwire Data Lo */
+#define B43_LPPHY_B_BIST_STAT B43_PHY_CCK(0x0E) /* B PHY Bist Status */
+#define B43_LPPHY_PA_RAMP_TX_TO B43_PHY_CCK(0x10) /* PA Ramp TX Timeout */
+#define B43_LPPHY_RF_SYNTH_DC_TIMER B43_PHY_CCK(0x11) /* RF Synth DC Timer */
+#define B43_LPPHY_PA_RAMP_TX_TIME_IN B43_PHY_CCK(0x12) /* PA ramp TX Time in */
+#define B43_LPPHY_RX_FILTER_TIME_IN B43_PHY_CCK(0x13) /* RX Filter Time in */
+#define B43_LPPHY_PLL_COEFF_S B43_PHY_CCK(0x18) /* PLL Coefficient(s) */
+#define B43_LPPHY_PLL_OUT B43_PHY_CCK(0x19) /* PLL Out */
+#define B43_LPPHY_RSSI_THRES B43_PHY_CCK(0x20) /* RSSI Threshold */
+#define B43_LPPHY_IQ_THRES_HH B43_PHY_CCK(0x21) /* IQ Threshold HH */
+#define B43_LPPHY_IQ_THRES_H B43_PHY_CCK(0x22) /* IQ Threshold H */
+#define B43_LPPHY_IQ_THRES_L B43_PHY_CCK(0x23) /* IQ Threshold L */
+#define B43_LPPHY_IQ_THRES_LL B43_PHY_CCK(0x24) /* IQ Threshold LL */
+#define B43_LPPHY_AGC_GAIN B43_PHY_CCK(0x25) /* AGC Gain */
+#define B43_LPPHY_LNA_GAIN_RANGE B43_PHY_CCK(0x26) /* LNA Gain Range */
+#define B43_LPPHY_JSSI B43_PHY_CCK(0x27) /* JSSI */
+#define B43_LPPHY_TSSI_CTL B43_PHY_CCK(0x28) /* TSSI Control */
+#define B43_LPPHY_TSSI B43_PHY_CCK(0x29) /* TSSI */
+#define B43_LPPHY_TR_LOSS B43_PHY_CCK(0x2A) /* TR Loss */
+#define B43_LPPHY_LO_LEAKAGE B43_PHY_CCK(0x2B) /* LO Leakage */
+#define B43_LPPHY_LO_RSSIACC B43_PHY_CCK(0x2C) /* LO RSSIAcc */
+#define B43_LPPHY_LO_IQ_MAG_ACC B43_PHY_CCK(0x2D) /* LO IQ Mag Acc */
+#define B43_LPPHY_TX_DCOFFSET1 B43_PHY_CCK(0x2E) /* TX DCOffset1 */
+#define B43_LPPHY_TX_DCOFFSET2 B43_PHY_CCK(0x2F) /* TX DCOffset2 */
+#define B43_LPPHY_SYNCPEAKCNT B43_PHY_CCK(0x30) /* SyncPeakCnt */
+#define B43_LPPHY_SYNCFREQ B43_PHY_CCK(0x31) /* SyncFreq */
+#define B43_LPPHY_SYNCDIVERSITYCTL B43_PHY_CCK(0x32) /* SyncDiversityControl */
+#define B43_LPPHY_PEAKENERGYL B43_PHY_CCK(0x33) /* PeakEnergyL */
+#define B43_LPPHY_PEAKENERGYH B43_PHY_CCK(0x34) /* PeakEnergyH */
+#define B43_LPPHY_SYNCCTL B43_PHY_CCK(0x35) /* SyncControl */
+#define B43_LPPHY_DSSSSTEP B43_PHY_CCK(0x38) /* DsssStep */
+#define B43_LPPHY_DSSSWARMUP B43_PHY_CCK(0x39) /* DsssWarmup */
+#define B43_LPPHY_DSSSSIGPOW B43_PHY_CCK(0x3D) /* DsssSigPow */
+#define B43_LPPHY_SFDDETECTBLOCKTIME B43_PHY_CCK(0x40) /* SfdDetectBlockTIme */
+#define B43_LPPHY_SFDTO B43_PHY_CCK(0x41) /* SFDTimeOut */
+#define B43_LPPHY_SFDCTL B43_PHY_CCK(0x42) /* SFDControl */
+#define B43_LPPHY_RXDBG B43_PHY_CCK(0x43) /* rxDebug */
+#define B43_LPPHY_RX_DELAYCOMP B43_PHY_CCK(0x44) /* RX DelayComp */
+#define B43_LPPHY_CRSDROPOUTTO B43_PHY_CCK(0x45) /* CRSDropoutTimeout */
+#define B43_LPPHY_PSEUDOSHORTTO B43_PHY_CCK(0x46) /* PseudoShortTimeout */
+#define B43_LPPHY_PR3931 B43_PHY_CCK(0x47) /* PR3931 */
+#define B43_LPPHY_DSSSCOEFF1 B43_PHY_CCK(0x48) /* DSSSCoeff1 */
+#define B43_LPPHY_DSSSCOEFF2 B43_PHY_CCK(0x49) /* DSSSCoeff2 */
+#define B43_LPPHY_CCKCOEFF1 B43_PHY_CCK(0x4A) /* CCKCoeff1 */
+#define B43_LPPHY_CCKCOEFF2 B43_PHY_CCK(0x4B) /* CCKCoeff2 */
+#define B43_LPPHY_TRCORR B43_PHY_CCK(0x4C) /* TRCorr */
+#define B43_LPPHY_ANGLESCALE B43_PHY_CCK(0x4D) /* AngleScale */
+#define B43_LPPHY_OPTIONALMODES2 B43_PHY_CCK(0x4F) /* OptionalModes2 */
+#define B43_LPPHY_CCKLMSSTEPSIZE B43_PHY_CCK(0x50) /* CCKLMSStepSize */
+#define B43_LPPHY_DFEBYPASS B43_PHY_CCK(0x51) /* DFEBypass */
+#define B43_LPPHY_CCKSTARTDELAYLONG B43_PHY_CCK(0x52) /* CCKStartDelayLong */
+#define B43_LPPHY_CCKSTARTDELAYSHORT B43_PHY_CCK(0x53) /* CCKStartDelayShort */
+#define B43_LPPHY_PPROCCHDELAY B43_PHY_CCK(0x54) /* PprocChDelay */
+#define B43_LPPHY_PPROCONOFF B43_PHY_CCK(0x55) /* PProcOnOff */
+#define B43_LPPHY_LNAGAINTWOBIT10 B43_PHY_CCK(0x5B) /* LNAGainTwoBit10 */
+#define B43_LPPHY_LNAGAINTWOBIT32 B43_PHY_CCK(0x5C) /* LNAGainTwoBit32 */
+#define B43_LPPHY_OPTIONALMODES B43_PHY_CCK(0x5D) /* OptionalModes */
+#define B43_LPPHY_B_RX_STAT2 B43_PHY_CCK(0x5E) /* B PHY RX Status2 */
+#define B43_LPPHY_B_RX_STAT3 B43_PHY_CCK(0x5F) /* B PHY RX Status3 */
+#define B43_LPPHY_PWDNDACDELAY B43_PHY_CCK(0x63) /* pwdnDacDelay */
+#define B43_LPPHY_FINEDIGIGAIN_CTL B43_PHY_CCK(0x67) /* FineDigiGain Control */
+#define B43_LPPHY_LG2GAINTBLLNA8 B43_PHY_CCK(0x68) /* Lg2GainTblLNA8 */
+#define B43_LPPHY_LG2GAINTBLLNA28 B43_PHY_CCK(0x69) /* Lg2GainTblLNA28 */
+#define B43_LPPHY_GAINTBLLNATRSW B43_PHY_CCK(0x6A) /* GainTblLNATrSw */
+#define B43_LPPHY_PEAKENERGY B43_PHY_CCK(0x6B) /* PeakEnergy */
+#define B43_LPPHY_LG2INITGAIN B43_PHY_CCK(0x6C) /* lg2InitGain */
+#define B43_LPPHY_BLANKCOUNTLNAPGA B43_PHY_CCK(0x6D) /* BlankCountLnaPga */
+#define B43_LPPHY_LNAGAINTWOBIT54 B43_PHY_CCK(0x6E) /* LNAGainTwoBit54 */
+#define B43_LPPHY_LNAGAINTWOBIT76 B43_PHY_CCK(0x6F) /* LNAGainTwoBit76 */
+#define B43_LPPHY_JSSICTL B43_PHY_CCK(0x70) /* JSSIControl */
+#define B43_LPPHY_LG2GAINTBLLNA44 B43_PHY_CCK(0x71) /* Lg2GainTblLNA44 */
+#define B43_LPPHY_LG2GAINTBLLNA62 B43_PHY_CCK(0x72) /* Lg2GainTblLNA62 */
+/* The OFDM PHY register range. */
+#define B43_LPPHY_VERSION B43_PHY_OFDM(0x00) /* Version */
+#define B43_LPPHY_BBCONFIG B43_PHY_OFDM(0x01) /* BBConfig */
+#define B43_LPPHY_RX_STAT0 B43_PHY_OFDM(0x04) /* RX Status0 */
+#define B43_LPPHY_RX_STAT1 B43_PHY_OFDM(0x05) /* RX Status1 */
+#define B43_LPPHY_TX_ERROR B43_PHY_OFDM(0x07) /* TX Error */
+#define B43_LPPHY_CHANNEL B43_PHY_OFDM(0x08) /* Channel */
+#define B43_LPPHY_WORKAROUND B43_PHY_OFDM(0x09) /* workaround */
+#define B43_LPPHY_FOURWIRE_ADDR B43_PHY_OFDM(0x0B) /* Fourwire Address */
+#define B43_LPPHY_FOURWIREDATAHI B43_PHY_OFDM(0x0C) /* FourwireDataHi */
+#define B43_LPPHY_FOURWIREDATALO B43_PHY_OFDM(0x0D) /* FourwireDataLo */
+#define B43_LPPHY_BISTSTAT0 B43_PHY_OFDM(0x0E) /* BistStatus0 */
+#define B43_LPPHY_BISTSTAT1 B43_PHY_OFDM(0x0F) /* BistStatus1 */
+#define B43_LPPHY_CRSGAIN_CTL B43_PHY_OFDM(0x10) /* crsgain Control */
+#define B43_LPPHY_OFDMPWR_THRESH0 B43_PHY_OFDM(0x11) /* ofdmPower Thresh0 */
+#define B43_LPPHY_OFDMPWR_THRESH1 B43_PHY_OFDM(0x12) /* ofdmPower Thresh1 */
+#define B43_LPPHY_OFDMPWR_THRESH2 B43_PHY_OFDM(0x13) /* ofdmPower Thresh2 */
+#define B43_LPPHY_DSSSPWR_THRESH0 B43_PHY_OFDM(0x14) /* dsssPower Thresh0 */
+#define B43_LPPHY_DSSSPWR_THRESH1 B43_PHY_OFDM(0x15) /* dsssPower Thresh1 */
+#define B43_LPPHY_MINPWR_LEVEL B43_PHY_OFDM(0x16) /* MinPower Level */
+#define B43_LPPHY_OFDMSYNCTHRESH0 B43_PHY_OFDM(0x17) /* ofdmSyncThresh0 */
+#define B43_LPPHY_OFDMSYNCTHRESH1 B43_PHY_OFDM(0x18) /* ofdmSyncThresh1 */
+#define B43_LPPHY_FINEFREQEST B43_PHY_OFDM(0x19) /* FineFreqEst */
+#define B43_LPPHY_IDLEAFTERPKTRXTO B43_PHY_OFDM(0x1A) /* IDLEafterPktRXTimeout */
+#define B43_LPPHY_LTRN_CTL B43_PHY_OFDM(0x1B) /* LTRN Control */
+#define B43_LPPHY_DCOFFSETTRANSIENT B43_PHY_OFDM(0x1C) /* DCOffsetTransient */
+#define B43_LPPHY_PREAMBLEINTO B43_PHY_OFDM(0x1D) /* PreambleInTimeout */
+#define B43_LPPHY_PREAMBLECONFIRMTO B43_PHY_OFDM(0x1E) /* PreambleConfirmTimeout */
+#define B43_LPPHY_CLIPTHRESH B43_PHY_OFDM(0x1F) /* ClipThresh */
+#define B43_LPPHY_CLIPCTRTHRESH B43_PHY_OFDM(0x20) /* ClipCtrThresh */
+#define B43_LPPHY_OFDMSYNCTIMER_CTL B43_PHY_OFDM(0x21) /* ofdmSyncTimer Control */
+#define B43_LPPHY_WAITFORPHYSELTO B43_PHY_OFDM(0x22) /* WaitforPHYSelTimeout */
+#define B43_LPPHY_HIGAINDB B43_PHY_OFDM(0x23) /* HiGainDB */
+#define B43_LPPHY_LOWGAINDB B43_PHY_OFDM(0x24) /* LowGainDB */
+#define B43_LPPHY_VERYLOWGAINDB B43_PHY_OFDM(0x25) /* VeryLowGainDB */
+#define B43_LPPHY_GAINMISMATCH B43_PHY_OFDM(0x26) /* gainMismatch */
+#define B43_LPPHY_GAINDIRECTMISMATCH B43_PHY_OFDM(0x27) /* gaindirectMismatch */
+#define B43_LPPHY_PWR_THRESH0 B43_PHY_OFDM(0x28) /* Power Thresh0 */
+#define B43_LPPHY_PWR_THRESH1 B43_PHY_OFDM(0x29) /* Power Thresh1 */
+#define B43_LPPHY_DETECTOR_DELAY_ADJUST B43_PHY_OFDM(0x2A) /* Detector Delay Adjust */
+#define B43_LPPHY_REDUCED_DETECTOR_DELAY B43_PHY_OFDM(0x2B) /* Reduced Detector Delay */
+#define B43_LPPHY_DATA_TO B43_PHY_OFDM(0x2C) /* data Timeout */
+#define B43_LPPHY_CORRELATOR_DIS_DELAY B43_PHY_OFDM(0x2D) /* correlator Dis Delay */
+#define B43_LPPHY_DIVERSITY_GAINBACK B43_PHY_OFDM(0x2E) /* Diversity GainBack */
+#define B43_LPPHY_DSSS_CONFIRM_CNT B43_PHY_OFDM(0x2F) /* DSSS Confirm Cnt */
+#define B43_LPPHY_DC_BLANK_INT B43_PHY_OFDM(0x30) /* DC Blank Interval */
+#define B43_LPPHY_GAIN_MISMATCH_LIMIT B43_PHY_OFDM(0x31) /* gain Mismatch Limit */
+#define B43_LPPHY_CRS_ED_THRESH B43_PHY_OFDM(0x32) /* crs ed thresh */
+#define B43_LPPHY_PHASE_SHIFT_CTL B43_PHY_OFDM(0x33) /* phase shift Control */
+#define B43_LPPHY_INPUT_PWRDB B43_PHY_OFDM(0x34) /* Input PowerDB */
+#define B43_LPPHY_OFDM_SYNC_CTL B43_PHY_OFDM(0x35) /* ofdm sync Control */
+#define B43_LPPHY_AFE_ADC_CTL_0 B43_PHY_OFDM(0x36) /* Afe ADC Control 0 */
+#define B43_LPPHY_AFE_ADC_CTL_1 B43_PHY_OFDM(0x37) /* Afe ADC Control 1 */
+#define B43_LPPHY_AFE_ADC_CTL_2 B43_PHY_OFDM(0x38) /* Afe ADC Control 2 */
+#define B43_LPPHY_AFE_DAC_CTL B43_PHY_OFDM(0x39) /* Afe DAC Control */
+#define B43_LPPHY_AFE_CTL B43_PHY_OFDM(0x3A) /* Afe Control */
+#define B43_LPPHY_AFE_CTL_OVR B43_PHY_OFDM(0x3B) /* Afe Control Ovr */
+#define B43_LPPHY_AFE_CTL_OVRVAL B43_PHY_OFDM(0x3C) /* Afe Control OvrVal */
+#define B43_LPPHY_AFE_RSSI_CTL_0 B43_PHY_OFDM(0x3D) /* Afe RSSI Control 0 */
+#define B43_LPPHY_AFE_RSSI_CTL_1 B43_PHY_OFDM(0x3E) /* Afe RSSI Control 1 */
+#define B43_LPPHY_AFE_RSSI_SEL B43_PHY_OFDM(0x3F) /* Afe RSSI Sel */
+#define B43_LPPHY_RADAR_THRESH B43_PHY_OFDM(0x40) /* Radar Thresh */
+#define B43_LPPHY_RADAR_BLANK_INT B43_PHY_OFDM(0x41) /* Radar blank Interval */
+#define B43_LPPHY_RADAR_MIN_FM_INT B43_PHY_OFDM(0x42) /* Radar min fm Interval */
+#define B43_LPPHY_RADAR_GAIN_TO B43_PHY_OFDM(0x43) /* Radar gain timeout */
+#define B43_LPPHY_RADAR_PULSE_TO B43_PHY_OFDM(0x44) /* Radar pulse timeout */
+#define B43_LPPHY_RADAR_DETECT_FM_CTL B43_PHY_OFDM(0x45) /* Radar detect FM Control */
+#define B43_LPPHY_RADAR_DETECT_EN B43_PHY_OFDM(0x46) /* Radar detect En */
+#define B43_LPPHY_RADAR_RD_DATA_REG B43_PHY_OFDM(0x47) /* Radar Rd Data Reg */
+#define B43_LPPHY_LP_PHY_CTL B43_PHY_OFDM(0x48) /* LP PHY Control */
+#define B43_LPPHY_CLASSIFIER_CTL B43_PHY_OFDM(0x49) /* classifier Control */
+#define B43_LPPHY_RESET_CTL B43_PHY_OFDM(0x4A) /* reset Control */
+#define B43_LPPHY_CLKEN_CTL B43_PHY_OFDM(0x4B) /* ClkEn Control */
+#define B43_LPPHY_RF_OVERRIDE_0 B43_PHY_OFDM(0x4C) /* RF Override 0 */
+#define B43_LPPHY_RF_OVERRIDE_VAL_0 B43_PHY_OFDM(0x4D) /* RF Override Val 0 */
+#define B43_LPPHY_TR_LOOKUP_1 B43_PHY_OFDM(0x4E) /* TR Lookup 1 */
+#define B43_LPPHY_TR_LOOKUP_2 B43_PHY_OFDM(0x4F) /* TR Lookup 2 */
+#define B43_LPPHY_RSSISELLOOKUP1 B43_PHY_OFDM(0x50) /* RssiSelLookup1 */
+#define B43_LPPHY_IQLO_CAL_CMD B43_PHY_OFDM(0x51) /* iqlo Cal Cmd */
+#define B43_LPPHY_IQLO_CAL_CMD_N_NUM B43_PHY_OFDM(0x52) /* iqlo Cal Cmd N num */
+#define B43_LPPHY_IQLO_CAL_CMD_G_CTL B43_PHY_OFDM(0x53) /* iqlo Cal Cmd G control */
+#define B43_LPPHY_MACINT_DBG_REGISTER B43_PHY_OFDM(0x54) /* macint Debug Register */
+#define B43_LPPHY_TABLE_ADDR B43_PHY_OFDM(0x55) /* Table Address */
+#define B43_LPPHY_TABLEDATALO B43_PHY_OFDM(0x56) /* TabledataLo */
+#define B43_LPPHY_TABLEDATAHI B43_PHY_OFDM(0x57) /* TabledataHi */
+#define B43_LPPHY_PHY_CRS_ENABLE_ADDR B43_PHY_OFDM(0x58) /* phy CRS Enable Address */
+#define B43_LPPHY_IDLETIME_CTL B43_PHY_OFDM(0x59) /* Idletime Control */
+#define B43_LPPHY_IDLETIME_CRS_ON_LO B43_PHY_OFDM(0x5A) /* Idletime CRS On Lo */
+#define B43_LPPHY_IDLETIME_CRS_ON_HI B43_PHY_OFDM(0x5B) /* Idletime CRS On Hi */
+#define B43_LPPHY_IDLETIME_MEAS_TIME_LO B43_PHY_OFDM(0x5C) /* Idletime Meas Time Lo */
+#define B43_LPPHY_IDLETIME_MEAS_TIME_HI B43_PHY_OFDM(0x5D) /* Idletime Meas Time Hi */
+#define B43_LPPHY_RESET_LEN_OFDM_TX_ADDR B43_PHY_OFDM(0x5E) /* Reset len Ofdm TX Address */
+#define B43_LPPHY_RESET_LEN_OFDM_RX_ADDR B43_PHY_OFDM(0x5F) /* Reset len Ofdm RX Address */
+#define B43_LPPHY_REG_CRS_ENABLE B43_PHY_OFDM(0x60) /* reg crs enable */
+#define B43_LPPHY_PLCP_TMT_STR0_CTR_MIN B43_PHY_OFDM(0x61) /* PLCP Tmt Str0 Ctr Min */
+#define B43_LPPHY_PKT_FSM_RESET_LEN_VAL B43_PHY_OFDM(0x62) /* Pkt fsm Reset Len Value */
+#define B43_LPPHY_READSYM2RESET_CTL B43_PHY_OFDM(0x63) /* readsym2reset Control */
+#define B43_LPPHY_DC_FILTER_DELAY1 B43_PHY_OFDM(0x64) /* Dc filter delay1 */
+#define B43_LPPHY_PACKET_RX_ACTIVE_TO B43_PHY_OFDM(0x65) /* packet rx Active timeout */
+#define B43_LPPHY_ED_TOVAL B43_PHY_OFDM(0x66) /* ed timeoutValue */
+#define B43_LPPHY_HOLD_CRS_ON_VAL B43_PHY_OFDM(0x67) /* hold CRS On Value */
+#define B43_LPPHY_OFDM_TX_PHY_CRS_DELAY_VAL B43_PHY_OFDM(0x69) /* ofdm tx phy CRS Delay Value */
+#define B43_LPPHY_CCK_TX_PHY_CRS_DELAY_VAL B43_PHY_OFDM(0x6A) /* cck tx phy CRS Delay Value */
+#define B43_LPPHY_ED_ON_CONFIRM_TIMER_VAL B43_PHY_OFDM(0x6B) /* Ed on confirm Timer Value */
+#define B43_LPPHY_ED_OFFSET_CONFIRM_TIMER_VAL B43_PHY_OFDM(0x6C) /* Ed offset confirm Timer Value */
+#define B43_LPPHY_PHY_CRS_OFFSET_TIMER_VAL B43_PHY_OFDM(0x6D) /* phy CRS offset Timer Value */
+#define B43_LPPHY_ADC_COMPENSATION_CTL B43_PHY_OFDM(0x70) /* ADC Compensation Control */
+#define B43_LPPHY_LOG2_RBPSK_ADDR B43_PHY_OFDM(0x71) /* log2 RBPSK Address */
+#define B43_LPPHY_LOG2_RQPSK_ADDR B43_PHY_OFDM(0x72) /* log2 RQPSK Address */
+#define B43_LPPHY_LOG2_R16QAM_ADDR B43_PHY_OFDM(0x73) /* log2 R16QAM Address */
+#define B43_LPPHY_LOG2_R64QAM_ADDR B43_PHY_OFDM(0x74) /* log2 R64QAM Address */
+#define B43_LPPHY_OFFSET_BPSK_ADDR B43_PHY_OFDM(0x75) /* offset BPSK Address */
+#define B43_LPPHY_OFFSET_QPSK_ADDR B43_PHY_OFDM(0x76) /* offset QPSK Address */
+#define B43_LPPHY_OFFSET_16QAM_ADDR B43_PHY_OFDM(0x77) /* offset 16QAM Address */
+#define B43_LPPHY_OFFSET_64QAM_ADDR B43_PHY_OFDM(0x78) /* offset 64QAM Address */
+#define B43_LPPHY_ALPHA1 B43_PHY_OFDM(0x79) /* Alpha1 */
+#define B43_LPPHY_ALPHA2 B43_PHY_OFDM(0x7A) /* Alpha2 */
+#define B43_LPPHY_BETA1 B43_PHY_OFDM(0x7B) /* Beta1 */
+#define B43_LPPHY_BETA2 B43_PHY_OFDM(0x7C) /* Beta2 */
+#define B43_LPPHY_LOOP_NUM_ADDR B43_PHY_OFDM(0x7D) /* Loop Num Address */
+#define B43_LPPHY_STR_COLLMAX_SMPL_ADDR B43_PHY_OFDM(0x7E) /* Str Collmax Sample Address */
+#define B43_LPPHY_MAX_SMPL_COARSE_FINE_ADDR B43_PHY_OFDM(0x7F) /* Max Sample Coarse/Fine Address */
+#define B43_LPPHY_MAX_SMPL_COARSE_STR0CTR_ADDR B43_PHY_OFDM(0x80) /* Max Sample Coarse/Str0Ctr Address */
+#define B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR B43_PHY_OFDM(0x81) /* IQ Enable Wait Time Address */
+#define B43_LPPHY_IQ_NUM_SMPLS_ADDR B43_PHY_OFDM(0x82) /* IQ Num Samples Address */
+#define B43_LPPHY_IQ_ACC_HI_ADDR B43_PHY_OFDM(0x83) /* IQ Acc Hi Address */
+#define B43_LPPHY_IQ_ACC_LO_ADDR B43_PHY_OFDM(0x84) /* IQ Acc Lo Address */
+#define B43_LPPHY_IQ_I_PWR_ACC_HI_ADDR B43_PHY_OFDM(0x85) /* IQ I PWR Acc Hi Address */
+#define B43_LPPHY_IQ_I_PWR_ACC_LO_ADDR B43_PHY_OFDM(0x86) /* IQ I PWR Acc Lo Address */
+#define B43_LPPHY_IQ_Q_PWR_ACC_HI_ADDR B43_PHY_OFDM(0x87) /* IQ Q PWR Acc Hi Address */
+#define B43_LPPHY_IQ_Q_PWR_ACC_LO_ADDR B43_PHY_OFDM(0x88) /* IQ Q PWR Acc Lo Address */
+#define B43_LPPHY_MAXNUMSTEPS B43_PHY_OFDM(0x89) /* MaxNumsteps */
+#define B43_LPPHY_ROTORPHASE_ADDR B43_PHY_OFDM(0x8A) /* RotorPhase Address */
+#define B43_LPPHY_ADVANCEDRETARDROTOR_ADDR B43_PHY_OFDM(0x8B) /* AdvancedRetardRotor Address */
+#define B43_LPPHY_RSSIADCDELAY_CTL_ADDR B43_PHY_OFDM(0x8D) /* rssiAdcdelay Control Address */
+#define B43_LPPHY_TSSISTAT_ADDR B43_PHY_OFDM(0x8E) /* tssiStatus Address */
+#define B43_LPPHY_TEMPSENSESTAT_ADDR B43_PHY_OFDM(0x8F) /* tempsenseStatus Address */
+#define B43_LPPHY_TEMPSENSE_CTL_ADDR B43_PHY_OFDM(0x90) /* tempsense Control Address */
+#define B43_LPPHY_WRSSISTAT_ADDR B43_PHY_OFDM(0x91) /* wrssistatus Address */
+#define B43_LPPHY_MUFACTORADDR B43_PHY_OFDM(0x92) /* mufactoraddr */
+#define B43_LPPHY_SCRAMSTATE_ADDR B43_PHY_OFDM(0x93) /* scramstate Address */
+#define B43_LPPHY_TXHOLDOFFADDR B43_PHY_OFDM(0x94) /* txholdoffaddr */
+#define B43_LPPHY_PKTGAINVAL_ADDR B43_PHY_OFDM(0x95) /* pktgainval Address */
+#define B43_LPPHY_COARSEESTIM_ADDR B43_PHY_OFDM(0x96) /* Coarseestim Address */
+#define B43_LPPHY_STATE_TRANSITION_ADDR B43_PHY_OFDM(0x97) /* state Transition Address */
+#define B43_LPPHY_TRN_OFFSET_ADDR B43_PHY_OFDM(0x98) /* TRN offset Address */
+#define B43_LPPHY_NUM_ROTOR_ADDR B43_PHY_OFDM(0x99) /* Num Rotor Address */
+#define B43_LPPHY_VITERBI_OFFSET_ADDR B43_PHY_OFDM(0x9A) /* Viterbi Offset Address */
+#define B43_LPPHY_SMPL_COLLECT_WAIT_ADDR B43_PHY_OFDM(0x9B) /* Sample collect wait Address */
+#define B43_LPPHY_A_PHY_CTL_ADDR B43_PHY_OFDM(0x9C) /* A PHY Control Address */
+#define B43_LPPHY_NUM_PASS_THROUGH_ADDR B43_PHY_OFDM(0x9D) /* Num Pass Through Address */
+#define B43_LPPHY_RX_COMP_COEFF_S B43_PHY_OFDM(0x9E) /* RX Comp coefficient(s) */
+#define B43_LPPHY_CPAROTATEVAL B43_PHY_OFDM(0x9F) /* cpaRotateValue */
+#define B43_LPPHY_SMPL_PLAY_COUNT B43_PHY_OFDM(0xA0) /* Sample play count */
+#define B43_LPPHY_SMPL_PLAY_BUFFER_CTL B43_PHY_OFDM(0xA1) /* Sample play Buffer Control */
+#define B43_LPPHY_FOURWIRE_CTL B43_PHY_OFDM(0xA2) /* fourwire Control */
+#define B43_LPPHY_CPA_TAILCOUNT_VAL B43_PHY_OFDM(0xA3) /* CPA TailCount Value */
+#define B43_LPPHY_TX_PWR_CTL_CMD B43_PHY_OFDM(0xA4) /* TX Power Control Cmd */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE 0xE000 /* TX power control mode mask */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF 0x0000 /* TX power control is OFF */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW 0x8000 /* TX power control is SOFTWARE */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW 0xE000 /* TX power control is HARDWARE */
+#define B43_LPPHY_TX_PWR_CTL_NNUM B43_PHY_OFDM(0xA5) /* TX Power Control Nnum */
+#define B43_LPPHY_TX_PWR_CTL_IDLETSSI B43_PHY_OFDM(0xA6) /* TX Power Control IdleTssi */
+#define B43_LPPHY_TX_PWR_CTL_TARGETPWR B43_PHY_OFDM(0xA7) /* TX Power Control TargetPower */
+#define B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT B43_PHY_OFDM(0xA8) /* TX Power Control DeltaPower Limit */
+#define B43_LPPHY_TX_PWR_CTL_BASEINDEX B43_PHY_OFDM(0xA9) /* TX Power Control BaseIndex */
+#define B43_LPPHY_TX_PWR_CTL_PWR_INDEX B43_PHY_OFDM(0xAA) /* TX Power Control Power Index */
+#define B43_LPPHY_TX_PWR_CTL_STAT B43_PHY_OFDM(0xAB) /* TX Power Control Status */
+#define B43_LPPHY_LP_RF_SIGNAL_LUT B43_PHY_OFDM(0xAC) /* LP RF signal LUT */
+#define B43_LPPHY_RX_RADIO_CTL_FILTER_STATE B43_PHY_OFDM(0xAD) /* RX Radio Control Filter State */
+#define B43_LPPHY_RX_RADIO_CTL B43_PHY_OFDM(0xAE) /* RX Radio Control */
+#define B43_LPPHY_NRSSI_STAT_ADDR B43_PHY_OFDM(0xAF) /* NRSSI status Address */
+#define B43_LPPHY_RF_OVERRIDE_2 B43_PHY_OFDM(0xB0) /* RF override 2 */
+#define B43_LPPHY_RF_OVERRIDE_2_VAL B43_PHY_OFDM(0xB1) /* RF override 2 val */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL0 B43_PHY_OFDM(0xB2) /* PS Control override val0 */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL1 B43_PHY_OFDM(0xB3) /* PS Control override val1 */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL2 B43_PHY_OFDM(0xB4) /* PS Control override val2 */
+#define B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL B43_PHY_OFDM(0xB5) /* TX gain Control override val */
+#define B43_LPPHY_RX_GAIN_CTL_OVERRIDE_VAL B43_PHY_OFDM(0xB6) /* RX gain Control override val */
+#define B43_LPPHY_AFE_DDFS B43_PHY_OFDM(0xB7) /* AFE DDFS */
+#define B43_LPPHY_AFE_DDFS_POINTER_INIT B43_PHY_OFDM(0xB8) /* AFE DDFS pointer init */
+#define B43_LPPHY_AFE_DDFS_INCR_INIT B43_PHY_OFDM(0xB9) /* AFE DDFS incr init */
+#define B43_LPPHY_MRCNOISEREDUCTION B43_PHY_OFDM(0xBA) /* mrcNoiseReduction */
+#define B43_LPPHY_TRLOOKUP3 B43_PHY_OFDM(0xBB) /* TRLookup3 */
+#define B43_LPPHY_TRLOOKUP4 B43_PHY_OFDM(0xBC) /* TRLookup4 */
+#define B43_LPPHY_RADAR_FIFO_STAT B43_PHY_OFDM(0xBD) /* Radar FIFO Status */
+#define B43_LPPHY_GPIO_OUTEN B43_PHY_OFDM(0xBE) /* GPIO Out enable */
+#define B43_LPPHY_GPIO_SELECT B43_PHY_OFDM(0xBF) /* GPIO Select */
+#define B43_LPPHY_GPIO_OUT B43_PHY_OFDM(0xC0) /* GPIO Out */
+
+
+/* Radio register access decorators. */
#define B43_LP_RADIO(radio_reg) (radio_reg)
#define B43_LP_NORTH(radio_reg) B43_LP_RADIO(radio_reg)
#define B43_LP_SOUTH(radio_reg) B43_LP_RADIO((radio_reg) | 0x4000)
@@ -529,8 +806,58 @@
+enum b43_lpphy_txpctl_mode {
+ B43_LPPHY_TXPCTL_UNKNOWN = 0,
+ B43_LPPHY_TXPCTL_OFF, /* TX power control is OFF */
+ B43_LPPHY_TXPCTL_SW, /* TX power control is set to Software */
+ B43_LPPHY_TXPCTL_HW, /* TX power control is set to Hardware */
+};
+
struct b43_phy_lp {
- //TODO
+ /* Current TX power control mode. */
+ enum b43_lpphy_txpctl_mode txpctl_mode;
+
+ /* Transmit isolation medium band */
+ u8 tx_isolation_med_band; /* FIXME initial value? */
+ /* Transmit isolation low band */
+ u8 tx_isolation_low_band; /* FIXME initial value? */
+ /* Transmit isolation high band */
+ u8 tx_isolation_hi_band; /* FIXME initial value? */
+
+ /* Receive power offset */
+ u8 rx_pwr_offset; /* FIXME initial value? */
+
+ /* TSSI transmit count */
+ u16 tssi_tx_count;
+ /* TSSI index */
+ u16 tssi_idx; /* FIXME initial value? */
+ /* TSSI npt */
+ u16 tssi_npt; /* FIXME initial value? */
+
+ /* Target TX frequency */
+ u16 tgt_tx_freq; /* FIXME initial value? */
+
+ /* Transmit power index override */
+ s8 tx_pwr_idx_over; /* FIXME initial value? */
+
+ /* RSSI vf */
+ u8 rssi_vf; /* FIXME initial value? */
+ /* RSSI vc */
+ u8 rssi_vc; /* FIXME initial value? */
+ /* RSSI gs */
+ u8 rssi_gs; /* FIXME initial value? */
+
+ /* RC cap */
+ u8 rc_cap; /* FIXME initial value? */
+ /* BX arch */
+ u8 bx_arch; /* FIXME initial value? */
+
+ /* Full calibration channel */
+ u8 full_calib_chan; /* FIXME initial value? */
+
+ /* Transmit iqlocal best coeffs */
+ bool tx_iqloc_best_coeffs_valid;
+ u8 tx_iqloc_best_coeffs[11];
};
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 1036bef8c4c..8cd9776752e 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -55,8 +55,8 @@ static u16 generate_cookie(struct b43_pio_txqueue *q,
}
static
-struct b43_pio_txqueue * parse_cookie(struct b43_wldev *dev,
- u16 cookie,
+struct b43_pio_txqueue *parse_cookie(struct b43_wldev *dev,
+ u16 cookie,
struct b43_pio_txpacket **pack)
{
struct b43_pio *pio = &dev->pio;
@@ -134,8 +134,8 @@ static u16 pio_rxqueue_offset(struct b43_wldev *dev)
return 8;
}
-static struct b43_pio_txqueue * b43_setup_pioqueue_tx(struct b43_wldev *dev,
- unsigned int index)
+static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
+ unsigned int index)
{
struct b43_pio_txqueue *q;
struct b43_pio_txpacket *p;
@@ -171,8 +171,8 @@ static struct b43_pio_txqueue * b43_setup_pioqueue_tx(struct b43_wldev *dev,
return q;
}
-static struct b43_pio_rxqueue * b43_setup_pioqueue_rx(struct b43_wldev *dev,
- unsigned int index)
+static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
+ unsigned int index)
{
struct b43_pio_rxqueue *q;
@@ -308,8 +308,8 @@ err_destroy_bk:
}
/* Static mapping of mac80211's queues (priorities) to b43 PIO queues. */
-static struct b43_pio_txqueue * select_queue_by_priority(struct b43_wldev *dev,
- u8 queue_prio)
+static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev,
+ u8 queue_prio)
{
struct b43_pio_txqueue *q;
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 713753781f4..afad4235869 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -113,7 +113,7 @@ out_unlock:
return err;
}
-char * b43_rfkill_led_name(struct b43_wldev *dev)
+char *b43_rfkill_led_name(struct b43_wldev *dev)
{
struct b43_rfkill *rfk = &(dev->wl->rfkill);
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
new file mode 100644
index 00000000000..4ea734dce21
--- /dev/null
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -0,0 +1,394 @@
+/*
+
+ Broadcom B43 wireless driver
+ IEEE 802.11g LP-PHY and radio device data tables
+
+ Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "tables_lpphy.h"
+#include "phy_common.h"
+#include "phy_lp.h"
+
+
+/* Entry of the 2062 radio init table */
+struct b2062_init_tab_entry {
+ u16 offset;
+ u16 value_a;
+ u16 value_g;
+ u8 flags;
+};
+#define B2062_FLAG_A 0x01 /* Flag: Init in A mode */
+#define B2062_FLAG_G 0x02 /* Flag: Init in G mode */
+
+static const struct b2062_init_tab_entry b2062_init_tab[] = {
+ /* { .offset = B2062_N_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = 0x0001, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PDN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_PDN_CTL1, .value_a = 0x0000, .value_g = 0x00CA, .flags = B2062_FLAG_G, },
+ /* { .offset = B2062_N_PDN_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
+ { .offset = B2062_N_PDN_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_PDN_CTL4, .value_a = 0x0015, .value_g = 0x002A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_GEN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ { .offset = B2062_N_LGENC, .value_a = 0x00DB, .value_g = 0x00FF, .flags = B2062_FLAG_A, },
+ /* { .offset = B2062_N_LGENA_LPF, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_BIAS0, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
+ /* { .offset = B2062_N_LGNEA_BIAS1, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL0, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_TUNE0, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_LGENA_TUNE1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_TUNE2, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_LGENA_TUNE3, .value_a = 0x0077, .value_g = 0x00B5, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_LGENA_CTL3, .value_a = 0x0000, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_LGENA_CTL4, .value_a = 0x001F, .value_g = 0x001F, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL5, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL6, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_CTL7, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXA_CTL0, .value_a = 0x0009, .value_g = 0x0009, .flags = 0, }, */
+ { .offset = B2062_N_RXA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXA_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL3, .value_a = 0x0027, .value_g = 0x0027, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL4, .value_a = 0x0028, .value_g = 0x0028, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL5, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL7, .value_a = 0x0008, .value_g = 0x0008, .flags = 0, }, */
+ { .offset = B2062_N_RXBB_CTL0, .value_a = 0x0082, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXBB_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_GAIN0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_RXBB_GAIN1, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_RXBB_GAIN2, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXBB_GAIN3, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI0, .value_a = 0x0043, .value_g = 0x0043, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI1, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS1, .value_a = 0x002A, .value_g = 0x002A, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS2, .value_a = 0x00AA, .value_g = 0x00AA, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS3, .value_a = 0x0021, .value_g = 0x0021, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS4, .value_a = 0x00AA, .value_g = 0x00AA, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS5, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI2, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI3, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI4, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL0, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL2, .value_a = 0x0084, .value_g = 0x0084, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_TX_CTL4, .value_a = 0x0003, .value_g = 0x0003, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_TX_CTL5, .value_a = 0x0002, .value_g = 0x0002, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_TX_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL7, .value_a = 0x0058, .value_g = 0x0058, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL8, .value_a = 0x0082, .value_g = 0x0082, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL_A, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_GC2G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_GC5G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
+ { .offset = B2062_N_TX_TUNE, .value_a = 0x0088, .value_g = 0x001B, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_TX_PAD, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PGA, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PADAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PGAAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL0, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL1, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL2, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_TS, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL1, .value_a = 0x0015, .value_g = 0x0015, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL2, .value_a = 0x000F, .value_g = 0x000F, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TEST_BUF0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RADIO_ID_CODE, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_PDS_CTL0, .value_a = 0x00FF, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_PDS_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_PDS_CTL2, .value_a = 0x008E, .value_g = 0x008E, .flags = 0, }, */
+ /* { .offset = B2062_S_PDS_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL2, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL0, .value_a = 0x00F8, .value_g = 0x00D8, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_LGENG_CTL1, .value_a = 0x003C, .value_g = 0x0024, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL3, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL4, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL5, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL6, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL8, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL9, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL10, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL1, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL2, .value_a = 0x00AF, .value_g = 0x00AF, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL3, .value_a = 0x0012, .value_g = 0x0012, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL4, .value_a = 0x000B, .value_g = 0x000B, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL5, .value_a = 0x005F, .value_g = 0x005F, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL7, .value_a = 0x0040, .value_g = 0x0040, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL8, .value_a = 0x0052, .value_g = 0x0052, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL9, .value_a = 0x0026, .value_g = 0x0026, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL10, .value_a = 0x0003, .value_g = 0x0003, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL11, .value_a = 0x0036, .value_g = 0x0036, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL12, .value_a = 0x0057, .value_g = 0x0057, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL13, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL14, .value_a = 0x0075, .value_g = 0x0075, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL15, .value_a = 0x00B4, .value_g = 0x00B4, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL0, .value_a = 0x0098, .value_g = 0x0098, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL1, .value_a = 0x0010, .value_g = 0x0010, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL5, .value_a = 0x0043, .value_g = 0x0043, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL6, .value_a = 0x0047, .value_g = 0x0047, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL7, .value_a = 0x000C, .value_g = 0x000C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL8, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL9, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL10, .value_a = 0x000E, .value_g = 0x000E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL11, .value_a = 0x0008, .value_g = 0x0008, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL12, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL13, .value_a = 0x000A, .value_g = 0x000A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL14, .value_a = 0x0006, .value_g = 0x0006, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL17, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL18, .value_a = 0x003E, .value_g = 0x003E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL19, .value_a = 0x0013, .value_g = 0x0013, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL20, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL21, .value_a = 0x0062, .value_g = 0x0062, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL22, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL23, .value_a = 0x0016, .value_g = 0x0016, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL24, .value_a = 0x005C, .value_g = 0x005C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL25, .value_a = 0x0095, .value_g = 0x0095, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL26, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL27, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL28, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL29, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL30, .value_a = 0x00A0, .value_g = 0x00A0, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL31, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL32, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL33, .value_a = 0x00CC, .value_g = 0x00CC, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL34, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RXG_CNT0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT6, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT7, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+ { .offset = B2062_S_RXG_CNT8, .value_a = 0x000F, .value_g = 0x000F, .flags = B2062_FLAG_A, },
+ /* { .offset = B2062_S_RXG_CNT9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT10, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT11, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT12, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT13, .value_a = 0x0044, .value_g = 0x0044, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT14, .value_a = 0x00A0, .value_g = 0x00A0, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT15, .value_a = 0x0004, .value_g = 0x0004, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT17, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+};
+
+void b2062_upload_init_table(struct b43_wldev *dev)
+{
+ const struct b2062_init_tab_entry *e;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(b2062_init_tab); i++) {
+ e = &b2062_init_tab[i];
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ if (!(e->flags & B2062_FLAG_G))
+ continue;
+ b43_radio_write(dev, e->offset, e->value_g);
+ } else {
+ if (!(e->flags & B2062_FLAG_A))
+ continue;
+ b43_radio_write(dev, e->offset, e->value_a);
+ }
+ }
+}
+
+u32 b43_lptab_read(struct b43_wldev *dev, u32 offset)
+{
+ u32 type, value;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ offset &= ~B43_LPTAB_TYPEMASK;
+ B43_WARN_ON(offset > 0xFFFF);
+
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATALO) & 0xFF;
+ break;
+ case B43_LPTAB_16BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
+ break;
+ case B43_LPTAB_32BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATAHI);
+ value <<= 16;
+ value |= b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
+ break;
+ default:
+ B43_WARN_ON(1);
+ value = 0;
+ }
+
+ return value;
+}
+
+void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, void *_data)
+{
+ u32 type, value;
+ u8 *data = _data;
+ unsigned int i;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ for (i = 0; i < nr_elements; i++) {
+ value = b43_lptab_read(dev, offset);
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ *data = value;
+ data++;
+ break;
+ case B43_LPTAB_16BIT:
+ *((u16 *)data) = value;
+ data += 2;
+ break;
+ case B43_LPTAB_32BIT:
+ *((u32 *)data) = value;
+ data += 4;
+ break;
+ default:
+ B43_WARN_ON(1);
+ }
+ offset++;
+ }
+}
+
+void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value)
+{
+ u32 type;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ offset &= ~B43_LPTAB_TYPEMASK;
+ B43_WARN_ON(offset > 0xFFFF);
+
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ B43_WARN_ON(value & ~0xFF);
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ case B43_LPTAB_16BIT:
+ B43_WARN_ON(value & ~0xFFFF);
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ case B43_LPTAB_32BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATAHI, value >> 16);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ default:
+ B43_WARN_ON(1);
+ }
+}
+
+void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, const void *_data)
+{
+ u32 type, value;
+ const u8 *data = _data;
+ unsigned int i;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ for (i = 0; i < nr_elements; i++) {
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ value = *data;
+ data++;
+ break;
+ case B43_LPTAB_16BIT:
+ value = *((u16 *)data);
+ data += 2;
+ break;
+ case B43_LPTAB_32BIT:
+ value = *((u32 *)data);
+ data += 4;
+ break;
+ default:
+ B43_WARN_ON(1);
+ value = 0;
+ }
+ b43_lptab_write(dev, offset, value);
+ offset++;
+ }
+}
diff --git a/drivers/net/wireless/b43/tables_lpphy.h b/drivers/net/wireless/b43/tables_lpphy.h
new file mode 100644
index 00000000000..0b8d02895a5
--- /dev/null
+++ b/drivers/net/wireless/b43/tables_lpphy.h
@@ -0,0 +1,31 @@
+#ifndef B43_TABLES_LPPHY_H_
+#define B43_TABLES_LPPHY_H_
+
+
+#define B43_LPTAB_TYPEMASK 0xF0000000
+#define B43_LPTAB_8BIT 0x10000000
+#define B43_LPTAB_16BIT 0x20000000
+#define B43_LPTAB_32BIT 0x30000000
+#define B43_LPTAB8(table, offset) (((table) << 10) | (offset) | B43_LPTAB_8BIT)
+#define B43_LPTAB16(table, offset) (((table) << 10) | (offset) | B43_LPTAB_16BIT)
+#define B43_LPTAB32(table, offset) (((table) << 10) | (offset) | B43_LPTAB_32BIT)
+
+/* Table definitions */
+#define B43_LPTAB_TXPWR_R2PLUS B43_LPTAB32(0x07, 0) /* TX power lookup table (rev >= 2) */
+#define B43_LPTAB_TXPWR_R0_1 B43_LPTAB32(0xA0, 0) /* TX power lookup table (rev < 2) */
+
+u32 b43_lptab_read(struct b43_wldev *dev, u32 offset);
+void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value);
+
+/* Bulk table access. Note that these functions return the bulk data in
+ * host endianness! The returned data is _not_ a bytearray, but an array
+ * consisting of nr_elements of the data type. */
+void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, void *data);
+void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, const void *data);
+
+void b2062_upload_init_table(struct b43_wldev *dev);
+
+
+#endif /* B43_TABLES_LPPHY_H_ */
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index 0c0fb15abb9..e1e20f69f6d 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -62,8 +62,7 @@ void b43_wa_initgains(struct b43_wldev *dev)
struct b43_phy *phy = &dev->phy;
b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- b43_phy_read(dev, B43_PHY_LPFGAINCTL) & 0xFF0F);
+ b43_phy_mask(dev, B43_PHY_LPFGAINCTL, 0xFF0F);
if (phy->rev <= 2)
b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF);
b43_radio_write16(dev, 0x0002, 0x1FBF);
@@ -73,11 +72,9 @@ void b43_wa_initgains(struct b43_wldev *dev)
b43_phy_write(dev, 0x001D, 0x0F40);
b43_phy_write(dev, 0x001F, 0x1C00);
if (phy->rev <= 3)
- b43_phy_write(dev, 0x002A,
- (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x0400);
+ b43_phy_maskset(dev, 0x002A, 0x00FF, 0x0400);
else if (phy->rev == 5) {
- b43_phy_write(dev, 0x002A,
- (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00);
+ b43_phy_maskset(dev, 0x002A, 0x00FF, 0x1A00);
b43_phy_write(dev, 0x00CC, 0x2121);
}
if (phy->rev >= 3)
@@ -86,7 +83,7 @@ void b43_wa_initgains(struct b43_wldev *dev)
static void b43_wa_divider(struct b43_wldev *dev)
{
- b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) & ~0x0100);
+ b43_phy_mask(dev, 0x002B, ~0x0100);
b43_phy_write(dev, 0x008E, 0x58C1);
}
@@ -272,8 +269,7 @@ static void b43_wa_2060txlna_gain(struct b43_wldev *dev)
static void b43_wa_lms(struct b43_wldev *dev)
{
- b43_phy_write(dev, 0x0055,
- (b43_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004);
+ b43_phy_maskset(dev, 0x0055, 0xFFC0, 0x0004);
}
static void b43_wa_mixedsignal(struct b43_wldev *dev)
@@ -318,23 +314,18 @@ static void b43_wa_crs_ed(struct b43_wldev *dev)
} else if (phy->rev == 2) {
b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x1861);
b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0271);
- b43_phy_write(dev, B43_PHY_ANTDWELL,
- b43_phy_read(dev, B43_PHY_ANTDWELL)
- | 0x0800);
+ b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
} else {
b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x0098);
b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0070);
b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080);
- b43_phy_write(dev, B43_PHY_ANTDWELL,
- b43_phy_read(dev, B43_PHY_ANTDWELL)
- | 0x0800);
+ b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
}
}
static void b43_wa_crs_thr(struct b43_wldev *dev)
{
- b43_phy_write(dev, B43_PHY_CRS0,
- (b43_phy_read(dev, B43_PHY_CRS0) & ~0x03C0) | 0xD000);
+ b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000);
}
static void b43_wa_crs_blank(struct b43_wldev *dev)
@@ -391,72 +382,45 @@ static void b43_wa_altagc(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25);
}
- b43_phy_write(dev, B43_PHY_CCKSHIFTBITS_WA,
- (b43_phy_read(dev, B43_PHY_CCKSHIFTBITS_WA) & ~0xFF00) | 0x5700);
- b43_phy_write(dev, B43_PHY_OFDM(0x1A),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x007F) | 0x000F);
- b43_phy_write(dev, B43_PHY_OFDM(0x1A),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x3F80) | 0x2B80);
- b43_phy_write(dev, B43_PHY_ANTWRSETT,
- (b43_phy_read(dev, B43_PHY_ANTWRSETT) & 0xF0FF) | 0x0300);
- b43_radio_write16(dev, 0x7A,
- b43_radio_read16(dev, 0x7A) | 0x0008);
- b43_phy_write(dev, B43_PHY_N1P1GAIN,
- (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x000F) | 0x0008);
- b43_phy_write(dev, B43_PHY_P1P2GAIN,
- (b43_phy_read(dev, B43_PHY_P1P2GAIN) & ~0x0F00) | 0x0600);
- b43_phy_write(dev, B43_PHY_N1N2GAIN,
- (b43_phy_read(dev, B43_PHY_N1N2GAIN) & ~0x0F00) | 0x0700);
- b43_phy_write(dev, B43_PHY_N1P1GAIN,
- (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x0F00) | 0x0100);
+ b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, (u16)~0xFF00, 0x5700);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80);
+ b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300);
+ b43_radio_set(dev, 0x7A, 0x0008);
+ b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x000F, 0x0008);
+ b43_phy_maskset(dev, B43_PHY_P1P2GAIN, ~0x0F00, 0x0600);
+ b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x0F00, 0x0700);
+ b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x0F00, 0x0100);
if (phy->rev == 1) {
- b43_phy_write(dev, B43_PHY_N1N2GAIN,
- (b43_phy_read(dev, B43_PHY_N1N2GAIN)
- & ~0x000F) | 0x0007);
+ b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x000F, 0x0007);
}
- b43_phy_write(dev, B43_PHY_OFDM(0x88),
- (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x00FF) | 0x001C);
- b43_phy_write(dev, B43_PHY_OFDM(0x88),
- (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x3F00) | 0x0200);
- b43_phy_write(dev, B43_PHY_OFDM(0x96),
- (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0x00FF) | 0x001C);
- b43_phy_write(dev, B43_PHY_OFDM(0x89),
- (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x00FF) | 0x0020);
- b43_phy_write(dev, B43_PHY_OFDM(0x89),
- (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x3F00) | 0x0200);
- b43_phy_write(dev, B43_PHY_OFDM(0x82),
- (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & ~0x00FF) | 0x002E);
- b43_phy_write(dev, B43_PHY_OFDM(0x96),
- (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0xFF00) | 0x1A00);
- b43_phy_write(dev, B43_PHY_OFDM(0x81),
- (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0x00FF) | 0x0028);
- b43_phy_write(dev, B43_PHY_OFDM(0x81),
- (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0xFF00) | 0x2C00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x00FF, 0x001C);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x3F00, 0x0200);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x96), ~0x00FF, 0x001C);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x96), (u16)~0xFF00, 0x1A00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x81), (u16)~0xFF00, 0x2C00);
if (phy->rev == 1) {
b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B);
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E) | 0x0002);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002);
} else {
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x001E);
b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0x000F) | 0x0004);
+ b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004);
if (phy->rev >= 6) {
b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0xF000) | 0x3000);
+ b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, (u16)~0xF000, 0x3000);
}
}
- b43_phy_write(dev, B43_PHY_DIVSRCHIDX,
- (b43_phy_read(dev, B43_PHY_DIVSRCHIDX) & 0x8080) | 0x7874);
+ b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874);
b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00);
if (phy->rev == 1) {
- b43_phy_write(dev, B43_PHY_DIVP1P2GAIN,
- (b43_phy_read(dev, B43_PHY_DIVP1P2GAIN) & ~0x0F00) | 0x0600);
+ b43_phy_maskset(dev, B43_PHY_DIVP1P2GAIN, ~0x0F00, 0x0600);
b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E);
- b43_phy_write(dev, B43_PHY_ANTWRSETT,
- (b43_phy_read(dev, B43_PHY_ANTWRSETT) & ~0x00FF) | 0x001E);
+ b43_phy_maskset(dev, B43_PHY_ANTWRSETT, ~0x00FF, 0x001E);
b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7);
@@ -469,10 +433,8 @@ static void b43_wa_altagc(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28);
}
if (phy->rev >= 6) {
- b43_phy_write(dev, B43_PHY_OFDM(0x26),
- b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x0003);
- b43_phy_write(dev, B43_PHY_OFDM(0x26),
- b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x1000);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x0003);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x1000);
}
b43_phy_read(dev, B43_PHY_VERSION_OFDM); /* Dummy read */
}
@@ -538,8 +500,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
(phy->rev >= 7)) {
- b43_phy_write(dev, B43_PHY_EXTG(0x11),
- b43_phy_read(dev, B43_PHY_EXTG(0x11)) & 0xF7FF);
+ b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index eae9b805265..0f53c7e5e01 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -538,8 +538,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
chanstat = le16_to_cpu(rxhdr->channel);
phytype = chanstat & B43_RX_CHAN_PHYTYPE;
- if (macstat & B43_RX_MAC_FCSERR)
+ if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
dev->wl->ieee_stats.dot11FCSErrorCount++;
+ status.flag |= RX_FLAG_FAILED_FCS_CRC;
+ }
+ if (unlikely(phystat0 & (B43_RX_PHYST0_PLCPHCF | B43_RX_PHYST0_PLCPFV)))
+ status.flag |= RX_FLAG_FAILED_PLCP_CRC;
+ if (phystat0 & B43_RX_PHYST0_SHORTPRMBL)
+ status.flag |= RX_FLAG_SHORTPRE;
if (macstat & B43_RX_MAC_DECERR) {
/* Decryption with the given key failed.
* Drop the packet. We also won't be able to decrypt it with
@@ -606,8 +612,12 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
phytype == B43_PHYTYPE_A);
else
status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
- if (unlikely(status.rate_idx == -1))
- goto drop;
+ if (unlikely(status.rate_idx == -1)) {
+ /* PLCP seems to be corrupted.
+ * Drop the frame, if we are not interested in corrupted frames. */
+ if (!(dev->wl->filter_flags & FIF_PLCPFAIL))
+ goto drop;
+ }
status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
/*
@@ -661,7 +671,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
goto drop;
}
- dev->stats.last_rx = jiffies;
ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
return;
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c
index cacb786d971..3ea55b18c70 100644
--- a/drivers/net/wireless/b43legacy/leds.c
+++ b/drivers/net/wireless/b43legacy/leds.c
@@ -146,12 +146,12 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev,
case B43legacy_LED_TRANSFER:
case B43legacy_LED_APTRANSFER:
snprintf(name, sizeof(name),
- "b43legacy-%s:tx", wiphy_name(hw->wiphy));
+ "b43legacy-%s::tx", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_tx, name,
ieee80211_get_tx_led_name(hw),
led_index, activelow);
snprintf(name, sizeof(name),
- "b43legacy-%s:rx", wiphy_name(hw->wiphy));
+ "b43legacy-%s::rx", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_rx, name,
ieee80211_get_rx_led_name(hw),
led_index, activelow);
@@ -161,7 +161,7 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev,
case B43legacy_LED_RADIO_B:
case B43legacy_LED_MODE_BG:
snprintf(name, sizeof(name),
- "b43legacy-%s:radio", wiphy_name(hw->wiphy));
+ "b43legacy-%s::radio", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_radio, name,
b43legacy_rfkill_led_name(dev),
led_index, activelow);
@@ -172,7 +172,7 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev,
case B43legacy_LED_WEIRD:
case B43legacy_LED_ASSOC:
snprintf(name, sizeof(name),
- "b43legacy-%s:assoc", wiphy_name(hw->wiphy));
+ "b43legacy-%s::assoc", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_assoc, name,
ieee80211_get_assoc_led_name(hw),
led_index, activelow);
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index fb996c27a19..879edc78671 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2650,7 +2650,7 @@ out_unlock_mutex:
return err;
}
-static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates)
+static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u32 brates)
{
struct ieee80211_supported_band *sband =
dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 2453deaa3e0..ce8721fbc10 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -31,7 +31,7 @@ void hostap_dump_rx_header(const char *name,
void hostap_dump_tx_header(const char *name,
const struct hfa384x_tx_frame *tx);
extern const struct header_ops hostap_80211_ops;
-int hostap_80211_get_hdrlen(u16 fc);
+int hostap_80211_get_hdrlen(__le16 fc);
struct net_device_stats *hostap_get_stats(struct net_device *dev);
void hostap_setup_dev(struct net_device *dev, local_info_t *local,
int type);
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index 3a9474d9a90..2e9fb0f383f 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -2,7 +2,7 @@
#define HOSTAP_80211_H
#include <linux/types.h>
-#include <net/ieee80211.h>
+#include <linux/skbuff.h>
struct hostap_ieee80211_mgmt {
__le16 frame_control;
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 19b1bf0478b..3816df96a66 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -1,5 +1,6 @@
#include <linux/etherdevice.h>
#include <net/lib80211.h>
+#include <linux/if_arp.h>
#include "hostap_80211.h"
#include "hostap.h"
@@ -17,10 +18,10 @@ static unsigned char bridge_tunnel_header[] =
void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
"jiffies=%ld\n",
@@ -30,9 +31,10 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
if (skb->len < 2)
return;
- fc = le16_to_cpu(hdr->frame_ctl);
+ fc = le16_to_cpu(hdr->frame_control);
printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
- fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+ fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
@@ -42,7 +44,7 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
}
printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
- le16_to_cpu(hdr->seq_ctl));
+ le16_to_cpu(hdr->seq_ctrl));
printk(KERN_DEBUG " A1=%pM", hdr->addr1);
printk(" A2=%pM", hdr->addr2);
@@ -63,7 +65,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
int hdrlen, phdrlen, head_need, tail_need;
u16 fc;
int prism_header, ret;
- struct ieee80211_hdr_4addr *fhdr;
+ struct ieee80211_hdr *fhdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -84,8 +86,8 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
phdrlen = 0;
}
- fhdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(fhdr->frame_ctl);
+ fhdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(fhdr->frame_control);
if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
printk(KERN_DEBUG "%s: dropped management frame with header "
@@ -94,7 +96,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
return 0;
}
- hdrlen = hostap_80211_get_hdrlen(fc);
+ hdrlen = hostap_80211_get_hdrlen(fhdr->frame_control);
/* check if there is enough room for extra data; if not, expand skb
* buffer to be large enough for the changes */
@@ -193,7 +195,7 @@ hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
if (prism_header)
skb_pull(skb, phdrlen);
skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_802_2);
+ skb->protocol = cpu_to_be16(ETH_P_802_2);
memset(skb->cb, 0, sizeof(skb->cb));
netif_rx(skb);
@@ -205,13 +207,11 @@ hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
static void monitor_rx(struct net_device *dev, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct net_device_stats *stats;
int len;
len = prism2_rx_80211(dev, skb, rx_stats, PRISM2_RX_MONITOR);
- stats = hostap_get_stats(dev);
- stats->rx_packets++;
- stats->rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
}
@@ -247,21 +247,21 @@ prism2_frag_cache_find(local_info_t *local, unsigned int seq,
/* Called only as a tasklet (software IRQ) */
static struct sk_buff *
-prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
+prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
{
struct sk_buff *skb = NULL;
u16 sc;
unsigned int frag, seq;
struct prism2_frag_entry *entry;
- sc = le16_to_cpu(hdr->seq_ctl);
- frag = WLAN_GET_SEQ_FRAG(sc);
- seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ frag = sc & IEEE80211_SCTL_FRAG;
+ seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
if (frag == 0) {
/* Reserve enough space to fit maximum frame length */
skb = dev_alloc_skb(local->dev->mtu +
- sizeof(struct ieee80211_hdr_4addr) +
+ sizeof(struct ieee80211_hdr) +
8 /* LLC */ +
2 /* alignment */ +
8 /* WEP */ + ETH_ALEN /* WDS */);
@@ -299,14 +299,14 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
/* Called only as a tasklet (software IRQ) */
static int prism2_frag_cache_invalidate(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr)
+ struct ieee80211_hdr *hdr)
{
u16 sc;
unsigned int seq;
struct prism2_frag_entry *entry;
- sc = le16_to_cpu(hdr->seq_ctl);
- seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
entry = prism2_frag_cache_find(local, seq, -1, hdr->addr2, hdr->addr1);
@@ -472,10 +472,8 @@ hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, u16 type,
u16 stype)
{
- if (local->iw_mode == IW_MODE_MASTER) {
- hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
- skb->data);
- }
+ if (local->iw_mode == IW_MODE_MASTER)
+ hostap_update_sta_ps(local, (struct ieee80211_hdr *) skb->data);
if (local->hostapd && type == IEEE80211_FTYPE_MGMT) {
if (stype == IEEE80211_STYPE_BEACON &&
@@ -552,8 +550,8 @@ static struct net_device *prism2_rx_get_wds(local_info_t *local,
static int
-hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
- u16 fc, struct net_device **wds)
+hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr, u16 fc,
+ struct net_device **wds)
{
/* FIX: is this really supposed to accept WDS frames only in Master
* mode? What about Repeater or Managed with WDS frames? */
@@ -611,14 +609,14 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
{
struct net_device *dev = local->dev;
u16 fc, ethertype;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u8 *pos;
if (skb->len < 24)
return 0;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
/* check that the frame is unicast frame to us */
if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
@@ -651,14 +649,14 @@ static int
hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
struct lib80211_crypt_data *crypt)
{
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ hdr = (struct ieee80211_hdr *) skb->data;
+ hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
if (local->tkip_countermeasures &&
strcmp(crypt->ops->name, "TKIP") == 0) {
@@ -689,14 +687,14 @@ static int
hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
int keyidx, struct lib80211_crypt_data *crypt)
{
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ hdr = (struct ieee80211_hdr *) skb->data;
+ hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
atomic_inc(&crypt->refcnt);
res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
@@ -720,11 +718,10 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
struct net_device *wds = NULL;
- struct net_device_stats *stats;
unsigned int frag;
u8 *payload;
struct sk_buff *skb2 = NULL;
@@ -747,18 +744,17 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
dev = local->ddev;
iface = netdev_priv(dev);
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- stats = hostap_get_stats(dev);
+ hdr = (struct ieee80211_hdr *) skb->data;
if (skb->len < 10)
goto rx_dropped;
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
- sc = le16_to_cpu(hdr->seq_ctl);
- frag = WLAN_GET_SEQ_FRAG(sc);
- hdrlen = hostap_80211_get_hdrlen(fc);
+ fc = le16_to_cpu(hdr->frame_control);
+ type = fc & IEEE80211_FCTL_FTYPE;
+ stype = fc & IEEE80211_FCTL_STYPE;
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ frag = sc & IEEE80211_SCTL_FRAG;
+ hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
/* Put this code here so that we avoid duplicating it in all
* Rx paths. - Jean II */
@@ -866,10 +862,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (hostap_rx_frame_wds(local, hdr, fc, &wds))
goto rx_dropped;
- if (wds) {
+ if (wds)
skb->dev = dev = wds;
- stats = hostap_get_stats(dev);
- }
if (local->iw_mode == IW_MODE_MASTER && !wds &&
(fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
@@ -878,7 +872,6 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
memcmp(hdr->addr2, local->assoc_ap_addr, ETH_ALEN) == 0) {
/* Frame from BSSID of the AP for which we are a client */
skb->dev = dev = local->stadev;
- stats = hostap_get_stats(dev);
from_assoc_ap = 1;
}
@@ -918,7 +911,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
(keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
goto rx_dropped;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
/* skb: hdr + (possibly fragmented) plaintext payload */
@@ -931,7 +924,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
printk(KERN_DEBUG "%s: Rx cannot get skb from "
"fragment cache (morefrag=%d seq=%u frag=%u)\n",
dev->name, (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
- WLAN_GET_SEQ_SEQ(sc) >> 4, frag);
+ (sc & IEEE80211_SCTL_SEQ) >> 4, frag);
goto rx_dropped;
}
@@ -972,7 +965,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
/* this was the last fragment and the frame will be
* delivered, so remove skb from fragment cache */
skb = frag_skb;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
prism2_frag_cache_invalidate(local, hdr);
}
@@ -983,7 +976,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
goto rx_dropped;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
if (local->ieee_802_1x &&
hostap_is_eapol_frame(local, skb)) {
@@ -1069,8 +1062,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
skb_trim(skb, skb->len - ETH_ALEN);
}
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
if (local->iw_mode == IW_MODE_MASTER && !wds &&
local->ap->bridge_packets) {
@@ -1094,7 +1087,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (skb2 != NULL) {
/* send to wireless media */
skb2->dev = dev;
- skb2->protocol = __constant_htons(ETH_P_802_3);
+ skb2->protocol = cpu_to_be16(ETH_P_802_3);
skb_reset_mac_header(skb2);
skb_reset_network_header(skb2);
/* skb2->network_header += ETH_HLEN; */
@@ -1115,7 +1108,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
rx_dropped:
dev_kfree_skb(skb);
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
goto rx_exit;
}
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 078a010f39a..6693423f63f 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -15,10 +15,10 @@ static unsigned char bridge_tunnel_header[] =
void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
{
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
name, skb->len, jiffies);
@@ -26,9 +26,10 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
if (skb->len < 2)
return;
- fc = le16_to_cpu(hdr->frame_ctl);
+ fc = le16_to_cpu(hdr->frame_control);
printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
- fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+ fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
@@ -38,7 +39,7 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
}
printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
- le16_to_cpu(hdr->seq_ctl));
+ le16_to_cpu(hdr->seq_ctrl));
printk(KERN_DEBUG " A1=%pM", hdr->addr1);
printk(" A2=%pM", hdr->addr2);
@@ -57,7 +58,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
int need_headroom, need_tailroom = 0;
- struct ieee80211_hdr_4addr hdr;
+ struct ieee80211_hdr hdr;
u16 fc, ethertype = 0;
enum {
WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
@@ -201,7 +202,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
memcpy(&hdr.addr3, local->bssid, ETH_ALEN);
}
- hdr.frame_ctl = cpu_to_le16(fc);
+ hdr.frame_control = cpu_to_le16(fc);
skb_pull(skb, skip_header_bytes);
need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len;
@@ -265,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
struct hostap_skb_tx_data *meta;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc;
iface = netdev_priv(dev);
@@ -287,10 +288,10 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
meta->iface = iface;
if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
- WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
+ if (ieee80211_is_data(hdr->frame_control) &&
+ (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DATA) {
u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN +
sizeof(rfc1042_header)];
meta->ethertype = (pos[0] << 8) | pos[1];
@@ -310,8 +311,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr_4addr *hdr;
- u16 fc;
+ struct ieee80211_hdr *hdr;
int prefix_len, postfix_len, hdr_len, res;
iface = netdev_priv(skb->dev);
@@ -324,7 +324,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (local->tkip_countermeasures &&
strcmp(crypt->ops->name, "TKIP") == 0) {
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
"TX packet to %pM\n",
@@ -349,9 +349,8 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
return NULL;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- hdr_len = hostap_80211_get_hdrlen(fc);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ hdr_len = hostap_80211_get_hdrlen(hdr->frame_control);
/* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
* call both MSDU and MPDU encryption functions from here. */
@@ -384,7 +383,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
ap_tx_ret tx_ret;
struct hostap_skb_tx_data *meta;
int no_encrypt = 0;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -427,14 +426,14 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_ret = hostap_handle_sta_tx(local, &tx);
skb = tx.skb;
meta = (struct hostap_skb_tx_data *) skb->cb;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
switch (tx_ret) {
case AP_TX_CONTINUE:
break;
case AP_TX_CONTINUE_NOT_AUTHORIZED:
if (local->ieee_802_1x &&
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
+ ieee80211_is_data(hdr->frame_control) &&
meta->ethertype != ETH_P_PAE &&
!(meta->flags & HOSTAP_TX_FLAGS_WDS)) {
printk(KERN_DEBUG "%s: dropped frame to unauthorized "
@@ -469,10 +468,10 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* remove special version from the frame header */
fc &= ~IEEE80211_FCTL_VERS;
- hdr->frame_ctl = cpu_to_le16(fc);
+ hdr->frame_control = cpu_to_le16(fc);
}
- if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_DATA) {
+ if (!ieee80211_is_data(hdr->frame_control)) {
no_encrypt = 1;
tx.crypt = NULL;
}
@@ -493,9 +492,9 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Add ISWEP flag both for firmware and host based encryption
*/
fc |= IEEE80211_FCTL_PROTECTED;
- hdr->frame_ctl = cpu_to_le16(fc);
+ hdr->frame_control = cpu_to_le16(fc);
} else if (local->drop_unencrypted &&
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
+ ieee80211_is_data(hdr->frame_control) &&
meta->ethertype != ETH_P_PAE) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: dropped unencrypted TX data "
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 0903db786d5..a2a203c90ba 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -19,6 +19,7 @@
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/random.h>
+#include <linux/if_arp.h>
#include "hostap_wlan.h"
#include "hostap.h"
@@ -588,28 +589,24 @@ void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver)
static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
- u16 fc;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
if (!ap->local->hostapd || !ap->local->apdev) {
dev_kfree_skb(skb);
return;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
-
/* Pass the TX callback frame to the hostapd; use 802.11 header version
* 1 to indicate failure (no ACK) and 2 success (frame ACKed) */
- fc &= ~IEEE80211_FCTL_VERS;
- fc |= ok ? BIT(1) : BIT(0);
- hdr->frame_ctl = cpu_to_le16(fc);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_VERS);
+ hdr->frame_control |= cpu_to_le16(ok ? BIT(1) : BIT(0));
skb->dev = ap->local->apdev;
- skb_pull(skb, hostap_80211_get_hdrlen(fc));
+ skb_pull(skb, hostap_80211_get_hdrlen(hdr->frame_control));
skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_802_2);
+ skb->protocol = cpu_to_be16(ETH_P_802_2);
memset(skb->cb, 0, sizeof(skb->cb));
netif_rx(skb);
}
@@ -621,8 +618,8 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
- struct ieee80211_hdr_4addr *hdr;
- u16 fc, auth_alg, auth_transaction, status;
+ struct ieee80211_hdr *hdr;
+ u16 auth_alg, auth_transaction, status;
__le16 *pos;
struct sta_info *sta = NULL;
char *txt = NULL;
@@ -632,10 +629,8 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
return;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
- WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
+ hdr = (struct ieee80211_hdr *) skb->data;
+ if (!ieee80211_is_auth(hdr->frame_control) ||
skb->len < IEEE80211_MGMT_HDR_LEN + 6) {
printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid "
"frame\n", dev->name);
@@ -691,7 +686,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc, status;
__le16 *pos;
struct sta_info *sta = NULL;
@@ -702,11 +697,10 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
return;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
- (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
- WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_REASSOC_RESP) ||
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
+ if ((!ieee80211_is_assoc_resp(hdr->frame_control) &&
+ !ieee80211_is_reassoc_resp(hdr->frame_control)) ||
skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid "
"frame\n", dev->name);
@@ -757,12 +751,12 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
struct sta_info *sta;
if (skb->len < 24)
goto fail;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (ok) {
spin_lock(&ap->sta_table_lock);
sta = ap_get_sta(ap, hdr->addr1);
@@ -917,7 +911,7 @@ static void prism2_send_mgmt(struct net_device *dev,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc;
struct sk_buff *skb;
struct hostap_skb_tx_data *meta;
@@ -942,8 +936,8 @@ static void prism2_send_mgmt(struct net_device *dev,
}
fc = type_subtype;
- hdrlen = hostap_80211_get_hdrlen(fc);
- hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
+ hdrlen = hostap_80211_get_hdrlen(cpu_to_le16(type_subtype));
+ hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
if (body)
memcpy(skb_put(skb, body_len), body, body_len);
@@ -954,11 +948,11 @@ static void prism2_send_mgmt(struct net_device *dev,
memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */
- if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) {
+ if (ieee80211_is_data(hdr->frame_control)) {
fc |= IEEE80211_FCTL_FROMDS;
memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */
- } else if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL) {
+ } else if (ieee80211_is_ctl(hdr->frame_control)) {
/* control:ACK does not have addr2 or addr3 */
memset(hdr->addr2, 0, ETH_ALEN);
memset(hdr->addr3, 0, ETH_ALEN);
@@ -967,7 +961,7 @@ static void prism2_send_mgmt(struct net_device *dev,
memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
}
- hdr->frame_ctl = cpu_to_le16(fc);
+ hdr->frame_control = cpu_to_le16(fc);
meta = (struct hostap_skb_tx_data *) skb->cb;
memset(meta, 0, sizeof(*meta));
@@ -1284,22 +1278,21 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
size_t hdrlen;
struct ap_data *ap = local->ap;
char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
int len, olen;
u16 auth_alg, auth_transaction, status_code;
__le16 *pos;
- u16 resp = WLAN_STATUS_SUCCESS, fc;
+ u16 resp = WLAN_STATUS_SUCCESS;
struct sta_info *sta = NULL;
struct lib80211_crypt_data *crypt;
char *txt = "";
len = skb->len - IEEE80211_MGMT_HDR_LEN;
- fc = le16_to_cpu(hdr->frame_ctl);
- hdrlen = hostap_80211_get_hdrlen(fc);
+ hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
if (len < 6) {
PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
@@ -1435,7 +1428,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
challenge == NULL ||
memcmp(sta->u.sta.challenge, challenge,
WLAN_AUTH_CHALLENGE_LEN) != 0 ||
- !(fc & IEEE80211_FCTL_PROTECTED)) {
+ !ieee80211_has_protected(hdr->frame_control)) {
txt = "challenge response incorrect";
resp = WLAN_STATUS_CHALLENGE_FAIL;
goto fail;
@@ -1488,7 +1481,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
"trans#=%d stat=%d len=%d fc=%04x) ==> %d (%s)\n",
dev->name, hdr->addr2,
auth_alg, auth_transaction, status_code, len,
- fc, resp, txt);
+ le16_to_cpu(hdr->frame_control), resp, txt);
}
}
@@ -1498,7 +1491,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, int reassoc)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
char body[12], *p, *lpos;
int len, left;
__le16 *pos;
@@ -1707,7 +1700,7 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
int len;
u16 reason_code;
@@ -1749,7 +1742,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len;
u16 reason_code;
@@ -1788,7 +1781,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_data_nullfunc(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr)
+ struct ieee80211_hdr *hdr)
{
struct net_device *dev = local->dev;
@@ -1805,7 +1798,7 @@ static void ap_handle_data_nullfunc(local_info_t *local,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_dropped_data(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr)
+ struct ieee80211_hdr *hdr)
{
struct net_device *dev = local->dev;
struct sta_info *sta;
@@ -1863,7 +1856,7 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
/* Called only as a scheduled task for pending AP frames. */
static void handle_pspoll(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr,
+ struct ieee80211_hdr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
@@ -1872,8 +1865,7 @@ static void handle_pspoll(local_info_t *local,
struct sk_buff *skb;
PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%pM, TA=%pM PWRMGT=%d\n",
- hdr->addr1, hdr->addr2,
- !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM));
+ hdr->addr1, hdr->addr2, !!ieee80211_has_pm(hdr->frame_control));
if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
PDEBUG(DEBUG_AP,
@@ -1984,7 +1976,7 @@ static void handle_wds_oper_queue(struct work_struct *work)
static void handle_beacon(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len, left;
u16 beacon_int, capability;
@@ -2143,14 +2135,14 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
struct net_device *dev = local->dev;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
u16 fc, type, stype;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
/* FIX: should give skb->len to handler functions and check that the
* buffer is long enough */
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
+ type = fc & IEEE80211_FCTL_FTYPE;
+ stype = fc & IEEE80211_FCTL_STYPE;
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
if (!local->hostapd && type == IEEE80211_FTYPE_DATA) {
@@ -2262,8 +2254,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- u16 fc;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -2271,17 +2262,15 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
if (skb->len < 16)
goto drop;
- local->stats.rx_packets++;
+ dev->stats.rx_packets++;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
+ hdr = (struct ieee80211_hdr *) skb->data;
if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT &&
- WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_BEACON)
+ ieee80211_is_beacon(hdr->frame_control))
goto drop;
- skb->protocol = __constant_htons(ETH_P_HOSTAP);
+ skb->protocol = cpu_to_be16(ETH_P_HOSTAP);
handle_ap_item(local, skb, rx_stats);
return;
@@ -2294,7 +2283,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
{
struct sk_buff *skb;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
struct hostap_80211_rx_status rx_stats;
if (skb_queue_empty(&sta->tx_buf))
@@ -2307,10 +2296,10 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
return;
}
- hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
+ hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
/* Generate a fake pspoll frame to start packet delivery */
- hdr->frame_ctl = __constant_cpu_to_le16(
+ hdr->frame_control = cpu_to_le16(
IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN);
memcpy(hdr->addr2, sta->addr, ETH_ALEN);
@@ -2689,7 +2678,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
struct sta_info *sta = NULL;
struct sk_buff *skb = tx->skb;
int set_tim, ret;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
struct hostap_skb_tx_data *meta;
meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2698,7 +2687,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
meta->iface->type == HOSTAP_INTERFACE_STA)
goto out;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (hdr->addr1[0] & 0x01) {
/* broadcast/multicast frame - no AP related processing */
@@ -2753,8 +2742,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) {
/* indicate to STA that more frames follow */
- hdr->frame_ctl |=
- __constant_cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+ hdr->frame_control |=
+ cpu_to_le16(IEEE80211_FCTL_MOREDATA);
}
if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) {
@@ -2828,10 +2817,10 @@ void hostap_handle_sta_release(void *ptr)
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
{
struct sta_info *sta;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
struct hostap_skb_tx_data *meta;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
meta = (struct hostap_skb_tx_data *) skb->cb;
spin_lock(&local->ap->sta_table_lock);
@@ -2898,8 +2887,8 @@ static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
/* Called only as a tasklet (software IRQ). Called for each RX frame to update
- * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
+ * STA power saving state. pwrmgt is a flag from 802.11 frame_control field. */
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
{
struct sta_info *sta;
u16 fc;
@@ -2913,9 +2902,10 @@ int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
if (!sta)
return -1;
- fc = le16_to_cpu(hdr->frame_ctl);
+ fc = le16_to_cpu(hdr->frame_control);
hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
- WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc));
+ fc & IEEE80211_FCTL_FTYPE,
+ fc & IEEE80211_FCTL_STYPE);
atomic_dec(&sta->users);
return 0;
@@ -2932,16 +2922,16 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
int ret;
struct sta_info *sta;
u16 fc, type, stype;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
if (local->ap == NULL)
return AP_RX_CONTINUE;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
+ fc = le16_to_cpu(hdr->frame_control);
+ type = fc & IEEE80211_FCTL_FTYPE;
+ stype = fc & IEEE80211_FCTL_STYPE;
spin_lock(&local->ap->sta_table_lock);
sta = ap_get_sta(local->ap, hdr->addr2);
@@ -3064,7 +3054,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
/* Called only as a tasklet (software IRQ) */
int hostap_handle_sta_crypto(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr,
+ struct ieee80211_hdr *hdr,
struct lib80211_crypt_data **crypt,
void **sta_ptr)
{
@@ -3166,7 +3156,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
/* Called only as a tasklet (software IRQ) */
int hostap_update_rx_stats(struct ap_data *ap,
- struct ieee80211_hdr_4addr *hdr,
+ struct ieee80211_hdr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct sta_info *sta;
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
index d36e4b17533..655ceeba961 100644
--- a/drivers/net/wireless/hostap/hostap_ap.h
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -235,7 +235,7 @@ struct hostap_tx_data {
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
void hostap_handle_sta_release(void *ptr);
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
typedef enum {
AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
} ap_rx_ret;
@@ -243,13 +243,13 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats,
int wds);
-int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
+int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
struct lib80211_crypt_data **crypt,
void **sta_ptr);
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
-int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
+int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
struct hostap_80211_rx_status *rx_stats);
void hostap_update_rates(local_info_t *local);
void hostap_add_wds_links(local_info_t *local);
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 0f27059bbe8..3dad1cf8f24 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -46,7 +46,6 @@
#include <linux/rtnetlink.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
-#include <net/ieee80211.h>
#include <net/lib80211.h>
#include <asm/irq.h>
@@ -1683,7 +1682,7 @@ static int prism2_get_txfid_idx(local_info_t *local)
PDEBUG(DEBUG_EXTRA2, "prism2_get_txfid_idx: no room in txfid buf: "
"packet dropped\n");
- local->stats.tx_dropped++;
+ local->dev->stats.tx_dropped++;
return -1;
}
@@ -1788,11 +1787,9 @@ static int prism2_transmit(struct net_device *dev, int idx)
prism2_transmit_cb, (long) idx);
if (res) {
- struct net_device_stats *stats;
printk(KERN_DEBUG "%s: prism2_transmit: CMDCODE_TRANSMIT "
"failed (res=%d)\n", dev->name, res);
- stats = hostap_get_stats(dev);
- stats->tx_dropped++;
+ dev->stats.tx_dropped++;
netif_wake_queue(dev);
return -1;
}
@@ -1840,8 +1837,8 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
hdr_len = 24;
skb_copy_from_linear_data(skb, &txdesc.frame_control, hdr_len);
fc = le16_to_cpu(txdesc.frame_control);
- if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
- (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS) &&
+ if (ieee80211_is_data(txdesc.frame_control) &&
+ ieee80211_has_a4(txdesc.frame_control) &&
skb->len >= 30) {
/* Addr4 */
skb_copy_from_linear_data_offset(skb, hdr_len, txdesc.addr4,
@@ -1940,12 +1937,10 @@ static void prism2_rx(local_info_t *local)
struct net_device *dev = local->dev;
int res, rx_pending = 0;
u16 len, hdr_len, rxfid, status, macport;
- struct net_device_stats *stats;
struct hfa384x_rx_frame rxdesc;
struct sk_buff *skb = NULL;
prism2_callback(local, PRISM2_CALLBACK_RX_START);
- stats = hostap_get_stats(dev);
rxfid = prism2_read_fid_reg(dev, HFA384X_RXFID_OFF);
#ifndef final_version
@@ -2032,7 +2027,7 @@ static void prism2_rx(local_info_t *local)
return;
rx_dropped:
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
if (skb)
dev_kfree_skb(skb);
goto rx_exit;
@@ -2082,7 +2077,7 @@ static void hostap_rx_skb(local_info_t *local, struct sk_buff *skb)
stats.rate = rxdesc->rate;
/* Convert Prism2 RX structure into IEEE 802.11 header */
- hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(rxdesc->frame_control));
+ hdrlen = hostap_80211_get_hdrlen(rxdesc->frame_control);
if (hdrlen > rx_hdrlen)
hdrlen = rx_hdrlen;
@@ -2204,7 +2199,7 @@ static void hostap_tx_callback(local_info_t *local,
return;
}
- hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(txdesc->frame_control));
+ hdrlen = hostap_80211_get_hdrlen(txdesc->frame_control);
len = le16_to_cpu(txdesc->data_len);
skb = dev_alloc_skb(hdrlen + len);
if (skb == NULL) {
@@ -2315,8 +2310,7 @@ static void hostap_sta_tx_exc_tasklet(unsigned long data)
if (skb->len >= sizeof(*txdesc)) {
/* Convert Prism2 RX structure into IEEE 802.11 header
*/
- u16 fc = le16_to_cpu(txdesc->frame_control);
- int hdrlen = hostap_80211_get_hdrlen(fc);
+ int hdrlen = hostap_80211_get_hdrlen(txdesc->frame_control);
memmove(skb_pull(skb, sizeof(*txdesc) - hdrlen),
&txdesc->frame_control, hdrlen);
@@ -2337,7 +2331,7 @@ static void prism2_txexc(local_info_t *local)
struct hfa384x_tx_frame txdesc;
show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR;
- local->stats.tx_errors++;
+ dev->stats.tx_errors++;
res = hostap_tx_compl_read(local, 1, &txdesc, &payload);
HFA384X_OUTW(HFA384X_EV_TXEXC, HFA384X_EVACK_OFF);
@@ -2394,12 +2388,12 @@ static void prism2_txexc(local_info_t *local)
PDEBUG(DEBUG_EXTRA, " retry_count=%d tx_rate=%d fc=0x%04x "
"(%s%s%s::%d%s%s)\n",
txdesc.retry_count, txdesc.tx_rate, fc,
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT ? "Mgmt" : "",
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL ? "Ctrl" : "",
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA ? "Data" : "",
- WLAN_FC_GET_STYPE(fc) >> 4,
- fc & IEEE80211_FCTL_TODS ? " ToDS" : "",
- fc & IEEE80211_FCTL_FROMDS ? " FromDS" : "");
+ ieee80211_is_mgmt(txdesc.frame_control) ? "Mgmt" : "",
+ ieee80211_is_ctl(txdesc.frame_control) ? "Ctrl" : "",
+ ieee80211_is_data(txdesc.frame_control) ? "Data" : "",
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
+ ieee80211_has_tods(txdesc.frame_control) ? " ToDS" : "",
+ ieee80211_has_fromds(txdesc.frame_control) ? " FromDS" : "");
PDEBUG(DEBUG_EXTRA, " A1=%pM A2=%pM A3=%pM A4=%pM\n",
txdesc.addr1, txdesc.addr2,
txdesc.addr3, txdesc.addr4);
@@ -3228,7 +3222,6 @@ while (0)
hostap_setup_dev(dev, local, HOSTAP_INTERFACE_MASTER);
- dev->hard_start_xmit = hostap_master_start_xmit;
dev->type = ARPHRD_IEEE80211;
dev->header_ops = &hostap_80211_ops;
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
index 99b4cf41edf..6fa14a4e4b5 100644
--- a/drivers/net/wireless/hostap/hostap_info.c
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -1,5 +1,6 @@
/* Host AP driver Info Frame processing (part of hostap.o module) */
+#include <linux/if_arp.h>
#include "hostap_wlan.h"
#include "hostap.h"
#include "hostap_ap.h"
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index c40fdf4c79d..3f2bda881a4 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -2,6 +2,7 @@
#include <linux/types.h>
#include <linux/ethtool.h>
+#include <linux/if_arp.h>
#include <net/lib80211.h>
#include "hostap_wlan.h"
@@ -1638,7 +1639,7 @@ static int prism2_request_hostscan(struct net_device *dev,
memset(&scan_req, 0, sizeof(scan_req));
scan_req.channel_list = cpu_to_le16(local->channel_mask &
local->scan_channel_mask);
- scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+ scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
if (ssid) {
if (ssid_len > 32)
return -EINVAL;
@@ -1668,7 +1669,7 @@ static int prism2_request_scan(struct net_device *dev)
memset(&scan_req, 0, sizeof(scan_req));
scan_req.channel_list = cpu_to_le16(local->channel_mask &
local->scan_channel_mask);
- scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+ scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
/* FIX:
* It seems to be enough to set roaming mode for a short moment to
@@ -2514,7 +2515,7 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
u16 rate;
memset(&scan_req, 0, sizeof(scan_req));
- scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
+ scan_req.channel_list = cpu_to_le16(0x3fff);
switch (value) {
case 1: rate = HFA384X_RATES_1MBPS; break;
case 2: rate = HFA384X_RATES_2MBPS; break;
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 02a312ca860..6fe122f18c0 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -26,7 +26,6 @@
#include <linux/etherdevice.h>
#include <net/net_namespace.h>
#include <net/iw_handler.h>
-#include <net/ieee80211.h>
#include <net/lib80211.h>
#include <asm/uaccess.h>
@@ -543,7 +542,8 @@ void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx)
fc = __le16_to_cpu(rx->frame_control);
printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
"data_len=%d%s%s\n",
- fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+ fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
__le16_to_cpu(rx->duration_id), __le16_to_cpu(rx->seq_ctrl),
__le16_to_cpu(rx->data_len),
fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
@@ -570,7 +570,8 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
fc = __le16_to_cpu(tx->frame_control);
printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
"data_len=%d%s%s\n",
- fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+ fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
__le16_to_cpu(tx->duration_id), __le16_to_cpu(tx->seq_ctrl),
__le16_to_cpu(tx->data_len),
fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
@@ -593,37 +594,16 @@ static int hostap_80211_header_parse(const struct sk_buff *skb,
}
-int hostap_80211_get_hdrlen(u16 fc)
+int hostap_80211_get_hdrlen(__le16 fc)
{
- int hdrlen = 24;
-
- switch (WLAN_FC_GET_TYPE(fc)) {
- case IEEE80211_FTYPE_DATA:
- if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
- hdrlen = 30; /* Addr4 */
- break;
- case IEEE80211_FTYPE_CTL:
- switch (WLAN_FC_GET_STYPE(fc)) {
- case IEEE80211_STYPE_CTS:
- case IEEE80211_STYPE_ACK:
- hdrlen = 10;
- break;
- default:
- hdrlen = 16;
- break;
- }
- break;
- }
-
- return hdrlen;
-}
-
-
-struct net_device_stats *hostap_get_stats(struct net_device *dev)
-{
- struct hostap_interface *iface;
- iface = netdev_priv(dev);
- return &iface->stats;
+ if (ieee80211_is_data(fc) && ieee80211_has_a4 (fc))
+ return 30; /* Addr4 */
+ else if (ieee80211_is_cts(fc) || ieee80211_is_ack(fc))
+ return 10;
+ else if (ieee80211_is_ctl(fc))
+ return 16;
+
+ return 24;
}
@@ -835,6 +815,46 @@ const struct header_ops hostap_80211_ops = {
};
EXPORT_SYMBOL(hostap_80211_ops);
+
+static const struct net_device_ops hostap_netdev_ops = {
+ .ndo_start_xmit = hostap_data_start_xmit,
+
+ .ndo_open = prism2_open,
+ .ndo_stop = prism2_close,
+ .ndo_do_ioctl = hostap_ioctl,
+ .ndo_set_mac_address = prism2_set_mac_address,
+ .ndo_set_multicast_list = hostap_set_multicast_list,
+ .ndo_change_mtu = prism2_change_mtu,
+ .ndo_tx_timeout = prism2_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static const struct net_device_ops hostap_mgmt_netdev_ops = {
+ .ndo_start_xmit = hostap_mgmt_start_xmit,
+
+ .ndo_open = prism2_open,
+ .ndo_stop = prism2_close,
+ .ndo_do_ioctl = hostap_ioctl,
+ .ndo_set_mac_address = prism2_set_mac_address,
+ .ndo_set_multicast_list = hostap_set_multicast_list,
+ .ndo_change_mtu = prism2_change_mtu,
+ .ndo_tx_timeout = prism2_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static const struct net_device_ops hostap_master_ops = {
+ .ndo_start_xmit = hostap_master_start_xmit,
+
+ .ndo_open = prism2_open,
+ .ndo_stop = prism2_close,
+ .ndo_do_ioctl = hostap_ioctl,
+ .ndo_set_mac_address = prism2_set_mac_address,
+ .ndo_set_multicast_list = hostap_set_multicast_list,
+ .ndo_change_mtu = prism2_change_mtu,
+ .ndo_tx_timeout = prism2_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
void hostap_setup_dev(struct net_device *dev, local_info_t *local,
int type)
{
@@ -844,37 +864,31 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
ether_setup(dev);
/* kernel callbacks */
- dev->get_stats = hostap_get_stats;
if (iface) {
/* Currently, we point to the proper spy_data only on
* the main_dev. This could be fixed. Jean II */
iface->wireless_data.spy_data = &iface->spy_data;
dev->wireless_data = &iface->wireless_data;
}
- dev->wireless_handlers =
- (struct iw_handler_def *) &hostap_iw_handler_def;
- dev->do_ioctl = hostap_ioctl;
- dev->open = prism2_open;
- dev->stop = prism2_close;
- dev->set_mac_address = prism2_set_mac_address;
- dev->set_multicast_list = hostap_set_multicast_list;
- dev->change_mtu = prism2_change_mtu;
- dev->tx_timeout = prism2_tx_timeout;
+ dev->wireless_handlers = &hostap_iw_handler_def;
dev->watchdog_timeo = TX_TIMEOUT;
- if (type == HOSTAP_INTERFACE_AP) {
- dev->hard_start_xmit = hostap_mgmt_start_xmit;
+ switch(type) {
+ case HOSTAP_INTERFACE_AP:
+ dev->netdev_ops = &hostap_mgmt_netdev_ops;
dev->type = ARPHRD_IEEE80211;
dev->header_ops = &hostap_80211_ops;
- } else {
- dev->hard_start_xmit = hostap_data_start_xmit;
+ break;
+ case HOSTAP_INTERFACE_MASTER:
+ dev->tx_queue_len = 0; /* use main radio device queue */
+ dev->netdev_ops = &hostap_master_ops;
+ break;
+ default:
+ dev->netdev_ops = &hostap_netdev_ops;
}
dev->mtu = local->mtu;
- if (type != HOSTAP_INTERFACE_MASTER) {
- /* use main radio device queue */
- dev->tx_queue_len = 0;
- }
+
SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
@@ -1124,7 +1138,6 @@ EXPORT_SYMBOL(hostap_set_auth_algs);
EXPORT_SYMBOL(hostap_dump_rx_header);
EXPORT_SYMBOL(hostap_dump_tx_header);
EXPORT_SYMBOL(hostap_80211_get_hdrlen);
-EXPORT_SYMBOL(hostap_get_stats);
EXPORT_SYMBOL(hostap_setup_dev);
EXPORT_SYMBOL(hostap_set_multicast_list_queue);
EXPORT_SYMBOL(hostap_set_hostapd);
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index 4d8d51a353c..3d238917af0 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -684,7 +684,6 @@ struct local_info {
u16 channel_mask; /* mask of allowed channels */
u16 scan_channel_mask; /* mask of channels to be scanned */
struct comm_tallies_sums comm_tallies;
- struct net_device_stats stats;
struct proc_dir_entry *proc;
int iw_mode; /* operating mode (IW_MODE_*) */
int pseudo_adhoc; /* 0: IW_MODE_ADHOC is real 802.11 compliant IBSS
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig
index 3d5cc4463d4..85cc79995f6 100644
--- a/drivers/net/wireless/ipw2x00/Kconfig
+++ b/drivers/net/wireless/ipw2x00/Kconfig
@@ -150,6 +150,7 @@ config IPW2200_DEBUG
config LIBIPW
tristate
+ depends on PCI && WLAN_80211
select WIRELESS_EXT
select CRYPTO
select CRYPTO_ARC4
@@ -185,7 +186,7 @@ config LIBIPW_DEBUG
% echo 0x00000FFO > /proc/net/ieee80211/debug_level
For a list of values you can assign to debug_level, you
- can look at the bit mask values in <net/ieee80211.h>
+ can look at the bit mask values in ieee80211.h
If you are not trying to debug or develop the libipw
component, you most likely want to say N here.
diff --git a/drivers/net/wireless/ipw2x00/ieee80211.h b/drivers/net/wireless/ipw2x00/ieee80211.h
new file mode 100644
index 00000000000..70755c1336d
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/ieee80211.h
@@ -0,0 +1,1087 @@
+/*
+ * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
+ * remains copyright by the original authors
+ *
+ * Portions of the merged code are based on Host AP (software wireless
+ * LAN access point) driver for Intersil Prism2/2.5/3.
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <j@w1.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno@linux.intel.com>
+ * Copyright (c) 2004-2005, 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. See README and COPYING for
+ * more details.
+ *
+ * API Version History
+ * 1.0.x -- Initial version
+ * 1.1.x -- Added radiotap, QoS, TIM, ieee80211_geo APIs,
+ * various structure changes, and crypto API init method
+ */
+#ifndef IEEE80211_H
+#define IEEE80211_H
+#include <linux/if_ether.h> /* ETH_ALEN */
+#include <linux/kernel.h> /* ARRAY_SIZE */
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+
+#include <net/lib80211.h>
+
+#define IEEE80211_VERSION "git-1.1.13"
+
+#define IEEE80211_DATA_LEN 2304
+/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+ 6.2.1.1.2.
+
+ The figure in section 7.1.2 suggests a body size of up to 2312
+ bytes is allowed, which is a bit confusing, I suspect this
+ represents the 2304 bytes of real data, plus a possible 8 bytes of
+ WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
+
+#define IEEE80211_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN 4
+#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+#define MIN_FRAG_THRESHOLD 256U
+#define MAX_FRAG_THRESHOLD 2346U
+
+/* QOS control */
+#define IEEE80211_QCTL_TID 0x000F
+
+/* debug macros */
+
+#ifdef CONFIG_LIBIPW_DEBUG
+extern u32 ieee80211_debug_level;
+#define IEEE80211_DEBUG(level, fmt, args...) \
+do { if (ieee80211_debug_level & (level)) \
+ printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
+ in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+static inline bool ieee80211_ratelimit_debug(u32 level)
+{
+ return (ieee80211_debug_level & level) && net_ratelimit();
+}
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+static inline bool ieee80211_ratelimit_debug(u32 level)
+{
+ return false;
+}
+#endif /* CONFIG_LIBIPW_DEBUG */
+
+/*
+ * To use the debug system:
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define IEEE80211_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry. xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
+ * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/ieee80211/debug_level
+ *
+ * you simply need to add your entry to the ieee80211_debug_level array.
+ *
+ * If you do not see debug_level in /proc/net/ieee80211 then you do not have
+ * CONFIG_LIBIPW_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define IEEE80211_DL_INFO (1<<0)
+#define IEEE80211_DL_WX (1<<1)
+#define IEEE80211_DL_SCAN (1<<2)
+#define IEEE80211_DL_STATE (1<<3)
+#define IEEE80211_DL_MGMT (1<<4)
+#define IEEE80211_DL_FRAG (1<<5)
+#define IEEE80211_DL_DROP (1<<7)
+
+#define IEEE80211_DL_TX (1<<8)
+#define IEEE80211_DL_RX (1<<9)
+#define IEEE80211_DL_QOS (1<<31)
+
+#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
+#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
+#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
+
+#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
+#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
+#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
+#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
+#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
+#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
+#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
+#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
+#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+#include <linux/netdevice.h>
+#include <linux/if_arp.h> /* ARPHRD_ETHER */
+
+#ifndef WIRELESS_SPY
+#define WIRELESS_SPY /* enable iwspy support */
+#endif
+#include <net/iw_handler.h> /* new driver API */
+
+#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+#endif
+
+/* IEEE 802.11 defines */
+
+#define P80211_OUI_LEN 3
+
+struct ieee80211_snap_hdr {
+
+ u8 dsap; /* always 0xAA */
+ u8 ssap; /* always 0xAA */
+ u8 ctrl; /* always 0x03 */
+ u8 oui[P80211_OUI_LEN]; /* organizational universal id */
+
+} __attribute__ ((packed));
+
+#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
+
+#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+#define IEEE80211_STATMASK_SIGNAL (1<<0)
+#define IEEE80211_STATMASK_RSSI (1<<1)
+#define IEEE80211_STATMASK_NOISE (1<<2)
+#define IEEE80211_STATMASK_RATE (1<<3)
+#define IEEE80211_STATMASK_WEMASK 0x7
+
+#define IEEE80211_CCK_MODULATION (1<<0)
+#define IEEE80211_OFDM_MODULATION (1<<1)
+
+#define IEEE80211_24GHZ_BAND (1<<0)
+#define IEEE80211_52GHZ_BAND (1<<1)
+
+#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)
+
+#define IEEE80211_NUM_OFDM_RATES 8
+#define IEEE80211_NUM_CCK_RATES 4
+#define IEEE80211_OFDM_SHIFT_MASK_A 4
+
+/* NOTE: This data is for statistical purposes; not all hardware provides this
+ * information for frames received.
+ * For ieee80211_rx_mgt, you need to set at least the 'len' parameter.
+ */
+struct ieee80211_rx_stats {
+ u32 mac_time;
+ s8 rssi;
+ u8 signal;
+ u8 noise;
+ u16 rate; /* in 100 kbps */
+ u8 received_channel;
+ u8 control;
+ u8 mask;
+ u8 freq;
+ u16 len;
+ u64 tsf;
+ u32 beacon_time;
+};
+
+/* IEEE 802.11 requires that STA supports concurrent reception of at least
+ * three fragmented frames. This define can be increased to support more
+ * concurrent frames, but it should be noted that each entry can consume about
+ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
+#define IEEE80211_FRAG_CACHE_LEN 4
+
+struct ieee80211_frag_entry {
+ unsigned long first_frag_time;
+ unsigned int seq;
+ unsigned int last_frag;
+ struct sk_buff *skb;
+ u8 src_addr[ETH_ALEN];
+ u8 dst_addr[ETH_ALEN];
+};
+
+struct ieee80211_stats {
+ unsigned int tx_unicast_frames;
+ unsigned int tx_multicast_frames;
+ unsigned int tx_fragments;
+ unsigned int tx_unicast_octets;
+ unsigned int tx_multicast_octets;
+ unsigned int tx_deferred_transmissions;
+ unsigned int tx_single_retry_frames;
+ unsigned int tx_multiple_retry_frames;
+ unsigned int tx_retry_limit_exceeded;
+ unsigned int tx_discards;
+ unsigned int rx_unicast_frames;
+ unsigned int rx_multicast_frames;
+ unsigned int rx_fragments;
+ unsigned int rx_unicast_octets;
+ unsigned int rx_multicast_octets;
+ unsigned int rx_fcs_errors;
+ unsigned int rx_discards_no_buffer;
+ unsigned int tx_discards_wrong_sa;
+ unsigned int rx_discards_undecryptable;
+ unsigned int rx_message_in_msg_fragments;
+ unsigned int rx_message_in_bad_msg_fragments;
+};
+
+struct ieee80211_device;
+
+#define SEC_KEY_1 (1<<0)
+#define SEC_KEY_2 (1<<1)
+#define SEC_KEY_3 (1<<2)
+#define SEC_KEY_4 (1<<3)
+#define SEC_ACTIVE_KEY (1<<4)
+#define SEC_AUTH_MODE (1<<5)
+#define SEC_UNICAST_GROUP (1<<6)
+#define SEC_LEVEL (1<<7)
+#define SEC_ENABLED (1<<8)
+#define SEC_ENCRYPT (1<<9)
+
+#define SEC_LEVEL_0 0 /* None */
+#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
+#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
+#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
+
+#define SEC_ALG_NONE 0
+#define SEC_ALG_WEP 1
+#define SEC_ALG_TKIP 2
+#define SEC_ALG_CCMP 3
+
+#define WEP_KEYS 4
+#define WEP_KEY_LEN 13
+#define SCM_KEY_LEN 32
+#define SCM_TEMPORAL_KEY_LENGTH 16
+
+struct ieee80211_security {
+ u16 active_key:2, enabled:1, unicast_uses_group:1, encrypt:1;
+ u8 auth_mode;
+ u8 encode_alg[WEP_KEYS];
+ u8 key_sizes[WEP_KEYS];
+ u8 keys[WEP_KEYS][SCM_KEY_LEN];
+ u8 level;
+ u16 flags;
+} __attribute__ ((packed));
+
+/*
+
+ 802.11 data frame from AP
+
+ ,-------------------------------------------------------------------.
+Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
+ |------|------|---------|---------|---------|------|---------|------|
+Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
+ | | tion | (BSSID) | | | ence | data | |
+ `-------------------------------------------------------------------'
+
+Total: 28-2340 bytes
+
+*/
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct ieee80211_hdr_1addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+ __le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+ u8 id;
+ u8 len;
+ u8 data[0];
+} __attribute__ ((packed));
+
+/*
+ * These are the data types that can make up management packets
+ *
+ u16 auth_algorithm;
+ u16 auth_sequence;
+ u16 beacon_interval;
+ u16 capability;
+ u8 current_ap[ETH_ALEN];
+ u16 listen_interval;
+ struct {
+ u16 association_id:14, reserved:2;
+ } __attribute__ ((packed));
+ u32 time_stamp[2];
+ u16 reason;
+ u16 status;
+*/
+
+struct ieee80211_auth {
+ struct ieee80211_hdr_3addr header;
+ __le16 algorithm;
+ __le16 transaction;
+ __le16 status;
+ /* challenge */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_channel_switch {
+ u8 id;
+ u8 len;
+ u8 mode;
+ u8 channel;
+ u8 count;
+} __attribute__ ((packed));
+
+struct ieee80211_action {
+ struct ieee80211_hdr_3addr header;
+ u8 category;
+ u8 action;
+ union {
+ struct ieee80211_action_exchange {
+ u8 token;
+ struct ieee80211_info_element info_element[0];
+ } exchange;
+ struct ieee80211_channel_switch channel_switch;
+
+ } format;
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+ struct ieee80211_hdr_3addr header;
+ __le16 reason;
+} __attribute__ ((packed));
+
+/* Alias deauth for disassoc */
+#define ieee80211_deauth ieee80211_disassoc
+
+struct ieee80211_probe_request {
+ struct ieee80211_hdr_3addr header;
+ /* SSID, supported rates */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+ struct ieee80211_hdr_3addr header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ /* SSID, supported rates, FH params, DS params,
+ * CF params, IBSS params, TIM (if beacon), RSN */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 listen_interval;
+ /* SSID, supported rates, RSN */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_reassoc_request {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 listen_interval;
+ u8 current_ap[ETH_ALEN];
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 status;
+ __le16 aid;
+ /* supported rates */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+ u8 nr_frags;
+ u8 encrypted;
+ u8 rts_included;
+ u8 reserved;
+ u16 frag_size;
+ u16 payload_size;
+ struct sk_buff *fragments[0];
+};
+
+/* SWEEP TABLE ENTRIES NUMBER */
+#define MAX_SWEEP_TAB_ENTRIES 42
+#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
+/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
+ * only use 8, and then use extended rates for the remaining supported
+ * rates. Other APs, however, stick all of their supported rates on the
+ * main rates information element... */
+#define MAX_RATES_LENGTH ((u8)12)
+#define MAX_RATES_EX_LENGTH ((u8)16)
+#define MAX_NETWORK_COUNT 128
+
+#define CRC_LENGTH 4U
+
+#define MAX_WPA_IE_LEN 64
+
+#define NETWORK_HAS_OFDM (1<<1)
+#define NETWORK_HAS_CCK (1<<2)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION (1<<4)
+#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \
+ NETWORK_HAS_QOS_INFORMATION)
+
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT (1<<5)
+#define NETWORK_HAS_CSA (1<<6)
+#define NETWORK_HAS_QUIET (1<<7)
+#define NETWORK_HAS_IBSS_DFS (1<<8)
+#define NETWORK_HAS_TPC_REPORT (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE (1<<10)
+
+#define QOS_QUEUE_NUM 4
+#define QOS_OUI_LEN 3
+#define QOS_OUI_TYPE 2
+#define QOS_ELEMENT_ID 221
+#define QOS_OUI_INFO_SUB_TYPE 0
+#define QOS_OUI_PARAM_SUB_TYPE 1
+#define QOS_VERSION_1 1
+#define QOS_AIFSN_MIN_VALUE 2
+
+struct ieee80211_qos_information_element {
+ u8 elementID;
+ u8 length;
+ u8 qui[QOS_OUI_LEN];
+ u8 qui_type;
+ u8 qui_subtype;
+ u8 version;
+ u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+ u8 aci_aifsn;
+ u8 ecw_min_max;
+ __le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+ struct ieee80211_qos_information_element info_element;
+ u8 reserved;
+ struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+ __le16 cw_min[QOS_QUEUE_NUM];
+ __le16 cw_max[QOS_QUEUE_NUM];
+ u8 aifs[QOS_QUEUE_NUM];
+ u8 flag[QOS_QUEUE_NUM];
+ __le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+ struct ieee80211_qos_parameters parameters;
+ int active;
+ int supported;
+ u8 param_count;
+ u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+ u8 tim_count;
+ u8 tim_period;
+} __attribute__ ((packed));
+
+/*******************************************************/
+
+enum { /* ieee80211_basic_report.map */
+ IEEE80211_BASIC_MAP_BSS = (1 << 0),
+ IEEE80211_BASIC_MAP_OFDM = (1 << 1),
+ IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2),
+ IEEE80211_BASIC_MAP_RADAR = (1 << 3),
+ IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4),
+ /* Bits 5-7 are reserved */
+
+};
+struct ieee80211_basic_report {
+ u8 channel;
+ __le64 start_time;
+ __le16 duration;
+ u8 map;
+} __attribute__ ((packed));
+
+enum { /* ieee80211_measurement_request.mode */
+ /* Bit 0 is reserved */
+ IEEE80211_MEASUREMENT_ENABLE = (1 << 1),
+ IEEE80211_MEASUREMENT_REQUEST = (1 << 2),
+ IEEE80211_MEASUREMENT_REPORT = (1 << 3),
+ /* Bits 4-7 are reserved */
+};
+
+enum {
+ IEEE80211_REPORT_BASIC = 0, /* required */
+ IEEE80211_REPORT_CCA = 1, /* optional */
+ IEEE80211_REPORT_RPI = 2, /* optional */
+ /* 3-255 reserved */
+};
+
+struct ieee80211_measurement_params {
+ u8 channel;
+ __le64 start_time;
+ __le16 duration;
+} __attribute__ ((packed));
+
+struct ieee80211_measurement_request {
+ struct ieee80211_info_element ie;
+ u8 token;
+ u8 mode;
+ u8 type;
+ struct ieee80211_measurement_params params[0];
+} __attribute__ ((packed));
+
+struct ieee80211_measurement_report {
+ struct ieee80211_info_element ie;
+ u8 token;
+ u8 mode;
+ u8 type;
+ union {
+ struct ieee80211_basic_report basic[0];
+ } u;
+} __attribute__ ((packed));
+
+struct ieee80211_tpc_report {
+ u8 transmit_power;
+ u8 link_margin;
+} __attribute__ ((packed));
+
+struct ieee80211_channel_map {
+ u8 channel;
+ u8 map;
+} __attribute__ ((packed));
+
+struct ieee80211_ibss_dfs {
+ struct ieee80211_info_element ie;
+ u8 owner[ETH_ALEN];
+ u8 recovery_interval;
+ struct ieee80211_channel_map channel_map[0];
+};
+
+struct ieee80211_csa {
+ u8 mode;
+ u8 channel;
+ u8 count;
+} __attribute__ ((packed));
+
+struct ieee80211_quiet {
+ u8 count;
+ u8 period;
+ u8 duration;
+ u8 offset;
+} __attribute__ ((packed));
+
+struct ieee80211_network {
+ /* These entries are used to identify a unique network */
+ u8 bssid[ETH_ALEN];
+ u8 channel;
+ /* Ensure null-terminated for any debug msgs */
+ u8 ssid[IW_ESSID_MAX_SIZE + 1];
+ u8 ssid_len;
+
+ struct ieee80211_qos_data qos_data;
+
+ /* These are network statistics */
+ struct ieee80211_rx_stats stats;
+ u16 capability;
+ u8 rates[MAX_RATES_LENGTH];
+ u8 rates_len;
+ u8 rates_ex[MAX_RATES_EX_LENGTH];
+ u8 rates_ex_len;
+ unsigned long last_scanned;
+ u8 mode;
+ u32 flags;
+ u32 last_associate;
+ u32 time_stamp[2];
+ u16 beacon_interval;
+ u16 listen_interval;
+ u16 atim_window;
+ u8 erp_value;
+ u8 wpa_ie[MAX_WPA_IE_LEN];
+ size_t wpa_ie_len;
+ u8 rsn_ie[MAX_WPA_IE_LEN];
+ size_t rsn_ie_len;
+ struct ieee80211_tim_parameters tim;
+
+ /* 802.11h info */
+
+ /* Power Constraint - mandatory if spctrm mgmt required */
+ u8 power_constraint;
+
+ /* TPC Report - mandatory if spctrm mgmt required */
+ struct ieee80211_tpc_report tpc_report;
+
+ /* IBSS DFS - mandatory if spctrm mgmt required and IBSS
+ * NOTE: This is variable length and so must be allocated dynamically */
+ struct ieee80211_ibss_dfs *ibss_dfs;
+
+ /* Channel Switch Announcement - optional if spctrm mgmt required */
+ struct ieee80211_csa csa;
+
+ /* Quiet - optional if spctrm mgmt required */
+ struct ieee80211_quiet quiet;
+
+ struct list_head list;
+};
+
+enum ieee80211_state {
+ IEEE80211_UNINITIALIZED = 0,
+ IEEE80211_INITIALIZED,
+ IEEE80211_ASSOCIATING,
+ IEEE80211_ASSOCIATED,
+ IEEE80211_AUTHENTICATING,
+ IEEE80211_AUTHENTICATED,
+ IEEE80211_SHUTDOWN
+};
+
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+#define DEFAULT_FTS 2346
+
+#define CFG_IEEE80211_RESERVE_FCS (1<<0)
+#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+ IEEE80211_24GHZ_MIN_CHANNEL + 1)
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+ IEEE80211_52GHZ_MIN_CHANNEL + 1)
+
+enum {
+ IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
+ IEEE80211_CH_80211H_RULES = (1 << 1),
+ IEEE80211_CH_B_ONLY = (1 << 2),
+ IEEE80211_CH_NO_IBSS = (1 << 3),
+ IEEE80211_CH_UNIFORM_SPREADING = (1 << 4),
+ IEEE80211_CH_RADAR_DETECT = (1 << 5),
+ IEEE80211_CH_INVALID = (1 << 6),
+};
+
+struct ieee80211_channel {
+ u32 freq; /* in MHz */
+ u8 channel;
+ u8 flags;
+ u8 max_power; /* in dBm */
+};
+
+struct ieee80211_geo {
+ u8 name[4];
+ u8 bg_channels;
+ u8 a_channels;
+ struct ieee80211_channel bg[IEEE80211_24GHZ_CHANNELS];
+ struct ieee80211_channel a[IEEE80211_52GHZ_CHANNELS];
+};
+
+struct ieee80211_device {
+ struct net_device *dev;
+ struct ieee80211_security sec;
+
+ /* Bookkeeping structures */
+ struct ieee80211_stats ieee_stats;
+
+ struct ieee80211_geo geo;
+
+ /* Probe / Beacon management */
+ struct list_head network_free_list;
+ struct list_head network_list;
+ struct ieee80211_network *networks;
+ int scans;
+ int scan_age;
+
+ int iw_mode; /* operating mode (IW_MODE_*) */
+ struct iw_spy_data spy_data; /* iwspy support */
+
+ spinlock_t lock;
+
+ int tx_headroom; /* Set to size of any additional room needed at front
+ * of allocated Tx SKBs */
+ u32 config;
+
+ /* WEP and other encryption related settings at the device level */
+ int open_wep; /* Set to 1 to allow unencrypted frames */
+
+ int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
+ * WEP key changes */
+
+ /* If the host performs {en,de}cryption, then set to 1 */
+ int host_encrypt;
+ int host_encrypt_msdu;
+ int host_decrypt;
+ /* host performs multicast decryption */
+ int host_mc_decrypt;
+
+ /* host should strip IV and ICV from protected frames */
+ /* meaningful only when hardware decryption is being used */
+ int host_strip_iv_icv;
+
+ int host_open_frag;
+ int host_build_iv;
+ int ieee802_1x; /* is IEEE 802.1X used */
+
+ /* WPA data */
+ int wpa_enabled;
+ int drop_unencrypted;
+ int privacy_invoked;
+ size_t wpa_ie_len;
+ u8 *wpa_ie;
+
+ struct lib80211_crypt_info crypt_info;
+
+ int bcrx_sta_key; /* use individual keys to override default keys even
+ * with RX of broad/multicast frames */
+
+ /* Fragmentation structures */
+ struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
+ unsigned int frag_next_idx;
+ u16 fts; /* Fragmentation Threshold */
+ u16 rts; /* RTS threshold */
+
+ /* Association info */
+ u8 bssid[ETH_ALEN];
+
+ enum ieee80211_state state;
+
+ int mode; /* A, B, G */
+ int modulation; /* CCK, OFDM */
+ int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
+ int abg_true; /* ABG flag */
+
+ int perfect_rssi;
+ int worst_rssi;
+
+ u16 prev_seq_ctl; /* used to drop duplicate frames */
+
+ /* Callback functions */
+ void (*set_security) (struct net_device * dev,
+ struct ieee80211_security * sec);
+ int (*hard_start_xmit) (struct ieee80211_txb * txb,
+ struct net_device * dev, int pri);
+ int (*reset_port) (struct net_device * dev);
+ int (*is_queue_full) (struct net_device * dev, int pri);
+
+ int (*handle_management) (struct net_device * dev,
+ struct ieee80211_network * network, u16 type);
+ int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+ /* Typical STA methods */
+ int (*handle_auth) (struct net_device * dev,
+ struct ieee80211_auth * auth);
+ int (*handle_deauth) (struct net_device * dev,
+ struct ieee80211_deauth * auth);
+ int (*handle_action) (struct net_device * dev,
+ struct ieee80211_action * action,
+ struct ieee80211_rx_stats * stats);
+ int (*handle_disassoc) (struct net_device * dev,
+ struct ieee80211_disassoc * assoc);
+ int (*handle_beacon) (struct net_device * dev,
+ struct ieee80211_beacon * beacon,
+ struct ieee80211_network * network);
+ int (*handle_probe_response) (struct net_device * dev,
+ struct ieee80211_probe_response * resp,
+ struct ieee80211_network * network);
+ int (*handle_probe_request) (struct net_device * dev,
+ struct ieee80211_probe_request * req,
+ struct ieee80211_rx_stats * stats);
+ int (*handle_assoc_response) (struct net_device * dev,
+ struct ieee80211_assoc_response * resp,
+ struct ieee80211_network * network);
+
+ /* Typical AP methods */
+ int (*handle_assoc_request) (struct net_device * dev);
+ int (*handle_reassoc_request) (struct net_device * dev,
+ struct ieee80211_reassoc_request * req);
+
+ /* This must be the last item so that it points to the data
+ * allocated beyond this structure by alloc_ieee80211 */
+ u8 priv[0];
+};
+
+#define IEEE_A (1<<0)
+#define IEEE_B (1<<1)
+#define IEEE_G (1<<2)
+#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
+
+static inline void *ieee80211_priv(struct net_device *dev)
+{
+ return ((struct ieee80211_device *)netdev_priv(dev))->priv;
+}
+
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
+ int mode)
+{
+ /*
+ * It is possible for both access points and our device to support
+ * combinations of modes, so as long as there is one valid combination
+ * of ap/device supported modes, then return success
+ *
+ */
+ if ((mode & IEEE_A) &&
+ (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+ (ieee->freq_band & IEEE80211_52GHZ_BAND))
+ return 1;
+
+ if ((mode & IEEE_G) &&
+ (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+ (ieee->freq_band & IEEE80211_24GHZ_BAND))
+ return 1;
+
+ if ((mode & IEEE_B) &&
+ (ieee->modulation & IEEE80211_CCK_MODULATION) &&
+ (ieee->freq_band & IEEE80211_24GHZ_BAND))
+ return 1;
+
+ return 0;
+}
+
+static inline int ieee80211_get_hdrlen(u16 fc)
+{
+ int hdrlen = IEEE80211_3ADDR_LEN;
+ u16 stype = WLAN_FC_GET_STYPE(fc);
+
+ switch (WLAN_FC_GET_TYPE(fc)) {
+ case IEEE80211_FTYPE_DATA:
+ if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+ hdrlen = IEEE80211_4ADDR_LEN;
+ if (stype & IEEE80211_STYPE_QOS_DATA)
+ hdrlen += 2;
+ break;
+ case IEEE80211_FTYPE_CTL:
+ switch (WLAN_FC_GET_STYPE(fc)) {
+ case IEEE80211_STYPE_CTS:
+ case IEEE80211_STYPE_ACK:
+ hdrlen = IEEE80211_1ADDR_LEN;
+ break;
+ default:
+ hdrlen = IEEE80211_2ADDR_LEN;
+ break;
+ }
+ break;
+ }
+
+ return hdrlen;
+}
+
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+ switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control))) {
+ case IEEE80211_1ADDR_LEN:
+ return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+ case IEEE80211_2ADDR_LEN:
+ return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+ case IEEE80211_3ADDR_LEN:
+ return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+ case IEEE80211_4ADDR_LEN:
+ return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+ }
+ return NULL;
+}
+
+static inline int ieee80211_is_ofdm_rate(u8 rate)
+{
+ switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+ case IEEE80211_OFDM_RATE_6MB:
+ case IEEE80211_OFDM_RATE_9MB:
+ case IEEE80211_OFDM_RATE_12MB:
+ case IEEE80211_OFDM_RATE_18MB:
+ case IEEE80211_OFDM_RATE_24MB:
+ case IEEE80211_OFDM_RATE_36MB:
+ case IEEE80211_OFDM_RATE_48MB:
+ case IEEE80211_OFDM_RATE_54MB:
+ return 1;
+ }
+ return 0;
+}
+
+static inline int ieee80211_is_cck_rate(u8 rate)
+{
+ switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+ case IEEE80211_CCK_RATE_1MB:
+ case IEEE80211_CCK_RATE_2MB:
+ case IEEE80211_CCK_RATE_5MB:
+ case IEEE80211_CCK_RATE_11MB:
+ return 1;
+ }
+ return 0;
+}
+
+/* ieee80211.c */
+extern void free_ieee80211(struct net_device *dev);
+extern struct net_device *alloc_ieee80211(int sizeof_priv);
+extern int ieee80211_change_mtu(struct net_device *dev, int new_mtu);
+
+extern void ieee80211_networks_age(struct ieee80211_device *ieee,
+ unsigned long age_secs);
+
+extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
+
+/* ieee80211_tx.c */
+extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
+extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+/* ieee80211_rx.c */
+extern void ieee80211_rx_any(struct ieee80211_device *ieee,
+ struct sk_buff *skb, struct ieee80211_rx_stats *stats);
+extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+ struct ieee80211_rx_stats *rx_stats);
+/* make sure to set stats->len */
+extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+ struct ieee80211_hdr_4addr *header,
+ struct ieee80211_rx_stats *stats);
+extern void ieee80211_network_reset(struct ieee80211_network *network);
+
+/* ieee80211_geo.c */
+extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device
+ *ieee);
+extern int ieee80211_set_geo(struct ieee80211_device *ieee,
+ const struct ieee80211_geo *geo);
+
+extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee,
+ u8 channel);
+extern int ieee80211_channel_to_index(struct ieee80211_device *ieee,
+ u8 channel);
+extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq);
+extern u8 ieee80211_get_channel_flags(struct ieee80211_device *ieee,
+ u8 channel);
+extern const struct ieee80211_channel *ieee80211_get_channel(struct
+ ieee80211_device
+ *ieee, u8 channel);
+extern u32 ieee80211_channel_to_freq(struct ieee80211_device * ieee,
+ u8 channel);
+
+/* ieee80211_wx.c */
+extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+
+static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+{
+ ieee->scans++;
+}
+
+static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+{
+ return ieee->scans;
+}
+
+#endif /* IEEE80211_H */
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 823c2bf5e31..115b7048750 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1692,7 +1692,13 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
u32 lock;
u32 ord_len = sizeof(lock);
- /* Quite if manually disabled. */
+ /* Age scan list entries found before suspend */
+ if (priv->suspend_time) {
+ ieee80211_networks_age(priv->ieee, priv->suspend_time);
+ priv->suspend_time = 0;
+ }
+
+ /* Quiet if manually disabled. */
if (priv->status & STATUS_RF_KILL_SW) {
IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable "
"switch\n", priv->net_dev->name);
@@ -1910,7 +1916,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
{
#define MAC_ASSOCIATION_READ_DELAY (HZ)
- int ret, len, essid_len;
+ int ret;
+ unsigned int len, essid_len;
char essid[IW_ESSID_MAX_SIZE];
u32 txrate;
u32 chan;
@@ -2384,13 +2391,14 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
#endif
priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
- priv->ieee->stats.rx_errors++;
+ priv->net_dev->stats.rx_errors++;
schedule_reset(priv);
}
static void isr_rx(struct ipw2100_priv *priv, int i,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->net_dev;
struct ipw2100_status *status = &priv->status_queue.drv[i];
struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
@@ -2399,14 +2407,14 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
if (unlikely(status->frame_size > skb_tailroom(packet->skb))) {
IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
" Dropping.\n",
- priv->net_dev->name,
+ dev->name,
status->frame_size, skb_tailroom(packet->skb));
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
return;
}
- if (unlikely(!netif_running(priv->net_dev))) {
- priv->ieee->stats.rx_errors++;
+ if (unlikely(!netif_running(dev))) {
+ dev->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
@@ -2436,10 +2444,10 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
#ifdef IPW2100_RX_DEBUG
IPW_DEBUG_DROP("%s: Non consumed packet:\n",
- priv->net_dev->name);
+ dev->name);
printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
#endif
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
/* ieee80211_rx failed, so it didn't free the SKB */
dev_kfree_skb_any(packet->skb);
@@ -2450,7 +2458,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
if (unlikely(ipw2100_alloc_skb(priv, packet))) {
printk(KERN_WARNING DRV_NAME ": "
"%s: Unable to allocate SKB onto RBD ring - disabling "
- "adapter.\n", priv->net_dev->name);
+ "adapter.\n", dev->name);
/* TODO: schedule adapter shutdown */
IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
}
@@ -2464,6 +2472,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->net_dev;
struct ipw2100_status *status = &priv->status_queue.drv[i];
struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
@@ -2481,15 +2490,15 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
sizeof(struct ipw_rt_hdr))) {
IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
" Dropping.\n",
- priv->net_dev->name,
+ dev->name,
status->frame_size,
skb_tailroom(packet->skb));
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
return;
}
- if (unlikely(!netif_running(priv->net_dev))) {
- priv->ieee->stats.rx_errors++;
+ if (unlikely(!netif_running(dev))) {
+ dev->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
@@ -2498,7 +2507,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
if (unlikely(priv->config & CFG_CRC_CHECK &&
status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
return;
}
@@ -2520,7 +2529,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));
if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
/* ieee80211_rx failed, so it didn't free the SKB */
dev_kfree_skb_any(packet->skb);
@@ -2531,7 +2540,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
if (unlikely(ipw2100_alloc_skb(priv, packet))) {
IPW_DEBUG_WARNING(
"%s: Unable to allocate SKB onto RBD ring - disabling "
- "adapter.\n", priv->net_dev->name);
+ "adapter.\n", dev->name);
/* TODO: schedule adapter shutdown */
IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
}
@@ -3333,7 +3342,7 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
if (!(priv->status & STATUS_ASSOCIATED)) {
IPW_DEBUG_INFO("Can not transmit when not connected.\n");
- priv->ieee->stats.tx_carrier_errors++;
+ priv->net_dev->stats.tx_carrier_errors++;
netif_stop_queue(dev);
goto fail_unlock;
}
@@ -4058,7 +4067,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
u8 bssid[ETH_ALEN];
u32 chan = 0;
char *out = buf;
- int length;
+ unsigned int length;
int ret;
if (priv->status & STATUS_RF_KILL_MASK)
@@ -5829,7 +5838,7 @@ static void ipw2100_tx_timeout(struct net_device *dev)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
- priv->ieee->stats.tx_errors++;
+ dev->stats.tx_errors++;
#ifdef CONFIG_IPW2100_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR)
@@ -5999,6 +6008,17 @@ static void ipw2100_rf_kill(struct work_struct *work)
static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
+static const struct net_device_ops ipw2100_netdev_ops = {
+ .ndo_open = ipw2100_open,
+ .ndo_stop = ipw2100_close,
+ .ndo_start_xmit = ieee80211_xmit,
+ .ndo_change_mtu = ieee80211_change_mtu,
+ .ndo_init = ipw2100_net_init,
+ .ndo_tx_timeout = ipw2100_tx_timeout,
+ .ndo_set_mac_address = ipw2100_set_address,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* Look into using netdev destructor to shutdown ieee80211? */
static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
@@ -6023,15 +6043,11 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
priv->ieee->perfect_rssi = -20;
priv->ieee->worst_rssi = -85;
- dev->open = ipw2100_open;
- dev->stop = ipw2100_close;
- dev->init = ipw2100_net_init;
+ dev->netdev_ops = &ipw2100_netdev_ops;
dev->ethtool_ops = &ipw2100_ethtool_ops;
- dev->tx_timeout = ipw2100_tx_timeout;
dev->wireless_handlers = &ipw2100_wx_handler_def;
priv->wireless_data.ieee80211 = priv->ieee;
dev->wireless_data = &priv->wireless_data;
- dev->set_mac_address = ipw2100_set_address;
dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
@@ -6414,6 +6430,8 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
pci_disable_device(pci_dev);
pci_set_power_state(pci_dev, PCI_D3hot);
+ priv->suspend_at = get_seconds();
+
mutex_unlock(&priv->action_mutex);
return 0;
@@ -6457,6 +6475,8 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
* the queue of needed */
netif_device_attach(dev);
+ priv->suspend_time = get_seconds() - priv->suspend_at;
+
/* Bring the device back up */
if (!(priv->status & STATUS_RF_KILL_SW))
ipw2100_up(priv, 0);
@@ -7122,7 +7142,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
int val;
- int len = sizeof(val);
+ unsigned int len = sizeof(val);
int err = 0;
if (!(priv->status & STATUS_ENABLED) ||
@@ -8297,7 +8317,7 @@ static void ipw2100_wx_event_work(struct work_struct *work)
struct ipw2100_priv *priv =
container_of(work, struct ipw2100_priv, wx_event_work.work);
union iwreq_data wrqu;
- int len = ETH_ALEN;
+ unsigned int len = ETH_ALEN;
if (priv->status & STATUS_STOPPING)
return;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h
index bbf1ddcafba..f183d951cd3 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.h
+++ b/drivers/net/wireless/ipw2x00/ipw2100.h
@@ -39,8 +39,6 @@
#include <linux/wireless.h>
#include <net/iw_handler.h> // new driver API
-#include <net/ieee80211.h>
-
#ifdef CONFIG_IPW2100_MONITOR
#include <net/ieee80211_radiotap.h>
#endif
@@ -48,6 +46,8 @@
#include <linux/workqueue.h>
#include <linux/mutex.h>
+#include "ieee80211.h"
+
struct ipw2100_priv;
struct ipw2100_tx_packet;
struct ipw2100_rx_packet;
@@ -591,6 +591,10 @@ struct ipw2100_priv {
int user_requested_scan;
+ /* Track time in suspend */
+ unsigned long suspend_at;
+ unsigned long suspend_time;
+
u32 interrupts;
int tx_interrupts;
int rx_interrupts;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 625f2cf99fa..b3449948a25 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -301,88 +301,102 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
}
/* 8-bit direct write (low 4K) */
-#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write8(struct ipw_priv *ipw, unsigned long ofs,
+ u8 val)
+{
+ writeb(val, ipw->hw_base + ofs);
+}
/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
#define ipw_write8(ipw, ofs, val) do { \
- IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write8(ipw, ofs, val); \
- } while (0)
+ IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, \
+ __LINE__, (u32)(ofs), (u32)(val)); \
+ _ipw_write8(ipw, ofs, val); \
+} while (0)
/* 16-bit direct write (low 4K) */
-#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write16(struct ipw_priv *ipw, unsigned long ofs,
+ u16 val)
+{
+ writew(val, ipw->hw_base + ofs);
+}
/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write16(ipw, ofs, val) \
- IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write16(ipw, ofs, val)
+#define ipw_write16(ipw, ofs, val) do { \
+ IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, \
+ __LINE__, (u32)(ofs), (u32)(val)); \
+ _ipw_write16(ipw, ofs, val); \
+} while (0)
/* 32-bit direct write (low 4K) */
-#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write32(struct ipw_priv *ipw, unsigned long ofs,
+ u32 val)
+{
+ writel(val, ipw->hw_base + ofs);
+}
/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write32(ipw, ofs, val) \
- IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write32(ipw, ofs, val)
+#define ipw_write32(ipw, ofs, val) do { \
+ IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, \
+ __LINE__, (u32)(ofs), (u32)(val)); \
+ _ipw_write32(ipw, ofs, val); \
+} while (0)
/* 8-bit direct read (low 4K) */
-#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
-
-/* 8-bit direct read (low 4K), with debug wrapper */
-static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u8 _ipw_read8(struct ipw_priv *ipw, unsigned long ofs)
{
- IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
- return _ipw_read8(ipw, ofs);
+ return readb(ipw->hw_base + ofs);
}
/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read8(ipw, ofs) ({ \
+ IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", __FILE__, __LINE__, \
+ (u32)(ofs)); \
+ _ipw_read8(ipw, ofs); \
+})
/* 16-bit direct read (low 4K) */
-#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
-
-/* 16-bit direct read (low 4K), with debug wrapper */
-static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u16 _ipw_read16(struct ipw_priv *ipw, unsigned long ofs)
{
- IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
- return _ipw_read16(ipw, ofs);
+ return readw(ipw->hw_base + ofs);
}
/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read16(ipw, ofs) ({ \
+ IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", __FILE__, __LINE__, \
+ (u32)(ofs)); \
+ _ipw_read16(ipw, ofs); \
+})
/* 32-bit direct read (low 4K) */
-#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
-
-/* 32-bit direct read (low 4K), with debug wrapper */
-static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u32 _ipw_read32(struct ipw_priv *ipw, unsigned long ofs)
{
- IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
- return _ipw_read32(ipw, ofs);
+ return readl(ipw->hw_base + ofs);
}
/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read32(ipw, ofs) ({ \
+ IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", __FILE__, __LINE__, \
+ (u32)(ofs)); \
+ _ipw_read32(ipw, ofs); \
+})
-/* multi-byte read (above 4K), with debug wrapper */
static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
-static inline void __ipw_read_indirect(const char *f, int l,
- struct ipw_priv *a, u32 b, u8 * c, int d)
-{
- IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
- d);
- _ipw_read_indirect(a, b, c, d);
-}
-
/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
-#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
+#define ipw_read_indirect(a, b, c, d) ({ \
+ IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %u bytes\n", __FILE__, \
+ __LINE__, (u32)(b), (u32)(d)); \
+ _ipw_read_indirect(a, b, c, d); \
+})
/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
int num);
-#define ipw_write_indirect(a, b, c, d) \
- IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
- _ipw_write_indirect(a, b, c, d)
+#define ipw_write_indirect(a, b, c, d) do { \
+ IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %u bytes\n", __FILE__, \
+ __LINE__, (u32)(b), (u32)(d)); \
+ _ipw_write_indirect(a, b, c, d); \
+} while (0)
/* 32-bit indirect write (above 4K) */
static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
@@ -7717,22 +7731,23 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
struct ipw_rx_mem_buffer *rxb,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->net_dev;
struct ieee80211_hdr_4addr *hdr;
struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
/* We received data from the HW, so stop the watchdog */
- priv->net_dev->trans_start = jiffies;
+ dev->trans_start = jiffies;
/* We only process data packets if the
* interface is open */
if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
skb_tailroom(rxb->skb))) {
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
return;
} else if (unlikely(!netif_running(priv->net_dev))) {
- priv->ieee->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
@@ -7754,7 +7769,7 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
ipw_rebuild_decrypted_skb(priv, rxb->skb);
if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
else { /* ieee80211_rx succeeded, so it now owns the SKB */
rxb->skb = NULL;
__ipw_led_activity_on(priv);
@@ -7766,6 +7781,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
struct ipw_rx_mem_buffer *rxb,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->net_dev;
struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
struct ipw_rx_frame *frame = &pkt->u.frame;
@@ -7783,18 +7799,18 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
short len = le16_to_cpu(pkt->u.frame.length);
/* We received data from the HW, so stop the watchdog */
- priv->net_dev->trans_start = jiffies;
+ dev->trans_start = jiffies;
/* We only process data packets if the
* interface is open */
if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
skb_tailroom(rxb->skb))) {
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
return;
} else if (unlikely(!netif_running(priv->net_dev))) {
- priv->ieee->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
@@ -7804,7 +7820,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
* that now */
if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
/* FIXME: Should alloc bigger skb instead */
- priv->ieee->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
return;
@@ -7910,7 +7926,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
else { /* ieee80211_rx succeeded, so it now owns the SKB */
rxb->skb = NULL;
/* no LED during capture */
@@ -7942,6 +7958,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
struct ipw_rx_mem_buffer *rxb,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->prom_net_dev;
struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
struct ipw_rx_frame *frame = &pkt->u.frame;
struct ipw_rt_hdr *ipw_rt;
@@ -7964,17 +7981,17 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
return;
/* We received data from the HW, so stop the watchdog */
- priv->prom_net_dev->trans_start = jiffies;
+ dev->trans_start = jiffies;
if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
- priv->prom_priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
return;
}
/* We only process data packets if the interface is open */
- if (unlikely(!netif_running(priv->prom_net_dev))) {
- priv->prom_priv->ieee->stats.rx_dropped++;
+ if (unlikely(!netif_running(dev))) {
+ dev->stats.rx_dropped++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
}
@@ -7983,7 +8000,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
* that now */
if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
/* FIXME: Should alloc bigger skb instead */
- priv->prom_priv->ieee->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
return;
}
@@ -8115,7 +8132,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
if (!ieee80211_rx(priv->prom_priv->ieee, skb, stats)) {
- priv->prom_priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb_any(skb);
}
}
@@ -8272,7 +8289,7 @@ static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
skb_reset_mac_header(skb);
skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_80211_STATS);
+ skb->protocol = cpu_to_be16(ETH_P_80211_STATS);
memset(skb->cb, 0, sizeof(rxb->skb->cb));
netif_rx(skb);
rxb->skb = NULL;
@@ -8399,7 +8416,7 @@ static void ipw_rx(struct ipw_priv *priv)
IPW_DEBUG_DROP
("Received packet is too small. "
"Dropping.\n");
- priv->ieee->stats.rx_errors++;
+ priv->net_dev->stats.rx_errors++;
priv->wstats.discard.misc++;
break;
}
@@ -10470,15 +10487,6 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
return ret;
}
-static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
-{
- struct ipw_priv *priv = ieee80211_priv(dev);
-
- priv->ieee->stats.tx_packets = priv->tx_packets;
- priv->ieee->stats.rx_packets = priv->rx_packets;
- return &priv->ieee->stats;
-}
-
static void ipw_net_set_multicast_list(struct net_device *dev)
{
@@ -11224,6 +11232,12 @@ static int ipw_up(struct ipw_priv *priv)
{
int rc, i, j;
+ /* Age scan list entries found before suspend */
+ if (priv->suspend_time) {
+ ieee80211_networks_age(priv->ieee, priv->suspend_time);
+ priv->suspend_time = 0;
+ }
+
if (priv->status & STATUS_EXIT_PENDING)
return -EIO;
@@ -11515,11 +11529,14 @@ static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return -EOPNOTSUPP;
}
-static struct net_device_stats *ipw_prom_get_stats(struct net_device *dev)
-{
- struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
- return &prom_priv->ieee->stats;
-}
+static const struct net_device_ops ipw_prom_netdev_ops = {
+ .ndo_open = ipw_prom_open,
+ .ndo_stop = ipw_prom_stop,
+ .ndo_start_xmit = ipw_prom_hard_start_xmit,
+ .ndo_change_mtu = ieee80211_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int ipw_prom_alloc(struct ipw_priv *priv)
{
@@ -11540,10 +11557,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
- priv->prom_net_dev->open = ipw_prom_open;
- priv->prom_net_dev->stop = ipw_prom_stop;
- priv->prom_net_dev->get_stats = ipw_prom_get_stats;
- priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit;
+ priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
@@ -11571,6 +11585,17 @@ static void ipw_prom_free(struct ipw_priv *priv)
#endif
+static const struct net_device_ops ipw_netdev_ops = {
+ .ndo_init = ipw_net_init,
+ .ndo_open = ipw_net_open,
+ .ndo_stop = ipw_net_stop,
+ .ndo_set_multicast_list = ipw_net_set_multicast_list,
+ .ndo_set_mac_address = ipw_net_set_mac_address,
+ .ndo_start_xmit = ieee80211_xmit,
+ .ndo_change_mtu = ieee80211_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int __devinit ipw_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -11672,12 +11697,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
priv->ieee->perfect_rssi = -20;
priv->ieee->worst_rssi = -85;
- net_dev->open = ipw_net_open;
- net_dev->stop = ipw_net_stop;
- net_dev->init = ipw_net_init;
- net_dev->get_stats = ipw_net_get_stats;
- net_dev->set_multicast_list = ipw_net_set_multicast_list;
- net_dev->set_mac_address = ipw_net_set_mac_address;
+ net_dev->netdev_ops = &ipw_netdev_ops;
priv->wireless_data.spy_data = &priv->ieee->spy_data;
net_dev->wireless_data = &priv->wireless_data;
net_dev->wireless_handlers = &ipw_wx_handler_def;
@@ -11824,6 +11844,8 @@ static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ priv->suspend_at = get_seconds();
+
return 0;
}
@@ -11859,6 +11881,8 @@ static int ipw_pci_resume(struct pci_dev *pdev)
* the queue of needed */
netif_device_attach(dev);
+ priv->suspend_time = get_seconds() - priv->suspend_at;
+
/* Bring the device back up */
queue_work(priv->workqueue, &priv->up);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h
index 277b274d4be..05e8ccf01c5 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/ipw2x00/ipw2200.h
@@ -49,13 +49,14 @@
#include <asm/io.h>
#include <net/lib80211.h>
-#include <net/ieee80211.h>
#include <net/ieee80211_radiotap.h>
#define DRV_NAME "ipw2200"
#include <linux/workqueue.h>
+#include "ieee80211.h"
+
/* Authentication and Association States */
enum connection_manager_assoc_states {
CMAS_INIT = 0,
@@ -1346,6 +1347,10 @@ struct ipw_priv {
s8 tx_power;
+ /* Track time in suspend */
+ unsigned long suspend_at;
+ unsigned long suspend_time;
+
#ifdef CONFIG_PM
u32 pm_state[16];
#endif
diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c
index 960ad13f5e9..9dfbb8760f6 100644
--- a/drivers/net/wireless/ipw2x00/libipw_geo.c
+++ b/drivers/net/wireless/ipw2x00/libipw_geo.c
@@ -41,7 +41,7 @@
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
-#include <net/ieee80211.h>
+#include "ieee80211.h"
int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
{
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index a2f5616d5b0..92a26922e79 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -50,7 +50,7 @@
#include <net/net_namespace.h>
#include <net/arp.h>
-#include <net/ieee80211.h>
+#include "ieee80211.h"
#define DRV_DESCRIPTION "802.11 data/management/control stack"
#define DRV_NAME "ieee80211"
@@ -105,6 +105,21 @@ static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
ieee->networks = NULL;
}
+void ieee80211_networks_age(struct ieee80211_device *ieee,
+ unsigned long age_secs)
+{
+ struct ieee80211_network *network = NULL;
+ unsigned long flags;
+ unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
+
+ spin_lock_irqsave(&ieee->lock, flags);
+ list_for_each_entry(network, &ieee->network_list, list) {
+ network->last_scanned -= age_jiffies;
+ }
+ spin_unlock_irqrestore(&ieee->lock, flags);
+}
+EXPORT_SYMBOL(ieee80211_networks_age);
+
static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
{
int i;
@@ -116,20 +131,14 @@ static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
&ieee->network_free_list);
}
-static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
+int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN))
return -EINVAL;
dev->mtu = new_mtu;
return 0;
}
-
-static struct net_device_stats *ieee80211_generic_get_stats(
- struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- return &ieee->stats;
-}
+EXPORT_SYMBOL(ieee80211_change_mtu);
struct net_device *alloc_ieee80211(int sizeof_priv)
{
@@ -145,12 +154,10 @@ 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;
-
- /* Drivers are free to override this if the generic implementation
- * does not meet their needs. */
- dev->get_stats = ieee80211_generic_get_stats;
+#endif
ieee->dev = dev;
@@ -206,7 +213,7 @@ void free_ieee80211(struct net_device *dev)
free_netdev(dev);
}
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
static int debug = 0;
u32 ieee80211_debug_level = 0;
@@ -237,11 +244,11 @@ static int store_debug_level(struct file *file, const char __user * buffer,
return strnlen(buf, len);
}
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
static int __init ieee80211_init(void)
{
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
struct proc_dir_entry *e;
ieee80211_debug_level = debug;
@@ -261,7 +268,7 @@ static int __init ieee80211_init(void)
e->read_proc = show_debug_level;
e->write_proc = store_debug_level;
e->data = NULL;
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
@@ -271,20 +278,20 @@ static int __init ieee80211_init(void)
static void __exit ieee80211_exit(void)
{
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
if (ieee80211_proc) {
remove_proc_entry("debug_level", ieee80211_proc);
remove_proc_entry(DRV_NAME, init_net.proc_net);
ieee80211_proc = NULL;
}
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
}
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
#include <linux/moduleparam.h>
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
module_exit(ieee80211_exit);
module_init(ieee80211_init);
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 9c67dfae432..dae4b8e4d8e 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -33,7 +33,8 @@
#include <linux/ctype.h>
#include <net/lib80211.h>
-#include <net/ieee80211.h>
+
+#include "ieee80211.h"
static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
struct sk_buff *skb,
@@ -334,7 +335,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_hdr_4addr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
- struct net_device_stats *stats;
unsigned int frag;
u8 *payload;
u16 ethertype;
@@ -353,8 +353,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
int can_be_decrypted = 0;
hdr = (struct ieee80211_hdr_4addr *)skb->data;
- stats = &ieee->stats;
-
if (skb->len < 10) {
printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
goto rx_dropped;
@@ -411,8 +409,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
#endif
if (ieee->iw_mode == IW_MODE_MONITOR) {
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
ieee80211_monitor_rx(ieee, skb, rx_stats);
return 1;
}
@@ -768,8 +766,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
}
#endif
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
#ifdef NOT_YET
if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
@@ -811,7 +809,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
* in our stats. */
IEEE80211_DEBUG_DROP
("RX: netif_rx dropped the packet\n");
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
}
}
@@ -823,7 +821,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
return 1;
rx_dropped:
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
/* Returning 0 indicates to caller that we have not handled the SKB--
* so it is still allocated and can be used again by underlying
@@ -918,7 +916,7 @@ void ieee80211_rx_any(struct ieee80211_device *ieee,
drop_free:
dev_kfree_skb_irq(skb);
- ieee->stats.rx_dropped++;
+ ieee->dev->stats.rx_dropped++;
return;
}
@@ -1079,37 +1077,37 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
return rc;
}
-#ifdef CONFIG_IEEE80211_DEBUG
-#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
+#ifdef CONFIG_LIBIPW_DEBUG
+#define MFIE_STRING(x) case WLAN_EID_ ##x: return #x
static const char *get_info_element_string(u16 id)
{
switch (id) {
MFIE_STRING(SSID);
- MFIE_STRING(RATES);
- MFIE_STRING(FH_SET);
- MFIE_STRING(DS_SET);
- MFIE_STRING(CF_SET);
+ MFIE_STRING(SUPP_RATES);
+ MFIE_STRING(FH_PARAMS);
+ MFIE_STRING(DS_PARAMS);
+ MFIE_STRING(CF_PARAMS);
MFIE_STRING(TIM);
- MFIE_STRING(IBSS_SET);
+ MFIE_STRING(IBSS_PARAMS);
MFIE_STRING(COUNTRY);
- MFIE_STRING(HOP_PARAMS);
- MFIE_STRING(HOP_TABLE);
+ MFIE_STRING(HP_PARAMS);
+ MFIE_STRING(HP_TABLE);
MFIE_STRING(REQUEST);
MFIE_STRING(CHALLENGE);
- MFIE_STRING(POWER_CONSTRAINT);
- MFIE_STRING(POWER_CAPABILITY);
+ MFIE_STRING(PWR_CONSTRAINT);
+ MFIE_STRING(PWR_CAPABILITY);
MFIE_STRING(TPC_REQUEST);
MFIE_STRING(TPC_REPORT);
- MFIE_STRING(SUPP_CHANNELS);
- MFIE_STRING(CSA);
+ MFIE_STRING(SUPPORTED_CHANNELS);
+ MFIE_STRING(CHANNEL_SWITCH);
MFIE_STRING(MEASURE_REQUEST);
MFIE_STRING(MEASURE_REPORT);
MFIE_STRING(QUIET);
MFIE_STRING(IBSS_DFS);
MFIE_STRING(ERP_INFO);
MFIE_STRING(RSN);
- MFIE_STRING(RATES_EX);
+ MFIE_STRING(EXT_SUPP_RATES);
MFIE_STRING(GENERIC);
MFIE_STRING(QOS_PARAMETER);
default:
@@ -1124,7 +1122,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
{
DECLARE_SSID_BUF(ssid);
u8 i;
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
char rates_str[64];
char *p;
#endif
@@ -1144,7 +1142,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
switch (info_element->id) {
- case MFIE_TYPE_SSID:
+ case WLAN_EID_SSID:
network->ssid_len = min(info_element->len,
(u8) IW_ESSID_MAX_SIZE);
memcpy(network->ssid, info_element->data,
@@ -1153,21 +1151,21 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len);
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
+ IEEE80211_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
network->ssid_len);
break;
- case MFIE_TYPE_RATES:
-#ifdef CONFIG_IEEE80211_DEBUG
+ case WLAN_EID_SUPP_RATES:
+#ifdef CONFIG_LIBIPW_DEBUG
p = rates_str;
#endif
network->rates_len = min(info_element->len,
MAX_RATES_LENGTH);
for (i = 0; i < network->rates_len; i++) {
network->rates[i] = info_element->data[i];
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
p += snprintf(p, sizeof(rates_str) -
(p - rates_str), "%02X ",
network->rates[i]);
@@ -1182,19 +1180,19 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
}
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
+ IEEE80211_DEBUG_MGMT("WLAN_EID_SUPP_RATES: '%s' (%d)\n",
rates_str, network->rates_len);
break;
- case MFIE_TYPE_RATES_EX:
-#ifdef CONFIG_IEEE80211_DEBUG
+ case WLAN_EID_EXT_SUPP_RATES:
+#ifdef CONFIG_LIBIPW_DEBUG
p = rates_str;
#endif
network->rates_ex_len = min(info_element->len,
MAX_RATES_EX_LENGTH);
for (i = 0; i < network->rates_ex_len; i++) {
network->rates_ex[i] = info_element->data[i];
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
p += snprintf(p, sizeof(rates_str) -
(p - rates_str), "%02X ",
network->rates[i]);
@@ -1209,49 +1207,49 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
}
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+ IEEE80211_DEBUG_MGMT("WLAN_EID_EXT_SUPP_RATES: '%s' (%d)\n",
rates_str, network->rates_ex_len);
break;
- case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
+ case WLAN_EID_DS_PARAMS:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_DS_PARAMS: %d\n",
info_element->data[0]);
network->channel = info_element->data[0];
break;
- case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
+ case WLAN_EID_FH_PARAMS:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_FH_PARAMS: ignored\n");
break;
- case MFIE_TYPE_CF_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
+ case WLAN_EID_CF_PARAMS:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_CF_PARAMS: ignored\n");
break;
- case MFIE_TYPE_TIM:
+ case WLAN_EID_TIM:
network->tim.tim_count = info_element->data[0];
network->tim.tim_period = info_element->data[1];
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
+ IEEE80211_DEBUG_MGMT("WLAN_EID_TIM: partially ignored\n");
break;
- case MFIE_TYPE_ERP_INFO:
+ case WLAN_EID_ERP_INFO:
network->erp_value = info_element->data[0];
network->flags |= NETWORK_HAS_ERP_VALUE;
IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
network->erp_value);
break;
- case MFIE_TYPE_IBSS_SET:
+ case WLAN_EID_IBSS_PARAMS:
network->atim_window = info_element->data[0];
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
+ IEEE80211_DEBUG_MGMT("WLAN_EID_IBSS_PARAMS: %d\n",
network->atim_window);
break;
- case MFIE_TYPE_CHALLENGE:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
+ case WLAN_EID_CHALLENGE:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n");
break;
- case MFIE_TYPE_GENERIC:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
+ case WLAN_EID_GENERIC:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_GENERIC: %d bytes\n",
info_element->len);
if (!ieee80211_parse_qos_info_param_IE(info_element,
network))
@@ -1269,8 +1267,8 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
break;
- case MFIE_TYPE_RSN:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
+ case WLAN_EID_RSN:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_RSN: %d bytes\n",
info_element->len);
network->rsn_ie_len = min(info_element->len + 2,
MAX_WPA_IE_LEN);
@@ -1278,22 +1276,22 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->rsn_ie_len);
break;
- case MFIE_TYPE_QOS_PARAMETER:
+ case WLAN_EID_QOS_PARAMETER:
printk(KERN_ERR
"QoS Error need to parse QOS_PARAMETER IE\n");
break;
/* 802.11h */
- case MFIE_TYPE_POWER_CONSTRAINT:
+ case WLAN_EID_PWR_CONSTRAINT:
network->power_constraint = info_element->data[0];
network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
break;
- case MFIE_TYPE_CSA:
+ case WLAN_EID_CHANNEL_SWITCH:
network->power_constraint = info_element->data[0];
network->flags |= NETWORK_HAS_CSA;
break;
- case MFIE_TYPE_QUIET:
+ case WLAN_EID_QUIET:
network->quiet.count = info_element->data[0];
network->quiet.period = info_element->data[1];
network->quiet.duration = info_element->data[2];
@@ -1301,7 +1299,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->flags |= NETWORK_HAS_QUIET;
break;
- case MFIE_TYPE_IBSS_DFS:
+ case WLAN_EID_IBSS_DFS:
if (network->ibss_dfs)
break;
network->ibss_dfs = kmemdup(info_element->data,
@@ -1312,7 +1310,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->flags |= NETWORK_HAS_IBSS_DFS;
break;
- case MFIE_TYPE_TPC_REPORT:
+ case WLAN_EID_TPC_REPORT:
network->tpc_report.transmit_power =
info_element->data[0];
network->tpc_report.link_margin = info_element->data[1];
@@ -1561,7 +1559,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
};
struct ieee80211_network *target;
struct ieee80211_network *oldest = NULL;
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
struct ieee80211_info_element *info_element = beacon->info_element;
#endif
unsigned long flags;
@@ -1615,7 +1613,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
break;
if ((oldest == NULL) ||
- (target->last_scanned < oldest->last_scanned))
+ time_before(target->last_scanned, oldest->last_scanned))
oldest = target;
}
@@ -1639,7 +1637,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
list_del(ieee->network_free_list.next);
}
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
print_ssid(ssid, network.ssid,
network.ssid_len),
diff --git a/drivers/net/wireless/ipw2x00/libipw_tx.c b/drivers/net/wireless/ipw2x00/libipw_tx.c
index f78f57e8844..65a8195b3d9 100644
--- a/drivers/net/wireless/ipw2x00/libipw_tx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_tx.c
@@ -41,7 +41,7 @@
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
-#include <net/ieee80211.h>
+#include "ieee80211.h"
/*
@@ -260,7 +260,6 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
rts_required;
unsigned long flags;
- struct net_device_stats *stats = &ieee->stats;
int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
__be16 ether_type;
int bytes, fc, hdr_len;
@@ -306,7 +305,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
if (!encrypt && ieee->ieee802_1x &&
ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
- stats->tx_dropped++;
+ dev->stats.tx_dropped++;
goto success;
}
@@ -526,8 +525,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
if (txb) {
int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
if (ret == 0) {
- stats->tx_packets++;
- stats->tx_bytes += txb->payload_size;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += txb->payload_size;
return 0;
}
@@ -539,8 +538,9 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
failed:
spin_unlock_irqrestore(&ieee->lock, flags);
netif_stop_queue(dev);
- stats->tx_errors++;
+ dev->stats.tx_errors++;
return 1;
}
+EXPORT_SYMBOL(ieee80211_xmit);
EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c
index 31ea3abfc32..3c0812db030 100644
--- a/drivers/net/wireless/ipw2x00/libipw_wx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_wx.c
@@ -35,13 +35,24 @@
#include <linux/jiffies.h>
#include <net/lib80211.h>
-#include <net/ieee80211.h>
#include <linux/wireless.h>
+#include "ieee80211.h"
+
static const char *ieee80211_modes[] = {
"?", "a", "b", "ab", "g", "ag", "bg", "abg"
};
+static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
+{
+ unsigned long end = jiffies;
+
+ if (end >= start)
+ return jiffies_to_msecs(end - start);
+
+ return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
+}
+
#define MAX_CUSTOM_LEN 64
static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
char *start, char *stop,
@@ -215,8 +226,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = IWEVCUSTOM;
p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %dms ago",
- jiffies_to_msecs(jiffies - network->last_scanned));
+ " Last beacon: %ums ago",
+ elapsed_jiffies_msecs(network->last_scanned));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
@@ -276,15 +287,15 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
time_after(network->last_scanned + ieee->scan_age, jiffies))
ev = ieee80211_translate_scan(ieee, ev, stop, network,
info);
- else
+ else {
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
- "%pM)' due to age (%dms).\n",
+ "%pM)' due to age (%ums).\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
network->bssid,
- jiffies_to_msecs(jiffies -
- network->
- last_scanned));
+ elapsed_jiffies_msecs(
+ network->last_scanned));
+ }
}
spin_unlock_irqrestore(&ieee->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 47bee0ee0a7..8304f6406a1 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,26 +1,29 @@
config IWLWIFI
- tristate
-
-config IWLCORE
- tristate "Intel Wireless Wifi Core"
+ tristate "Intel Wireless Wifi"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
select LIB80211
- select 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
- default n
+ bool "Enable LED support in iwlagn and iwl3945 drivers"
+ depends on IWLWIFI
config IWLWIFI_RFKILL
- boolean "Iwlwifi RF kill support"
- depends on IWLCORE
+ 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
+ ---help---
+ This option will enable spectrum measurement for the iwlagn driver.
config IWLWIFI_DEBUG
- bool "Enable full debugging output in iwlagn driver"
- depends on IWLCORE
+ bool "Enable full debugging output in iwlagn and iwl3945 drivers"
+ depends on IWLWIFI
---help---
This option will enable debug tracing output for the iwlwifi drivers
@@ -44,16 +47,14 @@ config IWLWIFI_DEBUG
any problems you may encounter.
config IWLWIFI_DEBUGFS
- bool "Iwlwifi debugfs support"
- depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
+ bool "iwlagn debugfs support"
+ depends on IWLWIFI && IWLWIFI_DEBUG && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifi drivers.
config IWLAGN
- tristate "Intel Wireless WiFi Next Gen AGN"
- depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
- select FW_LOADER
- select IWLCORE
+ tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)"
+ depends on IWLWIFI
---help---
Select to build the driver supporting the:
@@ -76,19 +77,6 @@ config IWLAGN
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwlagn.ko.
-config IWLAGN_SPECTRUM_MEASUREMENT
- bool "Enable Spectrum Measurement in iwlagn driver"
- depends on IWLAGN
- ---help---
- This option will enable spectrum measurement for the iwlagn driver.
-
-config IWLAGN_LEDS
- bool "Enable LEDS features in iwlagn driver"
- depends on IWLAGN
- select IWLWIFI_LEDS
- ---help---
- This option enables LEDS for the iwlagn drivers
-
config IWL4965
bool "Intel Wireless WiFi 4965AGN"
@@ -97,20 +85,14 @@ config IWL4965
This option enables support for Intel Wireless WiFi Link 4965AGN
config IWL5000
- bool "Intel Wireless WiFi 5000AGN"
+ bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 1000, 6000, and 6050 Series"
depends on IWLAGN
---help---
This option enables support for Intel Wireless WiFi Link 5000AGN Family
config IWL3945
- tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
- depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
- select FW_LOADER
- select LIB80211
- select IWLWIFI
- select MAC80211_LEDS if IWL3945_LEDS
- select LEDS_CLASS if IWL3945_LEDS
- select RFKILL if IWL3945_RFKILL
+ tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
+ depends on IWLWIFI
---help---
Select to build the driver supporting the:
@@ -133,45 +115,8 @@ config IWL3945
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945.ko.
-config IWL3945_RFKILL
- bool "Enable RF kill support in iwl3945 drivers"
- depends on IWL3945
-
config IWL3945_SPECTRUM_MEASUREMENT
- bool "Enable Spectrum Measurement in iwl3945 drivers"
+ bool "Enable Spectrum Measurement in iwl3945 driver"
depends on IWL3945
---help---
This option will enable spectrum measurement for the iwl3945 driver.
-
-config IWL3945_LEDS
- bool "Enable LEDS features in iwl3945 driver"
- depends on IWL3945
- ---help---
- This option enables LEDS for the iwl3945 driver.
-
-config IWL3945_DEBUG
- bool "Enable full debugging output in iwl3945 driver"
- depends on IWL3945
- ---help---
- This option will enable debug tracing output for the iwl3945
- driver.
-
- This will result in the kernel module being ~100k larger. You can
- control which debug output is sent to the kernel log by setting the
- value in
-
- /sys/bus/pci/drivers/${DRIVER}/debug_level
-
- This entry will only exist if this option is enabled.
-
- To set a value, simply echo an 8-byte hex value to the same file:
-
- % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
-
- You can find the list of debug mask values in:
- drivers/net/wireless/iwlwifi/iwl-3945-debug.h
-
- If this is your first time using this driver, you should say Y here
- as the debug information can assist others in helping you resolve
- any problems you may encounter.
-
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 0be9e6b66aa..d79d97ad61a 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,20 +1,21 @@
-obj-$(CONFIG_IWLCORE) += iwlcore.o
+obj-$(CONFIG_IWLWIFI) += iwlcore.o
iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
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_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
+iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
obj-$(CONFIG_IWLAGN) += iwlagn.o
-iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-hcmd-check.o
+iwlagn-objs := iwl-agn.o iwl-agn-rs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
+iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
+iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
obj-$(CONFIG_IWL3945) += iwl3945.o
-iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
-iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
+iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
new file mode 100644
index 00000000000..7da52f1cc1d
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+/* Highest firmware API version supported */
+#define IWL1000_UCODE_API_MAX 2
+
+/* Lowest firmware API version supported */
+#define IWL1000_UCODE_API_MIN 1
+
+#define IWL1000_FW_PRE "iwlwifi-1000-"
+#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
+#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
+
+struct iwl_cfg iwl1000_bgn_cfg = {
+ .name = "1000 Series BGN",
+ .fw_name_pre = IWL1000_FW_PRE,
+ .ucode_api_max = IWL1000_UCODE_API_MAX,
+ .ucode_api_min = IWL1000_UCODE_API_MIN,
+ .sku = IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
+};
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
deleted file mode 100644
index c6f4eb54a2b..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
+++ /dev/null
@@ -1,1702 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-/*
- * Please use this file (iwl-3945-commands.h) only for uCode API definitions.
- * Please use iwl-3945-hw.h for hardware-related definitions.
- * Please use iwl-3945.h for driver implementation definitions.
- */
-
-#ifndef __iwl_3945_commands_h__
-#define __iwl_3945_commands_h__
-
-/* uCode version contains 4 values: Major/Minor/API/Serial */
-#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
-#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
-#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
-#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
-
-enum {
- REPLY_ALIVE = 0x1,
- REPLY_ERROR = 0x2,
-
- /* RXON and QOS commands */
- REPLY_RXON = 0x10,
- REPLY_RXON_ASSOC = 0x11,
- REPLY_QOS_PARAM = 0x13,
- REPLY_RXON_TIMING = 0x14,
-
- /* Multi-Station support */
- REPLY_ADD_STA = 0x18,
- REPLY_REMOVE_STA = 0x19, /* not used */
- REPLY_REMOVE_ALL_STA = 0x1a, /* not used */
-
- /* RX, TX, LEDs */
- REPLY_3945_RX = 0x1b, /* 3945 only */
- REPLY_TX = 0x1c,
- REPLY_RATE_SCALE = 0x47, /* 3945 only */
- REPLY_LEDS_CMD = 0x48,
- REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
-
- /* 802.11h related */
- RADAR_NOTIFICATION = 0x70, /* not used */
- REPLY_QUIET_CMD = 0x71, /* not used */
- REPLY_CHANNEL_SWITCH = 0x72,
- CHANNEL_SWITCH_NOTIFICATION = 0x73,
- REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74,
- SPECTRUM_MEASURE_NOTIFICATION = 0x75,
-
- /* Power Management */
- POWER_TABLE_CMD = 0x77,
- PM_SLEEP_NOTIFICATION = 0x7A,
- PM_DEBUG_STATISTIC_NOTIFIC = 0x7B,
-
- /* Scan commands and notifications */
- REPLY_SCAN_CMD = 0x80,
- REPLY_SCAN_ABORT_CMD = 0x81,
- SCAN_START_NOTIFICATION = 0x82,
- SCAN_RESULTS_NOTIFICATION = 0x83,
- SCAN_COMPLETE_NOTIFICATION = 0x84,
-
- /* IBSS/AP commands */
- BEACON_NOTIFICATION = 0x90,
- REPLY_TX_BEACON = 0x91,
- WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */
-
- /* Miscellaneous commands */
- QUIET_NOTIFICATION = 0x96, /* not used */
- REPLY_TX_PWR_TABLE_CMD = 0x97,
- MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */
-
- /* Bluetooth device coexistence config command */
- REPLY_BT_CONFIG = 0x9b,
-
- /* Statistics */
- REPLY_STATISTICS_CMD = 0x9c,
- STATISTICS_NOTIFICATION = 0x9d,
-
- /* RF-KILL commands and notifications */
- REPLY_CARD_STATE_CMD = 0xa0,
- CARD_STATE_NOTIFICATION = 0xa1,
-
- /* Missed beacons notification */
- MISSED_BEACONS_NOTIFICATION = 0xa2,
-
- REPLY_MAX = 0xff
-};
-
-/******************************************************************************
- * (0)
- * Commonly used structures and definitions:
- * Command header, txpower
- *
- *****************************************************************************/
-
-/* iwl3945_cmd_header flags value */
-#define IWL_CMD_FAILED_MSK 0x40
-
-/**
- * struct iwl3945_cmd_header
- *
- * This header format appears in the beginning of each command sent from the
- * driver, and each response/notification received from uCode.
- */
-struct iwl3945_cmd_header {
- u8 cmd; /* Command ID: REPLY_RXON, etc. */
- u8 flags; /* IWL_CMD_* */
- /*
- * The driver sets up the sequence number to values of its choosing.
- * uCode does not use this value, but passes it back to the driver
- * when sending the response to each driver-originated command, so
- * the driver can match the response to the command. Since the values
- * don't get used by uCode, the driver may set up an arbitrary format.
- *
- * There is one exception: uCode sets bit 15 when it originates
- * the response/notification, i.e. when the response/notification
- * is not a direct response to a command sent by the driver. For
- * example, uCode issues REPLY_3945_RX when it sends a received frame
- * to the driver; it is not a direct response to any driver command.
- *
- * The Linux driver uses the following format:
- *
- * 0:7 index/position within Tx queue
- * 8:13 Tx queue selection
- * 14:14 driver sets this to indicate command is in the 'huge'
- * storage at the end of the command buffers, i.e. scan cmd
- * 15:15 uCode sets this in uCode-originated response/notification
- */
- __le16 sequence;
-
- /* command or response/notification data follows immediately */
- u8 data[0];
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_tx_power
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
- *
- * Each entry contains two values:
- * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained
- * linear value that multiplies the output of the digital signal processor,
- * before being sent to the analog radio.
- * 2) Radio gain. This sets the analog gain of the radio Tx path.
- * It is a coarser setting, and behaves in a logarithmic (dB) fashion.
- *
- * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
- */
-struct iwl3945_tx_power {
- u8 tx_gain; /* gain for analog radio */
- u8 dsp_atten; /* gain for DSP */
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_power_per_rate
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- */
-struct iwl3945_power_per_rate {
- u8 rate; /* plcp */
- struct iwl3945_tx_power tpc;
- u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (0a)
- * Alive and Error Commands & Responses:
- *
- *****************************************************************************/
-
-#define UCODE_VALID_OK cpu_to_le32(0x1)
-#define INITIALIZE_SUBTYPE (9)
-
-/*
- * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "initialize alive" notification once the initialization
- * uCode image has completed its work, and is ready to load the runtime image.
- * This is the *first* "alive" notification that the driver will receive after
- * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- */
-struct iwl3945_init_alive_resp {
- u8 ucode_minor;
- u8 ucode_major;
- __le16 reserved1;
- u8 sw_rev[8];
- u8 ver_type;
- u8 ver_subtype; /* "9" for initialize alive */
- __le16 reserved2;
- __le32 log_event_table_ptr;
- __le32 error_event_table_ptr;
- __le32 timestamp;
- __le32 is_valid;
-} __attribute__ ((packed));
-
-
-/**
- * REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "alive" notification once the runtime image is ready
- * to receive commands from the driver. This is the *second* "alive"
- * notification that the driver will receive after rebooting uCode;
- * this "alive" is indicated by subtype field != 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- *
- * This response includes two pointers to structures within the device's
- * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging:
- *
- * 1) log_event_table_ptr indicates base of the event log. This traces
- * a 256-entry history of uCode execution within a circular buffer.
- *
- * 2) error_event_table_ptr indicates base of the error log. This contains
- * information about any uCode error that occurs.
- *
- * The Linux driver can print both logs to the system log when a uCode error
- * occurs.
- */
-struct iwl3945_alive_resp {
- u8 ucode_minor;
- u8 ucode_major;
- __le16 reserved1;
- u8 sw_rev[8];
- u8 ver_type;
- u8 ver_subtype; /* not "9" for runtime alive */
- __le16 reserved2;
- __le32 log_event_table_ptr; /* SRAM address for event log */
- __le32 error_event_table_ptr; /* SRAM address for error log */
- __le32 timestamp;
- __le32 is_valid;
-} __attribute__ ((packed));
-
-union tsf {
- u8 byte[8];
- __le16 word[4];
- __le32 dw[2];
-};
-
-/*
- * REPLY_ERROR = 0x2 (response only, not a command)
- */
-struct iwl3945_error_resp {
- __le32 error_type;
- u8 cmd_id;
- u8 reserved1;
- __le16 bad_cmd_seq_num;
- __le16 reserved2;
- __le32 error_info;
- union tsf timestamp;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (1)
- * RXON Commands & Responses:
- *
- *****************************************************************************/
-
-/*
- * Rx config defines & structure
- */
-/* rx_config device types */
-enum {
- RXON_DEV_TYPE_AP = 1,
- RXON_DEV_TYPE_ESS = 3,
- RXON_DEV_TYPE_IBSS = 4,
- RXON_DEV_TYPE_SNIFFER = 6,
-};
-
-/* rx_config flags */
-/* band & modulation selection */
-#define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0)
-#define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1)
-/* auto detection enable */
-#define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2)
-/* TGg protection when tx */
-#define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3)
-/* cck short slot & preamble */
-#define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4)
-#define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5)
-/* antenna selection */
-#define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7)
-#define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00)
-#define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
-#define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
-/* radar detection enable */
-#define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12)
-#define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13)
-/* rx response to host with 8-byte TSF
-* (according to ON_AIR deassertion) */
-#define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15)
-
-/* rx_config filter flags */
-/* accept all data frames */
-#define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0)
-/* pass control & management to host */
-#define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1)
-/* accept multi-cast */
-#define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2)
-/* don't decrypt uni-cast frames */
-#define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3)
-/* don't decrypt multi-cast frames */
-#define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4)
-/* STA is associated */
-#define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5)
-/* transfer to host non bssid beacons in associated state */
-#define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6)
-
-/**
- * REPLY_RXON = 0x10 (command, has simple generic response)
- *
- * RXON tunes the radio tuner to a service channel, and sets up a number
- * of parameters that are used primarily for Rx, but also for Tx operations.
- *
- * NOTE: When tuning to a new channel, driver must set the
- * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent
- * info within the device, including the station tables, tx retry
- * rate tables, and txpower tables. Driver must build a new station
- * table and txpower table before transmitting anything on the RXON
- * channel.
- *
- * NOTE: All RXONs wipe clean the internal txpower table. Driver must
- * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
- * regardless of whether RXON_FILTER_ASSOC_MSK is set.
- */
-struct iwl3945_rxon_cmd {
- u8 node_addr[6];
- __le16 reserved1;
- u8 bssid_addr[6];
- __le16 reserved2;
- u8 wlap_bssid_addr[6];
- __le16 reserved3;
- u8 dev_type;
- u8 air_propagation;
- __le16 reserved4;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 assoc_id;
- __le32 flags;
- __le32 filter_flags;
- __le16 channel;
- __le16 reserved5;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl3945_rxon_assoc_cmd {
- __le32 flags;
- __le32 filter_flags;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
- */
-struct iwl3945_rxon_time_cmd {
- union tsf timestamp;
- __le16 beacon_interval;
- __le16 atim_window;
- __le32 beacon_init_val;
- __le16 listen_interval;
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
- */
-struct iwl3945_channel_switch_cmd {
- u8 band;
- u8 expect_beacon;
- __le16 channel;
- __le32 rxon_flags;
- __le32 rxon_filter_flags;
- __le32 switch_time;
- struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-/*
- * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
- */
-struct iwl3945_csa_notification {
- __le16 band;
- __le16 channel;
- __le32 status; /* 0 - OK, 1 - fail */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (2)
- * Quality-of-Service (QOS) Commands & Responses:
- *
- *****************************************************************************/
-
-/**
- * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM
- * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd
- *
- * @cw_min: Contention window, start value in numbers of slots.
- * Should be a power-of-2, minus 1. Device's default is 0x0f.
- * @cw_max: Contention window, max value in numbers of slots.
- * Should be a power-of-2, minus 1. Device's default is 0x3f.
- * @aifsn: Number of slots in Arbitration Interframe Space (before
- * performing random backoff timing prior to Tx). Device default 1.
- * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0.
- *
- * Device will automatically increase contention window by (2*CW) + 1 for each
- * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW
- * value, to cap the CW value.
- */
-struct iwl3945_ac_qos {
- __le16 cw_min;
- __le16 cw_max;
- u8 aifsn;
- u8 reserved1;
- __le16 edca_txop;
-} __attribute__ ((packed));
-
-/* QoS flags defines */
-#define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01)
-#define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02)
-#define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10)
-
-/* Number of Access Categories (AC) (EDCA), queues 0..3 */
-#define AC_NUM 4
-
-/*
- * REPLY_QOS_PARAM = 0x13 (command, has simple generic response)
- *
- * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs
- * 0: Background, 1: Best Effort, 2: Video, 3: Voice.
- */
-struct iwl3945_qosparam_cmd {
- __le32 qos_flags;
- struct iwl3945_ac_qos ac[AC_NUM];
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (3)
- * Add/Modify Stations Commands & Responses:
- *
- *****************************************************************************/
-/*
- * Multi station support
- */
-
-/* Special, dedicated locations within device's station table */
-#define IWL_AP_ID 0
-#define IWL_MULTICAST_ID 1
-#define IWL_STA_ID 2
-#define IWL3945_BROADCAST_ID 24
-#define IWL3945_STATION_COUNT 25
-
-#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
-#define IWL_INVALID_STATION 255
-
-#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2);
-#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
-
-/* Use in mode field. 1: modify existing entry, 0: add new station entry */
-#define STA_CONTROL_MODIFY_MSK 0x01
-
-/* key flags __le16*/
-#define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007)
-#define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000)
-#define STA_KEY_FLG_WEP cpu_to_le16(0x0001)
-#define STA_KEY_FLG_CCMP cpu_to_le16(0x0002)
-#define STA_KEY_FLG_TKIP cpu_to_le16(0x0003)
-
-#define STA_KEY_FLG_KEYID_POS 8
-#define STA_KEY_FLG_INVALID cpu_to_le16(0x0800)
-/* wep key is either from global key (0) or from station info array (1) */
-#define STA_KEY_FLG_WEP_KEY_MAP_MSK cpu_to_le16(0x0008)
-
-/* wep key in STA: 5-bytes (0) or 13-bytes (1) */
-#define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000)
-#define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000)
-
-/* Flags indicate whether to modify vs. don't change various station params */
-#define STA_MODIFY_KEY_MASK 0x01
-#define STA_MODIFY_TID_DISABLE_TX 0x02
-#define STA_MODIFY_TX_RATE_MSK 0x04
-
-/*
- * Antenna masks:
- * bit14:15 01 B inactive, A active
- * 10 B active, A inactive
- * 11 Both active
- */
-#define RATE_MCS_ANT_A_POS 14
-#define RATE_MCS_ANT_B_POS 15
-#define RATE_MCS_ANT_A_MSK 0x4000
-#define RATE_MCS_ANT_B_MSK 0x8000
-#define RATE_MCS_ANT_AB_MSK 0xc000
-
-struct iwl3945_keyinfo {
- __le16 key_flags;
- u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
- u8 reserved1;
- __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
- u8 key_offset;
- u8 reserved2;
- u8 key[16]; /* 16-byte unicast decryption key */
-} __attribute__ ((packed));
-
-/**
- * struct sta_id_modify
- * @addr[ETH_ALEN]: station's MAC address
- * @sta_id: index of station in uCode's station table
- * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change
- *
- * Driver selects unused table index when adding new station,
- * or the index to a pre-existing station entry when modifying that station.
- * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP).
- *
- * modify_mask flags select which parameters to modify vs. leave alone.
- */
-struct sta_id_modify {
- u8 addr[ETH_ALEN];
- __le16 reserved1;
- u8 sta_id;
- u8 modify_mask;
- __le16 reserved2;
-} __attribute__ ((packed));
-
-/*
- * REPLY_ADD_STA = 0x18 (command)
- *
- * The device contains an internal table of per-station information,
- * with info on security keys, aggregation parameters, and Tx rates for
- * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD,
- * 3945 uses REPLY_RATE_SCALE to set up rate tables).
- *
- * REPLY_ADD_STA sets up the table entry for one station, either creating
- * a new entry, or modifying a pre-existing one.
- *
- * NOTE: RXON command (without "associated" bit set) wipes the station table
- * clean. Moving into RF_KILL state does this also. Driver must set up
- * new station table before transmitting anything on the RXON channel
- * (except active scans or active measurements; those commands carry
- * their own txpower/rate setup data).
- *
- * When getting started on a new channel, driver must set up the
- * IWL_BROADCAST_ID entry (last entry in the table). For a client
- * station in a BSS, once an AP is selected, driver sets up the AP STA
- * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP
- * are all that are needed for a BSS client station. If the device is
- * used as AP, or in an IBSS network, driver must set up station table
- * entries for all STAs in network, starting with index IWL_STA_ID.
- */
-struct iwl3945_addsta_cmd {
- u8 mode; /* 1: modify existing, 0: add new station */
- u8 reserved[3];
- struct sta_id_modify sta;
- struct iwl3945_keyinfo key;
- __le32 station_flags; /* STA_FLG_* */
- __le32 station_flags_msk; /* STA_FLG_* */
-
- /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
- * corresponding to bit (e.g. bit 5 controls TID 5).
- * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
- __le16 tid_disable_tx;
-
- __le16 rate_n_flags;
-
- /* TID for which to add block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- u8 add_immediate_ba_tid;
-
- /* TID for which to remove block-ack support.
- * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
- u8 remove_immediate_ba_tid;
-
- /* Starting Sequence Number for added block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- __le16 add_immediate_ba_ssn;
-} __attribute__ ((packed));
-
-#define ADD_STA_SUCCESS_MSK 0x1
-#define ADD_STA_NO_ROOM_IN_TABLE 0x2
-#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4
-/*
- * REPLY_ADD_STA = 0x18 (response)
- */
-struct iwl3945_add_sta_resp {
- u8 status; /* ADD_STA_* */
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (4)
- * Rx Responses:
- *
- *****************************************************************************/
-
-struct iwl3945_rx_frame_stats {
- u8 phy_count;
- u8 id;
- u8 rssi;
- u8 agc;
- __le16 sig_avg;
- __le16 noise_diff;
- u8 payload[0];
-} __attribute__ ((packed));
-
-struct iwl3945_rx_frame_hdr {
- __le16 channel;
- __le16 phy_flags;
- u8 reserved1;
- u8 rate;
- __le16 len;
- u8 payload[0];
-} __attribute__ ((packed));
-
-#define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0)
-#define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1)
-
-#define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0)
-#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
-#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
-#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
-#define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0)
-
-#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
-#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
-#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8)
-#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8)
-#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8)
-
-#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11)
-#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11)
-#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11)
-#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11)
-#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11)
-
-struct iwl3945_rx_frame_end {
- __le32 status;
- __le64 timestamp;
- __le32 beacon_timestamp;
-} __attribute__ ((packed));
-
-/*
- * REPLY_3945_RX = 0x1b (response only, not a command)
- *
- * NOTE: DO NOT dereference from casts to this structure
- * It is provided only for calculating minimum data set size.
- * The actual offsets of the hdr and end are dynamic based on
- * stats.phy_count
- */
-struct iwl3945_rx_frame {
- struct iwl3945_rx_frame_stats stats;
- struct iwl3945_rx_frame_hdr hdr;
- struct iwl3945_rx_frame_end end;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (5)
- * Tx Commands & Responses:
- *
- * Driver must place each REPLY_TX command into one of the prioritized Tx
- * queues in host DRAM, shared between driver and device. When the device's
- * Tx scheduler and uCode are preparing to transmit, the device pulls the
- * Tx command over the PCI bus via one of the device's Tx DMA channels,
- * to fill an internal FIFO from which data will be transmitted.
- *
- * uCode handles all timing and protocol related to control frames
- * (RTS/CTS/ACK), based on flags in the Tx command.
- *
- * uCode handles retrying Tx when an ACK is expected but not received.
- * This includes trying lower data rates than the one requested in the Tx
- * command, as set up by the REPLY_RATE_SCALE (for 3945) or
- * REPLY_TX_LINK_QUALITY_CMD (4965).
- *
- * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
- * This command must be executed after every RXON command, before Tx can occur.
- *****************************************************************************/
-
-/* REPLY_TX Tx flags field */
-
-/* 1: Use Request-To-Send protocol before this frame.
- * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
-#define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1)
-
-/* 1: Transmit Clear-To-Send to self before this frame.
- * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames.
- * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */
-#define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2)
-
-/* 1: Expect ACK from receiving station
- * 0: Don't expect ACK (MAC header's duration field s/b 0)
- * Set this for unicast frames, but not broadcast/multicast. */
-#define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3)
-
-/* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
- * Tx command's initial_rate_index indicates first rate to try;
- * uCode walks through table for additional Tx attempts.
- * 0: Use Tx rate/MCS from Tx command's rate_n_flags field.
- * This rate will be used for all Tx attempts; it will not be scaled. */
-#define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4)
-
-/* 1: Expect immediate block-ack.
- * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */
-#define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6)
-
-/* 1: Frame requires full Tx-Op protection.
- * Set this if either RTS or CTS Tx Flag gets set. */
-#define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7)
-
-/* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
- * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
-#define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00)
-#define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
-#define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
-
-/* 1: Ignore Bluetooth priority for this frame.
- * 0: Delay Tx until Bluetooth device is done (normal usage). */
-#define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12)
-
-/* 1: uCode overrides sequence control field in MAC header.
- * 0: Driver provides sequence control field in MAC header.
- * Set this for management frames, non-QOS data frames, non-unicast frames,
- * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */
-#define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13)
-
-/* 1: This frame is non-last MPDU; more fragments are coming.
- * 0: Last fragment, or not using fragmentation. */
-#define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14)
-
-/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame.
- * 0: No TSF required in outgoing frame.
- * Set this for transmitting beacons and probe responses. */
-#define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16)
-
-/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword
- * alignment of frame's payload data field.
- * 0: No pad
- * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4
- * field (but not both). Driver must align frame data (i.e. data following
- * MAC header) to DWORD boundary. */
-#define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20)
-
-/* HCCA-AP - disable duration overwriting. */
-#define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25)
-
-/*
- * TX command security control
- */
-#define TX_CMD_SEC_WEP 0x01
-#define TX_CMD_SEC_CCM 0x02
-#define TX_CMD_SEC_TKIP 0x03
-#define TX_CMD_SEC_MSK 0x03
-#define TX_CMD_SEC_SHIFT 6
-#define TX_CMD_SEC_KEY128 0x08
-
-/*
- * REPLY_TX = 0x1c (command)
- */
-struct iwl3945_tx_cmd {
- /*
- * MPDU byte count:
- * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
- * + 8 byte IV for CCM or TKIP (not used for WEP)
- * + Data payload
- * + 8-byte MIC (not used for CCM/WEP)
- * NOTE: Does not include Tx command bytes, post-MAC pad bytes,
- * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
- * Range: 14-2342 bytes.
- */
- __le16 len;
-
- /*
- * MPDU or MSDU byte count for next frame.
- * Used for fragmentation and bursting, but not 11n aggregation.
- * Same as "len", but for next frame. Set to 0 if not applicable.
- */
- __le16 next_frame_len;
-
- __le32 tx_flags; /* TX_CMD_FLG_* */
-
- u8 rate;
-
- /* Index of recipient station in uCode's station table */
- u8 sta_id;
- u8 tid_tspec;
- u8 sec_ctl;
- u8 key[16];
- union {
- u8 byte[8];
- __le16 word[4];
- __le32 dw[2];
- } tkip_mic;
- __le32 next_frame_info;
- union {
- __le32 life_time;
- __le32 attempt;
- } stop_time;
- u8 supp_rates[2];
- u8 rts_retry_limit; /*byte 50 */
- u8 data_retry_limit; /*byte 51 */
- union {
- __le16 pm_frame_timeout;
- __le16 attempt_duration;
- } timeout;
-
- /*
- * Duration of EDCA burst Tx Opportunity, in 32-usec units.
- * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
- */
- __le16 driver_txop;
-
- /*
- * MAC header goes here, followed by 2 bytes padding if MAC header
- * length is 26 or 30 bytes, followed by payload data
- */
- u8 payload[0];
- struct ieee80211_hdr hdr[0];
-} __attribute__ ((packed));
-
-/* TX command response is sent after *all* transmission attempts.
- *
- * NOTES:
- *
- * TX_STATUS_FAIL_NEXT_FRAG
- *
- * If the fragment flag in the MAC header for the frame being transmitted
- * is set and there is insufficient time to transmit the next frame, the
- * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
- *
- * TX_STATUS_FIFO_UNDERRUN
- *
- * Indicates the host did not provide bytes to the FIFO fast enough while
- * a TX was in progress.
- *
- * TX_STATUS_FAIL_MGMNT_ABORT
- *
- * This status is only possible if the ABORT ON MGMT RX parameter was
- * set to true with the TX command.
- *
- * If the MSB of the status parameter is set then an abort sequence is
- * required. This sequence consists of the host activating the TX Abort
- * control line, and then waiting for the TX Abort command response. This
- * indicates that a the device is no longer in a transmit state, and that the
- * command FIFO has been cleared. The host must then deactivate the TX Abort
- * control line. Receiving is still allowed in this case.
- */
-enum {
- TX_STATUS_SUCCESS = 0x01,
- TX_STATUS_DIRECT_DONE = 0x02,
- TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
- TX_STATUS_FAIL_LONG_LIMIT = 0x83,
- TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
- TX_STATUS_FAIL_MGMNT_ABORT = 0x85,
- TX_STATUS_FAIL_NEXT_FRAG = 0x86,
- TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
- TX_STATUS_FAIL_DEST_PS = 0x88,
- TX_STATUS_FAIL_ABORTED = 0x89,
- TX_STATUS_FAIL_BT_RETRY = 0x8a,
- TX_STATUS_FAIL_STA_INVALID = 0x8b,
- TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
- TX_STATUS_FAIL_TID_DISABLE = 0x8d,
- TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
- TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
- TX_STATUS_FAIL_TX_LOCKED = 0x90,
- TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
-};
-
-#define TX_PACKET_MODE_REGULAR 0x0000
-#define TX_PACKET_MODE_BURST_SEQ 0x0100
-#define TX_PACKET_MODE_BURST_FIRST 0x0200
-
-enum {
- TX_POWER_PA_NOT_ACTIVE = 0x0,
-};
-
-enum {
- TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */
- TX_STATUS_DELAY_MSK = 0x00000040,
- TX_STATUS_ABORT_MSK = 0x00000080,
- TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */
- TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */
- TX_RESERVED = 0x00780000, /* bits 19:22 */
- TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */
- TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */
-};
-
-/*
- * REPLY_TX = 0x1c (response)
- */
-struct iwl3945_tx_resp {
- u8 failure_rts;
- u8 failure_frame;
- u8 bt_kill_count;
- u8 rate;
- __le32 wireless_media_time;
- __le32 status; /* TX status */
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
- */
-struct iwl3945_txpowertable_cmd {
- u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
- u8 reserved;
- __le16 channel;
- struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-struct iwl3945_rate_scaling_info {
- __le16 rate_n_flags;
- u8 try_cnt;
- u8 next_rate_index;
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
- *
- * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
- *
- * NOTE: The table of rates passed to the uCode via the
- * RATE_SCALE command sets up the corresponding order of
- * rates used for all related commands, including rate
- * masks, etc.
- *
- * For example, if you set 9MB (PLCP 0x0f) as the first
- * rate in the rate table, the bit mask for that rate
- * when passed through ofdm_basic_rates on the REPLY_RXON
- * command would be bit 0 (1 << 0)
- */
-struct iwl3945_rate_scaling_cmd {
- u8 table_id;
- u8 reserved[3];
- struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-/*
- * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
- *
- * 3945 and 4965 support hardware handshake with Bluetooth device on
- * same platform. Bluetooth device alerts wireless device when it will Tx;
- * wireless device can delay or kill its own Tx to accommodate.
- */
-struct iwl3945_bt_cmd {
- u8 flags;
- u8 lead_time;
- u8 max_kill;
- u8 reserved;
- __le32 kill_ack_mask;
- __le32 kill_cts_mask;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (6)
- * Spectrum Management (802.11h) Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/*
- * Spectrum Management
- */
-#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \
- RXON_FILTER_CTL2HOST_MSK | \
- RXON_FILTER_ACCEPT_GRP_MSK | \
- RXON_FILTER_DIS_DECRYPT_MSK | \
- RXON_FILTER_DIS_GRP_DECRYPT_MSK | \
- RXON_FILTER_ASSOC_MSK | \
- RXON_FILTER_BCON_AWARE_MSK)
-
-struct iwl3945_measure_channel {
- __le32 duration; /* measurement duration in extended beacon
- * format */
- u8 channel; /* channel to measure */
- u8 type; /* see enum iwl3945_measure_type */
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
- */
-struct iwl3945_spectrum_cmd {
- __le16 len; /* number of bytes starting from token */
- u8 token; /* token id */
- u8 id; /* measurement id -- 0 or 1 */
- u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */
- u8 periodic; /* 1 = periodic */
- __le16 path_loss_timeout;
- __le32 start_time; /* start time in extended beacon format */
- __le32 reserved2;
- __le32 flags; /* rxon flags */
- __le32 filter_flags; /* rxon filter flags */
- __le16 channel_count; /* minimum 1, maximum 10 */
- __le16 reserved3;
- struct iwl3945_measure_channel channels[10];
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
- */
-struct iwl3945_spectrum_resp {
- u8 token;
- u8 id; /* id of the prior command replaced, or 0xff */
- __le16 status; /* 0 - command will be handled
- * 1 - cannot handle (conflicts with another
- * measurement) */
-} __attribute__ ((packed));
-
-enum iwl3945_measurement_state {
- IWL_MEASUREMENT_START = 0,
- IWL_MEASUREMENT_STOP = 1,
-};
-
-enum iwl3945_measurement_status {
- IWL_MEASUREMENT_OK = 0,
- IWL_MEASUREMENT_CONCURRENT = 1,
- IWL_MEASUREMENT_CSA_CONFLICT = 2,
- IWL_MEASUREMENT_TGH_CONFLICT = 3,
- /* 4-5 reserved */
- IWL_MEASUREMENT_STOPPED = 6,
- IWL_MEASUREMENT_TIMEOUT = 7,
- IWL_MEASUREMENT_PERIODIC_FAILED = 8,
-};
-
-#define NUM_ELEMENTS_IN_HISTOGRAM 8
-
-struct iwl3945_measurement_histogram {
- __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */
- __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */
-} __attribute__ ((packed));
-
-/* clear channel availability counters */
-struct iwl3945_measurement_cca_counters {
- __le32 ofdm;
- __le32 cck;
-} __attribute__ ((packed));
-
-enum iwl3945_measure_type {
- IWL_MEASURE_BASIC = (1 << 0),
- IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
- IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
- IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3),
- IWL_MEASURE_FRAME = (1 << 4),
- /* bits 5:6 are reserved */
- IWL_MEASURE_IDLE = (1 << 7),
-};
-
-/*
- * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
- */
-struct iwl3945_spectrum_notification {
- u8 id; /* measurement id -- 0 or 1 */
- u8 token;
- u8 channel_index; /* index in measurement channel list */
- u8 state; /* 0 - start, 1 - stop */
- __le32 start_time; /* lower 32-bits of TSF */
- u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */
- u8 channel;
- u8 type; /* see enum iwl3945_measurement_type */
- u8 reserved1;
- /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only
- * valid if applicable for measurement type requested. */
- __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */
- __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */
- __le32 cca_time; /* channel load time in usecs */
- u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 -
- * unidentified */
- u8 reserved2[3];
- struct iwl3945_measurement_histogram histogram;
- __le32 stop_time; /* lower 32-bits of TSF */
- __le32 status; /* see iwl3945_measurement_status */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (7)
- * Power Management Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl3945_powertable_cmd - Power Table Command
- * @flags: See below:
- *
- * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
- *
- * PM allow:
- * bit 0 - '0' Driver not allow power management
- * '1' Driver allow PM (use rest of parameters)
- * uCode send sleep notifications:
- * bit 1 - '0' Don't send sleep notification
- * '1' send sleep notification (SEND_PM_NOTIFICATION)
- * Sleep over DTIM
- * bit 2 - '0' PM have to walk up every DTIM
- * '1' PM could sleep over DTIM till listen Interval.
- * PCI power managed
- * bit 3 - '0' (PCI_LINK_CTRL & 0x1)
- * '1' !(PCI_LINK_CTRL & 0x1)
- * Force sleep Modes
- * bit 31/30- '00' use both mac/xtal sleeps
- * '01' force Mac sleep
- * '10' force xtal sleep
- * '11' Illegal set
- *
- * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then
- * ucode assume sleep over DTIM is allowed and we don't need to wakeup
- * for every DTIM.
- */
-#define IWL_POWER_VEC_SIZE 5
-
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le32(1 << 0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le32(1 << 2)
-#define IWL_POWER_PCI_PM_MSK cpu_to_le32(1 << 3)
-struct iwl3945_powertable_cmd {
- __le32 flags;
- __le32 rx_data_timeout;
- __le32 tx_data_timeout;
- __le32 sleep_interval[IWL_POWER_VEC_SIZE];
-} __attribute__((packed));
-
-/*
- * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
- * 3945 and 4965 identical.
- */
-struct iwl3945_sleep_notification {
- u8 pm_sleep_mode;
- u8 pm_wakeup_src;
- __le16 reserved;
- __le32 sleep_time;
- __le32 tsf_low;
- __le32 bcon_timer;
-} __attribute__ ((packed));
-
-/* Sleep states. 3945 and 4965 identical. */
-enum {
- IWL_PM_NO_SLEEP = 0,
- IWL_PM_SLP_MAC = 1,
- IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2,
- IWL_PM_SLP_FULL_MAC_CARD_STATE = 3,
- IWL_PM_SLP_PHY = 4,
- IWL_PM_SLP_REPENT = 5,
- IWL_PM_WAKEUP_BY_TIMER = 6,
- IWL_PM_WAKEUP_BY_DRIVER = 7,
- IWL_PM_WAKEUP_BY_RFKILL = 8,
- /* 3 reserved */
- IWL_PM_NUM_OF_MODES = 12,
-};
-
-/*
- * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response)
- */
-#define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */
-#define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */
-#define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */
-struct iwl3945_card_state_cmd {
- __le32 status; /* CARD_STATE_CMD_* request new power state */
-} __attribute__ ((packed));
-
-/*
- * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
- */
-struct iwl3945_card_state_notif {
- __le32 flags;
-} __attribute__ ((packed));
-
-#define HW_CARD_DISABLED 0x01
-#define SW_CARD_DISABLED 0x02
-#define RF_CARD_DISABLED 0x04
-#define RXON_CARD_DISABLED 0x10
-
-struct iwl3945_ct_kill_config {
- __le32 reserved;
- __le32 critical_temperature_M;
- __le32 critical_temperature_R;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (8)
- * Scan Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl3945_scan_channel - entry in REPLY_SCAN_CMD channel table
- *
- * One for each channel in the scan list.
- * Each channel can independently select:
- * 1) SSID for directed active scans
- * 2) Txpower setting (for rate specified within Tx command)
- * 3) How long to stay on-channel (behavior may be modified by quiet_time,
- * quiet_plcp_th, good_CRC_th)
- *
- * To avoid uCode errors, make sure the following are true (see comments
- * under struct iwl3945_scan_cmd about max_out_time and quiet_time):
- * 1) If using passive_dwell (i.e. passive_dwell != 0):
- * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
- * 2) quiet_time <= active_dwell
- * 3) If restricting off-channel time (i.e. max_out_time !=0):
- * passive_dwell < max_out_time
- * active_dwell < max_out_time
- */
-struct iwl3945_scan_channel {
- /*
- * type is defined as:
- * 0:0 1 = active, 0 = passive
- * 1:4 SSID direct bit map; if a bit is set, then corresponding
- * SSID IE is transmitted in probe request.
- * 5:7 reserved
- */
- u8 type;
- u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */
- struct iwl3945_tx_power tpc;
- __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
- __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_ssid_ie - directed scan network information element
- *
- * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
- * in struct iwl3945_scan_channel; each channel may select different ssids from
- * among the 4 entries. SSID IEs get transmitted in reverse order of entry.
- */
-struct iwl3945_ssid_ie {
- u8 id;
- u8 len;
- u8 ssid[32];
-} __attribute__ ((packed));
-
-#define PROBE_OPTION_MAX 0x4
-#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH cpu_to_le16(1)
-#define IWL_MAX_SCAN_SIZE 1024
-
-/*
- * REPLY_SCAN_CMD = 0x80 (command)
- *
- * The hardware scan command is very powerful; the driver can set it up to
- * maintain (relatively) normal network traffic while doing a scan in the
- * background. The max_out_time and suspend_time control the ratio of how
- * long the device stays on an associated network channel ("service channel")
- * vs. how long it's away from the service channel, tuned to other channels
- * for scanning.
- *
- * max_out_time is the max time off-channel (in usec), and suspend_time
- * is how long (in "extended beacon" format) that the scan is "suspended"
- * after returning to the service channel. That is, suspend_time is the
- * time that we stay on the service channel, doing normal work, between
- * scan segments. The driver may set these parameters differently to support
- * scanning when associated vs. not associated, and light vs. heavy traffic
- * loads when associated.
- *
- * After receiving this command, the device's scan engine does the following;
- *
- * 1) Sends SCAN_START notification to driver
- * 2) Checks to see if it has time to do scan for one channel
- * 3) Sends NULL packet, with power-save (PS) bit set to 1,
- * to tell AP that we're going off-channel
- * 4) Tunes to first channel in scan list, does active or passive scan
- * 5) Sends SCAN_RESULT notification to driver
- * 6) Checks to see if it has time to do scan on *next* channel in list
- * 7) Repeats 4-6 until it no longer has time to scan the next channel
- * before max_out_time expires
- * 8) Returns to service channel
- * 9) Sends NULL packet with PS=0 to tell AP that we're back
- * 10) Stays on service channel until suspend_time expires
- * 11) Repeats entire process 2-10 until list is complete
- * 12) Sends SCAN_COMPLETE notification
- *
- * For fast, efficient scans, the scan command also has support for staying on
- * a channel for just a short time, if doing active scanning and getting no
- * responses to the transmitted probe request. This time is controlled by
- * quiet_time, and the number of received packets below which a channel is
- * considered "quiet" is controlled by quiet_plcp_threshold.
- *
- * For active scanning on channels that have regulatory restrictions against
- * blindly transmitting, the scan can listen before transmitting, to make sure
- * that there is already legitimate activity on the channel. If enough
- * packets are cleanly received on the channel (controlled by good_CRC_th,
- * typical value 1), the scan engine starts transmitting probe requests.
- *
- * Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
- *
- * To avoid uCode errors, see timing restrictions described under
- * struct iwl3945_scan_channel.
- */
-struct iwl3945_scan_cmd {
- __le16 len;
- u8 reserved0;
- u8 channel_count; /* # channels in channel list */
- __le16 quiet_time; /* dwell only this # millisecs on quiet channel
- * (only for active scan) */
- __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */
- __le16 good_CRC_th; /* passive -> active promotion threshold */
- __le16 reserved1;
- __le32 max_out_time; /* max usec to be away from associated (service)
- * channel */
- __le32 suspend_time; /* pause scan this long (in "extended beacon
- * format") when returning to service channel:
- * 3945; 31:24 # beacons, 19:0 additional usec,
- * 4965; 31:22 # beacons, 21:0 additional usec.
- */
- __le32 flags; /* RXON_FLG_* */
- __le32 filter_flags; /* RXON_FILTER_* */
-
- /* For active scans (set to all-0s for passive scans).
- * Does not include payload. Must specify Tx rate; no rate scaling. */
- struct iwl3945_tx_cmd tx_cmd;
-
- /* For directed active scans (set to all-0s otherwise) */
- struct iwl3945_ssid_ie direct_scan[PROBE_OPTION_MAX];
-
- /*
- * Probe request frame, followed by channel list.
- *
- * Size of probe request frame is specified by byte count in tx_cmd.
- * Channel list follows immediately after probe request frame.
- * Number of channels in list is specified by channel_count.
- * Each channel in list is of type:
- *
- * struct iwl3945_scan_channel channels[0];
- *
- * NOTE: Only one band of channels can be scanned per pass. You
- * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
- * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
- * before requesting another scan.
- */
- u8 data[0];
-} __attribute__ ((packed));
-
-/* Can abort will notify by complete notification with abort status. */
-#define CAN_ABORT_STATUS cpu_to_le32(0x1)
-/* complete notification statuses */
-#define ABORT_STATUS 0x2
-
-/*
- * REPLY_SCAN_CMD = 0x80 (response)
- */
-struct iwl3945_scanreq_notification {
- __le32 status; /* 1: okay, 2: cannot fulfill request */
-} __attribute__ ((packed));
-
-/*
- * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
- */
-struct iwl3945_scanstart_notification {
- __le32 tsf_low;
- __le32 tsf_high;
- __le32 beacon_timer;
- u8 channel;
- u8 band;
- u8 reserved[2];
- __le32 status;
-} __attribute__ ((packed));
-
-#define SCAN_OWNER_STATUS 0x1;
-#define MEASURE_OWNER_STATUS 0x2;
-
-#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */
-/*
- * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
- */
-struct iwl3945_scanresults_notification {
- u8 channel;
- u8 band;
- u8 reserved[2];
- __le32 tsf_low;
- __le32 tsf_high;
- __le32 statistics[NUMBER_OF_STATISTICS];
-} __attribute__ ((packed));
-
-/*
- * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
- */
-struct iwl3945_scancomplete_notification {
- u8 scanned_channels;
- u8 status;
- u8 reserved;
- u8 last_channel;
- __le32 tsf_low;
- __le32 tsf_high;
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (9)
- * IBSS/AP Commands and Notifications:
- *
- *****************************************************************************/
-
-/*
- * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
- */
-struct iwl3945_beacon_notif {
- struct iwl3945_tx_resp beacon_notify_hdr;
- __le32 low_tsf;
- __le32 high_tsf;
- __le32 ibss_mgr_status;
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
- */
-struct iwl3945_tx_beacon_cmd {
- struct iwl3945_tx_cmd tx;
- __le16 tim_idx;
- u8 tim_size;
- u8 reserved1;
- struct ieee80211_hdr frame[0]; /* beacon frame */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (10)
- * Statistics Commands and Notifications:
- *
- *****************************************************************************/
-
-#define IWL_TEMP_CONVERT 260
-
-#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
-#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
-#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
-
-/* Used for passing to driver number of successes and failures per rate */
-struct rate_histogram {
- union {
- __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
- __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
- __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
- } success;
- union {
- __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
- __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
- __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
- } failed;
-} __attribute__ ((packed));
-
-/* statistics command response */
-
-struct statistics_rx_phy {
- __le32 ina_cnt;
- __le32 fina_cnt;
- __le32 plcp_err;
- __le32 crc32_err;
- __le32 overrun_err;
- __le32 early_overrun_err;
- __le32 crc32_good;
- __le32 false_alarm_cnt;
- __le32 fina_sync_err_cnt;
- __le32 sfd_timeout;
- __le32 fina_timeout;
- __le32 unresponded_rts;
- __le32 rxe_frame_limit_overrun;
- __le32 sent_ack_cnt;
- __le32 sent_cts_cnt;
-} __attribute__ ((packed));
-
-struct statistics_rx_non_phy {
- __le32 bogus_cts; /* CTS received when not expecting CTS */
- __le32 bogus_ack; /* ACK received when not expecting ACK */
- __le32 non_bssid_frames; /* number of frames with BSSID that
- * doesn't belong to the STA BSSID */
- __le32 filtered_frames; /* count frames that were dumped in the
- * filtering process */
- __le32 non_channel_beacons; /* beacons with our bss id but not on
- * our serving channel */
-} __attribute__ ((packed));
-
-struct statistics_rx {
- struct statistics_rx_phy ofdm;
- struct statistics_rx_phy cck;
- struct statistics_rx_non_phy general;
-} __attribute__ ((packed));
-
-struct statistics_tx {
- __le32 preamble_cnt;
- __le32 rx_detected_cnt;
- __le32 bt_prio_defer_cnt;
- __le32 bt_prio_kill_cnt;
- __le32 few_bytes_cnt;
- __le32 cts_timeout;
- __le32 ack_timeout;
- __le32 expected_ack_cnt;
- __le32 actual_ack_cnt;
-} __attribute__ ((packed));
-
-struct statistics_dbg {
- __le32 burst_check;
- __le32 burst_count;
- __le32 reserved[4];
-} __attribute__ ((packed));
-
-struct statistics_div {
- __le32 tx_on_a;
- __le32 tx_on_b;
- __le32 exec_time;
- __le32 probe_time;
-} __attribute__ ((packed));
-
-struct statistics_general {
- __le32 temperature;
- struct statistics_dbg dbg;
- __le32 sleep_time;
- __le32 slots_out;
- __le32 slots_idle;
- __le32 ttl_timestamp;
- struct statistics_div div;
-} __attribute__ ((packed));
-
-/*
- * REPLY_STATISTICS_CMD = 0x9c,
- * 3945 and 4965 identical.
- *
- * This command triggers an immediate response containing uCode statistics.
- * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
- *
- * If the CLEAR_STATS configuration flag is set, uCode will clear its
- * internal copy of the statistics (counters) after issuing the response.
- * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below).
- *
- * If the DISABLE_NOTIF configuration flag is set, uCode will not issue
- * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag
- * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself.
- */
-#define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */
-#define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */
-struct iwl3945_statistics_cmd {
- __le32 configuration_flags; /* IWL_STATS_CONF_* */
-} __attribute__ ((packed));
-
-/*
- * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
- *
- * By default, uCode issues this notification after receiving a beacon
- * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
- * REPLY_STATISTICS_CMD 0x9c, above.
- *
- * Statistics counters continue to increment beacon after beacon, but are
- * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
- * 0x9c with CLEAR_STATS bit set (see above).
- *
- * uCode also issues this notification during scans. uCode clears statistics
- * appropriately so that each notification contains statistics for only the
- * one channel that has just been scanned.
- */
-#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
-#define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8)
-struct iwl3945_notif_statistics {
- __le32 flag;
- struct statistics_rx rx;
- struct statistics_tx tx;
- struct statistics_general general;
-} __attribute__ ((packed));
-
-
-/*
- * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
- */
-/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
- * then this notification will be sent. */
-#define CONSECUTIVE_MISSED_BCONS_TH 20
-
-struct iwl3945_missed_beacon_notif {
- __le32 consequtive_missed_beacons;
- __le32 total_missed_becons;
- __le32 num_expected_beacons;
- __le32 num_recvd_beacons;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (11)
- * Rx Calibration Commands:
- *
- *****************************************************************************/
-
-#define PHY_CALIBRATE_DIFF_GAIN_CMD (7)
-#define HD_TABLE_SIZE (11)
-
-struct iwl3945_sensitivity_cmd {
- __le16 control;
- __le16 table[HD_TABLE_SIZE];
-} __attribute__ ((packed));
-
-struct iwl3945_calibration_cmd {
- u8 opCode;
- u8 flags;
- __le16 reserved;
- s8 diff_gain_a;
- s8 diff_gain_b;
- s8 diff_gain_c;
- u8 reserved1;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (12)
- * Miscellaneous Commands:
- *
- *****************************************************************************/
-
-/*
- * LEDs Command & Response
- * REPLY_LEDS_CMD = 0x48 (command, has simple generic response)
- *
- * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
- * this command turns it on or off, or sets up a periodic blinking cycle.
- */
-struct iwl3945_led_cmd {
- __le32 interval; /* "interval" in uSec */
- u8 id; /* 1: Activity, 2: Link, 3: Tech */
- u8 off; /* # intervals off while blinking;
- * "0", with >0 "on" value, turns LED on */
- u8 on; /* # intervals on while blinking;
- * "0", regardless of "off", turns LED off */
- u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (13)
- * Union of all expected notifications/responses:
- *
- *****************************************************************************/
-
-struct iwl3945_rx_packet {
- __le32 len;
- struct iwl3945_cmd_header hdr;
- union {
- struct iwl3945_alive_resp alive_frame;
- struct iwl3945_rx_frame rx_frame;
- struct iwl3945_tx_resp tx_resp;
- struct iwl3945_spectrum_notification spectrum_notif;
- struct iwl3945_csa_notification csa_notif;
- struct iwl3945_error_resp err_resp;
- struct iwl3945_card_state_notif card_state_notif;
- struct iwl3945_beacon_notif beacon_status;
- struct iwl3945_add_sta_resp add_sta;
- struct iwl3945_sleep_notification sleep_notif;
- struct iwl3945_spectrum_resp spectrum;
- struct iwl3945_notif_statistics stats;
- __le32 status;
- u8 raw[0];
- } u;
-} __attribute__ ((packed));
-
-#define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
-
-#endif /* __iwl3945_3945_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
deleted file mode 100644
index 85eb778f9df..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl3945_debug_h__
-#define __iwl3945_debug_h__
-
-#ifdef CONFIG_IWL3945_DEBUG
-extern u32 iwl3945_debug_level;
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (iwl3945_debug_level & (level)) \
- printk(KERN_ERR DRV_NAME": %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \
- printk(KERN_ERR DRV_NAME": %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-
-static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
- if (!(iwl3945_debug_level & level))
- return;
-
- print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
- p, len, 1);
-}
-#else
-static inline void IWL_DEBUG(int level, const char *fmt, ...)
-{
-}
-static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
-{
-}
-static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
-}
-#endif /* CONFIG_IWL3945_DEBUG */
-
-
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IWL_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry. xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IWL_xxxx_DEBUG() macro definition for your
- * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/iwl/debug_level
- *
- * you simply need to add your entry to the iwl3945_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/iwl then you do not have
- * CONFIG_IWL3945_DEBUG defined in your kernel configuration
- *
- */
-
-#define IWL_DL_INFO (1 << 0)
-#define IWL_DL_MAC80211 (1 << 1)
-#define IWL_DL_HOST_COMMAND (1 << 2)
-#define IWL_DL_STATE (1 << 3)
-
-#define IWL_DL_RADIO (1 << 7)
-#define IWL_DL_POWER (1 << 8)
-#define IWL_DL_TEMP (1 << 9)
-
-#define IWL_DL_NOTIF (1 << 10)
-#define IWL_DL_SCAN (1 << 11)
-#define IWL_DL_ASSOC (1 << 12)
-#define IWL_DL_DROP (1 << 13)
-
-#define IWL_DL_TXPOWER (1 << 14)
-
-#define IWL_DL_AP (1 << 15)
-
-#define IWL_DL_FW (1 << 16)
-#define IWL_DL_RF_KILL (1 << 17)
-#define IWL_DL_FW_ERRORS (1 << 18)
-
-#define IWL_DL_LED (1 << 19)
-
-#define IWL_DL_RATE (1 << 20)
-
-#define IWL_DL_CALIB (1 << 21)
-#define IWL_DL_WEP (1 << 22)
-#define IWL_DL_TX (1 << 23)
-#define IWL_DL_RX (1 << 24)
-#define IWL_DL_ISR (1 << 25)
-#define IWL_DL_HT (1 << 26)
-#define IWL_DL_IO (1 << 27)
-#define IWL_DL_11H (1 << 28)
-
-#define IWL_DL_STATS (1 << 29)
-#define IWL_DL_TX_REPLY (1 << 30)
-#define IWL_DL_QOS (1 << 31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a)
-
-#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a)
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
new file mode 100644
index 00000000000..08ce259a0e6
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __iwl_3945_fh_h__
+#define __iwl_3945_fh_h__
+
+/************************************/
+/* iwl3945 Flow Handler Definitions */
+/************************************/
+
+/**
+ * This I/O area is directly read/writable by driver (e.g. Linux uses writel())
+ * Addresses are offsets from device's PCI hardware base address.
+ */
+#define FH39_MEM_LOWER_BOUND (0x0800)
+#define FH39_MEM_UPPER_BOUND (0x1000)
+
+#define FH39_CBCC_TABLE (FH39_MEM_LOWER_BOUND + 0x140)
+#define FH39_TFDB_TABLE (FH39_MEM_LOWER_BOUND + 0x180)
+#define FH39_RCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x400)
+#define FH39_RSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x4c0)
+#define FH39_TCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x500)
+#define FH39_TSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x680)
+
+/* TFDB (Transmit Frame Buffer Descriptor) */
+#define FH39_TFDB(_ch, buf) (FH39_TFDB_TABLE + \
+ ((_ch) * 2 + (buf)) * 0x28)
+#define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch) (FH39_TFDB_TABLE + 0x50 * (_ch))
+
+/* CBCC channel is [0,2] */
+#define FH39_CBCC(_ch) (FH39_CBCC_TABLE + (_ch) * 0x8)
+#define FH39_CBCC_CTRL(_ch) (FH39_CBCC(_ch) + 0x00)
+#define FH39_CBCC_BASE(_ch) (FH39_CBCC(_ch) + 0x04)
+
+/* RCSR channel is [0,2] */
+#define FH39_RCSR(_ch) (FH39_RCSR_TABLE + (_ch) * 0x40)
+#define FH39_RCSR_CONFIG(_ch) (FH39_RCSR(_ch) + 0x00)
+#define FH39_RCSR_RBD_BASE(_ch) (FH39_RCSR(_ch) + 0x04)
+#define FH39_RCSR_WPTR(_ch) (FH39_RCSR(_ch) + 0x20)
+#define FH39_RCSR_RPTR_ADDR(_ch) (FH39_RCSR(_ch) + 0x24)
+
+#define FH39_RSCSR_CHNL0_WPTR (FH39_RCSR_WPTR(0))
+
+/* RSSR */
+#define FH39_RSSR_CTRL (FH39_RSSR_TABLE + 0x000)
+#define FH39_RSSR_STATUS (FH39_RSSR_TABLE + 0x004)
+
+/* TCSR */
+#define FH39_TCSR(_ch) (FH39_TCSR_TABLE + (_ch) * 0x20)
+#define FH39_TCSR_CONFIG(_ch) (FH39_TCSR(_ch) + 0x00)
+#define FH39_TCSR_CREDIT(_ch) (FH39_TCSR(_ch) + 0x04)
+#define FH39_TCSR_BUFF_STTS(_ch) (FH39_TCSR(_ch) + 0x08)
+
+/* TSSR */
+#define FH39_TSSR_CBB_BASE (FH39_TSSR_TABLE + 0x000)
+#define FH39_TSSR_MSG_CONFIG (FH39_TSSR_TABLE + 0x008)
+#define FH39_TSSR_TX_STATUS (FH39_TSSR_TABLE + 0x010)
+
+
+/* DBM */
+
+#define FH39_SRVC_CHNL (6)
+
+#define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20)
+#define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4)
+
+#define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000)
+
+#define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000)
+
+#define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005)
+
+#define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) (BIT(_ch) << 24)
+#define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch) (BIT(_ch) << 16)
+
+#define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \
+ (FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \
+ FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch))
+
+#define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
+
+struct iwl3945_tfd_tb {
+ __le32 addr;
+ __le32 len;
+} __attribute__ ((packed));
+
+struct iwl3945_tfd {
+ __le32 control_flags;
+ struct iwl3945_tfd_tb tbs[4];
+ u8 __pad[28];
+} __attribute__ ((packed));
+
+
+#endif /* __iwl_3945_fh_h__ */
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 94ea0e60c41..205603d082a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,77 +69,26 @@
#ifndef __iwl_3945_hw__
#define __iwl_3945_hw__
+#include "iwl-eeprom.h"
+
/*
* uCode queue management definitions ...
* Queue #4 is the command queue for 3945 and 4965.
*/
-#define IWL_CMD_QUEUE_NUM 4
-
-/* Tx rates */
-#define IWL_CCK_RATES 4
-#define IWL_OFDM_RATES 8
-#define IWL_HT_RATES 0
-#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
+#define IWL_CMD_QUEUE_NUM 4
/* Time constants */
#define SHORT_SLOT_TIME 9
#define LONG_SLOT_TIME 20
/* RSSI to dBm */
-#define IWL_RSSI_OFFSET 95
+#define IWL39_RSSI_OFFSET 95
/*
* EEPROM related constants, enums, and structures.
*/
-
-/*
- * EEPROM access time values:
- *
- * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
- * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
- * CSR_EEPROM_REG_BIT_CMD (0x2).
- * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
- * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
- * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
- */
-#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
-
-/*
- * Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags.
- *
- * IBSS and/or AP operation is allowed *only* on those channels with
- * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because
- * RADAR detection is not supported by the 3945 driver, but is a
- * requirement for establishing a new network for legal operation on channels
- * requiring RADAR detection or restricting ACTIVE scanning.
- *
- * NOTE: "WIDE" flag indicates that 20 MHz channel is supported;
- * 3945 does not support FAT 40 MHz-wide channels.
- *
- * NOTE: Using a channel inappropriately will result in a uCode error!
- */
-enum {
- EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */
- EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */
- /* Bit 2 Reserved */
- EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */
- EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */
- EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */
- /* Bit 6 Reserved (was Narrow Channel) */
- EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */
-};
-
-/* SKU Capabilities */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7)
-/* *regulatory* channel data from eeprom, one for each channel */
-struct iwl3945_eeprom_channel {
- u8 flags; /* flags copied from EEPROM */
- s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
-} __attribute__ ((packed));
-
/*
* Mapping of a Tx power level, at factory calibration temperature,
* to a radio/DSP gain table index.
@@ -233,7 +182,7 @@ struct iwl3945_eeprom {
* 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
*/
u16 band_1_count; /* abs.ofs: 196 */
- struct iwl3945_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */
+ struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */
/*
* 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
@@ -241,28 +190,28 @@ struct iwl3945_eeprom {
* (4915-5080MHz) (none of these is ever supported)
*/
u16 band_2_count; /* abs.ofs: 226 */
- struct iwl3945_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
+ struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
/*
* 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
* (5170-5320MHz)
*/
u16 band_3_count; /* abs.ofs: 254 */
- struct iwl3945_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
+ struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
/*
* 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
* (5500-5700MHz)
*/
u16 band_4_count; /* abs.ofs: 280 */
- struct iwl3945_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
+ struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
/*
* 5.7 GHz channels 145, 149, 153, 157, 161, 165
* (5725-5825MHz)
*/
u16 band_5_count; /* abs.ofs: 304 */
- struct iwl3945_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
+ struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
u8 reserved9[194];
@@ -276,125 +225,15 @@ struct iwl3945_eeprom {
u8 reserved16[172]; /* fill out to full 1024 byte block */
} __attribute__ ((packed));
-#define IWL_EEPROM_IMAGE_SIZE 1024
+#define IWL3945_EEPROM_IMG_SIZE 1024
/* End of EEPROM */
-
-#include "iwl-3945-commands.h"
-
-#define PCI_LINK_CTRL 0x0F0
-#define PCI_POWER_SOURCE 0x0C8
-#define PCI_REG_WUM8 0x0E8
-#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
-
-/*=== FH (data Flow Handler) ===*/
-#define FH_BASE (0x800)
-
-#define FH_CBCC_TABLE (FH_BASE+0x140)
-#define FH_TFDB_TABLE (FH_BASE+0x180)
-#define FH_RCSR_TABLE (FH_BASE+0x400)
-#define FH_RSSR_TABLE (FH_BASE+0x4c0)
-#define FH_TCSR_TABLE (FH_BASE+0x500)
-#define FH_TSSR_TABLE (FH_BASE+0x680)
-
-/* TFDB (Transmit Frame Buffer Descriptor) */
-#define FH_TFDB(_channel, buf) \
- (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28)
-#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \
- (FH_TFDB_TABLE + 0x50 * _channel)
-/* CBCC _channel is [0,2] */
-#define FH_CBCC(_channel) (FH_CBCC_TABLE+(_channel)*0x8)
-#define FH_CBCC_CTRL(_channel) (FH_CBCC(_channel)+0x00)
-#define FH_CBCC_BASE(_channel) (FH_CBCC(_channel)+0x04)
-
-/* RCSR _channel is [0,2] */
-#define FH_RCSR(_channel) (FH_RCSR_TABLE+(_channel)*0x40)
-#define FH_RCSR_CONFIG(_channel) (FH_RCSR(_channel)+0x00)
-#define FH_RCSR_RBD_BASE(_channel) (FH_RCSR(_channel)+0x04)
-#define FH_RCSR_WPTR(_channel) (FH_RCSR(_channel)+0x20)
-#define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24)
-
-#define FH_RSCSR_CHNL0_WPTR (FH_RCSR_WPTR(0))
-
-/* RSSR */
-#define FH_RSSR_CTRL (FH_RSSR_TABLE+0x000)
-#define FH_RSSR_STATUS (FH_RSSR_TABLE+0x004)
-#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
-/* TCSR */
-#define FH_TCSR(_channel) (FH_TCSR_TABLE+(_channel)*0x20)
-#define FH_TCSR_CONFIG(_channel) (FH_TCSR(_channel)+0x00)
-#define FH_TCSR_CREDIT(_channel) (FH_TCSR(_channel)+0x04)
-#define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08)
-/* TSSR */
-#define FH_TSSR_CBB_BASE (FH_TSSR_TABLE+0x000)
-#define FH_TSSR_MSG_CONFIG (FH_TSSR_TABLE+0x008)
-#define FH_TSSR_TX_STATUS (FH_TSSR_TABLE+0x010)
-
-
-/* DBM */
-
-#define ALM_FH_SRVC_CHNL (6)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20)
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005)
-
-#define ALM_TB_MAX_BYTES_COUNT (0xFFF0)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \
- ((1LU << _channel) << 24)
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \
- ((1LU << _channel) << 16)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \
- (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \
- ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel))
#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */
#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */
#define TFD_QUEUE_MIN 0
#define TFD_QUEUE_MAX 6
-#define TFD_QUEUE_SIZE_MAX (256)
#define IWL_NUM_SCAN_RATES (2)
@@ -416,12 +255,6 @@ struct iwl3945_eeprom {
#define TFD_CTL_PAD_SET(n) (n << 28)
#define TFD_CTL_PAD_GET(ctl) (ctl >> 28)
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
- sizeof(struct iwl3945_cmd_meta))
-
/*
* RX related structures and functions
*/
@@ -430,45 +263,35 @@ struct iwl3945_eeprom {
/* Sizes and addresses for instruction and data memory (SRAM) in
* 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */
-#define RTC_INST_LOWER_BOUND (0x000000)
-#define ALM_RTC_INST_UPPER_BOUND (0x014000)
+#define IWL39_RTC_INST_LOWER_BOUND (0x000000)
+#define IWL39_RTC_INST_UPPER_BOUND (0x014000)
-#define RTC_DATA_LOWER_BOUND (0x800000)
-#define ALM_RTC_DATA_UPPER_BOUND (0x808000)
+#define IWL39_RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL39_RTC_DATA_UPPER_BOUND (0x808000)
-#define ALM_RTC_INST_SIZE (ALM_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define ALM_RTC_DATA_SIZE (ALM_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \
+ IWL39_RTC_INST_LOWER_BOUND)
+#define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \
+ IWL39_RTC_DATA_LOWER_BOUND)
-#define IWL_MAX_INST_SIZE ALM_RTC_INST_SIZE
-#define IWL_MAX_DATA_SIZE ALM_RTC_DATA_SIZE
+#define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE
+#define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE
/* Size of uCode instruction memory in bootstrap state machine */
-#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE
+#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE
#define IWL39_MAX_NUM_QUEUES 8
static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
- (addr < ALM_RTC_DATA_UPPER_BOUND);
+ return (addr >= IWL39_RTC_DATA_LOWER_BOUND) &&
+ (addr < IWL39_RTC_DATA_UPPER_BOUND);
}
/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE
* and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */
struct iwl3945_shared {
__le32 tx_base_ptr[8];
- __le32 rx_read_ptr[3];
-} __attribute__ ((packed));
-
-struct iwl3945_tfd_frame_data {
- __le32 addr;
- __le32 len;
-} __attribute__ ((packed));
-
-struct iwl3945_tfd_frame {
- __le32 control_flags;
- struct iwl3945_tfd_frame_data pa[4];
- u8 reserved[28];
} __attribute__ ((packed));
static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
deleted file mode 100644
index 2440fd664dd..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl3945_io_h__
-#define __iwl3945_io_h__
-
-#include <linux/io.h>
-
-#include "iwl-3945-debug.h"
-
-/*
- * IO, register, and NIC memory access functions
- *
- * NOTE on naming convention and macro usage for these
- *
- * A single _ prefix before a an access function means that no state
- * check or debug information is printed when that function is called.
- *
- * A double __ prefix before an access function means that state is checked
- * and the current line number is printed in addition to any other debug output.
- *
- * The non-prefixed name is the #define that maps the caller into a
- * #define that provides the caller's __LINE__ to the double prefix version.
- *
- * If you wish to call the function without any debug or state checking,
- * you should use the single _ prefix version (as is used by dependent IO
- * routines, for example _iwl3945_read_direct32 calls the non-check version of
- * _iwl3945_read32.)
- *
- * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguration of the hardware I/O. In combination with
- * git-bisect and the IO debug level you can quickly determine the specific
- * commit which breaks the IO sequence to the hardware.
- *
- */
-
-#define _iwl3945_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv,
- u32 ofs, u32 val)
-{
- IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
- _iwl3945_write32(priv, ofs, val);
-}
-#define iwl3945_write32(priv, ofs, val) \
- __iwl3945_write32(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val)
-#endif
-
-#define _iwl3945_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs)
-{
- IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
- return _iwl3945_read32(priv, ofs);
-}
-#define iwl3945_read32(priv, ofs)__iwl3945_read32(__FILE__, __LINE__, priv, ofs)
-#else
-#define iwl3945_read32(p, o) _iwl3945_read32(p, o)
-#endif
-
-static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int i = 0;
-
- do {
- if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask))
- return i;
- udelay(10);
- i += 10;
- } while (i < timeout);
-
- return -ETIMEDOUT;
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_poll_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout);
- IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
- addr, bits, mask,
- unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
- return ret;
-}
-#define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \
- __iwl3945_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
-#else
-#define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t)
-#endif
-
-static inline void _iwl3945_set_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) | mask);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read32(priv, reg) | mask;
- IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl3945_write32(priv, reg, val);
-}
-#define iwl3945_set_bit(p, r, m) __iwl3945_set_bit(__FILE__, __LINE__, p, r, m)
-#else
-#define iwl3945_set_bit(p, r, m) _iwl3945_set_bit(p, r, m)
-#endif
-
-static inline void _iwl3945_clear_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) & ~mask);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_clear_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read32(priv, reg) & ~mask;
- IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl3945_write32(priv, reg, val);
-}
-#define iwl3945_clear_bit(p, r, m) __iwl3945_clear_bit(__FILE__, __LINE__, p, r, m)
-#else
-#define iwl3945_clear_bit(p, r, m) _iwl3945_clear_bit(p, r, m)
-#endif
-
-static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv)
-{
- int ret;
-#ifdef CONFIG_IWL3945_DEBUG
- if (atomic_read(&priv->restrict_refcnt))
- return 0;
-#endif
- /* this bit wakes up the NIC */
- _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
- (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
- CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
- if (ret < 0) {
- IWL_ERROR("MAC is in deep sleep!\n");
- return -EIO;
- }
-
-#ifdef CONFIG_IWL3945_DEBUG
- atomic_inc(&priv->restrict_refcnt);
-#endif
- return 0;
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_grab_nic_access(const char *f, u32 l,
- struct iwl3945_priv *priv)
-{
- if (atomic_read(&priv->restrict_refcnt))
- IWL_DEBUG_INFO("Grabbing access while already held at "
- "line %d.\n", l);
-
- IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
- return _iwl3945_grab_nic_access(priv);
-}
-#define iwl3945_grab_nic_access(priv) \
- __iwl3945_grab_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl3945_grab_nic_access(priv) \
- _iwl3945_grab_nic_access(priv)
-#endif
-
-static inline void _iwl3945_release_nic_access(struct iwl3945_priv *priv)
-{
-#ifdef CONFIG_IWL3945_DEBUG
- if (atomic_dec_and_test(&priv->restrict_refcnt))
-#endif
- _iwl3945_clear_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_release_nic_access(const char *f, u32 l,
- struct iwl3945_priv *priv)
-{
- if (atomic_read(&priv->restrict_refcnt) <= 0)
- IWL_ERROR("Release unheld nic access at line %d.\n", l);
-
- IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
- _iwl3945_release_nic_access(priv);
-}
-#define iwl3945_release_nic_access(priv) \
- __iwl3945_release_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl3945_release_nic_access(priv) \
- _iwl3945_release_nic_access(priv)
-#endif
-
-static inline u32 _iwl3945_read_direct32(struct iwl3945_priv *priv, u32 reg)
-{
- return _iwl3945_read32(priv, reg);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read_direct32(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg)
-{
- u32 value = _iwl3945_read_direct32(priv, reg);
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s %d\n", f, l);
- IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
- f, l);
- return value;
-}
-#define iwl3945_read_direct32(priv, reg) \
- __iwl3945_read_direct32(__FILE__, __LINE__, priv, reg)
-#else
-#define iwl3945_read_direct32 _iwl3945_read_direct32
-#endif
-
-static inline void _iwl3945_write_direct32(struct iwl3945_priv *priv,
- u32 reg, u32 value)
-{
- _iwl3945_write32(priv, reg, value);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static void __iwl3945_write_direct32(u32 line,
- struct iwl3945_priv *priv, u32 reg, u32 value)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- _iwl3945_write_direct32(priv, reg, value);
-}
-#define iwl3945_write_direct32(priv, reg, value) \
- __iwl3945_write_direct32(__LINE__, priv, reg, value)
-#else
-#define iwl3945_write_direct32 _iwl3945_write_direct32
-#endif
-
-static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv,
- u32 reg, u32 len, u32 *values)
-{
- u32 count = sizeof(u32);
-
- if ((priv != NULL) && (values != NULL)) {
- for (; 0 < len; len -= count, reg += count, values++)
- _iwl3945_write_direct32(priv, reg, *values);
- }
-}
-
-static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv,
- u32 addr, u32 mask, int timeout)
-{
- return _iwl3945_poll_bit(priv, addr, mask, mask, timeout);
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_poll_direct_bit(const char *f, u32 l,
- struct iwl3945_priv *priv,
- u32 addr, u32 mask, int timeout)
-{
- int ret = _iwl3945_poll_direct_bit(priv, addr, mask, timeout);
-
- if (unlikely(ret == -ETIMEDOUT))
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
- "timedout - %s %d\n", addr, mask, f, l);
- else
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
- "- %s %d\n", addr, mask, ret, f, l);
- return ret;
-}
-#define iwl3945_poll_direct_bit(priv, addr, mask, timeout) \
- __iwl3945_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
-#else
-#define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit
-#endif
-
-static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg)
-{
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
- rmb();
- return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read_prph(u32 line, struct iwl3945_priv *priv, u32 reg)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- return _iwl3945_read_prph(priv, reg);
-}
-
-#define iwl3945_read_prph(priv, reg) \
- __iwl3945_read_prph(__LINE__, priv, reg)
-#else
-#define iwl3945_read_prph _iwl3945_read_prph
-#endif
-
-static inline void _iwl3945_write_prph(struct iwl3945_priv *priv,
- u32 addr, u32 val)
-{
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
- ((addr & 0x0000FFFF) | (3 << 24)));
- wmb();
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_write_prph(u32 line, struct iwl3945_priv *priv,
- u32 addr, u32 val)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access from line %d\n", line);
- _iwl3945_write_prph(priv, addr, val);
-}
-
-#define iwl3945_write_prph(priv, addr, val) \
- __iwl3945_write_prph(__LINE__, priv, addr, val);
-#else
-#define iwl3945_write_prph _iwl3945_write_prph
-#endif
-
-#define _iwl3945_set_bits_prph(priv, reg, mask) \
- _iwl3945_write_prph(priv, reg, (_iwl3945_read_prph(priv, reg) | mask))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bits_prph(u32 line, struct iwl3945_priv *priv,
- u32 reg, u32 mask)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
-
- _iwl3945_set_bits_prph(priv, reg, mask);
-}
-#define iwl3945_set_bits_prph(priv, reg, mask) \
- __iwl3945_set_bits_prph(__LINE__, priv, reg, mask)
-#else
-#define iwl3945_set_bits_prph _iwl3945_set_bits_prph
-#endif
-
-#define _iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
- _iwl3945_write_prph(priv, reg, ((_iwl3945_read_prph(priv, reg) & mask) | bits))
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bits_mask_prph(u32 line,
- struct iwl3945_priv *priv, u32 reg, u32 bits, u32 mask)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- _iwl3945_set_bits_mask_prph(priv, reg, bits, mask);
-}
-#define iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
- __iwl3945_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
-#else
-#define iwl3945_set_bits_mask_prph _iwl3945_set_bits_mask_prph
-#endif
-
-static inline void iwl3945_clear_bits_prph(struct iwl3945_priv
- *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read_prph(priv, reg);
- _iwl3945_write_prph(priv, reg, (val & ~mask));
-}
-
-static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
- rmb();
- return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
-}
-
-static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
-}
-
-static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 addr,
- u32 len, u32 *values)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- for (; 0 < len; len -= sizeof(u32), values++)
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
-}
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 4c638909a7d..ac22f59be9e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -24,6 +24,7 @@
*
*****************************************************************************/
+#ifdef CONFIG_IWLWIFI_LEDS
#include <linux/kernel.h>
#include <linux/module.h>
@@ -38,8 +39,10 @@
#include <linux/etherdevice.h>
#include <asm/unaligned.h>
+#include "iwl-commands.h"
#include "iwl-3945.h"
-#include "iwl-helpers.h"
+#include "iwl-core.h"
+#include "iwl-dev.h"
static const struct {
@@ -67,8 +70,8 @@ static const struct {
#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/
#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
-static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+static int iwl3945_led_cmd_callback(struct iwl_priv *priv,
+ struct iwl_cmd *cmd,
struct sk_buff *skb)
{
return 1;
@@ -80,27 +83,27 @@ static inline int iwl3945_brightness_to_idx(enum led_brightness brightness)
}
/* Send led command */
-static int iwl_send_led_cmd(struct iwl3945_priv *priv,
- struct iwl3945_led_cmd *led_cmd)
+static int iwl_send_led_cmd(struct iwl_priv *priv,
+ struct iwl_led_cmd *led_cmd)
{
- struct iwl3945_host_cmd cmd = {
+ struct iwl_host_cmd cmd = {
.id = REPLY_LEDS_CMD,
- .len = sizeof(struct iwl3945_led_cmd),
+ .len = sizeof(struct iwl_led_cmd),
.data = led_cmd,
.meta.flags = CMD_ASYNC,
.meta.u.callback = iwl3945_led_cmd_callback,
};
- return iwl3945_send_cmd(priv, &cmd);
+ return iwl_send_cmd(priv, &cmd);
}
/* Set led on command */
-static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
+static int iwl3945_led_pattern(struct iwl_priv *priv, int led_id,
unsigned int idx)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.interval = IWL_DEF_LED_INTRVL
};
@@ -114,11 +117,10 @@ static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
}
-#if 1
/* Set led on command */
-static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_on(struct iwl_priv *priv, int led_id)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.on = IWL_LED_SOLID,
.off = 0,
@@ -128,24 +130,22 @@ static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
}
/* Set led off command */
-static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_off(struct iwl_priv *priv, int led_id)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.on = 0,
.off = 0,
.interval = IWL_DEF_LED_INTRVL
};
- IWL_DEBUG_LED("led off %d\n", led_id);
+ IWL_DEBUG_LED(priv, "led off %d\n", led_id);
return iwl_send_led_cmd(priv, &led_cmd);
}
-#endif
-
/*
* brightness call back function for Tx/Rx LED
*/
-static int iwl3945_led_associated(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_associated(struct iwl_priv *priv, int led_id)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
!test_bit(STATUS_READY, &priv->status))
@@ -164,9 +164,9 @@ static int iwl3945_led_associated(struct iwl3945_priv *priv, int led_id)
static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
- struct iwl3945_led *led = container_of(led_cdev,
- struct iwl3945_led, led_dev);
- struct iwl3945_priv *priv = led->priv;
+ struct iwl_led *led = container_of(led_cdev,
+ struct iwl_led, led_dev);
+ struct iwl_priv *priv = led->priv;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -175,7 +175,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
case LED_FULL:
if (led->type == IWL_LED_TRG_ASSOC) {
priv->allow_blinking = 1;
- IWL_DEBUG_LED("MAC is associated\n");
+ IWL_DEBUG_LED(priv, "MAC is associated\n");
}
if (led->led_on)
led->led_on(priv, IWL_LED_LINK);
@@ -183,7 +183,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
case LED_OFF:
if (led->type == IWL_LED_TRG_ASSOC) {
priv->allow_blinking = 0;
- IWL_DEBUG_LED("MAC is disassociated\n");
+ IWL_DEBUG_LED(priv, "MAC is disassociated\n");
}
if (led->led_off)
led->led_off(priv, IWL_LED_LINK);
@@ -202,8 +202,8 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
/*
* Register led class with the system
*/
-static int iwl3945_led_register_led(struct iwl3945_priv *priv,
- struct iwl3945_led *led,
+static int iwl3945_led_register_led(struct iwl_priv *priv,
+ struct iwl_led *led,
enum led_type type, u8 set_led,
char *trigger)
{
@@ -219,7 +219,7 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv,
ret = led_classdev_register(device, &led->led_dev);
if (ret) {
- IWL_ERROR("Error: failed to register led handler.\n");
+ IWL_ERR(priv, "Error: failed to register led handler.\n");
return ret;
}
@@ -234,7 +234,7 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv,
/*
* calculate blink rate according to last 2 sec Tx/Rx activities
*/
-static inline u8 get_blink_rate(struct iwl3945_priv *priv)
+static inline u8 get_blink_rate(struct iwl_priv *priv)
{
int index;
u64 current_tpt = priv->rxtxpackets;
@@ -253,7 +253,7 @@ static inline u8 get_blink_rate(struct iwl3945_priv *priv)
return index;
}
-static inline int is_rf_kill(struct iwl3945_priv *priv)
+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);
@@ -264,7 +264,7 @@ static inline int is_rf_kill(struct iwl3945_priv *priv)
* happen very frequent we postpone led command to be called from
* REPLY handler so we know ucode is up
*/
-void iwl3945_led_background(struct iwl3945_priv *priv)
+void iwl3945_led_background(struct iwl_priv *priv)
{
u8 blink_idx;
@@ -304,7 +304,7 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
/* Register all led handler */
-int iwl3945_led_register(struct iwl3945_priv *priv)
+int iwl3945_led_register(struct iwl_priv *priv)
{
char *trigger;
int ret;
@@ -317,7 +317,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_RADIO].name,
- sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
+ sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
wiphy_name(priv->hw->wiphy));
priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
@@ -333,7 +333,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
- sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
+ sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
@@ -350,7 +350,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_RX].name,
- sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
+ sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
@@ -366,7 +366,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_TX].name,
- sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
+ sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
@@ -389,7 +389,7 @@ exit_fail:
/* unregister led class */
-static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
+static void iwl3945_led_unregister_led(struct iwl_led *led, u8 set_led)
{
if (!led->registered)
return;
@@ -402,7 +402,7 @@ static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
}
/* Unregister all led handlers */
-void iwl3945_led_unregister(struct iwl3945_priv *priv)
+void iwl3945_led_unregister(struct iwl_priv *priv)
{
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
@@ -410,3 +410,4 @@ void iwl3945_led_unregister(struct iwl3945_priv *priv)
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
}
+#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 749ac035fd6..3b65642258c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -27,48 +27,20 @@
#ifndef IWL3945_LEDS_H
#define IWL3945_LEDS_H
-struct iwl3945_priv;
+struct iwl_priv;
-#ifdef CONFIG_IWL3945_LEDS
-#define IWL_LED_SOLID 11
-#define IWL_LED_NAME_LEN 31
-#define IWL_DEF_LED_INTRVL __constant_cpu_to_le32(1000)
+#ifdef CONFIG_IWLWIFI_LEDS
-#define IWL_LED_ACTIVITY (0<<1)
-#define IWL_LED_LINK (1<<1)
+#include "iwl-led.h"
-enum led_type {
- IWL_LED_TRG_TX,
- IWL_LED_TRG_RX,
- IWL_LED_TRG_ASSOC,
- IWL_LED_TRG_RADIO,
- IWL_LED_TRG_MAX,
-};
-
-#include <linux/leds.h>
-
-struct iwl3945_led {
- struct iwl3945_priv *priv;
- struct led_classdev led_dev;
- char name[32];
-
- int (*led_on) (struct iwl3945_priv *priv, int led_id);
- int (*led_off) (struct iwl3945_priv *priv, int led_id);
- int (*led_pattern) (struct iwl3945_priv *priv, int led_id,
- unsigned int idx);
-
- enum led_type type;
- unsigned int registered;
-};
-
-extern int iwl3945_led_register(struct iwl3945_priv *priv);
-extern void iwl3945_led_unregister(struct iwl3945_priv *priv);
-extern void iwl3945_led_background(struct iwl3945_priv *priv);
+extern int iwl3945_led_register(struct iwl_priv *priv);
+extern void iwl3945_led_unregister(struct iwl_priv *priv);
+extern void iwl3945_led_background(struct iwl_priv *priv);
#else
-static inline int iwl3945_led_register(struct iwl3945_priv *priv) { return 0; }
-static inline void iwl3945_led_unregister(struct iwl3945_priv *priv) {}
-static inline void iwl3945_led_background(struct iwl3945_priv *priv) {}
-#endif /* CONFIG_IWL3945_LEDS */
+static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; }
+static inline void iwl3945_led_unregister(struct iwl_priv *priv) {}
+static inline void iwl3945_led_background(struct iwl_priv *priv) {}
+#endif /* IWLWIFI_LEDS*/
#endif /* IWL3945_LEDS_H */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 9b60a0c5de5..f65c308a671 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -36,6 +36,7 @@
#include <linux/workqueue.h>
+#include "iwl-commands.h"
#include "iwl-3945.h"
#define RS_NAME "iwl-3945-rs"
@@ -51,6 +52,7 @@ struct iwl3945_rate_scale_data {
struct iwl3945_rs_sta {
spinlock_t lock;
+ struct iwl_priv *priv;
s32 *expected_tpt;
unsigned long last_partial_flush;
unsigned long last_flush;
@@ -62,7 +64,7 @@ struct iwl3945_rs_sta {
u8 start_rate;
u8 ibss_sta_added;
struct timer_list rate_scale_flush;
- struct iwl3945_rate_scale_data win[IWL_RATE_COUNT];
+ struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_stats_table_file;
#endif
@@ -71,19 +73,19 @@ struct iwl3945_rs_sta {
int last_txrate_idx;
};
-static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
};
-static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
};
-static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = {
0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
};
-static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
};
@@ -119,12 +121,13 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
#define IWL_RATE_MAX_WINDOW 62
#define IWL_RATE_FLUSH (3*HZ)
#define IWL_RATE_WIN_FLUSH (HZ/2)
-#define IWL_RATE_HIGH_TH 11520
+#define IWL39_RATE_HIGH_TH 11520
#define IWL_SUCCESS_UP_TH 8960
#define IWL_SUCCESS_DOWN_TH 10880
#define IWL_RATE_MIN_FAILURE_TH 8
#define IWL_RATE_MIN_SUCCESS_TH 8
#define IWL_RATE_DECREASE_TH 1920
+#define IWL_RATE_RETRY_TH 15
static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band)
{
@@ -165,7 +168,7 @@ static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window)
window->success_counter = 0;
window->success_ratio = -1;
window->counter = 0;
- window->average_tpt = IWL_INV_TPT;
+ window->average_tpt = IWL_INVALID_VALUE;
window->stamp = 0;
}
@@ -181,20 +184,21 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta)
int unflushed = 0;
int i;
unsigned long flags;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
/*
* For each rate, if we have collected data on that rate
* and it has been more than IWL_RATE_WIN_FLUSH
* since we flushed, clear out the gathered statistics
*/
- for (i = 0; i < IWL_RATE_COUNT; i++) {
+ for (i = 0; i < IWL_RATE_COUNT_3945; i++) {
if (!rs_sta->win[i].counter)
continue;
spin_lock_irqsave(&rs_sta->lock, flags);
if (time_after(jiffies, rs_sta->win[i].stamp +
IWL_RATE_WIN_FLUSH)) {
- IWL_DEBUG_RATE("flushing %d samples of rate "
+ IWL_DEBUG_RATE(priv, "flushing %d samples of rate "
"index %d\n",
rs_sta->win[i].counter, i);
iwl3945_clear_window(&rs_sta->win[i]);
@@ -213,11 +217,12 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta)
static void iwl3945_bg_rate_scale_flush(unsigned long data)
{
struct iwl3945_rs_sta *rs_sta = (void *)data;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
int unflushed = 0;
unsigned long flags;
u32 packet_count, duration, pps;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
unflushed = iwl3945_rate_scale_flush_windows(rs_sta);
@@ -232,7 +237,7 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
duration =
jiffies_to_msecs(jiffies - rs_sta->last_partial_flush);
- IWL_DEBUG_RATE("Tx'd %d packets in %dms\n",
+ IWL_DEBUG_RATE(priv, "Tx'd %d packets in %dms\n",
packet_count, duration);
/* Determine packets per second */
@@ -252,7 +257,7 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
rs_sta->flush_time = msecs_to_jiffies(duration);
- IWL_DEBUG_RATE("new flush period: %d msec ave %d\n",
+ IWL_DEBUG_RATE(priv, "new flush period: %d msec ave %d\n",
duration, packet_count);
mod_timer(&rs_sta->rate_scale_flush, jiffies +
@@ -270,7 +275,7 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
spin_unlock_irqrestore(&rs_sta->lock, flags);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
}
/**
@@ -286,50 +291,70 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
{
unsigned long flags;
s32 fail_count;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
if (!retries) {
- IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n");
+ IWL_DEBUG_RATE(priv, "leave: retries == 0 -- should be at least 1\n");
return;
}
spin_lock_irqsave(&rs_sta->lock, flags);
- while (retries--) {
- /* If we have filled up the window then subtract one from the
- * success counter if the high-bit is counting toward
- * success */
- if (window->counter == IWL_RATE_MAX_WINDOW) {
- if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1)))
+ /*
+ * Keep track of only the latest 62 tx frame attempts in this rate's
+ * history window; anything older isn't really relevant any more.
+ * If we have filled up the sliding window, drop the oldest attempt;
+ * if the oldest attempt (highest bit in bitmap) shows "success",
+ * subtract "1" from the success counter (this is the main reason
+ * we keep these bitmaps!).
+ * */
+ while (retries > 0) {
+ if (window->counter >= IWL_RATE_MAX_WINDOW) {
+
+ /* remove earliest */
+ window->counter = IWL_RATE_MAX_WINDOW - 1;
+
+ if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) {
+ window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1));
window->success_counter--;
- } else
- window->counter++;
+ }
+ }
- /* Slide the window to the left one bit */
- window->data = (window->data << 1);
+ /* Increment frames-attempted counter */
+ window->counter++;
- /* If this packet was a success then set the low bit high */
- if (success) {
+ /* Shift bitmap by one frame (throw away oldest history),
+ * OR in "1", and increment "success" if this
+ * frame was successful. */
+ window->data <<= 1;
+ if (success > 0) {
window->success_counter++;
- window->data |= 1;
+ window->data |= 0x1;
+ success--;
}
- /* window->counter can't be 0 -- it is either >0 or
- * IWL_RATE_MAX_WINDOW */
- window->success_ratio = 12800 * window->success_counter /
- window->counter;
-
- /* Tag this window as having been updated */
- window->stamp = jiffies;
-
+ retries--;
}
+ /* Calculate current success ratio, avoid divide-by-0! */
+ if (window->counter > 0)
+ window->success_ratio = 128 * (100 * window->success_counter)
+ / window->counter;
+ else
+ window->success_ratio = IWL_INVALID_VALUE;
+
fail_count = window->counter - window->success_counter;
+
+ /* Calculate average throughput, if we have enough history. */
if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
(window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
window->average_tpt = ((window->success_ratio *
rs_sta->expected_tpt[index] + 64) / 128);
else
- window->average_tpt = IWL_INV_TPT;
+ window->average_tpt = IWL_INVALID_VALUE;
+
+ /* Tag this window as having been updated */
+ window->stamp = jiffies;
spin_unlock_irqrestore(&rs_sta->lock, flags);
@@ -339,10 +364,10 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
struct iwl3945_rs_sta *rs_sta = priv_sta;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
int i;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
/* TODO: what is a good starting rate for STA? About middle? Maybe not
* the lowest or the highest rate.. Could consider using RSSI from
@@ -365,7 +390,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
}
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
}
static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -379,10 +404,11 @@ static void rs_free(void *priv)
return;
}
-static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
+static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
{
struct iwl3945_rs_sta *rs_sta;
struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
+ struct iwl_priv *priv = iwl_priv;
int i;
/*
@@ -390,11 +416,11 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
* as well just put all the information there.
*/
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp);
if (!rs_sta) {
- IWL_DEBUG_RATE("leave: ENOMEM\n");
+ IWL_DEBUG_RATE(priv, "leave: ENOMEM\n");
return NULL;
}
@@ -402,6 +428,8 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
spin_lock_init(&rs_sta->lock);
+ rs_sta->priv = priv;
+
rs_sta->start_rate = IWL_RATE_INVALID;
/* default to just 802.11b */
@@ -417,33 +445,34 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush;
- for (i = 0; i < IWL_RATE_COUNT; i++)
+ for (i = 0; i < IWL_RATE_COUNT_3945; i++)
iwl3945_clear_window(&rs_sta->win[i]);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
return rs_sta;
}
-static void rs_free_sta(void *priv, struct ieee80211_sta *sta,
+static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
void *priv_sta)
{
struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
struct iwl3945_rs_sta *rs_sta = priv_sta;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
psta->rs_sta = NULL;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
del_timer_sync(&rs_sta->rate_scale_flush);
kfree(rs_sta);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
}
/**
* rs_tx_status - Update rate control values based on Tx results
*
- * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
+ * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by
* the hardware for each rate.
*/
static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
@@ -453,22 +482,25 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
s8 retries = 0, current_count;
int scale_rate_index, first_index, last_index;
unsigned long flags;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct iwl3945_rs_sta *rs_sta = priv_sta;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
- retries = info->status.rates[0].count;
+ retries = info->status.rates[0].count - 1;
+ /* Sanity Check for retries */
+ if (retries > IWL_RATE_RETRY_TH)
+ retries = IWL_RATE_RETRY_TH;
first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
- if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
- IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
+ if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) {
+ IWL_DEBUG_RATE(priv, "leave: Rate out of bounds: %d\n", first_index);
return;
}
if (!priv_sta) {
- IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
+ IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
return;
}
@@ -502,7 +534,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
iwl3945_collect_tx_data(rs_sta,
&rs_sta->win[scale_rate_index],
0, current_count, scale_rate_index);
- IWL_DEBUG_RATE("Update rate %d for %d retries.\n",
+ IWL_DEBUG_RATE(priv, "Update rate %d for %d retries.\n",
scale_rate_index, current_count);
retries -= current_count;
@@ -512,7 +544,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
/* Update the last index window with success/failure based on ACK */
- IWL_DEBUG_RATE("Update rate %d with %s.\n",
+ IWL_DEBUG_RATE(priv, "Update rate %d with %s.\n",
last_index,
(info->flags & IEEE80211_TX_STAT_ACK) ?
"success" : "failure");
@@ -537,7 +569,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
spin_unlock_irqrestore(&rs_sta->lock, flags);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
return;
}
@@ -547,6 +579,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
{
u8 high = IWL_RATE_INVALID;
u8 low = IWL_RATE_INVALID;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
/* 802.11A walks to the next literal adjacent rate in
* the rate table */
@@ -565,7 +598,8 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
/* Find the next rate that is in the rate mask */
i = index + 1;
- for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
+ for (mask = (1 << i); i < IWL_RATE_COUNT_3945;
+ i++, mask <<= 1) {
if (rate_mask & mask) {
high = i;
break;
@@ -585,7 +619,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
break;
if (rate_mask & (1 << low))
break;
- IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
+ IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low);
}
high = index;
@@ -598,7 +632,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
break;
if (rate_mask & (1 << high))
break;
- IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
+ IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high);
}
return (high << 8) | low;
@@ -631,18 +665,23 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
int index;
struct iwl3945_rs_sta *rs_sta = priv_sta;
struct iwl3945_rate_scale_data *window = NULL;
- int current_tpt = IWL_INV_TPT;
- int low_tpt = IWL_INV_TPT;
- int high_tpt = IWL_INV_TPT;
+ int current_tpt = IWL_INVALID_VALUE;
+ int low_tpt = IWL_INVALID_VALUE;
+ int high_tpt = IWL_INVALID_VALUE;
u32 fail_count;
s8 scale_action = 0;
unsigned long flags;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u16 fc, rate_mask;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
+ u16 fc;
+ u16 rate_mask = 0;
+ s8 max_rate_idx = -1;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
+
+ if (sta)
+ rate_mask = sta->supp_rates[sband->band];
/* Send management frames and broadcast/multicast data using lowest
* rate. */
@@ -650,13 +689,24 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
is_multicast_ether_addr(hdr->addr1) ||
!sta || !priv_sta) {
- IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
- info->control.rates[0].idx = rate_lowest_index(sband, sta);
+ IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
+ if (!rate_mask)
+ info->control.rates[0].idx =
+ rate_lowest_index(sband, NULL);
+ else
+ info->control.rates[0].idx =
+ rate_lowest_index(sband, sta);
return;
}
- rate_mask = sta->supp_rates[sband->band];
- index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
+ /* get user max rate if set */
+ max_rate_idx = txrc->max_rate_idx;
+ if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1))
+ max_rate_idx += IWL_FIRST_OFDM_RATE;
+ if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT))
+ max_rate_idx = -1;
+
+ index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1);
if (sband->band == IEEE80211_BAND_5GHZ)
rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
@@ -666,7 +716,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_RATE("LQ: ADD station %pm\n",
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
hdr->addr1);
sta_id = iwl3945_add_station(priv,
hdr->addr1, 0, CMD_ASYNC);
@@ -687,21 +737,30 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
rs_sta->start_rate = IWL_RATE_INVALID;
}
+ /* force user max rate if set by user */
+ if ((max_rate_idx != -1) && (max_rate_idx < index)) {
+ if (rate_mask & (1 << max_rate_idx))
+ index = max_rate_idx;
+ }
+
window = &(rs_sta->win[index]);
fail_count = window->counter - window->success_counter;
- if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) &&
+ if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
(window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
spin_unlock_irqrestore(&rs_sta->lock, flags);
- IWL_DEBUG_RATE("Invalid average_tpt on rate %d: "
+ IWL_DEBUG_RATE(priv, "Invalid average_tpt on rate %d: "
"counter: %d, success_counter: %d, "
"expected_tpt is %sNULL\n",
index,
window->counter,
window->success_counter,
rs_sta->expected_tpt ? "not " : "");
+
+ /* Can't calculate this yet; not enough history */
+ window->average_tpt = IWL_INVALID_VALUE;
goto out;
}
@@ -713,6 +772,11 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
+ /* If user set max rate, dont allow higher than user constrain */
+ if ((max_rate_idx != -1) && (max_rate_idx < high))
+ high = IWL_RATE_INVALID;
+
+ /* Collect Measured throughputs of adjacent rates */
if (low != IWL_RATE_INVALID)
low_tpt = rs_sta->win[low].average_tpt;
@@ -721,56 +785,79 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
spin_unlock_irqrestore(&rs_sta->lock, flags);
- scale_action = 1;
+ scale_action = 0;
+ /* Low success ratio , need to drop the rate */
if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
- IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
+ IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
scale_action = -1;
- } else if ((low_tpt == IWL_INV_TPT) && (high_tpt == IWL_INV_TPT))
- scale_action = 1;
- else if ((low_tpt != IWL_INV_TPT) && (high_tpt != IWL_INV_TPT) &&
+
+ /* No throughput measured yet for adjacent rates,
+ * try increase */
+ } else if ((low_tpt == IWL_INVALID_VALUE) &&
+ (high_tpt == IWL_INVALID_VALUE)) {
+
+ if (high != IWL_RATE_INVALID && window->success_counter >= IWL_RATE_INCREASE_TH)
+ scale_action = 1;
+ else if (low != IWL_RATE_INVALID)
+ scale_action = -1;
+
+ /* Both adjacent throughputs are measured, but neither one has
+ * better throughput; we're using the best rate, don't change
+ * it! */
+ } else if ((low_tpt != IWL_INVALID_VALUE) &&
+ (high_tpt != IWL_INVALID_VALUE) &&
(low_tpt < current_tpt) && (high_tpt < current_tpt)) {
- IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < "
+
+ IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < "
"current_tpt [%d]\n",
low_tpt, high_tpt, current_tpt);
scale_action = 0;
+
+ /* At least one of the rates has better throughput */
} else {
- if (high_tpt != IWL_INV_TPT) {
- if (high_tpt > current_tpt)
+ if (high_tpt != IWL_INVALID_VALUE) {
+
+ /* High rate has better throughput, Increase
+ * rate */
+ if (high_tpt > current_tpt &&
+ window->success_ratio >= IWL_RATE_INCREASE_TH)
scale_action = 1;
else {
- IWL_DEBUG_RATE
- ("decrease rate because of high tpt\n");
+ IWL_DEBUG_RATE(priv,
+ "decrease rate because of high tpt\n");
scale_action = -1;
}
- } else if (low_tpt != IWL_INV_TPT) {
+ } else if (low_tpt != IWL_INVALID_VALUE) {
if (low_tpt > current_tpt) {
- IWL_DEBUG_RATE
- ("decrease rate because of low tpt\n");
+ IWL_DEBUG_RATE(priv,
+ "decrease rate because of low tpt\n");
scale_action = -1;
- } else
+ } else if (window->success_counter >= IWL_RATE_INCREASE_TH) {
+ /* Lower rate has better
+ * throughput,decrease rate */
scale_action = 1;
+ }
}
}
- if (scale_action == -1) {
- if (window->success_ratio > IWL_SUCCESS_DOWN_TH)
- scale_action = 0;
- } else if (scale_action == 1) {
- if (window->success_ratio < IWL_SUCCESS_UP_TH) {
- IWL_DEBUG_RATE("No action -- success_ratio [%d] < "
- "SUCCESS UP\n", window->success_ratio);
- scale_action = 0;
- }
- }
+ /* Sanity check; asked for decrease, but success rate or throughput
+ * has been good at old rate. Don't change it. */
+ if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
+ ((window->success_ratio > IWL_RATE_HIGH_TH) ||
+ (current_tpt > (100 * rs_sta->expected_tpt[low]))))
+ scale_action = 0;
switch (scale_action) {
case -1:
+
+ /* Decrese rate */
if (low != IWL_RATE_INVALID)
index = low;
break;
case 1:
+ /* Increase rate */
if (high != IWL_RATE_INVALID)
index = high;
@@ -778,10 +865,11 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
case 0:
default:
+ /* No change */
break;
}
- IWL_DEBUG_RATE("Selected %d (action %d) - low %d high %d\n",
+ IWL_DEBUG_RATE(priv, "Selected %d (action %d) - low %d high %d\n",
index, scale_action, low, high);
out:
@@ -793,7 +881,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
else
info->control.rates[0].idx = rs_sta->last_txrate_idx;
- IWL_DEBUG_RATE("leave: %d\n", index);
+ IWL_DEBUG_RATE(priv, "leave: %d\n", index);
}
#ifdef CONFIG_MAC80211_DEBUGFS
@@ -807,24 +895,31 @@ static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
- char buff[1024];
+ char *buff;
int desc = 0;
int j;
+ ssize_t ret;
struct iwl3945_rs_sta *lq_sta = file->private_data;
+ buff = kmalloc(1024, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n"
"rate=0x%X flush time %d\n",
lq_sta->tx_packets,
lq_sta->last_txrate_idx,
lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time));
- for (j = 0; j < IWL_RATE_COUNT; j++) {
+ for (j = 0; j < IWL_RATE_COUNT_3945; j++) {
desc += sprintf(buff+desc,
"counter=%d success=%d %%=%d\n",
lq_sta->win[j].counter,
lq_sta->win[j].success_counter,
lq_sta->win[j].success_ratio);
}
- return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ kfree(buff);
+ return ret;
}
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
@@ -869,18 +964,18 @@ static struct rate_control_ops rs_ops = {
void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
s32 rssi = 0;
unsigned long flags;
struct iwl3945_rs_sta *rs_sta;
struct ieee80211_sta *sta;
struct iwl3945_sta_priv *psta;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
rcu_read_lock();
- sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
+ sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr);
if (!sta) {
rcu_read_unlock();
return;
@@ -916,11 +1011,11 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
if (rssi == 0)
rssi = IWL_MIN_RSSI_VAL;
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi);
+ IWL_DEBUG_RATE(priv, "Network RSSI: %d\n", rssi);
rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band);
- IWL_DEBUG_RATE("leave: rssi %d assign rate index: "
+ IWL_DEBUG_RATE(priv, "leave: rssi %d assign rate index: "
"%d (plcp 0x%x)\n", rssi, rs_sta->start_rate,
iwl3945_rates[rs_sta->start_rate].plcp);
rcu_read_unlock();
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
deleted file mode 100644
index b5a66135ded..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_3945_rs_h__
-#define __iwl_3945_rs_h__
-
-struct iwl3945_rate_info {
- u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
- u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
- u8 prev_ieee; /* previous rate in IEEE speeds */
- u8 next_ieee; /* next rate in IEEE speeds */
- u8 prev_rs; /* previous rate used in rs algo */
- u8 next_rs; /* next rate used in rs algo */
- u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
- u8 next_rs_tgg; /* next rate used in TGG rs algo */
- u8 table_rs_index; /* index in rate scale table cmd */
- u8 prev_table_rs; /* prev in rate table cmd */
-};
-
-/*
- * These serve as indexes into
- * struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
- */
-enum {
- IWL_RATE_1M_INDEX = 0,
- IWL_RATE_2M_INDEX,
- IWL_RATE_5M_INDEX,
- IWL_RATE_11M_INDEX,
- IWL_RATE_6M_INDEX,
- IWL_RATE_9M_INDEX,
- IWL_RATE_12M_INDEX,
- IWL_RATE_18M_INDEX,
- IWL_RATE_24M_INDEX,
- IWL_RATE_36M_INDEX,
- IWL_RATE_48M_INDEX,
- IWL_RATE_54M_INDEX,
- IWL_RATE_COUNT,
- IWL_RATE_INVM_INDEX,
- IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
-};
-
-enum {
- IWL_RATE_6M_INDEX_TABLE = 0,
- IWL_RATE_9M_INDEX_TABLE,
- IWL_RATE_12M_INDEX_TABLE,
- IWL_RATE_18M_INDEX_TABLE,
- IWL_RATE_24M_INDEX_TABLE,
- IWL_RATE_36M_INDEX_TABLE,
- IWL_RATE_48M_INDEX_TABLE,
- IWL_RATE_54M_INDEX_TABLE,
- IWL_RATE_1M_INDEX_TABLE,
- IWL_RATE_2M_INDEX_TABLE,
- IWL_RATE_5M_INDEX_TABLE,
- IWL_RATE_11M_INDEX_TABLE,
- IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX,
-};
-
-enum {
- IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
- IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
- IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
- IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
-};
-
-/* #define vs. enum to keep from defaulting to 'large integer' */
-#define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX)
-#define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX)
-#define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX)
-#define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX)
-#define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX)
-#define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX)
-#define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX)
-#define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX)
-#define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX)
-#define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX)
-#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
-#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
-
-/* 3945 uCode API values for (legacy) bit rates, both OFDM and CCK */
-enum {
- IWL_RATE_6M_PLCP = 13,
- IWL_RATE_9M_PLCP = 15,
- IWL_RATE_12M_PLCP = 5,
- IWL_RATE_18M_PLCP = 7,
- IWL_RATE_24M_PLCP = 9,
- IWL_RATE_36M_PLCP = 11,
- IWL_RATE_48M_PLCP = 1,
- IWL_RATE_54M_PLCP = 3,
- IWL_RATE_1M_PLCP = 10,
- IWL_RATE_2M_PLCP = 20,
- IWL_RATE_5M_PLCP = 55,
- IWL_RATE_11M_PLCP = 110,
-};
-
-/* MAC header values for bit rates */
-enum {
- IWL_RATE_6M_IEEE = 12,
- IWL_RATE_9M_IEEE = 18,
- IWL_RATE_12M_IEEE = 24,
- IWL_RATE_18M_IEEE = 36,
- IWL_RATE_24M_IEEE = 48,
- IWL_RATE_36M_IEEE = 72,
- IWL_RATE_48M_IEEE = 96,
- IWL_RATE_54M_IEEE = 108,
- IWL_RATE_1M_IEEE = 2,
- IWL_RATE_2M_IEEE = 4,
- IWL_RATE_5M_IEEE = 11,
- IWL_RATE_11M_IEEE = 22,
-};
-
-#define IWL_CCK_BASIC_RATES_MASK \
- (IWL_RATE_1M_MASK | \
- IWL_RATE_2M_MASK)
-
-#define IWL_CCK_RATES_MASK \
- (IWL_BASIC_RATES_MASK | \
- IWL_RATE_5M_MASK | \
- IWL_RATE_11M_MASK)
-
-#define IWL_OFDM_BASIC_RATES_MASK \
- (IWL_RATE_6M_MASK | \
- IWL_RATE_12M_MASK | \
- IWL_RATE_24M_MASK)
-
-#define IWL_OFDM_RATES_MASK \
- (IWL_OFDM_BASIC_RATES_MASK | \
- IWL_RATE_9M_MASK | \
- IWL_RATE_18M_MASK | \
- IWL_RATE_36M_MASK | \
- IWL_RATE_48M_MASK | \
- IWL_RATE_54M_MASK)
-
-#define IWL_BASIC_RATES_MASK \
- (IWL_OFDM_BASIC_RATES_MASK | \
- IWL_CCK_BASIC_RATES_MASK)
-
-#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
-
-#define IWL_INV_TPT -1
-
-#define IWL_MIN_RSSI_VAL -100
-#define IWL_MAX_RSSI_VAL 0
-
-extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
-
-static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
-{
- u8 rate = iwl3945_rates[rate_index].prev_ieee;
-
- if (rate == IWL_RATE_INVALID)
- rate = rate_index;
- return rate;
-}
-
-/**
- * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
- *
- * The specific throughput table used is based on the type of network
- * the associated with, including A, B, G, and G w/ TGG protection
- */
-extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
-
-/**
- * iwl3945_rate_control_register - Register the rate control algorithm callbacks
- *
- * Since the rate control algorithm is hardware specific, there is no need
- * or reason to place it as a stand alone module. The driver can call
- * iwl3945_rate_control_register in order to register the rate control callbacks
- * with the mac80211 subsystem. This should be performed prior to calling
- * ieee80211_register_hw
- *
- */
-extern int iwl3945_rate_control_register(void);
-
-/**
- * iwl3945_rate_control_unregister - Unregister the rate control callbacks
- *
- * This should be called after calling ieee80211_unregister_hw, but before
- * the driver is unloaded.
- */
-extern void iwl3945_rate_control_unregister(void);
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 45cfa1cf194..ba7e720e73c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -38,10 +38,15 @@
#include <asm/unaligned.h>
#include <net/mac80211.h>
-#include "iwl-3945-core.h"
+#include "iwl-fh.h"
+#include "iwl-3945-fh.h"
+#include "iwl-commands.h"
+#include "iwl-sta.h"
#include "iwl-3945.h"
+#include "iwl-eeprom.h"
#include "iwl-helpers.h"
-#include "iwl-3945-rs.h"
+#include "iwl-core.h"
+#include "iwl-agn-rs.h"
#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -63,7 +68,7 @@
* maps to IWL_RATE_INVALID
*
*/
-const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
+const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */
IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */
IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */
@@ -91,7 +96,7 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
* Use for only special debugging. This function is just a placeholder as-is,
* you'll need to provide the special bits! ...
* ... and set IWL_EVT_DISABLE to 1. */
-void iwl3945_disable_events(struct iwl3945_priv *priv)
+void iwl3945_disable_events(struct iwl_priv *priv)
{
int ret;
int i;
@@ -150,34 +155,34 @@ void iwl3945_disable_events(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
- ret = iwl3945_grab_nic_access(priv);
+ ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
- disable_ptr = iwl3945_read_targ_mem(priv, base + (4 * sizeof(u32)));
- array_size = iwl3945_read_targ_mem(priv, base + (5 * sizeof(u32)));
- iwl3945_release_nic_access(priv);
+ 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("Disabling selected uCode log events at 0x%x\n",
+ IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n",
disable_ptr);
- ret = iwl3945_grab_nic_access(priv);
+ ret = iwl_grab_nic_access(priv);
for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
- iwl3945_write_targ_mem(priv,
+ iwl_write_targ_mem(priv,
disable_ptr + (i * sizeof(u32)),
evt_disable[i]);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
} else {
- IWL_DEBUG_INFO("Selected uCode log events may be disabled\n");
- IWL_DEBUG_INFO(" by writing \"1\"s into disable bitmap\n");
- IWL_DEBUG_INFO(" in SRAM at 0x%x, size %d u32s\n",
+ IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n");
+ IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n");
+ IWL_DEBUG_INFO(priv, " in SRAM at 0x%x, size %d u32s\n",
disable_ptr, array_size);
}
@@ -193,40 +198,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
return -1;
}
-/**
- * iwl3945_get_antenna_flags - Get antenna flags for RXON command
- * @priv: eeprom and antenna fields are used to determine antenna flags
- *
- * priv->eeprom is used to determine if antenna AUX/MAIN are reversed
- * priv->antenna specifies the antenna diversity mode:
- *
- * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
- * IWL_ANTENNA_MAIN - Force MAIN antenna
- * IWL_ANTENNA_AUX - Force AUX antenna
- */
-__le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
-{
- switch (priv->antenna) {
- case IWL_ANTENNA_DIVERSITY:
- return 0;
-
- case IWL_ANTENNA_MAIN:
- if (priv->eeprom.antenna_switch_type)
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
-
- case IWL_ANTENNA_AUX:
- if (priv->eeprom.antenna_switch_type)
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
- }
-
- /* bad antenna selector value */
- IWL_ERROR("Bad antenna selector value (0x%x)\n", priv->antenna);
- return 0; /* "diversity" is default if error */
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
static const char *iwl3945_get_tx_fail_reason(u32 status)
@@ -266,7 +238,7 @@ static inline const char *iwl3945_get_tx_fail_reason(u32 status)
* for A and B mode we need to overright prev
* value
*/
-int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
+int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
{
int next_rate = iwl3945_get_prev_ieee_rate(rate);
@@ -279,7 +251,7 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
break;
case IEEE80211_BAND_2GHZ:
if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
- iwl3945_is_associated(priv)) {
+ iwl_is_associated(priv)) {
if (rate == IWL_RATE_11M_INDEX)
next_rate = IWL_RATE_5M_INDEX;
}
@@ -300,12 +272,12 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
* need to be reclaimed. As result, some free space forms. If there is
* enough free space (> low mark), wake the stack that feeds us.
*/
-static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
+static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
int txq_id, int index)
{
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
- struct iwl3945_queue *q = &txq->q;
- struct iwl3945_tx_info *tx_info;
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+ struct iwl_tx_info *tx_info;
BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
@@ -315,10 +287,10 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
tx_info = &txq->txb[txq->q.read_ptr];
ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
tx_info->skb[0] = NULL;
- iwl3945_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
}
- if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
+ if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
(txq_id != IWL_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
ieee80211_wake_queue(priv->hw, txq_id);
@@ -327,22 +299,22 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
/**
* iwl3945_rx_reply_tx - Handle Tx response
*/
-static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int index = SEQ_TO_INDEX(sequence);
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info;
struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->status);
int rate_idx;
int fail;
- if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -366,15 +338,15 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
IEEE80211_TX_STAT_ACK : 0;
- IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
+ IWL_DEBUG_TX(priv, "Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
txq_id, iwl3945_get_tx_fail_reason(status), status,
tx_resp->rate, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+ IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index);
iwl3945_tx_queue_reclaim(priv, txq_id, index);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
@@ -387,14 +359,14 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
*
*****************************************************************************/
-void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
+void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
(int)sizeof(struct iwl3945_notif_statistics),
le32_to_cpu(pkt->len));
- memcpy(&priv->statistics, pkt->u.raw, sizeof(priv->statistics));
+ memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
iwl3945_led_background(priv);
@@ -406,7 +378,7 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b
* Misc. internal state and helper functions
*
******************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
/**
* iwl3945_report_frame - dump frame to syslog during debug sessions
@@ -415,8 +387,8 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b
* including selective frame dumps.
* group100 parameter selects whether to show 1 out of 100 good frames.
*/
-static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
- struct iwl3945_rx_packet *pkt,
+static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
struct ieee80211_hdr *header, int group100)
{
u32 to_us;
@@ -524,13 +496,13 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
* MAC addresses show just the last byte (for brevity),
* but you can hack it to show more, if you'd like to. */
if (dataframe)
- IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
+ IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
"len=%u, rssi=%d, chnl=%d, rate=%d, \n",
title, le16_to_cpu(fc), header->addr1[5],
length, rssi, channel, rate);
else {
/* src/dst addresses assume managed mode */
- IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
+ IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, "
"src=0x%02x, rssi=%u, tim=%lu usec, "
"phy=0x%02x, chnl=%d\n",
title, le16_to_cpu(fc), header->addr1[5],
@@ -540,18 +512,27 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
}
}
if (print_dump)
- iwl3945_print_hex_dump(IWL_DL_RX, data, length);
+ iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
+}
+
+static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
+ struct ieee80211_hdr *header, int group100)
+{
+ if (priv->debug_level & IWL_DL_RX)
+ _iwl3945_dbg_report_frame(priv, pkt, header, group100);
}
+
#else
-static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
- struct iwl3945_rx_packet *pkt,
+static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
struct ieee80211_hdr *header, int group100)
{
}
#endif
/* This is necessary only for a number of statistics, see the caller. */
-static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
+static int iwl3945_is_network_packet(struct iwl_priv *priv,
struct ieee80211_hdr *header)
{
/* Filter incoming packets to determine if they are targeted toward
@@ -568,12 +549,12 @@ static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
}
}
-static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb,
+static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb,
struct ieee80211_rx_status *stats)
{
- struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
-#ifdef CONFIG_IWL3945_LEDS
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+#ifdef CONFIG_IWLWIFI_LEDS
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
#endif
struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
@@ -581,15 +562,15 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
short len = le16_to_cpu(rx_hdr->len);
/* We received data from the HW, so stop the watchdog */
- if (unlikely((len + IWL_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
- IWL_DEBUG_DROP("Corruption detected!\n");
+ if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
+ IWL_DEBUG_DROP(priv, "Corruption detected!\n");
return;
}
/* We only process data packets if the interface is open */
if (unlikely(!priv->is_open)) {
- IWL_DEBUG_DROP_LIMIT
- ("Dropping packet while interface is not open.\n");
+ IWL_DEBUG_DROP_LIMIT(priv,
+ "Dropping packet while interface is not open.\n");
return;
}
@@ -597,11 +578,12 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
/* Set the size of the skb to the size of the frame */
skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
- if (iwl3945_param_hwcrypto)
- iwl3945_set_decrypted_flag(priv, rxb->skb,
+ if (!iwl3945_mod_params.sw_crypto)
+ iwl_set_decrypted_flag(priv,
+ (struct ieee80211_hdr *)rxb->skb->data,
le32_to_cpu(rx_end->status), stats);
-#ifdef CONFIG_IWL3945_LEDS
+#ifdef CONFIG_IWLWIFI_LEDS
if (ieee80211_is_data(hdr->frame_control))
priv->rxtxpackets += len;
#endif
@@ -611,12 +593,12 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct ieee80211_hdr *header;
struct ieee80211_rx_status rx_status;
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
@@ -644,22 +626,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
rx_status.flag |= RX_FLAG_SHORTPRE;
if ((unlikely(rx_stats->phy_count > 20))) {
- IWL_DEBUG_DROP
- ("dsp size out of range [0,20]: "
- "%d/n", rx_stats->phy_count);
+ IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
+ rx_stats->phy_count);
return;
}
if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR)
|| !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
- IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n", rx_end->status);
+ IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", rx_end->status);
return;
}
/* Convert 3945's rssi indicator to dBm */
- rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
+ rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET;
/* Set default noise value to -127 */
if (priv->last_rx_noise == 0)
@@ -691,7 +672,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
}
- IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
+ IWL_DEBUG_STATS(priv, "Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
rx_status.signal, rx_status.noise, rx_status.qual,
rx_stats_sig_avg, rx_stats_noise_diff);
@@ -699,17 +680,14 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
network_packet = iwl3945_is_network_packet(priv, header);
- IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
+ IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
network_packet ? '*' : ' ',
le16_to_cpu(rx_hdr->channel),
rx_status.signal, rx_status.signal,
rx_status.noise, rx_status.rate_idx);
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_RX))
- /* Set "1" to report good data frames in groups of 100 */
- iwl3945_dbg_report_frame(priv, pkt, header, 1);
-#endif
+ /* Set "1" to report good data frames in groups of 100 */
+ iwl3945_dbg_report_frame(priv, pkt, header, 1);
if (network_packet) {
priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
@@ -721,24 +699,31 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
}
-int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
- dma_addr_t addr, u16 len)
+int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len, u8 reset, u8 pad)
{
int count;
- u32 pad;
- struct iwl3945_tfd_frame *tfd = (struct iwl3945_tfd_frame *)ptr;
+ struct iwl_queue *q;
+ struct iwl3945_tfd *tfd, *tfd_tmp;
+
+ q = &txq->q;
+ tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+ tfd = &tfd_tmp[q->write_ptr];
+
+ if (reset)
+ memset(tfd, 0, sizeof(*tfd));
count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
- pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags));
if ((count >= NUM_TFD_CHUNKS) || (count < 0)) {
- IWL_ERROR("Error can not send more than %d chunks\n",
+ IWL_ERR(priv, "Error can not send more than %d chunks\n",
NUM_TFD_CHUNKS);
return -EINVAL;
}
- tfd->pa[count].addr = cpu_to_le32(addr);
- tfd->pa[count].len = cpu_to_le32(len);
+ tfd->tbs[count].addr = cpu_to_le32(addr);
+ tfd->tbs[count].len = cpu_to_le32(len);
count++;
@@ -753,10 +738,11 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
*
* Does NOT advance any indexes
*/
-int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
+void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
- struct iwl3945_tfd_frame *bd_tmp = (struct iwl3945_tfd_frame *)&txq->bd[0];
- struct iwl3945_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
+ struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+ int index = txq->q.read_ptr;
+ struct iwl3945_tfd *tfd = &tfd_tmp[index];
struct pci_dev *dev = priv->pci_dev;
int i;
int counter;
@@ -764,21 +750,28 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *
/* classify bd */
if (txq->q.id == IWL_CMD_QUEUE_NUM)
/* nothing to cleanup after for host commands */
- return 0;
+ return;
/* sanity check */
- counter = TFD_CTL_COUNT_GET(le32_to_cpu(bd->control_flags));
+ counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
if (counter > NUM_TFD_CHUNKS) {
- IWL_ERROR("Too many chunks: %i\n", counter);
+ IWL_ERR(priv, "Too many chunks: %i\n", counter);
/* @todo issue fatal error, it is quite serious situation */
- return 0;
+ return;
}
+ /* Unmap tx_cmd */
+ if (counter)
+ pci_unmap_single(dev,
+ pci_unmap_addr(&txq->cmd[index]->meta, mapping),
+ pci_unmap_len(&txq->cmd[index]->meta, len),
+ PCI_DMA_TODEVICE);
+
/* unmap chunks if any */
for (i = 1; i < counter; i++) {
- pci_unmap_single(dev, le32_to_cpu(bd->pa[i].addr),
- le32_to_cpu(bd->pa[i].len), PCI_DMA_TODEVICE);
+ pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr),
+ le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE);
if (txq->txb[txq->q.read_ptr].skb[0]) {
struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0];
if (txq->txb[txq->q.read_ptr].skb[0]) {
@@ -788,10 +781,10 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *
}
}
}
- return 0;
+ return ;
}
-u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
+u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
{
int i, start = IWL_AP_ID;
int ret = IWL_INVALID_STATION;
@@ -802,18 +795,18 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
start = IWL_STA_ID;
if (is_broadcast_ether_addr(addr))
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
spin_lock_irqsave(&priv->sta_lock, flags);
- for (i = start; i < priv->hw_setting.max_stations; i++)
- if ((priv->stations[i].used) &&
+ for (i = start; i < priv->hw_params.max_stations; i++)
+ if ((priv->stations_39[i].used) &&
(!compare_ether_addr
- (priv->stations[i].sta.sta.addr, addr))) {
+ (priv->stations_39[i].sta.sta.addr, addr))) {
ret = i;
goto out;
}
- IWL_DEBUG_INFO("can not find STA %pM (total %d)\n",
+ IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n",
addr, priv->num_stations);
out:
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -824,12 +817,10 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
* iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
*
*/
-void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr, int sta_id, int tx_id)
{
- unsigned long flags;
u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
u16 rate_mask;
@@ -838,25 +829,15 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
u8 data_retry_limit;
__le32 tx_flags;
__le16 fc = hdr->frame_control;
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
rate = iwl3945_rates[rate_index].plcp;
- tx_flags = cmd->cmd.tx.tx_flags;
+ tx_flags = tx->tx_flags;
/* We need to figure out how to get the sta->supp_rates while
* in this running context */
rate_mask = IWL_RATES_MASK;
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- priv->stations[sta_id].current_rate.rate_n_flags = rate;
-
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
- (sta_id != priv->hw_setting.bcast_sta_id) &&
- (sta_id != IWL_MULTICAST_ID))
- priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate;
-
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
if (tx_id >= IWL_CMD_QUEUE_NUM)
rts_retry_limit = 3;
else
@@ -888,25 +869,25 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
}
}
- cmd->cmd.tx.rts_retry_limit = rts_retry_limit;
- cmd->cmd.tx.data_retry_limit = data_retry_limit;
- cmd->cmd.tx.rate = rate;
- cmd->cmd.tx.tx_flags = tx_flags;
+ tx->rts_retry_limit = rts_retry_limit;
+ tx->data_retry_limit = data_retry_limit;
+ tx->rate = rate;
+ tx->tx_flags = tx_flags;
/* OFDM */
- cmd->cmd.tx.supp_rates[0] =
+ tx->supp_rates[0] =
((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
/* CCK */
- cmd->cmd.tx.supp_rates[1] = (rate_mask & 0xF);
+ tx->supp_rates[1] = (rate_mask & 0xF);
- IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
+ IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
"cck/ofdm mask: 0x%x/0x%x\n", sta_id,
- cmd->cmd.tx.rate, le32_to_cpu(cmd->cmd.tx.tx_flags),
- cmd->cmd.tx.supp_rates[1], cmd->cmd.tx.supp_rates[0]);
+ tx->rate, le32_to_cpu(tx->tx_flags),
+ tx->supp_rates[1], tx->supp_rates[0]);
}
-u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags)
+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;
@@ -915,138 +896,133 @@ u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags
return IWL_INVALID_STATION;
spin_lock_irqsave(&priv->sta_lock, flags_spin);
- station = &priv->stations[sta_id];
+ station = &priv->stations_39[sta_id];
station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
station->sta.rate_n_flags = cpu_to_le16(tx_rate);
- station->current_rate.rate_n_flags = tx_rate;
station->sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- iwl3945_send_add_station(priv, &station->sta, flags);
- IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n",
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&station->sta, flags);
+ IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
sta_id, tx_rate);
return sta_id;
}
-static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max)
+static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
- int rc;
+ int ret;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
- if (rc) {
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
+ return ret;
}
- if (!pwr_max) {
- u32 val;
-
- rc = pci_read_config_dword(priv->pci_dev,
- PCI_POWER_SOURCE, &val);
- if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
- iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ 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);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
- iwl3945_poll_bit(priv, CSR_GPIO_IN,
+ iwl_poll_bit(priv, CSR_GPIO_IN,
CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
CSR_GPIO_IN_BIT_AUX_POWER, 5000);
- } else
- iwl3945_release_nic_access(priv);
+ } else {
+ iwl_release_nic_access(priv);
+ }
} else {
- iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~APMG_PS_CTRL_MSK_PWR_SRC);
- iwl3945_release_nic_access(priv);
- iwl3945_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_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 rc;
+ return ret;
}
-static int iwl3945_rx_init(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
+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 = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr);
- iwl3945_write_direct32(priv, FH_RCSR_RPTR_ADDR(0),
- priv->hw_setting.shared_phys +
- offsetof(struct iwl3945_shared, rx_read_ptr[0]));
- iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), 0);
- iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0),
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
- ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
- (RX_QUEUE_SIZE_LOG << ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
- (1 << ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
+ 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);
+ iwl_write_direct32(priv, FH39_RCSR_CONFIG(0),
+ FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
+ FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
+ FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
+ FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
+ (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
+ FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
+ (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
+ FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
/* fake read to flush all prev I/O */
- iwl3945_read_direct32(priv, FH_RSSR_CTRL);
+ iwl_read_direct32(priv, FH39_RSSR_CTRL);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-static int iwl3945_tx_reset(struct iwl3945_priv *priv)
+static int iwl3945_tx_reset(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
/* bypass mode */
- iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
+ iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
/* RA 0 is active */
- iwl3945_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
+ iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
/* all 6 fifo are active */
- iwl3945_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
-
- iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
- iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
- iwl3945_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
- iwl3945_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
-
- iwl3945_write_direct32(priv, FH_TSSR_CBB_BASE,
- priv->hw_setting.shared_phys);
-
- iwl3945_write_direct32(priv, FH_TSSR_MSG_CONFIG,
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
-
- iwl3945_release_nic_access(priv);
+ iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
+
+ iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
+ iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
+ iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
+ iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
+
+ iwl_write_direct32(priv, FH39_TSSR_CBB_BASE,
+ priv->shared_phys);
+
+ iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
+ 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;
@@ -1057,7 +1033,7 @@ static int iwl3945_tx_reset(struct iwl3945_priv *priv)
*
* Destroys all DMA structures and initialize them again
*/
-static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
+static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
{
int rc;
int txq_id, slots_num;
@@ -1073,10 +1049,10 @@ static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
- txq_id);
+ rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
+ txq_id);
if (rc) {
- IWL_ERROR("Tx %d queue init failed\n", txq_id);
+ IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
goto error;
}
}
@@ -1088,111 +1064,140 @@ static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
return rc;
}
-int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
+static int iwl3945_apm_init(struct iwl_priv *priv)
{
- u8 rev_id;
- int rc;
- unsigned long flags;
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ int ret = 0;
- iwl3945_power_init_handle(priv);
+ iwl_power_initialize(priv);
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL);
- iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- rc = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("Failed to init the card\n");
- return rc;
- }
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
- rc = iwl3945_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
+ /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+
+ /* set "initialization complete" bit to move adapter
+ * D0U* --> D0A* state */
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+ ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ if (ret < 0) {
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
+ goto out;
}
- iwl3945_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT |
- APMG_CLK_VAL_BSM_CLK_RQT);
+
+ 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);
+
udelay(20);
- iwl3945_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
- APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwl3945_release_nic_access(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("HW Revision ID = 0x%X\n", rev_id);
+ /* 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:
+ return ret;
+}
+
+static void iwl3945_nic_config(struct iwl_priv *priv)
+{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ unsigned long flags;
+ u8 rev_id = 0;
- iwl3945_nic_set_pwr_src(priv, 1);
spin_lock_irqsave(&priv->lock, flags);
if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
- IWL_DEBUG_INFO("RTP type \n");
+ IWL_DEBUG_INFO(priv, "RTP type \n");
else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
- IWL_DEBUG_INFO("3945 RADIO-MB type\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n");
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_3945_MB);
} else {
- IWL_DEBUG_INFO("3945 RADIO-MM type\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n");
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);
}
- if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) {
- IWL_DEBUG_INFO("SKU OP mode is mrc\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) {
+ IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n");
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);
} else
- IWL_DEBUG_INFO("SKU OP mode is basic\n");
+ IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n");
- if ((priv->eeprom.board_revision & 0xF0) == 0xD0) {
- IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
- priv->eeprom.board_revision);
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ if ((eeprom->board_revision & 0xF0) == 0xD0) {
+ IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
+ eeprom->board_revision);
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
} else {
- IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
- priv->eeprom.board_revision);
- iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+ IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
+ eeprom->board_revision);
+ iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
}
- if (priv->eeprom.almgor_m_version <= 1) {
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ if (eeprom->almgor_m_version <= 1) {
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
- IWL_DEBUG_INFO("Card M type A version is 0x%X\n",
- priv->eeprom.almgor_m_version);
+ IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n",
+ eeprom->almgor_m_version);
} else {
- IWL_DEBUG_INFO("Card M type B version is 0x%X\n",
- priv->eeprom.almgor_m_version);
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n",
+ eeprom->almgor_m_version);
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
}
spin_unlock_irqrestore(&priv->lock, flags);
- if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
- IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n");
+ if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
+ IWL_DEBUG_RF_KILL(priv, "SW RF KILL supported in EEPROM.\n");
+
+ if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
+ IWL_DEBUG_RF_KILL(priv, "HW RF KILL supported in EEPROM.\n");
+}
+
+int iwl3945_hw_nic_init(struct iwl_priv *priv)
+{
+ u8 rev_id;
+ int rc;
+ unsigned long flags;
+ struct iwl_rx_queue *rxq = &priv->rxq;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ 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;
- if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
- IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n");
+ priv->cfg->ops->lib->apm_ops.config(priv);
/* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) {
- rc = iwl3945_rx_queue_alloc(priv);
+ rc = iwl_rx_queue_alloc(priv);
if (rc) {
- IWL_ERROR("Unable to initialize Rx queue\n");
+ IWL_ERR(priv, "Unable to initialize Rx queue\n");
return -ENOMEM;
}
} else
- iwl3945_rx_queue_reset(priv, rxq);
+ iwl_rx_queue_reset(priv, rxq);
iwl3945_rx_replenish(priv);
@@ -1202,16 +1207,16 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
/* Look at using this instead:
rxq->need_update = 1;
- iwl3945_rx_queue_update_write_ptr(priv, rxq);
+ iwl_rx_queue_update_write_ptr(priv, rxq);
*/
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), rxq->write & ~7);
- iwl3945_release_nic_access(priv);
+ iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1229,116 +1234,121 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
*
* Destroy all TX DMA queues and structures
*/
-void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv)
+void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
{
int txq_id;
/* Tx queues */
for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
- iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
+ iwl_tx_queue_free(priv, txq_id);
}
-void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv)
+void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
{
- int queue;
+ int txq_id;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- if (iwl3945_grab_nic_access(priv)) {
+ if (iwl_grab_nic_access(priv)) {
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_free(priv);
return;
}
/* stop SCD */
- iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0);
+ iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
/* reset TFD queues */
- for (queue = TFD_QUEUE_MIN; queue < TFD_QUEUE_MAX; queue++) {
- iwl3945_write_direct32(priv, FH_TCSR_CONFIG(queue), 0x0);
- iwl3945_poll_direct_bit(priv, FH_TSSR_TX_STATUS,
- ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(queue),
+ for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
+ iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
+ iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
+ FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1000);
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_free(priv);
}
-int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv)
+static int iwl3945_apm_stop_master(struct iwl_priv *priv)
{
- int rc = 0;
- u32 reg_val;
+ int ret = 0;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
/* set stop master bit */
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
- reg_val = iwl3945_read32(priv, CSR_GP_CNTRL);
+ iwl_poll_direct_bit(priv, CSR_RESET,
+ CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE ==
- (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE))
- IWL_DEBUG_INFO("Card in power save, master is already "
- "stopped\n");
- else {
- rc = iwl3945_poll_direct_bit(priv, CSR_RESET,
- CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
- }
+ if (ret < 0)
+ goto out;
+out:
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("stop master\n");
+ IWL_DEBUG_INFO(priv, "stop master\n");
- return rc;
+ return ret;
+}
+
+static void iwl3945_apm_stop(struct iwl_priv *priv)
+{
+ 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);
+ /* clear "init complete" move adapter D0A* --> D0U state */
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
-int iwl3945_hw_nic_reset(struct iwl3945_priv *priv)
+static int iwl3945_apm_reset(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
- iwl3945_hw_nic_stop_master(priv);
+ iwl3945_apm_stop_master(priv);
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+ udelay(10);
+
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
+ iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (!rc) {
- iwl3945_write_prph(priv, APMG_CLK_CTRL_REG,
+ iwl_write_prph(priv, APMG_CLK_CTRL_REG,
APMG_CLK_VAL_BSM_CLK_RQT);
- udelay(10);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
- iwl3945_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
- iwl3945_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 */
- iwl3945_write_prph(priv, APMG_CLK_EN_REG,
+ iwl_write_prph(priv, APMG_CLK_EN_REG,
APMG_CLK_VAL_DMA_CLK_RQT |
APMG_CLK_VAL_BSM_CLK_RQT);
udelay(10);
- iwl3945_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);
- iwl3945_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+ iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
/* Clear the 'host command active' bit... */
@@ -1367,33 +1377,34 @@ static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
}
-int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
+int iwl3945_hw_get_temperature(struct iwl_priv *priv)
{
- return iwl3945_read32(priv, CSR_UCODE_DRV_GP2);
+ return iwl_read32(priv, CSR_UCODE_DRV_GP2);
}
/**
* iwl3945_hw_reg_txpower_get_temperature
* get the current temperature by reading from NIC
*/
-static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
+static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int temperature;
temperature = iwl3945_hw_get_temperature(priv);
/* driver's okay range is -260 to +25.
* human readable okay range is 0 to +285 */
- IWL_DEBUG_INFO("Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
+ IWL_DEBUG_INFO(priv, "Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
/* handle insane temp reading */
if (iwl3945_hw_reg_temp_out_of_range(temperature)) {
- IWL_ERROR("Error bad temperature value %d\n", temperature);
+ IWL_ERR(priv, "Error bad temperature value %d\n", temperature);
/* if really really hot(?),
* substitute the 3rd band/group's temp measured at factory */
if (priv->last_temperature > 100)
- temperature = priv->eeprom.groups[2].temperature;
+ temperature = eeprom->groups[2].temperature;
else /* else use most recent "sane" value from driver */
temperature = priv->last_temperature;
}
@@ -1412,7 +1423,7 @@ static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
* records new temperature in tx_mgr->temperature.
* replaces tx_mgr->last_temperature *only* if calib needed
* (assumes caller will actually do the calibration!). */
-static int is_temp_calib_needed(struct iwl3945_priv *priv)
+static int is_temp_calib_needed(struct iwl_priv *priv)
{
int temp_diff;
@@ -1421,20 +1432,20 @@ static int is_temp_calib_needed(struct iwl3945_priv *priv)
/* get absolute value */
if (temp_diff < 0) {
- IWL_DEBUG_POWER("Getting cooler, delta %d,\n", temp_diff);
+ IWL_DEBUG_POWER(priv, "Getting cooler, delta %d,\n", temp_diff);
temp_diff = -temp_diff;
} else if (temp_diff == 0)
- IWL_DEBUG_POWER("Same temp,\n");
+ IWL_DEBUG_POWER(priv, "Same temp,\n");
else
- IWL_DEBUG_POWER("Getting warmer, delta %d,\n", temp_diff);
+ IWL_DEBUG_POWER(priv, "Getting warmer, delta %d,\n", temp_diff);
/* if we don't need calibration, *don't* update last_temperature */
if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) {
- IWL_DEBUG_POWER("Timed thermal calib not needed\n");
+ IWL_DEBUG_POWER(priv, "Timed thermal calib not needed\n");
return 0;
}
- IWL_DEBUG_POWER("Timed thermal calib needed\n");
+ IWL_DEBUG_POWER(priv, "Timed thermal calib needed\n");
/* assume that caller will actually do calib ...
* update the "last temperature" value */
@@ -1627,9 +1638,9 @@ static inline u8 iwl3945_hw_reg_fix_power_index(int index)
* Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK)
* or 6 Mbit (OFDM) rates.
*/
-static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tbl_index,
+static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
s32 rate_index, const s8 *clip_pwrs,
- struct iwl3945_channel_info *ch_info,
+ struct iwl_channel_info *ch_info,
int band_index)
{
struct iwl3945_scan_power_info *scan_power_info;
@@ -1646,7 +1657,7 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tb
/* further limit to user's max power preference.
* FIXME: Other spectrum management power limitations do not
* seem to apply?? */
- power = min(power, priv->user_txpower_limit);
+ power = min(power, priv->tx_power_user_lmt);
scan_power_info->requested_power = power;
/* find difference between new scan *power* and current "normal"
@@ -1678,32 +1689,32 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tb
}
/**
- * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings
+ * iwl3945_send_tx_power - fill in Tx Power command with gain settings
*
* Configures power settings for all rates for the current channel,
* using values from channel info struct, and send to NIC
*/
-int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
+static int iwl3945_send_tx_power(struct iwl_priv *priv)
{
int rate_idx, i;
- const struct iwl3945_channel_info *ch_info = NULL;
+ const struct iwl_channel_info *ch_info = NULL;
struct iwl3945_txpowertable_cmd txpower = {
.channel = priv->active_rxon.channel,
};
txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
- ch_info = iwl3945_get_channel_info(priv,
+ ch_info = iwl_get_channel_info(priv,
priv->band,
le16_to_cpu(priv->active_rxon.channel));
if (!ch_info) {
- IWL_ERROR
- ("Failed to get channel info for channel %d [%d]\n",
- le16_to_cpu(priv->active_rxon.channel), priv->band);
+ IWL_ERR(priv,
+ "Failed to get channel info for channel %d [%d]\n",
+ le16_to_cpu(priv->active_rxon.channel), priv->band);
return -EINVAL;
}
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_POWER("Not calling TX_PWR_TABLE_CMD on "
+ IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on "
"non-Tx channel.\n");
return 0;
}
@@ -1711,12 +1722,12 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
/* fill cmd with power settings for all rates for current channel */
/* Fill OFDM rate */
for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0;
- rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) {
+ rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) {
txpower.power[i].tpc = ch_info->power_info[i].tpc;
txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
- IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
+ IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
le16_to_cpu(txpower.channel),
txpower.band,
txpower.power[i].tpc.tx_gain,
@@ -1729,7 +1740,7 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
txpower.power[i].tpc = ch_info->power_info[i].tpc;
txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
- IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
+ IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
le16_to_cpu(txpower.channel),
txpower.band,
txpower.power[i].tpc.tx_gain,
@@ -1737,8 +1748,9 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
txpower.power[i].rate);
}
- return iwl3945_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
- sizeof(struct iwl3945_txpowertable_cmd), &txpower);
+ return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
+ sizeof(struct iwl3945_txpowertable_cmd),
+ &txpower);
}
@@ -1758,8 +1770,8 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
* properly fill out the scan powers, and actual h/w gain settings,
* and send changes to NIC
*/
-static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
- struct iwl3945_channel_info *ch_info)
+static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv,
+ struct iwl_channel_info *ch_info)
{
struct iwl3945_channel_power_info *power_info;
int power_changed = 0;
@@ -1768,7 +1780,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
int power;
/* Get this chnlgrp's rate-to-max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* Get this channel's rate-to-current-power settings table */
power_info = ch_info->power_info;
@@ -1821,7 +1833,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
* based strictly on regulatory (eeprom and spectrum mgt) limitations
* (no consideration for h/w clipping limitations).
*/
-static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_info)
+static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
{
s8 max_power;
@@ -1849,9 +1861,10 @@ static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_i
*
* If RxOn is "associated", this sends the new Txpower to NIC!
*/
-static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
+static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
{
- struct iwl3945_channel_info *ch_info = NULL;
+ struct iwl_channel_info *ch_info = NULL;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int delta_index;
const s8 *clip_pwrs; /* array of h/w max power levels for each rate */
u8 a_band;
@@ -1867,7 +1880,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
a_band = is_channel_a_band(ch_info);
/* Get this chnlgrp's factory calibration temperature */
- ref_temp = (s16)priv->eeprom.groups[ch_info->group_index].
+ ref_temp = (s16)eeprom->groups[ch_info->group_index].
temperature;
/* get power index adjustment based on current and factory
@@ -1893,7 +1906,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
}
/* Get this chnlgrp's rate-to-max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */
for (scan_tbl_index = 0;
@@ -1907,24 +1920,24 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
}
/* send Txpower command for current channel to ucode */
- return iwl3945_hw_reg_send_txpower(priv);
+ return priv->cfg->ops->lib->send_tx_power(priv);
}
-int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
+int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
{
- struct iwl3945_channel_info *ch_info;
+ struct iwl_channel_info *ch_info;
s8 max_power;
u8 a_band;
u8 i;
- if (priv->user_txpower_limit == power) {
- IWL_DEBUG_POWER("Requested Tx power same as current "
+ if (priv->tx_power_user_lmt == power) {
+ IWL_DEBUG_POWER(priv, "Requested Tx power same as current "
"limit: %ddBm.\n", power);
return 0;
}
- IWL_DEBUG_POWER("Setting upper limit clamp to %ddBm.\n", power);
- priv->user_txpower_limit = power;
+ IWL_DEBUG_POWER(priv, "Setting upper limit clamp to %ddBm.\n", power);
+ priv->tx_power_user_lmt = power;
/* set up new Tx powers for each and every channel, 2.4 and 5.x */
@@ -1953,7 +1966,7 @@ int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
}
/* will add 3945 channel switch cmd handling later */
-int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
+int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
{
return 0;
}
@@ -1968,7 +1981,7 @@ int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
* -- send new set of gain settings to NIC
* NOTE: This should continue working, even when we're not associated,
* so we can keep our internal table of scan powers current. */
-void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
+void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
{
/* This will kick in the "brute force"
* iwl3945_hw_reg_comp_txpower_temp() below */
@@ -1987,7 +2000,7 @@ void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv,
+ struct iwl_priv *priv = container_of(work, struct iwl_priv,
thermal_periodic.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -2009,10 +2022,11 @@ static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
* on A-band, EEPROM's "group frequency" entries represent the top
* channel in each group 1-4. Group 5 All B/G channels are in group 0.
*/
-static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
- const struct iwl3945_channel_info *ch_info)
+static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
+ const struct iwl_channel_info *ch_info)
{
- struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0];
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0];
u8 group;
u16 group_index = 0; /* based on factory calib frequencies */
u8 grp_channel;
@@ -2032,7 +2046,7 @@ static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
} else
group_index = 0; /* 2.4 GHz, group 0 */
- IWL_DEBUG_POWER("Chnl %d mapped to grp %d\n", ch_info->channel,
+ IWL_DEBUG_POWER(priv, "Chnl %d mapped to grp %d\n", ch_info->channel,
group_index);
return group_index;
}
@@ -2043,11 +2057,12 @@ static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
* Interpolate to get nominal (i.e. at factory calibration temperature) index
* into radio/DSP gain settings table for requested power.
*/
-static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
+static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv,
s8 requested_power,
s32 setting_index, s32 *new_index)
{
const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
s32 index0, index1;
s32 power = 2 * requested_power;
s32 i;
@@ -2056,7 +2071,7 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
s32 res;
s32 denominator;
- chnl_grp = &priv->eeprom.groups[setting_index];
+ chnl_grp = &eeprom->groups[setting_index];
samples = chnl_grp->samples;
for (i = 0; i < 5; i++) {
if (power == samples[i].power) {
@@ -2091,22 +2106,23 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
return 0;
}
-static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
+static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
{
u32 i;
s32 rate_index;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
const struct iwl3945_eeprom_txpower_group *group;
- IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n");
+ IWL_DEBUG_POWER(priv, "Initializing factory calib info from EEPROM\n");
for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) {
s8 *clip_pwrs; /* table of power levels for each rate */
s8 satur_pwr; /* saturation power for each chnl group */
- group = &priv->eeprom.groups[i];
+ group = &eeprom->groups[i];
/* sanity check on factory saturation power value */
if (group->saturation_power < 40) {
- IWL_WARNING("Error: saturation power is %d, "
+ IWL_WARN(priv, "Error: saturation power is %d, "
"less than minimum expected 40\n",
group->saturation_power);
return;
@@ -2121,7 +2137,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
* power peaks, without too much distortion (clipping).
*/
/* we'll fill in this array with h/w max power levels */
- clip_pwrs = (s8 *) priv->clip_groups[i].clip_powers;
+ clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers;
/* divide factory saturation power by 2 to find -3dB level */
satur_pwr = (s8) (group->saturation_power >> 1);
@@ -2171,10 +2187,11 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
*
* This does *not* write values to NIC, just sets up our internal table.
*/
-int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
+int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
{
- struct iwl3945_channel_info *ch_info = NULL;
+ struct iwl_channel_info *ch_info = NULL;
struct iwl3945_channel_power_info *pwr_info;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int delta_index;
u8 rate_index;
u8 scan_tbl_index;
@@ -2204,15 +2221,15 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
/* Get this chnlgrp's rate->max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* calculate power index *adjustment* value according to
* diff between current temperature and factory temperature */
delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
- priv->eeprom.groups[ch_info->group_index].
+ eeprom->groups[ch_info->group_index].
temperature);
- IWL_DEBUG_POWER("Delta index for channel %d: %d [%d]\n",
+ IWL_DEBUG_POWER(priv, "Delta index for channel %d: %d [%d]\n",
ch_info->channel, delta_index, temperature +
IWL_TEMP_CONVERT);
@@ -2235,7 +2252,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
ch_info->group_index,
&power_idx);
if (rc) {
- IWL_ERROR("Invalid power index\n");
+ IWL_ERR(priv, "Invalid power index\n");
return rc;
}
pwr_info->base_power_index = (u8) power_idx;
@@ -2295,75 +2312,90 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
return 0;
}
-int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv)
+int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0);
- rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS,
- FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
+ iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
+ rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
+ FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
if (rc < 0)
- IWL_ERROR("Can't stop Rx DMA.\n");
+ IWL_ERR(priv, "Can't stop Rx DMA.\n");
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
+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->hw_setting.shared_virt;
+ 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 = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_CBCC_CTRL(txq_id), 0);
- iwl3945_write_direct32(priv, FH_CBCC_BASE(txq_id), 0);
+ iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
+ iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
- iwl3945_write_direct32(priv, FH_TCSR_CONFIG(txq_id),
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
- iwl3945_release_nic_access(priv);
+ iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id),
+ FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
+ FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
+ 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 */
- iwl3945_read32(priv, FH_TSSR_CBB_BASE);
+ iwl_read32(priv, FH39_TSSR_CBB_BASE);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv)
+/*
+ * HCMD utils
+ */
+static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
{
- struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
+ switch (cmd_id) {
+ case REPLY_RXON:
+ return sizeof(struct iwl3945_rxon_cmd);
+ case POWER_TABLE_CMD:
+ return sizeof(struct iwl3945_powertable_cmd);
+ default:
+ return len;
+ }
+}
- return le32_to_cpu(shared_data->rx_read_ptr[0]);
+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;
}
/**
* iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
*/
-int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
+int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
{
int rc, i, index, prev_index;
struct iwl3945_rate_scaling_cmd rate_cmd = {
@@ -2384,7 +2416,7 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
switch (priv->band) {
case IEEE80211_BAND_5GHZ:
- IWL_DEBUG_RATE("Select A mode rate scale\n");
+ IWL_DEBUG_RATE(priv, "Select A mode rate scale\n");
/* If one of the following CCK rates is used,
* have it fall back to the 6M OFDM rate */
for (i = IWL_RATE_1M_INDEX_TABLE;
@@ -2402,12 +2434,12 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
break;
case IEEE80211_BAND_2GHZ:
- IWL_DEBUG_RATE("Select B/G mode rate scale\n");
+ IWL_DEBUG_RATE(priv, "Select B/G mode rate scale\n");
/* If an OFDM rate is used, have it fall back to the
* 1M CCK rates */
if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
- iwl3945_is_associated(priv)) {
+ iwl_is_associated(priv)) {
index = IWL_FIRST_CCK_RATE;
for (i = IWL_RATE_6M_INDEX_TABLE;
@@ -2428,47 +2460,48 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
/* Update the rate scaling for control frame Tx */
rate_cmd.table_id = 0;
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+ rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
&rate_cmd);
if (rc)
return rc;
/* Update the rate scaling for data frame Tx */
rate_cmd.table_id = 1;
- return iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+ return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
&rate_cmd);
}
/* Called when initializing driver */
-int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv)
+int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
{
- memset((void *)&priv->hw_setting, 0,
- sizeof(struct iwl3945_driver_hw_info));
+ memset((void *)&priv->hw_params, 0,
+ sizeof(struct iwl_hw_params));
- priv->hw_setting.shared_virt =
+ priv->shared_virt =
pci_alloc_consistent(priv->pci_dev,
sizeof(struct iwl3945_shared),
- &priv->hw_setting.shared_phys);
+ &priv->shared_phys);
- if (!priv->hw_setting.shared_virt) {
- IWL_ERROR("failed to allocate pci memory\n");
+ if (!priv->shared_virt) {
+ IWL_ERR(priv, "failed to allocate pci memory\n");
mutex_unlock(&priv->mutex);
return -ENOMEM;
}
- priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE;
- priv->hw_setting.max_pkt_size = 2342;
- priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd);
- priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
- priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
- priv->hw_setting.max_stations = IWL3945_STATION_COUNT;
- priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID;
+ priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
+ priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
+ priv->hw_params.max_pkt_size = 2342;
+ priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
+ priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
+ priv->hw_params.max_stations = IWL3945_STATION_COUNT;
+ priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID;
+
+ priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
- priv->hw_setting.tx_ant_num = 2;
return 0;
}
-unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl3945_frame *frame, u8 rate)
{
struct iwl3945_tx_beacon_cmd *tx_beacon_cmd;
@@ -2477,7 +2510,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
- tx_beacon_cmd->tx.sta_id = priv->hw_setting.bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl3945_fill_beacon_frame(priv,
@@ -2501,37 +2534,262 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
}
-void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
+void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv)
{
priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
}
-void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv)
+void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv)
{
INIT_DELAYED_WORK(&priv->thermal_periodic,
iwl3945_bg_reg_txpower_periodic);
}
-void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv)
+void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv)
{
cancel_delayed_work(&priv->thermal_periodic);
}
-static struct iwl_3945_cfg iwl3945_bg_cfg = {
+/* check contents of special bootstrap uCode SRAM */
+static int iwl3945_verify_bsm(struct iwl_priv *priv)
+ {
+ __le32 *image = priv->ucode_boot.v_addr;
+ u32 len = priv->ucode_boot.len;
+ u32 reg;
+ u32 val;
+
+ IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
+
+ /* verify BSM SRAM contents */
+ val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
+ for (reg = BSM_SRAM_LOWER_BOUND;
+ reg < BSM_SRAM_LOWER_BOUND + len;
+ reg += sizeof(u32), image++) {
+ val = iwl_read_prph(priv, reg);
+ if (val != le32_to_cpu(*image)) {
+ IWL_ERR(priv, "BSM uCode verification failed at "
+ "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
+ BSM_SRAM_LOWER_BOUND,
+ reg - BSM_SRAM_LOWER_BOUND, len,
+ val, le32_to_cpu(*image));
+ return -EIO;
+ }
+ }
+
+ IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n");
+
+ return 0;
+}
+
+
+/******************************************************************************
+ *
+ * EEPROM related functions
+ *
+ ******************************************************************************/
+
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism. Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+ _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+ return 0;
+}
+
+
+static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+ return;
+}
+
+ /**
+ * iwl3945_load_bsm - Load bootstrap instructions
+ *
+ * BSM operation:
+ *
+ * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
+ * in special SRAM that does not power down during RFKILL. When powering back
+ * up after power-saving sleeps (or during initial uCode load), the BSM loads
+ * the bootstrap program into the on-board processor, and starts it.
+ *
+ * The bootstrap program loads (via DMA) instructions and data for a new
+ * program from host DRAM locations indicated by the host driver in the
+ * BSM_DRAM_* registers. Once the new program is loaded, it starts
+ * automatically.
+ *
+ * When initializing the NIC, the host driver points the BSM to the
+ * "initialize" uCode image. This uCode sets up some internal data, then
+ * notifies host via "initialize alive" that it is complete.
+ *
+ * The host then replaces the BSM_DRAM_* pointer values to point to the
+ * normal runtime uCode instructions and a backup uCode data cache buffer
+ * (filled initially with starting data values for the on-board processor),
+ * then triggers the "initialize" uCode to load and launch the runtime uCode,
+ * which begins normal operation.
+ *
+ * When doing a power-save shutdown, runtime uCode saves data SRAM into
+ * the backup data cache in DRAM before SRAM is powered down.
+ *
+ * When powering back up, the BSM loads the bootstrap program. This reloads
+ * the runtime uCode instructions and the backup data cache into SRAM,
+ * and re-launches the runtime uCode from where it left off.
+ */
+static int iwl3945_load_bsm(struct iwl_priv *priv)
+{
+ __le32 *image = priv->ucode_boot.v_addr;
+ u32 len = priv->ucode_boot.len;
+ dma_addr_t pinst;
+ dma_addr_t pdata;
+ u32 inst_len;
+ u32 data_len;
+ int rc;
+ int i;
+ u32 done;
+ u32 reg_offset;
+
+ IWL_DEBUG_INFO(priv, "Begin load bsm\n");
+
+ /* make sure bootstrap program is no larger than BSM's SRAM size */
+ if (len > IWL39_MAX_BSM_SIZE)
+ return -EINVAL;
+
+ /* Tell bootstrap uCode where to find the "Initialize" uCode
+ * in host DRAM ... host DRAM physical address bits 31:0 for 3945.
+ * NOTE: iwl3945_initialize_alive_start() will replace these values,
+ * after the "initialize" uCode has run, to point to
+ * runtime/protocol instructions and backup data cache. */
+ pinst = priv->ucode_init.p_addr;
+ pdata = priv->ucode_init_data.p_addr;
+ 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);
+ iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
+
+ /* Fill BSM memory with bootstrap instructions */
+ for (reg_offset = BSM_SRAM_LOWER_BOUND;
+ reg_offset < BSM_SRAM_LOWER_BOUND + len;
+ reg_offset += sizeof(u32), image++)
+ _iwl_write_prph(priv, reg_offset,
+ le32_to_cpu(*image));
+
+ rc = iwl3945_verify_bsm(priv);
+ if (rc) {
+ iwl_release_nic_access(priv);
+ return rc;
+ }
+
+ /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
+ iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
+ iwl_write_prph(priv, BSM_WR_MEM_DST_REG,
+ IWL39_RTC_INST_LOWER_BOUND);
+ iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
+
+ /* Load bootstrap code into instruction SRAM now,
+ * to prepare to load "initialize" uCode */
+ iwl_write_prph(priv, BSM_WR_CTRL_REG,
+ BSM_WR_CTRL_REG_BIT_START);
+
+ /* Wait for load of bootstrap uCode to finish */
+ for (i = 0; i < 100; i++) {
+ done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
+ if (!(done & BSM_WR_CTRL_REG_BIT_START))
+ break;
+ udelay(10);
+ }
+ if (i < 100)
+ IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i);
+ else {
+ IWL_ERR(priv, "BSM write did not complete!\n");
+ return -EIO;
+ }
+
+ /* Enable future boot loads whenever power management unit triggers it
+ * (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;
+}
+
+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,
+ .txq_init = iwl3945_hw_tx_queue_init,
+ .load_ucode = iwl3945_load_bsm,
+ .apm_ops = {
+ .init = iwl3945_apm_init,
+ .reset = iwl3945_apm_reset,
+ .stop = iwl3945_apm_stop,
+ .config = iwl3945_nic_config,
+ .set_pwr_src = iwl3945_set_pwr_src,
+ },
+ .eeprom_ops = {
+ .regulatory_bands = {
+ EEPROM_REGULATORY_BAND_1_CHANNELS,
+ EEPROM_REGULATORY_BAND_2_CHANNELS,
+ EEPROM_REGULATORY_BAND_3_CHANNELS,
+ EEPROM_REGULATORY_BAND_4_CHANNELS,
+ EEPROM_REGULATORY_BAND_5_CHANNELS,
+ EEPROM_REGULATORY_BAND_NO_FAT,
+ EEPROM_REGULATORY_BAND_NO_FAT,
+ },
+ .verify_signature = iwlcore_eeprom_verify_signature,
+ .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
+ .release_semaphore = iwl3945_eeprom_release_semaphore,
+ .query_addr = iwlcore_eeprom_query_addr,
+ },
+ .send_tx_power = iwl3945_send_tx_power,
+ .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
+};
+
+static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
+ .get_hcmd_size = iwl3945_get_hcmd_size,
+ .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
+};
+
+static struct iwl_ops iwl3945_ops = {
+ .lib = &iwl3945_lib,
+ .utils = &iwl3945_hcmd_utils,
+};
+
+static struct iwl_cfg iwl3945_bg_cfg = {
.name = "3945BG",
.fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_G,
+ .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+ .ops = &iwl3945_ops,
+ .mod_params = &iwl3945_mod_params
};
-static struct iwl_3945_cfg iwl3945_abg_cfg = {
+static struct iwl_cfg iwl3945_abg_cfg = {
.name = "3945ABG",
.fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
+ .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+ .ops = &iwl3945_ops,
+ .mod_params = &iwl3945_mod_params
};
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 2c0ddc5110c..ab7aaf6872c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -43,11 +43,13 @@
/* Hardware specific file defines the PCI IDs table for that hardware module */
extern struct pci_device_id iwl3945_hw_card_ids[];
-#define DRV_NAME "iwl3945"
#include "iwl-csr.h"
#include "iwl-prph.h"
+#include "iwl-fh.h"
#include "iwl-3945-hw.h"
-#include "iwl-3945-debug.h"
+#include "iwl-debug.h"
+#include "iwl-power.h"
+#include "iwl-dev.h"
#include "iwl-3945-led.h"
/* Highest firmware API version supported */
@@ -74,8 +76,7 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
/* Module parameters accessible from iwl-*.c */
-extern int iwl3945_param_hwcrypto;
-extern int iwl3945_param_queues_num;
+extern struct iwl_mod_params iwl3945_mod_params;
struct iwl3945_sta_priv {
struct iwl3945_rs_sta *rs_sta;
@@ -95,7 +96,6 @@ enum iwl3945_antenna {
* else RTS for data/management frames where MPDU is larger
* than RTS value.
*/
-#define IWL_RX_BUF_SIZE 3000U
#define DEFAULT_RTS_THRESHOLD 2347U
#define MIN_RTS_THRESHOLD 0U
#define MAX_RTS_THRESHOLD 2347U
@@ -105,136 +105,7 @@ enum iwl3945_antenna {
#define DEFAULT_SHORT_RETRY_LIMIT 7U
#define DEFAULT_LONG_RETRY_LIMIT 4U
-struct iwl3945_rx_mem_buffer {
- dma_addr_t dma_addr;
- struct sk_buff *skb;
- struct list_head list;
-};
-
-/*
- * Generic queue structure
- *
- * Contains common data for Rx and Tx queues
- */
-struct iwl3945_queue {
- int n_bd; /* number of BDs in this queue */
- int write_ptr; /* 1-st empty entry (index) host_w*/
- int read_ptr; /* last used entry (index) host_r*/
- dma_addr_t dma_addr; /* physical addr for BD's */
- int n_window; /* safe queue window */
- u32 id;
- int low_mark; /* low watermark, resume queue if free
- * space more than this */
- int high_mark; /* high watermark, stop queue if free
- * space less than this */
-} __attribute__ ((packed));
-
-int iwl3945_queue_space(const struct iwl3945_queue *q);
-int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i);
-
-#define MAX_NUM_OF_TBS (20)
-
-/* One for each TFD */
-struct iwl3945_tx_info {
- struct sk_buff *skb[MAX_NUM_OF_TBS];
-};
-
-/**
- * struct iwl3945_tx_queue - Tx Queue for DMA
- * @q: generic Rx/Tx queue descriptor
- * @bd: base of circular buffer of TFDs
- * @cmd: array of command/Tx buffers
- * @dma_addr_cmd: physical address of cmd/tx buffer array
- * @txb: array of per-TFD driver data
- * @need_update: indicates need to update read/write index
- *
- * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
- * descriptors) and required locking structures.
- */
-struct iwl3945_tx_queue {
- struct iwl3945_queue q;
- struct iwl3945_tfd_frame *bd;
- struct iwl3945_cmd *cmd;
- dma_addr_t dma_addr_cmd;
- struct iwl3945_tx_info *txb;
- int need_update;
- int active;
-};
-
-#define IWL_NUM_SCAN_RATES (2)
-
-struct iwl3945_channel_tgd_info {
- u8 type;
- s8 max_power;
-};
-
-struct iwl3945_channel_tgh_info {
- s64 last_radar_time;
-};
-
-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl3945_channel_power_info {
- struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 base_power_index; /* gain index for power at factory temp. */
- s8 requested_power; /* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl3945_scan_power_info {
- struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
-};
-
-/*
- * One for each channel, holds all channel setup data
- * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
- * with one another!
- */
-#define IWL4965_MAX_RATE (33)
-
-struct iwl3945_channel_info {
- struct iwl3945_channel_tgd_info tgd;
- struct iwl3945_channel_tgh_info tgh;
- struct iwl3945_eeprom_channel eeprom; /* EEPROM regulatory limit */
- struct iwl3945_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
- * FAT channel */
-
- u8 channel; /* channel number */
- u8 flags; /* flags copied from EEPROM */
- s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
- s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */
- s8 min_power; /* always 0 */
- s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */
-
- u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */
- u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */
- enum ieee80211_band band;
-
- /* Radio/DSP gain settings for each "normal" data Tx rate.
- * These include, in addition to RF and DSP gain, a few fields for
- * remembering/modifying gain settings (indexes). */
- struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
-
- /* Radio/DSP gain settings for each scan rate, for directed scans. */
- struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
-};
-
-struct iwl3945_clip_group {
- /* maximum power level to prevent clipping for each rate, derived by
- * us from this band's saturation power in EEPROM */
- const s8 clip_powers[IWL_MAX_RATES];
-};
-
-#include "iwl-3945-rs.h"
+#include "iwl-agn-rs.h"
#define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1
@@ -247,33 +118,6 @@ struct iwl3945_clip_group {
/* Minimum number of queues. MAX_NUM is defined in hw specific files */
#define IWL_MIN_NUM_QUEUES 4
-/* Power management (not Tx power) structures */
-
-struct iwl3945_power_vec_entry {
- struct iwl3945_powertable_cmd cmd;
- u8 no_dtim;
-};
-#define IWL_POWER_RANGE_0 (0)
-#define IWL_POWER_RANGE_1 (1)
-
-#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */
-#define IWL_POWER_INDEX_3 0x03
-#define IWL_POWER_INDEX_5 0x05
-#define IWL_POWER_AC 0x06
-#define IWL_POWER_BATTERY 0x07
-#define IWL_POWER_LIMIT 0x07
-#define IWL_POWER_MASK 0x0F
-#define IWL_POWER_ENABLED 0x10
-#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK)
-
-struct iwl3945_power_mgr {
- spinlock_t lock;
- struct iwl3945_power_vec_entry pwr_range_0[IWL_POWER_AC];
- struct iwl3945_power_vec_entry pwr_range_1[IWL_POWER_AC];
- u8 active_index;
- u32 dtim_val;
-};
-
#define IEEE80211_DATA_LEN 2304
#define IEEE80211_4ADDR_LEN 30
#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
@@ -289,81 +133,10 @@ struct iwl3945_frame {
struct list_head list;
};
-#define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf)
-#define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8)
-#define SEQ_TO_INDEX(x) ((u8)(x & 0xff))
-#define INDEX_TO_SEQ(x) ((u8)(x & 0xff))
-#define SEQ_HUGE_FRAME (0x4000)
-#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000)
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
-enum {
- /* CMD_SIZE_NORMAL = 0, */
- CMD_SIZE_HUGE = (1 << 0),
- /* CMD_SYNC = 0, */
- CMD_ASYNC = (1 << 1),
- /* CMD_NO_SKB = 0, */
- CMD_WANT_SKB = (1 << 2),
-};
-
-struct iwl3945_cmd;
-struct iwl3945_priv;
-
-struct iwl3945_cmd_meta {
- struct iwl3945_cmd_meta *source;
- union {
- struct sk_buff *skb;
- int (*callback)(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd, struct sk_buff *skb);
- } __attribute__ ((packed)) u;
-
- /* The CMD_SIZE_HUGE flag bit indicates that the command
- * structure is stored at the end of the shared queue memory. */
- u32 flags;
-
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_cmd
- *
- * For allocation of the command and tx queues, this establishes the overall
- * size of the largest command we send to uCode, except for a scan command
- * (which is relatively huge; space is allocated separately).
- */
-struct iwl3945_cmd {
- struct iwl3945_cmd_meta meta;
- struct iwl3945_cmd_header hdr;
- union {
- struct iwl3945_addsta_cmd addsta;
- struct iwl3945_led_cmd led;
- u32 flags;
- u8 val8;
- u16 val16;
- u32 val32;
- struct iwl3945_bt_cmd bt;
- struct iwl3945_rxon_time_cmd rxon_time;
- struct iwl3945_powertable_cmd powertable;
- struct iwl3945_qosparam_cmd qosparam;
- struct iwl3945_tx_cmd tx;
- struct iwl3945_tx_beacon_cmd tx_beacon;
- struct iwl3945_rxon_assoc_cmd rxon_assoc;
- u8 *indirect;
- u8 payload[360];
- } __attribute__ ((packed)) cmd;
-} __attribute__ ((packed));
-
-struct iwl3945_host_cmd {
- u8 id;
- u16 len;
- struct iwl3945_cmd_meta meta;
- const void *data;
-};
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
- sizeof(struct iwl3945_cmd_meta))
-
/*
* RX related structures and functions
*/
@@ -374,33 +147,6 @@ struct iwl3945_host_cmd {
#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
-/**
- * struct iwl3945_rx_queue - Rx queue
- * @processed: Internal index to last handled Rx packet
- * @read: Shared index to newest available Rx buffer
- * @write: Shared index to oldest written Rx packet
- * @free_count: Number of pre-allocated buffers in rx_free
- * @rx_free: list of free SKBs for use
- * @rx_used: List of Rx buffers with no SKB
- * @need_update: flag to indicate we need to update read/write index
- *
- * NOTE: rx_free and rx_used are used as a FIFO for iwl3945_rx_mem_buffers
- */
-struct iwl3945_rx_queue {
- __le32 *bd;
- dma_addr_t dma_addr;
- struct iwl3945_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
- struct iwl3945_rx_mem_buffer *queue[RX_QUEUE_SIZE];
- u32 processed;
- u32 read;
- u32 write;
- u32 free_count;
- struct list_head rx_free;
- struct list_head rx_used;
- int need_update;
- spinlock_t lock;
-};
-
#define IWL_SUPPORTED_RATES_IE_LEN 8
#define SCAN_INTERVAL 100
@@ -430,87 +176,9 @@ struct iwl3945_rx_queue {
#define IWL_INVALID_RATE 0xFF
#define IWL_INVALID_VALUE -1
-struct iwl3945_tid_data {
- u16 seq_number;
-};
-
-struct iwl3945_hw_key {
- enum ieee80211_key_alg alg;
- int keylen;
- u8 key[32];
-};
-
-union iwl3945_ht_rate_supp {
- u16 rates;
- struct {
- u8 siso_rate;
- u8 mimo_rate;
- };
-};
-
-union iwl3945_qos_capabity {
- struct {
- u8 edca_count:4; /* bit 0-3 */
- u8 q_ack:1; /* bit 4 */
- u8 queue_request:1; /* bit 5 */
- u8 txop_request:1; /* bit 6 */
- u8 reserved:1; /* bit 7 */
- } q_AP;
- struct {
- u8 acvo_APSD:1; /* bit 0 */
- u8 acvi_APSD:1; /* bit 1 */
- u8 ac_bk_APSD:1; /* bit 2 */
- u8 ac_be_APSD:1; /* bit 3 */
- u8 q_ack:1; /* bit 4 */
- u8 max_len:2; /* bit 5-6 */
- u8 more_data_ack:1; /* bit 7 */
- } q_STA;
- u8 val;
-};
-
-/* QoS structures */
-struct iwl3945_qos_info {
- int qos_active;
- union iwl3945_qos_capabity qos_cap;
- struct iwl3945_qosparam_cmd def_qos_parm;
-};
-
#define STA_PS_STATUS_WAKE 0
#define STA_PS_STATUS_SLEEP 1
-struct iwl3945_station_entry {
- struct iwl3945_addsta_cmd sta;
- struct iwl3945_tid_data tid[MAX_TID_COUNT];
- union {
- struct {
- u8 rate;
- u8 flags;
- } s;
- u16 rate_n_flags;
- } current_rate;
- u8 used;
- u8 ps_status;
- struct iwl3945_hw_key keyinfo;
-};
-
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_desc {
- void *v_addr; /* access by driver */
- dma_addr_t p_addr; /* access by card's busmaster DMA */
- u32 len; /* bytes */
-};
-
-/* uCode file layout */
-struct iwl3945_ucode {
- __le32 ver; /* major/minor/API/serial */
- __le32 inst_size; /* bytes of runtime instructions */
- __le32 data_size; /* bytes of runtime data */
- __le32 init_size; /* bytes of initialization instructions */
- __le32 init_data_size; /* bytes of initialization data */
- __le32 boot_size; /* bytes of bootstrap instructions */
- u8 data[0]; /* data in same order as "size" elements */
-};
-
struct iwl3945_ibss_seq {
u8 mac[ETH_ALEN];
u16 seq_num;
@@ -519,34 +187,6 @@ struct iwl3945_ibss_seq {
struct list_head list;
};
-/**
- * struct iwl3945_driver_hw_info
- * @max_txq_num: Max # Tx queues supported
- * @tx_cmd_len: Size of Tx command (but not including frame itself)
- * @tx_ant_num: Number of TX antennas
- * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
- * @rx_buf_size:
- * @max_pkt_size:
- * @max_rxq_log: Log-base-2 of max_rxq_size
- * @max_stations:
- * @bcast_sta_id:
- * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status
- * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status
- */
-struct iwl3945_driver_hw_info {
- u16 max_txq_num;
- u16 tx_cmd_len;
- u16 tx_ant_num;
- u16 max_rxq_size;
- u32 rx_buf_size;
- u32 max_pkt_size;
- u16 max_rxq_log;
- u8 max_stations;
- u8 bcast_sta_id;
- void *shared_virt;
- dma_addr_t shared_phys;
-};
-
#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\
x->u.rx_frame.stats.payload + \
x->u.rx_frame.stats.phy_count))
@@ -564,40 +204,30 @@ struct iwl3945_driver_hw_info {
*
*****************************************************************************/
struct iwl3945_addsta_cmd;
-extern int iwl3945_send_add_station(struct iwl3945_priv *priv,
+extern int iwl3945_send_add_station(struct iwl_priv *priv,
struct iwl3945_addsta_cmd *sta, u8 flags);
-extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid,
+extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
int is_ap, u8 flags);
-extern int iwl3945_power_init_handle(struct iwl3945_priv *priv);
-extern int iwl3945_eeprom_init(struct iwl3945_priv *priv);
-extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv);
-extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv,
- struct iwl3945_rx_queue *rxq);
+extern int iwl3945_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);
extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
-extern int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, int count, u32 id);
+extern int iwl3945_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq, int count, u32 id);
extern void iwl3945_rx_replenish(void *data);
-extern void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
-extern int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len,
+extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
const void *data);
-extern int __must_check iwl3945_send_cmd(struct iwl3945_priv *priv,
- struct iwl3945_host_cmd *cmd);
-extern unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv,
+ struct iwl_host_cmd *cmd);
+extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,int left);
-extern int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_rx_queue *q);
-extern int iwl3945_send_statistics_request(struct iwl3945_priv *priv);
-extern void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
- u32 decrypt_res,
- struct ieee80211_rx_status *stats);
-extern const u8 iwl3945_broadcast_addr[ETH_ALEN];
/*
* Currently used by iwl-3945-rs... look at restructuring so that it doesn't
* call this... todo... fix that.
*/
-extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id,
+extern u8 iwl3945_sync_station(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
/******************************************************************************
@@ -616,36 +246,37 @@ extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id,
* iwl3945_mac_ <-- mac80211 callback
*
****************************************************************************/
-extern void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv);
-extern void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv);
-extern void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv);
-extern int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv);
-extern int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_init(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv);
-extern void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv);
-extern void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_reset(struct iwl3945_priv *priv);
-extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *tfd,
- dma_addr_t addr, u16 len);
-extern int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
-extern int iwl3945_hw_get_temperature(struct iwl3945_priv *priv);
-extern int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq);
-extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv);
+extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv);
+extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv);
+extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv);
+extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_init(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv);
+extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv);
+extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_reset(struct iwl_priv *priv);
+extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len,
+ u8 reset, u8 pad);
+extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+extern int iwl3945_hw_get_temperature(struct iwl_priv *priv);
+extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl3945_frame *frame, u8 rate);
-extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv);
-extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr,
int sta_id, int tx_id);
-extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv);
-extern int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power);
-extern void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb);
-extern void iwl3945_disable_events(struct iwl3945_priv *priv);
-extern int iwl4965_get_temperature(const struct iwl3945_priv *priv);
+extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
+extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
+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);
/**
* iwl3945_hw_find_station - Find station id for a given BSSID
@@ -655,302 +286,26 @@ extern int iwl4965_get_temperature(const struct iwl3945_priv *priv);
* not yet been merged into a single common layer for managing the
* station tables.
*/
-extern u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *bssid);
+extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
-extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
+extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel);
/*
* Forward declare iwl-3945.c functions for iwl-base.c
*/
-extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
-extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
-extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
-extern int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv);
-extern u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id,
+extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
+extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
+extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
+extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv);
+extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
+extern const struct iwl_channel_info *iwl3945_get_channel_info(
+ const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-
-enum {
- MEASUREMENT_READY = (1 << 0),
- MEASUREMENT_ACTIVE = (1 << 1),
-};
-
-#endif
-
-#ifdef CONFIG_IWL3945_RFKILL
-struct iwl3945_priv;
-
-void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv);
-void iwl3945_rfkill_unregister(struct iwl3945_priv *priv);
-int iwl3945_rfkill_init(struct iwl3945_priv *priv);
-#else
-static inline void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) {}
-static inline void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) {}
-static inline int iwl3945_rfkill_init(struct iwl3945_priv *priv) { return 0; }
-#endif
-
-#define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES
-
-struct iwl3945_priv {
-
- /* ieee device used by generic ieee processing code */
- struct ieee80211_hw *hw;
- struct ieee80211_channel *ieee_channels;
- struct ieee80211_rate *ieee_rates;
- struct iwl_3945_cfg *cfg; /* device configuration */
-
- /* temporary frame storage list */
- struct list_head free_frames;
- int frames_count;
-
- enum ieee80211_band band;
- int alloc_rxb_skb;
-
- void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb);
-
- struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
-
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
- /* spectrum measurement report caching */
- struct iwl3945_spectrum_notification measure_report;
- u8 measurement_status;
-#endif
- /* ucode beacon time */
- u32 ucode_beacon_time;
-
- /* we allocate array of iwl3945_channel_info for NIC's valid channels.
- * Access via channel # using indirect index array */
- struct iwl3945_channel_info *channel_info; /* channel info array */
- u8 channel_count; /* # of channels */
-
- /* each calibration channel group in the EEPROM has a derived
- * clip setting for each rate. */
- const struct iwl3945_clip_group clip_groups[5];
-
- /* thermal calibration */
- s32 temperature; /* degrees Kelvin */
- s32 last_temperature;
-
- /* Scan related variables */
- unsigned long last_scan_jiffies;
- unsigned long next_scan_jiffies;
- unsigned long scan_start;
- unsigned long scan_pass_start;
- unsigned long scan_start_tsf;
- int scan_bands;
- int one_direct_scan;
- u8 direct_ssid_len;
- u8 direct_ssid[IW_ESSID_MAX_SIZE];
- struct iwl3945_scan_cmd *scan;
-
- /* spinlock */
- spinlock_t lock; /* protect general shared data */
- spinlock_t hcmd_lock; /* protect hcmd */
- struct mutex mutex;
-
- /* basic pci-network driver stuff */
- struct pci_dev *pci_dev;
-
- /* pci hardware address support */
- void __iomem *hw_base;
-
- /* uCode images, save to reload in case of failure */
- u32 ucode_ver; /* ucode version, copy of
- iwl3945_ucode.ver */
- struct fw_desc ucode_code; /* runtime inst */
- struct fw_desc ucode_data; /* runtime data original */
- struct fw_desc ucode_data_backup; /* runtime data save/restore */
- struct fw_desc ucode_init; /* initialization inst */
- struct fw_desc ucode_init_data; /* initialization data */
- struct fw_desc ucode_boot; /* bootstrap inst */
-
-
- struct iwl3945_rxon_time_cmd rxon_timing;
-
- /* We declare this const so it can only be
- * changed via explicit cast within the
- * routines that actually update the physical
- * hardware */
- const struct iwl3945_rxon_cmd active_rxon;
- struct iwl3945_rxon_cmd staging_rxon;
-
- int error_recovering;
- struct iwl3945_rxon_cmd recovery_rxon;
-
- /* 1st responses from initialize and runtime uCode images.
- * 4965's initialize alive response contains some calibration data. */
- struct iwl3945_init_alive_resp card_alive_init;
- struct iwl3945_alive_resp card_alive;
-
-#ifdef CONFIG_IWL3945_RFKILL
- struct rfkill *rfkill;
-#endif
-
-#ifdef CONFIG_IWL3945_LEDS
- struct iwl3945_led led[IWL_LED_TRG_MAX];
- unsigned long last_blink_time;
- u8 last_blink_rate;
- u8 allow_blinking;
- unsigned int rxtxpackets;
- u64 led_tpt;
-#endif
-
-
- u16 active_rate;
- u16 active_rate_basic;
-
- u32 sta_supp_rates;
-
- u8 call_post_assoc_from_beacon;
- /* Rate scaling data */
- s8 data_retry_limit;
- u8 retry_rate;
-
- wait_queue_head_t wait_command_queue;
-
- int activity_timer_active;
-
- /* Rx and Tx DMA processing queues */
- struct iwl3945_rx_queue rxq;
- struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES];
-
- unsigned long status;
-
- int last_rx_rssi; /* From Rx packet statisitics */
- int last_rx_noise; /* From beacon statistics */
-
- struct iwl3945_power_mgr power_data;
-
- struct iwl3945_notif_statistics statistics;
- unsigned long last_statistics_time;
-
- /* context information */
- u16 rates_mask;
-
- u32 power_mode;
- u32 antenna;
- u8 bssid[ETH_ALEN];
- u16 rts_threshold;
- u8 mac_addr[ETH_ALEN];
-
- /*station table variables */
- spinlock_t sta_lock;
- int num_stations;
- struct iwl3945_station_entry stations[IWL_STATION_COUNT];
-
- /* Indication if ieee80211_ops->open has been called */
- u8 is_open;
+extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
- u8 mac80211_registered;
-
- /* Rx'd packet timing information */
- u32 last_beacon_time;
- u64 last_tsf;
-
- /* eeprom */
- struct iwl3945_eeprom eeprom;
-
- enum nl80211_iftype iw_mode;
-
- struct sk_buff *ibss_beacon;
-
- /* Last Rx'd beacon timestamp */
- u32 timestamp0;
- u32 timestamp1;
- u16 beacon_int;
- struct iwl3945_driver_hw_info hw_setting;
- struct ieee80211_vif *vif;
-
- /* Current association information needed to configure the
- * hardware */
- u16 assoc_id;
- u16 assoc_capability;
- u8 ps_mode;
-
- struct iwl3945_qos_info qos_data;
-
- struct workqueue_struct *workqueue;
-
- struct work_struct up;
- struct work_struct restart;
- struct work_struct calibrated_work;
- struct work_struct scan_completed;
- struct work_struct rx_replenish;
- struct work_struct rf_kill;
- struct work_struct abort_scan;
- struct work_struct update_link_led;
- struct work_struct auth_work;
- struct work_struct report_work;
- struct work_struct request_scan;
- struct work_struct beacon_update;
-
- struct tasklet_struct irq_tasklet;
-
- struct delayed_work init_alive_start;
- struct delayed_work alive_start;
- struct delayed_work activity_timer;
- struct delayed_work thermal_periodic;
- struct delayed_work gather_stats;
- struct delayed_work scan_check;
-
-#define IWL_DEFAULT_TX_POWER 0x0F
- s8 user_txpower_limit;
- s8 max_channel_txpower_limit;
-
-
-#ifdef CONFIG_IWL3945_DEBUG
- /* debugging info */
- u32 framecnt_to_us;
- atomic_t restrict_refcnt;
-#endif
-}; /*iwl3945_priv */
-
-static inline int iwl3945_is_associated(struct iwl3945_priv *priv)
-{
- return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
-}
-
-static inline int is_channel_valid(const struct iwl3945_channel_info *ch_info)
-{
- if (ch_info == NULL)
- return 0;
- return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
-}
-
-static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info)
-{
- return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
-}
-
-static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info)
-{
- return ch_info->band == IEEE80211_BAND_5GHZ;
-}
-
-static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info)
-{
- return ch_info->band == IEEE80211_BAND_2GHZ;
-}
-
-static inline int is_channel_passive(const struct iwl3945_channel_info *ch)
-{
- return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0;
-}
-
-static inline int is_channel_ibss(const struct iwl3945_channel_info *ch)
-{
- return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
-}
-
-extern const struct iwl3945_channel_info *iwl3945_get_channel_info(
- const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel);
-
-extern int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate);
-
-/* Requires full declaration of iwl3945_priv before including */
-#include "iwl-3945-io.h"
+/* Requires full declaration of iwl_priv before including */
+#include "iwl-io.h"
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 6649f7b5565..a71a489096f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -89,64 +89,43 @@
#define LONG_SLOT_TIME 20
/* RSSI to dBm */
-#define IWL_RSSI_OFFSET 44
-
+#define IWL49_RSSI_OFFSET 44
/* PCI registers */
#define PCI_CFG_RETRY_TIMEOUT 0x041
-#define PCI_CFG_POWER_SOURCE 0x0C8
-#define PCI_REG_WUM8 0x0E8
-#define PCI_CFG_LINK_CTRL 0x0F0
/* PCI register values */
#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
-#define PCI_CFG_CMD_REG_INT_DIS_MSK 0x04
-#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
-
#define IWL_NUM_SCAN_RATES (2)
#define IWL_DEFAULT_TX_RETRY 15
-#define RX_QUEUE_SIZE 256
-#define RX_QUEUE_MASK 255
-#define RX_QUEUE_SIZE_LOG 8
-
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
-/* Size of one Rx buffer in host DRAM */
-#define IWL_RX_BUF_SIZE_4K (4 * 1024)
-#define IWL_RX_BUF_SIZE_8K (8 * 1024)
/* Sizes and addresses for instruction and data memory (SRAM) in
* 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */
-#define RTC_INST_LOWER_BOUND (0x000000)
+#define IWL49_RTC_INST_LOWER_BOUND (0x000000)
#define IWL49_RTC_INST_UPPER_BOUND (0x018000)
-#define RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL49_RTC_DATA_LOWER_BOUND (0x800000)
#define IWL49_RTC_DATA_UPPER_BOUND (0x80A000)
-#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - \
+ IWL49_RTC_INST_LOWER_BOUND)
+#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - \
+ IWL49_RTC_DATA_LOWER_BOUND)
-#define IWL_MAX_INST_SIZE IWL49_RTC_INST_SIZE
-#define IWL_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
+#define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE
+#define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
/* Size of uCode instruction memory in bootstrap state machine */
-#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE
+#define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE
static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
+ return (addr >= IWL49_RTC_DATA_LOWER_BOUND) &&
(addr < IWL49_RTC_DATA_UPPER_BOUND);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 5a72bc0377d..bd0140be774 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -76,7 +76,7 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv)
u32 reg;
u32 val;
- IWL_DEBUG_INFO("Begin verify bsm\n");
+ IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
/* verify BSM SRAM contents */
val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
@@ -85,7 +85,7 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv)
reg += sizeof(u32), image++) {
val = iwl_read_prph(priv, reg);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("BSM uCode verification failed at "
+ IWL_ERR(priv, "BSM uCode verification failed at "
"addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
BSM_SRAM_LOWER_BOUND,
reg - BSM_SRAM_LOWER_BOUND, len,
@@ -94,7 +94,7 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv)
}
}
- IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
+ IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n");
return 0;
}
@@ -144,12 +144,12 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
u32 reg_offset;
int ret;
- IWL_DEBUG_INFO("Begin load bsm\n");
+ IWL_DEBUG_INFO(priv, "Begin load bsm\n");
priv->ucode_type = UCODE_RT;
/* make sure bootstrap program is no larger than BSM's SRAM size */
- if (len > IWL_MAX_BSM_SIZE)
+ if (len > IWL49_MAX_BSM_SIZE)
return -EINVAL;
/* Tell bootstrap uCode where to find the "Initialize" uCode
@@ -186,7 +186,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
- iwl_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND);
+ iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND);
iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
/* Load bootstrap code into instruction SRAM now,
@@ -201,9 +201,9 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
udelay(10);
}
if (i < 100)
- IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
+ IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i);
else {
- IWL_ERROR("BSM write did not complete!\n");
+ IWL_ERR(priv, "BSM write did not complete!\n");
return -EIO;
}
@@ -257,7 +257,7 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
+ IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
return ret;
}
@@ -279,7 +279,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
goto restart;
}
@@ -289,7 +289,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
if (iwl_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
goto restart;
}
@@ -299,11 +299,11 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
/* Send pointers to protocol/runtime uCode image ... init code will
* load and launch runtime uCode, which will send us another "Alive"
* notification. */
- IWL_DEBUG_INFO("Initialization Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
if (iwl4965_set_ucode_ptrs(priv)) {
/* Runtime instruction load won't happen;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
+ IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
goto restart;
}
return;
@@ -354,7 +354,7 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
goto out;
}
@@ -381,27 +381,20 @@ out:
static void iwl4965_nic_config(struct iwl_priv *priv)
{
unsigned long flags;
- u32 val;
u16 radio_cfg;
- u16 link;
+ u16 lctl;
spin_lock_irqsave(&priv->lock, flags);
- if ((priv->rev_id & 0x80) == 0x80 && (priv->rev_id & 0x7f) < 8) {
- pci_read_config_dword(priv->pci_dev, PCI_REG_WUM8, &val);
- /* Enable No Snoop field */
- pci_write_config_dword(priv->pci_dev, PCI_REG_WUM8,
- val & ~(1 << 11));
- }
-
- pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
+ lctl = iwl_pcie_link_ctl(priv);
- /* L1 is enabled by BIOS */
- if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
- /* disable L0S disabled L1A enabled */
+ /* HW bug W/A - negligible power consumption */
+ /* L1-ASPM is enabled by BIOS */
+ if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
+ /* L1-ASPM enabled: disable L0S */
iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
else
- /* L0S enabled L1A disabled */
+ /* L1-ASPM disabled: enable L0S */
iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
@@ -437,7 +430,7 @@ static int iwl4965_apm_stop_master(struct iwl_priv *priv)
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("stop master\n");
+ IWL_DEBUG_INFO(priv, "stop master\n");
return 0;
}
@@ -523,9 +516,10 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
cmd.diff_gain_c = 0;
if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd))
- IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+ IWL_ERR(priv,
+ "Could not send REPLY_PHY_CALIBRATION_CMD\n");
data->state = IWL_CHAIN_NOISE_ACCUMULATE;
- IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
+ IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
}
}
@@ -557,7 +551,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
data->delta_gain_code[i] = 0;
}
}
- IWL_DEBUG_CALIB("delta_gain_codes: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "delta_gain_codes: a %d b %d c %d\n",
data->delta_gain_code[0],
data->delta_gain_code[1],
data->delta_gain_code[2]);
@@ -575,7 +569,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd);
if (ret)
- IWL_DEBUG_CALIB("fail sending cmd "
+ IWL_DEBUG_CALIB(priv, "fail sending cmd "
"REPLY_PHY_CALIBRATION_CMD \n");
/* TODO we might want recalculate
@@ -668,7 +662,7 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
txq->sched_retry = scd_retry;
- IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
+ IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
active ? "Activate" : "Deactivate",
scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
}
@@ -804,8 +798,9 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
(priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
return -EINVAL;
}
@@ -813,6 +808,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
+ priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -820,6 +816,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ);
+ priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
priv->hw_params.tx_chains_num = 2;
priv->hw_params.rx_chains_num = 2;
priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
@@ -902,7 +900,6 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel)
channel <= CALIB_IWL_TX_ATTEN_GR4_LCH)
return CALIB_CH_GROUP_4;
- IWL_ERROR("Can't find txatten group for channel %d.\n", channel);
return -1;
}
@@ -956,7 +953,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
s = iwl4965_get_sub_band(priv, channel);
if (s >= EEPROM_TX_POWER_BANDS) {
- IWL_ERROR("Tx Power can not find channel %d\n", channel);
+ IWL_ERR(priv, "Tx Power can not find channel %d\n", channel);
return -1;
}
@@ -964,7 +961,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
ch_i2 = priv->calib_info->band_info[s].ch2.ch_num;
chan_info->ch_num = (u8) channel;
- IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n",
+ IWL_DEBUG_TXPOWER(priv, "channel %d subband %d factory cal ch %d & %d\n",
channel, s, ch_i1, ch_i2);
for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
@@ -994,19 +991,19 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
m1->pa_det, ch_i2,
m2->pa_det);
- IWL_DEBUG_TXPOWER
- ("chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,
- m1->actual_pow, m2->actual_pow, omeas->actual_pow);
- IWL_DEBUG_TXPOWER
- ("chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,
- m1->gain_idx, m2->gain_idx, omeas->gain_idx);
- IWL_DEBUG_TXPOWER
- ("chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,
- m1->pa_det, m2->pa_det, omeas->pa_det);
- IWL_DEBUG_TXPOWER
- ("chain %d meas %d T1=%d T2=%d T=%d\n", c, m,
- m1->temperature, m2->temperature,
- omeas->temperature);
+ IWL_DEBUG_TXPOWER(priv,
+ "chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,
+ m1->actual_pow, m2->actual_pow, omeas->actual_pow);
+ IWL_DEBUG_TXPOWER(priv,
+ "chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,
+ m1->gain_idx, m2->gain_idx, omeas->gain_idx);
+ IWL_DEBUG_TXPOWER(priv,
+ "chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,
+ m1->pa_det, m2->pa_det, omeas->pa_det);
+ IWL_DEBUG_TXPOWER(priv,
+ "chain %d meas %d T1=%d T2=%d T=%d\n", c, m,
+ m1->temperature, m2->temperature,
+ omeas->temperature);
}
}
@@ -1303,12 +1300,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
s32 factory_actual_pwr[2];
s32 power_index;
- /* user_txpower_limit is in dBm, convert to half-dBm (half-dB units
+ /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units
* are used for indexing into txpower table) */
user_target_power = 2 * priv->tx_power_user_lmt;
/* Get current (RXON) channel, band, width */
- IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,
+ IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_fat %d\n", channel, band,
is_fat);
ch_info = iwl_get_channel_info(priv, priv->band, channel);
@@ -1319,10 +1316,13 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* get txatten group, used to select 1) thermal txpower adjustment
* and 2) mimo txpower balance between Tx chains. */
txatten_grp = iwl4965_get_tx_atten_grp(channel);
- if (txatten_grp < 0)
+ if (txatten_grp < 0) {
+ IWL_ERR(priv, "Can't find txatten group for channel %d.\n",
+ channel);
return -EINVAL;
+ }
- IWL_DEBUG_TXPOWER("channel %d belongs to txatten group %d\n",
+ IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n",
channel, txatten_grp);
if (is_fat) {
@@ -1372,7 +1372,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
voltage_compensation =
iwl4965_get_voltage_compensation(voltage, init_voltage);
- IWL_DEBUG_TXPOWER("curr volt %d eeprom volt %d volt comp %d\n",
+ IWL_DEBUG_TXPOWER(priv, "curr volt %d eeprom volt %d volt comp %d\n",
init_voltage,
voltage, voltage_compensation);
@@ -1403,13 +1403,13 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
factory_gain_index[c] = measurement->gain_idx;
factory_actual_pwr[c] = measurement->actual_pow;
- IWL_DEBUG_TXPOWER("chain = %d\n", c);
- IWL_DEBUG_TXPOWER("fctry tmp %d, "
+ IWL_DEBUG_TXPOWER(priv, "chain = %d\n", c);
+ IWL_DEBUG_TXPOWER(priv, "fctry tmp %d, "
"curr tmp %d, comp %d steps\n",
factory_temp, current_temp,
temperature_comp[c]);
- IWL_DEBUG_TXPOWER("fctry idx %d, fctry pwr %d\n",
+ IWL_DEBUG_TXPOWER(priv, "fctry idx %d, fctry pwr %d\n",
factory_gain_index[c],
factory_actual_pwr[c]);
}
@@ -1442,7 +1442,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
if (target_power > power_limit)
target_power = power_limit;
- IWL_DEBUG_TXPOWER("rate %d sat %d reg %d usr %d tgt %d\n",
+ IWL_DEBUG_TXPOWER(priv, "rate %d sat %d reg %d usr %d tgt %d\n",
i, saturation_power - back_off_table[i],
current_regulatory, user_target_power,
target_power);
@@ -1466,7 +1466,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
voltage_compensation +
atten_value);
-/* IWL_DEBUG_TXPOWER("calculated txpower index %d\n",
+/* IWL_DEBUG_TXPOWER(priv, "calculated txpower index %d\n",
power_index); */
if (power_index < get_min_power_index(i, band))
@@ -1483,12 +1483,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* stay within the table! */
if (power_index > 107) {
- IWL_WARNING("txpower index %d > 107\n",
+ IWL_WARN(priv, "txpower index %d > 107\n",
power_index);
power_index = 107;
}
if (power_index < 0) {
- IWL_WARNING("txpower index %d < 0\n",
+ IWL_WARN(priv, "txpower index %d < 0\n",
power_index);
power_index = 0;
}
@@ -1499,7 +1499,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
tx_power.s.dsp_predis_atten[c] =
gain_table[band][power_index].dsp;
- IWL_DEBUG_TXPOWER("chain %d mimo %d index %d "
+ IWL_DEBUG_TXPOWER(priv, "chain %d mimo %d index %d "
"gain 0x%02x dsp %d\n",
c, atten_value, power_index,
tx_power.s.radio_tx_gain[c],
@@ -1531,7 +1531,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
/* If this gets hit a lot, switch it to a BUG() and catch
* the stack trace to find out who is calling this during
* a scan. */
- IWL_WARNING("TX Power requested while scanning!\n");
+ IWL_WARN(priv, "TX Power requested while scanning!\n");
return -EAGAIN;
}
@@ -1574,7 +1574,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
rxon2->ofdm_ht_dual_stream_basic_rates) &&
(rxon1->rx_chain == rxon2->rx_chain) &&
(rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n");
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
return 0;
}
@@ -1631,7 +1631,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_fat,
ctrl_chan_high, &cmd.tx_power);
if (rc) {
- IWL_DEBUG_11H("error:%d fill txpower_tbl\n", rc);
+ IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc);
return rc;
}
@@ -1696,13 +1696,13 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
(priv->statistics.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)) {
- IWL_DEBUG_TEMP("Running FAT temperature calibration\n");
+ IWL_DEBUG_TEMP(priv, "Running FAT temperature calibration\n");
R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]);
R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]);
} else {
- IWL_DEBUG_TEMP("Running temperature calibration\n");
+ IWL_DEBUG_TEMP(priv, "Running temperature calibration\n");
R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]);
R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]);
R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]);
@@ -1722,10 +1722,10 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
vt = sign_extend(
le32_to_cpu(priv->statistics.general.temperature), 23);
- IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
+ IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
if (R3 == R1) {
- IWL_ERROR("Calibration conflict R1 == R3\n");
+ IWL_ERR(priv, "Calibration conflict R1 == R3\n");
return -1;
}
@@ -1735,7 +1735,7 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
temperature /= (R3 - R1);
temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
- IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n",
+ IWL_DEBUG_TEMP(priv, "Calibrated temperature: %dK, %dC\n",
temperature, KELVIN_TO_CELSIUS(temperature));
return temperature;
@@ -1758,7 +1758,7 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
int temp_diff;
if (!test_bit(STATUS_STATISTICS, &priv->status)) {
- IWL_DEBUG_TEMP("Temperature not updated -- no statistics.\n");
+ IWL_DEBUG_TEMP(priv, "Temperature not updated -- no statistics.\n");
return 0;
}
@@ -1766,19 +1766,19 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
/* get absolute value */
if (temp_diff < 0) {
- IWL_DEBUG_POWER("Getting cooler, delta %d, \n", temp_diff);
+ IWL_DEBUG_POWER(priv, "Getting cooler, delta %d, \n", temp_diff);
temp_diff = -temp_diff;
} else if (temp_diff == 0)
- IWL_DEBUG_POWER("Same temp, \n");
+ IWL_DEBUG_POWER(priv, "Same temp, \n");
else
- IWL_DEBUG_POWER("Getting warmer, delta %d, \n", temp_diff);
+ IWL_DEBUG_POWER(priv, "Getting warmer, delta %d, \n", temp_diff);
if (temp_diff < IWL_TEMPERATURE_THRESHOLD) {
- IWL_DEBUG_POWER("Thermal txpower calib not needed\n");
+ IWL_DEBUG_POWER(priv, "Thermal txpower calib not needed\n");
return 0;
}
- IWL_DEBUG_POWER("Thermal txpower calib needed\n");
+ IWL_DEBUG_POWER(priv, "Thermal txpower calib needed\n");
return 1;
}
@@ -1793,12 +1793,12 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv)
if (priv->temperature != temp) {
if (priv->temperature)
- IWL_DEBUG_TEMP("Temperature changed "
+ IWL_DEBUG_TEMP(priv, "Temperature changed "
"from %dC to %dC\n",
KELVIN_TO_CELSIUS(priv->temperature),
KELVIN_TO_CELSIUS(temp));
else
- IWL_DEBUG_TEMP("Temperature "
+ IWL_DEBUG_TEMP(priv, "Temperature "
"initialized to %dC\n",
KELVIN_TO_CELSIUS(temp));
}
@@ -1837,7 +1837,8 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL49_FIRST_AMPDU_QUEUE,
IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1908,7 +1909,8 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL49_FIRST_AMPDU_QUEUE,
IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1986,8 +1988,8 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
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;
- addsta->reserved1 = __constant_cpu_to_le16(0);
- addsta->reserved2 = __constant_cpu_to_le32(0);
+ addsta->reserved1 = cpu_to_le16(0);
+ addsta->reserved2 = cpu_to_le32(0);
return (u16)sizeof(struct iwl4965_addsta_cmd);
}
@@ -2013,7 +2015,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
int i, sh, idx;
u16 seq;
if (agg->wait_for_ba)
- IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
+ IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
@@ -2027,7 +2029,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
idx = start_idx;
/* FIXME: code repetition */
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
@@ -2038,9 +2040,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
/* FIXME: code repetition end */
- IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+ IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
agg->wait_for_ba = 0;
} else {
@@ -2060,21 +2062,21 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
AGG_TX_STATE_ABORT_MSK))
continue;
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
agg->frame_count, txq_id, idx);
hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
sc = le16_to_cpu(hdr->seq_ctrl);
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
- IWL_ERROR("BUG_ON idx doesn't match seq control"
- " idx=%d, seq_idx=%d, seq=%d\n",
- idx, SEQ_TO_SN(sc),
- hdr->seq_ctrl);
+ IWL_ERR(priv,
+ "BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n",
+ idx, SEQ_TO_SN(sc), hdr->seq_ctrl);
return -1;
}
- IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
i, idx, SEQ_TO_SN(sc));
sh = idx - start;
@@ -2092,13 +2094,13 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
sh = 0;
}
bitmap |= 1ULL << sh;
- IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
+ IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
start, (unsigned long long)bitmap);
}
agg->bitmap = bitmap;
agg->start_idx = start;
- IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+ IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
@@ -2129,7 +2131,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
u8 *qc = NULL;
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -2147,7 +2149,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
sta_id = iwl_get_ra_sta_id(priv, hdr);
if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
- IWL_ERROR("Station not known\n");
+ IWL_ERR(priv, "Station not known\n");
return;
}
@@ -2167,7 +2169,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (txq->q.read_ptr != (scd_ssn & 0xff)) {
index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
- IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
+ IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
"%d index %d\n", scd_ssn , index);
freed = iwl_tx_queue_reclaim(priv, txq_id, index);
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
@@ -2190,7 +2192,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);
- IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) "
+ IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) "
"rate_n_flags 0x%x retries %d\n",
txq_id,
iwl_get_tx_fail_reason(status), status,
@@ -2210,7 +2212,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
static int iwl4965_calc_rssi(struct iwl_priv *priv,
@@ -2238,13 +2240,13 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
if (valid_antennae & (1 << i))
max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
- IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+ IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
- return max_rssi - agc - IWL_RSSI_OFFSET;
+ return max_rssi - agc - IWL49_RSSI_OFFSET;
}
@@ -2287,6 +2289,9 @@ static struct iwl_lib_ops iwl4965_lib = {
.txq_set_sched = iwl4965_txq_set_sched,
.txq_agg_enable = iwl4965_txq_agg_enable,
.txq_agg_disable = iwl4965_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 = iwl4965_rx_handler_setup,
.setup_deferred_work = iwl4965_setup_deferred_work,
.cancel_deferred_work = iwl4965_cancel_deferred_work,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 82c3859ce0f..15cac70e36e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -68,10 +68,16 @@
#ifndef __iwl_5000_hw_h__
#define __iwl_5000_hw_h__
+#define IWL50_RTC_INST_LOWER_BOUND (0x000000)
#define IWL50_RTC_INST_UPPER_BOUND (0x020000)
+
+#define IWL50_RTC_DATA_LOWER_BOUND (0x800000)
#define IWL50_RTC_DATA_UPPER_BOUND (0x80C000)
-#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+
+#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - \
+ IWL50_RTC_INST_LOWER_BOUND)
+#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - \
+ IWL50_RTC_DATA_LOWER_BOUND)
/* EEPROM */
#define IWL_5000_EEPROM_IMG_SIZE 2048
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 66d053d28a7..08c19bea71e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -43,10 +43,11 @@
#include "iwl-sta.h"
#include "iwl-helpers.h"
#include "iwl-5000-hw.h"
+#include "iwl-6000-hw.h"
/* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 1
-#define IWL5150_UCODE_API_MAX 1
+#define IWL5150_UCODE_API_MAX 2
/* Lowest firmware API version supported */
#define IWL5000_UCODE_API_MIN 1
@@ -84,7 +85,7 @@ static int iwl5000_apm_stop_master(struct iwl_priv *priv)
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("stop master\n");
+ IWL_DEBUG_INFO(priv, "stop master\n");
return 0;
}
@@ -108,7 +109,8 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
- iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+ if (priv->cfg->need_pll_cfg)
+ iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
/* set "initialization complete" bit to move adapter
* D0U* --> D0A* state */
@@ -118,7 +120,7 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
return ret;
}
@@ -176,7 +178,8 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
/* FIXME: put here L1A -L0S w/a */
- iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+ if (priv->cfg->need_pll_cfg)
+ iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
/* set "initialization complete" bit to move adapter
* D0U* --> D0A* state */
@@ -186,7 +189,7 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
goto out;
}
@@ -216,18 +219,19 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
{
unsigned long flags;
u16 radio_cfg;
- u16 link;
+ u16 lctl;
spin_lock_irqsave(&priv->lock, flags);
- pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
+ lctl = iwl_pcie_link_ctl(priv);
- /* L1 is enabled by BIOS */
- if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
- /* disable L0S disabled L1A enabled */
+ /* HW bug W/A */
+ /* L1-ASPM is enabled by BIOS */
+ if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
+ /* L1-APSM enabled: disable L0S */
iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
else
- /* L0S enabled L1A disabled */
+ /* L1-ASPM disabled: enable L0S */
iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
@@ -289,7 +293,7 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
break;
default:
- IWL_ERROR("illegal indirect type: 0x%X\n",
+ IWL_ERR(priv, "illegal indirect type: 0x%X\n",
address & INDIRECT_TYPE_MSK);
break;
}
@@ -338,7 +342,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
data->delta_gain_code[i] |= (1 << 2);
}
- IWL_DEBUG_CALIB("Delta gains: ANT_B = %d ANT_C = %d\n",
+ IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d ANT_C = %d\n",
data->delta_gain_code[1], data->delta_gain_code[2]);
if (!data->radio_write) {
@@ -384,13 +388,14 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd);
if (ret)
- IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+ IWL_ERR(priv,
+ "Could not send REPLY_PHY_CALIBRATION_CMD\n");
data->state = IWL_CHAIN_NOISE_ACCUMULATE;
- IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
+ IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
}
}
-static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
__le32 *tx_flags)
{
if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
@@ -507,7 +512,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
index = IWL_CALIB_BASE_BAND;
break;
default:
- IWL_ERROR("Unknown calibration notification %d\n",
+ IWL_ERR(priv, "Unknown calibration notification %d\n",
hdr->op_code);
return;
}
@@ -517,7 +522,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
- IWL_DEBUG_INFO("Init. calibration is completed, restarting fw.\n");
+ IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
queue_work(priv->workqueue, &priv->restart);
}
@@ -580,40 +585,41 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
{
int ret = 0;
- ret = iwl5000_load_section(priv, inst_image, RTC_INST_LOWER_BOUND);
+ ret = iwl5000_load_section(priv, inst_image,
+ IWL50_RTC_INST_LOWER_BOUND);
if (ret)
return ret;
- IWL_DEBUG_INFO("INST uCode section being loaded...\n");
+ IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
priv->ucode_write_complete, 5 * HZ);
if (ret == -ERESTARTSYS) {
- IWL_ERROR("Could not load the INST uCode section due "
+ IWL_ERR(priv, "Could not load the INST uCode section due "
"to interrupt\n");
return ret;
}
if (!ret) {
- IWL_ERROR("Could not load the INST uCode section\n");
+ IWL_ERR(priv, "Could not load the INST uCode section\n");
return -ETIMEDOUT;
}
priv->ucode_write_complete = 0;
ret = iwl5000_load_section(
- priv, data_image, RTC_DATA_LOWER_BOUND);
+ priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
if (ret)
return ret;
- IWL_DEBUG_INFO("DATA uCode section being loaded...\n");
+ IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n");
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
priv->ucode_write_complete, 5 * HZ);
if (ret == -ERESTARTSYS) {
- IWL_ERROR("Could not load the INST uCode section due "
+ IWL_ERR(priv, "Could not load the INST uCode section due "
"to interrupt\n");
return ret;
} else if (!ret) {
- IWL_ERROR("Could not load the DATA uCode section\n");
+ IWL_ERR(priv, "Could not load the DATA uCode section\n");
return -ETIMEDOUT;
} else
ret = 0;
@@ -629,20 +635,20 @@ static int iwl5000_load_ucode(struct iwl_priv *priv)
/* check whether init ucode should be loaded, or rather runtime ucode */
if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
- IWL_DEBUG_INFO("Init ucode found. Loading init ucode...\n");
+ IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
ret = iwl5000_load_given_ucode(priv,
&priv->ucode_init, &priv->ucode_init_data);
if (!ret) {
- IWL_DEBUG_INFO("Init ucode load complete.\n");
+ IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
priv->ucode_type = UCODE_INIT;
}
} else {
- IWL_DEBUG_INFO("Init ucode not found, or already loaded. "
+ IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
"Loading runtime ucode...\n");
ret = iwl5000_load_given_ucode(priv,
&priv->ucode_code, &priv->ucode_data);
if (!ret) {
- IWL_DEBUG_INFO("Runtime ucode load complete.\n");
+ IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
priv->ucode_type = UCODE_RT;
}
}
@@ -658,7 +664,7 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv)
if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
goto restart;
}
@@ -668,14 +674,15 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv)
if (iwl_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
goto restart;
}
iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
- IWL_WARNING("Could not complete ALIVE transition: %d\n", ret);
+ IWL_WARN(priv,
+ "Could not complete ALIVE transition: %d\n", ret);
goto restart;
}
@@ -710,7 +717,7 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
txq->sched_retry = scd_retry;
- IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
+ IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
active ? "Activate" : "Deactivate",
scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
}
@@ -824,8 +831,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
{
if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
(priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
return -EINVAL;
}
@@ -833,70 +841,62 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
+ priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
- priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
- priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
+
+ switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+ case CSR_HW_REV_TYPE_6x00:
+ case CSR_HW_REV_TYPE_6x50:
+ priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
+ priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
+ break;
+ default:
+ priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
+ priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
+ }
+
priv->hw_params.max_bsm_size = 0;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
+ priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
priv->hw_params.sens = &iwl5000_sensitivity;
- switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
- case CSR_HW_REV_TYPE_5100:
- priv->hw_params.tx_chains_num = 1;
- priv->hw_params.rx_chains_num = 2;
- priv->hw_params.valid_tx_ant = ANT_B;
- priv->hw_params.valid_rx_ant = ANT_AB;
- break;
- case CSR_HW_REV_TYPE_5150:
- priv->hw_params.tx_chains_num = 1;
- priv->hw_params.rx_chains_num = 2;
- priv->hw_params.valid_tx_ant = ANT_A;
- priv->hw_params.valid_rx_ant = ANT_AB;
- break;
- case CSR_HW_REV_TYPE_5300:
- case CSR_HW_REV_TYPE_5350:
- priv->hw_params.tx_chains_num = 3;
- priv->hw_params.rx_chains_num = 3;
- priv->hw_params.valid_tx_ant = ANT_ABC;
- priv->hw_params.valid_rx_ant = ANT_ABC;
- break;
- }
+ priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
+ priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
+ priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
+ priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
- case CSR_HW_REV_TYPE_5100:
- case CSR_HW_REV_TYPE_5300:
- case CSR_HW_REV_TYPE_5350:
- /* 5X00 and 5350 wants in Celsius */
- priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
- break;
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;
}
/* Set initial calibration set */
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
- case CSR_HW_REV_TYPE_5100:
- case CSR_HW_REV_TYPE_5300:
- case CSR_HW_REV_TYPE_5350:
+ case CSR_HW_REV_TYPE_5150:
priv->hw_params.calib_init_cfg =
- BIT(IWL_CALIB_XTAL) |
+ BIT(IWL_CALIB_DC) |
BIT(IWL_CALIB_LO) |
BIT(IWL_CALIB_TX_IQ) |
- BIT(IWL_CALIB_TX_IQ_PERD) |
BIT(IWL_CALIB_BASE_BAND);
+
break;
- case CSR_HW_REV_TYPE_5150:
+ default:
priv->hw_params.calib_init_cfg =
- BIT(IWL_CALIB_DC) |
+ BIT(IWL_CALIB_XTAL) |
BIT(IWL_CALIB_LO) |
BIT(IWL_CALIB_TX_IQ) |
+ BIT(IWL_CALIB_TX_IQ_PERD) |
BIT(IWL_CALIB_BASE_BAND);
-
break;
}
@@ -1011,7 +1011,8 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL50_FIRST_AMPDU_QUEUE,
IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1076,7 +1077,8 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL50_FIRST_AMPDU_QUEUE,
IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1104,7 +1106,7 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
return 0;
}
-static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+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);
@@ -1142,7 +1144,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
u16 seq;
if (agg->wait_for_ba)
- IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
+ IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
@@ -1156,7 +1158,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
idx = start_idx;
/* FIXME: code repetition */
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
@@ -1168,9 +1170,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
/* FIXME: code repetition end */
- IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+ IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
agg->wait_for_ba = 0;
} else {
@@ -1190,21 +1192,22 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
AGG_TX_STATE_ABORT_MSK))
continue;
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
agg->frame_count, txq_id, idx);
hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
sc = le16_to_cpu(hdr->seq_ctrl);
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
- IWL_ERROR("BUG_ON idx doesn't match seq control"
- " idx=%d, seq_idx=%d, seq=%d\n",
+ IWL_ERR(priv,
+ "BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n",
idx, SEQ_TO_SN(sc),
hdr->seq_ctrl);
return -1;
}
- IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
i, idx, SEQ_TO_SN(sc));
sh = idx - start;
@@ -1222,13 +1225,13 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
sh = 0;
}
bitmap |= 1ULL << sh;
- IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
+ IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
start, (unsigned long long)bitmap);
}
agg->bitmap = bitmap;
agg->start_idx = start;
- IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+ IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
@@ -1254,7 +1257,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
int freed;
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -1281,7 +1284,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
if (txq->q.read_ptr != (scd_ssn & 0xff)) {
index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
- IWL_DEBUG_TX_REPLY("Retry scheduler reclaim "
+ IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim "
"scd_ssn=%d idx=%d txq=%d swq=%d\n",
scd_ssn , index, txq_id, txq->swq_id);
@@ -1308,7 +1311,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);
- IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) rate_n_flags "
+ IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
"0x%x retries %d\n",
txq_id,
iwl_get_tx_fail_reason(status), status,
@@ -1328,11 +1331,11 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
/* Currently 5000 is the superset of everything */
-static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
+u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
{
return len;
}
@@ -1356,7 +1359,7 @@ static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
static int iwl5000_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
+ return (addr >= IWL50_RTC_DATA_LOWER_BOUND) &&
(addr < IWL50_RTC_DATA_UPPER_BOUND);
}
@@ -1379,7 +1382,7 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
(rxon1->acquisition_data == rxon2->acquisition_data) &&
(rxon1->rx_chain == rxon2->rx_chain) &&
(rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n");
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
return 0;
}
@@ -1409,12 +1412,19 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
static int iwl5000_send_tx_power(struct iwl_priv *priv)
{
struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
+ u8 tx_ant_cfg_cmd;
/* half dBm need to multiply */
tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
- return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD,
+
+ if (IWL_UCODE_API(priv->ucode_ver) == 1)
+ tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
+ else
+ tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
+
+ return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
sizeof(tx_power_cmd), &tx_power_cmd,
NULL);
}
@@ -1426,7 +1436,7 @@ static void iwl5000_temperature(struct iwl_priv *priv)
}
/* Calc max signal level (dBm) among 3 possible receivers */
-static int iwl5000_calc_rssi(struct iwl_priv *priv,
+int iwl5000_calc_rssi(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp)
{
/* data from PHY/DSP regarding signal strength, etc.,
@@ -1455,19 +1465,19 @@ static int iwl5000_calc_rssi(struct iwl_priv *priv,
max_rssi = max_t(u32, rssi_a, rssi_b);
max_rssi = max_t(u32, max_rssi, rssi_c);
- IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+ IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
rssi_a, rssi_b, rssi_c, max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
- return max_rssi - agc - IWL_RSSI_OFFSET;
+ return max_rssi - agc - IWL49_RSSI_OFFSET;
}
-static struct iwl_hcmd_ops iwl5000_hcmd = {
+struct iwl_hcmd_ops iwl5000_hcmd = {
.rxon_assoc = iwl5000_send_rxon_assoc,
};
-static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
+struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
.get_hcmd_size = iwl5000_get_hcmd_size,
.build_addsta_hcmd = iwl5000_build_addsta_hcmd,
.gain_computation = iwl5000_gain_computation,
@@ -1476,13 +1486,16 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
.calc_rssi = iwl5000_calc_rssi,
};
-static struct iwl_lib_ops iwl5000_lib = {
+struct iwl_lib_ops iwl5000_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,
@@ -1517,13 +1530,13 @@ static struct iwl_lib_ops iwl5000_lib = {
},
};
-static struct iwl_ops iwl5000_ops = {
+struct iwl_ops iwl5000_ops = {
.lib = &iwl5000_lib,
.hcmd = &iwl5000_hcmd,
.utils = &iwl5000_hcmd_utils,
};
-static struct iwl_mod_params iwl50_mod_params = {
+struct iwl_mod_params iwl50_mod_params = {
.num_of_queues = IWL50_NUM_QUEUES,
.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
.amsdu_size_8K = 1,
@@ -1543,6 +1556,9 @@ struct iwl_cfg iwl5300_agn_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5100_bg_cfg = {
@@ -1556,6 +1572,9 @@ struct iwl_cfg iwl5100_bg_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5100_abg_cfg = {
@@ -1569,6 +1588,9 @@ struct iwl_cfg iwl5100_abg_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5100_agn_cfg = {
@@ -1582,6 +1604,9 @@ struct iwl_cfg iwl5100_agn_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5350_agn_cfg = {
@@ -1595,6 +1620,9 @@ struct iwl_cfg iwl5350_agn_cfg = {
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5150_agn_cfg = {
@@ -1608,6 +1636,9 @@ struct iwl_cfg iwl5150_agn_cfg = {
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
};
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-core.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 6f463555402..90185777d98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,47 +58,24 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
*****************************************************************************/
+/*
+ * Please use this file (iwl-6000-hw.h) only for hardware-related definitions.
+ * Use iwl-5000-commands.h for uCode API definitions.
+ */
-#ifndef __iwl_3945_dev_h__
-#define __iwl_3945_dev_h__
-
-#define IWL_PCI_DEVICE(dev, subdev, cfg) \
- .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
- .driver_data = (kernel_ulong_t)&(cfg)
+#ifndef __iwl_6000_hw_h__
+#define __iwl_6000_hw_h__
-#define IWL_SKU_G 0x1
-#define IWL_SKU_A 0x2
+#define IWL60_RTC_INST_LOWER_BOUND (0x000000)
+#define IWL60_RTC_INST_UPPER_BOUND (0x040000)
+#define IWL60_RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL60_RTC_DATA_UPPER_BOUND (0x814000)
+#define IWL60_RTC_INST_SIZE \
+ (IWL60_RTC_INST_UPPER_BOUND - IWL60_RTC_INST_LOWER_BOUND)
+#define IWL60_RTC_DATA_SIZE \
+ (IWL60_RTC_DATA_UPPER_BOUND - IWL60_RTC_DATA_LOWER_BOUND)
-/**
- * struct iwl_3945_cfg
- * @fw_name_pre: Firmware filename prefix. The api version and extension
- * (.ucode) will be added to filename before loading from disk. The
- * filename is constructed as fw_name_pre<api>.ucode.
- * @ucode_api_max: Highest version of uCode API supported by driver.
- * @ucode_api_min: Lowest version of uCode API supported by driver.
- *
- * We enable the driver to be backward compatible wrt API version. The
- * driver specifies which APIs it supports (with @ucode_api_max being the
- * highest and @ucode_api_min the lowest). Firmware will only be loaded if
- * it has a supported API version. The firmware's API version will be
- * stored in @iwl_priv, enabling the driver to make runtime changes based
- * on firmware version used.
- *
- * For example,
- * if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
- * Driver interacts with Firmware API version >= 2.
- * } else {
- * Driver interacts with Firmware API version 1.
- * }
- */
-struct iwl_3945_cfg {
- const char *name;
- const char *fw_name_pre;
- const unsigned int ucode_api_max;
- const unsigned int ucode_api_min;
- unsigned int sku;
-};
+#endif /* __iwl_6000_hw_h__ */
-#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
new file mode 100644
index 00000000000..edfa5e149f7
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -0,0 +1,158 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+/* Highest firmware API version supported */
+#define IWL6000_UCODE_API_MAX 2
+#define IWL6050_UCODE_API_MAX 2
+
+/* Lowest firmware API version supported */
+#define IWL6000_UCODE_API_MIN 1
+#define IWL6050_UCODE_API_MIN 1
+
+#define IWL6000_FW_PRE "iwlwifi-6000-"
+#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
+#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
+
+#define IWL6050_FW_PRE "iwlwifi-6050-"
+#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
+#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
+
+static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
+ .get_hcmd_size = iwl5000_get_hcmd_size,
+ .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
+ .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
+ .calc_rssi = iwl5000_calc_rssi,
+};
+
+static struct iwl_ops iwl6000_ops = {
+ .lib = &iwl5000_lib,
+ .hcmd = &iwl5000_hcmd,
+ .utils = &iwl6000_hcmd_utils,
+};
+
+struct iwl_cfg iwl6000_2ag_cfg = {
+ .name = "6000 Series 2x2 AG",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
+ .need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6000_2agn_cfg = {
+ .name = "6000 Series 2x2 AGN",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
+ .need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6050_2agn_cfg = {
+ .name = "6050 Series 2x2 AGN",
+ .fw_name_pre = IWL6050_FW_PRE,
+ .ucode_api_max = IWL6050_UCODE_API_MAX,
+ .ucode_api_min = IWL6050_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
+ .need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6000_3agn_cfg = {
+ .name = "6000 Series 3x3 AGN",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6050_3agn_cfg = {
+ .name = "6050 Series 3x3 AGN",
+ .fw_name_pre = IWL6050_FW_PRE,
+ .ucode_api_max = IWL6050_UCODE_API_MAX,
+ .ucode_api_min = IWL6050_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = false,
+};
+
+MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
deleted file mode 100644
index b8137eeae1d..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *****************************************************************************/
-
-#include <linux/kernel.h>
-#include <net/mac80211.h>
-#include "iwl-dev.h"
-#include "iwl-debug.h"
-#include "iwl-commands.h"
-
-
-/**
- * iwl_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE: This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
-int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
-{
- int error = 0;
- int counter = 1;
-
- if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
- error |= le32_to_cpu(rxon->flags &
- (RXON_FLG_TGJ_NARROW_BAND_MSK |
- RXON_FLG_RADAR_DETECT_MSK));
- if (error)
- IWL_WARNING("check 24G fields %d | %d\n",
- counter++, error);
- } else {
- error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
- 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
- if (error)
- IWL_WARNING("check 52 fields %d | %d\n",
- counter++, error);
- error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
- if (error)
- IWL_WARNING("check 52 CCK %d | %d\n",
- counter++, error);
- }
- error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
- if (error)
- IWL_WARNING("check mac addr %d | %d\n", counter++, error);
-
- /* make sure basic rates 6Mbps and 1Mbps are supported */
- error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
- ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
- if (error)
- IWL_WARNING("check basic rate %d | %d\n", counter++, error);
-
- error |= (le16_to_cpu(rxon->assoc_id) > 2007);
- if (error)
- IWL_WARNING("check assoc id %d | %d\n", counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
- if (error)
- IWL_WARNING("check CCK and short slot %d | %d\n",
- counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
- if (error)
- IWL_WARNING("check CCK & auto detect %d | %d\n",
- counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
- RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
- if (error)
- IWL_WARNING("check TGG and auto detect %d | %d\n",
- counter++, error);
-
- if (error)
- IWL_WARNING("Tuning to channel %d\n",
- le16_to_cpu(rxon->channel));
-
- if (error) {
- IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n");
- return -1;
- }
- return 0;
-}
-
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index f3f17929ca0..cab7842a73a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -49,6 +49,8 @@
#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
+/* max 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)
@@ -148,6 +150,8 @@ struct iwl_lq_sta {
u16 active_mimo2_rate;
u16 active_mimo3_rate;
u16 active_rate_basic;
+ s8 max_rate_idx; /* Max rate set by user */
+ u8 missed_rate_counter;
struct iwl_link_quality_cmd lq;
struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
@@ -356,7 +360,7 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
struct ieee80211_sta *sta)
{
if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
- IWL_DEBUG_HT("Starting Tx agg: STA: %pM tid: %d\n",
+ IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid);
ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid);
}
@@ -463,8 +467,9 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
* Fill uCode API rate_n_flags field, based on "search" or "active" table.
*/
/* FIXME:RS:remove this function and put the flags statically in the table */
-static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
- int index, u8 use_green)
+static u32 rate_n_flags_from_tbl(struct iwl_priv *priv,
+ struct iwl_scale_tbl_info *tbl,
+ int index, u8 use_green)
{
u32 rate_n_flags = 0;
@@ -475,7 +480,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
} else if (is_Ht(tbl->lq_type)) {
if (index > IWL_LAST_OFDM_RATE) {
- IWL_ERROR("invalid HT rate index %d\n", index);
+ IWL_ERR(priv, "Invalid HT rate index %d\n", index);
index = IWL_LAST_OFDM_RATE;
}
rate_n_flags = RATE_MCS_HT_MSK;
@@ -487,7 +492,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
else
rate_n_flags |= iwl_rates[index].plcp_mimo3;
} else {
- IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type);
+ IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type);
}
rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
@@ -507,7 +512,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
rate_n_flags |= RATE_MCS_GF_MSK;
if (is_siso(tbl->lq_type) && tbl->is_SGI) {
rate_n_flags &= ~RATE_MCS_SGI_MSK;
- IWL_ERROR("GF was set with SGI:SISO\n");
+ IWL_ERR(priv, "GF was set with SGI:SISO\n");
}
}
}
@@ -688,7 +693,7 @@ static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
break;
if (rate_mask & (1 << low))
break;
- IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
+ IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low);
}
high = index;
@@ -698,7 +703,7 @@ static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
break;
if (rate_mask & (1 << high))
break;
- IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
+ IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high);
}
return (high << 8) | low;
@@ -758,7 +763,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
low = scale_index;
out:
- return rate_n_flags_from_tbl(tbl, low, is_green);
+ return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green);
}
/*
@@ -785,7 +790,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
u8 active_index = 0;
s32 tpt = 0;
- IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
+ 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))
@@ -796,7 +801,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
!(info->flags & IEEE80211_TX_STAT_AMPDU))
return;
- retries = info->status.rates[0].count - 1;
+ if (info->flags & IEEE80211_TX_STAT_AMPDU)
+ retries = 0;
+ else
+ retries = info->status.rates[0].count - 1;
if (retries > 15)
retries = 15;
@@ -835,14 +843,19 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
(!!(tx_rate & RATE_MCS_GF_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
(hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) {
- IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
+ IWL_DEBUG_RATE(priv, "initial rate does not match 0x%x\n", tx_rate);
/* the last LQ command could failed so the LQ in ucode not
* the same in driver sync up
*/
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
+ lq_sta->missed_rate_counter++;
+ if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
+ lq_sta->missed_rate_counter = 0;
+ iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
+ }
goto out;
}
+ lq_sta->missed_rate_counter = 0;
/* Update frame history window with "failure" for each Tx retry. */
while (retries) {
/* Look up the rate and other info used for each tx attempt.
@@ -903,7 +916,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
tpt = search_tbl->expected_tpt[rs_index];
else
tpt = 0;
- if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ if (info->flags & IEEE80211_TX_STAT_AMPDU)
rs_collect_tx_data(search_win, rs_index, tpt,
info->status.ampdu_ack_len,
info->status.ampdu_ack_map);
@@ -919,7 +932,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
tpt = curr_tbl->expected_tpt[rs_index];
else
tpt = 0;
- if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ if (info->flags & IEEE80211_TX_STAT_AMPDU)
rs_collect_tx_data(window, rs_index, tpt,
info->status.ampdu_ack_len,
info->status.ampdu_ack_map);
@@ -931,7 +944,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
/* If not searching for new mode, increment success/failed counter
* ... these help determine when to start searching again */
if (lq_sta->stay_in_tbl) {
- if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (info->flags & IEEE80211_TX_STAT_AMPDU) {
lq_sta->total_success += info->status.ampdu_ack_map;
lq_sta->total_failed +=
(info->status.ampdu_ack_len - info->status.ampdu_ack_map);
@@ -944,7 +957,8 @@ 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. */
- rs_rate_scale_perform(priv, hdr, sta, lq_sta);
+ if (sta && sta->supp_rates[sband->band])
+ rs_rate_scale_perform(priv, hdr, sta, lq_sta);
out:
return;
}
@@ -960,7 +974,7 @@ out:
static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
struct iwl_lq_sta *lq_sta)
{
- IWL_DEBUG_RATE("we are staying in the same table\n");
+ IWL_DEBUG_RATE(priv, "we are staying in the same table\n");
lq_sta->stay_in_tbl = 1; /* only place this gets set */
if (is_legacy) {
lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
@@ -1128,7 +1142,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
s32 rate;
s8 is_green = lq_sta->is_green;
- if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
+ if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
@@ -1139,7 +1153,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
if (priv->hw_params.tx_chains_num < 2)
return -1;
- IWL_DEBUG_RATE("LQ: try to switch to MIMO2\n");
+ IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n");
tbl->lq_type = LQ_MIMO2;
tbl->is_dup = lq_sta->is_dup;
@@ -1168,16 +1182,16 @@ 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("LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
+ 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("Can't switch with index %d rate mask %x\n",
+ 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(tbl, rate, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
- IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
+ IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
tbl->current_rate, is_green);
return 0;
}
@@ -1195,10 +1209,10 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
u8 is_green = lq_sta->is_green;
s32 rate;
- if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
+ if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
- IWL_DEBUG_RATE("LQ: try to switch to SISO\n");
+ IWL_DEBUG_RATE(priv, "LQ: try to switch to SISO\n");
tbl->is_dup = lq_sta->is_dup;
tbl->lq_type = LQ_SISO;
@@ -1229,14 +1243,14 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
rs_set_expected_tpt_table(lq_sta, tbl);
rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
- IWL_DEBUG_RATE("LQ: get best rate %d mask %X\n", rate, rate_mask);
+ IWL_DEBUG_RATE(priv, "LQ: get best rate %d mask %X\n", rate, rate_mask);
if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
- IWL_DEBUG_RATE("can not switch with index %d rate mask %x\n",
+ IWL_DEBUG_RATE(priv, "can not switch with index %d rate mask %x\n",
rate, rate_mask);
return -1;
}
- tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
- IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
+ 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;
}
@@ -1265,7 +1279,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
switch (tbl->action) {
case IWL_LEGACY_SWITCH_ANTENNA1:
case IWL_LEGACY_SWITCH_ANTENNA2:
- IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n");
+ IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
lq_sta->action_counter++;
@@ -1289,7 +1303,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
}
break;
case IWL_LEGACY_SWITCH_SISO:
- IWL_DEBUG_RATE("LQ: Legacy switch to SISO\n");
+ IWL_DEBUG_RATE(priv, "LQ: Legacy switch to SISO\n");
/* Set up search table to try SISO */
memcpy(search_tbl, tbl, sz);
@@ -1305,7 +1319,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
case IWL_LEGACY_SWITCH_MIMO2_AB:
case IWL_LEGACY_SWITCH_MIMO2_AC:
case IWL_LEGACY_SWITCH_MIMO2_BC:
- IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n");
+ IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO2\n");
/* Set up search table to try MIMO */
memcpy(search_tbl, tbl, sz);
@@ -1374,7 +1388,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
switch (tbl->action) {
case IWL_SISO_SWITCH_ANTENNA1:
case IWL_SISO_SWITCH_ANTENNA2:
- IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n");
+ IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
tx_chains_num <= 1) ||
@@ -1393,7 +1407,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
case IWL_SISO_SWITCH_MIMO2_AB:
case IWL_SISO_SWITCH_MIMO2_AC:
case IWL_SISO_SWITCH_MIMO2_BC:
- IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n");
+ IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO2\n");
memcpy(search_tbl, tbl, sz);
search_tbl->is_SGI = 0;
@@ -1422,14 +1436,15 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
HT_SHORT_GI_40MHZ))
break;
- IWL_DEBUG_RATE("LQ: SISO toggle SGI/NGI\n");
+ IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n");
memcpy(search_tbl, tbl, sz);
if (is_green) {
if (!tbl->is_SGI)
break;
else
- IWL_ERROR("SGI was set in GF+SISO\n");
+ IWL_ERR(priv,
+ "SGI was set in GF+SISO\n");
}
search_tbl->is_SGI = !tbl->is_SGI;
rs_set_expected_tpt_table(lq_sta, search_tbl);
@@ -1438,8 +1453,9 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
if (tpt >= search_tbl->expected_tpt[index])
break;
}
- search_tbl->current_rate = rate_n_flags_from_tbl(
- search_tbl, index, is_green);
+ search_tbl->current_rate =
+ rate_n_flags_from_tbl(priv, search_tbl,
+ index, is_green);
goto out;
}
tbl->action++;
@@ -1485,7 +1501,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("LQ: MIMO toggle Antennas\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO toggle Antennas\n");
if (tx_chains_num <= 2)
break;
@@ -1501,7 +1517,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
case IWL_MIMO2_SWITCH_SISO_A:
case IWL_MIMO2_SWITCH_SISO_B:
case IWL_MIMO2_SWITCH_SISO_C:
- IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to SISO\n");
/* Set up new search table for SISO */
memcpy(search_tbl, tbl, sz);
@@ -1533,7 +1549,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
HT_SHORT_GI_40MHZ))
break;
- IWL_DEBUG_RATE("LQ: MIMO toggle SGI/NGI\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO toggle SGI/NGI\n");
/* Set up new search table for MIMO */
memcpy(search_tbl, tbl, sz);
@@ -1550,8 +1566,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
if (tpt >= search_tbl->expected_tpt[index])
break;
}
- search_tbl->current_rate = rate_n_flags_from_tbl(
- search_tbl, index, is_green);
+ search_tbl->current_rate =
+ rate_n_flags_from_tbl(priv, search_tbl,
+ index, is_green);
goto out;
}
@@ -1615,7 +1632,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
(lq_sta->total_success > lq_sta->max_success_limit) ||
((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
&& (flush_interval_passed))) {
- IWL_DEBUG_RATE("LQ: stay is expired %d %d %d\n:",
+ IWL_DEBUG_RATE(priv, "LQ: stay is expired %d %d %d\n:",
lq_sta->total_failed,
lq_sta->total_success,
flush_interval_passed);
@@ -1638,7 +1655,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
lq_sta->table_count_limit) {
lq_sta->table_count = 0;
- IWL_DEBUG_RATE("LQ: stay in table clear win\n");
+ IWL_DEBUG_RATE(priv, "LQ: stay in table clear win\n");
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(
&(tbl->win[i]));
@@ -1686,8 +1703,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
u16 high_low;
s32 sr;
u8 tid = MAX_TID_COUNT;
+ struct iwl_tid_data *tid_data;
- IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
+ IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
/* Send management frames and broadcast/multicast data using
* lowest rate. */
@@ -1719,13 +1737,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* current tx rate */
index = lq_sta->last_txrate_idx;
- IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index,
+ IWL_DEBUG_RATE(priv, "Rate scale index %d for type %d\n", index,
tbl->lq_type);
/* rates available for this association, and for modulation mode */
rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
- IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask);
+ IWL_DEBUG_RATE(priv, "mask 0x%04X \n", rate_mask);
/* mask with station rate restriction */
if (is_legacy(tbl->lq_type)) {
@@ -1744,16 +1762,25 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
rate_scale_index_msk = rate_mask;
if (!((1 << index) & rate_scale_index_msk)) {
- IWL_ERROR("Current Rate is not valid\n");
+ IWL_ERR(priv, "Current Rate is not valid\n");
return;
}
/* Get expected throughput table and history window for current rate */
if (!tbl->expected_tpt) {
- IWL_ERROR("tbl->expected_tpt is NULL\n");
+ IWL_ERR(priv, "tbl->expected_tpt is NULL\n");
return;
}
+ /* force user max rate if set by user */
+ if ((lq_sta->max_rate_idx != -1) &&
+ (lq_sta->max_rate_idx < index)) {
+ index = lq_sta->max_rate_idx;
+ update_lq = 1;
+ window = &(tbl->win[index]);
+ goto lq_update;
+ }
+
window = &(tbl->win[index]);
/*
@@ -1766,7 +1793,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
fail_count = window->counter - window->success_counter;
if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
(window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
- IWL_DEBUG_RATE("LQ: still below TH. succ=%d total=%d "
+ IWL_DEBUG_RATE(priv, "LQ: still below TH. succ=%d total=%d "
"for index %d\n",
window->success_counter, window->counter, index);
@@ -1794,7 +1821,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* continuing to use the setup that we've been trying. */
if (window->average_tpt > lq_sta->last_tpt) {
- IWL_DEBUG_RATE("LQ: SWITCHING TO NEW TABLE "
+ IWL_DEBUG_RATE(priv, "LQ: SWITCHING TO NEW TABLE "
"suc=%d cur-tpt=%d old-tpt=%d\n",
window->success_ratio,
window->average_tpt,
@@ -1810,7 +1837,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* Else poor success; go back to mode in "active" table */
} else {
- IWL_DEBUG_RATE("LQ: GOING BACK TO THE OLD TABLE "
+ IWL_DEBUG_RATE(priv, "LQ: GOING BACK TO THE OLD TABLE "
"suc=%d cur-tpt=%d old-tpt=%d\n",
window->success_ratio,
window->average_tpt,
@@ -1845,6 +1872,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
+ /* If user set max rate, dont allow higher than user constrain */
+ if ((lq_sta->max_rate_idx != -1) &&
+ (lq_sta->max_rate_idx < high))
+ high = IWL_RATE_INVALID;
+
sr = window->success_ratio;
/* Collect measured throughputs for current and adjacent rates */
@@ -1858,7 +1890,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* Too many failures, decrease rate */
if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) {
- IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
+ IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
scale_action = -1;
/* No throughput measured yet for adjacent rates; try increase. */
@@ -1868,7 +1900,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
scale_action = 1;
else if (low != IWL_RATE_INVALID)
- scale_action = -1;
+ scale_action = 0;
}
/* Both adjacent throughputs are measured, but neither one has better
@@ -1889,17 +1921,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
sr >= IWL_RATE_INCREASE_TH) {
scale_action = 1;
} else {
- IWL_DEBUG_RATE
- ("decrease rate because of high tpt\n");
- scale_action = -1;
+ scale_action = 0;
}
/* Lower adjacent rate's throughput is measured */
} else if (low_tpt != IWL_INVALID_VALUE) {
/* Lower rate has better throughput */
if (low_tpt > current_tpt) {
- IWL_DEBUG_RATE
- ("decrease rate because of low tpt\n");
+ IWL_DEBUG_RATE(priv,
+ "decrease rate because of low tpt\n");
scale_action = -1;
} else if (sr >= IWL_RATE_INCREASE_TH) {
scale_action = 1;
@@ -1936,14 +1966,14 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
break;
}
- IWL_DEBUG_RATE("choose rate scale index %d action %d low %d "
+ IWL_DEBUG_RATE(priv, "choose rate scale index %d action %d low %d "
"high %d type %d\n",
index, scale_action, low, high, tbl->lq_type);
lq_update:
/* Replace uCode's rate table for the destination station. */
if (update_lq) {
- rate = rate_n_flags_from_tbl(tbl, index, is_green);
+ rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
rs_fill_link_cmd(priv, lq_sta, rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
}
@@ -1980,7 +2010,7 @@ lq_update:
/* Use new "search" start rate */
index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
- IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n",
+ IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
tbl->current_rate, index);
rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
@@ -1992,10 +2022,10 @@ lq_update:
* stay with best antenna legacy modulation for a while
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
- if (is_legacy(tbl1->lq_type) && !conf->ht.enabled &&
+ if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
lq_sta->action_counter >= 1) {
lq_sta->action_counter = 0;
- IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
+ IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
rs_set_stay_in_table(priv, 1, lq_sta);
}
@@ -2007,8 +2037,15 @@ lq_update:
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) {
- IWL_DEBUG_RATE("try to aggregate tid %d\n", tid);
- rs_tl_turn_on_agg(priv, tid, lq_sta, sta);
+ tid_data =
+ &priv->stations[lq_sta->lq.sta_id].tid[tid];
+ if (tid_data->agg.state == IWL_AGG_OFF) {
+ IWL_DEBUG_RATE(priv,
+ "try to aggregate tid %d\n",
+ tid);
+ rs_tl_turn_on_agg(priv, tid,
+ lq_sta, sta);
+ }
}
lq_sta->action_counter = 0;
rs_set_stay_in_table(priv, 0, lq_sta);
@@ -2027,7 +2064,7 @@ lq_update:
}
out:
- tbl->current_rate = rate_n_flags_from_tbl(tbl, index, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
i = index;
lq_sta->last_txrate_idx = i;
@@ -2080,7 +2117,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
rs_toggle_antenna(valid_tx_ant, &rate, tbl);
- rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green);
+ rate = rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green);
tbl->current_rate = rate;
rs_set_expected_tpt_table(lq_sta, tbl);
rs_fill_link_cmd(NULL, lq_sta, rate);
@@ -2101,14 +2138,34 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct iwl_lq_sta *lq_sta = priv_sta;
int rate_idx;
+ u64 mask_bit = 0;
+
+ IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");
+
+ /* Get max rate if user set max rate */
+ if (lq_sta) {
+ lq_sta->max_rate_idx = txrc->max_rate_idx;
+ if ((sband->band == IEEE80211_BAND_5GHZ) &&
+ (lq_sta->max_rate_idx != -1))
+ lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
+ if ((lq_sta->max_rate_idx < 0) ||
+ (lq_sta->max_rate_idx >= IWL_RATE_COUNT))
+ lq_sta->max_rate_idx = -1;
+ }
- IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
+ if (sta)
+ mask_bit = sta->supp_rates[sband->band];
/* Send management frames and broadcast/multicast data using lowest
* rate. */
if (!ieee80211_is_data(hdr->frame_control) ||
is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) {
- info->control.rates[0].idx = rate_lowest_index(sband, 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);
return;
}
@@ -2119,7 +2176,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
u8 sta_id = iwl_find_station(priv, hdr->addr1);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_RATE("LQ: ADD station %pM\n",
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
hdr->addr1);
sta_id = iwl_add_station_flags(priv, hdr->addr1,
0, CMD_ASYNC, NULL);
@@ -2148,7 +2205,7 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
int i, j;
priv = (struct iwl_priv *)priv_rate;
- IWL_DEBUG_RATE("create station rate scale window\n");
+ IWL_DEBUG_RATE(priv, "create station rate scale window\n");
lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp);
@@ -2172,6 +2229,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_conf *conf = &priv->hw->conf;
struct iwl_lq_sta *lq_sta = priv_sta;
u16 mask_bit = 0;
+ int count;
+ int start_rate = 0;
lq_sta->flush_timer = 0;
lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2179,7 +2238,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
- IWL_DEBUG_RATE("LQ: *** rate scale station global init ***\n");
+ IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init ***\n");
/* TODO: what is a good starting rate for STA? About middle? Maybe not
* the lowest or the highest rate.. Could consider using RSSI from
* previous packets? Need to have IEEE 802.1X auth succeed immediately
@@ -2190,10 +2249,10 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
u8 sta_id = iwl_find_station(priv, sta->addr);
/* for IBSS the call are from tasklet */
- IWL_DEBUG_RATE("LQ: ADD station %pM\n", sta->addr);
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_RATE("LQ: ADD station %pM\n", sta->addr);
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
sta_id = iwl_add_station_flags(priv, sta->addr,
0, CMD_ASYNC, NULL);
}
@@ -2206,6 +2265,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
}
lq_sta->is_dup = 0;
+ lq_sta->max_rate_idx = -1;
+ lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
lq_sta->is_green = rs_use_green(priv, conf);
lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->active_rate_basic = priv->active_rate_basic;
@@ -2230,7 +2291,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->active_mimo3_rate &= ~((u16)0x2);
lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
- IWL_DEBUG_RATE("SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
+ IWL_DEBUG_RATE(priv, "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
lq_sta->active_siso_rate,
lq_sta->active_mimo2_rate,
lq_sta->active_mimo3_rate);
@@ -2244,16 +2305,20 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->drv = priv;
/* Find highest tx rate supported by hardware and destination station */
- mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate;
- lq_sta->last_txrate_idx = 3;
- for (i = 0; i < sband->n_bitrates; i++)
+ mask_bit = sta->supp_rates[sband->band];
+ count = sband->n_bitrates;
+ if (sband->band == IEEE80211_BAND_5GHZ) {
+ count += IWL_FIRST_OFDM_RATE;
+ start_rate = IWL_FIRST_OFDM_RATE;
+ mask_bit <<= IWL_FIRST_OFDM_RATE;
+ }
+
+ mask_bit = mask_bit & lq_sta->active_legacy_rate;
+ lq_sta->last_txrate_idx = 4;
+ for (i = start_rate; i < count; i++)
if (mask_bit & BIT(i))
lq_sta->last_txrate_idx = i;
- /* For MODE_IEEE80211A, skip over cck rates in global rate table */
- if (sband->band == IEEE80211_BAND_5GHZ)
- lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
-
rs_initialize_lq(priv, conf, sta, lq_sta);
}
@@ -2392,9 +2457,9 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta = priv_sta;
struct iwl_priv *priv __maybe_unused = priv_r;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
kfree(lq_sta);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
}
@@ -2408,20 +2473,27 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
u32 *rate_n_flags, int index)
{
struct iwl_priv *priv;
+ u8 valid_tx_ant;
+ u8 ant_sel_tx;
priv = lq_sta->drv;
+ valid_tx_ant = priv->hw_params.valid_tx_ant;
if (lq_sta->dbg_fixed_rate) {
- if (index < 12) {
+ ant_sel_tx =
+ ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
+ >> RATE_MCS_ANT_POS);
+ if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
*rate_n_flags = lq_sta->dbg_fixed_rate;
+ IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
} else {
- if (lq_sta->band == IEEE80211_BAND_5GHZ)
- *rate_n_flags = 0x800D;
- else
- *rate_n_flags = 0x820A;
+ lq_sta->dbg_fixed_rate = 0;
+ IWL_ERR(priv,
+ "Invalid antenna selection 0x%X, Valid is 0x%X\n",
+ ant_sel_tx, valid_tx_ant);
+ IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
}
- IWL_DEBUG_RATE("Fixed rate ON\n");
} else {
- IWL_DEBUG_RATE("Fixed rate OFF\n");
+ IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
}
}
@@ -2450,7 +2522,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
- IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
+ IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
if (lq_sta->dbg_fixed_rate) {
@@ -2464,11 +2536,19 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos)
{
- char buff[1024];
+ char *buff;
int desc = 0;
int i = 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;
+ buff = kmalloc(1024, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
@@ -2476,6 +2556,20 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
lq_sta->active_legacy_rate);
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
lq_sta->dbg_fixed_rate);
+ desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
+ (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
+ (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
+ (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : "");
+ desc += sprintf(buff+desc, "lq type %s\n",
+ (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
+ if (is_Ht(tbl->lq_type)) {
+ desc += sprintf(buff+desc, " %s",
+ (is_siso(tbl->lq_type)) ? "SISO" :
+ ((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, "general:"
"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
lq_sta->lq.general_params.flags,
@@ -2501,7 +2595,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
- return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ kfree(buff);
+ return ret;
}
static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
@@ -2512,11 +2608,17 @@ static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos)
{
- char buff[1024];
+ char *buff;
int desc = 0;
int i, j;
+ ssize_t ret;
struct iwl_lq_sta *lq_sta = file->private_data;
+
+ buff = kmalloc(1024, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
for (i = 0; i < LQ_SIZE; i++) {
desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
"rate=0x%X\n",
@@ -2534,7 +2636,9 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
lq_sta->lq_info[i].win[j].success_ratio);
}
}
- return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ kfree(buff);
+ return ret;
}
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 78ee83adf74..ab59acc405d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
#ifndef __iwl_agn_rs_h__
#define __iwl_agn_rs_h__
-#include "iwl-dev.h"
-
struct iwl_rate_info {
u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
@@ -43,6 +41,19 @@ struct iwl_rate_info {
u8 next_rs_tgg; /* next rate used in TGG rs algo */
};
+struct iwl3945_rate_info {
+ u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
+ u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
+ u8 prev_ieee; /* previous rate in IEEE speeds */
+ u8 next_ieee; /* next rate in IEEE speeds */
+ u8 prev_rs; /* previous rate used in rs algo */
+ u8 next_rs; /* next rate used in rs algo */
+ u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
+ u8 next_rs_tgg; /* next rate used in TGG rs algo */
+ u8 table_rs_index; /* index in rate scale table cmd */
+ u8 prev_table_rs; /* prev in rate table cmd */
+};
+
/*
* These serve as indexes into
* struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -62,12 +73,30 @@ enum {
IWL_RATE_54M_INDEX,
IWL_RATE_60M_INDEX,
IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
+ IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
IWL_RATE_INVALID = IWL_RATE_COUNT,
};
enum {
+ IWL_RATE_6M_INDEX_TABLE = 0,
+ IWL_RATE_9M_INDEX_TABLE,
+ IWL_RATE_12M_INDEX_TABLE,
+ IWL_RATE_18M_INDEX_TABLE,
+ IWL_RATE_24M_INDEX_TABLE,
+ IWL_RATE_36M_INDEX_TABLE,
+ IWL_RATE_48M_INDEX_TABLE,
+ IWL_RATE_54M_INDEX_TABLE,
+ IWL_RATE_1M_INDEX_TABLE,
+ IWL_RATE_2M_INDEX_TABLE,
+ IWL_RATE_5M_INDEX_TABLE,
+ IWL_RATE_11M_INDEX_TABLE,
+ IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1,
+};
+
+enum {
IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
+ IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
@@ -202,7 +231,7 @@ enum {
#define IWL_RS_GOOD_RATIO 12800 /* 100% */
#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
#define IWL_RATE_HIGH_TH 10880 /* 85% */
-#define IWL_RATE_INCREASE_TH 8960 /* 70% */
+#define IWL_RATE_INCREASE_TH 6400 /* 50% */
#define IWL_RATE_DECREASE_TH 1920 /* 15% */
/* possible actions when in legacy mode */
@@ -248,6 +277,7 @@ enum {
#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
+extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
enum iwl_table_type {
LQ_NONE,
@@ -303,6 +333,23 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
return rate;
}
+static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
+{
+ u8 rate = iwl3945_rates[rate_index].prev_ieee;
+
+ if (rate == IWL_RATE_INVALID)
+ rate = rate_index;
+ return rate;
+}
+
+/**
+ * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
+ *
+ * The specific throughput table used is based on the type of network
+ * the associated with, including A, B, G, and G w/ TGG protection
+ */
+extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
+
/**
* iwl_rate_control_register - Register the rate control algorithm callbacks
*
@@ -314,6 +361,7 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
*
*/
extern int iwlagn_rate_control_register(void);
+extern int iwl3945_rate_control_register(void);
/**
* iwl_rate_control_unregister - Unregister the rate control callbacks
@@ -322,5 +370,6 @@ extern int iwlagn_rate_control_register(void);
* the driver is unloaded.
*/
extern void iwlagn_rate_control_unregister(void);
+extern void iwl3945_rate_control_unregister(void);
#endif /* __iwl_agn__rs__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 5da6b35cd26..0db3bc011ac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -44,6 +44,8 @@
#include <asm/div64.h>
+#define DRV_NAME "iwlagn"
+
#include "iwl-eeprom.h"
#include "iwl-dev.h"
#include "iwl-core.h"
@@ -61,9 +63,7 @@
/*
* module name, copyright, version, etc.
- * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
*/
-
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -72,7 +72,7 @@
#define VD
#endif
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
#define VS "s"
#else
#define VS
@@ -94,66 +94,6 @@ MODULE_ALIAS("iwl4965");
/**************************************************************/
-
-
-static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
-{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-
- if (hw_decrypt)
- rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
- else
- rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
-
-}
-
-/**
- * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
- * @priv: staging_rxon is compared to active_rxon
- *
- * If the RXON structure is changing enough to require a new tune,
- * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
- * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
- */
-static int iwl_full_rxon_required(struct iwl_priv *priv)
-{
-
- /* These items are only settable from the full RXON command */
- if (!(iwl_is_associated(priv)) ||
- compare_ether_addr(priv->staging_rxon.bssid_addr,
- priv->active_rxon.bssid_addr) ||
- compare_ether_addr(priv->staging_rxon.node_addr,
- priv->active_rxon.node_addr) ||
- compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
- priv->active_rxon.wlap_bssid_addr) ||
- (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
- (priv->staging_rxon.channel != priv->active_rxon.channel) ||
- (priv->staging_rxon.air_propagation !=
- priv->active_rxon.air_propagation) ||
- (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
- (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
- (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
- return 1;
-
- /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
- * be updated with the RXON_ASSOC command -- however only some
- * flag transitions are allowed using RXON_ASSOC */
-
- /* Check if we are not switching bands */
- if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
- (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
- return 1;
-
- /* Check if we are switching association toggle */
- if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
- (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
- return 1;
-
- return 0;
-}
-
/**
* iwl_commit_rxon - commit staging_rxon to hardware
*
@@ -179,9 +119,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* 5000, but will not damage 4965 */
priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
- ret = iwl_agn_check_rxon_cmd(&priv->staging_rxon);
+ ret = iwl_check_rxon_cmd(priv);
if (ret) {
- IWL_ERROR("Invalid RXON configuration. Not committing.\n");
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
}
@@ -191,7 +131,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
if (!iwl_full_rxon_required(priv)) {
ret = iwl_send_rxon_assoc(priv);
if (ret) {
- IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret);
+ IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
@@ -207,7 +147,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* 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("Toggling associated bit on current RXON\n");
+ IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -218,12 +158,12 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* active_rxon back to what it was previously */
if (ret) {
active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERROR("Error clearing ASSOC_MSK (%d)\n", ret);
+ IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
return ret;
}
}
- IWL_DEBUG_INFO("Sending RXON\n"
+ IWL_DEBUG_INFO(priv, "Sending RXON\n"
"* with%s RXON_FILTER_ASSOC_MSK\n"
"* channel = %d\n"
"* bssid = %pM\n",
@@ -242,7 +182,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
if (ret) {
- IWL_ERROR("Error setting new RXON (%d)\n", ret);
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
@@ -256,7 +196,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
/* Add the broadcast address so we can send broadcast frames */
if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
IWL_INVALID_STATION) {
- IWL_ERROR("Error adding BROADCAST address for transmit.\n");
+ IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
return -EIO;
}
@@ -267,13 +207,15 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_rxon_add_station(priv,
priv->active_rxon.bssid_addr, 1);
if (ret == IWL_INVALID_STATION) {
- IWL_ERROR("Error adding AP address for TX.\n");
+ IWL_ERR(priv,
+ "Error adding AP address for TX.\n");
return -EIO;
}
priv->assoc_station_added = 1;
if (priv->default_wep_key &&
iwl_send_static_wepkey_cmd(priv, 0))
- IWL_ERROR("Could not send WEP static key.\n");
+ IWL_ERR(priv,
+ "Could not send WEP static key.\n");
}
/* Apply the new configuration
@@ -282,7 +224,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
if (ret) {
- IWL_ERROR("Error setting new RXON (%d)\n", ret);
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
@@ -294,7 +236,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* send a new TXPOWER command or we won't be able to Tx any frames */
ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
if (ret) {
- IWL_ERROR("Error sending TX power (%d)\n", ret);
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
return ret;
}
@@ -308,25 +250,11 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
iwl_commit_rxon(priv);
}
-static int iwl_send_bt_config(struct iwl_priv *priv)
-{
- struct iwl_bt_cmd bt_cmd = {
- .flags = 3,
- .lead_time = 0xAA,
- .max_kill = 1,
- .kill_ack_mask = 0,
- .kill_cts_mask = 0,
- };
-
- return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(struct iwl_bt_cmd), &bt_cmd);
-}
-
static void iwl_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
- IWL_DEBUG_INFO("%d frames on pre-allocated heap on clear.\n",
+ IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
priv->frames_count);
while (!list_empty(&priv->free_frames)) {
@@ -337,7 +265,7 @@ static void iwl_clear_free_frames(struct iwl_priv *priv)
}
if (priv->frames_count) {
- IWL_WARNING("%d frames still in use. Did we lose one?\n",
+ IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
priv->frames_count);
priv->frames_count = 0;
}
@@ -350,7 +278,7 @@ static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
if (list_empty(&priv->free_frames)) {
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame) {
- IWL_ERROR("Could not allocate frame!\n");
+ IWL_ERR(priv, "Could not allocate frame!\n");
return NULL;
}
@@ -386,31 +314,6 @@ static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
return priv->ibss_beacon->len;
}
-static u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
-{
- int i;
- int rate_mask;
-
- /* Set rate mask*/
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
- rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
- else
- rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
-
- /* Find lowest valid rate */
- for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
- i = iwl_rates[i].next_ieee) {
- if (rate_mask & (1 << i))
- return iwl_rates[i].plcp;
- }
-
- /* No valid rate was found. Assign the lowest one */
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
- return IWL_RATE_1M_PLCP;
- else
- return IWL_RATE_6M_PLCP;
-}
-
static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
@@ -452,7 +355,7 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
frame = iwl_get_free_frame(priv);
if (!frame) {
- IWL_ERROR("Could not obtain free frame buffer for beacon "
+ IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
"command.\n");
return -ENOMEM;
}
@@ -469,6 +372,159 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
return rc;
}
+static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+ dma_addr_t addr = get_unaligned_le32(&tb->lo);
+ if (sizeof(dma_addr_t) > sizeof(u32))
+ addr |=
+ ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
+
+ return addr;
+}
+
+static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+ return le16_to_cpu(tb->hi_n_len) >> 4;
+}
+
+static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
+ dma_addr_t addr, u16 len)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+ u16 hi_n_len = len << 4;
+
+ put_unaligned_le32(addr, &tb->lo);
+ if (sizeof(dma_addr_t) > sizeof(u32))
+ hi_n_len |= ((addr >> 16) >> 16) & 0xF;
+
+ tb->hi_n_len = cpu_to_le16(hi_n_len);
+
+ tfd->num_tbs = idx + 1;
+}
+
+static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
+{
+ return tfd->num_tbs & 0x1f;
+}
+
+/**
+ * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
+ * @priv - driver private data
+ * @txq - tx queue
+ *
+ * Does NOT advance any TFD circular buffer read/write indexes
+ * Does NOT free the TFD itself (which is within circular buffer)
+ */
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+ struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds;
+ struct iwl_tfd *tfd;
+ struct pci_dev *dev = priv->pci_dev;
+ int index = txq->q.read_ptr;
+ int i;
+ int num_tbs;
+
+ tfd = &tfd_tmp[index];
+
+ /* Sanity check on number of chunks */
+ num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+ if (num_tbs >= IWL_NUM_OF_TBS) {
+ IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
+ /* @todo issue fatal error, it is quite serious situation */
+ return;
+ }
+
+ /* Unmap tx_cmd */
+ if (num_tbs)
+ pci_unmap_single(dev,
+ pci_unmap_addr(&txq->cmd[index]->meta, mapping),
+ pci_unmap_len(&txq->cmd[index]->meta, len),
+ PCI_DMA_BIDIRECTIONAL);
+
+ /* Unmap chunks, if any. */
+ for (i = 1; i < num_tbs; i++) {
+ pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
+ iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
+
+ if (txq->txb) {
+ dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
+ txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
+ }
+ }
+}
+
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len,
+ u8 reset, u8 pad)
+{
+ struct iwl_queue *q;
+ struct iwl_tfd *tfd, *tfd_tmp;
+ u32 num_tbs;
+
+ q = &txq->q;
+ tfd_tmp = (struct iwl_tfd *)txq->tfds;
+ tfd = &tfd_tmp[q->write_ptr];
+
+ if (reset)
+ memset(tfd, 0, sizeof(*tfd));
+
+ num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+ /* Each TFD can point to a maximum 20 Tx buffers */
+ if (num_tbs >= IWL_NUM_OF_TBS) {
+ IWL_ERR(priv, "Error can not send more than %d chunks\n",
+ IWL_NUM_OF_TBS);
+ return -EINVAL;
+ }
+
+ BUG_ON(addr & ~DMA_BIT_MASK(36));
+ if (unlikely(addr & ~IWL_TX_DMA_MASK))
+ IWL_ERR(priv, "Unaligned address = %llx\n",
+ (unsigned long long)addr);
+
+ iwl_tfd_set_tb(tfd, num_tbs, addr, len);
+
+ return 0;
+}
+
+/*
+ * Tell nic where to find circular buffer of Tx Frame Descriptors for
+ * given Tx queue, and enable the DMA channel used for that queue.
+ *
+ * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * channels supported in hardware.
+ */
+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;
+}
+
+
/******************************************************************************
*
* Misc. internal state and helper functions
@@ -482,7 +538,7 @@ static void iwl_ht_conf(struct iwl_priv *priv,
struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
struct ieee80211_sta *sta;
- IWL_DEBUG_MAC80211("enter: \n");
+ IWL_DEBUG_MAC80211(priv, "enter: \n");
if (!iwl_conf->is_ht)
return;
@@ -520,9 +576,9 @@ static void iwl_ht_conf(struct iwl_priv *priv,
*/
iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
- if (priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40MINUS)
+ if (conf_is_ht40_minus(&priv->hw->conf))
iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- else if(priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40PLUS)
+ 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 */
@@ -542,39 +598,7 @@ static void iwl_ht_conf(struct iwl_priv *priv,
rcu_read_unlock();
- IWL_DEBUG_MAC80211("leave\n");
-}
-
-/*
- * QoS support
-*/
-static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- priv->qos_data.def_qos_parm.qos_flags = 0;
-
- if (priv->qos_data.qos_cap.q_AP.queue_request &&
- !priv->qos_data.qos_cap.q_AP.txop_request)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_TXOP_TYPE_MSK;
- if (priv->qos_data.qos_active)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
- if (priv->current_ht_config.is_ht)
- priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
-
- if (force || iwl_is_associated(priv)) {
- IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
- priv->qos_data.qos_active,
- priv->qos_data.def_qos_parm.qos_flags);
-
- iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl_qosparam_cmd),
- &priv->qos_data.def_qos_parm, NULL);
- }
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
#define MAX_UCODE_BEACON_INTERVAL 4096
@@ -588,6 +612,9 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val)
/ MAX_UCODE_BEACON_INTERVAL;
new_val = beacon_val / beacon_factor;
+ if (!new_val)
+ new_val = MAX_UCODE_BEACON_INTERVAL;
+
return new_val;
}
@@ -624,117 +651,16 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n",
+ IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n",
le16_to_cpu(priv->rxon_timing.beacon_interval),
le32_to_cpu(priv->rxon_timing.beacon_init_val),
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static void iwl_set_flags_for_band(struct iwl_priv *priv,
- enum ieee80211_band band)
-{
- if (band == IEEE80211_BAND_5GHZ) {
- priv->staging_rxon.flags &=
- ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
- | RXON_FLG_CCK_MSK);
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
- } else {
- /* Copied from iwl_post_associate() */
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
- priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
- priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
- }
-}
-
-/*
- * initialize rxon structure with default values from eeprom
- */
-static void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
-{
- const struct iwl_channel_info *ch_info;
-
- memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
-
- switch (mode) {
- case NL80211_IFTYPE_AP:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
- break;
-
- case NL80211_IFTYPE_STATION:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
- priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
- break;
-
- case NL80211_IFTYPE_ADHOC:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
- priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
- priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
- 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_ERROR("Unsupported interface type %d\n", mode);
- break;
- }
-
-#if 0
- /* TODO: Figure out when short_preamble would be set and cache from
- * that */
- if (!hw_to_local(priv->hw)->short_preamble)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
-#endif
-
- ch_info = iwl_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->active_rxon.channel));
-
- if (!ch_info)
- ch_info = &priv->channel_info[0];
-
- /*
- * in some case A channels are all non IBSS
- * in this case force B/G channel
- */
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
- !(is_channel_ibss(ch_info)))
- ch_info = &priv->channel_info[0];
-
- priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
- priv->band = ch_info->band;
-
- iwl_set_flags_for_band(priv, priv->band);
-
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
- 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);
- 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;
- iwl_set_rxon_chain(priv);
-}
-
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);
@@ -745,8 +671,8 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
cancel_delayed_work(&priv->scan_check);
if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+ IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
return -EAGAIN;
}
@@ -755,54 +681,6 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
return 0;
}
-static void iwl_set_rate(struct iwl_priv *priv)
-{
- const struct ieee80211_supported_band *hw = NULL;
- struct ieee80211_rate *rate;
- int i;
-
- hw = iwl_get_hw_mode(priv, priv->band);
- if (!hw) {
- IWL_ERROR("Failed to set rate: unable to get hw mode\n");
- return;
- }
-
- priv->active_rate = 0;
- priv->active_rate_basic = 0;
-
- for (i = 0; i < hw->n_bitrates; i++) {
- rate = &(hw->bitrates[i]);
- if (rate->hw_value < IWL_RATE_COUNT)
- priv->active_rate |= (1 << rate->hw_value);
- }
-
- IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
- priv->active_rate, priv->active_rate_basic);
-
- /*
- * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
- * otherwise set it to the default of all CCK rates and 6, 12, 24 for
- * OFDM
- */
- if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
- priv->staging_rxon.cck_basic_rates =
- ((priv->active_rate_basic &
- IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
- else
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-
- if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
- priv->staging_rxon.ofdm_basic_rates =
- ((priv->active_rate_basic &
- (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
- IWL_FIRST_OFDM_RATE) & 0xFF;
- else
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
-}
-
-
/******************************************************************************
*
* Generic RX handler implementations
@@ -817,19 +695,19 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
palive = &pkt->u.alive_frame;
- IWL_DEBUG_INFO("Alive ucode status 0x%08X revision "
+ IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
"0x%01X 0x%01X\n",
palive->is_valid, palive->ver_type,
palive->ver_subtype);
if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
- IWL_DEBUG_INFO("Initialization Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
memcpy(&priv->card_alive_init,
&pkt->u.alive_frame,
sizeof(struct iwl_init_alive_resp));
pwork = &priv->init_alive_start;
} else {
- IWL_DEBUG_INFO("Runtime Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
memcpy(&priv->card_alive, &pkt->u.alive_frame,
sizeof(struct iwl_alive_resp));
pwork = &priv->alive_start;
@@ -841,55 +719,7 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
queue_delayed_work(priv->workqueue, pwork,
msecs_to_jiffies(5));
else
- IWL_WARNING("uCode did not respond OK.\n");
-}
-
-static 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_ERROR("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));
-}
-
-#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-
-static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
- struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
- IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
- le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
- rxon->channel = csa->channel;
- priv->staging_rxon.channel = csa->channel;
-}
-
-static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
-#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("sleep mode: %d, src: %d\n",
- sleep->pm_sleep_mode, sleep->pm_wakeup_src);
-#endif
-}
-
-static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
- "notification for %s:\n",
- le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
- iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+ IWL_WARN(priv, "uCode did not respond OK.\n");
}
static void iwl_bg_beacon_update(struct work_struct *work)
@@ -902,7 +732,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
beacon = ieee80211_beacon_get(priv->hw, priv->vif);
if (!beacon) {
- IWL_ERROR("update beacon failed\n");
+ IWL_ERR(priv, "update beacon failed\n");
return;
}
@@ -950,7 +780,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
(struct iwl4965_beacon_notif *)pkt->u.raw;
u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
- IWL_DEBUG_RX("beacon status %x retries %d iss %d "
+ IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
"tsf %d %d rate %d\n",
le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
beacon->beacon_notify_hdr.failure_frame,
@@ -973,7 +803,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
unsigned long status = priv->status;
- IWL_DEBUG_RF_KILL("Card state received: HW:%s SW:%s\n",
+ IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
(flags & HW_CARD_DISABLED) ? "Kill" : "On",
(flags & SW_CARD_DISABLED) ? "Kill" : "On");
@@ -1046,11 +876,7 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
goto err;
if (src == IWL_PWR_SRC_VAUX) {
- u32 val;
- ret = pci_read_config_dword(priv->pci_dev, PCI_CFG_POWER_SOURCE,
- &val);
-
- if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
+ 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);
@@ -1135,7 +961,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
/* Rx interrupt, but nothing sent from uCode */
if (i == r)
- IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d\n", r, i);
+ IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
@@ -1175,12 +1001,12 @@ void iwl_rx_handle(struct iwl_priv *priv)
* handle those that need handling via function in
* rx_handlers table. See iwl_setup_rx_handlers() */
if (priv->rx_handlers[pkt->hdr.cmd]) {
- IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d, %s, 0x%02x\n", r,
+ 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);
} else {
/* No handling needed */
- IWL_DEBUG(IWL_DL_RX,
+ IWL_DEBUG_RX(priv,
"r %d i %d No handler needed for %s, 0x%02x\n",
r, i, get_cmd_string(pkt->hdr.cmd),
pkt->hdr.cmd);
@@ -1193,7 +1019,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
if (rxb && rxb->skb)
iwl_tx_cmd_complete(priv, rxb);
else
- IWL_WARNING("Claim null rxb?\n");
+ IWL_WARN(priv, "Claim null rxb?\n");
}
/* For now we just don't re-use anything. We can tweak this
@@ -1229,27 +1055,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
iwl_rx_queue_restock(priv);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
-{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-
- IWL_DEBUG_RADIO("RX CONFIG:\n");
- iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
- IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
- IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
- IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
- le32_to_cpu(rxon->filter_flags));
- IWL_DEBUG_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type);
- IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
- rxon->ofdm_basic_rates);
- IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
- IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
- IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
- IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
-}
-#endif
-
/* call this function to flush any scheduled tasklet */
static inline void iwl_synchronize_irq(struct iwl_priv *priv)
{
@@ -1258,45 +1063,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
tasklet_kill(&priv->irq_tasklet);
}
-/**
- * iwl_irq_handle_error - called for HW or SW error interrupt from card
- */
-static void iwl_irq_handle_error(struct iwl_priv *priv)
-{
- /* Set the FW error flag -- cleared on iwl_down */
- set_bit(STATUS_FW_ERROR, &priv->status);
-
- /* Cancel currently queued command. */
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (priv->debug_level & IWL_DL_FW_ERRORS) {
- iwl_dump_nic_error_log(priv);
- iwl_dump_nic_event_log(priv);
- iwl_print_rx_config_cmd(priv);
- }
-#endif
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- /* Keep the restart process from trying to send host
- * commands by clearing the INIT status bit */
- clear_bit(STATUS_READY, &priv->status);
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG(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);
- }
-}
-
static void iwl_error_recovery(struct iwl_priv *priv)
{
unsigned long flags;
@@ -1341,7 +1107,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (priv->debug_level & IWL_DL_ISR) {
/* just for debug */
inta_mask = iwl_read32(priv, CSR_INT_MASK);
- IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+ IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
}
#endif
@@ -1357,7 +1123,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Now service all interrupt bits discovered above. */
if (inta & CSR_INT_BIT_HW_ERR) {
- IWL_ERROR("Microcode HW error detected. Restarting.\n");
+ IWL_ERR(priv, "Microcode HW error detected. Restarting.\n");
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
@@ -1375,12 +1141,12 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
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("Scheduler finished to transmit "
+ IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE)
- IWL_DEBUG_ISR("Alive interrupt\n");
+ IWL_DEBUG_ISR(priv, "Alive interrupt\n");
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -1393,17 +1159,20 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
hw_rf_kill = 1;
- IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n",
+ IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
hw_rf_kill ? "disable radio" : "enable radio");
/* driver only loads ucode once setting the interface up.
- * the driver as well won't allow loading if RFKILL is set
- * therefore no need to restart the driver from this handler
+ * 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 (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
- clear_bit(STATUS_RF_KILL_HW, &priv->status);
- if (priv->is_open && !iwl_is_rfkill(priv))
- queue_work(priv->workqueue, &priv->up);
+ 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);
+ queue_work(priv->workqueue, &priv->rf_kill);
}
handled |= CSR_INT_BIT_RF_KILL;
@@ -1411,21 +1180,21 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Chip got too hot and stopped itself */
if (inta & CSR_INT_BIT_CT_KILL) {
- IWL_ERROR("Microcode CT kill error detected.\n");
+ IWL_ERR(priv, "Microcode CT kill error detected.\n");
handled |= CSR_INT_BIT_CT_KILL;
}
/* Error detected by uCode */
if (inta & CSR_INT_BIT_SW_ERR) {
- IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n",
- inta);
+ IWL_ERR(priv, "Microcode SW error detected. "
+ " Restarting 0x%X.\n", 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("Wakeup interrupt\n");
+ 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]);
@@ -1446,7 +1215,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
}
if (inta & CSR_INT_BIT_FH_TX) {
- IWL_DEBUG_ISR("Tx interrupt\n");
+ IWL_DEBUG_ISR(priv, "Tx interrupt\n");
handled |= CSR_INT_BIT_FH_TX;
/* FH finished to write, send event */
priv->ucode_write_complete = 1;
@@ -1454,12 +1223,12 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
}
if (inta & ~handled)
- IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
if (inta & ~CSR_INI_SET_MASK) {
- IWL_WARNING("Disabled INTA bits 0x%08x were pending\n",
+ IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
inta & ~CSR_INI_SET_MASK);
- IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh);
+ IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
/* Re-enable all interrupts */
@@ -1472,71 +1241,13 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
inta = iwl_read32(priv, CSR_INT);
inta_mask = iwl_read32(priv, CSR_INT_MASK);
inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
- IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
+ IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
}
#endif
spin_unlock_irqrestore(&priv->lock, flags);
}
-static irqreturn_t iwl_isr(int irq, void *data)
-{
- struct iwl_priv *priv = data;
- u32 inta, inta_mask;
- u32 inta_fh;
- 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);
- inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-
- /* Ignore interrupt if there's nothing in NIC to service.
- * This may be due to IRQ shared with another device,
- * or due to sporadic interrupts thrown from our NIC. */
- if (!inta && !inta_fh) {
- IWL_DEBUG_ISR("Ignore interrupt, inta == 0, inta_fh == 0\n");
- goto none;
- }
-
- if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
- /* Hardware disappeared. It might have already raised
- * an interrupt */
- IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
- goto unplugged;
- }
-
- IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
- inta, inta_mask, inta_fh);
-
- inta &= ~CSR_INT_BIT_SCD;
-
- /* iwl_irq_tasklet() will service interrupts and re-enable them */
- if (likely(inta || inta_fh))
- tasklet_schedule(&priv->irq_tasklet);
-
- 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 */
- if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl_enable_interrupts(priv);
- spin_unlock(&priv->lock);
- return IRQ_NONE;
-}
-
/******************************************************************************
*
* uCode download functions
@@ -1584,7 +1295,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
sprintf(buf, "%s%d%s", name_pre, index, ".ucode");
ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
if (ret < 0) {
- IWL_ERROR("%s firmware file req failed: Reason %d\n",
+ IWL_ERR(priv, "%s firmware file req failed: %d\n",
buf, ret);
if (ret == -ENOENT)
continue;
@@ -1592,9 +1303,12 @@ static int iwl_read_ucode(struct iwl_priv *priv)
goto error;
} else {
if (index < api_max)
- IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+ IWL_ERR(priv, "Loaded firmware %s, "
+ "which is deprecated. "
+ "Please use API v%u instead.\n",
buf, api_max);
- IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
+
+ IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
buf, ucode_raw->size);
break;
}
@@ -1605,7 +1319,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Make sure that we got at least our header! */
if (ucode_raw->size < sizeof(*ucode)) {
- IWL_ERROR("File size way too small!\n");
+ IWL_ERR(priv, "File size way too small!\n");
ret = -EINVAL;
goto err_release;
}
@@ -1626,7 +1340,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
* on the API version read from firware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
- IWL_ERROR("Driver unable to support your firmware API. "
+ IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
api_max, api_ver);
priv->ucode_ver = 0;
@@ -1634,28 +1348,28 @@ static int iwl_read_ucode(struct iwl_priv *priv)
goto err_release;
}
if (api_ver != api_max)
- IWL_ERROR("Firmware has old API version. Expected v%u, "
+ IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
"got v%u. New firmware can be obtained "
"from http://www.intellinuxwireless.org.\n",
api_max, api_ver);
- printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
- IWL_UCODE_MAJOR(priv->ucode_ver),
- IWL_UCODE_MINOR(priv->ucode_ver),
- IWL_UCODE_API(priv->ucode_ver),
- IWL_UCODE_SERIAL(priv->ucode_ver));
+ IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
+ IWL_UCODE_MAJOR(priv->ucode_ver),
+ IWL_UCODE_MINOR(priv->ucode_ver),
+ IWL_UCODE_API(priv->ucode_ver),
+ IWL_UCODE_SERIAL(priv->ucode_ver));
- IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
priv->ucode_ver);
- IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
inst_size);
- IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
data_size);
- IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
init_size);
- IWL_DEBUG_INFO("f/w package hdr init data size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
init_data_size);
- IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
boot_size);
/* Verify size of file vs. image size info in file's header */
@@ -1663,7 +1377,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
inst_size + data_size + init_size +
init_data_size + boot_size) {
- IWL_DEBUG_INFO("uCode file size %d too small\n",
+ IWL_DEBUG_INFO(priv, "uCode file size %d too small\n",
(int)ucode_raw->size);
ret = -EINVAL;
goto err_release;
@@ -1671,36 +1385,33 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Verify that uCode images will fit in card's SRAM */
if (inst_size > priv->hw_params.max_inst_size) {
- IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
+ IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
inst_size);
ret = -EINVAL;
goto err_release;
}
if (data_size > priv->hw_params.max_data_size) {
- IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
+ IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
data_size);
ret = -EINVAL;
goto err_release;
}
if (init_size > priv->hw_params.max_inst_size) {
- IWL_DEBUG_INFO
- ("uCode init instr len %d too large to fit in\n",
- init_size);
+ IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
+ init_size);
ret = -EINVAL;
goto err_release;
}
if (init_data_size > priv->hw_params.max_data_size) {
- IWL_DEBUG_INFO
- ("uCode init data len %d too large to fit in\n",
+ IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
init_data_size);
ret = -EINVAL;
goto err_release;
}
if (boot_size > priv->hw_params.max_bsm_size) {
- IWL_DEBUG_INFO
- ("uCode boot instr len %d too large to fit in\n",
- boot_size);
+ IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
+ boot_size);
ret = -EINVAL;
goto err_release;
}
@@ -1719,6 +1430,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
priv->ucode_data_backup.len = data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
+ if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
+ !priv->ucode_data_backup.v_addr)
+ goto err_pci_alloc;
+
/* Initialization instructions and data */
if (init_size && init_data_size) {
priv->ucode_init.len = init_size;
@@ -1745,16 +1460,16 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Runtime instructions (first block of data in file) */
src = &ucode->data[0];
len = priv->ucode_code.len;
- IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len);
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
memcpy(priv->ucode_code.v_addr, src, len);
- IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
+ IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
/* Runtime data (2nd block)
* NOTE: Copy into backup buffer will be done in iwl_up() */
src = &ucode->data[inst_size];
len = priv->ucode_data.len;
- IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
memcpy(priv->ucode_data.v_addr, src, len);
memcpy(priv->ucode_data_backup.v_addr, src, len);
@@ -1762,7 +1477,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
if (init_size) {
src = &ucode->data[inst_size + data_size];
len = priv->ucode_init.len;
- IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n",
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
len);
memcpy(priv->ucode_init.v_addr, src, len);
}
@@ -1771,7 +1486,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
if (init_data_size) {
src = &ucode->data[inst_size + data_size + init_size];
len = priv->ucode_init_data.len;
- IWL_DEBUG_INFO("Copying (but not loading) init data len %Zd\n",
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
len);
memcpy(priv->ucode_init_data.v_addr, src, len);
}
@@ -1779,7 +1494,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Bootstrap instructions (5th block) */
src = &ucode->data[inst_size + data_size + init_size + init_data_size];
len = priv->ucode_boot.len;
- IWL_DEBUG_INFO("Copying (but not loading) boot instr len %Zd\n", len);
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
memcpy(priv->ucode_boot.v_addr, src, len);
/* We have our copies now, allow OS release its copies */
@@ -1787,7 +1502,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
return 0;
err_pci_alloc:
- IWL_ERROR("failed to allocate pci memory\n");
+ IWL_ERR(priv, "failed to allocate pci memory\n");
ret = -ENOMEM;
iwl_dealloc_ucode_pci(priv);
@@ -1811,12 +1526,12 @@ static void iwl_alive_start(struct iwl_priv *priv)
{
int ret = 0;
- IWL_DEBUG_INFO("Runtime Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
if (priv->card_alive.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Alive failed.\n");
goto restart;
}
@@ -1826,15 +1541,15 @@ static void iwl_alive_start(struct iwl_priv *priv)
if (iwl_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad runtime uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
goto restart;
}
iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
- IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n",
- ret);
+ IWL_WARN(priv,
+ "Could not complete ALIVE transition [ntf]: %d\n", ret);
goto restart;
}
@@ -1859,6 +1574,7 @@ 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);
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
}
@@ -1875,7 +1591,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_leds_register(priv);
- IWL_DEBUG_INFO("ALIVE processing complete.\n");
+ IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
@@ -1909,7 +1625,7 @@ static void __iwl_down(struct iwl_priv *priv)
unsigned long flags;
int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
- IWL_DEBUG_INFO(DRV_NAME " is going down\n");
+ IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
if (!exit_pending)
set_bit(STATUS_EXIT_PENDING, &priv->status);
@@ -2020,12 +1736,12 @@ static int __iwl_up(struct iwl_priv *priv)
int ret;
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_WARNING("Exit pending; will not bring the NIC up\n");
+ IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
}
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
- IWL_ERROR("ucode not available for device bringup\n");
+ IWL_ERR(priv, "ucode not available for device bringup\n");
return -EIO;
}
@@ -2037,7 +1753,7 @@ static int __iwl_up(struct iwl_priv *priv)
if (iwl_is_rfkill(priv)) {
iwl_enable_interrupts(priv);
- IWL_WARNING("Radio disabled by %s RF Kill switch\n",
+ IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
return 0;
}
@@ -2046,7 +1762,7 @@ static int __iwl_up(struct iwl_priv *priv)
ret = iwl_hw_nic_init(priv);
if (ret) {
- IWL_ERROR("Unable to init nic\n");
+ IWL_ERR(priv, "Unable to init nic\n");
return ret;
}
@@ -2079,7 +1795,8 @@ static int __iwl_up(struct iwl_priv *priv)
ret = priv->cfg->ops->lib->load_ucode(priv);
if (ret) {
- IWL_ERROR("Unable to set up bootstrap uCode: %d\n", ret);
+ IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
+ ret);
continue;
}
@@ -2089,7 +1806,7 @@ static int __iwl_up(struct iwl_priv *priv)
/* start card; "initialize" will load runtime ucode */
iwl_nic_start(priv);
- IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
+ IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
return 0;
}
@@ -2100,7 +1817,7 @@ static int __iwl_up(struct iwl_priv *priv)
/* tried to restart and config the device for as long as our
* patience could withstand */
- IWL_ERROR("Unable to initialize device after %d attempts.\n", i);
+ IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
return -EIO;
}
@@ -2137,40 +1854,6 @@ static void iwl_bg_alive_start(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl_bg_rf_kill(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
-
- if (!iwl_is_rfkill(priv)) {
- IWL_DEBUG(IWL_DL_RF_KILL,
- "HW and/or SW RF Kill no longer active, restarting "
- "device\n");
- if (!test_bit(STATUS_EXIT_PENDING, &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 (!test_bit(STATUS_RF_KILL_HW, &priv->status))
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by SW switch\n");
- else
- IWL_WARNING("Radio Frequency Kill Switch is On:\n"
- "Kill switch must be turned off for "
- "wireless networking to work.\n");
- }
- mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
-}
-
static void iwl_bg_run_time_calib_work(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -2240,11 +1923,11 @@ static void iwl_post_associate(struct iwl_priv *priv)
unsigned long flags;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- IWL_ERROR("%s Should not be called in AP mode\n", __func__);
+ IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
- IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
priv->assoc_id, priv->active_rxon.bssid_addr);
@@ -2267,7 +1950,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -2277,7 +1960,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
iwl_set_rxon_chain(priv);
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
- IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n",
+ IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
priv->assoc_id, priv->beacon_int);
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -2313,7 +1996,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
break;
default:
- IWL_ERROR("%s Should not be called in %d mode\n",
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
__func__, priv->iw_mode);
break;
}
@@ -2349,30 +2032,8 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
- u16 pci_cmd;
-
- IWL_DEBUG_MAC80211("enter\n");
-
- if (pci_enable_device(priv->pci_dev)) {
- IWL_ERROR("Fail to pci_enable_device\n");
- return -ENODEV;
- }
- pci_restore_state(priv->pci_dev);
- pci_enable_msi(priv->pci_dev);
-
- /* enable interrupts if needed: hw bug w/a */
- pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
- if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
- pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
- pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
- }
- ret = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
- DRV_NAME, priv);
- if (ret) {
- IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
- goto out_disable_msi;
- }
+ IWL_DEBUG_MAC80211(priv, "enter\n");
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
@@ -2384,9 +2045,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
if (!priv->ucode_code.len) {
ret = iwl_read_ucode(priv);
if (ret) {
- IWL_ERROR("Could not read microcode: %d\n", ret);
+ IWL_ERR(priv, "Could not read microcode: %d\n", ret);
mutex_unlock(&priv->mutex);
- goto out_release_irq;
+ return ret;
}
}
@@ -2397,12 +2058,12 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
iwl_rfkill_set_hw_state(priv);
if (ret)
- goto out_release_irq;
+ return ret;
if (iwl_is_rfkill(priv))
goto out;
- IWL_DEBUG_INFO("Start UP work done.\n");
+ IWL_DEBUG_INFO(priv, "Start UP work done.\n");
if (test_bit(STATUS_IN_SUSPEND, &priv->status))
return 0;
@@ -2414,36 +2075,26 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
UCODE_READY_TIMEOUT);
if (!ret) {
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERROR("START_ALIVE timeout after %dms.\n",
+ IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
jiffies_to_msecs(UCODE_READY_TIMEOUT));
- ret = -ETIMEDOUT;
- goto out_release_irq;
+ return -ETIMEDOUT;
}
}
out:
priv->is_open = 1;
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
-
-out_release_irq:
- free_irq(priv->pci_dev->irq, priv);
-out_disable_msi:
- pci_disable_msi(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
- priv->is_open = 0;
- IWL_DEBUG_MAC80211("leave - failed\n");
- return ret;
}
static void iwl_mac_stop(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!priv->is_open) {
- IWL_DEBUG_MAC80211("leave - skip\n");
+ IWL_DEBUG_MAC80211(priv, "leave - skip\n");
return;
}
@@ -2461,28 +2112,28 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
iwl_down(priv);
flush_workqueue(priv->workqueue);
- free_irq(priv->pci_dev->irq, priv);
- pci_disable_msi(priv->pci_dev);
- pci_save_state(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
- IWL_DEBUG_MAC80211("leave\n");
+ /* enable interrupts again in order to receive rfkill changes */
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_enable_interrupts(priv);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MACDUMP("enter\n");
+ IWL_DEBUG_MACDUMP(priv, "enter\n");
- IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
+ IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
if (iwl_tx_skb(priv, skb))
dev_kfree_skb_any(skb);
- IWL_DEBUG_MACDUMP("leave\n");
- return 0;
+ IWL_DEBUG_MACDUMP(priv, "leave\n");
+ return NETDEV_TX_OK;
}
static int iwl_mac_add_interface(struct ieee80211_hw *hw,
@@ -2491,10 +2142,10 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
struct iwl_priv *priv = hw->priv;
unsigned long flags;
- IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
+ IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
if (priv->vif) {
- IWL_DEBUG_MAC80211("leave - vif != NULL\n");
+ IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
return -EOPNOTSUPP;
}
@@ -2507,7 +2158,7 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (conf->mac_addr) {
- IWL_DEBUG_MAC80211("Set %pM\n", conf->mac_addr);
+ IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
}
@@ -2517,7 +2168,7 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -2538,12 +2189,12 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
u16 channel;
mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
+ IWL_DEBUG_MAC80211(priv, "enter to channel %d\n", conf->channel->hw_value);
- priv->current_ht_config.is_ht = conf->ht.enabled;
+ priv->current_ht_config.is_ht = conf_is_ht(conf);
if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
- IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
+ IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - waiting for uCode\n");
goto out;
}
@@ -2551,14 +2202,14 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
iwl_radio_kill_sw_disable_radio(priv);
if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211("leave - not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
ret = -EIO;
goto out;
}
if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
test_bit(STATUS_SCANNING, &priv->status))) {
- IWL_DEBUG_MAC80211("leave - scanning\n");
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
mutex_unlock(&priv->mutex);
return 0;
}
@@ -2566,14 +2217,14 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
ch_info = iwl_get_channel_info(priv, conf->channel->band, channel);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_MAC80211("leave - invalid channel\n");
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
ret = -EINVAL;
goto out;
}
if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
!is_channel_ibss(ch_info)) {
- IWL_ERROR("channel %d in band %d not IBSS channel\n",
+ IWL_ERR(priv, "channel %d in band %d not IBSS channel\n",
conf->channel->hw_value, conf->channel->band);
ret = -EINVAL;
goto out;
@@ -2611,12 +2262,12 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
#endif
if (!conf->radio_enabled) {
- IWL_DEBUG_MAC80211("leave - radio disabled\n");
+ IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
goto out;
}
if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_MAC80211("leave - RF kill\n");
+ IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
ret = -EIO;
goto out;
}
@@ -2626,22 +2277,25 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
else
ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
if (ret)
- IWL_DEBUG_MAC80211("Error setting power level\n");
+ IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
- IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n",
+ 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);
iwl_set_rate(priv);
+ /* call to ensure that 4965 rx_chain is set properly in monitor mode */
+ iwl_set_rxon_chain(priv);
+
if (memcmp(&priv->active_rxon,
&priv->staging_rxon, sizeof(priv->staging_rxon)))
iwl_commit_rxon(priv);
else
- IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
+ IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
out:
mutex_unlock(&priv->mutex);
@@ -2668,7 +2322,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
iwl_set_rxon_chain(priv);
@@ -2722,7 +2376,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
return -EIO;
if (priv->vif != vif) {
- IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
+ IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
return 0;
}
@@ -2744,7 +2398,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (conf->bssid)
- IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
+ IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
/*
* very dubious code was here; the probe filtering flag is never set:
@@ -2757,7 +2411,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
if (!conf->bssid) {
conf->bssid = priv->mac_addr;
memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+ IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
conf->bssid);
}
if (priv->ibss_beacon)
@@ -2774,9 +2428,9 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
/* 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_WARNING("Aborted scan still in progress "
+ IWL_WARN(priv, "Aborted scan still in progress "
"after 100ms\n");
- IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
mutex_unlock(&priv->mutex);
return -EAGAIN;
}
@@ -2804,64 +2458,18 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
}
done:
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
mutex_unlock(&priv->mutex);
return 0;
}
-static void iwl_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- int mc_count, struct dev_addr_list *mc_list)
-{
- struct iwl_priv *priv = hw->priv;
- __le32 *filter_flags = &priv->staging_rxon.filter_flags;
-
- IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
- changed_flags, *total_flags);
-
- if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
- if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
- *filter_flags |= RXON_FILTER_PROMISC_MSK;
- else
- *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
- }
- if (changed_flags & FIF_ALLMULTI) {
- if (*total_flags & FIF_ALLMULTI)
- *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
- else
- *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
- }
- if (changed_flags & FIF_CONTROL) {
- if (*total_flags & FIF_CONTROL)
- *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
- else
- *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
- }
- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
- *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
- else
- *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
- }
-
- /* We avoid iwl_commit_rxon here to commit the new filter flags
- * since mac80211 will call ieee80211_hw_config immediately.
- * (mc_list is not supported at this time). Otherwise, we need to
- * queue a background iwl_commit_rxon work.
- */
-
- *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
- FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
-}
-
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("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
@@ -2876,7 +2484,7 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
}
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
@@ -2888,10 +2496,10 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+ IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+ 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;
@@ -2900,7 +2508,7 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_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
@@ -2913,7 +2521,7 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->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()))
@@ -2935,108 +2543,49 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
} else {
priv->assoc_id = 0;
- IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+ IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
}
} else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+ IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
iwl_send_rxon_assoc(priv);
}
}
-static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
-{
- unsigned long flags;
- struct iwl_priv *priv = hw->priv;
- int ret;
-
- IWL_DEBUG_MAC80211("enter\n");
-
- mutex_lock(&priv->mutex);
- spin_lock_irqsave(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- ret = -EIO;
- IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
- goto out_unlock;
- }
-
- /* We don't schedule scan within next_scan_jiffies period.
- * Avoid scanning during possible EAPOL exchange, return
- * success immediately.
- */
- if (priv->next_scan_jiffies &&
- time_after(priv->next_scan_jiffies, jiffies)) {
- IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
- queue_work(priv->workqueue, &priv->scan_completed);
- ret = 0;
- goto out_unlock;
- }
-
- /* if we just finished scan ask for delay */
- if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
- time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
- IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
- queue_work(priv->workqueue, &priv->scan_completed);
- ret = 0;
- goto out_unlock;
- }
-
- if (ssid_len) {
- priv->one_direct_scan = 1;
- priv->direct_ssid_len = min_t(u8, ssid_len, IW_ESSID_MAX_SIZE);
- memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
- } else {
- priv->one_direct_scan = 0;
- }
-
- ret = iwl_scan_initiate(priv);
-
- IWL_DEBUG_MAC80211("leave\n");
-
-out_unlock:
- spin_unlock_irqrestore(&priv->lock, flags);
- mutex_unlock(&priv->mutex);
-
- return ret;
-}
-
static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
struct ieee80211_key_conf *keyconf, const u8 *addr,
u32 iv32, u16 *phase1key)
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
- int ret = 0;
- u8 sta_id = IWL_INVALID_STATION;
- u8 is_default_wep_key = 0;
+ const u8 *addr;
+ int ret;
+ u8 sta_id;
+ bool is_default_wep_key = false;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (priv->hw_params.sw_crypto) {
- IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
+ IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
-
- if (is_zero_ether_addr(addr))
- /* only support pairwise keys */
- return -EOPNOTSUPP;
-
+ addr = sta ? sta->addr : iwl_bcast_addr;
sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+ IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
return -EINVAL;
@@ -3066,7 +2615,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
else
ret = iwl_set_dynamic_key(priv, key, sta_id);
- IWL_DEBUG_MAC80211("enable hwcrypto key\n");
+ IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
break;
case DISABLE_KEY:
if (is_default_wep_key)
@@ -3074,13 +2623,13 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
else
ret = iwl_remove_dynamic_key(priv, key, sta_id);
- IWL_DEBUG_MAC80211("disable hwcrypto key\n");
+ IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
break;
default:
ret = -EINVAL;
}
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return ret;
}
@@ -3092,15 +2641,15 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
unsigned long flags;
int q;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211("leave - queue >= AC_NUM %d\n", queue);
+ IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
return 0;
}
@@ -3124,7 +2673,7 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -3134,7 +2683,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_HT("A-MPDU action on addr %pM tid %d\n",
+ IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
sta->addr, tid);
if (!(priv->cfg->sku & IWL_SKU_N))
@@ -3142,19 +2691,19 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
switch (action) {
case IEEE80211_AMPDU_RX_START:
- IWL_DEBUG_HT("start Rx\n");
+ IWL_DEBUG_HT(priv, "start Rx\n");
return iwl_sta_rx_agg_start(priv, sta->addr, tid, *ssn);
case IEEE80211_AMPDU_RX_STOP:
- IWL_DEBUG_HT("stop Rx\n");
+ IWL_DEBUG_HT(priv, "stop Rx\n");
return iwl_sta_rx_agg_stop(priv, sta->addr, tid);
case IEEE80211_AMPDU_TX_START:
- IWL_DEBUG_HT("start Tx\n");
+ IWL_DEBUG_HT(priv, "start Tx\n");
return iwl_tx_agg_start(priv, sta->addr, tid, ssn);
case IEEE80211_AMPDU_TX_STOP:
- IWL_DEBUG_HT("stop Tx\n");
+ IWL_DEBUG_HT(priv, "stop Tx\n");
return iwl_tx_agg_stop(priv, sta->addr, tid);
default:
- IWL_DEBUG_HT("unknown\n");
+ IWL_DEBUG_HT(priv, "unknown\n");
return -EINVAL;
break;
}
@@ -3170,10 +2719,10 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
struct iwl_queue *q;
unsigned long flags;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
@@ -3191,7 +2740,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
}
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -3202,8 +2751,8 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
struct iwl_priv *priv = hw->priv;
priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -3214,7 +2763,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
unsigned long flags;
mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
spin_lock_irqsave(&priv->lock, flags);
memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
@@ -3241,7 +2790,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
spin_unlock_irqrestore(&priv->lock, flags);
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
mutex_unlock(&priv->mutex);
return;
}
@@ -3270,7 +2819,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
IEEE80211_CHAN_RADAR))
iwl_power_disable_management(priv, 3000);
- IWL_DEBUG_MAC80211("leave - not in IBSS\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
mutex_unlock(&priv->mutex);
return;
}
@@ -3279,7 +2828,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -3288,15 +2837,15 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
unsigned long flags;
__le64 timestamp;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211("leave - not IBSS\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
return -EIO;
}
@@ -3311,7 +2860,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
priv->timestamp = le64_to_cpu(timestamp);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
iwl_reset_qos(priv);
@@ -3355,8 +2904,7 @@ static ssize_t store_debug_level(struct device *d,
ret = strict_strtoul(buf, 0, &val);
if (ret)
- printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
+ IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
else
priv->debug_level = val;
@@ -3435,8 +2983,7 @@ static ssize_t store_tx_power(struct device *d,
ret = strict_strtoul(buf, 10, &val);
if (ret)
- printk(KERN_INFO DRV_NAME
- ": %s is not in decimal form.\n", buf);
+ IWL_INFO(priv, "%s is not in decimal form.\n", buf);
else
iwl_set_tx_power(priv, val, false);
@@ -3469,9 +3016,9 @@ static ssize_t store_flags(struct device *d,
if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags);
+ IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
iwl_commit_rxon(priv);
}
@@ -3508,9 +3055,9 @@ static ssize_t store_filter_flags(struct device *d,
if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Committing rxon.filter_flags = "
+ IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
@@ -3525,31 +3072,6 @@ static ssize_t store_filter_flags(struct device *d,
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
store_filter_flags);
-static ssize_t store_retry_rate(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwl_priv *priv = dev_get_drvdata(d);
- long val;
- int ret = strict_strtol(buf, 10, &val);
- if (!ret)
- return ret;
-
- priv->retry_rate = (val > 0) ? val : 1;
-
- return count;
-}
-
-static ssize_t show_retry_rate(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl_priv *priv = dev_get_drvdata(d);
- return sprintf(buf, "%d", priv->retry_rate);
-}
-
-static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
- store_retry_rate);
-
static ssize_t store_power_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -3572,7 +3094,7 @@ static ssize_t store_power_level(struct device *d,
ret = iwl_power_set_user_mode(priv, mode);
if (ret) {
- IWL_DEBUG_MAC80211("failed setting power mode.\n");
+ IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
goto out;
}
ret = count;
@@ -3652,16 +3174,6 @@ static ssize_t show_statistics(struct device *d,
static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
-static ssize_t show_status(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- if (!iwl_is_alive(priv))
- return -EAGAIN;
- return sprintf(buf, "0x%08x\n", (int)priv->status);
-}
-
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
/*****************************************************************************
*
@@ -3671,7 +3183,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static void iwl_setup_deferred_work(struct iwl_priv *priv)
{
- priv->workqueue = create_workqueue(DRV_NAME);
+ priv->workqueue = create_singlethread_workqueue(DRV_NAME);
init_waitqueue_head(&priv->wait_command_queue);
@@ -3715,9 +3227,7 @@ static struct attribute *iwl_sysfs_entries[] = {
&dev_attr_flags.attr,
&dev_attr_filter_flags.attr,
&dev_attr_power_level.attr,
- &dev_attr_retry_rate.attr,
&dev_attr_statistics.attr,
- &dev_attr_status.attr,
&dev_attr_temperature.attr,
&dev_attr_tx_power.attr,
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -3760,6 +3270,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
unsigned long flags;
+ u16 pci_cmd;
/************************
* 1. Allocating HW data
@@ -3784,7 +3295,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_IEEE80211_DEV(hw, &pdev->dev);
- IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
+ IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
priv->cfg = cfg;
priv->pci_dev = pdev;
@@ -3812,8 +3323,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
/* both attempts failed: */
if (err) {
- printk(KERN_WARNING "%s: No suitable DMA available.\n",
- DRV_NAME);
+ IWL_WARN(priv, "No suitable DMA available.\n");
goto out_pci_disable_device;
}
}
@@ -3834,13 +3344,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_pci_release_regions;
}
- IWL_DEBUG_INFO("pci_resource_len = 0x%08llx\n",
+ IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n",
(unsigned long long) pci_resource_len(pdev, 0));
- IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
+ IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
iwl_hw_detect(priv);
- printk(KERN_INFO DRV_NAME
- ": Detected Intel Wireless WiFi Link %s REV=0x%X\n",
+ IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
priv->cfg->name, priv->hw_rev);
/* We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -3850,7 +3359,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* amp init */
err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
- IWL_DEBUG_INFO("Failed to init APMG\n");
+ IWL_ERR(priv, "Failed to init APMG\n");
goto out_iounmap;
}
/*****************
@@ -3859,23 +3368,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Read the EEPROM */
err = iwl_eeprom_init(priv);
if (err) {
- IWL_ERROR("Unable to init EEPROM\n");
+ IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_iounmap;
}
err = iwl_eeprom_check_version(priv);
if (err)
- goto out_iounmap;
+ goto out_free_eeprom;
/* extract MAC Address */
iwl_eeprom_get_mac(priv, priv->mac_addr);
- IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
+ IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr);
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
/************************
* 5. Setup HW constants
************************/
if (iwl_set_hw_params(priv)) {
- IWL_ERROR("failed to set hw parameters\n");
+ IWL_ERR(priv, "failed to set hw parameters\n");
goto out_free_eeprom;
}
@@ -3895,7 +3404,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* 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("Radio disabled.\n");
+ IWL_DEBUG_INFO(priv, "Radio disabled.\n");
}
/********************
@@ -3905,52 +3414,76 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
+ pci_enable_msi(priv->pci_dev);
+
+ err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
+ DRV_NAME, priv);
+ if (err) {
+ IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
+ goto out_disable_msi;
+ }
err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
if (err) {
- IWL_ERROR("failed to create sysfs device attributes\n");
- goto out_uninit_drv;
+ IWL_ERR(priv, "failed to create sysfs device attributes\n");
+ goto out_free_irq;
}
-
iwl_setup_deferred_work(priv);
iwl_setup_rx_handlers(priv);
- /********************
- * 9. Conclude
- ********************/
- pci_save_state(pdev);
- pci_disable_device(pdev);
-
/**********************************
- * 10. Setup and register mac80211
+ * 9. Setup and register mac80211
**********************************/
+ /* enable interrupts if needed: hw bug w/a */
+ pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
+ if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
+ pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+ pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
+ }
+
+ iwl_enable_interrupts(priv);
+
err = iwl_setup_mac(priv);
if (err)
goto out_remove_sysfs;
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
- IWL_ERROR("failed to create debugfs files\n");
+ IWL_ERR(priv, "failed to create debugfs files\n");
+
+ /* If platform's RF_KILL switch is NOT set to KILL */
+ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
err = iwl_rfkill_init(priv);
if (err)
- IWL_ERROR("Unable to initialize RFKILL system. "
+ IWL_ERR(priv, "Unable to initialize RFKILL system. "
"Ignoring error: %d\n", err);
+ else
+ iwl_rfkill_set_hw_state(priv);
+
iwl_power_initialize(priv);
return 0;
out_remove_sysfs:
+ destroy_workqueue(priv->workqueue);
+ priv->workqueue = NULL;
sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
- out_uninit_drv:
+ out_free_irq:
+ free_irq(priv->pci_dev->irq, priv);
+ out_disable_msi:
+ pci_disable_msi(priv->pci_dev);
iwl_uninit_drv(priv);
out_free_eeprom:
iwl_eeprom_free(priv);
out_iounmap:
pci_iounmap(pdev, priv->hw_base);
out_pci_release_regions:
- pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
+ pci_release_regions(pdev);
out_pci_disable_device:
pci_disable_device(pdev);
out_ieee80211_free_hw:
@@ -3967,7 +3500,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
if (!priv)
return;
- IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
+ IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
iwl_dbgfs_unregister(priv);
sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
@@ -4013,6 +3546,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
+ free_irq(priv->pci_dev->irq, priv);
+ pci_disable_msi(priv->pci_dev);
pci_iounmap(pdev, priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -4038,6 +3573,8 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
priv->is_open = 1;
}
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
@@ -4046,8 +3583,14 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
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);
@@ -4088,6 +3631,21 @@ static struct pci_device_id iwl_hw_card_ids[] = {
/* 5150 Wifi/WiMax */
{IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
{IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
+/* 6000/6050 Series */
+ {IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)},
+/* 1000 Series WiFi */
+ {IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl1000_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl1000_bgn_cfg)},
#endif /* CONFIG_IWL5000 */
{0}
@@ -4114,13 +3672,14 @@ static int __init iwl_init(void)
ret = iwlagn_rate_control_register();
if (ret) {
- IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+ printk(KERN_ERR DRV_NAME
+ "Unable to register rate control algorithm: %d\n", ret);
return ret;
}
ret = pci_register_driver(&iwl_driver);
if (ret) {
- IWL_ERROR("Unable to initialize PCI module\n");
+ printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
goto error_register;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index f836ecc5575..735f3f19928 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -102,7 +102,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
return 0;
err:
- IWL_ERROR("Error %d iteration %d\n", ret, i);
+ IWL_ERR(priv, "Error %d iteration %d\n", ret, i);
return ret;
}
EXPORT_SYMBOL(iwl_send_calib_results);
@@ -202,7 +202,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
val = data->nrg_silence_rssi[i];
silence_ref = max(silence_ref, val);
}
- IWL_DEBUG_CALIB("silence a %u, b %u, c %u, 20-bcn max %u\n",
+ IWL_DEBUG_CALIB(priv, "silence a %u, b %u, c %u, 20-bcn max %u\n",
silence_rssi_a, silence_rssi_b, silence_rssi_c,
silence_ref);
@@ -226,7 +226,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
max_nrg_cck = (u32) max(max_nrg_cck, (data->nrg_value[i]));
max_nrg_cck += 6;
- IWL_DEBUG_CALIB("rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
+ IWL_DEBUG_CALIB(priv, "rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
rx_info->beacon_energy_a, rx_info->beacon_energy_b,
rx_info->beacon_energy_c, max_nrg_cck - 6);
@@ -236,15 +236,15 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
data->num_in_cck_no_fa++;
else
data->num_in_cck_no_fa = 0;
- IWL_DEBUG_CALIB("consecutive bcns with few false alarms = %u\n",
+ IWL_DEBUG_CALIB(priv, "consecutive bcns with few false alarms = %u\n",
data->num_in_cck_no_fa);
/* If we got too many false alarms this time, reduce sensitivity */
if ((false_alarms > max_false_alarms) &&
(data->auto_corr_cck > AUTO_CORR_MAX_TH_CCK)) {
- IWL_DEBUG_CALIB("norm FA %u > max FA %u\n",
+ IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u\n",
false_alarms, max_false_alarms);
- IWL_DEBUG_CALIB("... reducing sensitivity\n");
+ IWL_DEBUG_CALIB(priv, "... reducing sensitivity\n");
data->nrg_curr_state = IWL_FA_TOO_MANY;
/* Store for "fewer than desired" on later beacon */
data->nrg_silence_ref = silence_ref;
@@ -266,7 +266,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
data->nrg_auto_corr_silence_diff = (s32)data->nrg_silence_ref -
(s32)silence_ref;
- IWL_DEBUG_CALIB("norm FA %u < min FA %u, silence diff %d\n",
+ IWL_DEBUG_CALIB(priv, "norm FA %u < min FA %u, silence diff %d\n",
false_alarms, min_false_alarms,
data->nrg_auto_corr_silence_diff);
@@ -280,17 +280,17 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
((data->nrg_auto_corr_silence_diff > NRG_DIFF) ||
(data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) {
- IWL_DEBUG_CALIB("... increasing sensitivity\n");
+ IWL_DEBUG_CALIB(priv, "... increasing sensitivity\n");
/* Increase nrg value to increase sensitivity */
val = data->nrg_th_cck + NRG_STEP_CCK;
data->nrg_th_cck = min((u32)ranges->min_nrg_cck, val);
} else {
- IWL_DEBUG_CALIB("... but not changing sensitivity\n");
+ IWL_DEBUG_CALIB(priv, "... but not changing sensitivity\n");
}
/* Else we got a healthy number of false alarms, keep status quo */
} else {
- IWL_DEBUG_CALIB(" FA in safe zone\n");
+ IWL_DEBUG_CALIB(priv, " FA in safe zone\n");
data->nrg_curr_state = IWL_FA_GOOD_RANGE;
/* Store for use in "fewer than desired" with later beacon */
@@ -300,7 +300,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
* give it some extra margin by reducing sensitivity again
* (but don't go below measured energy of desired Rx) */
if (IWL_FA_TOO_MANY == data->nrg_prev_state) {
- IWL_DEBUG_CALIB("... increasing margin\n");
+ IWL_DEBUG_CALIB(priv, "... increasing margin\n");
if (data->nrg_th_cck > (max_nrg_cck + NRG_MARGIN))
data->nrg_th_cck -= NRG_MARGIN;
else
@@ -314,7 +314,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
* Lower value is higher energy, so we use max()!
*/
data->nrg_th_cck = max(max_nrg_cck, data->nrg_th_cck);
- IWL_DEBUG_CALIB("new nrg_th_cck %u\n", data->nrg_th_cck);
+ IWL_DEBUG_CALIB(priv, "new nrg_th_cck %u\n", data->nrg_th_cck);
data->nrg_prev_state = data->nrg_curr_state;
@@ -367,7 +367,7 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
/* If we got too many false alarms this time, reduce sensitivity */
if (false_alarms > max_false_alarms) {
- IWL_DEBUG_CALIB("norm FA %u > max FA %u)\n",
+ IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u)\n",
false_alarms, max_false_alarms);
val = data->auto_corr_ofdm + AUTO_CORR_STEP_OFDM;
@@ -390,7 +390,7 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
/* Else if we got fewer than desired, increase sensitivity */
else if (false_alarms < min_false_alarms) {
- IWL_DEBUG_CALIB("norm FA %u < min FA %u\n",
+ IWL_DEBUG_CALIB(priv, "norm FA %u < min FA %u\n",
false_alarms, min_false_alarms);
val = data->auto_corr_ofdm - AUTO_CORR_STEP_OFDM;
@@ -409,7 +409,7 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
data->auto_corr_ofdm_mrc_x1 =
max((u32)ranges->auto_corr_min_ofdm_mrc_x1, val);
} else {
- IWL_DEBUG_CALIB("min FA %u < norm FA %u < max FA %u OK\n",
+ IWL_DEBUG_CALIB(priv, "min FA %u < norm FA %u < max FA %u OK\n",
min_false_alarms, false_alarms, max_false_alarms);
}
return 0;
@@ -452,18 +452,18 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
cpu_to_le16((u16)data->nrg_th_ofdm);
cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
- __constant_cpu_to_le16(190);
+ cpu_to_le16(190);
cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
- __constant_cpu_to_le16(390);
+ cpu_to_le16(390);
cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] =
- __constant_cpu_to_le16(62);
+ cpu_to_le16(62);
- IWL_DEBUG_CALIB("ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
+ IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
data->auto_corr_ofdm, data->auto_corr_ofdm_mrc,
data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1,
data->nrg_th_ofdm);
- IWL_DEBUG_CALIB("cck: ac %u mrc %u thresh %u\n",
+ IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n",
data->auto_corr_cck, data->auto_corr_cck_mrc,
data->nrg_th_cck);
@@ -473,7 +473,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
/* Don't send command to uCode if nothing has changed */
if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]),
sizeof(u16)*HD_TABLE_SIZE)) {
- IWL_DEBUG_CALIB("No change in SENSITIVITY_CMD\n");
+ IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n");
return 0;
}
@@ -483,7 +483,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
ret = iwl_send_cmd(priv, &cmd_out);
if (ret)
- IWL_ERROR("SENSITIVITY_CMD failed\n");
+ IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
return ret;
}
@@ -498,7 +498,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
if (priv->disable_sens_cal)
return;
- IWL_DEBUG_CALIB("Start iwl_init_sensitivity\n");
+ IWL_DEBUG_CALIB(priv, "Start iwl_init_sensitivity\n");
/* Clear driver's sensitivity algo data */
data = &(priv->sensitivity_data);
@@ -536,7 +536,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
data->last_fa_cnt_cck = 0;
ret |= iwl_sensitivity_write(priv);
- IWL_DEBUG_CALIB("<<return 0x%X\n", ret);
+ IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
}
EXPORT_SYMBOL(iwl_init_sensitivity);
@@ -562,13 +562,13 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
data = &(priv->sensitivity_data);
if (!iwl_is_associated(priv)) {
- IWL_DEBUG_CALIB("<< - not associated\n");
+ IWL_DEBUG_CALIB(priv, "<< - not associated\n");
return;
}
spin_lock_irqsave(&priv->lock, flags);
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
- IWL_DEBUG_CALIB("<< invalid data.\n");
+ IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
spin_unlock_irqrestore(&priv->lock, flags);
return;
}
@@ -595,10 +595,10 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_CALIB("rx_enable_time = %u usecs\n", rx_enable_time);
+ IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time);
if (!rx_enable_time) {
- IWL_DEBUG_CALIB("<< RX Enable Time == 0! \n");
+ IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0! \n");
return;
}
@@ -637,7 +637,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
norm_fa_ofdm = fa_ofdm + bad_plcp_ofdm;
norm_fa_cck = fa_cck + bad_plcp_cck;
- IWL_DEBUG_CALIB("cck: fa %u badp %u ofdm: fa %u badp %u\n", fa_cck,
+ IWL_DEBUG_CALIB(priv, "cck: fa %u badp %u ofdm: fa %u badp %u\n", fa_cck,
bad_plcp_cck, fa_ofdm, bad_plcp_ofdm);
iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
@@ -690,13 +690,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
* then we're done forever. */
if (data->state != IWL_CHAIN_NOISE_ACCUMULATE) {
if (data->state == IWL_CHAIN_NOISE_ALIVE)
- IWL_DEBUG_CALIB("Wait for noise calib reset\n");
+ IWL_DEBUG_CALIB(priv, "Wait for noise calib reset\n");
return;
}
spin_lock_irqsave(&priv->lock, flags);
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
- IWL_DEBUG_CALIB(" << Interference data unavailable\n");
+ IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
spin_unlock_irqrestore(&priv->lock, flags);
return;
}
@@ -709,7 +709,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
/* Make sure we accumulate data for just the associated channel
* (even if scanning). */
if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) {
- IWL_DEBUG_CALIB("Stats not from chan=%d, band24=%d\n",
+ IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n",
rxon_chnum, rxon_band24);
spin_unlock_irqrestore(&priv->lock, flags);
return;
@@ -739,11 +739,11 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
data->chain_signal_b = (chain_sig_b + data->chain_signal_b);
data->chain_signal_c = (chain_sig_c + data->chain_signal_c);
- IWL_DEBUG_CALIB("chan=%d, band24=%d, beacon=%d\n",
+ IWL_DEBUG_CALIB(priv, "chan=%d, band24=%d, beacon=%d\n",
rxon_chnum, rxon_band24, data->beacon_count);
- IWL_DEBUG_CALIB("chain_sig: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "chain_sig: a %d b %d c %d\n",
chain_sig_a, chain_sig_b, chain_sig_c);
- IWL_DEBUG_CALIB("chain_noise: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "chain_noise: a %d b %d c %d\n",
chain_noise_a, chain_noise_b, chain_noise_c);
/* If this is the 20th beacon, determine:
@@ -773,9 +773,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
active_chains = (1 << max_average_sig_antenna_i);
}
- IWL_DEBUG_CALIB("average_sig: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
average_sig[0], average_sig[1], average_sig[2]);
- IWL_DEBUG_CALIB("max_average_sig = %d, antenna %d\n",
+ IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
max_average_sig, max_average_sig_antenna_i);
/* Compare signal strengths for all 3 receivers. */
@@ -789,7 +789,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
data->disconn_array[i] = 1;
else
active_chains |= (1 << i);
- IWL_DEBUG_CALIB("i = %d rssiDelta = %d "
+ IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d "
"disconn_array[i] = %d\n",
i, rssi_delta, data->disconn_array[i]);
}
@@ -813,7 +813,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
* disconnected connect it anyway */
data->disconn_array[i] = 0;
active_chains |= ant_msk;
- IWL_DEBUG_CALIB("All Tx chains are disconnected W/A - "
+ IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - "
"declare %d as connected\n", i);
break;
}
@@ -821,7 +821,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
/* Save for use within RXON, TX, SCAN commands, etc. */
priv->chain_noise_data.active_chains = active_chains;
- IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n",
+ IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
active_chains);
/* Analyze noise for rx balance */
@@ -839,15 +839,16 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
}
}
- IWL_DEBUG_CALIB("average_noise: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "average_noise: a %d b %d c %d\n",
average_noise[0], average_noise[1],
average_noise[2]);
- IWL_DEBUG_CALIB("min_average_noise = %d, antenna %d\n",
+ IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n",
min_average_noise, min_average_noise_antenna_i);
- priv->cfg->ops->utils->gain_computation(priv, average_noise,
- min_average_noise_antenna_i, min_average_noise);
+ if (priv->cfg->ops->utils->gain_computation)
+ priv->cfg->ops->utils->gain_computation(priv, average_noise,
+ min_average_noise_antenna_i, min_average_noise);
/* Some power changes may have been made during the calibration.
* Update and commit the RXON
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index 1abe84bb74a..b6cef989a79 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index ba997204c8d..29d40746da6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,12 +69,20 @@
#ifndef __iwl_commands_h__
#define __iwl_commands_h__
+struct iwl_priv;
+
/* uCode version contains 4 values: Major/Minor/API/Serial */
#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
+
+/* Tx rates */
+#define IWL_CCK_RATES 4
+#define IWL_OFDM_RATES 8
+#define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES)
+
enum {
REPLY_ALIVE = 0x1,
REPLY_ERROR = 0x2,
@@ -136,9 +144,11 @@ enum {
WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */
/* Miscellaneous commands */
+ REPLY_TX_POWER_DBM_CMD = 0x95,
QUIET_NOTIFICATION = 0x96, /* not used */
REPLY_TX_PWR_TABLE_CMD = 0x97,
- REPLY_TX_POWER_DBM_CMD = 0x98,
+ REPLY_TX_POWER_DBM_CMD_V1 = 0x98, /* old version of API */
+ TX_ANT_CONFIGURATION_CMD = 0x98, /* not used */
MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */
/* Bluetooth device coexistence config command */
@@ -219,6 +229,37 @@ struct iwl_cmd_header {
u8 data[0];
} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_tx_power
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
+ *
+ * Each entry contains two values:
+ * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained
+ * linear value that multiplies the output of the digital signal processor,
+ * before being sent to the analog radio.
+ * 2) Radio gain. This sets the analog gain of the radio Tx path.
+ * It is a coarser setting, and behaves in a logarithmic (dB) fashion.
+ *
+ * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
+ */
+struct iwl3945_tx_power {
+ u8 tx_gain; /* gain for analog radio */
+ u8 dsp_atten; /* gain for DSP */
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_power_per_rate
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
+ */
+struct iwl3945_power_per_rate {
+ u8 rate; /* plcp */
+ struct iwl3945_tx_power tpc;
+ u8 reserved;
+} __attribute__ ((packed));
+
/**
* iwlagn rate_n_flags bit fields
*
@@ -300,11 +341,12 @@ struct iwl_cmd_header {
* 5350 has 3 transmitters
* bit14:16
*/
-#define RATE_MCS_ANT_POS 14
-#define RATE_MCS_ANT_A_MSK 0x04000
-#define RATE_MCS_ANT_B_MSK 0x08000
-#define RATE_MCS_ANT_C_MSK 0x10000
-#define RATE_MCS_ANT_ABC_MSK 0x1C000
+#define RATE_MCS_ANT_POS 14
+#define RATE_MCS_ANT_A_MSK 0x04000
+#define RATE_MCS_ANT_B_MSK 0x08000
+#define RATE_MCS_ANT_C_MSK 0x10000
+#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | RATE_MCS_ANT_B_MSK)
+#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | RATE_MCS_ANT_C_MSK)
#define RATE_ANT_NUM 3
#define POWER_TABLE_NUM_ENTRIES 33
@@ -492,8 +534,6 @@ struct iwl_alive_resp {
__le32 is_valid;
} __attribute__ ((packed));
-
-
/*
* REPLY_ERROR = 0x2 (response only, not a command)
*/
@@ -525,6 +565,7 @@ enum {
#define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0)
+#define RXON_RX_CHAIN_DRIVER_FORCE_POS (0)
#define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1)
#define RXON_RX_CHAIN_VALID_POS (1)
#define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4)
@@ -611,6 +652,26 @@ enum {
* issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
* regardless of whether RXON_FILTER_ASSOC_MSK is set.
*/
+
+struct iwl3945_rxon_cmd {
+ u8 node_addr[6];
+ __le16 reserved1;
+ u8 bssid_addr[6];
+ __le16 reserved2;
+ u8 wlap_bssid_addr[6];
+ __le16 reserved3;
+ u8 dev_type;
+ u8 air_propagation;
+ __le16 reserved4;
+ u8 ofdm_basic_rates;
+ u8 cck_basic_rates;
+ __le16 assoc_id;
+ __le32 flags;
+ __le32 filter_flags;
+ __le16 channel;
+ __le16 reserved5;
+} __attribute__ ((packed));
+
struct iwl4965_rxon_cmd {
u8 node_addr[6];
__le16 reserved1;
@@ -656,33 +717,41 @@ struct iwl_rxon_cmd {
__le16 reserved6;
} __attribute__ ((packed));
-struct iwl5000_rxon_assoc_cmd {
+/*
+ * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
+ */
+struct iwl3945_rxon_assoc_cmd {
+ __le32 flags;
+ __le32 filter_flags;
+ u8 ofdm_basic_rates;
+ u8 cck_basic_rates;
+ __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwl4965_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
u8 cck_basic_rates;
- __le16 reserved1;
u8 ofdm_ht_single_stream_basic_rates;
u8 ofdm_ht_dual_stream_basic_rates;
- u8 ofdm_ht_triple_stream_basic_rates;
- u8 reserved2;
__le16 rx_chain_select_flags;
- __le16 acquisition_data;
- __le32 reserved3;
+ __le16 reserved;
} __attribute__ ((packed));
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl4965_rxon_assoc_cmd {
+struct iwl5000_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
u8 cck_basic_rates;
+ __le16 reserved1;
u8 ofdm_ht_single_stream_basic_rates;
u8 ofdm_ht_dual_stream_basic_rates;
+ u8 ofdm_ht_triple_stream_basic_rates;
+ u8 reserved2;
__le16 rx_chain_select_flags;
- __le16 reserved;
+ __le16 acquisition_data;
+ __le32 reserved3;
} __attribute__ ((packed));
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
@@ -702,6 +771,16 @@ struct iwl_rxon_time_cmd {
/*
* REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
*/
+struct iwl3945_channel_switch_cmd {
+ u8 band;
+ u8 expect_beacon;
+ __le16 channel;
+ __le32 rxon_flags;
+ __le32 rxon_filter_flags;
+ __le32 switch_time;
+ struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
struct iwl_channel_switch_cmd {
u8 band;
u8 expect_beacon;
@@ -783,6 +862,8 @@ struct iwl_qosparam_cmd {
#define IWL_AP_ID 0
#define IWL_MULTICAST_ID 1
#define IWL_STA_ID 2
+#define IWL3945_BROADCAST_ID 24
+#define IWL3945_STATION_COUNT 25
#define IWL4965_BROADCAST_ID 31
#define IWL4965_STATION_COUNT 32
#define IWL5000_BROADCAST_ID 15
@@ -791,6 +872,8 @@ struct iwl_qosparam_cmd {
#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
#define IWL_INVALID_STATION 255
+#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2);
+#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
#define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17)
#define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18)
@@ -901,6 +984,35 @@ struct sta_id_modify {
* used as AP, or in an IBSS network, driver must set up station table
* entries for all STAs in network, starting with index IWL_STA_ID.
*/
+
+struct iwl3945_addsta_cmd {
+ u8 mode; /* 1: modify existing, 0: add new station */
+ u8 reserved[3];
+ struct sta_id_modify sta;
+ struct iwl4965_keyinfo key;
+ __le32 station_flags; /* STA_FLG_* */
+ __le32 station_flags_msk; /* STA_FLG_* */
+
+ /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
+ * corresponding to bit (e.g. bit 5 controls TID 5).
+ * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
+ __le16 tid_disable_tx;
+
+ __le16 rate_n_flags;
+
+ /* TID for which to add block-ack support.
+ * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+ u8 add_immediate_ba_tid;
+
+ /* TID for which to remove block-ack support.
+ * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
+ u8 remove_immediate_ba_tid;
+
+ /* Starting Sequence Number for added block-ack support.
+ * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+ __le16 add_immediate_ba_ssn;
+} __attribute__ ((packed));
+
struct iwl4965_addsta_cmd {
u8 mode; /* 1: modify existing, 0: add new station */
u8 reserved[3];
@@ -1054,6 +1166,48 @@ struct iwl_wep_cmd {
#define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7)
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
+
+struct iwl3945_rx_frame_stats {
+ u8 phy_count;
+ u8 id;
+ u8 rssi;
+ u8 agc;
+ __le16 sig_avg;
+ __le16 noise_diff;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_hdr {
+ __le16 channel;
+ __le16 phy_flags;
+ u8 reserved1;
+ u8 rate;
+ __le16 len;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_end {
+ __le32 status;
+ __le64 timestamp;
+ __le32 beacon_timestamp;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_3945_RX = 0x1b (response only, not a command)
+ *
+ * NOTE: DO NOT dereference from casts to this structure
+ * It is provided only for calculating minimum data set size.
+ * The actual offsets of the hdr and end are dynamic based on
+ * stats.phy_count
+ */
+struct iwl3945_rx_frame {
+ struct iwl3945_rx_frame_stats stats;
+ struct iwl3945_rx_frame_hdr hdr;
+ struct iwl3945_rx_frame_end end;
+} __attribute__ ((packed));
+
+#define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
+
/* Fixed (non-configurable) rx data from phy */
#define IWL49_RX_RES_PHY_CNT 14
@@ -1234,6 +1388,84 @@ struct iwl4965_rx_mpdu_res_start {
#define TKIP_ICV_LEN 4
/*
+ * REPLY_TX = 0x1c (command)
+ */
+
+struct iwl3945_tx_cmd {
+ /*
+ * MPDU byte count:
+ * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
+ * + 8 byte IV for CCM or TKIP (not used for WEP)
+ * + Data payload
+ * + 8-byte MIC (not used for CCM/WEP)
+ * NOTE: Does not include Tx command bytes, post-MAC pad bytes,
+ * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
+ * Range: 14-2342 bytes.
+ */
+ __le16 len;
+
+ /*
+ * MPDU or MSDU byte count for next frame.
+ * Used for fragmentation and bursting, but not 11n aggregation.
+ * Same as "len", but for next frame. Set to 0 if not applicable.
+ */
+ __le16 next_frame_len;
+
+ __le32 tx_flags; /* TX_CMD_FLG_* */
+
+ u8 rate;
+
+ /* Index of recipient station in uCode's station table */
+ u8 sta_id;
+ u8 tid_tspec;
+ u8 sec_ctl;
+ u8 key[16];
+ union {
+ u8 byte[8];
+ __le16 word[4];
+ __le32 dw[2];
+ } tkip_mic;
+ __le32 next_frame_info;
+ union {
+ __le32 life_time;
+ __le32 attempt;
+ } stop_time;
+ u8 supp_rates[2];
+ u8 rts_retry_limit; /*byte 50 */
+ u8 data_retry_limit; /*byte 51 */
+ union {
+ __le16 pm_frame_timeout;
+ __le16 attempt_duration;
+ } timeout;
+
+ /*
+ * Duration of EDCA burst Tx Opportunity, in 32-usec units.
+ * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
+ */
+ __le16 driver_txop;
+
+ /*
+ * MAC header goes here, followed by 2 bytes padding if MAC header
+ * length is 26 or 30 bytes, followed by payload data
+ */
+ u8 payload[0];
+ struct ieee80211_hdr hdr[0];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX = 0x1c (response)
+ */
+struct iwl3945_tx_resp {
+ u8 failure_rts;
+ u8 failure_frame;
+ u8 bt_kill_count;
+ u8 rate;
+ __le32 wireless_media_time;
+ __le32 status; /* TX status */
+} __attribute__ ((packed));
+
+
+/*
* 4965 uCode updates these Tx attempt count values in host DRAM.
* Used for managing Tx retries when expecting block-acks.
* Driver should set these fields to 0.
@@ -1244,9 +1476,6 @@ struct iwl_dram_scratch {
__le16 reserved;
} __attribute__ ((packed));
-/*
- * REPLY_TX = 0x1c (command)
- */
struct iwl_tx_cmd {
/*
* MPDU byte count:
@@ -1584,6 +1813,14 @@ struct iwl_compressed_ba_resp {
*
* See details under "TXPOWER" in iwl-4965-hw.h.
*/
+
+struct iwl3945_txpowertable_cmd {
+ u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
+ u8 reserved;
+ __le16 channel;
+ struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
struct iwl4965_txpowertable_cmd {
u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
u8 reserved;
@@ -1591,6 +1828,35 @@ struct iwl4965_txpowertable_cmd {
struct iwl4965_tx_power_db tx_power;
} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
+ *
+ * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
+ *
+ * NOTE: The table of rates passed to the uCode via the
+ * RATE_SCALE command sets up the corresponding order of
+ * rates used for all related commands, including rate
+ * masks, etc.
+ *
+ * For example, if you set 9MB (PLCP 0x0f) as the first
+ * rate in the rate table, the bit mask for that rate
+ * when passed through ofdm_basic_rates on the REPLY_RXON
+ * command would be bit 0 (1 << 0)
+ */
+struct iwl3945_rate_scaling_info {
+ __le16 rate_n_flags;
+ u8 try_cnt;
+ u8 next_rate_index;
+} __attribute__ ((packed));
+
+struct iwl3945_rate_scaling_cmd {
+ u8 table_id;
+ u8 reserved[3];
+ struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
+
/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0)
@@ -2044,15 +2310,23 @@ struct iwl_spectrum_notification {
*/
#define IWL_POWER_VEC_SIZE 5
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(1 << 0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(1 << 2)
-#define IWL_POWER_PCI_PM_MSK cpu_to_le16(1 << 3)
-#define IWL_POWER_FAST_PD cpu_to_le16(1 << 4)
+#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0))
+#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2))
+#define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3))
+#define IWL_POWER_FAST_PD cpu_to_le16(BIT(4))
+
+struct iwl3945_powertable_cmd {
+ __le16 flags;
+ u8 reserved[2];
+ __le32 rx_data_timeout;
+ __le32 tx_data_timeout;
+ __le32 sleep_interval[IWL_POWER_VEC_SIZE];
+} __attribute__ ((packed));
struct iwl_powertable_cmd {
__le16 flags;
- u8 keep_alive_seconds;
- u8 debug_flags;
+ u8 keep_alive_seconds; /* 3945 reserved */
+ u8 debug_flags; /* 3945 reserved */
__le32 rx_data_timeout;
__le32 tx_data_timeout;
__le32 sleep_interval[IWL_POWER_VEC_SIZE];
@@ -2143,6 +2417,26 @@ struct iwl_ct_kill_config {
* passive_dwell < max_out_time
* active_dwell < max_out_time
*/
+
+/* FIXME: rename to AP1, remove tpc */
+struct iwl3945_scan_channel {
+ /*
+ * type is defined as:
+ * 0:0 1 = active, 0 = passive
+ * 1:4 SSID direct bit map; if a bit is set, then corresponding
+ * SSID IE is transmitted in probe request.
+ * 5:7 reserved
+ */
+ u8 type;
+ u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */
+ struct iwl3945_tx_power tpc;
+ __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
+ __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
+} __attribute__ ((packed));
+
+/* set number of direct probes u8 type */
+#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
+
struct iwl_scan_channel {
/*
* type is defined as:
@@ -2159,6 +2453,9 @@ struct iwl_scan_channel {
__le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
} __attribute__ ((packed));
+/* set number of direct probes __le32 type */
+#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+
/**
* struct iwl_ssid_ie - directed scan network information element
*
@@ -2172,6 +2469,7 @@ struct iwl_ssid_ie {
u8 ssid[32];
} __attribute__ ((packed));
+#define PROBE_OPTION_MAX_API1 0x4
#define PROBE_OPTION_MAX 0x14
#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
#define IWL_GOOD_CRC_TH cpu_to_le16(1)
@@ -2229,6 +2527,51 @@ struct iwl_ssid_ie {
* To avoid uCode errors, see timing restrictions described under
* struct iwl_scan_channel.
*/
+
+struct iwl3945_scan_cmd {
+ __le16 len;
+ u8 reserved0;
+ u8 channel_count; /* # channels in channel list */
+ __le16 quiet_time; /* dwell only this # millisecs on quiet channel
+ * (only for active scan) */
+ __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */
+ __le16 good_CRC_th; /* passive -> active promotion threshold */
+ __le16 reserved1;
+ __le32 max_out_time; /* max usec to be away from associated (service)
+ * channel */
+ __le32 suspend_time; /* pause scan this long (in "extended beacon
+ * format") when returning to service channel:
+ * 3945; 31:24 # beacons, 19:0 additional usec,
+ * 4965; 31:22 # beacons, 21:0 additional usec.
+ */
+ __le32 flags; /* RXON_FLG_* */
+ __le32 filter_flags; /* RXON_FILTER_* */
+
+ /* For active scans (set to all-0s for passive scans).
+ * Does not include payload. Must specify Tx rate; no rate scaling. */
+ struct iwl3945_tx_cmd tx_cmd;
+
+ /* For directed active scans (set to all-0s otherwise) */
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1];
+
+ /*
+ * Probe request frame, followed by channel list.
+ *
+ * Size of probe request frame is specified by byte count in tx_cmd.
+ * Channel list follows immediately after probe request frame.
+ * Number of channels in list is specified by channel_count.
+ * Each channel in list is of type:
+ *
+ * struct iwl3945_scan_channel channels[0];
+ *
+ * NOTE: Only one band of channels can be scanned per pass. You
+ * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
+ * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
+ * before requesting another scan.
+ */
+ u8 data[0];
+} __attribute__ ((packed));
+
struct iwl_scan_cmd {
__le16 len;
u8 reserved0;
@@ -2336,6 +2679,14 @@ struct iwl_scancomplete_notification {
/*
* BEACON_NOTIFICATION = 0x90 (notification only, not a command)
*/
+
+struct iwl3945_beacon_notif {
+ struct iwl3945_tx_resp beacon_notify_hdr;
+ __le32 low_tsf;
+ __le32 high_tsf;
+ __le32 ibss_mgr_status;
+} __attribute__ ((packed));
+
struct iwl4965_beacon_notif {
struct iwl4965_tx_resp beacon_notify_hdr;
__le32 low_tsf;
@@ -2346,6 +2697,15 @@ struct iwl4965_beacon_notif {
/*
* REPLY_TX_BEACON = 0x91 (command, has simple generic response)
*/
+
+struct iwl3945_tx_beacon_cmd {
+ struct iwl3945_tx_cmd tx;
+ __le16 tim_idx;
+ u8 tim_size;
+ u8 reserved1;
+ struct ieee80211_hdr frame[0]; /* beacon frame */
+} __attribute__ ((packed));
+
struct iwl_tx_beacon_cmd {
struct iwl_tx_cmd tx;
__le16 tim_idx;
@@ -2382,6 +2742,76 @@ struct rate_histogram {
/* statistics command response */
+struct iwl39_statistics_rx_phy {
+ __le32 ina_cnt;
+ __le32 fina_cnt;
+ __le32 plcp_err;
+ __le32 crc32_err;
+ __le32 overrun_err;
+ __le32 early_overrun_err;
+ __le32 crc32_good;
+ __le32 false_alarm_cnt;
+ __le32 fina_sync_err_cnt;
+ __le32 sfd_timeout;
+ __le32 fina_timeout;
+ __le32 unresponded_rts;
+ __le32 rxe_frame_limit_overrun;
+ __le32 sent_ack_cnt;
+ __le32 sent_cts_cnt;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_rx_non_phy {
+ __le32 bogus_cts; /* CTS received when not expecting CTS */
+ __le32 bogus_ack; /* ACK received when not expecting ACK */
+ __le32 non_bssid_frames; /* number of frames with BSSID that
+ * doesn't belong to the STA BSSID */
+ __le32 filtered_frames; /* count frames that were dumped in the
+ * filtering process */
+ __le32 non_channel_beacons; /* beacons with our bss id but not on
+ * our serving channel */
+} __attribute__ ((packed));
+
+struct iwl39_statistics_rx {
+ struct iwl39_statistics_rx_phy ofdm;
+ struct iwl39_statistics_rx_phy cck;
+ struct iwl39_statistics_rx_non_phy general;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_tx {
+ __le32 preamble_cnt;
+ __le32 rx_detected_cnt;
+ __le32 bt_prio_defer_cnt;
+ __le32 bt_prio_kill_cnt;
+ __le32 few_bytes_cnt;
+ __le32 cts_timeout;
+ __le32 ack_timeout;
+ __le32 expected_ack_cnt;
+ __le32 actual_ack_cnt;
+} __attribute__ ((packed));
+
+struct statistics_dbg {
+ __le32 burst_check;
+ __le32 burst_count;
+ __le32 reserved[4];
+} __attribute__ ((packed));
+
+struct iwl39_statistics_div {
+ __le32 tx_on_a;
+ __le32 tx_on_b;
+ __le32 exec_time;
+ __le32 probe_time;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_general {
+ __le32 temperature;
+ struct statistics_dbg dbg;
+ __le32 sleep_time;
+ __le32 slots_out;
+ __le32 slots_idle;
+ __le32 ttl_timestamp;
+ struct iwl39_statistics_div div;
+} __attribute__ ((packed));
+
struct statistics_rx_phy {
__le32 ina_cnt;
__le32 fina_cnt;
@@ -2418,7 +2848,7 @@ struct statistics_rx_ht_phy {
__le32 reserved2;
} __attribute__ ((packed));
-#define INTERFERENCE_DATA_AVAILABLE __constant_cpu_to_le32(1)
+#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1)
struct statistics_rx_non_phy {
__le32 bogus_cts; /* CTS received when not expecting CTS */
@@ -2493,11 +2923,6 @@ struct statistics_tx {
struct statistics_tx_non_phy_agg agg;
} __attribute__ ((packed));
-struct statistics_dbg {
- __le32 burst_check;
- __le32 burst_count;
- __le32 reserved[4];
-} __attribute__ ((packed));
struct statistics_div {
__le32 tx_on_a;
@@ -2561,6 +2986,14 @@ struct iwl_statistics_cmd {
*/
#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
#define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8)
+
+struct iwl3945_notif_statistics {
+ __le32 flag;
+ struct iwl39_statistics_rx rx;
+ struct iwl39_statistics_tx tx;
+ struct iwl39_statistics_general general;
+} __attribute__ ((packed));
+
struct iwl_notif_statistics {
__le32 flag;
struct statistics_rx rx;
@@ -3012,6 +3445,10 @@ struct iwl_rx_packet {
__le32 len;
struct iwl_cmd_header hdr;
union {
+ struct iwl3945_rx_frame rx_frame;
+ struct iwl3945_tx_resp tx_resp;
+ struct iwl3945_beacon_notif beacon_status;
+
struct iwl_alive_resp alive_frame;
struct iwl_spectrum_notification spectrum_notif;
struct iwl_csa_notification csa_notif;
@@ -3029,6 +3466,6 @@ struct iwl_rx_packet {
} u;
} __attribute__ ((packed));
-int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon);
+int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
#endif /* __iwl_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 73d7973707e..085e9cf1cac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/etherdevice.h>
#include <net/mac80211.h>
#include "iwl-eeprom.h"
@@ -170,7 +171,8 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_hw *hw =
ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
if (hw == NULL) {
- IWL_ERROR("Can not allocate network device\n");
+ printk(KERN_ERR "%s: Can not allocate network device\n",
+ cfg->name);
goto out;
}
@@ -210,7 +212,7 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
if (!rxq->bd) {
ret = iwl_rx_queue_alloc(priv);
if (ret) {
- IWL_ERROR("Unable to initialize Rx queue\n");
+ IWL_ERR(priv, "Unable to initialize Rx queue\n");
return -ENOMEM;
}
} else
@@ -238,6 +240,39 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_hw_nic_init);
+/*
+ * QoS support
+*/
+void iwl_activate_qos(struct iwl_priv *priv, u8 force)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ priv->qos_data.def_qos_parm.qos_flags = 0;
+
+ if (priv->qos_data.qos_cap.q_AP.queue_request &&
+ !priv->qos_data.qos_cap.q_AP.txop_request)
+ priv->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_TXOP_TYPE_MSK;
+ if (priv->qos_data.qos_active)
+ priv->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_UPDATE_EDCA_MSK;
+
+ if (priv->current_ht_config.is_ht)
+ priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+
+ if (force || iwl_is_associated(priv)) {
+ IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+ priv->qos_data.qos_active,
+ priv->qos_data.def_qos_parm.qos_flags);
+
+ iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
+ sizeof(struct iwl_qosparam_cmd),
+ &priv->qos_data.def_qos_parm, NULL);
+ }
+}
+EXPORT_SYMBOL(iwl_activate_qos);
+
void iwl_reset_qos(struct iwl_priv *priv)
{
u16 cw_min = 15;
@@ -321,7 +356,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
}
}
- IWL_DEBUG_QOS("set QoS to default \n");
+ IWL_DEBUG_QOS(priv, "set QoS to default \n");
spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -402,10 +437,11 @@ static void iwlcore_init_hw_rates(struct iwl_priv *priv,
}
}
+
/**
* iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
*/
-static int iwlcore_init_geos(struct iwl_priv *priv)
+int iwlcore_init_geos(struct iwl_priv *priv)
{
struct iwl_channel_info *ch;
struct ieee80211_supported_band *sband;
@@ -416,7 +452,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
- IWL_DEBUG_INFO("Geography modes already initialized.\n");
+ IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n");
set_bit(STATUS_GEO_CONFIGURED, &priv->status);
return 0;
}
@@ -457,8 +493,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
priv->ieee_channels = channels;
priv->ieee_rates = rates;
- iwlcore_init_hw_rates(priv, rates);
-
for (i = 0; i < priv->channel_count; i++) {
ch = &priv->channel_info[i];
@@ -500,7 +534,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
/* Save flags for reg domain usage */
geo_ch->orig_flags = geo_ch->flags;
- IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
+ IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
ch->channel, geo_ch->center_freq,
is_channel_a_band(ch) ? "5.2" : "2.4",
geo_ch->flags & IEEE80211_CHAN_DISABLED ?
@@ -510,33 +544,33 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
priv->cfg->sku & IWL_SKU_A) {
- printk(KERN_INFO DRV_NAME
- ": Incorrectly detected BG card as ABG. Please send "
- "your PCI ID 0x%04X:0x%04X to maintainer.\n",
- priv->pci_dev->device, priv->pci_dev->subsystem_device);
+ IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
+ "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n",
+ priv->pci_dev->device,
+ priv->pci_dev->subsystem_device);
priv->cfg->sku &= ~IWL_SKU_A;
}
- printk(KERN_INFO DRV_NAME
- ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- priv->bands[IEEE80211_BAND_2GHZ].n_channels,
- priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
+ IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
+ priv->bands[IEEE80211_BAND_2GHZ].n_channels,
+ priv->bands[IEEE80211_BAND_5GHZ].n_channels);
set_bit(STATUS_GEO_CONFIGURED, &priv->status);
return 0;
}
+EXPORT_SYMBOL(iwlcore_init_geos);
/*
* iwlcore_free_geos - undo allocations in iwlcore_init_geos
*/
-static void iwlcore_free_geos(struct iwl_priv *priv)
+void iwlcore_free_geos(struct iwl_priv *priv)
{
kfree(priv->ieee_channels);
kfree(priv->ieee_rates);
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}
+EXPORT_SYMBOL(iwlcore_free_geos);
static bool is_single_rx_stream(struct iwl_priv *priv)
{
@@ -587,6 +621,167 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
+{
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+ if (hw_decrypt)
+ rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
+ else
+ rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
+
+}
+EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
+
+/**
+ * iwl_check_rxon_cmd - validate RXON structure is valid
+ *
+ * NOTE: This is really only useful during development and can eventually
+ * be #ifdef'd out once the driver is stable and folks aren't actively
+ * making changes
+ */
+int iwl_check_rxon_cmd(struct iwl_priv *priv)
+{
+ int error = 0;
+ int counter = 1;
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+ if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
+ error |= le32_to_cpu(rxon->flags &
+ (RXON_FLG_TGJ_NARROW_BAND_MSK |
+ RXON_FLG_RADAR_DETECT_MSK));
+ if (error)
+ IWL_WARN(priv, "check 24G fields %d | %d\n",
+ counter++, error);
+ } else {
+ error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
+ 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
+ if (error)
+ IWL_WARN(priv, "check 52 fields %d | %d\n",
+ counter++, error);
+ error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
+ if (error)
+ IWL_WARN(priv, "check 52 CCK %d | %d\n",
+ counter++, error);
+ }
+ error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
+ if (error)
+ IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error);
+
+ /* make sure basic rates 6Mbps and 1Mbps are supported */
+ error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
+ ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
+ if (error)
+ IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error);
+
+ error |= (le16_to_cpu(rxon->assoc_id) > 2007);
+ if (error)
+ IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error);
+
+ error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
+ == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
+ if (error)
+ IWL_WARN(priv, "check CCK and short slot %d | %d\n",
+ counter++, error);
+
+ error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
+ == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
+ if (error)
+ IWL_WARN(priv, "check CCK & auto detect %d | %d\n",
+ counter++, error);
+
+ error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
+ RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
+ if (error)
+ IWL_WARN(priv, "check TGG and auto detect %d | %d\n",
+ counter++, error);
+
+ if (error)
+ IWL_WARN(priv, "Tuning to channel %d\n",
+ le16_to_cpu(rxon->channel));
+
+ if (error) {
+ IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n");
+ return -1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(iwl_check_rxon_cmd);
+
+/**
+ * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
+ * @priv: staging_rxon is compared to active_rxon
+ *
+ * If the RXON structure is changing enough to require a new tune,
+ * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
+ * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
+ */
+int iwl_full_rxon_required(struct iwl_priv *priv)
+{
+
+ /* These items are only settable from the full RXON command */
+ if (!(iwl_is_associated(priv)) ||
+ compare_ether_addr(priv->staging_rxon.bssid_addr,
+ priv->active_rxon.bssid_addr) ||
+ compare_ether_addr(priv->staging_rxon.node_addr,
+ priv->active_rxon.node_addr) ||
+ compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
+ priv->active_rxon.wlap_bssid_addr) ||
+ (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
+ (priv->staging_rxon.channel != priv->active_rxon.channel) ||
+ (priv->staging_rxon.air_propagation !=
+ priv->active_rxon.air_propagation) ||
+ (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
+ priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
+ (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
+ priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
+ (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
+ return 1;
+
+ /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
+ * be updated with the RXON_ASSOC command -- however only some
+ * flag transitions are allowed using RXON_ASSOC */
+
+ /* Check if we are not switching bands */
+ if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
+ (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
+ return 1;
+
+ /* Check if we are switching association toggle */
+ if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
+ (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_full_rxon_required);
+
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
+{
+ int i;
+ int rate_mask;
+
+ /* Set rate mask*/
+ if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
+ else
+ rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
+
+ /* Find lowest valid rate */
+ for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
+ i = iwl_rates[i].next_ieee) {
+ if (rate_mask & (1 << i))
+ return iwl_rates[i].plcp;
+ }
+
+ /* No valid rate was found. Assign the lowest one */
+ if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ return IWL_RATE_1M_PLCP;
+ else
+ return IWL_RATE_6M_PLCP;
+}
+EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
+
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
{
struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
@@ -628,7 +823,7 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
iwl_set_rxon_chain(priv);
- IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X "
+ IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
"rxon flags 0x%X operation mode :0x%X "
"extension channel offset 0x%x\n",
ht_info->mcs.rx_mask[0],
@@ -679,7 +874,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
break;
case WLAN_HT_CAP_SM_PS_INVALID:
default:
- IWL_ERROR("invalid mimo ps mode %d\n",
+ IWL_ERR(priv, "invalid mimo ps mode %d\n",
priv->current_ht_config.sm_ps);
WARN_ON(1);
idle_cnt = -1;
@@ -700,6 +895,18 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
}
/**
+ * iwl_is_monitor_mode - Determine if interface in monitor mode
+ *
+ * priv->iw_mode is set in add_interface, but add_interface is
+ * 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)
+{
+ return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
+}
+
+/**
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
*
* Selects how many and which Rx receivers/antennas/chains to use.
@@ -742,6 +949,19 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
+ /* copied from 'iwl_bg_request_scan()' */
+ /* Force use of chains B and C (0x6) for Rx for 4965
+ * Avoid A (0x1) because of its off-channel reception on A-band.
+ * MIMO is not used here, but value is required */
+ 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;
+ }
+
priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
@@ -749,7 +969,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
else
priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
- IWL_DEBUG_ASSOC("rx_chain=0x%X active=%d idle=%d\n",
+ IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
priv->staging_rxon.rx_chain,
active_rx_cnt, idle_rx_cnt);
@@ -774,7 +994,7 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
u16 channel = ieee80211_frequency_to_channel(ch->center_freq);
if (!iwl_get_channel_info(priv, band, channel)) {
- IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
+ IWL_DEBUG_INFO(priv, "Could not set channel to %d [%d]\n",
channel, band);
return -EINVAL;
}
@@ -791,12 +1011,283 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
priv->band = band;
- IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
+ IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
return 0;
}
EXPORT_SYMBOL(iwl_set_rxon_channel);
+void iwl_set_flags_for_band(struct iwl_priv *priv,
+ enum ieee80211_band band)
+{
+ if (band == IEEE80211_BAND_5GHZ) {
+ priv->staging_rxon.flags &=
+ ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
+ | RXON_FLG_CCK_MSK);
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ } else {
+ /* Copied from iwl_post_associate() */
+ if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ else
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+
+ priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
+ priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
+ priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
+ }
+}
+EXPORT_SYMBOL(iwl_set_flags_for_band);
+
+/*
+ * initialize rxon structure with default values from eeprom
+ */
+void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
+{
+ const struct iwl_channel_info *ch_info;
+
+ memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
+
+ switch (mode) {
+ case NL80211_IFTYPE_AP:
+ priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
+ break;
+
+ case NL80211_IFTYPE_STATION:
+ priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
+ priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+ break;
+
+ case NL80211_IFTYPE_ADHOC:
+ priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
+ priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
+ 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;
+ }
+
+#if 0
+ /* TODO: Figure out when short_preamble would be set and cache from
+ * that */
+ if (!hw_to_local(priv->hw)->short_preamble)
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+#endif
+
+ ch_info = iwl_get_channel_info(priv, priv->band,
+ le16_to_cpu(priv->active_rxon.channel));
+
+ if (!ch_info)
+ ch_info = &priv->channel_info[0];
+
+ /*
+ * in some case A channels are all non IBSS
+ * in this case force B/G channel
+ */
+ if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
+ !(is_channel_ibss(ch_info)))
+ ch_info = &priv->channel_info[0];
+
+ priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
+ priv->band = ch_info->band;
+
+ iwl_set_flags_for_band(priv, priv->band);
+
+ priv->staging_rxon.ofdm_basic_rates =
+ (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+ 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);
+ 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;
+}
+EXPORT_SYMBOL(iwl_connection_init_rx_config);
+
+void iwl_set_rate(struct iwl_priv *priv)
+{
+ const struct ieee80211_supported_band *hw = NULL;
+ struct ieee80211_rate *rate;
+ int i;
+
+ hw = iwl_get_hw_mode(priv, priv->band);
+ if (!hw) {
+ IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n");
+ return;
+ }
+
+ priv->active_rate = 0;
+ priv->active_rate_basic = 0;
+
+ for (i = 0; i < hw->n_bitrates; i++) {
+ rate = &(hw->bitrates[i]);
+ if (rate->hw_value < IWL_RATE_COUNT)
+ priv->active_rate |= (1 << rate->hw_value);
+ }
+
+ IWL_DEBUG_RATE(priv, "Set active_rate = %0x, active_rate_basic = %0x\n",
+ priv->active_rate, priv->active_rate_basic);
+
+ /*
+ * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
+ * otherwise set it to the default of all CCK rates and 6, 12, 24 for
+ * OFDM
+ */
+ if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
+ priv->staging_rxon.cck_basic_rates =
+ ((priv->active_rate_basic &
+ IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
+ else
+ priv->staging_rxon.cck_basic_rates =
+ (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
+
+ if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
+ priv->staging_rxon.ofdm_basic_rates =
+ ((priv->active_rate_basic &
+ (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
+ IWL_FIRST_OFDM_RATE) & 0xFF;
+ else
+ 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)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
+ struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
+ IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n",
+ le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
+ rxon->channel = csa->channel;
+ priv->staging_rxon.channel = csa->channel;
+}
+EXPORT_SYMBOL(iwl_rx_csa);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+{
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+ IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
+ iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
+ IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
+ IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
+ IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",
+ le32_to_cpu(rxon->filter_flags));
+ IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
+ IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
+ rxon->ofdm_basic_rates);
+ IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
+ IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr);
+ IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
+ IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
+}
+#endif
+
+/**
+ * iwl_irq_handle_error - called for HW or SW error interrupt from card
+ */
+void iwl_irq_handle_error(struct iwl_priv *priv)
+{
+ /* Set the FW error flag -- cleared on iwl_down */
+ set_bit(STATUS_FW_ERROR, &priv->status);
+
+ /* Cancel currently queued command. */
+ clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & IWL_DL_FW_ERRORS) {
+ iwl_dump_nic_error_log(priv);
+ iwl_dump_nic_event_log(priv);
+ iwl_print_rx_config_cmd(priv);
+ }
+#endif
+
+ wake_up_interruptible(&priv->wait_command_queue);
+
+ /* Keep the restart process from trying to send host
+ * commands by clearing the INIT status bit */
+ clear_bit(STATUS_READY, &priv->status);
+
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ 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);
+ }
+}
+EXPORT_SYMBOL(iwl_irq_handle_error);
+
+void iwl_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count, struct dev_addr_list *mc_list)
+{
+ struct iwl_priv *priv = hw->priv;
+ __le32 *filter_flags = &priv->staging_rxon.filter_flags;
+
+ IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
+ changed_flags, *total_flags);
+
+ if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
+ if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
+ *filter_flags |= RXON_FILTER_PROMISC_MSK;
+ else
+ *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
+ }
+ if (changed_flags & FIF_ALLMULTI) {
+ if (*total_flags & FIF_ALLMULTI)
+ *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
+ else
+ *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
+ }
+ if (changed_flags & FIF_CONTROL) {
+ if (*total_flags & FIF_CONTROL)
+ *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
+ else
+ *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
+ }
+ if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+ if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+ *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
+ else
+ *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
+ }
+
+ /* We avoid iwl_commit_rxon here to commit the new filter flags
+ * since mac80211 will call ieee80211_hw_config immediately.
+ * (mc_list is not supported at this time). Otherwise, we need to
+ * queue a background iwl_commit_rxon work.
+ */
+
+ *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
+ FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
+}
+EXPORT_SYMBOL(iwl_configure_filter);
+
int iwl_setup_mac(struct iwl_priv *priv)
{
int ret;
@@ -806,12 +1297,14 @@ int iwl_setup_mac(struct iwl_priv *priv)
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM |
- IEEE80211_HW_AMPDU_AGGREGATION;
+ IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_SUPPORTS_PS;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->fw_handles_regulatory = true;
+ hw->wiphy->custom_regulatory = true;
+ hw->wiphy->max_scan_ssids = 1;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
@@ -831,7 +1324,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
ret = ieee80211_register_hw(priv->hw);
if (ret) {
- IWL_ERROR("Failed to register hw (error %d)\n", ret);
+ IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
return ret;
}
priv->mac80211_registered = 1;
@@ -863,7 +1356,6 @@ int iwl_init_drv(struct iwl_priv *priv)
{
int ret;
- priv->retry_rate = 1;
priv->ibss_beacon = NULL;
spin_lock_init(&priv->lock);
@@ -897,21 +1389,22 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->qos_data.qos_cap.val = 0;
priv->rates_mask = IWL_RATES_MASK;
- /* If power management is turned on, default to AC mode */
- priv->power_mode = IWL_POWER_AC;
+ /* If power management is turned on, default to CAM mode */
+ priv->power_mode = IWL_POWER_MODE_CAM;
priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
ret = iwl_init_channel_map(priv);
if (ret) {
- IWL_ERROR("initializing regulatory failed: %d\n", ret);
+ IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
goto err;
}
ret = iwlcore_init_geos(priv);
if (ret) {
- IWL_ERROR("initializing geos failed: %d\n", ret);
+ IWL_ERR(priv, "initializing geos failed: %d\n", ret);
goto err_free_channel_map;
}
+ iwlcore_init_hw_rates(priv, priv->ieee_rates);
return 0;
@@ -926,14 +1419,16 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
int ret = 0;
if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) {
- IWL_WARNING("Requested user TXPOWER %d below limit.\n",
- priv->tx_power_user_lmt);
+ IWL_WARN(priv, "Requested user TXPOWER %d below lower limit %d.\n",
+ tx_power,
+ IWL_TX_POWER_TARGET_POWER_MIN);
return -EINVAL;
}
if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) {
- IWL_WARNING("Requested user TXPOWER %d above limit.\n",
- priv->tx_power_user_lmt);
+ IWL_WARN(priv, "Requested user TXPOWER %d above upper limit %d.\n",
+ tx_power,
+ IWL_TX_POWER_TARGET_POWER_MAX);
return -EINVAL;
}
@@ -970,18 +1465,92 @@ void iwl_disable_interrupts(struct iwl_priv *priv)
* from uCode or flow handler (Rx/Tx DMA) */
iwl_write32(priv, CSR_INT, 0xffffffff);
iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
- IWL_DEBUG_ISR("Disabled interrupts\n");
+ IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
}
EXPORT_SYMBOL(iwl_disable_interrupts);
void iwl_enable_interrupts(struct iwl_priv *priv)
{
- IWL_DEBUG_ISR("Enabling interrupts\n");
+ IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
set_bit(STATUS_INT_ENABLED, &priv->status);
iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
}
EXPORT_SYMBOL(iwl_enable_interrupts);
+irqreturn_t iwl_isr(int irq, void *data)
+{
+ struct iwl_priv *priv = data;
+ u32 inta, inta_mask;
+ u32 inta_fh;
+ 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);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+
+ /* Ignore interrupt if there's nothing in NIC to service.
+ * This may be due to IRQ shared with another device,
+ * or due to sporadic interrupts thrown from our NIC. */
+ if (!inta && !inta_fh) {
+ IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0, inta_fh == 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;
+ }
+
+ IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+ inta, inta_mask, inta_fh);
+
+ inta &= ~CSR_INT_BIT_SCD;
+
+ /* iwl_irq_tasklet() will service interrupts and re-enable them */
+ if (likely(inta || inta_fh))
+ tasklet_schedule(&priv->irq_tasklet);
+
+ 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 */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ iwl_enable_interrupts(priv);
+ spin_unlock(&priv->lock);
+ return IRQ_NONE;
+}
+EXPORT_SYMBOL(iwl_isr);
+
+int iwl_send_bt_config(struct iwl_priv *priv)
+{
+ struct iwl_bt_cmd bt_cmd = {
+ .flags = 3,
+ .lead_time = 0xAA,
+ .max_kill = 1,
+ .kill_ack_mask = 0,
+ .kill_cts_mask = 0,
+ };
+
+ return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+ sizeof(struct iwl_bt_cmd), &bt_cmd);
+}
+EXPORT_SYMBOL(iwl_send_bt_config);
+
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
{
u32 stat_flags = 0;
@@ -1007,7 +1576,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
u32 errcnt = 0;
u32 i;
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+ IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
ret = iwl_grab_nic_access(priv);
if (ret)
@@ -1018,7 +1587,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
- i + RTC_INST_LOWER_BOUND);
+ i + IWL49_RTC_INST_LOWER_BOUND);
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
ret = -EIO;
@@ -1045,13 +1614,14 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
int ret = 0;
u32 errcnt;
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+ 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, RTC_INST_LOWER_BOUND);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ IWL49_RTC_INST_LOWER_BOUND);
errcnt = 0;
for (; len > 0; len -= sizeof(u32), image++) {
@@ -1060,7 +1630,7 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
* if IWL_DL_IO is set */
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
save_len - len, val, le32_to_cpu(*image));
ret = -EIO;
@@ -1073,8 +1643,8 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
iwl_release_nic_access(priv);
if (!errcnt)
- IWL_DEBUG_INFO
- ("ucode image in INSTRUCTION memory is good\n");
+ IWL_DEBUG_INFO(priv,
+ "ucode image in INSTRUCTION memory is good\n");
return ret;
}
@@ -1094,7 +1664,7 @@ int iwl_verify_ucode(struct iwl_priv *priv)
len = priv->ucode_boot.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
- IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
return 0;
}
@@ -1103,7 +1673,7 @@ int iwl_verify_ucode(struct iwl_priv *priv)
len = priv->ucode_init.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
- IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
return 0;
}
@@ -1112,11 +1682,11 @@ int iwl_verify_ucode(struct iwl_priv *priv)
len = priv->ucode_code.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
- IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
return 0;
}
- IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
/* Since nothing seems to match, show first several data entries in
* instruction SRAM, so maybe visual inspection will give a clue.
@@ -1188,21 +1758,22 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
- IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
return;
}
ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ 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) {
- IWL_ERROR("Start IWL Error Log Dump:\n");
- IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+ IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+ IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+ priv->status, count);
}
desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
@@ -1215,12 +1786,12 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
- IWL_ERROR("Desc Time "
+ IWL_ERR(priv, "Desc Time "
"data1 data2 line\n");
- IWL_ERROR("%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
+ IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
desc_lookup(desc), desc, time, data1, data2, line);
- IWL_ERROR("blink1 blink2 ilink1 ilink2\n");
- IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
+ IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n");
+ IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
ilink1, ilink2);
iwl_release_nic_access(priv);
@@ -1266,11 +1837,11 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
ptr += sizeof(u32);
if (mode == 0) {
/* data, ev */
- IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev);
+ IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
} else {
data = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n",
+ IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
time, data, ev);
}
}
@@ -1292,13 +1863,13 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
@@ -1312,12 +1883,12 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
/* bail out if nothing in log */
if (size == 0) {
- IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
+ IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
iwl_release_nic_access(priv);
return;
}
- IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+ IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
size, num_wraps);
/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -1349,9 +1920,9 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
sizeof(cmd), &cmd);
if (ret)
- IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
+ IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
else
- IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "
+ IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD succeeded, "
"critical temperature is %d\n",
cmd.critical_temperature_R);
}
@@ -1368,7 +1939,7 @@ EXPORT_SYMBOL(iwl_rf_kill_ct_config);
* When in the 'halt' state, the card is shut down and must be fully
* restarted to come back on.
*/
-static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
{
struct iwl_host_cmd cmd = {
.id = REPLY_CARD_STATE_CMD,
@@ -1379,6 +1950,7 @@ static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
return iwl_send_cmd(priv, &cmd);
}
+EXPORT_SYMBOL(iwl_send_card_state);
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
{
@@ -1387,7 +1959,7 @@ void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
if (test_bit(STATUS_RF_KILL_SW, &priv->status))
return;
- IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO OFF\n");
+ IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n");
iwl_scan_cancel(priv);
/* FIXME: This is a workaround for AP */
@@ -1416,7 +1988,7 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
return 0;
- IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO ON\n");
+ IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n");
spin_lock_irqsave(&priv->lock, flags);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
@@ -1441,7 +2013,7 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
+ IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
"disabled by HW switch\n");
return 0;
}
@@ -1463,3 +2035,78 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
return 1;
}
EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);
+
+void iwl_bg_rf_kill(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
+
+ wake_up_interruptible(&priv->wait_command_queue);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ 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 (!test_bit(STATUS_RF_KILL_HW, &priv->status))
+ IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
+ "disabled by SW switch\n");
+ else
+ IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n"
+ "Kill switch must be turned off for "
+ "wireless networking to work.\n");
+ }
+ mutex_unlock(&priv->mutex);
+ iwl_rfkill_set_hw_state(priv);
+}
+EXPORT_SYMBOL(iwl_bg_rf_kill);
+
+void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+#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);
+
+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);
+
+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_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_rx_reply_error);
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7c3a20a986b..27310fec2e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ struct iwl_cmd;
#define IWLWIFI_VERSION "1.3.27k"
-#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -110,6 +110,14 @@ struct iwl_lib_ops {
void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
+ int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr,
+ u16 len, u8 reset, u8 pad);
+ void (*txq_free_tfd)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+ int (*txq_init)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
/* aggregations */
int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
int sta_id, int tid, u16 ssn_idx);
@@ -203,6 +211,9 @@ struct iwl_cfg {
u16 eeprom_calib_ver;
const struct iwl_ops *ops;
const struct iwl_mod_params *mod_params;
+ u8 valid_tx_ant;
+ u8 valid_rx_ant;
+ bool need_pll_cfg;
};
/***************************
@@ -213,11 +224,26 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_ops *hw_ops);
void iwl_hw_detect(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
+void iwl_activate_qos(struct iwl_priv *priv, u8 force);
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
+int iwl_check_rxon_cmd(struct iwl_priv *priv);
+int iwl_full_rxon_required(struct iwl_priv *priv);
void iwl_set_rxon_chain(struct iwl_priv *priv);
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *sta_ht_inf);
+void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band);
+void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode);
+int iwl_set_decrypted_flag(struct iwl_priv *priv,
+ struct ieee80211_hdr *hdr,
+ u32 decrypt_res,
+ struct ieee80211_rx_status *stats);
+void iwl_irq_handle_error(struct iwl_priv *priv);
+void iwl_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count, struct dev_addr_list *mc_list);
int iwl_hw_nic_init(struct iwl_priv *priv);
int iwl_setup_mac(struct iwl_priv *priv);
int iwl_set_hw_params(struct iwl_priv *priv);
@@ -225,6 +251,16 @@ int iwl_init_drv(struct iwl_priv *priv);
void iwl_uninit_drv(struct iwl_priv *priv);
/*****************************************************
+ * RX handlers.
+ * **************************************************/
+void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_reply_error(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+
+/*****************************************************
* RX
******************************************************/
void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
@@ -245,6 +281,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
/* TX helpers */
@@ -252,9 +289,18 @@ void iwl_rx_statistics(struct iwl_priv *priv,
* TX
******************************************************/
int iwl_txq_ctx_reset(struct iwl_priv *priv);
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len, u8 reset, u8 pad);
int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id);
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
@@ -267,7 +313,7 @@ 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_rf_kill(struct iwl_priv *priv);
+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);
@@ -279,6 +325,10 @@ void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
struct ieee80211_tx_info *info);
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)
@@ -306,8 +356,30 @@ void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
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);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes);
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band);
+void iwl_bg_scan_check(struct work_struct *data);
+void iwl_bg_abort_scan(struct work_struct *work);
+void iwl_bg_scan_completed(struct work_struct *work);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+int iwl_send_scan_abort(struct iwl_priv *priv);
+
+/* For faster active scanning, scan will move to the next channel if fewer than
+ * PLCP_QUIET_THRESH packets are heard on this channel within
+ * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
+ * time if it's a quiet channel (nothing responded to our probe, and there's
+ * no other traffic).
+ * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
+#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */
+#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */
+
/*******************************************************************************
* Calibrations - implemented in iwl-calib.c
@@ -319,7 +391,7 @@ void iwl_calib_free_results(struct iwl_priv *priv);
/*******************************************************************************
* Spectrum Measureemtns in iwl-spectrum.c
******************************************************************************/
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
#else
static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
@@ -342,11 +414,23 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
+ u8 meta_flag);
+
/*****************************************************
* PCI *
*****************************************************/
void iwl_disable_interrupts(struct iwl_priv *priv);
void iwl_enable_interrupts(struct iwl_priv *priv);
+irqreturn_t iwl_isr(int irq, void *data);
+static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
+{
+ int pos;
+ u16 pci_lnk_ctl;
+ pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP);
+ pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+ return pci_lnk_ctl;
+}
/*****************************************************
* Error Handling Debugging
@@ -354,6 +438,11 @@ void iwl_enable_interrupts(struct iwl_priv *priv);
void iwl_dump_nic_error_log(struct iwl_priv *priv);
void iwl_dump_nic_event_log(struct iwl_priv *priv);
+/*****************************************************
+* GEOS
+******************************************************/
+int iwlcore_init_geos(struct iwl_priv *priv);
+void iwlcore_free_geos(struct iwl_priv *priv);
/*************** DRIVER STATUS FUNCTIONS *****/
@@ -422,6 +511,7 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
}
extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
+extern int iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_verify_ucode(struct iwl_priv *priv);
extern int iwl_send_lq_cmd(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f34ede44ed1..2f1242447b3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -211,6 +211,9 @@
#define CSR_HW_REV_TYPE_5350 (0x0000030)
#define CSR_HW_REV_TYPE_5100 (0x0000050)
#define CSR_HW_REV_TYPE_5150 (0x0000040)
+#define CSR_HW_REV_TYPE_1000 (0x0000060)
+#define CSR_HW_REV_TYPE_6x00 (0x0000070)
+#define CSR_HW_REV_TYPE_6x50 (0x0000080)
#define CSR_HW_REV_TYPE_NONE (0x00000F0)
/* EEPROM REG */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 56c13b458de..65d1a7f2db9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -29,16 +29,29 @@
#ifndef __iwl_debug_h__
#define __iwl_debug_h__
+struct iwl_priv;
+
+#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a)
+#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a)
+#define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a)
+#define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a)
+
#ifdef CONFIG_IWLWIFI_DEBUG
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (priv->debug_level & (level)) \
- dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+#define IWL_DEBUG(__priv, level, fmt, args...) \
+do { \
+ if (__priv->debug_level & (level)) \
+ dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \
+ "%c %s " fmt, in_interrupt() ? 'I' : 'U', \
+ __func__ , ## args); \
+} while (0)
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((priv->debug_level & (level)) && net_ratelimit()) \
- dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) \
+do { \
+ if ((__priv->debug_level & (level)) && net_ratelimit()) \
+ dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \
+ "%c %s " fmt, in_interrupt() ? 'I' : 'U', \
+ __func__ , ## args); \
+} while (0)
#define iwl_print_hex_dump(priv, level, p, len) \
do { \
@@ -61,6 +74,7 @@ struct iwl_debugfs {
struct dentry *file_tx_statistics;
struct dentry *file_log_event;
struct dentry *file_channels;
+ struct dentry *file_status;
} dbgfs_data_files;
struct dir_rf_files {
struct dentry *file_disable_sensitivity;
@@ -76,8 +90,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
#endif
#else
-#define IWL_DEBUG(level, fmt, args...)
-#define IWL_DEBUG_LIMIT(level, fmt, args...)
+#define IWL_DEBUG(__priv, level, fmt, args...)
+#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
void *p, u32 len)
{}
@@ -117,84 +131,85 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
* when CONFIG_IWLWIFI_DEBUG=y.
*/
+/* 0x0000000F - 0x00000001 */
#define IWL_DL_INFO (1 << 0)
#define IWL_DL_MAC80211 (1 << 1)
#define IWL_DL_HCMD (1 << 2)
#define IWL_DL_STATE (1 << 3)
+/* 0x000000F0 - 0x00000010 */
#define IWL_DL_MACDUMP (1 << 4)
#define IWL_DL_HCMD_DUMP (1 << 5)
-#define IWL_DL_RADIO (1 << 7)
-#define IWL_DL_POWER (1 << 8)
-#define IWL_DL_TEMP (1 << 9)
-
-#define IWL_DL_NOTIF (1 << 10)
-#define IWL_DL_SCAN (1 << 11)
-#define IWL_DL_ASSOC (1 << 12)
-#define IWL_DL_DROP (1 << 13)
-
-#define IWL_DL_TXPOWER (1 << 14)
-
-#define IWL_DL_AP (1 << 15)
-
-#define IWL_DL_FW (1 << 16)
-#define IWL_DL_RF_KILL (1 << 17)
-#define IWL_DL_FW_ERRORS (1 << 18)
-
-#define IWL_DL_LED (1 << 19)
-
-#define IWL_DL_RATE (1 << 20)
-
-#define IWL_DL_CALIB (1 << 21)
-#define IWL_DL_WEP (1 << 22)
-#define IWL_DL_TX (1 << 23)
-#define IWL_DL_RX (1 << 24)
-#define IWL_DL_ISR (1 << 25)
-#define IWL_DL_HT (1 << 26)
-#define IWL_DL_IO (1 << 27)
-#define IWL_DL_11H (1 << 28)
-
-#define IWL_DL_STATS (1 << 29)
-#define IWL_DL_TX_REPLY (1 << 30)
-#define IWL_DL_QOS (1 << 31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a)
-
-#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_MACDUMP(f, a...) IWL_DEBUG(IWL_DL_MACDUMP, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HCMD, f, ## a)
-#define IWL_DEBUG_HC_DUMP(f, a...) IWL_DEBUG(IWL_DL_HCMD_DUMP, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a)
+#define IWL_DL_RADIO (1 << 7)
+/* 0x00000F00 - 0x00000100 */
+#define IWL_DL_POWER (1 << 8)
+#define IWL_DL_TEMP (1 << 9)
+#define IWL_DL_NOTIF (1 << 10)
+#define IWL_DL_SCAN (1 << 11)
+/* 0x0000F000 - 0x00001000 */
+#define IWL_DL_ASSOC (1 << 12)
+#define IWL_DL_DROP (1 << 13)
+#define IWL_DL_TXPOWER (1 << 14)
+#define IWL_DL_AP (1 << 15)
+/* 0x000F0000 - 0x00010000 */
+#define IWL_DL_FW (1 << 16)
+#define IWL_DL_RF_KILL (1 << 17)
+#define IWL_DL_FW_ERRORS (1 << 18)
+#define IWL_DL_LED (1 << 19)
+/* 0x00F00000 - 0x00100000 */
+#define IWL_DL_RATE (1 << 20)
+#define IWL_DL_CALIB (1 << 21)
+#define IWL_DL_WEP (1 << 22)
+#define IWL_DL_TX (1 << 23)
+/* 0x0F000000 - 0x01000000 */
+#define IWL_DL_RX (1 << 24)
+#define IWL_DL_ISR (1 << 25)
+#define IWL_DL_HT (1 << 26)
+#define IWL_DL_IO (1 << 27)
+/* 0xF0000000 - 0x10000000 */
+#define IWL_DL_11H (1 << 28)
+#define IWL_DL_STATS (1 << 29)
+#define IWL_DL_TX_REPLY (1 << 30)
+#define IWL_DL_QOS (1 << 31)
+
+#define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a)
+#define IWL_DEBUG_MACDUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_MACDUMP, f, ## a)
+#define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a)
+#define IWL_DEBUG_SCAN(p, f, a...) IWL_DEBUG(p, IWL_DL_SCAN, f, ## a)
+#define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a)
+#define IWL_DEBUG_TX(p, f, a...) IWL_DEBUG(p, IWL_DL_TX, f, ## a)
+#define IWL_DEBUG_ISR(p, f, a...) IWL_DEBUG(p, IWL_DL_ISR, f, ## a)
+#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a)
+#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
+#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
+#define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a)
+#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
+#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a)
+#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a)
+#define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_DROP_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a)
+#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a)
+#define IWL_DEBUG_IO(p, f, a...) IWL_DEBUG(p, IWL_DL_IO, f, ## a)
+#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_NOTIF(p, f, a...) IWL_DEBUG(p, IWL_DL_NOTIF, f, ## a)
+#define IWL_DEBUG_ASSOC(p, f, a...) \
+ IWL_DEBUG(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_ASSOC_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_HT(p, f, a...) IWL_DEBUG(p, IWL_DL_HT, f, ## a)
+#define IWL_DEBUG_STATS(p, f, a...) IWL_DEBUG(p, IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_STATS_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_QOS(p, f, a...) IWL_DEBUG(p, IWL_DL_QOS, f, ## a)
+#define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a)
+#define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a)
+#define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a)
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index d5253a179de..36cfeccfafb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -63,6 +63,14 @@
goto err; \
} while (0)
+#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
+ dbgfs->dbgfs_##parent##_files.file_##name = \
+ debugfs_create_x32(#name, 0444, dbgfs->dir_##parent, ptr); \
+ if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
+ || !dbgfs->dbgfs_##parent##_files.file_##name) \
+ goto err; \
+} while (0)
+
#define DEBUGFS_REMOVE(name) do { \
debugfs_remove(name); \
name = NULL; \
@@ -164,9 +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);
- printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n",
- priv->dbgfs->sram_offset, priv->dbgfs->sram_len);
-
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 + \
@@ -301,14 +306,14 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
buf_size = 4 * eeprom_len + 256;
if (eeprom_len % 16) {
- IWL_ERROR("EEPROM size is not multiple of 16.\n");
+ IWL_ERR(priv, "EEPROM size is not multiple of 16.\n");
return -ENODATA;
}
/* 4 characters for byte 0xYY */
buf = kzalloc(buf_size, GFP_KERNEL);
if (!buf) {
- IWL_ERROR("Can not allocate Buffer\n");
+ IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM;
}
@@ -365,7 +370,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) {
- IWL_ERROR("Can not allocate Buffer\n");
+ IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM;
}
@@ -420,7 +425,6 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
return ret;
}
-
DEBUGFS_READ_WRITE_FILE_OPS(sram);
DEBUGFS_WRITE_FILE_OPS(log_event);
DEBUGFS_READ_FILE_OPS(eeprom);
@@ -462,6 +466,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(rx_statistics, data);
DEBUGFS_ADD_FILE(tx_statistics, data);
DEBUGFS_ADD_FILE(channels, data);
+ DEBUGFS_ADD_X32(status, data, (u32 *)&priv->status);
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
@@ -469,7 +474,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
return 0;
err:
- IWL_ERROR("Can't open the debugfs directory\n");
+ IWL_ERR(priv, "Can't open the debugfs directory\n");
iwl_dbgfs_unregister(priv);
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0468fcc1ea9..0baae802282 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -36,13 +36,15 @@
#include <linux/kernel.h>
#include <net/ieee80211_radiotap.h>
-#define DRV_NAME "iwlagn"
-#include "iwl-rfkill.h"
#include "iwl-eeprom.h"
-#include "iwl-4965-hw.h"
#include "iwl-csr.h"
#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"
#include "iwl-led.h"
#include "iwl-power.h"
#include "iwl-agn-rs.h"
@@ -55,6 +57,28 @@ extern struct iwl_cfg iwl5350_agn_cfg;
extern struct iwl_cfg iwl5100_bg_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
+extern struct iwl_cfg iwl6000_2ag_cfg;
+extern struct iwl_cfg iwl6000_2agn_cfg;
+extern struct iwl_cfg iwl6000_3agn_cfg;
+extern struct iwl_cfg iwl6050_2agn_cfg;
+extern struct iwl_cfg iwl6050_3agn_cfg;
+extern struct iwl_cfg iwl1000_bgn_cfg;
+
+/* shared structures from iwl-5000.c */
+extern struct iwl_mod_params iwl50_mod_params;
+extern struct iwl_ops iwl5000_ops;
+extern struct iwl_lib_ops iwl5000_lib;
+extern struct iwl_hcmd_ops iwl5000_hcmd;
+extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
+
+/* shared functions from iwl-5000.c */
+extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len);
+extern u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd,
+ u8 *data);
+extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+ __le32 *tx_flags);
+extern int iwl5000_calc_rssi(struct iwl_priv *priv,
+ struct iwl_rx_phy_res *rx_resp);
/* CT-KILL constants */
#define CT_KILL_THRESHOLD 110 /* in Celsius */
@@ -132,9 +156,12 @@ struct iwl_tx_info {
* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
* descriptors) and required locking structures.
*/
+#define TFD_TX_CMD_SLOTS 256
+#define TFD_CMD_SLOTS 32
+
struct iwl_tx_queue {
struct iwl_queue q;
- struct iwl_tfd *tfds;
+ void *tfds;
struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
struct iwl_tx_info *txb;
u8 need_update;
@@ -154,6 +181,36 @@ struct iwl4965_channel_tgh_info {
s64 last_radar_time;
};
+#define IWL4965_MAX_RATE (33)
+
+struct iwl3945_clip_group {
+ /* maximum power level to prevent clipping for each rate, derived by
+ * us from this band's saturation power in EEPROM */
+ const s8 clip_powers[IWL_MAX_RATES];
+};
+
+/* current Tx power values to use, one for each rate for each channel.
+ * requested power is limited by:
+ * -- regulatory EEPROM limits for this channel
+ * -- hardware capabilities (clip-powers)
+ * -- spectrum management
+ * -- user preference (e.g. iwconfig)
+ * when requested power is set, base power index must also be set. */
+struct iwl3945_channel_power_info {
+ struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
+ s8 power_table_index; /* actual (compenst'd) index into gain table */
+ s8 base_power_index; /* gain index for power at factory temp. */
+ s8 requested_power; /* power (dBm) requested for this chnl/rate */
+};
+
+/* current scan Tx power values to use, one for each scan rate for each
+ * channel. */
+struct iwl3945_scan_power_info {
+ struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
+ s8 power_table_index; /* actual (compenst'd) index into gain table */
+ s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
+};
+
/*
* One for each channel, holds all channel setup data
* Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
@@ -184,8 +241,15 @@ struct iwl_channel_info {
s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */
u8 fat_flags; /* flags copied from EEPROM */
u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-};
+ /* Radio/DSP gain settings for each "normal" data Tx rate.
+ * These include, in addition to RF and DSP gain, a few fields for
+ * remembering/modifying gain settings (indexes). */
+ struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
+
+ /* Radio/DSP gain settings for each scan rate, for directed scans. */
+ struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
+};
#define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1
@@ -370,7 +434,7 @@ struct iwl_hw_key {
u8 key[32];
};
-union iwl4965_ht_rate_supp {
+union iwl_ht_rate_supp {
u16 rates;
struct {
u8 siso_rate;
@@ -430,6 +494,24 @@ 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];
+ u8 used;
+ u8 ps_status;
+ struct iwl3945_hw_key keyinfo;
+};
+
struct iwl_station_entry {
struct iwl_addsta_cmd sta;
struct iwl_tid_data tid[MAX_TID_COUNT];
@@ -497,11 +579,13 @@ struct iwl_sensitivity_ranges {
* @max_txq_num: Max # Tx queues supported
* @dma_chnl_num: Number of Tx DMA/FIFO channels
* @scd_bc_tbls_size: size of scheduler byte count tables
+ * @tfd_size: TFD size
* @tx/rx_chains_num: Number of TX/RX chains
* @valid_tx/rx_ant: usable antennas
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
* @max_rxq_log: Log-base-2 of max_rxq_size
* @rx_buf_size: Rx buffer size
+ * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
* @max_stations:
* @bcast_sta_id:
* @fat_channel: is 40MHz width possible in band 2.4
@@ -516,6 +600,7 @@ struct iwl_hw_params {
u8 max_txq_num;
u8 dma_chnl_num;
u16 scd_bc_tbls_size;
+ u32 tfd_size;
u8 tx_chains_num;
u8 rx_chains_num;
u8 valid_tx_ant;
@@ -523,6 +608,7 @@ struct iwl_hw_params {
u16 max_rxq_size;
u16 max_rxq_log;
u32 rx_buf_size;
+ u32 rx_wrt_ptr_reg;
u32 max_pkt_size;
u8 max_stations;
u8 bcast_sta_id;
@@ -755,7 +841,7 @@ struct iwl_priv {
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
/* spectrum measurement report caching */
struct iwl_spectrum_notification measure_report;
u8 measurement_status;
@@ -768,6 +854,10 @@ struct iwl_priv {
struct iwl_channel_info *channel_info; /* channel info array */
u8 channel_count; /* # of channels */
+ /* each calibration channel group in the EEPROM has a derived
+ * clip setting for each rate. 3945 only.*/
+ const struct iwl3945_clip_group clip39_groups[5];
+
/* thermal calibration */
s32 temperature; /* degrees Kelvin */
s32 last_temperature;
@@ -781,7 +871,7 @@ struct iwl_priv {
unsigned long scan_start;
unsigned long scan_pass_start;
unsigned long scan_start_tsf;
- struct iwl_scan_cmd *scan;
+ void *scan;
int scan_bands;
int one_direct_scan;
u8 direct_ssid_len;
@@ -832,18 +922,18 @@ struct iwl_priv {
* 4965's initialize alive response contains some calibration data. */
struct iwl_init_alive_resp card_alive_init;
struct iwl_alive_resp card_alive;
-#ifdef CONFIG_IWLWIFI_RFKILL
+#if defined(CONFIG_IWLWIFI_RFKILL)
struct rfkill *rfkill;
#endif
#ifdef CONFIG_IWLWIFI_LEDS
- struct iwl_led led[IWL_LED_TRG_MAX];
unsigned long last_blink_time;
u8 last_blink_rate;
u8 allow_blinking;
u64 led_tpt;
+ struct iwl_led led[IWL_LED_TRG_MAX];
+ unsigned int rxtxpackets;
#endif
-
u16 active_rate;
u16 active_rate_basic;
@@ -893,7 +983,6 @@ struct iwl_priv {
u16 rates_mask;
u32 power_mode;
- u32 antenna;
u8 bssid[ETH_ALEN];
u16 rts_threshold;
u8 mac_addr[ETH_ALEN];
@@ -929,6 +1018,10 @@ struct iwl_priv {
u16 beacon_int;
struct ieee80211_vif *vif;
+ /*Added for 3945 */
+ void *shared_virt;
+ dma_addr_t shared_phys;
+ /*End*/
struct iwl_hw_params hw_params;
@@ -960,6 +1053,11 @@ struct iwl_priv {
struct delayed_work init_alive_start;
struct delayed_work alive_start;
struct delayed_work scan_check;
+
+ /*For 3945 only*/
+ struct delayed_work thermal_periodic;
+ struct delayed_work rfkill_poll;
+
/* TX Power */
s8 tx_power_user_lmt;
s8 tx_power_channel_lmt;
@@ -982,6 +1080,15 @@ struct iwl_priv {
u32 disable_tx_power_cal;
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
+
+ /*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 */
static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index ce2f47306ce..75517d05df0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -145,7 +145,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
{
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+ IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
return -ENOENT;
}
return 0;
@@ -173,7 +173,7 @@ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
EEPROM_SEM_TIMEOUT);
if (ret >= 0) {
- IWL_DEBUG_IO("Acquired semaphore after %d tries.\n",
+ IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n",
count+1);
return ret;
}
@@ -223,7 +223,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
if (ret < 0) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+ IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
ret = -ENOENT;
goto err;
}
@@ -231,7 +231,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
if (ret < 0) {
- IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
+ IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT;
goto err;
}
@@ -247,7 +247,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
CSR_EEPROM_REG_READ_VALID_MSK,
IWL_EEPROM_ACCESS_TIMEOUT);
if (ret < 0) {
- IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
+ IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
goto done;
}
r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
@@ -285,7 +285,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
return 0;
err:
- IWL_ERROR("Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+ IWL_ERR(priv, "Unsupported 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;
@@ -390,7 +390,7 @@ static int iwl_set_fat_chan_info(struct iwl_priv *priv,
if (!is_channel_valid(ch_info))
return -1;
- IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
+ IWL_DEBUG_INFO(priv, "FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
" Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
@@ -432,11 +432,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
struct iwl_channel_info *ch_info;
if (priv->channel_count) {
- IWL_DEBUG_INFO("Channel map already initialized.\n");
+ IWL_DEBUG_INFO(priv, "Channel map already initialized.\n");
return 0;
}
- IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
+ IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n");
priv->channel_count =
ARRAY_SIZE(iwl_eeprom_band_1) +
@@ -445,12 +445,12 @@ int iwl_init_channel_map(struct iwl_priv *priv)
ARRAY_SIZE(iwl_eeprom_band_4) +
ARRAY_SIZE(iwl_eeprom_band_5);
- IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
+ IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count);
priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
priv->channel_count, GFP_KERNEL);
if (!priv->channel_info) {
- IWL_ERROR("Could not allocate channel_info\n");
+ IWL_ERR(priv, "Could not allocate channel_info\n");
priv->channel_count = 0;
return -ENOMEM;
}
@@ -485,7 +485,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
IEEE80211_CHAN_NO_FAT_BELOW);
if (!(is_channel_valid(ch_info))) {
- IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
+ IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
"No traffic\n",
ch_info->channel,
ch_info->flags,
@@ -501,7 +501,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
ch_info->min_power = 0;
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
+ IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
" Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
@@ -520,7 +520,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
flags & EEPROM_CHANNEL_RADAR))
? "" : "not ");
- /* Set the user_txpower_limit to the highest power
+ /* Set the tx_power_user_lmt to the highest power
* supported by any channel */
if (eeprom_ch_info[ch].max_power_avg >
priv->tx_power_user_lmt)
@@ -531,6 +531,13 @@ int iwl_init_channel_map(struct iwl_priv *priv)
}
}
+ /* Check if we do have FAT channels */
+ if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
+ EEPROM_REGULATORY_BAND_NO_FAT &&
+ priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
+ EEPROM_REGULATORY_BAND_NO_FAT)
+ return 0;
+
/* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
for (band = 6; band <= 7; band++) {
enum ieee80211_band ieeeband;
@@ -582,6 +589,7 @@ void iwl_free_channel_map(struct iwl_priv *priv)
kfree(priv->channel_info);
priv->channel_count = 0;
}
+EXPORT_SYMBOL(iwl_free_channel_map);
/**
* iwl_get_channel_info - Find driver's private channel info
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 603c84bed63..3479153d96c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -118,6 +118,9 @@ struct iwl_eeprom_channel {
s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
} __attribute__ ((packed));
+/* 3945 Specific */
+#define EEPROM_3945_EEPROM_VERSION (0x2f)
+
/* 4965 has two radio transmitters (and 3 radio receivers) */
#define EEPROM_TX_POWER_TX_CHAINS (2)
@@ -367,6 +370,8 @@ struct iwl_eeprom_calib_info {
*/
#define EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */
+#define EEPROM_REGULATORY_BAND_NO_FAT (0)
+
struct iwl_eeprom_ops {
const u32 regulatory_bands[7];
int (*verify_signature) (struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index d7da1986455..65fa8a69fd5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -399,6 +399,21 @@
*/
#define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002)
+#define RX_QUEUE_SIZE 256
+#define RX_QUEUE_MASK 255
+#define RX_QUEUE_SIZE_LOG 8
+
+/*
+ * RX related structures and functions
+ */
+#define RX_FREE_BUFFERS 64
+#define RX_LOW_WATERMARK 8
+
+/* Size of one Rx buffer in host DRAM */
+#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */
+#define IWL_RX_BUF_SIZE_4K (4 * 1024)
+#define IWL_RX_BUF_SIZE_8K (8 * 1024)
+
/**
* struct iwl_rb_status - reseve buffer status
* host memory mapped FH registers
@@ -414,6 +429,7 @@ struct iwl_rb_status {
__le16 closed_fr_num;
__le16 finished_rb_num;
__le16 finished_fr_nam;
+ __le32 __unused; /* 3945 only */
} __attribute__ ((packed));
@@ -477,7 +493,6 @@ struct iwl_tfd {
__le32 __pad;
} __attribute__ ((packed));
-
/* Keep Warm Size */
#define IWL_KW_SIZE 0x1000 /* 4k */
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 8c71ad4f88c..17d61ac8ed6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -109,14 +109,14 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = NULL;
if (!skb) {
- IWL_ERROR("Error: Response NULL in %s.\n",
+ IWL_ERR(priv, "Error: Response NULL in %s.\n",
get_cmd_string(cmd->hdr.cmd));
return 1;
}
pkt = (struct iwl_rx_packet *)skb->data;
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from %s (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
return 1;
}
@@ -125,11 +125,11 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv,
switch (cmd->hdr.cmd) {
case REPLY_TX_LINK_QUALITY_CMD:
case SENSITIVITY_CMD:
- IWL_DEBUG_HC_DUMP("back from %s (0x%08X)\n",
+ IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n",
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
break;
default:
- IWL_DEBUG_HC("back from %s (0x%08X)\n",
+ IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n",
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
}
#endif
@@ -156,7 +156,7 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
ret = iwl_enqueue_hcmd(priv, cmd);
if (ret < 0) {
- IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+ IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
return ret;
}
@@ -174,8 +174,9 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
BUG_ON(cmd->meta.u.callback != NULL);
if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: Already sending a host command\n",
- get_cmd_string(cmd->id));
+ IWL_ERR(priv,
+ "Error sending %s: Already sending a host command\n",
+ get_cmd_string(cmd->id));
ret = -EBUSY;
goto out;
}
@@ -188,7 +189,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
cmd_idx = iwl_enqueue_hcmd(priv, cmd);
if (cmd_idx < 0) {
ret = cmd_idx;
- IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+ IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
goto out;
}
@@ -198,9 +199,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
HOST_COMPLETE_TIMEOUT);
if (!ret) {
if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: time out after %dms.\n",
- get_cmd_string(cmd->id),
- jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
+ IWL_ERR(priv,
+ "Error sending %s: time out after %dms.\n",
+ get_cmd_string(cmd->id),
+ jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
ret = -ETIMEDOUT;
@@ -209,22 +211,22 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
}
if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n",
+ IWL_DEBUG_INFO(priv, "Command %s aborted: RF KILL Switch\n",
get_cmd_string(cmd->id));
ret = -ECANCELED;
goto fail;
}
if (test_bit(STATUS_FW_ERROR, &priv->status)) {
- IWL_DEBUG_INFO("Command %s failed: FW Error\n",
+ IWL_DEBUG_INFO(priv, "Command %s failed: FW Error\n",
get_cmd_string(cmd->id));
ret = -EIO;
goto fail;
}
if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
- IWL_ERROR("Error: Response NULL in '%s'\n",
+ IWL_ERR(priv, "Error: Response NULL in '%s'\n",
get_cmd_string(cmd->id));
ret = -EIO;
- goto out;
+ goto cancel;
}
ret = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index ca4f638ab9d..fb64d297dd4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 0a92e7431ad..083ea1ffbe8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -66,7 +66,7 @@
static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
u32 ofs, u32 val)
{
- IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
+ IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
_iwl_write32(priv, ofs, val);
}
#define iwl_write32(priv, ofs, val) \
@@ -79,7 +79,7 @@ static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
#ifdef CONFIG_IWLWIFI_DEBUG
static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
{
- IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
+ IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
return _iwl_read32(priv, ofs);
}
#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs)
@@ -108,7 +108,7 @@ static inline int __iwl_poll_bit(const char *f, u32 l,
u32 bits, u32 mask, int timeout)
{
int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout);
- IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
+ IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
addr, bits, mask,
unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
return ret;
@@ -128,7 +128,7 @@ static inline void __iwl_set_bit(const char *f, u32 l,
struct iwl_priv *priv, u32 reg, u32 mask)
{
u32 val = _iwl_read32(priv, reg) | mask;
- IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+ IWL_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)
@@ -145,7 +145,7 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
struct iwl_priv *priv, u32 reg, u32 mask)
{
u32 val = _iwl_read32(priv, reg) & ~mask;
- IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+ IWL_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)
@@ -156,6 +156,7 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
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;
@@ -165,9 +166,10 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
- CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
+ CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (ret < 0) {
- IWL_ERROR("MAC is in deep sleep!\n");
+ val = _iwl_read32(priv, CSR_GP_CNTRL);
+ IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
return -EIO;
}
@@ -182,9 +184,9 @@ static inline int __iwl_grab_nic_access(const char *f, u32 l,
struct iwl_priv *priv)
{
if (atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Grabbing access while already held %s %d.\n", f, l);
+ IWL_ERR(priv, "Grabbing access while already held %s %d.\n", f, l);
- IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
+ IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
return _iwl_grab_nic_access(priv);
}
#define iwl_grab_nic_access(priv) \
@@ -207,9 +209,9 @@ static inline void __iwl_release_nic_access(const char *f, u32 l,
struct iwl_priv *priv)
{
if (atomic_read(&priv->restrict_refcnt) <= 0)
- IWL_ERROR("Release unheld nic access at line %s %d.\n", f, l);
+ IWL_ERR(priv, "Release unheld nic access at line %s %d.\n", f, l);
- IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
+ IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
_iwl_release_nic_access(priv);
}
#define iwl_release_nic_access(priv) \
@@ -229,8 +231,8 @@ static inline u32 __iwl_read_direct32(const char *f, u32 l,
{
u32 value = _iwl_read_direct32(priv, reg);
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s %d\n", f, l);
- IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
+ 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;
}
@@ -250,7 +252,7 @@ static void __iwl_write_direct32(const char *f , u32 line,
struct iwl_priv *priv, u32 reg, u32 value)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_write_direct32(priv, reg, value);
}
#define iwl_write_direct32(priv, reg, value) \
@@ -284,10 +286,10 @@ static inline int __iwl_poll_direct_bit(const char *f, u32 l,
int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout);
if (unlikely(ret == -ETIMEDOUT))
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
+ IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
"timedout - %s %d\n", addr, mask, f, l);
else
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
+ IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
"- %s %d\n", addr, mask, ret, f, l);
return ret;
}
@@ -308,7 +310,7 @@ static inline u32 __iwl_read_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 reg)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
return _iwl_read_prph(priv, reg);
}
@@ -331,7 +333,7 @@ static inline void __iwl_write_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 addr, u32 val)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_write_prph(priv, addr, val);
}
@@ -349,7 +351,7 @@ static inline void __iwl_set_bits_prph(const char *f, u32 line,
u32 reg, u32 mask)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_set_bits_prph(priv, reg, mask);
}
@@ -367,7 +369,7 @@ static inline void __iwl_set_bits_mask_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_set_bits_mask_prph(priv, reg, bits, mask);
}
#define iwl_set_bits_mask_prph(priv, reg, bits, mask) \
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 11eccd7d268..19680f72087 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -123,7 +123,7 @@ static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id,
/* Set led register off */
static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id)
{
- IWL_DEBUG_LED("led on %d\n", led_id);
+ IWL_DEBUG_LED(priv, "led on %d\n", led_id);
iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
return 0;
}
@@ -150,7 +150,7 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
.off = 0,
.interval = IWL_DEF_LED_INTRVL
};
- IWL_DEBUG_LED("led off %d\n", led_id);
+ IWL_DEBUG_LED(priv, "led off %d\n", led_id);
return iwl_send_led_cmd(priv, &led_cmd);
}
#endif
@@ -159,7 +159,7 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
/* Set led register off */
static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
{
- IWL_DEBUG_LED("LED Reg off\n");
+ IWL_DEBUG_LED(priv, "LED Reg off\n");
iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
return 0;
}
@@ -169,7 +169,7 @@ static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
*/
static int iwl_led_associate(struct iwl_priv *priv, int led_id)
{
- IWL_DEBUG_LED("Associated\n");
+ IWL_DEBUG_LED(priv, "Associated\n");
priv->allow_blinking = 1;
return iwl4965_led_on_reg(priv, led_id);
}
@@ -213,7 +213,7 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
return;
- IWL_DEBUG_LED("Led type = %s brightness = %d\n",
+ IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
led_type_str[led->type], brightness);
switch (brightness) {
case LED_FULL:
@@ -254,7 +254,7 @@ static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
ret = led_classdev_register(device, &led->led_dev);
if (ret) {
- IWL_ERROR("Error: failed to register led handler.\n");
+ IWL_ERR(priv, "Error: failed to register led handler.\n");
return ret;
}
@@ -280,7 +280,7 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
if (tpt < 0) /* wraparound */
tpt = -tpt;
- IWL_DEBUG_LED("tpt %lld current_tpt %llu\n",
+ IWL_DEBUG_LED(priv, "tpt %lld current_tpt %llu\n",
(long long)tpt,
(unsigned long long)current_tpt);
priv->led_tpt = current_tpt;
@@ -292,7 +292,7 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE))
break;
- IWL_DEBUG_LED("LED BLINK IDX=%d\n", i);
+ IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i);
return i;
}
@@ -352,7 +352,7 @@ int iwl_leds_register(struct iwl_priv *priv)
trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_RADIO].name,
- sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
+ sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
wiphy_name(priv->hw->wiphy));
priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg;
@@ -366,7 +366,7 @@ int iwl_leds_register(struct iwl_priv *priv)
trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
- sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
+ sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
@@ -382,7 +382,7 @@ int iwl_leds_register(struct iwl_priv *priv)
trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_RX].name,
- sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
+ sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
@@ -397,7 +397,7 @@ int iwl_leds_register(struct iwl_priv *priv)
trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_TX].name,
- sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
+ sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 021e00bcd1b..ef9b174c37f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -35,7 +35,7 @@ struct iwl_priv;
#define IWL_LED_SOLID 11
#define IWL_LED_NAME_LEN 31
-#define IWL_DEF_LED_INTRVL __constant_cpu_to_le32(1000)
+#define IWL_DEF_LED_INTRVL cpu_to_le32(1000)
#define IWL_LED_ACTIVITY (0<<1)
#define IWL_LED_LINK (1<<1)
@@ -47,7 +47,9 @@ enum led_type {
IWL_LED_TRG_RADIO,
IWL_LED_TRG_MAX,
};
+#endif
+#ifdef CONFIG_IWLWIFI_LEDS
struct iwl_led {
struct iwl_priv *priv;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 75ca6a54217..18b7e4195ea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -60,14 +60,6 @@
#define IWL_POWER_RANGE_1_MAX (10)
-#define NOSLP __constant_cpu_to_le16(0), 0, 0
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
-#define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
- __constant_cpu_to_le32(X1), \
- __constant_cpu_to_le32(X2), \
- __constant_cpu_to_le32(X3), \
- __constant_cpu_to_le32(X4)}
#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5
#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM
@@ -110,6 +102,7 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
};
+
/* set card power command */
static int iwl_set_power(struct iwl_priv *priv, void *cmd)
{
@@ -134,13 +127,6 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
else
mode = IWL_POWER_ON_AC_DISASSOC;
break;
- /* FIXME: remove battery and ac from here */
- case IWL_POWER_BATTERY:
- mode = IWL_POWER_INDEX_3;
- break;
- case IWL_POWER_AC:
- mode = IWL_POWER_MODE_CAM;
- break;
default:
mode = priv->power_data.user_power_setting;
break;
@@ -149,17 +135,17 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
}
/* initialize to default */
-static int iwl_power_init_handle(struct iwl_priv *priv)
+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;
struct iwl_powertable_cmd *cmd;
int i;
- u16 pci_pm;
+ u16 lctl;
- IWL_DEBUG_POWER("Initialize power \n");
+ IWL_DEBUG_POWER(priv, "Initialize power \n");
- pow_data = &(priv->power_data);
+ pow_data = &priv->power_data;
memset(pow_data, 0, sizeof(*pow_data));
@@ -167,38 +153,37 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);
- pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &pci_pm);
+ lctl = iwl_pcie_link_ctl(priv);
- IWL_DEBUG_POWER("adjust power command flags\n");
+ IWL_DEBUG_POWER(priv, "adjust power command flags\n");
for (i = 0; i < IWL_POWER_MAX; i++) {
cmd = &pow_data->pwr_range_0[i].cmd;
- if (pci_pm & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
+ if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
else
cmd->flags |= IWL_POWER_PCI_PM_MSK;
}
- return 0;
}
/* adjust power command according to DTIM period and power level*/
-static int iwl_update_power_command(struct iwl_priv *priv,
- struct iwl_powertable_cmd *cmd,
- u16 mode)
+static int iwl_update_power_cmd(struct iwl_priv *priv,
+ struct iwl_powertable_cmd *cmd, u16 mode)
{
- int ret = 0, i;
- u8 skip;
- u32 max_sleep = 0;
struct iwl_power_vec_entry *range;
- u8 period = 0;
struct iwl_power_mgr *pow_data;
+ int i;
+ u32 max_sleep = 0;
+ u8 period;
+ bool skip;
if (mode > IWL_POWER_INDEX_5) {
- IWL_DEBUG_POWER("Error invalid power mode \n");
- return -1;
+ IWL_DEBUG_POWER(priv, "Error invalid power mode \n");
+ return -EINVAL;
}
- pow_data = &(priv->power_data);
+
+ pow_data = &priv->power_data;
if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX)
range = &pow_data->pwr_range_0[0];
@@ -212,14 +197,12 @@ static int iwl_update_power_command(struct iwl_priv *priv,
if (period == 0) {
period = 1;
- skip = 0;
- } else
- skip = range[mode].no_dtim;
-
- if (skip == 0) {
- max_sleep = period;
- cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ skip = false;
} else {
+ skip = !!range[mode].no_dtim;
+ }
+
+ if (skip) {
__le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
max_sleep = le32_to_cpu(slp_itrvl);
if (max_sleep == 0xFF)
@@ -227,24 +210,26 @@ static int iwl_update_power_command(struct iwl_priv *priv,
else if (max_sleep > period)
max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ } else {
+ max_sleep = period;
+ cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
}
- for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
+ for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
- }
- IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
- IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
- IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
- IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
+ IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags);
+ IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
+ IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
+ IWL_DEBUG_POWER(priv, "Sleep interval vector = { %d , %d , %d , %d , %d }\n",
le32_to_cpu(cmd->sleep_interval[0]),
le32_to_cpu(cmd->sleep_interval[1]),
le32_to_cpu(cmd->sleep_interval[2]),
le32_to_cpu(cmd->sleep_interval[3]),
le32_to_cpu(cmd->sleep_interval[4]));
- return ret;
+ return 0;
}
@@ -295,7 +280,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
if (final_mode != IWL_POWER_MODE_CAM)
set_bit(STATUS_POWER_PMI, &priv->status);
- iwl_update_power_command(priv, &cmd, final_mode);
+ iwl_update_power_cmd(priv, &cmd, final_mode);
cmd.keep_alive_beacons = 0;
if (final_mode == IWL_POWER_INDEX_5)
@@ -311,7 +296,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
if (priv->cfg->ops->lib->update_chain_flags && update_chains)
priv->cfg->ops->lib->update_chain_flags(priv);
else
- IWL_DEBUG_POWER("Cannot update the power, chain noise "
+ IWL_DEBUG_POWER(priv, "Cannot update the power, chain noise "
"calibration running: %d\n",
priv->chain_noise_data.state);
if (!ret)
@@ -366,7 +351,7 @@ 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_LIMIT)
+ if (mode > IWL_POWER_MAX)
return -EINVAL;
priv->power_data.user_power_setting = mode;
@@ -380,11 +365,10 @@ EXPORT_SYMBOL(iwl_power_set_user_mode);
*/
int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
{
- if (mode > IWL_POWER_LIMIT)
+ if (mode < IWL_POWER_SYS_MAX)
+ priv->power_data.system_power_setting = mode;
+ else
return -EINVAL;
-
- priv->power_data.system_power_setting = mode;
-
return iwl_power_update_mode(priv, 0);
}
EXPORT_SYMBOL(iwl_power_set_system_mode);
@@ -392,13 +376,11 @@ 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.power_disabled = 0;
priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
- priv->power_data.is_battery_active = 0;
priv->power_data.power_disabled = 0;
+ priv->power_data.is_battery_active = 0;
priv->power_data.critical_power_setting = 0;
}
EXPORT_SYMBOL(iwl_power_initialize);
@@ -407,8 +389,8 @@ EXPORT_SYMBOL(iwl_power_initialize);
int iwl_power_temperature_change(struct iwl_priv *priv)
{
int ret = 0;
- u16 new_critical = priv->power_data.critical_power_setting;
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;
@@ -434,7 +416,7 @@ 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(IWL_DL_STATE, "update power\n");
+ IWL_DEBUG_POWER(priv, "update power\n");
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index fa098d8975c..18963392121 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -42,22 +42,26 @@ enum {
IWL_POWER_INDEX_5,
IWL_POWER_AUTO,
IWL_POWER_MAX = IWL_POWER_AUTO,
- IWL_POWER_AC,
- IWL_POWER_BATTERY,
};
enum {
IWL_POWER_SYS_AUTO,
IWL_POWER_SYS_AC,
IWL_POWER_SYS_BATTERY,
+ IWL_POWER_SYS_MAX,
};
-#define IWL_POWER_LIMIT 0x08
-#define IWL_POWER_MASK 0x0F
-#define IWL_POWER_ENABLED 0x10
/* 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;
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index b7a5f23351c..3b9cac3fd21 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index 4b69da30665..2ad9faf1508 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -47,7 +47,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return 0;
- IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
+ IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state);
mutex_lock(&priv->mutex);
switch (state) {
@@ -62,7 +62,8 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
iwl_radio_kill_sw_disable_radio(priv);
break;
default:
- IWL_WARNING("we received unexpected RFKILL state %d\n", state);
+ IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
+ state);
break;
}
out_unlock:
@@ -78,10 +79,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)
BUG_ON(device == NULL);
- IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
+ IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n");
priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!priv->rfkill) {
- IWL_ERROR("Unable to allocate RFKILL device.\n");
+ IWL_ERR(priv, "Unable to allocate RFKILL device.\n");
ret = -ENOMEM;
goto error;
}
@@ -97,11 +98,11 @@ int iwl_rfkill_init(struct iwl_priv *priv)
ret = rfkill_register(priv->rfkill);
if (ret) {
- IWL_ERROR("Unable to register RFKILL: %d\n", ret);
+ IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret);
goto free_rfkill;
}
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
+ IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
return ret;
free_rfkill:
@@ -110,7 +111,7 @@ free_rfkill:
priv->rfkill = NULL;
error:
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
+ IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
return ret;
}
EXPORT_SYMBOL(iwl_rfkill_init);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
index 86dc055a2e9..633dafb4bf1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * 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.
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index c5f1aa0feac..8f65908f66f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -125,9 +125,10 @@ EXPORT_SYMBOL(iwl_rx_queue_space);
*/
int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
{
- u32 reg = 0;
- int ret = 0;
unsigned long flags;
+ u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg;
+ u32 reg;
+ int ret = 0;
spin_lock_irqsave(&q->lock, flags);
@@ -149,15 +150,14 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
goto exit_unlock;
/* Device expects a multiple of 8 */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
- q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
iwl_release_nic_access(priv);
/* Else device is assumed to be awake */
- } else
+ } else {
/* Device expects a multiple of 8 */
- iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
-
+ iwl_write32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
+ }
q->need_update = 0;
@@ -262,8 +262,7 @@ void iwl_rx_allocate(struct iwl_priv *priv)
rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
GFP_KERNEL);
if (!rxb->skb) {
- printk(KERN_CRIT DRV_NAME
- "Can not allocate SKB buffers\n");
+ IWL_CRIT(priv, "Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
* call the restock method and if it still needs
* more buffers it will schedule replenish */
@@ -495,7 +494,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
missed_beacon = &pkt->u.missed_beacon;
if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
- IWL_DEBUG_CALIB("missed bcn cnsq %d totl %d rcd %d expctd %d\n",
+ IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
le32_to_cpu(missed_beacon->consequtive_missed_beacons),
le32_to_cpu(missed_beacon->total_missed_becons),
le32_to_cpu(missed_beacon->num_recvd_beacons),
@@ -542,7 +541,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
else
priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
- IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
+ IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
bcn_silence_a, bcn_silence_b, bcn_silence_c,
priv->last_rx_noise);
}
@@ -555,7 +554,7 @@ void iwl_rx_statistics(struct iwl_priv *priv,
int change;
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
+ IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
(int)sizeof(priv->statistics), pkt->len);
change = ((priv->statistics.general.temperature !=
@@ -742,13 +741,13 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
* MAC addresses show just the last byte (for brevity),
* but you can hack it to show more, if you'd like to. */
if (dataframe)
- IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
+ IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
"len=%u, rssi=%d, chnl=%d, rate=%u, \n",
title, le16_to_cpu(fc), header->addr1[5],
length, rssi, channel, bitrate);
else {
/* src/dst addresses assume managed mode */
- IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, src=0x%02x, "
+ IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
"len=%u, rssi=%d, tim=%lu usec, "
"phy=0x%02x, chnl=%d\n",
title, le16_to_cpu(fc), header->addr1[5],
@@ -773,10 +772,10 @@ static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
/*
* returns non-zero if packet should be dropped
*/
-static int iwl_set_decrypted_flag(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
- u32 decrypt_res,
- struct ieee80211_rx_status *stats)
+int iwl_set_decrypted_flag(struct iwl_priv *priv,
+ struct ieee80211_hdr *hdr,
+ u32 decrypt_res,
+ struct ieee80211_rx_status *stats)
{
u16 fc = le16_to_cpu(hdr->frame_control);
@@ -786,7 +785,7 @@ static int iwl_set_decrypted_flag(struct iwl_priv *priv,
if (!(fc & IEEE80211_FCTL_PROTECTED))
return 0;
- IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
+ IWL_DEBUG_RX(priv, "decrypt_res:0x%x\n", decrypt_res);
switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
case RX_RES_STATUS_SEC_TYPE_TKIP:
/* The uCode has got a bad phase 1 Key, pushes the packet.
@@ -800,13 +799,13 @@ static int iwl_set_decrypted_flag(struct iwl_priv *priv,
RX_RES_STATUS_BAD_ICV_MIC) {
/* bad ICV, the packet is destroyed since the
* decryption is inplace, drop it */
- IWL_DEBUG_RX("Packet destroyed\n");
+ IWL_DEBUG_RX(priv, "Packet destroyed\n");
return -1;
}
case RX_RES_STATUS_SEC_TYPE_CCMP:
if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
RX_RES_STATUS_DECRYPT_OK) {
- IWL_DEBUG_RX("hw decrypt successfully!!!\n");
+ IWL_DEBUG_RX(priv, "hw decrypt successfully!!!\n");
stats->flag |= RX_FLAG_DECRYPTED;
}
break;
@@ -816,6 +815,7 @@ static int iwl_set_decrypted_flag(struct iwl_priv *priv,
}
return 0;
}
+EXPORT_SYMBOL(iwl_set_decrypted_flag);
static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
{
@@ -870,7 +870,7 @@ static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
break;
};
- IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n",
+ IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
decrypt_in, decrypt_out);
return decrypt_out;
@@ -895,7 +895,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
if (!rx_start) {
- IWL_ERROR("MPDU frame without a PHY data\n");
+ IWL_ERR(priv, "MPDU frame without a PHY data\n");
return;
}
if (include_phy) {
@@ -934,8 +934,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
/* We only process data packets if the interface is open */
if (unlikely(!priv->is_open)) {
- IWL_DEBUG_DROP_LIMIT
- ("Dropping packet while interface is not open.\n");
+ IWL_DEBUG_DROP_LIMIT(priv,
+ "Dropping packet while interface is not open.\n");
return;
}
@@ -1007,7 +1007,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
/*rx_status.flag |= RX_FLAG_TSFT;*/
if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
- IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
+ IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
rx_start->cfg_phy_cnt);
return;
}
@@ -1021,7 +1021,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
}
if (!rx_start) {
- IWL_ERROR("MPDU frame without a PHY data\n");
+ IWL_ERR(priv, "MPDU frame without a PHY data\n");
return;
}
@@ -1045,7 +1045,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
!(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
- IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n",
+ IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
le32_to_cpu(*rx_end));
return;
}
@@ -1078,7 +1078,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
if (unlikely(priv->debug_level & IWL_DL_RX))
iwl_dbg_report_frame(priv, rx_start, len, header, 1);
#endif
- IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
+ IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n",
rx_status.signal, rx_status.noise, rx_status.signal,
(unsigned long long)rx_status.mactime);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 3c803f6922e..23644cf884f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -46,15 +46,6 @@
#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
-
/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
* Must be set longer than active dwell time.
* For the most reliable scan, set > AP beacon interval (typically 100msec). */
@@ -63,7 +54,6 @@
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5
-#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
/**
@@ -80,12 +70,12 @@ int iwl_scan_cancel(struct iwl_priv *priv)
if (test_bit(STATUS_SCANNING, &priv->status)) {
if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Queuing scan abort.\n");
+ IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
set_bit(STATUS_SCAN_ABORTING, &priv->status);
queue_work(priv->workqueue, &priv->abort_scan);
} else
- IWL_DEBUG_SCAN("Scan abort already in progress.\n");
+ IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n");
return test_bit(STATUS_SCANNING, &priv->status);
}
@@ -119,7 +109,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
}
EXPORT_SYMBOL(iwl_scan_cancel_timeout);
-static int iwl_send_scan_abort(struct iwl_priv *priv)
+int iwl_send_scan_abort(struct iwl_priv *priv)
{
int ret = 0;
struct iwl_rx_packet *res;
@@ -150,7 +140,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
* can occur if we send the scan abort before we
* the microcode has notified us that a scan is
* completed. */
- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
+ IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", res->u.status);
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
clear_bit(STATUS_SCAN_HW, &priv->status);
}
@@ -160,7 +150,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
return ret;
}
-
+EXPORT_SYMBOL(iwl_send_scan_abort);
/* Service response to REPLY_SCAN_CMD (0x80) */
static void iwl_rx_reply_scan(struct iwl_priv *priv,
@@ -171,7 +161,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
struct iwl_scanreq_notification *notif =
(struct iwl_scanreq_notification *)pkt->u.raw;
- IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
+ IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
#endif
}
@@ -183,7 +173,7 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
struct iwl_scanstart_notification *notif =
(struct iwl_scanstart_notification *)pkt->u.raw;
priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
- IWL_DEBUG_SCAN("Scan start: "
+ IWL_DEBUG_SCAN(priv, "Scan start: "
"%d [802.11%s] "
"(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
notif->channel,
@@ -202,7 +192,7 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
struct iwl_scanresults_notification *notif =
(struct iwl_scanresults_notification *)pkt->u.raw;
- IWL_DEBUG_SCAN("Scan ch.res: "
+ IWL_DEBUG_SCAN(priv, "Scan ch.res: "
"%d [802.11%s] "
"(TSF: 0x%08X:%08X) - %d "
"elapsed=%lu usec (%dms since last)\n",
@@ -228,7 +218,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
- IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
+ IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
scan_notif->scanned_channels,
scan_notif->tsf_low,
scan_notif->tsf_high, scan_notif->status);
@@ -240,7 +230,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
/* The scan completion notification came in, so kill that timer... */
cancel_delayed_work(&priv->scan_check);
- IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
+ IWL_DEBUG_INFO(priv, "Scan pass on %sGHz took %dms\n",
(priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
"2.4" : "5.2",
jiffies_to_msecs(elapsed_jiffies
@@ -258,7 +248,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
* then we reset the scan state machine and terminate,
* re-queuing another scan if one has been requested */
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_INFO("Aborted scan completed.\n");
+ IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
} else {
/* If there are more bands on this scan pass reschedule */
@@ -268,11 +258,11 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
priv->last_scan_jiffies = jiffies;
priv->next_scan_jiffies = 0;
- IWL_DEBUG_INFO("Setting scan to off\n");
+ IWL_DEBUG_INFO(priv, "Setting scan to off\n");
clear_bit(STATUS_SCANNING, &priv->status);
- IWL_DEBUG_INFO("Scan took %dms\n",
+ IWL_DEBUG_INFO(priv, "Scan took %dms\n",
jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
queue_work(priv->workqueue, &priv->scan_completed);
@@ -296,9 +286,9 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_setup_rx_scan_handlers);
-static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band,
- u8 n_probes)
+inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes)
{
if (band == IEEE80211_BAND_5GHZ)
return IWL_ACTIVE_DWELL_TIME_52 +
@@ -307,9 +297,10 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
return IWL_ACTIVE_DWELL_TIME_24 +
IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
}
+EXPORT_SYMBOL(iwl_get_active_dwell_time);
-static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band)
{
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
@@ -327,6 +318,7 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
return passive;
}
+EXPORT_SYMBOL(iwl_get_passive_dwell_time);
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
@@ -363,7 +355,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
ch_info = iwl_get_channel_info(priv, band, channel);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
+ IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
channel);
continue;
}
@@ -392,7 +384,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
else
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
- IWL_DEBUG_SCAN("Scanning ch=%d prob=0x%X [%s %d]\n",
+ IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
channel, le32_to_cpu(scan_ch->type),
(scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
"ACTIVE" : "PASSIVE",
@@ -403,7 +395,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
added++;
}
- IWL_DEBUG_SCAN("total channels to scan %d \n", added);
+ IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added);
return added;
}
@@ -419,21 +411,21 @@ void iwl_init_scan_params(struct iwl_priv *priv)
int iwl_scan_initiate(struct iwl_priv *priv)
{
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
+ IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
return -EIO;
}
if (test_bit(STATUS_SCANNING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan already in progress.\n");
+ IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
return -EAGAIN;
}
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan request while abort pending\n");
+ IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
return -EAGAIN;
}
- IWL_DEBUG_INFO("Starting scan...\n");
+ IWL_DEBUG_INFO(priv, "Starting scan...\n");
if (priv->cfg->sku & IWL_SKU_G)
priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
if (priv->cfg->sku & IWL_SKU_A)
@@ -448,9 +440,77 @@ int iwl_scan_initiate(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_scan_initiate);
+#define IWL_DELAY_NEXT_SCAN (HZ*2)
+
+int iwl_mac_hw_scan(struct ieee80211_hw *hw,
+ struct cfg80211_scan_request *req)
+{
+ 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");
+
+ mutex_lock(&priv->mutex);
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (!iwl_is_ready_rf(priv)) {
+ ret = -EIO;
+ IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");
+ goto out_unlock;
+ }
+
+ /* We don't schedule scan within next_scan_jiffies period.
+ * Avoid scanning during possible EAPOL exchange, return
+ * success immediately.
+ */
+ if (priv->next_scan_jiffies &&
+ time_after(priv->next_scan_jiffies, jiffies)) {
+ IWL_DEBUG_SCAN(priv, "scan rejected: within next scan period\n");
+ queue_work(priv->workqueue, &priv->scan_completed);
+ ret = 0;
+ goto out_unlock;
+ }
+
+ /* if we just finished scan ask for delay */
+ if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
+ time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
+ IWL_DEBUG_SCAN(priv, "scan rejected: within previous scan period\n");
+ queue_work(priv->workqueue, &priv->scan_completed);
+ ret = 0;
+ 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;
+ }
+
+ ret = iwl_scan_initiate(priv);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+
+out_unlock:
+ spin_unlock_irqrestore(&priv->lock, flags);
+ mutex_unlock(&priv->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_mac_hw_scan);
+
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-static void iwl_bg_scan_check(struct work_struct *data)
+void iwl_bg_scan_check(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, scan_check.work);
@@ -461,7 +521,7 @@ static void iwl_bg_scan_check(struct work_struct *data)
mutex_lock(&priv->mutex);
if (test_bit(STATUS_SCANNING, &priv->status) ||
test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting "
+ IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting "
"adapter (%dms)\n",
jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
@@ -470,6 +530,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
}
mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_scan_check);
+
/**
* iwl_supported_rate_to_ie - fill in the supported rate in IE field
*
@@ -527,10 +589,10 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
* iwl_fill_probe_req - fill in all required fields and IE for probe request
*/
-static 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,
+ enum ieee80211_band band,
+ struct ieee80211_mgmt *frame,
+ int left)
{
int len = 0;
u8 *pos = NULL;
@@ -624,6 +686,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
return (u16)len;
}
+EXPORT_SYMBOL(iwl_fill_probe_req);
static void iwl_bg_request_scan(struct work_struct *data)
{
@@ -650,7 +713,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
mutex_lock(&priv->mutex);
if (!iwl_is_ready(priv)) {
- IWL_WARNING("request scan called when driver not ready.\n");
+ IWL_WARN(priv, "request scan called when driver not ready.\n");
goto done;
}
@@ -662,34 +725,34 @@ static void iwl_bg_request_scan(struct work_struct *data)
/* This should never be called or scheduled if there is currently
* a scan active in the hardware. */
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
+ IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
"Ignoring second request.\n");
ret = -EIO;
goto done;
}
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
+ IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
goto done;
}
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");
+ IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
goto done;
}
if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+ IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
goto done;
}
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");
+ IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
goto done;
}
if (!priv->scan_bands) {
- IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
+ IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
goto done;
}
@@ -714,7 +777,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
u32 scan_suspend_time = 100;
unsigned long flags;
- IWL_DEBUG_INFO("Scanning while associated...\n");
+ IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
spin_lock_irqsave(&priv->lock, flags);
interval = priv->beacon_int;
@@ -729,13 +792,13 @@ static void iwl_bg_request_scan(struct work_struct *data)
scan_suspend_time = (extra |
((suspend_time % interval) * 1024));
scan->suspend_time = cpu_to_le32(scan_suspend_time);
- IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
+ IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
scan_suspend_time, interval);
}
/* We should add the ability for user to lock to PASSIVE ONLY */
if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN("Start direct scan for '%s'\n",
+ 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;
@@ -744,7 +807,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
priv->direct_ssid, priv->direct_ssid_len);
n_probes++;
} else {
- IWL_DEBUG_SCAN("Start indirect scan.\n");
+ IWL_DEBUG_SCAN(priv, "Start indirect scan.\n");
}
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
@@ -773,7 +836,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
rx_chain = 0x6;
} else {
- IWL_WARNING("Invalid scan band count\n");
+ IWL_WARN(priv, "Invalid scan band count\n");
goto done;
}
@@ -806,7 +869,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
- IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+ IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
goto done;
}
@@ -839,7 +902,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl_bg_abort_scan(struct work_struct *work)
+void iwl_bg_abort_scan(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
@@ -853,18 +916,19 @@ static void iwl_bg_abort_scan(struct work_struct *work)
mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_abort_scan);
-static void iwl_bg_scan_completed(struct work_struct *work)
+void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
- IWL_DEBUG_SCAN("SCAN complete scan\n");
+ IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- ieee80211_scan_completed(priv->hw);
+ ieee80211_scan_completed(priv->hw, false);
/* Since setting the TXPOWER may have been deferred while
* performing the scan, fire one off */
@@ -872,7 +936,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
mutex_unlock(&priv->mutex);
}
-
+EXPORT_SYMBOL(iwl_bg_scan_completed);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
index 836c3c80b69..022bcf11573 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -146,7 +146,7 @@ static int iwl_get_measurement(struct iwl_priv *priv,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
rc = -EIO;
}
@@ -154,9 +154,9 @@ static int iwl_get_measurement(struct iwl_priv *priv,
switch (spectrum_resp_status) {
case 0: /* Command will be handled */
if (res->u.spectrum.id != 0xff) {
- IWL_DEBUG_INFO
- ("Replaced existing measurement: %d\n",
- res->u.spectrum.id);
+ IWL_DEBUG_INFO(priv,
+ "Replaced existing measurement: %d\n",
+ res->u.spectrum.id);
priv->measurement_status &= ~MEASUREMENT_READY;
}
priv->measurement_status |= MEASUREMENT_ACTIVE;
@@ -181,7 +181,7 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
if (!report->state) {
- IWL_DEBUG(IWL_DL_11H,
+ IWL_DEBUG_11H(priv,
"Spectrum Measure Notification: Start\n");
return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index b7d7943e476..a77c1e61906 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ieee80211 subsystem header files.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 412f66bac1a..1684490d93c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -60,7 +60,7 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
goto out;
}
- IWL_DEBUG_ASSOC_LIMIT("can not find STA %pM total %d\n",
+ IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
addr, priv->num_stations);
out:
@@ -86,11 +86,13 @@ 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))
- IWL_ERROR("ACTIVATE a non DRIVER active station %d\n", sta_id);
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
+ !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
+ IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
+ sta_id);
priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
- IWL_DEBUG_ASSOC("Added STA to Ucode: %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n",
priv->stations[sta_id].sta.sta.addr);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -105,13 +107,13 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
u8 sta_id = addsta->sta.sta_id;
if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
+ IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n");
return 1;
}
res = (struct iwl_rx_packet *)skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
res->hdr.flags);
return 1;
}
@@ -121,7 +123,7 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
iwl_sta_ucode_activate(priv, sta_id);
/* fall through */
default:
- IWL_DEBUG_HC("Received REPLY_ADD_STA:(0x%08X)\n",
+ IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
res->u.add_sta.status);
break;
}
@@ -130,7 +132,7 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
return 1;
}
-static int iwl_send_add_sta(struct iwl_priv *priv,
+int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags)
{
struct iwl_rx_packet *res = NULL;
@@ -155,7 +157,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
res->hdr.flags);
ret = -EIO;
}
@@ -164,11 +166,11 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
switch (res->u.add_sta.status) {
case ADD_STA_SUCCESS_MSK:
iwl_sta_ucode_activate(priv, sta->sta.sta_id);
- IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
+ IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
break;
default:
ret = -EIO;
- IWL_WARNING("REPLY_ADD_STA failed\n");
+ IWL_WARN(priv, "REPLY_ADD_STA failed\n");
break;
}
}
@@ -178,6 +180,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
return ret;
}
+EXPORT_SYMBOL(iwl_send_add_sta);
static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
struct ieee80211_sta_ht_cap *sta_ht_inf)
@@ -204,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
case WLAN_HT_CAP_SM_PS_DISABLED:
break;
default:
- IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
+ IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
break;
}
@@ -269,7 +272,7 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
station = &priv->stations[sta_id];
station->used = IWL_STA_DRIVER_ACTIVE;
- IWL_DEBUG_ASSOC("Add STA to driver ID %d: %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
sta_id, addr);
priv->num_stations++;
@@ -301,13 +304,13 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
BUG_ON(sta_id == IWL_INVALID_STATION);
- IWL_DEBUG_ASSOC("Removed STA from Ucode: %pM\n", addr);
+ IWL_DEBUG_ASSOC(priv, "Removed STA from Ucode: %pM\n", addr);
spin_lock_irqsave(&priv->sta_lock, flags);
/* Ucode must be active and driver must be non active */
if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
- IWL_ERROR("removed non active STA %d\n", sta_id);
+ IWL_ERR(priv, "removed non active STA %d\n", sta_id);
priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
@@ -324,13 +327,13 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
const char *addr = rm_sta->addr;
if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_REMOVE_STA.\n");
+ IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n");
return 1;
}
res = (struct iwl_rx_packet *)skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
res->hdr.flags);
return 1;
}
@@ -340,7 +343,7 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
iwl_sta_ucode_deactivate(priv, addr);
break;
default:
- IWL_ERROR("REPLY_REMOVE_STA failed\n");
+ IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
break;
}
@@ -378,7 +381,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
res->hdr.flags);
ret = -EIO;
}
@@ -387,11 +390,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
switch (res->u.rem_sta.status) {
case REM_STA_SUCCESS_MSK:
iwl_sta_ucode_deactivate(priv, addr);
- IWL_DEBUG_ASSOC("REPLY_REMOVE_STA PASSED\n");
+ IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
break;
default:
ret = -EIO;
- IWL_ERROR("REPLY_REMOVE_STA failed\n");
+ IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
break;
}
}
@@ -429,17 +432,17 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
if (unlikely(sta_id == IWL_INVALID_STATION))
goto out;
- IWL_DEBUG_ASSOC("Removing STA from driver:%d %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
sta_id, addr);
if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
- IWL_ERROR("Removing %pM but non DRIVER active\n",
+ IWL_ERR(priv, "Removing %pM but non DRIVER active\n",
addr);
goto out;
}
if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
- IWL_ERROR("Removing %pM but non UCODE active\n",
+ IWL_ERR(priv, "Removing %pM but non UCODE active\n",
addr);
goto out;
}
@@ -469,22 +472,32 @@ EXPORT_SYMBOL(iwl_remove_station);
void iwl_clear_stations_table(struct iwl_priv *priv)
{
unsigned long flags;
+ int i;
spin_lock_irqsave(&priv->sta_lock, flags);
if (iwl_is_alive(priv) &&
!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL))
- IWL_ERROR("Couldn't clear the station table\n");
+ IWL_ERR(priv, "Couldn't clear the station table\n");
priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations));
+ /* clean ucode key table bit map */
+ priv->ucode_key_table = 0;
+
+ /* 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);
+ }
+
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
EXPORT_SYMBOL(iwl_clear_stations_table);
-static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
+int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;
@@ -494,6 +507,7 @@ static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
return WEP_INVALID_OFFSET;
}
+EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
{
@@ -548,13 +562,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
spin_lock_irqsave(&priv->sta_lock, flags);
if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))
- IWL_ERROR("index %d not used in uCode key table.\n",
+ IWL_ERR(priv, "index %d not used in uCode key table.\n",
keyconf->keyidx);
priv->default_wep_key--;
memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
ret = iwl_send_static_wepkey_cmd(priv, 1);
- IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n",
+ IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -570,7 +584,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
if (keyconf->keylen != WEP_KEY_LEN_128 &&
keyconf->keylen != WEP_KEY_LEN_64) {
- IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen);
+ IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
return -EINVAL;
}
@@ -582,7 +596,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
priv->default_wep_key++;
if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table))
- IWL_ERROR("index %d already used in uCode key table.\n",
+ IWL_ERR(priv, "index %d already used in uCode key table.\n",
keyconf->keyidx);
priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
@@ -590,7 +604,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
keyconf->keylen);
ret = iwl_send_static_wepkey_cmd(priv, 0);
- IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",
+ IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
keyconf->keylen, keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -638,7 +652,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
@@ -686,7 +700,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
@@ -722,7 +736,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
/* This copy is acutally not needed: we get the key with each TX */
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
@@ -746,7 +760,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+ IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
return;
}
@@ -798,7 +812,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
- IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n",
+ IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
keyconf->keyidx, sta_id);
if (keyconf->keyidx != keyidx) {
@@ -812,7 +826,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
}
if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
- IWL_WARNING("Removing wrong key %d 0x%x\n",
+ IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
keyconf->keyidx, key_flags);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return 0;
@@ -820,7 +834,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
&priv->ucode_key_table))
- IWL_ERROR("index %d not used in uCode key table.\n",
+ IWL_ERR(priv, "index %d not used in uCode key table.\n",
priv->stations[sta_id].sta.key.key_offset);
memset(&priv->stations[sta_id].keyinfo, 0,
sizeof(struct iwl_hw_key));
@@ -857,11 +871,12 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id);
break;
default:
- IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ IWL_ERR(priv,
+ "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
ret = -EINVAL;
}
- IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+ IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
keyconf->alg, keyconf->keylen, keyconf->keyidx,
sta_id, ret);
@@ -874,13 +889,13 @@ static void iwl_dump_lq_cmd(struct iwl_priv *priv,
struct iwl_link_quality_cmd *lq)
{
int i;
- IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id);
- IWL_DEBUG_RATE("lq ant 0x%X 0x%X\n",
+ IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id);
+ IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n",
lq->general_params.single_stream_ant_msk,
lq->general_params.dual_stream_ant_msk);
for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
- IWL_DEBUG_RATE("lq index %d 0x%X\n",
+ IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n",
i, lq->rs_table[i].rate_n_flags);
}
#else
@@ -1057,7 +1072,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
if (sta_id != IWL_INVALID_STATION)
return sta_id;
- IWL_DEBUG_DROP("Station %pM not in station map. "
+ 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));
@@ -1069,7 +1084,8 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
return priv->hw_params.bcast_sta_id;
default:
- IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
+ IWL_WARN(priv, "Unknown mode of operation: %d\n",
+ priv->iw_mode);
return priv->hw_params.bcast_sta_id;
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 9bb7cefc1f3..59a586b6b56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -54,8 +54,11 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
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);
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,
struct ieee80211_sta_ht_cap *ht_info);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index b0ee86c6268..dff60fb7021 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -76,116 +76,6 @@ static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
memset(ptr, 0, sizeof(*ptr));
}
-static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
- dma_addr_t addr = get_unaligned_le32(&tb->lo);
- if (sizeof(dma_addr_t) > sizeof(u32))
- addr |=
- ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
-
- return addr;
-}
-
-static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
- return le16_to_cpu(tb->hi_n_len) >> 4;
-}
-
-static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
- dma_addr_t addr, u16 len)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
- u16 hi_n_len = len << 4;
-
- put_unaligned_le32(addr, &tb->lo);
- if (sizeof(dma_addr_t) > sizeof(u32))
- hi_n_len |= ((addr >> 16) >> 16) & 0xF;
-
- tb->hi_n_len = cpu_to_le16(hi_n_len);
-
- tfd->num_tbs = idx + 1;
-}
-
-static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
-{
- return tfd->num_tbs & 0x1f;
-}
-
-/**
- * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
- * @priv - driver private data
- * @txq - tx queue
- *
- * Does NOT advance any TFD circular buffer read/write indexes
- * Does NOT free the TFD itself (which is within circular buffer)
- */
-static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
-{
- struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)&txq->tfds[0];
- struct iwl_tfd *tfd;
- struct pci_dev *dev = priv->pci_dev;
- int index = txq->q.read_ptr;
- int i;
- int num_tbs;
-
- tfd = &tfd_tmp[index];
-
- /* Sanity check on number of chunks */
- num_tbs = iwl_tfd_get_num_tbs(tfd);
-
- if (num_tbs >= IWL_NUM_OF_TBS) {
- IWL_ERROR("Too many chunks: %i\n", num_tbs);
- /* @todo issue fatal error, it is quite serious situation */
- return;
- }
-
- /* Unmap tx_cmd */
- if (num_tbs)
- pci_unmap_single(dev,
- pci_unmap_addr(&txq->cmd[index]->meta, mapping),
- pci_unmap_len(&txq->cmd[index]->meta, len),
- PCI_DMA_TODEVICE);
-
- /* Unmap chunks, if any. */
- for (i = 1; i < num_tbs; i++) {
- pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
- iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
-
- if (txq->txb) {
- dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
- txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
- }
- }
-}
-
-static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
- struct iwl_tfd *tfd,
- dma_addr_t addr, u16 len)
-{
-
- u32 num_tbs = iwl_tfd_get_num_tbs(tfd);
-
- /* Each TFD can point to a maximum 20 Tx buffers */
- if (num_tbs >= IWL_NUM_OF_TBS) {
- IWL_ERROR("Error can not send more than %d chunks\n",
- IWL_NUM_OF_TBS);
- return -EINVAL;
- }
-
- BUG_ON(addr & ~DMA_BIT_MASK(36));
- if (unlikely(addr & ~IWL_TX_DMA_MASK))
- IWL_ERROR("Unaligned address = %llx\n",
- (unsigned long long)addr);
-
- iwl_tfd_set_tb(tfd, num_tbs, addr, len);
-
- return 0;
-}
-
/**
* iwl_txq_update_write_ptr - Send new write index to hardware
*/
@@ -206,7 +96,7 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
+ IWL_DEBUG_INFO(priv, "Requesting wakeup, GP1 = 0x%x\n", reg);
iwl_set_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
return ret;
@@ -241,7 +131,7 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
* Free all buffers.
* 0-fill, but do not free "txq" descriptor structure.
*/
-static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwl_queue *q = &txq->q;
@@ -254,7 +144,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* first, empty all BD's */
for (; q->write_ptr != q->read_ptr;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- iwl_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
len = sizeof(struct iwl_cmd) * q->n_window;
@@ -264,7 +154,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* De-alloc circular buffer of TFDs */
if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+ pci_free_consistent(dev, priv->hw_params.tfd_size *
txq->q.n_bd, txq->tfds, txq->q.dma_addr);
/* De-alloc array of per-TFD driver data */
@@ -274,7 +164,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq));
}
-
+EXPORT_SYMBOL(iwl_tx_queue_free);
/**
* iwl_cmd_queue_free - Deallocate DMA queue.
@@ -388,6 +278,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
struct iwl_tx_queue *txq, u32 id)
{
struct pci_dev *dev = priv->pci_dev;
+ size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
/* Driver private data, only for Tx (not command) queues,
* not shared with device. */
@@ -395,22 +286,20 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
txq->txb = kmalloc(sizeof(txq->txb[0]) *
TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
if (!txq->txb) {
- IWL_ERROR("kmalloc for auxiliary BD "
+ IWL_ERR(priv, "kmalloc for auxiliary BD "
"structures failed\n");
goto error;
}
- } else
+ } else {
txq->txb = NULL;
+ }
/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
- txq->tfds = pci_alloc_consistent(dev,
- sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
+ txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr);
if (!txq->tfds) {
- IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX);
+ IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
goto error;
}
txq->q.id = id;
@@ -424,42 +313,11 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
return -ENOMEM;
}
-/*
- * Tell nic where to find circular buffer of Tx Frame Descriptors for
- * given Tx queue, and enable the DMA channel used for that queue.
- *
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
- * channels supported in hardware.
- */
-static 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;
-}
-
/**
* iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
*/
-static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
- int slots_num, u32 txq_id)
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id)
{
int i, len;
int ret;
@@ -501,7 +359,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
/* Tell device where to find queue */
- iwl_hw_tx_queue_init(priv, txq);
+ priv->cfg->ops->lib->txq_init(priv, txq);
return 0;
err:
@@ -516,6 +374,8 @@ err:
}
return -ENOMEM;
}
+EXPORT_SYMBOL(iwl_tx_queue_init);
+
/**
* iwl_hw_txq_ctx_free - Free TXQ Context
*
@@ -557,13 +417,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
priv->hw_params.scd_bc_tbls_size);
if (ret) {
- IWL_ERROR("Scheduler BC Table allocation failed\n");
+ IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
goto error_bc_tbls;
}
/* Alloc keep-warm buffer */
ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
if (ret) {
- IWL_ERROR("Keep Warm allocation failed\n");
+ IWL_ERR(priv, "Keep Warm allocation failed\n");
goto error_kw;
}
spin_lock_irqsave(&priv->lock, flags);
@@ -589,7 +449,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
if (ret) {
- IWL_ERROR("Tx %d queue init failed\n", txq_id);
+ IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
goto error;
}
}
@@ -778,14 +638,14 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
if (info->flags & IEEE80211_TX_CTL_AMPDU)
tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
- IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
+ IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;
case ALG_TKIP:
tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
ieee80211_get_tkip_key(keyconf, skb_frag,
IEEE80211_TKIP_P2_KEY, tx_cmd->key);
- IWL_DEBUG_TX("tx_cmd with tkip hwcrypto\n");
+ IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
break;
case ALG_WEP:
@@ -797,12 +657,12 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
- IWL_DEBUG_TX("Configuring packet for WEP encryption "
+ IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
"with key %d\n", keyconf->keyidx);
break;
default:
- printk(KERN_ERR "Unknown encode alg %d\n", keyconf->alg);
+ IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
break;
}
}
@@ -822,7 +682,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl_tfd *tfd;
struct iwl_tx_queue *txq;
struct iwl_queue *q;
struct iwl_cmd *out_cmd;
@@ -844,13 +703,13 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_DROP("Dropping - RF KILL\n");
+ IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
goto drop_unlock;
}
if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
IWL_INVALID_RATE) {
- IWL_ERROR("ERROR: No TX rate available.\n");
+ IWL_ERR(priv, "ERROR: No TX rate available.\n");
goto drop_unlock;
}
@@ -858,11 +717,11 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
#ifdef CONFIG_IWLWIFI_DEBUG
if (ieee80211_is_auth(fc))
- IWL_DEBUG_TX("Sending AUTH frame\n");
+ IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
else if (ieee80211_is_assoc_req(fc))
- IWL_DEBUG_TX("Sending ASSOC frame\n");
+ IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
else if (ieee80211_is_reassoc_req(fc))
- IWL_DEBUG_TX("Sending REASSOC frame\n");
+ IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
#endif
/* drop all data frame if we are not associated */
@@ -872,7 +731,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
(!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
!priv->assoc_station_added)) {
- IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
+ IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
goto drop_unlock;
}
@@ -883,12 +742,12 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Find (or create) index into station table for destination station */
sta_id = iwl_get_sta_id(priv, hdr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+ IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
goto drop;
}
- IWL_DEBUG_TX("station Id %d\n", sta_id);
+ IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
swq_id = skb_get_queue_mapping(skb);
txq_id = swq_id;
@@ -898,7 +757,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
seq_number = priv->stations[sta_id].tid[tid].seq_number;
seq_number &= IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = hdr->seq_ctrl &
- __constant_cpu_to_le16(IEEE80211_SCTL_FRAG);
+ cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(seq_number);
seq_number += 0x10;
/* aggregation is on for this <sta,tid> */
@@ -913,10 +772,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
- /* Set up first empty TFD within this queue's circular TFD buffer */
- tfd = &txq->tfds[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb[0] = skb;
@@ -964,13 +819,14 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
* within command buffer array. */
txcmd_phys = pci_map_single(priv->pci_dev,
out_cmd, sizeof(struct iwl_cmd),
- PCI_DMA_TODEVICE);
+ PCI_DMA_BIDIRECTIONAL);
pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
txcmd_phys += offsetof(struct iwl_cmd, hdr);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ txcmd_phys, len, 1, 0);
if (info->control.hw_key)
iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
@@ -981,7 +837,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (len) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
len, PCI_DMA_TODEVICE);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, len,
+ 0, 0);
}
/* Tell NIC about any 2-byte padding after MAC header */
@@ -1063,7 +921,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
struct iwl_queue *q = &txq->q;
- struct iwl_tfd *tfd;
struct iwl_cmd *out_cmd;
dma_addr_t phys_addr;
unsigned long flags;
@@ -1081,21 +938,17 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
!(cmd->meta.flags & CMD_SIZE_HUGE));
if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_INFO("Not sending command - RF KILL");
+ IWL_DEBUG_INFO(priv, "Not sending command - RF KILL");
return -EIO;
}
if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
- IWL_ERROR("No space for Tx\n");
+ IWL_ERR(priv, "No space for Tx\n");
return -ENOSPC;
}
spin_lock_irqsave(&priv->hcmd_lock, flags);
- tfd = &txq->tfds[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
-
idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
out_cmd = txq->cmd[idx];
@@ -1115,18 +968,20 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
phys_addr = pci_map_single(priv->pci_dev, out_cmd,
- len, PCI_DMA_TODEVICE);
+ len, PCI_DMA_BIDIRECTIONAL);
pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
pci_unmap_len_set(&out_cmd->meta, len, len);
phys_addr += offsetof(struct iwl_cmd, hdr);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, fix_size, 1,
+ U32_PAD(cmd->len));
#ifdef CONFIG_IWLWIFI_DEBUG
switch (out_cmd->hdr.cmd) {
case REPLY_TX_LINK_QUALITY_CMD:
case SENSITIVITY_CMD:
- IWL_DEBUG_HC_DUMP("Sending command %s (#%x), seq: 0x%04X, "
+ IWL_DEBUG_HC_DUMP(priv, "Sending command %s (#%x), seq: 0x%04X, "
"%d bytes at %d[%d]:%d\n",
get_cmd_string(out_cmd->hdr.cmd),
out_cmd->hdr.cmd,
@@ -1134,7 +989,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
break;
default:
- IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
+ IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
"%d bytes at %d[%d]:%d\n",
get_cmd_string(out_cmd->hdr.cmd),
out_cmd->hdr.cmd,
@@ -1144,8 +999,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
#endif
txq->need_update = 1;
- /* Set up entry in queue's byte count circular buffer */
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
+ if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl)
+ /* Set up entry in queue's byte count circular buffer */
+ priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
/* Increment and update queue's write index */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -1163,7 +1019,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
int nfreed = 0;
if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
"is out of range [0-%d] %d %d.\n", txq_id,
index, q->n_bd, q->write_ptr, q->read_ptr);
return 0;
@@ -1180,7 +1036,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
- iwl_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
nfreed++;
}
return nfreed;
@@ -1203,7 +1059,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
int nfreed = 0;
if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
"is out of range [0-%d] %d %d.\n", txq_id,
idx, q->n_bd, q->write_ptr, q->read_ptr);
return;
@@ -1212,13 +1068,13 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
pci_unmap_single(priv->pci_dev,
pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping),
pci_unmap_len(&txq->cmd[cmd_idx]->meta, len),
- PCI_DMA_TODEVICE);
+ PCI_DMA_BIDIRECTIONAL);
for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
if (nfreed++ > 0) {
- IWL_ERROR("HCMD skipped: index (%d) %d %d\n", idx,
+ IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
q->write_ptr, q->read_ptr);
queue_work(priv->workqueue, &priv->restart);
}
@@ -1306,7 +1162,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
else
return -EINVAL;
- IWL_WARNING("%s on ra = %pM tid = %d\n",
+ IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
__func__, ra, tid);
sta_id = iwl_find_station(priv, ra);
@@ -1314,7 +1170,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return -ENXIO;
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
- IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n");
+ IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
return -ENXIO;
}
@@ -1334,11 +1190,11 @@ 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) {
- printk(KERN_ERR "HW queue is empty\n");
+ IWL_ERR(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
} else {
- IWL_DEBUG_HT("HW queue is NOT empty: %d packets in HW queue\n",
+ IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
tid_data->tfds_in_queue);
tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
}
@@ -1354,7 +1210,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
unsigned long flags;
if (!ra) {
- IWL_ERROR("ra = NULL\n");
+ IWL_ERR(priv, "ra = NULL\n");
return -EINVAL;
}
@@ -1369,7 +1225,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
return -ENXIO;
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
- IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n");
+ IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n");
tid_data = &priv->stations[sta_id].tid[tid];
ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
@@ -1379,13 +1235,13 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
/* The queue is not empty */
if (write_ptr != read_ptr) {
- IWL_DEBUG_HT("Stopping a non empty AGG HW QUEUE\n");
+ IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
priv->stations[sta_id].tid[tid].agg.state =
IWL_EMPTYING_HW_QUEUE_DELBA;
return 0;
}
- IWL_DEBUG_HT("HW queue is empty\n");
+ IWL_DEBUG_HT(priv, "HW queue is empty\n");
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
spin_lock_irqsave(&priv->lock, flags);
@@ -1416,7 +1272,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
(q->read_ptr == q->write_ptr)) {
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
int tx_fifo = default_tid_to_tx_fifo[tid];
- IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n");
+ IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
ssn, tx_fifo);
tid_data->agg.state = IWL_AGG_OFF;
@@ -1426,7 +1282,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
case IWL_EMPTYING_HW_QUEUE_ADDBA:
/* We are reclaiming the last packet of the queue */
if (tid_data->tfds_in_queue == 0) {
- IWL_DEBUG_HT("HW queue empty: continue ADDBA flow\n");
+ IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid);
}
@@ -1455,13 +1311,13 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
struct ieee80211_tx_info *info;
if (unlikely(!agg->wait_for_ba)) {
- IWL_ERROR("Received BA when not expected\n");
+ IWL_ERR(priv, "Received BA when not expected\n");
return -EINVAL;
}
/* Mark that the expected block-ack response arrived */
agg->wait_for_ba = 0;
- IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
+ IWL_DEBUG_TX_REPLY(priv, "BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
/* Calculate shift to align block-ack bits with our Tx window bits */
sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
@@ -1472,7 +1328,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
if (agg->frame_count > (64 - sh)) {
- IWL_DEBUG_TX_REPLY("more frames than bitmap size");
+ IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
return -1;
}
@@ -1485,7 +1341,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
for (i = 0; i < agg->frame_count ; i++) {
ack = bitmap & (1ULL << i);
successes += !!ack;
- IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
agg->start_idx + i);
}
@@ -1498,7 +1354,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
info->status.ampdu_ack_len = agg->frame_count;
iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
- IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
+ IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
return 0;
}
@@ -1528,7 +1384,8 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
if (scd_flow >= priv->hw_params.max_txq_num) {
- IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n");
+ IWL_ERR(priv,
+ "BUG_ON scd_flow is bigger than number of queues\n");
return;
}
@@ -1542,19 +1399,19 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
/* TODO: Need to get this copy more safely - now good for debug */
- IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d] Received from %pM, "
+ IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
"sta_id = %d\n",
agg->wait_for_ba,
(u8 *) &ba_resp->sta_addr_lo32,
ba_resp->sta_id);
- IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
+ IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
"%d, scd_ssn = %d\n",
ba_resp->tid,
ba_resp->seq_ctl,
(unsigned long long)le64_to_cpu(ba_resp->bitmap),
ba_resp->scd_flow,
ba_resp->scd_ssn);
- IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
+ IWL_DEBUG_TX_REPLY(priv, "DAT start_idx = %d, bitmap = 0x%llx \n",
agg->start_idx,
(unsigned long long)agg->bitmap);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d64580805d6..4465320f273 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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.
@@ -46,40 +46,25 @@
#include <asm/div64.h>
-#include "iwl-3945-core.h"
+#define DRV_NAME "iwl3945"
+
+#include "iwl-fh.h"
+#include "iwl-3945-fh.h"
+#include "iwl-commands.h"
+#include "iwl-sta.h"
#include "iwl-3945.h"
#include "iwl-helpers.h"
-
-#ifdef CONFIG_IWL3945_DEBUG
-u32 iwl3945_debug_level;
-#endif
-
-static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq);
-
-/******************************************************************************
- *
- * module boiler plate
- *
- ******************************************************************************/
-
-/* module parameters */
-static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */
-static u32 iwl3945_param_debug; /* def: 0 = minimal debug log messages */
-static int iwl3945_param_disable; /* def: 0 = enable radio */
-static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */
-int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */
-int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
+#include "iwl-core.h"
+#include "iwl-dev.h"
/*
* module name, copyright, version, etc.
- * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
*/
#define DRV_DESCRIPTION \
"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux"
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
#define VD "d"
#else
#define VD
@@ -91,10 +76,10 @@ int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
#define VS
#endif
-#define IWLWIFI_VERSION "1.2.26k" VD VS
-#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define IWL39_VERSION "1.2.26k" VD VS
+#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
-#define DRV_VERSION IWLWIFI_VERSION
+#define DRV_VERSION IWL39_VERSION
MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -102,235 +87,13 @@ MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
-static const struct ieee80211_supported_band *iwl3945_get_band(
- struct iwl3945_priv *priv, enum ieee80211_band band)
-{
- return priv->hw->wiphy->bands[band];
-}
-
-/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
- * DMA services
- *
- * Theory of operation
- *
- * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
- * of buffer descriptors, each of which points to one or more data buffers for
- * the device to read from or fill. Driver and device exchange status of each
- * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty
- * entries in each circular buffer, to protect against confusing empty and full
- * queue states.
- *
- * The device reads or writes the data in the queues via the device's several
- * DMA/FIFO channels. Each queue is mapped to a single DMA channel.
- *
- * For Tx queue, there are low mark and high mark limits. If, after queuing
- * the packet for Tx, free space become < low mark, Tx queue stopped. When
- * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
- * Tx queue resumed.
- *
- * The 3945 operates with six queues: One receive queue, one transmit queue
- * (#4) for sending commands to the device firmware, and four transmit queues
- * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused.
- ***************************************************/
-
-int iwl3945_queue_space(const struct iwl3945_queue *q)
-{
- int s = q->read_ptr - q->write_ptr;
-
- if (q->read_ptr > q->write_ptr)
- s -= q->n_bd;
-
- if (s <= 0)
- s += q->n_window;
- /* keep some reserve to not confuse empty and full situations */
- s -= 2;
- if (s < 0)
- s = 0;
- return s;
-}
-
-int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i)
-{
- return q->write_ptr > q->read_ptr ?
- (i >= q->read_ptr && i < q->write_ptr) :
- !(i < q->read_ptr && i >= q->write_ptr);
-}
-
-
-static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge)
-{
- /* This is for scan command, the big buffer at end of command array */
- if (is_huge)
- return q->n_window; /* must be power of 2 */
-
- /* Otherwise, use normal size buffers */
- return index & (q->n_window - 1);
-}
-
-/**
- * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes
- */
-static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q,
- int count, int slots_num, u32 id)
-{
- q->n_bd = count;
- q->n_window = slots_num;
- q->id = id;
-
- /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
- * and iwl_queue_dec_wrap are broken. */
- BUG_ON(!is_power_of_2(count));
-
- /* slots_num must be power-of-two size, otherwise
- * get_cmd_index is broken. */
- BUG_ON(!is_power_of_2(slots_num));
-
- q->low_mark = q->n_window / 4;
- if (q->low_mark < 4)
- q->low_mark = 4;
-
- q->high_mark = q->n_window / 8;
- if (q->high_mark < 2)
- q->high_mark = 2;
-
- q->write_ptr = q->read_ptr = 0;
-
- return 0;
-}
-
-/**
- * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
- */
-static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, u32 id)
-{
- struct pci_dev *dev = priv->pci_dev;
-
- /* Driver private data, only for Tx (not command) queues,
- * not shared with device. */
- if (id != IWL_CMD_QUEUE_NUM) {
- txq->txb = kmalloc(sizeof(txq->txb[0]) *
- TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
- if (!txq->txb) {
- IWL_ERROR("kmalloc for auxiliary BD "
- "structures failed\n");
- goto error;
- }
- } else
- txq->txb = NULL;
-
- /* Circular buffer of transmit frame descriptors (TFDs),
- * shared with device */
- txq->bd = pci_alloc_consistent(dev,
- sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
-
- if (!txq->bd) {
- IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX);
- goto error;
- }
- txq->q.id = id;
-
- return 0;
-
- error:
- kfree(txq->txb);
- txq->txb = NULL;
-
- return -ENOMEM;
-}
-
-/**
- * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue
- */
-int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id)
-{
- struct pci_dev *dev = priv->pci_dev;
- int len;
- int rc = 0;
-
- /*
- * Alloc buffer array for commands (Tx or other types of commands).
- * For the command queue (#4), allocate command space + one big
- * command for scan, since scan command is very huge; the system will
- * not have two scans at the same time, so only one is needed.
- * For data Tx queues (all other queues), no super-size command
- * space is needed.
- */
- len = sizeof(struct iwl3945_cmd) * slots_num;
- if (txq_id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
- txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
- if (!txq->cmd)
- return -ENOMEM;
-
- /* Alloc driver data array and TFD circular buffer */
- rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
- if (rc) {
- pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
- return -ENOMEM;
- }
- txq->need_update = 0;
-
- /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
- * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
- BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
- /* Initialize queue high/low-water, head/tail indexes */
- iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
-
- /* Tell device where to find queue, enable DMA channel. */
- iwl3945_hw_tx_queue_init(priv, txq);
-
- return 0;
-}
-
-/**
- * iwl3945_tx_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
-{
- struct iwl3945_queue *q = &txq->q;
- struct pci_dev *dev = priv->pci_dev;
- int len;
-
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- iwl3945_hw_txq_free_tfd(priv, txq);
-
- len = sizeof(struct iwl3945_cmd) * q->n_window;
- if (q->id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
-
- /* De-alloc array of command/tx buffers */
- pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
- /* De-alloc circular buffer of TFDs */
- if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) *
- txq->q.n_bd, txq->bd, txq->q.dma_addr);
-
- /* De-alloc array of per-TFD driver data */
- kfree(txq->txb);
- txq->txb = NULL;
-
- /* 0-fill queue descriptor structure */
- memset(txq, 0, sizeof(*txq));
-}
-
-const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ /* module parameters */
+struct iwl_mod_params iwl3945_mod_params = {
+ .num_of_queues = IWL39_MAX_NUM_QUEUES,
+ .sw_crypto = 1,
+ .restart_fw = 1,
+ /* the rest are 0 by default */
+};
/*************** STATION TABLE MANAGEMENT ****
* mac80211 should be examined to determine if sta_info is duplicating
@@ -344,7 +107,7 @@ const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
*
* NOTE: This does not remove station from device's station table.
*/
-static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap)
+static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
{
int index = IWL_INVALID_STATION;
int i;
@@ -355,11 +118,11 @@ static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int
if (is_ap)
index = IWL_AP_ID;
else if (is_broadcast_ether_addr(addr))
- index = priv->hw_setting.bcast_sta_id;
+ index = priv->hw_params.bcast_sta_id;
else
- for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
- if (priv->stations[i].used &&
- !compare_ether_addr(priv->stations[i].sta.sta.addr,
+ 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;
@@ -368,8 +131,8 @@ static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int
if (unlikely(index == IWL_INVALID_STATION))
goto out;
- if (priv->stations[index].used) {
- priv->stations[index].used = 0;
+ if (priv->stations_39[index].used) {
+ priv->stations_39[index].used = 0;
priv->num_stations--;
}
@@ -386,14 +149,14 @@ out:
*
* NOTE: This does not clear or otherwise alter the device's station table.
*/
-static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)
+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, 0, sizeof(priv->stations));
+ memset(priv->stations_39, 0, sizeof(priv->stations_39));
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
@@ -401,7 +164,7 @@ static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)
/**
* iwl3945_add_station - Add station to station tables in driver and device
*/
-u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags)
+u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
{
int i;
int index = IWL_INVALID_STATION;
@@ -413,16 +176,16 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
if (is_ap)
index = IWL_AP_ID;
else if (is_broadcast_ether_addr(addr))
- index = priv->hw_setting.bcast_sta_id;
+ index = priv->hw_params.bcast_sta_id;
else
- for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) {
- if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
+ 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[i].used &&
+ if (!priv->stations_39[i].used &&
index == IWL_INVALID_STATION)
index = i;
}
@@ -434,14 +197,14 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
return index;
}
- if (priv->stations[index].used &&
- !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) {
+ 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("Add STA ID %d: %pM\n", index, addr);
- station = &priv->stations[index];
+ IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
+ station = &priv->stations_39[index];
station->used = 1;
priv->num_stations++;
@@ -460,531 +223,35 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
/* Turn on both antennas for the station... */
station->sta.rate_n_flags =
iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
- station->current_rate.rate_n_flags =
- le16_to_cpu(station->sta.rate_n_flags);
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
/* Add station to device's station table */
- iwl3945_send_add_station(priv, &station->sta, flags);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&station->sta, flags);
return index;
}
-/*************** DRIVER STATUS FUNCTIONS *****/
-
-static inline int iwl3945_is_ready(struct iwl3945_priv *priv)
-{
- /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
- * set but EXIT_PENDING is not */
- return test_bit(STATUS_READY, &priv->status) &&
- test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
- !test_bit(STATUS_EXIT_PENDING, &priv->status);
-}
-
-static inline int iwl3945_is_alive(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_ALIVE, &priv->status);
-}
-
-static inline int iwl3945_is_init(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_INIT, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_HW, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
-{
- return iwl3945_is_rfkill_hw(priv) ||
- iwl3945_is_rfkill_sw(priv);
-}
-
-static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
-{
-
- if (iwl3945_is_rfkill(priv))
- return 0;
-
- return iwl3945_is_ready(priv);
-}
-
-/*************** HOST COMMAND QUEUE FUNCTIONS *****/
-
-#define IWL_CMD(x) case x: return #x
-
-static const char *get_cmd_string(u8 cmd)
-{
- switch (cmd) {
- IWL_CMD(REPLY_ALIVE);
- IWL_CMD(REPLY_ERROR);
- IWL_CMD(REPLY_RXON);
- IWL_CMD(REPLY_RXON_ASSOC);
- IWL_CMD(REPLY_QOS_PARAM);
- IWL_CMD(REPLY_RXON_TIMING);
- IWL_CMD(REPLY_ADD_STA);
- IWL_CMD(REPLY_REMOVE_STA);
- IWL_CMD(REPLY_REMOVE_ALL_STA);
- IWL_CMD(REPLY_3945_RX);
- IWL_CMD(REPLY_TX);
- IWL_CMD(REPLY_RATE_SCALE);
- IWL_CMD(REPLY_LEDS_CMD);
- IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
- IWL_CMD(RADAR_NOTIFICATION);
- IWL_CMD(REPLY_QUIET_CMD);
- IWL_CMD(REPLY_CHANNEL_SWITCH);
- IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
- IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
- IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
- IWL_CMD(POWER_TABLE_CMD);
- IWL_CMD(PM_SLEEP_NOTIFICATION);
- IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
- IWL_CMD(REPLY_SCAN_CMD);
- IWL_CMD(REPLY_SCAN_ABORT_CMD);
- IWL_CMD(SCAN_START_NOTIFICATION);
- IWL_CMD(SCAN_RESULTS_NOTIFICATION);
- IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
- IWL_CMD(BEACON_NOTIFICATION);
- IWL_CMD(REPLY_TX_BEACON);
- IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
- IWL_CMD(QUIET_NOTIFICATION);
- IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
- IWL_CMD(MEASURE_ABORT_NOTIFICATION);
- IWL_CMD(REPLY_BT_CONFIG);
- IWL_CMD(REPLY_STATISTICS_CMD);
- IWL_CMD(STATISTICS_NOTIFICATION);
- IWL_CMD(REPLY_CARD_STATE_CMD);
- IWL_CMD(CARD_STATE_NOTIFICATION);
- IWL_CMD(MISSED_BEACONS_NOTIFICATION);
- default:
- return "UNKNOWN";
-
- }
-}
-
-#define HOST_COMPLETE_TIMEOUT (HZ / 2)
-
-/**
- * iwl3945_enqueue_hcmd - enqueue a uCode command
- * @priv: device private data point
- * @cmd: a point to the ucode command structure
- *
- * The function returns < 0 values to indicate the operation is
- * failed. On success, it turns the index (> 0) of command in the
- * command queue.
- */
-static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- struct iwl3945_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
- struct iwl3945_queue *q = &txq->q;
- struct iwl3945_tfd_frame *tfd;
- u32 *control_flags;
- struct iwl3945_cmd *out_cmd;
- u32 idx;
- u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
- dma_addr_t phys_addr;
- int pad;
- u16 count;
- int ret;
- unsigned long flags;
-
- /* If any of the command structures end up being larger than
- * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
- * we will need to increase the size of the TFD entries */
- BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
- !(cmd->meta.flags & CMD_SIZE_HUGE));
-
-
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_INFO("Not sending command - RF KILL");
- return -EIO;
- }
-
- if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
- IWL_ERROR("No space for Tx\n");
- return -ENOSPC;
- }
-
- spin_lock_irqsave(&priv->hcmd_lock, flags);
-
- tfd = &txq->bd[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
- control_flags = (u32 *) tfd;
-
- idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
- out_cmd = &txq->cmd[idx];
-
- out_cmd->hdr.cmd = cmd->id;
- memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
- memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
-
- /* At this point, the out_cmd now has all of the incoming cmd
- * information */
-
- out_cmd->hdr.flags = 0;
- out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
- INDEX_TO_SEQ(q->write_ptr));
- if (out_cmd->meta.flags & CMD_SIZE_HUGE)
- out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
-
- phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
- offsetof(struct iwl3945_cmd, hdr);
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
-
- pad = U32_PAD(cmd->len);
- count = TFD_CTL_COUNT_GET(*control_flags);
- *control_flags = TFD_CTL_COUNT_SET(count) | TFD_CTL_PAD_SET(pad);
-
- IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
- "%d bytes at %d[%d]:%d\n",
- get_cmd_string(out_cmd->hdr.cmd),
- out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
- fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
-
- txq->need_update = 1;
-
- /* Increment and update queue's write index */
- q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- ret = iwl3945_tx_queue_update_write_ptr(priv, txq);
-
- spin_unlock_irqrestore(&priv->hcmd_lock, flags);
- return ret ? ret : idx;
-}
-
-static int iwl3945_send_cmd_async(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- int ret;
-
- BUG_ON(!(cmd->meta.flags & CMD_ASYNC));
-
- /* An asynchronous command can not expect an SKB to be set. */
- BUG_ON(cmd->meta.flags & CMD_WANT_SKB);
-
- /* An asynchronous command MUST have a callback. */
- BUG_ON(!cmd->meta.u.callback);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return -EBUSY;
-
- ret = iwl3945_enqueue_hcmd(priv, cmd);
- if (ret < 0) {
- IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
- get_cmd_string(cmd->id), ret);
- return ret;
- }
- return 0;
-}
-
-static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- int cmd_idx;
- int ret;
-
- BUG_ON(cmd->meta.flags & CMD_ASYNC);
-
- /* A synchronous command can not have a callback set. */
- BUG_ON(cmd->meta.u.callback != NULL);
-
- if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: Already sending a host command\n",
- get_cmd_string(cmd->id));
- ret = -EBUSY;
- goto out;
- }
-
- set_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
- if (cmd->meta.flags & CMD_WANT_SKB)
- cmd->meta.source = &cmd->meta;
-
- cmd_idx = iwl3945_enqueue_hcmd(priv, cmd);
- if (cmd_idx < 0) {
- ret = cmd_idx;
- IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
- get_cmd_string(cmd->id), ret);
- goto out;
- }
-
- ret = wait_event_interruptible_timeout(priv->wait_command_queue,
- !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
- HOST_COMPLETE_TIMEOUT);
- if (!ret) {
- if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: time out after %dms.\n",
- get_cmd_string(cmd->id),
- jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
-
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
- ret = -ETIMEDOUT;
- goto cancel;
- }
- }
-
- if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n",
- get_cmd_string(cmd->id));
- ret = -ECANCELED;
- goto fail;
- }
- if (test_bit(STATUS_FW_ERROR, &priv->status)) {
- IWL_DEBUG_INFO("Command %s failed: FW Error\n",
- get_cmd_string(cmd->id));
- ret = -EIO;
- goto fail;
- }
- if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
- IWL_ERROR("Error: Response NULL in '%s'\n",
- get_cmd_string(cmd->id));
- ret = -EIO;
- goto out;
- }
-
- ret = 0;
- goto out;
-
-cancel:
- if (cmd->meta.flags & CMD_WANT_SKB) {
- struct iwl3945_cmd *qcmd;
-
- /* Cancel the CMD_WANT_SKB flag for the cmd in the
- * TX cmd queue. Otherwise in case the cmd comes
- * in later, it will possibly set an invalid
- * address (cmd->meta.source). */
- qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
- qcmd->meta.flags &= ~CMD_WANT_SKB;
- }
-fail:
- if (cmd->meta.u.skb) {
- dev_kfree_skb_any(cmd->meta.u.skb);
- cmd->meta.u.skb = NULL;
- }
-out:
- clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
- return ret;
-}
-
-int iwl3945_send_cmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- if (cmd->meta.flags & CMD_ASYNC)
- return iwl3945_send_cmd_async(priv, cmd);
-
- return iwl3945_send_cmd_sync(priv, cmd);
-}
-
-int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, const void *data)
-{
- struct iwl3945_host_cmd cmd = {
- .id = id,
- .len = len,
- .data = data,
- };
-
- return iwl3945_send_cmd_sync(priv, &cmd);
-}
-
-static int __must_check iwl3945_send_cmd_u32(struct iwl3945_priv *priv, u8 id, u32 val)
-{
- struct iwl3945_host_cmd cmd = {
- .id = id,
- .len = sizeof(val),
- .data = &val,
- };
-
- return iwl3945_send_cmd_sync(priv, &cmd);
-}
-
-int iwl3945_send_statistics_request(struct iwl3945_priv *priv)
-{
- return iwl3945_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
-}
-
-/**
- * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON
- * @band: 2.4 or 5 GHz band
- * @channel: Any channel valid for the requested band
-
- * In addition to setting the staging RXON, priv->band is also set.
- *
- * NOTE: Does not commit to the hardware; it sets appropriate bit fields
- * in the staging RXON flag structure based on the band
- */
-static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv,
- enum ieee80211_band band,
- u16 channel)
-{
- if (!iwl3945_get_channel_info(priv, band, channel)) {
- IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
- channel, band);
- return -EINVAL;
- }
-
- if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
- (priv->band == band))
- return 0;
-
- priv->staging_rxon.channel = cpu_to_le16(channel);
- if (band == IEEE80211_BAND_5GHZ)
- priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
- else
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
-
- priv->band = band;
-
- IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
-
- return 0;
-}
-
-/**
- * iwl3945_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE: This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
-static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon)
-{
- int error = 0;
- int counter = 1;
-
- if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
- error |= le32_to_cpu(rxon->flags &
- (RXON_FLG_TGJ_NARROW_BAND_MSK |
- RXON_FLG_RADAR_DETECT_MSK));
- if (error)
- IWL_WARNING("check 24G fields %d | %d\n",
- counter++, error);
- } else {
- error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
- 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
- if (error)
- IWL_WARNING("check 52 fields %d | %d\n",
- counter++, error);
- error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
- if (error)
- IWL_WARNING("check 52 CCK %d | %d\n",
- counter++, error);
- }
- error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
- if (error)
- IWL_WARNING("check mac addr %d | %d\n", counter++, error);
-
- /* make sure basic rates 6Mbps and 1Mbps are supported */
- error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
- ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
- if (error)
- IWL_WARNING("check basic rate %d | %d\n", counter++, error);
-
- error |= (le16_to_cpu(rxon->assoc_id) > 2007);
- if (error)
- IWL_WARNING("check assoc id %d | %d\n", counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
- if (error)
- IWL_WARNING("check CCK and short slot %d | %d\n",
- counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
- if (error)
- IWL_WARNING("check CCK & auto detect %d | %d\n",
- counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
- RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
- if (error)
- IWL_WARNING("check TGG and auto detect %d | %d\n",
- counter++, error);
-
- if ((rxon->flags & RXON_FLG_DIS_DIV_MSK))
- error |= ((rxon->flags & (RXON_FLG_ANT_B_MSK |
- RXON_FLG_ANT_A_MSK)) == 0);
- if (error)
- IWL_WARNING("check antenna %d %d\n", counter++, error);
-
- if (error)
- IWL_WARNING("Tuning to channel %d\n",
- le16_to_cpu(rxon->channel));
-
- if (error) {
- IWL_ERROR("Not a valid iwl3945_rxon_assoc_cmd field values\n");
- return -1;
- }
- return 0;
-}
-
-/**
- * iwl3945_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
- * @priv: staging_rxon is compared to active_rxon
- *
- * If the RXON structure is changing enough to require a new tune,
- * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
- * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
- */
-static int iwl3945_full_rxon_required(struct iwl3945_priv *priv)
-{
-
- /* These items are only settable from the full RXON command */
- if (!(iwl3945_is_associated(priv)) ||
- compare_ether_addr(priv->staging_rxon.bssid_addr,
- priv->active_rxon.bssid_addr) ||
- compare_ether_addr(priv->staging_rxon.node_addr,
- priv->active_rxon.node_addr) ||
- compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
- priv->active_rxon.wlap_bssid_addr) ||
- (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
- (priv->staging_rxon.channel != priv->active_rxon.channel) ||
- (priv->staging_rxon.air_propagation !=
- priv->active_rxon.air_propagation) ||
- (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
- return 1;
-
- /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
- * be updated with the RXON_ASSOC command -- however only some
- * flag transitions are allowed using RXON_ASSOC */
-
- /* Check if we are not switching bands */
- if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
- (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
- return 1;
-
- /* Check if we are switching association toggle */
- if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
- (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
- return 1;
-
- return 0;
-}
-
-static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
{
int rc = 0;
- struct iwl3945_rx_packet *res = NULL;
+ struct iwl_rx_packet *res = NULL;
struct iwl3945_rxon_assoc_cmd rxon_assoc;
- struct iwl3945_host_cmd cmd = {
+ struct iwl_host_cmd cmd = {
.id = REPLY_RXON_ASSOC,
.len = sizeof(rxon_assoc),
.meta.flags = CMD_WANT_SKB,
.data = &rxon_assoc,
};
- const struct iwl3945_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl3945_rxon_cmd *rxon2 = &priv->active_rxon;
+ 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("Using current RXON_ASSOC. Not resending.\n");
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
return 0;
}
@@ -994,13 +261,13 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
rxon_assoc.reserved = 0;
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
return rc;
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
rc = -EIO;
}
@@ -1011,6 +278,43 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
}
/**
+ * iwl3945_get_antenna_flags - Get antenna flags for RXON command
+ * @priv: eeprom and antenna fields are used to determine antenna flags
+ *
+ * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed
+ * iwl3945_mod_params.antenna specifies the antenna diversity mode:
+ *
+ * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
+ * IWL_ANTENNA_MAIN - Force MAIN antenna
+ * IWL_ANTENNA_AUX - Force AUX antenna
+ */
+__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
+{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+
+ switch (iwl3945_mod_params.antenna) {
+ case IWL_ANTENNA_DIVERSITY:
+ return 0;
+
+ case IWL_ANTENNA_MAIN:
+ if (eeprom->antenna_switch_type)
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+
+ case IWL_ANTENNA_AUX:
+ if (eeprom->antenna_switch_type)
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+ }
+
+ /* bad antenna selector value */
+ IWL_ERR(priv, "Bad antenna selector value (0x%x)\n",
+ iwl3945_mod_params.antenna);
+
+ 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
@@ -1018,41 +322,44 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
+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 (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -1;
/* always get timestamp with Rx frame */
- priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
+ staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
/* select antenna */
- priv->staging_rxon.flags &=
+ staging_rxon->flags &=
~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
- priv->staging_rxon.flags |= iwl3945_get_antenna_flags(priv);
+ staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
- rc = iwl3945_check_rxon_cmd(&priv->staging_rxon);
+ rc = iwl_check_rxon_cmd(priv);
if (rc) {
- IWL_ERROR("Invalid RXON configuration. Not committing.\n");
+ 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 (!iwl3945_full_rxon_required(priv)) {
+ if (!iwl_full_rxon_required(priv)) {
rc = iwl3945_send_rxon_assoc(priv);
if (rc) {
- IWL_ERROR("Error setting RXON_ASSOC "
+ IWL_ERR(priv, "Error setting RXON_ASSOC "
"configuration (%d).\n", rc);
return rc;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
return 0;
}
@@ -1061,12 +368,17 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (iwl3945_is_associated(priv) &&
- (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
- IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
+ 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;
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
+ /*
+ * 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);
@@ -1074,290 +386,213 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
* active_rxon back to what it was previously */
if (rc) {
active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERROR("Error clearing ASSOC_MSK on current "
+ IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
"configuration (%d).\n", rc);
return rc;
}
}
- IWL_DEBUG_INFO("Sending RXON\n"
+ IWL_DEBUG_INFO(priv, "Sending RXON\n"
"* with%s RXON_FILTER_ASSOC_MSK\n"
"* channel = %d\n"
"* bssid = %pM\n",
- ((priv->staging_rxon.filter_flags &
- RXON_FILTER_ASSOC_MSK) ? "" : "out"),
- le16_to_cpu(priv->staging_rxon.channel),
- priv->staging_rxon.bssid_addr);
+ (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 = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd), &priv->staging_rxon);
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl3945_rxon_cmd),
+ staging_rxon);
if (rc) {
- IWL_ERROR("Error setting new configuration (%d).\n", rc);
+ IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
return rc;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ 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 = iwl3945_hw_reg_send_txpower(priv);
+ rc = priv->cfg->ops->lib->send_tx_power(priv);
if (rc) {
- IWL_ERROR("Error setting Tx power (%d).\n", 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, iwl3945_broadcast_addr, 0, 0) ==
+ if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
IWL_INVALID_STATION) {
- IWL_ERROR("Error adding BROADCAST address for transmit.\n");
+ 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 (iwl3945_is_associated(priv) &&
+ if (iwl_is_associated(priv) &&
(priv->iw_mode == NL80211_IFTYPE_STATION))
- if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
+ if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
+ 1, 0)
== IWL_INVALID_STATION) {
- IWL_ERROR("Error adding AP address for transmit.\n");
+ 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_ERROR("Error setting HW rate table: %02X\n", rc);
+ IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
return -EIO;
}
return 0;
}
-static int iwl3945_send_bt_config(struct iwl3945_priv *priv)
+static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
- struct iwl3945_bt_cmd bt_cmd = {
- .flags = 3,
- .lead_time = 0xAA,
- .max_kill = 1,
- .kill_ack_mask = 0,
- .kill_cts_mask = 0,
- };
+ unsigned long flags;
+ __le16 key_flags = 0;
+ int ret;
- return iwl3945_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(struct iwl3945_bt_cmd), &bt_cmd);
-}
+ key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
+ key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-static int iwl3945_send_scan_abort(struct iwl3945_priv *priv)
-{
- int rc = 0;
- struct iwl3945_rx_packet *res;
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_SCAN_ABORT_CMD,
- .meta.flags = CMD_WANT_SKB,
- };
+ if (sta_id == priv->hw_params.bcast_sta_id)
+ key_flags |= STA_KEY_MULTICAST_MSK;
- /* If there isn't a scan actively going on in the hardware
- * then we are in between scan bands and not actually
- * actively scanning, so don't send the abort command */
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return 0;
- }
+ keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ keyconf->hw_key_idx = keyconf->keyidx;
+ key_flags &= ~STA_KEY_FLG_INVALID;
- rc = iwl3945_send_cmd_sync(priv, &cmd);
- if (rc) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return rc;
- }
+ 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,
+ keyconf->keylen);
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
- if (res->u.status != CAN_ABORT_STATUS) {
- /* The scan abort will return 1 for success or
- * 2 for "failure". A failure condition can be
- * due to simply not being in an active scan which
- * can occur if we send the scan abort before we
- * the microcode has notified us that a scan is
- * completed. */
- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- clear_bit(STATUS_SCAN_HW, &priv->status);
- }
+ memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
+ keyconf->keylen);
- dev_kfree_skb_any(cmd.meta.u.skb);
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
+ iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
- return rc;
-}
+ WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+ "no space for a new key");
-static int iwl3945_card_state_sync_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
- struct sk_buff *skb)
-{
- return 1;
-}
+ 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;
-/*
- * CARD_STATE_CMD
- *
- * Use: Sets the device's internal card state to enable, disable, or halt
- *
- * When in the 'enable' state the card operates as normal.
- * When in the 'disable' state, the card enters into a low power mode.
- * When in the 'halt' state, the card is shut down and must be fully
- * restarted to come back on.
- */
-static int iwl3945_send_card_state(struct iwl3945_priv *priv, u32 flags, u8 meta_flag)
-{
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_CARD_STATE_CMD,
- .len = sizeof(u32),
- .data = &flags,
- .meta.flags = meta_flag,
- };
+ IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
- if (meta_flag & CMD_ASYNC)
- cmd.meta.u.callback = iwl3945_card_state_sync_callback;
+ ret = iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
- return iwl3945_send_cmd(priv, &cmd);
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return ret;
}
-static int iwl3945_add_sta_sync_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd, struct sk_buff *skb)
+static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
- struct iwl3945_rx_packet *res = NULL;
-
- if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
- return 1;
- }
-
- res = (struct iwl3945_rx_packet *)skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- return 1;
- }
-
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- break;
- default:
- break;
- }
-
- /* We didn't cache the SKB; let the caller free it */
- return 1;
+ return -EOPNOTSUPP;
}
-int iwl3945_send_add_station(struct iwl3945_priv *priv,
- struct iwl3945_addsta_cmd *sta, u8 flags)
+static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
- struct iwl3945_rx_packet *res = NULL;
- int rc = 0;
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_ADD_STA,
- .len = sizeof(struct iwl3945_addsta_cmd),
- .meta.flags = flags,
- .data = sta,
- };
-
- if (flags & CMD_ASYNC)
- cmd.meta.u.callback = iwl3945_add_sta_sync_callback;
- else
- cmd.meta.flags |= CMD_WANT_SKB;
-
- rc = iwl3945_send_cmd(priv, &cmd);
-
- if (rc || (flags & CMD_ASYNC))
- return rc;
-
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- rc = -EIO;
- }
+ return -EOPNOTSUPP;
+}
- if (rc == 0) {
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
- break;
- default:
- rc = -EIO;
- IWL_WARNING("REPLY_ADD_STA failed\n");
- break;
- }
- }
+static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
+{
+ unsigned long flags;
- priv->alloc_rxb_skb--;
- dev_kfree_skb_any(cmd.meta.u.skb);
+ 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,
+ 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;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
- return rc;
+ 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);
+ return 0;
}
-static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
+static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf, u8 sta_id)
{
- unsigned long flags;
- __le16 key_flags = 0;
+ int ret = 0;
+
+ keyconf->hw_key_idx = HW_KEY_DYNAMIC;
switch (keyconf->alg) {
case ALG_CCMP:
- key_flags |= STA_KEY_FLG_CCMP;
- key_flags |= cpu_to_le16(
- keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- key_flags &= ~STA_KEY_FLG_INVALID;
+ ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
break;
case ALG_TKIP:
+ ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
+ break;
case ALG_WEP:
+ ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id);
+ break;
default:
- return -EINVAL;
+ IWL_ERR(priv,"Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ ret = -EINVAL;
}
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
- memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
- keyconf->keylen);
- memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
- keyconf->keylen);
- 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;
-
- spin_unlock_irqrestore(&priv->sta_lock, flags);
+ IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->alg, keyconf->keylen, keyconf->keyidx,
+ sta_id, ret);
- IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
- iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
- return 0;
+ return ret;
}
-static int iwl3945_clear_sta_key_info(struct iwl3945_priv *priv, u8 sta_id)
+static int iwl3945_remove_static_key(struct iwl_priv *priv)
{
- unsigned long flags;
+ int ret = -EOPNOTSUPP;
- spin_lock_irqsave(&priv->sta_lock, flags);
- memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
- memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl3945_keyinfo));
- priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return ret;
+}
- IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
- iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
- return 0;
+static int iwl3945_set_static_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *key)
+{
+ if (key->alg == ALG_WEP)
+ return -EOPNOTSUPP;
+
+ IWL_ERR(priv, "Static key invalid: alg %d\n", key->alg);
+ return -EINVAL;
}
-static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
+static void iwl3945_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
- IWL_DEBUG_INFO("%d frames on pre-allocated heap on clear.\n",
+ IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
priv->frames_count);
while (!list_empty(&priv->free_frames)) {
@@ -1368,20 +603,20 @@ static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
}
if (priv->frames_count) {
- IWL_WARNING("%d frames still in use. Did we lose one?\n",
+ IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
priv->frames_count);
priv->frames_count = 0;
}
}
-static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
+static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv)
{
struct iwl3945_frame *frame;
struct list_head *element;
if (list_empty(&priv->free_frames)) {
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame) {
- IWL_ERROR("Could not allocate frame!\n");
+ IWL_ERR(priv, "Could not allocate frame!\n");
return NULL;
}
@@ -1394,18 +629,18 @@ static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
return list_entry(element, struct iwl3945_frame, list);
}
-static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *frame)
+static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame)
{
memset(frame, 0, sizeof(*frame));
list_add(&frame->list, &priv->free_frames);
}
-unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
int left)
{
- if (!iwl3945_is_associated(priv) || !priv->ibss_beacon ||
+ if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
(priv->iw_mode != NL80211_IFTYPE_AP)))
return 0;
@@ -1418,31 +653,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
return priv->ibss_beacon->len;
}
-static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
-{
- u8 i;
- int rate_mask;
-
- /* Set rate mask*/
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
- rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
- else
- rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
-
- for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
- i = iwl3945_rates[i].next_ieee) {
- if (rate_mask & (1 << i))
- return iwl3945_rates[i].plcp;
- }
-
- /* No valid rate was found. Assign the lowest one */
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
- return IWL_RATE_1M_PLCP;
- else
- return IWL_RATE_6M_PLCP;
-}
-
-static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
+static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
{
struct iwl3945_frame *frame;
unsigned int frame_size;
@@ -1452,16 +663,16 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
frame = iwl3945_get_free_frame(priv);
if (!frame) {
- IWL_ERROR("Could not obtain free frame buffer for beacon "
+ IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
"command.\n");
return -ENOMEM;
}
- rate = iwl3945_rate_get_lowest_plcp(priv);
+ rate = iwl_rate_get_lowest_plcp(priv);
frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
+ rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
&frame->u.cmd[0]);
iwl3945_free_frame(priv, frame);
@@ -1469,566 +680,17 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
return rc;
}
-/******************************************************************************
- *
- * EEPROM related functions
- *
- ******************************************************************************/
-
-static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
-{
- memcpy(mac, priv->eeprom.mac_address, 6);
-}
-
-/*
- * Clear the OWNER_MSK, to establish driver (instead of uCode running on
- * embedded controller) as EEPROM reader; each read is a series of pulses
- * to/from the EEPROM chip, not a single event, so even reads could conflict
- * if they weren't arbitrated by some ownership mechanism. Here, the driver
- * simply claims ownership, which should be safe when this function is called
- * (i.e. before loading uCode!).
- */
-static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
-{
- _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
- return 0;
-}
-
-/**
- * iwl3945_eeprom_init - read EEPROM contents
- *
- * Load the EEPROM contents from adapter into priv->eeprom
- *
- * NOTE: This routine uses the non-debug IO access functions.
- */
-int iwl3945_eeprom_init(struct iwl3945_priv *priv)
-{
- u16 *e = (u16 *)&priv->eeprom;
- u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
- int sz = sizeof(priv->eeprom);
- int ret;
- u16 addr;
-
- /* The EEPROM structure has several padding buffers within it
- * and when adding new EEPROM maps is subject to programmer errors
- * which may be very difficult to identify without explicitly
- * checking the resulting size of the eeprom map. */
- BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
-
- if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
- return -ENOENT;
- }
-
- /* Make sure driver (instead of uCode) is allowed to read EEPROM */
- ret = iwl3945_eeprom_acquire_semaphore(priv);
- if (ret < 0) {
- IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
- return -ENOENT;
- }
-
- /* eeprom is an array of 16bit values */
- for (addr = 0; addr < sz; addr += sizeof(u16)) {
- u32 r;
-
- _iwl3945_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
- _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
- ret = iwl3945_poll_direct_bit(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_READ_VALID_MSK,
- IWL_EEPROM_ACCESS_TIMEOUT);
- if (ret < 0) {
- IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
- return ret;
- }
-
- r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
- e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
- }
-
- return 0;
-}
-
-static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv)
+static void iwl3945_unset_hw_params(struct iwl_priv *priv)
{
- if (priv->hw_setting.shared_virt)
+ if (priv->shared_virt)
pci_free_consistent(priv->pci_dev,
sizeof(struct iwl3945_shared),
- priv->hw_setting.shared_virt,
- priv->hw_setting.shared_phys);
-}
-
-/**
- * iwl3945_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl3945_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] = iwl3945_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- (*cnt)++;
- (*left)--;
- if ((*left <= 0) ||
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
- break;
- }
- }
-
- return ret_rates;
-}
-
-/**
- * iwl3945_fill_probe_req - fill in all required fields and IE for probe request
- */
-static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
- struct ieee80211_mgmt *frame,
- int left)
-{
- int len = 0;
- u8 *pos = NULL;
- u16 active_rates, ret_rates, cck_rates;
-
- /* Make sure there is enough space for the probe request,
- * two mandatory IEs and the data */
- left -= 24;
- if (left < 0)
- return 0;
- len += 24;
-
- frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- memcpy(frame->da, iwl3945_broadcast_addr, ETH_ALEN);
- memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
- memcpy(frame->bssid, iwl3945_broadcast_addr, ETH_ALEN);
- frame->seq_ctrl = 0;
-
- /* fill in our indirect SSID IE */
- /* ...next IE... */
-
- left -= 2;
- if (left < 0)
- return 0;
- len += 2;
- pos = &(frame->u.probe_req.variable[0]);
- *pos++ = WLAN_EID_SSID;
- *pos++ = 0;
-
- /* fill in supported rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
-
- /* ... fill it in... */
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos = 0;
-
- priv->active_rate = priv->rates_mask;
- active_rates = priv->active_rate;
- priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
-
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
- ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates,
- priv->active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates,
- priv->active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- len += 2 + *pos;
- pos += (*pos) + 1;
- 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;
- iwl3945_supported_rate_to_ie(pos, active_rates,
- priv->active_rate_basic, &left);
- if (*pos > 0)
- len += 2 + *pos;
-
- fill_end:
- return (u16)len;
-}
-
-/*
- * QoS support
-*/
-static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv,
- struct iwl3945_qosparam_cmd *qos)
-{
-
- return iwl3945_send_cmd_pdu(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl3945_qosparam_cmd), qos);
-}
-
-static void iwl3945_reset_qos(struct iwl3945_priv *priv)
-{
- u16 cw_min = 15;
- u16 cw_max = 1023;
- u8 aifs = 2;
- u8 is_legacy = 0;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.qos_active = 0;
-
- /* QoS always active in AP and ADHOC mode
- * In STA mode wait for association
- */
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
- priv->iw_mode == NL80211_IFTYPE_AP)
- priv->qos_data.qos_active = 1;
- else
- priv->qos_data.qos_active = 0;
-
-
- /* check for legacy mode */
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
- (priv->iw_mode == NL80211_IFTYPE_STATION &&
- (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
- cw_min = 31;
- is_legacy = 1;
- }
-
- if (priv->qos_data.qos_active)
- aifs = 3;
-
- 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;
- priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
-
- if (priv->qos_data.qos_active) {
- 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);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
- priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-
- 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);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
- if (is_legacy)
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(6016);
- else
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(3008);
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-
- 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);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
- if (is_legacy)
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(3264);
- else
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(1504);
- } else {
- for (i = 1; i < 4; i++) {
- 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);
- priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
- priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
- }
- }
- IWL_DEBUG_QOS("set QoS to default \n");
-
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
-{
- unsigned long flags;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.def_qos_parm.qos_flags = 0;
-
- if (priv->qos_data.qos_cap.q_AP.queue_request &&
- !priv->qos_data.qos_cap.q_AP.txop_request)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_TXOP_TYPE_MSK;
-
- if (priv->qos_data.qos_active)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (force || iwl3945_is_associated(priv)) {
- IWL_DEBUG_QOS("send QoS cmd with QoS active %d \n",
- priv->qos_data.qos_active);
-
- iwl3945_send_qos_params_command(priv,
- &(priv->qos_data.def_qos_parm));
- }
-}
-
-/*
- * Power management (not Tx power!) functions
- */
-#define MSEC_TO_USEC 1024
-
-#define NOSLP __constant_cpu_to_le32(0)
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK
-#define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
- __constant_cpu_to_le32(X1), \
- __constant_cpu_to_le32(X2), \
- __constant_cpu_to_le32(X3), \
- __constant_cpu_to_le32(X4)}
-
-
-/* default power management (not Tx power) table values */
-/* for TIM 0-10 */
-static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
- {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},
- {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
-};
-
-/* for TIM > 10 */
-static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = {
- {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
- SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300),
- SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100),
- SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25),
- SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
-};
-
-int iwl3945_power_init_handle(struct iwl3945_priv *priv)
-{
- int rc = 0, i;
- struct iwl3945_power_mgr *pow_data;
- int size = sizeof(struct iwl3945_power_vec_entry) * IWL_POWER_AC;
- u16 pci_pm;
-
- IWL_DEBUG_POWER("Initialize power \n");
-
- pow_data = &(priv->power_data);
-
- memset(pow_data, 0, sizeof(*pow_data));
-
- pow_data->active_index = IWL_POWER_RANGE_0;
- pow_data->dtim_val = 0xffff;
-
- memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
- memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
-
- rc = pci_read_config_word(priv->pci_dev, PCI_LINK_CTRL, &pci_pm);
- if (rc != 0)
- return 0;
- else {
- struct iwl3945_powertable_cmd *cmd;
-
- IWL_DEBUG_POWER("adjust power command flags\n");
-
- for (i = 0; i < IWL_POWER_AC; i++) {
- cmd = &pow_data->pwr_range_0[i].cmd;
-
- if (pci_pm & 0x1)
- cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
- else
- cmd->flags |= IWL_POWER_PCI_PM_MSK;
- }
- }
- return rc;
-}
-
-static int iwl3945_update_power_cmd(struct iwl3945_priv *priv,
- struct iwl3945_powertable_cmd *cmd, u32 mode)
-{
- int rc = 0, i;
- u8 skip;
- u32 max_sleep = 0;
- struct iwl3945_power_vec_entry *range;
- u8 period = 0;
- struct iwl3945_power_mgr *pow_data;
-
- if (mode > IWL_POWER_INDEX_5) {
- IWL_DEBUG_POWER("Error invalid power mode \n");
- return -1;
- }
- pow_data = &(priv->power_data);
-
- if (pow_data->active_index == IWL_POWER_RANGE_0)
- range = &pow_data->pwr_range_0[0];
- else
- range = &pow_data->pwr_range_1[1];
-
- memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd));
-
-#ifdef IWL_MAC80211_DISABLE
- if (priv->assoc_network != NULL) {
- unsigned long flags;
-
- period = priv->assoc_network->tim.tim_period;
- }
-#endif /*IWL_MAC80211_DISABLE */
- skip = range[mode].no_dtim;
-
- if (period == 0) {
- period = 1;
- skip = 0;
- }
-
- if (skip == 0) {
- max_sleep = period;
- cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
- } else {
- __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
- max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
- cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
- }
-
- for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
- if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
- cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
- }
-
- IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
- IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
- IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
- IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
- le32_to_cpu(cmd->sleep_interval[0]),
- le32_to_cpu(cmd->sleep_interval[1]),
- le32_to_cpu(cmd->sleep_interval[2]),
- le32_to_cpu(cmd->sleep_interval[3]),
- le32_to_cpu(cmd->sleep_interval[4]));
-
- return rc;
-}
-
-static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
-{
- u32 uninitialized_var(final_mode);
- int rc;
- struct iwl3945_powertable_cmd cmd;
-
- /* If on battery, set to 3,
- * if plugged into AC power, set to CAM ("continuously aware mode"),
- * else user level */
- switch (mode) {
- case IWL_POWER_BATTERY:
- final_mode = IWL_POWER_INDEX_3;
- break;
- case IWL_POWER_AC:
- final_mode = IWL_POWER_MODE_CAM;
- break;
- default:
- final_mode = mode;
- break;
- }
-
- iwl3945_update_power_cmd(priv, &cmd, final_mode);
-
- rc = iwl3945_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
-
- if (final_mode == IWL_POWER_MODE_CAM)
- clear_bit(STATUS_POWER_PMI, &priv->status);
- else
- set_bit(STATUS_POWER_PMI, &priv->status);
-
- return rc;
-}
-
-/**
- * iwl3945_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-static int iwl3945_scan_cancel(struct iwl3945_priv *priv)
-{
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCANNING, &priv->status);
- return 0;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Queuing scan abort.\n");
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- queue_work(priv->workqueue, &priv->abort_scan);
-
- } else
- IWL_DEBUG_SCAN("Scan abort already in progress.\n");
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return 0;
-}
-
-/**
- * iwl3945_scan_cancel_timeout - Cancel any currently executing HW scan
- * @ms: amount of time to wait (in milliseconds) for scan to abort
- *
- * NOTE: priv->mutex must be held before calling this function
- */
-static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long ms)
-{
- unsigned long now = jiffies;
- int ret;
-
- ret = iwl3945_scan_cancel(priv);
- if (ret && ms) {
- mutex_unlock(&priv->mutex);
- while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
- test_bit(STATUS_SCANNING, &priv->status))
- msleep(1);
- mutex_lock(&priv->mutex);
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return ret;
+ priv->shared_virt,
+ priv->shared_phys);
}
#define MAX_UCODE_BEACON_INTERVAL 1024
-#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
+#define INTEL_CONN_LISTEN_INTERVAL cpu_to_le16(0xA)
static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
{
@@ -2043,7 +705,7 @@ static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
return cpu_to_le16(new_val);
}
-static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
+static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
{
u64 interval_tm_unit;
u64 tsf, result;
@@ -2054,13 +716,10 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
conf = ieee80211_get_hw_conf(priv->hw);
spin_lock_irqsave(&priv->lock, flags);
- priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1);
- priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0);
-
+ priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
- tsf = priv->timestamp1;
- tsf = ((tsf << 32) | priv->timestamp0);
+ tsf = priv->timestamp;
beacon_int = priv->beacon_int;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -2092,183 +751,41 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
priv->rxon_timing.beacon_init_val =
cpu_to_le32((u32) ((u64) interval_tm_unit - result));
- IWL_DEBUG_ASSOC
- ("beacon interval %d beacon timer %d beacon tim %d\n",
+ IWL_DEBUG_ASSOC(priv,
+ "beacon interval %d beacon timer %d beacon tim %d\n",
le16_to_cpu(priv->rxon_timing.beacon_interval),
le32_to_cpu(priv->rxon_timing.beacon_init_val),
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
-{
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
- return -EIO;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan already in progress.\n");
- return -EAGAIN;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan request while abort pending. "
- "Queuing.\n");
- return -EAGAIN;
- }
-
- IWL_DEBUG_INFO("Starting scan...\n");
- if (priv->cfg->sku & IWL_SKU_G)
- priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
- if (priv->cfg->sku & IWL_SKU_A)
- priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
- set_bit(STATUS_SCANNING, &priv->status);
- priv->scan_start = jiffies;
- priv->scan_pass_start = priv->scan_start;
-
- queue_work(priv->workqueue, &priv->request_scan);
-
- return 0;
-}
-
-static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt)
-{
- struct iwl3945_rxon_cmd *rxon = &priv->staging_rxon;
-
- if (hw_decrypt)
- rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
- else
- rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
-
- return 0;
-}
-
-static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
- enum ieee80211_band band)
-{
- if (band == IEEE80211_BAND_5GHZ) {
- priv->staging_rxon.flags &=
- ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
- | RXON_FLG_CCK_MSK);
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
- } else {
- /* Copied from iwl3945_bg_post_associate() */
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
- priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
- priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
- }
-}
-
-/*
- * initialize rxon structure with default values from eeprom
- */
-static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
- int mode)
-{
- const struct iwl3945_channel_info *ch_info;
-
- memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
-
- switch (mode) {
- case NL80211_IFTYPE_AP:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
- break;
-
- case NL80211_IFTYPE_STATION:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
- priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
- break;
-
- case NL80211_IFTYPE_ADHOC:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
- priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
- priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
- 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_ERROR("Unsupported interface type %d\n", mode);
- break;
- }
-
-#if 0
- /* TODO: Figure out when short_preamble would be set and cache from
- * that */
- if (!hw_to_local(priv->hw)->short_preamble)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
-#endif
-
- ch_info = iwl3945_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->active_rxon.channel));
-
- if (!ch_info)
- ch_info = &priv->channel_info[0];
-
- /*
- * in some case A channels are all non IBSS
- * in this case force B/G channel
- */
- if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info)))
- ch_info = &priv->channel_info[0];
-
- priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
- if (is_channel_a_band(ch_info))
- priv->band = IEEE80211_BAND_5GHZ;
- else
- priv->band = IEEE80211_BAND_2GHZ;
-
- iwl3945_set_flags_for_phymode(priv, priv->band);
-
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-}
-
-static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
+static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
{
if (mode == NL80211_IFTYPE_ADHOC) {
- const struct iwl3945_channel_info *ch_info;
+ const struct iwl_channel_info *ch_info;
- ch_info = iwl3945_get_channel_info(priv,
+ 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_ERROR("channel %d not IBSS channel\n",
+ IWL_ERR(priv, "channel %d not IBSS channel\n",
le16_to_cpu(priv->staging_rxon.channel));
return -EINVAL;
}
}
- iwl3945_connection_init_rx_config(priv, mode);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+ iwl_connection_init_rx_config(priv, mode);
iwl3945_clear_stations_table(priv);
/* don't commit rxon if rf-kill is on*/
- if (!iwl3945_is_ready_rf(priv))
+ if (!iwl_is_ready_rf(priv))
return -EAGAIN;
cancel_delayed_work(&priv->scan_check);
- if (iwl3945_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+ 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");
return -EAGAIN;
}
@@ -2277,49 +794,41 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
return 0;
}
-static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
+static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
- struct iwl3945_cmd *cmd,
+ struct iwl_cmd *cmd,
struct sk_buff *skb_frag,
- int last_frag)
+ int sta_id)
{
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
struct iwl3945_hw_key *keyinfo =
- &priv->stations[info->control.hw_key->hw_key_idx].keyinfo;
+ &priv->stations_39[sta_id].keyinfo;
switch (keyinfo->alg) {
case ALG_CCMP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
- memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
- IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
+ tx->sec_ctl = TX_CMD_SEC_CCM;
+ memcpy(tx->key, keyinfo->key, keyinfo->keylen);
+ IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;
case ALG_TKIP:
-#if 0
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP;
-
- if (last_frag)
- memcpy(cmd->cmd.tx.tkip_mic.byte, skb_frag->tail - 8,
- 8);
- else
- memset(cmd->cmd.tx.tkip_mic.byte, 0, 8);
-#endif
break;
case ALG_WEP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
+ tx->sec_ctl = TX_CMD_SEC_WEP |
(info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
if (keyinfo->keylen == 13)
- cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
+ tx->sec_ctl |= TX_CMD_SEC_KEY128;
- memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
+ memcpy(&tx->key[3], keyinfo->key, keyinfo->keylen);
- IWL_DEBUG_TX("Configuring packet for WEP encryption "
+ IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
"with key %d\n", info->control.hw_key->hw_key_idx);
break;
default:
- printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg);
+ IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg);
break;
}
}
@@ -2327,17 +836,17 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
/*
* handle build REPLY_TX command notification.
*/
-static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
+ struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
- struct ieee80211_hdr *hdr,
- int is_unicast, u8 std_id)
+ struct ieee80211_hdr *hdr, u8 std_id)
{
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
+ __le32 tx_flags = tx->tx_flags;
__le16 fc = hdr->frame_control;
- __le32 tx_flags = cmd->cmd.tx.tx_flags;
u8 rc_flags = info->control.rates[0].flags;
- cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+ tx->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
tx_flags |= TX_CMD_FLG_ACK_MSK;
if (ieee80211_is_mgmt(fc))
@@ -2350,13 +859,13 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
}
- cmd->cmd.tx.sta_id = std_id;
+ tx->sta_id = std_id;
if (ieee80211_has_morefrags(fc))
tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
if (ieee80211_is_data_qos(fc)) {
u8 *qc = ieee80211_get_qos_ctl(hdr);
- cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
+ tx->tid_tspec = qc[0] & 0xf;
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
} else {
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
@@ -2376,25 +885,25 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
if (ieee80211_is_mgmt(fc)) {
if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
- cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
+ tx->timeout.pm_frame_timeout = cpu_to_le16(3);
else
- cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
+ tx->timeout.pm_frame_timeout = cpu_to_le16(2);
} else {
- cmd->cmd.tx.timeout.pm_frame_timeout = 0;
-#ifdef CONFIG_IWL3945_LEDS
+ tx->timeout.pm_frame_timeout = 0;
+#ifdef CONFIG_IWLWIFI_LEDS
priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
#endif
}
- cmd->cmd.tx.driver_txop = 0;
- cmd->cmd.tx.tx_flags = tx_flags;
- cmd->cmd.tx.next_frame_len = 0;
+ tx->driver_txop = 0;
+ tx->tx_flags = tx_flags;
+ tx->next_frame_len = 0;
}
/**
* iwl3945_get_sta_id - Find station's index within station table
*/
-static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr)
+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);
@@ -2402,7 +911,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
/* If this frame is broadcast or management, use broadcast station id */
if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
is_multicast_ether_addr(hdr->addr1))
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
switch (priv->iw_mode) {
@@ -2416,7 +925,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
if (sta_id != IWL_INVALID_STATION)
return sta_id;
- return priv->hw_setting.bcast_sta_id;
+ 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 */
@@ -2431,38 +940,38 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
if (sta_id != IWL_INVALID_STATION)
return sta_id;
- IWL_DEBUG_DROP("Station %pM not in station map. "
+ IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
"Defaulting to broadcast...\n",
hdr->addr1);
- iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
- return priv->hw_setting.bcast_sta_id;
+ 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_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
default:
- IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
- return priv->hw_setting.bcast_sta_id;
+ IWL_WARN(priv, "Unknown mode of operation: %d\n",
+ priv->iw_mode);
+ return priv->hw_params.bcast_sta_id;
}
}
/*
* start REPLY_TX command process
*/
-static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
+static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl3945_tfd_frame *tfd;
- u32 *control_flags;
- int txq_id = skb_get_queue_mapping(skb);
- struct iwl3945_tx_queue *txq = NULL;
- struct iwl3945_queue *q = NULL;
+ struct iwl3945_tx_cmd *tx;
+ struct iwl_tx_queue *txq = NULL;
+ struct iwl_queue *q = NULL;
+ struct iwl_cmd *out_cmd = NULL;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
- struct iwl3945_cmd *out_cmd = NULL;
+ int txq_id = skb_get_queue_mapping(skb);
u16 len, idx, len_org, hdr_len;
u8 id;
u8 unicast;
@@ -2476,13 +985,13 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
int rc;
spin_lock_irqsave(&priv->lock, flags);
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_DROP("Dropping - RF KILL\n");
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
goto drop_unlock;
}
if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) {
- IWL_ERROR("ERROR: No TX rate available.\n");
+ IWL_ERR(priv, "ERROR: No TX rate available.\n");
goto drop_unlock;
}
@@ -2491,21 +1000,21 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
fc = hdr->frame_control;
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
if (ieee80211_is_auth(fc))
- IWL_DEBUG_TX("Sending AUTH frame\n");
+ IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
else if (ieee80211_is_assoc_req(fc))
- IWL_DEBUG_TX("Sending ASSOC frame\n");
+ IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
else if (ieee80211_is_reassoc_req(fc))
- IWL_DEBUG_TX("Sending REASSOC frame\n");
+ IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
#endif
/* drop all data frame if we are not associated */
if (ieee80211_is_data(fc) &&
(priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */
- (!iwl3945_is_associated(priv) ||
+ (!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
- IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
+ IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
goto drop_unlock;
}
@@ -2516,21 +1025,21 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
/* Find (or create) index into station table for destination station */
sta_id = iwl3945_get_sta_id(priv, hdr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+ IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
goto drop;
}
- IWL_DEBUG_RATE("station Id %d\n", sta_id);
+ IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id);
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
- seq_number = priv->stations[sta_id].tid[tid].seq_number &
+ seq_number = priv->stations_39[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = cpu_to_le16(seq_number) |
(hdr->seq_ctrl &
- __constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
+ cpu_to_le16(IEEE80211_SCTL_FRAG));
seq_number += 0x10;
}
@@ -2540,20 +1049,17 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
- /* Set up first empty TFD within this queue's circular TFD buffer */
- tfd = &txq->bd[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
- control_flags = (u32 *) tfd;
idx = get_cmd_index(q, q->write_ptr, 0);
/* Set up driver data for this TFD */
- memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info));
+ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb[0] = skb;
/* Init first empty entry in queue's array of Tx/cmd buffers */
- out_cmd = &txq->cmd[idx];
+ out_cmd = txq->cmd[idx];
+ tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
- memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
+ memset(tx, 0, sizeof(*tx));
/*
* Set up the Tx-command (not MAC!) header.
@@ -2566,7 +1072,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
INDEX_TO_SEQ(q->write_ptr)));
/* Copy MAC header from skb into command buffer */
- memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len);
+ memcpy(tx->hdr, hdr, hdr_len);
/*
* Use the first empty entry in this queue's command buffer array
@@ -2577,8 +1083,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
* of the MAC header (device reads on dword boundaries).
* We'll tell device about this padding later.
*/
- len = priv->hw_setting.tx_cmd_len +
- sizeof(struct iwl3945_cmd_header) + hdr_len;
+ len = sizeof(struct iwl3945_tx_cmd) +
+ sizeof(struct iwl_cmd_header) + hdr_len;
len_org = len;
len = (len + 3) & ~3;
@@ -2590,15 +1096,22 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
- txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx +
- offsetof(struct iwl3945_cmd, hdr);
+ txcmd_phys = pci_map_single(priv->pci_dev,
+ out_cmd, sizeof(struct iwl_cmd),
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
+ pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
+ /* Add buffer containing Tx command and MAC(!) header to TFD's
+ * first entry */
+ txcmd_phys += offsetof(struct iwl_cmd, hdr);
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ txcmd_phys, len, 1, 0);
if (info->control.hw_key)
- iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
+ iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
@@ -2606,60 +1119,52 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
if (len) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
len, PCI_DMA_TODEVICE);
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, len,
+ 0, U32_PAD(len));
}
- if (!len)
- /* If there is no payload, then we use only one Tx buffer */
- *control_flags = TFD_CTL_COUNT_SET(1);
- else
- /* Else use 2 buffers.
- * Tell 3945 about any padding after MAC header */
- *control_flags = TFD_CTL_COUNT_SET(2) |
- TFD_CTL_PAD_SET(U32_PAD(len));
-
/* Total # bytes to be transmitted */
len = (u16)skb->len;
- out_cmd->cmd.tx.len = cpu_to_le16(len);
+ tx->len = cpu_to_le16(len);
/* TODO need this for burst mode later on */
- iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, unicast, sta_id);
+ iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
/* set is_hcca to 0; it probably will never be implemented */
iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
- out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
- out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
+ tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
+ tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
if (qc)
- priv->stations[sta_id].tid[tid].seq_number = seq_number;
+ priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
} else {
wait_write_ptr = 1;
txq->need_update = 0;
}
- iwl3945_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
- sizeof(out_cmd->cmd.tx));
+ iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
- iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
+ iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
ieee80211_hdrlen(fc));
/* Tell device the write index *just past* this latest filled TFD */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- rc = iwl3945_tx_queue_update_write_ptr(priv, txq);
+ rc = iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
if (rc)
return rc;
- if ((iwl3945_queue_space(q) < q->high_mark)
+ if ((iwl_queue_space(q) < q->high_mark)
&& priv->mac80211_registered) {
if (wait_write_ptr) {
spin_lock_irqsave(&priv->lock, flags);
txq->need_update = 1;
- iwl3945_tx_queue_update_write_ptr(priv, txq);
+ iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -2674,142 +1179,6 @@ drop:
return -1;
}
-static void iwl3945_set_rate(struct iwl3945_priv *priv)
-{
- const struct ieee80211_supported_band *sband = NULL;
- struct ieee80211_rate *rate;
- int i;
-
- sband = iwl3945_get_band(priv, priv->band);
- if (!sband) {
- IWL_ERROR("Failed to set rate: unable to get hw mode\n");
- return;
- }
-
- priv->active_rate = 0;
- priv->active_rate_basic = 0;
-
- IWL_DEBUG_RATE("Setting rates for %s GHz\n",
- sband->band == IEEE80211_BAND_2GHZ ? "2.4" : "5");
-
- for (i = 0; i < sband->n_bitrates; i++) {
- rate = &sband->bitrates[i];
- if ((rate->hw_value < IWL_RATE_COUNT) &&
- !(rate->flags & IEEE80211_CHAN_DISABLED)) {
- IWL_DEBUG_RATE("Adding rate index %d (plcp %d)\n",
- rate->hw_value, iwl3945_rates[rate->hw_value].plcp);
- priv->active_rate |= (1 << rate->hw_value);
- }
- }
-
- IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
- priv->active_rate, priv->active_rate_basic);
-
- /*
- * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
- * otherwise set it to the default of all CCK rates and 6, 12, 24 for
- * OFDM
- */
- if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
- priv->staging_rxon.cck_basic_rates =
- ((priv->active_rate_basic &
- IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
- else
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-
- if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
- priv->staging_rxon.ofdm_basic_rates =
- ((priv->active_rate_basic &
- (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
- IWL_FIRST_OFDM_RATE) & 0xFF;
- else
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
-}
-
-static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
-{
- unsigned long flags;
-
- if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))
- return;
-
- IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",
- disable_radio ? "OFF" : "ON");
-
- if (disable_radio) {
- iwl3945_scan_cancel(priv);
- /* FIXME: This is a workaround for AP */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
- CSR_UCODE_SW_BIT_RFKILL);
- spin_unlock_irqrestore(&priv->lock, flags);
- iwl3945_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- }
- return;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
- clear_bit(STATUS_RF_KILL_SW, &priv->status);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* wake up ucode */
- msleep(10);
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
- if (!iwl3945_grab_nic_access(priv))
- iwl3945_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by HW switch\n");
- return;
- }
-
- if (priv->is_open)
- queue_work(priv->workqueue, &priv->restart);
- return;
-}
-
-void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
- u32 decrypt_res, struct ieee80211_rx_status *stats)
-{
- u16 fc =
- le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control);
-
- if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
- return;
-
- if (!(fc & IEEE80211_FCTL_PROTECTED))
- return;
-
- IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
- switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
- case RX_RES_STATUS_SEC_TYPE_TKIP:
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_BAD_ICV_MIC)
- stats->flag |= RX_FLAG_MMIC_ERROR;
- case RX_RES_STATUS_SEC_TYPE_WEP:
- case RX_RES_STATUS_SEC_TYPE_CCMP:
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_DECRYPT_OK) {
- IWL_DEBUG_RX("hw decrypt successfully!!!\n");
- stats->flag |= RX_FLAG_DECRYPTED;
- }
- break;
-
- default:
- break;
- }
-}
-
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
#include "iwl-spectrum.h"
@@ -2863,13 +1232,13 @@ static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
return cpu_to_le32(res);
}
-static int iwl3945_get_measurement(struct iwl3945_priv *priv,
+static int iwl3945_get_measurement(struct iwl_priv *priv,
struct ieee80211_measurement_params *params,
u8 type)
{
- struct iwl3945_spectrum_cmd spectrum;
- struct iwl3945_rx_packet *res;
- struct iwl3945_host_cmd cmd = {
+ struct iwl_spectrum_cmd spectrum;
+ struct iwl_rx_packet *res;
+ struct iwl_host_cmd cmd = {
.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
.data = (void *)&spectrum,
.meta.flags = CMD_WANT_SKB,
@@ -2879,7 +1248,7 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
int spectrum_resp_status;
int duration = le16_to_cpu(params->duration);
- if (iwl3945_is_associated(priv))
+ if (iwl_is_associated(priv))
add_time =
iwl3945_usecs_to_beacons(
le64_to_cpu(params->start_time) - priv->last_tsf,
@@ -2894,7 +1263,7 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
cmd.len = sizeof(spectrum);
spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
- if (iwl3945_is_associated(priv))
+ if (iwl_is_associated(priv))
spectrum.start_time =
iwl3945_add_beacon_time(priv->last_beacon_time,
add_time,
@@ -2909,13 +1278,13 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
spectrum.flags |= RXON_FLG_BAND_24G_MSK |
RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
return rc;
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
rc = -EIO;
}
@@ -2923,7 +1292,7 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
switch (spectrum_resp_status) {
case 0: /* Command will be handled */
if (res->u.spectrum.id != 0xff) {
- IWL_DEBUG_INFO("Replaced existing measurement: %d\n",
+ IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n",
res->u.spectrum.id);
priv->measurement_status &= ~MEASUREMENT_READY;
}
@@ -2942,30 +1311,29 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
}
#endif
-static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_alive_resp *palive;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_alive_resp *palive;
struct delayed_work *pwork;
palive = &pkt->u.alive_frame;
- IWL_DEBUG_INFO("Alive ucode status 0x%08X revision "
+ IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
"0x%01X 0x%01X\n",
palive->is_valid, palive->ver_type,
palive->ver_subtype);
if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
- IWL_DEBUG_INFO("Initialization Alive received.\n");
- memcpy(&priv->card_alive_init,
- &pkt->u.alive_frame,
- sizeof(struct iwl3945_init_alive_resp));
+ IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
+ memcpy(&priv->card_alive_init, &pkt->u.alive_frame,
+ sizeof(struct iwl_alive_resp));
pwork = &priv->init_alive_start;
} else {
- IWL_DEBUG_INFO("Runtime Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
memcpy(&priv->card_alive, &pkt->u.alive_frame,
- sizeof(struct iwl3945_alive_resp));
+ sizeof(struct iwl_alive_resp));
pwork = &priv->alive_start;
iwl3945_disable_events(priv);
}
@@ -2976,95 +1344,31 @@ static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
queue_delayed_work(priv->workqueue, pwork,
msecs_to_jiffies(5));
else
- IWL_WARNING("uCode did not respond OK.\n");
-}
-
-static void iwl3945_rx_reply_add_sta(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-
- IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
- return;
-}
-
-static void iwl3945_rx_reply_error(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-
- IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
- "seq 0x%04X ser 0x%08X\n",
- 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));
-}
-
-#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-
-static void iwl3945_rx_csa(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_rxon_cmd *rxon = (void *)&priv->active_rxon;
- struct iwl3945_csa_notification *csa = &(pkt->u.csa_notif);
- IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
- le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
- rxon->channel = csa->channel;
- priv->staging_rxon.channel = csa->channel;
-}
-
-static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_spectrum_notification *report = &(pkt->u.spectrum_notif);
-
- if (!report->state) {
- IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO,
- "Spectrum Measure Notification: Start\n");
- return;
- }
-
- memcpy(&priv->measure_report, report, sizeof(*report));
- priv->measurement_status |= MEASUREMENT_READY;
-#endif
+ IWL_WARN(priv, "uCode did not respond OK.\n");
}
-static void iwl3945_rx_pm_sleep_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_sleep_notification *sleep = &(pkt->u.sleep_notif);
- IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
- sleep->pm_sleep_mode, sleep->pm_wakeup_src);
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
#endif
-}
-static void iwl3945_rx_pm_debug_statistics_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
- "notification for %s:\n",
- le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
- iwl3945_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+ IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
+ return;
}
static void iwl3945_bg_beacon_update(struct work_struct *work)
{
- struct iwl3945_priv *priv =
- container_of(work, struct iwl3945_priv, beacon_update);
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, beacon_update);
struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
beacon = ieee80211_beacon_get(priv->hw, priv->vif);
if (!beacon) {
- IWL_ERROR("update beacon failed\n");
+ IWL_ERR(priv, "update beacon failed\n");
return;
}
@@ -3079,15 +1383,15 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
iwl3945_send_beacon_cmd(priv);
}
-static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
u8 rate = beacon->beacon_notify_hdr.rate;
- IWL_DEBUG_RX("beacon status %x retries %d iss %d "
+ IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
"tsf %d %d rate %d\n",
le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK,
beacon->beacon_notify_hdr.failure_frame,
@@ -3101,137 +1405,20 @@ static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
queue_work(priv->workqueue, &priv->beacon_update);
}
-/* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl3945_rx_reply_scan(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanreq_notification *notif =
- (struct iwl3945_scanreq_notification *)pkt->u.raw;
-
- IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
-#endif
-}
-
-/* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanstart_notification *notif =
- (struct iwl3945_scanstart_notification *)pkt->u.raw;
- priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
- IWL_DEBUG_SCAN("Scan start: "
- "%d [802.11%s] "
- "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
- notif->channel,
- notif->band ? "bg" : "a",
- notif->tsf_high,
- notif->tsf_low, notif->status, notif->beacon_timer);
-}
-
-/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanresults_notification *notif =
- (struct iwl3945_scanresults_notification *)pkt->u.raw;
-
- IWL_DEBUG_SCAN("Scan ch.res: "
- "%d [802.11%s] "
- "(TSF: 0x%08X:%08X) - %d "
- "elapsed=%lu usec (%dms since last)\n",
- notif->channel,
- notif->band ? "bg" : "a",
- le32_to_cpu(notif->tsf_high),
- le32_to_cpu(notif->tsf_low),
- le32_to_cpu(notif->statistics[0]),
- le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
- jiffies_to_msecs(elapsed_jiffies
- (priv->last_scan_jiffies, jiffies)));
-
- priv->last_scan_jiffies = jiffies;
- priv->next_scan_jiffies = 0;
-}
-
-/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
-
- IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
- scan_notif->scanned_channels,
- scan_notif->tsf_low,
- scan_notif->tsf_high, scan_notif->status);
-
- /* The HW is no longer scanning */
- clear_bit(STATUS_SCAN_HW, &priv->status);
-
- /* The scan completion notification came in, so kill that timer... */
- cancel_delayed_work(&priv->scan_check);
-
- IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
- (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
- "2.4" : "5.2",
- jiffies_to_msecs(elapsed_jiffies
- (priv->scan_pass_start, jiffies)));
-
- /* Remove this scanned band from the list of pending
- * bands to scan, band G precedes A in order of scanning
- * as seen in iwl3945_bg_request_scan */
- if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
- priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
- else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
- priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
-
- /* If a request to abort was given, or the scan did not succeed
- * then we reset the scan state machine and terminate,
- * re-queuing another scan if one has been requested */
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_INFO("Aborted scan completed.\n");
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- } else {
- /* If there are more bands on this scan pass reschedule */
- if (priv->scan_bands > 0)
- goto reschedule;
- }
-
- priv->last_scan_jiffies = jiffies;
- priv->next_scan_jiffies = 0;
- IWL_DEBUG_INFO("Setting scan to off\n");
-
- clear_bit(STATUS_SCANNING, &priv->status);
-
- IWL_DEBUG_INFO("Scan took %dms\n",
- jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
-
- queue_work(priv->workqueue, &priv->scan_completed);
-
- return;
-
-reschedule:
- priv->scan_pass_start = jiffies;
- queue_work(priv->workqueue, &priv->request_scan);
-}
-
/* Handle notification from uCode that card's power state is changing
* due to software, hardware, or critical temperature RFKILL */
-static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
unsigned long status = priv->status;
- IWL_DEBUG_RF_KILL("Card state received: HW:%s SW:%s\n",
+ IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
(flags & HW_CARD_DISABLED) ? "Kill" : "On",
(flags & SW_CARD_DISABLED) ? "Kill" : "On");
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
if (flags & HW_CARD_DISABLED)
@@ -3245,7 +1432,7 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
else
clear_bit(STATUS_RF_KILL_SW, &priv->status);
- iwl3945_scan_cancel(priv);
+ iwl_scan_cancel(priv);
if ((test_bit(STATUS_RF_KILL_HW, &status) !=
test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
@@ -3265,17 +1452,15 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
* This function chains into the hardware specific files for them to setup
* any hardware specific handlers as well.
*/
-static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
+static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
{
priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive;
priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
- priv->rx_handlers[REPLY_ERROR] = iwl3945_rx_reply_error;
- priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl3945_rx_csa;
- priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
- iwl3945_rx_spectrum_measure_notif;
- priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl3945_rx_pm_sleep_notif;
+ priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
+ priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
+ priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
- iwl3945_rx_pm_debug_statistics_notif;
+ iwl_rx_pm_debug_statistics_notif;
priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif;
/*
@@ -3286,90 +1471,14 @@ static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
- priv->rx_handlers[REPLY_SCAN_CMD] = iwl3945_rx_reply_scan;
- priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl3945_rx_scan_start_notif;
- priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
- iwl3945_rx_scan_results_notif;
- priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
- iwl3945_rx_scan_complete_notif;
+ iwl_setup_spectrum_handlers(priv);
+ iwl_setup_rx_scan_handlers(priv);
priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
/* Set up hardware specific Rx handlers */
iwl3945_hw_rx_handler_setup(priv);
}
-/**
- * iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries
- * When FW advances 'R' index, all entries between old and new 'R' index
- * need to be reclaimed.
- */
-static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
- int txq_id, int index)
-{
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
- struct iwl3945_queue *q = &txq->q;
- int nfreed = 0;
-
- if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
- "is out of range [0-%d] %d %d.\n", txq_id,
- index, q->n_bd, q->write_ptr, q->read_ptr);
- return;
- }
-
- for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
- if (nfreed > 1) {
- IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
- q->write_ptr, q->read_ptr);
- queue_work(priv->workqueue, &priv->restart);
- break;
- }
- nfreed++;
- }
-}
-
-
-/**
- * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
- * @rxb: Rx buffer to reclaim
- *
- * If an Rx buffer has an async callback associated with it the callback
- * will be executed. The attached skb (if present) will only be freed
- * if the callback returns 1
- */
-static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
- u16 sequence = le16_to_cpu(pkt->hdr.sequence);
- int txq_id = SEQ_TO_QUEUE(sequence);
- int index = SEQ_TO_INDEX(sequence);
- int huge = sequence & SEQ_HUGE_FRAME;
- int cmd_index;
- struct iwl3945_cmd *cmd;
-
- BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
-
- cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
- cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-
- /* Input error checking is done when commands are added to queue. */
- if (cmd->meta.flags & CMD_WANT_SKB) {
- cmd->meta.source->u.skb = rxb->skb;
- rxb->skb = NULL;
- } else if (cmd->meta.u.callback &&
- !cmd->meta.u.callback(priv, cmd, rxb->skb))
- rxb->skb = NULL;
-
- iwl3945_cmd_queue_reclaim(priv, txq_id, index);
-
- if (!(cmd->meta.flags & CMD_ASYNC)) {
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
- wake_up_interruptible(&priv->wait_command_queue);
- }
-}
-
/************************** RX-FUNCTIONS ****************************/
/*
* Rx theory of operation
@@ -3417,7 +1526,6 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
*
* Driver sequence:
*
- * iwl3945_rx_queue_alloc() Allocates rx_free
* iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls
* iwl3945_rx_queue_restock
* iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx
@@ -3426,7 +1534,7 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
* are available, schedules iwl3945_rx_replenish
*
* -- enable interrupts --
- * ISR - iwl3945_rx() Detach iwl3945_rx_mem_buffers from pool up to the
+ * ISR - iwl3945_rx() Detach iwl_rx_mem_buffers from pool up to the
* READ INDEX, detaching the SKB from the pool.
* Moves the packet buffer from queue to rx_used.
* Calls iwl3945_rx_queue_restock to refill any empty
@@ -3436,70 +1544,9 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
*/
/**
- * iwl3945_rx_queue_space - Return number of free slots available in queue.
- */
-static int iwl3945_rx_queue_space(const struct iwl3945_rx_queue *q)
-{
- int s = q->read - q->write;
- if (s <= 0)
- s += RX_QUEUE_SIZE;
- /* keep some buffer to not confuse full and empty queue */
- s -= 2;
- if (s < 0)
- s = 0;
- return s;
-}
-
-/**
- * iwl3945_rx_queue_update_write_ptr - Update the write pointer for the RX queue
- */
-int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_rx_queue *q)
-{
- u32 reg = 0;
- int rc = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
-
- if (q->need_update == 0)
- goto exit_unlock;
-
- /* If power-saving is in use, make sure device is awake */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- goto exit_unlock;
- }
-
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- goto exit_unlock;
-
- /* Device expects a multiple of 8 */
- iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
- q->write & ~0x7);
- iwl3945_release_nic_access(priv);
-
- /* Else device is assumed to be awake */
- } else
- /* Device expects a multiple of 8 */
- iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
-
-
- q->need_update = 0;
-
- exit_unlock:
- spin_unlock_irqrestore(&q->lock, flags);
- return rc;
-}
-
-/**
* iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
*/
-static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
+static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv,
dma_addr_t dma_addr)
{
return cpu_to_le32((u32)dma_addr);
@@ -3516,24 +1563,24 @@ static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
* also updates the memory address in the firmware to reference the new
* target buffer.
*/
-static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
+static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
- struct iwl3945_rx_mem_buffer *rxb;
+ struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
int write, rc;
spin_lock_irqsave(&rxq->lock, flags);
write = rxq->write & ~0x7;
- while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+ while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
/* Get next free Rx buffer, remove from free list */
element = rxq->rx_free.next;
- rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
list_del(element);
/* Point to Rx buffer via next RBD in circular buffer */
- rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr);
+ rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr);
rxq->queue[rxq->write] = rxb;
rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
rxq->free_count--;
@@ -3552,7 +1599,7 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
spin_lock_irqsave(&rxq->lock, flags);
rxq->need_update = 1;
spin_unlock_irqrestore(&rxq->lock, flags);
- rc = iwl3945_rx_queue_update_write_ptr(priv, rxq);
+ rc = iwl_rx_queue_update_write_ptr(priv, rxq);
if (rc)
return rc;
}
@@ -3568,24 +1615,24 @@ static int iwl3945_rx_queue_restock(struct iwl3945_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 iwl3945_priv *priv)
+static void iwl3945_rx_allocate(struct iwl_priv *priv)
{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
- struct iwl3945_rx_mem_buffer *rxb;
+ struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
spin_lock_irqsave(&rxq->lock, flags);
while (!list_empty(&rxq->rx_used)) {
element = rxq->rx_used.next;
- rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
/* Alloc a new receive buffer */
rxb->skb =
- alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC);
+ alloc_skb(priv->hw_params.rx_buf_size,
+ __GFP_NOWARN | GFP_ATOMIC);
if (!rxb->skb) {
if (net_ratelimit())
- printk(KERN_CRIT DRV_NAME
- ": Can not allocate SKB buffers\n");
+ IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
* call the restock method and if it still needs
* more buffers it will schedule replenish */
@@ -3604,9 +1651,10 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
list_del(element);
/* Get physical address of RB/SKB */
- rxb->dma_addr =
- pci_map_single(priv->pci_dev, rxb->skb->data,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ rxb->real_dma_addr = pci_map_single(priv->pci_dev,
+ rxb->skb->data,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
}
@@ -3618,7 +1666,7 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
*/
static void __iwl3945_rx_replenish(void *data)
{
- struct iwl3945_priv *priv = data;
+ struct iwl_priv *priv = data;
iwl3945_rx_allocate(priv);
iwl3945_rx_queue_restock(priv);
@@ -3627,7 +1675,7 @@ static void __iwl3945_rx_replenish(void *data)
void iwl3945_rx_replenish(void *data)
{
- struct iwl3945_priv *priv = data;
+ struct iwl_priv *priv = data;
unsigned long flags;
iwl3945_rx_allocate(priv);
@@ -3637,84 +1685,6 @@ void iwl3945_rx_replenish(void *data)
spin_unlock_irqrestore(&priv->lock, flags);
}
-/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
- * If an SKB has been detached, the POOL needs to have its SKB set to NULL
- * This free routine walks the list of POOL entries and if SKB is set to
- * non NULL it is unmapped and freed
- */
-static void iwl3945_rx_queue_free(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
-{
- int i;
- for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
- if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev,
- rxq->pool[i].dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- dev_kfree_skb(rxq->pool[i].skb);
- }
- }
-
- pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
- rxq->dma_addr);
- rxq->bd = NULL;
-}
-
-int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv)
-{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
- struct pci_dev *dev = priv->pci_dev;
- int i;
-
- spin_lock_init(&rxq->lock);
- INIT_LIST_HEAD(&rxq->rx_free);
- INIT_LIST_HEAD(&rxq->rx_used);
-
- /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
- rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
- if (!rxq->bd)
- return -ENOMEM;
-
- /* Fill the rx_used queue with _all_ of the Rx buffers */
- for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
- list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
-
- /* Set us so that we have processed and used all buffers, but have
- * not restocked the Rx queue with fresh buffers */
- rxq->read = rxq->write = 0;
- rxq->free_count = 0;
- rxq->need_update = 0;
- return 0;
-}
-
-void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
-{
- unsigned long flags;
- int i;
- spin_lock_irqsave(&rxq->lock, flags);
- INIT_LIST_HEAD(&rxq->rx_free);
- INIT_LIST_HEAD(&rxq->rx_used);
- /* Fill the rx_used queue with _all_ of the Rx buffers */
- for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
- /* In the reset function, these buffers may have been allocated
- * to an SKB, so we need to unmap and free potential storage */
- if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev,
- rxq->pool[i].dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- priv->alloc_rxb_skb--;
- dev_kfree_skb(rxq->pool[i].skb);
- rxq->pool[i].skb = NULL;
- }
- list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
- }
-
- /* Set us so that we have processed and used all buffers, but have
- * not restocked the Rx queue with fresh buffers */
- rxq->read = rxq->write = 0;
- rxq->free_count = 0;
- spin_unlock_irqrestore(&rxq->lock, flags);
-}
-
/* Convert linear signal-to-noise ratio into dB */
static u8 ratio2dB[100] = {
/* 0 1 2 3 4 5 6 7 8 9 */
@@ -3800,11 +1770,11 @@ int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm)
* the appropriate handlers, including command responses,
* frame-received notifications, and other notifications.
*/
-static void iwl3945_rx_handle(struct iwl3945_priv *priv)
+static void iwl3945_rx_handle(struct iwl_priv *priv)
{
- struct iwl3945_rx_mem_buffer *rxb;
- struct iwl3945_rx_packet *pkt;
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_mem_buffer *rxb;
+ struct iwl_rx_packet *pkt;
+ struct iwl_rx_queue *rxq = &priv->rxq;
u32 r, i;
int reclaim;
unsigned long flags;
@@ -3813,14 +1783,14 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
- r = iwl3945_hw_get_rx_read(priv);
+ r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
i = rxq->read;
- if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+ if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
/* Rx interrupt, but nothing sent from uCode */
if (i == r)
- IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
+ IWL_DEBUG(priv, IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
while (i != r) {
rxb = rxq->queue[i];
@@ -3832,10 +1802,10 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
rxq->queue[i] = NULL;
- pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
- IWL_RX_BUF_SIZE,
+ pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->real_dma_addr,
+ priv->hw_params.rx_buf_size,
PCI_DMA_FROMDEVICE);
- pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
+ pkt = (struct iwl_rx_packet *)rxb->skb->data;
/* Reclaim a command buffer only if this packet is a response
* to a (driver-originated) command.
@@ -3851,13 +1821,13 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
* handle those that need handling via function in
* rx_handlers table. See iwl3945_setup_rx_handlers() */
if (priv->rx_handlers[pkt->hdr.cmd]) {
- IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+ IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
"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);
} else {
/* No handling needed */
- IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+ IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
"r %d i %d No handler needed for %s, 0x%02x\n",
r, i, get_cmd_string(pkt->hdr.cmd),
pkt->hdr.cmd);
@@ -3865,12 +1835,12 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
if (reclaim) {
/* Invoke any callbacks, transfer the skb to caller, and
- * fire off the (possibly) blocking iwl3945_send_cmd()
+ * fire off the (possibly) blocking iwl_send_cmd()
* as we reclaim the driver command queue */
if (rxb && rxb->skb)
- iwl3945_tx_cmd_complete(priv, rxb);
+ iwl_tx_cmd_complete(priv, rxb);
else
- IWL_WARNING("Claim null rxb?\n");
+ IWL_WARN(priv, "Claim null rxb?\n");
}
/* For now we just don't re-use anything. We can tweak this
@@ -3882,8 +1852,9 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
rxb->skb = NULL;
}
- pci_unmap_single(priv->pci_dev, rxb->dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
spin_lock_irqsave(&rxq->lock, flags);
list_add_tail(&rxb->list, &priv->rxq.rx_used);
spin_unlock_irqrestore(&rxq->lock, flags);
@@ -3905,102 +1876,14 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
iwl3945_rx_queue_restock(priv);
}
-/**
- * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware
- */
-static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq)
-{
- u32 reg = 0;
- int rc = 0;
- int txq_id = txq->q.id;
-
- if (txq->need_update == 0)
- return rc;
-
- /* if we're trying to save power */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- /* wake up nic if it's powered down ...
- * uCode will wake up, and interrupt us again, so next
- * time we'll skip this part. */
- reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- return rc;
- }
-
- /* restore this queue's parameters in nic hardware. */
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- return rc;
- iwl3945_write_direct32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
- iwl3945_release_nic_access(priv);
-
- /* else not in power-save mode, uCode will never sleep when we're
- * trying to tx (during RFKILL, we're not trying to tx). */
- } else
- iwl3945_write32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
-
- txq->need_update = 0;
-
- return rc;
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
-{
- IWL_DEBUG_RADIO("RX CONFIG:\n");
- iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
- IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
- IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
- IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
- le32_to_cpu(rxon->filter_flags));
- IWL_DEBUG_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type);
- IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
- rxon->ofdm_basic_rates);
- IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
- IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
- IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
- IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
-}
-#endif
-
-static void iwl3945_enable_interrupts(struct iwl3945_priv *priv)
-{
- IWL_DEBUG_ISR("Enabling interrupts\n");
- set_bit(STATUS_INT_ENABLED, &priv->status);
- iwl3945_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
-}
-
-
/* call this function to flush any scheduled tasklet */
-static inline void iwl_synchronize_irq(struct iwl3945_priv *priv)
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
{
/* wait to make sure we flush pending tasklet*/
synchronize_irq(priv->pci_dev->irq);
tasklet_kill(&priv->irq_tasklet);
}
-
-static inline void iwl3945_disable_interrupts(struct iwl3945_priv *priv)
-{
- clear_bit(STATUS_INT_ENABLED, &priv->status);
-
- /* disable interrupts from uCode/NIC to host */
- iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
-
- /* acknowledge/clear/reset any interrupts still pending
- * from uCode or flow handler (Rx/Tx DMA) */
- iwl3945_write32(priv, CSR_INT, 0xffffffff);
- iwl3945_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
- IWL_DEBUG_ISR("Disabled interrupts\n");
-}
-
static const char *desc_lookup(int i)
{
switch (i) {
@@ -4024,7 +1907,7 @@ static const char *desc_lookup(int i)
#define ERROR_START_OFFSET (1 * sizeof(u32))
#define ERROR_ELEM_SIZE (7 * sizeof(u32))
-static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
+static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
{
u32 i;
u32 desc, time, count, base, data1;
@@ -4034,49 +1917,50 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
return;
}
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
- count = iwl3945_read_targ_mem(priv, base);
+ count = iwl_read_targ_mem(priv, base);
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
- IWL_ERROR("Start IWL Error Log Dump:\n");
- IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+ IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+ IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+ priv->status, count);
}
- IWL_ERROR("Desc Time asrtPC blink2 "
+ IWL_ERR(priv, "Desc Time asrtPC blink2 "
"ilink1 nmiPC Line\n");
for (i = ERROR_START_OFFSET;
i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET;
i += ERROR_ELEM_SIZE) {
- desc = iwl3945_read_targ_mem(priv, base + i);
+ desc = iwl_read_targ_mem(priv, base + i);
time =
- iwl3945_read_targ_mem(priv, base + i + 1 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 1 * sizeof(u32));
blink1 =
- iwl3945_read_targ_mem(priv, base + i + 2 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 2 * sizeof(u32));
blink2 =
- iwl3945_read_targ_mem(priv, base + i + 3 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 3 * sizeof(u32));
ilink1 =
- iwl3945_read_targ_mem(priv, base + i + 4 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 4 * sizeof(u32));
ilink2 =
- iwl3945_read_targ_mem(priv, base + i + 5 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 5 * sizeof(u32));
data1 =
- iwl3945_read_targ_mem(priv, base + i + 6 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32));
- IWL_ERROR
- ("%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
- desc_lookup(desc), desc, time, blink1, blink2,
- ilink1, ilink2, data1);
+ IWL_ERR(priv,
+ "%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
+ desc_lookup(desc), desc, time, blink1, blink2,
+ ilink1, ilink2, data1);
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
@@ -4085,9 +1969,9 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
/**
* iwl3945_print_event_log - Dump error event log to syslog
*
- * NOTE: Must be called with iwl3945_grab_nic_access() already obtained!
+ * NOTE: Must be called with iwl_grab_nic_access() already obtained!
*/
-static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
+static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 num_events, u32 mode)
{
u32 i;
@@ -4111,21 +1995,22 @@ static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
/* "time" is actually "data" for mode 0 (no timestamp).
* place event id # at far right for easier visual parsing. */
for (i = 0; i < num_events; i++) {
- ev = iwl3945_read_targ_mem(priv, ptr);
+ ev = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- time = iwl3945_read_targ_mem(priv, ptr);
+ time = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- if (mode == 0)
- IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
- else {
- data = iwl3945_read_targ_mem(priv, ptr);
+ if (mode == 0) {
+ /* data, ev */
+ IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
+ } else {
+ data = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
+ IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
}
}
}
-static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
+static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
{
int rc;
u32 base; /* SRAM byte address of event log header */
@@ -4137,32 +2022,32 @@ static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
/* event log header */
- capacity = iwl3945_read_targ_mem(priv, base);
- mode = iwl3945_read_targ_mem(priv, base + (1 * sizeof(u32)));
- num_wraps = iwl3945_read_targ_mem(priv, base + (2 * sizeof(u32)));
- next_entry = iwl3945_read_targ_mem(priv, base + (3 * sizeof(u32)));
+ capacity = iwl_read_targ_mem(priv, base);
+ mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
+ num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
+ next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
size = num_wraps ? capacity : next_entry;
/* bail out if nothing in log */
if (size == 0) {
- IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
- iwl3945_release_nic_access(priv);
+ IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
+ iwl_release_nic_access(priv);
return;
}
- IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+ IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
size, num_wraps);
/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -4174,48 +2059,10 @@ static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
/* (then/else) start at top of log */
iwl3945_print_event_log(priv, 0, next_entry, mode);
- iwl3945_release_nic_access(priv);
-}
-
-/**
- * iwl3945_irq_handle_error - called for HW or SW error interrupt from card
- */
-static void iwl3945_irq_handle_error(struct iwl3945_priv *priv)
-{
- /* Set the FW error flag -- cleared on iwl3945_down */
- set_bit(STATUS_FW_ERROR, &priv->status);
-
- /* Cancel currently queued command. */
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & IWL_DL_FW_ERRORS) {
- iwl3945_dump_nic_error_log(priv);
- iwl3945_dump_nic_event_log(priv);
- iwl3945_print_rx_config_cmd(&priv->staging_rxon);
- }
-#endif
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- /* Keep the restart process from trying to send host
- * commands by clearing the INIT status bit */
- clear_bit(STATUS_READY, &priv->status);
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS,
- "Restarting adapter due to uCode error.\n");
-
- if (iwl3945_is_associated(priv)) {
- memcpy(&priv->recovery_rxon, &priv->active_rxon,
- sizeof(priv->recovery_rxon));
- priv->error_recovering = 1;
- }
- queue_work(priv->workqueue, &priv->restart);
- }
+ iwl_release_nic_access(priv);
}
-static void iwl3945_error_recovery(struct iwl3945_priv *priv)
+static void iwl3945_error_recovery(struct iwl_priv *priv)
{
unsigned long flags;
@@ -4232,12 +2079,12 @@ static void iwl3945_error_recovery(struct iwl3945_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
+static void iwl3945_irq_tasklet(struct iwl_priv *priv)
{
u32 inta, handled = 0;
u32 inta_fh;
unsigned long flags;
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
u32 inta_mask;
#endif
@@ -4246,20 +2093,20 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Ack/clear/reset pending uCode interrupts.
* Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
* and will clear only when CSR_FH_INT_STATUS gets cleared. */
- inta = iwl3945_read32(priv, CSR_INT);
- iwl3945_write32(priv, CSR_INT, inta);
+ inta = iwl_read32(priv, CSR_INT);
+ iwl_write32(priv, CSR_INT, inta);
/* Ack/clear/reset pending flow-handler (DMA) interrupts.
* Any new interrupts that happen after this, either while we're
* in this tasklet, or later, will show up in next ISR/tasklet. */
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
- iwl3945_write32(priv, CSR_FH_INT_STATUS, inta_fh);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+ iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & IWL_DL_ISR) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & IWL_DL_ISR) {
/* just for debug */
- inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
- IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+ inta_mask = iwl_read32(priv, CSR_INT_MASK);
+ IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
}
#endif
@@ -4275,12 +2122,12 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Now service all interrupt bits discovered above. */
if (inta & CSR_INT_BIT_HW_ERR) {
- IWL_ERROR("Microcode HW error detected. Restarting.\n");
+ IWL_ERR(priv, "Microcode HW error detected. Restarting.\n");
/* Tell the device to stop sending interrupts */
- iwl3945_disable_interrupts(priv);
+ iwl_disable_interrupts(priv);
- iwl3945_irq_handle_error(priv);
+ iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_HW_ERR;
@@ -4289,16 +2136,16 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
return;
}
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_ISR)) {
+#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("Scheduler finished to transmit "
+ IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE)
- IWL_DEBUG_ISR("Alive interrupt\n");
+ IWL_DEBUG_ISR(priv, "Alive interrupt\n");
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -4306,22 +2153,22 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Error detected by uCode */
if (inta & CSR_INT_BIT_SW_ERR) {
- IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n",
- inta);
- iwl3945_irq_handle_error(priv);
+ IWL_ERR(priv, "Microcode SW error detected. "
+ "Restarting 0x%X.\n", 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("Wakeup interrupt\n");
- iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[0]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[1]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[2]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[3]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[4]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[5]);
+ 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]);
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -4335,432 +2182,63 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
}
if (inta & CSR_INT_BIT_FH_TX) {
- IWL_DEBUG_ISR("Tx interrupt\n");
-
- iwl3945_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
- if (!iwl3945_grab_nic_access(priv)) {
- iwl3945_write_direct32(priv,
- FH_TCSR_CREDIT
- (ALM_FH_SRVC_CHNL), 0x0);
- iwl3945_release_nic_access(priv);
+ IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+
+ 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);
}
handled |= CSR_INT_BIT_FH_TX;
}
if (inta & ~handled)
- IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
if (inta & ~CSR_INI_SET_MASK) {
- IWL_WARNING("Disabled INTA bits 0x%08x were pending\n",
+ IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
inta & ~CSR_INI_SET_MASK);
- IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh);
+ IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
/* Re-enable all interrupts */
/* only Re-enable if disabled by irq */
if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl3945_enable_interrupts(priv);
-
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_ISR)) {
- inta = iwl3945_read32(priv, CSR_INT);
- inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
- IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
+ iwl_enable_interrupts(priv);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & (IWL_DL_ISR)) {
+ inta = iwl_read32(priv, CSR_INT);
+ inta_mask = iwl_read32(priv, CSR_INT_MASK);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+ IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
}
#endif
spin_unlock_irqrestore(&priv->lock, flags);
}
-static irqreturn_t iwl3945_isr(int irq, void *data)
-{
- struct iwl3945_priv *priv = data;
- u32 inta, inta_mask;
- u32 inta_fh;
- 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 = iwl3945_read32(priv, CSR_INT_MASK); /* just for debug */
- iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
-
- /* Discover which interrupts are active/pending */
- inta = iwl3945_read32(priv, CSR_INT);
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
-
- /* Ignore interrupt if there's nothing in NIC to service.
- * This may be due to IRQ shared with another device,
- * or due to sporadic interrupts thrown from our NIC. */
- if (!inta && !inta_fh) {
- IWL_DEBUG_ISR("Ignore interrupt, inta == 0, inta_fh == 0\n");
- goto none;
- }
-
- if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
- /* Hardware disappeared */
- IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
- goto unplugged;
- }
-
- IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
- inta, inta_mask, inta_fh);
-
- inta &= ~CSR_INT_BIT_SCD;
-
- /* iwl3945_irq_tasklet() will service interrupts and re-enable them */
- if (likely(inta || inta_fh))
- tasklet_schedule(&priv->irq_tasklet);
-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 disabled by irq */
- if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl3945_enable_interrupts(priv);
- spin_unlock(&priv->lock);
- return IRQ_NONE;
-}
-
-/************************** EEPROM BANDS ****************************
- *
- * The iwl3945_eeprom_band definitions below provide the mapping from the
- * EEPROM contents to the specific channel number supported for each
- * band.
- *
- * For example, iwl3945_priv->eeprom.band_3_channels[4] from the band_3
- * definition below maps to physical channel 42 in the 5.2GHz spectrum.
- * The specific geography and calibration information for that channel
- * is contained in the eeprom map itself.
- *
- * During init, we copy the eeprom information and channel map
- * information into priv->channel_info_24/52 and priv->channel_map_24/52
- *
- * channel_map_24/52 provides the index in the channel_info array for a
- * given channel. We have to have two separate maps as there is channel
- * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
- * band_2
- *
- * A value of 0xff stored in the channel_map indicates that the channel
- * is not supported by the hardware at all.
- *
- * A value of 0xfe in the channel_map indicates that the channel is not
- * valid for Tx with the current hardware. This means that
- * while the system can tune and receive on a given channel, it may not
- * be able to associate or transmit any frames on that
- * channel. There is no corresponding channel information for that
- * entry.
- *
- *********************************************************************/
-
-/* 2.4 GHz */
-static const u8 iwl3945_eeprom_band_1[14] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-};
-
-/* 5.2 GHz bands */
-static const u8 iwl3945_eeprom_band_2[] = { /* 4915-5080MHz */
- 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16
-};
-
-static const u8 iwl3945_eeprom_band_3[] = { /* 5170-5320MHz */
- 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
-};
-
-static const u8 iwl3945_eeprom_band_4[] = { /* 5500-5700MHz */
- 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
-};
-
-static const u8 iwl3945_eeprom_band_5[] = { /* 5725-5825MHz */
- 145, 149, 153, 157, 161, 165
-};
-
-static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int band,
- int *eeprom_ch_count,
- const struct iwl3945_eeprom_channel
- **eeprom_ch_info,
- const u8 **eeprom_ch_index)
-{
- switch (band) {
- case 1: /* 2.4GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_1);
- *eeprom_ch_info = priv->eeprom.band_1_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_1;
- break;
- case 2: /* 4.9GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_2);
- *eeprom_ch_info = priv->eeprom.band_2_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_2;
- break;
- case 3: /* 5.2GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_3);
- *eeprom_ch_info = priv->eeprom.band_3_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_3;
- break;
- case 4: /* 5.5GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_4);
- *eeprom_ch_info = priv->eeprom.band_4_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_4;
- break;
- case 5: /* 5.7GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_5);
- *eeprom_ch_info = priv->eeprom.band_5_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_5;
- break;
- default:
- BUG();
- return;
- }
-}
-
-/**
- * iwl3945_get_channel_info - Find driver's private channel info
- *
- * Based on band and channel number.
- */
-const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv,
- enum ieee80211_band band, u16 channel)
-{
- int i;
-
- switch (band) {
- case IEEE80211_BAND_5GHZ:
- for (i = 14; i < priv->channel_count; i++) {
- if (priv->channel_info[i].channel == channel)
- return &priv->channel_info[i];
- }
- break;
-
- case IEEE80211_BAND_2GHZ:
- if (channel >= 1 && channel <= 14)
- return &priv->channel_info[channel - 1];
- break;
- case IEEE80211_NUM_BANDS:
- WARN_ON(1);
- }
-
- return NULL;
-}
-
-#define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
- ? # x " " : "")
-
-/**
- * iwl3945_init_channel_map - Set up driver's info for all possible channels
- */
-static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
-{
- int eeprom_ch_count = 0;
- const u8 *eeprom_ch_index = NULL;
- const struct iwl3945_eeprom_channel *eeprom_ch_info = NULL;
- int band, ch;
- struct iwl3945_channel_info *ch_info;
-
- if (priv->channel_count) {
- IWL_DEBUG_INFO("Channel map already initialized.\n");
- return 0;
- }
-
- if (priv->eeprom.version < 0x2f) {
- IWL_WARNING("Unsupported EEPROM version: 0x%04X\n",
- priv->eeprom.version);
- return -EINVAL;
- }
-
- IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
-
- priv->channel_count =
- ARRAY_SIZE(iwl3945_eeprom_band_1) +
- ARRAY_SIZE(iwl3945_eeprom_band_2) +
- ARRAY_SIZE(iwl3945_eeprom_band_3) +
- ARRAY_SIZE(iwl3945_eeprom_band_4) +
- ARRAY_SIZE(iwl3945_eeprom_band_5);
-
- IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
-
- priv->channel_info = kzalloc(sizeof(struct iwl3945_channel_info) *
- priv->channel_count, GFP_KERNEL);
- if (!priv->channel_info) {
- IWL_ERROR("Could not allocate channel_info\n");
- priv->channel_count = 0;
- return -ENOMEM;
- }
-
- ch_info = priv->channel_info;
-
- /* Loop through the 5 EEPROM bands adding them in order to the
- * channel map we maintain (that contains additional information than
- * what just in the EEPROM) */
- for (band = 1; band <= 5; band++) {
-
- iwl3945_init_band_reference(priv, band, &eeprom_ch_count,
- &eeprom_ch_info, &eeprom_ch_index);
-
- /* Loop through each band adding each of the channels */
- for (ch = 0; ch < eeprom_ch_count; ch++) {
- ch_info->channel = eeprom_ch_index[ch];
- ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ :
- IEEE80211_BAND_5GHZ;
-
- /* permanently store EEPROM's channel regulatory flags
- * and max power in channel info database. */
- ch_info->eeprom = eeprom_ch_info[ch];
-
- /* Copy the run-time flags so they are there even on
- * invalid channels */
- ch_info->flags = eeprom_ch_info[ch].flags;
-
- if (!(is_channel_valid(ch_info))) {
- IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
- "No traffic\n",
- ch_info->channel,
- ch_info->flags,
- is_channel_a_band(ch_info) ?
- "5.2" : "2.4");
- ch_info++;
- continue;
- }
-
- /* Initialize regulatory-based run-time data */
- ch_info->max_power_avg = ch_info->curr_txpow =
- eeprom_ch_info[ch].max_power_avg;
- ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
- ch_info->min_power = 0;
-
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
- " %ddBm): Ad-Hoc %ssupported\n",
- ch_info->channel,
- is_channel_a_band(ch_info) ?
- "5.2" : "2.4",
- CHECK_AND_PRINT(VALID),
- CHECK_AND_PRINT(IBSS),
- CHECK_AND_PRINT(ACTIVE),
- CHECK_AND_PRINT(RADAR),
- CHECK_AND_PRINT(WIDE),
- CHECK_AND_PRINT(DFS),
- eeprom_ch_info[ch].flags,
- eeprom_ch_info[ch].max_power_avg,
- ((eeprom_ch_info[ch].
- flags & EEPROM_CHANNEL_IBSS)
- && !(eeprom_ch_info[ch].
- flags & EEPROM_CHANNEL_RADAR))
- ? "" : "not ");
-
- /* Set the user_txpower_limit to the highest power
- * supported by any channel */
- if (eeprom_ch_info[ch].max_power_avg >
- priv->user_txpower_limit)
- priv->user_txpower_limit =
- eeprom_ch_info[ch].max_power_avg;
-
- ch_info++;
- }
- }
-
- /* Set up txpower settings in driver for all channels */
- if (iwl3945_txpower_set_from_eeprom(priv))
- return -EIO;
-
- return 0;
-}
-
-/*
- * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
- */
-static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
-{
- kfree(priv->channel_info);
- priv->channel_count = 0;
-}
-
-/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
- * sending probe req. This should be set long enough to hear probe responses
- * from more than one AP. */
-#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */
-#define IWL_ACTIVE_DWELL_TIME_52 (20)
-
-#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
-#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
-
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
-
-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
- * Must be set longer than active dwell time.
- * For the most reliable scan, set > AP beacon interval (typically 100msec). */
-#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
-#define IWL_PASSIVE_DWELL_TIME_52 (10)
-#define IWL_PASSIVE_DWELL_BASE (100)
-#define IWL_CHANNEL_TUNE_TIME 5
-
-#define IWL_SCAN_PROBE_MASK(n) (BIT(n) | (BIT(n) - BIT(1)))
-
-static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
- enum ieee80211_band band,
- u8 n_probes)
-{
- if (band == IEEE80211_BAND_5GHZ)
- return IWL_ACTIVE_DWELL_TIME_52 +
- IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
- else
- return IWL_ACTIVE_DWELL_TIME_24 +
- IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
-}
-
-static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
- enum ieee80211_band band)
-{
- u16 passive = (band == IEEE80211_BAND_2GHZ) ?
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
-
- if (iwl3945_is_associated(priv)) {
- /* If we're associated, we clamp the maximum passive
- * dwell time to be 98% of the beacon interval (minus
- * 2 * channel tune time) */
- passive = priv->beacon_int;
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
- passive = IWL_PASSIVE_DWELL_BASE;
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
- }
-
- return passive;
-}
-
-static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
+static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
u8 is_active, u8 n_probes,
struct iwl3945_scan_channel *scan_ch)
{
const struct ieee80211_channel *channels = NULL;
const struct ieee80211_supported_band *sband;
- const struct iwl3945_channel_info *ch_info;
+ const struct iwl_channel_info *ch_info;
u16 passive_dwell = 0;
u16 active_dwell = 0;
int added, i;
- sband = iwl3945_get_band(priv, band);
+ sband = iwl_get_hw_mode(priv, band);
if (!sband)
return 0;
channels = sband->channels;
- active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
- passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
+ active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band);
if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
@@ -4771,9 +2249,9 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
scan_ch->channel = channels[i].hw_value;
- ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
+ ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
+ IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
scan_ch->channel);
continue;
}
@@ -4798,12 +2276,12 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
* hearing clear Rx packet).*/
if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
if (n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+ scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
} else {
/* uCode v1 does not allow setting direct probe bits on
* passive channel. */
if ((scan_ch->type & 1) && n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+ scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
}
/* Set txpower levels to defaults */
@@ -4821,7 +2299,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
*/
}
- IWL_DEBUG_SCAN("Scanning %d [%s %d]\n",
+ IWL_DEBUG_SCAN(priv, "Scanning %d [%s %d]\n",
scan_ch->channel,
(scan_ch->type & 1) ? "ACTIVE" : "PASSIVE",
(scan_ch->type & 1) ?
@@ -4831,11 +2309,11 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
added++;
}
- IWL_DEBUG_SCAN("total channels to scan %d \n", added);
+ IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added);
return added;
}
-static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
+static void iwl3945_init_hw_rates(struct iwl_priv *priv,
struct ieee80211_rate *rates)
{
int i;
@@ -4845,7 +2323,7 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
rates[i].hw_value = i; /* Rate scaling will work on indexes */
rates[i].hw_value_short = i;
rates[i].flags = 0;
- if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
+ if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
/*
* If CCK != 1M then set short preamble rate flag.
*/
@@ -4855,145 +2333,13 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
}
}
-/**
- * iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom
- */
-static int iwl3945_init_geos(struct iwl3945_priv *priv)
-{
- struct iwl3945_channel_info *ch;
- struct ieee80211_supported_band *sband;
- struct ieee80211_channel *channels;
- struct ieee80211_channel *geo_ch;
- struct ieee80211_rate *rates;
- int i = 0;
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
- priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
- IWL_DEBUG_INFO("Geography modes already initialized.\n");
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
- return 0;
- }
-
- channels = kzalloc(sizeof(struct ieee80211_channel) *
- priv->channel_count, GFP_KERNEL);
- if (!channels)
- return -ENOMEM;
-
- rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
- GFP_KERNEL);
- if (!rates) {
- kfree(channels);
- return -ENOMEM;
- }
-
- /* 5.2GHz channels start after the 2.4GHz channels */
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
- /* just OFDM */
- sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
- sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
-
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
- sband->channels = channels;
- /* OFDM & CCK */
- sband->bitrates = rates;
- sband->n_bitrates = IWL_RATE_COUNT;
-
- priv->ieee_channels = channels;
- priv->ieee_rates = rates;
-
- iwl3945_init_hw_rates(priv, rates);
-
- for (i = 0; i < priv->channel_count; i++) {
- ch = &priv->channel_info[i];
-
- /* FIXME: might be removed if scan is OK*/
- if (!is_channel_valid(ch))
- continue;
-
- if (is_channel_a_band(ch))
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- else
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
-
- geo_ch = &sband->channels[sband->n_channels++];
-
- geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
- geo_ch->max_power = ch->max_power_avg;
- geo_ch->max_antenna_gain = 0xff;
- geo_ch->hw_value = ch->channel;
-
- if (is_channel_valid(ch)) {
- if (!(ch->flags & EEPROM_CHANNEL_IBSS))
- geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
-
- if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
- geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- if (ch->flags & EEPROM_CHANNEL_RADAR)
- geo_ch->flags |= IEEE80211_CHAN_RADAR;
-
- if (ch->max_power_avg > priv->max_channel_txpower_limit)
- priv->max_channel_txpower_limit =
- ch->max_power_avg;
- } else {
- geo_ch->flags |= IEEE80211_CHAN_DISABLED;
- }
-
- /* Save flags for reg domain usage */
- geo_ch->orig_flags = geo_ch->flags;
-
- IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
- ch->channel, geo_ch->center_freq,
- is_channel_a_band(ch) ? "5.2" : "2.4",
- geo_ch->flags & IEEE80211_CHAN_DISABLED ?
- "restricted" : "valid",
- geo_ch->flags);
- }
-
- if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
- priv->cfg->sku & IWL_SKU_A) {
- printk(KERN_INFO DRV_NAME
- ": Incorrectly detected BG card as ABG. Please send "
- "your PCI ID 0x%04X:0x%04X to maintainer.\n",
- priv->pci_dev->device, priv->pci_dev->subsystem_device);
- priv->cfg->sku &= ~IWL_SKU_A;
- }
-
- printk(KERN_INFO DRV_NAME
- ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- priv->bands[IEEE80211_BAND_2GHZ].n_channels,
- priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
- &priv->bands[IEEE80211_BAND_2GHZ];
- if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
- &priv->bands[IEEE80211_BAND_5GHZ];
-
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
-
- return 0;
-}
-
-/*
- * iwl3945_free_geos - undo allocations in iwl3945_init_geos
- */
-static void iwl3945_free_geos(struct iwl3945_priv *priv)
-{
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
- clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
-}
-
/******************************************************************************
*
* uCode download functions
*
******************************************************************************/
-static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
+static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv)
{
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
@@ -5007,29 +2353,30 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
* iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
* looking at all data.
*/
-static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len)
{
u32 val;
u32 save_len = len;
int rc = 0;
u32 errcnt;
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+ IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc)
return rc;
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ IWL39_RTC_INST_LOWER_BOUND);
errcnt = 0;
for (; len > 0; len -= sizeof(u32), image++) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
- val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
save_len - len, val, le32_to_cpu(*image));
rc = -EIO;
@@ -5039,10 +2386,11 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3
}
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
if (!errcnt)
- IWL_DEBUG_INFO("ucode image in INSTRUCTION memory is good\n");
+ IWL_DEBUG_INFO(priv,
+ "ucode image in INSTRUCTION memory is good\n");
return rc;
}
@@ -5053,16 +2401,16 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3
* using sample data 100 bytes apart. If these sample points are good,
* it's a pretty good bet that everything between them is good, too.
*/
-static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
{
u32 val;
int rc = 0;
u32 errcnt = 0;
u32 i;
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+ IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc)
return rc;
@@ -5070,12 +2418,12 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR,
- i + RTC_INST_LOWER_BOUND);
- val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ i + IWL39_RTC_INST_LOWER_BOUND);
+ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
#if 0 /* Enable this if you want to see details */
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
i, val, *image);
#endif
@@ -5086,7 +2434,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
}
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
return rc;
}
@@ -5096,7 +2444,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
* iwl3945_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
-static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
+static int iwl3945_verify_ucode(struct iwl_priv *priv)
{
__le32 *image;
u32 len;
@@ -5107,7 +2455,7 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
len = priv->ucode_boot.len;
rc = iwl3945_verify_inst_sparse(priv, image, len);
if (rc == 0) {
- IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
return 0;
}
@@ -5116,7 +2464,7 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
len = priv->ucode_init.len;
rc = iwl3945_verify_inst_sparse(priv, image, len);
if (rc == 0) {
- IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
return 0;
}
@@ -5125,11 +2473,11 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
len = priv->ucode_code.len;
rc = iwl3945_verify_inst_sparse(priv, image, len);
if (rc == 0) {
- IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
return 0;
}
- IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
/* Since nothing seems to match, show first several data entries in
* instruction SRAM, so maybe visual inspection will give a clue.
@@ -5141,160 +2489,10 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
return rc;
}
-
-/* check contents of special bootstrap uCode SRAM */
-static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
-{
- __le32 *image = priv->ucode_boot.v_addr;
- u32 len = priv->ucode_boot.len;
- u32 reg;
- u32 val;
-
- IWL_DEBUG_INFO("Begin verify bsm\n");
-
- /* verify BSM SRAM contents */
- val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
- for (reg = BSM_SRAM_LOWER_BOUND;
- reg < BSM_SRAM_LOWER_BOUND + len;
- reg += sizeof(u32), image++) {
- val = iwl3945_read_prph(priv, reg);
- if (val != le32_to_cpu(*image)) {
- IWL_ERROR("BSM uCode verification failed at "
- "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
- BSM_SRAM_LOWER_BOUND,
- reg - BSM_SRAM_LOWER_BOUND, len,
- val, le32_to_cpu(*image));
- return -EIO;
- }
- }
-
- IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
-
- return 0;
-}
-
-/**
- * iwl3945_load_bsm - Load bootstrap instructions
- *
- * BSM operation:
- *
- * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
- * in special SRAM that does not power down during RFKILL. When powering back
- * up after power-saving sleeps (or during initial uCode load), the BSM loads
- * the bootstrap program into the on-board processor, and starts it.
- *
- * The bootstrap program loads (via DMA) instructions and data for a new
- * program from host DRAM locations indicated by the host driver in the
- * BSM_DRAM_* registers. Once the new program is loaded, it starts
- * automatically.
- *
- * When initializing the NIC, the host driver points the BSM to the
- * "initialize" uCode image. This uCode sets up some internal data, then
- * notifies host via "initialize alive" that it is complete.
- *
- * The host then replaces the BSM_DRAM_* pointer values to point to the
- * normal runtime uCode instructions and a backup uCode data cache buffer
- * (filled initially with starting data values for the on-board processor),
- * then triggers the "initialize" uCode to load and launch the runtime uCode,
- * which begins normal operation.
- *
- * When doing a power-save shutdown, runtime uCode saves data SRAM into
- * the backup data cache in DRAM before SRAM is powered down.
- *
- * When powering back up, the BSM loads the bootstrap program. This reloads
- * the runtime uCode instructions and the backup data cache into SRAM,
- * and re-launches the runtime uCode from where it left off.
- */
-static int iwl3945_load_bsm(struct iwl3945_priv *priv)
-{
- __le32 *image = priv->ucode_boot.v_addr;
- u32 len = priv->ucode_boot.len;
- dma_addr_t pinst;
- dma_addr_t pdata;
- u32 inst_len;
- u32 data_len;
- int rc;
- int i;
- u32 done;
- u32 reg_offset;
-
- IWL_DEBUG_INFO("Begin load bsm\n");
-
- /* make sure bootstrap program is no larger than BSM's SRAM size */
- if (len > IWL_MAX_BSM_SIZE)
- return -EINVAL;
-
- /* Tell bootstrap uCode where to find the "Initialize" uCode
- * in host DRAM ... host DRAM physical address bits 31:0 for 3945.
- * NOTE: iwl3945_initialize_alive_start() will replace these values,
- * after the "initialize" uCode has run, to point to
- * runtime/protocol instructions and backup data cache. */
- pinst = priv->ucode_init.p_addr;
- pdata = priv->ucode_init_data.p_addr;
- inst_len = priv->ucode_init.len;
- data_len = priv->ucode_init_data.len;
-
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- return rc;
-
- iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
- iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
-
- /* Fill BSM memory with bootstrap instructions */
- for (reg_offset = BSM_SRAM_LOWER_BOUND;
- reg_offset < BSM_SRAM_LOWER_BOUND + len;
- reg_offset += sizeof(u32), image++)
- _iwl3945_write_prph(priv, reg_offset,
- le32_to_cpu(*image));
-
- rc = iwl3945_verify_bsm(priv);
- if (rc) {
- iwl3945_release_nic_access(priv);
- return rc;
- }
-
- /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
- iwl3945_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
- iwl3945_write_prph(priv, BSM_WR_MEM_DST_REG,
- RTC_INST_LOWER_BOUND);
- iwl3945_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
-
- /* Load bootstrap code into instruction SRAM now,
- * to prepare to load "initialize" uCode */
- iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
- BSM_WR_CTRL_REG_BIT_START);
-
- /* Wait for load of bootstrap uCode to finish */
- for (i = 0; i < 100; i++) {
- done = iwl3945_read_prph(priv, BSM_WR_CTRL_REG);
- if (!(done & BSM_WR_CTRL_REG_BIT_START))
- break;
- udelay(10);
- }
- if (i < 100)
- IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
- else {
- IWL_ERROR("BSM write did not complete!\n");
- return -EIO;
- }
-
- /* Enable future boot loads whenever power management unit triggers it
- * (e.g. when powering back up after power-save shutdown) */
- iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
- BSM_WR_CTRL_REG_BIT_START_EN);
-
- iwl3945_release_nic_access(priv);
-
- return 0;
-}
-
-static void iwl3945_nic_start(struct iwl3945_priv *priv)
+static void iwl3945_nic_start(struct iwl_priv *priv)
{
/* Remove all resets to allow NIC to operate */
- iwl3945_write32(priv, CSR_RESET, 0);
+ iwl_write32(priv, CSR_RESET, 0);
}
/**
@@ -5302,9 +2500,9 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv)
*
* Copy into buffers for card to fetch via bus-mastering
*/
-static int iwl3945_read_ucode(struct iwl3945_priv *priv)
+static int iwl3945_read_ucode(struct iwl_priv *priv)
{
- struct iwl3945_ucode *ucode;
+ struct iwl_ucode *ucode;
int ret = -EINVAL, index;
const struct firmware *ucode_raw;
/* firmware file name contains uCode/driver compatibility version */
@@ -5322,7 +2520,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
sprintf(buf, "%s%u%s", name_pre, index, ".ucode");
ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
if (ret < 0) {
- IWL_ERROR("%s firmware file req failed: Reason %d\n",
+ IWL_ERR(priv, "%s firmware file req failed: %d\n",
buf, ret);
if (ret == -ENOENT)
continue;
@@ -5330,9 +2528,12 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
goto error;
} else {
if (index < api_max)
- IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+ IWL_ERR(priv, "Loaded firmware %s, "
+ "which is deprecated. "
+ " Please use API v%u instead.\n",
buf, api_max);
- IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
+ IWL_DEBUG_INFO(priv, "Got firmware '%s' file "
+ "(%zd bytes) from disk\n",
buf, ucode_raw->size);
break;
}
@@ -5343,7 +2544,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
/* Make sure that we got at least our header! */
if (ucode_raw->size < sizeof(*ucode)) {
- IWL_ERROR("File size way too small!\n");
+ IWL_ERR(priv, "File size way too small!\n");
ret = -EINVAL;
goto err_release;
}
@@ -5364,7 +2565,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
* on the API version read from firware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
- IWL_ERROR("Driver unable to support your firmware API. "
+ IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
api_max, api_ver);
priv->ucode_ver = 0;
@@ -5372,23 +2573,29 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
goto err_release;
}
if (api_ver != api_max)
- IWL_ERROR("Firmware has old API version. Expected %u, "
+ IWL_ERR(priv, "Firmware has old API version. Expected %u, "
"got %u. New firmware can be obtained "
"from http://www.intellinuxwireless.org.\n",
api_max, api_ver);
- printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
- IWL_UCODE_MAJOR(priv->ucode_ver),
- IWL_UCODE_MINOR(priv->ucode_ver),
- IWL_UCODE_API(priv->ucode_ver),
- IWL_UCODE_SERIAL(priv->ucode_ver));
- IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
+ IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
+ IWL_UCODE_MAJOR(priv->ucode_ver),
+ IWL_UCODE_MINOR(priv->ucode_ver),
+ IWL_UCODE_API(priv->ucode_ver),
+ IWL_UCODE_SERIAL(priv->ucode_ver));
+
+ IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
priv->ucode_ver);
- IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size);
- IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size);
- IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size);
- IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size);
- IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
+ inst_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
+ data_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
+ init_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
+ init_data_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
+ boot_size);
/* Verify size of file vs. image size info in file's header */
@@ -5396,40 +2603,43 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
inst_size + data_size + init_size +
init_data_size + boot_size) {
- IWL_DEBUG_INFO("uCode file size %d too small\n",
- (int)ucode_raw->size);
+ IWL_DEBUG_INFO(priv, "uCode file size %zd too small\n",
+ ucode_raw->size);
ret = -EINVAL;
goto err_release;
}
/* Verify that uCode images will fit in card's SRAM */
- if (inst_size > IWL_MAX_INST_SIZE) {
- IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
+ if (inst_size > IWL39_MAX_INST_SIZE) {
+ IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
inst_size);
ret = -EINVAL;
goto err_release;
}
- if (data_size > IWL_MAX_DATA_SIZE) {
- IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
+ if (data_size > IWL39_MAX_DATA_SIZE) {
+ IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
data_size);
ret = -EINVAL;
goto err_release;
}
- if (init_size > IWL_MAX_INST_SIZE) {
- IWL_DEBUG_INFO("uCode init instr len %d too large to fit in\n",
+ if (init_size > IWL39_MAX_INST_SIZE) {
+ IWL_DEBUG_INFO(priv,
+ "uCode init instr len %d too large to fit in\n",
init_size);
ret = -EINVAL;
goto err_release;
}
- if (init_data_size > IWL_MAX_DATA_SIZE) {
- IWL_DEBUG_INFO("uCode init data len %d too large to fit in\n",
+ if (init_data_size > IWL39_MAX_DATA_SIZE) {
+ IWL_DEBUG_INFO(priv,
+ "uCode init data len %d too large to fit in\n",
init_data_size);
ret = -EINVAL;
goto err_release;
}
- if (boot_size > IWL_MAX_BSM_SIZE) {
- IWL_DEBUG_INFO("uCode boot instr len %d too large to fit in\n",
+ if (boot_size > IWL39_MAX_BSM_SIZE) {
+ IWL_DEBUG_INFO(priv,
+ "uCode boot instr len %d too large to fit in\n",
boot_size);
ret = -EINVAL;
goto err_release;
@@ -5479,16 +2689,18 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
/* Runtime instructions (first block of data in file) */
src = &ucode->data[0];
len = priv->ucode_code.len;
- IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) uCode instr len %zd\n", len);
memcpy(priv->ucode_code.v_addr, src, len);
- IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
+ IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
/* Runtime data (2nd block)
* NOTE: Copy into backup buffer will be done in iwl3945_up() */
src = &ucode->data[inst_size];
len = priv->ucode_data.len;
- IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) uCode data len %zd\n", len);
memcpy(priv->ucode_data.v_addr, src, len);
memcpy(priv->ucode_data_backup.v_addr, src, len);
@@ -5496,8 +2708,8 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
if (init_size) {
src = &ucode->data[inst_size + data_size];
len = priv->ucode_init.len;
- IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n",
- len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) init instr len %zd\n", len);
memcpy(priv->ucode_init.v_addr, src, len);
}
@@ -5505,16 +2717,16 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
if (init_data_size) {
src = &ucode->data[inst_size + data_size + init_size];
len = priv->ucode_init_data.len;
- IWL_DEBUG_INFO("Copying (but not loading) init data len %d\n",
- (int)len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) init data len %zd\n", len);
memcpy(priv->ucode_init_data.v_addr, src, len);
}
/* Bootstrap instructions (5th block) */
src = &ucode->data[inst_size + data_size + init_size + init_data_size];
len = priv->ucode_boot.len;
- IWL_DEBUG_INFO("Copying (but not loading) boot instr len %d\n",
- (int)len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) boot instr len %zd\n", len);
memcpy(priv->ucode_boot.v_addr, src, len);
/* We have our copies now, allow OS release its copies */
@@ -5522,7 +2734,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
return 0;
err_pci_alloc:
- IWL_ERROR("failed to allocate pci memory\n");
+ IWL_ERR(priv, "failed to allocate pci memory\n");
ret = -ENOMEM;
iwl3945_dealloc_ucode_pci(priv);
@@ -5543,7 +2755,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
* We need to replace them to load runtime uCode inst and data,
* and to save runtime data when powering down.
*/
-static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
+static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
{
dma_addr_t pinst;
dma_addr_t pdata;
@@ -5555,28 +2767,28 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
pdata = priv->ucode_data_backup.p_addr;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ 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 */
- iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+ 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_DATA_BYTECOUNT_REG,
priv->ucode_data.len);
/* Inst byte count must be last to set up, bit 31 signals uCode
* that all new ptr/size info is in place */
- iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+ iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
priv->ucode_code.len | BSM_DRAM_INST_LOAD);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
+ IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
return rc;
}
@@ -5588,13 +2800,13 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
*
* Tell "initialize" uCode to go ahead and load the runtime uCode.
*/
-static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
+static void iwl3945_init_alive_start(struct iwl_priv *priv)
{
/* Check alive response for "valid" sign from uCode */
if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
goto restart;
}
@@ -5604,18 +2816,18 @@ static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
if (iwl3945_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
goto restart;
}
/* Send pointers to protocol/runtime uCode image ... init code will
* load and launch runtime uCode, which will send us another "Alive"
* notification. */
- IWL_DEBUG_INFO("Initialization Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
if (iwl3945_set_ucode_ptrs(priv)) {
/* Runtime instruction load won't happen;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
+ IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
goto restart;
}
return;
@@ -5634,18 +2846,18 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
* from protocol/runtime uCode (initialization uCode's
* Alive gets handled by iwl3945_init_alive_start()).
*/
-static void iwl3945_alive_start(struct iwl3945_priv *priv)
+static void iwl3945_alive_start(struct iwl_priv *priv)
{
int rc = 0;
int thermal_spin = 0;
u32 rfkill;
- IWL_DEBUG_INFO("Runtime Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
if (priv->card_alive.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Alive failed.\n");
goto restart;
}
@@ -5655,21 +2867,21 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
if (iwl3945_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad runtime uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
goto restart;
}
iwl3945_clear_stations_table(priv);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read RFKILL status from adapter\n");
+ IWL_WARN(priv, "Can not read RFKILL status from adapter\n");
return;
}
- rfkill = iwl3945_read_prph(priv, APMG_RFKILL_REG);
- IWL_DEBUG_INFO("RFKILL status: 0x%x\n", rfkill);
- iwl3945_release_nic_access(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);
@@ -5681,7 +2893,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
}
if (thermal_spin)
- IWL_DEBUG_INFO("Thermal calibration took %dus\n",
+ IWL_DEBUG_INFO(priv, "Thermal calibration took %dus\n",
thermal_spin * 10);
} else
set_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -5692,7 +2904,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
/* Clear out the uCode error bit if it is set */
clear_bit(STATUS_FW_ERROR, &priv->status);
- if (iwl3945_is_rfkill(priv))
+ if (iwl_is_rfkill(priv))
return;
ieee80211_wake_queues(priv->hw);
@@ -5700,9 +2912,9 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
priv->active_rate = priv->rates_mask;
priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
- iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
+ iwl_power_update_mode(priv, false);
- if (iwl3945_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
struct iwl3945_rxon_cmd *active_rxon =
(struct iwl3945_rxon_cmd *)(&priv->active_rxon);
@@ -5711,12 +2923,11 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
- iwl3945_connection_init_rx_config(priv, priv->iw_mode);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+ iwl_connection_init_rx_config(priv, priv->iw_mode);
}
/* Configure Bluetooth device coexistence support */
- iwl3945_send_bt_config(priv);
+ iwl_send_bt_config(priv);
/* Configure the adapter for unassociated operation */
iwl3945_commit_rxon(priv);
@@ -5725,7 +2936,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
iwl3945_led_register(priv);
- IWL_DEBUG_INFO("ALIVE processing complete.\n");
+ IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
@@ -5746,15 +2957,15 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
queue_work(priv->workqueue, &priv->restart);
}
-static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv);
+static void iwl3945_cancel_deferred_work(struct iwl_priv *priv);
-static void __iwl3945_down(struct iwl3945_priv *priv)
+static void __iwl3945_down(struct iwl_priv *priv)
{
unsigned long flags;
int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
struct ieee80211_conf *conf = NULL;
- IWL_DEBUG_INFO(DRV_NAME " is going down\n");
+ IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
conf = ieee80211_get_hw_conf(priv->hw);
@@ -5773,11 +2984,11 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
clear_bit(STATUS_EXIT_PENDING, &priv->status);
/* stop and reset the on-board processor */
- iwl3945_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
/* tell the device to stop sending interrupts */
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_disable_interrupts(priv);
+ iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
iwl_synchronize_irq(priv);
@@ -5786,7 +2997,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
/* If we have not previously called iwl3945_init() then
* clear all bits but the RF Kill and SUSPEND bits and return */
- if (!iwl3945_is_init(priv)) {
+ 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) <<
@@ -5815,29 +3026,31 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
+ priv->cfg->ops->lib->apm_ops.reset(priv);
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_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);
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_stop(priv);
iwl3945_hw_rxq_stop(priv);
spin_lock_irqsave(&priv->lock, flags);
- if (!iwl3945_grab_nic_access(priv)) {
- iwl3945_write_prph(priv, APMG_CLK_DIS_REG,
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write_prph(priv, APMG_CLK_DIS_REG,
APMG_CLK_VAL_DMA_CLK_RQT);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
spin_unlock_irqrestore(&priv->lock, flags);
udelay(5);
- iwl3945_hw_nic_stop_master(priv);
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
- iwl3945_hw_nic_reset(priv);
+ if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ priv->cfg->ops->lib->apm_ops.stop(priv);
+ else
+ priv->cfg->ops->lib->apm_ops.reset(priv);
exit:
- memset(&priv->card_alive, 0, sizeof(struct iwl3945_alive_resp));
+ memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
@@ -5847,7 +3060,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
iwl3945_clear_free_frames(priv);
}
-static void iwl3945_down(struct iwl3945_priv *priv)
+static void iwl3945_down(struct iwl_priv *priv)
{
mutex_lock(&priv->mutex);
__iwl3945_down(priv);
@@ -5858,58 +3071,58 @@ static void iwl3945_down(struct iwl3945_priv *priv)
#define MAX_HW_RESTARTS 5
-static int __iwl3945_up(struct iwl3945_priv *priv)
+static int __iwl3945_up(struct iwl_priv *priv)
{
int rc, i;
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_WARNING("Exit pending; will not bring the NIC up\n");
+ IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
}
if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARNING("Radio disabled by SW RF kill (module "
+ 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_ERROR("ucode not available for device bring up\n");
+ IWL_ERR(priv, "ucode not available for device bring up\n");
return -EIO;
}
/* If platform's RF_KILL switch is NOT set to KILL */
- if (iwl3945_read32(priv, CSR_GP_CNTRL) &
+ 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_IN_SUSPEND, &priv->status)) {
- IWL_WARNING("Radio disabled by HW RF Kill switch\n");
+ IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
return -ENODEV;
}
}
- iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
rc = iwl3945_hw_nic_init(priv);
if (rc) {
- IWL_ERROR("Unable to int nic\n");
+ IWL_ERR(priv, "Unable to int nic\n");
return rc;
}
/* make sure rfkill handshake bits are cleared */
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
/* clear (again), then enable host interrupts */
- iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
- iwl3945_enable_interrupts(priv);
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_enable_interrupts(priv);
/* really make sure rfkill handshake bits are cleared */
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
/* Copy original ucode data image from disk into backup cache.
* This will be used to initialize the on-board processor's
@@ -5928,17 +3141,18 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
- rc = iwl3945_load_bsm(priv);
+ priv->cfg->ops->lib->load_ucode(priv);
if (rc) {
- IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc);
+ IWL_ERR(priv,
+ "Unable to set up bootstrap uCode: %d\n", rc);
continue;
}
/* start card; "initialize" will load runtime ucode */
iwl3945_nic_start(priv);
- IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
+ IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
return 0;
}
@@ -5949,7 +3163,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
/* tried to restart and config the device for as long as our
* patience could withstand */
- IWL_ERROR("Unable to initialize device after %d attempts.\n", i);
+ IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
return -EIO;
}
@@ -5962,8 +3176,8 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
static void iwl3945_bg_init_alive_start(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, init_alive_start.work);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, init_alive_start.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -5975,8 +3189,8 @@ static void iwl3945_bg_init_alive_start(struct work_struct *data)
static void iwl3945_bg_alive_start(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, alive_start.work);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, alive_start.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -5986,66 +3200,31 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl3945_bg_rf_kill(struct work_struct *work)
+static void iwl3945_rfkill_poll(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, rf_kill);
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, rfkill_poll.work);
+ unsigned long status = priv->status;
- mutex_lock(&priv->mutex);
+ 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 (!iwl3945_is_rfkill(priv)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
- "HW and/or SW RF Kill no longer active, restarting "
- "device\n");
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- queue_work(priv->workqueue, &priv->restart);
- } else {
+ if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status))
+ queue_work(priv->workqueue, &priv->rf_kill);
- if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by SW switch\n");
- else
- IWL_WARNING("Radio Frequency Kill Switch is On:\n"
- "Kill switch must be turned off for "
- "wireless networking to work.\n");
- }
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ round_jiffies_relative(2 * HZ));
- mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
}
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-
-static void iwl3945_bg_scan_check(struct work_struct *data)
-{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, scan_check.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) ||
- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
- "Scan completion watchdog resetting adapter (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- iwl3945_send_scan_abort(priv);
- }
- mutex_unlock(&priv->mutex);
-}
-
static void iwl3945_bg_request_scan(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, request_scan);
- struct iwl3945_host_cmd cmd = {
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, request_scan);
+ struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
.len = sizeof(struct iwl3945_scan_cmd),
.meta.flags = CMD_SIZE_HUGE,
@@ -6061,8 +3240,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
mutex_lock(&priv->mutex);
- if (!iwl3945_is_ready(priv)) {
- IWL_WARNING("request scan called when driver not ready.\n");
+ if (!iwl_is_ready(priv)) {
+ IWL_WARN(priv, "request scan called when driver not ready.\n");
goto done;
}
@@ -6074,34 +3253,36 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
/* This should never be called or scheduled if there is currently
* a scan active in the hardware. */
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
- "Ignoring second request.\n");
+ IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests "
+ "Ignoring second request.\n");
rc = -EIO;
goto done;
}
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
+ IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
goto done;
}
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");
+ IWL_DEBUG_HC(priv,
+ "Scan request while abort pending. Queuing.\n");
goto done;
}
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
goto done;
}
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");
+ IWL_DEBUG_HC(priv,
+ "Scan request while uninitialized. Queuing.\n");
goto done;
}
if (!priv->scan_bands) {
- IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
+ IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
goto done;
}
@@ -6119,14 +3300,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
- if (iwl3945_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
u16 interval = 0;
u32 extra;
u32 suspend_time = 100;
u32 scan_suspend_time = 100;
unsigned long flags;
- IWL_DEBUG_INFO("Scanning while associated...\n");
+ IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
spin_lock_irqsave(&priv->lock, flags);
interval = priv->beacon_int;
@@ -6148,15 +3329,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
(extra | ((suspend_time % interval) * 1024));
scan->suspend_time = cpu_to_le32(scan_suspend_time);
- IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
+ IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
scan_suspend_time, interval);
}
/* We should add the ability for user to lock to PASSIVE ONLY */
if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN
- ("Kicking off one direct scan for '%s'\n",
- print_ssid(ssid, priv->direct_ssid,
+ 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;
@@ -6164,15 +3344,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
priv->direct_ssid, priv->direct_ssid_len);
n_probes++;
} else
- IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
+ IWL_DEBUG_SCAN(priv, "Kicking off one indirect 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 */
- scan->tx_cmd.len = cpu_to_le16(
- iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan)));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
+ scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
/* flags + rate selection */
@@ -6187,10 +3364,15 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->good_CRC_th = IWL_GOOD_CRC_TH;
band = IEEE80211_BAND_5GHZ;
} else {
- IWL_WARNING("Invalid scan band count\n");
+ IWL_WARN(priv, "Invalid scan band count\n");
goto done;
}
+ scan->tx_cmd.len = cpu_to_le16(
+ iwl_fill_probe_req(priv, band,
+ (struct ieee80211_mgmt *)scan->data,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+
/* select Rx antennas */
scan->flags |= iwl3945_get_antenna_flags(priv);
@@ -6203,7 +3385,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
- IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+ IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
goto done;
}
@@ -6213,7 +3395,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->len = cpu_to_le16(cmd.len);
set_bit(STATUS_SCAN_HW, &priv->status);
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
goto done;
@@ -6239,7 +3421,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
static void iwl3945_bg_up(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, up);
+ struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6247,12 +3429,12 @@ static void iwl3945_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
+ iwl_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_restart(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, restart);
+ struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6263,8 +3445,8 @@ static void iwl3945_bg_restart(struct work_struct *data)
static void iwl3945_bg_rx_replenish(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, rx_replenish);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, rx_replenish);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6276,18 +3458,18 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl3945_post_associate(struct iwl3945_priv *priv)
+static void iwl3945_post_associate(struct iwl_priv *priv)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- IWL_ERROR("%s Should not be called in AP mode\n", __func__);
+ IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
- IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
priv->assoc_id, priv->active_rxon.bssid_addr);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -6296,26 +3478,26 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
if (!priv->vif || !priv->is_open)
return;
- iwl3945_scan_cancel_timeout(priv, 200);
+ iwl_scan_cancel_timeout(priv, 200);
conf = ieee80211_get_hw_conf(priv->hw);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
- memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+ memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (rc)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
- IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n",
+ IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
priv->assoc_id, priv->beacon_int);
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -6355,56 +3537,19 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
break;
default:
- IWL_ERROR("%s Should not be called in %d mode\n",
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
__func__, priv->iw_mode);
break;
}
- iwl3945_activate_qos(priv, 0);
+ iwl_activate_qos(priv, 0);
/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
-static void iwl3945_bg_abort_scan(struct work_struct *work)
-{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, abort_scan);
-
- if (!iwl3945_is_ready(priv))
- return;
-
- mutex_lock(&priv->mutex);
-
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- iwl3945_send_scan_abort(priv);
-
- mutex_unlock(&priv->mutex);
-}
-
static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
-static void iwl3945_bg_scan_completed(struct work_struct *work)
-{
- struct iwl3945_priv *priv =
- container_of(work, struct iwl3945_priv, scan_completed);
-
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (test_bit(STATUS_CONF_PENDING, &priv->status))
- iwl3945_mac_config(priv->hw, 0);
-
- ieee80211_scan_completed(priv->hw);
-
- /* Since setting the TXPOWER may have been deferred while
- * performing the scan, fire one off */
- mutex_lock(&priv->mutex);
- iwl3945_hw_reg_send_txpower(priv);
- mutex_unlock(&priv->mutex);
-}
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -6415,36 +3560,22 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
static int iwl3945_mac_start(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int ret;
- IWL_DEBUG_MAC80211("enter\n");
-
- if (pci_enable_device(priv->pci_dev)) {
- IWL_ERROR("Fail to pci_enable_device\n");
- return -ENODEV;
- }
- pci_restore_state(priv->pci_dev);
- pci_enable_msi(priv->pci_dev);
-
- ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED,
- DRV_NAME, priv);
- if (ret) {
- IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
- goto out_disable_msi;
- }
+ IWL_DEBUG_MAC80211(priv, "enter\n");
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
- memset(&priv->staging_rxon, 0, sizeof(struct iwl3945_rxon_cmd));
+ memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */
if (!priv->ucode_code.len) {
ret = iwl3945_read_ucode(priv);
if (ret) {
- IWL_ERROR("Could not read microcode: %d\n", ret);
+ IWL_ERR(priv, "Could not read microcode: %d\n", ret);
mutex_unlock(&priv->mutex);
goto out_release_irq;
}
@@ -6454,12 +3585,12 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
+ iwl_rfkill_set_hw_state(priv);
if (ret)
goto out_release_irq;
- IWL_DEBUG_INFO("Start UP work.\n");
+ IWL_DEBUG_INFO(priv, "Start UP work.\n");
if (test_bit(STATUS_IN_SUSPEND, &priv->status))
return 0;
@@ -6471,86 +3602,87 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
UCODE_READY_TIMEOUT);
if (!ret) {
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n",
- jiffies_to_msecs(UCODE_READY_TIMEOUT));
+ IWL_ERR(priv,
+ "Wait for START_ALIVE timeout after %dms.\n",
+ jiffies_to_msecs(UCODE_READY_TIMEOUT));
ret = -ETIMEDOUT;
goto out_release_irq;
}
}
+ /* ucode is running and will send rfkill notifications,
+ * no need to poll the killswitch state anymore */
+ cancel_delayed_work(&priv->rfkill_poll);
+
priv->is_open = 1;
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
out_release_irq:
- free_irq(priv->pci_dev->irq, priv);
-out_disable_msi:
- pci_disable_msi(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
priv->is_open = 0;
- IWL_DEBUG_MAC80211("leave - failed\n");
+ IWL_DEBUG_MAC80211(priv, "leave - failed\n");
return ret;
}
static void iwl3945_mac_stop(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!priv->is_open) {
- IWL_DEBUG_MAC80211("leave - skip\n");
+ IWL_DEBUG_MAC80211(priv, "leave - skip\n");
return;
}
priv->is_open = 0;
- if (iwl3945_is_ready_rf(priv)) {
+ if (iwl_is_ready_rf(priv)) {
/* stop mac, cancel any scan request and clear
* RXON_FILTER_ASSOC_MSK BIT
*/
mutex_lock(&priv->mutex);
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
mutex_unlock(&priv->mutex);
}
iwl3945_down(priv);
flush_workqueue(priv->workqueue);
- free_irq(priv->pci_dev->irq, priv);
- pci_disable_msi(priv->pci_dev);
- pci_save_state(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
- IWL_DEBUG_MAC80211("leave\n");
+ /* start polling the killswitch state again */
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ round_jiffies_relative(2 * HZ));
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
+ IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
if (iwl3945_tx_skb(priv, skb))
dev_kfree_skb_any(skb);
- IWL_DEBUG_MAC80211("leave\n");
- return 0;
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+ return NETDEV_TX_OK;
}
static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
- IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
+ IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
if (priv->vif) {
- IWL_DEBUG_MAC80211("leave - vif != NULL\n");
+ IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
return -EOPNOTSUPP;
}
@@ -6563,16 +3695,16 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (conf->mac_addr) {
- IWL_DEBUG_MAC80211("Set: %pM\n", conf->mac_addr);
+ IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr);
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
}
- if (iwl3945_is_ready(priv))
+ if (iwl_is_ready(priv))
iwl3945_set_mode(priv, conf->type);
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -6585,24 +3717,25 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
*/
static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
{
- struct iwl3945_priv *priv = hw->priv;
- const struct iwl3945_channel_info *ch_info;
+ 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("enter to channel %d\n", conf->channel->hw_value);
+ IWL_DEBUG_MAC80211(priv, "enter to channel %d\n",
+ conf->channel->hw_value);
- if (!iwl3945_is_ready(priv)) {
- IWL_DEBUG_MAC80211("leave - not ready\n");
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
ret = -EIO;
goto out;
}
- if (unlikely(!iwl3945_param_disable_hw_scan &&
+ if (unlikely(!iwl3945_mod_params.disable_hw_scan &&
test_bit(STATUS_SCANNING, &priv->status))) {
- IWL_DEBUG_MAC80211("leave - scanning\n");
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
set_bit(STATUS_CONF_PENDING, &priv->status);
mutex_unlock(&priv->mutex);
return 0;
@@ -6610,25 +3743,26 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
spin_lock_irqsave(&priv->lock, flags);
- ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
- conf->channel->hw_value);
+ ch_info = iwl_get_channel_info(priv, conf->channel->band,
+ conf->channel->hw_value);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
- conf->channel->hw_value, conf->channel->band);
- IWL_DEBUG_MAC80211("leave - invalid channel\n");
+ 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;
}
- iwl3945_set_rxon_channel(priv, conf->channel->band, conf->channel->hw_value);
+ iwl_set_rxon_channel(priv, conf->channel);
- iwl3945_set_flags_for_phymode(priv, conf->channel->band);
+ 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 */
- iwl3945_set_rate(priv);
+ iwl_set_rate(priv);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -6639,28 +3773,32 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
}
#endif
- iwl3945_radio_kill_sw(priv, !conf->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_DEBUG_MAC80211("leave - radio disabled\n");
+ iwl_radio_kill_sw_disable_radio(priv);
+ IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
goto out;
}
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_MAC80211("leave - RF kill\n");
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
ret = -EIO;
goto out;
}
- iwl3945_set_rate(priv);
+ iwl_set_rate(priv);
if (memcmp(&priv->active_rxon,
&priv->staging_rxon, sizeof(priv->staging_rxon)))
iwl3945_commit_rxon(priv);
else
- IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
+ IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n");
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
out:
clear_bit(STATUS_CONF_PENDING, &priv->status);
@@ -6668,7 +3806,7 @@ out:
return ret;
}
-static void iwl3945_config_ap(struct iwl3945_priv *priv)
+static void iwl3945_config_ap(struct iwl_priv *priv)
{
int rc = 0;
@@ -6676,19 +3814,20 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
return;
/* The following should be done only at AP bring up */
- if (!(iwl3945_is_associated(priv))) {
+ if (!(iwl_is_associated(priv))) {
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
/* RXON Timing */
- memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+ memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+ sizeof(priv->rxon_timing),
+ &priv->rxon_timing);
if (rc)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
/* FIXME: what should be the assoc_id for AP? */
@@ -6716,7 +3855,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
- iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
+ iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
}
iwl3945_send_beacon_cmd(priv);
@@ -6727,16 +3866,16 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
+ struct ieee80211_if_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int rc;
if (conf == NULL)
return -EIO;
if (priv->vif != vif) {
- IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
+ IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
return 0;
}
@@ -6753,13 +3892,13 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
return rc;
}
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
mutex_lock(&priv->mutex);
if (conf->bssid)
- IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
+ IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
/*
* very dubious code was here; the probe filtering flag is never set:
@@ -6772,7 +3911,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
if (!conf->bssid) {
conf->bssid = priv->mac_addr;
memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+ IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
conf->bssid);
}
if (priv->ibss_beacon)
@@ -6781,17 +3920,17 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
- if (iwl3945_is_rfkill(priv))
+ 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 (iwl3945_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress "
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress "
"after 100ms\n");
- IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+ IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n");
mutex_unlock(&priv->mutex);
return -EAGAIN;
}
@@ -6813,75 +3952,29 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
}
} else {
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
done:
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
mutex_unlock(&priv->mutex);
return 0;
}
-static void iwl3945_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- int mc_count, struct dev_addr_list *mc_list)
-{
- struct iwl3945_priv *priv = hw->priv;
- __le32 *filter_flags = &priv->staging_rxon.filter_flags;
-
- IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
- changed_flags, *total_flags);
-
- if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
- if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
- *filter_flags |= RXON_FILTER_PROMISC_MSK;
- else
- *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
- }
- if (changed_flags & FIF_ALLMULTI) {
- if (*total_flags & FIF_ALLMULTI)
- *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
- else
- *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
- }
- if (changed_flags & FIF_CONTROL) {
- if (*total_flags & FIF_CONTROL)
- *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
- else
- *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
- }
- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
- *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
- else
- *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
- }
-
- /* We avoid iwl_commit_rxon here to commit the new filter flags
- * since mac80211 will call ieee80211_hw_config immediately.
- * (mc_list is not supported at this time). Otherwise, we need to
- * queue a background iwl_commit_rxon work.
- */
-
- *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
- FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
-}
-
static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
- if (iwl3945_is_ready_rf(priv)) {
- iwl3945_scan_cancel_timeout(priv, 100);
+ 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);
}
@@ -6891,7 +3984,7 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
}
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
@@ -6901,21 +3994,23 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changes)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+ IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+ 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;
+ priv->staging_rxon.flags &=
+ ~RXON_FLG_SHORT_PREAMBLE_MSK;
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_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
@@ -6923,7 +4018,7 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->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()))
@@ -6931,10 +4026,9 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
if (bss_conf->assoc) {
priv->assoc_id = bss_conf->aid;
priv->beacon_int = bss_conf->beacon_int;
- priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF;
- priv->timestamp1 = (bss_conf->timestamp >> 32) &
- 0xFFFFFFFF;
+ 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);
@@ -6942,143 +4036,91 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
} else {
priv->assoc_id = 0;
- IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+ IWL_DEBUG_MAC80211(priv,
+ "DISASSOC %d\n", bss_conf->assoc);
}
- } else if (changes && iwl3945_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+ } 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_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
-{
- int rc = 0;
- unsigned long flags;
- struct iwl3945_priv *priv = hw->priv;
- DECLARE_SSID_BUF(ssid_buf);
-
- IWL_DEBUG_MAC80211("enter\n");
-
- mutex_lock(&priv->mutex);
- spin_lock_irqsave(&priv->lock, flags);
-
- if (!iwl3945_is_ready_rf(priv)) {
- rc = -EIO;
- IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
- goto out_unlock;
- }
-
- /* we don't schedule scan within next_scan_jiffies period */
- if (priv->next_scan_jiffies &&
- time_after(priv->next_scan_jiffies, jiffies)) {
- rc = -EAGAIN;
- goto out_unlock;
- }
- /* if we just finished scan ask for delay for a broadcast scan */
- if ((len == 0) && priv->last_scan_jiffies &&
- time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN,
- jiffies)) {
- rc = -EAGAIN;
- goto out_unlock;
- }
- if (len) {
- IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
- print_ssid(ssid_buf, ssid, len), (int)len);
-
- priv->one_direct_scan = 1;
- priv->direct_ssid_len = (u8)
- min((u8) len, (u8) IW_ESSID_MAX_SIZE);
- memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
- } else
- priv->one_direct_scan = 0;
-
- rc = iwl3945_scan_initiate(priv);
-
- IWL_DEBUG_MAC80211("leave\n");
-
-out_unlock:
- spin_unlock_irqrestore(&priv->lock, flags);
- mutex_unlock(&priv->mutex);
-
- return rc;
-}
-
static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
- struct iwl3945_priv *priv = hw->priv;
- int rc = 0;
- u8 sta_id;
+ struct iwl_priv *priv = hw->priv;
+ const u8 *addr;
+ int ret = 0;
+ u8 sta_id = IWL_INVALID_STATION;
+ u8 static_key;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!iwl3945_param_hwcrypto) {
- IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
+ if (iwl3945_mod_params.sw_crypto) {
+ IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
- if (is_zero_ether_addr(addr))
- /* only support pairwise keys */
- return -EOPNOTSUPP;
+ addr = sta ? sta->addr : iwl_bcast_addr;
+ static_key = !iwl_is_associated(priv);
- sta_id = iwl3945_hw_find_station(priv, addr);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
- addr);
- return -EINVAL;
+ if (!static_key) {
+ sta_id = iwl3945_hw_find_station(priv, addr);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_DEBUG_MAC80211(priv, "leave - %pMnot in station map.\n",
+ addr);
+ return -EINVAL;
+ }
}
mutex_lock(&priv->mutex);
-
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
+ mutex_unlock(&priv->mutex);
switch (cmd) {
- case SET_KEY:
- rc = iwl3945_update_sta_key_info(priv, key, sta_id);
- if (!rc) {
- iwl3945_set_rxon_hwcrypto(priv, 1);
- iwl3945_commit_rxon(priv);
- key->hw_key_idx = sta_id;
- IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- }
+ case SET_KEY:
+ if (static_key)
+ ret = iwl3945_set_static_key(priv, key);
+ else
+ ret = iwl3945_set_dynamic_key(priv, key, sta_id);
+ IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
break;
case DISABLE_KEY:
- rc = iwl3945_clear_sta_key_info(priv, sta_id);
- if (!rc) {
- iwl3945_set_rxon_hwcrypto(priv, 0);
- iwl3945_commit_rxon(priv);
- IWL_DEBUG_MAC80211("disable hwcrypto key\n");
- }
+ if (static_key)
+ ret = iwl3945_remove_static_key(priv);
+ else
+ ret = iwl3945_clear_sta_key_info(priv, sta_id);
+ IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
break;
default:
- rc = -EINVAL;
+ ret = -EINVAL;
}
- IWL_DEBUG_MAC80211("leave\n");
- mutex_unlock(&priv->mutex);
+ IWL_DEBUG_MAC80211(priv, "leave\n");
- return rc;
+ return ret;
}
static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
int q;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\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("leave - queue >= AC_NUM %d\n", queue);
+ IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
return 0;
}
@@ -7099,29 +4141,29 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
mutex_lock(&priv->mutex);
if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl3945_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl3945_is_associated(priv))
- iwl3945_activate_qos(priv, 0);
+ 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("leave\n");
+ 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 iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int i, avail;
- struct iwl3945_tx_queue *txq;
- struct iwl3945_queue *q;
+ struct iwl_tx_queue *txq;
+ struct iwl_queue *q;
unsigned long flags;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
@@ -7130,7 +4172,7 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
for (i = 0; i < AC_NUM; i++) {
txq = &priv->txq[i];
q = &txq->q;
- avail = iwl3945_queue_space(q);
+ avail = iwl_queue_space(q);
stats[i].len = q->n_window - avail;
stats[i].limit = q->n_window - q->high_mark;
@@ -7139,34 +4181,24 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
}
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_MAC80211("leave\n");
-
- return 0;
-}
-
-static int iwl3945_mac_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats)
-{
- IWL_DEBUG_MAC80211("enter\n");
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- iwl3945_reset_qos(priv);
+ iwl_reset_qos(priv);
spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = 0;
priv->assoc_capability = 0;
- priv->call_post_assoc_from_beacon = 0;
/* new association get rid of ibss beacon skb */
if (priv->ibss_beacon)
@@ -7175,15 +4207,14 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
priv->ibss_beacon = NULL;
priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp1 = 0;
- priv->timestamp0 = 0;
+ priv->timestamp = 0;
if ((priv->iw_mode == NL80211_IFTYPE_STATION))
priv->beacon_int = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - not ready\n");
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
mutex_unlock(&priv->mutex);
return;
}
@@ -7192,7 +4223,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
* clear RXON_FILTER_ASSOC_MSK bit
*/
if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
@@ -7200,33 +4231,34 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
/* Per mac80211.h: This is only used in IBSS mode... */
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211("leave - not in IBSS\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
mutex_unlock(&priv->mutex);
return;
}
- iwl3945_set_rate(priv);
+ iwl_set_rate(priv);
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
+ __le64 timestamp;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\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("leave - not IBSS\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
return -EIO;
}
@@ -7238,11 +4270,13 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
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("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
- iwl3945_reset_qos(priv);
+ iwl_reset_qos(priv);
iwl3945_post_associate(priv);
@@ -7256,7 +4290,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
*
*****************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
/*
* The following adds a new attribute to the sysfs representation
@@ -7265,38 +4299,41 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
*
* See the level definitions in iwl for details.
*/
-
-static ssize_t show_debug_level(struct device_driver *d, char *buf)
+static ssize_t show_debug_level(struct device *d,
+ struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "0x%08X\n", iwl3945_debug_level);
+ struct iwl_priv *priv = d->driver_data;
+
+ return sprintf(buf, "0x%08X\n", priv->debug_level);
}
-static ssize_t store_debug_level(struct device_driver *d,
+static ssize_t store_debug_level(struct device *d,
+ struct device_attribute *attr,
const char *buf, size_t count)
{
- char *p = (char *)buf;
- u32 val;
+ struct iwl_priv *priv = d->driver_data;
+ unsigned long val;
+ int ret;
- val = simple_strtoul(p, &p, 0);
- if (p == buf)
- printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret)
+ IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf);
else
- iwl3945_debug_level = val;
+ priv->debug_level = val;
return strnlen(buf, count);
}
-static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
- show_debug_level, store_debug_level);
+static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
+ show_debug_level, store_debug_level);
-#endif /* CONFIG_IWL3945_DEBUG */
+#endif /* CONFIG_IWLWIFI_DEBUG */
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv));
@@ -7307,22 +4344,21 @@ 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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
- return sprintf(buf, "%d\n", priv->user_txpower_limit);
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
}
static ssize_t store_tx_power(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
char *p = (char *)buf;
u32 val;
val = simple_strtoul(p, &p, 10);
if (p == buf)
- printk(KERN_INFO DRV_NAME
- ": %s is not in decimal form.\n", buf);
+ IWL_INFO(priv, ": %s is not in decimal form.\n", buf);
else
iwl3945_hw_reg_set_txpower(priv, val);
@@ -7334,7 +4370,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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
}
@@ -7343,16 +4379,16 @@ static ssize_t store_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
u32 flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
/* Cancel any currently running scans... */
- if (iwl3945_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ if (iwl_scan_cancel_timeout(priv, 100))
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
+ IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
iwl3945_commit_rxon(priv);
@@ -7368,7 +4404,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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
return sprintf(buf, "0x%04X\n",
le32_to_cpu(priv->active_rxon.filter_flags));
@@ -7378,16 +4414,16 @@ static ssize_t store_filter_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
- if (iwl3945_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ if (iwl_scan_cancel_timeout(priv, 100))
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Committing rxon.filter_flags = "
+ IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
@@ -7407,8 +4443,8 @@ static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
static ssize_t show_measurement(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
- struct iwl3945_spectrum_notification measure_report;
+ struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_spectrum_notification measure_report;
u32 size = sizeof(measure_report), len = 0, ofs = 0;
u8 *data = (u8 *)&measure_report;
unsigned long flags;
@@ -7440,7 +4476,7 @@ static ssize_t store_measurement(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
struct ieee80211_measurement_params params = {
.channel = le16_to_cpu(priv->active_rxon.channel),
.start_time = cpu_to_le64(priv->last_tsf),
@@ -7464,7 +4500,7 @@ static ssize_t store_measurement(struct device *d,
type = simple_strtoul(p + 1, NULL, 0);
}
- IWL_DEBUG_INFO("Invoking measurement of type %d on "
+ IWL_DEBUG_INFO(priv, "Invoking measurement of type %d on "
"channel %d (for '%s')\n", type, params.channel, buf);
iwl3945_get_measurement(priv, &params, type);
@@ -7479,7 +4515,7 @@ static ssize_t store_retry_rate(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
priv->retry_rate = simple_strtoul(buf, NULL, 0);
if (priv->retry_rate <= 0)
@@ -7491,50 +4527,77 @@ static ssize_t store_retry_rate(struct device *d,
static ssize_t show_retry_rate(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%d", priv->retry_rate);
}
static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
store_retry_rate);
+
static ssize_t store_power_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
- int rc;
- int mode;
+ struct iwl_priv *priv = dev_get_drvdata(d);
+ int ret;
+ unsigned long mode;
+
- mode = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
- if (!iwl3945_is_ready(priv)) {
- rc = -EAGAIN;
+ if (!iwl_is_ready(priv)) {
+ ret = -EAGAIN;
goto out;
}
- if ((mode < 1) || (mode > IWL_POWER_LIMIT) || (mode == IWL_POWER_AC))
- mode = IWL_POWER_AC;
- else
- mode |= IWL_POWER_ENABLED;
+ ret = strict_strtoul(buf, 10, &mode);
+ if (ret)
+ goto out;
- if (mode != priv->power_mode) {
- rc = iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(mode));
- if (rc) {
- IWL_DEBUG_MAC80211("failed setting power mode.\n");
- goto out;
- }
- priv->power_mode = mode;
+ ret = iwl_power_set_user_mode(priv, mode);
+ if (ret) {
+ IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
+ goto out;
}
-
- rc = count;
+ ret = count;
out:
mutex_unlock(&priv->mutex);
- return rc;
+ return ret;
}
+static ssize_t show_power_level(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ 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");
+ return p - buf + 1;
+}
+
+static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR,
+ show_power_level, store_power_level);
+
#define MAX_WX_STRING 80
/* Values are in microsecond */
@@ -7553,41 +4616,6 @@ static const s32 period_duration[] = {
1000000
};
-static ssize_t show_power_level(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
- int level = IWL_POWER_LEVEL(priv->power_mode);
- char *p = buf;
-
- p += sprintf(p, "%d ", level);
- switch (level) {
- case IWL_POWER_MODE_CAM:
- case IWL_POWER_AC:
- p += sprintf(p, "(AC)");
- break;
- case IWL_POWER_BATTERY:
- p += sprintf(p, "(BATTERY)");
- break;
- default:
- p += sprintf(p,
- "(Timeout %dms, Period %dms)",
- timeout_duration[level - 1] / 1000,
- period_duration[level - 1] / 1000);
- }
-
- if (!(priv->power_mode & IWL_POWER_ENABLED))
- p += sprintf(p, " OFF\n");
- else
- p += sprintf(p, " \n");
-
- return p - buf + 1;
-
-}
-
-static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
- store_power_level);
-
static ssize_t show_channels(struct device *d,
struct device_attribute *attr, char *buf)
{
@@ -7600,17 +4628,17 @@ static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
static ssize_t show_statistics(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 size = sizeof(struct iwl3945_notif_statistics);
u32 len = 0, ofs = 0;
- u8 *data = (u8 *)&priv->statistics;
+ u8 *data = (u8 *)&priv->statistics_39;
int rc = 0;
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
mutex_lock(&priv->mutex);
- rc = iwl3945_send_statistics_request(priv);
+ rc = iwl_send_statistics_request(priv, 0);
mutex_unlock(&priv->mutex);
if (rc) {
@@ -7638,34 +4666,34 @@ static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
static ssize_t show_antenna(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
- return sprintf(buf, "%d\n", priv->antenna);
+ return sprintf(buf, "%d\n", iwl3945_mod_params.antenna);
}
static ssize_t store_antenna(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv __maybe_unused = dev_get_drvdata(d);
int ant;
- struct iwl3945_priv *priv = dev_get_drvdata(d);
if (count == 0)
return 0;
if (sscanf(buf, "%1i", &ant) != 1) {
- IWL_DEBUG_INFO("not in hex or decimal form.\n");
+ IWL_DEBUG_INFO(priv, "not in hex or decimal form.\n");
return count;
}
if ((ant >= 0) && (ant <= 2)) {
- IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
- priv->antenna = (enum iwl3945_antenna)ant;
+ IWL_DEBUG_INFO(priv, "Setting antenna select to %d.\n", ant);
+ iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant;
} else
- IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);
+ IWL_DEBUG_INFO(priv, "Bad antenna select value %d.\n", ant);
return count;
@@ -7676,8 +4704,8 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
- if (!iwl3945_is_alive(priv))
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "0x%08x\n", (int)priv->status);
}
@@ -7691,7 +4719,7 @@ static ssize_t dump_error_log(struct device *d,
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_error_log((struct iwl3945_priv *)d->driver_data);
+ iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data);
return strnlen(buf, count);
}
@@ -7705,7 +4733,7 @@ static ssize_t dump_event_log(struct device *d,
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_event_log((struct iwl3945_priv *)d->driver_data);
+ iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data);
return strnlen(buf, count);
}
@@ -7718,23 +4746,24 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
*
*****************************************************************************/
-static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
+static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
{
- priv->workqueue = create_workqueue(DRV_NAME);
+ priv->workqueue = create_singlethread_workqueue(DRV_NAME);
init_waitqueue_head(&priv->wait_command_queue);
INIT_WORK(&priv->up, iwl3945_bg_up);
INIT_WORK(&priv->restart, iwl3945_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
- INIT_WORK(&priv->scan_completed, iwl3945_bg_scan_completed);
- INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
- INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
- INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
+ INIT_WORK(&priv->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);
- INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
+ INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll);
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+ INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
+ INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+ INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
iwl3945_hw_setup_deferred_work(priv);
@@ -7742,7 +4771,7 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
iwl3945_irq_tasklet, (unsigned long)priv);
}
-static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv)
+static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
{
iwl3945_hw_cancel_deferred_work(priv);
@@ -7768,7 +4797,9 @@ static struct attribute *iwl3945_sysfs_entries[] = {
&dev_attr_status.attr,
&dev_attr_temperature.attr,
&dev_attr_tx_power.attr,
-
+#ifdef CONFIG_IWLWIFI_DEBUG
+ &dev_attr_debug_level.attr,
+#endif
NULL
};
@@ -7785,70 +4816,93 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.remove_interface = iwl3945_mac_remove_interface,
.config = iwl3945_mac_config,
.config_interface = iwl3945_mac_config_interface,
- .configure_filter = iwl3945_configure_filter,
+ .configure_filter = iwl_configure_filter,
.set_key = iwl3945_mac_set_key,
- .get_stats = iwl3945_mac_get_stats,
.get_tx_stats = iwl3945_mac_get_tx_stats,
.conf_tx = iwl3945_mac_conf_tx,
.reset_tsf = iwl3945_mac_reset_tsf,
.bss_info_changed = iwl3945_bss_info_changed,
- .hw_scan = iwl3945_mac_hw_scan
+ .hw_scan = iwl_mac_hw_scan
};
-static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int iwl3945_init_drv(struct iwl_priv *priv)
{
- int err = 0;
- struct iwl3945_priv *priv;
- struct ieee80211_hw *hw;
- struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
- unsigned long flags;
+ int ret;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
- /***********************
- * 1. Allocating HW data
- * ********************/
+ priv->retry_rate = 1;
+ priv->ibss_beacon = NULL;
- /* Disabling hardware scan means that mac80211 will perform scans
- * "the hard way", rather than using device's scan. */
- if (iwl3945_param_disable_hw_scan) {
- IWL_DEBUG_INFO("Disabling hw_scan\n");
- iwl3945_hw_ops.hw_scan = 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);
+
+ INIT_LIST_HEAD(&priv->free_frames);
+
+ mutex_init(&priv->mutex);
+
+ /* Clear the driver's (not device's) station table */
+ iwl3945_clear_stations_table(priv);
+
+ priv->data_retry_limit = -1;
+ priv->ieee_channels = NULL;
+ priv->ieee_rates = NULL;
+ priv->band = IEEE80211_BAND_2GHZ;
+
+ priv->iw_mode = NL80211_IFTYPE_STATION;
+
+ iwl_reset_qos(priv);
+
+ priv->qos_data.qos_active = 0;
+ priv->qos_data.qos_cap.val = 0;
+
+ priv->rates_mask = IWL_RATES_MASK;
+ /* If power management is turned on, default to CAM mode */
+ priv->power_mode = IWL_POWER_MODE_CAM;
+ priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
+
+ if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
+ IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
+ eeprom->version);
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = iwl_init_channel_map(priv);
+ if (ret) {
+ IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
+ goto err;
}
- if ((iwl3945_param_queues_num > IWL39_MAX_NUM_QUEUES) ||
- (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
- err = -EINVAL;
- goto out;
+ /* Set up txpower settings in driver for all channels */
+ if (iwl3945_txpower_set_from_eeprom(priv)) {
+ ret = -EIO;
+ goto err_free_channel_map;
}
- /* mac80211 allocates memory for this device instance, including
- * space for this driver's private structure */
- hw = ieee80211_alloc_hw(sizeof(struct iwl3945_priv), &iwl3945_hw_ops);
- if (hw == NULL) {
- IWL_ERROR("Can not allocate network device\n");
- err = -ENOMEM;
- goto out;
+ ret = iwlcore_init_geos(priv);
+ if (ret) {
+ IWL_ERR(priv, "initializing geos failed: %d\n", ret);
+ goto err_free_channel_map;
}
+ iwl3945_init_hw_rates(priv, priv->ieee_rates);
- SET_IEEE80211_DEV(hw, &pdev->dev);
+ return 0;
- priv = hw->priv;
- priv->hw = hw;
- priv->pci_dev = pdev;
- priv->cfg = cfg;
+err_free_channel_map:
+ iwl_free_channel_map(priv);
+err:
+ return ret;
+}
+
+static int iwl3945_setup_mac(struct iwl_priv *priv)
+{
+ int ret;
+ struct ieee80211_hw *hw = priv->hw;
- IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
hw->rate_control_algorithm = "iwl-3945-rs";
hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
- /* Select antenna (may be helpful if only one antenna is connected) */
- priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
-#ifdef CONFIG_IWL3945_DEBUG
- iwl3945_debug_level = iwl3945_param_debug;
- atomic_set(&priv->restrict_refcnt, 0);
-#endif
-
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM;
@@ -7857,11 +4911,83 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->fw_handles_regulatory = true;
+ hw->wiphy->custom_regulatory = true;
- /* 4 EDCA QOS priorities */
+ /* 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];
+
+ if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &priv->bands[IEEE80211_BAND_5GHZ];
+
+ ret = ieee80211_register_hw(priv->hw);
+ if (ret) {
+ IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
+ return ret;
+ }
+ priv->mac80211_registered = 1;
+
+ return 0;
+}
+
+static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ int err = 0;
+ struct iwl_priv *priv;
+ struct ieee80211_hw *hw;
+ struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+ struct iwl3945_eeprom *eeprom;
+ unsigned long flags;
+
+ /***********************
+ * 1. Allocating HW data
+ * ********************/
+
+ /* mac80211 allocates memory for this device instance, including
+ * space for this driver's private structure */
+ hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
+ if (hw == NULL) {
+ printk(KERN_ERR DRV_NAME "Can not allocate network device\n");
+ err = -ENOMEM;
+ goto out;
+ }
+ priv = hw->priv;
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+
+ if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) ||
+ (iwl3945_mod_params.num_of_queues < IWL_MIN_NUM_QUEUES)) {
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
+ err = -EINVAL;
+ goto out_ieee80211_free_hw;
+ }
+
+ /*
+ * Disabling hardware scan means that mac80211 will perform scans
+ * "the hard way", rather than using device's scan.
+ */
+ if (iwl3945_mod_params.disable_hw_scan) {
+ IWL_DEBUG_INFO(priv, "Disabling hw_scan\n");
+ iwl3945_hw_ops.hw_scan = NULL;
+ }
+
+
+ IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
+ priv->cfg = cfg;
+ priv->pci_dev = pdev;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ priv->debug_level = iwl3945_mod_params.debug;
+ atomic_set(&priv->restrict_refcnt, 0);
+#endif
+
/***************************
* 2. Initializing PCI bus
* *************************/
@@ -7876,7 +5002,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if (!err)
err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
- printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
+ IWL_WARN(priv, "No suitable DMA available.\n");
goto out_pci_disable_device;
}
@@ -7894,98 +5020,58 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
goto out_pci_release_regions;
}
- IWL_DEBUG_INFO("pci_resource_len = 0x%08llx\n",
+ IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n",
(unsigned long long) pci_resource_len(pdev, 0));
- IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
+ IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
/* We disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, 0x41, 0x00);
- /* nic init */
- iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- err = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ /* amp init */
+ err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
- goto out_remove_sysfs;
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
+ goto out_iounmap;
}
/***********************
* 4. Read EEPROM
* ********************/
+
/* Read the EEPROM */
- err = iwl3945_eeprom_init(priv);
+ err = iwl_eeprom_init(priv);
if (err) {
- IWL_ERROR("Unable to init EEPROM\n");
- goto out_remove_sysfs;
+ IWL_ERR(priv, "Unable to init EEPROM\n");
+ goto out_iounmap;
}
/* MAC Address location in EEPROM same for 3945/4965 */
- get_eeprom_mac(priv, priv->mac_addr);
- IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
+ eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN);
+ IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr);
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
/***********************
* 5. Setup HW Constants
* ********************/
/* Device-specific setup */
- if (iwl3945_hw_set_hw_setting(priv)) {
- IWL_ERROR("failed to set hw settings\n");
- goto out_iounmap;
+ if (iwl3945_hw_set_hw_params(priv)) {
+ IWL_ERR(priv, "failed to set hw settings\n");
+ goto out_eeprom_free;
}
/***********************
* 6. Setup priv
* ********************/
- priv->retry_rate = 1;
- 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);
-
- INIT_LIST_HEAD(&priv->free_frames);
- mutex_init(&priv->mutex);
-
- /* Clear the driver's (not device's) station table */
- iwl3945_clear_stations_table(priv);
-
- priv->data_retry_limit = -1;
- priv->ieee_channels = NULL;
- priv->ieee_rates = NULL;
- priv->band = IEEE80211_BAND_2GHZ;
- priv->iw_mode = NL80211_IFTYPE_STATION;
-
- iwl3945_reset_qos(priv);
-
- priv->qos_data.qos_active = 0;
- priv->qos_data.qos_cap.val = 0;
-
-
- priv->rates_mask = IWL_RATES_MASK;
- /* If power management is turned on, default to AC mode */
- priv->power_mode = IWL_POWER_AC;
- priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
-
- err = iwl3945_init_channel_map(priv);
- if (err) {
- IWL_ERROR("initializing regulatory failed: %d\n", err);
- goto out_release_irq;
- }
-
- err = iwl3945_init_geos(priv);
+ err = iwl3945_init_drv(priv);
if (err) {
- IWL_ERROR("initializing geos failed: %d\n", err);
- goto out_free_channel_map;
+ IWL_ERR(priv, "initializing driver failed\n");
+ goto out_unset_hw_params;
}
- printk(KERN_INFO DRV_NAME
- ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+ IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
+ priv->cfg->name);
/***********************************
* 7. Initialize Module Parameters
@@ -7993,9 +5079,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* Initialize module parameter values here */
/* Disable radio (SW RF KILL) via parameter when loading driver */
- if (iwl3945_param_disable) {
+ if (iwl3945_mod_params.disable) {
set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO("Radio disabled.\n");
+ IWL_DEBUG_INFO(priv, "Radio disabled.\n");
}
@@ -8004,66 +5090,73 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* ********************/
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_disable_interrupts(priv);
+ iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
+ pci_enable_msi(priv->pci_dev);
+
+ err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
+ DRV_NAME, priv);
+ if (err) {
+ IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
+ goto out_disable_msi;
+ }
+
err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
if (err) {
- IWL_ERROR("failed to create sysfs device attributes\n");
- goto out_free_geos;
+ IWL_ERR(priv, "failed to create sysfs device attributes\n");
+ goto out_release_irq;
}
- iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
+ iwl_set_rxon_channel(priv,
+ &priv->bands[IEEE80211_BAND_2GHZ].channels[5]);
iwl3945_setup_deferred_work(priv);
iwl3945_setup_rx_handlers(priv);
- /***********************
- * 9. Conclude
- * ********************/
- pci_save_state(pdev);
- pci_disable_device(pdev);
-
/*********************************
- * 10. Setup and Register mac80211
+ * 9. Setup and Register mac80211
* *******************************/
- err = ieee80211_register_hw(priv->hw);
- if (err) {
- IWL_ERROR("Failed to register network device (error %d)\n", err);
- goto out_remove_sysfs;
- }
-
- priv->hw->conf.beacon_int = 100;
- priv->mac80211_registered = 1;
+ iwl_enable_interrupts(priv);
+ err = iwl3945_setup_mac(priv);
+ if (err)
+ goto out_remove_sysfs;
- err = iwl3945_rfkill_init(priv);
+ err = iwl_rfkill_init(priv);
if (err)
- IWL_ERROR("Unable to initialize RFKILL system. "
+ IWL_ERR(priv, "Unable to initialize RFKILL system. "
"Ignoring error: %d\n", err);
+ else
+ iwl_rfkill_set_hw_state(priv);
+
+ /* Start monitoring the killswitch */
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ 2 * HZ);
return 0;
out_remove_sysfs:
- sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- out_free_geos:
- iwl3945_free_geos(priv);
- out_free_channel_map:
- iwl3945_free_channel_map(priv);
-
-
- out_release_irq:
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
- iwl3945_unset_hw_setting(priv);
-
+ sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
+ out_release_irq:
+ free_irq(priv->pci_dev->irq, priv);
+ out_disable_msi:
+ pci_disable_msi(priv->pci_dev);
+ iwlcore_free_geos(priv);
+ iwl_free_channel_map(priv);
+ out_unset_hw_params:
+ iwl3945_unset_hw_params(priv);
+ out_eeprom_free:
+ iwl_eeprom_free(priv);
out_iounmap:
pci_iounmap(pdev, priv->hw_base);
out_pci_release_regions:
pci_release_regions(pdev);
out_pci_disable_device:
- pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
+ pci_disable_device(pdev);
out_ieee80211_free_hw:
ieee80211_free_hw(priv->hw);
out:
@@ -8072,42 +5165,46 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
{
- struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
unsigned long flags;
if (!priv)
return;
- IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
+ IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
set_bit(STATUS_EXIT_PENDING, &priv->status);
- iwl3945_down(priv);
+ if (priv->mac80211_registered) {
+ ieee80211_unregister_hw(priv->hw);
+ priv->mac80211_registered = 0;
+ } else {
+ iwl3945_down(priv);
+ }
/* make sure we flush any pending irq or
* tasklet for the driver
*/
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_disable_interrupts(priv);
+ iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
iwl_synchronize_irq(priv);
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- iwl3945_rfkill_unregister(priv);
+ iwl_rfkill_unregister(priv);
+ cancel_delayed_work(&priv->rfkill_poll);
+
iwl3945_dealloc_ucode_pci(priv);
if (priv->rxq.bd)
- iwl3945_rx_queue_free(priv, &priv->rxq);
+ iwl_rx_queue_free(priv, &priv->rxq);
iwl3945_hw_txq_ctx_free(priv);
- iwl3945_unset_hw_setting(priv);
+ iwl3945_unset_hw_params(priv);
iwl3945_clear_stations_table(priv);
- if (priv->mac80211_registered)
- ieee80211_unregister_hw(priv->hw);
-
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
@@ -8117,13 +5214,16 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
+ free_irq(pdev->irq, priv);
+ pci_disable_msi(pdev);
+
pci_iounmap(pdev, priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- iwl3945_free_channel_map(priv);
- iwl3945_free_geos(priv);
+ iwl_free_channel_map(priv);
+ iwlcore_free_geos(priv);
kfree(priv->scan);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
@@ -8135,14 +5235,15 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+ 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;
@@ -8150,9 +5251,14 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int iwl3945_pci_resume(struct pci_dev *pdev)
{
- struct iwl3945_priv *priv = pci_get_drvdata(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);
@@ -8163,114 +5269,6 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-/*************** RFKILL FUNCTIONS **********/
-#ifdef CONFIG_IWL3945_RFKILL
-/* software rf-kill from user */
-static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
-{
- struct iwl3945_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("we received soft RFKILL set to state %d\n", state);
- mutex_lock(&priv->mutex);
-
- switch (state) {
- case RFKILL_STATE_UNBLOCKED:
- if (iwl3945_is_rfkill_hw(priv)) {
- err = -EBUSY;
- goto out_unlock;
- }
- iwl3945_radio_kill_sw(priv, 0);
- break;
- case RFKILL_STATE_SOFT_BLOCKED:
- iwl3945_radio_kill_sw(priv, 1);
- break;
- default:
- IWL_WARNING("we received unexpected RFKILL state %d\n", state);
- break;
- }
-out_unlock:
- mutex_unlock(&priv->mutex);
-
- return err;
-}
-
-int iwl3945_rfkill_init(struct iwl3945_priv *priv)
-{
- struct device *device = wiphy_dev(priv->hw->wiphy);
- int ret = 0;
-
- BUG_ON(device == NULL);
-
- IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
- priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
- if (!priv->rfkill) {
- IWL_ERROR("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 = iwl3945_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_ERROR("Unable to register rfkill: %d\n", ret);
- goto freed_rfkill;
- }
-
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
- return ret;
-
-freed_rfkill:
- if (priv->rfkill != NULL)
- rfkill_free(priv->rfkill);
- priv->rfkill = NULL;
-
-error:
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
- return ret;
-}
-
-void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
-{
- if (priv->rfkill)
- rfkill_unregister(priv->rfkill);
-
- priv->rfkill = NULL;
-}
-
-/* set rf-kill to the right state. */
-void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
-{
-
- if (!priv->rfkill)
- return;
-
- if (iwl3945_is_rfkill_hw(priv)) {
- rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
- return;
- }
-
- if (!iwl3945_is_rfkill_sw(priv))
- rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
- else
- rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
-}
-#endif
-
/*****************************************************************************
*
* driver and module entry point
@@ -8297,29 +5295,19 @@ static int __init iwl3945_init(void)
ret = iwl3945_rate_control_register();
if (ret) {
- IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+ printk(KERN_ERR DRV_NAME
+ "Unable to register rate control algorithm: %d\n", ret);
return ret;
}
ret = pci_register_driver(&iwl3945_driver);
if (ret) {
- IWL_ERROR("Unable to initialize PCI module\n");
+ printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
goto error_register;
}
-#ifdef CONFIG_IWL3945_DEBUG
- ret = driver_create_file(&iwl3945_driver.driver, &driver_attr_debug_level);
- if (ret) {
- IWL_ERROR("Unable to create driver sysfs file\n");
- goto error_debug;
- }
-#endif
return ret;
-#ifdef CONFIG_IWL3945_DEBUG
-error_debug:
- pci_unregister_driver(&iwl3945_driver);
-#endif
error_register:
iwl3945_rate_control_unregister();
return ret;
@@ -8327,29 +5315,29 @@ error_register:
static void __exit iwl3945_exit(void)
{
-#ifdef CONFIG_IWL3945_DEBUG
- driver_remove_file(&iwl3945_driver.driver, &driver_attr_debug_level);
-#endif
pci_unregister_driver(&iwl3945_driver);
iwl3945_rate_control_unregister();
}
MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
-module_param_named(antenna, iwl3945_param_antenna, int, 0444);
+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_param_disable, int, 0444);
+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(hwcrypto, iwl3945_param_hwcrypto, int, 0444);
-MODULE_PARM_DESC(hwcrypto,
- "using hardware crypto engine (default 0 [software])\n");
-module_param_named(debug, iwl3945_param_debug, uint, 0444);
+module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
+MODULE_PARM_DESC(swcrypto,
+ "using software crypto (default 1 [software])\n");
+module_param_named(debug, iwl3945_mod_params.debug, uint, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
-module_param_named(disable_hw_scan, iwl3945_param_disable_hw_scan, int, 0444);
+module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444);
MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
-module_param_named(queues_num, iwl3945_param_queues_num, int, 0444);
+module_param_named(queues_num, iwl3945_mod_params.num_of_queues, int, 0444);
MODULE_PARM_DESC(queues_num, "number of hw queues.");
+module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
+MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
+
module_exit(iwl3945_exit);
module_init(iwl3945_init);
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index 02080a3682a..0b691858450 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -4,8 +4,10 @@ libertas-objs := main.o wext.o rx.o tx.o cmd.o cmdresp.o scan.o 11d.o \
usb8xxx-objs += if_usb.o
libertas_cs-objs += if_cs.o
libertas_sdio-objs += if_sdio.o
+libertas_spi-objs += if_spi.o
obj-$(CONFIG_LIBERTAS) += libertas.o
obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
obj-$(CONFIG_LIBERTAS_CS) += libertas_cs.o
obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o
+obj-$(CONFIG_LIBERTAS_SPI) += libertas_spi.o
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index ec4efd7ff3c..50e28a0cdfe 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -629,7 +629,7 @@ static ssize_t lbs_rdrf_write(struct file *file,
res = -EFAULT;
goto out_unlock;
}
- priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
+ priv->rf_offset = simple_strtoul(buf, NULL, 16);
res = count;
out_unlock:
free_page(addr);
@@ -680,12 +680,12 @@ out_unlock:
}
struct lbs_debugfs_files {
- char *name;
+ const char *name;
int perm;
struct file_operations fops;
};
-static struct lbs_debugfs_files debugfs_files[] = {
+static const struct lbs_debugfs_files debugfs_files[] = {
{ "info", 0444, FOPS(lbs_dev_info, write_file_dummy), },
{ "getscantable", 0444, FOPS(lbs_getscantable,
write_file_dummy), },
@@ -693,7 +693,7 @@ static struct lbs_debugfs_files debugfs_files[] = {
lbs_sleepparams_write), },
};
-static struct lbs_debugfs_files debugfs_events_files[] = {
+static const struct lbs_debugfs_files debugfs_events_files[] = {
{"low_rssi", 0644, FOPS(lbs_lowrssi_read,
lbs_lowrssi_write), },
{"low_snr", 0644, FOPS(lbs_lowsnr_read,
@@ -708,7 +708,7 @@ static struct lbs_debugfs_files debugfs_events_files[] = {
lbs_highsnr_write), },
};
-static struct lbs_debugfs_files debugfs_regs_files[] = {
+static const struct lbs_debugfs_files debugfs_regs_files[] = {
{"rdmac", 0644, FOPS(lbs_rdmac_read, lbs_rdmac_write), },
{"wrmac", 0600, FOPS(NULL, lbs_wrmac_write), },
{"rdbbp", 0644, FOPS(lbs_rdbbp_read, lbs_rdbbp_write), },
@@ -735,7 +735,7 @@ void lbs_debugfs_remove(void)
void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
{
int i;
- struct lbs_debugfs_files *files;
+ const struct lbs_debugfs_files *files;
if (!lbs_dir)
goto exit;
@@ -938,7 +938,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
return (ssize_t)cnt;
}
-static struct file_operations lbs_debug_fops = {
+static const struct file_operations lbs_debug_fops = {
.owner = THIS_MODULE,
.open = open_file_generic,
.write = lbs_debugfs_write,
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index c364e4c01d1..e8dfde39abf 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -41,6 +41,7 @@
#define LBS_DEB_HEX 0x00200000
#define LBS_DEB_SDIO 0x00400000
#define LBS_DEB_SYSFS 0x00800000
+#define LBS_DEB_SPI 0x01000000
extern unsigned int lbs_debug;
@@ -84,6 +85,7 @@ do { if ((lbs_debug & (grp)) == (grp)) \
#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args)
#define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args)
#define lbs_deb_sysfs(fmt, args...) LBS_DEB_LL(LBS_DEB_SYSFS, " sysfs", fmt, ##args)
+#define lbs_deb_spi(fmt, args...) LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args)
#define lbs_pr_info(format, args...) \
printk(KERN_INFO DRV_NAME": " format, ## args)
@@ -263,6 +265,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define CMD_F_HOSTCMD (1 << 0)
#define FW_CAPINFO_WPA (1 << 0)
+#define FW_CAPINFO_PS (1 << 1)
#define FW_CAPINFO_FIRMWARE_UPGRADE (1 << 13)
#define FW_CAPINFO_BOOT2_UPGRADE (1<<14)
#define FW_CAPINFO_PERSISTENT_CONFIG (1<<15)
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index dd682c4cfde..27e81fd97c9 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -109,7 +109,6 @@ struct lbs_private {
void *card;
struct net_device *dev;
- struct net_device_stats stats;
struct net_device *mesh_dev; /* Virtual device */
struct net_device *rtap_net_dev;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 61d2f50470c..b118a35ec60 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -23,7 +23,7 @@ static const char * mesh_stat_strings[]= {
static void lbs_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
snprintf(info->fw_version, 32, "%u.%u.%u.p%u",
priv->fwrelease >> 24 & 0xff,
@@ -47,7 +47,7 @@ static int lbs_ethtool_get_eeprom_len(struct net_device *dev)
static int lbs_ethtool_get_eeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 * bytes)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct cmd_ds_802_11_eeprom_access cmd;
int ret;
@@ -76,7 +76,7 @@ out:
static void lbs_ethtool_get_stats(struct net_device *dev,
struct ethtool_stats *stats, uint64_t *data)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct cmd_ds_mesh_access mesh_access;
int ret;
@@ -113,7 +113,7 @@ static void lbs_ethtool_get_stats(struct net_device *dev,
static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
return MESH_STATS_NUM;
@@ -143,7 +143,7 @@ static void lbs_ethtool_get_strings(struct net_device *dev,
static void lbs_ethtool_get_wol(struct net_device *dev,
struct ethtool_wolinfo *wol)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
if (priv->wol_criteria == 0xffffffff) {
/* Interface driver didn't configure wake */
@@ -166,7 +166,7 @@ static void lbs_ethtool_get_wol(struct net_device *dev,
static int lbs_ethtool_set_wol(struct net_device *dev,
struct ethtool_wolinfo *wol)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
uint32_t criteria = 0;
if (priv->wol_criteria == 0xffffffff && wol->wolopts)
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 277ff1975bd..d4457ef808a 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -66,6 +66,7 @@
#define CMD_802_11_LED_GPIO_CTRL 0x004e
#define CMD_802_11_EEPROM_ACCESS 0x0059
#define CMD_802_11_BAND_CONFIG 0x0058
+#define CMD_GSPI_BUS_CONFIG 0x005a
#define CMD_802_11D_DOMAIN_INFO 0x005b
#define CMD_802_11_KEY_MATERIAL 0x005e
#define CMD_802_11_SLEEP_PARAMS 0x0066
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index e173b1b46c2..a899aeb676b 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -32,7 +32,7 @@ struct txpd {
u8 pktdelay_2ms;
/* reserved */
u8 reserved1;
-};
+} __attribute__ ((packed));
/* RxPD Descriptor */
struct rxpd {
@@ -63,7 +63,7 @@ struct rxpd {
/* Pkt Priority */
u8 priority;
u8 reserved[3];
-};
+} __attribute__ ((packed));
struct cmd_header {
__le16 command;
@@ -97,7 +97,7 @@ struct enc_key {
struct lbs_offset_value {
u32 offset;
u32 value;
-};
+} __attribute__ ((packed));
/* Define general data structure */
/* cmd_DS_GEN */
@@ -107,7 +107,7 @@ struct cmd_ds_gen {
__le16 seqnum;
__le16 result;
void *cmdresp[0];
-};
+} __attribute__ ((packed));
#define S_DS_GEN sizeof(struct cmd_ds_gen)
@@ -163,7 +163,7 @@ struct cmd_ds_802_11_subscribe_event {
* bump this up a bit.
*/
uint8_t tlv[128];
-};
+} __attribute__ ((packed));
/*
* This scan handle Country Information IE(802.11d compliant)
@@ -180,7 +180,7 @@ struct cmd_ds_802_11_scan {
mrvlietypes_chanlistparamset_t ChanListParamSet;
mrvlietypes_ratesparamset_t OpRateSet;
#endif
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_scan_rsp {
struct cmd_header hdr;
@@ -188,7 +188,7 @@ struct cmd_ds_802_11_scan_rsp {
__le16 bssdescriptsize;
uint8_t nr_sets;
uint8_t bssdesc_and_tlvbuffer[0];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_get_log {
struct cmd_header hdr;
@@ -206,33 +206,41 @@ struct cmd_ds_802_11_get_log {
__le32 fcserror;
__le32 txframe;
__le32 wepundecryptable;
-};
+} __attribute__ ((packed));
struct cmd_ds_mac_control {
struct cmd_header hdr;
__le16 action;
u16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_mac_multicast_adr {
struct cmd_header hdr;
__le16 action;
__le16 nr_of_adrs;
u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
-};
+} __attribute__ ((packed));
+
+struct cmd_ds_gspi_bus_config {
+ struct cmd_header hdr;
+ __le16 action;
+ __le16 bus_delay_mode;
+ __le16 host_time_delay_to_read_port;
+ __le16 host_time_delay_to_read_register;
+} __attribute__ ((packed));
struct cmd_ds_802_11_authenticate {
u8 macaddr[ETH_ALEN];
u8 authtype;
u8 reserved[10];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_deauthenticate {
struct cmd_header hdr;
u8 macaddr[ETH_ALEN];
__le16 reasoncode;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_associate {
u8 peerstaaddr[6];
@@ -251,7 +259,7 @@ struct cmd_ds_802_11_associate {
struct cmd_ds_802_11_associate_rsp {
struct ieeetypes_assocrsp assocRsp;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_set_wep {
struct cmd_header hdr;
@@ -265,7 +273,7 @@ struct cmd_ds_802_11_set_wep {
/* 40, 128bit or TXWEP */
uint8_t keytype[4];
uint8_t keymaterial[4][16];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_3_get_stat {
__le32 xmitok;
@@ -274,7 +282,7 @@ struct cmd_ds_802_3_get_stat {
__le32 rcverror;
__le32 rcvnobuffer;
__le32 rcvcrcerror;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_get_stat {
__le32 txfragmentcnt;
@@ -294,7 +302,7 @@ struct cmd_ds_802_11_get_stat {
__le32 txbeacon;
__le32 rxbeacon;
__le32 wepundecryptable;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_snmp_mib {
struct cmd_header hdr;
@@ -303,58 +311,58 @@ struct cmd_ds_802_11_snmp_mib {
__le16 oid;
__le16 bufsize;
u8 value[128];
-};
+} __attribute__ ((packed));
struct cmd_ds_mac_reg_map {
__le16 buffersize;
u8 regmap[128];
__le16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_bbp_reg_map {
__le16 buffersize;
u8 regmap[128];
__le16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_rf_reg_map {
__le16 buffersize;
u8 regmap[64];
__le16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_mac_reg_access {
__le16 action;
__le16 offset;
__le32 value;
-};
+} __attribute__ ((packed));
struct cmd_ds_bbp_reg_access {
__le16 action;
__le16 offset;
u8 value;
u8 reserved[3];
-};
+} __attribute__ ((packed));
struct cmd_ds_rf_reg_access {
__le16 action;
__le16 offset;
u8 value;
u8 reserved[3];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_radio_control {
struct cmd_header hdr;
__le16 action;
__le16 control;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_beacon_control {
__le16 action;
__le16 beacon_enable;
__le16 beacon_period;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_sleep_params {
struct cmd_header hdr;
@@ -379,7 +387,7 @@ struct cmd_ds_802_11_sleep_params {
/* reserved field, should be set to zero */
__le16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_inactivity_timeout {
struct cmd_header hdr;
@@ -389,7 +397,7 @@ struct cmd_ds_802_11_inactivity_timeout {
/* Inactivity timeout in msec */
__le16 timeout;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rf_channel {
struct cmd_header hdr;
@@ -399,7 +407,7 @@ struct cmd_ds_802_11_rf_channel {
__le16 rftype; /* unused */
__le16 reserved; /* unused */
u8 channellist[32]; /* unused */
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rssi {
/* weighting factor */
@@ -408,21 +416,21 @@ struct cmd_ds_802_11_rssi {
__le16 reserved_0;
__le16 reserved_1;
__le16 reserved_2;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rssi_rsp {
__le16 SNR;
__le16 noisefloor;
__le16 avgSNR;
__le16 avgnoisefloor;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_mac_address {
struct cmd_header hdr;
__le16 action;
u8 macadd[ETH_ALEN];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rf_tx_power {
struct cmd_header hdr;
@@ -431,7 +439,7 @@ struct cmd_ds_802_11_rf_tx_power {
__le16 curlevel;
s8 maxlevel;
s8 minlevel;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rf_antenna {
__le16 action;
@@ -439,33 +447,33 @@ struct cmd_ds_802_11_rf_antenna {
/* Number of antennas or 0xffff(diversity) */
__le16 antennamode;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_monitor_mode {
__le16 action;
__le16 mode;
-};
+} __attribute__ ((packed));
struct cmd_ds_set_boot2_ver {
struct cmd_header hdr;
__le16 action;
__le16 version;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_fw_wake_method {
struct cmd_header hdr;
__le16 action;
__le16 method;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_sleep_period {
struct cmd_header hdr;
__le16 action;
__le16 period;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_ps_mode {
__le16 action;
@@ -473,7 +481,7 @@ struct cmd_ds_802_11_ps_mode {
__le16 multipledtim;
__le16 reserved;
__le16 locallisteninterval;
-};
+} __attribute__ ((packed));
struct cmd_confirm_sleep {
struct cmd_header hdr;
@@ -483,7 +491,7 @@ struct cmd_confirm_sleep {
__le16 multipledtim;
__le16 reserved;
__le16 locallisteninterval;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_data_rate {
struct cmd_header hdr;
@@ -491,14 +499,14 @@ struct cmd_ds_802_11_data_rate {
__le16 action;
__le16 reserved;
u8 rates[MAX_RATES];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rate_adapt_rateset {
struct cmd_header hdr;
__le16 action;
__le16 enablehwauto;
__le16 bitmap;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_ad_hoc_start {
struct cmd_header hdr;
@@ -520,7 +528,7 @@ struct cmd_ds_802_11_ad_hoc_result {
u8 pad[3];
u8 bssid[ETH_ALEN];
-};
+} __attribute__ ((packed));
struct adhoc_bssdesc {
u8 bssid[ETH_ALEN];
@@ -578,7 +586,7 @@ struct MrvlIEtype_keyParamSet {
/* key material of size keylen */
u8 key[32];
-};
+} __attribute__ ((packed));
#define MAX_WOL_RULES 16
@@ -590,7 +598,7 @@ struct host_wol_rule {
__le16 reserve;
__be32 sig_mask;
__be32 signature;
-};
+} __attribute__ ((packed));
struct wol_config {
uint8_t action;
@@ -598,8 +606,7 @@ struct wol_config {
uint8_t no_rules_in_cmd;
uint8_t result;
struct host_wol_rule rule[MAX_WOL_RULES];
-};
-
+} __attribute__ ((packed));
struct cmd_ds_host_sleep {
struct cmd_header hdr;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 842a08d1f10..cedeac6322f 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -151,7 +151,7 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
for (i = 0; i < 100000; i++) {
u8 val = if_cs_read8(card, addr);
if (val == reg)
- return i;
+ return 0;
udelay(5);
}
return -ETIME;
@@ -421,7 +421,7 @@ static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
len = if_cs_read16(priv->card, IF_CS_READ_LEN);
if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
- priv->stats.rx_dropped++;
+ priv->dev->stats.rx_dropped++;
goto dat_err;
}
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 4519d7314f4..76f4c653d64 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -95,6 +95,8 @@ struct if_sdio_card {
spinlock_t lock;
struct if_sdio_packet *packets;
+
+ struct workqueue_struct *workqueue;
struct work_struct packet_worker;
};
@@ -209,6 +211,9 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
if (ret)
goto out;
+
+ /* right shift 3 bits to get the event id */
+ event >>= 3;
} else {
if (size < 4) {
lbs_deb_sdio("event packet too small (%d bytes)\n",
@@ -743,7 +748,7 @@ static int if_sdio_host_to_card(struct lbs_private *priv,
spin_unlock_irqrestore(&card->lock, flags);
- schedule_work(&card->packet_worker);
+ queue_work(card->workqueue, &card->packet_worker);
ret = 0;
@@ -833,6 +838,7 @@ static int if_sdio_probe(struct sdio_func *func,
card->func = func;
card->model = model;
spin_lock_init(&card->lock);
+ card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
@@ -921,15 +927,17 @@ static int if_sdio_probe(struct sdio_func *func,
if (ret)
goto err_activate_card;
+ if (priv->fwcapinfo & FW_CAPINFO_PS)
+ priv->ps_supported = 1;
+
out:
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
err_activate_card:
- flush_scheduled_work();
- free_netdev(priv->dev);
- kfree(priv);
+ flush_workqueue(card->workqueue);
+ lbs_remove_card(priv);
reclaim:
sdio_claim_host(func);
release_int:
@@ -939,6 +947,7 @@ disable:
release:
sdio_release_host(func);
free:
+ destroy_workqueue(card->workqueue);
while (card->packets) {
packet = card->packets;
card->packets = card->packets->next;
@@ -965,7 +974,8 @@ static void if_sdio_remove(struct sdio_func *func)
lbs_stop_card(card->priv);
lbs_remove_card(card->priv);
- flush_scheduled_work();
+ flush_workqueue(card->workqueue);
+ destroy_workqueue(card->workqueue);
sdio_claim_host(func);
sdio_release_irq(func);
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
new file mode 100644
index 00000000000..07311e71af9
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -0,0 +1,1218 @@
+/*
+ * linux/drivers/net/wireless/libertas/if_spi.c
+ *
+ * Driver for Marvell SPI WLAN cards.
+ *
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Authors:
+ * Andrey Yurovsky <andrey@cozybit.com>
+ * Colin McCabe <colin@cozybit.com>
+ *
+ * Inspired by if_sdio.c, Copyright 2007-2008 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/gpio.h>
+#include <linux/jiffies.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/spi/libertas_spi.h>
+#include <linux/spi/spi.h>
+
+#include "host.h"
+#include "decl.h"
+#include "defs.h"
+#include "dev.h"
+#include "if_spi.h"
+
+struct if_spi_packet {
+ struct list_head list;
+ u16 blen;
+ u8 buffer[0] __attribute__((aligned(4)));
+};
+
+struct if_spi_card {
+ struct spi_device *spi;
+ struct lbs_private *priv;
+ struct libertas_spi_platform_data *pdata;
+
+ char helper_fw_name[FIRMWARE_NAME_MAX];
+ char main_fw_name[FIRMWARE_NAME_MAX];
+
+ /* The card ID and card revision, as reported by the hardware. */
+ 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;
+
+ int use_dummy_writes;
+ unsigned long spu_port_delay;
+ unsigned long spu_reg_delay;
+
+ /* Handles all SPI communication (except for FW load) */
+ struct task_struct *spi_thread;
+ int run_thread;
+
+ /* Used to wake up the spi_thread */
+ struct semaphore spi_ready;
+ struct semaphore spi_thread_terminated;
+
+ u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE];
+
+ /* A buffer of incoming packets from libertas core.
+ * Since we can't sleep in hw_host_to_card, we have to buffer
+ * them. */
+ struct list_head cmd_packet_list;
+ struct list_head data_packet_list;
+
+ /* Protects cmd_packet_list and data_packet_list */
+ spinlock_t buffer_lock;
+};
+
+static void free_if_spi_card(struct if_spi_card *card)
+{
+ struct list_head *cursor, *next;
+ struct if_spi_packet *packet;
+
+ BUG_ON(card->run_thread);
+ list_for_each_safe(cursor, next, &card->cmd_packet_list) {
+ packet = container_of(cursor, struct if_spi_packet, list);
+ list_del(&packet->list);
+ kfree(packet);
+ }
+ list_for_each_safe(cursor, next, &card->data_packet_list) {
+ packet = container_of(cursor, struct if_spi_packet, list);
+ list_del(&packet->list);
+ kfree(packet);
+ }
+ spi_set_drvdata(card->spi, NULL);
+ kfree(card);
+}
+
+static struct chip_ident chip_id_to_device_name[] = {
+ { .chip_id = 0x04, .name = 8385 },
+ { .chip_id = 0x0b, .name = 8686 },
+};
+
+/*
+ * SPI Interface Unit Routines
+ *
+ * The SPU sits between the host and the WLAN module.
+ * All communication with the firmware is through SPU transactions.
+ *
+ * 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)
+{
+ if (!time_after(jiffies, card->prev_xfer_time + 1)) {
+ /* Unfortunately, the SPU requires a delay between successive
+ * transactions. If our last transaction was more than a jiffy
+ * ago, we have obviously already delayed enough.
+ * 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;
+}
+
+/* Write out a byte buffer to an SPI register,
+ * using a series of 16-bit transfers. */
+static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
+{
+ int err = 0;
+ u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK;
+
+ /* You must give an even number of bytes to the SPU, even if it
+ * doesn't care about the last one. */
+ BUG_ON(len & 0x1);
+
+ spu_transaction_init(card);
+
+ /* write SPU register index */
+ err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
+ if (err)
+ goto out;
+
+ err = spi_write(card->spi, buf, len);
+
+out:
+ 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));
+}
+
+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));
+}
+
+static inline int spu_reg_is_port_reg(u16 reg)
+{
+ switch (reg) {
+ case IF_SPI_IO_RDWRPORT_REG:
+ case IF_SPI_CMD_RDWRPORT_REG:
+ case IF_SPI_DATA_RDWRPORT_REG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
+{
+ unsigned int i, delay;
+ int err = 0;
+ u16 zero = 0;
+ u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK;
+
+ /* You must take an even number of bytes from the SPU, even if you
+ * don't care about the last one. */
+ BUG_ON(len & 0x1);
+
+ spu_transaction_init(card);
+
+ /* write SPU register index */
+ err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
+ if (err)
+ goto out;
+
+ 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;
+ }
+ } else {
+ /* Busy-wait while the SPU fills the FIFO */
+ ndelay(100 + (delay * 10));
+ }
+
+ /* read in data */
+ err = spi_read(card->spi, buf, len);
+
+out:
+ spu_transaction_finish(card);
+ return err;
+}
+
+/* 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));
+}
+
+/* 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];
+ int err;
+ err = spu_read(card, reg, (u8 *)buf, sizeof(u32));
+ if (!err)
+ *val = buf[0] | (buf[1] << 16);
+ return err;
+}
+
+/* Keep reading 16 bits from an SPI register until you get the correct result.
+ *
+ * If mask = 0, the correct result is any non-zero number.
+ * If mask != 0, the correct result is any number where
+ * number & target_mask == target
+ *
+ * Returns -ETIMEDOUT if a second passes without the correct result. */
+static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
+ u16 target_mask, u16 target)
+{
+ int err;
+ unsigned long timeout = jiffies + 5*HZ;
+ while (1) {
+ u16 val;
+ err = spu_read_u16(card, reg, &val);
+ if (err)
+ return err;
+ if (target_mask) {
+ if ((val & target_mask) == target)
+ return 0;
+ } else {
+ if (val)
+ return 0;
+ }
+ udelay(100);
+ if (time_after(jiffies, timeout)) {
+ lbs_pr_err("%s: timeout with val=%02x, "
+ "target_mask=%02x, target=%02x\n",
+ __func__, val, target_mask, target);
+ return -ETIMEDOUT;
+ }
+ }
+}
+
+/* Read 16 bits from an SPI register until you receive a specific value.
+ * Returns -ETIMEDOUT if a 4 tries pass without success. */
+static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target)
+{
+ int err, try;
+ for (try = 0; try < 4; ++try) {
+ u32 val = 0;
+ err = spu_read_u32(card, reg, &val);
+ if (err)
+ return err;
+ if (val == target)
+ return 0;
+ mdelay(100);
+ }
+ return -ETIMEDOUT;
+}
+
+static int spu_set_interrupt_mode(struct if_spi_card *card,
+ int suppress_host_int,
+ int auto_int)
+{
+ int err = 0;
+
+ /* We can suppress a host interrupt by clearing the appropriate
+ * bit in the "host interrupt status mask" register */
+ if (suppress_host_int) {
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
+ if (err)
+ return err;
+ } else {
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG,
+ IF_SPI_HISM_TX_DOWNLOAD_RDY |
+ IF_SPI_HISM_RX_UPLOAD_RDY |
+ IF_SPI_HISM_CMD_DOWNLOAD_RDY |
+ IF_SPI_HISM_CARDEVENT |
+ IF_SPI_HISM_CMD_UPLOAD_RDY);
+ if (err)
+ return err;
+ }
+
+ /* If auto-interrupts are on, the completion of certain transactions
+ * will trigger an interrupt automatically. If auto-interrupts
+ * are off, we need to set the "Card Interrupt Cause" register to
+ * trigger a card interrupt. */
+ if (auto_int) {
+ err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG,
+ IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO |
+ IF_SPI_HICT_RX_UPLOAD_OVER_AUTO |
+ IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO |
+ IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO);
+ if (err)
+ return err;
+ } else {
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
+ if (err)
+ return err;
+ }
+ return err;
+}
+
+static int spu_get_chip_revision(struct if_spi_card *card,
+ u16 *card_id, u8 *card_rev)
+{
+ int err = 0;
+ u32 dev_ctrl;
+ err = spu_read_u32(card, IF_SPI_DEVICEID_CTRL_REG, &dev_ctrl);
+ if (err)
+ return err;
+ *card_id = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dev_ctrl);
+ *card_rev = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dev_ctrl);
+ return err;
+}
+
+static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
+{
+ int err = 0;
+ u16 rval;
+ /* set bus mode */
+ err = spu_write_u16(card, IF_SPI_SPU_BUS_MODE_REG, mode);
+ if (err)
+ return err;
+ /* Check that we were able to read back what we just wrote. */
+ err = spu_read_u16(card, IF_SPI_SPU_BUS_MODE_REG, &rval);
+ if (err)
+ return err;
+ if (rval != mode) {
+ lbs_pr_err("Can't read bus mode register.\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int spu_init(struct if_spi_card *card, int use_dummy_writes)
+{
+ int err = 0;
+ u32 delay;
+
+ /* We have to start up in timed delay mode so that we can safely
+ * read the Delay Read Register. */
+ card->use_dummy_writes = 0;
+ err = spu_set_bus_mode(card,
+ IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
+ IF_SPI_BUS_MODE_DELAY_METHOD_TIMED |
+ IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA);
+ if (err)
+ return err;
+ card->spu_port_delay = 1000;
+ card->spu_reg_delay = 1000;
+ err = spu_read_u32(card, IF_SPI_DELAY_READ_REG, &delay);
+ if (err)
+ return err;
+ card->spu_port_delay = delay & 0x0000ffff;
+ card->spu_reg_delay = (delay & 0xffff0000) >> 16;
+
+ /* If dummy clock delay mode has been requested, switch to it now */
+ if (use_dummy_writes) {
+ card->use_dummy_writes = 1;
+ err = spu_set_bus_mode(card,
+ IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
+ IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK |
+ IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA);
+ if (err)
+ return err;
+ }
+
+ lbs_deb_spi("Initialized SPU unit. "
+ "spu_port_delay=0x%04lx, spu_reg_delay=0x%04lx\n",
+ card->spu_port_delay, card->spu_reg_delay);
+ return err;
+}
+
+/*
+ * Firmware Loading
+ */
+
+static int if_spi_prog_helper_firmware(struct if_spi_card *card)
+{
+ int err = 0;
+ const struct firmware *firmware = NULL;
+ int bytes_remaining;
+ const u8 *fw;
+ u8 temp[HELPER_FW_LOAD_CHUNK_SZ];
+ struct spi_device *spi = card->spi;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ err = spu_set_interrupt_mode(card, 1, 0);
+ if (err)
+ goto out;
+ /* Get helper firmware image */
+ err = request_firmware(&firmware, card->helper_fw_name, &spi->dev);
+ if (err) {
+ lbs_pr_err("request_firmware failed with err = %d\n", err);
+ goto out;
+ }
+ bytes_remaining = firmware->size;
+ fw = firmware->data;
+
+ /* Load helper firmware image */
+ while (bytes_remaining > 0) {
+ /* Scratch pad 1 should contain the number of bytes we
+ * want to download to the firmware */
+ err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
+ HELPER_FW_LOAD_CHUNK_SZ);
+ if (err)
+ goto release_firmware;
+
+ err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+ IF_SPI_HIST_CMD_DOWNLOAD_RDY,
+ IF_SPI_HIST_CMD_DOWNLOAD_RDY);
+ if (err)
+ goto release_firmware;
+
+ /* Feed the data into the command read/write port reg
+ * in chunks of 64 bytes */
+ memset(temp, 0, sizeof(temp));
+ memcpy(temp, fw,
+ min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ));
+ mdelay(10);
+ err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
+ temp, HELPER_FW_LOAD_CHUNK_SZ);
+ if (err)
+ goto release_firmware;
+
+ /* Interrupt the boot code */
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+ if (err)
+ goto release_firmware;
+ err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
+ IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+ if (err)
+ goto release_firmware;
+ bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ;
+ fw += HELPER_FW_LOAD_CHUNK_SZ;
+ }
+
+ /* Once the helper / single stage firmware download is complete,
+ * write 0 to scratch pad 1 and interrupt the
+ * bootloader. This completes the helper download. */
+ err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
+ if (err)
+ goto release_firmware;
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+ if (err)
+ goto release_firmware;
+ err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
+ IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+ goto release_firmware;
+
+ lbs_deb_spi("waiting for helper to boot...\n");
+
+release_firmware:
+ release_firmware(firmware);
+out:
+ if (err)
+ lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
+ lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
+ return err;
+}
+
+/* Returns the length of the next packet the firmware expects us to send
+ * Sets crc_err if the previous transfer had a CRC error. */
+static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
+ int *crc_err)
+{
+ u16 len;
+ int err = 0;
+
+ /* wait until the host interrupt status register indicates
+ * that we are ready to download */
+ err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+ IF_SPI_HIST_CMD_DOWNLOAD_RDY,
+ IF_SPI_HIST_CMD_DOWNLOAD_RDY);
+ if (err) {
+ lbs_pr_err("timed out waiting for host_int_status\n");
+ return err;
+ }
+
+ /* Ask the device how many bytes of firmware it wants. */
+ err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len);
+ if (err)
+ return err;
+
+ if (len > IF_SPI_CMD_BUF_SIZE) {
+ lbs_pr_err("firmware load device requested a larger "
+ "tranfer than we are prepared to "
+ "handle. (len = %d)\n", len);
+ return -EIO;
+ }
+ if (len & 0x1) {
+ lbs_deb_spi("%s: crc error\n", __func__);
+ len &= ~0x1;
+ *crc_err = 1;
+ } else
+ *crc_err = 0;
+
+ return len;
+}
+
+static int if_spi_prog_main_firmware(struct if_spi_card *card)
+{
+ int len, prev_len;
+ int bytes, crc_err = 0, err = 0;
+ const struct firmware *firmware = NULL;
+ const u8 *fw;
+ struct spi_device *spi = card->spi;
+ u16 num_crc_errs;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ err = spu_set_interrupt_mode(card, 1, 0);
+ if (err)
+ goto out;
+
+ /* Get firmware image */
+ err = request_firmware(&firmware, card->main_fw_name, &spi->dev);
+ if (err) {
+ lbs_pr_err("%s: can't get firmware '%s' from kernel. "
+ "err = %d\n", __func__, card->main_fw_name, err);
+ goto out;
+ }
+
+ err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
+ if (err) {
+ lbs_pr_err("%s: timed out waiting for initial "
+ "scratch reg = 0\n", __func__);
+ goto release_firmware;
+ }
+
+ num_crc_errs = 0;
+ prev_len = 0;
+ bytes = firmware->size;
+ fw = firmware->data;
+ while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) {
+ if (len < 0) {
+ err = len;
+ goto release_firmware;
+ }
+ if (bytes < 0) {
+ /* If there are no more bytes left, we would normally
+ * expect to have terminated with len = 0 */
+ lbs_pr_err("Firmware load wants more bytes "
+ "than we have to offer.\n");
+ break;
+ }
+ if (crc_err) {
+ /* Previous transfer failed. */
+ if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) {
+ lbs_pr_err("Too many CRC errors encountered "
+ "in firmware load.\n");
+ err = -EIO;
+ goto release_firmware;
+ }
+ } else {
+ /* Previous transfer succeeded. Advance counters. */
+ bytes -= prev_len;
+ fw += prev_len;
+ }
+ if (bytes < len) {
+ memset(card->cmd_buffer, 0, len);
+ memcpy(card->cmd_buffer, fw, bytes);
+ } else
+ memcpy(card->cmd_buffer, fw, len);
+
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+ if (err)
+ goto release_firmware;
+ err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
+ card->cmd_buffer, len);
+ if (err)
+ goto release_firmware;
+ err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG ,
+ IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+ if (err)
+ goto release_firmware;
+ prev_len = len;
+ }
+ if (bytes > prev_len) {
+ lbs_pr_err("firmware load wants fewer bytes than "
+ "we have to offer.\n");
+ }
+
+ /* Confirm firmware download */
+ err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG,
+ SUCCESSFUL_FW_DOWNLOAD_MAGIC);
+ if (err) {
+ lbs_pr_err("failed to confirm the firmware download\n");
+ goto release_firmware;
+ }
+
+release_firmware:
+ release_firmware(firmware);
+
+out:
+ if (err)
+ lbs_pr_err("failed to load firmware (err=%d)\n", err);
+ lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
+ return err;
+}
+
+/*
+ * SPI Transfer Thread
+ *
+ * The SPI thread handles all SPI transfers, so there is no need for a lock.
+ */
+
+/* Move a command from the card to the host */
+static int if_spi_c2h_cmd(struct if_spi_card *card)
+{
+ struct lbs_private *priv = card->priv;
+ unsigned long flags;
+ int err = 0;
+ u16 len;
+ u8 i;
+
+ /* We need a buffer big enough to handle whatever people send to
+ * hw_host_to_card */
+ BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE);
+ BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE);
+
+ /* It's just annoying if the buffer size isn't a multiple of 4, because
+ * then we might have len < IF_SPI_CMD_BUF_SIZE but
+ * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */
+ BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0);
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ /* How many bytes are there to read? */
+ err = spu_read_u16(card, IF_SPI_SCRATCH_2_REG, &len);
+ if (err)
+ goto out;
+ if (!len) {
+ lbs_pr_err("%s: error: card has no data for host\n",
+ __func__);
+ err = -EINVAL;
+ goto out;
+ } else if (len > IF_SPI_CMD_BUF_SIZE) {
+ lbs_pr_err("%s: error: response packet too large: "
+ "%d bytes, but maximum is %d\n",
+ __func__, len, IF_SPI_CMD_BUF_SIZE);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* Read the data from the WLAN module into our command buffer */
+ err = spu_read(card, IF_SPI_CMD_RDWRPORT_REG,
+ card->cmd_buffer, ALIGN(len, 4));
+ if (err)
+ goto out;
+
+ spin_lock_irqsave(&priv->driver_lock, flags);
+ i = (priv->resp_idx == 0) ? 1 : 0;
+ BUG_ON(priv->resp_len[i]);
+ priv->resp_len[i] = len;
+ memcpy(priv->resp_buf[i], card->cmd_buffer, len);
+ lbs_notify_command_response(priv, i);
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+out:
+ if (err)
+ lbs_pr_err("%s: err=%d\n", __func__, err);
+ lbs_deb_leave(LBS_DEB_SPI);
+ return err;
+}
+
+/* Move data from the card to the host */
+static int if_spi_c2h_data(struct if_spi_card *card)
+{
+ struct sk_buff *skb;
+ char *data;
+ u16 len;
+ int err = 0;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ /* How many bytes are there to read? */
+ err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len);
+ if (err)
+ goto out;
+ if (!len) {
+ lbs_pr_err("%s: error: card has no data for host\n",
+ __func__);
+ err = -EINVAL;
+ goto out;
+ } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
+ lbs_pr_err("%s: error: card has %d bytes of data, but "
+ "our maximum skb size is %u\n",
+ __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* TODO: should we allocate a smaller skb if we have less data? */
+ skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+ if (!skb) {
+ err = -ENOBUFS;
+ goto out;
+ }
+ skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
+ data = skb_put(skb, len);
+
+ /* Read the data from the WLAN module into our skb... */
+ err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, 4));
+ if (err)
+ goto free_skb;
+
+ /* pass the SKB to libertas */
+ err = lbs_process_rxed_packet(card->priv, skb);
+ if (err)
+ goto free_skb;
+
+ /* success */
+ goto out;
+
+free_skb:
+ dev_kfree_skb(skb);
+out:
+ if (err)
+ lbs_pr_err("%s: err=%d\n", __func__, err);
+ lbs_deb_leave(LBS_DEB_SPI);
+ return err;
+}
+
+/* Move data or a command from the host to the card. */
+static void if_spi_h2c(struct if_spi_card *card,
+ struct if_spi_packet *packet, int type)
+{
+ int err = 0;
+ u16 int_type, port_reg;
+
+ switch (type) {
+ case MVMS_DAT:
+ int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER;
+ port_reg = IF_SPI_DATA_RDWRPORT_REG;
+ break;
+ case MVMS_CMD:
+ int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER;
+ port_reg = IF_SPI_CMD_RDWRPORT_REG;
+ break;
+ default:
+ lbs_pr_err("can't transfer buffer of type %d\n", type);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* Write the data to the card */
+ err = spu_write(card, port_reg, packet->buffer, packet->blen);
+ if (err)
+ goto out;
+
+out:
+ kfree(packet);
+
+ if (err)
+ lbs_pr_err("%s: error %d\n", __func__, err);
+}
+
+/* Inform the host about a card event */
+static void if_spi_e2h(struct if_spi_card *card)
+{
+ int err = 0;
+ unsigned long flags;
+ u32 cause;
+ struct lbs_private *priv = card->priv;
+
+ err = spu_read_u32(card, IF_SPI_SCRATCH_3_REG, &cause);
+ if (err)
+ goto out;
+
+ spin_lock_irqsave(&priv->driver_lock, flags);
+ lbs_queue_event(priv, cause & 0xff);
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+out:
+ if (err)
+ lbs_pr_err("%s: error %d\n", __func__, err);
+}
+
+static int lbs_spi_thread(void *data)
+{
+ int err;
+ struct if_spi_card *card = data;
+ u16 hiStatus;
+ unsigned long flags;
+ struct if_spi_packet *packet;
+
+ while (1) {
+ /* Wait to be woken up by one of two things. First, our ISR
+ * could tell us that something happened on the WLAN.
+ * Secondly, libertas could call hw_host_to_card with more
+ * data, which we might be able to send.
+ */
+ do {
+ err = down_interruptible(&card->spi_ready);
+ if (!card->run_thread) {
+ up(&card->spi_thread_terminated);
+ do_exit(0);
+ }
+ } while (err == EINTR);
+
+ /* Read the host interrupt status register to see what we
+ * can do. */
+ err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+ &hiStatus);
+ if (err) {
+ lbs_pr_err("I/O error\n");
+ goto err;
+ }
+
+ if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY)
+ err = if_spi_c2h_cmd(card);
+ if (err)
+ goto err;
+ if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY)
+ err = if_spi_c2h_data(card);
+ if (err)
+ goto err;
+ if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY) {
+ /* This means two things. First of all,
+ * if there was a previous command sent, the card has
+ * successfully received it.
+ * Secondly, it is now ready to download another
+ * command.
+ */
+ lbs_host_to_card_done(card->priv);
+
+ /* Do we have any command packets from the host to
+ * send? */
+ packet = NULL;
+ spin_lock_irqsave(&card->buffer_lock, flags);
+ if (!list_empty(&card->cmd_packet_list)) {
+ packet = (struct if_spi_packet *)(card->
+ cmd_packet_list.next);
+ list_del(&packet->list);
+ }
+ spin_unlock_irqrestore(&card->buffer_lock, flags);
+
+ if (packet)
+ if_spi_h2c(card, packet, MVMS_CMD);
+ }
+ if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) {
+ /* Do we have any data packets from the host to
+ * send? */
+ packet = NULL;
+ spin_lock_irqsave(&card->buffer_lock, flags);
+ if (!list_empty(&card->data_packet_list)) {
+ packet = (struct if_spi_packet *)(card->
+ data_packet_list.next);
+ list_del(&packet->list);
+ }
+ spin_unlock_irqrestore(&card->buffer_lock, flags);
+
+ if (packet)
+ if_spi_h2c(card, packet, MVMS_DAT);
+ }
+ if (hiStatus & IF_SPI_HIST_CARD_EVENT)
+ if_spi_e2h(card);
+
+err:
+ if (err)
+ lbs_pr_err("%s: got error %d\n", __func__, err);
+ }
+}
+
+/* Block until lbs_spi_thread thread has terminated */
+static void if_spi_terminate_spi_thread(struct if_spi_card *card)
+{
+ /* It would be nice to use kthread_stop here, but that function
+ * can't wake threads waiting for a semaphore. */
+ card->run_thread = 0;
+ up(&card->spi_ready);
+ down(&card->spi_thread_terminated);
+}
+
+/*
+ * Host to Card
+ *
+ * Called from Libertas to transfer some data to the WLAN device
+ * We can't sleep here. */
+static int if_spi_host_to_card(struct lbs_private *priv,
+ u8 type, u8 *buf, u16 nb)
+{
+ int err = 0;
+ unsigned long flags;
+ struct if_spi_card *card = priv->card;
+ struct if_spi_packet *packet;
+ u16 blen;
+
+ lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
+
+ if (nb == 0) {
+ lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb);
+ err = -EINVAL;
+ goto out;
+ }
+ blen = ALIGN(nb, 4);
+ packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC);
+ if (!packet) {
+ err = -ENOMEM;
+ goto out;
+ }
+ packet->blen = blen;
+ memcpy(packet->buffer, buf, nb);
+ memset(packet->buffer + nb, 0, blen - nb);
+
+ switch (type) {
+ case MVMS_CMD:
+ priv->dnld_sent = DNLD_CMD_SENT;
+ spin_lock_irqsave(&card->buffer_lock, flags);
+ list_add_tail(&packet->list, &card->cmd_packet_list);
+ spin_unlock_irqrestore(&card->buffer_lock, flags);
+ break;
+ case MVMS_DAT:
+ priv->dnld_sent = DNLD_DATA_SENT;
+ spin_lock_irqsave(&card->buffer_lock, flags);
+ list_add_tail(&packet->list, &card->data_packet_list);
+ spin_unlock_irqrestore(&card->buffer_lock, flags);
+ break;
+ default:
+ lbs_pr_err("can't transfer buffer of type %d", type);
+ err = -EINVAL;
+ break;
+ }
+
+ /* Wake up the spi thread */
+ up(&card->spi_ready);
+out:
+ lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err);
+ return err;
+}
+
+/*
+ * Host Interrupts
+ *
+ * Service incoming interrupts from the WLAN device. We can't sleep here, so
+ * don't try to talk on the SPI bus, just wake up the SPI thread.
+ */
+static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
+{
+ struct if_spi_card *card = dev_id;
+
+ up(&card->spi_ready);
+ return IRQ_HANDLED;
+}
+
+/*
+ * SPI callbacks
+ */
+
+static int if_spi_calculate_fw_names(u16 card_id,
+ char *helper_fw, char *main_fw)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) {
+ if (card_id == chip_id_to_device_name[i].chip_id)
+ break;
+ }
+ if (i == ARRAY_SIZE(chip_id_to_device_name)) {
+ lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id);
+ return -EAFNOSUPPORT;
+ }
+ snprintf(helper_fw, FIRMWARE_NAME_MAX, "libertas/gspi%d_hlp.bin",
+ chip_id_to_device_name[i].name);
+ snprintf(main_fw, FIRMWARE_NAME_MAX, "libertas/gspi%d.bin",
+ chip_id_to_device_name[i].name);
+ return 0;
+}
+
+static int __devinit if_spi_probe(struct spi_device *spi)
+{
+ struct if_spi_card *card;
+ struct lbs_private *priv = NULL;
+ struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
+ int err = 0;
+ u32 scratch;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ if (!pdata) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (pdata->setup) {
+ err = pdata->setup(spi);
+ if (err)
+ goto out;
+ }
+
+ /* Allocate card structure to represent this specific device */
+ card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL);
+ if (!card) {
+ err = -ENOMEM;
+ goto out;
+ }
+ 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);
+ sema_init(&card->spi_thread_terminated, 0);
+ INIT_LIST_HEAD(&card->cmd_packet_list);
+ 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;
+ err = spu_get_chip_revision(card, &card->card_id, &card->card_rev);
+ if (err)
+ goto free_gpio;
+
+ /* Firmware load */
+ err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch);
+ if (err)
+ goto free_gpio;
+ if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC)
+ lbs_deb_spi("Firmware is already loaded for "
+ "Marvell WLAN 802.11 adapter\n");
+ else {
+ err = if_spi_calculate_fw_names(card->card_id,
+ card->helper_fw_name, card->main_fw_name);
+ if (err)
+ goto free_gpio;
+
+ lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
+ "(chip_id = 0x%04x, chip_rev = 0x%02x) "
+ "attached to SPI bus_num %d, chip_select %d. "
+ "spi->max_speed_hz=%d\n",
+ card->card_id, card->card_rev,
+ spi->master->bus_num, spi->chip_select,
+ spi->max_speed_hz);
+ err = if_spi_prog_helper_firmware(card);
+ if (err)
+ goto free_gpio;
+ err = if_spi_prog_main_firmware(card);
+ if (err)
+ goto free_gpio;
+ 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;
+
+ /* Register our card with libertas.
+ * This will call alloc_etherdev */
+ priv = lbs_add_card(card, &spi->dev);
+ if (!priv) {
+ err = -ENOMEM;
+ goto free_gpio;
+ }
+ card->priv = priv;
+ priv->card = card;
+ priv->hw_host_to_card = if_spi_host_to_card;
+ priv->fw_ready = 1;
+ priv->ps_supported = 1;
+
+ /* Initialize interrupt handling stuff. */
+ card->run_thread = 1;
+ card->spi_thread = kthread_run(lbs_spi_thread, card, "lbs_spi_thread");
+ if (IS_ERR(card->spi_thread)) {
+ card->run_thread = 0;
+ err = PTR_ERR(card->spi_thread);
+ lbs_pr_err("error creating SPI thread: err=%d\n", err);
+ goto remove_card;
+ }
+ err = request_irq(spi->irq, if_spi_host_interrupt,
+ IRQF_TRIGGER_FALLING, "libertas_spi", card);
+ if (err) {
+ lbs_pr_err("can't get host irq line-- request_irq failed\n");
+ goto terminate_thread;
+ }
+
+ /* Start the card.
+ * This will call register_netdev, and we'll start
+ * getting interrupts... */
+ err = lbs_start_card(priv);
+ if (err)
+ goto release_irq;
+
+ lbs_deb_spi("Finished initializing WLAN module.\n");
+
+ /* successful exit */
+ goto out;
+
+release_irq:
+ free_irq(spi->irq, card);
+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:
+ lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
+ return err;
+}
+
+static int __devexit libertas_spi_remove(struct spi_device *spi)
+{
+ struct if_spi_card *card = spi_get_drvdata(spi);
+ struct lbs_private *priv = card->priv;
+
+ lbs_deb_spi("libertas_spi_remove\n");
+ lbs_deb_enter(LBS_DEB_SPI);
+ priv->surpriseremoved = 1;
+
+ lbs_stop_card(priv);
+ 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);
+ lbs_deb_leave(LBS_DEB_SPI);
+ return 0;
+}
+
+static struct spi_driver libertas_spi_driver = {
+ .probe = if_spi_probe,
+ .remove = __devexit_p(libertas_spi_remove),
+ .driver = {
+ .name = "libertas_spi",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+};
+
+/*
+ * Module functions
+ */
+
+static int __init if_spi_init_module(void)
+{
+ int ret = 0;
+ lbs_deb_enter(LBS_DEB_SPI);
+ printk(KERN_INFO "libertas_spi: Libertas SPI driver\n");
+ ret = spi_register_driver(&libertas_spi_driver);
+ lbs_deb_leave(LBS_DEB_SPI);
+ return ret;
+}
+
+static void __exit if_spi_exit_module(void)
+{
+ lbs_deb_enter(LBS_DEB_SPI);
+ spi_unregister_driver(&libertas_spi_driver);
+ lbs_deb_leave(LBS_DEB_SPI);
+}
+
+module_init(if_spi_init_module);
+module_exit(if_spi_exit_module);
+
+MODULE_DESCRIPTION("Libertas SPI WLAN Driver");
+MODULE_AUTHOR("Andrey Yurovsky <andrey@cozybit.com>, "
+ "Colin McCabe <colin@cozybit.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h
new file mode 100644
index 00000000000..2103869cc5b
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_spi.h
@@ -0,0 +1,208 @@
+/*
+ * linux/drivers/net/wireless/libertas/if_spi.c
+ *
+ * Driver for Marvell SPI WLAN cards.
+ *
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Authors:
+ * Andrey Yurovsky <andrey@cozybit.com>
+ * Colin McCabe <colin@cozybit.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.
+ */
+
+#ifndef _LBS_IF_SPI_H_
+#define _LBS_IF_SPI_H_
+
+#define IPFIELD_ALIGN_OFFSET 2
+#define IF_SPI_CMD_BUF_SIZE 2400
+
+/***************** Firmware *****************/
+struct chip_ident {
+ u16 chip_id;
+ u16 name;
+};
+
+#define MAX_MAIN_FW_LOAD_CRC_ERR 10
+
+/* Chunk size when loading the helper firmware */
+#define HELPER_FW_LOAD_CHUNK_SZ 64
+
+/* Value to write to indicate end of helper firmware dnld */
+#define FIRMWARE_DNLD_OK 0x0000
+
+/* Value to check once the main firmware is downloaded */
+#define SUCCESSFUL_FW_DOWNLOAD_MAGIC 0x88888888
+
+/***************** SPI Interface Unit *****************/
+/* Masks used in SPI register read/write operations */
+#define IF_SPI_READ_OPERATION_MASK 0x0
+#define IF_SPI_WRITE_OPERATION_MASK 0x8000
+
+/* SPI register offsets. 4-byte aligned. */
+#define IF_SPI_DEVICEID_CTRL_REG 0x00 /* DeviceID controller reg */
+#define IF_SPI_IO_READBASE_REG 0x04 /* Read I/O base reg */
+#define IF_SPI_IO_WRITEBASE_REG 0x08 /* Write I/O base reg */
+#define IF_SPI_IO_RDWRPORT_REG 0x0C /* Read/Write I/O port reg */
+
+#define IF_SPI_CMD_READBASE_REG 0x10 /* Read command base reg */
+#define IF_SPI_CMD_WRITEBASE_REG 0x14 /* Write command base reg */
+#define IF_SPI_CMD_RDWRPORT_REG 0x18 /* Read/Write command port reg */
+
+#define IF_SPI_DATA_READBASE_REG 0x1C /* Read data base reg */
+#define IF_SPI_DATA_WRITEBASE_REG 0x20 /* Write data base reg */
+#define IF_SPI_DATA_RDWRPORT_REG 0x24 /* Read/Write data port reg */
+
+#define IF_SPI_SCRATCH_1_REG 0x28 /* Scratch reg 1 */
+#define IF_SPI_SCRATCH_2_REG 0x2C /* Scratch reg 2 */
+#define IF_SPI_SCRATCH_3_REG 0x30 /* Scratch reg 3 */
+#define IF_SPI_SCRATCH_4_REG 0x34 /* Scratch reg 4 */
+
+#define IF_SPI_TX_FRAME_SEQ_NUM_REG 0x38 /* Tx frame sequence number reg */
+#define IF_SPI_TX_FRAME_STATUS_REG 0x3C /* Tx frame status reg */
+
+#define IF_SPI_HOST_INT_CTRL_REG 0x40 /* Host interrupt controller reg */
+
+#define IF_SPI_CARD_INT_CAUSE_REG 0x44 /* Card interrupt cause reg */
+#define IF_SPI_CARD_INT_STATUS_REG 0x48 /* Card interupt status reg */
+#define IF_SPI_CARD_INT_EVENT_MASK_REG 0x4C /* Card interrupt event mask */
+#define IF_SPI_CARD_INT_STATUS_MASK_REG 0x50 /* Card interrupt status mask */
+
+#define IF_SPI_CARD_INT_RESET_SELECT_REG 0x54 /* Card interrupt reset select */
+
+#define IF_SPI_HOST_INT_CAUSE_REG 0x58 /* Host interrupt cause reg */
+#define IF_SPI_HOST_INT_STATUS_REG 0x5C /* Host interrupt status reg */
+#define IF_SPI_HOST_INT_EVENT_MASK_REG 0x60 /* Host interrupt event mask */
+#define IF_SPI_HOST_INT_STATUS_MASK_REG 0x64 /* Host interrupt status mask */
+#define IF_SPI_HOST_INT_RESET_SELECT_REG 0x68 /* Host interrupt reset select */
+
+#define IF_SPI_DELAY_READ_REG 0x6C /* Delay read reg */
+#define IF_SPI_SPU_BUS_MODE_REG 0x70 /* SPU BUS mode reg */
+
+/***************** IF_SPI_DEVICEID_CTRL_REG *****************/
+#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dc) ((dc & 0xffff0000)>>16)
+#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff)
+
+/***************** IF_SPI_HOST_INT_CTRL_REG *****************/
+/** Host Interrupt Control bit : Wake up */
+#define IF_SPI_HICT_WAKE_UP (1<<0)
+/** Host Interrupt Control bit : WLAN ready */
+#define IF_SPI_HICT_WLAN_READY (1<<1)
+/*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY (1<<2) */
+/*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY (1<<3) */
+/*#define IF_SPI_HICT_IRQSRC_WLAN (1<<4) */
+/** Host Interrupt Control bit : Tx auto download */
+#define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO (1<<5)
+/** Host Interrupt Control bit : Rx auto upload */
+#define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO (1<<6)
+/** Host Interrupt Control bit : Command auto download */
+#define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO (1<<7)
+/** Host Interrupt Control bit : Command auto upload */
+#define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO (1<<8)
+
+/***************** IF_SPI_CARD_INT_CAUSE_REG *****************/
+/** Card Interrupt Case bit : Tx download over */
+#define IF_SPI_CIC_TX_DOWNLOAD_OVER (1<<0)
+/** Card Interrupt Case bit : Rx upload over */
+#define IF_SPI_CIC_RX_UPLOAD_OVER (1<<1)
+/** Card Interrupt Case bit : Command download over */
+#define IF_SPI_CIC_CMD_DOWNLOAD_OVER (1<<2)
+/** Card Interrupt Case bit : Host event */
+#define IF_SPI_CIC_HOST_EVENT (1<<3)
+/** Card Interrupt Case bit : Command upload over */
+#define IF_SPI_CIC_CMD_UPLOAD_OVER (1<<4)
+/** Card Interrupt Case bit : Power down */
+#define IF_SPI_CIC_POWER_DOWN (1<<5)
+
+/***************** IF_SPI_CARD_INT_STATUS_REG *****************/
+#define IF_SPI_CIS_TX_DOWNLOAD_OVER (1<<0)
+#define IF_SPI_CIS_RX_UPLOAD_OVER (1<<1)
+#define IF_SPI_CIS_CMD_DOWNLOAD_OVER (1<<2)
+#define IF_SPI_CIS_HOST_EVENT (1<<3)
+#define IF_SPI_CIS_CMD_UPLOAD_OVER (1<<4)
+#define IF_SPI_CIS_POWER_DOWN (1<<5)
+
+/***************** IF_SPI_HOST_INT_CAUSE_REG *****************/
+#define IF_SPI_HICU_TX_DOWNLOAD_RDY (1<<0)
+#define IF_SPI_HICU_RX_UPLOAD_RDY (1<<1)
+#define IF_SPI_HICU_CMD_DOWNLOAD_RDY (1<<2)
+#define IF_SPI_HICU_CARD_EVENT (1<<3)
+#define IF_SPI_HICU_CMD_UPLOAD_RDY (1<<4)
+#define IF_SPI_HICU_IO_WR_FIFO_OVERFLOW (1<<5)
+#define IF_SPI_HICU_IO_RD_FIFO_UNDERFLOW (1<<6)
+#define IF_SPI_HICU_DATA_WR_FIFO_OVERFLOW (1<<7)
+#define IF_SPI_HICU_DATA_RD_FIFO_UNDERFLOW (1<<8)
+#define IF_SPI_HICU_CMD_WR_FIFO_OVERFLOW (1<<9)
+#define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW (1<<10)
+
+/***************** IF_SPI_HOST_INT_STATUS_REG *****************/
+/** Host Interrupt Status bit : Tx download ready */
+#define IF_SPI_HIST_TX_DOWNLOAD_RDY (1<<0)
+/** Host Interrupt Status bit : Rx upload ready */
+#define IF_SPI_HIST_RX_UPLOAD_RDY (1<<1)
+/** Host Interrupt Status bit : Command download ready */
+#define IF_SPI_HIST_CMD_DOWNLOAD_RDY (1<<2)
+/** Host Interrupt Status bit : Card event */
+#define IF_SPI_HIST_CARD_EVENT (1<<3)
+/** Host Interrupt Status bit : Command upload ready */
+#define IF_SPI_HIST_CMD_UPLOAD_RDY (1<<4)
+/** Host Interrupt Status bit : I/O write FIFO overflow */
+#define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW (1<<5)
+/** Host Interrupt Status bit : I/O read FIFO underflow */
+#define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW (1<<6)
+/** Host Interrupt Status bit : Data write FIFO overflow */
+#define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW (1<<7)
+/** Host Interrupt Status bit : Data read FIFO underflow */
+#define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW (1<<8)
+/** Host Interrupt Status bit : Command write FIFO overflow */
+#define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW (1<<9)
+/** Host Interrupt Status bit : Command read FIFO underflow */
+#define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW (1<<10)
+
+/***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/
+/** Host Interrupt Status Mask bit : Tx download ready */
+#define IF_SPI_HISM_TX_DOWNLOAD_RDY (1<<0)
+/** Host Interrupt Status Mask bit : Rx upload ready */
+#define IF_SPI_HISM_RX_UPLOAD_RDY (1<<1)
+/** Host Interrupt Status Mask bit : Command download ready */
+#define IF_SPI_HISM_CMD_DOWNLOAD_RDY (1<<2)
+/** Host Interrupt Status Mask bit : Card event */
+#define IF_SPI_HISM_CARDEVENT (1<<3)
+/** Host Interrupt Status Mask bit : Command upload ready */
+#define IF_SPI_HISM_CMD_UPLOAD_RDY (1<<4)
+/** Host Interrupt Status Mask bit : I/O write FIFO overflow */
+#define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW (1<<5)
+/** Host Interrupt Status Mask bit : I/O read FIFO underflow */
+#define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW (1<<6)
+/** Host Interrupt Status Mask bit : Data write FIFO overflow */
+#define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW (1<<7)
+/** Host Interrupt Status Mask bit : Data write FIFO underflow */
+#define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW (1<<8)
+/** Host Interrupt Status Mask bit : Command write FIFO overflow */
+#define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW (1<<9)
+/** Host Interrupt Status Mask bit : Command write FIFO underflow */
+#define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW (1<<10)
+
+/***************** IF_SPI_SPU_BUS_MODE_REG *****************/
+/* SCK edge on which the WLAN module outputs data on MISO */
+#define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_FALLING 0x8
+#define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING 0x0
+
+/* In a SPU read operation, there is a delay between writing the SPU
+ * register name and getting back data from the WLAN module.
+ * This can be specified in terms of nanoseconds or in terms of dummy
+ * clock cycles which the master must output before receiving a response. */
+#define IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK 0x4
+#define IF_SPI_BUS_MODE_DELAY_METHOD_TIMED 0x0
+
+/* Some different modes of SPI operation */
+#define IF_SPI_BUS_MODE_8_BIT_ADDRESS_16_BIT_DATA 0x00
+#define IF_SPI_BUS_MODE_8_BIT_ADDRESS_32_BIT_DATA 0x01
+#define IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA 0x02
+#define IF_SPI_BUS_MODE_16_BIT_ADDRESS_32_BIT_DATA 0x03
+
+#endif
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 2fc637ad85c..ea3dc038be7 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -59,7 +59,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp);
static ssize_t if_usb_firmware_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct if_usb_card *cardp = priv->card;
char fwname[FIRMWARE_NAME_MAX];
int ret;
@@ -86,7 +86,7 @@ static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
static ssize_t if_usb_boot2_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct if_usb_card *cardp = priv->card;
char fwname[FIRMWARE_NAME_MAX];
int ret;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 4e0007d2003..8ae935ac32f 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -222,7 +222,7 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
static ssize_t lbs_anycast_get(struct device *dev,
struct device_attribute *attr, char * buf)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_access mesh_access;
int ret;
@@ -241,7 +241,7 @@ static ssize_t lbs_anycast_get(struct device *dev,
static ssize_t lbs_anycast_set(struct device *dev,
struct device_attribute *attr, const char * buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_access mesh_access;
uint32_t datum;
int ret;
@@ -263,7 +263,7 @@ static ssize_t lbs_anycast_set(struct device *dev,
static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_access mesh_access;
int ret;
u32 retry_limit;
@@ -286,7 +286,7 @@ static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_access mesh_access;
int ret;
unsigned long retry_limit;
@@ -321,7 +321,7 @@ static void lbs_remove_mesh(struct lbs_private *priv);
static ssize_t lbs_rtap_get(struct device *dev,
struct device_attribute *attr, char * buf)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
return snprintf(buf, 5, "0x%X\n", priv->monitormode);
}
@@ -332,7 +332,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
struct device_attribute *attr, const char * buf, size_t count)
{
int monitor_mode;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
sscanf(buf, "%x", &monitor_mode);
if (monitor_mode) {
@@ -383,7 +383,7 @@ static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
static ssize_t lbs_mesh_get(struct device *dev,
struct device_attribute *attr, char * buf)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
}
@@ -393,7 +393,7 @@ static ssize_t lbs_mesh_get(struct device *dev,
static ssize_t lbs_mesh_set(struct device *dev,
struct device_attribute *attr, const char * buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
int enable;
int ret, action = CMD_ACT_MESH_CONFIG_STOP;
@@ -452,7 +452,7 @@ static struct attribute_group lbs_mesh_attr_group = {
*/
static int lbs_dev_open(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev) ;
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
lbs_deb_enter(LBS_DEB_NET);
@@ -521,7 +521,7 @@ static int lbs_mesh_stop(struct net_device *dev)
*/
static int lbs_eth_stop(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_NET);
@@ -538,7 +538,7 @@ static int lbs_eth_stop(struct net_device *dev)
static void lbs_tx_timeout(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_TX);
@@ -582,24 +582,10 @@ void lbs_host_to_card_done(struct lbs_private *priv)
}
EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
-/**
- * @brief This function returns the network statistics
- *
- * @param dev A pointer to struct lbs_private structure
- * @return A pointer to net_device_stats structure
- */
-static struct net_device_stats *lbs_get_stats(struct net_device *dev)
-{
- struct lbs_private *priv = netdev_priv(dev);
-
- lbs_deb_enter(LBS_DEB_NET);
- return &priv->stats;
-}
-
static int lbs_set_mac_address(struct net_device *dev, void *addr)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct sockaddr *phwaddr = addr;
struct cmd_ds_802_11_mac_address cmd;
@@ -732,7 +718,7 @@ static void lbs_set_mcast_worker(struct work_struct *work)
static void lbs_set_multicast_list(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
schedule_work(&priv->mcast_work);
}
@@ -748,7 +734,7 @@ static void lbs_set_multicast_list(struct net_device *dev)
static int lbs_thread(void *data)
{
struct net_device *dev = data;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
wait_queue_t wait;
lbs_deb_enter(LBS_DEB_THREAD);
@@ -1006,9 +992,8 @@ void lbs_resume(struct lbs_private *priv)
EXPORT_SYMBOL_GPL(lbs_resume);
/**
- * @brief This function downloads firmware image, gets
- * HW spec from firmware and set basic parameters to
- * firmware.
+ * @brief This function gets the HW spec from the firmware and sets
+ * some basic parameters.
*
* @param priv A pointer to struct lbs_private structure
* @return 0 or -1
@@ -1163,6 +1148,17 @@ static void lbs_free_adapter(struct lbs_private *priv)
lbs_deb_leave(LBS_DEB_MAIN);
}
+static const struct net_device_ops lbs_netdev_ops = {
+ .ndo_open = lbs_dev_open,
+ .ndo_stop = lbs_eth_stop,
+ .ndo_start_xmit = lbs_hard_start_xmit,
+ .ndo_set_mac_address = lbs_set_mac_address,
+ .ndo_tx_timeout = lbs_tx_timeout,
+ .ndo_set_multicast_list = lbs_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/**
* @brief This function adds the card. it will probe the
* card, allocate the lbs_priv and initialize the device.
@@ -1184,6 +1180,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
goto done;
}
priv = netdev_priv(dev);
+ dev->ml_priv = priv;
if (lbs_init_adapter(priv)) {
lbs_pr_err("failed to initialize adapter structure.\n");
@@ -1196,19 +1193,13 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
priv->infra_open = 0;
/* Setup the OS Interface to our functions */
- dev->open = lbs_dev_open;
- dev->hard_start_xmit = lbs_hard_start_xmit;
- dev->stop = lbs_eth_stop;
- dev->set_mac_address = lbs_set_mac_address;
- dev->tx_timeout = lbs_tx_timeout;
- dev->get_stats = lbs_get_stats;
+ dev->netdev_ops = &lbs_netdev_ops;
dev->watchdog_timeo = 5 * HZ;
dev->ethtool_ops = &lbs_ethtool_ops;
#ifdef WIRELESS_EXT
- dev->wireless_handlers = (struct iw_handler_def *)&lbs_handler_def;
+ dev->wireless_handlers = &lbs_handler_def;
#endif
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
- dev->set_multicast_list = lbs_set_multicast_list;
SET_NETDEV_DEV(dev, dmdev);
@@ -1418,6 +1409,14 @@ out:
EXPORT_SYMBOL_GPL(lbs_stop_card);
+static const struct net_device_ops mesh_netdev_ops = {
+ .ndo_open = lbs_dev_open,
+ .ndo_stop = lbs_mesh_stop,
+ .ndo_start_xmit = lbs_hard_start_xmit,
+ .ndo_set_mac_address = lbs_set_mac_address,
+ .ndo_set_multicast_list = lbs_set_multicast_list,
+};
+
/**
* @brief This function adds mshX interface
*
@@ -1440,11 +1439,7 @@ static int lbs_add_mesh(struct lbs_private *priv)
mesh_dev->ml_priv = priv;
priv->mesh_dev = mesh_dev;
- mesh_dev->open = lbs_dev_open;
- mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
- mesh_dev->stop = lbs_mesh_stop;
- mesh_dev->get_stats = lbs_get_stats;
- mesh_dev->set_mac_address = lbs_set_mac_address;
+ mesh_dev->netdev_ops = &mesh_netdev_ops;
mesh_dev->ethtool_ops = &lbs_ethtool_ops;
memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
sizeof(priv->dev->dev_addr));
@@ -1455,7 +1450,6 @@ static int lbs_add_mesh(struct lbs_private *priv)
mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
#endif
mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
- mesh_dev->set_multicast_list = lbs_set_multicast_list;
/* Register virtual mesh interface */
ret = register_netdev(mesh_dev);
if (ret) {
@@ -1648,14 +1642,6 @@ static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
-static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
- lbs_deb_enter(LBS_DEB_NET);
- return &priv->stats;
-}
-
-
static void lbs_remove_rtap(struct lbs_private *priv)
{
lbs_deb_enter(LBS_DEB_MAIN);
@@ -1668,6 +1654,12 @@ out:
lbs_deb_leave(LBS_DEB_MAIN);
}
+static const struct net_device_ops rtap_netdev_ops = {
+ .ndo_open = lbs_rtap_open,
+ .ndo_stop = lbs_rtap_stop,
+ .ndo_start_xmit = lbs_rtap_hard_start_xmit,
+};
+
static int lbs_add_rtap(struct lbs_private *priv)
{
int ret = 0;
@@ -1687,10 +1679,7 @@ static int lbs_add_rtap(struct lbs_private *priv)
memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
- rtap_dev->open = lbs_rtap_open;
- rtap_dev->stop = lbs_rtap_stop;
- rtap_dev->get_stats = lbs_rtap_get_stats;
- rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
+ rtap_dev->netdev_ops = &rtap_netdev_ops;
rtap_dev->ml_priv = priv;
SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent);
diff --git a/drivers/net/wireless/libertas/persistcfg.c b/drivers/net/wireless/libertas/persistcfg.c
index d42b7a5a1b3..18fe29faf99 100644
--- a/drivers/net/wireless/libertas/persistcfg.c
+++ b/drivers/net/wireless/libertas/persistcfg.c
@@ -18,7 +18,7 @@
static int mesh_get_default_parameters(struct device *dev,
struct mrvl_mesh_defaults *defs)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_config cmd;
int ret;
@@ -57,7 +57,7 @@ static ssize_t bootflag_get(struct device *dev,
static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_config cmd;
uint32_t datum;
int ret;
@@ -100,7 +100,7 @@ static ssize_t boottime_get(struct device *dev,
static ssize_t boottime_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_config cmd;
uint32_t datum;
int ret;
@@ -152,7 +152,7 @@ static ssize_t channel_get(struct device *dev,
static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_config cmd;
uint32_t datum;
int ret;
@@ -210,7 +210,7 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
struct cmd_ds_mesh_config cmd;
struct mrvl_mesh_defaults defs;
struct mrvl_meshie *ie;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
int len;
int ret;
@@ -269,7 +269,7 @@ static ssize_t protocol_id_set(struct device *dev,
struct cmd_ds_mesh_config cmd;
struct mrvl_mesh_defaults defs;
struct mrvl_meshie *ie;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
uint32_t datum;
int ret;
@@ -323,7 +323,7 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
struct cmd_ds_mesh_config cmd;
struct mrvl_mesh_defaults defs;
struct mrvl_meshie *ie;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
uint32_t datum;
int ret;
@@ -377,7 +377,7 @@ static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
struct cmd_ds_mesh_config cmd;
struct mrvl_mesh_defaults defs;
struct mrvl_meshie *ie;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
uint32_t datum;
int ret;
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 079e6aa874d..4f60948dde9 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -168,7 +168,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
lbs_deb_rx("rx err: frame received with bad length\n");
- priv->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
ret = 0;
goto done;
}
@@ -179,7 +179,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
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");
- priv->stats.rx_errors++;
+ dev->stats.rx_errors++;
ret = 0;
goto done;
}
@@ -243,8 +243,8 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
lbs_compute_rssi(priv, p_rx_pd);
lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
- priv->stats.rx_bytes += skb->len;
- priv->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
skb->protocol = eth_type_trans(skb, dev);
if (in_interrupt())
@@ -311,7 +311,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
struct sk_buff *skb)
{
int ret = 0;
-
+ struct net_device *dev = priv->dev;
struct rx80211packethdr *p_rx_pkt;
struct rxpd *prxpd;
struct rx_radiotap_hdr radiotap_hdr;
@@ -326,7 +326,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
lbs_deb_rx("rx err: frame received with bad length\n");
- priv->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
ret = -EINVAL;
kfree_skb(skb);
goto done;
@@ -337,7 +337,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
*/
if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
//lbs_deb_rx("rx err: frame received with bad status\n");
- priv->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
@@ -389,8 +389,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
lbs_compute_rssi(priv, prxpd);
lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
- priv->stats.rx_bytes += skb->len;
- priv->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
netif_rx(skb);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 57f6c12cda2..8124db36aaf 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -692,7 +692,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
bss->wpa_ie_len);
} else if (pos[1] >= MARVELL_MESH_IE_LENGTH &&
pos[2] == 0x00 && pos[3] == 0x50 &&
- pos[4] == 0x43 && pos[4] == 0x04) {
+ pos[4] == 0x43 && pos[5] == 0x04) {
lbs_deb_scan("got mesh IE\n");
bss->mesh = 1;
} else {
@@ -945,7 +945,7 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
DECLARE_SSID_BUF(ssid);
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1008,7 +1008,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
#define SCAN_ITEM_SIZE 128
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int err = 0;
char *ev = extra;
char *stop = ev + dwrq->length;
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index dac46264117..f10aa39a6b6 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -60,7 +60,7 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned long flags;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct txpd *txpd;
char *p802x_hdr;
uint16_t pkt_len;
@@ -82,8 +82,8 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
/* We'll never manage to send this one; drop it and return 'OK' */
- priv->stats.tx_dropped++;
- priv->stats.tx_errors++;
+ dev->stats.tx_dropped++;
+ dev->stats.tx_errors++;
goto free;
}
@@ -146,8 +146,8 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
lbs_deb_tx("%s lined up packet\n", __func__);
- priv->stats.tx_packets++;
- priv->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev->trans_start = jiffies;
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index c6102e08179..8bc1907458b 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -163,7 +163,7 @@ static int lbs_get_name(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct chan_freq_power *cfp;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -189,7 +189,7 @@ static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
struct sockaddr *awrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -207,7 +207,7 @@ static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -231,7 +231,7 @@ static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -248,7 +248,7 @@ static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -273,7 +273,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
u32 val = vwrq->value;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -293,7 +293,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u16 val = 0;
@@ -315,7 +315,7 @@ out:
static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u32 val = vwrq->value;
@@ -336,7 +336,7 @@ static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u16 val = 0;
@@ -359,7 +359,7 @@ out:
static int lbs_get_mode(struct net_device *dev,
struct iw_request_info *info, u32 * uwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -385,7 +385,7 @@ static int lbs_get_txpow(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
s16 curlevel = 0;
int ret = 0;
@@ -418,7 +418,7 @@ out:
static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u16 slimit = 0, llimit = 0;
@@ -466,7 +466,7 @@ out:
static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u16 val = 0;
@@ -542,7 +542,7 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
int i, j;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct iw_range *range = (struct iw_range *)extra;
struct chan_freq_power *cfp;
u8 rates[MAX_RATES + 1];
@@ -708,7 +708,7 @@ out:
static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -758,7 +758,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_power(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -781,7 +781,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
EXCELLENT = 95,
PERFECT = 100
};
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
u32 rssi_qual;
u32 tx_qual;
u32 quality = 0;
@@ -830,7 +830,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
quality = rssi_qual;
/* Quality by TX errors */
- priv->wstats.discard.retries = priv->stats.tx_errors;
+ priv->wstats.discard.retries = dev->stats.tx_errors;
memset(&log, 0, sizeof(log));
log.hdr.size = cpu_to_le16(sizeof(log));
@@ -886,7 +886,7 @@ static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
int ret = -EINVAL;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct chan_freq_power *cfp;
struct assoc_request * assoc_req;
@@ -943,7 +943,7 @@ static int lbs_mesh_set_freq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct chan_freq_power *cfp;
int ret = -EINVAL;
@@ -994,7 +994,7 @@ out:
static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
u8 new_rate = 0;
int ret = -EINVAL;
u8 rates[MAX_RATES + 1];
@@ -1054,7 +1054,7 @@ out:
static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1079,7 +1079,7 @@ static int lbs_set_mode(struct net_device *dev,
struct iw_request_info *info, u32 * uwrq, char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct assoc_request * assoc_req;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1124,7 +1124,7 @@ static int lbs_get_encode(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *dwrq, u8 * extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1319,7 +1319,7 @@ static int lbs_set_encode(struct net_device *dev,
struct iw_point *dwrq, char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct assoc_request * assoc_req;
u16 is_default = 0, index = 0, set_tx_key = 0;
@@ -1395,7 +1395,7 @@ static int lbs_get_encodeext(struct net_device *dev,
char *extra)
{
int ret = -EINVAL;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int index, max_key_len;
@@ -1501,7 +1501,7 @@ static int lbs_set_encodeext(struct net_device *dev,
char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int alg = ext->alg;
struct assoc_request * assoc_req;
@@ -1639,7 +1639,7 @@ static int lbs_set_genie(struct net_device *dev,
struct iw_point *dwrq,
char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
struct assoc_request * assoc_req;
@@ -1685,7 +1685,7 @@ static int lbs_get_genie(struct net_device *dev,
char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1713,7 +1713,7 @@ static int lbs_set_auth(struct net_device *dev,
struct iw_param *dwrq,
char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct assoc_request * assoc_req;
int ret = 0;
int updated = 0;
@@ -1816,7 +1816,7 @@ static int lbs_get_auth(struct net_device *dev,
char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1857,7 +1857,7 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
s16 dbm = (s16) vwrq->value;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1936,7 +1936,7 @@ out:
static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1971,7 +1971,7 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u8 ssid[IW_ESSID_MAX_SIZE];
u8 ssid_len = 0;
@@ -2040,7 +2040,7 @@ static int lbs_mesh_get_essid(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -2058,7 +2058,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -2102,7 +2102,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
struct sockaddr *awrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct assoc_request * assoc_req;
int ret = 0;
diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c
index 3d3914c83b1..28790e03dc4 100644
--- a/drivers/net/wireless/libertas_tf/cmd.c
+++ b/drivers/net/wireless/libertas_tf/cmd.c
@@ -286,7 +286,7 @@ void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode)
lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd));
}
-void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid)
+void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
{
struct cmd_ds_set_bssid cmd;
diff --git a/drivers/net/wireless/libertas_tf/libertas_tf.h b/drivers/net/wireless/libertas_tf/libertas_tf.h
index 8995cd7c29b..4cc42dd5a00 100644
--- a/drivers/net/wireless/libertas_tf/libertas_tf.h
+++ b/drivers/net/wireless/libertas_tf/libertas_tf.h
@@ -463,7 +463,7 @@ int lbtf_set_radio_control(struct lbtf_private *priv);
int lbtf_update_hw_spec(struct lbtf_private *priv);
int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv);
void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode);
-void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid);
+void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid);
int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr);
int lbtf_set_channel(struct lbtf_private *priv, u8 channel);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index f83d69e813d..2368b7f825a 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -10,7 +10,6 @@
/*
* TODO:
* - IBSS mode simulation (Beacon transmission with competition for "air time")
- * - IEEE 802.11a and 802.11n modes
* - RX filtering based on filter configuration (data->rx_filter)
*/
@@ -31,6 +30,112 @@ static int radios = 2;
module_param(radios, int, 0444);
MODULE_PARM_DESC(radios, "Number of simulated radios");
+/**
+ * enum hwsim_regtest - the type of regulatory tests we offer
+ *
+ * These are the different values you can use for the regtest
+ * module parameter. This is useful to help test world roaming
+ * and the driver regulatory_hint() call and combinations of these.
+ * If you want to do specific alpha2 regulatory domain tests simply
+ * use the userspace regulatory request as that will be respected as
+ * well without the need of this module parameter. This is designed
+ * only for testing the driver regulatory request, world roaming
+ * and all possible combinations.
+ *
+ * @HWSIM_REGTEST_DISABLED: No regulatory tests are performed,
+ * this is the default value.
+ * @HWSIM_REGTEST_DRIVER_REG_FOLLOW: Used for testing the driver regulatory
+ * hint, only one driver regulatory hint will be sent as such the
+ * secondary radios are expected to follow.
+ * @HWSIM_REGTEST_DRIVER_REG_ALL: Used for testing the driver regulatory
+ * request with all radios reporting the same regulatory domain.
+ * @HWSIM_REGTEST_DIFF_COUNTRY: Used for testing the drivers calling
+ * different regulatory domains requests. Expected behaviour is for
+ * an intersection to occur but each device will still use their
+ * respective regulatory requested domains. Subsequent radios will
+ * use the resulting intersection.
+ * @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We acomplish
+ * this by using a custom beacon-capable regulatory domain for the first
+ * radio. All other device world roam.
+ * @HWSIM_REGTEST_CUSTOM_WORLD: Used for testing the custom world regulatory
+ * domain requests. All radios will adhere to this custom world regulatory
+ * domain.
+ * @HWSIM_REGTEST_CUSTOM_WORLD_2: Used for testing 2 custom world regulatory
+ * domain requests. The first radio will adhere to the first custom world
+ * regulatory domain, the second one to the second custom world regulatory
+ * domain. All other devices will world roam.
+ * @HWSIM_REGTEST_STRICT_FOLLOW_: Used for testing strict regulatory domain
+ * settings, only the first radio will send a regulatory domain request
+ * and use strict settings. The rest of the radios are expected to follow.
+ * @HWSIM_REGTEST_STRICT_ALL: Used for testing strict regulatory domain
+ * settings. All radios will adhere to this.
+ * @HWSIM_REGTEST_STRICT_AND_DRIVER_REG: Used for testing strict regulatory
+ * domain settings, combined with secondary driver regulatory domain
+ * settings. The first radio will get a strict regulatory domain setting
+ * using the first driver regulatory request and the second radio will use
+ * non-strict settings using the second driver regulatory request. All
+ * other devices should follow the intersection created between the
+ * first two.
+ * @HWSIM_REGTEST_ALL: Used for testing every possible mix. You will need
+ * at least 6 radios for a complete test. We will test in this order:
+ * 1 - driver custom world regulatory domain
+ * 2 - second custom world regulatory domain
+ * 3 - first driver regulatory domain request
+ * 4 - second driver regulatory domain request
+ * 5 - strict regulatory domain settings using the third driver regulatory
+ * domain request
+ * 6 and on - should follow the intersection of the 3rd, 4rth and 5th radio
+ * regulatory requests.
+ */
+enum hwsim_regtest {
+ HWSIM_REGTEST_DISABLED = 0,
+ HWSIM_REGTEST_DRIVER_REG_FOLLOW = 1,
+ HWSIM_REGTEST_DRIVER_REG_ALL = 2,
+ HWSIM_REGTEST_DIFF_COUNTRY = 3,
+ HWSIM_REGTEST_WORLD_ROAM = 4,
+ HWSIM_REGTEST_CUSTOM_WORLD = 5,
+ HWSIM_REGTEST_CUSTOM_WORLD_2 = 6,
+ HWSIM_REGTEST_STRICT_FOLLOW = 7,
+ HWSIM_REGTEST_STRICT_ALL = 8,
+ HWSIM_REGTEST_STRICT_AND_DRIVER_REG = 9,
+ HWSIM_REGTEST_ALL = 10,
+};
+
+/* Set to one of the HWSIM_REGTEST_* values above */
+static int regtest = HWSIM_REGTEST_DISABLED;
+module_param(regtest, int, 0444);
+MODULE_PARM_DESC(regtest, "The type of regulatory test we want to run");
+
+static const char *hwsim_alpha2s[] = {
+ "FI",
+ "AL",
+ "US",
+ "DE",
+ "JP",
+ "AL",
+};
+
+static const struct ieee80211_regdomain hwsim_world_regdom_custom_01 = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
+ REG_RULE(2484-10, 2484+10, 40, 0, 20, 0),
+ REG_RULE(5150-10, 5240+10, 40, 0, 30, 0),
+ REG_RULE(5745-10, 5825+10, 40, 0, 30, 0),
+ }
+};
+
+static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
+ .n_reg_rules = 2,
+ .alpha2 = "99",
+ .reg_rules = {
+ REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
+ REG_RULE(5725-10, 5850+10, 40, 0, 30,
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
+ }
+};
+
struct hwsim_vif_priv {
u32 magic;
u8 bssid[ETH_ALEN];
@@ -86,22 +191,65 @@ static struct class *hwsim_class;
static struct net_device *hwsim_mon; /* global monitor netdev */
+#define CHAN2G(_freq) { \
+ .band = IEEE80211_BAND_2GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_freq), \
+ .max_power = 20, \
+}
+
+#define CHAN5G(_freq) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_freq), \
+ .max_power = 20, \
+}
-static const struct ieee80211_channel hwsim_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_channel hwsim_channels_2ghz[] = {
+ CHAN2G(2412), /* Channel 1 */
+ CHAN2G(2417), /* Channel 2 */
+ CHAN2G(2422), /* Channel 3 */
+ CHAN2G(2427), /* Channel 4 */
+ CHAN2G(2432), /* Channel 5 */
+ CHAN2G(2437), /* Channel 6 */
+ CHAN2G(2442), /* Channel 7 */
+ CHAN2G(2447), /* Channel 8 */
+ CHAN2G(2452), /* Channel 9 */
+ CHAN2G(2457), /* Channel 10 */
+ CHAN2G(2462), /* Channel 11 */
+ CHAN2G(2467), /* Channel 12 */
+ CHAN2G(2472), /* Channel 13 */
+ CHAN2G(2484), /* Channel 14 */
+};
+
+static const struct ieee80211_channel hwsim_channels_5ghz[] = {
+ CHAN5G(5180), /* Channel 36 */
+ CHAN5G(5200), /* Channel 40 */
+ CHAN5G(5220), /* Channel 44 */
+ CHAN5G(5240), /* Channel 48 */
+
+ CHAN5G(5260), /* Channel 52 */
+ CHAN5G(5280), /* Channel 56 */
+ CHAN5G(5300), /* Channel 60 */
+ CHAN5G(5320), /* Channel 64 */
+
+ CHAN5G(5500), /* Channel 100 */
+ CHAN5G(5520), /* Channel 104 */
+ CHAN5G(5540), /* Channel 108 */
+ CHAN5G(5560), /* Channel 112 */
+ CHAN5G(5580), /* Channel 116 */
+ CHAN5G(5600), /* Channel 120 */
+ CHAN5G(5620), /* Channel 124 */
+ CHAN5G(5640), /* Channel 128 */
+ CHAN5G(5660), /* Channel 132 */
+ CHAN5G(5680), /* Channel 136 */
+ CHAN5G(5700), /* Channel 140 */
+
+ CHAN5G(5745), /* Channel 149 */
+ CHAN5G(5765), /* Channel 153 */
+ CHAN5G(5785), /* Channel 157 */
+ CHAN5G(5805), /* Channel 161 */
+ CHAN5G(5825), /* Channel 165 */
};
static const struct ieee80211_rate hwsim_rates[] = {
@@ -126,8 +274,9 @@ struct mac80211_hwsim_data {
struct list_head list;
struct ieee80211_hw *hw;
struct device *dev;
- struct ieee80211_supported_band band;
- struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)];
+ struct ieee80211_supported_band bands[2];
+ struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
+ struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
struct ieee80211_channel *channel;
@@ -590,10 +739,16 @@ static struct device_driver mac80211_hwsim_driver = {
.name = "mac80211_hwsim"
};
+static const struct net_device_ops hwsim_netdev_ops = {
+ .ndo_start_xmit = hwsim_mon_xmit,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static void hwsim_mon_setup(struct net_device *dev)
{
- dev->hard_start_xmit = hwsim_mon_xmit;
+ dev->netdev_ops = &hwsim_netdev_ops;
dev->destructor = free_netdev;
ether_setup(dev);
dev->tx_queue_len = 0;
@@ -728,6 +883,7 @@ static int __init init_mac80211_hwsim(void)
u8 addr[ETH_ALEN];
struct mac80211_hwsim_data *data;
struct ieee80211_hw *hw;
+ enum ieee80211_band band;
if (radios < 1 || radios > 100)
return -EINVAL;
@@ -779,29 +935,111 @@ static int __init init_mac80211_hwsim(void)
BIT(NL80211_IFTYPE_MESH_POINT);
hw->ampdu_queues = 1;
+ hw->flags = IEEE80211_HW_MFP_CAPABLE;
+
/* ask mac80211 to reserve space for magic */
hw->vif_data_size = sizeof(struct hwsim_vif_priv);
hw->sta_data_size = sizeof(struct hwsim_sta_priv);
- memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
+ memcpy(data->channels_2ghz, hwsim_channels_2ghz,
+ sizeof(hwsim_channels_2ghz));
+ memcpy(data->channels_5ghz, hwsim_channels_5ghz,
+ sizeof(hwsim_channels_5ghz));
memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
- data->band.channels = data->channels;
- data->band.n_channels = ARRAY_SIZE(hwsim_channels);
- data->band.bitrates = data->rates;
- data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
- data->band.ht_cap.ht_supported = true;
- data->band.ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
- IEEE80211_HT_CAP_GRN_FLD |
- IEEE80211_HT_CAP_SGI_40 |
- IEEE80211_HT_CAP_DSSSCCK40;
- data->band.ht_cap.ampdu_factor = 0x3;
- data->band.ht_cap.ampdu_density = 0x6;
- memset(&data->band.ht_cap.mcs, 0,
- sizeof(data->band.ht_cap.mcs));
- data->band.ht_cap.mcs.rx_mask[0] = 0xff;
- data->band.ht_cap.mcs.rx_mask[1] = 0xff;
- data->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
+
+ for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
+ struct ieee80211_supported_band *sband = &data->bands[band];
+ switch (band) {
+ case IEEE80211_BAND_2GHZ:
+ sband->channels = data->channels_2ghz;
+ sband->n_channels =
+ ARRAY_SIZE(hwsim_channels_2ghz);
+ break;
+ case IEEE80211_BAND_5GHZ:
+ sband->channels = data->channels_5ghz;
+ sband->n_channels =
+ ARRAY_SIZE(hwsim_channels_5ghz);
+ break;
+ default:
+ break;
+ }
+
+ sband->bitrates = data->rates;
+ sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
+
+ sband->ht_cap.ht_supported = true;
+ sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_DSSSCCK40;
+ sband->ht_cap.ampdu_factor = 0x3;
+ sband->ht_cap.ampdu_density = 0x6;
+ memset(&sband->ht_cap.mcs, 0,
+ sizeof(sband->ht_cap.mcs));
+ sband->ht_cap.mcs.rx_mask[0] = 0xff;
+ sband->ht_cap.mcs.rx_mask[1] = 0xff;
+ sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+
+ hw->wiphy->bands[band] = sband;
+ }
+
+ /* Work to be done prior to ieee80211_register_hw() */
+ switch (regtest) {
+ case HWSIM_REGTEST_DISABLED:
+ case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
+ case HWSIM_REGTEST_DRIVER_REG_ALL:
+ case HWSIM_REGTEST_DIFF_COUNTRY:
+ /*
+ * Nothing to be done for driver regulatory domain
+ * hints prior to ieee80211_register_hw()
+ */
+ break;
+ case HWSIM_REGTEST_WORLD_ROAM:
+ if (i == 0) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_01);
+ }
+ break;
+ case HWSIM_REGTEST_CUSTOM_WORLD:
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_01);
+ break;
+ case HWSIM_REGTEST_CUSTOM_WORLD_2:
+ if (i == 0) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_01);
+ } else if (i == 1) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_02);
+ }
+ break;
+ case HWSIM_REGTEST_STRICT_ALL:
+ hw->wiphy->strict_regulatory = true;
+ break;
+ case HWSIM_REGTEST_STRICT_FOLLOW:
+ case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
+ if (i == 0)
+ hw->wiphy->strict_regulatory = true;
+ break;
+ case HWSIM_REGTEST_ALL:
+ if (i == 0) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_01);
+ } else if (i == 1) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_02);
+ } else if (i == 4)
+ hw->wiphy->strict_regulatory = true;
+ break;
+ default:
+ break;
+ }
err = ieee80211_register_hw(hw);
if (err < 0) {
@@ -810,6 +1048,52 @@ static int __init init_mac80211_hwsim(void)
goto failed_hw;
}
+ /* Work to be done after to ieee80211_register_hw() */
+ switch (regtest) {
+ case HWSIM_REGTEST_WORLD_ROAM:
+ case HWSIM_REGTEST_DISABLED:
+ break;
+ case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
+ if (!i)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ break;
+ case HWSIM_REGTEST_DRIVER_REG_ALL:
+ case HWSIM_REGTEST_STRICT_ALL:
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ break;
+ case HWSIM_REGTEST_DIFF_COUNTRY:
+ if (i < ARRAY_SIZE(hwsim_alpha2s))
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[i]);
+ break;
+ case HWSIM_REGTEST_CUSTOM_WORLD:
+ case HWSIM_REGTEST_CUSTOM_WORLD_2:
+ /*
+ * Nothing to be done for custom world regulatory
+ * domains after to ieee80211_register_hw
+ */
+ break;
+ case HWSIM_REGTEST_STRICT_FOLLOW:
+ if (i == 0)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ break;
+ case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
+ if (i == 0)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ else if (i == 1)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[1]);
+ break;
+ case HWSIM_REGTEST_ALL:
+ if (i == 2)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ else if (i == 3)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[1]);
+ else if (i == 4)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[2]);
+ break;
+ default:
+ break;
+ }
+
printk(KERN_DEBUG "%s: hwaddr %pM registered\n",
wiphy_name(hw->wiphy),
hw->wiphy->perm_addr);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
new file mode 100644
index 00000000000..57a0268d1ba
--- /dev/null
+++ b/drivers/net/wireless/mwl8k.c
@@ -0,0 +1,3789 @@
+/*
+ * drivers/net/wireless/mwl8k.c driver for Marvell TOPDOG 802.11 Wireless cards
+ *
+ * Copyright (C) 2008 Marvell Semiconductor Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/workqueue.h>
+
+#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
+#define MWL8K_NAME KBUILD_MODNAME
+#define MWL8K_VERSION "0.9.1"
+
+MODULE_DESCRIPTION(MWL8K_DESC);
+MODULE_VERSION(MWL8K_VERSION);
+MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
+MODULE_LICENSE("GPL");
+
+static DEFINE_PCI_DEVICE_TABLE(mwl8k_table) = {
+ { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = 8687, },
+ { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = 8687, },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, mwl8k_table);
+
+#define IEEE80211_ADDR_LEN ETH_ALEN
+
+/* Register definitions */
+#define MWL8K_HIU_GEN_PTR 0x00000c10
+#define MWL8K_MODE_STA 0x0000005a
+#define MWL8K_MODE_AP 0x000000a5
+#define MWL8K_HIU_INT_CODE 0x00000c14
+#define MWL8K_FWSTA_READY 0xf0f1f2f4
+#define MWL8K_FWAP_READY 0xf1f2f4a5
+#define MWL8K_INT_CODE_CMD_FINISHED 0x00000005
+#define MWL8K_HIU_SCRATCH 0x00000c40
+
+/* Host->device communications */
+#define MWL8K_HIU_H2A_INTERRUPT_EVENTS 0x00000c18
+#define MWL8K_HIU_H2A_INTERRUPT_STATUS 0x00000c1c
+#define MWL8K_HIU_H2A_INTERRUPT_MASK 0x00000c20
+#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL 0x00000c24
+#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK 0x00000c28
+#define MWL8K_H2A_INT_DUMMY (1 << 20)
+#define MWL8K_H2A_INT_RESET (1 << 15)
+#define MWL8K_H2A_INT_PS (1 << 2)
+#define MWL8K_H2A_INT_DOORBELL (1 << 1)
+#define MWL8K_H2A_INT_PPA_READY (1 << 0)
+
+/* Device->host communications */
+#define MWL8K_HIU_A2H_INTERRUPT_EVENTS 0x00000c2c
+#define MWL8K_HIU_A2H_INTERRUPT_STATUS 0x00000c30
+#define MWL8K_HIU_A2H_INTERRUPT_MASK 0x00000c34
+#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38
+#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c
+#define MWL8K_A2H_INT_DUMMY (1 << 20)
+#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11)
+#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10)
+#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7)
+#define MWL8K_A2H_INT_RADIO_ON (1 << 6)
+#define MWL8K_A2H_INT_RADIO_OFF (1 << 5)
+#define MWL8K_A2H_INT_MAC_EVENT (1 << 3)
+#define MWL8K_A2H_INT_OPC_DONE (1 << 2)
+#define MWL8K_A2H_INT_RX_READY (1 << 1)
+#define MWL8K_A2H_INT_TX_DONE (1 << 0)
+
+#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \
+ MWL8K_A2H_INT_CHNL_SWITCHED | \
+ MWL8K_A2H_INT_QUEUE_EMPTY | \
+ MWL8K_A2H_INT_RADAR_DETECT | \
+ MWL8K_A2H_INT_RADIO_ON | \
+ MWL8K_A2H_INT_RADIO_OFF | \
+ MWL8K_A2H_INT_MAC_EVENT | \
+ MWL8K_A2H_INT_OPC_DONE | \
+ MWL8K_A2H_INT_RX_READY | \
+ MWL8K_A2H_INT_TX_DONE)
+
+/* WME stream classes */
+#define WME_AC_BE 0 /* best effort */
+#define WME_AC_BK 1 /* background */
+#define WME_AC_VI 2 /* video */
+#define WME_AC_VO 3 /* voice */
+
+#define MWL8K_RX_QUEUES 1
+#define MWL8K_TX_QUEUES 4
+
+struct mwl8k_rx_queue {
+ int rx_desc_count;
+
+ /* hw receives here */
+ int rx_head;
+
+ /* refill descs here */
+ int rx_tail;
+
+ struct mwl8k_rx_desc *rx_desc_area;
+ dma_addr_t rx_desc_dma;
+ struct sk_buff **rx_skb;
+};
+
+struct mwl8k_skb {
+ /*
+ * The DMA engine requires a modification to the payload.
+ * If the skbuff is shared/cloned, it needs to be unshared.
+ * This method is used to ensure the stack always gets back
+ * the skbuff it sent for transmission.
+ */
+ struct sk_buff *clone;
+ struct sk_buff *skb;
+};
+
+struct mwl8k_tx_queue {
+ /* hw transmits here */
+ int tx_head;
+
+ /* sw appends here */
+ int tx_tail;
+
+ struct ieee80211_tx_queue_stats tx_stats;
+ struct mwl8k_tx_desc *tx_desc_area;
+ dma_addr_t tx_desc_dma;
+ struct mwl8k_skb *tx_skb;
+};
+
+/* Pointers to the firmware data and meta information about it. */
+struct mwl8k_firmware {
+ /* Microcode */
+ struct firmware *ucode;
+
+ /* Boot helper code */
+ struct firmware *helper;
+};
+
+struct mwl8k_priv {
+ void __iomem *regs;
+ struct ieee80211_hw *hw;
+
+ struct pci_dev *pdev;
+ u8 name[16];
+ /* firmware access lock */
+ spinlock_t fw_lock;
+
+ /* firmware files and meta data */
+ struct mwl8k_firmware fw;
+ u32 part_num;
+
+ /* lock held over TX and TX reap */
+ spinlock_t tx_lock;
+ u32 int_mask;
+
+ struct ieee80211_vif *vif;
+ struct list_head vif_list;
+
+ struct ieee80211_channel *current_channel;
+
+ /* power management status cookie from firmware */
+ u32 *cookie;
+ dma_addr_t cookie_dma;
+
+ u16 num_mcaddrs;
+ u16 region_code;
+ u8 hw_rev;
+ __le32 fw_rev;
+ u32 wep_enabled;
+
+ /*
+ * Running count of TX packets in flight, to avoid
+ * iterating over the transmit rings each time.
+ */
+ int pending_tx_pkts;
+
+ struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
+ struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
+
+ /* PHY parameters */
+ struct ieee80211_supported_band band;
+ struct ieee80211_channel channels[14];
+ struct ieee80211_rate rates[12];
+
+ /* RF preamble: Short, Long or Auto */
+ u8 radio_preamble;
+ u8 radio_state;
+
+ /* WMM MODE 1 for enabled; 0 for disabled */
+ bool wmm_mode;
+
+ /* Set if PHY config is in progress */
+ bool inconfig;
+
+ /* XXX need to convert this to handle multiple interfaces */
+ bool capture_beacon;
+ u8 capture_bssid[IEEE80211_ADDR_LEN];
+ struct sk_buff *beacon_skb;
+
+ /*
+ * This FJ worker has to be global as it is scheduled from the
+ * RX handler. At this point we don't know which interface it
+ * belongs to until the list of bssids waiting to complete join
+ * is checked.
+ */
+ struct work_struct finalize_join_worker;
+
+ /* Tasklet to reclaim TX descriptors and buffers after tx */
+ struct tasklet_struct tx_reclaim_task;
+
+ /* Work thread to serialize configuration requests */
+ struct workqueue_struct *config_wq;
+ struct completion *hostcmd_wait;
+ struct completion *tx_wait;
+};
+
+/* Per interface specific private data */
+struct mwl8k_vif {
+ struct list_head node;
+
+ /* backpointer to parent config block */
+ struct mwl8k_priv *priv;
+
+ /* BSS config of AP or IBSS from mac80211*/
+ struct ieee80211_bss_conf bss_info;
+
+ /* BSSID of AP or IBSS */
+ u8 bssid[IEEE80211_ADDR_LEN];
+ u8 mac_addr[IEEE80211_ADDR_LEN];
+
+ /*
+ * Subset of supported legacy rates.
+ * Intersection of AP and STA supported rates.
+ */
+ struct ieee80211_rate legacy_rates[12];
+
+ /* number of supported legacy rates */
+ u8 legacy_nrates;
+
+ /* Number of supported MCS rates. Work in progress */
+ u8 mcs_nrates;
+
+ /* Index into station database.Returned by update_sta_db call */
+ u8 peer_id;
+
+ /* Non AMPDU sequence number assigned by driver */
+ u16 seqno;
+
+ /* Note:There is no channel info,
+ * refer to the master channel info in priv
+ */
+};
+
+#define MWL8K_VIF(_vif) (struct mwl8k_vif *)(&((_vif)->drv_priv))
+
+static const struct ieee80211_channel mwl8k_channels[] = {
+ { .center_freq = 2412, .hw_value = 1, },
+ { .center_freq = 2417, .hw_value = 2, },
+ { .center_freq = 2422, .hw_value = 3, },
+ { .center_freq = 2427, .hw_value = 4, },
+ { .center_freq = 2432, .hw_value = 5, },
+ { .center_freq = 2437, .hw_value = 6, },
+ { .center_freq = 2442, .hw_value = 7, },
+ { .center_freq = 2447, .hw_value = 8, },
+ { .center_freq = 2452, .hw_value = 9, },
+ { .center_freq = 2457, .hw_value = 10, },
+ { .center_freq = 2462, .hw_value = 11, },
+};
+
+static const struct ieee80211_rate mwl8k_rates[] = {
+ { .bitrate = 10, .hw_value = 2, },
+ { .bitrate = 20, .hw_value = 4, },
+ { .bitrate = 55, .hw_value = 11, },
+ { .bitrate = 60, .hw_value = 12, },
+ { .bitrate = 90, .hw_value = 18, },
+ { .bitrate = 110, .hw_value = 22, },
+ { .bitrate = 120, .hw_value = 24, },
+ { .bitrate = 180, .hw_value = 36, },
+ { .bitrate = 240, .hw_value = 48, },
+ { .bitrate = 360, .hw_value = 72, },
+ { .bitrate = 480, .hw_value = 96, },
+ { .bitrate = 540, .hw_value = 108, },
+};
+
+/* Radio settings */
+#define MWL8K_RADIO_FORCE 0x2
+#define MWL8K_RADIO_ENABLE 0x1
+#define MWL8K_RADIO_DISABLE 0x0
+#define MWL8K_RADIO_AUTO_PREAMBLE 0x0005
+#define MWL8K_RADIO_SHORT_PREAMBLE 0x0003
+#define MWL8K_RADIO_LONG_PREAMBLE 0x0001
+
+/* WMM */
+#define MWL8K_WMM_ENABLE 1
+#define MWL8K_WMM_DISABLE 0
+
+#define MWL8K_RADIO_DEFAULT_PREAMBLE MWL8K_RADIO_LONG_PREAMBLE
+
+/* Slot time */
+
+/* Short Slot: 9us slot time */
+#define MWL8K_SHORT_SLOTTIME 1
+
+/* Long slot: 20us slot time */
+#define MWL8K_LONG_SLOTTIME 0
+
+/* Set or get info from Firmware */
+#define MWL8K_CMD_SET 0x0001
+#define MWL8K_CMD_GET 0x0000
+
+/* Firmware command codes */
+#define MWL8K_CMD_CODE_DNLD 0x0001
+#define MWL8K_CMD_GET_HW_SPEC 0x0003
+#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010
+#define MWL8K_CMD_GET_STAT 0x0014
+#define MWL8K_CMD_RADIO_CONTROL 0x001C
+#define MWL8K_CMD_RF_TX_POWER 0x001E
+#define MWL8K_CMD_SET_PRE_SCAN 0x0107
+#define MWL8K_CMD_SET_POST_SCAN 0x0108
+#define MWL8K_CMD_SET_RF_CHANNEL 0x010A
+#define MWL8K_CMD_SET_SLOT 0x0114
+#define MWL8K_CMD_MIMO_CONFIG 0x0125
+#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
+#define MWL8K_CMD_SET_WMM_MODE 0x0123
+#define MWL8K_CMD_SET_EDCA_PARAMS 0x0115
+#define MWL8K_CMD_SET_FINALIZE_JOIN 0x0111
+#define MWL8K_CMD_UPDATE_STADB 0x1123
+#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
+#define MWL8K_CMD_SET_LINKADAPT_MODE 0x0129
+#define MWL8K_CMD_SET_AID 0x010d
+#define MWL8K_CMD_SET_RATE 0x0110
+#define MWL8K_CMD_USE_FIXED_RATE 0x0126
+#define MWL8K_CMD_RTS_THRESHOLD 0x0113
+#define MWL8K_CMD_ENCRYPTION 0x1122
+
+static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
+{
+#define MWL8K_CMDNAME(x) case MWL8K_CMD_##x: do {\
+ snprintf(buf, bufsize, "%s", #x);\
+ return buf;\
+ } while (0)
+ switch (cmd & (~0x8000)) {
+ MWL8K_CMDNAME(CODE_DNLD);
+ MWL8K_CMDNAME(GET_HW_SPEC);
+ MWL8K_CMDNAME(MAC_MULTICAST_ADR);
+ MWL8K_CMDNAME(GET_STAT);
+ MWL8K_CMDNAME(RADIO_CONTROL);
+ MWL8K_CMDNAME(RF_TX_POWER);
+ MWL8K_CMDNAME(SET_PRE_SCAN);
+ MWL8K_CMDNAME(SET_POST_SCAN);
+ MWL8K_CMDNAME(SET_RF_CHANNEL);
+ MWL8K_CMDNAME(SET_SLOT);
+ MWL8K_CMDNAME(MIMO_CONFIG);
+ MWL8K_CMDNAME(ENABLE_SNIFFER);
+ MWL8K_CMDNAME(SET_WMM_MODE);
+ MWL8K_CMDNAME(SET_EDCA_PARAMS);
+ MWL8K_CMDNAME(SET_FINALIZE_JOIN);
+ MWL8K_CMDNAME(UPDATE_STADB);
+ MWL8K_CMDNAME(SET_RATEADAPT_MODE);
+ MWL8K_CMDNAME(SET_LINKADAPT_MODE);
+ MWL8K_CMDNAME(SET_AID);
+ MWL8K_CMDNAME(SET_RATE);
+ MWL8K_CMDNAME(USE_FIXED_RATE);
+ MWL8K_CMDNAME(RTS_THRESHOLD);
+ MWL8K_CMDNAME(ENCRYPTION);
+ default:
+ snprintf(buf, bufsize, "0x%x", cmd);
+ }
+#undef MWL8K_CMDNAME
+
+ return buf;
+}
+
+/* Hardware and firmware reset */
+static void mwl8k_hw_reset(struct mwl8k_priv *priv)
+{
+ iowrite32(MWL8K_H2A_INT_RESET,
+ priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ iowrite32(MWL8K_H2A_INT_RESET,
+ priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ msleep(20);
+}
+
+/* Release fw image */
+static void mwl8k_release_fw(struct firmware **fw)
+{
+ if (*fw == NULL)
+ return;
+ release_firmware(*fw);
+ *fw = NULL;
+}
+
+static void mwl8k_release_firmware(struct mwl8k_priv *priv)
+{
+ mwl8k_release_fw(&priv->fw.ucode);
+ mwl8k_release_fw(&priv->fw.helper);
+}
+
+/* Request fw image */
+static int mwl8k_request_fw(struct mwl8k_priv *priv,
+ const char *fname, struct firmware **fw)
+{
+ /* release current image */
+ if (*fw != NULL)
+ mwl8k_release_fw(fw);
+
+ return request_firmware((const struct firmware **)fw,
+ fname, &priv->pdev->dev);
+}
+
+static int mwl8k_request_firmware(struct mwl8k_priv *priv, u32 part_num)
+{
+ u8 filename[64];
+ int rc;
+
+ priv->part_num = part_num;
+
+ snprintf(filename, sizeof(filename),
+ "mwl8k/helper_%u.fw", priv->part_num);
+
+ rc = mwl8k_request_fw(priv, filename, &priv->fw.helper);
+ if (rc) {
+ printk(KERN_ERR
+ "%s Error requesting helper firmware file %s\n",
+ pci_name(priv->pdev), filename);
+ return rc;
+ }
+
+ snprintf(filename, sizeof(filename),
+ "mwl8k/fmimage_%u.fw", priv->part_num);
+
+ rc = mwl8k_request_fw(priv, filename, &priv->fw.ucode);
+ if (rc) {
+ printk(KERN_ERR "%s Error requesting firmware file %s\n",
+ pci_name(priv->pdev), filename);
+ mwl8k_release_fw(&priv->fw.helper);
+ return rc;
+ }
+
+ return 0;
+}
+
+struct mwl8k_cmd_pkt {
+ __le16 code;
+ __le16 length;
+ __le16 seq_num;
+ __le16 result;
+ char payload[0];
+} __attribute__((packed));
+
+/*
+ * Firmware loading.
+ */
+static int
+mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
+{
+ void __iomem *regs = priv->regs;
+ dma_addr_t dma_addr;
+ int rc;
+ int loops;
+
+ dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(priv->pdev, dma_addr))
+ return -ENOMEM;
+
+ iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
+ iowrite32(0, regs + MWL8K_HIU_INT_CODE);
+ iowrite32(MWL8K_H2A_INT_DOORBELL,
+ regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ iowrite32(MWL8K_H2A_INT_DUMMY,
+ regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+
+ rc = -ETIMEDOUT;
+ loops = 1000;
+ do {
+ u32 int_code;
+
+ int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
+ if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
+ iowrite32(0, regs + MWL8K_HIU_INT_CODE);
+ rc = 0;
+ break;
+ }
+
+ udelay(1);
+ } while (--loops);
+
+ pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);
+
+ /*
+ * Clear 'command done' interrupt bit.
+ */
+ loops = 1000;
+ do {
+ u32 status;
+
+ status = ioread32(priv->regs +
+ MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ if (status & MWL8K_A2H_INT_OPC_DONE) {
+ iowrite32(~MWL8K_A2H_INT_OPC_DONE,
+ priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ break;
+ }
+
+ udelay(1);
+ } while (--loops);
+
+ return rc;
+}
+
+static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
+ const u8 *data, size_t length)
+{
+ struct mwl8k_cmd_pkt *cmd;
+ int done;
+ int rc = 0;
+
+ cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
+ cmd->seq_num = 0;
+ cmd->result = 0;
+
+ done = 0;
+ while (length) {
+ int block_size = length > 256 ? 256 : length;
+
+ memcpy(cmd->payload, data + done, block_size);
+ cmd->length = cpu_to_le16(block_size);
+
+ rc = mwl8k_send_fw_load_cmd(priv, cmd,
+ sizeof(*cmd) + block_size);
+ if (rc)
+ break;
+
+ done += block_size;
+ length -= block_size;
+ }
+
+ if (!rc) {
+ cmd->length = 0;
+ rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd));
+ }
+
+ kfree(cmd);
+
+ return rc;
+}
+
+static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
+ const u8 *data, size_t length)
+{
+ unsigned char *buffer;
+ int may_continue, rc = 0;
+ u32 done, prev_block_size;
+
+ buffer = kmalloc(1024, GFP_KERNEL);
+ if (buffer == NULL)
+ return -ENOMEM;
+
+ done = 0;
+ prev_block_size = 0;
+ may_continue = 1000;
+ while (may_continue > 0) {
+ u32 block_size;
+
+ block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH);
+ if (block_size & 1) {
+ block_size &= ~1;
+ may_continue--;
+ } else {
+ done += prev_block_size;
+ length -= prev_block_size;
+ }
+
+ if (block_size > 1024 || block_size > length) {
+ rc = -EOVERFLOW;
+ break;
+ }
+
+ if (length == 0) {
+ rc = 0;
+ break;
+ }
+
+ if (block_size == 0) {
+ rc = -EPROTO;
+ may_continue--;
+ udelay(1);
+ continue;
+ }
+
+ prev_block_size = block_size;
+ memcpy(buffer, data + done, block_size);
+
+ rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
+ if (rc)
+ break;
+ }
+
+ if (!rc && length != 0)
+ rc = -EREMOTEIO;
+
+ kfree(buffer);
+
+ return rc;
+}
+
+static int mwl8k_load_firmware(struct mwl8k_priv *priv)
+{
+ int loops, rc;
+
+ const u8 *ucode = priv->fw.ucode->data;
+ size_t ucode_len = priv->fw.ucode->size;
+ const u8 *helper = priv->fw.helper->data;
+ size_t helper_len = priv->fw.helper->size;
+
+ if (!memcmp(ucode, "\x01\x00\x00\x00", 4)) {
+ rc = mwl8k_load_fw_image(priv, helper, helper_len);
+ if (rc) {
+ printk(KERN_ERR "%s: unable to load firmware "
+ "helper image\n", pci_name(priv->pdev));
+ return rc;
+ }
+ msleep(1);
+
+ rc = mwl8k_feed_fw_image(priv, ucode, ucode_len);
+ } else {
+ rc = mwl8k_load_fw_image(priv, ucode, ucode_len);
+ }
+
+ if (rc) {
+ printk(KERN_ERR "%s: unable to load firmware data\n",
+ pci_name(priv->pdev));
+ return rc;
+ }
+
+ iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
+ msleep(1);
+
+ loops = 200000;
+ do {
+ if (ioread32(priv->regs + MWL8K_HIU_INT_CODE)
+ == MWL8K_FWSTA_READY)
+ break;
+ udelay(1);
+ } while (--loops);
+
+ return loops ? 0 : -ETIMEDOUT;
+}
+
+
+/*
+ * Defines shared between transmission and reception.
+ */
+/* HT control fields for firmware */
+struct ewc_ht_info {
+ __le16 control1;
+ __le16 control2;
+ __le16 control3;
+} __attribute__((packed));
+
+/* Firmware Station database operations */
+#define MWL8K_STA_DB_ADD_ENTRY 0
+#define MWL8K_STA_DB_MODIFY_ENTRY 1
+#define MWL8K_STA_DB_DEL_ENTRY 2
+#define MWL8K_STA_DB_FLUSH 3
+
+/* Peer Entry flags - used to define the type of the peer node */
+#define MWL8K_PEER_TYPE_ACCESSPOINT 2
+#define MWL8K_PEER_TYPE_ADHOC_STATION 4
+
+#define MWL8K_IEEE_LEGACY_DATA_RATES 12
+#define MWL8K_MCS_BITMAP_SIZE 16
+#define pad_size 16
+
+struct peer_capability_info {
+ /* Peer type - AP vs. STA. */
+ __u8 peer_type;
+
+ /* Basic 802.11 capabilities from assoc resp. */
+ __le16 basic_caps;
+
+ /* Set if peer supports 802.11n high throughput (HT). */
+ __u8 ht_support;
+
+ /* Valid if HT is supported. */
+ __le16 ht_caps;
+ __u8 extended_ht_caps;
+ struct ewc_ht_info ewc_info;
+
+ /* Legacy rate table. Intersection of our rates and peer rates. */
+ __u8 legacy_rates[MWL8K_IEEE_LEGACY_DATA_RATES];
+
+ /* HT rate table. Intersection of our rates and peer rates. */
+ __u8 ht_rates[MWL8K_MCS_BITMAP_SIZE];
+ __u8 pad[pad_size];
+
+ /* If set, interoperability mode, no proprietary extensions. */
+ __u8 interop;
+ __u8 pad2;
+ __u8 station_id;
+ __le16 amsdu_enabled;
+} __attribute__((packed));
+
+/* Inline functions to manipulate QoS field in data descriptor. */
+static inline u16 mwl8k_qos_setbit_tid(u16 qos, u8 tid)
+{
+ u16 val_mask = 0x000f;
+ u16 qos_mask = ~val_mask;
+
+ /* TID bits 0-3 */
+ return (qos & qos_mask) | (tid & val_mask);
+}
+
+static inline u16 mwl8k_qos_setbit_eosp(u16 qos)
+{
+ u16 val_mask = 1 << 4;
+
+ /* End of Service Period Bit 4 */
+ return qos | val_mask;
+}
+
+static inline u16 mwl8k_qos_setbit_ack(u16 qos, u8 ack_policy)
+{
+ u16 val_mask = 0x3;
+ u8 shift = 5;
+ u16 qos_mask = ~(val_mask << shift);
+
+ /* Ack Policy Bit 5-6 */
+ return (qos & qos_mask) | ((ack_policy & val_mask) << shift);
+}
+
+static inline u16 mwl8k_qos_setbit_amsdu(u16 qos)
+{
+ u16 val_mask = 1 << 7;
+
+ /* AMSDU present Bit 7 */
+ return qos | val_mask;
+}
+
+static inline u16 mwl8k_qos_setbit_qlen(u16 qos, u8 len)
+{
+ u16 val_mask = 0xff;
+ u8 shift = 8;
+ u16 qos_mask = ~(val_mask << shift);
+
+ /* Queue Length Bits 8-15 */
+ return (qos & qos_mask) | ((len & val_mask) << shift);
+}
+
+/* DMA header used by firmware and hardware. */
+struct mwl8k_dma_data {
+ __le16 fwlen;
+ struct ieee80211_hdr wh;
+} __attribute__((packed));
+
+/* Routines to add/remove DMA header from skb. */
+static inline int mwl8k_remove_dma_header(struct sk_buff *skb)
+{
+ struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)(skb->data);
+ void *dst, *src = &tr->wh;
+ __le16 fc = tr->wh.frame_control;
+ int hdrlen = ieee80211_hdrlen(fc);
+ u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
+
+ dst = (void *)tr + space;
+ if (dst != src) {
+ memmove(dst, src, hdrlen);
+ skb_pull(skb, space);
+ }
+
+ return 0;
+}
+
+static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
+{
+ struct ieee80211_hdr *wh;
+ u32 hdrlen, pktlen;
+ struct mwl8k_dma_data *tr;
+
+ wh = (struct ieee80211_hdr *)skb->data;
+ hdrlen = ieee80211_hdrlen(wh->frame_control);
+ pktlen = skb->len;
+
+ /*
+ * Copy up/down the 802.11 header; the firmware requires
+ * we present a 2-byte payload length followed by a
+ * 4-address header (w/o QoS), followed (optionally) by
+ * any WEP/ExtIV header (but only filled in for CCMP).
+ */
+ if (hdrlen != sizeof(struct mwl8k_dma_data))
+ skb_push(skb, sizeof(struct mwl8k_dma_data) - hdrlen);
+
+ tr = (struct mwl8k_dma_data *)skb->data;
+ if (wh != &tr->wh)
+ memmove(&tr->wh, wh, hdrlen);
+
+ /* Clear addr4 */
+ memset(tr->wh.addr4, 0, IEEE80211_ADDR_LEN);
+
+ /*
+ * Firmware length is the length of the fully formed "802.11
+ * payload". That is, everything except for the 802.11 header.
+ * This includes all crypto material including the MIC.
+ */
+ tr->fwlen = cpu_to_le16(pktlen - hdrlen);
+
+ return skb;
+}
+
+
+/*
+ * Packet reception.
+ */
+#define MWL8K_RX_CTRL_KEY_INDEX_MASK 0x30
+#define MWL8K_RX_CTRL_OWNED_BY_HOST 0x02
+#define MWL8K_RX_CTRL_AMPDU 0x01
+
+struct mwl8k_rx_desc {
+ __le16 pkt_len;
+ __u8 link_quality;
+ __u8 noise_level;
+ __le32 pkt_phys_addr;
+ __le32 next_rx_desc_phys_addr;
+ __le16 qos_control;
+ __le16 rate_info;
+ __le32 pad0[4];
+ __u8 rssi;
+ __u8 channel;
+ __le16 pad1;
+ __u8 rx_ctrl;
+ __u8 rx_status;
+ __u8 pad2[2];
+} __attribute__((packed));
+
+#define MWL8K_RX_DESCS 256
+#define MWL8K_RX_MAXSZ 3800
+
+static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_rx_queue *rxq = priv->rxq + index;
+ int size;
+ int i;
+
+ rxq->rx_desc_count = 0;
+ rxq->rx_head = 0;
+ rxq->rx_tail = 0;
+
+ size = MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc);
+
+ rxq->rx_desc_area =
+ pci_alloc_consistent(priv->pdev, size, &rxq->rx_desc_dma);
+ if (rxq->rx_desc_area == NULL) {
+ printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
+ priv->name);
+ return -ENOMEM;
+ }
+ memset(rxq->rx_desc_area, 0, size);
+
+ rxq->rx_skb = kmalloc(MWL8K_RX_DESCS *
+ sizeof(*rxq->rx_skb), GFP_KERNEL);
+ if (rxq->rx_skb == NULL) {
+ printk(KERN_ERR "%s: failed to alloc RX skbuff list\n",
+ priv->name);
+ pci_free_consistent(priv->pdev, size,
+ rxq->rx_desc_area, rxq->rx_desc_dma);
+ return -ENOMEM;
+ }
+ memset(rxq->rx_skb, 0, MWL8K_RX_DESCS * sizeof(*rxq->rx_skb));
+
+ for (i = 0; i < MWL8K_RX_DESCS; i++) {
+ struct mwl8k_rx_desc *rx_desc;
+ int nexti;
+
+ rx_desc = rxq->rx_desc_area + i;
+ nexti = (i + 1) % MWL8K_RX_DESCS;
+
+ rx_desc->next_rx_desc_phys_addr =
+ cpu_to_le32(rxq->rx_desc_dma
+ + nexti * sizeof(*rx_desc));
+ rx_desc->rx_ctrl =
+ cpu_to_le32(MWL8K_RX_CTRL_OWNED_BY_HOST);
+ }
+
+ return 0;
+}
+
+static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_rx_queue *rxq = priv->rxq + index;
+ int refilled;
+
+ refilled = 0;
+ while (rxq->rx_desc_count < MWL8K_RX_DESCS && limit--) {
+ struct sk_buff *skb;
+ int rx;
+
+ skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
+ if (skb == NULL)
+ break;
+
+ rxq->rx_desc_count++;
+
+ rx = rxq->rx_tail;
+ rxq->rx_tail = (rx + 1) % MWL8K_RX_DESCS;
+
+ rxq->rx_desc_area[rx].pkt_phys_addr =
+ cpu_to_le32(pci_map_single(priv->pdev, skb->data,
+ MWL8K_RX_MAXSZ, DMA_FROM_DEVICE));
+
+ rxq->rx_desc_area[rx].pkt_len = cpu_to_le16(MWL8K_RX_MAXSZ);
+ rxq->rx_skb[rx] = skb;
+ wmb();
+ rxq->rx_desc_area[rx].rx_ctrl = 0;
+
+ refilled++;
+ }
+
+ return refilled;
+}
+
+/* Must be called only when the card's reception is completely halted */
+static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_rx_queue *rxq = priv->rxq + index;
+ int i;
+
+ for (i = 0; i < MWL8K_RX_DESCS; i++) {
+ if (rxq->rx_skb[i] != NULL) {
+ unsigned long addr;
+
+ addr = le32_to_cpu(rxq->rx_desc_area[i].pkt_phys_addr);
+ pci_unmap_single(priv->pdev, addr, MWL8K_RX_MAXSZ,
+ PCI_DMA_FROMDEVICE);
+ kfree_skb(rxq->rx_skb[i]);
+ rxq->rx_skb[i] = NULL;
+ }
+ }
+
+ kfree(rxq->rx_skb);
+ rxq->rx_skb = NULL;
+
+ pci_free_consistent(priv->pdev,
+ MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc),
+ rxq->rx_desc_area, rxq->rx_desc_dma);
+ rxq->rx_desc_area = NULL;
+}
+
+
+/*
+ * Scan a list of BSSIDs to process for finalize join.
+ * Allows for extension to process multiple BSSIDs.
+ */
+static inline int
+mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
+{
+ return priv->capture_beacon &&
+ ieee80211_is_beacon(wh->frame_control) &&
+ !compare_ether_addr(wh->addr3, priv->capture_bssid);
+}
+
+static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
+ struct sk_buff *skb)
+{
+ priv->capture_beacon = false;
+ memset(priv->capture_bssid, 0, IEEE80211_ADDR_LEN);
+
+ /*
+ * Use GFP_ATOMIC as rxq_process is called from
+ * the primary interrupt handler, memory allocation call
+ * must not sleep.
+ */
+ priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
+ if (priv->beacon_skb != NULL)
+ queue_work(priv->config_wq,
+ &priv->finalize_join_worker);
+}
+
+static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_rx_queue *rxq = priv->rxq + index;
+ int processed;
+
+ processed = 0;
+ while (rxq->rx_desc_count && limit--) {
+ struct mwl8k_rx_desc *rx_desc;
+ struct sk_buff *skb;
+ struct ieee80211_rx_status status;
+ unsigned long addr;
+ struct ieee80211_hdr *wh;
+
+ rx_desc = rxq->rx_desc_area + rxq->rx_head;
+ if (!(rx_desc->rx_ctrl & MWL8K_RX_CTRL_OWNED_BY_HOST))
+ break;
+ rmb();
+
+ skb = rxq->rx_skb[rxq->rx_head];
+ rxq->rx_skb[rxq->rx_head] = NULL;
+
+ rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS;
+ rxq->rx_desc_count--;
+
+ addr = le32_to_cpu(rx_desc->pkt_phys_addr);
+ pci_unmap_single(priv->pdev, addr,
+ MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
+
+ skb_put(skb, le16_to_cpu(rx_desc->pkt_len));
+ if (mwl8k_remove_dma_header(skb)) {
+ dev_kfree_skb(skb);
+ continue;
+ }
+
+ wh = (struct ieee80211_hdr *)skb->data;
+
+ /*
+ * Check for pending join operation. save a copy of
+ * the beacon and schedule a tasklet to send finalize
+ * join command to the firmware.
+ */
+ if (mwl8k_capture_bssid(priv, wh))
+ mwl8k_save_beacon(priv, skb);
+
+ memset(&status, 0, sizeof(status));
+ status.mactime = 0;
+ status.signal = -rx_desc->rssi;
+ status.noise = -rx_desc->noise_level;
+ status.qual = rx_desc->link_quality;
+ status.antenna = 1;
+ status.rate_idx = 1;
+ status.flag = 0;
+ status.band = IEEE80211_BAND_2GHZ;
+ status.freq = ieee80211_channel_to_frequency(rx_desc->channel);
+ ieee80211_rx_irqsafe(hw, skb, &status);
+
+ processed++;
+ }
+
+ return processed;
+}
+
+
+/*
+ * Packet transmission.
+ */
+
+/* Transmit queue assignment. */
+enum {
+ MWL8K_WME_AC_BK = 0, /* background access */
+ MWL8K_WME_AC_BE = 1, /* best effort access */
+ MWL8K_WME_AC_VI = 2, /* video access */
+ MWL8K_WME_AC_VO = 3, /* voice access */
+};
+
+/* Transmit packet ACK policy */
+#define MWL8K_TXD_ACK_POLICY_NORMAL 0
+#define MWL8K_TXD_ACK_POLICY_NONE 1
+#define MWL8K_TXD_ACK_POLICY_NO_EXPLICIT 2
+#define MWL8K_TXD_ACK_POLICY_BLOCKACK 3
+
+#define GET_TXQ(_ac) (\
+ ((_ac) == WME_AC_VO) ? MWL8K_WME_AC_VO : \
+ ((_ac) == WME_AC_VI) ? MWL8K_WME_AC_VI : \
+ ((_ac) == WME_AC_BK) ? MWL8K_WME_AC_BK : \
+ MWL8K_WME_AC_BE)
+
+#define MWL8K_TXD_STATUS_IDLE 0x00000000
+#define MWL8K_TXD_STATUS_USED 0x00000001
+#define MWL8K_TXD_STATUS_OK 0x00000001
+#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002
+#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004
+#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008
+#define MWL8K_TXD_STATUS_BROADCAST_TX 0x00000010
+#define MWL8K_TXD_STATUS_FAILED_LINK_ERROR 0x00000020
+#define MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT 0x00000040
+#define MWL8K_TXD_STATUS_FAILED_AGING 0x00000080
+#define MWL8K_TXD_STATUS_HOST_CMD 0x40000000
+#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000
+#define MWL8K_TXD_SOFTSTALE 0x80
+#define MWL8K_TXD_SOFTSTALE_MGMT_RETRY 0x01
+
+struct mwl8k_tx_desc {
+ __le32 status;
+ __u8 data_rate;
+ __u8 tx_priority;
+ __le16 qos_control;
+ __le32 pkt_phys_addr;
+ __le16 pkt_len;
+ __u8 dest_MAC_addr[IEEE80211_ADDR_LEN];
+ __le32 next_tx_desc_phys_addr;
+ __le32 reserved;
+ __le16 rate_info;
+ __u8 peer_id;
+ __u8 tx_frag_cnt;
+} __attribute__((packed));
+
+#define MWL8K_TX_DESCS 128
+
+static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_tx_queue *txq = priv->txq + index;
+ int size;
+ int i;
+
+ memset(&txq->tx_stats, 0,
+ sizeof(struct ieee80211_tx_queue_stats));
+ txq->tx_stats.limit = MWL8K_TX_DESCS;
+ txq->tx_head = 0;
+ txq->tx_tail = 0;
+
+ size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc);
+
+ txq->tx_desc_area =
+ pci_alloc_consistent(priv->pdev, size, &txq->tx_desc_dma);
+ if (txq->tx_desc_area == NULL) {
+ printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
+ priv->name);
+ return -ENOMEM;
+ }
+ memset(txq->tx_desc_area, 0, size);
+
+ txq->tx_skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->tx_skb),
+ GFP_KERNEL);
+ if (txq->tx_skb == NULL) {
+ printk(KERN_ERR "%s: failed to alloc TX skbuff list\n",
+ priv->name);
+ pci_free_consistent(priv->pdev, size,
+ txq->tx_desc_area, txq->tx_desc_dma);
+ return -ENOMEM;
+ }
+ memset(txq->tx_skb, 0, MWL8K_TX_DESCS * sizeof(*txq->tx_skb));
+
+ for (i = 0; i < MWL8K_TX_DESCS; i++) {
+ struct mwl8k_tx_desc *tx_desc;
+ int nexti;
+
+ tx_desc = txq->tx_desc_area + i;
+ nexti = (i + 1) % MWL8K_TX_DESCS;
+
+ tx_desc->status = 0;
+ tx_desc->next_tx_desc_phys_addr =
+ cpu_to_le32(txq->tx_desc_dma +
+ nexti * sizeof(*tx_desc));
+ }
+
+ return 0;
+}
+
+static inline void mwl8k_tx_start(struct mwl8k_priv *priv)
+{
+ iowrite32(MWL8K_H2A_INT_PPA_READY,
+ priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ iowrite32(MWL8K_H2A_INT_DUMMY,
+ priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ ioread32(priv->regs + MWL8K_HIU_INT_CODE);
+}
+
+static inline int mwl8k_txq_busy(struct mwl8k_priv *priv)
+{
+ return priv->pending_tx_pkts;
+}
+
+struct mwl8k_txq_info {
+ u32 fw_owned;
+ u32 drv_owned;
+ u32 unused;
+ u32 len;
+ u32 head;
+ u32 tail;
+};
+
+static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
+ struct mwl8k_txq_info txinfo[],
+ u32 num_queues)
+{
+ int count, desc, status;
+ struct mwl8k_tx_queue *txq;
+ struct mwl8k_tx_desc *tx_desc;
+ int ndescs = 0;
+
+ memset(txinfo, 0, num_queues * sizeof(struct mwl8k_txq_info));
+ spin_lock_bh(&priv->tx_lock);
+ for (count = 0; count < num_queues; count++) {
+ txq = priv->txq + count;
+ txinfo[count].len = txq->tx_stats.len;
+ txinfo[count].head = txq->tx_head;
+ txinfo[count].tail = txq->tx_tail;
+ for (desc = 0; desc < MWL8K_TX_DESCS; desc++) {
+ tx_desc = txq->tx_desc_area + desc;
+ status = le32_to_cpu(tx_desc->status);
+
+ if (status & MWL8K_TXD_STATUS_FW_OWNED)
+ txinfo[count].fw_owned++;
+ else
+ txinfo[count].drv_owned++;
+
+ if (tx_desc->pkt_len == 0)
+ txinfo[count].unused++;
+ }
+ }
+ spin_unlock_bh(&priv->tx_lock);
+
+ return ndescs;
+}
+
+static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
+{
+ u32 count = 0;
+ unsigned long timeout = 0;
+ struct mwl8k_priv *priv = hw->priv;
+ DECLARE_COMPLETION_ONSTACK(cmd_wait);
+
+ might_sleep();
+
+ if (priv->tx_wait != NULL)
+ printk(KERN_ERR "WARNING Previous TXWaitEmpty instance\n");
+
+ spin_lock_bh(&priv->tx_lock);
+ count = mwl8k_txq_busy(priv);
+ if (count) {
+ priv->tx_wait = &cmd_wait;
+ if (priv->radio_state)
+ mwl8k_tx_start(priv);
+ }
+ spin_unlock_bh(&priv->tx_lock);
+
+ if (count) {
+ struct mwl8k_txq_info txinfo[4];
+ int index;
+ int newcount;
+
+ timeout = wait_for_completion_timeout(&cmd_wait,
+ msecs_to_jiffies(delay_ms));
+ if (timeout)
+ return 0;
+
+ spin_lock_bh(&priv->tx_lock);
+ priv->tx_wait = NULL;
+ newcount = mwl8k_txq_busy(priv);
+ spin_unlock_bh(&priv->tx_lock);
+
+ printk(KERN_ERR "%s(%u) TIMEDOUT:%ums Pend:%u-->%u\n",
+ __func__, __LINE__, delay_ms, count, newcount);
+
+ mwl8k_scan_tx_ring(priv, txinfo, 4);
+ for (index = 0 ; index < 4; index++)
+ printk(KERN_ERR
+ "TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n",
+ index,
+ txinfo[index].len,
+ txinfo[index].head,
+ txinfo[index].tail,
+ txinfo[index].fw_owned,
+ txinfo[index].drv_owned,
+ txinfo[index].unused);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+#define MWL8K_TXD_OK (MWL8K_TXD_STATUS_OK | \
+ MWL8K_TXD_STATUS_OK_RETRY | \
+ MWL8K_TXD_STATUS_OK_MORE_RETRY)
+#define MWL8K_TXD_SUCCESS(stat) ((stat) & MWL8K_TXD_OK)
+#define MWL8K_TXD_FAIL_RETRY(stat) \
+ ((stat) & (MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT))
+
+static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_tx_queue *txq = priv->txq + index;
+ int wake = 0;
+
+ while (txq->tx_stats.len > 0) {
+ int tx;
+ int rc;
+ struct mwl8k_tx_desc *tx_desc;
+ unsigned long addr;
+ size_t size;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ u32 status;
+
+ rc = 0;
+ tx = txq->tx_head;
+ tx_desc = txq->tx_desc_area + tx;
+
+ status = le32_to_cpu(tx_desc->status);
+
+ if (status & MWL8K_TXD_STATUS_FW_OWNED) {
+ if (!force)
+ break;
+ tx_desc->status &=
+ ~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED);
+ }
+
+ txq->tx_head = (tx + 1) % MWL8K_TX_DESCS;
+ BUG_ON(txq->tx_stats.len == 0);
+ txq->tx_stats.len--;
+ priv->pending_tx_pkts--;
+
+ addr = le32_to_cpu(tx_desc->pkt_phys_addr);
+ size = (u32)(le16_to_cpu(tx_desc->pkt_len));
+ skb = txq->tx_skb[tx].skb;
+ txq->tx_skb[tx].skb = NULL;
+
+ BUG_ON(skb == NULL);
+ pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
+
+ rc = mwl8k_remove_dma_header(skb);
+
+ /* Mark descriptor as unused */
+ tx_desc->pkt_phys_addr = 0;
+ tx_desc->pkt_len = 0;
+
+ if (txq->tx_skb[tx].clone) {
+ /* Replace with original skb
+ * before returning to stack
+ * as buffer has been cloned
+ */
+ dev_kfree_skb(skb);
+ skb = txq->tx_skb[tx].clone;
+ txq->tx_skb[tx].clone = NULL;
+ }
+
+ if (rc) {
+ /* Something has gone wrong here.
+ * Failed to remove DMA header.
+ * Print error message and drop packet.
+ */
+ printk(KERN_ERR "%s: Error removing DMA header from "
+ "tx skb 0x%p.\n", priv->name, skb);
+
+ dev_kfree_skb(skb);
+ continue;
+ }
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ /* Convert firmware status stuff into tx_status */
+ if (MWL8K_TXD_SUCCESS(status)) {
+ /* Transmit OK */
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ }
+
+ ieee80211_tx_status_irqsafe(hw, skb);
+
+ wake = !priv->inconfig && priv->radio_state;
+ }
+
+ if (wake)
+ ieee80211_wake_queue(hw, index);
+}
+
+/* must be called only when the card's transmit is completely halted */
+static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_tx_queue *txq = priv->txq + index;
+
+ mwl8k_txq_reclaim(hw, index, 1);
+
+ kfree(txq->tx_skb);
+ txq->tx_skb = NULL;
+
+ pci_free_consistent(priv->pdev,
+ MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc),
+ txq->tx_desc_area, txq->tx_desc_dma);
+ txq->tx_desc_area = NULL;
+}
+
+static int
+mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_hdr *wh;
+ struct mwl8k_tx_queue *txq;
+ struct mwl8k_tx_desc *tx;
+ struct mwl8k_dma_data *tr;
+ struct mwl8k_vif *mwl8k_vif;
+ struct sk_buff *org_skb = skb;
+ dma_addr_t dma;
+ u16 qos = 0;
+ bool qosframe = false, ampduframe = false;
+ bool mcframe = false, eapolframe = false;
+ bool amsduframe = false;
+ __le16 fc;
+
+ txq = priv->txq + index;
+ tx = txq->tx_desc_area + txq->tx_tail;
+
+ BUG_ON(txq->tx_skb[txq->tx_tail].skb != NULL);
+
+ /*
+ * Append HW DMA header to start of packet. Drop packet if
+ * there is not enough space or a failure to unshare/unclone
+ * the skb.
+ */
+ skb = mwl8k_add_dma_header(skb);
+
+ if (skb == NULL) {
+ printk(KERN_DEBUG "%s: failed to prepend HW DMA "
+ "header, dropping TX frame.\n", priv->name);
+ dev_kfree_skb(org_skb);
+ return NETDEV_TX_OK;
+ }
+
+ tx_info = IEEE80211_SKB_CB(skb);
+ mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
+ tr = (struct mwl8k_dma_data *)skb->data;
+ wh = &tr->wh;
+ fc = wh->frame_control;
+ qosframe = ieee80211_is_data_qos(fc);
+ mcframe = is_multicast_ether_addr(wh->addr1);
+ ampduframe = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
+
+ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ u16 seqno = mwl8k_vif->seqno;
+ wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ wh->seq_ctrl |= cpu_to_le16(seqno << 4);
+ mwl8k_vif->seqno = seqno++ % 4096;
+ }
+
+ if (qosframe)
+ qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
+
+ dma = pci_map_single(priv->pdev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
+
+ if (pci_dma_mapping_error(priv->pdev, dma)) {
+ printk(KERN_DEBUG "%s: failed to dma map skb, "
+ "dropping TX frame.\n", priv->name);
+
+ if (org_skb != NULL)
+ dev_kfree_skb(org_skb);
+ if (skb != NULL)
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ /* Set desc header, cpu bit order. */
+ tx->status = 0;
+ tx->data_rate = 0;
+ tx->tx_priority = index;
+ tx->qos_control = 0;
+ tx->rate_info = 0;
+ tx->peer_id = mwl8k_vif->peer_id;
+
+ amsduframe = !!(qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
+
+ /* Setup firmware control bit fields for each frame type. */
+ if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
+ tx->data_rate = 0;
+ qos = mwl8k_qos_setbit_eosp(qos);
+ /* Set Queue size to unspecified */
+ qos = mwl8k_qos_setbit_qlen(qos, 0xff);
+ } else if (ieee80211_is_data(fc)) {
+ tx->data_rate = 1;
+ if (mcframe)
+ tx->status |= MWL8K_TXD_STATUS_MULTICAST_TX;
+
+ /*
+ * Tell firmware to not send EAPOL pkts in an
+ * aggregate. Verify against mac80211 tx path. If
+ * stack turns off AMPDU for an EAPOL frame this
+ * check will be removed.
+ */
+ if (eapolframe) {
+ qos = mwl8k_qos_setbit_ack(qos,
+ MWL8K_TXD_ACK_POLICY_NORMAL);
+ } else {
+ /* Send pkt in an aggregate if AMPDU frame. */
+ if (ampduframe)
+ qos = mwl8k_qos_setbit_ack(qos,
+ MWL8K_TXD_ACK_POLICY_BLOCKACK);
+ else
+ qos = mwl8k_qos_setbit_ack(qos,
+ MWL8K_TXD_ACK_POLICY_NORMAL);
+
+ if (amsduframe)
+ qos = mwl8k_qos_setbit_amsdu(qos);
+ }
+ }
+
+ /* Convert to little endian */
+ tx->qos_control = cpu_to_le16(qos);
+ tx->status = cpu_to_le32(tx->status);
+ tx->pkt_phys_addr = cpu_to_le32(dma);
+ tx->pkt_len = cpu_to_le16(skb->len);
+
+ txq->tx_skb[txq->tx_tail].skb = skb;
+ txq->tx_skb[txq->tx_tail].clone =
+ skb == org_skb ? NULL : org_skb;
+
+ spin_lock_bh(&priv->tx_lock);
+
+ tx->status = cpu_to_le32(MWL8K_TXD_STATUS_OK |
+ MWL8K_TXD_STATUS_FW_OWNED);
+ wmb();
+ txq->tx_stats.len++;
+ priv->pending_tx_pkts++;
+ txq->tx_stats.count++;
+ txq->tx_tail++;
+
+ if (txq->tx_tail == MWL8K_TX_DESCS)
+ txq->tx_tail = 0;
+ if (txq->tx_head == txq->tx_tail)
+ ieee80211_stop_queue(hw, index);
+
+ if (priv->inconfig) {
+ /*
+ * Silently queue packet when we are in the middle of
+ * a config cycle. Notify firmware only if we are
+ * waiting for TXQs to empty. If a packet is sent
+ * before .config() is complete, perhaps it is better
+ * to drop the packet, as the channel is being changed
+ * and the packet will end up on the wrong channel.
+ */
+ printk(KERN_ERR "%s(): WARNING TX activity while "
+ "in config\n", __func__);
+
+ if (priv->tx_wait != NULL)
+ mwl8k_tx_start(priv);
+ } else
+ mwl8k_tx_start(priv);
+
+ spin_unlock_bh(&priv->tx_lock);
+
+ return NETDEV_TX_OK;
+}
+
+
+/*
+ * Command processing.
+ */
+
+/* Timeout firmware commands after 2000ms */
+#define MWL8K_CMD_TIMEOUT_MS 2000
+
+static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
+{
+ DECLARE_COMPLETION_ONSTACK(cmd_wait);
+ struct mwl8k_priv *priv = hw->priv;
+ void __iomem *regs = priv->regs;
+ dma_addr_t dma_addr;
+ unsigned int dma_size;
+ int rc;
+ u16 __iomem *result;
+ unsigned long timeout = 0;
+ u8 buf[32];
+
+ cmd->result = 0xFFFF;
+ dma_size = le16_to_cpu(cmd->length);
+ dma_addr = pci_map_single(priv->pdev, cmd, dma_size,
+ PCI_DMA_BIDIRECTIONAL);
+ if (pci_dma_mapping_error(priv->pdev, dma_addr))
+ return -ENOMEM;
+
+ if (priv->hostcmd_wait != NULL)
+ printk(KERN_ERR "WARNING host command in progress\n");
+
+ spin_lock_irq(&priv->fw_lock);
+ priv->hostcmd_wait = &cmd_wait;
+ iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
+ iowrite32(MWL8K_H2A_INT_DOORBELL,
+ regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ iowrite32(MWL8K_H2A_INT_DUMMY,
+ regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ spin_unlock_irq(&priv->fw_lock);
+
+ timeout = wait_for_completion_timeout(&cmd_wait,
+ msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
+
+ result = &cmd->result;
+ if (!timeout) {
+ spin_lock_irq(&priv->fw_lock);
+ priv->hostcmd_wait = NULL;
+ spin_unlock_irq(&priv->fw_lock);
+ printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
+ priv->name,
+ mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+ MWL8K_CMD_TIMEOUT_MS);
+ rc = -ETIMEDOUT;
+ } else {
+ rc = *result ? -EINVAL : 0;
+ if (rc)
+ printk(KERN_ERR "%s: Command %s error 0x%x\n",
+ priv->name,
+ mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+ *result);
+ }
+
+ pci_unmap_single(priv->pdev, dma_addr, dma_size,
+ PCI_DMA_BIDIRECTIONAL);
+ return rc;
+}
+
+/*
+ * GET_HW_SPEC.
+ */
+struct mwl8k_cmd_get_hw_spec {
+ struct mwl8k_cmd_pkt header;
+ __u8 hw_rev;
+ __u8 host_interface;
+ __le16 num_mcaddrs;
+ __u8 perm_addr[IEEE80211_ADDR_LEN];
+ __le16 region_code;
+ __le32 fw_rev;
+ __le32 ps_cookie;
+ __le32 caps;
+ __u8 mcs_bitmap[16];
+ __le32 rx_queue_ptr;
+ __le32 num_tx_queues;
+ __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
+ __le32 caps2;
+ __le32 num_tx_desc_per_queue;
+ __le32 total_rx_desc;
+} __attribute__((packed));
+
+static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_cmd_get_hw_spec *cmd;
+ int rc;
+ int i;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
+ cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
+ cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma);
+ cmd->num_tx_queues = MWL8K_TX_QUEUES;
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].tx_desc_dma);
+ cmd->num_tx_desc_per_queue = MWL8K_TX_DESCS;
+ cmd->total_rx_desc = MWL8K_RX_DESCS;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+
+ if (!rc) {
+ SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
+ priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
+ priv->fw_rev = cmd->fw_rev;
+ priv->hw_rev = cmd->hw_rev;
+ priv->region_code = le16_to_cpu(cmd->region_code);
+ }
+
+ kfree(cmd);
+ return rc;
+}
+
+/*
+ * CMD_MAC_MULTICAST_ADR.
+ */
+struct mwl8k_cmd_mac_multicast_adr {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 numaddr;
+ __u8 addr[1][IEEE80211_ADDR_LEN];
+};
+
+#define MWL8K_ENABLE_RX_MULTICAST 0x000F
+static int mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
+ int mc_count,
+ struct dev_addr_list *mclist)
+{
+ struct mwl8k_cmd_mac_multicast_adr *cmd;
+ int index = 0;
+ int rc;
+ int size = sizeof(*cmd) + ((mc_count - 1) * IEEE80211_ADDR_LEN);
+ cmd = kzalloc(size, GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
+ cmd->header.length = cpu_to_le16(size);
+ cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
+ cmd->numaddr = cpu_to_le16(mc_count);
+ while ((index < mc_count) && mclist) {
+ if (mclist->da_addrlen != IEEE80211_ADDR_LEN) {
+ rc = -EINVAL;
+ goto mwl8k_cmd_mac_multicast_adr_exit;
+ }
+ memcpy(cmd->addr[index], mclist->da_addr, IEEE80211_ADDR_LEN);
+ index++;
+ mclist = mclist->next;
+ }
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+
+mwl8k_cmd_mac_multicast_adr_exit:
+ kfree(cmd);
+ return rc;
+}
+
+/*
+ * CMD_802_11_GET_STAT.
+ */
+struct mwl8k_cmd_802_11_get_stat {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le32 stats[64];
+} __attribute__((packed));
+
+#define MWL8K_STAT_ACK_FAILURE 9
+#define MWL8K_STAT_RTS_FAILURE 12
+#define MWL8K_STAT_FCS_ERROR 24
+#define MWL8K_STAT_RTS_SUCCESS 11
+
+static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ struct mwl8k_cmd_802_11_get_stat *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_GET);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ if (!rc) {
+ stats->dot11ACKFailureCount =
+ le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]);
+ stats->dot11RTSFailureCount =
+ le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]);
+ stats->dot11FCSErrorCount =
+ le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]);
+ stats->dot11RTSSuccessCount =
+ le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]);
+ }
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_802_11_RADIO_CONTROL.
+ */
+struct mwl8k_cmd_802_11_radio_control {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 control;
+ __le16 radio_on;
+} __attribute__((packed));
+
+static int mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, int enable)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_cmd_802_11_radio_control *cmd;
+ int rc;
+
+ if (((enable & MWL8K_RADIO_ENABLE) == priv->radio_state) &&
+ !(enable & MWL8K_RADIO_FORCE))
+ return 0;
+
+ enable &= MWL8K_RADIO_ENABLE;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->control = cpu_to_le16(priv->radio_preamble);
+ cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ if (!rc)
+ priv->radio_state = enable;
+
+ return rc;
+}
+
+static int
+mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
+{
+ struct mwl8k_priv *priv;
+
+ if (hw == NULL || hw->priv == NULL)
+ return -EINVAL;
+ priv = hw->priv;
+
+ priv->radio_preamble = (short_preamble ?
+ MWL8K_RADIO_SHORT_PREAMBLE :
+ MWL8K_RADIO_LONG_PREAMBLE);
+
+ return mwl8k_cmd_802_11_radio_control(hw,
+ MWL8K_RADIO_ENABLE | MWL8K_RADIO_FORCE);
+}
+
+/*
+ * CMD_802_11_RF_TX_POWER.
+ */
+#define MWL8K_TX_POWER_LEVEL_TOTAL 8
+
+struct mwl8k_cmd_802_11_rf_tx_power {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 support_level;
+ __le16 current_level;
+ __le16 reserved;
+ __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
+} __attribute__((packed));
+
+static int mwl8k_cmd_802_11_rf_tx_power(struct ieee80211_hw *hw, int dBm)
+{
+ struct mwl8k_cmd_802_11_rf_tx_power *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->support_level = cpu_to_le16(dBm);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_PRE_SCAN.
+ */
+struct mwl8k_cmd_set_pre_scan {
+ struct mwl8k_cmd_pkt header;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
+{
+ struct mwl8k_cmd_set_pre_scan *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_POST_SCAN.
+ */
+struct mwl8k_cmd_set_post_scan {
+ struct mwl8k_cmd_pkt header;
+ __le32 isibss;
+ __u8 bssid[IEEE80211_ADDR_LEN];
+} __attribute__((packed));
+
+static int
+mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 mac[IEEE80211_ADDR_LEN])
+{
+ struct mwl8k_cmd_set_post_scan *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->isibss = 0;
+ memcpy(cmd->bssid, mac, IEEE80211_ADDR_LEN);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_RF_CHANNEL.
+ */
+struct mwl8k_cmd_set_rf_channel {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __u8 current_channel;
+ __le32 channel_flags;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
+ struct ieee80211_channel *channel)
+{
+ struct mwl8k_cmd_set_rf_channel *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->current_channel = channel->hw_value;
+ if (channel->band == IEEE80211_BAND_2GHZ)
+ cmd->channel_flags = cpu_to_le32(0x00000081);
+ else
+ cmd->channel_flags = cpu_to_le32(0x00000000);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_SLOT.
+ */
+struct mwl8k_cmd_set_slot {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __u8 short_slot;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, int slot_time)
+{
+ struct mwl8k_cmd_set_slot *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->short_slot = slot_time == MWL8K_SHORT_SLOTTIME ? 1 : 0;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_MIMO_CONFIG.
+ */
+struct mwl8k_cmd_mimo_config {
+ struct mwl8k_cmd_pkt header;
+ __le32 action;
+ __u8 rx_antenna_map;
+ __u8 tx_antenna_map;
+} __attribute__((packed));
+
+static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
+{
+ struct mwl8k_cmd_mimo_config *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
+ cmd->rx_antenna_map = rx;
+ cmd->tx_antenna_map = tx;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_ENABLE_SNIFFER.
+ */
+struct mwl8k_cmd_enable_sniffer {
+ struct mwl8k_cmd_pkt header;
+ __le32 action;
+} __attribute__((packed));
+
+static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
+{
+ struct mwl8k_cmd_enable_sniffer *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = enable ? cpu_to_le32((u32)MWL8K_CMD_SET) : 0;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_RATE_ADAPT_MODE.
+ */
+struct mwl8k_cmd_set_rate_adapt_mode {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 mode;
+} __attribute__((packed));
+
+static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode)
+{
+ struct mwl8k_cmd_set_rate_adapt_mode *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->mode = cpu_to_le16(mode);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_WMM_MODE.
+ */
+struct mwl8k_cmd_set_wmm {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+} __attribute__((packed));
+
+static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_cmd_set_wmm *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = enable ? cpu_to_le16(MWL8K_CMD_SET) : 0;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ if (!rc)
+ priv->wmm_mode = enable;
+
+ return rc;
+}
+
+/*
+ * CMD_SET_RTS_THRESHOLD.
+ */
+struct mwl8k_cmd_rts_threshold {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 threshold;
+} __attribute__((packed));
+
+static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
+ u16 action, u16 *threshold)
+{
+ struct mwl8k_cmd_rts_threshold *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(action);
+ cmd->threshold = cpu_to_le16(*threshold);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_EDCA_PARAMS.
+ */
+struct mwl8k_cmd_set_edca_params {
+ struct mwl8k_cmd_pkt header;
+
+ /* See MWL8K_SET_EDCA_XXX below */
+ __le16 action;
+
+ /* TX opportunity in units of 32 us */
+ __le16 txop;
+
+ /* Log exponent of max contention period: 0...15*/
+ __u8 log_cw_max;
+
+ /* Log exponent of min contention period: 0...15 */
+ __u8 log_cw_min;
+
+ /* Adaptive interframe spacing in units of 32us */
+ __u8 aifs;
+
+ /* TX queue to configure */
+ __u8 txq;
+} __attribute__((packed));
+
+#define MWL8K_GET_EDCA_ALL 0
+#define MWL8K_SET_EDCA_CW 0x01
+#define MWL8K_SET_EDCA_TXOP 0x02
+#define MWL8K_SET_EDCA_AIFS 0x04
+
+#define MWL8K_SET_EDCA_ALL (MWL8K_SET_EDCA_CW | \
+ MWL8K_SET_EDCA_TXOP | \
+ MWL8K_SET_EDCA_AIFS)
+
+static int
+mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
+ __u16 cw_min, __u16 cw_max,
+ __u8 aifs, __u16 txop)
+{
+ struct mwl8k_cmd_set_edca_params *cmd;
+ u32 log_cw_min, log_cw_max;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ log_cw_min = ilog2(cw_min+1);
+ log_cw_max = ilog2(cw_max+1);
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
+ cmd->txop = cpu_to_le16(txop);
+ cmd->log_cw_max = (u8)log_cw_max;
+ cmd->log_cw_min = (u8)log_cw_min;
+ cmd->aifs = aifs;
+ cmd->txq = qnum;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_FINALIZE_JOIN.
+ */
+
+/* FJ beacon buffer size is compiled into the firmware. */
+#define MWL8K_FJ_BEACON_MAXLEN 128
+
+struct mwl8k_cmd_finalize_join {
+ struct mwl8k_cmd_pkt header;
+ __le32 sleep_interval; /* Number of beacon periods to sleep */
+ __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
+} __attribute__((packed));
+
+static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
+ __u16 framelen, __u16 dtim)
+{
+ struct mwl8k_cmd_finalize_join *cmd;
+ struct ieee80211_mgmt *payload = frame;
+ u16 hdrlen;
+ u32 payload_len;
+ int rc;
+
+ if (frame == NULL)
+ return -EINVAL;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ if (dtim)
+ cmd->sleep_interval = cpu_to_le32(dtim);
+ else
+ cmd->sleep_interval = cpu_to_le32(1);
+
+ hdrlen = ieee80211_hdrlen(payload->frame_control);
+
+ payload_len = framelen > hdrlen ? framelen - hdrlen : 0;
+
+ /* XXX TBD Might just have to abort and return an error */
+ if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
+ printk(KERN_ERR "%s(): WARNING: Incomplete beacon "
+ "sent to firmware. Sz=%u MAX=%u\n", __func__,
+ payload_len, MWL8K_FJ_BEACON_MAXLEN);
+
+ payload_len = payload_len > MWL8K_FJ_BEACON_MAXLEN ?
+ MWL8K_FJ_BEACON_MAXLEN : payload_len;
+
+ if (payload && payload_len)
+ memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+ return rc;
+}
+
+/*
+ * CMD_UPDATE_STADB.
+ */
+struct mwl8k_cmd_update_sta_db {
+ struct mwl8k_cmd_pkt header;
+
+ /* See STADB_ACTION_TYPE */
+ __le32 action;
+
+ /* Peer MAC address */
+ __u8 peer_addr[IEEE80211_ADDR_LEN];
+
+ __le32 reserved;
+
+ /* Peer info - valid during add/update. */
+ struct peer_capability_info peer_info;
+} __attribute__((packed));
+
+static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, __u32 action)
+{
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+ struct ieee80211_bss_conf *info = &mv_vif->bss_info;
+ struct mwl8k_cmd_update_sta_db *cmd;
+ struct peer_capability_info *peer_info;
+ struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
+ DECLARE_MAC_BUF(mac);
+ int rc;
+ __u8 count, *rates;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ cmd->action = cpu_to_le32(action);
+ peer_info = &cmd->peer_info;
+ memcpy(cmd->peer_addr, mv_vif->bssid, IEEE80211_ADDR_LEN);
+
+ switch (action) {
+ case MWL8K_STA_DB_ADD_ENTRY:
+ case MWL8K_STA_DB_MODIFY_ENTRY:
+ /* Build peer_info block */
+ peer_info->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
+ peer_info->basic_caps = cpu_to_le16(info->assoc_capability);
+ peer_info->interop = 1;
+ peer_info->amsdu_enabled = 0;
+
+ rates = peer_info->legacy_rates;
+ for (count = 0 ; count < mv_vif->legacy_nrates; count++)
+ rates[count] = bitrates[count].hw_value;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ if (rc == 0)
+ mv_vif->peer_id = peer_info->station_id;
+
+ break;
+
+ case MWL8K_STA_DB_DEL_ENTRY:
+ case MWL8K_STA_DB_FLUSH:
+ default:
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ if (rc == 0)
+ mv_vif->peer_id = 0;
+ break;
+ }
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_AID.
+ */
+#define IEEE80211_OPMODE_DISABLED 0x00
+#define IEEE80211_OPMODE_NON_MEMBER_PROT_MODE 0x01
+#define IEEE80211_OPMODE_ONE_20MHZ_STA_PROT_MODE 0x02
+#define IEEE80211_OPMODE_HTMIXED_PROT_MODE 0x03
+
+#define MWL8K_RATE_INDEX_MAX_ARRAY 14
+
+#define MWL8K_FRAME_PROT_DISABLED 0x00
+#define MWL8K_FRAME_PROT_11G 0x07
+#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02
+#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06
+#define MWL8K_FRAME_PROT_MASK 0x07
+
+struct mwl8k_cmd_update_set_aid {
+ struct mwl8k_cmd_pkt header;
+ __le16 aid;
+
+ /* AP's MAC address (BSSID) */
+ __u8 bssid[IEEE80211_ADDR_LEN];
+ __le16 protection_mode;
+ __u8 supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+ struct ieee80211_bss_conf *info = &mv_vif->bss_info;
+ struct mwl8k_cmd_update_set_aid *cmd;
+ struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
+ int count;
+ u16 prot_mode;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->aid = cpu_to_le16(info->aid);
+
+ memcpy(cmd->bssid, mv_vif->bssid, IEEE80211_ADDR_LEN);
+
+ prot_mode = MWL8K_FRAME_PROT_DISABLED;
+
+ if (info->use_cts_prot) {
+ prot_mode = MWL8K_FRAME_PROT_11G;
+ } else {
+ 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;
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+ prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
+ break;
+ default:
+ prot_mode = MWL8K_FRAME_PROT_DISABLED;
+ break;
+ }
+ }
+
+ cmd->protection_mode = cpu_to_le16(prot_mode);
+
+ for (count = 0; count < mv_vif->legacy_nrates; count++)
+ cmd->supp_rates[count] = bitrates[count].hw_value;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_RATE.
+ */
+struct mwl8k_cmd_update_rateset {
+ struct mwl8k_cmd_pkt header;
+ __u8 legacy_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
+
+ /* Bitmap for supported MCS codes. */
+ __u8 mcs_set[MWL8K_IEEE_LEGACY_DATA_RATES];
+ __u8 reserved[MWL8K_IEEE_LEGACY_DATA_RATES];
+} __attribute__((packed));
+
+static int mwl8k_update_rateset(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+ struct mwl8k_cmd_update_rateset *cmd;
+ struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
+ int count;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ for (count = 0; count < mv_vif->legacy_nrates; count++)
+ cmd->legacy_rates[count] = bitrates[count].hw_value;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_USE_FIXED_RATE.
+ */
+#define MWL8K_RATE_TABLE_SIZE 8
+#define MWL8K_UCAST_RATE 0
+#define MWL8K_MCAST_RATE 1
+#define MWL8K_BCAST_RATE 2
+
+#define MWL8K_USE_FIXED_RATE 0x0001
+#define MWL8K_USE_AUTO_RATE 0x0002
+
+struct mwl8k_rate_entry {
+ /* Set to 1 if HT rate, 0 if legacy. */
+ __le32 is_ht_rate;
+
+ /* Set to 1 to use retry_count field. */
+ __le32 enable_retry;
+
+ /* Specified legacy rate or MCS. */
+ __le32 rate;
+
+ /* Number of allowed retries. */
+ __le32 retry_count;
+} __attribute__((packed));
+
+struct mwl8k_rate_table {
+ /* 1 to allow specified rate and below */
+ __le32 allow_rate_drop;
+ __le32 num_rates;
+ struct mwl8k_rate_entry rate_entry[MWL8K_RATE_TABLE_SIZE];
+} __attribute__((packed));
+
+struct mwl8k_cmd_use_fixed_rate {
+ struct mwl8k_cmd_pkt header;
+ __le32 action;
+ struct mwl8k_rate_table rate_table;
+
+ /* Unicast, Broadcast or Multicast */
+ __le32 rate_type;
+ __le32 reserved1;
+ __le32 reserved2;
+} __attribute__((packed));
+
+static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw,
+ u32 action, u32 rate_type, struct mwl8k_rate_table *rate_table)
+{
+ struct mwl8k_cmd_use_fixed_rate *cmd;
+ int count;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ cmd->action = cpu_to_le32(action);
+ cmd->rate_type = cpu_to_le32(rate_type);
+
+ if (rate_table != NULL) {
+ /* Copy over each field manually so
+ * that bitflipping can be done
+ */
+ cmd->rate_table.allow_rate_drop =
+ cpu_to_le32(rate_table->allow_rate_drop);
+ cmd->rate_table.num_rates =
+ cpu_to_le32(rate_table->num_rates);
+
+ for (count = 0; count < rate_table->num_rates; count++) {
+ struct mwl8k_rate_entry *dst =
+ &cmd->rate_table.rate_entry[count];
+ struct mwl8k_rate_entry *src =
+ &rate_table->rate_entry[count];
+
+ dst->is_ht_rate = cpu_to_le32(src->is_ht_rate);
+ dst->enable_retry = cpu_to_le32(src->enable_retry);
+ dst->rate = cpu_to_le32(src->rate);
+ dst->retry_count = cpu_to_le32(src->retry_count);
+ }
+ }
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+
+/*
+ * Interrupt handling.
+ */
+static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
+{
+ struct ieee80211_hw *hw = dev_id;
+ struct mwl8k_priv *priv = hw->priv;
+ u32 status;
+
+ status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+
+ status &= priv->int_mask;
+ if (!status)
+ return IRQ_NONE;
+
+ if (status & MWL8K_A2H_INT_TX_DONE)
+ tasklet_schedule(&priv->tx_reclaim_task);
+
+ if (status & MWL8K_A2H_INT_RX_READY) {
+ while (rxq_process(hw, 0, 1))
+ rxq_refill(hw, 0, 1);
+ }
+
+ if (status & MWL8K_A2H_INT_OPC_DONE) {
+ if (priv->hostcmd_wait != NULL) {
+ complete(priv->hostcmd_wait);
+ priv->hostcmd_wait = NULL;
+ }
+ }
+
+ if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
+ if (!priv->inconfig &&
+ priv->radio_state &&
+ mwl8k_txq_busy(priv))
+ mwl8k_tx_start(priv);
+ }
+
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * Core driver operations.
+ */
+static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ int index = skb_get_queue_mapping(skb);
+ int rc;
+
+ if (priv->current_channel == NULL) {
+ printk(KERN_DEBUG "%s: dropped TX frame since radio "
+ "disabled\n", priv->name);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ rc = mwl8k_txq_xmit(hw, index, skb);
+
+ return rc;
+}
+
+struct mwl8k_work_struct {
+ /* Initialized by mwl8k_queue_work(). */
+ struct work_struct wt;
+
+ /* Required field passed in to mwl8k_queue_work(). */
+ struct ieee80211_hw *hw;
+
+ /* Required field passed in to mwl8k_queue_work(). */
+ int (*wfunc)(struct work_struct *w);
+
+ /* Initialized by mwl8k_queue_work(). */
+ struct completion *cmd_wait;
+
+ /* Result code. */
+ int rc;
+
+ /*
+ * Optional field. Refer to explanation of MWL8K_WQ_XXX_XXX
+ * flags for explanation. Defaults to MWL8K_WQ_DEFAULT_OPTIONS.
+ */
+ u32 options;
+
+ /* Optional field. Defaults to MWL8K_CONFIG_TIMEOUT_MS. */
+ unsigned long timeout_ms;
+
+ /* Optional field. Defaults to MWL8K_WQ_TXWAIT_ATTEMPTS. */
+ u32 txwait_attempts;
+
+ /* Optional field. Defaults to MWL8K_TXWAIT_MS. */
+ u32 tx_timeout_ms;
+ u32 step;
+};
+
+/* Flags controlling behavior of config queue requests */
+
+/* Caller spins while waiting for completion. */
+#define MWL8K_WQ_SPIN 0x00000001
+
+/* Wait for TX queues to empty before proceeding with configuration. */
+#define MWL8K_WQ_TX_WAIT_EMPTY 0x00000002
+
+/* Queue request and return immediately. */
+#define MWL8K_WQ_POST_REQUEST 0x00000004
+
+/*
+ * Caller sleeps and waits for task complete notification.
+ * Do not use in atomic context.
+ */
+#define MWL8K_WQ_SLEEP 0x00000008
+
+/* Free work struct when task is done. */
+#define MWL8K_WQ_FREE_WORKSTRUCT 0x00000010
+
+/*
+ * Config request is queued and returns to caller imediately. Use
+ * this in atomic context. Work struct is freed by mwl8k_queue_work()
+ * when this flag is set.
+ */
+#define MWL8K_WQ_QUEUE_ONLY (MWL8K_WQ_POST_REQUEST | \
+ MWL8K_WQ_FREE_WORKSTRUCT)
+
+/* Default work queue behavior is to sleep and wait for tx completion. */
+#define MWL8K_WQ_DEFAULT_OPTIONS (MWL8K_WQ_SLEEP | MWL8K_WQ_TX_WAIT_EMPTY)
+
+/*
+ * Default config request timeout. Add adjustments to make sure the
+ * config thread waits long enough for both tx wait and cmd wait before
+ * timing out.
+ */
+
+/* Time to wait for all TXQs to drain. TX Doorbell is pressed each time. */
+#define MWL8K_TXWAIT_TIMEOUT_MS 1000
+
+/* Default number of TX wait attempts. */
+#define MWL8K_WQ_TXWAIT_ATTEMPTS 4
+
+/* Total time to wait for TXQ to drain. */
+#define MWL8K_TXWAIT_MS (MWL8K_TXWAIT_TIMEOUT_MS * \
+ MWL8K_WQ_TXWAIT_ATTEMPTS)
+
+/* Scheduling slop. */
+#define MWL8K_OS_SCHEDULE_OVERHEAD_MS 200
+
+#define MWL8K_CONFIG_TIMEOUT_MS (MWL8K_CMD_TIMEOUT_MS + \
+ MWL8K_TXWAIT_MS + \
+ MWL8K_OS_SCHEDULE_OVERHEAD_MS)
+
+static void mwl8k_config_thread(struct work_struct *wt)
+{
+ struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt;
+ struct ieee80211_hw *hw = worker->hw;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+
+ spin_lock_irq(&priv->tx_lock);
+ priv->inconfig = true;
+ spin_unlock_irq(&priv->tx_lock);
+
+ ieee80211_stop_queues(hw);
+
+ /*
+ * Wait for host queues to drain before doing PHY
+ * reconfiguration. This avoids interrupting any in-flight
+ * DMA transfers to the hardware.
+ */
+ if (worker->options & MWL8K_WQ_TX_WAIT_EMPTY) {
+ u32 timeout;
+ u32 time_remaining;
+ u32 iter;
+ u32 tx_wait_attempts = worker->txwait_attempts;
+
+ time_remaining = worker->tx_timeout_ms;
+ if (!tx_wait_attempts)
+ tx_wait_attempts = 1;
+
+ timeout = worker->tx_timeout_ms/tx_wait_attempts;
+ if (!timeout)
+ timeout = 1;
+
+ iter = tx_wait_attempts;
+ do {
+ int wait_time;
+
+ if (time_remaining > timeout) {
+ time_remaining -= timeout;
+ wait_time = timeout;
+ } else
+ wait_time = time_remaining;
+
+ if (!wait_time)
+ wait_time = 1;
+
+ rc = mwl8k_tx_wait_empty(hw, wait_time);
+ if (rc)
+ printk(KERN_ERR "%s() txwait timeout=%ums "
+ "Retry:%u/%u\n", __func__, timeout,
+ tx_wait_attempts - iter + 1,
+ tx_wait_attempts);
+
+ } while (rc && --iter);
+
+ rc = iter ? 0 : -ETIMEDOUT;
+ }
+ if (!rc)
+ rc = worker->wfunc(wt);
+
+ spin_lock_irq(&priv->tx_lock);
+ priv->inconfig = false;
+ if (priv->pending_tx_pkts && priv->radio_state)
+ mwl8k_tx_start(priv);
+ spin_unlock_irq(&priv->tx_lock);
+ ieee80211_wake_queues(hw);
+
+ worker->rc = rc;
+ if (worker->options & MWL8K_WQ_SLEEP)
+ complete(worker->cmd_wait);
+
+ if (worker->options & MWL8K_WQ_FREE_WORKSTRUCT)
+ kfree(wt);
+}
+
+static int mwl8k_queue_work(struct ieee80211_hw *hw,
+ struct mwl8k_work_struct *worker,
+ struct workqueue_struct *wqueue,
+ int (*wfunc)(struct work_struct *w))
+{
+ unsigned long timeout = 0;
+ int rc = 0;
+
+ DECLARE_COMPLETION_ONSTACK(cmd_wait);
+
+ if (!worker->timeout_ms)
+ worker->timeout_ms = MWL8K_CONFIG_TIMEOUT_MS;
+
+ if (!worker->options)
+ worker->options = MWL8K_WQ_DEFAULT_OPTIONS;
+
+ if (!worker->txwait_attempts)
+ worker->txwait_attempts = MWL8K_WQ_TXWAIT_ATTEMPTS;
+
+ if (!worker->tx_timeout_ms)
+ worker->tx_timeout_ms = MWL8K_TXWAIT_MS;
+
+ worker->hw = hw;
+ worker->cmd_wait = &cmd_wait;
+ worker->rc = 1;
+ worker->wfunc = wfunc;
+
+ INIT_WORK(&worker->wt, mwl8k_config_thread);
+ queue_work(wqueue, &worker->wt);
+
+ if (worker->options & MWL8K_WQ_POST_REQUEST) {
+ rc = 0;
+ } else {
+ if (worker->options & MWL8K_WQ_SPIN) {
+ timeout = worker->timeout_ms;
+ while (timeout && (worker->rc > 0)) {
+ mdelay(1);
+ timeout--;
+ }
+ } else if (worker->options & MWL8K_WQ_SLEEP)
+ timeout = wait_for_completion_timeout(&cmd_wait,
+ msecs_to_jiffies(worker->timeout_ms));
+
+ if (timeout)
+ rc = worker->rc;
+ else {
+ cancel_work_sync(&worker->wt);
+ rc = -ETIMEDOUT;
+ }
+ }
+
+ return rc;
+}
+
+struct mwl8k_start_worker {
+ struct mwl8k_work_struct header;
+};
+
+static int mwl8k_start_wt(struct work_struct *wt)
+{
+ struct mwl8k_start_worker *worker = (struct mwl8k_start_worker *)wt;
+ struct ieee80211_hw *hw = worker->header.hw;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+
+ if (priv->vif != NULL) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Turn on radio */
+ if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Purge TX/RX HW queues */
+ if (mwl8k_cmd_set_pre_scan(hw)) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ if (mwl8k_cmd_set_post_scan(hw, "\x00\x00\x00\x00\x00\x00")) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Enable firmware rate adaptation */
+ if (mwl8k_cmd_setrateadaptmode(hw, 0)) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Disable WMM. WMM gets enabled when stack sends WMM parms */
+ if (mwl8k_set_wmm(hw, MWL8K_WMM_DISABLE)) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Disable sniffer mode */
+ if (mwl8k_enable_sniffer(hw, 0))
+ rc = -EIO;
+
+mwl8k_start_exit:
+ return rc;
+}
+
+static int mwl8k_start(struct ieee80211_hw *hw)
+{
+ struct mwl8k_start_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc;
+
+ /* Enable tx reclaim tasklet */
+ tasklet_enable(&priv->tx_reclaim_task);
+
+ rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
+ IRQF_SHARED, MWL8K_NAME, hw);
+ if (rc) {
+ printk(KERN_ERR "%s: failed to register IRQ handler\n",
+ priv->name);
+ rc = -EIO;
+ goto mwl8k_start_disable_tasklet;
+ }
+
+ /* Enable interrupts */
+ iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL) {
+ rc = -ENOMEM;
+ goto mwl8k_start_disable_irq;
+ }
+
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_start_wt);
+ kfree(worker);
+ if (!rc)
+ return rc;
+
+ if (rc == -ETIMEDOUT)
+ printk(KERN_ERR "%s() timed out\n", __func__);
+
+ rc = -EIO;
+
+mwl8k_start_disable_irq:
+ spin_lock_irq(&priv->tx_lock);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ spin_unlock_irq(&priv->tx_lock);
+ free_irq(priv->pdev->irq, hw);
+
+mwl8k_start_disable_tasklet:
+ tasklet_disable(&priv->tx_reclaim_task);
+
+ return rc;
+}
+
+struct mwl8k_stop_worker {
+ struct mwl8k_work_struct header;
+};
+
+static int mwl8k_stop_wt(struct work_struct *wt)
+{
+ struct mwl8k_stop_worker *worker = (struct mwl8k_stop_worker *)wt;
+ struct ieee80211_hw *hw = worker->header.hw;
+ int rc;
+
+ rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+
+ return rc;
+}
+
+static void mwl8k_stop(struct ieee80211_hw *hw)
+{
+ int rc;
+ struct mwl8k_stop_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+ int i;
+
+ if (priv->vif != NULL)
+ return;
+
+ ieee80211_stop_queues(hw);
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return;
+
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_stop_wt);
+ kfree(worker);
+ if (rc == -ETIMEDOUT)
+ printk(KERN_ERR "%s() timed out\n", __func__);
+
+ /* Disable interrupts */
+ spin_lock_irq(&priv->tx_lock);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ spin_unlock_irq(&priv->tx_lock);
+ free_irq(priv->pdev->irq, hw);
+
+ /* Stop finalize join worker */
+ cancel_work_sync(&priv->finalize_join_worker);
+ if (priv->beacon_skb != NULL)
+ dev_kfree_skb(priv->beacon_skb);
+
+ /* Stop tx reclaim tasklet */
+ tasklet_disable(&priv->tx_reclaim_task);
+
+ /* Stop config thread */
+ flush_workqueue(priv->config_wq);
+
+ /* Return all skbs to mac80211 */
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_reclaim(hw, i, 1);
+}
+
+static int mwl8k_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_vif *mwl8k_vif;
+
+ /*
+ * We only support one active interface at a time.
+ */
+ if (priv->vif != NULL)
+ return -EBUSY;
+
+ /*
+ * We only support managed interfaces for now.
+ */
+ if (conf->type != NL80211_IFTYPE_STATION &&
+ conf->type != NL80211_IFTYPE_MONITOR)
+ return -EINVAL;
+
+ /* Clean out driver private area */
+ mwl8k_vif = MWL8K_VIF(conf->vif);
+ memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
+
+ /* Save the mac address */
+ memcpy(mwl8k_vif->mac_addr, conf->mac_addr, IEEE80211_ADDR_LEN);
+
+ /* Back pointer to parent config block */
+ mwl8k_vif->priv = priv;
+
+ /* Setup initial PHY parameters */
+ memcpy(mwl8k_vif->legacy_rates ,
+ priv->rates, sizeof(mwl8k_vif->legacy_rates));
+ mwl8k_vif->legacy_nrates = ARRAY_SIZE(priv->rates);
+
+ /* Set Initial sequence number to zero */
+ mwl8k_vif->seqno = 0;
+
+ priv->vif = conf->vif;
+ priv->current_channel = NULL;
+
+ return 0;
+}
+
+static void mwl8k_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct mwl8k_priv *priv = hw->priv;
+
+ if (priv->vif == NULL)
+ return;
+
+ priv->vif = NULL;
+}
+
+struct mwl8k_config_worker {
+ struct mwl8k_work_struct header;
+ u32 changed;
+};
+
+static int mwl8k_config_wt(struct work_struct *wt)
+{
+ struct mwl8k_config_worker *worker =
+ (struct mwl8k_config_worker *)wt;
+ struct ieee80211_hw *hw = worker->header.hw;
+ struct ieee80211_conf *conf = &hw->conf;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+
+ if (!conf->radio_enabled) {
+ mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+ priv->current_channel = NULL;
+ rc = 0;
+ goto mwl8k_config_exit;
+ }
+
+ if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
+ rc = -EINVAL;
+ goto mwl8k_config_exit;
+ }
+
+ priv->current_channel = conf->channel;
+
+ if (mwl8k_cmd_set_rf_channel(hw, conf->channel)) {
+ rc = -EINVAL;
+ goto mwl8k_config_exit;
+ }
+
+ if (conf->power_level > 18)
+ conf->power_level = 18;
+ if (mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level)) {
+ rc = -EINVAL;
+ goto mwl8k_config_exit;
+ }
+
+ if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7))
+ rc = -EINVAL;
+
+mwl8k_config_exit:
+ return rc;
+}
+
+static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
+{
+ int rc = 0;
+ struct mwl8k_config_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return -ENOMEM;
+
+ worker->changed = changed;
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_config_wt);
+ if (rc == -ETIMEDOUT) {
+ printk(KERN_ERR "%s() timed out.\n", __func__);
+ rc = -EINVAL;
+ }
+
+ kfree(worker);
+
+ /*
+ * mac80211 will crash on anything other than -EINVAL on
+ * error. Looks like wireless extensions which calls mac80211
+ * may be the actual culprit...
+ */
+ 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;
+ struct ieee80211_bss_conf *info;
+ u32 changed;
+};
+
+static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
+{
+ struct mwl8k_bss_info_changed_worker *worker =
+ (struct mwl8k_bss_info_changed_worker *)wt;
+ struct ieee80211_hw *hw = worker->header.hw;
+ struct ieee80211_vif *vif = worker->vif;
+ struct ieee80211_bss_conf *info = worker->info;
+ u32 changed;
+ int rc;
+
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+
+ changed = worker->changed;
+ priv->capture_beacon = false;
+
+ if (info->assoc) {
+ memcpy(&mwl8k_vif->bss_info, info,
+ sizeof(struct ieee80211_bss_conf));
+
+ /* Install rates */
+ if (mwl8k_update_rateset(hw, vif))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Turn on rate adaptation */
+ if (mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
+ MWL8K_UCAST_RATE, NULL))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Set radio preamble */
+ if (mwl8k_set_radio_preamble(hw,
+ info->use_short_preamble))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Set slot time */
+ if (mwl8k_cmd_set_slot(hw, info->use_short_slot ?
+ MWL8K_SHORT_SLOTTIME : MWL8K_LONG_SLOTTIME))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Update peer rate info */
+ if (mwl8k_cmd_update_sta_db(hw, vif,
+ MWL8K_STA_DB_MODIFY_ENTRY))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Set AID */
+ if (mwl8k_cmd_set_aid(hw, vif))
+ goto mwl8k_bss_info_changed_exit;
+
+ /*
+ * Finalize the join. Tell rx handler to process
+ * next beacon from our BSSID.
+ */
+ memcpy(priv->capture_bssid,
+ mwl8k_vif->bssid, IEEE80211_ADDR_LEN);
+ priv->capture_beacon = true;
+ } else {
+ mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
+ memset(&mwl8k_vif->bss_info, 0,
+ sizeof(struct ieee80211_bss_conf));
+ memset(mwl8k_vif->bssid, 0, IEEE80211_ADDR_LEN);
+ }
+
+mwl8k_bss_info_changed_exit:
+ rc = 0;
+ return rc;
+}
+
+static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ struct mwl8k_bss_info_changed_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc;
+
+ if ((changed & BSS_CHANGED_ASSOC) == 0)
+ return;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return;
+
+ worker->vif = vif;
+ worker->info = info;
+ worker->changed = changed;
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq,
+ mwl8k_bss_info_changed_wt);
+ kfree(worker);
+ if (rc == -ETIMEDOUT)
+ printk(KERN_ERR "%s() timed out\n", __func__);
+}
+
+struct mwl8k_configure_filter_worker {
+ struct mwl8k_work_struct header;
+ unsigned int changed_flags;
+ unsigned int *total_flags;
+ int mc_count;
+ struct dev_addr_list *mclist;
+};
+
+#define MWL8K_SUPPORTED_IF_FLAGS FIF_BCN_PRBRESP_PROMISC
+
+static int mwl8k_configure_filter_wt(struct work_struct *wt)
+{
+ struct mwl8k_configure_filter_worker *worker =
+ (struct mwl8k_configure_filter_worker *)wt;
+
+ struct ieee80211_hw *hw = worker->header.hw;
+ unsigned int changed_flags = worker->changed_flags;
+ unsigned int *total_flags = worker->total_flags;
+ int mc_count = worker->mc_count;
+ struct dev_addr_list *mclist = worker->mclist;
+
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_vif *mv_vif;
+ int rc = 0;
+
+ if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+ if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+ rc = mwl8k_cmd_set_pre_scan(hw);
+ else {
+ mv_vif = MWL8K_VIF(priv->vif);
+ rc = mwl8k_cmd_set_post_scan(hw, mv_vif->bssid);
+ }
+ }
+
+ if (rc)
+ goto mwl8k_configure_filter_exit;
+ if (mc_count) {
+ mc_count = mc_count < priv->num_mcaddrs ?
+ mc_count : priv->num_mcaddrs;
+ rc = mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
+ if (rc)
+ printk(KERN_ERR
+ "%s()Error setting multicast addresses\n",
+ __func__);
+ }
+
+mwl8k_configure_filter_exit:
+ return rc;
+}
+
+static void mwl8k_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mclist)
+{
+
+ struct mwl8k_configure_filter_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ /* Clear unsupported feature flags */
+ *total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
+
+ if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS) && !mc_count)
+ return;
+
+ worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
+ if (worker == NULL)
+ return;
+
+ worker->header.options = MWL8K_WQ_QUEUE_ONLY | MWL8K_WQ_TX_WAIT_EMPTY;
+ worker->changed_flags = changed_flags;
+ worker->total_flags = total_flags;
+ worker->mc_count = mc_count;
+ worker->mclist = mclist;
+
+ mwl8k_queue_work(hw, &worker->header, priv->config_wq,
+ mwl8k_configure_filter_wt);
+}
+
+struct mwl8k_set_rts_threshold_worker {
+ struct mwl8k_work_struct header;
+ u32 value;
+};
+
+static int mwl8k_set_rts_threshold_wt(struct work_struct *wt)
+{
+ struct mwl8k_set_rts_threshold_worker *worker =
+ (struct mwl8k_set_rts_threshold_worker *)wt;
+
+ struct ieee80211_hw *hw = worker->header.hw;
+ u16 threshold = (u16)(worker->value);
+ int rc;
+
+ rc = mwl8k_rts_threshold(hw, MWL8K_CMD_SET, &threshold);
+
+ return rc;
+}
+
+static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ int rc;
+ struct mwl8k_set_rts_threshold_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return -ENOMEM;
+
+ worker->value = value;
+
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq,
+ mwl8k_set_rts_threshold_wt);
+ kfree(worker);
+
+ if (rc == -ETIMEDOUT) {
+ printk(KERN_ERR "%s() timed out\n", __func__);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+struct mwl8k_conf_tx_worker {
+ struct mwl8k_work_struct header;
+ u16 queue;
+ const struct ieee80211_tx_queue_params *params;
+};
+
+static int mwl8k_conf_tx_wt(struct work_struct *wt)
+{
+ struct mwl8k_conf_tx_worker *worker =
+ (struct mwl8k_conf_tx_worker *)wt;
+
+ struct ieee80211_hw *hw = worker->header.hw;
+ u16 queue = worker->queue;
+ const struct ieee80211_tx_queue_params *params = worker->params;
+
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+
+ if (priv->wmm_mode == MWL8K_WMM_DISABLE)
+ if (mwl8k_set_wmm(hw, MWL8K_WMM_ENABLE)) {
+ rc = -EINVAL;
+ goto mwl8k_conf_tx_exit;
+ }
+
+ if (mwl8k_set_edca_params(hw, GET_TXQ(queue), params->cw_min,
+ params->cw_max, params->aifs, params->txop))
+ rc = -EINVAL;
+mwl8k_conf_tx_exit:
+ return rc;
+}
+
+static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
+{
+ int rc;
+ struct mwl8k_conf_tx_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return -ENOMEM;
+
+ worker->queue = queue;
+ worker->params = params;
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_conf_tx_wt);
+ kfree(worker);
+ if (rc == -ETIMEDOUT) {
+ printk(KERN_ERR "%s() timed out\n", __func__);
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
+static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
+ struct ieee80211_tx_queue_stats *stats)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_tx_queue *txq;
+ int index;
+
+ spin_lock_bh(&priv->tx_lock);
+ for (index = 0; index < MWL8K_TX_QUEUES; index++) {
+ txq = priv->txq + index;
+ memcpy(&stats[index], &txq->tx_stats,
+ sizeof(struct ieee80211_tx_queue_stats));
+ }
+ spin_unlock_bh(&priv->tx_lock);
+ return 0;
+}
+
+struct mwl8k_get_stats_worker {
+ struct mwl8k_work_struct header;
+ struct ieee80211_low_level_stats *stats;
+};
+
+static int mwl8k_get_stats_wt(struct work_struct *wt)
+{
+ struct mwl8k_get_stats_worker *worker =
+ (struct mwl8k_get_stats_worker *)wt;
+
+ return mwl8k_cmd_802_11_get_stat(worker->header.hw, worker->stats);
+}
+
+static int mwl8k_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ int rc;
+ struct mwl8k_get_stats_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return -ENOMEM;
+
+ worker->stats = stats;
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_get_stats_wt);
+
+ kfree(worker);
+ if (rc == -ETIMEDOUT) {
+ printk(KERN_ERR "%s() timed out\n", __func__);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static const struct ieee80211_ops mwl8k_ops = {
+ .tx = mwl8k_tx,
+ .start = mwl8k_start,
+ .stop = mwl8k_stop,
+ .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,
+ .conf_tx = mwl8k_conf_tx,
+ .get_tx_stats = mwl8k_get_tx_stats,
+ .get_stats = mwl8k_get_stats,
+};
+
+static void mwl8k_tx_reclaim_handler(unsigned long data)
+{
+ int i;
+ struct ieee80211_hw *hw = (struct ieee80211_hw *) data;
+ struct mwl8k_priv *priv = hw->priv;
+
+ spin_lock_bh(&priv->tx_lock);
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_reclaim(hw, i, 0);
+
+ if (priv->tx_wait != NULL) {
+ int count = mwl8k_txq_busy(priv);
+ if (count == 0) {
+ complete(priv->tx_wait);
+ priv->tx_wait = NULL;
+ }
+ }
+ spin_unlock_bh(&priv->tx_lock);
+}
+
+static void mwl8k_finalize_join_worker(struct work_struct *work)
+{
+ struct mwl8k_priv *priv =
+ container_of(work, struct mwl8k_priv, finalize_join_worker);
+ struct sk_buff *skb = priv->beacon_skb;
+ u8 dtim = (MWL8K_VIF(priv->vif))->bss_info.dtim_period;
+
+ mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim);
+ dev_kfree_skb(skb);
+
+ priv->beacon_skb = NULL;
+}
+
+static int __devinit mwl8k_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct ieee80211_hw *hw;
+ struct mwl8k_priv *priv;
+ DECLARE_MAC_BUF(mac);
+ int rc;
+ int i;
+ u8 *fw;
+
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot enable new PCI device\n",
+ MWL8K_NAME);
+ return rc;
+ }
+
+ rc = pci_request_regions(pdev, MWL8K_NAME);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
+ MWL8K_NAME);
+ return rc;
+ }
+
+ pci_set_master(pdev);
+
+ hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
+ if (hw == NULL) {
+ printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
+ rc = -ENOMEM;
+ goto err_free_reg;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+ priv->pdev = pdev;
+ priv->hostcmd_wait = NULL;
+ priv->tx_wait = NULL;
+ priv->inconfig = false;
+ priv->wep_enabled = 0;
+ priv->wmm_mode = false;
+ priv->pending_tx_pkts = 0;
+ strncpy(priv->name, MWL8K_NAME, sizeof(priv->name));
+
+ spin_lock_init(&priv->fw_lock);
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
+
+ priv->regs = pci_iomap(pdev, 1, 0x10000);
+ if (priv->regs == NULL) {
+ printk(KERN_ERR "%s: Cannot map device memory\n", priv->name);
+ goto err_iounmap;
+ }
+
+ memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
+ priv->band.band = IEEE80211_BAND_2GHZ;
+ priv->band.channels = priv->channels;
+ priv->band.n_channels = ARRAY_SIZE(mwl8k_channels);
+ priv->band.bitrates = priv->rates;
+ priv->band.n_bitrates = ARRAY_SIZE(mwl8k_rates);
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+
+ BUILD_BUG_ON(sizeof(priv->rates) != sizeof(mwl8k_rates));
+ memcpy(priv->rates, mwl8k_rates, sizeof(mwl8k_rates));
+
+ /*
+ * Extra headroom is the size of the required DMA header
+ * minus the size of the smallest 802.11 frame (CTS frame).
+ */
+ hw->extra_tx_headroom =
+ sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
+
+ hw->channel_change_time = 10;
+
+ hw->queues = MWL8K_TX_QUEUES;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_MONITOR);
+
+ /* Set rssi and noise values to dBm */
+ hw->flags |= (IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM);
+ hw->vif_data_size = sizeof(struct mwl8k_vif);
+ priv->vif = NULL;
+
+ /* Set default radio state and preamble */
+ priv->radio_preamble = MWL8K_RADIO_DEFAULT_PREAMBLE;
+ priv->radio_state = MWL8K_RADIO_DISABLE;
+
+ /* Finalize join worker */
+ INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
+
+ /* TX reclaim tasklet */
+ tasklet_init(&priv->tx_reclaim_task,
+ mwl8k_tx_reclaim_handler, (unsigned long)hw);
+ tasklet_disable(&priv->tx_reclaim_task);
+
+ /* Config workthread */
+ priv->config_wq = create_singlethread_workqueue("mwl8k_config");
+ if (priv->config_wq == NULL)
+ goto err_iounmap;
+
+ /* Power management cookie */
+ priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
+ if (priv->cookie == NULL)
+ goto err_iounmap;
+
+ rc = mwl8k_rxq_init(hw, 0);
+ if (rc)
+ goto err_iounmap;
+ rxq_refill(hw, 0, INT_MAX);
+
+ spin_lock_init(&priv->tx_lock);
+
+ for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+ rc = mwl8k_txq_init(hw, i);
+ if (rc)
+ goto err_free_queues;
+ }
+
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ priv->int_mask = 0;
+ iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
+ iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
+
+ rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
+ IRQF_SHARED, MWL8K_NAME, hw);
+ if (rc) {
+ printk(KERN_ERR "%s: failed to register IRQ handler\n",
+ priv->name);
+ goto err_free_queues;
+ }
+
+ /* Reset firmware and hardware */
+ mwl8k_hw_reset(priv);
+
+ /* Ask userland hotplug daemon for the device firmware */
+ rc = mwl8k_request_firmware(priv, (u32)id->driver_data);
+ if (rc) {
+ printk(KERN_ERR "%s: Firmware files not found\n", priv->name);
+ goto err_free_irq;
+ }
+
+ /* Load firmware into hardware */
+ rc = mwl8k_load_firmware(priv);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot start firmware\n", priv->name);
+ goto err_stop_firmware;
+ }
+
+ /* Reclaim memory once firmware is successfully loaded */
+ mwl8k_release_firmware(priv);
+
+ /*
+ * Temporarily enable interrupts. Initial firmware host
+ * commands use interrupts and avoids polling. Disable
+ * interrupts when done.
+ */
+ priv->int_mask |= MWL8K_A2H_EVENTS;
+
+ iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+
+ /* Get config data, mac addrs etc */
+ rc = mwl8k_cmd_get_hw_spec(hw);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot initialise firmware\n", priv->name);
+ goto err_stop_firmware;
+ }
+
+ /* Turn radio off */
+ rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot disable\n", priv->name);
+ goto err_stop_firmware;
+ }
+
+ /* Disable interrupts */
+ spin_lock_irq(&priv->tx_lock);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ spin_unlock_irq(&priv->tx_lock);
+ free_irq(priv->pdev->irq, hw);
+
+ rc = ieee80211_register_hw(hw);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot register device\n", priv->name);
+ goto err_stop_firmware;
+ }
+
+ fw = (u8 *)&priv->fw_rev;
+ printk(KERN_INFO "%s: 88W%u %s\n", priv->name, priv->part_num,
+ MWL8K_DESC);
+ printk(KERN_INFO "%s: Driver Ver:%s Firmware Ver:%u.%u.%u.%u\n",
+ priv->name, MWL8K_VERSION, fw[3], fw[2], fw[1], fw[0]);
+ printk(KERN_INFO "%s: MAC Address: %s\n", priv->name,
+ print_mac(mac, hw->wiphy->perm_addr));
+
+ return 0;
+
+err_stop_firmware:
+ mwl8k_hw_reset(priv);
+ mwl8k_release_firmware(priv);
+
+err_free_irq:
+ spin_lock_irq(&priv->tx_lock);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ spin_unlock_irq(&priv->tx_lock);
+ free_irq(priv->pdev->irq, hw);
+
+err_free_queues:
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_deinit(hw, i);
+ mwl8k_rxq_deinit(hw, 0);
+
+err_iounmap:
+ if (priv->cookie != NULL)
+ pci_free_consistent(priv->pdev, 4,
+ priv->cookie, priv->cookie_dma);
+
+ if (priv->regs != NULL)
+ pci_iounmap(pdev, priv->regs);
+
+ if (priv->config_wq != NULL)
+ destroy_workqueue(priv->config_wq);
+
+ pci_set_drvdata(pdev, NULL);
+ ieee80211_free_hw(hw);
+
+err_free_reg:
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+
+ return rc;
+}
+
+static void __devexit mwl8k_remove(struct pci_dev *pdev)
+{
+ printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__);
+}
+
+static void __devexit mwl8k_shutdown(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct mwl8k_priv *priv;
+ int i;
+
+ if (hw == NULL)
+ return;
+ priv = hw->priv;
+
+ ieee80211_stop_queues(hw);
+
+ /* Remove tx reclaim tasklet */
+ tasklet_kill(&priv->tx_reclaim_task);
+
+ /* Stop config thread */
+ destroy_workqueue(priv->config_wq);
+
+ /* Stop hardware */
+ mwl8k_hw_reset(priv);
+
+ /* Return all skbs to mac80211 */
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_reclaim(hw, i, 1);
+
+ ieee80211_unregister_hw(hw);
+
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_deinit(hw, i);
+
+ mwl8k_rxq_deinit(hw, 0);
+
+ pci_free_consistent(priv->pdev, 4,
+ priv->cookie, priv->cookie_dma);
+
+ pci_iounmap(pdev, priv->regs);
+ pci_set_drvdata(pdev, NULL);
+ ieee80211_free_hw(hw);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+static struct pci_driver mwl8k_driver = {
+ .name = MWL8K_NAME,
+ .id_table = mwl8k_table,
+ .probe = mwl8k_probe,
+ .remove = __devexit_p(mwl8k_remove),
+ .shutdown = __devexit_p(mwl8k_shutdown),
+};
+
+static int __init mwl8k_init(void)
+{
+ return pci_register_driver(&mwl8k_driver);
+}
+
+static void __exit mwl8k_exit(void)
+{
+ pci_unregister_driver(&mwl8k_driver);
+}
+
+module_init(mwl8k_init);
+module_exit(mwl8k_exit);
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 24caec6caf1..d63c8992f22 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -210,10 +210,6 @@ static int netwave_rx( struct net_device *dev);
static irqreturn_t netwave_interrupt(int irq, void *dev_id);
static void netwave_watchdog(struct net_device *);
-/* Statistics */
-static void update_stats(struct net_device *dev);
-static struct net_device_stats *netwave_get_stats(struct net_device *dev);
-
/* Wireless extensions */
static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
@@ -275,14 +271,9 @@ typedef struct netwave_private {
int lastExec;
struct timer_list watchdog; /* To avoid blocking state */
struct site_survey nss;
- struct net_device_stats stats;
struct iw_statistics iw_stats; /* Wireless stats */
} netwave_private;
-#ifdef NETWAVE_STATS
-static struct net_device_stats *netwave_get_stats(struct net_device *dev);
-#endif
-
/*
* The Netwave card is little-endian, so won't work for big endian
* systems.
@@ -364,6 +355,17 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
return &priv->iw_stats;
}
+static const struct net_device_ops netwave_netdev_ops = {
+ .ndo_open = netwave_open,
+ .ndo_stop = netwave_close,
+ .ndo_start_xmit = netwave_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = netwave_watchdog,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* Function netwave_attach (void)
*
@@ -412,17 +414,12 @@ static int netwave_probe(struct pcmcia_device *link)
spin_lock_init(&priv->spinlock);
/* Netwave specific entries in the device structure */
- dev->hard_start_xmit = &netwave_start_xmit;
- dev->get_stats = &netwave_get_stats;
- dev->set_multicast_list = &set_multicast_list;
+ dev->netdev_ops = &netwave_netdev_ops;
/* wireless extensions */
- dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
+ dev->wireless_handlers = &netwave_handler_def;
- dev->tx_timeout = &netwave_watchdog;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->open = &netwave_open;
- dev->stop = &netwave_close;
link->irq.Instance = dev;
return netwave_pcmcia_config( link);
@@ -988,7 +985,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
return 1;
}
- priv->stats.tx_bytes += len;
+ dev->stats.tx_bytes += len;
DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
readb(ramBase + NETWAVE_EREG_SPCQ),
@@ -1107,11 +1104,11 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
rser = readb(ramBase + NETWAVE_EREG_RSER);
if (rser & 0x04) {
- ++priv->stats.rx_dropped;
- ++priv->stats.rx_crc_errors;
+ ++dev->stats.rx_dropped;
+ ++dev->stats.rx_crc_errors;
}
if (rser & 0x02)
- ++priv->stats.rx_frame_errors;
+ ++dev->stats.rx_frame_errors;
/* Clear the RxErr bit in RSER. RSER+4 is the
* write part. Also clear the RxCRC (0x04) and
@@ -1125,8 +1122,8 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
wait_WOC(iobase);
writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
- /* Remember to count up priv->stats on error packets */
- ++priv->stats.rx_errors;
+ /* Remember to count up dev->stats on error packets */
+ ++dev->stats.rx_errors;
}
/* TxDN */
if (status & 0x20) {
@@ -1140,17 +1137,17 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
/* Transmitting was okay, clear bits */
wait_WOC(iobase);
writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
- ++priv->stats.tx_packets;
+ ++dev->stats.tx_packets;
}
if (txStatus & 0xd0) {
if (txStatus & 0x80) {
- ++priv->stats.collisions; /* Because of /proc/net/dev*/
- /* ++priv->stats.tx_aborted_errors; */
+ ++dev->stats.collisions; /* Because of /proc/net/dev*/
+ /* ++dev->stats.tx_aborted_errors; */
/* printk("Collision. %ld\n", jiffies - dev->trans_start); */
}
if (txStatus & 0x40)
- ++priv->stats.tx_carrier_errors;
+ ++dev->stats.tx_carrier_errors;
/* 0x80 TxGU Transmit giveup - nine times and no luck
* 0x40 TxNOAP No access point. Discarded packet.
* 0x10 TxErr Transmit error. Always set when
@@ -1163,7 +1160,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
/* Clear out TxGU, TxNOAP, TxErr and TxTrys */
wait_WOC(iobase);
writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
- ++priv->stats.tx_errors;
+ ++dev->stats.tx_errors;
}
DEBUG(3, "New status is TSER %x ASR %x\n",
readb(ramBase + NETWAVE_EREG_TSER),
@@ -1197,40 +1194,6 @@ static void netwave_watchdog(struct net_device *dev) {
netif_wake_queue(dev);
} /* netwave_watchdog */
-static struct net_device_stats *netwave_get_stats(struct net_device *dev) {
- netwave_private *priv = netdev_priv(dev);
-
- update_stats(dev);
-
- DEBUG(2, "netwave: SPCQ %x SPU %x LIF %x ISPLQ %x MHS %x rxtx %x"
- " %x tx %x %x %x %x\n",
- readb(priv->ramBase + NETWAVE_EREG_SPCQ),
- readb(priv->ramBase + NETWAVE_EREG_SPU),
- readb(priv->ramBase + NETWAVE_EREG_LIF),
- readb(priv->ramBase + NETWAVE_EREG_ISPLQ),
- readb(priv->ramBase + NETWAVE_EREG_MHS),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0xe),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0xf),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0x18),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0x19),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0x1a),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0x1b));
-
- return &priv->stats;
-}
-
-static void update_stats(struct net_device *dev) {
- //unsigned long flags;
-/* netwave_private *priv = netdev_priv(dev); */
-
- //spin_lock_irqsave(&priv->spinlock, flags);
-
-/* priv->stats.rx_packets = readb(priv->ramBase + 0x18e);
- priv->stats.tx_packets = readb(priv->ramBase + 0x18f); */
-
- //spin_unlock_irqrestore(&priv->spinlock, flags);
-}
-
static int netwave_rx(struct net_device *dev)
{
netwave_private *priv = netdev_priv(dev);
@@ -1274,7 +1237,7 @@ static int netwave_rx(struct net_device *dev)
if (skb == NULL) {
DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
"length %d\n", rcvLen);
- ++priv->stats.rx_dropped;
+ ++dev->stats.rx_dropped;
/* Tell the adapter to skip the packet */
wait_WOC(iobase);
writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
@@ -1307,8 +1270,8 @@ static int netwave_rx(struct net_device *dev)
/* Queue packet for network layer */
netif_rx(skb);
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += rcvLen;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += rcvLen;
/* Got the packet, tell the adapter to skip it */
wait_WOC(iobase);
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
new file mode 100644
index 00000000000..44411eb4e91
--- /dev/null
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -0,0 +1,120 @@
+config HERMES
+ tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
+ depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
+ select WIRELESS_EXT
+ select FW_LOADER
+ select CRYPTO
+ select CRYPTO_MICHAEL_MIC
+ ---help---
+ A driver for 802.11b wireless cards based on the "Hermes" or
+ Intersil HFA384x (Prism 2) MAC controller. This includes the vast
+ majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
+ - except for the Cisco/Aironet cards. Cards supported include the
+ Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
+ Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
+ IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
+ MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
+ IPW2011, and Symbol Spectrum24 High Rate amongst others.
+
+ This option includes the guts of the driver, but in order to
+ actually use a card you will also need to enable support for PCMCIA
+ Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
+
+ You will also very likely also need the Wireless Tools in order to
+ configure your card and that /etc/pcmcia/wireless.opts works :
+ <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
+
+config HERMES_CACHE_FW_ON_INIT
+ bool "Cache Hermes firmware on driver initialisation"
+ depends on HERMES
+ default y
+ ---help---
+ Say Y to cache any firmware required by the Hermes drivers
+ on startup. The firmware will remain cached until the
+ driver is unloaded. The cache uses 64K of RAM.
+
+ Otherwise load the firmware from userspace as required. In
+ this case the driver should be unloaded and restarted
+ whenever the firmware is changed.
+
+ If you are not sure, say Y.
+
+config APPLE_AIRPORT
+ tristate "Apple Airport support (built-in)"
+ depends on PPC_PMAC && HERMES
+ help
+ Say Y here to support the Airport 802.11b wireless Ethernet hardware
+ built into the Macintosh iBook and other recent PowerPC-based
+ Macintosh machines. This is essentially a Lucent Orinoco card with
+ a non-standard interface.
+
+ This driver does not support the Airport Extreme (802.11b/g). Use
+ the BCM43xx driver for Airport Extreme cards.
+
+config PLX_HERMES
+ tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
+ depends on PCI && HERMES
+ help
+ Enable support for PCMCIA cards supported by the "Hermes" (aka
+ orinoco) driver when used in PLX9052 based PCI adaptors. These
+ adaptors are not a full PCMCIA controller but act as a more limited
+ PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
+ 802.11b PCMCIA cards can be used in desktop machines. The Netgear
+ MA301 is such an adaptor.
+
+config TMD_HERMES
+ tristate "Hermes in TMD7160 based PCI adaptor support"
+ depends on PCI && HERMES
+ help
+ Enable support for PCMCIA cards supported by the "Hermes" (aka
+ orinoco) driver when used in TMD7160 based PCI adaptors. These
+ adaptors are not a full PCMCIA controller but act as a more limited
+ PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
+ 802.11b PCMCIA cards can be used in desktop machines.
+
+config NORTEL_HERMES
+ tristate "Nortel emobility PCI adaptor support"
+ depends on PCI && HERMES
+ help
+ Enable support for PCMCIA cards supported by the "Hermes" (aka
+ orinoco) driver when used in Nortel emobility PCI adaptors. These
+ adaptors are not full PCMCIA controllers, but act as a more limited
+ PCI <-> PCMCIA bridge.
+
+config PCI_HERMES
+ tristate "Prism 2.5 PCI 802.11b adaptor support"
+ depends on PCI && HERMES
+ help
+ Enable support for PCI and mini-PCI 802.11b wireless NICs based on
+ the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
+ PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
+ common. Some of the built-in wireless adaptors in laptops are of
+ this variety.
+
+config PCMCIA_HERMES
+ tristate "Hermes PCMCIA card support"
+ depends on PCMCIA && HERMES
+ ---help---
+ A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
+ as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
+ EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and
+ others). It should also be usable on various Prism II based cards
+ such as the Linksys, D-Link and Farallon Skyline. It should also
+ work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN.
+
+ You will very likely need the Wireless Tools in order to
+ configure your card and that /etc/pcmcia/wireless.opts works:
+ <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+
+config PCMCIA_SPECTRUM
+ tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
+ depends on PCMCIA && HERMES
+ ---help---
+
+ This is a driver for 802.11b cards using RAM-loadable Symbol
+ firmware, such as Symbol Wireless Networker LA4100, CompactFlash
+ cards by Socket Communications and Intel PRO/Wireless 2011B.
+
+ This driver requires firmware download on startup. Utilities
+ for downloading Symbol firmware are available at
+ <http://sourceforge.net/projects/orinoco/>
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile
index 791366e08c5..1fc7409d669 100644
--- a/drivers/net/wireless/orinoco/Makefile
+++ b/drivers/net/wireless/orinoco/Makefile
@@ -1,8 +1,9 @@
#
# Makefile for the orinoco wireless device drivers.
#
+orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o
-obj-$(CONFIG_HERMES) += orinoco.o hermes.o hermes_dld.o
+obj-$(CONFIG_HERMES) += orinoco.o
obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o
obj-$(CONFIG_APPLE_AIRPORT) += airport.o
obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 28f1cae4843..8c4065f1b0d 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -3,10 +3,10 @@
* A driver for "Hermes" chipset based Apple Airport wireless
* card.
*
- * Copyright notice & release notes in file orinoco.c
- *
+ * Copyright notice & release notes in file main.c
+ *
* Note specific to airport stub:
- *
+ *
* 0.05 : first version of the new split driver
* 0.06 : fix possible hang on powerup, add sleep support
*/
@@ -60,7 +60,8 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
orinoco_unlock(priv, &flags);
disable_irq(dev->irq);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(mdev), 0, 0);
return 0;
}
@@ -75,7 +76,8 @@ airport_resume(struct macio_dev *mdev)
printk(KERN_DEBUG "%s: Airport waking up\n", dev->name);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(mdev), 0, 1);
msleep(200);
enable_irq(dev->irq);
@@ -93,7 +95,7 @@ airport_resume(struct macio_dev *mdev)
priv->hw_unavailable--;
- if (priv->open && (! priv->hw_unavailable)) {
+ if (priv->open && (!priv->hw_unavailable)) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
@@ -127,7 +129,8 @@ airport_detach(struct macio_dev *mdev)
macio_release_resource(mdev, 0);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(mdev), 0, 0);
ssleep(1);
macio_set_drvdata(mdev, NULL);
@@ -153,9 +156,11 @@ static int airport_hard_reset(struct orinoco_private *priv)
* off. */
disable_irq(dev->irq);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 0);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(card->mdev), 0, 0);
ssleep(1);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 1);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(card->mdev), 0, 1);
ssleep(1);
enable_irq(dev->irq);
@@ -182,7 +187,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
/* Allocate space for private device-specific data */
dev = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
airport_hard_reset, NULL);
- if (! dev) {
+ if (!dev) {
printk(KERN_ERR PFX "Cannot allocate network device\n");
return -ENODEV;
}
@@ -214,9 +219,10 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
}
hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
-
+
/* Power up card */
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(mdev), 0, 1);
ssleep(1);
/* Reset it before we get the interrupt */
@@ -248,7 +254,7 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
MODULE_LICENSE("Dual MPL/GPL");
-static struct of_device_id airport_match[] =
+static struct of_device_id airport_match[] =
{
{
.name = "radio",
@@ -256,10 +262,9 @@ static struct of_device_id airport_match[] =
{},
};
-MODULE_DEVICE_TABLE (of, airport_match);
+MODULE_DEVICE_TABLE(of, airport_match);
-static struct macio_driver airport_driver =
-{
+static struct macio_driver airport_driver = {
.name = DRIVER_NAME,
.match_table = airport_match,
.probe = airport_attach,
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
new file mode 100644
index 00000000000..1084b43e04b
--- /dev/null
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -0,0 +1,390 @@
+/* Firmware file reading and download helpers
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+
+#include "hermes.h"
+#include "hermes_dld.h"
+#include "orinoco.h"
+
+#include "fw.h"
+
+/* End markers (for Symbol firmware only) */
+#define TEXT_END 0x1A /* End of text header */
+
+struct fw_info {
+ char *pri_fw;
+ char *sta_fw;
+ char *ap_fw;
+ u32 pda_addr;
+ u16 pda_size;
+};
+
+static const struct fw_info orinoco_fw[] = {
+ { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
+ { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
+ { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 }
+};
+
+/* Structure used to access fields in FW
+ * Make sure LE decoding macros are used
+ */
+struct orinoco_fw_header {
+ char hdr_vers[6]; /* ASCII string for header version */
+ __le16 headersize; /* Total length of header */
+ __le32 entry_point; /* NIC entry point */
+ __le32 blocks; /* Number of blocks to program */
+ __le32 block_offset; /* Offset of block data from eof header */
+ __le32 pdr_offset; /* Offset to PDR data from eof header */
+ __le32 pri_offset; /* Offset to primary plug data */
+ __le32 compat_offset; /* Offset to compatibility data*/
+ char signature[0]; /* FW signature length headersize-20 */
+} __attribute__ ((packed));
+
+/* Check the range of various header entries. Return a pointer to a
+ * description of the problem, or NULL if everything checks out. */
+static const char *validate_fw(const struct orinoco_fw_header *hdr, size_t len)
+{
+ u16 hdrsize;
+
+ if (len < sizeof(*hdr))
+ return "image too small";
+ if (memcmp(hdr->hdr_vers, "HFW", 3) != 0)
+ return "format not recognised";
+
+ hdrsize = le16_to_cpu(hdr->headersize);
+ if (hdrsize > len)
+ return "bad headersize";
+ if ((hdrsize + le32_to_cpu(hdr->block_offset)) > len)
+ return "bad block offset";
+ if ((hdrsize + le32_to_cpu(hdr->pdr_offset)) > len)
+ return "bad PDR offset";
+ if ((hdrsize + le32_to_cpu(hdr->pri_offset)) > len)
+ return "bad PRI offset";
+ if ((hdrsize + le32_to_cpu(hdr->compat_offset)) > len)
+ return "bad compat offset";
+
+ /* TODO: consider adding a checksum or CRC to the firmware format */
+ return NULL;
+}
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+static inline const struct firmware *
+orinoco_cached_fw_get(struct orinoco_private *priv, bool primary)
+{
+ if (primary)
+ return priv->cached_pri_fw;
+ else
+ return priv->cached_fw;
+}
+#else
+#define orinoco_cached_fw_get(priv, primary) (NULL)
+#endif
+
+/* Download either STA or AP firmware into the card. */
+static int
+orinoco_dl_firmware(struct orinoco_private *priv,
+ const struct fw_info *fw,
+ int ap)
+{
+ /* Plug Data Area (PDA) */
+ __le16 *pda;
+
+ hermes_t *hw = &priv->hw;
+ const struct firmware *fw_entry;
+ const struct orinoco_fw_header *hdr;
+ const unsigned char *first_block;
+ const void *end;
+ const char *firmware;
+ const char *fw_err;
+ struct net_device *dev = priv->ndev;
+ int err = 0;
+
+ pda = kzalloc(fw->pda_size, GFP_KERNEL);
+ if (!pda)
+ return -ENOMEM;
+
+ if (ap)
+ firmware = fw->ap_fw;
+ else
+ firmware = fw->sta_fw;
+
+ printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
+ dev->name, firmware);
+
+ /* Read current plug data */
+ err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
+ printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
+ if (err)
+ goto free;
+
+ if (!orinoco_cached_fw_get(priv, false)) {
+ err = request_firmware(&fw_entry, firmware, priv->dev);
+
+ if (err) {
+ printk(KERN_ERR "%s: Cannot find firmware %s\n",
+ dev->name, firmware);
+ err = -ENOENT;
+ goto free;
+ }
+ } else
+ fw_entry = orinoco_cached_fw_get(priv, false);
+
+ hdr = (const struct orinoco_fw_header *) fw_entry->data;
+
+ fw_err = validate_fw(hdr, fw_entry->size);
+ if (fw_err) {
+ printk(KERN_WARNING "%s: Invalid firmware image detected (%s). "
+ "Aborting download\n",
+ dev->name, fw_err);
+ err = -EINVAL;
+ goto abort;
+ }
+
+ /* Enable aux port to allow programming */
+ err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
+ printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
+ if (err != 0)
+ goto abort;
+
+ /* Program data */
+ first_block = (fw_entry->data +
+ le16_to_cpu(hdr->headersize) +
+ le32_to_cpu(hdr->block_offset));
+ end = fw_entry->data + fw_entry->size;
+
+ err = hermes_program(hw, first_block, end);
+ printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
+ if (err != 0)
+ goto abort;
+
+ /* Update production data */
+ first_block = (fw_entry->data +
+ le16_to_cpu(hdr->headersize) +
+ le32_to_cpu(hdr->pdr_offset));
+
+ err = hermes_apply_pda_with_defaults(hw, first_block, end, pda,
+ &pda[fw->pda_size / sizeof(*pda)]);
+ printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
+ if (err)
+ goto abort;
+
+ /* Tell card we've finished */
+ err = hermesi_program_end(hw);
+ printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
+ if (err != 0)
+ goto abort;
+
+ /* Check if we're running */
+ printk(KERN_DEBUG "%s: hermes_present returned %d\n",
+ dev->name, hermes_present(hw));
+
+abort:
+ /* If we requested the firmware, release it. */
+ if (!orinoco_cached_fw_get(priv, false))
+ release_firmware(fw_entry);
+
+free:
+ kfree(pda);
+ return err;
+}
+
+/*
+ * Process a firmware image - stop the card, load the firmware, reset
+ * the card and make sure it responds. For the secondary firmware take
+ * care of the PDA - read it and then write it on top of the firmware.
+ */
+static int
+symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
+ const unsigned char *image, const void *end,
+ int secondary)
+{
+ hermes_t *hw = &priv->hw;
+ int ret = 0;
+ const unsigned char *ptr;
+ const unsigned char *first_block;
+
+ /* Plug Data Area (PDA) */
+ __le16 *pda = NULL;
+
+ /* Binary block begins after the 0x1A marker */
+ ptr = image;
+ while (*ptr++ != TEXT_END);
+ first_block = ptr;
+
+ /* Read the PDA from EEPROM */
+ if (secondary) {
+ pda = kzalloc(fw->pda_size, GFP_KERNEL);
+ if (!pda)
+ return -ENOMEM;
+
+ ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
+ if (ret)
+ goto free;
+ }
+
+ /* Stop the firmware, so that it can be safely rewritten */
+ if (priv->stop_fw) {
+ ret = priv->stop_fw(priv, 1);
+ if (ret)
+ goto free;
+ }
+
+ /* Program the adapter with new firmware */
+ ret = hermes_program(hw, first_block, end);
+ if (ret)
+ goto free;
+
+ /* Write the PDA to the adapter */
+ if (secondary) {
+ size_t len = hermes_blocks_length(first_block, end);
+ ptr = first_block + len;
+ ret = hermes_apply_pda(hw, ptr, end, pda,
+ &pda[fw->pda_size / sizeof(*pda)]);
+ kfree(pda);
+ if (ret)
+ return ret;
+ }
+
+ /* Run the firmware */
+ if (priv->stop_fw) {
+ ret = priv->stop_fw(priv, 0);
+ if (ret)
+ return ret;
+ }
+
+ /* Reset hermes chip and make sure it responds */
+ ret = hermes_init(hw);
+
+ /* hermes_reset() should return 0 with the secondary firmware */
+ if (secondary && ret != 0)
+ return -ENODEV;
+
+ /* And this should work with any firmware */
+ if (!hermes_present(hw))
+ return -ENODEV;
+
+ return 0;
+
+free:
+ kfree(pda);
+ return ret;
+}
+
+
+/*
+ * Download the firmware into the card, this also does a PCMCIA soft
+ * reset on the card, to make sure it's in a sane state.
+ */
+static int
+symbol_dl_firmware(struct orinoco_private *priv,
+ const struct fw_info *fw)
+{
+ struct net_device *dev = priv->ndev;
+ int ret;
+ const struct firmware *fw_entry;
+
+ if (!orinoco_cached_fw_get(priv, true)) {
+ if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
+ printk(KERN_ERR "%s: Cannot find firmware: %s\n",
+ dev->name, fw->pri_fw);
+ return -ENOENT;
+ }
+ } else
+ fw_entry = orinoco_cached_fw_get(priv, true);
+
+ /* Load primary firmware */
+ ret = symbol_dl_image(priv, fw, fw_entry->data,
+ fw_entry->data + fw_entry->size, 0);
+
+ if (!orinoco_cached_fw_get(priv, true))
+ release_firmware(fw_entry);
+ if (ret) {
+ printk(KERN_ERR "%s: Primary firmware download failed\n",
+ dev->name);
+ return ret;
+ }
+
+ if (!orinoco_cached_fw_get(priv, false)) {
+ if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
+ printk(KERN_ERR "%s: Cannot find firmware: %s\n",
+ dev->name, fw->sta_fw);
+ return -ENOENT;
+ }
+ } else
+ fw_entry = orinoco_cached_fw_get(priv, false);
+
+ /* Load secondary firmware */
+ ret = symbol_dl_image(priv, fw, fw_entry->data,
+ fw_entry->data + fw_entry->size, 1);
+ if (!orinoco_cached_fw_get(priv, false))
+ release_firmware(fw_entry);
+ if (ret) {
+ printk(KERN_ERR "%s: Secondary firmware download failed\n",
+ dev->name);
+ }
+
+ return ret;
+}
+
+int orinoco_download(struct orinoco_private *priv)
+{
+ int err = 0;
+ /* Reload firmware */
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ /* case FIRMWARE_TYPE_INTERSIL: */
+ err = orinoco_dl_firmware(priv,
+ &orinoco_fw[priv->firmware_type], 0);
+ break;
+
+ case FIRMWARE_TYPE_SYMBOL:
+ err = symbol_dl_firmware(priv,
+ &orinoco_fw[priv->firmware_type]);
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ break;
+ }
+ /* TODO: if we fail we probably need to reinitialise
+ * the driver */
+
+ return err;
+}
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+void orinoco_cache_fw(struct orinoco_private *priv, int ap)
+{
+ const struct firmware *fw_entry = NULL;
+ const char *pri_fw;
+ const char *fw;
+
+ pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
+ if (ap)
+ fw = orinoco_fw[priv->firmware_type].ap_fw;
+ else
+ fw = orinoco_fw[priv->firmware_type].sta_fw;
+
+ if (pri_fw) {
+ if (request_firmware(&fw_entry, pri_fw, priv->dev) == 0)
+ priv->cached_pri_fw = fw_entry;
+ }
+
+ if (fw) {
+ if (request_firmware(&fw_entry, fw, priv->dev) == 0)
+ priv->cached_fw = fw_entry;
+ }
+}
+
+void orinoco_uncache_fw(struct orinoco_private *priv)
+{
+ if (priv->cached_pri_fw)
+ release_firmware(priv->cached_pri_fw);
+ if (priv->cached_fw)
+ release_firmware(priv->cached_fw);
+
+ priv->cached_pri_fw = NULL;
+ priv->cached_fw = NULL;
+}
+#endif
diff --git a/drivers/net/wireless/orinoco/fw.h b/drivers/net/wireless/orinoco/fw.h
new file mode 100644
index 00000000000..89fc26d25b0
--- /dev/null
+++ b/drivers/net/wireless/orinoco/fw.h
@@ -0,0 +1,21 @@
+/* Firmware file reading and download helpers
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_FW_H_
+#define _ORINOCO_FW_H_
+
+/* Forward declations */
+struct orinoco_private;
+
+int orinoco_download(struct orinoco_private *priv);
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+void orinoco_cache_fw(struct orinoco_private *priv, int ap);
+void orinoco_uncache_fw(struct orinoco_private *priv);
+#else
+#define orinoco_cache_fw(priv, ap) do { } while(0)
+#define orinoco_uncache_fw(priv) do { } while (0)
+#endif
+
+#endif /* _ORINOCO_FW_H_ */
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c
index bfa375369df..f2c918c2572 100644
--- a/drivers/net/wireless/orinoco/hermes.c
+++ b/drivers/net/wireless/orinoco/hermes.c
@@ -15,7 +15,7 @@
*
* Copyright (C) 2000, David Gibson, Linuxcare Australia.
* (C) Copyright David Gibson, IBM Corp. 2001-2003.
- *
+ *
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License
@@ -45,11 +45,6 @@
#include "hermes.h"
-MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"
- " & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_LICENSE("Dual MPL/GPL");
-
/* These are maximum timeouts. Most often, card wil react much faster */
#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
#define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
@@ -61,13 +56,13 @@ MODULE_LICENSE("Dual MPL/GPL");
*/
#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
- printk(stuff);} while (0)
+ printk(stuff); } while (0)
#undef HERMES_DEBUG
#ifdef HERMES_DEBUG
#include <stdarg.h>
-#define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff)
+#define DEBUG(lvl, stuff...) if ((lvl) <= HERMES_DEBUG) DMSG(stuff)
#else /* ! HERMES_DEBUG */
@@ -95,20 +90,19 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
/* First wait for the command register to unbusy */
reg = hermes_read_regn(hw, CMD);
- while ( (reg & HERMES_CMD_BUSY) && k ) {
+ while ((reg & HERMES_CMD_BUSY) && k) {
k--;
udelay(1);
reg = hermes_read_regn(hw, CMD);
}
- if (reg & HERMES_CMD_BUSY) {
+ if (reg & HERMES_CMD_BUSY)
return -EBUSY;
- }
hermes_write_regn(hw, PARAM2, param2);
hermes_write_regn(hw, PARAM1, param1);
hermes_write_regn(hw, PARAM0, param0);
hermes_write_regn(hw, CMD, cmd);
-
+
return 0;
}
@@ -191,23 +185,23 @@ int hermes_init(hermes_t *hw)
hermes_write_regn(hw, EVACK, 0xffff);
/* Normally it's a "can't happen" for the command register to
- be busy when we go to issue a command because we are
- serializing all commands. However we want to have some
- chance of resetting the card even if it gets into a stupid
- state, so we actually wait to see if the command register
- will unbusy itself here. */
+ be busy when we go to issue a command because we are
+ serializing all commands. However we want to have some
+ chance of resetting the card even if it gets into a stupid
+ state, so we actually wait to see if the command register
+ will unbusy itself here. */
k = CMD_BUSY_TIMEOUT;
reg = hermes_read_regn(hw, CMD);
while (k && (reg & HERMES_CMD_BUSY)) {
- if (reg == 0xffff) /* Special case - the card has probably been removed,
- so don't wait for the timeout */
+ if (reg == 0xffff) /* Special case - the card has probably been
+ removed, so don't wait for the timeout */
return -ENODEV;
k--;
udelay(1);
reg = hermes_read_regn(hw, CMD);
}
-
+
/* No need to explicitly handle the timeout - if we've timed
out hermes_issue_cmd() will probably return -EBUSY below */
@@ -228,7 +222,10 @@ EXPORT_SYMBOL(hermes_init);
/* Issue a command to the chip, and (busy!) wait for it to
* complete.
*
- * Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
+ * Returns:
+ * < 0 on internal error
+ * 0 on success
+ * > 0 on error returned by the firmware
*
* Callable from any context, but locking is your problem. */
int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
@@ -241,13 +238,13 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
err = hermes_issue_cmd(hw, cmd, parm0, 0, 0);
if (err) {
- if (! hermes_present(hw)) {
+ if (!hermes_present(hw)) {
if (net_ratelimit())
printk(KERN_WARNING "hermes @ %p: "
"Card removed while issuing command "
"0x%04x.\n", hw->iobase, cmd);
err = -ENODEV;
- } else
+ } else
if (net_ratelimit())
printk(KERN_ERR "hermes @ %p: "
"Error %d issuing command 0x%04x.\n",
@@ -257,21 +254,21 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
reg = hermes_read_regn(hw, EVSTAT);
k = CMD_COMPL_TIMEOUT;
- while ( (! (reg & HERMES_EV_CMD)) && k) {
+ while ((!(reg & HERMES_EV_CMD)) && k) {
k--;
udelay(10);
reg = hermes_read_regn(hw, EVSTAT);
}
- if (! hermes_present(hw)) {
+ if (!hermes_present(hw)) {
printk(KERN_WARNING "hermes @ %p: Card removed "
"while waiting for command 0x%04x completion.\n",
hw->iobase, cmd);
err = -ENODEV;
goto out;
}
-
- if (! (reg & HERMES_EV_CMD)) {
+
+ if (!(reg & HERMES_EV_CMD)) {
printk(KERN_ERR "hermes @ %p: Timeout waiting for "
"command 0x%04x completion.\n", hw->iobase, cmd);
err = -ETIMEDOUT;
@@ -301,31 +298,30 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
int err = 0;
int k;
u16 reg;
-
- if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
+
+ if ((size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX))
return -EINVAL;
err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
- if (err) {
+ if (err)
return err;
- }
reg = hermes_read_regn(hw, EVSTAT);
k = ALLOC_COMPL_TIMEOUT;
- while ( (! (reg & HERMES_EV_ALLOC)) && k) {
+ while ((!(reg & HERMES_EV_ALLOC)) && k) {
k--;
udelay(10);
reg = hermes_read_regn(hw, EVSTAT);
}
-
- if (! hermes_present(hw)) {
+
+ if (!hermes_present(hw)) {
printk(KERN_WARNING "hermes @ %p: "
"Card removed waiting for frame allocation.\n",
hw->iobase);
return -ENODEV;
}
-
- if (! (reg & HERMES_EV_ALLOC)) {
+
+ if (!(reg & HERMES_EV_ALLOC)) {
printk(KERN_ERR "hermes @ %p: "
"Timeout waiting for frame allocation\n",
hw->iobase);
@@ -334,14 +330,17 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
*fid = hermes_read_regn(hw, ALLOCFID);
hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC);
-
+
return 0;
}
EXPORT_SYMBOL(hermes_allocate);
/* Set up a BAP to read a particular chunk of data from card's internal buffer.
*
- * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
+ * Returns:
+ * < 0 on internal failure (errno)
+ * 0 on success
+ * > 0 on error
* from firmware
*
* Callable from any context */
@@ -353,7 +352,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
u16 reg;
/* Paranoia.. */
- if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
+ if ((offset > HERMES_BAP_OFFSET_MAX) || (offset % 2))
return -EINVAL;
k = HERMES_BAP_BUSY_TIMEOUT;
@@ -374,7 +373,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
/* Wait for the BAP to be ready */
k = HERMES_BAP_BUSY_TIMEOUT;
reg = hermes_read_reg(hw, oreg);
- while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
+ while ((reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
k--;
udelay(1);
reg = hermes_read_reg(hw, oreg);
@@ -386,9 +385,8 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
(reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
reg, id, offset);
- if (reg & HERMES_OFFSET_BUSY) {
+ if (reg & HERMES_OFFSET_BUSY)
return -ETIMEDOUT;
- }
return -EIO; /* error or wrong offset */
}
@@ -400,7 +398,10 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
* BAP. Synchronization/serialization is the caller's problem. len
* must be even.
*
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ * Returns:
+ * < 0 on internal failure (errno)
+ * 0 on success
+ * > 0 on error from firmware
*/
int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
u16 id, u16 offset)
@@ -408,7 +409,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
int err = 0;
- if ( (len < 0) || (len % 2) )
+ if ((len < 0) || (len % 2))
return -EINVAL;
err = hermes_bap_seek(hw, bap, id, offset);
@@ -426,7 +427,10 @@ EXPORT_SYMBOL(hermes_bap_pread);
/* Write a block of data to the chip's buffer, via the
* BAP. Synchronization/serialization is the caller's problem.
*
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ * Returns:
+ * < 0 on internal failure (errno)
+ * 0 on success
+ * > 0 on error from firmware
*/
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
u16 id, u16 offset)
@@ -440,11 +444,11 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
err = hermes_bap_seek(hw, bap, id, offset);
if (err)
goto out;
-
+
/* Actually do the transfer */
hermes_write_bytes(hw, dreg, buf, len);
- out:
+ out:
return err;
}
EXPORT_SYMBOL(hermes_bap_pwrite);
@@ -465,7 +469,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
u16 rlength, rtype;
unsigned nwords;
- if ( (bufsize < 0) || (bufsize % 2) )
+ if ((bufsize < 0) || (bufsize % 2))
return -EINVAL;
err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
@@ -478,7 +482,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
rlength = hermes_read_reg(hw, dreg);
- if (! rlength)
+ if (!rlength)
return -ENODATA;
rtype = hermes_read_reg(hw, dreg);
@@ -503,7 +507,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
}
EXPORT_SYMBOL(hermes_read_ltv);
-int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
+int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
u16 length, const void *value)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -530,15 +534,3 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
return err;
}
EXPORT_SYMBOL(hermes_write_ltv);
-
-static int __init init_hermes(void)
-{
- return 0;
-}
-
-static void __exit exit_hermes(void)
-{
-}
-
-module_init(init_hermes);
-module_exit(exit_hermes);
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h
index 8b13c8fef3d..c78c442a02c 100644
--- a/drivers/net/wireless/orinoco/hermes.h
+++ b/drivers/net/wireless/orinoco/hermes.h
@@ -15,7 +15,8 @@
* Copyright (C) 2000, David Gibson, Linuxcare Australia.
* (C) Copyright David Gibson, IBM Corp. 2001-2003.
*
- * Portions taken from hfa384x.h, Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+ * Portions taken from hfa384x.h.
+ * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
*
* This file distributed under the GPL, version 2.
*/
@@ -31,7 +32,7 @@
*/
#include <linux/if_ether.h>
-#include <asm/io.h>
+#include <linux/io.h>
/*
* Limits and constants
@@ -203,7 +204,7 @@ struct hermes_tx_descriptor {
__le32 sw_support;
u8 retry_count;
u8 tx_rate;
- __le16 tx_control;
+ __le16 tx_control;
} __attribute__ ((packed));
#define HERMES_TXSTAT_RETRYERR (0x0001)
@@ -298,7 +299,7 @@ struct symbol_scan_apinfo {
/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
__le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
- __le16 rates[5]; /* Bit rate supported */
+ __le16 rates[5]; /* Bit rate supported */
__le16 basic_rates; /* Basic rates bitmask */
u8 unknown2[6]; /* Always FF:FF:FF:FF:00:00 */
u8 unknown3[8]; /* Always 0, appeared in f/w 3.91-68 */
@@ -344,14 +345,14 @@ struct agere_ext_scan_info {
u8 data[316];
} __attribute__ ((packed));
-#define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000)
+#define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000)
#define HERMES_LINKSTATUS_CONNECTED (0x0001)
#define HERMES_LINKSTATUS_DISCONNECTED (0x0002)
#define HERMES_LINKSTATUS_AP_CHANGE (0x0003)
#define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
#define HERMES_LINKSTATUS_AP_IN_RANGE (0x0005)
#define HERMES_LINKSTATUS_ASSOC_FAILED (0x0006)
-
+
struct hermes_linkstatus {
__le16 linkstatus; /* Link status */
} __attribute__ ((packed));
@@ -384,11 +385,12 @@ typedef struct hermes {
/* Register access convenience macros */
#define hermes_read_reg(hw, off) \
- (ioread16((hw)->iobase + ( (off) << (hw)->reg_spacing )))
+ (ioread16((hw)->iobase + ((off) << (hw)->reg_spacing)))
#define hermes_write_reg(hw, off, val) \
(iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
#define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
-#define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val))
+#define hermes_write_regn(hw, name, val) \
+ hermes_write_reg((hw), HERMES_##name, (val))
/* Function prototypes */
void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
@@ -430,7 +432,7 @@ static inline int hermes_enable_port(hermes_t *hw, int port)
static inline int hermes_disable_port(hermes_t *hw, int port)
{
- return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
+ return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
0, NULL);
}
@@ -441,11 +443,12 @@ static inline int hermes_inquire(hermes_t *hw, u16 rid)
return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
}
-#define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
-#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
+#define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1)
+#define HERMES_RECLEN_TO_BYTES(n) (((n)-1) * 2)
/* Note that for the next two, the count is in 16-bit words, not bytes */
-static inline void hermes_read_words(struct hermes *hw, int off, void *buf, unsigned count)
+static inline void hermes_read_words(struct hermes *hw, int off,
+ void *buf, unsigned count)
{
off = off << hw->reg_spacing;
ioread16_rep(hw->iobase + off, buf, count);
@@ -460,7 +463,8 @@ static inline void hermes_write_bytes(struct hermes *hw, int off,
iowrite8(buf[count - 1], hw->iobase + off);
}
-static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
+static inline void hermes_clear_words(struct hermes *hw, int off,
+ unsigned count)
{
unsigned i;
@@ -471,9 +475,10 @@ static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count
}
#define HERMES_READ_RECORD(hw, bap, rid, buf) \
- (hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
+ (hermes_read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
- (hermes_write_ltv((hw),(bap),(rid),HERMES_BYTES_TO_RECLEN(sizeof(*buf)),(buf)))
+ (hermes_write_ltv((hw), (bap), (rid), \
+ HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf)))
static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
{
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index d8c626e61a3..a9ba195cdad 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -1,13 +1,7 @@
/*
- * Hermes download helper driver.
+ * Hermes download helper.
*
- * This could be entirely merged into hermes.c.
- *
- * I'm keeping it separate to minimise the amount of merging between
- * kernel upgrades. It also means the memory overhead for drivers that
- * don't need firmware download low.
- *
- * This driver:
+ * This helper:
* - is capable of writing to the volatile area of the hermes device
* - is currently not capable of writing to non-volatile areas
* - provide helpers to identify and update plugin data
@@ -50,10 +44,6 @@
#include "hermes.h"
#include "hermes_dld.h"
-MODULE_DESCRIPTION("Download helper for Lucent Hermes chipset");
-MODULE_AUTHOR("David Kilroy <kilroyd@gmail.com>");
-MODULE_LICENSE("Dual MPL/GPL");
-
#define PFX "hermes_dld: "
/*
@@ -81,18 +71,6 @@ MODULE_LICENSE("Dual MPL/GPL");
#define BLOCK_END 0xFFFFFFFF /* Last image block */
#define TEXT_END 0x1A /* End of text header */
-/*
- * PDA == Production Data Area
- *
- * In principle, the max. size of the PDA is is 4096 words. Currently,
- * however, only about 500 bytes of this area are used.
- *
- * Some USB implementations can't handle sizes in excess of 1016. Note
- * that PDA is not actually used in those USB environments, but may be
- * retrieved by common code.
- */
-#define MAX_PDA_SIZE 1000
-
/* Limit the amout we try to download in a single shot.
* Size is in bytes.
*/
@@ -228,13 +206,14 @@ hermes_aux_control(hermes_t *hw, int enabled)
* Scan PDR for the record with the specified RECORD_ID.
* If it's not found, return NULL.
*/
-static struct pdr *
-hermes_find_pdr(struct pdr *first_pdr, u32 record_id)
+static const struct pdr *
+hermes_find_pdr(const struct pdr *first_pdr, u32 record_id, const void *end)
{
- struct pdr *pdr = first_pdr;
- void *end = (void *)first_pdr + MAX_PDA_SIZE;
+ const struct pdr *pdr = first_pdr;
+
+ end -= sizeof(struct pdr);
- while (((void *)pdr < end) &&
+ while (((void *) pdr <= end) &&
(pdr_id(pdr) != PDI_END)) {
/*
* PDR area is currently not terminated by PDI_END.
@@ -254,12 +233,15 @@ hermes_find_pdr(struct pdr *first_pdr, u32 record_id)
}
/* Scan production data items for a particular entry */
-static struct pdi *
-hermes_find_pdi(struct pdi *first_pdi, u32 record_id)
+static const struct pdi *
+hermes_find_pdi(const struct pdi *first_pdi, u32 record_id, const void *end)
{
- struct pdi *pdi = first_pdi;
+ const struct pdi *pdi = first_pdi;
- while (pdi_id(pdi) != PDI_END) {
+ end -= sizeof(struct pdi);
+
+ while (((void *) pdi <= end) &&
+ (pdi_id(pdi) != PDI_END)) {
/* If the record ID matches, we are done */
if (pdi_id(pdi) == record_id)
@@ -272,12 +254,13 @@ hermes_find_pdi(struct pdi *first_pdi, u32 record_id)
/* Process one Plug Data Item - find corresponding PDR and plug it */
static int
-hermes_plug_pdi(hermes_t *hw, struct pdr *first_pdr, const struct pdi *pdi)
+hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr,
+ const struct pdi *pdi, const void *pdr_end)
{
- struct pdr *pdr;
+ const struct pdr *pdr;
/* Find the PDR corresponding to this PDI */
- pdr = hermes_find_pdr(first_pdr, pdi_id(pdi));
+ pdr = hermes_find_pdr(first_pdr, pdi_id(pdi), pdr_end);
/* No match is found, safe to ignore */
if (!pdr)
@@ -347,7 +330,6 @@ int hermes_read_pda(hermes_t *hw,
return 0;
}
-EXPORT_SYMBOL(hermes_read_pda);
/* Parse PDA and write the records into the adapter
*
@@ -356,18 +338,22 @@ EXPORT_SYMBOL(hermes_read_pda);
*/
int hermes_apply_pda(hermes_t *hw,
const char *first_pdr,
- const __le16 *pda)
+ const void *pdr_end,
+ const __le16 *pda,
+ const void *pda_end)
{
int ret;
const struct pdi *pdi;
- struct pdr *pdr;
+ const struct pdr *pdr;
- pdr = (struct pdr *) first_pdr;
+ pdr = (const struct pdr *) first_pdr;
+ pda_end -= sizeof(struct pdi);
/* Go through every PDI and plug them into the adapter */
pdi = (const struct pdi *) (pda + 2);
- while (pdi_id(pdi) != PDI_END) {
- ret = hermes_plug_pdi(hw, pdr, pdi);
+ while (((void *) pdi <= pda_end) &&
+ (pdi_id(pdi) != PDI_END)) {
+ ret = hermes_plug_pdi(hw, pdr, pdi, pdr_end);
if (ret)
return ret;
@@ -376,21 +362,23 @@ int hermes_apply_pda(hermes_t *hw,
}
return 0;
}
-EXPORT_SYMBOL(hermes_apply_pda);
/* Identify the total number of bytes in all blocks
* including the header data.
*/
size_t
-hermes_blocks_length(const char *first_block)
+hermes_blocks_length(const char *first_block, const void *end)
{
const struct dblock *blk = (const struct dblock *) first_block;
int total_len = 0;
int len;
+ end -= sizeof(*blk);
+
/* Skip all blocks to locate Plug Data References
* (Spectrum CS) */
- while (dblock_addr(blk) != BLOCK_END) {
+ while (((void *) blk <= end) &&
+ (dblock_addr(blk) != BLOCK_END)) {
len = dblock_len(blk);
total_len += sizeof(*blk) + len;
blk = (struct dblock *) &blk->data[len];
@@ -398,7 +386,6 @@ hermes_blocks_length(const char *first_block)
return total_len;
}
-EXPORT_SYMBOL(hermes_blocks_length);
/*** Hermes programming ***/
@@ -452,7 +439,6 @@ int hermesi_program_init(hermes_t *hw, u32 offset)
return err;
}
-EXPORT_SYMBOL(hermesi_program_init);
/* Done programming data (Hermes I)
*
@@ -488,10 +474,9 @@ int hermesi_program_end(hermes_t *hw)
return rc ? rc : err;
}
-EXPORT_SYMBOL(hermesi_program_end);
/* Program the data blocks */
-int hermes_program(hermes_t *hw, const char *first_block, const char *end)
+int hermes_program(hermes_t *hw, const char *first_block, const void *end)
{
const struct dblock *blk;
u32 blkaddr;
@@ -503,14 +488,14 @@ int hermes_program(hermes_t *hw, const char *first_block, const char *end)
blk = (const struct dblock *) first_block;
- if ((const char *) blk > (end - sizeof(*blk)))
+ if ((void *) blk > (end - sizeof(*blk)))
return -EIO;
blkaddr = dblock_addr(blk);
blklen = dblock_len(blk);
while ((blkaddr != BLOCK_END) &&
- (((const char *) blk + blklen) <= end)) {
+ (((void *) blk + blklen) <= end)) {
printk(KERN_DEBUG PFX
"Programming block of length %d to address 0x%08x\n",
blklen, blkaddr);
@@ -542,7 +527,7 @@ int hermes_program(hermes_t *hw, const char *first_block, const char *end)
#endif
blk = (const struct dblock *) &blk->data[blklen];
- if ((const char *) blk > (end - sizeof(*blk)))
+ if ((void *) blk > (end - sizeof(*blk)))
return -EIO;
blkaddr = dblock_addr(blk);
@@ -550,19 +535,6 @@ int hermes_program(hermes_t *hw, const char *first_block, const char *end)
}
return 0;
}
-EXPORT_SYMBOL(hermes_program);
-
-static int __init init_hermes_dld(void)
-{
- return 0;
-}
-
-static void __exit exit_hermes_dld(void)
-{
-}
-
-module_init(init_hermes_dld);
-module_exit(exit_hermes_dld);
/*** Default plugging data for Hermes I ***/
/* Values from wl_lkm_718/hcf/dhf.c */
@@ -573,9 +545,9 @@ static const struct { \
__le16 id; \
u8 val[length]; \
} __attribute__ ((packed)) default_pdr_data_##pid = { \
- __constant_cpu_to_le16((sizeof(default_pdr_data_##pid)/ \
+ cpu_to_le16((sizeof(default_pdr_data_##pid)/ \
sizeof(__le16)) - 1), \
- __constant_cpu_to_le16(pid), \
+ cpu_to_le16(pid), \
data \
}
@@ -644,17 +616,20 @@ DEFINE_DEFAULT_PDR(0x0161, 256,
*/
int hermes_apply_pda_with_defaults(hermes_t *hw,
const char *first_pdr,
- const __le16 *pda)
+ const void *pdr_end,
+ const __le16 *pda,
+ const void *pda_end)
{
const struct pdr *pdr = (const struct pdr *) first_pdr;
- struct pdi *first_pdi = (struct pdi *) &pda[2];
- struct pdi *pdi;
- struct pdi *default_pdi = NULL;
- struct pdi *outdoor_pdi;
- void *end = (void *)first_pdr + MAX_PDA_SIZE;
+ const struct pdi *first_pdi = (const struct pdi *) &pda[2];
+ const struct pdi *pdi;
+ const struct pdi *default_pdi = NULL;
+ const struct pdi *outdoor_pdi;
int record_id;
- while (((void *)pdr < end) &&
+ pdr_end -= sizeof(struct pdr);
+
+ while (((void *) pdr <= pdr_end) &&
(pdr_id(pdr) != PDI_END)) {
/*
* For spectrum_cs firmwares,
@@ -666,7 +641,7 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
break;
record_id = pdr_id(pdr);
- pdi = hermes_find_pdi(first_pdi, record_id);
+ pdi = hermes_find_pdi(first_pdi, record_id, pda_end);
if (pdi)
printk(KERN_DEBUG PFX "Found record 0x%04x at %p\n",
record_id, pdi);
@@ -674,7 +649,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
switch (record_id) {
case 0x110: /* Modem REFDAC values */
case 0x120: /* Modem VGDAC values */
- outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1);
+ outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1,
+ pda_end);
default_pdi = NULL;
if (outdoor_pdi) {
pdi = outdoor_pdi;
@@ -715,7 +691,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
if (pdi) {
/* Lengths of the data in PDI and PDR must match */
- if (pdi_len(pdi) == pdr_len(pdr)) {
+ if ((pdi_len(pdi) == pdr_len(pdr)) &&
+ ((void *) pdi->data + pdi_len(pdi) < pda_end)) {
/* do the actual plugging */
hermes_aux_setaddr(hw, pdr_addr(pdr));
hermes_write_bytes(hw, HERMES_AUXDATA,
@@ -727,4 +704,3 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
}
return 0;
}
-EXPORT_SYMBOL(hermes_apply_pda_with_defaults);
diff --git a/drivers/net/wireless/orinoco/hermes_dld.h b/drivers/net/wireless/orinoco/hermes_dld.h
index 6fcb2627799..583a5bcf917 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.h
+++ b/drivers/net/wireless/orinoco/hermes_dld.h
@@ -29,7 +29,7 @@
int hermesi_program_init(hermes_t *hw, u32 offset);
int hermesi_program_end(hermes_t *hw);
-int hermes_program(hermes_t *hw, const char *first_block, const char *end);
+int hermes_program(hermes_t *hw, const char *first_block, const void *end);
int hermes_read_pda(hermes_t *hw,
__le16 *pda,
@@ -38,11 +38,15 @@ int hermes_read_pda(hermes_t *hw,
int use_eeprom);
int hermes_apply_pda(hermes_t *hw,
const char *first_pdr,
- const __le16 *pda);
+ const void *pdr_end,
+ const __le16 *pda,
+ const void *pda_end);
int hermes_apply_pda_with_defaults(hermes_t *hw,
const char *first_pdr,
- const __le16 *pda);
+ const void *pdr_end,
+ const __le16 *pda,
+ const void *pda_end);
-size_t hermes_blocks_length(const char *first_block);
+size_t hermes_blocks_length(const char *first_block, const void *end);
#endif /* _HERMES_DLD_H */
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
new file mode 100644
index 00000000000..081428d9409
--- /dev/null
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -0,0 +1,586 @@
+/* Encapsulate basic setting changes and retrieval on Hermes hardware
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <linux/ieee80211.h>
+#include <linux/wireless.h>
+
+#include "hermes.h"
+#include "hermes_rid.h"
+#include "orinoco.h"
+
+#include "hw.h"
+
+/********************************************************************/
+/* Data tables */
+/********************************************************************/
+
+/* This tables gives the actual meanings of the bitrate IDs returned
+ * by the firmware. */
+static const struct {
+ int bitrate; /* in 100s of kilobits */
+ int automatic;
+ u16 agere_txratectrl;
+ u16 intersil_txratectrl;
+} bitrate_table[] = {
+ {110, 1, 3, 15}, /* Entry 0 is the default */
+ {10, 0, 1, 1},
+ {10, 1, 1, 1},
+ {20, 0, 2, 2},
+ {20, 1, 6, 3},
+ {55, 0, 4, 4},
+ {55, 1, 7, 7},
+ {110, 0, 5, 8},
+};
+#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
+
+int orinoco_get_bitratemode(int bitrate, int automatic)
+{
+ int ratemode = -1;
+ int i;
+
+ if ((bitrate != 10) && (bitrate != 20) &&
+ (bitrate != 55) && (bitrate != 110))
+ return ratemode;
+
+ for (i = 0; i < BITRATE_TABLE_SIZE; i++) {
+ if ((bitrate_table[i].bitrate == bitrate) &&
+ (bitrate_table[i].automatic == automatic)) {
+ ratemode = i;
+ break;
+ }
+ }
+ return ratemode;
+}
+
+void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic)
+{
+ BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
+
+ *bitrate = bitrate_table[ratemode].bitrate * 100000;
+ *automatic = bitrate_table[ratemode].automatic;
+}
+
+/* Get tsc from the firmware */
+int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
+
+ if ((key < 0) || (key > 4))
+ return -EINVAL;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
+ sizeof(tsc_arr), NULL, &tsc_arr);
+ if (!err)
+ memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
+
+ return err;
+}
+
+int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int ratemode = priv->bitratemode;
+ int err = 0;
+
+ if (ratemode >= BITRATE_TABLE_SIZE) {
+ printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
+ priv->ndev->name, ratemode);
+ return -EINVAL;
+ }
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFTXRATECONTROL,
+ bitrate_table[ratemode].agere_txratectrl);
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ case FIRMWARE_TYPE_SYMBOL:
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFTXRATECONTROL,
+ bitrate_table[ratemode].intersil_txratectrl);
+ break;
+ default:
+ BUG();
+ }
+
+ return err;
+}
+
+int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
+{
+ hermes_t *hw = &priv->hw;
+ int i;
+ int err = 0;
+ u16 val;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CURRENTTXRATE, &val);
+ if (err)
+ return err;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
+ /* Note : in Lucent firmware, the return value of
+ * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
+ * and therefore is totally different from the
+ * encoding of HERMES_RID_CNFTXRATECONTROL.
+ * Don't forget that 6Mb/s is really 5.5Mb/s */
+ if (val == 6)
+ *bitrate = 5500000;
+ else
+ *bitrate = val * 1000000;
+ break;
+ case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
+ case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
+ for (i = 0; i < BITRATE_TABLE_SIZE; i++)
+ if (bitrate_table[i].intersil_txratectrl == val)
+ break;
+
+ if (i >= BITRATE_TABLE_SIZE)
+ printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
+ priv->ndev->name, val);
+
+ *bitrate = bitrate_table[i].bitrate * 100000;
+ break;
+ default:
+ BUG();
+ }
+
+ return err;
+}
+
+/* Set fixed AP address */
+int __orinoco_hw_set_wap(struct orinoco_private *priv)
+{
+ int roaming_flag;
+ int err = 0;
+ hermes_t *hw = &priv->hw;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ /* not supported */
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ if (priv->bssid_fixed)
+ roaming_flag = 2;
+ else
+ roaming_flag = 1;
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFROAMINGMODE,
+ roaming_flag);
+ break;
+ case FIRMWARE_TYPE_SYMBOL:
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
+ &priv->desired_bssid);
+ break;
+ }
+ return err;
+}
+
+/* Change the WEP keys and/or the current keys. Can be called
+ * either from __orinoco_hw_setup_enc() or directly from
+ * orinoco_ioctl_setiwencode(). In the later case the association
+ * with the AP is not broken (if the firmware can handle it),
+ * which is needed for 802.1x implementations. */
+int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFWEPKEYS_AGERE,
+ &priv->keys);
+ if (err)
+ return err;
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFTXKEY_AGERE,
+ priv->tx_key);
+ if (err)
+ return err;
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ case FIRMWARE_TYPE_SYMBOL:
+ {
+ int keylen;
+ int i;
+
+ /* Force uniform key length to work around
+ * firmware bugs */
+ keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
+
+ if (keylen > LARGE_KEY_SIZE) {
+ printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
+ priv->ndev->name, priv->tx_key, keylen);
+ return -E2BIG;
+ }
+
+ /* Write all 4 keys */
+ for (i = 0; i < ORINOCO_MAX_KEYS; i++) {
+ err = hermes_write_ltv(hw, USER_BAP,
+ HERMES_RID_CNFDEFAULTKEY0 + i,
+ HERMES_BYTES_TO_RECLEN(keylen),
+ priv->keys[i].data);
+ if (err)
+ return err;
+ }
+
+ /* Write the index of the key used in transmission */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFWEPDEFAULTKEYID,
+ priv->tx_key);
+ if (err)
+ return err;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+int __orinoco_hw_setup_enc(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ int master_wep_flag;
+ int auth_flag;
+ int enc_flag;
+
+ /* Setup WEP keys for WEP and WPA */
+ if (priv->encode_alg)
+ __orinoco_hw_setup_wepkeys(priv);
+
+ if (priv->wep_restrict)
+ auth_flag = HERMES_AUTH_SHARED_KEY;
+ else
+ auth_flag = HERMES_AUTH_OPEN;
+
+ if (priv->wpa_enabled)
+ enc_flag = 2;
+ else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
+ enc_flag = 1;
+ else
+ enc_flag = 0;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
+ if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+ /* Enable the shared-key authentication. */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFAUTHENTICATION_AGERE,
+ auth_flag);
+ }
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFWEPENABLED_AGERE,
+ enc_flag);
+ if (err)
+ return err;
+
+ if (priv->has_wpa) {
+ /* Set WPA key management */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
+ priv->key_mgmt);
+ if (err)
+ return err;
+ }
+
+ break;
+
+ case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
+ case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
+ if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+ if (priv->wep_restrict ||
+ (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
+ master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
+ HERMES_WEP_EXCL_UNENCRYPTED;
+ else
+ master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFAUTHENTICATION,
+ auth_flag);
+ if (err)
+ return err;
+ } else
+ master_wep_flag = 0;
+
+ if (priv->iw_mode == IW_MODE_MONITOR)
+ master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
+
+ /* Master WEP setting : on/off */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFWEPFLAGS_INTERSIL,
+ master_wep_flag);
+ if (err)
+ return err;
+
+ break;
+ }
+
+ return 0;
+}
+
+/* key must be 32 bytes, including the tx and rx MIC keys.
+ * rsc must be 8 bytes
+ * tsc must be 8 bytes or NULL
+ */
+int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
+ u8 *key, u8 *rsc, u8 *tsc)
+{
+ struct {
+ __le16 idx;
+ u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
+ u8 key[TKIP_KEYLEN];
+ u8 tx_mic[MIC_KEYLEN];
+ u8 rx_mic[MIC_KEYLEN];
+ u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
+ } __attribute__ ((packed)) buf;
+ int ret;
+ int err;
+ int k;
+ u16 xmitting;
+
+ key_idx &= 0x3;
+
+ if (set_tx)
+ key_idx |= 0x8000;
+
+ buf.idx = cpu_to_le16(key_idx);
+ memcpy(buf.key, key,
+ sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
+
+ if (rsc == NULL)
+ memset(buf.rsc, 0, sizeof(buf.rsc));
+ else
+ memcpy(buf.rsc, rsc, sizeof(buf.rsc));
+
+ if (tsc == NULL) {
+ memset(buf.tsc, 0, sizeof(buf.tsc));
+ buf.tsc[4] = 0x10;
+ } else {
+ memcpy(buf.tsc, tsc, sizeof(buf.tsc));
+ }
+
+ /* Wait upto 100ms for tx queue to empty */
+ k = 100;
+ do {
+ k--;
+ udelay(1000);
+ ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
+ &xmitting);
+ if (ret)
+ break;
+ } while ((k > 0) && xmitting);
+
+ if (k == 0)
+ ret = -ETIMEDOUT;
+
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
+ &buf);
+
+ return ret ? ret : err;
+}
+
+int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx)
+{
+ hermes_t *hw = &priv->hw;
+ int err;
+
+ memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
+ key_idx);
+ if (err)
+ printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
+ priv->ndev->name, err, key_idx);
+ return err;
+}
+
+int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
+ struct dev_addr_list *mc_list,
+ int mc_count, int promisc)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+
+ if (promisc != priv->promiscuous) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPROMISCUOUSMODE,
+ promisc);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
+ priv->ndev->name, err);
+ } else
+ priv->promiscuous = promisc;
+ }
+
+ /* If we're not in promiscuous mode, then we need to set the
+ * group address if either we want to multicast, or if we were
+ * multicasting and want to stop */
+ if (!promisc && (mc_count || priv->mc_count)) {
+ struct dev_mc_list *p = mc_list;
+ struct hermes_multicast mclist;
+ int i;
+
+ for (i = 0; i < mc_count; i++) {
+ /* paranoia: is list shorter than mc_count? */
+ BUG_ON(!p);
+ /* paranoia: bad address size in list? */
+ BUG_ON(p->dmi_addrlen != ETH_ALEN);
+
+ memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
+ p = p->next;
+ }
+
+ if (p)
+ printk(KERN_WARNING "%s: Multicast list is "
+ "longer than mc_count\n", priv->ndev->name);
+
+ err = hermes_write_ltv(hw, USER_BAP,
+ HERMES_RID_CNFGROUPADDRESSES,
+ HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
+ &mclist);
+ if (err)
+ printk(KERN_ERR "%s: Error %d setting multicast list.\n",
+ priv->ndev->name, err);
+ else
+ priv->mc_count = mc_count;
+ }
+ return err;
+}
+
+/* Return : < 0 -> error code ; >= 0 -> length */
+int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
+ char buf[IW_ESSID_MAX_SIZE+1])
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ struct hermes_idstring essidbuf;
+ char *p = (char *)(&essidbuf.val);
+ int len;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (strlen(priv->desired_essid) > 0) {
+ /* We read the desired SSID from the hardware rather
+ than from priv->desired_essid, just in case the
+ firmware is allowed to change it on us. I'm not
+ sure about this */
+ /* My guess is that the OWNSSID should always be whatever
+ * we set to the card, whereas CURRENT_SSID is the one that
+ * may change... - Jean II */
+ u16 rid;
+
+ *active = 1;
+
+ rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
+ HERMES_RID_CNFDESIREDSSID;
+
+ err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
+ NULL, &essidbuf);
+ if (err)
+ goto fail_unlock;
+ } else {
+ *active = 0;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
+ sizeof(essidbuf), NULL, &essidbuf);
+ if (err)
+ goto fail_unlock;
+ }
+
+ len = le16_to_cpu(essidbuf.len);
+ BUG_ON(len > IW_ESSID_MAX_SIZE);
+
+ memset(buf, 0, IW_ESSID_MAX_SIZE);
+ memcpy(buf, p, len);
+ err = len;
+
+ fail_unlock:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+int orinoco_hw_get_freq(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u16 channel;
+ int freq = 0;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL,
+ &channel);
+ if (err)
+ goto out;
+
+ /* Intersil firmware 1.3.5 returns 0 when the interface is down */
+ if (channel == 0) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ if ((channel < 1) || (channel > NUM_CHANNELS)) {
+ printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
+ priv->ndev->name, channel);
+ err = -EBUSY;
+ goto out;
+
+ }
+ freq = ieee80211_dsss_chan_to_freq(channel);
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ if (err > 0)
+ err = -EBUSY;
+ return err ? err : freq;
+}
+
+int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
+ int *numrates, s32 *rates, int max)
+{
+ hermes_t *hw = &priv->hw;
+ struct hermes_idstring list;
+ unsigned char *p = (unsigned char *)&list.val;
+ int err = 0;
+ int num;
+ int i;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
+ sizeof(list), NULL, &list);
+ orinoco_unlock(priv, &flags);
+
+ if (err)
+ return err;
+
+ num = le16_to_cpu(list.len);
+ *numrates = num;
+ num = min(num, max);
+
+ for (i = 0; i < num; i++)
+ rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
+
+ return 0;
+}
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
new file mode 100644
index 00000000000..dc3f23a9c1c
--- /dev/null
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -0,0 +1,47 @@
+/* Encapsulate basic setting changes on Hermes hardware
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_HW_H_
+#define _ORINOCO_HW_H_
+
+#include <linux/types.h>
+#include <linux/wireless.h>
+
+/* Hardware BAPs */
+#define USER_BAP 0
+#define IRQ_BAP 1
+
+/* WEP key sizes */
+#define SMALL_KEY_SIZE 5
+#define LARGE_KEY_SIZE 13
+
+/* Number of supported channels */
+#define NUM_CHANNELS 14
+
+/* Forward declarations */
+struct orinoco_private;
+struct dev_addr_list;
+
+int orinoco_get_bitratemode(int bitrate, int automatic);
+void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
+
+int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc);
+int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
+int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate);
+int __orinoco_hw_set_wap(struct orinoco_private *priv);
+int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv);
+int __orinoco_hw_setup_enc(struct orinoco_private *priv);
+int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
+ u8 *key, u8 *rsc, u8 *tsc);
+int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx);
+int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
+ struct dev_addr_list *mc_list,
+ int mc_count, int promisc);
+int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
+ char buf[IW_ESSID_MAX_SIZE+1]);
+int orinoco_hw_get_freq(struct orinoco_private *priv);
+int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
+ int *numrates, s32 *rates, int max);
+
+#endif /* _ORINOCO_HW_H_ */
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
new file mode 100644
index 00000000000..345593c4acc
--- /dev/null
+++ b/drivers/net/wireless/orinoco/main.c
@@ -0,0 +1,2667 @@
+/* main.c - (formerly known as dldwd_cs.c, orinoco_cs.c and orinoco.c)
+ *
+ * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
+ * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
+ *
+ * Current maintainers (as of 29 September 2003) are:
+ * Pavel Roskin <proski AT gnu.org>
+ * and David Gibson <hermes AT gibson.dropbear.id.au>
+ *
+ * (C) Copyright David Gibson, IBM Corporation 2001-2003.
+ * Copyright (C) 2000 David Gibson, Linuxcare Australia.
+ * With some help from :
+ * Copyright (C) 2001 Jean Tourrilhes, HP Labs
+ * Copyright (C) 2001 Benjamin Herrenschmidt
+ *
+ * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
+ *
+ * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
+ * AT fasta.fh-dortmund.de>
+ * http://www.stud.fh-dortmund.de/~andy/wvlan/
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds AT users.sourceforge.net>. Portions created by David
+ * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights
+ * Reserved.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL. */
+
+/*
+ * TODO
+ * o Handle de-encapsulation within network layer, provide 802.11
+ * headers (patch from Thomas 'Dent' Mirlacher)
+ * o Fix possible races in SPY handling.
+ * o Disconnect wireless extensions from fundamental configuration.
+ * o (maybe) Software WEP support (patch from Stano Meduna).
+ * o (maybe) Use multiple Tx buffers - driver handling queue
+ * rather than firmware.
+ */
+
+/* Locking and synchronization:
+ *
+ * The basic principle is that everything is serialized through a
+ * single spinlock, priv->lock. The lock is used in user, bh and irq
+ * context, so when taken outside hardirq context it should always be
+ * taken with interrupts disabled. The lock protects both the
+ * hardware and the struct orinoco_private.
+ *
+ * Another flag, priv->hw_unavailable indicates that the hardware is
+ * unavailable for an extended period of time (e.g. suspended, or in
+ * the middle of a hard reset). This flag is protected by the
+ * spinlock. All code which touches the hardware should check the
+ * flag after taking the lock, and if it is set, give up on whatever
+ * they are doing and drop the lock again. The orinoco_lock()
+ * function handles this (it unlocks and returns -EBUSY if
+ * hw_unavailable is non-zero).
+ */
+
+#define DRIVER_NAME "orinoco"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/suspend.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/iw_handler.h>
+
+#include "hermes_rid.h"
+#include "hermes_dld.h"
+#include "hw.h"
+#include "scan.h"
+#include "mic.h"
+#include "fw.h"
+#include "wext.h"
+#include "main.h"
+
+#include "orinoco.h"
+
+/********************************************************************/
+/* Module information */
+/********************************************************************/
+
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & "
+ "David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based "
+ "and similar wireless cards");
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* Level of debugging. Used in the macros in orinoco.h */
+#ifdef ORINOCO_DEBUG
+int orinoco_debug = ORINOCO_DEBUG;
+EXPORT_SYMBOL(orinoco_debug);
+module_param(orinoco_debug, int, 0644);
+MODULE_PARM_DESC(orinoco_debug, "Debug level");
+#endif
+
+static int suppress_linkstatus; /* = 0 */
+module_param(suppress_linkstatus, bool, 0644);
+MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
+
+static int ignore_disconnect; /* = 0 */
+module_param(ignore_disconnect, int, 0644);
+MODULE_PARM_DESC(ignore_disconnect,
+ "Don't report lost link to the network layer");
+
+int force_monitor; /* = 0 */
+module_param(force_monitor, int, 0644);
+MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
+
+/********************************************************************/
+/* Internal constants */
+/********************************************************************/
+
+/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
+static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
+
+#define ORINOCO_MIN_MTU 256
+#define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
+
+#define SYMBOL_MAX_VER_LEN (14)
+#define MAX_IRQLOOPS_PER_IRQ 10
+#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
+ * how many events the
+ * device could
+ * legitimately generate */
+#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
+
+#define DUMMY_FID 0xFFFF
+
+/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
+ HERMES_MAX_MULTICAST : 0)*/
+#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST)
+
+#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \
+ | HERMES_EV_TX | HERMES_EV_TXEXC \
+ | HERMES_EV_WTERR | HERMES_EV_INFO \
+ | HERMES_EV_INFDROP)
+
+static const struct ethtool_ops orinoco_ethtool_ops;
+
+/********************************************************************/
+/* Data types */
+/********************************************************************/
+
+/* Beginning of the Tx descriptor, used in TxExc handling */
+struct hermes_txexc_data {
+ struct hermes_tx_descriptor desc;
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+} __attribute__ ((packed));
+
+/* Rx frame header except compatibility 802.3 header */
+struct hermes_rx_descriptor {
+ /* Control */
+ __le16 status;
+ __le32 time;
+ u8 silence;
+ u8 signal;
+ u8 rate;
+ u8 rxflow;
+ __le32 reserved;
+
+ /* 802.11 header */
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+
+ /* Data length */
+ __le16 data_len;
+} __attribute__ ((packed));
+
+struct orinoco_rx_data {
+ struct hermes_rx_descriptor *desc;
+ struct sk_buff *skb;
+ struct list_head list;
+};
+
+/********************************************************************/
+/* Function prototypes */
+/********************************************************************/
+
+static void __orinoco_set_multicast_list(struct net_device *dev);
+
+/********************************************************************/
+/* Internal helper functions */
+/********************************************************************/
+
+void set_port_type(struct orinoco_private *priv)
+{
+ switch (priv->iw_mode) {
+ case IW_MODE_INFRA:
+ priv->port_type = 1;
+ priv->createibss = 0;
+ break;
+ case IW_MODE_ADHOC:
+ if (priv->prefer_port3) {
+ priv->port_type = 3;
+ priv->createibss = 0;
+ } else {
+ priv->port_type = priv->ibss_port;
+ priv->createibss = 1;
+ }
+ break;
+ case IW_MODE_MONITOR:
+ priv->port_type = 3;
+ priv->createibss = 0;
+ break;
+ default:
+ printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
+ priv->ndev->name);
+ }
+}
+
+/********************************************************************/
+/* Device methods */
+/********************************************************************/
+
+static int orinoco_open(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = __orinoco_up(dev);
+
+ if (!err)
+ priv->open = 1;
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_stop(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+
+ /* We mustn't use orinoco_lock() here, because we need to be
+ able to close the interface even if hw_unavailable is set
+ (e.g. as we're released after a PC Card removal) */
+ spin_lock_irq(&priv->lock);
+
+ priv->open = 0;
+
+ err = __orinoco_down(dev);
+
+ spin_unlock_irq(&priv->lock);
+
+ return err;
+}
+
+static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ return &priv->stats;
+}
+
+static void orinoco_set_multicast_list(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
+ "called when hw_unavailable\n", dev->name);
+ return;
+ }
+
+ __orinoco_set_multicast_list(dev);
+ orinoco_unlock(priv, &flags);
+}
+
+static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
+ return -EINVAL;
+
+ /* MTU + encapsulation + header length */
+ if ((new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
+ (priv->nicbuf_size - ETH_HLEN))
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+
+ return 0;
+}
+
+/********************************************************************/
+/* Tx path */
+/********************************************************************/
+
+static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u16 txfid = priv->txfid;
+ struct ethhdr *eh;
+ int tx_control;
+ unsigned long flags;
+
+ if (!netif_running(dev)) {
+ printk(KERN_ERR "%s: Tx on stopped device!\n",
+ dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (netif_queue_stopped(dev)) {
+ printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
+ dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
+ dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (!netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
+ /* Oops, the firmware hasn't established a connection,
+ silently drop the packet (this seems to be the
+ safest approach). */
+ goto drop;
+ }
+
+ /* Check packet length */
+ if (skb->len < ETH_HLEN)
+ goto drop;
+
+ tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
+
+ if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
+ tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
+ HERMES_TXCTRL_MIC;
+
+ if (priv->has_alt_txcntl) {
+ /* WPA enabled firmwares have tx_cntl at the end of
+ * the 802.11 header. So write zeroed descriptor and
+ * 802.11 header at the same time
+ */
+ char desc[HERMES_802_3_OFFSET];
+ __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
+
+ memset(&desc, 0, sizeof(desc));
+
+ *txcntl = cpu_to_le16(tx_control);
+ err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
+ txfid, 0);
+ if (err) {
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d writing Tx "
+ "descriptor to BAP\n", dev->name, err);
+ goto busy;
+ }
+ } else {
+ struct hermes_tx_descriptor desc;
+
+ memset(&desc, 0, sizeof(desc));
+
+ desc.tx_control = cpu_to_le16(tx_control);
+ err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
+ txfid, 0);
+ if (err) {
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d writing Tx "
+ "descriptor to BAP\n", dev->name, err);
+ goto busy;
+ }
+
+ /* Clear the 802.11 header and data length fields - some
+ * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
+ * if this isn't done. */
+ hermes_clear_words(hw, HERMES_DATA0,
+ HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
+ }
+
+ eh = (struct ethhdr *)skb->data;
+
+ /* Encapsulate Ethernet-II frames */
+ if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
+ struct header_struct {
+ struct ethhdr eth; /* 802.3 header */
+ u8 encap[6]; /* 802.2 header */
+ } __attribute__ ((packed)) hdr;
+
+ /* Strip destination and source from the data */
+ skb_pull(skb, 2 * ETH_ALEN);
+
+ /* And move them to a separate header */
+ memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
+ hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
+ memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
+
+ /* Insert the SNAP header */
+ if (skb_headroom(skb) < sizeof(hdr)) {
+ printk(KERN_ERR
+ "%s: Not enough headroom for 802.2 headers %d\n",
+ dev->name, skb_headroom(skb));
+ goto drop;
+ }
+ eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
+ memcpy(eh, &hdr, sizeof(hdr));
+ }
+
+ err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
+ txfid, HERMES_802_3_OFFSET);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
+ dev->name, err);
+ goto busy;
+ }
+
+ /* Calculate Michael MIC */
+ if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
+ u8 mic_buf[MICHAEL_MIC_LEN + 1];
+ u8 *mic;
+ size_t offset;
+ size_t len;
+
+ if (skb->len % 2) {
+ /* MIC start is on an odd boundary */
+ mic_buf[0] = skb->data[skb->len - 1];
+ mic = &mic_buf[1];
+ offset = skb->len - 1;
+ len = MICHAEL_MIC_LEN + 1;
+ } else {
+ mic = &mic_buf[0];
+ offset = skb->len;
+ len = MICHAEL_MIC_LEN;
+ }
+
+ orinoco_mic(priv->tx_tfm_mic,
+ priv->tkip_key[priv->tx_key].tx_mic,
+ eh->h_dest, eh->h_source, 0 /* priority */,
+ skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
+
+ /* Write the MIC */
+ err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
+ txfid, HERMES_802_3_OFFSET + offset);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
+ dev->name, err);
+ goto busy;
+ }
+ }
+
+ /* Finally, we actually initiate the send */
+ netif_stop_queue(dev);
+
+ err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
+ txfid, NULL);
+ if (err) {
+ netif_start_queue(dev);
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d transmitting packet\n",
+ dev->name, err);
+ goto busy;
+ }
+
+ dev->trans_start = jiffies;
+ stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
+ goto ok;
+
+ drop:
+ stats->tx_errors++;
+ stats->tx_dropped++;
+
+ ok:
+ orinoco_unlock(priv, &flags);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+
+ busy:
+ if (err == -EIO)
+ schedule_work(&priv->reset_work);
+ orinoco_unlock(priv, &flags);
+ return NETDEV_TX_BUSY;
+}
+
+static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ u16 fid = hermes_read_regn(hw, ALLOCFID);
+
+ if (fid != priv->txfid) {
+ if (fid != DUMMY_FID)
+ printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
+ dev->name, fid);
+ return;
+ }
+
+ hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
+}
+
+static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+
+ stats->tx_packets++;
+
+ netif_wake_queue(dev);
+
+ hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+}
+
+static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ u16 fid = hermes_read_regn(hw, TXCOMPLFID);
+ u16 status;
+ struct hermes_txexc_data hdr;
+ int err = 0;
+
+ if (fid == DUMMY_FID)
+ return; /* Nothing's really happened */
+
+ /* Read part of the frame header - we need status and addr1 */
+ err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
+ sizeof(struct hermes_txexc_data),
+ fid, 0);
+
+ hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+ stats->tx_errors++;
+
+ if (err) {
+ printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
+ "(FID=%04X error %d)\n",
+ dev->name, fid, err);
+ return;
+ }
+
+ DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
+ err, fid);
+
+ /* We produce a TXDROP event only for retry or lifetime
+ * exceeded, because that's the only status that really mean
+ * that this particular node went away.
+ * Other errors means that *we* screwed up. - Jean II */
+ status = le16_to_cpu(hdr.desc.status);
+ if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+ union iwreq_data wrqu;
+
+ /* Copy 802.11 dest address.
+ * We use the 802.11 header because the frame may
+ * not be 802.3 or may be mangled...
+ * In Ad-Hoc mode, it will be the node address.
+ * In managed mode, it will be most likely the AP addr
+ * User space will figure out how to convert it to
+ * whatever it needs (IP address or else).
+ * - Jean II */
+ memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
+ wrqu.addr.sa_family = ARPHRD_ETHER;
+
+ /* Send event to user space */
+ wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
+ }
+
+ netif_wake_queue(dev);
+}
+
+static void orinoco_tx_timeout(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ struct hermes *hw = &priv->hw;
+
+ printk(KERN_WARNING "%s: Tx timeout! "
+ "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
+ dev->name, hermes_read_regn(hw, ALLOCFID),
+ hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
+
+ stats->tx_errors++;
+
+ schedule_work(&priv->reset_work);
+}
+
+/********************************************************************/
+/* Rx path (data frames) */
+/********************************************************************/
+
+/* Does the frame have a SNAP header indicating it should be
+ * de-encapsulated to Ethernet-II? */
+static inline int is_ethersnap(void *_hdr)
+{
+ u8 *hdr = _hdr;
+
+ /* We de-encapsulate all packets which, a) have SNAP headers
+ * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
+ * and where b) the OUI of the SNAP header is 00:00:00 or
+ * 00:00:f8 - we need both because different APs appear to use
+ * different OUIs for some reason */
+ return (memcmp(hdr, &encaps_hdr, 5) == 0)
+ && ((hdr[5] == 0x00) || (hdr[5] == 0xf8));
+}
+
+static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
+ int level, int noise)
+{
+ struct iw_quality wstats;
+ wstats.level = level - 0x95;
+ wstats.noise = noise - 0x95;
+ wstats.qual = (level > noise) ? (level - noise) : 0;
+ wstats.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+ /* Update spy records */
+ wireless_spy_update(dev, mac, &wstats);
+}
+
+static void orinoco_stat_gather(struct net_device *dev,
+ struct sk_buff *skb,
+ struct hermes_rx_descriptor *desc)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ /* Using spy support with lots of Rx packets, like in an
+ * infrastructure (AP), will really slow down everything, because
+ * the MAC address must be compared to each entry of the spy list.
+ * If the user really asks for it (set some address in the
+ * spy list), we do it, but he will pay the price.
+ * Note that to get here, you need both WIRELESS_SPY
+ * compiled in AND some addresses in the list !!!
+ */
+ /* Note : gcc will optimise the whole section away if
+ * WIRELESS_SPY is not defined... - Jean II */
+ if (SPY_NUMBER(priv)) {
+ orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
+ desc->signal, desc->silence);
+ }
+}
+
+/*
+ * orinoco_rx_monitor - handle received monitor frames.
+ *
+ * Arguments:
+ * dev network device
+ * rxfid received FID
+ * desc rx descriptor of the frame
+ *
+ * Call context: interrupt
+ */
+static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
+ struct hermes_rx_descriptor *desc)
+{
+ u32 hdrlen = 30; /* return full header by default */
+ u32 datalen = 0;
+ u16 fc;
+ int err;
+ int len;
+ struct sk_buff *skb;
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ hermes_t *hw = &priv->hw;
+
+ len = le16_to_cpu(desc->data_len);
+
+ /* Determine the size of the header and the data */
+ fc = le16_to_cpu(desc->frame_ctl);
+ switch (fc & IEEE80211_FCTL_FTYPE) {
+ case IEEE80211_FTYPE_DATA:
+ if ((fc & IEEE80211_FCTL_TODS)
+ && (fc & IEEE80211_FCTL_FROMDS))
+ hdrlen = 30;
+ else
+ hdrlen = 24;
+ datalen = len;
+ break;
+ case IEEE80211_FTYPE_MGMT:
+ hdrlen = 24;
+ datalen = len;
+ break;
+ case IEEE80211_FTYPE_CTL:
+ switch (fc & IEEE80211_FCTL_STYPE) {
+ case IEEE80211_STYPE_PSPOLL:
+ case IEEE80211_STYPE_RTS:
+ case IEEE80211_STYPE_CFEND:
+ case IEEE80211_STYPE_CFENDACK:
+ hdrlen = 16;
+ break;
+ case IEEE80211_STYPE_CTS:
+ case IEEE80211_STYPE_ACK:
+ hdrlen = 10;
+ break;
+ }
+ break;
+ default:
+ /* Unknown frame type */
+ break;
+ }
+
+ /* sanity check the length */
+ if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
+ printk(KERN_DEBUG "%s: oversized monitor frame, "
+ "data length = %d\n", dev->name, datalen);
+ stats->rx_length_errors++;
+ goto update_stats;
+ }
+
+ skb = dev_alloc_skb(hdrlen + datalen);
+ if (!skb) {
+ printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
+ dev->name);
+ goto update_stats;
+ }
+
+ /* Copy the 802.11 header to the skb */
+ memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
+ skb_reset_mac_header(skb);
+
+ /* If any, copy the data from the card to the skb */
+ if (datalen > 0) {
+ err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
+ ALIGN(datalen, 2), rxfid,
+ HERMES_802_2_OFFSET);
+ if (err) {
+ printk(KERN_ERR "%s: error %d reading monitor frame\n",
+ dev->name, err);
+ goto drop;
+ }
+ }
+
+ skb->dev = dev;
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = cpu_to_be16(ETH_P_802_2);
+
+ stats->rx_packets++;
+ stats->rx_bytes += skb->len;
+
+ netif_rx(skb);
+ return;
+
+ drop:
+ dev_kfree_skb_irq(skb);
+ update_stats:
+ stats->rx_errors++;
+ stats->rx_dropped++;
+}
+
+static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ struct iw_statistics *wstats = &priv->wstats;
+ struct sk_buff *skb = NULL;
+ u16 rxfid, status;
+ int length;
+ struct hermes_rx_descriptor *desc;
+ struct orinoco_rx_data *rx_data;
+ int err;
+
+ desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
+ if (!desc) {
+ printk(KERN_WARNING
+ "%s: Can't allocate space for RX descriptor\n",
+ dev->name);
+ goto update_stats;
+ }
+
+ rxfid = hermes_read_regn(hw, RXFID);
+
+ err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
+ rxfid, 0);
+ if (err) {
+ printk(KERN_ERR "%s: error %d reading Rx descriptor. "
+ "Frame dropped.\n", dev->name, err);
+ goto update_stats;
+ }
+
+ status = le16_to_cpu(desc->status);
+
+ if (status & HERMES_RXSTAT_BADCRC) {
+ DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
+ dev->name);
+ stats->rx_crc_errors++;
+ goto update_stats;
+ }
+
+ /* Handle frames in monitor mode */
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ orinoco_rx_monitor(dev, rxfid, desc);
+ goto out;
+ }
+
+ if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
+ DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
+ dev->name);
+ wstats->discard.code++;
+ goto update_stats;
+ }
+
+ length = le16_to_cpu(desc->data_len);
+
+ /* Sanity checks */
+ if (length < 3) { /* No for even an 802.2 LLC header */
+ /* At least on Symbol firmware with PCF we get quite a
+ lot of these legitimately - Poll frames with no
+ data. */
+ goto out;
+ }
+ if (length > IEEE80211_MAX_DATA_LEN) {
+ printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
+ dev->name, length);
+ stats->rx_length_errors++;
+ goto update_stats;
+ }
+
+ /* Payload size does not include Michael MIC. Increase payload
+ * size to read it together with the data. */
+ if (status & HERMES_RXSTAT_MIC)
+ length += MICHAEL_MIC_LEN;
+
+ /* We need space for the packet data itself, plus an ethernet
+ header, plus 2 bytes so we can align the IP header on a
+ 32bit boundary, plus 1 byte so we can read in odd length
+ packets from the card, which has an IO granularity of 16
+ bits */
+ skb = dev_alloc_skb(length+ETH_HLEN+2+1);
+ if (!skb) {
+ printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
+ dev->name);
+ goto update_stats;
+ }
+
+ /* We'll prepend the header, so reserve space for it. The worst
+ case is no decapsulation, when 802.3 header is prepended and
+ nothing is removed. 2 is for aligning the IP header. */
+ skb_reserve(skb, ETH_HLEN + 2);
+
+ err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
+ ALIGN(length, 2), rxfid,
+ HERMES_802_2_OFFSET);
+ if (err) {
+ printk(KERN_ERR "%s: error %d reading frame. "
+ "Frame dropped.\n", dev->name, err);
+ goto drop;
+ }
+
+ /* Add desc and skb to rx queue */
+ rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
+ if (!rx_data) {
+ printk(KERN_WARNING "%s: Can't allocate RX packet\n",
+ dev->name);
+ goto drop;
+ }
+ rx_data->desc = desc;
+ rx_data->skb = skb;
+ list_add_tail(&rx_data->list, &priv->rx_list);
+ tasklet_schedule(&priv->rx_tasklet);
+
+ return;
+
+drop:
+ dev_kfree_skb_irq(skb);
+update_stats:
+ stats->rx_errors++;
+ stats->rx_dropped++;
+out:
+ kfree(desc);
+}
+
+static void orinoco_rx(struct net_device *dev,
+ struct hermes_rx_descriptor *desc,
+ struct sk_buff *skb)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ u16 status, fc;
+ int length;
+ struct ethhdr *hdr;
+
+ status = le16_to_cpu(desc->status);
+ length = le16_to_cpu(desc->data_len);
+ fc = le16_to_cpu(desc->frame_ctl);
+
+ /* Calculate and check MIC */
+ if (status & HERMES_RXSTAT_MIC) {
+ int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
+ HERMES_MIC_KEY_ID_SHIFT);
+ u8 mic[MICHAEL_MIC_LEN];
+ u8 *rxmic;
+ u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
+ desc->addr3 : desc->addr2;
+
+ /* Extract Michael MIC from payload */
+ rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
+
+ skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
+ length -= MICHAEL_MIC_LEN;
+
+ orinoco_mic(priv->rx_tfm_mic,
+ priv->tkip_key[key_id].rx_mic,
+ desc->addr1,
+ src,
+ 0, /* priority or QoS? */
+ skb->data,
+ skb->len,
+ &mic[0]);
+
+ if (memcmp(mic, rxmic,
+ MICHAEL_MIC_LEN)) {
+ union iwreq_data wrqu;
+ struct iw_michaelmicfailure wxmic;
+
+ printk(KERN_WARNING "%s: "
+ "Invalid Michael MIC in data frame from %pM, "
+ "using key %i\n",
+ dev->name, src, key_id);
+
+ /* TODO: update stats */
+
+ /* Notify userspace */
+ memset(&wxmic, 0, sizeof(wxmic));
+ wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
+ wxmic.flags |= (desc->addr1[0] & 1) ?
+ IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
+ wxmic.src_addr.sa_family = ARPHRD_ETHER;
+ memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
+
+ (void) orinoco_hw_get_tkip_iv(priv, key_id,
+ &wxmic.tsc[0]);
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = sizeof(wxmic);
+ wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
+ (char *) &wxmic);
+
+ goto drop;
+ }
+ }
+
+ /* Handle decapsulation
+ * In most cases, the firmware tell us about SNAP frames.
+ * For some reason, the SNAP frames sent by LinkSys APs
+ * are not properly recognised by most firmwares.
+ * So, check ourselves */
+ if (length >= ENCAPS_OVERHEAD &&
+ (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
+ ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
+ is_ethersnap(skb->data))) {
+ /* These indicate a SNAP within 802.2 LLC within
+ 802.11 frame which we'll need to de-encapsulate to
+ the original EthernetII frame. */
+ hdr = (struct ethhdr *)skb_push(skb,
+ ETH_HLEN - ENCAPS_OVERHEAD);
+ } else {
+ /* 802.3 frame - prepend 802.3 header as is */
+ hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
+ hdr->h_proto = htons(length);
+ }
+ memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
+ if (fc & IEEE80211_FCTL_FROMDS)
+ memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
+ else
+ memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
+
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_NONE;
+ if (fc & IEEE80211_FCTL_TODS)
+ skb->pkt_type = PACKET_OTHERHOST;
+
+ /* Process the wireless stats if needed */
+ orinoco_stat_gather(dev, skb, desc);
+
+ /* Pass the packet to the networking stack */
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
+
+ return;
+
+ drop:
+ dev_kfree_skb(skb);
+ stats->rx_errors++;
+ stats->rx_dropped++;
+}
+
+static void orinoco_rx_isr_tasklet(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *) data;
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_rx_data *rx_data, *temp;
+ struct hermes_rx_descriptor *desc;
+ struct sk_buff *skb;
+ unsigned long flags;
+
+ /* orinoco_rx requires the driver lock, and we also need to
+ * protect priv->rx_list, so just hold the lock over the
+ * lot.
+ *
+ * If orinoco_lock fails, we've unplugged the card. In this
+ * case just abort. */
+ if (orinoco_lock(priv, &flags) != 0)
+ return;
+
+ /* extract desc and skb from queue */
+ list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
+ desc = rx_data->desc;
+ skb = rx_data->skb;
+ list_del(&rx_data->list);
+ kfree(rx_data);
+
+ orinoco_rx(dev, desc, skb);
+
+ kfree(desc);
+ }
+
+ orinoco_unlock(priv, &flags);
+}
+
+/********************************************************************/
+/* Rx path (info frames) */
+/********************************************************************/
+
+static void print_linkstatus(struct net_device *dev, u16 status)
+{
+ char *s;
+
+ if (suppress_linkstatus)
+ return;
+
+ switch (status) {
+ case HERMES_LINKSTATUS_NOT_CONNECTED:
+ s = "Not Connected";
+ break;
+ case HERMES_LINKSTATUS_CONNECTED:
+ s = "Connected";
+ break;
+ case HERMES_LINKSTATUS_DISCONNECTED:
+ s = "Disconnected";
+ break;
+ case HERMES_LINKSTATUS_AP_CHANGE:
+ s = "AP Changed";
+ break;
+ case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
+ s = "AP Out of Range";
+ break;
+ case HERMES_LINKSTATUS_AP_IN_RANGE:
+ s = "AP In Range";
+ break;
+ case HERMES_LINKSTATUS_ASSOC_FAILED:
+ s = "Association Failed";
+ break;
+ default:
+ s = "UNKNOWN";
+ }
+
+ printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
+ dev->name, s, status);
+}
+
+/* Search scan results for requested BSSID, join it if found */
+static void orinoco_join_ap(struct work_struct *work)
+{
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, join_work);
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ int err;
+ unsigned long flags;
+ struct join_req {
+ u8 bssid[ETH_ALEN];
+ __le16 channel;
+ } __attribute__ ((packed)) req;
+ const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
+ struct prism2_scan_apinfo *atom = NULL;
+ int offset = 4;
+ int found = 0;
+ u8 *buf;
+ u16 len;
+
+ /* Allocate buffer for scan results */
+ buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ goto fail_lock;
+
+ /* Sanity checks in case user changed something in the meantime */
+ if (!priv->bssid_fixed)
+ goto out;
+
+ if (strlen(priv->desired_essid) == 0)
+ goto out;
+
+ /* Read scan results from the firmware */
+ err = hermes_read_ltv(hw, USER_BAP,
+ HERMES_RID_SCANRESULTSTABLE,
+ MAX_SCAN_LEN, &len, buf);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot read scan results\n",
+ dev->name);
+ goto out;
+ }
+
+ len = HERMES_RECLEN_TO_BYTES(len);
+
+ /* Go through the scan results looking for the channel of the AP
+ * we were requested to join */
+ for (; offset + atom_len <= len; offset += atom_len) {
+ atom = (struct prism2_scan_apinfo *) (buf + offset);
+ if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ DEBUG(1, "%s: Requested AP not found in scan results\n",
+ dev->name);
+ goto out;
+ }
+
+ memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
+ req.channel = atom->channel; /* both are little-endian */
+ err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
+ &req);
+ if (err)
+ printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ fail_lock:
+ kfree(buf);
+}
+
+/* Send new BSSID to userspace */
+static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
+{
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ union iwreq_data wrqu;
+ int err;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+ ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
+ if (err != 0)
+ return;
+
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+
+ /* Send event to user space */
+ wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+}
+
+static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
+{
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ union iwreq_data wrqu;
+ int err;
+ u8 buf[88];
+ u8 *ie;
+
+ if (!priv->has_wpa)
+ return;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
+ sizeof(buf), NULL, &buf);
+ if (err != 0)
+ return;
+
+ ie = orinoco_get_wpa_ie(buf, sizeof(buf));
+ if (ie) {
+ int rem = sizeof(buf) - (ie - &buf[0]);
+ wrqu.data.length = ie[1] + 2;
+ if (wrqu.data.length > rem)
+ wrqu.data.length = rem;
+
+ if (wrqu.data.length)
+ /* Send event to user space */
+ wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
+ }
+}
+
+static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
+{
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ union iwreq_data wrqu;
+ int err;
+ u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
+ u8 *ie;
+
+ if (!priv->has_wpa)
+ return;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
+ sizeof(buf), NULL, &buf);
+ if (err != 0)
+ return;
+
+ ie = orinoco_get_wpa_ie(buf, sizeof(buf));
+ if (ie) {
+ int rem = sizeof(buf) - (ie - &buf[0]);
+ wrqu.data.length = ie[1] + 2;
+ if (wrqu.data.length > rem)
+ wrqu.data.length = rem;
+
+ if (wrqu.data.length)
+ /* Send event to user space */
+ wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
+ }
+}
+
+static void orinoco_send_wevents(struct work_struct *work)
+{
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, wevent_work);
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return;
+
+ orinoco_send_assocreqie_wevent(priv);
+ orinoco_send_assocrespie_wevent(priv);
+ orinoco_send_bssid_wevent(priv);
+
+ orinoco_unlock(priv, &flags);
+}
+
+static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ u16 infofid;
+ struct {
+ __le16 len;
+ __le16 type;
+ } __attribute__ ((packed)) info;
+ int len, type;
+ int err;
+
+ /* This is an answer to an INQUIRE command that we did earlier,
+ * or an information "event" generated by the card
+ * The controller return to us a pseudo frame containing
+ * the information in question - Jean II */
+ infofid = hermes_read_regn(hw, INFOFID);
+
+ /* Read the info frame header - don't try too hard */
+ err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
+ infofid, 0);
+ if (err) {
+ printk(KERN_ERR "%s: error %d reading info frame. "
+ "Frame dropped.\n", dev->name, err);
+ return;
+ }
+
+ len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
+ type = le16_to_cpu(info.type);
+
+ switch (type) {
+ case HERMES_INQ_TALLIES: {
+ struct hermes_tallies_frame tallies;
+ struct iw_statistics *wstats = &priv->wstats;
+
+ if (len > sizeof(tallies)) {
+ printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
+ dev->name, len);
+ len = sizeof(tallies);
+ }
+
+ err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
+ infofid, sizeof(info));
+ if (err)
+ break;
+
+ /* Increment our various counters */
+ /* wstats->discard.nwid - no wrong BSSID stuff */
+ wstats->discard.code +=
+ le16_to_cpu(tallies.RxWEPUndecryptable);
+ if (len == sizeof(tallies))
+ wstats->discard.code +=
+ le16_to_cpu(tallies.RxDiscards_WEPICVError) +
+ le16_to_cpu(tallies.RxDiscards_WEPExcluded);
+ wstats->discard.misc +=
+ le16_to_cpu(tallies.TxDiscardsWrongSA);
+ wstats->discard.fragment +=
+ le16_to_cpu(tallies.RxMsgInBadMsgFragments);
+ wstats->discard.retries +=
+ le16_to_cpu(tallies.TxRetryLimitExceeded);
+ /* wstats->miss.beacon - no match */
+ }
+ break;
+ case HERMES_INQ_LINKSTATUS: {
+ struct hermes_linkstatus linkstatus;
+ u16 newstatus;
+ int connected;
+
+ if (priv->iw_mode == IW_MODE_MONITOR)
+ break;
+
+ if (len != sizeof(linkstatus)) {
+ printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
+ dev->name, len);
+ break;
+ }
+
+ err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
+ infofid, sizeof(info));
+ if (err)
+ break;
+ newstatus = le16_to_cpu(linkstatus.linkstatus);
+
+ /* Symbol firmware uses "out of range" to signal that
+ * the hostscan frame can be requested. */
+ if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
+ priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
+ priv->has_hostscan && priv->scan_inprogress) {
+ hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
+ break;
+ }
+
+ connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
+ || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
+ || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
+
+ if (connected)
+ netif_carrier_on(dev);
+ else if (!ignore_disconnect)
+ netif_carrier_off(dev);
+
+ if (newstatus != priv->last_linkstatus) {
+ priv->last_linkstatus = newstatus;
+ print_linkstatus(dev, newstatus);
+ /* The info frame contains only one word which is the
+ * status (see hermes.h). The status is pretty boring
+ * in itself, that's why we export the new BSSID...
+ * Jean II */
+ schedule_work(&priv->wevent_work);
+ }
+ }
+ break;
+ case HERMES_INQ_SCAN:
+ if (!priv->scan_inprogress && priv->bssid_fixed &&
+ priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
+ schedule_work(&priv->join_work);
+ break;
+ }
+ /* fall through */
+ case HERMES_INQ_HOSTSCAN:
+ case HERMES_INQ_HOSTSCAN_SYMBOL: {
+ /* Result of a scanning. Contains information about
+ * cells in the vicinity - Jean II */
+ union iwreq_data wrqu;
+ unsigned char *buf;
+
+ /* Scan is no longer in progress */
+ priv->scan_inprogress = 0;
+
+ /* Sanity check */
+ if (len > 4096) {
+ printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
+ dev->name, len);
+ break;
+ }
+
+ /* Allocate buffer for results */
+ buf = kmalloc(len, GFP_ATOMIC);
+ if (buf == NULL)
+ /* No memory, so can't printk()... */
+ break;
+
+ /* Read scan data */
+ err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
+ infofid, sizeof(info));
+ if (err) {
+ kfree(buf);
+ break;
+ }
+
+#ifdef ORINOCO_DEBUG
+ {
+ int i;
+ printk(KERN_DEBUG "Scan result [%02X", buf[0]);
+ for (i = 1; i < (len * 2); i++)
+ printk(":%02X", buf[i]);
+ printk("]\n");
+ }
+#endif /* ORINOCO_DEBUG */
+
+ if (orinoco_process_scan_results(priv, buf, len) == 0) {
+ /* Send an empty event to user space.
+ * We don't send the received data on the event because
+ * it would require us to do complex transcoding, and
+ * we want to minimise the work done in the irq handler
+ * Use a request to extract the data - Jean II */
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+ }
+ kfree(buf);
+ }
+ break;
+ case HERMES_INQ_CHANNELINFO:
+ {
+ struct agere_ext_scan_info *bss;
+
+ if (!priv->scan_inprogress) {
+ printk(KERN_DEBUG "%s: Got chaninfo without scan, "
+ "len=%d\n", dev->name, len);
+ break;
+ }
+
+ /* An empty result indicates that the scan is complete */
+ if (len == 0) {
+ union iwreq_data wrqu;
+
+ /* Scan is no longer in progress */
+ priv->scan_inprogress = 0;
+
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+ break;
+ }
+
+ /* Sanity check */
+ else if (len > sizeof(*bss)) {
+ printk(KERN_WARNING
+ "%s: Ext scan results too large (%d bytes). "
+ "Truncating results to %zd bytes.\n",
+ dev->name, len, sizeof(*bss));
+ len = sizeof(*bss);
+ } else if (len < (offsetof(struct agere_ext_scan_info,
+ data) + 2)) {
+ /* Drop this result now so we don't have to
+ * keep checking later */
+ printk(KERN_WARNING
+ "%s: Ext scan results too short (%d bytes)\n",
+ dev->name, len);
+ break;
+ }
+
+ bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
+ if (bss == NULL)
+ break;
+
+ /* Read scan data */
+ err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
+ infofid, sizeof(info));
+ if (err) {
+ kfree(bss);
+ break;
+ }
+
+ orinoco_add_ext_scan_result(priv, bss);
+
+ kfree(bss);
+ break;
+ }
+ case HERMES_INQ_SEC_STAT_AGERE:
+ /* Security status (Agere specific) */
+ /* Ignore this frame for now */
+ if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+ break;
+ /* fall through */
+ default:
+ printk(KERN_DEBUG "%s: Unknown information frame received: "
+ "type 0x%04x, length %d\n", dev->name, type, len);
+ /* We don't actually do anything about it */
+ break;
+ }
+}
+
+static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
+{
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
+}
+
+/********************************************************************/
+/* Internal hardware control routines */
+/********************************************************************/
+
+int __orinoco_up(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+
+ netif_carrier_off(dev); /* just to make sure */
+
+ err = __orinoco_program_rids(dev);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d configuring card\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Fire things up again */
+ hermes_set_irqmask(hw, ORINOCO_INTEN);
+ err = hermes_enable_port(hw, 0);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d enabling MAC port\n",
+ dev->name, err);
+ return err;
+ }
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL(__orinoco_up);
+
+int __orinoco_down(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+
+ netif_stop_queue(dev);
+
+ if (!priv->hw_unavailable) {
+ if (!priv->broken_disableport) {
+ err = hermes_disable_port(hw, 0);
+ if (err) {
+ /* Some firmwares (e.g. Intersil 1.3.x) seem
+ * to have problems disabling the port, oh
+ * well, too bad. */
+ printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
+ dev->name, err);
+ priv->broken_disableport = 1;
+ }
+ }
+ hermes_set_irqmask(hw, 0);
+ hermes_write_regn(hw, EVACK, 0xffff);
+ }
+
+ /* firmware will have to reassociate */
+ netif_carrier_off(dev);
+ priv->last_linkstatus = 0xffff;
+
+ return 0;
+}
+EXPORT_SYMBOL(__orinoco_down);
+
+static int orinoco_allocate_fid(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+
+ err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+ if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
+ /* Try workaround for old Symbol firmware bug */
+ priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+ err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+
+ printk(KERN_WARNING "%s: firmware ALLOC bug detected "
+ "(old Symbol firmware?). Work around %s\n",
+ dev->name, err ? "failed!" : "ok.");
+ }
+
+ return err;
+}
+
+int orinoco_reinit_firmware(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+
+ err = hermes_init(hw);
+ if (priv->do_fw_download && !err) {
+ err = orinoco_download(priv);
+ if (err)
+ priv->do_fw_download = 0;
+ }
+ if (!err)
+ err = orinoco_allocate_fid(dev);
+
+ return err;
+}
+EXPORT_SYMBOL(orinoco_reinit_firmware);
+
+int __orinoco_program_rids(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err;
+ struct hermes_idstring idbuf;
+
+ /* Set the MAC address */
+ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+ HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting MAC address\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set up the link mode */
+ err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
+ priv->port_type);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting port type\n",
+ dev->name, err);
+ return err;
+ }
+ /* Set the channel/frequency */
+ if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFOWNCHANNEL,
+ priv->channel);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting channel %d\n",
+ dev->name, err, priv->channel);
+ return err;
+ }
+ }
+
+ if (priv->has_ibss) {
+ u16 createibss;
+
+ if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
+ printk(KERN_WARNING "%s: This firmware requires an "
+ "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
+ /* With wvlan_cs, in this case, we would crash.
+ * hopefully, this driver will behave better...
+ * Jean II */
+ createibss = 0;
+ } else {
+ createibss = priv->createibss;
+ }
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFCREATEIBSS,
+ createibss);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
+ dev->name, err);
+ return err;
+ }
+ }
+
+ /* Set the desired BSSID */
+ err = __orinoco_hw_set_wap(priv);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting AP address\n",
+ dev->name, err);
+ return err;
+ }
+ /* Set the desired ESSID */
+ idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
+ memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
+ /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
+ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
+ HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+ &idbuf);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
+ dev->name, err);
+ return err;
+ }
+ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
+ HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+ &idbuf);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set the station name */
+ idbuf.len = cpu_to_le16(strlen(priv->nick));
+ memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
+ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+ HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
+ &idbuf);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting nickname\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set AP density */
+ if (priv->has_sensitivity) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSYSTEMSCALE,
+ priv->ap_density);
+ if (err) {
+ printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
+ "Disabling sensitivity control\n",
+ dev->name, err);
+
+ priv->has_sensitivity = 0;
+ }
+ }
+
+ /* Set RTS threshold */
+ err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+ priv->rts_thresh);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set fragmentation threshold or MWO robustness */
+ if (priv->has_mwo)
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMWOROBUST_AGERE,
+ priv->mwo_robust);
+ else
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+ priv->frag_thresh);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting fragmentation\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set bitrate */
+ err = __orinoco_hw_set_bitrate(priv);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting bitrate\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set power management */
+ if (priv->has_pm) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMENABLED,
+ priv->pm_on);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting up PM\n",
+ dev->name, err);
+ return err;
+ }
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMULTICASTRECEIVE,
+ priv->pm_mcast);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting up PM\n",
+ dev->name, err);
+ return err;
+ }
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMAXSLEEPDURATION,
+ priv->pm_period);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting up PM\n",
+ dev->name, err);
+ return err;
+ }
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMHOLDOVERDURATION,
+ priv->pm_timeout);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting up PM\n",
+ dev->name, err);
+ return err;
+ }
+ }
+
+ /* Set preamble - only for Symbol so far... */
+ if (priv->has_preamble) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPREAMBLE_SYMBOL,
+ priv->preamble);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting preamble\n",
+ dev->name, err);
+ return err;
+ }
+ }
+
+ /* Set up encryption */
+ if (priv->has_wep || priv->has_wpa) {
+ err = __orinoco_hw_setup_enc(priv);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d activating encryption\n",
+ dev->name, err);
+ return err;
+ }
+ }
+
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ /* Enable monitor mode */
+ dev->type = ARPHRD_IEEE80211;
+ err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+ HERMES_TEST_MONITOR, 0, NULL);
+ } else {
+ /* Disable monitor mode */
+ dev->type = ARPHRD_ETHER;
+ err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+ HERMES_TEST_STOP, 0, NULL);
+ }
+ if (err)
+ return err;
+
+ /* Set promiscuity / multicast*/
+ priv->promiscuous = 0;
+ priv->mc_count = 0;
+
+ /* FIXME: what about netif_tx_lock */
+ __orinoco_set_multicast_list(dev);
+
+ return 0;
+}
+
+/* FIXME: return int? */
+static void
+__orinoco_set_multicast_list(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+ int promisc, mc_count;
+
+ /* The Hermes doesn't seem to have an allmulti mode, so we go
+ * into promiscuous mode and let the upper levels deal. */
+ if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
+ (dev->mc_count > MAX_MULTICAST(priv))) {
+ promisc = 1;
+ mc_count = 0;
+ } else {
+ promisc = 0;
+ mc_count = dev->mc_count;
+ }
+
+ err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count,
+ promisc);
+}
+
+/* This must be called from user context, without locks held - use
+ * schedule_work() */
+void orinoco_reset(struct work_struct *work)
+{
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, reset_work);
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ int err;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ /* When the hardware becomes available again, whatever
+ * detects that is responsible for re-initializing
+ * it. So no need for anything further */
+ return;
+
+ netif_stop_queue(dev);
+
+ /* Shut off interrupts. Depending on what state the hardware
+ * is in, this might not work, but we'll try anyway */
+ hermes_set_irqmask(hw, 0);
+ hermes_write_regn(hw, EVACK, 0xffff);
+
+ priv->hw_unavailable++;
+ priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
+ netif_carrier_off(dev);
+
+ orinoco_unlock(priv, &flags);
+
+ /* Scanning support: Cleanup of driver struct */
+ orinoco_clear_scan_results(priv, 0);
+ priv->scan_inprogress = 0;
+
+ if (priv->hard_reset) {
+ err = (*priv->hard_reset)(priv);
+ if (err) {
+ printk(KERN_ERR "%s: orinoco_reset: Error %d "
+ "performing hard reset\n", dev->name, err);
+ goto disable;
+ }
+ }
+
+ err = orinoco_reinit_firmware(dev);
+ if (err) {
+ printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
+ dev->name, err);
+ goto disable;
+ }
+
+ /* This has to be called from user context */
+ spin_lock_irq(&priv->lock);
+
+ priv->hw_unavailable--;
+
+ /* priv->open or priv->hw_unavailable might have changed while
+ * we dropped the lock */
+ if (priv->open && (!priv->hw_unavailable)) {
+ err = __orinoco_up(dev);
+ if (err) {
+ printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
+ dev->name, err);
+ } else
+ dev->trans_start = jiffies;
+ }
+
+ spin_unlock_irq(&priv->lock);
+
+ return;
+ disable:
+ hermes_set_irqmask(hw, 0);
+ netif_device_detach(dev);
+ printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
+}
+
+/********************************************************************/
+/* Interrupt handler */
+/********************************************************************/
+
+static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
+{
+ printk(KERN_DEBUG "%s: TICK\n", dev->name);
+}
+
+static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
+{
+ /* This seems to happen a fair bit under load, but ignoring it
+ seems to work fine...*/
+ printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
+ dev->name);
+}
+
+irqreturn_t orinoco_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int count = MAX_IRQLOOPS_PER_IRQ;
+ u16 evstat, events;
+ /* These are used to detect a runaway interrupt situation.
+ *
+ * If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
+ * we panic and shut down the hardware
+ */
+ /* jiffies value the last time we were called */
+ static int last_irq_jiffy; /* = 0 */
+ static int loops_this_jiffy; /* = 0 */
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ /* If hw is unavailable - we don't know if the irq was
+ * for us or not */
+ return IRQ_HANDLED;
+ }
+
+ evstat = hermes_read_regn(hw, EVSTAT);
+ events = evstat & hw->inten;
+ if (!events) {
+ orinoco_unlock(priv, &flags);
+ return IRQ_NONE;
+ }
+
+ if (jiffies != last_irq_jiffy)
+ loops_this_jiffy = 0;
+ last_irq_jiffy = jiffies;
+
+ while (events && count--) {
+ if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
+ printk(KERN_WARNING "%s: IRQ handler is looping too "
+ "much! Resetting.\n", dev->name);
+ /* Disable interrupts for now */
+ hermes_set_irqmask(hw, 0);
+ schedule_work(&priv->reset_work);
+ break;
+ }
+
+ /* Check the card hasn't been removed */
+ if (!hermes_present(hw)) {
+ DEBUG(0, "orinoco_interrupt(): card removed\n");
+ break;
+ }
+
+ if (events & HERMES_EV_TICK)
+ __orinoco_ev_tick(dev, hw);
+ if (events & HERMES_EV_WTERR)
+ __orinoco_ev_wterr(dev, hw);
+ if (events & HERMES_EV_INFDROP)
+ __orinoco_ev_infdrop(dev, hw);
+ if (events & HERMES_EV_INFO)
+ __orinoco_ev_info(dev, hw);
+ if (events & HERMES_EV_RX)
+ __orinoco_ev_rx(dev, hw);
+ if (events & HERMES_EV_TXEXC)
+ __orinoco_ev_txexc(dev, hw);
+ if (events & HERMES_EV_TX)
+ __orinoco_ev_tx(dev, hw);
+ if (events & HERMES_EV_ALLOC)
+ __orinoco_ev_alloc(dev, hw);
+
+ hermes_write_regn(hw, EVACK, evstat);
+
+ evstat = hermes_read_regn(hw, EVSTAT);
+ events = evstat & hw->inten;
+ };
+
+ orinoco_unlock(priv, &flags);
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(orinoco_interrupt);
+
+/********************************************************************/
+/* Power management */
+/********************************************************************/
+#if defined(CONFIG_PM_SLEEP) && !defined(CONFIG_HERMES_CACHE_FW_ON_INIT)
+static int orinoco_pm_notifier(struct notifier_block *notifier,
+ unsigned long pm_event,
+ void *unused)
+{
+ struct orinoco_private *priv = container_of(notifier,
+ struct orinoco_private,
+ pm_notifier);
+
+ /* All we need to do is cache the firmware before suspend, and
+ * release it when we come out.
+ *
+ * Only need to do this if we're downloading firmware. */
+ if (!priv->do_fw_download)
+ return NOTIFY_DONE;
+
+ switch (pm_event) {
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ orinoco_cache_fw(priv, 0);
+ break;
+
+ case PM_POST_RESTORE:
+ /* Restore from hibernation failed. We need to clean
+ * up in exactly the same way, so fall through. */
+ case PM_POST_HIBERNATION:
+ case PM_POST_SUSPEND:
+ orinoco_uncache_fw(priv);
+ break;
+
+ case PM_RESTORE_PREPARE:
+ default:
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static void orinoco_register_pm_notifier(struct orinoco_private *priv)
+{
+ priv->pm_notifier.notifier_call = orinoco_pm_notifier;
+ register_pm_notifier(&priv->pm_notifier);
+}
+
+static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
+{
+ unregister_pm_notifier(&priv->pm_notifier);
+}
+#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
+#define orinoco_register_pm_notifier(priv) do { } while(0)
+#define orinoco_unregister_pm_notifier(priv) do { } while(0)
+#endif
+
+/********************************************************************/
+/* Initialization */
+/********************************************************************/
+
+struct comp_id {
+ u16 id, variant, major, minor;
+} __attribute__ ((packed));
+
+static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
+{
+ if (nic_id->id < 0x8000)
+ return FIRMWARE_TYPE_AGERE;
+ else if (nic_id->id == 0x8000 && nic_id->major == 0)
+ return FIRMWARE_TYPE_SYMBOL;
+ else
+ return FIRMWARE_TYPE_INTERSIL;
+}
+
+/* Set priv->firmware type, determine firmware properties */
+static int determine_firmware(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err;
+ struct comp_id nic_id, sta_id;
+ unsigned int firmver;
+ char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
+
+ /* Get the hardware version */
+ err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
+ dev->name, err);
+ return err;
+ }
+
+ le16_to_cpus(&nic_id.id);
+ le16_to_cpus(&nic_id.variant);
+ le16_to_cpus(&nic_id.major);
+ le16_to_cpus(&nic_id.minor);
+ printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
+ dev->name, nic_id.id, nic_id.variant,
+ nic_id.major, nic_id.minor);
+
+ priv->firmware_type = determine_firmware_type(&nic_id);
+
+ /* Get the firmware version */
+ err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
+ dev->name, err);
+ return err;
+ }
+
+ le16_to_cpus(&sta_id.id);
+ le16_to_cpus(&sta_id.variant);
+ le16_to_cpus(&sta_id.major);
+ le16_to_cpus(&sta_id.minor);
+ printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
+ dev->name, sta_id.id, sta_id.variant,
+ sta_id.major, sta_id.minor);
+
+ switch (sta_id.id) {
+ case 0x15:
+ printk(KERN_ERR "%s: Primary firmware is active\n",
+ dev->name);
+ return -ENODEV;
+ case 0x14b:
+ printk(KERN_ERR "%s: Tertiary firmware is active\n",
+ dev->name);
+ return -ENODEV;
+ case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */
+ case 0x21: /* Symbol Spectrum24 Trilogy */
+ break;
+ default:
+ printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
+ dev->name);
+ break;
+ }
+
+ /* Default capabilities */
+ priv->has_sensitivity = 1;
+ priv->has_mwo = 0;
+ priv->has_preamble = 0;
+ priv->has_port3 = 1;
+ priv->has_ibss = 1;
+ priv->has_wep = 0;
+ priv->has_big_wep = 0;
+ priv->has_alt_txcntl = 0;
+ priv->has_ext_scan = 0;
+ priv->has_wpa = 0;
+ priv->do_fw_download = 0;
+
+ /* Determine capabilities from the firmware version */
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
+ ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
+
+ firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
+
+ priv->has_ibss = (firmver >= 0x60006);
+ priv->has_wep = (firmver >= 0x40020);
+ priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
+ Gold cards from the others? */
+ priv->has_mwo = (firmver >= 0x60000);
+ priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
+ priv->ibss_port = 1;
+ priv->has_hostscan = (firmver >= 0x8000a);
+ priv->do_fw_download = 1;
+ priv->broken_monitor = (firmver >= 0x80000);
+ priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
+ priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
+ priv->has_wpa = (firmver >= 0x9002a);
+ /* Tested with Agere firmware :
+ * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
+ * Tested CableTron firmware : 4.32 => Anton */
+ break;
+ case FIRMWARE_TYPE_SYMBOL:
+ /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
+ /* Intel MAC : 00:02:B3:* */
+ /* 3Com MAC : 00:50:DA:* */
+ memset(tmp, 0, sizeof(tmp));
+ /* Get the Symbol firmware version */
+ err = hermes_read_ltv(hw, USER_BAP,
+ HERMES_RID_SECONDARYVERSION_SYMBOL,
+ SYMBOL_MAX_VER_LEN, NULL, &tmp);
+ if (err) {
+ printk(KERN_WARNING
+ "%s: Error %d reading Symbol firmware info. "
+ "Wildly guessing capabilities...\n",
+ dev->name, err);
+ firmver = 0;
+ tmp[0] = '\0';
+ } else {
+ /* The firmware revision is a string, the format is
+ * something like : "V2.20-01".
+ * Quick and dirty parsing... - Jean II
+ */
+ firmver = ((tmp[1] - '0') << 16)
+ | ((tmp[3] - '0') << 12)
+ | ((tmp[4] - '0') << 8)
+ | ((tmp[6] - '0') << 4)
+ | (tmp[7] - '0');
+
+ tmp[SYMBOL_MAX_VER_LEN] = '\0';
+ }
+
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Symbol %s", tmp);
+
+ priv->has_ibss = (firmver >= 0x20000);
+ priv->has_wep = (firmver >= 0x15012);
+ priv->has_big_wep = (firmver >= 0x20000);
+ priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
+ (firmver >= 0x29000 && firmver < 0x30000) ||
+ firmver >= 0x31000;
+ priv->has_preamble = (firmver >= 0x20000);
+ priv->ibss_port = 4;
+
+ /* Symbol firmware is found on various cards, but
+ * there has been no attempt to check firmware
+ * download on non-spectrum_cs based cards.
+ *
+ * Given that the Agere firmware download works
+ * differently, we should avoid doing a firmware
+ * download with the Symbol algorithm on non-spectrum
+ * cards.
+ *
+ * For now we can identify a spectrum_cs based card
+ * because it has a firmware reset function.
+ */
+ priv->do_fw_download = (priv->stop_fw != NULL);
+
+ priv->broken_disableport = (firmver == 0x25013) ||
+ (firmver >= 0x30000 && firmver <= 0x31000);
+ priv->has_hostscan = (firmver >= 0x31001) ||
+ (firmver >= 0x29057 && firmver < 0x30000);
+ /* Tested with Intel firmware : 0x20015 => Jean II */
+ /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ /* D-Link, Linksys, Adtron, ZoomAir, and many others...
+ * Samsung, Compaq 100/200 and Proxim are slightly
+ * different and less well tested */
+ /* D-Link MAC : 00:40:05:* */
+ /* Addtron MAC : 00:90:D1:* */
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
+ sta_id.variant);
+
+ firmver = ((unsigned long)sta_id.major << 16) |
+ ((unsigned long)sta_id.minor << 8) | sta_id.variant;
+
+ priv->has_ibss = (firmver >= 0x000700); /* FIXME */
+ priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
+ priv->has_pm = (firmver >= 0x000700);
+ priv->has_hostscan = (firmver >= 0x010301);
+
+ if (firmver >= 0x000800)
+ priv->ibss_port = 0;
+ else {
+ printk(KERN_NOTICE "%s: Intersil firmware earlier "
+ "than v0.8.x - several features not supported\n",
+ dev->name);
+ priv->ibss_port = 1;
+ }
+ break;
+ }
+ printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
+ priv->fw_name);
+
+ return 0;
+}
+
+static int orinoco_init(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ struct hermes_idstring nickbuf;
+ u16 reclen;
+ int len;
+
+ /* No need to lock, the hw_unavailable flag is already set in
+ * alloc_orinocodev() */
+ priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
+
+ /* Initialize the firmware */
+ err = hermes_init(hw);
+ if (err != 0) {
+ printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
+ dev->name, err);
+ goto out;
+ }
+
+ err = determine_firmware(dev);
+ if (err != 0) {
+ printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+ dev->name);
+ goto out;
+ }
+
+ if (priv->do_fw_download) {
+#ifdef CONFIG_HERMES_CACHE_FW_ON_INIT
+ orinoco_cache_fw(priv, 0);
+#endif
+
+ err = orinoco_download(priv);
+ if (err)
+ priv->do_fw_download = 0;
+
+ /* Check firmware version again */
+ err = determine_firmware(dev);
+ if (err != 0) {
+ printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+ dev->name);
+ goto out;
+ }
+ }
+
+ if (priv->has_port3)
+ printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n",
+ dev->name);
+ if (priv->has_ibss)
+ printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
+ dev->name);
+ if (priv->has_wep) {
+ printk(KERN_DEBUG "%s: WEP supported, %s-bit key\n", dev->name,
+ priv->has_big_wep ? "104" : "40");
+ }
+ if (priv->has_wpa) {
+ printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
+ if (orinoco_mic_init(priv)) {
+ printk(KERN_ERR "%s: Failed to setup MIC crypto "
+ "algorithm. Disabling WPA support\n", dev->name);
+ priv->has_wpa = 0;
+ }
+ }
+
+ /* Now we have the firmware capabilities, allocate appropiate
+ * sized scan buffers */
+ if (orinoco_bss_data_allocate(priv))
+ goto out;
+ orinoco_bss_data_init(priv);
+
+ /* Get the MAC address */
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+ ETH_ALEN, NULL, dev->dev_addr);
+ if (err) {
+ printk(KERN_WARNING "%s: failed to read MAC address!\n",
+ dev->name);
+ goto out;
+ }
+
+ printk(KERN_DEBUG "%s: MAC address %pM\n",
+ dev->name, dev->dev_addr);
+
+ /* Get the station name */
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+ sizeof(nickbuf), &reclen, &nickbuf);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read station name\n",
+ dev->name);
+ goto out;
+ }
+ if (nickbuf.len)
+ len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
+ else
+ len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
+ memcpy(priv->nick, &nickbuf.val, len);
+ priv->nick[len] = '\0';
+
+ printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
+
+ err = orinoco_allocate_fid(dev);
+ if (err) {
+ printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
+ dev->name);
+ goto out;
+ }
+
+ /* Get allowed channels */
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
+ &priv->channel_mask);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read channel list!\n",
+ dev->name);
+ goto out;
+ }
+
+ /* Get initial AP density */
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+ &priv->ap_density);
+ if (err || priv->ap_density < 1 || priv->ap_density > 3)
+ priv->has_sensitivity = 0;
+
+ /* Get initial RTS threshold */
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+ &priv->rts_thresh);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read RTS threshold!\n",
+ dev->name);
+ goto out;
+ }
+
+ /* Get initial fragmentation settings */
+ if (priv->has_mwo)
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMWOROBUST_AGERE,
+ &priv->mwo_robust);
+ else
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+ &priv->frag_thresh);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
+ dev->name);
+ goto out;
+ }
+
+ /* Power management setup */
+ if (priv->has_pm) {
+ priv->pm_on = 0;
+ priv->pm_mcast = 1;
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMAXSLEEPDURATION,
+ &priv->pm_period);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read power management period!\n",
+ dev->name);
+ goto out;
+ }
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMHOLDOVERDURATION,
+ &priv->pm_timeout);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read power management timeout!\n",
+ dev->name);
+ goto out;
+ }
+ }
+
+ /* Preamble setup */
+ if (priv->has_preamble) {
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPREAMBLE_SYMBOL,
+ &priv->preamble);
+ if (err)
+ goto out;
+ }
+
+ /* Set up the default configuration */
+ priv->iw_mode = IW_MODE_INFRA;
+ /* By default use IEEE/IBSS ad-hoc mode if we have it */
+ priv->prefer_port3 = priv->has_port3 && (!priv->has_ibss);
+ set_port_type(priv);
+ priv->channel = 0; /* use firmware default */
+
+ priv->promiscuous = 0;
+ priv->encode_alg = IW_ENCODE_ALG_NONE;
+ priv->tx_key = 0;
+ priv->wpa_enabled = 0;
+ priv->tkip_cm_active = 0;
+ priv->key_mgmt = 0;
+ priv->wpa_ie_len = 0;
+ priv->wpa_ie = NULL;
+
+ /* Make the hardware available, as long as it hasn't been
+ * removed elsewhere (e.g. by PCMCIA hot unplug) */
+ spin_lock_irq(&priv->lock);
+ priv->hw_unavailable--;
+ spin_unlock_irq(&priv->lock);
+
+ printk(KERN_DEBUG "%s: ready\n", dev->name);
+
+ out:
+ return err;
+}
+
+static const struct net_device_ops orinoco_netdev_ops = {
+ .ndo_init = orinoco_init,
+ .ndo_open = orinoco_open,
+ .ndo_stop = orinoco_stop,
+ .ndo_start_xmit = orinoco_xmit,
+ .ndo_set_multicast_list = orinoco_set_multicast_list,
+ .ndo_change_mtu = orinoco_change_mtu,
+ .ndo_tx_timeout = orinoco_tx_timeout,
+ .ndo_get_stats = orinoco_get_stats,
+};
+
+struct net_device
+*alloc_orinocodev(int sizeof_card,
+ struct device *device,
+ int (*hard_reset)(struct orinoco_private *),
+ int (*stop_fw)(struct orinoco_private *, int))
+{
+ struct net_device *dev;
+ struct orinoco_private *priv;
+
+ dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
+ if (!dev)
+ return NULL;
+ priv = netdev_priv(dev);
+ priv->ndev = dev;
+ if (sizeof_card)
+ priv->card = (void *)((unsigned long)priv
+ + sizeof(struct orinoco_private));
+ else
+ priv->card = NULL;
+ priv->dev = device;
+
+ /* Setup / override net_device fields */
+ dev->netdev_ops = &orinoco_netdev_ops;
+ dev->watchdog_timeo = HZ; /* 1 second timeout */
+ dev->ethtool_ops = &orinoco_ethtool_ops;
+ dev->wireless_handlers = &orinoco_handler_def;
+#ifdef WIRELESS_SPY
+ priv->wireless_data.spy_data = &priv->spy_data;
+ dev->wireless_data = &priv->wireless_data;
+#endif
+ /* we use the default eth_mac_addr for setting the MAC addr */
+
+ /* Reserve space in skb for the SNAP header */
+ dev->hard_header_len += ENCAPS_OVERHEAD;
+
+ /* Set up default callbacks */
+ priv->hard_reset = hard_reset;
+ priv->stop_fw = stop_fw;
+
+ spin_lock_init(&priv->lock);
+ priv->open = 0;
+ priv->hw_unavailable = 1; /* orinoco_init() must clear this
+ * before anything else touches the
+ * hardware */
+ INIT_WORK(&priv->reset_work, orinoco_reset);
+ INIT_WORK(&priv->join_work, orinoco_join_ap);
+ INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
+
+ INIT_LIST_HEAD(&priv->rx_list);
+ tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
+ (unsigned long) dev);
+
+ netif_carrier_off(dev);
+ priv->last_linkstatus = 0xffff;
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+ priv->cached_pri_fw = NULL;
+ priv->cached_fw = NULL;
+#endif
+
+ /* Register PM notifiers */
+ orinoco_register_pm_notifier(priv);
+
+ return dev;
+}
+EXPORT_SYMBOL(alloc_orinocodev);
+
+void free_orinocodev(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_rx_data *rx_data, *temp;
+
+ /* If the tasklet is scheduled when we call tasklet_kill it
+ * will run one final time. However the tasklet will only
+ * drain priv->rx_list if the hw is still available. */
+ tasklet_kill(&priv->rx_tasklet);
+
+ /* Explicitly drain priv->rx_list */
+ list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
+ list_del(&rx_data->list);
+
+ dev_kfree_skb(rx_data->skb);
+ kfree(rx_data->desc);
+ kfree(rx_data);
+ }
+
+ orinoco_unregister_pm_notifier(priv);
+ orinoco_uncache_fw(priv);
+
+ priv->wpa_ie_len = 0;
+ kfree(priv->wpa_ie);
+ orinoco_mic_free(priv);
+ orinoco_bss_data_free(priv);
+ free_netdev(dev);
+}
+EXPORT_SYMBOL(free_orinocodev);
+
+static void orinoco_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
+ strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
+ if (dev->dev.parent)
+ strncpy(info->bus_info, dev_name(dev->dev.parent),
+ sizeof(info->bus_info) - 1);
+ else
+ snprintf(info->bus_info, sizeof(info->bus_info) - 1,
+ "PCMCIA %p", priv->hw.iobase);
+}
+
+static const struct ethtool_ops orinoco_ethtool_ops = {
+ .get_drvinfo = orinoco_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+};
+
+/********************************************************************/
+/* Module initialization */
+/********************************************************************/
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+ " (David Gibson <hermes@gibson.dropbear.id.au>, "
+ "Pavel Roskin <proski@gnu.org>, et al)";
+
+static int __init init_orinoco(void)
+{
+ printk(KERN_DEBUG "%s\n", version);
+ return 0;
+}
+
+static void __exit exit_orinoco(void)
+{
+}
+
+module_init(init_orinoco);
+module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h
new file mode 100644
index 00000000000..af2bae4fe39
--- /dev/null
+++ b/drivers/net/wireless/orinoco/main.h
@@ -0,0 +1,63 @@
+/* Exports from main to helper modules
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_MAIN_H_
+#define _ORINOCO_MAIN_H_
+
+#include <linux/ieee80211.h>
+#include "orinoco.h"
+
+/********************************************************************/
+/* Compile time configuration and compatibility stuff */
+/********************************************************************/
+
+/* We do this this way to avoid ifdefs in the actual code */
+#ifdef WIRELESS_SPY
+#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
+#else
+#define SPY_NUMBER(priv) 0
+#endif /* WIRELESS_SPY */
+
+/********************************************************************/
+
+/* Export module parameter */
+extern int force_monitor;
+
+/* Forward declarations */
+struct net_device;
+struct work_struct;
+
+void set_port_type(struct orinoco_private *priv);
+int __orinoco_program_rids(struct net_device *dev);
+void orinoco_reset(struct work_struct *work);
+
+
+/* Information element helpers - find a home for these... */
+static inline u8 *orinoco_get_ie(u8 *data, size_t len,
+ enum ieee80211_eid eid)
+{
+ u8 *p = data;
+ while ((p + 2) < (data + len)) {
+ if (p[0] == eid)
+ return p;
+ p += p[1] + 2;
+ }
+ return NULL;
+}
+
+#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
+#define WPA_SELECTOR_LEN 4
+static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
+{
+ u8 *p = data;
+ while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
+ if ((p[0] == WLAN_EID_GENERIC) &&
+ (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
+ return p;
+ p += p[1] + 2;
+ }
+ return NULL;
+}
+
+#endif /* _ORINOCO_MAIN_H_ */
diff --git a/drivers/net/wireless/orinoco/mic.c b/drivers/net/wireless/orinoco/mic.c
new file mode 100644
index 00000000000..c03e7f54d1b
--- /dev/null
+++ b/drivers/net/wireless/orinoco/mic.c
@@ -0,0 +1,79 @@
+/* Orinoco MIC helpers
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/if_ether.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+
+#include "orinoco.h"
+#include "mic.h"
+
+/********************************************************************/
+/* Michael MIC crypto setup */
+/********************************************************************/
+int orinoco_mic_init(struct orinoco_private *priv)
+{
+ priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
+ if (IS_ERR(priv->tx_tfm_mic)) {
+ printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
+ "crypto API michael_mic\n");
+ priv->tx_tfm_mic = NULL;
+ return -ENOMEM;
+ }
+
+ priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
+ if (IS_ERR(priv->rx_tfm_mic)) {
+ printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
+ "crypto API michael_mic\n");
+ priv->rx_tfm_mic = NULL;
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void orinoco_mic_free(struct orinoco_private *priv)
+{
+ if (priv->tx_tfm_mic)
+ crypto_free_hash(priv->tx_tfm_mic);
+ if (priv->rx_tfm_mic)
+ crypto_free_hash(priv->rx_tfm_mic);
+}
+
+int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
+ u8 *da, u8 *sa, u8 priority,
+ u8 *data, size_t data_len, u8 *mic)
+{
+ struct hash_desc desc;
+ struct scatterlist sg[2];
+ u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
+
+ if (tfm_michael == NULL) {
+ printk(KERN_WARNING "orinoco_mic: tfm_michael == NULL\n");
+ return -1;
+ }
+
+ /* Copy header into buffer. We need the padding on the end zeroed */
+ memcpy(&hdr[0], da, ETH_ALEN);
+ memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
+ hdr[ETH_ALEN*2] = priority;
+ hdr[ETH_ALEN*2+1] = 0;
+ hdr[ETH_ALEN*2+2] = 0;
+ hdr[ETH_ALEN*2+3] = 0;
+
+ /* Use scatter gather to MIC header and data in one go */
+ sg_init_table(sg, 2);
+ sg_set_buf(&sg[0], hdr, sizeof(hdr));
+ sg_set_buf(&sg[1], data, data_len);
+
+ if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
+ return -1;
+
+ desc.tfm = tfm_michael;
+ desc.flags = 0;
+ return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
+ mic);
+}
diff --git a/drivers/net/wireless/orinoco/mic.h b/drivers/net/wireless/orinoco/mic.h
new file mode 100644
index 00000000000..04d05bc566d
--- /dev/null
+++ b/drivers/net/wireless/orinoco/mic.h
@@ -0,0 +1,22 @@
+/* Orinoco MIC helpers
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_MIC_H_
+#define _ORINOCO_MIC_H_
+
+#include <linux/types.h>
+
+#define MICHAEL_MIC_LEN 8
+
+/* Forward declarations */
+struct orinoco_private;
+struct crypto_hash;
+
+int orinoco_mic_init(struct orinoco_private *priv);
+void orinoco_mic_free(struct orinoco_private *priv);
+int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
+ u8 *da, u8 *sa, u8 priority,
+ u8 *data, size_t data_len, u8 *mic);
+
+#endif /* ORINOCO_MIC_H */
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
deleted file mode 100644
index c3bb85e0251..00000000000
--- a/drivers/net/wireless/orinoco/orinoco.c
+++ /dev/null
@@ -1,6152 +0,0 @@
-/* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
- *
- * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
- * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
- *
- * Current maintainers (as of 29 September 2003) are:
- * Pavel Roskin <proski AT gnu.org>
- * and David Gibson <hermes AT gibson.dropbear.id.au>
- *
- * (C) Copyright David Gibson, IBM Corporation 2001-2003.
- * Copyright (C) 2000 David Gibson, Linuxcare Australia.
- * With some help from :
- * Copyright (C) 2001 Jean Tourrilhes, HP Labs
- * Copyright (C) 2001 Benjamin Herrenschmidt
- *
- * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
- *
- * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
- * AT fasta.fh-dortmund.de>
- * http://www.stud.fh-dortmund.de/~andy/wvlan/
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds AT users.sourceforge.net>. Portions created by David
- * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights
- * Reserved.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL. */
-
-/*
- * TODO
- * o Handle de-encapsulation within network layer, provide 802.11
- * headers (patch from Thomas 'Dent' Mirlacher)
- * o Fix possible races in SPY handling.
- * o Disconnect wireless extensions from fundamental configuration.
- * o (maybe) Software WEP support (patch from Stano Meduna).
- * o (maybe) Use multiple Tx buffers - driver handling queue
- * rather than firmware.
- */
-
-/* Locking and synchronization:
- *
- * The basic principle is that everything is serialized through a
- * single spinlock, priv->lock. The lock is used in user, bh and irq
- * context, so when taken outside hardirq context it should always be
- * taken with interrupts disabled. The lock protects both the
- * hardware and the struct orinoco_private.
- *
- * Another flag, priv->hw_unavailable indicates that the hardware is
- * unavailable for an extended period of time (e.g. suspended, or in
- * the middle of a hard reset). This flag is protected by the
- * spinlock. All code which touches the hardware should check the
- * flag after taking the lock, and if it is set, give up on whatever
- * they are doing and drop the lock again. The orinoco_lock()
- * function handles this (it unlocks and returns -EBUSY if
- * hw_unavailable is non-zero).
- */
-
-#define DRIVER_NAME "orinoco"
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/firmware.h>
-#include <linux/suspend.h>
-#include <linux/if_arp.h>
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-#include <net/iw_handler.h>
-
-#include <linux/scatterlist.h>
-#include <linux/crypto.h>
-
-#include "hermes_rid.h"
-#include "hermes_dld.h"
-#include "orinoco.h"
-
-/********************************************************************/
-/* Module information */
-/********************************************************************/
-
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
-MODULE_LICENSE("Dual MPL/GPL");
-
-/* Level of debugging. Used in the macros in orinoco.h */
-#ifdef ORINOCO_DEBUG
-int orinoco_debug = ORINOCO_DEBUG;
-module_param(orinoco_debug, int, 0644);
-MODULE_PARM_DESC(orinoco_debug, "Debug level");
-EXPORT_SYMBOL(orinoco_debug);
-#endif
-
-static int suppress_linkstatus; /* = 0 */
-module_param(suppress_linkstatus, bool, 0644);
-MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
-static int ignore_disconnect; /* = 0 */
-module_param(ignore_disconnect, int, 0644);
-MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
-
-static int force_monitor; /* = 0 */
-module_param(force_monitor, int, 0644);
-MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
-
-/********************************************************************/
-/* Compile time configuration and compatibility stuff */
-/********************************************************************/
-
-/* We do this this way to avoid ifdefs in the actual code */
-#ifdef WIRELESS_SPY
-#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
-#else
-#define SPY_NUMBER(priv) 0
-#endif /* WIRELESS_SPY */
-
-/********************************************************************/
-/* Internal constants */
-/********************************************************************/
-
-/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
-static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
-
-#define ORINOCO_MIN_MTU 256
-#define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
-
-#define SYMBOL_MAX_VER_LEN (14)
-#define USER_BAP 0
-#define IRQ_BAP 1
-#define MAX_IRQLOOPS_PER_IRQ 10
-#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
- * how many events the
- * device could
- * legitimately generate */
-#define SMALL_KEY_SIZE 5
-#define LARGE_KEY_SIZE 13
-#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
-
-#define DUMMY_FID 0xFFFF
-
-/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
- HERMES_MAX_MULTICAST : 0)*/
-#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST)
-
-#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \
- | HERMES_EV_TX | HERMES_EV_TXEXC \
- | HERMES_EV_WTERR | HERMES_EV_INFO \
- | HERMES_EV_INFDROP )
-
-#define MAX_RID_LEN 1024
-
-static const struct iw_handler_def orinoco_handler_def;
-static const struct ethtool_ops orinoco_ethtool_ops;
-
-/********************************************************************/
-/* Data tables */
-/********************************************************************/
-
-/* The frequency of each channel in MHz */
-static const long channel_frequency[] = {
- 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484
-};
-#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
-
-/* This tables gives the actual meanings of the bitrate IDs returned
- * by the firmware. */
-static struct {
- int bitrate; /* in 100s of kilobits */
- int automatic;
- u16 agere_txratectrl;
- u16 intersil_txratectrl;
-} bitrate_table[] = {
- {110, 1, 3, 15}, /* Entry 0 is the default */
- {10, 0, 1, 1},
- {10, 1, 1, 1},
- {20, 0, 2, 2},
- {20, 1, 6, 3},
- {55, 0, 4, 4},
- {55, 1, 7, 7},
- {110, 0, 5, 8},
-};
-#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
-
-/********************************************************************/
-/* Data types */
-/********************************************************************/
-
-/* Beginning of the Tx descriptor, used in TxExc handling */
-struct hermes_txexc_data {
- struct hermes_tx_descriptor desc;
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
-} __attribute__ ((packed));
-
-/* Rx frame header except compatibility 802.3 header */
-struct hermes_rx_descriptor {
- /* Control */
- __le16 status;
- __le32 time;
- u8 silence;
- u8 signal;
- u8 rate;
- u8 rxflow;
- __le32 reserved;
-
- /* 802.11 header */
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- __le16 seq_ctl;
- u8 addr4[ETH_ALEN];
-
- /* Data length */
- __le16 data_len;
-} __attribute__ ((packed));
-
-/********************************************************************/
-/* Function prototypes */
-/********************************************************************/
-
-static int __orinoco_program_rids(struct net_device *dev);
-static void __orinoco_set_multicast_list(struct net_device *dev);
-
-/********************************************************************/
-/* Michael MIC crypto setup */
-/********************************************************************/
-#define MICHAEL_MIC_LEN 8
-static int orinoco_mic_init(struct orinoco_private *priv)
-{
- priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
- if (IS_ERR(priv->tx_tfm_mic)) {
- printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
- "crypto API michael_mic\n");
- priv->tx_tfm_mic = NULL;
- return -ENOMEM;
- }
-
- priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
- if (IS_ERR(priv->rx_tfm_mic)) {
- printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
- "crypto API michael_mic\n");
- priv->rx_tfm_mic = NULL;
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void orinoco_mic_free(struct orinoco_private *priv)
-{
- if (priv->tx_tfm_mic)
- crypto_free_hash(priv->tx_tfm_mic);
- if (priv->rx_tfm_mic)
- crypto_free_hash(priv->rx_tfm_mic);
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 *key,
- u8 *da, u8 *sa, u8 priority,
- u8 *data, size_t data_len, u8 *mic)
-{
- struct hash_desc desc;
- struct scatterlist sg[2];
- u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
-
- if (tfm_michael == NULL) {
- printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
- return -1;
- }
-
- /* Copy header into buffer. We need the padding on the end zeroed */
- memcpy(&hdr[0], da, ETH_ALEN);
- memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
- hdr[ETH_ALEN*2] = priority;
- hdr[ETH_ALEN*2+1] = 0;
- hdr[ETH_ALEN*2+2] = 0;
- hdr[ETH_ALEN*2+3] = 0;
-
- /* Use scatter gather to MIC header and data in one go */
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], hdr, sizeof(hdr));
- sg_set_buf(&sg[1], data, data_len);
-
- if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
- return -1;
-
- desc.tfm = tfm_michael;
- desc.flags = 0;
- return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
- mic);
-}
-
-/********************************************************************/
-/* Internal helper functions */
-/********************************************************************/
-
-static inline void set_port_type(struct orinoco_private *priv)
-{
- switch (priv->iw_mode) {
- case IW_MODE_INFRA:
- priv->port_type = 1;
- priv->createibss = 0;
- break;
- case IW_MODE_ADHOC:
- if (priv->prefer_port3) {
- priv->port_type = 3;
- priv->createibss = 0;
- } else {
- priv->port_type = priv->ibss_port;
- priv->createibss = 1;
- }
- break;
- case IW_MODE_MONITOR:
- priv->port_type = 3;
- priv->createibss = 0;
- break;
- default:
- printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
- priv->ndev->name);
- }
-}
-
-#define ORINOCO_MAX_BSS_COUNT 64
-static int orinoco_bss_data_allocate(struct orinoco_private *priv)
-{
- if (priv->bss_xbss_data)
- return 0;
-
- if (priv->has_ext_scan)
- priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
- sizeof(struct xbss_element),
- GFP_KERNEL);
- else
- priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
- sizeof(struct bss_element),
- GFP_KERNEL);
-
- if (!priv->bss_xbss_data) {
- printk(KERN_WARNING "Out of memory allocating beacons");
- return -ENOMEM;
- }
- return 0;
-}
-
-static void orinoco_bss_data_free(struct orinoco_private *priv)
-{
- kfree(priv->bss_xbss_data);
- priv->bss_xbss_data = NULL;
-}
-
-#define PRIV_BSS ((struct bss_element *)priv->bss_xbss_data)
-#define PRIV_XBSS ((struct xbss_element *)priv->bss_xbss_data)
-static void orinoco_bss_data_init(struct orinoco_private *priv)
-{
- int i;
-
- INIT_LIST_HEAD(&priv->bss_free_list);
- INIT_LIST_HEAD(&priv->bss_list);
- if (priv->has_ext_scan)
- for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
- list_add_tail(&(PRIV_XBSS[i].list),
- &priv->bss_free_list);
- else
- for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
- list_add_tail(&(PRIV_BSS[i].list),
- &priv->bss_free_list);
-
-}
-
-static inline u8 *orinoco_get_ie(u8 *data, size_t len,
- enum ieee80211_eid eid)
-{
- u8 *p = data;
- while ((p + 2) < (data + len)) {
- if (p[0] == eid)
- return p;
- p += p[1] + 2;
- }
- return NULL;
-}
-
-#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
-#define WPA_SELECTOR_LEN 4
-static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
-{
- u8 *p = data;
- while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
- if ((p[0] == WLAN_EID_GENERIC) &&
- (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
- return p;
- p += p[1] + 2;
- }
- return NULL;
-}
-
-
-/********************************************************************/
-/* Download functionality */
-/********************************************************************/
-
-struct fw_info {
- char *pri_fw;
- char *sta_fw;
- char *ap_fw;
- u32 pda_addr;
- u16 pda_size;
-};
-
-const static struct fw_info orinoco_fw[] = {
- { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
- { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
- { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 }
-};
-
-/* Structure used to access fields in FW
- * Make sure LE decoding macros are used
- */
-struct orinoco_fw_header {
- char hdr_vers[6]; /* ASCII string for header version */
- __le16 headersize; /* Total length of header */
- __le32 entry_point; /* NIC entry point */
- __le32 blocks; /* Number of blocks to program */
- __le32 block_offset; /* Offset of block data from eof header */
- __le32 pdr_offset; /* Offset to PDR data from eof header */
- __le32 pri_offset; /* Offset to primary plug data */
- __le32 compat_offset; /* Offset to compatibility data*/
- char signature[0]; /* FW signature length headersize-20 */
-} __attribute__ ((packed));
-
-/* Download either STA or AP firmware into the card. */
-static int
-orinoco_dl_firmware(struct orinoco_private *priv,
- const struct fw_info *fw,
- int ap)
-{
- /* Plug Data Area (PDA) */
- __le16 *pda;
-
- hermes_t *hw = &priv->hw;
- const struct firmware *fw_entry;
- const struct orinoco_fw_header *hdr;
- const unsigned char *first_block;
- const unsigned char *end;
- const char *firmware;
- struct net_device *dev = priv->ndev;
- int err = 0;
-
- pda = kzalloc(fw->pda_size, GFP_KERNEL);
- if (!pda)
- return -ENOMEM;
-
- if (ap)
- firmware = fw->ap_fw;
- else
- firmware = fw->sta_fw;
-
- printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
- dev->name, firmware);
-
- /* Read current plug data */
- err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
- printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
- if (err)
- goto free;
-
- if (!priv->cached_fw) {
- err = request_firmware(&fw_entry, firmware, priv->dev);
-
- if (err) {
- printk(KERN_ERR "%s: Cannot find firmware %s\n",
- dev->name, firmware);
- err = -ENOENT;
- goto free;
- }
- } else
- fw_entry = priv->cached_fw;
-
- hdr = (const struct orinoco_fw_header *) fw_entry->data;
-
- /* Enable aux port to allow programming */
- err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
- printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
- if (err != 0)
- goto abort;
-
- /* Program data */
- first_block = (fw_entry->data +
- le16_to_cpu(hdr->headersize) +
- le32_to_cpu(hdr->block_offset));
- end = fw_entry->data + fw_entry->size;
-
- err = hermes_program(hw, first_block, end);
- printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
- if (err != 0)
- goto abort;
-
- /* Update production data */
- first_block = (fw_entry->data +
- le16_to_cpu(hdr->headersize) +
- le32_to_cpu(hdr->pdr_offset));
-
- err = hermes_apply_pda_with_defaults(hw, first_block, pda);
- printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
- if (err)
- goto abort;
-
- /* Tell card we've finished */
- err = hermesi_program_end(hw);
- printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
- if (err != 0)
- goto abort;
-
- /* Check if we're running */
- printk(KERN_DEBUG "%s: hermes_present returned %d\n",
- dev->name, hermes_present(hw));
-
-abort:
- /* If we requested the firmware, release it. */
- if (!priv->cached_fw)
- release_firmware(fw_entry);
-
-free:
- kfree(pda);
- return err;
-}
-
-/* End markers */
-#define TEXT_END 0x1A /* End of text header */
-
-/*
- * Process a firmware image - stop the card, load the firmware, reset
- * the card and make sure it responds. For the secondary firmware take
- * care of the PDA - read it and then write it on top of the firmware.
- */
-static int
-symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
- const unsigned char *image, const unsigned char *end,
- int secondary)
-{
- hermes_t *hw = &priv->hw;
- int ret = 0;
- const unsigned char *ptr;
- const unsigned char *first_block;
-
- /* Plug Data Area (PDA) */
- __le16 *pda = NULL;
-
- /* Binary block begins after the 0x1A marker */
- ptr = image;
- while (*ptr++ != TEXT_END);
- first_block = ptr;
-
- /* Read the PDA from EEPROM */
- if (secondary) {
- pda = kzalloc(fw->pda_size, GFP_KERNEL);
- if (!pda)
- return -ENOMEM;
-
- ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
- if (ret)
- goto free;
- }
-
- /* Stop the firmware, so that it can be safely rewritten */
- if (priv->stop_fw) {
- ret = priv->stop_fw(priv, 1);
- if (ret)
- goto free;
- }
-
- /* Program the adapter with new firmware */
- ret = hermes_program(hw, first_block, end);
- if (ret)
- goto free;
-
- /* Write the PDA to the adapter */
- if (secondary) {
- size_t len = hermes_blocks_length(first_block);
- ptr = first_block + len;
- ret = hermes_apply_pda(hw, ptr, pda);
- kfree(pda);
- if (ret)
- return ret;
- }
-
- /* Run the firmware */
- if (priv->stop_fw) {
- ret = priv->stop_fw(priv, 0);
- if (ret)
- return ret;
- }
-
- /* Reset hermes chip and make sure it responds */
- ret = hermes_init(hw);
-
- /* hermes_reset() should return 0 with the secondary firmware */
- if (secondary && ret != 0)
- return -ENODEV;
-
- /* And this should work with any firmware */
- if (!hermes_present(hw))
- return -ENODEV;
-
- return 0;
-
-free:
- kfree(pda);
- return ret;
-}
-
-
-/*
- * Download the firmware into the card, this also does a PCMCIA soft
- * reset on the card, to make sure it's in a sane state.
- */
-static int
-symbol_dl_firmware(struct orinoco_private *priv,
- const struct fw_info *fw)
-{
- struct net_device *dev = priv->ndev;
- int ret;
- const struct firmware *fw_entry;
-
- if (!priv->cached_pri_fw) {
- if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
- printk(KERN_ERR "%s: Cannot find firmware: %s\n",
- dev->name, fw->pri_fw);
- return -ENOENT;
- }
- } else
- fw_entry = priv->cached_pri_fw;
-
- /* Load primary firmware */
- ret = symbol_dl_image(priv, fw, fw_entry->data,
- fw_entry->data + fw_entry->size, 0);
-
- if (!priv->cached_pri_fw)
- release_firmware(fw_entry);
- if (ret) {
- printk(KERN_ERR "%s: Primary firmware download failed\n",
- dev->name);
- return ret;
- }
-
- if (!priv->cached_fw) {
- if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
- printk(KERN_ERR "%s: Cannot find firmware: %s\n",
- dev->name, fw->sta_fw);
- return -ENOENT;
- }
- } else
- fw_entry = priv->cached_fw;
-
- /* Load secondary firmware */
- ret = symbol_dl_image(priv, fw, fw_entry->data,
- fw_entry->data + fw_entry->size, 1);
- if (!priv->cached_fw)
- release_firmware(fw_entry);
- if (ret) {
- printk(KERN_ERR "%s: Secondary firmware download failed\n",
- dev->name);
- }
-
- return ret;
-}
-
-static int orinoco_download(struct orinoco_private *priv)
-{
- int err = 0;
- /* Reload firmware */
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- /* case FIRMWARE_TYPE_INTERSIL: */
- err = orinoco_dl_firmware(priv,
- &orinoco_fw[priv->firmware_type], 0);
- break;
-
- case FIRMWARE_TYPE_SYMBOL:
- err = symbol_dl_firmware(priv,
- &orinoco_fw[priv->firmware_type]);
- break;
- case FIRMWARE_TYPE_INTERSIL:
- break;
- }
- /* TODO: if we fail we probably need to reinitialise
- * the driver */
-
- return err;
-}
-
-#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
-static void orinoco_cache_fw(struct orinoco_private *priv, int ap)
-{
- const struct firmware *fw_entry = NULL;
- const char *pri_fw;
- const char *fw;
-
- pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
- if (ap)
- fw = orinoco_fw[priv->firmware_type].ap_fw;
- else
- fw = orinoco_fw[priv->firmware_type].sta_fw;
-
- if (pri_fw) {
- if (request_firmware(&fw_entry, pri_fw, priv->dev) == 0)
- priv->cached_pri_fw = fw_entry;
- }
-
- if (fw) {
- if (request_firmware(&fw_entry, fw, priv->dev) == 0)
- priv->cached_fw = fw_entry;
- }
-}
-
-static void orinoco_uncache_fw(struct orinoco_private *priv)
-{
- if (priv->cached_pri_fw)
- release_firmware(priv->cached_pri_fw);
- if (priv->cached_fw)
- release_firmware(priv->cached_fw);
-
- priv->cached_pri_fw = NULL;
- priv->cached_fw = NULL;
-}
-#else
-#define orinoco_cache_fw(priv, ap)
-#define orinoco_uncache_fw(priv)
-#endif
-
-/********************************************************************/
-/* Device methods */
-/********************************************************************/
-
-static int orinoco_open(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = __orinoco_up(dev);
-
- if (! err)
- priv->open = 1;
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_stop(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = 0;
-
- /* We mustn't use orinoco_lock() here, because we need to be
- able to close the interface even if hw_unavailable is set
- (e.g. as we're released after a PC Card removal) */
- spin_lock_irq(&priv->lock);
-
- priv->open = 0;
-
- err = __orinoco_down(dev);
-
- spin_unlock_irq(&priv->lock);
-
- return err;
-}
-
-static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- return &priv->stats;
-}
-
-static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- struct iw_statistics *wstats = &priv->wstats;
- int err;
- unsigned long flags;
-
- if (! netif_device_present(dev)) {
- printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
- dev->name);
- return NULL; /* FIXME: Can we do better than this? */
- }
-
- /* If busy, return the old stats. Returning NULL may cause
- * the interface to disappear from /proc/net/wireless */
- if (orinoco_lock(priv, &flags) != 0)
- return wstats;
-
- /* We can't really wait for the tallies inquiry command to
- * complete, so we just use the previous results and trigger
- * a new tallies inquiry command for next time - Jean II */
- /* FIXME: Really we should wait for the inquiry to come back -
- * as it is the stats we give don't make a whole lot of sense.
- * Unfortunately, it's not clear how to do that within the
- * wireless extensions framework: I think we're in user
- * context, but a lock seems to be held by the time we get in
- * here so we're not safe to sleep here. */
- hermes_inquire(hw, HERMES_INQ_TALLIES);
-
- if (priv->iw_mode == IW_MODE_ADHOC) {
- memset(&wstats->qual, 0, sizeof(wstats->qual));
- /* If a spy address is defined, we report stats of the
- * first spy address - Jean II */
- if (SPY_NUMBER(priv)) {
- wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
- wstats->qual.level = priv->spy_data.spy_stat[0].level;
- wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
- wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
- }
- } else {
- struct {
- __le16 qual, signal, noise, unused;
- } __attribute__ ((packed)) cq;
-
- err = HERMES_READ_RECORD(hw, USER_BAP,
- HERMES_RID_COMMSQUALITY, &cq);
-
- if (!err) {
- wstats->qual.qual = (int)le16_to_cpu(cq.qual);
- wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
- wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- }
- }
-
- orinoco_unlock(priv, &flags);
- return wstats;
-}
-
-static void orinoco_set_multicast_list(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0) {
- printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
- "called when hw_unavailable\n", dev->name);
- return;
- }
-
- __orinoco_set_multicast_list(dev);
- orinoco_unlock(priv, &flags);
-}
-
-static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
- return -EINVAL;
-
- /* MTU + encapsulation + header length */
- if ( (new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
- (priv->nicbuf_size - ETH_HLEN) )
- return -EINVAL;
-
- dev->mtu = new_mtu;
-
- return 0;
-}
-
-/********************************************************************/
-/* Tx path */
-/********************************************************************/
-
-static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- hermes_t *hw = &priv->hw;
- int err = 0;
- u16 txfid = priv->txfid;
- struct ethhdr *eh;
- int tx_control;
- unsigned long flags;
-
- if (! netif_running(dev)) {
- printk(KERN_ERR "%s: Tx on stopped device!\n",
- dev->name);
- return NETDEV_TX_BUSY;
- }
-
- if (netif_queue_stopped(dev)) {
- printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
- dev->name);
- return NETDEV_TX_BUSY;
- }
-
- if (orinoco_lock(priv, &flags) != 0) {
- printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
- dev->name);
- return NETDEV_TX_BUSY;
- }
-
- if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
- /* Oops, the firmware hasn't established a connection,
- silently drop the packet (this seems to be the
- safest approach). */
- goto drop;
- }
-
- /* Check packet length */
- if (skb->len < ETH_HLEN)
- goto drop;
-
- tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
-
- if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
- tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
- HERMES_TXCTRL_MIC;
-
- if (priv->has_alt_txcntl) {
- /* WPA enabled firmwares have tx_cntl at the end of
- * the 802.11 header. So write zeroed descriptor and
- * 802.11 header at the same time
- */
- char desc[HERMES_802_3_OFFSET];
- __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
-
- memset(&desc, 0, sizeof(desc));
-
- *txcntl = cpu_to_le16(tx_control);
- err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
- txfid, 0);
- if (err) {
- if (net_ratelimit())
- printk(KERN_ERR "%s: Error %d writing Tx "
- "descriptor to BAP\n", dev->name, err);
- goto busy;
- }
- } else {
- struct hermes_tx_descriptor desc;
-
- memset(&desc, 0, sizeof(desc));
-
- desc.tx_control = cpu_to_le16(tx_control);
- err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
- txfid, 0);
- if (err) {
- if (net_ratelimit())
- printk(KERN_ERR "%s: Error %d writing Tx "
- "descriptor to BAP\n", dev->name, err);
- goto busy;
- }
-
- /* Clear the 802.11 header and data length fields - some
- * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
- * if this isn't done. */
- hermes_clear_words(hw, HERMES_DATA0,
- HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
- }
-
- eh = (struct ethhdr *)skb->data;
-
- /* Encapsulate Ethernet-II frames */
- if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
- struct header_struct {
- struct ethhdr eth; /* 802.3 header */
- u8 encap[6]; /* 802.2 header */
- } __attribute__ ((packed)) hdr;
-
- /* Strip destination and source from the data */
- skb_pull(skb, 2 * ETH_ALEN);
-
- /* And move them to a separate header */
- memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
- hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
- memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
-
- /* Insert the SNAP header */
- if (skb_headroom(skb) < sizeof(hdr)) {
- printk(KERN_ERR
- "%s: Not enough headroom for 802.2 headers %d\n",
- dev->name, skb_headroom(skb));
- goto drop;
- }
- eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
- memcpy(eh, &hdr, sizeof(hdr));
- }
-
- err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
- txfid, HERMES_802_3_OFFSET);
- if (err) {
- printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
- dev->name, err);
- goto busy;
- }
-
- /* Calculate Michael MIC */
- if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
- u8 mic_buf[MICHAEL_MIC_LEN + 1];
- u8 *mic;
- size_t offset;
- size_t len;
-
- if (skb->len % 2) {
- /* MIC start is on an odd boundary */
- mic_buf[0] = skb->data[skb->len - 1];
- mic = &mic_buf[1];
- offset = skb->len - 1;
- len = MICHAEL_MIC_LEN + 1;
- } else {
- mic = &mic_buf[0];
- offset = skb->len;
- len = MICHAEL_MIC_LEN;
- }
-
- michael_mic(priv->tx_tfm_mic,
- priv->tkip_key[priv->tx_key].tx_mic,
- eh->h_dest, eh->h_source, 0 /* priority */,
- skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
-
- /* Write the MIC */
- err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
- txfid, HERMES_802_3_OFFSET + offset);
- if (err) {
- printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
- dev->name, err);
- goto busy;
- }
- }
-
- /* Finally, we actually initiate the send */
- netif_stop_queue(dev);
-
- err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
- txfid, NULL);
- if (err) {
- netif_start_queue(dev);
- if (net_ratelimit())
- printk(KERN_ERR "%s: Error %d transmitting packet\n",
- dev->name, err);
- goto busy;
- }
-
- dev->trans_start = jiffies;
- stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
- goto ok;
-
- drop:
- stats->tx_errors++;
- stats->tx_dropped++;
-
- ok:
- orinoco_unlock(priv, &flags);
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-
- busy:
- if (err == -EIO)
- schedule_work(&priv->reset_work);
- orinoco_unlock(priv, &flags);
- return NETDEV_TX_BUSY;
-}
-
-static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- u16 fid = hermes_read_regn(hw, ALLOCFID);
-
- if (fid != priv->txfid) {
- if (fid != DUMMY_FID)
- printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
- dev->name, fid);
- return;
- }
-
- hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
-}
-
-static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
-
- stats->tx_packets++;
-
- netif_wake_queue(dev);
-
- hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
-}
-
-static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- u16 fid = hermes_read_regn(hw, TXCOMPLFID);
- u16 status;
- struct hermes_txexc_data hdr;
- int err = 0;
-
- if (fid == DUMMY_FID)
- return; /* Nothing's really happened */
-
- /* Read part of the frame header - we need status and addr1 */
- err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
- sizeof(struct hermes_txexc_data),
- fid, 0);
-
- hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
- stats->tx_errors++;
-
- if (err) {
- printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
- "(FID=%04X error %d)\n",
- dev->name, fid, err);
- return;
- }
-
- DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
- err, fid);
-
- /* We produce a TXDROP event only for retry or lifetime
- * exceeded, because that's the only status that really mean
- * that this particular node went away.
- * Other errors means that *we* screwed up. - Jean II */
- status = le16_to_cpu(hdr.desc.status);
- if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
- union iwreq_data wrqu;
-
- /* Copy 802.11 dest address.
- * We use the 802.11 header because the frame may
- * not be 802.3 or may be mangled...
- * In Ad-Hoc mode, it will be the node address.
- * In managed mode, it will be most likely the AP addr
- * User space will figure out how to convert it to
- * whatever it needs (IP address or else).
- * - Jean II */
- memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
- wrqu.addr.sa_family = ARPHRD_ETHER;
-
- /* Send event to user space */
- wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
- }
-
- netif_wake_queue(dev);
-}
-
-static void orinoco_tx_timeout(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- struct hermes *hw = &priv->hw;
-
- printk(KERN_WARNING "%s: Tx timeout! "
- "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
- dev->name, hermes_read_regn(hw, ALLOCFID),
- hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
-
- stats->tx_errors++;
-
- schedule_work(&priv->reset_work);
-}
-
-/********************************************************************/
-/* Rx path (data frames) */
-/********************************************************************/
-
-/* Does the frame have a SNAP header indicating it should be
- * de-encapsulated to Ethernet-II? */
-static inline int is_ethersnap(void *_hdr)
-{
- u8 *hdr = _hdr;
-
- /* We de-encapsulate all packets which, a) have SNAP headers
- * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
- * and where b) the OUI of the SNAP header is 00:00:00 or
- * 00:00:f8 - we need both because different APs appear to use
- * different OUIs for some reason */
- return (memcmp(hdr, &encaps_hdr, 5) == 0)
- && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
-}
-
-static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
- int level, int noise)
-{
- struct iw_quality wstats;
- wstats.level = level - 0x95;
- wstats.noise = noise - 0x95;
- wstats.qual = (level > noise) ? (level - noise) : 0;
- wstats.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- /* Update spy records */
- wireless_spy_update(dev, mac, &wstats);
-}
-
-static void orinoco_stat_gather(struct net_device *dev,
- struct sk_buff *skb,
- struct hermes_rx_descriptor *desc)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- /* Using spy support with lots of Rx packets, like in an
- * infrastructure (AP), will really slow down everything, because
- * the MAC address must be compared to each entry of the spy list.
- * If the user really asks for it (set some address in the
- * spy list), we do it, but he will pay the price.
- * Note that to get here, you need both WIRELESS_SPY
- * compiled in AND some addresses in the list !!!
- */
- /* Note : gcc will optimise the whole section away if
- * WIRELESS_SPY is not defined... - Jean II */
- if (SPY_NUMBER(priv)) {
- orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
- desc->signal, desc->silence);
- }
-}
-
-/*
- * orinoco_rx_monitor - handle received monitor frames.
- *
- * Arguments:
- * dev network device
- * rxfid received FID
- * desc rx descriptor of the frame
- *
- * Call context: interrupt
- */
-static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
- struct hermes_rx_descriptor *desc)
-{
- u32 hdrlen = 30; /* return full header by default */
- u32 datalen = 0;
- u16 fc;
- int err;
- int len;
- struct sk_buff *skb;
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- hermes_t *hw = &priv->hw;
-
- len = le16_to_cpu(desc->data_len);
-
- /* Determine the size of the header and the data */
- fc = le16_to_cpu(desc->frame_ctl);
- switch (fc & IEEE80211_FCTL_FTYPE) {
- case IEEE80211_FTYPE_DATA:
- if ((fc & IEEE80211_FCTL_TODS)
- && (fc & IEEE80211_FCTL_FROMDS))
- hdrlen = 30;
- else
- hdrlen = 24;
- datalen = len;
- break;
- case IEEE80211_FTYPE_MGMT:
- hdrlen = 24;
- datalen = len;
- break;
- case IEEE80211_FTYPE_CTL:
- switch (fc & IEEE80211_FCTL_STYPE) {
- case IEEE80211_STYPE_PSPOLL:
- case IEEE80211_STYPE_RTS:
- case IEEE80211_STYPE_CFEND:
- case IEEE80211_STYPE_CFENDACK:
- hdrlen = 16;
- break;
- case IEEE80211_STYPE_CTS:
- case IEEE80211_STYPE_ACK:
- hdrlen = 10;
- break;
- }
- break;
- default:
- /* Unknown frame type */
- break;
- }
-
- /* sanity check the length */
- if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
- printk(KERN_DEBUG "%s: oversized monitor frame, "
- "data length = %d\n", dev->name, datalen);
- stats->rx_length_errors++;
- goto update_stats;
- }
-
- skb = dev_alloc_skb(hdrlen + datalen);
- if (!skb) {
- printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
- dev->name);
- goto update_stats;
- }
-
- /* Copy the 802.11 header to the skb */
- memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
- skb_reset_mac_header(skb);
-
- /* If any, copy the data from the card to the skb */
- if (datalen > 0) {
- err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
- ALIGN(datalen, 2), rxfid,
- HERMES_802_2_OFFSET);
- if (err) {
- printk(KERN_ERR "%s: error %d reading monitor frame\n",
- dev->name, err);
- goto drop;
- }
- }
-
- skb->dev = dev;
- skb->ip_summed = CHECKSUM_NONE;
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_802_2);
-
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
-
- netif_rx(skb);
- return;
-
- drop:
- dev_kfree_skb_irq(skb);
- update_stats:
- stats->rx_errors++;
- stats->rx_dropped++;
-}
-
-/* Get tsc from the firmware */
-static int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key,
- u8 *tsc)
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
- u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
-
- if ((key < 0) || (key > 4))
- return -EINVAL;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
- sizeof(tsc_arr), NULL, &tsc_arr);
- if (!err)
- memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
-
- return err;
-}
-
-static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- struct iw_statistics *wstats = &priv->wstats;
- struct sk_buff *skb = NULL;
- u16 rxfid, status;
- int length;
- struct hermes_rx_descriptor *desc;
- struct orinoco_rx_data *rx_data;
- int err;
-
- desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
- if (!desc) {
- printk(KERN_WARNING
- "%s: Can't allocate space for RX descriptor\n",
- dev->name);
- goto update_stats;
- }
-
- rxfid = hermes_read_regn(hw, RXFID);
-
- err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
- rxfid, 0);
- if (err) {
- printk(KERN_ERR "%s: error %d reading Rx descriptor. "
- "Frame dropped.\n", dev->name, err);
- goto update_stats;
- }
-
- status = le16_to_cpu(desc->status);
-
- if (status & HERMES_RXSTAT_BADCRC) {
- DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
- dev->name);
- stats->rx_crc_errors++;
- goto update_stats;
- }
-
- /* Handle frames in monitor mode */
- if (priv->iw_mode == IW_MODE_MONITOR) {
- orinoco_rx_monitor(dev, rxfid, desc);
- goto out;
- }
-
- if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
- DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
- dev->name);
- wstats->discard.code++;
- goto update_stats;
- }
-
- length = le16_to_cpu(desc->data_len);
-
- /* Sanity checks */
- if (length < 3) { /* No for even an 802.2 LLC header */
- /* At least on Symbol firmware with PCF we get quite a
- lot of these legitimately - Poll frames with no
- data. */
- goto out;
- }
- if (length > IEEE80211_MAX_DATA_LEN) {
- printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
- dev->name, length);
- stats->rx_length_errors++;
- goto update_stats;
- }
-
- /* Payload size does not include Michael MIC. Increase payload
- * size to read it together with the data. */
- if (status & HERMES_RXSTAT_MIC)
- length += MICHAEL_MIC_LEN;
-
- /* We need space for the packet data itself, plus an ethernet
- header, plus 2 bytes so we can align the IP header on a
- 32bit boundary, plus 1 byte so we can read in odd length
- packets from the card, which has an IO granularity of 16
- bits */
- skb = dev_alloc_skb(length+ETH_HLEN+2+1);
- if (!skb) {
- printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
- dev->name);
- goto update_stats;
- }
-
- /* We'll prepend the header, so reserve space for it. The worst
- case is no decapsulation, when 802.3 header is prepended and
- nothing is removed. 2 is for aligning the IP header. */
- skb_reserve(skb, ETH_HLEN + 2);
-
- err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
- ALIGN(length, 2), rxfid,
- HERMES_802_2_OFFSET);
- if (err) {
- printk(KERN_ERR "%s: error %d reading frame. "
- "Frame dropped.\n", dev->name, err);
- goto drop;
- }
-
- /* Add desc and skb to rx queue */
- rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
- if (!rx_data) {
- printk(KERN_WARNING "%s: Can't allocate RX packet\n",
- dev->name);
- goto drop;
- }
- rx_data->desc = desc;
- rx_data->skb = skb;
- list_add_tail(&rx_data->list, &priv->rx_list);
- tasklet_schedule(&priv->rx_tasklet);
-
- return;
-
-drop:
- dev_kfree_skb_irq(skb);
-update_stats:
- stats->rx_errors++;
- stats->rx_dropped++;
-out:
- kfree(desc);
-}
-
-static void orinoco_rx(struct net_device *dev,
- struct hermes_rx_descriptor *desc,
- struct sk_buff *skb)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- u16 status, fc;
- int length;
- struct ethhdr *hdr;
-
- status = le16_to_cpu(desc->status);
- length = le16_to_cpu(desc->data_len);
- fc = le16_to_cpu(desc->frame_ctl);
-
- /* Calculate and check MIC */
- if (status & HERMES_RXSTAT_MIC) {
- int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
- HERMES_MIC_KEY_ID_SHIFT);
- u8 mic[MICHAEL_MIC_LEN];
- u8 *rxmic;
- u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
- desc->addr3 : desc->addr2;
-
- /* Extract Michael MIC from payload */
- rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
-
- skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
- length -= MICHAEL_MIC_LEN;
-
- michael_mic(priv->rx_tfm_mic,
- priv->tkip_key[key_id].rx_mic,
- desc->addr1,
- src,
- 0, /* priority or QoS? */
- skb->data,
- skb->len,
- &mic[0]);
-
- if (memcmp(mic, rxmic,
- MICHAEL_MIC_LEN)) {
- union iwreq_data wrqu;
- struct iw_michaelmicfailure wxmic;
-
- printk(KERN_WARNING "%s: "
- "Invalid Michael MIC in data frame from %pM, "
- "using key %i\n",
- dev->name, src, key_id);
-
- /* TODO: update stats */
-
- /* Notify userspace */
- memset(&wxmic, 0, sizeof(wxmic));
- wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
- wxmic.flags |= (desc->addr1[0] & 1) ?
- IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
- wxmic.src_addr.sa_family = ARPHRD_ETHER;
- memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
-
- (void) orinoco_hw_get_tkip_iv(priv, key_id,
- &wxmic.tsc[0]);
-
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(wxmic);
- wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
- (char *) &wxmic);
-
- goto drop;
- }
- }
-
- /* Handle decapsulation
- * In most cases, the firmware tell us about SNAP frames.
- * For some reason, the SNAP frames sent by LinkSys APs
- * are not properly recognised by most firmwares.
- * So, check ourselves */
- if (length >= ENCAPS_OVERHEAD &&
- (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
- ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
- is_ethersnap(skb->data))) {
- /* These indicate a SNAP within 802.2 LLC within
- 802.11 frame which we'll need to de-encapsulate to
- the original EthernetII frame. */
- hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
- } else {
- /* 802.3 frame - prepend 802.3 header as is */
- hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
- hdr->h_proto = htons(length);
- }
- memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
- if (fc & IEEE80211_FCTL_FROMDS)
- memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
- else
- memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
-
- skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
- if (fc & IEEE80211_FCTL_TODS)
- skb->pkt_type = PACKET_OTHERHOST;
-
- /* Process the wireless stats if needed */
- orinoco_stat_gather(dev, skb, desc);
-
- /* Pass the packet to the networking stack */
- netif_rx(skb);
- stats->rx_packets++;
- stats->rx_bytes += length;
-
- return;
-
- drop:
- dev_kfree_skb(skb);
- stats->rx_errors++;
- stats->rx_dropped++;
-}
-
-static void orinoco_rx_isr_tasklet(unsigned long data)
-{
- struct net_device *dev = (struct net_device *) data;
- struct orinoco_private *priv = netdev_priv(dev);
- struct orinoco_rx_data *rx_data, *temp;
- struct hermes_rx_descriptor *desc;
- struct sk_buff *skb;
- unsigned long flags;
-
- /* orinoco_rx requires the driver lock, and we also need to
- * protect priv->rx_list, so just hold the lock over the
- * lot.
- *
- * If orinoco_lock fails, we've unplugged the card. In this
- * case just abort. */
- if (orinoco_lock(priv, &flags) != 0)
- return;
-
- /* extract desc and skb from queue */
- list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
- desc = rx_data->desc;
- skb = rx_data->skb;
- list_del(&rx_data->list);
- kfree(rx_data);
-
- orinoco_rx(dev, desc, skb);
-
- kfree(desc);
- }
-
- orinoco_unlock(priv, &flags);
-}
-
-/********************************************************************/
-/* Rx path (info frames) */
-/********************************************************************/
-
-static void print_linkstatus(struct net_device *dev, u16 status)
-{
- char * s;
-
- if (suppress_linkstatus)
- return;
-
- switch (status) {
- case HERMES_LINKSTATUS_NOT_CONNECTED:
- s = "Not Connected";
- break;
- case HERMES_LINKSTATUS_CONNECTED:
- s = "Connected";
- break;
- case HERMES_LINKSTATUS_DISCONNECTED:
- s = "Disconnected";
- break;
- case HERMES_LINKSTATUS_AP_CHANGE:
- s = "AP Changed";
- break;
- case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
- s = "AP Out of Range";
- break;
- case HERMES_LINKSTATUS_AP_IN_RANGE:
- s = "AP In Range";
- break;
- case HERMES_LINKSTATUS_ASSOC_FAILED:
- s = "Association Failed";
- break;
- default:
- s = "UNKNOWN";
- }
-
- printk(KERN_INFO "%s: New link status: %s (%04x)\n",
- dev->name, s, status);
-}
-
-/* Search scan results for requested BSSID, join it if found */
-static void orinoco_join_ap(struct work_struct *work)
-{
- struct orinoco_private *priv =
- container_of(work, struct orinoco_private, join_work);
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- int err;
- unsigned long flags;
- struct join_req {
- u8 bssid[ETH_ALEN];
- __le16 channel;
- } __attribute__ ((packed)) req;
- const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
- struct prism2_scan_apinfo *atom = NULL;
- int offset = 4;
- int found = 0;
- u8 *buf;
- u16 len;
-
- /* Allocate buffer for scan results */
- buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
- if (! buf)
- return;
-
- if (orinoco_lock(priv, &flags) != 0)
- goto fail_lock;
-
- /* Sanity checks in case user changed something in the meantime */
- if (! priv->bssid_fixed)
- goto out;
-
- if (strlen(priv->desired_essid) == 0)
- goto out;
-
- /* Read scan results from the firmware */
- err = hermes_read_ltv(hw, USER_BAP,
- HERMES_RID_SCANRESULTSTABLE,
- MAX_SCAN_LEN, &len, buf);
- if (err) {
- printk(KERN_ERR "%s: Cannot read scan results\n",
- dev->name);
- goto out;
- }
-
- len = HERMES_RECLEN_TO_BYTES(len);
-
- /* Go through the scan results looking for the channel of the AP
- * we were requested to join */
- for (; offset + atom_len <= len; offset += atom_len) {
- atom = (struct prism2_scan_apinfo *) (buf + offset);
- if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
- found = 1;
- break;
- }
- }
-
- if (! found) {
- DEBUG(1, "%s: Requested AP not found in scan results\n",
- dev->name);
- goto out;
- }
-
- memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
- req.channel = atom->channel; /* both are little-endian */
- err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
- &req);
- if (err)
- printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
-
- out:
- orinoco_unlock(priv, &flags);
-
- fail_lock:
- kfree(buf);
-}
-
-/* Send new BSSID to userspace */
-static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
-{
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- union iwreq_data wrqu;
- int err;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
- ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
- if (err != 0)
- return;
-
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-
- /* Send event to user space */
- wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
-}
-
-static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
-{
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- union iwreq_data wrqu;
- int err;
- u8 buf[88];
- u8 *ie;
-
- if (!priv->has_wpa)
- return;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
- sizeof(buf), NULL, &buf);
- if (err != 0)
- return;
-
- ie = orinoco_get_wpa_ie(buf, sizeof(buf));
- if (ie) {
- int rem = sizeof(buf) - (ie - &buf[0]);
- wrqu.data.length = ie[1] + 2;
- if (wrqu.data.length > rem)
- wrqu.data.length = rem;
-
- if (wrqu.data.length)
- /* Send event to user space */
- wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
- }
-}
-
-static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
-{
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- union iwreq_data wrqu;
- int err;
- u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
- u8 *ie;
-
- if (!priv->has_wpa)
- return;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
- sizeof(buf), NULL, &buf);
- if (err != 0)
- return;
-
- ie = orinoco_get_wpa_ie(buf, sizeof(buf));
- if (ie) {
- int rem = sizeof(buf) - (ie - &buf[0]);
- wrqu.data.length = ie[1] + 2;
- if (wrqu.data.length > rem)
- wrqu.data.length = rem;
-
- if (wrqu.data.length)
- /* Send event to user space */
- wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
- }
-}
-
-static void orinoco_send_wevents(struct work_struct *work)
-{
- struct orinoco_private *priv =
- container_of(work, struct orinoco_private, wevent_work);
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return;
-
- orinoco_send_assocreqie_wevent(priv);
- orinoco_send_assocrespie_wevent(priv);
- orinoco_send_bssid_wevent(priv);
-
- orinoco_unlock(priv, &flags);
-}
-
-static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
- unsigned long scan_age)
-{
- if (priv->has_ext_scan) {
- struct xbss_element *bss;
- struct xbss_element *tmp_bss;
-
- /* Blow away current list of scan results */
- list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
- if (!scan_age ||
- time_after(jiffies, bss->last_scanned + scan_age)) {
- list_move_tail(&bss->list,
- &priv->bss_free_list);
- /* Don't blow away ->list, just BSS data */
- memset(&bss->bss, 0, sizeof(bss->bss));
- bss->last_scanned = 0;
- }
- }
- } else {
- struct bss_element *bss;
- struct bss_element *tmp_bss;
-
- /* Blow away current list of scan results */
- list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
- if (!scan_age ||
- time_after(jiffies, bss->last_scanned + scan_age)) {
- list_move_tail(&bss->list,
- &priv->bss_free_list);
- /* Don't blow away ->list, just BSS data */
- memset(&bss->bss, 0, sizeof(bss->bss));
- bss->last_scanned = 0;
- }
- }
- }
-}
-
-static void orinoco_add_ext_scan_result(struct orinoco_private *priv,
- struct agere_ext_scan_info *atom)
-{
- struct xbss_element *bss = NULL;
- int found = 0;
-
- /* Try to update an existing bss first */
- list_for_each_entry(bss, &priv->bss_list, list) {
- if (compare_ether_addr(bss->bss.bssid, atom->bssid))
- continue;
- /* ESSID lengths */
- if (bss->bss.data[1] != atom->data[1])
- continue;
- if (memcmp(&bss->bss.data[2], &atom->data[2],
- atom->data[1]))
- continue;
- found = 1;
- break;
- }
-
- /* Grab a bss off the free list */
- if (!found && !list_empty(&priv->bss_free_list)) {
- bss = list_entry(priv->bss_free_list.next,
- struct xbss_element, list);
- list_del(priv->bss_free_list.next);
-
- list_add_tail(&bss->list, &priv->bss_list);
- }
-
- if (bss) {
- /* Always update the BSS to get latest beacon info */
- memcpy(&bss->bss, atom, sizeof(bss->bss));
- bss->last_scanned = jiffies;
- }
-}
-
-static int orinoco_process_scan_results(struct net_device *dev,
- unsigned char *buf,
- int len)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int offset; /* In the scan data */
- union hermes_scan_info *atom;
- int atom_len;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- atom_len = sizeof(struct agere_scan_apinfo);
- offset = 0;
- break;
- case FIRMWARE_TYPE_SYMBOL:
- /* Lack of documentation necessitates this hack.
- * Different firmwares have 68 or 76 byte long atoms.
- * We try modulo first. If the length divides by both,
- * we check what would be the channel in the second
- * frame for a 68-byte atom. 76-byte atoms have 0 there.
- * Valid channel cannot be 0. */
- if (len % 76)
- atom_len = 68;
- else if (len % 68)
- atom_len = 76;
- else if (len >= 1292 && buf[68] == 0)
- atom_len = 76;
- else
- atom_len = 68;
- offset = 0;
- break;
- case FIRMWARE_TYPE_INTERSIL:
- offset = 4;
- if (priv->has_hostscan) {
- atom_len = le16_to_cpup((__le16 *)buf);
- /* Sanity check for atom_len */
- if (atom_len < sizeof(struct prism2_scan_apinfo)) {
- printk(KERN_ERR "%s: Invalid atom_len in scan "
- "data: %d\n", dev->name, atom_len);
- return -EIO;
- }
- } else
- atom_len = offsetof(struct prism2_scan_apinfo, atim);
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- /* Check that we got an whole number of atoms */
- if ((len - offset) % atom_len) {
- printk(KERN_ERR "%s: Unexpected scan data length %d, "
- "atom_len %d, offset %d\n", dev->name, len,
- atom_len, offset);
- return -EIO;
- }
-
- orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
-
- /* Read the entries one by one */
- for (; offset + atom_len <= len; offset += atom_len) {
- int found = 0;
- struct bss_element *bss = NULL;
-
- /* Get next atom */
- atom = (union hermes_scan_info *) (buf + offset);
-
- /* Try to update an existing bss first */
- list_for_each_entry(bss, &priv->bss_list, list) {
- if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
- continue;
- if (le16_to_cpu(bss->bss.a.essid_len) !=
- le16_to_cpu(atom->a.essid_len))
- continue;
- if (memcmp(bss->bss.a.essid, atom->a.essid,
- le16_to_cpu(atom->a.essid_len)))
- continue;
- found = 1;
- break;
- }
-
- /* Grab a bss off the free list */
- if (!found && !list_empty(&priv->bss_free_list)) {
- bss = list_entry(priv->bss_free_list.next,
- struct bss_element, list);
- list_del(priv->bss_free_list.next);
-
- list_add_tail(&bss->list, &priv->bss_list);
- }
-
- if (bss) {
- /* Always update the BSS to get latest beacon info */
- memcpy(&bss->bss, atom, sizeof(bss->bss));
- bss->last_scanned = jiffies;
- }
- }
-
- return 0;
-}
-
-static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- u16 infofid;
- struct {
- __le16 len;
- __le16 type;
- } __attribute__ ((packed)) info;
- int len, type;
- int err;
-
- /* This is an answer to an INQUIRE command that we did earlier,
- * or an information "event" generated by the card
- * The controller return to us a pseudo frame containing
- * the information in question - Jean II */
- infofid = hermes_read_regn(hw, INFOFID);
-
- /* Read the info frame header - don't try too hard */
- err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
- infofid, 0);
- if (err) {
- printk(KERN_ERR "%s: error %d reading info frame. "
- "Frame dropped.\n", dev->name, err);
- return;
- }
-
- len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
- type = le16_to_cpu(info.type);
-
- switch (type) {
- case HERMES_INQ_TALLIES: {
- struct hermes_tallies_frame tallies;
- struct iw_statistics *wstats = &priv->wstats;
-
- if (len > sizeof(tallies)) {
- printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
- dev->name, len);
- len = sizeof(tallies);
- }
-
- err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
- infofid, sizeof(info));
- if (err)
- break;
-
- /* Increment our various counters */
- /* wstats->discard.nwid - no wrong BSSID stuff */
- wstats->discard.code +=
- le16_to_cpu(tallies.RxWEPUndecryptable);
- if (len == sizeof(tallies))
- wstats->discard.code +=
- le16_to_cpu(tallies.RxDiscards_WEPICVError) +
- le16_to_cpu(tallies.RxDiscards_WEPExcluded);
- wstats->discard.misc +=
- le16_to_cpu(tallies.TxDiscardsWrongSA);
- wstats->discard.fragment +=
- le16_to_cpu(tallies.RxMsgInBadMsgFragments);
- wstats->discard.retries +=
- le16_to_cpu(tallies.TxRetryLimitExceeded);
- /* wstats->miss.beacon - no match */
- }
- break;
- case HERMES_INQ_LINKSTATUS: {
- struct hermes_linkstatus linkstatus;
- u16 newstatus;
- int connected;
-
- if (priv->iw_mode == IW_MODE_MONITOR)
- break;
-
- if (len != sizeof(linkstatus)) {
- printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
- dev->name, len);
- break;
- }
-
- err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
- infofid, sizeof(info));
- if (err)
- break;
- newstatus = le16_to_cpu(linkstatus.linkstatus);
-
- /* Symbol firmware uses "out of range" to signal that
- * the hostscan frame can be requested. */
- if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
- priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
- priv->has_hostscan && priv->scan_inprogress) {
- hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
- break;
- }
-
- connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
- || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
- || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
-
- if (connected)
- netif_carrier_on(dev);
- else if (!ignore_disconnect)
- netif_carrier_off(dev);
-
- if (newstatus != priv->last_linkstatus) {
- priv->last_linkstatus = newstatus;
- print_linkstatus(dev, newstatus);
- /* The info frame contains only one word which is the
- * status (see hermes.h). The status is pretty boring
- * in itself, that's why we export the new BSSID...
- * Jean II */
- schedule_work(&priv->wevent_work);
- }
- }
- break;
- case HERMES_INQ_SCAN:
- if (!priv->scan_inprogress && priv->bssid_fixed &&
- priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
- schedule_work(&priv->join_work);
- break;
- }
- /* fall through */
- case HERMES_INQ_HOSTSCAN:
- case HERMES_INQ_HOSTSCAN_SYMBOL: {
- /* Result of a scanning. Contains information about
- * cells in the vicinity - Jean II */
- union iwreq_data wrqu;
- unsigned char *buf;
-
- /* Scan is no longer in progress */
- priv->scan_inprogress = 0;
-
- /* Sanity check */
- if (len > 4096) {
- printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
- dev->name, len);
- break;
- }
-
- /* Allocate buffer for results */
- buf = kmalloc(len, GFP_ATOMIC);
- if (buf == NULL)
- /* No memory, so can't printk()... */
- break;
-
- /* Read scan data */
- err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
- infofid, sizeof(info));
- if (err) {
- kfree(buf);
- break;
- }
-
-#ifdef ORINOCO_DEBUG
- {
- int i;
- printk(KERN_DEBUG "Scan result [%02X", buf[0]);
- for(i = 1; i < (len * 2); i++)
- printk(":%02X", buf[i]);
- printk("]\n");
- }
-#endif /* ORINOCO_DEBUG */
-
- if (orinoco_process_scan_results(dev, buf, len) == 0) {
- /* Send an empty event to user space.
- * We don't send the received data on the event because
- * it would require us to do complex transcoding, and
- * we want to minimise the work done in the irq handler
- * Use a request to extract the data - Jean II */
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
- }
- kfree(buf);
- }
- break;
- case HERMES_INQ_CHANNELINFO:
- {
- struct agere_ext_scan_info *bss;
-
- if (!priv->scan_inprogress) {
- printk(KERN_DEBUG "%s: Got chaninfo without scan, "
- "len=%d\n", dev->name, len);
- break;
- }
-
- /* An empty result indicates that the scan is complete */
- if (len == 0) {
- union iwreq_data wrqu;
-
- /* Scan is no longer in progress */
- priv->scan_inprogress = 0;
-
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
- break;
- }
-
- /* Sanity check */
- else if (len > sizeof(*bss)) {
- printk(KERN_WARNING
- "%s: Ext scan results too large (%d bytes). "
- "Truncating results to %zd bytes.\n",
- dev->name, len, sizeof(*bss));
- len = sizeof(*bss);
- } else if (len < (offsetof(struct agere_ext_scan_info,
- data) + 2)) {
- /* Drop this result now so we don't have to
- * keep checking later */
- printk(KERN_WARNING
- "%s: Ext scan results too short (%d bytes)\n",
- dev->name, len);
- break;
- }
-
- bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
- if (bss == NULL)
- break;
-
- /* Read scan data */
- err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
- infofid, sizeof(info));
- if (err) {
- kfree(bss);
- break;
- }
-
- orinoco_add_ext_scan_result(priv, bss);
-
- kfree(bss);
- break;
- }
- case HERMES_INQ_SEC_STAT_AGERE:
- /* Security status (Agere specific) */
- /* Ignore this frame for now */
- if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
- break;
- /* fall through */
- default:
- printk(KERN_DEBUG "%s: Unknown information frame received: "
- "type 0x%04x, length %d\n", dev->name, type, len);
- /* We don't actually do anything about it */
- break;
- }
-}
-
-static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
-{
- if (net_ratelimit())
- printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
-}
-
-/********************************************************************/
-/* Internal hardware control routines */
-/********************************************************************/
-
-int __orinoco_up(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- int err;
-
- netif_carrier_off(dev); /* just to make sure */
-
- err = __orinoco_program_rids(dev);
- if (err) {
- printk(KERN_ERR "%s: Error %d configuring card\n",
- dev->name, err);
- return err;
- }
-
- /* Fire things up again */
- hermes_set_irqmask(hw, ORINOCO_INTEN);
- err = hermes_enable_port(hw, 0);
- if (err) {
- printk(KERN_ERR "%s: Error %d enabling MAC port\n",
- dev->name, err);
- return err;
- }
-
- netif_start_queue(dev);
-
- return 0;
-}
-
-int __orinoco_down(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- int err;
-
- netif_stop_queue(dev);
-
- if (! priv->hw_unavailable) {
- if (! priv->broken_disableport) {
- err = hermes_disable_port(hw, 0);
- if (err) {
- /* Some firmwares (e.g. Intersil 1.3.x) seem
- * to have problems disabling the port, oh
- * well, too bad. */
- printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
- dev->name, err);
- priv->broken_disableport = 1;
- }
- }
- hermes_set_irqmask(hw, 0);
- hermes_write_regn(hw, EVACK, 0xffff);
- }
-
- /* firmware will have to reassociate */
- netif_carrier_off(dev);
- priv->last_linkstatus = 0xffff;
-
- return 0;
-}
-
-static int orinoco_allocate_fid(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- int err;
-
- err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
- if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
- /* Try workaround for old Symbol firmware bug */
- printk(KERN_WARNING "%s: firmware ALLOC bug detected "
- "(old Symbol firmware?). Trying to work around... ",
- dev->name);
-
- priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
- err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
- if (err)
- printk("failed!\n");
- else
- printk("ok.\n");
- }
-
- return err;
-}
-
-int orinoco_reinit_firmware(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- int err;
-
- err = hermes_init(hw);
- if (priv->do_fw_download && !err) {
- err = orinoco_download(priv);
- if (err)
- priv->do_fw_download = 0;
- }
- if (!err)
- err = orinoco_allocate_fid(dev);
-
- return err;
-}
-
-static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
-
- if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
- printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
- priv->ndev->name, priv->bitratemode);
- return -EINVAL;
- }
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFTXRATECONTROL,
- bitrate_table[priv->bitratemode].agere_txratectrl);
- break;
- case FIRMWARE_TYPE_INTERSIL:
- case FIRMWARE_TYPE_SYMBOL:
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFTXRATECONTROL,
- bitrate_table[priv->bitratemode].intersil_txratectrl);
- break;
- default:
- BUG();
- }
-
- return err;
-}
-
-/* Set fixed AP address */
-static int __orinoco_hw_set_wap(struct orinoco_private *priv)
-{
- int roaming_flag;
- int err = 0;
- hermes_t *hw = &priv->hw;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- /* not supported */
- break;
- case FIRMWARE_TYPE_INTERSIL:
- if (priv->bssid_fixed)
- roaming_flag = 2;
- else
- roaming_flag = 1;
-
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFROAMINGMODE,
- roaming_flag);
- break;
- case FIRMWARE_TYPE_SYMBOL:
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
- &priv->desired_bssid);
- break;
- }
- return err;
-}
-
-/* Change the WEP keys and/or the current keys. Can be called
- * either from __orinoco_hw_setup_enc() or directly from
- * orinoco_ioctl_setiwencode(). In the later case the association
- * with the AP is not broken (if the firmware can handle it),
- * which is needed for 802.1x implementations. */
-static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFWEPKEYS_AGERE,
- &priv->keys);
- if (err)
- return err;
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFTXKEY_AGERE,
- priv->tx_key);
- if (err)
- return err;
- break;
- case FIRMWARE_TYPE_INTERSIL:
- case FIRMWARE_TYPE_SYMBOL:
- {
- int keylen;
- int i;
-
- /* Force uniform key length to work around firmware bugs */
- keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
-
- if (keylen > LARGE_KEY_SIZE) {
- printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
- priv->ndev->name, priv->tx_key, keylen);
- return -E2BIG;
- }
-
- /* Write all 4 keys */
- for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
- err = hermes_write_ltv(hw, USER_BAP,
- HERMES_RID_CNFDEFAULTKEY0 + i,
- HERMES_BYTES_TO_RECLEN(keylen),
- priv->keys[i].data);
- if (err)
- return err;
- }
-
- /* Write the index of the key used in transmission */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFWEPDEFAULTKEYID,
- priv->tx_key);
- if (err)
- return err;
- }
- break;
- }
-
- return 0;
-}
-
-static int __orinoco_hw_setup_enc(struct orinoco_private *priv)
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
- int master_wep_flag;
- int auth_flag;
- int enc_flag;
-
- /* Setup WEP keys for WEP and WPA */
- if (priv->encode_alg)
- __orinoco_hw_setup_wepkeys(priv);
-
- if (priv->wep_restrict)
- auth_flag = HERMES_AUTH_SHARED_KEY;
- else
- auth_flag = HERMES_AUTH_OPEN;
-
- if (priv->wpa_enabled)
- enc_flag = 2;
- else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
- enc_flag = 1;
- else
- enc_flag = 0;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
- if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
- /* Enable the shared-key authentication. */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFAUTHENTICATION_AGERE,
- auth_flag);
- }
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFWEPENABLED_AGERE,
- enc_flag);
- if (err)
- return err;
-
- if (priv->has_wpa) {
- /* Set WPA key management */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
- priv->key_mgmt);
- if (err)
- return err;
- }
-
- break;
-
- case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
- case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
- if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
- if (priv->wep_restrict ||
- (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
- master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
- HERMES_WEP_EXCL_UNENCRYPTED;
- else
- master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
-
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFAUTHENTICATION,
- auth_flag);
- if (err)
- return err;
- } else
- master_wep_flag = 0;
-
- if (priv->iw_mode == IW_MODE_MONITOR)
- master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
-
- /* Master WEP setting : on/off */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFWEPFLAGS_INTERSIL,
- master_wep_flag);
- if (err)
- return err;
-
- break;
- }
-
- return 0;
-}
-
-/* key must be 32 bytes, including the tx and rx MIC keys.
- * rsc must be 8 bytes
- * tsc must be 8 bytes or NULL
- */
-static int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
- u8 *key, u8 *rsc, u8 *tsc)
-{
- struct {
- __le16 idx;
- u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
- u8 key[TKIP_KEYLEN];
- u8 tx_mic[MIC_KEYLEN];
- u8 rx_mic[MIC_KEYLEN];
- u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
- } __attribute__ ((packed)) buf;
- int ret;
- int err;
- int k;
- u16 xmitting;
-
- key_idx &= 0x3;
-
- if (set_tx)
- key_idx |= 0x8000;
-
- buf.idx = cpu_to_le16(key_idx);
- memcpy(buf.key, key,
- sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
-
- if (rsc == NULL)
- memset(buf.rsc, 0, sizeof(buf.rsc));
- else
- memcpy(buf.rsc, rsc, sizeof(buf.rsc));
-
- if (tsc == NULL) {
- memset(buf.tsc, 0, sizeof(buf.tsc));
- buf.tsc[4] = 0x10;
- } else {
- memcpy(buf.tsc, tsc, sizeof(buf.tsc));
- }
-
- /* Wait upto 100ms for tx queue to empty */
- k = 100;
- do {
- k--;
- udelay(1000);
- ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
- &xmitting);
- if (ret)
- break;
- } while ((k > 0) && xmitting);
-
- if (k == 0)
- ret = -ETIMEDOUT;
-
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
- &buf);
-
- return ret ? ret : err;
-}
-
-static int orinoco_clear_tkip_key(struct orinoco_private *priv,
- int key_idx)
-{
- hermes_t *hw = &priv->hw;
- int err;
-
- memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
- key_idx);
- if (err)
- printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
- priv->ndev->name, err, key_idx);
- return err;
-}
-
-static int __orinoco_program_rids(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err;
- struct hermes_idstring idbuf;
-
- /* Set the MAC address */
- err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
- HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting MAC address\n",
- dev->name, err);
- return err;
- }
-
- /* Set up the link mode */
- err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
- priv->port_type);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting port type\n",
- dev->name, err);
- return err;
- }
- /* Set the channel/frequency */
- if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFOWNCHANNEL,
- priv->channel);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting channel %d\n",
- dev->name, err, priv->channel);
- return err;
- }
- }
-
- if (priv->has_ibss) {
- u16 createibss;
-
- if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
- printk(KERN_WARNING "%s: This firmware requires an "
- "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
- /* With wvlan_cs, in this case, we would crash.
- * hopefully, this driver will behave better...
- * Jean II */
- createibss = 0;
- } else {
- createibss = priv->createibss;
- }
-
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFCREATEIBSS,
- createibss);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
- dev->name, err);
- return err;
- }
- }
-
- /* Set the desired BSSID */
- err = __orinoco_hw_set_wap(priv);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting AP address\n",
- dev->name, err);
- return err;
- }
- /* Set the desired ESSID */
- idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
- memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
- /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
- err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
- HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
- &idbuf);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
- dev->name, err);
- return err;
- }
- err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
- HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
- &idbuf);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
- dev->name, err);
- return err;
- }
-
- /* Set the station name */
- idbuf.len = cpu_to_le16(strlen(priv->nick));
- memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
- err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
- HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
- &idbuf);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting nickname\n",
- dev->name, err);
- return err;
- }
-
- /* Set AP density */
- if (priv->has_sensitivity) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSYSTEMSCALE,
- priv->ap_density);
- if (err) {
- printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
- "Disabling sensitivity control\n",
- dev->name, err);
-
- priv->has_sensitivity = 0;
- }
- }
-
- /* Set RTS threshold */
- err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
- priv->rts_thresh);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
- dev->name, err);
- return err;
- }
-
- /* Set fragmentation threshold or MWO robustness */
- if (priv->has_mwo)
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMWOROBUST_AGERE,
- priv->mwo_robust);
- else
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
- priv->frag_thresh);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting fragmentation\n",
- dev->name, err);
- return err;
- }
-
- /* Set bitrate */
- err = __orinoco_hw_set_bitrate(priv);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting bitrate\n",
- dev->name, err);
- return err;
- }
-
- /* Set power management */
- if (priv->has_pm) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPMENABLED,
- priv->pm_on);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting up PM\n",
- dev->name, err);
- return err;
- }
-
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMULTICASTRECEIVE,
- priv->pm_mcast);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting up PM\n",
- dev->name, err);
- return err;
- }
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMAXSLEEPDURATION,
- priv->pm_period);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting up PM\n",
- dev->name, err);
- return err;
- }
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPMHOLDOVERDURATION,
- priv->pm_timeout);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting up PM\n",
- dev->name, err);
- return err;
- }
- }
-
- /* Set preamble - only for Symbol so far... */
- if (priv->has_preamble) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPREAMBLE_SYMBOL,
- priv->preamble);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting preamble\n",
- dev->name, err);
- return err;
- }
- }
-
- /* Set up encryption */
- if (priv->has_wep || priv->has_wpa) {
- err = __orinoco_hw_setup_enc(priv);
- if (err) {
- printk(KERN_ERR "%s: Error %d activating encryption\n",
- dev->name, err);
- return err;
- }
- }
-
- if (priv->iw_mode == IW_MODE_MONITOR) {
- /* Enable monitor mode */
- dev->type = ARPHRD_IEEE80211;
- err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
- HERMES_TEST_MONITOR, 0, NULL);
- } else {
- /* Disable monitor mode */
- dev->type = ARPHRD_ETHER;
- err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
- HERMES_TEST_STOP, 0, NULL);
- }
- if (err)
- return err;
-
- /* Set promiscuity / multicast*/
- priv->promiscuous = 0;
- priv->mc_count = 0;
-
- /* FIXME: what about netif_tx_lock */
- __orinoco_set_multicast_list(dev);
-
- return 0;
-}
-
-/* FIXME: return int? */
-static void
-__orinoco_set_multicast_list(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- int promisc, mc_count;
-
- /* The Hermes doesn't seem to have an allmulti mode, so we go
- * into promiscuous mode and let the upper levels deal. */
- if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
- (dev->mc_count > MAX_MULTICAST(priv)) ) {
- promisc = 1;
- mc_count = 0;
- } else {
- promisc = 0;
- mc_count = dev->mc_count;
- }
-
- if (promisc != priv->promiscuous) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPROMISCUOUSMODE,
- promisc);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
- dev->name, err);
- } else
- priv->promiscuous = promisc;
- }
-
- /* If we're not in promiscuous mode, then we need to set the
- * group address if either we want to multicast, or if we were
- * multicasting and want to stop */
- if (! promisc && (mc_count || priv->mc_count) ) {
- struct dev_mc_list *p = dev->mc_list;
- struct hermes_multicast mclist;
- int i;
-
- for (i = 0; i < mc_count; i++) {
- /* paranoia: is list shorter than mc_count? */
- BUG_ON(! p);
- /* paranoia: bad address size in list? */
- BUG_ON(p->dmi_addrlen != ETH_ALEN);
-
- memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
- p = p->next;
- }
-
- if (p)
- printk(KERN_WARNING "%s: Multicast list is "
- "longer than mc_count\n", dev->name);
-
- err = hermes_write_ltv(hw, USER_BAP,
- HERMES_RID_CNFGROUPADDRESSES,
- HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
- &mclist);
- if (err)
- printk(KERN_ERR "%s: Error %d setting multicast list.\n",
- dev->name, err);
- else
- priv->mc_count = mc_count;
- }
-}
-
-/* This must be called from user context, without locks held - use
- * schedule_work() */
-static void orinoco_reset(struct work_struct *work)
-{
- struct orinoco_private *priv =
- container_of(work, struct orinoco_private, reset_work);
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- int err;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- /* When the hardware becomes available again, whatever
- * detects that is responsible for re-initializing
- * it. So no need for anything further */
- return;
-
- netif_stop_queue(dev);
-
- /* Shut off interrupts. Depending on what state the hardware
- * is in, this might not work, but we'll try anyway */
- hermes_set_irqmask(hw, 0);
- hermes_write_regn(hw, EVACK, 0xffff);
-
- priv->hw_unavailable++;
- priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
- netif_carrier_off(dev);
-
- orinoco_unlock(priv, &flags);
-
- /* Scanning support: Cleanup of driver struct */
- orinoco_clear_scan_results(priv, 0);
- priv->scan_inprogress = 0;
-
- if (priv->hard_reset) {
- err = (*priv->hard_reset)(priv);
- if (err) {
- printk(KERN_ERR "%s: orinoco_reset: Error %d "
- "performing hard reset\n", dev->name, err);
- goto disable;
- }
- }
-
- err = orinoco_reinit_firmware(dev);
- if (err) {
- printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
- dev->name, err);
- goto disable;
- }
-
- spin_lock_irq(&priv->lock); /* This has to be called from user context */
-
- priv->hw_unavailable--;
-
- /* priv->open or priv->hw_unavailable might have changed while
- * we dropped the lock */
- if (priv->open && (! priv->hw_unavailable)) {
- err = __orinoco_up(dev);
- if (err) {
- printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
- dev->name, err);
- } else
- dev->trans_start = jiffies;
- }
-
- spin_unlock_irq(&priv->lock);
-
- return;
- disable:
- hermes_set_irqmask(hw, 0);
- netif_device_detach(dev);
- printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
-}
-
-/********************************************************************/
-/* Interrupt handler */
-/********************************************************************/
-
-static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
-{
- printk(KERN_DEBUG "%s: TICK\n", dev->name);
-}
-
-static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
-{
- /* This seems to happen a fair bit under load, but ignoring it
- seems to work fine...*/
- printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
- dev->name);
-}
-
-irqreturn_t orinoco_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int count = MAX_IRQLOOPS_PER_IRQ;
- u16 evstat, events;
- /* These are used to detect a runaway interrupt situation */
- /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
- * we panic and shut down the hardware */
- static int last_irq_jiffy = 0; /* jiffies value the last time
- * we were called */
- static int loops_this_jiffy = 0;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0) {
- /* If hw is unavailable - we don't know if the irq was
- * for us or not */
- return IRQ_HANDLED;
- }
-
- evstat = hermes_read_regn(hw, EVSTAT);
- events = evstat & hw->inten;
- if (! events) {
- orinoco_unlock(priv, &flags);
- return IRQ_NONE;
- }
-
- if (jiffies != last_irq_jiffy)
- loops_this_jiffy = 0;
- last_irq_jiffy = jiffies;
-
- while (events && count--) {
- if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
- printk(KERN_WARNING "%s: IRQ handler is looping too "
- "much! Resetting.\n", dev->name);
- /* Disable interrupts for now */
- hermes_set_irqmask(hw, 0);
- schedule_work(&priv->reset_work);
- break;
- }
-
- /* Check the card hasn't been removed */
- if (! hermes_present(hw)) {
- DEBUG(0, "orinoco_interrupt(): card removed\n");
- break;
- }
-
- if (events & HERMES_EV_TICK)
- __orinoco_ev_tick(dev, hw);
- if (events & HERMES_EV_WTERR)
- __orinoco_ev_wterr(dev, hw);
- if (events & HERMES_EV_INFDROP)
- __orinoco_ev_infdrop(dev, hw);
- if (events & HERMES_EV_INFO)
- __orinoco_ev_info(dev, hw);
- if (events & HERMES_EV_RX)
- __orinoco_ev_rx(dev, hw);
- if (events & HERMES_EV_TXEXC)
- __orinoco_ev_txexc(dev, hw);
- if (events & HERMES_EV_TX)
- __orinoco_ev_tx(dev, hw);
- if (events & HERMES_EV_ALLOC)
- __orinoco_ev_alloc(dev, hw);
-
- hermes_write_regn(hw, EVACK, evstat);
-
- evstat = hermes_read_regn(hw, EVSTAT);
- events = evstat & hw->inten;
- };
-
- orinoco_unlock(priv, &flags);
- return IRQ_HANDLED;
-}
-
-/********************************************************************/
-/* Power management */
-/********************************************************************/
-#if defined(CONFIG_PM_SLEEP) && !defined(CONFIG_HERMES_CACHE_FW_ON_INIT)
-static int orinoco_pm_notifier(struct notifier_block *notifier,
- unsigned long pm_event,
- void *unused)
-{
- struct orinoco_private *priv = container_of(notifier,
- struct orinoco_private,
- pm_notifier);
-
- /* All we need to do is cache the firmware before suspend, and
- * release it when we come out.
- *
- * Only need to do this if we're downloading firmware. */
- if (!priv->do_fw_download)
- return NOTIFY_DONE;
-
- switch (pm_event) {
- case PM_HIBERNATION_PREPARE:
- case PM_SUSPEND_PREPARE:
- orinoco_cache_fw(priv, 0);
- break;
-
- case PM_POST_RESTORE:
- /* Restore from hibernation failed. We need to clean
- * up in exactly the same way, so fall through. */
- case PM_POST_HIBERNATION:
- case PM_POST_SUSPEND:
- orinoco_uncache_fw(priv);
- break;
-
- case PM_RESTORE_PREPARE:
- default:
- break;
- }
-
- return NOTIFY_DONE;
-}
-#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
-#define orinoco_pm_notifier NULL
-#endif
-
-/********************************************************************/
-/* Initialization */
-/********************************************************************/
-
-struct comp_id {
- u16 id, variant, major, minor;
-} __attribute__ ((packed));
-
-static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
-{
- if (nic_id->id < 0x8000)
- return FIRMWARE_TYPE_AGERE;
- else if (nic_id->id == 0x8000 && nic_id->major == 0)
- return FIRMWARE_TYPE_SYMBOL;
- else
- return FIRMWARE_TYPE_INTERSIL;
-}
-
-/* Set priv->firmware type, determine firmware properties */
-static int determine_firmware(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err;
- struct comp_id nic_id, sta_id;
- unsigned int firmver;
- char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
-
- /* Get the hardware version */
- err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
- if (err) {
- printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
- dev->name, err);
- return err;
- }
-
- le16_to_cpus(&nic_id.id);
- le16_to_cpus(&nic_id.variant);
- le16_to_cpus(&nic_id.major);
- le16_to_cpus(&nic_id.minor);
- printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
- dev->name, nic_id.id, nic_id.variant,
- nic_id.major, nic_id.minor);
-
- priv->firmware_type = determine_firmware_type(&nic_id);
-
- /* Get the firmware version */
- err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
- if (err) {
- printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
- dev->name, err);
- return err;
- }
-
- le16_to_cpus(&sta_id.id);
- le16_to_cpus(&sta_id.variant);
- le16_to_cpus(&sta_id.major);
- le16_to_cpus(&sta_id.minor);
- printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
- dev->name, sta_id.id, sta_id.variant,
- sta_id.major, sta_id.minor);
-
- switch (sta_id.id) {
- case 0x15:
- printk(KERN_ERR "%s: Primary firmware is active\n",
- dev->name);
- return -ENODEV;
- case 0x14b:
- printk(KERN_ERR "%s: Tertiary firmware is active\n",
- dev->name);
- return -ENODEV;
- case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */
- case 0x21: /* Symbol Spectrum24 Trilogy */
- break;
- default:
- printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
- dev->name);
- break;
- }
-
- /* Default capabilities */
- priv->has_sensitivity = 1;
- priv->has_mwo = 0;
- priv->has_preamble = 0;
- priv->has_port3 = 1;
- priv->has_ibss = 1;
- priv->has_wep = 0;
- priv->has_big_wep = 0;
- priv->has_alt_txcntl = 0;
- priv->has_ext_scan = 0;
- priv->has_wpa = 0;
- priv->do_fw_download = 0;
-
- /* Determine capabilities from the firmware version */
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
- ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
- snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
- "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
-
- firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
-
- priv->has_ibss = (firmver >= 0x60006);
- priv->has_wep = (firmver >= 0x40020);
- priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
- Gold cards from the others? */
- priv->has_mwo = (firmver >= 0x60000);
- priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
- priv->ibss_port = 1;
- priv->has_hostscan = (firmver >= 0x8000a);
- priv->do_fw_download = 1;
- priv->broken_monitor = (firmver >= 0x80000);
- priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
- priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
- priv->has_wpa = (firmver >= 0x9002a);
- /* Tested with Agere firmware :
- * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
- * Tested CableTron firmware : 4.32 => Anton */
- break;
- case FIRMWARE_TYPE_SYMBOL:
- /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
- /* Intel MAC : 00:02:B3:* */
- /* 3Com MAC : 00:50:DA:* */
- memset(tmp, 0, sizeof(tmp));
- /* Get the Symbol firmware version */
- err = hermes_read_ltv(hw, USER_BAP,
- HERMES_RID_SECONDARYVERSION_SYMBOL,
- SYMBOL_MAX_VER_LEN, NULL, &tmp);
- if (err) {
- printk(KERN_WARNING
- "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
- dev->name, err);
- firmver = 0;
- tmp[0] = '\0';
- } else {
- /* The firmware revision is a string, the format is
- * something like : "V2.20-01".
- * Quick and dirty parsing... - Jean II
- */
- firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
- | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
- | (tmp[7] - '0');
-
- tmp[SYMBOL_MAX_VER_LEN] = '\0';
- }
-
- snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
- "Symbol %s", tmp);
-
- priv->has_ibss = (firmver >= 0x20000);
- priv->has_wep = (firmver >= 0x15012);
- priv->has_big_wep = (firmver >= 0x20000);
- priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
- (firmver >= 0x29000 && firmver < 0x30000) ||
- firmver >= 0x31000;
- priv->has_preamble = (firmver >= 0x20000);
- priv->ibss_port = 4;
-
- /* Symbol firmware is found on various cards, but
- * there has been no attempt to check firmware
- * download on non-spectrum_cs based cards.
- *
- * Given that the Agere firmware download works
- * differently, we should avoid doing a firmware
- * download with the Symbol algorithm on non-spectrum
- * cards.
- *
- * For now we can identify a spectrum_cs based card
- * because it has a firmware reset function.
- */
- priv->do_fw_download = (priv->stop_fw != NULL);
-
- priv->broken_disableport = (firmver == 0x25013) ||
- (firmver >= 0x30000 && firmver <= 0x31000);
- priv->has_hostscan = (firmver >= 0x31001) ||
- (firmver >= 0x29057 && firmver < 0x30000);
- /* Tested with Intel firmware : 0x20015 => Jean II */
- /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
- break;
- case FIRMWARE_TYPE_INTERSIL:
- /* D-Link, Linksys, Adtron, ZoomAir, and many others...
- * Samsung, Compaq 100/200 and Proxim are slightly
- * different and less well tested */
- /* D-Link MAC : 00:40:05:* */
- /* Addtron MAC : 00:90:D1:* */
- snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
- "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
- sta_id.variant);
-
- firmver = ((unsigned long)sta_id.major << 16) |
- ((unsigned long)sta_id.minor << 8) | sta_id.variant;
-
- priv->has_ibss = (firmver >= 0x000700); /* FIXME */
- priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
- priv->has_pm = (firmver >= 0x000700);
- priv->has_hostscan = (firmver >= 0x010301);
-
- if (firmver >= 0x000800)
- priv->ibss_port = 0;
- else {
- printk(KERN_NOTICE "%s: Intersil firmware earlier "
- "than v0.8.x - several features not supported\n",
- dev->name);
- priv->ibss_port = 1;
- }
- break;
- }
- printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
- priv->fw_name);
-
- return 0;
-}
-
-static int orinoco_init(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- struct hermes_idstring nickbuf;
- u16 reclen;
- int len;
-
- /* No need to lock, the hw_unavailable flag is already set in
- * alloc_orinocodev() */
- priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
-
- /* Initialize the firmware */
- err = hermes_init(hw);
- if (err != 0) {
- printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
- dev->name, err);
- goto out;
- }
-
- err = determine_firmware(dev);
- if (err != 0) {
- printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
- dev->name);
- goto out;
- }
-
- if (priv->do_fw_download) {
-#ifdef CONFIG_HERMES_CACHE_FW_ON_INIT
- orinoco_cache_fw(priv, 0);
-#endif
-
- err = orinoco_download(priv);
- if (err)
- priv->do_fw_download = 0;
-
- /* Check firmware version again */
- err = determine_firmware(dev);
- if (err != 0) {
- printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
- dev->name);
- goto out;
- }
- }
-
- if (priv->has_port3)
- printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
- if (priv->has_ibss)
- printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
- dev->name);
- if (priv->has_wep) {
- printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
- if (priv->has_big_wep)
- printk("104-bit key\n");
- else
- printk("40-bit key\n");
- }
- if (priv->has_wpa) {
- printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
- if (orinoco_mic_init(priv)) {
- printk(KERN_ERR "%s: Failed to setup MIC crypto "
- "algorithm. Disabling WPA support\n", dev->name);
- priv->has_wpa = 0;
- }
- }
-
- /* Now we have the firmware capabilities, allocate appropiate
- * sized scan buffers */
- if (orinoco_bss_data_allocate(priv))
- goto out;
- orinoco_bss_data_init(priv);
-
- /* Get the MAC address */
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
- ETH_ALEN, NULL, dev->dev_addr);
- if (err) {
- printk(KERN_WARNING "%s: failed to read MAC address!\n",
- dev->name);
- goto out;
- }
-
- printk(KERN_DEBUG "%s: MAC address %pM\n",
- dev->name, dev->dev_addr);
-
- /* Get the station name */
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
- sizeof(nickbuf), &reclen, &nickbuf);
- if (err) {
- printk(KERN_ERR "%s: failed to read station name\n",
- dev->name);
- goto out;
- }
- if (nickbuf.len)
- len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
- else
- len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
- memcpy(priv->nick, &nickbuf.val, len);
- priv->nick[len] = '\0';
-
- printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
-
- err = orinoco_allocate_fid(dev);
- if (err) {
- printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
- dev->name);
- goto out;
- }
-
- /* Get allowed channels */
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
- &priv->channel_mask);
- if (err) {
- printk(KERN_ERR "%s: failed to read channel list!\n",
- dev->name);
- goto out;
- }
-
- /* Get initial AP density */
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
- &priv->ap_density);
- if (err || priv->ap_density < 1 || priv->ap_density > 3) {
- priv->has_sensitivity = 0;
- }
-
- /* Get initial RTS threshold */
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
- &priv->rts_thresh);
- if (err) {
- printk(KERN_ERR "%s: failed to read RTS threshold!\n",
- dev->name);
- goto out;
- }
-
- /* Get initial fragmentation settings */
- if (priv->has_mwo)
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMWOROBUST_AGERE,
- &priv->mwo_robust);
- else
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
- &priv->frag_thresh);
- if (err) {
- printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
- dev->name);
- goto out;
- }
-
- /* Power management setup */
- if (priv->has_pm) {
- priv->pm_on = 0;
- priv->pm_mcast = 1;
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMAXSLEEPDURATION,
- &priv->pm_period);
- if (err) {
- printk(KERN_ERR "%s: failed to read power management period!\n",
- dev->name);
- goto out;
- }
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPMHOLDOVERDURATION,
- &priv->pm_timeout);
- if (err) {
- printk(KERN_ERR "%s: failed to read power management timeout!\n",
- dev->name);
- goto out;
- }
- }
-
- /* Preamble setup */
- if (priv->has_preamble) {
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPREAMBLE_SYMBOL,
- &priv->preamble);
- if (err)
- goto out;
- }
-
- /* Set up the default configuration */
- priv->iw_mode = IW_MODE_INFRA;
- /* By default use IEEE/IBSS ad-hoc mode if we have it */
- priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
- set_port_type(priv);
- priv->channel = 0; /* use firmware default */
-
- priv->promiscuous = 0;
- priv->encode_alg = IW_ENCODE_ALG_NONE;
- priv->tx_key = 0;
- priv->wpa_enabled = 0;
- priv->tkip_cm_active = 0;
- priv->key_mgmt = 0;
- priv->wpa_ie_len = 0;
- priv->wpa_ie = NULL;
-
- /* Make the hardware available, as long as it hasn't been
- * removed elsewhere (e.g. by PCMCIA hot unplug) */
- spin_lock_irq(&priv->lock);
- priv->hw_unavailable--;
- spin_unlock_irq(&priv->lock);
-
- printk(KERN_DEBUG "%s: ready\n", dev->name);
-
- out:
- return err;
-}
-
-struct net_device
-*alloc_orinocodev(int sizeof_card,
- struct device *device,
- int (*hard_reset)(struct orinoco_private *),
- int (*stop_fw)(struct orinoco_private *, int))
-{
- struct net_device *dev;
- struct orinoco_private *priv;
-
- dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
- if (! dev)
- return NULL;
- priv = netdev_priv(dev);
- priv->ndev = dev;
- if (sizeof_card)
- priv->card = (void *)((unsigned long)priv
- + sizeof(struct orinoco_private));
- else
- priv->card = NULL;
- priv->dev = device;
-
- /* Setup / override net_device fields */
- dev->init = orinoco_init;
- dev->hard_start_xmit = orinoco_xmit;
- dev->tx_timeout = orinoco_tx_timeout;
- dev->watchdog_timeo = HZ; /* 1 second timeout */
- dev->get_stats = orinoco_get_stats;
- dev->ethtool_ops = &orinoco_ethtool_ops;
- dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
-#ifdef WIRELESS_SPY
- priv->wireless_data.spy_data = &priv->spy_data;
- dev->wireless_data = &priv->wireless_data;
-#endif
- dev->change_mtu = orinoco_change_mtu;
- dev->set_multicast_list = orinoco_set_multicast_list;
- /* we use the default eth_mac_addr for setting the MAC addr */
-
- /* Reserve space in skb for the SNAP header */
- dev->hard_header_len += ENCAPS_OVERHEAD;
-
- /* Set up default callbacks */
- dev->open = orinoco_open;
- dev->stop = orinoco_stop;
- priv->hard_reset = hard_reset;
- priv->stop_fw = stop_fw;
-
- spin_lock_init(&priv->lock);
- priv->open = 0;
- priv->hw_unavailable = 1; /* orinoco_init() must clear this
- * before anything else touches the
- * hardware */
- INIT_WORK(&priv->reset_work, orinoco_reset);
- INIT_WORK(&priv->join_work, orinoco_join_ap);
- INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
-
- INIT_LIST_HEAD(&priv->rx_list);
- tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
- (unsigned long) dev);
-
- netif_carrier_off(dev);
- priv->last_linkstatus = 0xffff;
-
- priv->cached_pri_fw = NULL;
- priv->cached_fw = NULL;
-
- /* Register PM notifiers */
- priv->pm_notifier.notifier_call = orinoco_pm_notifier;
- register_pm_notifier(&priv->pm_notifier);
-
- return dev;
-}
-
-void free_orinocodev(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct orinoco_rx_data *rx_data, *temp;
-
- /* If the tasklet is scheduled when we call tasklet_kill it
- * will run one final time. However the tasklet will only
- * drain priv->rx_list if the hw is still available. */
- tasklet_kill(&priv->rx_tasklet);
-
- /* Explicitly drain priv->rx_list */
- list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
- list_del(&rx_data->list);
-
- dev_kfree_skb(rx_data->skb);
- kfree(rx_data->desc);
- kfree(rx_data);
- }
-
- unregister_pm_notifier(&priv->pm_notifier);
- orinoco_uncache_fw(priv);
-
- priv->wpa_ie_len = 0;
- kfree(priv->wpa_ie);
- orinoco_mic_free(priv);
- orinoco_bss_data_free(priv);
- free_netdev(dev);
-}
-
-/********************************************************************/
-/* Wireless extensions */
-/********************************************************************/
-
-/* Return : < 0 -> error code ; >= 0 -> length */
-static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
- char buf[IW_ESSID_MAX_SIZE+1])
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
- struct hermes_idstring essidbuf;
- char *p = (char *)(&essidbuf.val);
- int len;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (strlen(priv->desired_essid) > 0) {
- /* We read the desired SSID from the hardware rather
- than from priv->desired_essid, just in case the
- firmware is allowed to change it on us. I'm not
- sure about this */
- /* My guess is that the OWNSSID should always be whatever
- * we set to the card, whereas CURRENT_SSID is the one that
- * may change... - Jean II */
- u16 rid;
-
- *active = 1;
-
- rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
- HERMES_RID_CNFDESIREDSSID;
-
- err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
- NULL, &essidbuf);
- if (err)
- goto fail_unlock;
- } else {
- *active = 0;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
- sizeof(essidbuf), NULL, &essidbuf);
- if (err)
- goto fail_unlock;
- }
-
- len = le16_to_cpu(essidbuf.len);
- BUG_ON(len > IW_ESSID_MAX_SIZE);
-
- memset(buf, 0, IW_ESSID_MAX_SIZE);
- memcpy(buf, p, len);
- err = len;
-
- fail_unlock:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static long orinoco_hw_get_freq(struct orinoco_private *priv)
-{
-
- hermes_t *hw = &priv->hw;
- int err = 0;
- u16 channel;
- long freq = 0;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
- if (err)
- goto out;
-
- /* Intersil firmware 1.3.5 returns 0 when the interface is down */
- if (channel == 0) {
- err = -EBUSY;
- goto out;
- }
-
- if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
- printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
- priv->ndev->name, channel);
- err = -EBUSY;
- goto out;
-
- }
- freq = channel_frequency[channel-1] * 100000;
-
- out:
- orinoco_unlock(priv, &flags);
-
- if (err > 0)
- err = -EBUSY;
- return err ? err : freq;
-}
-
-static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
- int *numrates, s32 *rates, int max)
-{
- hermes_t *hw = &priv->hw;
- struct hermes_idstring list;
- unsigned char *p = (unsigned char *)&list.val;
- int err = 0;
- int num;
- int i;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
- sizeof(list), NULL, &list);
- orinoco_unlock(priv, &flags);
-
- if (err)
- return err;
-
- num = le16_to_cpu(list.len);
- *numrates = num;
- num = min(num, max);
-
- for (i = 0; i < num; i++) {
- rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
- }
-
- return 0;
-}
-
-static int orinoco_ioctl_getname(struct net_device *dev,
- struct iw_request_info *info,
- char *name,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int numrates;
- int err;
-
- err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
-
- if (!err && (numrates > 2))
- strcpy(name, "IEEE 802.11b");
- else
- strcpy(name, "IEEE 802.11-DS");
-
- return 0;
-}
-
-static int orinoco_ioctl_setwap(struct net_device *dev,
- struct iw_request_info *info,
- struct sockaddr *ap_addr,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
- static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* Enable automatic roaming - no sanity checks are needed */
- if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
- memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
- priv->bssid_fixed = 0;
- memset(priv->desired_bssid, 0, ETH_ALEN);
-
- /* "off" means keep existing connection */
- if (ap_addr->sa_data[0] == 0) {
- __orinoco_hw_set_wap(priv);
- err = 0;
- }
- goto out;
- }
-
- if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
- printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
- "support manual roaming\n",
- dev->name);
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (priv->iw_mode != IW_MODE_INFRA) {
- printk(KERN_WARNING "%s: Manual roaming supported only in "
- "managed mode\n", dev->name);
- err = -EOPNOTSUPP;
- goto out;
- }
-
- /* Intersil firmware hangs without Desired ESSID */
- if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
- strlen(priv->desired_essid) == 0) {
- printk(KERN_WARNING "%s: Desired ESSID must be set for "
- "manual roaming\n", dev->name);
- err = -EOPNOTSUPP;
- goto out;
- }
-
- /* Finally, enable manual roaming */
- priv->bssid_fixed = 1;
- memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
-
- out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-static int orinoco_ioctl_getwap(struct net_device *dev,
- struct iw_request_info *info,
- struct sockaddr *ap_addr,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- hermes_t *hw = &priv->hw;
- int err = 0;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- ap_addr->sa_family = ARPHRD_ETHER;
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
- ETH_ALEN, NULL, ap_addr->sa_data);
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_setmode(struct net_device *dev,
- struct iw_request_info *info,
- u32 *mode,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
-
- if (priv->iw_mode == *mode)
- return 0;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (*mode) {
- case IW_MODE_ADHOC:
- if (!priv->has_ibss && !priv->has_port3)
- err = -EOPNOTSUPP;
- break;
-
- case IW_MODE_INFRA:
- break;
-
- case IW_MODE_MONITOR:
- if (priv->broken_monitor && !force_monitor) {
- printk(KERN_WARNING "%s: Monitor mode support is "
- "buggy in this firmware, not enabling\n",
- dev->name);
- err = -EOPNOTSUPP;
- }
- break;
-
- default:
- err = -EOPNOTSUPP;
- break;
- }
-
- if (err == -EINPROGRESS) {
- priv->iw_mode = *mode;
- set_port_type(priv);
- }
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getmode(struct net_device *dev,
- struct iw_request_info *info,
- u32 *mode,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- *mode = priv->iw_mode;
- return 0;
-}
-
-static int orinoco_ioctl_getiwrange(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = 0;
- struct iw_range *range = (struct iw_range *) extra;
- int numrates;
- int i, k;
-
- rrq->length = sizeof(struct iw_range);
- memset(range, 0, sizeof(struct iw_range));
-
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 22;
-
- /* Set available channels/frequencies */
- range->num_channels = NUM_CHANNELS;
- k = 0;
- for (i = 0; i < NUM_CHANNELS; i++) {
- if (priv->channel_mask & (1 << i)) {
- range->freq[k].i = i + 1;
- range->freq[k].m = channel_frequency[i] * 100000;
- range->freq[k].e = 1;
- k++;
- }
-
- if (k >= IW_MAX_FREQUENCIES)
- break;
- }
- range->num_frequency = k;
- range->sensitivity = 3;
-
- if (priv->has_wep) {
- range->max_encoding_tokens = ORINOCO_MAX_KEYS;
- range->encoding_size[0] = SMALL_KEY_SIZE;
- range->num_encoding_sizes = 1;
-
- if (priv->has_big_wep) {
- range->encoding_size[1] = LARGE_KEY_SIZE;
- range->num_encoding_sizes = 2;
- }
- }
-
- if (priv->has_wpa)
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
-
- if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
- /* Quality stats meaningless in ad-hoc mode */
- } else {
- range->max_qual.qual = 0x8b - 0x2f;
- range->max_qual.level = 0x2f - 0x95 - 1;
- range->max_qual.noise = 0x2f - 0x95 - 1;
- /* Need to get better values */
- range->avg_qual.qual = 0x24;
- range->avg_qual.level = 0xC2;
- range->avg_qual.noise = 0x9E;
- }
-
- err = orinoco_hw_get_bitratelist(priv, &numrates,
- range->bitrate, IW_MAX_BITRATES);
- if (err)
- return err;
- range->num_bitrates = numrates;
-
- /* Set an indication of the max TCP throughput in bit/s that we can
- * expect using this interface. May be use for QoS stuff...
- * Jean II */
- if (numrates > 2)
- range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
- else
- range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
-
- range->min_rts = 0;
- range->max_rts = 2347;
- range->min_frag = 256;
- range->max_frag = 2346;
-
- range->min_pmp = 0;
- range->max_pmp = 65535000;
- range->min_pmt = 0;
- range->max_pmt = 65535 * 1000; /* ??? */
- range->pmp_flags = IW_POWER_PERIOD;
- range->pmt_flags = IW_POWER_TIMEOUT;
- range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
-
- range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
- range->retry_flags = IW_RETRY_LIMIT;
- range->r_time_flags = IW_RETRY_LIFETIME;
- range->min_retry = 0;
- range->max_retry = 65535; /* ??? */
- range->min_r_time = 0;
- range->max_r_time = 65535 * 1000; /* ??? */
-
- if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
- range->scan_capa = IW_SCAN_CAPA_ESSID;
- else
- range->scan_capa = IW_SCAN_CAPA_NONE;
-
- /* Event capability (kernel) */
- IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
- /* Event capability (driver) */
- IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
- IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
- IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
- IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
-
- return 0;
-}
-
-static int orinoco_ioctl_setiwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq,
- char *keybuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int index = (erq->flags & IW_ENCODE_INDEX) - 1;
- int setindex = priv->tx_key;
- int encode_alg = priv->encode_alg;
- int restricted = priv->wep_restrict;
- u16 xlen = 0;
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
-
- if (! priv->has_wep)
- return -EOPNOTSUPP;
-
- if (erq->pointer) {
- /* We actually have a key to set - check its length */
- if (erq->length > LARGE_KEY_SIZE)
- return -E2BIG;
-
- if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
- return -E2BIG;
- }
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* Clear any TKIP key we have */
- if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
- (void) orinoco_clear_tkip_key(priv, setindex);
-
- if (erq->length > 0) {
- if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
- index = priv->tx_key;
-
- /* Adjust key length to a supported value */
- if (erq->length > SMALL_KEY_SIZE) {
- xlen = LARGE_KEY_SIZE;
- } else if (erq->length > 0) {
- xlen = SMALL_KEY_SIZE;
- } else
- xlen = 0;
-
- /* Switch on WEP if off */
- if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
- setindex = index;
- encode_alg = IW_ENCODE_ALG_WEP;
- }
- } else {
- /* Important note : if the user do "iwconfig eth0 enc off",
- * we will arrive there with an index of -1. This is valid
- * but need to be taken care off... Jean II */
- if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
- if((index != -1) || (erq->flags == 0)) {
- err = -EINVAL;
- goto out;
- }
- } else {
- /* Set the index : Check that the key is valid */
- if(priv->keys[index].len == 0) {
- err = -EINVAL;
- goto out;
- }
- setindex = index;
- }
- }
-
- if (erq->flags & IW_ENCODE_DISABLED)
- encode_alg = IW_ENCODE_ALG_NONE;
- if (erq->flags & IW_ENCODE_OPEN)
- restricted = 0;
- if (erq->flags & IW_ENCODE_RESTRICTED)
- restricted = 1;
-
- if (erq->pointer && erq->length > 0) {
- priv->keys[index].len = cpu_to_le16(xlen);
- memset(priv->keys[index].data, 0,
- sizeof(priv->keys[index].data));
- memcpy(priv->keys[index].data, keybuf, erq->length);
- }
- priv->tx_key = setindex;
-
- /* Try fast key change if connected and only keys are changed */
- if ((priv->encode_alg == encode_alg) &&
- (priv->wep_restrict == restricted) &&
- netif_carrier_ok(dev)) {
- err = __orinoco_hw_setup_wepkeys(priv);
- /* No need to commit if successful */
- goto out;
- }
-
- priv->encode_alg = encode_alg;
- priv->wep_restrict = restricted;
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getiwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq,
- char *keybuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int index = (erq->flags & IW_ENCODE_INDEX) - 1;
- u16 xlen = 0;
- unsigned long flags;
-
- if (! priv->has_wep)
- return -EOPNOTSUPP;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
- index = priv->tx_key;
-
- erq->flags = 0;
- if (!priv->encode_alg)
- erq->flags |= IW_ENCODE_DISABLED;
- erq->flags |= index + 1;
-
- if (priv->wep_restrict)
- erq->flags |= IW_ENCODE_RESTRICTED;
- else
- erq->flags |= IW_ENCODE_OPEN;
-
- xlen = le16_to_cpu(priv->keys[index].len);
-
- erq->length = xlen;
-
- memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
-
- orinoco_unlock(priv, &flags);
- return 0;
-}
-
-static int orinoco_ioctl_setessid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq,
- char *essidbuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
- * anyway... - Jean II */
-
- /* Hum... Should not use Wireless Extension constant (may change),
- * should use our own... - Jean II */
- if (erq->length > IW_ESSID_MAX_SIZE)
- return -E2BIG;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
- memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
-
- /* If not ANY, get the new ESSID */
- if (erq->flags) {
- memcpy(priv->desired_essid, essidbuf, erq->length);
- }
-
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getessid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq,
- char *essidbuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int active;
- int err = 0;
- unsigned long flags;
-
- if (netif_running(dev)) {
- err = orinoco_hw_get_essid(priv, &active, essidbuf);
- if (err < 0)
- return err;
- erq->length = err;
- } else {
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
- memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
- erq->length = strlen(priv->desired_essid);
- orinoco_unlock(priv, &flags);
- }
-
- erq->flags = 1;
-
- return 0;
-}
-
-static int orinoco_ioctl_setnick(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *nrq,
- char *nickbuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- if (nrq->length > IW_ESSID_MAX_SIZE)
- return -E2BIG;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- memset(priv->nick, 0, sizeof(priv->nick));
- memcpy(priv->nick, nickbuf, nrq->length);
-
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getnick(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *nrq,
- char *nickbuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
- orinoco_unlock(priv, &flags);
-
- nrq->length = strlen(priv->nick);
-
- return 0;
-}
-
-static int orinoco_ioctl_setfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *frq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int chan = -1;
- unsigned long flags;
- int err = -EINPROGRESS; /* Call commit handler */
-
- /* In infrastructure mode the AP sets the channel */
- if (priv->iw_mode == IW_MODE_INFRA)
- return -EBUSY;
-
- if ( (frq->e == 0) && (frq->m <= 1000) ) {
- /* Setting by channel number */
- chan = frq->m;
- } else {
- /* Setting by frequency - search the table */
- int mult = 1;
- int i;
-
- for (i = 0; i < (6 - frq->e); i++)
- mult *= 10;
-
- for (i = 0; i < NUM_CHANNELS; i++)
- if (frq->m == (channel_frequency[i] * mult))
- chan = i+1;
- }
-
- if ( (chan < 1) || (chan > NUM_CHANNELS) ||
- ! (priv->channel_mask & (1 << (chan-1)) ) )
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- priv->channel = chan;
- if (priv->iw_mode == IW_MODE_MONITOR) {
- /* Fast channel change - no commit if successful */
- hermes_t *hw = &priv->hw;
- err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
- HERMES_TEST_SET_CHANNEL,
- chan, NULL);
- }
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *frq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int tmp;
-
- /* Locking done in there */
- tmp = orinoco_hw_get_freq(priv);
- if (tmp < 0) {
- return tmp;
- }
-
- frq->m = tmp;
- frq->e = 1;
-
- return 0;
-}
-
-static int orinoco_ioctl_getsens(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- u16 val;
- int err;
- unsigned long flags;
-
- if (!priv->has_sensitivity)
- return -EOPNOTSUPP;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSYSTEMSCALE, &val);
- orinoco_unlock(priv, &flags);
-
- if (err)
- return err;
-
- srq->value = val;
- srq->fixed = 0; /* auto */
-
- return 0;
-}
-
-static int orinoco_ioctl_setsens(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int val = srq->value;
- unsigned long flags;
-
- if (!priv->has_sensitivity)
- return -EOPNOTSUPP;
-
- if ((val < 1) || (val > 3))
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
- priv->ap_density = val;
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_setrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int val = rrq->value;
- unsigned long flags;
-
- if (rrq->disabled)
- val = 2347;
-
- if ( (val < 0) || (val > 2347) )
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- priv->rts_thresh = val;
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- rrq->value = priv->rts_thresh;
- rrq->disabled = (rrq->value == 2347);
- rrq->fixed = 1;
-
- return 0;
-}
-
-static int orinoco_ioctl_setfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (priv->has_mwo) {
- if (frq->disabled)
- priv->mwo_robust = 0;
- else {
- if (frq->fixed)
- printk(KERN_WARNING "%s: Fixed fragmentation is "
- "not supported on this firmware. "
- "Using MWO robust instead.\n", dev->name);
- priv->mwo_robust = 1;
- }
- } else {
- if (frq->disabled)
- priv->frag_thresh = 2346;
- else {
- if ( (frq->value < 256) || (frq->value > 2346) )
- err = -EINVAL;
- else
- priv->frag_thresh = frq->value & ~0x1; /* must be even */
- }
- }
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err;
- u16 val;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (priv->has_mwo) {
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMWOROBUST_AGERE,
- &val);
- if (err)
- val = 0;
-
- frq->value = val ? 2347 : 0;
- frq->disabled = ! val;
- frq->fixed = 0;
- } else {
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
- &val);
- if (err)
- val = 0;
-
- frq->value = val;
- frq->disabled = (val >= 2346);
- frq->fixed = 1;
- }
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_setrate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int ratemode = -1;
- int bitrate; /* 100s of kilobits */
- int i;
- unsigned long flags;
-
- /* As the user space doesn't know our highest rate, it uses -1
- * to ask us to set the highest rate. Test it using "iwconfig
- * ethX rate auto" - Jean II */
- if (rrq->value == -1)
- bitrate = 110;
- else {
- if (rrq->value % 100000)
- return -EINVAL;
- bitrate = rrq->value / 100000;
- }
-
- if ( (bitrate != 10) && (bitrate != 20) &&
- (bitrate != 55) && (bitrate != 110) )
- return -EINVAL;
-
- for (i = 0; i < BITRATE_TABLE_SIZE; i++)
- if ( (bitrate_table[i].bitrate == bitrate) &&
- (bitrate_table[i].automatic == ! rrq->fixed) ) {
- ratemode = i;
- break;
- }
-
- if (ratemode == -1)
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
- priv->bitratemode = ratemode;
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS;
-}
-
-static int orinoco_ioctl_getrate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- int ratemode;
- int i;
- u16 val;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- ratemode = priv->bitratemode;
-
- BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
-
- rrq->value = bitrate_table[ratemode].bitrate * 100000;
- rrq->fixed = ! bitrate_table[ratemode].automatic;
- rrq->disabled = 0;
-
- /* If the interface is running we try to find more about the
- current mode */
- if (netif_running(dev)) {
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CURRENTTXRATE, &val);
- if (err)
- goto out;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
- /* Note : in Lucent firmware, the return value of
- * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
- * and therefore is totally different from the
- * encoding of HERMES_RID_CNFTXRATECONTROL.
- * Don't forget that 6Mb/s is really 5.5Mb/s */
- if (val == 6)
- rrq->value = 5500000;
- else
- rrq->value = val * 1000000;
- break;
- case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
- case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
- for (i = 0; i < BITRATE_TABLE_SIZE; i++)
- if (bitrate_table[i].intersil_txratectrl == val) {
- ratemode = i;
- break;
- }
- if (i >= BITRATE_TABLE_SIZE)
- printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
- dev->name, val);
-
- rrq->value = bitrate_table[ratemode].bitrate * 100000;
- break;
- default:
- BUG();
- }
- }
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_setpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *prq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (prq->disabled) {
- priv->pm_on = 0;
- } else {
- switch (prq->flags & IW_POWER_MODE) {
- case IW_POWER_UNICAST_R:
- priv->pm_mcast = 0;
- priv->pm_on = 1;
- break;
- case IW_POWER_ALL_R:
- priv->pm_mcast = 1;
- priv->pm_on = 1;
- break;
- case IW_POWER_ON:
- /* No flags : but we may have a value - Jean II */
- break;
- default:
- err = -EINVAL;
- goto out;
- }
-
- if (prq->flags & IW_POWER_TIMEOUT) {
- priv->pm_on = 1;
- priv->pm_timeout = prq->value / 1000;
- }
- if (prq->flags & IW_POWER_PERIOD) {
- priv->pm_on = 1;
- priv->pm_period = prq->value / 1000;
- }
- /* It's valid to not have a value if we are just toggling
- * the flags... Jean II */
- if(!priv->pm_on) {
- err = -EINVAL;
- goto out;
- }
- }
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *prq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- u16 enable, period, timeout, mcast;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMAXSLEEPDURATION, &period);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
- if (err)
- goto out;
-
- prq->disabled = !enable;
- /* Note : by default, display the period */
- if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- prq->flags = IW_POWER_TIMEOUT;
- prq->value = timeout * 1000;
- } else {
- prq->flags = IW_POWER_PERIOD;
- prq->value = period * 1000;
- }
- if (mcast)
- prq->flags |= IW_POWER_ALL_R;
- else
- prq->flags |= IW_POWER_UNICAST_R;
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_set_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, alg = ext->alg, set_key = 1;
- unsigned long flags;
- int err = -EINVAL;
- u16 key_len;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* Determine and validate the key index */
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if ((idx < 1) || (idx > 4))
- goto out;
- idx--;
- } else
- idx = priv->tx_key;
-
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
-
- if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
- /* Clear any TKIP TX key we had */
- (void) orinoco_clear_tkip_key(priv, priv->tx_key);
- }
-
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- priv->tx_key = idx;
- set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
- (ext->key_len > 0)) ? 1 : 0;
- }
-
- if (set_key) {
- /* Set the requested key first */
- switch (alg) {
- case IW_ENCODE_ALG_NONE:
- priv->encode_alg = alg;
- priv->keys[idx].len = 0;
- break;
-
- case IW_ENCODE_ALG_WEP:
- if (ext->key_len > SMALL_KEY_SIZE)
- key_len = LARGE_KEY_SIZE;
- else if (ext->key_len > 0)
- key_len = SMALL_KEY_SIZE;
- else
- goto out;
-
- priv->encode_alg = alg;
- priv->keys[idx].len = cpu_to_le16(key_len);
-
- key_len = min(ext->key_len, key_len);
-
- memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
- memcpy(priv->keys[idx].data, ext->key, key_len);
- break;
-
- case IW_ENCODE_ALG_TKIP:
- {
- hermes_t *hw = &priv->hw;
- u8 *tkip_iv = NULL;
-
- if (!priv->has_wpa ||
- (ext->key_len > sizeof(priv->tkip_key[0])))
- goto out;
-
- priv->encode_alg = alg;
- memset(&priv->tkip_key[idx], 0,
- sizeof(priv->tkip_key[idx]));
- memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
-
- if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
- tkip_iv = &ext->rx_seq[0];
-
- err = __orinoco_hw_set_tkip_key(hw, idx,
- ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
- (u8 *) &priv->tkip_key[idx],
- tkip_iv, NULL);
- if (err)
- printk(KERN_ERR "%s: Error %d setting TKIP key"
- "\n", dev->name, err);
-
- goto out;
- }
- default:
- goto out;
- }
- }
- err = -EINPROGRESS;
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_get_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, max_key_len;
- unsigned long flags;
- int err;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = -EINVAL;
- max_key_len = encoding->length - sizeof(*ext);
- if (max_key_len < 0)
- goto out;
-
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if ((idx < 1) || (idx > 4))
- goto out;
- idx--;
- } else
- idx = priv->tx_key;
-
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
-
- ext->alg = priv->encode_alg;
- switch (priv->encode_alg) {
- case IW_ENCODE_ALG_NONE:
- ext->key_len = 0;
- encoding->flags |= IW_ENCODE_DISABLED;
- break;
- case IW_ENCODE_ALG_WEP:
- ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
- max_key_len);
- memcpy(ext->key, priv->keys[idx].data, ext->key_len);
- encoding->flags |= IW_ENCODE_ENABLED;
- break;
- case IW_ENCODE_ALG_TKIP:
- ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
- max_key_len);
- memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
- encoding->flags |= IW_ENCODE_ENABLED;
- break;
- }
-
- err = 0;
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- struct iw_param *param = &wrqu->param;
- unsigned long flags;
- int ret = -EINPROGRESS;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- case IW_AUTH_PRIVACY_INVOKED:
- case IW_AUTH_DROP_UNENCRYPTED:
- /*
- * orinoco does not use these parameters
- */
- break;
-
- case IW_AUTH_KEY_MGMT:
- /* wl_lkm implies value 2 == PSK for Hermes I
- * which ties in with WEXT
- * no other hints tho :(
- */
- priv->key_mgmt = param->value;
- break;
-
- case IW_AUTH_TKIP_COUNTERMEASURES:
- /* When countermeasures are enabled, shut down the
- * card; when disabled, re-enable the card. This must
- * take effect immediately.
- *
- * TODO: Make sure that the EAPOL message is getting
- * out before card disabled
- */
- if (param->value) {
- priv->tkip_cm_active = 1;
- ret = hermes_enable_port(hw, 0);
- } else {
- priv->tkip_cm_active = 0;
- ret = hermes_disable_port(hw, 0);
- }
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- if (param->value & IW_AUTH_ALG_SHARED_KEY)
- priv->wep_restrict = 1;
- else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
- priv->wep_restrict = 0;
- else
- ret = -EINVAL;
- break;
-
- case IW_AUTH_WPA_ENABLED:
- if (priv->has_wpa) {
- priv->wpa_enabled = param->value ? 1 : 0;
- } else {
- if (param->value)
- ret = -EOPNOTSUPP;
- /* else silently accept disable of WPA */
- priv->wpa_enabled = 0;
- }
- break;
-
- default:
- ret = -EOPNOTSUPP;
- }
-
- orinoco_unlock(priv, &flags);
- return ret;
-}
-
-static int orinoco_ioctl_get_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct iw_param *param = &wrqu->param;
- unsigned long flags;
- int ret = 0;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_KEY_MGMT:
- param->value = priv->key_mgmt;
- break;
-
- case IW_AUTH_TKIP_COUNTERMEASURES:
- param->value = priv->tkip_cm_active;
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- if (priv->wep_restrict)
- param->value = IW_AUTH_ALG_SHARED_KEY;
- else
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
-
- case IW_AUTH_WPA_ENABLED:
- param->value = priv->wpa_enabled;
- break;
-
- default:
- ret = -EOPNOTSUPP;
- }
-
- orinoco_unlock(priv, &flags);
- return ret;
-}
-
-static int orinoco_ioctl_set_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- u8 *buf;
- unsigned long flags;
- int err = 0;
-
- /* cut off at IEEE80211_MAX_DATA_LEN */
- if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
- (wrqu->data.length && (extra == NULL)))
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (wrqu->data.length) {
- buf = kmalloc(wrqu->data.length, GFP_KERNEL);
- if (buf == NULL) {
- err = -ENOMEM;
- goto out;
- }
-
- memcpy(buf, extra, wrqu->data.length);
- kfree(priv->wpa_ie);
- priv->wpa_ie = buf;
- priv->wpa_ie_len = wrqu->data.length;
- } else {
- kfree(priv->wpa_ie);
- priv->wpa_ie = NULL;
- priv->wpa_ie_len = 0;
- }
-
- if (priv->wpa_ie) {
- /* Looks like wl_lkm wants to check the auth alg, and
- * somehow pass it to the firmware.
- * Instead it just calls the key mgmt rid
- * - we do this in set auth.
- */
- }
-
-out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-static int orinoco_ioctl_get_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err = 0;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
- wrqu->data.length = 0;
- goto out;
- }
-
- if (wrqu->data.length < priv->wpa_ie_len) {
- err = -E2BIG;
- goto out;
- }
-
- wrqu->data.length = priv->wpa_ie_len;
- memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
-
-out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-static int orinoco_ioctl_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
- unsigned long flags;
- int ret = 0;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- /* silently ignore */
- break;
-
- case IW_MLME_DISASSOC:
- {
- struct {
- u8 addr[ETH_ALEN];
- __le16 reason_code;
- } __attribute__ ((packed)) buf;
-
- memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
- buf.reason_code = cpu_to_le16(mlme->reason_code);
- ret = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFDISASSOCIATE,
- &buf);
- break;
- }
- default:
- ret = -EOPNOTSUPP;
- }
-
- orinoco_unlock(priv, &flags);
- return ret;
-}
-
-static int orinoco_ioctl_getretry(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- u16 short_limit, long_limit, lifetime;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
- &short_limit);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
- &long_limit);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
- &lifetime);
- if (err)
- goto out;
-
- rrq->disabled = 0; /* Can't be disabled */
-
- /* Note : by default, display the retry number */
- if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
- rrq->flags = IW_RETRY_LIFETIME;
- rrq->value = lifetime * 1000; /* ??? */
- } else {
- /* By default, display the min number */
- if ((rrq->flags & IW_RETRY_LONG)) {
- rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
- rrq->value = long_limit;
- } else {
- rrq->flags = IW_RETRY_LIMIT;
- rrq->value = short_limit;
- if(short_limit != long_limit)
- rrq->flags |= IW_RETRY_SHORT;
- }
- }
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_reset(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- if (! capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
- printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
-
- /* Firmware reset */
- orinoco_reset(&priv->reset_work);
- } else {
- printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
-
- schedule_work(&priv->reset_work);
- }
-
- return 0;
-}
-
-static int orinoco_ioctl_setibssport(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int val = *( (int *) extra );
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- priv->ibss_port = val ;
-
- /* Actually update the mode we are using */
- set_port_type(priv);
-
- orinoco_unlock(priv, &flags);
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getibssport(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int *val = (int *) extra;
-
- *val = priv->ibss_port;
- return 0;
-}
-
-static int orinoco_ioctl_setport3(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int val = *( (int *) extra );
- int err = 0;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (val) {
- case 0: /* Try to do IEEE ad-hoc mode */
- if (! priv->has_ibss) {
- err = -EINVAL;
- break;
- }
- priv->prefer_port3 = 0;
-
- break;
-
- case 1: /* Try to do Lucent proprietary ad-hoc mode */
- if (! priv->has_port3) {
- err = -EINVAL;
- break;
- }
- priv->prefer_port3 = 1;
- break;
-
- default:
- err = -EINVAL;
- }
-
- if (! err) {
- /* Actually update the mode we are using */
- set_port_type(priv);
- err = -EINPROGRESS;
- }
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getport3(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int *val = (int *) extra;
-
- *val = priv->prefer_port3;
- return 0;
-}
-
-static int orinoco_ioctl_setpreamble(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int val;
-
- if (! priv->has_preamble)
- return -EOPNOTSUPP;
-
- /* 802.11b has recently defined some short preamble.
- * Basically, the Phy header has been reduced in size.
- * This increase performance, especially at high rates
- * (the preamble is transmitted at 1Mb/s), unfortunately
- * this give compatibility troubles... - Jean II */
- val = *( (int *) extra );
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (val)
- priv->preamble = 1;
- else
- priv->preamble = 0;
-
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getpreamble(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int *val = (int *) extra;
-
- if (! priv->has_preamble)
- return -EOPNOTSUPP;
-
- *val = priv->preamble;
- return 0;
-}
-
-/* ioctl interface to hermes_read_ltv()
- * To use with iwpriv, pass the RID as the token argument, e.g.
- * iwpriv get_rid [0xfc00]
- * At least Wireless Tools 25 is required to use iwpriv.
- * For Wireless Tools 25 and 26 append "dummy" are the end. */
-static int orinoco_ioctl_getrid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int rid = data->flags;
- u16 length;
- int err;
- unsigned long flags;
-
- /* It's a "get" function, but we don't want users to access the
- * WEP key and other raw firmware data */
- if (! capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (rid < 0xfc00 || rid > 0xffff)
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
- extra);
- if (err)
- goto out;
-
- data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
- MAX_RID_LEN);
-
- out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-/* Trigger a scan (look for other cells in the vicinity) */
-static int orinoco_ioctl_setscan(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- struct iw_scan_req *si = (struct iw_scan_req *) extra;
- int err = 0;
- unsigned long flags;
-
- /* Note : you may have realised that, as this is a SET operation,
- * this is privileged and therefore a normal user can't
- * perform scanning.
- * This is not an error, while the device perform scanning,
- * traffic doesn't flow, so it's a perfect DoS...
- * Jean II */
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* Scanning with port 0 disabled would fail */
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
-
- /* In monitor mode, the scan results are always empty.
- * Probe responses are passed to the driver as received
- * frames and could be processed in software. */
- if (priv->iw_mode == IW_MODE_MONITOR) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- /* Note : because we don't lock out the irq handler, the way
- * we access scan variables in priv is critical.
- * o scan_inprogress : not touched by irq handler
- * o scan_mode : not touched by irq handler
- * Before modifying anything on those variables, please think hard !
- * Jean II */
-
- /* Save flags */
- priv->scan_mode = srq->flags;
-
- /* Always trigger scanning, even if it's in progress.
- * This way, if the info frame get lost, we will recover somewhat
- * gracefully - Jean II */
-
- if (priv->has_hostscan) {
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_SYMBOL:
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFHOSTSCAN_SYMBOL,
- HERMES_HOSTSCAN_SYMBOL_ONCE |
- HERMES_HOSTSCAN_SYMBOL_BCAST);
- break;
- case FIRMWARE_TYPE_INTERSIL: {
- __le16 req[3];
-
- req[0] = cpu_to_le16(0x3fff); /* All channels */
- req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
- req[2] = 0; /* Any ESSID */
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFHOSTSCAN, &req);
- }
- break;
- case FIRMWARE_TYPE_AGERE:
- if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
- struct hermes_idstring idbuf;
- size_t len = min(sizeof(idbuf.val),
- (size_t) si->essid_len);
- idbuf.len = cpu_to_le16(len);
- memcpy(idbuf.val, si->essid, len);
-
- err = hermes_write_ltv(hw, USER_BAP,
- HERMES_RID_CNFSCANSSID_AGERE,
- HERMES_BYTES_TO_RECLEN(len + 2),
- &idbuf);
- } else
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSCANSSID_AGERE,
- 0); /* Any ESSID */
- if (err)
- break;
-
- if (priv->has_ext_scan) {
- /* Clear scan results at the start of
- * an extended scan */
- orinoco_clear_scan_results(priv,
- msecs_to_jiffies(15000));
-
- /* TODO: Is this available on older firmware?
- * Can we use it to scan specific channels
- * for IW_SCAN_THIS_FREQ? */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSCANCHANNELS2GHZ,
- 0x7FFF);
- if (err)
- goto out;
-
- err = hermes_inquire(hw,
- HERMES_INQ_CHANNELINFO);
- } else
- err = hermes_inquire(hw, HERMES_INQ_SCAN);
- break;
- }
- } else
- err = hermes_inquire(hw, HERMES_INQ_SCAN);
-
- /* One more client */
- if (! err)
- priv->scan_inprogress = 1;
-
- out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-#define MAX_CUSTOM_LEN 64
-
-/* Translate scan data returned from the card to a card independant
- * format that the Wireless Tools will understand - Jean II */
-static inline char *orinoco_translate_scan(struct net_device *dev,
- struct iw_request_info *info,
- char *current_ev,
- char *end_buf,
- union hermes_scan_info *bss,
- unsigned long last_scanned)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- u16 capabilities;
- u16 channel;
- struct iw_event iwe; /* Temporary buffer */
- char custom[MAX_CUSTOM_LEN];
-
- memset(&iwe, 0, sizeof(iwe));
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_ADDR_LEN);
-
- /* Other entries will be displayed in the order we give them */
-
- /* Add the ESSID */
- iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
- if (iwe.u.data.length > 32)
- iwe.u.data.length = 32;
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, bss->a.essid);
-
- /* Add mode */
- iwe.cmd = SIOCGIWMODE;
- capabilities = le16_to_cpu(bss->a.capabilities);
- if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
- if (capabilities & WLAN_CAPABILITY_ESS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_UINT_LEN);
- }
-
- channel = bss->s.channel;
- if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
- /* Add channel and frequency */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = channel;
- iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
-
- iwe.u.freq.m = channel_frequency[channel-1] * 100000;
- iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
- }
-
- /* Add quality statistics. level and noise in dB. No link quality */
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
- iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
- iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
- /* Wireless tools prior to 27.pre22 will show link quality
- * anyway, so we provide a reasonable value. */
- if (iwe.u.qual.level > iwe.u.qual.noise)
- iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
- else
- iwe.u.qual.qual = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_QUAL_LEN);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (capabilities & WLAN_CAPABILITY_PRIVACY)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, NULL);
-
- /* Bit rate is not available in Lucent/Agere firmwares */
- if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
- char *current_val = current_ev + iwe_stream_lcp_len(info);
- int i;
- int step;
-
- if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
- step = 2;
- else
- step = 1;
-
- iwe.cmd = SIOCGIWRATE;
- /* Those two flags are ignored... */
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
- /* Max 10 values */
- for (i = 0; i < 10; i += step) {
- /* NULL terminated */
- if (bss->p.rates[i] == 0x0)
- break;
- /* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value =
- ((bss->p.rates[i] & 0x7f) * 500000);
- current_val = iwe_stream_add_value(info, current_ev,
- current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
- }
- /* Check if we added any event */
- if ((current_val - current_ev) > iwe_stream_lcp_len(info))
- current_ev = current_val;
- }
-
- /* Beacon interval */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- "bcn_int=%d",
- le16_to_cpu(bss->a.beacon_interv));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Capabilites */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- "capab=0x%04x",
- capabilities);
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network. */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- " Last beacon: %dms ago",
- jiffies_to_msecs(jiffies - last_scanned));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- return current_ev;
-}
-
-static inline char *orinoco_translate_ext_scan(struct net_device *dev,
- struct iw_request_info *info,
- char *current_ev,
- char *end_buf,
- struct agere_ext_scan_info *bss,
- unsigned long last_scanned)
-{
- u16 capabilities;
- u16 channel;
- struct iw_event iwe; /* Temporary buffer */
- char custom[MAX_CUSTOM_LEN];
- u8 *ie;
-
- memset(&iwe, 0, sizeof(iwe));
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_ADDR_LEN);
-
- /* Other entries will be displayed in the order we give them */
-
- /* Add the ESSID */
- ie = bss->data;
- iwe.u.data.length = ie[1];
- if (iwe.u.data.length) {
- if (iwe.u.data.length > 32)
- iwe.u.data.length = 32;
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, &ie[2]);
- }
-
- /* Add mode */
- capabilities = le16_to_cpu(bss->capabilities);
- if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
- iwe.cmd = SIOCGIWMODE;
- if (capabilities & WLAN_CAPABILITY_ESS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_UINT_LEN);
- }
-
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
- channel = ie ? ie[2] : 0;
- if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
- /* Add channel and frequency */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = channel;
- iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
-
- iwe.u.freq.m = channel_frequency[channel-1] * 100000;
- iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
- }
-
- /* Add quality statistics. level and noise in dB. No link quality */
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
- iwe.u.qual.level = bss->level - 0x95;
- iwe.u.qual.noise = bss->noise - 0x95;
- /* Wireless tools prior to 27.pre22 will show link quality
- * anyway, so we provide a reasonable value. */
- if (iwe.u.qual.level > iwe.u.qual.noise)
- iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
- else
- iwe.u.qual.qual = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_QUAL_LEN);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (capabilities & WLAN_CAPABILITY_PRIVACY)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, NULL);
-
- /* WPA IE */
- ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
- if (ie) {
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = ie[1] + 2;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, ie);
- }
-
- /* RSN IE */
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
- if (ie) {
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = ie[1] + 2;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, ie);
- }
-
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
- if (ie) {
- char *p = current_ev + iwe_stream_lcp_len(info);
- int i;
-
- iwe.cmd = SIOCGIWRATE;
- /* Those two flags are ignored... */
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
- for (i = 2; i < (ie[1] + 2); i++) {
- iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
- p = iwe_stream_add_value(info, current_ev, p, end_buf,
- &iwe, IW_EV_PARAM_LEN);
- }
- /* Check if we added any event */
- if (p > (current_ev + iwe_stream_lcp_len(info)))
- current_ev = p;
- }
-
- /* Timestamp */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length =
- snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
- (unsigned long long) le64_to_cpu(bss->timestamp));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Beacon interval */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- "bcn_int=%d",
- le16_to_cpu(bss->beacon_interval));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Capabilites */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- "capab=0x%04x",
- capabilities);
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network. */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- " Last beacon: %dms ago",
- jiffies_to_msecs(jiffies - last_scanned));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- return current_ev;
-}
-
-/* Return results of a scan */
-static int orinoco_ioctl_getscan(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = 0;
- unsigned long flags;
- char *current_ev = extra;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (priv->scan_inprogress) {
- /* Important note : we don't want to block the caller
- * until results are ready for various reasons.
- * First, managing wait queues is complex and racy.
- * Second, we grab some rtnetlink lock before comming
- * here (in dev_ioctl()).
- * Third, we generate an Wireless Event, so the
- * caller can wait itself on that - Jean II */
- err = -EAGAIN;
- goto out;
- }
-
- if (priv->has_ext_scan) {
- struct xbss_element *bss;
-
- list_for_each_entry(bss, &priv->bss_list, list) {
- /* Translate this entry to WE format */
- current_ev =
- orinoco_translate_ext_scan(dev, info,
- current_ev,
- extra + srq->length,
- &bss->bss,
- bss->last_scanned);
-
- /* Check if there is space for one more entry */
- if ((extra + srq->length - current_ev)
- <= IW_EV_ADDR_LEN) {
- /* Ask user space to try again with a
- * bigger buffer */
- err = -E2BIG;
- goto out;
- }
- }
-
- } else {
- struct bss_element *bss;
-
- list_for_each_entry(bss, &priv->bss_list, list) {
- /* Translate this entry to WE format */
- current_ev = orinoco_translate_scan(dev, info,
- current_ev,
- extra + srq->length,
- &bss->bss,
- bss->last_scanned);
-
- /* Check if there is space for one more entry */
- if ((extra + srq->length - current_ev)
- <= IW_EV_ADDR_LEN) {
- /* Ask user space to try again with a
- * bigger buffer */
- err = -E2BIG;
- goto out;
- }
- }
- }
-
- srq->length = (current_ev - extra);
- srq->flags = (__u16) priv->scan_mode;
-
-out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-/* Commit handler, called after set operations */
-static int orinoco_ioctl_commit(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- unsigned long flags;
- int err = 0;
-
- if (!priv->open)
- return 0;
-
- if (priv->broken_disableport) {
- orinoco_reset(&priv->reset_work);
- return 0;
- }
-
- if (orinoco_lock(priv, &flags) != 0)
- return err;
-
- err = hermes_disable_port(hw, 0);
- if (err) {
- printk(KERN_WARNING "%s: Unable to disable port "
- "while reconfiguring card\n", dev->name);
- priv->broken_disableport = 1;
- goto out;
- }
-
- err = __orinoco_program_rids(dev);
- if (err) {
- printk(KERN_WARNING "%s: Unable to reconfigure card\n",
- dev->name);
- goto out;
- }
-
- err = hermes_enable_port(hw, 0);
- if (err) {
- printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
- dev->name);
- goto out;
- }
-
- out:
- if (err) {
- printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
- schedule_work(&priv->reset_work);
- err = 0;
- }
-
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-static const struct iw_priv_args orinoco_privtab[] = {
- { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
- { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
- { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "set_port3" },
- { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_port3" },
- { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "set_preamble" },
- { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_preamble" },
- { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "set_ibssport" },
- { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_ibssport" },
- { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
- "get_rid" },
-};
-
-
-/*
- * Structures to export the Wireless Handlers
- */
-
-#define STD_IW_HANDLER(id, func) \
- [IW_IOCTL_IDX(id)] = (iw_handler) func
-static const iw_handler orinoco_handler[] = {
- STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit),
- STD_IW_HANDLER(SIOCGIWNAME, orinoco_ioctl_getname),
- STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq),
- STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq),
- STD_IW_HANDLER(SIOCSIWMODE, orinoco_ioctl_setmode),
- STD_IW_HANDLER(SIOCGIWMODE, orinoco_ioctl_getmode),
- STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens),
- STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens),
- STD_IW_HANDLER(SIOCGIWRANGE, orinoco_ioctl_getiwrange),
- STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
- STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
- STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
- STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
- STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap),
- STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap),
- STD_IW_HANDLER(SIOCSIWSCAN, orinoco_ioctl_setscan),
- STD_IW_HANDLER(SIOCGIWSCAN, orinoco_ioctl_getscan),
- STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid),
- STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid),
- STD_IW_HANDLER(SIOCSIWNICKN, orinoco_ioctl_setnick),
- STD_IW_HANDLER(SIOCGIWNICKN, orinoco_ioctl_getnick),
- STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate),
- STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate),
- STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts),
- STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts),
- STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag),
- STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag),
- STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry),
- STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode),
- STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode),
- STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower),
- STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower),
- STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
- STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
- STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
- STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
- STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
- STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
- STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
-};
-
-
-/*
- Added typecasting since we no longer use iwreq_data -- Moustafa
- */
-static const iw_handler orinoco_private_handler[] = {
- [0] = (iw_handler) orinoco_ioctl_reset,
- [1] = (iw_handler) orinoco_ioctl_reset,
- [2] = (iw_handler) orinoco_ioctl_setport3,
- [3] = (iw_handler) orinoco_ioctl_getport3,
- [4] = (iw_handler) orinoco_ioctl_setpreamble,
- [5] = (iw_handler) orinoco_ioctl_getpreamble,
- [6] = (iw_handler) orinoco_ioctl_setibssport,
- [7] = (iw_handler) orinoco_ioctl_getibssport,
- [9] = (iw_handler) orinoco_ioctl_getrid,
-};
-
-static const struct iw_handler_def orinoco_handler_def = {
- .num_standard = ARRAY_SIZE(orinoco_handler),
- .num_private = ARRAY_SIZE(orinoco_private_handler),
- .num_private_args = ARRAY_SIZE(orinoco_privtab),
- .standard = orinoco_handler,
- .private = orinoco_private_handler,
- .private_args = orinoco_privtab,
- .get_wireless_stats = orinoco_get_wireless_stats,
-};
-
-static void orinoco_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
- strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
- strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
- if (dev->dev.parent)
- strncpy(info->bus_info, dev_name(dev->dev.parent),
- sizeof(info->bus_info) - 1);
- else
- snprintf(info->bus_info, sizeof(info->bus_info) - 1,
- "PCMCIA %p", priv->hw.iobase);
-}
-
-static const struct ethtool_ops orinoco_ethtool_ops = {
- .get_drvinfo = orinoco_get_drvinfo,
- .get_link = ethtool_op_get_link,
-};
-
-/********************************************************************/
-/* Module initialization */
-/********************************************************************/
-
-EXPORT_SYMBOL(alloc_orinocodev);
-EXPORT_SYMBOL(free_orinocodev);
-
-EXPORT_SYMBOL(__orinoco_up);
-EXPORT_SYMBOL(__orinoco_down);
-EXPORT_SYMBOL(orinoco_reinit_firmware);
-
-EXPORT_SYMBOL(orinoco_interrupt);
-
-/* Can't be declared "const" or the whole __initdata section will
- * become const */
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
- " (David Gibson <hermes@gibson.dropbear.id.au>, "
- "Pavel Roskin <proski@gnu.org>, et al)";
-
-static int __init init_orinoco(void)
-{
- printk(KERN_DEBUG "%s\n", version);
- return 0;
-}
-
-static void __exit exit_orinoco(void)
-{
-}
-
-module_init(init_orinoco);
-module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 00750c8ba7d..8e5a72cc297 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -1,5 +1,5 @@
/* orinoco.h
- *
+ *
* Common definitions to all pieces of the various orinoco
* drivers
*/
@@ -18,9 +18,9 @@
#include "hermes.h"
/* To enable debug messages */
-//#define ORINOCO_DEBUG 3
+/*#define ORINOCO_DEBUG 3*/
-#define WIRELESS_SPY // enable iwspy support
+#define WIRELESS_SPY /* enable iwspy support */
#define MAX_SCAN_LEN 4096
@@ -59,14 +59,6 @@ struct xbss_element {
struct list_head list;
};
-struct hermes_rx_descriptor;
-
-struct orinoco_rx_data {
- struct hermes_rx_descriptor *desc;
- struct sk_buff *skb;
- struct list_head list;
-};
-
struct firmware;
struct orinoco_private {
@@ -83,7 +75,6 @@ struct orinoco_private {
/* Interrupt tasklets */
struct tasklet_struct rx_tasklet;
struct list_head rx_list;
- struct orinoco_rx_data *rx_data;
/* driver state */
int open;
@@ -130,7 +121,7 @@ struct orinoco_private {
u16 encode_alg, wep_restrict, tx_key;
struct orinoco_key keys[ORINOCO_MAX_KEYS];
int bitratemode;
- char nick[IW_ESSID_MAX_SIZE+1];
+ char nick[IW_ESSID_MAX_SIZE+1];
char desired_essid[IW_ESSID_MAX_SIZE+1];
char desired_bssid[ETH_ALEN];
int bssid_fixed;
@@ -140,7 +131,7 @@ struct orinoco_private {
u16 pm_on, pm_mcast, pm_period, pm_timeout;
u16 preamble;
#ifdef WIRELESS_SPY
- struct iw_spy_data spy_data; /* iwspy support */
+ struct iw_spy_data spy_data; /* iwspy support */
struct iw_public_data wireless_data;
#endif
@@ -168,16 +159,21 @@ struct orinoco_private {
unsigned int tkip_cm_active:1;
unsigned int key_mgmt:3;
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
/* Cached in memory firmware to use during ->resume. */
const struct firmware *cached_pri_fw;
const struct firmware *cached_fw;
+#endif
struct notifier_block pm_notifier;
};
#ifdef ORINOCO_DEBUG
extern int orinoco_debug;
-#define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0)
+#define DEBUG(n, args...) do { \
+ if (orinoco_debug > (n)) \
+ printk(KERN_DEBUG args); \
+} while (0)
#else
#define DEBUG(n, args...) do { } while (0)
#endif /* ORINOCO_DEBUG */
@@ -194,7 +190,7 @@ extern void free_orinocodev(struct net_device *dev);
extern int __orinoco_up(struct net_device *dev);
extern int __orinoco_down(struct net_device *dev);
extern int orinoco_reinit_firmware(struct net_device *dev);
-extern irqreturn_t orinoco_interrupt(int irq, void * dev_id);
+extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
/********************************************************************/
/* Locking and synchronization functions */
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 0b32215d3f5..b381aed24d7 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -6,8 +6,8 @@
* It should also be usable on various Prism II based cards such as the
* Linksys, D-Link and Farallon Skyline. It should also work on Symbol
* cards such as the 3Com AirConnect and Ericsson WLAN.
- *
- * Copyright notice & release notes in file orinoco.c
+ *
+ * Copyright notice & release notes in file main.c
*/
#define DRIVER_NAME "orinoco_cs"
@@ -30,7 +30,8 @@
/********************************************************************/
MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
+MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco,"
+ " Prism II based and similar wireless cards");
MODULE_LICENSE("Dual MPL/GPL");
/* Module parameters */
@@ -53,8 +54,8 @@ struct orinoco_pccard {
/* Used to handle hard reset */
/* yuck, we need this hack to work around the insanity of the
- * PCMCIA layer */
- unsigned long hard_reset_in_progress;
+ * PCMCIA layer */
+ unsigned long hard_reset_in_progress;
};
@@ -98,7 +99,7 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
* This creates an "instance" of the driver, allocating local data
* structures for one device. The device is registered with Card
* Services.
- *
+ *
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event. */
@@ -111,7 +112,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
orinoco_cs_hard_reset, NULL);
- if (! dev)
+ if (!dev)
return -ENOMEM;
priv = netdev_priv(dev);
card = priv->card;
@@ -124,7 +125,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = orinoco_interrupt;
- link->irq.Instance = dev;
+ link->irq.Instance = dev;
/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
@@ -162,8 +163,10 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
*/
#define CS_CHECK(fn, ret) do { \
- last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
- } while (0)
+ last_fn = (fn); \
+ if ((last_ret = (ret)) != 0) \
+ goto cs_failed; \
+} while (0)
static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
@@ -307,8 +310,8 @@ orinoco_cs_config(struct pcmcia_device *link)
* initialized and arranged in a linked list at link->dev_node. */
strcpy(card->node.dev_name, dev->name);
link->dev_node = &card->node; /* link->dev_node being non-NULL is also
- used to indicate that the
- net_device has been registered */
+ * used to indicate that the
+ * net_device has been registered */
/* Finally, report what we've done */
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
@@ -359,7 +362,7 @@ static int orinoco_cs_suspend(struct pcmcia_device *link)
/* This is probably racy, but I can't think of
a better way, short of rewriting the PCMCIA
layer to not suck :-( */
- if (! test_bit(0, &card->hard_reset_in_progress)) {
+ if (!test_bit(0, &card->hard_reset_in_progress)) {
spin_lock_irqsave(&priv->lock, flags);
err = __orinoco_down(dev);
@@ -384,7 +387,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
int err = 0;
unsigned long flags;
- if (! test_bit(0, &card->hard_reset_in_progress)) {
+ if (!test_bit(0, &card->hard_reset_in_progress)) {
err = orinoco_reinit_firmware(dev);
if (err) {
printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
@@ -397,7 +400,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
netif_device_attach(dev);
priv->hw_unavailable--;
- if (priv->open && ! priv->hw_unavailable) {
+ if (priv->open && !priv->hw_unavailable) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card\n",
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index 2fc86596302..b01726255c6 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -9,12 +9,12 @@
*
* Some of this code is borrowed from orinoco_plx.c
* Copyright (C) 2001 Daniel Barlow
- * Some of this code is borrowed from orinoco_pci.c
+ * Some of this code is borrowed from orinoco_pci.c
* Copyright (C) 2001 Jean Tourrilhes
* Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
* has been copied from it. linux-wlan-ng-0.1.10 is originally :
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
- *
+ *
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License
@@ -103,9 +103,8 @@ static int orinoco_nortel_hw_init(struct orinoco_pci_card *card)
iowrite16(0x8, card->bridge_io + 2);
for (i = 0; i < 30; i++) {
mdelay(30);
- if (ioread16(card->bridge_io) & 0x10) {
+ if (ioread16(card->bridge_io) & 0x10)
break;
- }
}
if (i == 30) {
printk(KERN_ERR PFX "brg1 timed out\n");
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index 4ebd638a073..78cafff1fb2 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -1,5 +1,5 @@
/* orinoco_pci.c
- *
+ *
* Driver for Prism 2.5/3 devices that have a direct PCI interface
* (i.e. these are not PCMCIA cards in a PCMCIA-to-PCI bridge).
* The card contains only one PCI region, which contains all the usual
@@ -237,7 +237,8 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
" (Pavel Roskin <proski@gnu.org>,"
" David Gibson <hermes@gibson.dropbear.id.au> &"
" Jean Tourrilhes <jt@hpl.hp.com>)";
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> &"
+ " David Gibson <hermes@gibson.dropbear.id.au>");
MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
MODULE_LICENSE("Dual MPL/GPL");
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h
index f4e5e06760c..c655b4a3de1 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.h
+++ b/drivers/net/wireless/orinoco/orinoco_pci.h
@@ -1,10 +1,10 @@
/* orinoco_pci.h
- *
+ *
* Common code for all Orinoco drivers for PCI devices, including
* both native PCI and PCMCIA-to-PCI bridges.
*
* Copyright (C) 2005, Pavel Roskin.
- * See orinoco.c for license.
+ * See main.c for license.
*/
#ifndef _ORINOCO_PCI_H
@@ -37,11 +37,11 @@ static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
if (err)
printk(KERN_WARNING "%s: error %d bringing interface down "
"for suspend\n", dev->name, err);
-
+
netif_device_detach(dev);
priv->hw_unavailable++;
-
+
orinoco_unlock(priv, &flags);
free_irq(pdev->irq, dev);
@@ -90,13 +90,13 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
priv->hw_unavailable--;
- if (priv->open && (! priv->hw_unavailable)) {
+ if (priv->open && (!priv->hw_unavailable)) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card on resume\n",
dev->name, err);
}
-
+
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index ef761857bb3..a2a4471c033 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -146,9 +146,8 @@ static int orinoco_plx_hw_init(struct orinoco_pci_card *card)
};
printk(KERN_DEBUG PFX "CIS: ");
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < 16; i++)
printk("%02X:", ioread8(card->attr_io + (i << 1)));
- }
printk("\n");
/* Verify whether a supported PC card is present */
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index ede24ec309c..cda0e6e4d7a 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -1,7 +1,7 @@
/* orinoco_tmd.c
*
* Driver for Prism II devices which would usually be driven by orinoco_cs,
- * but are connected to the PCI bus by a TMD7160.
+ * but are connected to the PCI bus by a TMD7160.
*
* Copyright (C) 2003 Joerg Dorchain <joerg AT dorchain.net>
* based heavily upon orinoco_plx.c Copyright (C) 2001 Daniel Barlow
@@ -27,7 +27,7 @@
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
*
- * The actual driving is done by orinoco.c, this is just resource
+ * The actual driving is done by main.c, this is just resource
* allocation stuff.
*
* This driver is modeled after the orinoco_plx driver. The main
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
new file mode 100644
index 00000000000..89d699d4dfe
--- /dev/null
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -0,0 +1,233 @@
+/* Helpers for managing scan queues
+ *
+ * See copyright notice in main.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/etherdevice.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+#include "scan.h"
+
+#define ORINOCO_MAX_BSS_COUNT 64
+
+#define PRIV_BSS ((struct bss_element *)priv->bss_xbss_data)
+#define PRIV_XBSS ((struct xbss_element *)priv->bss_xbss_data)
+
+int orinoco_bss_data_allocate(struct orinoco_private *priv)
+{
+ if (priv->bss_xbss_data)
+ return 0;
+
+ if (priv->has_ext_scan)
+ priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
+ sizeof(struct xbss_element),
+ GFP_KERNEL);
+ else
+ priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
+ sizeof(struct bss_element),
+ GFP_KERNEL);
+
+ if (!priv->bss_xbss_data) {
+ printk(KERN_WARNING "Out of memory allocating beacons");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+void orinoco_bss_data_free(struct orinoco_private *priv)
+{
+ kfree(priv->bss_xbss_data);
+ priv->bss_xbss_data = NULL;
+}
+
+void orinoco_bss_data_init(struct orinoco_private *priv)
+{
+ int i;
+
+ INIT_LIST_HEAD(&priv->bss_free_list);
+ INIT_LIST_HEAD(&priv->bss_list);
+ if (priv->has_ext_scan)
+ for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+ list_add_tail(&(PRIV_XBSS[i].list),
+ &priv->bss_free_list);
+ else
+ for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+ list_add_tail(&(PRIV_BSS[i].list),
+ &priv->bss_free_list);
+
+}
+
+void orinoco_clear_scan_results(struct orinoco_private *priv,
+ unsigned long scan_age)
+{
+ if (priv->has_ext_scan) {
+ struct xbss_element *bss;
+ struct xbss_element *tmp_bss;
+
+ /* Blow away current list of scan results */
+ list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+ if (!scan_age ||
+ time_after(jiffies, bss->last_scanned + scan_age)) {
+ list_move_tail(&bss->list,
+ &priv->bss_free_list);
+ /* Don't blow away ->list, just BSS data */
+ memset(&bss->bss, 0, sizeof(bss->bss));
+ bss->last_scanned = 0;
+ }
+ }
+ } else {
+ struct bss_element *bss;
+ struct bss_element *tmp_bss;
+
+ /* Blow away current list of scan results */
+ list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+ if (!scan_age ||
+ time_after(jiffies, bss->last_scanned + scan_age)) {
+ list_move_tail(&bss->list,
+ &priv->bss_free_list);
+ /* Don't blow away ->list, just BSS data */
+ memset(&bss->bss, 0, sizeof(bss->bss));
+ bss->last_scanned = 0;
+ }
+ }
+ }
+}
+
+void orinoco_add_ext_scan_result(struct orinoco_private *priv,
+ struct agere_ext_scan_info *atom)
+{
+ struct xbss_element *bss = NULL;
+ int found = 0;
+
+ /* Try to update an existing bss first */
+ list_for_each_entry(bss, &priv->bss_list, list) {
+ if (compare_ether_addr(bss->bss.bssid, atom->bssid))
+ continue;
+ /* ESSID lengths */
+ if (bss->bss.data[1] != atom->data[1])
+ continue;
+ if (memcmp(&bss->bss.data[2], &atom->data[2],
+ atom->data[1]))
+ continue;
+ found = 1;
+ break;
+ }
+
+ /* Grab a bss off the free list */
+ if (!found && !list_empty(&priv->bss_free_list)) {
+ bss = list_entry(priv->bss_free_list.next,
+ struct xbss_element, list);
+ list_del(priv->bss_free_list.next);
+
+ list_add_tail(&bss->list, &priv->bss_list);
+ }
+
+ if (bss) {
+ /* Always update the BSS to get latest beacon info */
+ memcpy(&bss->bss, atom, sizeof(bss->bss));
+ bss->last_scanned = jiffies;
+ }
+}
+
+int orinoco_process_scan_results(struct orinoco_private *priv,
+ unsigned char *buf,
+ int len)
+{
+ int offset; /* In the scan data */
+ union hermes_scan_info *atom;
+ int atom_len;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ atom_len = sizeof(struct agere_scan_apinfo);
+ offset = 0;
+ break;
+ case FIRMWARE_TYPE_SYMBOL:
+ /* Lack of documentation necessitates this hack.
+ * Different firmwares have 68 or 76 byte long atoms.
+ * We try modulo first. If the length divides by both,
+ * we check what would be the channel in the second
+ * frame for a 68-byte atom. 76-byte atoms have 0 there.
+ * Valid channel cannot be 0. */
+ if (len % 76)
+ atom_len = 68;
+ else if (len % 68)
+ atom_len = 76;
+ else if (len >= 1292 && buf[68] == 0)
+ atom_len = 76;
+ else
+ atom_len = 68;
+ offset = 0;
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ offset = 4;
+ if (priv->has_hostscan) {
+ atom_len = le16_to_cpup((__le16 *)buf);
+ /* Sanity check for atom_len */
+ if (atom_len < sizeof(struct prism2_scan_apinfo)) {
+ printk(KERN_ERR "%s: Invalid atom_len in scan "
+ "data: %d\n", priv->ndev->name,
+ atom_len);
+ return -EIO;
+ }
+ } else
+ atom_len = offsetof(struct prism2_scan_apinfo, atim);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ /* Check that we got an whole number of atoms */
+ if ((len - offset) % atom_len) {
+ printk(KERN_ERR "%s: Unexpected scan data length %d, "
+ "atom_len %d, offset %d\n", priv->ndev->name, len,
+ atom_len, offset);
+ return -EIO;
+ }
+
+ orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
+
+ /* Read the entries one by one */
+ for (; offset + atom_len <= len; offset += atom_len) {
+ int found = 0;
+ struct bss_element *bss = NULL;
+
+ /* Get next atom */
+ atom = (union hermes_scan_info *) (buf + offset);
+
+ /* Try to update an existing bss first */
+ list_for_each_entry(bss, &priv->bss_list, list) {
+ if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
+ continue;
+ if (le16_to_cpu(bss->bss.a.essid_len) !=
+ le16_to_cpu(atom->a.essid_len))
+ continue;
+ if (memcmp(bss->bss.a.essid, atom->a.essid,
+ le16_to_cpu(atom->a.essid_len)))
+ continue;
+ found = 1;
+ break;
+ }
+
+ /* Grab a bss off the free list */
+ if (!found && !list_empty(&priv->bss_free_list)) {
+ bss = list_entry(priv->bss_free_list.next,
+ struct bss_element, list);
+ list_del(priv->bss_free_list.next);
+
+ list_add_tail(&bss->list, &priv->bss_list);
+ }
+
+ if (bss) {
+ /* Always update the BSS to get latest beacon info */
+ memcpy(&bss->bss, atom, sizeof(bss->bss));
+ bss->last_scanned = jiffies;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h
new file mode 100644
index 00000000000..f319f7466af
--- /dev/null
+++ b/drivers/net/wireless/orinoco/scan.h
@@ -0,0 +1,29 @@
+/* Helpers for managing scan queues
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_SCAN_H_
+#define _ORINOCO_SCAN_H_
+
+/* Forward declarations */
+struct orinoco_private;
+struct agere_ext_scan_info;
+
+/* Setup and free memory for scan results */
+int orinoco_bss_data_allocate(struct orinoco_private *priv);
+void orinoco_bss_data_free(struct orinoco_private *priv);
+void orinoco_bss_data_init(struct orinoco_private *priv);
+
+/* Add scan results */
+void orinoco_add_ext_scan_result(struct orinoco_private *priv,
+ struct agere_ext_scan_info *atom);
+int orinoco_process_scan_results(struct orinoco_private *dev,
+ unsigned char *buf,
+ int len);
+
+/* Clear scan results */
+void orinoco_clear_scan_results(struct orinoco_private *priv,
+ unsigned long scan_age);
+
+
+#endif /* _ORINOCO_SCAN_H_ */
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index b2ca2e39c2c..38e5198e44c 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -4,7 +4,7 @@
* Communications and Intel PRO/Wireless 2011B.
*
* The driver implements Symbol firmware download. The rest is handled
- * in hermes.c and orinoco.c.
+ * in hermes.c and main.c.
*
* Utilities for downloading the Symbol firmware are available at
* http://sourceforge.net/projects/orinoco/
@@ -15,7 +15,7 @@
* Portions based on Spectrum24tDnld.c from original spectrum24 driver:
* Copyright (C) Symbol Technologies.
*
- * See copyright notice in file orinoco.c.
+ * See copyright notice in file main.c.
*/
#define DRIVER_NAME "spectrum_cs"
@@ -133,7 +133,7 @@ spectrum_reset(struct pcmcia_device *link, int idle)
udelay(1000);
return 0;
- cs_failed:
+cs_failed:
cs_error(link, last_fn, last_ret);
return -ENODEV;
}
@@ -171,7 +171,7 @@ spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
* This creates an "instance" of the driver, allocating local data
* structures for one device. The device is registered with Card
* Services.
- *
+ *
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event. */
@@ -185,7 +185,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
spectrum_cs_hard_reset,
spectrum_cs_stop_firmware);
- if (! dev)
+ if (!dev)
return -ENOMEM;
priv = netdev_priv(dev);
card = priv->card;
@@ -198,7 +198,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = orinoco_interrupt;
- link->irq.Instance = dev;
+ link->irq.Instance = dev;
/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
@@ -367,9 +367,8 @@ spectrum_cs_config(struct pcmcia_device *link)
card->node.major = card->node.minor = 0;
/* Reset card */
- if (spectrum_cs_hard_reset(priv) != 0) {
+ if (spectrum_cs_hard_reset(priv) != 0)
goto failed;
- }
SET_NETDEV_DEV(dev, &handle_to_dev(link));
/* Tell the stack we exist */
@@ -382,8 +381,8 @@ spectrum_cs_config(struct pcmcia_device *link)
* initialized and arranged in a linked list at link->dev_node. */
strcpy(card->node.dev_name, dev->name);
link->dev_node = &card->node; /* link->dev_node being non-NULL is also
- used to indicate that the
- net_device has been registered */
+ * used to indicate that the
+ * net_device has been registered */
/* Finally, report what we've done */
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
new file mode 100644
index 00000000000..3f081423439
--- /dev/null
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -0,0 +1,2325 @@
+/* Wireless extensions support.
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/iw_handler.h>
+
+#include "hermes.h"
+#include "hermes_rid.h"
+#include "orinoco.h"
+
+#include "hw.h"
+#include "mic.h"
+#include "scan.h"
+#include "main.h"
+
+#include "wext.h"
+
+#define MAX_RID_LEN 1024
+
+static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ struct iw_statistics *wstats = &priv->wstats;
+ int err;
+ unsigned long flags;
+
+ if (!netif_device_present(dev)) {
+ printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
+ dev->name);
+ return NULL; /* FIXME: Can we do better than this? */
+ }
+
+ /* If busy, return the old stats. Returning NULL may cause
+ * the interface to disappear from /proc/net/wireless */
+ if (orinoco_lock(priv, &flags) != 0)
+ return wstats;
+
+ /* We can't really wait for the tallies inquiry command to
+ * complete, so we just use the previous results and trigger
+ * a new tallies inquiry command for next time - Jean II */
+ /* FIXME: Really we should wait for the inquiry to come back -
+ * as it is the stats we give don't make a whole lot of sense.
+ * Unfortunately, it's not clear how to do that within the
+ * wireless extensions framework: I think we're in user
+ * context, but a lock seems to be held by the time we get in
+ * here so we're not safe to sleep here. */
+ hermes_inquire(hw, HERMES_INQ_TALLIES);
+
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ memset(&wstats->qual, 0, sizeof(wstats->qual));
+ /* If a spy address is defined, we report stats of the
+ * first spy address - Jean II */
+ if (SPY_NUMBER(priv)) {
+ wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
+ wstats->qual.level = priv->spy_data.spy_stat[0].level;
+ wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
+ wstats->qual.updated =
+ priv->spy_data.spy_stat[0].updated;
+ }
+ } else {
+ struct {
+ __le16 qual, signal, noise, unused;
+ } __attribute__ ((packed)) cq;
+
+ err = HERMES_READ_RECORD(hw, USER_BAP,
+ HERMES_RID_COMMSQUALITY, &cq);
+
+ if (!err) {
+ wstats->qual.qual = (int)le16_to_cpu(cq.qual);
+ wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
+ wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
+ wstats->qual.updated =
+ IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+ }
+ }
+
+ orinoco_unlock(priv, &flags);
+ return wstats;
+}
+
+/********************************************************************/
+/* Wireless extensions */
+/********************************************************************/
+
+static int orinoco_ioctl_getname(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int numrates;
+ int err;
+
+ err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
+
+ if (!err && (numrates > 2))
+ strcpy(name, "IEEE 802.11b");
+ else
+ strcpy(name, "IEEE 802.11-DS");
+
+ return 0;
+}
+
+static int orinoco_ioctl_setwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+ static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* Enable automatic roaming - no sanity checks are needed */
+ if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
+ memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
+ priv->bssid_fixed = 0;
+ memset(priv->desired_bssid, 0, ETH_ALEN);
+
+ /* "off" means keep existing connection */
+ if (ap_addr->sa_data[0] == 0) {
+ __orinoco_hw_set_wap(priv);
+ err = 0;
+ }
+ goto out;
+ }
+
+ if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
+ printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
+ "support manual roaming\n",
+ dev->name);
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (priv->iw_mode != IW_MODE_INFRA) {
+ printk(KERN_WARNING "%s: Manual roaming supported only in "
+ "managed mode\n", dev->name);
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /* Intersil firmware hangs without Desired ESSID */
+ if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
+ strlen(priv->desired_essid) == 0) {
+ printk(KERN_WARNING "%s: Desired ESSID must be set for "
+ "manual roaming\n", dev->name);
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /* Finally, enable manual roaming */
+ priv->bssid_fixed = 1;
+ memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
+
+ out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+static int orinoco_ioctl_getwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+ ETH_ALEN, NULL, ap_addr->sa_data);
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_setmode(struct net_device *dev,
+ struct iw_request_info *info,
+ u32 *mode,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+
+ if (priv->iw_mode == *mode)
+ return 0;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (*mode) {
+ case IW_MODE_ADHOC:
+ if (!priv->has_ibss && !priv->has_port3)
+ err = -EOPNOTSUPP;
+ break;
+
+ case IW_MODE_INFRA:
+ break;
+
+ case IW_MODE_MONITOR:
+ if (priv->broken_monitor && !force_monitor) {
+ printk(KERN_WARNING "%s: Monitor mode support is "
+ "buggy in this firmware, not enabling\n",
+ dev->name);
+ err = -EOPNOTSUPP;
+ }
+ break;
+
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ if (err == -EINPROGRESS) {
+ priv->iw_mode = *mode;
+ set_port_type(priv);
+ }
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getmode(struct net_device *dev,
+ struct iw_request_info *info,
+ u32 *mode,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ *mode = priv->iw_mode;
+ return 0;
+}
+
+static int orinoco_ioctl_getiwrange(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+ struct iw_range *range = (struct iw_range *) extra;
+ int numrates;
+ int i, k;
+
+ rrq->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 22;
+
+ /* Set available channels/frequencies */
+ range->num_channels = NUM_CHANNELS;
+ k = 0;
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ if (priv->channel_mask & (1 << i)) {
+ range->freq[k].i = i + 1;
+ range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) *
+ 100000);
+ range->freq[k].e = 1;
+ k++;
+ }
+
+ if (k >= IW_MAX_FREQUENCIES)
+ break;
+ }
+ range->num_frequency = k;
+ range->sensitivity = 3;
+
+ if (priv->has_wep) {
+ range->max_encoding_tokens = ORINOCO_MAX_KEYS;
+ range->encoding_size[0] = SMALL_KEY_SIZE;
+ range->num_encoding_sizes = 1;
+
+ if (priv->has_big_wep) {
+ range->encoding_size[1] = LARGE_KEY_SIZE;
+ range->num_encoding_sizes = 2;
+ }
+ }
+
+ if (priv->has_wpa)
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
+
+ if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))) {
+ /* Quality stats meaningless in ad-hoc mode */
+ } else {
+ range->max_qual.qual = 0x8b - 0x2f;
+ range->max_qual.level = 0x2f - 0x95 - 1;
+ range->max_qual.noise = 0x2f - 0x95 - 1;
+ /* Need to get better values */
+ range->avg_qual.qual = 0x24;
+ range->avg_qual.level = 0xC2;
+ range->avg_qual.noise = 0x9E;
+ }
+
+ err = orinoco_hw_get_bitratelist(priv, &numrates,
+ range->bitrate, IW_MAX_BITRATES);
+ if (err)
+ return err;
+ range->num_bitrates = numrates;
+
+ /* Set an indication of the max TCP throughput in bit/s that we can
+ * expect using this interface. May be use for QoS stuff...
+ * Jean II */
+ if (numrates > 2)
+ range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
+ else
+ range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
+
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+
+ range->min_pmp = 0;
+ range->max_pmp = 65535000;
+ range->min_pmt = 0;
+ range->max_pmt = 65535 * 1000; /* ??? */
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_TIMEOUT;
+ range->pm_capa = (IW_POWER_PERIOD | IW_POWER_TIMEOUT |
+ IW_POWER_UNICAST_R);
+
+ range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->r_time_flags = IW_RETRY_LIFETIME;
+ range->min_retry = 0;
+ range->max_retry = 65535; /* ??? */
+ range->min_r_time = 0;
+ range->max_r_time = 65535 * 1000; /* ??? */
+
+ if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+ range->scan_capa = IW_SCAN_CAPA_ESSID;
+ else
+ range->scan_capa = IW_SCAN_CAPA_NONE;
+
+ /* Event capability (kernel) */
+ IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+ /* Event capability (driver) */
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+
+ return 0;
+}
+
+static int orinoco_ioctl_setiwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq,
+ char *keybuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+ int setindex = priv->tx_key;
+ int encode_alg = priv->encode_alg;
+ int restricted = priv->wep_restrict;
+ u16 xlen = 0;
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+
+ if (!priv->has_wep)
+ return -EOPNOTSUPP;
+
+ if (erq->pointer) {
+ /* We actually have a key to set - check its length */
+ if (erq->length > LARGE_KEY_SIZE)
+ return -E2BIG;
+
+ if ((erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep)
+ return -E2BIG;
+ }
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* Clear any TKIP key we have */
+ if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
+ (void) orinoco_clear_tkip_key(priv, setindex);
+
+ if (erq->length > 0) {
+ if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
+ index = priv->tx_key;
+
+ /* Adjust key length to a supported value */
+ if (erq->length > SMALL_KEY_SIZE)
+ xlen = LARGE_KEY_SIZE;
+ else if (erq->length > 0)
+ xlen = SMALL_KEY_SIZE;
+ else
+ xlen = 0;
+
+ /* Switch on WEP if off */
+ if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
+ setindex = index;
+ encode_alg = IW_ENCODE_ALG_WEP;
+ }
+ } else {
+ /* Important note : if the user do "iwconfig eth0 enc off",
+ * we will arrive there with an index of -1. This is valid
+ * but need to be taken care off... Jean II */
+ if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
+ if ((index != -1) || (erq->flags == 0)) {
+ err = -EINVAL;
+ goto out;
+ }
+ } else {
+ /* Set the index : Check that the key is valid */
+ if (priv->keys[index].len == 0) {
+ err = -EINVAL;
+ goto out;
+ }
+ setindex = index;
+ }
+ }
+
+ if (erq->flags & IW_ENCODE_DISABLED)
+ encode_alg = IW_ENCODE_ALG_NONE;
+ if (erq->flags & IW_ENCODE_OPEN)
+ restricted = 0;
+ if (erq->flags & IW_ENCODE_RESTRICTED)
+ restricted = 1;
+
+ if (erq->pointer && erq->length > 0) {
+ priv->keys[index].len = cpu_to_le16(xlen);
+ memset(priv->keys[index].data, 0,
+ sizeof(priv->keys[index].data));
+ memcpy(priv->keys[index].data, keybuf, erq->length);
+ }
+ priv->tx_key = setindex;
+
+ /* Try fast key change if connected and only keys are changed */
+ if ((priv->encode_alg == encode_alg) &&
+ (priv->wep_restrict == restricted) &&
+ netif_carrier_ok(dev)) {
+ err = __orinoco_hw_setup_wepkeys(priv);
+ /* No need to commit if successful */
+ goto out;
+ }
+
+ priv->encode_alg = encode_alg;
+ priv->wep_restrict = restricted;
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getiwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq,
+ char *keybuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+ u16 xlen = 0;
+ unsigned long flags;
+
+ if (!priv->has_wep)
+ return -EOPNOTSUPP;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
+ index = priv->tx_key;
+
+ erq->flags = 0;
+ if (!priv->encode_alg)
+ erq->flags |= IW_ENCODE_DISABLED;
+ erq->flags |= index + 1;
+
+ if (priv->wep_restrict)
+ erq->flags |= IW_ENCODE_RESTRICTED;
+ else
+ erq->flags |= IW_ENCODE_OPEN;
+
+ xlen = le16_to_cpu(priv->keys[index].len);
+
+ erq->length = xlen;
+
+ memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
+
+ orinoco_unlock(priv, &flags);
+ return 0;
+}
+
+static int orinoco_ioctl_setessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq,
+ char *essidbuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
+ * anyway... - Jean II */
+
+ /* Hum... Should not use Wireless Extension constant (may change),
+ * should use our own... - Jean II */
+ if (erq->length > IW_ESSID_MAX_SIZE)
+ return -E2BIG;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
+ memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
+
+ /* If not ANY, get the new ESSID */
+ if (erq->flags)
+ memcpy(priv->desired_essid, essidbuf, erq->length);
+
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq,
+ char *essidbuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int active;
+ int err = 0;
+ unsigned long flags;
+
+ if (netif_running(dev)) {
+ err = orinoco_hw_get_essid(priv, &active, essidbuf);
+ if (err < 0)
+ return err;
+ erq->length = err;
+ } else {
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+ memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
+ erq->length = strlen(priv->desired_essid);
+ orinoco_unlock(priv, &flags);
+ }
+
+ erq->flags = 1;
+
+ return 0;
+}
+
+static int orinoco_ioctl_setnick(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *nrq,
+ char *nickbuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ if (nrq->length > IW_ESSID_MAX_SIZE)
+ return -E2BIG;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ memset(priv->nick, 0, sizeof(priv->nick));
+ memcpy(priv->nick, nickbuf, nrq->length);
+
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getnick(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *nrq,
+ char *nickbuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
+ orinoco_unlock(priv, &flags);
+
+ nrq->length = strlen(priv->nick);
+
+ return 0;
+}
+
+static int orinoco_ioctl_setfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *frq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int chan = -1;
+ unsigned long flags;
+ int err = -EINPROGRESS; /* Call commit handler */
+
+ /* In infrastructure mode the AP sets the channel */
+ if (priv->iw_mode == IW_MODE_INFRA)
+ return -EBUSY;
+
+ if ((frq->e == 0) && (frq->m <= 1000)) {
+ /* Setting by channel number */
+ chan = frq->m;
+ } else {
+ /* Setting by frequency */
+ int denom = 1;
+ int i;
+
+ /* Calculate denominator to rescale to MHz */
+ for (i = 0; i < (6 - frq->e); i++)
+ denom *= 10;
+
+ chan = ieee80211_freq_to_dsss_chan(frq->m / denom);
+ }
+
+ if ((chan < 1) || (chan > NUM_CHANNELS) ||
+ !(priv->channel_mask & (1 << (chan-1))))
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ priv->channel = chan;
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ /* Fast channel change - no commit if successful */
+ hermes_t *hw = &priv->hw;
+ err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+ HERMES_TEST_SET_CHANNEL,
+ chan, NULL);
+ }
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *frq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int tmp;
+
+ /* Locking done in there */
+ tmp = orinoco_hw_get_freq(priv);
+ if (tmp < 0)
+ return tmp;
+
+ frq->m = tmp * 100000;
+ frq->e = 1;
+
+ return 0;
+}
+
+static int orinoco_ioctl_getsens(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *srq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ u16 val;
+ int err;
+ unsigned long flags;
+
+ if (!priv->has_sensitivity)
+ return -EOPNOTSUPP;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSYSTEMSCALE, &val);
+ orinoco_unlock(priv, &flags);
+
+ if (err)
+ return err;
+
+ srq->value = val;
+ srq->fixed = 0; /* auto */
+
+ return 0;
+}
+
+static int orinoco_ioctl_setsens(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *srq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int val = srq->value;
+ unsigned long flags;
+
+ if (!priv->has_sensitivity)
+ return -EOPNOTSUPP;
+
+ if ((val < 1) || (val > 3))
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+ priv->ap_density = val;
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_setrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int val = rrq->value;
+ unsigned long flags;
+
+ if (rrq->disabled)
+ val = 2347;
+
+ if ((val < 0) || (val > 2347))
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ priv->rts_thresh = val;
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ rrq->value = priv->rts_thresh;
+ rrq->disabled = (rrq->value == 2347);
+ rrq->fixed = 1;
+
+ return 0;
+}
+
+static int orinoco_ioctl_setfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (priv->has_mwo) {
+ if (frq->disabled)
+ priv->mwo_robust = 0;
+ else {
+ if (frq->fixed)
+ printk(KERN_WARNING "%s: Fixed fragmentation "
+ "is not supported on this firmware. "
+ "Using MWO robust instead.\n",
+ dev->name);
+ priv->mwo_robust = 1;
+ }
+ } else {
+ if (frq->disabled)
+ priv->frag_thresh = 2346;
+ else {
+ if ((frq->value < 256) || (frq->value > 2346))
+ err = -EINVAL;
+ else
+ /* must be even */
+ priv->frag_thresh = frq->value & ~0x1;
+ }
+ }
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err;
+ u16 val;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (priv->has_mwo) {
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMWOROBUST_AGERE,
+ &val);
+ if (err)
+ val = 0;
+
+ frq->value = val ? 2347 : 0;
+ frq->disabled = !val;
+ frq->fixed = 0;
+ } else {
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+ &val);
+ if (err)
+ val = 0;
+
+ frq->value = val;
+ frq->disabled = (val >= 2346);
+ frq->fixed = 1;
+ }
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_setrate(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int ratemode;
+ int bitrate; /* 100s of kilobits */
+ unsigned long flags;
+
+ /* As the user space doesn't know our highest rate, it uses -1
+ * to ask us to set the highest rate. Test it using "iwconfig
+ * ethX rate auto" - Jean II */
+ if (rrq->value == -1)
+ bitrate = 110;
+ else {
+ if (rrq->value % 100000)
+ return -EINVAL;
+ bitrate = rrq->value / 100000;
+ }
+
+ ratemode = orinoco_get_bitratemode(bitrate, !rrq->fixed);
+
+ if (ratemode == -1)
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+ priv->bitratemode = ratemode;
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS;
+}
+
+static int orinoco_ioctl_getrate(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+ int bitrate, automatic;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ orinoco_get_ratemode_cfg(priv->bitratemode, &bitrate, &automatic);
+
+ /* If the interface is running we try to find more about the
+ current mode */
+ if (netif_running(dev))
+ err = orinoco_hw_get_act_bitrate(priv, &bitrate);
+
+ orinoco_unlock(priv, &flags);
+
+ rrq->value = bitrate;
+ rrq->fixed = !automatic;
+ rrq->disabled = 0;
+
+ return err;
+}
+
+static int orinoco_ioctl_setpower(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *prq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (prq->disabled) {
+ priv->pm_on = 0;
+ } else {
+ switch (prq->flags & IW_POWER_MODE) {
+ case IW_POWER_UNICAST_R:
+ priv->pm_mcast = 0;
+ priv->pm_on = 1;
+ break;
+ case IW_POWER_ALL_R:
+ priv->pm_mcast = 1;
+ priv->pm_on = 1;
+ break;
+ case IW_POWER_ON:
+ /* No flags : but we may have a value - Jean II */
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (prq->flags & IW_POWER_TIMEOUT) {
+ priv->pm_on = 1;
+ priv->pm_timeout = prq->value / 1000;
+ }
+ if (prq->flags & IW_POWER_PERIOD) {
+ priv->pm_on = 1;
+ priv->pm_period = prq->value / 1000;
+ }
+ /* It's valid to not have a value if we are just toggling
+ * the flags... Jean II */
+ if (!priv->pm_on) {
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getpower(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *prq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u16 enable, period, timeout, mcast;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMENABLED, &enable);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMAXSLEEPDURATION, &period);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
+ if (err)
+ goto out;
+
+ prq->disabled = !enable;
+ /* Note : by default, display the period */
+ if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+ prq->flags = IW_POWER_TIMEOUT;
+ prq->value = timeout * 1000;
+ } else {
+ prq->flags = IW_POWER_PERIOD;
+ prq->value = period * 1000;
+ }
+ if (mcast)
+ prq->flags |= IW_POWER_ALL_R;
+ else
+ prq->flags |= IW_POWER_UNICAST_R;
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_set_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int idx, alg = ext->alg, set_key = 1;
+ unsigned long flags;
+ int err = -EINVAL;
+ u16 key_len;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* Determine and validate the key index */
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx) {
+ if ((idx < 1) || (idx > 4))
+ goto out;
+ idx--;
+ } else
+ idx = priv->tx_key;
+
+ if (encoding->flags & IW_ENCODE_DISABLED)
+ alg = IW_ENCODE_ALG_NONE;
+
+ if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
+ /* Clear any TKIP TX key we had */
+ (void) orinoco_clear_tkip_key(priv, priv->tx_key);
+ }
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ priv->tx_key = idx;
+ set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
+ (ext->key_len > 0)) ? 1 : 0;
+ }
+
+ if (set_key) {
+ /* Set the requested key first */
+ switch (alg) {
+ case IW_ENCODE_ALG_NONE:
+ priv->encode_alg = alg;
+ priv->keys[idx].len = 0;
+ break;
+
+ case IW_ENCODE_ALG_WEP:
+ if (ext->key_len > SMALL_KEY_SIZE)
+ key_len = LARGE_KEY_SIZE;
+ else if (ext->key_len > 0)
+ key_len = SMALL_KEY_SIZE;
+ else
+ goto out;
+
+ priv->encode_alg = alg;
+ priv->keys[idx].len = cpu_to_le16(key_len);
+
+ key_len = min(ext->key_len, key_len);
+
+ memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
+ memcpy(priv->keys[idx].data, ext->key, key_len);
+ break;
+
+ case IW_ENCODE_ALG_TKIP:
+ {
+ hermes_t *hw = &priv->hw;
+ u8 *tkip_iv = NULL;
+
+ if (!priv->has_wpa ||
+ (ext->key_len > sizeof(priv->tkip_key[0])))
+ goto out;
+
+ priv->encode_alg = alg;
+ memset(&priv->tkip_key[idx], 0,
+ sizeof(priv->tkip_key[idx]));
+ memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
+
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+ tkip_iv = &ext->rx_seq[0];
+
+ err = __orinoco_hw_set_tkip_key(hw, idx,
+ ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
+ (u8 *) &priv->tkip_key[idx],
+ tkip_iv, NULL);
+ if (err)
+ printk(KERN_ERR "%s: Error %d setting TKIP key"
+ "\n", dev->name, err);
+
+ goto out;
+ }
+ default:
+ goto out;
+ }
+ }
+ err = -EINPROGRESS;
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_get_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int idx, max_key_len;
+ unsigned long flags;
+ int err;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = -EINVAL;
+ max_key_len = encoding->length - sizeof(*ext);
+ if (max_key_len < 0)
+ goto out;
+
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx) {
+ if ((idx < 1) || (idx > 4))
+ goto out;
+ idx--;
+ } else
+ idx = priv->tx_key;
+
+ encoding->flags = idx + 1;
+ memset(ext, 0, sizeof(*ext));
+
+ ext->alg = priv->encode_alg;
+ switch (priv->encode_alg) {
+ case IW_ENCODE_ALG_NONE:
+ ext->key_len = 0;
+ encoding->flags |= IW_ENCODE_DISABLED;
+ break;
+ case IW_ENCODE_ALG_WEP:
+ ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
+ max_key_len);
+ memcpy(ext->key, priv->keys[idx].data, ext->key_len);
+ encoding->flags |= IW_ENCODE_ENABLED;
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
+ max_key_len);
+ memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
+ encoding->flags |= IW_ENCODE_ENABLED;
+ break;
+ }
+
+ err = 0;
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_set_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ struct iw_param *param = &wrqu->param;
+ unsigned long flags;
+ int ret = -EINPROGRESS;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ case IW_AUTH_PRIVACY_INVOKED:
+ case IW_AUTH_DROP_UNENCRYPTED:
+ /*
+ * orinoco does not use these parameters
+ */
+ break;
+
+ case IW_AUTH_KEY_MGMT:
+ /* wl_lkm implies value 2 == PSK for Hermes I
+ * which ties in with WEXT
+ * no other hints tho :(
+ */
+ priv->key_mgmt = param->value;
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ /* When countermeasures are enabled, shut down the
+ * card; when disabled, re-enable the card. This must
+ * take effect immediately.
+ *
+ * TODO: Make sure that the EAPOL message is getting
+ * out before card disabled
+ */
+ if (param->value) {
+ priv->tkip_cm_active = 1;
+ ret = hermes_enable_port(hw, 0);
+ } else {
+ priv->tkip_cm_active = 0;
+ ret = hermes_disable_port(hw, 0);
+ }
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ if (param->value & IW_AUTH_ALG_SHARED_KEY)
+ priv->wep_restrict = 1;
+ else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
+ priv->wep_restrict = 0;
+ else
+ ret = -EINVAL;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ if (priv->has_wpa) {
+ priv->wpa_enabled = param->value ? 1 : 0;
+ } else {
+ if (param->value)
+ ret = -EOPNOTSUPP;
+ /* else silently accept disable of WPA */
+ priv->wpa_enabled = 0;
+ }
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ orinoco_unlock(priv, &flags);
+ return ret;
+}
+
+static int orinoco_ioctl_get_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct iw_param *param = &wrqu->param;
+ unsigned long flags;
+ int ret = 0;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_KEY_MGMT:
+ param->value = priv->key_mgmt;
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ param->value = priv->tkip_cm_active;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ if (priv->wep_restrict)
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ else
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ param->value = priv->wpa_enabled;
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ orinoco_unlock(priv, &flags);
+ return ret;
+}
+
+static int orinoco_ioctl_set_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ u8 *buf;
+ unsigned long flags;
+
+ /* cut off at IEEE80211_MAX_DATA_LEN */
+ if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
+ (wrqu->data.length && (extra == NULL)))
+ return -EINVAL;
+
+ if (wrqu->data.length) {
+ buf = kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ memcpy(buf, extra, wrqu->data.length);
+ } else
+ buf = NULL;
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ kfree(buf);
+ return -EBUSY;
+ }
+
+ kfree(priv->wpa_ie);
+ priv->wpa_ie = buf;
+ priv->wpa_ie_len = wrqu->data.length;
+
+ if (priv->wpa_ie) {
+ /* Looks like wl_lkm wants to check the auth alg, and
+ * somehow pass it to the firmware.
+ * Instead it just calls the key mgmt rid
+ * - we do this in set auth.
+ */
+ }
+
+ orinoco_unlock(priv, &flags);
+ return 0;
+}
+
+static int orinoco_ioctl_get_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err = 0;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
+ wrqu->data.length = 0;
+ goto out;
+ }
+
+ if (wrqu->data.length < priv->wpa_ie_len) {
+ err = -E2BIG;
+ goto out;
+ }
+
+ wrqu->data.length = priv->wpa_ie_len;
+ memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
+
+out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+static int orinoco_ioctl_set_mlme(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ unsigned long flags;
+ int ret = 0;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ /* silently ignore */
+ break;
+
+ case IW_MLME_DISASSOC:
+ {
+ struct {
+ u8 addr[ETH_ALEN];
+ __le16 reason_code;
+ } __attribute__ ((packed)) buf;
+
+ memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
+ buf.reason_code = cpu_to_le16(mlme->reason_code);
+ ret = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFDISASSOCIATE,
+ &buf);
+ break;
+ }
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ orinoco_unlock(priv, &flags);
+ return ret;
+}
+
+static int orinoco_ioctl_getretry(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u16 short_limit, long_limit, lifetime;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
+ &short_limit);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
+ &long_limit);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
+ &lifetime);
+ if (err)
+ goto out;
+
+ rrq->disabled = 0; /* Can't be disabled */
+
+ /* Note : by default, display the retry number */
+ if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+ rrq->flags = IW_RETRY_LIFETIME;
+ rrq->value = lifetime * 1000; /* ??? */
+ } else {
+ /* By default, display the min number */
+ if ((rrq->flags & IW_RETRY_LONG)) {
+ rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
+ rrq->value = long_limit;
+ } else {
+ rrq->flags = IW_RETRY_LIMIT;
+ rrq->value = short_limit;
+ if (short_limit != long_limit)
+ rrq->flags |= IW_RETRY_SHORT;
+ }
+ }
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_reset(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
+ printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
+
+ /* Firmware reset */
+ orinoco_reset(&priv->reset_work);
+ } else {
+ printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
+
+ schedule_work(&priv->reset_work);
+ }
+
+ return 0;
+}
+
+static int orinoco_ioctl_setibssport(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int val = *((int *) extra);
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ priv->ibss_port = val ;
+
+ /* Actually update the mode we are using */
+ set_port_type(priv);
+
+ orinoco_unlock(priv, &flags);
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getibssport(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int *val = (int *) extra;
+
+ *val = priv->ibss_port;
+ return 0;
+}
+
+static int orinoco_ioctl_setport3(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int val = *((int *) extra);
+ int err = 0;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (val) {
+ case 0: /* Try to do IEEE ad-hoc mode */
+ if (!priv->has_ibss) {
+ err = -EINVAL;
+ break;
+ }
+ priv->prefer_port3 = 0;
+
+ break;
+
+ case 1: /* Try to do Lucent proprietary ad-hoc mode */
+ if (!priv->has_port3) {
+ err = -EINVAL;
+ break;
+ }
+ priv->prefer_port3 = 1;
+ break;
+
+ default:
+ err = -EINVAL;
+ }
+
+ if (!err) {
+ /* Actually update the mode we are using */
+ set_port_type(priv);
+ err = -EINPROGRESS;
+ }
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getport3(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int *val = (int *) extra;
+
+ *val = priv->prefer_port3;
+ return 0;
+}
+
+static int orinoco_ioctl_setpreamble(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int val;
+
+ if (!priv->has_preamble)
+ return -EOPNOTSUPP;
+
+ /* 802.11b has recently defined some short preamble.
+ * Basically, the Phy header has been reduced in size.
+ * This increase performance, especially at high rates
+ * (the preamble is transmitted at 1Mb/s), unfortunately
+ * this give compatibility troubles... - Jean II */
+ val = *((int *) extra);
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (val)
+ priv->preamble = 1;
+ else
+ priv->preamble = 0;
+
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getpreamble(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int *val = (int *) extra;
+
+ if (!priv->has_preamble)
+ return -EOPNOTSUPP;
+
+ *val = priv->preamble;
+ return 0;
+}
+
+/* ioctl interface to hermes_read_ltv()
+ * To use with iwpriv, pass the RID as the token argument, e.g.
+ * iwpriv get_rid [0xfc00]
+ * At least Wireless Tools 25 is required to use iwpriv.
+ * For Wireless Tools 25 and 26 append "dummy" are the end. */
+static int orinoco_ioctl_getrid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int rid = data->flags;
+ u16 length;
+ int err;
+ unsigned long flags;
+
+ /* It's a "get" function, but we don't want users to access the
+ * WEP key and other raw firmware data */
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (rid < 0xfc00 || rid > 0xffff)
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
+ extra);
+ if (err)
+ goto out;
+
+ data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
+ MAX_RID_LEN);
+
+ out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+/* Trigger a scan (look for other cells in the vicinity) */
+static int orinoco_ioctl_setscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *srq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ struct iw_scan_req *si = (struct iw_scan_req *) extra;
+ int err = 0;
+ unsigned long flags;
+
+ /* Note : you may have realised that, as this is a SET operation,
+ * this is privileged and therefore a normal user can't
+ * perform scanning.
+ * This is not an error, while the device perform scanning,
+ * traffic doesn't flow, so it's a perfect DoS...
+ * Jean II */
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* Scanning with port 0 disabled would fail */
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ /* In monitor mode, the scan results are always empty.
+ * Probe responses are passed to the driver as received
+ * frames and could be processed in software. */
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /* Note : because we don't lock out the irq handler, the way
+ * we access scan variables in priv is critical.
+ * o scan_inprogress : not touched by irq handler
+ * o scan_mode : not touched by irq handler
+ * Before modifying anything on those variables, please think hard !
+ * Jean II */
+
+ /* Save flags */
+ priv->scan_mode = srq->flags;
+
+ /* Always trigger scanning, even if it's in progress.
+ * This way, if the info frame get lost, we will recover somewhat
+ * gracefully - Jean II */
+
+ if (priv->has_hostscan) {
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_SYMBOL:
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFHOSTSCAN_SYMBOL,
+ HERMES_HOSTSCAN_SYMBOL_ONCE |
+ HERMES_HOSTSCAN_SYMBOL_BCAST);
+ break;
+ case FIRMWARE_TYPE_INTERSIL: {
+ __le16 req[3];
+
+ req[0] = cpu_to_le16(0x3fff); /* All channels */
+ req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
+ req[2] = 0; /* Any ESSID */
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFHOSTSCAN, &req);
+ }
+ break;
+ case FIRMWARE_TYPE_AGERE:
+ if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
+ struct hermes_idstring idbuf;
+ size_t len = min(sizeof(idbuf.val),
+ (size_t) si->essid_len);
+ idbuf.len = cpu_to_le16(len);
+ memcpy(idbuf.val, si->essid, len);
+
+ err = hermes_write_ltv(hw, USER_BAP,
+ HERMES_RID_CNFSCANSSID_AGERE,
+ HERMES_BYTES_TO_RECLEN(len + 2),
+ &idbuf);
+ } else
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSCANSSID_AGERE,
+ 0); /* Any ESSID */
+ if (err)
+ break;
+
+ if (priv->has_ext_scan) {
+ /* Clear scan results at the start of
+ * an extended scan */
+ orinoco_clear_scan_results(priv,
+ msecs_to_jiffies(15000));
+
+ /* TODO: Is this available on older firmware?
+ * Can we use it to scan specific channels
+ * for IW_SCAN_THIS_FREQ? */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSCANCHANNELS2GHZ,
+ 0x7FFF);
+ if (err)
+ goto out;
+
+ err = hermes_inquire(hw,
+ HERMES_INQ_CHANNELINFO);
+ } else
+ err = hermes_inquire(hw, HERMES_INQ_SCAN);
+ break;
+ }
+ } else
+ err = hermes_inquire(hw, HERMES_INQ_SCAN);
+
+ /* One more client */
+ if (!err)
+ priv->scan_inprogress = 1;
+
+ out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+#define MAX_CUSTOM_LEN 64
+
+/* Translate scan data returned from the card to a card independant
+ * format that the Wireless Tools will understand - Jean II */
+static inline char *orinoco_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ char *current_ev,
+ char *end_buf,
+ union hermes_scan_info *bss,
+ unsigned long last_scanned)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ u16 capabilities;
+ u16 channel;
+ struct iw_event iwe; /* Temporary buffer */
+ char custom[MAX_CUSTOM_LEN];
+
+ memset(&iwe, 0, sizeof(iwe));
+
+ /* First entry *MUST* be the AP MAC address */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
+
+ /* Other entries will be displayed in the order we give them */
+
+ /* Add the ESSID */
+ iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
+ if (iwe.u.data.length > 32)
+ iwe.u.data.length = 32;
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->a.essid);
+
+ /* Add mode */
+ iwe.cmd = SIOCGIWMODE;
+ capabilities = le16_to_cpu(bss->a.capabilities);
+ if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+ if (capabilities & WLAN_CAPABILITY_ESS)
+ iwe.u.mode = IW_MODE_MASTER;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
+ }
+
+ channel = bss->s.channel;
+ if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+ /* Add channel and frequency */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = channel;
+ iwe.u.freq.e = 0;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+
+ iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
+ iwe.u.freq.e = 1;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+ }
+
+ /* Add quality statistics. level and noise in dB. No link quality */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
+ iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
+ iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
+ /* Wireless tools prior to 27.pre22 will show link quality
+ * anyway, so we provide a reasonable value. */
+ if (iwe.u.qual.level > iwe.u.qual.noise)
+ iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+ else
+ iwe.u.qual.qual = 0;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
+
+ /* Add encryption capability */
+ iwe.cmd = SIOCGIWENCODE;
+ if (capabilities & WLAN_CAPABILITY_PRIVACY)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ iwe.u.data.length = 0;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
+
+ /* Bit rate is not available in Lucent/Agere firmwares */
+ if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
+ char *current_val = current_ev + iwe_stream_lcp_len(info);
+ int i;
+ int step;
+
+ if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+ step = 2;
+ else
+ step = 1;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+ /* Max 10 values */
+ for (i = 0; i < 10; i += step) {
+ /* NULL terminated */
+ if (bss->p.rates[i] == 0x0)
+ break;
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value =
+ ((bss->p.rates[i] & 0x7f) * 500000);
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val,
+ end_buf, &iwe,
+ IW_EV_PARAM_LEN);
+ }
+ /* Check if we added any event */
+ if ((current_val - current_ev) > iwe_stream_lcp_len(info))
+ current_ev = current_val;
+ }
+
+ /* Beacon interval */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ "bcn_int=%d",
+ le16_to_cpu(bss->a.beacon_interv));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Capabilites */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ "capab=0x%04x",
+ capabilities);
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Add EXTRA: Age to display seconds since last beacon/probe response
+ * for given network. */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ " Last beacon: %dms ago",
+ jiffies_to_msecs(jiffies - last_scanned));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ return current_ev;
+}
+
+static inline char *orinoco_translate_ext_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ char *current_ev,
+ char *end_buf,
+ struct agere_ext_scan_info *bss,
+ unsigned long last_scanned)
+{
+ u16 capabilities;
+ u16 channel;
+ struct iw_event iwe; /* Temporary buffer */
+ char custom[MAX_CUSTOM_LEN];
+ u8 *ie;
+
+ memset(&iwe, 0, sizeof(iwe));
+
+ /* First entry *MUST* be the AP MAC address */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
+
+ /* Other entries will be displayed in the order we give them */
+
+ /* Add the ESSID */
+ ie = bss->data;
+ iwe.u.data.length = ie[1];
+ if (iwe.u.data.length) {
+ if (iwe.u.data.length > 32)
+ iwe.u.data.length = 32;
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, &ie[2]);
+ }
+
+ /* Add mode */
+ capabilities = le16_to_cpu(bss->capabilities);
+ if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+ iwe.cmd = SIOCGIWMODE;
+ if (capabilities & WLAN_CAPABILITY_ESS)
+ iwe.u.mode = IW_MODE_MASTER;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
+ }
+
+ ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
+ channel = ie ? ie[2] : 0;
+ if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+ /* Add channel and frequency */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = channel;
+ iwe.u.freq.e = 0;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+
+ iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
+ iwe.u.freq.e = 1;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+ }
+
+ /* Add quality statistics. level and noise in dB. No link quality */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
+ iwe.u.qual.level = bss->level - 0x95;
+ iwe.u.qual.noise = bss->noise - 0x95;
+ /* Wireless tools prior to 27.pre22 will show link quality
+ * anyway, so we provide a reasonable value. */
+ if (iwe.u.qual.level > iwe.u.qual.noise)
+ iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+ else
+ iwe.u.qual.qual = 0;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
+
+ /* Add encryption capability */
+ iwe.cmd = SIOCGIWENCODE;
+ if (capabilities & WLAN_CAPABILITY_PRIVACY)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ iwe.u.data.length = 0;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
+
+ /* WPA IE */
+ ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
+ if (ie) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie[1] + 2;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, ie);
+ }
+
+ /* RSN IE */
+ ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
+ if (ie) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie[1] + 2;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, ie);
+ }
+
+ ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
+ if (ie) {
+ char *p = current_ev + iwe_stream_lcp_len(info);
+ int i;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+ for (i = 2; i < (ie[1] + 2); i++) {
+ iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
+ p = iwe_stream_add_value(info, current_ev, p, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
+ }
+ /* Check if we added any event */
+ if (p > (current_ev + iwe_stream_lcp_len(info)))
+ current_ev = p;
+ }
+
+ /* Timestamp */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length =
+ snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
+ (unsigned long long) le64_to_cpu(bss->timestamp));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Beacon interval */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ "bcn_int=%d",
+ le16_to_cpu(bss->beacon_interval));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Capabilites */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ "capab=0x%04x",
+ capabilities);
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Add EXTRA: Age to display seconds since last beacon/probe response
+ * for given network. */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ " Last beacon: %dms ago",
+ jiffies_to_msecs(jiffies - last_scanned));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ return current_ev;
+}
+
+/* Return results of a scan */
+static int orinoco_ioctl_getscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *srq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+ unsigned long flags;
+ char *current_ev = extra;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (priv->scan_inprogress) {
+ /* Important note : we don't want to block the caller
+ * until results are ready for various reasons.
+ * First, managing wait queues is complex and racy.
+ * Second, we grab some rtnetlink lock before comming
+ * here (in dev_ioctl()).
+ * Third, we generate an Wireless Event, so the
+ * caller can wait itself on that - Jean II */
+ err = -EAGAIN;
+ goto out;
+ }
+
+ if (priv->has_ext_scan) {
+ struct xbss_element *bss;
+
+ list_for_each_entry(bss, &priv->bss_list, list) {
+ /* Translate this entry to WE format */
+ current_ev =
+ orinoco_translate_ext_scan(dev, info,
+ current_ev,
+ extra + srq->length,
+ &bss->bss,
+ bss->last_scanned);
+
+ /* Check if there is space for one more entry */
+ if ((extra + srq->length - current_ev)
+ <= IW_EV_ADDR_LEN) {
+ /* Ask user space to try again with a
+ * bigger buffer */
+ err = -E2BIG;
+ goto out;
+ }
+ }
+
+ } else {
+ struct bss_element *bss;
+
+ list_for_each_entry(bss, &priv->bss_list, list) {
+ /* Translate this entry to WE format */
+ current_ev = orinoco_translate_scan(dev, info,
+ current_ev,
+ extra + srq->length,
+ &bss->bss,
+ bss->last_scanned);
+
+ /* Check if there is space for one more entry */
+ if ((extra + srq->length - current_ev)
+ <= IW_EV_ADDR_LEN) {
+ /* Ask user space to try again with a
+ * bigger buffer */
+ err = -E2BIG;
+ goto out;
+ }
+ }
+ }
+
+ srq->length = (current_ev - extra);
+ srq->flags = (__u16) priv->scan_mode;
+
+out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+/* Commit handler, called after set operations */
+static int orinoco_ioctl_commit(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ unsigned long flags;
+ int err = 0;
+
+ if (!priv->open)
+ return 0;
+
+ if (priv->broken_disableport) {
+ orinoco_reset(&priv->reset_work);
+ return 0;
+ }
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return err;
+
+ err = hermes_disable_port(hw, 0);
+ if (err) {
+ printk(KERN_WARNING "%s: Unable to disable port "
+ "while reconfiguring card\n", dev->name);
+ priv->broken_disableport = 1;
+ goto out;
+ }
+
+ err = __orinoco_program_rids(dev);
+ if (err) {
+ printk(KERN_WARNING "%s: Unable to reconfigure card\n",
+ dev->name);
+ goto out;
+ }
+
+ err = hermes_enable_port(hw, 0);
+ if (err) {
+ printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
+ dev->name);
+ goto out;
+ }
+
+ out:
+ if (err) {
+ printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
+ schedule_work(&priv->reset_work);
+ err = 0;
+ }
+
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+static const struct iw_priv_args orinoco_privtab[] = {
+ { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
+ { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
+ { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_port3" },
+ { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_port3" },
+ { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_preamble" },
+ { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_preamble" },
+ { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_ibssport" },
+ { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_ibssport" },
+ { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
+ "get_rid" },
+};
+
+
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+#define STD_IW_HANDLER(id, func) \
+ [IW_IOCTL_IDX(id)] = (iw_handler) func
+static const iw_handler orinoco_handler[] = {
+ STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit),
+ STD_IW_HANDLER(SIOCGIWNAME, orinoco_ioctl_getname),
+ STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq),
+ STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq),
+ STD_IW_HANDLER(SIOCSIWMODE, orinoco_ioctl_setmode),
+ STD_IW_HANDLER(SIOCGIWMODE, orinoco_ioctl_getmode),
+ STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens),
+ STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens),
+ STD_IW_HANDLER(SIOCGIWRANGE, orinoco_ioctl_getiwrange),
+ STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
+ STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
+ STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
+ STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
+ STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap),
+ STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap),
+ STD_IW_HANDLER(SIOCSIWSCAN, orinoco_ioctl_setscan),
+ STD_IW_HANDLER(SIOCGIWSCAN, orinoco_ioctl_getscan),
+ STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid),
+ STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid),
+ STD_IW_HANDLER(SIOCSIWNICKN, orinoco_ioctl_setnick),
+ STD_IW_HANDLER(SIOCGIWNICKN, orinoco_ioctl_getnick),
+ STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate),
+ STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate),
+ STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts),
+ STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts),
+ STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag),
+ STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag),
+ STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry),
+ STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode),
+ STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode),
+ STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower),
+ STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower),
+ STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
+ STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
+ STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
+ STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
+ STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
+ STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
+ STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
+};
+
+
+/*
+ Added typecasting since we no longer use iwreq_data -- Moustafa
+ */
+static const iw_handler orinoco_private_handler[] = {
+ [0] = (iw_handler) orinoco_ioctl_reset,
+ [1] = (iw_handler) orinoco_ioctl_reset,
+ [2] = (iw_handler) orinoco_ioctl_setport3,
+ [3] = (iw_handler) orinoco_ioctl_getport3,
+ [4] = (iw_handler) orinoco_ioctl_setpreamble,
+ [5] = (iw_handler) orinoco_ioctl_getpreamble,
+ [6] = (iw_handler) orinoco_ioctl_setibssport,
+ [7] = (iw_handler) orinoco_ioctl_getibssport,
+ [9] = (iw_handler) orinoco_ioctl_getrid,
+};
+
+const struct iw_handler_def orinoco_handler_def = {
+ .num_standard = ARRAY_SIZE(orinoco_handler),
+ .num_private = ARRAY_SIZE(orinoco_private_handler),
+ .num_private_args = ARRAY_SIZE(orinoco_privtab),
+ .standard = orinoco_handler,
+ .private = orinoco_private_handler,
+ .private_args = orinoco_privtab,
+ .get_wireless_stats = orinoco_get_wireless_stats,
+};
diff --git a/drivers/net/wireless/orinoco/wext.h b/drivers/net/wireless/orinoco/wext.h
new file mode 100644
index 00000000000..1479f4e26dd
--- /dev/null
+++ b/drivers/net/wireless/orinoco/wext.h
@@ -0,0 +1,13 @@
+/* Wireless extensions support.
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_WEXT_H_
+#define _ORINOCO_WEXT_H_
+
+#include <net/iw_handler.h>
+
+/* Structure defining all our WEXT handlers */
+extern const struct iw_handler_def orinoco_handler_def;
+
+#endif /* _ORINOCO_WEXT_H_ */
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig
index d3469d08f96..cfc5f41aa13 100644
--- a/drivers/net/wireless/p54/Kconfig
+++ b/drivers/net/wireless/p54/Kconfig
@@ -61,3 +61,13 @@ config P54_PCI
http://prism54.org/
If you choose to build a module, it'll be called p54pci.
+
+config P54_SPI
+ tristate "Prism54 SPI (stlc45xx) support"
+ depends on P54_COMMON && SPI_MASTER
+ ---help---
+ This driver is for stlc4550 or stlc4560 based wireless chips.
+ This driver is experimental, untested and will probably only work on
+ Nokia's N800/N810 Portable Internet Tablet.
+
+ If you choose to build a module, it'll be called p54spi.
diff --git a/drivers/net/wireless/p54/Makefile b/drivers/net/wireless/p54/Makefile
index 4fa9ce71736..c2050dee629 100644
--- a/drivers/net/wireless/p54/Makefile
+++ b/drivers/net/wireless/p54/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_P54_COMMON) += p54common.o
obj-$(CONFIG_P54_USB) += p54usb.o
obj-$(CONFIG_P54_PCI) += p54pci.o
+obj-$(CONFIG_P54_SPI) += p54spi.o
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index ab79e32f0b2..2dda5fe418b 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -14,6 +14,10 @@
* published by the Free Software Foundation.
*/
+#ifdef CONFIG_MAC80211_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_MAC80211_LEDS */
+
enum p54_control_frame_types {
P54_CONTROL_TYPE_SETUP = 0,
P54_CONTROL_TYPE_SCAN,
@@ -44,6 +48,18 @@ enum p54_control_frame_types {
P54_CONTROL_TYPE_BT_OPTIONS = 35
};
+/* provide 16 bytes for the transport back-end */
+#define P54_TX_INFO_DATA_SIZE 16
+
+/* stored in ieee80211_tx_info's rate_driver_data */
+struct p54_tx_info {
+ u32 start_addr;
+ u32 end_addr;
+ void *data[P54_TX_INFO_DATA_SIZE / sizeof(void *)];
+};
+
+#define P54_MAX_CTRL_FRAME_LEN 0x1000
+
#define P54_HDR_FLAG_CONTROL BIT(15)
#define P54_HDR_FLAG_CONTROL_OPSET (BIT(15) + BIT(0))
@@ -75,6 +91,14 @@ struct p54_rssi_linear_approximation {
s16 longbow_unk2;
};
+struct p54_cal_database {
+ size_t entries;
+ size_t entry_size;
+ size_t offset;
+ size_t len;
+ u8 data[0];
+};
+
#define EEPROM_READBACK_LEN 0x3fc
#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
@@ -84,6 +108,29 @@ struct p54_rssi_linear_approximation {
#define FW_LM87 0x4c4d3837
#define FW_LM20 0x4c4d3230
+enum fw_state {
+ FW_STATE_OFF,
+ FW_STATE_BOOTING,
+ FW_STATE_READY,
+ FW_STATE_RESET,
+ FW_STATE_RESETTING,
+};
+
+#ifdef CONFIG_MAC80211_LEDS
+
+#define P54_LED_MAX_NAME_LEN 31
+
+struct p54_led_dev {
+ struct ieee80211_hw *hw_dev;
+ struct led_classdev led_dev;
+ char name[P54_LED_MAX_NAME_LEN + 1];
+
+ unsigned int index;
+ unsigned int registered;
+};
+
+#endif /* CONFIG_MAC80211_LEDS */
+
struct p54_common {
struct ieee80211_hw *hw;
u32 rx_start;
@@ -99,11 +146,12 @@ struct p54_common {
struct mutex conf_mutex;
u8 mac_addr[ETH_ALEN];
u8 bssid[ETH_ALEN];
+ u8 rx_diversity_mask;
+ u8 tx_diversity_mask;
struct pda_iq_autocal_entry *iq_autocal;
unsigned int iq_autocal_len;
- struct pda_channel_output_limit *output_limit;
- unsigned int output_limit_len;
- struct pda_pa_curve_data *curve_data;
+ struct p54_cal_database *output_limit;
+ struct p54_cal_database *curve_data;
struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
unsigned int filter_flags;
bool use_short_slot;
@@ -115,7 +163,7 @@ struct p54_common {
unsigned int output_power;
u32 tsf_low32;
u32 tsf_high32;
- u64 basic_rate_mask;
+ u32 basic_rate_mask;
u16 wakeup_timer;
u16 aid;
struct ieee80211_tx_queue_stats tx_stats[8];
@@ -128,13 +176,21 @@ struct p54_common {
struct completion eeprom_comp;
u8 privacy_caps;
u8 rx_keycache_size;
+ /* LED management */
+ #ifdef CONFIG_MAC80211_LEDS
+ struct p54_led_dev assoc_led;
+ struct p54_led_dev tx_led;
+ #endif /* CONFIG_MAC80211_LEDS */
+ u16 softled_state; /* bit field of glowing LEDs */
};
int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb);
int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
+int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len);
int p54_read_eeprom(struct ieee80211_hw *dev);
struct ieee80211_hw *p54_init_common(size_t priv_data_len);
+int p54_register_common(struct ieee80211_hw *dev, struct device *pdev);
void p54_free_common(struct ieee80211_hw *dev);
#endif /* P54_H */
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index c6a370fa9bc..0a989834b70 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -21,6 +21,9 @@
#include <linux/etherdevice.h>
#include <net/mac80211.h>
+#ifdef CONFIG_MAC80211_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_MAC80211_LEDS */
#include "p54.h"
#include "p54common.h"
@@ -239,11 +242,11 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
if (priv->fw_var >= 0x300) {
/* Firmware supports QoS, use it! */
- priv->tx_stats[4].limit = 3; /* AC_VO */
- priv->tx_stats[5].limit = 4; /* AC_VI */
- priv->tx_stats[6].limit = 3; /* AC_BE */
- priv->tx_stats[7].limit = 2; /* AC_BK */
- dev->queues = 4;
+ priv->tx_stats[P54_QUEUE_AC_VO].limit = 3;
+ priv->tx_stats[P54_QUEUE_AC_VI].limit = 4;
+ priv->tx_stats[P54_QUEUE_AC_BE].limit = 3;
+ priv->tx_stats[P54_QUEUE_AC_BK].limit = 2;
+ dev->queues = P54_QUEUE_AC_NUM;
}
if (!modparam_nohwcrypt)
@@ -272,13 +275,19 @@ static int p54_convert_rev0(struct ieee80211_hw *dev,
unsigned int i, j;
void *source, *target;
- priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
+ priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
+ GFP_KERNEL);
if (!priv->curve_data)
return -ENOMEM;
- memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
+ priv->curve_data->entries = curve_data->channels;
+ priv->curve_data->entry_size = sizeof(__le16) +
+ sizeof(*dst) * curve_data->points_per_channel;
+ priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
+ priv->curve_data->len = cd_len;
+ memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
source = curve_data->data;
- target = priv->curve_data->data;
+ target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
for (i = 0; i < curve_data->channels; i++) {
__le16 *freq = source;
source += sizeof(__le16);
@@ -318,13 +327,19 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
unsigned int i, j;
void *source, *target;
- priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
+ priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
+ GFP_KERNEL);
if (!priv->curve_data)
return -ENOMEM;
- memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
+ priv->curve_data->entries = curve_data->channels;
+ priv->curve_data->entry_size = sizeof(__le16) +
+ sizeof(*dst) * curve_data->points_per_channel;
+ priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
+ priv->curve_data->len = cd_len;
+ memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
source = curve_data->data;
- target = priv->curve_data->data;
+ target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
for (i = 0; i < curve_data->channels; i++) {
__le16 *freq = source;
source += sizeof(__le16);
@@ -376,7 +391,102 @@ static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
}
}
-static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
+static void p54_parse_default_country(struct ieee80211_hw *dev,
+ void *data, int len)
+{
+ struct pda_country *country;
+
+ if (len != sizeof(*country)) {
+ printk(KERN_ERR "%s: found possible invalid default country "
+ "eeprom entry. (entry size: %d)\n",
+ wiphy_name(dev->wiphy), len);
+
+ print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
+ data, len);
+
+ printk(KERN_ERR "%s: please report this issue.\n",
+ wiphy_name(dev->wiphy));
+ return;
+ }
+
+ country = (struct pda_country *) data;
+ if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
+ regulatory_hint(dev->wiphy, country->alpha2);
+ else {
+ /* TODO:
+ * write a shared/common function that converts
+ * "Regulatory domain codes" (802.11-2007 14.8.2.2)
+ * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
+ */
+ }
+}
+
+static int p54_convert_output_limits(struct ieee80211_hw *dev,
+ u8 *data, size_t len)
+{
+ struct p54_common *priv = dev->priv;
+
+ if (len < 2)
+ return -EINVAL;
+
+ if (data[0] != 0) {
+ printk(KERN_ERR "%s: unknown output power db revision:%x\n",
+ wiphy_name(dev->wiphy), data[0]);
+ return -EINVAL;
+ }
+
+ if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
+ return -EINVAL;
+
+ priv->output_limit = kmalloc(data[1] *
+ sizeof(struct pda_channel_output_limit) +
+ sizeof(*priv->output_limit), GFP_KERNEL);
+
+ if (!priv->output_limit)
+ return -ENOMEM;
+
+ priv->output_limit->offset = 0;
+ priv->output_limit->entries = data[1];
+ priv->output_limit->entry_size =
+ sizeof(struct pda_channel_output_limit);
+ priv->output_limit->len = priv->output_limit->entry_size *
+ priv->output_limit->entries +
+ priv->output_limit->offset;
+
+ memcpy(priv->output_limit->data, &data[2],
+ data[1] * sizeof(struct pda_channel_output_limit));
+
+ return 0;
+}
+
+static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
+ size_t total_len)
+{
+ struct p54_cal_database *dst;
+ size_t payload_len, entries, entry_size, offset;
+
+ payload_len = le16_to_cpu(src->len);
+ entries = le16_to_cpu(src->entries);
+ entry_size = le16_to_cpu(src->entry_size);
+ offset = le16_to_cpu(src->offset);
+ if (((entries * entry_size + offset) != payload_len) ||
+ (payload_len + sizeof(*src) != total_len))
+ return NULL;
+
+ dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
+ if (!dst)
+ return NULL;
+
+ dst->entries = entries;
+ dst->entry_size = entry_size;
+ dst->offset = offset;
+ dst->len = payload_len;
+
+ memcpy(dst->data, src->data, payload_len);
+ return dst;
+}
+
+int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
{
struct p54_common *priv = dev->priv;
struct eeprom_pda_wrap *wrap = NULL;
@@ -401,30 +511,17 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
switch (le16_to_cpu(entry->code)) {
case PDR_MAC_ADDRESS:
+ if (data_len != ETH_ALEN)
+ break;
SET_IEEE80211_PERM_ADDR(dev, entry->data);
break;
case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
- if (data_len < 2) {
- err = -EINVAL;
- goto err;
- }
-
- if (2 + entry->data[1]*sizeof(*priv->output_limit) > data_len) {
- err = -EINVAL;
- goto err;
- }
-
- priv->output_limit = kmalloc(entry->data[1] *
- sizeof(*priv->output_limit), GFP_KERNEL);
-
- if (!priv->output_limit) {
- err = -ENOMEM;
+ if (priv->output_limit)
+ break;
+ err = p54_convert_output_limits(dev, entry->data,
+ data_len);
+ if (err)
goto err;
- }
-
- memcpy(priv->output_limit, &entry->data[2],
- entry->data[1]*sizeof(*priv->output_limit));
- priv->output_limit_len = entry->data[1];
break;
case PDR_PRISM_PA_CAL_CURVE_DATA: {
struct pda_pa_curve_data *curve_data =
@@ -451,8 +548,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
}
if (err)
goto err;
-
- }
+ }
+ break;
case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
if (!priv->iq_autocal) {
@@ -463,6 +560,9 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
memcpy(priv->iq_autocal, entry->data, data_len);
priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
break;
+ case PDR_DEFAULT_COUNTRY:
+ p54_parse_default_country(dev, entry->data, data_len);
+ break;
case PDR_INTERFACE_LIST:
tmp = entry->data;
while ((u8 *)tmp < entry->data + data_len) {
@@ -473,6 +573,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
}
break;
case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
+ if (data_len < 2)
+ break;
priv->version = *(u8 *)(entry->data + 1);
break;
case PDR_RSSI_LINEAR_APPROXIMATION:
@@ -481,6 +583,34 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
p54_parse_rssical(dev, entry->data, data_len,
le16_to_cpu(entry->code));
break;
+ case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: {
+ __le16 *src = (void *) entry->data;
+ s16 *dst = (void *) &priv->rssical_db;
+ int i;
+
+ if (data_len != sizeof(priv->rssical_db)) {
+ err = -EINVAL;
+ goto err;
+ }
+ for (i = 0; i < sizeof(priv->rssical_db) /
+ sizeof(*src); i++)
+ *(dst++) = (s16) le16_to_cpu(*(src++));
+ }
+ break;
+ case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
+ struct pda_custom_wrapper *pda = (void *) entry->data;
+ if (priv->output_limit || data_len < sizeof(*pda))
+ break;
+ priv->output_limit = p54_convert_db(pda, data_len);
+ }
+ break;
+ case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
+ struct pda_custom_wrapper *pda = (void *) entry->data;
+ if (priv->curve_data || data_len < sizeof(*pda))
+ break;
+ priv->curve_data = p54_convert_db(pda, data_len);
+ }
+ break;
case PDR_END:
/* make it overrun */
entry_len = len;
@@ -497,7 +627,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
case PDR_UTF8_OEM_NAME:
case PDR_UTF8_PRODUCT_NAME:
case PDR_COUNTRY_LIST:
- case PDR_DEFAULT_COUNTRY:
case PDR_ANTENNA_GAIN:
case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA:
case PDR_REGULATORY_POWER_LIMITS:
@@ -525,12 +654,16 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
}
priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
- if (priv->rxhw == 4)
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
p54_init_xbow_synth(dev);
if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
+ if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
+ priv->rx_diversity_mask = 3;
+ if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
+ priv->tx_diversity_mask = 3;
if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
u8 perm_addr[ETH_ALEN];
@@ -568,13 +701,21 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
wiphy_name(dev->wiphy));
return err;
}
+EXPORT_SYMBOL_GPL(p54_parse_eeprom);
static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
{
struct p54_common *priv = dev->priv;
int band = dev->conf.channel->band;
- return ((rssi * priv->rssical_db[band].mul) / 64 +
+ if (priv->rxhw != PDR_SYNTH_FRONTEND_LONGBOW)
+ return ((rssi * priv->rssical_db[band].mul) / 64 +
+ priv->rssical_db[band].add) / 4;
+ else
+ /*
+ * TODO: find the correct formula
+ */
+ return ((rssi * priv->rssical_db[band].mul) / 64 +
priv->rssical_db[band].add) / 4;
}
@@ -597,10 +738,7 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
return 0;
if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD))) {
- if (priv->filter_flags & FIF_FCSFAIL)
- rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
- else
- return 0;
+ return 0;
}
if (hdr->decrypt_status == P54_DECRYPT_OK)
@@ -655,7 +793,8 @@ static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
return ;
for (i = 0; i < dev->queues; i++)
- if (priv->tx_stats[i + 4].len < priv->tx_stats[i + 4].limit)
+ if (priv->tx_stats[i + P54_QUEUE_DATA].len <
+ priv->tx_stats[i + P54_QUEUE_DATA].limit)
ieee80211_wake_queue(dev, i);
}
@@ -663,7 +802,7 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54_common *priv = dev->priv;
struct ieee80211_tx_info *info;
- struct memrecord *range;
+ struct p54_tx_info *range;
unsigned long flags;
u32 freed = 0, last_addr = priv->rx_start;
@@ -681,18 +820,18 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
range = (void *)info->rate_driver_data;
if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
- struct memrecord *mr;
+ struct p54_tx_info *mr;
ni = IEEE80211_SKB_CB(skb->prev);
- mr = (struct memrecord *)ni->rate_driver_data;
+ mr = (struct p54_tx_info *)ni->rate_driver_data;
last_addr = mr->end_addr;
}
if (skb->next != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
- struct memrecord *mr;
+ struct p54_tx_info *mr;
ni = IEEE80211_SKB_CB(skb->next);
- mr = (struct memrecord *)ni->rate_driver_data;
+ mr = (struct p54_tx_info *)ni->rate_driver_data;
freed = mr->start_addr - last_addr;
} else
freed = priv->rx_end - last_addr;
@@ -710,10 +849,11 @@ static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev,
__le32 req_id)
{
struct p54_common *priv = dev->priv;
- struct sk_buff *entry = priv->tx_queue.next;
+ struct sk_buff *entry;
unsigned long flags;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
+ entry = priv->tx_queue.next;
while (entry != (struct sk_buff *)&priv->tx_queue) {
struct p54_hdr *hdr = (struct p54_hdr *) entry->data;
@@ -732,20 +872,21 @@ static void p54_rx_frame_sent(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_frame_sent *payload = (struct p54_frame_sent *) hdr->data;
- struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next;
+ struct sk_buff *entry;
u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
- struct memrecord *range = NULL;
+ 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) {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
struct p54_hdr *entry_hdr;
struct p54_tx_data *entry_data;
- int pad = 0;
+ unsigned int pad = 0, frame_len;
range = (void *)info->rate_driver_data;
if (range->start_addr != addr) {
@@ -756,10 +897,10 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
if (entry->next != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
- struct memrecord *mr;
+ struct p54_tx_info *mr;
ni = IEEE80211_SKB_CB(entry->next);
- mr = (struct memrecord *)ni->rate_driver_data;
+ mr = (struct p54_tx_info *)ni->rate_driver_data;
freed = mr->start_addr - last_addr;
} else
freed = priv->rx_end - last_addr;
@@ -768,14 +909,22 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
__skb_unlink(entry, &priv->tx_queue);
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+ frame_len = entry->len;
entry_hdr = (struct p54_hdr *) entry->data;
entry_data = (struct p54_tx_data *) entry_hdr->data;
priv->tx_stats[entry_data->hw_queue].len--;
priv->stats.dot11ACKFailureCount += payload->tries - 1;
- if (unlikely(entry == priv->cached_beacon)) {
+ /*
+ * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
+ * generated by the driver. Therefore tx_status is bogus
+ * and we don't want to confuse the mac80211 stack.
+ */
+ if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
+ if (entry_data->hw_queue == P54_QUEUE_BEACON)
+ priv->cached_beacon = NULL;
+
kfree_skb(entry);
- priv->cached_beacon = NULL;
goto out;
}
@@ -814,15 +963,28 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
info->status.ack_signal = p54_rssi_to_dbm(dev,
(int)payload->ack_rssi);
- if (entry_data->key_type == P54_CRYPTO_TKIPMICHAEL) {
+ /* Undo all changes to the frame. */
+ switch (entry_data->key_type) {
+ case P54_CRYPTO_TKIPMICHAEL: {
u8 *iv = (u8 *)(entry_data->align + pad +
- entry_data->crypt_offset);
+ entry_data->crypt_offset);
/* Restore the original TKIP IV. */
iv[2] = iv[0];
iv[0] = iv[1];
iv[1] = (iv[0] | 0x20) & 0x7f; /* WEPSeed - 8.3.2.2 */
+
+ frame_len -= 12; /* remove TKIP_MMIC + TKIP_ICV */
+ break;
+ }
+ case P54_CRYPTO_AESCCMP:
+ frame_len -= 8; /* remove CCMP_MIC */
+ break;
+ case P54_CRYPTO_WEP:
+ frame_len -= 4; /* remove WEP_ICV */
+ break;
}
+ skb_trim(entry, frame_len);
skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
ieee80211_tx_status_irqsafe(dev, entry);
goto out;
@@ -955,17 +1117,17 @@ EXPORT_SYMBOL_GPL(p54_rx);
* can find some unused memory to upload our packets to. However, data that we
* want the card to TX needs to stay intact until the card has told us that
* it is done with it. This function finds empty places we can upload to and
- * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees
- * allocated areas.
+ * marks allocated areas as reserved if necessary. p54_rx_frame_sent or
+ * p54_free_skb frees allocated areas.
*/
static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
struct p54_hdr *data, u32 len)
{
struct p54_common *priv = dev->priv;
- struct sk_buff *entry = priv->tx_queue.next;
+ struct sk_buff *entry;
struct sk_buff *target_skb = NULL;
struct ieee80211_tx_info *info;
- struct memrecord *range;
+ struct p54_tx_info *range;
u32 last_addr = priv->rx_start;
u32 largest_hole = 0;
u32 target_addr = priv->rx_start;
@@ -1000,6 +1162,7 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
}
}
+ entry = priv->tx_queue.next;
while (left--) {
u32 hole_size;
info = IEEE80211_SKB_CB(entry);
@@ -1046,25 +1209,29 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
return 0;
}
-static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev,
- u16 hdr_flags, u16 len, u16 type, gfp_t memflags)
+static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, u16 hdr_flags,
+ u16 payload_len, u16 type, gfp_t memflags)
{
struct p54_common *priv = dev->priv;
struct p54_hdr *hdr;
struct sk_buff *skb;
+ size_t frame_len = sizeof(*hdr) + payload_len;
+
+ if (frame_len > P54_MAX_CTRL_FRAME_LEN)
+ return NULL;
- skb = __dev_alloc_skb(len + priv->tx_hdr_len, memflags);
+ skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags);
if (!skb)
return NULL;
skb_reserve(skb, priv->tx_hdr_len);
hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr));
hdr->flags = cpu_to_le16(hdr_flags);
- hdr->len = cpu_to_le16(len - sizeof(*hdr));
+ hdr->len = cpu_to_le16(payload_len);
hdr->type = cpu_to_le16(type);
hdr->tries = hdr->rts_tries = 0;
- if (unlikely(p54_assign_address(dev, skb, hdr, len))) {
+ if (p54_assign_address(dev, skb, hdr, frame_len)) {
kfree_skb(skb);
return NULL;
}
@@ -1074,7 +1241,6 @@ static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev,
int p54_read_eeprom(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
- struct p54_hdr *hdr = NULL;
struct p54_eeprom_lm86 *eeprom_hdr;
struct sk_buff *skb;
size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
@@ -1087,9 +1253,9 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
else
maxblocksize -= 0x4;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*hdr) +
- sizeof(*eeprom_hdr) + maxblocksize,
- P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*eeprom_hdr) +
+ maxblocksize, P54_CONTROL_TYPE_EEPROM_READBACK,
+ GFP_KERNEL);
if (!skb)
goto free;
priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL);
@@ -1145,9 +1311,8 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
struct sk_buff *skb;
struct p54_tim *tim;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
- sizeof(struct p54_hdr) + sizeof(*tim),
- P54_CONTROL_TYPE_TIM, GFP_KERNEL);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim),
+ P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1164,9 +1329,8 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
struct sk_buff *skb;
struct p54_sta_unlock *sta;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
- sizeof(struct p54_hdr) + sizeof(*sta),
- P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta),
+ P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1206,9 +1370,8 @@ static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry)
struct p54_hdr *hdr;
struct p54_txcancel *cancel;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
- sizeof(struct p54_hdr) + sizeof(*cancel),
- P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel),
+ P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1225,46 +1388,73 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct p54_common *priv = dev->priv;
- int ret = 0;
-
- if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
- if (ieee80211_is_beacon(hdr->frame_control)) {
- *aid = 0;
- *queue = 0;
- *extra_len = IEEE80211_MAX_TIM_LEN;
- *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
- return 0;
- } else if (ieee80211_is_probe_resp(hdr->frame_control)) {
- *aid = 0;
- *queue = 2;
- *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
- P54_HDR_FLAG_DATA_OUT_NOCANCEL;
- return 0;
- } else {
- *queue = 2;
- ret = 0;
- }
- } else {
- *queue += 4;
- ret = 1;
- }
+ int ret = 1;
switch (priv->mode) {
+ case NL80211_IFTYPE_MONITOR:
+ /*
+ * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for
+ * every frame in promiscuous/monitor mode.
+ * see STSW45x0C LMAC API - page 12.
+ */
+ *aid = 0;
+ *flags = P54_HDR_FLAG_DATA_OUT_PROMISC;
+ *queue += P54_QUEUE_DATA;
+ break;
case NL80211_IFTYPE_STATION:
*aid = 1;
+ if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+ *queue = P54_QUEUE_MGMT;
+ ret = 0;
+ } else
+ *queue += P54_QUEUE_DATA;
break;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
*aid = 0;
- *queue = 3;
+ *queue = P54_QUEUE_CAB;
return 0;
}
+
+ if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+ if (ieee80211_is_probe_resp(hdr->frame_control)) {
+ *aid = 0;
+ *queue = P54_QUEUE_MGMT;
+ *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
+ P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+ return 0;
+ } else if (ieee80211_is_beacon(hdr->frame_control)) {
+ *aid = 0;
+
+ if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+ /*
+ * Injecting beacons on top of a AP is
+ * not a good idea... nevertheless,
+ * it should be doable.
+ */
+
+ *queue += P54_QUEUE_DATA;
+ return 1;
+ }
+
+ *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
+ *queue = P54_QUEUE_BEACON;
+ *extra_len = IEEE80211_MAX_TIM_LEN;
+ return 0;
+ } else {
+ *queue = P54_QUEUE_MGMT;
+ ret = 0;
+ }
+ } else
+ *queue += P54_QUEUE_DATA;
+
if (info->control.sta)
*aid = info->control.sta->aid;
else
*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+ break;
}
return ret;
}
@@ -1286,7 +1476,7 @@ static u8 p54_convert_algo(enum ieee80211_key_alg alg)
static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_tx_queue_stats *current_queue = NULL;
+ struct ieee80211_tx_queue_stats *current_queue;
struct p54_common *priv = dev->priv;
struct p54_hdr *hdr;
struct p54_tx_data *txhdr;
@@ -1429,15 +1619,17 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
}
txhdr->crypt_offset = crypt_offset;
txhdr->hw_queue = queue;
- if (current_queue)
- txhdr->backlog = current_queue->len;
- else
- txhdr->backlog = 0;
+ txhdr->backlog = current_queue->len;
memset(txhdr->durations, 0, sizeof(txhdr->durations));
- txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
- 2 : info->antenna_sel_tx - 1;
- txhdr->output_power = priv->output_power;
- txhdr->cts_rate = cts_rate;
+ txhdr->tx_antenna = ((info->antenna_sel_tx == 0) ?
+ 2 : info->antenna_sel_tx - 1) & priv->tx_diversity_mask;
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ txhdr->longbow.cts_rate = cts_rate;
+ txhdr->longbow.output_power = cpu_to_le16(priv->output_power);
+ } else {
+ txhdr->normal.output_power = priv->output_power;
+ txhdr->normal.cts_rate = cts_rate;
+ }
if (padding)
txhdr->align[0] = padding;
@@ -1450,14 +1642,12 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
queue_delayed_work(dev->workqueue, &priv->work,
msecs_to_jiffies(P54_TX_FRAME_LIFETIME));
- return 0;
+ return NETDEV_TX_OK;
err:
skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding);
- if (current_queue) {
- current_queue->len--;
- current_queue->count--;
- }
+ current_queue->len--;
+ current_queue->count--;
return NETDEV_TX_BUSY;
}
@@ -1468,9 +1658,8 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
struct p54_setup_mac *setup;
u16 mode;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_SETUP,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup),
+ P54_CONTROL_TYPE_SETUP, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1487,19 +1676,29 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
case NL80211_IFTYPE_MESH_POINT:
mode = P54_FILTER_TYPE_IBSS;
break;
+ case NL80211_IFTYPE_MONITOR:
+ mode = P54_FILTER_TYPE_PROMISCUOUS;
+ break;
default:
- mode = P54_FILTER_TYPE_NONE;
+ mode = P54_FILTER_TYPE_HIBERNATE;
break;
}
- if (priv->filter_flags & FIF_PROMISC_IN_BSS)
+
+ /*
+ * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
+ * STSW45X0C LMAC API - page 12
+ */
+ if (((priv->filter_flags & FIF_PROMISC_IN_BSS) ||
+ (priv->filter_flags & FIF_OTHER_BSS)) &&
+ (mode != P54_FILTER_TYPE_PROMISCUOUS))
mode |= P54_FILTER_TYPE_TRANSPARENT;
} else
- mode = P54_FILTER_TYPE_RX_DISABLED;
+ mode = P54_FILTER_TYPE_HIBERNATE;
setup->mac_mode = cpu_to_le16(mode);
memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
memcpy(setup->bssid, priv->bssid, ETH_ALEN);
- setup->rx_antenna = 2; /* automatic */
+ setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */
setup->rx_align = 0;
if (priv->fw_var < 0x500) {
setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
@@ -1532,105 +1731,162 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
{
struct p54_common *priv = dev->priv;
struct sk_buff *skb;
- struct p54_scan *chan;
+ struct p54_hdr *hdr;
+ struct p54_scan_head *head;
+ struct p54_iq_autocal_entry *iq_autocal;
+ union p54_scan_body_union *body;
+ struct p54_scan_tail_rate *rate;
+ struct pda_rssi_cal_entry *rssi;
unsigned int i;
void *entry;
- __le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
int band = dev->conf.channel->band;
+ __le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
+ 2 + sizeof(*iq_autocal) + sizeof(*body) +
+ sizeof(*rate) + 2 * sizeof(*rssi),
+ P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
- chan = (struct p54_scan *) skb_put(skb, sizeof(*chan));
- memset(chan->padding1, 0, sizeof(chan->padding1));
- chan->mode = cpu_to_le16(mode);
- chan->dwell = cpu_to_le16(dwell);
+ head = (struct p54_scan_head *) skb_put(skb, sizeof(*head));
+ memset(head->scan_params, 0, sizeof(head->scan_params));
+ head->mode = cpu_to_le16(mode);
+ head->dwell = cpu_to_le16(dwell);
+ head->freq = freq;
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ __le16 *pa_power_points = (__le16 *) skb_put(skb, 2);
+ *pa_power_points = cpu_to_le16(0x0c);
+ }
+
+ iq_autocal = (void *) skb_put(skb, sizeof(*iq_autocal));
for (i = 0; i < priv->iq_autocal_len; i++) {
if (priv->iq_autocal[i].freq != freq)
continue;
- memcpy(&chan->iq_autocal, &priv->iq_autocal[i],
- sizeof(*priv->iq_autocal));
+ memcpy(iq_autocal, &priv->iq_autocal[i].params,
+ sizeof(struct p54_iq_autocal_entry));
break;
}
if (i == priv->iq_autocal_len)
goto err;
- for (i = 0; i < priv->output_limit_len; i++) {
- if (priv->output_limit[i].freq != freq)
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW)
+ body = (void *) skb_put(skb, sizeof(body->longbow));
+ else
+ body = (void *) skb_put(skb, sizeof(body->normal));
+
+ for (i = 0; i < priv->output_limit->entries; i++) {
+ __le16 *entry_freq = (void *) (priv->output_limit->data +
+ priv->output_limit->entry_size * i);
+
+ if (*entry_freq != freq)
continue;
- chan->val_barker = 0x38;
- chan->val_bpsk = chan->dup_bpsk =
- priv->output_limit[i].val_bpsk;
- chan->val_qpsk = chan->dup_qpsk =
- priv->output_limit[i].val_qpsk;
- chan->val_16qam = chan->dup_16qam =
- priv->output_limit[i].val_16qam;
- chan->val_64qam = chan->dup_64qam =
- priv->output_limit[i].val_64qam;
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ memcpy(&body->longbow.power_limits,
+ (void *) entry_freq + sizeof(__le16),
+ priv->output_limit->entry_size);
+ } else {
+ struct pda_channel_output_limit *limits =
+ (void *) entry_freq;
+
+ body->normal.val_barker = 0x38;
+ body->normal.val_bpsk = body->normal.dup_bpsk =
+ limits->val_bpsk;
+ body->normal.val_qpsk = body->normal.dup_qpsk =
+ limits->val_qpsk;
+ body->normal.val_16qam = body->normal.dup_16qam =
+ limits->val_16qam;
+ body->normal.val_64qam = body->normal.dup_64qam =
+ limits->val_64qam;
+ }
break;
}
- if (i == priv->output_limit_len)
+ if (i == priv->output_limit->entries)
goto err;
- entry = priv->curve_data->data;
- for (i = 0; i < priv->curve_data->channels; i++) {
+ entry = (void *)(priv->curve_data->data + priv->curve_data->offset);
+ for (i = 0; i < priv->curve_data->entries; i++) {
if (*((__le16 *)entry) != freq) {
- entry += sizeof(__le16);
- entry += sizeof(struct p54_pa_curve_data_sample) *
- priv->curve_data->points_per_channel;
+ entry += priv->curve_data->entry_size;
continue;
}
- entry += sizeof(__le16);
- chan->pa_points_per_curve = 8;
- memset(chan->curve_data, 0, sizeof(*chan->curve_data));
- memcpy(chan->curve_data, entry,
- sizeof(struct p54_pa_curve_data_sample) *
- min((u8)8, priv->curve_data->points_per_channel));
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ memcpy(&body->longbow.curve_data,
+ (void *) entry + sizeof(__le16),
+ priv->curve_data->entry_size);
+ } else {
+ struct p54_scan_body *chan = &body->normal;
+ struct pda_pa_curve_data *curve_data =
+ (void *) priv->curve_data->data;
+
+ entry += sizeof(__le16);
+ chan->pa_points_per_curve = 8;
+ memset(chan->curve_data, 0, sizeof(*chan->curve_data));
+ memcpy(chan->curve_data, entry,
+ sizeof(struct p54_pa_curve_data_sample) *
+ min((u8)8, curve_data->points_per_channel));
+ }
break;
}
+ if (i == priv->curve_data->entries)
+ goto err;
- if (priv->fw_var < 0x500) {
- chan->v1_rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
- chan->v1_rssi.add = cpu_to_le16(priv->rssical_db[band].add);
- } else {
- chan->v2.rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
- chan->v2.rssi.add = cpu_to_le16(priv->rssical_db[band].add);
- chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
- memset(chan->v2.rts_rates, 0, 8);
+ if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) {
+ rate = (void *) skb_put(skb, sizeof(*rate));
+ rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+ for (i = 0; i < sizeof(rate->rts_rates); i++)
+ rate->rts_rates[i] = i;
+ }
+
+ rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
+ rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
+ rssi->add = cpu_to_le16(priv->rssical_db[band].add);
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ /* Longbow frontend needs ever more */
+ rssi = (void *) skb_put(skb, sizeof(*rssi));
+ rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
+ rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
}
+
+ if (priv->fw_var >= 0x509) {
+ rate = (void *) skb_put(skb, sizeof(*rate));
+ rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+ for (i = 0; i < sizeof(rate->rts_rates); i++)
+ rate->rts_rates[i] = i;
+ }
+
+ hdr = (struct p54_hdr *) skb->data;
+ hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
+
priv->tx(dev, skb);
return 0;
err:
printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
- kfree_skb(skb);
+ p54_free_skb(dev, skb);
return -EINVAL;
}
-static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
+static int p54_set_leds(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
struct sk_buff *skb;
struct p54_led *led;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_LED,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led),
+ P54_CONTROL_TYPE_LED, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
- led = (struct p54_led *)skb_put(skb, sizeof(*led));
- led->mode = cpu_to_le16(mode);
- led->led_permanent = cpu_to_le16(link);
- led->led_temporary = cpu_to_le16(act);
- led->duration = cpu_to_le16(1000);
+ led = (struct p54_led *) skb_put(skb, sizeof(*led));
+ led->flags = cpu_to_le16(0x0003);
+ led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state);
+ led->delay[0] = cpu_to_le16(1);
+ led->delay[1] = cpu_to_le16(0);
priv->tx(dev, skb);
return 0;
}
@@ -1649,9 +1905,8 @@ static int p54_set_edcf(struct ieee80211_hw *dev)
struct sk_buff *skb;
struct p54_edcf *edcf;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_DCFINIT,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
+ P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1675,6 +1930,42 @@ static int p54_set_edcf(struct ieee80211_hw *dev)
return 0;
}
+static int p54_set_ps(struct ieee80211_hw *dev)
+{
+ struct p54_common *priv = dev->priv;
+ struct sk_buff *skb;
+ struct p54_psm *psm;
+ u16 mode;
+ int i;
+
+ if (dev->conf.flags & IEEE80211_CONF_PS)
+ mode = P54_PSM | P54_PSM_DTIM | P54_PSM_MCBC;
+ else
+ mode = P54_PSM_CAM;
+
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm),
+ P54_CONTROL_TYPE_PSM, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ psm = (struct p54_psm *)skb_put(skb, sizeof(*psm));
+ psm->mode = cpu_to_le16(mode);
+ psm->aid = cpu_to_le16(priv->aid);
+ for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) {
+ psm->intervals[i].interval =
+ cpu_to_le16(dev->conf.listen_interval);
+ psm->intervals[i].periods = cpu_to_le16(1);
+ }
+
+ psm->beacon_rssi_skip_max = 60;
+ psm->rssi_delta_threshold = 0;
+ psm->nr = 0;
+
+ priv->tx(dev, skb);
+
+ return 0;
+}
+
static int p54_beacon_tim(struct sk_buff *skb)
{
/*
@@ -1779,6 +2070,9 @@ static int p54_start(struct ieee80211_hw *dev)
queue_delayed_work(dev->workqueue, &priv->work, 0);
+ priv->softled_state = 0;
+ err = p54_set_leds(dev);
+
out:
mutex_unlock(&priv->conf_mutex);
return err;
@@ -1791,6 +2085,9 @@ static void p54_stop(struct ieee80211_hw *dev)
mutex_lock(&priv->conf_mutex);
priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+ priv->softled_state = 0;
+ p54_set_leds(dev);
+
cancel_delayed_work_sync(&priv->work);
if (priv->cached_beacon)
p54_tx_cancel(dev, priv->cached_beacon);
@@ -1828,7 +2125,6 @@ static int p54_add_interface(struct ieee80211_hw *dev,
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
p54_setup_mac(dev);
- p54_set_leds(dev, 1, 0, 0);
mutex_unlock(&priv->conf_mutex);
return 0;
}
@@ -1867,6 +2163,11 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed)
if (ret)
goto out;
}
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ ret = p54_set_ps(dev);
+ if (ret)
+ goto out;
+ }
out:
mutex_unlock(&priv->conf_mutex);
@@ -1903,8 +2204,6 @@ static int p54_config_interface(struct ieee80211_hw *dev,
goto out;
}
- ret = p54_set_leds(dev, 1, !is_multicast_ether_addr(priv->bssid), 0);
-
out:
mutex_unlock(&priv->conf_mutex);
return ret;
@@ -1918,12 +2217,11 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
struct p54_common *priv = dev->priv;
*total_flags &= FIF_PROMISC_IN_BSS |
- (*total_flags & FIF_PROMISC_IN_BSS) ?
- FIF_FCSFAIL : 0;
+ FIF_OTHER_BSS;
priv->filter_flags = *total_flags;
- if (changed_flags & FIF_PROMISC_IN_BSS)
+ if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
p54_setup_mac(dev);
}
@@ -1950,10 +2248,8 @@ static int p54_init_xbow_synth(struct ieee80211_hw *dev)
struct sk_buff *skb;
struct p54_xbow_synth *xbow;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow) +
- sizeof(struct p54_hdr),
- P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
- GFP_KERNEL);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow),
+ P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL);
if (!skb)
return -ENOMEM;
@@ -1982,7 +2278,7 @@ static void p54_work(struct work_struct *work)
* 2. cancel stuck frames / reset the device if necessary.
*/
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(struct p54_hdr) +
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL,
sizeof(struct p54_statistics),
P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
if (!skb)
@@ -2005,8 +2301,8 @@ static int p54_get_tx_stats(struct ieee80211_hw *dev,
{
struct p54_common *priv = dev->priv;
- memcpy(stats, &priv->tx_stats[4], sizeof(stats[0]) * dev->queues);
-
+ memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA],
+ sizeof(stats[0]) * dev->queues);
return 0;
}
@@ -2042,7 +2338,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
}
static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct p54_common *priv = dev->priv;
@@ -2077,7 +2373,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
algo = P54_CRYPTO_AESCCMP;
break;
default:
- return -EINVAL;
+ return -EOPNOTSUPP;
}
}
@@ -2093,9 +2389,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
}
mutex_lock(&priv->conf_mutex);
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_RX_KEYCACHE,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
+ P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC);
if (!skb) {
mutex_unlock(&priv->conf_mutex);
return -ENOMEM;
@@ -2106,8 +2401,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
rxkey->entry = key->keyidx;
rxkey->key_id = key->keyidx;
rxkey->key_type = algo;
- if (address)
- memcpy(rxkey->mac, address, ETH_ALEN);
+ if (sta)
+ memcpy(rxkey->mac, sta->addr, ETH_ALEN);
else
memset(rxkey->mac, ~0, ETH_ALEN);
if (key->alg != ALG_TKIP) {
@@ -2125,6 +2420,96 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
return 0;
}
+#ifdef CONFIG_MAC80211_LEDS
+static void p54_led_brightness_set(struct led_classdev *led_dev,
+ enum led_brightness brightness)
+{
+ struct p54_led_dev *led = container_of(led_dev, struct p54_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);
+}
+
+static int p54_register_led(struct ieee80211_hw *dev,
+ struct p54_led_dev *led,
+ unsigned int led_index,
+ char *name, char *trigger)
+{
+ int err;
+
+ if (led->registered)
+ return -EEXIST;
+
+ snprintf(led->name, sizeof(led->name), "p54-%s::%s",
+ wiphy_name(dev->wiphy), name);
+ led->hw_dev = dev;
+ led->index = led_index;
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = trigger;
+ led->led_dev.brightness_set = p54_led_brightness_set;
+
+ err = led_classdev_register(wiphy_dev(dev->wiphy), &led->led_dev);
+ if (err)
+ printk(KERN_ERR "%s: Failed to register %s LED.\n",
+ wiphy_name(dev->wiphy), name);
+ else
+ led->registered = 1;
+
+ return err;
+}
+
+static int p54_init_leds(struct ieee80211_hw *dev)
+{
+ struct p54_common *priv = dev->priv;
+ int err;
+
+ /*
+ * 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",
+ ieee80211_get_assoc_led_name(dev));
+ if (err)
+ return err;
+
+ err = p54_register_led(dev, &priv->tx_led, 1, "tx",
+ ieee80211_get_tx_led_name(dev));
+ if (err)
+ return err;
+
+ err = p54_set_leds(dev);
+ return err;
+}
+
+static void p54_unregister_leds(struct ieee80211_hw *dev)
+{
+ struct p54_common *priv = dev->priv;
+
+ 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);
+}
+#endif /* CONFIG_MAC80211_LEDS */
+
static const struct ieee80211_ops p54_ops = {
.tx = p54_tx,
.start = p54_start,
@@ -2158,6 +2543,8 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
priv->basic_rate_mask = 0x15f;
skb_queue_head_init(&priv->tx_queue);
dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM;
@@ -2167,11 +2554,11 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
BIT(NL80211_IFTYPE_MESH_POINT);
dev->channel_change_time = 1000; /* TODO: find actual value */
- priv->tx_stats[0].limit = 1; /* Beacon queue */
- priv->tx_stats[1].limit = 1; /* Probe queue for HW scan */
- priv->tx_stats[2].limit = 3; /* queue for MLMEs */
- priv->tx_stats[3].limit = 3; /* Broadcast / MC queue */
- priv->tx_stats[4].limit = 5; /* Data */
+ priv->tx_stats[P54_QUEUE_BEACON].limit = 1;
+ priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1;
+ priv->tx_stats[P54_QUEUE_MGMT].limit = 3;
+ priv->tx_stats[P54_QUEUE_CAB].limit = 3;
+ priv->tx_stats[P54_QUEUE_DATA].limit = 5;
dev->queues = 1;
priv->noise = -94;
/*
@@ -2195,12 +2582,37 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
}
EXPORT_SYMBOL_GPL(p54_init_common);
+int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
+{
+ int err;
+
+ err = ieee80211_register_hw(dev);
+ if (err) {
+ dev_err(pdev, "Cannot register device (%d).\n", err);
+ return err;
+ }
+
+ #ifdef CONFIG_MAC80211_LEDS
+ err = p54_init_leds(dev);
+ if (err)
+ return err;
+ #endif /* CONFIG_MAC80211_LEDS */
+
+ dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
+ return 0;
+}
+EXPORT_SYMBOL_GPL(p54_register_common);
+
void p54_free_common(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
kfree(priv->iq_autocal);
kfree(priv->output_limit);
kfree(priv->curve_data);
+
+ #ifdef CONFIG_MAC80211_LEDS
+ p54_unregister_leds(dev);
+ #endif /* CONFIG_MAC80211_LEDS */
}
EXPORT_SYMBOL_GPL(p54_free_common);
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index f5729de83fe..75ead7a150f 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -26,12 +26,17 @@ struct bootrec {
} __attribute__((packed));
#define PDR_SYNTH_FRONTEND_MASK 0x0007
+#define PDR_SYNTH_FRONTEND_DUETTE3 0x0001
+#define PDR_SYNTH_FRONTEND_DUETTE2 0x0002
+#define PDR_SYNTH_FRONTEND_FRISBEE 0x0003
+#define PDR_SYNTH_FRONTEND_XBOW 0x0004
+#define PDR_SYNTH_FRONTEND_LONGBOW 0x0005
#define PDR_SYNTH_IQ_CAL_MASK 0x0018
#define PDR_SYNTH_IQ_CAL_PA_DETECTOR 0x0000
#define PDR_SYNTH_IQ_CAL_DISABLED 0x0008
#define PDR_SYNTH_IQ_CAL_ZIF 0x0010
#define PDR_SYNTH_FAA_SWITCH_MASK 0x0020
-#define PDR_SYNTH_FAA_SWITCH_ENABLED 0x0001
+#define PDR_SYNTH_FAA_SWITCH_ENABLED 0x0020
#define PDR_SYNTH_24_GHZ_MASK 0x0040
#define PDR_SYNTH_24_GHZ_DISABLED 0x0040
#define PDR_SYNTH_5_GHZ_MASK 0x0080
@@ -125,9 +130,13 @@ struct eeprom_pda_wrap {
u8 data[0];
} __attribute__ ((packed));
+struct p54_iq_autocal_entry {
+ __le16 iq_param[4];
+} __attribute__ ((packed));
+
struct pda_iq_autocal_entry {
__le16 freq;
- __le16 iq_param[4];
+ struct p54_iq_autocal_entry params;
} __attribute__ ((packed));
struct pda_channel_output_limit {
@@ -180,6 +189,35 @@ struct pda_rssi_cal_entry {
__le16 add;
} __attribute__ ((packed));
+struct pda_country {
+ u8 regdomain;
+ u8 alpha2[2];
+ u8 flags;
+} __attribute__ ((packed));
+
+/*
+ * Warning: Longbow's structures are bogus.
+ */
+struct p54_channel_output_limit_longbow {
+ __le16 rf_power_points[12];
+} __attribute__ ((packed));
+
+struct p54_pa_curve_data_sample_longbow {
+ __le16 rf_power;
+ __le16 pa_detector;
+ struct {
+ __le16 data[4];
+ } points[3] __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct pda_custom_wrapper {
+ __le16 entries;
+ __le16 entry_size;
+ __le16 offset;
+ __le16 len;
+ u8 data[0];
+} __attribute__ ((packed));
+
/*
* this defines the PDR codes used to build PDAs as defined in document
* number 553155. The current implementation mirrors version 1.1 of the
@@ -225,8 +263,13 @@ struct pda_rssi_cal_entry {
/* reserved range (0x2000 - 0x7fff) */
/* customer range (0x8000 - 0xffff) */
-#define PDR_BASEBAND_REGISTERS 0x8000
-#define PDR_PER_CHANNEL_BASEBAND_REGISTERS 0x8001
+#define PDR_BASEBAND_REGISTERS 0x8000
+#define PDR_PER_CHANNEL_BASEBAND_REGISTERS 0x8001
+
+/* used by our modificated eeprom image */
+#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD
+#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF
+#define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D
/* PDR definitions for default country & country list */
#define PDR_COUNTRY_CERT_CODE 0x80
@@ -241,12 +284,6 @@ struct pda_rssi_cal_entry {
#define PDR_COUNTRY_CERT_IODOOR_OUTDOOR 0x30
#define PDR_COUNTRY_CERT_INDEX 0x0F
-/* stored in skb->cb */
-struct memrecord {
- u32 start_addr;
- u32 end_addr;
-};
-
struct p54_eeprom_lm86 {
union {
struct {
@@ -329,7 +366,7 @@ struct p54_frame_sent {
u8 padding;
} __attribute__ ((packed));
-enum p54_tx_data_crypt {
+enum p54_tx_data_crypt {
P54_CRYPTO_NONE = 0,
P54_CRYPTO_WEP,
P54_CRYPTO_TKIP,
@@ -340,6 +377,23 @@ enum p54_tx_data_crypt {
P54_CRYPTO_AESCCMP
};
+enum p54_tx_data_queue {
+ P54_QUEUE_BEACON = 0,
+ P54_QUEUE_FWSCAN = 1,
+ P54_QUEUE_MGMT = 2,
+ P54_QUEUE_CAB = 3,
+ P54_QUEUE_DATA = 4,
+
+ P54_QUEUE_AC_NUM = 4,
+ P54_QUEUE_AC_VO = 4,
+ P54_QUEUE_AC_VI = 5,
+ P54_QUEUE_AC_BE = 6,
+ P54_QUEUE_AC_BK = 7,
+
+ /* keep last */
+ P54_QUEUE_NUM = 8,
+};
+
struct p54_tx_data {
u8 rateset[8];
u8 rts_rate_idx;
@@ -351,9 +405,18 @@ struct p54_tx_data {
u8 backlog;
__le16 durations[4];
u8 tx_antenna;
- u8 output_power;
- u8 cts_rate;
- u8 unalloc2[3];
+ union {
+ struct {
+ u8 cts_rate;
+ __le16 output_power;
+ } __attribute__((packed)) longbow;
+ struct {
+ u8 output_power;
+ u8 cts_rate;
+ u8 unalloc;
+ } __attribute__ ((packed)) normal;
+ } __attribute__ ((packed));
+ u8 unalloc2[2];
u8 align[0];
} __attribute__ ((packed));
@@ -414,11 +477,14 @@ struct p54_setup_mac {
#define P54_SCAN_ACTIVE BIT(2)
#define P54_SCAN_FILTER BIT(3)
-struct p54_scan {
+struct p54_scan_head {
__le16 mode;
__le16 dwell;
- u8 padding1[20];
- struct pda_iq_autocal_entry iq_autocal;
+ u8 scan_params[20];
+ __le16 freq;
+} __attribute__ ((packed));
+
+struct p54_scan_body {
u8 pa_points_per_curve;
u8 val_barker;
u8 val_bpsk;
@@ -430,25 +496,28 @@ struct p54_scan {
u8 dup_qpsk;
u8 dup_16qam;
u8 dup_64qam;
- union {
- struct pda_rssi_cal_entry v1_rssi;
+} __attribute__ ((packed));
- struct {
- __le32 basic_rate_mask;
- u8 rts_rates[8];
- struct pda_rssi_cal_entry rssi;
- } v2 __attribute__ ((packed));
- } __attribute__ ((packed));
+struct p54_scan_body_longbow {
+ struct p54_channel_output_limit_longbow power_limits;
+ struct p54_pa_curve_data_sample_longbow curve_data[8];
+ __le16 unkn[6]; /* maybe more power_limits or rate_mask */
} __attribute__ ((packed));
-#define P54_SCAN_V1_LEN 0x70
-#define P54_SCAN_V2_LEN 0x7c
+union p54_scan_body_union {
+ struct p54_scan_body normal;
+ struct p54_scan_body_longbow longbow;
+} __attribute__ ((packed));
+
+struct p54_scan_tail_rate {
+ __le32 basic_rate_mask;
+ u8 rts_rates[8];
+} __attribute__ ((packed));
struct p54_led {
- __le16 mode;
- __le16 led_temporary;
- __le16 led_permanent;
- __le16 duration;
+ __le16 flags;
+ __le16 mask[2];
+ __le16 delay[2];
} __attribute__ ((packed));
struct p54_edcf {
@@ -511,6 +580,7 @@ struct p54_psm_interval {
__le16 periods;
} __attribute__ ((packed));
+#define P54_PSM_CAM 0
#define P54_PSM BIT(0)
#define P54_PSM_DTIM BIT(1)
#define P54_PSM_MCBC BIT(2)
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index aa367a0ddc4..e3569a0a952 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -79,6 +79,12 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
if (err)
return err;
+ if (priv->common.fw_interface != FW_LM86) {
+ dev_err(&priv->pdev->dev, "wrong firmware, "
+ "please get a LM86(PCI) firmware a try again.\n");
+ return -EINVAL;
+ }
+
data = (__le32 *) priv->firmware->data;
remains = priv->firmware->size;
device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
@@ -407,8 +413,7 @@ static int p54p_open(struct ieee80211_hw *dev)
err = request_irq(priv->pdev->irq, &p54p_interrupt,
IRQF_SHARED, "p54pci", dev);
if (err) {
- printk(KERN_ERR "%s: failed to register IRQ handler\n",
- wiphy_name(dev->wiphy));
+ dev_err(&priv->pdev->dev, "failed to register IRQ handler\n");
return err;
}
@@ -470,30 +475,26 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
err = pci_enable_device(pdev);
if (err) {
- printk(KERN_ERR "%s (p54pci): Cannot enable new PCI device\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Cannot enable new PCI device\n");
return err;
}
mem_addr = pci_resource_start(pdev, 0);
mem_len = pci_resource_len(pdev, 0);
if (mem_len < sizeof(struct p54p_csr)) {
- printk(KERN_ERR "%s (p54pci): Too short PCI resources\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Too short PCI resources\n");
goto err_disable_dev;
}
err = pci_request_regions(pdev, "p54pci");
if (err) {
- printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Cannot obtain PCI resources\n");
goto err_disable_dev;
}
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
- printk(KERN_ERR "%s (p54pci): No suitable DMA available\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "No suitable DMA available\n");
goto err_free_reg;
}
@@ -505,8 +506,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
dev = p54_init_common(sizeof(*priv));
if (!dev) {
- printk(KERN_ERR "%s (p54pci): ieee80211 alloc failed\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "ieee80211 alloc failed\n");
err = -ENOMEM;
goto err_free_reg;
}
@@ -519,17 +519,15 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
priv->map = ioremap(mem_addr, mem_len);
if (!priv->map) {
- printk(KERN_ERR "%s (p54pci): Cannot map device memory\n",
- pci_name(pdev));
- err = -EINVAL; // TODO: use a better error code?
+ dev_err(&pdev->dev, "Cannot map device memory\n");
+ err = -ENOMEM;
goto err_free_dev;
}
priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
&priv->ring_control_dma);
if (!priv->ring_control) {
- printk(KERN_ERR "%s (p54pci): Cannot allocate rings\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Cannot allocate rings\n");
err = -ENOMEM;
goto err_iounmap;
}
@@ -543,8 +541,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
err = request_firmware(&priv->firmware, "isl3886pci",
&priv->pdev->dev);
if (err) {
- printk(KERN_ERR "%s (p54pci): cannot find firmware "
- "(isl3886pci)\n", pci_name(priv->pdev));
+ dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
err = request_firmware(&priv->firmware, "isl3886",
&priv->pdev->dev);
if (err)
@@ -559,12 +556,9 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
if (err)
goto err_free_common;
- err = ieee80211_register_hw(dev);
- if (err) {
- printk(KERN_ERR "%s (p54pci): Cannot register netdevice\n",
- pci_name(pdev));
+ err = p54_register_common(dev, &pdev->dev);
+ if (err)
goto err_free_common;
- }
return 0;
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
new file mode 100644
index 00000000000..2b222aaa6f0
--- /dev/null
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -0,0 +1,765 @@
+/*
+ * Copyright (C) 2008 Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This driver is a port from stlc45xx:
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio.h>
+
+#include "p54spi.h"
+#include "p54spi_eeprom.h"
+#include "p54.h"
+
+#include "p54common.h"
+
+MODULE_FIRMWARE("3826.arm");
+MODULE_ALIAS("stlc45xx");
+
+/*
+ * gpios should be handled in board files and provided via platform data,
+ * but because it's currently impossible for p54spi to have a header file
+ * in include/linux, let's use module paramaters for now
+ */
+
+static int p54spi_gpio_power = 97;
+module_param(p54spi_gpio_power, int, 0444);
+MODULE_PARM_DESC(p54spi_gpio_power, "gpio number for power line");
+
+static int p54spi_gpio_irq = 87;
+module_param(p54spi_gpio_irq, int, 0444);
+MODULE_PARM_DESC(p54spi_gpio_irq, "gpio number for irq line");
+
+static void p54spi_spi_read(struct p54s_priv *priv, u8 address,
+ void *buf, size_t len)
+{
+ struct spi_transfer t[2];
+ struct spi_message m;
+ __le16 addr;
+
+ /* We first push the address */
+ addr = cpu_to_le16(address << 8 | SPI_ADRS_READ_BIT_15);
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &addr;
+ t[0].len = sizeof(addr);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].rx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ spi_sync(priv->spi, &m);
+}
+
+
+static void p54spi_spi_write(struct p54s_priv *priv, u8 address,
+ const void *buf, size_t len)
+{
+ struct spi_transfer t[3];
+ struct spi_message m;
+ __le16 addr;
+
+ /* We first push the address */
+ addr = cpu_to_le16(address << 8);
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &addr;
+ t[0].len = sizeof(addr);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ if (len % 2) {
+ __le16 last_word;
+ last_word = cpu_to_le16(((u8 *)buf)[len - 1]);
+
+ t[2].tx_buf = &last_word;
+ t[2].len = sizeof(last_word);
+ spi_message_add_tail(&t[2], &m);
+ }
+
+ spi_sync(priv->spi, &m);
+}
+
+static u16 p54spi_read16(struct p54s_priv *priv, u8 addr)
+{
+ __le16 val;
+
+ p54spi_spi_read(priv, addr, &val, sizeof(val));
+
+ return le16_to_cpu(val);
+}
+
+static u32 p54spi_read32(struct p54s_priv *priv, u8 addr)
+{
+ __le32 val;
+
+ p54spi_spi_read(priv, addr, &val, sizeof(val));
+
+ return le32_to_cpu(val);
+}
+
+static inline void p54spi_write16(struct p54s_priv *priv, u8 addr, __le16 val)
+{
+ p54spi_spi_write(priv, addr, &val, sizeof(val));
+}
+
+static inline void p54spi_write32(struct p54s_priv *priv, u8 addr, __le32 val)
+{
+ p54spi_spi_write(priv, addr, &val, sizeof(val));
+}
+
+struct p54spi_spi_reg {
+ u16 address; /* __le16 ? */
+ u16 length;
+ char *name;
+};
+
+static const struct p54spi_spi_reg p54spi_registers_array[] =
+{
+ { SPI_ADRS_ARM_INTERRUPTS, 32, "ARM_INT " },
+ { SPI_ADRS_ARM_INT_EN, 32, "ARM_INT_ENA " },
+ { SPI_ADRS_HOST_INTERRUPTS, 32, "HOST_INT " },
+ { SPI_ADRS_HOST_INT_EN, 32, "HOST_INT_ENA" },
+ { SPI_ADRS_HOST_INT_ACK, 32, "HOST_INT_ACK" },
+ { SPI_ADRS_GEN_PURP_1, 32, "GP1_COMM " },
+ { SPI_ADRS_GEN_PURP_2, 32, "GP2_COMM " },
+ { SPI_ADRS_DEV_CTRL_STAT, 32, "DEV_CTRL_STA" },
+ { SPI_ADRS_DMA_DATA, 16, "DMA_DATA " },
+ { SPI_ADRS_DMA_WRITE_CTRL, 16, "DMA_WR_CTRL " },
+ { SPI_ADRS_DMA_WRITE_LEN, 16, "DMA_WR_LEN " },
+ { SPI_ADRS_DMA_WRITE_BASE, 32, "DMA_WR_BASE " },
+ { SPI_ADRS_DMA_READ_CTRL, 16, "DMA_RD_CTRL " },
+ { SPI_ADRS_DMA_READ_LEN, 16, "DMA_RD_LEN " },
+ { SPI_ADRS_DMA_WRITE_BASE, 32, "DMA_RD_BASE " }
+};
+
+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)
+ return 1;
+
+ msleep(1);
+ }
+ return 0;
+}
+
+static int p54spi_request_firmware(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+ int ret;
+
+ /* FIXME: should driver use it's own struct device? */
+ ret = request_firmware(&priv->firmware, "3826.arm", &priv->spi->dev);
+
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "request_firmware() failed: %d", ret);
+ return ret;
+ }
+
+ ret = p54_parse_firmware(dev, priv->firmware);
+ if (ret) {
+ release_firmware(priv->firmware);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int p54spi_request_eeprom(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+ const struct firmware *eeprom;
+ int ret;
+
+ /*
+ * allow users to customize their eeprom.
+ */
+
+ ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
+ if (ret < 0) {
+ dev_info(&priv->spi->dev, "loading default eeprom...\n");
+ ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom,
+ sizeof(p54spi_eeprom));
+ } else {
+ dev_info(&priv->spi->dev, "loading user eeprom...\n");
+ ret = p54_parse_eeprom(dev, (void *) eeprom->data,
+ (int)eeprom->size);
+ release_firmware(eeprom);
+ }
+ return ret;
+}
+
+static int p54spi_upload_firmware(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+ unsigned long fw_len, fw_addr;
+ long _fw_len;
+
+ /* stop the device */
+ p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET |
+ SPI_CTRL_STAT_START_HALTED));
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+ SPI_CTRL_STAT_HOST_OVERRIDE |
+ SPI_CTRL_STAT_START_HALTED));
+
+ 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);
+
+ 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! */
+ }
+
+ BUG_ON(fw_len != 0);
+
+ /* enable host interrupts */
+ p54spi_write32(priv, SPI_ADRS_HOST_INT_EN,
+ cpu_to_le32(SPI_HOST_INTS_DEFAULT));
+
+ /* boot the device */
+ p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET |
+ SPI_CTRL_STAT_RAM_BOOT));
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ 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;
+}
+
+static void p54spi_power_off(struct p54s_priv *priv)
+{
+ disable_irq(gpio_to_irq(p54spi_gpio_irq));
+ gpio_set_value(p54spi_gpio_power, 0);
+}
+
+static void p54spi_power_on(struct p54s_priv *priv)
+{
+ gpio_set_value(p54spi_gpio_power, 1);
+ enable_irq(gpio_to_irq(p54spi_gpio_irq));
+
+ /*
+ * need to wait a while before device can be accessed, the lenght
+ * is just a guess
+ */
+ msleep(10);
+}
+
+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)
+{
+ 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);
+ }
+
+ p54spi_int_ack(priv, SPI_HOST_INT_READY);
+
+out:
+ return;
+}
+
+static inline void p54spi_sleep(struct p54s_priv *priv)
+{
+ p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS,
+ cpu_to_le32(SPI_TARGET_INT_SLEEP));
+}
+
+static void p54spi_int_ready(struct p54s_priv *priv)
+{
+ p54spi_write32(priv, SPI_ADRS_HOST_INT_EN, cpu_to_le32(
+ SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE));
+
+ switch (priv->fw_state) {
+ case FW_STATE_BOOTING:
+ priv->fw_state = FW_STATE_READY;
+ complete(&priv->fw_comp);
+ break;
+ case FW_STATE_RESETTING:
+ priv->fw_state = FW_STATE_READY;
+ /* TODO: reinitialize state */
+ break;
+ default:
+ break;
+ }
+}
+
+static int p54spi_rx(struct p54s_priv *priv)
+{
+ struct sk_buff *skb;
+ u16 len;
+
+ p54spi_wakeup(priv);
+
+ /* dummy read to flush SPI DMA controller bug */
+ p54spi_read16(priv, SPI_ADRS_GEN_PURP_1);
+
+ len = p54spi_read16(priv, SPI_ADRS_DMA_DATA);
+
+ if (len == 0) {
+ dev_err(&priv->spi->dev, "rx request of zero bytes");
+ return 0;
+ }
+
+ skb = dev_alloc_skb(len);
+ if (!skb) {
+ dev_err(&priv->spi->dev, "could not alloc skb");
+ return 0;
+ }
+
+ p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
+ p54spi_sleep(priv);
+
+ if (p54_rx(priv->hw, skb) == 0)
+ dev_kfree_skb(skb);
+
+ return 0;
+}
+
+
+static irqreturn_t p54spi_interrupt(int irq, void *config)
+{
+ struct spi_device *spi = config;
+ struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
+
+ queue_work(priv->hw->workqueue, &priv->work);
+
+ return IRQ_HANDLED;
+}
+
+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;
+
+ 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);
+
+ 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);
+ }
+
+ p54spi_int_ack(priv, SPI_HOST_INT_WR_READY);
+ p54spi_sleep(priv);
+
+out:
+ if (FREE_AFTER_TX(skb))
+ p54_free_skb(priv->hw, skb);
+ return ret;
+}
+
+static int p54spi_wq_tx(struct p54s_priv *priv)
+{
+ struct p54s_tx_info *entry;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ struct p54_tx_info *minfo;
+ struct p54s_tx_info *dinfo;
+ int ret = 0;
+
+ spin_lock_bh(&priv->tx_lock);
+
+ while (!list_empty(&priv->tx_pending)) {
+ entry = list_entry(priv->tx_pending.next,
+ struct p54s_tx_info, tx_list);
+
+ list_del_init(&entry->tx_list);
+
+ spin_unlock_bh(&priv->tx_lock);
+
+ dinfo = container_of((void *) entry, struct p54s_tx_info,
+ tx_list);
+ minfo = container_of((void *) dinfo, struct p54_tx_info,
+ data);
+ info = container_of((void *) minfo, struct ieee80211_tx_info,
+ rate_driver_data);
+ skb = container_of((void *) info, struct sk_buff, cb);
+
+ ret = p54spi_tx_frame(priv, skb);
+
+ spin_lock_bh(&priv->tx_lock);
+
+ if (ret < 0) {
+ p54_free_skb(priv->hw, skb);
+ goto out;
+ }
+ }
+
+out:
+ spin_unlock_bh(&priv->tx_lock);
+ return ret;
+}
+
+static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+ struct p54s_priv *priv = dev->priv;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data;
+ struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data;
+
+ BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data)));
+
+ spin_lock_bh(&priv->tx_lock);
+ list_add_tail(&di->tx_list, &priv->tx_pending);
+ spin_unlock_bh(&priv->tx_lock);
+
+ queue_work(priv->hw->workqueue, &priv->work);
+}
+
+static void p54spi_work(struct work_struct *work)
+{
+ struct p54s_priv *priv = container_of(work, struct p54s_priv, work);
+ u32 ints;
+ int ret;
+
+ mutex_lock(&priv->mutex);
+
+ if (priv->fw_state == FW_STATE_OFF &&
+ priv->fw_state == FW_STATE_RESET)
+ goto out;
+
+ ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+
+ if (ints & SPI_HOST_INT_READY) {
+ p54spi_int_ready(priv);
+ p54spi_int_ack(priv, SPI_HOST_INT_READY);
+ }
+
+ if (priv->fw_state != FW_STATE_READY)
+ goto out;
+
+ if (ints & SPI_HOST_INT_UPDATE) {
+ p54spi_int_ack(priv, SPI_HOST_INT_UPDATE);
+ ret = p54spi_rx(priv);
+ if (ret < 0)
+ goto out;
+ }
+ if (ints & SPI_HOST_INT_SW_UPDATE) {
+ p54spi_int_ack(priv, SPI_HOST_INT_SW_UPDATE);
+ ret = p54spi_rx(priv);
+ if (ret < 0)
+ goto out;
+ }
+
+ ret = p54spi_wq_tx(priv);
+ if (ret < 0)
+ goto out;
+
+ ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+
+out:
+ mutex_unlock(&priv->mutex);
+}
+
+static int p54spi_op_start(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+ unsigned long timeout;
+ int ret = 0;
+
+ if (mutex_lock_interruptible(&priv->mutex)) {
+ ret = -EINTR;
+ goto out;
+ }
+
+ priv->fw_state = FW_STATE_BOOTING;
+
+ p54spi_power_on(priv);
+
+ ret = p54spi_upload_firmware(dev);
+ if (ret < 0) {
+ p54spi_power_off(priv);
+ goto out_unlock;
+ }
+
+ mutex_unlock(&priv->mutex);
+
+ timeout = msecs_to_jiffies(2000);
+ timeout = wait_for_completion_interruptible_timeout(&priv->fw_comp,
+ timeout);
+ if (!timeout) {
+ dev_err(&priv->spi->dev, "firmware boot failed");
+ p54spi_power_off(priv);
+ ret = -1;
+ goto out;
+ }
+
+ if (mutex_lock_interruptible(&priv->mutex)) {
+ ret = -EINTR;
+ p54spi_power_off(priv);
+ goto out;
+ }
+
+ WARN_ON(priv->fw_state != FW_STATE_READY);
+
+out_unlock:
+ mutex_unlock(&priv->mutex);
+
+out:
+ return ret;
+}
+
+static void p54spi_op_stop(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+
+ if (mutex_lock_interruptible(&priv->mutex)) {
+ /* FIXME: how to handle this error? */
+ return;
+ }
+
+ WARN_ON(priv->fw_state != FW_STATE_READY);
+
+ cancel_work_sync(&priv->work);
+
+ p54spi_power_off(priv);
+ spin_lock_bh(&priv->tx_lock);
+ INIT_LIST_HEAD(&priv->tx_pending);
+ spin_unlock_bh(&priv->tx_lock);
+
+ priv->fw_state = FW_STATE_OFF;
+ mutex_unlock(&priv->mutex);
+}
+
+static int __devinit p54spi_probe(struct spi_device *spi)
+{
+ struct p54s_priv *priv = NULL;
+ struct ieee80211_hw *hw;
+ int ret = -EINVAL;
+
+ hw = p54_init_common(sizeof(*priv));
+ if (!hw) {
+ dev_err(&priv->spi->dev, "could not alloc ieee80211_hw");
+ return -ENOMEM;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+ dev_set_drvdata(&spi->dev, priv);
+ priv->spi = spi;
+
+ spi->bits_per_word = 16;
+ spi->max_speed_hz = 24000000;
+
+ ret = spi_setup(spi);
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "spi_setup failed");
+ goto err_free_common;
+ }
+
+ ret = gpio_request(p54spi_gpio_power, "p54spi power");
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
+ goto err_free_common;
+ }
+
+ ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
+ goto err_free_common;
+ }
+
+ gpio_direction_output(p54spi_gpio_power, 0);
+ gpio_direction_input(p54spi_gpio_irq);
+
+ ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
+ p54spi_interrupt, IRQF_DISABLED, "p54spi",
+ priv->spi);
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "request_irq() failed");
+ goto err_free_common;
+ }
+
+ set_irq_type(gpio_to_irq(p54spi_gpio_irq),
+ IRQ_TYPE_EDGE_RISING);
+
+ disable_irq(gpio_to_irq(p54spi_gpio_irq));
+
+ INIT_WORK(&priv->work, p54spi_work);
+ init_completion(&priv->fw_comp);
+ INIT_LIST_HEAD(&priv->tx_pending);
+ mutex_init(&priv->mutex);
+ SET_IEEE80211_DEV(hw, &spi->dev);
+ priv->common.open = p54spi_op_start;
+ priv->common.stop = p54spi_op_stop;
+ priv->common.tx = p54spi_op_tx;
+
+ ret = p54spi_request_firmware(hw);
+ if (ret < 0)
+ goto err_free_common;
+
+ ret = p54spi_request_eeprom(hw);
+ if (ret)
+ goto err_free_common;
+
+ ret = p54_register_common(hw, &priv->spi->dev);
+ if (ret)
+ goto err_free_common;
+
+ return 0;
+
+err_free_common:
+ p54_free_common(priv->hw);
+ return ret;
+}
+
+static int __devexit p54spi_remove(struct spi_device *spi)
+{
+ struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
+
+ ieee80211_unregister_hw(priv->hw);
+
+ free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
+
+ gpio_free(p54spi_gpio_power);
+ gpio_free(p54spi_gpio_irq);
+ release_firmware(priv->firmware);
+
+ mutex_destroy(&priv->mutex);
+
+ p54_free_common(priv->hw);
+ ieee80211_free_hw(priv->hw);
+
+ return 0;
+}
+
+
+static struct spi_driver p54spi_driver = {
+ .driver = {
+ /* use cx3110x name because board-n800.c uses that for the
+ * SPI port */
+ .name = "cx3110x",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = p54spi_probe,
+ .remove = __devexit_p(p54spi_remove),
+};
+
+static int __init p54spi_init(void)
+{
+ int ret;
+
+ ret = spi_register_driver(&p54spi_driver);
+ if (ret < 0) {
+ printk(KERN_ERR "failed to register SPI driver: %d", ret);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit p54spi_exit(void)
+{
+ spi_unregister_driver(&p54spi_driver);
+}
+
+module_init(p54spi_init);
+module_exit(p54spi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
diff --git a/drivers/net/wireless/p54/p54spi.h b/drivers/net/wireless/p54/p54spi.h
new file mode 100644
index 00000000000..7fbe8d8fc67
--- /dev/null
+++ b/drivers/net/wireless/p54/p54spi.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 Christian Lamparter <chunkeey@web.de>
+ *
+ * This driver is a port from stlc45xx:
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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 P54SPI_H
+#define P54SPI_H
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <net/mac80211.h>
+
+#include "p54.h"
+
+/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */
+#define SPI_ADRS_READ_BIT_15 0x8000
+
+#define SPI_ADRS_ARM_INTERRUPTS 0x00
+#define SPI_ADRS_ARM_INT_EN 0x04
+
+#define SPI_ADRS_HOST_INTERRUPTS 0x08
+#define SPI_ADRS_HOST_INT_EN 0x0c
+#define SPI_ADRS_HOST_INT_ACK 0x10
+
+#define SPI_ADRS_GEN_PURP_1 0x14
+#define SPI_ADRS_GEN_PURP_2 0x18
+
+#define SPI_ADRS_DEV_CTRL_STAT 0x26 /* high word */
+
+#define SPI_ADRS_DMA_DATA 0x28
+
+#define SPI_ADRS_DMA_WRITE_CTRL 0x2c
+#define SPI_ADRS_DMA_WRITE_LEN 0x2e
+#define SPI_ADRS_DMA_WRITE_BASE 0x30
+
+#define SPI_ADRS_DMA_READ_CTRL 0x34
+#define SPI_ADRS_DMA_READ_LEN 0x36
+#define SPI_ADRS_DMA_READ_BASE 0x38
+
+#define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000
+#define SPI_CTRL_STAT_START_HALTED 0x4000
+#define SPI_CTRL_STAT_RAM_BOOT 0x2000
+#define SPI_CTRL_STAT_HOST_RESET 0x1000
+#define SPI_CTRL_STAT_HOST_CPU_EN 0x0800
+
+#define SPI_DMA_WRITE_CTRL_ENABLE 0x0001
+#define SPI_DMA_READ_CTRL_ENABLE 0x0001
+#define HOST_ALLOWED (1 << 7)
+
+#define SPI_TIMEOUT 100 /* msec */
+
+#define SPI_MAX_TX_PACKETS 32
+
+#define SPI_MAX_PACKET_SIZE 32767
+
+#define SPI_TARGET_INT_WAKEUP 0x00000001
+#define SPI_TARGET_INT_SLEEP 0x00000002
+#define SPI_TARGET_INT_RDDONE 0x00000004
+
+#define SPI_TARGET_INT_CTS 0x00004000
+#define SPI_TARGET_INT_DR 0x00008000
+
+#define SPI_HOST_INT_READY 0x00000001
+#define SPI_HOST_INT_WR_READY 0x00000002
+#define SPI_HOST_INT_SW_UPDATE 0x00000004
+#define SPI_HOST_INT_UPDATE 0x10000000
+
+/* clear to send */
+#define SPI_HOST_INT_CR 0x00004000
+
+/* data ready */
+#define SPI_HOST_INT_DR 0x00008000
+
+#define SPI_HOST_INTS_DEFAULT \
+ (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)
+
+#define TARGET_BOOT_SLEEP 50
+
+struct p54s_dma_regs {
+ __le16 cmd;
+ __le16 len;
+ __le32 addr;
+} __attribute__ ((packed));
+
+struct p54s_tx_info {
+ struct list_head tx_list;
+};
+
+struct p54s_priv {
+ /* p54_common has to be the first entry */
+ struct p54_common common;
+ struct ieee80211_hw *hw;
+ struct spi_device *spi;
+
+ struct work_struct work;
+
+ struct mutex mutex;
+ struct completion fw_comp;
+
+ spinlock_t tx_lock;
+
+ /* protected by tx_lock */
+ struct list_head tx_pending;
+
+ enum fw_state fw_state;
+ const struct firmware *firmware;
+};
+
+#endif /* P54SPI_H */
diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h
new file mode 100644
index 00000000000..1ea1050911d
--- /dev/null
+++ b/drivers/net/wireless/p54/p54spi_eeprom.h
@@ -0,0 +1,678 @@
+/*
+ * Copyright (C) 2003 Conexant Americas Inc. All Rights Reserved.
+ * Copyright (C) 2004, 2005, 2006 Nokia Corporation
+ * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2008 Christian Lamparter <chunkeey@web.de>
+ *
+ * based on:
+ * - cx3110x's pda.h from Nokia
+ * - cx3110-transfer.log by Johannes Berg
+ *
+ * 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 P54SPI_EEPROM_H
+#define P54SPI_EEPROM_H
+
+static unsigned char p54spi_eeprom[] = {
+
+/* struct eeprom_pda_wrap */
+0x47, 0x4d, 0x55, 0xaa, /* magic */
+0x00, 0x00, /* pad */
+0x00, 0x00, /* eeprom_pda_data_wrap length */
+0x00, 0x00, 0x00, 0x00, /* arm opcode */
+
+/* bogus MAC address */
+0x04, 0x00, 0x01, 0x01, /* PDR_MAC_ADDRESS */
+ 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee,
+
+/* struct bootrec_exp_if */
+0x06, 0x00, 0x01, 0x10, /* PDR_INTERFACE_LIST */
+ 0x00, 0x00, /* role */
+ 0x0f, 0x00, /* if_id */
+ 0x85, 0x00, /* variant = Longbow RF, 2GHz */
+ 0x01, 0x00, /* btm_compat */
+ 0x1f, 0x00, /* top_compat */
+
+0x03, 0x00, 0x02, 0x10, /* PDR_HARDWARE_PLATFORM_COMPONENT_ID */
+ 0x03, 0x20, 0x00, 0x43,
+
+/* struct pda_country[6] */
+0x0d, 0x00, 0x07, 0x10, /* PDR_COUNTRY_LIST */
+ 0x10, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00,
+ 0x31, 0x00, 0x00, 0x00,
+ 0x32, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00,
+
+/* struct pda_country */
+0x03, 0x00, 0x08, 0x10, /* PDR_DEFAULT_COUNTRY */
+ 0x30, 0x00, 0x00, 0x00, /* ETSI */
+
+0x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */
+ 0x08, 0x08, 0x08, 0x08,
+
+0x09, 0x00, 0xad, 0xde, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */
+ 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+/* struct pda_custom_wrapper */
+0x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */
+ 0x0d, 0x00, 0xee, 0x00, /* 13 entries, 238 bytes per entry */
+ 0x00, 0x00, 0x16, 0x0c, /* no offset, 3094 total len */
+ /* 2412 MHz */
+ 0x6c, 0x09,
+ 0x10, 0x01, 0x9a, 0x84,
+ 0xaa, 0x8a, 0xaa, 0x8a, 0xaa, 0x8a, 0xaa, 0x8a,
+ 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6,
+ 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6,
+ 0xf0, 0x00, 0x94, 0x6c,
+ 0x99, 0x82, 0x99, 0x82, 0x99, 0x82, 0x99, 0x82,
+ 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae,
+ 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae,
+ 0xd0, 0x00, 0xaa, 0x5a,
+ 0x88, 0x7a, 0x88, 0x7a, 0x88, 0x7a, 0x88, 0x7a,
+ 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6,
+ 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6,
+ 0xa0, 0x00, 0xf3, 0x47,
+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+ 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a,
+ 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a,
+ 0x50, 0x00, 0x59, 0x36,
+ 0x43, 0x5a, 0x43, 0x5a, 0x43, 0x5a, 0x43, 0x5a,
+ 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85,
+ 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85,
+ 0x00, 0x00, 0xe4, 0x2d,
+ 0x18, 0x46, 0x18, 0x46, 0x18, 0x46, 0x18, 0x46,
+ 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71,
+ 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2417 MHz */
+ 0x71, 0x09,
+ 0x10, 0x01, 0xb9, 0x83,
+ 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a,
+ 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+ 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+ 0xf0, 0x00, 0x2e, 0x6c,
+ 0x68, 0x82, 0x68, 0x82, 0x68, 0x82, 0x68, 0x82,
+ 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+ 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+ 0xd0, 0x00, 0x8d, 0x5a,
+ 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a,
+ 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+ 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+ 0xa0, 0x00, 0x0a, 0x48,
+ 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e,
+ 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+ 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+ 0x50, 0x00, 0x7c, 0x36,
+ 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59,
+ 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+ 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+ 0x00, 0x00, 0xf5, 0x2d,
+ 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45,
+ 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+ 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2422 MHz */
+ 0x76, 0x09,
+ 0x10, 0x01, 0xb9, 0x83,
+ 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a,
+ 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+ 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+ 0xf0, 0x00, 0x2e, 0x6c,
+ 0x68, 0x82, 0x68, 0x82, 0x68, 0x82, 0x68, 0x82,
+ 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+ 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+ 0xd0, 0x00, 0x8d, 0x5a,
+ 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a,
+ 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+ 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+ 0xa0, 0x00, 0x0a, 0x48,
+ 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e,
+ 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+ 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+ 0x50, 0x00, 0x7c, 0x36,
+ 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59,
+ 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+ 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+ 0x00, 0x00, 0xf5, 0x2d,
+ 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45,
+ 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+ 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2427 MHz */
+ 0x7b, 0x09,
+ 0x10, 0x01, 0x48, 0x83,
+ 0x67, 0x8a, 0x67, 0x8a, 0x67, 0x8a, 0x67, 0x8a,
+ 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5,
+ 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5,
+ 0xf0, 0x00, 0xfb, 0x6b,
+ 0x50, 0x82, 0x50, 0x82, 0x50, 0x82, 0x50, 0x82,
+ 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad,
+ 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad,
+ 0xd0, 0x00, 0x7e, 0x5a,
+ 0x38, 0x7a, 0x38, 0x7a, 0x38, 0x7a, 0x38, 0x7a,
+ 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5,
+ 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5,
+ 0xa0, 0x00, 0x15, 0x48,
+ 0x14, 0x6e, 0x14, 0x6e, 0x14, 0x6e, 0x14, 0x6e,
+ 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99,
+ 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99,
+ 0x50, 0x00, 0x8e, 0x36,
+ 0xd9, 0x59, 0xd9, 0x59, 0xd9, 0x59, 0xd9, 0x59,
+ 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85,
+ 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85,
+ 0x00, 0x00, 0xfe, 0x2d,
+ 0x9d, 0x45, 0x9d, 0x45, 0x9d, 0x45, 0x9d, 0x45,
+ 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71,
+ 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2432 MHz */
+ 0x80, 0x09,
+ 0x10, 0x01, 0xd7, 0x82,
+ 0x51, 0x8a, 0x51, 0x8a, 0x51, 0x8a, 0x51, 0x8a,
+ 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5,
+ 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5,
+ 0xf0, 0x00, 0xc8, 0x6b,
+ 0x37, 0x82, 0x37, 0x82, 0x37, 0x82, 0x37, 0x82,
+ 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad,
+ 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad,
+ 0xd0, 0x00, 0x6f, 0x5a,
+ 0x1d, 0x7a, 0x1d, 0x7a, 0x1d, 0x7a, 0x1d, 0x7a,
+ 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5,
+ 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5,
+ 0xa0, 0x00, 0x20, 0x48,
+ 0xf6, 0x6d, 0xf6, 0x6d, 0xf6, 0x6d, 0xf6, 0x6d,
+ 0x88, 0x99, 0x88, 0x99, 0x88, 0x99, 0x88, 0x99,
+ 0x88, 0x99, 0x88, 0x99, 0x88, 0x99, 0x88, 0x99,
+ 0x50, 0x00, 0x9f, 0x36,
+ 0xb5, 0x59, 0xb5, 0x59, 0xb5, 0x59, 0xb5, 0x59,
+ 0x47, 0x85, 0x47, 0x85, 0x47, 0x85, 0x47, 0x85,
+ 0x47, 0x85, 0x47, 0x85, 0x47, 0x85, 0x47, 0x85,
+ 0x00, 0x00, 0x06, 0x2e,
+ 0x74, 0x45, 0x74, 0x45, 0x74, 0x45, 0x74, 0x45,
+ 0x06, 0x71, 0x06, 0x71, 0x06, 0x71, 0x06, 0x71,
+ 0x06, 0x71, 0x06, 0x71, 0x06, 0x71, 0x06, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2437 MHz */
+ 0x85, 0x09,
+ 0x10, 0x01, 0x67, 0x82,
+ 0x3a, 0x8a, 0x3a, 0x8a, 0x3a, 0x8a, 0x3a, 0x8a,
+ 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5,
+ 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5,
+ 0xf0, 0x00, 0x95, 0x6b,
+ 0x1f, 0x82, 0x1f, 0x82, 0x1f, 0x82, 0x1f, 0x82,
+ 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad,
+ 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad,
+ 0xd0, 0x00, 0x61, 0x5a,
+ 0x02, 0x7a, 0x02, 0x7a, 0x02, 0x7a, 0x02, 0x7a,
+ 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5,
+ 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5,
+ 0xa0, 0x00, 0x2c, 0x48,
+ 0xd8, 0x6d, 0xd8, 0x6d, 0xd8, 0x6d, 0xd8, 0x6d,
+ 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99,
+ 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99,
+ 0x50, 0x00, 0xb1, 0x36,
+ 0x92, 0x59, 0x92, 0x59, 0x92, 0x59, 0x92, 0x59,
+ 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+ 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+ 0x00, 0x00, 0x0f, 0x2e,
+ 0x4b, 0x45, 0x4b, 0x45, 0x4b, 0x45, 0x4b, 0x45,
+ 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70,
+ 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2442 MHz */
+ 0x8a, 0x09,
+ 0x10, 0x01, 0xf6, 0x81,
+ 0x24, 0x8a, 0x24, 0x8a, 0x24, 0x8a, 0x24, 0x8a,
+ 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5,
+ 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5,
+ 0xf0, 0x00, 0x62, 0x6b,
+ 0x06, 0x82, 0x06, 0x82, 0x06, 0x82, 0x06, 0x82,
+ 0x98, 0xad, 0x98, 0xad, 0x98, 0xad, 0x98, 0xad,
+ 0x98, 0xad, 0x98, 0xad, 0x98, 0xad, 0x98, 0xad,
+ 0xd0, 0x00, 0x52, 0x5a,
+ 0xe7, 0x79, 0xe7, 0x79, 0xe7, 0x79, 0xe7, 0x79,
+ 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5,
+ 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5,
+ 0xa0, 0x00, 0x37, 0x48,
+ 0xba, 0x6d, 0xba, 0x6d, 0xba, 0x6d, 0xba, 0x6d,
+ 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99,
+ 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99,
+ 0x50, 0x00, 0xc2, 0x36,
+ 0x6e, 0x59, 0x6e, 0x59, 0x6e, 0x59, 0x6e, 0x59,
+ 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85,
+ 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85,
+ 0x00, 0x00, 0x17, 0x2e,
+ 0x22, 0x45, 0x22, 0x45, 0x22, 0x45, 0x22, 0x45,
+ 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70,
+ 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2447 MHz */
+ 0x8f, 0x09,
+ 0x10, 0x01, 0x75, 0x83,
+ 0x61, 0x8a, 0x61, 0x8a, 0x61, 0x8a, 0x61, 0x8a,
+ 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5,
+ 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5,
+ 0xf0, 0x00, 0x4b, 0x6c,
+ 0x3f, 0x82, 0x3f, 0x82, 0x3f, 0x82, 0x3f, 0x82,
+ 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad,
+ 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad,
+ 0xd0, 0x00, 0xda, 0x5a,
+ 0x1c, 0x7a, 0x1c, 0x7a, 0x1c, 0x7a, 0x1c, 0x7a,
+ 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5,
+ 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5,
+ 0xa0, 0x00, 0x6d, 0x48,
+ 0xe9, 0x6d, 0xe9, 0x6d, 0xe9, 0x6d, 0xe9, 0x6d,
+ 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99,
+ 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99,
+ 0x50, 0x00, 0xc6, 0x36,
+ 0x92, 0x59, 0x92, 0x59, 0x92, 0x59, 0x92, 0x59,
+ 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+ 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+ 0x00, 0x00, 0x15, 0x2e,
+ 0x3c, 0x45, 0x3c, 0x45, 0x3c, 0x45, 0x3c, 0x45,
+ 0xce, 0x70, 0xce, 0x70, 0xce, 0x70, 0xce, 0x70,
+ 0xce, 0x70, 0xce, 0x70, 0xce, 0x70, 0xce, 0x70,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2452 MHz */
+ 0x94, 0x09,
+ 0x10, 0x01, 0xf4, 0x84,
+ 0x9e, 0x8a, 0x9e, 0x8a, 0x9e, 0x8a, 0x9e, 0x8a,
+ 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6,
+ 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6,
+ 0xf0, 0x00, 0x34, 0x6d,
+ 0x77, 0x82, 0x77, 0x82, 0x77, 0x82, 0x77, 0x82,
+ 0x09, 0xae, 0x09, 0xae, 0x09, 0xae, 0x09, 0xae,
+ 0x09, 0xae, 0x09, 0xae, 0x09, 0xae, 0x09, 0xae,
+ 0xd0, 0x00, 0x62, 0x5b,
+ 0x50, 0x7a, 0x50, 0x7a, 0x50, 0x7a, 0x50, 0x7a,
+ 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5,
+ 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5,
+ 0xa0, 0x00, 0xa2, 0x48,
+ 0x17, 0x6e, 0x17, 0x6e, 0x17, 0x6e, 0x17, 0x6e,
+ 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99,
+ 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99,
+ 0x50, 0x00, 0xc9, 0x36,
+ 0xb7, 0x59, 0xb7, 0x59, 0xb7, 0x59, 0xb7, 0x59,
+ 0x49, 0x85, 0x49, 0x85, 0x49, 0x85, 0x49, 0x85,
+ 0x49, 0x85, 0x49, 0x85, 0x49, 0x85, 0x49, 0x85,
+ 0x00, 0x00, 0x12, 0x2e,
+ 0x57, 0x45, 0x57, 0x45, 0x57, 0x45, 0x57, 0x45,
+ 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70,
+ 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2452 MHz */
+ 0x99, 0x09,
+ 0x10, 0x01, 0x74, 0x86,
+ 0xdb, 0x8a, 0xdb, 0x8a, 0xdb, 0x8a, 0xdb, 0x8a,
+ 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6,
+ 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6,
+ 0xf0, 0x00, 0x1e, 0x6e,
+ 0xb0, 0x82, 0xb0, 0x82, 0xb0, 0x82, 0xb0, 0x82,
+ 0x42, 0xae, 0x42, 0xae, 0x42, 0xae, 0x42, 0xae,
+ 0x42, 0xae, 0x42, 0xae, 0x42, 0xae, 0x42, 0xae,
+ 0xd0, 0x00, 0xeb, 0x5b,
+ 0x85, 0x7a, 0x85, 0x7a, 0x85, 0x7a, 0x85, 0x7a,
+ 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6,
+ 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6,
+ 0xa0, 0x00, 0xd8, 0x48,
+ 0x46, 0x6e, 0x46, 0x6e, 0x46, 0x6e, 0x46, 0x6e,
+ 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99,
+ 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99,
+ 0x50, 0x00, 0xcd, 0x36,
+ 0xdb, 0x59, 0xdb, 0x59, 0xdb, 0x59, 0xdb, 0x59,
+ 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85,
+ 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85,
+ 0x00, 0x00, 0x10, 0x2e,
+ 0x71, 0x45, 0x71, 0x45, 0x71, 0x45, 0x71, 0x45,
+ 0x03, 0x71, 0x03, 0x71, 0x03, 0x71, 0x03, 0x71,
+ 0x03, 0x71, 0x03, 0x71, 0x03, 0x71, 0x03, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2557 MHz */
+ 0x9e, 0x09,
+ 0x10, 0x01, 0xf3, 0x87,
+ 0x17, 0x8b, 0x17, 0x8b, 0x17, 0x8b, 0x17, 0x8b,
+ 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6,
+ 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6,
+ 0xf0, 0x00, 0x07, 0x6f,
+ 0xe9, 0x82, 0xe9, 0x82, 0xe9, 0x82, 0xe9, 0x82,
+ 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae,
+ 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae,
+ 0xd0, 0x00, 0x73, 0x5c,
+ 0xba, 0x7a, 0xba, 0x7a, 0xba, 0x7a, 0xba, 0x7a,
+ 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6,
+ 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6,
+ 0xa0, 0x00, 0x0d, 0x49,
+ 0x74, 0x6e, 0x74, 0x6e, 0x74, 0x6e, 0x74, 0x6e,
+ 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a,
+ 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a,
+ 0x50, 0x00, 0xd1, 0x36,
+ 0xff, 0x59, 0xff, 0x59, 0xff, 0x59, 0xff, 0x59,
+ 0x91, 0x85, 0x91, 0x85, 0x91, 0x85, 0x91, 0x85,
+ 0x91, 0x85, 0x91, 0x85, 0x91, 0x85, 0x91, 0x85,
+ 0x00, 0x00, 0x0e, 0x2e,
+ 0x8b, 0x45, 0x8b, 0x45, 0x8b, 0x45, 0x8b, 0x45,
+ 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71,
+ 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2562 MHz */
+ 0xa3, 0x09,
+ 0x10, 0x01, 0x72, 0x89,
+ 0x54, 0x8b, 0x54, 0x8b, 0x54, 0x8b, 0x54, 0x8b,
+ 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6,
+ 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6,
+ 0xf0, 0x00, 0xf0, 0x6f,
+ 0x21, 0x83, 0x21, 0x83, 0x21, 0x83, 0x21, 0x83,
+ 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae,
+ 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae,
+ 0xd0, 0x00, 0xfb, 0x5c,
+ 0xee, 0x7a, 0xee, 0x7a, 0xee, 0x7a, 0xee, 0x7a,
+ 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6,
+ 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6,
+ 0xa0, 0x00, 0x43, 0x49,
+ 0xa3, 0x6e, 0xa3, 0x6e, 0xa3, 0x6e, 0xa3, 0x6e,
+ 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a,
+ 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a,
+ 0x50, 0x00, 0xd4, 0x36,
+ 0x24, 0x5a, 0x24, 0x5a, 0x24, 0x5a, 0x24, 0x5a,
+ 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85,
+ 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85,
+ 0x00, 0x00, 0x0b, 0x2e,
+ 0xa6, 0x45, 0xa6, 0x45, 0xa6, 0x45, 0xa6, 0x45,
+ 0x38, 0x71, 0x38, 0x71, 0x38, 0x71, 0x38, 0x71,
+ 0x38, 0x71, 0x38, 0x71, 0x38, 0x71, 0x38, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2572 MHz */
+ 0xa8, 0x09,
+ 0x10, 0x01, 0xf1, 0x8a,
+ 0x91, 0x8b, 0x91, 0x8b, 0x91, 0x8b, 0x91, 0x8b,
+ 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7,
+ 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7,
+ 0xf0, 0x00, 0xd9, 0x70,
+ 0x5a, 0x83, 0x5a, 0x83, 0x5a, 0x83, 0x5a, 0x83,
+ 0xec, 0xae, 0xec, 0xae, 0xec, 0xae, 0xec, 0xae,
+ 0xec, 0xae, 0xec, 0xae, 0xec, 0xae, 0xec, 0xae,
+ 0xd0, 0x00, 0x83, 0x5d,
+ 0x23, 0x7b, 0x23, 0x7b, 0x23, 0x7b, 0x23, 0x7b,
+ 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6,
+ 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6,
+ 0xa0, 0x00, 0x78, 0x49,
+ 0xd1, 0x6e, 0xd1, 0x6e, 0xd1, 0x6e, 0xd1, 0x6e,
+ 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a,
+ 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a,
+ 0x50, 0x00, 0xd8, 0x36,
+ 0x48, 0x5a, 0x48, 0x5a, 0x48, 0x5a, 0x48, 0x5a,
+ 0xda, 0x85, 0xda, 0x85, 0xda, 0x85, 0xda, 0x85,
+ 0xda, 0x85, 0xda, 0x85, 0xda, 0x85, 0xda, 0x85,
+ 0x00, 0x00, 0x09, 0x2e,
+ 0xc0, 0x45, 0xc0, 0x45, 0xc0, 0x45, 0xc0, 0x45,
+ 0x52, 0x71, 0x52, 0x71, 0x52, 0x71, 0x52, 0x71,
+ 0x52, 0x71, 0x52, 0x71, 0x52, 0x71, 0x52, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+/*
+ * Not really sure if this is actually the power_limit database,
+ * it looks a bit "related" to PDR_PRISM_ZIF_TX_IQ_CALIBRATION
+ */
+/* struct pda_custom_wrapper */
+0xae, 0x00, 0xef, 0xbe, /* PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM */
+ 0x0d, 0x00, 0x1a, 0x00, /* 13 entries, 26 bytes per entry */
+ 0x00, 0x00, 0x52, 0x01, /* no offset, 338 bytes total */
+
+ /* 2412 MHz */
+ 0x6c, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2417 MHz */
+ 0x71, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2422 MHz */
+ 0x76, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2427 MHz */
+ 0x7b, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2432 MHz */
+ 0x80, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2437 MHz */
+ 0x85, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2442 MHz */
+ 0x8a, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2447 MHz */
+ 0x8f, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2452 MHz */
+ 0x94, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2457 MHz */
+ 0x99, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2462 MHz */
+ 0x9e, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2467 MHz */
+ 0xa3, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2472 MHz */
+ 0xa8, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+/* struct pda_iq_autocal_entry[13] */
+0x42, 0x00, 0x06, 0x19, /* PDR_PRISM_ZIF_TX_IQ_CALIBRATION */
+ /* 2412 MHz */
+ 0x6c, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2417 MHz */
+ 0x71, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2422 MHz */
+ 0x76, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2427 MHz */
+ 0x7b, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2432 MHz */
+ 0x80, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2437 MHz */
+ 0x85, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2442 MHz */
+ 0x8a, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2447 MHz */
+ 0x8f, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2452 MHz */
+ 0x94, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2457 MHz */
+ 0x99, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+ /* 2462 MHz */
+ 0x9e, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+ /* 2467 MHz */
+ 0xa3, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+ /* 2472 MHz */
+ 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+
+0x02, 0x00, 0x00, 0x00, /* PDR_END */
+ 0xa8, 0xf5 /* bogus data */
+};
+
+#endif /* P54SPI_EEPROM_H */
+
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 6a6a72f6f82..da6640afc83 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -144,11 +144,8 @@ static void p54u_tx_cb(struct urb *urb)
struct sk_buff *skb = urb->context;
struct ieee80211_hw *dev = (struct ieee80211_hw *)
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
- struct p54u_priv *priv = dev->priv;
- skb_pull(skb, priv->common.tx_hdr_len);
- if (FREE_AFTER_TX(skb))
- p54_free_skb(dev, skb);
+ p54_free_skb(dev, skb);
}
static void p54u_tx_dummy_cb(struct urb *urb) { }
@@ -230,7 +227,10 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
p54u_tx_dummy_cb, dev);
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ 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);
@@ -239,7 +239,7 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
goto out;
}
- usb_anchor_urb(addr_urb, &priv->submitted);
+ usb_anchor_urb(data_urb, &priv->submitted);
err = usb_submit_urb(data_urb, GFP_ATOMIC);
if (err)
usb_unanchor_urb(data_urb);
@@ -269,28 +269,24 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54u_priv *priv = dev->priv;
struct urb *data_urb;
- struct lm87_tx_hdr *hdr;
- __le32 checksum;
- __le32 addr = ((struct p54_hdr *)skb->data)->req_id;
+ struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
data_urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!data_urb)
return;
- checksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
- hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr));
- hdr->chksum = checksum;
- hdr->device_addr = addr;
+ hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
+ hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
+ p54u_tx_cb : p54u_tx_dummy_cb, skb);
data_urb->transfer_flags |= URB_ZERO_PACKET;
usb_anchor_urb(data_urb, &priv->submitted);
if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
usb_unanchor_urb(data_urb);
- skb_pull(skb, sizeof(*hdr));
p54_free_skb(dev, skb);
}
usb_free_urb(data_urb);
@@ -300,11 +296,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54u_priv *priv = dev->priv;
struct urb *int_urb, *data_urb;
- struct net2280_tx_hdr *hdr;
+ struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
struct net2280_reg_write *reg;
int err = 0;
- __le32 addr = ((struct p54_hdr *) skb->data)->req_id;
- __le16 len = cpu_to_le16(skb->len);
reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
if (!reg)
@@ -327,10 +321,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
reg->addr = cpu_to_le32(P54U_DEV_BASE);
reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
- hdr = (void *)skb_push(skb, sizeof(*hdr));
memset(hdr, 0, sizeof(*hdr));
- hdr->len = len;
- hdr->device_addr = addr;
+ hdr->len = cpu_to_le16(skb->len);
+ hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
usb_fill_bulk_urb(int_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
@@ -341,11 +334,13 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
* free what's inside the transfer_buffer after the callback routine
* has completed.
*/
- int_urb->transfer_flags |= URB_FREE_BUFFER;
+ int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
+ p54u_tx_cb : p54u_tx_dummy_cb, skb);
+ data_urb->transfer_flags |= URB_ZERO_PACKET;
usb_anchor_urb(int_urb, &priv->submitted);
err = usb_submit_urb(int_urb, GFP_ATOMIC);
@@ -429,9 +424,46 @@ 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)
+{
+ 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);
+ return ret;
+ }
+ }
+
+ ret = usb_reset_device(priv->udev);
+ if (lock)
+ usb_unlock_device(priv->udev);
+
+ if (ret) {
+ dev_err(&priv->udev->dev, "(p54usb) unable to reset "
+ "device: %d\n", ret);
+ return 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);
+
+ return ret;
+}
+
static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
{
- static char start_string[] = "~~~~<\r";
struct p54u_priv *priv = dev->priv;
const struct firmware *fw_entry = NULL;
int err, alen;
@@ -450,12 +482,9 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
goto err_bufalloc;
}
- memcpy(buf, start_string, 4);
- err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
- if (err) {
- dev_err(&priv->udev->dev, "(p54usb) reset failed! (%d)\n", err);
+ err = p54u_device_reset_3887(dev);
+ if (err)
goto err_reset;
- }
err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev);
if (err) {
@@ -471,15 +500,22 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
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;
+ }
+
left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
- strcpy(buf, start_string);
- left -= strlen(start_string);
- tmp += strlen(start_string);
+ 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;
- hdr = (struct x2_header *)(buf + strlen(start_string));
+ 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);
@@ -621,6 +657,14 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
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,\
@@ -881,6 +925,9 @@ static int __devinit p54u_probe(struct usb_interface *intf,
SET_IEEE80211_DEV(dev, &intf->dev);
usb_set_intfdata(intf, dev);
priv->udev = udev;
+ priv->intf = intf;
+ skb_queue_head_init(&priv->rx_queue);
+ init_usb_anchor(&priv->submitted);
usb_get_dev(udev);
@@ -923,20 +970,15 @@ static int __devinit p54u_probe(struct usb_interface *intf,
if (err)
goto err_free_dev;
- skb_queue_head_init(&priv->rx_queue);
- init_usb_anchor(&priv->submitted);
-
p54u_open(dev);
err = p54_read_eeprom(dev);
p54u_stop(dev);
if (err)
goto err_free_dev;
- err = ieee80211_register_hw(dev);
- if (err) {
- dev_err(&udev->dev, "(p54usb) Cannot register netdevice\n");
+ err = p54_register_common(dev, &udev->dev);
+ if (err)
goto err_free_dev;
- }
return 0;
@@ -963,11 +1005,24 @@ static void __devexit p54u_disconnect(struct usb_interface *intf)
ieee80211_free_hw(dev);
}
+static int p54u_pre_reset(struct usb_interface *intf)
+{
+ return 0;
+}
+
+static int p54u_post_reset(struct usb_interface *intf)
+{
+ return 0;
+}
+
static struct usb_driver p54u_driver = {
.name = "p54usb",
.id_table = p54u_table,
.probe = p54u_probe,
.disconnect = p54u_disconnect,
+ .pre_reset = p54u_pre_reset,
+ .post_reset = p54u_post_reset,
+ .soft_unbind = 1,
};
static int __init p54u_init(void)
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h
index 54ee738bf2a..8bc58982d8d 100644
--- a/drivers/net/wireless/p54/p54usb.h
+++ b/drivers/net/wireless/p54/p54usb.h
@@ -126,6 +126,7 @@ struct p54u_rx_info {
struct p54u_priv {
struct p54_common common;
struct usb_device *udev;
+ struct usb_interface *intf;
enum {
P54U_NET2280 = 0,
P54U_3887
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 57a150a22de..4c97c6ad6f5 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -2981,7 +2981,8 @@ prism54_set_spy(struct net_device *ndev,
union iwreq_data *uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 u, oid = OID_INL_CONFIG;
+ u32 u;
+ enum oid_num_t oid = OID_INL_CONFIG;
down_write(&priv->mib_sem);
mgt_get(priv, OID_INL_CONFIG, &u);
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 9196825ed1b..166ed958460 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -43,7 +43,6 @@
static int prism54_bring_down(islpci_private *);
static int islpci_alloc_memory(islpci_private *);
-static struct net_device_stats *islpci_statistics(struct net_device *);
/* Temporary dummy MAC address to use until firmware is loaded.
* The idea there is that some tools (such as nameif) may query
@@ -614,18 +613,6 @@ islpci_reset(islpci_private *priv, int reload_firmware)
return rc;
}
-static struct net_device_stats *
-islpci_statistics(struct net_device *ndev)
-{
- islpci_private *priv = netdev_priv(ndev);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics\n");
-#endif
-
- return &priv->statistics;
-}
-
/******************************************************************************
Network device configuration functions
******************************************************************************/
@@ -804,10 +791,22 @@ static void islpci_ethtool_get_drvinfo(struct net_device *dev,
strcpy(info->version, DRV_VERSION);
}
-static struct ethtool_ops islpci_ethtool_ops = {
+static const struct ethtool_ops islpci_ethtool_ops = {
.get_drvinfo = islpci_ethtool_get_drvinfo,
};
+static const struct net_device_ops islpci_netdev_ops = {
+ .ndo_open = islpci_open,
+ .ndo_stop = islpci_close,
+ .ndo_do_ioctl = prism54_ioctl,
+ .ndo_start_xmit = islpci_eth_transmit,
+ .ndo_tx_timeout = islpci_eth_tx_timeout,
+ .ndo_set_mac_address = prism54_set_mac_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
struct net_device *
islpci_setup(struct pci_dev *pdev)
{
@@ -827,25 +826,16 @@ islpci_setup(struct pci_dev *pdev)
ndev->irq = pdev->irq;
/* initialize the function pointers */
- ndev->open = &islpci_open;
- ndev->stop = &islpci_close;
- ndev->get_stats = &islpci_statistics;
- ndev->do_ioctl = &prism54_ioctl;
- ndev->wireless_handlers =
- (struct iw_handler_def *) &prism54_handler_def;
+ ndev->netdev_ops = &islpci_netdev_ops;
+ ndev->wireless_handlers = &prism54_handler_def;
ndev->ethtool_ops = &islpci_ethtool_ops;
- ndev->hard_start_xmit = &islpci_eth_transmit;
/* ndev->set_multicast_list = &islpci_set_multicast_list; */
ndev->addr_len = ETH_ALEN;
- ndev->set_mac_address = &prism54_set_mac_address;
/* Get a non-zero dummy MAC address for nameif. Jean II */
memcpy(ndev->dev_addr, dummy_mac, 6);
-#ifdef HAVE_TX_TIMEOUT
ndev->watchdog_timeo = ISLPCI_TX_TIMEOUT;
- ndev->tx_timeout = &islpci_eth_tx_timeout;
-#endif
/* allocate a private device structure to the network device */
priv = netdev_priv(ndev);
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index 8e55a5fcffa..c4d0f19b7cb 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -158,9 +158,6 @@ typedef struct {
dma_addr_t pci_map_tx_address[ISL38XX_CB_TX_QSIZE];
dma_addr_t pci_map_rx_address[ISL38XX_CB_RX_QSIZE];
- /* driver network interface members */
- struct net_device_stats statistics;
-
/* wait for a reset interrupt */
wait_queue_head_t reset_done;
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index e43bae97ed8..ef3ef4551b3 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -23,6 +23,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <asm/byteorder.h>
#include "prismcompat.h"
#include "isl_38xx.h"
@@ -230,8 +231,8 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
/* set the transmission time */
ndev->trans_start = jiffies;
- priv->statistics.tx_packets++;
- priv->statistics.tx_bytes += skb->len;
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
/* trigger the device */
islpci_trigger(priv);
@@ -242,7 +243,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
return 0;
drop_free:
- priv->statistics.tx_dropped++;
+ ndev->stats.tx_dropped++;
spin_unlock_irqrestore(&priv->slock, flags);
dev_kfree_skb(skb);
return err;
@@ -407,8 +408,8 @@ islpci_eth_receive(islpci_private *priv)
skb->protocol = eth_type_trans(skb, ndev);
}
skb->ip_summed = CHECKSUM_NONE;
- priv->statistics.rx_packets++;
- priv->statistics.rx_bytes += size;
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += size;
/* deliver the skb to the network layer */
#ifdef ISLPCI_ETH_DEBUG
@@ -471,8 +472,8 @@ islpci_eth_receive(islpci_private *priv)
wmb();
/* increment the driver read pointer */
- add_le32p(&control_block->
- driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
+ le32_add_cpu(&control_block->
+ driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
}
/* trigger the device */
@@ -496,10 +497,9 @@ void
islpci_eth_tx_timeout(struct net_device *ndev)
{
islpci_private *priv = netdev_priv(ndev);
- struct net_device_stats *statistics = &priv->statistics;
/* increment the transmit error counter */
- statistics->tx_errors++;
+ ndev->stats.tx_errors++;
if (!priv->reset_task_pending) {
printk(KERN_WARNING
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
index f91a88fc1e3..87a1734663d 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.h
+++ b/drivers/net/wireless/prism54/islpci_mgt.h
@@ -85,12 +85,6 @@ extern int pc_debug;
#define PIMFOR_FLAG_APPLIC_ORIGIN 0x01
#define PIMFOR_FLAG_LITTLE_ENDIAN 0x02
-static inline void
-add_le32p(__le32 * le_number, u32 add)
-{
- *le_number = cpu_to_le32(le32_to_cpup(le_number) + add);
-}
-
void display_buffer(char *, int);
/*
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 57a4ac34bed..1187e6112a6 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -698,7 +698,7 @@ int
mgt_commit(islpci_private *priv)
{
int rvalue;
- u32 u;
+ enum oid_num_t u;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 99ec7d62251..fa90d1d8d82 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -8,7 +8,7 @@
* Copyright (c) 1998 Corey Thomas (corey@world.std.com)
*
* This driver is free software; you can redistribute it and/or modify
- * it under the terms of version 2 only of the GNU General Public License as
+ * it under the terms of version 2 only of the GNU General Public License as
* published by the Free Software Foundation.
*
* It is distributed in the hope that it will be useful,
@@ -27,7 +27,7 @@
*
* Daniele Bellucci <bellucda@tiscali.it> - 07/10/2003
* - Audit copy_to_user in ioctl(SIOCGIWESSID)
- *
+ *
=============================================================================*/
#include <linux/module.h>
@@ -65,8 +65,8 @@
/* Warning : these stuff will slow down the driver... */
#define WIRELESS_SPY /* Enable spying addresses */
/* Definitions we need for spy */
-typedef struct iw_statistics iw_stats;
-typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */
+typedef struct iw_statistics iw_stats;
+typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */
#include "rayctl.h"
#include "ray_cs.h"
@@ -86,7 +86,7 @@ static int ray_debug;
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(args);
+#define DEBUG(n, args...) if (pc_debug > (n)) printk(args);
#else
#define DEBUG(n, args...)
#endif
@@ -108,12 +108,12 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static void ray_update_multi_list(struct net_device *dev, int all);
static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
- unsigned char *data, int len);
-static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
- unsigned char *data);
+ unsigned char *data, int len);
+static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
+ UCHAR msg_type, unsigned char *data);
static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
-static iw_stats * ray_get_wireless_stats(struct net_device * dev);
-static const struct iw_handler_def ray_handler_def;
+static iw_stats *ray_get_wireless_stats(struct net_device *dev);
+static const struct iw_handler_def ray_handler_def;
/***** Prototypes for raylink functions **************************************/
static int asc_to_int(char a);
@@ -124,7 +124,7 @@ static int get_free_ccs(ray_dev_t *local);
static int get_free_tx_ccs(ray_dev_t *local);
static void init_startup_params(ray_dev_t *local);
static int parse_addr(char *in_str, UCHAR *out);
-static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type);
+static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev, UCHAR type);
static int ray_init(struct net_device *dev);
static int interrupt_ecf(ray_dev_t *local, int ccs);
static void ray_reset(struct net_device *dev);
@@ -132,17 +132,17 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, i
static void verify_dl_startup(u_long);
/* Prototypes for interrpt time functions **********************************/
-static irqreturn_t ray_interrupt (int reg, void *dev_id);
+static irqreturn_t ray_interrupt(int reg, void *dev_id);
static void clear_interrupt(ray_dev_t *local);
-static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
- unsigned int pkt_addr, int rx_len);
+static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
+ unsigned int pkt_addr, int rx_len);
static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs);
static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs);
static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
- unsigned int pkt_addr, int rx_len);
-static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr,
- int rx_len);
+ unsigned int pkt_addr, int rx_len);
+static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
+ unsigned int pkt_addr, int rx_len);
static void associate(ray_dev_t *local);
/* Card command functions */
@@ -219,82 +219,97 @@ module_param(phy_addr, charp, 0);
module_param(ray_mem_speed, int, 0);
static UCHAR b5_default_startup_parms[] = {
- 0, 0, /* Adhoc station */
- 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, /* Active scan, CA Mode */
- 0, 0, 0, 0, 0, 0, /* No default MAC addr */
- 0x7f, 0xff, /* Frag threshold */
- 0x00, 0x80, /* Hop time 128 Kus*/
- 0x01, 0x00, /* Beacon period 256 Kus */
- 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/
- 0x1d, 0x82, 0x4e, /* SIFS, DIFS, PIFS */
- 0x7f, 0xff, /* RTS threshold */
- 0x04, 0xe2, 0x38, 0xA4, /* scan_dwell, max_scan_dwell */
- 0x05, /* assoc resp timeout thresh */
- 0x08, 0x02, 0x08, /* adhoc, infra, super cycle max*/
- 0, /* Promiscuous mode */
- 0x0c, 0x0bd, /* Unique word */
- 0x32, /* Slot time */
- 0xff, 0xff, /* roam-low snr, low snr count */
- 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
- 0x01, 0x0b, 0x4f, /* USA, hop pattern, hop pat length */
+ 0, 0, /* Adhoc station */
+ 'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, /* Active scan, CA Mode */
+ 0, 0, 0, 0, 0, 0, /* No default MAC addr */
+ 0x7f, 0xff, /* Frag threshold */
+ 0x00, 0x80, /* Hop time 128 Kus */
+ 0x01, 0x00, /* Beacon period 256 Kus */
+ 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout */
+ 0x1d, 0x82, 0x4e, /* SIFS, DIFS, PIFS */
+ 0x7f, 0xff, /* RTS threshold */
+ 0x04, 0xe2, 0x38, 0xA4, /* scan_dwell, max_scan_dwell */
+ 0x05, /* assoc resp timeout thresh */
+ 0x08, 0x02, 0x08, /* adhoc, infra, super cycle max */
+ 0, /* Promiscuous mode */
+ 0x0c, 0x0bd, /* Unique word */
+ 0x32, /* Slot time */
+ 0xff, 0xff, /* roam-low snr, low snr count */
+ 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
+ 0x01, 0x0b, 0x4f, /* USA, hop pattern, hop pat length */
/* b4 - b5 differences start here */
- 0x00, 0x3f, /* CW max */
- 0x00, 0x0f, /* CW min */
- 0x04, 0x08, /* Noise gain, limit offset */
- 0x28, 0x28, /* det rssi, med busy offsets */
- 7, /* det sync thresh */
- 0, 2, 2, /* test mode, min, max */
- 0, /* allow broadcast SSID probe resp */
- 0, 0, /* privacy must start, can join */
- 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */
+ 0x00, 0x3f, /* CW max */
+ 0x00, 0x0f, /* CW min */
+ 0x04, 0x08, /* Noise gain, limit offset */
+ 0x28, 0x28, /* det rssi, med busy offsets */
+ 7, /* det sync thresh */
+ 0, 2, 2, /* test mode, min, max */
+ 0, /* allow broadcast SSID probe resp */
+ 0, 0, /* privacy must start, can join */
+ 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */
};
static UCHAR b4_default_startup_parms[] = {
- 0, 0, /* Adhoc station */
- 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, /* Active scan, CA Mode */
- 0, 0, 0, 0, 0, 0, /* No default MAC addr */
- 0x7f, 0xff, /* Frag threshold */
- 0x02, 0x00, /* Hop time */
- 0x00, 0x01, /* Beacon period */
- 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/
- 0x1d, 0x82, 0xce, /* SIFS, DIFS, PIFS */
- 0x7f, 0xff, /* RTS threshold */
- 0xfb, 0x1e, 0xc7, 0x5c, /* scan_dwell, max_scan_dwell */
- 0x05, /* assoc resp timeout thresh */
- 0x04, 0x02, 0x4, /* adhoc, infra, super cycle max*/
- 0, /* Promiscuous mode */
- 0x0c, 0x0bd, /* Unique word */
- 0x4e, /* Slot time (TBD seems wrong)*/
- 0xff, 0xff, /* roam-low snr, low snr count */
- 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
- 0x01, 0x0b, 0x4e, /* USA, hop pattern, hop pat length */
+ 0, 0, /* Adhoc station */
+ 'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, /* Active scan, CA Mode */
+ 0, 0, 0, 0, 0, 0, /* No default MAC addr */
+ 0x7f, 0xff, /* Frag threshold */
+ 0x02, 0x00, /* Hop time */
+ 0x00, 0x01, /* Beacon period */
+ 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout */
+ 0x1d, 0x82, 0xce, /* SIFS, DIFS, PIFS */
+ 0x7f, 0xff, /* RTS threshold */
+ 0xfb, 0x1e, 0xc7, 0x5c, /* scan_dwell, max_scan_dwell */
+ 0x05, /* assoc resp timeout thresh */
+ 0x04, 0x02, 0x4, /* adhoc, infra, super cycle max */
+ 0, /* Promiscuous mode */
+ 0x0c, 0x0bd, /* Unique word */
+ 0x4e, /* Slot time (TBD seems wrong) */
+ 0xff, 0xff, /* roam-low snr, low snr count */
+ 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
+ 0x01, 0x0b, 0x4e, /* USA, hop pattern, hop pat length */
/* b4 - b5 differences start here */
- 0x3f, 0x0f, /* CW max, min */
- 0x04, 0x08, /* Noise gain, limit offset */
- 0x28, 0x28, /* det rssi, med busy offsets */
- 7, /* det sync thresh */
- 0, 2, 2 /* test mode, min, max*/
+ 0x3f, 0x0f, /* CW max, min */
+ 0x04, 0x08, /* Noise gain, limit offset */
+ 0x28, 0x28, /* det rssi, med busy offsets */
+ 7, /* det sync thresh */
+ 0, 2, 2 /* test mode, min, max */
};
+
/*===========================================================================*/
-static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0};
+static unsigned char eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
static char hop_pattern_length[] = { 1,
- USA_HOP_MOD, EUROPE_HOP_MOD,
- JAPAN_HOP_MOD, KOREA_HOP_MOD,
- SPAIN_HOP_MOD, FRANCE_HOP_MOD,
- ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
- JAPAN_TEST_HOP_MOD
+ USA_HOP_MOD, EUROPE_HOP_MOD,
+ JAPAN_HOP_MOD, KOREA_HOP_MOD,
+ SPAIN_HOP_MOD, FRANCE_HOP_MOD,
+ ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
+ JAPAN_TEST_HOP_MOD
};
-static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
+static char rcsid[] =
+ "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
+
+static const struct net_device_ops ray_netdev_ops = {
+ .ndo_init = ray_dev_init,
+ .ndo_open = ray_open,
+ .ndo_stop = ray_dev_close,
+ .ndo_start_xmit = ray_dev_start_xmit,
+ .ndo_set_config = ray_dev_config,
+ .ndo_get_stats = ray_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
/*=============================================================================
ray_attach() creates an "instance" of the driver, allocating
@@ -306,71 +321,66 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
=============================================================================*/
static int ray_probe(struct pcmcia_device *p_dev)
{
- ray_dev_t *local;
- struct net_device *dev;
-
- DEBUG(1, "ray_attach()\n");
-
- /* Allocate space for private device-specific data */
- dev = alloc_etherdev(sizeof(ray_dev_t));
- if (!dev)
- goto fail_alloc_dev;
-
- local = netdev_priv(dev);
- local->finder = p_dev;
-
- /* The io structure describes IO port mapping. None used here */
- p_dev->io.NumPorts1 = 0;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.IOAddrLines = 5;
-
- /* Interrupt setup. For PCMCIA, driver takes what's given */
- p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
- p_dev->irq.Handler = &ray_interrupt;
-
- /* General socket configuration */
- p_dev->conf.Attributes = CONF_ENABLE_IRQ;
- p_dev->conf.IntType = INT_MEMORY_AND_IO;
- p_dev->conf.ConfigIndex = 1;
-
- p_dev->priv = dev;
- p_dev->irq.Instance = dev;
-
- local->finder = p_dev;
- local->card_status = CARD_INSERTED;
- local->authentication_state = UNAUTHENTICATED;
- local->num_multi = 0;
- DEBUG(2,"ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
- p_dev,dev,local,&ray_interrupt);
-
- /* Raylink entries in the device structure */
- dev->hard_start_xmit = &ray_dev_start_xmit;
- dev->set_config = &ray_dev_config;
- dev->get_stats = &ray_get_stats;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->wireless_handlers = &ray_handler_def;
+ ray_dev_t *local;
+ struct net_device *dev;
+
+ DEBUG(1, "ray_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ dev = alloc_etherdev(sizeof(ray_dev_t));
+ if (!dev)
+ goto fail_alloc_dev;
+
+ local = netdev_priv(dev);
+ local->finder = p_dev;
+
+ /* The io structure describes IO port mapping. None used here */
+ p_dev->io.NumPorts1 = 0;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = 5;
+
+ /* Interrupt setup. For PCMCIA, driver takes what's given */
+ p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
+ p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Handler = &ray_interrupt;
+
+ /* General socket configuration */
+ p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+ p_dev->conf.IntType = INT_MEMORY_AND_IO;
+ p_dev->conf.ConfigIndex = 1;
+
+ p_dev->priv = dev;
+ p_dev->irq.Instance = dev;
+
+ local->finder = p_dev;
+ local->card_status = CARD_INSERTED;
+ local->authentication_state = UNAUTHENTICATED;
+ local->num_multi = 0;
+ DEBUG(2, "ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
+ p_dev, dev, local, &ray_interrupt);
+
+ /* Raylink entries in the device structure */
+ dev->netdev_ops = &ray_netdev_ops;
+ SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+ dev->wireless_handlers = &ray_handler_def;
#ifdef WIRELESS_SPY
- local->wireless_data.spy_data = &local->spy_data;
- dev->wireless_data = &local->wireless_data;
-#endif /* WIRELESS_SPY */
+ local->wireless_data.spy_data = &local->spy_data;
+ dev->wireless_data = &local->wireless_data;
+#endif /* WIRELESS_SPY */
- dev->set_multicast_list = &set_multicast_list;
- DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
- dev->init = &ray_dev_init;
- dev->open = &ray_open;
- dev->stop = &ray_dev_close;
- netif_stop_queue(dev);
+ DEBUG(2, "ray_cs ray_attach calling ether_setup.)\n");
+ netif_stop_queue(dev);
- init_timer(&local->timer);
+ init_timer(&local->timer);
- this_device = p_dev;
- return ray_config(p_dev);
+ this_device = p_dev;
+ return ray_config(p_dev);
fail_alloc_dev:
- return -ENOMEM;
+ return -ENOMEM;
} /* ray_attach */
+
/*=============================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
@@ -379,25 +389,27 @@ fail_alloc_dev:
=============================================================================*/
static void ray_detach(struct pcmcia_device *link)
{
- struct net_device *dev;
- ray_dev_t *local;
+ struct net_device *dev;
+ ray_dev_t *local;
- DEBUG(1, "ray_detach(0x%p)\n", link);
+ DEBUG(1, "ray_detach(0x%p)\n", link);
- this_device = NULL;
- dev = link->priv;
+ this_device = NULL;
+ dev = link->priv;
- ray_release(link);
+ ray_release(link);
- local = netdev_priv(dev);
- del_timer(&local->timer);
+ local = netdev_priv(dev);
+ del_timer(&local->timer);
- if (link->priv) {
- if (link->dev_node) unregister_netdev(dev);
- free_netdev(dev);
- }
- DEBUG(2,"ray_cs ray_detach ending\n");
+ if (link->priv) {
+ if (link->dev_node)
+ unregister_netdev(dev);
+ free_netdev(dev);
+ }
+ DEBUG(2, "ray_cs ray_detach ending\n");
} /* ray_detach */
+
/*=============================================================================
ray_config() is run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
@@ -408,92 +420,101 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define MAX_TUPLE_SIZE 128
static int ray_config(struct pcmcia_device *link)
{
- int last_fn = 0, last_ret = 0;
- int i;
- win_req_t req;
- memreq_t mem;
- struct net_device *dev = (struct net_device *)link->priv;
- ray_dev_t *local = netdev_priv(dev);
-
- DEBUG(1, "ray_config(0x%p)\n", link);
-
- /* Determine card type and firmware version */
- printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
- link->prod_id[0] ? link->prod_id[0] : " ",
- link->prod_id[1] ? link->prod_id[1] : " ",
- link->prod_id[2] ? link->prod_id[2] : " ",
- link->prod_id[3] ? link->prod_id[3] : " ");
-
- /* Now allocate an interrupt line. Note that this does not
- actually assign a handler to the interrupt.
- */
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- dev->irq = link->irq.AssignedIRQ;
-
- /* This actually configures the PCMCIA socket -- setting up
- the I/O windows and the interrupt mapping.
- */
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ int last_fn = 0, last_ret = 0;
+ int i;
+ win_req_t req;
+ memreq_t mem;
+ struct net_device *dev = (struct net_device *)link->priv;
+ ray_dev_t *local = netdev_priv(dev);
+
+ DEBUG(1, "ray_config(0x%p)\n", link);
+
+ /* Determine card type and firmware version */
+ printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
+ link->prod_id[0] ? link->prod_id[0] : " ",
+ link->prod_id[1] ? link->prod_id[1] : " ",
+ link->prod_id[2] ? link->prod_id[2] : " ",
+ link->prod_id[3] ? link->prod_id[3] : " ");
+
+ /* Now allocate an interrupt line. Note that this does not
+ actually assign a handler to the interrupt.
+ */
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ dev->irq = link->irq.AssignedIRQ;
+
+ /* This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping.
+ */
+ CS_CHECK(RequestConfiguration,
+ pcmcia_request_configuration(link, &link->conf));
/*** Set up 32k window for shared memory (transmit and control) ************/
- req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
- req.Base = 0;
- req.Size = 0x8000;
- req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
- mem.CardOffset = 0x0000; mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
- local->sram = ioremap(req.Base,req.Size);
+ req.Attributes =
+ WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+ req.Base = 0;
+ req.Size = 0x8000;
+ req.AccessSpeed = ray_mem_speed;
+ CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+ mem.CardOffset = 0x0000;
+ mem.Page = 0;
+ CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+ local->sram = ioremap(req.Base, req.Size);
/*** Set up 16k window for shared memory (receive buffer) ***************/
- req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
- req.Base = 0;
- req.Size = 0x4000;
- req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle));
- mem.CardOffset = 0x8000; mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
- local->rmem = ioremap(req.Base,req.Size);
+ req.Attributes =
+ WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+ req.Base = 0;
+ req.Size = 0x4000;
+ req.AccessSpeed = ray_mem_speed;
+ CS_CHECK(RequestWindow,
+ pcmcia_request_window(&link, &req, &local->rmem_handle));
+ mem.CardOffset = 0x8000;
+ mem.Page = 0;
+ CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
+ local->rmem = ioremap(req.Base, req.Size);
/*** Set up window for attribute memory ***********************************/
- req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
- req.Base = 0;
- req.Size = 0x1000;
- req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle));
- mem.CardOffset = 0x0000; mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
- local->amem = ioremap(req.Base,req.Size);
-
- DEBUG(3,"ray_config sram=%p\n",local->sram);
- DEBUG(3,"ray_config rmem=%p\n",local->rmem);
- DEBUG(3,"ray_config amem=%p\n",local->amem);
- if (ray_init(dev) < 0) {
- ray_release(link);
- return -ENODEV;
- }
-
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
- i = register_netdev(dev);
- if (i != 0) {
- printk("ray_config register_netdev() failed\n");
- ray_release(link);
- return i;
- }
-
- strcpy(local->node.dev_name, dev->name);
- link->dev_node = &local->node;
-
- printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
- dev->name, dev->irq, dev->dev_addr);
-
- return 0;
+ req.Attributes =
+ WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
+ req.Base = 0;
+ req.Size = 0x1000;
+ req.AccessSpeed = ray_mem_speed;
+ CS_CHECK(RequestWindow,
+ pcmcia_request_window(&link, &req, &local->amem_handle));
+ mem.CardOffset = 0x0000;
+ mem.Page = 0;
+ CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
+ local->amem = ioremap(req.Base, req.Size);
+
+ DEBUG(3, "ray_config sram=%p\n", local->sram);
+ DEBUG(3, "ray_config rmem=%p\n", local->rmem);
+ DEBUG(3, "ray_config amem=%p\n", local->amem);
+ if (ray_init(dev) < 0) {
+ ray_release(link);
+ return -ENODEV;
+ }
+
+ SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ i = register_netdev(dev);
+ if (i != 0) {
+ printk("ray_config register_netdev() failed\n");
+ ray_release(link);
+ return i;
+ }
+
+ strcpy(local->node.dev_name, dev->name);
+ link->dev_node = &local->node;
+
+ printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
+ dev->name, dev->irq, dev->dev_addr);
+
+ return 0;
cs_failed:
- cs_error(link, last_fn, last_ret);
+ cs_error(link, last_fn, last_ret);
- ray_release(link);
- return -ENODEV;
+ ray_release(link);
+ return -ENODEV;
} /* ray_config */
static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
@@ -516,267 +537,278 @@ static inline struct rcs __iomem *rcs_base(ray_dev_t *dev)
/*===========================================================================*/
static int ray_init(struct net_device *dev)
{
- int i;
- UCHAR *p;
- struct ccs __iomem *pccs;
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- DEBUG(1, "ray_init(0x%p)\n", dev);
- if (!(pcmcia_dev_present(link))) {
- DEBUG(0,"ray_init - device not present\n");
- return -1;
- }
-
- local->net_type = net_type;
- local->sta_type = TYPE_STA;
-
- /* Copy the startup results to local memory */
- memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,\
- sizeof(struct startup_res_6));
-
- /* Check Power up test status and get mac address from card */
- if (local->startup_res.startup_word != 0x80) {
- printk(KERN_INFO "ray_init ERROR card status = %2x\n",
- local->startup_res.startup_word);
- local->card_status = CARD_INIT_ERROR;
- return -1;
- }
-
- local->fw_ver = local->startup_res.firmware_version[0];
- local->fw_bld = local->startup_res.firmware_version[1];
- local->fw_var = local->startup_res.firmware_version[2];
- DEBUG(1,"ray_init firmware version %d.%d \n",local->fw_ver, local->fw_bld);
-
- local->tib_length = 0x20;
- if ((local->fw_ver == 5) && (local->fw_bld >= 30))
- local->tib_length = local->startup_res.tib_length;
- DEBUG(2,"ray_init tib_length = 0x%02x\n", local->tib_length);
- /* Initialize CCS's to buffer free state */
- pccs = ccs_base(local);
- for (i=0; i<NUMBER_OF_CCS; i++) {
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- }
- init_startup_params(local);
-
- /* copy mac address to startup parameters */
- if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr))
- {
- p = local->sparm.b4.a_mac_addr;
- }
- else
- {
- memcpy(&local->sparm.b4.a_mac_addr,
- &local->startup_res.station_addr, ADDRLEN);
- p = local->sparm.b4.a_mac_addr;
- }
-
- clear_interrupt(local); /* Clear any interrupt from the card */
- local->card_status = CARD_AWAITING_PARAM;
- DEBUG(2,"ray_init ending\n");
- return 0;
+ int i;
+ UCHAR *p;
+ struct ccs __iomem *pccs;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ DEBUG(1, "ray_init(0x%p)\n", dev);
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(0, "ray_init - device not present\n");
+ return -1;
+ }
+
+ local->net_type = net_type;
+ local->sta_type = TYPE_STA;
+
+ /* Copy the startup results to local memory */
+ memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,
+ sizeof(struct startup_res_6));
+
+ /* Check Power up test status and get mac address from card */
+ if (local->startup_res.startup_word != 0x80) {
+ printk(KERN_INFO "ray_init ERROR card status = %2x\n",
+ local->startup_res.startup_word);
+ local->card_status = CARD_INIT_ERROR;
+ return -1;
+ }
+
+ local->fw_ver = local->startup_res.firmware_version[0];
+ local->fw_bld = local->startup_res.firmware_version[1];
+ local->fw_var = local->startup_res.firmware_version[2];
+ DEBUG(1, "ray_init firmware version %d.%d \n", local->fw_ver,
+ local->fw_bld);
+
+ local->tib_length = 0x20;
+ if ((local->fw_ver == 5) && (local->fw_bld >= 30))
+ local->tib_length = local->startup_res.tib_length;
+ DEBUG(2, "ray_init tib_length = 0x%02x\n", local->tib_length);
+ /* Initialize CCS's to buffer free state */
+ pccs = ccs_base(local);
+ for (i = 0; i < NUMBER_OF_CCS; i++) {
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ }
+ init_startup_params(local);
+
+ /* copy mac address to startup parameters */
+ if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr)) {
+ p = local->sparm.b4.a_mac_addr;
+ } else {
+ memcpy(&local->sparm.b4.a_mac_addr,
+ &local->startup_res.station_addr, ADDRLEN);
+ p = local->sparm.b4.a_mac_addr;
+ }
+
+ clear_interrupt(local); /* Clear any interrupt from the card */
+ local->card_status = CARD_AWAITING_PARAM;
+ DEBUG(2, "ray_init ending\n");
+ return 0;
} /* ray_init */
+
/*===========================================================================*/
/* Download startup parameters to the card and command it to read them */
static int dl_startup_params(struct net_device *dev)
{
- int ccsindex;
- ray_dev_t *local = netdev_priv(dev);
- struct ccs __iomem *pccs;
- struct pcmcia_device *link = local->finder;
-
- DEBUG(1,"dl_startup_params entered\n");
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs dl_startup_params - device not present\n");
- return -1;
- }
-
- /* Copy parameters to host to ECF area */
- if (local->fw_ver == 0x55)
- memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
- sizeof(struct b4_startup_params));
- else
- memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
- sizeof(struct b5_startup_params));
-
-
- /* Fill in the CCS fields for the ECF */
- if ((ccsindex = get_free_ccs(local)) < 0) return -1;
- local->dl_param_ccs = ccsindex;
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
- DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs);
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- printk(KERN_INFO "ray dl_startup_params failed - "
- "ECF not ready for intr\n");
- local->card_status = CARD_DL_PARAM_ERROR;
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- return -2;
- }
- local->card_status = CARD_DL_PARAM;
- /* Start kernel timer to wait for dl startup to complete. */
- local->timer.expires = jiffies + HZ/2;
- local->timer.data = (long)local;
- local->timer.function = &verify_dl_startup;
- add_timer(&local->timer);
- DEBUG(2,"ray_cs dl_startup_params started timer for verify_dl_startup\n");
- return 0;
+ int ccsindex;
+ ray_dev_t *local = netdev_priv(dev);
+ struct ccs __iomem *pccs;
+ struct pcmcia_device *link = local->finder;
+
+ DEBUG(1, "dl_startup_params entered\n");
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs dl_startup_params - device not present\n");
+ return -1;
+ }
+
+ /* Copy parameters to host to ECF area */
+ if (local->fw_ver == 0x55)
+ memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
+ sizeof(struct b4_startup_params));
+ else
+ memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
+ sizeof(struct b5_startup_params));
+
+ /* Fill in the CCS fields for the ECF */
+ if ((ccsindex = get_free_ccs(local)) < 0)
+ return -1;
+ local->dl_param_ccs = ccsindex;
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
+ DEBUG(2, "dl_startup_params start ccsindex = %d\n",
+ local->dl_param_ccs);
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ printk(KERN_INFO "ray dl_startup_params failed - "
+ "ECF not ready for intr\n");
+ local->card_status = CARD_DL_PARAM_ERROR;
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ return -2;
+ }
+ local->card_status = CARD_DL_PARAM;
+ /* Start kernel timer to wait for dl startup to complete. */
+ local->timer.expires = jiffies + HZ / 2;
+ local->timer.data = (long)local;
+ local->timer.function = &verify_dl_startup;
+ add_timer(&local->timer);
+ DEBUG(2,
+ "ray_cs dl_startup_params started timer for verify_dl_startup\n");
+ return 0;
} /* dl_startup_params */
+
/*===========================================================================*/
static void init_startup_params(ray_dev_t *local)
{
- int i;
-
- if (country > JAPAN_TEST) country = USA;
- else
- if (country < USA) country = USA;
- /* structure for hop time and beacon period is defined here using
- * New 802.11D6.1 format. Card firmware is still using old format
- * until version 6.
- * Before After
- * a_hop_time ms byte a_hop_time ms byte
- * a_hop_time 2s byte a_hop_time ls byte
- * a_hop_time ls byte a_beacon_period ms byte
- * a_beacon_period a_beacon_period ls byte
- *
- * a_hop_time = uS a_hop_time = KuS
- * a_beacon_period = hops a_beacon_period = KuS
- */ /* 64ms = 010000 */
- if (local->fw_ver == 0x55) {
- memcpy((UCHAR *)&local->sparm.b4, b4_default_startup_parms,
- sizeof(struct b4_startup_params));
- /* Translate sane kus input values to old build 4/5 format */
- /* i = hop time in uS truncated to 3 bytes */
- i = (hop_dwell * 1024) & 0xffffff;
- local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
- local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
- local->sparm.b4.a_beacon_period[0] = 0;
- local->sparm.b4.a_beacon_period[1] =
- ((beacon_period/hop_dwell) - 1) & 0xff;
- local->sparm.b4.a_curr_country_code = country;
- local->sparm.b4.a_hop_pattern_length =
- hop_pattern_length[(int)country] - 1;
- if (bc)
- {
- local->sparm.b4.a_ack_timeout = 0x50;
- local->sparm.b4.a_sifs = 0x3f;
- }
- }
- else { /* Version 5 uses real kus values */
- memcpy((UCHAR *)&local->sparm.b5, b5_default_startup_parms,
- sizeof(struct b5_startup_params));
-
- local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
- local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
- local->sparm.b5.a_beacon_period[0] = (beacon_period >> 8) & 0xff;
- local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
- if (psm)
- local->sparm.b5.a_power_mgt_state = 1;
- local->sparm.b5.a_curr_country_code = country;
- local->sparm.b5.a_hop_pattern_length =
- hop_pattern_length[(int)country];
- }
-
- local->sparm.b4.a_network_type = net_type & 0x01;
- local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
-
- if (essid != NULL)
- strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
-} /* init_startup_params */
+ int i;
+
+ if (country > JAPAN_TEST)
+ country = USA;
+ else if (country < USA)
+ country = USA;
+ /* structure for hop time and beacon period is defined here using
+ * New 802.11D6.1 format. Card firmware is still using old format
+ * until version 6.
+ * Before After
+ * a_hop_time ms byte a_hop_time ms byte
+ * a_hop_time 2s byte a_hop_time ls byte
+ * a_hop_time ls byte a_beacon_period ms byte
+ * a_beacon_period a_beacon_period ls byte
+ *
+ * a_hop_time = uS a_hop_time = KuS
+ * a_beacon_period = hops a_beacon_period = KuS
+ *//* 64ms = 010000 */
+ if (local->fw_ver == 0x55) {
+ memcpy((UCHAR *) &local->sparm.b4, b4_default_startup_parms,
+ sizeof(struct b4_startup_params));
+ /* Translate sane kus input values to old build 4/5 format */
+ /* i = hop time in uS truncated to 3 bytes */
+ i = (hop_dwell * 1024) & 0xffffff;
+ local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
+ local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
+ local->sparm.b4.a_beacon_period[0] = 0;
+ local->sparm.b4.a_beacon_period[1] =
+ ((beacon_period / hop_dwell) - 1) & 0xff;
+ local->sparm.b4.a_curr_country_code = country;
+ local->sparm.b4.a_hop_pattern_length =
+ hop_pattern_length[(int)country] - 1;
+ if (bc) {
+ local->sparm.b4.a_ack_timeout = 0x50;
+ local->sparm.b4.a_sifs = 0x3f;
+ }
+ } else { /* Version 5 uses real kus values */
+ memcpy((UCHAR *) &local->sparm.b5, b5_default_startup_parms,
+ sizeof(struct b5_startup_params));
+
+ local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
+ local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
+ local->sparm.b5.a_beacon_period[0] =
+ (beacon_period >> 8) & 0xff;
+ local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
+ if (psm)
+ local->sparm.b5.a_power_mgt_state = 1;
+ local->sparm.b5.a_curr_country_code = country;
+ local->sparm.b5.a_hop_pattern_length =
+ hop_pattern_length[(int)country];
+ }
+
+ local->sparm.b4.a_network_type = net_type & 0x01;
+ local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
+
+ if (essid != NULL)
+ strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
+} /* init_startup_params */
+
/*===========================================================================*/
static void verify_dl_startup(u_long data)
{
- ray_dev_t *local = (ray_dev_t *)data;
- struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
- UCHAR status;
- struct pcmcia_device *link = local->finder;
+ ray_dev_t *local = (ray_dev_t *) data;
+ struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
+ UCHAR status;
+ struct pcmcia_device *link = local->finder;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
- return;
- }
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs verify_dl_startup - device not present\n");
+ return;
+ }
#ifdef PCMCIA_DEBUG
- if (pc_debug > 2) {
- int i;
- printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n",
- local->dl_param_ccs);
- for (i=0; i<sizeof(struct b5_startup_params); i++) {
- printk(" %2x", (unsigned int) readb(local->sram + HOST_TO_ECF_BASE + i));
- }
- printk("\n");
- }
+ if (pc_debug > 2) {
+ int i;
+ printk(KERN_DEBUG
+ "verify_dl_startup parameters sent via ccs %d:\n",
+ local->dl_param_ccs);
+ for (i = 0; i < sizeof(struct b5_startup_params); i++) {
+ printk(" %2x",
+ (unsigned int)readb(local->sram +
+ HOST_TO_ECF_BASE + i));
+ }
+ printk("\n");
+ }
#endif
- status = readb(&pccs->buffer_status);
- if (status!= CCS_BUFFER_FREE)
- {
- printk(KERN_INFO "Download startup params failed. Status = %d\n",
- status);
- local->card_status = CARD_DL_PARAM_ERROR;
- return;
- }
- if (local->sparm.b4.a_network_type == ADHOC)
- start_net((u_long)local);
- else
- join_net((u_long)local);
-
- return;
+ status = readb(&pccs->buffer_status);
+ if (status != CCS_BUFFER_FREE) {
+ printk(KERN_INFO
+ "Download startup params failed. Status = %d\n",
+ status);
+ local->card_status = CARD_DL_PARAM_ERROR;
+ return;
+ }
+ if (local->sparm.b4.a_network_type == ADHOC)
+ start_net((u_long) local);
+ else
+ join_net((u_long) local);
+
+ return;
} /* end verify_dl_startup */
+
/*===========================================================================*/
/* Command card to start a network */
static void start_net(u_long data)
{
- ray_dev_t *local = (ray_dev_t *)data;
- struct ccs __iomem *pccs;
- int ccsindex;
- struct pcmcia_device *link = local->finder;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs start_net - device not present\n");
- return;
- }
- /* Fill in the CCS fields for the ECF */
- if ((ccsindex = get_free_ccs(local)) < 0) return;
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_START_NETWORK, &pccs->cmd);
- writeb(0, &pccs->var.start_network.update_param);
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray start net failed - card not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- return;
- }
- local->card_status = CARD_DOING_ACQ;
- return;
+ ray_dev_t *local = (ray_dev_t *) data;
+ struct ccs __iomem *pccs;
+ int ccsindex;
+ struct pcmcia_device *link = local->finder;
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs start_net - device not present\n");
+ return;
+ }
+ /* Fill in the CCS fields for the ECF */
+ if ((ccsindex = get_free_ccs(local)) < 0)
+ return;
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_START_NETWORK, &pccs->cmd);
+ writeb(0, &pccs->var.start_network.update_param);
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1, "ray start net failed - card not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ return;
+ }
+ local->card_status = CARD_DOING_ACQ;
+ return;
} /* end start_net */
+
/*===========================================================================*/
/* Command card to join a network */
static void join_net(u_long data)
{
- ray_dev_t *local = (ray_dev_t *)data;
-
- struct ccs __iomem *pccs;
- int ccsindex;
- struct pcmcia_device *link = local->finder;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs join_net - device not present\n");
- return;
- }
- /* Fill in the CCS fields for the ECF */
- if ((ccsindex = get_free_ccs(local)) < 0) return;
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_JOIN_NETWORK, &pccs->cmd);
- writeb(0, &pccs->var.join_network.update_param);
- writeb(0, &pccs->var.join_network.net_initiated);
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray join net failed - card not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- return;
- }
- local->card_status = CARD_DOING_ACQ;
- return;
+ ray_dev_t *local = (ray_dev_t *) data;
+
+ struct ccs __iomem *pccs;
+ int ccsindex;
+ struct pcmcia_device *link = local->finder;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs join_net - device not present\n");
+ return;
+ }
+ /* Fill in the CCS fields for the ECF */
+ if ((ccsindex = get_free_ccs(local)) < 0)
+ return;
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_JOIN_NETWORK, &pccs->cmd);
+ writeb(0, &pccs->var.join_network.update_param);
+ writeb(0, &pccs->var.join_network.net_initiated);
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1, "ray join net failed - card not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ return;
+ }
+ local->card_status = CARD_DOING_ACQ;
+ return;
}
+
/*============================================================================
After a card is removed, ray_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
@@ -784,25 +816,27 @@ static void join_net(u_long data)
=============================================================================*/
static void ray_release(struct pcmcia_device *link)
{
- struct net_device *dev = link->priv;
- ray_dev_t *local = netdev_priv(dev);
- int i;
-
- DEBUG(1, "ray_release(0x%p)\n", link);
-
- del_timer(&local->timer);
-
- iounmap(local->sram);
- iounmap(local->rmem);
- iounmap(local->amem);
- /* Do bother checking to see if these succeed or not */
- i = pcmcia_release_window(local->amem_handle);
- if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
- i = pcmcia_release_window(local->rmem_handle);
- if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
- pcmcia_disable_device(link);
-
- DEBUG(2,"ray_release ending\n");
+ struct net_device *dev = link->priv;
+ ray_dev_t *local = netdev_priv(dev);
+ int i;
+
+ DEBUG(1, "ray_release(0x%p)\n", link);
+
+ del_timer(&local->timer);
+
+ iounmap(local->sram);
+ iounmap(local->rmem);
+ iounmap(local->amem);
+ /* Do bother checking to see if these succeed or not */
+ i = pcmcia_release_window(local->amem_handle);
+ if (i != 0)
+ DEBUG(0, "ReleaseWindow(local->amem) ret = %x\n", i);
+ i = pcmcia_release_window(local->rmem_handle);
+ if (i != 0)
+ DEBUG(0, "ReleaseWindow(local->rmem) ret = %x\n", i);
+ pcmcia_disable_device(link);
+
+ DEBUG(2, "ray_release ending\n");
}
static int ray_suspend(struct pcmcia_device *link)
@@ -831,237 +865,243 @@ static int ray_resume(struct pcmcia_device *link)
static int ray_dev_init(struct net_device *dev)
{
#ifdef RAY_IMMEDIATE_INIT
- int i;
-#endif /* RAY_IMMEDIATE_INIT */
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
-
- DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_dev_init - device not present\n");
- return -1;
- }
+ int i;
+#endif /* RAY_IMMEDIATE_INIT */
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+
+ DEBUG(1, "ray_dev_init(dev=%p)\n", dev);
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_dev_init - device not present\n");
+ return -1;
+ }
#ifdef RAY_IMMEDIATE_INIT
- /* Download startup parameters */
- if ( (i = dl_startup_params(dev)) < 0)
- {
- printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
- "returns 0x%x\n",i);
- return -1;
- }
-#else /* RAY_IMMEDIATE_INIT */
- /* Postpone the card init so that we can still configure the card,
- * for example using the Wireless Extensions. The init will happen
- * in ray_open() - Jean II */
- DEBUG(1,"ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
- local->card_status);
-#endif /* RAY_IMMEDIATE_INIT */
-
- /* copy mac and broadcast addresses to linux device */
- memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
- memset(dev->broadcast, 0xff, ETH_ALEN);
-
- DEBUG(2,"ray_dev_init ending\n");
- return 0;
+ /* Download startup parameters */
+ if ((i = dl_startup_params(dev)) < 0) {
+ printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
+ "returns 0x%x\n", i);
+ return -1;
+ }
+#else /* RAY_IMMEDIATE_INIT */
+ /* Postpone the card init so that we can still configure the card,
+ * for example using the Wireless Extensions. The init will happen
+ * in ray_open() - Jean II */
+ DEBUG(1,
+ "ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
+ local->card_status);
+#endif /* RAY_IMMEDIATE_INIT */
+
+ /* copy mac and broadcast addresses to linux device */
+ memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
+ memset(dev->broadcast, 0xff, ETH_ALEN);
+
+ DEBUG(2, "ray_dev_init ending\n");
+ return 0;
}
+
/*===========================================================================*/
static int ray_dev_config(struct net_device *dev, struct ifmap *map)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- /* Dummy routine to satisfy device structure */
- DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_dev_config - device not present\n");
- return -1;
- }
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ /* Dummy routine to satisfy device structure */
+ DEBUG(1, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_dev_config - device not present\n");
+ return -1;
+ }
- return 0;
+ return 0;
}
+
/*===========================================================================*/
static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- short length = skb->len;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_dev_start_xmit - device not present\n");
- return -1;
- }
- DEBUG(3,"ray_dev_start_xmit(skb=%p, dev=%p)\n",skb,dev);
- if (local->authentication_state == NEED_TO_AUTH) {
- DEBUG(0,"ray_cs Sending authentication request.\n");
- if (!build_auth_frame (local, local->auth_id, OPEN_AUTH_REQUEST)) {
- local->authentication_state = AUTHENTICATED;
- netif_stop_queue(dev);
- return 1;
- }
- }
-
- if (length < ETH_ZLEN)
- {
- if (skb_padto(skb, ETH_ZLEN))
- return 0;
- length = ETH_ZLEN;
- }
- switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) {
- case XMIT_NO_CCS:
- case XMIT_NEED_AUTH:
- netif_stop_queue(dev);
- return 1;
- case XMIT_NO_INTR:
- case XMIT_MSG_BAD:
- case XMIT_OK:
- default:
- dev->trans_start = jiffies;
- dev_kfree_skb(skb);
- return 0;
- }
- return 0;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ short length = skb->len;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_dev_start_xmit - device not present\n");
+ return -1;
+ }
+ DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
+ if (local->authentication_state == NEED_TO_AUTH) {
+ DEBUG(0, "ray_cs Sending authentication request.\n");
+ if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
+ local->authentication_state = AUTHENTICATED;
+ netif_stop_queue(dev);
+ return 1;
+ }
+ }
+
+ if (length < ETH_ZLEN) {
+ if (skb_padto(skb, ETH_ZLEN))
+ return 0;
+ length = ETH_ZLEN;
+ }
+ switch (ray_hw_xmit(skb->data, length, dev, DATA_TYPE)) {
+ case XMIT_NO_CCS:
+ case XMIT_NEED_AUTH:
+ netif_stop_queue(dev);
+ return 1;
+ case XMIT_NO_INTR:
+ case XMIT_MSG_BAD:
+ case XMIT_OK:
+ default:
+ dev->trans_start = jiffies;
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ return 0;
} /* ray_dev_start_xmit */
+
/*===========================================================================*/
-static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev,
- UCHAR msg_type)
-{
- ray_dev_t *local = netdev_priv(dev);
- struct ccs __iomem *pccs;
- int ccsindex;
- int offset;
- struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */
- short int addr; /* Address of xmit buffer in card space */
-
- DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev);
- if (len + TX_HEADER_LENGTH > TX_BUF_SIZE)
- {
- printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",len);
- return XMIT_MSG_BAD;
- }
+static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
+ UCHAR msg_type)
+{
+ ray_dev_t *local = netdev_priv(dev);
+ struct ccs __iomem *pccs;
+ int ccsindex;
+ int offset;
+ struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */
+ short int addr; /* Address of xmit buffer in card space */
+
+ DEBUG(3, "ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
+ if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) {
+ printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",
+ len);
+ return XMIT_MSG_BAD;
+ }
switch (ccsindex = get_free_tx_ccs(local)) {
case ECCSBUSY:
- DEBUG(2,"ray_hw_xmit tx_ccs table busy\n");
+ DEBUG(2, "ray_hw_xmit tx_ccs table busy\n");
case ECCSFULL:
- DEBUG(2,"ray_hw_xmit No free tx ccs\n");
+ DEBUG(2, "ray_hw_xmit No free tx ccs\n");
case ECARDGONE:
- netif_stop_queue(dev);
- return XMIT_NO_CCS;
+ netif_stop_queue(dev);
+ return XMIT_NO_CCS;
default:
break;
}
- addr = TX_BUF_BASE + (ccsindex << 11);
-
- if (msg_type == DATA_TYPE) {
- local->stats.tx_bytes += len;
- local->stats.tx_packets++;
- }
-
- ptx = local->sram + addr;
-
- ray_build_header(local, ptx, msg_type, data);
- if (translate) {
- offset = translate_frame(local, ptx, data, len);
- }
- else { /* Encapsulate frame */
- /* TBD TIB length will move address of ptx->var */
- memcpy_toio(&ptx->var, data, len);
- offset = 0;
- }
-
- /* fill in the CCS */
- pccs = ccs_base(local) + ccsindex;
- len += TX_HEADER_LENGTH + offset;
- writeb(CCS_TX_REQUEST, &pccs->cmd);
- writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
- writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
- writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
- writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
+ addr = TX_BUF_BASE + (ccsindex << 11);
+
+ if (msg_type == DATA_TYPE) {
+ local->stats.tx_bytes += len;
+ local->stats.tx_packets++;
+ }
+
+ ptx = local->sram + addr;
+
+ ray_build_header(local, ptx, msg_type, data);
+ if (translate) {
+ offset = translate_frame(local, ptx, data, len);
+ } else { /* Encapsulate frame */
+ /* TBD TIB length will move address of ptx->var */
+ memcpy_toio(&ptx->var, data, len);
+ offset = 0;
+ }
+
+ /* fill in the CCS */
+ pccs = ccs_base(local) + ccsindex;
+ len += TX_HEADER_LENGTH + offset;
+ writeb(CCS_TX_REQUEST, &pccs->cmd);
+ writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
+ writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
+ writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
+ writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
/* TBD still need psm_cam? */
- writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
- writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
- writeb(0, &pccs->var.tx_request.antenna);
- DEBUG(3,"ray_hw_xmit default_tx_rate = 0x%x\n",\
- local->net_default_tx_rate);
-
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(2,"ray_hw_xmit failed - ECF not ready for intr\n");
+ writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
+ writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
+ writeb(0, &pccs->var.tx_request.antenna);
+ DEBUG(3, "ray_hw_xmit default_tx_rate = 0x%x\n",
+ local->net_default_tx_rate);
+
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(2, "ray_hw_xmit failed - ECF not ready for intr\n");
/* TBD very inefficient to copy packet to buffer, and then not
send it, but the alternative is to queue the messages and that
won't be done for a while. Maybe set tbusy until a CCS is free?
*/
- writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
- return XMIT_NO_INTR;
- }
- return XMIT_OK;
+ writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
+ return XMIT_NO_INTR;
+ }
+ return XMIT_OK;
} /* end ray_hw_xmit */
+
/*===========================================================================*/
-static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data,
- int len)
-{
- __be16 proto = ((struct ethhdr *)data)->h_proto;
- if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
- DEBUG(3,"ray_cs translate_frame DIX II\n");
- /* Copy LLC header to card buffer */
- memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
- memcpy_toio( ((void __iomem *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);
- if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
- /* This is the selective translation table, only 2 entries */
- writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
- }
- /* Copy body of ethernet packet without ethernet header */
- memcpy_toio((void __iomem *)&ptx->var + sizeof(struct snaphdr_t), \
- data + ETH_HLEN, len - ETH_HLEN);
- return (int) sizeof(struct snaphdr_t) - ETH_HLEN;
- }
- else { /* already 802 type, and proto is length */
- DEBUG(3,"ray_cs translate_frame 802\n");
- if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
- DEBUG(3,"ray_cs translate_frame evil IPX\n");
- memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
- return 0 - ETH_HLEN;
- }
- memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
- return 0 - ETH_HLEN;
- }
- /* TBD do other frame types */
+static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
+ unsigned char *data, int len)
+{
+ __be16 proto = ((struct ethhdr *)data)->h_proto;
+ if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
+ DEBUG(3, "ray_cs translate_frame DIX II\n");
+ /* Copy LLC header to card buffer */
+ memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
+ memcpy_toio(((void __iomem *)&ptx->var) + sizeof(eth2_llc),
+ (UCHAR *) &proto, 2);
+ if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
+ /* This is the selective translation table, only 2 entries */
+ writeb(0xf8,
+ &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
+ }
+ /* Copy body of ethernet packet without ethernet header */
+ memcpy_toio((void __iomem *)&ptx->var +
+ sizeof(struct snaphdr_t), data + ETH_HLEN,
+ len - ETH_HLEN);
+ return (int)sizeof(struct snaphdr_t) - ETH_HLEN;
+ } else { /* already 802 type, and proto is length */
+ DEBUG(3, "ray_cs translate_frame 802\n");
+ if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
+ DEBUG(3, "ray_cs translate_frame evil IPX\n");
+ memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
+ return 0 - ETH_HLEN;
+ }
+ memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
+ return 0 - ETH_HLEN;
+ }
+ /* TBD do other frame types */
} /* end translate_frame */
+
/*===========================================================================*/
-static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
- unsigned char *data)
+static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
+ UCHAR msg_type, unsigned char *data)
{
- writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
+ writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
/*** IEEE 802.11 Address field assignments *************
- TODS FROMDS addr_1 addr_2 addr_3 addr_4
-Adhoc 0 0 dest src (terminal) BSSID N/A
-AP to Terminal 0 1 dest AP(BSSID) source N/A
-Terminal to AP 1 0 AP(BSSID) src (terminal) dest N/A
-AP to AP 1 1 dest AP src AP dest source
+ TODS FROMDS addr_1 addr_2 addr_3 addr_4
+Adhoc 0 0 dest src (terminal) BSSID N/A
+AP to Terminal 0 1 dest AP(BSSID) source N/A
+Terminal to AP 1 0 AP(BSSID) src (terminal) dest N/A
+AP to AP 1 1 dest AP src AP dest source
*******************************************************/
- if (local->net_type == ADHOC) {
- writeb(0, &ptx->mac.frame_ctl_2);
- memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, 2 * ADDRLEN);
- memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
- }
- else /* infrastructure */
- {
- if (local->sparm.b4.a_acting_as_ap_status)
- {
- writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
- memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, ADDRLEN);
- memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
- memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_source, ADDRLEN);
- }
- else /* Terminal */
- {
- writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
- memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
- memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source, ADDRLEN);
- memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_dest, ADDRLEN);
- }
- }
+ if (local->net_type == ADHOC) {
+ writeb(0, &ptx->mac.frame_ctl_2);
+ memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest,
+ 2 * ADDRLEN);
+ memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
+ } else { /* infrastructure */
+
+ if (local->sparm.b4.a_acting_as_ap_status) {
+ writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
+ memcpy_toio(ptx->mac.addr_1,
+ ((struct ethhdr *)data)->h_dest, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
+ memcpy_toio(ptx->mac.addr_3,
+ ((struct ethhdr *)data)->h_source, ADDRLEN);
+ } else { /* Terminal */
+
+ writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
+ memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_2,
+ ((struct ethhdr *)data)->h_source, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_3,
+ ((struct ethhdr *)data)->h_dest, ADDRLEN);
+ }
+ }
} /* end encapsulate_frame */
-
/*===========================================================================*/
static void netdev_get_drvinfo(struct net_device *dev,
@@ -1071,7 +1111,7 @@ static void netdev_get_drvinfo(struct net_device *dev,
}
static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
+ .get_drvinfo = netdev_get_drvinfo,
};
/*====================================================================*/
@@ -1081,9 +1121,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
* Wireless Handler : get protocol name
*/
static int ray_get_name(struct net_device *dev,
- struct iw_request_info *info,
- char *cwrq,
- char *extra)
+ struct iw_request_info *info, char *cwrq, char *extra)
{
strcpy(cwrq, "IEEE 802.11-FH");
return 0;
@@ -1095,14 +1133,13 @@ static int ray_get_name(struct net_device *dev,
*/
static int ray_set_freq(struct net_device *dev,
struct iw_request_info *info,
- struct iw_freq *fwrq,
- char *extra)
+ struct iw_freq *fwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
+ int err = -EINPROGRESS; /* Call commit handler */
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* Setting by channel number */
@@ -1113,15 +1150,14 @@ static int ray_set_freq(struct net_device *dev,
return err;
}
-
+
/*------------------------------------------------------------------*/
/*
* Wireless Handler : get frequency
*/
static int ray_get_freq(struct net_device *dev,
struct iw_request_info *info,
- struct iw_freq *fwrq,
- char *extra)
+ struct iw_freq *fwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
@@ -1136,22 +1172,21 @@ static int ray_get_freq(struct net_device *dev,
*/
static int ray_set_essid(struct net_device *dev,
struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra)
+ struct iw_point *dwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* Check if we asked for `any' */
- if(dwrq->flags == 0) {
+ if (dwrq->flags == 0) {
/* Corey : can you do that ? */
return -EOPNOTSUPP;
} else {
/* Check the size of the string */
- if(dwrq->length > IW_ESSID_MAX_SIZE) {
+ if (dwrq->length > IW_ESSID_MAX_SIZE) {
return -E2BIG;
}
@@ -1160,7 +1195,7 @@ static int ray_set_essid(struct net_device *dev,
memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length);
}
- return -EINPROGRESS; /* Call commit handler */
+ return -EINPROGRESS; /* Call commit handler */
}
/*------------------------------------------------------------------*/
@@ -1169,8 +1204,7 @@ static int ray_set_essid(struct net_device *dev,
*/
static int ray_get_essid(struct net_device *dev,
struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra)
+ struct iw_point *dwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
@@ -1179,7 +1213,7 @@ static int ray_get_essid(struct net_device *dev,
/* Push it out ! */
dwrq->length = strlen(extra);
- dwrq->flags = 1; /* active */
+ dwrq->flags = 1; /* active */
return 0;
}
@@ -1189,9 +1223,8 @@ static int ray_get_essid(struct net_device *dev,
* Wireless Handler : get AP address
*/
static int ray_get_wap(struct net_device *dev,
- struct iw_request_info *info,
- struct sockaddr *awrq,
- char *extra)
+ struct iw_request_info *info,
+ struct sockaddr *awrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
@@ -1207,25 +1240,24 @@ static int ray_get_wap(struct net_device *dev,
*/
static int ray_set_rate(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* Check if rate is in range */
- if((vwrq->value != 1000000) && (vwrq->value != 2000000))
+ if ((vwrq->value != 1000000) && (vwrq->value != 2000000))
return -EINVAL;
/* Hack for 1.5 Mb/s instead of 2 Mb/s */
- if((local->fw_ver == 0x55) && /* Please check */
- (vwrq->value == 2000000))
+ if ((local->fw_ver == 0x55) && /* Please check */
+ (vwrq->value == 2000000))
local->net_default_tx_rate = 3;
else
- local->net_default_tx_rate = vwrq->value/500000;
+ local->net_default_tx_rate = vwrq->value / 500000;
return 0;
}
@@ -1236,16 +1268,15 @@ static int ray_set_rate(struct net_device *dev,
*/
static int ray_get_rate(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
- if(local->net_default_tx_rate == 3)
- vwrq->value = 2000000; /* Hum... */
+ if (local->net_default_tx_rate == 3)
+ vwrq->value = 2000000; /* Hum... */
else
vwrq->value = local->net_default_tx_rate * 500000;
- vwrq->fixed = 0; /* We are in auto mode */
+ vwrq->fixed = 0; /* We are in auto mode */
return 0;
}
@@ -1256,43 +1287,40 @@ static int ray_get_rate(struct net_device *dev,
*/
static int ray_set_rts(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
int rthr = vwrq->value;
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* if(wrq->u.rts.fixed == 0) we should complain */
- if(vwrq->disabled)
+ if (vwrq->disabled)
rthr = 32767;
else {
- if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
+ if ((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
return -EINVAL;
}
local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
- return -EINPROGRESS; /* Call commit handler */
+ return -EINPROGRESS; /* Call commit handler */
}
-
/*------------------------------------------------------------------*/
/*
* Wireless Handler : get RTS threshold
*/
static int ray_get_rts(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8)
- + local->sparm.b5.a_rts_threshold[1];
+ + local->sparm.b5.a_rts_threshold[1];
vwrq->disabled = (vwrq->value == 32767);
vwrq->fixed = 1;
@@ -1305,27 +1333,26 @@ static int ray_get_rts(struct net_device *dev,
*/
static int ray_set_frag(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
int fthr = vwrq->value;
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* if(wrq->u.frag.fixed == 0) should complain */
- if(vwrq->disabled)
+ if (vwrq->disabled)
fthr = 32767;
else {
- if((fthr < 256) || (fthr > 2347)) /* To check out ! */
+ if ((fthr < 256) || (fthr > 2347)) /* To check out ! */
return -EINVAL;
}
local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
- return -EINPROGRESS; /* Call commit handler */
+ return -EINPROGRESS; /* Call commit handler */
}
/*------------------------------------------------------------------*/
@@ -1334,13 +1361,12 @@ static int ray_set_frag(struct net_device *dev,
*/
static int ray_get_frag(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8)
- + local->sparm.b5.a_frag_threshold[1];
+ + local->sparm.b5.a_frag_threshold[1];
vwrq->disabled = (vwrq->value == 32767);
vwrq->fixed = 1;
@@ -1352,23 +1378,20 @@ static int ray_get_frag(struct net_device *dev,
* Wireless Handler : set Mode of Operation
*/
static int ray_set_mode(struct net_device *dev,
- struct iw_request_info *info,
- __u32 *uwrq,
- char *extra)
+ struct iw_request_info *info, __u32 *uwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
+ int err = -EINPROGRESS; /* Call commit handler */
char card_mode = 1;
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
- switch (*uwrq)
- {
+ switch (*uwrq) {
case IW_MODE_ADHOC:
card_mode = 0;
- // Fall through
+ /* Fall through */
case IW_MODE_INFRA:
local->sparm.b5.a_network_type = card_mode;
break;
@@ -1384,13 +1407,11 @@ static int ray_set_mode(struct net_device *dev,
* Wireless Handler : get Mode of Operation
*/
static int ray_get_mode(struct net_device *dev,
- struct iw_request_info *info,
- __u32 *uwrq,
- char *extra)
+ struct iw_request_info *info, __u32 *uwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
- if(local->sparm.b5.a_network_type)
+ if (local->sparm.b5.a_network_type)
*uwrq = IW_MODE_INFRA;
else
*uwrq = IW_MODE_ADHOC;
@@ -1404,12 +1425,11 @@ static int ray_get_mode(struct net_device *dev,
*/
static int ray_get_range(struct net_device *dev,
struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra)
+ struct iw_point *dwrq, char *extra)
{
- struct iw_range *range = (struct iw_range *) extra;
+ struct iw_range *range = (struct iw_range *)extra;
- memset((char *) range, 0, sizeof(struct iw_range));
+ memset((char *)range, 0, sizeof(struct iw_range));
/* Set the length (very important for backward compatibility) */
dwrq->length = sizeof(struct iw_range);
@@ -1420,7 +1440,7 @@ static int ray_get_range(struct net_device *dev,
/* Set information in the range struct */
range->throughput = 1.1 * 1000 * 1000; /* Put the right number here */
- range->num_channels = hop_pattern_length[(int)country];
+ range->num_channels = hop_pattern_length[(int)country];
range->num_frequency = 0;
range->max_qual.qual = 0;
range->max_qual.level = 255; /* What's the correct value ? */
@@ -1437,8 +1457,7 @@ static int ray_get_range(struct net_device *dev,
*/
static int ray_set_framing(struct net_device *dev,
struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ union iwreq_data *wrqu, char *extra)
{
translate = *(extra); /* Set framing mode */
@@ -1451,8 +1470,7 @@ static int ray_set_framing(struct net_device *dev,
*/
static int ray_get_framing(struct net_device *dev,
struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ union iwreq_data *wrqu, char *extra)
{
*(extra) = translate;
@@ -1465,8 +1483,7 @@ static int ray_get_framing(struct net_device *dev,
*/
static int ray_get_country(struct net_device *dev,
struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ union iwreq_data *wrqu, char *extra)
{
*(extra) = country;
@@ -1477,11 +1494,10 @@ static int ray_get_country(struct net_device *dev,
/*
* Commit handler : called after a bunch of SET operations
*/
-static int ray_commit(struct net_device *dev,
- struct iw_request_info *info, /* NULL */
- void *zwrq, /* NULL */
- char *extra) /* NULL */
-{
+static int ray_commit(struct net_device *dev, struct iw_request_info *info, /* NULL */
+ void *zwrq, /* NULL */
+ char *extra)
+{ /* NULL */
return 0;
}
@@ -1489,33 +1505,34 @@ static int ray_commit(struct net_device *dev,
/*
* Stats handler : return Wireless Stats
*/
-static iw_stats * ray_get_wireless_stats(struct net_device * dev)
+static iw_stats *ray_get_wireless_stats(struct net_device *dev)
{
- ray_dev_t * local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- struct status __iomem *p = local->sram + STATUS_BASE;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ struct status __iomem *p = local->sram + STATUS_BASE;
- if(local == (ray_dev_t *) NULL)
- return (iw_stats *) NULL;
+ if (local == (ray_dev_t *) NULL)
+ return (iw_stats *) NULL;
- local->wstats.status = local->card_status;
+ local->wstats.status = local->card_status;
#ifdef WIRELESS_SPY
- if((local->spy_data.spy_number > 0) && (local->sparm.b5.a_network_type == 0))
- {
- /* Get it from the first node in spy list */
- local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
- local->wstats.qual.level = local->spy_data.spy_stat[0].level;
- local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
- local->wstats.qual.updated = local->spy_data.spy_stat[0].updated;
- }
+ if ((local->spy_data.spy_number > 0)
+ && (local->sparm.b5.a_network_type == 0)) {
+ /* Get it from the first node in spy list */
+ local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
+ local->wstats.qual.level = local->spy_data.spy_stat[0].level;
+ local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
+ local->wstats.qual.updated =
+ local->spy_data.spy_stat[0].updated;
+ }
#endif /* WIRELESS_SPY */
- if(pcmcia_dev_present(link)) {
- local->wstats.qual.noise = readb(&p->rxnoise);
- local->wstats.qual.updated |= 4;
- }
+ if (pcmcia_dev_present(link)) {
+ local->wstats.qual.noise = readb(&p->rxnoise);
+ local->wstats.qual.updated |= 4;
+ }
- return &local->wstats;
+ return &local->wstats;
} /* end ray_get_wireless_stats */
/*------------------------------------------------------------------*/
@@ -1523,1159 +1540,1264 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev)
* Structures to export the Wireless Handlers
*/
-static const iw_handler ray_handler[] = {
- [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit,
- [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) ray_get_name,
- [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) ray_set_freq,
- [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) ray_get_freq,
- [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) ray_set_mode,
- [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) ray_get_mode,
- [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range,
+static const iw_handler ray_handler[] = {
+ [SIOCSIWCOMMIT - SIOCIWFIRST] = (iw_handler) ray_commit,
+ [SIOCGIWNAME - SIOCIWFIRST] = (iw_handler) ray_get_name,
+ [SIOCSIWFREQ - SIOCIWFIRST] = (iw_handler) ray_set_freq,
+ [SIOCGIWFREQ - SIOCIWFIRST] = (iw_handler) ray_get_freq,
+ [SIOCSIWMODE - SIOCIWFIRST] = (iw_handler) ray_set_mode,
+ [SIOCGIWMODE - SIOCIWFIRST] = (iw_handler) ray_get_mode,
+ [SIOCGIWRANGE - SIOCIWFIRST] = (iw_handler) ray_get_range,
#ifdef WIRELESS_SPY
- [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
- [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
- [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
- [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
-#endif /* WIRELESS_SPY */
- [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) ray_get_wap,
- [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid,
- [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid,
- [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) ray_set_rate,
- [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) ray_get_rate,
- [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) ray_set_rts,
- [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) ray_get_rts,
- [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) ray_set_frag,
- [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) ray_get_frag,
+ [SIOCSIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+ [SIOCGIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+ [SIOCSIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+ [SIOCGIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
+#endif /* WIRELESS_SPY */
+ [SIOCGIWAP - SIOCIWFIRST] = (iw_handler) ray_get_wap,
+ [SIOCSIWESSID - SIOCIWFIRST] = (iw_handler) ray_set_essid,
+ [SIOCGIWESSID - SIOCIWFIRST] = (iw_handler) ray_get_essid,
+ [SIOCSIWRATE - SIOCIWFIRST] = (iw_handler) ray_set_rate,
+ [SIOCGIWRATE - SIOCIWFIRST] = (iw_handler) ray_get_rate,
+ [SIOCSIWRTS - SIOCIWFIRST] = (iw_handler) ray_set_rts,
+ [SIOCGIWRTS - SIOCIWFIRST] = (iw_handler) ray_get_rts,
+ [SIOCSIWFRAG - SIOCIWFIRST] = (iw_handler) ray_set_frag,
+ [SIOCGIWFRAG - SIOCIWFIRST] = (iw_handler) ray_get_frag,
};
-#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
+#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */
#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
-static const iw_handler ray_private_handler[] = {
+static const iw_handler ray_private_handler[] = {
[0] = (iw_handler) ray_set_framing,
[1] = (iw_handler) ray_get_framing,
[3] = (iw_handler) ray_get_country,
};
-static const struct iw_priv_args ray_private_args[] = {
+static const struct iw_priv_args ray_private_args[] = {
/* cmd, set_args, get_args, name */
-{ SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" },
-{ SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" },
-{ SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" },
+ {SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
+ "set_framing"},
+ {SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+ "get_framing"},
+ {SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+ "get_country"},
};
-static const struct iw_handler_def ray_handler_def =
-{
- .num_standard = ARRAY_SIZE(ray_handler),
- .num_private = ARRAY_SIZE(ray_private_handler),
+static const struct iw_handler_def ray_handler_def = {
+ .num_standard = ARRAY_SIZE(ray_handler),
+ .num_private = ARRAY_SIZE(ray_private_handler),
.num_private_args = ARRAY_SIZE(ray_private_args),
- .standard = ray_handler,
- .private = ray_private_handler,
- .private_args = ray_private_args,
+ .standard = ray_handler,
+ .private = ray_private_handler,
+ .private_args = ray_private_args,
.get_wireless_stats = ray_get_wireless_stats,
};
/*===========================================================================*/
static int ray_open(struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link;
- link = local->finder;
-
- DEBUG(1, "ray_open('%s')\n", dev->name);
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link;
+ link = local->finder;
- if (link->open == 0)
- local->num_multi = 0;
- link->open++;
+ DEBUG(1, "ray_open('%s')\n", dev->name);
- /* If the card is not started, time to start it ! - Jean II */
- if(local->card_status == CARD_AWAITING_PARAM) {
- int i;
+ if (link->open == 0)
+ local->num_multi = 0;
+ link->open++;
- DEBUG(1,"ray_open: doing init now !\n");
+ /* If the card is not started, time to start it ! - Jean II */
+ if (local->card_status == CARD_AWAITING_PARAM) {
+ int i;
- /* Download startup parameters */
- if ( (i = dl_startup_params(dev)) < 0)
- {
- printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
- "returns 0x%x\n",i);
- return -1;
- }
- }
-
- if (sniffer) netif_stop_queue(dev);
- else netif_start_queue(dev);
-
- DEBUG(2,"ray_open ending\n");
- return 0;
+ DEBUG(1, "ray_open: doing init now !\n");
+
+ /* Download startup parameters */
+ if ((i = dl_startup_params(dev)) < 0) {
+ printk(KERN_INFO
+ "ray_dev_init dl_startup_params failed - "
+ "returns 0x%x\n", i);
+ return -1;
+ }
+ }
+
+ if (sniffer)
+ netif_stop_queue(dev);
+ else
+ netif_start_queue(dev);
+
+ DEBUG(2, "ray_open ending\n");
+ return 0;
} /* end ray_open */
+
/*===========================================================================*/
static int ray_dev_close(struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link;
- link = local->finder;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link;
+ link = local->finder;
- DEBUG(1, "ray_dev_close('%s')\n", dev->name);
+ DEBUG(1, "ray_dev_close('%s')\n", dev->name);
- link->open--;
- netif_stop_queue(dev);
+ link->open--;
+ netif_stop_queue(dev);
- /* In here, we should stop the hardware (stop card from beeing active)
- * and set local->card_status to CARD_AWAITING_PARAM, so that while the
- * card is closed we can chage its configuration.
- * Probably also need a COR reset to get sane state - Jean II */
+ /* In here, we should stop the hardware (stop card from beeing active)
+ * and set local->card_status to CARD_AWAITING_PARAM, so that while the
+ * card is closed we can chage its configuration.
+ * Probably also need a COR reset to get sane state - Jean II */
- return 0;
+ return 0;
} /* end ray_dev_close */
+
/*===========================================================================*/
-static void ray_reset(struct net_device *dev) {
- DEBUG(1,"ray_reset entered\n");
- return;
+static void ray_reset(struct net_device *dev)
+{
+ DEBUG(1, "ray_reset entered\n");
+ return;
}
+
/*===========================================================================*/
/* Cause a firmware interrupt if it is ready for one */
/* Return nonzero if not ready */
static int interrupt_ecf(ray_dev_t *local, int ccs)
{
- int i = 50;
- struct pcmcia_device *link = local->finder;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
- return -1;
- }
- DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs);
-
- while ( i &&
- (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET))
- i--;
- if (i == 0) {
- DEBUG(2,"ray_cs interrupt_ecf card not ready for interrupt\n");
- return -1;
- }
+ int i = 50;
+ struct pcmcia_device *link = local->finder;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs interrupt_ecf - device not present\n");
+ return -1;
+ }
+ DEBUG(2, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
+
+ while (i &&
+ (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
+ ECF_INTR_SET))
+ i--;
+ if (i == 0) {
+ DEBUG(2, "ray_cs interrupt_ecf card not ready for interrupt\n");
+ return -1;
+ }
/* Fill the mailbox, then kick the card */
- writeb(ccs, local->sram + SCB_BASE);
- writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
- return 0;
+ writeb(ccs, local->sram + SCB_BASE);
+ writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
+ return 0;
} /* interrupt_ecf */
+
/*===========================================================================*/
/* Get next free transmit CCS */
/* Return - index of current tx ccs */
static int get_free_tx_ccs(ray_dev_t *local)
{
- int i;
- struct ccs __iomem *pccs = ccs_base(local);
- struct pcmcia_device *link = local->finder;
+ int i;
+ struct ccs __iomem *pccs = ccs_base(local);
+ struct pcmcia_device *link = local->finder;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
- return ECARDGONE;
- }
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs get_free_tx_ccs - device not present\n");
+ return ECARDGONE;
+ }
- if (test_and_set_bit(0,&local->tx_ccs_lock)) {
- DEBUG(1,"ray_cs tx_ccs_lock busy\n");
- return ECCSBUSY;
- }
+ if (test_and_set_bit(0, &local->tx_ccs_lock)) {
+ DEBUG(1, "ray_cs tx_ccs_lock busy\n");
+ return ECCSBUSY;
+ }
- for (i=0; i < NUMBER_OF_TX_CCS; i++) {
- if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
- writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
- writeb(CCS_END_LIST, &(pccs+i)->link);
+ for (i = 0; i < NUMBER_OF_TX_CCS; i++) {
+ if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
+ writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
+ writeb(CCS_END_LIST, &(pccs + i)->link);
local->tx_ccs_lock = 0;
- return i;
- }
- }
+ return i;
+ }
+ }
local->tx_ccs_lock = 0;
- DEBUG(2,"ray_cs ERROR no free tx CCS for raylink card\n");
- return ECCSFULL;
+ DEBUG(2, "ray_cs ERROR no free tx CCS for raylink card\n");
+ return ECCSFULL;
} /* get_free_tx_ccs */
+
/*===========================================================================*/
/* Get next free CCS */
/* Return - index of current ccs */
static int get_free_ccs(ray_dev_t *local)
{
- int i;
- struct ccs __iomem *pccs = ccs_base(local);
- struct pcmcia_device *link = local->finder;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs get_free_ccs - device not present\n");
- return ECARDGONE;
- }
- if (test_and_set_bit(0,&local->ccs_lock)) {
- DEBUG(1,"ray_cs ccs_lock busy\n");
- return ECCSBUSY;
- }
-
- for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
- if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
- writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
- writeb(CCS_END_LIST, &(pccs+i)->link);
+ int i;
+ struct ccs __iomem *pccs = ccs_base(local);
+ struct pcmcia_device *link = local->finder;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs get_free_ccs - device not present\n");
+ return ECARDGONE;
+ }
+ if (test_and_set_bit(0, &local->ccs_lock)) {
+ DEBUG(1, "ray_cs ccs_lock busy\n");
+ return ECCSBUSY;
+ }
+
+ for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
+ if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
+ writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
+ writeb(CCS_END_LIST, &(pccs + i)->link);
local->ccs_lock = 0;
- return i;
- }
- }
+ return i;
+ }
+ }
local->ccs_lock = 0;
- DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n");
- return ECCSFULL;
+ DEBUG(1, "ray_cs ERROR no free CCS for raylink card\n");
+ return ECCSFULL;
} /* get_free_ccs */
+
/*===========================================================================*/
static void authenticate_timeout(u_long data)
{
- ray_dev_t *local = (ray_dev_t *)data;
- del_timer(&local->timer);
- printk(KERN_INFO "ray_cs Authentication with access point failed"
- " - timeout\n");
- join_net((u_long)local);
+ ray_dev_t *local = (ray_dev_t *) data;
+ del_timer(&local->timer);
+ printk(KERN_INFO "ray_cs Authentication with access point failed"
+ " - timeout\n");
+ join_net((u_long) local);
}
+
/*===========================================================================*/
static int asc_to_int(char a)
{
- if (a < '0') return -1;
- if (a <= '9') return (a - '0');
- if (a < 'A') return -1;
- if (a <= 'F') return (10 + a - 'A');
- if (a < 'a') return -1;
- if (a <= 'f') return (10 + a - 'a');
- return -1;
+ if (a < '0')
+ return -1;
+ if (a <= '9')
+ return (a - '0');
+ if (a < 'A')
+ return -1;
+ if (a <= 'F')
+ return (10 + a - 'A');
+ if (a < 'a')
+ return -1;
+ if (a <= 'f')
+ return (10 + a - 'a');
+ return -1;
}
+
/*===========================================================================*/
static int parse_addr(char *in_str, UCHAR *out)
{
- int len;
- int i,j,k;
- int status;
-
- if (in_str == NULL) return 0;
- if ((len = strlen(in_str)) < 2) return 0;
- memset(out, 0, ADDRLEN);
-
- status = 1;
- j = len - 1;
- if (j > 12) j = 12;
- i = 5;
-
- while (j > 0)
- {
- if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k;
- else return 0;
-
- if (j == 0) break;
- if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4;
- else return 0;
- if (!i--) break;
- }
- return status;
+ int len;
+ int i, j, k;
+ int status;
+
+ if (in_str == NULL)
+ return 0;
+ if ((len = strlen(in_str)) < 2)
+ return 0;
+ memset(out, 0, ADDRLEN);
+
+ status = 1;
+ j = len - 1;
+ if (j > 12)
+ j = 12;
+ i = 5;
+
+ while (j > 0) {
+ if ((k = asc_to_int(in_str[j--])) != -1)
+ out[i] = k;
+ else
+ return 0;
+
+ if (j == 0)
+ break;
+ if ((k = asc_to_int(in_str[j--])) != -1)
+ out[i] += k << 4;
+ else
+ return 0;
+ if (!i--)
+ break;
+ }
+ return status;
}
+
/*===========================================================================*/
static struct net_device_stats *ray_get_stats(struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- struct status __iomem *p = local->sram + STATUS_BASE;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs net_device_stats - device not present\n");
- return &local->stats;
- }
- if (readb(&p->mrx_overflow_for_host))
- {
- local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
- writeb(0,&p->mrx_overflow);
- writeb(0,&p->mrx_overflow_for_host);
- }
- if (readb(&p->mrx_checksum_error_for_host))
- {
- local->stats.rx_crc_errors += swab16(readw(&p->mrx_checksum_error));
- writeb(0,&p->mrx_checksum_error);
- writeb(0,&p->mrx_checksum_error_for_host);
- }
- if (readb(&p->rx_hec_error_for_host))
- {
- local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
- writeb(0,&p->rx_hec_error);
- writeb(0,&p->rx_hec_error_for_host);
- }
- return &local->stats;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ struct status __iomem *p = local->sram + STATUS_BASE;
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs net_device_stats - device not present\n");
+ return &local->stats;
+ }
+ if (readb(&p->mrx_overflow_for_host)) {
+ local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
+ writeb(0, &p->mrx_overflow);
+ writeb(0, &p->mrx_overflow_for_host);
+ }
+ if (readb(&p->mrx_checksum_error_for_host)) {
+ local->stats.rx_crc_errors +=
+ swab16(readw(&p->mrx_checksum_error));
+ writeb(0, &p->mrx_checksum_error);
+ writeb(0, &p->mrx_checksum_error_for_host);
+ }
+ if (readb(&p->rx_hec_error_for_host)) {
+ local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
+ writeb(0, &p->rx_hec_error);
+ writeb(0, &p->rx_hec_error_for_host);
+ }
+ return &local->stats;
}
+
/*===========================================================================*/
-static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
-{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- int ccsindex;
- int i;
- struct ccs __iomem *pccs;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_update_parm - device not present\n");
- return;
- }
-
- if ((ccsindex = get_free_ccs(local)) < 0)
- {
- DEBUG(0,"ray_update_parm - No free ccs\n");
- return;
- }
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
- writeb(objid, &pccs->var.update_param.object_id);
- writeb(1, &pccs->var.update_param.number_objects);
- writeb(0, &pccs->var.update_param.failure_cause);
- for (i=0; i<len; i++) {
- writeb(value[i], local->sram + HOST_TO_ECF_BASE);
- }
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(0,"ray_cs associate failed - ECF not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- }
+static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
+ int len)
+{
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ int ccsindex;
+ int i;
+ struct ccs __iomem *pccs;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_update_parm - device not present\n");
+ return;
+ }
+
+ if ((ccsindex = get_free_ccs(local)) < 0) {
+ DEBUG(0, "ray_update_parm - No free ccs\n");
+ return;
+ }
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
+ writeb(objid, &pccs->var.update_param.object_id);
+ writeb(1, &pccs->var.update_param.number_objects);
+ writeb(0, &pccs->var.update_param.failure_cause);
+ for (i = 0; i < len; i++) {
+ writeb(value[i], local->sram + HOST_TO_ECF_BASE);
+ }
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(0, "ray_cs associate failed - ECF not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ }
}
+
/*===========================================================================*/
static void ray_update_multi_list(struct net_device *dev, int all)
{
- struct dev_mc_list *dmi, **dmip;
- int ccsindex;
- struct ccs __iomem *pccs;
- int i = 0;
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- void __iomem *p = local->sram + HOST_TO_ECF_BASE;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_update_multi_list - device not present\n");
- return;
- }
- else
- DEBUG(2,"ray_update_multi_list(%p)\n",dev);
- if ((ccsindex = get_free_ccs(local)) < 0)
- {
- DEBUG(1,"ray_update_multi - No free ccs\n");
- return;
- }
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
-
- if (all) {
- writeb(0xff, &pccs->var);
- local->num_multi = 0xff;
- }
- else {
- /* Copy the kernel's list of MC addresses to card */
- for (dmip=&dev->mc_list; (dmi=*dmip)!=NULL; dmip=&dmi->next) {
- memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
- DEBUG(1,"ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",dmi->dmi_addr[0],dmi->dmi_addr[1],dmi->dmi_addr[2],dmi->dmi_addr[3],dmi->dmi_addr[4],dmi->dmi_addr[5]);
- p += ETH_ALEN;
- i++;
- }
- if (i > 256/ADDRLEN) i = 256/ADDRLEN;
- writeb((UCHAR)i, &pccs->var);
- DEBUG(1,"ray_cs update_multi %d addresses in list\n", i);
- /* Interrupt the firmware to process the command */
- local->num_multi = i;
- }
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray_cs update_multi failed - ECF not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- }
+ struct dev_mc_list *dmi, **dmip;
+ int ccsindex;
+ struct ccs __iomem *pccs;
+ int i = 0;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ void __iomem *p = local->sram + HOST_TO_ECF_BASE;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_update_multi_list - device not present\n");
+ return;
+ } else
+ DEBUG(2, "ray_update_multi_list(%p)\n", dev);
+ if ((ccsindex = get_free_ccs(local)) < 0) {
+ DEBUG(1, "ray_update_multi - No free ccs\n");
+ return;
+ }
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
+
+ if (all) {
+ writeb(0xff, &pccs->var);
+ local->num_multi = 0xff;
+ } else {
+ /* Copy the kernel's list of MC addresses to card */
+ for (dmip = &dev->mc_list; (dmi = *dmip) != NULL;
+ dmip = &dmi->next) {
+ memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
+ DEBUG(1,
+ "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
+ dmi->dmi_addr[0], dmi->dmi_addr[1],
+ dmi->dmi_addr[2], dmi->dmi_addr[3],
+ dmi->dmi_addr[4], dmi->dmi_addr[5]);
+ p += ETH_ALEN;
+ i++;
+ }
+ if (i > 256 / ADDRLEN)
+ i = 256 / ADDRLEN;
+ writeb((UCHAR) i, &pccs->var);
+ DEBUG(1, "ray_cs update_multi %d addresses in list\n", i);
+ /* Interrupt the firmware to process the command */
+ local->num_multi = i;
+ }
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1,
+ "ray_cs update_multi failed - ECF not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ }
} /* end ray_update_multi_list */
+
/*===========================================================================*/
static void set_multicast_list(struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- UCHAR promisc;
-
- DEBUG(2,"ray_cs set_multicast_list(%p)\n",dev);
-
- if (dev->flags & IFF_PROMISC)
- {
- if (local->sparm.b5.a_promiscuous_mode == 0) {
- DEBUG(1,"ray_cs set_multicast_list promisc on\n");
- local->sparm.b5.a_promiscuous_mode = 1;
- promisc = 1;
- ray_update_parm(dev, OBJID_promiscuous_mode, \
- &promisc, sizeof(promisc));
- }
- }
- else {
- if (local->sparm.b5.a_promiscuous_mode == 1) {
- DEBUG(1,"ray_cs set_multicast_list promisc off\n");
- local->sparm.b5.a_promiscuous_mode = 0;
- promisc = 0;
- ray_update_parm(dev, OBJID_promiscuous_mode, \
- &promisc, sizeof(promisc));
- }
- }
-
- if (dev->flags & IFF_ALLMULTI) ray_update_multi_list(dev, 1);
- else
- {
- if (local->num_multi != dev->mc_count) ray_update_multi_list(dev, 0);
- }
+ ray_dev_t *local = netdev_priv(dev);
+ UCHAR promisc;
+
+ DEBUG(2, "ray_cs set_multicast_list(%p)\n", dev);
+
+ if (dev->flags & IFF_PROMISC) {
+ if (local->sparm.b5.a_promiscuous_mode == 0) {
+ DEBUG(1, "ray_cs set_multicast_list promisc on\n");
+ local->sparm.b5.a_promiscuous_mode = 1;
+ promisc = 1;
+ ray_update_parm(dev, OBJID_promiscuous_mode,
+ &promisc, sizeof(promisc));
+ }
+ } else {
+ if (local->sparm.b5.a_promiscuous_mode == 1) {
+ DEBUG(1, "ray_cs set_multicast_list promisc off\n");
+ local->sparm.b5.a_promiscuous_mode = 0;
+ promisc = 0;
+ ray_update_parm(dev, OBJID_promiscuous_mode,
+ &promisc, sizeof(promisc));
+ }
+ }
+
+ if (dev->flags & IFF_ALLMULTI)
+ ray_update_multi_list(dev, 1);
+ else {
+ if (local->num_multi != dev->mc_count)
+ ray_update_multi_list(dev, 0);
+ }
} /* end set_multicast_list */
+
/*=============================================================================
* All routines below here are run at interrupt time.
=============================================================================*/
static irqreturn_t ray_interrupt(int irq, void *dev_id)
{
- struct net_device *dev = (struct net_device *)dev_id;
- struct pcmcia_device *link;
- ray_dev_t *local;
- struct ccs __iomem *pccs;
- struct rcs __iomem *prcs;
- UCHAR rcsindex;
- UCHAR tmp;
- UCHAR cmd;
- UCHAR status;
-
- if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
- return IRQ_NONE;
-
- DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
-
- local = netdev_priv(dev);
- link = (struct pcmcia_device *)local->finder;
- if (!pcmcia_dev_present(link)) {
- DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
- return IRQ_NONE;
- }
- rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
-
- if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS))
- {
- DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
- clear_interrupt(local);
- return IRQ_HANDLED;
- }
- if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */
- {
- pccs = ccs_base(local) + rcsindex;
- cmd = readb(&pccs->cmd);
- status = readb(&pccs->buffer_status);
- switch (cmd)
- {
- case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
- del_timer(&local->timer);
- if (status == CCS_COMMAND_COMPLETE) {
- DEBUG(1,"ray_cs interrupt download_startup_parameters OK\n");
- }
- else {
- DEBUG(1,"ray_cs interrupt download_startup_parameters fail\n");
- }
- break;
- case CCS_UPDATE_PARAMS:
- DEBUG(1,"ray_cs interrupt update params done\n");
- if (status != CCS_COMMAND_COMPLETE) {
- tmp = readb(&pccs->var.update_param.failure_cause);
- DEBUG(0,"ray_cs interrupt update params failed - reason %d\n",tmp);
- }
- break;
- case CCS_REPORT_PARAMS:
- DEBUG(1,"ray_cs interrupt report params done\n");
- break;
- case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
- DEBUG(1,"ray_cs interrupt CCS Update Multicast List done\n");
- break;
- case CCS_UPDATE_POWER_SAVINGS_MODE:
- DEBUG(1,"ray_cs interrupt update power save mode done\n");
- break;
- case CCS_START_NETWORK:
- case CCS_JOIN_NETWORK:
- if (status == CCS_COMMAND_COMPLETE) {
- if (readb(&pccs->var.start_network.net_initiated) == 1) {
- DEBUG(0,"ray_cs interrupt network \"%s\" started\n",\
- local->sparm.b4.a_current_ess_id);
- }
- else {
- DEBUG(0,"ray_cs interrupt network \"%s\" joined\n",\
- local->sparm.b4.a_current_ess_id);
- }
- memcpy_fromio(&local->bss_id,pccs->var.start_network.bssid,ADDRLEN);
-
- if (local->fw_ver == 0x55) local->net_default_tx_rate = 3;
- else local->net_default_tx_rate =
- readb(&pccs->var.start_network.net_default_tx_rate);
- local->encryption = readb(&pccs->var.start_network.encryption);
- if (!sniffer && (local->net_type == INFRA)
- && !(local->sparm.b4.a_acting_as_ap_status)) {
- authenticate(local);
- }
- local->card_status = CARD_ACQ_COMPLETE;
- }
- else {
- local->card_status = CARD_ACQ_FAILED;
-
- del_timer(&local->timer);
- local->timer.expires = jiffies + HZ*5;
- local->timer.data = (long)local;
- if (status == CCS_START_NETWORK) {
- DEBUG(0,"ray_cs interrupt network \"%s\" start failed\n",\
- local->sparm.b4.a_current_ess_id);
- local->timer.function = &start_net;
- }
- else {
- DEBUG(0,"ray_cs interrupt network \"%s\" join failed\n",\
- local->sparm.b4.a_current_ess_id);
- local->timer.function = &join_net;
- }
- add_timer(&local->timer);
- }
- break;
- case CCS_START_ASSOCIATION:
- if (status == CCS_COMMAND_COMPLETE) {
- local->card_status = CARD_ASSOC_COMPLETE;
- DEBUG(0,"ray_cs association successful\n");
- }
- else
- {
- DEBUG(0,"ray_cs association failed,\n");
- local->card_status = CARD_ASSOC_FAILED;
- join_net((u_long)local);
- }
- break;
- case CCS_TX_REQUEST:
- if (status == CCS_COMMAND_COMPLETE) {
- DEBUG(3,"ray_cs interrupt tx request complete\n");
- }
- else {
- DEBUG(1,"ray_cs interrupt tx request failed\n");
- }
- if (!sniffer) netif_start_queue(dev);
- netif_wake_queue(dev);
- break;
- case CCS_TEST_MEMORY:
- DEBUG(1,"ray_cs interrupt mem test done\n");
- break;
- case CCS_SHUTDOWN:
- DEBUG(1,"ray_cs interrupt Unexpected CCS returned - Shutdown\n");
- break;
- case CCS_DUMP_MEMORY:
- DEBUG(1,"ray_cs interrupt dump memory done\n");
- break;
- case CCS_START_TIMER:
- DEBUG(2,"ray_cs interrupt DING - raylink timer expired\n");
- break;
- default:
- DEBUG(1,"ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",\
- rcsindex, cmd);
- }
- writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
- }
- else /* It's an RCS */
- {
- prcs = rcs_base(local) + rcsindex;
-
- switch (readb(&prcs->interrupt_id))
- {
- case PROCESS_RX_PACKET:
- ray_rx(dev, local, prcs);
- break;
- case REJOIN_NET_COMPLETE:
- DEBUG(1,"ray_cs interrupt rejoin net complete\n");
- local->card_status = CARD_ACQ_COMPLETE;
- /* do we need to clear tx buffers CCS's? */
- if (local->sparm.b4.a_network_type == ADHOC) {
- if (!sniffer) netif_start_queue(dev);
- }
- else {
- memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete.bssid, ADDRLEN);
- DEBUG(1,"ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",\
- local->bss_id[0], local->bss_id[1], local->bss_id[2],\
- local->bss_id[3], local->bss_id[4], local->bss_id[5]);
- if (!sniffer) authenticate(local);
- }
- break;
- case ROAMING_INITIATED:
- DEBUG(1,"ray_cs interrupt roaming initiated\n");
- netif_stop_queue(dev);
- local->card_status = CARD_DOING_ACQ;
- break;
- case JAPAN_CALL_SIGN_RXD:
- DEBUG(1,"ray_cs interrupt japan call sign rx\n");
- break;
- default:
- DEBUG(1,"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",\
- rcsindex, (unsigned int) readb(&prcs->interrupt_id));
- break;
- }
- writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
- }
- clear_interrupt(local);
- return IRQ_HANDLED;
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct pcmcia_device *link;
+ ray_dev_t *local;
+ struct ccs __iomem *pccs;
+ struct rcs __iomem *prcs;
+ UCHAR rcsindex;
+ UCHAR tmp;
+ UCHAR cmd;
+ UCHAR status;
+
+ if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
+ return IRQ_NONE;
+
+ DEBUG(4, "ray_cs: interrupt for *dev=%p\n", dev);
+
+ local = netdev_priv(dev);
+ link = (struct pcmcia_device *)local->finder;
+ if (!pcmcia_dev_present(link)) {
+ DEBUG(2,
+ "ray_cs interrupt from device not present or suspended.\n");
+ return IRQ_NONE;
+ }
+ rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
+
+ if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
+ DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
+ clear_interrupt(local);
+ return IRQ_HANDLED;
+ }
+ if (rcsindex < NUMBER_OF_CCS) { /* If it's a returned CCS */
+ pccs = ccs_base(local) + rcsindex;
+ cmd = readb(&pccs->cmd);
+ status = readb(&pccs->buffer_status);
+ switch (cmd) {
+ case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
+ del_timer(&local->timer);
+ if (status == CCS_COMMAND_COMPLETE) {
+ DEBUG(1,
+ "ray_cs interrupt download_startup_parameters OK\n");
+ } else {
+ DEBUG(1,
+ "ray_cs interrupt download_startup_parameters fail\n");
+ }
+ break;
+ case CCS_UPDATE_PARAMS:
+ DEBUG(1, "ray_cs interrupt update params done\n");
+ if (status != CCS_COMMAND_COMPLETE) {
+ tmp =
+ readb(&pccs->var.update_param.
+ failure_cause);
+ DEBUG(0,
+ "ray_cs interrupt update params failed - reason %d\n",
+ tmp);
+ }
+ break;
+ case CCS_REPORT_PARAMS:
+ DEBUG(1, "ray_cs interrupt report params done\n");
+ break;
+ case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
+ DEBUG(1,
+ "ray_cs interrupt CCS Update Multicast List done\n");
+ break;
+ case CCS_UPDATE_POWER_SAVINGS_MODE:
+ DEBUG(1,
+ "ray_cs interrupt update power save mode done\n");
+ break;
+ case CCS_START_NETWORK:
+ case CCS_JOIN_NETWORK:
+ if (status == CCS_COMMAND_COMPLETE) {
+ if (readb
+ (&pccs->var.start_network.net_initiated) ==
+ 1) {
+ DEBUG(0,
+ "ray_cs interrupt network \"%s\" started\n",
+ local->sparm.b4.a_current_ess_id);
+ } else {
+ DEBUG(0,
+ "ray_cs interrupt network \"%s\" joined\n",
+ local->sparm.b4.a_current_ess_id);
+ }
+ memcpy_fromio(&local->bss_id,
+ pccs->var.start_network.bssid,
+ ADDRLEN);
+
+ if (local->fw_ver == 0x55)
+ local->net_default_tx_rate = 3;
+ else
+ local->net_default_tx_rate =
+ readb(&pccs->var.start_network.
+ net_default_tx_rate);
+ local->encryption =
+ readb(&pccs->var.start_network.encryption);
+ if (!sniffer && (local->net_type == INFRA)
+ && !(local->sparm.b4.a_acting_as_ap_status)) {
+ authenticate(local);
+ }
+ local->card_status = CARD_ACQ_COMPLETE;
+ } else {
+ local->card_status = CARD_ACQ_FAILED;
+
+ del_timer(&local->timer);
+ local->timer.expires = jiffies + HZ * 5;
+ local->timer.data = (long)local;
+ if (status == CCS_START_NETWORK) {
+ DEBUG(0,
+ "ray_cs interrupt network \"%s\" start failed\n",
+ local->sparm.b4.a_current_ess_id);
+ local->timer.function = &start_net;
+ } else {
+ DEBUG(0,
+ "ray_cs interrupt network \"%s\" join failed\n",
+ local->sparm.b4.a_current_ess_id);
+ local->timer.function = &join_net;
+ }
+ add_timer(&local->timer);
+ }
+ break;
+ case CCS_START_ASSOCIATION:
+ if (status == CCS_COMMAND_COMPLETE) {
+ local->card_status = CARD_ASSOC_COMPLETE;
+ DEBUG(0, "ray_cs association successful\n");
+ } else {
+ DEBUG(0, "ray_cs association failed,\n");
+ local->card_status = CARD_ASSOC_FAILED;
+ join_net((u_long) local);
+ }
+ break;
+ case CCS_TX_REQUEST:
+ if (status == CCS_COMMAND_COMPLETE) {
+ DEBUG(3,
+ "ray_cs interrupt tx request complete\n");
+ } else {
+ DEBUG(1,
+ "ray_cs interrupt tx request failed\n");
+ }
+ if (!sniffer)
+ netif_start_queue(dev);
+ netif_wake_queue(dev);
+ break;
+ case CCS_TEST_MEMORY:
+ DEBUG(1, "ray_cs interrupt mem test done\n");
+ break;
+ case CCS_SHUTDOWN:
+ DEBUG(1,
+ "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
+ break;
+ case CCS_DUMP_MEMORY:
+ DEBUG(1, "ray_cs interrupt dump memory done\n");
+ break;
+ case CCS_START_TIMER:
+ DEBUG(2,
+ "ray_cs interrupt DING - raylink timer expired\n");
+ break;
+ default:
+ DEBUG(1,
+ "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
+ rcsindex, cmd);
+ }
+ writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
+ } else { /* It's an RCS */
+
+ prcs = rcs_base(local) + rcsindex;
+
+ switch (readb(&prcs->interrupt_id)) {
+ case PROCESS_RX_PACKET:
+ ray_rx(dev, local, prcs);
+ break;
+ case REJOIN_NET_COMPLETE:
+ DEBUG(1, "ray_cs interrupt rejoin net complete\n");
+ local->card_status = CARD_ACQ_COMPLETE;
+ /* do we need to clear tx buffers CCS's? */
+ if (local->sparm.b4.a_network_type == ADHOC) {
+ if (!sniffer)
+ netif_start_queue(dev);
+ } else {
+ memcpy_fromio(&local->bss_id,
+ prcs->var.rejoin_net_complete.
+ bssid, ADDRLEN);
+ DEBUG(1,
+ "ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",
+ local->bss_id[0], local->bss_id[1],
+ local->bss_id[2], local->bss_id[3],
+ local->bss_id[4], local->bss_id[5]);
+ if (!sniffer)
+ authenticate(local);
+ }
+ break;
+ case ROAMING_INITIATED:
+ DEBUG(1, "ray_cs interrupt roaming initiated\n");
+ netif_stop_queue(dev);
+ local->card_status = CARD_DOING_ACQ;
+ break;
+ case JAPAN_CALL_SIGN_RXD:
+ DEBUG(1, "ray_cs interrupt japan call sign rx\n");
+ break;
+ default:
+ DEBUG(1,
+ "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
+ rcsindex,
+ (unsigned int)readb(&prcs->interrupt_id));
+ break;
+ }
+ writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
+ }
+ clear_interrupt(local);
+ return IRQ_HANDLED;
} /* ray_interrupt */
+
/*===========================================================================*/
-static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs)
-{
- int rx_len;
- unsigned int pkt_addr;
- void __iomem *pmsg;
- DEBUG(4,"ray_rx process rx packet\n");
-
- /* Calculate address of packet within Rx buffer */
- pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
- + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
- /* Length of first packet fragment */
- rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
- + readb(&prcs->var.rx_packet.rx_data_length[1]);
-
- local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
- pmsg = local->rmem + pkt_addr;
- switch(readb(pmsg))
- {
- case DATA_TYPE:
- DEBUG(4,"ray_rx data type\n");
- rx_data(dev, prcs, pkt_addr, rx_len);
- break;
- case AUTHENTIC_TYPE:
- DEBUG(4,"ray_rx authentic type\n");
- if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
- else rx_authenticate(local, prcs, pkt_addr, rx_len);
- break;
- case DEAUTHENTIC_TYPE:
- DEBUG(4,"ray_rx deauth type\n");
- if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
- else rx_deauthenticate(local, prcs, pkt_addr, rx_len);
- break;
- case NULL_MSG_TYPE:
- DEBUG(3,"ray_cs rx NULL msg\n");
- break;
- case BEACON_TYPE:
- DEBUG(4,"ray_rx beacon type\n");
- if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
-
- copy_from_rx_buff(local, (UCHAR *)&local->last_bcn, pkt_addr,
- rx_len < sizeof(struct beacon_rx) ?
- rx_len : sizeof(struct beacon_rx));
-
- local->beacon_rxed = 1;
- /* Get the statistics so the card counters never overflow */
- ray_get_stats(dev);
- break;
- default:
- DEBUG(0,"ray_cs unknown pkt type %2x\n", (unsigned int) readb(pmsg));
- break;
- }
+static void ray_rx(struct net_device *dev, ray_dev_t *local,
+ struct rcs __iomem *prcs)
+{
+ int rx_len;
+ unsigned int pkt_addr;
+ void __iomem *pmsg;
+ DEBUG(4, "ray_rx process rx packet\n");
+
+ /* Calculate address of packet within Rx buffer */
+ pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
+ + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
+ /* Length of first packet fragment */
+ rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
+ + readb(&prcs->var.rx_packet.rx_data_length[1]);
+
+ local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
+ pmsg = local->rmem + pkt_addr;
+ switch (readb(pmsg)) {
+ case DATA_TYPE:
+ DEBUG(4, "ray_rx data type\n");
+ rx_data(dev, prcs, pkt_addr, rx_len);
+ break;
+ case AUTHENTIC_TYPE:
+ DEBUG(4, "ray_rx authentic type\n");
+ if (sniffer)
+ rx_data(dev, prcs, pkt_addr, rx_len);
+ else
+ rx_authenticate(local, prcs, pkt_addr, rx_len);
+ break;
+ case DEAUTHENTIC_TYPE:
+ DEBUG(4, "ray_rx deauth type\n");
+ if (sniffer)
+ rx_data(dev, prcs, pkt_addr, rx_len);
+ else
+ rx_deauthenticate(local, prcs, pkt_addr, rx_len);
+ break;
+ case NULL_MSG_TYPE:
+ DEBUG(3, "ray_cs rx NULL msg\n");
+ break;
+ case BEACON_TYPE:
+ DEBUG(4, "ray_rx beacon type\n");
+ if (sniffer)
+ rx_data(dev, prcs, pkt_addr, rx_len);
+
+ copy_from_rx_buff(local, (UCHAR *) &local->last_bcn, pkt_addr,
+ rx_len < sizeof(struct beacon_rx) ?
+ rx_len : sizeof(struct beacon_rx));
+
+ local->beacon_rxed = 1;
+ /* Get the statistics so the card counters never overflow */
+ ray_get_stats(dev);
+ break;
+ default:
+ DEBUG(0, "ray_cs unknown pkt type %2x\n",
+ (unsigned int)readb(pmsg));
+ break;
+ }
} /* end ray_rx */
+
/*===========================================================================*/
-static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr,
- int rx_len)
-{
- struct sk_buff *skb = NULL;
- struct rcs __iomem *prcslink = prcs;
- ray_dev_t *local = netdev_priv(dev);
- UCHAR *rx_ptr;
- int total_len;
- int tmp;
+static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
+ unsigned int pkt_addr, int rx_len)
+{
+ struct sk_buff *skb = NULL;
+ struct rcs __iomem *prcslink = prcs;
+ ray_dev_t *local = netdev_priv(dev);
+ UCHAR *rx_ptr;
+ int total_len;
+ int tmp;
#ifdef WIRELESS_SPY
- int siglev = local->last_rsl;
- u_char linksrcaddr[ETH_ALEN]; /* Other end of the wireless link */
+ int siglev = local->last_rsl;
+ u_char linksrcaddr[ETH_ALEN]; /* Other end of the wireless link */
#endif
- if (!sniffer) {
- if (translate) {
+ if (!sniffer) {
+ if (translate) {
/* TBD length needs fixing for translated header */
- if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
- rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
- {
- DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
- return;
- }
- }
- else /* encapsulated ethernet */ {
- if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
- rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
- {
- DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
- return;
- }
- }
- }
- DEBUG(4,"ray_cs rx_data packet\n");
- /* If fragmented packet, verify sizes of fragments add up */
- if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
- DEBUG(1,"ray_cs rx'ed fragment\n");
- tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
- + readb(&prcs->var.rx_packet.totalpacketlength[1]);
- total_len = tmp;
- prcslink = prcs;
- do {
- tmp -= (readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
- + readb(&prcslink->var.rx_packet.rx_data_length[1]);
- if (readb(&prcslink->var.rx_packet.next_frag_rcs_index) == 0xFF
- || tmp < 0) break;
- prcslink = rcs_base(local)
- + readb(&prcslink->link_field);
- } while (1);
-
- if (tmp < 0)
- {
- DEBUG(0,"ray_cs rx_data fragment lengths don't add up\n");
- local->stats.rx_dropped++;
- release_frag_chain(local, prcs);
- return;
- }
- }
- else { /* Single unfragmented packet */
- total_len = rx_len;
- }
-
- skb = dev_alloc_skb( total_len+5 );
- if (skb == NULL)
- {
- DEBUG(0,"ray_cs rx_data could not allocate skb\n");
- local->stats.rx_dropped++;
- if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
- release_frag_chain(local, prcs);
- return;
- }
- skb_reserve( skb, 2); /* Align IP on 16 byte (TBD check this)*/
-
- DEBUG(4,"ray_cs rx_data total_len = %x, rx_len = %x\n",total_len,rx_len);
+ if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
+ rx_len >
+ (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
+ FCS_LEN)) {
+ DEBUG(0,
+ "ray_cs invalid packet length %d received \n",
+ rx_len);
+ return;
+ }
+ } else { /* encapsulated ethernet */
+
+ if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
+ rx_len >
+ (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
+ FCS_LEN)) {
+ DEBUG(0,
+ "ray_cs invalid packet length %d received \n",
+ rx_len);
+ return;
+ }
+ }
+ }
+ DEBUG(4, "ray_cs rx_data packet\n");
+ /* If fragmented packet, verify sizes of fragments add up */
+ if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
+ DEBUG(1, "ray_cs rx'ed fragment\n");
+ tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
+ + readb(&prcs->var.rx_packet.totalpacketlength[1]);
+ total_len = tmp;
+ prcslink = prcs;
+ do {
+ tmp -=
+ (readb(&prcslink->var.rx_packet.rx_data_length[0])
+ << 8)
+ + readb(&prcslink->var.rx_packet.rx_data_length[1]);
+ if (readb(&prcslink->var.rx_packet.next_frag_rcs_index)
+ == 0xFF || tmp < 0)
+ break;
+ prcslink = rcs_base(local)
+ + readb(&prcslink->link_field);
+ } while (1);
+
+ if (tmp < 0) {
+ DEBUG(0,
+ "ray_cs rx_data fragment lengths don't add up\n");
+ local->stats.rx_dropped++;
+ release_frag_chain(local, prcs);
+ return;
+ }
+ } else { /* Single unfragmented packet */
+ total_len = rx_len;
+ }
+
+ skb = dev_alloc_skb(total_len + 5);
+ if (skb == NULL) {
+ DEBUG(0, "ray_cs rx_data could not allocate skb\n");
+ local->stats.rx_dropped++;
+ if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
+ release_frag_chain(local, prcs);
+ return;
+ }
+ skb_reserve(skb, 2); /* Align IP on 16 byte (TBD check this) */
+
+ DEBUG(4, "ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
+ rx_len);
/************************/
- /* Reserve enough room for the whole damn packet. */
- rx_ptr = skb_put( skb, total_len);
- /* Copy the whole packet to sk_buff */
- rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
- /* Get source address */
+ /* Reserve enough room for the whole damn packet. */
+ rx_ptr = skb_put(skb, total_len);
+ /* Copy the whole packet to sk_buff */
+ rx_ptr +=
+ copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
+ /* Get source address */
#ifdef WIRELESS_SPY
- skb_copy_from_linear_data_offset(skb, offsetof(struct mac_header, addr_2),
- linksrcaddr, ETH_ALEN);
+ skb_copy_from_linear_data_offset(skb,
+ offsetof(struct mac_header, addr_2),
+ linksrcaddr, ETH_ALEN);
#endif
- /* Now, deal with encapsulation/translation/sniffer */
- if (!sniffer) {
- if (!translate) {
- /* Encapsulated ethernet, so just lop off 802.11 MAC header */
+ /* Now, deal with encapsulation/translation/sniffer */
+ if (!sniffer) {
+ if (!translate) {
+ /* Encapsulated ethernet, so just lop off 802.11 MAC header */
/* TBD reserve skb_reserve( skb, RX_MAC_HEADER_LENGTH); */
- skb_pull( skb, RX_MAC_HEADER_LENGTH);
- }
- else {
- /* Do translation */
- untranslate(local, skb, total_len);
- }
- }
- else
- { /* sniffer mode, so just pass whole packet */ };
+ skb_pull(skb, RX_MAC_HEADER_LENGTH);
+ } else {
+ /* Do translation */
+ untranslate(local, skb, total_len);
+ }
+ } else { /* sniffer mode, so just pass whole packet */
+ };
/************************/
- /* Now pick up the rest of the fragments if any */
- tmp = 17;
- if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
- prcslink = prcs;
- DEBUG(1,"ray_cs rx_data in fragment loop\n");
- do {
- prcslink = rcs_base(local)
- + readb(&prcslink->var.rx_packet.next_frag_rcs_index);
- rx_len = (( readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
- + readb(&prcslink->var.rx_packet.rx_data_length[1]))
- & RX_BUFF_END;
- pkt_addr = (( readb(&prcslink->var.rx_packet.rx_data_ptr[0]) << 8)
- + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
- & RX_BUFF_END;
-
- rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
-
- } while (tmp-- &&
- readb(&prcslink->var.rx_packet.next_frag_rcs_index) != 0xFF);
- release_frag_chain(local, prcs);
- }
-
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- local->stats.rx_packets++;
- local->stats.rx_bytes += total_len;
-
- /* Gather signal strength per address */
+ /* Now pick up the rest of the fragments if any */
+ tmp = 17;
+ if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
+ prcslink = prcs;
+ DEBUG(1, "ray_cs rx_data in fragment loop\n");
+ do {
+ prcslink = rcs_base(local)
+ +
+ readb(&prcslink->var.rx_packet.next_frag_rcs_index);
+ rx_len =
+ ((readb(&prcslink->var.rx_packet.rx_data_length[0])
+ << 8)
+ +
+ readb(&prcslink->var.rx_packet.rx_data_length[1]))
+ & RX_BUFF_END;
+ pkt_addr =
+ ((readb(&prcslink->var.rx_packet.rx_data_ptr[0]) <<
+ 8)
+ + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
+ & RX_BUFF_END;
+
+ rx_ptr +=
+ copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
+
+ } while (tmp-- &&
+ readb(&prcslink->var.rx_packet.next_frag_rcs_index) !=
+ 0xFF);
+ release_frag_chain(local, prcs);
+ }
+
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ local->stats.rx_packets++;
+ local->stats.rx_bytes += total_len;
+
+ /* Gather signal strength per address */
#ifdef WIRELESS_SPY
- /* For the Access Point or the node having started the ad-hoc net
- * note : ad-hoc work only in some specific configurations, but we
- * kludge in ray_get_wireless_stats... */
- if(!memcmp(linksrcaddr, local->bss_id, ETH_ALEN))
- {
- /* Update statistics */
- /*local->wstats.qual.qual = none ? */
- local->wstats.qual.level = siglev;
- /*local->wstats.qual.noise = none ? */
- local->wstats.qual.updated = 0x2;
- }
- /* Now, update the spy stuff */
- {
- struct iw_quality wstats;
- wstats.level = siglev;
- /* wstats.noise = none ? */
- /* wstats.qual = none ? */
- wstats.updated = 0x2;
- /* Update spy records */
- wireless_spy_update(dev, linksrcaddr, &wstats);
- }
-#endif /* WIRELESS_SPY */
+ /* For the Access Point or the node having started the ad-hoc net
+ * note : ad-hoc work only in some specific configurations, but we
+ * kludge in ray_get_wireless_stats... */
+ if (!memcmp(linksrcaddr, local->bss_id, ETH_ALEN)) {
+ /* Update statistics */
+ /*local->wstats.qual.qual = none ? */
+ local->wstats.qual.level = siglev;
+ /*local->wstats.qual.noise = none ? */
+ local->wstats.qual.updated = 0x2;
+ }
+ /* Now, update the spy stuff */
+ {
+ struct iw_quality wstats;
+ wstats.level = siglev;
+ /* wstats.noise = none ? */
+ /* wstats.qual = none ? */
+ wstats.updated = 0x2;
+ /* Update spy records */
+ wireless_spy_update(dev, linksrcaddr, &wstats);
+ }
+#endif /* WIRELESS_SPY */
} /* end rx_data */
+
/*===========================================================================*/
static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
{
- snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
- struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
- __be16 type = *(__be16 *)psnap->ethertype;
- int delta;
- struct ethhdr *peth;
- UCHAR srcaddr[ADDRLEN];
- UCHAR destaddr[ADDRLEN];
- static UCHAR org_bridge[3] = {0, 0, 0xf8};
- static UCHAR org_1042[3] = {0, 0, 0};
+ snaphdr_t *psnap = (snaphdr_t *) (skb->data + RX_MAC_HEADER_LENGTH);
+ struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
+ __be16 type = *(__be16 *) psnap->ethertype;
+ int delta;
+ struct ethhdr *peth;
+ UCHAR srcaddr[ADDRLEN];
+ UCHAR destaddr[ADDRLEN];
+ static UCHAR org_bridge[3] = { 0, 0, 0xf8 };
+ static UCHAR org_1042[3] = { 0, 0, 0 };
- memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
- memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
+ memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
+ memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
#ifdef PCMCIA_DEBUG
- if (pc_debug > 3) {
- int i;
- printk(KERN_DEBUG "skb->data before untranslate");
- for (i=0;i<64;i++)
- printk("%02x ",skb->data[i]);
- printk("\n" KERN_DEBUG "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
- ntohs(type),
- psnap->dsap, psnap->ssap, psnap->ctrl,
- psnap->org[0], psnap->org[1], psnap->org[2]);
- printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data);
- }
+ if (pc_debug > 3) {
+ int i;
+ printk(KERN_DEBUG "skb->data before untranslate");
+ for (i = 0; i < 64; i++)
+ printk("%02x ", skb->data[i]);
+ printk("\n" KERN_DEBUG
+ "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
+ ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,
+ psnap->org[0], psnap->org[1], psnap->org[2]);
+ printk(KERN_DEBUG "untranslate skb->data = %p\n", skb->data);
+ }
#endif
- if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
- /* not a snap type so leave it alone */
- DEBUG(3,"ray_cs untranslate NOT SNAP %02x %02x %02x\n",
- psnap->dsap, psnap->ssap, psnap->ctrl);
-
- delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
- }
- else { /* Its a SNAP */
- if (memcmp(psnap->org, org_bridge, 3) == 0) { /* EtherII and nuke the LLC */
- DEBUG(3,"ray_cs untranslate Bridge encap\n");
- delta = RX_MAC_HEADER_LENGTH
- + sizeof(struct snaphdr_t) - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = type;
- } else if (memcmp(psnap->org, org_1042, 3) == 0) {
- switch (ntohs(type)) {
- case ETH_P_IPX:
- case ETH_P_AARP:
- DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n");
- delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
- break;
- default:
- DEBUG(3,"ray_cs untranslate RFC default\n");
- delta = RX_MAC_HEADER_LENGTH +
- sizeof(struct snaphdr_t) - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = type;
- break;
- }
- } else {
- printk("ray_cs untranslate very confused by packet\n");
- delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = type;
+ if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
+ /* not a snap type so leave it alone */
+ DEBUG(3, "ray_cs untranslate NOT SNAP %02x %02x %02x\n",
+ psnap->dsap, psnap->ssap, psnap->ctrl);
+
+ delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
+ } else { /* Its a SNAP */
+ if (memcmp(psnap->org, org_bridge, 3) == 0) {
+ /* EtherII and nuke the LLC */
+ DEBUG(3, "ray_cs untranslate Bridge encap\n");
+ delta = RX_MAC_HEADER_LENGTH
+ + sizeof(struct snaphdr_t) - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto = type;
+ } else if (memcmp(psnap->org, org_1042, 3) == 0) {
+ switch (ntohs(type)) {
+ case ETH_P_IPX:
+ case ETH_P_AARP:
+ DEBUG(3, "ray_cs untranslate RFC IPX/AARP\n");
+ delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto =
+ htons(len - RX_MAC_HEADER_LENGTH);
+ break;
+ default:
+ DEBUG(3, "ray_cs untranslate RFC default\n");
+ delta = RX_MAC_HEADER_LENGTH +
+ sizeof(struct snaphdr_t) - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto = type;
+ break;
+ }
+ } else {
+ printk("ray_cs untranslate very confused by packet\n");
+ delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto = type;
+ }
}
- }
/* TBD reserve skb_reserve(skb, delta); */
- skb_pull(skb, delta);
- DEBUG(3,"untranslate after skb_pull(%d), skb->data = %p\n",delta,skb->data);
- memcpy(peth->h_dest, destaddr, ADDRLEN);
- memcpy(peth->h_source, srcaddr, ADDRLEN);
+ skb_pull(skb, delta);
+ DEBUG(3, "untranslate after skb_pull(%d), skb->data = %p\n", delta,
+ skb->data);
+ memcpy(peth->h_dest, destaddr, ADDRLEN);
+ memcpy(peth->h_source, srcaddr, ADDRLEN);
#ifdef PCMCIA_DEBUG
- if (pc_debug > 3) {
- int i;
- printk(KERN_DEBUG "skb->data after untranslate:");
- for (i=0;i<64;i++)
- printk("%02x ",skb->data[i]);
- printk("\n");
- }
+ if (pc_debug > 3) {
+ int i;
+ printk(KERN_DEBUG "skb->data after untranslate:");
+ for (i = 0; i < 64; i++)
+ printk("%02x ", skb->data[i]);
+ printk("\n");
+ }
#endif
} /* end untranslate */
+
/*===========================================================================*/
/* Copy data from circular receive buffer to PC memory.
* dest = destination address in PC memory
* pkt_addr = source address in receive buffer
* len = length of packet to copy
*/
-static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length)
-{
- int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
- if (wrap_bytes <= 0)
- {
- memcpy_fromio(dest,local->rmem + pkt_addr,length);
- }
- else /* Packet wrapped in circular buffer */
- {
- memcpy_fromio(dest,local->rmem+pkt_addr,length - wrap_bytes);
- memcpy_fromio(dest + length - wrap_bytes, local->rmem, wrap_bytes);
- }
- return length;
+static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr,
+ int length)
+{
+ int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
+ if (wrap_bytes <= 0) {
+ memcpy_fromio(dest, local->rmem + pkt_addr, length);
+ } else { /* Packet wrapped in circular buffer */
+
+ memcpy_fromio(dest, local->rmem + pkt_addr,
+ length - wrap_bytes);
+ memcpy_fromio(dest + length - wrap_bytes, local->rmem,
+ wrap_bytes);
+ }
+ return length;
}
+
/*===========================================================================*/
-static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs)
-{
- struct rcs __iomem *prcslink = prcs;
- int tmp = 17;
- unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
-
- while (tmp--) {
- writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
- if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
- DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
- break;
- }
- prcslink = rcs_base(local) + rcsindex;
- rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
- }
- writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
+static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
+{
+ struct rcs __iomem *prcslink = prcs;
+ int tmp = 17;
+ unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
+
+ while (tmp--) {
+ writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
+ if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
+ DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n",
+ rcsindex);
+ break;
+ }
+ prcslink = rcs_base(local) + rcsindex;
+ rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
+ }
+ writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
}
+
/*===========================================================================*/
static void authenticate(ray_dev_t *local)
{
- struct pcmcia_device *link = local->finder;
- DEBUG(0,"ray_cs Starting authentication.\n");
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs authenticate - device not present\n");
- return;
- }
-
- del_timer(&local->timer);
- if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
- local->timer.function = &join_net;
- }
- else {
- local->timer.function = &authenticate_timeout;
- }
- local->timer.expires = jiffies + HZ*2;
- local->timer.data = (long)local;
- add_timer(&local->timer);
- local->authentication_state = AWAITING_RESPONSE;
+ struct pcmcia_device *link = local->finder;
+ DEBUG(0, "ray_cs Starting authentication.\n");
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs authenticate - device not present\n");
+ return;
+ }
+
+ del_timer(&local->timer);
+ if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
+ local->timer.function = &join_net;
+ } else {
+ local->timer.function = &authenticate_timeout;
+ }
+ local->timer.expires = jiffies + HZ * 2;
+ local->timer.data = (long)local;
+ add_timer(&local->timer);
+ local->authentication_state = AWAITING_RESPONSE;
} /* end authenticate */
+
/*===========================================================================*/
static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
- unsigned int pkt_addr, int rx_len)
-{
- UCHAR buff[256];
- struct rx_msg *msg = (struct rx_msg *)buff;
-
- del_timer(&local->timer);
-
- copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
- /* if we are trying to get authenticated */
- if (local->sparm.b4.a_network_type == ADHOC) {
- DEBUG(1,"ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", msg->var[0],msg->var[1],msg->var[2],msg->var[3],msg->var[4],msg->var[5]);
- if (msg->var[2] == 1) {
- DEBUG(0,"ray_cs Sending authentication response.\n");
- if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
- local->authentication_state = NEED_TO_AUTH;
- memcpy(local->auth_id, msg->mac.addr_2, ADDRLEN);
- }
- }
- }
- else /* Infrastructure network */
- {
- if (local->authentication_state == AWAITING_RESPONSE) {
- /* Verify authentication sequence #2 and success */
- if (msg->var[2] == 2) {
- if ((msg->var[3] | msg->var[4]) == 0) {
- DEBUG(1,"Authentication successful\n");
- local->card_status = CARD_AUTH_COMPLETE;
- associate(local);
- local->authentication_state = AUTHENTICATED;
- }
- else {
- DEBUG(0,"Authentication refused\n");
- local->card_status = CARD_AUTH_REFUSED;
- join_net((u_long)local);
- local->authentication_state = UNAUTHENTICATED;
- }
- }
- }
- }
+ unsigned int pkt_addr, int rx_len)
+{
+ UCHAR buff[256];
+ struct rx_msg *msg = (struct rx_msg *)buff;
+
+ del_timer(&local->timer);
+
+ copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
+ /* if we are trying to get authenticated */
+ if (local->sparm.b4.a_network_type == ADHOC) {
+ DEBUG(1, "ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
+ msg->var[0], msg->var[1], msg->var[2], msg->var[3],
+ msg->var[4], msg->var[5]);
+ if (msg->var[2] == 1) {
+ DEBUG(0, "ray_cs Sending authentication response.\n");
+ if (!build_auth_frame
+ (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
+ local->authentication_state = NEED_TO_AUTH;
+ memcpy(local->auth_id, msg->mac.addr_2,
+ ADDRLEN);
+ }
+ }
+ } else { /* Infrastructure network */
+
+ if (local->authentication_state == AWAITING_RESPONSE) {
+ /* Verify authentication sequence #2 and success */
+ if (msg->var[2] == 2) {
+ if ((msg->var[3] | msg->var[4]) == 0) {
+ DEBUG(1, "Authentication successful\n");
+ local->card_status = CARD_AUTH_COMPLETE;
+ associate(local);
+ local->authentication_state =
+ AUTHENTICATED;
+ } else {
+ DEBUG(0, "Authentication refused\n");
+ local->card_status = CARD_AUTH_REFUSED;
+ join_net((u_long) local);
+ local->authentication_state =
+ UNAUTHENTICATED;
+ }
+ }
+ }
+ }
} /* end rx_authenticate */
+
/*===========================================================================*/
static void associate(ray_dev_t *local)
{
- struct ccs __iomem *pccs;
- struct pcmcia_device *link = local->finder;
- struct net_device *dev = link->priv;
- int ccsindex;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs associate - device not present\n");
- return;
- }
- /* If no tx buffers available, return*/
- if ((ccsindex = get_free_ccs(local)) < 0)
- {
+ struct ccs __iomem *pccs;
+ struct pcmcia_device *link = local->finder;
+ struct net_device *dev = link->priv;
+ int ccsindex;
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs associate - device not present\n");
+ return;
+ }
+ /* If no tx buffers available, return */
+ if ((ccsindex = get_free_ccs(local)) < 0) {
/* TBD should never be here but... what if we are? */
- DEBUG(1,"ray_cs associate - No free ccs\n");
- return;
- }
- DEBUG(1,"ray_cs Starting association with access point\n");
- pccs = ccs_base(local) + ccsindex;
- /* fill in the CCS */
- writeb(CCS_START_ASSOCIATION, &pccs->cmd);
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray_cs associate failed - ECF not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-
- del_timer(&local->timer);
- local->timer.expires = jiffies + HZ*2;
- local->timer.data = (long)local;
- local->timer.function = &join_net;
- add_timer(&local->timer);
- local->card_status = CARD_ASSOC_FAILED;
- return;
- }
- if (!sniffer) netif_start_queue(dev);
+ DEBUG(1, "ray_cs associate - No free ccs\n");
+ return;
+ }
+ DEBUG(1, "ray_cs Starting association with access point\n");
+ pccs = ccs_base(local) + ccsindex;
+ /* fill in the CCS */
+ writeb(CCS_START_ASSOCIATION, &pccs->cmd);
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1, "ray_cs associate failed - ECF not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+
+ del_timer(&local->timer);
+ local->timer.expires = jiffies + HZ * 2;
+ local->timer.data = (long)local;
+ local->timer.function = &join_net;
+ add_timer(&local->timer);
+ local->card_status = CARD_ASSOC_FAILED;
+ return;
+ }
+ if (!sniffer)
+ netif_start_queue(dev);
} /* end associate */
+
/*===========================================================================*/
-static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
- unsigned int pkt_addr, int rx_len)
+static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
+ unsigned int pkt_addr, int rx_len)
{
/* UCHAR buff[256];
struct rx_msg *msg = (struct rx_msg *)buff;
*/
- DEBUG(0,"Deauthentication frame received\n");
- local->authentication_state = UNAUTHENTICATED;
- /* Need to reauthenticate or rejoin depending on reason code */
+ DEBUG(0, "Deauthentication frame received\n");
+ local->authentication_state = UNAUTHENTICATED;
+ /* Need to reauthenticate or rejoin depending on reason code */
/* copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
*/
}
+
/*===========================================================================*/
static void clear_interrupt(ray_dev_t *local)
{
- writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
+ writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
}
+
/*===========================================================================*/
#ifdef CONFIG_PROC_FS
#define MAXDATA (PAGE_SIZE - 80)
static char *card_status[] = {
- "Card inserted - uninitialized", /* 0 */
- "Card not downloaded", /* 1 */
- "Waiting for download parameters", /* 2 */
- "Card doing acquisition", /* 3 */
- "Acquisition complete", /* 4 */
- "Authentication complete", /* 5 */
- "Association complete", /* 6 */
- "???", "???", "???", "???", /* 7 8 9 10 undefined */
- "Card init error", /* 11 */
- "Download parameters error", /* 12 */
- "???", /* 13 */
- "Acquisition failed", /* 14 */
- "Authentication refused", /* 15 */
- "Association failed" /* 16 */
+ "Card inserted - uninitialized", /* 0 */
+ "Card not downloaded", /* 1 */
+ "Waiting for download parameters", /* 2 */
+ "Card doing acquisition", /* 3 */
+ "Acquisition complete", /* 4 */
+ "Authentication complete", /* 5 */
+ "Association complete", /* 6 */
+ "???", "???", "???", "???", /* 7 8 9 10 undefined */
+ "Card init error", /* 11 */
+ "Download parameters error", /* 12 */
+ "???", /* 13 */
+ "Acquisition failed", /* 14 */
+ "Authentication refused", /* 15 */
+ "Association failed" /* 16 */
};
-static char *nettype[] = {"Adhoc", "Infra "};
-static char *framing[] = {"Encapsulation", "Translation"}
+static char *nettype[] = { "Adhoc", "Infra " };
+static char *framing[] = { "Encapsulation", "Translation" }
+
;
/*===========================================================================*/
static int ray_cs_proc_show(struct seq_file *m, void *v)
{
/* Print current values which are not available via other means
- * eg ifconfig
+ * eg ifconfig
*/
- int i;
- struct pcmcia_device *link;
- struct net_device *dev;
- ray_dev_t *local;
- UCHAR *p;
- struct freq_hop_element *pfh;
- UCHAR c[33];
-
- link = this_device;
- if (!link)
- return 0;
- dev = (struct net_device *)link->priv;
- if (!dev)
- return 0;
- local = netdev_priv(dev);
- if (!local)
- return 0;
-
- seq_puts(m, "Raylink Wireless LAN driver status\n");
- seq_printf(m, "%s\n", rcsid);
- /* build 4 does not report version, and field is 0x55 after memtest */
- seq_puts(m, "Firmware version = ");
- if (local->fw_ver == 0x55)
- seq_puts(m, "4 - Use dump_cis for more details\n");
- else
- seq_printf(m, "%2d.%02d.%02d\n",
- local->fw_ver, local->fw_bld, local->fw_var);
-
- for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i];
- c[32] = 0;
- seq_printf(m, "%s network ESSID = \"%s\"\n",
- nettype[local->sparm.b5.a_network_type], c);
-
- p = local->bss_id;
- seq_printf(m, "BSSID = %pM\n", p);
-
- seq_printf(m, "Country code = %d\n",
- local->sparm.b5.a_curr_country_code);
-
- i = local->card_status;
- if (i < 0) i = 10;
- if (i > 16) i = 10;
- seq_printf(m, "Card status = %s\n", card_status[i]);
-
- seq_printf(m, "Framing mode = %s\n",framing[translate]);
-
- seq_printf(m, "Last pkt signal lvl = %d\n", local->last_rsl);
-
- if (local->beacon_rxed) {
- /* Pull some fields out of last beacon received */
- seq_printf(m, "Beacon Interval = %d Kus\n",
- local->last_bcn.beacon_intvl[0]
- + 256 * local->last_bcn.beacon_intvl[1]);
-
- p = local->last_bcn.elements;
- if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2;
- else {
- seq_printf(m, "Parse beacon failed at essid element id = %d\n",p[0]);
- return 0;
- }
-
- if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
- seq_puts(m, "Supported rate codes = ");
- for (i=2; i<p[1] + 2; i++)
- seq_printf(m, "0x%02x ", p[i]);
- seq_putc(m, '\n');
- p += p[1] + 2;
- }
- else {
- seq_puts(m, "Parse beacon failed at rates element\n");
- return 0;
- }
-
- if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
- pfh = (struct freq_hop_element *)p;
- seq_printf(m, "Hop dwell = %d Kus\n",
- pfh->dwell_time[0] + 256 * pfh->dwell_time[1]);
- seq_printf(m, "Hop set = %d \n", pfh->hop_set);
- seq_printf(m, "Hop pattern = %d \n", pfh->hop_pattern);
- seq_printf(m, "Hop index = %d \n", pfh->hop_index);
- p += p[1] + 2;
- }
- else {
- seq_puts(m, "Parse beacon failed at FH param element\n");
- return 0;
+ int i;
+ struct pcmcia_device *link;
+ struct net_device *dev;
+ ray_dev_t *local;
+ UCHAR *p;
+ struct freq_hop_element *pfh;
+ UCHAR c[33];
+
+ link = this_device;
+ if (!link)
+ return 0;
+ dev = (struct net_device *)link->priv;
+ if (!dev)
+ return 0;
+ local = netdev_priv(dev);
+ if (!local)
+ return 0;
+
+ seq_puts(m, "Raylink Wireless LAN driver status\n");
+ seq_printf(m, "%s\n", rcsid);
+ /* build 4 does not report version, and field is 0x55 after memtest */
+ seq_puts(m, "Firmware version = ");
+ if (local->fw_ver == 0x55)
+ seq_puts(m, "4 - Use dump_cis for more details\n");
+ else
+ seq_printf(m, "%2d.%02d.%02d\n",
+ local->fw_ver, local->fw_bld, local->fw_var);
+
+ for (i = 0; i < 32; i++)
+ c[i] = local->sparm.b5.a_current_ess_id[i];
+ c[32] = 0;
+ seq_printf(m, "%s network ESSID = \"%s\"\n",
+ nettype[local->sparm.b5.a_network_type], c);
+
+ p = local->bss_id;
+ seq_printf(m, "BSSID = %pM\n", p);
+
+ seq_printf(m, "Country code = %d\n",
+ local->sparm.b5.a_curr_country_code);
+
+ i = local->card_status;
+ if (i < 0)
+ i = 10;
+ if (i > 16)
+ i = 10;
+ seq_printf(m, "Card status = %s\n", card_status[i]);
+
+ seq_printf(m, "Framing mode = %s\n", framing[translate]);
+
+ seq_printf(m, "Last pkt signal lvl = %d\n", local->last_rsl);
+
+ if (local->beacon_rxed) {
+ /* Pull some fields out of last beacon received */
+ seq_printf(m, "Beacon Interval = %d Kus\n",
+ local->last_bcn.beacon_intvl[0]
+ + 256 * local->last_bcn.beacon_intvl[1]);
+
+ p = local->last_bcn.elements;
+ if (p[0] == C_ESSID_ELEMENT_ID)
+ p += p[1] + 2;
+ else {
+ seq_printf(m,
+ "Parse beacon failed at essid element id = %d\n",
+ p[0]);
+ return 0;
+ }
+
+ if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
+ seq_puts(m, "Supported rate codes = ");
+ for (i = 2; i < p[1] + 2; i++)
+ seq_printf(m, "0x%02x ", p[i]);
+ seq_putc(m, '\n');
+ p += p[1] + 2;
+ } else {
+ seq_puts(m, "Parse beacon failed at rates element\n");
+ return 0;
+ }
+
+ if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
+ pfh = (struct freq_hop_element *)p;
+ seq_printf(m, "Hop dwell = %d Kus\n",
+ pfh->dwell_time[0] +
+ 256 * pfh->dwell_time[1]);
+ seq_printf(m, "Hop set = %d \n",
+ pfh->hop_set);
+ seq_printf(m, "Hop pattern = %d \n",
+ pfh->hop_pattern);
+ seq_printf(m, "Hop index = %d \n",
+ pfh->hop_index);
+ p += p[1] + 2;
+ } else {
+ seq_puts(m,
+ "Parse beacon failed at FH param element\n");
+ return 0;
+ }
+ } else {
+ seq_puts(m, "No beacons received\n");
}
- } else {
- seq_puts(m, "No beacons received\n");
- }
- return 0;
+ return 0;
}
static int ray_cs_proc_open(struct inode *inode, struct file *file)
@@ -2684,74 +2806,77 @@ static int ray_cs_proc_open(struct inode *inode, struct file *file)
}
static const struct file_operations ray_cs_proc_fops = {
- .owner = THIS_MODULE,
- .open = ray_cs_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .owner = THIS_MODULE,
+ .open = ray_cs_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
#endif
/*===========================================================================*/
static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
{
- int addr;
- struct ccs __iomem *pccs;
- struct tx_msg __iomem *ptx;
- int ccsindex;
-
- /* If no tx buffers available, return */
- if ((ccsindex = get_free_tx_ccs(local)) < 0)
- {
- DEBUG(1,"ray_cs send authenticate - No free tx ccs\n");
- return -1;
- }
-
- pccs = ccs_base(local) + ccsindex;
-
- /* Address in card space */
- addr = TX_BUF_BASE + (ccsindex << 11);
- /* fill in the CCS */
- writeb(CCS_TX_REQUEST, &pccs->cmd);
- writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
- writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
- writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
- writeb(TX_AUTHENTICATE_LENGTH_LSB,pccs->var.tx_request.tx_data_length + 1);
- writeb(0, &pccs->var.tx_request.pow_sav_mode);
-
- ptx = local->sram + addr;
- /* fill in the mac header */
- writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
- writeb(0, &ptx->mac.frame_ctl_2);
-
- memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
- memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
- memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
-
- /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
- memset_io(ptx->var, 0, 6);
- writeb(auth_type & 0xff, ptx->var + 2);
-
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray_cs send authentication request failed - ECF not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- return -1;
- }
- return 0;
+ int addr;
+ struct ccs __iomem *pccs;
+ struct tx_msg __iomem *ptx;
+ int ccsindex;
+
+ /* If no tx buffers available, return */
+ if ((ccsindex = get_free_tx_ccs(local)) < 0) {
+ DEBUG(1, "ray_cs send authenticate - No free tx ccs\n");
+ return -1;
+ }
+
+ pccs = ccs_base(local) + ccsindex;
+
+ /* Address in card space */
+ addr = TX_BUF_BASE + (ccsindex << 11);
+ /* fill in the CCS */
+ writeb(CCS_TX_REQUEST, &pccs->cmd);
+ writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
+ writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
+ writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
+ writeb(TX_AUTHENTICATE_LENGTH_LSB,
+ pccs->var.tx_request.tx_data_length + 1);
+ writeb(0, &pccs->var.tx_request.pow_sav_mode);
+
+ ptx = local->sram + addr;
+ /* fill in the mac header */
+ writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
+ writeb(0, &ptx->mac.frame_ctl_2);
+
+ memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
+
+ /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
+ memset_io(ptx->var, 0, 6);
+ writeb(auth_type & 0xff, ptx->var + 2);
+
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1,
+ "ray_cs send authentication request failed - ECF not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ return -1;
+ }
+ return 0;
} /* End build_auth_frame */
/*===========================================================================*/
#ifdef CONFIG_PROC_FS
static void raycs_write(const char *name, write_proc_t *w, void *data)
{
- struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
+ struct proc_dir_entry *entry =
+ create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
if (entry) {
entry->write_proc = w;
entry->data = data;
}
}
-static int write_essid(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int write_essid(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
{
static char proc_essid[33];
int len = count;
@@ -2765,7 +2890,8 @@ static int write_essid(struct file *file, const char __user *buffer, unsigned lo
return count;
}
-static int write_int(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int write_int(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
{
static char proc_number[10];
char *p;
@@ -2785,7 +2911,7 @@ static int write_int(struct file *file, const char __user *buffer, unsigned long
unsigned int c = *p - '0';
if (c > 9)
return -EINVAL;
- nr = nr*10 + c;
+ nr = nr * 10 + c;
p++;
} while (--len);
*(int *)data = nr;
@@ -2797,55 +2923,58 @@ static struct pcmcia_device_id ray_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
PCMCIA_DEVICE_NULL,
};
+
MODULE_DEVICE_TABLE(pcmcia, ray_ids);
static struct pcmcia_driver ray_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "ray_cs",
- },
- .probe = ray_probe,
- .remove = ray_detach,
- .id_table = ray_ids,
- .suspend = ray_suspend,
- .resume = ray_resume,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "ray_cs",
+ },
+ .probe = ray_probe,
+ .remove = ray_detach,
+ .id_table = ray_ids,
+ .suspend = ray_suspend,
+ .resume = ray_resume,
};
static int __init init_ray_cs(void)
{
- int rc;
-
- DEBUG(1, "%s\n", rcsid);
- rc = pcmcia_register_driver(&ray_driver);
- DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
+ int rc;
+
+ DEBUG(1, "%s\n", rcsid);
+ rc = pcmcia_register_driver(&ray_driver);
+ DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",
+ rc);
#ifdef CONFIG_PROC_FS
- proc_mkdir("driver/ray_cs", NULL);
+ proc_mkdir("driver/ray_cs", NULL);
- proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops);
- raycs_write("driver/ray_cs/essid", write_essid, NULL);
- raycs_write("driver/ray_cs/net_type", write_int, &net_type);
- raycs_write("driver/ray_cs/translate", write_int, &translate);
+ proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops);
+ raycs_write("driver/ray_cs/essid", write_essid, NULL);
+ raycs_write("driver/ray_cs/net_type", write_int, &net_type);
+ raycs_write("driver/ray_cs/translate", write_int, &translate);
#endif
- if (translate != 0) translate = 1;
- return 0;
+ if (translate != 0)
+ translate = 1;
+ return 0;
} /* init_ray_cs */
/*===========================================================================*/
static void __exit exit_ray_cs(void)
{
- DEBUG(0, "ray_cs: cleanup_module\n");
+ DEBUG(0, "ray_cs: cleanup_module\n");
#ifdef CONFIG_PROC_FS
- remove_proc_entry("driver/ray_cs/ray_cs", NULL);
- remove_proc_entry("driver/ray_cs/essid", NULL);
- remove_proc_entry("driver/ray_cs/net_type", NULL);
- remove_proc_entry("driver/ray_cs/translate", NULL);
- remove_proc_entry("driver/ray_cs", NULL);
+ remove_proc_entry("driver/ray_cs/ray_cs", NULL);
+ remove_proc_entry("driver/ray_cs/essid", NULL);
+ remove_proc_entry("driver/ray_cs/net_type", NULL);
+ remove_proc_entry("driver/ray_cs/translate", NULL);
+ remove_proc_entry("driver/ray_cs", NULL);
#endif
- pcmcia_unregister_driver(&ray_driver);
+ pcmcia_unregister_driver(&ray_driver);
} /* exit_ray_cs */
module_init(init_ray_cs);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 607ce9f61b5..db91db77650 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -90,44 +90,44 @@ MODULE_PARM_DESC(workaround_interval,
/* various RNDIS OID defs */
-#define OID_GEN_LINK_SPEED ccpu2(0x00010107)
-#define OID_GEN_RNDIS_CONFIG_PARAMETER ccpu2(0x0001021b)
-
-#define OID_GEN_XMIT_OK ccpu2(0x00020101)
-#define OID_GEN_RCV_OK ccpu2(0x00020102)
-#define OID_GEN_XMIT_ERROR ccpu2(0x00020103)
-#define OID_GEN_RCV_ERROR ccpu2(0x00020104)
-#define OID_GEN_RCV_NO_BUFFER ccpu2(0x00020105)
-
-#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
-#define OID_802_3_CURRENT_ADDRESS ccpu2(0x01010102)
-#define OID_802_3_MULTICAST_LIST ccpu2(0x01010103)
-#define OID_802_3_MAXIMUM_LIST_SIZE ccpu2(0x01010104)
-
-#define OID_802_11_BSSID ccpu2(0x0d010101)
-#define OID_802_11_SSID ccpu2(0x0d010102)
-#define OID_802_11_INFRASTRUCTURE_MODE ccpu2(0x0d010108)
-#define OID_802_11_ADD_WEP ccpu2(0x0d010113)
-#define OID_802_11_REMOVE_WEP ccpu2(0x0d010114)
-#define OID_802_11_DISASSOCIATE ccpu2(0x0d010115)
-#define OID_802_11_AUTHENTICATION_MODE ccpu2(0x0d010118)
-#define OID_802_11_PRIVACY_FILTER ccpu2(0x0d010119)
-#define OID_802_11_BSSID_LIST_SCAN ccpu2(0x0d01011a)
-#define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b)
-#define OID_802_11_ADD_KEY ccpu2(0x0d01011d)
-#define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e)
-#define OID_802_11_ASSOCIATION_INFORMATION ccpu2(0x0d01011f)
-#define OID_802_11_PMKID ccpu2(0x0d010123)
-#define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203)
-#define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204)
-#define OID_802_11_TX_POWER_LEVEL ccpu2(0x0d010205)
-#define OID_802_11_RSSI ccpu2(0x0d010206)
-#define OID_802_11_RSSI_TRIGGER ccpu2(0x0d010207)
-#define OID_802_11_FRAGMENTATION_THRESHOLD ccpu2(0x0d010209)
-#define OID_802_11_RTS_THRESHOLD ccpu2(0x0d01020a)
-#define OID_802_11_SUPPORTED_RATES ccpu2(0x0d01020e)
-#define OID_802_11_CONFIGURATION ccpu2(0x0d010211)
-#define OID_802_11_BSSID_LIST ccpu2(0x0d010217)
+#define OID_GEN_LINK_SPEED cpu_to_le32(0x00010107)
+#define OID_GEN_RNDIS_CONFIG_PARAMETER cpu_to_le32(0x0001021b)
+
+#define OID_GEN_XMIT_OK cpu_to_le32(0x00020101)
+#define OID_GEN_RCV_OK cpu_to_le32(0x00020102)
+#define OID_GEN_XMIT_ERROR cpu_to_le32(0x00020103)
+#define OID_GEN_RCV_ERROR cpu_to_le32(0x00020104)
+#define OID_GEN_RCV_NO_BUFFER cpu_to_le32(0x00020105)
+
+#define OID_802_3_PERMANENT_ADDRESS cpu_to_le32(0x01010101)
+#define OID_802_3_CURRENT_ADDRESS cpu_to_le32(0x01010102)
+#define OID_802_3_MULTICAST_LIST cpu_to_le32(0x01010103)
+#define OID_802_3_MAXIMUM_LIST_SIZE cpu_to_le32(0x01010104)
+
+#define OID_802_11_BSSID cpu_to_le32(0x0d010101)
+#define OID_802_11_SSID cpu_to_le32(0x0d010102)
+#define OID_802_11_INFRASTRUCTURE_MODE cpu_to_le32(0x0d010108)
+#define OID_802_11_ADD_WEP cpu_to_le32(0x0d010113)
+#define OID_802_11_REMOVE_WEP cpu_to_le32(0x0d010114)
+#define OID_802_11_DISASSOCIATE cpu_to_le32(0x0d010115)
+#define OID_802_11_AUTHENTICATION_MODE cpu_to_le32(0x0d010118)
+#define OID_802_11_PRIVACY_FILTER cpu_to_le32(0x0d010119)
+#define OID_802_11_BSSID_LIST_SCAN cpu_to_le32(0x0d01011a)
+#define OID_802_11_ENCRYPTION_STATUS cpu_to_le32(0x0d01011b)
+#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d)
+#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e)
+#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f)
+#define OID_802_11_PMKID cpu_to_le32(0x0d010123)
+#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203)
+#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204)
+#define OID_802_11_TX_POWER_LEVEL cpu_to_le32(0x0d010205)
+#define OID_802_11_RSSI cpu_to_le32(0x0d010206)
+#define OID_802_11_RSSI_TRIGGER cpu_to_le32(0x0d010207)
+#define OID_802_11_FRAGMENTATION_THRESHOLD cpu_to_le32(0x0d010209)
+#define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a)
+#define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e)
+#define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211)
+#define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217)
/* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
@@ -144,8 +144,8 @@ MODULE_PARM_DESC(workaround_interval,
/* codes for "status" field of completion messages */
-#define RNDIS_STATUS_ADAPTER_NOT_READY ccpu2(0xc0010011)
-#define RNDIS_STATUS_ADAPTER_NOT_OPEN ccpu2(0xc0010012)
+#define RNDIS_STATUS_ADAPTER_NOT_READY cpu_to_le32(0xc0010011)
+#define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012)
/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
@@ -369,9 +369,6 @@ struct rndis_wext_private {
};
-static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
@@ -445,7 +442,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
memset(u.get, 0, sizeof *u.get);
u.get->msg_type = RNDIS_MSG_QUERY;
- u.get->msg_len = ccpu2(sizeof *u.get);
+ u.get->msg_len = cpu_to_le32(sizeof *u.get);
u.get->oid = oid;
ret = rndis_command(dev, u.header, buflen);
@@ -494,8 +491,8 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
u.set->oid = oid;
u.set->len = cpu_to_le32(len);
- u.set->offset = ccpu2(sizeof(*u.set) - 8);
- u.set->handle = ccpu2(0);
+ u.set->offset = cpu_to_le32(sizeof(*u.set) - 8);
+ u.set->handle = cpu_to_le32(0);
memcpy(u.buf + sizeof(*u.set), data, len);
ret = rndis_command(dev, u.header, buflen);
@@ -640,8 +637,8 @@ static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
{
if (freq->m < 1000 && freq->e == 0) {
- if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan))
- *dsconfig = freq_chan[freq->m - 1] * 1000;
+ if (freq->m >= 1 && freq->m <= 14)
+ *dsconfig = ieee80211_dsss_chan_to_freq(freq->m) * 1000;
else
return -1;
} else {
@@ -1178,11 +1175,11 @@ static int rndis_iw_get_range(struct net_device *dev,
range->throughput = 11 * 1000 * 1000 / 2;
}
- range->num_channels = ARRAY_SIZE(freq_chan);
+ range->num_channels = 14;
- for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) {
+ for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) {
range->freq[i].i = i + 1;
- range->freq[i].m = freq_chan[i] * 100000;
+ range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
range->freq[i].e = 1;
}
range->num_frequency = i;
@@ -1633,7 +1630,7 @@ static int rndis_iw_set_scan(struct net_device *dev,
devdbg(usbdev, "SIOCSIWSCAN");
if (wrqu->data.flags == 0) {
- tmp = ccpu2(1);
+ tmp = cpu_to_le32(1);
ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
sizeof(tmp));
evt.data.flags = 0;
@@ -1649,9 +1646,7 @@ static char *rndis_translate_scan(struct net_device *dev,
char *end_buf,
struct ndis_80211_bssid_ex *bssid)
{
-#ifdef DEBUG
struct usbnet *usbdev = netdev_priv(dev);
-#endif
u8 *ie;
char *current_val;
int bssid_len, ie_len, i;
@@ -2433,7 +2428,7 @@ static void rndis_update_wireless_stats(struct work_struct *work)
/* Send scan OID. Use of both OIDs is required to get device
* working.
*/
- tmp = ccpu2(1);
+ tmp = cpu_to_le32(1);
rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
sizeof(tmp));
@@ -2529,6 +2524,17 @@ static int bcm4320_early_init(struct usbnet *usbdev)
return 0;
}
+/* same as rndis_netdev_ops but with local multicast handler */
+static const struct net_device_ops rndis_wext_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,
+};
+
static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
{
@@ -2564,7 +2570,8 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
* rndis_host wants to avoid all OID as much as possible
* so do promisc/multicast handling in rndis_wext.
*/
- usbdev->net->set_multicast_list = rndis_wext_set_multicast_list;
+ usbdev->net->netdev_ops = &rndis_wext_netdev_ops;
+
tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
sizeof(tmp));
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 178b313293b..bfc5d9cf716 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -97,10 +97,11 @@ config RT2X00_LIB_CRYPTO
config RT2X00_LIB_RFKILL
boolean
- default y if (RT2X00_LIB=y && RFKILL=y) || (RT2X00_LIB=m && RFKILL!=n)
+ default y if (RT2X00_LIB=y && INPUT=y) || (RT2X00_LIB=m && INPUT!=n)
+ select INPUT_POLLDEV
-comment "rt2x00 rfkill support disabled due to modularized RFKILL and built-in rt2x00"
- depends on RT2X00_LIB=y && RFKILL=m
+comment "rt2x00 rfkill support disabled due to modularized INPUT and built-in rt2x00"
+ depends on RT2X00_LIB=y && INPUT=m
config RT2X00_LIB_LEDS
boolean
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index 917cb4f3b03..f22d808d8c5 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -2,6 +2,7 @@ rt2x00lib-y += rt2x00dev.o
rt2x00lib-y += rt2x00mac.o
rt2x00lib-y += rt2x00config.o
rt2x00lib-y += rt2x00queue.o
+rt2x00lib-y += rt2x00link.o
rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o
rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 6a977679124..0f08773328c 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -114,9 +114,6 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -524,6 +521,32 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, CSR12, reg);
}
+static void rt2400pci_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) {
+ rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
+ rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
+ (libconf->conf->beacon_int - 20) * 16);
+ rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
+ libconf->conf->listen_interval - 1);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+
+ rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
+ rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+ }
+
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -537,6 +560,8 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
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);
}
static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev,
@@ -572,35 +597,37 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = bbp;
}
-static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
{
- rt2400pci_bbp_write(rt2x00dev, 13, 0x08);
- rt2x00dev->link.vgc_level = 0x08;
+ rt2400pci_bbp_write(rt2x00dev, 13, vgc_level);
+ qual->vgc_level = vgc_level;
+ qual->vgc_level_reg = vgc_level;
}
-static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
- u8 reg;
+ rt2400pci_set_vgc(rt2x00dev, qual, 0x08);
+}
+static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
+{
/*
* The link tuner should not run longer then 60 seconds,
* and should run once every 2 seconds.
*/
- if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1))
+ if (count > 60 || !(count & 1))
return;
/*
* Base r13 link tuning on the false cca count.
*/
- rt2400pci_bbp_read(rt2x00dev, 13, &reg);
-
- if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
- rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
- rt2x00dev->link.vgc_level = reg;
- } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
- rt2400pci_bbp_write(rt2x00dev, 13, --reg);
- rt2x00dev->link.vgc_level = reg;
- }
+ if ((qual->false_cca > 512) && (qual->vgc_level < 0x20))
+ rt2400pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level);
+ else if ((qual->false_cca < 100) && (qual->vgc_level > 0x08))
+ rt2400pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
}
/*
@@ -904,21 +931,10 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev)
static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
-
- rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
-
- /*
- * Disable synchronisation.
- */
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
/*
- * Cancel RX and TX.
+ * Disable power
*/
- rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
}
static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -1115,6 +1131,20 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
+static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ u32 reg;
+
+ if (qid == QID_BEACON) {
+ rt2x00pci_register_write(rt2x00dev, CSR14, 0);
+ } else {
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ }
+}
+
/*
* RX control handlers
*/
@@ -1365,7 +1395,9 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
- if (value == LED_MODE_TXRX_ACTIVITY)
+ if (value == LED_MODE_TXRX_ACTIVITY ||
+ value == LED_MODE_DEFAULT ||
+ value == LED_MODE_ASUS)
rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2X00_LIB_LEDS */
@@ -1419,7 +1451,9 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
* Initialize all hw fields.
*/
rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = 0;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
@@ -1572,6 +1606,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data,
.write_beacon = rt2400pci_write_beacon,
.kick_tx_queue = rt2400pci_kick_tx_queue,
+ .kill_tx_queue = rt2400pci_kill_tx_queue,
.fill_rxdone = rt2400pci_fill_rxdone,
.config_filter = rt2400pci_config_filter,
.config_intf = rt2400pci_config_intf,
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index 9aefda4ab3c..ec3b004ddc3 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -48,8 +48,8 @@
#define EEPROM_SIZE 0x0100
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0020
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0010
+#define RF_BASE 0x0004
+#define RF_SIZE 0x000c
/*
* Number of TX queues.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index d3bc218ec85..276a8232aaa 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -114,9 +114,6 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -573,6 +570,32 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, CSR12, reg);
}
+static void rt2500pci_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) {
+ rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
+ rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
+ (libconf->conf->beacon_int - 20) * 16);
+ rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
+ libconf->conf->listen_interval - 1);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+
+ rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
+ rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+ }
+
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -588,6 +611,8 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
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);
}
/*
@@ -611,29 +636,33 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
}
-static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
{
- rt2500pci_bbp_write(rt2x00dev, 17, 0x48);
- rt2x00dev->link.vgc_level = 0x48;
+ if (qual->vgc_level_reg != vgc_level) {
+ rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
+ qual->vgc_level_reg = vgc_level;
+ }
}
-static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
+ rt2500pci_set_vgc(rt2x00dev, qual, 0x48);
+}
+static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
+{
/*
* To prevent collisions with MAC ASIC on chipsets
* up to version C the link tuning should halt after 20
* seconds while being associated.
*/
if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
- rt2x00dev->intf_associated &&
- rt2x00dev->link.count > 20)
+ rt2x00dev->intf_associated && count > 20)
return;
- rt2500pci_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Chipset versions C and lower should directly continue
* to the dynamic CCA tuning. Chipset version D and higher
@@ -649,29 +678,25 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* then corrupt the R17 tuning. To remidy this the tuning should
* be stopped (While making sure the R17 value will not exceed limits)
*/
- if (rssi < -80 && rt2x00dev->link.count > 20) {
- if (r17 >= 0x41) {
- r17 = rt2x00dev->link.vgc_level;
- rt2500pci_bbp_write(rt2x00dev, 17, r17);
- }
+ if (qual->rssi < -80 && count > 20) {
+ if (qual->vgc_level_reg >= 0x41)
+ rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
return;
}
/*
* Special big-R17 for short distance
*/
- if (rssi >= -58) {
- if (r17 != 0x50)
- rt2500pci_bbp_write(rt2x00dev, 17, 0x50);
+ if (qual->rssi >= -58) {
+ rt2500pci_set_vgc(rt2x00dev, qual, 0x50);
return;
}
/*
* Special mid-R17 for middle distance
*/
- if (rssi >= -74) {
- if (r17 != 0x41)
- rt2500pci_bbp_write(rt2x00dev, 17, 0x41);
+ if (qual->rssi >= -74) {
+ rt2500pci_set_vgc(rt2x00dev, qual, 0x41);
return;
}
@@ -679,8 +704,8 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Leave short or middle distance condition, restore r17
* to the dynamic tuning range.
*/
- if (r17 >= 0x41) {
- rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level);
+ if (qual->vgc_level_reg >= 0x41) {
+ rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
return;
}
@@ -690,12 +715,12 @@ dynamic_cca_tune:
* R17 is inside the dynamic tuning range,
* start tuning the link based on the false cca counter.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) {
- rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
- rt2x00dev->link.vgc_level = r17;
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
- rt2500pci_bbp_write(rt2x00dev, 17, --r17);
- rt2x00dev->link.vgc_level = r17;
+ if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40) {
+ rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg);
+ qual->vgc_level = qual->vgc_level_reg;
+ } else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32) {
+ rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg);
+ qual->vgc_level = qual->vgc_level_reg;
}
}
@@ -1065,21 +1090,10 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev)
static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
-
- rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
-
- /*
- * Disable synchronisation.
- */
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
/*
- * Cancel RX and TX.
+ * Disable power
*/
- rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
}
static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -1205,7 +1219,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
- test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+ (txdesc->rate_mode == RATE_MODE_OFDM));
rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1);
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
@@ -1275,6 +1289,20 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
+static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ u32 reg;
+
+ if (qid == QID_BEACON) {
+ rt2x00pci_register_write(rt2x00dev, CSR14, 0);
+ } else {
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ }
+}
+
/*
* RX control handlers
*/
@@ -1524,7 +1552,9 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
- if (value == LED_MODE_TXRX_ACTIVITY)
+ if (value == LED_MODE_TXRX_ACTIVITY ||
+ value == LED_MODE_DEFAULT ||
+ value == LED_MODE_ASUS)
rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2X00_LIB_LEDS */
@@ -1721,7 +1751,9 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
* Initialize all hw fields.
*/
rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = 0;
@@ -1873,6 +1905,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data,
.write_beacon = rt2500pci_write_beacon,
.kick_tx_queue = rt2500pci_kick_tx_queue,
+ .kill_tx_queue = rt2500pci_kill_tx_queue,
.fill_rxdone = rt2500pci_fill_rxdone,
.config_filter = rt2500pci_config_filter,
.config_intf = rt2500pci_config_intf,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index e135247f7f8..ce2f065c748 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -59,8 +59,8 @@
#define EEPROM_SIZE 0x0200
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0040
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0014
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
/*
* Number of TX queues.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index af6b5847be5..9e630e70fc9 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -204,9 +204,6 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
{
u16 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -280,6 +277,18 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = {
};
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+ u16 reg;
+
+ rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
+ return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
+}
+#else
+#define rt2500usb_rfkill_poll NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
#ifdef CONFIG_RT2X00_LIB_LEDS
static void rt2500usb_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
@@ -634,6 +643,32 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
}
+static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ enum dev_state state =
+ (libconf->conf->flags & IEEE80211_CONF_PS) ?
+ STATE_SLEEP : STATE_AWAKE;
+ u16 reg;
+
+ 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);
+ rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP,
+ libconf->conf->listen_interval - 1);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 0);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
+
+ rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 1);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
+ }
+
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -647,6 +682,8 @@ static void rt2500usb_config(struct rt2x00_dev *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);
}
/*
@@ -670,7 +707,8 @@ static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
}
-static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
u16 eeprom;
u16 value;
@@ -691,7 +729,7 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_VGCUPPER);
rt2500usb_bbp_write(rt2x00dev, 17, value);
- rt2x00dev->link.vgc_level = value;
+ qual->vgc_level = value;
}
/*
@@ -1176,7 +1214,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
- test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+ (txdesc->rate_mode == RATE_MODE_OFDM));
rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
@@ -1562,12 +1600,22 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
- if (value == LED_MODE_TXRX_ACTIVITY)
+ if (value == LED_MODE_TXRX_ACTIVITY ||
+ value == LED_MODE_DEFAULT ||
+ value == LED_MODE_ASUS)
rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual,
LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2X00_LIB_LEDS */
/*
+ * Detect if this device has an hardware controlled radio.
+ */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+ /*
* Check if the BBP tuning should be disabled.
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
@@ -1752,7 +1800,9 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->flags =
IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
@@ -1839,7 +1889,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
if (!modparam_nohwcrypt) {
__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
- __set_bit(CONFIG_CRYPTO_COPY_IV, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
}
__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);
@@ -1873,6 +1923,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.uninitialize = rt2x00usb_uninitialize,
.clear_entry = rt2x00usb_clear_entry,
.set_device_state = rt2500usb_set_device_state,
+ .rfkill_poll = rt2500usb_rfkill_poll,
.link_stats = rt2500usb_link_stats,
.reset_tuner = rt2500usb_reset_tuner,
.link_tuner = rt2500usb_link_tuner,
@@ -1881,6 +1932,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.write_beacon = rt2500usb_write_beacon,
.get_tx_data_len = rt2500usb_get_tx_data_len,
.kick_tx_queue = rt2500usb_kick_tx_queue,
+ .kill_tx_queue = rt2x00usb_kill_tx_queue,
.fill_rxdone = rt2500usb_fill_rxdone,
.config_shared_key = rt2500usb_config_key,
.config_pairwise_key = rt2500usb_config_key,
@@ -1952,6 +2004,8 @@ static struct usb_device_id rt2500usb_device_table[] = {
{ USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) },
+ /* CNet */
+ { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt2500usb_ops) },
/* Conceptronic */
{ USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) },
/* D-LINK */
@@ -1976,14 +2030,20 @@ static struct usb_device_id rt2500usb_device_table[] = {
{ USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt2500usb_ops) },
{ USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
+ /* Sagem */
+ { USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) },
/* Siemens */
{ USB_DEVICE(0x0681, 0x3c06), USB_DEVICE_DATA(&rt2500usb_ops) },
/* SMC */
{ USB_DEVICE(0x0707, 0xee13), USB_DEVICE_DATA(&rt2500usb_ops) },
/* Spairon */
{ USB_DEVICE(0x114b, 0x0110), USB_DEVICE_DATA(&rt2500usb_ops) },
+ /* SURECOM */
+ { USB_DEVICE(0x0769, 0x11f3), USB_DEVICE_DATA(&rt2500usb_ops) },
/* Trust */
{ USB_DEVICE(0x0eb0, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
+ /* VTech */
+ { USB_DEVICE(0x0f88, 0x3012), USB_DEVICE_DATA(&rt2500usb_ops) },
/* Zinwell */
{ USB_DEVICE(0x5a57, 0x0260), USB_DEVICE_DATA(&rt2500usb_ops) },
{ 0, }
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 4347dfdabcd..5bc46fe7217 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -59,8 +59,8 @@
#define EEPROM_SIZE 0x006a
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0060
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0014
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
/*
* Number of TX queues.
@@ -189,6 +189,14 @@
* MAC_CSR19: GPIO control register.
*/
#define MAC_CSR19 0x0426
+#define MAC_CSR19_BIT0 FIELD32(0x0001)
+#define MAC_CSR19_BIT1 FIELD32(0x0002)
+#define MAC_CSR19_BIT2 FIELD32(0x0004)
+#define MAC_CSR19_BIT3 FIELD32(0x0008)
+#define MAC_CSR19_BIT4 FIELD32(0x0010)
+#define MAC_CSR19_BIT5 FIELD32(0x0020)
+#define MAC_CSR19_BIT6 FIELD32(0x0040)
+#define MAC_CSR19_BIT7 FIELD32(0x0080)
/*
* MAC_CSR20: LED control register.
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 39ecf3b82ca..84bd6f19acb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -33,6 +33,7 @@
#include <linux/leds.h>
#include <linux/mutex.h>
#include <linux/etherdevice.h>
+#include <linux/input-polldev.h>
#include <net/mac80211.h>
@@ -44,7 +45,7 @@
/*
* Module information.
*/
-#define DRV_VERSION "2.2.3"
+#define DRV_VERSION "2.3.0"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
@@ -177,52 +178,41 @@ struct antenna_setup {
*/
struct link_qual {
/*
- * Statistics required for Link tuning.
- * For the average RSSI value we use the "Walking average" approach.
- * When adding RSSI to the average value the following calculation
- * is needed:
- *
- * avg_rssi = ((avg_rssi * 7) + rssi) / 8;
- *
- * The advantage of this approach is that we only need 1 variable
- * to store the average in (No need for a count and a total).
- * But more importantly, normal average values will over time
- * move less and less towards newly added values this results
- * that with link tuning, the device can have a very good RSSI
- * for a few minutes but when the device is moved away from the AP
- * the average will not decrease fast enough to compensate.
- * The walking average compensates this and will move towards
- * the new values correctly allowing a effective link tuning.
+ * Statistics required for Link tuning by driver
+ * The rssi value is provided by rt2x00lib during the
+ * link_tuner() callback function.
+ * The false_cca field is filled during the link_stats()
+ * callback function and could be used during the
+ * link_tuner() callback function.
*/
- int avg_rssi;
+ int rssi;
int false_cca;
/*
- * Statistics required for Signal quality calculation.
- * For calculating the Signal quality we have to determine
- * the total number of success and failed RX and TX frames.
- * After that we also use the average RSSI value to help
- * determining the signal quality.
- * For the calculation we will use the following algorithm:
- *
- * rssi_percentage = (avg_rssi * 100) / rssi_offset
- * rx_percentage = (rx_success * 100) / rx_total
- * tx_percentage = (tx_success * 100) / tx_total
- * avg_signal = ((WEIGHT_RSSI * avg_rssi) +
- * (WEIGHT_TX * tx_percentage) +
- * (WEIGHT_RX * rx_percentage)) / 100
+ * VGC levels
+ * Hardware driver will tune the VGC level during each call
+ * to the link_tuner() callback function. This vgc_level is
+ * is determined based on the link quality statistics like
+ * average RSSI and the false CCA count.
*
- * This value should then be checked to not be greated then 100.
+ * In some cases the drivers need to differentiate between
+ * the currently "desired" VGC level and the level configured
+ * in the hardware. The latter is important to reduce the
+ * number of BBP register reads to reduce register access
+ * overhead. For this reason we store both values here.
+ */
+ u8 vgc_level;
+ u8 vgc_level_reg;
+
+ /*
+ * Statistics required for Signal quality calculation.
+ * These fields might be changed during the link_stats()
+ * callback function.
*/
- int rx_percentage;
int rx_success;
int rx_failed;
- int tx_percentage;
int tx_success;
int tx_failed;
-#define WEIGHT_RSSI 20
-#define WEIGHT_RX 40
-#define WEIGHT_TX 40
};
/*
@@ -286,9 +276,16 @@ struct link {
struct link_ant ant;
/*
- * Active VGC level
+ * Currently active average RSSI value
*/
- int vgc_level;
+ int avg_rssi;
+
+ /*
+ * Currently precalculated percentages of successful
+ * TX and RX frames.
+ */
+ int rx_percentage;
+ int tx_percentage;
/*
* Work structure for scheduling periodic link tuning.
@@ -297,55 +294,6 @@ struct link {
};
/*
- * Small helper macro to work with moving/walking averages.
- */
-#define MOVING_AVERAGE(__avg, __val, __samples) \
- ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
-
-/*
- * When we lack RSSI information return something less then -80 to
- * tell the driver to tune the device to maximum sensitivity.
- */
-#define DEFAULT_RSSI ( -128 )
-
-/*
- * Link quality access functions.
- */
-static inline int rt2x00_get_link_rssi(struct link *link)
-{
- if (link->qual.avg_rssi && link->qual.rx_success)
- return link->qual.avg_rssi;
- return DEFAULT_RSSI;
-}
-
-static inline int rt2x00_get_link_ant_rssi(struct link *link)
-{
- if (link->ant.rssi_ant && link->qual.rx_success)
- return link->ant.rssi_ant;
- return DEFAULT_RSSI;
-}
-
-static inline void rt2x00_reset_link_ant_rssi(struct link *link)
-{
- link->ant.rssi_ant = 0;
-}
-
-static inline int rt2x00_get_link_ant_rssi_history(struct link *link,
- enum antenna ant)
-{
- if (link->ant.rssi_history[ant - ANTENNA_A])
- return link->ant.rssi_history[ant - ANTENNA_A];
- return DEFAULT_RSSI;
-}
-
-static inline int rt2x00_update_ant_rssi(struct link *link, int rssi)
-{
- int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A];
- link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi;
- return old_rssi;
-}
-
-/*
* Interface structure
* Per interface configuration details, this structure
* is allocated as the private data for ieee80211_vif.
@@ -448,7 +396,7 @@ struct rt2x00lib_erp {
int ack_timeout;
int ack_consume_time;
- u64 basic_rates;
+ u32 basic_rates;
int slot_time;
@@ -520,9 +468,10 @@ struct rt2x00lib_ops {
*/
int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev);
- u16 (*get_firmware_crc) (const void *data, const size_t len);
- int (*load_firmware) (struct rt2x00_dev *rt2x00dev, const void *data,
- const size_t len);
+ int (*check_firmware) (struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len);
+ int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len);
/*
* Device initialization/deinitialization handlers.
@@ -544,8 +493,10 @@ struct rt2x00lib_ops {
int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev);
void (*link_stats) (struct rt2x00_dev *rt2x00dev,
struct link_qual *qual);
- void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
- void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
+ void (*reset_tuner) (struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual);
+ void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count);
/*
* TX control handlers
@@ -558,6 +509,8 @@ struct rt2x00lib_ops {
int (*get_tx_data_len) (struct queue_entry *entry);
void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid queue);
+ void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid queue);
/*
* RX control handlers
@@ -625,7 +578,6 @@ enum rt2x00_flags {
DEVICE_STATE_REGISTERED_HW,
DEVICE_STATE_INITIALIZED,
DEVICE_STATE_STARTED,
- DEVICE_STATE_STARTED_SUSPEND,
DEVICE_STATE_ENABLED_RADIO,
DEVICE_STATE_DISABLED_RADIO_HW,
@@ -637,6 +589,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_ATIM_QUEUE,
DRIVER_REQUIRE_SCHEDULED,
DRIVER_REQUIRE_DMA,
+ DRIVER_REQUIRE_COPY_IV,
/*
* Driver features
@@ -653,7 +606,6 @@ enum rt2x00_flags {
CONFIG_EXTERNAL_LNA_BG,
CONFIG_DOUBLE_ANTENNA,
CONFIG_DISABLE_LINK_TUNING,
- CONFIG_CRYPTO_COPY_IV,
};
/*
@@ -689,8 +641,8 @@ struct rt2x00_dev {
unsigned long rfkill_state;
#define RFKILL_STATE_ALLOCATED 1
#define RFKILL_STATE_REGISTERED 2
- struct rfkill *rfkill;
- struct delayed_work rfkill_work;
+#define RFKILL_STATE_BLOCKED 3
+ struct input_polled_dev *rfkill_poll_dev;
#endif /* CONFIG_RT2X00_LIB_RFKILL */
/*
@@ -918,7 +870,7 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip)
return (chipset->rf == chip);
}
-static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset)
+static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset)
{
return chipset->rev;
}
@@ -982,7 +934,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
int mc_count, struct dev_addr_list *mc_list);
#ifdef CONFIG_RT2X00_LIB_CRYPTO
int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key);
#else
#define rt2x00mac_set_key NULL
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index e66fb316cd6..9c2f5517af2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,7 @@
void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
enum nl80211_iftype type,
- u8 *mac, u8 *bssid)
+ const u8 *mac, const u8 *bssid)
{
struct rt2x00intf_conf conf;
unsigned int flags = 0;
@@ -42,6 +42,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
switch (type) {
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_WDS:
conf.sync = TSF_SYNC_BEACON;
break;
case NL80211_IFTYPE_STATION:
@@ -152,8 +154,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
*/
rt2x00dev->ops->lib->config_ant(rt2x00dev, ant);
- rt2x00lib_reset_link_tuner(rt2x00dev);
- rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
+ rt2x00link_reset_tuner(rt2x00dev, true);
memcpy(active, ant, sizeof(*ant));
@@ -191,7 +192,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
* which means we need to reset the link tuner.
*/
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
- rt2x00lib_reset_link_tuner(rt2x00dev);
+ rt2x00link_reset_tuner(rt2x00dev, false);
rt2x00dev->curr_band = conf->channel->band;
rt2x00dev->tx_power = conf->power_level;
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index aee9cba13eb..0b41845d954 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -49,9 +49,14 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
+ if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
+ !hw_key || entry->skb->do_not_encrypt)
+ return;
+
__set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);
txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key);
@@ -69,11 +74,17 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
__set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags);
}
-unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
+unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb)
{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_key_conf *key = tx_info->control.hw_key;
unsigned int overhead = 0;
+ if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
+ !key || skb->do_not_encrypt)
+ return overhead;
+
/*
* Extend frame length to include IV/EIV/ICV/MMIC,
* note that these lengths should only be added when
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 54dd10060bf..07d378ef0b4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -130,9 +130,11 @@ struct rt2x00debug_intf {
};
void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
- enum cipher cipher, enum rx_crypto status)
+ struct rxdone_entry_desc *rxdesc)
{
struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
+ enum cipher cipher = rxdesc->cipher;
+ enum rx_crypto status = rxdesc->cipher_status;
if (cipher == CIPHER_TKIP_NO_MIC)
cipher = CIPHER_TKIP;
@@ -433,11 +435,12 @@ static ssize_t rt2x00debug_read_##__name(struct file *file, \
if (index >= debug->__name.word_count) \
return -EINVAL; \
\
+ index += (debug->__name.word_base / \
+ debug->__name.word_size); \
+ \
if (debug->__name.flags & RT2X00DEBUGFS_OFFSET) \
index *= debug->__name.word_size; \
\
- index += debug->__name.word_base; \
- \
debug->__name.read(intf->rt2x00dev, index, &value); \
\
size = sprintf(line, __format, value); \
@@ -474,11 +477,12 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \
size = strlen(line); \
value = simple_strtoul(line, NULL, 0); \
\
+ index += (debug->__name.word_base / \
+ debug->__name.word_size); \
+ \
if (debug->__name.flags & RT2X00DEBUGFS_OFFSET) \
index *= debug->__name.word_size; \
\
- index += debug->__name.word_base; \
- \
debug->__name.write(intf->rt2x00dev, index, value); \
\
*offset += size; \
@@ -543,9 +547,9 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name,
return NULL;
blob->data = data;
- data += sprintf(data, "driver: %s\n", intf->rt2x00dev->ops->name);
- data += sprintf(data, "version: %s\n", DRV_VERSION);
- data += sprintf(data, "compiled: %s %s\n", __DATE__, __TIME__);
+ data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
+ data += sprintf(data, "version:\t%s\n", DRV_VERSION);
+ data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__);
blob->size = strlen(blob->data);
return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
@@ -566,14 +570,27 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name,
return NULL;
blob->data = data;
- data += sprintf(data, "rt chip: %04x\n", intf->rt2x00dev->chip.rt);
- data += sprintf(data, "rf chip: %04x\n", intf->rt2x00dev->chip.rf);
- data += sprintf(data, "revision:%08x\n", intf->rt2x00dev->chip.rev);
+ data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
+ data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
+ data += sprintf(data, "revision:\t%08x\n", intf->rt2x00dev->chip.rev);
data += sprintf(data, "\n");
- data += sprintf(data, "csr length: %d\n", debug->csr.word_count);
- data += sprintf(data, "eeprom length: %d\n", debug->eeprom.word_count);
- data += sprintf(data, "bbp length: %d\n", debug->bbp.word_count);
- data += sprintf(data, "rf length: %d\n", debug->rf.word_count);
+ data += sprintf(data, "register\tbase\twords\twordsize\n");
+ data += sprintf(data, "csr\t%d\t%d\t%d\n",
+ debug->csr.word_base,
+ debug->csr.word_count,
+ debug->csr.word_size);
+ data += sprintf(data, "eeprom\t%d\t%d\t%d\n",
+ debug->eeprom.word_base,
+ debug->eeprom.word_count,
+ debug->eeprom.word_size);
+ data += sprintf(data, "bbp\t%d\t%d\t%d\n",
+ debug->bbp.word_base,
+ debug->bbp.word_count,
+ debug->bbp.word_size);
+ data += sprintf(data, "rf\t%d\t%d\t%d\n",
+ debug->rf.word_base,
+ debug->rf.word_count,
+ debug->rf.word_size);
blob->size = strlen(blob->data);
return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h
index a92104dfee9..035cbc98c59 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.h
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 87c0f2c8307..05f94e21b42 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -30,60 +30,6 @@
#include "rt2x00lib.h"
/*
- * Link tuning handlers
- */
-void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
- if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- return;
-
- /*
- * Reset link information.
- * Both the currently active vgc level as well as
- * the link tuner counter should be reset. Resetting
- * the counter is important for devices where the
- * device should only perform link tuning during the
- * first minute after being enabled.
- */
- rt2x00dev->link.count = 0;
- rt2x00dev->link.vgc_level = 0;
-
- /*
- * Reset the link tuner.
- */
- rt2x00dev->ops->lib->reset_tuner(rt2x00dev);
-}
-
-static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
- /*
- * Clear all (possibly) pre-existing quality statistics.
- */
- memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual));
-
- /*
- * The RX and TX percentage should start at 50%
- * this will assure we will get at least get some
- * decent value when the link tuner starts.
- * The value will be dropped and overwritten with
- * the correct (measured )value anyway during the
- * first run of the link tuner.
- */
- rt2x00dev->link.qual.rx_percentage = 50;
- rt2x00dev->link.qual.tx_percentage = 50;
-
- rt2x00lib_reset_link_tuner(rt2x00dev);
-
- queue_delayed_work(rt2x00dev->hw->workqueue,
- &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
-}
-
-static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
- cancel_delayed_work_sync(&rt2x00dev->link.work);
-}
-
-/*
* Radio control handlers.
*/
int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
@@ -137,9 +83,10 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Stop the TX queues.
+ * Stop the TX queues in mac80211.
*/
ieee80211_stop_queues(rt2x00dev->hw);
+ rt2x00queue_stop_queues(rt2x00dev);
/*
* Disable RX.
@@ -161,238 +108,15 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
* When we are disabling the RX, we should also stop the link tuner.
*/
if (state == STATE_RADIO_RX_OFF)
- rt2x00lib_stop_link_tuner(rt2x00dev);
+ rt2x00link_stop_tuner(rt2x00dev);
rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
/*
* When we are enabling the RX, we should also start the link tuner.
*/
- if (state == STATE_RADIO_RX_ON &&
- (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count))
- rt2x00lib_start_link_tuner(rt2x00dev);
-}
-
-static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
-{
- struct antenna_setup ant;
- int sample_a =
- rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
- int sample_b =
- rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
-
- memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
-
- /*
- * We are done sampling. Now we should evaluate the results.
- */
- rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
-
- /*
- * During the last period we have sampled the RSSI
- * from both antenna's. It now is time to determine
- * which antenna demonstrated the best performance.
- * When we are already on the antenna with the best
- * performance, then there really is nothing for us
- * left to do.
- */
- if (sample_a == sample_b)
- return;
-
- if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
- ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
-
- if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
- ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
-
- rt2x00lib_config_antenna(rt2x00dev, &ant);
-}
-
-static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
-{
- struct antenna_setup ant;
- int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
- int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
-
- memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
-
- /*
- * Legacy driver indicates that we should swap antenna's
- * when the difference in RSSI is greater that 5. This
- * also should be done when the RSSI was actually better
- * then the previous sample.
- * When the difference exceeds the threshold we should
- * sample the rssi from the other antenna to make a valid
- * comparison between the 2 antennas.
- */
- if (abs(rssi_curr - rssi_old) < 5)
- return;
-
- rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
-
- if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
- ant.rx = (ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
-
- if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
- ant.tx = (ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
-
- rt2x00lib_config_antenna(rt2x00dev, &ant);
-}
-
-static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
-{
- /*
- * Determine if software diversity is enabled for
- * either the TX or RX antenna (or both).
- * Always perform this check since within the link
- * tuner interval the configuration might have changed.
- */
- rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY;
- rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
-
- if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
- rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
- if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
- rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
-
- if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&
- !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) {
- rt2x00dev->link.ant.flags = 0;
- return;
- }
-
- /*
- * If we have only sampled the data over the last period
- * we should now harvest the data. Otherwise just evaluate
- * the data. The latter should only be performed once
- * every 2 seconds.
- */
- if (rt2x00dev->link.ant.flags & ANTENNA_MODE_SAMPLE)
- rt2x00lib_evaluate_antenna_sample(rt2x00dev);
- else if (rt2x00dev->link.count & 1)
- rt2x00lib_evaluate_antenna_eval(rt2x00dev);
-}
-
-static void rt2x00lib_update_link_stats(struct link *link, int rssi)
-{
- int avg_rssi = rssi;
-
- /*
- * Update global RSSI
- */
- if (link->qual.avg_rssi)
- avg_rssi = MOVING_AVERAGE(link->qual.avg_rssi, rssi, 8);
- link->qual.avg_rssi = avg_rssi;
-
- /*
- * Update antenna RSSI
- */
- if (link->ant.rssi_ant)
- rssi = MOVING_AVERAGE(link->ant.rssi_ant, rssi, 8);
- link->ant.rssi_ant = rssi;
-}
-
-static void rt2x00lib_precalculate_link_signal(struct link_qual *qual)
-{
- if (qual->rx_failed || qual->rx_success)
- qual->rx_percentage =
- (qual->rx_success * 100) /
- (qual->rx_failed + qual->rx_success);
- else
- qual->rx_percentage = 50;
-
- if (qual->tx_failed || qual->tx_success)
- qual->tx_percentage =
- (qual->tx_success * 100) /
- (qual->tx_failed + qual->tx_success);
- else
- qual->tx_percentage = 50;
-
- qual->rx_success = 0;
- qual->rx_failed = 0;
- qual->tx_success = 0;
- qual->tx_failed = 0;
-}
-
-static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
- int rssi)
-{
- int rssi_percentage = 0;
- int signal;
-
- /*
- * We need a positive value for the RSSI.
- */
- if (rssi < 0)
- rssi += rt2x00dev->rssi_offset;
-
- /*
- * Calculate the different percentages,
- * which will be used for the signal.
- */
- if (rt2x00dev->rssi_offset)
- rssi_percentage = (rssi * 100) / rt2x00dev->rssi_offset;
-
- /*
- * Add the individual percentages and use the WEIGHT
- * defines to calculate the current link signal.
- */
- signal = ((WEIGHT_RSSI * rssi_percentage) +
- (WEIGHT_TX * rt2x00dev->link.qual.tx_percentage) +
- (WEIGHT_RX * rt2x00dev->link.qual.rx_percentage)) / 100;
-
- return (signal > 100) ? 100 : signal;
-}
-
-static void rt2x00lib_link_tuner(struct work_struct *work)
-{
- struct rt2x00_dev *rt2x00dev =
- container_of(work, struct rt2x00_dev, link.work.work);
-
- /*
- * When the radio is shutting down we should
- * immediately cease all link tuning.
- */
- if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- return;
-
- /*
- * Update statistics.
- */
- rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual);
- rt2x00dev->low_level_stats.dot11FCSErrorCount +=
- rt2x00dev->link.qual.rx_failed;
-
- /*
- * Only perform the link tuning when Link tuning
- * has been enabled (This could have been disabled from the EEPROM).
- */
- if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags))
- rt2x00dev->ops->lib->link_tuner(rt2x00dev);
-
- /*
- * Precalculate a portion of the link signal which is
- * in based on the tx/rx success/failure counters.
- */
- rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
-
- /*
- * Send a signal to the led to update the led signal strength.
- */
- rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi);
-
- /*
- * Evaluate antenna setup, make this the last step since this could
- * possibly reset some statistics.
- */
- rt2x00lib_evaluate_antenna(rt2x00dev);
-
- /*
- * Increase tuner counter, and reschedule the next link tuner run.
- */
- rt2x00dev->link.count++;
- queue_delayed_work(rt2x00dev->hw->workqueue,
- &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
+ if (state == STATE_RADIO_RX_ON)
+ rt2x00link_start_tuner(rt2x00dev);
}
static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
@@ -434,7 +158,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
return;
if (delayed_flags & DELAYED_UPDATE_BEACON)
- rt2x00queue_update_beacon(rt2x00dev, vif);
+ rt2x00queue_update_beacon(rt2x00dev, vif, true);
if (delayed_flags & DELAYED_CONFIG_ERP)
rt2x00lib_config_erp(rt2x00dev, intf, &conf);
@@ -467,7 +191,9 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
struct rt2x00_intf *intf = vif_to_intf(vif);
if (vif->type != NL80211_IFTYPE_AP &&
- vif->type != NL80211_IFTYPE_ADHOC)
+ vif->type != NL80211_IFTYPE_ADHOC &&
+ vif->type != NL80211_IFTYPE_MESH_POINT &&
+ vif->type != NL80211_IFTYPE_WDS)
return;
/*
@@ -490,7 +216,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
rt2x00lib_beacondone_iter,
rt2x00dev);
- schedule_work(&rt2x00dev->intf_work);
+ queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
}
EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
@@ -597,7 +323,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
struct ieee80211_supported_band *sband;
- struct ieee80211_hdr *hdr;
const struct rt2x00_rate *rate;
unsigned int header_length;
unsigned int align;
@@ -668,30 +393,22 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
if (idx < 0) {
WARNING(rt2x00dev, "Frame received with unrecognized signal,"
- "signal=0x%.2x, plcp=%d.\n", rxdesc.signal,
- !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP));
+ "signal=0x%.2x, type=%d.\n", rxdesc.signal,
+ (rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
idx = 0;
}
/*
- * Only update link status if this is a beacon frame carrying our bssid.
+ * Update extra components
*/
- hdr = (struct ieee80211_hdr *)entry->skb->data;
- if (ieee80211_is_beacon(hdr->frame_control) &&
- (rxdesc.dev_flags & RXDONE_MY_BSS))
- rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi);
-
- rt2x00debug_update_crypto(rt2x00dev,
- rxdesc.cipher,
- rxdesc.cipher_status);
-
- rt2x00dev->link.qual.rx_success++;
+ rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
+ rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
rx_status->mactime = rxdesc.timestamp;
rx_status->rate_idx = idx;
- rx_status->qual =
- rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi);
+ rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
rx_status->signal = rxdesc.rssi;
+ rx_status->noise = rxdesc.noise;
rx_status->flag = rxdesc.flags;
rx_status->antenna = rt2x00dev->link.ant.active.rx;
@@ -1067,7 +784,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
if (rt2x00dev->ops->bcn->entry_num > 0)
rt2x00dev->hw->wiphy->interface_modes |=
BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_AP);
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+ BIT(NL80211_IFTYPE_WDS);
/*
* Let the driver probe the device to detect the capabilities.
@@ -1083,7 +802,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
*/
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
- INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
/*
* Allocate queue array.
@@ -1104,6 +822,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
/*
* Register extra components.
*/
+ rt2x00link_register(rt2x00dev);
rt2x00leds_register(rt2x00dev);
rt2x00rfkill_allocate(rt2x00dev);
rt2x00debug_register(rt2x00dev);
@@ -1163,23 +882,17 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
#ifdef CONFIG_PM
int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
{
- int retval;
-
NOTICE(rt2x00dev, "Going to sleep.\n");
/*
- * Only continue if mac80211 has open interfaces.
+ * Prevent mac80211 from accessing driver while suspended.
*/
- if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
- !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
- goto exit;
-
- set_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags);
+ if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ return 0;
/*
- * Disable radio.
+ * Cleanup as much as possible.
*/
- rt2x00lib_stop(rt2x00dev);
rt2x00lib_uninitialize(rt2x00dev);
/*
@@ -1188,7 +901,6 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
rt2x00leds_suspend(rt2x00dev);
rt2x00debug_deregister(rt2x00dev);
-exit:
/*
* Set device mode to sleep for power management,
* on some hardware this call seems to consistently fail.
@@ -1200,8 +912,7 @@ exit:
* the radio and the other components already disabled the
* device is as good as disabled.
*/
- retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP);
- if (retval)
+ if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP))
WARNING(rt2x00dev, "Device failed to enter sleep state, "
"continue suspending.\n");
@@ -1209,32 +920,8 @@ exit:
}
EXPORT_SYMBOL_GPL(rt2x00lib_suspend);
-static void rt2x00lib_resume_intf(void *data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct rt2x00_dev *rt2x00dev = data;
- struct rt2x00_intf *intf = vif_to_intf(vif);
-
- spin_lock(&intf->lock);
-
- rt2x00lib_config_intf(rt2x00dev, intf,
- vif->type, intf->mac, intf->bssid);
-
-
- /*
- * Master or Ad-hoc mode require a new beacon update.
- */
- if (vif->type == NL80211_IFTYPE_AP ||
- vif->type == NL80211_IFTYPE_ADHOC)
- intf->delayed_flags |= DELAYED_UPDATE_BEACON;
-
- spin_unlock(&intf->lock);
-}
-
int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
{
- int retval;
-
NOTICE(rt2x00dev, "Waking up.\n");
/*
@@ -1244,60 +931,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
rt2x00leds_resume(rt2x00dev);
/*
- * Only continue if mac80211 had open interfaces.
- */
- if (!test_and_clear_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags))
- return 0;
-
- /*
- * Reinitialize device and all active interfaces.
- */
- retval = rt2x00lib_start(rt2x00dev);
- if (retval)
- goto exit;
-
- /*
- * Reconfigure device.
- */
- retval = rt2x00mac_config(rt2x00dev->hw, ~0);
- if (retval)
- goto exit;
-
- /*
- * Iterator over each active interface to
- * reconfigure the hardware.
- */
- ieee80211_iterate_active_interfaces(rt2x00dev->hw,
- rt2x00lib_resume_intf, rt2x00dev);
-
- /*
* We are ready again to receive requests from mac80211.
*/
set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
- /*
- * It is possible that during that mac80211 has attempted
- * to send frames while we were suspending or resuming.
- * In that case we have disabled the TX queue and should
- * now enable it again
- */
- ieee80211_wake_queues(rt2x00dev->hw);
-
- /*
- * During interface iteration we might have changed the
- * delayed_flags, time to handles the event by calling
- * the work handler directly.
- */
- rt2x00lib_intf_scheduled(&rt2x00dev->intf_work);
-
return 0;
-
-exit:
- rt2x00lib_stop(rt2x00dev);
- rt2x00lib_uninitialize(rt2x00dev);
- rt2x00debug_deregister(rt2x00dev);
-
- return retval;
}
EXPORT_SYMBOL_GPL(rt2x00lib_resume);
#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h
index 7169c222a48..fdedb512292 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dump.h
+++ b/drivers/net/wireless/rt2x00/rt2x00dump.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index bab05a56e7a..d2deea2f267 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,6 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
const struct firmware *fw;
char *fw_name;
int retval;
- u16 crc;
/*
* Read correct firmware from harddisk.
@@ -61,16 +60,26 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
return -ENOENT;
}
- crc = rt2x00dev->ops->lib->get_firmware_crc(fw->data, fw->size);
- if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) {
- ERROR(rt2x00dev, "Firmware checksum error.\n");
- retval = -ENOENT;
- goto exit;
- }
-
INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n",
fw->data[fw->size - 4], fw->data[fw->size - 3]);
+ retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size);
+ switch (retval) {
+ case FW_OK:
+ break;
+ case FW_BAD_CRC:
+ ERROR(rt2x00dev, "Firmware checksum error.\n");
+ goto exit;
+ case FW_BAD_LENGTH:
+ ERROR(rt2x00dev,
+ "Invalid firmware file length (len=%zu)\n", fw->size);
+ goto exit;
+ case FW_BAD_VERSION:
+ ERROR(rt2x00dev,
+ "Current firmware does not support detected chipset.\n");
+ goto exit;
+ };
+
rt2x00dev->fw = fw;
return 0;
@@ -78,7 +87,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
exit:
release_firmware(fw);
- return retval;
+ return -ENOENT;
}
int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c
index a0cd35b6beb..49671fed91d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.c
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -134,7 +134,7 @@ void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy));
if (rt2x00dev->led_radio.flags & LED_INITIALIZED) {
- snprintf(name, sizeof(name), "%s:radio", dev_name);
+ snprintf(name, sizeof(name), "%s::radio", dev_name);
retval = rt2x00leds_register_led(rt2x00dev,
&rt2x00dev->led_radio,
@@ -144,7 +144,7 @@ void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
}
if (rt2x00dev->led_assoc.flags & LED_INITIALIZED) {
- snprintf(name, sizeof(name), "%s:assoc", dev_name);
+ snprintf(name, sizeof(name), "%s::assoc", dev_name);
retval = rt2x00leds_register_led(rt2x00dev,
&rt2x00dev->led_assoc,
@@ -154,7 +154,7 @@ void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
}
if (rt2x00dev->led_qual.flags & LED_INITIALIZED) {
- snprintf(name, sizeof(name), "%s:quality", dev_name);
+ snprintf(name, sizeof(name), "%s::quality", dev_name);
retval = rt2x00leds_register_led(rt2x00dev,
&rt2x00dev->led_qual,
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h
index 9df4a49bdca..1046977e6a1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.h
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 86cd26fbf76..a631613177d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -33,7 +33,7 @@
* 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 ( round_jiffies_relative(HZ) )
+#define RFKILL_POLL_INTERVAL ( 1000 )
/*
* rt2x00_rate: Per rate device information
@@ -63,7 +63,6 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state);
-void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev);
/*
* Initialization handlers.
@@ -77,7 +76,7 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
enum nl80211_iftype type,
- u8 *mac, u8 *bssid);
+ const u8 *mac, const u8 *bssid);
void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
struct ieee80211_bss_conf *conf);
@@ -124,9 +123,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
* rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @vif: Interface for which the beacon should be updated.
+ * @enable_beacon: Enable beaconing
*/
int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif);
+ struct ieee80211_vif *vif,
+ const bool enable_beacon);
/**
* rt2x00queue_index_inc - Index incrementation function
@@ -140,6 +141,15 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
/**
+ * rt2x00queue_stop_queues - Halt all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This function will loop through all available queues to stop
+ * any pending outgoing frames.
+ */
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
+
+/**
* rt2x00queue_init_queues - Initialize all data queues
* @rt2x00dev: Pointer to &struct rt2x00_dev.
*
@@ -154,6 +164,81 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev);
int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev);
void rt2x00queue_free(struct rt2x00_dev *rt2x00dev);
+/**
+ * rt2x00link_update_stats - Update link statistics from RX frame
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: Received frame
+ * @rxdesc: Received frame descriptor
+ *
+ * Update link statistics based on the information from the
+ * received frame descriptor.
+ */
+void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb,
+ struct rxdone_entry_desc *rxdesc);
+
+/**
+ * rt2x00link_calculate_signal - Calculate signal quality
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @rssi: RX Frame RSSI
+ *
+ * Calculate the signal quality of a frame based on the rssi
+ * measured during the receiving of the frame and the global
+ * link quality statistics measured since the start of the
+ * link tuning. The result is a value between 0 and 100 which
+ * is an indication of the signal quality.
+ */
+int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi);
+
+/**
+ * rt2x00link_start_tuner - Start periodic link tuner work
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This start the link tuner periodic work, this work will
+ * be executed periodically until &rt2x00link_stop_tuner has
+ * been called.
+ */
+void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00link_stop_tuner - Stop periodic link tuner work
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * After this function completed the link tuner will not
+ * be running until &rt2x00link_start_tuner is called.
+ */
+void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00link_reset_tuner - Reset periodic link tuner work
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @antenna: Should the antenna tuning also be reset
+ *
+ * The VGC limit configured in the hardware will be reset to 0
+ * which forces the driver to rediscover the correct value for
+ * the current association. This is needed when configuration
+ * options have changed which could drastically change the
+ * SNR level or link quality (i.e. changing the antenna setting).
+ *
+ * Resetting the link tuner will also cause the periodic work counter
+ * to be reset. Any driver which has a fixed limit on the number
+ * of rounds the link tuner is supposed to work will accept the
+ * tuner actions again if this limit was previously reached.
+ *
+ * If @antenna is set to true a the software antenna diversity
+ * tuning will also be reset.
+ */
+void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna);
+
+/**
+ * rt2x00link_register - Initialize link tuning functionality
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * Initialize work structure and all link tuning related
+ * paramters. This will not start the link tuning process itself.
+ */
+void rt2x00link_register(struct rt2x00_dev *rt2x00dev);
+
/*
* Firmware handlers.
*/
@@ -179,7 +264,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev);
void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
enum rt2x00_dump_type type, struct sk_buff *skb);
void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
- enum cipher cipher, enum rx_crypto status);
+ struct rxdone_entry_desc *rxdesc);
#else
static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
{
@@ -196,8 +281,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
}
static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
- enum cipher cipher,
- enum rx_crypto status)
+ struct rxdone_entry_desc *rxdesc)
{
}
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
@@ -209,7 +293,8 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key);
void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc);
-unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info);
+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);
@@ -227,7 +312,8 @@ static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
{
}
-static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
+static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb)
{
return 0;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
new file mode 100644
index 00000000000..7eb5cd7e5f3
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -0,0 +1,471 @@
+/*
+ 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 generic link tuning routines.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "rt2x00.h"
+#include "rt2x00lib.h"
+
+/*
+ * When we lack RSSI information return something less then -80 to
+ * tell the driver to tune the device to maximum sensitivity.
+ */
+#define DEFAULT_RSSI -128
+
+/*
+ * When no TX/RX percentage could be calculated due to lack of
+ * frames on the air, we fallback to a percentage of 50%.
+ * This will assure we will get at least get some decent value
+ * when the link tuner starts.
+ * The value will be dropped and overwritten with the correct (measured)
+ * value anyway during the first run of the link tuner.
+ */
+#define DEFAULT_PERCENTAGE 50
+
+/*
+ * Small helper macro to work with moving/walking averages.
+ * When adding a value to the average value the following calculation
+ * is needed:
+ *
+ * avg_rssi = ((avg_rssi * 7) + rssi) / 8;
+ *
+ * The advantage of this approach is that we only need 1 variable
+ * to store the average in (No need for a count and a total).
+ * But more importantly, normal average values will over time
+ * move less and less towards newly added values this results
+ * that with link tuning, the device can have a very good RSSI
+ * for a few minutes but when the device is moved away from the AP
+ * the average will not decrease fast enough to compensate.
+ * The walking average compensates this and will move towards
+ * the new values correctly allowing a effective link tuning.
+ */
+#define MOVING_AVERAGE(__avg, __val, __samples) \
+ ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
+
+/*
+ * Small helper macro for percentage calculation
+ * This is a very simple macro with the only catch that it will
+ * produce a default value in case no total value was provided.
+ */
+#define PERCENTAGE(__value, __total) \
+ ( (__total) ? (((__value) * 100) / (__total)) : (DEFAULT_PERCENTAGE) )
+
+/*
+ * For calculating the Signal quality we have determined
+ * the total number of success and failed RX and TX frames.
+ * With the addition of the average RSSI value we can determine
+ * the link quality using the following algorithm:
+ *
+ * rssi_percentage = (avg_rssi * 100) / rssi_offset
+ * rx_percentage = (rx_success * 100) / rx_total
+ * tx_percentage = (tx_success * 100) / tx_total
+ * avg_signal = ((WEIGHT_RSSI * avg_rssi) +
+ * (WEIGHT_TX * tx_percentage) +
+ * (WEIGHT_RX * rx_percentage)) / 100
+ *
+ * This value should then be checked to not be greater then 100.
+ * This means the values of WEIGHT_RSSI, WEIGHT_RX, WEIGHT_TX must
+ * sum up to 100 as well.
+ */
+#define WEIGHT_RSSI 20
+#define WEIGHT_RX 40
+#define WEIGHT_TX 40
+
+static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+
+ if (ant->rssi_ant && rt2x00dev->link.qual.rx_success)
+ return ant->rssi_ant;
+ return DEFAULT_RSSI;
+}
+
+static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev,
+ enum antenna antenna)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+
+ if (ant->rssi_history[antenna - ANTENNA_A])
+ return ant->rssi_history[antenna - ANTENNA_A];
+ return DEFAULT_RSSI;
+}
+/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
+#define rt2x00link_antenna_get_rssi_rx_history(__dev) \
+ rt2x00link_antenna_get_rssi_history((__dev), \
+ (__dev)->link.ant.active.rx)
+#define rt2x00link_antenna_get_rssi_tx_history(__dev) \
+ rt2x00link_antenna_get_rssi_history((__dev), \
+ (__dev)->link.ant.active.tx)
+
+static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev,
+ enum antenna antenna,
+ int rssi)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ ant->rssi_history[ant->active.rx - ANTENNA_A] = rssi;
+}
+/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
+#define rt2x00link_antenna_update_rssi_rx_history(__dev, __rssi) \
+ rt2x00link_antenna_update_rssi_history((__dev), \
+ (__dev)->link.ant.active.rx, \
+ (__rssi))
+#define rt2x00link_antenna_update_rssi_tx_history(__dev, __rssi) \
+ rt2x00link_antenna_update_rssi_history((__dev), \
+ (__dev)->link.ant.active.tx, \
+ (__rssi))
+
+static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev)
+{
+ rt2x00dev->link.ant.rssi_ant = 0;
+}
+
+static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct antenna_setup new_ant;
+ int sample_a = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_A);
+ int sample_b = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_B);
+
+ memcpy(&new_ant, &ant->active, sizeof(new_ant));
+
+ /*
+ * We are done sampling. Now we should evaluate the results.
+ */
+ ant->flags &= ~ANTENNA_MODE_SAMPLE;
+
+ /*
+ * During the last period we have sampled the RSSI
+ * from both antenna's. It now is time to determine
+ * which antenna demonstrated the best performance.
+ * When we are already on the antenna with the best
+ * performance, then there really is nothing for us
+ * left to do.
+ */
+ if (sample_a == sample_b)
+ return;
+
+ if (ant->flags & ANTENNA_RX_DIVERSITY)
+ new_ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+
+ if (ant->flags & ANTENNA_TX_DIVERSITY)
+ new_ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+
+ rt2x00lib_config_antenna(rt2x00dev, &new_ant);
+}
+
+static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct antenna_setup new_ant;
+ int rssi_curr;
+ int rssi_old;
+
+ memcpy(&new_ant, &ant->active, sizeof(new_ant));
+
+ /*
+ * Get current RSSI value along with the historical value,
+ * after that update the history with the current value.
+ */
+ rssi_curr = rt2x00link_antenna_get_link_rssi(rt2x00dev);
+ rssi_old = rt2x00link_antenna_get_rssi_rx_history(rt2x00dev);
+ rt2x00link_antenna_update_rssi_rx_history(rt2x00dev, rssi_curr);
+
+ /*
+ * Legacy driver indicates that we should swap antenna's
+ * when the difference in RSSI is greater that 5. This
+ * also should be done when the RSSI was actually better
+ * then the previous sample.
+ * When the difference exceeds the threshold we should
+ * sample the rssi from the other antenna to make a valid
+ * comparison between the 2 antennas.
+ */
+ if (abs(rssi_curr - rssi_old) < 5)
+ return;
+
+ ant->flags |= ANTENNA_MODE_SAMPLE;
+
+ if (ant->flags & ANTENNA_RX_DIVERSITY)
+ new_ant.rx = (new_ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+ if (ant->flags & ANTENNA_TX_DIVERSITY)
+ new_ant.tx = (new_ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+ rt2x00lib_config_antenna(rt2x00dev, &new_ant);
+}
+
+static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+
+ /*
+ * Determine if software diversity is enabled for
+ * either the TX or RX antenna (or both).
+ * Always perform this check since within the link
+ * tuner interval the configuration might have changed.
+ */
+ ant->flags &= ~ANTENNA_RX_DIVERSITY;
+ ant->flags &= ~ANTENNA_TX_DIVERSITY;
+
+ if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+ ant->flags |= ANTENNA_RX_DIVERSITY;
+ if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+ ant->flags |= ANTENNA_TX_DIVERSITY;
+
+ if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
+ !(ant->flags & ANTENNA_TX_DIVERSITY)) {
+ ant->flags = 0;
+ return;
+ }
+
+ /*
+ * If we have only sampled the data over the last period
+ * we should now harvest the data. Otherwise just evaluate
+ * the data. The latter should only be performed once
+ * every 2 seconds.
+ */
+ if (ant->flags & ANTENNA_MODE_SAMPLE)
+ rt2x00lib_antenna_diversity_sample(rt2x00dev);
+ else if (rt2x00dev->link.count & 1)
+ rt2x00lib_antenna_diversity_eval(rt2x00dev);
+}
+
+void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb,
+ struct rxdone_entry_desc *rxdesc)
+{
+ struct link *link = &rt2x00dev->link;
+ struct link_qual *qual = &rt2x00dev->link.qual;
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ int avg_rssi = rxdesc->rssi;
+ int ant_rssi = rxdesc->rssi;
+
+ /*
+ * Frame was received successfully since non-succesfull
+ * frames would have been dropped by the hardware.
+ */
+ qual->rx_success++;
+
+ /*
+ * We are only interested in quality statistics from
+ * beacons which came from the BSS which we are
+ * associated with.
+ */
+ if (!ieee80211_is_beacon(hdr->frame_control) ||
+ !(rxdesc->dev_flags & RXDONE_MY_BSS))
+ return;
+
+ /*
+ * Update global RSSI
+ */
+ if (link->avg_rssi)
+ avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi, 8);
+ link->avg_rssi = avg_rssi;
+
+ /*
+ * Update antenna RSSI
+ */
+ if (ant->rssi_ant)
+ ant_rssi = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi, 8);
+ ant->rssi_ant = ant_rssi;
+}
+
+static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev)
+{
+ struct link *link = &rt2x00dev->link;
+ struct link_qual *qual = &rt2x00dev->link.qual;
+
+ link->rx_percentage =
+ PERCENTAGE(qual->rx_success, qual->rx_failed + qual->rx_success);
+ link->tx_percentage =
+ PERCENTAGE(qual->tx_success, qual->tx_failed + qual->tx_success);
+}
+
+int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi)
+{
+ struct link *link = &rt2x00dev->link;
+ int rssi_percentage = 0;
+ int signal;
+
+ /*
+ * We need a positive value for the RSSI.
+ */
+ if (rssi < 0)
+ rssi += rt2x00dev->rssi_offset;
+
+ /*
+ * Calculate the different percentages,
+ * which will be used for the signal.
+ */
+ rssi_percentage = PERCENTAGE(rssi, rt2x00dev->rssi_offset);
+
+ /*
+ * Add the individual percentages and use the WEIGHT
+ * defines to calculate the current link signal.
+ */
+ signal = ((WEIGHT_RSSI * rssi_percentage) +
+ (WEIGHT_TX * link->tx_percentage) +
+ (WEIGHT_RX * link->rx_percentage)) / 100;
+
+ return max_t(int, signal, 100);
+}
+
+void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
+{
+ struct link *link = &rt2x00dev->link;
+
+ /*
+ * Link tuning should only be performed when
+ * an active sta or master interface exists.
+ * Single monitor mode interfaces should never have
+ * work with link tuners.
+ */
+ if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)
+ return;
+
+ link->rx_percentage = DEFAULT_PERCENTAGE;
+ link->tx_percentage = DEFAULT_PERCENTAGE;
+
+ rt2x00link_reset_tuner(rt2x00dev, false);
+
+ queue_delayed_work(rt2x00dev->hw->workqueue,
+ &link->work, LINK_TUNE_INTERVAL);
+}
+
+void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
+{
+ cancel_delayed_work_sync(&rt2x00dev->link.work);
+}
+
+void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna)
+{
+ struct link_qual *qual = &rt2x00dev->link.qual;
+
+ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
+ /*
+ * Reset link information.
+ * Both the currently active vgc level as well as
+ * the link tuner counter should be reset. Resetting
+ * the counter is important for devices where the
+ * device should only perform link tuning during the
+ * first minute after being enabled.
+ */
+ rt2x00dev->link.count = 0;
+ memset(qual, 0, sizeof(*qual));
+
+ /*
+ * Reset the link tuner.
+ */
+ rt2x00dev->ops->lib->reset_tuner(rt2x00dev, qual);
+
+ if (antenna)
+ rt2x00link_antenna_reset(rt2x00dev);
+}
+
+void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_qual *qual = &rt2x00dev->link.qual;
+
+ qual->rx_success = 0;
+ qual->rx_failed = 0;
+ qual->tx_success = 0;
+ qual->tx_failed = 0;
+}
+
+static void rt2x00link_tuner(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, link.work.work);
+ struct link *link = &rt2x00dev->link;
+ struct link_qual *qual = &rt2x00dev->link.qual;
+
+ /*
+ * When the radio is shutting down we should
+ * immediately cease all link tuning.
+ */
+ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
+ /*
+ * Update statistics.
+ */
+ rt2x00dev->ops->lib->link_stats(rt2x00dev, qual);
+ rt2x00dev->low_level_stats.dot11FCSErrorCount += qual->rx_failed;
+
+ /*
+ * Update quality RSSI for link tuning,
+ * when we have received some frames and we managed to
+ * collect the RSSI data we could use this. Otherwise we
+ * must fallback to the default RSSI value.
+ */
+ if (!link->avg_rssi || !qual->rx_success)
+ qual->rssi = DEFAULT_RSSI;
+ else
+ qual->rssi = link->avg_rssi;
+
+ /*
+ * Only perform the link tuning when Link tuning
+ * has been enabled (This could have been disabled from the EEPROM).
+ */
+ if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags))
+ rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count);
+
+ /*
+ * Precalculate a portion of the link signal which is
+ * in based on the tx/rx success/failure counters.
+ */
+ rt2x00link_precalculate_signal(rt2x00dev);
+
+ /*
+ * Send a signal to the led to update the led signal strength.
+ */
+ rt2x00leds_led_quality(rt2x00dev, link->avg_rssi);
+
+ /*
+ * Evaluate antenna setup, make this the last step since this could
+ * possibly reset some statistics.
+ */
+ rt2x00lib_antenna_diversity(rt2x00dev);
+
+ /*
+ * Reset the quality counters which recounted during each period.
+ */
+ rt2x00link_reset_qual(rt2x00dev);
+
+ /*
+ * Increase tuner counter, and reschedule the next link tuner run.
+ */
+ link->count++;
+ queue_delayed_work(rt2x00dev->hw->workqueue,
+ &link->work, LINK_TUNE_INTERVAL);
+}
+
+void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
+{
+ INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
+}
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 38edee5fe16..c41a0b9e473 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -79,8 +79,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
* RTS/CTS frame should use the length of the frame plus any
* encryption overhead that will be added by the hardware.
*/
- if (!frag_skb->do_not_encrypt)
- data_length += rt2x00crypto_tx_overhead(tx_info);
+ data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb);
if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
@@ -226,6 +225,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
break;
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_WDS:
/*
* We don't support mixed combinations of
* sta and ap interfaces.
@@ -430,8 +431,10 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
/*
* Update the beacon.
*/
- if (conf->changed & IEEE80211_IFCC_BEACON)
- status = rt2x00queue_update_beacon(rt2x00dev, vif);
+ if (conf->changed & (IEEE80211_IFCC_BEACON |
+ IEEE80211_IFCC_BEACON_ENABLED))
+ status = rt2x00queue_update_beacon(rt2x00dev, vif,
+ conf->enable_beacon);
return status;
}
@@ -482,16 +485,36 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
#ifdef CONFIG_RT2X00_LIB_CRYPTO
+static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
+{
+ if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
+ memcpy(&crypto->key,
+ &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
+ sizeof(crypto->key));
+
+ if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
+ memcpy(&crypto->tx_mic,
+ &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
+ sizeof(crypto->tx_mic));
+
+ if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
+ memcpy(&crypto->rx_mic,
+ &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
+ sizeof(crypto->rx_mic));
+}
+
int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
- struct ieee80211_sta *sta;
+ struct rt2x00_intf *intf = vif_to_intf(vif);
int (*set_key) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_crypto *crypto,
struct ieee80211_key_conf *key);
struct rt2x00lib_crypto crypto;
+ static const u8 bcast_addr[ETH_ALEN] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
return 0;
@@ -509,45 +532,25 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (rt2x00dev->intf_sta_count)
crypto.bssidx = 0;
else
- crypto.bssidx =
- local_address[5] & (rt2x00dev->ops->max_ap_intf - 1);
+ crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1);
crypto.cipher = rt2x00crypto_key_to_cipher(key);
if (crypto.cipher == CIPHER_NONE)
return -EOPNOTSUPP;
crypto.cmd = cmd;
- crypto.address = address;
-
- if (crypto.cipher == CIPHER_TKIP) {
- if (key->keylen > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
- memcpy(&crypto.key,
- &key->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
- sizeof(crypto.key));
-
- if (key->keylen > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
- memcpy(&crypto.tx_mic,
- &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
- sizeof(crypto.tx_mic));
-
- if (key->keylen > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
- memcpy(&crypto.rx_mic,
- &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
- sizeof(crypto.rx_mic));
- } else
- memcpy(&crypto.key, &key->key[0], key->keylen);
- /*
- * Discover the Association ID from mac80211.
- * Some drivers need this information when updating the
- * hardware key (either adding or removing).
- */
- rcu_read_lock();
- sta = ieee80211_find_sta(hw, address);
- if (sta)
+ if (sta) {
+ /* some drivers need the AID */
crypto.aid = sta->aid;
- rcu_read_unlock();
+ crypto.address = sta->addr;
+ } else
+ crypto.address = bcast_addr;
+ if (crypto.cipher == CIPHER_TKIP)
+ memcpy_tkip(&crypto, &key->key[0], key->keylen);
+ else
+ memcpy(&crypto.key, &key->key[0], key->keylen);
/*
* Each BSS has a maximum of 4 shared keys.
* Shared key index values:
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index d52b22b82d1..e616c20d4a7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 9c0a4d77bc1..15a12487e04 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 746a8f36b93..a5664bd8493 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -148,6 +148,96 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
+static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
+ struct txentry_desc *txdesc)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+ struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
+ unsigned long irqflags;
+
+ if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) ||
+ unlikely(!tx_info->control.vif))
+ return;
+
+ /*
+ * Hardware should insert sequence counter.
+ * FIXME: We insert a software sequence counter first for
+ * hardware that doesn't support hardware sequence counting.
+ *
+ * This is wrong because beacons are not getting sequence
+ * numbers assigned properly.
+ *
+ * A secondary problem exists for drivers that cannot toggle
+ * sequence counting per-frame, since those will override the
+ * sequence counter given by mac80211.
+ */
+ spin_lock_irqsave(&intf->seqlock, irqflags);
+
+ if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
+ intf->seqno += 0x10;
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
+
+ spin_unlock_irqrestore(&intf->seqlock, irqflags);
+
+ __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
+}
+
+static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
+ unsigned int data_length;
+ unsigned int duration;
+ unsigned int residual;
+
+ /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */
+ data_length = entry->skb->len + 4;
+ data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb);
+
+ /*
+ * PLCP setup
+ * Length calculation depends on OFDM/CCK rate.
+ */
+ txdesc->signal = hwrate->plcp;
+ txdesc->service = 0x04;
+
+ if (hwrate->flags & DEV_RATE_OFDM) {
+ txdesc->length_high = (data_length >> 6) & 0x3f;
+ txdesc->length_low = data_length & 0x3f;
+ } else {
+ /*
+ * Convert length to microseconds.
+ */
+ residual = GET_DURATION_RES(data_length, hwrate->bitrate);
+ duration = GET_DURATION(data_length, hwrate->bitrate);
+
+ if (residual != 0) {
+ duration++;
+
+ /*
+ * Check if we need to set the Length Extension
+ */
+ if (hwrate->bitrate == 110 && residual <= 30)
+ txdesc->service |= 0x80;
+ }
+
+ txdesc->length_high = (duration >> 8) & 0xff;
+ txdesc->length_low = duration & 0xff;
+
+ /*
+ * When preamble is enabled we should set the
+ * preamble bit for the signal.
+ */
+ if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ txdesc->signal |= 0x08;
+ }
+}
+
static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
@@ -157,10 +247,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
struct ieee80211_rate *rate =
ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
const struct rt2x00_rate *hwrate;
- unsigned int data_length;
- unsigned int duration;
- unsigned int residual;
- unsigned long irqflags;
memset(txdesc, 0, sizeof(*txdesc));
@@ -172,27 +258,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
txdesc->cw_max = entry->queue->cw_max;
txdesc->aifs = entry->queue->aifs;
- /* Data length + CRC */
- data_length = entry->skb->len + 4;
-
/*
* Check whether this frame is to be acked.
*/
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
__set_bit(ENTRY_TXD_ACK, &txdesc->flags);
- if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) &&
- !entry->skb->do_not_encrypt) {
- /* Apply crypto specific descriptor information */
- rt2x00crypto_create_tx_descriptor(entry, txdesc);
-
- /*
- * Extend frame length to include all encryption overhead
- * that will be added by the hardware.
- */
- data_length += rt2x00crypto_tx_overhead(tx_info);
- }
-
/*
* Check if this is a RTS/CTS frame
*/
@@ -236,86 +307,27 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* Set ifs to IFS_SIFS when the this is not the first fragment,
* or this fragment came after RTS/CTS.
*/
- if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
- txdesc->ifs = IFS_SIFS;
- } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
+ if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) &&
+ !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
__set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags);
txdesc->ifs = IFS_BACKOFF;
- } else {
+ } else
txdesc->ifs = IFS_SIFS;
- }
/*
- * Hardware should insert sequence counter.
- * FIXME: We insert a software sequence counter first for
- * hardware that doesn't support hardware sequence counting.
- *
- * This is wrong because beacons are not getting sequence
- * numbers assigned properly.
- *
- * A secondary problem exists for drivers that cannot toggle
- * sequence counting per-frame, since those will override the
- * sequence counter given by mac80211.
+ * Determine rate modulation.
*/
- if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- if (likely(tx_info->control.vif)) {
- struct rt2x00_intf *intf;
-
- intf = vif_to_intf(tx_info->control.vif);
-
- spin_lock_irqsave(&intf->seqlock, irqflags);
-
- if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
- intf->seqno += 0x10;
- hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
-
- spin_unlock_irqrestore(&intf->seqlock, irqflags);
-
- __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
- }
- }
+ hwrate = rt2x00_get_rate(rate->hw_value);
+ txdesc->rate_mode = RATE_MODE_CCK;
+ if (hwrate->flags & DEV_RATE_OFDM)
+ txdesc->rate_mode = RATE_MODE_OFDM;
/*
- * PLCP setup
- * Length calculation depends on OFDM/CCK rate.
+ * Apply TX descriptor handling by components
*/
- hwrate = rt2x00_get_rate(rate->hw_value);
- txdesc->signal = hwrate->plcp;
- txdesc->service = 0x04;
-
- if (hwrate->flags & DEV_RATE_OFDM) {
- __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags);
-
- txdesc->length_high = (data_length >> 6) & 0x3f;
- txdesc->length_low = data_length & 0x3f;
- } else {
- /*
- * Convert length to microseconds.
- */
- residual = GET_DURATION_RES(data_length, hwrate->bitrate);
- duration = GET_DURATION(data_length, hwrate->bitrate);
-
- if (residual != 0) {
- duration++;
-
- /*
- * Check if we need to set the Length Extension
- */
- if (hwrate->bitrate == 110 && residual <= 30)
- txdesc->service |= 0x80;
- }
-
- txdesc->length_high = (duration >> 8) & 0xff;
- txdesc->length_low = duration & 0xff;
-
- /*
- * When preamble is enabled we should set the
- * preamble bit for the signal.
- */
- if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
- txdesc->signal |= 0x08;
- }
+ rt2x00crypto_create_tx_descriptor(entry, txdesc);
+ rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
+ rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
}
static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
@@ -402,7 +414,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
*/
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
- if (test_bit(CONFIG_CRYPTO_COPY_IV, &queue->rt2x00dev->flags))
+ if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
rt2x00crypto_tx_copy_iv(skb, iv_len);
else
rt2x00crypto_tx_remove_iv(skb, iv_len);
@@ -431,7 +443,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
}
int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif)
+ struct ieee80211_vif *vif,
+ const bool enable_beacon)
{
struct rt2x00_intf *intf = vif_to_intf(vif);
struct skb_frame_desc *skbdesc;
@@ -441,6 +454,11 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
if (unlikely(!intf->beacon))
return -ENOBUFS;
+ if (!enable_beacon) {
+ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON);
+ return 0;
+ }
+
intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
if (!intf->beacon->skb)
return -ENOMEM;
@@ -489,6 +507,9 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
{
int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
+ if (queue == QID_RX)
+ return rt2x00dev->rx;
+
if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx)
return &rt2x00dev->tx[queue];
@@ -565,6 +586,14 @@ static void rt2x00queue_reset(struct data_queue *queue)
spin_unlock_irqrestore(&queue->lock, irqflags);
}
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+
+ txall_queue_for_each(rt2x00dev, queue)
+ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid);
+}
+
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 28293715340..97e2ab08f08 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -158,6 +158,14 @@ enum rxdone_entry_desc_flags {
};
/**
+ * RXDONE_SIGNAL_MASK - Define to mask off all &rxdone_entry_desc_flags flags
+ * except for the RXDONE_SIGNAL_* flags. This is useful to convert the dev_flags
+ * from &rxdone_entry_desc to a signal value type.
+ */
+#define RXDONE_SIGNAL_MASK \
+ ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE )
+
+/**
* struct rxdone_entry_desc: RX Entry descriptor
*
* Summary of information that has been read from the RX frame descriptor.
@@ -165,6 +173,7 @@ enum rxdone_entry_desc_flags {
* @timestamp: RX Timestamp
* @signal: Signal of the received frame.
* @rssi: RSSI of the received frame.
+ * @noise: Measured noise during frame reception.
* @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).
@@ -177,6 +186,7 @@ struct rxdone_entry_desc {
u64 timestamp;
int signal;
int rssi;
+ int noise;
int size;
int flags;
int dev_flags;
@@ -222,7 +232,6 @@ struct txdone_entry_desc {
*
* @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame.
* @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame.
- * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate.
* @ENTRY_TXD_GENERATE_SEQ: This frame requires sequence counter.
* @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame.
* @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment.
@@ -238,7 +247,6 @@ struct txdone_entry_desc {
enum txentry_desc_flags {
ENTRY_TXD_RTS_FRAME,
ENTRY_TXD_CTS_FRAME,
- ENTRY_TXD_OFDM_RATE,
ENTRY_TXD_GENERATE_SEQ,
ENTRY_TXD_FIRST_FRAGMENT,
ENTRY_TXD_MORE_FRAG,
@@ -263,6 +271,7 @@ enum txentry_desc_flags {
* @length_low: PLCP length low word.
* @signal: PLCP signal.
* @service: PLCP service.
+ * @rate_mode: Rate mode (See @enum rate_modulation).
* @retry_limit: Max number of retries.
* @aifs: AIFS value.
* @ifs: IFS value.
@@ -282,6 +291,8 @@ struct txentry_desc {
u16 signal;
u16 service;
+ u16 rate_mode;
+
short retry_limit;
short aifs;
short ifs;
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index c2fba7c9f05..861322d97fc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -125,6 +125,26 @@ enum cipher {
};
/*
+ * Rate modulations
+ */
+enum rate_modulation {
+ RATE_MODE_CCK = 0,
+ RATE_MODE_OFDM = 1,
+ RATE_MODE_HT_MIX = 2,
+ RATE_MODE_HT_GREENFIELD = 3,
+};
+
+/*
+ * Firmware validation error codes
+ */
+enum firmware_errors {
+ FW_OK,
+ FW_BAD_CRC,
+ FW_BAD_LENGTH,
+ FW_BAD_VERSION,
+};
+
+/*
* Register handlers.
* We store the position of a register field inside a field structure,
* This will simplify the process of setting and reading a certain field
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index c3f53a92180..b6d4c6700bf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -25,73 +25,30 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/rfkill.h>
#include "rt2x00.h"
#include "rt2x00lib.h"
-static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
+static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
{
- struct rt2x00_dev *rt2x00dev = data;
- int retval = 0;
-
- if (unlikely(!rt2x00dev))
- return 0;
-
- /*
- * Only continue if there are enabled interfaces.
- */
- if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
- return 0;
-
- if (state == RFKILL_STATE_UNBLOCKED) {
- INFO(rt2x00dev, "RFKILL event: enabling radio.\n");
- clear_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
- retval = rt2x00lib_enable_radio(rt2x00dev);
- } else if (state == RFKILL_STATE_SOFT_BLOCKED) {
- INFO(rt2x00dev, "RFKILL event: disabling radio.\n");
- set_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
- rt2x00lib_disable_radio(rt2x00dev);
- } else {
- WARNING(rt2x00dev, "RFKILL event: unknown state %d.\n", state);
- }
-
- return retval;
-}
-
-static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state)
-{
- struct rt2x00_dev *rt2x00dev = data;
-
- /*
- * rfkill_poll reports 1 when the key has been pressed and the
- * radio should be blocked.
- */
- *state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
- RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
-
- return 0;
-}
-
-static void rt2x00rfkill_poll(struct work_struct *work)
-{
- struct rt2x00_dev *rt2x00dev =
- container_of(work, struct rt2x00_dev, rfkill_work.work);
- enum rfkill_state state;
+ struct rt2x00_dev *rt2x00dev = poll_dev->private;
+ int state, old_state;
if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) ||
!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return;
/*
- * Poll latest state and report it to rfkill who should sort
- * out if the state should be toggled or not.
+ * Poll latest state, if the state is different then the previous state,
+ * we should generate an input event.
*/
- if (!rt2x00rfkill_get_state(rt2x00dev, &state))
- rfkill_force_state(rt2x00dev->rfkill, state);
+ state = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+ old_state = !!test_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state);
- queue_delayed_work(rt2x00dev->hw->workqueue,
- &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL);
+ if (old_state != state) {
+ input_report_switch(poll_dev->input, SW_RFKILL_ALL, state);
+ change_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state);
+ }
}
void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -100,8 +57,8 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
return;
- if (rfkill_register(rt2x00dev->rfkill)) {
- ERROR(rt2x00dev, "Failed to register rfkill handler.\n");
+ if (input_register_polled_device(rt2x00dev->rfkill_poll_dev)) {
+ ERROR(rt2x00dev, "Failed to register polled device.\n");
return;
}
@@ -109,10 +66,10 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
/*
* Force initial poll which will detect the initial device state,
- * and correctly sends the signal to the rfkill layer about this
+ * and correctly sends the signal to the input layer about this
* state.
*/
- rt2x00rfkill_poll(&rt2x00dev->rfkill_work.work);
+ rt2x00rfkill_poll(rt2x00dev->rfkill_poll_dev);
}
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
@@ -121,52 +78,50 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
return;
- cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
-
- rfkill_unregister(rt2x00dev->rfkill);
+ input_unregister_polled_device(rt2x00dev->rfkill_poll_dev);
__clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
}
void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
{
- struct device *dev = wiphy_dev(rt2x00dev->hw->wiphy);
+ struct input_polled_dev *poll_dev;
- if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
+ !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return;
- rt2x00dev->rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN);
- if (!rt2x00dev->rfkill) {
- ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev) {
+ ERROR(rt2x00dev, "Failed to allocate polled device.\n");
return;
}
- __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
+ poll_dev->private = rt2x00dev;
+ poll_dev->poll = rt2x00rfkill_poll;
+ poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
- rt2x00dev->rfkill->name = rt2x00dev->ops->name;
- rt2x00dev->rfkill->data = rt2x00dev;
- rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
- if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) {
- rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
- rt2x00dev->rfkill->state =
- rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
- RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
- } else {
- rt2x00dev->rfkill->state = RFKILL_STATE_UNBLOCKED;
- }
+ poll_dev->input->name = rt2x00dev->ops->name;
+ poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
+ poll_dev->input->id.bustype = BUS_HOST;
+ poll_dev->input->id.vendor = 0x1814;
+ poll_dev->input->id.product = rt2x00dev->chip.rt;
+ poll_dev->input->id.version = rt2x00dev->chip.rev;
+ poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
+ poll_dev->input->evbit[0] = BIT(EV_SW);
+ poll_dev->input->swbit[0] = BIT(SW_RFKILL_ALL);
- INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
+ rt2x00dev->rfkill_poll_dev = poll_dev;
- return;
+ __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
}
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->flags))
+ if (!__test_and_clear_bit(RFKILL_STATE_ALLOCATED,
+ &rt2x00dev->rfkill_state))
return;
- cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
-
- rfkill_free(rt2x00dev->rfkill);
- rt2x00dev->rfkill = NULL;
+ input_free_polled_device(rt2x00dev->rfkill_poll_dev);
+ rt2x00dev->rfkill_poll_dev = NULL;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 0b29d767a25..7d50ca82375 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -296,6 +296,41 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
+void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
+ struct queue_entry_priv_usb *entry_priv;
+ struct queue_entry_priv_usb_bcn *bcn_priv;
+ unsigned int i;
+ bool kill_guard;
+
+ /*
+ * When killing the beacon queue, we must also kill
+ * the beacon guard byte.
+ */
+ kill_guard =
+ (qid == QID_BEACON) &&
+ (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags));
+
+ /*
+ * Cancel all entries.
+ */
+ for (i = 0; i < queue->limit; i++) {
+ entry_priv = queue->entries[i].priv_data;
+ usb_kill_urb(entry_priv->urb);
+
+ /*
+ * Kill guardian urb (if required by driver).
+ */
+ if (kill_guard) {
+ bcn_priv = queue->entries[i].priv_data;
+ usb_kill_urb(bcn_priv->guardian_urb);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
+
/*
* RX data handlers.
*/
@@ -338,35 +373,14 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
*/
void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- struct queue_entry_priv_usb *entry_priv;
- struct queue_entry_priv_usb_bcn *bcn_priv;
- struct data_queue *queue;
- unsigned int i;
-
rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
REGISTER_TIMEOUT);
/*
- * Cancel all queues.
+ * The USB version of kill_tx_queue also works
+ * on the RX queue.
*/
- queue_for_each(rt2x00dev, queue) {
- for (i = 0; i < queue->limit; i++) {
- entry_priv = queue->entries[i].priv_data;
- usb_kill_urb(entry_priv->urb);
- }
- }
-
- /*
- * Kill guardian urb (if required by driver).
- */
- if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
- return;
-
- for (i = 0; i < rt2x00dev->bcn->limit; i++) {
- bcn_priv = rt2x00dev->bcn->entries[i].priv_data;
- if (bcn_priv->guardian_urb)
- usb_kill_urb(bcn_priv->guardian_urb);
- }
+ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX);
}
EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 2bd4ac855f5..bd2d59c85f1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -419,6 +419,17 @@ struct queue_entry_priv_usb_bcn {
void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid qid);
+/**
+ * rt2x00usb_kill_tx_queue - Kill data queue
+ * @rt2x00dev: Pointer to &struct rt2x00_dev
+ * @qid: Data queue to kill
+ *
+ * This will walk through all entries of the queue and kill all
+ * previously kicked frames before they can be send.
+ */
+void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid);
+
/*
* Device initialization handlers.
*/
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 987e89009f7..2ca8b7a9722 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -123,9 +123,6 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -146,12 +143,6 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
mutex_unlock(&rt2x00dev->csr_mutex);
}
-#ifdef CONFIG_RT2X00_LIB_LEDS
-/*
- * This function is only called from rt61pci_led_brightness()
- * make gcc happy by placing this function inside the
- * same ifdef statement as the caller.
- */
static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1)
@@ -180,7 +171,6 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
mutex_unlock(&rt2x00dev->csr_mutex);
}
-#endif /* CONFIG_RT2X00_LIB_LEDS */
static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
{
@@ -967,6 +957,50 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
+static void rt61pci_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) {
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
+ libconf->conf->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);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 1);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000005);
+ rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c);
+ rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060);
+
+ rt61pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0);
+ } else {
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007);
+ rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018);
+ rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020);
+
+ rt61pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+ }
+}
+
static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -984,6 +1018,8 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
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);
}
/*
@@ -1007,21 +1043,28 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
-static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
+{
+ if (qual->vgc_level != vgc_level) {
+ rt61pci_bbp_write(rt2x00dev, 17, vgc_level);
+ qual->vgc_level = vgc_level;
+ qual->vgc_level_reg = vgc_level;
+ }
+}
+
+static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
- rt61pci_bbp_write(rt2x00dev, 17, 0x20);
- rt2x00dev->link.vgc_level = 0x20;
+ rt61pci_set_vgc(rt2x00dev, qual, 0x20);
}
-static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
u8 up_bound;
u8 low_bound;
- rt61pci_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Determine r17 bounds.
*/
@@ -1051,38 +1094,32 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
/*
* Special big-R17 for very short distance
*/
- if (rssi >= -35) {
- if (r17 != 0x60)
- rt61pci_bbp_write(rt2x00dev, 17, 0x60);
+ if (qual->rssi >= -35) {
+ rt61pci_set_vgc(rt2x00dev, qual, 0x60);
return;
}
/*
* Special big-R17 for short distance
*/
- if (rssi >= -58) {
- if (r17 != up_bound)
- rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+ if (qual->rssi >= -58) {
+ rt61pci_set_vgc(rt2x00dev, qual, up_bound);
return;
}
/*
* Special big-R17 for middle-short distance
*/
- if (rssi >= -66) {
- low_bound += 0x10;
- if (r17 != low_bound)
- rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+ if (qual->rssi >= -66) {
+ rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x10);
return;
}
/*
* Special mid-R17 for middle distance
*/
- if (rssi >= -74) {
- low_bound += 0x08;
- if (r17 != low_bound)
- rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+ if (qual->rssi >= -74) {
+ rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x08);
return;
}
@@ -1090,12 +1127,12 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special case: Change up_bound based on the rssi.
* Lower up_bound when rssi is weaker then -74 dBm.
*/
- up_bound -= 2 * (-74 - rssi);
+ up_bound -= 2 * (-74 - qual->rssi);
if (low_bound > up_bound)
up_bound = low_bound;
- if (r17 > up_bound) {
- rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+ if (qual->vgc_level > up_bound) {
+ rt61pci_set_vgc(rt2x00dev, qual, up_bound);
return;
}
@@ -1105,15 +1142,10 @@ dynamic_cca_tune:
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
- if (++r17 > up_bound)
- r17 = up_bound;
- rt61pci_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
- if (--r17 < low_bound)
- r17 = low_bound;
- rt61pci_bbp_write(rt2x00dev, 17, r17);
- }
+ if ((qual->false_cca > 512) && (qual->vgc_level < up_bound))
+ rt61pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level);
+ else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound))
+ rt61pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
}
/*
@@ -1141,25 +1173,37 @@ static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
return fw_name;
}
-static u16 rt61pci_get_firmware_crc(const void *data, const size_t len)
+static int rt61pci_check_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
{
+ u16 fw_crc;
u16 crc;
/*
- * Use the crc itu-t algorithm.
+ * Only support 8kb firmware files.
+ */
+ if (len != 8192)
+ return FW_BAD_LENGTH;
+
+ /*
* 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 itu-t algorithm.
+ */
crc = crc_itu_t(0, data, len - 2);
crc = crc_itu_t_byte(crc, 0);
crc = crc_itu_t_byte(crc, 0);
- return crc;
+ return (fw_crc == crc) ? FW_OK : FW_BAD_CRC;
}
-static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
- const size_t len)
+static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
{
int i;
u32 reg;
@@ -1656,24 +1700,10 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev)
static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
-
- rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
-
/*
- * Disable synchronisation.
+ * Disable power
*/
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
-
- /*
- * Cancel RX and TX.
- */
- rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
- rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
}
static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
@@ -1812,7 +1842,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
- test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+ (txdesc->rate_mode == RATE_MODE_OFDM));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
@@ -1896,6 +1926,24 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
}
+static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ u32 reg;
+
+ if (qid == QID_BEACON) {
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
+ return;
+ }
+
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO));
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+}
+
/*
* RX control handlers
*/
@@ -2195,7 +2243,8 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
if (word == 0xffff) {
rt2x00_set_field16(&word, EEPROM_NIC_ENABLE_DIVERSITY, 0);
rt2x00_set_field16(&word, EEPROM_NIC_TX_DIVERSITY, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_TX_RX_FIXED, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_RX_FIXED, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_TX_FIXED, 0);
rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
@@ -2339,24 +2388,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
*/
if (rt2x00_rf(&rt2x00dev->chip, RF2529) &&
!test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
- switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
- case 0:
- rt2x00dev->default_ant.tx = ANTENNA_B;
- rt2x00dev->default_ant.rx = ANTENNA_A;
- break;
- case 1:
- rt2x00dev->default_ant.tx = ANTENNA_B;
- rt2x00dev->default_ant.rx = ANTENNA_B;
- break;
- case 2:
- rt2x00dev->default_ant.tx = ANTENNA_A;
- rt2x00dev->default_ant.rx = ANTENNA_A;
- break;
- case 3:
- rt2x00dev->default_ant.tx = ANTENNA_A;
- rt2x00dev->default_ant.rx = ANTENNA_B;
- break;
- }
+ rt2x00dev->default_ant.rx =
+ ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED);
+ rt2x00dev->default_ant.tx =
+ ANTENNA_B - rt2x00_get_field16(eeprom, EEPROM_NIC_TX_FIXED);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY))
rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY;
@@ -2534,7 +2569,9 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = 0;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
@@ -2633,6 +2670,7 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
struct rt2x00_field32 field;
int retval;
u32 reg;
+ u32 offset;
/*
* First pass the configuration through rt2x00lib, that will
@@ -2644,24 +2682,23 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
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 */
- if (queue_idx < 2) {
- field.bit_offset = queue_idx * 16;
- field.bit_mask = 0xffff << field.bit_offset;
-
- rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
- rt2x00_set_field32(&reg, field, queue->txop);
- rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
- } else if (queue_idx < 4) {
- field.bit_offset = (queue_idx - 2) * 16;
- field.bit_mask = 0xffff << field.bit_offset;
-
- rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
- rt2x00_set_field32(&reg, field, queue->txop);
- rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
- }
+ offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2)));
+ field.bit_offset = (queue_idx & 1) * 16;
+ field.bit_mask = 0xffff << field.bit_offset;
+
+ rt2x00pci_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field, queue->txop);
+ rt2x00pci_register_write(rt2x00dev, offset, reg);
/* Update WMM registers */
field.bit_offset = queue_idx * 4;
@@ -2717,7 +2754,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.irq_handler = rt61pci_interrupt,
.probe_hw = rt61pci_probe_hw,
.get_firmware_name = rt61pci_get_firmware_name,
- .get_firmware_crc = rt61pci_get_firmware_crc,
+ .check_firmware = rt61pci_check_firmware,
.load_firmware = rt61pci_load_firmware,
.initialize = rt2x00pci_initialize,
.uninitialize = rt2x00pci_uninitialize,
@@ -2732,6 +2769,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data,
.write_beacon = rt61pci_write_beacon,
.kick_tx_queue = rt61pci_kick_tx_queue,
+ .kill_tx_queue = rt61pci_kill_tx_queue,
.fill_rxdone = rt61pci_fill_rxdone,
.config_shared_key = rt61pci_config_shared_key,
.config_pairwise_key = rt61pci_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 65fe3332364..41e8959919f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -50,8 +50,8 @@
#define EEPROM_SIZE 0x0100
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0080
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0014
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
/*
* Number of TX queues.
@@ -88,8 +88,10 @@
/*
* SOFT_RESET_CSR
+ * FORCE_CLOCK_ON: Host force MAC clock ON
*/
#define SOFT_RESET_CSR 0x0010
+#define SOFT_RESET_CSR_FORCE_CLOCK_ON FIELD32(0x00000002)
/*
* MCU_INT_SOURCE_CSR: MCU interrupt source/mask register.
@@ -1054,8 +1056,10 @@ struct hw_pairwise_ta_entry {
/*
* IO_CNTL_CSR
+ * RF_PS: Set RF interface value to power save
*/
#define IO_CNTL_CSR 0x3498
+#define IO_CNTL_CSR_RF_PS FIELD32(0x00000004)
/*
* UART_INT_SOURCE_CSR
@@ -1186,7 +1190,8 @@ struct hw_pairwise_ta_entry {
#define EEPROM_NIC 0x0011
#define EEPROM_NIC_ENABLE_DIVERSITY FIELD16(0x0001)
#define EEPROM_NIC_TX_DIVERSITY FIELD16(0x0002)
-#define EEPROM_NIC_TX_RX_FIXED FIELD16(0x000c)
+#define EEPROM_NIC_RX_FIXED FIELD16(0x0004)
+#define EEPROM_NIC_TX_FIXED FIELD16(0x0008)
#define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0010)
#define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0020)
#define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0040)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 96a8d69f879..24fdfdfee3d 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -122,9 +122,6 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -186,6 +183,18 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
};
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
+ return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
+}
+#else
+#define rt73usb_rfkill_poll NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
#ifdef CONFIG_RT2X00_LIB_LEDS
static void rt73usb_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
@@ -844,6 +853,44 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
}
+static void rt73usb_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_read(rt2x00dev, MAC_CSR11, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
+ libconf->conf->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);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+ USB_MODE_SLEEP, REGISTER_TIMEOUT);
+ } else {
+ rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+ USB_MODE_WAKEUP, REGISTER_TIMEOUT);
+
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+ }
+}
+
static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -861,6 +908,8 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
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);
}
/*
@@ -884,21 +933,28 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
-static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
{
- rt73usb_bbp_write(rt2x00dev, 17, 0x20);
- rt2x00dev->link.vgc_level = 0x20;
+ if (qual->vgc_level != vgc_level) {
+ rt73usb_bbp_write(rt2x00dev, 17, vgc_level);
+ qual->vgc_level = vgc_level;
+ qual->vgc_level_reg = vgc_level;
+ }
}
-static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
+{
+ rt73usb_set_vgc(rt2x00dev, qual, 0x20);
+}
+
+static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
u8 up_bound;
u8 low_bound;
- rt73usb_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Determine r17 bounds.
*/
@@ -911,10 +967,10 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
up_bound += 0x10;
}
} else {
- if (rssi > -82) {
+ if (qual->rssi > -82) {
low_bound = 0x1c;
up_bound = 0x40;
- } else if (rssi > -84) {
+ } else if (qual->rssi > -84) {
low_bound = 0x1c;
up_bound = 0x20;
} else {
@@ -938,37 +994,32 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
/*
* Special big-R17 for very short distance
*/
- if (rssi > -35) {
- if (r17 != 0x60)
- rt73usb_bbp_write(rt2x00dev, 17, 0x60);
+ if (qual->rssi > -35) {
+ rt73usb_set_vgc(rt2x00dev, qual, 0x60);
return;
}
/*
* Special big-R17 for short distance
*/
- if (rssi >= -58) {
- if (r17 != up_bound)
- rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+ if (qual->rssi >= -58) {
+ rt73usb_set_vgc(rt2x00dev, qual, up_bound);
return;
}
/*
* Special big-R17 for middle-short distance
*/
- if (rssi >= -66) {
- low_bound += 0x10;
- if (r17 != low_bound)
- rt73usb_bbp_write(rt2x00dev, 17, low_bound);
+ if (qual->rssi >= -66) {
+ rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x10);
return;
}
/*
* Special mid-R17 for middle distance
*/
- if (rssi >= -74) {
- if (r17 != (low_bound + 0x10))
- rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08);
+ if (qual->rssi >= -74) {
+ rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x08);
return;
}
@@ -976,12 +1027,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special case: Change up_bound based on the rssi.
* Lower up_bound when rssi is weaker then -74 dBm.
*/
- up_bound -= 2 * (-74 - rssi);
+ up_bound -= 2 * (-74 - qual->rssi);
if (low_bound > up_bound)
up_bound = low_bound;
- if (r17 > up_bound) {
- rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+ if (qual->vgc_level > up_bound) {
+ rt73usb_set_vgc(rt2x00dev, qual, up_bound);
return;
}
@@ -991,17 +1042,12 @@ dynamic_cca_tune:
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
- r17 += 4;
- if (r17 > up_bound)
- r17 = up_bound;
- rt73usb_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
- r17 -= 4;
- if (r17 < low_bound)
- r17 = low_bound;
- rt73usb_bbp_write(rt2x00dev, 17, r17);
- }
+ if ((qual->false_cca > 512) && (qual->vgc_level < up_bound))
+ rt73usb_set_vgc(rt2x00dev, qual,
+ min_t(u8, qual->vgc_level + 4, up_bound));
+ else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound))
+ rt73usb_set_vgc(rt2x00dev, qual,
+ max_t(u8, qual->vgc_level - 4, low_bound));
}
/*
@@ -1012,25 +1058,37 @@ static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
return FIRMWARE_RT2571;
}
-static u16 rt73usb_get_firmware_crc(const void *data, const size_t len)
+static int rt73usb_check_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
{
+ u16 fw_crc;
u16 crc;
/*
- * Use the crc itu-t algorithm.
+ * Only support 2kb firmware files.
+ */
+ if (len != 2048)
+ return FW_BAD_LENGTH;
+
+ /*
* 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 itu-t algorithm.
+ */
crc = crc_itu_t(0, data, len - 2);
crc = crc_itu_t_byte(crc, 0);
crc = crc_itu_t_byte(crc, 0);
- return crc;
+ return (fw_crc == crc) ? FW_OK : FW_BAD_CRC;
}
-static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
- const size_t len)
+static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
{
unsigned int i;
int status;
@@ -1449,7 +1507,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
- test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+ (txdesc->rate_mode == RATE_MODE_OFDM));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
@@ -1816,6 +1874,14 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
/*
+ * Detect if this device has an hardware controlled radio.
+ */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+ /*
* Read frequency offset.
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
@@ -2020,7 +2086,9 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
@@ -2121,6 +2189,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
struct rt2x00_field32 field;
int retval;
u32 reg;
+ u32 offset;
/*
* First pass the configuration through rt2x00lib, that will
@@ -2132,24 +2201,23 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
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 */
- if (queue_idx < 2) {
- field.bit_offset = queue_idx * 16;
- field.bit_mask = 0xffff << field.bit_offset;
-
- rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
- rt2x00_set_field32(&reg, field, queue->txop);
- rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
- } else if (queue_idx < 4) {
- field.bit_offset = (queue_idx - 2) * 16;
- field.bit_mask = 0xffff << field.bit_offset;
-
- rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
- rt2x00_set_field32(&reg, field, queue->txop);
- rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
- }
+ offset = AC_TXOP_CSR0 + (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;
@@ -2170,13 +2238,6 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
return 0;
}
-#if 0
-/*
- * Mac80211 demands get_tsf must be atomic.
- * This is not possible for rt73usb since all register access
- * functions require sleeping. Untill mac80211 no longer needs
- * get_tsf to be atomic, this function should be disabled.
- */
static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -2190,9 +2251,6 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
return tsf;
}
-#else
-#define rt73usb_get_tsf NULL
-#endif
static const struct ieee80211_ops rt73usb_mac80211_ops = {
.tx = rt2x00mac_tx,
@@ -2214,12 +2272,13 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.probe_hw = rt73usb_probe_hw,
.get_firmware_name = rt73usb_get_firmware_name,
- .get_firmware_crc = rt73usb_get_firmware_crc,
+ .check_firmware = rt73usb_check_firmware,
.load_firmware = rt73usb_load_firmware,
.initialize = rt2x00usb_initialize,
.uninitialize = rt2x00usb_uninitialize,
.clear_entry = rt2x00usb_clear_entry,
.set_device_state = rt73usb_set_device_state,
+ .rfkill_poll = rt73usb_rfkill_poll,
.link_stats = rt73usb_link_stats,
.reset_tuner = rt73usb_reset_tuner,
.link_tuner = rt73usb_link_tuner,
@@ -2228,6 +2287,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.write_beacon = rt73usb_write_beacon,
.get_tx_data_len = rt73usb_get_tx_data_len,
.kick_tx_queue = rt73usb_kick_tx_queue,
+ .kill_tx_queue = rt2x00usb_kill_tx_queue,
.fill_rxdone = rt73usb_fill_rxdone,
.config_shared_key = rt73usb_config_shared_key,
.config_pairwise_key = rt73usb_config_pairwise_key,
@@ -2281,7 +2341,18 @@ static const struct rt2x00_ops rt73usb_ops = {
*/
static struct usb_device_id rt73usb_device_table[] = {
/* AboCom */
+ { USB_DEVICE(0x07b8, 0xb21b), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x07b8, 0xb21c), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x07b8, 0xb21e), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x07b8, 0xb21f), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* AL */
+ { USB_DEVICE(0x14b2, 0x3c10), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* Amigo */
+ { USB_DEVICE(0x148f, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0eb0, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* AMIT */
+ { USB_DEVICE(0x18c5, 0x0002), USB_DEVICE_DATA(&rt73usb_ops) },
/* Askey */
{ USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) },
/* ASUS */
@@ -2294,7 +2365,9 @@ static struct usb_device_id rt73usb_device_table[] = {
{ USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) },
/* Billionton */
{ USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) },
/* Buffalo */
+ { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
/* CNet */
{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
@@ -2308,6 +2381,11 @@ static struct usb_device_id rt73usb_device_table[] = {
{ USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* Edimax */
+ { USB_DEVICE(0x7392, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x7392, 0x7618), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* EnGenius */
+ { USB_DEVICE(0x1740, 0x3701), USB_DEVICE_DATA(&rt73usb_ops) },
/* Gemtek */
{ USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) },
/* Gigabyte */
@@ -2328,22 +2406,34 @@ static struct usb_device_id rt73usb_device_table[] = {
{ USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) },
/* Ralink */
+ { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
/* Qcom */
{ USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* Samsung */
+ { USB_DEVICE(0x04e8, 0x4471), USB_DEVICE_DATA(&rt73usb_ops) },
/* Senao */
{ USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) },
/* Sitecom */
- { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0024), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0df6, 0x0027), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0df6, 0x002f), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
/* Surecom */
{ USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* Philips */
+ { USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) },
/* Planex */
{ USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* Zcom */
+ { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* ZyXEL */
+ { USB_DEVICE(0x0586, 0x3415), USB_DEVICE_DATA(&rt73usb_ops) },
{ 0, }
};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 46e1405eb0e..c8016f65b4b 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -50,8 +50,8 @@
#define EEPROM_SIZE 0x0100
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0080
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0014
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
/*
* Number of TX queues.
@@ -267,6 +267,19 @@ struct hw_pairwise_ta_entry {
* MAC_CSR13: GPIO.
*/
#define MAC_CSR13 0x3034
+#define MAC_CSR13_BIT0 FIELD32(0x00000001)
+#define MAC_CSR13_BIT1 FIELD32(0x00000002)
+#define MAC_CSR13_BIT2 FIELD32(0x00000004)
+#define MAC_CSR13_BIT3 FIELD32(0x00000008)
+#define MAC_CSR13_BIT4 FIELD32(0x00000010)
+#define MAC_CSR13_BIT5 FIELD32(0x00000020)
+#define MAC_CSR13_BIT6 FIELD32(0x00000040)
+#define MAC_CSR13_BIT7 FIELD32(0x00000080)
+#define MAC_CSR13_BIT8 FIELD32(0x00000100)
+#define MAC_CSR13_BIT9 FIELD32(0x00000200)
+#define MAC_CSR13_BIT10 FIELD32(0x00000400)
+#define MAC_CSR13_BIT11 FIELD32(0x00000800)
+#define MAC_CSR13_BIT12 FIELD32(0x00001000)
/*
* MAC_CSR14: LED control register.
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index 3b1e1c2aad2..9718f61809c 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -100,6 +100,8 @@ struct rtl8187_priv {
struct usb_device *udev;
u32 rx_conf;
struct usb_anchor anchored;
+ struct delayed_work work;
+ struct ieee80211_hw *dev;
u16 txpwr_base;
u8 asic_rev;
u8 is_rtl8187b;
@@ -117,7 +119,7 @@ struct rtl8187_priv {
struct {
__le64 buf;
struct sk_buff_head queue;
- } b_tx_status;
+ } b_tx_status; /* This queue is used by both -b and non-b devices */
};
void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 6ad6bac3770..fd81884b9c7 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -48,6 +48,10 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
{USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
{USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
{USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
+ /* Surecom */
+ {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187},
+ /* Logitech */
+ {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187},
/* Netgear */
{USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
@@ -57,8 +61,16 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
/* Sitecom */
{USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
+ /* Sphairon Access Systems GmbH */
+ {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187},
+ /* Dick Smith Electronics */
+ {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187},
/* Abocom */
{USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187},
+ /* Qcom */
+ {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187},
+ /* AirLive */
+ {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187},
{}
};
@@ -177,25 +189,33 @@ static void rtl8187_tx_cb(struct urb *urb)
sizeof(struct rtl8187_tx_hdr));
ieee80211_tx_info_clear_status(info);
- if (!urb->status &&
- !(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- priv->is_rtl8187b) {
- skb_queue_tail(&priv->b_tx_status.queue, skb);
+ if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ if (priv->is_rtl8187b) {
+ skb_queue_tail(&priv->b_tx_status.queue, skb);
- /* queue is "full", discard last items */
- while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
- struct sk_buff *old_skb;
+ /* queue is "full", discard last items */
+ while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
+ struct sk_buff *old_skb;
- dev_dbg(&priv->udev->dev,
- "transmit status queue full\n");
+ dev_dbg(&priv->udev->dev,
+ "transmit status queue full\n");
- old_skb = skb_dequeue(&priv->b_tx_status.queue);
- ieee80211_tx_status_irqsafe(hw, old_skb);
- }
- } else {
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !urb->status)
+ old_skb = skb_dequeue(&priv->b_tx_status.queue);
+ ieee80211_tx_status_irqsafe(hw, old_skb);
+ }
+ return;
+ } else {
info->flags |= IEEE80211_TX_STAT_ACK;
+ }
+ }
+ if (priv->is_rtl8187b)
ieee80211_tx_status_irqsafe(hw, skb);
+ else {
+ /* Retry information for the RTI8187 is only available by
+ * reading a register in the device. We are in interrupt mode
+ * here, thus queue the skb and finish on a work queue. */
+ skb_queue_tail(&priv->b_tx_status.queue, skb);
+ queue_delayed_work(hw->workqueue, &priv->work, 0);
}
}
@@ -273,6 +293,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
buf, skb->len, rtl8187_tx_cb, skb);
+ urb->transfer_flags |= URB_ZERO_PACKET;
usb_anchor_urb(urb, &priv->anchored);
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc < 0) {
@@ -390,7 +411,7 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
struct rtl8187_rx_info *info;
int ret = 0;
- while (skb_queue_len(&priv->rx_queue) < 8) {
+ while (skb_queue_len(&priv->rx_queue) < 16) {
skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
if (!skb) {
ret = -ENOMEM;
@@ -644,7 +665,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
- rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
+ rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);
// TODO: set RESP_RATE and BRSR properly
rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
@@ -764,9 +785,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
- reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
- reg |= RTL818X_RATE_FALLBACK_ENABLE;
- rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);
rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
@@ -854,6 +872,34 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
return 0;
}
+static void rtl8187_work(struct work_struct *work)
+{
+ /* The RTL8187 returns the retry count through register 0xFFFA. In
+ * addition, it appears to be a cumulative retry count, not the
+ * value for the current TX packet. When multiple TX entries are
+ * queued, the retry count will be valid for the last one in the queue.
+ * The "error" should not matter for purposes of rate setting. */
+ struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+ work.work);
+ struct ieee80211_tx_info *info;
+ struct ieee80211_hw *dev = priv->dev;
+ static u16 retry;
+ u16 tmp;
+
+ mutex_lock(&priv->conf_mutex);
+ tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA);
+ while (skb_queue_len(&priv->b_tx_status.queue) > 0) {
+ struct sk_buff *old_skb;
+
+ old_skb = skb_dequeue(&priv->b_tx_status.queue);
+ info = IEEE80211_SKB_CB(old_skb);
+ info->status.rates[0].count = tmp - retry + 1;
+ ieee80211_tx_status_irqsafe(dev, old_skb);
+ }
+ retry = tmp;
+ mutex_unlock(&priv->conf_mutex);
+}
+
static int rtl8187_start(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
@@ -868,6 +914,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
mutex_lock(&priv->conf_mutex);
init_usb_anchor(&priv->anchored);
+ priv->dev = dev;
if (priv->is_rtl8187b) {
reg = RTL818X_RX_CONF_MGMT |
@@ -935,6 +982,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
reg |= RTL818X_CMD_TX_ENABLE;
reg |= RTL818X_CMD_RX_ENABLE;
rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+ INIT_DELAYED_WORK(&priv->work, rtl8187_work);
mutex_unlock(&priv->conf_mutex);
return 0;
@@ -965,6 +1013,8 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
dev_kfree_skb_any(skb);
usb_kill_anchored_urbs(&priv->anchored);
+ if (!priv->is_rtl8187b)
+ cancel_delayed_work_sync(&priv->work);
mutex_unlock(&priv->conf_mutex);
}
@@ -973,19 +1023,21 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
{
struct rtl8187_priv *priv = dev->priv;
int i;
+ int ret = -EOPNOTSUPP;
+ mutex_lock(&priv->conf_mutex);
if (priv->mode != NL80211_IFTYPE_MONITOR)
- return -EOPNOTSUPP;
+ goto exit;
switch (conf->type) {
case NL80211_IFTYPE_STATION:
priv->mode = conf->type;
break;
default:
- return -EOPNOTSUPP;
+ goto exit;
}
- mutex_lock(&priv->conf_mutex);
+ ret = 0;
priv->vif = conf->vif;
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
@@ -994,8 +1046,9 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
((u8 *)conf->mac_addr)[i]);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+exit:
mutex_unlock(&priv->conf_mutex);
- return 0;
+ return ret;
}
static void rtl8187_remove_interface(struct ieee80211_hw *dev,
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
index 4e75e8e7fa9..78df281b297 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
@@ -285,7 +285,10 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
ofdm_power = priv->channels[channel - 1].hw_value >> 4;
cck_power = min(cck_power, (u8)11);
- ofdm_power = min(ofdm_power, (u8)35);
+ if (ofdm_power > (u8)15)
+ ofdm_power = 25;
+ else
+ ofdm_power += 10;
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
@@ -536,7 +539,10 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
cck_power += priv->txpwr_base & 0xF;
cck_power = min(cck_power, (u8)35);
- ofdm_power = min(ofdm_power, (u8)15);
+ if (ofdm_power > (u8)15)
+ ofdm_power = 25;
+ else
+ ofdm_power += 10;
ofdm_power += priv->txpwr_base >> 4;
ofdm_power = min(ofdm_power, (u8)35);
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 7015f248055..f9520463269 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -950,6 +950,7 @@ static struct strip *strip_get_idx(loff_t pos)
}
static void *strip_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
rcu_read_lock();
return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
@@ -973,6 +974,7 @@ static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void strip_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
rcu_read_unlock();
}
@@ -1125,7 +1127,7 @@ static int strip_seq_show(struct seq_file *seq, void *v)
}
-static struct seq_operations strip_seq_ops = {
+static const struct seq_operations strip_seq_ops = {
.start = strip_seq_start,
.next = strip_seq_next,
.stop = strip_seq_stop,
@@ -2475,6 +2477,16 @@ static const struct header_ops strip_header_ops = {
.rebuild = strip_rebuild_header,
};
+
+static const struct net_device_ops strip_netdev_ops = {
+ .ndo_open = strip_open_low,
+ .ndo_stop = strip_close_low,
+ .ndo_start_xmit = strip_xmit,
+ .ndo_set_mac_address = strip_set_mac_address,
+ .ndo_get_stats = strip_get_stats,
+ .ndo_change_mtu = strip_change_mtu,
+};
+
/*
* This routine is called by DDI when the
* (dynamically assigned) device is registered
@@ -2501,18 +2513,8 @@ static void strip_dev_setup(struct net_device *dev)
dev->dev_addr[0] = 0;
dev->addr_len = sizeof(MetricomAddress);
- /*
- * Pointers to interface service routines.
- */
-
- dev->open = strip_open_low;
- dev->stop = strip_close_low;
- dev->hard_start_xmit = strip_xmit;
- dev->header_ops = &strip_header_ops;
-
- dev->set_mac_address = strip_set_mac_address;
- dev->get_stats = strip_get_stats;
- dev->change_mtu = strip_change_mtu;
+ dev->header_ops = &strip_header_ops,
+ dev->netdev_ops = &strip_netdev_ops;
}
/*
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 832679396b6..b728541f2fb 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -40,11 +40,11 @@ static u8 wv_irq_to_psa(int irq)
*/
static int __init wv_psa_to_irq(u8 irqval)
{
- int irq;
+ int i;
- for (irq = 0; irq < ARRAY_SIZE(irqvals); irq++)
- if (irqvals[irq] == irqval)
- return irq;
+ for (i = 0; i < ARRAY_SIZE(irqvals); i++)
+ if (irqvals[i] == irqval)
+ return i;
return -1;
}
@@ -4281,8 +4281,7 @@ int __init init_module(void)
/* Loop on all possible base addresses. */
- i = -1;
- while ((io[++i] != 0) && (i < ARRAY_SIZE(io))) {
+ for (i = 0; i < ARRAY_SIZE(io) && io[i] != 0; i++) {
struct net_device *dev = alloc_etherdev(sizeof(net_local));
if (!dev)
break;
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index de717f8ffd6..e55b33961ae 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -838,9 +838,8 @@ wv_82593_cmd(struct net_device * dev,
}
while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
- /* If the interrupt hasn't be posted */
- if(spin <= 0)
- {
+ /* If the interrupt hasn't been posted */
+ if (spin < 0) {
#ifdef DEBUG_INTERRUPT_ERROR
printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n",
str, status);
@@ -1353,21 +1352,6 @@ wv_init_info(struct net_device * dev)
* or wireless extensions
*/
-/*------------------------------------------------------------------*/
-/*
- * Get the current ethernet statistics. This may be called with the
- * card open or closed.
- * Used when the user read /proc/net/dev
- */
-static en_stats *
-wavelan_get_stats(struct net_device * dev)
-{
-#ifdef DEBUG_IOCTL_TRACE
- printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
-#endif
-
- return(&((net_local *)netdev_priv(dev))->stats);
-}
/*------------------------------------------------------------------*/
/*
@@ -2818,7 +2802,7 @@ wv_packet_read(struct net_device * dev,
printk(KERN_INFO "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC)\n",
dev->name, sksize);
#endif
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
/*
* Not only do we want to return here, but we also need to drop the
* packet on the floor to clear the interrupt.
@@ -2878,8 +2862,8 @@ wv_packet_read(struct net_device * dev,
netif_rx(skb);
/* Keep stats up to date */
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += sksize;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += sksize;
#ifdef DEBUG_RX_TRACE
printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
@@ -2981,13 +2965,13 @@ wv_packet_rcv(struct net_device * dev)
/* Check status */
if((status & RX_RCV_OK) != RX_RCV_OK)
{
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
if(status & RX_NO_SFD)
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if(status & RX_CRC_ERR)
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if(status & RX_OVRRUN)
- lp->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
#ifdef DEBUG_RX_FAIL
printk(KERN_DEBUG "%s: wv_packet_rcv(): packet not received ok, status = 0x%x\n",
@@ -3074,7 +3058,7 @@ wv_packet_write(struct net_device * dev,
dev->trans_start = jiffies;
/* Keep stats up to date */
- lp->stats.tx_bytes += length;
+ dev->stats.tx_bytes += length;
spin_unlock_irqrestore(&lp->spinlock, flags);
@@ -4107,7 +4091,7 @@ wavelan_interrupt(int irq,
printk(KERN_INFO "%s: wv_interrupt(): receive buffer overflow\n",
dev->name);
#endif
- lp->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
lp->overrunning = 1;
}
@@ -4156,7 +4140,7 @@ wavelan_interrupt(int irq,
/* Check for possible errors */
if((tx_status & TX_OK) != TX_OK)
{
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if(tx_status & TX_FRTL)
{
@@ -4171,14 +4155,14 @@ wavelan_interrupt(int irq,
printk(KERN_DEBUG "%s: wv_interrupt(): DMA underrun\n",
dev->name);
#endif
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
}
if(tx_status & TX_LOST_CTS)
{
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG "%s: wv_interrupt(): no CTS\n", dev->name);
#endif
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
}
if(tx_status & TX_LOST_CRS)
{
@@ -4186,14 +4170,14 @@ wavelan_interrupt(int irq,
printk(KERN_DEBUG "%s: wv_interrupt(): no carrier\n",
dev->name);
#endif
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
}
if(tx_status & TX_HRT_BEAT)
{
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG "%s: wv_interrupt(): heart beat\n", dev->name);
#endif
- lp->stats.tx_heartbeat_errors++;
+ dev->stats.tx_heartbeat_errors++;
}
if(tx_status & TX_DEFER)
{
@@ -4217,14 +4201,14 @@ wavelan_interrupt(int irq,
#endif
if(!(tx_status & TX_NCOL_MASK))
{
- lp->stats.collisions += 0x10;
+ dev->stats.collisions += 0x10;
}
}
}
} /* if(!(tx_status & TX_OK)) */
- lp->stats.collisions += (tx_status & TX_NCOL_MASK);
- lp->stats.tx_packets++;
+ dev->stats.collisions += (tx_status & TX_NCOL_MASK);
+ dev->stats.tx_packets++;
netif_wake_queue(dev);
outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Acknowledge the interrupt */
@@ -4452,6 +4436,19 @@ wavelan_close(struct net_device * dev)
return 0;
}
+static const struct net_device_ops wavelan_netdev_ops = {
+ .ndo_open = wavelan_open,
+ .ndo_stop = wavelan_close,
+ .ndo_start_xmit = wavelan_packet_xmit,
+ .ndo_set_multicast_list = wavelan_set_multicast_list,
+#ifdef SET_MAC_ADDRESS
+ .ndo_set_mac_address = wavelan_set_mac_address,
+#endif
+ .ndo_tx_timeout = wavelan_watchdog,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*------------------------------------------------------------------*/
/*
* wavelan_attach() creates an "instance" of the driver, allocating
@@ -4512,17 +4509,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
lp->dev = dev;
/* wavelan NET3 callbacks */
- dev->open = &wavelan_open;
- dev->stop = &wavelan_close;
- dev->hard_start_xmit = &wavelan_packet_xmit;
- dev->get_stats = &wavelan_get_stats;
- dev->set_multicast_list = &wavelan_set_multicast_list;
-#ifdef SET_MAC_ADDRESS
- dev->set_mac_address = &wavelan_set_mac_address;
-#endif /* SET_MAC_ADDRESS */
-
- /* Set the watchdog timer */
- dev->tx_timeout = &wavelan_watchdog;
+ dev->netdev_ops = &wavelan_netdev_ops;
dev->watchdog_timeo = WATCHDOG_JIFFIES;
SET_ETHTOOL_OPS(dev, &ops);
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 628192d7248..706fd3007d2 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -576,7 +576,6 @@ struct wavepoint_table
/****************************** TYPES ******************************/
/* Shortcuts */
-typedef struct net_device_stats en_stats;
typedef struct iw_statistics iw_stats;
typedef struct iw_quality iw_qual;
typedef struct iw_freq iw_freq;
@@ -592,8 +591,6 @@ typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */
* For each network interface, Linux keep data in two structure. "device"
* keep the generic data (same format for everybody) and "net_local" keep
* the additional specific data.
- * Note that some of this specific data is in fact generic (en_stats, for
- * example).
*/
struct net_local
{
@@ -601,7 +598,6 @@ struct net_local
struct net_device * dev; /* Reverse link... */
spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
struct pcmcia_device * link; /* pcmcia structure */
- en_stats stats; /* Ethernet interface statistics */
int nresets; /* Number of hw resets */
u_char configured; /* If it is configured */
u_char reconfig_82593; /* Need to reconfigure the controller */
@@ -694,8 +690,6 @@ static void
static void
wv_init_info(struct net_device *); /* display startup info */
/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static en_stats *
- wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
static iw_stats *
wavelan_get_wireless_stats(struct net_device *);
/* ----------------------- PACKET RECEPTION ----------------------- */
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 59bb3a55ab4..8bce1a550a2 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -606,7 +606,7 @@ struct wl3501_card {
u8 reg_domain;
u8 version[2];
struct wl3501_scan_confirm bss_set[20];
- struct net_device_stats stats;
+
struct iw_statistics wstats;
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index c99a1b6b948..1f64d6033ab 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -44,6 +44,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/wireless.h>
+#include <linux/ieee80211.h>
#include <net/iw_handler.h>
@@ -111,12 +112,6 @@ static void wl3501_release(struct pcmcia_device *link);
*/
static dev_info_t wl3501_dev_info = "wl3501_cs";
-static int wl3501_chan2freq[] = {
- [0] = 2412, [1] = 2417, [2] = 2422, [3] = 2427, [4] = 2432,
- [5] = 2437, [6] = 2442, [7] = 2447, [8] = 2452, [9] = 2457,
- [10] = 2462, [11] = 2467, [12] = 2472, [13] = 2477,
-};
-
static const struct {
int reg_domain;
int min, max, deflt;
@@ -1005,7 +1000,7 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
if (!skb) {
printk(KERN_WARNING "%s: Can't alloc a sk_buff of size %d.\n",
dev->name, pkt_len);
- this->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
} else {
skb->dev = dev;
skb_reserve(skb, 2); /* IP headers on 16 bytes boundaries */
@@ -1013,8 +1008,8 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
wl3501_receive(this, skb->data, pkt_len);
skb_put(skb, pkt_len);
skb->protocol = eth_type_trans(skb, dev);
- this->stats.rx_packets++;
- this->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
netif_rx(skb);
}
}
@@ -1316,7 +1311,7 @@ out:
static void wl3501_tx_timeout(struct net_device *dev)
{
struct wl3501_card *this = netdev_priv(dev);
- struct net_device_stats *stats = &this->stats;
+ struct net_device_stats *stats = &dev->stats;
unsigned long flags;
int rc;
@@ -1351,11 +1346,11 @@ static int wl3501_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (enabled)
wl3501_unblock_interrupt(this);
if (rc) {
- ++this->stats.tx_dropped;
+ ++dev->stats.tx_dropped;
netif_stop_queue(dev);
} else {
- ++this->stats.tx_packets;
- this->stats.tx_bytes += skb->len;
+ ++dev->stats.tx_packets;
+ dev->stats.tx_bytes += skb->len;
kfree_skb(skb);
if (this->tx_buffer_cnt < 2)
@@ -1405,13 +1400,6 @@ fail:
goto out;
}
-static struct net_device_stats *wl3501_get_stats(struct net_device *dev)
-{
- struct wl3501_card *this = netdev_priv(dev);
-
- return &this->stats;
-}
-
static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
{
struct wl3501_card *this = netdev_priv(dev);
@@ -1510,7 +1498,7 @@ static int wl3501_get_freq(struct net_device *dev, struct iw_request_info *info,
{
struct wl3501_card *this = netdev_priv(dev);
- wrqu->freq.m = wl3501_chan2freq[this->chan - 1] * 100000;
+ wrqu->freq.m = ieee80211_dsss_chan_to_freq(this->chan) * 100000;
wrqu->freq.e = 1;
return 0;
}
@@ -1895,6 +1883,16 @@ static const struct iw_handler_def wl3501_handler_def = {
.get_wireless_stats = wl3501_get_wireless_stats,
};
+static const struct net_device_ops wl3501_netdev_ops = {
+ .ndo_open = wl3501_open,
+ .ndo_stop = wl3501_close,
+ .ndo_start_xmit = wl3501_hard_start_xmit,
+ .ndo_tx_timeout = wl3501_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/**
* wl3501_attach - creates an "instance" of the driver
*
@@ -1927,17 +1925,16 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
dev = alloc_etherdev(sizeof(struct wl3501_card));
if (!dev)
goto out_link;
- dev->open = wl3501_open;
- dev->stop = wl3501_close;
- dev->hard_start_xmit = wl3501_hard_start_xmit;
- dev->tx_timeout = wl3501_tx_timeout;
+
+
+ dev->netdev_ops = &wl3501_netdev_ops;
dev->watchdog_timeo = 5 * HZ;
- dev->get_stats = wl3501_get_stats;
+
this = netdev_priv(dev);
this->wireless_data.spy_data = &this->spy_data;
this->p_dev = p_dev;
dev->wireless_data = &this->wireless_data;
- dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def;
+ dev->wireless_handlers = &wl3501_handler_def;
SET_ETHTOOL_OPS(dev, &ops);
netif_stop_queue(dev);
p_dev->priv = p_dev->irq.Instance = dev;
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index b45c27d42fd..9b244c96b22 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -328,8 +328,8 @@ static void zd1201_usbrx(struct urb *urb)
memcpy(skb_put(skb, 2), &data[datalen-24], 2);
memcpy(skb_put(skb, len), data, len);
skb->protocol = eth_type_trans(skb, zd->dev);
- zd->stats.rx_packets++;
- zd->stats.rx_bytes += skb->len;
+ zd->dev->stats.rx_packets++;
+ zd->dev->stats.rx_bytes += skb->len;
netif_rx(skb);
goto resubmit;
}
@@ -384,8 +384,8 @@ static void zd1201_usbrx(struct urb *urb)
memcpy(skb_put(skb, len), data+8, len);
}
skb->protocol = eth_type_trans(skb, zd->dev);
- zd->stats.rx_packets++;
- zd->stats.rx_bytes += skb->len;
+ zd->dev->stats.rx_packets++;
+ zd->dev->stats.rx_bytes += skb->len;
netif_rx(skb);
}
resubmit:
@@ -787,7 +787,7 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct urb *urb = zd->tx_urb;
if (!zd->mac_enabled || zd->monitor) {
- zd->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
kfree_skb(skb);
return 0;
}
@@ -817,12 +817,12 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
err = usb_submit_urb(zd->tx_urb, GFP_ATOMIC);
if (err) {
- zd->stats.tx_errors++;
+ dev->stats.tx_errors++;
netif_start_queue(dev);
return err;
}
- zd->stats.tx_packets++;
- zd->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev->trans_start = jiffies;
kfree_skb(skb);
@@ -838,7 +838,7 @@ static void zd1201_tx_timeout(struct net_device *dev)
dev_warn(&zd->usb->dev, "%s: TX timeout, shooting down urb\n",
dev->name);
usb_unlink_urb(zd->tx_urb);
- zd->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* Restart the timeout to quiet the watchdog: */
dev->trans_start = jiffies;
}
@@ -861,13 +861,6 @@ static int zd1201_set_mac_address(struct net_device *dev, void *p)
return zd1201_mac_reset(zd);
}
-static struct net_device_stats *zd1201_get_stats(struct net_device *dev)
-{
- struct zd1201 *zd = netdev_priv(dev);
-
- return &zd->stats;
-}
-
static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
{
struct zd1201 *zd = netdev_priv(dev);
@@ -919,10 +912,9 @@ static int zd1201_set_freq(struct net_device *dev,
if (freq->e == 0)
channel = freq->m;
else {
- if (freq->m >= 2482)
- channel = 14;
- if (freq->m >= 2407)
- channel = (freq->m-2407)/5;
+ channel = ieee80211_freq_to_dsss_chan(freq->m);
+ if (channel < 0)
+ channel = 0;
}
err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel);
@@ -1725,6 +1717,18 @@ static const struct iw_handler_def zd1201_iw_handlers = {
.get_wireless_stats = zd1201_get_wireless_stats,
};
+static const struct net_device_ops zd1201_netdev_ops = {
+ .ndo_open = zd1201_net_open,
+ .ndo_stop = zd1201_net_stop,
+ .ndo_start_xmit = zd1201_hard_start_xmit,
+ .ndo_tx_timeout = zd1201_tx_timeout,
+ .ndo_set_multicast_list = zd1201_set_multicast,
+ .ndo_set_mac_address = zd1201_set_mac_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int zd1201_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
@@ -1777,16 +1781,9 @@ static int zd1201_probe(struct usb_interface *interface,
if (err)
goto err_start;
- dev->open = zd1201_net_open;
- dev->stop = zd1201_net_stop;
- dev->get_stats = zd1201_get_stats;
- dev->wireless_handlers =
- (struct iw_handler_def *)&zd1201_iw_handlers;
- dev->hard_start_xmit = zd1201_hard_start_xmit;
+ dev->netdev_ops = &zd1201_netdev_ops;
+ dev->wireless_handlers = &zd1201_iw_handlers;
dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
- dev->tx_timeout = zd1201_tx_timeout;
- dev->set_multicast_list = zd1201_set_multicast;
- dev->set_mac_address = zd1201_set_mac_address;
strcpy(dev->name, "wlan%d");
err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR,
diff --git a/drivers/net/wireless/zd1201.h b/drivers/net/wireless/zd1201.h
index 235f0ee34b2..dd7ea1f35be 100644
--- a/drivers/net/wireless/zd1201.h
+++ b/drivers/net/wireless/zd1201.h
@@ -26,7 +26,6 @@ struct zd1201 {
struct usb_device *usb;
int removed;
struct net_device *dev;
- struct net_device_stats stats;
struct iw_statistics iwstats;
int endp_in;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index f1519143f8a..2c813d87092 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1616,3 +1616,24 @@ int zd_chip_set_multicast_hash(struct zd_chip *chip,
return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
}
+
+u64 zd_chip_get_tsf(struct zd_chip *chip)
+{
+ int r;
+ static const zd_addr_t aw_pt_bi_addr[] =
+ { CR_TSF_LOW_PART, CR_TSF_HIGH_PART };
+ u32 values[2];
+ u64 tsf;
+
+ mutex_lock(&chip->mutex);
+ r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
+ ARRAY_SIZE(aw_pt_bi_addr));
+ mutex_unlock(&chip->mutex);
+ if (r)
+ return 0;
+
+ tsf = values[1];
+ tsf = (tsf << 32) | values[0];
+
+ return tsf;
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index f8c061a9b6e..ee42751d5cb 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -950,4 +950,6 @@ static inline void zd_mc_add_addr(struct zd_mc_hash *hash, u8 *addr)
int zd_chip_set_multicast_hash(struct zd_chip *chip,
struct zd_mc_hash *hash);
+u64 zd_chip_get_tsf(struct zd_chip *chip);
+
#endif /* _ZD_CHIP_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
index 5200db40561..6ac597ffd3b 100644
--- a/drivers/net/wireless/zd1211rw/zd_def.h
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -33,8 +33,13 @@ typedef u16 __nocast zd_addr_t;
#ifdef DEBUG
# define dev_dbg_f(dev, fmt, args...) \
dev_printk_f(KERN_DEBUG, dev, fmt, ## args)
+# define dev_dbg_f_limit(dev, fmt, args...) do { \
+ if (net_ratelimit()) \
+ dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \
+} while (0)
#else
# define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0)
+# define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0)
#endif /* DEBUG */
#ifdef DEBUG
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index a611ad85798..c3a51266de2 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -170,10 +170,10 @@ int zd_mac_init_hw(struct ieee80211_hw *hw)
goto disable_int;
r = zd_reg2alpha2(mac->regdomain, alpha2);
- if (!r)
- regulatory_hint(hw->wiphy, alpha2);
+ if (r)
+ goto disable_int;
- r = 0;
+ r = regulatory_hint(hw->wiphy, alpha2);
disable_int:
zd_chip_disable_int(chip);
out:
@@ -575,13 +575,17 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
r = fill_ctrlset(mac, skb);
if (r)
- return r;
+ goto fail;
info->rate_driver_data[0] = hw;
r = zd_usb_tx(&mac->chip.usb, skb);
if (r)
- return r;
+ goto fail;
+ return 0;
+
+fail:
+ dev_kfree_skb(skb);
return 0;
}
@@ -768,13 +772,23 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
if (!beacon)
return -ENOMEM;
r = zd_mac_config_beacon(hw, beacon);
+ kfree_skb(beacon);
+
if (r < 0)
return r;
- r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
- hw->conf.beacon_int);
+ }
+
+ 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;
- kfree_skb(beacon);
}
} else
associated = is_valid_ether_addr(conf->bssid);
@@ -793,10 +807,9 @@ static void zd_process_intr(struct work_struct *work)
struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4));
- if (int_status & INT_CFG_NEXT_BCN) {
- if (net_ratelimit())
- dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
- } else
+ if (int_status & INT_CFG_NEXT_BCN)
+ dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
+ else
dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
zd_chip_enable_hwint(&mac->chip);
@@ -926,6 +939,12 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
}
}
+static u64 zd_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct zd_mac *mac = zd_hw_mac(hw);
+ return zd_chip_get_tsf(&mac->chip);
+}
+
static const struct ieee80211_ops zd_ops = {
.tx = zd_op_tx,
.start = zd_op_start,
@@ -936,6 +955,7 @@ static const struct ieee80211_ops zd_ops = {
.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,
};
struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
@@ -967,7 +987,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SIGNAL_DB;
+ IEEE80211_HW_SIGNAL_UNSPEC;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_MESH_POINT) |
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index 7207bfd2e6c..c875ee05e22 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -86,6 +86,7 @@ int zd_rf_init_hw(struct zd_rf *rf, u8 type)
case AL7230B_RF:
r = zd_rf_init_al7230b(rf);
break;
+ case MAXIM_NEW_RF:
case UW2453_RF:
r = zd_rf_init_uw2453(rf);
break;
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index b5db57d2fcf..f0e5e943f6e 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -37,6 +37,7 @@
static struct usb_device_id usb_ids[] = {
/* ZD1211 */
{ USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 },
+ { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },
@@ -84,6 +85,7 @@ static struct usb_device_id usb_ids[] = {
{ USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B },
/* "Driverless" devices that need ejecting */
{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index cd6184ee08e..9f102a6535c 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -196,7 +196,7 @@ static void rx_refill_timeout(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct netfront_info *np = netdev_priv(dev);
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
}
static int netfront_tx_slot_available(struct netfront_info *np)
@@ -328,7 +328,7 @@ static int xennet_open(struct net_device *dev)
xennet_alloc_rx_buffers(dev);
np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
}
spin_unlock_bh(&np->rx_lock);
@@ -979,7 +979,7 @@ err:
RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do);
if (!more_to_do)
- __netif_rx_complete(napi);
+ __napi_complete(napi);
local_irq_restore(flags);
}
@@ -1317,7 +1317,7 @@ static irqreturn_t xennet_interrupt(int irq, void *dev_id)
xennet_tx_buf_gc(dev);
/* Under tx_lock: protects access to rx shared-ring indexes. */
if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
}
spin_unlock_irqrestore(&np->tx_lock, flags);
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
index 03a3f34e903..a12a7211c98 100644
--- a/drivers/net/xtsonic.c
+++ b/drivers/net/xtsonic.c
@@ -183,7 +183,7 @@ static int __init sonic_probe1(struct net_device *dev)
if (lp->descriptors == NULL) {
printk(KERN_ERR "%s: couldn't alloc DMA memory for "
- " descriptors.\n", lp->device->bus_id);
+ " descriptors.\n", dev_name(lp->device));
goto out;
}
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 2f1645dcb8c..7477ffdcddb 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -107,9 +107,9 @@ static int gx_fix;
#include <asm/io.h>
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v1.05 1/09/2001 Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v1.05 1/09/2001 Written by Donald Becker <becker@scyld.com>\n"
+ KERN_INFO " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index f0b15c9347d..0a6992d8611 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -358,6 +358,17 @@ static void znet_set_multicast_list (struct net_device *dev)
* multicast address configured isn't equal to IFF_ALLMULTI */
}
+static const struct net_device_ops znet_netdev_ops = {
+ .ndo_open = znet_open,
+ .ndo_stop = znet_close,
+ .ndo_start_xmit = znet_send_packet,
+ .ndo_set_multicast_list = znet_set_multicast_list,
+ .ndo_tx_timeout = znet_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* The Z-Note probe is pretty easy. The NETIDBLK exists in the safe-to-probe
BIOS area. We just scan for the signature, and pull the vital parameters
out of the structure. */
@@ -440,11 +451,7 @@ static int __init znet_probe (void)
znet->tx_end = znet->tx_start + znet->tx_buf_len;
/* The ZNET-specific entries in the device structure. */
- dev->open = &znet_open;
- dev->hard_start_xmit = &znet_send_packet;
- dev->stop = &znet_close;
- dev->set_multicast_list = &znet_set_multicast_list;
- dev->tx_timeout = znet_tx_timeout;
+ dev->netdev_ops = &znet_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
err = register_netdev(dev);
if (err)
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 2e03b6d796d..e76d715e434 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -393,16 +393,21 @@ oprofile_write_reserve(struct op_entry *entry, struct pt_regs * const regs,
return;
fail:
+ entry->event = NULL;
cpu_buf->sample_lost_overflow++;
}
int oprofile_add_data(struct op_entry *entry, unsigned long val)
{
+ if (!entry->event)
+ return 0;
return op_cpu_buffer_add_data(entry, val);
}
int oprofile_write_commit(struct op_entry *entry)
{
+ if (!entry->event)
+ return -EINVAL;
return op_cpu_buffer_write_commit(entry);
}
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
index 63f81c44846..272995d2029 100644
--- a/drivers/oprofile/cpu_buffer.h
+++ b/drivers/oprofile/cpu_buffer.h
@@ -66,6 +66,13 @@ static inline void op_cpu_buffer_reset(int cpu)
cpu_buf->last_task = NULL;
}
+/*
+ * op_cpu_buffer_add_data() and op_cpu_buffer_write_commit() may be
+ * called only if op_cpu_buffer_write_reserve() did not return NULL or
+ * entry->event != NULL, otherwise entry->size or entry->event will be
+ * used uninitialized.
+ */
+
struct op_sample
*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size);
int op_cpu_buffer_write_commit(struct op_entry *entry);
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index d539d9df88e..bb5a1c9597c 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -479,7 +479,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
res = &dino_dev->hba.lmmio_space;
res->flags = IORESOURCE_MEM;
size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)",
- bus->bridge->bus_id);
+ dev_name(bus->bridge));
res->name = kmalloc(size+1, GFP_KERNEL);
if(res->name)
strcpy((char *)res->name, name);
@@ -493,7 +493,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
struct list_head *ln, *tmp_ln;
printk(KERN_ERR "Dino: cannot attach bus %s\n",
- bus->bridge->bus_id);
+ dev_name(bus->bridge));
/* kill the bus, we can't do anything with it */
list_for_each_safe(ln, tmp_ln, &bus->devices) {
struct pci_dev *dev = pci_dev_b(ln);
@@ -587,7 +587,7 @@ dino_fixup_bus(struct pci_bus *bus)
bus->resource[i+1] = &res[i];
}
- } else if(bus->self) {
+ } else if (bus->parent) {
int i;
pci_read_bridge_bases(bus);
@@ -611,12 +611,12 @@ dino_fixup_bus(struct pci_bus *bus)
}
DBG("DEBUG %s assigning %d [0x%lx,0x%lx]\n",
- bus->self->dev.bus_id, i,
+ dev_name(&bus->self->dev), i,
bus->self->resource[i].start,
bus->self->resource[i].end);
pci_assign_resource(bus->self, i);
DBG("DEBUG %s after assign %d [0x%lx,0x%lx]\n",
- bus->self->dev.bus_id, i,
+ dev_name(&bus->self->dev), i,
bus->self->resource[i].start,
bus->self->resource[i].end);
}
@@ -1026,7 +1026,8 @@ static int __init dino_probe(struct parisc_device *dev)
dino_current_bus = bus->subordinate + 1;
pci_bus_assign_resources(bus);
} else {
- printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n", dev->dev.bus_id, dino_current_bus);
+ printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n",
+ dev_name(&dev->dev), dino_current_bus);
/* increment the bus number in case of duplicates */
dino_current_bus++;
}
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index e76db9e4d50..d3363291769 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -186,29 +186,34 @@ void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp)
*irqp = irq;
}
-static struct device *next_device(struct klist_iter *i)
+struct gsc_fixup_struct {
+ void (*choose_irq)(struct parisc_device *, void *);
+ void *ctrl;
+};
+
+static int gsc_fixup_irqs_callback(struct device *dev, void *data)
{
- struct klist_node * n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+ struct parisc_device *padev = to_parisc_device(dev);
+ struct gsc_fixup_struct *gf = data;
+
+ /* work-around for 715/64 and others which have parent
+ at path [5] and children at path [5/0/x] */
+ if (padev->id.hw_type == HPHW_FAULTY)
+ gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq);
+ gf->choose_irq(padev, gf->ctrl);
+
+ return 0;
}
void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
void (*choose_irq)(struct parisc_device *, void *))
{
- struct device *dev;
- struct klist_iter i;
-
- klist_iter_init(&parent->dev.klist_children, &i);
- while ((dev = next_device(&i))) {
- struct parisc_device *padev = to_parisc_device(dev);
-
- /* work-around for 715/64 and others which have parent
- at path [5] and children at path [5/0/x] */
- if (padev->id.hw_type == HPHW_FAULTY)
- return gsc_fixup_irqs(padev, ctrl, choose_irq);
- choose_irq(padev, ctrl);
- }
- klist_iter_exit(&i);
+ struct gsc_fixup_struct data = {
+ .choose_irq = choose_irq,
+ .ctrl = ctrl,
+ };
+
+ device_for_each_child(&parent->dev, &data, gsc_fixup_irqs_callback);
}
int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 0797659ee01..501aaf1f253 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -487,7 +487,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
}
/* Check if pcidev behind a PPB */
- if (NULL != pcidev->bus->self) {
+ if (pcidev->bus->parent) {
/* Convert pcidev INTR_PIN into something we
** can lookup in the IRT.
*/
@@ -523,10 +523,9 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
#endif /* PCI_BRIDGE_FUNCS */
/*
- ** Locate the host slot the PPB nearest the Host bus
- ** adapter.
- */
- while (NULL != p->parent->self)
+ * Locate the host slot of the PPB.
+ */
+ while (p->parent->parent)
p = p->parent;
intr_slot = PCI_SLOT(p->self->devfn);
@@ -709,11 +708,14 @@ static void iosapic_set_affinity_irq(unsigned int irq,
struct vector_info *vi = iosapic_get_vector(irq);
u32 d0, d1, dummy_d0;
unsigned long flags;
+ int dest_cpu;
- if (cpu_check_affinity(irq, dest))
+ dest_cpu = cpu_check_affinity(irq, dest);
+ if (dest_cpu < 0)
return;
- vi->txn_addr = txn_affinity_addr(irq, cpumask_first(dest));
+ irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu);
+ vi->txn_addr = txn_affinity_addr(irq, dest_cpu);
spin_lock_irqsave(&iosapic_lock, flags);
/* d1 contains the destination CPU, so only want to set that
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index d8233de8c75..59fbbf12836 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -644,7 +644,7 @@ lba_fixup_bus(struct pci_bus *bus)
** Properly Setup MMIO resources for this bus.
** pci_alloc_primary_bus() mangles this.
*/
- if (bus->self) {
+ if (bus->parent) {
int i;
/* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
@@ -802,7 +802,7 @@ lba_fixup_bus(struct pci_bus *bus)
** Can't fixup here anyway....garr...
*/
if (fbb_enable) {
- if (bus->self) {
+ if (bus->parent) {
u8 control;
/* enable on PPB */
(void) pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &control);
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 3fac8f81d59..e5999c4cedc 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -668,7 +668,7 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
* @dev: instance of PCI owned by the driver that's asking
* @mask: number of address bits this PCI device can handle
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static int sba_dma_supported( struct device *dev, u64 mask)
{
@@ -680,8 +680,8 @@ static int sba_dma_supported( struct device *dev, u64 mask)
return(0);
}
- /* Documentation/DMA-mapping.txt tells drivers to try 64-bit first,
- * then fall back to 32-bit if that fails.
+ /* Documentation/PCI/PCI-DMA-mapping.txt tells drivers to try 64-bit
+ * first, then fall back to 32-bit if that fails.
* We are just "encouraging" 32-bit DMA masks here since we can
* never allow IOMMU bypass unless we add special support for ZX1.
*/
@@ -706,7 +706,7 @@ static int sba_dma_supported( struct device *dev, u64 mask)
* @size: number of bytes to map in driver buffer.
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static dma_addr_t
sba_map_single(struct device *dev, void *addr, size_t size,
@@ -785,7 +785,7 @@ sba_map_single(struct device *dev, void *addr, size_t size,
* @size: number of bytes mapped in driver buffer.
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static void
sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
@@ -861,7 +861,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
* @size: number of bytes mapped in driver buffer.
* @dma_handle: IOVA of new buffer.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static void *sba_alloc_consistent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
@@ -892,7 +892,7 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size,
* @vaddr: virtual address IOVA of "consistent" buffer.
* @dma_handler: IO virtual address of "consistent" buffer.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static void
sba_free_consistent(struct device *hwdev, size_t size, void *vaddr,
@@ -927,7 +927,7 @@ int dump_run_sg = 0;
* @nents: number of entries in list
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static int
sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
@@ -1011,7 +1011,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
* @nents: number of entries in list
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static void
sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
@@ -1206,30 +1206,48 @@ sba_alloc_pdir(unsigned int pdir_size)
return (void *) pdir_base;
}
-static struct device *next_device(struct klist_iter *i)
+struct ibase_data_struct {
+ struct ioc *ioc;
+ int ioc_num;
+};
+
+static int setup_ibase_imask_callback(struct device *dev, void *data)
{
- struct klist_node * n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+ /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
+ extern void lba_set_iregs(struct parisc_device *, u32, u32);
+ struct parisc_device *lba = to_parisc_device(dev);
+ struct ibase_data_struct *ibd = data;
+ int rope_num = (lba->hpa.start >> 13) & 0xf;
+ if (rope_num >> 3 == ibd->ioc_num)
+ lba_set_iregs(lba, ibd->ioc->ibase, ibd->ioc->imask);
+ return 0;
}
/* setup Mercury or Elroy IBASE/IMASK registers. */
static void
setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
{
- /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
- extern void lba_set_iregs(struct parisc_device *, u32, u32);
- struct device *dev;
- struct klist_iter i;
-
- klist_iter_init(&sba->dev.klist_children, &i);
- while ((dev = next_device(&i))) {
- struct parisc_device *lba = to_parisc_device(dev);
- int rope_num = (lba->hpa.start >> 13) & 0xf;
- if (rope_num >> 3 == ioc_num)
- lba_set_iregs(lba, ioc->ibase, ioc->imask);
- }
- klist_iter_exit(&i);
+ struct ibase_data_struct ibase_data = {
+ .ioc = ioc,
+ .ioc_num = ioc_num,
+ };
+
+ device_for_each_child(&sba->dev, &ibase_data,
+ setup_ibase_imask_callback);
+}
+
+#ifdef SBA_AGP_SUPPORT
+static int
+sba_ioc_find_quicksilver(struct device *dev, void *data)
+{
+ int *agp_found = data;
+ struct parisc_device *lba = to_parisc_device(dev);
+
+ if (IS_QUICKSILVER(lba))
+ *agp_found = 1;
+ return 0;
}
+#endif
static void
sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
@@ -1332,9 +1350,6 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
#ifdef SBA_AGP_SUPPORT
-{
- struct klist_iter i;
- struct device *dev = NULL;
/*
** If an AGP device is present, only use half of the IOV space
@@ -1344,13 +1359,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
** We program the next pdir index after we stop w/ a key for
** the GART code to handshake on.
*/
- klist_iter_init(&sba->dev.klist_children, &i);
- while ((dev = next_device(&i))) {
- struct parisc_device *lba = to_parisc_device(dev);
- if (IS_QUICKSILVER(lba))
- agp_found = 1;
- }
- klist_iter_exit(&i);
+ device_for_each_child(&sba->dev, &agp_found, sba_ioc_find_quicksilver);
if (agp_found && sba_reserve_agpgart) {
printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",
@@ -1358,9 +1367,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
ioc->pdir_size /= 2;
ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE;
}
-}
#endif /*SBA_AGP_SUPPORT*/
-
}
static void
diff --git a/drivers/parport/parport_atari.c b/drivers/parport/parport_atari.c
index ad4cdd25613..0b28fccec03 100644
--- a/drivers/parport/parport_atari.c
+++ b/drivers/parport/parport_atari.c
@@ -84,7 +84,7 @@ parport_atari_frob_control(struct parport *p, unsigned char mask,
static unsigned char
parport_atari_read_status(struct parport *p)
{
- return ((mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) |
+ return ((st_mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) |
PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR);
}
@@ -193,9 +193,9 @@ static int __init parport_atari_init(void)
sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
local_irq_restore(flags);
/* MFP port I0 as input. */
- mfp.data_dir &= ~1;
+ st_mfp.data_dir &= ~1;
/* MFP port I0 interrupt on high->low edge. */
- mfp.active_edge &= ~1;
+ st_mfp.active_edge &= ~1;
p = parport_register_port((unsigned long)&sound_ym.wd_data,
IRQ_MFP_BUSY, PARPORT_DMA_NONE,
&parport_atari_ops);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 101ed49a2d1..032db815b0f 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -64,6 +64,11 @@ struct parport_pc_pci {
static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma)
{
+ /* the rule described below doesn't hold for this device */
+ if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
+ dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+ dev->subsystem_device == 0x0299)
+ return -ENODEV;
/*
* Netmos uses the subdevice ID to indicate the number of parallel
* and serial ports. The form is 0x00PS, where <P> is the number of
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index f5a662a50ac..26c536b51c5 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -330,6 +330,14 @@ parse_dmar_table(void)
entry_header = (struct acpi_dmar_header *)(dmar + 1);
while (((unsigned long)entry_header) <
(((unsigned long)dmar) + dmar_tbl->length)) {
+ /* Avoid looping forever on bad ACPI tables */
+ if (entry_header->length == 0) {
+ printk(KERN_WARNING PREFIX
+ "Invalid 0-length structure\n");
+ ret = -EINVAL;
+ break;
+ }
+
dmar_table_print_dmar_entry(entry_header);
switch (entry_header->type) {
@@ -491,7 +499,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
int map_size;
u32 ver;
static int iommu_allocated = 0;
- int agaw;
+ int agaw = 0;
iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
if (!iommu)
@@ -507,6 +515,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
+#ifdef CONFIG_DMAR
agaw = iommu_calculate_agaw(iommu);
if (agaw < 0) {
printk(KERN_ERR
@@ -514,6 +523,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
iommu->seq_id);
goto error;
}
+#endif
iommu->agaw = agaw;
/* the registers might be more than one page */
@@ -571,19 +581,49 @@ static inline void reclaim_free_desc(struct q_inval *qi)
}
}
+static int qi_check_fault(struct intel_iommu *iommu, int index)
+{
+ u32 fault;
+ int head;
+ struct q_inval *qi = iommu->qi;
+ int wait_index = (index + 1) % QI_LENGTH;
+
+ fault = readl(iommu->reg + DMAR_FSTS_REG);
+
+ /*
+ * If IQE happens, the head points to the descriptor associated
+ * with the error. No new descriptors are fetched until the IQE
+ * is cleared.
+ */
+ if (fault & DMA_FSTS_IQE) {
+ head = readl(iommu->reg + DMAR_IQH_REG);
+ if ((head >> 4) == index) {
+ memcpy(&qi->desc[index], &qi->desc[wait_index],
+ sizeof(struct qi_desc));
+ __iommu_flush_cache(iommu, &qi->desc[index],
+ sizeof(struct qi_desc));
+ writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
/*
* Submit the queued invalidation descriptor to the remapping
* hardware unit and wait for its completion.
*/
-void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
+int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
{
+ int rc = 0;
struct q_inval *qi = iommu->qi;
struct qi_desc *hw, wait_desc;
int wait_index, index;
unsigned long flags;
if (!qi)
- return;
+ return 0;
hw = qi->desc;
@@ -601,7 +641,8 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
hw[index] = *desc;
- wait_desc.low = QI_IWD_STATUS_DATA(2) | QI_IWD_STATUS_WRITE | QI_IWD_TYPE;
+ wait_desc.low = QI_IWD_STATUS_DATA(QI_DONE) |
+ QI_IWD_STATUS_WRITE | QI_IWD_TYPE;
wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]);
hw[wait_index] = wait_desc;
@@ -612,13 +653,11 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
qi->free_head = (qi->free_head + 2) % QI_LENGTH;
qi->free_cnt -= 2;
- spin_lock(&iommu->register_lock);
/*
* update the HW tail register indicating the presence of
* new descriptors.
*/
writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG);
- spin_unlock(&iommu->register_lock);
while (qi->desc_status[wait_index] != QI_DONE) {
/*
@@ -628,15 +667,21 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
* a deadlock where the interrupt context can wait indefinitely
* for free slots in the queue.
*/
+ rc = qi_check_fault(iommu, index);
+ if (rc)
+ goto out;
+
spin_unlock(&qi->q_lock);
cpu_relax();
spin_lock(&qi->q_lock);
}
-
- qi->desc_status[index] = QI_DONE;
+out:
+ qi->desc_status[index] = qi->desc_status[wait_index] = QI_DONE;
reclaim_free_desc(qi);
spin_unlock_irqrestore(&qi->q_lock, flags);
+
+ return rc;
}
/*
@@ -649,13 +694,13 @@ void qi_global_iec(struct intel_iommu *iommu)
desc.low = QI_IEC_TYPE;
desc.high = 0;
+ /* should never fail */
qi_submit_sync(&desc, iommu);
}
int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
u64 type, int non_present_entry_flush)
{
-
struct qi_desc desc;
if (non_present_entry_flush) {
@@ -669,10 +714,7 @@ int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
| QI_CC_GRAN(type) | QI_CC_TYPE;
desc.high = 0;
- qi_submit_sync(&desc, iommu);
-
- return 0;
-
+ return qi_submit_sync(&desc, iommu);
}
int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
@@ -702,10 +744,7 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih)
| QI_IOTLB_AM(size_order);
- qi_submit_sync(&desc, iommu);
-
- return 0;
-
+ return qi_submit_sync(&desc, iommu);
}
/*
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index eacfb13998b..9aa4fe100a0 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -143,7 +143,7 @@ config HOTPLUG_PCI_SHPC
config HOTPLUG_PCI_RPA
tristate "RPA PCI Hotplug driver"
- depends on PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE
+ depends on PPC_PSERIES && EEH && !HOTPLUG_PCI_FAKE
help
Say Y here if you have a RPA system that supports PCI Hotplug.
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index e31fb91652c..2aa117c8cd8 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -5,11 +5,15 @@
obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
+
+# pciehp should be linked before acpiphp in order to allow the native driver
+# to attempt to bind first. We can then fall back to generic support.
+
+obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o
obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o
-obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index f09b1010d47..803d9ddd6e7 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -266,6 +266,8 @@ static int detect_ejectable_slots(struct pci_bus *pbus)
int found = acpi_pci_detect_ejectable(pbus);
if (!found) {
acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus);
+ if (!bridge_handle)
+ return 0;
acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
is_pci_dock_device, (void *)&found, NULL);
}
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index a13abf55d78..8450f4a6568 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -225,7 +225,8 @@ void cpqhp_shutdown_debugfs(void)
void cpqhp_create_debugfs_files(struct controller *ctrl)
{
- ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops);
+ ctrl->dentry = debugfs_create_file(dev_name(&ctrl->pci_dev->dev),
+ S_IRUGO, root, ctrl, &debug_ops);
}
void cpqhp_remove_debugfs_files(struct controller *ctrl)
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index b0e7de9e536..d8649e12729 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work)
* Tries hard not to re-enable already existing devices;
* also handles scanning of subfunctions.
*/
-static void pci_rescan_slot(struct pci_dev *temp)
+static int pci_rescan_slot(struct pci_dev *temp)
{
struct pci_bus *bus = temp->bus;
struct pci_dev *dev;
int func;
- int retval;
u8 hdr_type;
+ int count = 0;
if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
temp->hdr_type = hdr_type & 0x7f;
@@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp)
dbg("New device on %s function %x:%x\n",
bus->name, temp->devfn >> 3,
temp->devfn & 7);
- retval = pci_bus_add_device(dev);
- if (retval)
- dev_err(&dev->dev, "error adding "
- "device, continuing.\n");
- else
- add_slot(dev);
+ count++;
}
}
/* multifunction device? */
if (!(hdr_type & 0x80))
- return;
+ return count;
/* continue scanning for other functions */
for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
@@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp)
dbg("New device on %s function %x:%x\n",
bus->name, temp->devfn >> 3,
temp->devfn & 7);
- retval = pci_bus_add_device(dev);
- if (retval)
- dev_err(&dev->dev, "error adding "
- "device, continuing.\n");
- else
- add_slot(dev);
+ count++;
}
}
}
}
+
+ return count;
}
@@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus)
{
unsigned int devfn;
struct pci_dev *dev;
+ int retval;
+ int found = 0;
dev = alloc_pci_dev();
if (!dev)
return;
@@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus)
dev->sysdata = bus->sysdata;
for (devfn = 0; devfn < 0x100; devfn += 8) {
dev->devfn = devfn;
- pci_rescan_slot(dev);
+ found += pci_rescan_slot(dev);
+ }
+
+ if (found) {
+ pci_bus_assign_resources(bus);
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ /* Skip already-added devices */
+ if (dev->is_added)
+ continue;
+ retval = pci_bus_add_device(dev);
+ if (retval)
+ dev_err(&dev->dev,
+ "Error adding device, continuing\n");
+ else
+ add_slot(dev);
+ }
+ pci_bus_add_devices(bus);
}
kfree(dev);
}
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index db85284ffb6..39ae37589fd 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -111,6 +111,7 @@ struct controller {
int cmd_busy;
unsigned int no_cmd_complete:1;
unsigned int link_active_reporting:1;
+ unsigned int notification_enabled:1;
};
#define INT_BUTTON_IGNORE 0
@@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot);
extern int pciehp_unconfigure_device(struct slot *p_slot);
extern void pciehp_queue_pushbutton_work(struct work_struct *work);
struct controller *pcie_init(struct pcie_device *dev);
+int pcie_init_notification(struct controller *ctrl);
int pciehp_enable_slot(struct slot *p_slot);
int pciehp_disable_slot(struct slot *p_slot);
int pcie_enable_notification(struct controller *ctrl);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 5482d4ed825..681e3912b82 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -126,8 +126,10 @@ static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status)
mutex_lock(&slot->ctrl->crit_sect);
/* has it been >1 sec since our last toggle? */
- if ((get_seconds() - slot->last_emi_toggle) < 1)
+ if ((get_seconds() - slot->last_emi_toggle) < 1) {
+ mutex_unlock(&slot->ctrl->crit_sect);
return -EINVAL;
+ }
/* see what our current state is */
retval = get_lock_status(hotplug_slot, &value);
@@ -432,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
goto err_out_release_ctlr;
}
+ /* Enable events after we have setup the data structures */
+ rc = pcie_init_notification(ctrl);
+ if (rc) {
+ ctrl_err(ctrl, "Notification initialization failed\n");
+ goto err_out_release_ctlr;
+ }
+
/* Check if slot is occupied */
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
t_slot->hpc_ops->get_adapter_status(t_slot, &value);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 71a8012886b..7a16c6897bb 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl)
ctrl_warn(ctrl, "Cannot disable software notification\n");
}
-static int pcie_init_notification(struct controller *ctrl)
+int pcie_init_notification(struct controller *ctrl)
{
if (pciehp_request_irq(ctrl))
return -1;
@@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl)
pciehp_free_irq(ctrl);
return -1;
}
+ ctrl->notification_enabled = 1;
return 0;
}
static void pcie_shutdown_notification(struct controller *ctrl)
{
- pcie_disable_notification(ctrl);
- pciehp_free_irq(ctrl);
+ if (ctrl->notification_enabled) {
+ pcie_disable_notification(ctrl);
+ pciehp_free_irq(ctrl);
+ ctrl->notification_enabled = 0;
+ }
}
static int pcie_init_slot(struct controller *ctrl)
@@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev)
if (pcie_init_slot(ctrl))
goto abort_ctrl;
- if (pcie_init_notification(ctrl))
- goto abort_slot;
-
return ctrl;
-abort_slot:
- pcie_cleanup_slot(ctrl);
abort_ctrl:
kfree(ctrl);
abort:
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 3dfecb20d5e..f3f686581a9 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -61,6 +61,8 @@
/* global iommu list, set NULL for ignored DMAR units */
static struct intel_iommu **g_iommus;
+static int rwbf_quirk;
+
/*
* 0: Present
* 1-11: Reserved
@@ -268,7 +270,12 @@ static long list_size;
static void domain_remove_dev_info(struct dmar_domain *domain);
-int dmar_disabled;
+#ifdef CONFIG_DMAR_DEFAULT_ON
+int dmar_disabled = 0;
+#else
+int dmar_disabled = 1;
+#endif /*CONFIG_DMAR_DEFAULT_ON*/
+
static int __initdata dmar_map_gfx = 1;
static int dmar_forcedac;
static int intel_iommu_strict;
@@ -284,9 +291,12 @@ static int __init intel_iommu_setup(char *str)
if (!str)
return -EINVAL;
while (*str) {
- if (!strncmp(str, "off", 3)) {
+ if (!strncmp(str, "on", 2)) {
+ dmar_disabled = 0;
+ printk(KERN_INFO "Intel-IOMMU: enabled\n");
+ } else if (!strncmp(str, "off", 3)) {
dmar_disabled = 1;
- printk(KERN_INFO"Intel-IOMMU: disabled\n");
+ printk(KERN_INFO "Intel-IOMMU: disabled\n");
} else if (!strncmp(str, "igfx_off", 8)) {
dmar_map_gfx = 0;
printk(KERN_INFO
@@ -777,7 +787,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu)
u32 val;
unsigned long flag;
- if (!cap_rwbf(iommu->cap))
+ if (!rwbf_quirk && !cap_rwbf(iommu->cap))
return;
val = iommu->gcmd | DMA_GCMD_WBF;
@@ -3129,3 +3139,15 @@ static struct iommu_ops intel_iommu_ops = {
.unmap = intel_iommu_unmap_range,
.iova_to_phys = intel_iommu_iova_to_phys,
};
+
+static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
+{
+ /*
+ * Mobile 4 Series Chipset neglects to set RWBF capability,
+ * but needs it:
+ */
+ printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n");
+ rwbf_quirk = 1;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index f78371b2252..b721c2fbe8f 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -20,7 +20,7 @@ struct irq_2_iommu {
u8 irte_mask;
};
-#ifdef CONFIG_SPARSE_IRQ
+#ifdef CONFIG_GENERIC_HARDIRQS
static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
{
struct irq_2_iommu *iommu;
@@ -207,7 +207,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
return index;
}
-static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
+static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
{
struct qi_desc desc;
@@ -215,7 +215,7 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
| QI_IEC_SELECTIVE;
desc.high = 0;
- qi_submit_sync(&desc, iommu);
+ return qi_submit_sync(&desc, iommu);
}
int map_irq_to_irte_handle(int irq, u16 *sub_handle)
@@ -283,6 +283,7 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
int modify_irte(int irq, struct irte *irte_modified)
{
+ int rc;
int index;
struct irte *irte;
struct intel_iommu *iommu;
@@ -303,14 +304,15 @@ int modify_irte(int irq, struct irte *irte_modified)
set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1));
__iommu_flush_cache(iommu, irte, sizeof(*irte));
- qi_flush_iec(iommu, index, 0);
-
+ rc = qi_flush_iec(iommu, index, 0);
spin_unlock(&irq_2_ir_lock);
- return 0;
+
+ return rc;
}
int flush_irte(int irq)
{
+ int rc;
int index;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
@@ -326,10 +328,10 @@ int flush_irte(int irq)
index = irq_iommu->irte_index + irq_iommu->sub_handle;
- qi_flush_iec(iommu, index, irq_iommu->irte_mask);
+ rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
spin_unlock(&irq_2_ir_lock);
- return 0;
+ return rc;
}
struct intel_iommu *map_ioapic_to_ir(int apic)
@@ -355,6 +357,7 @@ struct intel_iommu *map_dev_to_ir(struct pci_dev *dev)
int free_irte(int irq)
{
+ int rc = 0;
int index, i;
struct irte *irte;
struct intel_iommu *iommu;
@@ -375,7 +378,7 @@ int free_irte(int irq)
if (!irq_iommu->sub_handle) {
for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
set_64bit((unsigned long *)irte, 0);
- qi_flush_iec(iommu, index, irq_iommu->irte_mask);
+ rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
}
irq_iommu->iommu = NULL;
@@ -385,7 +388,7 @@ int free_irte(int irq)
spin_unlock(&irq_2_ir_lock);
- return 0;
+ return rc;
}
static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index b4a90badd0a..baba2eb5367 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -103,6 +103,14 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
}
}
+static inline __attribute_const__ u32 msi_mask(unsigned x)
+{
+ /* Don't shift by >= width of type */
+ if (x >= 5)
+ return 0xffffffff;
+ return (1 << (1 << x)) - 1;
+}
+
static void msix_flush_writes(struct irq_desc *desc)
{
struct msi_desc *entry;
@@ -398,21 +406,18 @@ static int msi_capability_init(struct pci_dev *dev)
entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
entry->msi_attrib.pos = pos;
- if (entry->msi_attrib.maskbit) {
- entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
- entry->msi_attrib.is_64);
- }
entry->dev = dev;
if (entry->msi_attrib.maskbit) {
- unsigned int maskbits, temp;
+ unsigned int base, maskbits, temp;
+
+ base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
+ entry->mask_base = (void __iomem *)(long)base;
+
/* All MSIs are unmasked by default, Mask them all */
- pci_read_config_dword(dev,
- msi_mask_bits_reg(pos, entry->msi_attrib.is_64),
- &maskbits);
- temp = (1 << multi_msi_capable(control));
- temp = ((temp - 1) & ~temp);
+ pci_read_config_dword(dev, base, &maskbits);
+ temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
maskbits |= temp;
- pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits);
+ pci_write_config_dword(dev, base, maskbits);
entry->msi_attrib.maskbits_mask = temp;
}
list_add_tail(&entry->list, &dev->msi_list);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index c697f268085..93eac142358 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -355,17 +355,34 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
int i = 0;
if (drv && drv->suspend) {
+ pci_power_t prev = pci_dev->current_state;
+
+ pci_dev->state_saved = false;
+
i = drv->suspend(pci_dev, state);
suspend_report_result(drv->suspend, i);
- } else {
- pci_save_state(pci_dev);
- /*
- * This is for compatibility with existing code with legacy PM
- * support.
- */
- pci_pm_set_unknown_state(pci_dev);
+ if (i)
+ return i;
+
+ if (pci_dev->state_saved)
+ goto Fixup;
+
+ if (pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ WARN_ONCE(pci_dev->current_state != prev,
+ "PCI PM: Device state not saved by %pF\n",
+ drv->suspend);
+ goto Fixup;
+ }
}
+ pci_save_state(pci_dev);
+ /*
+ * This is for compatibility with existing code with legacy PM support.
+ */
+ pci_pm_set_unknown_state(pci_dev);
+
+ Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev);
return i;
@@ -386,108 +403,47 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
static int pci_legacy_resume_early(struct device *dev)
{
- int error = 0;
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- pci_fixup_device(pci_fixup_resume_early, pci_dev);
-
- if (drv && drv->resume_early)
- error = drv->resume_early(pci_dev);
- return error;
+ return drv && drv->resume_early ?
+ drv->resume_early(pci_dev) : 0;
}
static int pci_legacy_resume(struct device *dev)
{
- int error;
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
pci_fixup_device(pci_fixup_resume, pci_dev);
- if (drv && drv->resume) {
- error = drv->resume(pci_dev);
- } else {
- /* restore the PCI config space */
- pci_restore_state(pci_dev);
- error = pci_pm_reenable_device(pci_dev);
- }
- return error;
+ return drv && drv->resume ?
+ drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev);
}
/* Auxiliary functions used by the new power management framework */
-static int pci_restore_standard_config(struct pci_dev *pci_dev)
-{
- struct pci_dev *parent = pci_dev->bus->self;
- int error = 0;
-
- /* Check if the device's bus is operational */
- if (!parent || parent->current_state == PCI_D0) {
- pci_restore_state(pci_dev);
- pci_update_current_state(pci_dev, PCI_D0);
- } else {
- dev_warn(&pci_dev->dev, "unable to restore config, "
- "bridge %s in low power state D%d\n", pci_name(parent),
- parent->current_state);
- pci_dev->current_state = PCI_UNKNOWN;
- error = -EAGAIN;
- }
-
- return error;
-}
-
-static bool pci_is_bridge(struct pci_dev *pci_dev)
-{
- return !!(pci_dev->subordinate);
-}
-
static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
{
- if (pci_restore_standard_config(pci_dev))
- pci_fixup_device(pci_fixup_resume_early, pci_dev);
+ pci_restore_standard_config(pci_dev);
+ pci_dev->state_saved = false;
+ pci_fixup_device(pci_fixup_resume_early, pci_dev);
}
-static int pci_pm_default_resume(struct pci_dev *pci_dev)
+static void pci_pm_default_resume(struct pci_dev *pci_dev)
{
- /*
- * pci_restore_standard_config() should have been called once already,
- * but it would have failed if the device's parent bridge had not been
- * in power state D0 at that time. Check it and try again if necessary.
- */
- if (pci_dev->current_state == PCI_UNKNOWN) {
- int error = pci_restore_standard_config(pci_dev);
- if (error)
- return error;
- }
-
pci_fixup_device(pci_fixup_resume, pci_dev);
if (!pci_is_bridge(pci_dev))
pci_enable_wake(pci_dev, PCI_D0, false);
-
- return pci_pm_reenable_device(pci_dev);
-}
-
-static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev)
-{
- /* If device is enabled at this point, disable it */
- pci_disable_enabled_device(pci_dev);
- /*
- * Save state with interrupts enabled, because in principle the bus the
- * device is on may be put into a low power state after this code runs.
- */
- pci_save_state(pci_dev);
}
static void pci_pm_default_suspend(struct pci_dev *pci_dev)
{
- pci_pm_default_suspend_generic(pci_dev);
-
+ /* Disable non-bridge devices without PM support */
if (!pci_is_bridge(pci_dev))
- pci_prepare_to_sleep(pci_dev);
-
- pci_fixup_device(pci_fixup_suspend, pci_dev);
+ pci_disable_enabled_device(pci_dev);
+ pci_save_state(pci_dev);
}
static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -532,21 +488,49 @@ static void pci_pm_complete(struct device *dev)
static int pci_pm_suspend(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_SUSPEND);
- if (drv && drv->pm && drv->pm->suspend) {
- error = drv->pm->suspend(dev);
- suspend_report_result(drv->pm->suspend, error);
+ if (!pm) {
+ pci_pm_default_suspend(pci_dev);
+ goto Fixup;
}
- if (!error)
- pci_pm_default_suspend(pci_dev);
+ pci_dev->state_saved = false;
- return error;
+ if (pm->suspend) {
+ pci_power_t prev = pci_dev->current_state;
+ int error;
+
+ error = pm->suspend(dev);
+ suspend_report_result(pm->suspend, error);
+ if (error)
+ return error;
+
+ if (pci_dev->state_saved)
+ goto Fixup;
+
+ if (pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ WARN_ONCE(pci_dev->current_state != prev,
+ "PCI PM: State of device not saved by %pF\n",
+ pm->suspend);
+ goto Fixup;
+ }
+ }
+
+ if (!pci_dev->state_saved) {
+ pci_save_state(pci_dev);
+ if (!pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+ }
+
+ Fixup:
+ pci_fixup_device(pci_fixup_suspend, pci_dev);
+
+ return 0;
}
static int pci_pm_suspend_noirq(struct device *dev)
@@ -575,11 +559,11 @@ static int pci_pm_resume_noirq(struct device *dev)
struct device_driver *drv = dev->driver;
int error = 0;
+ pci_pm_default_resume_noirq(pci_dev);
+
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev);
- pci_pm_default_resume_noirq(pci_dev);
-
if (drv && drv->pm && drv->pm->resume_noirq)
error = drv->pm->resume_noirq(dev);
@@ -589,18 +573,29 @@ static int pci_pm_resume_noirq(struct device *dev)
static int pci_pm_resume(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0;
+ /*
+ * This is necessary for the suspend error path in which resume is
+ * called without restoring the standard config registers of the device.
+ */
+ if (pci_dev->state_saved)
+ pci_restore_standard_config(pci_dev);
+
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- error = pci_pm_default_resume(pci_dev);
+ pci_pm_default_resume(pci_dev);
- if (!error && drv && drv->pm && drv->pm->resume)
- error = drv->pm->resume(dev);
+ if (pm) {
+ if (pm->resume)
+ error = pm->resume(dev);
+ } else {
+ pci_pm_reenable_device(pci_dev);
+ }
- return error;
+ return 0;
}
#else /* !CONFIG_SUSPEND */
@@ -617,21 +612,31 @@ static int pci_pm_resume(struct device *dev)
static int pci_pm_freeze(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_FREEZE);
- if (drv && drv->pm && drv->pm->freeze) {
- error = drv->pm->freeze(dev);
- suspend_report_result(drv->pm->freeze, error);
+ if (!pm) {
+ pci_pm_default_suspend(pci_dev);
+ return 0;
}
- if (!error)
- pci_pm_default_suspend_generic(pci_dev);
+ pci_dev->state_saved = false;
- return error;
+ if (pm->freeze) {
+ int error;
+
+ error = pm->freeze(dev);
+ suspend_report_result(pm->freeze, error);
+ if (error)
+ return error;
+ }
+
+ if (!pci_dev->state_saved)
+ pci_save_state(pci_dev);
+
+ return 0;
}
static int pci_pm_freeze_noirq(struct device *dev)
@@ -674,16 +679,18 @@ static int pci_pm_thaw_noirq(struct device *dev)
static int pci_pm_thaw(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- pci_pm_reenable_device(pci_dev);
-
- if (drv && drv->pm && drv->pm->thaw)
- error = drv->pm->thaw(dev);
+ if (pm) {
+ if (pm->thaw)
+ error = pm->thaw(dev);
+ } else {
+ pci_pm_reenable_device(pci_dev);
+ }
return error;
}
@@ -691,19 +698,29 @@ static int pci_pm_thaw(struct device *dev)
static int pci_pm_poweroff(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_HIBERNATE);
- if (drv && drv->pm && drv->pm->poweroff) {
- error = drv->pm->poweroff(dev);
- suspend_report_result(drv->pm->poweroff, error);
+ if (!pm) {
+ pci_pm_default_suspend(pci_dev);
+ goto Fixup;
}
- if (!error)
- pci_pm_default_suspend(pci_dev);
+ pci_dev->state_saved = false;
+
+ if (pm->poweroff) {
+ error = pm->poweroff(dev);
+ suspend_report_result(pm->poweroff, error);
+ }
+
+ if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+
+ Fixup:
+ pci_fixup_device(pci_fixup_suspend, pci_dev);
return error;
}
@@ -730,11 +747,11 @@ static int pci_pm_restore_noirq(struct device *dev)
struct device_driver *drv = dev->driver;
int error = 0;
+ pci_pm_default_resume_noirq(pci_dev);
+
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev);
- pci_pm_default_resume_noirq(pci_dev);
-
if (drv && drv->pm && drv->pm->restore_noirq)
error = drv->pm->restore_noirq(dev);
@@ -744,16 +761,27 @@ static int pci_pm_restore_noirq(struct device *dev)
static int pci_pm_restore(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0;
+ /*
+ * This is necessary for the hibernation error path in which restore is
+ * called without restoring the standard config registers of the device.
+ */
+ if (pci_dev->state_saved)
+ pci_restore_standard_config(pci_dev);
+
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- error = pci_pm_default_resume(pci_dev);
+ pci_pm_default_resume(pci_dev);
- if (!error && drv && drv->pm && drv->pm->restore)
- error = drv->pm->restore(dev);
+ if (pm) {
+ if (pm->restore)
+ error = pm->restore(dev);
+ } else {
+ pci_pm_reenable_device(pci_dev);
+ }
return error;
}
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index db7ec14fa71..dfc4e0ddf24 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -768,8 +768,8 @@ pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
return -EINVAL;
rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */
- if (!rom)
- return 0;
+ if (!rom || !size)
+ return -EIO;
if (off >= size)
count = 0;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c12f6c79069..6d6120007af 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -22,7 +22,7 @@
#include <asm/dma.h> /* isa_dma_bridge_buggy */
#include "pci.h"
-unsigned int pci_pm_d3_delay = 10;
+unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT;
#ifdef CONFIG_PCI_DOMAINS
int pci_domains_supported = 1;
@@ -426,6 +426,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
* given PCI device
* @dev: PCI device to handle.
* @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
+ * @wait: If 'true', wait for the device to change its power state
*
* RETURN VALUE:
* -EINVAL if the requested state is invalid.
@@ -435,7 +436,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
* 0 if device's power state has been successfully changed.
*/
static int
-pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
+pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
{
u16 pmcsr;
bool need_restore = false;
@@ -480,8 +481,10 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
break;
case PCI_UNKNOWN: /* Boot-up */
if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
- && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+ && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) {
need_restore = true;
+ wait = true;
+ }
/* Fall-through: force to D0 */
default:
pmcsr = 0;
@@ -491,12 +494,15 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
/* enter specified state */
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
+ if (!wait)
+ return 0;
+
/* Mandatory power management transition delays */
/* see PCI PM 1.1 5.6.1 table 18 */
if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
msleep(pci_pm_d3_delay);
else if (state == PCI_D2 || dev->current_state == PCI_D2)
- udelay(200);
+ udelay(PCI_PM_D2_DELAY);
dev->current_state = state;
@@ -515,7 +521,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
if (need_restore)
pci_restore_bars(dev);
- if (dev->bus->self)
+ if (wait && dev->bus->self)
pcie_aspm_pm_state_change(dev->bus->self);
return 0;
@@ -585,7 +591,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
return 0;
- error = pci_raw_set_power_state(dev, state);
+ error = pci_raw_set_power_state(dev, state, true);
if (state > PCI_D0 && platform_pci_power_manageable(dev)) {
/* Allow the platform to finalize the transition */
@@ -730,6 +736,7 @@ pci_save_state(struct pci_dev *dev)
/* XXX: 100% dword access ok here? */
for (i = 0; i < 16; i++)
pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
+ dev->state_saved = true;
if ((i = pci_save_pcie_state(dev)) != 0)
return i;
if ((i = pci_save_pcix_state(dev)) != 0)
@@ -1260,15 +1267,14 @@ void pci_pm_init(struct pci_dev *dev)
/* find PCI PM capability in list */
pm = pci_find_capability(dev, PCI_CAP_ID_PM);
if (!pm)
- goto Exit;
-
+ return;
/* Check device's ability to generate PME# */
pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc);
if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n",
pmc & PCI_PM_CAP_VER_MASK);
- goto Exit;
+ return;
}
dev->pm_cap = pm;
@@ -1307,9 +1313,6 @@ void pci_pm_init(struct pci_dev *dev)
} else {
dev->pme_support = 0;
}
-
- Exit:
- pci_update_current_state(dev, PCI_D0);
}
/**
@@ -1378,6 +1381,50 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
}
/**
+ * pci_restore_standard_config - restore standard config registers of PCI device
+ * @dev: PCI device to handle
+ *
+ * This function assumes that the device's configuration space is accessible.
+ * If the device needs to be powered up, the function will wait for it to
+ * change the state.
+ */
+int pci_restore_standard_config(struct pci_dev *dev)
+{
+ pci_power_t prev_state;
+ int error;
+
+ pci_update_current_state(dev, PCI_D0);
+
+ prev_state = dev->current_state;
+ if (prev_state == PCI_D0)
+ goto Restore;
+
+ error = pci_raw_set_power_state(dev, PCI_D0, false);
+ if (error)
+ return error;
+
+ /*
+ * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
+ * we've made this assumption forever and it appears to be universally
+ * satisfied.
+ */
+ switch(prev_state) {
+ case PCI_D3cold:
+ case PCI_D3hot:
+ mdelay(pci_pm_d3_delay);
+ break;
+ case PCI_D2:
+ udelay(PCI_PM_D2_DELAY);
+ break;
+ }
+
+ pci_update_current_state(dev, PCI_D0);
+
+ Restore:
+ return dev->state_saved ? pci_restore_state(dev) : 0;
+}
+
+/**
* pci_enable_ari - enable ARI forwarding if hardware support it
* @dev: the PCI device
*/
@@ -1493,16 +1540,21 @@ void pci_release_region(struct pci_dev *pdev, int bar)
}
/**
- * pci_request_region - Reserved PCI I/O and memory resource
+ * __pci_request_region - Reserved PCI I/O and memory resource
* @pdev: PCI device whose resources are to be reserved
* @bar: BAR to be reserved
* @res_name: Name to be associated with resource.
+ * @exclusive: whether the region access is exclusive or not
*
* Mark the PCI region associated with PCI device @pdev BR @bar as
* being reserved by owner @res_name. Do not access any
* address inside the PCI regions unless this call returns
* successfully.
*
+ * If @exclusive is set, then the region is marked so that userspace
+ * is explicitly not allowed to map the resource via /dev/mem or
+ * sysfs MMIO access.
+ *
* Returns 0 on success, or %EBUSY on error. A warning
* message is also printed on failure.
*/
@@ -1541,12 +1593,12 @@ err_out:
}
/**
- * pci_request_region - Reserved PCI I/O and memory resource
+ * pci_request_region - Reserve PCI I/O and memory resource
* @pdev: PCI device whose resources are to be reserved
* @bar: BAR to be reserved
- * @res_name: Name to be associated with resource.
+ * @res_name: Name to be associated with resource
*
- * Mark the PCI region associated with PCI device @pdev BR @bar as
+ * Mark the PCI region associated with PCI device @pdev BAR @bar as
* being reserved by owner @res_name. Do not access any
* address inside the PCI regions unless this call returns
* successfully.
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 1351bb4addd..07c0aa5275e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -16,21 +16,21 @@ extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
#endif
/**
- * Firmware PM callbacks
+ * struct pci_platform_pm_ops - Firmware PM callbacks
*
- * @is_manageable - returns 'true' if given device is power manageable by the
- * platform firmware
+ * @is_manageable: returns 'true' if given device is power manageable by the
+ * platform firmware
*
- * @set_state - invokes the platform firmware to set the device's power state
+ * @set_state: invokes the platform firmware to set the device's power state
*
- * @choose_state - returns PCI power state of given device preferred by the
- * platform; to be used during system-wide transitions from a
- * sleeping state to the working state and vice versa
+ * @choose_state: returns PCI power state of given device preferred by the
+ * platform; to be used during system-wide transitions from a
+ * sleeping state to the working state and vice versa
*
- * @can_wakeup - returns 'true' if given device is capable of waking up the
- * system from a sleeping state
+ * @can_wakeup: returns 'true' if given device is capable of waking up the
+ * system from a sleeping state
*
- * @sleep_wake - enables/disables the system wake up capability of given device
+ * @sleep_wake: enables/disables the system wake up capability of given device
*
* If given platform is generally capable of power managing PCI devices, all of
* these callbacks are mandatory.
@@ -49,6 +49,12 @@ extern void pci_disable_enabled_device(struct pci_dev *dev);
extern void pci_pm_init(struct pci_dev *dev);
extern void platform_pci_wakeup_init(struct pci_dev *dev);
extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
+extern int pci_restore_standard_config(struct pci_dev *dev);
+
+static inline bool pci_is_bridge(struct pci_dev *pci_dev)
+{
+ return !!(pci_dev->subordinate);
+}
extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index aac7006949f..38257500738 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -108,6 +108,37 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
}
#endif /* 0 */
+
+static void set_device_error_reporting(struct pci_dev *dev, void *data)
+{
+ bool enable = *((bool *)data);
+
+ if (dev->pcie_type != PCIE_RC_PORT &&
+ dev->pcie_type != PCIE_SW_UPSTREAM_PORT &&
+ dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT)
+ return;
+
+ if (enable)
+ pci_enable_pcie_error_reporting(dev);
+ else
+ pci_disable_pcie_error_reporting(dev);
+}
+
+/**
+ * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports.
+ * @dev: pointer to root port's pci_dev data structure
+ * @enable: true = enable error reporting, false = disable error reporting.
+ */
+static void set_downstream_devices_error_reporting(struct pci_dev *dev,
+ bool enable)
+{
+ set_device_error_reporting(dev, &enable);
+
+ if (!dev->subordinate)
+ return;
+ pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
+}
+
static int find_device_iter(struct device *device, void *data)
{
struct pci_dev *dev;
@@ -525,15 +556,11 @@ void aer_enable_rootport(struct aer_rpc *rpc)
pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);
- /* Enable Root Port device reporting error itself */
- pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, &reg16);
- reg16 = reg16 |
- PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE;
- pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL,
- reg16);
+ /*
+ * Enable error reporting for the root port device and downstream port
+ * devices.
+ */
+ set_downstream_devices_error_reporting(pdev, true);
/* Enable Root Port's interrupt in response to error messages */
pci_write_config_dword(pdev,
@@ -553,6 +580,12 @@ static void disable_root_aer(struct aer_rpc *rpc)
u32 reg32;
int pos;
+ /*
+ * Disable error reporting for the root port device and downstream port
+ * devices.
+ */
+ set_downstream_devices_error_reporting(pdev, false);
+
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Disable Root's interrupt in response to error messages */
pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 586b6f75910..b0367f168af 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -718,9 +718,9 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
/*
* All PCIe functions are in one slot, remove one function will remove
- * the the whole slot, so just wait
+ * the whole slot, so just wait until we are the last function left.
*/
- if (!list_empty(&parent->subordinate->devices))
+ if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices))
goto out;
/* All functions are removed, so just disable ASPM for the link */
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 99a914a027f..5ea566e20b3 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -55,25 +55,13 @@ static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state)
}
-static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state)
-{
- return pci_save_state(dev);
-}
-
-static int pcie_portdrv_resume_early(struct pci_dev *dev)
-{
- return pci_restore_state(dev);
-}
-
static int pcie_portdrv_resume(struct pci_dev *dev)
{
- pcie_portdrv_restore_config(dev);
+ pci_set_master(dev);
return pcie_port_device_resume(dev);
}
#else
#define pcie_portdrv_suspend NULL
-#define pcie_portdrv_suspend_late NULL
-#define pcie_portdrv_resume_early NULL
#define pcie_portdrv_resume NULL
#endif
@@ -109,14 +97,13 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
pcie_portdrv_save_config(dev);
- pci_enable_pcie_error_reporting(dev);
-
return 0;
}
static void pcie_portdrv_remove (struct pci_dev *dev)
{
pcie_port_device_remove(dev);
+ pci_disable_device(dev);
kfree(pci_get_drvdata(dev));
}
@@ -292,8 +279,6 @@ static struct pci_driver pcie_portdriver = {
.remove = pcie_portdrv_remove,
.suspend = pcie_portdrv_suspend,
- .suspend_late = pcie_portdrv_suspend_late,
- .resume_early = pcie_portdrv_resume_early,
.resume = pcie_portdrv_resume,
.err_handler = &pcie_portdrv_err_handler,
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index baad093aafe..92b9efe9bca 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -23,6 +23,7 @@
#include <linux/acpi.h>
#include <linux/kallsyms.h>
#include <linux/dmi.h>
+#include <linux/pci-aspm.h>
#include "pci.h"
int isa_dma_bridge_buggy;
@@ -1584,6 +1585,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_
*/
#define AMD_813X_MISC 0x40
#define AMD_813X_NOIOAMODE (1<<0)
+#define AMD_813X_REV_B2 0x13
static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
{
@@ -1591,6 +1593,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
if (noioapicquirk)
return;
+ if (dev->revision == AMD_813X_REV_B2)
+ return;
pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword);
pci_config_dword &= ~AMD_813X_NOIOAMODE;
@@ -1746,6 +1750,30 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt);
+/*
+ * The 82575 and 82598 may experience data corruption issues when transitioning
+ * out of L0S. To prevent this we need to disable L0S on the pci-e link
+ */
+static void __devinit quirk_disable_aspm_l0s(struct pci_dev *dev)
+{
+ dev_info(&dev->dev, "Disabling L0s\n");
+ pci_disable_link_state(dev, PCIE_LINK_STATE_L0S);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
+
static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
{
/* rev 1 ncr53c810 chips don't set the class at all which means
@@ -1981,7 +2009,6 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE,
quirk_msi_ht_cap);
-
/* The nVidia CK804 chipset may have 2 HT MSI mappings.
* MSI are supported if the MSI capability set in any of these mappings.
*/
@@ -2032,6 +2059,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
ht_enable_msi_mapping);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE,
+ ht_enable_msi_mapping);
+
/* The P5N32-SLI Premium motherboard from Asus has a problem with msi
* for the MCP55 NIC. It is not yet determined whether the msi problem
* also affects other devices. As for now, turn off msi for this device.
@@ -2048,11 +2078,105 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NVENET_15,
nvenet_msi_disable);
-static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
+static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
{
struct pci_dev *host_bridge;
+ int pos;
+ int i, dev_no;
+ int found = 0;
+
+ dev_no = dev->devfn >> 3;
+ for (i = dev_no; i >= 0; i--) {
+ host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0));
+ if (!host_bridge)
+ continue;
+
+ pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
+ if (pos != 0) {
+ found = 1;
+ break;
+ }
+ pci_dev_put(host_bridge);
+ }
+
+ if (!found)
+ return;
+
+ /* root did that ! */
+ if (msi_ht_cap_enabled(host_bridge))
+ goto out;
+
+ ht_enable_msi_mapping(dev);
+
+out:
+ pci_dev_put(host_bridge);
+}
+
+static void __devinit ht_disable_msi_mapping(struct pci_dev *dev)
+{
int pos, ttl = 48;
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+ while (pos && ttl--) {
+ u8 flags;
+
+ if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+ &flags) == 0) {
+ dev_info(&dev->dev, "Disabling HT MSI Mapping\n");
+
+ pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
+ flags & ~HT_MSI_FLAGS_ENABLE);
+ }
+ pos = pci_find_next_ht_capability(dev, pos,
+ HT_CAPTYPE_MSI_MAPPING);
+ }
+}
+
+static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
+{
+ int pos, ttl = 48;
+ int found = 0;
+
+ /* check if there is HT MSI cap or enabled on this device */
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+ while (pos && ttl--) {
+ u8 flags;
+
+ if (found < 1)
+ found = 1;
+ if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+ &flags) == 0) {
+ if (flags & HT_MSI_FLAGS_ENABLE) {
+ if (found < 2) {
+ found = 2;
+ break;
+ }
+ }
+ }
+ pos = pci_find_next_ht_capability(dev, pos,
+ HT_CAPTYPE_MSI_MAPPING);
+ }
+
+ return found;
+}
+
+static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
+{
+ struct pci_dev *host_bridge;
+ int pos;
+ int found;
+
+ /* Enabling HT MSI mapping on this device breaks MCP51 */
+ if (dev->device == 0x270)
+ return;
+
+ /* check if there is HT MSI cap or enabled on this device */
+ found = ht_check_msi_mapping(dev);
+
+ /* no HT MSI CAP */
+ if (found == 0)
+ return;
+
/*
* HT MSI mapping should be disabled on devices that are below
* a non-Hypertransport host bridge. Locate the host bridge...
@@ -2067,24 +2191,19 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
if (pos != 0) {
/* Host bridge is to HT */
- ht_enable_msi_mapping(dev);
+ if (found == 1) {
+ /* it is not enabled, try to enable it */
+ nv_ht_enable_msi_mapping(dev);
+ }
return;
}
- /* Host bridge is not to HT, disable HT MSI mapping on this device */
- pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
- while (pos && ttl--) {
- u8 flags;
+ /* HT MSI is not enabled */
+ if (found == 1)
+ return;
- if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
- &flags) == 0) {
- dev_info(&dev->dev, "Disabling HT MSI mapping");
- pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
- flags & ~HT_MSI_FLAGS_ENABLE);
- }
- pos = pci_find_next_ht_capability(dev, pos,
- HT_CAPTYPE_MSI_MAPPING);
- }
+ /* Host bridge is not to HT, disable HT MSI mapping on this device */
+ ht_disable_msi_mapping(dev);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 132a78159b6..36864a935d6 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -55,6 +55,7 @@ void pci_disable_rom(struct pci_dev *pdev)
/**
* pci_get_rom_size - obtain the actual size of the ROM image
+ * @pdev: target PCI device
* @rom: kernel virtual pointer to image of ROM
* @size: size of PCI window
* return: size of actual ROM image
@@ -63,7 +64,7 @@ void pci_disable_rom(struct pci_dev *pdev)
* The PCI window size could be much larger than the
* actual image size.
*/
-size_t pci_get_rom_size(void __iomem *rom, size_t size)
+size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
{
void __iomem *image;
int last_image;
@@ -72,8 +73,10 @@ size_t pci_get_rom_size(void __iomem *rom, size_t size)
do {
void __iomem *pds;
/* Standard PCI ROMs start out with these bytes 55 AA */
- if (readb(image) != 0x55)
+ if (readb(image) != 0x55) {
+ dev_err(&pdev->dev, "Invalid ROM contents\n");
break;
+ }
if (readb(image + 1) != 0xAA)
break;
/* get the PCI data structure and check its signature */
@@ -159,7 +162,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
* size is much larger than the actual size of the ROM.
* True size is important if the ROM is going to be copied.
*/
- *size = pci_get_rom_size(rom, *size);
+ *size = pci_get_rom_size(pdev, rom, *size);
return rom;
}
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index fc1de46fd20..90013341cd5 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -468,13 +468,13 @@ out:
return ret;
}
-int au1x00_drv_pcmcia_remove(struct device *dev)
+int au1x00_drv_pcmcia_remove(struct platform_device *dev)
{
- struct skt_dev_info *sinfo = dev_get_drvdata(dev);
+ struct skt_dev_info *sinfo = platform_get_drvdata(dev);
int i;
mutex_lock(&pcmcia_sockets_lock);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
for (i = 0; i < sinfo->nskt; i++) {
struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
@@ -498,13 +498,13 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
* PCMCIA "Driver" API
*/
-static int au1x00_drv_pcmcia_probe(struct device *dev)
+static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;
mutex_lock(&pcmcia_sockets_lock);
for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
- ret = au1x00_pcmcia_hw_init[i](dev);
+ ret = au1x00_pcmcia_hw_init[i](&dev->dev);
if (ret == 0)
break;
}
@@ -512,14 +512,26 @@ static int au1x00_drv_pcmcia_probe(struct device *dev)
return ret;
}
+static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
-static struct device_driver au1x00_pcmcia_driver = {
+static struct platform_driver au1x00_pcmcia_driver = {
+ .driver = {
+ .name = "au1x00-pcmcia",
+ .owner = THIS_MODULE,
+ },
.probe = au1x00_drv_pcmcia_probe,
.remove = au1x00_drv_pcmcia_remove,
- .name = "au1x00-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .suspend = au1x00_drv_pcmcia_suspend,
+ .resume = au1x00_drv_pcmcia_resume,
};
@@ -533,8 +545,7 @@ static struct device_driver au1x00_pcmcia_driver = {
static int __init au1x00_pcmcia_init(void)
{
int error = 0;
- if ((error = driver_register(&au1x00_pcmcia_driver)))
- return error;
+ error = platform_driver_register(&au1x00_pcmcia_driver);
return error;
}
@@ -544,7 +555,7 @@ static int __init au1x00_pcmcia_init(void)
*/
static void __exit au1x00_pcmcia_exit(void)
{
- driver_unregister(&au1x00_pcmcia_driver);
+ platform_driver_unregister(&au1x00_pcmcia_driver);
}
module_init(au1x00_pcmcia_init);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 71653ab8489..40d4953e4b1 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1238,6 +1238,16 @@ static int pcic_init(struct pcmcia_socket *s)
return 0;
}
+static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int i82365_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
static struct pccard_operations pcic_operations = {
.init = pcic_init,
.get_status = pcic_get_status,
@@ -1248,11 +1258,13 @@ static struct pccard_operations pcic_operations = {
/*====================================================================*/
-static struct device_driver i82365_driver = {
- .name = "i82365",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver i82365_driver = {
+ .driver = {
+ .name = "i82365",
+ .owner = THIS_MODULE,
+ },
+ .suspend = i82365_drv_pcmcia_suspend,
+ .resume = i82365_drv_pcmcia_resume,
};
static struct platform_device *i82365_device;
@@ -1261,7 +1273,7 @@ static int __init init_i82365(void)
{
int i, ret;
- ret = driver_register(&i82365_driver);
+ ret = platform_driver_register(&i82365_driver);
if (ret)
goto err_out;
@@ -1337,7 +1349,7 @@ err_dev_unregister:
pnp_disable_dev(i82365_pnpdev);
#endif
err_driver_unregister:
- driver_unregister(&i82365_driver);
+ platform_driver_unregister(&i82365_driver);
err_out:
return ret;
} /* init_i82365 */
@@ -1365,7 +1377,7 @@ static void __exit exit_i82365(void)
if (i82365_pnpdev)
pnp_disable_dev(i82365_pnpdev);
#endif
- driver_unregister(&i82365_driver);
+ platform_driver_unregister(&i82365_driver);
} /* exit_i82365 */
module_init(init_i82365);
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 2ab4f22c21d..62b4ecc97c4 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -696,13 +696,25 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};
+static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int cfc_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver pcc_driver = {
- .name = "cfc",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+ .driver = {
+ .name = "cfc",
+ .owner = THIS_MODULE,
+ },
+ .suspend = cfc_drv_pcmcia_suspend,
+ .resume = cfc_drv_pcmcia_resume,
};
static struct platform_device pcc_device = {
@@ -716,13 +728,13 @@ static int __init init_m32r_pcc(void)
{
int i, ret;
- ret = driver_register(&pcc_driver);
+ ret = platform_driver_register(&pcc_driver);
if (ret)
return ret;
ret = platform_device_register(&pcc_device);
if (ret){
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return ret;
}
@@ -754,7 +766,7 @@ static int __init init_m32r_pcc(void)
if (pcc_sockets == 0) {
printk("socket is not found.\n");
platform_device_unregister(&pcc_device);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return -ENODEV;
}
@@ -802,7 +814,7 @@ static void __exit exit_m32r_pcc(void)
if (poll_interval != 0)
del_timer_sync(&poll_timer);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
} /* exit_m32r_pcc */
module_init(init_m32r_pcc);
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 2f108c23dbd..12034b41d19 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -672,13 +672,25 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};
+static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int pcc_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver pcc_driver = {
- .name = "pcc",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+ .driver = {
+ .name = "pcc",
+ .owner = THIS_MODULE,
+ },
+ .suspend = pcc_drv_pcmcia_suspend,
+ .resume = pcc_drv_pcmcia_resume,
};
static struct platform_device pcc_device = {
@@ -692,13 +704,13 @@ static int __init init_m32r_pcc(void)
{
int i, ret;
- ret = driver_register(&pcc_driver);
+ ret = platform_driver_register(&pcc_driver);
if (ret)
return ret;
ret = platform_device_register(&pcc_device);
if (ret){
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return ret;
}
@@ -715,7 +727,7 @@ static int __init init_m32r_pcc(void)
if (pcc_sockets == 0) {
printk("socket is not found.\n");
platform_device_unregister(&pcc_device);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return -ENODEV;
}
@@ -763,7 +775,7 @@ static void __exit exit_m32r_pcc(void)
if (poll_interval != 0)
del_timer_sync(&poll_timer);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
} /* exit_m32r_pcc */
module_init(init_m32r_pcc);
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index c0e2afc79e3..e592e0e0d7e 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -153,7 +153,7 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num,
unsigned long align, struct pcmcia_socket *s)
{
struct resource *res = make_resource(0, num, IORESOURCE_IO,
- s->dev.bus_id);
+ dev_name(&s->dev));
struct pcmcia_align_data data;
unsigned long min = base;
int ret;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index c5b2a44b4c3..d8da5ac844e 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -65,7 +65,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#endif
};
-static int sa11x0_drv_pcmcia_probe(struct device *dev)
+static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;
@@ -73,7 +73,7 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
* Initialise any "on-board" PCMCIA sockets.
*/
for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) {
- ret = sa11x0_pcmcia_hw_init[i](dev);
+ ret = sa11x0_pcmcia_hw_init[i](&dev->dev);
if (ret == 0)
break;
}
@@ -81,13 +81,31 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
return ret;
}
-static struct device_driver sa11x0_pcmcia_driver = {
+static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+{
+ return soc_common_drv_pcmcia_remove(&dev->dev);
+}
+
+static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver sa11x0_pcmcia_driver = {
+ .driver = {
+ .name = "sa11x0-pcmcia",
+ .owner = THIS_MODULE,
+ },
.probe = sa11x0_drv_pcmcia_probe,
- .remove = soc_common_drv_pcmcia_remove,
- .name = "sa11x0-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .remove = sa11x0_drv_pcmcia_remove,
+ .suspend = sa11x0_drv_pcmcia_suspend,
+ .resume = sa11x0_drv_pcmcia_resume,
};
/* sa11x0_pcmcia_init()
@@ -100,7 +118,7 @@ static struct device_driver sa11x0_pcmcia_driver = {
*/
static int __init sa11x0_pcmcia_init(void)
{
- return driver_register(&sa11x0_pcmcia_driver);
+ return platform_driver_register(&sa11x0_pcmcia_driver);
}
/* sa11x0_pcmcia_exit()
@@ -110,7 +128,7 @@ static int __init sa11x0_pcmcia_init(void)
*/
static void __exit sa11x0_pcmcia_exit(void)
{
- driver_unregister(&sa11x0_pcmcia_driver);
+ platform_driver_unregister(&sa11x0_pcmcia_driver);
}
MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 2a613e920fd..9ad97ea836e 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -363,13 +363,25 @@ static int __init get_tcic_id(void)
return id;
}
+static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int tcic_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver tcic_driver = {
- .name = "tcic-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver tcic_driver = {
+ .driver = {
+ .name = "tcic-pcmcia",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tcic_drv_pcmcia_suspend,
+ .resume = tcic_drv_pcmcia_resume,
};
static struct platform_device tcic_device = {
@@ -383,7 +395,7 @@ static int __init init_tcic(void)
int i, sock, ret = 0;
u_int mask, scan;
- if (driver_register(&tcic_driver))
+ if (platform_driver_register(&tcic_driver))
return -1;
printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
@@ -391,7 +403,7 @@ static int __init init_tcic(void)
if (!request_region(tcic_base, 16, "tcic-2")) {
printk("could not allocate ports,\n ");
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
else {
@@ -414,7 +426,7 @@ static int __init init_tcic(void)
if (sock == 0) {
printk("not found.\n");
release_region(tcic_base, 16);
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
@@ -542,7 +554,7 @@ static void __exit exit_tcic(void)
}
platform_device_unregister(&tcic_device);
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
} /* exit_tcic */
/*====================================================================*/
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index b2c41241905..659421d0ca4 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -704,24 +704,37 @@ static int __devinit vrc4171_card_setup(char *options)
__setup("vrc4171_card=", vrc4171_card_setup);
-static struct device_driver vrc4171_card_driver = {
- .name = vrc4171_card_name,
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static int vrc4171_card_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int vrc4171_card_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver vrc4171_card_driver = {
+ .driver = {
+ .name = vrc4171_card_name,
+ .owner = THIS_MODULE,
+ },
+ .suspend = vrc4171_card_suspend,
+ .resume = vrc4171_card_resume,
};
static int __devinit vrc4171_card_init(void)
{
int retval;
- retval = driver_register(&vrc4171_card_driver);
+ retval = platform_driver_register(&vrc4171_card_driver);
if (retval < 0)
return retval;
retval = platform_device_register(&vrc4171_card_device);
if (retval < 0) {
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
return retval;
}
@@ -735,11 +748,12 @@ static int __devinit vrc4171_card_init(void)
if (retval < 0) {
vrc4171_remove_sockets();
platform_device_unregister(&vrc4171_card_device);
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
return retval;
}
- printk(KERN_INFO "%s, connected to IRQ %d\n", vrc4171_card_driver.name, vrc4171_irq);
+ printk(KERN_INFO "%s, connected to IRQ %d\n",
+ vrc4171_card_driver.driver.name, vrc4171_irq);
return 0;
}
@@ -749,7 +763,7 @@ static void __devexit vrc4171_card_exit(void)
free_irq(vrc4171_irq, vrc4171_sockets);
vrc4171_remove_sockets();
platform_device_unregister(&vrc4171_card_device);
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
}
module_init(vrc4171_card_init);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index e65448e99b4..3608081bc3e 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -15,8 +15,7 @@ menuconfig X86_PLATFORM_DEVICES
if X86_PLATFORM_DEVICES
config ACER_WMI
- tristate "Acer WMI Laptop Extras (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ tristate "Acer WMI Laptop Extras"
depends on ACPI
depends on LEDS_CLASS
depends on NEW_LEDS
@@ -39,9 +38,10 @@ config ASUS_LAPTOP
tristate "Asus Laptop Extras (EXPERIMENTAL)"
depends on ACPI
depends on EXPERIMENTAL && !ACPI_ASUS
- depends on LEDS_CLASS
- depends on NEW_LEDS
- depends on BACKLIGHT_CLASS_DEVICE
+ select LEDS_CLASS
+ select NEW_LEDS
+ select BACKLIGHT_CLASS_DEVICE
+ depends on INPUT
---help---
This is the new Linux driver for Asus laptops. It may also support some
MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate
@@ -54,6 +54,19 @@ config ASUS_LAPTOP
If you have an ACPI-compatible ASUS laptop, say Y or M here.
+config DELL_LAPTOP
+ tristate "Dell Laptop Extras (EXPERIMENTAL)"
+ depends on X86
+ depends on DCDBAS
+ depends on EXPERIMENTAL
+ depends on BACKLIGHT_CLASS_DEVICE
+ depends on RFKILL
+ depends on POWER_SUPPLY
+ default n
+ ---help---
+ This driver adds support for rfkill and backlight control to Dell
+ laptops.
+
config FUJITSU_LAPTOP
tristate "Fujitsu Laptop Extras"
depends on ACPI
@@ -171,11 +184,11 @@ config SONYPI_COMPAT
config THINKPAD_ACPI
tristate "ThinkPad ACPI Laptop Extras"
depends on ACPI
+ depends on INPUT
select BACKLIGHT_LCD_SUPPORT
select BACKLIGHT_CLASS_DEVICE
select HWMON
select NVRAM
- select INPUT
select NEW_LEDS
select LEDS_CLASS
select NET
@@ -192,6 +205,17 @@ config THINKPAD_ACPI
If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
+config THINKPAD_ACPI_DEBUGFACILITIES
+ bool "Maintainer debug facilities"
+ depends on THINKPAD_ACPI
+ default n
+ ---help---
+ Enables extra stuff in the thinkpad-acpi which is completely useless
+ for normal use. Read the driver source to find out what it does.
+
+ Say N here, unless you were told by a kernel maintainer to do
+ otherwise.
+
config THINKPAD_ACPI_DEBUG
bool "Verbose debug mode"
depends on THINKPAD_ACPI
@@ -277,6 +301,7 @@ config INTEL_MENLOW
config EEEPC_LAPTOP
tristate "Eee PC Hotkey Driver (EXPERIMENTAL)"
depends on ACPI
+ depends on INPUT
depends on EXPERIMENTAL
select BACKLIGHT_CLASS_DEVICE
select HWMON
@@ -289,9 +314,8 @@ config EEEPC_LAPTOP
config ACPI_WMI
- tristate "WMI (EXPERIMENTAL)"
+ tristate "WMI"
depends on ACPI
- depends on EXPERIMENTAL
help
This driver adds support for the ACPI-WMI (Windows Management
Instrumentation) mapper device (PNP0C14) found on some systems.
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 1e9de2ae0de..e29065120be 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
+obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_HP_WMI) += hp-wmi.o
obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 94c9f911824..a6a42e8c060 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -1026,7 +1026,7 @@ static void acer_rfkill_exit(void)
kfree(wireless_rfkill->data);
rfkill_unregister(wireless_rfkill);
if (has_cap(ACER_CAP_BLUETOOTH)) {
- kfree(wireless_rfkill->data);
+ kfree(bluetooth_rfkill->data);
rfkill_unregister(bluetooth_rfkill);
}
return;
@@ -1297,7 +1297,7 @@ static int __init acer_wmi_init(void)
set_quirks();
- if (!acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) {
+ if (acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) {
interface->capability &= ~ACER_CAP_BRIGHTNESS;
printk(ACER_INFO "Brightness must be controlled by "
"generic video driver\n");
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 8fb8b359104..eeafc6c0160 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -46,6 +46,7 @@
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>
+#include <linux/input.h>
#define ASUS_LAPTOP_VERSION "0.42"
@@ -181,6 +182,8 @@ struct asus_hotk {
u8 light_level; //light sensor level
u8 light_switch; //light sensor switch value
u16 event_count[128]; //count for each event TODO make this better
+ struct input_dev *inputdev;
+ u16 *keycode_map;
};
/*
@@ -250,6 +253,37 @@ ASUS_LED(rled, "record");
ASUS_LED(pled, "phone");
ASUS_LED(gled, "gaming");
+struct key_entry {
+ char type;
+ u8 code;
+ u16 keycode;
+};
+
+enum { KE_KEY, KE_END };
+
+static struct key_entry asus_keymap[] = {
+ {KE_KEY, 0x30, KEY_VOLUMEUP},
+ {KE_KEY, 0x31, KEY_VOLUMEDOWN},
+ {KE_KEY, 0x32, KEY_MUTE},
+ {KE_KEY, 0x33, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x40, KEY_PREVIOUSSONG},
+ {KE_KEY, 0x41, KEY_NEXTSONG},
+ {KE_KEY, 0x43, KEY_STOP},
+ {KE_KEY, 0x45, KEY_PLAYPAUSE},
+ {KE_KEY, 0x50, KEY_EMAIL},
+ {KE_KEY, 0x51, KEY_WWW},
+ {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */
+ {KE_KEY, 0x5D, KEY_WLAN},
+ {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */
+ {KE_KEY, 0x82, KEY_CAMERA},
+ {KE_KEY, 0x8A, KEY_TV},
+ {KE_KEY, 0x95, KEY_MEDIA},
+ {KE_KEY, 0x99, KEY_PHONE},
+ {KE_END, 0},
+};
+
/*
* This function evaluates an ACPI method, given an int as parameter, the
* method is searched within the scope of the handle, can be NULL. The output
@@ -720,8 +754,69 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr,
return store_status(buf, count, NULL, GPS_ON);
}
+/*
+ * Hotkey functions
+ */
+static struct key_entry *asus_get_entry_by_scancode(int code)
+{
+ struct key_entry *key;
+
+ for (key = asus_keymap; key->type != KE_END; key++)
+ if (code == key->code)
+ return key;
+
+ return NULL;
+}
+
+static struct key_entry *asus_get_entry_by_keycode(int code)
+{
+ struct key_entry *key;
+
+ for (key = asus_keymap; key->type != KE_END; key++)
+ if (code == key->keycode && key->type == KE_KEY)
+ return key;
+
+ return NULL;
+}
+
+static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+ struct key_entry *key = asus_get_entry_by_scancode(scancode);
+
+ if (key && key->type == KE_KEY) {
+ *keycode = key->keycode;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+ struct key_entry *key;
+ int old_keycode;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ key = asus_get_entry_by_scancode(scancode);
+ if (key && key->type == KE_KEY) {
+ old_keycode = key->keycode;
+ key->keycode = keycode;
+ set_bit(keycode, dev->keybit);
+ if (!asus_get_entry_by_keycode(old_keycode))
+ clear_bit(old_keycode, dev->keybit);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
{
+ static struct key_entry *key;
+ u16 count;
+
/* TODO Find a better way to handle events count. */
if (!hotk)
return;
@@ -738,10 +833,26 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
lcd_blank(FB_BLANK_POWERDOWN);
}
- acpi_bus_generate_proc_event(hotk->device, event,
- hotk->event_count[event % 128]++);
-
- return;
+ count = hotk->event_count[event % 128]++;
+ acpi_bus_generate_proc_event(hotk->device, event, count);
+ acpi_bus_generate_netlink_event(hotk->device->pnp.device_class,
+ dev_name(&hotk->device->dev), event,
+ count);
+
+ if (hotk->inputdev) {
+ key = asus_get_entry_by_scancode(event);
+ if (!key)
+ return ;
+
+ switch (key->type) {
+ case KE_KEY:
+ input_report_key(hotk->inputdev, key->keycode, 1);
+ input_sync(hotk->inputdev);
+ input_report_key(hotk->inputdev, key->keycode, 0);
+ input_sync(hotk->inputdev);
+ break;
+ }
+ }
}
#define ASUS_CREATE_DEVICE_ATTR(_name) \
@@ -959,6 +1070,38 @@ static int asus_hotk_get_info(void)
return AE_OK;
}
+static int asus_input_init(void)
+{
+ const struct key_entry *key;
+ int result;
+
+ hotk->inputdev = input_allocate_device();
+ if (!hotk->inputdev) {
+ printk(ASUS_INFO "Unable to allocate input device\n");
+ return 0;
+ }
+ hotk->inputdev->name = "Asus Laptop extra buttons";
+ hotk->inputdev->phys = ASUS_HOTK_FILE "/input0";
+ hotk->inputdev->id.bustype = BUS_HOST;
+ hotk->inputdev->getkeycode = asus_getkeycode;
+ hotk->inputdev->setkeycode = asus_setkeycode;
+
+ for (key = asus_keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_KEY:
+ set_bit(EV_KEY, hotk->inputdev->evbit);
+ set_bit(key->keycode, hotk->inputdev->keybit);
+ break;
+ }
+ }
+ result = input_register_device(hotk->inputdev);
+ if (result) {
+ printk(ASUS_INFO "Unable to register input device\n");
+ input_free_device(hotk->inputdev);
+ }
+ return result;
+}
+
static int asus_hotk_check(void)
{
int result = 0;
@@ -1044,7 +1187,7 @@ static int asus_hotk_add(struct acpi_device *device)
/* GPS is on by default */
write_status(NULL, 1, GPS_ON);
- end:
+end:
if (result) {
kfree(hotk->name);
kfree(hotk);
@@ -1091,10 +1234,17 @@ static void asus_led_exit(void)
ASUS_LED_UNREGISTER(gled);
}
+static void asus_input_exit(void)
+{
+ if (hotk->inputdev)
+ input_unregister_device(hotk->inputdev);
+}
+
static void __exit asus_laptop_exit(void)
{
asus_backlight_exit();
asus_led_exit();
+ asus_input_exit();
acpi_bus_unregister_driver(&asus_hotk_driver);
sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group);
@@ -1216,6 +1366,10 @@ static int __init asus_laptop_init(void)
printk(ASUS_INFO "Brightness ignored, must be controlled by "
"ACPI video driver\n");
+ result = asus_input_init();
+ if (result)
+ goto fail_input;
+
result = asus_led_init(dev);
if (result)
goto fail_led;
@@ -1242,22 +1396,25 @@ static int __init asus_laptop_init(void)
return 0;
- fail_sysfs:
+fail_sysfs:
platform_device_del(asuspf_device);
- fail_platform_device2:
+fail_platform_device2:
platform_device_put(asuspf_device);
- fail_platform_device1:
+fail_platform_device1:
platform_driver_unregister(&asuspf_driver);
- fail_platform_driver:
+fail_platform_driver:
asus_led_exit();
- fail_led:
+fail_led:
+ asus_input_exit();
+
+fail_input:
asus_backlight_exit();
- fail_backlight:
+fail_backlight:
return result;
}
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
index 1e74988c7b2..d63f26e666a 100644
--- a/drivers/platform/x86/asus_acpi.c
+++ b/drivers/platform/x86/asus_acpi.c
@@ -143,6 +143,7 @@ struct asus_hotk {
S1300N, S5200N*/
A4S, /* Z81sp */
F3Sa, /* (Centrino) */
+ R1F,
END_MODEL
} model; /* Models currently supported */
u16 event_count[128]; /* Count for each event TODO make this better */
@@ -420,7 +421,18 @@ static struct model_data model_conf[END_MODEL] = {
.display_get = "\\ADVG",
.display_set = "SDSP",
},
-
+ {
+ .name = "R1F",
+ .mt_bt_switch = "BLED",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = "\\Q10",
+ .lcd_status = "\\GP06",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"
+ }
};
/* procdir we use */
@@ -1165,6 +1177,8 @@ static int asus_model_match(char *model)
return W3V;
else if (strncmp(model, "W5A", 3) == 0)
return W5A;
+ else if (strncmp(model, "R1F", 3) == 0)
+ return R1F;
else if (strncmp(model, "A4S", 3) == 0)
return A4S;
else if (strncmp(model, "F3Sa", 4) == 0)
diff --git a/drivers/misc/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 4d33a2068b7..16e11c2ee19 100644
--- a/drivers/misc/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -22,7 +22,7 @@
#include <linux/rfkill.h>
#include <linux/power_supply.h>
#include <linux/acpi.h>
-#include "../firmware/dcdbas.h"
+#include "../../firmware/dcdbas.h"
#define BRIGHTNESS_TOKEN 0x7d
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 02fe2b8b893..6f54fd1757c 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -30,6 +30,7 @@
#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/rfkill.h>
+#include <linux/pci.h>
#define EEEPC_LAPTOP_VERSION "0.1"
@@ -90,7 +91,7 @@ enum {
};
static const char *cm_getv[] = {
- "WLDG", NULL, NULL, NULL,
+ "WLDG", "BTHG", NULL, NULL,
"CAMG", NULL, NULL, NULL,
NULL, "PBLG", NULL, NULL,
"CFVG", NULL, NULL, NULL,
@@ -99,7 +100,7 @@ static const char *cm_getv[] = {
};
static const char *cm_setv[] = {
- "WLDS", NULL, NULL, NULL,
+ "WLDS", "BTHS", NULL, NULL,
"CAMS", NULL, NULL, NULL,
"SDSP", "PBLS", "HDPS", NULL,
"CFVS", NULL, NULL, NULL,
@@ -161,6 +162,10 @@ static struct key_entry eeepc_keymap[] = {
{KE_KEY, 0x13, KEY_MUTE },
{KE_KEY, 0x14, KEY_VOLUMEDOWN },
{KE_KEY, 0x15, KEY_VOLUMEUP },
+ {KE_KEY, 0x1a, KEY_COFFEE },
+ {KE_KEY, 0x1b, KEY_ZOOM },
+ {KE_KEY, 0x1c, KEY_PROG2 },
+ {KE_KEY, 0x1d, KEY_PROG3 },
{KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
@@ -510,18 +515,59 @@ static int eeepc_hotk_check(void)
static void notify_brn(void)
{
struct backlight_device *bd = eeepc_backlight_device;
- bd->props.brightness = read_brightness(bd);
+ if (bd)
+ bd->props.brightness = read_brightness(bd);
+}
+
+static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct pci_dev *dev;
+ struct pci_bus *bus = pci_find_bus(0, 1);
+
+ if (event != ACPI_NOTIFY_BUS_CHECK)
+ return;
+
+ if (!bus) {
+ printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
+ return;
+ }
+
+ if (get_acpi(CM_ASL_WLAN) == 1) {
+ dev = pci_get_slot(bus, 0);
+ if (dev) {
+ /* Device already present */
+ pci_dev_put(dev);
+ return;
+ }
+ dev = pci_scan_single_device(bus, 0);
+ if (dev) {
+ pci_bus_assign_resources(bus);
+ if (pci_bus_add_device(dev))
+ printk(EEEPC_ERR "Unable to hotplug wifi\n");
+ }
+ } else {
+ dev = pci_get_slot(bus, 0);
+ if (dev) {
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+ }
+ }
}
static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
{
static struct key_entry *key;
+ u16 count;
+
if (!ehotk)
return;
if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
notify_brn();
- acpi_bus_generate_proc_event(ehotk->device, event,
- ehotk->event_count[event % 128]++);
+ count = ehotk->event_count[event % 128]++;
+ acpi_bus_generate_proc_event(ehotk->device, event, count);
+ acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
+ dev_name(&ehotk->device->dev), event,
+ count);
if (ehotk->inputdev) {
key = eepc_get_entry_by_scancode(event);
if (key) {
@@ -539,6 +585,45 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
}
}
+static int eeepc_register_rfkill_notifier(char *node)
+{
+ acpi_status status = AE_OK;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, node, &handle);
+
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_install_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ eeepc_rfkill_notify,
+ NULL);
+ if (ACPI_FAILURE(status))
+ printk(EEEPC_WARNING
+ "Failed to register notify on %s\n", node);
+ } else
+ return -ENODEV;
+
+ return 0;
+}
+
+static void eeepc_unregister_rfkill_notifier(char *node)
+{
+ acpi_status status = AE_OK;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, node, &handle);
+
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_remove_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ eeepc_rfkill_notify);
+ if (ACPI_FAILURE(status))
+ printk(EEEPC_ERR
+ "Error removing rfkill notify handler %s\n",
+ node);
+ }
+}
+
static int eeepc_hotk_add(struct acpi_device *device)
{
acpi_status status = AE_OK;
@@ -558,7 +643,7 @@ static int eeepc_hotk_add(struct acpi_device *device)
ehotk->device = device;
result = eeepc_hotk_check();
if (result)
- goto end;
+ goto ehotk_fail;
status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
eeepc_hotk_notify, ehotk);
if (ACPI_FAILURE(status))
@@ -569,18 +654,25 @@ static int eeepc_hotk_add(struct acpi_device *device)
RFKILL_TYPE_WLAN);
if (!ehotk->eeepc_wlan_rfkill)
- goto end;
+ goto wlan_fail;
ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
- if (get_acpi(CM_ASL_WLAN) == 1)
+ if (get_acpi(CM_ASL_WLAN) == 1) {
ehotk->eeepc_wlan_rfkill->state =
RFKILL_STATE_UNBLOCKED;
- else
+ rfkill_set_default(RFKILL_TYPE_WLAN,
+ RFKILL_STATE_UNBLOCKED);
+ } else {
ehotk->eeepc_wlan_rfkill->state =
RFKILL_STATE_SOFT_BLOCKED;
- rfkill_register(ehotk->eeepc_wlan_rfkill);
+ rfkill_set_default(RFKILL_TYPE_WLAN,
+ RFKILL_STATE_SOFT_BLOCKED);
+ }
+ result = rfkill_register(ehotk->eeepc_wlan_rfkill);
+ if (result)
+ goto wlan_fail;
}
if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
@@ -588,27 +680,47 @@ static int eeepc_hotk_add(struct acpi_device *device)
rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
if (!ehotk->eeepc_bluetooth_rfkill)
- goto end;
+ goto bluetooth_fail;
ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
ehotk->eeepc_bluetooth_rfkill->toggle_radio =
eeepc_bluetooth_rfkill_set;
ehotk->eeepc_bluetooth_rfkill->get_state =
eeepc_bluetooth_rfkill_state;
- if (get_acpi(CM_ASL_BLUETOOTH) == 1)
+ if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
ehotk->eeepc_bluetooth_rfkill->state =
RFKILL_STATE_UNBLOCKED;
- else
+ rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
+ RFKILL_STATE_UNBLOCKED);
+ } else {
ehotk->eeepc_bluetooth_rfkill->state =
RFKILL_STATE_SOFT_BLOCKED;
- rfkill_register(ehotk->eeepc_bluetooth_rfkill);
- }
+ rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
+ RFKILL_STATE_SOFT_BLOCKED);
+ }
- end:
- if (result) {
- kfree(ehotk);
- ehotk = NULL;
+ result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
+ if (result)
+ goto bluetooth_fail;
}
+
+ eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
+ eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
+
+ return 0;
+
+ bluetooth_fail:
+ if (ehotk->eeepc_bluetooth_rfkill)
+ rfkill_free(ehotk->eeepc_bluetooth_rfkill);
+ rfkill_unregister(ehotk->eeepc_wlan_rfkill);
+ ehotk->eeepc_wlan_rfkill = NULL;
+ wlan_fail:
+ if (ehotk->eeepc_wlan_rfkill)
+ rfkill_free(ehotk->eeepc_wlan_rfkill);
+ ehotk_fail:
+ kfree(ehotk);
+ ehotk = NULL;
+
return result;
}
@@ -622,6 +734,10 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
eeepc_hotk_notify);
if (ACPI_FAILURE(status))
printk(EEEPC_ERR "Error removing notify handler\n");
+
+ eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
+ eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
+
kfree(ehotk);
return 0;
}
@@ -737,13 +853,21 @@ static void eeepc_backlight_exit(void)
{
if (eeepc_backlight_device)
backlight_device_unregister(eeepc_backlight_device);
- if (ehotk->inputdev)
- input_unregister_device(ehotk->inputdev);
+ eeepc_backlight_device = NULL;
+}
+
+static void eeepc_rfkill_exit(void)
+{
if (ehotk->eeepc_wlan_rfkill)
rfkill_unregister(ehotk->eeepc_wlan_rfkill);
if (ehotk->eeepc_bluetooth_rfkill)
rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
- eeepc_backlight_device = NULL;
+}
+
+static void eeepc_input_exit(void)
+{
+ if (ehotk->inputdev)
+ input_unregister_device(ehotk->inputdev);
}
static void eeepc_hwmon_exit(void)
@@ -762,6 +886,8 @@ static void eeepc_hwmon_exit(void)
static void __exit eeepc_laptop_exit(void)
{
eeepc_backlight_exit();
+ eeepc_rfkill_exit();
+ eeepc_input_exit();
eeepc_hwmon_exit();
acpi_bus_unregister_driver(&eeepc_hotk_driver);
sysfs_remove_group(&platform_device->dev.kobj,
@@ -865,6 +991,8 @@ fail_platform_driver:
fail_hwmon:
eeepc_backlight_exit();
fail_backlight:
+ eeepc_input_exit();
+ eeepc_rfkill_exit();
return result;
}
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 65dc41540c6..45940f31fe9 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -166,6 +166,7 @@ struct fujitsu_hotkey_t {
struct platform_device *pf_device;
struct kfifo *fifo;
spinlock_t fifo_lock;
+ int rfkill_supported;
int rfkill_state;
int logolamp_registered;
int kblamps_registered;
@@ -526,7 +527,7 @@ static ssize_t
show_lid_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
- if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+ if (!(fujitsu_hotkey->rfkill_supported & 0x100))
return sprintf(buf, "unknown\n");
if (fujitsu_hotkey->rfkill_state & 0x100)
return sprintf(buf, "open\n");
@@ -538,7 +539,7 @@ static ssize_t
show_dock_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
- if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+ if (!(fujitsu_hotkey->rfkill_supported & 0x200))
return sprintf(buf, "unknown\n");
if (fujitsu_hotkey->rfkill_state & 0x200)
return sprintf(buf, "docked\n");
@@ -550,7 +551,7 @@ static ssize_t
show_radios_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
- if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+ if (!(fujitsu_hotkey->rfkill_supported & 0x20))
return sprintf(buf, "unknown\n");
if (fujitsu_hotkey->rfkill_state & 0x20)
return sprintf(buf, "on\n");
@@ -928,8 +929,17 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
; /* No action, result is discarded */
vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);
- fujitsu_hotkey->rfkill_state =
- call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
+ fujitsu_hotkey->rfkill_supported =
+ call_fext_func(FUNC_RFKILL, 0x0, 0x0, 0x0);
+
+ /* Make sure our bitmask of supported functions is cleared if the
+ RFKILL function block is not implemented, like on the S7020. */
+ if (fujitsu_hotkey->rfkill_supported == UNSUPPORTED_CMD)
+ fujitsu_hotkey->rfkill_supported = 0;
+
+ if (fujitsu_hotkey->rfkill_supported)
+ fujitsu_hotkey->rfkill_state =
+ call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
/* Suspect this is a keymap of the application panel, print it */
printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n",
@@ -1005,8 +1015,9 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
input = fujitsu_hotkey->input;
- fujitsu_hotkey->rfkill_state =
- call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
+ if (fujitsu_hotkey->rfkill_supported)
+ fujitsu_hotkey->rfkill_state =
+ call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
switch (event) {
case ACPI_FUJITSU_NOTIFY_CODE1:
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 7c789f0a94d..f41135f2fb2 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -382,6 +382,11 @@ static int __init hp_wmi_input_setup(void)
case KE_SW:
set_bit(EV_SW, hp_wmi_input_dev->evbit);
set_bit(key->keycode, hp_wmi_input_dev->swbit);
+
+ /* Set initial dock state */
+ input_report_switch(hp_wmi_input_dev, key->keycode,
+ hp_wmi_dock_state());
+ input_sync(hp_wmi_input_dev);
break;
}
}
@@ -441,6 +446,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set;
bluetooth_rfkill->user_claim_unsupported = 1;
err = rfkill_register(bluetooth_rfkill);
+ if (err)
goto register_bluetooth_error;
}
@@ -457,9 +463,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
return 0;
register_wwan_err:
- rfkill_unregister(bluetooth_rfkill);
+ if (bluetooth_rfkill)
+ rfkill_unregister(bluetooth_rfkill);
register_bluetooth_error:
- rfkill_unregister(wifi_rfkill);
+ if (wifi_rfkill)
+ rfkill_unregister(wifi_rfkill);
add_sysfs_error:
cleanup_sysfs(device);
return err;
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index f30db367c82..c47a44dcb70 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -507,7 +507,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
hkey_num = result & 0xf;
- if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) {
+ if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"hotkey number out of range: %d\n",
hkey_num));
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 537959d0714..bc8996c849a 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1917,12 +1917,7 @@ static struct sonypi_compat_s sonypi_compat = {
static int sonypi_misc_fasync(int fd, struct file *filp, int on)
{
- int retval;
-
- retval = fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
- if (retval < 0)
- return retval;
- return 0;
+ return fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
}
static int sonypi_misc_release(struct inode *inode, struct file *file)
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 3478453eba7..d2433204a40 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -21,7 +21,7 @@
* 02110-1301, USA.
*/
-#define TPACPI_VERSION "0.21"
+#define TPACPI_VERSION "0.22"
#define TPACPI_SYSFS_VERSION 0x020200
/*
@@ -122,6 +122,27 @@ enum {
#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */
#define TPACPI_HKEY_INPUT_VERSION 0x4101
+/* ACPI \WGSV commands */
+enum {
+ TP_ACPI_WGSV_GET_STATE = 0x01, /* Get state information */
+ TP_ACPI_WGSV_PWR_ON_ON_RESUME = 0x02, /* Resume WWAN powered on */
+ TP_ACPI_WGSV_PWR_OFF_ON_RESUME = 0x03, /* Resume WWAN powered off */
+ TP_ACPI_WGSV_SAVE_STATE = 0x04, /* Save state for S4/S5 */
+};
+
+/* TP_ACPI_WGSV_GET_STATE bits */
+enum {
+ TP_ACPI_WGSV_STATE_WWANEXIST = 0x0001, /* WWAN hw available */
+ TP_ACPI_WGSV_STATE_WWANPWR = 0x0002, /* WWAN radio enabled */
+ TP_ACPI_WGSV_STATE_WWANPWRRES = 0x0004, /* WWAN state at resume */
+ TP_ACPI_WGSV_STATE_WWANBIOSOFF = 0x0008, /* WWAN disabled in BIOS */
+ TP_ACPI_WGSV_STATE_BLTHEXIST = 0x0001, /* BLTH hw available */
+ TP_ACPI_WGSV_STATE_BLTHPWR = 0x0002, /* BLTH radio enabled */
+ TP_ACPI_WGSV_STATE_BLTHPWRRES = 0x0004, /* BLTH state at resume */
+ TP_ACPI_WGSV_STATE_BLTHBIOSOFF = 0x0008, /* BLTH disabled in BIOS */
+ TP_ACPI_WGSV_STATE_UWBEXIST = 0x0010, /* UWB hw available */
+ TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */
+};
/****************************************************************************
* Main driver
@@ -148,14 +169,17 @@ enum {
enum {
TPACPI_RFK_BLUETOOTH_SW_ID = 0,
TPACPI_RFK_WWAN_SW_ID,
+ TPACPI_RFK_UWB_SW_ID,
};
/* Debugging */
#define TPACPI_LOG TPACPI_FILE ": "
-#define TPACPI_ERR KERN_ERR TPACPI_LOG
-#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
-#define TPACPI_INFO KERN_INFO TPACPI_LOG
-#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
+#define TPACPI_ALERT KERN_ALERT TPACPI_LOG
+#define TPACPI_CRIT KERN_CRIT TPACPI_LOG
+#define TPACPI_ERR KERN_ERR TPACPI_LOG
+#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
+#define TPACPI_INFO KERN_INFO TPACPI_LOG
+#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
#define TPACPI_DBG_ALL 0xffff
#define TPACPI_DBG_INIT 0x0001
@@ -201,6 +225,7 @@ struct ibm_struct {
void (*exit) (void);
void (*resume) (void);
void (*suspend) (pm_message_t state);
+ void (*shutdown) (void);
struct list_head all_drivers;
@@ -239,6 +264,7 @@ static struct {
u32 bright_16levels:1;
u32 bright_acpimode:1;
u32 wan:1;
+ u32 uwb:1;
u32 fan_ctrl_status_undef:1;
u32 input_device_registered:1;
u32 platform_drv_registered:1;
@@ -288,6 +314,18 @@ struct tpacpi_led_classdev {
unsigned int led;
};
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+static int dbg_wlswemul;
+static int tpacpi_wlsw_emulstate;
+static int dbg_bluetoothemul;
+static int tpacpi_bluetooth_emulstate;
+static int dbg_wwanemul;
+static int tpacpi_wwan_emulstate;
+static int dbg_uwbemul;
+static int tpacpi_uwb_emulstate;
+#endif
+
+
/****************************************************************************
****************************************************************************
*
@@ -728,6 +766,18 @@ static int tpacpi_resume_handler(struct platform_device *pdev)
return 0;
}
+static void tpacpi_shutdown_handler(struct platform_device *pdev)
+{
+ struct ibm_struct *ibm, *itmp;
+
+ list_for_each_entry_safe(ibm, itmp,
+ &tpacpi_all_drivers,
+ all_drivers) {
+ if (ibm->shutdown)
+ (ibm->shutdown)();
+ }
+}
+
static struct platform_driver tpacpi_pdriver = {
.driver = {
.name = TPACPI_DRVR_NAME,
@@ -735,6 +785,7 @@ static struct platform_driver tpacpi_pdriver = {
},
.suspend = tpacpi_suspend_handler,
.resume = tpacpi_resume_handler,
+ .shutdown = tpacpi_shutdown_handler,
};
static struct platform_driver tpacpi_hwmon_pdriver = {
@@ -922,11 +973,27 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
struct rfkill **rfk,
const enum rfkill_type rfktype,
const char *name,
+ const bool set_default,
int (*toggle_radio)(void *, enum rfkill_state),
int (*get_state)(void *, enum rfkill_state *))
{
int res;
- enum rfkill_state initial_state;
+ enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED;
+
+ res = get_state(NULL, &initial_state);
+ if (res < 0) {
+ printk(TPACPI_ERR
+ "failed to read initial state for %s, error %d; "
+ "will turn radio off\n", name, res);
+ } else if (set_default) {
+ /* try to set the initial state as the default for the rfkill
+ * type, since we ask the firmware to preserve it across S5 in
+ * NVRAM */
+ rfkill_set_default(rfktype,
+ (initial_state == RFKILL_STATE_UNBLOCKED) ?
+ RFKILL_STATE_UNBLOCKED :
+ RFKILL_STATE_SOFT_BLOCKED);
+ }
*rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
if (!*rfk) {
@@ -938,9 +1005,7 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
(*rfk)->name = name;
(*rfk)->get_state = get_state;
(*rfk)->toggle_radio = toggle_radio;
-
- if (!get_state(NULL, &initial_state))
- (*rfk)->state = initial_state;
+ (*rfk)->state = initial_state;
res = rfkill_register(*rfk);
if (res < 0) {
@@ -1006,6 +1071,119 @@ static DRIVER_ATTR(version, S_IRUGO,
/* --------------------------------------------------------------------- */
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+
+static void tpacpi_send_radiosw_update(void);
+
+/* wlsw_emulstate ------------------------------------------------------ */
+static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wlsw_emulstate);
+}
+
+static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
+ const char *buf, size_t count)
+{
+ unsigned long t;
+
+ if (parse_strtoul(buf, 1, &t))
+ return -EINVAL;
+
+ if (tpacpi_wlsw_emulstate != t) {
+ tpacpi_wlsw_emulstate = !!t;
+ tpacpi_send_radiosw_update();
+ } else
+ tpacpi_wlsw_emulstate = !!t;
+
+ return count;
+}
+
+static DRIVER_ATTR(wlsw_emulstate, S_IWUSR | S_IRUGO,
+ tpacpi_driver_wlsw_emulstate_show,
+ tpacpi_driver_wlsw_emulstate_store);
+
+/* bluetooth_emulstate ------------------------------------------------- */
+static ssize_t tpacpi_driver_bluetooth_emulstate_show(
+ struct device_driver *drv,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_bluetooth_emulstate);
+}
+
+static ssize_t tpacpi_driver_bluetooth_emulstate_store(
+ struct device_driver *drv,
+ const char *buf, size_t count)
+{
+ unsigned long t;
+
+ if (parse_strtoul(buf, 1, &t))
+ return -EINVAL;
+
+ tpacpi_bluetooth_emulstate = !!t;
+
+ return count;
+}
+
+static DRIVER_ATTR(bluetooth_emulstate, S_IWUSR | S_IRUGO,
+ tpacpi_driver_bluetooth_emulstate_show,
+ tpacpi_driver_bluetooth_emulstate_store);
+
+/* wwan_emulstate ------------------------------------------------- */
+static ssize_t tpacpi_driver_wwan_emulstate_show(
+ struct device_driver *drv,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wwan_emulstate);
+}
+
+static ssize_t tpacpi_driver_wwan_emulstate_store(
+ struct device_driver *drv,
+ const char *buf, size_t count)
+{
+ unsigned long t;
+
+ if (parse_strtoul(buf, 1, &t))
+ return -EINVAL;
+
+ tpacpi_wwan_emulstate = !!t;
+
+ return count;
+}
+
+static DRIVER_ATTR(wwan_emulstate, S_IWUSR | S_IRUGO,
+ tpacpi_driver_wwan_emulstate_show,
+ tpacpi_driver_wwan_emulstate_store);
+
+/* uwb_emulstate ------------------------------------------------- */
+static ssize_t tpacpi_driver_uwb_emulstate_show(
+ struct device_driver *drv,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_uwb_emulstate);
+}
+
+static ssize_t tpacpi_driver_uwb_emulstate_store(
+ struct device_driver *drv,
+ const char *buf, size_t count)
+{
+ unsigned long t;
+
+ if (parse_strtoul(buf, 1, &t))
+ return -EINVAL;
+
+ tpacpi_uwb_emulstate = !!t;
+
+ return count;
+}
+
+static DRIVER_ATTR(uwb_emulstate, S_IWUSR | S_IRUGO,
+ tpacpi_driver_uwb_emulstate_show,
+ tpacpi_driver_uwb_emulstate_store);
+#endif
+
+/* --------------------------------------------------------------------- */
+
static struct driver_attribute *tpacpi_driver_attributes[] = {
&driver_attr_debug_level, &driver_attr_version,
&driver_attr_interface_version,
@@ -1022,6 +1200,17 @@ static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
i++;
}
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (!res && dbg_wlswemul)
+ res = driver_create_file(drv, &driver_attr_wlsw_emulstate);
+ if (!res && dbg_bluetoothemul)
+ res = driver_create_file(drv, &driver_attr_bluetooth_emulstate);
+ if (!res && dbg_wwanemul)
+ res = driver_create_file(drv, &driver_attr_wwan_emulstate);
+ if (!res && dbg_uwbemul)
+ res = driver_create_file(drv, &driver_attr_uwb_emulstate);
+#endif
+
return res;
}
@@ -1031,6 +1220,13 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
driver_remove_file(drv, tpacpi_driver_attributes[i]);
+
+#ifdef THINKPAD_ACPI_DEBUGFACILITIES
+ driver_remove_file(drv, &driver_attr_wlsw_emulstate);
+ driver_remove_file(drv, &driver_attr_bluetooth_emulstate);
+ driver_remove_file(drv, &driver_attr_wwan_emulstate);
+ driver_remove_file(drv, &driver_attr_uwb_emulstate);
+#endif
}
/****************************************************************************
@@ -1216,6 +1412,12 @@ static struct attribute_set *hotkey_dev_attributes;
static int hotkey_get_wlsw(int *status)
{
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_wlswemul) {
+ *status = !!tpacpi_wlsw_emulstate;
+ return 0;
+ }
+#endif
if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
return -EIO;
return 0;
@@ -1678,7 +1880,7 @@ static ssize_t hotkey_mask_show(struct device *dev,
{
int res;
- if (mutex_lock_interruptible(&hotkey_mutex))
+ if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
res = hotkey_mask_get();
mutex_unlock(&hotkey_mutex);
@@ -1697,7 +1899,7 @@ static ssize_t hotkey_mask_store(struct device *dev,
if (parse_strtoul(buf, 0xffffffffUL, &t))
return -EINVAL;
- if (mutex_lock_interruptible(&hotkey_mutex))
+ if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
res = hotkey_mask_set(t);
@@ -1783,7 +1985,7 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))
return -EINVAL;
- if (mutex_lock_interruptible(&hotkey_mutex))
+ if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
HOTKEY_CONFIG_CRITICAL_START
@@ -1818,7 +2020,7 @@ static ssize_t hotkey_poll_freq_store(struct device *dev,
if (parse_strtoul(buf, 25, &t))
return -EINVAL;
- if (mutex_lock_interruptible(&hotkey_mutex))
+ if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
hotkey_poll_freq = t;
@@ -1958,6 +2160,7 @@ static struct attribute *hotkey_mask_attributes[] __initdata = {
static void bluetooth_update_rfk(void);
static void wan_update_rfk(void);
+static void uwb_update_rfk(void);
static void tpacpi_send_radiosw_update(void)
{
int wlsw;
@@ -1967,6 +2170,8 @@ static void tpacpi_send_radiosw_update(void)
bluetooth_update_rfk();
if (tp_features.wan)
wan_update_rfk();
+ if (tp_features.uwb)
+ uwb_update_rfk();
if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
mutex_lock(&tpacpi_inputdev_send_mutex);
@@ -2222,6 +2427,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
hotkey_source_mask, hotkey_poll_freq);
#endif
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_wlswemul) {
+ tp_features.hotkey_wlsw = 1;
+ printk(TPACPI_INFO
+ "radio switch emulation enabled\n");
+ } else
+#endif
/* Not all thinkpads have a hardware radio switch */
if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
tp_features.hotkey_wlsw = 1;
@@ -2361,13 +2573,154 @@ err_exit:
return (res < 0)? res : 1;
}
+static bool hotkey_notify_hotkey(const u32 hkey,
+ bool *send_acpi_ev,
+ bool *ignore_acpi_ev)
+{
+ /* 0x1000-0x1FFF: key presses */
+ unsigned int scancode = hkey & 0xfff;
+ *send_acpi_ev = true;
+ *ignore_acpi_ev = false;
+
+ if (scancode > 0 && scancode < 0x21) {
+ scancode--;
+ if (!(hotkey_source_mask & (1 << scancode))) {
+ tpacpi_input_send_key(scancode);
+ *send_acpi_ev = false;
+ } else {
+ *ignore_acpi_ev = true;
+ }
+ return true;
+ }
+ return false;
+}
+
+static bool hotkey_notify_wakeup(const u32 hkey,
+ bool *send_acpi_ev,
+ bool *ignore_acpi_ev)
+{
+ /* 0x2000-0x2FFF: Wakeup reason */
+ *send_acpi_ev = true;
+ *ignore_acpi_ev = false;
+
+ switch (hkey) {
+ case 0x2304: /* suspend, undock */
+ case 0x2404: /* hibernation, undock */
+ hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;
+ *ignore_acpi_ev = true;
+ break;
+
+ case 0x2305: /* suspend, bay eject */
+ case 0x2405: /* hibernation, bay eject */
+ hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;
+ *ignore_acpi_ev = true;
+ break;
+
+ case 0x2313: /* Battery on critical low level (S3) */
+ case 0x2413: /* Battery on critical low level (S4) */
+ printk(TPACPI_ALERT
+ "EMERGENCY WAKEUP: battery almost empty\n");
+ /* how to auto-heal: */
+ /* 2313: woke up from S3, go to S4/S5 */
+ /* 2413: woke up from S4, go to S5 */
+ break;
+
+ default:
+ return false;
+ }
+
+ if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) {
+ printk(TPACPI_INFO
+ "woke up due to a hot-unplug "
+ "request...\n");
+ hotkey_wakeup_reason_notify_change();
+ }
+ return true;
+}
+
+static bool hotkey_notify_usrevent(const u32 hkey,
+ bool *send_acpi_ev,
+ bool *ignore_acpi_ev)
+{
+ /* 0x5000-0x5FFF: human interface helpers */
+ *send_acpi_ev = true;
+ *ignore_acpi_ev = false;
+
+ switch (hkey) {
+ case 0x5010: /* Lenovo new BIOS: brightness changed */
+ case 0x500b: /* X61t: tablet pen inserted into bay */
+ case 0x500c: /* X61t: tablet pen removed from bay */
+ return true;
+
+ case 0x5009: /* X41t-X61t: swivel up (tablet mode) */
+ case 0x500a: /* X41t-X61t: swivel down (normal mode) */
+ tpacpi_input_send_tabletsw();
+ hotkey_tablet_mode_notify_change();
+ *send_acpi_ev = false;
+ return true;
+
+ case 0x5001:
+ case 0x5002:
+ /* LID switch events. Do not propagate */
+ *ignore_acpi_ev = true;
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static bool hotkey_notify_thermal(const u32 hkey,
+ bool *send_acpi_ev,
+ bool *ignore_acpi_ev)
+{
+ /* 0x6000-0x6FFF: thermal alarms */
+ *send_acpi_ev = true;
+ *ignore_acpi_ev = false;
+
+ switch (hkey) {
+ case 0x6011:
+ printk(TPACPI_CRIT
+ "THERMAL ALARM: battery is too hot!\n");
+ /* recommended action: warn user through gui */
+ return true;
+ case 0x6012:
+ printk(TPACPI_ALERT
+ "THERMAL EMERGENCY: battery is extremely hot!\n");
+ /* recommended action: immediate sleep/hibernate */
+ return true;
+ case 0x6021:
+ printk(TPACPI_CRIT
+ "THERMAL ALARM: "
+ "a sensor reports something is too hot!\n");
+ /* recommended action: warn user through gui, that */
+ /* some internal component is too hot */
+ return true;
+ case 0x6022:
+ printk(TPACPI_ALERT
+ "THERMAL EMERGENCY: "
+ "a sensor reports something is extremely hot!\n");
+ /* recommended action: immediate sleep/hibernate */
+ return true;
+ case 0x6030:
+ printk(TPACPI_INFO
+ "EC reports that Thermal Table has changed\n");
+ /* recommended action: do nothing, we don't have
+ * Lenovo ATM information */
+ return true;
+ default:
+ printk(TPACPI_ALERT
+ "THERMAL ALERT: unknown thermal alarm received\n");
+ return false;
+ }
+}
+
static void hotkey_notify(struct ibm_struct *ibm, u32 event)
{
u32 hkey;
- unsigned int scancode;
- int send_acpi_ev;
- int ignore_acpi_ev;
- int unk_ev;
+ bool send_acpi_ev;
+ bool ignore_acpi_ev;
+ bool known_ev;
if (event != 0x80) {
printk(TPACPI_ERR
@@ -2375,7 +2728,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
/* forward it to userspace, maybe it knows how to handle it */
acpi_bus_generate_netlink_event(
ibm->acpi->device->pnp.device_class,
- ibm->acpi->device->dev.bus_id,
+ dev_name(&ibm->acpi->device->dev),
event, 0);
return;
}
@@ -2391,107 +2744,72 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
return;
}
- send_acpi_ev = 1;
- ignore_acpi_ev = 0;
- unk_ev = 0;
+ send_acpi_ev = true;
+ ignore_acpi_ev = false;
switch (hkey >> 12) {
case 1:
/* 0x1000-0x1FFF: key presses */
- scancode = hkey & 0xfff;
- if (scancode > 0 && scancode < 0x21) {
- scancode--;
- if (!(hotkey_source_mask & (1 << scancode))) {
- tpacpi_input_send_key(scancode);
- send_acpi_ev = 0;
- } else {
- ignore_acpi_ev = 1;
- }
- } else {
- unk_ev = 1;
- }
+ known_ev = hotkey_notify_hotkey(hkey, &send_acpi_ev,
+ &ignore_acpi_ev);
break;
case 2:
- /* Wakeup reason */
- switch (hkey) {
- case 0x2304: /* suspend, undock */
- case 0x2404: /* hibernation, undock */
- hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;
- ignore_acpi_ev = 1;
- break;
- case 0x2305: /* suspend, bay eject */
- case 0x2405: /* hibernation, bay eject */
- hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;
- ignore_acpi_ev = 1;
- break;
- default:
- unk_ev = 1;
- }
- if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) {
- printk(TPACPI_INFO
- "woke up due to a hot-unplug "
- "request...\n");
- hotkey_wakeup_reason_notify_change();
- }
+ /* 0x2000-0x2FFF: Wakeup reason */
+ known_ev = hotkey_notify_wakeup(hkey, &send_acpi_ev,
+ &ignore_acpi_ev);
break;
case 3:
- /* bay-related wakeups */
+ /* 0x3000-0x3FFF: bay-related wakeups */
if (hkey == 0x3003) {
hotkey_autosleep_ack = 1;
printk(TPACPI_INFO
"bay ejected\n");
hotkey_wakeup_hotunplug_complete_notify_change();
+ known_ev = true;
} else {
- unk_ev = 1;
+ known_ev = false;
}
break;
case 4:
- /* dock-related wakeups */
+ /* 0x4000-0x4FFF: dock-related wakeups */
if (hkey == 0x4003) {
hotkey_autosleep_ack = 1;
printk(TPACPI_INFO
"undocked\n");
hotkey_wakeup_hotunplug_complete_notify_change();
+ known_ev = true;
} else {
- unk_ev = 1;
+ known_ev = false;
}
break;
case 5:
/* 0x5000-0x5FFF: human interface helpers */
- switch (hkey) {
- case 0x5010: /* Lenovo new BIOS: brightness changed */
- case 0x500b: /* X61t: tablet pen inserted into bay */
- case 0x500c: /* X61t: tablet pen removed from bay */
- break;
- case 0x5009: /* X41t-X61t: swivel up (tablet mode) */
- case 0x500a: /* X41t-X61t: swivel down (normal mode) */
- tpacpi_input_send_tabletsw();
- hotkey_tablet_mode_notify_change();
- send_acpi_ev = 0;
- break;
- case 0x5001:
- case 0x5002:
- /* LID switch events. Do not propagate */
- ignore_acpi_ev = 1;
- break;
- default:
- unk_ev = 1;
- }
+ known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev,
+ &ignore_acpi_ev);
+ break;
+ case 6:
+ /* 0x6000-0x6FFF: thermal alarms */
+ known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev,
+ &ignore_acpi_ev);
break;
case 7:
/* 0x7000-0x7FFF: misc */
if (tp_features.hotkey_wlsw && hkey == 0x7000) {
tpacpi_send_radiosw_update();
send_acpi_ev = 0;
+ known_ev = true;
break;
}
/* fallthrough to default */
default:
- unk_ev = 1;
+ known_ev = false;
}
- if (unk_ev) {
+ if (!known_ev) {
printk(TPACPI_NOTICE
"unhandled HKEY event 0x%04x\n", hkey);
+ printk(TPACPI_NOTICE
+ "please report the conditions when this "
+ "event happened to %s\n", TPACPI_MAIL);
}
/* Legacy events */
@@ -2505,7 +2823,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
if (!ignore_acpi_ev && send_acpi_ev) {
acpi_bus_generate_netlink_event(
ibm->acpi->device->pnp.device_class,
- ibm->acpi->device->dev.bus_id,
+ dev_name(&ibm->acpi->device->dev),
event, hkey);
}
}
@@ -2544,7 +2862,7 @@ static int hotkey_read(char *p)
return len;
}
- if (mutex_lock_interruptible(&hotkey_mutex))
+ if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
res = hotkey_status_get(&status);
if (!res)
@@ -2575,7 +2893,7 @@ static int hotkey_write(char *buf)
if (!tp_features.hotkey)
return -ENODEV;
- if (mutex_lock_interruptible(&hotkey_mutex))
+ if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
status = -1;
@@ -2640,11 +2958,28 @@ enum {
/* ACPI GBDC/SBDC bits */
TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
- TP_ACPI_BLUETOOTH_UNK = 0x04, /* unknown function */
+ TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume:
+ off / last state */
+};
+
+enum {
+ /* ACPI \BLTH commands */
+ TP_ACPI_BLTH_GET_ULTRAPORT_ID = 0x00, /* Get Ultraport BT ID */
+ TP_ACPI_BLTH_GET_PWR_ON_RESUME = 0x01, /* Get power-on-resume state */
+ TP_ACPI_BLTH_PWR_ON_ON_RESUME = 0x02, /* Resume powered on */
+ TP_ACPI_BLTH_PWR_OFF_ON_RESUME = 0x03, /* Resume powered off */
+ TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */
};
static struct rfkill *tpacpi_bluetooth_rfkill;
+static void bluetooth_suspend(pm_message_t state)
+{
+ /* Try to make sure radio will resume powered off */
+ acpi_evalf(NULL, NULL, "\\BLTH", "vd",
+ TP_ACPI_BLTH_PWR_OFF_ON_RESUME);
+}
+
static int bluetooth_get_radiosw(void)
{
int status;
@@ -2656,6 +2991,12 @@ static int bluetooth_get_radiosw(void)
if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
return RFKILL_STATE_HARD_BLOCKED;
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_bluetoothemul)
+ return (tpacpi_bluetooth_emulstate) ?
+ RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+#endif
+
if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
return -EIO;
@@ -2689,12 +3030,20 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
- if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
- return -EIO;
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_bluetoothemul) {
+ tpacpi_bluetooth_emulstate = !!radio_on;
+ if (update_rfk)
+ bluetooth_update_rfk();
+ return 0;
+ }
+#endif
+
+ /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
if (radio_on)
- status |= TP_ACPI_BLUETOOTH_RADIOSSW;
+ status = TP_ACPI_BLUETOOTH_RADIOSSW;
else
- status &= ~TP_ACPI_BLUETOOTH_RADIOSSW;
+ status = 0;
if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
return -EIO;
@@ -2765,8 +3114,19 @@ static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
+static void bluetooth_shutdown(void)
+{
+ /* Order firmware to save current state to NVRAM */
+ if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
+ TP_ACPI_BLTH_SAVE_STATE))
+ printk(TPACPI_NOTICE
+ "failed to save bluetooth state to NVRAM\n");
+}
+
static void bluetooth_exit(void)
{
+ bluetooth_shutdown();
+
if (tpacpi_bluetooth_rfkill)
rfkill_unregister(tpacpi_bluetooth_rfkill);
@@ -2792,6 +3152,13 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
str_supported(tp_features.bluetooth),
status);
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_bluetoothemul) {
+ tp_features.bluetooth = 1;
+ printk(TPACPI_INFO
+ "bluetooth switch emulation enabled\n");
+ } else
+#endif
if (tp_features.bluetooth &&
!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
/* no bluetooth hardware present in system */
@@ -2812,6 +3179,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
&tpacpi_bluetooth_rfkill,
RFKILL_TYPE_BLUETOOTH,
"tpacpi_bluetooth_sw",
+ true,
tpacpi_bluetooth_rfk_set,
tpacpi_bluetooth_rfk_get);
if (res) {
@@ -2864,6 +3232,8 @@ static struct ibm_struct bluetooth_driver_data = {
.read = bluetooth_read,
.write = bluetooth_write,
.exit = bluetooth_exit,
+ .suspend = bluetooth_suspend,
+ .shutdown = bluetooth_shutdown,
};
/*************************************************************************
@@ -2874,11 +3244,19 @@ enum {
/* ACPI GWAN/SWAN bits */
TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
- TP_ACPI_WANCARD_UNK = 0x04, /* unknown function */
+ TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume:
+ off / last state */
};
static struct rfkill *tpacpi_wan_rfkill;
+static void wan_suspend(pm_message_t state)
+{
+ /* Try to make sure radio will resume powered off */
+ acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
+ TP_ACPI_WGSV_PWR_OFF_ON_RESUME);
+}
+
static int wan_get_radiosw(void)
{
int status;
@@ -2890,6 +3268,12 @@ static int wan_get_radiosw(void)
if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
return RFKILL_STATE_HARD_BLOCKED;
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_wwanemul)
+ return (tpacpi_wwan_emulstate) ?
+ RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+#endif
+
if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
return -EIO;
@@ -2923,12 +3307,20 @@ static int wan_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
- if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
- return -EIO;
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_wwanemul) {
+ tpacpi_wwan_emulstate = !!radio_on;
+ if (update_rfk)
+ wan_update_rfk();
+ return 0;
+ }
+#endif
+
+ /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
if (radio_on)
- status |= TP_ACPI_WANCARD_RADIOSSW;
+ status = TP_ACPI_WANCARD_RADIOSSW;
else
- status &= ~TP_ACPI_WANCARD_RADIOSSW;
+ status = 0;
if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
return -EIO;
@@ -2999,8 +3391,19 @@ static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
+static void wan_shutdown(void)
+{
+ /* Order firmware to save current state to NVRAM */
+ if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd",
+ TP_ACPI_WGSV_SAVE_STATE))
+ printk(TPACPI_NOTICE
+ "failed to save WWAN state to NVRAM\n");
+}
+
static void wan_exit(void)
{
+ wan_shutdown();
+
if (tpacpi_wan_rfkill)
rfkill_unregister(tpacpi_wan_rfkill);
@@ -3024,6 +3427,13 @@ static int __init wan_init(struct ibm_init_struct *iibm)
str_supported(tp_features.wan),
status);
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_wwanemul) {
+ tp_features.wan = 1;
+ printk(TPACPI_INFO
+ "wwan switch emulation enabled\n");
+ } else
+#endif
if (tp_features.wan &&
!(status & TP_ACPI_WANCARD_HWPRESENT)) {
/* no wan hardware present in system */
@@ -3044,6 +3454,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
&tpacpi_wan_rfkill,
RFKILL_TYPE_WWAN,
"tpacpi_wwan_sw",
+ true,
tpacpi_wan_rfk_set,
tpacpi_wan_rfk_get);
if (res) {
@@ -3096,6 +3507,164 @@ static struct ibm_struct wan_driver_data = {
.read = wan_read,
.write = wan_write,
.exit = wan_exit,
+ .suspend = wan_suspend,
+ .shutdown = wan_shutdown,
+};
+
+/*************************************************************************
+ * UWB subdriver
+ */
+
+enum {
+ /* ACPI GUWB/SUWB bits */
+ TP_ACPI_UWB_HWPRESENT = 0x01, /* UWB hw available */
+ TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */
+};
+
+static struct rfkill *tpacpi_uwb_rfkill;
+
+static int uwb_get_radiosw(void)
+{
+ int status;
+
+ if (!tp_features.uwb)
+ return -ENODEV;
+
+ /* WLSW overrides UWB in firmware/hardware, reflect that */
+ if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
+ return RFKILL_STATE_HARD_BLOCKED;
+
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_uwbemul)
+ return (tpacpi_uwb_emulstate) ?
+ RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+#endif
+
+ if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))
+ return -EIO;
+
+ return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?
+ RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+}
+
+static void uwb_update_rfk(void)
+{
+ int status;
+
+ if (!tpacpi_uwb_rfkill)
+ return;
+
+ status = uwb_get_radiosw();
+ if (status < 0)
+ return;
+ rfkill_force_state(tpacpi_uwb_rfkill, status);
+}
+
+static int uwb_set_radiosw(int radio_on, int update_rfk)
+{
+ int status;
+
+ if (!tp_features.uwb)
+ return -ENODEV;
+
+ /* WLSW overrides UWB in firmware/hardware, but there is no
+ * reason to risk weird behaviour. */
+ if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
+ && radio_on)
+ return -EPERM;
+
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_uwbemul) {
+ tpacpi_uwb_emulstate = !!radio_on;
+ if (update_rfk)
+ uwb_update_rfk();
+ return 0;
+ }
+#endif
+
+ status = (radio_on) ? TP_ACPI_UWB_RADIOSSW : 0;
+ if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))
+ return -EIO;
+
+ if (update_rfk)
+ uwb_update_rfk();
+
+ return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state)
+{
+ int uwbs = uwb_get_radiosw();
+
+ if (uwbs < 0)
+ return uwbs;
+
+ *state = uwbs;
+ return 0;
+}
+
+static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
+{
+ return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
+}
+
+static void uwb_exit(void)
+{
+ if (tpacpi_uwb_rfkill)
+ rfkill_unregister(tpacpi_uwb_rfkill);
+}
+
+static int __init uwb_init(struct ibm_init_struct *iibm)
+{
+ int res;
+ int status = 0;
+
+ vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n");
+
+ TPACPI_ACPIHANDLE_INIT(hkey);
+
+ tp_features.uwb = hkey_handle &&
+ acpi_evalf(hkey_handle, &status, "GUWB", "qd");
+
+ vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n",
+ str_supported(tp_features.uwb),
+ status);
+
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+ if (dbg_uwbemul) {
+ tp_features.uwb = 1;
+ printk(TPACPI_INFO
+ "uwb switch emulation enabled\n");
+ } else
+#endif
+ if (tp_features.uwb &&
+ !(status & TP_ACPI_UWB_HWPRESENT)) {
+ /* no uwb hardware present in system */
+ tp_features.uwb = 0;
+ dbg_printk(TPACPI_DBG_INIT,
+ "uwb hardware not installed\n");
+ }
+
+ if (!tp_features.uwb)
+ return 1;
+
+ res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
+ &tpacpi_uwb_rfkill,
+ RFKILL_TYPE_UWB,
+ "tpacpi_uwb_sw",
+ false,
+ tpacpi_uwb_rfk_set,
+ tpacpi_uwb_rfk_get);
+
+ return res;
+}
+
+static struct ibm_struct uwb_driver_data = {
+ .name = "uwb",
+ .exit = uwb_exit,
+ .flags.experimental = 1,
};
/*************************************************************************
@@ -3724,7 +4293,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event)
}
acpi_bus_generate_proc_event(ibm->acpi->device, event, data);
acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
- ibm->acpi->device->dev.bus_id,
+ dev_name(&ibm->acpi->device->dev),
event, data);
}
@@ -3826,7 +4395,7 @@ static void bay_notify(struct ibm_struct *ibm, u32 event)
{
acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
- ibm->acpi->device->dev.bus_id,
+ dev_name(&ibm->acpi->device->dev),
event, 0);
}
@@ -4850,7 +5419,7 @@ static int brightness_set(int value)
value < 0)
return -EINVAL;
- res = mutex_lock_interruptible(&brightness_mutex);
+ res = mutex_lock_killable(&brightness_mutex);
if (res < 0)
return res;
@@ -5334,6 +5903,60 @@ TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */
); /* all others */
/*
+ * Unitialized HFSP quirk: ACPI DSDT and EC fail to initialize the
+ * HFSP register at boot, so it contains 0x07 but the Thinkpad could
+ * be in auto mode (0x80).
+ *
+ * This is corrected by any write to HFSP either by the driver, or
+ * by the firmware.
+ *
+ * We assume 0x07 really means auto mode while this quirk is active,
+ * as this is far more likely than the ThinkPad being in level 7,
+ * which is only used by the firmware during thermal emergencies.
+ */
+
+static void fan_quirk1_detect(void)
+{
+ /* In some ThinkPads, neither the EC nor the ACPI
+ * DSDT initialize the HFSP register, and it ends up
+ * being initially set to 0x07 when it *could* be
+ * either 0x07 or 0x80.
+ *
+ * Enable for TP-1Y (T43), TP-78 (R51e),
+ * TP-76 (R52), TP-70 (T43, R52), which are known
+ * to be buggy. */
+ if (fan_control_initial_status == 0x07) {
+ switch (thinkpad_id.ec_model) {
+ case 0x5931: /* TP-1Y */
+ case 0x3837: /* TP-78 */
+ case 0x3637: /* TP-76 */
+ case 0x3037: /* TP-70 */
+ printk(TPACPI_NOTICE
+ "fan_init: initial fan status is unknown, "
+ "assuming it is in auto mode\n");
+ tp_features.fan_ctrl_status_undef = 1;
+ ;;
+ }
+ }
+}
+
+static void fan_quirk1_handle(u8 *fan_status)
+{
+ if (unlikely(tp_features.fan_ctrl_status_undef)) {
+ if (*fan_status != fan_control_initial_status) {
+ /* something changed the HFSP regisnter since
+ * driver init time, so it is not undefined
+ * anymore */
+ tp_features.fan_ctrl_status_undef = 0;
+ } else {
+ /* Return most likely status. In fact, it
+ * might be the only possible status */
+ *fan_status = TP_EC_FAN_AUTO;
+ }
+ }
+}
+
+/*
* Call with fan_mutex held
*/
static void fan_update_desired_level(u8 status)
@@ -5371,8 +5994,10 @@ static int fan_get_status(u8 *status)
if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
return -EIO;
- if (likely(status))
+ if (likely(status)) {
*status = s;
+ fan_quirk1_handle(status);
+ }
break;
@@ -5388,7 +6013,7 @@ static int fan_get_status_safe(u8 *status)
int rc;
u8 s;
- if (mutex_lock_interruptible(&fan_mutex))
+ if (mutex_lock_killable(&fan_mutex))
return -ERESTARTSYS;
rc = fan_get_status(&s);
if (!rc)
@@ -5471,7 +6096,7 @@ static int fan_set_level_safe(int level)
if (!fan_control_allowed)
return -EPERM;
- if (mutex_lock_interruptible(&fan_mutex))
+ if (mutex_lock_killable(&fan_mutex))
return -ERESTARTSYS;
if (level == TPACPI_FAN_LAST_LEVEL)
@@ -5493,7 +6118,7 @@ static int fan_set_enable(void)
if (!fan_control_allowed)
return -EPERM;
- if (mutex_lock_interruptible(&fan_mutex))
+ if (mutex_lock_killable(&fan_mutex))
return -ERESTARTSYS;
switch (fan_control_access_mode) {
@@ -5548,7 +6173,7 @@ static int fan_set_disable(void)
if (!fan_control_allowed)
return -EPERM;
- if (mutex_lock_interruptible(&fan_mutex))
+ if (mutex_lock_killable(&fan_mutex))
return -ERESTARTSYS;
rc = 0;
@@ -5586,7 +6211,7 @@ static int fan_set_speed(int speed)
if (!fan_control_allowed)
return -EPERM;
- if (mutex_lock_interruptible(&fan_mutex))
+ if (mutex_lock_killable(&fan_mutex))
return -ERESTARTSYS;
rc = 0;
@@ -5682,16 +6307,6 @@ static ssize_t fan_pwm1_enable_show(struct device *dev,
if (res)
return res;
- if (unlikely(tp_features.fan_ctrl_status_undef)) {
- if (status != fan_control_initial_status) {
- tp_features.fan_ctrl_status_undef = 0;
- } else {
- /* Return most likely status. In fact, it
- * might be the only possible status */
- status = TP_EC_FAN_AUTO;
- }
- }
-
if (status & TP_EC_FAN_FULLSPEED) {
mode = 0;
} else if (status & TP_EC_FAN_AUTO) {
@@ -5756,14 +6371,6 @@ static ssize_t fan_pwm1_show(struct device *dev,
if (res)
return res;
- if (unlikely(tp_features.fan_ctrl_status_undef)) {
- if (status != fan_control_initial_status) {
- tp_features.fan_ctrl_status_undef = 0;
- } else {
- status = TP_EC_FAN_AUTO;
- }
- }
-
if ((status &
(TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
status = fan_control_desired_level;
@@ -5788,7 +6395,7 @@ static ssize_t fan_pwm1_store(struct device *dev,
/* scale down from 0-255 to 0-7 */
newlevel = (s >> 5) & 0x07;
- if (mutex_lock_interruptible(&fan_mutex))
+ if (mutex_lock_killable(&fan_mutex))
return -ERESTARTSYS;
rc = fan_get_status(&status);
@@ -5895,29 +6502,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
if (likely(acpi_ec_read(fan_status_offset,
&fan_control_initial_status))) {
fan_status_access_mode = TPACPI_FAN_RD_TPEC;
-
- /* In some ThinkPads, neither the EC nor the ACPI
- * DSDT initialize the fan status, and it ends up
- * being set to 0x07 when it *could* be either
- * 0x07 or 0x80.
- *
- * Enable for TP-1Y (T43), TP-78 (R51e),
- * TP-76 (R52), TP-70 (T43, R52), which are known
- * to be buggy. */
- if (fan_control_initial_status == 0x07) {
- switch (thinkpad_id.ec_model) {
- case 0x5931: /* TP-1Y */
- case 0x3837: /* TP-78 */
- case 0x3637: /* TP-76 */
- case 0x3037: /* TP-70 */
- printk(TPACPI_NOTICE
- "fan_init: initial fan status "
- "is unknown, assuming it is "
- "in auto mode\n");
- tp_features.fan_ctrl_status_undef = 1;
- ;;
- }
- }
+ fan_quirk1_detect();
} else {
printk(TPACPI_ERR
"ThinkPad ACPI EC access misbehaving, "
@@ -6106,15 +6691,6 @@ static int fan_read(char *p)
if (rc < 0)
return rc;
- if (unlikely(tp_features.fan_ctrl_status_undef)) {
- if (status != fan_control_initial_status)
- tp_features.fan_ctrl_status_undef = 0;
- else
- /* Return most likely status. In fact, it
- * might be the only possible status */
- status = TP_EC_FAN_AUTO;
- }
-
len += sprintf(p + len, "status:\t\t%s\n",
(status != 0) ? "enabled" : "disabled");
@@ -6563,6 +7139,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
.init = wan_init,
.data = &wan_driver_data,
},
+ {
+ .init = uwb_init,
+ .data = &uwb_driver_data,
+ },
#ifdef CONFIG_THINKPAD_ACPI_VIDEO
{
.init = video_init,
@@ -6701,6 +7281,32 @@ TPACPI_PARAM(brightness);
TPACPI_PARAM(volume);
TPACPI_PARAM(fan);
+#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
+module_param(dbg_wlswemul, uint, 0);
+MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");
+module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
+MODULE_PARM_DESC(wlsw_state,
+ "Initial state of the emulated WLSW switch");
+
+module_param(dbg_bluetoothemul, uint, 0);
+MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");
+module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
+MODULE_PARM_DESC(bluetooth_state,
+ "Initial state of the emulated bluetooth switch");
+
+module_param(dbg_wwanemul, uint, 0);
+MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");
+module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
+MODULE_PARM_DESC(wwan_state,
+ "Initial state of the emulated WWAN switch");
+
+module_param(dbg_uwbemul, uint, 0);
+MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation");
+module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0);
+MODULE_PARM_DESC(uwb_state,
+ "Initial state of the emulated UWB switch");
+#endif
+
static void thinkpad_acpi_module_exit(void)
{
struct ibm_struct *ibm, *itmp;
@@ -6926,7 +7532,7 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
* if it is not there yet.
*/
#define IBM_BIOS_MODULE_ALIAS(__type) \
- MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW")
+ MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*")
/* Non-ancient thinkpads */
MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
@@ -6935,9 +7541,9 @@ MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
/* Ancient thinkpad BIOSes have to be identified by
* BIOS type or model number, and there are far less
* BIOS types than model numbers... */
-IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]");
-IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]");
-IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
+IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]");
+IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]");
+IBM_BIOS_MODULE_ALIAS("K[UX-Z]");
MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
MODULE_DESCRIPTION(TPACPI_DESC);
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 8a8b377712c..2f269e117b8 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -708,7 +708,7 @@ static int __init acpi_wmi_add(struct acpi_device *device)
static int __init acpi_wmi_init(void)
{
- acpi_status result;
+ int result;
INIT_LIST_HEAD(&wmi_blocks.list);
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
index 1d768928e0b..a52d4a11652 100644
--- a/drivers/power/ds2760_battery.c
+++ b/drivers/power/ds2760_battery.c
@@ -180,10 +180,13 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di)
di->empty_uAh = battery_interpolate(scale, di->temp_C / 10);
di->empty_uAh *= 1000; /* convert to µAh */
- /* From Maxim Application Note 131: remaining capacity =
- * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */
- di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) /
- (di->full_active_uAh - di->empty_uAh);
+ if (di->full_active_uAh == di->empty_uAh)
+ di->rem_capacity = 0;
+ else
+ /* From Maxim Application Note 131: remaining capacity =
+ * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */
+ di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) /
+ (di->full_active_uAh - di->empty_uAh);
if (di->rem_capacity < 0)
di->rem_capacity = 0;
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index e988ec130fc..41aec2acbb9 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -199,7 +199,8 @@ static int adapter_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
- struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
+ struct pcf50633_mbc *mbc = container_of(psy,
+ struct pcf50633_mbc, adapter);
int ret = 0;
switch (psp) {
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
index d30bb766fce..b56a704409d 100644
--- a/drivers/power/pda_power.c
+++ b/drivers/power/pda_power.c
@@ -20,7 +20,7 @@
static inline unsigned int get_irq_flags(struct resource *res)
{
- unsigned int flags = IRQF_DISABLED | IRQF_SHARED;
+ unsigned int flags = IRQF_SAMPLE_RANDOM | IRQF_SHARED;
flags |= res->flags & IRQF_TRIGGER_MASK;
diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c
index 204158cf7a5..fe96793e3f0 100644
--- a/drivers/ps3/ps3-lpm.c
+++ b/drivers/ps3/ps3-lpm.c
@@ -732,7 +732,7 @@ static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group)
case 8:
return pm_translate_signal_group_number_on_island8(subgroup);
default:
- dev_dbg(sbd_core(), "%s:%u: island not found: %lu\n", __func__,
+ dev_dbg(sbd_core(), "%s:%u: island not found: %llu\n", __func__,
__LINE__, group);
BUG();
break;
@@ -765,7 +765,7 @@ static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select,
signal_select, attr1, attr2, attr3);
if (ret)
dev_err(sbd_core(),
- "%s:%u: error:%d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
+ "%s:%u: error:%d 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n",
__func__, __LINE__, ret, lv1_signal_group, bus_select,
signal_select, attr1, attr2, attr3);
@@ -908,7 +908,7 @@ void ps3_disable_pm(u32 cpu)
lpm_priv->tb_count = tmp;
- dev_dbg(sbd_core(), "%s:%u: tb_count %lu (%lxh)\n", __func__, __LINE__,
+ dev_dbg(sbd_core(), "%s:%u: tb_count %llu (%llxh)\n", __func__, __LINE__,
lpm_priv->tb_count, lpm_priv->tb_count);
}
EXPORT_SYMBOL_GPL(ps3_disable_pm);
@@ -938,7 +938,7 @@ int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count,
if (offset >= lpm_priv->tb_count)
return 0;
- count = min(count, lpm_priv->tb_count - offset);
+ count = min_t(u64, count, lpm_priv->tb_count - offset);
while (*bytes_copied < count) {
const unsigned long request = count - *bytes_copied;
@@ -993,7 +993,7 @@ int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
if (offset >= lpm_priv->tb_count)
return 0;
- count = min(count, lpm_priv->tb_count - offset);
+ count = min_t(u64, count, lpm_priv->tb_count - offset);
while (*bytes_copied < count) {
const unsigned long request = count - *bytes_copied;
@@ -1013,7 +1013,7 @@ int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
result = copy_to_user(buf, lpm_priv->tb_cache, tmp);
if (result) {
- dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%p\n",
+ dev_dbg(sbd_core(), "%s:%u: 0x%llx bytes at 0x%p\n",
__func__, __LINE__, tmp, buf);
dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n",
__func__, __LINE__, result);
@@ -1148,8 +1148,8 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT;
lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT;
- dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, "
- "tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id,
+ dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%llx, outlet_id 0x%llx, "
+ "tb_size 0x%llx\n", __func__, __LINE__, lpm_priv->lpm_id,
lpm_priv->outlet_id, tb_size);
return 0;
diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c
index 90c097a7a47..e4ad5ba5d0a 100644
--- a/drivers/ps3/ps3-vuart.c
+++ b/drivers/ps3/ps3-vuart.c
@@ -114,7 +114,7 @@ struct ports_bmp {
static void __maybe_unused _dump_ports_bmp(
const struct ports_bmp *bmp, const char *func, int line)
{
- pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status);
+ pr_debug("%s:%d: ports_bmp: %016llxh\n", func, line, bmp->status);
}
#define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__)
@@ -159,11 +159,13 @@ int ps3_vuart_get_triggers(struct ps3_system_bus_device *dev,
struct vuart_triggers *trig)
{
int result;
- unsigned long size;
- unsigned long val;
+ u64 size;
+ u64 val;
+ u64 tx;
result = lv1_get_virtual_uart_param(dev->port_number,
- PARAM_TX_TRIGGER, &trig->tx);
+ PARAM_TX_TRIGGER, &tx);
+ trig->tx = tx;
if (result) {
dev_dbg(&dev->core, "%s:%d: tx_trigger failed: %s\n",
@@ -201,7 +203,7 @@ int ps3_vuart_set_triggers(struct ps3_system_bus_device *dev, unsigned int tx,
unsigned int rx)
{
int result;
- unsigned long size;
+ u64 size;
result = lv1_set_virtual_uart_param(dev->port_number,
PARAM_TX_TRIGGER, tx);
@@ -248,7 +250,7 @@ static int ps3_vuart_get_rx_bytes_waiting(struct ps3_system_bus_device *dev,
dev_dbg(&dev->core, "%s:%d: rx_bytes failed: %s\n",
__func__, __LINE__, ps3_result(result));
- dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__,
+ dev_dbg(&dev->core, "%s:%d: %llxh\n", __func__, __LINE__,
*bytes_waiting);
return result;
}
@@ -295,7 +297,7 @@ static int ps3_vuart_get_interrupt_status(struct ps3_system_bus_device *dev,
*status = tmp & priv->interrupt_mask;
- dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
+ dev_dbg(&dev->core, "%s:%d: m %llxh, s %llxh, m&s %lxh\n",
__func__, __LINE__, priv->interrupt_mask, tmp, *status);
return result;
@@ -363,7 +365,7 @@ int ps3_vuart_disable_interrupt_disconnect(struct ps3_system_bus_device *dev)
*/
static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev,
- const void *buf, unsigned int bytes, unsigned long *bytes_written)
+ const void *buf, unsigned int bytes, u64 *bytes_written)
{
int result;
struct ps3_vuart_port_priv *priv = to_port_priv(dev);
@@ -379,7 +381,7 @@ static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev,
priv->stats.bytes_written += *bytes_written;
- dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__,
+ dev_dbg(&dev->core, "%s:%d: wrote %llxh/%xh=>%lxh\n", __func__, __LINE__,
*bytes_written, bytes, priv->stats.bytes_written);
return result;
@@ -393,7 +395,7 @@ static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev,
*/
static int ps3_vuart_raw_read(struct ps3_system_bus_device *dev, void *buf,
- unsigned int bytes, unsigned long *bytes_read)
+ unsigned int bytes, u64 *bytes_read)
{
int result;
struct ps3_vuart_port_priv *priv = to_port_priv(dev);
@@ -411,7 +413,7 @@ static int ps3_vuart_raw_read(struct ps3_system_bus_device *dev, void *buf,
priv->stats.bytes_read += *bytes_read;
- dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
+ dev_dbg(&dev->core, "%s:%d: read %llxh/%xh=>%lxh\n", __func__, __LINE__,
*bytes_read, bytes, priv->stats.bytes_read);
return result;
@@ -500,7 +502,7 @@ int ps3_vuart_write(struct ps3_system_bus_device *dev, const void *buf,
spin_lock_irqsave(&priv->tx_list.lock, flags);
if (list_empty(&priv->tx_list.head)) {
- unsigned long bytes_written;
+ u64 bytes_written;
result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);
@@ -592,7 +594,7 @@ static int ps3_vuart_queue_rx_bytes(struct ps3_system_bus_device *dev,
list_add_tail(&lb->link, &priv->rx_list.head);
priv->rx_list.bytes_held += bytes;
- dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
+ dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %llxh bytes\n",
__func__, __LINE__, lb->dbg_number, bytes);
*bytes_queued = bytes;
@@ -745,7 +747,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_system_bus_device *dev)
list_for_each_entry_safe(lb, n, &priv->tx_list.head, link) {
- unsigned long bytes_written;
+ u64 bytes_written;
result = ps3_vuart_raw_write(dev, lb->head, lb->tail - lb->head,
&bytes_written);
@@ -762,7 +764,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_system_bus_device *dev)
if (bytes_written < lb->tail - lb->head) {
lb->head += bytes_written;
dev_dbg(&dev->core,
- "%s:%d cleared buf_%lu, %lxh bytes\n",
+ "%s:%d cleared buf_%lu, %llxh bytes\n",
__func__, __LINE__, lb->dbg_number,
bytes_written);
goto port_full;
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
index 55955f16ad9..18066d55539 100644
--- a/drivers/ps3/ps3stor_lib.c
+++ b/drivers/ps3/ps3stor_lib.c
@@ -70,7 +70,7 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev)
__func__, __LINE__, n);
dev->region_idx = __ffs(dev->accessible_regions);
dev_info(&dev->sbd.core,
- "First accessible region has index %u start %lu size %lu\n",
+ "First accessible region has index %u start %llu size %llu\n",
dev->region_idx, dev->regions[dev->region_idx].start,
dev->regions[dev->region_idx].size);
@@ -220,7 +220,7 @@ u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar,
const char *op = write ? "write" : "read";
int res;
- dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n",
+ dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
__func__, __LINE__, op, sectors, start_sector);
init_completion(&dev->done);
@@ -238,7 +238,7 @@ u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar,
wait_for_completion(&dev->done);
if (dev->lv1_status) {
- dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
+ dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
__LINE__, op, dev->lv1_status);
return dev->lv1_status;
}
@@ -268,7 +268,7 @@ u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, u64 arg1,
{
int res;
- dev_dbg(&dev->sbd.core, "%s:%u: send device command 0x%lx\n", __func__,
+ dev_dbg(&dev->sbd.core, "%s:%u: send device command 0x%llx\n", __func__,
__LINE__, cmd);
init_completion(&dev->done);
@@ -277,19 +277,19 @@ u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, u64 arg1,
arg2, arg3, arg4, &dev->tag);
if (res) {
dev_err(&dev->sbd.core,
- "%s:%u: send_device_command 0x%lx failed %d\n",
+ "%s:%u: send_device_command 0x%llx failed %d\n",
__func__, __LINE__, cmd, res);
return -1;
}
wait_for_completion(&dev->done);
if (dev->lv1_status) {
- dev_dbg(&dev->sbd.core, "%s:%u: command 0x%lx failed 0x%lx\n",
+ dev_dbg(&dev->sbd.core, "%s:%u: command 0x%llx failed 0x%llx\n",
__func__, __LINE__, cmd, dev->lv1_status);
return dev->lv1_status;
}
- dev_dbg(&dev->sbd.core, "%s:%u: command 0x%lx completed\n", __func__,
+ dev_dbg(&dev->sbd.core, "%s:%u: command 0x%llx completed\n", __func__,
__LINE__, cmd);
return 0;
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index addb87cf44d..3222fa3c808 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -193,7 +193,7 @@ static int rio_match_bus(struct device *dev, struct device_driver *drv)
}
static struct device rio_bus = {
- .bus_id = "rapidio",
+ .init_name = "rapidio",
};
struct bus_type rio_bus_type = {
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index 366565aba86..c175e38a4cd 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -152,11 +152,7 @@ static void __exit bq24022_exit(void)
platform_driver_unregister(&bq24022_driver);
}
-/*
- * make sure this is probed before gpio_vbus and pda_power,
- * but after asic3 or other GPIO expander drivers.
- */
-subsys_initcall(bq24022_init);
+module_init(bq24022_init);
module_exit(bq24022_exit);
MODULE_AUTHOR("Philipp Zabel");
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 7aa35248181..5056e23e441 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1435,7 +1435,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
struct platform_device *pdev;
int ret;
- if (lednum > ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
+ if (lednum >= ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
dev_err(wm8350->dev, "Invalid LED index %d\n", lednum);
return -ENODEV;
}
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 48b372e038a..56e23d44ba5 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -289,7 +289,7 @@ static struct regulator_desc regulators[] = {
},
};
-static int __init wm8400_regulator_probe(struct platform_device *pdev)
+static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
{
struct regulator_dev *rdev;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index cced4d10831..81450fbd8b1 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -241,6 +241,12 @@ config RTC_DRV_M41T80_WDT
If you say Y here you will get support for the
watchdog timer in the ST M41T60 and M41T80 RTC chips series.
+config RTC_DRV_DM355EVM
+ tristate "TI DaVinci DM355 EVM RTC"
+ depends on MFD_DM355EVM_MSP
+ help
+ Supports the RTC firmware in the MSP430 on the DM355 EVM.
+
config RTC_DRV_TWL92330
boolean "TI TWL92330/Menelaus"
depends on MENELAUS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6e28021abb9..0e697aa51ca 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o
obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
+obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o
obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index d5e4e637dde..86c61f14351 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -351,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
/* register irq handler after we know what name we'll use */
ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
IRQF_DISABLED | IRQF_SHARED,
- rtc->rtcdev->dev.bus_id, rtc);
+ dev_name(&rtc->rtcdev->dev), rtc);
if (ret) {
dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
rtc_device_unregister(rtc->rtcdev);
@@ -366,7 +366,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
if (gpbr_readl(rtc) == 0)
dev_warn(&pdev->dev, "%s: SET TIME!\n",
- rtc->rtcdev->dev.bus_id);
+ dev_name(&rtc->rtcdev->dev));
return 0;
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c
index 8906a688e6a..979ed0406ce 100644
--- a/drivers/rtc/rtc-au1xxx.c
+++ b/drivers/rtc/rtc-au1xxx.c
@@ -81,7 +81,7 @@ static int __devinit au1xtoy_rtc_probe(struct platform_device *pdev)
if (au_readl(SYS_TOYTRIM) != 32767) {
/* wait until hardware gives access to TRIM register */
t = 0x00100000;
- while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && t--)
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && --t)
msleep(1);
if (!t) {
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c
new file mode 100644
index 00000000000..58d4e18530d
--- /dev/null
+++ b/drivers/rtc/rtc-dm355evm.c
@@ -0,0 +1,175 @@
+/*
+ * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware
+ *
+ * Copyright (c) 2008 by David Brownell
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c/dm355evm_msp.h>
+
+
+/*
+ * The MSP430 firmware on the DM355 EVM uses a watch crystal to feed
+ * a 1 Hz counter. When a backup battery is supplied, that makes a
+ * reasonable RTC for applications where alarms and non-NTP drift
+ * compensation aren't important.
+ *
+ * The only real glitch is the inability to read or write all four
+ * counter bytes atomically: the count may increment in the middle
+ * of an operation, causing trouble when the LSB rolls over.
+ *
+ * This driver was tested with firmware revision A4.
+ */
+union evm_time {
+ u8 bytes[4];
+ u32 value;
+};
+
+static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ union evm_time time;
+ int status;
+ int tries = 0;
+
+ do {
+ /*
+ * Read LSB(0) to MSB(3) bytes. Defend against the counter
+ * rolling over by re-reading until the value is stable,
+ * and assuming the four reads take at most a few seconds.
+ */
+ status = dm355evm_msp_read(DM355EVM_MSP_RTC_0);
+ if (status < 0)
+ return status;
+ if (tries && time.bytes[0] == status)
+ break;
+ time.bytes[0] = status;
+
+ status = dm355evm_msp_read(DM355EVM_MSP_RTC_1);
+ if (status < 0)
+ return status;
+ if (tries && time.bytes[1] == status)
+ break;
+ time.bytes[1] = status;
+
+ status = dm355evm_msp_read(DM355EVM_MSP_RTC_2);
+ if (status < 0)
+ return status;
+ if (tries && time.bytes[2] == status)
+ break;
+ time.bytes[2] = status;
+
+ status = dm355evm_msp_read(DM355EVM_MSP_RTC_3);
+ if (status < 0)
+ return status;
+ if (tries && time.bytes[3] == status)
+ break;
+ time.bytes[3] = status;
+
+ } while (++tries < 5);
+
+ dev_dbg(dev, "read timestamp %08x\n", time.value);
+
+ rtc_time_to_tm(le32_to_cpu(time.value), tm);
+ return 0;
+}
+
+static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ union evm_time time;
+ unsigned long value;
+ int status;
+
+ rtc_tm_to_time(tm, &value);
+ time.value = cpu_to_le32(value);
+
+ dev_dbg(dev, "write timestamp %08x\n", time.value);
+
+ /*
+ * REVISIT handle non-atomic writes ... maybe just retry until
+ * byte[1] sticks (no rollover)?
+ */
+ status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0);
+ if (status < 0)
+ return status;
+
+ status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1);
+ if (status < 0)
+ return status;
+
+ status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2);
+ if (status < 0)
+ return status;
+
+ status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3);
+ if (status < 0)
+ return status;
+
+ return 0;
+}
+
+static struct rtc_class_ops dm355evm_rtc_ops = {
+ .read_time = dm355evm_rtc_read_time,
+ .set_time = dm355evm_rtc_set_time,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit dm355evm_rtc_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register(pdev->name,
+ &pdev->dev, &dm355evm_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+ PTR_ERR(rtc));
+ return PTR_ERR(rtc);
+ }
+ platform_set_drvdata(pdev, rtc);
+
+ return 0;
+}
+
+static int __devexit dm355evm_rtc_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+ rtc_device_unregister(rtc);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+/*
+ * I2C is used to talk to the MSP430, but this platform device is
+ * exposed by an MFD driver that manages I2C communications.
+ */
+static struct platform_driver rtc_dm355evm_driver = {
+ .probe = dm355evm_rtc_probe,
+ .remove = __devexit_p(dm355evm_rtc_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "rtc-dm355evm",
+ },
+};
+
+static int __init dm355evm_rtc_init(void)
+{
+ return platform_driver_register(&rtc_dm355evm_driver);
+}
+module_init(dm355evm_rtc_init);
+
+static void __exit dm355evm_rtc_exit(void)
+{
+ platform_driver_unregister(&rtc_dm355evm_driver);
+}
+module_exit(dm355evm_rtc_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c
index e54b5c619bd..e01b955db07 100644
--- a/drivers/rtc/rtc-ds1390.c
+++ b/drivers/rtc/rtc-ds1390.c
@@ -122,7 +122,6 @@ static const struct rtc_class_ops ds1390_rtc_ops = {
static int __devinit ds1390_probe(struct spi_device *spi)
{
- struct rtc_device *rtc;
unsigned char tmp;
struct ds1390 *chip;
int res;
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 2cbeb0794f1..bd1ce8e2bc1 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -377,13 +377,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
/* handle periodic and alarm irqs */
if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
- rtc->dev.bus_id, rtc)) {
+ dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_timer);
goto fail0;
}
if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
- rtc->dev.bus_id, rtc)) {
+ dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_alarm);
goto fail1;
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c
index bd56a033bfd..bb8cc05605a 100644
--- a/drivers/rtc/rtc-pxa.c
+++ b/drivers/rtc/rtc-pxa.c
@@ -485,7 +485,7 @@ static void __exit pxa_rtc_exit(void)
module_init(pxa_rtc_init);
module_exit(pxa_rtc_exit);
-MODULE_AUTHOR("Robert Jarzmik");
+MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
MODULE_DESCRIPTION("PXA27x/PXA3xx Realtime Clock Driver (RTC)");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pxa-rtc");
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 1c3fc6b428e..4898f7fe851 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -28,7 +28,7 @@
#include <asm/rtc.h>
#define DRV_NAME "sh-rtc"
-#define DRV_VERSION "0.2.0"
+#define DRV_VERSION "0.2.1"
#define RTC_REG(r) ((r) * rtc_reg_size)
@@ -99,56 +99,51 @@ struct sh_rtc {
unsigned short periodic_freq;
};
-static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
+static int __sh_rtc_interrupt(struct sh_rtc *rtc)
{
- struct sh_rtc *rtc = dev_id;
- unsigned int tmp;
-
- spin_lock(&rtc->lock);
+ unsigned int tmp, pending;
tmp = readb(rtc->regbase + RCR1);
+ pending = tmp & RCR1_CF;
tmp &= ~RCR1_CF;
writeb(tmp, rtc->regbase + RCR1);
/* Users have requested One x Second IRQ */
- if (rtc->periodic_freq & PF_OXS)
+ if (pending && rtc->periodic_freq & PF_OXS)
rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
- spin_unlock(&rtc->lock);
-
- return IRQ_HANDLED;
+ return pending;
}
-static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
+static int __sh_rtc_alarm(struct sh_rtc *rtc)
{
- struct sh_rtc *rtc = dev_id;
- unsigned int tmp;
-
- spin_lock(&rtc->lock);
+ unsigned int tmp, pending;
tmp = readb(rtc->regbase + RCR1);
+ pending = tmp & RCR1_AF;
tmp &= ~(RCR1_AF | RCR1_AIE);
- writeb(tmp, rtc->regbase + RCR1);
-
- rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
+ writeb(tmp, rtc->regbase + RCR1);
- spin_unlock(&rtc->lock);
+ if (pending)
+ rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
- return IRQ_HANDLED;
+ return pending;
}
-static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
+static int __sh_rtc_periodic(struct sh_rtc *rtc)
{
- struct sh_rtc *rtc = dev_id;
struct rtc_device *rtc_dev = rtc->rtc_dev;
- unsigned int tmp;
-
- spin_lock(&rtc->lock);
+ struct rtc_task *irq_task;
+ unsigned int tmp, pending;
tmp = readb(rtc->regbase + RCR2);
+ pending = tmp & RCR2_PEF;
tmp &= ~RCR2_PEF;
writeb(tmp, rtc->regbase + RCR2);
+ if (!pending)
+ return 0;
+
/* Half period enabled than one skipped and the next notified */
if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT))
rtc->periodic_freq &= ~PF_COUNT;
@@ -157,16 +152,65 @@ static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
rtc->periodic_freq |= PF_COUNT;
if (rtc->periodic_freq & PF_KOU) {
spin_lock(&rtc_dev->irq_task_lock);
- if (rtc_dev->irq_task)
- rtc_dev->irq_task->func(rtc_dev->irq_task->private_data);
+ irq_task = rtc_dev->irq_task;
+ if (irq_task)
+ irq_task->func(irq_task->private_data);
spin_unlock(&rtc_dev->irq_task_lock);
} else
rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
}
+ return pending;
+}
+
+static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
+{
+ struct sh_rtc *rtc = dev_id;
+ int ret;
+
+ spin_lock(&rtc->lock);
+ ret = __sh_rtc_interrupt(rtc);
+ spin_unlock(&rtc->lock);
+
+ return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
+{
+ struct sh_rtc *rtc = dev_id;
+ int ret;
+
+ spin_lock(&rtc->lock);
+ ret = __sh_rtc_alarm(rtc);
+ spin_unlock(&rtc->lock);
+
+ return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
+{
+ struct sh_rtc *rtc = dev_id;
+ int ret;
+
+ spin_lock(&rtc->lock);
+ ret = __sh_rtc_periodic(rtc);
spin_unlock(&rtc->lock);
- return IRQ_HANDLED;
+ return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_shared(int irq, void *dev_id)
+{
+ struct sh_rtc *rtc = dev_id;
+ int ret;
+
+ spin_lock(&rtc->lock);
+ ret = __sh_rtc_interrupt(rtc);
+ ret |= __sh_rtc_alarm(rtc);
+ ret |= __sh_rtc_periodic(rtc);
+ spin_unlock(&rtc->lock);
+
+ return IRQ_RETVAL(ret);
}
static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
@@ -275,6 +319,25 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
+static inline void sh_rtc_setcie(struct device *dev, unsigned int enable)
+{
+ struct sh_rtc *rtc = dev_get_drvdata(dev);
+ unsigned int tmp;
+
+ spin_lock_irq(&rtc->lock);
+
+ tmp = readb(rtc->regbase + RCR1);
+
+ if (!enable)
+ tmp &= ~RCR1_CIE;
+ else
+ tmp |= RCR1_CIE;
+
+ writeb(tmp, rtc->regbase + RCR1);
+
+ spin_unlock_irq(&rtc->lock);
+}
+
static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct sh_rtc *rtc = dev_get_drvdata(dev);
@@ -291,9 +354,11 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
break;
case RTC_UIE_OFF:
rtc->periodic_freq &= ~PF_OXS;
+ sh_rtc_setcie(dev, 0);
break;
case RTC_UIE_ON:
rtc->periodic_freq |= PF_OXS;
+ sh_rtc_setcie(dev, 1);
break;
case RTC_IRQP_READ:
ret = put_user(rtc->rtc_dev->irq_freq,
@@ -356,18 +421,17 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_sec--;
#endif
+ /* only keep the carry interrupt enabled if UIE is on */
+ if (!(rtc->periodic_freq & PF_OXS))
+ sh_rtc_setcie(dev, 0);
+
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
- if (rtc_valid_tm(tm) < 0) {
- dev_err(dev, "invalid date\n");
- rtc_time_to_tm(0, tm);
- }
-
- return 0;
+ return rtc_valid_tm(tm);
}
static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -572,7 +636,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
{
struct sh_rtc *rtc;
struct resource *res;
- unsigned int tmp;
+ struct rtc_time r;
int ret;
rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
@@ -585,26 +649,12 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
ret = platform_get_irq(pdev, 0);
if (unlikely(ret <= 0)) {
ret = -ENOENT;
- dev_err(&pdev->dev, "No IRQ for period\n");
+ dev_err(&pdev->dev, "No IRQ resource\n");
goto err_badres;
}
rtc->periodic_irq = ret;
-
- ret = platform_get_irq(pdev, 1);
- if (unlikely(ret <= 0)) {
- ret = -ENOENT;
- dev_err(&pdev->dev, "No IRQ for carry\n");
- goto err_badres;
- }
- rtc->carry_irq = ret;
-
- ret = platform_get_irq(pdev, 2);
- if (unlikely(ret <= 0)) {
- ret = -ENOENT;
- dev_err(&pdev->dev, "No IRQ for alarm\n");
- goto err_badres;
- }
- rtc->alarm_irq = ret;
+ rtc->carry_irq = platform_get_irq(pdev, 1);
+ rtc->alarm_irq = platform_get_irq(pdev, 2);
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (unlikely(res == NULL)) {
@@ -646,47 +696,66 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
}
rtc->rtc_dev->max_user_freq = 256;
- rtc->rtc_dev->irq_freq = 1;
- rtc->periodic_freq = 0x60;
platform_set_drvdata(pdev, rtc);
- /* register periodic/carry/alarm irqs */
- ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED,
- "sh-rtc period", rtc);
- if (unlikely(ret)) {
- dev_err(&pdev->dev,
- "request period IRQ failed with %d, IRQ %d\n", ret,
- rtc->periodic_irq);
- goto err_unmap;
- }
+ if (rtc->carry_irq <= 0) {
+ /* register shared periodic/carry/alarm irq */
+ ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
+ IRQF_DISABLED, "sh-rtc", rtc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev,
+ "request IRQ failed with %d, IRQ %d\n", ret,
+ rtc->periodic_irq);
+ goto err_unmap;
+ }
+ } else {
+ /* register periodic/carry/alarm irqs */
+ ret = request_irq(rtc->periodic_irq, sh_rtc_periodic,
+ IRQF_DISABLED, "sh-rtc period", rtc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev,
+ "request period IRQ failed with %d, IRQ %d\n",
+ ret, rtc->periodic_irq);
+ goto err_unmap;
+ }
- ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
- "sh-rtc carry", rtc);
- if (unlikely(ret)) {
- dev_err(&pdev->dev,
- "request carry IRQ failed with %d, IRQ %d\n", ret,
- rtc->carry_irq);
- free_irq(rtc->periodic_irq, rtc);
- goto err_unmap;
- }
+ ret = request_irq(rtc->carry_irq, sh_rtc_interrupt,
+ IRQF_DISABLED, "sh-rtc carry", rtc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev,
+ "request carry IRQ failed with %d, IRQ %d\n",
+ ret, rtc->carry_irq);
+ free_irq(rtc->periodic_irq, rtc);
+ goto err_unmap;
+ }
- ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED,
- "sh-rtc alarm", rtc);
- if (unlikely(ret)) {
- dev_err(&pdev->dev,
- "request alarm IRQ failed with %d, IRQ %d\n", ret,
- rtc->alarm_irq);
- free_irq(rtc->carry_irq, rtc);
- free_irq(rtc->periodic_irq, rtc);
- goto err_unmap;
+ ret = request_irq(rtc->alarm_irq, sh_rtc_alarm,
+ IRQF_DISABLED, "sh-rtc alarm", rtc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev,
+ "request alarm IRQ failed with %d, IRQ %d\n",
+ ret, rtc->alarm_irq);
+ free_irq(rtc->carry_irq, rtc);
+ free_irq(rtc->periodic_irq, rtc);
+ goto err_unmap;
+ }
}
- tmp = readb(rtc->regbase + RCR1);
- tmp &= ~RCR1_CF;
- tmp |= RCR1_CIE;
- writeb(tmp, rtc->regbase + RCR1);
+ /* everything disabled by default */
+ rtc->periodic_freq = 0;
+ rtc->rtc_dev->irq_freq = 0;
+ sh_rtc_setpie(&pdev->dev, 0);
+ sh_rtc_setaie(&pdev->dev, 0);
+ sh_rtc_setcie(&pdev->dev, 0);
+
+ /* reset rtc to epoch 0 if time is invalid */
+ if (rtc_read_time(rtc->rtc_dev, &r) < 0) {
+ rtc_time_to_tm(0, &r);
+ rtc_set_time(rtc->rtc_dev, &r);
+ }
+ device_init_wakeup(&pdev->dev, 1);
return 0;
err_unmap:
@@ -708,10 +777,13 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
sh_rtc_setpie(&pdev->dev, 0);
sh_rtc_setaie(&pdev->dev, 0);
+ sh_rtc_setcie(&pdev->dev, 0);
- free_irq(rtc->carry_irq, rtc);
free_irq(rtc->periodic_irq, rtc);
- free_irq(rtc->alarm_irq, rtc);
+ if (rtc->carry_irq > 0) {
+ free_irq(rtc->carry_irq, rtc);
+ free_irq(rtc->alarm_irq, rtc);
+ }
release_resource(rtc->res);
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c
index ad35f76c46b..a6341e4f9a0 100644
--- a/drivers/rtc/rtc-twl4030.c
+++ b/drivers/rtc/rtc-twl4030.c
@@ -426,7 +426,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
ret = request_irq(irq, twl4030_rtc_interrupt,
IRQF_TRIGGER_RISING,
- rtc->dev.bus_id, rtc);
+ dev_name(&rtc->dev), rtc);
if (ret < 0) {
dev_err(&pdev->dev, "IRQ is not free.\n");
goto out1;
diff --git a/drivers/s390/Makefile b/drivers/s390/Makefile
index d0eae59bc36..95bccfd3f16 100644
--- a/drivers/s390/Makefile
+++ b/drivers/s390/Makefile
@@ -2,9 +2,6 @@
# Makefile for the S/390 specific device drivers
#
-CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
-
-obj-y += s390mach.o sysinfo.o
obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/
drivers-y += drivers/s390/built-in.o
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index bd591499414..2fd64e5a9ab 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -9,6 +9,9 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -22,6 +25,7 @@
#include <asm/ebcdic.h>
#include <asm/idals.h>
#include <asm/todclk.h>
+#include <asm/itcw.h>
/* This is ugly... */
#define PRINTK_HEADER "dasd:"
@@ -57,6 +61,8 @@ static void dasd_device_tasklet(struct dasd_device *);
static void dasd_block_tasklet(struct dasd_block *);
static void do_kick_device(struct work_struct *);
static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
+static void dasd_device_timeout(unsigned long);
+static void dasd_block_timeout(unsigned long);
/*
* SECTION: Operations on the device structure.
@@ -99,6 +105,8 @@ struct dasd_device *dasd_alloc_device(void)
(unsigned long) device);
INIT_LIST_HEAD(&device->ccw_queue);
init_timer(&device->timer);
+ device->timer.function = dasd_device_timeout;
+ device->timer.data = (unsigned long) device;
INIT_WORK(&device->kick_work, do_kick_device);
device->state = DASD_STATE_NEW;
device->target = DASD_STATE_NEW;
@@ -138,6 +146,8 @@ struct dasd_block *dasd_alloc_block(void)
INIT_LIST_HEAD(&block->ccw_queue);
spin_lock_init(&block->queue_lock);
init_timer(&block->timer);
+ block->timer.function = dasd_block_timeout;
+ block->timer.data = (unsigned long) block;
return block;
}
@@ -215,7 +225,7 @@ static int dasd_state_known_to_basic(struct dasd_device *device)
return rc;
}
/* register 'device' debug area, used for all DBF_DEV_XXX calls */
- device->debug_area = debug_register(dev_name(&device->cdev->dev), 1, 1,
+ device->debug_area = debug_register(dev_name(&device->cdev->dev), 4, 1,
8 * sizeof(long));
debug_register_view(device->debug_area, &debug_sprintf_view);
debug_set_level(device->debug_area, DBF_WARNING);
@@ -756,7 +766,7 @@ static inline int dasd_check_cqr(struct dasd_ccw_req *cqr)
return -EINVAL;
device = cqr->startdev;
if (strncmp((char *) &cqr->magic, device->discipline->ebcname, 4)) {
- DEV_MESSAGE(KERN_WARNING, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
" dasd_ccw_req 0x%08x magic doesn't match"
" discipline 0x%08x",
cqr->magic,
@@ -776,6 +786,7 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
{
struct dasd_device *device;
int retries, rc;
+ char errorstring[ERRORLENGTH];
/* Check the cqr */
rc = dasd_check_cqr(cqr);
@@ -809,10 +820,10 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
"device busy, retry later");
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "line %d unknown RC=%d, please "
- "report to linux390@de.ibm.com",
- __LINE__, rc);
+ /* internal error 10 - unknown rc*/
+ snprintf(errorstring, ERRORLENGTH, "10 %d", rc);
+ dev_err(&device->cdev->dev, "An error occurred in the "
+ "DASD device driver, reason=%s\n", errorstring);
BUG();
break;
}
@@ -830,6 +841,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
{
struct dasd_device *device;
int rc;
+ char errorstring[ERRORLENGTH];
/* Check the cqr */
rc = dasd_check_cqr(cqr);
@@ -837,17 +849,23 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
return rc;
device = (struct dasd_device *) cqr->startdev;
if (cqr->retries < 0) {
- DEV_MESSAGE(KERN_DEBUG, device,
- "start_IO: request %p (%02x/%i) - no retry left.",
- cqr, cqr->status, cqr->retries);
+ /* internal error 14 - start_IO run out of retries */
+ sprintf(errorstring, "14 %p", cqr);
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", errorstring);
cqr->status = DASD_CQR_ERROR;
return -EIO;
}
cqr->startclk = get_clock();
cqr->starttime = jiffies;
cqr->retries--;
- rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr,
- cqr->lpm, 0);
+ if (cqr->cpmode == 1) {
+ rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
+ (long) cqr, cqr->lpm);
+ } else {
+ rc = ccw_device_start(device->cdev, cqr->cpaddr,
+ (long) cqr, cqr->lpm, 0);
+ }
switch (rc) {
case 0:
cqr->status = DASD_CQR_IN_IO;
@@ -856,11 +874,11 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr);
break;
case -EBUSY:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: device busy, retry later");
break;
case -ETIMEDOUT:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: request timeout, retry later");
break;
case -EACCES:
@@ -870,19 +888,24 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
* Do a retry with all available pathes.
*/
cqr->lpm = LPM_ANYPATH;
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: selected pathes gone,"
" retry on all pathes");
break;
case -ENODEV:
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ "start_IO: -ENODEV device gone, retry");
+ break;
case -EIO:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
- "start_IO: device gone, retry");
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ "start_IO: -EIO device gone, retry");
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "line %d unknown RC=%d, please report"
- " to linux390@de.ibm.com", __LINE__, rc);
+ /* internal error 11 - unknown rc */
+ snprintf(errorstring, ERRORLENGTH, "11 %d", rc);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
BUG();
break;
}
@@ -915,19 +938,10 @@ static void dasd_device_timeout(unsigned long ptr)
*/
void dasd_device_set_timer(struct dasd_device *device, int expires)
{
- if (expires == 0) {
- if (timer_pending(&device->timer))
- del_timer(&device->timer);
- return;
- }
- if (timer_pending(&device->timer)) {
- if (mod_timer(&device->timer, jiffies + expires))
- return;
- }
- device->timer.function = dasd_device_timeout;
- device->timer.data = (unsigned long) device;
- device->timer.expires = jiffies + expires;
- add_timer(&device->timer);
+ if (expires == 0)
+ del_timer(&device->timer);
+ else
+ mod_timer(&device->timer, jiffies + expires);
}
/*
@@ -935,8 +949,7 @@ void dasd_device_set_timer(struct dasd_device *device, int expires)
*/
void dasd_device_clear_timer(struct dasd_device *device)
{
- if (timer_pending(&device->timer))
- del_timer(&device->timer);
+ del_timer(&device->timer);
}
static void dasd_handle_killed_request(struct ccw_device *cdev,
@@ -949,7 +962,7 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
return;
cqr = (struct dasd_ccw_req *) intparm;
if (cqr->status != DASD_CQR_IN_IO) {
- MESSAGE(KERN_DEBUG,
+ DBF_EVENT(DBF_DEBUG,
"invalid status in handle_killed_request: "
"bus_id %s, status %02x",
dev_name(&cdev->dev), cqr->status);
@@ -960,8 +973,8 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
if (device == NULL ||
device != dasd_device_from_cdev_locked(cdev) ||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
- dev_name(&cdev->dev));
+ DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
+ "bus_id %s", dev_name(&cdev->dev));
return;
}
@@ -1000,11 +1013,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
case -EIO:
break;
case -ETIMEDOUT:
- printk(KERN_WARNING"%s(%s): request timed out\n",
+ DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n",
__func__, dev_name(&cdev->dev));
break;
default:
- printk(KERN_WARNING"%s(%s): unknown error %ld\n",
+ DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n",
__func__, dev_name(&cdev->dev), PTR_ERR(irb));
}
dasd_handle_killed_request(cdev, intparm);
@@ -1013,15 +1026,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
now = get_clock();
- DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
- dev_name(&cdev->dev), ((irb->scsw.cmd.cstat << 8) |
- irb->scsw.cmd.dstat), (unsigned int) intparm);
-
/* check for unsolicited interrupts */
cqr = (struct dasd_ccw_req *) intparm;
- if (!cqr || ((irb->scsw.cmd.cc == 1) &&
- (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
- (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) {
+ if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
+ (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+ (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) {
if (cqr && cqr->status == DASD_CQR_IN_IO)
cqr->status = DASD_CQR_QUEUED;
device = dasd_device_from_cdev_locked(cdev);
@@ -1037,14 +1046,14 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
device = (struct dasd_device *) cqr->startdev;
if (!device ||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
- dev_name(&cdev->dev));
+ DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
+ "bus_id %s", dev_name(&cdev->dev));
return;
}
/* Check for clear pending */
if (cqr->status == DASD_CQR_CLEAR_PENDING &&
- irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
+ scsw_fctl(&irb->scsw) & SCSW_FCTL_CLEAR_FUNC) {
cqr->status = DASD_CQR_CLEARED;
dasd_device_clear_timer(device);
wake_up(&dasd_flush_wq);
@@ -1052,19 +1061,17 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
return;
}
- /* check status - the request might have been killed by dyn detach */
+ /* check status - the request might have been killed by dyn detach */
if (cqr->status != DASD_CQR_IN_IO) {
- MESSAGE(KERN_DEBUG,
- "invalid status: bus_id %s, status %02x",
- dev_name(&cdev->dev), cqr->status);
+ DBF_DEV_EVENT(DBF_DEBUG, device, "invalid status: bus_id %s, "
+ "status %02x", dev_name(&cdev->dev), cqr->status);
return;
}
- DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
- ((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr);
+
next = NULL;
expires = 0;
- if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
- irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) {
+ if (scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
+ scsw_cstat(&irb->scsw) == 0) {
/* request was completed successfully */
cqr->status = DASD_CQR_SUCCESS;
cqr->stopclk = now;
@@ -1075,18 +1082,23 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
}
} else { /* error */
memcpy(&cqr->irb, irb, sizeof(struct irb));
+ /* log sense for every failed I/O to s390 debugfeature */
+ dasd_log_sense_dbf(cqr, irb);
if (device->features & DASD_FEATURE_ERPLOG) {
dasd_log_sense(cqr, irb);
}
+
/*
* If we don't want complex ERP for this request, then just
* reset this and retry it in the fastpath
*/
if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
cqr->retries > 0) {
- DEV_MESSAGE(KERN_DEBUG, device,
- "default ERP in fastpath (%i retries left)",
- cqr->retries);
+ if (cqr->lpm == LPM_ANYPATH)
+ DBF_DEV_EVENT(DBF_DEBUG, device,
+ "default ERP in fastpath "
+ "(%i retries left)",
+ cqr->retries);
cqr->lpm = LPM_ANYPATH;
cqr->status = DASD_CQR_QUEUED;
next = cqr;
@@ -1097,10 +1109,6 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
(!device->stopped)) {
if (device->discipline->start_IO(next) == 0)
expires = next->expires;
- else
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Interrupt fastpath "
- "failed!");
}
if (expires != 0)
dasd_device_set_timer(device, expires);
@@ -1173,6 +1181,7 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
struct dasd_block *block;
void (*callback)(struct dasd_ccw_req *, void *data);
void *callback_data;
+ char errorstring[ERRORLENGTH];
list_for_each_safe(l, n, final_queue) {
cqr = list_entry(l, struct dasd_ccw_req, devlist);
@@ -1193,10 +1202,11 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
cqr->status = DASD_CQR_TERMINATED;
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "wrong cqr status in __dasd_process_final_queue "
- "for cqr %p, status %x",
- cqr, cqr->status);
+ /* internal error 12 - wrong cqr status*/
+ snprintf(errorstring, ERRORLENGTH, "12 %p %x02", cqr, cqr->status);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
BUG();
}
if (cqr->callback != NULL)
@@ -1221,18 +1231,17 @@ static void __dasd_device_check_expire(struct dasd_device *device)
(time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
if (device->discipline->term_IO(cqr) != 0) {
/* Hmpf, try again in 5 sec */
- DEV_MESSAGE(KERN_ERR, device,
- "internal error - timeout (%is) expired "
- "for cqr %p, termination failed, "
- "retrying in 5s",
- (cqr->expires/HZ), cqr);
+ dev_err(&device->cdev->dev,
+ "cqr %p timed out (%is) but cannot be "
+ "ended, retrying in 5 s\n",
+ cqr, (cqr->expires/HZ));
cqr->expires += 5*HZ;
dasd_device_set_timer(device, 5*HZ);
} else {
- DEV_MESSAGE(KERN_ERR, device,
- "internal error - timeout (%is) expired "
- "for cqr %p (%i retries left)",
- (cqr->expires/HZ), cqr, cqr->retries);
+ dev_err(&device->cdev->dev,
+ "cqr %p timed out (%is), %i retries "
+ "remaining\n", cqr, (cqr->expires/HZ),
+ cqr->retries);
}
}
}
@@ -1294,10 +1303,9 @@ int dasd_flush_device_queue(struct dasd_device *device)
rc = device->discipline->term_IO(cqr);
if (rc) {
/* unable to terminate requeust */
- DEV_MESSAGE(KERN_ERR, device,
- "dasd flush ccw_queue is unable "
- " to terminate request %p",
- cqr);
+ dev_err(&device->cdev->dev,
+ "Flushing the DASD request queue "
+ "failed for request %p\n", cqr);
/* stop flush processing */
goto finished;
}
@@ -1541,10 +1549,9 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
/* request in IO - terminate IO and release again */
rc = device->discipline->term_IO(cqr);
if (rc) {
- DEV_MESSAGE(KERN_ERR, device,
- "dasd_cancel_req is unable "
- " to terminate request %p, rc = %d",
- cqr, rc);
+ dev_err(&device->cdev->dev,
+ "Cancelling request %p failed with rc=%d\n",
+ cqr, rc);
} else {
cqr->stopclk = get_clock();
rc = 1;
@@ -1586,19 +1593,10 @@ static void dasd_block_timeout(unsigned long ptr)
*/
void dasd_block_set_timer(struct dasd_block *block, int expires)
{
- if (expires == 0) {
- if (timer_pending(&block->timer))
- del_timer(&block->timer);
- return;
- }
- if (timer_pending(&block->timer)) {
- if (mod_timer(&block->timer, jiffies + expires))
- return;
- }
- block->timer.function = dasd_block_timeout;
- block->timer.data = (unsigned long) block;
- block->timer.expires = jiffies + expires;
- add_timer(&block->timer);
+ if (expires == 0)
+ del_timer(&block->timer);
+ else
+ mod_timer(&block->timer, jiffies + expires);
}
/*
@@ -1606,8 +1604,7 @@ void dasd_block_set_timer(struct dasd_block *block, int expires)
*/
void dasd_block_clear_timer(struct dasd_block *block)
{
- if (timer_pending(&block->timer))
- del_timer(&block->timer);
+ del_timer(&block->timer);
}
/*
@@ -1631,7 +1628,7 @@ static inline void __dasd_block_process_erp(struct dasd_block *block,
if (cqr->status == DASD_CQR_DONE)
DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful");
else
- DEV_MESSAGE(KERN_ERR, device, "%s", "ERP unsuccessful");
+ dev_err(&device->cdev->dev, "ERP failed for the DASD\n");
erp_fn = device->discipline->erp_postaction(cqr);
erp_fn(cqr);
}
@@ -2005,8 +2002,11 @@ static void dasd_setup_queue(struct dasd_block *block)
blk_queue_max_sectors(block->request_queue, max);
blk_queue_max_phys_segments(block->request_queue, -1L);
blk_queue_max_hw_segments(block->request_queue, -1L);
- blk_queue_max_segment_size(block->request_queue, -1L);
- blk_queue_segment_boundary(block->request_queue, -1L);
+ /* with page sized segments we can translate each segement into
+ * one idaw/tidaw
+ */
+ blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
+ blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL);
}
@@ -2057,8 +2057,9 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
}
if (dasd_probeonly) {
- DEV_MESSAGE(KERN_INFO, base, "%s",
- "No access to device due to probeonly mode");
+ dev_info(&base->cdev->dev,
+ "Accessing the DASD failed because it is in "
+ "probeonly mode\n");
rc = -EPERM;
goto out;
}
@@ -2115,7 +2116,8 @@ dasd_device_operations = {
.owner = THIS_MODULE,
.open = dasd_open,
.release = dasd_release,
- .locked_ioctl = dasd_ioctl,
+ .ioctl = dasd_ioctl,
+ .compat_ioctl = dasd_ioctl,
.getgeo = dasd_getgeo,
};
@@ -2157,14 +2159,14 @@ int dasd_generic_probe(struct ccw_device *cdev,
ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_generic_probe: could not set ccw-device options "
"for %s\n", dev_name(&cdev->dev));
return ret;
}
ret = dasd_add_sysfs_files(cdev);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_generic_probe: could not add sysfs entries "
"for %s\n", dev_name(&cdev->dev));
return ret;
@@ -2180,9 +2182,7 @@ int dasd_generic_probe(struct ccw_device *cdev,
(dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0))
ret = ccw_device_set_online(cdev);
if (ret)
- printk(KERN_WARNING
- "dasd_generic_probe: could not initially "
- "online ccw-device %s; return code: %d\n",
+ pr_warning("%s: Setting the DASD online failed with rc=%d\n",
dev_name(&cdev->dev), ret);
return 0;
}
@@ -2246,10 +2246,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
discipline = base_discipline;
if (device->features & DASD_FEATURE_USEDIAG) {
if (!dasd_diag_discipline_pointer) {
- printk (KERN_WARNING
- "dasd_generic couldn't online device %s "
- "- discipline DIAG not available\n",
- dev_name(&cdev->dev));
+ pr_warning("%s Setting the DASD online failed because "
+ "of missing DIAG discipline\n",
+ dev_name(&cdev->dev));
dasd_delete_device(device);
return -ENODEV;
}
@@ -2270,10 +2269,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
/* check_device will allocate block device if necessary */
rc = discipline->check_device(device);
if (rc) {
- printk (KERN_WARNING
- "dasd_generic couldn't online device %s "
- "with discipline %s rc=%i\n",
- dev_name(&cdev->dev), discipline->name, rc);
+ pr_warning("%s Setting the DASD online with discipline %s "
+ "failed with rc=%i\n",
+ dev_name(&cdev->dev), discipline->name, rc);
module_put(discipline->owner);
module_put(base_discipline->owner);
dasd_delete_device(device);
@@ -2282,9 +2280,8 @@ int dasd_generic_set_online(struct ccw_device *cdev,
dasd_set_target_state(device, DASD_STATE_ONLINE);
if (device->state <= DASD_STATE_KNOWN) {
- printk (KERN_WARNING
- "dasd_generic discipline not found for %s\n",
- dev_name(&cdev->dev));
+ pr_warning("%s Setting the DASD online failed because of a "
+ "missing discipline\n", dev_name(&cdev->dev));
rc = -ENODEV;
dasd_set_target_state(device, DASD_STATE_NEW);
if (device->block)
@@ -2328,13 +2325,13 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
open_count = atomic_read(&device->block->open_count);
if (open_count > max_count) {
if (open_count > 0)
- printk(KERN_WARNING "Can't offline dasd "
- "device with open count = %i.\n",
- open_count);
+ pr_warning("%s: The DASD cannot be set offline "
+ "with open count %i\n",
+ dev_name(&cdev->dev), open_count);
else
- printk(KERN_WARNING "%s",
- "Can't offline dasd device due "
- "to internal use\n");
+ pr_warning("%s: The DASD cannot be set offline "
+ "while it is in use\n",
+ dev_name(&cdev->dev));
clear_bit(DASD_FLAG_OFFLINE, &device->flags);
dasd_put_device(device);
return -EBUSY;
@@ -2407,8 +2404,10 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate RDC request");
+ /* internal error 13 - Allocating the RDC request failed*/
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "13");
return cqr;
}
@@ -2445,6 +2444,40 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
}
EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars);
+/*
+ * In command mode and transport mode we need to look for sense
+ * data in different places. The sense data itself is allways
+ * an array of 32 bytes, so we can unify the sense data access
+ * for both modes.
+ */
+char *dasd_get_sense(struct irb *irb)
+{
+ struct tsb *tsb = NULL;
+ char *sense = NULL;
+
+ if (scsw_is_tm(&irb->scsw) && (irb->scsw.tm.fcxs == 0x01)) {
+ if (irb->scsw.tm.tcw)
+ tsb = tcw_get_tsb((struct tcw *)(unsigned long)
+ irb->scsw.tm.tcw);
+ if (tsb && tsb->length == 64 && tsb->flags)
+ switch (tsb->flags & 0x07) {
+ case 1: /* tsa_iostat */
+ sense = tsb->tsa.iostat.sense;
+ break;
+ case 2: /* tsa_ddpc */
+ sense = tsb->tsa.ddpc.sense;
+ break;
+ default:
+ /* currently we don't use interrogate data */
+ break;
+ }
+ } else if (irb->esw.esw0.erw.cons) {
+ sense = irb->ecw;
+ }
+ return sense;
+}
+EXPORT_SYMBOL_GPL(dasd_get_sense);
+
static int __init dasd_init(void)
{
int rc;
@@ -2486,7 +2519,7 @@ static int __init dasd_init(void)
return 0;
failed:
- MESSAGE(KERN_INFO, "%s", "initialization not performed due to errors");
+ pr_info("The DASD device driver could not be initialized\n");
dasd_exit();
return rc;
}
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index d82aad5224f..27991b69205 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -7,6 +7,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/timer.h>
#include <linux/slab.h>
#include <asm/idals.h>
@@ -75,7 +77,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
struct dasd_device *device = erp->startdev;
unsigned long flags;
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"blocking request queue for %is", expires/HZ);
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
@@ -114,9 +116,9 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp)
} else {
/* issue a message and wait for 'device ready' interrupt */
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ dev_err(&device->cdev->dev,
"is offline or not installed - "
- "INTERVENTION REQUIRED!!");
+ "INTERVENTION REQUIRED!!\n");
dasd_3990_erp_block_queue(erp, 60*HZ);
}
@@ -158,7 +160,7 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
if ((erp->lpm & opm) != 0x00) {
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
"try alternate lpm=%x (lpum=%x / opm=%x)",
erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm);
@@ -166,10 +168,9 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
erp->status = DASD_CQR_FILLED;
erp->retries = 10;
} else {
- DEV_MESSAGE(KERN_ERR, device,
- "No alternate channel path left (lpum=%x / "
- "opm=%x) -> permanent error",
- erp->irb.esw.esw0.sublog.lpum, opm);
+ dev_err(&device->cdev->dev,
+ "The DASD cannot be reached on any path (lpum=%x"
+ "/opm=%x)\n", erp->irb.esw.esw0.sublog.lpum, opm);
/* post request with permanent error */
erp->status = DASD_CQR_FAILED;
@@ -204,8 +205,8 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
sizeof(struct DCTL_data),
device);
if (IS_ERR(dctl_cqr)) {
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Unable to allocate DCTL-CQR");
+ dev_err(&device->cdev->dev,
+ "Unable to allocate DCTL-CQR\n");
erp->status = DASD_CQR_FAILED;
return erp;
}
@@ -294,7 +295,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
/* interrupt (this enables easier enqueing of the cqr) */
if (erp->function != dasd_3990_erp_action_4) {
- DEV_MESSAGE(KERN_INFO, device, "%s",
+ DBF_DEV_EVENT(DBF_INFO, device, "%s",
"dasd_3990_erp_action_4: first time retry");
erp->retries = 256;
@@ -303,7 +304,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
} else {
if (sense && (sense[25] == 0x1D)) { /* state change pending */
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"waiting for state change pending "
"interrupt, %d retries left",
erp->retries);
@@ -311,15 +312,14 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
dasd_3990_erp_block_queue(erp, 30*HZ);
} else if (sense && (sense[25] == 0x1E)) { /* busy */
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"busy - redriving request later, "
"%d retries left",
erp->retries);
dasd_3990_erp_block_queue(erp, HZ);
} else {
-
/* no state change pending - retry */
- DEV_MESSAGE (KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"redriving request immediately, "
"%d retries left",
erp->retries);
@@ -384,6 +384,7 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
struct dasd_device *device = erp->startdev;
char msg_format = (sense[7] & 0xF0);
char msg_no = (sense[7] & 0x0F);
+ char errorstring[ERRORLENGTH];
switch (msg_format) {
case 0x00: /* Format 0 - Program or System Checks */
@@ -394,95 +395,97 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Invalid Command");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Invalid Command\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Invalid Command "
- "Sequence");
+ "Sequence\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - CCW Count less than "
- "required");
+ "required\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Invalid Parameter");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Invalid Parameter\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Diagnostic of Sepecial"
- " Command Violates File Mask");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Diagnostic of Special"
+ " Command Violates File Mask\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Channel Returned with "
- "Incorrect retry CCW");
+ "Incorrect retry CCW\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reset Notification");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reset Notification\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Storage Path Restart");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Storage Path Restart\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Channel requested "
- "... %02x", sense[8]);
+ "... %02x\n", sense[8]);
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Invalid Defective/"
- "Alternate Track Pointer");
+ "Alternate Track Pointer\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - DPS Installation "
- "Check");
+ "Check\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Command Invalid on "
- "Secondary Address");
+ "Secondary Address\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Status Not As "
- "Required: reason %02x", sense[8]);
+ "Required: reason %02x\n",
+ sense[8]);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reseved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
}
} else {
switch (msg_no) {
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Device Error Source");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Device Error "
+ "Source\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Device Fenced - "
- "device = %02x", sense[4]);
+ "device = %02x\n", sense[4]);
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Data Pinned for "
- "Device");
+ "Device\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
}
}
break;
@@ -492,348 +495,352 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device Status 1 not as "
- "expected");
+ "expected\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Index missing");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Index missing\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Interruption cannot be reset");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Interruption cannot be "
+ "reset\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device did not respond to "
- "selection");
+ "selection\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device check-2 error or Set "
- "Sector is not complete");
+ "Sector is not complete\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Head address does not "
- "compare");
+ "compare\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Device status 1 not valid");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Device status 1 not valid\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Device not ready");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Device not ready\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Track physical address did "
- "not compare");
+ "not compare\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Missing device address bit");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Missing device address bit\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Drive motor switch is off");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Drive motor switch is off\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Seek incomplete");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Seek incomplete\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Cylinder address did not "
- "compare");
+ "compare\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Offset active cannot be "
- "reset");
+ "reset\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Reserved\n");
}
break;
case 0x20: /* Format 2 - 3990 Equipment Checks */
switch (msg_no) {
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - 3990 check-2 error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - 3990 check-2 error\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - Support facility errors");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Support facility errors\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device,
- "FORMAT 2 - Microcode detected error %02x",
- sense[8]);
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Microcode detected error "
+ "%02x\n",
+ sense[8]);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Reserved\n");
}
break;
case 0x30: /* Format 3 - 3990 Control Checks */
switch (msg_no) {
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 3 - Allegiance terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 3 - Allegiance terminated\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 3 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 3 - Reserved\n");
}
break;
case 0x40: /* Format 4 - Data Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Home address area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Home address area error\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Count area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Count area error\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Key area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Key area error\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Data area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Data area error\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in home address "
- "area");
+ "area\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in count address "
- "area");
+ "area\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - No sync byte in key area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - No sync byte in key area\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - No sync byte in data area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - No sync byte in data area\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Home address area error; "
- "offset active");
+ "offset active\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Count area error; offset "
- "active");
+ "active\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Key area error; offset "
- "active");
+ "active\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Data area error; "
- "offset active");
+ "offset active\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in home "
- "address area; offset active");
+ "address area; offset active\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No syn byte in count "
- "address area; offset active");
+ "address area; offset active\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in key area; "
- "offset active");
+ "offset active\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No syn byte in data area; "
- "offset active");
+ "offset active\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Reserved\n");
}
break;
case 0x50: /* Format 5 - Data Check with displacement information */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the "
- "home address area");
+ "home address area\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the count area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the count "
+ "area\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the key area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the key area\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the data area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the data "
+ "area\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the "
- "home address area; offset active");
+ "home address area; offset active\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the count area; "
- "offset active");
+ "offset active\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the key area; "
- "offset active");
+ "offset active\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the data area; "
- "offset active");
+ "offset active\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Reserved\n");
}
break;
case 0x60: /* Format 6 - Usage Statistics/Overrun Errors */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel A");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel A\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel B");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel B\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel C");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel C\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel D");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel D\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel E");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel E\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel F");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel F\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel G");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel G\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel H");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel H\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Reserved\n");
}
break;
case 0x70: /* Format 7 - Device Connection Control Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC initiated by a connection "
- "check alert");
+ "check alert\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC 1 sequence not "
- "successful");
+ "successful\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC 1 and RCC 2 sequences not "
- "successful");
+ "successful\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in during "
- "selection sequence");
+ "selection sequence\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 7 - extra RCC required");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 7 - extra RCC required\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid DCC selection "
- "response or timeout");
+ "response or timeout\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Missing end operation; device "
- "transfer complete");
+ "transfer complete\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Missing end operation; device "
- "transfer incomplete");
+ "transfer incomplete\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in for an "
- "immediate command sequence");
+ "immediate command sequence\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in for an "
- "extended command sequence");
+ "extended command sequence\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - 3990 microcode time out when "
- "stopping selection");
+ "stopping selection\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - No response to selection "
- "after a poll interruption");
+ "after a poll interruption\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Permanent path error (DASD "
- "controller not available)");
+ "controller not available)\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - DASD controller not available"
- " on disconnected command chain");
+ " on disconnected command chain\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 7 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 7 - Reserved\n");
}
break;
@@ -841,52 +848,52 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
switch (msg_no) {
case 0x00: /* No Message */
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Error correction code "
- "hardware fault");
+ "hardware fault\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Unexpected end operation "
- "response code");
+ "response code\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - End operation with transfer "
- "count not zero");
+ "count not zero\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - End operation with transfer "
- "count zero");
+ "count zero\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - DPS checks after a system "
- "reset or selective reset");
+ "reset or selective reset\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 8 - DPS cannot be filled");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 8 - DPS cannot be filled\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Short busy time-out during "
- "device selection");
+ "device selection\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - DASD controller failed to "
- "set or reset the long busy latch");
+ "set or reset the long busy latch\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - No interruption from device "
- "during a command chain");
+ "during a command chain\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 8 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 8 - Reserved\n");
}
break;
@@ -895,97 +902,100 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00:
break; /* No Message */
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Device check-2 error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Device check-2 error\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Head address did not compare");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Head address did not "
+ "compare\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 9 - Track physical address did "
- "not compare while oriented");
+ "not compare while oriented\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 9 - Cylinder address did not "
- "compare");
+ "compare\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Reserved\n");
}
break;
case 0xF0: /* Format F - Cache Storage Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Operation Terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Operation Terminated\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Subsystem Processing Error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Subsystem Processing Error\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Cache or nonvolatile storage "
- "equipment failure");
+ "equipment failure\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Caching terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Caching terminated\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Cache fast write access not "
- "authorized");
+ "authorized\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Track format incorrect");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Track format incorrect\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Caching reinitiated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Caching reinitiated\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Nonvolatile storage "
- "terminated");
+ "terminated\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Volume is suspended duplex");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Volume is suspended duplex\n");
/* call extended error reporting (EER) */
dasd_eer_write(device, erp->refers,
DASD_EER_PPRCSUSPEND);
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Subsystem status connot be "
- "determined");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Subsystem status cannot be "
+ "determined\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Caching status reset to "
- "default");
+ "default\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - DASD Fast Write inhibited");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - DASD Fast Write inhibited\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT D - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT D - Reserved\n");
}
break;
- default: /* unknown message format - should not happen */
- DEV_MESSAGE (KERN_WARNING, device,
- "unknown message format %02x",
- msg_format);
+ default: /* unknown message format - should not happen
+ internal error 03 - unknown message format */
+ snprintf(errorstring, ERRORLENGTH, "03 %x02", msg_format);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
break;
} /* end switch message format */
@@ -1015,7 +1025,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
/* env data present (ACTION 10 - retry should work) */
if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Command Reject - environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1023,9 +1033,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
erp->retries = 5;
} else {
- /* fatal error - set status to FAILED */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Command Reject - Fatal error");
+ /* fatal error - set status to FAILED
+ internal error 09 - Command Reject */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "09");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
}
@@ -1061,7 +1072,7 @@ dasd_3990_erp_bus_out(struct dasd_ccw_req * erp)
} else {
/* issue a message and wait for 'device ready' interrupt */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"bus out parity error or BOPC requested by "
"channel");
@@ -1093,21 +1104,19 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_equip_check;
if (sense[1] & SNS1_WRITE_INHIBITED) {
+ dev_info(&device->cdev->dev,
+ "Write inhibited path encountered\n");
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Write inhibited path encountered");
-
- /* vary path offline */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Path should be varied off-line. "
- "This is not implemented yet \n - please report "
- "to linux390@de.ibm.com");
+ /* vary path offline
+ internal error 04 - Path should be varied off-line.*/
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "04");
erp = dasd_3990_erp_action_1(erp);
} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment Check - " "environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1116,7 +1125,7 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[1] & SNS1_PERM_ERR) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment Check - retry exhausted or "
"undesirable");
@@ -1125,7 +1134,7 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
} else {
/* all other equipment checks - Action 5 */
/* rest is done when retries == 0 */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment check or processing error");
erp = dasd_3990_erp_action_5(erp);
@@ -1156,9 +1165,9 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
if (sense[2] & SNS2_CORRECTABLE) { /* correctable data check */
/* issue message that the data has been corrected */
- DEV_MESSAGE(KERN_EMERG, device, "%s",
+ dev_emerg(&device->cdev->dev,
"Data recovered during retry with PCI "
- "fetch mode active");
+ "fetch mode active\n");
/* not possible to handle this situation in Linux */
panic("No way to inform application about the possibly "
@@ -1166,7 +1175,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check recovered secondary "
"addr of duplex pair");
@@ -1174,7 +1183,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[1] & SNS1_PERM_ERR) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check with internal "
"retry exhausted");
@@ -1182,7 +1191,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else {
/* all other data checks */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check with retry count "
"exhausted...");
@@ -1212,7 +1221,7 @@ dasd_3990_erp_overrun(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_overrun;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Overrun - service overrun or overrun"
" error requested by channel");
@@ -1243,7 +1252,7 @@ dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense)
if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Track format error when destaging or "
"staging data");
@@ -1252,8 +1261,10 @@ dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_action_4(erp, sense);
} else {
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Invalid Track Format - Fatal error");
+ /* internal error 06 - The track format is not valid*/
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "06");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
}
@@ -1279,8 +1290,8 @@ dasd_3990_erp_EOC(struct dasd_ccw_req * default_erp, char *sense)
struct dasd_device *device = default_erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "End-of-Cylinder - must never happen");
+ dev_err(&device->cdev->dev,
+ "The cylinder data for accessing the DASD is inconsistent\n");
/* implement action 7 - BUG */
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
@@ -1306,7 +1317,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_env_data;
- DEV_MESSAGE(KERN_DEBUG, device, "%s", "Environmental data present");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1339,8 +1350,8 @@ dasd_3990_erp_no_rec(struct dasd_ccw_req * default_erp, char *sense)
struct dasd_device *device = default_erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "No Record Found - Fatal error ");
+ dev_err(&device->cdev->dev,
+ "The specified record was not found\n");
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
@@ -1365,7 +1376,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
struct dasd_device *device = erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected");
+ dev_err(&device->cdev->dev, "Accessing the DASD failed because of "
+ "a hardware error\n");
return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
@@ -1394,7 +1406,7 @@ static struct dasd_ccw_req *dasd_3990_erp_inspect_alias(
if (cqr->block &&
(cqr->block->base != cqr->startdev)) {
if (cqr->startdev->features & DASD_FEATURE_ERPLOG) {
- DEV_MESSAGE(KERN_ERR, cqr->startdev,
+ DBF_DEV_EVENT(DBF_ERR, cqr->startdev,
"ERP on alias device for request %p,"
" recover on base device %s", cqr,
dev_name(&cqr->block->base->cdev->dev));
@@ -1511,7 +1523,7 @@ dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense)
erp->retries = 256;
erp->function = dasd_3990_erp_action_10_32;
- DEV_MESSAGE(KERN_DEBUG, device, "%s", "Perform logging requested");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Perform logging requested");
return erp;
@@ -1549,7 +1561,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
char *LO_data; /* LO_eckd_data_t */
struct ccw1 *ccw, *oldccw;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Write not finished because of unexpected condition");
default_erp->function = dasd_3990_erp_action_1B_32;
@@ -1561,10 +1573,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
cqr = cqr->refers;
}
+ if (scsw_is_tm(&cqr->irb.scsw)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "32 bit sense, action 1B is not defined"
+ " in transport mode - just retry");
+ return default_erp;
+ }
+
/* for imprecise ending just do default erp */
if (sense[1] & 0x01) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Imprecise ending is set - just retry");
return default_erp;
@@ -1575,8 +1593,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
cpa = default_erp->refers->irb.scsw.cmd.cpa;
if (cpa == 0) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Unable to determine address of the CCW "
"to be restarted");
@@ -1590,7 +1607,9 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
sizeof(struct LO_eckd_data), device);
if (IS_ERR(erp)) {
- DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP");
+ /* internal error 01 - Unable to allocate ERP */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "01");
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
}
@@ -1599,7 +1618,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
oldccw = cqr->cpaddr;
if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) {
PFX_data = cqr->data;
- memcpy(DE_data, &PFX_data->define_extend,
+ memcpy(DE_data, &PFX_data->define_extent,
sizeof(struct DE_eckd_data));
} else
memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data));
@@ -1608,10 +1627,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
LO_data = erp->data + sizeof(struct DE_eckd_data);
if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "BUG - this should not happen");
-
+ /* should not */
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
}
@@ -1701,7 +1717,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
char *LO_data; /* struct LO_eckd_data */
struct ccw1 *ccw;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Write not finished because of unexpected condition"
" - follow on");
@@ -1712,10 +1728,16 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
cqr = cqr->refers;
}
+ if (scsw_is_tm(&cqr->irb.scsw)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "32 bit sense, action 1B, update,"
+ " in transport mode - just retry");
+ return previous_erp;
+ }
+
/* for imprecise ending just do default erp */
if (sense[1] & 0x01) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Imprecise ending is set - just retry");
previous_erp->status = DASD_CQR_FILLED;
@@ -1728,10 +1750,10 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
cpa = previous_erp->irb.scsw.cmd.cpa;
if (cpa == 0) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Unable to determine address of the CCW "
- "to be restarted");
+ /* internal error 02 -
+ Unable to determine address of the CCW to be restarted */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "02");
previous_erp->status = DASD_CQR_FAILED;
@@ -1744,10 +1766,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
LO_data = erp->data + sizeof(struct DE_eckd_data);
if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "BUG - this should not happen");
-
+ /* should not happen */
previous_erp->status = DASD_CQR_FAILED;
return previous_erp;
@@ -1935,14 +1954,13 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense)
if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) {
- /* set to suspended duplex state then restart */
+ /* set to suspended duplex state then restart
+ internal error 05 - Set device to suspended duplex state
+ should be done */
struct dasd_device *device = erp->startdev;
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Set device to suspended duplex state should be "
- "done!\n"
- "This is not implemented yet (for compound ERP)"
- " - please report to linux390@de.ibm.com");
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "05");
}
@@ -2012,15 +2030,14 @@ dasd_3990_erp_handle_sim(struct dasd_device *device, char *sense)
{
/* print message according to log or message to operator mode */
if ((sense[24] & DASD_SIM_MSG_TO_OP) || (sense[1] & 0x10)) {
-
/* print SIM SRC from RefCode */
- DEV_MESSAGE(KERN_ERR, device, "SIM - SRC: "
- "%02x%02x%02x%02x", sense[22],
+ dev_err(&device->cdev->dev, "SIM - SRC: "
+ "%02x%02x%02x%02x\n", sense[22],
sense[23], sense[11], sense[12]);
} else if (sense[24] & DASD_SIM_LOG) {
/* print SIM SRC Refcode */
- DEV_MESSAGE(KERN_WARNING, device, "SIM - SRC: "
- "%02x%02x%02x%02x", sense[22],
+ dev_warn(&device->cdev->dev, "log SIM - SRC: "
+ "%02x%02x%02x%02x\n", sense[22],
sense[23], sense[11], sense[12]);
}
}
@@ -2063,14 +2080,14 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
switch (sense[25]) {
case 0x00: /* success - use default ERP for retries */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"ERP called for successful request"
" - just retry");
break;
case 0x01: /* fatal error */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Retry not recommended - Fatal error");
+ dev_err(&device->cdev->dev,
+ "ERP failed for the DASD\n");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2080,13 +2097,10 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_int_req(erp);
break;
- case 0x0F: /* length mismatch during update write command */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "update write command error - should not "
- "happen;\n"
- "Please send this message together with "
- "the above sense data to linux390@de."
- "ibm.com");
+ case 0x0F: /* length mismatch during update write command
+ internal error 08 - update write command error*/
+ dev_err(&device->cdev->dev, "An error occurred in the "
+ "DASD device driver, reason=%s\n", "08");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2095,13 +2109,12 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_action_10_32(erp, sense);
break;
- case 0x15: /* next track outside defined extend */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "next track outside defined extend - "
- "should not happen;\n"
- "Please send this message together with "
- "the above sense data to linux390@de."
- "ibm.com");
+ case 0x15: /* next track outside defined extend
+ internal error 07 - The next track is not
+ within the defined storage extent */
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "07");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2112,9 +2125,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1C: /* invalid data */
- DEV_MESSAGE(KERN_EMERG, device, "%s",
+ dev_emerg(&device->cdev->dev,
"Data recovered during retry with PCI "
- "fetch mode active");
+ "fetch mode active\n");
/* not possible to handle this situation in Linux */
panic
@@ -2123,7 +2136,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1D: /* state-change pending */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"A State change pending condition exists "
"for the subsystem or device");
@@ -2131,7 +2144,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1E: /* busy */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Busy condition exists "
"for the subsystem or device");
erp = dasd_3990_erp_action_4(erp, sense);
@@ -2171,9 +2184,9 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
{
struct dasd_device *device = erp->startdev;
- if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK
+ if (scsw_cstat(&erp->refers->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK
| SCHN_STAT_CHN_CTRL_CHK)) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"channel or interface control check");
erp = dasd_3990_erp_action_4(erp, NULL);
}
@@ -2193,21 +2206,23 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
* erp_new contens was possibly modified
*/
static struct dasd_ccw_req *
-dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
+dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
{
struct dasd_ccw_req *erp_new = NULL;
- /* sense data are located in the refers record of the */
- /* already set up new ERP ! */
- char *sense = erp->refers->irb.ecw;
+ char *sense;
/* if this problem occured on an alias retry on base */
erp_new = dasd_3990_erp_inspect_alias(erp);
if (erp_new)
return erp_new;
- /* check if no concurrent sens is available */
- if (!erp->refers->irb.esw.esw0.erw.cons)
+ /* sense data are located in the refers record of the
+ * already set up new ERP !
+ * check if concurrent sens is available
+ */
+ sense = dasd_get_sense(&erp->refers->irb);
+ if (!sense)
erp_new = dasd_3990_erp_control_check(erp);
/* distinguish between 24 and 32 byte sense data */
else if (sense[27] & DASD_SENSE_BIT_0) {
@@ -2231,7 +2246,11 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
* DESCRIPTION
* This funtion adds an additional request block (ERP) to the head of
* the given cqr (or erp).
- * This erp is initialized as an default erp (retry TIC)
+ * For a command mode cqr the erp is initialized as an default erp
+ * (retry TIC).
+ * For transport mode we make a copy of the original TCW (points to
+ * the original TCCB, TIDALs, etc.) but give it a fresh
+ * TSB so the original sense data will not be changed.
*
* PARAMETER
* cqr head of the current ERP-chain (or single cqr if
@@ -2239,25 +2258,35 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
* RETURN VALUES
* erp pointer to new ERP-chain head
*/
-static struct dasd_ccw_req *
-dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
+static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
{
struct dasd_device *device = cqr->startdev;
struct ccw1 *ccw;
-
- /* allocate additional request block */
struct dasd_ccw_req *erp;
+ int cplength, datasize;
+ struct tcw *tcw;
+ struct tsb *tsb;
+
+ if (cqr->cpmode == 1) {
+ cplength = 0;
+ datasize = sizeof(struct tcw) + sizeof(struct tsb);
+ } else {
+ cplength = 2;
+ datasize = 0;
+ }
- erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device);
+ /* allocate additional request block */
+ erp = dasd_alloc_erp_request((char *) &cqr->magic,
+ cplength, datasize, device);
if (IS_ERR(erp)) {
if (cqr->retries <= 0) {
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"Unable to allocate ERP request");
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock ();
} else {
- DEV_MESSAGE (KERN_ERR, device,
+ DBF_DEV_EVENT(DBF_ERR, device,
"Unable to allocate ERP request "
"(%i retries left)",
cqr->retries);
@@ -2266,13 +2295,24 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
return cqr;
}
- /* initialize request with default TIC to current ERP/CQR */
- ccw = erp->cpaddr;
- ccw->cmd_code = CCW_CMD_NOOP;
- ccw->flags = CCW_FLAG_CC;
- ccw++;
- ccw->cmd_code = CCW_CMD_TIC;
- ccw->cda = (long)(cqr->cpaddr);
+ if (cqr->cpmode == 1) {
+ /* make a shallow copy of the original tcw but set new tsb */
+ erp->cpmode = 1;
+ erp->cpaddr = erp->data;
+ tcw = erp->data;
+ tsb = (struct tsb *) &tcw[1];
+ *tcw = *((struct tcw *)cqr->cpaddr);
+ tcw->tsb = (long)tsb;
+ } else {
+ /* initialize request with default TIC to current ERP/CQR */
+ ccw = erp->cpaddr;
+ ccw->cmd_code = CCW_CMD_NOOP;
+ ccw->flags = CCW_FLAG_CC;
+ ccw++;
+ ccw->cmd_code = CCW_CMD_TIC;
+ ccw->cda = (long)(cqr->cpaddr);
+ }
+
erp->function = dasd_3990_erp_add_erp;
erp->refers = cqr;
erp->startdev = device;
@@ -2282,7 +2322,6 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
erp->expires = 0;
erp->retries = 256;
erp->buildclk = get_clock();
-
erp->status = DASD_CQR_FILLED;
return erp;
@@ -2340,28 +2379,33 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
* match 'boolean' for match found
* returns 1 if match found, otherwise 0.
*/
-static int
-dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
+static int dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1,
+ struct dasd_ccw_req *cqr2)
{
+ char *sense1, *sense2;
if (cqr1->startdev != cqr2->startdev)
return 0;
- if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
- return 0;
+ sense1 = dasd_get_sense(&cqr1->irb);
+ sense2 = dasd_get_sense(&cqr2->irb);
- if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
- (cqr2->irb.esw.esw0.erw.cons == 0)) {
- if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
- SCHN_STAT_CHN_CTRL_CHK)) ==
- (cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
- SCHN_STAT_CHN_CTRL_CHK)))
+ /* one request has sense data, the other not -> no match, return 0 */
+ if (!sense1 != !sense2)
+ return 0;
+ /* no sense data in both cases -> check cstat for IFCC */
+ if (!sense1 && !sense2) {
+ if ((scsw_cstat(&cqr1->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)) ==
+ (scsw_cstat(&cqr2->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)))
return 1; /* match with ifcc*/
}
/* check sense data; byte 0-2,25,27 */
- if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) &&
- (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) &&
- (cqr1->irb.ecw[25] == cqr2->irb.ecw[25]))) {
+ if (!(sense1 && sense2 &&
+ (memcmp(sense1, sense2, 3) == 0) &&
+ (sense1[27] == sense2[27]) &&
+ (sense1[25] == sense2[25]))) {
return 0; /* sense doesn't match */
}
@@ -2434,7 +2478,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
{
struct dasd_device *device = erp->startdev;
- char *sense = erp->irb.ecw;
+ char *sense = dasd_get_sense(&erp->irb);
/* check for 24 byte sense ERP */
if ((erp->function == dasd_3990_erp_bus_out) ||
@@ -2449,7 +2493,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
/* prepare erp for retry on different channel path */
erp = dasd_3990_erp_action_1(erp);
- if (!(sense[2] & DASD_SENSE_BIT_0)) {
+ if (sense && !(sense[2] & DASD_SENSE_BIT_0)) {
/* issue a Diagnostic Control command with an
* Inhibit Write subcommand */
@@ -2471,7 +2515,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
break;
}
default:
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
"invalid subcommand modifier 0x%x "
"for Diagnostic Control Command",
sense[25]);
@@ -2479,19 +2523,21 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
}
/* check for 32 byte sense ERP */
- } else if ((erp->function == dasd_3990_erp_compound_retry) ||
- (erp->function == dasd_3990_erp_compound_path) ||
- (erp->function == dasd_3990_erp_compound_code) ||
- (erp->function == dasd_3990_erp_compound_config)) {
+ } else if (sense &&
+ ((erp->function == dasd_3990_erp_compound_retry) ||
+ (erp->function == dasd_3990_erp_compound_path) ||
+ (erp->function == dasd_3990_erp_compound_code) ||
+ (erp->function == dasd_3990_erp_compound_config))) {
erp = dasd_3990_erp_compound(erp, sense);
} else {
- /* No retry left and no additional special handling */
- /*necessary */
- DEV_MESSAGE(KERN_ERR, device,
- "no retries left for erp %p - "
- "set status to FAILED", erp);
+ /*
+ * No retry left and no additional special handling
+ * necessary
+ */
+ dev_err(&device->cdev->dev,
+ "ERP %p has run out of retries and failed\n", erp);
erp->status = DASD_CQR_FAILED;
}
@@ -2548,24 +2594,25 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head,
if (erp->retries > 0) {
- char *sense = erp->refers->irb.ecw;
+ char *sense = dasd_get_sense(&erp->refers->irb);
/* check for special retries */
- if (erp->function == dasd_3990_erp_action_4) {
+ if (sense && erp->function == dasd_3990_erp_action_4) {
erp = dasd_3990_erp_action_4(erp, sense);
- } else if (erp->function == dasd_3990_erp_action_1B_32) {
+ } else if (sense &&
+ erp->function == dasd_3990_erp_action_1B_32) {
erp = dasd_3990_update_1B(erp, sense);
- } else if (erp->function == dasd_3990_erp_int_req) {
+ } else if (sense && erp->function == dasd_3990_erp_int_req) {
erp = dasd_3990_erp_int_req(erp);
} else {
/* simple retry */
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"%i retries left for erp %p",
erp->retries, erp);
@@ -2609,24 +2656,24 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "ERP chain at BEGINNING of ERP-ACTION");
+ dev_err(&device->cdev->dev,
+ "ERP chain at BEGINNING of ERP-ACTION\n");
for (temp_erp = cqr;
temp_erp != NULL; temp_erp = temp_erp->refers) {
- DEV_MESSAGE(KERN_ERR, device,
- " erp %p (%02x) refers to %p",
+ dev_err(&device->cdev->dev,
+ "ERP %p (%02x) refers to %p\n",
temp_erp, temp_erp->status,
temp_erp->refers);
}
}
/* double-check if current erp/cqr was successful */
- if ((cqr->irb.scsw.cmd.cstat == 0x00) &&
- (cqr->irb.scsw.cmd.dstat ==
+ if ((scsw_cstat(&cqr->irb.scsw) == 0x00) &&
+ (scsw_dstat(&cqr->irb.scsw) ==
(DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"ERP called for successful request %p"
" - NO ERP necessary", cqr);
@@ -2648,13 +2695,13 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "ERP chain at END of ERP-ACTION");
+ dev_err(&device->cdev->dev,
+ "ERP chain at END of ERP-ACTION\n");
for (temp_erp = erp;
temp_erp != NULL; temp_erp = temp_erp->refers) {
- DEV_MESSAGE(KERN_ERR, device,
- " erp %p (%02x) refers to %p",
+ dev_err(&device->cdev->dev,
+ "ERP %p (%02x) refers to %p\n",
temp_erp, temp_erp->status,
temp_erp->refers);
}
@@ -2667,6 +2714,8 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
list_add_tail(&erp->blocklist, &cqr->blocklist);
}
+
+
return erp;
} /* end dasd_3990_erp_action */
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 20676cdef4a..5b7bbc87593 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -5,6 +5,8 @@
* Author(s): Stefan Weinhuber <wein@de.ibm.com>
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/list.h>
#include <asm/ebcdic.h>
#include "dasd_int.h"
@@ -503,7 +505,7 @@ static void lcu_update_work(struct work_struct *work)
*/
spin_lock_irqsave(&lcu->lock, flags);
if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
- DEV_MESSAGE(KERN_WARNING, device, "could not update"
+ DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
" alias data in lcu (rc = %d), retry later", rc);
schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
} else {
@@ -646,14 +648,16 @@ static int reset_summary_unit_check(struct alias_lcu *lcu,
{
struct dasd_ccw_req *cqr;
int rc = 0;
+ struct ccw1 *ccw;
cqr = lcu->rsu_cqr;
strncpy((char *) &cqr->magic, "ECKD", 4);
ASCEBC((char *) &cqr->magic, 4);
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RSCK;
- cqr->cpaddr->flags = 0 ;
- cqr->cpaddr->count = 16;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RSCK;
+ ccw->flags = 0 ;
+ ccw->count = 16;
+ ccw->cda = (__u32)(addr_t) cqr->data;
((char *)cqr->data)[0] = reason;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -855,16 +859,25 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
struct alias_lcu *lcu;
char reason;
struct dasd_eckd_private *private;
+ char *sense;
private = (struct dasd_eckd_private *) device->private;
- reason = irb->ecw[8];
- DEV_MESSAGE(KERN_WARNING, device, "%s %x",
- "eckd handle summary unit check: reason", reason);
+ sense = dasd_get_sense(irb);
+ if (sense) {
+ reason = sense[8];
+ DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",
+ "eckd handle summary unit check: reason", reason);
+ } else {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "eckd handle summary unit check:"
+ " no reason code available");
+ return;
+ }
lcu = private->lcu;
if (!lcu) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"device not ready to handle summary"
" unit check (no lcu structure)");
return;
@@ -877,7 +890,7 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
* the next interrupt on a different device
*/
if (list_empty(&device->alias_list)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"device is in offline processing,"
" don't do summary unit check handling");
spin_unlock(&lcu->lock);
@@ -885,7 +898,7 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
}
if (lcu->suc_data.device) {
/* already scheduled or running */
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"previous instance of summary unit check worker"
" still pending");
spin_unlock(&lcu->lock);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 300e28a531f..e77666c8e6c 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -13,6 +13,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -67,6 +69,8 @@ int dasd_probeonly = 0; /* is true, when probeonly mode is active */
int dasd_autodetect = 0; /* is true, when autodetection is active */
int dasd_nopav = 0; /* is true, when PAV is disabled */
EXPORT_SYMBOL_GPL(dasd_nopav);
+int dasd_nofcx; /* disable High Performance Ficon */
+EXPORT_SYMBOL_GPL(dasd_nofcx);
/*
* char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -125,6 +129,7 @@ __setup ("dasd=", dasd_call_setup);
* Read a device busid/devno from a string.
*/
static int
+
dasd_busid(char **str, int *id0, int *id1, int *devno)
{
int val, old_style;
@@ -132,8 +137,7 @@ dasd_busid(char **str, int *id0, int *id1, int *devno)
/* Interpret ipldev busid */
if (strncmp(DASD_IPLDEV, *str, strlen(DASD_IPLDEV)) == 0) {
if (ipl_info.type != IPL_TYPE_CCW) {
- MESSAGE(KERN_ERR, "%s", "ipl device is not a ccw "
- "device");
+ pr_err("The IPL device is not a CCW device\n");
return -EINVAL;
}
*id0 = 0;
@@ -209,9 +213,8 @@ dasd_feature_list(char *str, char **endp)
else if (len == 8 && !strncmp(str, "failfast", 8))
features |= DASD_FEATURE_FAILFAST;
else {
- MESSAGE(KERN_WARNING,
- "unsupported feature: %*s, "
- "ignoring setting", len, str);
+ pr_warning("%*s is not a supported device option\n",
+ len, str);
rc = -EINVAL;
}
str += len;
@@ -220,8 +223,8 @@ dasd_feature_list(char *str, char **endp)
str++;
}
if (*str != ')') {
- MESSAGE(KERN_WARNING, "%s",
- "missing ')' in dasd parameter string\n");
+ pr_warning("A closing parenthesis ')' is missing in the "
+ "dasd= parameter\n");
rc = -EINVAL;
} else
str++;
@@ -253,25 +256,29 @@ dasd_parse_keyword( char *parsestring ) {
}
if (strncmp("autodetect", parsestring, length) == 0) {
dasd_autodetect = 1;
- MESSAGE (KERN_INFO, "%s",
- "turning to autodetection mode");
+ pr_info("The autodetection mode has been activated\n");
return residual_str;
}
if (strncmp("probeonly", parsestring, length) == 0) {
dasd_probeonly = 1;
- MESSAGE(KERN_INFO, "%s",
- "turning to probeonly mode");
+ pr_info("The probeonly mode has been activated\n");
return residual_str;
}
if (strncmp("nopav", parsestring, length) == 0) {
if (MACHINE_IS_VM)
- MESSAGE(KERN_INFO, "%s", "'nopav' not supported on VM");
+ pr_info("'nopav' is not supported on z/VM\n");
else {
dasd_nopav = 1;
- MESSAGE(KERN_INFO, "%s", "disable PAV mode");
+ pr_info("PAV support has be deactivated\n");
}
return residual_str;
}
+ if (strncmp("nofcx", parsestring, length) == 0) {
+ dasd_nofcx = 1;
+ pr_info("High Performance FICON support has been "
+ "deactivated\n");
+ return residual_str;
+ }
if (strncmp("fixedbuffers", parsestring, length) == 0) {
if (dasd_page_cache)
return residual_str;
@@ -280,10 +287,10 @@ dasd_parse_keyword( char *parsestring ) {
PAGE_SIZE, SLAB_CACHE_DMA,
NULL);
if (!dasd_page_cache)
- MESSAGE(KERN_WARNING, "%s", "Failed to create slab, "
+ DBF_EVENT(DBF_WARNING, "%s", "Failed to create slab, "
"fixed buffer mode disabled.");
else
- MESSAGE (KERN_INFO, "%s",
+ DBF_EVENT(DBF_INFO, "%s",
"turning on fixed buffer mode");
return residual_str;
}
@@ -321,7 +328,7 @@ dasd_parse_range( char *parsestring ) {
(from_id0 != to_id0 || from_id1 != to_id1 || from > to))
rc = -EINVAL;
if (rc) {
- MESSAGE(KERN_ERR, "Invalid device range %s", parsestring);
+ pr_err("%s is not a valid device range\n", parsestring);
return ERR_PTR(rc);
}
features = dasd_feature_list(str, &str);
@@ -340,8 +347,8 @@ dasd_parse_range( char *parsestring ) {
return str + 1;
if (*str == '\0')
return str;
- MESSAGE(KERN_WARNING,
- "junk at end of dasd parameter string: %s\n", str);
+ pr_warning("The dasd= parameter value %s has an invalid ending\n",
+ str);
return ERR_PTR(-EINVAL);
}
@@ -677,7 +684,7 @@ static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
struct dasd_devmap *devmap;
int ff_flag;
- devmap = dasd_find_busid(dev->bus_id);
+ devmap = dasd_find_busid(dev_name(dev));
if (!IS_ERR(devmap))
ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
else
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index ef2a5695205..b9a7f773344 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -8,6 +8,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -144,8 +146,8 @@ dasd_diag_erp(struct dasd_device *device)
mdsk_term_io(device);
rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
if (rc)
- DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, "
- "rc=%d", rc);
+ dev_warn(&device->cdev->dev, "DIAG ERP failed with "
+ "rc=%d\n", rc);
}
/* Start a given request at the device. Return zero on success, non-zero
@@ -160,7 +162,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
device = cqr->startdev;
if (cqr->retries < 0) {
- DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p "
+ DBF_DEV_EVENT(DBF_ERR, device, "DIAG start_IO: request %p "
"- no retry left)", cqr);
cqr->status = DASD_CQR_ERROR;
return -EIO;
@@ -195,7 +197,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
break;
default: /* Error condition */
cqr->status = DASD_CQR_QUEUED;
- DEV_MESSAGE(KERN_WARNING, device, "dia250 returned rc=%d", rc);
+ DBF_DEV_EVENT(DBF_WARNING, device, "dia250 returned rc=%d", rc);
dasd_diag_erp(device);
rc = -EIO;
break;
@@ -243,13 +245,14 @@ dasd_ext_handler(__u16 code)
return;
}
if (!ip) { /* no intparm: unsolicited interrupt */
- MESSAGE(KERN_DEBUG, "%s", "caught unsolicited interrupt");
+ DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited "
+ "interrupt");
return;
}
cqr = (struct dasd_ccw_req *) ip;
device = (struct dasd_device *) cqr->startdev;
if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- DEV_MESSAGE(KERN_WARNING, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
" magic number of dasd_ccw_req 0x%08X doesn't"
" match discipline 0x%08X",
cqr->magic, *(int *) (&device->discipline->name));
@@ -281,15 +284,11 @@ dasd_ext_handler(__u16 code)
rc = dasd_start_diag(next);
if (rc == 0)
expires = next->expires;
- else if (rc != -EACCES)
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Interrupt fastpath "
- "failed!");
}
}
} else {
cqr->status = DASD_CQR_QUEUED;
- DEV_MESSAGE(KERN_WARNING, device, "interrupt status for "
+ DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
"request %p was %d (%d retries left)", cqr, status,
cqr->retries);
dasd_diag_erp(device);
@@ -322,8 +321,9 @@ dasd_diag_check_device(struct dasd_device *device)
if (private == NULL) {
private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private data");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "Allocating memory for private DASD data "
+ "failed\n");
return -ENOMEM;
}
ccw_device_get_id(device->cdev, &private->dev_id);
@@ -331,7 +331,7 @@ dasd_diag_check_device(struct dasd_device *device)
}
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"could not allocate dasd block structure");
device->private = NULL;
kfree(private);
@@ -347,7 +347,7 @@ dasd_diag_check_device(struct dasd_device *device)
rc = diag210((struct diag210 *) rdc_data);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device "
+ DBF_DEV_EVENT(DBF_WARNING, device, "failed to retrieve device "
"information (rc=%d)", rc);
rc = -EOPNOTSUPP;
goto out;
@@ -362,8 +362,8 @@ dasd_diag_check_device(struct dasd_device *device)
private->pt_block = 2;
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "unsupported device class "
- "(class=%d)", private->rdc_data.vdev_class);
+ dev_warn(&device->cdev->dev, "Device type %d is not supported "
+ "in DIAG mode\n", private->rdc_data.vdev_class);
rc = -EOPNOTSUPP;
goto out;
}
@@ -380,7 +380,7 @@ dasd_diag_check_device(struct dasd_device *device)
/* figure out blocksize of device */
label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL);
if (label == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"No memory to allocate initialization request");
rc = -ENOMEM;
goto out;
@@ -404,8 +404,8 @@ dasd_diag_check_device(struct dasd_device *device)
private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
rc = dia250(&private->iob, RW_BIO);
if (rc == 3) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "DIAG call failed");
+ dev_warn(&device->cdev->dev,
+ "A 64-bit DIAG call failed\n");
rc = -EOPNOTSUPP;
goto out_label;
}
@@ -414,8 +414,8 @@ dasd_diag_check_device(struct dasd_device *device)
break;
}
if (bsize > PAGE_SIZE) {
- DEV_MESSAGE(KERN_WARNING, device, "device access failed "
- "(rc=%d)", rc);
+ dev_warn(&device->cdev->dev, "Accessing the DASD failed because"
+ " of an incorrect format (rc=%d)\n", rc);
rc = -EIO;
goto out_label;
}
@@ -433,15 +433,15 @@ dasd_diag_check_device(struct dasd_device *device)
block->s2b_shift++;
rc = mdsk_init_io(device, block->bp_block, 0, NULL);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
- "failed (rc=%d)", rc);
+ dev_warn(&device->cdev->dev, "DIAG initialization "
+ "failed with rc=%d\n", rc);
rc = -EIO;
} else {
- DEV_MESSAGE(KERN_INFO, device,
- "(%ld B/blk): %ldkB",
- (unsigned long) block->bp_block,
- (unsigned long) (block->blocks <<
- block->s2b_shift) >> 1);
+ dev_info(&device->cdev->dev,
+ "New DASD with %ld byte/block, total size %ld KB\n",
+ (unsigned long) block->bp_block,
+ (unsigned long) (block->blocks <<
+ block->s2b_shift) >> 1);
}
out_label:
free_page((long) label);
@@ -595,7 +595,7 @@ static void
dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
struct irb *stat)
{
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"dump sense not available for DIAG data");
}
@@ -621,10 +621,8 @@ static int __init
dasd_diag_init(void)
{
if (!MACHINE_IS_VM) {
- MESSAGE_LOG(KERN_INFO,
- "Machine is not VM: %s "
- "discipline not initializing",
- dasd_diag_discipline.name);
+ pr_info("Discipline %s cannot be used without z/VM\n",
+ dasd_diag_discipline.name);
return -ENODEV;
}
ASCEBC(dasd_diag_discipline.ebcname, 4);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index bdb87998f36..21254793c60 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -11,6 +11,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -27,9 +29,12 @@
#include <asm/uaccess.h>
#include <asm/cio.h>
#include <asm/ccwdev.h>
+#include <asm/itcw.h>
#include "dasd_int.h"
#include "dasd_eckd.h"
+#include "../cio/chsc.h"
+
#ifdef PRINTK_HEADER
#undef PRINTK_HEADER
@@ -84,7 +89,7 @@ dasd_eckd_probe (struct ccw_device *cdev)
/* set ECKD specific ccw-device options */
ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_eckd_probe: could not set ccw-device options "
"for %s\n", dev_name(&cdev->dev));
return ret;
@@ -159,6 +164,14 @@ recs_per_track(struct dasd_eckd_characteristics * rdc,
return 0;
}
+static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)
+{
+ geo->cyl = (__u16) cyl;
+ geo->head = cyl >> 16;
+ geo->head <<= 4;
+ geo->head |= head;
+}
+
static int
check_XRC (struct ccw1 *de_ccw,
struct DE_eckd_data *data,
@@ -186,11 +199,12 @@ check_XRC (struct ccw1 *de_ccw,
}
static int
-define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
- int totrk, int cmd, struct dasd_device * device)
+define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
+ unsigned int totrk, int cmd, struct dasd_device *device)
{
struct dasd_eckd_private *private;
- struct ch_t geo, beg, end;
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
int rc = 0;
private = (struct dasd_eckd_private *) device->private;
@@ -236,7 +250,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
rc = check_XRC (ccw, data, device);
break;
default:
- DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
+ dev_err(&device->cdev->dev,
+ "0x%x is not a known command\n", cmd);
break;
}
@@ -248,27 +263,24 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
&& !(private->uses_cdl && trk < 2))
data->ga_extended |= 0x40; /* Regular Data Format Mode */
- geo.cyl = private->rdc_data.no_cyl;
- geo.head = private->rdc_data.trk_per_cyl;
- beg.cyl = trk / geo.head;
- beg.head = trk % geo.head;
- end.cyl = totrk / geo.head;
- end.head = totrk % geo.head;
+ heads = private->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
/* check for sequential prestage - enhance cylinder range */
if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
data->attributes.operation == DASD_SEQ_ACCESS) {
- if (end.cyl + private->attrib.nr_cyl < geo.cyl)
- end.cyl += private->attrib.nr_cyl;
+ if (endcyl + private->attrib.nr_cyl < private->real_cyl)
+ endcyl += private->attrib.nr_cyl;
else
- end.cyl = (geo.cyl - 1);
+ endcyl = (private->real_cyl - 1);
}
- data->beg_ext.cyl = beg.cyl;
- data->beg_ext.head = beg.head;
- data->end_ext.cyl = end.cyl;
- data->end_ext.head = end.head;
+ set_ch_t(&data->beg_ext, begcyl, beghead);
+ set_ch_t(&data->end_ext, endcyl, endhead);
return rc;
}
@@ -283,29 +295,145 @@ static int check_XRC_on_prefix(struct PFX_eckd_data *pfxdata,
return 0;
/* switch on System Time Stamp - needed for XRC Support */
- pfxdata->define_extend.ga_extended |= 0x08; /* 'Time Stamp Valid' */
- pfxdata->define_extend.ga_extended |= 0x02; /* 'Extended Parameter' */
+ pfxdata->define_extent.ga_extended |= 0x08; /* 'Time Stamp Valid' */
+ pfxdata->define_extent.ga_extended |= 0x02; /* 'Extended Parameter' */
pfxdata->validity.time_stamp = 1; /* 'Time Stamp Valid' */
- rc = get_sync_clock(&pfxdata->define_extend.ep_sys_time);
+ rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time);
/* Ignore return code if sync clock is switched off. */
if (rc == -ENOSYS || rc == -EACCES)
rc = 0;
return rc;
}
-static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
- int totrk, int cmd, struct dasd_device *basedev,
- struct dasd_device *startdev)
+static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
+ unsigned int rec_on_trk, int count, int cmd,
+ struct dasd_device *device, unsigned int reclen,
+ unsigned int tlf)
+{
+ struct dasd_eckd_private *private;
+ int sector;
+ int dn, d;
+
+ private = (struct dasd_eckd_private *) device->private;
+
+ memset(data, 0, sizeof(*data));
+ sector = 0;
+ if (rec_on_trk) {
+ switch (private->rdc_data.dev_type) {
+ case 0x3390:
+ dn = ceil_quot(reclen + 6, 232);
+ d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
+ sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+ break;
+ case 0x3380:
+ d = 7 + ceil_quot(reclen + 12, 32);
+ sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+ break;
+ }
+ }
+ data->sector = sector;
+ /* note: meaning of count depends on the operation
+ * for record based I/O it's the number of records, but for
+ * track based I/O it's the number of tracks
+ */
+ data->count = count;
+ switch (cmd) {
+ case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x03;
+ break;
+ case DASD_ECKD_CCW_READ_HOME_ADDRESS:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x16;
+ break;
+ case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
+ data->operation.orientation = 0x1;
+ data->operation.operation = 0x03;
+ data->count++;
+ break;
+ case DASD_ECKD_CCW_READ_RECORD_ZERO:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x16;
+ data->count++;
+ break;
+ case DASD_ECKD_CCW_WRITE:
+ case DASD_ECKD_CCW_WRITE_MT:
+ case DASD_ECKD_CCW_WRITE_KD:
+ case DASD_ECKD_CCW_WRITE_KD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x01;
+ break;
+ case DASD_ECKD_CCW_WRITE_CKD:
+ case DASD_ECKD_CCW_WRITE_CKD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x03;
+ break;
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen; /* not tlf, as one might think */
+ data->operation.operation = 0x3F;
+ data->extended_operation = 0x23;
+ break;
+ case DASD_ECKD_CCW_READ:
+ case DASD_ECKD_CCW_READ_MT:
+ case DASD_ECKD_CCW_READ_KD:
+ case DASD_ECKD_CCW_READ_KD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x06;
+ break;
+ case DASD_ECKD_CCW_READ_CKD:
+ case DASD_ECKD_CCW_READ_CKD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x16;
+ break;
+ case DASD_ECKD_CCW_READ_COUNT:
+ data->operation.operation = 0x06;
+ break;
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ data->auxiliary.length_valid = 0x1;
+ data->length = tlf;
+ data->operation.operation = 0x0C;
+ break;
+ case DASD_ECKD_CCW_ERASE:
+ data->length = reclen;
+ data->auxiliary.length_valid = 0x1;
+ data->operation.operation = 0x0b;
+ break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, device,
+ "fill LRE unknown opcode 0x%x", cmd);
+ BUG();
+ }
+ set_ch_t(&data->seek_addr,
+ trk / private->rdc_data.trk_per_cyl,
+ trk % private->rdc_data.trk_per_cyl);
+ data->search_arg.cyl = data->seek_addr.cyl;
+ data->search_arg.head = data->seek_addr.head;
+ data->search_arg.record = rec_on_trk;
+}
+
+static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev, struct dasd_device *startdev,
+ unsigned char format, unsigned int rec_on_trk, int count,
+ unsigned int blksize, unsigned int tlf)
{
struct dasd_eckd_private *basepriv, *startpriv;
- struct DE_eckd_data *data;
- struct ch_t geo, beg, end;
+ struct DE_eckd_data *dedata;
+ struct LRE_eckd_data *lredata;
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
int rc = 0;
basepriv = (struct dasd_eckd_private *) basedev->private;
startpriv = (struct dasd_eckd_private *) startdev->private;
- data = &pfxdata->define_extend;
+ dedata = &pfxdata->define_extent;
+ lredata = &pfxdata->locate_record;
ccw->cmd_code = DASD_ECKD_CCW_PFX;
ccw->flags = 0;
@@ -314,10 +442,16 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
memset(pfxdata, 0, sizeof(*pfxdata));
/* prefix data */
- pfxdata->format = 0;
+ if (format > 1) {
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "PFX LRE unknown format 0x%x", format);
+ BUG();
+ return -EINVAL;
+ }
+ pfxdata->format = format;
pfxdata->base_address = basepriv->ned->unit_addr;
pfxdata->base_lss = basepriv->ned->ID;
- pfxdata->validity.define_extend = 1;
+ pfxdata->validity.define_extent = 1;
/* private uid is kept up to date, conf_data may be outdated */
if (startpriv->uid.type != UA_BASE_DEVICE) {
@@ -337,70 +471,94 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
case DASD_ECKD_CCW_READ_KD:
case DASD_ECKD_CCW_READ_KD_MT:
case DASD_ECKD_CCW_READ_COUNT:
- data->mask.perm = 0x1;
- data->attributes.operation = basepriv->attrib.operation;
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ break;
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = 0;
break;
case DASD_ECKD_CCW_WRITE:
case DASD_ECKD_CCW_WRITE_MT:
case DASD_ECKD_CCW_WRITE_KD:
case DASD_ECKD_CCW_WRITE_KD_MT:
- data->mask.perm = 0x02;
- data->attributes.operation = basepriv->attrib.operation;
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
case DASD_ECKD_CCW_WRITE_CKD:
case DASD_ECKD_CCW_WRITE_CKD_MT:
- data->attributes.operation = DASD_BYPASS_CACHE;
+ dedata->attributes.operation = DASD_BYPASS_CACHE;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
case DASD_ECKD_CCW_ERASE:
case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
- data->mask.perm = 0x3;
- data->mask.auth = 0x1;
- data->attributes.operation = DASD_BYPASS_CACHE;
+ dedata->mask.perm = 0x3;
+ dedata->mask.auth = 0x1;
+ dedata->attributes.operation = DASD_BYPASS_CACHE;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
- default:
- DEV_MESSAGE(KERN_ERR, basedev, "unknown opcode 0x%x", cmd);
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ rc = check_XRC_on_prefix(pfxdata, basedev);
break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "PFX LRE unknown opcode 0x%x", cmd);
+ BUG();
+ return -EINVAL;
}
- data->attributes.mode = 0x3; /* ECKD */
+ dedata->attributes.mode = 0x3; /* ECKD */
if ((basepriv->rdc_data.cu_type == 0x2105 ||
basepriv->rdc_data.cu_type == 0x2107 ||
basepriv->rdc_data.cu_type == 0x1750)
&& !(basepriv->uses_cdl && trk < 2))
- data->ga_extended |= 0x40; /* Regular Data Format Mode */
+ dedata->ga_extended |= 0x40; /* Regular Data Format Mode */
- geo.cyl = basepriv->rdc_data.no_cyl;
- geo.head = basepriv->rdc_data.trk_per_cyl;
- beg.cyl = trk / geo.head;
- beg.head = trk % geo.head;
- end.cyl = totrk / geo.head;
- end.head = totrk % geo.head;
+ heads = basepriv->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
/* check for sequential prestage - enhance cylinder range */
- if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
- data->attributes.operation == DASD_SEQ_ACCESS) {
+ if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+ dedata->attributes.operation == DASD_SEQ_ACCESS) {
- if (end.cyl + basepriv->attrib.nr_cyl < geo.cyl)
- end.cyl += basepriv->attrib.nr_cyl;
+ if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+ endcyl += basepriv->attrib.nr_cyl;
else
- end.cyl = (geo.cyl - 1);
+ endcyl = (basepriv->real_cyl - 1);
+ }
+
+ set_ch_t(&dedata->beg_ext, begcyl, beghead);
+ set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+ if (format == 1) {
+ fill_LRE_data(lredata, trk, rec_on_trk, count, cmd,
+ basedev, blksize, tlf);
}
- data->beg_ext.cyl = beg.cyl;
- data->beg_ext.head = beg.head;
- data->end_ext.cyl = end.cyl;
- data->end_ext.head = end.head;
return rc;
}
+static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev, struct dasd_device *startdev)
+{
+ return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,
+ 0, 0, 0, 0, 0);
+}
+
static void
-locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
- int rec_on_trk, int no_rec, int cmd,
+locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
+ unsigned int rec_on_trk, int no_rec, int cmd,
struct dasd_device * device, int reclen)
{
struct dasd_eckd_private *private;
@@ -491,12 +649,14 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
data->operation.operation = 0x0b;
break;
default:
- DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
- }
- data->seek_addr.cyl = data->search_arg.cyl =
- trk / private->rdc_data.trk_per_cyl;
- data->seek_addr.head = data->search_arg.head =
- trk % private->rdc_data.trk_per_cyl;
+ DBF_DEV_EVENT(DBF_ERR, device, "unknown locate record "
+ "opcode 0x%x", cmd);
+ }
+ set_ch_t(&data->seek_addr,
+ trk / private->rdc_data.trk_per_cyl,
+ trk % private->rdc_data.trk_per_cyl);
+ data->search_arg.cyl = data->seek_addr.cyl;
+ data->search_arg.head = data->seek_addr.head;
data->search_arg.record = rec_on_trk;
}
@@ -585,8 +745,8 @@ static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate RCD request");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "Could not allocate RCD request");
return cqr;
}
@@ -736,14 +896,16 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
rc = dasd_eckd_read_conf_lpm(device, &conf_data,
&conf_len, lpm);
if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
- MESSAGE(KERN_WARNING,
- "Read configuration data returned "
- "error %d", rc);
+ DBF_EVENT(DBF_WARNING,
+ "Read configuration data returned "
+ "error %d for device: %s", rc,
+ dev_name(&device->cdev->dev));
return rc;
}
if (conf_data == NULL) {
- MESSAGE(KERN_WARNING, "%s", "No configuration "
- "data retrieved");
+ DBF_EVENT(DBF_WARNING, "No configuration "
+ "data retrieved for device: %s",
+ dev_name(&device->cdev->dev));
continue; /* no error */
}
/* save first valid configuration data */
@@ -790,8 +952,9 @@ static int dasd_eckd_read_features(struct dasd_device *device)
sizeof(struct dasd_rssd_features)),
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate initialization request");
+ DBF_EVENT(DBF_WARNING, "Could not allocate initialization "
+ "request for device: %s",
+ dev_name(&device->cdev->dev));
return PTR_ERR(cqr);
}
cqr->startdev = device;
@@ -840,7 +1003,8 @@ static int dasd_eckd_read_features(struct dasd_device *device)
/*
* Build CP for Perform Subsystem Function - SSC.
*/
-static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
+static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
+ int enable_pav)
{
struct dasd_ccw_req *cqr;
struct dasd_psf_ssc_data *psf_ssc_data;
@@ -851,15 +1015,17 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate PSF-SSC request");
return cqr;
}
psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
psf_ssc_data->order = PSF_ORDER_SSC;
- psf_ssc_data->suborder = 0x88;
- psf_ssc_data->reserved[0] = 0x88;
-
+ psf_ssc_data->suborder = 0x40;
+ if (enable_pav) {
+ psf_ssc_data->suborder |= 0x88;
+ psf_ssc_data->reserved[0] = 0x88;
+ }
ccw = cqr->cpaddr;
ccw->cmd_code = DASD_ECKD_CCW_PSF;
ccw->cda = (__u32)(addr_t)psf_ssc_data;
@@ -880,12 +1046,12 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
* call might change behaviour of DASD devices.
*/
static int
-dasd_eckd_psf_ssc(struct dasd_device *device)
+dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
{
struct dasd_ccw_req *cqr;
int rc;
- cqr = dasd_eckd_build_psf_ssc(device);
+ cqr = dasd_eckd_build_psf_ssc(device, enable_pav);
if (IS_ERR(cqr))
return PTR_ERR(cqr);
@@ -904,19 +1070,20 @@ static int dasd_eckd_validate_server(struct dasd_device *device)
{
int rc;
struct dasd_eckd_private *private;
+ int enable_pav;
- /* Currently PAV is the only reason to 'validate' server on LPAR */
if (dasd_nopav || MACHINE_IS_VM)
- return 0;
-
- rc = dasd_eckd_psf_ssc(device);
+ enable_pav = 0;
+ else
+ enable_pav = 1;
+ rc = dasd_eckd_psf_ssc(device, enable_pav);
/* may be requested feature is not available on server,
* therefore just report error and go ahead */
private = (struct dasd_eckd_private *) device->private;
- DEV_MESSAGE(KERN_INFO, device,
- "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d",
- private->uid.vendor, private->uid.serial,
- private->uid.ssid, rc);
+ DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x "
+ "returned rc=%d for device: %s",
+ private->uid.vendor, private->uid.serial,
+ private->uid.ssid, rc, dev_name(&device->cdev->dev));
/* RE-Read Configuration Data */
return dasd_eckd_read_conf(device);
}
@@ -938,9 +1105,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
private = kzalloc(sizeof(struct dasd_eckd_private),
GFP_KERNEL | GFP_DMA);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private "
- "data");
+ dev_warn(&device->cdev->dev,
+ "Allocating memory for private DASD data "
+ "failed\n");
return -ENOMEM;
}
device->private = (void *) private;
@@ -965,8 +1132,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
if (private->uid.type == UA_BASE_DEVICE) {
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "could not allocate dasd block structure");
+ DBF_EVENT(DBF_WARNING, "could not allocate dasd "
+ "block structure for device: %s",
+ dev_name(&device->cdev->dev));
rc = PTR_ERR(block);
goto out_err1;
}
@@ -997,20 +1165,27 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
memset(rdc_data, 0, sizeof(rdc_data));
rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Read device characteristics returned "
- "rc=%d", rc);
+ DBF_EVENT(DBF_WARNING,
+ "Read device characteristics failed, rc=%d for "
+ "device: %s", rc, dev_name(&device->cdev->dev));
goto out_err3;
}
- DEV_MESSAGE(KERN_INFO, device,
- "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
- private->rdc_data.dev_type,
- private->rdc_data.dev_model,
- private->rdc_data.cu_type,
- private->rdc_data.cu_model.model,
- private->rdc_data.no_cyl,
- private->rdc_data.trk_per_cyl,
- private->rdc_data.sec_per_trk);
+ /* find the vaild cylinder size */
+ if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
+ private->rdc_data.long_no_cyl)
+ private->real_cyl = private->rdc_data.long_no_cyl;
+ else
+ private->real_cyl = private->rdc_data.no_cyl;
+
+ dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
+ "with %d cylinders, %d heads, %d sectors\n",
+ private->rdc_data.dev_type,
+ private->rdc_data.dev_model,
+ private->rdc_data.cu_type,
+ private->rdc_data.cu_model.model,
+ private->real_cyl,
+ private->rdc_data.trk_per_cyl,
+ private->rdc_data.sec_per_trk);
return 0;
out_err3:
@@ -1151,14 +1326,12 @@ dasd_eckd_end_analysis(struct dasd_block *block)
status = private->init_cqr_status;
private->init_cqr_status = -1;
if (status != DASD_CQR_DONE) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "volume analysis returned unformatted disk");
+ dev_warn(&device->cdev->dev,
+ "The DASD is not formatted\n");
return -EMEDIUMTYPE;
}
private->uses_cdl = 1;
- /* Calculate number of blocks/records per track. */
- blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
/* Check Track 0 for Compatible Disk Layout */
count_area = NULL;
for (i = 0; i < 3; i++) {
@@ -1182,8 +1355,8 @@ dasd_eckd_end_analysis(struct dasd_block *block)
count_area = &private->count_area[0];
} else {
if (private->count_area[3].record == 1)
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Trk 0: no records after VTOC!");
+ dev_warn(&device->cdev->dev,
+ "Track 0 has no records following the VTOC\n");
}
if (count_area != NULL && count_area->kl == 0) {
/* we found notthing violating our disk layout */
@@ -1191,8 +1364,8 @@ dasd_eckd_end_analysis(struct dasd_block *block)
block->bp_block = count_area->dl;
}
if (block->bp_block == 0) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Volume has incompatible disk layout");
+ dev_warn(&device->cdev->dev,
+ "The disk layout of the DASD is not supported\n");
return -EMEDIUMTYPE;
}
block->s2b_shift = 0; /* bits to shift 512 to get a block */
@@ -1200,19 +1373,19 @@ dasd_eckd_end_analysis(struct dasd_block *block)
block->s2b_shift++;
blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
- block->blocks = (private->rdc_data.no_cyl *
+ block->blocks = (private->real_cyl *
private->rdc_data.trk_per_cyl *
blk_per_trk);
- DEV_MESSAGE(KERN_INFO, device,
- "(%dkB blks): %dkB at %dkB/trk %s",
- (block->bp_block >> 10),
- ((private->rdc_data.no_cyl *
- private->rdc_data.trk_per_cyl *
- blk_per_trk * (block->bp_block >> 9)) >> 1),
- ((blk_per_trk * block->bp_block) >> 10),
- private->uses_cdl ?
- "compatible disk layout" : "linux disk layout");
+ dev_info(&device->cdev->dev,
+ "DASD with %d KB/block, %d KB total size, %d KB/track, "
+ "%s\n", (block->bp_block >> 10),
+ ((private->real_cyl *
+ private->rdc_data.trk_per_cyl *
+ blk_per_trk * (block->bp_block >> 9)) >> 1),
+ ((blk_per_trk * block->bp_block) >> 10),
+ private->uses_cdl ?
+ "compatible disk layout" : "linux disk layout");
return 0;
}
@@ -1262,31 +1435,35 @@ dasd_eckd_format_device(struct dasd_device * device,
struct eckd_count *ect;
struct ccw1 *ccw;
void *data;
- int rpt, cyl, head;
+ int rpt;
+ struct ch_t address;
int cplength, datasize;
int i;
+ int intensity = 0;
+ int r0_perm;
private = (struct dasd_eckd_private *) device->private;
rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
- cyl = fdata->start_unit / private->rdc_data.trk_per_cyl;
- head = fdata->start_unit % private->rdc_data.trk_per_cyl;
+ set_ch_t(&address,
+ fdata->start_unit / private->rdc_data.trk_per_cyl,
+ fdata->start_unit % private->rdc_data.trk_per_cyl);
/* Sanity checks. */
if (fdata->start_unit >=
- (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)) {
- DEV_MESSAGE(KERN_INFO, device, "Track no %d too big!",
- fdata->start_unit);
+ (private->real_cyl * private->rdc_data.trk_per_cyl)) {
+ dev_warn(&device->cdev->dev, "Start track number %d used in "
+ "formatting is too big\n", fdata->start_unit);
return ERR_PTR(-EINVAL);
}
if (fdata->start_unit > fdata->stop_unit) {
- DEV_MESSAGE(KERN_INFO, device, "Track %d reached! ending.",
- fdata->start_unit);
+ dev_warn(&device->cdev->dev, "Start track %d used in "
+ "formatting exceeds end track\n", fdata->start_unit);
return ERR_PTR(-EINVAL);
}
if (dasd_check_blocksize(fdata->blksize) != 0) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Invalid blocksize %d...terminating!",
- fdata->blksize);
+ dev_warn(&device->cdev->dev,
+ "The DASD cannot be formatted with block size %d\n",
+ fdata->blksize);
return ERR_PTR(-EINVAL);
}
@@ -1296,9 +1473,17 @@ dasd_eckd_format_device(struct dasd_device * device,
* Bit 1: write home address, currently not supported
* Bit 2: invalidate tracks
* Bit 3: use OS/390 compatible disk layout (cdl)
+ * Bit 4: do not allow storage subsystem to modify record zero
* Only some bit combinations do make sense.
*/
- switch (fdata->intensity) {
+ if (fdata->intensity & 0x10) {
+ r0_perm = 0;
+ intensity = fdata->intensity & ~0x10;
+ } else {
+ r0_perm = 1;
+ intensity = fdata->intensity;
+ }
+ switch (intensity) {
case 0x00: /* Normal format */
case 0x08: /* Normal format, use cdl. */
cplength = 2 + rpt;
@@ -1322,8 +1507,8 @@ dasd_eckd_format_device(struct dasd_device * device,
sizeof(struct eckd_count);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
- fdata->intensity);
+ dev_warn(&device->cdev->dev, "An I/O control call used "
+ "incorrect flags 0x%x\n", fdata->intensity);
return ERR_PTR(-EINVAL);
}
/* Allocate the format ccw request. */
@@ -1335,11 +1520,14 @@ dasd_eckd_format_device(struct dasd_device * device,
data = fcp->data;
ccw = fcp->cpaddr;
- switch (fdata->intensity & ~0x08) {
+ switch (intensity & ~0x08) {
case 0x00: /* Normal format. */
define_extent(ccw++, (struct DE_eckd_data *) data,
fdata->start_unit, fdata->start_unit,
DASD_ECKD_CCW_WRITE_CKD, device);
+ /* grant subsystem permission to format R0 */
+ if (r0_perm)
+ ((struct DE_eckd_data *)data)->ga_extended |= 0x04;
data += sizeof(struct DE_eckd_data);
ccw[-1].flags |= CCW_FLAG_CC;
locate_record(ccw++, (struct LO_eckd_data *) data,
@@ -1373,11 +1561,11 @@ dasd_eckd_format_device(struct dasd_device * device,
data += sizeof(struct LO_eckd_data);
break;
}
- if (fdata->intensity & 0x01) { /* write record zero */
+ if (intensity & 0x01) { /* write record zero */
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = 0;
ect->kl = 0;
ect->dl = 8;
@@ -1388,11 +1576,11 @@ dasd_eckd_format_device(struct dasd_device * device,
ccw->cda = (__u32)(addr_t) ect;
ccw++;
}
- if ((fdata->intensity & ~0x08) & 0x04) { /* erase track */
+ if ((intensity & ~0x08) & 0x04) { /* erase track */
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = 1;
ect->kl = 0;
ect->dl = 0;
@@ -1405,20 +1593,20 @@ dasd_eckd_format_device(struct dasd_device * device,
for (i = 0; i < rpt; i++) {
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = i + 1;
ect->kl = 0;
ect->dl = fdata->blksize;
/* Check for special tracks 0-1 when formatting CDL */
- if ((fdata->intensity & 0x08) &&
+ if ((intensity & 0x08) &&
fdata->start_unit == 0) {
if (i < 3) {
ect->kl = 4;
ect->dl = sizes_trk0[i] - 4;
}
}
- if ((fdata->intensity & 0x08) &&
+ if ((intensity & 0x08) &&
fdata->start_unit == 1) {
ect->kl = 44;
ect->dl = LABEL_SIZE - 44;
@@ -1479,57 +1667,69 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
struct irb *irb)
{
char mask;
+ char *sense = NULL;
/* first of all check for state change pending interrupt */
mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
- if ((irb->scsw.cmd.dstat & mask) == mask) {
+ if ((scsw_dstat(&irb->scsw) & mask) == mask) {
dasd_generic_handle_state_change(device);
return;
}
/* summary unit check */
- if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
+ if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
(irb->ecw[7] == 0x0D)) {
dasd_alias_handle_summary_unit_check(device, irb);
return;
}
-
+ sense = dasd_get_sense(irb);
/* service information message SIM */
- if (irb->esw.esw0.erw.cons && !(irb->ecw[27] & DASD_SENSE_BIT_0) &&
- ((irb->ecw[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
- dasd_3990_erp_handle_sim(device, irb->ecw);
+ if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
+ ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
+ dasd_3990_erp_handle_sim(device, sense);
dasd_schedule_device_bh(device);
return;
}
- if ((irb->scsw.cmd.cc == 1) &&
- (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
- (irb->scsw.cmd.actl & SCSW_ACTL_START_PEND) &&
- (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND)) {
+ if ((scsw_cc(&irb->scsw) == 1) &&
+ (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+ (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) &&
+ (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) {
/* fake irb do nothing, they are handled elsewhere */
dasd_schedule_device_bh(device);
return;
}
- if (!(irb->esw.esw0.erw.cons)) {
+ if (!sense) {
/* just report other unsolicited interrupts */
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"unsolicited interrupt received");
} else {
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"unsolicited interrupt received "
"(sense available)");
- device->discipline->dump_sense(device, NULL, irb);
+ device->discipline->dump_sense_dbf(device, NULL, irb,
+ "unsolicited");
}
dasd_schedule_device_bh(device);
return;
};
-static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
+ struct dasd_device *startdev,
struct dasd_block *block,
- struct request *req)
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
{
struct dasd_eckd_private *private;
unsigned long *idaws;
@@ -1539,11 +1739,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
struct req_iterator iter;
struct bio_vec *bv;
char *dst;
- unsigned int blksize, blk_per_trk, off;
+ unsigned int off;
int count, cidaw, cplength, datasize;
- sector_t recid, first_rec, last_rec;
- sector_t first_trk, last_trk;
- unsigned int first_offs, last_offs;
+ sector_t recid;
unsigned char cmd, rcmd;
int use_prefix;
struct dasd_device *basedev;
@@ -1556,15 +1754,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
cmd = DASD_ECKD_CCW_WRITE_MT;
else
return ERR_PTR(-EINVAL);
- /* Calculate number of blocks/records per track. */
- blksize = block->bp_block;
- blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
- /* Calculate record id of first and last block. */
- first_rec = first_trk = req->sector >> block->s2b_shift;
- first_offs = sector_div(first_trk, blk_per_trk);
- last_rec = last_trk =
- (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
- last_offs = sector_div(last_trk, blk_per_trk);
+
/* Check struct bio and count the number of blocks for the request. */
count = 0;
cidaw = 0;
@@ -1714,6 +1904,497 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
return cqr;
}
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
+ struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
+{
+ struct dasd_eckd_private *private;
+ unsigned long *idaws;
+ struct dasd_ccw_req *cqr;
+ struct ccw1 *ccw;
+ struct req_iterator iter;
+ struct bio_vec *bv;
+ char *dst, *idaw_dst;
+ unsigned int cidaw, cplength, datasize;
+ unsigned int tlf;
+ sector_t recid;
+ unsigned char cmd;
+ struct dasd_device *basedev;
+ unsigned int trkcount, count, count_to_trk_end;
+ unsigned int idaw_len, seg_len, part_len, len_to_track_end;
+ unsigned char new_track, end_idaw;
+ sector_t trkid;
+ unsigned int recoffs;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+ if (rq_data_dir(req) == READ)
+ cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+ else if (rq_data_dir(req) == WRITE)
+ cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+ else
+ return ERR_PTR(-EINVAL);
+
+ /* Track based I/O needs IDAWs for each page, and not just for
+ * 64 bit addresses. We need additional idals for pages
+ * that get filled from two tracks, so we use the number
+ * of records as upper limit.
+ */
+ cidaw = last_rec - first_rec + 1;
+ trkcount = last_trk - first_trk + 1;
+
+ /* 1x prefix + one read/write ccw per track */
+ cplength = 1 + trkcount;
+
+ /* on 31-bit we need space for two 32 bit addresses per page
+ * on 64-bit one 64 bit address
+ */
+ datasize = sizeof(struct PFX_eckd_data) +
+ cidaw * sizeof(unsigned long long);
+
+ /* Allocate the ccw request. */
+ cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+ cplength, datasize, startdev);
+ if (IS_ERR(cqr))
+ return cqr;
+ ccw = cqr->cpaddr;
+ /* transfer length factor: how many bytes to read from the last track */
+ if (first_trk == last_trk)
+ tlf = last_offs - first_offs + 1;
+ else
+ tlf = last_offs + 1;
+ tlf *= blksize;
+
+ if (prefix_LRE(ccw++, cqr->data, first_trk,
+ last_trk, cmd, basedev, startdev,
+ 1 /* format */, first_offs + 1,
+ trkcount, blksize,
+ tlf) == -EAGAIN) {
+ /* Clock not in sync and XRC is enabled.
+ * Try again later.
+ */
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-EAGAIN);
+ }
+
+ /*
+ * The translation of request into ccw programs must meet the
+ * following conditions:
+ * - all idaws but the first and the last must address full pages
+ * (or 2K blocks on 31-bit)
+ * - the scope of a ccw and it's idal ends with the track boundaries
+ */
+ idaws = (unsigned long *) (cqr->data + sizeof(struct PFX_eckd_data));
+ recid = first_rec;
+ new_track = 1;
+ end_idaw = 0;
+ len_to_track_end = 0;
+ idaw_dst = 0;
+ idaw_len = 0;
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ seg_len = bv->bv_len;
+ while (seg_len) {
+ if (new_track) {
+ trkid = recid;
+ recoffs = sector_div(trkid, blk_per_trk);
+ count_to_trk_end = blk_per_trk - recoffs;
+ count = min((last_rec - recid + 1),
+ (sector_t)count_to_trk_end);
+ len_to_track_end = count * blksize;
+ ccw[-1].flags |= CCW_FLAG_CC;
+ ccw->cmd_code = cmd;
+ ccw->count = len_to_track_end;
+ ccw->cda = (__u32)(addr_t)idaws;
+ ccw->flags = CCW_FLAG_IDA;
+ ccw++;
+ recid += count;
+ new_track = 0;
+ }
+ /* If we start a new idaw, everything is fine and the
+ * start of the new idaw is the start of this segment.
+ * If we continue an idaw, we must make sure that the
+ * current segment begins where the so far accumulated
+ * idaw ends
+ */
+ if (!idaw_dst)
+ idaw_dst = dst;
+ if ((idaw_dst + idaw_len) != dst) {
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-ERANGE);
+ }
+ part_len = min(seg_len, len_to_track_end);
+ seg_len -= part_len;
+ dst += part_len;
+ idaw_len += part_len;
+ len_to_track_end -= part_len;
+ /* collected memory area ends on an IDA_BLOCK border,
+ * -> create an idaw
+ * idal_create_words will handle cases where idaw_len
+ * is larger then IDA_BLOCK_SIZE
+ */
+ if (!(__pa(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE-1)))
+ end_idaw = 1;
+ /* We also need to end the idaw at track end */
+ if (!len_to_track_end) {
+ new_track = 1;
+ end_idaw = 1;
+ }
+ if (end_idaw) {
+ idaws = idal_create_words(idaws, idaw_dst,
+ idaw_len);
+ idaw_dst = 0;
+ idaw_len = 0;
+ end_idaw = 0;
+ }
+ }
+ }
+
+ if (blk_noretry_request(req) ||
+ block->base->features & DASD_FEATURE_FAILFAST)
+ set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 5 * 60 * HZ; /* 5 minutes */
+ cqr->lpm = private->path_data.ppm;
+ cqr->retries = 256;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ return cqr;
+}
+
+static int prepare_itcw(struct itcw *itcw,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev,
+ struct dasd_device *startdev,
+ unsigned int rec_on_trk, int count,
+ unsigned int blksize,
+ unsigned int total_data_size,
+ unsigned int tlf,
+ unsigned int blk_per_trk)
+{
+ struct PFX_eckd_data pfxdata;
+ struct dasd_eckd_private *basepriv, *startpriv;
+ struct DE_eckd_data *dedata;
+ struct LRE_eckd_data *lredata;
+ struct dcw *dcw;
+
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
+ u8 pfx_cmd;
+
+ int rc = 0;
+ int sector = 0;
+ int dn, d;
+
+
+ /* setup prefix data */
+ basepriv = (struct dasd_eckd_private *) basedev->private;
+ startpriv = (struct dasd_eckd_private *) startdev->private;
+ dedata = &pfxdata.define_extent;
+ lredata = &pfxdata.locate_record;
+
+ memset(&pfxdata, 0, sizeof(pfxdata));
+ pfxdata.format = 1; /* PFX with LRE */
+ pfxdata.base_address = basepriv->ned->unit_addr;
+ pfxdata.base_lss = basepriv->ned->ID;
+ pfxdata.validity.define_extent = 1;
+
+ /* private uid is kept up to date, conf_data may be outdated */
+ if (startpriv->uid.type != UA_BASE_DEVICE) {
+ pfxdata.validity.verify_base = 1;
+ if (startpriv->uid.type == UA_HYPER_PAV_ALIAS)
+ pfxdata.validity.hyper_pav = 1;
+ }
+
+ switch (cmd) {
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ dedata->ga_extended |= 0x42;
+ lredata->operation.orientation = 0x0;
+ lredata->operation.operation = 0x0C;
+ lredata->auxiliary.check_bytes = 0x01;
+ pfx_cmd = DASD_ECKD_CCW_PFX_READ;
+ break;
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ rc = check_XRC_on_prefix(&pfxdata, basedev);
+ dedata->ga_extended |= 0x42;
+ lredata->operation.orientation = 0x0;
+ lredata->operation.operation = 0x3F;
+ lredata->extended_operation = 0x23;
+ lredata->auxiliary.check_bytes = 0x2;
+ pfx_cmd = DASD_ECKD_CCW_PFX;
+ break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "prepare itcw, unknown opcode 0x%x", cmd);
+ BUG();
+ break;
+ }
+ if (rc)
+ return rc;
+
+ dedata->attributes.mode = 0x3; /* ECKD */
+
+ heads = basepriv->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
+
+ /* check for sequential prestage - enhance cylinder range */
+ if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+ dedata->attributes.operation == DASD_SEQ_ACCESS) {
+
+ if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+ endcyl += basepriv->attrib.nr_cyl;
+ else
+ endcyl = (basepriv->real_cyl - 1);
+ }
+
+ set_ch_t(&dedata->beg_ext, begcyl, beghead);
+ set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+ dedata->ep_format = 0x20; /* records per track is valid */
+ dedata->ep_rec_per_track = blk_per_trk;
+
+ if (rec_on_trk) {
+ switch (basepriv->rdc_data.dev_type) {
+ case 0x3390:
+ dn = ceil_quot(blksize + 6, 232);
+ d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);
+ sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+ break;
+ case 0x3380:
+ d = 7 + ceil_quot(blksize + 12, 32);
+ sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+ break;
+ }
+ }
+
+ lredata->auxiliary.length_valid = 1;
+ lredata->auxiliary.length_scope = 1;
+ lredata->auxiliary.imbedded_ccw_valid = 1;
+ lredata->length = tlf;
+ lredata->imbedded_ccw = cmd;
+ lredata->count = count;
+ lredata->sector = sector;
+ set_ch_t(&lredata->seek_addr, begcyl, beghead);
+ lredata->search_arg.cyl = lredata->seek_addr.cyl;
+ lredata->search_arg.head = lredata->seek_addr.head;
+ lredata->search_arg.record = rec_on_trk;
+
+ dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
+ &pfxdata, sizeof(pfxdata), total_data_size);
+
+ return rc;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
+ struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
+{
+ struct dasd_eckd_private *private;
+ struct dasd_ccw_req *cqr;
+ struct req_iterator iter;
+ struct bio_vec *bv;
+ char *dst;
+ unsigned int trkcount, ctidaw;
+ unsigned char cmd;
+ struct dasd_device *basedev;
+ unsigned int tlf;
+ struct itcw *itcw;
+ struct tidaw *last_tidaw = NULL;
+ int itcw_op;
+ size_t itcw_size;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+ if (rq_data_dir(req) == READ) {
+ cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+ itcw_op = ITCW_OP_READ;
+ } else if (rq_data_dir(req) == WRITE) {
+ cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+ itcw_op = ITCW_OP_WRITE;
+ } else
+ return ERR_PTR(-EINVAL);
+
+ /* trackbased I/O needs address all memory via TIDAWs,
+ * not just for 64 bit addresses. This allows us to map
+ * each segment directly to one tidaw.
+ */
+ trkcount = last_trk - first_trk + 1;
+ ctidaw = 0;
+ rq_for_each_segment(bv, req, iter) {
+ ++ctidaw;
+ }
+
+ /* Allocate the ccw request. */
+ itcw_size = itcw_calc_size(0, ctidaw, 0);
+ cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+ 0, itcw_size, startdev);
+ if (IS_ERR(cqr))
+ return cqr;
+
+ cqr->cpmode = 1;
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 100*HZ;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ cqr->retries = 10;
+
+ /* transfer length factor: how many bytes to read from the last track */
+ if (first_trk == last_trk)
+ tlf = last_offs - first_offs + 1;
+ else
+ tlf = last_offs + 1;
+ tlf *= blksize;
+
+ itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
+ cqr->cpaddr = itcw_get_tcw(itcw);
+
+ if (prepare_itcw(itcw, first_trk, last_trk,
+ cmd, basedev, startdev,
+ first_offs + 1,
+ trkcount, blksize,
+ (last_rec - first_rec + 1) * blksize,
+ tlf, blk_per_trk) == -EAGAIN) {
+ /* Clock not in sync and XRC is enabled.
+ * Try again later.
+ */
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-EAGAIN);
+ }
+
+ /*
+ * A tidaw can address 4k of memory, but must not cross page boundaries
+ * We can let the block layer handle this by setting
+ * blk_queue_segment_boundary to page boundaries and
+ * blk_max_segment_size to page size when setting up the request queue.
+ */
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len);
+ if (IS_ERR(last_tidaw))
+ return (struct dasd_ccw_req *)last_tidaw;
+ }
+
+ last_tidaw->flags |= 0x80;
+ itcw_finalize(itcw);
+
+ if (blk_noretry_request(req) ||
+ block->base->features & DASD_FEATURE_FAILFAST)
+ set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 5 * 60 * HZ; /* 5 minutes */
+ cqr->lpm = private->path_data.ppm;
+ cqr->retries = 256;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ return cqr;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req)
+{
+ int tpm, cmdrtd, cmdwtd;
+ int use_prefix;
+
+ struct dasd_eckd_private *private;
+ int fcx_in_css, fcx_in_gneq, fcx_in_features;
+ struct dasd_device *basedev;
+ sector_t first_rec, last_rec;
+ sector_t first_trk, last_trk;
+ unsigned int first_offs, last_offs;
+ unsigned int blk_per_trk, blksize;
+ int cdlspecial;
+ struct dasd_ccw_req *cqr;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+
+ /* Calculate number of blocks/records per track. */
+ blksize = block->bp_block;
+ blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
+ /* Calculate record id of first and last block. */
+ first_rec = first_trk = req->sector >> block->s2b_shift;
+ first_offs = sector_div(first_trk, blk_per_trk);
+ last_rec = last_trk =
+ (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
+ last_offs = sector_div(last_trk, blk_per_trk);
+ cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
+
+ /* is transport mode supported ? */
+ fcx_in_css = css_general_characteristics.fcx;
+ fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
+ fcx_in_features = private->features.feature[40] & 0x80;
+ tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
+
+ /* is read track data and write track data in command mode supported? */
+ cmdrtd = private->features.feature[9] & 0x20;
+ cmdwtd = private->features.feature[12] & 0x40;
+ use_prefix = private->features.feature[8] & 0x01;
+
+ cqr = NULL;
+ if (cdlspecial || dasd_page_cache) {
+ /* do nothing, just fall through to the cmd mode single case */
+ } else if (!dasd_nofcx && tpm && (first_trk == last_trk)) {
+ cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ cqr = NULL;
+ } else if (use_prefix &&
+ (((rq_data_dir(req) == READ) && cmdrtd) ||
+ ((rq_data_dir(req) == WRITE) && cmdwtd))) {
+ cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ cqr = NULL;
+ }
+ if (!cqr)
+ cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ return cqr;
+}
+
static int
dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
{
@@ -1767,7 +2448,7 @@ out:
}
/*
- * Modify ccw chain in cqr so it can be started on a base device.
+ * Modify ccw/tcw in cqr so it can be started on a base device.
*
* Note that this is not enough to restart the cqr!
* Either reset cqr->startdev as well (summary unit check handling)
@@ -1777,13 +2458,24 @@ void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *cqr)
{
struct ccw1 *ccw;
struct PFX_eckd_data *pfxdata;
-
- ccw = cqr->cpaddr;
- pfxdata = cqr->data;
-
- if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+ struct tcw *tcw;
+ struct tccb *tccb;
+ struct dcw *dcw;
+
+ if (cqr->cpmode == 1) {
+ tcw = cqr->cpaddr;
+ tccb = tcw_get_tccb(tcw);
+ dcw = (struct dcw *)&tccb->tca[0];
+ pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];
pfxdata->validity.verify_base = 0;
pfxdata->validity.hyper_pav = 0;
+ } else {
+ ccw = cqr->cpaddr;
+ pfxdata = cqr->data;
+ if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+ pfxdata->validity.verify_base = 0;
+ pfxdata->validity.hyper_pav = 0;
+ }
}
}
@@ -1861,6 +2553,7 @@ dasd_eckd_release(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1868,14 +2561,15 @@ dasd_eckd_release(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1902,6 +2596,7 @@ dasd_eckd_reserve(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1909,14 +2604,15 @@ dasd_eckd_reserve(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1942,6 +2638,7 @@ dasd_eckd_steal_lock(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1949,14 +2646,15 @@ dasd_eckd_steal_lock(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_SLCK;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1990,7 +2688,7 @@ dasd_eckd_performance(struct dasd_device *device, void __user *argp)
sizeof(struct dasd_rssd_perf_stats_t)),
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
@@ -2080,9 +2778,9 @@ dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
return -EFAULT;
private->attrib = attrib;
- DEV_MESSAGE(KERN_INFO, device,
- "cache operation mode set to %x (%i cylinder prestage)",
- private->attrib.operation, private->attrib.nr_cyl);
+ dev_info(&device->cdev->dev,
+ "The DASD cache mode was set to %x (%i cylinder prestage)\n",
+ private->attrib.operation, private->attrib.nr_cyl);
return 0;
}
@@ -2133,7 +2831,7 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
/* setup CCWs for PSF + RSSD */
cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
rc = PTR_ERR(cqr);
goto out_free;
@@ -2242,11 +2940,54 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
return len;
}
+static void
+dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+ struct irb *irb, char *reason)
+{
+ u64 *sense;
+ int sl;
+ struct tsb *tsb;
+
+ sense = NULL;
+ tsb = NULL;
+ if (req && scsw_is_tm(&req->irb.scsw)) {
+ if (irb->scsw.tm.tcw)
+ tsb = tcw_get_tsb(
+ (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
+ if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+ switch (tsb->flags & 0x07) {
+ case 1: /* tsa_iostat */
+ sense = (u64 *)tsb->tsa.iostat.sense;
+ break;
+ case 2: /* ts_ddpc */
+ sense = (u64 *)tsb->tsa.ddpc.sense;
+ break;
+ case 3: /* tsa_intrg */
+ break;
+ }
+ }
+ } else {
+ if (irb->esw.esw0.erw.cons)
+ sense = (u64 *)irb->ecw;
+ }
+ if (sense) {
+ for (sl = 0; sl < 4; sl++) {
+ DBF_DEV_EVENT(DBF_EMERG, device,
+ "%s: %016llx %016llx %016llx %016llx",
+ reason, sense[0], sense[1], sense[2],
+ sense[3]);
+ }
+ } else {
+ DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+ "SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+}
+
/*
* Print sense data and related channel program.
* Parts are printed because printk buffer is only 1024 bytes.
*/
-static void dasd_eckd_dump_sense(struct dasd_device *device,
+static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
struct dasd_ccw_req *req, struct irb *irb)
{
char *page;
@@ -2255,8 +2996,8 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
page = (char *) get_zeroed_page(GFP_ATOMIC);
if (page == NULL) {
- DEV_MESSAGE(KERN_ERR, device, " %s",
- "No memory to dump sense data");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "No memory to dump sense data\n");
return;
}
/* dump the sense data */
@@ -2265,7 +3006,7 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" in req: %p CS: 0x%02X DS: 0x%02X\n", req,
- irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
+ scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing CCW: %p\n",
dev_name(&device->cdev->dev),
@@ -2341,6 +3082,147 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
free_page((unsigned long) page);
}
+
+/*
+ * Print sense data from a tcw.
+ */
+static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
+ struct dasd_ccw_req *req, struct irb *irb)
+{
+ char *page;
+ int len, sl, sct, residual;
+
+ struct tsb *tsb;
+ u8 *sense;
+
+
+ page = (char *) get_zeroed_page(GFP_ATOMIC);
+ if (page == NULL) {
+ DBF_DEV_EVENT(DBF_WARNING, device, " %s",
+ "No memory to dump sense data");
+ return;
+ }
+ /* dump the sense data */
+ len = sprintf(page, KERN_ERR PRINTK_HEADER
+ " I/O status report for device %s:\n",
+ dev_name(&device->cdev->dev));
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " in req: %p CS: 0x%02X DS: 0x%02X "
+ "fcxs: 0x%02X schxs: 0x%02X\n", req,
+ scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
+ irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " device %s: Failing TCW: %p\n",
+ dev_name(&device->cdev->dev),
+ (void *) (addr_t) irb->scsw.tm.tcw);
+
+ tsb = NULL;
+ sense = NULL;
+ if (irb->scsw.tm.tcw)
+ tsb = tcw_get_tsb(
+ (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
+
+ if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->length %d\n", tsb->length);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->flags %x\n", tsb->flags);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->dcw_offset %d\n", tsb->dcw_offset);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->count %d\n", tsb->count);
+ residual = tsb->count - 28;
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " residual %d\n", residual);
+
+ switch (tsb->flags & 0x07) {
+ case 1: /* tsa_iostat */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_time %d\n",
+ tsb->tsa.iostat.dev_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.def_time %d\n",
+ tsb->tsa.iostat.def_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.queue_time %d\n",
+ tsb->tsa.iostat.queue_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_busy_time %d\n",
+ tsb->tsa.iostat.dev_busy_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_act_time %d\n",
+ tsb->tsa.iostat.dev_act_time);
+ sense = tsb->tsa.iostat.sense;
+ break;
+ case 2: /* ts_ddpc */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.ddpc.rcq: ");
+ for (sl = 0; sl < 16; sl++) {
+ for (sct = 0; sct < 8; sct++) {
+ len += sprintf(page + len, " %02x",
+ tsb->tsa.ddpc.rcq[sl]);
+ }
+ len += sprintf(page + len, "\n");
+ }
+ sense = tsb->tsa.ddpc.sense;
+ break;
+ case 3: /* tsa_intrg */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.intrg.: not supportet yet \n");
+ break;
+ }
+
+ if (sense) {
+ for (sl = 0; sl < 4; sl++) {
+ len += sprintf(page + len,
+ KERN_ERR PRINTK_HEADER
+ " Sense(hex) %2d-%2d:",
+ (8 * sl), ((8 * sl) + 7));
+ for (sct = 0; sct < 8; sct++) {
+ len += sprintf(page + len, " %02x",
+ sense[8 * sl + sct]);
+ }
+ len += sprintf(page + len, "\n");
+ }
+
+ if (sense[27] & DASD_SENSE_BIT_0) {
+ /* 24 Byte Sense Data */
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " 24 Byte: %x MSG %x, "
+ "%s MSGb to SYSOP\n",
+ sense[7] >> 4, sense[7] & 0x0f,
+ sense[1] & 0x10 ? "" : "no");
+ } else {
+ /* 32 Byte Sense Data */
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " 32 Byte: Format: %x "
+ "Exception class %x\n",
+ sense[6] & 0x0f, sense[22] >> 4);
+ }
+ } else {
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+ } else {
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " SORRY - NO TSB DATA AVAILABLE\n");
+ }
+ printk("%s", page);
+ free_page((unsigned long) page);
+}
+
+static void dasd_eckd_dump_sense(struct dasd_device *device,
+ struct dasd_ccw_req *req, struct irb *irb)
+{
+ if (req && scsw_is_tm(&req->irb.scsw))
+ dasd_eckd_dump_sense_tcw(device, req, irb);
+ else
+ dasd_eckd_dump_sense_ccw(device, req, irb);
+}
+
+
/*
* max_blocks is dependent on the amount of storage that is available
* in the static io buffer for each device. Currently each device has
@@ -2375,6 +3257,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
.build_cp = dasd_eckd_build_alias_cp,
.free_cp = dasd_eckd_free_alias_cp,
.dump_sense = dasd_eckd_dump_sense,
+ .dump_sense_dbf = dasd_eckd_dump_sense_dbf,
.fill_info = dasd_eckd_fill_info,
.ioctl = dasd_eckd_ioctl,
};
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 2476f87d21d..ad45bcac3ce 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -38,8 +38,11 @@
#define DASD_ECKD_CCW_RELEASE 0x94
#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
+#define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5
+#define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6
#define DASD_ECKD_CCW_RESERVE 0xB4
#define DASD_ECKD_CCW_PFX 0xE7
+#define DASD_ECKD_CCW_PFX_READ 0xEA
#define DASD_ECKD_CCW_RSCK 0xF9
/*
@@ -48,6 +51,11 @@
#define PSF_ORDER_PRSSD 0x18
#define PSF_ORDER_SSC 0x1D
+/*
+ * Size that is reportet for large volumes in the old 16-bit no_cyl field
+ */
+#define LV_COMPAT_CYL 0xFFFE
+
/*****************************************************************************
* SECTION: Type Definitions
****************************************************************************/
@@ -118,7 +126,9 @@ struct DE_eckd_data {
unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
__u8 ep_format; /* Extended Parameter format byte */
__u8 ep_prio; /* Extended Parameter priority I/O byte */
- __u8 ep_reserved[6]; /* Extended Parameter Reserved */
+ __u8 ep_reserved1; /* Extended Parameter Reserved */
+ __u8 ep_rec_per_track; /* Number of records on a track */
+ __u8 ep_reserved[4]; /* Extended Parameter Reserved */
} __attribute__ ((packed));
struct LO_eckd_data {
@@ -139,11 +149,37 @@ struct LO_eckd_data {
__u16 length;
} __attribute__ ((packed));
+struct LRE_eckd_data {
+ struct {
+ unsigned char orientation:2;
+ unsigned char operation:6;
+ } __attribute__ ((packed)) operation;
+ struct {
+ unsigned char length_valid:1;
+ unsigned char length_scope:1;
+ unsigned char imbedded_ccw_valid:1;
+ unsigned char check_bytes:2;
+ unsigned char imbedded_count_valid:1;
+ unsigned char reserved:1;
+ unsigned char read_count_suffix:1;
+ } __attribute__ ((packed)) auxiliary;
+ __u8 imbedded_ccw;
+ __u8 count;
+ struct ch_t seek_addr;
+ struct chr_t search_arg;
+ __u8 sector;
+ __u16 length;
+ __u8 imbedded_count;
+ __u8 extended_operation;
+ __u16 extended_parameter_length;
+ __u8 extended_parameter[0];
+} __attribute__ ((packed));
+
/* Prefix data for format 0x00 and 0x01 */
struct PFX_eckd_data {
unsigned char format;
struct {
- unsigned char define_extend:1;
+ unsigned char define_extent:1;
unsigned char time_stamp:1;
unsigned char verify_base:1;
unsigned char hyper_pav:1;
@@ -153,9 +189,8 @@ struct PFX_eckd_data {
__u8 aux;
__u8 base_lss;
__u8 reserved[7];
- struct DE_eckd_data define_extend;
- struct LO_eckd_data locate_record;
- __u8 LO_extended_data[4];
+ struct DE_eckd_data define_extent;
+ struct LRE_eckd_data locate_record;
} __attribute__ ((packed));
struct dasd_eckd_characteristics {
@@ -228,7 +263,8 @@ struct dasd_eckd_characteristics {
__u8 factor7;
__u8 factor8;
__u8 reserved2[3];
- __u8 reserved3[10];
+ __u8 reserved3[6];
+ __u32 long_no_cyl;
} __attribute__ ((packed));
/* elements of the configuration data */
@@ -406,6 +442,7 @@ struct dasd_eckd_private {
int uses_cdl;
struct attrib_data_t attrib; /* e.g. cache operations */
struct dasd_rssd_features features;
+ u32 real_cyl;
/* alias managemnet */
struct dasd_uid uid;
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index f8e05ce9862..c24c8c30380 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -6,6 +6,8 @@
* Author(s): Stefan Weinhuber <wein@de.ibm.com>
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/kernel.h>
@@ -297,11 +299,12 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
struct dasd_eer_header header;
unsigned long flags;
struct eerbuffer *eerb;
+ char *sense;
/* go through cqr chain and count the valid sense data sets */
data_size = 0;
for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
- if (temp_cqr->irb.esw.esw0.erw.cons)
+ if (dasd_get_sense(&temp_cqr->irb))
data_size += 32;
header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
@@ -316,9 +319,11 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
list_for_each_entry(eerb, &bufferlist, list) {
dasd_eer_start_record(eerb, header.total_size);
dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header));
- for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
- if (temp_cqr->irb.esw.esw0.erw.cons)
- dasd_eer_write_buffer(eerb, cqr->irb.ecw, 32);
+ for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) {
+ sense = dasd_get_sense(&temp_cqr->irb);
+ if (sense)
+ dasd_eer_write_buffer(eerb, sense, 32);
+ }
dasd_eer_write_buffer(eerb, "EOR", 4);
}
spin_unlock_irqrestore(&bufferlock, flags);
@@ -451,6 +456,7 @@ int dasd_eer_enable(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
unsigned long flags;
+ struct ccw1 *ccw;
if (device->eer_cqr)
return 0;
@@ -468,10 +474,11 @@ int dasd_eer_enable(struct dasd_device *device)
cqr->expires = 10 * HZ;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS;
- cqr->cpaddr->count = SNSS_DATA_SIZE;
- cqr->cpaddr->flags = 0;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_SNSS;
+ ccw->count = SNSS_DATA_SIZE;
+ ccw->flags = 0;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
@@ -534,7 +541,7 @@ static int dasd_eer_open(struct inode *inp, struct file *filp)
if (eerb->buffer_page_count < 1 ||
eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
kfree(eerb);
- MESSAGE(KERN_WARNING, "can't open device since module "
+ DBF_EVENT(DBF_WARNING, "can't open device since module "
"parameter eer_pages is smaller than 1 or"
" bigger than %d", (int)(INT_MAX / PAGE_SIZE));
unlock_kernel();
@@ -687,7 +694,7 @@ int __init dasd_eer_init(void)
if (rc) {
kfree(dasd_eer_dev);
dasd_eer_dev = NULL;
- MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
+ DBF_EVENT(DBF_ERR, "%s", "dasd_eer_init could not "
"register misc device");
return rc;
}
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 8f10000851a..d970ce2814b 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -9,6 +9,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/ctype.h>
#include <linux/init.h>
@@ -91,14 +93,14 @@ dasd_default_erp_action(struct dasd_ccw_req *cqr)
/* just retry - there is nothing to save ... I got no sense data.... */
if (cqr->retries > 0) {
- DEV_MESSAGE (KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"default ERP called (%i retries left)",
cqr->retries);
cqr->lpm = LPM_ANYPATH;
cqr->status = DASD_CQR_FILLED;
} else {
- DEV_MESSAGE (KERN_WARNING, device, "%s",
- "default ERP called (NO retry left)");
+ dev_err(&device->cdev->dev,
+ "default ERP has run out of retries and failed\n");
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock();
}
@@ -162,8 +164,21 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
device->discipline->dump_sense(device, cqr, irb);
}
+void
+dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb)
+{
+ struct dasd_device *device;
+
+ device = cqr->startdev;
+ /* dump sense data to s390 debugfeature*/
+ if (device->discipline && device->discipline->dump_sense_dbf)
+ device->discipline->dump_sense_dbf(device, cqr, irb, "log");
+}
+EXPORT_SYMBOL(dasd_log_sense_dbf);
+
EXPORT_SYMBOL(dasd_default_erp_action);
EXPORT_SYMBOL(dasd_default_erp_postaction);
EXPORT_SYMBOL(dasd_alloc_erp_request);
EXPORT_SYMBOL(dasd_free_erp_request);
EXPORT_SYMBOL(dasd_log_sense);
+
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index f1d17602169..a3eb6fd1467 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -6,6 +6,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <asm/debug.h>
@@ -128,17 +130,18 @@ dasd_fba_check_characteristics(struct dasd_device *device)
private = kzalloc(sizeof(struct dasd_fba_private),
GFP_KERNEL | GFP_DMA);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private "
- "data");
+ dev_warn(&device->cdev->dev,
+ "Allocating memory for private DASD "
+ "data failed\n");
return -ENOMEM;
}
device->private = (void *) private;
}
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "could not allocate dasd block structure");
+ DBF_EVENT(DBF_WARNING, "could not allocate dasd block "
+ "structure for device: %s",
+ dev_name(&device->cdev->dev));
device->private = NULL;
kfree(private);
return PTR_ERR(block);
@@ -150,9 +153,9 @@ dasd_fba_check_characteristics(struct dasd_device *device)
rdc_data = (void *) &(private->rdc_data);
rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Read device characteristics returned error %d",
- rc);
+ DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
+ "error %d for device: %s",
+ rc, dev_name(&device->cdev->dev));
device->block = NULL;
dasd_free_block(block);
device->private = NULL;
@@ -160,15 +163,16 @@ dasd_fba_check_characteristics(struct dasd_device *device)
return rc;
}
- DEV_MESSAGE(KERN_INFO, device,
- "%04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)",
- cdev->id.dev_type,
- cdev->id.dev_model,
- cdev->id.cu_type,
- cdev->id.cu_model,
- ((private->rdc_data.blk_bdsa *
- (private->rdc_data.blk_size >> 9)) >> 11),
- private->rdc_data.blk_size);
+ dev_info(&device->cdev->dev,
+ "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
+ "and %d B/blk\n",
+ cdev->id.dev_type,
+ cdev->id.dev_model,
+ cdev->id.cu_type,
+ cdev->id.cu_model,
+ ((private->rdc_data.blk_bdsa *
+ (private->rdc_data.blk_size >> 9)) >> 11),
+ private->rdc_data.blk_size);
return 0;
}
@@ -180,7 +184,7 @@ static int dasd_fba_do_analysis(struct dasd_block *block)
private = (struct dasd_fba_private *) block->base->private;
rc = dasd_check_blocksize(private->rdc_data.blk_size);
if (rc) {
- DEV_MESSAGE(KERN_INFO, block->base, "unknown blocksize %d",
+ DBF_DEV_EVENT(DBF_WARNING, block->base, "unknown blocksize %d",
private->rdc_data.blk_size);
return rc;
}
@@ -215,7 +219,7 @@ dasd_fba_erp_postaction(struct dasd_ccw_req * cqr)
if (cqr->function == dasd_default_erp_action)
return dasd_default_erp_postaction;
- DEV_MESSAGE(KERN_WARNING, cqr->startdev, "unknown ERP action %p",
+ DBF_DEV_EVENT(DBF_WARNING, cqr->startdev, "unknown ERP action %p",
cqr->function);
return NULL;
}
@@ -233,9 +237,9 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device,
}
/* check for unsolicited interrupts */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"unsolicited interrupt received");
- device->discipline->dump_sense(device, NULL, irb);
+ device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited");
dasd_schedule_device_bh(device);
return;
};
@@ -437,6 +441,25 @@ dasd_fba_fill_info(struct dasd_device * device,
}
static void
+dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+ struct irb *irb, char *reason)
+{
+ int sl;
+ if (irb->esw.esw0.erw.cons) {
+ for (sl = 0; sl < 4; sl++) {
+ DBF_DEV_EVENT(DBF_EMERG, device,
+ "%s: %08x %08x %08x %08x",
+ reason, irb->ecw[8 * 0], irb->ecw[8 * 1],
+ irb->ecw[8 * 2], irb->ecw[8 * 3]);
+ }
+ } else {
+ DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+ "SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+}
+
+
+static void
dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
struct irb *irb)
{
@@ -446,7 +469,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
page = (char *) get_zeroed_page(GFP_ATOMIC);
if (page == NULL) {
- DEV_MESSAGE(KERN_ERR, device, " %s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"No memory to dump sense data");
return;
}
@@ -476,8 +499,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" SORRY - NO VALID SENSE AVAILABLE\n");
}
- MESSAGE_LOG(KERN_ERR, "%s",
- page + sizeof(KERN_ERR PRINTK_HEADER));
+ printk(KERN_ERR "%s", page);
/* dump the Channel Program */
/* print first CCWs (maximum 8) */
@@ -498,8 +520,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
len += sprintf(page + len, "\n");
act++;
}
- MESSAGE_LOG(KERN_ERR, "%s",
- page + sizeof(KERN_ERR PRINTK_HEADER));
+ printk(KERN_ERR "%s", page);
/* print failing CCW area */
@@ -540,8 +561,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
act++;
}
if (len > 0)
- MESSAGE_LOG(KERN_ERR, "%s",
- page + sizeof(KERN_ERR PRINTK_HEADER));
+ printk(KERN_ERR "%s", page);
free_page((unsigned long) page);
}
@@ -576,6 +596,7 @@ static struct dasd_discipline dasd_fba_discipline = {
.build_cp = dasd_fba_build_cp,
.free_cp = dasd_fba_free_cp,
.dump_sense = dasd_fba_dump_sense,
+ .dump_sense_dbf = dasd_fba_dump_sense_dbf,
.fill_info = dasd_fba_fill_info,
};
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index e99d566b69c..d3198303b93 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -11,6 +11,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/blkpg.h>
@@ -163,9 +165,8 @@ int dasd_gendisk_init(void)
/* Register to static dasd major 94 */
rc = register_blkdev(DASD_MAJOR, "dasd");
if (rc != 0) {
- MESSAGE(KERN_WARNING,
- "Couldn't register successfully to "
- "major no %d", DASD_MAJOR);
+ pr_warning("Registering the device driver with major number "
+ "%d failed\n", DASD_MAJOR);
return rc;
}
return 0;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 4a39084d9c9..c1e487f774c 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -112,6 +112,9 @@ do { \
d_data); \
} while(0)
+/* limit size for an errorstring */
+#define ERRORLENGTH 30
+
/* definition of dbf debug levels */
#define DBF_EMERG 0 /* system is unusable */
#define DBF_ALERT 1 /* action must be taken immediately */
@@ -157,7 +160,8 @@ struct dasd_ccw_req {
struct dasd_block *block; /* the originating block device */
struct dasd_device *memdev; /* the device used to allocate this */
struct dasd_device *startdev; /* device the request is started on */
- struct ccw1 *cpaddr; /* address of channel program */
+ void *cpaddr; /* address of ccw or tcw */
+ unsigned char cpmode; /* 0 = cmd mode, 1 = itcw */
char status; /* status of this request */
short retries; /* A retry counter */
unsigned long flags; /* flags of this request */
@@ -280,6 +284,8 @@ struct dasd_discipline {
dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
struct irb *);
+ void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *,
+ struct irb *, char *);
void (*handle_unsolicited_interrupt) (struct dasd_device *,
struct irb *);
@@ -378,7 +384,7 @@ struct dasd_block {
struct block_device *bdev;
atomic_t open_count;
- unsigned long blocks; /* size of volume in blocks */
+ unsigned long long blocks; /* size of volume in blocks */
unsigned int bp_block; /* bytes per block */
unsigned int s2b_shift; /* log2 (bp_block/512) */
@@ -573,12 +579,14 @@ int dasd_generic_notify(struct ccw_device *, int);
void dasd_generic_handle_state_change(struct dasd_device *);
int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
+char *dasd_get_sense(struct irb *);
/* externals in dasd_devmap.c */
extern int dasd_max_devindex;
extern int dasd_probeonly;
extern int dasd_autodetect;
extern int dasd_nopav;
+extern int dasd_nofcx;
int dasd_devmap_init(void);
void dasd_devmap_exit(void);
@@ -623,6 +631,7 @@ struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
struct dasd_device *);
void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
+void dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb);
/* externals in dasd_3990_erp.c */
struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *);
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index b82d816d9ef..4ce3f72ee1c 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -9,6 +9,9 @@
*
* i/o controls for the dasd driver.
*/
+
+#define KMSG_COMPONENT "dasd"
+
#include <linux/interrupt.h>
#include <linux/major.h>
#include <linux/fs.h>
@@ -94,7 +97,8 @@ static int dasd_ioctl_quiesce(struct dasd_block *block)
if (!capable (CAP_SYS_ADMIN))
return -EACCES;
- DEV_MESSAGE(KERN_DEBUG, base, "%s", "Quiesce IO on device");
+ dev_info(&base->cdev->dev, "The DASD has been put in the quiesce "
+ "state\n");
spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
base->stopped |= DASD_STOPPED_QUIESCE;
spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -103,7 +107,7 @@ static int dasd_ioctl_quiesce(struct dasd_block *block)
/*
- * Quiesce device.
+ * Resume device.
*/
static int dasd_ioctl_resume(struct dasd_block *block)
{
@@ -114,7 +118,8 @@ static int dasd_ioctl_resume(struct dasd_block *block)
if (!capable (CAP_SYS_ADMIN))
return -EACCES;
- DEV_MESSAGE(KERN_DEBUG, base, "%s", "resume IO on device");
+ dev_info(&base->cdev->dev, "I/O operations have been resumed "
+ "on the DASD\n");
spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
base->stopped &= ~DASD_STOPPED_QUIESCE;
spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -140,13 +145,13 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
return -EPERM;
if (base->state != DASD_STATE_BASIC) {
- DEV_MESSAGE(KERN_WARNING, base, "%s",
- "dasd_format: device is not disabled! ");
+ dev_warn(&base->cdev->dev,
+ "The DASD cannot be formatted while it is enabled\n");
return -EBUSY;
}
DBF_DEV_EVENT(DBF_NOTICE, base,
- "formatting units %d to %d (%d B blocks) flags %d",
+ "formatting units %u to %u (%u B blocks) flags %u",
fdata->start_unit,
fdata->stop_unit, fdata->blksize, fdata->intensity);
@@ -169,10 +174,9 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
dasd_sfree_request(cqr, cqr->memdev);
if (rc) {
if (rc != -ERESTARTSYS)
- DEV_MESSAGE(KERN_ERR, base,
- " Formatting of unit %d failed "
- "with rc = %d",
- fdata->start_unit, rc);
+ dev_err(&base->cdev->dev,
+ "Formatting unit %d failed with "
+ "rc=%d\n", fdata->start_unit, rc);
return rc;
}
fdata->start_unit++;
@@ -199,8 +203,9 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp)
if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
return -EFAULT;
if (bdev != bdev->bd_contains) {
- DEV_MESSAGE(KERN_WARNING, block->base, "%s",
- "Cannot low-level format a partition");
+ dev_warn(&block->base->cdev->dev,
+ "The specified DASD is a partition and cannot be "
+ "formatted\n");
return -EINVAL;
}
return dasd_format(block, &fdata);
@@ -365,9 +370,9 @@ static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd,
return ret;
}
-int
-dasd_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
+static int
+dasd_do_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
{
struct dasd_block *block = bdev->bd_disk->private_data;
void __user *argp = (void __user *)arg;
@@ -420,3 +425,14 @@ dasd_ioctl(struct block_device *bdev, fmode_t mode,
return -EINVAL;
}
}
+
+int dasd_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ int rc;
+
+ lock_kernel();
+ rc = dasd_do_ioctl(bdev, mode, cmd, arg);
+ unlock_kernel();
+ return rc;
+}
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index bf6fd348f20..2080ba6a69b 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -11,6 +11,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/ctype.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
@@ -112,7 +114,7 @@ dasd_devices_show(struct seq_file *m, void *v)
seq_printf(m, "n/f ");
else
seq_printf(m,
- "at blocksize: %d, %ld blocks, %ld MB",
+ "at blocksize: %d, %lld blocks, %lld MB",
block->bp_block, block->blocks,
((block->bp_block >> 9) *
block->blocks) >> 11);
@@ -267,7 +269,7 @@ dasd_statistics_write(struct file *file, const char __user *user_buf,
buffer = dasd_get_user_string(user_buf, user_len);
if (IS_ERR(buffer))
return PTR_ERR(buffer);
- MESSAGE_LOG(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer);
+ DBF_EVENT(DBF_DEBUG, "/proc/dasd/statictics: '%s'\n", buffer);
/* check for valid verbs */
for (str = buffer; isspace(*str); str++);
@@ -277,33 +279,33 @@ dasd_statistics_write(struct file *file, const char __user *user_buf,
if (strcmp(str, "on") == 0) {
/* switch on statistics profiling */
dasd_profile_level = DASD_PROFILE_ON;
- MESSAGE(KERN_INFO, "%s", "Statistics switched on");
+ pr_info("The statistics feature has been switched "
+ "on\n");
} else if (strcmp(str, "off") == 0) {
/* switch off and reset statistics profiling */
memset(&dasd_global_profile,
0, sizeof (struct dasd_profile_info_t));
dasd_profile_level = DASD_PROFILE_OFF;
- MESSAGE(KERN_INFO, "%s", "Statistics switched off");
+ pr_info("The statistics feature has been switched "
+ "off\n");
} else
goto out_error;
} else if (strncmp(str, "reset", 5) == 0) {
/* reset the statistics */
memset(&dasd_global_profile, 0,
sizeof (struct dasd_profile_info_t));
- MESSAGE(KERN_INFO, "%s", "Statistics reset");
+ pr_info("The statistics have been reset\n");
} else
goto out_error;
kfree(buffer);
return user_len;
out_error:
- MESSAGE(KERN_WARNING, "%s",
- "/proc/dasd/statistics: only 'set on', 'set off' "
- "and 'reset' are supported verbs");
+ pr_warning("%s is not a supported value for /proc/dasd/statistics\n",
+ str);
kfree(buffer);
return -EINVAL;
#else
- MESSAGE(KERN_WARNING, "%s",
- "/proc/dasd/statistics: is not activated in this kernel");
+ pr_warning("/proc/dasd/statistics: is not activated in this kernel\n");
return user_len;
#endif /* CONFIG_DASD_PROFILE */
}
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 1fd8f2193ed..4377e93a43d 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -280,8 +280,11 @@ sclp_dispatch_evbufs(struct sccb_header *sccb)
rc = 0;
for (offset = sizeof(struct sccb_header); offset < sccb->length;
offset += evbuf->length) {
- /* Search for event handler */
evbuf = (struct evbuf_header *) ((addr_t) sccb + offset);
+ /* Check for malformed hardware response */
+ if (evbuf->length == 0)
+ break;
+ /* Search for event handler */
reg = NULL;
list_for_each(l, &sclp_reg_list) {
reg = list_entry(l, struct sclp_register, list);
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 50639049641..77ab6e34a10 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -19,6 +19,7 @@
#include <linux/memory.h>
#include <asm/chpid.h>
#include <asm/sclp.h>
+#include <asm/setup.h>
#include "sclp.h"
@@ -474,6 +475,10 @@ static void __init add_memory_merged(u16 rn)
goto skip_add;
if (start + size > VMEM_MAX_PHYS)
size = VMEM_MAX_PHYS - start;
+ if (memory_end_set && (start >= memory_end))
+ goto skip_add;
+ if (memory_end_set && (start + size > memory_end))
+ size = memory_end - start;
add_memory(0, start, size);
skip_add:
first_rn = rn;
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index d0d565a05df..c07809c8016 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -324,8 +324,6 @@ static inline void tape_proc_cleanup (void) {;}
#endif
/* a function for dumping device sense info */
-extern void tape_dump_sense(struct tape_device *, struct tape_request *,
- struct irb *);
extern void tape_dump_sense_dbf(struct tape_device *, struct tape_request *,
struct irb *);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 22ca34361ed..807ded5eb04 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -8,6 +8,8 @@
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
@@ -18,8 +20,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_34XX: "
-
/*
* Pointer to debug area.
*/
@@ -203,8 +203,7 @@ tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb)
tape_34xx_schedule_work(device, TO_MSEN);
} else {
DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
- PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
- tape_dump_sense(device, NULL, irb);
+ tape_dump_sense_dbf(device, NULL, irb);
}
return TAPE_IO_SUCCESS;
}
@@ -226,9 +225,7 @@ tape_34xx_erp_read_opposite(struct tape_device *device,
tape_std_read_backward(device, request);
return tape_34xx_erp_retry(request);
}
- if (request->op != TO_RBA)
- PRINT_ERR("read_opposite called with state:%s\n",
- tape_op_verbose[request->op]);
+
/*
* We tried to read forward and backward, but hat no
* success -> failed.
@@ -241,13 +238,9 @@ tape_34xx_erp_bug(struct tape_device *device, struct tape_request *request,
struct irb *irb, int no)
{
if (request->op != TO_ASSIGN) {
- PRINT_WARN("An unexpected condition #%d was caught in "
- "tape error recovery.\n", no);
- PRINT_WARN("Please report this incident.\n");
- if (request)
- PRINT_WARN("Operation of tape:%s\n",
- tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ dev_err(&device->cdev->dev, "An unexpected condition %d "
+ "occurred in tape error recovery\n", no);
+ tape_dump_sense_dbf(device, request, irb);
}
return tape_34xx_erp_failed(request, -EIO);
}
@@ -261,9 +254,8 @@ tape_34xx_erp_overrun(struct tape_device *device, struct tape_request *request,
struct irb *irb)
{
if (irb->ecw[3] == 0x40) {
- PRINT_WARN ("Data overrun error between control-unit "
- "and drive. Use a faster channel connection, "
- "if possible! \n");
+ dev_warn (&device->cdev->dev, "A data overrun occurred between"
+ " the control unit and tape unit\n");
return tape_34xx_erp_failed(request, -EIO);
}
return tape_34xx_erp_bug(device, request, irb, -1);
@@ -280,7 +272,8 @@ tape_34xx_erp_sequence(struct tape_device *device,
/*
* cu detected incorrect block-id sequence on tape.
*/
- PRINT_WARN("Illegal block-id sequence found!\n");
+ dev_warn (&device->cdev->dev, "The block ID sequence on the "
+ "tape is incorrect\n");
return tape_34xx_erp_failed(request, -EIO);
}
/*
@@ -393,8 +386,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
/* Writing at physical end of volume */
return tape_34xx_erp_failed(request, -ENOSPC);
default:
- PRINT_ERR("Invalid op in %s:%i\n",
- __func__, __LINE__);
return tape_34xx_erp_failed(request, 0);
}
}
@@ -420,7 +411,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
irb, -4);
/* data check is permanent, CU recovery has failed */
- PRINT_WARN("Permanent read error\n");
+ dev_warn (&device->cdev->dev, "A read error occurred "
+ "that cannot be recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x25:
// a write data check occurred
@@ -433,22 +425,26 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
irb, -5);
// data check is permanent, cu-recovery has failed
- PRINT_WARN("Permanent write error\n");
+ dev_warn (&device->cdev->dev, "A write error on the "
+ "tape cannot be recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x26:
/* Data Check (read opposite) occurred. */
return tape_34xx_erp_read_opposite(device, request);
case 0x28:
/* ID-Mark at tape start couldn't be written */
- PRINT_WARN("ID-Mark could not be written.\n");
+ dev_warn (&device->cdev->dev, "Writing the ID-mark "
+ "failed\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x31:
/* Tape void. Tried to read beyond end of device. */
- PRINT_WARN("Read beyond end of recorded area.\n");
+ dev_warn (&device->cdev->dev, "Reading the tape beyond"
+ " the end of the recorded area failed\n");
return tape_34xx_erp_failed(request, -ENOSPC);
case 0x41:
/* Record sequence error. */
- PRINT_WARN("Invalid block-id sequence found.\n");
+ dev_warn (&device->cdev->dev, "The tape contains an "
+ "incorrect block ID sequence\n");
return tape_34xx_erp_failed(request, -EIO);
default:
/* all data checks for 3480 should result in one of
@@ -470,16 +466,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
switch (sense[3]) {
case 0x00:
/* Unit check with erpa code 0. Report and ignore. */
- PRINT_WARN("Non-error sense was found. "
- "Unit-check will be ignored.\n");
return TAPE_IO_SUCCESS;
case 0x21:
/*
* Data streaming not operational. CU will switch to
* interlock mode. Reissue the command.
*/
- PRINT_WARN("Data streaming not operational. "
- "Switching to interlock-mode.\n");
return tape_34xx_erp_retry(request);
case 0x22:
/*
@@ -487,11 +479,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* error on the lower interface, internal path not usable,
* or error during cartridge load.
*/
- PRINT_WARN("A path equipment check occurred. One of the "
- "following conditions occurred:\n");
- PRINT_WARN("drive adapter error, buffer error on the lower "
- "interface, internal path not usable, error "
- "during cartridge load.\n");
+ dev_warn (&device->cdev->dev, "A path equipment check occurred"
+ " for the tape device\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x24:
/*
@@ -514,7 +503,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* but the hardware isn't capable to do idrc, or a perform
* subsystem func is issued and the CU is not on-line.
*/
- PRINT_WARN ("Function incompatible. Try to switch off idrc\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x2a:
/*
@@ -552,23 +540,26 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* reading the format id mark or that that format specified
* is not supported by the drive.
*/
- PRINT_WARN("Drive not capable processing the tape format!\n");
+ dev_warn (&device->cdev->dev, "The tape unit cannot process "
+ "the tape format\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
case 0x30:
/* The medium is write protected. */
- PRINT_WARN("Medium is write protected!\n");
+ dev_warn (&device->cdev->dev, "The tape medium is write-"
+ "protected\n");
return tape_34xx_erp_failed(request, -EACCES);
case 0x32:
// Tension loss. We cannot recover this, it's an I/O error.
- PRINT_WARN("The drive lost tape tension.\n");
+ dev_warn (&device->cdev->dev, "The tape does not have the "
+ "required tape tension\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x33:
/*
* Load Failure. The cartridge was not inserted correctly or
* the tape is not threaded correctly.
*/
- PRINT_WARN("Cartridge load failure. Reload the cartridge "
- "and try again.\n");
+ dev_warn (&device->cdev->dev, "The tape unit failed to load"
+ " the cartridge\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x34:
@@ -576,8 +567,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Unload failure. The drive cannot maintain tape tension
* and control tape movement during an unload operation.
*/
- PRINT_WARN("Failure during cartridge unload. "
- "Please try manually.\n");
+ dev_warn (&device->cdev->dev, "Automatic unloading of the tape"
+ " cartridge failed\n");
if (request->op == TO_RUN)
return tape_34xx_erp_failed(request, -EIO);
return tape_34xx_erp_bug(device, request, irb, sense[3]);
@@ -589,8 +580,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* - the cartridge loader does not respond correctly
* - a failure occurs during an index, load, or unload cycle
*/
- PRINT_WARN("Equipment check! Please check the drive and "
- "the cartridge loader.\n");
+ dev_warn (&device->cdev->dev, "An equipment check has occurred"
+ " on the tape unit\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x36:
if (device->cdev->id.driver_info == tape_3490)
@@ -603,7 +594,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Tape length error. The tape is shorter than reported in
* the beginning-of-tape data.
*/
- PRINT_WARN("Tape length error.\n");
+ dev_warn (&device->cdev->dev, "The tape information states an"
+ " incorrect length\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x38:
/*
@@ -620,12 +612,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_failed(request, -EIO);
case 0x3a:
/* Drive switched to not ready. */
- PRINT_WARN("Drive not ready. Turn the ready/not ready switch "
- "to ready position and try again.\n");
+ dev_warn (&device->cdev->dev, "The tape unit is not ready\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x3b:
/* Manual rewind or unload. This causes an I/O error. */
- PRINT_WARN("Medium was rewound or unloaded manually.\n");
+ dev_warn (&device->cdev->dev, "The tape medium has been "
+ "rewound or unloaded manually\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x42:
@@ -633,7 +625,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Degraded mode. A condition that can cause degraded
* performance is detected.
*/
- PRINT_WARN("Subsystem is running in degraded mode.\n");
+ dev_warn (&device->cdev->dev, "The tape subsystem is running "
+ "in degraded mode\n");
return tape_34xx_erp_retry(request);
case 0x43:
/* Drive not ready. */
@@ -652,7 +645,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
break;
}
}
- PRINT_WARN("The drive is not ready.\n");
return tape_34xx_erp_failed(request, -ENOMEDIUM);
case 0x44:
/* Locate Block unsuccessful. */
@@ -663,7 +655,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_failed(request, -EIO);
case 0x45:
/* The drive is assigned to a different channel path. */
- PRINT_WARN("The drive is assigned elsewhere.\n");
+ dev_warn (&device->cdev->dev, "The tape unit is already "
+ "assigned\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x46:
/*
@@ -671,11 +664,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* the power supply may be switched off or
* the drive address may not be set correctly.
*/
- PRINT_WARN("The drive is not on-line.");
+ dev_warn (&device->cdev->dev, "The tape unit is not online\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x47:
/* Volume fenced. CU reports volume integrity is lost. */
- PRINT_WARN("Volume fenced. The volume integrity is lost.\n");
+ dev_warn (&device->cdev->dev, "The control unit has fenced "
+ "access to the tape volume\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x48:
@@ -683,20 +677,21 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_retry(request);
case 0x49:
/* Bus out check. A parity check error on the bus was found. */
- PRINT_WARN("Bus out check. A data transfer over the bus "
- "has been corrupted.\n");
+ dev_warn (&device->cdev->dev, "A parity error occurred on the "
+ "tape bus\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4a:
/* Control unit erp failed. */
- PRINT_WARN("The control unit I/O error recovery failed.\n");
+ dev_warn (&device->cdev->dev, "I/O error recovery failed on "
+ "the tape control unit\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4b:
/*
* CU and drive incompatible. The drive requests micro-program
* patches, which are not available on the CU.
*/
- PRINT_WARN("The drive needs microprogram patches from the "
- "control unit, which are not available.\n");
+ dev_warn (&device->cdev->dev, "The tape unit requires a "
+ "firmware update\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4c:
/*
@@ -721,8 +716,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* the block to be written is larger than allowed for
* buffered mode.
*/
- PRINT_WARN("Maximum block size for buffered "
- "mode exceeded.\n");
+ dev_warn (&device->cdev->dev, "The maximum block size"
+ " for buffered mode is exceeded\n");
return tape_34xx_erp_failed(request, -ENOBUFS);
}
/* This erpa is reserved for 3480. */
@@ -759,22 +754,20 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_retry(request);
case 0x55:
/* Channel interface recovery (permanent). */
- PRINT_WARN("A permanent channel interface error occurred.\n");
+ dev_warn (&device->cdev->dev, "A channel interface error cannot be"
+ " recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x56:
/* Channel protocol error. */
- PRINT_WARN("A channel protocol error occurred.\n");
+ dev_warn (&device->cdev->dev, "A channel protocol error "
+ "occurred\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x57:
if (device->cdev->id.driver_info == tape_3480) {
/* Attention intercept. */
- PRINT_WARN("An attention intercept occurred, "
- "which will be recovered.\n");
return tape_34xx_erp_retry(request);
} else {
/* Global status intercept. */
- PRINT_WARN("An global status intercept was received, "
- "which will be recovered.\n");
return tape_34xx_erp_retry(request);
}
case 0x5a:
@@ -782,42 +775,31 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Tape length incompatible. The tape inserted is too long,
* which could cause damage to the tape or the drive.
*/
- PRINT_WARN("Tape Length Incompatible\n");
- PRINT_WARN("Tape length exceeds IBM enhanced capacity "
- "cartdridge length or a medium\n");
- PRINT_WARN("with EC-CST identification mark has been mounted "
- "in a device that writes\n");
- PRINT_WARN("3480 or 3480 XF format.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support "
+ "the tape length\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5b:
/* Format 3480 XF incompatible */
if (sense[1] & SENSE_BEGINNING_OF_TAPE)
/* The tape will get overwritten. */
return tape_34xx_erp_retry(request);
- PRINT_WARN("Format 3480 XF Incompatible\n");
- PRINT_WARN("Medium has been created in 3480 format. "
- "To change the format writes\n");
- PRINT_WARN("must be issued at BOT.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " format 3480 XF\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5c:
/* Format 3480-2 XF incompatible */
- PRINT_WARN("Format 3480-2 XF Incompatible\n");
- PRINT_WARN("Device can only read 3480 or 3480 XF format.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support tape "
+ "format 3480-2 XF\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5d:
/* Tape length violation. */
- PRINT_WARN("Tape Length Violation\n");
- PRINT_WARN("The mounted tape exceeds IBM Enhanced Capacity "
- "Cartdridge System Tape length.\n");
- PRINT_WARN("This may cause damage to the drive or tape when "
- "processing to the EOV\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " the current tape length\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
case 0x5e:
/* Compaction algorithm incompatible. */
- PRINT_WARN("Compaction Algorithm Incompatible\n");
- PRINT_WARN("The volume is recorded using an incompatible "
- "compaction algorithm,\n");
- PRINT_WARN("which is not supported by the device.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " the compaction algorithm\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
/* The following erpas should have been covered earlier. */
@@ -848,7 +830,6 @@ tape_34xx_irq(struct tape_device *device, struct tape_request *request,
(irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
(request->op == TO_WRI)) {
/* Write at end of volume */
- PRINT_INFO("End of volume\n"); /* XXX */
return tape_34xx_erp_failed(request, -ENOSPC);
}
@@ -869,9 +850,7 @@ tape_34xx_irq(struct tape_device *device, struct tape_request *request,
}
DBF_EVENT(6, "xunknownirq\n");
- PRINT_ERR("Unexpected interrupt.\n");
- PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ tape_dump_sense_dbf(device, request, irb);
return TAPE_IO_STOP;
}
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 71605a179d6..fc1d9129414 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -8,12 +8,15 @@
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
#include <asm/ebcdic.h>
#define TAPE_DBF_AREA tape_3590_dbf
+#define BUFSIZE 512 /* size of buffers for dynamic generated messages */
#include "tape.h"
#include "tape_std.h"
@@ -36,7 +39,7 @@ EXPORT_SYMBOL(TAPE_DBF_AREA);
* - Read Alternate: implemented
*******************************************************************/
-#define PRINTK_HEADER "TAPE_3590: "
+#define KMSG_COMPONENT "tape"
static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = {
[0x00] = "",
@@ -661,8 +664,7 @@ tape_3590_bread(struct tape_device *device, struct request *req)
ccw++;
dst += TAPEBLOCK_HSEC_SIZE;
}
- if (off > bv->bv_len)
- BUG();
+ BUG_ON(off > bv->bv_len);
}
ccw = tape_ccw_end(ccw, NOP, 0, NULL);
DBF_EVENT(6, "xBREDccwg\n");
@@ -726,7 +728,7 @@ static void tape_3590_med_state_set(struct tape_device *device,
}
c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
if (sense->flags & MSENSE_CRYPT_MASK) {
- PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags);
+ DBF_EVENT(6, "Medium is encrypted (%04x)\n", sense->flags);
c_info->medium_status |= TAPE390_MEDIUM_ENCRYPTED_MASK;
} else {
DBF_EVENT(6, "Medium is not encrypted %04x\n", sense->flags);
@@ -847,8 +849,7 @@ tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb)
tape_3590_schedule_work(device, TO_READ_ATTMSG);
} else {
DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
- PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
- tape_dump_sense(device, NULL, irb);
+ tape_dump_sense_dbf(device, NULL, irb);
}
/* check medium state */
tape_3590_schedule_work(device, TO_MSEN);
@@ -876,8 +877,6 @@ tape_3590_erp_basic(struct tape_device *device, struct tape_request *request,
case SENSE_BRA_DRE:
return tape_3590_erp_failed(device, request, irb, rc);
default:
- PRINT_ERR("Unknown BRA %x - This should not happen!\n",
- sense->bra);
BUG();
return TAPE_IO_STOP;
}
@@ -910,7 +909,8 @@ tape_3590_erp_swap(struct tape_device *device, struct tape_request *request,
* should proceed with the new tape... this
* should probably be done in user space!
*/
- PRINT_WARN("(%s): Swap Tape Device!\n", dev_name(&device->cdev->dev));
+ dev_warn (&device->cdev->dev, "The tape medium must be loaded into a "
+ "different tape unit\n");
return tape_3590_erp_basic(device, request, irb, -EIO);
}
@@ -985,8 +985,6 @@ tape_3590_erp_read_opposite(struct tape_device *device,
return tape_3590_erp_failed(device, request, irb, -EIO);
break;
default:
- PRINT_WARN("read_opposite_recovery_called_with_op: %s\n",
- tape_op_verbose[request->op]);
return tape_3590_erp_failed(device, request, irb, -EIO);
}
}
@@ -998,50 +996,61 @@ static void
tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f70.emc) {
case 0x02:
- PRINT_WARN("(%s): Data degraded\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Data degraded");
break;
case 0x03:
- PRINT_WARN("(%s): Data degraded in partion %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+ snprintf(exception, BUFSIZE, "Data degraded in partion %i",
+ sense->fmt.f70.mp);
break;
case 0x04:
- PRINT_WARN("(%s): Medium degraded\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Medium degraded");
break;
case 0x05:
- PRINT_WARN("(%s): Medium degraded in partition %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+ snprintf(exception, BUFSIZE, "Medium degraded in partition %i",
+ sense->fmt.f70.mp);
break;
case 0x06:
- PRINT_WARN("(%s): Block 0 Error\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Block 0 Error");
break;
case 0x07:
- PRINT_WARN("(%s): Medium Exception 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.md);
+ snprintf(exception, BUFSIZE, "Medium Exception 0x%02x",
+ sense->fmt.f70.md);
break;
default:
- PRINT_WARN("(%s): MIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f70.emc);
break;
}
/* Service Message */
switch (sense->fmt.f70.smc) {
case 0x02:
- PRINT_WARN("(%s): Reference Media maintenance procedure %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.md);
+ snprintf(service, BUFSIZE, "Reference Media maintenance "
+ "procedure %i", sense->fmt.f70.md);
break;
default:
- PRINT_WARN("(%s): MIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f70.smc);
break;
}
+
+ dev_warn (&device->cdev->dev, "Tape media information: exception %s, "
+ "service %s\n", exception, service);
+
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1051,108 +1060,108 @@ static void
tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f71.emc) {
case 0x01:
- PRINT_WARN("(%s): Effect of failure is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Effect of failure is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): CU Exception - no performance impact\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "CU Exception - no performance "
+ "impact");
break;
case 0x03:
- PRINT_WARN("(%s): CU Exception on channel interface 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on channel "
+ "interface 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x04:
- PRINT_WARN("(%s): CU Exception on device path 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on device path "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
case 0x05:
- PRINT_WARN("(%s): CU Exception on library path 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on library path "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
case 0x06:
- PRINT_WARN("(%s): CU Exception on node 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on node 0x%02x",
+ sense->fmt.f71.md[0]);
break;
case 0x07:
- PRINT_WARN("(%s): CU Exception on partition 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on partition "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
default:
- PRINT_WARN("(%s): SIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f71.emc);
}
/* Service Message */
switch (sense->fmt.f71.smc) {
case 0x01:
- PRINT_WARN("(%s): Repair impact is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair impact is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): Repair will not impact cu performance\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will not impact cu "
+ "performance");
break;
case 0x03:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable node "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable node "
+ "0x%x on CU", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable nodes "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "nodes (0x%x-0x%x) on CU", sense->fmt.f71.md[1],
+ sense->fmt.f71.md[2]);
break;
case 0x04:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable cannel path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path 0x%x on CU",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable cannel paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable cannel"
+ " paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x05:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable device path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable device"
+ " path 0x%x on CU", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable device paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable device"
+ " paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x06:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable library path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "library path 0x%x on CU",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable library paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "library paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x07:
- PRINT_WARN("(%s): Repair will disable access to CU\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will disable access to CU");
break;
default:
- PRINT_WARN("(%s): SIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f71.smc);
}
+
+ dev_warn (&device->cdev->dev, "I/O subsystem information: exception"
+ " %s, service %s\n", exception, service);
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1162,111 +1171,109 @@ static void
tape_3590_print_dev_sim_msg_f2(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f71.emc) {
case 0x01:
- PRINT_WARN("(%s): Effect of failure is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Effect of failure is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): DV Exception - no performance impact\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception - no performance"
+ " impact");
break;
case 0x03:
- PRINT_WARN("(%s): DV Exception on channel interface 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on channel "
+ "interface 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x04:
- PRINT_WARN("(%s): DV Exception on loader 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on loader 0x%02x",
+ sense->fmt.f71.md[0]);
break;
case 0x05:
- PRINT_WARN("(%s): DV Exception on message display 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on message display"
+ " 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x06:
- PRINT_WARN("(%s): DV Exception in tape path\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception in tape path");
break;
case 0x07:
- PRINT_WARN("(%s): DV Exception in drive\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception in drive");
break;
default:
- PRINT_WARN("(%s): DSIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f71.emc);
}
/* Service Message */
switch (sense->fmt.f71.smc) {
case 0x01:
- PRINT_WARN("(%s): Repair impact is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair impact is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): Repair will not impact device performance\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will not impact device "
+ "performance");
break;
case 0x03:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable channel path "
- "0x%x on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path 0x%x on DV",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable channel path "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x04:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable interface 0x%x "
- "on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "interface 0x%x on DV", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable interfaces "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "interfaces (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x05:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable loader 0x%x "
- "on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable loader"
+ " 0x%x on DV", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable loader "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable loader"
+ " (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x07:
- PRINT_WARN("(%s): Repair will disable access to DV\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will disable access to DV");
break;
case 0x08:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable message "
- "display 0x%x on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "message display 0x%x on DV",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable message "
- "displays (0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "message displays (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x09:
- PRINT_WARN("(%s): Clean DV\n", dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Clean DV");
break;
default:
- PRINT_WARN("(%s): DSIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f71.smc);
}
+
+ dev_warn (&device->cdev->dev, "Device subsystem information: exception"
+ " %s, service %s\n", exception, service);
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1282,46 +1289,44 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
return;
if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) {
if (tape_3590_msg[sense->mc] != NULL)
- PRINT_WARN("(%s): %s\n", dev_name(&device->cdev->dev),
- tape_3590_msg[sense->mc]);
- else {
- PRINT_WARN("(%s): Message Code 0x%x\n",
- dev_name(&device->cdev->dev), sense->mc);
- }
+ dev_warn (&device->cdev->dev, "The tape unit has "
+ "issued sense message %s\n",
+ tape_3590_msg[sense->mc]);
+ else
+ dev_warn (&device->cdev->dev, "The tape unit has "
+ "issued an unknown sense message code 0x%x\n",
+ sense->mc);
return;
}
if (sense->mc == 0xf0) {
/* Standard Media Information Message */
- PRINT_WARN("(%s): MIM SEV=%i, MC=%02x, ES=%x/%x, "
- "RC=%02x-%04x-%02x\n", dev_name(&device->cdev->dev),
- sense->fmt.f70.sev, sense->mc,
- sense->fmt.f70.emc, sense->fmt.f70.smc,
- sense->fmt.f70.refcode, sense->fmt.f70.mid,
- sense->fmt.f70.fid);
+ dev_warn (&device->cdev->dev, "MIM SEV=%i, MC=%02x, ES=%x/%x, "
+ "RC=%02x-%04x-%02x\n", sense->fmt.f70.sev, sense->mc,
+ sense->fmt.f70.emc, sense->fmt.f70.smc,
+ sense->fmt.f70.refcode, sense->fmt.f70.mid,
+ sense->fmt.f70.fid);
tape_3590_print_mim_msg_f0(device, irb);
return;
}
if (sense->mc == 0xf1) {
/* Standard I/O Subsystem Service Information Message */
- PRINT_WARN("(%s): IOSIM SEV=%i, DEVTYPE=3590/%02x, "
- "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.sev,
- device->cdev->id.dev_model,
- sense->mc, sense->fmt.f71.emc,
- sense->fmt.f71.smc, sense->fmt.f71.refcode1,
- sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+ dev_warn (&device->cdev->dev, "IOSIM SEV=%i, DEVTYPE=3590/%02x,"
+ " MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+ sense->fmt.f71.sev, device->cdev->id.dev_model,
+ sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+ sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+ sense->fmt.f71.refcode3);
tape_3590_print_io_sim_msg_f1(device, irb);
return;
}
if (sense->mc == 0xf2) {
/* Standard Device Service Information Message */
- PRINT_WARN("(%s): DEVSIM SEV=%i, DEVTYPE=3590/%02x, "
- "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.sev,
- device->cdev->id.dev_model,
- sense->mc, sense->fmt.f71.emc,
- sense->fmt.f71.smc, sense->fmt.f71.refcode1,
- sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+ dev_warn (&device->cdev->dev, "DEVSIM SEV=%i, DEVTYPE=3590/%02x"
+ ", MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+ sense->fmt.f71.sev, device->cdev->id.dev_model,
+ sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+ sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+ sense->fmt.f71.refcode3);
tape_3590_print_dev_sim_msg_f2(device, irb);
return;
}
@@ -1329,8 +1334,8 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
/* Standard Library Service Information Message */
return;
}
- PRINT_WARN("(%s): Device Message(%x)\n",
- dev_name(&device->cdev->dev), sense->mc);
+ dev_warn (&device->cdev->dev, "The tape unit has issued an unknown "
+ "sense message code %x\n", sense->mc);
}
static int tape_3590_crypt_error(struct tape_device *device,
@@ -1355,9 +1360,8 @@ static int tape_3590_crypt_error(struct tape_device *device,
/* No connection to EKM */
return tape_3590_erp_basic(device, request, irb, -ENOTCONN);
- PRINT_ERR("(%s): Unable to get encryption key from EKM\n", bus_id);
- PRINT_ERR("(%s): CU=%02X DRIVE=%06X EKM=%02X:%04X\n", bus_id, cu_rc,
- drv_rc, ekm_rc1, ekm_rc2);
+ dev_err (&device->cdev->dev, "The tape unit failed to obtain the "
+ "encryption key from EKM\n");
return tape_3590_erp_basic(device, request, irb, -ENOKEY);
}
@@ -1443,8 +1447,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
* print additional msg since default msg
* "device intervention" is not very meaningfull
*/
- PRINT_WARN("(%s): Tape operation when medium not loaded\n",
- dev_name(&device->cdev->dev));
tape_med_state_set(device, MS_UNLOADED);
tape_3590_schedule_work(device, TO_CRYPT_OFF);
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
@@ -1490,19 +1492,13 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
case 0x6020:
- PRINT_WARN("(%s): Cartridge of wrong type ?\n",
- dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE);
case 0x8011:
- PRINT_WARN("(%s): Another host has reserved the tape device\n",
- dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EPERM);
case 0x8013:
- PRINT_WARN("(%s): Another host has privileged access to the "
- "tape device\n", dev_name(&device->cdev->dev));
- PRINT_WARN("(%s): To solve the problem unload the current "
- "cartridge!\n", dev_name(&device->cdev->dev));
+ dev_warn (&device->cdev->dev, "A different host has privileged"
+ " access to the tape unit\n");
return tape_3590_erp_basic(device, request, irb, -EPERM);
default:
return tape_3590_erp_basic(device, request, irb, -EIO);
@@ -1552,9 +1548,7 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request,
}
DBF_EVENT(6, "xunknownirq\n");
- PRINT_ERR("Unexpected interrupt.\n");
- PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ tape_dump_sense_dbf(device, request, irb);
return TAPE_IO_STOP;
}
@@ -1609,7 +1603,6 @@ tape_3590_setup_device(struct tape_device *device)
if (rc)
goto fail_rdc_data;
if (rdc_data->data[31] == 0x13) {
- PRINT_INFO("Device has crypto support\n");
data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK;
tape_3592_disable_crypt(device);
} else {
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index ae18baf59f0..f32e89e7c4f 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -10,6 +10,8 @@
* Stefan Bader <shbader@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/blkdev.h>
@@ -23,8 +25,6 @@
#include "tape.h"
-#define PRINTK_HEADER "TAPE_BLOCK: "
-
#define TAPEBLOCK_MAX_SEC 100
#define TAPEBLOCK_MIN_REQUEUE 3
@@ -279,8 +279,6 @@ tapeblock_cleanup_device(struct tape_device *device)
tape_put_device(device);
if (!device->blk_data.disk) {
- PRINT_ERR("(%s): No gendisk to clean up!\n",
- dev_name(&device->cdev->dev));
goto cleanup_queue;
}
@@ -314,7 +312,8 @@ tapeblock_revalidate_disk(struct gendisk *disk)
if (!device->blk_data.medium_changed)
return 0;
- PRINT_INFO("Detecting media size...\n");
+ dev_info(&device->cdev->dev, "Determining the size of the recorded "
+ "area...\n");
rc = tape_mtop(device, MTFSFM, 1);
if (rc)
return rc;
@@ -341,7 +340,8 @@ tapeblock_revalidate_disk(struct gendisk *disk)
device->bof = rc;
nr_of_blks -= rc;
- PRINT_INFO("Found %i blocks on media\n", nr_of_blks);
+ dev_info(&device->cdev->dev, "The size of the recorded area is %i "
+ "blocks\n", nr_of_blks);
set_capacity(device->blk_data.disk,
nr_of_blks*(TAPEBLOCK_HSEC_SIZE/512));
@@ -376,8 +376,8 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)
if (device->required_tapemarks) {
DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
- PRINT_ERR("TBLOCK: Refusing to open tape with missing"
- " end of file marks.\n");
+ dev_warn(&device->cdev->dev, "Opening the tape failed because"
+ " of missing end-of-file marks\n");
rc = -EPERM;
goto put_device;
}
@@ -452,7 +452,6 @@ tapeblock_ioctl(
rc = -EINVAL;
break;
default:
- PRINT_WARN("invalid ioctl 0x%x\n", command);
rc = -EINVAL;
}
@@ -474,7 +473,6 @@ tapeblock_init(void)
if (tapeblock_major == 0)
tapeblock_major = rc;
- PRINT_INFO("tape gets major %d for block device\n", tapeblock_major);
return 0;
}
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index be0ce2215c8..31566c55adf 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -24,8 +24,6 @@
#include "tape_std.h"
#include "tape_class.h"
-#define PRINTK_HEADER "TAPE_CHAR: "
-
#define TAPECHAR_MAJOR 0 /* get dynamic major */
/*
@@ -102,8 +100,6 @@ tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
if (block_size > MAX_BLOCKSIZE) {
DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n",
block_size, MAX_BLOCKSIZE);
- PRINT_ERR("Invalid blocksize (%zd> %d)\n",
- block_size, MAX_BLOCKSIZE);
return -EINVAL;
}
@@ -485,7 +481,6 @@ tapechar_init (void)
return -1;
tapechar_major = MAJOR(dev);
- PRINT_INFO("tape gets major %d for character devices\n", MAJOR(dev));
return 0;
}
@@ -496,7 +491,5 @@ tapechar_init (void)
void
tapechar_exit(void)
{
- PRINT_INFO("tape releases major %d for character devices\n",
- tapechar_major);
unregister_chrdev_region(MKDEV(tapechar_major, 0), 256);
}
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index f9bb51fa7f5..08c09d3503c 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -11,6 +11,7 @@
* Stefan Bader <shbader@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
#include <linux/module.h>
#include <linux/init.h> // for kernel parameters
#include <linux/kmod.h> // for requesting modules
@@ -25,7 +26,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_CORE: "
#define LONG_BUSY_TIMEOUT 180 /* seconds */
static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
@@ -214,13 +214,13 @@ tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
switch(newstate){
case MS_UNLOADED:
device->tape_generic_status |= GMT_DR_OPEN(~0);
- PRINT_INFO("(%s): Tape is unloaded\n",
- dev_name(&device->cdev->dev));
+ dev_info(&device->cdev->dev, "The tape cartridge has been "
+ "successfully unloaded\n");
break;
case MS_LOADED:
device->tape_generic_status &= ~GMT_DR_OPEN(~0);
- PRINT_INFO("(%s): Tape has been mounted\n",
- dev_name(&device->cdev->dev));
+ dev_info(&device->cdev->dev, "A tape cartridge has been "
+ "mounted\n");
break;
default:
// print nothing
@@ -333,7 +333,6 @@ tape_generic_online(struct tape_device *device,
/* Let the discipline have a go at the device. */
device->discipline = discipline;
if (!try_module_get(discipline->owner)) {
- PRINT_ERR("Cannot get module. Module gone.\n");
return -EINVAL;
}
@@ -391,7 +390,6 @@ int
tape_generic_offline(struct tape_device *device)
{
if (!device) {
- PRINT_ERR("tape_generic_offline: no such device\n");
return -ENODEV;
}
@@ -413,9 +411,6 @@ tape_generic_offline(struct tape_device *device)
DBF_EVENT(3, "(%08x): Set offline failed "
"- drive in use.\n",
device->cdev_id);
- PRINT_WARN("(%s): Set offline failed "
- "- drive in use.\n",
- dev_name(&device->cdev->dev));
spin_unlock_irq(get_ccwdev_lock(device->cdev));
return -EBUSY;
}
@@ -435,14 +430,11 @@ tape_alloc_device(void)
device = kzalloc(sizeof(struct tape_device), GFP_KERNEL);
if (device == NULL) {
DBF_EXCEPTION(2, "ti:no mem\n");
- PRINT_INFO ("can't allocate memory for "
- "tape info structure\n");
return ERR_PTR(-ENOMEM);
}
device->modeset_byte = kmalloc(1, GFP_KERNEL | GFP_DMA);
if (device->modeset_byte == NULL) {
DBF_EXCEPTION(2, "ti:no mem\n");
- PRINT_INFO("can't allocate memory for modeset byte\n");
kfree(device);
return ERR_PTR(-ENOMEM);
}
@@ -490,7 +482,6 @@ tape_put_device(struct tape_device *device)
} else {
if (remain < 0) {
DBF_EVENT(4, "put device without reference\n");
- PRINT_ERR("put device without reference\n");
} else {
DBF_EVENT(4, "tape_free_device(%p)\n", device);
kfree(device->modeset_byte);
@@ -538,8 +529,6 @@ tape_generic_probe(struct ccw_device *cdev)
ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
if (ret) {
tape_put_device(device);
- PRINT_ERR("probe failed for tape device %s\n",
- dev_name(&cdev->dev));
return ret;
}
cdev->dev.driver_data = device;
@@ -547,7 +536,6 @@ tape_generic_probe(struct ccw_device *cdev)
device->cdev = cdev;
ccw_device_get_id(cdev, &dev_id);
device->cdev_id = devid_to_int(&dev_id);
- PRINT_INFO("tape device %s found\n", dev_name(&cdev->dev));
return ret;
}
@@ -584,7 +572,6 @@ tape_generic_remove(struct ccw_device *cdev)
device = cdev->dev.driver_data;
if (!device) {
- PRINT_ERR("No device pointer in tape_generic_remove!\n");
return;
}
DBF_LH(3, "(%08x): tape_generic_remove(%p)\n", device->cdev_id, cdev);
@@ -615,10 +602,8 @@ tape_generic_remove(struct ccw_device *cdev)
*/
DBF_EVENT(3, "(%08x): Drive in use vanished!\n",
device->cdev_id);
- PRINT_WARN("(%s): Drive in use vanished - "
- "expect trouble!\n",
- dev_name(&device->cdev->dev));
- PRINT_WARN("State was %i\n", device->tape_state);
+ dev_warn(&device->cdev->dev, "A tape unit was detached"
+ " while in use\n");
tape_state_set(device, TS_NOT_OPER);
__tape_discard_requests(device);
spin_unlock_irq(get_ccwdev_lock(device->cdev));
@@ -639,8 +624,7 @@ tape_alloc_request(int cplength, int datasize)
{
struct tape_request *request;
- if (datasize > PAGE_SIZE || (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
- BUG();
+ BUG_ON(datasize > PAGE_SIZE || (cplength*sizeof(struct ccw1)) > PAGE_SIZE);
DBF_LH(6, "tape_alloc_request(%d, %d)\n", cplength, datasize);
@@ -797,8 +781,7 @@ static void tape_long_busy_timeout(unsigned long data)
device = (struct tape_device *) data;
spin_lock_irq(get_ccwdev_lock(device->cdev));
request = list_entry(device->req_queue.next, struct tape_request, list);
- if (request->status != TAPE_REQUEST_LONG_BUSY)
- BUG();
+ BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY);
DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
__tape_start_next_request(device);
device->lb_timeout.data = (unsigned long) tape_put_device(device);
@@ -830,30 +813,6 @@ __tape_end_request(
}
/*
- * Write sense data to console/dbf
- */
-void
-tape_dump_sense(struct tape_device* device, struct tape_request *request,
- struct irb *irb)
-{
- unsigned int *sptr;
-
- PRINT_INFO("-------------------------------------------------\n");
- PRINT_INFO("DSTAT : %02x CSTAT: %02x CPA: %04x\n",
- irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa);
- PRINT_INFO("DEVICE: %s\n", dev_name(&device->cdev->dev));
- if (request != NULL)
- PRINT_INFO("OP : %s\n", tape_op_verbose[request->op]);
-
- sptr = (unsigned int *) irb->ecw;
- PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
- sptr[0], sptr[1], sptr[2], sptr[3]);
- PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
- sptr[4], sptr[5], sptr[6], sptr[7]);
- PRINT_INFO("--------------------------------------------------\n");
-}
-
-/*
* Write sense data to dbf
*/
void
@@ -1051,8 +1010,6 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
device = (struct tape_device *) cdev->dev.driver_data;
if (device == NULL) {
- PRINT_ERR("could not get device structure for %s "
- "in interrupt\n", dev_name(&cdev->dev));
return;
}
request = (struct tape_request *) intparm;
@@ -1064,13 +1021,13 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
/* FIXME: What to do with the request? */
switch (PTR_ERR(irb)) {
case -ETIMEDOUT:
- PRINT_WARN("(%s): Request timed out\n",
+ DBF_LH(1, "(%s): Request timed out\n",
dev_name(&cdev->dev));
case -EIO:
__tape_end_request(device, request, -EIO);
break;
default:
- PRINT_ERR("(%s): Unexpected i/o error %li\n",
+ DBF_LH(1, "(%s): Unexpected i/o error %li\n",
dev_name(&cdev->dev),
PTR_ERR(irb));
}
@@ -1182,8 +1139,6 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
default:
if (rc > 0) {
DBF_EVENT(6, "xunknownrc\n");
- PRINT_ERR("Invalid return code from discipline "
- "interrupt function.\n");
__tape_end_request(device, request, -EIO);
} else {
__tape_end_request(device, request, rc);
@@ -1323,7 +1278,6 @@ EXPORT_SYMBOL(tape_state_set);
EXPORT_SYMBOL(tape_med_state_set);
EXPORT_SYMBOL(tape_alloc_request);
EXPORT_SYMBOL(tape_free_request);
-EXPORT_SYMBOL(tape_dump_sense);
EXPORT_SYMBOL(tape_dump_sense_dbf);
EXPORT_SYMBOL(tape_do_io);
EXPORT_SYMBOL(tape_do_io_async);
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
index 8a376af926a..202f4213293 100644
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -20,8 +20,6 @@
#include "tape.h"
-#define PRINTK_HEADER "TAPE_PROC: "
-
static const char *tape_med_st_verbose[MS_SIZE] =
{
[MS_UNKNOWN] = "UNKNOWN ",
@@ -128,7 +126,6 @@ tape_proc_init(void)
proc_create("tapedevices", S_IFREG | S_IRUGO | S_IWUSR, NULL,
&tape_proc_ops);
if (tape_proc_devices == NULL) {
- PRINT_WARN("tape: Cannot register procfs entry tapedevices\n");
return;
}
}
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
index 5bd573d144d..1a9420ba518 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -26,8 +26,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_STD: "
-
/*
* tape_std_assign
*/
@@ -39,16 +37,15 @@ tape_std_assign_timeout(unsigned long data)
int rc;
request = (struct tape_request *) data;
- if ((device = request->device) == NULL)
- BUG();
+ device = request->device;
+ BUG_ON(!device);
DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n",
device->cdev_id);
rc = tape_cancel_io(device, request);
if(rc)
- PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n",
+ DBF_EVENT(3, "(%s): Assign timeout: Cancel failed with rc = %i\n",
dev_name(&device->cdev->dev), rc);
-
}
int
@@ -82,8 +79,6 @@ tape_std_assign(struct tape_device *device)
del_timer(&timeout);
if (rc != 0) {
- PRINT_WARN("%s: assign failed - device might be busy\n",
- dev_name(&device->cdev->dev));
DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
device->cdev_id);
} else {
@@ -105,8 +100,6 @@ tape_std_unassign (struct tape_device *device)
if (device->tape_state == TS_NOT_OPER) {
DBF_EVENT(3, "(%08x): Can't unassign device\n",
device->cdev_id);
- PRINT_WARN("(%s): Can't unassign device - device gone\n",
- dev_name(&device->cdev->dev));
return -EIO;
}
@@ -120,8 +113,6 @@ tape_std_unassign (struct tape_device *device)
if ((rc = tape_do_io(device, request)) != 0) {
DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
- PRINT_WARN("%s: Unassign failed\n",
- dev_name(&device->cdev->dev));
} else {
DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
}
@@ -242,8 +233,6 @@ tape_std_mtsetblk(struct tape_device *device, int count)
if (count > MAX_BLOCKSIZE) {
DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
count, MAX_BLOCKSIZE);
- PRINT_ERR("Invalid block size (%d > %d) given.\n",
- count, MAX_BLOCKSIZE);
return -EINVAL;
}
@@ -633,14 +622,6 @@ tape_std_mtcompression(struct tape_device *device, int mt_count)
if (mt_count < 0 || mt_count > 1) {
DBF_EXCEPTION(6, "xcom parm\n");
- if (*device->modeset_byte & 0x08)
- PRINT_INFO("(%s) Compression is currently on\n",
- dev_name(&device->cdev->dev));
- else
- PRINT_INFO("(%s) Compression is currently off\n",
- dev_name(&device->cdev->dev));
- PRINT_INFO("Use 1 to switch compression on, 0 to "
- "switch it off\n");
return -EINVAL;
}
request = tape_alloc_request(2, 0);
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index eefc6611412..1bbae433fbd 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -5,7 +5,7 @@
*
* For more information please refer to Documentation/s390/zfcpdump.txt
*
- * Copyright IBM Corp. 2003,2007
+ * Copyright IBM Corp. 2003,2008
* Author(s): Michael Holzheu
*/
@@ -24,6 +24,7 @@
#include <asm/debug.h>
#include <asm/processor.h>
#include <asm/irqflags.h>
+#include <asm/checksum.h>
#include "sclp.h"
#define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x)
@@ -48,12 +49,19 @@ struct sys_info {
union save_area lc_mask;
};
+struct ipib_info {
+ unsigned long ipib;
+ u32 checksum;
+} __attribute__((packed));
+
static struct sys_info sys_info;
static struct debug_info *zcore_dbf;
static int hsa_available;
static struct dentry *zcore_dir;
static struct dentry *zcore_file;
static struct dentry *zcore_memmap_file;
+static struct dentry *zcore_reipl_file;
+static struct ipl_parameter_block *ipl_block;
/*
* Copy memory from HSA to kernel or user memory (not reentrant):
@@ -527,6 +535,33 @@ static const struct file_operations zcore_memmap_fops = {
.release = zcore_memmap_release,
};
+static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ if (ipl_block) {
+ diag308(DIAG308_SET, ipl_block);
+ diag308(DIAG308_IPL, NULL);
+ }
+ return count;
+}
+
+static int zcore_reipl_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static int zcore_reipl_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static const struct file_operations zcore_reipl_fops = {
+ .owner = THIS_MODULE,
+ .write = zcore_reipl_write,
+ .open = zcore_reipl_open,
+ .release = zcore_reipl_release,
+};
+
static void __init set_s390_lc_mask(union save_area *map)
{
@@ -645,6 +680,40 @@ static int __init zcore_header_init(int arch, struct zcore_header *hdr)
return 0;
}
+/*
+ * Provide IPL parameter information block from either HSA or memory
+ * for future reipl
+ */
+static int __init zcore_reipl_init(void)
+{
+ struct ipib_info ipib_info;
+ int rc;
+
+ rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
+ if (rc)
+ return rc;
+ if (ipib_info.ipib == 0)
+ return 0;
+ ipl_block = (void *) __get_free_page(GFP_KERNEL);
+ if (!ipl_block)
+ return -ENOMEM;
+ if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
+ rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
+ else
+ rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE);
+ if (rc) {
+ free_page((unsigned long) ipl_block);
+ return rc;
+ }
+ if (csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
+ ipib_info.checksum) {
+ TRACE("Checksum does not match\n");
+ free_page((unsigned long) ipl_block);
+ ipl_block = NULL;
+ }
+ return 0;
+}
+
static int __init zcore_init(void)
{
unsigned char arch;
@@ -690,6 +759,10 @@ static int __init zcore_init(void)
if (rc)
goto fail;
+ rc = zcore_reipl_init();
+ if (rc)
+ goto fail;
+
zcore_dir = debugfs_create_dir("zcore" , NULL);
if (!zcore_dir) {
rc = -ENOMEM;
@@ -707,9 +780,17 @@ static int __init zcore_init(void)
rc = -ENOMEM;
goto fail_file;
}
+ zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
+ NULL, &zcore_reipl_fops);
+ if (!zcore_reipl_file) {
+ rc = -ENOMEM;
+ goto fail_memmap_file;
+ }
hsa_available = 1;
return 0;
+fail_memmap_file:
+ debugfs_remove(zcore_memmap_file);
fail_file:
debugfs_remove(zcore_file);
fail_dir:
@@ -723,10 +804,15 @@ static void __exit zcore_exit(void)
{
debug_unregister(zcore_dbf);
sclp_sdias_exit();
+ free_page((unsigned long) ipl_block);
+ debugfs_remove(zcore_reipl_file);
+ debugfs_remove(zcore_memmap_file);
+ debugfs_remove(zcore_file);
+ debugfs_remove(zcore_dir);
diag308(DIAG308_REL_HSA, NULL);
}
-MODULE_AUTHOR("Copyright IBM Corp. 2003,2007");
+MODULE_AUTHOR("Copyright IBM Corp. 2003,2008");
MODULE_DESCRIPTION("zcore module for zfcpdump support");
MODULE_LICENSE("GPL");
diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile
index bd79bd16539..adb3dd30152 100644
--- a/drivers/s390/cio/Makefile
+++ b/drivers/s390/cio/Makefile
@@ -3,7 +3,7 @@
#
obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \
- fcx.o itcw.o
+ fcx.o itcw.o crw.o
ccw_device-objs += device.o device_fsm.o device_ops.o
ccw_device-objs += device_id.o device_pgid.o device_status.o
obj-y += ccw_device.o cmf.o
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index fe6cea15bba..65d2e769dfa 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -34,8 +34,8 @@ struct airq_t {
void *drv_data;
};
-static union indicator_t indicators[MAX_ISC];
-static struct airq_t *airqs[MAX_ISC][NR_AIRQS];
+static union indicator_t indicators[MAX_ISC+1];
+static struct airq_t *airqs[MAX_ISC+1][NR_AIRQS];
static int register_airq(struct airq_t *airq, u8 isc)
{
@@ -133,6 +133,8 @@ void do_adapter_IO(u8 isc)
while (word) {
if (word & INDICATOR_MASK) {
airq = airqs[isc][i];
+ /* Make sure gcc reads from airqs only once. */
+ barrier();
if (likely(airq))
airq->handler(&indicators[isc].byte[i],
airq->drv_data);
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index fe00be3675c..6565f027791 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -336,8 +336,7 @@ cio_ignore_write(struct file *file, const char __user *user_buf,
size_t user_len, loff_t *offset)
{
char *buf;
- size_t i;
- ssize_t rc, ret;
+ ssize_t rc, ret, i;
if (*offset)
return -EINVAL;
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 918e6fce257..22ce765d537 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -104,8 +104,9 @@ ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const
rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
out:
if (rc) {
- /* Release onoff "lock" when ungrouping failed. */
- atomic_set(&gdev->onoff, 0);
+ if (rc != -EAGAIN)
+ /* Release onoff "lock" when ungrouping failed. */
+ atomic_set(&gdev->onoff, 0);
return rc;
}
return count;
@@ -314,16 +315,32 @@ error:
}
EXPORT_SYMBOL(ccwgroup_create_from_string);
-static int __init
-init_ccwgroup (void)
+static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+ void *data);
+
+static struct notifier_block ccwgroup_nb = {
+ .notifier_call = ccwgroup_notifier
+};
+
+static int __init init_ccwgroup(void)
{
- return bus_register (&ccwgroup_bus_type);
+ int ret;
+
+ ret = bus_register(&ccwgroup_bus_type);
+ if (ret)
+ return ret;
+
+ ret = bus_register_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+ if (ret)
+ bus_unregister(&ccwgroup_bus_type);
+
+ return ret;
}
-static void __exit
-cleanup_ccwgroup (void)
+static void __exit cleanup_ccwgroup(void)
{
- bus_unregister (&ccwgroup_bus_type);
+ bus_unregister_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+ bus_unregister(&ccwgroup_bus_type);
}
module_init(init_ccwgroup);
@@ -391,27 +408,28 @@ ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const
unsigned long value;
int ret;
- gdev = to_ccwgroupdev(dev);
if (!dev->driver)
- return count;
+ return -ENODEV;
+
+ gdev = to_ccwgroupdev(dev);
+ gdrv = to_ccwgroupdrv(dev->driver);
- gdrv = to_ccwgroupdrv (gdev->dev.driver);
if (!try_module_get(gdrv->owner))
return -EINVAL;
ret = strict_strtoul(buf, 0, &value);
if (ret)
goto out;
- ret = count;
+
if (value == 1)
- ccwgroup_set_online(gdev);
+ ret = ccwgroup_set_online(gdev);
else if (value == 0)
- ccwgroup_set_offline(gdev);
+ ret = ccwgroup_set_offline(gdev);
else
ret = -EINVAL;
out:
module_put(gdrv->owner);
- return ret;
+ return (ret == 0) ? count : ret;
}
static ssize_t
@@ -453,13 +471,18 @@ ccwgroup_remove (struct device *dev)
struct ccwgroup_device *gdev;
struct ccwgroup_driver *gdrv;
+ device_remove_file(dev, &dev_attr_online);
+ device_remove_file(dev, &dev_attr_ungroup);
+
+ if (!dev->driver)
+ return 0;
+
gdev = to_ccwgroupdev(dev);
gdrv = to_ccwgroupdrv(dev->driver);
- device_remove_file(dev, &dev_attr_online);
-
- if (gdrv && gdrv->remove)
+ if (gdrv->remove)
gdrv->remove(gdev);
+
return 0;
}
@@ -468,9 +491,13 @@ static void ccwgroup_shutdown(struct device *dev)
struct ccwgroup_device *gdev;
struct ccwgroup_driver *gdrv;
+ if (!dev->driver)
+ return;
+
gdev = to_ccwgroupdev(dev);
gdrv = to_ccwgroupdrv(dev->driver);
- if (gdrv && gdrv->shutdown)
+
+ if (gdrv->shutdown)
gdrv->shutdown(gdev);
}
@@ -483,6 +510,19 @@ static struct bus_type ccwgroup_bus_type = {
.shutdown = ccwgroup_shutdown,
};
+
+static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+
+ if (action == BUS_NOTIFY_UNBIND_DRIVER)
+ device_schedule_callback(dev, ccwgroup_ungroup_callback);
+
+ return NOTIFY_OK;
+}
+
+
/**
* ccwgroup_driver_register() - register a ccw group driver
* @cdriver: driver to be registered
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 1246f61a533..3e5f304ad88 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -17,8 +17,8 @@
#include <linux/errno.h>
#include <asm/chpid.h>
#include <asm/sclp.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "cio.h"
#include "css.h"
#include "ioasm.h"
@@ -706,12 +706,12 @@ static int __init chp_init(void)
struct chp_id chpid;
int ret;
- ret = s390_register_crw_handler(CRW_RSC_CPATH, chp_process_crw);
+ ret = crw_register_handler(CRW_RSC_CPATH, chp_process_crw);
if (ret)
return ret;
chp_wq = create_singlethread_workqueue("cio_chp");
if (!chp_wq) {
- s390_unregister_crw_handler(CRW_RSC_CPATH);
+ crw_unregister_handler(CRW_RSC_CPATH);
return -ENOMEM;
}
INIT_WORK(&cfg_work, cfg_func);
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index ebab6ea4659..883f16f96f2 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -19,8 +19,8 @@
#include <asm/cio.h>
#include <asm/chpid.h>
#include <asm/chsc.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "css.h"
#include "cio.h"
#include "cio_debug.h"
@@ -589,6 +589,7 @@ __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
case 0x0102:
case 0x0103:
ret = -EINVAL;
+ break;
default:
ret = chsc_error_from_response(secm_area->response.code);
}
@@ -820,7 +821,7 @@ int __init chsc_alloc_sei_area(void)
"chsc machine checks!\n");
return -ENOMEM;
}
- ret = s390_register_crw_handler(CRW_RSC_CSS, chsc_process_crw);
+ ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw);
if (ret)
kfree(sei_page);
return ret;
@@ -828,7 +829,7 @@ int __init chsc_alloc_sei_area(void)
void __init chsc_free_sei_area(void)
{
- s390_unregister_crw_handler(CRW_RSC_CSS);
+ crw_unregister_handler(CRW_RSC_CSS);
kfree(sei_page);
}
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 0a2f2edafc0..93eca1731b8 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -84,8 +84,8 @@ static int chsc_subchannel_probe(struct subchannel *sch)
kfree(private);
} else {
sch->private = private;
- if (sch->dev.uevent_suppress) {
- sch->dev.uevent_suppress = 0;
+ if (dev_get_uevent_suppress(&sch->dev)) {
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
}
}
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 659f8a79165..2aebb982304 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -30,6 +30,8 @@
#include <asm/isc.h>
#include <asm/cpu.h>
#include <asm/fcx.h>
+#include <asm/nmi.h>
+#include <asm/crw.h>
#include "cio.h"
#include "css.h"
#include "chsc.h"
@@ -38,7 +40,6 @@
#include "blacklist.h"
#include "cio_debug.h"
#include "chp.h"
-#include "../s390mach.h"
debug_info_t *cio_debug_msg_id;
debug_info_t *cio_debug_trace_id;
@@ -471,6 +472,7 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel);
int cio_disable_subchannel(struct subchannel *sch)
{
char dbf_txt[15];
+ int retry;
int ret;
CIO_TRACE_EVENT (2, "dissch");
@@ -481,16 +483,17 @@ int cio_disable_subchannel(struct subchannel *sch)
if (cio_update_schib(sch))
return -ENODEV;
- if (scsw_actl(&sch->schib.scsw) != 0)
- /*
- * the disable function must not be called while there are
- * requests pending for completion !
- */
- return -EBUSY;
-
sch->config.ena = 0;
- ret = cio_commit_config(sch);
+ for (retry = 0; retry < 3; retry++) {
+ ret = cio_commit_config(sch);
+ if (ret == -EBUSY) {
+ struct irb irb;
+ if (tsch(sch->schid, &irb) != 0)
+ break;
+ } else
+ break;
+ }
sprintf (dbf_txt, "ret:%d", ret);
CIO_TRACE_EVENT (2, dbf_txt);
return ret;
diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c
new file mode 100644
index 00000000000..d157665d0e7
--- /dev/null
+++ b/drivers/s390/cio/crw.c
@@ -0,0 +1,159 @@
+/*
+ * Channel report handling code
+ *
+ * Copyright IBM Corp. 2000,2009
+ * Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ * Cornelia Huck <cornelia.huck@de.ibm.com>,
+ * Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#include <linux/semaphore.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/init.h>
+#include <asm/crw.h>
+
+static struct semaphore crw_semaphore;
+static DEFINE_MUTEX(crw_handler_mutex);
+static crw_handler_t crw_handlers[NR_RSCS];
+
+/**
+ * crw_register_handler() - register a channel report word handler
+ * @rsc: reporting source code to handle
+ * @handler: handler to be registered
+ *
+ * Returns %0 on success and a negative error value otherwise.
+ */
+int crw_register_handler(int rsc, crw_handler_t handler)
+{
+ int rc = 0;
+
+ if ((rsc < 0) || (rsc >= NR_RSCS))
+ return -EINVAL;
+ mutex_lock(&crw_handler_mutex);
+ if (crw_handlers[rsc])
+ rc = -EBUSY;
+ else
+ crw_handlers[rsc] = handler;
+ mutex_unlock(&crw_handler_mutex);
+ return rc;
+}
+
+/**
+ * crw_unregister_handler() - unregister a channel report word handler
+ * @rsc: reporting source code to handle
+ */
+void crw_unregister_handler(int rsc)
+{
+ if ((rsc < 0) || (rsc >= NR_RSCS))
+ return;
+ mutex_lock(&crw_handler_mutex);
+ crw_handlers[rsc] = NULL;
+ mutex_unlock(&crw_handler_mutex);
+}
+
+/*
+ * Retrieve CRWs and call function to handle event.
+ */
+static int crw_collect_info(void *unused)
+{
+ struct crw crw[2];
+ int ccode;
+ unsigned int chain;
+ int ignore;
+
+repeat:
+ ignore = down_interruptible(&crw_semaphore);
+ chain = 0;
+ while (1) {
+ crw_handler_t handler;
+
+ if (unlikely(chain > 1)) {
+ struct crw tmp_crw;
+
+ printk(KERN_WARNING"%s: Code does not support more "
+ "than two chained crws; please report to "
+ "linux390@de.ibm.com!\n", __func__);
+ ccode = stcrw(&tmp_crw);
+ printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
+ "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+ __func__, tmp_crw.slct, tmp_crw.oflw,
+ tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
+ tmp_crw.erc, tmp_crw.rsid);
+ printk(KERN_WARNING"%s: This was crw number %x in the "
+ "chain\n", __func__, chain);
+ if (ccode != 0)
+ break;
+ chain = tmp_crw.chn ? chain + 1 : 0;
+ continue;
+ }
+ ccode = stcrw(&crw[chain]);
+ if (ccode != 0)
+ break;
+ printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
+ "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+ crw[chain].slct, crw[chain].oflw, crw[chain].chn,
+ crw[chain].rsc, crw[chain].anc, crw[chain].erc,
+ crw[chain].rsid);
+ /* Check for overflows. */
+ if (crw[chain].oflw) {
+ int i;
+
+ pr_debug("%s: crw overflow detected!\n", __func__);
+ mutex_lock(&crw_handler_mutex);
+ for (i = 0; i < NR_RSCS; i++) {
+ if (crw_handlers[i])
+ crw_handlers[i](NULL, NULL, 1);
+ }
+ mutex_unlock(&crw_handler_mutex);
+ chain = 0;
+ continue;
+ }
+ if (crw[0].chn && !chain) {
+ chain++;
+ continue;
+ }
+ mutex_lock(&crw_handler_mutex);
+ handler = crw_handlers[crw[chain].rsc];
+ if (handler)
+ handler(&crw[0], chain ? &crw[1] : NULL, 0);
+ mutex_unlock(&crw_handler_mutex);
+ /* chain is always 0 or 1 here. */
+ chain = crw[chain].chn ? chain + 1 : 0;
+ }
+ goto repeat;
+ return 0;
+}
+
+void crw_handle_channel_report(void)
+{
+ up(&crw_semaphore);
+}
+
+/*
+ * Separate initcall needed for semaphore initialization since
+ * crw_handle_channel_report might be called before crw_machine_check_init.
+ */
+static int __init crw_init_semaphore(void)
+{
+ init_MUTEX_LOCKED(&crw_semaphore);
+ return 0;
+}
+pure_initcall(crw_init_semaphore);
+
+/*
+ * Machine checks for the channel subsystem must be enabled
+ * after the channel subsystem is initialized
+ */
+static int __init crw_machine_check_init(void)
+{
+ struct task_struct *task;
+
+ task = kthread_run(crw_collect_info, NULL, "kmcheck");
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+ ctl_set_bit(14, 28); /* enable channel report MCH */
+ return 0;
+}
+device_initcall(crw_machine_check_init);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 8019288bc6d..0085d890179 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -18,8 +18,8 @@
#include <linux/list.h>
#include <linux/reboot.h>
#include <asm/isc.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "css.h"
#include "cio.h"
#include "cio_debug.h"
@@ -83,6 +83,25 @@ static int call_fn_unknown_sch(struct subchannel_id schid, void *data)
return rc;
}
+static int call_fn_all_sch(struct subchannel_id schid, void *data)
+{
+ struct cb_data *cb = data;
+ struct subchannel *sch;
+ int rc = 0;
+
+ sch = get_subchannel_by_schid(schid);
+ if (sch) {
+ if (cb->fn_known_sch)
+ rc = cb->fn_known_sch(sch, cb->data);
+ put_device(&sch->dev);
+ } else {
+ if (cb->fn_unknown_sch)
+ rc = cb->fn_unknown_sch(schid, cb->data);
+ }
+
+ return rc;
+}
+
int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
int (*fn_unknown)(struct subchannel_id,
void *), void *data)
@@ -90,13 +109,17 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
struct cb_data cb;
int rc;
- cb.set = idset_sch_new();
- if (!cb.set)
- return -ENOMEM;
- idset_fill(cb.set);
cb.data = data;
cb.fn_known_sch = fn_known;
cb.fn_unknown_sch = fn_unknown;
+
+ cb.set = idset_sch_new();
+ if (!cb.set)
+ /* fall back to brute force scanning in case of oom */
+ return for_each_subchannel(call_fn_all_sch, &cb);
+
+ idset_fill(cb.set);
+
/* Process registered subchannels. */
rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch);
if (rc)
@@ -272,7 +295,7 @@ static int css_register_subchannel(struct subchannel *sch)
* the subchannel driver can decide itself when it wants to inform
* userspace of its existence.
*/
- sch->dev.uevent_suppress = 1;
+ dev_set_uevent_suppress(&sch->dev, 1);
css_update_ssd_info(sch);
/* make it known to the system */
ret = css_sch_device_register(sch);
@@ -287,7 +310,7 @@ static int css_register_subchannel(struct subchannel *sch)
* a fitting driver module may be loaded based on the
* modalias.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
}
return ret;
@@ -510,6 +533,17 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data)
return ret;
}
+static void reprobe_after_idle(struct work_struct *unused)
+{
+ /* Make sure initial subchannel scan is done. */
+ wait_event(ccw_device_init_wq,
+ atomic_read(&ccw_device_init_count) == 0);
+ if (need_reprobe)
+ css_schedule_reprobe();
+}
+
+static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle);
+
/* Work function used to reprobe all unregistered subchannels. */
static void reprobe_all(struct work_struct *unused)
{
@@ -517,10 +551,12 @@ static void reprobe_all(struct work_struct *unused)
CIO_MSG_EVENT(4, "reprobe start\n");
- need_reprobe = 0;
/* Make sure initial subchannel scan is done. */
- wait_event(ccw_device_init_wq,
- atomic_read(&ccw_device_init_count) == 0);
+ if (atomic_read(&ccw_device_init_count) != 0) {
+ queue_work(ccw_device_work, &reprobe_idle_work);
+ return;
+ }
+ need_reprobe = 0;
ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
@@ -619,7 +655,7 @@ css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
} else {
#ifdef CONFIG_SMP
- css->global_pgid.pgid_high.cpu_addr = hard_smp_processor_id();
+ css->global_pgid.pgid_high.cpu_addr = stap();
#else
css->global_pgid.pgid_high.cpu_addr = 0;
#endif
@@ -765,7 +801,7 @@ init_channel_subsystem (void)
if (ret)
goto out;
- ret = s390_register_crw_handler(CRW_RSC_SCH, css_process_crw);
+ ret = crw_register_handler(CRW_RSC_SCH, css_process_crw);
if (ret)
goto out;
@@ -845,7 +881,7 @@ out_unregister:
out_bus:
bus_unregister(&css_bus_type);
out:
- s390_unregister_crw_handler(CRW_RSC_CSS);
+ crw_unregister_handler(CRW_RSC_CSS);
chsc_free_sei_area();
kfree(slow_subchannel_set);
pr_alert("The CSS device driver initialization failed with "
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 23d5752349b..c4d2f667a2f 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -457,12 +457,13 @@ int ccw_device_set_online(struct ccw_device *cdev)
return (ret == 0) ? -ENODEV : ret;
}
-static void online_store_handle_offline(struct ccw_device *cdev)
+static int online_store_handle_offline(struct ccw_device *cdev)
{
if (cdev->private->state == DEV_STATE_DISCONNECTED)
ccw_device_remove_disconnected(cdev);
- else if (cdev->drv && cdev->drv->set_offline)
- ccw_device_set_offline(cdev);
+ else if (cdev->online && cdev->drv && cdev->drv->set_offline)
+ return ccw_device_set_offline(cdev);
+ return 0;
}
static int online_store_recog_and_online(struct ccw_device *cdev)
@@ -530,13 +531,10 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
goto out;
switch (i) {
case 0:
- online_store_handle_offline(cdev);
- ret = count;
+ ret = online_store_handle_offline(cdev);
break;
case 1:
ret = online_store_handle_online(cdev, force);
- if (!ret)
- ret = count;
break;
default:
ret = -EINVAL;
@@ -545,7 +543,7 @@ out:
if (cdev->drv)
module_put(cdev->drv->owner);
atomic_set(&cdev->private->onoff, 0);
- return ret;
+ return (ret < 0) ? ret : count;
}
static ssize_t
@@ -681,35 +679,22 @@ get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css,
return dev ? to_ccwdev(dev) : NULL;
}
-static void
-ccw_device_add_changed(struct work_struct *work)
-{
- struct ccw_device_private *priv;
- struct ccw_device *cdev;
-
- priv = container_of(work, struct ccw_device_private, kick_work);
- cdev = priv->cdev;
- if (device_add(&cdev->dev)) {
- put_device(&cdev->dev);
- return;
- }
- set_bit(1, &cdev->private->registered);
-}
-
-void ccw_device_do_unreg_rereg(struct work_struct *work)
+void ccw_device_do_unbind_bind(struct work_struct *work)
{
struct ccw_device_private *priv;
struct ccw_device *cdev;
struct subchannel *sch;
+ int ret;
priv = container_of(work, struct ccw_device_private, kick_work);
cdev = priv->cdev;
sch = to_subchannel(cdev->dev.parent);
- ccw_device_unregister(cdev);
- PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_add_changed);
- queue_work(ccw_device_work, &cdev->private->kick_work);
+ if (test_bit(1, &cdev->private->registered)) {
+ device_release_driver(&cdev->dev);
+ ret = device_attach(&cdev->dev);
+ WARN_ON(ret == -ENODEV);
+ }
}
static void
@@ -799,7 +784,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch,
return;
other_sch = to_subchannel(cdev->dev.parent);
/* Note: device_move() changes cdev->dev.parent */
- ret = device_move(&cdev->dev, &sch->dev);
+ ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
if (ret) {
CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
"(ret=%d)!\n", cdev->private->dev_id.ssid,
@@ -830,7 +815,7 @@ static void sch_attach_orphaned_device(struct subchannel *sch,
* Try to move the ccw device to its new subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- ret = device_move(&cdev->dev, &sch->dev);
+ ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
if (ret) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage "
"failed (ret=%d)!\n",
@@ -897,7 +882,8 @@ void ccw_device_move_to_orphanage(struct work_struct *work)
* ccw device can take its place on the subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev);
+ ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev,
+ DPM_ORDER_NONE);
if (ret) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed "
"(ret=%d)!\n", cdev->private->dev_id.ssid,
@@ -981,7 +967,7 @@ io_subchannel_register(struct work_struct *work)
* Now we know this subchannel will stay, we can throw
* our delayed uevent.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
/* make it known to the system */
ret = ccw_device_register(cdev);
@@ -1034,8 +1020,6 @@ static void ccw_device_call_sch_unregister(struct work_struct *work)
void
io_subchannel_recog_done(struct ccw_device *cdev)
{
- struct subchannel *sch;
-
if (css_init_done == 0) {
cdev->private->flags.recog_done = 1;
return;
@@ -1046,7 +1030,6 @@ io_subchannel_recog_done(struct ccw_device *cdev)
/* Remove device found not operational. */
if (!get_device(&cdev->dev))
break;
- sch = to_subchannel(cdev->dev.parent);
PREPARE_WORK(&cdev->private->kick_work,
ccw_device_call_sch_unregister);
queue_work(slow_path_wq, &cdev->private->kick_work);
@@ -1129,7 +1112,7 @@ static void ccw_device_move_to_sch(struct work_struct *work)
* Try to move the ccw device to its new subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- rc = device_move(&cdev->dev, &sch->dev);
+ rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
mutex_unlock(&sch->reg_mutex);
if (rc) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
@@ -1243,7 +1226,7 @@ static int io_subchannel_probe(struct subchannel *sch)
* the ccw_device and exit. This happens for all early
* devices, e.g. the console.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
cdev->dev.groups = ccwdev_attr_groups;
device_initialize(&cdev->dev);
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 0f2e63ea48d..85e01846ca6 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -80,7 +80,7 @@ void io_subchannel_init_config(struct subchannel *sch);
int ccw_device_cancel_halt_clear(struct ccw_device *);
-void ccw_device_do_unreg_rereg(struct work_struct *);
+void ccw_device_do_unbind_bind(struct work_struct *);
void ccw_device_move_to_orphanage(struct work_struct *);
int ccw_device_is_orphan(struct ccw_device *);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 8df5eaafc5a..87b4bfca080 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -194,7 +194,7 @@ ccw_device_handle_oper(struct ccw_device *cdev)
cdev->id.dev_type != cdev->private->senseid.dev_type ||
cdev->id.dev_model != cdev->private->senseid.dev_model) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_do_unreg_rereg);
+ ccw_device_do_unbind_bind);
queue_work(ccw_device_work, &cdev->private->kick_work);
return 0;
}
@@ -366,7 +366,7 @@ static void ccw_device_oper_notify(struct ccw_device *cdev)
}
/* Driver doesn't want device back. */
ccw_device_set_notoper(cdev);
- PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg);
+ PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
@@ -728,7 +728,7 @@ static void ccw_device_generic_notoper(struct ccw_device *cdev,
{
struct subchannel *sch;
- cdev->private->state = DEV_STATE_NOT_OPER;
+ ccw_device_set_notoper(cdev);
sch = to_subchannel(cdev->dev.parent);
css_schedule_eval(sch->schid);
}
@@ -1052,7 +1052,7 @@ ccw_device_offline_irq(struct ccw_device *cdev, enum dev_event dev_event)
sch = to_subchannel(cdev->dev.parent);
/*
* An interrupt in state offline means a previous disable was not
- * successful. Try again.
+ * successful - should not happen, but we try to disable again.
*/
cio_disable_subchannel(sch);
}
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index eabcc42d63d..151754d5474 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -680,7 +680,7 @@ int ccw_device_tm_intrg(struct ccw_device *cdev)
if (cdev->private->state != DEV_STATE_ONLINE)
return -EIO;
if (!scsw_is_tm(&sch->schib.scsw) ||
- !(scsw_actl(&sch->schib.scsw) | SCSW_ACTL_START_PEND))
+ !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_START_PEND))
return -EINVAL;
return cio_tm_intrg(sch);
}
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 42f2b09631b..13bcb811438 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -186,6 +186,9 @@ struct qdio_input_q {
/* input buffer acknowledgement flag */
int polling;
+ /* first ACK'ed buffer */
+ int ack_start;
+
/* how much sbals are acknowledged with qebsm */
int ack_count;
@@ -234,7 +237,7 @@ struct qdio_q {
int first_to_check;
/* first_to_check of the last time */
- int last_move_ftc;
+ int last_move;
/* beginning position for calling the program */
int first_to_kick;
@@ -244,7 +247,6 @@ struct qdio_q {
struct qdio_irq *irq_ptr;
struct tasklet_struct tasklet;
- spinlock_t lock;
/* error condition during a data transfer */
unsigned int qdio_error;
@@ -354,7 +356,7 @@ int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state,
int auto_ack);
void qdio_check_outbound_after_thinint(struct qdio_q *q);
int qdio_inbound_q_moved(struct qdio_q *q);
-void qdio_kick_inbound_handler(struct qdio_q *q);
+void qdio_kick_handler(struct qdio_q *q);
void qdio_stop_polling(struct qdio_q *q);
int qdio_siga_sync_q(struct qdio_q *q);
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index da7afb04e71..e3434b34f86 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -63,8 +63,9 @@ static int qstat_show(struct seq_file *m, void *v)
seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci);
seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used));
seq_printf(m, "ftc: %d\n", q->first_to_check);
- seq_printf(m, "last_move_ftc: %d\n", q->last_move_ftc);
+ seq_printf(m, "last_move: %d\n", q->last_move);
seq_printf(m, "polling: %d\n", q->u.in.polling);
+ seq_printf(m, "ack start: %d\n", q->u.in.ack_start);
seq_printf(m, "ack count: %d\n", q->u.in.ack_count);
seq_printf(m, "slsb buffer states:\n");
seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 10cb0f8726e..9e8a2914259 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -380,11 +380,11 @@ inline void qdio_stop_polling(struct qdio_q *q)
/* show the card that we are not polling anymore */
if (is_qebsm(q)) {
- set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
+ set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
q->u.in.ack_count);
q->u.in.ack_count = 0;
} else
- set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
+ set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
}
static void announce_buffer_error(struct qdio_q *q, int count)
@@ -419,15 +419,15 @@ static inline void inbound_primed(struct qdio_q *q, int count)
if (!q->u.in.polling) {
q->u.in.polling = 1;
q->u.in.ack_count = count;
- q->last_move_ftc = q->first_to_check;
+ q->u.in.ack_start = q->first_to_check;
return;
}
/* delete the previous ACK's */
- set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
+ set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
q->u.in.ack_count);
q->u.in.ack_count = count;
- q->last_move_ftc = q->first_to_check;
+ q->u.in.ack_start = q->first_to_check;
return;
}
@@ -439,14 +439,13 @@ static inline void inbound_primed(struct qdio_q *q, int count)
if (q->u.in.polling) {
/* reset the previous ACK but first set the new one */
set_buf_state(q, new, SLSB_P_INPUT_ACK);
- set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
- }
- else {
+ set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
+ } else {
q->u.in.polling = 1;
- set_buf_state(q, q->first_to_check, SLSB_P_INPUT_ACK);
+ set_buf_state(q, new, SLSB_P_INPUT_ACK);
}
- q->last_move_ftc = new;
+ q->u.in.ack_start = new;
count--;
if (!count)
return;
@@ -455,7 +454,7 @@ static inline void inbound_primed(struct qdio_q *q, int count)
* Need to change all PRIMED buffers to NOT_INIT, otherwise
* we're loosing initiative in the thinint code.
*/
- set_buf_states(q, next_buf(q->first_to_check), SLSB_P_INPUT_NOT_INIT,
+ set_buf_states(q, q->first_to_check, SLSB_P_INPUT_NOT_INIT,
count);
}
@@ -523,7 +522,8 @@ int qdio_inbound_q_moved(struct qdio_q *q)
bufnr = get_inbound_buffer_frontier(q);
- if ((bufnr != q->last_move_ftc) || q->qdio_error) {
+ if ((bufnr != q->last_move) || q->qdio_error) {
+ q->last_move = bufnr;
if (!need_siga_sync(q) && !pci_out_supported(q))
q->u.in.timestamp = get_usecs();
@@ -570,29 +570,30 @@ static int qdio_inbound_q_done(struct qdio_q *q)
}
}
-void qdio_kick_inbound_handler(struct qdio_q *q)
+void qdio_kick_handler(struct qdio_q *q)
{
- int count, start, end;
-
- qdio_perf_stat_inc(&perf_stats.inbound_handler);
-
- start = q->first_to_kick;
- end = q->first_to_check;
- if (end >= start)
- count = end - start;
- else
- count = end + QDIO_MAX_BUFFERS_PER_Q - start;
-
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count);
+ int start = q->first_to_kick;
+ int end = q->first_to_check;
+ int count;
if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
return;
- q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr,
- start, count, q->irq_ptr->int_parm);
+ count = sub_buf(end, start);
+
+ if (q->is_input_q) {
+ qdio_perf_stat_inc(&perf_stats.inbound_handler);
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count);
+ } else {
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: nr:%1d", q->nr);
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count);
+ }
+
+ q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
+ q->irq_ptr->int_parm);
/* for the next time */
- q->first_to_kick = q->first_to_check;
+ q->first_to_kick = end;
q->qdio_error = 0;
}
@@ -603,7 +604,7 @@ again:
if (!qdio_inbound_q_moved(q))
return;
- qdio_kick_inbound_handler(q);
+ qdio_kick_handler(q);
if (!qdio_inbound_q_done(q))
/* means poll time is not yet over */
@@ -698,21 +699,21 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
bufnr = get_outbound_buffer_frontier(q);
- if ((bufnr != q->last_move_ftc) || q->qdio_error) {
- q->last_move_ftc = bufnr;
+ if ((bufnr != q->last_move) || q->qdio_error) {
+ q->last_move = bufnr;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
return 1;
} else
return 0;
}
-static void qdio_kick_outbound_q(struct qdio_q *q)
+static int qdio_kick_outbound_q(struct qdio_q *q)
{
unsigned int busy_bit;
int cc;
if (!need_siga_out(q))
- return;
+ return 0;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr);
qdio_perf_stat_inc(&perf_stats.siga_out);
@@ -724,75 +725,37 @@ static void qdio_kick_outbound_q(struct qdio_q *q)
case 2:
if (busy_bit) {
DBF_ERROR("%4x cc2 REP:%1d", SCH_NO(q), q->nr);
- q->qdio_error = cc | QDIO_ERROR_SIGA_BUSY;
- } else {
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d",
- q->nr);
- q->qdio_error = cc;
- }
+ cc |= QDIO_ERROR_SIGA_BUSY;
+ } else
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr);
break;
case 1:
case 3:
DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc);
- q->qdio_error = cc;
break;
}
-}
-
-static void qdio_kick_outbound_handler(struct qdio_q *q)
-{
- int start, end, count;
-
- start = q->first_to_kick;
- end = q->last_move_ftc;
- if (end >= start)
- count = end - start;
- else
- count = end + QDIO_MAX_BUFFERS_PER_Q - start;
-
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kickouth: %1d", q->nr);
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count);
-
- if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
- return;
-
- q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
- q->irq_ptr->int_parm);
-
- /* for the next time: */
- q->first_to_kick = q->last_move_ftc;
- q->qdio_error = 0;
+ return cc;
}
static void __qdio_outbound_processing(struct qdio_q *q)
{
- unsigned long flags;
-
qdio_perf_stat_inc(&perf_stats.tasklet_outbound);
- spin_lock_irqsave(&q->lock, flags);
-
BUG_ON(atomic_read(&q->nr_buf_used) < 0);
if (qdio_outbound_q_moved(q))
- qdio_kick_outbound_handler(q);
-
- spin_unlock_irqrestore(&q->lock, flags);
+ qdio_kick_handler(q);
- if (queue_type(q) == QDIO_ZFCP_QFMT) {
+ if (queue_type(q) == QDIO_ZFCP_QFMT)
if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
- tasklet_schedule(&q->tasklet);
- return;
- }
+ goto sched;
/* bail out for HiperSockets unicast queues */
if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
return;
if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
- (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) {
- tasklet_schedule(&q->tasklet);
- return;
- }
+ (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
+ goto sched;
if (q->u.out.pci_out_enabled)
return;
@@ -810,6 +773,12 @@ static void __qdio_outbound_processing(struct qdio_q *q)
qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
}
}
+ return;
+
+sched:
+ if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
+ tasklet_schedule(&q->tasklet);
}
/* outbound tasklet */
@@ -822,6 +791,9 @@ void qdio_outbound_processing(unsigned long data)
void qdio_outbound_timer(unsigned long data)
{
struct qdio_q *q = (struct qdio_q *)data;
+
+ if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
tasklet_schedule(&q->tasklet);
}
@@ -863,6 +835,9 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
int i;
struct qdio_q *q;
+ if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
+
qdio_perf_stat_inc(&perf_stats.pci_int);
for_each_input_queue(irq_ptr, q, i)
@@ -1065,8 +1040,9 @@ EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
* @cdev: associated ccw device
* @how: use halt or clear to shutdown
*
- * This function calls qdio_shutdown() for @cdev with method @how
- * and on success qdio_free() for @cdev.
+ * This function calls qdio_shutdown() for @cdev with method @how.
+ * and qdio_free(). The qdio_free() return value is ignored since
+ * !irq_ptr is already checked.
*/
int qdio_cleanup(struct ccw_device *cdev, int how)
{
@@ -1077,8 +1053,8 @@ int qdio_cleanup(struct ccw_device *cdev, int how)
return -ENODEV;
rc = qdio_shutdown(cdev, how);
- if (rc == 0)
- rc = qdio_free(cdev);
+
+ qdio_free(cdev);
return rc;
}
EXPORT_SYMBOL_GPL(qdio_cleanup);
@@ -1090,11 +1066,11 @@ static void qdio_shutdown_queues(struct ccw_device *cdev)
int i;
for_each_input_queue(irq_ptr, q, i)
- tasklet_disable(&q->tasklet);
+ tasklet_kill(&q->tasklet);
for_each_output_queue(irq_ptr, q, i) {
- tasklet_disable(&q->tasklet);
del_timer(&q->u.out.timer);
+ tasklet_kill(&q->tasklet);
}
}
@@ -1112,6 +1088,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
if (!irq_ptr)
return -ENODEV;
+ BUG_ON(irqs_disabled());
DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
mutex_lock(&irq_ptr->setup_mutex);
@@ -1124,6 +1101,12 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
return 0;
}
+ /*
+ * Indicate that the device is going down. Scheduling the queue
+ * tasklets is forbidden from here on.
+ */
+ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
+
tiqdio_remove_input_queues(irq_ptr);
qdio_shutdown_queues(cdev);
qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1403,9 +1386,8 @@ int qdio_activate(struct ccw_device *cdev)
switch (irq_ptr->state) {
case QDIO_IRQ_STATE_STOPPED:
case QDIO_IRQ_STATE_ERR:
- mutex_unlock(&irq_ptr->setup_mutex);
- qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
- return -EIO;
+ rc = -EIO;
+ break;
default:
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE);
rc = 0;
@@ -1442,10 +1424,10 @@ static inline int buf_in_between(int bufnr, int start, int count)
* @bufnr: first buffer to process
* @count: how many buffers are emptied
*/
-static void handle_inbound(struct qdio_q *q, unsigned int callflags,
- int bufnr, int count)
+static int handle_inbound(struct qdio_q *q, unsigned int callflags,
+ int bufnr, int count)
{
- int used, cc, diff;
+ int used, diff;
if (!q->u.in.polling)
goto set;
@@ -1456,19 +1438,18 @@ static void handle_inbound(struct qdio_q *q, unsigned int callflags,
q->u.in.polling = 0;
q->u.in.ack_count = 0;
goto set;
- } else if (buf_in_between(q->last_move_ftc, bufnr, count)) {
+ } else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
if (is_qebsm(q)) {
- /* partial overwrite, just update last_move_ftc */
+ /* partial overwrite, just update ack_start */
diff = add_buf(bufnr, count);
- diff = sub_buf(diff, q->last_move_ftc);
+ diff = sub_buf(diff, q->u.in.ack_start);
q->u.in.ack_count -= diff;
if (q->u.in.ack_count <= 0) {
q->u.in.polling = 0;
q->u.in.ack_count = 0;
- /* TODO: must we set last_move_ftc to something meaningful? */
goto set;
}
- q->last_move_ftc = add_buf(q->last_move_ftc, diff);
+ q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
}
else
/* the only ACK will be deleted, so stop polling */
@@ -1483,13 +1464,11 @@ set:
/* no need to signal as long as the adapter had free buffers */
if (used)
- return;
+ return 0;
- if (need_siga_in(q)) {
- cc = qdio_siga_input(q);
- if (cc)
- q->qdio_error = cc;
- }
+ if (need_siga_in(q))
+ return qdio_siga_input(q);
+ return 0;
}
/**
@@ -1499,11 +1478,11 @@ set:
* @bufnr: first buffer to process
* @count: how many buffers are filled
*/
-static void handle_outbound(struct qdio_q *q, unsigned int callflags,
- int bufnr, int count)
+static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+ int bufnr, int count)
{
unsigned char state;
- int used;
+ int used, rc = 0;
qdio_perf_stat_inc(&perf_stats.outbound_handler);
@@ -1518,27 +1497,26 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
if (queue_type(q) == QDIO_IQDIO_QFMT) {
if (multicast_outbound(q))
- qdio_kick_outbound_q(q);
+ rc = qdio_kick_outbound_q(q);
else
if ((q->irq_ptr->ssqd_desc.mmwc > 1) &&
(count > 1) &&
(count <= q->irq_ptr->ssqd_desc.mmwc)) {
/* exploit enhanced SIGA */
q->u.out.use_enh_siga = 1;
- qdio_kick_outbound_q(q);
+ rc = qdio_kick_outbound_q(q);
} else {
/*
* One siga-w per buffer required for unicast
* HiperSockets.
*/
q->u.out.use_enh_siga = 0;
- while (count--)
- qdio_kick_outbound_q(q);
+ while (count--) {
+ rc = qdio_kick_outbound_q(q);
+ if (rc)
+ goto out;
+ }
}
-
- /* report CC=2 conditions synchronously */
- if (q->qdio_error)
- __qdio_outbound_processing(q);
goto out;
}
@@ -1550,14 +1528,14 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
/* try to fast requeue buffers */
get_buf_state(q, prev_buf(bufnr), &state, 0);
if (state != SLSB_CU_OUTPUT_PRIMED)
- qdio_kick_outbound_q(q);
+ rc = qdio_kick_outbound_q(q);
else {
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "fast-req");
qdio_perf_stat_inc(&perf_stats.fast_requeue);
}
out:
- /* Fixme: could wait forever if called from process context */
tasklet_schedule(&q->tasklet);
+ return rc;
}
/**
@@ -1596,14 +1574,12 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
return -EBUSY;
if (callflags & QDIO_FLAG_SYNC_INPUT)
- handle_inbound(irq_ptr->input_qs[q_nr], callflags, bufnr,
- count);
+ return handle_inbound(irq_ptr->input_qs[q_nr],
+ callflags, bufnr, count);
else if (callflags & QDIO_FLAG_SYNC_OUTPUT)
- handle_outbound(irq_ptr->output_qs[q_nr], callflags, bufnr,
- count);
- else
- return -EINVAL;
- return 0;
+ return handle_outbound(irq_ptr->output_qs[q_nr],
+ callflags, bufnr, count);
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(do_QDIO);
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index c08356b95bf..18d54fc21ce 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -117,7 +117,6 @@ static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr,
q->mask = 1 << (31 - i);
q->nr = i;
q->handler = handler;
- spin_lock_init(&q->lock);
}
static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 8e90e147b74..c655d011a78 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -31,6 +31,7 @@
/* list of thin interrupt input queues */
static LIST_HEAD(tiq_list);
+DEFINE_MUTEX(tiq_list_lock);
/* adapter local summary indicator */
static unsigned char *tiqdio_alsi;
@@ -95,12 +96,11 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
css_qdio_omit_svs = 1;
- for_each_input_queue(irq_ptr, q, i) {
+ mutex_lock(&tiq_list_lock);
+ for_each_input_queue(irq_ptr, q, i)
list_add_rcu(&q->entry, &tiq_list);
- synchronize_rcu();
- }
+ mutex_unlock(&tiq_list_lock);
xchg(irq_ptr->dsci, 1);
- tasklet_schedule(&tiqdio_tasklet);
}
/*
@@ -118,7 +118,10 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
/* if establish triggered an error */
if (!q || !q->entry.prev || !q->entry.next)
continue;
+
+ mutex_lock(&tiq_list_lock);
list_del_rcu(&q->entry);
+ mutex_unlock(&tiq_list_lock);
synchronize_rcu();
}
}
@@ -155,15 +158,15 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
*/
qdio_check_outbound_after_thinint(q);
-again:
if (!qdio_inbound_q_moved(q))
return;
- qdio_kick_inbound_handler(q);
+ qdio_kick_handler(q);
if (!tiqdio_inbound_q_done(q)) {
qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
- goto again;
+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+ tasklet_schedule(&q->tasklet);
}
qdio_stop_polling(q);
@@ -173,7 +176,8 @@ again:
*/
if (!tiqdio_inbound_q_done(q)) {
qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
- goto again;
+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+ tasklet_schedule(&q->tasklet);
}
}
@@ -366,10 +370,11 @@ void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
void __exit tiqdio_unregister_thinints(void)
{
- tasklet_disable(&tiqdio_tasklet);
+ WARN_ON(!list_empty(&tiq_list));
if (tiqdio_alsi) {
s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC);
isc_unregister(QDIO_AIRQ_ISC);
}
+ tasklet_kill(&tiqdio_tasklet);
}
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index cb22b97944b..65b6a96afe6 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -128,8 +128,7 @@ static void __zcrypt_increase_preference(struct zcrypt_device *zdev)
if (l == zdev->list.prev)
return;
/* Move zdev behind l */
- list_del(&zdev->list);
- list_add(&zdev->list, l);
+ list_move(&zdev->list, l);
}
/**
@@ -157,8 +156,7 @@ static void __zcrypt_decrease_preference(struct zcrypt_device *zdev)
if (l == zdev->list.next)
return;
/* Move zdev before l */
- list_del(&zdev->list);
- list_add_tail(&zdev->list, l);
+ list_move_tail(&zdev->list, l);
}
static void zcrypt_device_release(struct kref *kref)
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index e7a1e22e77a..c20d4790258 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -781,8 +781,7 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
- memset(ap_msg.message, 0x0, ap_msg.length);
- kfree(ap_msg.message);
+ kzfree(ap_msg.message);
return rc;
}
diff --git a/drivers/s390/ebcdic.c b/drivers/s390/ebcdic.c
deleted file mode 100644
index 99c98da1547..00000000000
--- a/drivers/s390/ebcdic.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * arch/s390/kernel/ebcdic.c
- * ECBDIC -> ASCII, ASCII -> ECBDIC conversion tables.
- *
- * S390 version
- * Copyright (C) 1998 IBM Corporation
- * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <asm/types.h>
-
-/*
- * ASCII -> EBCDIC
- */
-__u8 _ascebc[256] =
-{
- /*00 NL SH SX EX ET NQ AK BL */
- 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- /*08 BS HT LF VT FF CR SO SI */
- 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10 DL D1 D2 D3 D4 NK SN EB */
- 0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
- /*18 CN EM SB EC FS GS RS US */
- 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
- /*20 SP ! " # $ % & ' */
- 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- /*28 ( ) * + , - . / */
- 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- /*30 0 1 2 3 4 5 6 7 */
- 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- /*38 8 9 : ; < = > ? */
- 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- /*40 @ A B C D E F G */
- 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- /*48 H I J K L M N O */
- 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- /*50 P Q R S T U V W */
- 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- /*58 X Y Z [ \ ] ^ _ */
- 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
- /*60 ` a b c d e f g */
- 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /*68 h i j k l m n o */
- 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- /*70 p q r s t u v w */
- 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- /*78 x y z { | } ~ DL */
- 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-/*
- * EBCDIC -> ASCII
- */
-__u8 _ebcasc[256] =
-{
- /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08 -GE -SPS -RPT VT FF CR SO SI */
- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC
- -ENP ->LF */
- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB
- -IUS */
- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC
- -INP */
- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
- -SW */
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40 SP RSP ä ---- */
- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48 . < ( + | */
- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50 & ---- */
- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58 ß ! $ * ) ; */
- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60 - / ---- Ä ---- ---- ---- */
- 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68 ---- , % _ > ? */
- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70 ---- ---- ---- ---- ---- ---- ---- */
- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78 * ` : # @ ' = " */
- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80 * a b c d e f g */
- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88 h i ---- ---- ---- */
- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90 ° j k l m n o p */
- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98 q r ---- ---- */
- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0 ~ s t u v w x */
- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8 y z ---- ---- ---- ---- */
- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0 ^ ---- § ---- */
- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8 ---- [ ] ---- ---- ---- ---- */
- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0 { A B C D E F G */
- 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8 H I ---- ö ---- */
- 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0 } J K L M N O P */
- 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8 Q R ---- ü */
- 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0 \ S T U V W X */
- 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8 Y Z ---- Ö ---- ---- ---- */
- 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0 0 1 2 3 4 5 6 7 */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */
- 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
-
-/*
- * EBCDIC (capitals) -> ASCII (small case)
- */
-__u8 _ebcasc_reduce_case[256] =
-{
- /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
-
- /* 0x08 -GE -SPS -RPT VT FF CR SO SI */
- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-
- /* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC
- -ENP ->LF */
- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
-
- /* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB
- -IUS */
- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC
- -INP */
- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
-
- /* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
- -SW */
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
-
- /* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
-
- /* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
-
- /* 0x40 SP RSP ä ---- */
- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
-
- /* 0x48 . < ( + | */
- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
-
- /* 0x50 & ---- */
- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
-
- /* 0x58 ß ! $ * ) ; */
- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
-
- /* 0x60 - / ---- Ä ---- ---- ---- */
- 0x2D, 0x2F, 0x07, 0x84, 0x07, 0x07, 0x07, 0x8F,
-
- /* 0x68 ---- , % _ > ? */
- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
-
- /* 0x70 ---- ---- ---- ---- ---- ---- ---- */
- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x78 * ` : # @ ' = " */
- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
-
- /* 0x80 * a b c d e f g */
- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0x88 h i ---- ---- ---- */
- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
-
- /* 0x90 ° j k l m n o p */
- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0x98 q r ---- ---- */
- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
-
- /* 0xA0 ~ s t u v w x */
- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xA8 y z ---- ---- ---- ---- */
- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xB0 ^ ---- § ---- */
- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
-
- /* 0xB8 ---- [ ] ---- ---- ---- ---- */
- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xC0 { A B C D E F G */
- 0x7B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0xC8 H I ---- ö ---- */
- 0x68, 0x69, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
-
- /* 0xD0 } J K L M N O P */
- 0x7D, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0xD8 Q R ---- ü */
- 0x71, 0x72, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
-
- /* 0xE0 \ S T U V W X */
- 0x5C, 0xF6, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xE8 Y Z ---- Ö ---- ---- ---- */
- 0x79, 0x7A, 0xFD, 0x07, 0x94, 0x07, 0x07, 0x07,
-
- /* 0xF0 0 1 2 3 4 5 6 7 */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-
- /* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */
- 0x38, 0x39, 0x07, 0x07, 0x81, 0x07, 0x07, 0x07
-};
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 6382c04d2bd..96eddb3b1d0 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_LCS) += lcs.o cu3088.o
obj-$(CONFIG_CLAW) += claw.o cu3088.o
-qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o qeth_core_offl.o
+qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
obj-$(CONFIG_QETH) += qeth.o
qeth_l2-y += qeth_l2_main.o
obj-$(CONFIG_QETH_L2) += qeth_l2.o
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index f5e618562c5..30a43cc79e7 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -60,6 +60,9 @@
* 1.25 Added Packing support
* 1.5
*/
+
+#define KMSG_COMPONENT "claw"
+
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
#include <asm/debug.h>
@@ -94,7 +97,7 @@
CLAW uses the s390dbf file system see claw_trace and claw_setup
*/
-
+static char version[] __initdata = "CLAW driver";
static char debug_buffer[255];
/**
* Debug Facility Stuff
@@ -206,20 +209,30 @@ static struct net_device_stats *claw_stats(struct net_device *dev);
static int pages_to_order_of_mag(int num_of_pages);
static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr);
/* sysfs Functions */
-static ssize_t claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_hname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_hname_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_hname_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_adname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_adname_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_adname_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_apname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_apname_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_apname_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_wbuff_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_wbuff_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_wbuff_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_rbuff_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_rbuff_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_rbuff_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
static int claw_add_files(struct device *dev);
static void claw_remove_files(struct device *dev);
@@ -298,8 +311,8 @@ claw_probe(struct ccwgroup_device *cgdev)
if (rc) {
probe_error(cgdev);
put_device(&cgdev->dev);
- printk(KERN_WARNING "add_files failed %s %s Exit Line %d \n",
- dev_name(&cgdev->cdev[0]->dev), __func__, __LINE__);
+ dev_err(&cgdev->dev, "Creating the /proc files for a new"
+ " CLAW device failed\n");
CLAW_DBF_TEXT_(2, setup, "probex%d", rc);
return rc;
}
@@ -335,6 +348,8 @@ claw_tx(struct sk_buff *skb, struct net_device *dev)
rc=claw_hw_tx( skb, dev, 1 );
spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags);
CLAW_DBF_TEXT_(4, trace, "clawtx%d", rc);
+ if (rc)
+ rc = NETDEV_TX_BUSY;
return rc;
} /* end of claw_tx */
@@ -496,7 +511,8 @@ claw_open(struct net_device *dev)
~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) ||
(((privptr->channel[READ].flag |
privptr->channel[WRITE].flag) & CLAW_TIMER) != 0x00)) {
- printk(KERN_INFO "%s: remote side is not ready\n", dev->name);
+ dev_info(&privptr->channel[READ].cdev->dev,
+ "%s: remote side is not ready\n", dev->name);
CLAW_DBF_TEXT(2, trace, "notrdy");
for ( i = 0; i < 2; i++) {
@@ -582,10 +598,9 @@ claw_irq_handler(struct ccw_device *cdev,
CLAW_DBF_TEXT(4, trace, "clawirq");
/* Bypass all 'unsolicited interrupts' */
if (!cdev->dev.driver_data) {
- printk(KERN_WARNING "claw: unsolicited interrupt for device:"
- "%s received c-%02x d-%02x\n",
- dev_name(&cdev->dev), irb->scsw.cmd.cstat,
- irb->scsw.cmd.dstat);
+ dev_warn(&cdev->dev, "An uninitialized CLAW device received an"
+ " IRQ, c-%02x d-%02x\n",
+ irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
CLAW_DBF_TEXT(2, trace, "badirq");
return;
}
@@ -597,8 +612,7 @@ claw_irq_handler(struct ccw_device *cdev,
else if (privptr->channel[WRITE].cdev == cdev)
p_ch = &privptr->channel[WRITE];
else {
- printk(KERN_WARNING "claw: Can't determine channel for "
- "interrupt, device %s\n", dev_name(&cdev->dev));
+ dev_warn(&cdev->dev, "The device is not a CLAW device\n");
CLAW_DBF_TEXT(2, trace, "badchan");
return;
}
@@ -612,7 +626,8 @@ claw_irq_handler(struct ccw_device *cdev,
/* Check for good subchannel return code, otherwise info message */
if (irb->scsw.cmd.cstat && !(irb->scsw.cmd.cstat & SCHN_STAT_PCI)) {
- printk(KERN_INFO "%s: subchannel check for device: %04x -"
+ dev_info(&cdev->dev,
+ "%s: subchannel check for device: %04x -"
" Sch Stat %02x Dev Stat %02x CPA - %04x\n",
dev->name, p_ch->devno,
irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
@@ -651,7 +666,7 @@ claw_irq_handler(struct ccw_device *cdev,
wake_up(&p_ch->wait); /* wake claw_open (READ)*/
} else if (p_ch->flag == CLAW_WRITE) {
p_ch->claw_state = CLAW_START_WRITE;
- /* send SYSTEM_VALIDATE */
+ /* send SYSTEM_VALIDATE */
claw_strt_read(dev, LOCK_NO);
claw_send_control(dev,
SYSTEM_VALIDATE_REQUEST,
@@ -659,10 +674,9 @@ claw_irq_handler(struct ccw_device *cdev,
p_env->host_name,
p_env->adapter_name);
} else {
- printk(KERN_WARNING "claw: unsolicited "
- "interrupt for device:"
- "%s received c-%02x d-%02x\n",
- dev_name(&cdev->dev),
+ dev_warn(&cdev->dev, "The CLAW device received"
+ " an unexpected IRQ, "
+ "c-%02x d-%02x\n",
irb->scsw.cmd.cstat,
irb->scsw.cmd.dstat);
return;
@@ -677,8 +691,8 @@ claw_irq_handler(struct ccw_device *cdev,
(p_ch->irb->ecw[0] & 0x40) == 0x40 ||
(p_ch->irb->ecw[0]) == 0) {
privptr->stats.rx_errors++;
- printk(KERN_INFO "%s: Restart is "
- "required after remote "
+ dev_info(&cdev->dev,
+ "%s: Restart is required after remote "
"side recovers \n",
dev->name);
}
@@ -713,11 +727,13 @@ claw_irq_handler(struct ccw_device *cdev,
return;
case CLAW_START_WRITE:
if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
- printk(KERN_INFO "%s: Unit Check Occured in "
+ dev_info(&cdev->dev,
+ "%s: Unit Check Occured in "
"write channel\n", dev->name);
clear_bit(0, (void *)&p_ch->IO_active);
if (p_ch->irb->ecw[0] & 0x80) {
- printk(KERN_INFO "%s: Resetting Event "
+ dev_info(&cdev->dev,
+ "%s: Resetting Event "
"occurred:\n", dev->name);
init_timer(&p_ch->timer);
p_ch->timer.function =
@@ -725,7 +741,8 @@ claw_irq_handler(struct ccw_device *cdev,
p_ch->timer.data = (unsigned long)p_ch;
p_ch->timer.expires = jiffies + 10*HZ;
add_timer(&p_ch->timer);
- printk(KERN_INFO "%s: write connection "
+ dev_info(&cdev->dev,
+ "%s: write connection "
"restarting\n", dev->name);
}
CLAW_DBF_TEXT(4, trace, "rstrtwrt");
@@ -733,9 +750,10 @@ claw_irq_handler(struct ccw_device *cdev,
}
if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) {
clear_bit(0, (void *)&p_ch->IO_active);
- printk(KERN_INFO "%s: Unit Exception "
- "Occured in write channel\n",
- dev->name);
+ dev_info(&cdev->dev,
+ "%s: Unit Exception "
+ "occurred in write channel\n",
+ dev->name);
}
if (!((p_ch->irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) ||
(p_ch->irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) ||
@@ -757,8 +775,9 @@ claw_irq_handler(struct ccw_device *cdev,
CLAW_DBF_TEXT(4, trace, "StWtExit");
return;
default:
- printk(KERN_WARNING "%s: wrong selection code - irq "
- "state=%d\n", dev->name, p_ch->claw_state);
+ dev_warn(&cdev->dev,
+ "The CLAW device for %s received an unexpected IRQ\n",
+ dev->name);
CLAW_DBF_TEXT(2, trace, "badIRQ");
return;
}
@@ -910,8 +929,10 @@ claw_release(struct net_device *dev)
if (((privptr->channel[READ].last_dstat |
privptr->channel[WRITE].last_dstat) &
~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) {
- printk(KERN_WARNING "%s: channel problems during close - "
- "read: %02x - write: %02x\n",
+ dev_warn(&privptr->channel[READ].cdev->dev,
+ "Deactivating %s completed with incorrect"
+ " subchannel status "
+ "(read %02x, write %02x)\n",
dev->name,
privptr->channel[READ].last_dstat,
privptr->channel[WRITE].last_dstat);
@@ -1012,7 +1033,7 @@ static int
pages_to_order_of_mag(int num_of_pages)
{
int order_of_mag=1; /* assume 2 pages */
- int nump=2;
+ int nump;
CLAW_DBF_TEXT_(5, trace, "pages%d", num_of_pages);
if (num_of_pages == 1) {return 0; } /* magnitude of 0 = 1 page */
@@ -1076,8 +1097,8 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
}
if ( privptr-> p_read_active_first ==NULL ) {
- privptr-> p_read_active_first= p_first; /* set new first */
- privptr-> p_read_active_last = p_last; /* set new last */
+ privptr->p_read_active_first = p_first; /* set new first */
+ privptr->p_read_active_last = p_last; /* set new last */
}
else {
@@ -1113,7 +1134,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
privptr->p_read_active_last->r_TIC_2.cda=
(__u32)__pa(&p_first->read);
}
- /* chain in new set of blocks */
+ /* chain in new set of blocks */
privptr->p_read_active_last->next = p_first;
privptr->p_read_active_last=p_last;
} /* end of if ( privptr-> p_read_active_first ==NULL) */
@@ -1135,21 +1156,18 @@ ccw_check_return_code(struct ccw_device *cdev, int return_code)
case -EBUSY: /* BUSY is a transient state no action needed */
break;
case -ENODEV:
- printk(KERN_EMERG "%s: Missing device called "
- "for IO ENODEV\n", dev_name(&cdev->dev));
- break;
- case -EIO:
- printk(KERN_EMERG "%s: Status pending... EIO \n",
- dev_name(&cdev->dev));
+ dev_err(&cdev->dev, "The remote channel adapter is not"
+ " available\n");
break;
case -EINVAL:
- printk(KERN_EMERG "%s: Invalid Dev State EINVAL \n",
- dev_name(&cdev->dev));
+ dev_err(&cdev->dev,
+ "The status of the remote channel adapter"
+ " is not valid\n");
break;
default:
- printk(KERN_EMERG "%s: Unknown error in "
- "Do_IO %d\n", dev_name(&cdev->dev),
- return_code);
+ dev_err(&cdev->dev, "The common device layer"
+ " returned error code %d\n",
+ return_code);
}
}
CLAW_DBF_TEXT(4, trace, "ccwret");
@@ -1163,42 +1181,37 @@ static void
ccw_check_unit_check(struct chbk * p_ch, unsigned char sense )
{
struct net_device *ndev = p_ch->ndev;
+ struct device *dev = &p_ch->cdev->dev;
CLAW_DBF_TEXT(4, trace, "unitchek");
- printk(KERN_INFO "%s: Unit Check with sense byte:0x%04x\n",
- ndev->name, sense);
-
- if (sense & 0x40) {
- if (sense & 0x01) {
- printk(KERN_WARNING "%s: Interface disconnect or "
- "Selective reset "
- "occurred (remote side)\n", ndev->name);
- }
- else {
- printk(KERN_WARNING "%s: System reset occured"
- " (remote side)\n", ndev->name);
- }
- }
- else if (sense & 0x20) {
- if (sense & 0x04) {
- printk(KERN_WARNING "%s: Data-streaming "
- "timeout)\n", ndev->name);
- }
- else {
- printk(KERN_WARNING "%s: Data-transfer parity"
- " error\n", ndev->name);
- }
- }
- else if (sense & 0x10) {
- if (sense & 0x20) {
- printk(KERN_WARNING "%s: Hardware malfunction "
- "(remote side)\n", ndev->name);
- }
- else {
- printk(KERN_WARNING "%s: read-data parity error "
- "(remote side)\n", ndev->name);
- }
- }
+ dev_warn(dev, "The communication peer of %s disconnected\n",
+ ndev->name);
+
+ if (sense & 0x40) {
+ if (sense & 0x01) {
+ dev_warn(dev, "The remote channel adapter for"
+ " %s has been reset\n",
+ ndev->name);
+ }
+ } else if (sense & 0x20) {
+ if (sense & 0x04) {
+ dev_warn(dev, "A data streaming timeout occurred"
+ " for %s\n",
+ ndev->name);
+ } else if (sense & 0x10) {
+ dev_warn(dev, "The remote channel adapter for %s"
+ " is faulty\n",
+ ndev->name);
+ } else {
+ dev_warn(dev, "A data transfer parity error occurred"
+ " for %s\n",
+ ndev->name);
+ }
+ } else if (sense & 0x10) {
+ dev_warn(dev, "A read data parity error occurred"
+ " for %s\n",
+ ndev->name);
+ }
} /* end of ccw_check_unit_check */
@@ -1235,7 +1248,7 @@ find_link(struct net_device *dev, char *host_name, char *ws_name )
break;
}
- return 0;
+ return rc;
} /* end of find_link */
/*-------------------------------------------------------------------*
@@ -1347,7 +1360,10 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
privptr->p_write_free_chain=p_this_ccw->next;
p_this_ccw->next=NULL;
--privptr->write_free_count; /* -1 */
- bytesInThisBuffer=len_of_data;
+ if (len_of_data >= privptr->p_env->write_size)
+ bytesInThisBuffer = privptr->p_env->write_size;
+ else
+ bytesInThisBuffer = len_of_data;
memcpy( p_this_ccw->p_buffer,pDataAddress, bytesInThisBuffer);
len_of_data-=bytesInThisBuffer;
pDataAddress+=(unsigned long)bytesInThisBuffer;
@@ -1375,7 +1391,7 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
*/
if (p_first_ccw!=NULL) {
- /* setup ending ccw sequence for this segment */
+ /* setup ending ccw sequence for this segment */
pEnd=privptr->p_end_ccw;
if (pEnd->write1) {
pEnd->write1=0x00; /* second end ccw is now active */
@@ -1697,10 +1713,11 @@ init_ccw_bk(struct net_device *dev)
p_buf-> w_TIC_1.flags = 0;
p_buf-> w_TIC_1.count = 0;
- if (((unsigned long)p_buff+privptr->p_env->write_size) >=
+ if (((unsigned long)p_buff +
+ privptr->p_env->write_size) >=
((unsigned long)(p_buff+2*
- (privptr->p_env->write_size) -1) & PAGE_MASK)) {
- p_buff= p_buff+privptr->p_env->write_size;
+ (privptr->p_env->write_size) - 1) & PAGE_MASK)) {
+ p_buff = p_buff+privptr->p_env->write_size;
}
}
}
@@ -1840,15 +1857,16 @@ init_ccw_bk(struct net_device *dev)
p_buf->header.opcode=0xff;
p_buf->header.flag=CLAW_PENDING;
- if (((unsigned long)p_buff+privptr->p_env->read_size) >=
- ((unsigned long)(p_buff+2*(privptr->p_env->read_size) -1)
- & PAGE_MASK) ) {
+ if (((unsigned long)p_buff+privptr->p_env->read_size) >=
+ ((unsigned long)(p_buff+2*(privptr->p_env->read_size)
+ -1)
+ & PAGE_MASK)) {
p_buff= p_buff+privptr->p_env->read_size;
}
else {
p_buff=
(void *)((unsigned long)
- (p_buff+2*(privptr->p_env->read_size) -1)
+ (p_buff+2*(privptr->p_env->read_size)-1)
& PAGE_MASK) ;
}
} /* for read_buffers */
@@ -1856,24 +1874,28 @@ init_ccw_bk(struct net_device *dev)
else { /* read Size >= PAGE_SIZE */
for (i=0 ; i< privptr->p_env->read_buffers ; i++) {
p_buff = (void *)__get_free_pages(__GFP_DMA,
- (int)pages_to_order_of_mag(privptr->p_buff_pages_perread) );
+ (int)pages_to_order_of_mag(
+ privptr->p_buff_pages_perread));
if (p_buff==NULL) {
free_pages((unsigned long)privptr->p_buff_ccw,
- (int)pages_to_order_of_mag(privptr->p_buff_ccw_num));
+ (int)pages_to_order_of_mag(privptr->
+ p_buff_ccw_num));
/* free the write pages */
p_buf=privptr->p_buff_write;
while (p_buf!=NULL) {
- free_pages((unsigned long)p_buf->p_buffer,
- (int)pages_to_order_of_mag(
- privptr->p_buff_pages_perwrite ));
+ free_pages(
+ (unsigned long)p_buf->p_buffer,
+ (int)pages_to_order_of_mag(
+ privptr->p_buff_pages_perwrite));
p_buf=p_buf->next;
}
/* free any read pages already alloc */
p_buf=privptr->p_buff_read;
while (p_buf!=NULL) {
- free_pages((unsigned long)p_buf->p_buffer,
- (int)pages_to_order_of_mag(
- privptr->p_buff_pages_perread ));
+ free_pages(
+ (unsigned long)p_buf->p_buffer,
+ (int)pages_to_order_of_mag(
+ privptr->p_buff_pages_perread));
p_buf=p_buf->next;
}
privptr->p_buff_ccw=NULL;
@@ -2003,7 +2025,7 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
tdev = &privptr->channel[READ].cdev->dev;
memcpy( &temp_host_name, p_env->host_name, 8);
memcpy( &temp_ws_name, p_env->adapter_name , 8);
- printk(KERN_INFO "%s: CLAW device %.8s: "
+ dev_info(tdev, "%s: CLAW device %.8s: "
"Received Control Packet\n",
dev->name, temp_ws_name);
if (privptr->release_pend==1) {
@@ -2022,32 +2044,30 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
if (p_ctlbk->version != CLAW_VERSION_ID) {
claw_snd_sys_validate_rsp(dev, p_ctlbk,
CLAW_RC_WRONG_VERSION);
- printk("%s: %d is wrong version id. "
- "Expected %d\n",
- dev->name, p_ctlbk->version,
- CLAW_VERSION_ID);
+ dev_warn(tdev, "The communication peer of %s"
+ " uses an incorrect API version %d\n",
+ dev->name, p_ctlbk->version);
}
p_sysval = (struct sysval *)&(p_ctlbk->data);
- printk("%s: Recv Sys Validate Request: "
- "Vers=%d,link_id=%d,Corr=%d,WS name=%."
- "8s,Host name=%.8s\n",
- dev->name, p_ctlbk->version,
- p_ctlbk->linkid,
- p_ctlbk->correlator,
- p_sysval->WS_name,
- p_sysval->host_name);
+ dev_info(tdev, "%s: Recv Sys Validate Request: "
+ "Vers=%d,link_id=%d,Corr=%d,WS name=%.8s,"
+ "Host name=%.8s\n",
+ dev->name, p_ctlbk->version,
+ p_ctlbk->linkid,
+ p_ctlbk->correlator,
+ p_sysval->WS_name,
+ p_sysval->host_name);
if (memcmp(temp_host_name, p_sysval->host_name, 8)) {
claw_snd_sys_validate_rsp(dev, p_ctlbk,
CLAW_RC_NAME_MISMATCH);
CLAW_DBF_TEXT(2, setup, "HSTBAD");
CLAW_DBF_TEXT_(2, setup, "%s", p_sysval->host_name);
CLAW_DBF_TEXT_(2, setup, "%s", temp_host_name);
- printk(KERN_INFO "%s: Host name mismatch\n",
- dev->name);
- printk(KERN_INFO "%s: Received :%s: "
- "expected :%s: \n",
- dev->name,
+ dev_warn(tdev,
+ "Host name %s for %s does not match the"
+ " remote adapter name %s\n",
p_sysval->host_name,
+ dev->name,
temp_host_name);
}
if (memcmp(temp_ws_name, p_sysval->WS_name, 8)) {
@@ -2056,35 +2076,38 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
CLAW_DBF_TEXT(2, setup, "WSNBAD");
CLAW_DBF_TEXT_(2, setup, "%s", p_sysval->WS_name);
CLAW_DBF_TEXT_(2, setup, "%s", temp_ws_name);
- printk(KERN_INFO "%s: WS name mismatch\n",
- dev->name);
- printk(KERN_INFO "%s: Received :%s: "
- "expected :%s: \n",
- dev->name,
- p_sysval->WS_name,
- temp_ws_name);
+ dev_warn(tdev, "Adapter name %s for %s does not match"
+ " the remote host name %s\n",
+ p_sysval->WS_name,
+ dev->name,
+ temp_ws_name);
}
if ((p_sysval->write_frame_size < p_env->write_size) &&
(p_env->packing == 0)) {
claw_snd_sys_validate_rsp(dev, p_ctlbk,
CLAW_RC_HOST_RCV_TOO_SMALL);
- printk(KERN_INFO "%s: host write size is too "
- "small\n", dev->name);
+ dev_warn(tdev,
+ "The local write buffer is smaller than the"
+ " remote read buffer\n");
CLAW_DBF_TEXT(2, setup, "wrtszbad");
}
if ((p_sysval->read_frame_size < p_env->read_size) &&
(p_env->packing == 0)) {
claw_snd_sys_validate_rsp(dev, p_ctlbk,
CLAW_RC_HOST_RCV_TOO_SMALL);
- printk(KERN_INFO "%s: host read size is too "
- "small\n", dev->name);
+ dev_warn(tdev,
+ "The local read buffer is smaller than the"
+ " remote write buffer\n");
CLAW_DBF_TEXT(2, setup, "rdsizbad");
}
claw_snd_sys_validate_rsp(dev, p_ctlbk, 0);
- printk(KERN_INFO "%s: CLAW device %.8s: System validate "
- "completed.\n", dev->name, temp_ws_name);
- printk("%s: sys Validate Rsize:%d Wsize:%d\n", dev->name,
- p_sysval->read_frame_size, p_sysval->write_frame_size);
+ dev_info(tdev,
+ "CLAW device %.8s: System validate"
+ " completed.\n", temp_ws_name);
+ dev_info(tdev,
+ "%s: sys Validate Rsize:%d Wsize:%d\n",
+ dev->name, p_sysval->read_frame_size,
+ p_sysval->write_frame_size);
privptr->system_validate_comp = 1;
if (strncmp(p_env->api_type, WS_APPL_NAME_PACKED, 6) == 0)
p_env->packing = PACKING_ASK;
@@ -2092,8 +2115,10 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
break;
case SYSTEM_VALIDATE_RESPONSE:
p_sysval = (struct sysval *)&(p_ctlbk->data);
- printk("%s: Recv Sys Validate Resp: Vers=%d,Corr=%d,RC=%d,"
- "WS name=%.8s,Host name=%.8s\n",
+ dev_info(tdev,
+ "Settings for %s validated (version=%d, "
+ "remote device=%d, rc=%d, adapter name=%.8s, "
+ "host name=%.8s)\n",
dev->name,
p_ctlbk->version,
p_ctlbk->correlator,
@@ -2102,41 +2127,39 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
p_sysval->host_name);
switch (p_ctlbk->rc) {
case 0:
- printk(KERN_INFO "%s: CLAW device "
- "%.8s: System validate "
- "completed.\n",
- dev->name, temp_ws_name);
+ dev_info(tdev, "%s: CLAW device "
+ "%.8s: System validate completed.\n",
+ dev->name, temp_ws_name);
if (privptr->system_validate_comp == 0)
claw_strt_conn_req(dev);
privptr->system_validate_comp = 1;
break;
case CLAW_RC_NAME_MISMATCH:
- printk(KERN_INFO "%s: Sys Validate "
- "Resp : Host, WS name is "
- "mismatch\n",
- dev->name);
+ dev_warn(tdev, "Validating %s failed because of"
+ " a host or adapter name mismatch\n",
+ dev->name);
break;
case CLAW_RC_WRONG_VERSION:
- printk(KERN_INFO "%s: Sys Validate "
- "Resp : Wrong version\n",
+ dev_warn(tdev, "Validating %s failed because of a"
+ " version conflict\n",
dev->name);
break;
case CLAW_RC_HOST_RCV_TOO_SMALL:
- printk(KERN_INFO "%s: Sys Validate "
- "Resp : bad frame size\n",
+ dev_warn(tdev, "Validating %s failed because of a"
+ " frame size conflict\n",
dev->name);
break;
default:
- printk(KERN_INFO "%s: Sys Validate "
- "error code=%d \n",
- dev->name, p_ctlbk->rc);
+ dev_warn(tdev, "The communication peer of %s rejected"
+ " the connection\n",
+ dev->name);
break;
}
break;
case CONNECTION_REQUEST:
p_connect = (struct conncmd *)&(p_ctlbk->data);
- printk(KERN_INFO "%s: Recv Conn Req: Vers=%d,link_id=%d,"
+ dev_info(tdev, "%s: Recv Conn Req: Vers=%d,link_id=%d,"
"Corr=%d,HOST appl=%.8s,WS appl=%.8s\n",
dev->name,
p_ctlbk->version,
@@ -2146,21 +2169,21 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
p_connect->WS_name);
if (privptr->active_link_ID != 0) {
claw_snd_disc(dev, p_ctlbk);
- printk(KERN_INFO "%s: Conn Req error : "
- "already logical link is active \n",
+ dev_info(tdev, "%s rejected a connection request"
+ " because it is already active\n",
dev->name);
}
if (p_ctlbk->linkid != 1) {
claw_snd_disc(dev, p_ctlbk);
- printk(KERN_INFO "%s: Conn Req error : "
- "req logical link id is not 1\n",
+ dev_info(tdev, "%s rejected a request to open multiple"
+ " connections\n",
dev->name);
}
rc = find_link(dev, p_connect->host_name, p_connect->WS_name);
if (rc != 0) {
claw_snd_disc(dev, p_ctlbk);
- printk(KERN_INFO "%s: Conn Resp error: "
- "req appl name does not match\n",
+ dev_info(tdev, "%s rejected a connection request"
+ " because of a type mismatch\n",
dev->name);
}
claw_send_control(dev,
@@ -2172,7 +2195,7 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
p_env->packing = PACK_SEND;
claw_snd_conn_req(dev, 0);
}
- printk(KERN_INFO "%s: CLAW device %.8s: Connection "
+ dev_info(tdev, "%s: CLAW device %.8s: Connection "
"completed link_id=%d.\n",
dev->name, temp_ws_name,
p_ctlbk->linkid);
@@ -2182,7 +2205,7 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
break;
case CONNECTION_RESPONSE:
p_connect = (struct conncmd *)&(p_ctlbk->data);
- printk(KERN_INFO "%s: Revc Conn Resp: Vers=%d,link_id=%d,"
+ dev_info(tdev, "%s: Recv Conn Resp: Vers=%d,link_id=%d,"
"Corr=%d,RC=%d,Host appl=%.8s, WS appl=%.8s\n",
dev->name,
p_ctlbk->version,
@@ -2193,16 +2216,18 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
p_connect->WS_name);
if (p_ctlbk->rc != 0) {
- printk(KERN_INFO "%s: Conn Resp error: rc=%d \n",
- dev->name, p_ctlbk->rc);
+ dev_warn(tdev, "The communication peer of %s rejected"
+ " a connection request\n",
+ dev->name);
return 1;
}
rc = find_link(dev,
p_connect->host_name, p_connect->WS_name);
if (rc != 0) {
claw_snd_disc(dev, p_ctlbk);
- printk(KERN_INFO "%s: Conn Resp error: "
- "req appl name does not match\n",
+ dev_warn(tdev, "The communication peer of %s"
+ " rejected a connection "
+ "request because of a type mismatch\n",
dev->name);
}
/* should be until CONNECTION_CONFIRM */
@@ -2210,7 +2235,8 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
break;
case CONNECTION_CONFIRM:
p_connect = (struct conncmd *)&(p_ctlbk->data);
- printk(KERN_INFO "%s: Recv Conn Confirm:Vers=%d,link_id=%d,"
+ dev_info(tdev,
+ "%s: Recv Conn Confirm:Vers=%d,link_id=%d,"
"Corr=%d,Host appl=%.8s,WS appl=%.8s\n",
dev->name,
p_ctlbk->version,
@@ -2221,21 +2247,21 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
if (p_ctlbk->linkid == -(privptr->active_link_ID)) {
privptr->active_link_ID = p_ctlbk->linkid;
if (p_env->packing > PACKING_ASK) {
- printk(KERN_INFO "%s: Confirmed Now packing\n",
- dev->name);
+ dev_info(tdev,
+ "%s: Confirmed Now packing\n", dev->name);
p_env->packing = DO_PACKED;
}
p_ch = &privptr->channel[WRITE];
wake_up(&p_ch->wait);
} else {
- printk(KERN_INFO "%s: Conn confirm: "
- "unexpected linkid=%d \n",
+ dev_warn(tdev, "Activating %s failed because of"
+ " an incorrect link ID=%d\n",
dev->name, p_ctlbk->linkid);
claw_snd_disc(dev, p_ctlbk);
}
break;
case DISCONNECT:
- printk(KERN_INFO "%s: Disconnect: "
+ dev_info(tdev, "%s: Disconnect: "
"Vers=%d,link_id=%d,Corr=%d\n",
dev->name, p_ctlbk->version,
p_ctlbk->linkid, p_ctlbk->correlator);
@@ -2247,12 +2273,13 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
privptr->active_link_ID = 0;
break;
case CLAW_ERROR:
- printk(KERN_INFO "%s: CLAW ERROR detected\n",
+ dev_warn(tdev, "The communication peer of %s failed\n",
dev->name);
break;
default:
- printk(KERN_INFO "%s: Unexpected command code=%d \n",
- dev->name, p_ctlbk->command);
+ dev_warn(tdev, "The communication peer of %s sent"
+ " an unknown command code\n",
+ dev->name);
break;
}
@@ -2294,12 +2321,14 @@ claw_send_control(struct net_device *dev, __u8 type, __u8 link,
memcpy(&p_sysval->host_name, local_name, 8);
memcpy(&p_sysval->WS_name, remote_name, 8);
if (privptr->p_env->packing > 0) {
- p_sysval->read_frame_size=DEF_PACK_BUFSIZE;
- p_sysval->write_frame_size=DEF_PACK_BUFSIZE;
+ p_sysval->read_frame_size = DEF_PACK_BUFSIZE;
+ p_sysval->write_frame_size = DEF_PACK_BUFSIZE;
} else {
/* how big is the biggest group of packets */
- p_sysval->read_frame_size=privptr->p_env->read_size;
- p_sysval->write_frame_size=privptr->p_env->write_size;
+ p_sysval->read_frame_size =
+ privptr->p_env->read_size;
+ p_sysval->write_frame_size =
+ privptr->p_env->write_size;
}
memset(&p_sysval->reserved, 0x00, 4);
break;
@@ -2485,7 +2514,6 @@ unpack_read(struct net_device *dev )
p_dev = &privptr->channel[READ].cdev->dev;
p_env = privptr->p_env;
p_this_ccw=privptr->p_read_active_first;
- i=0;
while (p_this_ccw!=NULL && p_this_ccw->header.flag!=CLAW_PENDING) {
pack_off = 0;
p = 0;
@@ -2511,8 +2539,10 @@ unpack_read(struct net_device *dev )
mtc_this_frm=1;
if (p_this_ccw->header.length!=
privptr->p_env->read_size ) {
- printk(KERN_INFO " %s: Invalid frame detected "
- "length is %02x\n" ,
+ dev_warn(p_dev,
+ "The communication peer of %s"
+ " sent a faulty"
+ " frame of length %02x\n",
dev->name, p_this_ccw->header.length);
}
}
@@ -2544,7 +2574,7 @@ unpack_next:
goto NextFrame;
p_packd = p_this_ccw->p_buffer+pack_off;
p_packh = (struct clawph *) p_packd;
- if ((p_packh->len == 0) || /* all done with this frame? */
+ if ((p_packh->len == 0) || /* done with this frame? */
(p_packh->flag != 0))
goto NextFrame;
bytes_to_mov = p_packh->len;
@@ -2594,9 +2624,9 @@ unpack_next:
netif_rx(skb);
}
else {
+ dev_info(p_dev, "Allocating a buffer for"
+ " incoming data failed\n");
privptr->stats.rx_dropped++;
- printk(KERN_WARNING "%s: %s() low on memory\n",
- dev->name,__func__);
}
privptr->mtc_offset=0;
privptr->mtc_logical_link=-1;
@@ -2720,8 +2750,8 @@ claw_strt_out_IO( struct net_device *dev )
if (test_and_set_bit(0, (void *)&p_ch->IO_active) == 0) {
parm = (unsigned long) p_ch;
CLAW_DBF_TEXT(2, trace, "StWrtIO");
- rc = ccw_device_start (p_ch->cdev,&p_first_ccw->write, parm,
- 0xff, 0);
+ rc = ccw_device_start(p_ch->cdev, &p_first_ccw->write, parm,
+ 0xff, 0);
if (rc != 0) {
ccw_check_return_code(p_ch->cdev, rc);
}
@@ -2816,22 +2846,26 @@ claw_free_netdevice(struct net_device * dev, int free_dev)
* Initialize everything of the net device except the name and the
* channel structs.
*/
+static const struct net_device_ops claw_netdev_ops = {
+ .ndo_open = claw_open,
+ .ndo_stop = claw_release,
+ .ndo_get_stats = claw_stats,
+ .ndo_start_xmit = claw_tx,
+ .ndo_change_mtu = claw_change_mtu,
+};
+
static void
claw_init_netdevice(struct net_device * dev)
{
CLAW_DBF_TEXT(2, setup, "init_dev");
CLAW_DBF_TEXT_(2, setup, "%s", dev->name);
dev->mtu = CLAW_DEFAULT_MTU_SIZE;
- dev->hard_start_xmit = claw_tx;
- dev->open = claw_open;
- dev->stop = claw_release;
- dev->get_stats = claw_stats;
- dev->change_mtu = claw_change_mtu;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 1300;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->netdev_ops = &claw_netdev_ops;
CLAW_DBF_TEXT(2, setup, "initok");
return;
}
@@ -2880,8 +2914,8 @@ claw_new_device(struct ccwgroup_device *cgdev)
int ret;
struct ccw_dev_id dev_id;
- printk(KERN_INFO "claw: add for %s\n",
- dev_name(&cgdev->cdev[READ]->dev));
+ dev_info(&cgdev->dev, "add for %s\n",
+ dev_name(&cgdev->cdev[READ]->dev));
CLAW_DBF_TEXT(2, setup, "new_dev");
privptr = cgdev->dev.driver_data;
cgdev->cdev[READ]->dev.driver_data = privptr;
@@ -2897,29 +2931,28 @@ claw_new_device(struct ccwgroup_device *cgdev)
if (ret == 0)
ret = add_channel(cgdev->cdev[1],1,privptr);
if (ret != 0) {
- printk(KERN_WARNING
- "add channel failed with ret = %d\n", ret);
+ dev_warn(&cgdev->dev, "Creating a CLAW group device"
+ " failed with error code %d\n", ret);
goto out;
}
ret = ccw_device_set_online(cgdev->cdev[READ]);
if (ret != 0) {
- printk(KERN_WARNING
- "claw: ccw_device_set_online %s READ failed "
- "with ret = %d\n", dev_name(&cgdev->cdev[READ]->dev),
- ret);
+ dev_warn(&cgdev->dev,
+ "Setting the read subchannel online"
+ " failed with error code %d\n", ret);
goto out;
}
ret = ccw_device_set_online(cgdev->cdev[WRITE]);
if (ret != 0) {
- printk(KERN_WARNING
- "claw: ccw_device_set_online %s WRITE failed "
- "with ret = %d\n", dev_name(&cgdev->cdev[WRITE]->dev),
- ret);
+ dev_warn(&cgdev->dev,
+ "Setting the write subchannel online "
+ "failed with error code %d\n", ret);
goto out;
}
dev = alloc_netdev(0,"claw%d",claw_init_netdevice);
if (!dev) {
- printk(KERN_WARNING "%s:alloc_netdev failed\n",__func__);
+ dev_warn(&cgdev->dev,
+ "Activating the CLAW device failed\n");
goto out;
}
dev->ml_priv = privptr;
@@ -2947,13 +2980,13 @@ claw_new_device(struct ccwgroup_device *cgdev)
privptr->channel[WRITE].ndev = dev;
privptr->p_env->ndev = dev;
- printk(KERN_INFO "%s:readsize=%d writesize=%d "
+ dev_info(&cgdev->dev, "%s:readsize=%d writesize=%d "
"readbuffer=%d writebuffer=%d read=0x%04x write=0x%04x\n",
dev->name, p_env->read_size,
p_env->write_size, p_env->read_buffers,
p_env->write_buffers, p_env->devno[READ],
p_env->devno[WRITE]);
- printk(KERN_INFO "%s:host_name:%.8s, adapter_name "
+ dev_info(&cgdev->dev, "%s:host_name:%.8s, adapter_name "
":%.8s api_type: %.8s\n",
dev->name, p_env->host_name,
p_env->adapter_name , p_env->api_type);
@@ -2997,8 +3030,8 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
ndev = priv->channel[READ].ndev;
if (ndev) {
/* Close the device */
- printk(KERN_INFO
- "%s: shuting down \n",ndev->name);
+ dev_info(&cgdev->dev, "%s: shutting down \n",
+ ndev->name);
if (ndev->flags & IFF_RUNNING)
ret = claw_release(ndev);
ndev->flags &=~IFF_RUNNING;
@@ -3023,8 +3056,7 @@ claw_remove_device(struct ccwgroup_device *cgdev)
CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
priv = cgdev->dev.driver_data;
BUG_ON(!priv);
- printk(KERN_INFO "claw: %s() called %s will be removed.\n",
- __func__, dev_name(&cgdev->cdev[0]->dev));
+ dev_info(&cgdev->dev, " will be removed.\n");
if (cgdev->state == CCWGROUP_ONLINE)
claw_shutdown_device(cgdev);
claw_remove_files(&cgdev->dev);
@@ -3063,7 +3095,8 @@ claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_hname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_hname_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -3100,7 +3133,8 @@ claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_adname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_adname_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -3138,7 +3172,8 @@ claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_apname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_apname_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -3185,7 +3220,8 @@ claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_wbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_wbuff_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -3226,7 +3262,8 @@ claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_rbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_rbuff_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env *p_env;
@@ -3289,7 +3326,7 @@ claw_cleanup(void)
{
unregister_cu3088_discipline(&claw_group_driver);
claw_unregister_debug_facility();
- printk(KERN_INFO "claw: Driver unloaded\n");
+ pr_info("Driver unloaded\n");
}
@@ -3303,12 +3340,12 @@ static int __init
claw_init(void)
{
int ret = 0;
- printk(KERN_INFO "claw: starting driver\n");
+ pr_info("Loading %s\n", version);
ret = claw_register_debug_facility();
if (ret) {
- printk(KERN_WARNING "claw: %s() debug_register failed %d\n",
- __func__,ret);
+ pr_err("Registering with the S/390 debug feature"
+ " failed with error code %d\n", ret);
return ret;
}
CLAW_DBF_TEXT(2, setup, "init_mod");
@@ -3316,8 +3353,8 @@ claw_init(void)
if (ret) {
CLAW_DBF_TEXT(2, setup, "init_bad");
claw_unregister_debug_facility();
- printk(KERN_WARNING "claw; %s() cu3088 register failed %d\n",
- __func__,ret);
+ pr_err("Registering with the cu3088 device driver failed "
+ "with error code %d\n", ret);
}
return ret;
}
diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c
index f29c7086fc1..4ded9ac2c5e 100644
--- a/drivers/s390/net/ctcm_fsms.c
+++ b/drivers/s390/net/ctcm_fsms.c
@@ -410,9 +410,8 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
priv->stats.rx_length_errors++;
goto again;
}
- block_len -= 2;
- if (block_len > 0) {
- *((__u16 *)skb->data) = block_len;
+ if (block_len > 2) {
+ *((__u16 *)skb->data) = block_len - 2;
ctcm_unpack_skb(ch, skb);
}
again:
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 2678573bece..77f4033a0f4 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -105,7 +105,8 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
return;
}
pskb->protocol = ntohs(header->type);
- if (header->length <= LL_HEADER_LENGTH) {
+ if ((header->length <= LL_HEADER_LENGTH) ||
+ (len <= LL_HEADER_LENGTH)) {
if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
"%s(%s): Illegal packet size %d(%d,%d)"
@@ -167,11 +168,9 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
if (len > 0) {
skb_pull(pskb, header->length);
if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
- if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
- CTCM_DBF_DEV_NAME(TRACE, dev,
- "Overrun in ctcm_unpack_skb");
- ch->logflags |= LOG_FLAG_OVERRUN;
- }
+ CTCM_DBF_DEV_NAME(TRACE, dev,
+ "Overrun in ctcm_unpack_skb");
+ ch->logflags |= LOG_FLAG_OVERRUN;
return;
}
skb_put(pskb, LL_HEADER_LENGTH);
@@ -906,11 +905,11 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
}
if (ctcm_test_and_set_busy(dev))
- return -EBUSY;
+ return NETDEV_TX_BUSY;
dev->trans_start = jiffies;
if (ctcm_transmit_skb(priv->channel[WRITE], skb) != 0)
- return 1;
+ return NETDEV_TX_BUSY;
return 0;
}
@@ -1099,12 +1098,24 @@ static void ctcm_free_netdevice(struct net_device *dev)
struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv);
+static const struct net_device_ops ctcm_netdev_ops = {
+ .ndo_open = ctcm_open,
+ .ndo_stop = ctcm_close,
+ .ndo_get_stats = ctcm_stats,
+ .ndo_change_mtu = ctcm_change_mtu,
+ .ndo_start_xmit = ctcm_tx,
+};
+
+static const struct net_device_ops ctcm_mpc_netdev_ops = {
+ .ndo_open = ctcm_open,
+ .ndo_stop = ctcm_close,
+ .ndo_get_stats = ctcm_stats,
+ .ndo_change_mtu = ctcm_change_mtu,
+ .ndo_start_xmit = ctcmpc_tx,
+};
+
void static ctcm_dev_setup(struct net_device *dev)
{
- dev->open = ctcm_open;
- dev->stop = ctcm_close;
- dev->get_stats = ctcm_stats;
- dev->change_mtu = ctcm_change_mtu;
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 100;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
@@ -1157,12 +1168,12 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
dev->mtu = MPC_BUFSIZE_DEFAULT -
TH_HEADER_LENGTH - PDU_HEADER_LENGTH;
- dev->hard_start_xmit = ctcmpc_tx;
+ dev->netdev_ops = &ctcm_mpc_netdev_ops;
dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
priv->buffer_size = MPC_BUFSIZE_DEFAULT;
} else {
dev->mtu = CTCM_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
- dev->hard_start_xmit = ctcm_tx;
+ dev->netdev_ops = &ctcm_netdev_ops;
dev->hard_header_len = LL_HEADER_LENGTH + 2;
}
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index 3db5f846bbf..781e18be7e8 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -393,7 +393,6 @@ int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int))
} else {
/* there are problems...bail out */
/* there may be a state mismatch so restart */
- grp->port_persist = 1;
fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
grp->allocchan_callback_retries = 0;
}
@@ -699,11 +698,9 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
return;
done:
- if (rc != 0) {
- grp->in_sweep = 0;
- ctcm_clear_busy_do(dev);
- fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
- }
+ grp->in_sweep = 0;
+ ctcm_clear_busy_do(dev);
+ fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
return;
}
@@ -1118,7 +1115,6 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
if (unlikely(fsm_getstate(grp->fsm) != MPCG_STATE_READY))
goto done;
- pdu_last_seen = 0;
while ((pskb->len > 0) && !pdu_last_seen) {
curr_pdu = (struct pdu *)pskb->data;
@@ -1396,8 +1392,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
CTCM_FUNTAIL, dev->name);
if ((grp->saved_state != MPCG_STATE_RESET) ||
/* dealloc_channel has been called */
- ((grp->saved_state == MPCG_STATE_RESET) &&
- (grp->port_persist == 0)))
+ (grp->port_persist == 0))
fsm_deltimer(&priv->restart_timer);
wch = priv->channel[WRITE];
@@ -1917,10 +1912,8 @@ static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg)
if (priv)
grp = priv->mpcg;
- if (grp == NULL) {
- fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
+ if (grp == NULL)
return;
- }
for (direction = READ; direction <= WRITE; direction++) {
struct channel *ch = priv->channel[direction];
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index acca6678cb2..a45bc24eb5f 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -39,6 +39,7 @@
#include <linux/in.h>
#include <linux/igmp.h>
#include <linux/delay.h>
+#include <linux/kthread.h>
#include <net/arp.h>
#include <net/ip.h>
@@ -70,7 +71,9 @@ static char debug_buffer[255];
static void lcs_tasklet(unsigned long);
static void lcs_start_kernel_thread(struct work_struct *);
static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *);
+#ifdef CONFIG_IP_MULTICAST
static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *);
+#endif /* CONFIG_IP_MULTICAST */
static int lcs_recovery(void *ptr);
/**
@@ -1257,7 +1260,6 @@ lcs_register_mc_addresses(void *data)
struct in_device *in4_dev;
card = (struct lcs_card *) data;
- daemonize("regipm");
if (!lcs_do_run_thread(card, LCS_SET_MC_THREAD))
return 0;
@@ -1285,6 +1287,8 @@ out:
lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD);
return 0;
}
+#endif /* CONFIG_IP_MULTICAST */
+
/**
* function called by net device to
* handle multicast address relevant things
@@ -1292,6 +1296,7 @@ out:
static void
lcs_set_multicast_list(struct net_device *dev)
{
+#ifdef CONFIG_IP_MULTICAST
struct lcs_card *card;
LCS_DBF_TEXT(4, trace, "setmulti");
@@ -1299,9 +1304,8 @@ lcs_set_multicast_list(struct net_device *dev)
if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD))
schedule_work(&card->kernel_thread_starter);
-}
-
#endif /* CONFIG_IP_MULTICAST */
+}
static long
lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb)
@@ -1558,7 +1562,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
if (skb == NULL) {
card->stats.tx_dropped++;
card->stats.tx_errors++;
- return -EIO;
+ return 0;
}
if (card->state != DEV_STATE_UP) {
dev_kfree_skb(skb);
@@ -1583,7 +1587,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
card->tx_buffer = lcs_get_buffer(&card->write);
if (card->tx_buffer == NULL) {
card->stats.tx_dropped++;
- rc = -EBUSY;
+ rc = NETDEV_TX_BUSY;
goto out;
}
card->tx_buffer->callback = lcs_txbuffer_cb;
@@ -1749,11 +1753,10 @@ lcs_start_kernel_thread(struct work_struct *work)
struct lcs_card *card = container_of(work, struct lcs_card, kernel_thread_starter);
LCS_DBF_TEXT(5, trace, "krnthrd");
if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD))
- kernel_thread(lcs_recovery, (void *) card, SIGCHLD);
+ kthread_run(lcs_recovery, card, "lcs_recover");
#ifdef CONFIG_IP_MULTICAST
if (lcs_do_start_thread(card, LCS_SET_MC_THREAD))
- kernel_thread(lcs_register_mc_addresses,
- (void *) card, SIGCHLD);
+ kthread_run(lcs_register_mc_addresses, card, "regipm");
#endif
}
@@ -2097,6 +2100,20 @@ lcs_register_netdev(struct ccwgroup_device *ccwgdev)
/**
* lcs_new_device will be called by setting the group device online.
*/
+static const struct net_device_ops lcs_netdev_ops = {
+ .ndo_open = lcs_open_device,
+ .ndo_stop = lcs_stop_device,
+ .ndo_get_stats = lcs_getstats,
+ .ndo_start_xmit = lcs_start_xmit,
+};
+
+static const struct net_device_ops lcs_mc_netdev_ops = {
+ .ndo_open = lcs_open_device,
+ .ndo_stop = lcs_stop_device,
+ .ndo_get_stats = lcs_getstats,
+ .ndo_start_xmit = lcs_start_xmit,
+ .ndo_set_multicast_list = lcs_set_multicast_list,
+};
static int
lcs_new_device(struct ccwgroup_device *ccwgdev)
@@ -2164,14 +2181,11 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
goto out;
card->dev = dev;
card->dev->ml_priv = card;
- card->dev->open = lcs_open_device;
- card->dev->stop = lcs_stop_device;
- card->dev->hard_start_xmit = lcs_start_xmit;
- card->dev->get_stats = lcs_getstats;
+ card->dev->netdev_ops = &lcs_netdev_ops;
memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH);
#ifdef CONFIG_IP_MULTICAST
if (!lcs_check_multicast_support(card))
- card->dev->set_multicast_list = lcs_set_multicast_list;
+ card->dev->netdev_ops = &lcs_mc_netdev_ops;
#endif
netdev_out:
lcs_set_allowed_threads(card,0xffffffff);
@@ -2254,7 +2268,6 @@ lcs_recovery(void *ptr)
int rc;
card = (struct lcs_card *) ptr;
- daemonize("lcs_recover");
LCS_DBF_TEXT(4, trace, "recover1");
if (!lcs_do_run_thread(card, LCS_RECOVERY_THREAD))
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 930e2fc2a01..be716e45f7a 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1312,7 +1312,7 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
if (netiucv_test_and_set_busy(dev)) {
IUCV_DBF_TEXT(data, 2, "EBUSY from netiucv_tx\n");
- return -EBUSY;
+ return NETDEV_TX_BUSY;
}
dev->trans_start = jiffies;
rc = netiucv_transmit_skb(privptr->conn, skb) != 0;
@@ -1876,20 +1876,24 @@ static void netiucv_free_netdevice(struct net_device *dev)
/**
* Initialize a net device. (Called from kernel in alloc_netdev())
*/
+static const struct net_device_ops netiucv_netdev_ops = {
+ .ndo_open = netiucv_open,
+ .ndo_stop = netiucv_close,
+ .ndo_get_stats = netiucv_stats,
+ .ndo_start_xmit = netiucv_tx,
+ .ndo_change_mtu = netiucv_change_mtu,
+};
+
static void netiucv_setup_netdevice(struct net_device *dev)
{
dev->mtu = NETIUCV_MTU_DEFAULT;
- dev->hard_start_xmit = netiucv_tx;
- dev->open = netiucv_open;
- dev->stop = netiucv_close;
- dev->get_stats = netiucv_stats;
- dev->change_mtu = netiucv_change_mtu;
dev->destructor = netiucv_free_netdevice;
dev->hard_header_len = NETIUCV_HDRLEN;
dev->addr_len = 0;
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = NETIUCV_QUEUELEN_DEFAULT;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->netdev_ops = &netiucv_netdev_ops;
}
/**
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index e0c45574b0c..447e1d19581 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -134,6 +134,7 @@ struct qeth_perf_stats {
unsigned int sg_skbs_rx;
unsigned int sg_frags_rx;
unsigned int sg_alloc_page_rx;
+ unsigned int tx_csum;
};
/* Routing stuff */
@@ -403,7 +404,6 @@ struct qeth_qdio_q {
/* possible types of qeth large_send support */
enum qeth_large_send_types {
QETH_LARGE_SEND_NO,
- QETH_LARGE_SEND_EDDP,
QETH_LARGE_SEND_TSO,
};
@@ -838,11 +838,9 @@ int qeth_get_cast_type(struct qeth_card *, struct sk_buff *);
int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
- struct sk_buff *, struct qeth_hdr *, int,
- struct qeth_eddp_context *, int, int);
+ struct sk_buff *, struct qeth_hdr *, int, int, int);
int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
- struct sk_buff *, struct qeth_hdr *,
- int, struct qeth_eddp_context *);
+ struct sk_buff *, struct qeth_hdr *, int);
int qeth_core_get_stats_count(struct net_device *);
void qeth_core_get_ethtool_stats(struct net_device *,
struct ethtool_stats *, u64 *);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index d1b5bebea7f..c827d69b5a9 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/ip.h>
-#include <linux/ipv6.h>
#include <linux/tcp.h>
#include <linux/mii.h>
#include <linux/kthread.h>
@@ -26,7 +25,6 @@
#include <asm/io.h>
#include "qeth_core.h"
-#include "qeth_core_offl.h"
struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
/* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */
@@ -285,17 +283,6 @@ int qeth_set_large_send(struct qeth_card *card,
netif_tx_disable(card->dev);
card->options.large_send = type;
switch (card->options.large_send) {
- case QETH_LARGE_SEND_EDDP:
- if (card->info.type != QETH_CARD_TYPE_IQD) {
- card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
- NETIF_F_HW_CSUM;
- } else {
- card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
- NETIF_F_HW_CSUM);
- card->options.large_send = QETH_LARGE_SEND_NO;
- rc = -EOPNOTSUPP;
- }
- break;
case QETH_LARGE_SEND_TSO:
if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
@@ -956,7 +943,6 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
dev_kfree_skb_any(skb);
skb = skb_dequeue(&buf->skb_list);
}
- qeth_eddp_buf_release_contexts(buf);
for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
if (buf->buffer->element[i].addr && buf->is_header[i])
kmem_cache_free(qeth_core_header_cache,
@@ -1690,7 +1676,7 @@ int qeth_send_control_data(struct qeth_card *card, int len,
int rc;
unsigned long flags;
struct qeth_reply *reply = NULL;
- unsigned long timeout;
+ unsigned long timeout, event_timeout;
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(TRACE, 2, "sendctl");
@@ -1715,9 +1701,10 @@ int qeth_send_control_data(struct qeth_card *card, int len,
qeth_prepare_control_data(card, len, iob);
if (IS_IPA(iob->data))
- timeout = jiffies + QETH_IPA_TIMEOUT;
+ event_timeout = QETH_IPA_TIMEOUT;
else
- timeout = jiffies + QETH_TIMEOUT;
+ event_timeout = QETH_TIMEOUT;
+ timeout = jiffies + event_timeout;
QETH_DBF_TEXT(TRACE, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
@@ -1745,7 +1732,7 @@ int qeth_send_control_data(struct qeth_card *card, int len,
if ((cmd->hdr.command == IPA_CMD_SETIP) &&
(cmd->hdr.prot_version == QETH_PROT_IPV4)) {
if (!wait_event_timeout(reply->wait_q,
- atomic_read(&reply->received), timeout))
+ atomic_read(&reply->received), event_timeout))
goto time_err;
} else {
while (!atomic_read(&reply->received)) {
@@ -2693,40 +2680,21 @@ static int qeth_handle_send_error(struct qeth_card *card,
struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
{
int sbalf15 = buffer->buffer->element[15].flags & 0xff;
- int cc = qdio_err & 3;
QETH_DBF_TEXT(TRACE, 6, "hdsnderr");
qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
- switch (cc) {
- case 0:
- if (qdio_err) {
- QETH_DBF_TEXT(TRACE, 1, "lnkfail");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
- (u16)qdio_err, (u8)sbalf15);
- return QETH_SEND_ERROR_LINK_FAILURE;
- }
+
+ if (!qdio_err)
return QETH_SEND_ERROR_NONE;
- case 2:
- if (qdio_err & QDIO_ERROR_SIGA_BUSY) {
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc2B");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_KICK_IT;
- }
- if ((sbalf15 >= 15) && (sbalf15 <= 31))
- return QETH_SEND_ERROR_RETRY;
- return QETH_SEND_ERROR_LINK_FAILURE;
- /* look at qdio_error and sbalf 15 */
- case 1:
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc1");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_LINK_FAILURE;
- case 3:
- default:
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc3");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_KICK_IT;
- }
+
+ if ((sbalf15 >= 15) && (sbalf15 <= 31))
+ return QETH_SEND_ERROR_RETRY;
+
+ QETH_DBF_TEXT(TRACE, 1, "lnkfail");
+ QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
+ QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
+ (u16)qdio_err, (u8)sbalf15);
+ return QETH_SEND_ERROR_LINK_FAILURE;
}
/*
@@ -2862,10 +2830,14 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
qeth_get_micros() -
queue->card->perf_stats.outbound_do_qdio_start_time;
if (rc) {
+ queue->card->stats.tx_errors += count;
+ /* ignore temporary SIGA errors without busy condition */
+ if (rc == QDIO_ERROR_SIGA_TARGET)
+ return;
QETH_DBF_TEXT(TRACE, 2, "flushbuf");
QETH_DBF_TEXT_(TRACE, 2, " err%d", rc);
QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_DDEV_ID(queue->card));
- queue->card->stats.tx_errors += count;
+
/* this must not happen under normal circumstances. if it
* happens something is really wrong -> recover */
qeth_schedule_recovery(queue->card);
@@ -2940,13 +2912,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
}
for (i = first_element; i < (first_element + count); ++i) {
buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
- /*we only handle the KICK_IT error by doing a recovery */
- if (qeth_handle_send_error(card, buffer, qdio_error)
- == QETH_SEND_ERROR_KICK_IT){
- netif_stop_queue(card->dev);
- qeth_schedule_recovery(card);
- return;
- }
+ qeth_handle_send_error(card, buffer, qdio_error);
qeth_clear_output_buffer(queue, buffer);
}
atomic_sub(count, &queue->used_buffers);
@@ -3187,11 +3153,9 @@ static inline int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
int qeth_do_send_packet_fast(struct qeth_card *card,
struct qeth_qdio_out_q *queue, struct sk_buff *skb,
struct qeth_hdr *hdr, int elements_needed,
- struct qeth_eddp_context *ctx, int offset, int hd_len)
+ int offset, int hd_len)
{
struct qeth_qdio_out_buffer *buffer;
- int buffers_needed = 0;
- int flush_cnt = 0;
int index;
/* spin until we get the queue ... */
@@ -3206,27 +3170,11 @@ int qeth_do_send_packet_fast(struct qeth_card *card,
*/
if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
goto out;
- if (ctx == NULL)
- queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
+ queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
- else {
- buffers_needed = qeth_eddp_check_buffers_for_context(queue,
- ctx);
- if (buffers_needed < 0)
- goto out;
- queue->next_buf_to_fill =
- (queue->next_buf_to_fill + buffers_needed) %
- QDIO_MAX_BUFFERS_PER_Q;
- }
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
- if (ctx == NULL) {
- qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
- qeth_flush_buffers(queue, index, 1);
- } else {
- flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index);
- WARN_ON(buffers_needed != flush_cnt);
- qeth_flush_buffers(queue, index, flush_cnt);
- }
+ qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
+ qeth_flush_buffers(queue, index, 1);
return 0;
out:
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
@@ -3236,7 +3184,7 @@ EXPORT_SYMBOL_GPL(qeth_do_send_packet_fast);
int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
struct sk_buff *skb, struct qeth_hdr *hdr,
- int elements_needed, struct qeth_eddp_context *ctx)
+ int elements_needed)
{
struct qeth_qdio_out_buffer *buffer;
int start_index;
@@ -3262,53 +3210,32 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
qeth_switch_to_packing_if_needed(queue);
if (queue->do_pack) {
do_pack = 1;
- if (ctx == NULL) {
- /* does packet fit in current buffer? */
- if ((QETH_MAX_BUFFER_ELEMENTS(card) -
- buffer->next_element_to_fill) < elements_needed) {
- /* ... no -> set state PRIMED */
- atomic_set(&buffer->state,
- QETH_QDIO_BUF_PRIMED);
- flush_count++;
- queue->next_buf_to_fill =
- (queue->next_buf_to_fill + 1) %
- QDIO_MAX_BUFFERS_PER_Q;
- buffer = &queue->bufs[queue->next_buf_to_fill];
- /* we did a step forward, so check buffer state
- * again */
- if (atomic_read(&buffer->state) !=
- QETH_QDIO_BUF_EMPTY){
- qeth_flush_buffers(queue, start_index,
+ /* does packet fit in current buffer? */
+ if ((QETH_MAX_BUFFER_ELEMENTS(card) -
+ buffer->next_element_to_fill) < elements_needed) {
+ /* ... no -> set state PRIMED */
+ atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
+ flush_count++;
+ queue->next_buf_to_fill =
+ (queue->next_buf_to_fill + 1) %
+ QDIO_MAX_BUFFERS_PER_Q;
+ buffer = &queue->bufs[queue->next_buf_to_fill];
+ /* we did a step forward, so check buffer state
+ * again */
+ if (atomic_read(&buffer->state) !=
+ QETH_QDIO_BUF_EMPTY) {
+ qeth_flush_buffers(queue, start_index,
flush_count);
- atomic_set(&queue->state,
+ atomic_set(&queue->state,
QETH_OUT_Q_UNLOCKED);
- return -EBUSY;
- }
- }
- } else {
- /* check if we have enough elements (including following
- * free buffers) to handle eddp context */
- if (qeth_eddp_check_buffers_for_context(queue, ctx)
- < 0) {
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
}
}
- if (ctx == NULL)
- tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
- else {
- tmp = qeth_eddp_fill_buffer(queue, ctx,
- queue->next_buf_to_fill);
- if (tmp < 0) {
- rc = -EBUSY;
- goto out;
- }
- }
+ tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
QDIO_MAX_BUFFERS_PER_Q;
flush_count += tmp;
-out:
if (flush_count)
qeth_flush_buffers(queue, start_index, flush_count);
else if (!atomic_read(&queue->set_pci_flags_count))
@@ -4327,6 +4254,7 @@ static struct {
/* 30 */{"tx count"},
{"tx do_QDIO time"},
{"tx do_QDIO count"},
+ {"tx csum"},
};
int qeth_core_get_stats_count(struct net_device *dev)
@@ -4378,6 +4306,7 @@ void qeth_core_get_ethtool_stats(struct net_device *dev,
data[30] = card->perf_stats.outbound_cnt;
data[31] = card->perf_stats.outbound_do_qdio_time;
data[32] = card->perf_stats.outbound_do_qdio_cnt;
+ data[33] = card->perf_stats.tx_csum;
}
EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
diff --git a/drivers/s390/net/qeth_core_offl.c b/drivers/s390/net/qeth_core_offl.c
index 4080126ca48..e69de29bb2d 100644
--- a/drivers/s390/net/qeth_core_offl.c
+++ b/drivers/s390/net/qeth_core_offl.c
@@ -1,699 +0,0 @@
-/*
- * drivers/s390/net/qeth_core_offl.c
- *
- * Copyright IBM Corp. 2007
- * Author(s): Thomas Spatzier <tspat@de.ibm.com>,
- * Frank Blaschka <frank.blaschka@de.ibm.com>
- */
-
-#include <linux/errno.h>
-#include <linux/ip.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-#include <linux/kernel.h>
-#include <linux/tcp.h>
-#include <net/tcp.h>
-#include <linux/skbuff.h>
-
-#include <net/ip.h>
-#include <net/ip6_checksum.h>
-
-#include "qeth_core.h"
-#include "qeth_core_mpc.h"
-#include "qeth_core_offl.h"
-
-int qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
- struct qeth_eddp_context *ctx)
-{
- int index = queue->next_buf_to_fill;
- int elements_needed = ctx->num_elements;
- int elements_in_buffer;
- int skbs_in_buffer;
- int buffers_needed = 0;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcbfc");
- while (elements_needed > 0) {
- buffers_needed++;
- if (atomic_read(&queue->bufs[index].state) !=
- QETH_QDIO_BUF_EMPTY)
- return -EBUSY;
-
- elements_in_buffer = QETH_MAX_BUFFER_ELEMENTS(queue->card) -
- queue->bufs[index].next_element_to_fill;
- skbs_in_buffer = elements_in_buffer / ctx->elements_per_skb;
- elements_needed -= skbs_in_buffer * ctx->elements_per_skb;
- index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
- }
- return buffers_needed;
-}
-
-static void qeth_eddp_free_context(struct qeth_eddp_context *ctx)
-{
- int i;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpfctx");
- for (i = 0; i < ctx->num_pages; ++i)
- free_page((unsigned long)ctx->pages[i]);
- kfree(ctx->pages);
- kfree(ctx->elements);
- kfree(ctx);
-}
-
-
-static void qeth_eddp_get_context(struct qeth_eddp_context *ctx)
-{
- atomic_inc(&ctx->refcnt);
-}
-
-void qeth_eddp_put_context(struct qeth_eddp_context *ctx)
-{
- if (atomic_dec_return(&ctx->refcnt) == 0)
- qeth_eddp_free_context(ctx);
-}
-EXPORT_SYMBOL_GPL(qeth_eddp_put_context);
-
-void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
-{
- struct qeth_eddp_context_reference *ref;
-
- QETH_DBF_TEXT(TRACE, 6, "eddprctx");
- while (!list_empty(&buf->ctx_list)) {
- ref = list_entry(buf->ctx_list.next,
- struct qeth_eddp_context_reference, list);
- qeth_eddp_put_context(ref->ctx);
- list_del(&ref->list);
- kfree(ref);
- }
-}
-
-static int qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
- struct qeth_eddp_context *ctx)
-{
- struct qeth_eddp_context_reference *ref;
-
- QETH_DBF_TEXT(TRACE, 6, "eddprfcx");
- ref = kmalloc(sizeof(struct qeth_eddp_context_reference), GFP_ATOMIC);
- if (ref == NULL)
- return -ENOMEM;
- qeth_eddp_get_context(ctx);
- ref->ctx = ctx;
- list_add_tail(&ref->list, &buf->ctx_list);
- return 0;
-}
-
-int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
- struct qeth_eddp_context *ctx, int index)
-{
- struct qeth_qdio_out_buffer *buf = NULL;
- struct qdio_buffer *buffer;
- int elements = ctx->num_elements;
- int element = 0;
- int flush_cnt = 0;
- int must_refcnt = 1;
- int i;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpfibu");
- while (elements > 0) {
- buf = &queue->bufs[index];
- if (atomic_read(&buf->state) != QETH_QDIO_BUF_EMPTY) {
- /* normally this should not happen since we checked for
- * available elements in qeth_check_elements_for_context
- */
- if (element == 0)
- return -EBUSY;
- else {
- QETH_DBF_MESSAGE(2, "could only partially fill"
- "eddp buffer!\n");
- goto out;
- }
- }
- /* check if the whole next skb fits into current buffer */
- if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
- buf->next_element_to_fill)
- < ctx->elements_per_skb){
- /* no -> go to next buffer */
- atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
- index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
- flush_cnt++;
- /* new buffer, so we have to add ctx to buffer'ctx_list
- * and increment ctx's refcnt */
- must_refcnt = 1;
- continue;
- }
- if (must_refcnt) {
- must_refcnt = 0;
- if (qeth_eddp_buf_ref_context(buf, ctx)) {
- goto out_check;
- }
- }
- buffer = buf->buffer;
- /* fill one skb into buffer */
- for (i = 0; i < ctx->elements_per_skb; ++i) {
- if (ctx->elements[element].length != 0) {
- buffer->element[buf->next_element_to_fill].
- addr = ctx->elements[element].addr;
- buffer->element[buf->next_element_to_fill].
- length = ctx->elements[element].length;
- buffer->element[buf->next_element_to_fill].
- flags = ctx->elements[element].flags;
- buf->next_element_to_fill++;
- }
- element++;
- elements--;
- }
- }
-out_check:
- if (!queue->do_pack) {
- QETH_DBF_TEXT(TRACE, 6, "fillbfnp");
- /* set state to PRIMED -> will be flushed */
- if (buf->next_element_to_fill > 0) {
- atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
- flush_cnt++;
- }
- } else {
- if (queue->card->options.performance_stats)
- queue->card->perf_stats.skbs_sent_pack++;
- QETH_DBF_TEXT(TRACE, 6, "fillbfpa");
- if (buf->next_element_to_fill >=
- QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
- /*
- * packed buffer if full -> set state PRIMED
- * -> will be flushed
- */
- atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
- flush_cnt++;
- }
- }
-out:
- return flush_cnt;
-}
-
-static void qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
- struct qeth_eddp_data *eddp, int data_len)
-{
- u8 *page;
- int page_remainder;
- int page_offset;
- int pkt_len;
- struct qeth_eddp_element *element;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcrsh");
- page = ctx->pages[ctx->offset >> PAGE_SHIFT];
- page_offset = ctx->offset % PAGE_SIZE;
- element = &ctx->elements[ctx->num_elements];
- pkt_len = eddp->nhl + eddp->thl + data_len;
- /* FIXME: layer2 and VLAN !!! */
- if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
- pkt_len += ETH_HLEN;
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
- pkt_len += VLAN_HLEN;
- /* does complete packet fit in current page ? */
- page_remainder = PAGE_SIZE - page_offset;
- if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)) {
- /* no -> go to start of next page */
- ctx->offset += page_remainder;
- page = ctx->pages[ctx->offset >> PAGE_SHIFT];
- page_offset = 0;
- }
- memcpy(page + page_offset, &eddp->qh, sizeof(struct qeth_hdr));
- element->addr = page + page_offset;
- element->length = sizeof(struct qeth_hdr);
- ctx->offset += sizeof(struct qeth_hdr);
- page_offset += sizeof(struct qeth_hdr);
- /* add mac header (?) */
- if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
- memcpy(page + page_offset, &eddp->mac, ETH_HLEN);
- element->length += ETH_HLEN;
- ctx->offset += ETH_HLEN;
- page_offset += ETH_HLEN;
- }
- /* add VLAN tag */
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
- memcpy(page + page_offset, &eddp->vlan, VLAN_HLEN);
- element->length += VLAN_HLEN;
- ctx->offset += VLAN_HLEN;
- page_offset += VLAN_HLEN;
- }
- /* add network header */
- memcpy(page + page_offset, (u8 *)&eddp->nh, eddp->nhl);
- element->length += eddp->nhl;
- eddp->nh_in_ctx = page + page_offset;
- ctx->offset += eddp->nhl;
- page_offset += eddp->nhl;
- /* add transport header */
- memcpy(page + page_offset, (u8 *)&eddp->th, eddp->thl);
- element->length += eddp->thl;
- eddp->th_in_ctx = page + page_offset;
- ctx->offset += eddp->thl;
-}
-
-static void qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp,
- int len, __wsum *hcsum)
-{
- struct skb_frag_struct *frag;
- int left_in_frag;
- int copy_len;
- u8 *src;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcdtc");
- if (skb_shinfo(eddp->skb)->nr_frags == 0) {
- skb_copy_from_linear_data_offset(eddp->skb, eddp->skb_offset,
- dst, len);
- *hcsum = csum_partial(eddp->skb->data + eddp->skb_offset, len,
- *hcsum);
- eddp->skb_offset += len;
- } else {
- while (len > 0) {
- if (eddp->frag < 0) {
- /* we're in skb->data */
- left_in_frag = (eddp->skb->len -
- eddp->skb->data_len)
- - eddp->skb_offset;
- src = eddp->skb->data + eddp->skb_offset;
- } else {
- frag = &skb_shinfo(eddp->skb)->frags[
- eddp->frag];
- left_in_frag = frag->size - eddp->frag_offset;
- src = (u8 *)((page_to_pfn(frag->page) <<
- PAGE_SHIFT) + frag->page_offset +
- eddp->frag_offset);
- }
- if (left_in_frag <= 0) {
- eddp->frag++;
- eddp->frag_offset = 0;
- continue;
- }
- copy_len = min(left_in_frag, len);
- memcpy(dst, src, copy_len);
- *hcsum = csum_partial(src, copy_len, *hcsum);
- dst += copy_len;
- eddp->frag_offset += copy_len;
- eddp->skb_offset += copy_len;
- len -= copy_len;
- }
- }
-}
-
-static void qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
- struct qeth_eddp_data *eddp, int data_len, __wsum hcsum)
-{
- u8 *page;
- int page_remainder;
- int page_offset;
- struct qeth_eddp_element *element;
- int first_lap = 1;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcsdt");
- page = ctx->pages[ctx->offset >> PAGE_SHIFT];
- page_offset = ctx->offset % PAGE_SIZE;
- element = &ctx->elements[ctx->num_elements];
- while (data_len) {
- page_remainder = PAGE_SIZE - page_offset;
- if (page_remainder < data_len) {
- qeth_eddp_copy_data_tcp(page + page_offset, eddp,
- page_remainder, &hcsum);
- element->length += page_remainder;
- if (first_lap)
- element->flags = SBAL_FLAGS_FIRST_FRAG;
- else
- element->flags = SBAL_FLAGS_MIDDLE_FRAG;
- ctx->num_elements++;
- element++;
- data_len -= page_remainder;
- ctx->offset += page_remainder;
- page = ctx->pages[ctx->offset >> PAGE_SHIFT];
- page_offset = 0;
- element->addr = page + page_offset;
- } else {
- qeth_eddp_copy_data_tcp(page + page_offset, eddp,
- data_len, &hcsum);
- element->length += data_len;
- if (!first_lap)
- element->flags = SBAL_FLAGS_LAST_FRAG;
- ctx->num_elements++;
- ctx->offset += data_len;
- data_len = 0;
- }
- first_lap = 0;
- }
- ((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
-}
-
-static __wsum qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp,
- int data_len)
-{
- __wsum phcsum; /* pseudo header checksum */
-
- QETH_DBF_TEXT(TRACE, 5, "eddpckt4");
- eddp->th.tcp.h.check = 0;
- /* compute pseudo header checksum */
- phcsum = csum_tcpudp_nofold(eddp->nh.ip4.h.saddr, eddp->nh.ip4.h.daddr,
- eddp->thl + data_len, IPPROTO_TCP, 0);
- /* compute checksum of tcp header */
- return csum_partial(&eddp->th, eddp->thl, phcsum);
-}
-
-static __wsum qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp,
- int data_len)
-{
- __be32 proto;
- __wsum phcsum; /* pseudo header checksum */
-
- QETH_DBF_TEXT(TRACE, 5, "eddpckt6");
- eddp->th.tcp.h.check = 0;
- /* compute pseudo header checksum */
- phcsum = csum_partial(&eddp->nh.ip6.h.saddr,
- sizeof(struct in6_addr), 0);
- phcsum = csum_partial(&eddp->nh.ip6.h.daddr,
- sizeof(struct in6_addr), phcsum);
- proto = htonl(IPPROTO_TCP);
- phcsum = csum_partial(&proto, sizeof(u32), phcsum);
- return phcsum;
-}
-
-static struct qeth_eddp_data *qeth_eddp_create_eddp_data(struct qeth_hdr *qh,
- u8 *nh, u8 nhl, u8 *th, u8 thl)
-{
- struct qeth_eddp_data *eddp;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcrda");
- eddp = kzalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC);
- if (eddp) {
- eddp->nhl = nhl;
- eddp->thl = thl;
- memcpy(&eddp->qh, qh, sizeof(struct qeth_hdr));
- memcpy(&eddp->nh, nh, nhl);
- memcpy(&eddp->th, th, thl);
- eddp->frag = -1; /* initially we're in skb->data */
- }
- return eddp;
-}
-
-static void __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
- struct qeth_eddp_data *eddp)
-{
- struct tcphdr *tcph;
- int data_len;
- __wsum hcsum;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpftcp");
- eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
- if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
- eddp->skb_offset += sizeof(struct ethhdr);
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
- eddp->skb_offset += VLAN_HLEN;
- }
- tcph = tcp_hdr(eddp->skb);
- while (eddp->skb_offset < eddp->skb->len) {
- data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
- (int)(eddp->skb->len - eddp->skb_offset));
- /* prepare qdio hdr */
- if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
- eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN +
- eddp->nhl + eddp->thl;
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
- eddp->qh.hdr.l2.pkt_length += VLAN_HLEN;
- } else
- eddp->qh.hdr.l3.length = data_len + eddp->nhl +
- eddp->thl;
- /* prepare ip hdr */
- if (eddp->skb->protocol == htons(ETH_P_IP)) {
- eddp->nh.ip4.h.tot_len = htons(data_len + eddp->nhl +
- eddp->thl);
- eddp->nh.ip4.h.check = 0;
- eddp->nh.ip4.h.check =
- ip_fast_csum((u8 *)&eddp->nh.ip4.h,
- eddp->nh.ip4.h.ihl);
- } else
- eddp->nh.ip6.h.payload_len = htons(data_len +
- eddp->thl);
- /* prepare tcp hdr */
- if (data_len == (eddp->skb->len - eddp->skb_offset)) {
- /* last segment -> set FIN and PSH flags */
- eddp->th.tcp.h.fin = tcph->fin;
- eddp->th.tcp.h.psh = tcph->psh;
- }
- if (eddp->skb->protocol == htons(ETH_P_IP))
- hcsum = qeth_eddp_check_tcp4_hdr(eddp, data_len);
- else
- hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len);
- /* fill the next segment into the context */
- qeth_eddp_create_segment_hdrs(ctx, eddp, data_len);
- qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum);
- if (eddp->skb_offset >= eddp->skb->len)
- break;
- /* prepare headers for next round */
- if (eddp->skb->protocol == htons(ETH_P_IP))
- eddp->nh.ip4.h.id = htons(ntohs(eddp->nh.ip4.h.id) + 1);
- eddp->th.tcp.h.seq = htonl(ntohl(eddp->th.tcp.h.seq) +
- data_len);
- }
-}
-
-static int qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
- struct sk_buff *skb, struct qeth_hdr *qhdr)
-{
- struct qeth_eddp_data *eddp = NULL;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpficx");
- /* create our segmentation headers and copy original headers */
- if (skb->protocol == htons(ETH_P_IP))
- eddp = qeth_eddp_create_eddp_data(qhdr,
- skb_network_header(skb),
- ip_hdrlen(skb),
- skb_transport_header(skb),
- tcp_hdrlen(skb));
- else
- eddp = qeth_eddp_create_eddp_data(qhdr,
- skb_network_header(skb),
- sizeof(struct ipv6hdr),
- skb_transport_header(skb),
- tcp_hdrlen(skb));
-
- if (eddp == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "eddpfcnm");
- return -ENOMEM;
- }
- if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
- skb_set_mac_header(skb, sizeof(struct qeth_hdr));
- memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN);
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
- eddp->vlan[0] = skb->protocol;
- eddp->vlan[1] = htons(vlan_tx_tag_get(skb));
- }
- }
- /* the next flags will only be set on the last segment */
- eddp->th.tcp.h.fin = 0;
- eddp->th.tcp.h.psh = 0;
- eddp->skb = skb;
- /* begin segmentation and fill context */
- __qeth_eddp_fill_context_tcp(ctx, eddp);
- kfree(eddp);
- return 0;
-}
-
-static void qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx,
- struct sk_buff *skb, int hdr_len)
-{
- int skbs_per_page;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcanp");
- /* can we put multiple skbs in one page? */
- skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
- if (skbs_per_page > 1) {
- ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
- skbs_per_page + 1;
- ctx->elements_per_skb = 1;
- } else {
- /* no -> how many elements per skb? */
- ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
- PAGE_SIZE) >> PAGE_SHIFT;
- ctx->num_pages = ctx->elements_per_skb *
- (skb_shinfo(skb)->gso_segs + 1);
- }
- ctx->num_elements = ctx->elements_per_skb *
- (skb_shinfo(skb)->gso_segs + 1);
-}
-
-static struct qeth_eddp_context *qeth_eddp_create_context_generic(
- struct qeth_card *card, struct sk_buff *skb, int hdr_len)
-{
- struct qeth_eddp_context *ctx = NULL;
- u8 *addr;
- int i;
-
- QETH_DBF_TEXT(TRACE, 5, "creddpcg");
- /* create the context and allocate pages */
- ctx = kzalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC);
- if (ctx == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcn1");
- return NULL;
- }
- ctx->type = QETH_LARGE_SEND_EDDP;
- qeth_eddp_calc_num_pages(ctx, skb, hdr_len);
- if (ctx->elements_per_skb > QETH_MAX_BUFFER_ELEMENTS(card)) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcis");
- kfree(ctx);
- return NULL;
- }
- ctx->pages = kcalloc(ctx->num_pages, sizeof(u8 *), GFP_ATOMIC);
- if (ctx->pages == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcn2");
- kfree(ctx);
- return NULL;
- }
- for (i = 0; i < ctx->num_pages; ++i) {
- addr = (u8 *)get_zeroed_page(GFP_ATOMIC);
- if (addr == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcn3");
- ctx->num_pages = i;
- qeth_eddp_free_context(ctx);
- return NULL;
- }
- ctx->pages[i] = addr;
- }
- ctx->elements = kcalloc(ctx->num_elements,
- sizeof(struct qeth_eddp_element), GFP_ATOMIC);
- if (ctx->elements == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcn4");
- qeth_eddp_free_context(ctx);
- return NULL;
- }
- /* reset num_elements; will be incremented again in fill_buffer to
- * reflect number of actually used elements */
- ctx->num_elements = 0;
- return ctx;
-}
-
-static struct qeth_eddp_context *qeth_eddp_create_context_tcp(
- struct qeth_card *card, struct sk_buff *skb,
- struct qeth_hdr *qhdr)
-{
- struct qeth_eddp_context *ctx = NULL;
-
- QETH_DBF_TEXT(TRACE, 5, "creddpct");
- if (skb->protocol == htons(ETH_P_IP))
- ctx = qeth_eddp_create_context_generic(card, skb,
- (sizeof(struct qeth_hdr) +
- ip_hdrlen(skb) +
- tcp_hdrlen(skb)));
- else if (skb->protocol == htons(ETH_P_IPV6))
- ctx = qeth_eddp_create_context_generic(card, skb,
- sizeof(struct qeth_hdr) + sizeof(struct ipv6hdr) +
- tcp_hdrlen(skb));
- else
- QETH_DBF_TEXT(TRACE, 2, "cetcpinv");
-
- if (ctx == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "creddpnl");
- return NULL;
- }
- if (qeth_eddp_fill_context_tcp(ctx, skb, qhdr)) {
- QETH_DBF_TEXT(TRACE, 2, "ceddptfe");
- qeth_eddp_free_context(ctx);
- return NULL;
- }
- atomic_set(&ctx->refcnt, 1);
- return ctx;
-}
-
-struct qeth_eddp_context *qeth_eddp_create_context(struct qeth_card *card,
- struct sk_buff *skb, struct qeth_hdr *qhdr,
- unsigned char sk_protocol)
-{
- QETH_DBF_TEXT(TRACE, 5, "creddpc");
- switch (sk_protocol) {
- case IPPROTO_TCP:
- return qeth_eddp_create_context_tcp(card, skb, qhdr);
- default:
- QETH_DBF_TEXT(TRACE, 2, "eddpinvp");
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(qeth_eddp_create_context);
-
-void qeth_tso_fill_header(struct qeth_card *card, struct qeth_hdr *qhdr,
- struct sk_buff *skb)
-{
- struct qeth_hdr_tso *hdr = (struct qeth_hdr_tso *)qhdr;
- struct tcphdr *tcph = tcp_hdr(skb);
- struct iphdr *iph = ip_hdr(skb);
- struct ipv6hdr *ip6h = ipv6_hdr(skb);
-
- QETH_DBF_TEXT(TRACE, 5, "tsofhdr");
-
- /*fix header to TSO values ...*/
- hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
- /*set values which are fix for the first approach ...*/
- hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
- hdr->ext.imb_hdr_no = 1;
- hdr->ext.hdr_type = 1;
- hdr->ext.hdr_version = 1;
- hdr->ext.hdr_len = 28;
- /*insert non-fix values */
- hdr->ext.mss = skb_shinfo(skb)->gso_size;
- hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
- hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
- sizeof(struct qeth_hdr_tso));
- tcph->check = 0;
- if (skb->protocol == ETH_P_IPV6) {
- ip6h->payload_len = 0;
- tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
- 0, IPPROTO_TCP, 0);
- } else {
- /*OSA want us to set these values ...*/
- tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
- 0, IPPROTO_TCP, 0);
- iph->tot_len = 0;
- iph->check = 0;
- }
-}
-EXPORT_SYMBOL_GPL(qeth_tso_fill_header);
-
-void qeth_tx_csum(struct sk_buff *skb)
-{
- int tlen;
- if (skb->protocol == htons(ETH_P_IP)) {
- tlen = ntohs(ip_hdr(skb)->tot_len) - (ip_hdr(skb)->ihl << 2);
- switch (ip_hdr(skb)->protocol) {
- case IPPROTO_TCP:
- tcp_hdr(skb)->check = 0;
- tcp_hdr(skb)->check = csum_tcpudp_magic(
- ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
- tlen, ip_hdr(skb)->protocol,
- skb_checksum(skb, skb_transport_offset(skb),
- tlen, 0));
- break;
- case IPPROTO_UDP:
- udp_hdr(skb)->check = 0;
- udp_hdr(skb)->check = csum_tcpudp_magic(
- ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
- tlen, ip_hdr(skb)->protocol,
- skb_checksum(skb, skb_transport_offset(skb),
- tlen, 0));
- break;
- }
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
- switch (ipv6_hdr(skb)->nexthdr) {
- case IPPROTO_TCP:
- tcp_hdr(skb)->check = 0;
- tcp_hdr(skb)->check = csum_ipv6_magic(
- &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
- ipv6_hdr(skb)->payload_len,
- ipv6_hdr(skb)->nexthdr,
- skb_checksum(skb, skb_transport_offset(skb),
- ipv6_hdr(skb)->payload_len, 0));
- break;
- case IPPROTO_UDP:
- udp_hdr(skb)->check = 0;
- udp_hdr(skb)->check = csum_ipv6_magic(
- &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
- ipv6_hdr(skb)->payload_len,
- ipv6_hdr(skb)->nexthdr,
- skb_checksum(skb, skb_transport_offset(skb),
- ipv6_hdr(skb)->payload_len, 0));
- break;
- }
- }
-}
-EXPORT_SYMBOL_GPL(qeth_tx_csum);
diff --git a/drivers/s390/net/qeth_core_offl.h b/drivers/s390/net/qeth_core_offl.h
index 86bf7df8cf1..e69de29bb2d 100644
--- a/drivers/s390/net/qeth_core_offl.h
+++ b/drivers/s390/net/qeth_core_offl.h
@@ -1,76 +0,0 @@
-/*
- * drivers/s390/net/qeth_core_offl.h
- *
- * Copyright IBM Corp. 2007
- * Author(s): Thomas Spatzier <tspat@de.ibm.com>,
- * Frank Blaschka <frank.blaschka@de.ibm.com>
- */
-
-#ifndef __QETH_CORE_OFFL_H__
-#define __QETH_CORE_OFFL_H__
-
-struct qeth_eddp_element {
- u32 flags;
- u32 length;
- void *addr;
-};
-
-struct qeth_eddp_context {
- atomic_t refcnt;
- enum qeth_large_send_types type;
- int num_pages; /* # of allocated pages */
- u8 **pages; /* pointers to pages */
- int offset; /* offset in ctx during creation */
- int num_elements; /* # of required 'SBALEs' */
- struct qeth_eddp_element *elements; /* array of 'SBALEs' */
- int elements_per_skb; /* # of 'SBALEs' per skb **/
-};
-
-struct qeth_eddp_context_reference {
- struct list_head list;
- struct qeth_eddp_context *ctx;
-};
-
-struct qeth_eddp_data {
- struct qeth_hdr qh;
- struct ethhdr mac;
- __be16 vlan[2];
- union {
- struct {
- struct iphdr h;
- u8 options[40];
- } ip4;
- struct {
- struct ipv6hdr h;
- } ip6;
- } nh;
- u8 nhl;
- void *nh_in_ctx; /* address of nh within the ctx */
- union {
- struct {
- struct tcphdr h;
- u8 options[40];
- } tcp;
- } th;
- u8 thl;
- void *th_in_ctx; /* address of th within the ctx */
- struct sk_buff *skb;
- int skb_offset;
- int frag;
- int frag_offset;
-} __attribute__ ((packed));
-
-extern struct qeth_eddp_context *qeth_eddp_create_context(struct qeth_card *,
- struct sk_buff *, struct qeth_hdr *, unsigned char);
-extern void qeth_eddp_put_context(struct qeth_eddp_context *);
-extern int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *,
- struct qeth_eddp_context *, int);
-extern void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *);
-extern int qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *,
- struct qeth_eddp_context *);
-
-void qeth_tso_fill_header(struct qeth_card *, struct qeth_hdr *,
- struct sk_buff *);
-void qeth_tx_csum(struct sk_buff *skb);
-
-#endif /* __QETH_CORE_EDDP_H__ */
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index c26e842ad90..568465d7517 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -427,8 +427,6 @@ static ssize_t qeth_dev_large_send_show(struct device *dev,
switch (card->options.large_send) {
case QETH_LARGE_SEND_NO:
return sprintf(buf, "%s\n", "no");
- case QETH_LARGE_SEND_EDDP:
- return sprintf(buf, "%s\n", "EDDP");
case QETH_LARGE_SEND_TSO:
return sprintf(buf, "%s\n", "TSO");
default:
@@ -449,8 +447,6 @@ static ssize_t qeth_dev_large_send_store(struct device *dev,
tmp = strsep((char **) &buf, "\n");
if (!strcmp(tmp, "no")) {
type = QETH_LARGE_SEND_NO;
- } else if (!strcmp(tmp, "EDDP")) {
- type = QETH_LARGE_SEND_EDDP;
} else if (!strcmp(tmp, "TSO")) {
type = QETH_LARGE_SEND_TSO;
} else {
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 07ab8a5c1c4..172031baedc 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -21,7 +21,6 @@
#include <linux/ip.h>
#include "qeth_core.h"
-#include "qeth_core_offl.h"
static int qeth_l2_set_offline(struct ccwgroup_device *);
static int qeth_l2_stop(struct net_device *);
@@ -328,6 +327,10 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
struct qeth_vlan_vid *id;
QETH_DBF_TEXT_(TRACE, 4, "aid:%d", vid);
+ if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+ QETH_DBF_TEXT(TRACE, 3, "aidREC");
+ return;
+ }
id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC);
if (id) {
id->vid = vid;
@@ -344,6 +347,10 @@ static void qeth_l2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
struct qeth_card *card = dev->ml_priv;
QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid);
+ if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+ QETH_DBF_TEXT(TRACE, 3, "kidREC");
+ return;
+ }
spin_lock_bh(&card->vlanlock);
list_for_each_entry(id, &card->vid_list, list) {
if (id->vid == vid) {
@@ -379,7 +386,8 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
dev_close(card->dev);
rtnl_unlock();
}
- if (!card->use_hard_stop) {
+ if (!card->use_hard_stop ||
+ recovery_mode) {
__u8 *mac = &card->dev->dev_addr[0];
rc = qeth_l2_send_delmac(card, mac);
QETH_DBF_TEXT_(SETUP, 2, "Lerr%d", rc);
@@ -388,7 +396,8 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
}
if (card->state == CARD_STATE_SOFTSETUP) {
qeth_l2_process_vlans(card, 1);
- if (!card->use_hard_stop)
+ if (!card->use_hard_stop ||
+ recovery_mode)
qeth_l2_del_all_mc(card);
qeth_clear_ipacmd_list(card);
card->state = CARD_STATE_HARDSETUP;
@@ -593,6 +602,10 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
}
QETH_DBF_TEXT_(TRACE, 3, "%s", CARD_BUS_ID(card));
QETH_DBF_HEX(TRACE, 3, addr->sa_data, OSA_ADDR_LEN);
+ if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+ QETH_DBF_TEXT(TRACE, 3, "setmcREC");
+ return -ERESTARTSYS;
+ }
rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
if (!rc)
rc = qeth_l2_send_setmac(card, addr->sa_data);
@@ -608,6 +621,9 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
return ;
QETH_DBF_TEXT(TRACE, 3, "setmulti");
+ if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
+ (card->state != CARD_STATE_UP))
+ return;
qeth_l2_del_all_mc(card);
spin_lock_bh(&card->mclock);
for (dm = dev->mc_list; dm; dm = dm->next)
@@ -634,8 +650,6 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct qeth_qdio_out_q *queue = card->qdio.out_qs
[qeth_get_priority_queue(card, skb, ipv, cast_type)];
int tx_bytes = skb->len;
- enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
- struct qeth_eddp_context *ctx = NULL;
int data_offset = -1;
int elements_needed = 0;
int hd_len = 0;
@@ -655,14 +669,10 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
netif_stop_queue(dev);
- if (skb_is_gso(skb))
- large_send = QETH_LARGE_SEND_EDDP;
-
if (card->info.type == QETH_CARD_TYPE_OSN)
hdr = (struct qeth_hdr *)skb->data;
else {
- if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
- (skb_shinfo(skb)->nr_frags == 0)) {
+ if (card->info.type == QETH_CARD_TYPE_IQD) {
new_skb = skb;
data_offset = ETH_HLEN;
hd_len = ETH_HLEN;
@@ -689,59 +699,26 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- if (large_send == QETH_LARGE_SEND_EDDP) {
- ctx = qeth_eddp_create_context(card, new_skb, hdr,
- skb->sk->sk_protocol);
- if (ctx == NULL) {
- QETH_DBF_MESSAGE(2, "could not create eddp context\n");
- goto tx_drop;
- }
- } else {
- elements = qeth_get_elements_no(card, (void *)hdr, new_skb,
+ elements = qeth_get_elements_no(card, (void *)hdr, new_skb,
elements_needed);
- if (!elements) {
- if (data_offset >= 0)
- kmem_cache_free(qeth_core_header_cache, hdr);
- goto tx_drop;
- }
+ if (!elements) {
+ if (data_offset >= 0)
+ kmem_cache_free(qeth_core_header_cache, hdr);
+ goto tx_drop;
}
- if ((large_send == QETH_LARGE_SEND_NO) &&
- (skb->ip_summed == CHECKSUM_PARTIAL))
- qeth_tx_csum(new_skb);
-
if (card->info.type != QETH_CARD_TYPE_IQD)
rc = qeth_do_send_packet(card, queue, new_skb, hdr,
- elements, ctx);
+ elements);
else
rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
- elements, ctx, data_offset, hd_len);
+ elements, data_offset, hd_len);
if (!rc) {
card->stats.tx_packets++;
card->stats.tx_bytes += tx_bytes;
if (new_skb != skb)
dev_kfree_skb_any(skb);
- if (card->options.performance_stats) {
- if (large_send != QETH_LARGE_SEND_NO) {
- card->perf_stats.large_send_bytes += tx_bytes;
- card->perf_stats.large_send_cnt++;
- }
- if (skb_shinfo(new_skb)->nr_frags > 0) {
- card->perf_stats.sg_skbs_sent++;
- /* nr_frags + skb->data */
- card->perf_stats.sg_frags_sent +=
- skb_shinfo(new_skb)->nr_frags + 1;
- }
- }
-
- if (ctx != NULL) {
- qeth_eddp_put_context(ctx);
- dev_kfree_skb_any(new_skb);
- }
} else {
- if (ctx != NULL)
- qeth_eddp_put_context(ctx);
-
if (data_offset >= 0)
kmem_cache_free(qeth_core_header_cache, hdr);
@@ -878,30 +855,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
return;
}
-static int qeth_l2_ethtool_set_tso(struct net_device *dev, u32 data)
-{
- struct qeth_card *card = dev->ml_priv;
-
- if (data) {
- if (card->options.large_send == QETH_LARGE_SEND_NO) {
- card->options.large_send = QETH_LARGE_SEND_EDDP;
- dev->features |= NETIF_F_TSO;
- }
- } else {
- dev->features &= ~NETIF_F_TSO;
- card->options.large_send = QETH_LARGE_SEND_NO;
- }
- return 0;
-}
-
static struct ethtool_ops qeth_l2_ethtool_ops = {
.get_link = ethtool_op_get_link,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = qeth_l2_ethtool_set_tso,
.get_strings = qeth_core_get_strings,
.get_ethtool_stats = qeth_core_get_ethtool_stats,
.get_stats_count = qeth_core_get_stats_count,
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 3d04920b9bb..0ba3817cb6a 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -19,15 +19,15 @@
#include <linux/etherdevice.h>
#include <linux/mii.h>
#include <linux/ip.h>
-#include <linux/reboot.h>
+#include <linux/ipv6.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <net/ip.h>
#include <net/arp.h>
+#include <net/ip6_checksum.h>
#include "qeth_l3.h"
-#include "qeth_core_offl.h"
static int qeth_l3_set_offline(struct ccwgroup_device *);
static int qeth_l3_recover(void *);
@@ -1038,7 +1038,7 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card)
rc = qeth_query_setadapterparms(card);
if (rc) {
QETH_DBF_MESSAGE(2, "%s couldn't set adapter parameters: "
- "0x%x\n", card->gdev->dev.bus_id, rc);
+ "0x%x\n", dev_name(&card->gdev->dev), rc);
return rc;
}
if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) {
@@ -1838,6 +1838,10 @@ static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
unsigned long flags;
QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid);
+ if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+ QETH_DBF_TEXT(TRACE, 3, "kidREC");
+ return;
+ }
spin_lock_irqsave(&card->vlanlock, flags);
/* unregister IP addresses of vlan device */
qeth_l3_free_vlan_addresses(card, vid);
@@ -2101,6 +2105,9 @@ static void qeth_l3_set_multicast_list(struct net_device *dev)
struct qeth_card *card = dev->ml_priv;
QETH_DBF_TEXT(TRACE, 3, "setmulti");
+ if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
+ (card->state != CARD_STATE_UP))
+ return;
qeth_l3_delete_mc_addresses(card);
qeth_l3_add_multicast_ipv4(card);
#ifdef CONFIG_QETH_IPV6
@@ -2577,12 +2584,63 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
}
}
+static void qeth_tso_fill_header(struct qeth_card *card,
+ struct qeth_hdr *qhdr, struct sk_buff *skb)
+{
+ struct qeth_hdr_tso *hdr = (struct qeth_hdr_tso *)qhdr;
+ struct tcphdr *tcph = tcp_hdr(skb);
+ struct iphdr *iph = ip_hdr(skb);
+ struct ipv6hdr *ip6h = ipv6_hdr(skb);
+
+ /*fix header to TSO values ...*/
+ hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
+ /*set values which are fix for the first approach ...*/
+ hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
+ hdr->ext.imb_hdr_no = 1;
+ hdr->ext.hdr_type = 1;
+ hdr->ext.hdr_version = 1;
+ hdr->ext.hdr_len = 28;
+ /*insert non-fix values */
+ hdr->ext.mss = skb_shinfo(skb)->gso_size;
+ hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
+ hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
+ sizeof(struct qeth_hdr_tso));
+ tcph->check = 0;
+ if (skb->protocol == ETH_P_IPV6) {
+ ip6h->payload_len = 0;
+ tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
+ 0, IPPROTO_TCP, 0);
+ } else {
+ /*OSA want us to set these values ...*/
+ tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
+ 0, IPPROTO_TCP, 0);
+ iph->tot_len = 0;
+ iph->check = 0;
+ }
+}
+
+static void qeth_tx_csum(struct sk_buff *skb)
+{
+ __wsum csum;
+ int offset;
+
+ skb_set_transport_header(skb, skb->csum_start - skb_headroom(skb));
+ offset = skb->csum_start - skb_headroom(skb);
+ BUG_ON(offset >= skb_headlen(skb));
+ csum = skb_checksum(skb, offset, skb->len - offset, 0);
+
+ offset += skb->csum_offset;
+ BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb));
+ *(__sum16 *)(skb->data + offset) = csum_fold(csum);
+}
+
static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
int rc;
u16 *tag;
struct qeth_hdr *hdr = NULL;
int elements_needed = 0;
+ int elems;
struct qeth_card *card = dev->ml_priv;
struct sk_buff *new_skb = NULL;
int ipv = qeth_get_ip_version(skb);
@@ -2591,8 +2649,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
[qeth_get_priority_queue(card, skb, ipv, cast_type)];
int tx_bytes = skb->len;
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
- struct qeth_eddp_context *ctx = NULL;
int data_offset = -1;
+ int nr_frags;
if ((card->info.type == QETH_CARD_TYPE_IQD) &&
(skb->protocol != htons(ETH_P_IPV6)) &&
@@ -2615,6 +2673,12 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb_is_gso(skb))
large_send = card->options.large_send;
+ else
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ qeth_tx_csum(skb);
+ if (card->options.performance_stats)
+ card->perf_stats.tx_csum++;
+ }
if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
(skb_shinfo(skb)->nr_frags == 0)) {
@@ -2661,12 +2725,13 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
/* fix hardware limitation: as long as we do not have sbal
- * chaining we can not send long frag lists so we temporary
- * switch to EDDP
+ * chaining we can not send long frag lists
*/
if ((large_send == QETH_LARGE_SEND_TSO) &&
- ((skb_shinfo(new_skb)->nr_frags + 2) > 16))
- large_send = QETH_LARGE_SEND_EDDP;
+ ((skb_shinfo(new_skb)->nr_frags + 2) > 16)) {
+ if (skb_linearize(new_skb))
+ goto tx_drop;
+ }
if ((large_send == QETH_LARGE_SEND_TSO) &&
(cast_type == RTN_UNSPEC)) {
@@ -2689,37 +2754,22 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- if (large_send == QETH_LARGE_SEND_EDDP) {
- /* new_skb is not owned by a socket so we use skb to get
- * the protocol
- */
- ctx = qeth_eddp_create_context(card, new_skb, hdr,
- skb->sk->sk_protocol);
- if (ctx == NULL) {
- QETH_DBF_MESSAGE(2, "could not create eddp context\n");
- goto tx_drop;
- }
- } else {
- int elems = qeth_get_elements_no(card, (void *)hdr, new_skb,
+ elems = qeth_get_elements_no(card, (void *)hdr, new_skb,
elements_needed);
- if (!elems) {
- if (data_offset >= 0)
- kmem_cache_free(qeth_core_header_cache, hdr);
- goto tx_drop;
- }
- elements_needed += elems;
+ if (!elems) {
+ if (data_offset >= 0)
+ kmem_cache_free(qeth_core_header_cache, hdr);
+ goto tx_drop;
}
-
- if ((large_send == QETH_LARGE_SEND_NO) &&
- (new_skb->ip_summed == CHECKSUM_PARTIAL))
- qeth_tx_csum(new_skb);
+ elements_needed += elems;
+ nr_frags = skb_shinfo(new_skb)->nr_frags;
if (card->info.type != QETH_CARD_TYPE_IQD)
rc = qeth_do_send_packet(card, queue, new_skb, hdr,
- elements_needed, ctx);
+ elements_needed);
else
rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
- elements_needed, ctx, data_offset, 0);
+ elements_needed, data_offset, 0);
if (!rc) {
card->stats.tx_packets++;
@@ -2731,22 +2781,13 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
card->perf_stats.large_send_bytes += tx_bytes;
card->perf_stats.large_send_cnt++;
}
- if (skb_shinfo(new_skb)->nr_frags > 0) {
+ if (nr_frags) {
card->perf_stats.sg_skbs_sent++;
/* nr_frags + skb->data */
- card->perf_stats.sg_frags_sent +=
- skb_shinfo(new_skb)->nr_frags + 1;
+ card->perf_stats.sg_frags_sent += nr_frags + 1;
}
}
-
- if (ctx != NULL) {
- qeth_eddp_put_context(ctx);
- dev_kfree_skb_any(new_skb);
- }
} else {
- if (ctx != NULL)
- qeth_eddp_put_context(ctx);
-
if (data_offset >= 0)
kmem_cache_free(qeth_core_header_cache, hdr);
@@ -2841,7 +2882,7 @@ static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
if (data) {
if (card->options.large_send == QETH_LARGE_SEND_NO) {
if (card->info.type == QETH_CARD_TYPE_IQD)
- card->options.large_send = QETH_LARGE_SEND_EDDP;
+ return -EPERM;
else
card->options.large_send = QETH_LARGE_SEND_TSO;
dev->features |= NETIF_F_TSO;
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
deleted file mode 100644
index 92b0417f8e1..00000000000
--- a/drivers/s390/s390mach.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * drivers/s390/s390mach.c
- * S/390 machine check handler
- *
- * Copyright IBM Corp. 2000,2008
- * Author(s): Ingo Adlung (adlung@de.ibm.com)
- * Martin Schwidefsky (schwidefsky@de.ibm.com)
- * Cornelia Huck <cornelia.huck@de.ibm.com>
- */
-
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/workqueue.h>
-#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/kthread.h>
-#include <asm/etr.h>
-#include <asm/lowcore.h>
-#include <asm/cio.h>
-#include <asm/cpu.h>
-#include "s390mach.h"
-
-static struct semaphore m_sem;
-
-static NORET_TYPE void
-s390_handle_damage(char *msg)
-{
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- disabled_wait((unsigned long) __builtin_return_address(0));
- for(;;);
-}
-
-static crw_handler_t crw_handlers[NR_RSCS];
-
-/**
- * s390_register_crw_handler() - register a channel report word handler
- * @rsc: reporting source code to handle
- * @handler: handler to be registered
- *
- * Returns %0 on success and a negative error value otherwise.
- */
-int s390_register_crw_handler(int rsc, crw_handler_t handler)
-{
- if ((rsc < 0) || (rsc >= NR_RSCS))
- return -EINVAL;
- if (!cmpxchg(&crw_handlers[rsc], NULL, handler))
- return 0;
- return -EBUSY;
-}
-
-/**
- * s390_unregister_crw_handler() - unregister a channel report word handler
- * @rsc: reporting source code to handle
- */
-void s390_unregister_crw_handler(int rsc)
-{
- if ((rsc < 0) || (rsc >= NR_RSCS))
- return;
- xchg(&crw_handlers[rsc], NULL);
- synchronize_sched();
-}
-
-/*
- * Retrieve CRWs and call function to handle event.
- */
-static int s390_collect_crw_info(void *param)
-{
- struct crw crw[2];
- int ccode;
- struct semaphore *sem;
- unsigned int chain;
- int ignore;
-
- sem = (struct semaphore *)param;
-repeat:
- ignore = down_interruptible(sem);
- chain = 0;
- while (1) {
- if (unlikely(chain > 1)) {
- struct crw tmp_crw;
-
- printk(KERN_WARNING"%s: Code does not support more "
- "than two chained crws; please report to "
- "linux390@de.ibm.com!\n", __func__);
- ccode = stcrw(&tmp_crw);
- printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
- "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
- __func__, tmp_crw.slct, tmp_crw.oflw,
- tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
- tmp_crw.erc, tmp_crw.rsid);
- printk(KERN_WARNING"%s: This was crw number %x in the "
- "chain\n", __func__, chain);
- if (ccode != 0)
- break;
- chain = tmp_crw.chn ? chain + 1 : 0;
- continue;
- }
- ccode = stcrw(&crw[chain]);
- if (ccode != 0)
- break;
- printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
- "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
- crw[chain].slct, crw[chain].oflw, crw[chain].chn,
- crw[chain].rsc, crw[chain].anc, crw[chain].erc,
- crw[chain].rsid);
- /* Check for overflows. */
- if (crw[chain].oflw) {
- int i;
-
- pr_debug("%s: crw overflow detected!\n", __func__);
- for (i = 0; i < NR_RSCS; i++) {
- if (crw_handlers[i])
- crw_handlers[i](NULL, NULL, 1);
- }
- chain = 0;
- continue;
- }
- if (crw[0].chn && !chain) {
- chain++;
- continue;
- }
- if (crw_handlers[crw[chain].rsc])
- crw_handlers[crw[chain].rsc](&crw[0],
- chain ? &crw[1] : NULL,
- 0);
- /* chain is always 0 or 1 here. */
- chain = crw[chain].chn ? chain + 1 : 0;
- }
- goto repeat;
- return 0;
-}
-
-struct mcck_struct {
- int kill_task;
- int channel_report;
- int warning;
- unsigned long long mcck_code;
-};
-
-static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
-
-/*
- * Main machine check handler function. Will be called with interrupts enabled
- * or disabled and machine checks enabled or disabled.
- */
-void
-s390_handle_mcck(void)
-{
- unsigned long flags;
- struct mcck_struct mcck;
-
- /*
- * Disable machine checks and get the current state of accumulated
- * machine checks. Afterwards delete the old state and enable machine
- * checks again.
- */
- local_irq_save(flags);
- local_mcck_disable();
- mcck = __get_cpu_var(cpu_mcck);
- memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct));
- clear_thread_flag(TIF_MCCK_PENDING);
- local_mcck_enable();
- local_irq_restore(flags);
-
- if (mcck.channel_report)
- up(&m_sem);
-
-#ifdef CONFIG_MACHCHK_WARNING
-/*
- * The warning may remain for a prolonged period on the bare iron.
- * (actually till the machine is powered off, or until the problem is gone)
- * So we just stop listening for the WARNING MCH and prevent continuously
- * being interrupted. One caveat is however, that we must do this per
- * processor and cannot use the smp version of ctl_clear_bit().
- * On VM we only get one interrupt per virtally presented machinecheck.
- * Though one suffices, we may get one interrupt per (virtual) processor.
- */
- if (mcck.warning) { /* WARNING pending ? */
- static int mchchk_wng_posted = 0;
- /*
- * Use single machine clear, as we cannot handle smp right now
- */
- __ctl_clear_bit(14, 24); /* Disable WARNING MCH */
- if (xchg(&mchchk_wng_posted, 1) == 0)
- kill_cad_pid(SIGPWR, 1);
- }
-#endif
-
- if (mcck.kill_task) {
- local_irq_enable();
- printk(KERN_EMERG "mcck: Terminating task because of machine "
- "malfunction (code 0x%016llx).\n", mcck.mcck_code);
- printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
- current->comm, current->pid);
- do_exit(SIGSEGV);
- }
-}
-EXPORT_SYMBOL_GPL(s390_handle_mcck);
-
-/*
- * returns 0 if all registers could be validated
- * returns 1 otherwise
- */
-static int
-s390_revalidate_registers(struct mci *mci)
-{
- int kill_task;
- u64 tmpclock;
- u64 zero;
- void *fpt_save_area, *fpt_creg_save_area;
-
- kill_task = 0;
- zero = 0;
- /* General purpose registers */
- if (!mci->gr)
- /*
- * General purpose registers couldn't be restored and have
- * unknown contents. Process needs to be terminated.
- */
- kill_task = 1;
-
- /* Revalidate floating point registers */
- if (!mci->fp)
- /*
- * Floating point registers can't be restored and
- * therefore the process needs to be terminated.
- */
- kill_task = 1;
-
-#ifndef CONFIG_64BIT
- asm volatile(
- " ld 0,0(%0)\n"
- " ld 2,8(%0)\n"
- " ld 4,16(%0)\n"
- " ld 6,24(%0)"
- : : "a" (&S390_lowcore.floating_pt_save_area));
-#endif
-
- if (MACHINE_HAS_IEEE) {
-#ifdef CONFIG_64BIT
- fpt_save_area = &S390_lowcore.floating_pt_save_area;
- fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
-#else
- fpt_save_area = (void *) S390_lowcore.extended_save_area_addr;
- fpt_creg_save_area = fpt_save_area+128;
-#endif
- /* Floating point control register */
- if (!mci->fc) {
- /*
- * Floating point control register can't be restored.
- * Task will be terminated.
- */
- asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
- kill_task = 1;
-
- } else
- asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
-
- asm volatile(
- " ld 0,0(%0)\n"
- " ld 1,8(%0)\n"
- " ld 2,16(%0)\n"
- " ld 3,24(%0)\n"
- " ld 4,32(%0)\n"
- " ld 5,40(%0)\n"
- " ld 6,48(%0)\n"
- " ld 7,56(%0)\n"
- " ld 8,64(%0)\n"
- " ld 9,72(%0)\n"
- " ld 10,80(%0)\n"
- " ld 11,88(%0)\n"
- " ld 12,96(%0)\n"
- " ld 13,104(%0)\n"
- " ld 14,112(%0)\n"
- " ld 15,120(%0)\n"
- : : "a" (fpt_save_area));
- }
-
- /* Revalidate access registers */
- asm volatile(
- " lam 0,15,0(%0)"
- : : "a" (&S390_lowcore.access_regs_save_area));
- if (!mci->ar)
- /*
- * Access registers have unknown contents.
- * Terminating task.
- */
- kill_task = 1;
-
- /* Revalidate control registers */
- if (!mci->cr)
- /*
- * Control registers have unknown contents.
- * Can't recover and therefore stopping machine.
- */
- s390_handle_damage("invalid control registers.");
- else
-#ifdef CONFIG_64BIT
- asm volatile(
- " lctlg 0,15,0(%0)"
- : : "a" (&S390_lowcore.cregs_save_area));
-#else
- asm volatile(
- " lctl 0,15,0(%0)"
- : : "a" (&S390_lowcore.cregs_save_area));
-#endif
-
- /*
- * We don't even try to revalidate the TOD register, since we simply
- * can't write something sensible into that register.
- */
-
-#ifdef CONFIG_64BIT
- /*
- * See if we can revalidate the TOD programmable register with its
- * old contents (should be zero) otherwise set it to zero.
- */
- if (!mci->pr)
- asm volatile(
- " sr 0,0\n"
- " sckpf"
- : : : "0", "cc");
- else
- asm volatile(
- " l 0,0(%0)\n"
- " sckpf"
- : : "a" (&S390_lowcore.tod_progreg_save_area)
- : "0", "cc");
-#endif
-
- /* Revalidate clock comparator register */
- asm volatile(
- " stck 0(%1)\n"
- " sckc 0(%1)"
- : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
-
- /* Check if old PSW is valid */
- if (!mci->wp)
- /*
- * Can't tell if we come from user or kernel mode
- * -> stopping machine.
- */
- s390_handle_damage("old psw invalid.");
-
- if (!mci->ms || !mci->pm || !mci->ia)
- kill_task = 1;
-
- return kill_task;
-}
-
-#define MAX_IPD_COUNT 29
-#define MAX_IPD_TIME (5 * 60 * USEC_PER_SEC) /* 5 minutes */
-
-/*
- * machine check handler.
- */
-void
-s390_do_machine_check(struct pt_regs *regs)
-{
- static DEFINE_SPINLOCK(ipd_lock);
- static unsigned long long last_ipd;
- static int ipd_count;
- unsigned long long tmp;
- struct mci *mci;
- struct mcck_struct *mcck;
- int umode;
-
- lockdep_off();
-
- s390_idle_check();
-
- mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
- mcck = &__get_cpu_var(cpu_mcck);
- umode = user_mode(regs);
-
- if (mci->sd)
- /* System damage -> stopping machine */
- s390_handle_damage("received system damage machine check.");
-
- if (mci->pd) {
- if (mci->b) {
- /* Processing backup -> verify if we can survive this */
- u64 z_mcic, o_mcic, t_mcic;
-#ifdef CONFIG_64BIT
- z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
- o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
- 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
- 1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
- 1ULL<<16);
-#else
- z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
- 1ULL<<29);
- o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
- 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
- 1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
-#endif
- t_mcic = *(u64 *)mci;
-
- if (((t_mcic & z_mcic) != 0) ||
- ((t_mcic & o_mcic) != o_mcic)) {
- s390_handle_damage("processing backup machine "
- "check with damage.");
- }
-
- /*
- * Nullifying exigent condition, therefore we might
- * retry this instruction.
- */
-
- spin_lock(&ipd_lock);
-
- tmp = get_clock();
-
- if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME)
- ipd_count++;
- else
- ipd_count = 1;
-
- last_ipd = tmp;
-
- if (ipd_count == MAX_IPD_COUNT)
- s390_handle_damage("too many ipd retries.");
-
- spin_unlock(&ipd_lock);
- }
- else {
- /* Processing damage -> stopping machine */
- s390_handle_damage("received instruction processing "
- "damage machine check.");
- }
- }
- if (s390_revalidate_registers(mci)) {
- if (umode) {
- /*
- * Couldn't restore all register contents while in
- * user mode -> mark task for termination.
- */
- mcck->kill_task = 1;
- mcck->mcck_code = *(unsigned long long *) mci;
- set_thread_flag(TIF_MCCK_PENDING);
- }
- else
- /*
- * Couldn't restore all register contents while in
- * kernel mode -> stopping machine.
- */
- s390_handle_damage("unable to revalidate registers.");
- }
-
- if (mci->cd) {
- /* Timing facility damage */
- s390_handle_damage("TOD clock damaged");
- }
-
- if (mci->ed && mci->ec) {
- /* External damage */
- if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))
- etr_sync_check();
- if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))
- etr_switch_to_local();
- if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC))
- stp_sync_check();
- if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND))
- stp_island_check();
- }
-
- if (mci->se)
- /* Storage error uncorrected */
- s390_handle_damage("received storage error uncorrected "
- "machine check.");
-
- if (mci->ke)
- /* Storage key-error uncorrected */
- s390_handle_damage("received storage key-error uncorrected "
- "machine check.");
-
- if (mci->ds && mci->fa)
- /* Storage degradation */
- s390_handle_damage("received storage degradation machine "
- "check.");
-
- if (mci->cp) {
- /* Channel report word pending */
- mcck->channel_report = 1;
- set_thread_flag(TIF_MCCK_PENDING);
- }
-
- if (mci->w) {
- /* Warning pending */
- mcck->warning = 1;
- set_thread_flag(TIF_MCCK_PENDING);
- }
- lockdep_on();
-}
-
-/*
- * s390_init_machine_check
- *
- * initialize machine check handling
- */
-static int
-machine_check_init(void)
-{
- init_MUTEX_LOCKED(&m_sem);
- ctl_set_bit(14, 25); /* enable external damage MCH */
- ctl_set_bit(14, 27); /* enable system recovery MCH */
-#ifdef CONFIG_MACHCHK_WARNING
- ctl_set_bit(14, 24); /* enable warning MCH */
-#endif
- return 0;
-}
-
-/*
- * Initialize the machine check handler really early to be able to
- * catch all machine checks that happen during boot
- */
-arch_initcall(machine_check_init);
-
-/*
- * Machine checks for the channel subsystem must be enabled
- * after the channel subsystem is initialized
- */
-static int __init
-machine_check_crw_init (void)
-{
- struct task_struct *task;
-
- task = kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
- if (IS_ERR(task))
- return PTR_ERR(task);
- ctl_set_bit(14, 28); /* enable channel report MCH */
- return 0;
-}
-
-device_initcall (machine_check_crw_init);
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
deleted file mode 100644
index d39f8b697d2..00000000000
--- a/drivers/s390/s390mach.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * drivers/s390/s390mach.h
- * S/390 data definitions for machine check processing
- *
- * S390 version
- * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390mach_h
-#define __s390mach_h
-
-#include <asm/types.h>
-
-struct mci {
- __u32 sd : 1; /* 00 system damage */
- __u32 pd : 1; /* 01 instruction-processing damage */
- __u32 sr : 1; /* 02 system recovery */
- __u32 to_be_defined_1 : 1; /* 03 */
- __u32 cd : 1; /* 04 timing-facility damage */
- __u32 ed : 1; /* 05 external damage */
- __u32 to_be_defined_2 : 1; /* 06 */
- __u32 dg : 1; /* 07 degradation */
- __u32 w : 1; /* 08 warning pending */
- __u32 cp : 1; /* 09 channel-report pending */
- __u32 sp : 1; /* 10 service-processor damage */
- __u32 ck : 1; /* 11 channel-subsystem damage */
- __u32 to_be_defined_3 : 2; /* 12-13 */
- __u32 b : 1; /* 14 backed up */
- __u32 to_be_defined_4 : 1; /* 15 */
- __u32 se : 1; /* 16 storage error uncorrected */
- __u32 sc : 1; /* 17 storage error corrected */
- __u32 ke : 1; /* 18 storage-key error uncorrected */
- __u32 ds : 1; /* 19 storage degradation */
- __u32 wp : 1; /* 20 psw mwp validity */
- __u32 ms : 1; /* 21 psw mask and key validity */
- __u32 pm : 1; /* 22 psw program mask and cc validity */
- __u32 ia : 1; /* 23 psw instruction address validity */
- __u32 fa : 1; /* 24 failing storage address validity */
- __u32 to_be_defined_5 : 1; /* 25 */
- __u32 ec : 1; /* 26 external damage code validity */
- __u32 fp : 1; /* 27 floating point register validity */
- __u32 gr : 1; /* 28 general register validity */
- __u32 cr : 1; /* 29 control register validity */
- __u32 to_be_defined_6 : 1; /* 30 */
- __u32 st : 1; /* 31 storage logical validity */
- __u32 ie : 1; /* 32 indirect storage error */
- __u32 ar : 1; /* 33 access register validity */
- __u32 da : 1; /* 34 delayed access exception */
- __u32 to_be_defined_7 : 7; /* 35-41 */
- __u32 pr : 1; /* 42 tod programmable register validity */
- __u32 fc : 1; /* 43 fp control register validity */
- __u32 ap : 1; /* 44 ancillary report */
- __u32 to_be_defined_8 : 1; /* 45 */
- __u32 ct : 1; /* 46 cpu timer validity */
- __u32 cc : 1; /* 47 clock comparator validity */
- __u32 to_be_defined_9 : 16; /* 47-63 */
-};
-
-/*
- * Channel Report Word
- */
-struct crw {
- __u32 res1 : 1; /* reserved zero */
- __u32 slct : 1; /* solicited */
- __u32 oflw : 1; /* overflow */
- __u32 chn : 1; /* chained */
- __u32 rsc : 4; /* reporting source code */
- __u32 anc : 1; /* ancillary report */
- __u32 res2 : 1; /* reserved zero */
- __u32 erc : 6; /* error-recovery code */
- __u32 rsid : 16; /* reporting-source ID */
-} __attribute__ ((packed));
-
-typedef void (*crw_handler_t)(struct crw *, struct crw *, int);
-
-extern int s390_register_crw_handler(int rsc, crw_handler_t handler);
-extern void s390_unregister_crw_handler(int rsc);
-
-#define NR_RSCS 16
-
-#define CRW_RSC_MONITOR 0x2 /* monitoring facility */
-#define CRW_RSC_SCH 0x3 /* subchannel */
-#define CRW_RSC_CPATH 0x4 /* channel path */
-#define CRW_RSC_CONFIG 0x9 /* configuration-alert facility */
-#define CRW_RSC_CSS 0xB /* channel subsystem */
-
-#define CRW_ERC_EVENT 0x00 /* event information pending */
-#define CRW_ERC_AVAIL 0x01 /* available */
-#define CRW_ERC_INIT 0x02 /* initialized */
-#define CRW_ERC_TERROR 0x03 /* temporary error */
-#define CRW_ERC_IPARM 0x04 /* installed parm initialized */
-#define CRW_ERC_TERM 0x05 /* terminal */
-#define CRW_ERC_PERRN 0x06 /* perm. error, fac. not init */
-#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
-#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
-
-static inline int stcrw(struct crw *pcrw )
-{
- int ccode;
-
- __asm__ __volatile__(
- "stcrw 0(%2)\n\t"
- "ipm %0\n\t"
- "srl %0,28\n\t"
- : "=d" (ccode), "=m" (*pcrw)
- : "a" (pcrw)
- : "cc" );
- return ccode;
-}
-
-#define ED_ETR_SYNC 12 /* External damage ETR sync check */
-#define ED_ETR_SWITCH 13 /* External damage ETR switch to local */
-
-#define ED_STP_SYNC 7 /* External damage STP sync check */
-#define ED_STP_ISLAND 6 /* External damage STP island check */
-
-struct pt_regs;
-
-void s390_handle_mcck(void);
-void s390_do_machine_check(struct pt_regs *regs);
-#endif /* __s390mach */
diff --git a/drivers/s390/sysinfo.c b/drivers/s390/sysinfo.c
deleted file mode 100644
index 0eea9078138..00000000000
--- a/drivers/s390/sysinfo.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * drivers/s390/sysinfo.c
- *
- * Copyright IBM Corp. 2001, 2008
- * Author(s): Ulrich Weigand (Ulrich.Weigand@de.ibm.com)
- * Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <asm/ebcdic.h>
-#include <asm/sysinfo.h>
-#include <asm/cpcmd.h>
-
-/* Sigh, math-emu. Don't ask. */
-#include <asm/sfp-util.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-static inline int stsi_0(void)
-{
- int rc = stsi (NULL, 0, 0, 0);
- return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
-}
-
-static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
-{
- if (stsi(info, 1, 1, 1) == -ENOSYS)
- return len;
-
- EBCASC(info->manufacturer, sizeof(info->manufacturer));
- EBCASC(info->type, sizeof(info->type));
- EBCASC(info->model, sizeof(info->model));
- EBCASC(info->sequence, sizeof(info->sequence));
- EBCASC(info->plant, sizeof(info->plant));
- EBCASC(info->model_capacity, sizeof(info->model_capacity));
- EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
- EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
- len += sprintf(page + len, "Manufacturer: %-16.16s\n",
- info->manufacturer);
- len += sprintf(page + len, "Type: %-4.4s\n",
- info->type);
- if (info->model[0] != '\0')
- /*
- * Sigh: the model field has been renamed with System z9
- * to model_capacity and a new model field has been added
- * after the plant field. To avoid confusing older programs
- * the "Model:" prints "model_capacity model" or just
- * "model_capacity" if the model string is empty .
- */
- len += sprintf(page + len,
- "Model: %-16.16s %-16.16s\n",
- info->model_capacity, info->model);
- else
- len += sprintf(page + len, "Model: %-16.16s\n",
- info->model_capacity);
- len += sprintf(page + len, "Sequence Code: %-16.16s\n",
- info->sequence);
- len += sprintf(page + len, "Plant: %-4.4s\n",
- info->plant);
- len += sprintf(page + len, "Model Capacity: %-16.16s %08u\n",
- info->model_capacity, *(u32 *) info->model_cap_rating);
- if (info->model_perm_cap[0] != '\0')
- len += sprintf(page + len,
- "Model Perm. Capacity: %-16.16s %08u\n",
- info->model_perm_cap,
- *(u32 *) info->model_perm_cap_rating);
- if (info->model_temp_cap[0] != '\0')
- len += sprintf(page + len,
- "Model Temp. Capacity: %-16.16s %08u\n",
- info->model_temp_cap,
- *(u32 *) info->model_temp_cap_rating);
- return len;
-}
-
-#if 0 /* Currently unused */
-static int stsi_1_2_1(struct sysinfo_1_2_1 *info, char *page, int len)
-{
- if (stsi(info, 1, 2, 1) == -ENOSYS)
- return len;
-
- len += sprintf(page + len, "\n");
- EBCASC(info->sequence, sizeof(info->sequence));
- EBCASC(info->plant, sizeof(info->plant));
- len += sprintf(page + len, "Sequence Code of CPU: %-16.16s\n",
- info->sequence);
- len += sprintf(page + len, "Plant of CPU: %-16.16s\n",
- info->plant);
- return len;
-}
-#endif
-
-static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
-{
- struct sysinfo_1_2_2_extension *ext;
- int i;
-
- if (stsi(info, 1, 2, 2) == -ENOSYS)
- return len;
- ext = (struct sysinfo_1_2_2_extension *)
- ((unsigned long) info + info->acc_offset);
-
- len += sprintf(page + len, "\n");
- len += sprintf(page + len, "CPUs Total: %d\n",
- info->cpus_total);
- len += sprintf(page + len, "CPUs Configured: %d\n",
- info->cpus_configured);
- len += sprintf(page + len, "CPUs Standby: %d\n",
- info->cpus_standby);
- len += sprintf(page + len, "CPUs Reserved: %d\n",
- info->cpus_reserved);
-
- if (info->format == 1) {
- /*
- * Sigh 2. According to the specification the alternate
- * capability field is a 32 bit floating point number
- * if the higher order 8 bits are not zero. Printing
- * a floating point number in the kernel is a no-no,
- * always print the number as 32 bit unsigned integer.
- * The user-space needs to know about the strange
- * encoding of the alternate cpu capability.
- */
- len += sprintf(page + len, "Capability: %u %u\n",
- info->capability, ext->alt_capability);
- for (i = 2; i <= info->cpus_total; i++)
- len += sprintf(page + len,
- "Adjustment %02d-way: %u %u\n",
- i, info->adjustment[i-2],
- ext->alt_adjustment[i-2]);
-
- } else {
- len += sprintf(page + len, "Capability: %u\n",
- info->capability);
- for (i = 2; i <= info->cpus_total; i++)
- len += sprintf(page + len,
- "Adjustment %02d-way: %u\n",
- i, info->adjustment[i-2]);
- }
-
- if (info->secondary_capability != 0)
- len += sprintf(page + len, "Secondary Capability: %d\n",
- info->secondary_capability);
-
- return len;
-}
-
-#if 0 /* Currently unused */
-static int stsi_2_2_1(struct sysinfo_2_2_1 *info, char *page, int len)
-{
- if (stsi(info, 2, 2, 1) == -ENOSYS)
- return len;
-
- len += sprintf(page + len, "\n");
- EBCASC (info->sequence, sizeof(info->sequence));
- EBCASC (info->plant, sizeof(info->plant));
- len += sprintf(page + len, "Sequence Code of logical CPU: %-16.16s\n",
- info->sequence);
- len += sprintf(page + len, "Plant of logical CPU: %-16.16s\n",
- info->plant);
- return len;
-}
-#endif
-
-static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len)
-{
- if (stsi(info, 2, 2, 2) == -ENOSYS)
- return len;
-
- EBCASC (info->name, sizeof(info->name));
-
- len += sprintf(page + len, "\n");
- len += sprintf(page + len, "LPAR Number: %d\n",
- info->lpar_number);
-
- len += sprintf(page + len, "LPAR Characteristics: ");
- if (info->characteristics & LPAR_CHAR_DEDICATED)
- len += sprintf(page + len, "Dedicated ");
- if (info->characteristics & LPAR_CHAR_SHARED)
- len += sprintf(page + len, "Shared ");
- if (info->characteristics & LPAR_CHAR_LIMITED)
- len += sprintf(page + len, "Limited ");
- len += sprintf(page + len, "\n");
-
- len += sprintf(page + len, "LPAR Name: %-8.8s\n",
- info->name);
-
- len += sprintf(page + len, "LPAR Adjustment: %d\n",
- info->caf);
-
- len += sprintf(page + len, "LPAR CPUs Total: %d\n",
- info->cpus_total);
- len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
- info->cpus_configured);
- len += sprintf(page + len, "LPAR CPUs Standby: %d\n",
- info->cpus_standby);
- len += sprintf(page + len, "LPAR CPUs Reserved: %d\n",
- info->cpus_reserved);
- len += sprintf(page + len, "LPAR CPUs Dedicated: %d\n",
- info->cpus_dedicated);
- len += sprintf(page + len, "LPAR CPUs Shared: %d\n",
- info->cpus_shared);
- return len;
-}
-
-static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
-{
- int i;
-
- if (stsi(info, 3, 2, 2) == -ENOSYS)
- return len;
- for (i = 0; i < info->count; i++) {
- EBCASC (info->vm[i].name, sizeof(info->vm[i].name));
- EBCASC (info->vm[i].cpi, sizeof(info->vm[i].cpi));
- len += sprintf(page + len, "\n");
- len += sprintf(page + len, "VM%02d Name: %-8.8s\n",
- i, info->vm[i].name);
- len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n",
- i, info->vm[i].cpi);
-
- len += sprintf(page + len, "VM%02d Adjustment: %d\n",
- i, info->vm[i].caf);
-
- len += sprintf(page + len, "VM%02d CPUs Total: %d\n",
- i, info->vm[i].cpus_total);
- len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
- i, info->vm[i].cpus_configured);
- len += sprintf(page + len, "VM%02d CPUs Standby: %d\n",
- i, info->vm[i].cpus_standby);
- len += sprintf(page + len, "VM%02d CPUs Reserved: %d\n",
- i, info->vm[i].cpus_reserved);
- }
- return len;
-}
-
-
-static int proc_read_sysinfo(char *page, char **start,
- off_t off, int count,
- int *eof, void *data)
-{
- unsigned long info = get_zeroed_page (GFP_KERNEL);
- int level, len;
-
- if (!info)
- return 0;
-
- len = 0;
- level = stsi_0();
- if (level >= 1)
- len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
-
- if (level >= 1)
- len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
-
- if (level >= 2)
- len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len);
-
- if (level >= 3)
- len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
-
- free_page (info);
- return len;
-}
-
-static __init int create_proc_sysinfo(void)
-{
- create_proc_read_entry("sysinfo", 0444, NULL,
- proc_read_sysinfo, NULL);
- return 0;
-}
-
-__initcall(create_proc_sysinfo);
-
-/*
- * Service levels interface.
- */
-
-static DECLARE_RWSEM(service_level_sem);
-static LIST_HEAD(service_level_list);
-
-int register_service_level(struct service_level *slr)
-{
- struct service_level *ptr;
-
- down_write(&service_level_sem);
- list_for_each_entry(ptr, &service_level_list, list)
- if (ptr == slr) {
- up_write(&service_level_sem);
- return -EEXIST;
- }
- list_add_tail(&slr->list, &service_level_list);
- up_write(&service_level_sem);
- return 0;
-}
-EXPORT_SYMBOL(register_service_level);
-
-int unregister_service_level(struct service_level *slr)
-{
- struct service_level *ptr, *next;
- int rc = -ENOENT;
-
- down_write(&service_level_sem);
- list_for_each_entry_safe(ptr, next, &service_level_list, list) {
- if (ptr != slr)
- continue;
- list_del(&ptr->list);
- rc = 0;
- break;
- }
- up_write(&service_level_sem);
- return rc;
-}
-EXPORT_SYMBOL(unregister_service_level);
-
-static void *service_level_start(struct seq_file *m, loff_t *pos)
-{
- down_read(&service_level_sem);
- return seq_list_start(&service_level_list, *pos);
-}
-
-static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
-{
- return seq_list_next(p, &service_level_list, pos);
-}
-
-static void service_level_stop(struct seq_file *m, void *p)
-{
- up_read(&service_level_sem);
-}
-
-static int service_level_show(struct seq_file *m, void *p)
-{
- struct service_level *slr;
-
- slr = list_entry(p, struct service_level, list);
- slr->seq_print(m, slr);
- return 0;
-}
-
-static const struct seq_operations service_level_seq_ops = {
- .start = service_level_start,
- .next = service_level_next,
- .stop = service_level_stop,
- .show = service_level_show
-};
-
-static int service_level_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &service_level_seq_ops);
-}
-
-static const struct file_operations service_level_ops = {
- .open = service_level_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release
-};
-
-static void service_level_vm_print(struct seq_file *m,
- struct service_level *slr)
-{
- char *query_buffer, *str;
-
- query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
- if (!query_buffer)
- return;
- cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
- str = strchr(query_buffer, '\n');
- if (str)
- *str = 0;
- seq_printf(m, "VM: %s\n", query_buffer);
- kfree(query_buffer);
-}
-
-static struct service_level service_level_vm = {
- .seq_print = service_level_vm_print
-};
-
-static __init int create_proc_service_level(void)
-{
- proc_create("service_levels", 0, NULL, &service_level_ops);
- if (MACHINE_IS_VM)
- register_service_level(&service_level_vm);
- return 0;
-}
-
-subsys_initcall(create_proc_service_level);
-
-/*
- * Bogomips calculation based on cpu capability.
- */
-
-int get_cpu_capability(unsigned int *capability)
-{
- struct sysinfo_1_2_2 *info;
- int rc;
-
- info = (void *) get_zeroed_page(GFP_KERNEL);
- if (!info)
- return -ENOMEM;
- rc = stsi(info, 1, 2, 2);
- if (rc == -ENOSYS)
- goto out;
- rc = 0;
- *capability = info->capability;
-out:
- free_page((unsigned long) info);
- return rc;
-}
-
-/*
- * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
- */
-void s390_adjust_jiffies(void)
-{
- struct sysinfo_1_2_2 *info;
- const unsigned int fmil = 0x4b189680; /* 1e7 as 32-bit float. */
- FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
- FP_DECL_EX;
- unsigned int capability;
-
- info = (void *) get_zeroed_page(GFP_KERNEL);
- if (!info)
- return;
-
- if (stsi(info, 1, 2, 2) != -ENOSYS) {
- /*
- * Major sigh. The cpu capability encoding is "special".
- * If the first 9 bits of info->capability are 0 then it
- * is a 32 bit unsigned integer in the range 0 .. 2^23.
- * If the first 9 bits are != 0 then it is a 32 bit float.
- * In addition a lower value indicates a proportionally
- * higher cpu capacity. Bogomips are the other way round.
- * To get to a halfway suitable number we divide 1e7
- * by the cpu capability number. Yes, that means a floating
- * point division .. math-emu here we come :-)
- */
- FP_UNPACK_SP(SA, &fmil);
- if ((info->capability >> 23) == 0)
- FP_FROM_INT_S(SB, info->capability, 32, int);
- else
- FP_UNPACK_SP(SB, &info->capability);
- FP_DIV_S(SR, SA, SB);
- FP_TO_INT_S(capability, SR, 32, 0);
- } else
- /*
- * Really old machine without stsi block for basic
- * cpu information. Report 42.0 bogomips.
- */
- capability = 42;
- loops_per_jiffy = capability * (500000/HZ);
- free_page((unsigned long) info);
-}
-
-/*
- * calibrate the delay loop
- */
-void __cpuinit calibrate_delay(void)
-{
- s390_adjust_jiffies();
- /* Print the good old Bogomips line .. */
- printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
- "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
- (loops_per_jiffy/(5000/HZ)) % 100);
-}
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
index f08e169ba1b..7e30e5f6e03 100644
--- a/drivers/sbus/char/bbc_i2c.c
+++ b/drivers/sbus/char/bbc_i2c.c
@@ -129,7 +129,7 @@ static int wait_for_pin(struct bbc_i2c_bus *bp, u8 *status)
bp->waiting = 1;
add_wait_queue(&bp->wq, &wait);
while (limit-- > 0) {
- unsigned long val;
+ long val;
val = wait_event_interruptible_timeout(
bp->wq,
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index a9a9893a5f9..e6d1fc8c54f 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -38,9 +38,6 @@
#include <linux/string.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
-
-#define MAJOR_NR JSFD_MAJOR
-
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 29dc735e1a2..124f660a038 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -51,6 +51,7 @@ MODULE_AUTHOR("Thomas K. Dyas (tdyas@noc.rutgers.edu) and Eddie C. Dost (ecd@sk
MODULE_DESCRIPTION("OPENPROM Configuration Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
+MODULE_ALIAS_MISCDEV(SUN_OPENPROM_MINOR);
/* Private data kept by the driver for each descriptor. */
typedef struct openprom_private_data
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index d4bda201774..61af3d91ac8 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -35,7 +35,7 @@ static struct platform_device *a4000t_scsi_device;
#define A4000T_SCSI_ADDR 0xdd0040
-static int __devinit a4000t_probe(struct device *dev)
+static int __devinit a4000t_probe(struct platform_device *dev)
{
struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata;
@@ -61,7 +61,8 @@ static int __devinit a4000t_probe(struct device *dev)
hostdata->dcntl_extra = EA_710;
/* and register the chip */
- host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata, dev);
+ host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata,
+ &dev->dev);
if (!host) {
printk(KERN_ERR "a4000t-scsi: No host detected; "
"board configuration problem?\n");
@@ -78,7 +79,7 @@ static int __devinit a4000t_probe(struct device *dev)
goto out_put_host;
}
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);
return 0;
@@ -93,9 +94,9 @@ static int __devinit a4000t_probe(struct device *dev)
return -ENODEV;
}
-static __devexit int a4000t_device_remove(struct device *dev)
+static __devexit int a4000t_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
scsi_remove_host(host);
@@ -108,25 +109,27 @@ static __devexit int a4000t_device_remove(struct device *dev)
return 0;
}
-static struct device_driver a4000t_scsi_driver = {
- .name = "a4000t-scsi",
- .bus = &platform_bus_type,
- .probe = a4000t_probe,
- .remove = __devexit_p(a4000t_device_remove),
+static struct platform_driver a4000t_scsi_driver = {
+ .driver = {
+ .name = "a4000t-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = a4000t_probe,
+ .remove = __devexit_p(a4000t_device_remove),
};
static int __init a4000t_scsi_init(void)
{
int err;
- err = driver_register(&a4000t_scsi_driver);
+ err = platform_driver_register(&a4000t_scsi_driver);
if (err)
return err;
a4000t_scsi_device = platform_device_register_simple("a4000t-scsi",
-1, NULL, 0);
if (IS_ERR(a4000t_scsi_device)) {
- driver_unregister(&a4000t_scsi_driver);
+ platform_driver_register(&a4000t_scsi_driver);
return PTR_ERR(a4000t_scsi_device);
}
@@ -136,7 +139,7 @@ static int __init a4000t_scsi_init(void)
static void __exit a4000t_scsi_exit(void)
{
platform_device_unregister(a4000t_scsi_device);
- driver_unregister(&a4000t_scsi_driver);
+ platform_driver_unregister(&a4000t_scsi_driver);
}
module_init(a4000t_scsi_init);
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 93b61f14865..0471f880048 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -844,7 +844,7 @@ static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int lengt
*
*/
-static int NCR5380_init(struct Scsi_Host *instance, int flags)
+static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
{
int i;
SETUP_HOSTDATA(instance);
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index 21fe07f9df8..ad7a23aef0e 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -589,7 +589,7 @@ int atari_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
#endif
-int atari_scsi_detect(struct scsi_host_template *host)
+int __init atari_scsi_detect(struct scsi_host_template *host)
{
static int called = 0;
struct Scsi_Host *instance;
diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c
index d858f3d4127..5799cb5cba6 100644
--- a/drivers/scsi/bvme6000_scsi.c
+++ b/drivers/scsi/bvme6000_scsi.c
@@ -34,7 +34,7 @@ static struct scsi_host_template bvme6000_scsi_driver_template = {
static struct platform_device *bvme6000_scsi_device;
static __devinit int
-bvme6000_probe(struct device *dev)
+bvme6000_probe(struct platform_device *dev)
{
struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata;
@@ -58,7 +58,8 @@ bvme6000_probe(struct device *dev)
hostdata->ctest7_extra = CTEST7_TT1;
/* and register the chip */
- host = NCR_700_detect(&bvme6000_scsi_driver_template, hostdata, dev);
+ host = NCR_700_detect(&bvme6000_scsi_driver_template, hostdata,
+ &dev->dev);
if (!host) {
printk(KERN_ERR "bvme6000-scsi: No host detected; "
"board configuration problem?\n");
@@ -73,7 +74,7 @@ bvme6000_probe(struct device *dev)
goto out_put_host;
}
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);
return 0;
@@ -87,9 +88,9 @@ bvme6000_probe(struct device *dev)
}
static __devexit int
-bvme6000_device_remove(struct device *dev)
+bvme6000_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
scsi_remove_host(host);
@@ -100,25 +101,27 @@ bvme6000_device_remove(struct device *dev)
return 0;
}
-static struct device_driver bvme6000_scsi_driver = {
- .name = "bvme6000-scsi",
- .bus = &platform_bus_type,
- .probe = bvme6000_probe,
- .remove = __devexit_p(bvme6000_device_remove),
+static struct platform_driver bvme6000_scsi_driver = {
+ .driver = {
+ .name = "bvme6000-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = bvme6000_probe,
+ .remove = __devexit_p(bvme6000_device_remove),
};
static int __init bvme6000_scsi_init(void)
{
int err;
- err = driver_register(&bvme6000_scsi_driver);
+ err = platform_driver_register(&bvme6000_scsi_driver);
if (err)
return err;
bvme6000_scsi_device = platform_device_register_simple("bvme6000-scsi",
-1, NULL, 0);
if (IS_ERR(bvme6000_scsi_device)) {
- driver_unregister(&bvme6000_scsi_driver);
+ platform_driver_unregister(&bvme6000_scsi_driver);
return PTR_ERR(bvme6000_scsi_device);
}
@@ -128,7 +131,7 @@ static int __init bvme6000_scsi_init(void)
static void __exit bvme6000_scsi_exit(void)
{
platform_device_unregister(bvme6000_scsi_device);
- driver_unregister(&bvme6000_scsi_driver);
+ platform_driver_unregister(&bvme6000_scsi_driver);
}
module_init(bvme6000_scsi_init);
diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h
index fde6e4c634e..a7cf550b9cc 100644
--- a/drivers/scsi/cxgb3i/cxgb3i.h
+++ b/drivers/scsi/cxgb3i/cxgb3i.h
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/scatterlist.h>
+#include <linux/skbuff.h>
#include <scsi/libiscsi_tcp.h>
/* from cxgb3 LLD */
@@ -113,6 +114,26 @@ struct cxgb3i_endpoint {
struct cxgb3i_conn *cconn;
};
+/**
+ * struct cxgb3i_task_data - private iscsi task data
+ *
+ * @nr_frags: # of coalesced page frags (from scsi sgl)
+ * @frags: coalesced page frags (from scsi sgl)
+ * @skb: tx pdu skb
+ * @offset: data offset for the next pdu
+ * @count: max. possible pdu payload
+ * @sgoffset: offset to the first sg entry for a given offset
+ */
+#define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512)
+struct cxgb3i_task_data {
+ unsigned short nr_frags;
+ skb_frag_t frags[MAX_PDU_FRAGS];
+ struct sk_buff *skb;
+ unsigned int offset;
+ unsigned int count;
+ unsigned int sgoffset;
+};
+
int cxgb3i_iscsi_init(void);
void cxgb3i_iscsi_cleanup(void);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
index 08f3a09d923..a83d36e4926 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
@@ -639,10 +639,11 @@ static int ddp_init(struct t3cdev *tdev)
write_unlock(&cxgb3i_ddp_rwlock);
ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x "
- "pkt %u,%u.\n",
+ "pkt %u/%u, %u/%u.\n",
ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits,
ddp->idx_mask, ddp->rsvd_tag_mask,
- ddp->max_txsz, ddp->max_rxsz);
+ ddp->max_txsz, uinfo.max_txsz,
+ ddp->max_rxsz, uinfo.max_rxsz);
return 0;
free_ddp_map:
@@ -654,8 +655,8 @@ free_ddp_map:
* cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource
* @tdev: t3cdev adapter
* @tformat: tag format
- * @txsz: max tx pkt size, filled in by this func.
- * @rxsz: max rx pkt size, filled in by this func.
+ * @txsz: max tx pdu payload size, filled in by this func.
+ * @rxsz: max rx pdu payload size, filled in by this func.
* initialize the ddp pagepod manager for a given adapter if needed and
* setup the tag format for a given iscsi entity
*/
@@ -685,10 +686,12 @@ int cxgb3i_adapter_ddp_init(struct t3cdev *tdev,
tformat->sw_bits, tformat->rsvd_bits,
tformat->rsvd_shift, tformat->rsvd_mask);
- *txsz = ddp->max_txsz;
- *rxsz = ddp->max_rxsz;
- ddp_log_info("ddp max pkt size: %u, %u.\n",
- ddp->max_txsz, ddp->max_rxsz);
+ *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ ddp_log_info("max payload size: %u/%u, %u/%u.\n",
+ *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
return 0;
}
EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
index 5c7c4d95c49..3faae7831c8 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
@@ -13,6 +13,8 @@
#ifndef __CXGB3I_ULP2_DDP_H__
#define __CXGB3I_ULP2_DDP_H__
+#include <linux/vmalloc.h>
+
/**
* struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity
*
@@ -85,8 +87,9 @@ struct cxgb3i_ddp_info {
struct sk_buff **gl_skb;
};
+#define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8) */
#define ULP2_MAX_PKT_SIZE 16224
-#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_MAX)
+#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN)
#define PPOD_PAGES_MAX 4
#define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */
diff --git a/drivers/scsi/cxgb3i/cxgb3i_init.c b/drivers/scsi/cxgb3i/cxgb3i_init.c
index 091ecb4d9f3..1ce9f244e46 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_init.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_init.c
@@ -12,8 +12,8 @@
#include "cxgb3i.h"
#define DRV_MODULE_NAME "cxgb3i"
-#define DRV_MODULE_VERSION "1.0.0"
-#define DRV_MODULE_RELDATE "Jun. 1, 2008"
+#define DRV_MODULE_VERSION "1.0.1"
+#define DRV_MODULE_RELDATE "Jan. 2009"
static char version[] =
"Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index d83464b9b3f..fa2a44f37b3 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -364,7 +364,8 @@ cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth,
cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost,
cmds_max,
- sizeof(struct iscsi_tcp_task),
+ sizeof(struct iscsi_tcp_task) +
+ sizeof(struct cxgb3i_task_data),
initial_cmdsn, ISCSI_MAX_TARGET);
if (!cls_session)
return NULL;
@@ -402,17 +403,15 @@ static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn)
{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
- cconn->hba->snic->tx_max_size -
- ISCSI_PDU_NONPAYLOAD_MAX);
+ unsigned int max = max(512 * MAX_SKB_FRAGS, SKB_TX_HEADROOM);
+ max = min(cconn->hba->snic->tx_max_size, max);
if (conn->max_xmit_dlength)
- conn->max_xmit_dlength = min_t(unsigned int,
- conn->max_xmit_dlength, max);
+ conn->max_xmit_dlength = min(conn->max_xmit_dlength, max);
else
conn->max_xmit_dlength = max;
align_pdu_size(conn->max_xmit_dlength);
- cxgb3i_log_info("conn 0x%p, max xmit %u.\n",
+ cxgb3i_api_debug("conn 0x%p, max xmit %u.\n",
conn, conn->max_xmit_dlength);
return 0;
}
@@ -427,9 +426,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn)
{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
- cconn->hba->snic->rx_max_size -
- ISCSI_PDU_NONPAYLOAD_MAX);
+ unsigned int max = cconn->hba->snic->rx_max_size;
align_pdu_size(max);
if (conn->max_recv_dlength) {
@@ -439,8 +436,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn)
conn->max_recv_dlength, max);
return -EINVAL;
}
- conn->max_recv_dlength = min_t(unsigned int,
- conn->max_recv_dlength, max);
+ conn->max_recv_dlength = min(conn->max_recv_dlength, max);
align_pdu_size(conn->max_recv_dlength);
} else
conn->max_recv_dlength = max;
@@ -844,7 +840,7 @@ static struct scsi_host_template cxgb3i_host_template = {
.proc_name = "cxgb3i",
.queuecommand = iscsi_queuecommand,
.change_queue_depth = iscsi_change_queue_depth,
- .can_queue = 128 * (ISCSI_DEF_XMIT_CMDS_MAX - 1),
+ .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1,
.sg_tablesize = SG_ALL,
.max_sectors = 0xFFFF,
.cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c
index a865f1fefe8..de3b3b614cc 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c
@@ -23,19 +23,19 @@
#include "cxgb3i_ddp.h"
#ifdef __DEBUG_C3CN_CONN__
-#define c3cn_conn_debug cxgb3i_log_info
+#define c3cn_conn_debug cxgb3i_log_debug
#else
#define c3cn_conn_debug(fmt...)
#endif
#ifdef __DEBUG_C3CN_TX__
-#define c3cn_tx_debug cxgb3i_log_debug
+#define c3cn_tx_debug cxgb3i_log_debug
#else
#define c3cn_tx_debug(fmt...)
#endif
#ifdef __DEBUG_C3CN_RX__
-#define c3cn_rx_debug cxgb3i_log_debug
+#define c3cn_rx_debug cxgb3i_log_debug
#else
#define c3cn_rx_debug(fmt...)
#endif
@@ -47,9 +47,9 @@ static int cxgb3_rcv_win = 256 * 1024;
module_param(cxgb3_rcv_win, int, 0644);
MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)");
-static int cxgb3_snd_win = 64 * 1024;
+static int cxgb3_snd_win = 128 * 1024;
module_param(cxgb3_snd_win, int, 0644);
-MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=64KB)");
+MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)");
static int cxgb3_rx_credit_thres = 10 * 1024;
module_param(cxgb3_rx_credit_thres, int, 0644);
@@ -301,8 +301,8 @@ static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb,
int flags)
{
- CXGB3_SKB_CB(skb)->seq = c3cn->write_seq;
- CXGB3_SKB_CB(skb)->flags = flags;
+ skb_tcp_seq(skb) = c3cn->write_seq;
+ skb_flags(skb) = flags;
__skb_queue_tail(&c3cn->write_queue, skb);
}
@@ -457,12 +457,9 @@ static unsigned int wrlen __read_mostly;
* The number of WRs needed for an skb depends on the number of fragments
* in the skb and whether it has any payload in its main body. This maps the
* length of the gather list represented by an skb into the # of necessary WRs.
- *
- * The max. length of an skb is controlled by the max pdu size which is ~16K.
- * Also, assume the min. fragment length is the sector size (512), then add
- * extra fragment counts for iscsi bhs and payload padding.
+ * The extra two fragments are for iscsi bhs and payload padding.
*/
-#define SKB_WR_LIST_SIZE (16384/512 + 3)
+#define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2)
static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly;
static void s3_init_wr_tab(unsigned int wr_len)
@@ -485,7 +482,7 @@ static void s3_init_wr_tab(unsigned int wr_len)
static inline void reset_wr_list(struct s3_conn *c3cn)
{
- c3cn->wr_pending_head = NULL;
+ c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL;
}
/*
@@ -496,7 +493,7 @@ static inline void reset_wr_list(struct s3_conn *c3cn)
static inline void enqueue_wr(struct s3_conn *c3cn,
struct sk_buff *skb)
{
- skb_wr_data(skb) = NULL;
+ skb_tx_wr_next(skb) = NULL;
/*
* We want to take an extra reference since both us and the driver
@@ -509,10 +506,22 @@ static inline void enqueue_wr(struct s3_conn *c3cn,
if (!c3cn->wr_pending_head)
c3cn->wr_pending_head = skb;
else
- skb_wr_data(skb) = skb;
+ skb_tx_wr_next(c3cn->wr_pending_tail) = skb;
c3cn->wr_pending_tail = skb;
}
+static int count_pending_wrs(struct s3_conn *c3cn)
+{
+ int n = 0;
+ const struct sk_buff *skb = c3cn->wr_pending_head;
+
+ while (skb) {
+ n += skb->csum;
+ skb = skb_tx_wr_next(skb);
+ }
+ return n;
+}
+
static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn)
{
return c3cn->wr_pending_head;
@@ -529,8 +538,8 @@ static inline struct sk_buff *dequeue_wr(struct s3_conn *c3cn)
if (likely(skb)) {
/* Don't bother clearing the tail */
- c3cn->wr_pending_head = skb_wr_data(skb);
- skb_wr_data(skb) = NULL;
+ c3cn->wr_pending_head = skb_tx_wr_next(skb);
+ skb_tx_wr_next(skb) = NULL;
}
return skb;
}
@@ -543,13 +552,14 @@ static void purge_wr_queue(struct s3_conn *c3cn)
}
static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb,
- int len)
+ int len, int req_completion)
{
struct tx_data_wr *req;
skb_reset_transport_header(skb);
req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req));
- req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
+ req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) |
+ (req_completion ? F_WR_COMPL : 0));
req->wr_lo = htonl(V_WR_TID(c3cn->tid));
req->sndseq = htonl(c3cn->snd_nxt);
/* len includes the length of any HW ULP additions */
@@ -592,7 +602,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
if (unlikely(c3cn->state == C3CN_STATE_CONNECTING ||
c3cn->state == C3CN_STATE_CLOSE_WAIT_1 ||
- c3cn->state == C3CN_STATE_ABORTING)) {
+ c3cn->state >= C3CN_STATE_ABORTING)) {
c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n",
c3cn, c3cn->state);
return 0;
@@ -615,7 +625,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
if (c3cn->wr_avail < wrs_needed) {
c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, "
"wr %d < %u.\n",
- c3cn, skb->len, skb->datalen, frags,
+ c3cn, skb->len, skb->data_len, frags,
wrs_needed, c3cn->wr_avail);
break;
}
@@ -627,20 +637,24 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
c3cn->wr_unacked += wrs_needed;
enqueue_wr(c3cn, skb);
- if (likely(CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_NEED_HDR)) {
- len += ulp_extra_len(skb);
- make_tx_data_wr(c3cn, skb, len);
- c3cn->snd_nxt += len;
- if ((req_completion
- && c3cn->wr_unacked == wrs_needed)
- || (CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_COMPL)
- || c3cn->wr_unacked >= c3cn->wr_max / 2) {
- struct work_request_hdr *wr = cplhdr(skb);
+ c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, "
+ "wr %d, left %u, unack %u.\n",
+ c3cn, skb->len, skb->data_len, frags,
+ wrs_needed, c3cn->wr_avail, c3cn->wr_unacked);
+
- wr->wr_hi |= htonl(F_WR_COMPL);
+ if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) {
+ if ((req_completion &&
+ c3cn->wr_unacked == wrs_needed) ||
+ (skb_flags(skb) & C3CB_FLAG_COMPL) ||
+ c3cn->wr_unacked >= c3cn->wr_max / 2) {
+ req_completion = 1;
c3cn->wr_unacked = 0;
}
- CXGB3_SKB_CB(skb)->flags &= ~C3CB_FLAG_NEED_HDR;
+ len += ulp_extra_len(skb);
+ make_tx_data_wr(c3cn, skb, len, req_completion);
+ c3cn->snd_nxt += len;
+ skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR;
}
total_size += skb->truesize;
@@ -735,8 +749,11 @@ static void process_act_establish(struct s3_conn *c3cn, struct sk_buff *skb)
if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED)))
/* upper layer has requested closing */
send_abort_req(c3cn);
- else if (c3cn_push_tx_frames(c3cn, 1))
+ else {
+ if (skb_queue_len(&c3cn->write_queue))
+ c3cn_push_tx_frames(c3cn, 1);
cxgb3i_conn_tx_open(c3cn);
+ }
}
static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb,
@@ -1082,8 +1099,8 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
return;
}
- CXGB3_SKB_CB(skb)->seq = ntohl(hdr_cpl->seq);
- CXGB3_SKB_CB(skb)->flags = 0;
+ skb_tcp_seq(skb) = ntohl(hdr_cpl->seq);
+ skb_flags(skb) = 0;
skb_reset_transport_header(skb);
__skb_pull(skb, sizeof(struct cpl_iscsi_hdr));
@@ -1103,12 +1120,12 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
goto abort_conn;
skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY;
- skb_ulp_pdulen(skb) = ntohs(ddp_cpl.len);
- skb_ulp_ddigest(skb) = ntohl(ddp_cpl.ulp_crc);
+ skb_rx_pdulen(skb) = ntohs(ddp_cpl.len);
+ skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc);
status = ntohl(ddp_cpl.ddp_status);
c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n",
- skb, skb->len, skb_ulp_pdulen(skb), status);
+ skb, skb->len, skb_rx_pdulen(skb), status);
if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT))
skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR;
@@ -1126,7 +1143,7 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
} else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT))
skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED;
- c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_ulp_pdulen(skb);
+ c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb);
__pskb_trim(skb, len);
__skb_queue_tail(&c3cn->receive_queue, skb);
cxgb3i_conn_pdu_ready(c3cn);
@@ -1151,12 +1168,27 @@ static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx)
* Process an acknowledgment of WR completion. Advance snd_una and send the
* next batch of work requests from the write queue.
*/
+static void check_wr_invariants(struct s3_conn *c3cn)
+{
+ int pending = count_pending_wrs(c3cn);
+
+ if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max))
+ cxgb3i_log_error("TID %u: credit imbalance: avail %u, "
+ "pending %u, total should be %u\n",
+ c3cn->tid, c3cn->wr_avail, pending,
+ c3cn->wr_max);
+}
+
static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
{
struct cpl_wr_ack *hdr = cplhdr(skb);
unsigned int credits = ntohs(hdr->credits);
u32 snd_una = ntohl(hdr->snd_una);
+ c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n",
+ credits, c3cn->wr_avail, c3cn->wr_unacked,
+ c3cn->tid, c3cn->state);
+
c3cn->wr_avail += credits;
if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail)
c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail;
@@ -1171,6 +1203,17 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
break;
}
if (unlikely(credits < p->csum)) {
+ struct tx_data_wr *w = cplhdr(p);
+ cxgb3i_log_error("TID %u got %u WR credits need %u, "
+ "len %u, main body %u, frags %u, "
+ "seq # %u, ACK una %u, ACK nxt %u, "
+ "WR_AVAIL %u, WRs pending %u\n",
+ c3cn->tid, credits, p->csum, p->len,
+ p->len - p->data_len,
+ skb_shinfo(p)->nr_frags,
+ ntohl(w->sndseq), snd_una,
+ ntohl(hdr->snd_nxt), c3cn->wr_avail,
+ count_pending_wrs(c3cn) - credits);
p->csum -= credits;
break;
} else {
@@ -1180,15 +1223,24 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
}
}
- if (unlikely(before(snd_una, c3cn->snd_una)))
+ check_wr_invariants(c3cn);
+
+ if (unlikely(before(snd_una, c3cn->snd_una))) {
+ cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK "
+ "snd_una %u\n",
+ c3cn->tid, snd_una, c3cn->snd_una);
goto out_free;
+ }
if (c3cn->snd_una != snd_una) {
c3cn->snd_una = snd_una;
dst_confirm(c3cn->dst_cache);
}
- if (skb_queue_len(&c3cn->write_queue) && c3cn_push_tx_frames(c3cn, 0))
+ if (skb_queue_len(&c3cn->write_queue)) {
+ if (c3cn_push_tx_frames(c3cn, 0))
+ cxgb3i_conn_tx_open(c3cn);
+ } else
cxgb3i_conn_tx_open(c3cn);
out_free:
__kfree_skb(skb);
@@ -1452,7 +1504,7 @@ static void init_offload_conn(struct s3_conn *c3cn,
struct dst_entry *dst)
{
BUG_ON(c3cn->cdev != cdev);
- c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs;
+ c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1;
c3cn->wr_unacked = 0;
c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst));
@@ -1671,9 +1723,17 @@ int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb)
goto out_err;
}
- err = -EPIPE;
if (c3cn->err) {
c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err);
+ err = -EPIPE;
+ goto out_err;
+ }
+
+ if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) {
+ c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n",
+ c3cn, c3cn->write_seq, c3cn->snd_una,
+ cxgb3_snd_win);
+ err = -EAGAIN;
goto out_err;
}
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h
index d23156907ff..6344b9eb258 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h
@@ -178,25 +178,33 @@ void cxgb3i_c3cn_release(struct s3_conn *);
* @flag: see C3CB_FLAG_* below
* @ulp_mode: ULP mode/submode of sk_buff
* @seq: tcp sequence number
- * @ddigest: pdu data digest
- * @pdulen: recovered pdu length
- * @wr_data: scratch area for tx wr
*/
+struct cxgb3_skb_rx_cb {
+ __u32 ddigest; /* data digest */
+ __u32 pdulen; /* recovered pdu length */
+};
+
+struct cxgb3_skb_tx_cb {
+ struct sk_buff *wr_next; /* next wr */
+};
+
struct cxgb3_skb_cb {
__u8 flags;
__u8 ulp_mode;
__u32 seq;
- __u32 ddigest;
- __u32 pdulen;
- struct sk_buff *wr_data;
+ union {
+ struct cxgb3_skb_rx_cb rx;
+ struct cxgb3_skb_tx_cb tx;
+ };
};
#define CXGB3_SKB_CB(skb) ((struct cxgb3_skb_cb *)&((skb)->cb[0]))
-
+#define skb_flags(skb) (CXGB3_SKB_CB(skb)->flags)
#define skb_ulp_mode(skb) (CXGB3_SKB_CB(skb)->ulp_mode)
-#define skb_ulp_ddigest(skb) (CXGB3_SKB_CB(skb)->ddigest)
-#define skb_ulp_pdulen(skb) (CXGB3_SKB_CB(skb)->pdulen)
-#define skb_wr_data(skb) (CXGB3_SKB_CB(skb)->wr_data)
+#define skb_tcp_seq(skb) (CXGB3_SKB_CB(skb)->seq)
+#define skb_rx_ddigest(skb) (CXGB3_SKB_CB(skb)->rx.ddigest)
+#define skb_rx_pdulen(skb) (CXGB3_SKB_CB(skb)->rx.pdulen)
+#define skb_tx_wr_next(skb) (CXGB3_SKB_CB(skb)->tx.wr_next)
enum c3cb_flags {
C3CB_FLAG_NEED_HDR = 1 << 0, /* packet needs a TX_DATA_WR header */
@@ -217,6 +225,7 @@ struct sge_opaque_hdr {
/* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */
#define TX_HEADER_LEN \
(sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr))
+#define SKB_TX_HEADROOM SKB_MAX_HEAD(TX_HEADER_LEN)
/*
* get and set private ip for iscsi traffic
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
index ce7ce8c6094..17115c230d6 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
@@ -32,6 +32,10 @@
#define cxgb3i_tx_debug(fmt...)
#endif
+/* always allocate rooms for AHS */
+#define SKB_TX_PDU_HEADER_LEN \
+ (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE)
+static unsigned int skb_extra_headroom;
static struct page *pad_page;
/*
@@ -146,12 +150,13 @@ static inline void tx_skb_setmode(struct sk_buff *skb, int hcrc, int dcrc)
void cxgb3i_conn_cleanup_task(struct iscsi_task *task)
{
- struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgb3i_task_data *tdata = task->dd_data +
+ sizeof(struct iscsi_tcp_task);
/* never reached the xmit task callout */
- if (tcp_task->dd_data)
- kfree_skb(tcp_task->dd_data);
- tcp_task->dd_data = NULL;
+ if (tdata->skb)
+ __kfree_skb(tdata->skb);
+ memset(tdata, 0, sizeof(struct cxgb3i_task_data));
/* MNC - Do we need a check in case this is called but
* cxgb3i_conn_alloc_pdu has never been called on the task */
@@ -159,28 +164,102 @@ void cxgb3i_conn_cleanup_task(struct iscsi_task *task)
iscsi_tcp_cleanup_task(task);
}
-/*
- * We do not support ahs yet
- */
+static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt,
+ unsigned int offset, unsigned int *off,
+ struct scatterlist **sgp)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sgl, sg, sgcnt, i) {
+ if (offset < sg->length) {
+ *off = offset;
+ *sgp = sg;
+ return 0;
+ }
+ offset -= sg->length;
+ }
+ return -EFAULT;
+}
+
+static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset,
+ unsigned int dlen, skb_frag_t *frags,
+ int frag_max)
+{
+ unsigned int datalen = dlen;
+ unsigned int sglen = sg->length - sgoffset;
+ struct page *page = sg_page(sg);
+ int i;
+
+ i = 0;
+ do {
+ unsigned int copy;
+
+ if (!sglen) {
+ sg = sg_next(sg);
+ if (!sg) {
+ cxgb3i_log_error("%s, sg NULL, len %u/%u.\n",
+ __func__, datalen, dlen);
+ return -EINVAL;
+ }
+ sgoffset = 0;
+ sglen = sg->length;
+ page = sg_page(sg);
+
+ }
+ copy = min(datalen, sglen);
+ if (i && page == frags[i - 1].page &&
+ sgoffset + sg->offset ==
+ frags[i - 1].page_offset + frags[i - 1].size) {
+ frags[i - 1].size += copy;
+ } else {
+ if (i >= frag_max) {
+ cxgb3i_log_error("%s, too many pages %u, "
+ "dlen %u.\n", __func__,
+ frag_max, dlen);
+ return -EINVAL;
+ }
+
+ frags[i].page = page;
+ frags[i].page_offset = sg->offset + sgoffset;
+ frags[i].size = copy;
+ i++;
+ }
+ datalen -= copy;
+ sgoffset += copy;
+ sglen -= copy;
+ } while (datalen);
+
+ return i;
+}
+
int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
{
+ struct iscsi_conn *conn = task->conn;
struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct sk_buff *skb;
+ struct cxgb3i_task_data *tdata = task->dd_data + sizeof(*tcp_task);
+ struct scsi_cmnd *sc = task->sc;
+ int headroom = SKB_TX_PDU_HEADER_LEN;
+ tcp_task->dd_data = tdata;
task->hdr = NULL;
- /* always allocate rooms for AHS */
- skb = alloc_skb(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE +
- TX_HEADER_LEN, GFP_ATOMIC);
- if (!skb)
+
+ /* write command, need to send data pdus */
+ if (skb_extra_headroom && (opcode == ISCSI_OP_SCSI_DATA_OUT ||
+ (opcode == ISCSI_OP_SCSI_CMD &&
+ (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE))))
+ headroom += min(skb_extra_headroom, conn->max_xmit_dlength);
+
+ tdata->skb = alloc_skb(TX_HEADER_LEN + headroom, GFP_ATOMIC);
+ if (!tdata->skb)
return -ENOMEM;
+ skb_reserve(tdata->skb, TX_HEADER_LEN);
cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n",
- task, opcode, skb);
+ task, opcode, tdata->skb);
- tcp_task->dd_data = skb;
- skb_reserve(skb, TX_HEADER_LEN);
- task->hdr = (struct iscsi_hdr *)skb->data;
- task->hdr_max = sizeof(struct iscsi_hdr);
+ task->hdr = (struct iscsi_hdr *)tdata->skb->data;
+ task->hdr_max = SKB_TX_PDU_HEADER_LEN;
/* data_out uses scsi_cmd's itt */
if (opcode != ISCSI_OP_SCSI_DATA_OUT)
@@ -192,13 +271,13 @@ int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
unsigned int count)
{
- struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct sk_buff *skb = tcp_task->dd_data;
struct iscsi_conn *conn = task->conn;
- struct page *pg;
+ struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgb3i_task_data *tdata = tcp_task->dd_data;
+ struct sk_buff *skb = tdata->skb;
unsigned int datalen = count;
int i, padlen = iscsi_padding(count);
- skb_frag_t *frag;
+ struct page *pg;
cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n",
task, task->sc, offset, count, skb);
@@ -209,90 +288,94 @@ int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
return 0;
if (task->sc) {
- struct scatterlist *sg;
- struct scsi_data_buffer *sdb;
- unsigned int sgoffset = offset;
- struct page *sgpg;
- unsigned int sglen;
-
- sdb = scsi_out(task->sc);
- sg = sdb->table.sgl;
-
- for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) {
- cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n",
- i, sg_page(sg), sg->length, sg->offset);
-
- if (sgoffset < sg->length)
- break;
- sgoffset -= sg->length;
+ struct scsi_data_buffer *sdb = scsi_out(task->sc);
+ struct scatterlist *sg = NULL;
+ int err;
+
+ tdata->offset = offset;
+ tdata->count = count;
+ err = sgl_seek_offset(sdb->table.sgl, sdb->table.nents,
+ tdata->offset, &tdata->sgoffset, &sg);
+ if (err < 0) {
+ cxgb3i_log_warn("tpdu, sgl %u, bad offset %u/%u.\n",
+ sdb->table.nents, tdata->offset,
+ sdb->length);
+ return err;
}
- sgpg = sg_page(sg);
- sglen = sg->length - sgoffset;
-
- do {
- int j = skb_shinfo(skb)->nr_frags;
- unsigned int copy;
-
- if (!sglen) {
- sg = sg_next(sg);
- sgpg = sg_page(sg);
- sgoffset = 0;
- sglen = sg->length;
- ++i;
+ err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count,
+ tdata->frags, MAX_PDU_FRAGS);
+ if (err < 0) {
+ cxgb3i_log_warn("tpdu, sgl %u, bad offset %u + %u.\n",
+ sdb->table.nents, tdata->offset,
+ tdata->count);
+ return err;
+ }
+ tdata->nr_frags = err;
+
+ if (tdata->nr_frags > MAX_SKB_FRAGS ||
+ (padlen && tdata->nr_frags == MAX_SKB_FRAGS)) {
+ char *dst = skb->data + task->hdr_len;
+ skb_frag_t *frag = tdata->frags;
+
+ /* data fits in the skb's headroom */
+ for (i = 0; i < tdata->nr_frags; i++, frag++) {
+ char *src = kmap_atomic(frag->page,
+ KM_SOFTIRQ0);
+
+ memcpy(dst, src+frag->page_offset, frag->size);
+ dst += frag->size;
+ kunmap_atomic(src, KM_SOFTIRQ0);
}
- copy = min(sglen, datalen);
- if (j && skb_can_coalesce(skb, j, sgpg,
- sg->offset + sgoffset)) {
- skb_shinfo(skb)->frags[j - 1].size += copy;
- } else {
- get_page(sgpg);
- skb_fill_page_desc(skb, j, sgpg,
- sg->offset + sgoffset, copy);
+ if (padlen) {
+ memset(dst, 0, padlen);
+ padlen = 0;
}
- sgoffset += copy;
- sglen -= copy;
- datalen -= copy;
- } while (datalen);
+ skb_put(skb, count + padlen);
+ } else {
+ /* data fit into frag_list */
+ for (i = 0; i < tdata->nr_frags; i++)
+ get_page(tdata->frags[i].page);
+
+ memcpy(skb_shinfo(skb)->frags, tdata->frags,
+ sizeof(skb_frag_t) * tdata->nr_frags);
+ skb_shinfo(skb)->nr_frags = tdata->nr_frags;
+ skb->len += count;
+ skb->data_len += count;
+ skb->truesize += count;
+ }
+
} else {
pg = virt_to_page(task->data);
- while (datalen) {
- i = skb_shinfo(skb)->nr_frags;
- frag = &skb_shinfo(skb)->frags[i];
-
- get_page(pg);
- frag->page = pg;
- frag->page_offset = 0;
- frag->size = min((unsigned int)PAGE_SIZE, datalen);
-
- skb_shinfo(skb)->nr_frags++;
- datalen -= frag->size;
- pg++;
- }
+ get_page(pg);
+ skb_fill_page_desc(skb, 0, pg, offset_in_page(task->data),
+ count);
+ skb->len += count;
+ skb->data_len += count;
+ skb->truesize += count;
}
if (padlen) {
i = skb_shinfo(skb)->nr_frags;
- frag = &skb_shinfo(skb)->frags[i];
- frag->page = pad_page;
- frag->page_offset = 0;
- frag->size = padlen;
- skb_shinfo(skb)->nr_frags++;
+ get_page(pad_page);
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, pad_page, 0,
+ padlen);
+
+ skb->data_len += padlen;
+ skb->truesize += padlen;
+ skb->len += padlen;
}
- datalen = count + padlen;
- skb->data_len += datalen;
- skb->truesize += datalen;
- skb->len += datalen;
return 0;
}
int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
{
- struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct sk_buff *skb = tcp_task->dd_data;
struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
struct cxgb3i_conn *cconn = tcp_conn->dd_data;
+ struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgb3i_task_data *tdata = tcp_task->dd_data;
+ struct sk_buff *skb = tdata->skb;
unsigned int datalen;
int err;
@@ -300,13 +383,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
return 0;
datalen = skb->data_len;
- tcp_task->dd_data = NULL;
+ tdata->skb = NULL;
err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb);
- cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
- task, skb, skb->len, skb->data_len, err);
if (err > 0) {
int pdulen = err;
+ cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
+ task, skb, skb->len, skb->data_len, err);
+
if (task->conn->hdrdgst_en)
pdulen += ISCSI_DIGEST_SIZE;
if (datalen && task->conn->datadgst_en)
@@ -325,12 +409,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
return err;
}
/* reset skb to send when we are called again */
- tcp_task->dd_data = skb;
+ tdata->skb = skb;
return -EAGAIN;
}
int cxgb3i_pdu_init(void)
{
+ if (SKB_TX_HEADROOM > (512 * MAX_SKB_FRAGS))
+ skb_extra_headroom = SKB_TX_HEADROOM;
pad_page = alloc_page(GFP_KERNEL);
if (!pad_page)
return -ENOMEM;
@@ -366,7 +452,9 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn)
skb = skb_peek(&c3cn->receive_queue);
while (!err && skb) {
__skb_unlink(skb, &c3cn->receive_queue);
- read += skb_ulp_pdulen(skb);
+ read += skb_rx_pdulen(skb);
+ cxgb3i_rx_debug("conn 0x%p, cn 0x%p, rx skb 0x%p, pdulen %u.\n",
+ conn, c3cn, skb, skb_rx_pdulen(skb));
err = cxgb3i_conn_read_pdu_skb(conn, skb);
__kfree_skb(skb);
skb = skb_peek(&c3cn->receive_queue);
@@ -377,6 +465,11 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn)
cxgb3i_c3cn_rx_credits(c3cn, read);
}
conn->rxdata_octets += read;
+
+ if (err) {
+ cxgb3i_log_info("conn 0x%p rx failed err %d.\n", conn, err);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ }
}
void cxgb3i_conn_tx_open(struct s3_conn *c3cn)
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.h b/drivers/scsi/cxgb3i/cxgb3i_pdu.h
index a3f685cc236..0770b23d90d 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_pdu.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.h
@@ -53,7 +53,7 @@ struct cpl_rx_data_ddp_norss {
#define ULP2_FLAG_DCRC_ERROR 0x20
#define ULP2_FLAG_PAD_ERROR 0x40
-void cxgb3i_conn_closing(struct s3_conn *);
+void cxgb3i_conn_closing(struct s3_conn *c3cn);
void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn);
void cxgb3i_conn_tx_open(struct s3_conn *c3cn);
#endif
diff --git a/drivers/scsi/fcoe/fc_transport_fcoe.c b/drivers/scsi/fcoe/fc_transport_fcoe.c
index bf7fe6fc082..8862758006c 100644
--- a/drivers/scsi/fcoe/fc_transport_fcoe.c
+++ b/drivers/scsi/fcoe/fc_transport_fcoe.c
@@ -33,19 +33,19 @@ static LIST_HEAD(fcoe_transports);
static DEFINE_MUTEX(fcoe_transports_lock);
/**
- * fcoe_transport_default - returns ptr to the default transport fcoe_sw
- **/
+ * fcoe_transport_default() - Returns ptr to the default transport fcoe_sw
+ */
struct fcoe_transport *fcoe_transport_default(void)
{
return &fcoe_sw_transport;
}
/**
- * fcoe_transport_to_pcidev - get the pci dev from a netdev
+ * fcoe_transport_to_pcidev() - get the pci dev from a netdev
* @netdev: the netdev that pci dev will be retrived from
*
* Returns: NULL or the corrsponding pci_dev
- **/
+ */
struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev)
{
if (!netdev->dev.parent)
@@ -54,18 +54,17 @@ struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev)
}
/**
- * fcoe_transport_device_lookup - find out netdev is managed by the
- * transport
- * assign a transport to a device
+ * fcoe_transport_device_lookup() - Lookup a transport
* @netdev: the netdev the transport to be attached to
*
* This will look for existing offload driver, if not found, it falls back to
* the default sw hba (fcoe_sw) as its fcoe transport.
*
* Returns: 0 for success
- **/
-static struct fcoe_transport_internal *fcoe_transport_device_lookup(
- struct fcoe_transport *t, struct net_device *netdev)
+ */
+static struct fcoe_transport_internal *
+fcoe_transport_device_lookup(struct fcoe_transport *t,
+ struct net_device *netdev)
{
struct fcoe_transport_internal *ti;
@@ -81,14 +80,14 @@ static struct fcoe_transport_internal *fcoe_transport_device_lookup(
return NULL;
}
/**
- * fcoe_transport_device_add - assign a transport to a device
+ * fcoe_transport_device_add() - Assign a transport to a device
* @netdev: the netdev the transport to be attached to
*
* This will look for existing offload driver, if not found, it falls back to
* the default sw hba (fcoe_sw) as its fcoe transport.
*
* Returns: 0 for success
- **/
+ */
static int fcoe_transport_device_add(struct fcoe_transport *t,
struct net_device *netdev)
{
@@ -123,14 +122,14 @@ static int fcoe_transport_device_add(struct fcoe_transport *t,
}
/**
- * fcoe_transport_device_remove - remove a device from its transport
+ * fcoe_transport_device_remove() - Remove a device from its transport
* @netdev: the netdev the transport to be attached to
*
- * this removes the device from the transport so the given transport will
+ * This removes the device from the transport so the given transport will
* not manage this device any more
*
* Returns: 0 for success
- **/
+ */
static int fcoe_transport_device_remove(struct fcoe_transport *t,
struct net_device *netdev)
{
@@ -155,13 +154,13 @@ static int fcoe_transport_device_remove(struct fcoe_transport *t,
}
/**
- * fcoe_transport_device_remove_all - remove all from transport devlist
+ * fcoe_transport_device_remove_all() - Remove all from transport devlist
*
- * this removes the device from the transport so the given transport will
+ * This removes the device from the transport so the given transport will
* not manage this device any more
*
* Returns: 0 for success
- **/
+ */
static void fcoe_transport_device_remove_all(struct fcoe_transport *t)
{
struct fcoe_transport_internal *ti, *tmp;
@@ -175,18 +174,18 @@ static void fcoe_transport_device_remove_all(struct fcoe_transport *t)
}
/**
- * fcoe_transport_match - use the bus device match function to match the hw
- * @t: the fcoe transport
- * @netdev:
+ * fcoe_transport_match() - Use the bus device match function to match the hw
+ * @t: The fcoe transport to check
+ * @netdev: The netdev to match against
*
- * This function is used to check if the givne transport wants to manage the
+ * This function is used to check if the given transport wants to manage the
* input netdev. if the transports implements the match function, it will be
* called, o.w. we just compare the pci vendor and device id.
*
* Returns: true for match up
- **/
+ */
static bool fcoe_transport_match(struct fcoe_transport *t,
- struct net_device *netdev)
+ struct net_device *netdev)
{
/* match transport by vendor and device id */
struct pci_dev *pci;
@@ -210,17 +209,17 @@ static bool fcoe_transport_match(struct fcoe_transport *t,
}
/**
- * fcoe_transport_lookup - check if the transport is already registered
+ * fcoe_transport_lookup() - Check if the transport is already registered
* @t: the transport to be looked up
*
* This compares the parent device (pci) vendor and device id
*
* Returns: NULL if not found
*
- * TODO - return default sw transport if no other transport is found
- **/
-static struct fcoe_transport *fcoe_transport_lookup(
- struct net_device *netdev)
+ * TODO: return default sw transport if no other transport is found
+ */
+static struct fcoe_transport *
+fcoe_transport_lookup(struct net_device *netdev)
{
struct fcoe_transport *t;
@@ -239,11 +238,11 @@ static struct fcoe_transport *fcoe_transport_lookup(
}
/**
- * fcoe_transport_register - adds a fcoe transport to the fcoe transports list
+ * fcoe_transport_register() - Adds a fcoe transport to the fcoe transports list
* @t: ptr to the fcoe transport to be added
*
* Returns: 0 for success
- **/
+ */
int fcoe_transport_register(struct fcoe_transport *t)
{
struct fcoe_transport *tt;
@@ -259,9 +258,6 @@ int fcoe_transport_register(struct fcoe_transport *t)
list_add_tail(&t->list, &fcoe_transports);
mutex_unlock(&fcoe_transports_lock);
- mutex_init(&t->devlock);
- INIT_LIST_HEAD(&t->devlist);
-
printk(KERN_DEBUG "fcoe_transport_register:%s\n", t->name);
return 0;
@@ -269,11 +265,11 @@ int fcoe_transport_register(struct fcoe_transport *t)
EXPORT_SYMBOL_GPL(fcoe_transport_register);
/**
- * fcoe_transport_unregister - remove the tranport fro the fcoe transports list
+ * fcoe_transport_unregister() - Remove the tranport fro the fcoe transports list
* @t: ptr to the fcoe transport to be removed
*
* Returns: 0 for success
- **/
+ */
int fcoe_transport_unregister(struct fcoe_transport *t)
{
struct fcoe_transport *tt, *tmp;
@@ -294,8 +290,8 @@ int fcoe_transport_unregister(struct fcoe_transport *t)
}
EXPORT_SYMBOL_GPL(fcoe_transport_unregister);
-/*
- * fcoe_load_transport_driver - load an offload driver by alias name
+/**
+ * fcoe_load_transport_driver() - Load an offload driver by alias name
* @netdev: the target net device
*
* Requests for an offload driver module as the fcoe transport, if fails, it
@@ -307,7 +303,7 @@ EXPORT_SYMBOL_GPL(fcoe_transport_unregister);
* 3. pure hw fcoe hba may not have netdev
*
* Returns: 0 for success
- **/
+ */
int fcoe_load_transport_driver(struct net_device *netdev)
{
struct pci_dev *pci;
@@ -335,14 +331,14 @@ int fcoe_load_transport_driver(struct net_device *netdev)
EXPORT_SYMBOL_GPL(fcoe_load_transport_driver);
/**
- * fcoe_transport_attach - load transport to fcoe
+ * fcoe_transport_attach() - Load transport to fcoe
* @netdev: the netdev the transport to be attached to
*
* This will look for existing offload driver, if not found, it falls back to
* the default sw hba (fcoe_sw) as its fcoe transport.
*
* Returns: 0 for success
- **/
+ */
int fcoe_transport_attach(struct net_device *netdev)
{
struct fcoe_transport *t;
@@ -373,11 +369,11 @@ int fcoe_transport_attach(struct net_device *netdev)
EXPORT_SYMBOL_GPL(fcoe_transport_attach);
/**
- * fcoe_transport_release - unload transport from fcoe
+ * fcoe_transport_release() - Unload transport from fcoe
* @netdev: the net device on which fcoe is to be released
*
* Returns: 0 for success
- **/
+ */
int fcoe_transport_release(struct net_device *netdev)
{
struct fcoe_transport *t;
@@ -410,12 +406,12 @@ int fcoe_transport_release(struct net_device *netdev)
EXPORT_SYMBOL_GPL(fcoe_transport_release);
/**
- * fcoe_transport_init - initializes fcoe transport layer
+ * fcoe_transport_init() - Initializes fcoe transport layer
*
* This prepares for the fcoe transport layer
*
* Returns: none
- **/
+ */
int __init fcoe_transport_init(void)
{
INIT_LIST_HEAD(&fcoe_transports);
@@ -424,12 +420,13 @@ int __init fcoe_transport_init(void)
}
/**
- * fcoe_transport_exit - cleans up the fcoe transport layer
+ * fcoe_transport_exit() - Cleans up the fcoe transport layer
+ *
* This cleans up the fcoe transport layer. removing any transport on the list,
* note that the transport destroy func is not called here.
*
* Returns: none
- **/
+ */
int __exit fcoe_transport_exit(void)
{
struct fcoe_transport *t, *tmp;
diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c
index dc4cd5e2576..da210eba194 100644
--- a/drivers/scsi/fcoe/fcoe_sw.c
+++ b/drivers/scsi/fcoe/fcoe_sw.c
@@ -104,19 +104,19 @@ static struct scsi_host_template fcoe_sw_shost_template = {
.max_sectors = 0xffff,
};
-/*
- * fcoe_sw_lport_config - sets up the fc_lport
+/**
+ * fcoe_sw_lport_config() - sets up the fc_lport
* @lp: ptr to the fc_lport
* @shost: ptr to the parent scsi host
*
* Returns: 0 for success
- *
*/
static int fcoe_sw_lport_config(struct fc_lport *lp)
{
int i = 0;
- lp->link_status = 0;
+ lp->link_up = 0;
+ lp->qfull = 0;
lp->max_retry_count = 3;
lp->e_d_tov = 2 * 1000; /* FC-FS default */
lp->r_a_tov = 2 * 2 * 1000;
@@ -136,16 +136,14 @@ static int fcoe_sw_lport_config(struct fc_lport *lp)
return 0;
}
-/*
- * fcoe_sw_netdev_config - sets up fcoe_softc for lport and network
- * related properties
+/**
+ * fcoe_sw_netdev_config() - Set up netdev for SW FCoE
* @lp : ptr to the fc_lport
* @netdev : ptr to the associated netdevice struct
*
* Must be called after fcoe_sw_lport_config() as it will use lport mutex
*
* Returns : 0 for success
- *
*/
static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
{
@@ -181,9 +179,8 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
if (fc_set_mfs(lp, mfs))
return -EINVAL;
- lp->link_status = ~FC_PAUSE & ~FC_LINK_UP;
if (!fcoe_link_ok(lp))
- lp->link_status |= FC_LINK_UP;
+ lp->link_up = 1;
/* offload features support */
if (fc->real_dev->features & NETIF_F_SG)
@@ -191,6 +188,7 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
skb_queue_head_init(&fc->fcoe_pending_queue);
+ fc->fcoe_pending_queue_active = 0;
/* setup Source Mac Address */
memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr,
@@ -224,16 +222,15 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
return 0;
}
-/*
- * fcoe_sw_shost_config - sets up fc_lport->host
+/**
+ * fcoe_sw_shost_config() - Sets up fc_lport->host
* @lp : ptr to the fc_lport
* @shost : ptr to the associated scsi host
* @dev : device associated to scsi host
*
- * Must be called after fcoe_sw_lport_config) and fcoe_sw_netdev_config()
+ * Must be called after fcoe_sw_lport_config() and fcoe_sw_netdev_config()
*
* Returns : 0 for success
- *
*/
static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
struct device *dev)
@@ -261,8 +258,8 @@ static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
return 0;
}
-/*
- * fcoe_sw_em_config - allocates em for this lport
+/**
+ * fcoe_sw_em_config() - allocates em for this lport
* @lp: the port that em is to allocated for
*
* Returns : 0 on success
@@ -279,8 +276,8 @@ static inline int fcoe_sw_em_config(struct fc_lport *lp)
return 0;
}
-/*
- * fcoe_sw_destroy - FCoE software HBA tear-down function
+/**
+ * fcoe_sw_destroy() - FCoE software HBA tear-down function
* @netdev: ptr to the associated net_device
*
* Returns: 0 if link is OK for use by FCoE.
@@ -301,7 +298,7 @@ static int fcoe_sw_destroy(struct net_device *netdev)
if (!lp)
return -ENODEV;
- fc = fcoe_softc(lp);
+ fc = lport_priv(lp);
/* Logout of the fabric */
fc_fabric_logoff(lp);
@@ -353,8 +350,8 @@ static struct libfc_function_template fcoe_sw_libfc_fcn_templ = {
.frame_send = fcoe_xmit,
};
-/*
- * fcoe_sw_create - this function creates the fcoe interface
+/**
+ * fcoe_sw_create() - this function creates the fcoe interface
* @netdev: pointer the associated netdevice
*
* Creates fc_lport struct and scsi_host for lport, configures lport
@@ -440,8 +437,8 @@ out_host_put:
return rc;
}
-/*
- * fcoe_sw_match - the fcoe sw transport match function
+/**
+ * fcoe_sw_match() - The FCoE SW transport match function
*
* Returns : false always
*/
@@ -461,8 +458,8 @@ struct fcoe_transport fcoe_sw_transport = {
.device = 0xffff,
};
-/*
- * fcoe_sw_init - registers fcoe_sw_transport
+/**
+ * fcoe_sw_init() - Registers fcoe_sw_transport
*
* Returns : 0 on success
*/
@@ -471,17 +468,22 @@ int __init fcoe_sw_init(void)
/* attach to scsi transport */
scsi_transport_fcoe_sw =
fc_attach_transport(&fcoe_sw_transport_function);
+
if (!scsi_transport_fcoe_sw) {
printk(KERN_ERR "fcoe_sw_init:fc_attach_transport() failed\n");
return -ENODEV;
}
+
+ mutex_init(&fcoe_sw_transport.devlock);
+ INIT_LIST_HEAD(&fcoe_sw_transport.devlist);
+
/* register sw transport */
fcoe_transport_register(&fcoe_sw_transport);
return 0;
}
-/*
- * fcoe_sw_exit - unregisters fcoe_sw_transport
+/**
+ * fcoe_sw_exit() - Unregisters fcoe_sw_transport
*
* Returns : 0 on success
*/
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index e419f486cdb..5548bf3bb58 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -49,6 +49,7 @@
static int debug_fcoe;
#define FCOE_MAX_QUEUE_DEPTH 256
+#define FCOE_LOW_QUEUE_DEPTH 32
/* destination address mode */
#define FCOE_GW_ADDR_MODE 0x00
@@ -69,8 +70,6 @@ struct fcoe_percpu_s *fcoe_percpu[NR_CPUS];
/* Function Prototyes */
static int fcoe_check_wait_queue(struct fc_lport *);
-static void fcoe_insert_wait_queue_head(struct fc_lport *, struct sk_buff *);
-static void fcoe_insert_wait_queue(struct fc_lport *, struct sk_buff *);
static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
#ifdef CONFIG_HOTPLUG_CPU
static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
@@ -91,13 +90,13 @@ static struct notifier_block fcoe_cpu_notifier = {
};
/**
- * fcoe_create_percpu_data - creates the associated cpu data
+ * fcoe_create_percpu_data() - creates the associated cpu data
* @cpu: index for the cpu where fcoe cpu data will be created
*
* create percpu stats block, from cpu add notifier
*
* Returns: none
- **/
+ */
static void fcoe_create_percpu_data(int cpu)
{
struct fc_lport *lp;
@@ -115,13 +114,13 @@ static void fcoe_create_percpu_data(int cpu)
}
/**
- * fcoe_destroy_percpu_data - destroys the associated cpu data
+ * fcoe_destroy_percpu_data() - destroys the associated cpu data
* @cpu: index for the cpu where fcoe cpu data will destroyed
*
* destroy percpu stats block called by cpu add/remove notifier
*
* Retuns: none
- **/
+ */
static void fcoe_destroy_percpu_data(int cpu)
{
struct fc_lport *lp;
@@ -137,7 +136,7 @@ static void fcoe_destroy_percpu_data(int cpu)
}
/**
- * fcoe_cpu_callback - fcoe cpu hotplug event callback
+ * fcoe_cpu_callback() - fcoe cpu hotplug event callback
* @nfb: callback data block
* @action: event triggering the callback
* @hcpu: index for the cpu of this event
@@ -145,7 +144,7 @@ static void fcoe_destroy_percpu_data(int cpu)
* this creates or destroys per cpu data for fcoe
*
* Returns NOTIFY_OK always.
- **/
+ */
static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
void *hcpu)
{
@@ -166,7 +165,7 @@ static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
#endif /* CONFIG_HOTPLUG_CPU */
/**
- * fcoe_rcv - this is the fcoe receive function called by NET_RX_SOFTIRQ
+ * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
* @skb: the receive skb
* @dev: associated net device
* @ptype: context
@@ -175,7 +174,7 @@ static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
* this function will receive the packet and build fc frame and pass it up
*
* Returns: 0 for success
- **/
+ */
int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *olddev)
{
@@ -265,11 +264,11 @@ err2:
EXPORT_SYMBOL_GPL(fcoe_rcv);
/**
- * fcoe_start_io - pass to netdev to start xmit for fcoe
+ * fcoe_start_io() - pass to netdev to start xmit for fcoe
* @skb: the skb to be xmitted
*
* Returns: 0 for success
- **/
+ */
static inline int fcoe_start_io(struct sk_buff *skb)
{
int rc;
@@ -283,12 +282,12 @@ static inline int fcoe_start_io(struct sk_buff *skb)
}
/**
- * fcoe_get_paged_crc_eof - in case we need alloc a page for crc_eof
+ * fcoe_get_paged_crc_eof() - in case we need alloc a page for crc_eof
* @skb: the skb to be xmitted
* @tlen: total len
*
* Returns: 0 for success
- **/
+ */
static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
{
struct fcoe_percpu_s *fps;
@@ -326,13 +325,12 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
}
/**
- * fcoe_fc_crc - calculates FC CRC in this fcoe skb
+ * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
* @fp: the fc_frame containg data to be checksummed
*
* This uses crc32() to calculate the crc for fc frame
* Return : 32 bit crc
- *
- **/
+ */
u32 fcoe_fc_crc(struct fc_frame *fp)
{
struct sk_buff *skb = fp_skb(fp);
@@ -363,13 +361,12 @@ u32 fcoe_fc_crc(struct fc_frame *fp)
EXPORT_SYMBOL_GPL(fcoe_fc_crc);
/**
- * fcoe_xmit - FCoE frame transmit function
+ * fcoe_xmit() - FCoE frame transmit function
* @lp: the associated local port
* @fp: the fc_frame to be transmitted
*
* Return : 0 for success
- *
- **/
+ */
int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
{
int wlen, rc = 0;
@@ -389,7 +386,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
- fc = fcoe_softc(lp);
+ fc = lport_priv(lp);
/*
* if it is a flogi then we need to learn gw-addr
* and my own fcid
@@ -439,7 +436,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
if (skb_is_nonlinear(skb)) {
skb_frag_t *frag;
if (fcoe_get_paged_crc_eof(skb, tlen)) {
- kfree(skb);
+ kfree_skb(skb);
return -ENOMEM;
}
frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
@@ -502,21 +499,22 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
rc = fcoe_start_io(skb);
if (rc) {
- fcoe_insert_wait_queue(lp, skb);
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ __skb_queue_tail(&fc->fcoe_pending_queue, skb);
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
- fc_pause(lp);
+ lp->qfull = 1;
}
return 0;
}
EXPORT_SYMBOL_GPL(fcoe_xmit);
-/*
- * fcoe_percpu_receive_thread - recv thread per cpu
+/**
+ * fcoe_percpu_receive_thread() - recv thread per cpu
* @arg: ptr to the fcoe per cpu struct
*
* Return: 0 for success
- *
*/
int fcoe_percpu_receive_thread(void *arg)
{
@@ -533,7 +531,7 @@ int fcoe_percpu_receive_thread(void *arg)
struct fcoe_softc *fc;
struct fcoe_hdr *hp;
- set_user_nice(current, 19);
+ set_user_nice(current, -20);
while (!kthread_should_stop()) {
@@ -658,7 +656,7 @@ int fcoe_percpu_receive_thread(void *arg)
}
/**
- * fcoe_recv_flogi - flogi receive function
+ * fcoe_recv_flogi() - flogi receive function
* @fc: associated fcoe_softc
* @fp: the recieved frame
* @sa: the source address of this flogi
@@ -667,7 +665,7 @@ int fcoe_percpu_receive_thread(void *arg)
* mac address for the initiator, eitehr OUI based or GW based.
*
* Returns: none
- **/
+ */
static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
{
struct fc_frame_header *fh;
@@ -715,32 +713,23 @@ static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
}
/**
- * fcoe_watchdog - fcoe timer callback
+ * fcoe_watchdog() - fcoe timer callback
* @vp:
*
- * This checks the pending queue length for fcoe and put fcoe to be paused state
+ * This checks the pending queue length for fcoe and set lport qfull
* if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the
* fcoe_hostlist.
*
* Returns: 0 for success
- **/
+ */
void fcoe_watchdog(ulong vp)
{
- struct fc_lport *lp;
struct fcoe_softc *fc;
- int paused = 0;
read_lock(&fcoe_hostlist_lock);
list_for_each_entry(fc, &fcoe_hostlist, list) {
- lp = fc->lp;
- if (lp) {
- if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
- paused = 1;
- if (fcoe_check_wait_queue(lp) < FCOE_MAX_QUEUE_DEPTH) {
- if (paused)
- fc_unpause(lp);
- }
- }
+ if (fc->lp)
+ fcoe_check_wait_queue(fc->lp);
}
read_unlock(&fcoe_hostlist_lock);
@@ -750,96 +739,64 @@ void fcoe_watchdog(ulong vp)
/**
- * fcoe_check_wait_queue - put the skb into fcoe pending xmit queue
+ * fcoe_check_wait_queue() - put the skb into fcoe pending xmit queue
* @lp: the fc_port for this skb
* @skb: the associated skb to be xmitted
*
* This empties the wait_queue, dequeue the head of the wait_queue queue
* and calls fcoe_start_io() for each packet, if all skb have been
- * transmitted, return 0 if a error occurs, then restore wait_queue and
- * try again later.
+ * transmitted, return qlen or -1 if a error occurs, then restore
+ * wait_queue and try again later.
*
* The wait_queue is used when the skb transmit fails. skb will go
* in the wait_queue which will be emptied by the time function OR
* by the next skb transmit.
*
* Returns: 0 for success
- **/
+ */
static int fcoe_check_wait_queue(struct fc_lport *lp)
{
- int rc, unpause = 0;
- int paused = 0;
+ struct fcoe_softc *fc = lport_priv(lp);
struct sk_buff *skb;
- struct fcoe_softc *fc;
+ int rc = -1;
- fc = fcoe_softc(lp);
spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ if (fc->fcoe_pending_queue_active)
+ goto out;
+ fc->fcoe_pending_queue_active = 1;
- /*
- * is this interface paused?
- */
- if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
- paused = 1;
- if (fc->fcoe_pending_queue.qlen) {
- while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- rc = fcoe_start_io(skb);
- if (rc) {
- fcoe_insert_wait_queue_head(lp, skb);
- return rc;
- }
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- }
- if (fc->fcoe_pending_queue.qlen < FCOE_MAX_QUEUE_DEPTH)
- unpause = 1;
- }
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- if ((unpause) && (paused))
- fc_unpause(lp);
- return fc->fcoe_pending_queue.qlen;
-}
-
-/**
- * fcoe_insert_wait_queue_head - puts skb to fcoe pending queue head
- * @lp: the fc_port for this skb
- * @skb: the associated skb to be xmitted
- *
- * Returns: none
- **/
-static void fcoe_insert_wait_queue_head(struct fc_lport *lp,
- struct sk_buff *skb)
-{
- struct fcoe_softc *fc;
+ while (fc->fcoe_pending_queue.qlen) {
+ /* keep qlen > 0 until fcoe_start_io succeeds */
+ fc->fcoe_pending_queue.qlen++;
+ skb = __skb_dequeue(&fc->fcoe_pending_queue);
- fc = fcoe_softc(lp);
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- __skb_queue_head(&fc->fcoe_pending_queue, skb);
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
-}
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ rc = fcoe_start_io(skb);
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
-/**
- * fcoe_insert_wait_queue - put the skb into fcoe pending queue tail
- * @lp: the fc_port for this skb
- * @skb: the associated skb to be xmitted
- *
- * Returns: none
- **/
-static void fcoe_insert_wait_queue(struct fc_lport *lp,
- struct sk_buff *skb)
-{
- struct fcoe_softc *fc;
+ if (rc) {
+ __skb_queue_head(&fc->fcoe_pending_queue, skb);
+ /* undo temporary increment above */
+ fc->fcoe_pending_queue.qlen--;
+ break;
+ }
+ /* undo temporary increment above */
+ fc->fcoe_pending_queue.qlen--;
+ }
- fc = fcoe_softc(lp);
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- __skb_queue_tail(&fc->fcoe_pending_queue, skb);
+ if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
+ lp->qfull = 0;
+ fc->fcoe_pending_queue_active = 0;
+ rc = fc->fcoe_pending_queue.qlen;
+out:
spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ return rc;
}
/**
- * fcoe_dev_setup - setup link change notification interface
- *
- **/
-static void fcoe_dev_setup(void)
+ * fcoe_dev_setup() - setup link change notification interface
+ */
+static void fcoe_dev_setup()
{
/*
* here setup a interface specific wd time to
@@ -849,15 +806,15 @@ static void fcoe_dev_setup(void)
}
/**
- * fcoe_dev_setup - cleanup link change notification interface
- **/
+ * fcoe_dev_setup() - cleanup link change notification interface
+ */
static void fcoe_dev_cleanup(void)
{
unregister_netdevice_notifier(&fcoe_notifier);
}
/**
- * fcoe_device_notification - netdev event notification callback
+ * fcoe_device_notification() - netdev event notification callback
* @notifier: context of the notification
* @event: type of event
* @ptr: fixed array for output parsed ifname
@@ -865,7 +822,7 @@ static void fcoe_dev_cleanup(void)
* This function is called by the ethernet driver in case of link change event
*
* Returns: 0 for success
- **/
+ */
static int fcoe_device_notification(struct notifier_block *notifier,
ulong event, void *ptr)
{
@@ -873,7 +830,7 @@ static int fcoe_device_notification(struct notifier_block *notifier,
struct net_device *real_dev = ptr;
struct fcoe_softc *fc;
struct fcoe_dev_stats *stats;
- u16 new_status;
+ u32 new_link_up;
u32 mfs;
int rc = NOTIFY_OK;
@@ -890,17 +847,15 @@ static int fcoe_device_notification(struct notifier_block *notifier,
goto out;
}
- new_status = lp->link_status;
+ new_link_up = lp->link_up;
switch (event) {
case NETDEV_DOWN:
case NETDEV_GOING_DOWN:
- new_status &= ~FC_LINK_UP;
+ new_link_up = 0;
break;
case NETDEV_UP:
case NETDEV_CHANGE:
- new_status &= ~FC_LINK_UP;
- if (!fcoe_link_ok(lp))
- new_status |= FC_LINK_UP;
+ new_link_up = !fcoe_link_ok(lp);
break;
case NETDEV_CHANGEMTU:
mfs = fc->real_dev->mtu -
@@ -908,17 +863,15 @@ static int fcoe_device_notification(struct notifier_block *notifier,
sizeof(struct fcoe_crc_eof));
if (mfs >= FC_MIN_MAX_FRAME)
fc_set_mfs(lp, mfs);
- new_status &= ~FC_LINK_UP;
- if (!fcoe_link_ok(lp))
- new_status |= FC_LINK_UP;
+ new_link_up = !fcoe_link_ok(lp);
break;
case NETDEV_REGISTER:
break;
default:
FC_DBG("unknown event %ld call", event);
}
- if (lp->link_status != new_status) {
- if ((new_status & FC_LINK_UP) == FC_LINK_UP)
+ if (lp->link_up != new_link_up) {
+ if (new_link_up)
fc_linkup(lp);
else {
stats = lp->dev_stats[smp_processor_id()];
@@ -933,12 +886,12 @@ out:
}
/**
- * fcoe_if_to_netdev - parse a name buffer to get netdev
+ * fcoe_if_to_netdev() - parse a name buffer to get netdev
* @ifname: fixed array for output parsed ifname
* @buffer: incoming buffer to be copied
*
* Returns: NULL or ptr to netdeive
- **/
+ */
static struct net_device *fcoe_if_to_netdev(const char *buffer)
{
char *cp;
@@ -955,13 +908,13 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer)
}
/**
- * fcoe_netdev_to_module_owner - finds out the nic drive moddule of the netdev
+ * fcoe_netdev_to_module_owner() - finds out the nic drive moddule of the netdev
* @netdev: the target netdev
*
* Returns: ptr to the struct module, NULL for failure
- **/
-static struct module *fcoe_netdev_to_module_owner(
- const struct net_device *netdev)
+ */
+static struct module *
+fcoe_netdev_to_module_owner(const struct net_device *netdev)
{
struct device *dev;
@@ -979,12 +932,14 @@ static struct module *fcoe_netdev_to_module_owner(
}
/**
- * fcoe_ethdrv_get - holds the nic driver module by try_module_get() for
- * the corresponding netdev.
+ * fcoe_ethdrv_get() - Hold the Ethernet driver
* @netdev: the target netdev
*
+ * Holds the Ethernet driver module by try_module_get() for
+ * the corresponding netdev.
+ *
* Returns: 0 for succsss
- **/
+ */
static int fcoe_ethdrv_get(const struct net_device *netdev)
{
struct module *owner;
@@ -999,12 +954,14 @@ static int fcoe_ethdrv_get(const struct net_device *netdev)
}
/**
- * fcoe_ethdrv_get - releases the nic driver module by module_put for
- * the corresponding netdev.
+ * fcoe_ethdrv_put() - Release the Ethernet driver
* @netdev: the target netdev
*
+ * Releases the Ethernet driver module by module_put for
+ * the corresponding netdev.
+ *
* Returns: 0 for succsss
- **/
+ */
static int fcoe_ethdrv_put(const struct net_device *netdev)
{
struct module *owner;
@@ -1020,12 +977,12 @@ static int fcoe_ethdrv_put(const struct net_device *netdev)
}
/**
- * fcoe_destroy- handles the destroy from sysfs
+ * fcoe_destroy() - handles the destroy from sysfs
* @buffer: expcted to be a eth if name
* @kp: associated kernel param
*
* Returns: 0 for success
- **/
+ */
static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
{
int rc;
@@ -1058,12 +1015,12 @@ out_nodev:
}
/**
- * fcoe_create - handles the create call from sysfs
+ * fcoe_create() - Handles the create call from sysfs
* @buffer: expcted to be a eth if name
* @kp: associated kernel param
*
* Returns: 0 for success
- **/
+ */
static int fcoe_create(const char *buffer, struct kernel_param *kp)
{
int rc;
@@ -1104,8 +1061,8 @@ module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
__MODULE_PARM_TYPE(destroy, "string");
MODULE_PARM_DESC(destroy, "Destroy fcoe port");
-/*
- * fcoe_link_ok - check if link is ok for the fc_lport
+/**
+ * fcoe_link_ok() - Check if link is ok for the fc_lport
* @lp: ptr to the fc_lport
*
* Any permanently-disqualifying conditions have been previously checked.
@@ -1120,7 +1077,7 @@ MODULE_PARM_DESC(destroy, "Destroy fcoe port");
*/
int fcoe_link_ok(struct fc_lport *lp)
{
- struct fcoe_softc *fc = fcoe_softc(lp);
+ struct fcoe_softc *fc = lport_priv(lp);
struct net_device *dev = fc->real_dev;
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
int rc = 0;
@@ -1149,9 +1106,8 @@ int fcoe_link_ok(struct fc_lport *lp)
}
EXPORT_SYMBOL_GPL(fcoe_link_ok);
-/*
- * fcoe_percpu_clean - frees skb of the corresponding lport from the per
- * cpu queue.
+/**
+ * fcoe_percpu_clean() - Clear the pending skbs for an lport
* @lp: the fc_lport
*/
void fcoe_percpu_clean(struct fc_lport *lp)
@@ -1185,11 +1141,11 @@ void fcoe_percpu_clean(struct fc_lport *lp)
EXPORT_SYMBOL_GPL(fcoe_percpu_clean);
/**
- * fcoe_clean_pending_queue - dequeue skb and free it
+ * fcoe_clean_pending_queue() - Dequeue a skb and free it
* @lp: the corresponding fc_lport
*
* Returns: none
- **/
+ */
void fcoe_clean_pending_queue(struct fc_lport *lp)
{
struct fcoe_softc *fc = lport_priv(lp);
@@ -1206,21 +1162,21 @@ void fcoe_clean_pending_queue(struct fc_lport *lp)
EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
/**
- * libfc_host_alloc - allocate a Scsi_Host with room for the fc_lport
+ * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport
* @sht: ptr to the scsi host templ
* @priv_size: size of private data after fc_lport
*
* Returns: ptr to Scsi_Host
- * TODO - to libfc?
+ * TODO: to libfc?
*/
-static inline struct Scsi_Host *libfc_host_alloc(
- struct scsi_host_template *sht, int priv_size)
+static inline struct Scsi_Host *
+libfc_host_alloc(struct scsi_host_template *sht, int priv_size)
{
return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size);
}
/**
- * fcoe_host_alloc - allocate a Scsi_Host with room for the fcoe_softc
+ * fcoe_host_alloc() - Allocate a Scsi_Host with room for the fcoe_softc
* @sht: ptr to the scsi host templ
* @priv_size: size of private data after fc_lport
*
@@ -1232,8 +1188,8 @@ struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *sht, int priv_size)
}
EXPORT_SYMBOL_GPL(fcoe_host_alloc);
-/*
- * fcoe_reset - resets the fcoe
+/**
+ * fcoe_reset() - Resets the fcoe
* @shost: shost the reset is from
*
* Returns: always 0
@@ -1246,8 +1202,8 @@ int fcoe_reset(struct Scsi_Host *shost)
}
EXPORT_SYMBOL_GPL(fcoe_reset);
-/*
- * fcoe_wwn_from_mac - converts 48-bit IEEE MAC address to 64-bit FC WWN.
+/**
+ * fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN.
* @mac: mac address
* @scheme: check port
* @port: port indicator for converting
@@ -1286,14 +1242,15 @@ u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
return wwn;
}
EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
-/*
- * fcoe_hostlist_lookup_softc - find the corresponding lport by a given device
+
+/**
+ * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device
* @device: this is currently ptr to net_device
*
* Returns: NULL or the located fcoe_softc
*/
-static struct fcoe_softc *fcoe_hostlist_lookup_softc(
- const struct net_device *dev)
+static struct fcoe_softc *
+fcoe_hostlist_lookup_softc(const struct net_device *dev)
{
struct fcoe_softc *fc;
@@ -1308,8 +1265,8 @@ static struct fcoe_softc *fcoe_hostlist_lookup_softc(
return NULL;
}
-/*
- * fcoe_hostlist_lookup - find the corresponding lport by netdev
+/**
+ * fcoe_hostlist_lookup() - Find the corresponding lport by netdev
* @netdev: ptr to net_device
*
* Returns: 0 for success
@@ -1324,8 +1281,8 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
}
EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup);
-/*
- * fcoe_hostlist_add - add a lport to lports list
+/**
+ * fcoe_hostlist_add() - Add a lport to lports list
* @lp: ptr to the fc_lport to badded
*
* Returns: 0 for success
@@ -1336,7 +1293,7 @@ int fcoe_hostlist_add(const struct fc_lport *lp)
fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
if (!fc) {
- fc = fcoe_softc(lp);
+ fc = lport_priv(lp);
write_lock_bh(&fcoe_hostlist_lock);
list_add_tail(&fc->list, &fcoe_hostlist);
write_unlock_bh(&fcoe_hostlist_lock);
@@ -1345,8 +1302,8 @@ int fcoe_hostlist_add(const struct fc_lport *lp)
}
EXPORT_SYMBOL_GPL(fcoe_hostlist_add);
-/*
- * fcoe_hostlist_remove - remove a lport from lports list
+/**
+ * fcoe_hostlist_remove() - remove a lport from lports list
* @lp: ptr to the fc_lport to badded
*
* Returns: 0 for success
@@ -1366,12 +1323,12 @@ int fcoe_hostlist_remove(const struct fc_lport *lp)
EXPORT_SYMBOL_GPL(fcoe_hostlist_remove);
/**
- * fcoe_libfc_config - sets up libfc related properties for lport
+ * fcoe_libfc_config() - sets up libfc related properties for lport
* @lp: ptr to the fc_lport
* @tt: libfc function template
*
* Returns : 0 for success
- **/
+ */
int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
{
/* Set the function pointers set by the LLDD */
@@ -1389,14 +1346,14 @@ int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
EXPORT_SYMBOL_GPL(fcoe_libfc_config);
/**
- * fcoe_init - fcoe module loading initialization
+ * fcoe_init() - fcoe module loading initialization
*
* Initialization routine
* 1. Will create fc transport software structure
* 2. initialize the link list of port information structure
*
* Returns 0 on success, negative on failure
- **/
+ */
static int __init fcoe_init(void)
{
int cpu;
@@ -1433,7 +1390,6 @@ static int __init fcoe_init(void)
} else {
fcoe_percpu[cpu] = NULL;
kfree(p);
-
}
}
}
@@ -1443,11 +1399,9 @@ static int __init fcoe_init(void)
*/
fcoe_dev_setup();
- init_timer(&fcoe_timer);
- fcoe_timer.data = 0;
- fcoe_timer.function = fcoe_watchdog;
- fcoe_timer.expires = (jiffies + (10 * HZ));
- add_timer(&fcoe_timer);
+ setup_timer(&fcoe_timer, fcoe_watchdog, 0);
+
+ mod_timer(&fcoe_timer, jiffies + (10 * HZ));
/* initiatlize the fcoe transport */
fcoe_transport_init();
@@ -1459,10 +1413,10 @@ static int __init fcoe_init(void)
module_init(fcoe_init);
/**
- * fcoe_exit - fcoe module unloading cleanup
+ * fcoe_exit() - fcoe module unloading cleanup
*
* Returns 0 on success, negative on failure
- **/
+ */
static void __exit fcoe_exit(void)
{
u32 idx;
@@ -1483,7 +1437,7 @@ static void __exit fcoe_exit(void)
*/
del_timer_sync(&fcoe_timer);
- /* releases the assocaited fcoe transport for each lport */
+ /* releases the associated fcoe transport for each lport */
list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
fcoe_transport_release(fc->real_dev);
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index a48e4990fe1..34be88d7afa 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -1251,6 +1251,7 @@ static struct pci_device_id hptiop_id_table[] = {
{ PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops },
+ { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops },
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index ee0739b217b..ed1e728763a 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -933,7 +933,7 @@ static void ibmvfc_get_host_speed(struct Scsi_Host *shost)
fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
break;
default:
- ibmvfc_log(vhost, 3, "Unknown port speed: %ld Gbit\n",
+ ibmvfc_log(vhost, 3, "Unknown port speed: %lld Gbit\n",
vhost->login_buf->resp.link_speed / 100);
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break;
@@ -1322,7 +1322,9 @@ static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd,
&evt->ext_list_token);
if (!evt->ext_list) {
- scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
+ scsi_dma_unmap(scmd);
+ if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
+ scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
return -ENOMEM;
}
}
@@ -1571,9 +1573,6 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
vfc_cmd->resp_len = sizeof(vfc_cmd->rsp);
vfc_cmd->cancel_key = (unsigned long)cmnd->device->hostdata;
vfc_cmd->tgt_scsi_id = rport->port_id;
- if ((rport->supported_classes & FC_COS_CLASS3) &&
- (fc_host_supported_classes(vhost->host) & FC_COS_CLASS3))
- vfc_cmd->flags = IBMVFC_CLASS_3_ERR;
vfc_cmd->iu.xfer_len = scsi_bufflen(cmnd);
int_to_scsilun(cmnd->device->lun, &vfc_cmd->iu.lun);
memcpy(vfc_cmd->iu.cdb, cmnd->cmnd, cmnd->cmd_len);
@@ -2149,8 +2148,8 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
{
const char *desc = ibmvfc_get_ae_desc(crq->event);
- ibmvfc_log(vhost, 3, "%s event received. scsi_id: %lx, wwpn: %lx,"
- " node_name: %lx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name);
+ ibmvfc_log(vhost, 3, "%s event received. scsi_id: %llx, wwpn: %llx,"
+ " node_name: %llx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name);
switch (crq->event) {
case IBMVFC_AE_LINK_UP:
@@ -2184,7 +2183,7 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
ibmvfc_link_down(vhost, IBMVFC_HALTED);
break;
default:
- dev_err(vhost->dev, "Unknown async event received: %ld\n", crq->event);
+ dev_err(vhost->dev, "Unknown async event received: %lld\n", crq->event);
break;
};
}
@@ -2261,13 +2260,13 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost)
* actually sent
*/
if (unlikely(!ibmvfc_valid_event(&vhost->pool, evt))) {
- dev_err(vhost->dev, "Returned correlation_token 0x%08lx is invalid!\n",
+ dev_err(vhost->dev, "Returned correlation_token 0x%08llx is invalid!\n",
crq->ioba);
return;
}
if (unlikely(atomic_read(&evt->free))) {
- dev_err(vhost->dev, "Received duplicate correlation_token 0x%08lx!\n",
+ dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n",
crq->ioba);
return;
}
@@ -3259,11 +3258,12 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id)
tgt = mempool_alloc(vhost->tgt_pool, GFP_KERNEL);
if (!tgt) {
- dev_err(vhost->dev, "Target allocation failure for scsi id %08lx\n",
+ dev_err(vhost->dev, "Target allocation failure for scsi id %08llx\n",
scsi_id);
return -ENOMEM;
}
+ memset(tgt, 0, sizeof(*tgt));
tgt->scsi_id = scsi_id;
tgt->new_scsi_id = scsi_id;
tgt->vhost = vhost;
@@ -3574,9 +3574,18 @@ static void ibmvfc_log_ae(struct ibmvfc_host *vhost, int events)
static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt)
{
struct ibmvfc_host *vhost = tgt->vhost;
- struct fc_rport *rport;
+ struct fc_rport *rport = tgt->rport;
unsigned long flags;
+ if (rport) {
+ tgt_dbg(tgt, "Setting rport roles\n");
+ fc_remote_port_rolechg(rport, tgt->ids.roles);
+ spin_lock_irqsave(vhost->host->host_lock, flags);
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+ return;
+ }
+
tgt_dbg(tgt, "Adding rport\n");
rport = fc_remote_port_add(vhost->host, 0, &tgt->ids);
spin_lock_irqsave(vhost->host->host_lock, flags);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index babdf3db59d..b21e071b986 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -32,7 +32,7 @@
#define IBMVFC_DRIVER_VERSION "1.0.4"
#define IBMVFC_DRIVER_DATE "(November 14, 2008)"
-#define IBMVFC_DEFAULT_TIMEOUT 15
+#define IBMVFC_DEFAULT_TIMEOUT 60
#define IBMVFC_INIT_TIMEOUT 120
#define IBMVFC_MAX_REQUESTS_DEFAULT 100
@@ -691,13 +691,13 @@ struct ibmvfc_host {
#define DBG_CMD(CMD) do { if (ibmvfc_debug) CMD; } while (0)
#define tgt_dbg(t, fmt, ...) \
- DBG_CMD(dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__))
+ DBG_CMD(dev_info((t)->vhost->dev, "%llX: " fmt, (t)->scsi_id, ##__VA_ARGS__))
#define tgt_info(t, fmt, ...) \
- dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__)
+ dev_info((t)->vhost->dev, "%llX: " fmt, (t)->scsi_id, ##__VA_ARGS__)
#define tgt_err(t, fmt, ...) \
- dev_err((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__)
+ dev_err((t)->vhost->dev, "%llX: " fmt, (t)->scsi_id, ##__VA_ARGS__)
#define ibmvfc_dbg(vhost, ...) \
DBG_CMD(dev_info((vhost)->dev, ##__VA_ARGS__))
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 74d07d137da..c9aa7611e40 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -432,6 +432,7 @@ static int map_sg_data(struct scsi_cmnd *cmd,
sdev_printk(KERN_ERR, cmd->device,
"Can't allocate memory "
"for indirect table\n");
+ scsi_dma_unmap(cmd);
return 0;
}
}
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 841f460edbc..07829009a8b 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4912,7 +4912,7 @@ static int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
if (res && ipr_is_gata(res)) {
if (cmd == HDIO_GET_IDENTITY)
return -ENOTTY;
- return ata_scsi_ioctl(sdev, cmd, arg);
+ return ata_sas_scsi_ioctl(res->sata_port->ap, sdev, cmd, arg);
}
return -EINVAL;
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index 4a4e6954ec7..f23c4ca9a2e 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -103,7 +103,7 @@ lasi700_probe(struct parisc_device *dev)
hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL);
if (!hostdata) {
- dev_printk(KERN_ERR, dev, "Failed to allocate host data\n");
+ dev_printk(KERN_ERR, &dev->dev, "Failed to allocate host data\n");
return -ENOMEM;
}
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index dd1564c9e04..e57556ea5b4 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -64,7 +64,7 @@ static void fc_disc_single(struct fc_disc *, struct fc_disc_port *);
static void fc_disc_restart(struct fc_disc *);
/**
- * fc_disc_lookup_rport - lookup a remote port by port_id
+ * fc_disc_lookup_rport() - lookup a remote port by port_id
* @lport: Fibre Channel host port instance
* @port_id: remote port port_id to match
*/
@@ -92,7 +92,7 @@ struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport,
}
/**
- * fc_disc_stop_rports - delete all the remote ports associated with the lport
+ * fc_disc_stop_rports() - delete all the remote ports associated with the lport
* @disc: The discovery job to stop rports on
*
* Locking Note: This function expects that the lport mutex is locked before
@@ -117,7 +117,7 @@ void fc_disc_stop_rports(struct fc_disc *disc)
}
/**
- * fc_disc_rport_callback - Event handler for rport events
+ * fc_disc_rport_callback() - Event handler for rport events
* @lport: The lport which is receiving the event
* @rport: The rport which the event has occured on
* @event: The event that occured
@@ -151,7 +151,7 @@ static void fc_disc_rport_callback(struct fc_lport *lport,
}
/**
- * fc_disc_recv_rscn_req - Handle Registered State Change Notification (RSCN)
+ * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN)
* @sp: Current sequence of the RSCN exchange
* @fp: RSCN Frame
* @lport: Fibre Channel host port instance
@@ -246,7 +246,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
list_del(&dp->peers);
rport = lport->tt.rport_lookup(lport, dp->ids.port_id);
if (rport) {
- rdata = RPORT_TO_PRIV(rport);
+ rdata = rport->dd_data;
list_del(&rdata->peers);
lport->tt.rport_logoff(rport);
}
@@ -265,7 +265,7 @@ reject:
}
/**
- * fc_disc_recv_req - Handle incoming requests
+ * fc_disc_recv_req() - Handle incoming requests
* @sp: Current sequence of the request exchange
* @fp: The frame
* @lport: The FC local port
@@ -294,7 +294,7 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp,
}
/**
- * fc_disc_restart - Restart discovery
+ * fc_disc_restart() - Restart discovery
* @lport: FC discovery context
*
* Locking Note: This function expects that the disc mutex
@@ -322,7 +322,7 @@ static void fc_disc_restart(struct fc_disc *disc)
}
/**
- * fc_disc_start - Fibre Channel Target discovery
+ * fc_disc_start() - Fibre Channel Target discovery
* @lport: FC local port
*
* Returns non-zero if discovery cannot be started.
@@ -383,7 +383,7 @@ static struct fc_rport_operations fc_disc_rport_ops = {
};
/**
- * fc_disc_new_target - Handle new target found by discovery
+ * fc_disc_new_target() - Handle new target found by discovery
* @lport: FC local port
* @rport: The previous FC remote port (NULL if new remote port)
* @ids: Identifiers for the new FC remote port
@@ -396,7 +396,7 @@ static int fc_disc_new_target(struct fc_disc *disc,
struct fc_rport_identifiers *ids)
{
struct fc_lport *lport = disc->lport;
- struct fc_rport_libfc_priv *rp;
+ struct fc_rport_libfc_priv *rdata;
int error = 0;
if (rport && ids->port_name) {
@@ -430,15 +430,15 @@ static int fc_disc_new_target(struct fc_disc *disc,
dp.ids.port_name = ids->port_name;
dp.ids.node_name = ids->node_name;
dp.ids.roles = ids->roles;
- rport = fc_rport_rogue_create(&dp);
+ rport = lport->tt.rport_create(&dp);
}
if (!rport)
error = -ENOMEM;
}
if (rport) {
- rp = rport->dd_data;
- rp->ops = &fc_disc_rport_ops;
- rp->rp_state = RPORT_ST_INIT;
+ rdata = rport->dd_data;
+ rdata->ops = &fc_disc_rport_ops;
+ rdata->rp_state = RPORT_ST_INIT;
lport->tt.rport_login(rport);
}
}
@@ -446,20 +446,20 @@ static int fc_disc_new_target(struct fc_disc *disc,
}
/**
- * fc_disc_del_target - Delete a target
+ * fc_disc_del_target() - Delete a target
* @disc: FC discovery context
* @rport: The remote port to be removed
*/
static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport)
{
struct fc_lport *lport = disc->lport;
- struct fc_rport_libfc_priv *rdata = RPORT_TO_PRIV(rport);
+ struct fc_rport_libfc_priv *rdata = rport->dd_data;
list_del(&rdata->peers);
lport->tt.rport_logoff(rport);
}
/**
- * fc_disc_done - Discovery has been completed
+ * fc_disc_done() - Discovery has been completed
* @disc: FC discovery context
*/
static void fc_disc_done(struct fc_disc *disc)
@@ -479,7 +479,7 @@ static void fc_disc_done(struct fc_disc *disc)
}
/**
- * fc_disc_error - Handle error on dNS request
+ * fc_disc_error() - Handle error on dNS request
* @disc: FC discovery context
* @fp: The frame pointer
*/
@@ -519,7 +519,7 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
}
/**
- * fc_disc_gpn_ft_req - Send Get Port Names by FC-4 type (GPN_FT) request
+ * fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request
* @lport: FC discovery context
*
* Locking Note: This function expects that the disc_mutex is locked
@@ -553,7 +553,7 @@ err:
}
/**
- * fc_disc_gpn_ft_parse - Parse the list of IDs and names resulting from a request
+ * fc_disc_gpn_ft_parse() - Parse the list of IDs and names resulting from a request
* @lport: Fibre Channel host port instance
* @buf: GPN_FT response buffer
* @len: size of response buffer
@@ -617,7 +617,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
if ((dp.ids.port_id != fc_host_port_id(lport->host)) &&
(dp.ids.port_name != lport->wwpn)) {
- rport = fc_rport_rogue_create(&dp);
+ rport = lport->tt.rport_create(&dp);
if (rport) {
rdata = rport->dd_data;
rdata->ops = &fc_disc_rport_ops;
@@ -658,7 +658,10 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
return error;
}
-/*
+/**
+ * fc_disc_timeout() - Retry handler for the disc component
+ * @work: Structure holding disc obj that needs retry discovery
+ *
* Handle retry of memory allocation for remote ports.
*/
static void fc_disc_timeout(struct work_struct *work)
@@ -673,7 +676,7 @@ static void fc_disc_timeout(struct work_struct *work)
}
/**
- * fc_disc_gpn_ft_resp - Handle a response frame from Get Port Names (GPN_FT)
+ * fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT)
* @sp: Current sequence of GPN_FT exchange
* @fp: response frame
* @lp_arg: Fibre Channel host port instance
@@ -712,9 +715,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
fr_len(fp));
} else if (ntohs(cp->ct_cmd) == FC_FS_ACC) {
- /*
- * Accepted. Parse response.
- */
+ /* Accepted, parse the response. */
buf = cp + 1;
len -= sizeof(*cp);
} else if (ntohs(cp->ct_cmd) == FC_FS_RJT) {
@@ -746,7 +747,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
}
/**
- * fc_disc_single - Discover the directory information for a single target
+ * fc_disc_single() - Discover the directory information for a single target
* @lport: FC local port
* @dp: The port to rediscover
*
@@ -769,7 +770,7 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp)
if (rport)
fc_disc_del_target(disc, rport);
- new_rport = fc_rport_rogue_create(dp);
+ new_rport = lport->tt.rport_create(dp);
if (new_rport) {
rdata = new_rport->dd_data;
rdata->ops = &fc_disc_rport_ops;
@@ -782,7 +783,7 @@ out:
}
/**
- * fc_disc_stop - Stop discovery for a given lport
+ * fc_disc_stop() - Stop discovery for a given lport
* @lport: The lport that discovery should stop for
*/
void fc_disc_stop(struct fc_lport *lport)
@@ -796,7 +797,7 @@ void fc_disc_stop(struct fc_lport *lport)
}
/**
- * fc_disc_stop_final - Stop discovery for a given lport
+ * fc_disc_stop_final() - Stop discovery for a given lport
* @lport: The lport that discovery should stop for
*
* This function will block until discovery has been
@@ -809,7 +810,7 @@ void fc_disc_stop_final(struct fc_lport *lport)
}
/**
- * fc_disc_init - Initialize the discovery block
+ * fc_disc_init() - Initialize the discovery block
* @lport: FC local port
*/
int fc_disc_init(struct fc_lport *lport)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 66db08a5f27..505825b6124 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -32,8 +32,6 @@
#include <scsi/libfc.h>
#include <scsi/fc_encode.h>
-#define FC_DEF_R_A_TOV (10 * 1000) /* resource allocation timeout */
-
/*
* fc_exch_debug can be set in debugger or at compile time to get more logs.
*/
@@ -627,7 +625,6 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
{
struct fc_exch *ep;
struct fc_frame_header *fh;
- u16 rxid;
ep = mp->lp->tt.exch_get(mp->lp, fp);
if (ep) {
@@ -654,18 +651,6 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0)
ep->esb_stat &= ~ESB_ST_SEQ_INIT;
- /*
- * Set the responder ID in the frame header.
- * The old one should've been 0xffff.
- * If it isn't, don't assign one.
- * Incoming basic link service frames may specify
- * a referenced RX_ID.
- */
- if (fh->fh_type != FC_TYPE_BLS) {
- rxid = ntohs(fh->fh_rx_id);
- WARN_ON(rxid != FC_XID_UNKNOWN);
- fh->fh_rx_id = htons(ep->rxid);
- }
fc_exch_hold(ep); /* hold for caller */
spin_unlock_bh(&ep->ex_lock); /* lock from exch_get */
}
@@ -677,8 +662,8 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
* If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold
* on the ep that should be released by the caller.
*/
-static enum fc_pf_rjt_reason
-fc_seq_lookup_recip(struct fc_exch_mgr *mp, struct fc_frame *fp)
+static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp,
+ struct fc_frame *fp)
{
struct fc_frame_header *fh = fc_frame_header_get(fp);
struct fc_exch *ep = NULL;
@@ -996,9 +981,9 @@ static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
* Send BLS Reject.
* This is for rejecting BA_ABTS only.
*/
-static void
-fc_exch_send_ba_rjt(struct fc_frame *rx_fp, enum fc_ba_rjt_reason reason,
- enum fc_ba_rjt_explan explan)
+static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
+ enum fc_ba_rjt_reason reason,
+ enum fc_ba_rjt_explan explan)
{
struct fc_frame *fp;
struct fc_frame_header *rx_fh;
@@ -1096,7 +1081,7 @@ static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
ap->ba_high_seq_cnt = fh->fh_seq_cnt;
ap->ba_low_seq_cnt = htons(sp->cnt);
}
- sp = fc_seq_start_next(sp);
+ sp = fc_seq_start_next_locked(sp);
spin_unlock_bh(&ep->ex_lock);
fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS);
fc_frame_free(rx_fp);
@@ -1480,10 +1465,11 @@ static void fc_exch_reset(struct fc_exch *ep)
* If sid is non-zero, reset only exchanges we source from that FID.
* If did is non-zero, reset only exchanges destined to that FID.
*/
-void fc_exch_mgr_reset(struct fc_exch_mgr *mp, u32 sid, u32 did)
+void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did)
{
struct fc_exch *ep;
struct fc_exch *next;
+ struct fc_exch_mgr *mp = lp->emp;
spin_lock_bh(&mp->em_lock);
restart:
@@ -1607,7 +1593,7 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
if (IS_ERR(fp)) {
int err = PTR_ERR(fp);
- if (err == -FC_EX_CLOSED)
+ if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT)
goto cleanup;
FC_DBG("Cannot process RRQ, because of frame error %d\n", err);
return;
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 404e63ff46b..2a631d7dbce 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -161,7 +161,7 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lp, gfp_t gfp)
}
/**
- * fc_fcp_pkt_release - release hold on scsi_pkt packet
+ * fc_fcp_pkt_release() - release hold on scsi_pkt packet
* @fsp: fcp packet struct
*
* This is used by upper layer scsi driver.
@@ -183,8 +183,7 @@ static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp)
}
/**
- * fc_fcp_pkt_destory - release hold on scsi_pkt packet
- *
+ * fc_fcp_pkt_destory() - release hold on scsi_pkt packet
* @seq: exchange sequence
* @fsp: fcp packet struct
*
@@ -199,7 +198,7 @@ static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp)
}
/**
- * fc_fcp_lock_pkt - lock a packet and get a ref to it.
+ * fc_fcp_lock_pkt() - lock a packet and get a ref to it.
* @fsp: fcp packet
*
* We should only return error if we return a command to scsi-ml before
@@ -291,9 +290,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
buf = fc_frame_payload_get(fp, 0);
if (offset + len > fsp->data_len) {
- /*
- * this should never happen
- */
+ /* this should never happen */
if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) &&
fc_frame_crc_check(fp))
goto crc_err;
@@ -387,8 +384,8 @@ crc_err:
fc_fcp_complete_locked(fsp);
}
-/*
- * fc_fcp_send_data - Send SCSI data to target.
+/**
+ * fc_fcp_send_data() - Send SCSI data to target.
* @fsp: ptr to fc_fcp_pkt
* @sp: ptr to this sequence
* @offset: starting offset for this data request
@@ -610,8 +607,8 @@ static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
}
}
-/*
- * fc_fcp_reduce_can_queue - drop can_queue
+/**
+ * fc_fcp_reduce_can_queue() - drop can_queue
* @lp: lport to drop queueing for
*
* If we are getting memory allocation failures, then we may
@@ -642,9 +639,11 @@ done:
spin_unlock_irqrestore(lp->host->host_lock, flags);
}
-/*
- * exch mgr calls this routine to process scsi
- * exchanges.
+/**
+ * fc_fcp_recv() - Reveive FCP frames
+ * @seq: The sequence the frame is on
+ * @fp: The FC frame
+ * @arg: The related FCP packet
*
* Return : None
* Context : called from Soft IRQ context
@@ -832,7 +831,7 @@ err:
}
/**
- * fc_fcp_complete_locked - complete processing of a fcp packet
+ * fc_fcp_complete_locked() - complete processing of a fcp packet
* @fsp: fcp packet
*
* This function may sleep if a timer is pending. The packet lock must be
@@ -900,7 +899,7 @@ static void fc_fcp_cleanup_cmd(struct fc_fcp_pkt *fsp, int error)
}
/**
- * fc_fcp_cleanup_each_cmd - run fn on each active command
+ * fc_fcp_cleanup_each_cmd() - Cleanup active commads
* @lp: logical port
* @id: target id
* @lun: lun
@@ -952,7 +951,7 @@ static void fc_fcp_abort_io(struct fc_lport *lp)
}
/**
- * fc_fcp_pkt_send - send a fcp packet to the lower level.
+ * fc_fcp_pkt_send() - send a fcp packet to the lower level.
* @lp: fc lport
* @fsp: fc packet.
*
@@ -1621,7 +1620,7 @@ out:
static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp)
{
/* lock ? */
- return (lp->state == LPORT_ST_READY) && (lp->link_status & FC_LINK_UP);
+ return (lp->state == LPORT_ST_READY) && lp->link_up && !lp->qfull;
}
/**
@@ -1727,7 +1726,7 @@ out:
EXPORT_SYMBOL(fc_queuecommand);
/**
- * fc_io_compl - Handle responses for completed commands
+ * fc_io_compl() - Handle responses for completed commands
* @fsp: scsi packet
*
* Translates a error to a Linux SCSI error.
@@ -1810,12 +1809,12 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
sc_cmd->result = DID_ERROR << 16;
break;
case FC_DATA_UNDRUN:
- if (fsp->cdb_status == 0) {
+ if ((fsp->cdb_status == 0) && !(fsp->req_flags & FC_SRB_READ)) {
/*
* scsi status is good but transport level
- * underrun. for read it should be an error??
+ * underrun.
*/
- sc_cmd->result = (DID_OK << 16) | fsp->cdb_status;
+ sc_cmd->result = DID_OK << 16;
} else {
/*
* scsi got underrun, this is an error
@@ -1857,7 +1856,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
}
/**
- * fc_fcp_complete - complete processing of a fcp packet
+ * fc_fcp_complete() - complete processing of a fcp packet
* @fsp: fcp packet
*
* This function may sleep if a fsp timer is pending.
@@ -1874,9 +1873,10 @@ void fc_fcp_complete(struct fc_fcp_pkt *fsp)
EXPORT_SYMBOL(fc_fcp_complete);
/**
- * fc_eh_abort - Abort a command...from scsi host template
+ * fc_eh_abort() - Abort a command
* @sc_cmd: scsi command to abort
*
+ * From scsi host template.
* send ABTS to the target device and wait for the response
* sc_cmd is the pointer to the command to be aborted.
*/
@@ -1890,7 +1890,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
lp = shost_priv(sc_cmd->device->host);
if (lp->state != LPORT_ST_READY)
return rc;
- else if (!(lp->link_status & FC_LINK_UP))
+ else if (!lp->link_up)
return rc;
spin_lock_irqsave(lp->host->host_lock, flags);
@@ -1920,7 +1920,7 @@ release_pkt:
EXPORT_SYMBOL(fc_eh_abort);
/**
- * fc_eh_device_reset: Reset a single LUN
+ * fc_eh_device_reset() Reset a single LUN
* @sc_cmd: scsi command
*
* Set from scsi host template to send tm cmd to the target and wait for the
@@ -1973,7 +1973,7 @@ out:
EXPORT_SYMBOL(fc_eh_device_reset);
/**
- * fc_eh_host_reset - The reset function will reset the ports on the host.
+ * fc_eh_host_reset() - The reset function will reset the ports on the host.
* @sc_cmd: scsi command
*/
int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
@@ -1999,7 +1999,7 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
EXPORT_SYMBOL(fc_eh_host_reset);
/**
- * fc_slave_alloc - configure queue depth
+ * fc_slave_alloc() - configure queue depth
* @sdev: scsi device
*
* Configures queue depth based on host's cmd_per_len. If not set
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 0b9bdb1fb80..2ae50a1188e 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -139,7 +139,7 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
}
/**
- * fc_lport_rport_callback - Event handler for rport events
+ * fc_lport_rport_callback() - Event handler for rport events
* @lport: The lport which is receiving the event
* @rport: The rport which the event has occured on
* @event: The event that occured
@@ -195,7 +195,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
}
/**
- * fc_lport_state - Return a string which represents the lport's state
+ * fc_lport_state() - Return a string which represents the lport's state
* @lport: The lport whose state is to converted to a string
*/
static const char *fc_lport_state(struct fc_lport *lport)
@@ -209,7 +209,7 @@ static const char *fc_lport_state(struct fc_lport *lport)
}
/**
- * fc_lport_ptp_setup - Create an rport for point-to-point mode
+ * fc_lport_ptp_setup() - Create an rport for point-to-point mode
* @lport: The lport to attach the ptp rport to
* @fid: The FID of the ptp rport
* @remote_wwpn: The WWPN of the ptp rport
@@ -232,7 +232,7 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
lport->ptp_rp = NULL;
}
- lport->ptp_rp = fc_rport_rogue_create(&dp);
+ lport->ptp_rp = lport->tt.rport_create(&dp);
lport->tt.rport_login(lport->ptp_rp);
@@ -250,7 +250,7 @@ void fc_get_host_port_state(struct Scsi_Host *shost)
{
struct fc_lport *lp = shost_priv(shost);
- if ((lp->link_status & FC_LINK_UP) == FC_LINK_UP)
+ if (lp->link_up)
fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
else
fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
@@ -351,7 +351,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
}
/**
- * fc_lport_recv_rlir_req - Handle received Registered Link Incident Report.
+ * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report.
* @lport: Fibre Channel local port recieving the RLIR
* @sp: current sequence in the RLIR exchange
* @fp: RLIR request frame
@@ -370,7 +370,7 @@ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
}
/**
- * fc_lport_recv_echo_req - Handle received ECHO request
+ * fc_lport_recv_echo_req() - Handle received ECHO request
* @lport: Fibre Channel local port recieving the ECHO
* @sp: current sequence in the ECHO exchange
* @fp: ECHO request frame
@@ -412,7 +412,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
}
/**
- * fc_lport_recv_echo_req - Handle received Request Node ID data request
+ * fc_lport_recv_echo_req() - Handle received Request Node ID data request
* @lport: Fibre Channel local port recieving the RNID
* @sp: current sequence in the RNID exchange
* @fp: RNID request frame
@@ -479,7 +479,7 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
}
/**
- * fc_lport_recv_adisc_req - Handle received Address Discovery Request
+ * fc_lport_recv_adisc_req() - Handle received Address Discovery Request
* @lport: Fibre Channel local port recieving the ADISC
* @sp: current sequence in the ADISC exchange
* @fp: ADISC request frame
@@ -529,7 +529,7 @@ static void fc_lport_recv_adisc_req(struct fc_seq *sp, struct fc_frame *in_fp,
}
/**
- * fc_lport_recv_logo_req - Handle received fabric LOGO request
+ * fc_lport_recv_logo_req() - Handle received fabric LOGO request
* @lport: Fibre Channel local port recieving the LOGO
* @sp: current sequence in the LOGO exchange
* @fp: LOGO request frame
@@ -546,7 +546,7 @@ static void fc_lport_recv_logo_req(struct fc_seq *sp, struct fc_frame *fp,
}
/**
- * fc_fabric_login - Start the lport state machine
+ * fc_fabric_login() - Start the lport state machine
* @lport: The lport that should log into the fabric
*
* Locking Note: This function should not be called
@@ -568,7 +568,7 @@ int fc_fabric_login(struct fc_lport *lport)
EXPORT_SYMBOL(fc_fabric_login);
/**
- * fc_linkup - Handler for transport linkup events
+ * fc_linkup() - Handler for transport linkup events
* @lport: The lport whose link is up
*/
void fc_linkup(struct fc_lport *lport)
@@ -577,8 +577,8 @@ void fc_linkup(struct fc_lport *lport)
fc_host_port_id(lport->host));
mutex_lock(&lport->lp_mutex);
- if ((lport->link_status & FC_LINK_UP) != FC_LINK_UP) {
- lport->link_status |= FC_LINK_UP;
+ if (!lport->link_up) {
+ lport->link_up = 1;
if (lport->state == LPORT_ST_RESET)
fc_lport_enter_flogi(lport);
@@ -588,7 +588,7 @@ void fc_linkup(struct fc_lport *lport)
EXPORT_SYMBOL(fc_linkup);
/**
- * fc_linkdown - Handler for transport linkdown events
+ * fc_linkdown() - Handler for transport linkdown events
* @lport: The lport whose link is down
*/
void fc_linkdown(struct fc_lport *lport)
@@ -597,8 +597,8 @@ void fc_linkdown(struct fc_lport *lport)
FC_DEBUG_LPORT("Link is down for port (%6x)\n",
fc_host_port_id(lport->host));
- if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) {
- lport->link_status &= ~(FC_LINK_UP);
+ if (lport->link_up) {
+ lport->link_up = 0;
fc_lport_enter_reset(lport);
lport->tt.fcp_cleanup(lport);
}
@@ -607,48 +607,25 @@ void fc_linkdown(struct fc_lport *lport)
EXPORT_SYMBOL(fc_linkdown);
/**
- * fc_pause - Pause the flow of frames
- * @lport: The lport to be paused
- */
-void fc_pause(struct fc_lport *lport)
-{
- mutex_lock(&lport->lp_mutex);
- lport->link_status |= FC_PAUSE;
- mutex_unlock(&lport->lp_mutex);
-}
-EXPORT_SYMBOL(fc_pause);
-
-/**
- * fc_unpause - Unpause the flow of frames
- * @lport: The lport to be unpaused
- */
-void fc_unpause(struct fc_lport *lport)
-{
- mutex_lock(&lport->lp_mutex);
- lport->link_status &= ~(FC_PAUSE);
- mutex_unlock(&lport->lp_mutex);
-}
-EXPORT_SYMBOL(fc_unpause);
-
-/**
- * fc_fabric_logoff - Logout of the fabric
+ * fc_fabric_logoff() - Logout of the fabric
* @lport: fc_lport pointer to logoff the fabric
*
* Return value:
* 0 for success, -1 for failure
- **/
+ */
int fc_fabric_logoff(struct fc_lport *lport)
{
lport->tt.disc_stop_final(lport);
mutex_lock(&lport->lp_mutex);
fc_lport_enter_logo(lport);
mutex_unlock(&lport->lp_mutex);
+ cancel_delayed_work_sync(&lport->retry_work);
return 0;
}
EXPORT_SYMBOL(fc_fabric_logoff);
/**
- * fc_lport_destroy - unregister a fc_lport
+ * fc_lport_destroy() - unregister a fc_lport
* @lport: fc_lport pointer to unregister
*
* Return value:
@@ -658,26 +635,25 @@ EXPORT_SYMBOL(fc_fabric_logoff);
* clean-up all the allocated memory
* and free up other system resources.
*
- **/
+ */
int fc_lport_destroy(struct fc_lport *lport)
{
lport->tt.frame_send = fc_frame_drop;
lport->tt.fcp_abort_io(lport);
- lport->tt.exch_mgr_reset(lport->emp, 0, 0);
+ lport->tt.exch_mgr_reset(lport, 0, 0);
return 0;
}
EXPORT_SYMBOL(fc_lport_destroy);
/**
- * fc_set_mfs - sets up the mfs for the corresponding fc_lport
+ * fc_set_mfs() - sets up the mfs for the corresponding fc_lport
* @lport: fc_lport pointer to unregister
* @mfs: the new mfs for fc_lport
*
* Set mfs for the given fc_lport to the new mfs.
*
* Return: 0 for success
- *
- **/
+ */
int fc_set_mfs(struct fc_lport *lport, u32 mfs)
{
unsigned int old_mfs;
@@ -706,7 +682,7 @@ int fc_set_mfs(struct fc_lport *lport, u32 mfs)
EXPORT_SYMBOL(fc_set_mfs);
/**
- * fc_lport_disc_callback - Callback for discovery events
+ * fc_lport_disc_callback() - Callback for discovery events
* @lport: FC local port
* @event: The discovery event
*/
@@ -731,7 +707,7 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
}
/**
- * fc_rport_enter_ready - Enter the ready state and start discovery
+ * fc_rport_enter_ready() - Enter the ready state and start discovery
* @lport: Fibre Channel local port that is ready
*
* Locking Note: The lport lock is expected to be held before calling
@@ -748,7 +724,7 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
}
/**
- * fc_lport_recv_flogi_req - Receive a FLOGI request
+ * fc_lport_recv_flogi_req() - Receive a FLOGI request
* @sp_in: The sequence the FLOGI is on
* @rx_fp: The frame the FLOGI is in
* @lport: The lport that recieved the request
@@ -838,7 +814,7 @@ out:
}
/**
- * fc_lport_recv_req - The generic lport request handler
+ * fc_lport_recv_req() - The generic lport request handler
* @lport: The lport that received the request
* @sp: The sequence the request is on
* @fp: The frame the request is in
@@ -934,7 +910,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
}
/**
- * fc_lport_reset - Reset an lport
+ * fc_lport_reset() - Reset an lport
* @lport: The lport which should be reset
*
* Locking Note: This functions should not be called with the
@@ -942,6 +918,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
*/
int fc_lport_reset(struct fc_lport *lport)
{
+ cancel_delayed_work_sync(&lport->retry_work);
mutex_lock(&lport->lp_mutex);
fc_lport_enter_reset(lport);
mutex_unlock(&lport->lp_mutex);
@@ -950,7 +927,7 @@ int fc_lport_reset(struct fc_lport *lport)
EXPORT_SYMBOL(fc_lport_reset);
/**
- * fc_rport_enter_reset - Reset the local port
+ * fc_rport_enter_reset() - Reset the local port
* @lport: Fibre Channel local port to be reset
*
* Locking Note: The lport lock is expected to be held before calling
@@ -973,16 +950,16 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
lport->tt.disc_stop(lport);
- lport->tt.exch_mgr_reset(lport->emp, 0, 0);
+ lport->tt.exch_mgr_reset(lport, 0, 0);
fc_host_fabric_name(lport->host) = 0;
fc_host_port_id(lport->host) = 0;
- if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP)
+ if (lport->link_up)
fc_lport_enter_flogi(lport);
}
/**
- * fc_lport_error - Handler for any errors
+ * fc_lport_error() - Handler for any errors
* @lport: The fc_lport object
* @fp: The frame pointer
*
@@ -1029,8 +1006,8 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
}
/**
- * fc_lport_rft_id_resp - Handle response to Register Fibre
- * Channel Types by ID (RPN_ID) request
+ * fc_lport_rft_id_resp() - Handle response to Register Fibre
+ * Channel Types by ID (RPN_ID) request
* @sp: current sequence in RPN_ID exchange
* @fp: response frame
* @lp_arg: Fibre Channel host port instance
@@ -1053,17 +1030,17 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a RFT_ID response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_RFT_ID) {
FC_DBG("Received a RFT_ID response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
fh = fc_frame_header_get(fp);
ct = fc_frame_payload_get(fp, sizeof(*ct));
@@ -1081,8 +1058,8 @@ err:
}
/**
- * fc_lport_rpn_id_resp - Handle response to Register Port
- * Name by ID (RPN_ID) request
+ * fc_lport_rpn_id_resp() - Handle response to Register Port
+ * Name by ID (RPN_ID) request
* @sp: current sequence in RPN_ID exchange
* @fp: response frame
* @lp_arg: Fibre Channel host port instance
@@ -1105,17 +1082,17 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a RPN_ID response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_RPN_ID) {
FC_DBG("Received a RPN_ID response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
fh = fc_frame_header_get(fp);
ct = fc_frame_payload_get(fp, sizeof(*ct));
if (fh && ct && fh->fh_type == FC_TYPE_CT &&
@@ -1133,7 +1110,7 @@ err:
}
/**
- * fc_lport_scr_resp - Handle response to State Change Register (SCR) request
+ * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
* @sp: current sequence in SCR exchange
* @fp: response frame
* @lp_arg: Fibre Channel lport port instance that sent the registration request
@@ -1155,17 +1132,17 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a SCR response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_SCR) {
FC_DBG("Received a SCR response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC)
fc_lport_enter_ready(lport);
@@ -1179,7 +1156,7 @@ err:
}
/**
- * fc_lport_enter_scr - Send a State Change Register (SCR) request
+ * fc_lport_enter_scr() - Send a State Change Register (SCR) request
* @lport: Fibre Channel local port to register for state changes
*
* Locking Note: The lport lock is expected to be held before calling
@@ -1206,7 +1183,7 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
}
/**
- * fc_lport_enter_rft_id - Register FC4-types with the name server
+ * fc_lport_enter_rft_id() - Register FC4-types with the name server
* @lport: Fibre Channel local port to register
*
* Locking Note: The lport lock is expected to be held before calling
@@ -1248,7 +1225,7 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport)
}
/**
- * fc_rport_enter_rft_id - Register port name with the name server
+ * fc_rport_enter_rft_id() - Register port name with the name server
* @lport: Fibre Channel local port to register
*
* Locking Note: The lport lock is expected to be held before calling
@@ -1281,7 +1258,7 @@ static struct fc_rport_operations fc_lport_rport_ops = {
};
/**
- * fc_rport_enter_dns - Create a rport to the name server
+ * fc_rport_enter_dns() - Create a rport to the name server
* @lport: Fibre Channel local port requesting a rport for the name server
*
* Locking Note: The lport lock is expected to be held before calling
@@ -1304,7 +1281,7 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
fc_lport_state_enter(lport, LPORT_ST_DNS);
- rport = fc_rport_rogue_create(&dp);
+ rport = lport->tt.rport_create(&dp);
if (!rport)
goto err;
@@ -1318,7 +1295,7 @@ err:
}
/**
- * fc_lport_timeout - Handler for the retry_work timer.
+ * fc_lport_timeout() - Handler for the retry_work timer.
* @work: The work struct of the fc_lport
*/
static void fc_lport_timeout(struct work_struct *work)
@@ -1359,7 +1336,7 @@ static void fc_lport_timeout(struct work_struct *work)
}
/**
- * fc_lport_logo_resp - Handle response to LOGO request
+ * fc_lport_logo_resp() - Handle response to LOGO request
* @sp: current sequence in LOGO exchange
* @fp: response frame
* @lp_arg: Fibre Channel lport port instance that sent the LOGO request
@@ -1381,17 +1358,17 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a LOGO response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_LOGO) {
FC_DBG("Received a LOGO response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC)
fc_lport_enter_reset(lport);
@@ -1405,7 +1382,7 @@ err:
}
/**
- * fc_rport_enter_logo - Logout of the fabric
+ * fc_rport_enter_logo() - Logout of the fabric
* @lport: Fibre Channel local port to be logged out
*
* Locking Note: The lport lock is expected to be held before calling
@@ -1437,7 +1414,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
}
/**
- * fc_lport_flogi_resp - Handle response to FLOGI request
+ * fc_lport_flogi_resp() - Handle response to FLOGI request
* @sp: current sequence in FLOGI exchange
* @fp: response frame
* @lp_arg: Fibre Channel lport port instance that sent the FLOGI request
@@ -1465,17 +1442,17 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a FLOGI response\n");
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
if (lport->state != LPORT_ST_FLOGI) {
FC_DBG("Received a FLOGI response, but in state %s\n",
fc_lport_state(lport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
fh = fc_frame_header_get(fp);
did = ntoh24(fh->fh_d_id);
if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
@@ -1532,7 +1509,7 @@ err:
}
/**
- * fc_rport_enter_flogi - Send a FLOGI request to the fabric manager
+ * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
* @lport: Fibre Channel local port to be logged in to the fabric
*
* Locking Note: The lport lock is expected to be held before calling
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index e780d8caf70..dae65133a83 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -81,6 +81,7 @@ static void fc_rport_recv_logo_req(struct fc_rport *,
struct fc_seq *, struct fc_frame *);
static void fc_rport_timeout(struct work_struct *);
static void fc_rport_error(struct fc_rport *, struct fc_frame *);
+static void fc_rport_error_retry(struct fc_rport *, struct fc_frame *);
static void fc_rport_work(struct work_struct *);
static const char *fc_rport_state_names[] = {
@@ -145,7 +146,7 @@ struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp)
}
/**
- * fc_rport_state - return a string for the state the rport is in
+ * fc_rport_state() - return a string for the state the rport is in
* @rport: The rport whose state we want to get a string for
*/
static const char *fc_rport_state(struct fc_rport *rport)
@@ -160,7 +161,7 @@ static const char *fc_rport_state(struct fc_rport *rport)
}
/**
- * fc_set_rport_loss_tmo - Set the remote port loss timeout in seconds.
+ * fc_set_rport_loss_tmo() - Set the remote port loss timeout in seconds.
* @rport: Pointer to Fibre Channel remote port structure
* @timeout: timeout in seconds
*/
@@ -174,12 +175,12 @@ void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
EXPORT_SYMBOL(fc_set_rport_loss_tmo);
/**
- * fc_plogi_get_maxframe - Get max payload from the common service parameters
+ * fc_plogi_get_maxframe() - Get max payload from the common service parameters
* @flp: FLOGI payload structure
* @maxval: upper limit, may be less than what is in the service parameters
*/
-static unsigned int
-fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval)
+static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp,
+ unsigned int maxval)
{
unsigned int mfs;
@@ -197,7 +198,7 @@ fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval)
}
/**
- * fc_rport_state_enter - Change the rport's state
+ * fc_rport_state_enter() - Change the rport's state
* @rport: The rport whose state should change
* @new: The new state of the rport
*
@@ -214,6 +215,7 @@ static void fc_rport_state_enter(struct fc_rport *rport,
static void fc_rport_work(struct work_struct *work)
{
+ u32 port_id;
struct fc_rport_libfc_priv *rdata =
container_of(work, struct fc_rport_libfc_priv, event_work);
enum fc_rport_event event;
@@ -279,14 +281,18 @@ static void fc_rport_work(struct work_struct *work)
rport_ops->event_callback(lport, rport, event);
if (trans_state == FC_PORTSTATE_ROGUE)
put_device(&rport->dev);
- else
+ else {
+ port_id = rport->port_id;
fc_remote_port_delete(rport);
+ lport->tt.exch_mgr_reset(lport, 0, port_id);
+ lport->tt.exch_mgr_reset(lport, port_id, 0);
+ }
} else
mutex_unlock(&rdata->rp_mutex);
}
/**
- * fc_rport_login - Start the remote port login state machine
+ * fc_rport_login() - Start the remote port login state machine
* @rport: Fibre Channel remote port
*
* Locking Note: Called without the rport lock held. This
@@ -309,7 +315,7 @@ int fc_rport_login(struct fc_rport *rport)
}
/**
- * fc_rport_logoff - Logoff and remove an rport
+ * fc_rport_logoff() - Logoff and remove an rport
* @rport: Fibre Channel remote port to be removed
*
* Locking Note: Called without the rport lock held. This
@@ -347,7 +353,7 @@ int fc_rport_logoff(struct fc_rport *rport)
}
/**
- * fc_rport_enter_ready - The rport is ready
+ * fc_rport_enter_ready() - The rport is ready
* @rport: Fibre Channel remote port that is ready
*
* Locking Note: The rport lock is expected to be held before calling
@@ -366,7 +372,7 @@ static void fc_rport_enter_ready(struct fc_rport *rport)
}
/**
- * fc_rport_timeout - Handler for the retry_work timer.
+ * fc_rport_timeout() - Handler for the retry_work timer.
* @work: The work struct of the fc_rport_libfc_priv
*
* Locking Note: Called without the rport lock held. This
@@ -405,59 +411,75 @@ static void fc_rport_timeout(struct work_struct *work)
}
/**
- * fc_rport_error - Handler for any errors
+ * fc_rport_error() - Error handler, called once retries have been exhausted
* @rport: The fc_rport object
* @fp: The frame pointer
*
- * If the error was caused by a resource allocation failure
- * then wait for half a second and retry, otherwise retry
- * immediately.
- *
* Locking Note: The rport lock is expected to be held before
* calling this routine
*/
static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
{
struct fc_rport_libfc_priv *rdata = rport->dd_data;
- unsigned long delay = 0;
FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n",
PTR_ERR(fp), fc_rport_state(rport), rdata->retries);
- if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) {
- /*
- * Memory allocation failure, or the exchange timed out.
- * Retry after delay
- */
- if (rdata->retries < rdata->local_port->max_retry_count) {
- rdata->retries++;
- if (!fp)
- delay = msecs_to_jiffies(500);
- get_device(&rport->dev);
- schedule_delayed_work(&rdata->retry_work, delay);
- } else {
- switch (rdata->rp_state) {
- case RPORT_ST_PLOGI:
- case RPORT_ST_PRLI:
- case RPORT_ST_LOGO:
- rdata->event = RPORT_EV_FAILED;
- queue_work(rport_event_queue,
- &rdata->event_work);
- break;
- case RPORT_ST_RTV:
- fc_rport_enter_ready(rport);
- break;
- case RPORT_ST_NONE:
- case RPORT_ST_READY:
- case RPORT_ST_INIT:
- break;
- }
- }
+ switch (rdata->rp_state) {
+ case RPORT_ST_PLOGI:
+ case RPORT_ST_PRLI:
+ case RPORT_ST_LOGO:
+ rdata->event = RPORT_EV_FAILED;
+ queue_work(rport_event_queue,
+ &rdata->event_work);
+ break;
+ case RPORT_ST_RTV:
+ fc_rport_enter_ready(rport);
+ break;
+ case RPORT_ST_NONE:
+ case RPORT_ST_READY:
+ case RPORT_ST_INIT:
+ break;
}
}
/**
- * fc_rport_plogi_recv_resp - Handle incoming ELS PLOGI response
+ * fc_rport_error_retry() - Error handler when retries are desired
+ * @rport: The fc_rport object
+ * @fp: The frame pointer
+ *
+ * If the error was an exchange timeout retry immediately,
+ * otherwise wait for E_D_TOV.
+ *
+ * Locking Note: The rport lock is expected to be held before
+ * calling this routine
+ */
+static void fc_rport_error_retry(struct fc_rport *rport, struct fc_frame *fp)
+{
+ struct fc_rport_libfc_priv *rdata = rport->dd_data;
+ unsigned long delay = FC_DEF_E_D_TOV;
+
+ /* make sure this isn't an FC_EX_CLOSED error, never retry those */
+ if (PTR_ERR(fp) == -FC_EX_CLOSED)
+ return fc_rport_error(rport, fp);
+
+ if (rdata->retries < rdata->local_port->max_retry_count) {
+ FC_DEBUG_RPORT("Error %ld in state %s, retrying\n",
+ PTR_ERR(fp), fc_rport_state(rport));
+ rdata->retries++;
+ /* no additional delay on exchange timeouts */
+ if (PTR_ERR(fp) == -FC_EX_TIMEOUT)
+ delay = 0;
+ get_device(&rport->dev);
+ schedule_delayed_work(&rdata->retry_work, delay);
+ return;
+ }
+
+ return fc_rport_error(rport, fp);
+}
+
+/**
+ * fc_rport_plogi_recv_resp() - Handle incoming ELS PLOGI response
* @sp: current sequence in the PLOGI exchange
* @fp: response frame
* @rp_arg: Fibre Channel remote port
@@ -483,17 +505,17 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n",
rport->port_id);
+ if (IS_ERR(fp)) {
+ fc_rport_error_retry(rport, fp);
+ goto err;
+ }
+
if (rdata->rp_state != RPORT_ST_PLOGI) {
FC_DBG("Received a PLOGI response, but in state %s\n",
fc_rport_state(rport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_rport_error(rport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC &&
(plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
@@ -522,7 +544,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
else
fc_rport_enter_prli(rport);
} else
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
out:
fc_frame_free(fp);
@@ -532,7 +554,7 @@ err:
}
/**
- * fc_rport_enter_plogi - Send Port Login (PLOGI) request to peer
+ * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer
* @rport: Fibre Channel remote port to send PLOGI to
*
* Locking Note: The rport lock is expected to be held before calling
@@ -552,20 +574,20 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
if (!fp) {
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
return;
}
rdata->e_d_tov = lport->e_d_tov;
if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI,
fc_rport_plogi_resp, rport, lport->e_d_tov))
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
else
get_device(&rport->dev);
}
/**
- * fc_rport_prli_resp - Process Login (PRLI) response handler
+ * fc_rport_prli_resp() - Process Login (PRLI) response handler
* @sp: current sequence in the PRLI exchange
* @fp: response frame
* @rp_arg: Fibre Channel remote port
@@ -592,17 +614,17 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n",
rport->port_id);
+ if (IS_ERR(fp)) {
+ fc_rport_error_retry(rport, fp);
+ goto err;
+ }
+
if (rdata->rp_state != RPORT_ST_PRLI) {
FC_DBG("Received a PRLI response, but in state %s\n",
fc_rport_state(rport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_rport_error(rport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC) {
pp = fc_frame_payload_get(fp, sizeof(*pp));
@@ -635,7 +657,7 @@ err:
}
/**
- * fc_rport_logo_resp - Logout (LOGO) response handler
+ * fc_rport_logo_resp() - Logout (LOGO) response handler
* @sp: current sequence in the LOGO exchange
* @fp: response frame
* @rp_arg: Fibre Channel remote port
@@ -657,7 +679,7 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
rport->port_id);
if (IS_ERR(fp)) {
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
goto err;
}
@@ -684,7 +706,7 @@ err:
}
/**
- * fc_rport_enter_prli - Send Process Login (PRLI) request to peer
+ * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer
* @rport: Fibre Channel remote port to send PRLI to
*
* Locking Note: The rport lock is expected to be held before calling
@@ -707,19 +729,19 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
fp = fc_frame_alloc(lport, sizeof(*pp));
if (!fp) {
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
return;
}
if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI,
fc_rport_prli_resp, rport, lport->e_d_tov))
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
else
get_device(&rport->dev);
}
/**
- * fc_rport_els_rtv_resp - Request Timeout Value response handler
+ * fc_rport_els_rtv_resp() - Request Timeout Value response handler
* @sp: current sequence in the RTV exchange
* @fp: response frame
* @rp_arg: Fibre Channel remote port
@@ -742,17 +764,17 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n",
rport->port_id);
+ if (IS_ERR(fp)) {
+ fc_rport_error(rport, fp);
+ goto err;
+ }
+
if (rdata->rp_state != RPORT_ST_RTV) {
FC_DBG("Received a RTV response, but in state %s\n",
fc_rport_state(rport));
goto out;
}
- if (IS_ERR(fp)) {
- fc_rport_error(rport, fp);
- goto err;
- }
-
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC) {
struct fc_els_rtv_acc *rtv;
@@ -785,7 +807,7 @@ err:
}
/**
- * fc_rport_enter_rtv - Send Request Timeout Value (RTV) request to peer
+ * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer
* @rport: Fibre Channel remote port to send RTV to
*
* Locking Note: The rport lock is expected to be held before calling
@@ -804,19 +826,19 @@ static void fc_rport_enter_rtv(struct fc_rport *rport)
fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv));
if (!fp) {
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
return;
}
if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV,
fc_rport_rtv_resp, rport, lport->e_d_tov))
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
else
get_device(&rport->dev);
}
/**
- * fc_rport_enter_logo - Send Logout (LOGO) request to peer
+ * fc_rport_enter_logo() - Send Logout (LOGO) request to peer
* @rport: Fibre Channel remote port to send LOGO to
*
* Locking Note: The rport lock is expected to be held before calling
@@ -835,20 +857,20 @@ static void fc_rport_enter_logo(struct fc_rport *rport)
fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo));
if (!fp) {
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
return;
}
if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO,
fc_rport_logo_resp, rport, lport->e_d_tov))
- fc_rport_error(rport, fp);
+ fc_rport_error_retry(rport, fp);
else
get_device(&rport->dev);
}
/**
- * fc_rport_recv_req - Receive a request from a rport
+ * fc_rport_recv_req() - Receive a request from a rport
* @sp: current sequence in the PLOGI exchange
* @fp: response frame
* @rp_arg: Fibre Channel remote port
@@ -909,7 +931,7 @@ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
}
/**
- * fc_rport_recv_plogi_req - Handle incoming Port Login (PLOGI) request
+ * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request
* @rport: Fibre Channel remote port that initiated PLOGI
* @sp: current sequence in the PLOGI exchange
* @fp: PLOGI request frame
@@ -1031,7 +1053,7 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
}
/**
- * fc_rport_recv_prli_req - Handle incoming Process Login (PRLI) request
+ * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request
* @rport: Fibre Channel remote port that initiated PRLI
* @sp: current sequence in the PRLI exchange
* @fp: PRLI request frame
@@ -1182,7 +1204,7 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
}
/**
- * fc_rport_recv_prlo_req - Handle incoming Process Logout (PRLO) request
+ * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request
* @rport: Fibre Channel remote port that initiated PRLO
* @sp: current sequence in the PRLO exchange
* @fp: PRLO request frame
@@ -1213,7 +1235,7 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp,
}
/**
- * fc_rport_recv_logo_req - Handle incoming Logout (LOGO) request
+ * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request
* @rport: Fibre Channel remote port that initiated LOGO
* @sp: current sequence in the LOGO exchange
* @fp: LOGO request frame
@@ -1249,6 +1271,9 @@ static void fc_rport_flush_queue(void)
int fc_rport_init(struct fc_lport *lport)
{
+ if (!lport->tt.rport_create)
+ lport->tt.rport_create = fc_rport_rogue_create;
+
if (!lport->tt.rport_login)
lport->tt.rport_login = fc_rport_login;
@@ -1285,7 +1310,7 @@ void fc_rport_terminate_io(struct fc_rport *rport)
struct fc_rport_libfc_priv *rdata = rport->dd_data;
struct fc_lport *lport = rdata->local_port;
- lport->tt.exch_mgr_reset(lport->emp, 0, rport->port_id);
- lport->tt.exch_mgr_reset(lport->emp, rport->port_id, 0);
+ lport->tt.exch_mgr_reset(lport, 0, rport->port_id);
+ lport->tt.exch_mgr_reset(lport, rport->port_id, 0);
}
EXPORT_SYMBOL(fc_rport_terminate_io);
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 7225b6e2029..809d32d95c7 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1981,6 +1981,7 @@ void iscsi_pool_free(struct iscsi_pool *q)
kfree(q->pool[i]);
if (q->pool)
kfree(q->pool);
+ kfree(q->queue);
}
EXPORT_SYMBOL_GPL(iscsi_pool_free);
@@ -1997,6 +1998,8 @@ int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev)
if (!shost->can_queue)
shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX;
+ if (!shost->transportt->eh_timed_out)
+ shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
return scsi_add_host(shost, pdev);
}
EXPORT_SYMBOL_GPL(iscsi_host_add);
@@ -2019,7 +2022,6 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size);
if (!shost)
return NULL;
- shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
if (qdepth != 0)
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index a745f91d292..e7705d3532c 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -177,7 +177,6 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
struct iscsi_segment *segment, int recv,
unsigned copied)
{
- static unsigned char padbuf[ISCSI_PAD_LEN];
struct scatterlist sg;
unsigned int pad;
@@ -233,7 +232,7 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
debug_tcp("consume %d pad bytes\n", pad);
segment->total_size += pad;
segment->size = pad;
- segment->data = padbuf;
+ segment->data = segment->padbuf;
return 0;
}
}
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 744838780ad..1c558d3bce1 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -717,7 +717,7 @@ int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
struct domain_device *dev = sdev_to_domain_dev(sdev);
if (dev_is_sata(dev))
- return ata_scsi_ioctl(sdev, cmd, arg);
+ return ata_sas_scsi_ioctl(dev->sata_dev.ap, sdev, cmd, arg);
return -EINVAL;
}
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index a8f30bdaff6..a7302480bc4 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -5258,6 +5258,7 @@ lpfc_send_els_event(struct lpfc_vport *vport,
sizeof(struct lpfc_name));
break;
default:
+ kfree(els_data);
return;
}
memcpy(els_data->wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name));
diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c
index b264b499d98..b5fbfd6ce87 100644
--- a/drivers/scsi/mvme16x_scsi.c
+++ b/drivers/scsi/mvme16x_scsi.c
@@ -34,7 +34,7 @@ static struct scsi_host_template mvme16x_scsi_driver_template = {
static struct platform_device *mvme16x_scsi_device;
static __devinit int
-mvme16x_probe(struct device *dev)
+mvme16x_probe(struct platform_device *dev)
{
struct Scsi_Host * host = NULL;
struct NCR_700_Host_Parameters *hostdata;
@@ -64,7 +64,8 @@ mvme16x_probe(struct device *dev)
hostdata->ctest7_extra = CTEST7_TT1;
/* and register the chip */
- host = NCR_700_detect(&mvme16x_scsi_driver_template, hostdata, dev);
+ host = NCR_700_detect(&mvme16x_scsi_driver_template, hostdata,
+ &dev->dev);
if (!host) {
printk(KERN_ERR "mvme16x-scsi: No host detected; "
"board configuration problem?\n");
@@ -88,7 +89,7 @@ mvme16x_probe(struct device *dev)
out_be32(0xfff4202c, v);
}
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);
return 0;
@@ -102,9 +103,9 @@ mvme16x_probe(struct device *dev)
}
static __devexit int
-mvme16x_device_remove(struct device *dev)
+mvme16x_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
/* Disable scsi chip ints */
@@ -123,25 +124,27 @@ mvme16x_device_remove(struct device *dev)
return 0;
}
-static struct device_driver mvme16x_scsi_driver = {
- .name = "mvme16x-scsi",
- .bus = &platform_bus_type,
- .probe = mvme16x_probe,
- .remove = __devexit_p(mvme16x_device_remove),
+static struct platform_driver mvme16x_scsi_driver = {
+ .driver = {
+ .name = "mvme16x-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = mvme16x_probe,
+ .remove = __devexit_p(mvme16x_device_remove),
};
static int __init mvme16x_scsi_init(void)
{
int err;
- err = driver_register(&mvme16x_scsi_driver);
+ err = platform_driver_register(&mvme16x_scsi_driver);
if (err)
return err;
mvme16x_scsi_device = platform_device_register_simple("mvme16x-scsi",
-1, NULL, 0);
if (IS_ERR(mvme16x_scsi_device)) {
- driver_unregister(&mvme16x_scsi_driver);
+ platform_driver_unregister(&mvme16x_scsi_driver);
return PTR_ERR(mvme16x_scsi_device);
}
@@ -151,7 +154,7 @@ static int __init mvme16x_scsi_init(void)
static void __exit mvme16x_scsi_exit(void)
{
platform_device_unregister(mvme16x_scsi_device);
- driver_unregister(&mvme16x_scsi_driver);
+ platform_driver_unregister(&mvme16x_scsi_driver);
}
module_init(mvme16x_scsi_init);
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index ce48e2d0193..ca0dd33497e 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -290,11 +290,11 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
if (tag != dev->tag)
dev_err(&dev->sbd.core,
- "%s:%u: tag mismatch, got %lx, expected %lx\n",
+ "%s:%u: tag mismatch, got %llx, expected %llx\n",
__func__, __LINE__, tag, dev->tag);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
__func__, __LINE__, res, status);
return IRQ_HANDLED;
}
@@ -364,7 +364,7 @@ static int __devinit ps3rom_probe(struct ps3_system_bus_device *_dev)
if (dev->blk_size != CD_FRAMESIZE) {
dev_err(&dev->sbd.core,
- "%s:%u: cannot handle block size %lu\n", __func__,
+ "%s:%u: cannot handle block size %llu\n", __func__,
__LINE__, dev->blk_size);
return -EINVAL;
}
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index c7acef50d5d..ee9d4015243 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -244,12 +244,6 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
if (ha->optrom_state != QLA_SWAITING)
break;
- if (start & 0xfff) {
- qla_printk(KERN_WARNING, ha,
- "Invalid start region 0x%x/0x%x.\n", start, size);
- return -EINVAL;
- }
-
ha->optrom_region_start = start;
ha->optrom_region_size = start + size > ha->optrom_size ?
ha->optrom_size - start : size;
@@ -303,8 +297,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
else if (start == (ha->flt_region_boot * 4) ||
start == (ha->flt_region_fw * 4))
valid = 1;
- else if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) &&
- start == (ha->flt_region_vpd_nvram * 4))
+ else if (IS_QLA25XX(ha) || IS_QLA81XX(ha))
valid = 1;
if (!valid) {
qla_printk(KERN_WARNING, ha,
@@ -1016,6 +1009,9 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
struct Scsi_Host *host = rport_to_shost(rport);
fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+ if (!fcport)
+ return;
+
qla2x00_abort_fcport_cmds(fcport);
/*
@@ -1033,6 +1029,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
{
fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+ if (!fcport)
+ return;
+
/*
* At this point all fcport's software-states are cleared. Perform any
* final cleanup of firmware resources (PCBs and XCBs).
@@ -1259,13 +1258,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
msleep(1000);
- if (ha->mqenable) {
- if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS)
- qla_printk(KERN_WARNING, ha,
- "Queue delete failed.\n");
- vha->req_ques[0] = ha->req_q_map[0]->id;
- }
-
qla24xx_disable_vp(vha);
fc_remove_host(vha->host);
@@ -1287,6 +1279,12 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
vha->host_no, vha->vp_idx, vha));
}
+ if (ha->mqenable) {
+ if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS)
+ qla_printk(KERN_WARNING, ha,
+ "Queue delete failed.\n");
+ }
+
scsi_host_put(vha->host);
qla_printk(KERN_INFO, ha, "vport %d deleted\n", id);
return 0;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 023ee77fb02..e0c5bb54b25 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2135,6 +2135,7 @@ struct qla_msix_entry {
/* Work events. */
enum qla_work_type {
QLA_EVT_AEN,
+ QLA_EVT_IDC_ACK,
};
@@ -2149,6 +2150,10 @@ struct qla_work_evt {
enum fc_host_event_code code;
u32 data;
} aen;
+ struct {
+#define QLA_IDC_ACK_REGS 7
+ uint16_t mb[QLA_IDC_ACK_REGS];
+ } idc_ack;
} u;
};
diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h
index d78d35e681a..d6ea69df7c5 100644
--- a/drivers/scsi/qla2xxx/qla_devtbl.h
+++ b/drivers/scsi/qla2xxx/qla_devtbl.h
@@ -72,7 +72,7 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = {
"QLA2462", "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */
"QLE2460", "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */
"QLE2462", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x143 */
- "QEM2462" "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */
+ "QEM2462", "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */
"QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */
"QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */
"QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 7abb045a041..ffff4255408 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1402,6 +1402,8 @@ struct access_chip_rsp_84xx {
#define MBA_IDC_NOTIFY 0x8101
#define MBA_IDC_TIME_EXT 0x8102
+#define MBC_IDC_ACK 0x101
+
struct nvram_81xx {
/* NVRAM header. */
uint8_t id[4];
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index ba491335375..6de283f8f11 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -34,6 +34,7 @@ extern void qla24xx_update_fw_options(scsi_qla_host_t *);
extern void qla81xx_update_fw_options(scsi_qla_host_t *);
extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
+extern int qla81xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern int qla2x00_loop_resync(scsi_qla_host_t *);
@@ -71,6 +72,7 @@ extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
fc_host_event_code, u32);
+extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
extern void qla2x00_abort_fcport_cmds(fc_port_t *);
extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
@@ -265,6 +267,8 @@ qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
+extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *);
+
/*
* Global Function Prototypes in qla_isr.c source file.
*/
@@ -375,10 +379,8 @@ extern int qla2x00_dfs_remove(scsi_qla_host_t *);
/* Globa function prototypes for multi-q */
extern int qla25xx_request_irq(struct rsp_que *);
-extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *,
- uint8_t);
-extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *,
- uint8_t);
+extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *);
+extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *);
extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t,
uint16_t, uint8_t, uint8_t);
extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 2d4f32b4df5..87f9abc7146 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1226,9 +1226,8 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
icb->firmware_options_2 |=
__constant_cpu_to_le32(BIT_18);
- icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22);
+ icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22);
icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23);
- ha->rsp_q_map[0]->options = icb->firmware_options_2;
WRT_REG_DWORD(&reg->isp25mq.req_q_in, 0);
WRT_REG_DWORD(&reg->isp25mq.req_q_out, 0);
@@ -1258,35 +1257,48 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
{
int rval;
unsigned long flags = 0;
- int cnt;
+ int cnt, que;
struct qla_hw_data *ha = vha->hw;
- struct req_que *req = ha->req_q_map[0];
- struct rsp_que *rsp = ha->rsp_q_map[0];
+ struct req_que *req;
+ struct rsp_que *rsp;
+ struct scsi_qla_host *vp;
struct mid_init_cb_24xx *mid_init_cb =
(struct mid_init_cb_24xx *) ha->init_cb;
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Clear outstanding commands array. */
- for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
- req->outstanding_cmds[cnt] = NULL;
+ for (que = 0; que < ha->max_queues; que++) {
+ req = ha->req_q_map[que];
+ if (!req)
+ continue;
+ for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
+ req->outstanding_cmds[cnt] = NULL;
- req->current_outstanding_cmd = 0;
+ req->current_outstanding_cmd = 0;
- /* Clear RSCN queue. */
- vha->rscn_in_ptr = 0;
- vha->rscn_out_ptr = 0;
+ /* Initialize firmware. */
+ req->ring_ptr = req->ring;
+ req->ring_index = 0;
+ req->cnt = req->length;
+ }
- /* Initialize firmware. */
- req->ring_ptr = req->ring;
- req->ring_index = 0;
- req->cnt = req->length;
- rsp->ring_ptr = rsp->ring;
- rsp->ring_index = 0;
+ for (que = 0; que < ha->max_queues; que++) {
+ rsp = ha->rsp_q_map[que];
+ if (!rsp)
+ continue;
+ rsp->ring_ptr = rsp->ring;
+ rsp->ring_index = 0;
- /* Initialize response queue entries */
- qla2x00_init_response_q_entries(rsp);
+ /* Initialize response queue entries */
+ qla2x00_init_response_q_entries(rsp);
+ }
+ /* Clear RSCN queue. */
+ list_for_each_entry(vp, &ha->vp_list, list) {
+ vp->rscn_in_ptr = 0;
+ vp->rscn_out_ptr = 0;
+ }
ha->isp_ops->config_rings(vha);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -1296,8 +1308,12 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
DEBUG(printk("scsi(%ld): Issue init firmware.\n", vha->host_no));
- if (ha->flags.npiv_supported)
+ if (ha->flags.npiv_supported) {
+ if (ha->operating_mode == LOOP)
+ ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1;
mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports);
+ }
+
mid_init_cb->options = __constant_cpu_to_le16(BIT_1);
@@ -2598,6 +2614,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
port_id_t wrap, nxt_d_id;
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev);
+ struct scsi_qla_host *tvp;
rval = QLA_SUCCESS;
@@ -2697,7 +2714,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
/* Bypass virtual ports of the same host. */
found = 0;
if (ha->num_vhosts) {
- list_for_each_entry(vp, &ha->vp_list, list) {
+ list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
if (new_fcport->d_id.b24 == vp->d_id.b24) {
found = 1;
break;
@@ -2820,6 +2837,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
uint16_t first_loop_id;
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *vp;
+ struct scsi_qla_host *tvp;
rval = QLA_SUCCESS;
@@ -2844,7 +2862,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
/* Check for loop ID being already in use. */
found = 0;
fcport = NULL;
- list_for_each_entry(vp, &ha->vp_list, list) {
+ list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
list_for_each_entry(fcport, &vp->vp_fcports, list) {
if (fcport->loop_id == dev->loop_id &&
fcport != dev) {
@@ -3212,8 +3230,8 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
int rval = QLA_SUCCESS;
uint32_t wait_time;
struct qla_hw_data *ha = vha->hw;
- struct req_que *req = ha->req_q_map[0];
- struct rsp_que *rsp = ha->rsp_q_map[0];
+ struct req_que *req = ha->req_q_map[vha->req_ques[0]];
+ struct rsp_que *rsp = req->rsp;
atomic_set(&vha->loop_state, LOOP_UPDATE);
clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
@@ -3279,6 +3297,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
uint8_t status = 0;
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *vp;
+ struct scsi_qla_host *tvp;
struct req_que *req = ha->req_q_map[0];
if (vha->flags.online) {
@@ -3294,7 +3313,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(vha, 0);
- list_for_each_entry(vp, &ha->vp_list, list)
+ list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
qla2x00_mark_all_devices_lost(vp, 0);
} else {
if (!atomic_read(&vha->loop_down_timer))
@@ -3391,7 +3410,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
DEBUG(printk(KERN_INFO
"qla2x00_abort_isp(%ld): succeeded.\n",
vha->host_no));
- list_for_each_entry(vp, &ha->vp_list, list) {
+ list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
if (vp->vp_idx)
qla2x00_vp_abort_isp(vp);
}
@@ -3416,7 +3435,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
static int
qla2x00_restart_isp(scsi_qla_host_t *vha)
{
- uint8_t status = 0;
+ int status = 0;
uint32_t wait_time;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0];
@@ -3480,7 +3499,7 @@ qla25xx_init_queues(struct qla_hw_data *ha)
rsp = ha->rsp_q_map[i];
if (rsp) {
rsp->options &= ~BIT_0;
- ret = qla25xx_init_rsp_que(base_vha, rsp, rsp->options);
+ ret = qla25xx_init_rsp_que(base_vha, rsp);
if (ret != QLA_SUCCESS)
DEBUG2_17(printk(KERN_WARNING
"%s Rsp que:%d init failed\n", __func__,
@@ -3492,15 +3511,16 @@ qla25xx_init_queues(struct qla_hw_data *ha)
}
req = ha->req_q_map[i];
if (req) {
+ /* Clear outstanding commands array. */
req->options &= ~BIT_0;
- ret = qla25xx_init_req_que(base_vha, req, req->options);
+ ret = qla25xx_init_req_que(base_vha, req);
if (ret != QLA_SUCCESS)
DEBUG2_17(printk(KERN_WARNING
"%s Req que:%d init failed\n", __func__,
req->id));
else
DEBUG2_17(printk(KERN_WARNING
- "%s Rsp que:%d inited\n", __func__,
+ "%s Req que:%d inited\n", __func__,
req->id));
}
}
@@ -3548,6 +3568,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)
WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
RD_REG_DWORD(&reg->hccr);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+ if (IS_NOPOLLING_TYPE(ha))
+ ha->isp_ops->enable_intrs(ha);
}
/* On sparc systems, obtain port and node WWN from firmware
@@ -3833,6 +3856,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr)
uint32_t i;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0];
+
+ qla_printk(KERN_INFO, ha,
+ "FW: Loading from flash (%x)...\n", ha->flt_region_fw);
+
rval = QLA_SUCCESS;
segments = FA_RISC_CODE_SEGMENTS;
@@ -4008,8 +4035,8 @@ fail_fw_integrity:
return QLA_FUNCTION_FAILED;
}
-int
-qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
+static int
+qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
{
int rval;
int segments, fragment;
@@ -4029,12 +4056,12 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
qla_printk(KERN_ERR, ha, "Firmware images can be retrieved "
"from: " QLA_FW_URL ".\n");
- /* Try to load RISC code from flash. */
- qla_printk(KERN_ERR, ha, "Attempting to load (potentially "
- "outdated) firmware from flash.\n");
- return qla24xx_load_risc_flash(vha, srisc_addr);
+ return QLA_FUNCTION_FAILED;
}
+ qla_printk(KERN_INFO, ha,
+ "FW: Loading via request-firmware...\n");
+
rval = QLA_SUCCESS;
segments = FA_RISC_CODE_SEGMENTS;
@@ -4119,6 +4146,40 @@ fail_fw_integrity:
return QLA_FUNCTION_FAILED;
}
+int
+qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
+{
+ int rval;
+
+ /*
+ * FW Load priority:
+ * 1) Firmware via request-firmware interface (.bin file).
+ * 2) Firmware residing in flash.
+ */
+ rval = qla24xx_load_risc_blob(vha, srisc_addr);
+ if (rval == QLA_SUCCESS)
+ return rval;
+
+ return qla24xx_load_risc_flash(vha, srisc_addr);
+}
+
+int
+qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
+{
+ int rval;
+
+ /*
+ * FW Load priority:
+ * 1) Firmware residing in flash.
+ * 2) Firmware via request-firmware interface (.bin file).
+ */
+ rval = qla24xx_load_risc_flash(vha, srisc_addr);
+ if (rval == QLA_SUCCESS)
+ return rval;
+
+ return qla24xx_load_risc_blob(vha, srisc_addr);
+}
+
void
qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha)
{
@@ -4151,8 +4212,8 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha)
uint16_t mb[MAILBOX_REGISTER_COUNT];
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
- struct req_que *req = ha->req_q_map[0];
- struct rsp_que *rsp = ha->rsp_q_map[0];
+ struct req_que *req = ha->req_q_map[vha->req_ques[0]];
+ struct rsp_que *rsp = req->rsp;
if (!vha->vp_idx)
return -EINVAL;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 789fc576f22..f250e5b7897 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -266,6 +266,40 @@ qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
}
}
+static void
+qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
+{
+ static char *event[] =
+ { "Complete", "Request Notification", "Time Extension" };
+ int rval;
+ struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24;
+ uint16_t __iomem *wptr;
+ uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS];
+
+ /* Seed data -- mailbox1 -> mailbox7. */
+ wptr = (uint16_t __iomem *)&reg24->mailbox1;
+ for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++)
+ mb[cnt] = RD_REG_WORD(wptr);
+
+ DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- "
+ "%04x %04x %04x %04x %04x %04x %04x.\n", vha->host_no,
+ event[aen & 0xff],
+ mb[0], mb[1], mb[2], mb[3], mb[4], mb[5], mb[6]));
+
+ /* Acknowledgement needed? [Notify && non-zero timeout]. */
+ timeout = (descr >> 8) & 0xf;
+ if (aen != MBA_IDC_NOTIFY || !timeout)
+ return;
+
+ DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- "
+ "ACK timeout=%d.\n", vha->host_no, event[aen & 0xff], timeout));
+
+ rval = qla2x00_post_idc_ack_work(vha, mb);
+ if (rval != QLA_SUCCESS)
+ qla_printk(KERN_WARNING, vha->hw,
+ "IDC failed to post ACK.\n");
+}
+
/**
* qla2x00_async_event() - Process aynchronous events.
* @ha: SCSI driver HA context
@@ -714,21 +748,9 @@ skip_rio:
"%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3]));
break;
case MBA_IDC_COMPLETE:
- DEBUG2(printk("scsi(%ld): Inter-Driver Commucation "
- "Complete -- %04x %04x %04x\n", vha->host_no, mb[1], mb[2],
- mb[3]));
- break;
case MBA_IDC_NOTIFY:
- DEBUG2(printk("scsi(%ld): Inter-Driver Commucation "
- "Request Notification -- %04x %04x %04x\n", vha->host_no,
- mb[1], mb[2], mb[3]));
- /**** Mailbox registers 4 - 7 valid!!! */
- break;
case MBA_IDC_TIME_EXT:
- DEBUG2(printk("scsi(%ld): Inter-Driver Commucation "
- "Time Extension -- %04x %04x %04x\n", vha->host_no, mb[1],
- mb[2], mb[3]));
- /**** Mailbox registers 4 - 7 valid!!! */
+ qla81xx_idc_event(vha, mb[0], mb[1]);
break;
}
@@ -1707,7 +1729,6 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
struct qla_hw_data *ha;
struct rsp_que *rsp;
struct device_reg_24xx __iomem *reg;
- uint16_t msix_disabled_hccr = 0;
rsp = (struct rsp_que *) dev_id;
if (!rsp) {
@@ -1720,17 +1741,8 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
spin_lock_irq(&ha->hardware_lock);
- msix_disabled_hccr = rsp->options;
- if (!rsp->id)
- msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22);
- else
- msix_disabled_hccr &= __constant_cpu_to_le32(BIT_6);
-
qla24xx_process_response_queue(rsp);
- if (!msix_disabled_hccr)
- WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
-
spin_unlock_irq(&ha->hardware_lock);
return IRQ_HANDLED;
@@ -1868,6 +1880,7 @@ qla24xx_disable_msix(struct qla_hw_data *ha)
static int
qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
{
+#define MIN_MSIX_COUNT 2
int i, ret;
struct msix_entry *entries;
struct qla_msix_entry *qentry;
@@ -1883,12 +1896,16 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
if (ret) {
+ if (ret < MIN_MSIX_COUNT)
+ goto msix_failed;
+
qla_printk(KERN_WARNING, ha,
"MSI-X: Failed to enable support -- %d/%d\n"
" Retry with %d vectors\n", ha->msix_count, ret, ret);
ha->msix_count = ret;
ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
if (ret) {
+msix_failed:
qla_printk(KERN_WARNING, ha, "MSI-X: Failed to enable"
" support, giving up -- %d/%d\n",
ha->msix_count, ret);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index db4df45234a..4aab7acf752 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -58,14 +58,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
* seconds. This is to serialize actual issuing of mailbox cmds during
* non ISP abort time.
*/
- if (!abort_active) {
- if (!wait_for_completion_timeout(&ha->mbx_cmd_comp,
- mcp->tov * HZ)) {
- /* Timeout occurred. Return error. */
- DEBUG2_3_11(printk("%s(%ld): cmd access timeout. "
- "Exiting.\n", __func__, base_vha->host_no));
- return QLA_FUNCTION_TIMEOUT;
- }
+ if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
+ /* Timeout occurred. Return error. */
+ DEBUG2_3_11(printk("%s(%ld): cmd access timeout. "
+ "Exiting.\n", __func__, base_vha->host_no));
+ return QLA_FUNCTION_TIMEOUT;
}
ha->flags.mbox_busy = 1;
@@ -265,8 +262,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
}
/* Allow next mbx cmd to come in. */
- if (!abort_active)
- complete(&ha->mbx_cmd_comp);
+ complete(&ha->mbx_cmd_comp);
if (rval) {
DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, "
@@ -2689,6 +2685,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *vp;
+ scsi_qla_host_t *tvp;
if (rptid_entry->entry_status != 0)
return;
@@ -2714,7 +2711,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
if (MSB(stat) == 1)
return;
- list_for_each_entry(vp, &ha->vp_list, list)
+ list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
if (vp_idx == vp->vp_idx)
break;
if (!vp)
@@ -3094,8 +3091,7 @@ verify_done:
}
int
-qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
- uint8_t options)
+qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
{
int rval;
unsigned long flags;
@@ -3105,7 +3101,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
struct qla_hw_data *ha = vha->hw;
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
- mcp->mb[1] = options;
+ mcp->mb[1] = req->options;
mcp->mb[2] = MSW(LSD(req->dma));
mcp->mb[3] = LSW(LSD(req->dma));
mcp->mb[6] = MSW(MSD(req->dma));
@@ -3132,7 +3128,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
mcp->tov = 60;
spin_lock_irqsave(&ha->hardware_lock, flags);
- if (!(options & BIT_0)) {
+ if (!(req->options & BIT_0)) {
WRT_REG_DWORD(&reg->req_q_in, 0);
WRT_REG_DWORD(&reg->req_q_out, 0);
}
@@ -3146,8 +3142,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
}
int
-qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
- uint8_t options)
+qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
{
int rval;
unsigned long flags;
@@ -3157,7 +3152,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
struct qla_hw_data *ha = vha->hw;
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
- mcp->mb[1] = options;
+ mcp->mb[1] = rsp->options;
mcp->mb[2] = MSW(LSD(rsp->dma));
mcp->mb[3] = LSW(LSD(rsp->dma));
mcp->mb[6] = MSW(MSD(rsp->dma));
@@ -3182,7 +3177,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
mcp->tov = 60;
spin_lock_irqsave(&ha->hardware_lock, flags);
- if (!(options & BIT_0)) {
+ if (!(rsp->options & BIT_0)) {
WRT_REG_DWORD(&reg->rsp_q_out, 0);
WRT_REG_DWORD(&reg->rsp_q_in, 0);
}
@@ -3197,3 +3192,29 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
return rval;
}
+int
+qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_IDC_ACK;
+ memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
+ mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
+ vha->host_no, rval, mcp->mb[0]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 886323130fc..785c61279e6 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -69,9 +69,10 @@ static scsi_qla_host_t *
qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name)
{
scsi_qla_host_t *vha;
+ struct scsi_qla_host *tvha;
/* Locate matching device in database. */
- list_for_each_entry(vha, &ha->vp_list, list) {
+ list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) {
if (!memcmp(port_name, vha->port_name, WWN_SIZE))
return vha;
}
@@ -194,11 +195,11 @@ qla24xx_configure_vp(scsi_qla_host_t *vha)
void
qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
{
- scsi_qla_host_t *vha;
+ scsi_qla_host_t *vha, *tvha;
struct qla_hw_data *ha = rsp->hw;
int i = 0;
- list_for_each_entry(vha, &ha->vp_list, list) {
+ list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) {
if (vha->vp_idx) {
switch (mb[0]) {
case MBA_LIP_OCCURRED:
@@ -300,6 +301,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
int ret;
struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *vp;
+ struct scsi_qla_host *tvp;
if (vha->vp_idx)
return;
@@ -308,7 +310,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
clear_bit(VP_DPC_NEEDED, &vha->dpc_flags);
- list_for_each_entry(vp, &ha->vp_list, list) {
+ list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
if (vp->vp_idx)
ret = qla2x00_do_dpc_vp(vp);
}
@@ -396,7 +398,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL);
- memset(vha->req_ques, 0, sizeof(vha->req_ques) * QLA_MAX_HOST_QUES);
+ memset(vha->req_ques, 0, sizeof(vha->req_ques));
vha->req_ques[0] = ha->req_q_map[0]->id;
host->can_queue = ha->req_q_map[0]->length + 128;
host->this_id = 255;
@@ -471,7 +473,7 @@ qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req)
if (req) {
req->options |= BIT_0;
- ret = qla25xx_init_req_que(vha, req, req->options);
+ ret = qla25xx_init_req_que(vha, req);
}
if (ret == QLA_SUCCESS)
qla25xx_free_req_que(vha, req);
@@ -486,7 +488,7 @@ qla25xx_delete_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
if (rsp) {
rsp->options |= BIT_0;
- ret = qla25xx_init_rsp_que(vha, rsp, rsp->options);
+ ret = qla25xx_init_rsp_que(vha, rsp);
}
if (ret == QLA_SUCCESS)
qla25xx_free_rsp_que(vha, rsp);
@@ -502,7 +504,7 @@ int qla25xx_update_req_que(struct scsi_qla_host *vha, uint8_t que, uint8_t qos)
req->options |= BIT_3;
req->qos = qos;
- ret = qla25xx_init_req_que(vha, req, req->options);
+ ret = qla25xx_init_req_que(vha, req);
if (ret != QLA_SUCCESS)
DEBUG2_17(printk(KERN_WARNING "%s failed\n", __func__));
/* restore options bit */
@@ -629,9 +631,10 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
req->ring_index = 0;
req->cnt = req->length;
req->id = que_id;
+ req->max_q_depth = ha->req_q_map[0]->max_q_depth;
mutex_unlock(&ha->vport_lock);
- ret = qla25xx_init_req_que(base_vha, req, options);
+ ret = qla25xx_init_req_que(base_vha, req);
if (ret != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha, "%s failed\n", __func__);
mutex_lock(&ha->vport_lock);
@@ -709,7 +712,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
if (ret)
goto que_failed;
- ret = qla25xx_init_rsp_que(base_vha, rsp, options);
+ ret = qla25xx_init_rsp_que(base_vha, rsp);
if (ret != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha, "%s failed\n", __func__);
mutex_lock(&ha->vport_lock);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4a71f522f92..3ddfa889e94 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -65,8 +65,6 @@ MODULE_PARM_DESC(ql2xextended_error_logging,
static void qla2x00_free_device(scsi_qla_host_t *);
-static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);
-
int ql2xfdmienable=1;
module_param(ql2xfdmienable, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xfdmienable,
@@ -800,6 +798,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
if (ha->isp_ops->abort_command(vha, sp, req)) {
DEBUG2(printk("%s(%ld): abort_command "
"mbx failed.\n", __func__, vha->host_no));
+ ret = FAILED;
} else {
DEBUG3(printk("%s(%ld): abort_command "
"mbx success.\n", __func__, vha->host_no));
@@ -1158,8 +1157,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
struct req_que *req;
spin_lock_irqsave(&ha->hardware_lock, flags);
- for (que = 0; que < QLA_MAX_HOST_QUES; que++) {
- req = ha->req_q_map[vha->req_ques[que]];
+ for (que = 0; que < ha->max_queues; que++) {
+ req = ha->req_q_map[que];
if (!req)
continue;
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
@@ -1193,7 +1192,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
scsi_qla_host_t *vha = shost_priv(sdev->host);
struct qla_hw_data *ha = vha->hw;
struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
- struct req_que *req = ha->req_q_map[0];
+ struct req_que *req = ha->req_q_map[vha->req_ques[0]];
if (sdev->tagged_supported)
scsi_activate_tcq(sdev, req->max_q_depth);
@@ -1241,9 +1240,8 @@ qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type)
* supported addressing method.
*/
static void
-qla2x00_config_dma_addressing(scsi_qla_host_t *vha)
+qla2x00_config_dma_addressing(struct qla_hw_data *ha)
{
- struct qla_hw_data *ha = vha->hw;
/* Assume a 32bit DMA mask. */
ha->flags.enable_64bit_addressing = 0;
@@ -1480,7 +1478,7 @@ static struct isp_operations qla81xx_isp_ops = {
.reset_adapter = qla24xx_reset_adapter,
.nvram_config = qla81xx_nvram_config,
.update_fw_options = qla81xx_update_fw_options,
- .load_risc = qla24xx_load_risc,
+ .load_risc = qla81xx_load_risc,
.pci_info_str = qla24xx_pci_info_str,
.fw_version_str = qla24xx_fw_version_str,
.intr_handler = qla24xx_intr_handler,
@@ -1869,6 +1867,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
set_bit(0, (unsigned long *) ha->vp_idx_map);
+ qla2x00_config_dma_addressing(ha);
ret = qla2x00_mem_alloc(ha, req_length, rsp_length, &req, &rsp);
if (!ret) {
qla_printk(KERN_WARNING, ha,
@@ -1888,13 +1887,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
"[ERROR] Failed to allocate memory for scsi_host\n");
ret = -ENOMEM;
+ qla2x00_mem_free(ha);
+ qla2x00_free_que(ha, req, rsp);
goto probe_hw_failed;
}
pci_set_drvdata(pdev, base_vha);
- qla2x00_config_dma_addressing(base_vha);
-
host = base_vha->host;
base_vha->req_ques[0] = req->id;
host->can_queue = req->length + 128;
@@ -1917,14 +1916,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Set up the irqs */
ret = qla2x00_request_irqs(ha, rsp);
if (ret)
- goto probe_failed;
-
+ goto probe_init_failed;
/* Alloc arrays of request and response ring ptrs */
if (!qla2x00_alloc_queues(ha)) {
qla_printk(KERN_WARNING, ha,
"[ERROR] Failed to allocate memory for queue"
" pointers\n");
- goto probe_failed;
+ goto probe_init_failed;
}
ha->rsp_q_map[0] = rsp;
ha->req_q_map[0] = req;
@@ -1997,8 +1995,11 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
-probe_failed:
+probe_init_failed:
qla2x00_free_que(ha, req, rsp);
+ ha->max_queues = 0;
+
+probe_failed:
qla2x00_free_device(base_vha);
scsi_host_put(base_vha->host);
@@ -2221,10 +2222,6 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
{
char name[16];
- ha->init_cb_size = sizeof(init_cb_t);
- if (IS_QLA2XXX_MIDTYPE(ha))
- ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
-
ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
&ha->init_cb_dma, GFP_KERNEL);
if (!ha->init_cb)
@@ -2521,6 +2518,19 @@ qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code,
return qla2x00_post_work(vha, e, 1);
}
+int
+qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
+{
+ struct qla_work_evt *e;
+
+ e = qla2x00_alloc_work(vha, QLA_EVT_IDC_ACK, 1);
+ if (!e)
+ return QLA_FUNCTION_FAILED;
+
+ memcpy(e->u.idc_ack.mb, mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
+ return qla2x00_post_work(vha, e, 1);
+}
+
static void
qla2x00_do_work(struct scsi_qla_host *vha)
{
@@ -2538,6 +2548,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
fc_host_post_event(vha->host, fc_get_event_number(),
e->u.aen.code, e->u.aen.data);
break;
+ case QLA_EVT_IDC_ACK:
+ qla81xx_idc_ack(vha, e->u.idc_ack.mb);
+ break;
}
if (e->flags & QLA_EVT_FLAG_FREE)
kfree(e);
@@ -2551,7 +2564,7 @@ qla2x00_do_work(struct scsi_qla_host *vha)
void qla2x00_relogin(struct scsi_qla_host *vha)
{
fc_port_t *fcport;
- uint8_t status;
+ int status;
uint16_t next_loopid = 0;
struct qla_hw_data *ha = vha->hw;
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 303f8ee11f2..284827926ef 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -684,7 +684,7 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
"end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start,
le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size)));
- switch (le32_to_cpu(region->code)) {
+ switch (le32_to_cpu(region->code) & 0xff) {
case FLT_REG_FW:
ha->flt_region_fw = start;
break;
@@ -944,9 +944,9 @@ qla24xx_unprotect_flash(struct qla_hw_data *ha)
if (!ha->fdt_wrt_disable)
return;
- /* Disable flash write-protection. */
+ /* Disable flash write-protection, first clear SR protection bit */
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
- /* Some flash parts need an additional zero-write to clear bits.*/
+ /* Then write zero again to clear remaining SR bits.*/
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
}
@@ -980,12 +980,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
uint32_t dwords)
{
int ret;
- uint32_t liter, miter;
+ uint32_t liter;
uint32_t sec_mask, rest_addr;
- uint32_t fdata, findex;
+ uint32_t fdata;
dma_addr_t optrom_dma;
void *optrom = NULL;
- uint32_t *s, *d;
struct qla_hw_data *ha = vha->hw;
ret = QLA_SUCCESS;
@@ -1003,17 +1002,15 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
}
rest_addr = (ha->fdt_block_size >> 2) - 1;
- sec_mask = (ha->optrom_size >> 2) - (ha->fdt_block_size >> 2);
+ sec_mask = ~rest_addr;
qla24xx_unprotect_flash(ha);
for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
-
- findex = faddr;
- fdata = (findex & sec_mask) << 2;
+ fdata = (faddr & sec_mask) << 2;
/* Are we at the beginning of a sector? */
- if ((findex & rest_addr) == 0) {
+ if ((faddr & rest_addr) == 0) {
/* Do sector unprotect. */
if (ha->fdt_unprotect_sec_cmd)
qla24xx_write_flash_dword(ha,
@@ -1024,7 +1021,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
(fdata & 0xff00) |((fdata << 16) &
0xff0000) | ((fdata >> 16) & 0xff));
if (ret != QLA_SUCCESS) {
- DEBUG9(qla_printk("Unable to flash sector: "
+ DEBUG9(qla_printk("Unable to erase sector: "
"address=%x.\n", faddr));
break;
}
@@ -1033,9 +1030,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
/* Go with burst-write. */
if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) {
/* Copy data to DMA'ble buffer. */
- for (miter = 0, s = optrom, d = dwptr;
- miter < OPTROM_BURST_DWORDS; miter++, s++, d++)
- *s = cpu_to_le32(*d);
+ memcpy(optrom, dwptr, OPTROM_BURST_SIZE);
ret = qla2x00_load_ram(vha, optrom_dma,
flash_data_addr(ha, faddr),
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 808bab6ef06..a772eab2f0e 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.00-k1"
+#define QLA2XXX_VERSION "8.03.00-k4"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index d6be0762eb9..b586f27c3bd 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -244,6 +244,7 @@ struct ddb_entry {
uint8_t ip_addr[ISCSI_IPADDR_SIZE];
uint8_t iscsi_name[ISCSI_NAME_SIZE]; /* 72 x48 */
uint8_t iscsi_alias[0x20];
+ uint8_t isid[6];
};
/*
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 109c5f5985e..af8c3233e8a 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -342,8 +342,12 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no,
__func__, fw_ddb_index));
list_for_each_entry(ddb_entry, &ha->ddb_list, list) {
- if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name,
- ISCSI_NAME_SIZE) == 0) {
+ if ((memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name,
+ ISCSI_NAME_SIZE) == 0) &&
+ (ddb_entry->tpgt ==
+ le32_to_cpu(fw_ddb_entry->tgt_portal_grp)) &&
+ (memcmp(ddb_entry->isid, fw_ddb_entry->isid,
+ sizeof(ddb_entry->isid)) == 0)) {
found++;
break;
}
@@ -430,6 +434,8 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
ddb_entry->port = le16_to_cpu(fw_ddb_entry->port);
ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
+ memcpy(ddb_entry->isid, fw_ddb_entry->isid, sizeof(ddb_entry->isid));
+
memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0],
min(sizeof(ddb_entry->iscsi_name),
sizeof(fw_ddb_entry->iscsi_name)));
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 42e72a2c1f9..cbcd3f681b6 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -1095,7 +1095,8 @@ EXPORT_SYMBOL(__starget_for_each_device);
* Description: Looks up the scsi_device with the specified @lun for a given
* @starget. The returned scsi_device does not have an additional
* reference. You must hold the host's host_lock over this call and
- * any access to the returned scsi_device.
+ * any access to the returned scsi_device. A scsi_device in state
+ * SDEV_DEL is skipped.
*
* Note: The only reason why drivers should use this is because
* they need to access the device list in irq context. Otherwise you
@@ -1107,6 +1108,8 @@ struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *starget,
struct scsi_device *sdev;
list_for_each_entry(sdev, &starget->devices, same_target_siblings) {
+ if (sdev->sdev_state == SDEV_DEL)
+ continue;
if (sdev->lun ==lun)
return sdev;
}
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 4969e4ec75e..099b5455bbc 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -224,6 +224,7 @@ static struct {
{"SGI", "TP9100", "*", BLIST_REPORTLUN2},
{"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
{"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
+ {"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
{"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36},
{"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN},
{"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 940dc32ff0d..b82ffd90632 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1040,12 +1040,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
action = ACTION_FAIL;
break;
case ABORTED_COMMAND:
+ action = ACTION_FAIL;
if (sshdr.asc == 0x10) { /* DIF */
description = "Target Data Integrity Failure";
- action = ACTION_FAIL;
error = -EILSEQ;
- } else
- action = ACTION_RETRY;
+ }
break;
case NOT_READY:
/* If the device is in the process of becoming
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 66505bb7941..8f4de20c9de 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -317,6 +317,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
return sdev;
out_device_destroy:
+ scsi_device_set_state(sdev, SDEV_DEL);
transport_destroy_device(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
out:
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 5f77417ed58..3ee4eb40abc 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -533,12 +533,8 @@ fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
event->event_code = event_code;
event->event_data = event_data;
- err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
- GFP_KERNEL);
- if (err && (err != -ESRCH)) /* filter no recipient errors */
- /* nlmsg_multicast already kfree_skb'd */
- goto send_fail;
-
+ nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
+ GFP_KERNEL);
return;
send_fail_skb:
@@ -607,12 +603,8 @@ fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
event->event_code = FCH_EVT_VENDOR_UNIQUE;
memcpy(&event->event_data, data_buf, data_len);
- err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
- GFP_KERNEL);
- if (err && (err != -ESRCH)) /* filter no recipient errors */
- /* nlmsg_multicast already kfree_skb'd */
- goto send_vendor_fail;
-
+ nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
+ GFP_KERNEL);
return;
send_vendor_fail_skb:
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 75c9297694c..2adfab8c11c 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -966,15 +966,7 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt)
static int
iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp)
{
- int rc;
-
- rc = netlink_broadcast(nls, skb, 0, 1, gfp);
- if (rc < 0) {
- printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc);
- return rc;
- }
-
- return 0;
+ return netlink_broadcast(nls, skb, 0, 1, gfp);
}
static int
@@ -1207,7 +1199,7 @@ int iscsi_session_event(struct iscsi_cls_session *session,
* the user and when the daemon is restarted it will handle it
*/
rc = iscsi_broadcast_skb(skb, GFP_KERNEL);
- if (rc < 0)
+ if (rc == -ESRCH)
iscsi_cls_session_printk(KERN_ERR, session,
"Cannot notify userspace of session "
"event %u. Check iscsi daemon\n",
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d57566b8be0..4970ae4a62d 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -107,6 +107,7 @@ static void scsi_disk_release(struct device *cdev);
static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
static void sd_print_result(struct scsi_disk *, int);
+static DEFINE_SPINLOCK(sd_index_lock);
static DEFINE_IDA(sd_index_ida);
/* This semaphore is used to mediate the 0->1 reference get in the
@@ -1166,23 +1167,19 @@ sd_spinup_disk(struct scsi_disk *sdkp)
/*
* The device does not want the automatic start to be issued.
*/
- if (sdkp->device->no_start_on_add) {
+ if (sdkp->device->no_start_on_add)
break;
- }
-
- /*
- * If manual intervention is required, or this is an
- * absent USB storage device, a spinup is meaningless.
- */
- if (sense_valid &&
- sshdr.sense_key == NOT_READY &&
- sshdr.asc == 4 && sshdr.ascq == 3) {
- break; /* manual intervention required */
- /*
- * Issue command to spin up drive when not ready
- */
- } else if (sense_valid && sshdr.sense_key == NOT_READY) {
+ if (sense_valid && sshdr.sense_key == NOT_READY) {
+ if (sshdr.asc == 4 && sshdr.ascq == 3)
+ break; /* manual intervention required */
+ if (sshdr.asc == 4 && sshdr.ascq == 0xb)
+ break; /* standby */
+ if (sshdr.asc == 4 && sshdr.ascq == 0xc)
+ break; /* unavailable */
+ /*
+ * Issue command to spin up drive when not ready
+ */
if (!spintime) {
sd_printk(KERN_NOTICE, sdkp, "Spinning up disk...");
cmd[0] = START_STOP;
@@ -1914,7 +1911,9 @@ static int sd_probe(struct device *dev)
if (!ida_pre_get(&sd_index_ida, GFP_KERNEL))
goto out_put;
+ spin_lock(&sd_index_lock);
error = ida_get_new(&sd_index_ida, &index);
+ spin_unlock(&sd_index_lock);
} while (error == -EAGAIN);
if (error)
@@ -1936,7 +1935,9 @@ static int sd_probe(struct device *dev)
return 0;
out_free_index:
+ spin_lock(&sd_index_lock);
ida_remove(&sd_index_ida, index);
+ spin_unlock(&sd_index_lock);
out_put:
put_disk(gd);
out_free:
@@ -1986,7 +1987,9 @@ static void scsi_disk_release(struct device *dev)
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct gendisk *disk = sdkp->disk;
+ spin_lock(&sd_index_lock);
ida_remove(&sd_index_ida, sdkp->index);
+ spin_unlock(&sd_index_lock);
disk->private_data = NULL;
put_disk(disk);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 8f0bd3f7a59..b4ef2f84ea3 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1078,7 +1078,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
case BLKTRACESETUP:
return blk_trace_setup(sdp->device->request_queue,
sdp->disk->disk_name,
- sdp->device->sdev_gendev.devt,
+ MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
(char *)arg);
case BLKTRACESTART:
return blk_trace_startstop(sdp->device->request_queue, 1);
@@ -1154,7 +1154,6 @@ sg_poll(struct file *filp, poll_table * wait)
static int
sg_fasync(int fd, struct file *filp, int mode)
{
- int retval;
Sg_device *sdp;
Sg_fd *sfp;
@@ -1163,8 +1162,7 @@ sg_fasync(int fd, struct file *filp, int mode)
SCSI_LOG_TIMEOUT(3, printk("sg_fasync: %s, mode=%d\n",
sdp->disk->disk_name, mode));
- retval = fasync_helper(fd, filp, mode, &sfp->async_qp);
- return (retval < 0) ? retval : 0;
+ return fasync_helper(fd, filp, mode, &sfp->async_qp);
}
static int
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
index a8d61a62522..97f3158fa7b 100644
--- a/drivers/scsi/zalon.c
+++ b/drivers/scsi/zalon.c
@@ -137,7 +137,7 @@ zalon_probe(struct parisc_device *dev)
goto fail;
if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) {
- dev_printk(KERN_ERR, dev, "irq problem with %d, detaching\n ",
+ dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching\n ",
dev->irq);
goto fail;
}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0d934bfbdd9..b4b39811b44 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2083,6 +2083,20 @@ static int serial8250_startup(struct uart_port *port)
serial8250_set_mctrl(&up->port, up->port.mctrl);
+ /* Serial over Lan (SoL) hack:
+ Intel 8257x Gigabit ethernet chips have a
+ 16550 emulation, to be used for Serial Over Lan.
+ Those chips take a longer time than a normal
+ serial device to signalize that a transmission
+ data was queued. Due to that, the above test generally
+ fails. One solution would be to delay the reading of
+ iir. However, this is not reliable, since the timeout
+ is variable. So, let's just don't test if we receive
+ TX irq. This way, we'll never enable UART_BUG_TXEN.
+ */
+ if (up->port.flags & UPF_NO_TXEN_TEST)
+ goto dont_test_tx_en;
+
/*
* Do a quick test to see if we receive an
* interrupt when we enable the TX irq.
@@ -2102,6 +2116,7 @@ static int serial8250_startup(struct uart_port *port)
up->bugs &= ~UART_BUG_TXEN;
}
+dont_test_tx_en:
spin_unlock_irqrestore(&up->port.lock, flags);
/*
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 2a3671233b1..533f82025ad 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -798,6 +798,21 @@ pci_default_setup(struct serial_private *priv,
return setup_port(priv, port, bar, offset, board->reg_shift);
}
+static int skip_tx_en_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_port *port, int idx)
+{
+ port->flags |= UPF_NO_TXEN_TEST;
+ printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
+ "[%04x:%04x] subsystem [%04x:%04x]\n",
+ priv->dev->vendor,
+ priv->dev->device,
+ priv->dev->subsystem_vendor,
+ priv->dev->subsystem_device);
+
+ return pci_default_setup(priv, board, port, idx);
+}
+
/* This should be in linux/pci_ids.h */
#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
@@ -806,6 +821,8 @@ pci_default_setup(struct serial_private *priv,
#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208
#define PCI_SUBDEVICE_ID_POCTAL232 0x0308
#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
+#define PCI_VENDOR_ID_ADVANTECH 0x13fe
+#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@@ -862,6 +879,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.init = pci_inteli960ni_init,
.setup = pci_default_setup,
},
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_8257X_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82573L_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82573E_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
/*
* ITE
*/
@@ -2152,6 +2190,10 @@ static int pciserial_resume_one(struct pci_dev *dev)
#endif
static struct pci_device_id serial_pci_tbl[] = {
+ /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
+ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
+ PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0,
+ pbn_b2_8_921600 },
{ PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 3e525e38a5d..7d7f576da20 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -982,7 +982,7 @@ config SERIAL_SH_SCI_CONSOLE
config SERIAL_PNX8XXX
bool "Enable PNX8XXX SoCs' UART Support"
- depends on MIPS && SOC_PNX8550
+ depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
select SERIAL_CORE
help
If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 89362d733d6..8f58f7ff0dd 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -877,6 +877,10 @@ static int atmel_startup(struct uart_port *port)
}
}
+ /* Save current CSR for comparison in atmel_tasklet_func() */
+ atmel_port->irq_status_prev = UART_GET_CSR(port);
+ atmel_port->irq_status = atmel_port->irq_status_prev;
+
/*
* Finally, enable the serial port
*/
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index 338cf8a08b4..ac79cbe4c2c 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -84,6 +84,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
brd->pci_dev = pdev;
if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM)
brd->maxports = 4;
+ else if (pdev->device == PCI_DEVICE_ID_DIGI_NEO_8)
+ brd->maxports = 8;
else
brd->maxports = 2;
@@ -180,7 +182,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
}
-static void jsm_remove_one(struct pci_dev *pdev)
+static void __devexit jsm_remove_one(struct pci_dev *pdev)
{
struct jsm_board *brd = pci_get_drvdata(pdev);
int i = 0;
@@ -212,6 +214,7 @@ static struct pci_device_id jsm_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 },
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 },
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 },
+ { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_NEO_8), 0, 0, 5 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, jsm_pci_tbl);
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 3547558d2ca..324c74d2f66 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -161,6 +161,11 @@ static void jsm_tty_stop_rx(struct uart_port *port)
channel->ch_bd->bd_ops->disable_receiver(channel);
}
+static void jsm_tty_enable_ms(struct uart_port *port)
+{
+ /* Nothing needed */
+}
+
static void jsm_tty_break(struct uart_port *port, int break_state)
{
unsigned long lock_flags;
@@ -345,6 +350,7 @@ static struct uart_ops jsm_ops = {
.start_tx = jsm_tty_start_tx,
.send_xchar = jsm_tty_send_xchar,
.stop_rx = jsm_tty_stop_rx,
+ .enable_ms = jsm_tty_enable_ms,
.break_ctl = jsm_tty_break,
.startup = jsm_tty_open,
.shutdown = jsm_tty_close,
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index b2001c5b145..56841fe5f48 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -212,10 +212,18 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
{
unsigned long flags;
unsigned int baud, baudclk;
+#if defined(CONFIG_M5272)
+ unsigned int baudfr;
+#endif
unsigned char mr1, mr2;
baud = uart_get_baud_rate(port, termios, old, 0, 230400);
+#if defined(CONFIG_M5272)
+ baudclk = (MCF_BUSCLK / baud) / 32;
+ baudfr = (((MCF_BUSCLK / baud) + 1) / 2) % 16;
+#else
baudclk = ((MCF_BUSCLK / baud) + 16) / 32;
+#endif
mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR;
mr2 = 0;
@@ -262,6 +270,9 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
writeb(mr2, port->membase + MCFUART_UMR);
writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1);
writeb((baudclk & 0xff), port->membase + MCFUART_UBG2);
+#if defined(CONFIG_M5272)
+ writeb((baudfr & 0x0f), port->membase + MCFUART_UFPD);
+#endif
writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER,
port->membase + MCFUART_UCSR);
writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index a821e3a3d66..14f8fa9135b 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -163,6 +163,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = {
{ .type = "serial", .compatible = "ns16450", .data = (void *)PORT_16450, },
{ .type = "serial", .compatible = "ns16550", .data = (void *)PORT_16550, },
{ .type = "serial", .compatible = "ns16750", .data = (void *)PORT_16750, },
+ { .type = "serial", .compatible = "ns16850", .data = (void *)PORT_16850, },
#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
{ .type = "serial", .compatible = "ibm,qpace-nwp-serial",
.data = (void *)PORT_NWPSERIAL, },
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 557b54ab2f2..dbf5357a77b 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -139,7 +139,7 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
} while (!(status & SCxSR_TDxE(port)));
sci_in(port, SCxSR); /* Dummy read */
- sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+ sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
sci_out(port, SCxTDR, c);
}
#endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
@@ -263,6 +263,7 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786) || \
defined(CONFIG_CPU_SUBTYPE_SHX3)
static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
{
@@ -284,7 +285,8 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
- defined(CONFIG_CPU_SUBTYPE_SH7785)
+ defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786)
static inline int scif_txroom(struct uart_port *port)
{
return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
@@ -1095,6 +1097,7 @@ static void serial_console_write(struct console *co, const char *s,
unsigned count)
{
struct uart_port *port = &serial_console_port->port;
+ unsigned short bits;
int i;
for (i = 0; i < count; i++) {
@@ -1103,6 +1106,11 @@ static void serial_console_write(struct console *co, const char *s,
sci_poll_put_char(port, *s++);
}
+
+ /* wait until fifo is empty and last bit has been transmitted */
+ bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
+ while ((sci_in(port, SCxSR) & bits) != bits)
+ cpu_relax();
}
static int __init serial_console_setup(struct console *co, char *options)
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 38c600c0dbb..d0aa82d7fce 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -1,6 +1,6 @@
#include <linux/serial_core.h>
#include <asm/io.h>
-#include <asm/gpio.h>
+#include <linux/gpio.h>
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
#include <asm/regs306x.h>
@@ -32,7 +32,9 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
-#define SCIF_ORER 0x0200 /* overrun error bit */
+# define PORT_PTCR 0xA405011EUL
+# define PORT_PVCR 0xA4050122UL
+# define SCIF_ORER 0x0200 /* overrun error bit */
#elif defined(CONFIG_SH_RTS7751R2D)
# define SCSPTR1 0xFFE0001C /* 8 bit SCIF */
# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
@@ -124,14 +126,15 @@
# define SCSPTR1 0xffe10024 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7785)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786)
# define SCSPTR0 0xffea0024 /* 16 bit SCIF */
# define SCSPTR1 0xffeb0024 /* 16 bit SCIF */
# define SCSPTR2 0xffec0024 /* 16 bit SCIF */
# define SCSPTR3 0xffed0024 /* 16 bit SCIF */
# define SCSPTR4 0xffee0024 /* 16 bit SCIF */
# define SCSPTR5 0xffef0024 /* 16 bit SCIF */
-# define SCIF_OPER 0x0001 /* Overrun error bit */
+# define SCIF_ORER 0x0001 /* Overrun error bit */
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
defined(CONFIG_CPU_SUBTYPE_SH7203) || \
@@ -180,6 +183,7 @@
defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786) || \
defined(CONFIG_CPU_SUBTYPE_SHX3)
#define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */
#else
@@ -393,6 +397,7 @@ SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16)
SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8)
SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16)
SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8)
+SCIx_FNS(SCSPTR, 0, 0, 0, 0)
SCIF_FNS(SCTDSR, 0x0c, 8)
SCIF_FNS(SCFER, 0x10, 16)
SCIF_FNS(SCFCR, 0x18, 16)
@@ -410,7 +415,8 @@ SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
- defined(CONFIG_CPU_SUBTYPE_SH7785)
+ defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786)
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
@@ -641,7 +647,8 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
return 1;
}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7785)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786)
static inline int sci_rxd_in(struct uart_port *port)
{
if (port->mapbase == 0xffea0000)
@@ -743,7 +750,8 @@ static inline int sci_rxd_in(struct uart_port *port)
*/
#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
- defined(CONFIG_CPU_SUBTYPE_SH7785)
+ defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786)
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 45a299f3561..e09d3cebb4f 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1438,12 +1438,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
} else {
printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) "
"is a %s\n",
- op->dev.bus_id,
+ dev_name(&op->dev),
(unsigned long long) up[0].port.mapbase,
op->irqs[0], sunzilog_type(&up[0].port));
printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) "
"is a %s\n",
- op->dev.bus_id,
+ dev_name(&op->dev),
(unsigned long long) up[1].port.mapbase,
op->irqs[0], sunzilog_type(&up[1].port));
kbm_inst++;
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 58d24c5a76c..2269fbcaa18 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -568,6 +568,10 @@ static void __init intc_register_irq(struct intc_desc *desc,
if (!data[0] && data[1])
primary = 1;
+ if (!data[0] && !data[1])
+ pr_warning("intc: missing unique irq mask for "
+ "irq %d (vect 0x%04x)\n", irq, irq2evt(irq));
+
data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1);
data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1);
@@ -641,6 +645,17 @@ static unsigned int __init save_reg(struct intc_desc_int *d,
return 0;
}
+static unsigned char *intc_evt2irq_table;
+
+unsigned int intc_evt2irq(unsigned int vector)
+{
+ unsigned int irq = evt2irq(vector);
+
+ if (intc_evt2irq_table && intc_evt2irq_table[irq])
+ irq = intc_evt2irq_table[irq];
+
+ return irq;
+}
void __init register_intc_controller(struct intc_desc *desc)
{
@@ -705,9 +720,41 @@ void __init register_intc_controller(struct intc_desc *desc)
BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
+ /* keep the first vector only if same enum is used multiple times */
+ for (i = 0; i < desc->nr_vectors; i++) {
+ struct intc_vect *vect = desc->vectors + i;
+ int first_irq = evt2irq(vect->vect);
+
+ if (!vect->enum_id)
+ continue;
+
+ for (k = i + 1; k < desc->nr_vectors; k++) {
+ struct intc_vect *vect2 = desc->vectors + k;
+
+ if (vect->enum_id != vect2->enum_id)
+ continue;
+
+ vect2->enum_id = 0;
+
+ if (!intc_evt2irq_table)
+ intc_evt2irq_table = alloc_bootmem(NR_IRQS);
+
+ if (!intc_evt2irq_table) {
+ pr_warning("intc: cannot allocate evt2irq!\n");
+ continue;
+ }
+
+ intc_evt2irq_table[evt2irq(vect2->vect)] = first_irq;
+ }
+ }
+
+ /* register the vectors one by one */
for (i = 0; i < desc->nr_vectors; i++) {
struct intc_vect *vect = desc->vectors + i;
+ if (!vect->enum_id)
+ continue;
+
intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect));
}
}
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 63f0de29aa1..cab1ab7cfb7 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -1,16 +1,10 @@
/*
* Core maple bus functionality
*
- * Copyright (C) 2007, 2008 Adrian McMenamin
+ * Copyright (C) 2007 - 2009 Adrian McMenamin
* Copyright (C) 2001 - 2008 Paul Mundt
- *
- * Based on 2.4 code by:
- *
- * Copyright (C) 2000-2001 YAEGASHI Takeshi
+ * Copyright (C) 2000 - 2001 YAEGASHI Takeshi
* Copyright (C) 2001 M. R. Brown
- * Copyright (C) 2001 Paul Mundt
- *
- * and others.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -32,7 +26,7 @@
#include <mach/dma.h>
#include <mach/sysasic.h>
-MODULE_AUTHOR("Yaegashi Takeshi, Paul Mundt, M. R. Brown, Adrian McMenamin");
+MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
MODULE_DESCRIPTION("Maple bus driver for Dreamcast");
MODULE_LICENSE("GPL v2");
MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}");
@@ -49,7 +43,7 @@ static LIST_HEAD(maple_sentq);
/* mutex to protect queue of waiting packets */
static DEFINE_MUTEX(maple_wlist_lock);
-static struct maple_driver maple_dummy_driver;
+static struct maple_driver maple_unsupported_device;
static struct device maple_bus;
static int subdevice_map[MAPLE_PORTS];
static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr;
@@ -62,8 +56,9 @@ struct maple_device_specify {
int unit;
};
-static bool checked[4];
-static struct maple_device *baseunits[4];
+static bool checked[MAPLE_PORTS];
+static bool empty[MAPLE_PORTS];
+static struct maple_device *baseunits[MAPLE_PORTS];
/**
* maple_driver_register - register a maple driver
@@ -97,12 +92,20 @@ void maple_driver_unregister(struct maple_driver *drv)
EXPORT_SYMBOL_GPL(maple_driver_unregister);
/* set hardware registers to enable next round of dma */
-static void maplebus_dma_reset(void)
+static void maple_dma_reset(void)
{
ctrl_outl(MAPLE_MAGIC, MAPLE_RESET);
/* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */
ctrl_outl(1, MAPLE_TRIGTYPE);
- ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(50000), MAPLE_SPEED);
+ /*
+ * Maple system register
+ * bits 31 - 16 timeout in units of 20nsec
+ * bit 12 hard trigger - set 0 to keep responding to VBLANK
+ * bits 9 - 8 set 00 for 2 Mbps, 01 for 1 Mbps
+ * bits 3 - 0 delay (in 1.3ms) between VBLANK and start of DMA
+ * max delay is 11
+ */
+ ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(0xFFFF), MAPLE_SPEED);
ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR);
ctrl_outl(1, MAPLE_ENABLE);
}
@@ -134,21 +137,16 @@ static void maple_release_device(struct device *dev)
{
struct maple_device *mdev;
struct mapleq *mq;
- if (!dev)
- return;
+
mdev = to_maple_dev(dev);
mq = mdev->mq;
- if (mq) {
- if (mq->recvbufdcsp)
- kmem_cache_free(maple_queue_cache, mq->recvbufdcsp);
- kfree(mq);
- mq = NULL;
- }
+ kmem_cache_free(maple_queue_cache, mq->recvbuf);
+ kfree(mq);
kfree(mdev);
}
/**
- * maple_add_packet - add a single instruction to the queue
+ * maple_add_packet - add a single instruction to the maple bus queue
* @mdev: maple device
* @function: function on device being queried
* @command: maple command to add
@@ -158,68 +156,12 @@ static void maple_release_device(struct device *dev)
int maple_add_packet(struct maple_device *mdev, u32 function, u32 command,
size_t length, void *data)
{
- int locking, ret = 0;
+ int ret = 0;
void *sendbuf = NULL;
- mutex_lock(&maple_wlist_lock);
- /* bounce if device already locked */
- locking = mutex_is_locked(&mdev->mq->mutex);
- if (locking) {
- ret = -EBUSY;
- goto out;
- }
-
- mutex_lock(&mdev->mq->mutex);
-
if (length) {
- sendbuf = kmalloc(length * 4, GFP_KERNEL);
+ sendbuf = kzalloc(length * 4, GFP_KERNEL);
if (!sendbuf) {
- mutex_unlock(&mdev->mq->mutex);
- ret = -ENOMEM;
- goto out;
- }
- ((__be32 *)sendbuf)[0] = cpu_to_be32(function);
- }
-
- mdev->mq->command = command;
- mdev->mq->length = length;
- if (length > 1)
- memcpy(sendbuf + 4, data, (length - 1) * 4);
- mdev->mq->sendbuf = sendbuf;
-
- list_add(&mdev->mq->list, &maple_waitq);
-out:
- mutex_unlock(&maple_wlist_lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(maple_add_packet);
-
-/**
- * maple_add_packet_sleeps - add a single instruction to the queue
- * @mdev: maple device
- * @function: function on device being queried
- * @command: maple command to add
- * @length: length of command string (in 32 bit words)
- * @data: remainder of command string
- *
- * Same as maple_add_packet(), but waits for the lock to become free.
- */
-int maple_add_packet_sleeps(struct maple_device *mdev, u32 function,
- u32 command, size_t length, void *data)
-{
- int locking, ret = 0;
- void *sendbuf = NULL;
-
- locking = mutex_lock_interruptible(&mdev->mq->mutex);
- if (locking) {
- ret = -EIO;
- goto out;
- }
-
- if (length) {
- sendbuf = kmalloc(length * 4, GFP_KERNEL);
- if (!sendbuf) {
- mutex_unlock(&mdev->mq->mutex);
ret = -ENOMEM;
goto out;
}
@@ -233,38 +175,35 @@ int maple_add_packet_sleeps(struct maple_device *mdev, u32 function,
mdev->mq->sendbuf = sendbuf;
mutex_lock(&maple_wlist_lock);
- list_add(&mdev->mq->list, &maple_waitq);
+ list_add_tail(&mdev->mq->list, &maple_waitq);
mutex_unlock(&maple_wlist_lock);
out:
return ret;
}
-EXPORT_SYMBOL_GPL(maple_add_packet_sleeps);
+EXPORT_SYMBOL_GPL(maple_add_packet);
static struct mapleq *maple_allocq(struct maple_device *mdev)
{
struct mapleq *mq;
- mq = kmalloc(sizeof(*mq), GFP_KERNEL);
+ mq = kzalloc(sizeof(*mq), GFP_KERNEL);
if (!mq)
goto failed_nomem;
+ INIT_LIST_HEAD(&mq->list);
mq->dev = mdev;
- mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL);
- mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp);
+ mq->recvbuf = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL);
if (!mq->recvbuf)
goto failed_p2;
- /*
- * most devices do not need the mutex - but
- * anything that injects block reads or writes
- * will rely on it
- */
- mutex_init(&mq->mutex);
+ mq->recvbuf->buf = &((mq->recvbuf->bufx)[0]);
return mq;
failed_p2:
kfree(mq);
failed_nomem:
+ dev_err(&mdev->dev, "could not allocate memory for device (%d, %d)\n",
+ mdev->port, mdev->unit);
return NULL;
}
@@ -272,12 +211,16 @@ static struct maple_device *maple_alloc_dev(int port, int unit)
{
struct maple_device *mdev;
+ /* zero this out to avoid kobj subsystem
+ * thinking it has already been registered */
+
mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev)
return NULL;
mdev->port = port;
mdev->unit = unit;
+
mdev->mq = maple_allocq(mdev);
if (!mdev->mq) {
@@ -286,19 +229,14 @@ static struct maple_device *maple_alloc_dev(int port, int unit)
}
mdev->dev.bus = &maple_bus_type;
mdev->dev.parent = &maple_bus;
+ init_waitqueue_head(&mdev->maple_wait);
return mdev;
}
static void maple_free_dev(struct maple_device *mdev)
{
- if (!mdev)
- return;
- if (mdev->mq) {
- if (mdev->mq->recvbufdcsp)
- kmem_cache_free(maple_queue_cache,
- mdev->mq->recvbufdcsp);
- kfree(mdev->mq);
- }
+ kmem_cache_free(maple_queue_cache, mdev->mq->recvbuf);
+ kfree(mdev->mq);
kfree(mdev);
}
@@ -320,7 +258,7 @@ static void maple_build_block(struct mapleq *mq)
maple_lastptr = maple_sendptr;
*maple_sendptr++ = (port << 16) | len | 0x80000000;
- *maple_sendptr++ = PHYSADDR(mq->recvbuf);
+ *maple_sendptr++ = PHYSADDR(mq->recvbuf->buf);
*maple_sendptr++ =
mq->command | (to << 8) | (from << 16) | (len << 24);
while (len-- > 0)
@@ -333,20 +271,28 @@ static void maple_send(void)
int i, maple_packets = 0;
struct mapleq *mq, *nmq;
- if (!list_empty(&maple_sentq))
+ if (!maple_dma_done())
return;
+
+ /* disable DMA */
+ ctrl_outl(0, MAPLE_ENABLE);
+
+ if (!list_empty(&maple_sentq))
+ goto finish;
+
mutex_lock(&maple_wlist_lock);
- if (list_empty(&maple_waitq) || !maple_dma_done()) {
+ if (list_empty(&maple_waitq)) {
mutex_unlock(&maple_wlist_lock);
- return;
+ goto finish;
}
- mutex_unlock(&maple_wlist_lock);
+
maple_lastptr = maple_sendbuf;
maple_sendptr = maple_sendbuf;
- mutex_lock(&maple_wlist_lock);
+
list_for_each_entry_safe(mq, nmq, &maple_waitq, list) {
maple_build_block(mq);
- list_move(&mq->list, &maple_sentq);
+ list_del_init(&mq->list);
+ list_add_tail(&mq->list, &maple_sentq);
if (maple_packets++ > MAPLE_MAXPACKETS)
break;
}
@@ -356,10 +302,13 @@ static void maple_send(void)
dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE,
PAGE_SIZE, DMA_BIDIRECTIONAL);
}
+
+finish:
+ maple_dma_reset();
}
/* check if there is a driver registered likely to match this device */
-static int check_matching_maple_driver(struct device_driver *driver,
+static int maple_check_matching_driver(struct device_driver *driver,
void *devptr)
{
struct maple_driver *maple_drv;
@@ -374,10 +323,7 @@ static int check_matching_maple_driver(struct device_driver *driver,
static void maple_detach_driver(struct maple_device *mdev)
{
- if (!mdev)
- return;
device_unregister(&mdev->dev);
- mdev = NULL;
}
/* process initial MAPLE_COMMAND_DEVINFO for each device or port */
@@ -385,9 +331,9 @@ static void maple_attach_driver(struct maple_device *mdev)
{
char *p, *recvbuf;
unsigned long function;
- int matched, retval;
+ int matched, error;
- recvbuf = mdev->mq->recvbuf;
+ recvbuf = mdev->mq->recvbuf->buf;
/* copy the data as individual elements in
* case of memory optimisation */
memcpy(&mdev->devinfo.function, recvbuf + 4, 4);
@@ -395,7 +341,6 @@ static void maple_attach_driver(struct maple_device *mdev)
memcpy(&mdev->devinfo.area_code, recvbuf + 20, 1);
memcpy(&mdev->devinfo.connector_direction, recvbuf + 21, 1);
memcpy(&mdev->devinfo.product_name[0], recvbuf + 22, 30);
- memcpy(&mdev->devinfo.product_licence[0], recvbuf + 52, 60);
memcpy(&mdev->devinfo.standby_power, recvbuf + 112, 2);
memcpy(&mdev->devinfo.max_power, recvbuf + 114, 2);
memcpy(mdev->product_name, mdev->devinfo.product_name, 30);
@@ -414,43 +359,39 @@ static void maple_attach_driver(struct maple_device *mdev)
else
break;
- printk(KERN_INFO "Maple device detected: %s\n",
- mdev->product_name);
- printk(KERN_INFO "Maple device: %s\n", mdev->product_licence);
-
function = be32_to_cpu(mdev->devinfo.function);
+ dev_info(&mdev->dev, "detected %s: function 0x%lX: at (%d, %d)\n",
+ mdev->product_name, function, mdev->port, mdev->unit);
+
if (function > 0x200) {
/* Do this silently - as not a real device */
function = 0;
- mdev->driver = &maple_dummy_driver;
- sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port);
+ mdev->driver = &maple_unsupported_device;
+ dev_set_name(&mdev->dev, "%d:0.port", mdev->port);
} else {
- printk(KERN_INFO
- "Maple bus at (%d, %d): Function 0x%lX\n",
- mdev->port, mdev->unit, function);
-
matched =
bus_for_each_drv(&maple_bus_type, NULL, mdev,
- check_matching_maple_driver);
+ maple_check_matching_driver);
if (matched == 0) {
/* Driver does not exist yet */
- printk(KERN_INFO
- "No maple driver found.\n");
- mdev->driver = &maple_dummy_driver;
+ dev_info(&mdev->dev, "no driver found\n");
+ mdev->driver = &maple_unsupported_device;
}
- sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port,
- mdev->unit, function);
+ dev_set_name(&mdev->dev, "%d:0%d.%lX", mdev->port,
+ mdev->unit, function);
}
+
mdev->function = function;
mdev->dev.release = &maple_release_device;
- retval = device_register(&mdev->dev);
- if (retval) {
- printk(KERN_INFO
- "Maple bus: Attempt to register device"
- " (%x, %x) failed.\n",
- mdev->port, mdev->unit);
+
+ atomic_set(&mdev->busy, 0);
+ error = device_register(&mdev->dev);
+ if (error) {
+ dev_warn(&mdev->dev, "could not register device at"
+ " (%d, %d), with error 0x%X\n", mdev->unit,
+ mdev->port, error);
maple_free_dev(mdev);
mdev = NULL;
return;
@@ -462,7 +403,7 @@ static void maple_attach_driver(struct maple_device *mdev)
* port and unit then return 1 - allows identification
* of which devices need to be attached or detached
*/
-static int detach_maple_device(struct device *device, void *portptr)
+static int check_maple_device(struct device *device, void *portptr)
{
struct maple_device_specify *ds;
struct maple_device *mdev;
@@ -477,21 +418,25 @@ static int detach_maple_device(struct device *device, void *portptr)
static int setup_maple_commands(struct device *device, void *ignored)
{
int add;
- struct maple_device *maple_dev = to_maple_dev(device);
-
- if ((maple_dev->interval > 0)
- && time_after(jiffies, maple_dev->when)) {
- /* bounce if we cannot lock */
- add = maple_add_packet(maple_dev,
- be32_to_cpu(maple_dev->devinfo.function),
+ struct maple_device *mdev = to_maple_dev(device);
+ if (mdev->interval > 0 && atomic_read(&mdev->busy) == 0 &&
+ time_after(jiffies, mdev->when)) {
+ /* bounce if we cannot add */
+ add = maple_add_packet(mdev,
+ be32_to_cpu(mdev->devinfo.function),
MAPLE_COMMAND_GETCOND, 1, NULL);
if (!add)
- maple_dev->when = jiffies + maple_dev->interval;
+ mdev->when = jiffies + mdev->interval;
} else {
if (time_after(jiffies, maple_pnp_time))
- /* This will also bounce */
- maple_add_packet(maple_dev, 0,
- MAPLE_COMMAND_DEVINFO, 0, NULL);
+ /* Ensure we don't have block reads and devinfo
+ * calls interfering with one another - so flag the
+ * device as busy */
+ if (atomic_read(&mdev->busy) == 0) {
+ atomic_set(&mdev->busy, 1);
+ maple_add_packet(mdev, 0,
+ MAPLE_COMMAND_DEVINFO, 0, NULL);
+ }
}
return 0;
}
@@ -499,29 +444,50 @@ static int setup_maple_commands(struct device *device, void *ignored)
/* VBLANK bottom half - implemented via workqueue */
static void maple_vblank_handler(struct work_struct *work)
{
- if (!list_empty(&maple_sentq) || !maple_dma_done())
+ int x, locking;
+ struct maple_device *mdev;
+
+ if (!maple_dma_done())
return;
ctrl_outl(0, MAPLE_ENABLE);
+ if (!list_empty(&maple_sentq))
+ goto finish;
+
+ /*
+ * Set up essential commands - to fetch data and
+ * check devices are still present
+ */
bus_for_each_dev(&maple_bus_type, NULL, NULL,
- setup_maple_commands);
+ setup_maple_commands);
+
+ if (time_after(jiffies, maple_pnp_time)) {
+ /*
+ * Scan the empty ports - bus is flakey and may have
+ * mis-reported emptyness
+ */
+ for (x = 0; x < MAPLE_PORTS; x++) {
+ if (checked[x] && empty[x]) {
+ mdev = baseunits[x];
+ if (!mdev)
+ break;
+ atomic_set(&mdev->busy, 1);
+ locking = maple_add_packet(mdev, 0,
+ MAPLE_COMMAND_DEVINFO, 0, NULL);
+ if (!locking)
+ break;
+ }
+ }
- if (time_after(jiffies, maple_pnp_time))
maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL;
-
- mutex_lock(&maple_wlist_lock);
- if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) {
- mutex_unlock(&maple_wlist_lock);
- maple_send();
- } else {
- mutex_unlock(&maple_wlist_lock);
}
- maplebus_dma_reset();
+finish:
+ maple_send();
}
-/* handle devices added via hotplugs - placing them on queue for DEVINFO*/
+/* handle devices added via hotplugs - placing them on queue for DEVINFO */
static void maple_map_subunits(struct maple_device *mdev, int submask)
{
int retval, k, devcheck;
@@ -533,7 +499,7 @@ static void maple_map_subunits(struct maple_device *mdev, int submask)
ds.unit = k + 1;
retval =
bus_for_each_dev(&maple_bus_type, NULL, &ds,
- detach_maple_device);
+ check_maple_device);
if (retval) {
submask = submask >> 1;
continue;
@@ -543,6 +509,7 @@ static void maple_map_subunits(struct maple_device *mdev, int submask)
mdev_add = maple_alloc_dev(mdev->port, k + 1);
if (!mdev_add)
return;
+ atomic_set(&mdev_add->busy, 1);
maple_add_packet(mdev_add, 0, MAPLE_COMMAND_DEVINFO,
0, NULL);
/* mark that we are checking sub devices */
@@ -564,27 +531,45 @@ static void maple_clean_submap(struct maple_device *mdev)
}
/* handle empty port or hotplug removal */
-static void maple_response_none(struct maple_device *mdev,
- struct mapleq *mq)
-{
- if (mdev->unit != 0) {
- list_del(&mq->list);
- maple_clean_submap(mdev);
- printk(KERN_INFO
- "Maple bus device detaching at (%d, %d)\n",
- mdev->port, mdev->unit);
+static void maple_response_none(struct maple_device *mdev)
+{
+ maple_clean_submap(mdev);
+
+ if (likely(mdev->unit != 0)) {
+ /*
+ * Block devices play up
+ * and give the impression they have
+ * been removed even when still in place or
+ * trip the mtd layer when they have
+ * really gone - this code traps that eventuality
+ * and ensures we aren't overloaded with useless
+ * error messages
+ */
+ if (mdev->can_unload) {
+ if (!mdev->can_unload(mdev)) {
+ atomic_set(&mdev->busy, 2);
+ wake_up(&mdev->maple_wait);
+ return;
+ }
+ }
+
+ dev_info(&mdev->dev, "detaching device at (%d, %d)\n",
+ mdev->port, mdev->unit);
maple_detach_driver(mdev);
return;
- }
- if (!started || !fullscan) {
- if (checked[mdev->port] == false) {
- checked[mdev->port] = true;
- printk(KERN_INFO "No maple devices attached"
- " to port %d\n", mdev->port);
+ } else {
+ if (!started || !fullscan) {
+ if (checked[mdev->port] == false) {
+ checked[mdev->port] = true;
+ empty[mdev->port] = true;
+ dev_info(&mdev->dev, "no devices"
+ " to port %d\n", mdev->port);
+ }
+ return;
}
- return;
}
- maple_clean_submap(mdev);
+ /* Some hardware devices generate false detach messages on unit 0 */
+ atomic_set(&mdev->busy, 0);
}
/* preprocess hotplugs or scans */
@@ -599,8 +584,11 @@ static void maple_response_devinfo(struct maple_device *mdev,
} else {
if (mdev->unit != 0)
maple_attach_driver(mdev);
+ if (mdev->unit == 0) {
+ empty[mdev->port] = false;
+ maple_attach_driver(mdev);
+ }
}
- return;
}
if (mdev->unit == 0) {
submask = recvbuf[2] & 0x1F;
@@ -611,6 +599,17 @@ static void maple_response_devinfo(struct maple_device *mdev,
}
}
+static void maple_response_fileerr(struct maple_device *mdev, void *recvbuf)
+{
+ if (mdev->fileerr_handler) {
+ mdev->fileerr_handler(mdev, recvbuf);
+ return;
+ } else
+ dev_warn(&mdev->dev, "device at (%d, %d) reports"
+ "file error 0x%X\n", mdev->port, mdev->unit,
+ ((int *)recvbuf)[1]);
+}
+
static void maple_port_rescan(void)
{
int i;
@@ -621,12 +620,6 @@ static void maple_port_rescan(void)
if (checked[i] == false) {
fullscan = 0;
mdev = baseunits[i];
- /*
- * test lock in case scan has failed
- * but device is still locked
- */
- if (mutex_is_locked(&mdev->mq->mutex))
- mutex_unlock(&mdev->mq->mutex);
maple_add_packet(mdev, 0, MAPLE_COMMAND_DEVINFO,
0, NULL);
}
@@ -637,7 +630,7 @@ static void maple_port_rescan(void)
static void maple_dma_handler(struct work_struct *work)
{
struct mapleq *mq, *nmq;
- struct maple_device *dev;
+ struct maple_device *mdev;
char *recvbuf;
enum maple_code code;
@@ -646,43 +639,56 @@ static void maple_dma_handler(struct work_struct *work)
ctrl_outl(0, MAPLE_ENABLE);
if (!list_empty(&maple_sentq)) {
list_for_each_entry_safe(mq, nmq, &maple_sentq, list) {
- recvbuf = mq->recvbuf;
+ mdev = mq->dev;
+ recvbuf = mq->recvbuf->buf;
+ dma_cache_sync(&mdev->dev, recvbuf, 0x400,
+ DMA_FROM_DEVICE);
code = recvbuf[0];
- dev = mq->dev;
kfree(mq->sendbuf);
- mutex_unlock(&mq->mutex);
list_del_init(&mq->list);
-
switch (code) {
case MAPLE_RESPONSE_NONE:
- maple_response_none(dev, mq);
+ maple_response_none(mdev);
break;
case MAPLE_RESPONSE_DEVINFO:
- maple_response_devinfo(dev, recvbuf);
+ maple_response_devinfo(mdev, recvbuf);
+ atomic_set(&mdev->busy, 0);
break;
case MAPLE_RESPONSE_DATATRF:
- if (dev->callback)
- dev->callback(mq);
+ if (mdev->callback)
+ mdev->callback(mq);
+ atomic_set(&mdev->busy, 0);
+ wake_up(&mdev->maple_wait);
break;
case MAPLE_RESPONSE_FILEERR:
+ maple_response_fileerr(mdev, recvbuf);
+ atomic_set(&mdev->busy, 0);
+ wake_up(&mdev->maple_wait);
+ break;
+
case MAPLE_RESPONSE_AGAIN:
case MAPLE_RESPONSE_BADCMD:
case MAPLE_RESPONSE_BADFUNC:
- printk(KERN_DEBUG
- "Maple non-fatal error 0x%X\n",
- code);
+ dev_warn(&mdev->dev, "non-fatal error"
+ " 0x%X at (%d, %d)\n", code,
+ mdev->port, mdev->unit);
+ atomic_set(&mdev->busy, 0);
break;
case MAPLE_RESPONSE_ALLINFO:
- printk(KERN_DEBUG
- "Maple - extended device information"
- " not supported\n");
+ dev_notice(&mdev->dev, "extended"
+ " device information request for (%d, %d)"
+ " but call is not supported\n", mdev->port,
+ mdev->unit);
+ atomic_set(&mdev->busy, 0);
break;
case MAPLE_RESPONSE_OK:
+ atomic_set(&mdev->busy, 0);
+ wake_up(&mdev->maple_wait);
break;
default:
@@ -699,20 +705,19 @@ static void maple_dma_handler(struct work_struct *work)
if (!fullscan)
maple_port_rescan();
/* mark that we have been through the first scan */
- if (started == 0)
- started = 1;
+ started = 1;
}
- maplebus_dma_reset();
+ maple_send();
}
-static irqreturn_t maplebus_dma_interrupt(int irq, void *dev_id)
+static irqreturn_t maple_dma_interrupt(int irq, void *dev_id)
{
/* Load everything into the bottom half */
schedule_work(&maple_dma_process);
return IRQ_HANDLED;
}
-static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id)
+static irqreturn_t maple_vblank_interrupt(int irq, void *dev_id)
{
schedule_work(&maple_vblank_process);
return IRQ_HANDLED;
@@ -720,14 +725,14 @@ static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id)
static int maple_set_dma_interrupt_handler(void)
{
- return request_irq(HW_EVENT_MAPLE_DMA, maplebus_dma_interrupt,
- IRQF_SHARED, "maple bus DMA", &maple_dummy_driver);
+ return request_irq(HW_EVENT_MAPLE_DMA, maple_dma_interrupt,
+ IRQF_SHARED, "maple bus DMA", &maple_unsupported_device);
}
static int maple_set_vblank_interrupt_handler(void)
{
- return request_irq(HW_EVENT_VSYNC, maplebus_vblank_interrupt,
- IRQF_SHARED, "maple bus VBLANK", &maple_dummy_driver);
+ return request_irq(HW_EVENT_VSYNC, maple_vblank_interrupt,
+ IRQF_SHARED, "maple bus VBLANK", &maple_unsupported_device);
}
static int maple_get_dma_buffer(void)
@@ -740,7 +745,7 @@ static int maple_get_dma_buffer(void)
return 0;
}
-static int match_maple_bus_driver(struct device *devptr,
+static int maple_match_bus_driver(struct device *devptr,
struct device_driver *drvptr)
{
struct maple_driver *maple_drv = to_maple_driver(drvptr);
@@ -765,22 +770,24 @@ static void maple_bus_release(struct device *dev)
{
}
-static struct maple_driver maple_dummy_driver = {
+static struct maple_driver maple_unsupported_device = {
.drv = {
- .name = "maple_dummy_driver",
+ .name = "maple_unsupported_device",
.bus = &maple_bus_type,
},
};
-
+/**
+ * maple_bus_type - core maple bus structure
+ */
struct bus_type maple_bus_type = {
.name = "maple",
- .match = match_maple_bus_driver,
+ .match = maple_match_bus_driver,
.uevent = maple_bus_uevent,
};
EXPORT_SYMBOL_GPL(maple_bus_type);
static struct device maple_bus = {
- .bus_id = "maple",
+ .init_name = "maple",
.release = maple_bus_release,
};
@@ -788,7 +795,8 @@ static int __init maple_bus_init(void)
{
int retval, i;
struct maple_device *mdev[MAPLE_PORTS];
- ctrl_outl(0, MAPLE_STATE);
+
+ ctrl_outl(0, MAPLE_ENABLE);
retval = device_register(&maple_bus);
if (retval)
@@ -798,36 +806,33 @@ static int __init maple_bus_init(void)
if (retval)
goto cleanup_device;
- retval = driver_register(&maple_dummy_driver.drv);
+ retval = driver_register(&maple_unsupported_device.drv);
if (retval)
goto cleanup_bus;
/* allocate memory for maple bus dma */
retval = maple_get_dma_buffer();
if (retval) {
- printk(KERN_INFO
- "Maple bus: Failed to allocate Maple DMA buffers\n");
+ dev_err(&maple_bus, "failed to allocate DMA buffers\n");
goto cleanup_basic;
}
/* set up DMA interrupt handler */
retval = maple_set_dma_interrupt_handler();
if (retval) {
- printk(KERN_INFO
- "Maple bus: Failed to grab maple DMA IRQ\n");
+ dev_err(&maple_bus, "bus failed to grab maple "
+ "DMA IRQ\n");
goto cleanup_dma;
}
/* set up VBLANK interrupt handler */
retval = maple_set_vblank_interrupt_handler();
if (retval) {
- printk(KERN_INFO "Maple bus: Failed to grab VBLANK IRQ\n");
+ dev_err(&maple_bus, "bus failed to grab VBLANK IRQ\n");
goto cleanup_irq;
}
- maple_queue_cache =
- kmem_cache_create("maple_queue_cache", 0x400, 0,
- SLAB_HWCACHE_ALIGN, NULL);
+ maple_queue_cache = KMEM_CACHE(maple_buffer, SLAB_HWCACHE_ALIGN);
if (!maple_queue_cache)
goto cleanup_bothirqs;
@@ -838,23 +843,23 @@ static int __init maple_bus_init(void)
/* setup maple ports */
for (i = 0; i < MAPLE_PORTS; i++) {
checked[i] = false;
+ empty[i] = false;
mdev[i] = maple_alloc_dev(i, 0);
- baseunits[i] = mdev[i];
if (!mdev[i]) {
while (i-- > 0)
maple_free_dev(mdev[i]);
goto cleanup_cache;
}
+ baseunits[i] = mdev[i];
+ atomic_set(&mdev[i]->busy, 1);
maple_add_packet(mdev[i], 0, MAPLE_COMMAND_DEVINFO, 0, NULL);
subdevice_map[i] = 0;
}
- /* setup maplebus hardware */
- maplebus_dma_reset();
- /* initial detection */
+ maple_pnp_time = jiffies + HZ;
+ /* prepare initial queue */
maple_send();
- maple_pnp_time = jiffies;
- printk(KERN_INFO "Maple bus core now registered.\n");
+ dev_info(&maple_bus, "bus core now registered\n");
return 0;
@@ -871,7 +876,7 @@ cleanup_dma:
free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES);
cleanup_basic:
- driver_unregister(&maple_dummy_driver.drv);
+ driver_unregister(&maple_unsupported_device.drv);
cleanup_bus:
bus_unregister(&maple_bus_type);
@@ -880,7 +885,7 @@ cleanup_device:
device_unregister(&maple_bus);
cleanup:
- printk(KERN_INFO "Maple bus registration failed\n");
+ printk(KERN_ERR "Maple bus registration failed\n");
return retval;
}
/* Push init to later to ensure hardware gets detected */
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index 4d0282b821b..2d9e7f3d561 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -22,7 +22,7 @@
static int superhyway_devices;
static struct device superhyway_bus_device = {
- .bus_id = "superhyway",
+ .init_name = "superhyway",
};
static void superhyway_device_release(struct device *dev)
@@ -83,7 +83,7 @@ int superhyway_add_device(unsigned long base, struct superhyway_device *sdev,
dev->id.id = dev->vcr.mod_id;
sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
- sprintf(dev->dev.bus_id, "%02x", superhyway_devices);
+ dev_set_name(&dev->dev, "%02x", superhyway_devices);
superhyway_devices++;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 4a6fe01831a..83a185d5296 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -230,17 +230,6 @@ config SPI_XILINX
#
comment "SPI Protocol Masters"
-config SPI_AT25
- tristate "SPI EEPROMs from most vendors"
- depends on SYSFS
- help
- Enable this driver to get read/write support to most SPI EEPROMs,
- after you configure the board init code to know about each eeprom
- on your target board.
-
- This driver can also be built as a module. If so, the module
- will be called at25.
-
config SPI_SPIDEV
tristate "User mode SPI device driver support"
depends on EXPERIMENTAL
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 5e9f521b884..5d0451936d8 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
# ... add above this line ...
# SPI protocol drivers (device/link on bus)
-obj-$(CONFIG_SPI_AT25) += at25.o
obj-$(CONFIG_SPI_SPIDEV) += spidev.o
obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o
# ... add above this line ...
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 56ff3e6864e..12e443cc4ac 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -322,7 +322,7 @@ static void atmel_spi_next_message(struct spi_master *master)
spi = msg->spi;
dev_dbg(master->dev.parent, "start message %p for %s\n",
- msg, spi->dev.bus_id);
+ msg, dev_name(&spi->dev));
/* select chip if it's not still active */
if (as->stay) {
@@ -627,7 +627,7 @@ static int atmel_spi_setup(struct spi_device *spi)
if (!asd)
return -ENOMEM;
- ret = gpio_request(npcs_pin, spi->dev.bus_id);
+ ret = gpio_request(npcs_pin, dev_name(&spi->dev));
if (ret) {
kfree(asd);
return ret;
@@ -668,7 +668,7 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
as = spi_master_get_devdata(spi->master);
dev_dbg(controller, "new message %p submitted for %s\n",
- msg, spi->dev.bus_id);
+ msg, dev_name(&spi->dev));
if (unlikely(list_empty(&msg->transfers)))
return -EINVAL;
@@ -803,7 +803,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev)
as->clk = clk;
ret = request_irq(irq, atmel_spi_interrupt, 0,
- pdev->dev.bus_id, master);
+ dev_name(&pdev->dev), master);
if (ret)
goto out_unmap_regs;
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 3b97803e1d1..68c77a91159 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -429,7 +429,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
INIT_LIST_HEAD(&mps->queue);
mps->workqueue = create_singlethread_workqueue(
- master->dev.parent->bus_id);
+ dev_name(master->dev.parent));
if (mps->workqueue == NULL) {
ret = -EBUSY;
goto free_irq;
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 454a2712e62..1c65e380c84 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -1003,7 +1003,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
goto err1;
}
if (!request_mem_region(r->start, (r->end - r->start) + 1,
- pdev->dev.bus_id)) {
+ dev_name(&pdev->dev))) {
status = -EBUSY;
goto err1;
}
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index bab6ff061e9..60b5381c65c 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -245,7 +245,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
#ifdef VERBOSE
pr_debug("%s: write-%d =%04x\n",
- spi->dev.bus_id, bits, val);
+ dev_name(&spi->dev), bits, val);
#endif
if (wait_uwire_csr_flag(CSRB, 0, 0))
goto eio;
@@ -305,7 +305,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
status += bytes;
#ifdef VERBOSE
pr_debug("%s: read-%d =%04x\n",
- spi->dev.bus_id, bits, val);
+ dev_name(&spi->dev), bits, val);
#endif
}
@@ -331,7 +331,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
uwire = spi_master_get_devdata(spi->master);
if (spi->chip_select > 3) {
- pr_debug("%s: cs%d?\n", spi->dev.bus_id, spi->chip_select);
+ pr_debug("%s: cs%d?\n", dev_name(&spi->dev), spi->chip_select);
status = -ENODEV;
goto done;
}
@@ -343,7 +343,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
bits = 8;
if (bits > 16) {
- pr_debug("%s: wordsize %d?\n", spi->dev.bus_id, bits);
+ pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits);
status = -ENODEV;
goto done;
}
@@ -378,7 +378,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
hz = t->speed_hz;
if (!hz) {
- pr_debug("%s: zero speed?\n", spi->dev.bus_id);
+ pr_debug("%s: zero speed?\n", dev_name(&spi->dev));
status = -EINVAL;
goto done;
}
@@ -406,7 +406,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
}
if (div1_idx == 4) {
pr_debug("%s: lowest clock %ld, need %d\n",
- spi->dev.bus_id, rate / 10 / 8, hz);
+ dev_name(&spi->dev), rate / 10 / 8, hz);
status = -EDOM;
goto done;
}
diff --git a/drivers/spi/orion_spi.c b/drivers/spi/orion_spi.c
index 014becb7d53..c8b0babdc2a 100644
--- a/drivers/spi/orion_spi.c
+++ b/drivers/spi/orion_spi.c
@@ -496,7 +496,7 @@ static int __init orion_spi_probe(struct platform_device *pdev)
}
if (!request_mem_region(r->start, (r->end - r->start) + 1,
- pdev->dev.bus_id)) {
+ dev_name(&pdev->dev))) {
status = -EBUSY;
goto out;
}
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index d0fc4ca2f65..ec24f2d16f3 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -1333,7 +1333,7 @@ static int __init init_queue(struct driver_data *drv_data)
INIT_WORK(&drv_data->pump_messages, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
- drv_data->master->dev.parent->bus_id);
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;
@@ -1462,7 +1462,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR;
}
- status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data);
+ status = request_irq(ssp->irq, ssp_int, 0, dev_name(dev), drv_data);
if (status < 0) {
dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq);
goto out_error_master_alloc;
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 7fea3cf4588..3410b0c55ed 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1160,8 +1160,8 @@ static inline int init_queue(struct driver_data *drv_data)
/* init messages workqueue */
INIT_WORK(&drv_data->pump_messages, pump_messages);
- drv_data->workqueue =
- create_singlethread_workqueue(drv_data->master->dev.parent->bus_id);
+ drv_data->workqueue = create_singlethread_workqueue(
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;
diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c
index 49698cabc30..d2866c293de 100644
--- a/drivers/spi/spi_gpio.c
+++ b/drivers/spi/spi_gpio.c
@@ -114,7 +114,7 @@ static inline void setmosi(const struct spi_device *spi, int is_on)
static inline int getmiso(const struct spi_device *spi)
{
- return gpio_get_value(SPI_MISO_GPIO);
+ return !!gpio_get_value(SPI_MISO_GPIO);
}
#undef pdata
@@ -191,7 +191,7 @@ static int spi_gpio_setup(struct spi_device *spi)
return -EINVAL;
if (!spi->controller_state) {
- status = gpio_request(cs, spi->dev.bus_id);
+ status = gpio_request(cs, dev_name(&spi->dev));
if (status)
return status;
status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 269a55ec52e..0480d8bb19d 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1381,7 +1381,7 @@ static int __init init_queue(struct driver_data *drv_data)
INIT_WORK(&drv_data->work, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
- drv_data->master->dev.parent->bus_id);
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;
@@ -1525,7 +1525,8 @@ static int __init spi_imx_probe(struct platform_device *pdev)
status = -ENODEV;
goto err_no_irqres;
}
- status = request_irq(irq, spi_int, IRQF_DISABLED, dev->bus_id, drv_data);
+ status = request_irq(irq, spi_int, IRQF_DISABLED,
+ dev_name(dev), drv_data);
if (status < 0) {
dev_err(&pdev->dev, "probe - cannot get IRQ (%d)\n", status);
goto err_no_irqres;
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index ac0e3e4b3c5..44a2b46ccb7 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -637,7 +637,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
INIT_LIST_HEAD(&mpc83xx_spi->queue);
mpc83xx_spi->workqueue = create_singlethread_workqueue(
- master->dev.parent->bus_id);
+ dev_name(master->dev.parent));
if (mpc83xx_spi->workqueue == NULL) {
ret = -EBUSY;
goto free_irq;
@@ -649,7 +649,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
printk(KERN_INFO
"%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
- dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq);
+ dev_name(&dev->dev), mpc83xx_spi->base, mpc83xx_spi->irq);
return ret;
diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c
index 2296f37ea3c..29cbb065618 100644
--- a/drivers/spi/spi_txx9.c
+++ b/drivers/spi/spi_txx9.c
@@ -404,7 +404,8 @@ static int __init txx9spi_probe(struct platform_device *dev)
if (ret)
goto exit;
- c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id);
+ c->workqueue = create_singlethread_workqueue(
+ dev_name(master->dev.parent));
if (!c->workqueue)
goto exit_busy;
c->last_chipselect = -1;
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index 6f255e9c5af..cfbb74f2982 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -9,6 +9,7 @@ ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o
# built-in drivers
ssb-y += driver_chipcommon.o
+ssb-y += driver_chipcommon_pmu.o
ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o
ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c
index 2d27d6d6d08..27a677584a4 100644
--- a/drivers/ssb/b43_pci_bridge.c
+++ b/drivers/ssb/b43_pci_bridge.c
@@ -21,6 +21,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4307) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4311) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
@@ -29,6 +30,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4329) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl);
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 571f4fd5523..9681536163c 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -26,19 +26,6 @@ enum ssb_clksrc {
};
-static inline u32 chipco_read32(struct ssb_chipcommon *cc,
- u16 offset)
-{
- return ssb_read32(cc->dev, offset);
-}
-
-static inline void chipco_write32(struct ssb_chipcommon *cc,
- u16 offset,
- u32 value)
-{
- ssb_write32(cc->dev, offset, value);
-}
-
static inline u32 chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset,
u32 mask, u32 value)
{
@@ -246,6 +233,7 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
{
if (!cc->dev)
return; /* We don't have a ChipCommon */
+ ssb_pmu_init(cc);
chipco_powercontrol_init(cc);
ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
calc_fast_powerup_delay(cc);
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
new file mode 100644
index 00000000000..4aaddeec55a
--- /dev/null
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -0,0 +1,508 @@
+/*
+ * Sonics Silicon Backplane
+ * Broadcom ChipCommon Power Management Unit driver
+ *
+ * Copyright 2009, Michael Buesch <mb@bu3sch.de>
+ * Copyright 2007, Broadcom Corporation
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <linux/ssb/ssb.h>
+#include <linux/ssb/ssb_regs.h>
+#include <linux/ssb/ssb_driver_chipcommon.h>
+#include <linux/delay.h>
+
+#include "ssb_private.h"
+
+static u32 ssb_chipco_pll_read(struct ssb_chipcommon *cc, u32 offset)
+{
+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_ADDR, offset);
+ return chipco_read32(cc, SSB_CHIPCO_PLLCTL_DATA);
+}
+
+static void ssb_chipco_pll_write(struct ssb_chipcommon *cc,
+ u32 offset, u32 value)
+{
+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_ADDR, offset);
+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value);
+}
+
+struct pmu0_plltab_entry {
+ u16 freq; /* Crystal frequency in kHz.*/
+ u8 xf; /* Crystal frequency value for PMU control */
+ u8 wb_int;
+ u32 wb_frac;
+};
+
+static const struct pmu0_plltab_entry pmu0_plltab[] = {
+ { .freq = 12000, .xf = 1, .wb_int = 73, .wb_frac = 349525, },
+ { .freq = 13000, .xf = 2, .wb_int = 67, .wb_frac = 725937, },
+ { .freq = 14400, .xf = 3, .wb_int = 61, .wb_frac = 116508, },
+ { .freq = 15360, .xf = 4, .wb_int = 57, .wb_frac = 305834, },
+ { .freq = 16200, .xf = 5, .wb_int = 54, .wb_frac = 336579, },
+ { .freq = 16800, .xf = 6, .wb_int = 52, .wb_frac = 399457, },
+ { .freq = 19200, .xf = 7, .wb_int = 45, .wb_frac = 873813, },
+ { .freq = 19800, .xf = 8, .wb_int = 44, .wb_frac = 466033, },
+ { .freq = 20000, .xf = 9, .wb_int = 44, .wb_frac = 0, },
+ { .freq = 25000, .xf = 10, .wb_int = 70, .wb_frac = 419430, },
+ { .freq = 26000, .xf = 11, .wb_int = 67, .wb_frac = 725937, },
+ { .freq = 30000, .xf = 12, .wb_int = 58, .wb_frac = 699050, },
+ { .freq = 38400, .xf = 13, .wb_int = 45, .wb_frac = 873813, },
+ { .freq = 40000, .xf = 14, .wb_int = 45, .wb_frac = 0, },
+};
+#define SSB_PMU0_DEFAULT_XTALFREQ 20000
+
+static const struct pmu0_plltab_entry * pmu0_plltab_find_entry(u32 crystalfreq)
+{
+ const struct pmu0_plltab_entry *e;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(pmu0_plltab); i++) {
+ e = &pmu0_plltab[i];
+ if (e->freq == crystalfreq)
+ return e;
+ }
+
+ return NULL;
+}
+
+/* Tune the PLL to the crystal speed. crystalfreq is in kHz. */
+static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc,
+ u32 crystalfreq)
+{
+ struct ssb_bus *bus = cc->dev->bus;
+ const struct pmu0_plltab_entry *e = NULL;
+ u32 pmuctl, tmp, pllctl;
+ unsigned int i;
+
+ if ((bus->chip_id == 0x5354) && !crystalfreq) {
+ /* The 5354 crystal freq is 25MHz */
+ crystalfreq = 25000;
+ }
+ if (crystalfreq)
+ e = pmu0_plltab_find_entry(crystalfreq);
+ if (!e)
+ e = pmu0_plltab_find_entry(SSB_PMU0_DEFAULT_XTALFREQ);
+ BUG_ON(!e);
+ crystalfreq = e->freq;
+ cc->pmu.crystalfreq = e->freq;
+
+ /* Check if the PLL already is programmed to this frequency. */
+ pmuctl = chipco_read32(cc, SSB_CHIPCO_PMU_CTL);
+ if (((pmuctl & SSB_CHIPCO_PMU_CTL_XTALFREQ) >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT) == e->xf) {
+ /* We're already there... */
+ return;
+ }
+
+ ssb_printk(KERN_INFO PFX "Programming PLL to %u.%03u MHz\n",
+ (crystalfreq / 1000), (crystalfreq % 1000));
+
+ /* First turn the PLL off. */
+ switch (bus->chip_id) {
+ case 0x4328:
+ chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK,
+ ~(1 << SSB_PMURES_4328_BB_PLL_PU));
+ chipco_mask32(cc, SSB_CHIPCO_PMU_MAXRES_MSK,
+ ~(1 << SSB_PMURES_4328_BB_PLL_PU));
+ break;
+ case 0x5354:
+ chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK,
+ ~(1 << SSB_PMURES_5354_BB_PLL_PU));
+ chipco_mask32(cc, SSB_CHIPCO_PMU_MAXRES_MSK,
+ ~(1 << SSB_PMURES_5354_BB_PLL_PU));
+ break;
+ default:
+ SSB_WARN_ON(1);
+ }
+ for (i = 1500; i; i--) {
+ tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST);
+ if (!(tmp & SSB_CHIPCO_CLKCTLST_HAVEHT))
+ break;
+ udelay(10);
+ }
+ tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST);
+ if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT)
+ ssb_printk(KERN_EMERG PFX "Failed to turn the PLL off!\n");
+
+ /* Set PDIV in PLL control 0. */
+ pllctl = ssb_chipco_pll_read(cc, SSB_PMU0_PLLCTL0);
+ if (crystalfreq >= SSB_PMU0_PLLCTL0_PDIV_FREQ)
+ pllctl |= SSB_PMU0_PLLCTL0_PDIV_MSK;
+ else
+ pllctl &= ~SSB_PMU0_PLLCTL0_PDIV_MSK;
+ ssb_chipco_pll_write(cc, SSB_PMU0_PLLCTL0, pllctl);
+
+ /* Set WILD in PLL control 1. */
+ pllctl = ssb_chipco_pll_read(cc, SSB_PMU0_PLLCTL1);
+ pllctl &= ~SSB_PMU0_PLLCTL1_STOPMOD;
+ pllctl &= ~(SSB_PMU0_PLLCTL1_WILD_IMSK | SSB_PMU0_PLLCTL1_WILD_FMSK);
+ pllctl |= ((u32)e->wb_int << SSB_PMU0_PLLCTL1_WILD_IMSK_SHIFT) & SSB_PMU0_PLLCTL1_WILD_IMSK;
+ pllctl |= ((u32)e->wb_frac << SSB_PMU0_PLLCTL1_WILD_FMSK_SHIFT) & SSB_PMU0_PLLCTL1_WILD_FMSK;
+ if (e->wb_frac == 0)
+ pllctl |= SSB_PMU0_PLLCTL1_STOPMOD;
+ ssb_chipco_pll_write(cc, SSB_PMU0_PLLCTL1, pllctl);
+
+ /* Set WILD in PLL control 2. */
+ pllctl = ssb_chipco_pll_read(cc, SSB_PMU0_PLLCTL2);
+ pllctl &= ~SSB_PMU0_PLLCTL2_WILD_IMSKHI;
+ pllctl |= (((u32)e->wb_int >> 4) << SSB_PMU0_PLLCTL2_WILD_IMSKHI_SHIFT) & SSB_PMU0_PLLCTL2_WILD_IMSKHI;
+ ssb_chipco_pll_write(cc, SSB_PMU0_PLLCTL2, pllctl);
+
+ /* Set the crystalfrequency and the divisor. */
+ pmuctl = chipco_read32(cc, SSB_CHIPCO_PMU_CTL);
+ pmuctl &= ~SSB_CHIPCO_PMU_CTL_ILP_DIV;
+ pmuctl |= (((crystalfreq + 127) / 128 - 1) << SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT)
+ & SSB_CHIPCO_PMU_CTL_ILP_DIV;
+ pmuctl &= ~SSB_CHIPCO_PMU_CTL_XTALFREQ;
+ pmuctl |= ((u32)e->xf << SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT) & SSB_CHIPCO_PMU_CTL_XTALFREQ;
+ chipco_write32(cc, SSB_CHIPCO_PMU_CTL, pmuctl);
+}
+
+struct pmu1_plltab_entry {
+ u16 freq; /* Crystal frequency in kHz.*/
+ u8 xf; /* Crystal frequency value for PMU control */
+ u8 ndiv_int;
+ u32 ndiv_frac;
+ u8 p1div;
+ u8 p2div;
+};
+
+static const struct pmu1_plltab_entry pmu1_plltab[] = {
+ { .freq = 12000, .xf = 1, .p1div = 3, .p2div = 22, .ndiv_int = 0x9, .ndiv_frac = 0xFFFFEF, },
+ { .freq = 13000, .xf = 2, .p1div = 1, .p2div = 6, .ndiv_int = 0xb, .ndiv_frac = 0x483483, },
+ { .freq = 14400, .xf = 3, .p1div = 1, .p2div = 10, .ndiv_int = 0xa, .ndiv_frac = 0x1C71C7, },
+ { .freq = 15360, .xf = 4, .p1div = 1, .p2div = 5, .ndiv_int = 0xb, .ndiv_frac = 0x755555, },
+ { .freq = 16200, .xf = 5, .p1div = 1, .p2div = 10, .ndiv_int = 0x5, .ndiv_frac = 0x6E9E06, },
+ { .freq = 16800, .xf = 6, .p1div = 1, .p2div = 10, .ndiv_int = 0x5, .ndiv_frac = 0x3CF3CF, },
+ { .freq = 19200, .xf = 7, .p1div = 1, .p2div = 9, .ndiv_int = 0x5, .ndiv_frac = 0x17B425, },
+ { .freq = 19800, .xf = 8, .p1div = 1, .p2div = 11, .ndiv_int = 0x4, .ndiv_frac = 0xA57EB, },
+ { .freq = 20000, .xf = 9, .p1div = 1, .p2div = 11, .ndiv_int = 0x4, .ndiv_frac = 0, },
+ { .freq = 24000, .xf = 10, .p1div = 3, .p2div = 11, .ndiv_int = 0xa, .ndiv_frac = 0, },
+ { .freq = 25000, .xf = 11, .p1div = 5, .p2div = 16, .ndiv_int = 0xb, .ndiv_frac = 0, },
+ { .freq = 26000, .xf = 12, .p1div = 1, .p2div = 2, .ndiv_int = 0x10, .ndiv_frac = 0xEC4EC4, },
+ { .freq = 30000, .xf = 13, .p1div = 3, .p2div = 8, .ndiv_int = 0xb, .ndiv_frac = 0, },
+ { .freq = 38400, .xf = 14, .p1div = 1, .p2div = 5, .ndiv_int = 0x4, .ndiv_frac = 0x955555, },
+ { .freq = 40000, .xf = 15, .p1div = 1, .p2div = 2, .ndiv_int = 0xb, .ndiv_frac = 0, },
+};
+
+#define SSB_PMU1_DEFAULT_XTALFREQ 15360
+
+static const struct pmu1_plltab_entry * pmu1_plltab_find_entry(u32 crystalfreq)
+{
+ const struct pmu1_plltab_entry *e;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(pmu1_plltab); i++) {
+ e = &pmu1_plltab[i];
+ if (e->freq == crystalfreq)
+ return e;
+ }
+
+ return NULL;
+}
+
+/* Tune the PLL to the crystal speed. crystalfreq is in kHz. */
+static void ssb_pmu1_pllinit_r0(struct ssb_chipcommon *cc,
+ u32 crystalfreq)
+{
+ struct ssb_bus *bus = cc->dev->bus;
+ const struct pmu1_plltab_entry *e = NULL;
+ u32 buffer_strength = 0;
+ u32 tmp, pllctl, pmuctl;
+ unsigned int i;
+
+ if (bus->chip_id == 0x4312) {
+ /* We do not touch the BCM4312 PLL and assume
+ * the default crystal settings work out-of-the-box. */
+ cc->pmu.crystalfreq = 20000;
+ return;
+ }
+
+ if (crystalfreq)
+ e = pmu1_plltab_find_entry(crystalfreq);
+ if (!e)
+ e = pmu1_plltab_find_entry(SSB_PMU1_DEFAULT_XTALFREQ);
+ BUG_ON(!e);
+ crystalfreq = e->freq;
+ cc->pmu.crystalfreq = e->freq;
+
+ /* Check if the PLL already is programmed to this frequency. */
+ pmuctl = chipco_read32(cc, SSB_CHIPCO_PMU_CTL);
+ if (((pmuctl & SSB_CHIPCO_PMU_CTL_XTALFREQ) >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT) == e->xf) {
+ /* We're already there... */
+ return;
+ }
+
+ ssb_printk(KERN_INFO PFX "Programming PLL to %u.%03u MHz\n",
+ (crystalfreq / 1000), (crystalfreq % 1000));
+
+ /* First turn the PLL off. */
+ switch (bus->chip_id) {
+ case 0x4325:
+ chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK,
+ ~((1 << SSB_PMURES_4325_BBPLL_PWRSW_PU) |
+ (1 << SSB_PMURES_4325_HT_AVAIL)));
+ chipco_mask32(cc, SSB_CHIPCO_PMU_MAXRES_MSK,
+ ~((1 << SSB_PMURES_4325_BBPLL_PWRSW_PU) |
+ (1 << SSB_PMURES_4325_HT_AVAIL)));
+ /* Adjust the BBPLL to 2 on all channels later. */
+ buffer_strength = 0x222222;
+ break;
+ default:
+ SSB_WARN_ON(1);
+ }
+ for (i = 1500; i; i--) {
+ tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST);
+ if (!(tmp & SSB_CHIPCO_CLKCTLST_HAVEHT))
+ break;
+ udelay(10);
+ }
+ tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST);
+ if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT)
+ ssb_printk(KERN_EMERG PFX "Failed to turn the PLL off!\n");
+
+ /* Set p1div and p2div. */
+ pllctl = ssb_chipco_pll_read(cc, SSB_PMU1_PLLCTL0);
+ pllctl &= ~(SSB_PMU1_PLLCTL0_P1DIV | SSB_PMU1_PLLCTL0_P2DIV);
+ pllctl |= ((u32)e->p1div << SSB_PMU1_PLLCTL0_P1DIV_SHIFT) & SSB_PMU1_PLLCTL0_P1DIV;
+ pllctl |= ((u32)e->p2div << SSB_PMU1_PLLCTL0_P2DIV_SHIFT) & SSB_PMU1_PLLCTL0_P2DIV;
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, pllctl);
+
+ /* Set ndiv int and ndiv mode */
+ pllctl = ssb_chipco_pll_read(cc, SSB_PMU1_PLLCTL2);
+ pllctl &= ~(SSB_PMU1_PLLCTL2_NDIVINT | SSB_PMU1_PLLCTL2_NDIVMODE);
+ pllctl |= ((u32)e->ndiv_int << SSB_PMU1_PLLCTL2_NDIVINT_SHIFT) & SSB_PMU1_PLLCTL2_NDIVINT;
+ pllctl |= (1 << SSB_PMU1_PLLCTL2_NDIVMODE_SHIFT) & SSB_PMU1_PLLCTL2_NDIVMODE;
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, pllctl);
+
+ /* Set ndiv frac */
+ pllctl = ssb_chipco_pll_read(cc, SSB_PMU1_PLLCTL3);
+ pllctl &= ~SSB_PMU1_PLLCTL3_NDIVFRAC;
+ pllctl |= ((u32)e->ndiv_frac << SSB_PMU1_PLLCTL3_NDIVFRAC_SHIFT) & SSB_PMU1_PLLCTL3_NDIVFRAC;
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL3, pllctl);
+
+ /* Change the drive strength, if required. */
+ if (buffer_strength) {
+ pllctl = ssb_chipco_pll_read(cc, SSB_PMU1_PLLCTL5);
+ pllctl &= ~SSB_PMU1_PLLCTL5_CLKDRV;
+ pllctl |= (buffer_strength << SSB_PMU1_PLLCTL5_CLKDRV_SHIFT) & SSB_PMU1_PLLCTL5_CLKDRV;
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, pllctl);
+ }
+
+ /* Tune the crystalfreq and the divisor. */
+ pmuctl = chipco_read32(cc, SSB_CHIPCO_PMU_CTL);
+ pmuctl &= ~(SSB_CHIPCO_PMU_CTL_ILP_DIV | SSB_CHIPCO_PMU_CTL_XTALFREQ);
+ pmuctl |= ((((u32)e->freq + 127) / 128 - 1) << SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT)
+ & SSB_CHIPCO_PMU_CTL_ILP_DIV;
+ pmuctl |= ((u32)e->xf << SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT) & SSB_CHIPCO_PMU_CTL_XTALFREQ;
+ chipco_write32(cc, SSB_CHIPCO_PMU_CTL, pmuctl);
+}
+
+static void ssb_pmu_pll_init(struct ssb_chipcommon *cc)
+{
+ struct ssb_bus *bus = cc->dev->bus;
+ u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
+
+ if (bus->bustype == SSB_BUSTYPE_SSB) {
+ /* TODO: The user may override the crystal frequency. */
+ }
+
+ switch (bus->chip_id) {
+ case 0x4312:
+ case 0x4325:
+ ssb_pmu1_pllinit_r0(cc, crystalfreq);
+ break;
+ case 0x4328:
+ case 0x5354:
+ ssb_pmu0_pllinit_r0(cc, crystalfreq);
+ break;
+ default:
+ ssb_printk(KERN_ERR PFX
+ "ERROR: PLL init unknown for device %04X\n",
+ bus->chip_id);
+ }
+}
+
+struct pmu_res_updown_tab_entry {
+ u8 resource; /* The resource number */
+ u16 updown; /* The updown value */
+};
+
+enum pmu_res_depend_tab_task {
+ PMU_RES_DEP_SET = 1,
+ PMU_RES_DEP_ADD,
+ PMU_RES_DEP_REMOVE,
+};
+
+struct pmu_res_depend_tab_entry {
+ u8 resource; /* The resource number */
+ u8 task; /* SET | ADD | REMOVE */
+ u32 depend; /* The depend mask */
+};
+
+static const struct pmu_res_updown_tab_entry pmu_res_updown_tab_4328a0[] = {
+ { .resource = SSB_PMURES_4328_EXT_SWITCHER_PWM, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_BB_SWITCHER_PWM, .updown = 0x1F01, },
+ { .resource = SSB_PMURES_4328_BB_SWITCHER_BURST, .updown = 0x010F, },
+ { .resource = SSB_PMURES_4328_BB_EXT_SWITCHER_BURST, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_ILP_REQUEST, .updown = 0x0202, },
+ { .resource = SSB_PMURES_4328_RADIO_SWITCHER_PWM, .updown = 0x0F01, },
+ { .resource = SSB_PMURES_4328_RADIO_SWITCHER_BURST, .updown = 0x0F01, },
+ { .resource = SSB_PMURES_4328_ROM_SWITCH, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_PA_REF_LDO, .updown = 0x0F01, },
+ { .resource = SSB_PMURES_4328_RADIO_LDO, .updown = 0x0F01, },
+ { .resource = SSB_PMURES_4328_AFE_LDO, .updown = 0x0F01, },
+ { .resource = SSB_PMURES_4328_PLL_LDO, .updown = 0x0F01, },
+ { .resource = SSB_PMURES_4328_BG_FILTBYP, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_TX_FILTBYP, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_RX_FILTBYP, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_XTAL_PU, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_XTAL_EN, .updown = 0xA001, },
+ { .resource = SSB_PMURES_4328_BB_PLL_FILTBYP, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_RF_PLL_FILTBYP, .updown = 0x0101, },
+ { .resource = SSB_PMURES_4328_BB_PLL_PU, .updown = 0x0701, },
+};
+
+static const struct pmu_res_depend_tab_entry pmu_res_depend_tab_4328a0[] = {
+ {
+ /* Adjust ILP Request to avoid forcing EXT/BB into burst mode. */
+ .resource = SSB_PMURES_4328_ILP_REQUEST,
+ .task = PMU_RES_DEP_SET,
+ .depend = ((1 << SSB_PMURES_4328_EXT_SWITCHER_PWM) |
+ (1 << SSB_PMURES_4328_BB_SWITCHER_PWM)),
+ },
+};
+
+static const struct pmu_res_updown_tab_entry pmu_res_updown_tab_4325a0[] = {
+ { .resource = SSB_PMURES_4325_XTAL_PU, .updown = 0x1501, },
+};
+
+static const struct pmu_res_depend_tab_entry pmu_res_depend_tab_4325a0[] = {
+ {
+ /* Adjust HT-Available dependencies. */
+ .resource = SSB_PMURES_4325_HT_AVAIL,
+ .task = PMU_RES_DEP_ADD,
+ .depend = ((1 << SSB_PMURES_4325_RX_PWRSW_PU) |
+ (1 << SSB_PMURES_4325_TX_PWRSW_PU) |
+ (1 << SSB_PMURES_4325_LOGEN_PWRSW_PU) |
+ (1 << SSB_PMURES_4325_AFE_PWRSW_PU)),
+ },
+};
+
+static void ssb_pmu_resources_init(struct ssb_chipcommon *cc)
+{
+ struct ssb_bus *bus = cc->dev->bus;
+ u32 min_msk = 0, max_msk = 0;
+ unsigned int i;
+ const struct pmu_res_updown_tab_entry *updown_tab = NULL;
+ unsigned int updown_tab_size;
+ const struct pmu_res_depend_tab_entry *depend_tab = NULL;
+ unsigned int depend_tab_size;
+
+ switch (bus->chip_id) {
+ case 0x4312:
+ /* We keep the default settings:
+ * min_msk = 0xCBB
+ * max_msk = 0x7FFFF
+ */
+ break;
+ case 0x4325:
+ /* Power OTP down later. */
+ min_msk = (1 << SSB_PMURES_4325_CBUCK_BURST) |
+ (1 << SSB_PMURES_4325_LNLDO2_PU);
+ if (chipco_read32(cc, SSB_CHIPCO_CHIPSTAT) &
+ SSB_CHIPCO_CHST_4325_PMUTOP_2B)
+ min_msk |= (1 << SSB_PMURES_4325_CLDO_CBUCK_BURST);
+ /* The PLL may turn on, if it decides so. */
+ max_msk = 0xFFFFF;
+ updown_tab = pmu_res_updown_tab_4325a0;
+ updown_tab_size = ARRAY_SIZE(pmu_res_updown_tab_4325a0);
+ depend_tab = pmu_res_depend_tab_4325a0;
+ depend_tab_size = ARRAY_SIZE(pmu_res_depend_tab_4325a0);
+ break;
+ case 0x4328:
+ min_msk = (1 << SSB_PMURES_4328_EXT_SWITCHER_PWM) |
+ (1 << SSB_PMURES_4328_BB_SWITCHER_PWM) |
+ (1 << SSB_PMURES_4328_XTAL_EN);
+ /* The PLL may turn on, if it decides so. */
+ max_msk = 0xFFFFF;
+ updown_tab = pmu_res_updown_tab_4328a0;
+ updown_tab_size = ARRAY_SIZE(pmu_res_updown_tab_4328a0);
+ depend_tab = pmu_res_depend_tab_4328a0;
+ depend_tab_size = ARRAY_SIZE(pmu_res_depend_tab_4328a0);
+ break;
+ case 0x5354:
+ /* The PLL may turn on, if it decides so. */
+ max_msk = 0xFFFFF;
+ break;
+ default:
+ ssb_printk(KERN_ERR PFX
+ "ERROR: PMU resource config unknown for device %04X\n",
+ bus->chip_id);
+ }
+
+ if (updown_tab) {
+ for (i = 0; i < updown_tab_size; i++) {
+ chipco_write32(cc, SSB_CHIPCO_PMU_RES_TABSEL,
+ updown_tab[i].resource);
+ chipco_write32(cc, SSB_CHIPCO_PMU_RES_UPDNTM,
+ updown_tab[i].updown);
+ }
+ }
+ if (depend_tab) {
+ for (i = 0; i < depend_tab_size; i++) {
+ chipco_write32(cc, SSB_CHIPCO_PMU_RES_TABSEL,
+ depend_tab[i].resource);
+ switch (depend_tab[i].task) {
+ case PMU_RES_DEP_SET:
+ chipco_write32(cc, SSB_CHIPCO_PMU_RES_DEPMSK,
+ depend_tab[i].depend);
+ break;
+ case PMU_RES_DEP_ADD:
+ chipco_set32(cc, SSB_CHIPCO_PMU_RES_DEPMSK,
+ depend_tab[i].depend);
+ break;
+ case PMU_RES_DEP_REMOVE:
+ chipco_mask32(cc, SSB_CHIPCO_PMU_RES_DEPMSK,
+ ~(depend_tab[i].depend));
+ break;
+ default:
+ SSB_WARN_ON(1);
+ }
+ }
+ }
+
+ /* Set the resource masks. */
+ if (min_msk)
+ chipco_write32(cc, SSB_CHIPCO_PMU_MINRES_MSK, min_msk);
+ if (max_msk)
+ chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk);
+}
+
+void ssb_pmu_init(struct ssb_chipcommon *cc)
+{
+ struct ssb_bus *bus = cc->dev->bus;
+ u32 pmucap;
+
+ if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
+ return;
+
+ pmucap = chipco_read32(cc, SSB_CHIPCO_PMU_CAP);
+ cc->pmu.rev = (pmucap & SSB_CHIPCO_PMU_CAP_REVISION);
+
+ ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
+ cc->pmu.rev, pmucap);
+
+ if (cc->pmu.rev >= 1) {
+ if ((bus->chip_id == 0x4325) && (bus->chip_rev < 2)) {
+ chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
+ ~SSB_CHIPCO_PMU_CTL_NOILPONW);
+ } else {
+ chipco_set32(cc, SSB_CHIPCO_PMU_CTL,
+ SSB_CHIPCO_PMU_CTL_NOILPONW);
+ }
+ }
+ ssb_pmu_pll_init(cc);
+ ssb_pmu_resources_init(cc);
+}
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index d5cde051806..40ea4176224 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -467,6 +467,51 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
/* TODO - get remaining rev 4 stuff needed */
}
+static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
+{
+ int i;
+ u16 v;
+
+ /* extract the MAC address */
+ for (i = 0; i < 3; i++) {
+ v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
+ *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
+ }
+ SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
+ SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
+ SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
+ SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
+ SSB_SPROM8_ANTAVAIL_A_SHIFT);
+ SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
+ SSB_SPROM8_ANTAVAIL_BG_SHIFT);
+ SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
+ SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
+ SSB_SPROM8_ITSSI_BG_SHIFT);
+ SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
+ SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
+ SSB_SPROM8_ITSSI_A_SHIFT);
+ SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
+ SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
+ SSB_SPROM8_GPIOA_P1_SHIFT);
+ SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
+ SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
+ SSB_SPROM8_GPIOB_P3_SHIFT);
+
+ /* Extract the antenna gain values. */
+ SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
+ SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
+ SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
+ SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
+ SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
+ SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
+ SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
+ SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
+ memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
+ sizeof(out->antenna_gain.ghz5));
+
+ /* TODO - get remaining rev 8 stuff needed */
+}
+
static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
const u16 *in, u16 size)
{
@@ -487,15 +532,25 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
out->revision = 4;
sprom_extract_r45(out, in);
} else {
- if (out->revision == 0)
- goto unsupported;
- if (out->revision >= 1 && out->revision <= 3) {
+ switch (out->revision) {
+ case 1:
+ case 2:
+ case 3:
sprom_extract_r123(out, in);
- }
- if (out->revision == 4 || out->revision == 5)
+ break;
+ case 4:
+ case 5:
sprom_extract_r45(out, in);
- if (out->revision > 5)
- goto unsupported;
+ break;
+ case 8:
+ sprom_extract_r8(out, in);
+ break;
+ default:
+ ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
+ " revision %d detected. Will extract"
+ " v1\n", out->revision);
+ sprom_extract_r123(out, in);
+ }
}
if (out->boardflags_lo == 0xFFFF)
@@ -504,16 +559,12 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
out->boardflags_hi = 0; /* per specs */
return 0;
-unsupported:
- ssb_printk(KERN_WARNING PFX "Unsupported SPROM revision %d "
- "detected. Will extract v1\n", out->revision);
- sprom_extract_r123(out, in);
- return 0;
}
static int ssb_pci_sprom_get(struct ssb_bus *bus,
struct ssb_sprom *sprom)
{
+ const struct ssb_sprom *fallback;
int err = -ENOMEM;
u16 *buf;
@@ -533,12 +584,23 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
sprom_do_read(bus, buf);
err = sprom_check_crc(buf, bus->sprom_size);
- if (err)
+ if (err) {
+ /* All CRC attempts failed.
+ * Maybe there is no SPROM on the device?
+ * If we have a fallback, use that. */
+ fallback = ssb_get_fallback_sprom();
+ if (fallback) {
+ memcpy(sprom, fallback, sizeof(*sprom));
+ err = 0;
+ goto out_free;
+ }
ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
" SPROM CRC (corrupt SPROM)\n");
+ }
}
err = sprom_extract(bus, sprom, buf, bus->sprom_size);
+out_free:
kfree(buf);
out:
return err;
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
index 3668edb3931..8943015a3ee 100644
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -14,6 +14,9 @@
#include "ssb_private.h"
+static const struct ssb_sprom *fallback_sprom;
+
+
static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
size_t sprom_size_words)
{
@@ -131,3 +134,36 @@ out:
return res;
return err ? err : count;
}
+
+/**
+ * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
+ *
+ * @sprom: The SPROM data structure to register.
+ *
+ * With this function the architecture implementation may register a fallback
+ * SPROM data structure. The fallback is only used for PCI based SSB devices,
+ * where no valid SPROM can be found in the shadow registers.
+ *
+ * This function is useful for weird architectures that have a half-assed SSB device
+ * hardwired to their PCI bus.
+ *
+ * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently
+ * don't use this fallback.
+ * Architectures must provide the SPROM for native SSB devices anyway,
+ * so the fallback also isn't used for native devices.
+ *
+ * This function is available for architecture code, only. So it is not exported.
+ */
+int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
+{
+ if (fallback_sprom)
+ return -EEXIST;
+ fallback_sprom = sprom;
+
+ return 0;
+}
+
+const struct ssb_sprom *ssb_get_fallback_sprom(void)
+{
+ return fallback_sprom;
+}
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index ebc32d8fe15..57fa482abb9 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -131,6 +131,7 @@ ssize_t ssb_attr_sprom_store(struct ssb_bus *bus,
const char *buf, size_t count,
int (*sprom_check_crc)(const u16 *sprom, size_t size),
int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
+extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
/* core.c */
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ce6badded47..211af86a6c5 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -73,8 +73,6 @@ source "drivers/staging/rt2860/Kconfig"
source "drivers/staging/rt2870/Kconfig"
-source "drivers/staging/benet/Kconfig"
-
source "drivers/staging/comedi/Kconfig"
source "drivers/staging/asus_oled/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 9ddcc2bb336..47a56f5ffab 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_AGNX) += agnx/
obj-$(CONFIG_OTUS) += otus/
obj-$(CONFIG_RT2860) += rt2860/
obj-$(CONFIG_RT2870) += rt2870/
-obj-$(CONFIG_BENET) += benet/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/
diff --git a/drivers/staging/agnx/agnx.h b/drivers/staging/agnx/agnx.h
index a75b0db3726..20f36da6247 100644
--- a/drivers/staging/agnx/agnx.h
+++ b/drivers/staging/agnx/agnx.h
@@ -1,6 +1,8 @@
#ifndef AGNX_H_
#define AGNX_H_
+#include <linux/io.h>
+
#include "xmit.h"
#define PFX KBUILD_MODNAME ": "
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
index 8e2b4ca0651..f516140ca97 100644
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ b/drivers/staging/altpciechdma/altpciechdma.c
@@ -531,7 +531,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
goto fail;
/* allocate and map coherently-cached memory for a DMA-able buffer */
- /* @see 2.6.26.2/Documentation/DMA-mapping.txt line 318 */
+ /* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
buffer_virt = (u8 *)pci_alloc_consistent(dev, PAGE_SIZE * 4, &buffer_bus);
if (!buffer_virt) {
printk(KERN_DEBUG "Could not allocate coherent DMA buffer.\n");
@@ -846,7 +846,7 @@ static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
#if 1 // @todo For now, disable 64-bit, because I do not understand the implications (DAC!)
/* query for DMA transfer */
- /* @see Documentation/DMA-mapping.txt */
+ /* @see Documentation/PCI/PCI-DMA-mapping.txt */
if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)) {
pci_set_consistent_dma_mask(dev, DMA_64BIT_MASK);
/* use 64-bit DMA */
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 6b996db0dd6..604bd1e0d54 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -27,6 +27,7 @@ menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
bool "Android RAM Console Enable error correction"
default n
depends on ANDROID_RAM_CONSOLE
+ depends on !ANDROID_RAM_CONSOLE_EARLY_INIT
select REED_SOLOMON
select REED_SOLOMON_ENC8
select REED_SOLOMON_DEC8
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 6a4ceacb33f..758131cad08 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -319,6 +319,7 @@ int task_get_unused_fd_flags(struct task_struct *tsk, int flags)
int fd, error;
struct fdtable *fdt;
unsigned long rlim_cur;
+ unsigned long irqs;
if (files == NULL)
return -ESRCH;
@@ -335,12 +336,11 @@ repeat:
* N.B. For clone tasks sharing a files structure, this test
* will limit the total number of files that can be opened.
*/
- rcu_read_lock();
- if (tsk->signal)
+ rlim_cur = 0;
+ if (lock_task_sighand(tsk, &irqs)) {
rlim_cur = tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
- else
- rlim_cur = 0;
- rcu_read_unlock();
+ unlock_task_sighand(tsk, &irqs);
+ }
if (fd >= rlim_cur)
goto out;
@@ -2649,14 +2649,14 @@ static void binder_vma_open(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot);
+ printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
dump_stack();
}
static void binder_vma_close(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot);
+ printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
proc->vma = NULL;
}
@@ -2677,7 +2677,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_end = vma->vm_start + SZ_4M;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot);
+ printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
ret = -EPERM;
diff --git a/drivers/staging/android/lowmemorykiller.txt b/drivers/staging/android/lowmemorykiller.txt
new file mode 100644
index 00000000000..bd5c0c02896
--- /dev/null
+++ b/drivers/staging/android/lowmemorykiller.txt
@@ -0,0 +1,16 @@
+The lowmemorykiller driver lets user-space specify a set of memory thresholds
+where processes with a range of oom_adj values will get killed. Specify the
+minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
+number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
+files take a comma separated list of numbers in ascending order.
+
+For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
+"1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes
+with a oom_adj value of 8 or higher when the free memory drops below 4096 pages
+and kill processes with a oom_adj value of 0 or higher when the free memory
+drops below 1024 pages.
+
+The driver considers memory used for caches to be free, but if a large
+percentage of the cached memory is locked this can be very inaccurate
+and processes may not get killed until the normal oom killer is triggered.
+
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index bf006857a87..643ac5ce381 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -224,9 +224,23 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
ram_console_buffer_size =
buffer_size - sizeof(struct ram_console_buffer);
+ if (ram_console_buffer_size > buffer_size) {
+ pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n",
+ buffer, buffer_size, ram_console_buffer_size);
+ return 0;
+ }
+
#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size,
ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
+
+ if (ram_console_buffer_size > buffer_size) {
+ pr_err("ram_console: buffer %p, invalid size %d, "
+ "non-ecc datasize %d\n",
+ buffer, buffer_size, ram_console_buffer_size);
+ return 0;
+ }
+
ram_console_par_buffer = buffer->data + ram_console_buffer_size;
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index bea68c9fc94..33daff0481d 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -18,7 +18,7 @@
#include <linux/platform_device.h>
#include <linux/hrtimer.h>
#include <linux/err.h>
-#include <asm/arch/gpio.h>
+#include <linux/gpio.h>
#include "timed_gpio.h"
@@ -49,7 +49,8 @@ static ssize_t gpio_enable_show(struct device *dev, struct device_attribute *att
if (hrtimer_active(&gpio_data->timer)) {
ktime_t r = hrtimer_get_remaining(&gpio_data->timer);
- remaining = r.tv.sec * 1000 + r.tv.nsec / 1000000;
+ struct timeval t = ktime_to_timeval(r);
+ remaining = t.tv_sec * 1000 + t.tv_usec / 1000;
} else
remaining = 0;
diff --git a/drivers/staging/at76_usb/Kconfig b/drivers/staging/at76_usb/Kconfig
index 4c0e55e1544..8606f962162 100644
--- a/drivers/staging/at76_usb/Kconfig
+++ b/drivers/staging/at76_usb/Kconfig
@@ -1,6 +1,6 @@
config USB_ATMEL
tristate "Atmel at76c503/at76c505/at76c505a USB cards"
- depends on MAC80211 && WLAN_80211 && USB
+ depends on WLAN_80211 && USB
default N
select FW_LOADER
---help---
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
index 185533e5476..c8e4d31c7df 100644
--- a/drivers/staging/at76_usb/at76_usb.c
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -6,7 +6,6 @@
* Copyright (c) 2004 Nick Jones
* Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
* Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
- * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -17,13 +16,6 @@
* Atmel AT76C503A/505/505A.
*
* Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
- *
- * TODO for the mac80211 port:
- * o adhoc support
- * o RTS/CTS support
- * o Power Save Mode support
- * o support for short/long preambles
- * o export variables through debugfs/sysfs
*/
#include <linux/init.h>
@@ -44,7 +36,7 @@
#include <net/ieee80211_radiotap.h>
#include <linux/firmware.h>
#include <linux/leds.h>
-#include <net/mac80211.h>
+#include <net/ieee80211.h>
#include "at76_usb.h"
@@ -84,43 +76,31 @@
#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
#define DBG_FW 0x10000000 /* firmware download */
#define DBG_DFU 0x20000000 /* device firmware upgrade */
-#define DBG_CMD 0x40000000
-#define DBG_MAC80211 0x80000000
#define DBG_DEFAULTS 0
/* Use our own dbg macro */
#define at76_dbg(bits, format, arg...) \
-do { \
- if (at76_debug & (bits)) \
- printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
-} while (0)
-
-#define at76_dbg_dump(bits, buf, len, format, arg...) \
-do { \
- if (at76_debug & (bits)) { \
+ do { \
+ if (at76_debug & (bits)) \
printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \
- } \
-} while (0)
+ } while (0)
static int at76_debug = DBG_DEFAULTS;
-#define FIRMWARE_IS_WPA(ver) ((ver.major == 1) && (ver.minor == 103))
-
/* Protect against concurrent firmware loading and parsing */
static struct mutex fw_mutex;
static struct fwentry firmwares[] = {
- [0] = { "" },
- [BOARD_503_ISL3861] = { "atmel_at76c503-i3861.bin" },
- [BOARD_503_ISL3863] = { "atmel_at76c503-i3863.bin" },
- [BOARD_503] = { "atmel_at76c503-rfmd.bin" },
- [BOARD_503_ACC] = { "atmel_at76c503-rfmd-acc.bin" },
- [BOARD_505] = { "atmel_at76c505-rfmd.bin" },
- [BOARD_505_2958] = { "atmel_at76c505-rfmd2958.bin" },
- [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" },
- [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" },
+ [0] = {""},
+ [BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"},
+ [BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"},
+ [BOARD_503] = {"atmel_at76c503-rfmd.bin"},
+ [BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"},
+ [BOARD_505] = {"atmel_at76c505-rfmd.bin"},
+ [BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"},
+ [BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"},
+ [BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"},
};
#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
@@ -130,133 +110,135 @@ static struct usb_device_id dev_table[] = {
* at76c503-i3861
*/
/* Generic AT76C503/3861 device */
- { USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Linksys WUSB11 v2.1/v2.6 */
- { USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Netgear MA101 rev. A */
- { USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Tekram U300C / Allnet ALL0193 */
- { USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* HP HN210W J7801A */
- { USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Sitecom/Z-Com/Zyxel M4Y-750 */
- { USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Dynalink/Askey WLL013 (intersil) */
- { USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
- { USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* BenQ AWL300 */
- { USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Addtron AWU-120, Compex WLU11 */
- { USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Intel AP310 AnyPoint II USB */
- { USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Dynalink L11U */
- { USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Arescom WL-210, FCC id 07J-GL2411USB */
- { USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* I-O DATA WN-B11/USB */
- { USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* BT Voyager 1010 */
- { USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/*
* at76c503-i3863
*/
/* Generic AT76C503/3863 device */
- { USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)},
/* Samsung SWL-2100U */
- { USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)},
/*
* at76c503-rfmd
*/
/* Generic AT76C503/RFMD device */
- { USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)},
/* Dynalink/Askey WLL013 (rfmd) */
- { USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)},
/* Linksys WUSB11 v2.6 */
- { USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)},
/* Network Everywhere NWU11B */
- { USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)},
/* Netgear MA101 rev. B */
- { USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)},
/* D-Link DWL-120 rev. E */
- { USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)},
/* Actiontec 802UAT1, HWU01150-01UK */
- { USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)},
/* AirVast W-Buddie WN210 */
- { USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)},
/* Dick Smith Electronics XH1153 802.11b USB adapter */
- { USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)},
/* CNet CNUSB611 */
- { USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)},
/* FiberLine FL-WL200U */
- { USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)},
/* BenQ AWL400 USB stick */
- { USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)},
/* 3Com 3CRSHEW696 */
- { USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)},
/* Siemens Santis ADSL WLAN USB adapter WLL 013 */
- { USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)},
/* Belkin F5D6050, version 2 */
- { USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)},
/* iBlitzz, BWU613 (not *B or *SB) */
- { USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)},
/* Gigabyte GN-WLBM101 */
- { USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)},
/* Planex GW-US11S */
- { USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)},
/* Internal WLAN adapter in h5[4,5]xx series iPAQs */
- { USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)},
/* Corega Wireless LAN USB-11 mini */
- { USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)},
/* Corega Wireless LAN USB-11 mini2 */
- { USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)},
/* Uniden PCW100 */
- { USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)},
/*
* at76c503-rfmd-acc
*/
/* SMC2664W */
- { USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) },
+ {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)},
/* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
- { USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) },
+ {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)},
/*
* at76c505-rfmd
*/
/* Generic AT76C505/RFMD */
- { USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) },
+ {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)},
/*
* at76c505-rfmd2958
*/
/* Generic AT76C505/RFMD, OvisLink WL-1130USB */
- { USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
/* Fiberline FL-WL240U */
- { USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)},
/* CNet CNUSB-611G */
- { USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)},
/* Linksys WUSB11 v2.8 */
- { USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)},
/* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
- { USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)},
/* Corega WLAN USB Stick 11 */
- { USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
/* Microstar MSI Box MS6978 */
- { USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)},
/*
* at76c505a-rfmd2958
*/
/* Generic AT76C505A device */
- { USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)},
/* Generic AT76C505AS device */
- { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)},
/* Siemens Gigaset USB WLAN Adapter 11 */
- { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)},
+ /* OQO Model 01+ Internal Wi-Fi */
+ {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)},
/*
* at76c505amx-rfmd
*/
/* Generic AT76C505AMX device */
- { USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) },
- { }
+ {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)},
+ {}
};
MODULE_DEVICE_TABLE(usb, dev_table);
@@ -264,8 +246,26 @@ MODULE_DEVICE_TABLE(usb, dev_table);
/* Supported rates of this hardware, bit 7 marks basic rates */
static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
+/* Frequency of each channel in MHz */
+static const long channel_frequency[] = {
+ 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+ 2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+
+#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
+
static const char *const preambles[] = { "long", "short", "auto" };
+static const char *const mac_states[] = {
+ [MAC_INIT] = "INIT",
+ [MAC_SCANNING] = "SCANNING",
+ [MAC_AUTH] = "AUTH",
+ [MAC_ASSOC] = "ASSOC",
+ [MAC_JOINING] = "JOINING",
+ [MAC_CONNECTED] = "CONNECTED",
+ [MAC_OWN_IBSS] = "OWN_IBSS"
+};
+
/* Firmware download */
/* DFU states */
#define STATE_IDLE 0x00
@@ -300,30 +300,17 @@ struct dfu_status {
static inline int at76_is_intersil(enum board_type board)
{
- if (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863)
- return 1;
- return 0;
+ return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
}
static inline int at76_is_503rfmd(enum board_type board)
{
- if (board == BOARD_503 || board == BOARD_503_ACC)
- return 1;
- return 0;
-}
-
-static inline int at76_is_505(enum board_type board)
-{
- if (board == BOARD_505 || board == BOARD_505_2958)
- return 1;
- return 0;
+ return (board == BOARD_503 || board == BOARD_503_ACC);
}
static inline int at76_is_505a(enum board_type board)
{
- if (board == BOARD_505A || board == BOARD_505AMX)
- return 1;
- return 0;
+ return (board == BOARD_505A || board == BOARD_505AMX);
}
/* Load a block of the first (internal) part of the firmware */
@@ -504,6 +491,41 @@ exit:
return ret;
}
+/* Report that the scan results are ready */
+static inline void at76_iwevent_scan_complete(struct net_device *netdev)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name);
+}
+
+static inline void at76_iwevent_bss_connect(struct net_device *netdev,
+ u8 *bssid)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
+ __func__);
+}
+
+static inline void at76_iwevent_bss_disconnect(struct net_device *netdev)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
+ __func__);
+}
+
#define HEX2STR_BUFFERS 4
#define HEX2STR_MAX_LEN 64
#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
@@ -575,6 +597,37 @@ static void at76_ledtrig_tx_activity(void)
mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
}
+/* Check if the given ssid is hidden */
+static inline int at76_is_hidden_ssid(u8 *ssid, int length)
+{
+ static const u8 zeros[32];
+
+ if (length == 0)
+ return 1;
+
+ if (length == 1 && ssid[0] == ' ')
+ return 1;
+
+ return (memcmp(ssid, zeros, length) == 0);
+}
+
+static inline void at76_free_bss_list(struct at76_priv *priv)
+{
+ struct list_head *next, *ptr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ priv->curr_bss = NULL;
+
+ list_for_each_safe(ptr, next, &priv->bss_list) {
+ list_del(ptr);
+ kfree(list_entry(ptr, struct bss_info, list));
+ }
+
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
static int at76_remap(struct usb_device *udev)
{
int ret;
@@ -598,7 +651,7 @@ static int at76_get_op_mode(struct usb_device *udev)
return -ENOMEM;
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
USB_TYPE_VENDOR | USB_DIR_IN |
- USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1,
+ USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
USB_CTRL_GET_TIMEOUT);
saved = *op_mode;
kfree(op_mode);
@@ -676,7 +729,7 @@ exit:
kfree(hwcfg);
if (ret < 0)
printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -685,15 +738,15 @@ static struct reg_domain const *at76_get_reg_domain(u16 code)
{
int i;
static struct reg_domain const fd_tab[] = {
- { 0x10, "FCC (USA)", 0x7ff }, /* ch 1-11 */
- { 0x20, "IC (Canada)", 0x7ff }, /* ch 1-11 */
- { 0x30, "ETSI (most of Europe)", 0x1fff }, /* ch 1-13 */
- { 0x31, "Spain", 0x600 }, /* ch 10-11 */
- { 0x32, "France", 0x1e00 }, /* ch 10-13 */
- { 0x40, "MKK (Japan)", 0x2000 }, /* ch 14 */
- { 0x41, "MKK1 (Japan)", 0x3fff }, /* ch 1-14 */
- { 0x50, "Israel", 0x3fc }, /* ch 3-9 */
- { 0x00, "<unknown>", 0xffffffff } /* ch 1-32 */
+ {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */
+ {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */
+ {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */
+ {0x31, "Spain", 0x600}, /* ch 10-11 */
+ {0x32, "France", 0x1e00}, /* ch 10-13 */
+ {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */
+ {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */
+ {0x50, "Israel", 0x3fc}, /* ch 3-9 */
+ {0x00, "<unknown>", 0xffffffff} /* ch 1-32 */
};
/* Last entry is fallback for unknown domain code */
@@ -731,7 +784,7 @@ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
USB_TYPE_VENDOR | USB_DIR_IN |
USB_RECIP_INTERFACE, cmd, 0, stat_buf,
- sizeof(stat_buf), USB_CTRL_GET_TIMEOUT);
+ 40, USB_CTRL_GET_TIMEOUT);
if (ret >= 0)
ret = stat_buf[5];
kfree(stat_buf);
@@ -739,24 +792,6 @@ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
return ret;
}
-#define MAKE_CMD_CASE(c) case (c): return #c
-
-static const char *at76_get_cmd_string(u8 cmd_status)
-{
- switch (cmd_status) {
- MAKE_CMD_CASE(CMD_SET_MIB);
- MAKE_CMD_CASE(CMD_GET_MIB);
- MAKE_CMD_CASE(CMD_SCAN);
- MAKE_CMD_CASE(CMD_JOIN);
- MAKE_CMD_CASE(CMD_START_IBSS);
- MAKE_CMD_CASE(CMD_RADIO_ON);
- MAKE_CMD_CASE(CMD_RADIO_OFF);
- MAKE_CMD_CASE(CMD_STARTUP);
- }
-
- return "UNKNOWN";
-}
-
static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
int buf_size)
{
@@ -772,10 +807,6 @@ static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
cmd_buf->size = cpu_to_le16(buf_size);
memcpy(cmd_buf->data, buf, buf_size);
- at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size,
- "issuing command %s (0x%02x)",
- at76_get_cmd_string(cmd), cmd);
-
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
0, 0, cmd_buf,
@@ -813,13 +844,13 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
status = at76_get_cmd_status(priv->udev, cmd);
if (status < 0) {
printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
- wiphy_name(priv->hw->wiphy), status);
+ priv->netdev->name, status);
break;
}
at76_dbg(DBG_WAIT_COMPLETE,
"%s: Waiting on cmd %d, status = %d (%s)",
- wiphy_name(priv->hw->wiphy), cmd, status,
+ priv->netdev->name, cmd, status,
at76_get_cmd_status_string(status));
if (status != CMD_STATUS_IN_PROGRESS
@@ -830,7 +861,7 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
if (time_after(jiffies, timeout)) {
printk(KERN_ERR
"%s: completion timeout for command %d\n",
- wiphy_name(priv->hw->wiphy), cmd);
+ priv->netdev->name, cmd);
status = -ETIMEDOUT;
break;
}
@@ -853,7 +884,7 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
if (ret != CMD_STATUS_COMPLETE) {
printk(KERN_INFO
"%s: set_mib: at76_wait_completion failed "
- "with %d\n", wiphy_name(priv->hw->wiphy), ret);
+ "with %d\n", priv->netdev->name, ret);
ret = -EIO;
}
@@ -874,7 +905,7 @@ static int at76_set_radio(struct at76_priv *priv, int enable)
ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
if (ret < 0)
printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
- wiphy_name(priv->hw->wiphy), cmd, ret);
+ priv->netdev->name, cmd, ret);
else
ret = 1;
@@ -895,7 +926,44 @@ static int at76_set_pm_mode(struct at76_priv *priv)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+/* Set the association id for power save mode */
+static int at76_set_associd(struct at76_priv *priv, u16 id)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id);
+ priv->mib_buf.data.word = cpu_to_le16(id);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (associd) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+/* Set the listen interval for power save mode */
+static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, listen_interval);
+ priv->mib_buf.data.word = cpu_to_le16(interval);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: set_mib (listen_interval) failed: %d\n",
+ priv->netdev->name, ret);
return ret;
}
@@ -912,7 +980,7 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -929,7 +997,7 @@ static int at76_set_frag(struct at76_priv *priv, u16 size)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -946,7 +1014,7 @@ static int at76_set_rts(struct at76_priv *priv, u16 size)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -963,41 +1031,24 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
-static int at76_set_tkip_bssid(struct at76_priv *priv, const void *addr)
+static int at76_add_mac_address(struct at76_priv *priv, void *addr)
{
int ret = 0;
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
+ priv->mib_buf.type = MIB_MAC_ADDR;
priv->mib_buf.size = ETH_ALEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption, tkip_bssid);
+ priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN);
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
- printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, tkip_bssid) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
-
- return ret;
-}
-
-static int at76_reset_rsc(struct at76_priv *priv)
-{
- int ret = 0;
-
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
- priv->mib_buf.size = 4 * 8;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption, key_rsc);
- memset(priv->mib_buf.data.data, 0 , priv->mib_buf.size);
-
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret < 0)
- printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, key_rsc) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n",
+ priv->netdev->name, ret);
return ret;
}
@@ -1016,16 +1067,16 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv)
sizeof(struct mib_mac_addr));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
mac2str(m->mac_addr), m->res[0], m->res[1]);
for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
- "status %d", wiphy_name(priv->hw->wiphy), i,
+ "status %d", priv->netdev->name, i,
mac2str(m->group_addr[i]), m->group_addr_status[i]);
exit:
kfree(m);
@@ -1045,13 +1096,13 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
sizeof(struct mib_mac_wep));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
"key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
- "encr_level %u key %d", wiphy_name(priv->hw->wiphy),
+ "encr_level %u key %d", priv->netdev->name,
m->privacy_invoked, m->wep_default_key_id,
m->wep_key_mapping_len, m->exclude_unencrypted,
le32_to_cpu(m->wep_icv_error_count),
@@ -1063,55 +1114,12 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
for (i = 0; i < WEP_KEYS; i++)
at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
- wiphy_name(priv->hw->wiphy), i,
+ priv->netdev->name, i,
hex2str(m->wep_default_keyvalue[i], key_len));
exit:
kfree(m);
}
-static void at76_dump_mib_mac_encryption(struct at76_priv *priv)
-{
- int i;
- int ret;
- /*int key_len;*/
- struct mib_mac_encryption *m;
-
- m = kmalloc(sizeof(struct mib_mac_encryption), GFP_KERNEL);
- if (!m)
- return;
-
- ret = at76_get_mib(priv->udev, MIB_MAC_ENCRYPTION, m,
- sizeof(struct mib_mac_encryption));
- if (ret < 0) {
- dev_err(&priv->udev->dev,
- "%s: at76_get_mib (MAC_ENCRYPTION) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- goto exit;
- }
-
- at76_dbg(DBG_MIB,
- "%s: MIB MAC_ENCRYPTION: tkip_bssid %s priv_invoked %u "
- "ciph_key_id %u grp_key_id %u excl_unencr %u "
- "ckip_key_perm %u wep_icv_err %u wep_excluded %u",
- wiphy_name(priv->hw->wiphy), mac2str(m->tkip_bssid),
- m->privacy_invoked, m->cipher_default_key_id,
- m->cipher_default_group_key_id, m->exclude_unencrypted,
- m->ckip_key_permutation,
- le32_to_cpu(m->wep_icv_error_count),
- le32_to_cpu(m->wep_excluded_count));
-
- /*key_len = (m->encryption_level == 1) ?
- WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;*/
-
- for (i = 0; i < CIPHER_KEYS; i++)
- at76_dbg(DBG_MIB, "%s: MIB MAC_ENCRYPTION: key %d: %s",
- wiphy_name(priv->hw->wiphy), i,
- hex2str(m->cipher_default_keyvalue[i],
- CIPHER_KEY_LEN));
-exit:
- kfree(m);
-}
-
static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
{
int ret;
@@ -1125,7 +1133,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
sizeof(struct mib_mac_mgmt));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1136,7 +1144,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
"pm_mode %d ibss_change %d res %d "
"multi_domain_capability_implemented %d "
"international_roaming %d country_string %.3s",
- wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period),
+ priv->netdev->name, le16_to_cpu(m->beacon_period),
le16_to_cpu(m->CFP_max_duration),
le16_to_cpu(m->medium_occupancy_limit),
le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
@@ -1161,7 +1169,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1171,8 +1179,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
"scan_type %d scan_channel %d probe_delay %u "
"min_channel_time %d max_channel_time %d listen_int %d "
"desired_ssid %s desired_bssid %s desired_bsstype %d",
- wiphy_name(priv->hw->wiphy),
- le32_to_cpu(m->max_tx_msdu_lifetime),
+ priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime),
le32_to_cpu(m->max_rx_lifetime),
le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
@@ -1198,7 +1205,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1207,7 +1214,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
"mpdu_max_length %d cca_mode_supported %d operation_rate_set "
"0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
"phy_type %d current_reg_domain %d",
- wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold),
+ priv->netdev->name, le32_to_cpu(m->ed_threshold),
le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
le16_to_cpu(m->preamble_length),
le16_to_cpu(m->plcp_header_length),
@@ -1231,14 +1238,13 @@ static void at76_dump_mib_local(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
"txautorate_fallback %d ssid_size %d promiscuous_mode %d "
- "preamble_type %d", wiphy_name(priv->hw->wiphy),
- m->beacon_enable,
+ "preamble_type %d", priv->netdev->name, m->beacon_enable,
m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
m->preamble_type);
exit:
@@ -1257,21 +1263,118 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv)
sizeof(struct mib_mdomain));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
hex2str(m->channel_list, sizeof(m->channel_list)));
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
exit:
kfree(m);
}
+static int at76_get_current_bssid(struct at76_priv *priv)
+{
+ int ret = 0;
+ struct mib_mac_mgmt *mac_mgmt =
+ kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
+
+ if (!mac_mgmt) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
+ priv->netdev->name, ret);
+ goto error;
+ }
+ memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN);
+ printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name,
+ mac2str(priv->bssid));
+error:
+ kfree(mac_mgmt);
+exit:
+ return ret;
+}
+
+static int at76_get_current_channel(struct at76_priv *priv)
+{
+ int ret = 0;
+ struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!phy) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n",
+ priv->netdev->name, ret);
+ goto error;
+ }
+ priv->channel = phy->channel_id;
+error:
+ kfree(phy);
+exit:
+ return ret;
+}
+
+/**
+ * at76_start_scan - start a scan
+ *
+ * @use_essid - use the configured ESSID in non passive mode
+ */
+static int at76_start_scan(struct at76_priv *priv, int use_essid)
+{
+ struct at76_req_scan scan;
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xff, ETH_ALEN);
+
+ if (use_essid) {
+ memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE);
+ scan.essid_size = priv->essid_size;
+ } else
+ scan.essid_size = 0;
+
+ /* jal: why should we start at a certain channel? we do scan the whole
+ range allowed by reg domain. */
+ scan.channel = priv->channel;
+
+ /* atmelwlandriver differs between scan type 0 and 1 (active/passive)
+ For ad-hoc mode, it uses type 0 only. */
+ scan.scan_type = priv->scan_mode;
+
+ /* INFO: For probe_delay, not multiplying by 1024 as this will be
+ slightly less than min_channel_time
+ (per spec: probe delay < min. channel time) */
+ scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
+ scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
+ scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
+ scan.international_scan = 0;
+
+ /* other values are set to 0 for type 0 */
+
+ at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, "
+ "channel = %d, probe_delay = %d, scan_min_time = %d, "
+ "scan_max_time = %d)",
+ priv->netdev->name, use_essid,
+ scan.international_scan, scan.channel,
+ le16_to_cpu(scan.probe_delay),
+ le16_to_cpu(scan.min_channel_time),
+ le16_to_cpu(scan.max_channel_time));
+
+ return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+}
+
/* Enable monitor mode */
static int at76_start_monitor(struct at76_priv *priv)
{
@@ -1292,6 +1395,86 @@ static int at76_start_monitor(struct at76_priv *priv)
return ret;
}
+static int at76_start_ibss(struct at76_priv *priv)
+{
+ struct at76_req_ibss bss;
+ int ret;
+
+ WARN_ON(priv->mac_state != MAC_OWN_IBSS);
+ if (priv->mac_state != MAC_OWN_IBSS)
+ return -EBUSY;
+
+ memset(&bss, 0, sizeof(struct at76_req_ibss));
+ memset(bss.bssid, 0xff, ETH_ALEN);
+ memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE);
+ bss.essid_size = priv->essid_size;
+ bss.bss_type = ADHOC_MODE;
+ bss.channel = priv->channel;
+
+ ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss,
+ sizeof(struct at76_req_ibss));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: start_ibss failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ ret = at76_wait_completion(priv, CMD_START_IBSS);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_ERR "%s: start_ibss failed to complete, %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ ret = at76_get_current_bssid(priv);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_get_current_channel(priv);
+ if (ret < 0)
+ return ret;
+
+ /* not sure what this is good for ??? */
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
+ priv->mib_buf.data.byte = 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ netif_carrier_on(priv->netdev);
+ netif_start_queue(priv->netdev);
+ return 0;
+}
+
+/* Request card to join BSS in managed or ad-hoc mode */
+static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr)
+{
+ struct at76_req_join join;
+
+ BUG_ON(!ptr);
+
+ memset(&join, 0, sizeof(struct at76_req_join));
+ memcpy(join.bssid, ptr->bssid, ETH_ALEN);
+ memcpy(join.essid, ptr->ssid, ptr->ssid_len);
+ join.essid_size = ptr->ssid_len;
+ join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2);
+ join.channel = ptr->channel;
+ join.timeout = cpu_to_le16(2000);
+
+ at76_dbg(DBG_PROGRESS,
+ "%s join addr %s ssid %s type %d ch %d timeout %d",
+ priv->netdev->name, mac2str(join.bssid), join.essid,
+ join.bss_type, join.channel, le16_to_cpu(join.timeout));
+ return at76_set_card_command(priv->udev, CMD_JOIN, &join,
+ sizeof(struct at76_req_join));
+}
+
/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
likely to compensate a flaw in the AT76C503A USB part ... */
static inline int at76_calc_padding(int wlen)
@@ -1310,6 +1493,14 @@ static inline int at76_calc_padding(int wlen)
return 0;
}
+/* We are doing a lot of things here in an interrupt. Need
+ a bh handler (Watching TV with a TV card is probably
+ a good test: if you see flickers, we are doing too much.
+ Currently I do see flickers... even with our tasklet :-( )
+ Maybe because the bttv driver and usb-uhci use the same interrupt
+*/
+/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't
+ * solve everything.. (alex) */
static void at76_rx_callback(struct urb *urb)
{
struct at76_priv *priv = urb->context;
@@ -1319,6 +1510,1758 @@ static void at76_rx_callback(struct urb *urb)
return;
}
+static void at76_tx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+ struct net_device_stats *stats = &priv->stats;
+ unsigned long flags;
+ struct at76_tx_buffer *mgmt_buf;
+ int ret;
+
+ switch (urb->status) {
+ case 0:
+ stats->tx_packets++;
+ break;
+ case -ENOENT:
+ case -ECONNRESET:
+ /* urb has been unlinked */
+ return;
+ default:
+ at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
+ __func__, urb->status);
+ stats->tx_errors++;
+ break;
+ }
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+ mgmt_buf = priv->next_mgmt_bulk;
+ priv->next_mgmt_bulk = NULL;
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+
+ if (!mgmt_buf) {
+ netif_wake_queue(priv->netdev);
+ return;
+ }
+
+ /* we don't copy the padding bytes, but add them
+ to the length */
+ memcpy(priv->bulk_out_buffer, mgmt_buf,
+ le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
+ priv->bulk_out_buffer,
+ le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding +
+ AT76_TX_HDRLEN, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret)
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ priv->netdev->name, ret);
+
+ kfree(mgmt_buf);
+}
+
+/* Send a management frame on bulk-out. txbuf->wlength must be set */
+static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf)
+{
+ unsigned long flags;
+ int ret;
+ int urb_status;
+ void *oldbuf = NULL;
+
+ netif_carrier_off(priv->netdev); /* stop netdev watchdog */
+ netif_stop_queue(priv->netdev); /* stop tx data packets */
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+
+ urb_status = priv->tx_urb->status;
+ if (urb_status == -EINPROGRESS) {
+ /* cannot transmit now, put in the queue */
+ oldbuf = priv->next_mgmt_bulk;
+ priv->next_mgmt_bulk = txbuf;
+ }
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+
+ if (oldbuf) {
+ /* a data/mgmt tx is already pending in the URB -
+ if this is no error in some situations we must
+ implement a queue or silently modify the old msg */
+ printk(KERN_ERR "%s: removed pending mgmt buffer %s\n",
+ priv->netdev->name, hex2str(oldbuf, 64));
+ kfree(oldbuf);
+ return 0;
+ }
+
+ txbuf->tx_rate = TX_RATE_1MBIT;
+ txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength));
+ memset(txbuf->reserved, 0, sizeof(txbuf->reserved));
+
+ if (priv->next_mgmt_bulk)
+ printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n",
+ priv->netdev->name, urb_status);
+
+ at76_dbg(DBG_TX_MGMT,
+ "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
+ priv->netdev->name, le16_to_cpu(txbuf->wlength),
+ txbuf->tx_rate, txbuf->padding,
+ hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength)));
+
+ /* txbuf was not consumed above -> send mgmt msg immediately */
+ memcpy(priv->bulk_out_buffer, txbuf,
+ le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
+ priv->bulk_out_buffer,
+ le16_to_cpu(txbuf->wlength) + txbuf->padding +
+ AT76_TX_HDRLEN, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret)
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ priv->netdev->name, ret);
+
+ kfree(txbuf);
+
+ return ret;
+}
+
+/* Go to the next information element */
+static inline void next_ie(struct ieee80211_info_element **ie)
+{
+ *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]);
+}
+
+/* Challenge is the challenge string (in TLV format)
+ we got with seq_nr 2 for shared secret authentication only and
+ send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;
+ otherwise it is NULL */
+static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss,
+ int seq_nr, struct ieee80211_info_element *challenge)
+{
+ struct at76_tx_buffer *tx_buffer;
+ struct ieee80211_hdr_3addr *mgmt;
+ struct ieee80211_auth *req;
+ int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE :
+ AUTH_FRAME_SIZE + 1 + 1 + challenge->len);
+
+ BUG_ON(!bss);
+ BUG_ON(seq_nr == 3 && !challenge);
+ tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);
+ if (!tx_buffer)
+ return -ENOMEM;
+
+ req = (struct ieee80211_auth *)tx_buffer->packet;
+ mgmt = &req->header;
+
+ /* make wireless header */
+ /* first auth msg is not encrypted, only the second (seq_nr == 3) */
+ mgmt->frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH |
+ (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0));
+
+ mgmt->duration_id = cpu_to_le16(0x8000);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = cpu_to_le16(0);
+
+ req->algorithm = cpu_to_le16(priv->auth_mode);
+ req->transaction = cpu_to_le16(seq_nr);
+ req->status = cpu_to_le16(0);
+
+ if (seq_nr == 3)
+ memcpy(req->info_element, challenge, 1 + 1 + challenge->len);
+
+ /* init. at76_priv tx header */
+ tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN);
+ at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction));
+ if (seq_nr == 3)
+ at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...",
+ priv->netdev->name, hex2str(req->info_element, 18));
+
+ /* either send immediately (if no data tx is pending
+ or put it in pending list */
+ return at76_tx_mgmt(priv, tx_buffer);
+}
+
+static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
+{
+ struct at76_tx_buffer *tx_buffer;
+ struct ieee80211_hdr_3addr *mgmt;
+ struct ieee80211_assoc_request *req;
+ struct ieee80211_info_element *ie;
+ char *essid;
+ int essid_len;
+ u16 capa;
+
+ BUG_ON(!bss);
+
+ tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC);
+ if (!tx_buffer)
+ return -ENOMEM;
+
+ req = (struct ieee80211_assoc_request *)tx_buffer->packet;
+ mgmt = &req->header;
+ ie = req->info_element;
+
+ /* make wireless header */
+ mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ASSOC_REQ);
+
+ mgmt->duration_id = cpu_to_le16(0x8000);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = cpu_to_le16(0);
+
+ /* we must set the Privacy bit in the capabilities to assure an
+ Agere-based AP with optional WEP transmits encrypted frames
+ to us. AP only set the Privacy bit in their capabilities
+ if WEP is mandatory in the BSS! */
+ capa = bss->capa;
+ if (priv->wep_enabled)
+ capa |= WLAN_CAPABILITY_PRIVACY;
+ if (priv->preamble_type != PREAMBLE_TYPE_LONG)
+ capa |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+ req->capability = cpu_to_le16(capa);
+
+ req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
+
+ /* write TLV data elements */
+
+ ie->id = MFIE_TYPE_SSID;
+ ie->len = bss->ssid_len;
+ memcpy(ie->data, bss->ssid, bss->ssid_len);
+ next_ie(&ie);
+
+ ie->id = MFIE_TYPE_RATES;
+ ie->len = sizeof(hw_rates);
+ memcpy(ie->data, hw_rates, sizeof(hw_rates));
+ next_ie(&ie); /* ie points behind the supp_rates field */
+
+ /* init. at76_priv tx header */
+ tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt);
+
+ ie = req->info_element;
+ essid = ie->data;
+ essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
+
+ next_ie(&ie); /* points to IE of rates now */
+ at76_dbg(DBG_TX_MGMT,
+ "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(req->capability), essid_len, essid,
+ hex2str(ie->data, ie->len));
+
+ /* either send immediately (if no data tx is pending
+ or put it in pending list */
+ return at76_tx_mgmt(priv, tx_buffer);
+}
+
+/* We got to check the bss_list for old entries */
+static void at76_bss_list_timeout(unsigned long par)
+{
+ struct at76_priv *priv = (struct at76_priv *)par;
+ unsigned long flags;
+ struct list_head *lptr, *nptr;
+ struct bss_info *ptr;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ list_for_each_safe(lptr, nptr, &priv->bss_list) {
+
+ ptr = list_entry(lptr, struct bss_info, list);
+
+ if (ptr != priv->curr_bss
+ && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) {
+ at76_dbg(DBG_BSS_TABLE_RM,
+ "%s: bss_list: removing old BSS %s ch %d",
+ priv->netdev->name, mac2str(ptr->bssid),
+ ptr->channel);
+ list_del(&ptr->list);
+ kfree(ptr);
+ }
+ }
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+ /* restart the timer */
+ mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
+}
+
+static inline void at76_set_mac_state(struct at76_priv *priv,
+ enum mac_state mac_state)
+{
+ at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name,
+ mac_states[mac_state]);
+ priv->mac_state = mac_state;
+}
+
+static void at76_dump_bss_table(struct at76_priv *priv)
+{
+ struct bss_info *ptr;
+ unsigned long flags;
+ struct list_head *lptr;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name,
+ priv->curr_bss);
+
+ list_for_each(lptr, &priv->bss_list) {
+ ptr = list_entry(lptr, struct bss_info, list);
+ at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s "
+ "(%s) capa 0x%04x rates %s rssi %d link %d noise %d",
+ ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len,
+ ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len),
+ ptr->capa, hex2str(ptr->rates, ptr->rates_len),
+ ptr->rssi, ptr->link_qual, ptr->noise_level);
+ }
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
+/* Called upon successful association to mark interface as connected */
+static void at76_work_assoc_done(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_assoc_done);
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_ASSOC);
+ WARN_ON(!priv->curr_bss);
+ if (priv->mac_state != MAC_ASSOC || !priv->curr_bss)
+ goto exit;
+
+ if (priv->iw_mode == IW_MODE_INFRA) {
+ if (priv->pm_mode != AT76_PM_OFF) {
+ /* calculate the listen interval in units of
+ beacon intervals of the curr_bss */
+ u32 pm_period_beacon = (priv->pm_period >> 10) /
+ priv->curr_bss->beacon_interval;
+
+ pm_period_beacon = max(pm_period_beacon, 2u);
+ pm_period_beacon = min(pm_period_beacon, 0xffffu);
+
+ at76_dbg(DBG_PM,
+ "%s: pm_mode %d assoc id 0x%x listen int %d",
+ priv->netdev->name, priv->pm_mode,
+ priv->assoc_id, pm_period_beacon);
+
+ at76_set_associd(priv, priv->assoc_id);
+ at76_set_listen_interval(priv, (u16)pm_period_beacon);
+ }
+ schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT);
+ }
+ at76_set_pm_mode(priv);
+
+ netif_carrier_on(priv->netdev);
+ netif_wake_queue(priv->netdev);
+ at76_set_mac_state(priv, MAC_CONNECTED);
+ at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid);
+ at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s",
+ priv->netdev->name, mac2str(priv->curr_bss->bssid));
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* We only store the new mac address in netdev struct,
+ it gets set when the netdev is opened. */
+static int at76_set_mac_address(struct net_device *netdev, void *addr)
+{
+ struct sockaddr *mac = addr;
+ memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
+ return 1;
+}
+
+static struct net_device_stats *at76_get_stats(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ return &priv->stats;
+}
+
+static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d",
+ priv->wstats.qual.qual, priv->wstats.qual.level,
+ priv->wstats.qual.noise, priv->wstats.qual.updated);
+
+ return &priv->wstats;
+}
+
+static void at76_set_multicast(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int promisc;
+
+ promisc = ((netdev->flags & IFF_PROMISC) != 0);
+ if (promisc != priv->promisc) {
+ /* This gets called in interrupt, must reschedule */
+ priv->promisc = promisc;
+ schedule_work(&priv->work_set_promisc);
+ }
+}
+
+/* Stop all network activity, flush all pending tasks */
+static void at76_quiesce(struct at76_priv *priv)
+{
+ unsigned long flags;
+
+ netif_stop_queue(priv->netdev);
+ netif_carrier_off(priv->netdev);
+
+ at76_set_mac_state(priv, MAC_INIT);
+
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ cancel_delayed_work(&priv->dwork_restart);
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+ kfree(priv->next_mgmt_bulk);
+ priv->next_mgmt_bulk = NULL;
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+}
+
+/*******************************************************************************
+ * at76_priv implementations of iw_handler functions:
+ */
+static int at76_iw_handler_commit(struct net_device *netdev,
+ struct iw_request_info *info,
+ void *null, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
+ __func__);
+
+ if (priv->mac_state != MAC_INIT)
+ at76_quiesce(priv);
+
+ /* Wait half second before the restart to process subsequent
+ * requests from the same iwconfig in a single restart */
+ schedule_delayed_work(&priv->dwork_restart, HZ / 2);
+
+ return 0;
+}
+
+static int at76_iw_handler_get_name(struct net_device *netdev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ strcpy(name, "IEEE 802.11b");
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
+ return 0;
+}
+
+static int at76_iw_handler_set_freq(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int chan = -1;
+ int ret = -EIWCOMMIT;
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d",
+ netdev->name, freq->m, freq->e);
+
+ if ((freq->e == 0) && (freq->m <= 1000))
+ /* Setting by channel number */
+ chan = freq->m;
+ else {
+ /* Setting by frequency - search the table */
+ int mult = 1;
+ int i;
+
+ for (i = 0; i < (6 - freq->e); i++)
+ mult *= 10;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ if (freq->m == (channel_frequency[i] * mult))
+ chan = i + 1;
+ }
+ }
+
+ if (chan < 1 || !priv->domain)
+ /* non-positive channels are invalid
+ * we need a domain info to set the channel
+ * either that or an invalid frequency was
+ * provided by the user */
+ ret = -EINVAL;
+ else if (!(priv->domain->channel_map & (1 << (chan - 1)))) {
+ printk(KERN_INFO "%s: channel %d not allowed for domain %s\n",
+ priv->netdev->name, chan, priv->domain->name);
+ ret = -EINVAL;
+ }
+
+ if (ret == -EIWCOMMIT) {
+ priv->channel = chan;
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name,
+ chan);
+ }
+
+ return ret;
+}
+
+static int at76_iw_handler_get_freq(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ freq->m = priv->channel;
+ freq->e = 0;
+
+ if (priv->channel)
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d",
+ netdev->name, channel_frequency[priv->channel - 1], 6);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name,
+ priv->channel);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
+
+ if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
+ (*mode != IW_MODE_MONITOR))
+ return -EINVAL;
+
+ priv->iw_mode = *mode;
+ if (priv->iw_mode != IW_MODE_INFRA)
+ priv->pm_mode = AT76_PM_OFF;
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ *mode = priv->iw_mode;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
+
+ return 0;
+}
+
+static int at76_iw_handler_get_range(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ /* inspired by atmel.c */
+ struct at76_priv *priv = netdev_priv(netdev);
+ struct iw_range *range = (struct iw_range *)extra;
+ int i;
+
+ data->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ /* TODO: range->throughput = xxxxxx; */
+
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0x0000;
+
+ /* this driver doesn't maintain sensitivity information */
+ range->sensitivity = 0;
+
+ range->max_qual.qual = 100;
+ range->max_qual.level = 100;
+ range->max_qual.noise = 0;
+ range->max_qual.updated = IW_QUAL_NOISE_INVALID;
+
+ range->avg_qual.qual = 50;
+ range->avg_qual.level = 50;
+ range->avg_qual.noise = 0;
+ range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
+
+ range->bitrate[0] = 1000000;
+ range->bitrate[1] = 2000000;
+ range->bitrate[2] = 5500000;
+ range->bitrate[3] = 11000000;
+ range->num_bitrates = 4;
+
+ range->min_rts = 0;
+ range->max_rts = MAX_RTS_THRESHOLD;
+
+ range->min_frag = MIN_FRAG_THRESHOLD;
+ range->max_frag = MAX_FRAG_THRESHOLD;
+
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_ON;
+ range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R;
+
+ range->encoding_size[0] = WEP_SMALL_KEY_LEN;
+ range->encoding_size[1] = WEP_LARGE_KEY_LEN;
+ range->num_encoding_sizes = 2;
+ range->max_encoding_tokens = WEP_KEYS;
+
+ /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power
+ - take this for all (ignore antenna gains) */
+ range->txpower[0] = 15;
+ range->num_txpower = 1;
+ range->txpower_capa = IW_TXPOW_DBM;
+
+ range->we_version_source = WIRELESS_EXT;
+ range->we_version_compiled = WIRELESS_EXT;
+
+ /* same as the values used in atmel.c */
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->r_time_flags = 0;
+ range->min_retry = 1;
+ range->max_retry = 255;
+
+ range->num_channels = NUM_CHANNELS;
+ range->num_frequency = 0;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ /* test if channel map bit is raised */
+ if (priv->domain->channel_map & (0x1 << i)) {
+ range->num_frequency += 1;
+
+ range->freq[i].i = i + 1;
+ range->freq[i].m = channel_frequency[i] * 100000;
+ range->freq[i].e = 1; /* freq * 10^1 */
+ }
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_spy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
+ netdev->name, data->length);
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ return ret;
+}
+
+static int at76_iw_handler_get_spy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_get_spy(priv->netdev, info,
+ (union iwreq_data *)data, extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
+ netdev->name, data->length);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_thrspy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
+ netdev->name, data->length);
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ return ret;
+}
+
+static int at76_iw_handler_get_thrspy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret;
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
+ netdev->name, data->length);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_wap(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
+ mac2str(ap_addr->sa_data));
+
+ /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has
+ chosen any or auto AP preference */
+ if (is_broadcast_ether_addr(ap_addr->sa_data)
+ || is_zero_ether_addr(ap_addr->sa_data))
+ priv->wanted_bssid_valid = 0;
+ else {
+ /* user wants to set a preferred AP address */
+ priv->wanted_bssid_valid = 1;
+ memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN);
+ }
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_wap(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
+ mac2str(ap_addr->sa_data));
+
+ return 0;
+}
+
+static int at76_iw_handler_set_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ if (!netif_running(netdev)) {
+ ret = -ENETDOWN;
+ goto exit;
+ }
+
+ /* jal: we don't allow "iwlist ethX scan" while we are
+ in monitor mode */
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* Discard old scan results */
+ if ((jiffies - priv->last_scan) > (20 * HZ))
+ priv->scan_state = SCAN_IDLE;
+ priv->last_scan = jiffies;
+
+ /* Initiate a scan command */
+ if (priv->scan_state == SCAN_IN_PROGRESS) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ priv->scan_state = SCAN_IN_PROGRESS;
+
+ at76_quiesce(priv);
+
+ /* Try to do passive or active scan if WE asks as. */
+ if (wrqu->data.length
+ && wrqu->data.length == sizeof(struct iw_scan_req)) {
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+
+ if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
+ priv->scan_mode = SCAN_TYPE_PASSIVE;
+ else if (req->scan_type == IW_SCAN_TYPE_ACTIVE)
+ priv->scan_mode = SCAN_TYPE_ACTIVE;
+
+ /* Sanity check values? */
+ if (req->min_channel_time > 0)
+ priv->scan_min_time = req->min_channel_time;
+
+ if (req->max_channel_time > 0)
+ priv->scan_max_time = req->max_channel_time;
+ }
+
+ /* change to scanning state */
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+
+exit:
+ mutex_unlock(&priv->mtx);
+ return ret;
+}
+
+static int at76_iw_handler_get_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ unsigned long flags;
+ struct list_head *lptr, *nptr;
+ struct bss_info *curr_bss;
+ struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL);
+ char *curr_val, *curr_pos = extra;
+ int i;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
+
+ if (!iwe)
+ return -ENOMEM;
+
+ if (priv->scan_state != SCAN_COMPLETED) {
+ /* scan not yet finished */
+ kfree(iwe);
+ return -EAGAIN;
+ }
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ list_for_each_safe(lptr, nptr, &priv->bss_list) {
+ curr_bss = list_entry(lptr, struct bss_info, list);
+
+ iwe->cmd = SIOCGIWAP;
+ iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6);
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_ADDR_LEN);
+
+ iwe->u.data.length = curr_bss->ssid_len;
+ iwe->cmd = SIOCGIWESSID;
+ iwe->u.data.flags = 1;
+
+ curr_pos = iwe_stream_add_point(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ curr_bss->ssid);
+
+ iwe->cmd = SIOCGIWMODE;
+ iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ?
+ IW_MODE_ADHOC :
+ (curr_bss->capa & WLAN_CAPABILITY_ESS) ?
+ IW_MODE_MASTER : IW_MODE_AUTO;
+ /* IW_MODE_AUTO = 0 which I thought is
+ * the most logical value to return in this case */
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_UINT_LEN);
+
+ iwe->cmd = SIOCGIWFREQ;
+ iwe->u.freq.m = curr_bss->channel;
+ iwe->u.freq.e = 0;
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_FREQ_LEN);
+
+ iwe->cmd = SIOCGIWENCODE;
+ if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY)
+ iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe->u.data.flags = IW_ENCODE_DISABLED;
+
+ iwe->u.data.length = 0;
+ curr_pos = iwe_stream_add_point(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ NULL);
+
+ /* Add quality statistics */
+ iwe->cmd = IWEVQUAL;
+ iwe->u.qual.noise = 0;
+ iwe->u.qual.updated =
+ IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED;
+ iwe->u.qual.level = (curr_bss->rssi * 100 / 42);
+ if (iwe->u.qual.level > 100)
+ iwe->u.qual.level = 100;
+ if (at76_is_intersil(priv->board_type))
+ iwe->u.qual.qual = curr_bss->link_qual;
+ else {
+ iwe->u.qual.qual = 0;
+ iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID;
+ }
+ /* Add new value to event */
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_QUAL_LEN);
+
+ /* Rate: stuffing multiple values in a single event requires
+ * a bit more of magic - Jean II */
+ curr_val = curr_pos + IW_EV_LCP_LEN;
+
+ iwe->cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe->u.bitrate.fixed = 0;
+ iwe->u.bitrate.disabled = 0;
+ /* Max 8 values */
+ for (i = 0; i < curr_bss->rates_len; i++) {
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe->u.bitrate.value =
+ ((curr_bss->rates[i] & 0x7f) * 500000);
+ /* Add new value to event */
+ curr_val = iwe_stream_add_value(info, curr_pos,
+ curr_val,
+ extra +
+ IW_SCAN_MAX_DATA, iwe,
+ IW_EV_PARAM_LEN);
+ }
+
+ /* Check if we added any event */
+ if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
+ curr_pos = curr_val;
+
+ /* more information may be sent back using IWECUSTOM */
+
+ }
+
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+
+ data->length = (curr_pos - extra);
+ data->flags = 0;
+
+ kfree(iwe);
+ return 0;
+}
+
+static int at76_iw_handler_set_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
+
+ if (data->flags) {
+ memcpy(priv->essid, extra, data->length);
+ priv->essid_size = data->length;
+ } else
+ priv->essid_size = 0; /* Use any SSID */
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ if (priv->essid_size) {
+ /* not the ANY ssid in priv->essid */
+ data->flags = 1;
+ data->length = priv->essid_size;
+ memcpy(extra, priv->essid, data->length);
+ } else {
+ /* the ANY ssid was specified */
+ if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) {
+ /* report the SSID we have found */
+ data->flags = 1;
+ data->length = priv->curr_bss->ssid_len;
+ memcpy(extra, priv->curr_bss->ssid, data->length);
+ } else {
+ /* report ANY back */
+ data->flags = 0;
+ data->length = 0;
+ }
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name,
+ data->length, extra);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_rate(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *bitrate, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
+ bitrate->value);
+
+ switch (bitrate->value) {
+ case -1:
+ priv->txrate = TX_RATE_AUTO;
+ break; /* auto rate */
+ case 1000000:
+ priv->txrate = TX_RATE_1MBIT;
+ break;
+ case 2000000:
+ priv->txrate = TX_RATE_2MBIT;
+ break;
+ case 5500000:
+ priv->txrate = TX_RATE_5_5MBIT;
+ break;
+ case 11000000:
+ priv->txrate = TX_RATE_11MBIT;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int at76_iw_handler_get_rate(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *bitrate, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ switch (priv->txrate) {
+ /* return max rate if RATE_AUTO */
+ case TX_RATE_AUTO:
+ bitrate->value = 11000000;
+ break;
+ case TX_RATE_1MBIT:
+ bitrate->value = 1000000;
+ break;
+ case TX_RATE_2MBIT:
+ bitrate->value = 2000000;
+ break;
+ case TX_RATE_5_5MBIT:
+ bitrate->value = 5500000;
+ break;
+ case TX_RATE_11MBIT:
+ bitrate->value = 11000000;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ bitrate->fixed = (priv->txrate != TX_RATE_AUTO);
+ bitrate->disabled = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
+ bitrate->value);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_rts(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+ int rthr = rts->value;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
+ netdev->name, rts->value, (rts->disabled) ? "true" : "false");
+
+ if (rts->disabled)
+ rthr = MAX_RTS_THRESHOLD;
+
+ if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD))
+ ret = -EINVAL;
+ else
+ priv->rts_threshold = rthr;
+
+ return ret;
+}
+
+static int at76_iw_handler_get_rts(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ rts->value = priv->rts_threshold;
+ rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
+ rts->fixed = 1;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
+ netdev->name, rts->value, (rts->disabled) ? "true" : "false");
+
+ return 0;
+}
+
+static int at76_iw_handler_set_frag(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+ int fthr = frag->value;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
+ netdev->name, frag->value,
+ (frag->disabled) ? "true" : "false");
+
+ if (frag->disabled)
+ fthr = MAX_FRAG_THRESHOLD;
+
+ if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD))
+ ret = -EINVAL;
+ else
+ priv->frag_threshold = fthr & ~0x1; /* get an even value */
+
+ return ret;
+}
+
+static int at76_iw_handler_get_frag(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ frag->value = priv->frag_threshold;
+ frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
+ frag->fixed = 1;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
+ netdev->name, frag->value,
+ (frag->disabled) ? "true" : "false");
+
+ return 0;
+}
+
+static int at76_iw_handler_get_txpow(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *power, char *extra)
+{
+ power->value = 15;
+ power->fixed = 1; /* No power control */
+ power->disabled = 0;
+ power->flags = IW_TXPOW_DBM;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
+ power->value);
+
+ return 0;
+}
+
+/* jal: short retry is handled by the firmware (at least 0.90.x),
+ while long retry is not (?) */
+static int at76_iw_handler_set_retry(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d",
+ netdev->name, retry->disabled, retry->flags, retry->value);
+
+ if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) {
+ if ((retry->flags & IW_RETRY_MIN) ||
+ !(retry->flags & IW_RETRY_MAX))
+ priv->short_retry_limit = retry->value;
+ else
+ ret = -EINVAL;
+ } else
+ ret = -EINVAL;
+
+ return ret;
+}
+
+/* Adapted (ripped) from atmel.c */
+static int at76_iw_handler_get_retry(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
+
+ retry->disabled = 0; /* Can't be disabled */
+ retry->flags = IW_RETRY_LIMIT;
+ retry->value = priv->short_retry_limit;
+
+ return 0;
+}
+
+static int at76_iw_handler_set_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *encoding, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ int len = encoding->length;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x "
+ "pointer %p len %d", netdev->name, encoding->flags,
+ encoding->pointer, encoding->length);
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d "
+ "auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id,
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ /* take the old default key if index is invalid */
+ if ((index < 0) || (index >= WEP_KEYS))
+ index = priv->wep_key_id;
+
+ if (len > 0) {
+ if (len > WEP_LARGE_KEY_LEN)
+ len = WEP_LARGE_KEY_LEN;
+
+ memset(priv->wep_keys[index], 0, WEP_KEY_LEN);
+ memcpy(priv->wep_keys[index], extra, len);
+ priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ?
+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+ priv->wep_enabled = 1;
+ }
+
+ priv->wep_key_id = index;
+ priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
+
+ if (encoding->flags & IW_ENCODE_RESTRICTED)
+ priv->auth_mode = WLAN_AUTH_SHARED_KEY;
+ if (encoding->flags & IW_ENCODE_OPEN)
+ priv->auth_mode = WLAN_AUTH_OPEN;
+
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d "
+ "key_len %d auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
+ priv->wep_keys_len[priv->wep_key_id],
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *encoding, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
+
+ if ((index < 0) || (index >= WEP_KEYS))
+ index = priv->wep_key_id;
+
+ encoding->flags =
+ (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ?
+ IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
+
+ if (!priv->wep_enabled)
+ encoding->flags |= IW_ENCODE_DISABLED;
+
+ if (encoding->pointer) {
+ encoding->length = priv->wep_keys_len[index];
+
+ memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]);
+
+ encoding->flags |= (index + 1);
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x "
+ "pointer %p len %d", netdev->name, encoding->flags,
+ encoding->pointer, encoding->length);
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d "
+ "key_len %d auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
+ priv->wep_keys_len[priv->wep_key_id],
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ return 0;
+}
+
+static int at76_iw_handler_set_power(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *prq, char *extra)
+{
+ int err = -EIWCOMMIT;
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x",
+ netdev->name, (prq->disabled) ? "true" : "false", prq->flags,
+ prq->value);
+
+ if (prq->disabled)
+ priv->pm_mode = AT76_PM_OFF;
+ else {
+ switch (prq->flags & IW_POWER_MODE) {
+ case IW_POWER_ALL_R:
+ case IW_POWER_ON:
+ break;
+ default:
+ err = -EINVAL;
+ goto exit;
+ }
+ if (prq->flags & IW_POWER_PERIOD)
+ priv->pm_period = prq->value;
+
+ if (prq->flags & IW_POWER_TIMEOUT) {
+ err = -EINVAL;
+ goto exit;
+ }
+ priv->pm_mode = AT76_PM_ON;
+ }
+exit:
+ return err;
+}
+
+static int at76_iw_handler_get_power(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *power, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ power->disabled = (priv->pm_mode == AT76_PM_OFF);
+ if (!power->disabled) {
+ power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R;
+ power->value = priv->pm_period;
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x",
+ netdev->name, power->disabled ? "disabled" : "enabled",
+ power->flags, power->value);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Private IOCTLS
+ */
+static int at76_iw_set_short_preamble(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d",
+ netdev->name, val);
+
+ if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO)
+ ret = -EINVAL;
+ else
+ priv->preamble_type = val;
+
+ return ret;
+}
+
+static int at76_iw_get_short_preamble(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)",
+ preambles[priv->preamble_type], priv->preamble_type);
+ return 0;
+}
+
+static int at76_iw_set_debug(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ char *ptr;
+ u32 val;
+
+ if (data->length > 0) {
+ val = simple_strtol(extra, &ptr, 0);
+
+ if (ptr == extra)
+ val = DBG_DEFAULTS;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x",
+ netdev->name, data->length, extra, val);
+ } else
+ val = DBG_DEFAULTS;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x",
+ netdev->name, at76_debug, val);
+
+ /* jal: some more output to pin down lockups */
+ at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d "
+ "carrier_ok %d", netdev->name, netif_running(netdev),
+ netif_queue_stopped(netdev), netif_carrier_ok(netdev));
+
+ at76_debug = val;
+
+ return 0;
+}
+
+static int at76_iw_get_debug(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug);
+ return 0;
+}
+
+static int at76_iw_set_powersave_mode(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)",
+ netdev->name, val,
+ val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" :
+ val == AT76_PM_SMART ? "smart save" : "<invalid>");
+ if (val < AT76_PM_OFF || val > AT76_PM_SMART)
+ ret = -EINVAL;
+ else
+ priv->pm_mode = val;
+
+ return ret;
+}
+
+static int at76_iw_get_powersave_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->pm_mode;
+ return 0;
+}
+
+static int at76_iw_set_scan_times(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int mint = *((int *)name);
+ int maxt = *((int *)name + 1);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d",
+ netdev->name, mint, maxt);
+ if (mint <= 0 || maxt <= 0 || mint > maxt)
+ ret = -EINVAL;
+ else {
+ priv->scan_min_time = mint;
+ priv->scan_max_time = maxt;
+ }
+
+ return ret;
+}
+
+static int at76_iw_get_scan_times(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->scan_min_time;
+ param[1] = priv->scan_max_time;
+ return 0;
+}
+
+static int at76_iw_set_scan_mode(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s",
+ netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" :
+ (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>");
+
+ if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE)
+ ret = -EINVAL;
+ else
+ priv->scan_mode = val;
+
+ return ret;
+}
+
+static int at76_iw_get_scan_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->scan_mode;
+ return 0;
+}
+
+#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f
+
+/* Standard wireless handlers */
+static const iw_handler at76_handlers[] = {
+ AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit),
+ AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name),
+ AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq),
+ AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq),
+ AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode),
+ AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode),
+ AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range),
+ AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy),
+ AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy),
+ AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy),
+ AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy),
+ AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap),
+ AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap),
+ AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan),
+ AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan),
+ AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid),
+ AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid),
+ AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate),
+ AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate),
+ AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts),
+ AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts),
+ AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag),
+ AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag),
+ AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow),
+ AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry),
+ AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry),
+ AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode),
+ AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode),
+ AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power),
+ AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power)
+};
+
+#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f
+
+/* Private wireless handlers */
+static const iw_handler at76_priv_handlers[] = {
+ AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble),
+ AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble),
+ AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug),
+ AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug),
+ AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode),
+ AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode),
+ AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times),
+ AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times),
+ AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode),
+ AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode),
+};
+
+/* Names and arguments of private wireless handlers */
+static const struct iw_priv_args at76_priv_args[] = {
+ /* 0 - long, 1 - short */
+ {AT76_SET_SHORT_PREAMBLE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
+
+ {AT76_GET_SHORT_PREAMBLE,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"},
+
+ /* we must pass the new debug mask as a string, because iwpriv cannot
+ * parse hex numbers starting with 0x :-( */
+ {AT76_SET_DEBUG,
+ IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"},
+
+ {AT76_GET_DEBUG,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"},
+
+ /* 1 - active, 2 - power save, 3 - smart power save */
+ {AT76_SET_POWERSAVE_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"},
+
+ {AT76_GET_POWERSAVE_MODE,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"},
+
+ /* min_channel_time, max_channel_time */
+ {AT76_SET_SCAN_TIMES,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"},
+
+ {AT76_GET_SCAN_TIMES,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"},
+
+ /* 0 - active, 1 - passive scan */
+ {AT76_SET_SCAN_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"},
+
+ {AT76_GET_SCAN_MODE,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"},
+};
+
+static const struct iw_handler_def at76_handler_def = {
+ .num_standard = ARRAY_SIZE(at76_handlers),
+ .num_private = ARRAY_SIZE(at76_priv_handlers),
+ .num_private_args = ARRAY_SIZE(at76_priv_args),
+ .standard = at76_handlers,
+ .private = at76_priv_handlers,
+ .private_args = at76_priv_args,
+ .get_wireless_stats = at76_get_wireless_stats,
+};
+
+static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 };
+
+/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with
+ * a SNAP OID of 0 (0x00, 0x00, 0x00) */
+static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+
+static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ struct net_device_stats *stats = &priv->stats;
+ int ret = 0;
+ int wlen;
+ int submit_len;
+ struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
+ struct ieee80211_hdr_3addr *i802_11_hdr =
+ (struct ieee80211_hdr_3addr *)tx_buffer->packet;
+ u8 *payload = i802_11_hdr->payload;
+ struct ethhdr *eh = (struct ethhdr *)skb->data;
+
+ if (netif_queue_stopped(netdev)) {
+ printk(KERN_ERR "%s: %s called while netdev is stopped\n",
+ netdev->name, __func__);
+ /* skip this packet */
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (priv->tx_urb->status == -EINPROGRESS) {
+ printk(KERN_ERR "%s: %s called while tx urb is pending\n",
+ netdev->name, __func__);
+ /* skip this packet */
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (skb->len < ETH_HLEN) {
+ printk(KERN_ERR "%s: %s: skb too short (%d)\n",
+ netdev->name, __func__, skb->len);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+
+ /* we can get rid of memcpy if we set netdev->hard_header_len to
+ reserve enough space, but we would need to keep the skb around */
+
+ if (ntohs(eh->h_proto) <= ETH_DATA_LEN) {
+ /* this is a 802.3 packet */
+ if (skb->len >= ETH_HLEN + sizeof(rfc1042sig)
+ && skb->data[ETH_HLEN] == rfc1042sig[0]
+ && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) {
+ /* higher layer delivered SNAP header - keep it */
+ memcpy(payload, skb->data + ETH_HLEN,
+ skb->len - ETH_HLEN);
+ wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN;
+ } else {
+ printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet "
+ "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n",
+ priv->netdev->name, skb->data[ETH_HLEN],
+ skb->data[ETH_HLEN + 1],
+ skb->data[ETH_HLEN + 2]);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ } else {
+ /* add RFC 1042 header in front */
+ memcpy(payload, rfc1042sig, sizeof(rfc1042sig));
+ memcpy(payload + sizeof(rfc1042sig), &eh->h_proto,
+ skb->len - offsetof(struct ethhdr, h_proto));
+ wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len -
+ offsetof(struct ethhdr, h_proto);
+ }
+
+ /* make wireless header */
+ i802_11_hdr->frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_DATA |
+ (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) |
+ (priv->iw_mode ==
+ IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0));
+
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN);
+ memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
+ memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN);
+ } else if (priv->iw_mode == IW_MODE_INFRA) {
+ memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN);
+ memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
+ memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN);
+ }
+
+ i802_11_hdr->duration_id = cpu_to_le16(0);
+ i802_11_hdr->seq_ctl = cpu_to_le16(0);
+
+ /* setup 'Atmel' header */
+ tx_buffer->wlength = cpu_to_le16(wlen);
+ tx_buffer->tx_rate = priv->txrate;
+ /* for broadcast destination addresses, the firmware 0.100.x
+ seems to choose the highest rate set with CMD_STARTUP in
+ basic_rate_set replacing this value */
+
+ memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
+
+ tx_buffer->padding = at76_calc_padding(wlen);
+ submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding;
+
+ at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name,
+ hex2str(skb->data, 32));
+ at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s",
+ priv->netdev->name,
+ le16_to_cpu(tx_buffer->wlength),
+ tx_buffer->padding, tx_buffer->tx_rate,
+ hex2str(i802_11_hdr, sizeof(*i802_11_hdr)));
+ at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name,
+ hex2str(payload, 48));
+
+ /* send stuff */
+ netif_stop_queue(netdev);
+ netdev->trans_start = jiffies;
+
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
+ submit_len, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret) {
+ stats->tx_errors++;
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ netdev->name, ret);
+ if (ret == -EINVAL)
+ printk(KERN_ERR
+ "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
+ priv->netdev->name, priv->tx_urb,
+ priv->tx_urb->hcpriv, priv->tx_urb->complete);
+ } else {
+ stats->tx_bytes += skb->len;
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
+static void at76_tx_timeout(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ if (!priv)
+ return;
+ dev_warn(&netdev->dev, "tx timeout.");
+
+ usb_unlink_urb(priv->tx_urb);
+ priv->stats.tx_errors++;
+}
+
static int at76_submit_rx_urb(struct at76_priv *priv)
{
int ret;
@@ -1327,7 +3270,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
if (!priv->rx_urb) {
printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
- wiphy_name(priv->hw->wiphy), __func__);
+ priv->netdev->name, __func__);
return -EFAULT;
}
@@ -1335,7 +3278,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
if (!skb) {
printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
- wiphy_name(priv->hw->wiphy));
+ priv->netdev->name);
ret = -ENOMEM;
goto exit;
}
@@ -1355,18 +3298,110 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
"usb_submit_urb returned -ENODEV");
else
printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
}
exit:
if (ret < 0 && ret != -ENODEV)
printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
"driver and/or power cycle the device\n",
- wiphy_name(priv->hw->wiphy));
+ priv->netdev->name);
return ret;
}
+static int at76_open(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ /* if netdev->dev_addr != priv->mac_addr we must
+ set the mac address in the device ! */
+ if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) {
+ if (at76_add_mac_address(priv, netdev->dev_addr) >= 0)
+ at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s",
+ netdev->name, mac2str(netdev->dev_addr));
+ }
+
+ priv->scan_state = SCAN_IDLE;
+ priv->last_scan = jiffies;
+
+ ret = at76_submit_rx_urb(priv);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
+ netdev->name, ret);
+ goto error;
+ }
+
+ schedule_delayed_work(&priv->dwork_restart, 0);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__);
+error:
+ mutex_unlock(&priv->mtx);
+ return ret < 0 ? ret : 0;
+}
+
+static int at76_stop(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ at76_quiesce(priv);
+
+ if (!priv->device_unplugged) {
+ /* We are called by "ifconfig ethX down", not because the
+ * device is not available anymore. */
+ at76_set_radio(priv, 0);
+
+ /* We unlink rx_urb because at76_open() re-submits it.
+ * If unplugged, at76_delete_device() takes care of it. */
+ usb_kill_urb(priv->rx_urb);
+ }
+
+ /* free the bss_list */
+ at76_free_bss_list(priv);
+
+ mutex_unlock(&priv->mtx);
+ at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__);
+
+ return 0;
+}
+
+static void at76_ethtool_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *info)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
+
+ usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info));
+
+ snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d",
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+}
+
+static u32 at76_ethtool_get_link(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ return priv->mac_state == MAC_CONNECTED;
+}
+
+static struct ethtool_ops at76_ethtool_ops = {
+ .get_drvinfo = at76_ethtool_get_drvinfo,
+ .get_link = at76_ethtool_get_link,
+};
+
/* Download external firmware */
static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
{
@@ -1463,6 +3498,406 @@ exit:
return ret;
}
+static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr)
+{
+ /* common criteria for both modi */
+
+ int ret = (priv->essid_size == 0 /* ANY ssid */ ||
+ (priv->essid_size == ptr->ssid_len &&
+ !memcmp(priv->essid, ptr->ssid, ptr->ssid_len)));
+ if (!ret)
+ at76_dbg(DBG_BSS_MATCH,
+ "%s bss table entry %p: essid didn't match",
+ priv->netdev->name, ptr);
+ return ret;
+}
+
+static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr)
+{
+ int ret;
+
+ if (priv->iw_mode == IW_MODE_ADHOC)
+ ret = ptr->capa & WLAN_CAPABILITY_IBSS;
+ else
+ ret = ptr->capa & WLAN_CAPABILITY_ESS;
+ if (!ret)
+ at76_dbg(DBG_BSS_MATCH,
+ "%s bss table entry %p: mode didn't match",
+ priv->netdev->name, ptr);
+ return ret;
+}
+
+static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr)
+{
+ int i;
+
+ for (i = 0; i < ptr->rates_len; i++) {
+ u8 rate = ptr->rates[i];
+
+ if (!(rate & 0x80))
+ continue;
+
+ /* this is a basic rate we have to support
+ (see IEEE802.11, ch. 7.3.2.2) */
+ if (rate != (0x80 | hw_rates[0])
+ && rate != (0x80 | hw_rates[1])
+ && rate != (0x80 | hw_rates[2])
+ && rate != (0x80 | hw_rates[3])) {
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: bss table entry %p: basic rate %02x not "
+ "supported", priv->netdev->name, ptr, rate);
+ return 0;
+ }
+ }
+
+ /* if we use short preamble, the bss must support it */
+ if (priv->preamble_type == PREAMBLE_TYPE_SHORT &&
+ !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: %p does not support short preamble",
+ priv->netdev->name, ptr);
+ return 0;
+ } else
+ return 1;
+}
+
+static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr)
+{
+ if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) {
+ /* we have disabled WEP, but the BSS signals privacy */
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: bss table entry %p: requires encryption",
+ priv->netdev->name, ptr);
+ return 0;
+ }
+ /* otherwise if the BSS does not signal privacy it may well
+ accept encrypted packets from us ... */
+ return 1;
+}
+
+static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr)
+{
+ if (!priv->wanted_bssid_valid ||
+ !compare_ether_addr(ptr->bssid, priv->wanted_bssid))
+ return 1;
+
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: requested bssid - %s does not match",
+ priv->netdev->name, mac2str(priv->wanted_bssid));
+ at76_dbg(DBG_BSS_MATCH,
+ " AP bssid - %s of bss table entry %p",
+ mac2str(ptr->bssid), ptr);
+ return 0;
+}
+
+/**
+ * at76_match_bss - try to find a matching bss in priv->bss
+ *
+ * last - last bss tried
+ *
+ * last == NULL signals a new round starting with priv->bss_list.next
+ * this function must be called inside an acquired priv->bss_list_spinlock
+ * otherwise the timeout on bss may remove the newly chosen entry
+ */
+static struct bss_info *at76_match_bss(struct at76_priv *priv,
+ struct bss_info *last)
+{
+ struct bss_info *ptr = NULL;
+ struct list_head *curr;
+
+ curr = last ? last->list.next : priv->bss_list.next;
+ while (curr != &priv->bss_list) {
+ ptr = list_entry(curr, struct bss_info, list);
+ if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr)
+ && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr)
+ && at76_match_bssid(priv, ptr))
+ break;
+ curr = curr->next;
+ }
+
+ if (curr == &priv->bss_list)
+ ptr = NULL;
+ /* otherwise ptr points to the struct bss_info we have chosen */
+
+ at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name,
+ __func__, ptr);
+ return ptr;
+}
+
+/* Start joining a matching BSS, or create own IBSS */
+static void at76_work_join(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_join);
+ int ret;
+ unsigned long flags;
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_JOINING);
+ if (priv->mac_state != MAC_JOINING)
+ goto exit;
+
+ /* secure the access to priv->curr_bss ! */
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+ priv->curr_bss = at76_match_bss(priv, priv->curr_bss);
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+
+ if (!priv->curr_bss) {
+ /* here we haven't found a matching (i)bss ... */
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ at76_set_mac_state(priv, MAC_OWN_IBSS);
+ at76_start_ibss(priv);
+ goto exit;
+ }
+ /* haven't found a matching BSS in infra mode - try again */
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+ goto exit;
+ }
+
+ ret = at76_join_bss(priv, priv->curr_bss);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: join_bss failed with %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ ret = at76_wait_completion(priv, CMD_JOIN);
+ if (ret != CMD_STATUS_COMPLETE) {
+ if (ret != CMD_STATUS_TIME_OUT)
+ printk(KERN_ERR "%s: join_bss completed with %d\n",
+ priv->netdev->name, ret);
+ else
+ printk(KERN_INFO "%s: join_bss ssid %s timed out\n",
+ priv->netdev->name,
+ mac2str(priv->curr_bss->bssid));
+
+ /* retry next BSS immediately */
+ schedule_work(&priv->work_join);
+ goto exit;
+ }
+
+ /* here we have joined the (I)BSS */
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ struct bss_info *bptr = priv->curr_bss;
+ at76_set_mac_state(priv, MAC_CONNECTED);
+ /* get ESSID, BSSID and channel for priv->curr_bss */
+ priv->essid_size = bptr->ssid_len;
+ memcpy(priv->essid, bptr->ssid, bptr->ssid_len);
+ memcpy(priv->bssid, bptr->bssid, ETH_ALEN);
+ priv->channel = bptr->channel;
+ at76_iwevent_bss_connect(priv->netdev, bptr->bssid);
+ netif_carrier_on(priv->netdev);
+ netif_start_queue(priv->netdev);
+ /* just to be sure */
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ } else {
+ /* send auth req */
+ priv->retries = AUTH_RETRIES;
+ at76_set_mac_state(priv, MAC_AUTH);
+ at76_auth_req(priv, priv->curr_bss, 1, NULL);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Reap scan results */
+static void at76_dwork_get_scan(struct work_struct *work)
+{
+ int status;
+ int ret;
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_get_scan.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_SCANNING);
+ if (priv->mac_state != MAC_SCANNING)
+ goto exit;
+
+ status = at76_get_cmd_status(priv->udev, CMD_SCAN);
+ if (status < 0) {
+ printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n",
+ priv->netdev->name, __func__, status);
+ status = CMD_STATUS_IN_PROGRESS;
+ /* INFO: Hope it was a one off error - if not, scanning
+ further down the line and stop this cycle */
+ }
+ at76_dbg(DBG_PROGRESS,
+ "%s %s: got cmd_status %d (state %s, need_any %d)",
+ priv->netdev->name, __func__, status,
+ mac_states[priv->mac_state], priv->scan_need_any);
+
+ if (status != CMD_STATUS_COMPLETE) {
+ if ((status != CMD_STATUS_IN_PROGRESS) &&
+ (status != CMD_STATUS_IDLE))
+ printk(KERN_ERR "%s: %s: Bad scan status: %s\n",
+ priv->netdev->name, __func__,
+ at76_get_cmd_status_string(status));
+
+ /* the first cmd status after scan start is always a IDLE ->
+ start the timer to poll again until COMPLETED */
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks",
+ __func__, __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ goto exit;
+ }
+
+ if (at76_debug & DBG_BSS_TABLE)
+ at76_dump_bss_table(priv);
+
+ if (priv->scan_need_any) {
+ ret = at76_start_scan(priv, 0);
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: %s: start_scan (ANY) failed with %d\n",
+ priv->netdev->name, __func__, ret);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks", __func__,
+ __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ priv->scan_need_any = 0;
+ } else {
+ priv->scan_state = SCAN_COMPLETED;
+ /* report the end of scan to user space */
+ at76_iwevent_scan_complete(priv->netdev);
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle loss of beacons from the AP */
+static void at76_dwork_beacon(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_beacon.work);
+
+ mutex_lock(&priv->mtx);
+ if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA)
+ goto exit;
+
+ /* We haven't received any beacons from out AP for BEACON_TIMEOUT */
+ printk(KERN_INFO "%s: lost beacon bssid %s\n",
+ priv->netdev->name, mac2str(priv->curr_bss->bssid));
+
+ netif_carrier_off(priv->netdev);
+ netif_stop_queue(priv->netdev);
+ at76_iwevent_bss_disconnect(priv->netdev);
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle authentication response timeout */
+static void at76_dwork_auth(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_auth.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_AUTH);
+ if (priv->mac_state != MAC_AUTH)
+ goto exit;
+
+ at76_dbg(DBG_PROGRESS, "%s: authentication response timeout",
+ priv->netdev->name);
+
+ if (priv->retries-- >= 0) {
+ at76_auth_req(priv, priv->curr_bss, 1, NULL);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
+ __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+ } else {
+ /* try to get next matching BSS */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle association response timeout */
+static void at76_dwork_assoc(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_assoc.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_ASSOC);
+ if (priv->mac_state != MAC_ASSOC)
+ goto exit;
+
+ at76_dbg(DBG_PROGRESS, "%s: association response timeout",
+ priv->netdev->name);
+
+ if (priv->retries-- >= 0) {
+ at76_assoc_req(priv, priv->curr_bss);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
+ __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
+ } else {
+ /* try to get next matching BSS */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Read new bssid in ad-hoc mode */
+static void at76_work_new_bss(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_new_bss);
+ int ret;
+ struct mib_mac_mgmt mac_mgmt;
+
+ mutex_lock(&priv->mtx);
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change);
+ memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN);
+ at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid));
+
+ at76_iwevent_bss_connect(priv->netdev, priv->bssid);
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
+ priv->mib_buf.data.byte = 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
+ priv->netdev->name, ret);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
static int at76_startup_device(struct at76_priv *priv)
{
struct at76_card_config *ccfg = &priv->card_config;
@@ -1470,14 +3905,14 @@ static int at76_startup_device(struct at76_priv *priv)
at76_dbg(DBG_PARAMS,
"%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
- "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size,
- priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE),
+ "keylen %d", priv->netdev->name, priv->essid_size, priv->essid,
+ hex2str(priv->essid, IW_ESSID_MAX_SIZE),
priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
priv->channel, priv->wep_enabled ? "enabled" : "disabled",
priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
at76_dbg(DBG_PARAMS,
"%s param: preamble %s rts %d retry %d frag %d "
- "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy),
+ "txrate %s auth_mode %d", priv->netdev->name,
preambles[priv->preamble_type], priv->rts_threshold,
priv->short_retry_limit, priv->frag_threshold,
priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
@@ -1488,7 +3923,7 @@ static int at76_startup_device(struct at76_priv *priv)
at76_dbg(DBG_PARAMS,
"%s param: pm_mode %d pm_period %d auth_mode %s "
"scan_times %d %d scan_mode %s",
- wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period,
+ priv->netdev->name, priv->pm_mode, priv->pm_period,
priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
priv->scan_min_time, priv->scan_max_time,
priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
@@ -1522,8 +3957,7 @@ static int at76_startup_device(struct at76_priv *priv)
ccfg->ssid_len = priv->essid_size;
ccfg->wep_default_key_id = priv->wep_key_id;
- memcpy(ccfg->wep_default_key_value, priv->wep_keys,
- sizeof(priv->wep_keys));
+ memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN);
ccfg->short_preamble = priv->preamble_type;
ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
@@ -1532,7 +3966,7 @@ static int at76_startup_device(struct at76_priv *priv)
sizeof(struct at76_card_config));
if (ret < 0) {
printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -1578,6 +4012,69 @@ static int at76_startup_device(struct at76_priv *priv)
return 0;
}
+/* Restart the interface */
+static void at76_dwork_restart(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_restart.work);
+
+ mutex_lock(&priv->mtx);
+
+ netif_carrier_off(priv->netdev); /* stop netdev watchdog */
+ netif_stop_queue(priv->netdev); /* stop tx data packets */
+
+ at76_startup_device(priv);
+
+ if (priv->iw_mode != IW_MODE_MONITOR) {
+ priv->netdev->type = ARPHRD_ETHER;
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+ } else {
+ priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
+ at76_start_monitor(priv);
+ }
+
+ mutex_unlock(&priv->mtx);
+}
+
+/* Initiate scanning */
+static void at76_work_start_scan(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_start_scan);
+ int ret;
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_SCANNING);
+ if (priv->mac_state != MAC_SCANNING)
+ goto exit;
+
+ /* only clear the bss list when a scan is actively initiated,
+ * otherwise simply rely on at76_bss_list_timeout */
+ if (priv->scan_state == SCAN_IN_PROGRESS) {
+ at76_free_bss_list(priv);
+ priv->scan_need_any = 1;
+ } else
+ priv->scan_need_any = 0;
+
+ ret = at76_start_scan(priv, 1);
+
+ if (ret < 0)
+ printk(KERN_ERR "%s: %s: start_scan failed with %d\n",
+ priv->netdev->name, __func__, ret);
+ else {
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks",
+ __func__, __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
/* Enable or disable promiscuous mode */
static void at76_work_set_promisc(struct work_struct *work)
{
@@ -1595,7 +4092,7 @@ static void at76_work_set_promisc(struct work_struct *work)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
mutex_unlock(&priv->mtx);
}
@@ -1611,759 +4108,1088 @@ static void at76_work_submit_rx(struct work_struct *work)
mutex_unlock(&priv->mtx);
}
-static void at76_rx_tasklet(unsigned long param)
+/* We got an association response */
+static void at76_rx_mgmt_assoc(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct urb *urb = (struct urb *)param;
- struct at76_priv *priv = urb->context;
- struct at76_rx_buffer *buf;
- struct ieee80211_rx_status rx_status = { 0 };
-
- if (priv->device_unplugged) {
- at76_dbg(DBG_DEVSTART, "device unplugged");
- if (urb)
- at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ struct ieee80211_assoc_response *resp =
+ (struct ieee80211_assoc_response *)buf->packet;
+ u16 assoc_id = le16_to_cpu(resp->aid);
+ u16 status = le16_to_cpu(resp->status);
+
+ at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status "
+ "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name,
+ mac2str(resp->header.addr3), le16_to_cpu(resp->capability),
+ status, assoc_id, hex2str(resp->info_element->data,
+ resp->info_element->len));
+
+ if (priv->mac_state != MAC_ASSOC) {
+ printk(KERN_INFO "%s: AssocResp in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
return;
}
- if (!priv->rx_skb || !priv->rx_skb->data)
- return;
-
- buf = (struct at76_rx_buffer *)priv->rx_skb->data;
-
- if (urb->status != 0) {
- if (urb->status != -ENOENT && urb->status != -ECONNRESET)
- at76_dbg(DBG_URB,
- "%s %s: - nonzero Rx bulk status received: %d",
- __func__, wiphy_name(priv->hw->wiphy),
- urb->status);
- return;
+ BUG_ON(!priv->curr_bss);
+
+ cancel_delayed_work(&priv->dwork_assoc);
+ if (status == WLAN_STATUS_SUCCESS) {
+ struct bss_info *ptr = priv->curr_bss;
+ priv->assoc_id = assoc_id & 0x3fff;
+ /* update iwconfig params */
+ memcpy(priv->bssid, ptr->bssid, ETH_ALEN);
+ memcpy(priv->essid, ptr->ssid, ptr->ssid_len);
+ priv->essid_size = ptr->ssid_len;
+ priv->channel = ptr->channel;
+ schedule_work(&priv->work_assoc_done);
+ } else {
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
}
+}
- at76_dbg(DBG_RX_ATMEL_HDR,
- "%s: rx frame: rate %d rssi %d noise %d link %d",
- wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi,
- buf->noise_level, buf->link_quality);
-
- skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength) + AT76_RX_HDRLEN);
- at76_dbg_dump(DBG_RX_DATA, &priv->rx_skb->data[AT76_RX_HDRLEN],
- priv->rx_skb->len, "RX: len=%d",
- (int)(priv->rx_skb->len - AT76_RX_HDRLEN));
+/* Process disassociation request from the AP */
+static void at76_rx_mgmt_disassoc(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_disassoc *resp =
+ (struct ieee80211_disassoc *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+
+ at76_dbg(DBG_RX_MGMT,
+ "%s: rx DisAssoc bssid %s reason 0x%04x destination %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
+
+ /* We are not connected, ignore */
+ if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT
+ || !priv->curr_bss)
+ return;
- rx_status.signal = buf->rssi;
- /* FIXME: is rate_idx still present in structure? */
- rx_status.rate_idx = buf->rx_rate;
- rx_status.flag |= RX_FLAG_DECRYPTED;
- rx_status.flag |= RX_FLAG_IV_STRIPPED;
+ /* Not our BSSID, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
+ return;
- skb_pull(priv->rx_skb, AT76_RX_HDRLEN);
- at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
- priv->rx_skb->len, priv->rx_skb->data_len);
- ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
+ /* Not for our STA and not broadcast, ignore */
+ if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
+ && !is_broadcast_ether_addr(mgmt->addr1))
+ return;
- /* Use a new skb for the next receive */
- priv->rx_skb = NULL;
+ if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED
+ && priv->mac_state != MAC_JOINING) {
+ printk(KERN_INFO "%s: DisAssoc in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
- at76_submit_rx_urb(priv);
+ if (priv->mac_state == MAC_CONNECTED) {
+ netif_carrier_off(priv->netdev);
+ netif_stop_queue(priv->netdev);
+ at76_iwevent_bss_disconnect(priv->netdev);
+ }
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
}
-/* Load firmware into kernel memory and parse it */
-static struct fwentry *at76_load_firmware(struct usb_device *udev,
- enum board_type board_type)
+static void at76_rx_mgmt_auth(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- int ret;
- char *str;
- struct at76_fw_header *fwh;
- struct fwentry *fwe = &firmwares[board_type];
-
- mutex_lock(&fw_mutex);
-
- if (fwe->loaded) {
- at76_dbg(DBG_FW, "re-using previously loaded fw");
- goto exit;
+ struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+ int seq_nr = le16_to_cpu(resp->transaction);
+ int alg = le16_to_cpu(resp->algorithm);
+ int status = le16_to_cpu(resp->status);
+
+ at76_dbg(DBG_RX_MGMT,
+ "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
+ "destination %s", priv->netdev->name, mac2str(mgmt->addr3),
+ alg, seq_nr, status, mac2str(mgmt->addr1));
+
+ if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2)
+ at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...",
+ priv->netdev->name, hex2str(resp->info_element, 18));
+
+ if (priv->mac_state != MAC_AUTH) {
+ printk(KERN_INFO "%s: ignored AuthFrame in state %s\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
}
-
- at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
- ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
- if (ret < 0) {
- dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
- fwe->fwname);
- dev_printk(KERN_ERR, &udev->dev,
- "you may need to download the firmware from "
- "http://developer.berlios.de/projects/at76c503a/\n");
- goto exit;
+ if (priv->auth_mode != alg) {
+ printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n",
+ priv->netdev->name, alg);
+ return;
}
- at76_dbg(DBG_FW, "got it.");
- fwh = (struct at76_fw_header *)(fwe->fw->data);
+ BUG_ON(!priv->curr_bss);
- if (fwe->fw->size <= sizeof(*fwh)) {
- dev_printk(KERN_ERR, &udev->dev,
- "firmware is too short (0x%zx)\n", fwe->fw->size);
- goto exit;
+ /* Not our BSSID or not for our STA, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)
+ || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1))
+ return;
+
+ cancel_delayed_work(&priv->dwork_auth);
+ if (status != WLAN_STATUS_SUCCESS) {
+ /* try to join next bss */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ return;
}
- /* CRC currently not checked */
- fwe->board_type = le32_to_cpu(fwh->board_type);
- if (fwe->board_type != board_type) {
- dev_printk(KERN_ERR, &udev->dev,
- "board type mismatch, requested %u, got %u\n",
- board_type, fwe->board_type);
- goto exit;
+ if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) {
+ priv->retries = ASSOC_RETRIES;
+ at76_set_mac_state(priv, MAC_ASSOC);
+ at76_assoc_req(priv, priv->curr_bss);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
+ return;
}
- fwe->fw_version.major = fwh->major;
- fwe->fw_version.minor = fwh->minor;
- fwe->fw_version.patch = fwh->patch;
- fwe->fw_version.build = fwh->build;
+ WARN_ON(seq_nr != 2);
+ at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__,
+ __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+}
- str = (char *)fwh + le32_to_cpu(fwh->str_offset);
- fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
- fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
- fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
- fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
+static void at76_rx_mgmt_deauth(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_disassoc *resp =
+ (struct ieee80211_disassoc *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+
+ at76_dbg(DBG_RX_MGMT | DBG_PROGRESS,
+ "%s: rx DeAuth bssid %s reason 0x%04x destination %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
+
+ if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC
+ && priv->mac_state != MAC_CONNECTED) {
+ printk(KERN_INFO "%s: DeAuth in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
- fwe->loaded = 1;
+ BUG_ON(!priv->curr_bss);
- dev_printk(KERN_DEBUG, &udev->dev,
- "using firmware %s (version %d.%d.%d-%d)\n",
- fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
+ /* Not our BSSID, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
+ return;
- at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
- le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
- le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
- at76_dbg(DBG_DEVSTART, "firmware id %s", str);
+ /* Not for our STA and not broadcast, ignore */
+ if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
+ && !is_broadcast_ether_addr(mgmt->addr1))
+ return;
-exit:
- mutex_unlock(&fw_mutex);
+ if (priv->mac_state == MAC_CONNECTED)
+ at76_iwevent_bss_disconnect(priv->netdev);
- if (fwe->loaded)
- return fwe;
- else
- return NULL;
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
}
-static void at76_mac80211_tx_callback(struct urb *urb)
+static void at76_rx_mgmt_beacon(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = urb->context;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
+ int varpar_len;
+ /* beacon content */
+ struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &bdata->header;
+
+ struct list_head *lptr;
+ struct bss_info *match; /* entry matching addr3 with its bssid */
+ int new_entry = 0;
+ int len;
+ struct ieee80211_info_element *ie;
+ int have_ssid = 0;
+ int have_rates = 0;
+ int have_channel = 0;
+ int keep_going = 1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+ if (priv->mac_state == MAC_CONNECTED) {
+ /* in state MAC_CONNECTED we use the mgmt_timer to control
+ the beacon of the BSS */
+ BUG_ON(!priv->curr_bss);
+
+ if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) {
+ /* We got our AP's beacon, defer the timeout handler.
+ Kill pending work first, as schedule_delayed_work()
+ won't do it. */
+ cancel_delayed_work(&priv->dwork_beacon);
+ schedule_delayed_work(&priv->dwork_beacon,
+ BEACON_TIMEOUT);
+ priv->curr_bss->rssi = buf->rssi;
+ priv->beacons_received++;
+ goto exit;
+ }
+ }
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ /* look if we have this BSS already in the list */
+ match = NULL;
- switch (urb->status) {
- case 0:
- /* success */
- /* FIXME:
- * is the frame really ACKed when tx_callback is called ? */
- info->flags |= IEEE80211_TX_STAT_ACK;
- break;
- case -ENOENT:
- case -ECONNRESET:
- /* fail, urb has been unlinked */
- /* FIXME: add error message */
- break;
- default:
- at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
- __func__, urb->status);
- break;
+ if (!list_empty(&priv->bss_list)) {
+ list_for_each(lptr, &priv->bss_list) {
+ struct bss_info *bss_ptr =
+ list_entry(lptr, struct bss_info, list);
+ if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) {
+ match = bss_ptr;
+ break;
+ }
+ }
}
- memset(&info->status, 0, sizeof(info->status));
+ if (!match) {
+ /* BSS not in the list - append it */
+ match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC);
+ if (!match) {
+ at76_dbg(DBG_BSS_TABLE,
+ "%s: cannot kmalloc new bss info (%zd byte)",
+ priv->netdev->name, sizeof(struct bss_info));
+ goto exit;
+ }
+ new_entry = 1;
+ list_add_tail(&match->list, &priv->bss_list);
+ }
- ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
+ match->capa = le16_to_cpu(bdata->capability);
+ match->beacon_interval = le16_to_cpu(bdata->beacon_interval);
+ match->rssi = buf->rssi;
+ match->link_qual = buf->link_quality;
+ match->noise_level = buf->noise_level;
+ memcpy(match->bssid, mgmt->addr3, ETH_ALEN);
+ at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name,
+ mac2str(match->bssid));
+
+ ie = bdata->info_element;
+
+ /* length of var length beacon parameters */
+ varpar_len = min_t(int, le16_to_cpu(buf->wlength) -
+ sizeof(struct ieee80211_beacon),
+ BEACON_MAX_DATA_LENGTH);
+
+ /* This routine steps through the bdata->data array to get
+ * some useful information about the access point.
+ * Currently, this implementation supports receipt of: SSID,
+ * supported transfer rates and channel, in any order, with some
+ * tolerance for intermittent unknown codes (although this
+ * functionality may not be necessary as the useful information will
+ * usually arrive in consecutively, but there have been some
+ * reports of some of the useful information fields arriving in a
+ * different order).
+ * It does not support any more IE types although MFIE_TYPE_TIM may
+ * be supported (on my AP at least).
+ * The bdata->data array is about 1500 bytes long but only ~36 of those
+ * bytes are useful, hence the have_ssid etc optimizations. */
+
+ while (keep_going &&
+ ((&ie->data[ie->len] - (u8 *)bdata->info_element) <=
+ varpar_len)) {
+
+ switch (ie->id) {
+
+ case MFIE_TYPE_SSID:
+ if (have_ssid)
+ break;
- priv->tx_skb = NULL;
+ len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
- ieee80211_wake_queues(priv->hw);
-}
+ /* we copy only if this is a new entry,
+ or the incoming SSID is not a hidden SSID. This
+ will protect us from overwriting a real SSID read
+ in a ProbeResponse with a hidden one from a
+ following beacon. */
+ if (!new_entry && at76_is_hidden_ssid(ie->data, len)) {
+ have_ssid = 1;
+ break;
+ }
-static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct at76_priv *priv = hw->priv;
- struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- int padding, submit_len, ret;
+ match->ssid_len = len;
+ memcpy(match->ssid, ie->data, len);
+ at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s",
+ priv->netdev->name, len, match->ssid);
+ have_ssid = 1;
+ break;
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ case MFIE_TYPE_RATES:
+ if (have_rates)
+ break;
- if (priv->tx_urb->status == -EINPROGRESS) {
- printk(KERN_ERR "%s: %s called while tx urb is pending\n",
- wiphy_name(priv->hw->wiphy), __func__);
- return NETDEV_TX_BUSY;
- }
+ match->rates_len =
+ min_t(int, sizeof(match->rates), ie->len);
+ memcpy(match->rates, ie->data, match->rates_len);
+ have_rates = 1;
+ at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s",
+ priv->netdev->name,
+ hex2str(ie->data, ie->len));
+ break;
- ieee80211_stop_queues(hw);
+ case MFIE_TYPE_DS_SET:
+ if (have_channel)
+ break;
- at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+ match->channel = ie->data[0];
+ have_channel = 1;
+ at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d",
+ priv->netdev->name, match->channel);
+ break;
- WARN_ON(priv->tx_skb != NULL);
+ case MFIE_TYPE_CF_SET:
+ case MFIE_TYPE_TIM:
+ case MFIE_TYPE_IBSS_SET:
+ default:
+ at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
+ priv->netdev->name, ie->id, ie->len,
+ hex2str(ie->data, ie->len));
+ break;
+ }
- priv->tx_skb = skb;
- padding = at76_calc_padding(skb->len);
- submit_len = AT76_TX_HDRLEN + skb->len + padding;
+ /* advance to the next informational element */
+ next_ie(&ie);
- /* setup 'Atmel' header */
- memset(tx_buffer, 0, sizeof(*tx_buffer));
- tx_buffer->padding = padding;
- tx_buffer->wlength = cpu_to_le16(skb->len);
- tx_buffer->tx_rate = ieee80211_get_tx_rate(hw, info)->hw_value;
- if (FIRMWARE_IS_WPA(priv->fw_version) && info->control.hw_key) {
- tx_buffer->key_id = (info->control.hw_key->keyidx);
- tx_buffer->cipher_type =
- priv->keys[info->control.hw_key->keyidx].cipher;
- tx_buffer->cipher_length =
- priv->keys[info->control.hw_key->keyidx].keylen;
- tx_buffer->reserved = 0;
- } else {
- tx_buffer->key_id = 0;
- tx_buffer->cipher_type = 0;
- tx_buffer->cipher_length = 0;
- tx_buffer->reserved = 0;
- };
- /* memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved)); */
- memcpy(tx_buffer->packet, skb->data, skb->len);
+ /* Optimization: after all, the bdata->data array is
+ * varpar_len bytes long, whereas we get all of the useful
+ * information after only ~36 bytes, this saves us a lot of
+ * time (and trouble as the remaining portion of the array
+ * could be full of junk)
+ * Comment this out if you want to see what other information
+ * comes from the AP - although little of it may be useful */
+ }
- at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr",
- wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength),
- tx_buffer->padding, tx_buffer->tx_rate);
+ at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data",
+ priv->netdev->name);
- /* send stuff */
- at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len,
- "%s(): tx_buffer %d bytes:", __func__, submit_len);
- usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
- submit_len, at76_mac80211_tx_callback, priv);
- ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
- if (ret) {
- printk(KERN_ERR "%s: error in tx submit urb: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- if (ret == -EINVAL)
- printk(KERN_ERR
- "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
- wiphy_name(priv->hw->wiphy), priv->tx_urb,
- priv->tx_urb->hcpriv, priv->tx_urb->complete);
- }
+ match->last_rx = jiffies; /* record last rx of beacon */
- return 0;
+exit:
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
}
-static int at76_mac80211_start(struct ieee80211_hw *hw)
+/* Calculate the link level from a given rx_buffer */
+static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
{
- struct at76_priv *priv = hw->priv;
- int ret;
-
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ /* just a guess for now, might be different for other chips */
+ int max_rssi = 42;
- mutex_lock(&priv->mtx);
-
- ret = at76_submit_rx_urb(priv);
- if (ret < 0) {
- printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- goto error;
- }
+ qual->level = (buf->rssi * 100 / max_rssi);
+ if (qual->level > 100)
+ qual->level = 100;
+ qual->updated |= IW_QUAL_LEVEL_UPDATED;
+}
- at76_startup_device(priv);
+/* Calculate the link quality from a given rx_buffer */
+static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
+{
+ if (at76_is_intersil(priv->board_type))
+ qual->qual = buf->link_quality;
+ else {
+ unsigned long elapsed;
- at76_start_monitor(priv);
+ /* Update qual at most once a second */
+ elapsed = jiffies - priv->beacons_last_qual;
+ if (elapsed < 1 * HZ)
+ return;
-error:
- mutex_unlock(&priv->mtx);
+ qual->qual = qual->level * priv->beacons_received *
+ msecs_to_jiffies(priv->beacon_period) / elapsed;
- return 0;
+ priv->beacons_last_qual = jiffies;
+ priv->beacons_received = 0;
+ }
+ qual->qual = (qual->qual > 100) ? 100 : qual->qual;
+ qual->updated |= IW_QUAL_QUAL_UPDATED;
}
-static void at76_mac80211_stop(struct ieee80211_hw *hw)
+/* Calculate the noise quality from a given rx_buffer */
+static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
{
- struct at76_priv *priv = hw->priv;
-
- at76_dbg(DBG_MAC80211, "%s()", __func__);
-
- mutex_lock(&priv->mtx);
+ qual->noise = 0;
+ qual->updated |= IW_QUAL_NOISE_INVALID;
+}
- if (!priv->device_unplugged) {
- /* We are called by "ifconfig ethX down", not because the
- * device is not available anymore. */
- if (at76_set_radio(priv, 0) == 1)
- at76_wait_completion(priv, CMD_RADIO_ON);
+static void at76_update_wstats(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct iw_quality *qual = &priv->wstats.qual;
- /* We unlink rx_urb because at76_open() re-submits it.
- * If unplugged, at76_delete_device() takes care of it. */
- usb_kill_urb(priv->rx_urb);
+ if (buf->rssi && priv->mac_state == MAC_CONNECTED) {
+ qual->updated = 0;
+ at76_calc_level(priv, buf, qual);
+ at76_calc_qual(priv, buf, qual);
+ at76_calc_noise(priv, buf, qual);
+ } else {
+ qual->qual = 0;
+ qual->level = 0;
+ qual->noise = 0;
+ qual->updated = IW_QUAL_ALL_INVALID;
}
-
- mutex_unlock(&priv->mtx);
}
-static int at76_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
+static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = hw->priv;
- int ret = 0;
+ struct ieee80211_hdr_3addr *mgmt =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ u16 framectl = le16_to_cpu(mgmt->frame_ctl);
+
+ /* update wstats */
+ if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) {
+ /* jal: this is a dirty hack needed by Tim in ad-hoc mode */
+ /* Data packets always seem to have a 0 link level, so we
+ only read link quality info from management packets.
+ Atmel driver actually averages the present, and previous
+ values, we just present the raw value at the moment - TJS */
+ if (priv->iw_mode == IW_MODE_ADHOC
+ || (priv->curr_bss
+ && !compare_ether_addr(mgmt->addr3,
+ priv->curr_bss->bssid)))
+ at76_update_wstats(priv, buf);
+ }
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s",
+ priv->netdev->name, framectl,
+ hex2str(mgmt, le16_to_cpu(buf->wlength)));
- mutex_lock(&priv->mtx);
+ switch (framectl & IEEE80211_FCTL_STYPE) {
+ case IEEE80211_STYPE_BEACON:
+ case IEEE80211_STYPE_PROBE_RESP:
+ at76_rx_mgmt_beacon(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_ASSOC_RESP:
+ at76_rx_mgmt_assoc(priv, buf);
+ break;
- switch (conf->type) {
- case NL80211_IFTYPE_STATION:
- priv->iw_mode = IW_MODE_INFRA;
+ case IEEE80211_STYPE_DISASSOC:
+ at76_rx_mgmt_disassoc(priv, buf);
break;
+
+ case IEEE80211_STYPE_AUTH:
+ at76_rx_mgmt_auth(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_DEAUTH:
+ at76_rx_mgmt_deauth(priv, buf);
+ break;
+
default:
- ret = -EOPNOTSUPP;
- goto exit;
+ printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
+ priv->netdev->name, framectl);
}
-exit:
- mutex_unlock(&priv->mtx);
-
- return ret;
+ return;
}
-static void at76_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
+/* Convert the 802.11 header into an ethernet-style header, make skb
+ * ready for consumption by netif_rx() */
+static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
{
- at76_dbg(DBG_MAC80211, "%s()", __func__);
-}
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ struct ethhdr *eth_hdr_p;
+ u8 *src_addr;
+ u8 *dest_addr;
-static int at76_join(struct at76_priv *priv)
-{
- struct at76_req_join join;
- int ret;
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
- memset(&join, 0, sizeof(struct at76_req_join));
- memcpy(join.essid, priv->essid, priv->essid_size);
- join.essid_size = priv->essid_size;
- memcpy(join.bssid, priv->bssid, ETH_ALEN);
- join.bss_type = INFRASTRUCTURE_MODE;
- join.channel = priv->channel;
- join.timeout = cpu_to_le16(2000);
+ /* That would be the ethernet header if the hardware converted
+ * the frame for us. Make sure the source and the destination
+ * match the 802.11 header. Which hardware does it? */
+ eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN);
- at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
- ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
- sizeof(struct at76_req_join));
+ dest_addr = i802_11_hdr->addr1;
+ if (iw_mode == IW_MODE_ADHOC)
+ src_addr = i802_11_hdr->addr2;
+ else
+ src_addr = i802_11_hdr->addr3;
- if (ret < 0) {
- printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- return 0;
- }
+ if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) &&
+ !compare_ether_addr(eth_hdr_p->h_dest, dest_addr))
+ /* Yes, we already have an ethernet header */
+ skb_reset_mac_header(skb);
+ else {
+ u16 len;
+
+ /* Need to build an ethernet header */
+ if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
+ /* SNAP frame - decapsulate, keep proto */
+ skb_push(skb, offsetof(struct ethhdr, h_proto) -
+ sizeof(rfc1042sig));
+ len = 0;
+ } else {
+ /* 802.3 frame, proto is length */
+ len = skb->len;
+ skb_push(skb, ETH_HLEN);
+ }
- ret = at76_wait_completion(priv, CMD_JOIN);
- at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
- if (ret != CMD_STATUS_COMPLETE) {
- printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- return 0;
+ skb_reset_mac_header(skb);
+ eth_hdr_p = eth_hdr(skb);
+ /* This needs to be done in this order (eth_hdr_p->h_dest may
+ * overlap src_addr) */
+ memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
+ memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
+ if (len)
+ eth_hdr_p->h_proto = htons(len);
}
- at76_set_tkip_bssid(priv, priv->bssid);
- at76_set_pm_mode(priv);
-
- return 0;
+ skb->protocol = eth_type_trans(skb, skb->dev);
}
-static void at76_dwork_hw_scan(struct work_struct *work)
+/* Check for fragmented data in priv->rx_skb. If the packet was no fragment
+ or it was the last of a fragment set a skb containing the whole packet
+ is returned for further processing. Otherwise we get NULL and are
+ done and the packet is either stored inside the fragment buffer
+ or thrown away. Every returned skb starts with the ieee802_11 header
+ and contains _no_ FCS at the end */
+static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv)
{
- struct at76_priv *priv = container_of(work, struct at76_priv,
- dwork_hw_scan.work);
- int ret;
+ struct sk_buff *skb = priv->rx_skb;
+ struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
+ struct ieee80211_hdr_3addr *i802_11_hdr =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ /* seq_ctrl, fragment_number, sequence number of new packet */
+ u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl);
+ u16 fragnr = sctl & 0xf;
+ u16 seqnr = sctl >> 4;
+ u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
- ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
- at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret);
+ /* Length including the IEEE802.11 header, but without the trailing
+ * FCS and without the Atmel Rx header */
+ int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN;
- /* FIXME: add maximum time for scan to complete */
+ /* where does the data payload start in skb->data ? */
+ u8 *data = i802_11_hdr->payload;
- if (ret != CMD_STATUS_COMPLETE) {
- queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
- SCAN_POLL_INTERVAL);
- goto exit;
+ /* length of payload, excl. the trailing FCS */
+ int data_len = length - IEEE80211_3ADDR_LEN;
+
+ int i;
+ struct rx_data_buf *bptr, *optr;
+ unsigned long oldest = ~0UL;
+
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d "
+ "length %d data %d: %s ...", priv->netdev->name, frame_ctl,
+ mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len,
+ hex2str(data, 32));
+
+ at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p "
+ "tail %p end %p len %d", priv->netdev->name, skb->head,
+ skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
+ skb->len);
+
+ if (data_len < 0) {
+ /* make sure data starts in the buffer */
+ printk(KERN_INFO "%s: data frame too short\n",
+ priv->netdev->name);
+ return NULL;
}
- ieee80211_scan_completed(priv->hw);
+ WARN_ON(length <= AT76_RX_HDRLEN);
+ if (length <= AT76_RX_HDRLEN)
+ return NULL;
- if (is_valid_ether_addr(priv->bssid)) {
- ieee80211_wake_queues(priv->hw);
- at76_join(priv);
+ /* remove the at76_rx_buffer header - we don't need it anymore */
+ /* we need the IEEE802.11 header (for the addresses) if this packet
+ is the first of a chain */
+ skb_pull(skb, AT76_RX_HDRLEN);
+
+ /* remove FCS at end */
+ skb_trim(skb, length);
+
+ at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p "
+ "end %p len %d data %p data_len %d", priv->netdev->name,
+ skb->head, skb->data, skb_tail_pointer(skb),
+ skb_end_pointer(skb), skb->len, data, data_len);
+
+ if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) {
+ /* unfragmented packet received */
+ /* Use a new skb for the next receive */
+ priv->rx_skb = NULL;
+ at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name);
+ return skb;
}
- ieee80211_wake_queues(priv->hw);
+ /* look if we've got a chain for the sender address.
+ afterwards optr points to first free or the oldest entry,
+ or, if i < NR_RX_DATA_BUF, bptr points to the entry for the
+ sender address */
+ /* determining the oldest entry doesn't cope with jiffies wrapping
+ but I don't care to delete a young entry at these rare moments ... */
+
+ bptr = priv->rx_data;
+ optr = NULL;
+ for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) {
+ if (!bptr->skb) {
+ optr = bptr;
+ oldest = 0UL;
+ continue;
+ }
-exit:
- return;
-}
+ if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender))
+ break;
-static int at76_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
-{
- struct at76_priv *priv = hw->priv;
- struct at76_req_scan scan;
- int ret;
+ if (!optr) {
+ optr = bptr;
+ oldest = bptr->last_rx;
+ } else if (bptr->last_rx < oldest)
+ optr = bptr;
+ }
- at76_dbg(DBG_MAC80211, "%s():", __func__);
- at76_dbg_dump(DBG_MAC80211, ssid, len, "ssid %zd bytes:", len);
+ if (i < NR_RX_DATA_BUF) {
+
+ at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) "
+ "matched sender addr",
+ priv->netdev->name, i, bptr->seqnr, bptr->fragnr);
+
+ /* bptr points to an entry for the sender address */
+ if (bptr->seqnr == seqnr) {
+ int left;
+ /* the fragment has the current sequence number */
+ if (((bptr->fragnr + 1) & 0xf) != fragnr) {
+ /* wrong fragment number -> ignore it */
+ /* is & 0xf necessary above ??? */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: frag nr mismatch: %d + 1 != %d",
+ priv->netdev->name, bptr->fragnr,
+ fragnr);
+ return NULL;
+ }
+ bptr->last_rx = jiffies;
+ /* the next following fragment number ->
+ add the data at the end */
+
+ /* for test only ??? */
+ left = skb_tailroom(bptr->skb);
+ if (left < data_len)
+ printk(KERN_INFO
+ "%s: only %d byte free (need %d)\n",
+ priv->netdev->name, left, data_len);
+ else
+ memcpy(skb_put(bptr->skb, data_len), data,
+ data_len);
+
+ bptr->fragnr = fragnr;
+ if (frame_ctl & IEEE80211_FCTL_MOREFRAGS)
+ return NULL;
+
+ /* this was the last fragment - send it */
+ skb = bptr->skb;
+ bptr->skb = NULL; /* free the entry */
+ at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d",
+ priv->netdev->name, seqnr);
+ return skb;
+ }
- mutex_lock(&priv->mtx);
+ /* got another sequence number */
+ if (fragnr == 0) {
+ /* it's the start of a new chain - replace the
+ old one by this */
+ /* bptr->sender has the correct value already */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: start of new seq %d, removing old seq %d",
+ priv->netdev->name, seqnr, bptr->seqnr);
+ bptr->seqnr = seqnr;
+ bptr->fragnr = 0;
+ bptr->last_rx = jiffies;
+ /* swap bptr->skb and priv->rx_skb */
+ skb = bptr->skb;
+ bptr->skb = priv->rx_skb;
+ priv->rx_skb = skb;
+ } else {
+ /* it from the middle of a new chain ->
+ delete the old entry and skip the new one */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: middle of new seq %d (%d) "
+ "removing old seq %d",
+ priv->netdev->name, seqnr, fragnr,
+ bptr->seqnr);
+ dev_kfree_skb(bptr->skb);
+ bptr->skb = NULL;
+ }
+ return NULL;
+ }
- ieee80211_stop_queues(hw);
+ /* if we didn't find a chain for the sender address, optr
+ points either to the first free or the oldest entry */
- memset(&scan, 0, sizeof(struct at76_req_scan));
- memset(scan.bssid, 0xFF, ETH_ALEN);
- scan.scan_type = SCAN_TYPE_ACTIVE;
- if (priv->essid_size > 0) {
- memcpy(scan.essid, ssid, len);
- scan.essid_size = len;
+ if (fragnr != 0) {
+ /* this is not the begin of a fragment chain ... */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: no chain for non-first fragment (%d)",
+ priv->netdev->name, fragnr);
+ return NULL;
}
- scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
- scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
- scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
- scan.international_scan = 0;
- at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__);
- ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+ BUG_ON(!optr);
+ if (optr->skb) {
+ /* swap the skb's */
+ skb = optr->skb;
+ optr->skb = priv->rx_skb;
+ priv->rx_skb = skb;
- if (ret < 0) {
- err("CMD_SCAN failed: %d", ret);
- goto exit;
- }
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: free old contents: sender %s seq/frag %d/%d",
+ priv->netdev->name, mac2str(optr->sender),
+ optr->seqnr, optr->fragnr);
- queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
- SCAN_POLL_INTERVAL);
+ } else {
+ /* take the skb from priv->rx_skb */
+ optr->skb = priv->rx_skb;
+ /* let at76_submit_rx_urb() allocate a new skb */
+ priv->rx_skb = NULL;
-exit:
- mutex_unlock(&priv->mtx);
+ at76_dbg(DBG_RX_FRAGS, "%s: use a free entry",
+ priv->netdev->name);
+ }
+ memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN);
+ optr->seqnr = seqnr;
+ optr->fragnr = 0;
+ optr->last_rx = jiffies;
- return 0;
+ return NULL;
}
-static int at76_config(struct ieee80211_hw *hw, u32 changed)
+/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */
+static void at76_rx_data(struct at76_priv *priv)
{
- struct at76_priv *priv = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
+ struct net_device *netdev = priv->netdev;
+ struct net_device_stats *stats = &priv->stats;
+ struct sk_buff *skb = priv->rx_skb;
+ struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ int length = le16_to_cpu(buf->wlength);
- at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
- __func__, conf->channel->hw_value, conf->radio_enabled);
- at76_dbg_dump(DBG_MAC80211, priv->essid, priv->essid_size, "ssid:");
- at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
+ at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name,
+ hex2str(skb->data, AT76_RX_HDRLEN));
- mutex_lock(&priv->mtx);
+ at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s",
+ hex2str(skb->data + AT76_RX_HDRLEN, length));
- priv->channel = conf->channel->hw_value;
+ skb = at76_check_for_rx_frags(priv);
+ if (!skb)
+ return;
- if (is_valid_ether_addr(priv->bssid)) {
- at76_join(priv);
- ieee80211_wake_queues(priv->hw);
- } else {
- ieee80211_stop_queues(priv->hw);
- at76_start_monitor(priv);
- };
+ /* Atmel header and the FCS are already removed */
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
- mutex_unlock(&priv->mtx);
+ skb->dev = netdev;
+ skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */
- return 0;
-}
+ if (is_broadcast_ether_addr(i802_11_hdr->addr1)) {
+ if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast))
+ skb->pkt_type = PACKET_BROADCAST;
+ else
+ skb->pkt_type = PACKET_MULTICAST;
+ } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr))
+ skb->pkt_type = PACKET_OTHERHOST;
-static int at76_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct at76_priv *priv = hw->priv;
+ at76_ieee80211_to_eth(skb, priv->iw_mode);
- at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
+ netdev->last_rx = jiffies;
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
- mutex_lock(&priv->mtx);
+ return;
+}
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-// memcpy(priv->essid, conf->ssid, conf->ssid_len);
-// priv->essid_size = conf->ssid_len;
+static void at76_rx_monitor_mode(struct at76_priv *priv)
+{
+ struct at76_rx_radiotap *rt;
+ u8 *payload;
+ int skblen;
+ struct net_device *netdev = priv->netdev;
+ struct at76_rx_buffer *buf =
+ (struct at76_rx_buffer *)priv->rx_skb->data;
+ /* length including the IEEE802.11 header and the trailing FCS,
+ but not at76_rx_buffer */
+ int length = le16_to_cpu(buf->wlength);
+ struct sk_buff *skb = priv->rx_skb;
+ struct net_device_stats *stats = &priv->stats;
- if (is_valid_ether_addr(priv->bssid)) {
- /* mac80211 is joining a bss */
- ieee80211_wake_queues(priv->hw);
- at76_join(priv);
- } else
- ieee80211_stop_queues(priv->hw);
+ if (length < IEEE80211_FCS_LEN) {
+ /* buffer contains no data */
+ at76_dbg(DBG_MONITOR_MODE,
+ "%s: MONITOR MODE: rx skb without data",
+ priv->netdev->name);
+ return;
+ }
- mutex_unlock(&priv->mtx);
+ skblen = sizeof(struct at76_rx_radiotap) + length;
- return 0;
+ skb = dev_alloc_skb(skblen);
+ if (!skb) {
+ printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap "
+ "header returned NULL\n", priv->netdev->name);
+ return;
+ }
+
+ skb_put(skb, skblen);
+
+ rt = (struct at76_rx_radiotap *)skb->data;
+ payload = skb->data + sizeof(struct at76_rx_radiotap);
+
+ rt->rt_hdr.it_version = 0;
+ rt->rt_hdr.it_pad = 0;
+ rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap));
+ rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT);
+
+ rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time));
+ rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80);
+ rt->rt_signal = buf->rssi;
+ rt->rt_noise = buf->noise_level;
+ rt->rt_flags = IEEE80211_RADIOTAP_F_FCS;
+ if (buf->fragmentation)
+ rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+ memcpy(payload, buf->packet, length);
+ skb->dev = netdev;
+ skb->ip_summed = CHECKSUM_NONE;
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+
+ netdev->last_rx = jiffies;
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
}
-/* must be atomic */
-static void at76_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags, int mc_count,
- struct dev_addr_list *mc_list)
+/* Check if we spy on the sender address in buf and update stats */
+static void at76_iwspy_update(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = hw->priv;
- int flags;
-
- at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
- "total_flags=0x%08x mc_count=%d",
- __func__, changed_flags, *total_flags, mc_count);
+ struct ieee80211_hdr_3addr *hdr =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ struct iw_quality qual;
- flags = changed_flags & AT76_SUPPORTED_FILTERS;
- *total_flags = AT76_SUPPORTED_FILTERS;
+ /* We can only set the level here */
+ qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
+ qual.level = 0;
+ qual.noise = 0;
+ at76_calc_level(priv, buf, &qual);
- /* FIXME: access to priv->promisc should be protected with
- * priv->mtx, but it's impossible because this function needs to be
- * atomic */
+ spin_lock_bh(&priv->spy_spinlock);
- if (flags && !priv->promisc) {
- /* mac80211 wants us to enable promiscuous mode */
- priv->promisc = 1;
- } else if (!flags && priv->promisc) {
- /* we need to disable promiscuous mode */
- priv->promisc = 0;
- } else
- return;
+ if (priv->spy_data.spy_number > 0)
+ wireless_spy_update(priv->netdev, hdr->addr2, &qual);
- queue_work(hw->workqueue, &priv->work_set_promisc);
+ spin_unlock_bh(&priv->spy_spinlock);
}
-static int at76_set_key_oldfw(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
+static void at76_rx_tasklet(unsigned long param)
{
- struct at76_priv *priv = hw->priv;
-
- int i;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ struct urb *urb = (struct urb *)param;
+ struct at76_priv *priv = urb->context;
+ struct net_device *netdev = priv->netdev;
+ struct at76_rx_buffer *buf;
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ u16 frame_ctl;
- if (key->alg != ALG_WEP)
- return -EOPNOTSUPP;
+ if (priv->device_unplugged) {
+ at76_dbg(DBG_DEVSTART, "device unplugged");
+ if (urb)
+ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ return;
+ }
- key->hw_key_idx = key->keyidx;
+ if (!priv->rx_skb || !netdev || !priv->rx_skb->data)
+ return;
- mutex_lock(&priv->mtx);
+ buf = (struct at76_rx_buffer *)priv->rx_skb->data;
- switch (cmd) {
- case SET_KEY:
- memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen);
- priv->wep_keys_len[key->keyidx] = key->keylen;
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet;
- /* FIXME: find out how to do this properly */
- priv->wep_key_id = key->keyidx;
+ frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
- break;
- case DISABLE_KEY:
- default:
- priv->wep_keys_len[key->keyidx] = 0;
- break;
+ if (urb->status != 0) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET)
+ at76_dbg(DBG_URB,
+ "%s %s: - nonzero Rx bulk status received: %d",
+ __func__, netdev->name, urb->status);
+ return;
}
- priv->wep_enabled = 0;
+ at76_dbg(DBG_RX_ATMEL_HDR,
+ "%s: rx frame: rate %d rssi %d noise %d link %d %s",
+ priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level,
+ buf->link_quality, hex2str(i802_11_hdr, 48));
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ at76_rx_monitor_mode(priv);
+ goto exit;
+ }
- for (i = 0; i < WEP_KEYS; i++) {
- if (priv->wep_keys_len[i] != 0)
- priv->wep_enabled = 1;
+ /* there is a new bssid around, accept it: */
+ if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) {
+ at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name);
+ schedule_work(&priv->work_new_bss);
}
- at76_startup_device(priv);
+ switch (frame_ctl & IEEE80211_FCTL_FTYPE) {
+ case IEEE80211_FTYPE_DATA:
+ at76_rx_data(priv);
+ break;
- mutex_unlock(&priv->mtx);
+ case IEEE80211_FTYPE_MGMT:
+ /* jal: TODO: find out if we can update iwspy also on
+ other frames than management (might depend on the
+ radio chip / firmware version !) */
- return 0;
-}
+ at76_iwspy_update(priv, buf);
-static int at76_set_key_newfw(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
-{
- struct at76_priv *priv = hw->priv;
- int ret = -EOPNOTSUPP;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ at76_rx_mgmt(priv, buf);
+ break;
- mutex_lock(&priv->mtx);
+ case IEEE80211_FTYPE_CTL:
+ at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x",
+ priv->netdev->name, frame_ctl);
+ break;
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
+ default:
+ printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
+ priv->netdev->name, frame_ctl);
+ }
+exit:
+ at76_submit_rx_urb(priv);
+}
- if (cmd == DISABLE_KEY) {
- priv->mib_buf.size = CIPHER_KEY_LEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- cipher_default_keyvalue[key->keyidx]);
- memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN);
- if (at76_set_mib(priv, &priv->mib_buf) != CMD_STATUS_COMPLETE)
- ret = -EOPNOTSUPP; /* -EIO would be probably better */
- else {
+/* Load firmware into kernel memory and parse it */
+static struct fwentry *at76_load_firmware(struct usb_device *udev,
+ enum board_type board_type)
+{
+ int ret;
+ char *str;
+ struct at76_fw_header *fwh;
+ struct fwentry *fwe = &firmwares[board_type];
- priv->keys[key->keyidx].cipher = CIPHER_NONE;
- priv->keys[key->keyidx].keylen = 0;
- };
- if (priv->default_group_key == key->keyidx)
- priv->default_group_key = 0xff;
+ mutex_lock(&fw_mutex);
- if (priv->default_pairwise_key == key->keyidx)
- priv->default_pairwise_key = 0xff;
- /* If default pairwise key is removed, fall back to
- * group key? */
- ret = 0;
+ if (fwe->loaded) {
+ at76_dbg(DBG_FW, "re-using previously loaded fw");
goto exit;
- };
-
- if (cmd == SET_KEY) {
- /* store key into MIB */
- priv->mib_buf.size = CIPHER_KEY_LEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- cipher_default_keyvalue[key->keyidx]);
- memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN);
- memcpy(priv->mib_buf.data.data, key->key, key->keylen);
-
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == 5) {
- priv->keys[key->keyidx].cipher =
- CIPHER_WEP64;
- priv->keys[key->keyidx].keylen = 8;
- } else if (key->keylen == 13) {
- priv->keys[key->keyidx].cipher =
- CIPHER_WEP128;
- /* Firmware needs this */
- priv->keys[key->keyidx].keylen = 8;
- } else {
- ret = -EOPNOTSUPP;
- goto exit;
- };
- break;
- case ALG_TKIP:
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- priv->keys[key->keyidx].cipher = CIPHER_TKIP;
- priv->keys[key->keyidx].keylen = 12;
- break;
+ }
- case ALG_CCMP:
- if (!at76_is_505a(priv->board_type)) {
- ret = -EOPNOTSUPP;
- goto exit;
- };
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- priv->keys[key->keyidx].cipher = CIPHER_CCMP;
- priv->keys[key->keyidx].keylen = 16;
- break;
+ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
+ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
+ fwe->fwname);
+ dev_printk(KERN_ERR, &udev->dev,
+ "you may need to download the firmware from "
+ "http://developer.berlios.de/projects/at76c503a/");
+ goto exit;
+ }
- default:
- ret = -EOPNOTSUPP;
- goto exit;
- };
-
- priv->mib_buf.data.data[38] = priv->keys[key->keyidx].cipher;
- priv->mib_buf.data.data[39] = 1; /* Taken from atmelwlandriver,
- not documented */
-
- if (is_valid_ether_addr(address))
- /* Pairwise key */
- priv->mib_buf.data.data[39] |= (KEY_PAIRWISE | KEY_TX);
- else if (is_broadcast_ether_addr(address))
- /* Group key */
- priv->mib_buf.data.data[39] |= (KEY_TX);
- else /* Key used only for transmission ??? */
- priv->mib_buf.data.data[39] |= (KEY_TX);
-
- if (at76_set_mib(priv, &priv->mib_buf) !=
- CMD_STATUS_COMPLETE) {
- ret = -EOPNOTSUPP; /* -EIO would be probably better */
- goto exit;
- };
+ at76_dbg(DBG_FW, "got it.");
+ fwh = (struct at76_fw_header *)(fwe->fw->data);
- if ((key->alg == ALG_TKIP) || (key->alg == ALG_CCMP))
- at76_reset_rsc(priv);
+ if (fwe->fw->size <= sizeof(*fwh)) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "firmware is too short (0x%zx)\n", fwe->fw->size);
+ goto exit;
+ }
- key->hw_key_idx = key->keyidx;
+ /* CRC currently not checked */
+ fwe->board_type = le32_to_cpu(fwh->board_type);
+ if (fwe->board_type != board_type) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "board type mismatch, requested %u, got %u\n",
+ board_type, fwe->board_type);
+ goto exit;
+ }
- /* Set up default keys */
- if (is_broadcast_ether_addr(address))
- priv->default_group_key = key->keyidx;
- if (is_valid_ether_addr(address))
- priv->default_pairwise_key = key->keyidx;
+ fwe->fw_version.major = fwh->major;
+ fwe->fw_version.minor = fwh->minor;
+ fwe->fw_version.patch = fwh->patch;
+ fwe->fw_version.build = fwh->build;
- /* Set up encryption MIBs */
+ str = (char *)fwh + le32_to_cpu(fwh->str_offset);
+ fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
+ fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
+ fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
+ fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
- /* first block of settings */
- priv->mib_buf.size = 3;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- privacy_invoked);
- priv->mib_buf.data.data[0] = 1; /* privacy_invoked */
- priv->mib_buf.data.data[1] = priv->default_pairwise_key;
- priv->mib_buf.data.data[2] = priv->default_group_key;
+ fwe->loaded = 1;
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret != CMD_STATUS_COMPLETE)
- goto exit;
+ dev_printk(KERN_DEBUG, &udev->dev,
+ "using firmware %s (version %d.%d.%d-%d)\n",
+ fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
- /* second block of settings */
- priv->mib_buf.size = 3;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- exclude_unencrypted);
- priv->mib_buf.data.data[0] = 1; /* exclude_unencrypted */
- priv->mib_buf.data.data[1] = 0; /* wep_encryption_type */
- priv->mib_buf.data.data[2] = 0; /* ckip_key_permutation */
+ at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
+ le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
+ le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
+ at76_dbg(DBG_DEVSTART, "firmware id %s", str);
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret != CMD_STATUS_COMPLETE)
- goto exit;
- ret = 0;
- };
exit:
- at76_dump_mib_mac_encryption(priv);
- mutex_unlock(&priv->mtx);
- return ret;
-}
-
-static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
-{
- struct at76_priv *priv = hw->priv;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ mutex_unlock(&fw_mutex);
- if (FIRMWARE_IS_WPA(priv->fw_version))
- return at76_set_key_newfw(hw, cmd, local_address, address, key);
+ if (fwe->loaded)
+ return fwe;
else
- return at76_set_key_oldfw(hw, cmd, local_address, address, key);
-
+ return NULL;
}
-static const struct ieee80211_ops at76_ops = {
- .tx = at76_mac80211_tx,
- .add_interface = at76_add_interface,
- .remove_interface = at76_remove_interface,
- .config = at76_config,
- .config_interface = at76_config_interface,
- .configure_filter = at76_configure_filter,
- .start = at76_mac80211_start,
- .stop = at76_mac80211_stop,
- .hw_scan = at76_hw_scan,
- .set_key = at76_set_key,
-};
-
/* Allocate network device and initialize private data */
static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
{
- struct ieee80211_hw *hw;
+ struct net_device *netdev;
struct at76_priv *priv;
+ int i;
- hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops);
- if (!hw) {
- printk(KERN_ERR DRIVER_NAME ": could not register"
- " ieee80211_hw\n");
+ /* allocate memory for our device state and initialize it */
+ netdev = alloc_etherdev(sizeof(struct at76_priv));
+ if (!netdev) {
+ dev_printk(KERN_ERR, &udev->dev, "out of memory\n");
return NULL;
}
- priv = hw->priv;
- priv->hw = hw;
+ priv = netdev_priv(netdev);
priv->udev = udev;
+ priv->netdev = netdev;
mutex_init(&priv->mtx);
+ INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done);
+ INIT_WORK(&priv->work_join, at76_work_join);
+ INIT_WORK(&priv->work_new_bss, at76_work_new_bss);
+ INIT_WORK(&priv->work_start_scan, at76_work_start_scan);
INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
- INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
+ INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart);
+ INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan);
+ INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon);
+ INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth);
+ INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc);
+
+ spin_lock_init(&priv->mgmt_spinlock);
+ priv->next_mgmt_bulk = NULL;
+ priv->mac_state = MAC_INIT;
+
+ /* initialize empty BSS list */
+ priv->curr_bss = NULL;
+ INIT_LIST_HEAD(&priv->bss_list);
+ spin_lock_init(&priv->bss_list_spinlock);
+
+ init_timer(&priv->bss_list_timer);
+ priv->bss_list_timer.data = (unsigned long)priv;
+ priv->bss_list_timer.function = at76_bss_list_timeout;
+
+ spin_lock_init(&priv->spy_spinlock);
+
+ /* mark all rx data entries as unused */
+ for (i = 0; i < NR_RX_DATA_BUF; i++)
+ priv->rx_data[i].skb = NULL;
priv->rx_tasklet.func = at76_rx_tasklet;
priv->rx_tasklet.data = 0;
@@ -2371,9 +5197,6 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
priv->pm_mode = AT76_PM_OFF;
priv->pm_period = 0;
- /* unit us */
- priv->hw->channel_change_time = 100000;
-
return priv;
}
@@ -2436,42 +5259,11 @@ static int at76_alloc_urbs(struct at76_priv *priv,
return 0;
}
-static struct ieee80211_rate at76_rates[] = {
- { .bitrate = 10, .hw_value = TX_RATE_1MBIT, },
- { .bitrate = 20, .hw_value = TX_RATE_2MBIT, },
- { .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, },
- { .bitrate = 110, .hw_value = TX_RATE_11MBIT, },
-};
-
-static struct ieee80211_channel at76_channels[] = {
- { .center_freq = 2412, .hw_value = 1 },
- { .center_freq = 2417, .hw_value = 2 },
- { .center_freq = 2422, .hw_value = 3 },
- { .center_freq = 2427, .hw_value = 4 },
- { .center_freq = 2432, .hw_value = 5 },
- { .center_freq = 2437, .hw_value = 6 },
- { .center_freq = 2442, .hw_value = 7 },
- { .center_freq = 2447, .hw_value = 8 },
- { .center_freq = 2452, .hw_value = 9 },
- { .center_freq = 2457, .hw_value = 10 },
- { .center_freq = 2462, .hw_value = 11 },
- { .center_freq = 2467, .hw_value = 12 },
- { .center_freq = 2472, .hw_value = 13 },
- { .center_freq = 2484, .hw_value = 14 }
-};
-
-static struct ieee80211_supported_band at76_supported_band = {
- .channels = at76_channels,
- .n_channels = ARRAY_SIZE(at76_channels),
- .bitrates = at76_rates,
- .n_bitrates = ARRAY_SIZE(at76_rates),
-};
-
/* Register network device and initialize the hardware */
static int at76_init_new_device(struct at76_priv *priv,
struct usb_interface *interface)
{
- struct device *dev = &interface->dev;
+ struct net_device *netdev = priv->netdev;
int ret;
/* set up the endpoint information */
@@ -2487,11 +5279,14 @@ static int at76_init_new_device(struct at76_priv *priv,
/* MAC address */
ret = at76_get_hw_config(priv);
if (ret < 0) {
- dev_err(dev, "cannot get MAC address\n");
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot get MAC address\n");
goto exit;
}
priv->domain = at76_get_reg_domain(priv->regulatory_domain);
+ /* init. netdev->dev_addr */
+ memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN);
priv->channel = DEF_CHANNEL;
priv->iw_mode = IW_MODE_INFRA;
@@ -2501,54 +5296,47 @@ static int at76_init_new_device(struct at76_priv *priv,
priv->txrate = TX_RATE_AUTO;
priv->preamble_type = PREAMBLE_TYPE_LONG;
priv->beacon_period = 100;
+ priv->beacons_last_qual = jiffies;
priv->auth_mode = WLAN_AUTH_OPEN;
priv->scan_min_time = DEF_SCAN_MIN_TIME;
priv->scan_max_time = DEF_SCAN_MAX_TIME;
priv->scan_mode = SCAN_TYPE_ACTIVE;
- priv->default_pairwise_key = 0xff;
- priv->default_group_key = 0xff;
-
- /* mac80211 initialisation */
- priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
- if (FIRMWARE_IS_WPA(priv->fw_version) &&
- (at76_is_503rfmd(priv->board_type) ||
- at76_is_505(priv->board_type)))
- priv->hw->flags = IEEE80211_HW_SIGNAL_UNSPEC;
- else
- priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SIGNAL_UNSPEC;
-
- priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-
- SET_IEEE80211_DEV(priv->hw, &interface->dev);
- SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
-
- ret = ieee80211_register_hw(priv->hw);
+ netdev->flags &= ~IFF_MULTICAST; /* not yet or never */
+ netdev->open = at76_open;
+ netdev->stop = at76_stop;
+ netdev->get_stats = at76_get_stats;
+ netdev->ethtool_ops = &at76_ethtool_ops;
+
+ /* Add pointers to enable iwspy support. */
+ priv->wireless_data.spy_data = &priv->spy_data;
+ netdev->wireless_data = &priv->wireless_data;
+
+ netdev->hard_start_xmit = at76_tx;
+ netdev->tx_timeout = at76_tx_timeout;
+ netdev->watchdog_timeo = 2 * HZ;
+ netdev->wireless_handlers = &at76_handler_def;
+ netdev->set_multicast_list = at76_set_multicast;
+ netdev->set_mac_address = at76_set_mac_address;
+ dev_alloc_name(netdev, "wlan%d");
+
+ ret = register_netdev(priv->netdev);
if (ret) {
- dev_err(dev, "cannot register mac80211 hw (status %d)!\n", ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot register netdevice (status %d)!\n", ret);
goto exit;
}
+ priv->netdev_registered = 1;
- priv->mac80211_registered = 1;
+ printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
+ netdev->name, dev_name(&interface->dev), mac2str(priv->mac_addr),
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+ printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name,
+ priv->regulatory_domain, priv->domain->name);
- dev_info(dev, "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
- wiphy_name(priv->hw->wiphy),
- dev_name(&interface->dev), mac2str(priv->mac_addr),
- priv->fw_version.major, priv->fw_version.minor,
- priv->fw_version.patch, priv->fw_version.build);
- dev_info(dev, "%s: regulatory domain 0x%02x: %s\n",
- wiphy_name(priv->hw->wiphy),
- priv->regulatory_domain, priv->domain->name);
- dev_info(dev, "%s: WPA support: ", wiphy_name(priv->hw->wiphy));
- if (!FIRMWARE_IS_WPA(priv->fw_version))
- printk("none\n");
- else {
- if (!at76_is_505a(priv->board_type))
- printk("TKIP\n");
- else
- printk("TKIP, AES/CCMP\n");
- };
+ /* we let this timer run the whole time this driver instance lives */
+ mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
exit:
return ret;
@@ -2556,13 +5344,15 @@ exit:
static void at76_delete_device(struct at76_priv *priv)
{
+ int i;
+
at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
/* The device is gone, don't bother turning it off */
priv->device_unplugged = 1;
- if (priv->mac80211_registered)
- ieee80211_unregister_hw(priv->hw);
+ if (priv->netdev_registered)
+ unregister_netdev(priv->netdev);
/* assuming we used keventd, it must quiesce too */
flush_scheduled_work();
@@ -2583,11 +5373,25 @@ static void at76_delete_device(struct at76_priv *priv)
if (priv->rx_skb)
kfree_skb(priv->rx_skb);
+ at76_free_bss_list(priv);
+ del_timer_sync(&priv->bss_list_timer);
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+
+ if (priv->mac_state == MAC_CONNECTED)
+ at76_iwevent_bss_disconnect(priv->netdev);
+
+ for (i = 0; i < NR_RX_DATA_BUF; i++)
+ if (priv->rx_data[i].skb) {
+ dev_kfree_skb(priv->rx_data[i].skb);
+ priv->rx_data[i].skb = NULL;
+ }
usb_put_dev(priv->udev);
- at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw",
- __func__);
- ieee80211_free_hw(priv->hw);
+ at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__);
+ free_netdev(priv->netdev); /* priv is in netdev */
at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
}
@@ -2621,8 +5425,8 @@ static int at76_probe(struct usb_interface *interface,
we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
if (op_mode == OPMODE_HW_CONFIG_MODE) {
- dev_err(&interface->dev,
- "cannot handle a device in HW_CONFIG_MODE\n");
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot handle a device in HW_CONFIG_MODE\n");
ret = -EBUSY;
goto error;
}
@@ -2630,12 +5434,13 @@ static int at76_probe(struct usb_interface *interface,
if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
&& op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
/* download internal firmware part */
- dev_dbg(&interface->dev, "downloading internal firmware\n");
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading internal firmware\n");
ret = at76_load_internal_fw(udev, fwe);
if (ret < 0) {
- dev_err(&interface->dev,
- "error %d downloading internal firmware\n",
- ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d downloading internal firmware\n",
+ ret);
goto error;
}
usb_put_dev(udev);
@@ -2660,7 +5465,8 @@ static int at76_probe(struct usb_interface *interface,
need_ext_fw = 1;
if (need_ext_fw) {
- dev_dbg(&interface->dev, "downloading external firmware\n");
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading external firmware\n");
ret = at76_load_external_fw(udev, fwe);
if (ret)
@@ -2669,8 +5475,8 @@ static int at76_probe(struct usb_interface *interface,
/* Re-check firmware version */
ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
if (ret < 0) {
- dev_err(&interface->dev,
- "error %d getting firmware version\n", ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d getting firmware version\n", ret);
goto error;
}
}
@@ -2681,6 +5487,7 @@ static int at76_probe(struct usb_interface *interface,
goto error;
}
+ SET_NETDEV_DEV(priv->netdev, &interface->dev);
usb_set_intfdata(interface, priv);
memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
@@ -2708,7 +5515,7 @@ static void at76_disconnect(struct usb_interface *interface)
if (!priv)
return;
- printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
+ printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name);
at76_delete_device(priv);
dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
}
@@ -2764,8 +5571,5 @@ MODULE_AUTHOR("Alex <alex@foogod.com>");
MODULE_AUTHOR("Nick Jones");
MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
-MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
-MODULE_AUTHOR("Milan Plzik <milan.plzik@gmail.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
index 8bb352f16d4..b20be9da1fa 100644
--- a/drivers/staging/at76_usb/at76_usb.h
+++ b/drivers/staging/at76_usb/at76_usb.h
@@ -34,6 +34,23 @@ enum board_type {
BOARD_505AMX = 8
};
+/* our private ioctl's */
+/* preamble length (0 - long, 1 - short, 2 - auto) */
+#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0)
+#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1)
+/* which debug channels are enabled */
+#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2)
+#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3)
+/* power save mode (incl. the Atmel proprietary smart save mode) */
+#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4)
+#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5)
+/* min and max channel times for scan */
+#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6)
+#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7)
+/* scan mode (0 - active, 1 - passive) */
+#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8)
+#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9)
+
#define CMD_STATUS_IDLE 0x00
#define CMD_STATUS_COMPLETE 0x01
#define CMD_STATUS_UNKNOWN 0x02
@@ -65,7 +82,6 @@ enum board_type {
#define MIB_MAC 0x03
#define MIB_MAC_MGMT 0x05
#define MIB_MAC_WEP 0x06
-#define MIB_MAC_ENCRYPTION 0x06
#define MIB_PHY 0x07
#define MIB_FW_VERSION 0x08
#define MIB_MDOMAIN 0x09
@@ -90,26 +106,6 @@ enum board_type {
#define AT76_PM_ON 2
#define AT76_PM_SMART 3
-/* cipher values for encryption keys */
-#define CIPHER_NONE 0 /* this value is only guessed */
-#define CIPHER_WEP64 1
-#define CIPHER_TKIP 2
-#define CIPHER_CCMP 3
-#define CIPHER_CCX 4 /* for consistency sake only */
-#define CIPHER_WEP128 5
-
-/* bit flags key types for encryption keys */
-#define KEY_PAIRWISE 2
-#define KEY_TX 4
-
-#define CIPHER_KEYS (4)
-#define CIPHER_KEY_LEN (40)
-
-struct key_config {
- u8 cipher;
- u8 keylen;
-};
-
struct hwcfg_r505 {
u8 cr39_values[14];
u8 reserved1[14];
@@ -151,9 +147,6 @@ union at76_hwcfg {
#define WEP_SMALL_KEY_LEN (40 / 8)
#define WEP_LARGE_KEY_LEN (104 / 8)
-#define WEP_KEYS (4)
-
-
struct at76_card_config {
u8 exclude_unencrypted;
@@ -168,7 +161,7 @@ struct at76_card_config {
u8 privacy_invoked;
u8 wep_default_key_id; /* 0..3 */
u8 current_ssid[32];
- u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN];
+ u8 wep_default_key_value[4][WEP_KEY_LEN];
u8 ssid_len;
u8 short_preamble;
__le16 beacon_period;
@@ -193,7 +186,7 @@ struct at76_rx_buffer {
u8 link_quality;
u8 noise_level;
__le32 rx_time;
- u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+ u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
} __attribute__((packed));
/* Length of Atmel-specific Tx header before 802.11 frame */
@@ -203,11 +196,8 @@ struct at76_tx_buffer {
__le16 wlength;
u8 tx_rate;
u8 padding;
- u8 key_id;
- u8 cipher_type;
- u8 cipher_length;
- u8 reserved;
- u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+ u8 reserved[4];
+ u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
} __attribute__((packed));
/* defines for scan_type below */
@@ -254,7 +244,6 @@ struct set_mib_buffer {
u8 byte;
__le16 word;
u8 addr[ETH_ALEN];
- u8 data[256]; /* we need more space for mib_mac_encryption */
} data;
} __attribute__((packed));
@@ -328,24 +317,10 @@ struct mib_mac_wep {
u8 exclude_unencrypted;
__le32 wep_icv_error_count;
__le32 wep_excluded_count;
- u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN];
+ u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN];
u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
} __attribute__((packed));
-struct mib_mac_encryption {
- u8 cipher_default_keyvalue[CIPHER_KEYS][CIPHER_KEY_LEN];
- u8 tkip_bssid[6];
- u8 privacy_invoked;
- u8 cipher_default_key_id;
- u8 cipher_default_group_key_id;
- u8 exclude_unencrypted;
- u8 wep_encryption_type;
- u8 ckip_key_permutation; /* bool */
- __le32 wep_icv_error_count;
- __le32 wep_excluded_count;
- u8 key_rsc[CIPHER_KEYS][8];
-} __attribute__((packed));
-
struct mib_phy {
__le32 ed_threshold;
@@ -389,6 +364,16 @@ struct at76_fw_header {
__le32 ext_fw_len; /* external firmware image length */
} __attribute__((packed));
+enum mac_state {
+ MAC_INIT,
+ MAC_SCANNING,
+ MAC_AUTH,
+ MAC_ASSOC,
+ MAC_JOINING,
+ MAC_CONNECTED,
+ MAC_OWN_IBSS
+};
+
/* a description of a regulatory domain and the allowed channels */
struct reg_domain {
u16 code;
@@ -396,6 +381,47 @@ struct reg_domain {
u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
};
+/* how long do we keep a (I)BSS in the bss_list in jiffies
+ this should be long enough for the user to retrieve the table
+ (by iwlist ?) after the device started, because all entries from
+ other channels than the one the device locks on get removed, too */
+#define BSS_LIST_TIMEOUT (120 * HZ)
+/* struct to store BSS info found during scan */
+#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */
+
+struct bss_info {
+ struct list_head list;
+
+ u8 bssid[ETH_ALEN]; /* bssid */
+ u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */
+ u8 ssid_len; /* length of ssid above */
+ u8 channel;
+ u16 capa; /* BSS capabilities */
+ u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */
+ u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of
+ 500 kbps, ORed with 0x80 for
+ basic rates */
+ u8 rates_len;
+
+ /* quality of received beacon */
+ u8 rssi;
+ u8 link_qual;
+ u8 noise_level;
+
+ unsigned long last_rx; /* time (jiffies) of last beacon received */
+};
+
+/* a rx data buffer to collect rx fragments */
+struct rx_data_buf {
+ u8 sender[ETH_ALEN]; /* sender address */
+ u16 seqnr; /* sequence number */
+ u16 fragnr; /* last fragment received */
+ unsigned long last_rx; /* jiffies of last rx */
+ struct sk_buff *skb; /* == NULL if entry is free */
+};
+
+#define NR_RX_DATA_BUF 8
+
/* Data for one loaded firmware file */
struct fwentry {
const char *const fwname;
@@ -412,9 +438,11 @@ struct fwentry {
struct at76_priv {
struct usb_device *udev; /* USB device pointer */
+ struct net_device *netdev; /* net device pointer */
+ struct net_device_stats stats; /* net device stats */
+ struct iw_statistics wstats; /* wireless stats */
struct sk_buff *rx_skb; /* skbuff for receiving data */
- struct sk_buff *tx_skb; /* skbuff for transmitting data */
void *bulk_out_buffer; /* buffer for sending data */
struct urb *tx_urb; /* URB for sending data */
@@ -426,17 +454,26 @@ struct at76_priv {
struct mutex mtx; /* locks this structure */
/* work queues */
+ struct work_struct work_assoc_done;
+ struct work_struct work_join;
+ struct work_struct work_new_bss;
+ struct work_struct work_start_scan;
struct work_struct work_set_promisc;
struct work_struct work_submit_rx;
- struct delayed_work dwork_hw_scan;
+ struct delayed_work dwork_restart;
+ struct delayed_work dwork_get_scan;
+ struct delayed_work dwork_beacon;
+ struct delayed_work dwork_auth;
+ struct delayed_work dwork_assoc;
struct tasklet_struct rx_tasklet;
/* the WEP stuff */
int wep_enabled; /* 1 if WEP is enabled */
int wep_key_id; /* key id to be used */
- u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN]; /* WEP keys */
- u8 wep_keys_len[WEP_KEYS]; /* length of WEP keys */
+ u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys,
+ 5 or 13 bytes are used */
+ u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */
int channel;
int iw_mode;
@@ -458,13 +495,44 @@ struct at76_priv {
int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
int scan_need_any; /* if set, need to scan for any ESSID */
+ /* the list we got from scanning */
+ spinlock_t bss_list_spinlock; /* protects bss_list operations */
+ struct list_head bss_list; /* list of BSS we got beacons from */
+ struct timer_list bss_list_timer; /* timer to purge old entries
+ from bss_list */
+ struct bss_info *curr_bss; /* current BSS */
u16 assoc_id; /* current association ID, if associated */
+ u8 wanted_bssid[ETH_ALEN];
+ int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */
+
+ /* some data for infrastructure mode only */
+ spinlock_t mgmt_spinlock; /* this spinlock protects access to
+ next_mgmt_bulk */
+
+ struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to
+ send via bulk out */
+ enum mac_state mac_state;
+ enum {
+ SCAN_IDLE,
+ SCAN_IN_PROGRESS,
+ SCAN_COMPLETED
+ } scan_state;
+ time_t last_scan;
+
+ int retries; /* remaining retries in case of timeout when
+ * sending AuthReq or AssocReq */
u8 pm_mode; /* power management mode */
u32 pm_period; /* power management period in microseconds */
struct reg_domain const *domain; /* reg domain description */
+ /* iwspy support */
+ spinlock_t spy_spinlock;
+ struct iw_spy_data spy_data;
+
+ struct iw_public_data wireless_data;
+
/* These fields contain HW config provided by the device (not all of
* these fields are used by all board types) */
u8 mac_addr[ETH_ALEN];
@@ -472,6 +540,9 @@ struct at76_priv {
struct at76_card_config card_config;
+ /* store rx fragments until complete */
+ struct rx_data_buf rx_data[NR_RX_DATA_BUF];
+
enum board_type board_type;
struct mib_fw_version fw_version;
@@ -479,20 +550,58 @@ struct at76_priv {
unsigned int netdev_registered:1;
struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
+ /* beacon counting */
int beacon_period; /* period of mgmt beacons, Kus */
+ int beacons_received;
+ unsigned long beacons_last_qual; /* time we restarted counting
+ beacons */
+};
- struct ieee80211_hw *hw;
- int mac80211_registered;
-
- struct key_config keys[4]; /* installed key types */
- u8 default_pairwise_key;
- u8 default_group_key;
+struct at76_rx_radiotap {
+ struct ieee80211_radiotap_header rt_hdr;
+ __le64 rt_tsft;
+ u8 rt_flags;
+ u8 rt_rate;
+ s8 rt_signal;
+ s8 rt_noise;
};
-#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS
+#define AT76_RX_RADIOTAP_PRESENT \
+ ((1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
+
+#define BEACON_MAX_DATA_LENGTH 1500
+
+/* the maximum size of an AssocReq packet */
+#define ASSOCREQ_MAX_SIZE \
+ (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \
+ 1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4)
+
+/* for shared secret auth, add the challenge text size */
+#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth))
+
+/* Maximal number of AuthReq retries */
+#define AUTH_RETRIES 3
+/* Maximal number of AssocReq retries */
+#define ASSOC_RETRIES 3
+
+/* Beacon timeout in managed mode when we are connected */
+#define BEACON_TIMEOUT (10 * HZ)
+
+/* Timeout for authentication response */
+#define AUTH_TIMEOUT (1 * HZ)
+
+/* Timeout for association response */
+#define ASSOC_TIMEOUT (1 * HZ)
+
+/* Polling interval when scan is running */
#define SCAN_POLL_INTERVAL (HZ / 4)
+/* Command completion timeout */
#define CMD_COMPLETION_TIMEOUT (5 * HZ)
#define DEF_RTS_THRESHOLD 1536
@@ -502,6 +611,8 @@ struct at76_priv {
#define DEF_SCAN_MIN_TIME 10
#define DEF_SCAN_MAX_TIME 120
+#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1)
+
/* the max padding size for tx in bytes (see calc_padding) */
#define MAX_PADDING_SIZE 53
diff --git a/drivers/staging/benet/Kconfig b/drivers/staging/benet/Kconfig
deleted file mode 100644
index f6806074f99..00000000000
--- a/drivers/staging/benet/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config BENET
- tristate "ServerEngines 10Gb NIC - BladeEngine"
- depends on PCI && INET
- select INET_LRO
- help
- This driver implements the NIC functionality for ServerEngines
- 10Gb network adapter BladeEngine (EC 3210).
diff --git a/drivers/staging/benet/MAINTAINERS b/drivers/staging/benet/MAINTAINERS
deleted file mode 100644
index d5ce340218b..00000000000
--- a/drivers/staging/benet/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-SERVER ENGINES 10Gbe NIC - BLADE-ENGINE
-P: Subbu Seetharaman
-M: subbus@serverengines.com
-L: netdev@vger.kernel.org
-W: http://www.serverengines.com
-S: Supported
diff --git a/drivers/staging/benet/Makefile b/drivers/staging/benet/Makefile
deleted file mode 100644
index 460b923b99b..00000000000
--- a/drivers/staging/benet/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Makefile to build the network driver for ServerEngine's BladeEngine
-#
-obj-$(CONFIG_BENET) += benet.o
-
-benet-y := be_init.o \
- be_int.o \
- be_netif.o \
- be_ethtool.o \
- funcobj.o \
- cq.o \
- eq.o \
- mpu.o \
- eth.o
diff --git a/drivers/staging/benet/TODO b/drivers/staging/benet/TODO
deleted file mode 100644
index a51dfb59a62..00000000000
--- a/drivers/staging/benet/TODO
+++ /dev/null
@@ -1,6 +0,0 @@
-TODO:
- - remove wrappers around common iowrite functions
- - full netdev audit of common problems/issues
-
-Please send all patches and questions to Subbu Seetharaman
-<subbus@serverengines.com> and Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/benet/asyncmesg.h b/drivers/staging/benet/asyncmesg.h
deleted file mode 100644
index d1e779adb84..00000000000
--- a/drivers/staging/benet/asyncmesg.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __asyncmesg_amap_h__
-#define __asyncmesg_amap_h__
-#include "fwcmd_common.h"
-
-/* --- ASYNC_EVENT_CODES --- */
-#define ASYNC_EVENT_CODE_LINK_STATE (1)
-#define ASYNC_EVENT_CODE_ISCSI (2)
-
-/* --- ASYNC_LINK_STATES --- */
-#define ASYNC_EVENT_LINK_DOWN (0) /* Link Down on a port */
-#define ASYNC_EVENT_LINK_UP (1) /* Link Up on a port */
-
-/*
- * The last 4 bytes of the async events have this common format. It allows
- * the driver to distinguish [link]MCC_CQ_ENTRY[/link] structs from
- * asynchronous events. Both arrive on the same completion queue. This
- * structure also contains the common fields used to decode the async event.
- */
-struct BE_ASYNC_EVENT_TRAILER_AMAP {
- u8 rsvd0[8]; /* DWORD 0 */
- u8 event_code[8]; /* DWORD 0 */
- u8 event_type[8]; /* DWORD 0 */
- u8 rsvd1[6]; /* DWORD 0 */
- u8 async_event; /* DWORD 0 */
- u8 valid; /* DWORD 0 */
-} __packed;
-struct ASYNC_EVENT_TRAILER_AMAP {
- u32 dw[1];
-};
-
-/*
- * Applicable in Initiator, Target and NIC modes.
- * A link state async event is seen by all device drivers as soon they
- * create an MCC ring. Thereafter, anytime the link status changes the
- * drivers will receive a link state async event. Notifications continue to
- * be sent until a driver destroys its MCC ring. A link down event is
- * reported when either port loses link. A link up event is reported
- * when either port regains link. When BE's failover mechanism is enabled, a
- * link down on the active port causes traffic to be diverted to the standby
- * port by the BE's ARM firmware (assuming the standby port has link). In
- * this case, the standy port assumes the active status. Note: when link is
- * restored on the failed port, traffic continues on the currently active
- * port. The ARM firmware does not attempt to 'fail back' traffic to
- * the restored port.
- */
-struct BE_ASYNC_EVENT_LINK_STATE_AMAP {
- u8 port0_link_status[8];
- u8 port1_link_status[8];
- u8 active_port[8];
- u8 rsvd0[8]; /* DWORD 0 */
- u8 port0_duplex[8];
- u8 port0_speed[8];
- u8 port1_duplex[8];
- u8 port1_speed[8];
- u8 port0_fault[8];
- u8 port1_fault[8];
- u8 rsvd1[2][8]; /* DWORD 2 */
- struct BE_ASYNC_EVENT_TRAILER_AMAP trailer;
-} __packed;
-struct ASYNC_EVENT_LINK_STATE_AMAP {
- u32 dw[4];
-};
-#endif /* __asyncmesg_amap_h__ */
diff --git a/drivers/staging/benet/be_cm.h b/drivers/staging/benet/be_cm.h
deleted file mode 100644
index b7a1dfd20c3..00000000000
--- a/drivers/staging/benet/be_cm.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __be_cm_amap_h__
-#define __be_cm_amap_h__
-#include "be_common.h"
-#include "etx_context.h"
-#include "mpu_context.h"
-
-/*
- * --- CEV_WATERMARK_ENUM ---
- * CQ/EQ Watermark Encodings. Encoded as number of free entries in
- * Queue when Watermark is reached.
- */
-#define CEV_WMARK_0 (0) /* Watermark when Queue full */
-#define CEV_WMARK_16 (1) /* Watermark at 16 free entries */
-#define CEV_WMARK_32 (2) /* Watermark at 32 free entries */
-#define CEV_WMARK_48 (3) /* Watermark at 48 free entries */
-#define CEV_WMARK_64 (4) /* Watermark at 64 free entries */
-#define CEV_WMARK_80 (5) /* Watermark at 80 free entries */
-#define CEV_WMARK_96 (6) /* Watermark at 96 free entries */
-#define CEV_WMARK_112 (7) /* Watermark at 112 free entries */
-#define CEV_WMARK_128 (8) /* Watermark at 128 free entries */
-#define CEV_WMARK_144 (9) /* Watermark at 144 free entries */
-#define CEV_WMARK_160 (10) /* Watermark at 160 free entries */
-#define CEV_WMARK_176 (11) /* Watermark at 176 free entries */
-#define CEV_WMARK_192 (12) /* Watermark at 192 free entries */
-#define CEV_WMARK_208 (13) /* Watermark at 208 free entries */
-#define CEV_WMARK_224 (14) /* Watermark at 224 free entries */
-#define CEV_WMARK_240 (15) /* Watermark at 240 free entries */
-
-/*
- * --- CQ_CNT_ENUM ---
- * Completion Queue Count Encodings.
- */
-#define CEV_CQ_CNT_256 (0) /* CQ has 256 entries */
-#define CEV_CQ_CNT_512 (1) /* CQ has 512 entries */
-#define CEV_CQ_CNT_1024 (2) /* CQ has 1024 entries */
-
-/*
- * --- EQ_CNT_ENUM ---
- * Event Queue Count Encodings.
- */
-#define CEV_EQ_CNT_256 (0) /* EQ has 256 entries (16-byte EQEs only) */
-#define CEV_EQ_CNT_512 (1) /* EQ has 512 entries (16-byte EQEs only) */
-#define CEV_EQ_CNT_1024 (2) /* EQ has 1024 entries (4-byte or */
- /* 16-byte EQEs only) */
-#define CEV_EQ_CNT_2048 (3) /* EQ has 2048 entries (4-byte or */
- /* 16-byte EQEs only) */
-#define CEV_EQ_CNT_4096 (4) /* EQ has 4096 entries (4-byte EQEs only) */
-
-/*
- * --- EQ_SIZE_ENUM ---
- * Event Queue Entry Size Encoding.
- */
-#define CEV_EQ_SIZE_4 (0) /* EQE is 4 bytes */
-#define CEV_EQ_SIZE_16 (1) /* EQE is 16 bytes */
-
-/*
- * Completion Queue Context Table Entry. Contains the state of a CQ.
- * Located in RAM within the CEV block.
- */
-struct BE_CQ_CONTEXT_AMAP {
- u8 Cidx[11]; /* DWORD 0 */
- u8 Watermark[4]; /* DWORD 0 */
- u8 NoDelay; /* DWORD 0 */
- u8 EPIdx[11]; /* DWORD 0 */
- u8 Count[2]; /* DWORD 0 */
- u8 valid; /* DWORD 0 */
- u8 SolEvent; /* DWORD 0 */
- u8 Eventable; /* DWORD 0 */
- u8 Pidx[11]; /* DWORD 1 */
- u8 PD[10]; /* DWORD 1 */
- u8 EQID[7]; /* DWORD 1 */
- u8 Func; /* DWORD 1 */
- u8 WME; /* DWORD 1 */
- u8 Stalled; /* DWORD 1 */
- u8 Armed; /* DWORD 1 */
-} __packed;
-struct CQ_CONTEXT_AMAP {
- u32 dw[2];
-};
-
-/*
- * Event Queue Context Table Entry. Contains the state of an EQ.
- * Located in RAM in the CEV block.
- */
-struct BE_EQ_CONTEXT_AMAP {
- u8 Cidx[13]; /* DWORD 0 */
- u8 rsvd0[2]; /* DWORD 0 */
- u8 Func; /* DWORD 0 */
- u8 EPIdx[13]; /* DWORD 0 */
- u8 valid; /* DWORD 0 */
- u8 rsvd1; /* DWORD 0 */
- u8 Size; /* DWORD 0 */
- u8 Pidx[13]; /* DWORD 1 */
- u8 rsvd2[3]; /* DWORD 1 */
- u8 PD[10]; /* DWORD 1 */
- u8 Count[3]; /* DWORD 1 */
- u8 SolEvent; /* DWORD 1 */
- u8 Stalled; /* DWORD 1 */
- u8 Armed; /* DWORD 1 */
- u8 Watermark[4]; /* DWORD 2 */
- u8 WME; /* DWORD 2 */
- u8 rsvd3[3]; /* DWORD 2 */
- u8 EventVect[6]; /* DWORD 2 */
- u8 rsvd4[2]; /* DWORD 2 */
- u8 Delay[8]; /* DWORD 2 */
- u8 rsvd5[6]; /* DWORD 2 */
- u8 TMR; /* DWORD 2 */
- u8 rsvd6; /* DWORD 2 */
- u8 rsvd7[32]; /* DWORD 3 */
-} __packed;
-struct EQ_CONTEXT_AMAP {
- u32 dw[4];
-};
-
-#endif /* __be_cm_amap_h__ */
diff --git a/drivers/staging/benet/be_common.h b/drivers/staging/benet/be_common.h
deleted file mode 100644
index 7e63dc5e334..00000000000
--- a/drivers/staging/benet/be_common.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __be_common_amap_h__
-#define __be_common_amap_h__
-
-/* Physical Address. */
-struct BE_PHYS_ADDR_AMAP {
- u8 lo[32]; /* DWORD 0 */
- u8 hi[32]; /* DWORD 1 */
-} __packed;
-struct PHYS_ADDR_AMAP {
- u32 dw[2];
-};
-
-/* Virtual Address. */
-struct BE_VIRT_ADDR_AMAP {
- u8 lo[32]; /* DWORD 0 */
- u8 hi[32]; /* DWORD 1 */
-} __packed;
-struct VIRT_ADDR_AMAP {
- u32 dw[2];
-};
-
-/* Scatter gather element. */
-struct BE_SGE_AMAP {
- u8 addr_hi[32]; /* DWORD 0 */
- u8 addr_lo[32]; /* DWORD 1 */
- u8 rsvd0[32]; /* DWORD 2 */
- u8 len[16]; /* DWORD 3 */
- u8 rsvd1[16]; /* DWORD 3 */
-} __packed;
-struct SGE_AMAP {
- u32 dw[4];
-};
-
-#endif /* __be_common_amap_h__ */
diff --git a/drivers/staging/benet/be_ethtool.c b/drivers/staging/benet/be_ethtool.c
deleted file mode 100644
index 027af85707a..00000000000
--- a/drivers/staging/benet/be_ethtool.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * be_ethtool.c
- *
- * This file contains various functions that ethtool can use
- * to talk to the driver and the BE H/W.
- */
-
-#include "benet.h"
-
-#include <linux/ethtool.h>
-
-static const char benet_gstrings_stats[][ETH_GSTRING_LEN] = {
-/* net_device_stats */
- "rx_packets",
- "tx_packets",
- "rx_bytes",
- "tx_bytes",
- "rx_errors",
- "tx_errors",
- "rx_dropped",
- "tx_dropped",
- "multicast",
- "collisions",
- "rx_length_errors",
- "rx_over_errors",
- "rx_crc_errors",
- "rx_frame_errors",
- "rx_fifo_errors",
- "rx_missed_errors",
- "tx_aborted_errors",
- "tx_carrier_errors",
- "tx_fifo_errors",
- "tx_heartbeat_errors",
- "tx_window_errors",
- "rx_compressed",
- "tc_compressed",
-/* BE driver Stats */
- "bes_tx_reqs",
- "bes_tx_fails",
- "bes_fwd_reqs",
- "bes_tx_wrbs",
- "bes_interrupts",
- "bes_events",
- "bes_tx_events",
- "bes_rx_events",
- "bes_tx_compl",
- "bes_rx_compl",
- "bes_ethrx_post_fail",
- "bes_802_3_dropped_frames",
- "bes_802_3_malformed_frames",
- "bes_rx_misc_pkts",
- "bes_eth_tx_rate",
- "bes_eth_rx_rate",
- "Num Packets collected",
- "Num Times Flushed",
-};
-
-#define NET_DEV_STATS_LEN \
- (sizeof(struct net_device_stats)/sizeof(unsigned long))
-
-#define BENET_STATS_LEN ARRAY_SIZE(benet_gstrings_stats)
-
-static void
-be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- strncpy(drvinfo->driver, be_driver_name, 32);
- strncpy(drvinfo->version, be_drvr_ver, 32);
- strncpy(drvinfo->fw_version, be_fw_ver, 32);
- strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
- drvinfo->testinfo_len = 0;
- drvinfo->regdump_len = 0;
- drvinfo->eedump_len = 0;
-}
-
-static int
-be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- coalesce->rx_max_coalesced_frames = adapter->max_rx_coal;
-
- coalesce->rx_coalesce_usecs = adapter->cur_eqd;
- coalesce->rx_coalesce_usecs_high = adapter->max_eqd;
- coalesce->rx_coalesce_usecs_low = adapter->min_eqd;
-
- coalesce->tx_coalesce_usecs = adapter->cur_eqd;
- coalesce->tx_coalesce_usecs_high = adapter->max_eqd;
- coalesce->tx_coalesce_usecs_low = adapter->min_eqd;
-
- coalesce->use_adaptive_rx_coalesce = adapter->enable_aic;
- coalesce->use_adaptive_tx_coalesce = adapter->enable_aic;
-
- return 0;
-}
-
-/*
- * This routine is used to set interrup coalescing delay *as well as*
- * the number of pkts to coalesce for LRO.
- */
-static int
-be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- struct be_eq_object *eq_objectp;
- u32 max, min, cur;
- int status;
-
- adapter->max_rx_coal = coalesce->rx_max_coalesced_frames;
- if (adapter->max_rx_coal >= BE_LRO_MAX_PKTS)
- adapter->max_rx_coal = BE_LRO_MAX_PKTS;
-
- if (adapter->enable_aic == 0 &&
- coalesce->use_adaptive_rx_coalesce == 1) {
- /* if AIC is being turned on now, start with an EQD of 0 */
- adapter->cur_eqd = 0;
- }
- adapter->enable_aic = coalesce->use_adaptive_rx_coalesce;
-
- /* round off to nearest multiple of 8 */
- max = (((coalesce->rx_coalesce_usecs_high + 4) >> 3) << 3);
- min = (((coalesce->rx_coalesce_usecs_low + 4) >> 3) << 3);
- cur = (((coalesce->rx_coalesce_usecs + 4) >> 3) << 3);
-
- if (adapter->enable_aic) {
- /* accept low and high if AIC is enabled */
- if (max > MAX_EQD)
- max = MAX_EQD;
- if (min > max)
- min = max;
- adapter->max_eqd = max;
- adapter->min_eqd = min;
- if (adapter->cur_eqd > max)
- adapter->cur_eqd = max;
- if (adapter->cur_eqd < min)
- adapter->cur_eqd = min;
- } else {
- /* accept specified coalesce_usecs only if AIC is disabled */
- if (cur > MAX_EQD)
- cur = MAX_EQD;
- eq_objectp = &pnob->event_q_obj;
- status =
- be_eq_modify_delay(&pnob->fn_obj, 1, &eq_objectp, &cur,
- NULL, NULL, NULL);
- if (status == BE_SUCCESS)
- adapter->cur_eqd = cur;
- }
- return 0;
-}
-
-static u32 be_get_rx_csum(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- return adapter->rx_csum;
-}
-
-static int be_set_rx_csum(struct net_device *netdev, uint32_t data)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- if (data)
- adapter->rx_csum = 1;
- else
- adapter->rx_csum = 0;
-
- return 0;
-}
-
-static void
-be_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
-{
- switch (stringset) {
- case ETH_SS_STATS:
- memcpy(data, *benet_gstrings_stats,
- sizeof(benet_gstrings_stats));
- break;
- }
-}
-
-static int be_get_stats_count(struct net_device *netdev)
-{
- return BENET_STATS_LEN;
-}
-
-static void
-be_get_ethtool_stats(struct net_device *netdev,
- struct ethtool_stats *stats, uint64_t *data)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- int i;
-
- benet_get_stats(netdev);
-
- for (i = 0; i <= NET_DEV_STATS_LEN; i++)
- data[i] = ((unsigned long *)&adapter->benet_stats)[i];
-
- data[i] = adapter->be_stat.bes_tx_reqs;
- data[i++] = adapter->be_stat.bes_tx_fails;
- data[i++] = adapter->be_stat.bes_fwd_reqs;
- data[i++] = adapter->be_stat.bes_tx_wrbs;
-
- data[i++] = adapter->be_stat.bes_ints;
- data[i++] = adapter->be_stat.bes_events;
- data[i++] = adapter->be_stat.bes_tx_events;
- data[i++] = adapter->be_stat.bes_rx_events;
- data[i++] = adapter->be_stat.bes_tx_compl;
- data[i++] = adapter->be_stat.bes_rx_compl;
- data[i++] = adapter->be_stat.bes_ethrx_post_fail;
- data[i++] = adapter->be_stat.bes_802_3_dropped_frames;
- data[i++] = adapter->be_stat.bes_802_3_malformed_frames;
- data[i++] = adapter->be_stat.bes_rx_misc_pkts;
- data[i++] = adapter->be_stat.bes_eth_tx_rate;
- data[i++] = adapter->be_stat.bes_eth_rx_rate;
- data[i++] = adapter->be_stat.bes_rx_coal;
- data[i++] = adapter->be_stat.bes_rx_flush;
-
-}
-
-static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
-{
- ecmd->speed = SPEED_10000;
- ecmd->duplex = DUPLEX_FULL;
- ecmd->autoneg = AUTONEG_DISABLE;
- return 0;
-}
-
-/* Get the Ring parameters from the pnob */
-static void
-be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- /* Pre Set Maxims */
- ring->rx_max_pending = pnob->rx_q_len;
- ring->rx_mini_max_pending = ring->rx_mini_max_pending;
- ring->rx_jumbo_max_pending = ring->rx_jumbo_max_pending;
- ring->tx_max_pending = pnob->tx_q_len;
-
- /* Current hardware Settings */
- ring->rx_pending = atomic_read(&pnob->rx_q_posted);
- ring->rx_mini_pending = ring->rx_mini_pending;
- ring->rx_jumbo_pending = ring->rx_jumbo_pending;
- ring->tx_pending = atomic_read(&pnob->tx_q_used);
-
-}
-
-static void
-be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- bool rxfc, txfc;
- int status;
-
- status = be_eth_get_flow_control(&pnob->fn_obj, &txfc, &rxfc);
- if (status != BE_SUCCESS) {
- dev_info(&netdev->dev, "Unable to get pause frame settings\n");
- /* return defaults */
- ecmd->rx_pause = 1;
- ecmd->tx_pause = 0;
- ecmd->autoneg = AUTONEG_ENABLE;
- return;
- }
-
- if (txfc == true)
- ecmd->tx_pause = 1;
- else
- ecmd->tx_pause = 0;
-
- if (rxfc == true)
- ecmd->rx_pause = 1;
- else
- ecmd->rx_pause = 0;
-
- ecmd->autoneg = AUTONEG_ENABLE;
-}
-
-static int
-be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- bool txfc, rxfc;
- int status;
-
- if (ecmd->autoneg != AUTONEG_ENABLE)
- return -EINVAL;
-
- if (ecmd->tx_pause)
- txfc = true;
- else
- txfc = false;
-
- if (ecmd->rx_pause)
- rxfc = true;
- else
- rxfc = false;
-
- status = be_eth_set_flow_control(&pnob->fn_obj, txfc, rxfc);
- if (status != BE_SUCCESS) {
- dev_info(&netdev->dev, "Unable to set pause frame settings\n");
- return -1;
- }
- return 0;
-}
-
-struct ethtool_ops be_ethtool_ops = {
- .get_settings = be_get_settings,
- .get_drvinfo = be_get_drvinfo,
- .get_link = ethtool_op_get_link,
- .get_coalesce = be_get_coalesce,
- .set_coalesce = be_set_coalesce,
- .get_ringparam = be_get_ringparam,
- .get_pauseparam = be_get_pauseparam,
- .set_pauseparam = be_set_pauseparam,
- .get_rx_csum = be_get_rx_csum,
- .set_rx_csum = be_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
- .get_strings = be_get_strings,
- .get_stats_count = be_get_stats_count,
- .get_ethtool_stats = be_get_ethtool_stats,
-};
diff --git a/drivers/staging/benet/be_init.c b/drivers/staging/benet/be_init.c
deleted file mode 100644
index 12a026c3f9e..00000000000
--- a/drivers/staging/benet/be_init.c
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include <linux/etherdevice.h>
-#include "benet.h"
-
-#define DRVR_VERSION "1.0.728"
-
-static const struct pci_device_id be_device_id_table[] = {
- {PCI_DEVICE(0x19a2, 0x0201)},
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, be_device_id_table);
-
-MODULE_VERSION(DRVR_VERSION);
-
-#define DRV_DESCRIPTION "ServerEngines BladeEngine Network Driver Version "
-
-MODULE_DESCRIPTION(DRV_DESCRIPTION DRVR_VERSION);
-MODULE_AUTHOR("ServerEngines");
-MODULE_LICENSE("GPL");
-
-static unsigned int msix = 1;
-module_param(msix, uint, S_IRUGO);
-MODULE_PARM_DESC(msix, "Use MSI-x interrupts");
-
-static unsigned int rxbuf_size = 2048; /* Default RX frag size */
-module_param(rxbuf_size, uint, S_IRUGO);
-MODULE_PARM_DESC(rxbuf_size, "Size of buffers to hold Rx data");
-
-const char be_drvr_ver[] = DRVR_VERSION;
-char be_fw_ver[32]; /* F/W version filled in by be_probe */
-char be_driver_name[] = "benet";
-
-/*
- * Number of entries in each queue.
- */
-#define EVENT_Q_LEN 1024
-#define ETH_TXQ_LEN 2048
-#define ETH_TXCQ_LEN 1024
-#define ETH_RXQ_LEN 1024 /* Does not support any other value */
-#define ETH_UC_RXCQ_LEN 1024
-#define ETH_BC_RXCQ_LEN 256
-#define MCC_Q_LEN 64 /* total size not to exceed 8 pages */
-#define MCC_CQ_LEN 256
-
-/* Bit mask describing events of interest to be traced */
-unsigned int trace_level;
-
-static int
-init_pci_be_function(struct be_adapter *adapter, struct pci_dev *pdev)
-{
- u64 pa;
-
- /* CSR */
- pa = pci_resource_start(pdev, 2);
- adapter->csr_va = ioremap_nocache(pa, pci_resource_len(pdev, 2));
- if (adapter->csr_va == NULL)
- return -ENOMEM;
-
- /* Door Bell */
- pa = pci_resource_start(pdev, 4);
- adapter->db_va = ioremap_nocache(pa, (128 * 1024));
- if (adapter->db_va == NULL) {
- iounmap(adapter->csr_va);
- return -ENOMEM;
- }
-
- /* PCI */
- pa = pci_resource_start(pdev, 1);
- adapter->pci_va = ioremap_nocache(pa, pci_resource_len(pdev, 1));
- if (adapter->pci_va == NULL) {
- iounmap(adapter->csr_va);
- iounmap(adapter->db_va);
- return -ENOMEM;
- }
- return 0;
-}
-
-/*
- This function enables the interrupt corresponding to the Event
- queue ID for the given NetObject
-*/
-void be_enable_eq_intr(struct be_net_object *pnob)
-{
- struct CQ_DB_AMAP cqdb;
- cqdb.dw[0] = 0;
- AMAP_SET_BITS_PTR(CQ_DB, event, &cqdb, 1);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, 1);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, 0);
- AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, pnob->event_q_id);
- PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]);
-}
-
-/*
- This function disables the interrupt corresponding to the Event
- queue ID for the given NetObject
-*/
-void be_disable_eq_intr(struct be_net_object *pnob)
-{
- struct CQ_DB_AMAP cqdb;
- cqdb.dw[0] = 0;
- AMAP_SET_BITS_PTR(CQ_DB, event, &cqdb, 1);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, 0);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, 0);
- AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, pnob->event_q_id);
- PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]);
-}
-
-/*
- This function enables the interrupt from the network function
- of the BladeEngine. Use the function be_disable_eq_intr()
- to enable the interrupt from the event queue of only one specific
- NetObject
-*/
-void be_enable_intr(struct be_net_object *pnob)
-{
- struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl;
- u32 host_intr;
-
- ctrl.dw[0] = PCICFG1_READ(&pnob->fn_obj, host_timer_int_ctrl);
- host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR,
- hostintr, ctrl.dw);
- if (!host_intr) {
- AMAP_SET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR,
- hostintr, ctrl.dw, 1);
- PCICFG1_WRITE(&pnob->fn_obj, host_timer_int_ctrl,
- ctrl.dw[0]);
- }
-}
-
-/*
- This function disables the interrupt from the network function of
- the BladeEngine. Use the function be_disable_eq_intr() to
- disable the interrupt from the event queue of only one specific NetObject
-*/
-void be_disable_intr(struct be_net_object *pnob)
-{
-
- struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl;
- u32 host_intr;
- ctrl.dw[0] = PCICFG1_READ(&pnob->fn_obj, host_timer_int_ctrl);
- host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR,
- hostintr, ctrl.dw);
- if (host_intr) {
- AMAP_SET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, hostintr,
- ctrl.dw, 0);
- PCICFG1_WRITE(&pnob->fn_obj, host_timer_int_ctrl,
- ctrl.dw[0]);
- }
-}
-
-static int be_enable_msix(struct be_adapter *adapter)
-{
- int i, ret;
-
- if (!msix)
- return -1;
-
- for (i = 0; i < BE_MAX_REQ_MSIX_VECTORS; i++)
- adapter->msix_entries[i].entry = i;
-
- ret = pci_enable_msix(adapter->pdev, adapter->msix_entries,
- BE_MAX_REQ_MSIX_VECTORS);
-
- if (ret == 0)
- adapter->msix_enabled = 1;
- return ret;
-}
-
-static int be_register_isr(struct be_adapter *adapter,
- struct be_net_object *pnob)
-{
- struct net_device *netdev = pnob->netdev;
- int intx = 0, r;
-
- netdev->irq = adapter->pdev->irq;
- r = be_enable_msix(adapter);
-
- if (r == 0) {
- r = request_irq(adapter->msix_entries[0].vector,
- be_int, IRQF_SHARED, netdev->name, netdev);
- if (r) {
- printk(KERN_WARNING
- "MSIX Request IRQ failed - Errno %d\n", r);
- intx = 1;
- pci_disable_msix(adapter->pdev);
- adapter->msix_enabled = 0;
- }
- } else {
- intx = 1;
- }
-
- if (intx) {
- r = request_irq(netdev->irq, be_int, IRQF_SHARED,
- netdev->name, netdev);
- if (r) {
- printk(KERN_WARNING
- "INTx Request IRQ failed - Errno %d\n", r);
- return -1;
- }
- }
- adapter->isr_registered = 1;
- return 0;
-}
-
-static void be_unregister_isr(struct be_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdevp;
- if (adapter->isr_registered) {
- if (adapter->msix_enabled) {
- free_irq(adapter->msix_entries[0].vector, netdev);
- pci_disable_msix(adapter->pdev);
- adapter->msix_enabled = 0;
- } else {
- free_irq(netdev->irq, netdev);
- }
- adapter->isr_registered = 0;
- }
-}
-
-/*
- This function processes the Flush Completions that are issued by the
- ARM F/W, when a Recv Ring is destroyed. A flush completion is
- identified when a Rx COmpl descriptor has the tcpcksum and udpcksum
- set and the pktsize is 32. These completions are received on the
- Rx Completion Queue.
-*/
-static u32 be_process_rx_flush_cmpl(struct be_net_object *pnob)
-{
- struct ETH_RX_COMPL_AMAP *rxcp;
- unsigned int i = 0;
- while ((rxcp = be_get_rx_cmpl(pnob)) != NULL) {
- be_notify_cmpl(pnob, 1, pnob->rx_cq_id, 1);
- i++;
- }
- return i;
-}
-
-static void be_tx_q_clean(struct be_net_object *pnob)
-{
- while (atomic_read(&pnob->tx_q_used))
- process_one_tx_compl(pnob, tx_compl_lastwrb_idx_get(pnob));
-}
-
-static void be_rx_q_clean(struct be_net_object *pnob)
-{
- if (pnob->rx_ctxt) {
- int i;
- struct be_rx_page_info *rx_page_info;
- for (i = 0; i < pnob->rx_q_len; i++) {
- rx_page_info = &(pnob->rx_page_info[i]);
- if (!pnob->rx_pg_shared || rx_page_info->page_offset) {
- pci_unmap_page(pnob->adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- pnob->rx_buf_size,
- PCI_DMA_FROMDEVICE);
- }
- if (rx_page_info->page)
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- }
- pnob->rx_pg_info_hd = 0;
- }
-}
-
-static void be_destroy_netobj(struct be_net_object *pnob)
-{
- int status;
-
- if (pnob->tx_q_created) {
- status = be_eth_sq_destroy(&pnob->tx_q_obj);
- pnob->tx_q_created = 0;
- }
-
- if (pnob->rx_q_created) {
- status = be_eth_rq_destroy(&pnob->rx_q_obj);
- if (status != 0) {
- status = be_eth_rq_destroy_options(&pnob->rx_q_obj, 0,
- NULL, NULL);
- BUG_ON(status);
- }
- pnob->rx_q_created = 0;
- }
-
- be_process_rx_flush_cmpl(pnob);
-
- if (pnob->tx_cq_created) {
- status = be_cq_destroy(&pnob->tx_cq_obj);
- pnob->tx_cq_created = 0;
- }
-
- if (pnob->rx_cq_created) {
- status = be_cq_destroy(&pnob->rx_cq_obj);
- pnob->rx_cq_created = 0;
- }
-
- if (pnob->mcc_q_created) {
- status = be_mcc_ring_destroy(&pnob->mcc_q_obj);
- pnob->mcc_q_created = 0;
- }
- if (pnob->mcc_cq_created) {
- status = be_cq_destroy(&pnob->mcc_cq_obj);
- pnob->mcc_cq_created = 0;
- }
-
- if (pnob->event_q_created) {
- status = be_eq_destroy(&pnob->event_q_obj);
- pnob->event_q_created = 0;
- }
- be_function_cleanup(&pnob->fn_obj);
-}
-
-/*
- * free all resources associated with a pnob
- * Called at the time of module cleanup as well a any error during
- * module init. Some resources may be partially allocated in a NetObj.
- */
-static void netobject_cleanup(struct be_adapter *adapter,
- struct be_net_object *pnob)
-{
- struct net_device *netdev = adapter->netdevp;
-
- if (netif_running(netdev)) {
- netif_stop_queue(netdev);
- be_wait_nic_tx_cmplx_cmpl(pnob);
- be_disable_eq_intr(pnob);
- }
-
- be_unregister_isr(adapter);
-
- if (adapter->tasklet_started) {
- tasklet_kill(&(adapter->sts_handler));
- adapter->tasklet_started = 0;
- }
- if (pnob->fn_obj_created)
- be_disable_intr(pnob);
-
- if (adapter->dev_state != BE_DEV_STATE_NONE)
- unregister_netdev(netdev);
-
- if (pnob->fn_obj_created)
- be_destroy_netobj(pnob);
-
- adapter->net_obj = NULL;
- adapter->netdevp = NULL;
-
- be_rx_q_clean(pnob);
- if (pnob->rx_ctxt) {
- kfree(pnob->rx_page_info);
- kfree(pnob->rx_ctxt);
- }
-
- be_tx_q_clean(pnob);
- kfree(pnob->tx_ctxt);
-
- if (pnob->mcc_q)
- pci_free_consistent(adapter->pdev, pnob->mcc_q_size,
- pnob->mcc_q, pnob->mcc_q_bus);
-
- if (pnob->mcc_wrb_ctxt)
- free_pages((unsigned long)pnob->mcc_wrb_ctxt,
- get_order(pnob->mcc_wrb_ctxt_size));
-
- if (pnob->mcc_cq)
- pci_free_consistent(adapter->pdev, pnob->mcc_cq_size,
- pnob->mcc_cq, pnob->mcc_cq_bus);
-
- if (pnob->event_q)
- pci_free_consistent(adapter->pdev, pnob->event_q_size,
- pnob->event_q, pnob->event_q_bus);
-
- if (pnob->tx_cq)
- pci_free_consistent(adapter->pdev, pnob->tx_cq_size,
- pnob->tx_cq, pnob->tx_cq_bus);
-
- if (pnob->tx_q)
- pci_free_consistent(adapter->pdev, pnob->tx_q_size,
- pnob->tx_q, pnob->tx_q_bus);
-
- if (pnob->rx_q)
- pci_free_consistent(adapter->pdev, pnob->rx_q_size,
- pnob->rx_q, pnob->rx_q_bus);
-
- if (pnob->rx_cq)
- pci_free_consistent(adapter->pdev, pnob->rx_cq_size,
- pnob->rx_cq, pnob->rx_cq_bus);
-
-
- if (pnob->mb_ptr)
- pci_free_consistent(adapter->pdev, pnob->mb_size, pnob->mb_ptr,
- pnob->mb_bus);
-
- free_netdev(netdev);
-}
-
-
-static int be_nob_ring_alloc(struct be_adapter *adapter,
- struct be_net_object *pnob)
-{
- u32 size;
-
- /* Mail box rd; mailbox pointer needs to be 16 byte aligned */
- pnob->mb_size = sizeof(struct MCC_MAILBOX_AMAP) + 16;
- pnob->mb_ptr = pci_alloc_consistent(adapter->pdev, pnob->mb_size,
- &pnob->mb_bus);
- if (!pnob->mb_bus)
- return -1;
- memset(pnob->mb_ptr, 0, pnob->mb_size);
- pnob->mb_rd.va = PTR_ALIGN(pnob->mb_ptr, 16);
- pnob->mb_rd.pa = PTR_ALIGN(pnob->mb_bus, 16);
- pnob->mb_rd.length = sizeof(struct MCC_MAILBOX_AMAP);
- /*
- * Event queue
- */
- pnob->event_q_len = EVENT_Q_LEN;
- pnob->event_q_size = pnob->event_q_len * sizeof(struct EQ_ENTRY_AMAP);
- pnob->event_q = pci_alloc_consistent(adapter->pdev, pnob->event_q_size,
- &pnob->event_q_bus);
- if (!pnob->event_q_bus)
- return -1;
- memset(pnob->event_q, 0, pnob->event_q_size);
- /*
- * Eth TX queue
- */
- pnob->tx_q_len = ETH_TXQ_LEN;
- pnob->tx_q_port = 0;
- pnob->tx_q_size = pnob->tx_q_len * sizeof(struct ETH_WRB_AMAP);
- pnob->tx_q = pci_alloc_consistent(adapter->pdev, pnob->tx_q_size,
- &pnob->tx_q_bus);
- if (!pnob->tx_q_bus)
- return -1;
- memset(pnob->tx_q, 0, pnob->tx_q_size);
- /*
- * Eth TX Compl queue
- */
- pnob->txcq_len = ETH_TXCQ_LEN;
- pnob->tx_cq_size = pnob->txcq_len * sizeof(struct ETH_TX_COMPL_AMAP);
- pnob->tx_cq = pci_alloc_consistent(adapter->pdev, pnob->tx_cq_size,
- &pnob->tx_cq_bus);
- if (!pnob->tx_cq_bus)
- return -1;
- memset(pnob->tx_cq, 0, pnob->tx_cq_size);
- /*
- * Eth RX queue
- */
- pnob->rx_q_len = ETH_RXQ_LEN;
- pnob->rx_q_size = pnob->rx_q_len * sizeof(struct ETH_RX_D_AMAP);
- pnob->rx_q = pci_alloc_consistent(adapter->pdev, pnob->rx_q_size,
- &pnob->rx_q_bus);
- if (!pnob->rx_q_bus)
- return -1;
- memset(pnob->rx_q, 0, pnob->rx_q_size);
- /*
- * Eth Unicast RX Compl queue
- */
- pnob->rx_cq_len = ETH_UC_RXCQ_LEN;
- pnob->rx_cq_size = pnob->rx_cq_len *
- sizeof(struct ETH_RX_COMPL_AMAP);
- pnob->rx_cq = pci_alloc_consistent(adapter->pdev, pnob->rx_cq_size,
- &pnob->rx_cq_bus);
- if (!pnob->rx_cq_bus)
- return -1;
- memset(pnob->rx_cq, 0, pnob->rx_cq_size);
-
- /* TX resources */
- size = pnob->tx_q_len * sizeof(void **);
- pnob->tx_ctxt = kzalloc(size, GFP_KERNEL);
- if (pnob->tx_ctxt == NULL)
- return -1;
-
- /* RX resources */
- size = pnob->rx_q_len * sizeof(void *);
- pnob->rx_ctxt = kzalloc(size, GFP_KERNEL);
- if (pnob->rx_ctxt == NULL)
- return -1;
-
- size = (pnob->rx_q_len * sizeof(struct be_rx_page_info));
- pnob->rx_page_info = kzalloc(size, GFP_KERNEL);
- if (pnob->rx_page_info == NULL)
- return -1;
-
- adapter->eth_statsp = kzalloc(sizeof(struct FWCMD_ETH_GET_STATISTICS),
- GFP_KERNEL);
- if (adapter->eth_statsp == NULL)
- return -1;
- pnob->rx_buf_size = rxbuf_size;
- return 0;
-}
-
-/*
- This function initializes the be_net_object for subsequent
- network operations.
-
- Before calling this function, the driver must have allocated
- space for the NetObject structure, initialized the structure,
- allocated DMAable memory for all the network queues that form
- part of the NetObject and populated the start address (virtual)
- and number of entries allocated for each queue in the NetObject structure.
-
- The driver must also have allocated memory to hold the
- mailbox structure (MCC_MAILBOX) and post the physical address,
- virtual addresses and the size of the mailbox memory in the
- NetObj.mb_rd. This structure is used by BECLIB for
- initial communication with the embedded MCC processor. BECLIB
- uses the mailbox until MCC rings are created for more efficient
- communication with the MCC processor.
-
- If the driver wants to create multiple network interface for more
- than one protection domain, it can call be_create_netobj()
- multiple times once for each protection domain. A Maximum of
- 32 protection domains are supported.
-
-*/
-static int
-be_create_netobj(struct be_net_object *pnob, u8 __iomem *csr_va,
- u8 __iomem *db_va, u8 __iomem *pci_va)
-{
- int status = 0;
- bool eventable = false, tx_no_delay = false, rx_no_delay = false;
- struct be_eq_object *eq_objectp = NULL;
- struct be_function_object *pfob = &pnob->fn_obj;
- struct ring_desc rd;
- u32 set_rxbuf_size;
- u32 tx_cmpl_wm = CEV_WMARK_96; /* 0xffffffff to disable */
- u32 rx_cmpl_wm = CEV_WMARK_160; /* 0xffffffff to disable */
- u32 eq_delay = 0; /* delay in 8usec units. 0xffffffff to disable */
-
- memset(&rd, 0, sizeof(struct ring_desc));
-
- status = be_function_object_create(csr_va, db_va, pci_va,
- BE_FUNCTION_TYPE_NETWORK, &pnob->mb_rd, pfob);
- if (status != BE_SUCCESS)
- return status;
- pnob->fn_obj_created = true;
-
- if (tx_cmpl_wm == 0xffffffff)
- tx_no_delay = true;
- if (rx_cmpl_wm == 0xffffffff)
- rx_no_delay = true;
- /*
- * now create the necessary rings
- * Event Queue first.
- */
- if (pnob->event_q_len) {
- rd.va = pnob->event_q;
- rd.pa = pnob->event_q_bus;
- rd.length = pnob->event_q_size;
-
- status = be_eq_create(pfob, &rd, 4, pnob->event_q_len,
- (u32) -1, /* CEV_WMARK_* or -1 */
- eq_delay, /* in 8us units, or -1 */
- &pnob->event_q_obj);
- if (status != BE_SUCCESS)
- goto error_ret;
- pnob->event_q_id = pnob->event_q_obj.eq_id;
- pnob->event_q_created = 1;
- eventable = true;
- eq_objectp = &pnob->event_q_obj;
- }
- /*
- * Now Eth Tx Compl. queue.
- */
- if (pnob->txcq_len) {
- rd.va = pnob->tx_cq;
- rd.pa = pnob->tx_cq_bus;
- rd.length = pnob->tx_cq_size;
-
- status = be_cq_create(pfob, &rd,
- pnob->txcq_len * sizeof(struct ETH_TX_COMPL_AMAP),
- false, /* solicted events, */
- tx_no_delay, /* nodelay */
- tx_cmpl_wm, /* Watermark encodings */
- eq_objectp, &pnob->tx_cq_obj);
- if (status != BE_SUCCESS)
- goto error_ret;
-
- pnob->tx_cq_id = pnob->tx_cq_obj.cq_id;
- pnob->tx_cq_created = 1;
- }
- /*
- * Eth Tx queue
- */
- if (pnob->tx_q_len) {
- struct be_eth_sq_parameters ex_params = { 0 };
- u32 type;
-
- if (pnob->tx_q_port) {
- /* TXQ to be bound to a specific port */
- type = BE_ETH_TX_RING_TYPE_BOUND;
- ex_params.port = pnob->tx_q_port - 1;
- } else
- type = BE_ETH_TX_RING_TYPE_STANDARD;
-
- rd.va = pnob->tx_q;
- rd.pa = pnob->tx_q_bus;
- rd.length = pnob->tx_q_size;
-
- status = be_eth_sq_create_ex(pfob, &rd,
- pnob->tx_q_len * sizeof(struct ETH_WRB_AMAP),
- type, 2, &pnob->tx_cq_obj,
- &ex_params, &pnob->tx_q_obj);
-
- if (status != BE_SUCCESS)
- goto error_ret;
-
- pnob->tx_q_id = pnob->tx_q_obj.bid;
- pnob->tx_q_created = 1;
- }
- /*
- * Now Eth Rx compl. queue. Always needed.
- */
- rd.va = pnob->rx_cq;
- rd.pa = pnob->rx_cq_bus;
- rd.length = pnob->rx_cq_size;
-
- status = be_cq_create(pfob, &rd,
- pnob->rx_cq_len * sizeof(struct ETH_RX_COMPL_AMAP),
- false, /* solicted events, */
- rx_no_delay, /* nodelay */
- rx_cmpl_wm, /* Watermark encodings */
- eq_objectp, &pnob->rx_cq_obj);
- if (status != BE_SUCCESS)
- goto error_ret;
-
- pnob->rx_cq_id = pnob->rx_cq_obj.cq_id;
- pnob->rx_cq_created = 1;
-
- status = be_eth_rq_set_frag_size(pfob, pnob->rx_buf_size,
- (u32 *) &set_rxbuf_size);
- if (status != BE_SUCCESS) {
- be_eth_rq_get_frag_size(pfob, (u32 *) &pnob->rx_buf_size);
- if ((pnob->rx_buf_size != 2048) && (pnob->rx_buf_size != 4096)
- && (pnob->rx_buf_size != 8192))
- goto error_ret;
- } else {
- if (pnob->rx_buf_size != set_rxbuf_size)
- pnob->rx_buf_size = set_rxbuf_size;
- }
- /*
- * Eth RX queue. be_eth_rq_create() always assumes 2 pages size
- */
- rd.va = pnob->rx_q;
- rd.pa = pnob->rx_q_bus;
- rd.length = pnob->rx_q_size;
-
- status = be_eth_rq_create(pfob, &rd, &pnob->rx_cq_obj,
- &pnob->rx_cq_obj, &pnob->rx_q_obj);
-
- if (status != BE_SUCCESS)
- goto error_ret;
-
- pnob->rx_q_id = pnob->rx_q_obj.rid;
- pnob->rx_q_created = 1;
-
- return BE_SUCCESS; /* All required queues created. */
-
-error_ret:
- be_destroy_netobj(pnob);
- return status;
-}
-
-static int be_nob_ring_init(struct be_adapter *adapter,
- struct be_net_object *pnob)
-{
- int status;
-
- pnob->event_q_tl = 0;
-
- pnob->tx_q_hd = 0;
- pnob->tx_q_tl = 0;
-
- pnob->tx_cq_tl = 0;
-
- pnob->rx_cq_tl = 0;
-
- memset(pnob->event_q, 0, pnob->event_q_size);
- memset(pnob->tx_cq, 0, pnob->tx_cq_size);
- memset(pnob->tx_ctxt, 0, pnob->tx_q_len * sizeof(void **));
- memset(pnob->rx_ctxt, 0, pnob->rx_q_len * sizeof(void *));
- pnob->rx_pg_info_hd = 0;
- pnob->rx_q_hd = 0;
- atomic_set(&pnob->rx_q_posted, 0);
-
- status = be_create_netobj(pnob, adapter->csr_va, adapter->db_va,
- adapter->pci_va);
- if (status != BE_SUCCESS)
- return -1;
-
- be_post_eth_rx_buffs(pnob);
- return 0;
-}
-
-/* This function handles async callback for link status */
-static void
-be_link_status_async_callback(void *context, u32 event_code, void *event)
-{
- struct ASYNC_EVENT_LINK_STATE_AMAP *link_status = event;
- struct be_adapter *adapter = context;
- bool link_enable = false;
- struct be_net_object *pnob;
- struct ASYNC_EVENT_TRAILER_AMAP *async_trailer;
- struct net_device *netdev;
- u32 async_event_code, async_event_type, active_port;
- u32 port0_link_status, port1_link_status, port0_duplex, port1_duplex;
- u32 port0_speed, port1_speed;
-
- if (event_code != ASYNC_EVENT_CODE_LINK_STATE) {
- /* Not our event to handle */
- return;
- }
- async_trailer = (struct ASYNC_EVENT_TRAILER_AMAP *)
- ((u8 *) event + sizeof(struct MCC_CQ_ENTRY_AMAP) -
- sizeof(struct ASYNC_EVENT_TRAILER_AMAP));
-
- async_event_code = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, event_code,
- async_trailer);
- BUG_ON(async_event_code != ASYNC_EVENT_CODE_LINK_STATE);
-
- pnob = adapter->net_obj;
- netdev = pnob->netdev;
-
- /* Determine if this event is a switch VLD or a physical link event */
- async_event_type = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, event_type,
- async_trailer);
- active_port = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- active_port, link_status);
- port0_link_status = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port0_link_status, link_status);
- port1_link_status = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port1_link_status, link_status);
- port0_duplex = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port0_duplex, link_status);
- port1_duplex = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port1_duplex, link_status);
- port0_speed = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port0_speed, link_status);
- port1_speed = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port1_speed, link_status);
- if (async_event_type == NTWK_LINK_TYPE_VIRTUAL) {
- adapter->be_stat.bes_link_change_virtual++;
- if (adapter->be_link_sts->active_port != active_port) {
- dev_notice(&netdev->dev,
- "Active port changed due to VLD on switch\n");
- } else {
- dev_notice(&netdev->dev, "Link status update\n");
- }
-
- } else {
- adapter->be_stat.bes_link_change_physical++;
- if (adapter->be_link_sts->active_port != active_port) {
- dev_notice(&netdev->dev,
- "Active port changed due to port link"
- " status change\n");
- } else {
- dev_notice(&netdev->dev, "Link status update\n");
- }
- }
-
- memset(adapter->be_link_sts, 0, sizeof(adapter->be_link_sts));
-
- if ((port0_link_status == ASYNC_EVENT_LINK_UP) ||
- (port1_link_status == ASYNC_EVENT_LINK_UP)) {
- if ((adapter->port0_link_sts == BE_PORT_LINK_DOWN) &&
- (adapter->port1_link_sts == BE_PORT_LINK_DOWN)) {
- /* Earlier both the ports are down So link is up */
- link_enable = true;
- }
-
- if (port0_link_status == ASYNC_EVENT_LINK_UP) {
- adapter->port0_link_sts = BE_PORT_LINK_UP;
- adapter->be_link_sts->mac0_duplex = port0_duplex;
- adapter->be_link_sts->mac0_speed = port0_speed;
- if (active_port == NTWK_PORT_A)
- adapter->be_link_sts->active_port = 0;
- } else
- adapter->port0_link_sts = BE_PORT_LINK_DOWN;
-
- if (port1_link_status == ASYNC_EVENT_LINK_UP) {
- adapter->port1_link_sts = BE_PORT_LINK_UP;
- adapter->be_link_sts->mac1_duplex = port1_duplex;
- adapter->be_link_sts->mac1_speed = port1_speed;
- if (active_port == NTWK_PORT_B)
- adapter->be_link_sts->active_port = 1;
- } else
- adapter->port1_link_sts = BE_PORT_LINK_DOWN;
-
- printk(KERN_INFO "Link Properties for %s:\n", netdev->name);
- dev_info(&netdev->dev, "Link Properties:\n");
- be_print_link_info(adapter->be_link_sts);
-
- if (!link_enable)
- return;
- /*
- * Both ports were down previously, but atleast one of
- * them has come up if this netdevice's carrier is not up,
- * then indicate to stack
- */
- if (!netif_carrier_ok(netdev)) {
- netif_start_queue(netdev);
- netif_carrier_on(netdev);
- }
- return;
- }
-
- /* Now both the ports are down. Tell the stack about it */
- dev_info(&netdev->dev, "Both ports are down\n");
- adapter->port0_link_sts = BE_PORT_LINK_DOWN;
- adapter->port1_link_sts = BE_PORT_LINK_DOWN;
- if (netif_carrier_ok(netdev)) {
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- }
- return;
-}
-
-static int be_mcc_create(struct be_adapter *adapter)
-{
- struct be_net_object *pnob;
-
- pnob = adapter->net_obj;
- /*
- * Create the MCC ring so that all further communication with
- * MCC can go thru the ring. we do this at the end since
- * we do not want to be dealing with interrupts until the
- * initialization is complete.
- */
- pnob->mcc_q_len = MCC_Q_LEN;
- pnob->mcc_q_size = pnob->mcc_q_len * sizeof(struct MCC_WRB_AMAP);
- pnob->mcc_q = pci_alloc_consistent(adapter->pdev, pnob->mcc_q_size,
- &pnob->mcc_q_bus);
- if (!pnob->mcc_q_bus)
- return -1;
- /*
- * space for MCC WRB context
- */
- pnob->mcc_wrb_ctxtLen = MCC_Q_LEN;
- pnob->mcc_wrb_ctxt_size = pnob->mcc_wrb_ctxtLen *
- sizeof(struct be_mcc_wrb_context);
- pnob->mcc_wrb_ctxt = (void *)__get_free_pages(GFP_KERNEL,
- get_order(pnob->mcc_wrb_ctxt_size));
- if (pnob->mcc_wrb_ctxt == NULL)
- return -1;
- /*
- * Space for MCC compl. ring
- */
- pnob->mcc_cq_len = MCC_CQ_LEN;
- pnob->mcc_cq_size = pnob->mcc_cq_len * sizeof(struct MCC_CQ_ENTRY_AMAP);
- pnob->mcc_cq = pci_alloc_consistent(adapter->pdev, pnob->mcc_cq_size,
- &pnob->mcc_cq_bus);
- if (!pnob->mcc_cq_bus)
- return -1;
- return 0;
-}
-
-/*
- This function creates the MCC request and completion ring required
- for communicating with the ARM processor. The caller must have
- allocated required amount of memory for the MCC ring and MCC
- completion ring and posted the virtual address and number of
- entries in the corresponding members (mcc_q and mcc_cq) in the
- NetObject struture.
-
- When this call is completed, all further communication with
- ARM will switch from mailbox to this ring.
-
- pnob - Pointer to the NetObject structure. This NetObject should
- have been created using a previous call to be_create_netobj()
-*/
-int be_create_mcc_rings(struct be_net_object *pnob)
-{
- int status = 0;
- struct ring_desc rd;
- struct be_function_object *pfob = &pnob->fn_obj;
-
- memset(&rd, 0, sizeof(struct ring_desc));
- if (pnob->mcc_cq_len) {
- rd.va = pnob->mcc_cq;
- rd.pa = pnob->mcc_cq_bus;
- rd.length = pnob->mcc_cq_size;
-
- status = be_cq_create(pfob, &rd,
- pnob->mcc_cq_len * sizeof(struct MCC_CQ_ENTRY_AMAP),
- false, /* solicted events, */
- true, /* nodelay */
- 0, /* 0 Watermark since Nodelay is true */
- &pnob->event_q_obj,
- &pnob->mcc_cq_obj);
-
- if (status != BE_SUCCESS)
- return status;
-
- pnob->mcc_cq_id = pnob->mcc_cq_obj.cq_id;
- pnob->mcc_cq_created = 1;
- }
- if (pnob->mcc_q_len) {
- rd.va = pnob->mcc_q;
- rd.pa = pnob->mcc_q_bus;
- rd.length = pnob->mcc_q_size;
-
- status = be_mcc_ring_create(pfob, &rd,
- pnob->mcc_q_len * sizeof(struct MCC_WRB_AMAP),
- pnob->mcc_wrb_ctxt, pnob->mcc_wrb_ctxtLen,
- &pnob->mcc_cq_obj, &pnob->mcc_q_obj);
-
- if (status != BE_SUCCESS)
- return status;
-
- pnob->mcc_q_created = 1;
- }
- return BE_SUCCESS;
-}
-
-static int be_mcc_init(struct be_adapter *adapter)
-{
- u32 r;
- struct be_net_object *pnob;
-
- pnob = adapter->net_obj;
- memset(pnob->mcc_q, 0, pnob->mcc_q_size);
- pnob->mcc_q_hd = 0;
-
- memset(pnob->mcc_wrb_ctxt, 0, pnob->mcc_wrb_ctxt_size);
-
- memset(pnob->mcc_cq, 0, pnob->mcc_cq_size);
- pnob->mcc_cq_tl = 0;
-
- r = be_create_mcc_rings(adapter->net_obj);
- if (r != BE_SUCCESS)
- return -1;
-
- return 0;
-}
-
-static void be_remove(struct pci_dev *pdev)
-{
- struct be_net_object *pnob;
- struct be_adapter *adapter;
-
- adapter = pci_get_drvdata(pdev);
- if (!adapter)
- return;
-
- pci_set_drvdata(pdev, NULL);
- pnob = (struct be_net_object *)adapter->net_obj;
-
- flush_scheduled_work();
-
- if (pnob) {
- /* Unregister async callback function for link status updates */
- if (pnob->mcc_q_created)
- be_mcc_add_async_event_callback(&pnob->mcc_q_obj,
- NULL, NULL);
- netobject_cleanup(adapter, pnob);
- }
-
- if (adapter->csr_va)
- iounmap(adapter->csr_va);
- if (adapter->db_va)
- iounmap(adapter->db_va);
- if (adapter->pci_va)
- iounmap(adapter->pci_va);
-
- pci_release_regions(adapter->pdev);
- pci_disable_device(adapter->pdev);
-
- kfree(adapter->be_link_sts);
- kfree(adapter->eth_statsp);
-
- if (adapter->timer_ctxt.get_stats_timer.function)
- del_timer_sync(&adapter->timer_ctxt.get_stats_timer);
- kfree(adapter);
-}
-
-/*
- * This function is called by the PCI sub-system when it finds a PCI
- * device with dev/vendor IDs that match with one of our devices.
- * All of the driver initialization is done in this function.
- */
-static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
-{
- int status = 0;
- struct be_adapter *adapter;
- struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD get_fwv;
- struct be_net_object *pnob;
- struct net_device *netdev;
-
- status = pci_enable_device(pdev);
- if (status)
- goto error;
-
- status = pci_request_regions(pdev, be_driver_name);
- if (status)
- goto error_pci_req;
-
- pci_set_master(pdev);
- adapter = kzalloc(sizeof(struct be_adapter), GFP_KERNEL);
- if (adapter == NULL) {
- status = -ENOMEM;
- goto error_adapter;
- }
- adapter->dev_state = BE_DEV_STATE_NONE;
- adapter->pdev = pdev;
- pci_set_drvdata(pdev, adapter);
-
- adapter->enable_aic = 1;
- adapter->max_eqd = MAX_EQD;
- adapter->min_eqd = 0;
- adapter->cur_eqd = 0;
-
- status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
- if (!status) {
- adapter->dma_64bit_cap = true;
- } else {
- adapter->dma_64bit_cap = false;
- status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (status != 0) {
- printk(KERN_ERR "Could not set PCI DMA Mask\n");
- goto cleanup;
- }
- }
-
- status = init_pci_be_function(adapter, pdev);
- if (status != 0) {
- printk(KERN_ERR "Failed to map PCI BARS\n");
- status = -ENOMEM;
- goto cleanup;
- }
-
- be_trace_set_level(DL_ALWAYS | DL_ERR);
-
- adapter->be_link_sts = kmalloc(sizeof(struct BE_LINK_STATUS),
- GFP_KERNEL);
- if (adapter->be_link_sts == NULL) {
- printk(KERN_ERR "Memory allocation for link status "
- "buffer failed\n");
- goto cleanup;
- }
- spin_lock_init(&adapter->txq_lock);
-
- netdev = alloc_etherdev(sizeof(struct be_net_object));
- if (netdev == NULL) {
- status = -ENOMEM;
- goto cleanup;
- }
- pnob = netdev_priv(netdev);
- adapter->net_obj = pnob;
- adapter->netdevp = netdev;
- pnob->adapter = adapter;
- pnob->netdev = netdev;
-
- status = be_nob_ring_alloc(adapter, pnob);
- if (status != 0)
- goto cleanup;
-
- status = be_nob_ring_init(adapter, pnob);
- if (status != 0)
- goto cleanup;
-
- be_rxf_mac_address_read_write(&pnob->fn_obj, false, false, false,
- false, false, netdev->dev_addr, NULL, NULL);
-
- netdev->init = &benet_init;
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
- SET_NETDEV_DEV(netdev, &(adapter->pdev->dev));
-
- netif_napi_add(netdev, &pnob->napi, be_poll, 64);
-
- /* if the rx_frag size if 2K, one page is shared as two RX frags */
- pnob->rx_pg_shared =
- (pnob->rx_buf_size <= PAGE_SIZE / 2) ? true : false;
- if (pnob->rx_buf_size != rxbuf_size) {
- printk(KERN_WARNING
- "Could not set Rx buffer size to %d. Using %d\n",
- rxbuf_size, pnob->rx_buf_size);
- rxbuf_size = pnob->rx_buf_size;
- }
-
- tasklet_init(&(adapter->sts_handler), be_process_intr,
- (unsigned long)adapter);
- adapter->tasklet_started = 1;
- spin_lock_init(&(adapter->int_lock));
-
- status = be_register_isr(adapter, pnob);
- if (status != 0)
- goto cleanup;
-
- adapter->rx_csum = 1;
- adapter->max_rx_coal = BE_LRO_MAX_PKTS;
-
- memset(&get_fwv, 0,
- sizeof(struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD));
- printk(KERN_INFO "BladeEngine Driver version:%s. "
- "Copyright ServerEngines, Corporation 2005 - 2008\n",
- be_drvr_ver);
- status = be_function_get_fw_version(&pnob->fn_obj, &get_fwv, NULL,
- NULL);
- if (status == BE_SUCCESS) {
- strncpy(be_fw_ver, get_fwv.firmware_version_string, 32);
- printk(KERN_INFO "BladeEngine Firmware Version:%s\n",
- get_fwv.firmware_version_string);
- } else {
- printk(KERN_WARNING "Unable to get BE Firmware Version\n");
- }
-
- sema_init(&adapter->get_eth_stat_sem, 0);
- init_timer(&adapter->timer_ctxt.get_stats_timer);
- atomic_set(&adapter->timer_ctxt.get_stat_flag, 0);
- adapter->timer_ctxt.get_stats_timer.function =
- &be_get_stats_timer_handler;
-
- status = be_mcc_create(adapter);
- if (status < 0)
- goto cleanup;
- status = be_mcc_init(adapter);
- if (status < 0)
- goto cleanup;
-
-
- status = be_mcc_add_async_event_callback(&adapter->net_obj->mcc_q_obj,
- be_link_status_async_callback, (void *)adapter);
- if (status != BE_SUCCESS) {
- printk(KERN_WARNING "add_async_event_callback failed");
- printk(KERN_WARNING
- "Link status changes may not be reflected\n");
- }
-
- status = register_netdev(netdev);
- if (status != 0)
- goto cleanup;
- be_update_link_status(adapter);
- adapter->dev_state = BE_DEV_STATE_INIT;
- return 0;
-
-cleanup:
- be_remove(pdev);
- return status;
-error_adapter:
- pci_release_regions(pdev);
-error_pci_req:
- pci_disable_device(pdev);
-error:
- printk(KERN_ERR "BladeEngine initalization failed\n");
- return status;
-}
-
-/*
- * Get the current link status and print the status on console
- */
-void be_update_link_status(struct be_adapter *adapter)
-{
- int status;
- struct be_net_object *pnob = adapter->net_obj;
-
- status = be_rxf_link_status(&pnob->fn_obj, adapter->be_link_sts, NULL,
- NULL, NULL);
- if (status == BE_SUCCESS) {
- if (adapter->be_link_sts->mac0_speed &&
- adapter->be_link_sts->mac0_duplex)
- adapter->port0_link_sts = BE_PORT_LINK_UP;
- else
- adapter->port0_link_sts = BE_PORT_LINK_DOWN;
-
- if (adapter->be_link_sts->mac1_speed &&
- adapter->be_link_sts->mac1_duplex)
- adapter->port1_link_sts = BE_PORT_LINK_UP;
- else
- adapter->port1_link_sts = BE_PORT_LINK_DOWN;
-
- dev_info(&pnob->netdev->dev, "Link Properties:\n");
- be_print_link_info(adapter->be_link_sts);
- return;
- }
- dev_info(&pnob->netdev->dev, "Could not get link status\n");
- return;
-}
-
-
-#ifdef CONFIG_PM
-static void
-be_pm_cleanup(struct be_adapter *adapter,
- struct be_net_object *pnob, struct net_device *netdev)
-{
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
- be_wait_nic_tx_cmplx_cmpl(pnob);
- be_disable_eq_intr(pnob);
-
- if (adapter->tasklet_started) {
- tasklet_kill(&adapter->sts_handler);
- adapter->tasklet_started = 0;
- }
-
- be_unregister_isr(adapter);
- be_disable_intr(pnob);
-
- be_tx_q_clean(pnob);
- be_rx_q_clean(pnob);
-
- be_destroy_netobj(pnob);
-}
-
-static int be_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct be_adapter *adapter = pci_get_drvdata(pdev);
- struct net_device *netdev = adapter->netdevp;
- struct be_net_object *pnob = netdev_priv(netdev);
-
- adapter->dev_pm_state = adapter->dev_state;
- adapter->dev_state = BE_DEV_STATE_SUSPEND;
-
- netif_device_detach(netdev);
- if (netif_running(netdev))
- be_pm_cleanup(adapter, pnob, netdev);
-
- pci_enable_wake(pdev, 3, 1);
- pci_enable_wake(pdev, 4, 1); /* D3 Cold = 4 */
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
-}
-
-static void be_up(struct be_adapter *adapter)
-{
- struct be_net_object *pnob = adapter->net_obj;
-
- if (pnob->num_vlans != 0)
- be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans,
- pnob->vlan_tag, NULL, NULL, NULL);
-
-}
-
-static int be_resume(struct pci_dev *pdev)
-{
- int status = 0;
- struct be_adapter *adapter = pci_get_drvdata(pdev);
- struct net_device *netdev = adapter->netdevp;
- struct be_net_object *pnob = netdev_priv(netdev);
-
- netif_device_detach(netdev);
-
- status = pci_enable_device(pdev);
- if (status)
- return status;
-
- pci_set_power_state(pdev, 0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, 3, 0);
- pci_enable_wake(pdev, 4, 0); /* 4 is D3 cold */
-
- netif_carrier_on(netdev);
- netif_start_queue(netdev);
-
- if (netif_running(netdev)) {
- be_rxf_mac_address_read_write(&pnob->fn_obj, false, false,
- false, true, false, netdev->dev_addr, NULL, NULL);
-
- status = be_nob_ring_init(adapter, pnob);
- if (status < 0)
- return status;
-
- tasklet_init(&(adapter->sts_handler), be_process_intr,
- (unsigned long)adapter);
- adapter->tasklet_started = 1;
-
- if (be_register_isr(adapter, pnob) != 0) {
- printk(KERN_ERR "be_register_isr failed\n");
- return status;
- }
-
-
- status = be_mcc_init(adapter);
- if (status < 0) {
- printk(KERN_ERR "be_mcc_init failed\n");
- return status;
- }
- be_update_link_status(adapter);
- /*
- * Register async call back function to handle link
- * status updates
- */
- status = be_mcc_add_async_event_callback(
- &adapter->net_obj->mcc_q_obj,
- be_link_status_async_callback, (void *)adapter);
- if (status != BE_SUCCESS) {
- printk(KERN_WARNING "add_async_event_callback failed");
- printk(KERN_WARNING
- "Link status changes may not be reflected\n");
- }
- be_enable_intr(pnob);
- be_enable_eq_intr(pnob);
- be_up(adapter);
- }
- netif_device_attach(netdev);
- adapter->dev_state = adapter->dev_pm_state;
- return 0;
-
-}
-
-#endif
-
-/* Wait until no more pending transmits */
-void be_wait_nic_tx_cmplx_cmpl(struct be_net_object *pnob)
-{
- int i;
-
- /* Wait for 20us * 50000 (= 1s) and no more */
- i = 0;
- while ((pnob->tx_q_tl != pnob->tx_q_hd) && (i < 50000)) {
- ++i;
- udelay(20);
- }
-
- /* Check for no more pending transmits */
- if (i >= 50000) {
- printk(KERN_WARNING
- "Did not receive completions for all TX requests\n");
- }
-}
-
-static struct pci_driver be_driver = {
- .name = be_driver_name,
- .id_table = be_device_id_table,
- .probe = be_probe,
-#ifdef CONFIG_PM
- .suspend = be_suspend,
- .resume = be_resume,
-#endif
- .remove = be_remove
-};
-
-/*
- * Module init entry point. Registers our our device and return.
- * Our probe will be called if the device is found.
- */
-static int __init be_init_module(void)
-{
- int ret;
-
- if (rxbuf_size != 8192 && rxbuf_size != 4096 && rxbuf_size != 2048) {
- printk(KERN_WARNING
- "Unsupported receive buffer size (%d) requested\n",
- rxbuf_size);
- printk(KERN_WARNING
- "Must be 2048, 4096 or 8192. Defaulting to 2048\n");
- rxbuf_size = 2048;
- }
-
- ret = pci_register_driver(&be_driver);
-
- return ret;
-}
-
-module_init(be_init_module);
-
-/*
- * be_exit_module - Driver Exit Cleanup Routine
- */
-static void __exit be_exit_module(void)
-{
- pci_unregister_driver(&be_driver);
-}
-
-module_exit(be_exit_module);
diff --git a/drivers/staging/benet/be_int.c b/drivers/staging/benet/be_int.c
deleted file mode 100644
index cba95d09a8b..00000000000
--- a/drivers/staging/benet/be_int.c
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include <linux/if_vlan.h>
-#include <linux/inet_lro.h>
-
-#include "benet.h"
-
-/* number of bytes of RX frame that are copied to skb->data */
-#define BE_HDR_LEN 64
-
-#define NETIF_RX(skb) netif_receive_skb(skb)
-#define VLAN_ACCEL_RX(skb, pnob, vt) \
- vlan_hwaccel_rx(skb, pnob->vlan_grp, vt)
-
-/*
- This function notifies BladeEngine of the number of completion
- entries processed from the specified completion queue by writing
- the number of popped entries to the door bell.
-
- pnob - Pointer to the NetObject structure
- n - Number of completion entries processed
- cq_id - Queue ID of the completion queue for which notification
- is being done.
- re_arm - 1 - rearm the completion ring to generate an event.
- - 0 - dont rearm the completion ring to generate an event
-*/
-void be_notify_cmpl(struct be_net_object *pnob, int n, int cq_id, int re_arm)
-{
- struct CQ_DB_AMAP cqdb;
-
- cqdb.dw[0] = 0;
- AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, cq_id);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, re_arm);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, n);
- PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]);
-}
-
-/*
- * adds additional receive frags indicated by BE starting from given
- * frag index (fi) to specified skb's frag list
- */
-static void
-add_skb_frags(struct be_net_object *pnob, struct sk_buff *skb,
- u32 nresid, u32 fi)
-{
- struct be_adapter *adapter = pnob->adapter;
- u32 sk_frag_idx, n;
- struct be_rx_page_info *rx_page_info;
- u32 frag_sz = pnob->rx_buf_size;
-
- sk_frag_idx = skb_shinfo(skb)->nr_frags;
- while (nresid) {
- index_inc(&fi, pnob->rx_q_len);
-
- rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi];
- pnob->rx_ctxt[fi] = NULL;
- if ((rx_page_info->page_offset) ||
- (pnob->rx_pg_shared == false)) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- frag_sz, PCI_DMA_FROMDEVICE);
- }
-
- n = min(nresid, frag_sz);
- skb_shinfo(skb)->frags[sk_frag_idx].page = rx_page_info->page;
- skb_shinfo(skb)->frags[sk_frag_idx].page_offset
- = rx_page_info->page_offset;
- skb_shinfo(skb)->frags[sk_frag_idx].size = n;
-
- sk_frag_idx++;
- skb->len += n;
- skb->data_len += n;
- skb_shinfo(skb)->nr_frags++;
- nresid -= n;
-
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- atomic_dec(&pnob->rx_q_posted);
- }
-}
-
-/*
- * This function processes incoming nic packets over various Rx queues.
- * This function takes the adapter, the current Rx status descriptor
- * entry and the Rx completion queue ID as argument.
- */
-static inline int process_nic_rx_completion(struct be_net_object *pnob,
- struct ETH_RX_COMPL_AMAP *rxcp)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct sk_buff *skb;
- int udpcksm, tcpcksm;
- int n;
- u32 nresid, fi;
- u32 frag_sz = pnob->rx_buf_size;
- u8 *va;
- struct be_rx_page_info *rx_page_info;
- u32 numfrags, vtp, vtm, vlan_tag, pktsize;
-
- fi = AMAP_GET_BITS_PTR(ETH_RX_COMPL, fragndx, rxcp);
- BUG_ON(fi >= (int)pnob->rx_q_len);
- BUG_ON(fi < 0);
-
- rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi];
- BUG_ON(!rx_page_info->page);
- pnob->rx_ctxt[fi] = NULL;
-
- /*
- * If one page is used per fragment or if this is the second half of
- * of the page, unmap the page here
- */
- if ((rx_page_info->page_offset) || (pnob->rx_pg_shared == false)) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus), frag_sz,
- PCI_DMA_FROMDEVICE);
- }
-
- atomic_dec(&pnob->rx_q_posted);
- udpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, udpcksm, rxcp);
- tcpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, tcpcksm, rxcp);
- pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp);
- /*
- * get rid of RX flush completions first.
- */
- if ((tcpcksm) && (udpcksm) && (pktsize == 32)) {
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- return 0;
- }
- skb = netdev_alloc_skb(pnob->netdev, BE_HDR_LEN + NET_IP_ALIGN);
- if (skb == NULL) {
- dev_info(&pnob->netdev->dev, "alloc_skb() failed\n");
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- goto free_frags;
- }
- skb_reserve(skb, NET_IP_ALIGN);
-
- skb->dev = pnob->netdev;
-
- n = min(pktsize, frag_sz);
-
- va = page_address(rx_page_info->page) + rx_page_info->page_offset;
- prefetch(va);
-
- skb->len = n;
- skb->data_len = n;
- if (n <= BE_HDR_LEN) {
- memcpy(skb->data, va, n);
- put_page(rx_page_info->page);
- skb->data_len -= n;
- skb->tail += n;
- } else {
-
- /* Setup the SKB with page buffer information */
- skb_shinfo(skb)->frags[0].page = rx_page_info->page;
- skb_shinfo(skb)->nr_frags++;
-
- /* Copy the header into the skb_data */
- memcpy(skb->data, va, BE_HDR_LEN);
- skb_shinfo(skb)->frags[0].page_offset =
- rx_page_info->page_offset + BE_HDR_LEN;
- skb_shinfo(skb)->frags[0].size = n - BE_HDR_LEN;
- skb->data_len -= BE_HDR_LEN;
- skb->tail += BE_HDR_LEN;
- }
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- nresid = pktsize - n;
-
- skb->protocol = eth_type_trans(skb, pnob->netdev);
-
- if ((tcpcksm || udpcksm) && adapter->rx_csum)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb->ip_summed = CHECKSUM_NONE;
- /*
- * if we have more bytes left, the frame has been
- * given to us in multiple fragments. This happens
- * with Jumbo frames. Add the remaining fragments to
- * skb->frags[] array.
- */
- if (nresid)
- add_skb_frags(pnob, skb, nresid, fi);
-
- /* update the the true size of the skb. */
- skb->truesize = skb->len + sizeof(struct sk_buff);
-
- /*
- * If a 802.3 frame or 802.2 LLC frame
- * (i.e) contains length field in MAC Hdr
- * and frame len is greater than 64 bytes
- */
- if (((skb->protocol == ntohs(ETH_P_802_2)) ||
- (skb->protocol == ntohs(ETH_P_802_3)))
- && (pktsize > BE_HDR_LEN)) {
- /*
- * If the length given in Mac Hdr is less than frame size
- * Erraneous frame, Drop it
- */
- if ((ntohs(*(u16 *) (va + 12)) + ETH_HLEN) < pktsize) {
- /* Increment Non Ether type II frames dropped */
- adapter->be_stat.bes_802_3_dropped_frames++;
-
- kfree_skb(skb);
- return 0;
- }
- /*
- * else if the length given in Mac Hdr is greater than
- * frame size, should not be seeing this sort of frames
- * dump the pkt and pass to stack
- */
- else if ((ntohs(*(u16 *) (va + 12)) + ETH_HLEN) > pktsize) {
- /* Increment Non Ether type II frames malformed */
- adapter->be_stat.bes_802_3_malformed_frames++;
- }
- }
-
- vtp = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtp, rxcp);
- vtm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtm, rxcp);
- if (vtp && vtm) {
- /* Vlan tag present in pkt and BE found
- * that the tag matched an entry in VLAN table
- */
- if (!pnob->vlan_grp || pnob->num_vlans == 0) {
- /* But we have no VLANs configured.
- * This should never happen. Drop the packet.
- */
- dev_info(&pnob->netdev->dev,
- "BladeEngine: Unexpected vlan tagged packet\n");
- kfree_skb(skb);
- return 0;
- }
- /* pass the VLAN packet to stack */
- vlan_tag = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vlan_tag, rxcp);
- VLAN_ACCEL_RX(skb, pnob, be16_to_cpu(vlan_tag));
-
- } else {
- NETIF_RX(skb);
- }
- return 0;
-
-free_frags:
- /* free all frags associated with the current rxcp */
- numfrags = AMAP_GET_BITS_PTR(ETH_RX_COMPL, numfrags, rxcp);
- while (numfrags-- > 1) {
- index_inc(&fi, pnob->rx_q_len);
-
- rx_page_info = (struct be_rx_page_info *)
- pnob->rx_ctxt[fi];
- pnob->rx_ctxt[fi] = (void *)NULL;
- if (rx_page_info->page_offset || !pnob->rx_pg_shared) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- frag_sz, PCI_DMA_FROMDEVICE);
- }
-
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- atomic_dec(&pnob->rx_q_posted);
- }
- return -ENOMEM;
-}
-
-static void process_nic_rx_completion_lro(struct be_net_object *pnob,
- struct ETH_RX_COMPL_AMAP *rxcp)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME];
- unsigned int udpcksm, tcpcksm;
- u32 numfrags, vlanf, vtm, vlan_tag, nresid;
- u16 vlant;
- unsigned int fi, idx, n;
- struct be_rx_page_info *rx_page_info;
- u32 frag_sz = pnob->rx_buf_size, pktsize;
- bool rx_coal = (adapter->max_rx_coal <= 1) ? 0 : 1;
- u8 err, *va;
- __wsum csum = 0;
-
- if (AMAP_GET_BITS_PTR(ETH_RX_COMPL, ipsec, rxcp)) {
- /* Drop the pkt and move to the next completion. */
- adapter->be_stat.bes_rx_misc_pkts++;
- return;
- }
- err = AMAP_GET_BITS_PTR(ETH_RX_COMPL, err, rxcp);
- if (err || !rx_coal) {
- /* We won't coalesce Rx pkts if the err bit set.
- * take the path of normal completion processing */
- process_nic_rx_completion(pnob, rxcp);
- return;
- }
-
- fi = AMAP_GET_BITS_PTR(ETH_RX_COMPL, fragndx, rxcp);
- BUG_ON(fi >= (int)pnob->rx_q_len);
- BUG_ON(fi < 0);
- rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi];
- BUG_ON(!rx_page_info->page);
- pnob->rx_ctxt[fi] = (void *)NULL;
- /* If one page is used per fragment or if this is the
- * second half of the page, unmap the page here
- */
- if (rx_page_info->page_offset || !pnob->rx_pg_shared) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- frag_sz, PCI_DMA_FROMDEVICE);
- }
-
- numfrags = AMAP_GET_BITS_PTR(ETH_RX_COMPL, numfrags, rxcp);
- udpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, udpcksm, rxcp);
- tcpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, tcpcksm, rxcp);
- vlan_tag = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vlan_tag, rxcp);
- vlant = be16_to_cpu(vlan_tag);
- vlanf = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtp, rxcp);
- vtm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtm, rxcp);
- pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp);
-
- atomic_dec(&pnob->rx_q_posted);
-
- if (tcpcksm && udpcksm && pktsize == 32) {
- /* flush completion entries */
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- return;
- }
- /* Only one of udpcksum and tcpcksum can be set */
- BUG_ON(udpcksm && tcpcksm);
-
- /* jumbo frames could come in multiple fragments */
- BUG_ON(numfrags != ((pktsize + (frag_sz - 1)) / frag_sz));
- n = min(pktsize, frag_sz);
- nresid = pktsize - n; /* will be useful for jumbo pkts */
- idx = 0;
-
- va = page_address(rx_page_info->page) + rx_page_info->page_offset;
- prefetch(va);
- rx_frags[idx].page = rx_page_info->page;
- rx_frags[idx].page_offset = (rx_page_info->page_offset);
- rx_frags[idx].size = n;
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
-
- /* If we got multiple fragments, we have more data. */
- while (nresid) {
- idx++;
- index_inc(&fi, pnob->rx_q_len);
-
- rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi];
- pnob->rx_ctxt[fi] = (void *)NULL;
- if (rx_page_info->page_offset || !pnob->rx_pg_shared) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- frag_sz, PCI_DMA_FROMDEVICE);
- }
-
- n = min(nresid, frag_sz);
- rx_frags[idx].page = rx_page_info->page;
- rx_frags[idx].page_offset = (rx_page_info->page_offset);
- rx_frags[idx].size = n;
-
- nresid -= n;
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- atomic_dec(&pnob->rx_q_posted);
- }
-
- if (likely(!(vlanf && vtm))) {
- lro_receive_frags(&pnob->lro_mgr, rx_frags,
- pktsize, pktsize,
- (void *)(unsigned long)csum, csum);
- } else {
- /* Vlan tag present in pkt and BE found
- * that the tag matched an entry in VLAN table
- */
- if (unlikely(!pnob->vlan_grp || pnob->num_vlans == 0)) {
- /* But we have no VLANs configured.
- * This should never happen. Drop the packet.
- */
- dev_info(&pnob->netdev->dev,
- "BladeEngine: Unexpected vlan tagged packet\n");
- return;
- }
- /* pass the VLAN packet to stack */
- lro_vlan_hwaccel_receive_frags(&pnob->lro_mgr,
- rx_frags, pktsize, pktsize,
- pnob->vlan_grp, vlant,
- (void *)(unsigned long)csum,
- csum);
- }
-
- adapter->be_stat.bes_rx_coal++;
-}
-
-struct ETH_RX_COMPL_AMAP *be_get_rx_cmpl(struct be_net_object *pnob)
-{
- struct ETH_RX_COMPL_AMAP *rxcp = &pnob->rx_cq[pnob->rx_cq_tl];
- u32 valid, ct;
-
- valid = AMAP_GET_BITS_PTR(ETH_RX_COMPL, valid, rxcp);
- if (valid == 0)
- return NULL;
-
- ct = AMAP_GET_BITS_PTR(ETH_RX_COMPL, ct, rxcp);
- if (ct != 0) {
- /* Invalid chute #. treat as error */
- AMAP_SET_BITS_PTR(ETH_RX_COMPL, err, rxcp, 1);
- }
-
- be_adv_rxcq_tl(pnob);
- AMAP_SET_BITS_PTR(ETH_RX_COMPL, valid, rxcp, 0);
- return rxcp;
-}
-
-static void update_rx_rate(struct be_adapter *adapter)
-{
- /* update the rate once in two seconds */
- if ((jiffies - adapter->eth_rx_jiffies) > 2 * (HZ)) {
- u32 r;
- r = adapter->eth_rx_bytes /
- ((jiffies - adapter->eth_rx_jiffies) / (HZ));
- r = (r / 1000000); /* MB/Sec */
-
- /* Mega Bits/Sec */
- adapter->be_stat.bes_eth_rx_rate = (r * 8);
- adapter->eth_rx_jiffies = jiffies;
- adapter->eth_rx_bytes = 0;
- }
-}
-
-static int process_rx_completions(struct be_net_object *pnob, int max_work)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct ETH_RX_COMPL_AMAP *rxcp;
- u32 nc = 0;
- unsigned int pktsize;
-
- while (max_work && (rxcp = be_get_rx_cmpl(pnob))) {
- prefetch(rxcp);
- pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp);
- process_nic_rx_completion_lro(pnob, rxcp);
- adapter->eth_rx_bytes += pktsize;
- update_rx_rate(adapter);
- nc++;
- max_work--;
- adapter->be_stat.bes_rx_compl++;
- }
- if (likely(adapter->max_rx_coal > 1)) {
- adapter->be_stat.bes_rx_flush++;
- lro_flush_all(&pnob->lro_mgr);
- }
-
- /* Refill the queue */
- if (atomic_read(&pnob->rx_q_posted) < 900)
- be_post_eth_rx_buffs(pnob);
-
- return nc;
-}
-
-static struct ETH_TX_COMPL_AMAP *be_get_tx_cmpl(struct be_net_object *pnob)
-{
- struct ETH_TX_COMPL_AMAP *txcp = &pnob->tx_cq[pnob->tx_cq_tl];
- u32 valid;
-
- valid = AMAP_GET_BITS_PTR(ETH_TX_COMPL, valid, txcp);
- if (valid == 0)
- return NULL;
-
- AMAP_SET_BITS_PTR(ETH_TX_COMPL, valid, txcp, 0);
- be_adv_txcq_tl(pnob);
- return txcp;
-
-}
-
-void process_one_tx_compl(struct be_net_object *pnob, u32 end_idx)
-{
- struct be_adapter *adapter = pnob->adapter;
- int cur_index, tx_wrbs_completed = 0;
- struct sk_buff *skb;
- u64 busaddr, pa, pa_lo, pa_hi;
- struct ETH_WRB_AMAP *wrb;
- u32 frag_len, last_index, j;
-
- last_index = tx_compl_lastwrb_idx_get(pnob);
- BUG_ON(last_index != end_idx);
- pnob->tx_ctxt[pnob->tx_q_tl] = NULL;
- do {
- cur_index = pnob->tx_q_tl;
- wrb = &pnob->tx_q[cur_index];
- pa_hi = AMAP_GET_BITS_PTR(ETH_WRB, frag_pa_hi, wrb);
- pa_lo = AMAP_GET_BITS_PTR(ETH_WRB, frag_pa_lo, wrb);
- frag_len = AMAP_GET_BITS_PTR(ETH_WRB, frag_len, wrb);
- busaddr = (pa_hi << 32) | pa_lo;
- if (busaddr != 0) {
- pa = le64_to_cpu(busaddr);
- pci_unmap_single(adapter->pdev, pa,
- frag_len, PCI_DMA_TODEVICE);
- }
- if (cur_index == last_index) {
- skb = (struct sk_buff *)pnob->tx_ctxt[cur_index];
- BUG_ON(!skb);
- for (j = 0; j < skb_shinfo(skb)->nr_frags; j++) {
- struct skb_frag_struct *frag;
- frag = &skb_shinfo(skb)->frags[j];
- pci_unmap_page(adapter->pdev,
- (ulong) frag->page, frag->size,
- PCI_DMA_TODEVICE);
- }
- kfree_skb(skb);
- pnob->tx_ctxt[cur_index] = NULL;
- } else {
- BUG_ON(pnob->tx_ctxt[cur_index]);
- }
- tx_wrbs_completed++;
- be_adv_txq_tl(pnob);
- } while (cur_index != last_index);
- atomic_sub(tx_wrbs_completed, &pnob->tx_q_used);
-}
-
-/* there is no need to take an SMP lock here since currently
- * we have only one instance of the tasklet that does completion
- * processing.
- */
-static void process_nic_tx_completions(struct be_net_object *pnob)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct ETH_TX_COMPL_AMAP *txcp;
- struct net_device *netdev = pnob->netdev;
- u32 end_idx, num_processed = 0;
-
- adapter->be_stat.bes_tx_events++;
-
- while ((txcp = be_get_tx_cmpl(pnob))) {
- end_idx = AMAP_GET_BITS_PTR(ETH_TX_COMPL, wrb_index, txcp);
- process_one_tx_compl(pnob, end_idx);
- num_processed++;
- adapter->be_stat.bes_tx_compl++;
- }
- be_notify_cmpl(pnob, num_processed, pnob->tx_cq_id, 1);
- /*
- * We got Tx completions and have usable WRBs.
- * If the netdev's queue has been stopped
- * because we had run out of WRBs, wake it now.
- */
- spin_lock(&adapter->txq_lock);
- if (netif_queue_stopped(netdev)
- && atomic_read(&pnob->tx_q_used) < pnob->tx_q_len / 2) {
- netif_wake_queue(netdev);
- }
- spin_unlock(&adapter->txq_lock);
-}
-
-static u32 post_rx_buffs(struct be_net_object *pnob, struct list_head *rxbl)
-{
- u32 nposted = 0;
- struct ETH_RX_D_AMAP *rxd = NULL;
- struct be_recv_buffer *rxbp;
- void **rx_ctxp;
- struct RQ_DB_AMAP rqdb;
-
- rx_ctxp = pnob->rx_ctxt;
-
- while (!list_empty(rxbl) &&
- (rx_ctxp[pnob->rx_q_hd] == NULL) && nposted < 255) {
-
- rxbp = list_first_entry(rxbl, struct be_recv_buffer, rxb_list);
- list_del(&rxbp->rxb_list);
- rxd = pnob->rx_q + pnob->rx_q_hd;
- AMAP_SET_BITS_PTR(ETH_RX_D, fragpa_lo, rxd, rxbp->rxb_pa_lo);
- AMAP_SET_BITS_PTR(ETH_RX_D, fragpa_hi, rxd, rxbp->rxb_pa_hi);
-
- rx_ctxp[pnob->rx_q_hd] = rxbp->rxb_ctxt;
- be_adv_rxq_hd(pnob);
- nposted++;
- }
-
- if (nposted) {
- /* Now press the door bell to notify BladeEngine. */
- rqdb.dw[0] = 0;
- AMAP_SET_BITS_PTR(RQ_DB, numPosted, &rqdb, nposted);
- AMAP_SET_BITS_PTR(RQ_DB, rq, &rqdb, pnob->rx_q_id);
- PD_WRITE(&pnob->fn_obj, erx_rq_db, rqdb.dw[0]);
- }
- atomic_add(nposted, &pnob->rx_q_posted);
- return nposted;
-}
-
-void be_post_eth_rx_buffs(struct be_net_object *pnob)
-{
- struct be_adapter *adapter = pnob->adapter;
- u32 num_bufs, r;
- u64 busaddr = 0, tmp_pa;
- u32 max_bufs, pg_hd;
- u32 frag_size;
- struct be_recv_buffer *rxbp;
- struct list_head rxbl;
- struct be_rx_page_info *rx_page_info;
- struct page *page = NULL;
- u32 page_order = 0;
- gfp_t alloc_flags = GFP_ATOMIC;
-
- BUG_ON(!adapter);
-
- max_bufs = 64; /* should be even # <= 255. */
-
- frag_size = pnob->rx_buf_size;
- page_order = get_order(frag_size);
-
- if (frag_size == 8192)
- alloc_flags |= (gfp_t) __GFP_COMP;
- /*
- * Form a linked list of RECV_BUFFFER structure to be be posted.
- * We will post even number of buffer so that pages can be
- * shared.
- */
- INIT_LIST_HEAD(&rxbl);
-
- for (num_bufs = 0; num_bufs < max_bufs &&
- !pnob->rx_page_info[pnob->rx_pg_info_hd].page; ++num_bufs) {
-
- rxbp = &pnob->eth_rx_bufs[num_bufs];
- pg_hd = pnob->rx_pg_info_hd;
- rx_page_info = &pnob->rx_page_info[pg_hd];
-
- if (!page) {
- page = alloc_pages(alloc_flags, page_order);
- if (unlikely(page == NULL)) {
- adapter->be_stat.bes_ethrx_post_fail++;
- pnob->rxbuf_post_fail++;
- break;
- }
- pnob->rxbuf_post_fail = 0;
- busaddr = pci_map_page(adapter->pdev, page, 0,
- frag_size, PCI_DMA_FROMDEVICE);
- rx_page_info->page_offset = 0;
- rx_page_info->page = page;
- /*
- * If we are sharing a page among two skbs,
- * alloc a new one on the next iteration
- */
- if (pnob->rx_pg_shared == false)
- page = NULL;
- } else {
- get_page(page);
- rx_page_info->page_offset += frag_size;
- rx_page_info->page = page;
- /*
- * We are finished with the alloced page,
- * Alloc a new one on the next iteration
- */
- page = NULL;
- }
- rxbp->rxb_ctxt = (void *)rx_page_info;
- index_inc(&pnob->rx_pg_info_hd, pnob->rx_q_len);
-
- pci_unmap_addr_set(rx_page_info, bus, busaddr);
- tmp_pa = busaddr + rx_page_info->page_offset;
- rxbp->rxb_pa_lo = (tmp_pa & 0xFFFFFFFF);
- rxbp->rxb_pa_hi = (tmp_pa >> 32);
- rxbp->rxb_len = frag_size;
- list_add_tail(&rxbp->rxb_list, &rxbl);
- } /* End of for */
-
- r = post_rx_buffs(pnob, &rxbl);
- BUG_ON(r != num_bufs);
- return;
-}
-
-/*
- * Interrupt service for network function. We just schedule the
- * tasklet which does all completion processing.
- */
-irqreturn_t be_int(int irq, void *dev)
-{
- struct net_device *netdev = dev;
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- u32 isr;
-
- isr = CSR_READ(&pnob->fn_obj, cev.isr1);
- if (unlikely(!isr))
- return IRQ_NONE;
-
- spin_lock(&adapter->int_lock);
- adapter->isr |= isr;
- spin_unlock(&adapter->int_lock);
-
- adapter->be_stat.bes_ints++;
-
- tasklet_schedule(&adapter->sts_handler);
- return IRQ_HANDLED;
-}
-
-/*
- * Poll function called by NAPI with a work budget.
- * We process as many UC. BC and MC receive completions
- * as the budget allows and return the actual number of
- * RX ststutses processed.
- */
-int be_poll(struct napi_struct *napi, int budget)
-{
- struct be_net_object *pnob =
- container_of(napi, struct be_net_object, napi);
- u32 work_done;
-
- pnob->adapter->be_stat.bes_polls++;
- work_done = process_rx_completions(pnob, budget);
- BUG_ON(work_done > budget);
-
- /* All consumed */
- if (work_done < budget) {
- netif_rx_complete(napi);
- /* enable intr */
- be_notify_cmpl(pnob, work_done, pnob->rx_cq_id, 1);
- } else {
- /* More to be consumed; continue with interrupts disabled */
- be_notify_cmpl(pnob, work_done, pnob->rx_cq_id, 0);
- }
- return work_done;
-}
-
-static struct EQ_ENTRY_AMAP *get_event(struct be_net_object *pnob)
-{
- struct EQ_ENTRY_AMAP *eqp = &(pnob->event_q[pnob->event_q_tl]);
- if (!AMAP_GET_BITS_PTR(EQ_ENTRY, Valid, eqp))
- return NULL;
- be_adv_eq_tl(pnob);
- return eqp;
-}
-
-/*
- * Processes all valid events in the event ring associated with given
- * NetObject. Also, notifies BE the number of events processed.
- */
-static inline u32 process_events(struct be_net_object *pnob)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct EQ_ENTRY_AMAP *eqp;
- u32 rid, num_events = 0;
- struct net_device *netdev = pnob->netdev;
-
- while ((eqp = get_event(pnob)) != NULL) {
- adapter->be_stat.bes_events++;
- rid = AMAP_GET_BITS_PTR(EQ_ENTRY, ResourceID, eqp);
- if (rid == pnob->rx_cq_id) {
- adapter->be_stat.bes_rx_events++;
- netif_rx_schedule(&pnob->napi);
- } else if (rid == pnob->tx_cq_id) {
- process_nic_tx_completions(pnob);
- } else if (rid == pnob->mcc_cq_id) {
- be_mcc_process_cq(&pnob->mcc_q_obj, 1);
- } else {
- dev_info(&netdev->dev,
- "Invalid EQ ResourceID %d\n", rid);
- }
- AMAP_SET_BITS_PTR(EQ_ENTRY, Valid, eqp, 0);
- AMAP_SET_BITS_PTR(EQ_ENTRY, ResourceID, eqp, 0);
- num_events++;
- }
- return num_events;
-}
-
-static void update_eqd(struct be_adapter *adapter, struct be_net_object *pnob)
-{
- int status;
- struct be_eq_object *eq_objectp;
-
- /* update once a second */
- if ((jiffies - adapter->ips_jiffies) > 1 * (HZ)) {
- /* One second elapsed since last update */
- u32 r, new_eqd = -1;
- r = adapter->be_stat.bes_ints - adapter->be_stat.bes_prev_ints;
- r = r / ((jiffies - adapter->ips_jiffies) / (HZ));
- adapter->be_stat.bes_ips = r;
- adapter->ips_jiffies = jiffies;
- adapter->be_stat.bes_prev_ints = adapter->be_stat.bes_ints;
- if (r > IPS_HI_WM && adapter->cur_eqd < adapter->max_eqd)
- new_eqd = (adapter->cur_eqd + 8);
- if (r < IPS_LO_WM && adapter->cur_eqd > adapter->min_eqd)
- new_eqd = (adapter->cur_eqd - 8);
- if (adapter->enable_aic && new_eqd != -1) {
- eq_objectp = &pnob->event_q_obj;
- status = be_eq_modify_delay(&pnob->fn_obj, 1,
- &eq_objectp, &new_eqd, NULL,
- NULL, NULL);
- if (status == BE_SUCCESS)
- adapter->cur_eqd = new_eqd;
- }
- }
-}
-
-/*
- This function notifies BladeEngine of how many events were processed
- from the event queue by ringing the corresponding door bell and
- optionally re-arms the event queue.
- n - number of events processed
- re_arm - 1 - re-arm the EQ, 0 - do not re-arm the EQ
-
-*/
-static void be_notify_event(struct be_net_object *pnob, int n, int re_arm)
-{
- struct CQ_DB_AMAP eqdb;
- eqdb.dw[0] = 0;
-
- AMAP_SET_BITS_PTR(CQ_DB, qid, &eqdb, pnob->event_q_id);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &eqdb, re_arm);
- AMAP_SET_BITS_PTR(CQ_DB, event, &eqdb, 1);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &eqdb, n);
- /*
- * Under some situations we see an interrupt and no valid
- * EQ entry. To keep going, we need to ring the DB even if
- * numPOsted is 0.
- */
- PD_WRITE(&pnob->fn_obj, cq_db, eqdb.dw[0]);
- return;
-}
-
-/*
- * Called from the tasklet scheduled by ISR. All real interrupt processing
- * is done here.
- */
-void be_process_intr(unsigned long context)
-{
- struct be_adapter *adapter = (struct be_adapter *)context;
- struct be_net_object *pnob = adapter->net_obj;
- u32 isr, n;
- ulong flags = 0;
-
- isr = adapter->isr;
-
- /*
- * we create only one NIC event queue in Linux. Event is
- * expected only in the first event queue
- */
- BUG_ON(isr & 0xfffffffe);
- if ((isr & 1) == 0)
- return; /* not our interrupt */
- n = process_events(pnob);
- /*
- * Clear the event bit. adapter->isr is set by
- * hard interrupt. Prevent race with lock.
- */
- spin_lock_irqsave(&adapter->int_lock, flags);
- adapter->isr &= ~1;
- spin_unlock_irqrestore(&adapter->int_lock, flags);
- be_notify_event(pnob, n, 1);
- /*
- * If previous allocation attempts had failed and
- * BE has used up all posted buffers, post RX buffers here
- */
- if (pnob->rxbuf_post_fail && atomic_read(&pnob->rx_q_posted) == 0)
- be_post_eth_rx_buffs(pnob);
- update_eqd(adapter, pnob);
- return;
-}
diff --git a/drivers/staging/benet/be_netif.c b/drivers/staging/benet/be_netif.c
deleted file mode 100644
index 2b8daf63dc7..00000000000
--- a/drivers/staging/benet/be_netif.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * be_netif.c
- *
- * This file contains various entry points of drivers seen by tcp/ip stack.
- */
-
-#include <linux/if_vlan.h>
-#include <linux/in.h>
-#include "benet.h"
-#include <linux/ip.h>
-#include <linux/inet_lro.h>
-
-/* Strings to print Link properties */
-static const char *link_speed[] = {
- "Invalid link Speed Value",
- "10 Mbps",
- "100 Mbps",
- "1 Gbps",
- "10 Gbps"
-};
-
-static const char *link_duplex[] = {
- "Invalid Duplex Value",
- "Half Duplex",
- "Full Duplex"
-};
-
-static const char *link_state[] = {
- "",
- "(active)"
-};
-
-void be_print_link_info(struct BE_LINK_STATUS *lnk_status)
-{
- u16 si, di, ai;
-
- /* Port 0 */
- if (lnk_status->mac0_speed && lnk_status->mac0_duplex) {
- /* Port is up and running */
- si = (lnk_status->mac0_speed < 5) ? lnk_status->mac0_speed : 0;
- di = (lnk_status->mac0_duplex < 3) ?
- lnk_status->mac0_duplex : 0;
- ai = (lnk_status->active_port == 0) ? 1 : 0;
- printk(KERN_INFO "PortNo. 0: Speed - %s %s %s\n",
- link_speed[si], link_duplex[di], link_state[ai]);
- } else
- printk(KERN_INFO "PortNo. 0: Down\n");
-
- /* Port 1 */
- if (lnk_status->mac1_speed && lnk_status->mac1_duplex) {
- /* Port is up and running */
- si = (lnk_status->mac1_speed < 5) ? lnk_status->mac1_speed : 0;
- di = (lnk_status->mac1_duplex < 3) ?
- lnk_status->mac1_duplex : 0;
- ai = (lnk_status->active_port == 0) ? 1 : 0;
- printk(KERN_INFO "PortNo. 1: Speed - %s %s %s\n",
- link_speed[si], link_duplex[di], link_state[ai]);
- } else
- printk(KERN_INFO "PortNo. 1: Down\n");
-
- return;
-}
-
-static int
-be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
- void **ip_hdr, void **tcpudp_hdr,
- u64 *hdr_flags, void *priv)
-{
- struct ethhdr *eh;
- struct vlan_ethhdr *veh;
- struct iphdr *iph;
- u8 *va = page_address(frag->page) + frag->page_offset;
- unsigned long ll_hlen;
-
- /* find the mac header, abort if not IPv4 */
-
- prefetch(va);
- eh = (struct ethhdr *)va;
- *mac_hdr = eh;
- ll_hlen = ETH_HLEN;
- if (eh->h_proto != htons(ETH_P_IP)) {
- if (eh->h_proto == htons(ETH_P_8021Q)) {
- veh = (struct vlan_ethhdr *)va;
- if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
- return -1;
-
- ll_hlen += VLAN_HLEN;
-
- } else {
- return -1;
- }
- }
- *hdr_flags = LRO_IPV4;
-
- iph = (struct iphdr *)(va + ll_hlen);
- *ip_hdr = iph;
- if (iph->protocol != IPPROTO_TCP)
- return -1;
- *hdr_flags |= LRO_TCP;
- *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2);
-
- return 0;
-}
-
-static int benet_open(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- struct net_lro_mgr *lro_mgr;
-
- if (adapter->dev_state < BE_DEV_STATE_INIT)
- return -EAGAIN;
-
- lro_mgr = &pnob->lro_mgr;
- lro_mgr->dev = netdev;
-
- lro_mgr->features = LRO_F_NAPI;
- lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
- lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
- lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS;
- lro_mgr->lro_arr = pnob->lro_desc;
- lro_mgr->get_frag_header = be_get_frag_header;
- lro_mgr->max_aggr = adapter->max_rx_coal;
- lro_mgr->frag_align_pad = 2;
- if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
- lro_mgr->max_aggr = MAX_SKB_FRAGS;
-
- adapter->max_rx_coal = BE_LRO_MAX_PKTS;
-
- be_update_link_status(adapter);
-
- /*
- * Set carrier on only if Physical Link up
- * Either of the port link status up signifies this
- */
- if ((adapter->port0_link_sts == BE_PORT_LINK_UP) ||
- (adapter->port1_link_sts == BE_PORT_LINK_UP)) {
- netif_start_queue(netdev);
- netif_carrier_on(netdev);
- }
-
- adapter->dev_state = BE_DEV_STATE_OPEN;
- napi_enable(&pnob->napi);
- be_enable_intr(pnob);
- be_enable_eq_intr(pnob);
- /*
- * RX completion queue may be in dis-armed state. Arm it.
- */
- be_notify_cmpl(pnob, 0, pnob->rx_cq_id, 1);
-
- return 0;
-}
-
-static int benet_close(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- netif_stop_queue(netdev);
- synchronize_irq(netdev->irq);
-
- be_wait_nic_tx_cmplx_cmpl(pnob);
- adapter->dev_state = BE_DEV_STATE_INIT;
- netif_carrier_off(netdev);
-
- adapter->port0_link_sts = BE_PORT_LINK_DOWN;
- adapter->port1_link_sts = BE_PORT_LINK_DOWN;
- be_disable_intr(pnob);
- be_disable_eq_intr(pnob);
- napi_disable(&pnob->napi);
-
- return 0;
-}
-
-/*
- * Setting a Mac Address for BE
- * Takes netdev and a void pointer as arguments.
- * The pointer holds the new addres to be used.
- */
-static int benet_set_mac_addr(struct net_device *netdev, void *p)
-{
- struct sockaddr *addr = p;
- struct be_net_object *pnob = netdev_priv(netdev);
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- be_rxf_mac_address_read_write(&pnob->fn_obj, 0, 0, false, true, false,
- netdev->dev_addr, NULL, NULL);
- /*
- * Since we are doing Active-Passive failover, both
- * ports should have matching MAC addresses everytime.
- */
- be_rxf_mac_address_read_write(&pnob->fn_obj, 1, 0, false, true, false,
- netdev->dev_addr, NULL, NULL);
-
- return 0;
-}
-
-void be_get_stats_timer_handler(unsigned long context)
-{
- struct be_timer_ctxt *ctxt = (struct be_timer_ctxt *)context;
-
- if (atomic_read(&ctxt->get_stat_flag)) {
- atomic_dec(&ctxt->get_stat_flag);
- up((void *)ctxt->get_stat_sem_addr);
- }
- del_timer(&ctxt->get_stats_timer);
- return;
-}
-
-void be_get_stat_cb(void *context, int status,
- struct MCC_WRB_AMAP *optional_wrb)
-{
- struct be_timer_ctxt *ctxt = (struct be_timer_ctxt *)context;
- /*
- * just up the semaphore if the get_stat_flag
- * reads 1. so that the waiter can continue.
- * If it is 0, then it was handled by the timer handler.
- */
- del_timer(&ctxt->get_stats_timer);
- if (atomic_read(&ctxt->get_stat_flag)) {
- atomic_dec(&ctxt->get_stat_flag);
- up((void *)ctxt->get_stat_sem_addr);
- }
-}
-
-struct net_device_stats *benet_get_stats(struct net_device *dev)
-{
- struct be_net_object *pnob = netdev_priv(dev);
- struct be_adapter *adapter = pnob->adapter;
- u64 pa;
- struct be_timer_ctxt *ctxt = &adapter->timer_ctxt;
-
- if (adapter->dev_state != BE_DEV_STATE_OPEN) {
- /* Return previously read stats */
- return &(adapter->benet_stats);
- }
- /* Get Physical Addr */
- pa = pci_map_single(adapter->pdev, adapter->eth_statsp,
- sizeof(struct FWCMD_ETH_GET_STATISTICS),
- PCI_DMA_FROMDEVICE);
- ctxt->get_stat_sem_addr = (unsigned long)&adapter->get_eth_stat_sem;
- atomic_inc(&ctxt->get_stat_flag);
-
- be_rxf_query_eth_statistics(&pnob->fn_obj, adapter->eth_statsp,
- cpu_to_le64(pa), be_get_stat_cb, ctxt,
- NULL);
-
- ctxt->get_stats_timer.data = (unsigned long)ctxt;
- mod_timer(&ctxt->get_stats_timer, (jiffies + (HZ * 2)));
- down((void *)ctxt->get_stat_sem_addr); /* callback will unblock us */
-
- /* Adding port0 and port1 stats. */
- adapter->benet_stats.rx_packets =
- adapter->eth_statsp->params.response.p0recvdtotalframes +
- adapter->eth_statsp->params.response.p1recvdtotalframes;
- adapter->benet_stats.tx_packets =
- adapter->eth_statsp->params.response.p0xmitunicastframes +
- adapter->eth_statsp->params.response.p1xmitunicastframes;
- adapter->benet_stats.tx_bytes =
- adapter->eth_statsp->params.response.p0xmitbyteslsd +
- adapter->eth_statsp->params.response.p1xmitbyteslsd;
- adapter->benet_stats.rx_errors =
- adapter->eth_statsp->params.response.p0crcerrors +
- adapter->eth_statsp->params.response.p1crcerrors;
- adapter->benet_stats.rx_errors +=
- adapter->eth_statsp->params.response.p0alignmentsymerrs +
- adapter->eth_statsp->params.response.p1alignmentsymerrs;
- adapter->benet_stats.rx_errors +=
- adapter->eth_statsp->params.response.p0inrangelenerrors +
- adapter->eth_statsp->params.response.p1inrangelenerrors;
- adapter->benet_stats.rx_bytes =
- adapter->eth_statsp->params.response.p0recvdtotalbytesLSD +
- adapter->eth_statsp->params.response.p1recvdtotalbytesLSD;
- adapter->benet_stats.rx_crc_errors =
- adapter->eth_statsp->params.response.p0crcerrors +
- adapter->eth_statsp->params.response.p1crcerrors;
-
- adapter->benet_stats.tx_packets +=
- adapter->eth_statsp->params.response.p0xmitmulticastframes +
- adapter->eth_statsp->params.response.p1xmitmulticastframes;
- adapter->benet_stats.tx_packets +=
- adapter->eth_statsp->params.response.p0xmitbroadcastframes +
- adapter->eth_statsp->params.response.p1xmitbroadcastframes;
- adapter->benet_stats.tx_errors = 0;
-
- adapter->benet_stats.multicast =
- adapter->eth_statsp->params.response.p0xmitmulticastframes +
- adapter->eth_statsp->params.response.p1xmitmulticastframes;
-
- adapter->benet_stats.rx_fifo_errors =
- adapter->eth_statsp->params.response.p0rxfifooverflowdropped +
- adapter->eth_statsp->params.response.p1rxfifooverflowdropped;
- adapter->benet_stats.rx_frame_errors =
- adapter->eth_statsp->params.response.p0alignmentsymerrs +
- adapter->eth_statsp->params.response.p1alignmentsymerrs;
- adapter->benet_stats.rx_length_errors =
- adapter->eth_statsp->params.response.p0inrangelenerrors +
- adapter->eth_statsp->params.response.p1inrangelenerrors;
- adapter->benet_stats.rx_length_errors +=
- adapter->eth_statsp->params.response.p0outrangeerrors +
- adapter->eth_statsp->params.response.p1outrangeerrors;
- adapter->benet_stats.rx_length_errors +=
- adapter->eth_statsp->params.response.p0frametoolongerrors +
- adapter->eth_statsp->params.response.p1frametoolongerrors;
-
- pci_unmap_single(adapter->pdev, (ulong) adapter->eth_statsp,
- sizeof(struct FWCMD_ETH_GET_STATISTICS),
- PCI_DMA_FROMDEVICE);
- return &(adapter->benet_stats);
-
-}
-
-static void be_start_tx(struct be_net_object *pnob, u32 nposted)
-{
-#define CSR_ETH_MAX_SQPOSTS 255
- struct SQ_DB_AMAP sqdb;
-
- sqdb.dw[0] = 0;
-
- AMAP_SET_BITS_PTR(SQ_DB, cid, &sqdb, pnob->tx_q_id);
- while (nposted) {
- if (nposted > CSR_ETH_MAX_SQPOSTS) {
- AMAP_SET_BITS_PTR(SQ_DB, numPosted, &sqdb,
- CSR_ETH_MAX_SQPOSTS);
- nposted -= CSR_ETH_MAX_SQPOSTS;
- } else {
- AMAP_SET_BITS_PTR(SQ_DB, numPosted, &sqdb, nposted);
- nposted = 0;
- }
- PD_WRITE(&pnob->fn_obj, etx_sq_db, sqdb.dw[0]);
- }
-
- return;
-}
-
-static void update_tx_rate(struct be_adapter *adapter)
-{
- /* update the rate once in two seconds */
- if ((jiffies - adapter->eth_tx_jiffies) > 2 * (HZ)) {
- u32 r;
- r = adapter->eth_tx_bytes /
- ((jiffies - adapter->eth_tx_jiffies) / (HZ));
- r = (r / 1000000); /* M bytes/s */
- adapter->be_stat.bes_eth_tx_rate = (r * 8); /* M bits/s */
- adapter->eth_tx_jiffies = jiffies;
- adapter->eth_tx_bytes = 0;
- }
-}
-
-static int wrb_cnt_in_skb(struct sk_buff *skb)
-{
- int cnt = 0;
- while (skb) {
- if (skb->len > skb->data_len)
- cnt++;
- cnt += skb_shinfo(skb)->nr_frags;
- skb = skb_shinfo(skb)->frag_list;
- }
- BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT);
- return cnt;
-}
-
-static void wrb_fill(struct ETH_WRB_AMAP *wrb, u64 addr, int len)
-{
- AMAP_SET_BITS_PTR(ETH_WRB, frag_pa_hi, wrb, addr >> 32);
- AMAP_SET_BITS_PTR(ETH_WRB, frag_pa_lo, wrb, addr & 0xFFFFFFFF);
- AMAP_SET_BITS_PTR(ETH_WRB, frag_len, wrb, len);
-}
-
-static void wrb_fill_extra(struct ETH_WRB_AMAP *wrb, struct sk_buff *skb,
- struct be_net_object *pnob)
-{
- wrb->dw[2] = 0;
- wrb->dw[3] = 0;
- AMAP_SET_BITS_PTR(ETH_WRB, crc, wrb, 1);
- if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) {
- AMAP_SET_BITS_PTR(ETH_WRB, lso, wrb, 1);
- AMAP_SET_BITS_PTR(ETH_WRB, lso_mss, wrb,
- skb_shinfo(skb)->gso_size);
- } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
- u8 proto = ((struct iphdr *)ip_hdr(skb))->protocol;
- if (proto == IPPROTO_TCP)
- AMAP_SET_BITS_PTR(ETH_WRB, tcpcs, wrb, 1);
- else if (proto == IPPROTO_UDP)
- AMAP_SET_BITS_PTR(ETH_WRB, udpcs, wrb, 1);
- }
- if (pnob->vlan_grp && vlan_tx_tag_present(skb)) {
- AMAP_SET_BITS_PTR(ETH_WRB, vlan, wrb, 1);
- AMAP_SET_BITS_PTR(ETH_WRB, vlan_tag, wrb, vlan_tx_tag_get(skb));
- }
-}
-
-static inline void wrb_copy_extra(struct ETH_WRB_AMAP *to,
- struct ETH_WRB_AMAP *from)
-{
-
- to->dw[2] = from->dw[2];
- to->dw[3] = from->dw[3];
-}
-
-/* Returns the actual count of wrbs used including a possible dummy */
-static int copy_skb_to_txq(struct be_net_object *pnob, struct sk_buff *skb,
- u32 wrb_cnt, u32 *copied)
-{
- u64 busaddr;
- struct ETH_WRB_AMAP *wrb = NULL, *first = NULL;
- u32 i;
- bool dummy = true;
- struct pci_dev *pdev = pnob->adapter->pdev;
-
- if (wrb_cnt & 1)
- wrb_cnt++;
- else
- dummy = false;
-
- atomic_add(wrb_cnt, &pnob->tx_q_used);
-
- 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);
- busaddr = cpu_to_le64(busaddr);
- wrb = &pnob->tx_q[pnob->tx_q_hd];
- if (first == NULL) {
- wrb_fill_extra(wrb, skb, pnob);
- first = wrb;
- } else {
- wrb_copy_extra(wrb, first);
- }
- wrb_fill(wrb, busaddr, len);
- be_adv_txq_hd(pnob);
- *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);
- busaddr = cpu_to_le64(busaddr);
- wrb = &pnob->tx_q[pnob->tx_q_hd];
- if (first == NULL) {
- wrb_fill_extra(wrb, skb, pnob);
- first = wrb;
- } else {
- wrb_copy_extra(wrb, first);
- }
- wrb_fill(wrb, busaddr, frag->size);
- be_adv_txq_hd(pnob);
- *copied += frag->size;
- }
- skb = skb_shinfo(skb)->frag_list;
- }
-
- if (dummy) {
- wrb = &pnob->tx_q[pnob->tx_q_hd];
- BUG_ON(first == NULL);
- wrb_copy_extra(wrb, first);
- wrb_fill(wrb, 0, 0);
- be_adv_txq_hd(pnob);
- }
- AMAP_SET_BITS_PTR(ETH_WRB, complete, wrb, 1);
- AMAP_SET_BITS_PTR(ETH_WRB, last, wrb, 1);
- return wrb_cnt;
-}
-
-/* For each skb transmitted, tx_ctxt stores the num of wrbs in the
- * start index and skb pointer in the end index
- */
-static inline void be_tx_wrb_info_remember(struct be_net_object *pnob,
- struct sk_buff *skb, int wrb_cnt,
- u32 start)
-{
- *(u32 *) (&pnob->tx_ctxt[start]) = wrb_cnt;
- index_adv(&start, wrb_cnt - 1, pnob->tx_q_len);
- pnob->tx_ctxt[start] = skb;
-}
-
-static int benet_xmit(struct sk_buff *skb, struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- u32 wrb_cnt, copied = 0;
- u32 start = pnob->tx_q_hd;
-
- adapter->be_stat.bes_tx_reqs++;
-
- wrb_cnt = wrb_cnt_in_skb(skb);
- spin_lock_bh(&adapter->txq_lock);
- if ((pnob->tx_q_len - 2 - atomic_read(&pnob->tx_q_used)) <= wrb_cnt) {
- netif_stop_queue(pnob->netdev);
- spin_unlock_bh(&adapter->txq_lock);
- adapter->be_stat.bes_tx_fails++;
- return NETDEV_TX_BUSY;
- }
- spin_unlock_bh(&adapter->txq_lock);
-
- wrb_cnt = copy_skb_to_txq(pnob, skb, wrb_cnt, &copied);
- be_tx_wrb_info_remember(pnob, skb, wrb_cnt, start);
-
- be_start_tx(pnob, wrb_cnt);
-
- adapter->eth_tx_bytes += copied;
- adapter->be_stat.bes_tx_wrbs += wrb_cnt;
- update_tx_rate(adapter);
- netdev->trans_start = jiffies;
-
- return NETDEV_TX_OK;
-}
-
-/*
- * This is the driver entry point to change the mtu of the device
- * Returns 0 for success and errno for failure.
- */
-static int benet_change_mtu(struct net_device *netdev, int new_mtu)
-{
- /*
- * BE supports jumbo frame size upto 9000 bytes including the link layer
- * header. Considering the different variants of frame formats possible
- * like VLAN, SNAP/LLC, the maximum possible value for MTU is 8974 bytes
- */
-
- if (new_mtu < (ETH_ZLEN + ETH_FCS_LEN) || (new_mtu > BE_MAX_MTU)) {
- dev_info(&netdev->dev, "Invalid MTU requested. "
- "Must be between %d and %d bytes\n",
- (ETH_ZLEN + ETH_FCS_LEN), BE_MAX_MTU);
- return -EINVAL;
- }
- dev_info(&netdev->dev, "MTU changed from %d to %d\n",
- netdev->mtu, new_mtu);
- netdev->mtu = new_mtu;
- return 0;
-}
-
-/*
- * This is the driver entry point to register a vlan with the device
- */
-static void benet_vlan_register(struct net_device *netdev,
- struct vlan_group *grp)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- be_disable_eq_intr(pnob);
- pnob->vlan_grp = grp;
- pnob->num_vlans = 0;
- be_enable_eq_intr(pnob);
-}
-
-/*
- * This is the driver entry point to add a vlan vlan_id
- * with the device netdev
- */
-static void benet_vlan_add_vid(struct net_device *netdev, u16 vlan_id)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- if (pnob->num_vlans == (BE_NUM_VLAN_SUPPORTED - 1)) {
- /* no way to return an error */
- dev_info(&netdev->dev,
- "BladeEngine: Cannot configure more than %d Vlans\n",
- BE_NUM_VLAN_SUPPORTED);
- return;
- }
- /* The new vlan tag will be in the slot indicated by num_vlans. */
- pnob->vlan_tag[pnob->num_vlans++] = vlan_id;
- be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans,
- pnob->vlan_tag, NULL, NULL, NULL);
-}
-
-/*
- * This is the driver entry point to remove a vlan vlan_id
- * with the device netdev
- */
-static void benet_vlan_rem_vid(struct net_device *netdev, u16 vlan_id)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- u32 i, value;
-
- /*
- * In Blade Engine, we support 32 vlan tag filters across both ports.
- * To program a vlan tag, the RXF_RTPR_CSR register is used.
- * Each 32-bit value of RXF_RTDR_CSR can address 2 vlan tag entries.
- * The Vlan table is of depth 16. thus we support 32 tags.
- */
-
- value = vlan_id | VLAN_VALID_BIT;
- for (i = 0; i < BE_NUM_VLAN_SUPPORTED; i++) {
- if (pnob->vlan_tag[i] == vlan_id)
- break;
- }
-
- if (i == BE_NUM_VLAN_SUPPORTED)
- return;
- /* Now compact the vlan tag array by removing hole created. */
- while ((i + 1) < BE_NUM_VLAN_SUPPORTED) {
- pnob->vlan_tag[i] = pnob->vlan_tag[i + 1];
- i++;
- }
- if ((i + 1) == BE_NUM_VLAN_SUPPORTED)
- pnob->vlan_tag[i] = (u16) 0x0;
- pnob->num_vlans--;
- be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans,
- pnob->vlan_tag, NULL, NULL, NULL);
-}
-
-/*
- * This function is called to program multicast
- * address in the multicast filter of the ASIC.
- */
-static void be_set_multicast_filter(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct dev_mc_list *mc_ptr;
- u8 mac_addr[32][ETH_ALEN];
- int i;
-
- if (netdev->flags & IFF_ALLMULTI) {
- /* set BE in Multicast promiscuous */
- be_rxf_multicast_config(&pnob->fn_obj, true, 0, NULL, NULL,
- NULL, NULL);
- return;
- }
-
- for (mc_ptr = netdev->mc_list, i = 0; mc_ptr;
- mc_ptr = mc_ptr->next, i++) {
- memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN);
- }
-
- /* reset the promiscuous mode also. */
- be_rxf_multicast_config(&pnob->fn_obj, false, i,
- &mac_addr[0][0], NULL, NULL, NULL);
-}
-
-/*
- * This is the driver entry point to set multicast list
- * with the device netdev. This function will be used to
- * set promiscuous mode or multicast promiscuous mode
- * or multicast mode....
- */
-static void benet_set_multicast_list(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- if (netdev->flags & IFF_PROMISC) {
- be_rxf_promiscuous(&pnob->fn_obj, 1, 1, NULL, NULL, NULL);
- } else {
- be_rxf_promiscuous(&pnob->fn_obj, 0, 0, NULL, NULL, NULL);
- be_set_multicast_filter(netdev);
- }
-}
-
-int benet_init(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- ether_setup(netdev);
-
- netdev->open = &benet_open;
- netdev->stop = &benet_close;
- netdev->hard_start_xmit = &benet_xmit;
-
- netdev->get_stats = &benet_get_stats;
-
- netdev->set_multicast_list = &benet_set_multicast_list;
-
- netdev->change_mtu = &benet_change_mtu;
- netdev->set_mac_address = &benet_set_mac_addr;
-
- netdev->vlan_rx_register = benet_vlan_register;
- netdev->vlan_rx_add_vid = benet_vlan_add_vid;
- netdev->vlan_rx_kill_vid = benet_vlan_rem_vid;
-
- netdev->features =
- NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM;
-
- netdev->flags |= IFF_MULTICAST;
-
- /* If device is DAC Capable, set the HIGHDMA flag for netdevice. */
- if (adapter->dma_64bit_cap)
- netdev->features |= NETIF_F_HIGHDMA;
-
- SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
- return 0;
-}
diff --git a/drivers/staging/benet/benet.h b/drivers/staging/benet/benet.h
deleted file mode 100644
index 09a1f081772..00000000000
--- a/drivers/staging/benet/benet.h
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#ifndef _BENET_H_
-#define _BENET_H_
-
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/inet_lro.h>
-#include "hwlib.h"
-
-#define _SA_MODULE_NAME "net-driver"
-
-#define VLAN_VALID_BIT 0x8000
-#define BE_NUM_VLAN_SUPPORTED 32
-#define BE_PORT_LINK_DOWN 0000
-#define BE_PORT_LINK_UP 0001
-#define BE_MAX_TX_FRAG_COUNT (30)
-
-/* Flag bits for send operation */
-#define IPCS (1 << 0) /* Enable IP checksum offload */
-#define UDPCS (1 << 1) /* Enable UDP checksum offload */
-#define TCPCS (1 << 2) /* Enable TCP checksum offload */
-#define LSO (1 << 3) /* Enable Large Segment offload */
-#define ETHVLAN (1 << 4) /* Enable VLAN insert */
-#define ETHEVENT (1 << 5) /* Generate event on completion */
-#define ETHCOMPLETE (1 << 6) /* Generate completion when done */
-#define IPSEC (1 << 7) /* Enable IPSEC */
-#define FORWARD (1 << 8) /* Send the packet in forwarding path */
-#define FIN (1 << 9) /* Issue FIN segment */
-
-#define BE_MAX_MTU 8974
-
-#define BE_MAX_LRO_DESCRIPTORS 8
-#define BE_LRO_MAX_PKTS 64
-#define BE_MAX_FRAGS_PER_FRAME 6
-
-extern const char be_drvr_ver[];
-extern char be_fw_ver[];
-extern char be_driver_name[];
-
-extern struct ethtool_ops be_ethtool_ops;
-
-#define BE_DEV_STATE_NONE 0
-#define BE_DEV_STATE_INIT 1
-#define BE_DEV_STATE_OPEN 2
-#define BE_DEV_STATE_SUSPEND 3
-
-/* This structure is used to describe physical fragments to use
- * for DMAing data from NIC.
- */
-struct be_recv_buffer {
- struct list_head rxb_list; /* for maintaining a linked list */
- void *rxb_va; /* buffer virtual address */
- u32 rxb_pa_lo; /* low part of physical address */
- u32 rxb_pa_hi; /* high part of physical address */
- u32 rxb_len; /* length of recv buffer */
- void *rxb_ctxt; /* context for OSM driver to use */
-};
-
-/*
- * fragment list to describe scattered data.
- */
-struct be_tx_frag_list {
- u32 txb_len; /* Size of this fragment */
- u32 txb_pa_lo; /* Lower 32 bits of 64 bit physical addr */
- u32 txb_pa_hi; /* Higher 32 bits of 64 bit physical addr */
-};
-
-struct be_rx_page_info {
- struct page *page;
- dma_addr_t bus;
- u16 page_offset;
-};
-
-/*
- * This structure is the main tracking structure for a NIC interface.
- */
-struct be_net_object {
- /* MCC Ring - used to send fwcmds to embedded ARM processor */
- struct MCC_WRB_AMAP *mcc_q; /* VA of the start of the ring */
- u32 mcc_q_len; /* # of WRB entries in this ring */
- u32 mcc_q_size;
- u32 mcc_q_hd; /* MCC ring head */
- u8 mcc_q_created; /* flag to help cleanup */
- struct be_mcc_object mcc_q_obj; /* BECLIB's MCC ring Object */
- dma_addr_t mcc_q_bus; /* DMA'ble bus address */
-
- /* MCC Completion Ring - FW responses to fwcmds sent from MCC ring */
- struct MCC_CQ_ENTRY_AMAP *mcc_cq; /* VA of the start of the ring */
- u32 mcc_cq_len; /* # of compl. entries in this ring */
- u32 mcc_cq_size;
- u32 mcc_cq_tl; /* compl. ring tail */
- u8 mcc_cq_created; /* flag to help cleanup */
- struct be_cq_object mcc_cq_obj; /* BECLIB's MCC compl. ring object */
- u32 mcc_cq_id; /* MCC ring ID */
- dma_addr_t mcc_cq_bus; /* DMA'ble bus address */
-
- struct ring_desc mb_rd; /* RD for MCC_MAIL_BOX */
- void *mb_ptr; /* mailbox ptr to be freed */
- dma_addr_t mb_bus; /* DMA'ble bus address */
- u32 mb_size;
-
- /* BEClib uses an array of context objects to track outstanding
- * requests to the MCC. We need allocate the same number of
- * conext entries as the number of entries in the MCC WRB ring
- */
- u32 mcc_wrb_ctxt_size;
- void *mcc_wrb_ctxt; /* pointer to the context area */
- u32 mcc_wrb_ctxtLen; /* Number of entries in the context */
- /*
- * NIC send request ring - used for xmitting raw ether frames.
- */
- struct ETH_WRB_AMAP *tx_q; /* VA of the start of the ring */
- u32 tx_q_len; /* # if entries in the send ring */
- u32 tx_q_size;
- u32 tx_q_hd; /* Head index. Next req. goes here */
- u32 tx_q_tl; /* Tail indx. oldest outstanding req. */
- u8 tx_q_created; /* flag to help cleanup */
- struct be_ethsq_object tx_q_obj;/* BECLIB's send Q handle */
- dma_addr_t tx_q_bus; /* DMA'ble bus address */
- u32 tx_q_id; /* send queue ring ID */
- u32 tx_q_port; /* 0 no binding, 1 port A, 2 port B */
- atomic_t tx_q_used; /* # of WRBs used */
- /* ptr to an array in which we store context info for each send req. */
- void **tx_ctxt;
- /*
- * NIC Send compl. ring - completion status for all NIC frames xmitted.
- */
- struct ETH_TX_COMPL_AMAP *tx_cq;/* VA of start of the ring */
- u32 txcq_len; /* # of entries in the ring */
- u32 tx_cq_size;
- /*
- * index into compl ring where the host expects next completion entry
- */
- u32 tx_cq_tl;
- u32 tx_cq_id; /* completion queue id */
- u8 tx_cq_created; /* flag to help cleanup */
- struct be_cq_object tx_cq_obj;
- dma_addr_t tx_cq_bus; /* DMA'ble bus address */
- /*
- * Event Queue - all completion entries post events here.
- */
- struct EQ_ENTRY_AMAP *event_q; /* VA of start of event queue */
- u32 event_q_len; /* # of entries */
- u32 event_q_size;
- u32 event_q_tl; /* Tail of the event queue */
- u32 event_q_id; /* Event queue ID */
- u8 event_q_created; /* flag to help cleanup */
- struct be_eq_object event_q_obj; /* Queue handle */
- dma_addr_t event_q_bus; /* DMA'ble bus address */
- /*
- * NIC receive queue - Data buffers to be used for receiving unicast,
- * broadcast and multi-cast frames are posted here.
- */
- struct ETH_RX_D_AMAP *rx_q; /* VA of start of the queue */
- u32 rx_q_len; /* # of entries */
- u32 rx_q_size;
- u32 rx_q_hd; /* Head of the queue */
- atomic_t rx_q_posted; /* number of posted buffers */
- u32 rx_q_id; /* queue ID */
- u8 rx_q_created; /* flag to help cleanup */
- struct be_ethrq_object rx_q_obj; /* NIC RX queue handle */
- dma_addr_t rx_q_bus; /* DMA'ble bus address */
- /*
- * Pointer to an array of opaque context object for use by OSM driver
- */
- void **rx_ctxt;
- /*
- * NIC unicast RX completion queue - all unicast ether frame completion
- * statuses from BE come here.
- */
- struct ETH_RX_COMPL_AMAP *rx_cq; /* VA of start of the queue */
- u32 rx_cq_len; /* # of entries */
- u32 rx_cq_size;
- u32 rx_cq_tl; /* Tail of the queue */
- u32 rx_cq_id; /* queue ID */
- u8 rx_cq_created; /* flag to help cleanup */
- struct be_cq_object rx_cq_obj; /* queue handle */
- dma_addr_t rx_cq_bus; /* DMA'ble bus address */
- struct be_function_object fn_obj; /* function object */
- bool fn_obj_created;
- u32 rx_buf_size; /* Size of the RX buffers */
-
- struct net_device *netdev;
- struct be_recv_buffer eth_rx_bufs[256]; /* to pass Rx buffer
- addresses */
- struct be_adapter *adapter; /* Pointer to OSM adapter */
- u32 devno; /* OSM, network dev no. */
- u32 use_port; /* Current active port */
- struct be_rx_page_info *rx_page_info; /* Array of Rx buf pages */
- u32 rx_pg_info_hd; /* Head of queue */
- int rxbuf_post_fail; /* RxBuff posting fail count */
- bool rx_pg_shared; /* Is an allocsted page shared as two frags ? */
- struct vlan_group *vlan_grp;
- u32 num_vlans; /* Number of vlans in BE's filter */
- u16 vlan_tag[BE_NUM_VLAN_SUPPORTED]; /* vlans currently configured */
- struct napi_struct napi;
- struct net_lro_mgr lro_mgr;
- struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS];
-};
-
-#define NET_FH(np) (&(np)->fn_obj)
-
-/*
- * BE driver statistics.
- */
-struct be_drvr_stat {
- u32 bes_tx_reqs; /* number of TX requests initiated */
- u32 bes_tx_fails; /* number of TX requests that failed */
- u32 bes_fwd_reqs; /* number of send reqs through forwarding i/f */
- u32 bes_tx_wrbs; /* number of tx WRBs used */
-
- u32 bes_ints; /* number of interrupts */
- u32 bes_polls; /* number of times NAPI called poll function */
- u32 bes_events; /* total evet entries processed */
- u32 bes_tx_events; /* number of tx completion events */
- u32 bes_rx_events; /* number of ucast rx completion events */
- u32 bes_tx_compl; /* number of tx completion entries processed */
- u32 bes_rx_compl; /* number of rx completion entries
- processed */
- u32 bes_ethrx_post_fail; /* number of ethrx buffer alloc
- failures */
- /*
- * number of non ether type II frames dropped where
- * frame len > length field of Mac Hdr
- */
- u32 bes_802_3_dropped_frames;
- /*
- * number of non ether type II frames malformed where
- * in frame len < length field of Mac Hdr
- */
- u32 bes_802_3_malformed_frames;
- u32 bes_ips; /* interrupts / sec */
- u32 bes_prev_ints; /* bes_ints at last IPS calculation */
- u16 bes_eth_tx_rate; /* ETH TX rate - Mb/sec */
- u16 bes_eth_rx_rate; /* ETH RX rate - Mb/sec */
- u32 bes_rx_coal; /* Num pkts coalasced */
- u32 bes_rx_flush; /* Num times coalasced */
- u32 bes_link_change_physical; /*Num of times physical link changed */
- u32 bes_link_change_virtual; /*Num of times virtual link changed */
- u32 bes_rx_misc_pkts; /* Misc pkts received */
-};
-
-/* Maximum interrupt delay (in microseconds) allowed */
-#define MAX_EQD 120
-
-/*
- * timer to prevent system shutdown hang for ever if h/w stops responding
- */
-struct be_timer_ctxt {
- atomic_t get_stat_flag;
- struct timer_list get_stats_timer;
- unsigned long get_stat_sem_addr;
-} ;
-
-/* This structure is the main BladeEngine driver context. */
-struct be_adapter {
- struct net_device *netdevp;
- struct be_drvr_stat be_stat;
- struct net_device_stats benet_stats;
-
- /* PCI BAR mapped addresses */
- u8 __iomem *csr_va; /* CSR */
- u8 __iomem *db_va; /* Door Bell */
- u8 __iomem *pci_va; /* PCI Config */
-
- struct tasklet_struct sts_handler;
- struct timer_list cq_timer;
- spinlock_t int_lock; /* to protect the isr field in adapter */
-
- struct FWCMD_ETH_GET_STATISTICS *eth_statsp;
- /*
- * This will enable the use of ethtool to enable or disable
- * Checksum on Rx pkts to be obeyed or disobeyed.
- * If this is true = 1, then whatever is the checksum on the
- * Received pkt as per BE, it will be given to the stack.
- * Else the stack will re calculate it.
- */
- bool rx_csum;
- /*
- * This will enable the use of ethtool to enable or disable
- * Coalese on Rx pkts to be obeyed or disobeyed.
- * If this is grater than 0 and less than 16 then coalascing
- * is enabled else it is disabled
- */
- u32 max_rx_coal;
- struct pci_dev *pdev; /* Pointer to OS's PCI dvice */
-
- spinlock_t txq_lock; /* to stop/wake queue based on tx_q_used */
-
- u32 isr; /* copy of Intr status reg. */
-
- u32 port0_link_sts; /* Port 0 link status */
- u32 port1_link_sts; /* port 1 list status */
- struct BE_LINK_STATUS *be_link_sts;
-
- /* pointer to the first netobject of this adapter */
- struct be_net_object *net_obj;
-
- /* Flags to indicate what to clean up */
- bool tasklet_started;
- bool isr_registered;
- /*
- * adaptive interrupt coalescing (AIC) related
- */
- bool enable_aic; /* 1 if AIC is enabled */
- u16 min_eqd; /* minimum EQ delay in usec */
- u16 max_eqd; /* minimum EQ delay in usec */
- u16 cur_eqd; /* current EQ delay in usec */
- /*
- * book keeping for interrupt / sec and TX/RX rate calculation
- */
- ulong ips_jiffies; /* jiffies at last IPS calc */
- u32 eth_tx_bytes;
- ulong eth_tx_jiffies;
- u32 eth_rx_bytes;
- ulong eth_rx_jiffies;
-
- struct semaphore get_eth_stat_sem;
-
- /* timer ctxt to prevent shutdown hanging due to un-responsive BE */
- struct be_timer_ctxt timer_ctxt;
-
-#define BE_MAX_MSIX_VECTORS 32
-#define BE_MAX_REQ_MSIX_VECTORS 1 /* only one EQ in Linux driver */
- struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
- bool msix_enabled;
- bool dma_64bit_cap; /* the Device DAC capable or not */
- u8 dev_state; /* The current state of the device */
- u8 dev_pm_state; /* The State of device before going to suspend */
-};
-
-/*
- * Every second we look at the ints/sec and adjust eq_delay
- * between adapter->min_eqd and adapter->max_eqd to keep the ints/sec between
- * IPS_HI_WM and IPS_LO_WM.
- */
-#define IPS_HI_WM 18000
-#define IPS_LO_WM 8000
-
-
-static inline void index_adv(u32 *index, u32 val, u32 limit)
-{
- BUG_ON(limit & (limit-1));
- *index = (*index + val) & (limit - 1);
-}
-
-static inline void index_inc(u32 *index, u32 limit)
-{
- BUG_ON(limit & (limit-1));
- *index = (*index + 1) & (limit - 1);
-}
-
-static inline void be_adv_eq_tl(struct be_net_object *pnob)
-{
- index_inc(&pnob->event_q_tl, pnob->event_q_len);
-}
-
-static inline void be_adv_txq_hd(struct be_net_object *pnob)
-{
- index_inc(&pnob->tx_q_hd, pnob->tx_q_len);
-}
-
-static inline void be_adv_txq_tl(struct be_net_object *pnob)
-{
- index_inc(&pnob->tx_q_tl, pnob->tx_q_len);
-}
-
-static inline void be_adv_txcq_tl(struct be_net_object *pnob)
-{
- index_inc(&pnob->tx_cq_tl, pnob->txcq_len);
-}
-
-static inline void be_adv_rxq_hd(struct be_net_object *pnob)
-{
- index_inc(&pnob->rx_q_hd, pnob->rx_q_len);
-}
-
-static inline void be_adv_rxcq_tl(struct be_net_object *pnob)
-{
- index_inc(&pnob->rx_cq_tl, pnob->rx_cq_len);
-}
-
-static inline u32 tx_compl_lastwrb_idx_get(struct be_net_object *pnob)
-{
- return (pnob->tx_q_tl + *(u32 *)&pnob->tx_ctxt[pnob->tx_q_tl] - 1)
- & (pnob->tx_q_len - 1);
-}
-
-int benet_init(struct net_device *);
-int be_ethtool_ioctl(struct net_device *, struct ifreq *);
-struct net_device_stats *benet_get_stats(struct net_device *);
-void be_process_intr(unsigned long context);
-irqreturn_t be_int(int irq, void *dev);
-void be_post_eth_rx_buffs(struct be_net_object *);
-void be_get_stat_cb(void *, int, struct MCC_WRB_AMAP *);
-void be_get_stats_timer_handler(unsigned long);
-void be_wait_nic_tx_cmplx_cmpl(struct be_net_object *);
-void be_print_link_info(struct BE_LINK_STATUS *);
-void be_update_link_status(struct be_adapter *);
-void be_init_procfs(struct be_adapter *);
-void be_cleanup_procfs(struct be_adapter *);
-int be_poll(struct napi_struct *, int);
-struct ETH_RX_COMPL_AMAP *be_get_rx_cmpl(struct be_net_object *);
-void be_notify_cmpl(struct be_net_object *, int, int, int);
-void be_enable_intr(struct be_net_object *);
-void be_enable_eq_intr(struct be_net_object *);
-void be_disable_intr(struct be_net_object *);
-void be_disable_eq_intr(struct be_net_object *);
-int be_set_uc_mac_adr(struct be_net_object *, u8, u8, u8,
- u8 *, mcc_wrb_cqe_callback, void *);
-int be_get_flow_ctl(struct be_function_object *pFnObj, bool *, bool *);
-void process_one_tx_compl(struct be_net_object *pnob, u32 end_idx);
-
-#endif /* _BENET_H_ */
diff --git a/drivers/staging/benet/bestatus.h b/drivers/staging/benet/bestatus.h
deleted file mode 100644
index 59c7a4b6222..00000000000
--- a/drivers/staging/benet/bestatus.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#ifndef _BESTATUS_H_
-#define _BESTATUS_H_
-
-#define BE_SUCCESS (0x00000000L)
-/*
- * MessageId: BE_PENDING
- * The BladeEngine Driver call succeeded, and pended operation.
- */
-#define BE_PENDING (0x20070001L)
-#define BE_STATUS_PENDING (BE_PENDING)
-/*
- * MessageId: BE_NOT_OK
- * An error occurred.
- */
-#define BE_NOT_OK (0xE0070002L)
-/*
- * MessageId: BE_STATUS_SYSTEM_RESOURCES
- * Insufficient host system resources exist to complete the API.
- */
-#define BE_STATUS_SYSTEM_RESOURCES (0xE0070003L)
-/*
- * MessageId: BE_STATUS_CHIP_RESOURCES
- * Insufficient chip resources exist to complete the API.
- */
-#define BE_STATUS_CHIP_RESOURCES (0xE0070004L)
-/*
- * MessageId: BE_STATUS_NO_RESOURCE
- * Insufficient resources to complete request.
- */
-#define BE_STATUS_NO_RESOURCE (0xE0070005L)
-/*
- * MessageId: BE_STATUS_BUSY
- * Resource is currently busy.
- */
-#define BE_STATUS_BUSY (0xE0070006L)
-/*
- * MessageId: BE_STATUS_INVALID_PARAMETER
- * Invalid Parameter in request.
- */
-#define BE_STATUS_INVALID_PARAMETER (0xE0000007L)
-/*
- * MessageId: BE_STATUS_NOT_SUPPORTED
- * Requested operation is not supported.
- */
-#define BE_STATUS_NOT_SUPPORTED (0xE000000DL)
-
-/*
- * ***************************************************************************
- * E T H E R N E T S T A T U S
- * ***************************************************************************
- */
-
-/*
- * MessageId: BE_ETH_TX_ERROR
- * The Ethernet device driver failed to transmit a packet.
- */
-#define BE_ETH_TX_ERROR (0xE0070101L)
-
-/*
- * ***************************************************************************
- * S H A R E D S T A T U S
- * ***************************************************************************
- */
-
-/*
- * MessageId: BE_STATUS_VBD_INVALID_VERSION
- * The device driver is not compatible with this version of the VBD.
- */
-#define BE_STATUS_INVALID_VERSION (0xE0070402L)
-/*
- * MessageId: BE_STATUS_DOMAIN_DENIED
- * The operation failed to complete due to insufficient access
- * rights for the requesting domain.
- */
-#define BE_STATUS_DOMAIN_DENIED (0xE0070403L)
-/*
- * MessageId: BE_STATUS_TCP_NOT_STARTED
- * The embedded TCP/IP stack has not been started.
- */
-#define BE_STATUS_TCP_NOT_STARTED (0xE0070409L)
-/*
- * MessageId: BE_STATUS_NO_MCC_WRB
- * No free MCC WRB are available for posting the request.
- */
-#define BE_STATUS_NO_MCC_WRB (0xE0070414L)
-
-#endif /* _BESTATUS_ */
diff --git a/drivers/staging/benet/cev.h b/drivers/staging/benet/cev.h
deleted file mode 100644
index 30996920a54..00000000000
--- a/drivers/staging/benet/cev.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __cev_amap_h__
-#define __cev_amap_h__
-#include "ep.h"
-
-/*
- * Host Interrupt Status Register 0. The first of four application
- * interrupt status registers. This register contains the interrupts
- * for Event Queues EQ0 through EQ31.
- */
-struct BE_CEV_ISR0_CSR_AMAP {
- u8 interrupt0; /* DWORD 0 */
- u8 interrupt1; /* DWORD 0 */
- u8 interrupt2; /* DWORD 0 */
- u8 interrupt3; /* DWORD 0 */
- u8 interrupt4; /* DWORD 0 */
- u8 interrupt5; /* DWORD 0 */
- u8 interrupt6; /* DWORD 0 */
- u8 interrupt7; /* DWORD 0 */
- u8 interrupt8; /* DWORD 0 */
- u8 interrupt9; /* DWORD 0 */
- u8 interrupt10; /* DWORD 0 */
- u8 interrupt11; /* DWORD 0 */
- u8 interrupt12; /* DWORD 0 */
- u8 interrupt13; /* DWORD 0 */
- u8 interrupt14; /* DWORD 0 */
- u8 interrupt15; /* DWORD 0 */
- u8 interrupt16; /* DWORD 0 */
- u8 interrupt17; /* DWORD 0 */
- u8 interrupt18; /* DWORD 0 */
- u8 interrupt19; /* DWORD 0 */
- u8 interrupt20; /* DWORD 0 */
- u8 interrupt21; /* DWORD 0 */
- u8 interrupt22; /* DWORD 0 */
- u8 interrupt23; /* DWORD 0 */
- u8 interrupt24; /* DWORD 0 */
- u8 interrupt25; /* DWORD 0 */
- u8 interrupt26; /* DWORD 0 */
- u8 interrupt27; /* DWORD 0 */
- u8 interrupt28; /* DWORD 0 */
- u8 interrupt29; /* DWORD 0 */
- u8 interrupt30; /* DWORD 0 */
- u8 interrupt31; /* DWORD 0 */
-} __packed;
-struct CEV_ISR0_CSR_AMAP {
- u32 dw[1];
-};
-
-/*
- * Host Interrupt Status Register 1. The second of four application
- * interrupt status registers. This register contains the interrupts
- * for Event Queues EQ32 through EQ63.
- */
-struct BE_CEV_ISR1_CSR_AMAP {
- u8 interrupt32; /* DWORD 0 */
- u8 interrupt33; /* DWORD 0 */
- u8 interrupt34; /* DWORD 0 */
- u8 interrupt35; /* DWORD 0 */
- u8 interrupt36; /* DWORD 0 */
- u8 interrupt37; /* DWORD 0 */
- u8 interrupt38; /* DWORD 0 */
- u8 interrupt39; /* DWORD 0 */
- u8 interrupt40; /* DWORD 0 */
- u8 interrupt41; /* DWORD 0 */
- u8 interrupt42; /* DWORD 0 */
- u8 interrupt43; /* DWORD 0 */
- u8 interrupt44; /* DWORD 0 */
- u8 interrupt45; /* DWORD 0 */
- u8 interrupt46; /* DWORD 0 */
- u8 interrupt47; /* DWORD 0 */
- u8 interrupt48; /* DWORD 0 */
- u8 interrupt49; /* DWORD 0 */
- u8 interrupt50; /* DWORD 0 */
- u8 interrupt51; /* DWORD 0 */
- u8 interrupt52; /* DWORD 0 */
- u8 interrupt53; /* DWORD 0 */
- u8 interrupt54; /* DWORD 0 */
- u8 interrupt55; /* DWORD 0 */
- u8 interrupt56; /* DWORD 0 */
- u8 interrupt57; /* DWORD 0 */
- u8 interrupt58; /* DWORD 0 */
- u8 interrupt59; /* DWORD 0 */
- u8 interrupt60; /* DWORD 0 */
- u8 interrupt61; /* DWORD 0 */
- u8 interrupt62; /* DWORD 0 */
- u8 interrupt63; /* DWORD 0 */
-} __packed;
-struct CEV_ISR1_CSR_AMAP {
- u32 dw[1];
-};
-/*
- * Host Interrupt Status Register 2. The third of four application
- * interrupt status registers. This register contains the interrupts
- * for Event Queues EQ64 through EQ95.
- */
-struct BE_CEV_ISR2_CSR_AMAP {
- u8 interrupt64; /* DWORD 0 */
- u8 interrupt65; /* DWORD 0 */
- u8 interrupt66; /* DWORD 0 */
- u8 interrupt67; /* DWORD 0 */
- u8 interrupt68; /* DWORD 0 */
- u8 interrupt69; /* DWORD 0 */
- u8 interrupt70; /* DWORD 0 */
- u8 interrupt71; /* DWORD 0 */
- u8 interrupt72; /* DWORD 0 */
- u8 interrupt73; /* DWORD 0 */
- u8 interrupt74; /* DWORD 0 */
- u8 interrupt75; /* DWORD 0 */
- u8 interrupt76; /* DWORD 0 */
- u8 interrupt77; /* DWORD 0 */
- u8 interrupt78; /* DWORD 0 */
- u8 interrupt79; /* DWORD 0 */
- u8 interrupt80; /* DWORD 0 */
- u8 interrupt81; /* DWORD 0 */
- u8 interrupt82; /* DWORD 0 */
- u8 interrupt83; /* DWORD 0 */
- u8 interrupt84; /* DWORD 0 */
- u8 interrupt85; /* DWORD 0 */
- u8 interrupt86; /* DWORD 0 */
- u8 interrupt87; /* DWORD 0 */
- u8 interrupt88; /* DWORD 0 */
- u8 interrupt89; /* DWORD 0 */
- u8 interrupt90; /* DWORD 0 */
- u8 interrupt91; /* DWORD 0 */
- u8 interrupt92; /* DWORD 0 */
- u8 interrupt93; /* DWORD 0 */
- u8 interrupt94; /* DWORD 0 */
- u8 interrupt95; /* DWORD 0 */
-} __packed;
-struct CEV_ISR2_CSR_AMAP {
- u32 dw[1];
-};
-
-/*
- * Host Interrupt Status Register 3. The fourth of four application
- * interrupt status registers. This register contains the interrupts
- * for Event Queues EQ96 through EQ127.
- */
-struct BE_CEV_ISR3_CSR_AMAP {
- u8 interrupt96; /* DWORD 0 */
- u8 interrupt97; /* DWORD 0 */
- u8 interrupt98; /* DWORD 0 */
- u8 interrupt99; /* DWORD 0 */
- u8 interrupt100; /* DWORD 0 */
- u8 interrupt101; /* DWORD 0 */
- u8 interrupt102; /* DWORD 0 */
- u8 interrupt103; /* DWORD 0 */
- u8 interrupt104; /* DWORD 0 */
- u8 interrupt105; /* DWORD 0 */
- u8 interrupt106; /* DWORD 0 */
- u8 interrupt107; /* DWORD 0 */
- u8 interrupt108; /* DWORD 0 */
- u8 interrupt109; /* DWORD 0 */
- u8 interrupt110; /* DWORD 0 */
- u8 interrupt111; /* DWORD 0 */
- u8 interrupt112; /* DWORD 0 */
- u8 interrupt113; /* DWORD 0 */
- u8 interrupt114; /* DWORD 0 */
- u8 interrupt115; /* DWORD 0 */
- u8 interrupt116; /* DWORD 0 */
- u8 interrupt117; /* DWORD 0 */
- u8 interrupt118; /* DWORD 0 */
- u8 interrupt119; /* DWORD 0 */
- u8 interrupt120; /* DWORD 0 */
- u8 interrupt121; /* DWORD 0 */
- u8 interrupt122; /* DWORD 0 */
- u8 interrupt123; /* DWORD 0 */
- u8 interrupt124; /* DWORD 0 */
- u8 interrupt125; /* DWORD 0 */
- u8 interrupt126; /* DWORD 0 */
- u8 interrupt127; /* DWORD 0 */
-} __packed;
-struct CEV_ISR3_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Completions and Events block Registers. */
-struct BE_CEV_CSRMAP_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[32]; /* DWORD 1 */
- u8 rsvd2[32]; /* DWORD 2 */
- u8 rsvd3[32]; /* DWORD 3 */
- struct BE_CEV_ISR0_CSR_AMAP isr0;
- struct BE_CEV_ISR1_CSR_AMAP isr1;
- struct BE_CEV_ISR2_CSR_AMAP isr2;
- struct BE_CEV_ISR3_CSR_AMAP isr3;
- u8 rsvd4[32]; /* DWORD 8 */
- u8 rsvd5[32]; /* DWORD 9 */
- u8 rsvd6[32]; /* DWORD 10 */
- u8 rsvd7[32]; /* DWORD 11 */
- u8 rsvd8[32]; /* DWORD 12 */
- u8 rsvd9[32]; /* DWORD 13 */
- u8 rsvd10[32]; /* DWORD 14 */
- u8 rsvd11[32]; /* DWORD 15 */
- u8 rsvd12[32]; /* DWORD 16 */
- u8 rsvd13[32]; /* DWORD 17 */
- u8 rsvd14[32]; /* DWORD 18 */
- u8 rsvd15[32]; /* DWORD 19 */
- u8 rsvd16[32]; /* DWORD 20 */
- u8 rsvd17[32]; /* DWORD 21 */
- u8 rsvd18[32]; /* DWORD 22 */
- u8 rsvd19[32]; /* DWORD 23 */
- u8 rsvd20[32]; /* DWORD 24 */
- u8 rsvd21[32]; /* DWORD 25 */
- u8 rsvd22[32]; /* DWORD 26 */
- u8 rsvd23[32]; /* DWORD 27 */
- u8 rsvd24[32]; /* DWORD 28 */
- u8 rsvd25[32]; /* DWORD 29 */
- u8 rsvd26[32]; /* DWORD 30 */
- u8 rsvd27[32]; /* DWORD 31 */
- u8 rsvd28[32]; /* DWORD 32 */
- u8 rsvd29[32]; /* DWORD 33 */
- u8 rsvd30[192]; /* DWORD 34 */
- u8 rsvd31[192]; /* DWORD 40 */
- u8 rsvd32[160]; /* DWORD 46 */
- u8 rsvd33[160]; /* DWORD 51 */
- u8 rsvd34[160]; /* DWORD 56 */
- u8 rsvd35[96]; /* DWORD 61 */
- u8 rsvd36[192][32]; /* DWORD 64 */
-} __packed;
-struct CEV_CSRMAP_AMAP {
- u32 dw[256];
-};
-
-#endif /* __cev_amap_h__ */
diff --git a/drivers/staging/benet/cq.c b/drivers/staging/benet/cq.c
deleted file mode 100644
index 65045864543..00000000000
--- a/drivers/staging/benet/cq.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include "hwlib.h"
-#include "bestatus.h"
-
-/*
- * Completion Queue Objects
- */
-/*
- *============================================================================
- * P U B L I C R O U T I N E S
- *============================================================================
- */
-
-/*
- This routine creates a completion queue based on the client completion
- queue configuration information.
-
-
- FunctionObject - Handle to a function object
- CqBaseVa - Base VA for a the CQ ring
- NumEntries - CEV_CQ_CNT_* values
- solEventEnable - 0 = All CQEs can generate Events if CQ is eventable
- 1 = only CQEs with solicited bit set are eventable
- eventable - Eventable CQ, generates interrupts.
- nodelay - 1 = Force interrupt, relevent if CQ eventable.
- Interrupt is asserted immediately after EQE
- write is confirmed, regardless of EQ Timer
- or watermark settings.
- wme - Enable watermark based coalescing
- wmThresh - High watermark(CQ fullness at which event
- or interrupt should be asserted). These are the
- CEV_WATERMARK encoded values.
- EqObject - EQ Handle to assign to this CQ
- ppCqObject - Internal CQ Handle returned.
-
- Returns BE_SUCCESS if successfull, otherwise a useful error code is
- returned.
-
- IRQL < DISPATCH_LEVEL
-
-*/
-int be_cq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length, bool solicited_eventable,
- bool no_delay, u32 wm_thresh,
- struct be_eq_object *eq_object, struct be_cq_object *cq_object)
-{
- int status = BE_SUCCESS;
- u32 num_entries_encoding;
- u32 num_entries = length / sizeof(struct MCC_CQ_ENTRY_AMAP);
- struct FWCMD_COMMON_CQ_CREATE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 n;
- unsigned long irql;
-
- ASSERT(rd);
- ASSERT(cq_object);
- ASSERT(length % sizeof(struct MCC_CQ_ENTRY_AMAP) == 0);
-
- switch (num_entries) {
- case 256:
- num_entries_encoding = CEV_CQ_CNT_256;
- break;
- case 512:
- num_entries_encoding = CEV_CQ_CNT_512;
- break;
- case 1024:
- num_entries_encoding = CEV_CQ_CNT_1024;
- break;
- default:
- ASSERT(0);
- return BE_STATUS_INVALID_PARAMETER;
- }
-
- /*
- * All cq entries all the same size. Use iSCSI version
- * as a test for the proper rd length.
- */
- memset(cq_object, 0, sizeof(*cq_object));
-
- atomic_set(&cq_object->ref_count, 0);
- cq_object->parent_function = pfob;
- cq_object->eq_object = eq_object;
- cq_object->num_entries = num_entries;
- /* save for MCC cq processing */
- cq_object->va = rd->va;
-
- /* map into UT. */
- length = num_entries * sizeof(struct MCC_CQ_ENTRY_AMAP);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_CQ_CREATE);
-
- fwcmd->params.request.num_pages = PAGES_SPANNED(OFFSET_IN_PAGE(rd->va),
- length);
-
- AMAP_SET_BITS_PTR(CQ_CONTEXT, valid, &fwcmd->params.request.context, 1);
- n = pfob->pci_function_number;
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Func, &fwcmd->params.request.context, n);
-
- n = (eq_object != NULL);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Eventable,
- &fwcmd->params.request.context, n);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Armed, &fwcmd->params.request.context, 1);
-
- n = eq_object ? eq_object->eq_id : 0;
- AMAP_SET_BITS_PTR(CQ_CONTEXT, EQID, &fwcmd->params.request.context, n);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Count,
- &fwcmd->params.request.context, num_entries_encoding);
-
- n = 0; /* Protection Domain is always 0 in Linux driver */
- AMAP_SET_BITS_PTR(CQ_CONTEXT, PD, &fwcmd->params.request.context, n);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, NoDelay,
- &fwcmd->params.request.context, no_delay);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, SolEvent,
- &fwcmd->params.request.context, solicited_eventable);
-
- n = (wm_thresh != 0xFFFFFFFF);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, WME, &fwcmd->params.request.context, n);
-
- n = (n ? wm_thresh : 0);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Watermark,
- &fwcmd->params.request.context, n);
- /* Create a page list for the FWCMD. */
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "MCC to create CQ failed.");
- goto Error;
- }
- /* Remember the CQ id. */
- cq_object->cq_id = fwcmd->params.response.cq_id;
-
- /* insert this cq into eq_object reference */
- if (eq_object) {
- atomic_inc(&eq_object->ref_count);
- list_add_tail(&cq_object->cqlist_for_eq,
- &eq_object->cq_list_head);
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
-
- Deferences the given object. Once the object's reference count drops to
- zero, the object is destroyed and all resources that are held by this object
- are released. The on-chip context is also destroyed along with the queue
- ID, and any mappings made into the UT.
-
- cq_object - CQ handle returned from cq_object_create.
-
- returns the current reference count on the object
-
- IRQL: IRQL < DISPATCH_LEVEL
-*/
-int be_cq_destroy(struct be_cq_object *cq_object)
-{
- int status = 0;
-
- /* Nothing should reference this CQ at this point. */
- ASSERT(atomic_read(&cq_object->ref_count) == 0);
-
- /* Send fwcmd to destroy the CQ. */
- status = be_function_ring_destroy(cq_object->parent_function,
- cq_object->cq_id, FWCMD_RING_TYPE_CQ,
- NULL, NULL, NULL, NULL);
- ASSERT(status == 0);
-
- /* Remove reference if this is an eventable CQ. */
- if (cq_object->eq_object) {
- atomic_dec(&cq_object->eq_object->ref_count);
- list_del(&cq_object->cqlist_for_eq);
- }
- return BE_SUCCESS;
-}
-
diff --git a/drivers/staging/benet/descriptors.h b/drivers/staging/benet/descriptors.h
deleted file mode 100644
index 8da438c407d..00000000000
--- a/drivers/staging/benet/descriptors.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __descriptors_amap_h__
-#define __descriptors_amap_h__
-
-/*
- * --- IPC_NODE_ID_ENUM ---
- * IPC processor id values
- */
-#define TPOST_NODE_ID (0) /* TPOST ID */
-#define TPRE_NODE_ID (1) /* TPRE ID */
-#define TXULP0_NODE_ID (2) /* TXULP0 ID */
-#define TXULP1_NODE_ID (3) /* TXULP1 ID */
-#define TXULP2_NODE_ID (4) /* TXULP2 ID */
-#define RXULP0_NODE_ID (5) /* RXULP0 ID */
-#define RXULP1_NODE_ID (6) /* RXULP1 ID */
-#define RXULP2_NODE_ID (7) /* RXULP2 ID */
-#define MPU_NODE_ID (15) /* MPU ID */
-
-/*
- * --- MAC_ID_ENUM ---
- * Meaning of the mac_id field in rxpp_eth_d
- */
-#define PORT0_HOST_MAC0 (0) /* PD 0, Port 0, host networking, MAC 0. */
-#define PORT0_HOST_MAC1 (1) /* PD 0, Port 0, host networking, MAC 1. */
-#define PORT0_STORAGE_MAC0 (2) /* PD 0, Port 0, host storage, MAC 0. */
-#define PORT0_STORAGE_MAC1 (3) /* PD 0, Port 0, host storage, MAC 1. */
-#define PORT1_HOST_MAC0 (4) /* PD 0, Port 1 host networking, MAC 0. */
-#define PORT1_HOST_MAC1 (5) /* PD 0, Port 1 host networking, MAC 1. */
-#define PORT1_STORAGE_MAC0 (6) /* PD 0, Port 1 host storage, MAC 0. */
-#define PORT1_STORAGE_MAC1 (7) /* PD 0, Port 1 host storage, MAC 1. */
-#define FIRST_VM_MAC (8) /* PD 1 MAC. Protection domains have IDs */
- /* from 0x8-0x26, one per PD. */
-#define LAST_VM_MAC (38) /* PD 31 MAC. */
-#define MGMT_MAC (39) /* Management port MAC. */
-#define MARBLE_MAC0 (59) /* Used for flushing function 0 receive */
- /*
- * queues before re-using a torn-down
- * receive ring. the DA =
- * 00-00-00-00-00-00, and the MSB of the
- * SA = 00
- */
-#define MARBLE_MAC1 (60) /* Used for flushing function 1 receive */
- /*
- * queues before re-using a torn-down
- * receive ring. the DA =
- * 00-00-00-00-00-00, and the MSB of the
- * SA != 00
- */
-#define NULL_MAC (61) /* Promiscuous mode, indicates no match */
-#define MCAST_MAC (62) /* Multicast match. */
-#define BCAST_MATCH (63) /* Broadcast match. */
-
-#endif /* __descriptors_amap_h__ */
diff --git a/drivers/staging/benet/doorbells.h b/drivers/staging/benet/doorbells.h
deleted file mode 100644
index 550cc4d5d6f..00000000000
--- a/drivers/staging/benet/doorbells.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __doorbells_amap_h__
-#define __doorbells_amap_h__
-
-/* The TX/RDMA send queue doorbell. */
-struct BE_SQ_DB_AMAP {
- u8 cid[11]; /* DWORD 0 */
- u8 rsvd0[5]; /* DWORD 0 */
- u8 numPosted[14]; /* DWORD 0 */
- u8 rsvd1[2]; /* DWORD 0 */
-} __packed;
-struct SQ_DB_AMAP {
- u32 dw[1];
-};
-
-/* The receive queue doorbell. */
-struct BE_RQ_DB_AMAP {
- u8 rq[10]; /* DWORD 0 */
- u8 rsvd0[13]; /* DWORD 0 */
- u8 Invalidate; /* DWORD 0 */
- u8 numPosted[8]; /* DWORD 0 */
-} __packed;
-struct RQ_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * The CQ/EQ doorbell. Software MUST set reserved fields in this
- * descriptor to zero, otherwise (CEV) hardware will not execute the
- * doorbell (flagging a bad_db_qid error instead).
- */
-struct BE_CQ_DB_AMAP {
- u8 qid[10]; /* DWORD 0 */
- u8 rsvd0[4]; /* DWORD 0 */
- u8 rearm; /* DWORD 0 */
- u8 event; /* DWORD 0 */
- u8 num_popped[13]; /* DWORD 0 */
- u8 rsvd1[3]; /* DWORD 0 */
-} __packed;
-struct CQ_DB_AMAP {
- u32 dw[1];
-};
-
-struct BE_TPM_RQ_DB_AMAP {
- u8 qid[10]; /* DWORD 0 */
- u8 rsvd0[6]; /* DWORD 0 */
- u8 numPosted[11]; /* DWORD 0 */
- u8 mss_cnt[5]; /* DWORD 0 */
-} __packed;
-struct TPM_RQ_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * Post WRB Queue Doorbell Register used by the host Storage stack
- * to notify the controller of a posted Work Request Block
- */
-struct BE_WRB_POST_DB_AMAP {
- u8 wrb_cid[10]; /* DWORD 0 */
- u8 rsvd0[6]; /* DWORD 0 */
- u8 wrb_index[8]; /* DWORD 0 */
- u8 numberPosted[8]; /* DWORD 0 */
-} __packed;
-struct WRB_POST_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * Update Default PDU Queue Doorbell Register used to communicate
- * to the controller that the driver has stopped processing the queue
- * and where in the queue it stopped, this is
- * a CQ Entry Type. Used by storage driver.
- */
-struct BE_DEFAULT_PDU_DB_AMAP {
- u8 qid[10]; /* DWORD 0 */
- u8 rsvd0[4]; /* DWORD 0 */
- u8 rearm; /* DWORD 0 */
- u8 event; /* DWORD 0 */
- u8 cqproc[14]; /* DWORD 0 */
- u8 rsvd1[2]; /* DWORD 0 */
-} __packed;
-struct DEFAULT_PDU_DB_AMAP {
- u32 dw[1];
-};
-
-/* Management Command and Controller default fragment ring */
-struct BE_MCC_DB_AMAP {
- u8 rid[11]; /* DWORD 0 */
- u8 rsvd0[5]; /* DWORD 0 */
- u8 numPosted[14]; /* DWORD 0 */
- u8 rsvd1[2]; /* DWORD 0 */
-} __packed;
-struct MCC_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * Used for bootstrapping the Host interface. This register is
- * used for driver communication with the MPU when no MCC Rings exist.
- * The software must write this register twice to post any MCC
- * command. First, it writes the register with hi=1 and the upper bits of
- * the physical address for the MCC_MAILBOX structure. Software must poll
- * the ready bit until this is acknowledged. Then, sotware writes the
- * register with hi=0 with the lower bits in the address. It must
- * poll the ready bit until the MCC command is complete. Upon completion,
- * the MCC_MAILBOX will contain a valid completion queue entry.
- */
-struct BE_MPU_MAILBOX_DB_AMAP {
- u8 ready; /* DWORD 0 */
- u8 hi; /* DWORD 0 */
- u8 address[30]; /* DWORD 0 */
-} __packed;
-struct MPU_MAILBOX_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * This is the protection domain doorbell register map. Note that
- * while this map shows doorbells for all Blade Engine supported
- * protocols, not all of these may be valid in a given function or
- * protection domain. It is the responsibility of the application
- * accessing the doorbells to know which are valid. Each doorbell
- * occupies 32 bytes of space, but unless otherwise specified,
- * only the first 4 bytes should be written. There are 32 instances
- * of these doorbells for the host and 31 virtual machines respectively.
- * The host and VMs will only map the doorbell pages belonging to its
- * protection domain. It will not be able to touch the doorbells for
- * another VM. The doorbells are the only registers directly accessible
- * by a virtual machine. Similarly, there are 511 additional
- * doorbells for RDMA protection domains. PD 0 for RDMA shares
- * the same physical protection domain doorbell page as ETH/iSCSI.
- *
- */
-struct BE_PROTECTION_DOMAIN_DBMAP_AMAP {
- u8 rsvd0[512]; /* DWORD 0 */
- struct BE_SQ_DB_AMAP rdma_sq_db;
- u8 rsvd1[7][32]; /* DWORD 17 */
- struct BE_WRB_POST_DB_AMAP iscsi_wrb_post_db;
- u8 rsvd2[7][32]; /* DWORD 25 */
- struct BE_SQ_DB_AMAP etx_sq_db;
- u8 rsvd3[7][32]; /* DWORD 33 */
- struct BE_RQ_DB_AMAP rdma_rq_db;
- u8 rsvd4[7][32]; /* DWORD 41 */
- struct BE_DEFAULT_PDU_DB_AMAP iscsi_default_pdu_db;
- u8 rsvd5[7][32]; /* DWORD 49 */
- struct BE_TPM_RQ_DB_AMAP tpm_rq_db;
- u8 rsvd6[7][32]; /* DWORD 57 */
- struct BE_RQ_DB_AMAP erx_rq_db;
- u8 rsvd7[7][32]; /* DWORD 65 */
- struct BE_CQ_DB_AMAP cq_db;
- u8 rsvd8[7][32]; /* DWORD 73 */
- struct BE_MCC_DB_AMAP mpu_mcc_db;
- u8 rsvd9[7][32]; /* DWORD 81 */
- struct BE_MPU_MAILBOX_DB_AMAP mcc_bootstrap_db;
- u8 rsvd10[935][32]; /* DWORD 89 */
-} __packed;
-struct PROTECTION_DOMAIN_DBMAP_AMAP {
- u32 dw[1024];
-};
-
-#endif /* __doorbells_amap_h__ */
diff --git a/drivers/staging/benet/ep.h b/drivers/staging/benet/ep.h
deleted file mode 100644
index 72fcf64a9ff..00000000000
--- a/drivers/staging/benet/ep.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __ep_amap_h__
-#define __ep_amap_h__
-
-/* General Control and Status Register. */
-struct BE_EP_CONTROL_CSR_AMAP {
- u8 m0_RxPbuf; /* DWORD 0 */
- u8 m1_RxPbuf; /* DWORD 0 */
- u8 m2_RxPbuf; /* DWORD 0 */
- u8 ff_en; /* DWORD 0 */
- u8 rsvd0[27]; /* DWORD 0 */
- u8 CPU_reset; /* DWORD 0 */
-} __packed;
-struct EP_CONTROL_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Semaphore Register. */
-struct BE_EP_SEMAPHORE_CSR_AMAP {
- u8 value[32]; /* DWORD 0 */
-} __packed;
-struct EP_SEMAPHORE_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Embedded Processor Specific Registers. */
-struct BE_EP_CSRMAP_AMAP {
- struct BE_EP_CONTROL_CSR_AMAP ep_control;
- u8 rsvd0[32]; /* DWORD 1 */
- u8 rsvd1[32]; /* DWORD 2 */
- u8 rsvd2[32]; /* DWORD 3 */
- u8 rsvd3[32]; /* DWORD 4 */
- u8 rsvd4[32]; /* DWORD 5 */
- u8 rsvd5[8][128]; /* DWORD 6 */
- u8 rsvd6[32]; /* DWORD 38 */
- u8 rsvd7[32]; /* DWORD 39 */
- u8 rsvd8[32]; /* DWORD 40 */
- u8 rsvd9[32]; /* DWORD 41 */
- u8 rsvd10[32]; /* DWORD 42 */
- struct BE_EP_SEMAPHORE_CSR_AMAP ep_semaphore;
- u8 rsvd11[32]; /* DWORD 44 */
- u8 rsvd12[19][32]; /* DWORD 45 */
-} __packed;
-struct EP_CSRMAP_AMAP {
- u32 dw[64];
-};
-
-#endif /* __ep_amap_h__ */
diff --git a/drivers/staging/benet/eq.c b/drivers/staging/benet/eq.c
deleted file mode 100644
index db92ccd8fed..00000000000
--- a/drivers/staging/benet/eq.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include "hwlib.h"
-#include "bestatus.h"
-/*
- This routine creates an event queue based on the client completion
- queue configuration information.
-
- FunctionObject - Handle to a function object
- EqBaseVa - Base VA for a the EQ ring
- SizeEncoding - The encoded size for the EQ entries. This value is
- either CEV_EQ_SIZE_4 or CEV_EQ_SIZE_16
- NumEntries - CEV_CQ_CNT_* values.
- Watermark - Enables watermark based coalescing. This parameter
- must be of the type CEV_WMARK_* if watermarks
- are enabled. If watermarks to to be disabled
- this value should be-1.
- TimerDelay - If a timer delay is enabled this value should be the
- time of the delay in 8 microsecond units. If
- delays are not used this parameter should be
- set to -1.
- ppEqObject - Internal EQ Handle returned.
-
- Returns BE_SUCCESS if successfull,, otherwise a useful error code
- is returned.
-
- IRQL < DISPATCH_LEVEL
-*/
-int
-be_eq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 eqe_size, u32 num_entries,
- u32 watermark, /* CEV_WMARK_* or -1 */
- u32 timer_delay, /* in 8us units, or -1 */
- struct be_eq_object *eq_object)
-{
- int status = BE_SUCCESS;
- u32 num_entries_encoding, eqe_size_encoding, length;
- struct FWCMD_COMMON_EQ_CREATE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 n;
- unsigned long irql;
-
- ASSERT(rd);
- ASSERT(eq_object);
-
- switch (num_entries) {
- case 256:
- num_entries_encoding = CEV_EQ_CNT_256;
- break;
- case 512:
- num_entries_encoding = CEV_EQ_CNT_512;
- break;
- case 1024:
- num_entries_encoding = CEV_EQ_CNT_1024;
- break;
- case 2048:
- num_entries_encoding = CEV_EQ_CNT_2048;
- break;
- case 4096:
- num_entries_encoding = CEV_EQ_CNT_4096;
- break;
- default:
- ASSERT(0);
- return BE_STATUS_INVALID_PARAMETER;
- }
-
- switch (eqe_size) {
- case 4:
- eqe_size_encoding = CEV_EQ_SIZE_4;
- break;
- case 16:
- eqe_size_encoding = CEV_EQ_SIZE_16;
- break;
- default:
- ASSERT(0);
- return BE_STATUS_INVALID_PARAMETER;
- }
-
- if ((eqe_size == 4 && num_entries < 1024) ||
- (eqe_size == 16 && num_entries == 4096)) {
- TRACE(DL_ERR, "Bad EQ size. eqe_size:%d num_entries:%d",
- eqe_size, num_entries);
- ASSERT(0);
- return BE_STATUS_INVALID_PARAMETER;
- }
-
- memset(eq_object, 0, sizeof(*eq_object));
-
- atomic_set(&eq_object->ref_count, 0);
- eq_object->parent_function = pfob;
- eq_object->eq_id = 0xFFFFFFFF;
-
- INIT_LIST_HEAD(&eq_object->cq_list_head);
-
- length = num_entries * eqe_size;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_EQ_CREATE);
-
- fwcmd->params.request.num_pages = PAGES_SPANNED(OFFSET_IN_PAGE(rd->va),
- length);
- n = pfob->pci_function_number;
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Func, &fwcmd->params.request.context, n);
-
- AMAP_SET_BITS_PTR(EQ_CONTEXT, valid, &fwcmd->params.request.context, 1);
-
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Size,
- &fwcmd->params.request.context, eqe_size_encoding);
-
- n = 0; /* Protection Domain is always 0 in Linux driver */
- AMAP_SET_BITS_PTR(EQ_CONTEXT, PD, &fwcmd->params.request.context, n);
-
- /* Let the caller ARM the EQ with the doorbell. */
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Armed, &fwcmd->params.request.context, 0);
-
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Count, &fwcmd->params.request.context,
- num_entries_encoding);
-
- n = pfob->pci_function_number * 32;
- AMAP_SET_BITS_PTR(EQ_CONTEXT, EventVect,
- &fwcmd->params.request.context, n);
- if (watermark != -1) {
- AMAP_SET_BITS_PTR(EQ_CONTEXT, WME,
- &fwcmd->params.request.context, 1);
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Watermark,
- &fwcmd->params.request.context, watermark);
- ASSERT(watermark <= CEV_WMARK_240);
- } else
- AMAP_SET_BITS_PTR(EQ_CONTEXT, WME,
- &fwcmd->params.request.context, 0);
- if (timer_delay != -1) {
- AMAP_SET_BITS_PTR(EQ_CONTEXT, TMR,
- &fwcmd->params.request.context, 1);
-
- ASSERT(timer_delay <= 250); /* max value according to EAS */
- timer_delay = min(timer_delay, (u32)250);
-
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Delay,
- &fwcmd->params.request.context, timer_delay);
- } else {
- AMAP_SET_BITS_PTR(EQ_CONTEXT, TMR,
- &fwcmd->params.request.context, 0);
- }
- /* Create a page list for the FWCMD. */
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
-
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "MCC to create EQ failed.");
- goto Error;
- }
- /* Get the EQ id. The MPU allocates the IDs. */
- eq_object->eq_id = fwcmd->params.response.eq_id;
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- Deferences the given object. Once the object's reference count drops to
- zero, the object is destroyed and all resources that are held by this
- object are released. The on-chip context is also destroyed along with
- the queue ID, and any mappings made into the UT.
-
- eq_object - EQ handle returned from eq_object_create.
-
- Returns BE_SUCCESS if successfull, otherwise a useful error code
- is returned.
-
- IRQL: IRQL < DISPATCH_LEVEL
-*/
-int be_eq_destroy(struct be_eq_object *eq_object)
-{
- int status = 0;
-
- ASSERT(atomic_read(&eq_object->ref_count) == 0);
- /* no CQs should reference this EQ now */
- ASSERT(list_empty(&eq_object->cq_list_head));
-
- /* Send fwcmd to destroy the EQ. */
- status = be_function_ring_destroy(eq_object->parent_function,
- eq_object->eq_id, FWCMD_RING_TYPE_EQ,
- NULL, NULL, NULL, NULL);
- ASSERT(status == 0);
-
- return BE_SUCCESS;
-}
-/*
- *---------------------------------------------------------------------------
- * Function: be_eq_modify_delay
- * Changes the EQ delay for a group of EQs.
- * num_eq - The number of EQs in the eq_array to adjust.
- * This also is the number of delay values in
- * the eq_delay_array.
- * eq_array - Array of struct be_eq_object pointers to adjust.
- * eq_delay_array - Array of "num_eq" timer delays in units
- * of microseconds. The be_eq_query_delay_range
- * fwcmd returns the resolution and range of
- * legal EQ delays.
- * cb -
- * cb_context -
- * q_ctxt - Optional. Pointer to a previously allocated
- * struct. If the MCC WRB ring is full, this
- * structure is used to queue the operation. It
- * will be posted to the MCC ring when space
- * becomes available. All queued commands will
- * be posted to the ring in the order they are
- * received. It is always valid to pass a pointer to
- * a generic be_generic_q_cntxt. However,
- * the specific context structs
- * are generally smaller than the generic struct.
- * return pend_status - BE_SUCCESS (0) on success.
- * BE_PENDING (postive value) if the FWCMD
- * completion is pending. Negative error code on failure.
- *-------------------------------------------------------------------------
- */
-int
-be_eq_modify_delay(struct be_function_object *pfob,
- u32 num_eq, struct be_eq_object **eq_array,
- u32 *eq_delay_array, mcc_wrb_cqe_callback cb,
- void *cb_context, struct be_eq_modify_delay_q_ctxt *q_ctxt)
-{
- struct FWCMD_COMMON_MODIFY_EQ_DELAY *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *gen_ctxt = NULL;
- u32 i;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- gen_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- gen_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_MODIFY_EQ_DELAY);
-
- ASSERT(num_eq > 0);
- ASSERT(num_eq <= ARRAY_SIZE(fwcmd->params.request.delay));
- fwcmd->params.request.num_eq = num_eq;
- for (i = 0; i < num_eq; i++) {
- fwcmd->params.request.delay[i].eq_id = eq_array[i]->eq_id;
- fwcmd->params.request.delay[i].delay_in_microseconds =
- eq_delay_array[i];
- }
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, gen_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, NULL);
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
diff --git a/drivers/staging/benet/eth.c b/drivers/staging/benet/eth.c
deleted file mode 100644
index f641b6260d0..00000000000
--- a/drivers/staging/benet/eth.c
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include <linux/if_ether.h>
-#include "hwlib.h"
-#include "bestatus.h"
-
-/*
- *---------------------------------------------------------
- * Function: be_eth_sq_create_ex
- * Creates an ethernet send ring - extended version with
- * additional parameters.
- * pfob -
- * rd - ring address
- * length_in_bytes -
- * type - The type of ring to create.
- * ulp - The requested ULP number for the ring.
- * This should be zero based, i.e. 0,1,2. This must
- * be valid NIC ULP based on the firmware config.
- * All doorbells for this ring must be sent to
- * this ULP. The first network ring allocated for
- * each ULP are higher performance than subsequent rings.
- * cq_object - cq object for completions
- * ex_parameters - Additional parameters (that may increase in
- * future revisions). These parameters are only used
- * for certain ring types -- see
- * struct be_eth_sq_parameters for details.
- * eth_sq -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *---------------------------------------------------------
- */
-int
-be_eth_sq_create_ex(struct be_function_object *pfob, struct ring_desc *rd,
- u32 length, u32 type, u32 ulp, struct be_cq_object *cq_object,
- struct be_eth_sq_parameters *ex_parameters,
- struct be_ethsq_object *eth_sq)
-{
- struct FWCMD_COMMON_ETH_TX_CREATE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- u32 n;
- unsigned long irql;
-
- ASSERT(rd);
- ASSERT(eth_sq);
- ASSERT(ex_parameters);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- memset(eth_sq, 0, sizeof(*eth_sq));
-
- eth_sq->parent_function = pfob;
- eth_sq->bid = 0xFFFFFFFF;
- eth_sq->cq_object = cq_object;
-
- /* Translate hwlib interface to arm interface. */
- switch (type) {
- case BE_ETH_TX_RING_TYPE_FORWARDING:
- type = ETH_TX_RING_TYPE_FORWARDING;
- break;
- case BE_ETH_TX_RING_TYPE_STANDARD:
- type = ETH_TX_RING_TYPE_STANDARD;
- break;
- case BE_ETH_TX_RING_TYPE_BOUND:
- ASSERT(ex_parameters->port < 2);
- type = ETH_TX_RING_TYPE_BOUND;
- break;
- default:
- TRACE(DL_ERR, "Invalid eth tx ring type:%d", type);
- return BE_NOT_OK;
- break;
- }
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* NIC must be supported by the current config. */
- ASSERT(pfob->fw_config.nic_ulp_mask);
-
- /*
- * The ulp parameter must select a valid NIC ULP
- * for the current config.
- */
- ASSERT((1 << ulp) & pfob->fw_config.nic_ulp_mask);
-
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_TX_CREATE);
- fwcmd->header.request.port_number = ex_parameters->port;
-
- AMAP_SET_BITS_PTR(ETX_CONTEXT, pd_id,
- &fwcmd->params.request.context, 0);
-
- n = be_ring_length_to_encoding(length, sizeof(struct ETH_WRB_AMAP));
- AMAP_SET_BITS_PTR(ETX_CONTEXT, tx_ring_size,
- &fwcmd->params.request.context, n);
-
- AMAP_SET_BITS_PTR(ETX_CONTEXT, cq_id_send,
- &fwcmd->params.request.context, cq_object->cq_id);
-
- n = pfob->pci_function_number;
- AMAP_SET_BITS_PTR(ETX_CONTEXT, func, &fwcmd->params.request.context, n);
-
- fwcmd->params.request.type = type;
- fwcmd->params.request.ulp_num = (1 << ulp);
- fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
- ASSERT(PAGES_SPANNED(rd->va, rd->length) >=
- fwcmd->params.request.num_pages);
-
- /* Create a page list for the FWCMD. */
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
-
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "MCC to create etx queue failed.");
- goto Error;
- }
- /* save the butler ID */
- eth_sq->bid = fwcmd->params.response.cid;
-
- /* add a reference to the corresponding CQ */
- atomic_inc(&cq_object->ref_count);
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-/*
- This routine destroys an ethernet send queue
-
- EthSq - EthSq Handle returned from EthSqCreate
-
- This function always return BE_SUCCESS.
-
- This function frees memory allocated by EthSqCreate for the EthSq Object.
-
-*/
-int be_eth_sq_destroy(struct be_ethsq_object *eth_sq)
-{
- int status = 0;
-
- /* Send fwcmd to destroy the queue. */
- status = be_function_ring_destroy(eth_sq->parent_function, eth_sq->bid,
- FWCMD_RING_TYPE_ETH_TX, NULL, NULL, NULL, NULL);
- ASSERT(status == 0);
-
- /* Derefence any associated CQs. */
- atomic_dec(&eth_sq->cq_object->ref_count);
- return status;
-}
-/*
- This routine attempts to set the transmit flow control parameters.
-
- FunctionObject - Handle to a function object
-
- txfc_enable - transmit flow control enable - true for
- enable, false for disable
-
- rxfc_enable - receive flow control enable - true for
- enable, false for disable
-
- Returns BE_SUCCESS if successfull, otherwise a useful int error
- code is returned.
-
- IRQL: < DISPATCH_LEVEL
-
- This function always fails in non-privileged machine context.
-*/
-int
-be_eth_set_flow_control(struct be_function_object *pfob,
- bool txfc_enable, bool rxfc_enable)
-{
- struct FWCMD_COMMON_SET_FLOW_CONTROL *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FLOW_CONTROL);
-
- fwcmd->params.request.rx_flow_control = rxfc_enable;
- fwcmd->params.request.tx_flow_control = txfc_enable;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "set flow control fwcmd failed.");
- goto error;
- }
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine attempts to get the transmit flow control parameters.
-
- pfob - Handle to a function object
-
- txfc_enable - transmit flow control enable - true for
- enable, false for disable
-
- rxfc_enable - receive flow control enable - true for enable,
- false for disable
-
- Returns BE_SUCCESS if successfull, otherwise a useful int error code
- is returned.
-
- IRQL: < DISPATCH_LEVEL
-
- This function always fails in non-privileged machine context.
-*/
-int
-be_eth_get_flow_control(struct be_function_object *pfob,
- bool *txfc_enable, bool *rxfc_enable)
-{
- struct FWCMD_COMMON_GET_FLOW_CONTROL *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FLOW_CONTROL);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "get flow control fwcmd failed.");
- goto error;
- }
-
- *txfc_enable = fwcmd->params.response.tx_flow_control;
- *rxfc_enable = fwcmd->params.response.rx_flow_control;
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- *---------------------------------------------------------
- * Function: be_eth_set_qos
- * This function sets the ethernet transmit Quality of Service (QoS)
- * characteristics of BladeEngine for the domain. All ethernet
- * transmit rings of the domain will evenly share the bandwidth.
- * The exeception to sharing is the host primary (super) ethernet
- * transmit ring as well as the host ethernet forwarding ring
- * for missed offload data.
- * pfob -
- * max_bps - the maximum bits per second in units of
- * 10 Mbps (valid 0-100)
- * max_pps - the maximum packets per second in units
- * of 1 Kpps (0 indicates no limit)
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *---------------------------------------------------------
- */
-int
-be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps)
-{
- struct FWCMD_COMMON_SET_QOS *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_QOS);
-
- /* Set fields in fwcmd */
- fwcmd->params.request.max_bits_per_second_NIC = max_bps;
- fwcmd->params.request.max_packets_per_second_NIC = max_pps;
- fwcmd->params.request.valid_flags = QOS_BITS_NIC | QOS_PKTS_NIC;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0)
- TRACE(DL_ERR, "network set qos fwcmd failed.");
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- *---------------------------------------------------------
- * Function: be_eth_get_qos
- * This function retrieves the ethernet transmit Quality of Service (QoS)
- * characteristics for the domain.
- * max_bps - the maximum bits per second in units of
- * 10 Mbps (valid 0-100)
- * max_pps - the maximum packets per second in units of
- * 1 Kpps (0 indicates no limit)
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *---------------------------------------------------------
- */
-int
-be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps)
-{
- struct FWCMD_COMMON_GET_QOS *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_QOS);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "network get qos fwcmd failed.");
- goto error;
- }
-
- *max_bps = fwcmd->params.response.max_bits_per_second_NIC;
- *max_pps = fwcmd->params.response.max_packets_per_second_NIC;
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- *---------------------------------------------------------
- * Function: be_eth_set_frame_size
- * This function sets the ethernet maximum frame size. The previous
- * values are returned.
- * pfob -
- * tx_frame_size - maximum transmit frame size in bytes
- * rx_frame_size - maximum receive frame size in bytes
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *---------------------------------------------------------
- */
-int
-be_eth_set_frame_size(struct be_function_object *pfob,
- u32 *tx_frame_size, u32 *rx_frame_size)
-{
- struct FWCMD_COMMON_SET_FRAME_SIZE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FRAME_SIZE);
- fwcmd->params.request.max_tx_frame_size = *tx_frame_size;
- fwcmd->params.request.max_rx_frame_size = *rx_frame_size;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "network set frame size fwcmd failed.");
- goto error;
- }
-
- *tx_frame_size = fwcmd->params.response.chip_max_tx_frame_size;
- *rx_frame_size = fwcmd->params.response.chip_max_rx_frame_size;
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-/*
- This routine creates a Ethernet receive ring.
-
- pfob - handle to a function object
- rq_base_va - base VA for the default receive ring. this must be
- exactly 8K in length and continguous physical memory.
- cq_object - handle to a previously created CQ to be associated
- with the RQ.
- pp_eth_rq - pointer to an opqaue handle where an eth
- receive object is returned.
- Returns BE_SUCCESS if successfull, , otherwise a useful
- int error code is returned.
-
- IRQL: < DISPATCH_LEVEL
- this function allocates a struct be_ethrq_object *object.
- there must be no more than 1 of these per function object, unless the
- function object supports RSS (is networking and on the host).
- the rq_base_va must point to a buffer of exactly 8K.
- the erx::host_cqid (or host_stor_cqid) register and erx::ring_page registers
- will be updated as appropriate on return
-*/
-int
-be_eth_rq_create(struct be_function_object *pfob,
- struct ring_desc *rd, struct be_cq_object *cq_object,
- struct be_cq_object *bcmc_cq_object,
- struct be_ethrq_object *eth_rq)
-{
- int status = 0;
- struct MCC_WRB_AMAP *wrb = NULL;
- struct FWCMD_COMMON_ETH_RX_CREATE *fwcmd = NULL;
- unsigned long irql;
-
- /* MPU will set the */
- ASSERT(rd);
- ASSERT(eth_rq);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- eth_rq->parent_function = pfob;
- eth_rq->cq_object = cq_object;
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_RX_CREATE);
-
- fwcmd->params.request.num_pages = 2; /* required length */
- fwcmd->params.request.cq_id = cq_object->cq_id;
-
- if (bcmc_cq_object)
- fwcmd->params.request.bcmc_cq_id = bcmc_cq_object->cq_id;
- else
- fwcmd->params.request.bcmc_cq_id = 0xFFFF;
-
- /* Create a page list for the FWCMD. */
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "fwcmd to map eth rxq frags failed.");
- goto Error;
- }
- /* Save the ring ID for cleanup. */
- eth_rq->rid = fwcmd->params.response.id;
-
- atomic_inc(&cq_object->ref_count);
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine destroys an Ethernet receive queue
-
- eth_rq - ethernet receive queue handle returned from eth_rq_create
-
- Returns BE_SUCCESS on success and an appropriate int on failure.
-
- This function frees resourcs allocated by EthRqCreate.
- The erx::host_cqid (or host_stor_cqid) register and erx::ring_page
- registers will be updated as appropriate on return
- IRQL: < DISPATCH_LEVEL
-*/
-
-static void be_eth_rq_destroy_internal_cb(void *context, int status,
- struct MCC_WRB_AMAP *wrb)
-{
- struct be_ethrq_object *eth_rq = (struct be_ethrq_object *) context;
-
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "Destroy eth rq failed in internal callback.\n");
- } else {
- /* Dereference any CQs associated with this queue. */
- atomic_dec(&eth_rq->cq_object->ref_count);
- }
-
- return;
-}
-
-int be_eth_rq_destroy(struct be_ethrq_object *eth_rq)
-{
- int status = BE_SUCCESS;
-
- /* Send fwcmd to destroy the RQ. */
- status = be_function_ring_destroy(eth_rq->parent_function,
- eth_rq->rid, FWCMD_RING_TYPE_ETH_RX, NULL, NULL,
- be_eth_rq_destroy_internal_cb, eth_rq);
-
- return status;
-}
-
-/*
- *---------------------------------------------------------------------------
- * Function: be_eth_rq_destroy_options
- * Destroys an ethernet receive ring with finer granularity options
- * than the standard be_eth_rq_destroy() API function.
- * eth_rq -
- * flush - Set to 1 to flush the ring, set to 0 to bypass the flush
- * cb - Callback function on completion
- * cb_context - Callback context
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *----------------------------------------------------------------------------
- */
-int
-be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush,
- mcc_wrb_cqe_callback cb, void *cb_context)
-{
- struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = BE_SUCCESS;
- struct be_function_object *pfob = NULL;
- unsigned long irql;
-
- pfob = eth_rq->parent_function;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- TRACE(DL_INFO, "Destroy eth_rq ring id:%d, flush:%d", eth_rq->rid,
- flush);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in destroy eth_rq ring.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY);
-
- fwcmd->params.request.id = eth_rq->rid;
- fwcmd->params.request.ring_type = FWCMD_RING_TYPE_ETH_RX;
- fwcmd->params.request.bypass_flush = ((0 == flush) ? 1 : 0);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context,
- be_eth_rq_destroy_internal_cb, eth_rq, fwcmd, NULL);
-
- if (status != BE_SUCCESS && status != BE_PENDING) {
- TRACE(DL_ERR, "eth_rq ring destroy failed. id:%d, flush:%d",
- eth_rq->rid, flush);
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine queries the frag size for erx.
-
- pfob - handle to a function object
-
- frag_size_bytes - erx frag size in bytes that is/was set.
-
- Returns BE_SUCCESS if successfull, otherwise a useful int error
- code is returned.
-
- IRQL: < DISPATCH_LEVEL
-
-*/
-int
-be_eth_rq_get_frag_size(struct be_function_object *pfob, u32 *frag_size_bytes)
-{
- struct FWCMD_ETH_GET_RX_FRAG_SIZE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- ASSERT(frag_size_bytes);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- return BE_STATUS_NO_MCC_WRB;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_GET_RX_FRAG_SIZE);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "get frag size fwcmd failed.");
- goto error;
- }
-
- *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2;
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine attempts to set the frag size for erx. If the frag size is
- already set, the attempt fails and the current frag size is returned.
-
- pfob - Handle to a function object
-
- frag_size - Erx frag size in bytes that is/was set.
-
- current_frag_size_bytes - Pointer to location where currrent frag
- is to be rturned
-
- Returns BE_SUCCESS if successfull, otherwise a useful int error
- code is returned.
-
- IRQL: < DISPATCH_LEVEL
-
- This function always fails in non-privileged machine context.
-*/
-int
-be_eth_rq_set_frag_size(struct be_function_object *pfob,
- u32 frag_size, u32 *frag_size_bytes)
-{
- struct FWCMD_ETH_SET_RX_FRAG_SIZE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- ASSERT(frag_size_bytes);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_SET_RX_FRAG_SIZE);
-
- ASSERT(frag_size >= 128 && frag_size <= 16 * 1024);
-
- /* This is the log2 of the fragsize. This is not the exact
- * ERX encoding. */
- fwcmd->params.request.new_fragsize_log2 = __ilog2_u32(frag_size);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "set frag size fwcmd failed.");
- goto error;
- }
-
- *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2;
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-/*
- This routine gets or sets a mac address for a domain
- given the port and mac.
-
- FunctionObject - Function object handle.
- port1 - Set to TRUE if this function will set/get the Port 1
- address. Only the host may set this to TRUE.
- mac1 - Set to TRUE if this function will set/get the
- MAC 1 address. Only the host may set this to TRUE.
- write - Set to TRUE if this function should write the mac address.
- mac_address - Buffer of the mac address to read or write.
-
- Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
-
- IRQL: < DISPATCH_LEVEL
-*/
-int be_rxf_mac_address_read_write(struct be_function_object *pfob,
- bool port1, /* VM must always set to false */
- bool mac1, /* VM must always set to false */
- bool mgmt, bool write,
- bool permanent, u8 *mac_address,
- mcc_wrb_cqe_callback cb, /* optional */
- void *cb_context) /* optional */
-{
- int status = BE_SUCCESS;
- union {
- struct FWCMD_COMMON_NTWK_MAC_QUERY *query;
- struct FWCMD_COMMON_NTWK_MAC_SET *set;
- } fwcmd = {NULL};
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 type = 0;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- ASSERT(mac_address);
-
- ASSERT(port1 == false);
- ASSERT(mac1 == false);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
-
- if (mgmt) {
- type = MAC_ADDRESS_TYPE_MANAGEMENT;
- } else {
- if (pfob->type == BE_FUNCTION_TYPE_NETWORK)
- type = MAC_ADDRESS_TYPE_NETWORK;
- else
- type = MAC_ADDRESS_TYPE_STORAGE;
- }
-
- if (write) {
- /* Prepares an embedded fwcmd, including
- * request/response sizes.
- */
- fwcmd.set = BE_PREPARE_EMBEDDED_FWCMD(pfob,
- wrb, COMMON_NTWK_MAC_SET);
-
- fwcmd.set->params.request.invalidate = 0;
- fwcmd.set->params.request.mac1 = (mac1 ? 1 : 0);
- fwcmd.set->params.request.port = (port1 ? 1 : 0);
- fwcmd.set->params.request.type = type;
-
- /* Copy the mac address to set. */
- fwcmd.set->params.request.mac.SizeOfStructure =
- sizeof(fwcmd.set->params.request.mac);
- memcpy(fwcmd.set->params.request.mac.MACAddress,
- mac_address, ETH_ALEN);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL,
- cb, cb_context, NULL, NULL, fwcmd.set, NULL);
-
- } else {
-
- /*
- * Prepares an embedded fwcmd, including
- * request/response sizes.
- */
- fwcmd.query = BE_PREPARE_EMBEDDED_FWCMD(pfob,
- wrb, COMMON_NTWK_MAC_QUERY);
-
- fwcmd.query->params.request.mac1 = (mac1 ? 1 : 0);
- fwcmd.query->params.request.port = (port1 ? 1 : 0);
- fwcmd.query->params.request.type = type;
- fwcmd.query->params.request.permanent = permanent;
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_MAC_QUERY,
- params.response.mac.MACAddress);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_MAC_QUERY,
- params.response.mac.MACAddress);
- rc.va = mac_address;
- /* Post the f/w command (with a copy for the response) */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb,
- cb_context, NULL, NULL, fwcmd.query, &rc);
- }
-
- if (status < 0) {
- TRACE(DL_ERR, "mac set/query failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine writes data to context memory.
-
- pfob - Function object handle.
- mac_table - Set to the 128-bit multicast address hash table.
-
- Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
-
- IRQL: < DISPATCH_LEVEL
-*/
-
-int be_rxf_multicast_config(struct be_function_object *pfob,
- bool promiscuous, u32 num, u8 *mac_table,
- mcc_wrb_cqe_callback cb, /* optional */
- void *cb_context,
- struct be_multicast_q_ctxt *q_ctxt)
-{
- int status = BE_SUCCESS;
- struct FWCMD_COMMON_NTWK_MULTICAST_SET *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
-
- ASSERT(num <= ARRAY_SIZE(fwcmd->params.request.mac));
-
- if (num > ARRAY_SIZE(fwcmd->params.request.mac)) {
- TRACE(DL_ERR, "Too many multicast addresses. BE supports %d.",
- (int) ARRAY_SIZE(fwcmd->params.request.mac));
- return BE_NOT_OK;
- }
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_MULTICAST_SET);
-
- fwcmd->params.request.promiscuous = promiscuous;
- if (!promiscuous) {
- fwcmd->params.request.num_mac = num;
- if (num > 0) {
- ASSERT(mac_table);
- memcpy(fwcmd->params.request.mac,
- mac_table, ETH_ALEN * num);
- }
- }
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, NULL);
- if (status < 0) {
- TRACE(DL_ERR, "multicast fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine adds or removes a vlan tag from the rxf table.
-
- FunctionObject - Function object handle.
- VLanTag - VLan tag to add or remove.
- Add - Set to TRUE if this will add a vlan tag
-
- Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
-
- IRQL: < DISPATCH_LEVEL
-*/
-int be_rxf_vlan_config(struct be_function_object *pfob,
- bool promiscuous, u32 num, u16 *vlan_tag_array,
- mcc_wrb_cqe_callback cb, /* optional */
- void *cb_context,
- struct be_vlan_q_ctxt *q_ctxt) /* optional */
-{
- int status = BE_SUCCESS;
- struct FWCMD_COMMON_NTWK_VLAN_CONFIG *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
-
- if (num > ARRAY_SIZE(fwcmd->params.request.vlan_tag)) {
- TRACE(DL_ERR, "Too many VLAN tags.");
- return BE_NOT_OK;
- }
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_VLAN_CONFIG);
-
- fwcmd->params.request.promiscuous = promiscuous;
- if (!promiscuous) {
- fwcmd->params.request.num_vlan = num;
-
- if (num > 0) {
- ASSERT(vlan_tag_array);
- memcpy(fwcmd->params.request.vlan_tag, vlan_tag_array,
- num * sizeof(vlan_tag_array[0]));
- }
- }
-
- /* Post the commadn */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, NULL);
- if (status < 0) {
- TRACE(DL_ERR, "vlan fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-int be_rxf_link_status(struct be_function_object *pfob,
- struct BE_LINK_STATUS *link_status,
- mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_link_status_q_ctxt *q_ctxt)
-{
- struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- ASSERT(link_status);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
-
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb,
- COMMON_NTWK_LINK_STATUS_QUERY);
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY,
- params.response);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY,
- params.response);
- rc.va = link_status;
- /* Post or queue the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, &rc);
-
- if (status < 0) {
- TRACE(DL_ERR, "link status fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-int
-be_rxf_query_eth_statistics(struct be_function_object *pfob,
- struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd,
- u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_nonembedded_q_ctxt *q_ctxt)
-{
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
-
- ASSERT(va_for_fwcmd);
- ASSERT(pa_for_fwcmd);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
-
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
-
- TRACE(DL_INFO, "Query eth stats. fwcmd va:%p pa:0x%08x_%08x",
- va_for_fwcmd, upper_32_bits(pa_for_fwcmd), (u32)pa_for_fwcmd);
-
- /* Prepares an embedded fwcmd, including request/response sizes. */
- va_for_fwcmd = BE_PREPARE_NONEMBEDDED_FWCMD(pfob, wrb,
- va_for_fwcmd, pa_for_fwcmd, ETH_GET_STATISTICS);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, va_for_fwcmd, NULL);
- if (status < 0) {
- TRACE(DL_ERR, "eth stats fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-int
-be_rxf_promiscuous(struct be_function_object *pfob,
- bool enable_port0, bool enable_port1,
- mcc_wrb_cqe_callback cb, void *cb_context,
- struct be_promiscuous_q_ctxt *q_ctxt)
-{
- struct FWCMD_ETH_PROMISCUOUS *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
-
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
-
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_PROMISCUOUS);
-
- fwcmd->params.request.port0_promiscuous = enable_port0;
- fwcmd->params.request.port1_promiscuous = enable_port1;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, NULL);
-
- if (status < 0) {
- TRACE(DL_ERR, "promiscuous fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-/*
- *-------------------------------------------------------------------------
- * Function: be_rxf_filter_config
- * Configures BladeEngine ethernet receive filter settings.
- * pfob -
- * settings - Pointer to the requested filter settings.
- * The response from BladeEngine will be placed back
- * in this structure.
- * cb - optional
- * cb_context - optional
- * q_ctxt - Optional. Pointer to a previously allocated struct.
- * If the MCC WRB ring is full, this structure is
- * used to queue the operation. It will be posted
- * to the MCC ring when space becomes available. All
- * queued commands will be posted to the ring in
- * the order they are received. It is always valid
- * to pass a pointer to a generic
- * be_generic_q_ctxt. However, the specific
- * context structs are generally smaller than
- * the generic struct.
- * return pend_status - BE_SUCCESS (0) on success.
- * BE_PENDING (postive value) if the FWCMD
- * completion is pending. Negative error code on failure.
- *---------------------------------------------------------------------------
- */
-int
-be_rxf_filter_config(struct be_function_object *pfob,
- struct NTWK_RX_FILTER_SETTINGS *settings,
- mcc_wrb_cqe_callback cb, void *cb_context,
- struct be_rxf_filter_q_ctxt *q_ctxt)
-{
- struct FWCMD_COMMON_NTWK_RX_FILTER *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- ASSERT(settings);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
-
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_RX_FILTER);
- memcpy(&fwcmd->params.request, settings, sizeof(*settings));
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_RX_FILTER,
- params.response);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_RX_FILTER,
- params.response);
- rc.va = settings;
- /* Post or queue the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, &rc);
-
- if (status < 0) {
- TRACE(DL_ERR, "RXF/ERX filter config fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
diff --git a/drivers/staging/benet/etx_context.h b/drivers/staging/benet/etx_context.h
deleted file mode 100644
index 554fbe5d127..00000000000
--- a/drivers/staging/benet/etx_context.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __etx_context_amap_h__
-#define __etx_context_amap_h__
-
-/* ETX ring context structure. */
-struct BE_ETX_CONTEXT_AMAP {
- u8 tx_cidx[11]; /* DWORD 0 */
- u8 rsvd0[5]; /* DWORD 0 */
- u8 rsvd1[16]; /* DWORD 0 */
- u8 tx_pidx[11]; /* DWORD 1 */
- u8 rsvd2; /* DWORD 1 */
- u8 tx_ring_size[4]; /* DWORD 1 */
- u8 pd_id[5]; /* DWORD 1 */
- u8 pd_id_not_valid; /* DWORD 1 */
- u8 cq_id_send[10]; /* DWORD 1 */
- u8 rsvd3[32]; /* DWORD 2 */
- u8 rsvd4[32]; /* DWORD 3 */
- u8 cur_bytes[32]; /* DWORD 4 */
- u8 max_bytes[32]; /* DWORD 5 */
- u8 time_stamp[32]; /* DWORD 6 */
- u8 rsvd5[11]; /* DWORD 7 */
- u8 func; /* DWORD 7 */
- u8 rsvd6[20]; /* DWORD 7 */
- u8 cur_txd_count[32]; /* DWORD 8 */
- u8 max_txd_count[32]; /* DWORD 9 */
- u8 rsvd7[32]; /* DWORD 10 */
- u8 rsvd8[32]; /* DWORD 11 */
- u8 rsvd9[32]; /* DWORD 12 */
- u8 rsvd10[32]; /* DWORD 13 */
- u8 rsvd11[32]; /* DWORD 14 */
- u8 rsvd12[32]; /* DWORD 15 */
-} __packed;
-struct ETX_CONTEXT_AMAP {
- u32 dw[16];
-};
-
-#endif /* __etx_context_amap_h__ */
diff --git a/drivers/staging/benet/funcobj.c b/drivers/staging/benet/funcobj.c
deleted file mode 100644
index 0f57eb58dae..00000000000
--- a/drivers/staging/benet/funcobj.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include "hwlib.h"
-#include "bestatus.h"
-
-
-int
-be_function_internal_query_firmware_config(struct be_function_object *pfob,
- struct BE_FIRMWARE_CONFIG *config)
-{
- struct FWCMD_COMMON_FIRMWARE_CONFIG *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_FIRMWARE_CONFIG);
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_FIRMWARE_CONFIG,
- params.response);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_FIRMWARE_CONFIG,
- params.response);
- rc.va = config;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL,
- NULL, NULL, NULL, fwcmd, &rc);
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This allocates and initializes a function object based on the information
- provided by upper layer drivers.
-
- Returns BE_SUCCESS on success and an appropriate int on failure.
-
- A function object represents a single BladeEngine (logical) PCI function.
- That is a function object either represents
- the networking side of BladeEngine or the iSCSI side of BladeEngine.
-
- This routine will also detect and create an appropriate PD object for the
- PCI function as needed.
-*/
-int
-be_function_object_create(u8 __iomem *csr_va, u8 __iomem *db_va,
- u8 __iomem *pci_va, u32 function_type,
- struct ring_desc *mailbox, struct be_function_object *pfob)
-{
- int status;
-
- ASSERT(pfob); /* not a magic assert */
- ASSERT(function_type <= 2);
-
- TRACE(DL_INFO, "Create function object. type:%s object:0x%p",
- (function_type == BE_FUNCTION_TYPE_ISCSI ? "iSCSI" :
- (function_type == BE_FUNCTION_TYPE_NETWORK ? "Network" :
- "Arm")), pfob);
-
- memset(pfob, 0, sizeof(*pfob));
-
- pfob->type = function_type;
- pfob->csr_va = csr_va;
- pfob->db_va = db_va;
- pfob->pci_va = pci_va;
-
- spin_lock_init(&pfob->cq_lock);
- spin_lock_init(&pfob->post_lock);
- spin_lock_init(&pfob->mcc_context_lock);
-
-
- pfob->pci_function_number = 1;
-
-
- pfob->emulate = false;
- TRACE(DL_NOTE, "Non-emulation mode");
- status = be_drive_POST(pfob);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "BladeEngine POST failed.");
- goto error;
- }
-
- /* Initialize the mailbox */
- status = be_mpu_init_mailbox(pfob, mailbox);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "Failed to initialize mailbox.");
- goto error;
- }
- /*
- * Cache the firmware config for ASSERTs in hwclib and later
- * driver queries.
- */
- status = be_function_internal_query_firmware_config(pfob,
- &pfob->fw_config);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "Failed to query firmware config.");
- goto error;
- }
-
-error:
- if (status != BE_SUCCESS) {
- /* No cleanup necessary */
- TRACE(DL_ERR, "Failed to create function.");
- memset(pfob, 0, sizeof(*pfob));
- }
- return status;
-}
-
-/*
- This routine drops the reference count on a given function object. Once
- the reference count falls to zero, the function object is destroyed and all
- resources held are freed.
-
- FunctionObject - The function object to drop the reference to.
-*/
-int be_function_object_destroy(struct be_function_object *pfob)
-{
- TRACE(DL_INFO, "Destroy pfob. Object:0x%p",
- pfob);
-
-
- ASSERT(pfob->mcc == NULL);
-
- return BE_SUCCESS;
-}
-
-int be_function_cleanup(struct be_function_object *pfob)
-{
- int status = 0;
- u32 isr;
- u32 host_intr;
- struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl;
-
-
- if (pfob->type == BE_FUNCTION_TYPE_NETWORK) {
- status = be_rxf_multicast_config(pfob, false, 0,
- NULL, NULL, NULL, NULL);
- ASSERT(status == BE_SUCCESS);
- }
- /* VLAN */
- status = be_rxf_vlan_config(pfob, false, 0, NULL, NULL, NULL, NULL);
- ASSERT(status == BE_SUCCESS);
- /*
- * MCC Queue -- Switches to mailbox mode. May want to destroy
- * all but the MCC CQ before this call if polling CQ is much better
- * performance than polling mailbox register.
- */
- if (pfob->mcc)
- status = be_mcc_ring_destroy(pfob->mcc);
- /*
- * If interrupts are disabled, clear any CEV interrupt assertions that
- * fired after we stopped processing EQs.
- */
- ctrl.dw[0] = PCICFG1_READ(pfob, host_timer_int_ctrl);
- host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR,
- hostintr, ctrl.dw);
- if (!host_intr)
- if (pfob->type == BE_FUNCTION_TYPE_NETWORK)
- isr = CSR_READ(pfob, cev.isr1);
- else
- isr = CSR_READ(pfob, cev.isr0);
- else
- /* This should never happen... */
- TRACE(DL_ERR, "function_cleanup called with interrupt enabled");
- /* Function object destroy */
- status = be_function_object_destroy(pfob);
- ASSERT(status == BE_SUCCESS);
-
- return status;
-}
-
-
-void *
-be_function_prepare_embedded_fwcmd(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, u32 payld_len, u32 request_length,
- u32 response_length, u32 opcode, u32 subsystem)
-{
- struct FWCMD_REQUEST_HEADER *header = NULL;
- u32 n;
-
- ASSERT(wrb);
-
- n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8;
- AMAP_SET_BITS_PTR(MCC_WRB, embedded, wrb, 1);
- AMAP_SET_BITS_PTR(MCC_WRB, payload_length, wrb, min(payld_len, n));
- header = (struct FWCMD_REQUEST_HEADER *)((u8 *)wrb + n);
-
- header->timeout = 0;
- header->domain = 0;
- header->request_length = max(request_length, response_length);
- header->opcode = opcode;
- header->subsystem = subsystem;
-
- return header;
-}
-
-void *
-be_function_prepare_nonembedded_fwcmd(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb,
- void *fwcmd_va, u64 fwcmd_pa,
- u32 payld_len,
- u32 request_length,
- u32 response_length,
- u32 opcode, u32 subsystem)
-{
- struct FWCMD_REQUEST_HEADER *header = NULL;
- u32 n;
- struct MCC_WRB_PAYLOAD_AMAP *plp;
-
- ASSERT(wrb);
- ASSERT(fwcmd_va);
-
- header = (struct FWCMD_REQUEST_HEADER *) fwcmd_va;
-
- AMAP_SET_BITS_PTR(MCC_WRB, embedded, wrb, 0);
- AMAP_SET_BITS_PTR(MCC_WRB, payload_length, wrb, payld_len);
-
- /*
- * Assume one fragment. The caller may override the SGL by
- * rewriting the 0th length and adding more entries. They
- * will also need to update the sge_count.
- */
- AMAP_SET_BITS_PTR(MCC_WRB, sge_count, wrb, 1);
-
- n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8;
- plp = (struct MCC_WRB_PAYLOAD_AMAP *)((u8 *)wrb + n);
- AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].length, plp, payld_len);
- AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].pa_lo, plp, (u32)fwcmd_pa);
- AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].pa_hi, plp,
- upper_32_bits(fwcmd_pa));
-
- header->timeout = 0;
- header->domain = 0;
- header->request_length = max(request_length, response_length);
- header->opcode = opcode;
- header->subsystem = subsystem;
-
- return header;
-}
-
-struct MCC_WRB_AMAP *
-be_function_peek_mcc_wrb(struct be_function_object *pfob)
-{
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 offset;
-
- if (pfob->mcc)
- wrb = _be_mpu_peek_ring_wrb(pfob->mcc, false);
- else {
- offset = offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8;
- wrb = (struct MCC_WRB_AMAP *) ((u8 *) pfob->mailbox.va +
- offset);
- }
-
- if (wrb)
- memset(wrb, 0, sizeof(struct MCC_WRB_AMAP));
-
- return wrb;
-}
-
-#if defined(BE_DEBUG)
-void be_function_debug_print_wrb(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, void *optional_fwcmd_va,
- struct be_mcc_wrb_context *wrb_context)
-{
-
- struct FWCMD_REQUEST_HEADER *header = NULL;
- u8 embedded;
- u32 n;
-
- embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, wrb);
-
- if (embedded) {
- n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8;
- header = (struct FWCMD_REQUEST_HEADER *)((u8 *)wrb + n);
- } else {
- header = (struct FWCMD_REQUEST_HEADER *) optional_fwcmd_va;
- }
-
- /* Save the completed count before posting for a debug assert. */
-
- if (header) {
- wrb_context->opcode = header->opcode;
- wrb_context->subsystem = header->subsystem;
-
- } else {
- wrb_context->opcode = 0;
- wrb_context->subsystem = 0;
- }
-}
-#else
-#define be_function_debug_print_wrb(a_, b_, c_, d_)
-#endif
-
-int
-be_function_post_mcc_wrb(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb,
- struct be_generic_q_ctxt *q_ctxt,
- mcc_wrb_cqe_callback cb, void *cb_context,
- mcc_wrb_cqe_callback internal_cb,
- void *internal_cb_context, void *optional_fwcmd_va,
- struct be_mcc_wrb_response_copy *rc)
-{
- int status;
- struct be_mcc_wrb_context *wrb_context = NULL;
- u64 *p;
-
- if (q_ctxt) {
- /* Initialize context. */
- q_ctxt->context.internal_cb = internal_cb;
- q_ctxt->context.internal_cb_context = internal_cb_context;
- q_ctxt->context.cb = cb;
- q_ctxt->context.cb_context = cb_context;
- if (rc) {
- q_ctxt->context.copy.length = rc->length;
- q_ctxt->context.copy.fwcmd_offset = rc->fwcmd_offset;
- q_ctxt->context.copy.va = rc->va;
- } else
- q_ctxt->context.copy.length = 0;
-
- q_ctxt->context.optional_fwcmd_va = optional_fwcmd_va;
-
- /* Queue this request */
- status = be_function_queue_mcc_wrb(pfob, q_ctxt);
-
- goto Error;
- }
- /*
- * Allocate a WRB context struct to hold the callback pointers,
- * status, etc. This is required if commands complete out of order.
- */
- wrb_context = _be_mcc_allocate_wrb_context(pfob);
- if (!wrb_context) {
- TRACE(DL_WARN, "Failed to allocate MCC WRB context.");
- status = BE_STATUS_SYSTEM_RESOURCES;
- goto Error;
- }
- /* Initialize context. */
- memset(wrb_context, 0, sizeof(*wrb_context));
- wrb_context->internal_cb = internal_cb;
- wrb_context->internal_cb_context = internal_cb_context;
- wrb_context->cb = cb;
- wrb_context->cb_context = cb_context;
- if (rc) {
- wrb_context->copy.length = rc->length;
- wrb_context->copy.fwcmd_offset = rc->fwcmd_offset;
- wrb_context->copy.va = rc->va;
- } else
- wrb_context->copy.length = 0;
- wrb_context->wrb = wrb;
-
- /*
- * Copy the context pointer into the WRB opaque tag field.
- * Verify assumption of 64-bit tag with a compile time assert.
- */
- p = (u64 *) ((u8 *)wrb + offsetof(struct BE_MCC_WRB_AMAP, tag)/8);
- *p = (u64)(size_t)wrb_context;
-
- /* Print info about this FWCMD for debug builds. */
- be_function_debug_print_wrb(pfob, wrb, optional_fwcmd_va, wrb_context);
-
- /*
- * issue the WRB to the MPU as appropriate
- */
- if (pfob->mcc) {
- /*
- * we're in WRB mode, pass to the mcc layer
- */
- status = _be_mpu_post_wrb_ring(pfob->mcc, wrb, wrb_context);
- } else {
- /*
- * we're in mailbox mode
- */
- status = _be_mpu_post_wrb_mailbox(pfob, wrb, wrb_context);
-
- /* mailbox mode always completes synchronously */
- ASSERT(status != BE_STATUS_PENDING);
- }
-
-Error:
-
- return status;
-}
-
-int
-be_function_ring_destroy(struct be_function_object *pfob,
- u32 id, u32 ring_type, mcc_wrb_cqe_callback cb,
- void *cb_context, mcc_wrb_cqe_callback internal_cb,
- void *internal_cb_context)
-{
-
- struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- TRACE(DL_INFO, "Destroy ring id:%d type:%d", id, ring_type);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in destroy ring.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY);
-
- fwcmd->params.request.id = id;
- fwcmd->params.request.ring_type = ring_type;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context,
- internal_cb, internal_cb_context, fwcmd, NULL);
- if (status != BE_SUCCESS && status != BE_PENDING) {
- TRACE(DL_ERR, "Ring destroy fwcmd failed. id:%d ring_type:%d",
- id, ring_type);
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-void
-be_rd_to_pa_list(struct ring_desc *rd, struct PHYS_ADDR *pa_list, u32 max_num)
-{
- u32 num_pages = PAGES_SPANNED(rd->va, rd->length);
- u32 i = 0;
- u64 pa = rd->pa;
- __le64 lepa;
-
- ASSERT(pa_list);
- ASSERT(pa);
-
- for (i = 0; i < min(num_pages, max_num); i++) {
- lepa = cpu_to_le64(pa);
- pa_list[i].lo = (u32)lepa;
- pa_list[i].hi = upper_32_bits(lepa);
- pa += PAGE_SIZE;
- }
-}
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: be_function_get_fw_version
- * Retrieves the firmware version on the adpater. If the callback is
- * NULL this call executes synchronously. If the callback is not NULL,
- * the returned status will be BE_PENDING if the command was issued
- * successfully.
- * pfob -
- * fwv - Pointer to response buffer if callback is NULL.
- * cb - Callback function invoked when the FWCMD completes.
- * cb_context - Passed to the callback function.
- * return pend_status - BE_SUCCESS (0) on success.
- * BE_PENDING (postive value) if the FWCMD
- * completion is pending. Negative error code on failure.
- *---------------------------------------------------------------------------
- */
-int
-be_function_get_fw_version(struct be_function_object *pfob,
- struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD *fwv,
- mcc_wrb_cqe_callback cb, void *cb_context)
-{
- int status = BE_SUCCESS;
- struct MCC_WRB_AMAP *wrb = NULL;
- struct FWCMD_COMMON_GET_FW_VERSION *fwcmd = NULL;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
-
- if (!cb && !fwv) {
- TRACE(DL_ERR, "callback and response buffer NULL!");
- status = BE_NOT_OK;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FW_VERSION);
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_GET_FW_VERSION,
- params.response);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_GET_FW_VERSION,
- params.response);
- rc.va = fwv;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb,
- cb_context, NULL, NULL, fwcmd, &rc);
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-int
-be_function_queue_mcc_wrb(struct be_function_object *pfob,
- struct be_generic_q_ctxt *q_ctxt)
-{
- int status;
-
- ASSERT(q_ctxt);
-
- /*
- * issue the WRB to the MPU as appropriate
- */
- if (pfob->mcc) {
-
- /* We're in ring mode. Queue this item. */
- pfob->mcc->backlog_length++;
- list_add_tail(&q_ctxt->context.list, &pfob->mcc->backlog);
- status = BE_PENDING;
- } else {
- status = BE_NOT_OK;
- }
- return status;
-}
-
diff --git a/drivers/staging/benet/fwcmd_common.h b/drivers/staging/benet/fwcmd_common.h
deleted file mode 100644
index 406e0d6fa98..00000000000
--- a/drivers/staging/benet/fwcmd_common.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_common_amap_h__
-#define __fwcmd_common_amap_h__
-#include "host_struct.h"
-
-/* --- PHY_LINK_DUPLEX_ENUM --- */
-#define PHY_LINK_DUPLEX_NONE (0)
-#define PHY_LINK_DUPLEX_HALF (1)
-#define PHY_LINK_DUPLEX_FULL (2)
-
-/* --- PHY_LINK_SPEED_ENUM --- */
-#define PHY_LINK_SPEED_ZERO (0) /* No link. */
-#define PHY_LINK_SPEED_10MBPS (1) /* 10 Mbps */
-#define PHY_LINK_SPEED_100MBPS (2) /* 100 Mbps */
-#define PHY_LINK_SPEED_1GBPS (3) /* 1 Gbps */
-#define PHY_LINK_SPEED_10GBPS (4) /* 10 Gbps */
-
-/* --- PHY_LINK_FAULT_ENUM --- */
-#define PHY_LINK_FAULT_NONE (0) /* No fault status
- available or detected */
-#define PHY_LINK_FAULT_LOCAL (1) /* Local fault detected */
-#define PHY_LINK_FAULT_REMOTE (2) /* Remote fault detected */
-
-/* --- BE_ULP_MASK --- */
-#define BE_ULP0_MASK (1)
-#define BE_ULP1_MASK (2)
-#define BE_ULP2_MASK (4)
-
-/* --- NTWK_ACTIVE_PORT --- */
-#define NTWK_PORT_A (0) /* Port A is currently active */
-#define NTWK_PORT_B (1) /* Port B is currently active */
-#define NTWK_NO_ACTIVE_PORT (15) /* Both ports have lost link */
-
-/* --- NTWK_LINK_TYPE --- */
-#define NTWK_LINK_TYPE_PHYSICAL (0) /* link up/down event
- applies to BladeEngine's
- Physical Ports
- */
-#define NTWK_LINK_TYPE_VIRTUAL (1) /* Virtual link up/down event
- reported by BladeExchange.
- This applies only when the
- VLD feature is enabled
- */
-
-/*
- * --- FWCMD_MAC_TYPE_ENUM ---
- * This enum defines the types of MAC addresses in the RXF MAC Address Table.
- */
-#define MAC_ADDRESS_TYPE_STORAGE (0) /* Storage MAC Address */
-#define MAC_ADDRESS_TYPE_NETWORK (1) /* Network MAC Address */
-#define MAC_ADDRESS_TYPE_PD (2) /* Protection Domain MAC Addr */
-#define MAC_ADDRESS_TYPE_MANAGEMENT (3) /* Managment MAC Address */
-
-
-/* --- FWCMD_RING_TYPE_ENUM --- */
-#define FWCMD_RING_TYPE_ETH_RX (1) /* Ring created with */
- /* FWCMD_COMMON_ETH_RX_CREATE. */
-#define FWCMD_RING_TYPE_ETH_TX (2) /* Ring created with */
- /* FWCMD_COMMON_ETH_TX_CREATE. */
-#define FWCMD_RING_TYPE_ISCSI_WRBQ (3) /* Ring created with */
- /* FWCMD_COMMON_ISCSI_WRBQ_CREATE. */
-#define FWCMD_RING_TYPE_ISCSI_DEFQ (4) /* Ring created with */
- /* FWCMD_COMMON_ISCSI_DEFQ_CREATE. */
-#define FWCMD_RING_TYPE_TPM_WRBQ (5) /* Ring created with */
- /* FWCMD_COMMON_TPM_WRBQ_CREATE. */
-#define FWCMD_RING_TYPE_TPM_DEFQ (6) /* Ring created with */
- /* FWCMD_COMMONTPM_TDEFQ_CREATE. */
-#define FWCMD_RING_TYPE_TPM_RQ (7) /* Ring created with */
- /* FWCMD_COMMON_TPM_RQ_CREATE. */
-#define FWCMD_RING_TYPE_MCC (8) /* Ring created with */
- /* FWCMD_COMMON_MCC_CREATE. */
-#define FWCMD_RING_TYPE_CQ (9) /* Ring created with */
- /* FWCMD_COMMON_CQ_CREATE. */
-#define FWCMD_RING_TYPE_EQ (10) /* Ring created with */
- /* FWCMD_COMMON_EQ_CREATE. */
-#define FWCMD_RING_TYPE_QP (11) /* Ring created with */
- /* FWCMD_RDMA_QP_CREATE. */
-
-
-/* --- ETH_TX_RING_TYPE_ENUM --- */
-#define ETH_TX_RING_TYPE_FORWARDING (1) /* Ethernet ring for
- forwarding packets */
-#define ETH_TX_RING_TYPE_STANDARD (2) /* Ethernet ring for sending
- network packets. */
-#define ETH_TX_RING_TYPE_BOUND (3) /* Ethernet ring bound to the
- port specified in the command
- header.port_number field.
- Rings of this type are
- NOT subject to the
- failover logic implemented
- in the BladeEngine.
- */
-
-/* --- FWCMD_COMMON_QOS_TYPE_ENUM --- */
-#define QOS_BITS_NIC (1) /* max_bits_per_second_NIC */
- /* field is valid. */
-#define QOS_PKTS_NIC (2) /* max_packets_per_second_NIC */
- /* field is valid. */
-#define QOS_IOPS_ISCSI (4) /* max_ios_per_second_iSCSI */
- /*field is valid. */
-#define QOS_VLAN_TAG (8) /* domain_VLAN_tag field
- is valid. */
-#define QOS_FABRIC_ID (16) /* fabric_domain_ID field
- is valid. */
-#define QOS_OEM_PARAMS (32) /* qos_params_oem field
- is valid. */
-#define QOS_TPUT_ISCSI (64) /* max_bytes_per_second_iSCSI
- field is valid. */
-
-
-/*
- * --- FAILOVER_CONFIG_ENUM ---
- * Failover configuration setting used in FWCMD_COMMON_FORCE_FAILOVER
- */
-#define FAILOVER_CONFIG_NO_CHANGE (0) /* No change to automatic */
- /* port failover setting. */
-#define FAILOVER_CONFIG_ON (1) /* Automatic port failover
- on link down is enabled. */
-#define FAILOVER_CONFIG_OFF (2) /* Automatic port failover
- on link down is disabled. */
-
-/*
- * --- FAILOVER_PORT_ENUM ---
- * Failover port setting used in FWCMD_COMMON_FORCE_FAILOVER
- */
-#define FAILOVER_PORT_A (0) /* Selects port A. */
-#define FAILOVER_PORT_B (1) /* Selects port B. */
-#define FAILOVER_PORT_NONE (15) /* No port change requested. */
-
-
-/*
- * --- MGMT_FLASHROM_OPCODE ---
- * Flash ROM operation code
- */
-#define MGMT_FLASHROM_OPCODE_FLASH (1) /* Commit downloaded data
- to Flash ROM */
-#define MGMT_FLASHROM_OPCODE_SAVE (2) /* Save downloaded data to
- ARM's DDR - do not flash */
-#define MGMT_FLASHROM_OPCODE_CLEAR (3) /* Erase specified component
- from FlashROM */
-#define MGMT_FLASHROM_OPCODE_REPORT (4) /* Read specified component
- from Flash ROM */
-#define MGMT_FLASHROM_OPCODE_IMAGE_INFO (5) /* Returns size of a
- component */
-
-/*
- * --- MGMT_FLASHROM_OPTYPE ---
- * Flash ROM operation type
- */
-#define MGMT_FLASHROM_OPTYPE_CODE_FIRMWARE (0) /* Includes ARM firmware,
- IPSec (optional) and EP
- firmware */
-#define MGMT_FLASHROM_OPTYPE_CODE_REDBOOT (1)
-#define MGMT_FLASHROM_OPTYPE_CODE_BIOS (2)
-#define MGMT_FLASHROM_OPTYPE_CODE_PXE_BIOS (3)
-#define MGMT_FLASHROM_OPTYPE_CODE_CTRLS (4)
-#define MGMT_FLASHROM_OPTYPE_CFG_IPSEC (5)
-#define MGMT_FLASHROM_OPTYPE_CFG_INI (6)
-#define MGMT_FLASHROM_OPTYPE_ROM_OFFSET_SPECIFIED (7)
-
-/*
- * --- FLASHROM_TYPE ---
- * Flash ROM manufacturers supported in the f/w
- */
-#define INTEL (0)
-#define SPANSION (1)
-#define MICRON (2)
-
-/* --- DDR_CAS_TYPE --- */
-#define CAS_3 (0)
-#define CAS_4 (1)
-#define CAS_5 (2)
-
-/* --- DDR_SIZE_TYPE --- */
-#define SIZE_256MB (0)
-#define SIZE_512MB (1)
-
-/* --- DDR_MODE_TYPE --- */
-#define DDR_NO_ECC (0)
-#define DDR_ECC (1)
-
-/* --- INTERFACE_10GB_TYPE --- */
-#define CX4_TYPE (0)
-#define XFP_TYPE (1)
-
-/* --- BE_CHIP_MAX_MTU --- */
-#define CHIP_MAX_MTU (9000)
-
-/* --- XAUI_STATE_ENUM --- */
-#define XAUI_STATE_ENABLE (0) /* This MUST be the default
- value for all requests
- which set/change
- equalization parameter. */
-#define XAUI_STATE_DISABLE (255) /* The XAUI for both ports
- may be disabled for EMI
- tests. There is no
- provision for turning off
- individual ports.
- */
-/* --- BE_ASIC_REVISION --- */
-#define BE_ASIC_REV_A0 (1)
-#define BE_ASIC_REV_A1 (2)
-
-#endif /* __fwcmd_common_amap_h__ */
diff --git a/drivers/staging/benet/fwcmd_common_bmap.h b/drivers/staging/benet/fwcmd_common_bmap.h
deleted file mode 100644
index a007cf27650..00000000000
--- a/drivers/staging/benet/fwcmd_common_bmap.h
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_common_bmap_h__
-#define __fwcmd_common_bmap_h__
-#include "fwcmd_types_bmap.h"
-#include "fwcmd_hdr_bmap.h"
-
-#if defined(__BIG_ENDIAN)
- /* Physical Address. */
-struct PHYS_ADDR {
- union {
- struct {
- u32 lo; /* DWORD 0 */
- u32 hi; /* DWORD 1 */
- } __packed; /* unnamed struct */
- u32 dw[2]; /* dword union */
- }; /* unnamed union */
-} __packed ;
-
-
-#else
- /* Physical Address. */
-struct PHYS_ADDR {
- union {
- struct {
- u32 lo; /* DWORD 0 */
- u32 hi; /* DWORD 1 */
- } __packed; /* unnamed struct */
- u32 dw[2]; /* dword union */
- }; /* unnamed union */
-} __packed ;
-
-struct BE_LINK_STATUS {
- u8 mac0_duplex;
- u8 mac0_speed;
- u8 mac1_duplex;
- u8 mac1_speed;
- u8 mgmt_mac_duplex;
- u8 mgmt_mac_speed;
- u8 active_port;
- u8 rsvd0;
- u8 mac0_fault;
- u8 mac1_fault;
- u16 rsvd1;
-} __packed;
-#endif
-
-struct FWCMD_COMMON_ANON_170_REQUEST {
- u32 rsvd0;
-} __packed;
-
-union LINK_STATUS_QUERY_PARAMS {
- struct BE_LINK_STATUS response;
- struct FWCMD_COMMON_ANON_170_REQUEST request;
-} __packed;
-
-/*
- * Queries the the link status for all ports. The valid values below
- * DO NOT indicate that a particular duplex or speed is supported by
- * BladeEngine. These enumerations simply list all possible duplexes
- * and speeds for any port. Consult BladeEngine product documentation
- * for the supported parameters.
- */
-struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY {
- union FWCMD_HEADER header;
- union LINK_STATUS_QUERY_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_171_REQUEST {
- u8 type;
- u8 port;
- u8 mac1;
- u8 permanent;
-} __packed;
-
-struct FWCMD_COMMON_ANON_172_RESPONSE {
- struct MAC_ADDRESS_FORMAT mac;
-} __packed;
-
-union NTWK_MAC_QUERY_PARAMS {
- struct FWCMD_COMMON_ANON_171_REQUEST request;
- struct FWCMD_COMMON_ANON_172_RESPONSE response;
-} __packed;
-
-/* Queries one MAC address. */
-struct FWCMD_COMMON_NTWK_MAC_QUERY {
- union FWCMD_HEADER header;
- union NTWK_MAC_QUERY_PARAMS params;
-} __packed;
-
-struct MAC_SET_PARAMS_IN {
- u8 type;
- u8 port;
- u8 mac1;
- u8 invalidate;
- struct MAC_ADDRESS_FORMAT mac;
-} __packed;
-
-struct MAC_SET_PARAMS_OUT {
- u32 rsvd0;
-} __packed;
-
-union MAC_SET_PARAMS {
- struct MAC_SET_PARAMS_IN request;
- struct MAC_SET_PARAMS_OUT response;
-} __packed;
-
-/* Sets a MAC address. */
-struct FWCMD_COMMON_NTWK_MAC_SET {
- union FWCMD_HEADER header;
- union MAC_SET_PARAMS params;
-} __packed;
-
-/* MAC address list. */
-struct NTWK_MULTICAST_MAC_LIST {
- u8 byte[6];
-} __packed;
-
-struct FWCMD_COMMON_NTWK_MULTICAST_SET_REQUEST_PAYLOAD {
- u16 num_mac;
- u8 promiscuous;
- u8 rsvd0;
- struct NTWK_MULTICAST_MAC_LIST mac[32];
-} __packed;
-
-struct FWCMD_COMMON_ANON_174_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_173_PARAMS {
- struct FWCMD_COMMON_NTWK_MULTICAST_SET_REQUEST_PAYLOAD request;
- struct FWCMD_COMMON_ANON_174_RESPONSE response;
-} __packed;
-
-/*
- * Sets multicast address hash. The MPU will merge the MAC address lists
- * from all clients, including the networking and storage functions.
- * This command may fail if the final merged list of MAC addresses exceeds
- * 32 entries.
- */
-struct FWCMD_COMMON_NTWK_MULTICAST_SET {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_173_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_NTWK_VLAN_CONFIG_REQUEST_PAYLOAD {
- u16 num_vlan;
- u8 promiscuous;
- u8 rsvd0;
- u16 vlan_tag[32];
-} __packed;
-
-struct FWCMD_COMMON_ANON_176_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_175_PARAMS {
- struct FWCMD_COMMON_NTWK_VLAN_CONFIG_REQUEST_PAYLOAD request;
- struct FWCMD_COMMON_ANON_176_RESPONSE response;
-} __packed;
-
-/*
- * Sets VLAN tag filter. The MPU will merge the VLAN tag list from all
- * clients, including the networking and storage functions. This command
- * may fail if the final vlan_tag array (from all functions) is longer
- * than 32 entries.
- */
-struct FWCMD_COMMON_NTWK_VLAN_CONFIG {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_175_PARAMS params;
-} __packed;
-
-struct RING_DESTROY_REQUEST {
- u16 ring_type;
- u16 id;
- u8 bypass_flush;
- u8 rsvd0;
- u16 rsvd1;
-} __packed;
-
-struct FWCMD_COMMON_ANON_190_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_189_PARAMS {
- struct RING_DESTROY_REQUEST request;
- struct FWCMD_COMMON_ANON_190_RESPONSE response;
-} __packed;
-/*
- * Command for destroying any ring. The connection(s) using the ring should
- * be quiesced before destroying the ring.
- */
-struct FWCMD_COMMON_RING_DESTROY {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_189_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_192_REQUEST {
- u16 num_pages;
- u16 rsvd0;
- struct CQ_CONTEXT_AMAP context;
- struct PHYS_ADDR pages[4];
-} __packed ;
-
-struct FWCMD_COMMON_ANON_193_RESPONSE {
- u16 cq_id;
-} __packed ;
-
-union FWCMD_COMMON_ANON_191_PARAMS {
- struct FWCMD_COMMON_ANON_192_REQUEST request;
- struct FWCMD_COMMON_ANON_193_RESPONSE response;
-} __packed ;
-
-/*
- * Command for creating a completion queue. A Completion Queue must span
- * at least 1 page and at most 4 pages. Each completion queue entry
- * is 16 bytes regardless of CQ entry format. Thus the ring must be
- * at least 256 entries deep (corresponding to 1 page) and can be at
- * most 1024 entries deep (corresponding to 4 pages). The number of
- * pages posted must contain the CQ ring size as encoded in the context.
- *
- */
-struct FWCMD_COMMON_CQ_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_191_PARAMS params;
-} __packed ;
-
-struct FWCMD_COMMON_ANON_198_REQUEST {
- u16 num_pages;
- u16 rsvd0;
- struct EQ_CONTEXT_AMAP context;
- struct PHYS_ADDR pages[8];
-} __packed ;
-
-struct FWCMD_COMMON_ANON_199_RESPONSE {
- u16 eq_id;
-} __packed ;
-
-union FWCMD_COMMON_ANON_197_PARAMS {
- struct FWCMD_COMMON_ANON_198_REQUEST request;
- struct FWCMD_COMMON_ANON_199_RESPONSE response;
-} __packed ;
-
-/*
- * Command for creating a event queue. An Event Queue must span at least
- * 1 page and at most 8 pages. The number of pages posted must contain
- * the EQ ring. The ring is defined by the size of the EQ entries (encoded
- * in the context) and the number of EQ entries (also encoded in the
- * context).
- */
-struct FWCMD_COMMON_EQ_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_197_PARAMS params;
-} __packed ;
-
-struct FWCMD_COMMON_ANON_201_REQUEST {
- u16 cq_id;
- u16 bcmc_cq_id;
- u16 num_pages;
- u16 rsvd0;
- struct PHYS_ADDR pages[2];
-} __packed;
-
-struct FWCMD_COMMON_ANON_202_RESPONSE {
- u16 id;
-} __packed;
-
-union FWCMD_COMMON_ANON_200_PARAMS {
- struct FWCMD_COMMON_ANON_201_REQUEST request;
- struct FWCMD_COMMON_ANON_202_RESPONSE response;
-} __packed;
-
-/*
- * Command for creating Ethernet receive ring. An ERX ring contains ETH_RX_D
- * entries (8 bytes each). An ERX ring must be 1024 entries deep
- * (corresponding to 2 pages).
- */
-struct FWCMD_COMMON_ETH_RX_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_200_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_204_REQUEST {
- u16 num_pages;
- u8 ulp_num;
- u8 type;
- struct ETX_CONTEXT_AMAP context;
- struct PHYS_ADDR pages[8];
-} __packed ;
-
-struct FWCMD_COMMON_ANON_205_RESPONSE {
- u16 cid;
- u8 ulp_num;
- u8 rsvd0;
-} __packed ;
-
-union FWCMD_COMMON_ANON_203_PARAMS {
- struct FWCMD_COMMON_ANON_204_REQUEST request;
- struct FWCMD_COMMON_ANON_205_RESPONSE response;
-} __packed ;
-
-/*
- * Command for creating an Ethernet transmit ring. An ETX ring contains
- * ETH_WRB entries (16 bytes each). An ETX ring must be at least 256
- * entries deep (corresponding to 1 page) and at most 2k entries deep
- * (corresponding to 8 pages).
- */
-struct FWCMD_COMMON_ETH_TX_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_203_PARAMS params;
-} __packed ;
-
-struct FWCMD_COMMON_ANON_222_REQUEST {
- u16 num_pages;
- u16 rsvd0;
- struct MCC_RING_CONTEXT_AMAP context;
- struct PHYS_ADDR pages[8];
-} __packed ;
-
-struct FWCMD_COMMON_ANON_223_RESPONSE {
- u16 id;
-} __packed ;
-
-union FWCMD_COMMON_ANON_221_PARAMS {
- struct FWCMD_COMMON_ANON_222_REQUEST request;
- struct FWCMD_COMMON_ANON_223_RESPONSE response;
-} __packed ;
-
-/*
- * Command for creating the MCC ring. An MCC ring must be at least 16
- * entries deep (corresponding to 1 page) and at most 128 entries deep
- * (corresponding to 8 pages).
- */
-struct FWCMD_COMMON_MCC_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_221_PARAMS params;
-} __packed ;
-
-struct GET_QOS_IN {
- u32 qos_params_rsvd;
-} __packed;
-
-struct GET_QOS_OUT {
- u32 max_bits_per_second_NIC;
- u32 max_packets_per_second_NIC;
- u32 max_ios_per_second_iSCSI;
- u32 max_bytes_per_second_iSCSI;
- u16 domain_VLAN_tag;
- u16 fabric_domain_ID;
- u32 qos_params_oem[4];
-} __packed;
-
-union GET_QOS_PARAMS {
- struct GET_QOS_IN request;
- struct GET_QOS_OUT response;
-} __packed;
-
-/* QOS/Bandwidth settings per domain. Applicable only in VMs. */
-struct FWCMD_COMMON_GET_QOS {
- union FWCMD_HEADER header;
- union GET_QOS_PARAMS params;
-} __packed;
-
-struct SET_QOS_IN {
- u32 valid_flags;
- u32 max_bits_per_second_NIC;
- u32 max_packets_per_second_NIC;
- u32 max_ios_per_second_iSCSI;
- u32 max_bytes_per_second_iSCSI;
- u16 domain_VLAN_tag;
- u16 fabric_domain_ID;
- u32 qos_params_oem[4];
-} __packed;
-
-struct SET_QOS_OUT {
- u32 qos_params_rsvd;
-} __packed;
-
-union SET_QOS_PARAMS {
- struct SET_QOS_IN request;
- struct SET_QOS_OUT response;
-} __packed;
-
-/* QOS/Bandwidth settings per domain. Applicable only in VMs. */
-struct FWCMD_COMMON_SET_QOS {
- union FWCMD_HEADER header;
- union SET_QOS_PARAMS params;
-} __packed;
-
-struct SET_FRAME_SIZE_IN {
- u32 max_tx_frame_size;
- u32 max_rx_frame_size;
-} __packed;
-
-struct SET_FRAME_SIZE_OUT {
- u32 chip_max_tx_frame_size;
- u32 chip_max_rx_frame_size;
-} __packed;
-
-union SET_FRAME_SIZE_PARAMS {
- struct SET_FRAME_SIZE_IN request;
- struct SET_FRAME_SIZE_OUT response;
-} __packed;
-
-/* Set frame size command. Only host domain may issue this command. */
-struct FWCMD_COMMON_SET_FRAME_SIZE {
- union FWCMD_HEADER header;
- union SET_FRAME_SIZE_PARAMS params;
-} __packed;
-
-struct FORCE_FAILOVER_IN {
- u32 move_to_port;
- u32 failover_config;
-} __packed;
-
-struct FWCMD_COMMON_ANON_231_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_230_PARAMS {
- struct FORCE_FAILOVER_IN request;
- struct FWCMD_COMMON_ANON_231_RESPONSE response;
-} __packed;
-
-/*
- * Use this command to control failover in BladeEngine. It may be used
- * to failback to a restored port or to forcibly move traffic from
- * one port to another. It may also be used to enable or disable the
- * automatic failover feature. This command can only be issued by domain
- * 0.
- */
-struct FWCMD_COMMON_FORCE_FAILOVER {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_230_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_240_REQUEST {
- u64 context;
-} __packed;
-
-struct FWCMD_COMMON_ANON_241_RESPONSE {
- u64 context;
-} __packed;
-
-union FWCMD_COMMON_ANON_239_PARAMS {
- struct FWCMD_COMMON_ANON_240_REQUEST request;
- struct FWCMD_COMMON_ANON_241_RESPONSE response;
-} __packed;
-
-/*
- * This command can be used by clients as a no-operation request. Typical
- * uses for drivers are as a heartbeat mechanism, or deferred processing
- * catalyst. The ARM will always complete this command with a good completion.
- * The 64-bit parameter is not touched by the ARM processor.
- */
-struct FWCMD_COMMON_NOP {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_239_PARAMS params;
-} __packed;
-
-struct NTWK_RX_FILTER_SETTINGS {
- u8 promiscuous;
- u8 ip_cksum;
- u8 tcp_cksum;
- u8 udp_cksum;
- u8 pass_err;
- u8 pass_ckerr;
- u8 strip_crc;
- u8 mcast_en;
- u8 bcast_en;
- u8 mcast_promiscuous_en;
- u8 unicast_en;
- u8 vlan_promiscuous;
-} __packed;
-
-union FWCMD_COMMON_ANON_242_PARAMS {
- struct NTWK_RX_FILTER_SETTINGS request;
- struct NTWK_RX_FILTER_SETTINGS response;
-} __packed;
-
-/*
- * This command is used to modify the ethernet receive filter configuration.
- * Only domain 0 network function drivers may issue this command. The
- * applied configuration is returned in the response payload. Note:
- * Some receive packet filter settings are global on BladeEngine and
- * can affect both the storage and network function clients that the
- * BladeEngine hardware and firmware serve. Additionaly, depending
- * on the revision of BladeEngine, some ethernet receive filter settings
- * are dependent on others. If a dependency exists between settings
- * for the BladeEngine revision, and the command request settings do
- * not meet the dependency requirement, the invalid settings will not
- * be applied despite the comand succeeding. For example: a driver may
- * request to enable broadcast packets, but not enable multicast packets.
- * On early revisions of BladeEngine, there may be no distinction between
- * broadcast and multicast filters, so broadcast could not be enabled
- * without enabling multicast. In this scenario, the comand would still
- * succeed, but the response payload would indicate the previously
- * configured broadcast and multicast setting.
- */
-struct FWCMD_COMMON_NTWK_RX_FILTER {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_242_PARAMS params;
-} __packed;
-
-
-struct FWCMD_COMMON_ANON_244_REQUEST {
- u32 rsvd0;
-} __packed;
-
-struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD {
- u8 firmware_version_string[32];
- u8 fw_on_flash_version_string[32];
-} __packed;
-
-union FWCMD_COMMON_ANON_243_PARAMS {
- struct FWCMD_COMMON_ANON_244_REQUEST request;
- struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD response;
-} __packed;
-
-/* This comand retrieves the firmware version. */
-struct FWCMD_COMMON_GET_FW_VERSION {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_243_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_246_REQUEST {
- u16 tx_flow_control;
- u16 rx_flow_control;
-} __packed;
-
-struct FWCMD_COMMON_ANON_247_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_245_PARAMS {
- struct FWCMD_COMMON_ANON_246_REQUEST request;
- struct FWCMD_COMMON_ANON_247_RESPONSE response;
-} __packed;
-
-/*
- * This comand is used to program BladeEngine flow control behavior.
- * Only the host networking driver is allowed to use this comand.
- */
-struct FWCMD_COMMON_SET_FLOW_CONTROL {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_245_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_249_REQUEST {
- u32 rsvd0;
-} __packed;
-
-struct FWCMD_COMMON_ANON_250_RESPONSE {
- u16 tx_flow_control;
- u16 rx_flow_control;
-} __packed;
-
-union FWCMD_COMMON_ANON_248_PARAMS {
- struct FWCMD_COMMON_ANON_249_REQUEST request;
- struct FWCMD_COMMON_ANON_250_RESPONSE response;
-} __packed;
-
-/* This comand is used to read BladeEngine flow control settings. */
-struct FWCMD_COMMON_GET_FLOW_CONTROL {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_248_PARAMS params;
-} __packed;
-
-struct EQ_DELAY_PARAMS {
- u32 eq_id;
- u32 delay_in_microseconds;
-} __packed;
-
-struct FWCMD_COMMON_ANON_257_REQUEST {
- u32 num_eq;
- u32 rsvd0;
- struct EQ_DELAY_PARAMS delay[16];
-} __packed;
-
-struct FWCMD_COMMON_ANON_258_RESPONSE {
- u32 delay_resolution_in_microseconds;
- u32 delay_max_in_microseconds;
-} __packed;
-
-union MODIFY_EQ_DELAY_PARAMS {
- struct FWCMD_COMMON_ANON_257_REQUEST request;
- struct FWCMD_COMMON_ANON_258_RESPONSE response;
-} __packed;
-
-/* This comand changes the EQ delay for a given set of EQs. */
-struct FWCMD_COMMON_MODIFY_EQ_DELAY {
- union FWCMD_HEADER header;
- union MODIFY_EQ_DELAY_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_260_REQUEST {
- u32 rsvd0;
-} __packed;
-
-struct BE_FIRMWARE_CONFIG {
- u16 be_config_number;
- u16 asic_revision;
- u32 nic_ulp_mask;
- u32 tulp_mask;
- u32 iscsi_ulp_mask;
- u32 rdma_ulp_mask;
- u32 rsvd0[4];
- u32 eth_tx_id_start;
- u32 eth_tx_id_count;
- u32 eth_rx_id_start;
- u32 eth_rx_id_count;
- u32 tpm_wrbq_id_start;
- u32 tpm_wrbq_id_count;
- u32 tpm_defq_id_start;
- u32 tpm_defq_id_count;
- u32 iscsi_wrbq_id_start;
- u32 iscsi_wrbq_id_count;
- u32 iscsi_defq_id_start;
- u32 iscsi_defq_id_count;
- u32 rdma_qp_id_start;
- u32 rdma_qp_id_count;
- u32 rsvd1[8];
-} __packed;
-
-union FWCMD_COMMON_ANON_259_PARAMS {
- struct FWCMD_COMMON_ANON_260_REQUEST request;
- struct BE_FIRMWARE_CONFIG response;
-} __packed;
-
-/*
- * This comand queries the current firmware configuration parameters.
- * The static configuration type is defined by be_config_number. This
- * differentiates different BladeEngine builds, such as iSCSI Initiator
- * versus iSCSI Target. For a given static configuration, the Upper
- * Layer Protocol (ULP) processors may be reconfigured to support different
- * protocols. Each ULP processor supports one or more protocols. The
- * masks indicate which processors are configured for each protocol.
- * For a given static configuration, the number of TCP connections
- * supported for each protocol may vary. The *_id_start and *_id_count
- * variables define a linear range of IDs that are available for each
- * supported protocol. The *_id_count may be used by the driver to allocate
- * the appropriate number of connection resources. The *_id_start may
- * be used to map the arbitrary range of IDs to a zero-based range
- * of indices.
- */
-struct FWCMD_COMMON_FIRMWARE_CONFIG {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_259_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS {
- u32 emph_lev_sel_port0;
- u32 emph_lev_sel_port1;
- u8 xaui_vo_sel;
- u8 xaui_state;
- u16 rsvd0;
- u32 xaui_eq_vector;
-} __packed;
-
-struct FWCMD_COMMON_ANON_262_REQUEST {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_261_PARAMS {
- struct FWCMD_COMMON_ANON_262_REQUEST request;
- struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS response;
-} __packed;
-
-/*
- * This comand can be used to read XAUI equalization parameters. The
- * ARM firmware applies default equalization parameters during initialization.
- * These parameters may be customer-specific when derived from the
- * SEEPROM. See SEEPROM_DATA for equalization specific fields.
- */
-struct FWCMD_COMMON_GET_PORT_EQUALIZATION {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_261_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_264_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_263_PARAMS {
- struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS request;
- struct FWCMD_COMMON_ANON_264_RESPONSE response;
-} __packed;
-
-/*
- * This comand can be used to set XAUI equalization parameters. The ARM
- * firmware applies default equalization parameters during initialization.
- * These parameters may be customer-specific when derived from the
- * SEEPROM. See SEEPROM_DATA for equalization specific fields.
- */
-struct FWCMD_COMMON_SET_PORT_EQUALIZATION {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_263_PARAMS params;
-} __packed;
-
-#endif /* __fwcmd_common_bmap_h__ */
diff --git a/drivers/staging/benet/fwcmd_eth_bmap.h b/drivers/staging/benet/fwcmd_eth_bmap.h
deleted file mode 100644
index 234b179eace..00000000000
--- a/drivers/staging/benet/fwcmd_eth_bmap.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_eth_bmap_h__
-#define __fwcmd_eth_bmap_h__
-#include "fwcmd_hdr_bmap.h"
-#include "fwcmd_types_bmap.h"
-
-struct MIB_ETH_STATISTICS_PARAMS_IN {
- u32 rsvd0;
-} __packed;
-
-struct BE_RXF_STATS {
- u32 p0recvdtotalbytesLSD; /* DWORD 0 */
- u32 p0recvdtotalbytesMSD; /* DWORD 1 */
- u32 p0recvdtotalframes; /* DWORD 2 */
- u32 p0recvdunicastframes; /* DWORD 3 */
- u32 p0recvdmulticastframes; /* DWORD 4 */
- u32 p0recvdbroadcastframes; /* DWORD 5 */
- u32 p0crcerrors; /* DWORD 6 */
- u32 p0alignmentsymerrs; /* DWORD 7 */
- u32 p0pauseframesrecvd; /* DWORD 8 */
- u32 p0controlframesrecvd; /* DWORD 9 */
- u32 p0inrangelenerrors; /* DWORD 10 */
- u32 p0outrangeerrors; /* DWORD 11 */
- u32 p0frametoolongerrors; /* DWORD 12 */
- u32 p0droppedaddressmatch; /* DWORD 13 */
- u32 p0droppedvlanmismatch; /* DWORD 14 */
- u32 p0ipdroppedtoosmall; /* DWORD 15 */
- u32 p0ipdroppedtooshort; /* DWORD 16 */
- u32 p0ipdroppedhdrtoosmall; /* DWORD 17 */
- u32 p0tcpdroppedlen; /* DWORD 18 */
- u32 p0droppedrunt; /* DWORD 19 */
- u32 p0recvd64; /* DWORD 20 */
- u32 p0recvd65_127; /* DWORD 21 */
- u32 p0recvd128_256; /* DWORD 22 */
- u32 p0recvd256_511; /* DWORD 23 */
- u32 p0recvd512_1023; /* DWORD 24 */
- u32 p0recvd1518_1522; /* DWORD 25 */
- u32 p0recvd1522_2047; /* DWORD 26 */
- u32 p0recvd2048_4095; /* DWORD 27 */
- u32 p0recvd4096_8191; /* DWORD 28 */
- u32 p0recvd8192_9216; /* DWORD 29 */
- u32 p0rcvdipcksmerrs; /* DWORD 30 */
- u32 p0recvdtcpcksmerrs; /* DWORD 31 */
- u32 p0recvdudpcksmerrs; /* DWORD 32 */
- u32 p0recvdnonrsspackets; /* DWORD 33 */
- u32 p0recvdippackets; /* DWORD 34 */
- u32 p0recvdchute1packets; /* DWORD 35 */
- u32 p0recvdchute2packets; /* DWORD 36 */
- u32 p0recvdchute3packets; /* DWORD 37 */
- u32 p0recvdipsecpackets; /* DWORD 38 */
- u32 p0recvdmanagementpackets; /* DWORD 39 */
- u32 p0xmitbyteslsd; /* DWORD 40 */
- u32 p0xmitbytesmsd; /* DWORD 41 */
- u32 p0xmitunicastframes; /* DWORD 42 */
- u32 p0xmitmulticastframes; /* DWORD 43 */
- u32 p0xmitbroadcastframes; /* DWORD 44 */
- u32 p0xmitpauseframes; /* DWORD 45 */
- u32 p0xmitcontrolframes; /* DWORD 46 */
- u32 p0xmit64; /* DWORD 47 */
- u32 p0xmit65_127; /* DWORD 48 */
- u32 p0xmit128_256; /* DWORD 49 */
- u32 p0xmit256_511; /* DWORD 50 */
- u32 p0xmit512_1023; /* DWORD 51 */
- u32 p0xmit1518_1522; /* DWORD 52 */
- u32 p0xmit1522_2047; /* DWORD 53 */
- u32 p0xmit2048_4095; /* DWORD 54 */
- u32 p0xmit4096_8191; /* DWORD 55 */
- u32 p0xmit8192_9216; /* DWORD 56 */
- u32 p0rxfifooverflowdropped; /* DWORD 57 */
- u32 p0ipseclookupfaileddropped; /* DWORD 58 */
- u32 p1recvdtotalbytesLSD; /* DWORD 59 */
- u32 p1recvdtotalbytesMSD; /* DWORD 60 */
- u32 p1recvdtotalframes; /* DWORD 61 */
- u32 p1recvdunicastframes; /* DWORD 62 */
- u32 p1recvdmulticastframes; /* DWORD 63 */
- u32 p1recvdbroadcastframes; /* DWORD 64 */
- u32 p1crcerrors; /* DWORD 65 */
- u32 p1alignmentsymerrs; /* DWORD 66 */
- u32 p1pauseframesrecvd; /* DWORD 67 */
- u32 p1controlframesrecvd; /* DWORD 68 */
- u32 p1inrangelenerrors; /* DWORD 69 */
- u32 p1outrangeerrors; /* DWORD 70 */
- u32 p1frametoolongerrors; /* DWORD 71 */
- u32 p1droppedaddressmatch; /* DWORD 72 */
- u32 p1droppedvlanmismatch; /* DWORD 73 */
- u32 p1ipdroppedtoosmall; /* DWORD 74 */
- u32 p1ipdroppedtooshort; /* DWORD 75 */
- u32 p1ipdroppedhdrtoosmall; /* DWORD 76 */
- u32 p1tcpdroppedlen; /* DWORD 77 */
- u32 p1droppedrunt; /* DWORD 78 */
- u32 p1recvd64; /* DWORD 79 */
- u32 p1recvd65_127; /* DWORD 80 */
- u32 p1recvd128_256; /* DWORD 81 */
- u32 p1recvd256_511; /* DWORD 82 */
- u32 p1recvd512_1023; /* DWORD 83 */
- u32 p1recvd1518_1522; /* DWORD 84 */
- u32 p1recvd1522_2047; /* DWORD 85 */
- u32 p1recvd2048_4095; /* DWORD 86 */
- u32 p1recvd4096_8191; /* DWORD 87 */
- u32 p1recvd8192_9216; /* DWORD 88 */
- u32 p1rcvdipcksmerrs; /* DWORD 89 */
- u32 p1recvdtcpcksmerrs; /* DWORD 90 */
- u32 p1recvdudpcksmerrs; /* DWORD 91 */
- u32 p1recvdnonrsspackets; /* DWORD 92 */
- u32 p1recvdippackets; /* DWORD 93 */
- u32 p1recvdchute1packets; /* DWORD 94 */
- u32 p1recvdchute2packets; /* DWORD 95 */
- u32 p1recvdchute3packets; /* DWORD 96 */
- u32 p1recvdipsecpackets; /* DWORD 97 */
- u32 p1recvdmanagementpackets; /* DWORD 98 */
- u32 p1xmitbyteslsd; /* DWORD 99 */
- u32 p1xmitbytesmsd; /* DWORD 100 */
- u32 p1xmitunicastframes; /* DWORD 101 */
- u32 p1xmitmulticastframes; /* DWORD 102 */
- u32 p1xmitbroadcastframes; /* DWORD 103 */
- u32 p1xmitpauseframes; /* DWORD 104 */
- u32 p1xmitcontrolframes; /* DWORD 105 */
- u32 p1xmit64; /* DWORD 106 */
- u32 p1xmit65_127; /* DWORD 107 */
- u32 p1xmit128_256; /* DWORD 108 */
- u32 p1xmit256_511; /* DWORD 109 */
- u32 p1xmit512_1023; /* DWORD 110 */
- u32 p1xmit1518_1522; /* DWORD 111 */
- u32 p1xmit1522_2047; /* DWORD 112 */
- u32 p1xmit2048_4095; /* DWORD 113 */
- u32 p1xmit4096_8191; /* DWORD 114 */
- u32 p1xmit8192_9216; /* DWORD 115 */
- u32 p1rxfifooverflowdropped; /* DWORD 116 */
- u32 p1ipseclookupfaileddropped; /* DWORD 117 */
- u32 pxdroppednopbuf; /* DWORD 118 */
- u32 pxdroppednotxpb; /* DWORD 119 */
- u32 pxdroppednoipsecbuf; /* DWORD 120 */
- u32 pxdroppednoerxdescr; /* DWORD 121 */
- u32 pxdroppednotpredescr; /* DWORD 122 */
- u32 pxrecvdmanagementportpackets; /* DWORD 123 */
- u32 pxrecvdmanagementportbytes; /* DWORD 124 */
- u32 pxrecvdmanagementportpauseframes; /* DWORD 125 */
- u32 pxrecvdmanagementporterrors; /* DWORD 126 */
- u32 pxxmitmanagementportpackets; /* DWORD 127 */
- u32 pxxmitmanagementportbytes; /* DWORD 128 */
- u32 pxxmitmanagementportpause; /* DWORD 129 */
- u32 pxxmitmanagementportrxfifooverflow; /* DWORD 130 */
- u32 pxrecvdipsecipcksmerrs; /* DWORD 131 */
- u32 pxrecvdtcpsecipcksmerrs; /* DWORD 132 */
- u32 pxrecvdudpsecipcksmerrs; /* DWORD 133 */
- u32 pxipsecrunt; /* DWORD 134 */
- u32 pxipsecaddressmismatchdropped; /* DWORD 135 */
- u32 pxipsecrxfifooverflowdropped; /* DWORD 136 */
- u32 pxipsecframestoolong; /* DWORD 137 */
- u32 pxipsectotalipframes; /* DWORD 138 */
- u32 pxipseciptoosmall; /* DWORD 139 */
- u32 pxipseciptooshort; /* DWORD 140 */
- u32 pxipseciphdrtoosmall; /* DWORD 141 */
- u32 pxipsectcphdrbad; /* DWORD 142 */
- u32 pxrecvdipsecchute1; /* DWORD 143 */
- u32 pxrecvdipsecchute2; /* DWORD 144 */
- u32 pxrecvdipsecchute3; /* DWORD 145 */
- u32 pxdropped7frags; /* DWORD 146 */
- u32 pxdroppedfrags; /* DWORD 147 */
- u32 pxdroppedinvalidfragring; /* DWORD 148 */
- u32 pxnumforwardedpackets; /* DWORD 149 */
-} __packed;
-
-union MIB_ETH_STATISTICS_PARAMS {
- struct MIB_ETH_STATISTICS_PARAMS_IN request;
- struct BE_RXF_STATS response;
-} __packed;
-
-/*
- * Query ethernet statistics. All domains may issue this command. The
- * host domain drivers may optionally reset internal statistic counters
- * with a query.
- */
-struct FWCMD_ETH_GET_STATISTICS {
- union FWCMD_HEADER header;
- union MIB_ETH_STATISTICS_PARAMS params;
-} __packed;
-
-
-struct FWCMD_ETH_ANON_175_REQUEST {
- u8 port0_promiscuous;
- u8 port1_promiscuous;
- u16 rsvd0;
-} __packed;
-
-struct FWCMD_ETH_ANON_176_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_ETH_ANON_174_PARAMS {
- struct FWCMD_ETH_ANON_175_REQUEST request;
- struct FWCMD_ETH_ANON_176_RESPONSE response;
-} __packed;
-
-/* Enables/Disables promiscuous ethernet receive mode. */
-struct FWCMD_ETH_PROMISCUOUS {
- union FWCMD_HEADER header;
- union FWCMD_ETH_ANON_174_PARAMS params;
-} __packed;
-
-struct FWCMD_ETH_ANON_178_REQUEST {
- u32 new_fragsize_log2;
-} __packed;
-
-struct FWCMD_ETH_ANON_179_RESPONSE {
- u32 actual_fragsize_log2;
-} __packed;
-
-union FWCMD_ETH_ANON_177_PARAMS {
- struct FWCMD_ETH_ANON_178_REQUEST request;
- struct FWCMD_ETH_ANON_179_RESPONSE response;
-} __packed;
-
-/*
- * Sets the Ethernet RX fragment size. Only host (domain 0) networking
- * drivers may issue this command. This call will fail for non-host
- * protection domains. In this situation the MCC CQ status will indicate
- * a failure due to insufficient priviledges. The response should be
- * ignored, and the driver should use the FWCMD_ETH_GET_FRAG_SIZE to
- * query the existing ethernet receive fragment size. It must use this
- * fragment size for all fragments in the ethernet receive ring. If
- * the command succeeds, the driver must use the frag size indicated
- * in the command response since the requested frag size may not be applied
- * until the next reboot. When the requested fragsize matches the response
- * fragsize, this indicates the request was applied immediately.
- */
-struct FWCMD_ETH_SET_RX_FRAG_SIZE {
- union FWCMD_HEADER header;
- union FWCMD_ETH_ANON_177_PARAMS params;
-} __packed;
-
-struct FWCMD_ETH_ANON_181_REQUEST {
- u32 rsvd0;
-} __packed;
-
-struct FWCMD_ETH_ANON_182_RESPONSE {
- u32 actual_fragsize_log2;
-} __packed;
-
-union FWCMD_ETH_ANON_180_PARAMS {
- struct FWCMD_ETH_ANON_181_REQUEST request;
- struct FWCMD_ETH_ANON_182_RESPONSE response;
-} __packed;
-
-/*
- * Queries the Ethernet RX fragment size. All domains may issue this
- * command. The driver should call this command to determine the minimum
- * required fragment size for the ethernet RX ring buffers. Drivers
- * may choose to use a larger size for each fragment buffer, but BladeEngine
- * will use up to the configured minimum required fragsize in each ethernet
- * receive fragment buffer. For example, if the ethernet receive fragment
- * size is configured to 4kB, and a driver uses 8kB fragments, a 6kB
- * ethernet packet received by BladeEngine will be split accross two
- * of the driver's receive framgents (4kB in one fragment buffer, and
- * 2kB in the subsequent fragment buffer).
- */
-struct FWCMD_ETH_GET_RX_FRAG_SIZE {
- union FWCMD_HEADER header;
- union FWCMD_ETH_ANON_180_PARAMS params;
-} __packed;
-
-#endif /* __fwcmd_eth_bmap_h__ */
diff --git a/drivers/staging/benet/fwcmd_hdr_bmap.h b/drivers/staging/benet/fwcmd_hdr_bmap.h
deleted file mode 100644
index 28b45328fe7..00000000000
--- a/drivers/staging/benet/fwcmd_hdr_bmap.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_hdr_bmap_h__
-#define __fwcmd_hdr_bmap_h__
-
-struct FWCMD_REQUEST_HEADER {
- u8 opcode;
- u8 subsystem;
- u8 port_number;
- u8 domain;
- u32 timeout;
- u32 request_length;
- u32 rsvd0;
-} __packed;
-
-struct FWCMD_RESPONSE_HEADER {
- u8 opcode;
- u8 subsystem;
- u8 rsvd0;
- u8 domain;
- u8 status;
- u8 additional_status;
- u16 rsvd1;
- u32 response_length;
- u32 actual_response_length;
-} __packed;
-
-/*
- * The firmware/driver overwrites the input FWCMD_REQUEST_HEADER with
- * the output FWCMD_RESPONSE_HEADER.
- */
-union FWCMD_HEADER {
- struct FWCMD_REQUEST_HEADER request;
- struct FWCMD_RESPONSE_HEADER response;
-} __packed;
-
-#endif /* __fwcmd_hdr_bmap_h__ */
diff --git a/drivers/staging/benet/fwcmd_mcc.h b/drivers/staging/benet/fwcmd_mcc.h
deleted file mode 100644
index 9eeca878c1f..00000000000
--- a/drivers/staging/benet/fwcmd_mcc.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_mcc_amap_h__
-#define __fwcmd_mcc_amap_h__
-#include "fwcmd_opcodes.h"
-/*
- * Where applicable, a WRB, may contain a list of Scatter-gather elements.
- * Each element supports a 64 bit address and a 32bit length field.
- */
-struct BE_MCC_SGE_AMAP {
- u8 pa_lo[32]; /* DWORD 0 */
- u8 pa_hi[32]; /* DWORD 1 */
- u8 length[32]; /* DWORD 2 */
-} __packed;
-struct MCC_SGE_AMAP {
- u32 dw[3];
-};
-/*
- * The design of an MCC_SGE allows up to 19 elements to be embedded
- * in a WRB, supporting 64KB data transfers (assuming a 4KB page size).
- */
-struct BE_MCC_WRB_PAYLOAD_AMAP {
- union {
- struct BE_MCC_SGE_AMAP sgl[19];
- u8 embedded[59][32]; /* DWORD 0 */
- };
-} __packed;
-struct MCC_WRB_PAYLOAD_AMAP {
- u32 dw[59];
-};
-
-/*
- * This is the structure of the MCC Command WRB for commands
- * sent to the Management Processing Unit (MPU). See section
- * for usage in embedded and non-embedded modes.
- */
-struct BE_MCC_WRB_AMAP {
- u8 embedded; /* DWORD 0 */
- u8 rsvd0[2]; /* DWORD 0 */
- u8 sge_count[5]; /* DWORD 0 */
- u8 rsvd1[16]; /* DWORD 0 */
- u8 special[8]; /* DWORD 0 */
- u8 payload_length[32]; /* DWORD 1 */
- u8 tag[2][32]; /* DWORD 2 */
- u8 rsvd2[32]; /* DWORD 4 */
- struct BE_MCC_WRB_PAYLOAD_AMAP payload;
-} __packed;
-struct MCC_WRB_AMAP {
- u32 dw[64];
-};
-
-/* This is the structure of the MCC Completion queue entry */
-struct BE_MCC_CQ_ENTRY_AMAP {
- u8 completion_status[16]; /* DWORD 0 */
- u8 extended_status[16]; /* DWORD 0 */
- u8 mcc_tag[2][32]; /* DWORD 1 */
- u8 rsvd0[27]; /* DWORD 3 */
- u8 consumed; /* DWORD 3 */
- u8 completed; /* DWORD 3 */
- u8 hpi_buffer_completion; /* DWORD 3 */
- u8 async_event; /* DWORD 3 */
- u8 valid; /* DWORD 3 */
-} __packed;
-struct MCC_CQ_ENTRY_AMAP {
- u32 dw[4];
-};
-
-/* Mailbox structures used by the MPU during bootstrap */
-struct BE_MCC_MAILBOX_AMAP {
- struct BE_MCC_WRB_AMAP wrb;
- struct BE_MCC_CQ_ENTRY_AMAP cq;
-} __packed;
-struct MCC_MAILBOX_AMAP {
- u32 dw[68];
-};
-
-#endif /* __fwcmd_mcc_amap_h__ */
diff --git a/drivers/staging/benet/fwcmd_opcodes.h b/drivers/staging/benet/fwcmd_opcodes.h
deleted file mode 100644
index 23d569386b4..00000000000
--- a/drivers/staging/benet/fwcmd_opcodes.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_opcodes_amap_h__
-#define __fwcmd_opcodes_amap_h__
-
-/*
- * --- FWCMD_SUBSYSTEMS ---
- * The commands are grouped into the following subsystems. The subsystem
- * code along with the opcode uniquely identify a particular fwcmd.
- */
-#define FWCMD_SUBSYSTEM_RSVD (0) /* This subsystem is reserved. It is */
- /* never used. */
-#define FWCMD_SUBSYSTEM_COMMON (1) /* CMDs in this group are common to
- * all subsystems. See
- * COMMON_SUBSYSTEM_OPCODES for opcodes
- * and Common Host Configuration CMDs
- * for the FWCMD descriptions.
- */
-#define FWCMD_SUBSYSTEM_COMMON_ISCSI (2) /* CMDs in this group are */
- /*
- * common to Initiator and Target. See
- * COMMON_ISCSI_SUBSYSTEM_OPCODES and
- * Common iSCSI Initiator and Target
- * CMDs for the command descriptions.
- */
-#define FWCMD_SUBSYSTEM_ETH (3) /* This subsystem is used to
- execute Ethernet commands. */
-
-#define FWCMD_SUBSYSTEM_TPM (4) /* This subsystem is used
- to execute TPM commands. */
-#define FWCMD_SUBSYSTEM_PXE_UNDI (5) /* This subsystem is used
- * to execute PXE
- * and UNDI specific commands.
- */
-
-#define FWCMD_SUBSYSTEM_ISCSI_INI (6) /* This subsystem is used to
- execute ISCSI Initiator
- specific commands.
- */
-#define FWCMD_SUBSYSTEM_ISCSI_TGT (7) /* This subsystem is used
- to execute iSCSI Target
- specific commands.between
- PTL and ARM firmware.
- */
-#define FWCMD_SUBSYSTEM_MILI_PTL (8) /* This subsystem is used to
- execute iSCSI Target specific
- commands.between MILI
- and PTL. */
-#define FWCMD_SUBSYSTEM_MILI_TMD (9) /* This subsystem is used to
- execute iSCSI Target specific
- commands between MILI
- and TMD. */
-#define FWCMD_SUBSYSTEM_PROXY (11) /* This subsystem is used
- to execute proxied commands
- within the host at the
- explicit request of a
- non priviledged domain.
- This 'subsystem' is entirely
- virtual from the controller
- and firmware perspective as
- it is implemented in host
- drivers.
- */
-
-/*
- * --- COMMON_SUBSYSTEM_OPCODES ---
- * These opcodes are common to both networking and storage PCI
- * functions. They are used to reserve resources and configure
- * BladeEngine. These opcodes all use the FWCMD_SUBSYSTEM_COMMON
- * subsystem code.
- */
-#define OPCODE_COMMON_NTWK_MAC_QUERY (1)
-#define SUBSYSTEM_COMMON_NTWK_MAC_QUERY (1)
-#define SUBSYSTEM_COMMON_NTWK_MAC_SET (1)
-#define SUBSYSTEM_COMMON_NTWK_MULTICAST_SET (1)
-#define SUBSYSTEM_COMMON_NTWK_VLAN_CONFIG (1)
-#define SUBSYSTEM_COMMON_NTWK_LINK_STATUS_QUERY (1)
-#define SUBSYSTEM_COMMON_READ_FLASHROM (1)
-#define SUBSYSTEM_COMMON_WRITE_FLASHROM (1)
-#define SUBSYSTEM_COMMON_QUERY_MAX_FWCMD_BUFFER_SIZE (1)
-#define SUBSYSTEM_COMMON_ADD_PAGE_TABLES (1)
-#define SUBSYSTEM_COMMON_REMOVE_PAGE_TABLES (1)
-#define SUBSYSTEM_COMMON_RING_DESTROY (1)
-#define SUBSYSTEM_COMMON_CQ_CREATE (1)
-#define SUBSYSTEM_COMMON_EQ_CREATE (1)
-#define SUBSYSTEM_COMMON_ETH_RX_CREATE (1)
-#define SUBSYSTEM_COMMON_ETH_TX_CREATE (1)
-#define SUBSYSTEM_COMMON_ISCSI_DEFQ_CREATE (1)
-#define SUBSYSTEM_COMMON_ISCSI_WRBQ_CREATE (1)
-#define SUBSYSTEM_COMMON_MCC_CREATE (1)
-#define SUBSYSTEM_COMMON_JELL_CONFIG (1)
-#define SUBSYSTEM_COMMON_FORCE_FAILOVER (1)
-#define SUBSYSTEM_COMMON_ADD_TEMPLATE_HEADER_BUFFERS (1)
-#define SUBSYSTEM_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS (1)
-#define SUBSYSTEM_COMMON_POST_ZERO_BUFFER (1)
-#define SUBSYSTEM_COMMON_GET_QOS (1)
-#define SUBSYSTEM_COMMON_SET_QOS (1)
-#define SUBSYSTEM_COMMON_TCP_GET_STATISTICS (1)
-#define SUBSYSTEM_COMMON_SEEPROM_READ (1)
-#define SUBSYSTEM_COMMON_TCP_STATE_QUERY (1)
-#define SUBSYSTEM_COMMON_GET_CNTL_ATTRIBUTES (1)
-#define SUBSYSTEM_COMMON_NOP (1)
-#define SUBSYSTEM_COMMON_NTWK_RX_FILTER (1)
-#define SUBSYSTEM_COMMON_GET_FW_VERSION (1)
-#define SUBSYSTEM_COMMON_SET_FLOW_CONTROL (1)
-#define SUBSYSTEM_COMMON_GET_FLOW_CONTROL (1)
-#define SUBSYSTEM_COMMON_SET_TCP_PARAMETERS (1)
-#define SUBSYSTEM_COMMON_SET_FRAME_SIZE (1)
-#define SUBSYSTEM_COMMON_GET_FAT (1)
-#define SUBSYSTEM_COMMON_MODIFY_EQ_DELAY (1)
-#define SUBSYSTEM_COMMON_FIRMWARE_CONFIG (1)
-#define SUBSYSTEM_COMMON_ENABLE_DISABLE_DOMAINS (1)
-#define SUBSYSTEM_COMMON_GET_DOMAIN_CONFIG (1)
-#define SUBSYSTEM_COMMON_SET_VLD_CONFIG (1)
-#define SUBSYSTEM_COMMON_GET_VLD_CONFIG (1)
-#define SUBSYSTEM_COMMON_GET_PORT_EQUALIZATION (1)
-#define SUBSYSTEM_COMMON_SET_PORT_EQUALIZATION (1)
-#define SUBSYSTEM_COMMON_RED_CONFIG (1)
-#define OPCODE_COMMON_NTWK_MAC_SET (2)
-#define OPCODE_COMMON_NTWK_MULTICAST_SET (3)
-#define OPCODE_COMMON_NTWK_VLAN_CONFIG (4)
-#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY (5)
-#define OPCODE_COMMON_READ_FLASHROM (6)
-#define OPCODE_COMMON_WRITE_FLASHROM (7)
-#define OPCODE_COMMON_QUERY_MAX_FWCMD_BUFFER_SIZE (8)
-#define OPCODE_COMMON_ADD_PAGE_TABLES (9)
-#define OPCODE_COMMON_REMOVE_PAGE_TABLES (10)
-#define OPCODE_COMMON_RING_DESTROY (11)
-#define OPCODE_COMMON_CQ_CREATE (12)
-#define OPCODE_COMMON_EQ_CREATE (13)
-#define OPCODE_COMMON_ETH_RX_CREATE (14)
-#define OPCODE_COMMON_ETH_TX_CREATE (15)
-#define OPCODE_COMMON_NET_RESERVED0 (16) /* Reserved */
-#define OPCODE_COMMON_NET_RESERVED1 (17) /* Reserved */
-#define OPCODE_COMMON_NET_RESERVED2 (18) /* Reserved */
-#define OPCODE_COMMON_ISCSI_DEFQ_CREATE (19)
-#define OPCODE_COMMON_ISCSI_WRBQ_CREATE (20)
-#define OPCODE_COMMON_MCC_CREATE (21)
-#define OPCODE_COMMON_JELL_CONFIG (22)
-#define OPCODE_COMMON_FORCE_FAILOVER (23)
-#define OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS (24)
-#define OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS (25)
-#define OPCODE_COMMON_POST_ZERO_BUFFER (26)
-#define OPCODE_COMMON_GET_QOS (27)
-#define OPCODE_COMMON_SET_QOS (28)
-#define OPCODE_COMMON_TCP_GET_STATISTICS (29)
-#define OPCODE_COMMON_SEEPROM_READ (30)
-#define OPCODE_COMMON_TCP_STATE_QUERY (31)
-#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES (32)
-#define OPCODE_COMMON_NOP (33)
-#define OPCODE_COMMON_NTWK_RX_FILTER (34)
-#define OPCODE_COMMON_GET_FW_VERSION (35)
-#define OPCODE_COMMON_SET_FLOW_CONTROL (36)
-#define OPCODE_COMMON_GET_FLOW_CONTROL (37)
-#define OPCODE_COMMON_SET_TCP_PARAMETERS (38)
-#define OPCODE_COMMON_SET_FRAME_SIZE (39)
-#define OPCODE_COMMON_GET_FAT (40)
-#define OPCODE_COMMON_MODIFY_EQ_DELAY (41)
-#define OPCODE_COMMON_FIRMWARE_CONFIG (42)
-#define OPCODE_COMMON_ENABLE_DISABLE_DOMAINS (43)
-#define OPCODE_COMMON_GET_DOMAIN_CONFIG (44)
-#define OPCODE_COMMON_SET_VLD_CONFIG (45)
-#define OPCODE_COMMON_GET_VLD_CONFIG (46)
-#define OPCODE_COMMON_GET_PORT_EQUALIZATION (47)
-#define OPCODE_COMMON_SET_PORT_EQUALIZATION (48)
-#define OPCODE_COMMON_RED_CONFIG (49)
-
-
-
-/*
- * --- ETH_SUBSYSTEM_OPCODES ---
- * These opcodes are used for configuring the Ethernet interfaces. These
- * opcodes all use the FWCMD_SUBSYSTEM_ETH subsystem code.
- */
-#define OPCODE_ETH_RSS_CONFIG (1)
-#define OPCODE_ETH_ACPI_CONFIG (2)
-#define SUBSYSTEM_ETH_RSS_CONFIG (3)
-#define SUBSYSTEM_ETH_ACPI_CONFIG (3)
-#define OPCODE_ETH_PROMISCUOUS (3)
-#define SUBSYSTEM_ETH_PROMISCUOUS (3)
-#define SUBSYSTEM_ETH_GET_STATISTICS (3)
-#define SUBSYSTEM_ETH_GET_RX_FRAG_SIZE (3)
-#define SUBSYSTEM_ETH_SET_RX_FRAG_SIZE (3)
-#define OPCODE_ETH_GET_STATISTICS (4)
-#define OPCODE_ETH_GET_RX_FRAG_SIZE (5)
-#define OPCODE_ETH_SET_RX_FRAG_SIZE (6)
-
-
-
-
-
-/*
- * --- MCC_STATUS_CODE ---
- * These are the global status codes used by all subsystems
- */
-#define MCC_STATUS_SUCCESS (0) /* Indicates a successful
- completion of the command */
-#define MCC_STATUS_INSUFFICIENT_PRIVILEGES (1) /* The client does not have
- sufficient privileges to
- execute the command */
-#define MCC_STATUS_INVALID_PARAMETER (2) /* A parameter in the command
- was invalid. The extended
- status contains the index
- of the parameter */
-#define MCC_STATUS_INSUFFICIENT_RESOURCES (3) /* There are insufficient
- chip resources to execute
- the command */
-#define MCC_STATUS_QUEUE_FLUSHING (4) /* The command is completing
- because the queue was
- getting flushed */
-#define MCC_STATUS_DMA_FAILED (5) /* The command is completing
- with a DMA error */
-
-/*
- * --- MGMT_ERROR_CODES ---
- * Error Codes returned in the status field of the FWCMD response header
- */
-#define MGMT_STATUS_SUCCESS (0) /* The FWCMD completed
- without errors */
-#define MGMT_STATUS_FAILED (1) /* Error status in the Status
- field of the
- struct FWCMD_RESPONSE_HEADER */
-#define MGMT_STATUS_ILLEGAL_REQUEST (2) /* Invalid FWCMD opcode */
-#define MGMT_STATUS_ILLEGAL_FIELD (3) /* Invalid parameter in
- the FWCMD payload */
-
-#endif /* __fwcmd_opcodes_amap_h__ */
diff --git a/drivers/staging/benet/fwcmd_types_bmap.h b/drivers/staging/benet/fwcmd_types_bmap.h
deleted file mode 100644
index 92217aff3a1..00000000000
--- a/drivers/staging/benet/fwcmd_types_bmap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_types_bmap_h__
-#define __fwcmd_types_bmap_h__
-
-/* MAC address format */
-struct MAC_ADDRESS_FORMAT {
- u16 SizeOfStructure;
- u8 MACAddress[6];
-} __packed;
-
-#endif /* __fwcmd_types_bmap_h__ */
diff --git a/drivers/staging/benet/host_struct.h b/drivers/staging/benet/host_struct.h
deleted file mode 100644
index 3de6722b980..00000000000
--- a/drivers/staging/benet/host_struct.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __host_struct_amap_h__
-#define __host_struct_amap_h__
-#include "be_cm.h"
-#include "be_common.h"
-#include "descriptors.h"
-
-/* --- EQ_COMPLETION_MAJOR_CODE_ENUM --- */
-#define EQ_MAJOR_CODE_COMPLETION (0) /* Completion event on a */
- /* qcompletion ueue. */
-#define EQ_MAJOR_CODE_ETH (1) /* Affiliated Ethernet Event. */
-#define EQ_MAJOR_CODE_RESERVED (2) /* Reserved */
-#define EQ_MAJOR_CODE_RDMA (3) /* Affiliated RDMA Event. */
-#define EQ_MAJOR_CODE_ISCSI (4) /* Affiliated ISCSI Event */
-#define EQ_MAJOR_CODE_UNAFFILIATED (5) /* Unaffiliated Event */
-
-/* --- EQ_COMPLETION_MINOR_CODE_ENUM --- */
-#define EQ_MINOR_CODE_COMPLETION (0) /* Completion event on a */
- /* completion queue. */
-#define EQ_MINOR_CODE_OTHER (1) /* Other Event (TBD). */
-
-/* Queue Entry Definition for all 4 byte event queue types. */
-struct BE_EQ_ENTRY_AMAP {
- u8 Valid; /* DWORD 0 */
- u8 MajorCode[3]; /* DWORD 0 */
- u8 MinorCode[12]; /* DWORD 0 */
- u8 ResourceID[16]; /* DWORD 0 */
-} __packed;
-struct EQ_ENTRY_AMAP {
- u32 dw[1];
-};
-
-/*
- * --- ETH_EVENT_CODE ---
- * These codes are returned by the MPU when one of these events has occurred,
- * and the event is configured to report to an Event Queue when an event
- * is detected.
- */
-#define ETH_EQ_LINK_STATUS (0) /* Link status change event */
- /* detected. */
-#define ETH_EQ_WATERMARK (1) /* watermark event detected. */
-#define ETH_EQ_MAGIC_PKT (2) /* magic pkt event detected. */
-#define ETH_EQ_ACPI_PKT0 (3) /* ACPI interesting packet */
- /* detected. */
-#define ETH_EQ_ACPI_PKT1 (3) /* ACPI interesting packet */
- /* detected. */
-#define ETH_EQ_ACPI_PKT2 (3) /* ACPI interesting packet */
- /* detected. */
-#define ETH_EQ_ACPI_PKT3 (3) /* ACPI interesting packet */
- /* detected. */
-
-/*
- * --- ETH_TX_COMPL_STATUS_ENUM ---
- * Status codes contained in Ethernet TX completion descriptors.
- */
-#define ETH_COMP_VALID (0)
-#define ETH_COMP_ERROR (1)
-#define ETH_COMP_INVALID (15)
-
-/*
- * --- ETH_TX_COMPL_PORT_ENUM ---
- * Port indicator contained in Ethernet TX completion descriptors.
- */
-#define ETH_COMP_PORT0 (0)
-#define ETH_COMP_PORT1 (1)
-#define ETH_COMP_MGMT (2)
-
-/*
- * --- ETH_TX_COMPL_CT_ENUM ---
- * Completion type indicator contained in Ethernet TX completion descriptors.
- */
-#define ETH_COMP_ETH (0)
-
-/*
- * Work request block that the driver issues to the chip for
- * Ethernet transmissions. All control fields must be valid in each WRB for
- * a message. The controller, as specified by the flags, optionally writes
- * an entry to the Completion Ring and generate an event.
- */
-struct BE_ETH_WRB_AMAP {
- u8 frag_pa_hi[32]; /* DWORD 0 */
- u8 frag_pa_lo[32]; /* DWORD 1 */
- u8 complete; /* DWORD 2 */
- u8 event; /* DWORD 2 */
- u8 crc; /* DWORD 2 */
- u8 forward; /* DWORD 2 */
- u8 ipsec; /* DWORD 2 */
- u8 mgmt; /* DWORD 2 */
- u8 ipcs; /* DWORD 2 */
- u8 udpcs; /* DWORD 2 */
- u8 tcpcs; /* DWORD 2 */
- u8 lso; /* DWORD 2 */
- u8 last; /* DWORD 2 */
- u8 vlan; /* DWORD 2 */
- u8 dbg[3]; /* DWORD 2 */
- u8 hash_val[3]; /* DWORD 2 */
- u8 lso_mss[14]; /* DWORD 2 */
- u8 frag_len[16]; /* DWORD 3 */
- u8 vlan_tag[16]; /* DWORD 3 */
-} __packed;
-struct ETH_WRB_AMAP {
- u32 dw[4];
-};
-
-/* This is an Ethernet transmit completion descriptor */
-struct BE_ETH_TX_COMPL_AMAP {
- u8 user_bytes[16]; /* DWORD 0 */
- u8 nwh_bytes[8]; /* DWORD 0 */
- u8 lso; /* DWORD 0 */
- u8 rsvd0[7]; /* DWORD 0 */
- u8 wrb_index[16]; /* DWORD 1 */
- u8 ct[2]; /* DWORD 1 */
- u8 port[2]; /* DWORD 1 */
- u8 rsvd1[8]; /* DWORD 1 */
- u8 status[4]; /* DWORD 1 */
- u8 rsvd2[16]; /* DWORD 2 */
- u8 ringid[11]; /* DWORD 2 */
- u8 hash_val[4]; /* DWORD 2 */
- u8 valid; /* DWORD 2 */
- u8 rsvd3[32]; /* DWORD 3 */
-} __packed;
-struct ETH_TX_COMPL_AMAP {
- u32 dw[4];
-};
-
-/* Ethernet Receive Buffer descriptor */
-struct BE_ETH_RX_D_AMAP {
- u8 fragpa_hi[32]; /* DWORD 0 */
- u8 fragpa_lo[32]; /* DWORD 1 */
-} __packed;
-struct ETH_RX_D_AMAP {
- u32 dw[2];
-};
-
-/* This is an Ethernet Receive Completion Descriptor */
-struct BE_ETH_RX_COMPL_AMAP {
- u8 vlan_tag[16]; /* DWORD 0 */
- u8 pktsize[14]; /* DWORD 0 */
- u8 port; /* DWORD 0 */
- u8 rsvd0; /* DWORD 0 */
- u8 err; /* DWORD 1 */
- u8 rsshp; /* DWORD 1 */
- u8 ipf; /* DWORD 1 */
- u8 tcpf; /* DWORD 1 */
- u8 udpf; /* DWORD 1 */
- u8 ipcksm; /* DWORD 1 */
- u8 tcpcksm; /* DWORD 1 */
- u8 udpcksm; /* DWORD 1 */
- u8 macdst[6]; /* DWORD 1 */
- u8 vtp; /* DWORD 1 */
- u8 vtm; /* DWORD 1 */
- u8 fragndx[10]; /* DWORD 1 */
- u8 ct[2]; /* DWORD 1 */
- u8 ipsec; /* DWORD 1 */
- u8 numfrags[3]; /* DWORD 1 */
- u8 rsvd1[31]; /* DWORD 2 */
- u8 valid; /* DWORD 2 */
- u8 rsshash[32]; /* DWORD 3 */
-} __packed;
-struct ETH_RX_COMPL_AMAP {
- u32 dw[4];
-};
-
-#endif /* __host_struct_amap_h__ */
diff --git a/drivers/staging/benet/hwlib.h b/drivers/staging/benet/hwlib.h
deleted file mode 100644
index afedf4dc590..00000000000
--- a/drivers/staging/benet/hwlib.h
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#ifndef __hwlib_h__
-#define __hwlib_h__
-
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-
-#include "regmap.h" /* srcgen array map output */
-
-#include "asyncmesg.h"
-#include "fwcmd_opcodes.h"
-#include "post_codes.h"
-#include "fwcmd_mcc.h"
-
-#include "fwcmd_types_bmap.h"
-#include "fwcmd_common_bmap.h"
-#include "fwcmd_eth_bmap.h"
-#include "bestatus.h"
-/*
- *
- * Macros for reading/writing a protection domain or CSR registers
- * in BladeEngine.
- */
-#define PD_READ(fo, field) ioread32((fo)->db_va + \
- offsetof(struct BE_PROTECTION_DOMAIN_DBMAP_AMAP, field)/8)
-
-#define PD_WRITE(fo, field, val) iowrite32(val, (fo)->db_va + \
- offsetof(struct BE_PROTECTION_DOMAIN_DBMAP_AMAP, field)/8)
-
-#define CSR_READ(fo, field) ioread32((fo)->csr_va + \
- offsetof(struct BE_BLADE_ENGINE_CSRMAP_AMAP, field)/8)
-
-#define CSR_WRITE(fo, field, val) iowrite32(val, (fo)->csr_va + \
- offsetof(struct BE_BLADE_ENGINE_CSRMAP_AMAP, field)/8)
-
-#define PCICFG0_READ(fo, field) ioread32((fo)->pci_va + \
- offsetof(struct BE_PCICFG0_CSRMAP_AMAP, field)/8)
-
-#define PCICFG0_WRITE(fo, field, val) iowrite32(val, (fo)->pci_va + \
- offsetof(struct BE_PCICFG0_CSRMAP_AMAP, field)/8)
-
-#define PCICFG1_READ(fo, field) ioread32((fo)->pci_va + \
- offsetof(struct BE_PCICFG1_CSRMAP_AMAP, field)/8)
-
-#define PCICFG1_WRITE(fo, field, val) iowrite32(val, (fo)->pci_va + \
- offsetof(struct BE_PCICFG1_CSRMAP_AMAP, field)/8)
-
-#ifdef BE_DEBUG
-#define ASSERT(c) BUG_ON(!(c));
-#else
-#define ASSERT(c)
-#endif
-
-/* debug levels */
-enum BE_DEBUG_LEVELS {
- DL_ALWAYS = 0, /* cannot be masked */
- DL_ERR = 0x1, /* errors that should never happen */
- DL_WARN = 0x2, /* something questionable.
- recoverable errors */
- DL_NOTE = 0x4, /* infrequent, important debug info */
- DL_INFO = 0x8, /* debug information */
- DL_VERBOSE = 0x10, /* detailed info, such as buffer traces */
- BE_DL_MIN_VALUE = 0x1, /* this is the min value used */
- BE_DL_MAX_VALUE = 0x80 /* this is the higheset value used */
-} ;
-
-extern unsigned int trace_level;
-
-#define TRACE(lm, fmt, args...) { \
- if (trace_level & lm) { \
- printk(KERN_NOTICE "BE: %s:%d \n" fmt, \
- __FILE__ , __LINE__ , ## args); \
- } \
- }
-
-static inline unsigned int be_trace_set_level(unsigned int level)
-{
- unsigned int old_level = trace_level;
- trace_level = level;
- return old_level;
-}
-
-#define be_trace_get_level() trace_level
-/*
- * Returns number of pages spanned by the size of data
- * starting at the given address.
- */
-#define PAGES_SPANNED(_address, _size) \
- ((u32)((((size_t)(_address) & (PAGE_SIZE - 1)) + \
- (_size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
-/* Byte offset into the page corresponding to given address */
-#define OFFSET_IN_PAGE(_addr_) ((size_t)(_addr_) & (PAGE_SIZE-1))
-
-/*
- * circular subtract.
- * Returns a - b assuming a circular number system, where a and b are
- * in range (0, maxValue-1). If a==b, zero is returned so the
- * highest value possible with this subtraction is maxValue-1.
- */
-static inline u32 be_subc(u32 a, u32 b, u32 max)
-{
- ASSERT(a <= max && b <= max);
- ASSERT(max > 0);
- return a >= b ? (a - b) : (max - b + a);
-}
-
-static inline u32 be_addc(u32 a, u32 b, u32 max)
-{
- ASSERT(a < max);
- ASSERT(max > 0);
- return (max - a > b) ? (a + b) : (b + a - max);
-}
-
-/* descriptor for a physically contiguous memory used for ring */
-struct ring_desc {
- u32 length; /* length in bytes */
- void *va; /* virtual address */
- u64 pa; /* bus address */
-} ;
-
-/*
- * This structure stores information about a ring shared between hardware
- * and software. Each ring is allocated by the driver in the uncached
- * extension and mapped into BladeEngine's unified table.
- */
-struct mp_ring {
- u32 pages; /* queue size in pages */
- u32 id; /* queue id assigned by beklib */
- u32 num; /* number of elements in queue */
- u32 cidx; /* consumer index */
- u32 pidx; /* producer index -- not used by most rings */
- u32 itemSize; /* size in bytes of one object */
-
- void *va; /* The virtual address of the ring.
- This should be last to allow 32 & 64
- bit debugger extensions to work. */
-} ;
-
-/*----------- amap bit filed get / set macros and functions -----*/
-/*
- * Structures defined in the map header files (under fw/amap/) with names
- * in the format BE_<name>_AMAP are pseudo structures with members
- * of type u8. These structures are templates that are used in
- * conjuntion with the structures with names in the format
- * <name>_AMAP to calculate the bit masks and bit offsets to get or set
- * bit fields in structures. The structures <name>_AMAP are arrays
- * of 32 bits words and have the correct size. The following macros
- * provide convenient ways to get and set the various members
- * in the structures without using strucctures with bit fields.
- * Always use the macros AMAP_GET_BITS_PTR and AMAP_SET_BITS_PTR
- * macros to extract and set various members.
- */
-
-/*
- * Returns the a bit mask for the register that is NOT shifted into location.
- * That means return values always look like: 0x1, 0xFF, 0x7FF, etc...
- */
-static inline u32 amap_mask(u32 bit_size)
-{
- return bit_size == 32 ? 0xFFFFFFFF : (1 << bit_size) - 1;
-}
-
-#define AMAP_BIT_MASK(_struct_, field) \
- amap_mask(AMAP_BIT_SIZE(_struct_, field))
-
-/*
- * non-optimized set bits function. First clears the bits and then assigns them.
- * This does not require knowledge of the particular DWORD you are setting.
- * e.g. AMAP_SET_BITS_PTR (struct, field1, &contextMemory, 123);
- */
-static inline void
-amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value)
-{
- u32 *dw = (u32 *)ptr;
- *(dw + dw_offset) &= ~(mask << offset);
- *(dw + dw_offset) |= (mask & value) << offset;
-}
-
-#define AMAP_SET_BITS_PTR(_struct_, field, _structPtr_, val) \
- amap_set(_structPtr_, AMAP_WORD_OFFSET(_struct_, field),\
- AMAP_BIT_MASK(_struct_, field), \
- AMAP_BIT_OFFSET(_struct_, field), val)
-/*
- * Non-optimized routine that gets the bits without knowing the correct DWORD.
- * e.g. fieldValue = AMAP_GET_BITS_PTR (struct, field1, &contextMemory);
- */
-static inline u32
-amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
-{
- u32 *dw = (u32 *)ptr;
- return mask & (*(dw + dw_offset) >> offset);
-}
-#define AMAP_GET_BITS_PTR(_struct_, field, _structPtr_) \
- amap_get(_structPtr_, AMAP_WORD_OFFSET(_struct_, field), \
- AMAP_BIT_MASK(_struct_, field), \
- AMAP_BIT_OFFSET(_struct_, field))
-
-/* Returns 0-31 representing bit offset within a DWORD of a bitfield. */
-#define AMAP_BIT_OFFSET(_struct_, field) \
- (offsetof(struct BE_ ## _struct_ ## _AMAP, field) % 32)
-
-/* Returns 0-n representing DWORD offset of bitfield within the structure. */
-#define AMAP_WORD_OFFSET(_struct_, field) \
- (offsetof(struct BE_ ## _struct_ ## _AMAP, field)/32)
-
-/* Returns size of bitfield in bits. */
-#define AMAP_BIT_SIZE(_struct_, field) \
- sizeof(((struct BE_ ## _struct_ ## _AMAP*)0)->field)
-
-struct be_mcc_wrb_response_copy {
- u16 length; /* bytes in response */
- u16 fwcmd_offset; /* offset within the wrb of the response */
- void *va; /* user's va to copy response into */
-
-} ;
-typedef void (*mcc_wrb_cqe_callback) (void *context, int status,
- struct MCC_WRB_AMAP *optional_wrb);
-struct be_mcc_wrb_context {
-
- mcc_wrb_cqe_callback internal_cb; /* Function to call on
- completion */
- void *internal_cb_context; /* Parameter to pass
- to completion function */
-
- mcc_wrb_cqe_callback cb; /* Function to call on completion */
- void *cb_context; /* Parameter to pass to completion function */
-
- int *users_final_status; /* pointer to a local
- variable for synchronous
- commands */
- struct MCC_WRB_AMAP *wrb; /* pointer to original wrb for embedded
- commands only */
- struct list_head next; /* links context structs together in
- free list */
-
- struct be_mcc_wrb_response_copy copy; /* Optional parameters to copy
- embedded response to user's va */
-
-#if defined(BE_DEBUG)
- u16 subsystem, opcode; /* Track this FWCMD for debug builds. */
- struct MCC_WRB_AMAP *ring_wrb;
- u32 consumed_count;
-#endif
-} ;
-
-/*
- Represents a function object for network or storage. This
- is used to manage per-function resources like MCC CQs, etc.
-*/
-struct be_function_object {
-
- u32 magic; /*!< magic for detecting memory corruption. */
-
- /* PCI BAR mapped addresses */
- u8 __iomem *csr_va; /* CSR */
- u8 __iomem *db_va; /* Door Bell */
- u8 __iomem *pci_va; /* PCI config space */
- u32 emulate; /* if set, MPU is not available.
- Emulate everything. */
- u32 pend_queue_driving; /* if set, drive the queued WRBs
- after releasing the WRB lock */
-
- spinlock_t post_lock; /* lock for verifying one thread posting wrbs */
- spinlock_t cq_lock; /* lock for verifying one thread
- processing cq */
- spinlock_t mcc_context_lock; /* lock for protecting mcc
- context free list */
- unsigned long post_irq;
- unsigned long cq_irq;
-
- u32 type;
- u32 pci_function_number;
-
- struct be_mcc_object *mcc; /* mcc rings. */
-
- struct {
- struct MCC_MAILBOX_AMAP *va; /* VA to the mailbox */
- u64 pa; /* PA to the mailbox */
- u32 length; /* byte length of mailbox */
-
- /* One default context struct used for posting at
- * least one MCC_WRB
- */
- struct be_mcc_wrb_context default_context;
- bool default_context_allocated;
- } mailbox;
-
- struct {
-
- /* Wake on lans configured. */
- u32 wol_bitmask; /* bits 0,1,2,3 are set if
- corresponding index is enabled */
- } config;
-
-
- struct BE_FIRMWARE_CONFIG fw_config;
-} ;
-
-/*
- Represents an Event Queue
-*/
-struct be_eq_object {
- u32 magic;
- atomic_t ref_count;
-
- struct be_function_object *parent_function;
-
- struct list_head eq_list;
- struct list_head cq_list_head;
-
- u32 eq_id;
- void *cb_context;
-
-} ;
-
-/*
- Manages a completion queue
-*/
-struct be_cq_object {
- u32 magic;
- atomic_t ref_count;
-
- struct be_function_object *parent_function;
- struct be_eq_object *eq_object;
-
- struct list_head cq_list;
- struct list_head cqlist_for_eq;
-
- void *va;
- u32 num_entries;
-
- void *cb_context;
-
- u32 cq_id;
-
-} ;
-
-/*
- Manages an ethernet send queue
-*/
-struct be_ethsq_object {
- u32 magic;
-
- struct list_head list;
-
- struct be_function_object *parent_function;
- struct be_cq_object *cq_object;
- u32 bid;
-
-} ;
-
-/*
-@brief
- Manages an ethernet receive queue
-*/
-struct be_ethrq_object {
- u32 magic;
- struct list_head list;
- struct be_function_object *parent_function;
- u32 rid;
- struct be_cq_object *cq_object;
- struct be_cq_object *rss_cq_object[4];
-
-} ;
-
-/*
- Manages an MCC
-*/
-typedef void (*mcc_async_event_callback) (void *context, u32 event_code,
- void *event);
-struct be_mcc_object {
- u32 magic;
-
- struct be_function_object *parent_function;
- struct list_head mcc_list;
-
- struct be_cq_object *cq_object;
-
- /* Async event callback for MCC CQ. */
- mcc_async_event_callback async_cb;
- void *async_context;
-
- struct {
- struct be_mcc_wrb_context *base;
- u32 num;
- struct list_head list_head;
- } wrb_context;
-
- struct {
- struct ring_desc *rd;
- struct mp_ring ring;
- } sq;
-
- struct {
- struct mp_ring ring;
- } cq;
-
- u32 processing; /* flag indicating that one thread
- is processing CQ */
- u32 rearm; /* doorbell rearm setting to make
- sure the active processing thread */
- /* rearms the CQ if any of the threads requested it. */
-
- struct list_head backlog;
- u32 backlog_length;
- u32 driving_backlog;
- u32 consumed_index;
-
-} ;
-
-
-/* Queue context header -- the required software information for
- * queueing a WRB.
- */
-struct be_queue_driver_context {
- mcc_wrb_cqe_callback internal_cb; /* Function to call on
- completion */
- void *internal_cb_context; /* Parameter to pass
- to completion function */
-
- mcc_wrb_cqe_callback cb; /* Function to call on completion */
- void *cb_context; /* Parameter to pass to completion function */
-
- struct be_mcc_wrb_response_copy copy; /* Optional parameters to copy
- embedded response to user's va */
- void *optional_fwcmd_va;
- struct list_head list;
- u32 bytes;
-} ;
-
-/*
- * Common MCC WRB header that all commands require.
- */
-struct be_mcc_wrb_header {
- u8 rsvd[offsetof(struct BE_MCC_WRB_AMAP, payload)/8];
-} ;
-
-/*
- * All non embedded commands supported by hwlib functions only allow
- * 1 SGE. This queue context handles them all.
- */
-struct be_nonembedded_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct MCC_SGE_AMAP sge[1];
-} ;
-
-/*
- * ------------------------------------------------------------------------
- * This section contains the specific queue struct for each command.
- * The user could always provide a be_generic_q_ctxt but this is a
- * rather large struct. By using the specific struct, memory consumption
- * can be reduced.
- * ------------------------------------------------------------------------
- */
-
-struct be_link_status_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY fwcmd;
-} ;
-
-struct be_multicast_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_NTWK_MULTICAST_SET fwcmd;
-} ;
-
-
-struct be_vlan_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_NTWK_VLAN_CONFIG fwcmd;
-} ;
-
-struct be_promiscuous_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_ETH_PROMISCUOUS fwcmd;
-} ;
-
-struct be_force_failover_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_FORCE_FAILOVER fwcmd;
-} ;
-
-
-struct be_rxf_filter_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_NTWK_RX_FILTER fwcmd;
-} ;
-
-struct be_eq_modify_delay_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_MODIFY_EQ_DELAY fwcmd;
-} ;
-
-/*
- * The generic context is the largest size that would be required.
- * It is the software context plus an entire WRB.
- */
-struct be_generic_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct MCC_WRB_PAYLOAD_AMAP payload;
-} ;
-
-/*
- * Types for the BE_QUEUE_CONTEXT object.
- */
-#define BE_QUEUE_INVALID (0)
-#define BE_QUEUE_LINK_STATUS (0xA006)
-#define BE_QUEUE_ETH_STATS (0xA007)
-#define BE_QUEUE_TPM_STATS (0xA008)
-#define BE_QUEUE_TCP_STATS (0xA009)
-#define BE_QUEUE_MULTICAST (0xA00A)
-#define BE_QUEUE_VLAN (0xA00B)
-#define BE_QUEUE_RSS (0xA00C)
-#define BE_QUEUE_FORCE_FAILOVER (0xA00D)
-#define BE_QUEUE_PROMISCUOUS (0xA00E)
-#define BE_QUEUE_WAKE_ON_LAN (0xA00F)
-#define BE_QUEUE_NOP (0xA010)
-
-/* --- BE_FUNCTION_ENUM --- */
-#define BE_FUNCTION_TYPE_ISCSI (0)
-#define BE_FUNCTION_TYPE_NETWORK (1)
-#define BE_FUNCTION_TYPE_ARM (2)
-
-/* --- BE_ETH_TX_RING_TYPE_ENUM --- */
-#define BE_ETH_TX_RING_TYPE_FORWARDING (1) /* Ether ring for forwarding */
-#define BE_ETH_TX_RING_TYPE_STANDARD (2) /* Ether ring for sending */
- /* network packets. */
-#define BE_ETH_TX_RING_TYPE_BOUND (3) /* Ethernet ring for sending */
- /* network packets, bound */
- /* to a physical port. */
-/*
- * ----------------------------------------------------------------------
- * API MACROS
- * ----------------------------------------------------------------------
- */
-#define BE_FWCMD_NAME(_short_name_) struct FWCMD_##_short_name_
-#define BE_OPCODE_NAME(_short_name_) OPCODE_##_short_name_
-#define BE_SUBSYSTEM_NAME(_short_name_) SUBSYSTEM_##_short_name_
-
-
-#define BE_PREPARE_EMBEDDED_FWCMD(_pfob_, _wrb_, _short_name_) \
- ((BE_FWCMD_NAME(_short_name_) *) \
- be_function_prepare_embedded_fwcmd(_pfob_, _wrb_, \
- sizeof(BE_FWCMD_NAME(_short_name_)), \
- FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.request), \
- FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.response), \
- BE_OPCODE_NAME(_short_name_), \
- BE_SUBSYSTEM_NAME(_short_name_)));
-
-#define BE_PREPARE_NONEMBEDDED_FWCMD(_pfob_, _wrb_, _iva_, _ipa_, _short_name_)\
- ((BE_FWCMD_NAME(_short_name_) *) \
- be_function_prepare_nonembedded_fwcmd(_pfob_, _wrb_, (_iva_), (_ipa_), \
- sizeof(BE_FWCMD_NAME(_short_name_)), \
- FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.request), \
- FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.response), \
- BE_OPCODE_NAME(_short_name_), \
- BE_SUBSYSTEM_NAME(_short_name_)));
-
-int be_function_object_create(u8 __iomem *csr_va, u8 __iomem *db_va,
- u8 __iomem *pci_va, u32 function_type, struct ring_desc *mailbox_rd,
- struct be_function_object *pfob);
-
-int be_function_object_destroy(struct be_function_object *pfob);
-int be_function_cleanup(struct be_function_object *pfob);
-
-
-int be_function_get_fw_version(struct be_function_object *pfob,
- struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD *fw_version,
- mcc_wrb_cqe_callback cb, void *cb_context);
-
-
-int be_eq_modify_delay(struct be_function_object *pfob,
- u32 num_eq, struct be_eq_object **eq_array,
- u32 *eq_delay_array, mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_eq_modify_delay_q_ctxt *q_ctxt);
-
-
-
-int be_eq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 eqe_size, u32 num_entries,
- u32 watermark, u32 timer_delay, struct be_eq_object *eq_object);
-
-int be_eq_destroy(struct be_eq_object *eq);
-
-int be_cq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length,
- bool solicited_eventable, bool no_delay,
- u32 wm_thresh, struct be_eq_object *eq_object,
- struct be_cq_object *cq_object);
-
-int be_cq_destroy(struct be_cq_object *cq);
-
-int be_mcc_ring_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length,
- struct be_mcc_wrb_context *context_array,
- u32 num_context_entries,
- struct be_cq_object *cq, struct be_mcc_object *mcc);
-int be_mcc_ring_destroy(struct be_mcc_object *mcc_object);
-
-int be_mcc_process_cq(struct be_mcc_object *mcc_object, bool rearm);
-
-int be_mcc_add_async_event_callback(struct be_mcc_object *mcc_object,
- mcc_async_event_callback cb, void *cb_context);
-
-int be_pci_soft_reset(struct be_function_object *pfob);
-
-
-int be_drive_POST(struct be_function_object *pfob);
-
-
-int be_eth_sq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length_in_bytes,
- u32 type, u32 ulp, struct be_cq_object *cq_object,
- struct be_ethsq_object *eth_sq);
-
-struct be_eth_sq_parameters {
- u32 port;
- u32 rsvd0[2];
-} ;
-
-int be_eth_sq_create_ex(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length_in_bytes,
- u32 type, u32 ulp, struct be_cq_object *cq_object,
- struct be_eth_sq_parameters *ex_parameters,
- struct be_ethsq_object *eth_sq);
-int be_eth_sq_destroy(struct be_ethsq_object *eth_sq);
-
-int be_eth_set_flow_control(struct be_function_object *pfob,
- bool txfc_enable, bool rxfc_enable);
-
-int be_eth_get_flow_control(struct be_function_object *pfob,
- bool *txfc_enable, bool *rxfc_enable);
-int be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps);
-
-int be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps);
-
-int be_eth_set_frame_size(struct be_function_object *pfob,
- u32 *tx_frame_size, u32 *rx_frame_size);
-
-int be_eth_rq_create(struct be_function_object *pfob,
- struct ring_desc *rd, struct be_cq_object *cq_object,
- struct be_cq_object *bcmc_cq_object,
- struct be_ethrq_object *eth_rq);
-
-int be_eth_rq_destroy(struct be_ethrq_object *eth_rq);
-
-int be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush,
- mcc_wrb_cqe_callback cb, void *cb_context);
-int be_eth_rq_set_frag_size(struct be_function_object *pfob,
- u32 new_frag_size_bytes, u32 *actual_frag_size_bytes);
-int be_eth_rq_get_frag_size(struct be_function_object *pfob,
- u32 *frag_size_bytes);
-
-void *be_function_prepare_embedded_fwcmd(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb,
- u32 payload_length, u32 request_length,
- u32 response_length, u32 opcode, u32 subsystem);
-void *be_function_prepare_nonembedded_fwcmd(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, void *fwcmd_header_va, u64 fwcmd_header_pa,
- u32 payload_length, u32 request_length, u32 response_length,
- u32 opcode, u32 subsystem);
-
-
-struct MCC_WRB_AMAP *
-be_function_peek_mcc_wrb(struct be_function_object *pfob);
-
-int be_rxf_mac_address_read_write(struct be_function_object *pfob,
- bool port1, bool mac1, bool mgmt,
- bool write, bool permanent, u8 *mac_address,
- mcc_wrb_cqe_callback cb,
- void *cb_context);
-
-int be_rxf_multicast_config(struct be_function_object *pfob,
- bool promiscuous, u32 num, u8 *mac_table,
- mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_multicast_q_ctxt *q_ctxt);
-
-int be_rxf_vlan_config(struct be_function_object *pfob,
- bool promiscuous, u32 num, u16 *vlan_tag_array,
- mcc_wrb_cqe_callback cb, void *cb_context,
- struct be_vlan_q_ctxt *q_ctxt);
-
-
-int be_rxf_link_status(struct be_function_object *pfob,
- struct BE_LINK_STATUS *link_status,
- mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_link_status_q_ctxt *q_ctxt);
-
-
-int be_rxf_query_eth_statistics(struct be_function_object *pfob,
- struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd,
- u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_nonembedded_q_ctxt *q_ctxt);
-
-int be_rxf_promiscuous(struct be_function_object *pfob,
- bool enable_port0, bool enable_port1,
- mcc_wrb_cqe_callback cb, void *cb_context,
- struct be_promiscuous_q_ctxt *q_ctxt);
-
-
-int be_rxf_filter_config(struct be_function_object *pfob,
- struct NTWK_RX_FILTER_SETTINGS *settings,
- mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_rxf_filter_q_ctxt *q_ctxt);
-
-/*
- * ------------------------------------------------------
- * internal functions used by hwlib
- * ------------------------------------------------------
- */
-
-
-int be_function_ring_destroy(struct be_function_object *pfob,
- u32 id, u32 ring_type, mcc_wrb_cqe_callback cb,
- void *cb_context,
- mcc_wrb_cqe_callback internal_cb,
- void *internal_callback_context);
-
-int be_function_post_mcc_wrb(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb,
- struct be_generic_q_ctxt *q_ctxt,
- mcc_wrb_cqe_callback cb, void *cb_context,
- mcc_wrb_cqe_callback internal_cb,
- void *internal_cb_context, void *optional_fwcmd_va,
- struct be_mcc_wrb_response_copy *response_copy);
-
-int be_function_queue_mcc_wrb(struct be_function_object *pfob,
- struct be_generic_q_ctxt *q_ctxt);
-
-/*
- * ------------------------------------------------------
- * MCC QUEUE
- * ------------------------------------------------------
- */
-
-int be_mpu_init_mailbox(struct be_function_object *pfob, struct ring_desc *rd);
-
-
-struct MCC_WRB_AMAP *
-_be_mpu_peek_ring_wrb(struct be_mcc_object *mcc, bool driving_queue);
-
-struct be_mcc_wrb_context *
-_be_mcc_allocate_wrb_context(struct be_function_object *pfob);
-
-void _be_mcc_free_wrb_context(struct be_function_object *pfob,
- struct be_mcc_wrb_context *context);
-
-int _be_mpu_post_wrb_mailbox(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context);
-
-int _be_mpu_post_wrb_ring(struct be_mcc_object *mcc,
- struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context);
-
-void be_drive_mcc_wrb_queue(struct be_mcc_object *mcc);
-
-
-/*
- * ------------------------------------------------------
- * Ring Sizes
- * ------------------------------------------------------
- */
-static inline u32 be_ring_encoding_to_length(u32 encoding, u32 object_size)
-{
-
- ASSERT(encoding != 1); /* 1 is rsvd */
- ASSERT(encoding < 16);
- ASSERT(object_size > 0);
-
- if (encoding == 0) /* 32k deep */
- encoding = 16;
-
- return (1 << (encoding - 1)) * object_size;
-}
-
-static inline
-u32 be_ring_length_to_encoding(u32 length_in_bytes, u32 object_size)
-{
-
- u32 count, encoding;
-
- ASSERT(object_size > 0);
- ASSERT(length_in_bytes % object_size == 0);
-
- count = length_in_bytes / object_size;
-
- ASSERT(count > 1);
- ASSERT(count <= 32 * 1024);
- ASSERT(length_in_bytes <= 8 * PAGE_SIZE); /* max ring size in UT */
-
- encoding = __ilog2_u32(count) + 1;
-
- if (encoding == 16)
- encoding = 0; /* 32k deep */
-
- return encoding;
-}
-
-void be_rd_to_pa_list(struct ring_desc *rd, struct PHYS_ADDR *pa_list,
- u32 max_num);
-#endif /* __hwlib_h__ */
diff --git a/drivers/staging/benet/mpu.c b/drivers/staging/benet/mpu.c
deleted file mode 100644
index 269cc11d305..00000000000
--- a/drivers/staging/benet/mpu.c
+++ /dev/null
@@ -1,1364 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include <linux/delay.h>
-#include "hwlib.h"
-#include "bestatus.h"
-
-static
-inline void mp_ring_create(struct mp_ring *ring, u32 num, u32 size, void *va)
-{
- ASSERT(ring);
- memset(ring, 0, sizeof(struct mp_ring));
- ring->num = num;
- ring->pages = DIV_ROUND_UP(num * size, PAGE_SIZE);
- ring->itemSize = size;
- ring->va = va;
-}
-
-/*
- * -----------------------------------------------------------------------
- * Interface for 2 index rings. i.e. consumer/producer rings
- * --------------------------------------------------------------------------
- */
-
-/* Returns number items pending on ring. */
-static inline u32 mp_ring_num_pending(struct mp_ring *ring)
-{
- ASSERT(ring);
- if (ring->num == 0)
- return 0;
- return be_subc(ring->pidx, ring->cidx, ring->num);
-}
-
-/* Returns number items free on ring. */
-static inline u32 mp_ring_num_empty(struct mp_ring *ring)
-{
- ASSERT(ring);
- return ring->num - 1 - mp_ring_num_pending(ring);
-}
-
-/* Consume 1 item */
-static inline void mp_ring_consume(struct mp_ring *ring)
-{
- ASSERT(ring);
- ASSERT(ring->pidx != ring->cidx);
-
- ring->cidx = be_addc(ring->cidx, 1, ring->num);
-}
-
-/* Produce 1 item */
-static inline void mp_ring_produce(struct mp_ring *ring)
-{
- ASSERT(ring);
- ring->pidx = be_addc(ring->pidx, 1, ring->num);
-}
-
-/* Consume count items */
-static inline void mp_ring_consume_multiple(struct mp_ring *ring, u32 count)
-{
- ASSERT(ring);
- ASSERT(mp_ring_num_pending(ring) >= count);
- ring->cidx = be_addc(ring->cidx, count, ring->num);
-}
-
-static inline void *mp_ring_item(struct mp_ring *ring, u32 index)
-{
- ASSERT(ring);
- ASSERT(index < ring->num);
- ASSERT(ring->itemSize > 0);
- return (u8 *) ring->va + index * ring->itemSize;
-}
-
-/* Ptr to produce item */
-static inline void *mp_ring_producer_ptr(struct mp_ring *ring)
-{
- ASSERT(ring);
- return mp_ring_item(ring, ring->pidx);
-}
-
-/*
- * Returns a pointer to the current location in the ring.
- * This is used for rings with 1 index.
- */
-static inline void *mp_ring_current(struct mp_ring *ring)
-{
- ASSERT(ring);
- ASSERT(ring->pidx == 0); /* not used */
-
- return mp_ring_item(ring, ring->cidx);
-}
-
-/*
- * Increment index for rings with only 1 index.
- * This is used for rings with 1 index.
- */
-static inline void *mp_ring_next(struct mp_ring *ring)
-{
- ASSERT(ring);
- ASSERT(ring->num > 0);
- ASSERT(ring->pidx == 0); /* not used */
-
- ring->cidx = be_addc(ring->cidx, 1, ring->num);
- return mp_ring_current(ring);
-}
-
-/*
- This routine waits for a previously posted mailbox WRB to be completed.
- Specifically it waits for the mailbox to say that it's ready to accept
- more data by setting the LSB of the mailbox pd register to 1.
-
- pcontroller - The function object to post this data to
-
- IRQL < DISPATCH_LEVEL
-*/
-static void be_mcc_mailbox_wait(struct be_function_object *pfob)
-{
- struct MPU_MAILBOX_DB_AMAP mailbox_db;
- u32 i = 0;
- u32 ready;
-
- if (pfob->emulate) {
- /* No waiting for mailbox in emulated mode. */
- return;
- }
-
- mailbox_db.dw[0] = PD_READ(pfob, mcc_bootstrap_db);
- ready = AMAP_GET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db);
-
- while (ready == false) {
- if ((++i & 0x3FFFF) == 0) {
- TRACE(DL_WARN, "Waiting for mailbox ready - %dk polls",
- i / 1000);
- }
- udelay(1);
- mailbox_db.dw[0] = PD_READ(pfob, mcc_bootstrap_db);
- ready = AMAP_GET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db);
- }
-}
-
-/*
- This routine tells the MCC mailbox that there is data to processed
- in the mailbox. It does this by setting the physical address for the
- mailbox location and clearing the LSB. This routine returns immediately
- and does not wait for the WRB to be processed.
-
- pcontroller - The function object to post this data to
-
- IRQL < DISPATCH_LEVEL
-
-*/
-static void be_mcc_mailbox_notify(struct be_function_object *pfob)
-{
- struct MPU_MAILBOX_DB_AMAP mailbox_db;
- u32 pa;
-
- ASSERT(pfob->mailbox.pa);
- ASSERT(pfob->mailbox.va);
-
- /* If emulated, do not ring the mailbox */
- if (pfob->emulate) {
- TRACE(DL_WARN, "MPU disabled. Skipping mailbox notify.");
- return;
- }
-
- /* form the higher bits in the address */
- mailbox_db.dw[0] = 0; /* init */
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, hi, &mailbox_db, 1);
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db, 0);
-
- /* bits 34 to 63 */
- pa = (u32) (pfob->mailbox.pa >> 34);
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, address, &mailbox_db, pa);
-
- /* Wait for the MPU to be ready */
- be_mcc_mailbox_wait(pfob);
-
- /* Ring doorbell 1st time */
- PD_WRITE(pfob, mcc_bootstrap_db, mailbox_db.dw[0]);
-
- /* Wait for 1st write to be acknowledged. */
- be_mcc_mailbox_wait(pfob);
-
- /* lower bits 30 bits from 4th bit (bits 4 to 33)*/
- pa = (u32) (pfob->mailbox.pa >> 4) & 0x3FFFFFFF;
-
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, hi, &mailbox_db, 0);
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db, 0);
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, address, &mailbox_db, pa);
-
- /* Ring doorbell 2nd time */
- PD_WRITE(pfob, mcc_bootstrap_db, mailbox_db.dw[0]);
-}
-
-/*
- This routine tells the MCC mailbox that there is data to processed
- in the mailbox. It does this by setting the physical address for the
- mailbox location and clearing the LSB. This routine spins until the
- MPU writes a 1 into the LSB indicating that the data has been received
- and is ready to be processed.
-
- pcontroller - The function object to post this data to
-
- IRQL < DISPATCH_LEVEL
-*/
-static void
-be_mcc_mailbox_notify_and_wait(struct be_function_object *pfob)
-{
- /*
- * Notify it
- */
- be_mcc_mailbox_notify(pfob);
- /*
- * Now wait for completion of WRB
- */
- be_mcc_mailbox_wait(pfob);
-}
-
-void
-be_mcc_process_cqe(struct be_function_object *pfob,
- struct MCC_CQ_ENTRY_AMAP *cqe)
-{
- struct be_mcc_wrb_context *wrb_context = NULL;
- u32 offset, status;
- u8 *p;
-
- ASSERT(cqe);
- /*
- * A command completed. Commands complete out-of-order.
- * Determine which command completed from the TAG.
- */
- offset = offsetof(struct BE_MCC_CQ_ENTRY_AMAP, mcc_tag)/8;
- p = (u8 *) cqe + offset;
- wrb_context = (struct be_mcc_wrb_context *)(void *)(size_t)(*(u64 *)p);
- ASSERT(wrb_context);
-
- /*
- * Perform a response copy if requested.
- * Only copy data if the FWCMD is successful.
- */
- status = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, completion_status, cqe);
- if (status == MGMT_STATUS_SUCCESS && wrb_context->copy.length > 0) {
- ASSERT(wrb_context->wrb);
- ASSERT(wrb_context->copy.va);
- p = (u8 *)wrb_context->wrb +
- offsetof(struct BE_MCC_WRB_AMAP, payload)/8;
- memcpy(wrb_context->copy.va,
- (u8 *)p + wrb_context->copy.fwcmd_offset,
- wrb_context->copy.length);
- }
-
- if (status)
- status = BE_NOT_OK;
- /* internal callback */
- if (wrb_context->internal_cb) {
- wrb_context->internal_cb(wrb_context->internal_cb_context,
- status, wrb_context->wrb);
- }
-
- /* callback */
- if (wrb_context->cb) {
- wrb_context->cb(wrb_context->cb_context,
- status, wrb_context->wrb);
- }
- /* Free the context structure */
- _be_mcc_free_wrb_context(pfob, wrb_context);
-}
-
-void be_drive_mcc_wrb_queue(struct be_mcc_object *mcc)
-{
- struct be_function_object *pfob = NULL;
- int status = BE_PENDING;
- struct be_generic_q_ctxt *q_ctxt;
- struct MCC_WRB_AMAP *wrb;
- struct MCC_WRB_AMAP *queue_wrb;
- u32 length, payload_length, sge_count, embedded;
- unsigned long irql;
-
- BUILD_BUG_ON((sizeof(struct be_generic_q_ctxt) <
- sizeof(struct be_queue_driver_context) +
- sizeof(struct MCC_WRB_AMAP)));
- pfob = mcc->parent_function;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- if (mcc->driving_backlog) {
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return;
- }
- /* Acquire the flag to limit 1 thread to redrive posts. */
- mcc->driving_backlog = 1;
-
- while (!list_empty(&mcc->backlog)) {
- wrb = _be_mpu_peek_ring_wrb(mcc, true); /* Driving the queue */
- if (!wrb)
- break; /* No space in the ring yet. */
- /* Get the next queued entry to process. */
- q_ctxt = list_first_entry(&mcc->backlog,
- struct be_generic_q_ctxt, context.list);
- list_del(&q_ctxt->context.list);
- pfob->mcc->backlog_length--;
- /*
- * Compute the required length of the WRB.
- * Since the queue element may be smaller than
- * the complete WRB, copy only the required number of bytes.
- */
- queue_wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, queue_wrb);
- if (embedded) {
- payload_length = AMAP_GET_BITS_PTR(MCC_WRB,
- payload_length, queue_wrb);
- length = sizeof(struct be_mcc_wrb_header) +
- payload_length;
- } else {
- sge_count = AMAP_GET_BITS_PTR(MCC_WRB, sge_count,
- queue_wrb);
- ASSERT(sge_count == 1); /* only 1 frag. */
- length = sizeof(struct be_mcc_wrb_header) +
- sge_count * sizeof(struct MCC_SGE_AMAP);
- }
-
- /*
- * Truncate the length based on the size of the
- * queue element. Some elements that have output parameters
- * can be smaller than the payload_length field would
- * indicate. We really only need to copy the request
- * parameters, not the response.
- */
- length = min(length, (u32) (q_ctxt->context.bytes -
- offsetof(struct be_generic_q_ctxt, wrb_header)));
-
- /* Copy the queue element WRB into the ring. */
- memcpy(wrb, &q_ctxt->wrb_header, length);
-
- /* Post the wrb. This should not fail assuming we have
- * enough context structs. */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL,
- q_ctxt->context.cb, q_ctxt->context.cb_context,
- q_ctxt->context.internal_cb,
- q_ctxt->context.internal_cb_context,
- q_ctxt->context.optional_fwcmd_va,
- &q_ctxt->context.copy);
-
- if (status == BE_SUCCESS) {
- /*
- * Synchronous completion. Since it was queued,
- * we will invoke the callback.
- * To the user, this is an asynchronous request.
- */
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
-
- ASSERT(q_ctxt->context.cb);
-
- q_ctxt->context.cb(
- q_ctxt->context.cb_context,
- BE_SUCCESS, NULL);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- } else if (status != BE_PENDING) {
- /*
- * Another resource failed. Should never happen
- * if we have sufficient MCC_WRB_CONTEXT structs.
- * Return to head of the queue.
- */
- TRACE(DL_WARN, "Failed to post a queued WRB. 0x%x",
- status);
- list_add(&q_ctxt->context.list, &mcc->backlog);
- pfob->mcc->backlog_length++;
- break;
- }
- }
-
- /* Free the flag to limit 1 thread to redrive posts. */
- mcc->driving_backlog = 0;
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-}
-
-/* This function asserts that the WRB was consumed in order. */
-#ifdef BE_DEBUG
-u32 be_mcc_wrb_consumed_in_order(struct be_mcc_object *mcc,
- struct MCC_CQ_ENTRY_AMAP *cqe)
-{
- struct be_mcc_wrb_context *wrb_context = NULL;
- u32 wrb_index;
- u32 wrb_consumed_in_order;
- u32 offset;
- u8 *p;
-
- ASSERT(cqe);
- /*
- * A command completed. Commands complete out-of-order.
- * Determine which command completed from the TAG.
- */
- offset = offsetof(struct BE_MCC_CQ_ENTRY_AMAP, mcc_tag)/8;
- p = (u8 *) cqe + offset;
- wrb_context = (struct be_mcc_wrb_context *)(void *)(size_t)(*(u64 *)p);
-
- ASSERT(wrb_context);
-
- wrb_index = (u32) (((u64)(size_t)wrb_context->ring_wrb -
- (u64)(size_t)mcc->sq.ring.va) / sizeof(struct MCC_WRB_AMAP));
-
- ASSERT(wrb_index < mcc->sq.ring.num);
-
- wrb_consumed_in_order = (u32) (wrb_index == mcc->consumed_index);
- mcc->consumed_index = be_addc(mcc->consumed_index, 1, mcc->sq.ring.num);
- return wrb_consumed_in_order;
-}
-#endif
-
-int be_mcc_process_cq(struct be_mcc_object *mcc, bool rearm)
-{
- struct be_function_object *pfob = NULL;
- struct MCC_CQ_ENTRY_AMAP *cqe;
- struct CQ_DB_AMAP db;
- struct mp_ring *cq_ring = &mcc->cq.ring;
- struct mp_ring *mp_ring = &mcc->sq.ring;
- u32 num_processed = 0;
- u32 consumed = 0, valid, completed, cqe_consumed, async_event;
-
- pfob = mcc->parent_function;
-
- spin_lock_irqsave(&pfob->cq_lock, pfob->cq_irq);
-
- /*
- * Verify that only one thread is processing the CQ at once.
- * We cannot hold the lock while processing the CQ due to
- * the callbacks into the OS. Therefore, this flag is used
- * to control it. If any of the threads want to
- * rearm the CQ, we need to honor that.
- */
- if (mcc->processing != 0) {
- mcc->rearm = mcc->rearm || rearm;
- goto Error;
- } else {
- mcc->processing = 1; /* lock processing for this thread. */
- mcc->rearm = rearm; /* set our rearm setting */
- }
-
- spin_unlock_irqrestore(&pfob->cq_lock, pfob->cq_irq);
-
- cqe = mp_ring_current(cq_ring);
- valid = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe);
- while (valid) {
-
- if (num_processed >= 8) {
- /* coalesce doorbells, but free space in cq
- * ring while processing. */
- db.dw[0] = 0; /* clear */
- AMAP_SET_BITS_PTR(CQ_DB, qid, &db, cq_ring->id);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &db, false);
- AMAP_SET_BITS_PTR(CQ_DB, event, &db, false);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &db,
- num_processed);
- num_processed = 0;
-
- PD_WRITE(pfob, cq_db, db.dw[0]);
- }
-
- async_event = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, async_event, cqe);
- if (async_event) {
- /* This is an asynchronous event. */
- struct ASYNC_EVENT_TRAILER_AMAP *async_trailer =
- (struct ASYNC_EVENT_TRAILER_AMAP *)
- ((u8 *) cqe + sizeof(struct MCC_CQ_ENTRY_AMAP) -
- sizeof(struct ASYNC_EVENT_TRAILER_AMAP));
- u32 event_code;
- async_event = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER,
- async_event, async_trailer);
- ASSERT(async_event == 1);
-
-
- valid = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER,
- valid, async_trailer);
- ASSERT(valid == 1);
-
- /* Call the async event handler if it is installed. */
- if (mcc->async_cb) {
- event_code =
- AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER,
- event_code, async_trailer);
- mcc->async_cb(mcc->async_context,
- (u32) event_code, (void *) cqe);
- }
-
- } else {
- /* This is a completion entry. */
-
- /* No vm forwarding in this driver. */
-
- cqe_consumed = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY,
- consumed, cqe);
- if (cqe_consumed) {
- /*
- * A command on the MCC ring was consumed.
- * Update the consumer index.
- * These occur in order.
- */
- ASSERT(be_mcc_wrb_consumed_in_order(mcc, cqe));
- consumed++;
- }
-
- completed = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY,
- completed, cqe);
- if (completed) {
- /* A command completed. Use tag to
- * determine which command. */
- be_mcc_process_cqe(pfob, cqe);
- }
- }
-
- /* Reset the CQE */
- AMAP_SET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe, false);
- num_processed++;
-
- /* Update our tracking for the CQ ring. */
- cqe = mp_ring_next(cq_ring);
- valid = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe);
- }
-
- TRACE(DL_INFO, "num_processed:0x%x, and consumed:0x%x",
- num_processed, consumed);
- /*
- * Grab the CQ lock to synchronize the "rearm" setting for
- * the doorbell, and for clearing the "processing" flag.
- */
- spin_lock_irqsave(&pfob->cq_lock, pfob->cq_irq);
-
- /*
- * Rearm the cq. This is done based on the global mcc->rearm
- * flag which combines the rearm parameter from the current
- * call to process_cq and any other threads
- * that tried to process the CQ while this one was active.
- * This handles the situation where a sync. fwcmd was processing
- * the CQ while the interrupt/dpc tries to process it.
- * The sync process gets to continue -- but it is now
- * responsible for the rearming.
- */
- if (num_processed > 0 || mcc->rearm == true) {
- db.dw[0] = 0; /* clear */
- AMAP_SET_BITS_PTR(CQ_DB, qid, &db, cq_ring->id);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &db, mcc->rearm);
- AMAP_SET_BITS_PTR(CQ_DB, event, &db, false);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &db, num_processed);
-
- PD_WRITE(pfob, cq_db, db.dw[0]);
- }
- /*
- * Update the consumer index after ringing the CQ doorbell.
- * We don't want another thread to post more WRBs before we
- * have CQ space available.
- */
- mp_ring_consume_multiple(mp_ring, consumed);
-
- /* Clear the processing flag. */
- mcc->processing = 0;
-
-Error:
- spin_unlock_irqrestore(&pfob->cq_lock, pfob->cq_irq);
- /*
- * Use the local variable to detect if the current thread
- * holds the WRB post lock. If rearm is false, this is
- * either a synchronous command, or the upper layer driver is polling
- * from a thread. We do not drive the queue from that
- * context since the driver may hold the
- * wrb post lock already.
- */
- if (rearm)
- be_drive_mcc_wrb_queue(mcc);
- else
- pfob->pend_queue_driving = 1;
-
- return BE_SUCCESS;
-}
-
-/*
- *============================================================================
- * P U B L I C R O U T I N E S
- *============================================================================
- */
-
-/*
- This routine creates an MCC object. This object contains an MCC send queue
- and a CQ private to the MCC.
-
- pcontroller - Handle to a function object
-
- EqObject - EQ object that will be used to dispatch this MCC
-
- ppMccObject - Pointer to an internal Mcc Object returned.
-
- Returns BE_SUCCESS if successfull,, otherwise a useful error code
- is returned.
-
- IRQL < DISPATCH_LEVEL
-
-*/
-int
-be_mcc_ring_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length,
- struct be_mcc_wrb_context *context_array,
- u32 num_context_entries,
- struct be_cq_object *cq, struct be_mcc_object *mcc)
-{
- int status = 0;
-
- struct FWCMD_COMMON_MCC_CREATE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 num_entries_encoded, n, i;
- void *va = NULL;
- unsigned long irql;
-
- if (length < sizeof(struct MCC_WRB_AMAP) * 2) {
- TRACE(DL_ERR, "Invalid MCC ring length:%d", length);
- return BE_NOT_OK;
- }
- /*
- * Reduce the actual ring size to be less than the number
- * of context entries. This ensures that we run out of
- * ring WRBs first so the queuing works correctly. We never
- * queue based on context structs.
- */
- if (num_context_entries + 1 <
- length / sizeof(struct MCC_WRB_AMAP) - 1) {
-
- u32 max_length =
- (num_context_entries + 2) * sizeof(struct MCC_WRB_AMAP);
-
- if (is_power_of_2(max_length))
- length = __roundup_pow_of_two(max_length+1) / 2;
- else
- length = __roundup_pow_of_two(max_length) / 2;
-
- ASSERT(length <= max_length);
-
- TRACE(DL_WARN,
- "MCC ring length reduced based on context entries."
- " length:%d wrbs:%d context_entries:%d", length,
- (int) (length / sizeof(struct MCC_WRB_AMAP)),
- num_context_entries);
- }
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- num_entries_encoded =
- be_ring_length_to_encoding(length, sizeof(struct MCC_WRB_AMAP));
-
- /* Init MCC object. */
- memset(mcc, 0, sizeof(*mcc));
- mcc->parent_function = pfob;
- mcc->cq_object = cq;
-
- INIT_LIST_HEAD(&mcc->backlog);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_MCC_CREATE);
-
- fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
- /*
- * Program MCC ring context
- */
- AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, pdid,
- &fwcmd->params.request.context, 0);
- AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, invalid,
- &fwcmd->params.request.context, false);
- AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, ring_size,
- &fwcmd->params.request.context, num_entries_encoded);
-
- n = cq->cq_id;
- AMAP_SET_BITS_PTR(MCC_RING_CONTEXT,
- cq_id, &fwcmd->params.request.context, n);
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "MCC to create CQ failed.");
- goto error;
- }
- /*
- * Create a linked list of context structures
- */
- mcc->wrb_context.base = context_array;
- mcc->wrb_context.num = num_context_entries;
- INIT_LIST_HEAD(&mcc->wrb_context.list_head);
- memset(context_array, 0,
- sizeof(struct be_mcc_wrb_context) * num_context_entries);
- for (i = 0; i < mcc->wrb_context.num; i++) {
- list_add_tail(&context_array[i].next,
- &mcc->wrb_context.list_head);
- }
-
- /*
- *
- * Create an mcc_ring for tracking WRB hw ring
- */
- va = rd->va;
- ASSERT(va);
- mp_ring_create(&mcc->sq.ring, length / sizeof(struct MCC_WRB_AMAP),
- sizeof(struct MCC_WRB_AMAP), va);
- mcc->sq.ring.id = fwcmd->params.response.id;
- /*
- * Init a mcc_ring for tracking the MCC CQ.
- */
- ASSERT(cq->va);
- mp_ring_create(&mcc->cq.ring, cq->num_entries,
- sizeof(struct MCC_CQ_ENTRY_AMAP), cq->va);
- mcc->cq.ring.id = cq->cq_id;
-
- /* Force zeroing of CQ. */
- memset(cq->va, 0, cq->num_entries * sizeof(struct MCC_CQ_ENTRY_AMAP));
-
- /* Initialize debug index. */
- mcc->consumed_index = 0;
-
- atomic_inc(&cq->ref_count);
- pfob->mcc = mcc;
-
- TRACE(DL_INFO, "MCC ring created. id:%d bytes:%d cq_id:%d cq_entries:%d"
- " num_context:%d", mcc->sq.ring.id, length,
- cq->cq_id, cq->num_entries, num_context_entries);
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine destroys an MCC send queue
-
- MccObject - Internal Mcc Object to be destroyed.
-
- Returns BE_SUCCESS if successfull, otherwise an error code is returned.
-
- IRQL < DISPATCH_LEVEL
-
- The caller of this routine must ensure that no other WRB may be posted
- until this routine returns.
-
-*/
-int be_mcc_ring_destroy(struct be_mcc_object *mcc)
-{
- int status = 0;
- struct be_function_object *pfob = mcc->parent_function;
-
-
- ASSERT(mcc->processing == 0);
-
- /*
- * Remove the ring from the function object.
- * This transitions back to mailbox mode.
- */
- pfob->mcc = NULL;
-
- /* Send fwcmd to destroy the queue. (Using the mailbox.) */
- status = be_function_ring_destroy(mcc->parent_function, mcc->sq.ring.id,
- FWCMD_RING_TYPE_MCC, NULL, NULL, NULL, NULL);
- ASSERT(status == 0);
-
- /* Release the SQ reference to the CQ */
- atomic_dec(&mcc->cq_object->ref_count);
-
- return status;
-}
-
-static void
-mcc_wrb_sync_cb(void *context, int staus, struct MCC_WRB_AMAP *wrb)
-{
- struct be_mcc_wrb_context *wrb_context =
- (struct be_mcc_wrb_context *) context;
- ASSERT(wrb_context);
- *wrb_context->users_final_status = staus;
-}
-
-/*
- This routine posts a command to the MCC send queue
-
- mcc - Internal Mcc Object to be destroyed.
-
- wrb - wrb to post.
-
- Returns BE_SUCCESS if successfull, otherwise an error code is returned.
-
- IRQL < DISPATCH_LEVEL if CompletionCallback is not NULL
- IRQL <=DISPATCH_LEVEL if CompletionCallback is NULL
-
- If this routine is called with CompletionCallback != NULL the
- call is considered to be asynchronous and will return as soon
- as the WRB is posted to the MCC with BE_PENDING.
-
- If CompletionCallback is NULL, then this routine will not return until
- a completion for this MCC command has been processed.
- If called at DISPATCH_LEVEL the CompletionCallback must be NULL.
-
- This routine should only be called if the MPU has been boostraped past
- mailbox mode.
-
-
-*/
-int
-_be_mpu_post_wrb_ring(struct be_mcc_object *mcc, struct MCC_WRB_AMAP *wrb,
- struct be_mcc_wrb_context *wrb_context)
-{
-
- struct MCC_WRB_AMAP *ring_wrb = NULL;
- int status = BE_PENDING;
- int final_status = BE_PENDING;
- mcc_wrb_cqe_callback cb = NULL;
- struct MCC_DB_AMAP mcc_db;
- u32 embedded;
-
- ASSERT(mp_ring_num_empty(&mcc->sq.ring) > 0);
- /*
- * Input wrb is most likely the next wrb in the ring, since the client
- * can peek at the address.
- */
- ring_wrb = mp_ring_producer_ptr(&mcc->sq.ring);
- if (wrb != ring_wrb) {
- /* If not equal, copy it into the ring. */
- memcpy(ring_wrb, wrb, sizeof(struct MCC_WRB_AMAP));
- }
-#ifdef BE_DEBUG
- wrb_context->ring_wrb = ring_wrb;
-#endif
- embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, ring_wrb);
- if (embedded) {
- /* embedded commands will have the response within the WRB. */
- wrb_context->wrb = ring_wrb;
- } else {
- /*
- * non-embedded commands will not have the response
- * within the WRB, and they may complete out-of-order.
- * The WRB will not be valid to inspect
- * during the completion.
- */
- wrb_context->wrb = NULL;
- }
- cb = wrb_context->cb;
-
- if (cb == NULL) {
- /* Assign our internal callback if this is a
- * synchronous call. */
- wrb_context->cb = mcc_wrb_sync_cb;
- wrb_context->cb_context = wrb_context;
- wrb_context->users_final_status = &final_status;
- }
- /* Increment producer index */
-
- mcc_db.dw[0] = 0; /* initialize */
- AMAP_SET_BITS_PTR(MCC_DB, rid, &mcc_db, mcc->sq.ring.id);
- AMAP_SET_BITS_PTR(MCC_DB, numPosted, &mcc_db, 1);
-
- mp_ring_produce(&mcc->sq.ring);
- PD_WRITE(mcc->parent_function, mpu_mcc_db, mcc_db.dw[0]);
- TRACE(DL_INFO, "pidx: %x and cidx: %x.", mcc->sq.ring.pidx,
- mcc->sq.ring.cidx);
-
- if (cb == NULL) {
- int polls = 0; /* At >= 1 us per poll */
- /* Wait until this command completes, polling the CQ. */
- do {
- TRACE(DL_INFO, "FWCMD submitted in the poll mode.");
- /* Do not rearm CQ in this context. */
- be_mcc_process_cq(mcc, false);
-
- if (final_status == BE_PENDING) {
- if ((++polls & 0x7FFFF) == 0) {
- TRACE(DL_WARN,
- "Warning : polling MCC CQ for %d"
- "ms.", polls / 1000);
- }
-
- udelay(1);
- }
-
- /* final_status changed when the command completes */
- } while (final_status == BE_PENDING);
-
- status = final_status;
- }
-
- return status;
-}
-
-struct MCC_WRB_AMAP *
-_be_mpu_peek_ring_wrb(struct be_mcc_object *mcc, bool driving_queue)
-{
- /* If we have queued items, do not allow a post to bypass the queue. */
- if (!driving_queue && !list_empty(&mcc->backlog))
- return NULL;
-
- if (mp_ring_num_empty(&mcc->sq.ring) <= 0)
- return NULL;
- return (struct MCC_WRB_AMAP *) mp_ring_producer_ptr(&mcc->sq.ring);
-}
-
-int
-be_mpu_init_mailbox(struct be_function_object *pfob, struct ring_desc *mailbox)
-{
- ASSERT(mailbox);
- pfob->mailbox.va = mailbox->va;
- pfob->mailbox.pa = cpu_to_le64(mailbox->pa);
- pfob->mailbox.length = mailbox->length;
-
- ASSERT(((u32)(size_t)pfob->mailbox.va & 0xf) == 0);
- ASSERT(((u32)(size_t)pfob->mailbox.pa & 0xf) == 0);
- /*
- * Issue the WRB to set MPU endianness
- */
- {
- u64 *endian_check = (u64 *) (pfob->mailbox.va +
- offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8);
- *endian_check = 0xFF1234FFFF5678FFULL;
- }
-
- be_mcc_mailbox_notify_and_wait(pfob);
-
- return BE_SUCCESS;
-}
-
-
-/*
- This routine posts a command to the MCC mailbox.
-
- FuncObj - Function Object to post the WRB on behalf of.
- wrb - wrb to post.
- CompletionCallback - Address of a callback routine to invoke once the WRB
- is completed.
- CompletionCallbackContext - Opaque context to be passed during the call to
- the CompletionCallback.
- Returns BE_SUCCESS if successfull, otherwise an error code is returned.
-
- IRQL <=DISPATCH_LEVEL if CompletionCallback is NULL
-
- This routine will block until a completion for this MCC command has been
- processed. If called at DISPATCH_LEVEL the CompletionCallback must be NULL.
-
- This routine should only be called if the MPU has not been boostraped past
- mailbox mode.
-*/
-int
-_be_mpu_post_wrb_mailbox(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context)
-{
- struct MCC_MAILBOX_AMAP *mailbox = NULL;
- struct MCC_WRB_AMAP *mb_wrb;
- struct MCC_CQ_ENTRY_AMAP *mb_cq;
- u32 offset, status;
-
- ASSERT(pfob->mcc == NULL);
- mailbox = pfob->mailbox.va;
- ASSERT(mailbox);
-
- offset = offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8;
- mb_wrb = (struct MCC_WRB_AMAP *) (u8 *)mailbox + offset;
- if (mb_wrb != wrb) {
- memset(mailbox, 0, sizeof(*mailbox));
- memcpy(mb_wrb, wrb, sizeof(struct MCC_WRB_AMAP));
- }
- /* The callback can inspect the final WRB to get output parameters. */
- wrb_context->wrb = mb_wrb;
-
- be_mcc_mailbox_notify_and_wait(pfob);
-
- /* A command completed. Use tag to determine which command. */
- offset = offsetof(struct BE_MCC_MAILBOX_AMAP, cq)/8;
- mb_cq = (struct MCC_CQ_ENTRY_AMAP *) ((u8 *)mailbox + offset);
- be_mcc_process_cqe(pfob, mb_cq);
-
- status = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, completion_status, mb_cq);
- if (status)
- status = BE_NOT_OK;
- return status;
-}
-
-struct be_mcc_wrb_context *
-_be_mcc_allocate_wrb_context(struct be_function_object *pfob)
-{
- struct be_mcc_wrb_context *context = NULL;
- unsigned long irq;
-
- spin_lock_irqsave(&pfob->mcc_context_lock, irq);
-
- if (!pfob->mailbox.default_context_allocated) {
- /* Use the single default context that we
- * always have allocated. */
- pfob->mailbox.default_context_allocated = true;
- context = &pfob->mailbox.default_context;
- } else if (pfob->mcc) {
- /* Get a context from the free list. If any are available. */
- if (!list_empty(&pfob->mcc->wrb_context.list_head)) {
- context = list_first_entry(
- &pfob->mcc->wrb_context.list_head,
- struct be_mcc_wrb_context, next);
- }
- }
-
- spin_unlock_irqrestore(&pfob->mcc_context_lock, irq);
-
- return context;
-}
-
-void
-_be_mcc_free_wrb_context(struct be_function_object *pfob,
- struct be_mcc_wrb_context *context)
-{
- unsigned long irq;
-
- ASSERT(context);
- /*
- * Zero during free to try and catch any bugs where the context
- * is accessed after a free.
- */
- memset(context, 0, sizeof(context));
-
- spin_lock_irqsave(&pfob->mcc_context_lock, irq);
-
- if (context == &pfob->mailbox.default_context) {
- /* Free the default context. */
- ASSERT(pfob->mailbox.default_context_allocated);
- pfob->mailbox.default_context_allocated = false;
- } else {
- /* Add to free list. */
- ASSERT(pfob->mcc);
- list_add_tail(&context->next,
- &pfob->mcc->wrb_context.list_head);
- }
-
- spin_unlock_irqrestore(&pfob->mcc_context_lock, irq);
-}
-
-int
-be_mcc_add_async_event_callback(struct be_mcc_object *mcc_object,
- mcc_async_event_callback cb, void *cb_context)
-{
- /* Lock against anyone trying to change the callback/context pointers
- * while being used. */
- spin_lock_irqsave(&mcc_object->parent_function->cq_lock,
- mcc_object->parent_function->cq_irq);
-
- /* Assign the async callback. */
- mcc_object->async_context = cb_context;
- mcc_object->async_cb = cb;
-
- spin_unlock_irqrestore(&mcc_object->parent_function->cq_lock,
- mcc_object->parent_function->cq_irq);
-
- return BE_SUCCESS;
-}
-
-#define MPU_EP_CONTROL 0
-#define MPU_EP_SEMAPHORE 0xac
-
-/*
- *-------------------------------------------------------------------
- * Function: be_wait_for_POST_complete
- * Waits until the BladeEngine POST completes (either in error or success).
- * pfob -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *-------------------------------------------------------------------
- */
-static int be_wait_for_POST_complete(struct be_function_object *pfob)
-{
- struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status;
- int s;
- u32 post_error, post_stage;
-
- const u32 us_per_loop = 1000; /* 1000us */
- const u32 print_frequency_loops = 1000000 / us_per_loop;
- const u32 max_loops = 60 * print_frequency_loops;
- u32 loops = 0;
-
- /*
- * Wait for arm fw indicating it is done or a fatal error happened.
- * Note: POST can take some time to complete depending on configuration
- * settings (consider ARM attempts to acquire an IP address
- * over DHCP!!!).
- *
- */
- do {
- status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE);
- post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT,
- error, &status);
- post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT,
- stage, &status);
- if (0 == (loops % print_frequency_loops)) {
- /* Print current status */
- TRACE(DL_INFO, "POST status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- }
- udelay(us_per_loop);
- } while ((post_error != 1) &&
- (post_stage != POST_STAGE_ARMFW_READY) &&
- (++loops < max_loops));
-
- if (post_error == 1) {
- TRACE(DL_ERR, "POST error! Status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- s = BE_NOT_OK;
- } else if (post_stage != POST_STAGE_ARMFW_READY) {
- TRACE(DL_ERR, "POST time-out! Status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- s = BE_NOT_OK;
- } else {
- s = BE_SUCCESS;
- }
- return s;
-}
-
-/*
- *-------------------------------------------------------------------
- * Function: be_kickoff_and_wait_for_POST
- * Interacts with the BladeEngine management processor to initiate POST, and
- * subsequently waits until POST completes (either in error or success).
- * The caller must acquire the reset semaphore before initiating POST
- * to prevent multiple drivers interacting with the management processor.
- * Once POST is complete the caller must release the reset semaphore.
- * Callers who only want to wait for POST complete may call
- * be_wait_for_POST_complete.
- * pfob -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *-------------------------------------------------------------------
- */
-static int
-be_kickoff_and_wait_for_POST(struct be_function_object *pfob)
-{
- struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status;
- int s;
-
- const u32 us_per_loop = 1000; /* 1000us */
- const u32 print_frequency_loops = 1000000 / us_per_loop;
- const u32 max_loops = 5 * print_frequency_loops;
- u32 loops = 0;
- u32 post_error, post_stage;
-
- /* Wait for arm fw awaiting host ready or a fatal error happened. */
- TRACE(DL_INFO, "Wait for BladeEngine ready to POST");
- do {
- status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE);
- post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT,
- error, &status);
- post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT,
- stage, &status);
- if (0 == (loops % print_frequency_loops)) {
- /* Print current status */
- TRACE(DL_INFO, "POST status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- }
- udelay(us_per_loop);
- } while ((post_error != 1) &&
- (post_stage < POST_STAGE_AWAITING_HOST_RDY) &&
- (++loops < max_loops));
-
- if (post_error == 1) {
- TRACE(DL_ERR, "Pre-POST error! Status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- s = BE_NOT_OK;
- } else if (post_stage == POST_STAGE_AWAITING_HOST_RDY) {
- iowrite32(POST_STAGE_HOST_RDY, pfob->csr_va + MPU_EP_SEMAPHORE);
-
- /* Wait for POST to complete */
- s = be_wait_for_POST_complete(pfob);
- } else {
- /*
- * Either a timeout waiting for host ready signal or POST has
- * moved ahead without requiring a host ready signal.
- * Might as well give POST a chance to complete
- * (or timeout again).
- */
- s = be_wait_for_POST_complete(pfob);
- }
- return s;
-}
-
-/*
- *-------------------------------------------------------------------
- * Function: be_pci_soft_reset
- * This function is called to issue a BladeEngine soft reset.
- * Callers should acquire the soft reset semaphore before calling this
- * function. Additionaly, callers should ensure they cannot be pre-empted
- * while the routine executes. Upon completion of this routine, callers
- * should release the reset semaphore. This routine implicitly waits
- * for BladeEngine POST to complete.
- * pfob -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *-------------------------------------------------------------------
- */
-int be_pci_soft_reset(struct be_function_object *pfob)
-{
- struct PCICFG_SOFT_RESET_CSR_AMAP soft_reset;
- struct PCICFG_ONLINE0_CSR_AMAP pciOnline0;
- struct PCICFG_ONLINE1_CSR_AMAP pciOnline1;
- struct EP_CONTROL_CSR_AMAP epControlCsr;
- int status = BE_SUCCESS;
- u32 i, soft_reset_bit;
-
- TRACE(DL_NOTE, "PCI reset...");
-
- /* Issue soft reset #1 to get BladeEngine into a known state. */
- soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset);
- AMAP_SET_BITS_PTR(PCICFG_SOFT_RESET_CSR, softreset, soft_reset.dw, 1);
- PCICFG0_WRITE(pfob, host_timer_int_ctrl, soft_reset.dw[0]);
- /*
- * wait til soft reset is deasserted - hardware
- * deasserts after some time.
- */
- i = 0;
- do {
- udelay(50);
- soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset);
- soft_reset_bit = AMAP_GET_BITS_PTR(PCICFG_SOFT_RESET_CSR,
- softreset, soft_reset.dw);
- } while (soft_reset_bit && (i++ < 1024));
- if (soft_reset_bit != 0) {
- TRACE(DL_ERR, "Soft-reset #1 did not deassert as expected.");
- status = BE_NOT_OK;
- goto Error_label;
- }
- /* Mask everything */
- PCICFG0_WRITE(pfob, ue_status_low_mask, 0xFFFFFFFF);
- PCICFG0_WRITE(pfob, ue_status_hi_mask, 0xFFFFFFFF);
- /*
- * Set everything offline except MPU IRAM (it is offline with
- * the soft-reset, but soft-reset does not reset the PCICFG registers!)
- */
- pciOnline0.dw[0] = 0;
- pciOnline1.dw[0] = 0;
- AMAP_SET_BITS_PTR(PCICFG_ONLINE1_CSR, mpu_iram_online,
- pciOnline1.dw, 1);
- PCICFG0_WRITE(pfob, online0, pciOnline0.dw[0]);
- PCICFG0_WRITE(pfob, online1, pciOnline1.dw[0]);
-
- udelay(20000);
-
- /* Issue soft reset #2. */
- AMAP_SET_BITS_PTR(PCICFG_SOFT_RESET_CSR, softreset, soft_reset.dw, 1);
- PCICFG0_WRITE(pfob, host_timer_int_ctrl, soft_reset.dw[0]);
- /*
- * wait til soft reset is deasserted - hardware
- * deasserts after some time.
- */
- i = 0;
- do {
- udelay(50);
- soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset);
- soft_reset_bit = AMAP_GET_BITS_PTR(PCICFG_SOFT_RESET_CSR,
- softreset, soft_reset.dw);
- } while (soft_reset_bit && (i++ < 1024));
- if (soft_reset_bit != 0) {
- TRACE(DL_ERR, "Soft-reset #1 did not deassert as expected.");
- status = BE_NOT_OK;
- goto Error_label;
- }
-
-
- udelay(20000);
-
- /* Take MPU out of reset. */
-
- epControlCsr.dw[0] = ioread32(pfob->csr_va + MPU_EP_CONTROL);
- AMAP_SET_BITS_PTR(EP_CONTROL_CSR, CPU_reset, &epControlCsr, 0);
- iowrite32((u32)epControlCsr.dw[0], pfob->csr_va + MPU_EP_CONTROL);
-
- /* Kickoff BE POST and wait for completion */
- status = be_kickoff_and_wait_for_POST(pfob);
-
-Error_label:
- return status;
-}
-
-
-/*
- *-------------------------------------------------------------------
- * Function: be_pci_reset_required
- * This private function is called to detect if a host entity is
- * required to issue a PCI soft reset and subsequently drive
- * BladeEngine POST. Scenarios where this is required:
- * 1) BIOS-less configuration
- * 2) Hot-swap/plug/power-on
- * pfob -
- * return true if a reset is required, false otherwise
- *-------------------------------------------------------------------
- */
-static bool be_pci_reset_required(struct be_function_object *pfob)
-{
- struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status;
- bool do_reset = false;
- u32 post_error, post_stage;
-
- /*
- * Read the POST status register
- */
- status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE);
- post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, error,
- &status);
- post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, stage,
- &status);
- if (post_stage <= POST_STAGE_AWAITING_HOST_RDY) {
- /*
- * If BladeEngine is waiting for host ready indication,
- * we want to do a PCI reset.
- */
- do_reset = true;
- }
-
- return do_reset;
-}
-
-/*
- *-------------------------------------------------------------------
- * Function: be_drive_POST
- * This function is called to drive BladeEngine POST. The
- * caller should ensure they cannot be pre-empted while this routine executes.
- * pfob -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *-------------------------------------------------------------------
- */
-int be_drive_POST(struct be_function_object *pfob)
-{
- int status;
-
- if (false != be_pci_reset_required(pfob)) {
- /* PCI reset is needed (implicitly starts and waits for POST) */
- status = be_pci_soft_reset(pfob);
- } else {
- /* No PCI reset is needed, start POST */
- status = be_kickoff_and_wait_for_POST(pfob);
- }
-
- return status;
-}
diff --git a/drivers/staging/benet/mpu.h b/drivers/staging/benet/mpu.h
deleted file mode 100644
index 41f3f87516e..00000000000
--- a/drivers/staging/benet/mpu.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __mpu_amap_h__
-#define __mpu_amap_h__
-#include "ep.h"
-
-/* Provide control parameters for the Managment Processor Unit. */
-struct BE_MPU_CSRMAP_AMAP {
- struct BE_EP_CSRMAP_AMAP ep;
- u8 rsvd0[128]; /* DWORD 64 */
- u8 rsvd1[32]; /* DWORD 68 */
- u8 rsvd2[192]; /* DWORD 69 */
- u8 rsvd3[192]; /* DWORD 75 */
- u8 rsvd4[32]; /* DWORD 81 */
- u8 rsvd5[32]; /* DWORD 82 */
- u8 rsvd6[32]; /* DWORD 83 */
- u8 rsvd7[32]; /* DWORD 84 */
- u8 rsvd8[32]; /* DWORD 85 */
- u8 rsvd9[32]; /* DWORD 86 */
- u8 rsvd10[32]; /* DWORD 87 */
- u8 rsvd11[32]; /* DWORD 88 */
- u8 rsvd12[32]; /* DWORD 89 */
- u8 rsvd13[32]; /* DWORD 90 */
- u8 rsvd14[32]; /* DWORD 91 */
- u8 rsvd15[32]; /* DWORD 92 */
- u8 rsvd16[32]; /* DWORD 93 */
- u8 rsvd17[32]; /* DWORD 94 */
- u8 rsvd18[32]; /* DWORD 95 */
- u8 rsvd19[32]; /* DWORD 96 */
- u8 rsvd20[32]; /* DWORD 97 */
- u8 rsvd21[32]; /* DWORD 98 */
- u8 rsvd22[32]; /* DWORD 99 */
- u8 rsvd23[32]; /* DWORD 100 */
- u8 rsvd24[32]; /* DWORD 101 */
- u8 rsvd25[32]; /* DWORD 102 */
- u8 rsvd26[32]; /* DWORD 103 */
- u8 rsvd27[32]; /* DWORD 104 */
- u8 rsvd28[96]; /* DWORD 105 */
- u8 rsvd29[32]; /* DWORD 108 */
- u8 rsvd30[32]; /* DWORD 109 */
- u8 rsvd31[32]; /* DWORD 110 */
- u8 rsvd32[32]; /* DWORD 111 */
- u8 rsvd33[32]; /* DWORD 112 */
- u8 rsvd34[96]; /* DWORD 113 */
- u8 rsvd35[32]; /* DWORD 116 */
- u8 rsvd36[32]; /* DWORD 117 */
- u8 rsvd37[32]; /* DWORD 118 */
- u8 rsvd38[32]; /* DWORD 119 */
- u8 rsvd39[32]; /* DWORD 120 */
- u8 rsvd40[32]; /* DWORD 121 */
- u8 rsvd41[134][32]; /* DWORD 122 */
-} __packed;
-struct MPU_CSRMAP_AMAP {
- u32 dw[256];
-};
-
-#endif /* __mpu_amap_h__ */
diff --git a/drivers/staging/benet/mpu_context.h b/drivers/staging/benet/mpu_context.h
deleted file mode 100644
index 8ce90f9c46c..00000000000
--- a/drivers/staging/benet/mpu_context.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __mpu_context_amap_h__
-#define __mpu_context_amap_h__
-
-/*
- * Management command and control ring context. The MPUs BTLR_CTRL1 CSR
- * controls the writeback behavior of the producer and consumer index values.
- */
-struct BE_MCC_RING_CONTEXT_AMAP {
- u8 con_index[16]; /* DWORD 0 */
- u8 ring_size[4]; /* DWORD 0 */
- u8 cq_id[11]; /* DWORD 0 */
- u8 rsvd0; /* DWORD 0 */
- u8 prod_index[16]; /* DWORD 1 */
- u8 pdid[15]; /* DWORD 1 */
- u8 invalid; /* DWORD 1 */
- u8 cmd_pending_current[7]; /* DWORD 2 */
- u8 rsvd1[25]; /* DWORD 2 */
- u8 hpi_port_cq_id[11]; /* DWORD 3 */
- u8 rsvd2[5]; /* DWORD 3 */
- u8 cmd_pending_max[7]; /* DWORD 3 */
- u8 rsvd3[9]; /* DWORD 3 */
-} __packed;
-struct MCC_RING_CONTEXT_AMAP {
- u32 dw[4];
-};
-
-#endif /* __mpu_context_amap_h__ */
diff --git a/drivers/staging/benet/pcicfg.h b/drivers/staging/benet/pcicfg.h
deleted file mode 100644
index 7c15684adf4..00000000000
--- a/drivers/staging/benet/pcicfg.h
+++ /dev/null
@@ -1,825 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __pcicfg_amap_h__
-#define __pcicfg_amap_h__
-
-/* Vendor and Device ID Register. */
-struct BE_PCICFG_ID_CSR_AMAP {
- u8 vendorid[16]; /* DWORD 0 */
- u8 deviceid[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ID_CSR_AMAP {
- u32 dw[1];
-};
-
-/* IO Bar Register. */
-struct BE_PCICFG_IOBAR_CSR_AMAP {
- u8 iospace; /* DWORD 0 */
- u8 rsvd0[7]; /* DWORD 0 */
- u8 iobar[24]; /* DWORD 0 */
-} __packed;
-struct PCICFG_IOBAR_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 0 Register. */
-struct BE_PCICFG_MEMBAR0_CSR_AMAP {
- u8 memspace; /* DWORD 0 */
- u8 type[2]; /* DWORD 0 */
- u8 pf; /* DWORD 0 */
- u8 rsvd0[10]; /* DWORD 0 */
- u8 membar0[18]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR0_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 1 - Low Address Register. */
-struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP {
- u8 memspace; /* DWORD 0 */
- u8 type[2]; /* DWORD 0 */
- u8 pf; /* DWORD 0 */
- u8 rsvd0[13]; /* DWORD 0 */
- u8 membar1lo[15]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR1_LO_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 1 - High Address Register. */
-struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP {
- u8 membar1hi[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR1_HI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 2 - Low Address Register. */
-struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP {
- u8 memspace; /* DWORD 0 */
- u8 type[2]; /* DWORD 0 */
- u8 pf; /* DWORD 0 */
- u8 rsvd0[17]; /* DWORD 0 */
- u8 membar2lo[11]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR2_LO_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 2 - High Address Register. */
-struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP {
- u8 membar2hi[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR2_HI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Subsystem Vendor and ID (Function 0) Register. */
-struct BE_PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP {
- u8 subsys_vendor_id[16]; /* DWORD 0 */
- u8 subsys_id[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Subsystem Vendor and ID (Function 1) Register. */
-struct BE_PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP {
- u8 subsys_vendor_id[16]; /* DWORD 0 */
- u8 subsys_id[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Semaphore Register. */
-struct BE_PCICFG_SEMAPHORE_CSR_AMAP {
- u8 locked; /* DWORD 0 */
- u8 rsvd0[31]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SEMAPHORE_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Soft Reset Register. */
-struct BE_PCICFG_SOFT_RESET_CSR_AMAP {
- u8 rsvd0[7]; /* DWORD 0 */
- u8 softreset; /* DWORD 0 */
- u8 rsvd1[16]; /* DWORD 0 */
- u8 nec_ll_rcvdetect_i[8]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SOFT_RESET_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Unrecoverable Error Status (Low) Register. Each bit corresponds to
- * an internal Unrecoverable Error. These are set by hardware and may be
- * cleared by writing a one to the respective bit(s) to be cleared. Any
- * bit being set that is also unmasked will result in Unrecoverable Error
- * interrupt notification to the host CPU and/or Server Management chip
- * and the transitioning of BladeEngine to an Offline state.
- */
-struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP {
- u8 cev_ue_status; /* DWORD 0 */
- u8 ctx_ue_status; /* DWORD 0 */
- u8 dbuf_ue_status; /* DWORD 0 */
- u8 erx_ue_status; /* DWORD 0 */
- u8 host_ue_status; /* DWORD 0 */
- u8 mpu_ue_status; /* DWORD 0 */
- u8 ndma_ue_status; /* DWORD 0 */
- u8 ptc_ue_status; /* DWORD 0 */
- u8 rdma_ue_status; /* DWORD 0 */
- u8 rxf_ue_status; /* DWORD 0 */
- u8 rxips_ue_status; /* DWORD 0 */
- u8 rxulp0_ue_status; /* DWORD 0 */
- u8 rxulp1_ue_status; /* DWORD 0 */
- u8 rxulp2_ue_status; /* DWORD 0 */
- u8 tim_ue_status; /* DWORD 0 */
- u8 tpost_ue_status; /* DWORD 0 */
- u8 tpre_ue_status; /* DWORD 0 */
- u8 txips_ue_status; /* DWORD 0 */
- u8 txulp0_ue_status; /* DWORD 0 */
- u8 txulp1_ue_status; /* DWORD 0 */
- u8 uc_ue_status; /* DWORD 0 */
- u8 wdma_ue_status; /* DWORD 0 */
- u8 txulp2_ue_status; /* DWORD 0 */
- u8 host1_ue_status; /* DWORD 0 */
- u8 p0_ob_link_ue_status; /* DWORD 0 */
- u8 p1_ob_link_ue_status; /* DWORD 0 */
- u8 host_gpio_ue_status; /* DWORD 0 */
- u8 mbox_netw_ue_status; /* DWORD 0 */
- u8 mbox_stor_ue_status; /* DWORD 0 */
- u8 axgmac0_ue_status; /* DWORD 0 */
- u8 axgmac1_ue_status; /* DWORD 0 */
- u8 mpu_intpend_ue_status; /* DWORD 0 */
-} __packed;
-struct PCICFG_UE_STATUS_LOW_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Unrecoverable Error Status (High) Register. Each bit corresponds to
- * an internal Unrecoverable Error. These are set by hardware and may be
- * cleared by writing a one to the respective bit(s) to be cleared. Any
- * bit being set that is also unmasked will result in Unrecoverable Error
- * interrupt notification to the host CPU and/or Server Management chip;
- * and the transitioning of BladeEngine to an Offline state.
- */
-struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP {
- u8 jtag_ue_status; /* DWORD 0 */
- u8 lpcmemhost_ue_status; /* DWORD 0 */
- u8 mgmt_mac_ue_status; /* DWORD 0 */
- u8 mpu_iram_ue_status; /* DWORD 0 */
- u8 pcs0online_ue_status; /* DWORD 0 */
- u8 pcs1online_ue_status; /* DWORD 0 */
- u8 pctl0_ue_status; /* DWORD 0 */
- u8 pctl1_ue_status; /* DWORD 0 */
- u8 pmem_ue_status; /* DWORD 0 */
- u8 rr_ue_status; /* DWORD 0 */
- u8 rxpp_ue_status; /* DWORD 0 */
- u8 txpb_ue_status; /* DWORD 0 */
- u8 txp_ue_status; /* DWORD 0 */
- u8 xaui_ue_status; /* DWORD 0 */
- u8 arm_ue_status; /* DWORD 0 */
- u8 ipc_ue_status; /* DWORD 0 */
- u8 rsvd0[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_UE_STATUS_HI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Unrecoverable Error Mask (Low) Register. Each bit, when set to one,
- * will mask the associated Unrecoverable Error status bit from notification
- * of Unrecoverable Error to the host CPU and/or Server Managment chip and the
- * transitioning of all BladeEngine units to an Offline state.
- */
-struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP {
- u8 cev_ue_mask; /* DWORD 0 */
- u8 ctx_ue_mask; /* DWORD 0 */
- u8 dbuf_ue_mask; /* DWORD 0 */
- u8 erx_ue_mask; /* DWORD 0 */
- u8 host_ue_mask; /* DWORD 0 */
- u8 mpu_ue_mask; /* DWORD 0 */
- u8 ndma_ue_mask; /* DWORD 0 */
- u8 ptc_ue_mask; /* DWORD 0 */
- u8 rdma_ue_mask; /* DWORD 0 */
- u8 rxf_ue_mask; /* DWORD 0 */
- u8 rxips_ue_mask; /* DWORD 0 */
- u8 rxulp0_ue_mask; /* DWORD 0 */
- u8 rxulp1_ue_mask; /* DWORD 0 */
- u8 rxulp2_ue_mask; /* DWORD 0 */
- u8 tim_ue_mask; /* DWORD 0 */
- u8 tpost_ue_mask; /* DWORD 0 */
- u8 tpre_ue_mask; /* DWORD 0 */
- u8 txips_ue_mask; /* DWORD 0 */
- u8 txulp0_ue_mask; /* DWORD 0 */
- u8 txulp1_ue_mask; /* DWORD 0 */
- u8 uc_ue_mask; /* DWORD 0 */
- u8 wdma_ue_mask; /* DWORD 0 */
- u8 txulp2_ue_mask; /* DWORD 0 */
- u8 host1_ue_mask; /* DWORD 0 */
- u8 p0_ob_link_ue_mask; /* DWORD 0 */
- u8 p1_ob_link_ue_mask; /* DWORD 0 */
- u8 host_gpio_ue_mask; /* DWORD 0 */
- u8 mbox_netw_ue_mask; /* DWORD 0 */
- u8 mbox_stor_ue_mask; /* DWORD 0 */
- u8 axgmac0_ue_mask; /* DWORD 0 */
- u8 axgmac1_ue_mask; /* DWORD 0 */
- u8 mpu_intpend_ue_mask; /* DWORD 0 */
-} __packed;
-struct PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Unrecoverable Error Mask (High) Register. Each bit, when set to one,
- * will mask the associated Unrecoverable Error status bit from notification
- * of Unrecoverable Error to the host CPU and/or Server Managment chip and the
- * transitioning of all BladeEngine units to an Offline state.
- */
-struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP {
- u8 jtag_ue_mask; /* DWORD 0 */
- u8 lpcmemhost_ue_mask; /* DWORD 0 */
- u8 mgmt_mac_ue_mask; /* DWORD 0 */
- u8 mpu_iram_ue_mask; /* DWORD 0 */
- u8 pcs0online_ue_mask; /* DWORD 0 */
- u8 pcs1online_ue_mask; /* DWORD 0 */
- u8 pctl0_ue_mask; /* DWORD 0 */
- u8 pctl1_ue_mask; /* DWORD 0 */
- u8 pmem_ue_mask; /* DWORD 0 */
- u8 rr_ue_mask; /* DWORD 0 */
- u8 rxpp_ue_mask; /* DWORD 0 */
- u8 txpb_ue_mask; /* DWORD 0 */
- u8 txp_ue_mask; /* DWORD 0 */
- u8 xaui_ue_mask; /* DWORD 0 */
- u8 arm_ue_mask; /* DWORD 0 */
- u8 ipc_ue_mask; /* DWORD 0 */
- u8 rsvd0[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_UE_STATUS_HI_MASK_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Online Control Register 0. This register controls various units within
- * BladeEngine being in an Online or Offline state.
- */
-struct BE_PCICFG_ONLINE0_CSR_AMAP {
- u8 cev_online; /* DWORD 0 */
- u8 ctx_online; /* DWORD 0 */
- u8 dbuf_online; /* DWORD 0 */
- u8 erx_online; /* DWORD 0 */
- u8 host_online; /* DWORD 0 */
- u8 mpu_online; /* DWORD 0 */
- u8 ndma_online; /* DWORD 0 */
- u8 ptc_online; /* DWORD 0 */
- u8 rdma_online; /* DWORD 0 */
- u8 rxf_online; /* DWORD 0 */
- u8 rxips_online; /* DWORD 0 */
- u8 rxulp0_online; /* DWORD 0 */
- u8 rxulp1_online; /* DWORD 0 */
- u8 rxulp2_online; /* DWORD 0 */
- u8 tim_online; /* DWORD 0 */
- u8 tpost_online; /* DWORD 0 */
- u8 tpre_online; /* DWORD 0 */
- u8 txips_online; /* DWORD 0 */
- u8 txulp0_online; /* DWORD 0 */
- u8 txulp1_online; /* DWORD 0 */
- u8 uc_online; /* DWORD 0 */
- u8 wdma_online; /* DWORD 0 */
- u8 txulp2_online; /* DWORD 0 */
- u8 host1_online; /* DWORD 0 */
- u8 p0_ob_link_online; /* DWORD 0 */
- u8 p1_ob_link_online; /* DWORD 0 */
- u8 host_gpio_online; /* DWORD 0 */
- u8 mbox_netw_online; /* DWORD 0 */
- u8 mbox_stor_online; /* DWORD 0 */
- u8 axgmac0_online; /* DWORD 0 */
- u8 axgmac1_online; /* DWORD 0 */
- u8 mpu_intpend_online; /* DWORD 0 */
-} __packed;
-struct PCICFG_ONLINE0_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Online Control Register 1. This register controls various units within
- * BladeEngine being in an Online or Offline state.
- */
-struct BE_PCICFG_ONLINE1_CSR_AMAP {
- u8 jtag_online; /* DWORD 0 */
- u8 lpcmemhost_online; /* DWORD 0 */
- u8 mgmt_mac_online; /* DWORD 0 */
- u8 mpu_iram_online; /* DWORD 0 */
- u8 pcs0online_online; /* DWORD 0 */
- u8 pcs1online_online; /* DWORD 0 */
- u8 pctl0_online; /* DWORD 0 */
- u8 pctl1_online; /* DWORD 0 */
- u8 pmem_online; /* DWORD 0 */
- u8 rr_online; /* DWORD 0 */
- u8 rxpp_online; /* DWORD 0 */
- u8 txpb_online; /* DWORD 0 */
- u8 txp_online; /* DWORD 0 */
- u8 xaui_online; /* DWORD 0 */
- u8 arm_online; /* DWORD 0 */
- u8 ipc_online; /* DWORD 0 */
- u8 rsvd0[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ONLINE1_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Host Timer Register. */
-struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP {
- u8 hosttimer[24]; /* DWORD 0 */
- u8 hostintr; /* DWORD 0 */
- u8 rsvd0[7]; /* DWORD 0 */
-} __packed;
-struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Scratchpad Register (for software use). */
-struct BE_PCICFG_SCRATCHPAD_CSR_AMAP {
- u8 scratchpad[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SCRATCHPAD_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Capabilities Register. */
-struct BE_PCICFG_PCIE_CAP_CSR_AMAP {
- u8 capid[8]; /* DWORD 0 */
- u8 nextcap[8]; /* DWORD 0 */
- u8 capver[4]; /* DWORD 0 */
- u8 devport[4]; /* DWORD 0 */
- u8 rsvd0[6]; /* DWORD 0 */
- u8 rsvd1[2]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_CAP_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Device Capabilities Register. */
-struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP {
- u8 payload[3]; /* DWORD 0 */
- u8 rsvd0[3]; /* DWORD 0 */
- u8 lo_lat[3]; /* DWORD 0 */
- u8 l1_lat[3]; /* DWORD 0 */
- u8 rsvd1[3]; /* DWORD 0 */
- u8 rsvd2[3]; /* DWORD 0 */
- u8 pwr_value[8]; /* DWORD 0 */
- u8 pwr_scale[2]; /* DWORD 0 */
- u8 rsvd3[4]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_DEVCAP_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Device Control/Status Registers. */
-struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP {
- u8 CorrErrReportEn; /* DWORD 0 */
- u8 NonFatalErrReportEn; /* DWORD 0 */
- u8 FatalErrReportEn; /* DWORD 0 */
- u8 UnsuppReqReportEn; /* DWORD 0 */
- u8 EnableRelaxOrder; /* DWORD 0 */
- u8 Max_Payload_Size[3]; /* DWORD 0 */
- u8 ExtendTagFieldEnable; /* DWORD 0 */
- u8 PhantomFnEnable; /* DWORD 0 */
- u8 AuxPwrPMEnable; /* DWORD 0 */
- u8 EnableNoSnoop; /* DWORD 0 */
- u8 Max_Read_Req_Size[3]; /* DWORD 0 */
- u8 rsvd0; /* DWORD 0 */
- u8 CorrErrDetect; /* DWORD 0 */
- u8 NonFatalErrDetect; /* DWORD 0 */
- u8 FatalErrDetect; /* DWORD 0 */
- u8 UnsuppReqDetect; /* DWORD 0 */
- u8 AuxPwrDetect; /* DWORD 0 */
- u8 TransPending; /* DWORD 0 */
- u8 rsvd1[10]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Link Capabilities Register. */
-struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP {
- u8 MaxLinkSpeed[4]; /* DWORD 0 */
- u8 MaxLinkWidth[6]; /* DWORD 0 */
- u8 ASPMSupport[2]; /* DWORD 0 */
- u8 L0sExitLat[3]; /* DWORD 0 */
- u8 L1ExitLat[3]; /* DWORD 0 */
- u8 rsvd0[6]; /* DWORD 0 */
- u8 PortNum[8]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_LINK_CAP_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Link Status Register. */
-struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP {
- u8 ASPMCtl[2]; /* DWORD 0 */
- u8 rsvd0; /* DWORD 0 */
- u8 ReadCmplBndry; /* DWORD 0 */
- u8 LinkDisable; /* DWORD 0 */
- u8 RetrainLink; /* DWORD 0 */
- u8 CommonClkConfig; /* DWORD 0 */
- u8 ExtendSync; /* DWORD 0 */
- u8 rsvd1[8]; /* DWORD 0 */
- u8 LinkSpeed[4]; /* DWORD 0 */
- u8 NegLinkWidth[6]; /* DWORD 0 */
- u8 LinkTrainErr; /* DWORD 0 */
- u8 LinkTrain; /* DWORD 0 */
- u8 SlotClkConfig; /* DWORD 0 */
- u8 rsvd2[3]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_LINK_STATUS_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI Configuration Register. */
-struct BE_PCICFG_MSI_CSR_AMAP {
- u8 capid[8]; /* DWORD 0 */
- u8 nextptr[8]; /* DWORD 0 */
- u8 tablesize[11]; /* DWORD 0 */
- u8 rsvd0[3]; /* DWORD 0 */
- u8 funcmask; /* DWORD 0 */
- u8 en; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* MSI-X Table Offset Register. */
-struct BE_PCICFG_MSIX_TABLE_CSR_AMAP {
- u8 tablebir[3]; /* DWORD 0 */
- u8 offset[29]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_TABLE_CSR_AMAP {
- u32 dw[1];
-};
-
-/* MSI-X PBA Offset Register. */
-struct BE_PCICFG_MSIX_PBA_CSR_AMAP {
- u8 pbabir[3]; /* DWORD 0 */
- u8 offset[29]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_PBA_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI-X Message Vector Control Register. */
-struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP {
- u8 vector_control; /* DWORD 0 */
- u8 rsvd0[31]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI-X Message Data Register. */
-struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP {
- u8 data[16]; /* DWORD 0 */
- u8 rsvd0[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_MSG_DATA_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI-X Message Address Register - High Part. */
-struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP {
- u8 addr[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI-X Message Address Register - Low Part. */
-struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP {
- u8 rsvd0[2]; /* DWORD 0 */
- u8 addr[30]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_18_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_18_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_19_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_19_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_20_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[25][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_20_RSVD_AMAP {
- u32 dw[26];
-};
-
-struct BE_PCICFG_ANON_21_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[1919][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_21_RSVD_AMAP {
- u32 dw[1920];
-};
-
-struct BE_PCICFG_ANON_22_MESSAGE_AMAP {
- struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP vec_ctrl;
- struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP msg_data;
- struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP addr_hi;
- struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP addr_low;
-} __packed;
-struct PCICFG_ANON_22_MESSAGE_AMAP {
- u32 dw[4];
-};
-
-struct BE_PCICFG_ANON_23_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[895][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_23_RSVD_AMAP {
- u32 dw[896];
-};
-
-/* These PCI Configuration Space registers are for the Storage Function of
- * BladeEngine (Function 0). In the memory map of the registers below their
- * table,
- */
-struct BE_PCICFG0_CSRMAP_AMAP {
- struct BE_PCICFG_ID_CSR_AMAP id;
- u8 rsvd0[32]; /* DWORD 1 */
- u8 rsvd1[32]; /* DWORD 2 */
- u8 rsvd2[32]; /* DWORD 3 */
- struct BE_PCICFG_IOBAR_CSR_AMAP iobar;
- struct BE_PCICFG_MEMBAR0_CSR_AMAP membar0;
- struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP membar1_lo;
- struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP membar1_hi;
- struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP membar2_lo;
- struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP membar2_hi;
- u8 rsvd3[32]; /* DWORD 10 */
- struct BE_PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP subsystem_id;
- u8 rsvd4[32]; /* DWORD 12 */
- u8 rsvd5[32]; /* DWORD 13 */
- u8 rsvd6[32]; /* DWORD 14 */
- u8 rsvd7[32]; /* DWORD 15 */
- struct BE_PCICFG_SEMAPHORE_CSR_AMAP semaphore[4];
- struct BE_PCICFG_SOFT_RESET_CSR_AMAP soft_reset;
- u8 rsvd8[32]; /* DWORD 21 */
- struct BE_PCICFG_SCRATCHPAD_CSR_AMAP scratchpad;
- u8 rsvd9[32]; /* DWORD 23 */
- u8 rsvd10[32]; /* DWORD 24 */
- u8 rsvd11[32]; /* DWORD 25 */
- u8 rsvd12[32]; /* DWORD 26 */
- u8 rsvd13[32]; /* DWORD 27 */
- u8 rsvd14[2][32]; /* DWORD 28 */
- u8 rsvd15[32]; /* DWORD 30 */
- u8 rsvd16[32]; /* DWORD 31 */
- u8 rsvd17[8][32]; /* DWORD 32 */
- struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP ue_status_low;
- struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP ue_status_hi;
- struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP ue_status_low_mask;
- struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP ue_status_hi_mask;
- struct BE_PCICFG_ONLINE0_CSR_AMAP online0;
- struct BE_PCICFG_ONLINE1_CSR_AMAP online1;
- u8 rsvd18[32]; /* DWORD 46 */
- u8 rsvd19[32]; /* DWORD 47 */
- u8 rsvd20[32]; /* DWORD 48 */
- u8 rsvd21[32]; /* DWORD 49 */
- struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP host_timer_int_ctrl;
- u8 rsvd22[32]; /* DWORD 51 */
- struct BE_PCICFG_PCIE_CAP_CSR_AMAP pcie_cap;
- struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP pcie_devcap;
- struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP pcie_control_status;
- struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP pcie_link_cap;
- struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP pcie_link_status;
- struct BE_PCICFG_MSI_CSR_AMAP msi;
- struct BE_PCICFG_MSIX_TABLE_CSR_AMAP msix_table_offset;
- struct BE_PCICFG_MSIX_PBA_CSR_AMAP msix_pba_offset;
- u8 rsvd23[32]; /* DWORD 60 */
- u8 rsvd24[32]; /* DWORD 61 */
- u8 rsvd25[32]; /* DWORD 62 */
- u8 rsvd26[32]; /* DWORD 63 */
- u8 rsvd27[32]; /* DWORD 64 */
- u8 rsvd28[32]; /* DWORD 65 */
- u8 rsvd29[32]; /* DWORD 66 */
- u8 rsvd30[32]; /* DWORD 67 */
- u8 rsvd31[32]; /* DWORD 68 */
- u8 rsvd32[32]; /* DWORD 69 */
- u8 rsvd33[32]; /* DWORD 70 */
- u8 rsvd34[32]; /* DWORD 71 */
- u8 rsvd35[32]; /* DWORD 72 */
- u8 rsvd36[32]; /* DWORD 73 */
- u8 rsvd37[32]; /* DWORD 74 */
- u8 rsvd38[32]; /* DWORD 75 */
- u8 rsvd39[32]; /* DWORD 76 */
- u8 rsvd40[32]; /* DWORD 77 */
- u8 rsvd41[32]; /* DWORD 78 */
- u8 rsvd42[32]; /* DWORD 79 */
- u8 rsvd43[32]; /* DWORD 80 */
- u8 rsvd44[32]; /* DWORD 81 */
- u8 rsvd45[32]; /* DWORD 82 */
- u8 rsvd46[32]; /* DWORD 83 */
- u8 rsvd47[32]; /* DWORD 84 */
- u8 rsvd48[32]; /* DWORD 85 */
- u8 rsvd49[32]; /* DWORD 86 */
- u8 rsvd50[32]; /* DWORD 87 */
- u8 rsvd51[32]; /* DWORD 88 */
- u8 rsvd52[32]; /* DWORD 89 */
- u8 rsvd53[32]; /* DWORD 90 */
- u8 rsvd54[32]; /* DWORD 91 */
- u8 rsvd55[32]; /* DWORD 92 */
- u8 rsvd56[832]; /* DWORD 93 */
- u8 rsvd57[32]; /* DWORD 119 */
- u8 rsvd58[32]; /* DWORD 120 */
- u8 rsvd59[32]; /* DWORD 121 */
- u8 rsvd60[32]; /* DWORD 122 */
- u8 rsvd61[32]; /* DWORD 123 */
- u8 rsvd62[32]; /* DWORD 124 */
- u8 rsvd63[32]; /* DWORD 125 */
- u8 rsvd64[32]; /* DWORD 126 */
- u8 rsvd65[32]; /* DWORD 127 */
- u8 rsvd66[61440]; /* DWORD 128 */
- struct BE_PCICFG_ANON_22_MESSAGE_AMAP message[32];
- u8 rsvd67[28672]; /* DWORD 2176 */
- u8 rsvd68[32]; /* DWORD 3072 */
- u8 rsvd69[1023][32]; /* DWORD 3073 */
-} __packed;
-struct PCICFG0_CSRMAP_AMAP {
- u32 dw[4096];
-};
-
-struct BE_PCICFG_ANON_24_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_24_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_25_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_25_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_26_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_26_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_27_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_27_RSVD_AMAP {
- u32 dw[2];
-};
-
-struct BE_PCICFG_ANON_28_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[3][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_28_RSVD_AMAP {
- u32 dw[4];
-};
-
-struct BE_PCICFG_ANON_29_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[36][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_29_RSVD_AMAP {
- u32 dw[37];
-};
-
-struct BE_PCICFG_ANON_30_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[1930][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_30_RSVD_AMAP {
- u32 dw[1931];
-};
-
-struct BE_PCICFG_ANON_31_MESSAGE_AMAP {
- struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP vec_ctrl;
- struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP msg_data;
- struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP addr_hi;
- struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP addr_low;
-} __packed;
-struct PCICFG_ANON_31_MESSAGE_AMAP {
- u32 dw[4];
-};
-
-struct BE_PCICFG_ANON_32_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[895][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_32_RSVD_AMAP {
- u32 dw[896];
-};
-
-/* This PCI configuration space register map is for the Networking Function of
- * BladeEngine (Function 1).
- */
-struct BE_PCICFG1_CSRMAP_AMAP {
- struct BE_PCICFG_ID_CSR_AMAP id;
- u8 rsvd0[32]; /* DWORD 1 */
- u8 rsvd1[32]; /* DWORD 2 */
- u8 rsvd2[32]; /* DWORD 3 */
- struct BE_PCICFG_IOBAR_CSR_AMAP iobar;
- struct BE_PCICFG_MEMBAR0_CSR_AMAP membar0;
- struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP membar1_lo;
- struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP membar1_hi;
- struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP membar2_lo;
- struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP membar2_hi;
- u8 rsvd3[32]; /* DWORD 10 */
- struct BE_PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP subsystem_id;
- u8 rsvd4[32]; /* DWORD 12 */
- u8 rsvd5[32]; /* DWORD 13 */
- u8 rsvd6[32]; /* DWORD 14 */
- u8 rsvd7[32]; /* DWORD 15 */
- struct BE_PCICFG_SEMAPHORE_CSR_AMAP semaphore[4];
- struct BE_PCICFG_SOFT_RESET_CSR_AMAP soft_reset;
- u8 rsvd8[32]; /* DWORD 21 */
- struct BE_PCICFG_SCRATCHPAD_CSR_AMAP scratchpad;
- u8 rsvd9[32]; /* DWORD 23 */
- u8 rsvd10[32]; /* DWORD 24 */
- u8 rsvd11[32]; /* DWORD 25 */
- u8 rsvd12[32]; /* DWORD 26 */
- u8 rsvd13[32]; /* DWORD 27 */
- u8 rsvd14[2][32]; /* DWORD 28 */
- u8 rsvd15[32]; /* DWORD 30 */
- u8 rsvd16[32]; /* DWORD 31 */
- u8 rsvd17[8][32]; /* DWORD 32 */
- struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP ue_status_low;
- struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP ue_status_hi;
- struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP ue_status_low_mask;
- struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP ue_status_hi_mask;
- struct BE_PCICFG_ONLINE0_CSR_AMAP online0;
- struct BE_PCICFG_ONLINE1_CSR_AMAP online1;
- u8 rsvd18[32]; /* DWORD 46 */
- u8 rsvd19[32]; /* DWORD 47 */
- u8 rsvd20[32]; /* DWORD 48 */
- u8 rsvd21[32]; /* DWORD 49 */
- struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP host_timer_int_ctrl;
- u8 rsvd22[32]; /* DWORD 51 */
- struct BE_PCICFG_PCIE_CAP_CSR_AMAP pcie_cap;
- struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP pcie_devcap;
- struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP pcie_control_status;
- struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP pcie_link_cap;
- struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP pcie_link_status;
- struct BE_PCICFG_MSI_CSR_AMAP msi;
- struct BE_PCICFG_MSIX_TABLE_CSR_AMAP msix_table_offset;
- struct BE_PCICFG_MSIX_PBA_CSR_AMAP msix_pba_offset;
- u8 rsvd23[64]; /* DWORD 60 */
- u8 rsvd24[32]; /* DWORD 62 */
- u8 rsvd25[32]; /* DWORD 63 */
- u8 rsvd26[32]; /* DWORD 64 */
- u8 rsvd27[32]; /* DWORD 65 */
- u8 rsvd28[32]; /* DWORD 66 */
- u8 rsvd29[32]; /* DWORD 67 */
- u8 rsvd30[32]; /* DWORD 68 */
- u8 rsvd31[32]; /* DWORD 69 */
- u8 rsvd32[32]; /* DWORD 70 */
- u8 rsvd33[32]; /* DWORD 71 */
- u8 rsvd34[32]; /* DWORD 72 */
- u8 rsvd35[32]; /* DWORD 73 */
- u8 rsvd36[32]; /* DWORD 74 */
- u8 rsvd37[128]; /* DWORD 75 */
- u8 rsvd38[32]; /* DWORD 79 */
- u8 rsvd39[1184]; /* DWORD 80 */
- u8 rsvd40[61792]; /* DWORD 117 */
- struct BE_PCICFG_ANON_31_MESSAGE_AMAP message[32];
- u8 rsvd41[28672]; /* DWORD 2176 */
- u8 rsvd42[32]; /* DWORD 3072 */
- u8 rsvd43[1023][32]; /* DWORD 3073 */
-} __packed;
-struct PCICFG1_CSRMAP_AMAP {
- u32 dw[4096];
-};
-
-#endif /* __pcicfg_amap_h__ */
diff --git a/drivers/staging/benet/post_codes.h b/drivers/staging/benet/post_codes.h
deleted file mode 100644
index 6d1621f5f5f..00000000000
--- a/drivers/staging/benet/post_codes.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __post_codes_amap_h__
-#define __post_codes_amap_h__
-
-/* --- MGMT_HBA_POST_STAGE_ENUM --- */
-#define POST_STAGE_POWER_ON_RESET (0) /* State after a cold or warm boot. */
-#define POST_STAGE_AWAITING_HOST_RDY (1) /* ARM boot code awaiting a
- go-ahed from the host. */
-#define POST_STAGE_HOST_RDY (2) /* Host has given go-ahed to ARM. */
-#define POST_STAGE_BE_RESET (3) /* Host wants to reset chip, this is a chip
- workaround */
-#define POST_STAGE_SEEPROM_CS_START (256) /* SEEPROM checksum
- test start. */
-#define POST_STAGE_SEEPROM_CS_DONE (257) /* SEEPROM checksum test
- done. */
-#define POST_STAGE_DDR_CONFIG_START (512) /* DDR configuration start. */
-#define POST_STAGE_DDR_CONFIG_DONE (513) /* DDR configuration done. */
-#define POST_STAGE_DDR_CALIBRATE_START (768) /* DDR calibration start. */
-#define POST_STAGE_DDR_CALIBRATE_DONE (769) /* DDR calibration done. */
-#define POST_STAGE_DDR_TEST_START (1024) /* DDR memory test start. */
-#define POST_STAGE_DDR_TEST_DONE (1025) /* DDR memory test done. */
-#define POST_STAGE_REDBOOT_INIT_START (1536) /* Redboot starts execution. */
-#define POST_STAGE_REDBOOT_INIT_DONE (1537) /* Redboot done execution. */
-#define POST_STAGE_FW_IMAGE_LOAD_START (1792) /* Firmware image load to
- DDR start. */
-#define POST_STAGE_FW_IMAGE_LOAD_DONE (1793) /* Firmware image load
- to DDR done. */
-#define POST_STAGE_ARMFW_START (2048) /* ARMfw runtime code
- starts execution. */
-#define POST_STAGE_DHCP_QUERY_START (2304) /* DHCP server query start. */
-#define POST_STAGE_DHCP_QUERY_DONE (2305) /* DHCP server query done. */
-#define POST_STAGE_BOOT_TARGET_DISCOVERY_START (2560) /* Boot Target
- Discovery Start. */
-#define POST_STAGE_BOOT_TARGET_DISCOVERY_DONE (2561) /* Boot Target
- Discovery Done. */
-#define POST_STAGE_RC_OPTION_SET (2816) /* Remote configuration
- option is set in SEEPROM */
-#define POST_STAGE_SWITCH_LINK (2817) /* Wait for link up on switch */
-#define POST_STAGE_SEND_ICDS_MESSAGE (2818) /* Send the ICDS message
- to switch */
-#define POST_STAGE_PERFROM_TFTP (2819) /* Download xml using TFTP */
-#define POST_STAGE_PARSE_XML (2820) /* Parse XML file */
-#define POST_STAGE_DOWNLOAD_IMAGE (2821) /* Download IMAGE from
- TFTP server */
-#define POST_STAGE_FLASH_IMAGE (2822) /* Flash the IMAGE */
-#define POST_STAGE_RC_DONE (2823) /* Remote configuration
- complete */
-#define POST_STAGE_REBOOT_SYSTEM (2824) /* Upgrade IMAGE done,
- reboot required */
-#define POST_STAGE_MAC_ADDRESS (3072) /* MAC Address Check */
-#define POST_STAGE_ARMFW_READY (49152) /* ARMfw is done with POST
- and ready. */
-#define POST_STAGE_ARMFW_UE (61440) /* ARMfw has asserted an
- unrecoverable error. The
- lower 3 hex digits of the
- stage code identify the
- unique error code.
- */
-
-/* This structure defines the format of the MPU semaphore
- * register when used for POST.
- */
-struct BE_MGMT_HBA_POST_STATUS_STRUCT_AMAP {
- u8 stage[16]; /* DWORD 0 */
- u8 rsvd0[10]; /* DWORD 0 */
- u8 iscsi_driver_loaded; /* DWORD 0 */
- u8 option_rom_installed; /* DWORD 0 */
- u8 iscsi_ip_conflict; /* DWORD 0 */
- u8 iscsi_no_ip; /* DWORD 0 */
- u8 backup_fw; /* DWORD 0 */
- u8 error; /* DWORD 0 */
-} __packed;
-struct MGMT_HBA_POST_STATUS_STRUCT_AMAP {
- u32 dw[1];
-};
-
-/* --- MGMT_HBA_POST_DUMMY_BITS_ENUM --- */
-#define POST_BIT_ISCSI_LOADED (26)
-#define POST_BIT_OPTROM_INST (27)
-#define POST_BIT_BAD_IP_ADDR (28)
-#define POST_BIT_NO_IP_ADDR (29)
-#define POST_BIT_BACKUP_FW (30)
-#define POST_BIT_ERROR (31)
-
-/* --- MGMT_HBA_POST_DUMMY_VALUES_ENUM --- */
-#define POST_ISCSI_DRIVER_LOADED (67108864)
-#define POST_OPTROM_INSTALLED (134217728)
-#define POST_ISCSI_IP_ADDRESS_CONFLICT (268435456)
-#define POST_ISCSI_NO_IP_ADDRESS (536870912)
-#define POST_BACKUP_FW_LOADED (1073741824)
-#define POST_FATAL_ERROR (2147483648)
-
-#endif /* __post_codes_amap_h__ */
diff --git a/drivers/staging/benet/regmap.h b/drivers/staging/benet/regmap.h
deleted file mode 100644
index e816ba210e8..00000000000
--- a/drivers/staging/benet/regmap.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __regmap_amap_h__
-#define __regmap_amap_h__
-#include "pcicfg.h"
-#include "ep.h"
-#include "cev.h"
-#include "mpu.h"
-#include "doorbells.h"
-
-/*
- * This is the control and status register map for BladeEngine, showing
- * the relative size and offset of each sub-module. The CSR registers
- * are identical for the network and storage PCI functions. The
- * CSR map is shown below, followed by details of each block,
- * in sub-sections. The sub-sections begin with a description
- * of CSRs that are instantiated in multiple blocks.
- */
-struct BE_BLADE_ENGINE_CSRMAP_AMAP {
- struct BE_MPU_CSRMAP_AMAP mpu;
- u8 rsvd0[8192]; /* DWORD 256 */
- u8 rsvd1[8192]; /* DWORD 512 */
- struct BE_CEV_CSRMAP_AMAP cev;
- u8 rsvd2[8192]; /* DWORD 1024 */
- u8 rsvd3[8192]; /* DWORD 1280 */
- u8 rsvd4[8192]; /* DWORD 1536 */
- u8 rsvd5[8192]; /* DWORD 1792 */
- u8 rsvd6[8192]; /* DWORD 2048 */
- u8 rsvd7[8192]; /* DWORD 2304 */
- u8 rsvd8[8192]; /* DWORD 2560 */
- u8 rsvd9[8192]; /* DWORD 2816 */
- u8 rsvd10[8192]; /* DWORD 3072 */
- u8 rsvd11[8192]; /* DWORD 3328 */
- u8 rsvd12[8192]; /* DWORD 3584 */
- u8 rsvd13[8192]; /* DWORD 3840 */
- u8 rsvd14[8192]; /* DWORD 4096 */
- u8 rsvd15[8192]; /* DWORD 4352 */
- u8 rsvd16[8192]; /* DWORD 4608 */
- u8 rsvd17[8192]; /* DWORD 4864 */
- u8 rsvd18[8192]; /* DWORD 5120 */
- u8 rsvd19[8192]; /* DWORD 5376 */
- u8 rsvd20[8192]; /* DWORD 5632 */
- u8 rsvd21[8192]; /* DWORD 5888 */
- u8 rsvd22[8192]; /* DWORD 6144 */
- u8 rsvd23[17152][32]; /* DWORD 6400 */
-} __packed;
-struct BLADE_ENGINE_CSRMAP_AMAP {
- u32 dw[23552];
-};
-
-#endif /* __regmap_amap_h__ */
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index b501bfb9c75..b47ca1e7e38 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1,6 +1,7 @@
config COMEDI
tristate "Data Acquision support (comedi)"
default N
+ depends on m
---help---
Enable support a wide range of data acquision devices
for Linux.
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
index a7de401f61a..cd19be6c00e 100644
--- a/drivers/staging/go7007/snd-go7007.c
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -248,10 +248,11 @@ int go7007_snd_init(struct go7007 *go)
spin_lock_init(&gosnd->lock);
gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
gosnd->capturing = 0;
- gosnd->card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (gosnd->card == NULL) {
+ ret = snd_card_create(index[dev], id[dev], THIS_MODULE, 0,
+ &gosnd->card);
+ if (ret < 0) {
kfree(gosnd);
- return -ENOMEM;
+ return ret;
}
ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
&go7007_snd_device_ops);
diff --git a/drivers/staging/meilhaus/Kconfig b/drivers/staging/meilhaus/Kconfig
index 6def83fa2c9..923af22a468 100644
--- a/drivers/staging/meilhaus/Kconfig
+++ b/drivers/staging/meilhaus/Kconfig
@@ -4,6 +4,7 @@
menuconfig MEILHAUS
tristate "Meilhaus support"
+ depends on m
---help---
If you have a Meilhaus card, say Y (or M) here.
@@ -18,7 +19,7 @@ if MEILHAUS
config ME0600
tristate "Meilhaus ME-600 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-600 family of boards
that do data collection and multipurpose I/O.
@@ -29,7 +30,7 @@ config ME0600
config ME0900
tristate "Meilhaus ME-900 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-900 family of boards
that do data collection and multipurpose I/O.
@@ -40,7 +41,7 @@ config ME0900
config ME1000
tristate "Meilhaus ME-1000 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-1000 family of boards
that do data collection and multipurpose I/O.
@@ -51,7 +52,7 @@ config ME1000
config ME1400
tristate "Meilhaus ME-1400 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-1400 family of boards
that do data collection and multipurpose I/O.
@@ -62,7 +63,7 @@ config ME1400
config ME1600
tristate "Meilhaus ME-1600 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-1600 family of boards
that do data collection and multipurpose I/O.
@@ -73,7 +74,7 @@ config ME1600
config ME4600
tristate "Meilhaus ME-4600 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-4600 family of boards
that do data collection and multipurpose I/O.
@@ -84,7 +85,7 @@ config ME4600
config ME6000
tristate "Meilhaus ME-6000 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-6000 family of boards
that do data collection and multipurpose I/O.
@@ -95,7 +96,7 @@ config ME6000
config ME8100
tristate "Meilhaus ME-8100 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-8100 family of boards
that do data collection and multipurpose I/O.
@@ -106,7 +107,7 @@ config ME8100
config ME8200
tristate "Meilhaus ME-8200 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-8200 family of boards
that do data collection and multipurpose I/O.
@@ -117,7 +118,7 @@ config ME8200
config MEDUMMY
tristate "Meilhaus dummy driver"
default n
- depends on PCI
+ depends on PCI && m
help
This provides a dummy driver for the Meilhaus driver package
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 5ffe269c238..c2747bc88c6 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -622,7 +622,7 @@ static int set_ctrl_bits(void)
}
/* sets ctrl & data port bits according to current signals values */
-static void set_bits(void)
+static void panel_set_bits(void)
{
set_data_bits();
set_ctrl_bits();
@@ -707,12 +707,12 @@ static void lcd_send_serial(int byte)
*/
for (bit = 0; bit < 8; bit++) {
bits.cl = BIT_CLR; /* CLK low */
- set_bits();
+ panel_set_bits();
bits.da = byte & 1;
- set_bits();
+ panel_set_bits();
udelay(2); /* maintain the data during 2 us before CLK up */
bits.cl = BIT_SET; /* CLK high */
- set_bits();
+ panel_set_bits();
udelay(1); /* maintain the strobe during 1 us */
byte >>= 1;
}
@@ -727,7 +727,7 @@ static void lcd_backlight(int on)
/* The backlight is activated by seting the AUTOFEED line to +5V */
spin_lock(&pprt_lock);
bits.bl = on;
- set_bits();
+ panel_set_bits();
spin_unlock(&pprt_lock);
}
@@ -2164,19 +2164,20 @@ static void __exit panel_cleanup_module(void)
if (scan_timer.function != NULL)
del_timer(&scan_timer);
- if (keypad_enabled)
- misc_deregister(&keypad_dev);
-
- if (lcd_enabled) {
- panel_lcd_print("\x0cLCD driver " PANEL_VERSION
- "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
- misc_deregister(&lcd_dev);
- }
+ if (pprt != NULL) {
+ if (keypad_enabled)
+ misc_deregister(&keypad_dev);
- /* TODO: free all input signals */
+ if (lcd_enabled) {
+ panel_lcd_print("\x0cLCD driver " PANEL_VERSION
+ "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
+ misc_deregister(&lcd_dev);
+ }
- parport_release(pprt);
- parport_unregister_device(pprt);
+ /* TODO: free all input signals */
+ parport_release(pprt);
+ parport_unregister_device(pprt);
+ }
parport_unregister_driver(&panel_driver);
}
diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c
index ec343ef53a8..0d111ddfabb 100644
--- a/drivers/staging/poch/poch.c
+++ b/drivers/staging/poch/poch.c
@@ -1026,7 +1026,7 @@ static int poch_ioctl(struct inode *inode, struct file *filp,
}
break;
case POCH_IOC_GET_COUNTERS:
- if (access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters)))
+ if (!access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters)))
return -EFAULT;
spin_lock_irq(&channel->counters_lock);
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
index 79c225acd1a..f636296b54b 100644
--- a/drivers/staging/rtl8187se/Kconfig
+++ b/drivers/staging/rtl8187se/Kconfig
@@ -1,5 +1,6 @@
config RTL8187SE
tristate "RealTek RTL8187SE Wireless LAN NIC driver"
depends on PCI
+ depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS
default N
---help---
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
index af64cfbe16d..7370296225e 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
@@ -234,20 +234,21 @@ out:
void ieee80211_crypto_deinit(void)
{
struct list_head *ptr, *n;
+ struct ieee80211_crypto_alg *alg = NULL;
if (hcrypt == NULL)
return;
- for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
- ptr = n, n = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- list_del(ptr);
- printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- "'%s' (deinit)\n", alg->ops->name);
- kfree(alg);
+ list_for_each_safe(ptr, n, &hcrypt->algs) {
+ alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
+ if (alg) {
+ list_del(ptr);
+ printk(KERN_DEBUG
+ "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
+ alg->ops->name);
+ kfree(alg);
+ }
}
-
kfree(hcrypt);
}
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 94534955e38..66de5cc8ddf 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -6161,10 +6161,10 @@ static void __exit rtl8180_pci_module_exit(void)
{
pci_unregister_driver (&rtl8180_pci_driver);
rtl8180_proc_module_remove();
- ieee80211_crypto_deinit();
ieee80211_crypto_tkip_exit();
ieee80211_crypto_ccmp_exit();
ieee80211_crypto_wep_exit();
+ ieee80211_crypto_deinit();
DMESG("Exiting");
}
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 72e209276ea..22f93dd0ba0 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -406,8 +406,20 @@ void usbip_start_threads(struct usbip_device *ud)
/*
* threads are invoked per one device (per one connection).
*/
- kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0);
- kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0);
+ int retval;
+
+ retval = kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0);
+ if (retval < 0) {
+ printk(KERN_ERR "Creating tcp_rx thread for ud %p failed.\n",
+ ud);
+ return;
+ }
+ retval = kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0);
+ if (retval < 0) {
+ printk(KERN_ERR "Creating tcp_tx thread for ud %p failed.\n",
+ ud);
+ return;
+ }
/* confirm threads are starting */
wait_for_completion(&ud->tcp_rx.thread_done);
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index b003f9a7e15..f716b2e92b6 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -319,16 +319,18 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_device *udev = interface_to_usbdev(intf);
struct wbsoft_priv *priv;
struct ieee80211_hw *dev;
- int err;
+ int nr, err;
usb_get_dev(udev);
// 20060630.2 Check the device if it already be opened
- err = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
- 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
- 0x0, 0x400, &ltmp, 4, HZ*100 );
- if (err)
+ nr = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
+ 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
+ 0x0, 0x400, &ltmp, 4, HZ*100 );
+ if (nr < 0) {
+ err = nr;
goto error;
+ }
ltmp = cpu_to_le32(ltmp);
if (ltmp) { // Is already initialized?
@@ -337,8 +339,10 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
}
dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
- if (!dev)
+ if (!dev) {
+ err = -ENOMEM;
goto error;
+ }
priv = dev->priv;
@@ -369,9 +373,11 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
}
dev->extra_tx_headroom = 12; /* FIXME */
- dev->flags = 0;
+ dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
+ dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
dev->channel_change_time = 1000;
+ dev->max_signal = 100;
dev->queues = 1;
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
index f77f62a4b32..e5bd4470a57 100644
--- a/drivers/tc/tc.c
+++ b/drivers/tc/tc.c
@@ -86,7 +86,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
slot);
goto out_err;
}
- sprintf(tdev->dev.bus_id, "tc%x", slot);
+ dev_set_name(&tdev->dev, "tc%x", slot);
tdev->bus = tbus;
tdev->dev.parent = &tbus->dev;
tdev->dev.bus = &tc_bus_type;
@@ -104,7 +104,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
tdev->vendor[8] = 0;
tdev->name[8] = 0;
- pr_info("%s: %s %s %s\n", tdev->dev.bus_id, tdev->vendor,
+ pr_info("%s: %s %s %s\n", dev_name(&tdev->dev), tdev->vendor,
tdev->name, tdev->firmware);
devsize = readb(module + offset + TC_SLOT_SIZE);
@@ -118,7 +118,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
} else {
printk(KERN_ERR "%s: Cannot provide slot space "
"(%dMiB required, up to %dMiB supported)\n",
- tdev->dev.bus_id, devsize >> 20,
+ dev_name(&tdev->dev), devsize >> 20,
max(slotsize, extslotsize) >> 20);
kfree(tdev);
goto out_err;
@@ -146,7 +146,7 @@ static int __init tc_init(void)
return 0;
INIT_LIST_HEAD(&tc_bus.devices);
- strcpy(tc_bus.dev.bus_id, "tc");
+ dev_set_name(&tc_bus.dev, "tc");
device_register(&tc_bus.dev);
if (tc_bus.info.slot_size) {
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 04b954cfce7..7f86534de26 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -58,6 +58,24 @@ config UIO_SMX
If you compile this as a module, it will be called uio_smx.
+config UIO_AEC
+ tristate "AEC video timestamp device"
+ depends on PCI
+ default n
+ help
+
+ UIO driver for the Adrienne Electronics Corporation PCI time
+ code device.
+
+ This device differs from other UIO devices since it uses I/O
+ ports instead of memory mapped I/O. In order to make it
+ possible for UIO to work with this device a utility, uioport,
+ can be used to read and write the ports:
+
+ git clone git://ifup.org/philips/uioport.git
+
+ If you compile this as a module, it will be called uio_aec.
+
config UIO_SERCOS3
tristate "Automata Sercos III PCI card driver"
default n
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index e6955814985..5c2586d7579 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_UIO_CIF) += uio_cif.o
obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o
obj-$(CONFIG_UIO_SMX) += uio_smx.o
+obj-$(CONFIG_UIO_AEC) += uio_aec.o
obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 4ca85a113aa..03efb065455 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -61,6 +61,14 @@ struct uio_map {
};
#define to_map(map) container_of(map, struct uio_map, kobj)
+static ssize_t map_name_show(struct uio_mem *mem, char *buf)
+{
+ if (unlikely(!mem->name))
+ mem->name = "";
+
+ return sprintf(buf, "%s\n", mem->name);
+}
+
static ssize_t map_addr_show(struct uio_mem *mem, char *buf)
{
return sprintf(buf, "0x%lx\n", mem->addr);
@@ -82,6 +90,8 @@ struct map_sysfs_entry {
ssize_t (*store)(struct uio_mem *, const char *, size_t);
};
+static struct map_sysfs_entry name_attribute =
+ __ATTR(name, S_IRUGO, map_name_show, NULL);
static struct map_sysfs_entry addr_attribute =
__ATTR(addr, S_IRUGO, map_addr_show, NULL);
static struct map_sysfs_entry size_attribute =
@@ -90,6 +100,7 @@ static struct map_sysfs_entry offset_attribute =
__ATTR(offset, S_IRUGO, map_offset_show, NULL);
static struct attribute *attrs[] = {
+ &name_attribute.attr,
&addr_attribute.attr,
&size_attribute.attr,
&offset_attribute.attr,
@@ -133,6 +144,14 @@ struct uio_portio {
};
#define to_portio(portio) container_of(portio, struct uio_portio, kobj)
+static ssize_t portio_name_show(struct uio_port *port, char *buf)
+{
+ if (unlikely(!port->name))
+ port->name = "";
+
+ return sprintf(buf, "%s\n", port->name);
+}
+
static ssize_t portio_start_show(struct uio_port *port, char *buf)
{
return sprintf(buf, "0x%lx\n", port->start);
@@ -159,6 +178,8 @@ struct portio_sysfs_entry {
ssize_t (*store)(struct uio_port *, const char *, size_t);
};
+static struct portio_sysfs_entry portio_name_attribute =
+ __ATTR(name, S_IRUGO, portio_name_show, NULL);
static struct portio_sysfs_entry portio_start_attribute =
__ATTR(start, S_IRUGO, portio_start_show, NULL);
static struct portio_sysfs_entry portio_size_attribute =
@@ -167,6 +188,7 @@ static struct portio_sysfs_entry portio_porttype_attribute =
__ATTR(porttype, S_IRUGO, portio_porttype_show, NULL);
static struct attribute *portio_attrs[] = {
+ &portio_name_attribute.attr,
&portio_start_attribute.attr,
&portio_size_attribute.attr,
&portio_porttype_attribute.attr,
@@ -686,7 +708,8 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
return -EINVAL;
requested_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
- actual_pages = (idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
+ actual_pages = ((idev->info->mem[mi].addr & ~PAGE_MASK)
+ + idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
if (requested_pages > actual_pages)
return -EINVAL;
diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c
new file mode 100644
index 00000000000..b7830e9a3ba
--- /dev/null
+++ b/drivers/uio/uio_aec.c
@@ -0,0 +1,175 @@
+/*
+ * uio_aec.c -- simple driver for Adrienne Electronics Corp time code PCI device
+ *
+ * Copyright (C) 2008 Brandon Philips <brandon@ifup.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/uio_driver.h>
+
+#define PCI_VENDOR_ID_AEC 0xaecb
+#define PCI_DEVICE_ID_AEC_VITCLTC 0x6250
+
+#define INT_ENABLE_ADDR 0xFC
+#define INT_ENABLE 0x10
+#define INT_DISABLE 0x0
+
+#define INT_MASK_ADDR 0x2E
+#define INT_MASK_ALL 0x3F
+
+#define INTA_DRVR_ADDR 0xFE
+#define INTA_ENABLED_FLAG 0x08
+#define INTA_FLAG 0x01
+
+#define MAILBOX 0x0F
+
+static struct pci_device_id ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AEC, PCI_DEVICE_ID_AEC_VITCLTC), },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, ids);
+
+static irqreturn_t aectc_irq(int irq, struct uio_info *dev_info)
+{
+ void __iomem *int_flag = dev_info->priv + INTA_DRVR_ADDR;
+ unsigned char status = ioread8(int_flag);
+
+
+ if ((status & INTA_ENABLED_FLAG) && (status & INTA_FLAG)) {
+ /* application writes 0x00 to 0x2F to get next interrupt */
+ status = ioread8(dev_info->priv + MAILBOX);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static void print_board_data(struct pci_dev *pdev, struct uio_info *i)
+{
+ dev_info(&pdev->dev, "PCI-TC board vendor: %x%x number: %x%x"
+ " revision: %c%c\n",
+ ioread8(i->priv + 0x01),
+ ioread8(i->priv + 0x00),
+ ioread8(i->priv + 0x03),
+ ioread8(i->priv + 0x02),
+ ioread8(i->priv + 0x06),
+ ioread8(i->priv + 0x07));
+}
+
+static int __devinit probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct uio_info *info;
+ int ret;
+
+ info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ if (pci_enable_device(pdev))
+ goto out_free;
+
+ if (pci_request_regions(pdev, "aectc"))
+ goto out_disable;
+
+ info->name = "aectc";
+ info->port[0].start = pci_resource_start(pdev, 0);
+ if (!info->port[0].start)
+ goto out_release;
+ info->priv = pci_iomap(pdev, 0, 0);
+ if (!info->priv)
+ goto out_release;
+ info->port[0].size = pci_resource_len(pdev, 0);
+ info->port[0].porttype = UIO_PORT_GPIO;
+
+ info->version = "0.0.1";
+ info->irq = pdev->irq;
+ info->irq_flags = IRQF_SHARED;
+ info->handler = aectc_irq;
+
+ print_board_data(pdev, info);
+ ret = uio_register_device(&pdev->dev, info);
+ if (ret)
+ goto out_unmap;
+
+ iowrite32(INT_ENABLE, info->priv + INT_ENABLE_ADDR);
+ iowrite8(INT_MASK_ALL, info->priv + INT_MASK_ADDR);
+ if (!(ioread8(info->priv + INTA_DRVR_ADDR)
+ & INTA_ENABLED_FLAG))
+ dev_err(&pdev->dev, "aectc: interrupts not enabled\n");
+
+ pci_set_drvdata(pdev, info);
+
+ return 0;
+
+out_unmap:
+ pci_iounmap(pdev, info->priv);
+out_release:
+ pci_release_regions(pdev);
+out_disable:
+ pci_disable_device(pdev);
+out_free:
+ kfree(info);
+ return -ENODEV;
+}
+
+static void remove(struct pci_dev *pdev)
+{
+ struct uio_info *info = pci_get_drvdata(pdev);
+
+ /* disable interrupts */
+ iowrite8(INT_DISABLE, info->priv + INT_MASK_ADDR);
+ iowrite32(INT_DISABLE, info->priv + INT_ENABLE_ADDR);
+ /* read mailbox to ensure board drops irq */
+ ioread8(info->priv + MAILBOX);
+
+ uio_unregister_device(info);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ iounmap(info->priv);
+
+ kfree(info);
+}
+
+static struct pci_driver pci_driver = {
+ .name = "aectc",
+ .id_table = ids,
+ .probe = probe,
+ .remove = remove,
+};
+
+static int __init aectc_init(void)
+{
+ return pci_register_driver(&pci_driver);
+}
+
+static void __exit aectc_exit(void)
+{
+ pci_unregister_driver(&pci_driver);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(aectc_init);
+module_exit(aectc_exit);
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 83babb0a1df..c6c816b7ecb 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -47,6 +47,7 @@ config USB_ARCH_HAS_OHCI
default y if CPU_SUBTYPE_SH7720
default y if CPU_SUBTYPE_SH7721
default y if CPU_SUBTYPE_SH7763
+ default y if CPU_SUBTYPE_SH7786
# more:
default PCI
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 8b7c419b876..89299a5ce16 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -11,12 +11,15 @@ obj-$(CONFIG_USB_MON) += mon/
obj-$(CONFIG_PCI) += host/
obj-$(CONFIG_USB_EHCI_HCD) += host/
obj-$(CONFIG_USB_ISP116X_HCD) += host/
+obj-$(CONFIG_USB_ISP1760_HCD) += host/
obj-$(CONFIG_USB_OHCI_HCD) += host/
obj-$(CONFIG_USB_UHCI_HCD) += host/
+obj-$(CONFIG_USB_FHCI_HCD) += host/
obj-$(CONFIG_USB_SL811_HCD) += host/
obj-$(CONFIG_USB_U132_HCD) += host/
obj-$(CONFIG_USB_R8A66597_HCD) += host/
obj-$(CONFIG_USB_HWA_HCD) += host/
+obj-$(CONFIG_USB_ISP1760_HCD) += host/
obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 5ed4ae07bac..6789089e246 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -485,7 +485,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n",
wbuflen, rbuflen);
ret = -ENOMEM;
- goto fail;
+ goto err;
}
mutex_lock(&instance->cm_serialize);
@@ -565,6 +565,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
dbg("cm %#x", cm);
fail:
mutex_unlock(&instance->cm_serialize);
+err:
return ret;
}
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 00b47ea24f8..b3d5a23ab56 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1349,6 +1349,9 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
+ { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
{ USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
@@ -1370,6 +1373,18 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
+ { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
+ { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
+ },
+ { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
+ .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
+ data interface instead of
+ communications interface.
+ Maybe we should define a new
+ quirk for this. */
+ },
/* control interfaces with various AT-command sets */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index b5775af3ba2..d2747a49b97 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -226,6 +226,7 @@ static const struct quirk_printer_struct quirk_printers[] = {
{ 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
{ 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
{ 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
+ { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
{ 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
{ 0, 0 }
};
@@ -879,16 +880,19 @@ static int usblp_wwait(struct usblp *usblp, int nonblock)
if (rc <= 0)
break;
- if (usblp->flags & LP_ABORT) {
- if (schedule_timeout(msecs_to_jiffies(5000)) == 0) {
+ if (schedule_timeout(msecs_to_jiffies(1500)) == 0) {
+ if (usblp->flags & LP_ABORT) {
err = usblp_check_status(usblp, err);
if (err == 1) { /* Paper out */
rc = -ENOSPC;
break;
}
+ } else {
+ /* Prod the printer, Gentoo#251237. */
+ mutex_lock(&usblp->mut);
+ usblp_read_status(usblp, usblp->statusbuf);
+ mutex_unlock(&usblp->mut);
}
- } else {
- schedule();
}
}
set_current_state(TASK_RUNNING);
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index 0f5c05f6f9d..c40a9b284cc 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -50,6 +50,7 @@
static struct usb_device_id usbtmc_devices[] = {
{ USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), },
+ { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), },
{ 0, } /* terminating entry */
};
MODULE_DEVICE_TABLE(usb, usbtmc_devices);
@@ -106,12 +107,13 @@ static int usbtmc_open(struct inode *inode, struct file *filp)
{
struct usb_interface *intf;
struct usbtmc_device_data *data;
- int retval = -ENODEV;
+ int retval = 0;
intf = usb_find_interface(&usbtmc_driver, iminor(inode));
if (!intf) {
printk(KERN_ERR KBUILD_MODNAME
": can not find device for minor %d", iminor(inode));
+ retval = -ENODEV;
goto exit;
}
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 6ec38175a81..73c108d117b 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -187,7 +187,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,
}
/* this isn't checking for illegal values */
- switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(desc)) {
case USB_ENDPOINT_XFER_CONTROL:
type = "Ctrl";
if (speed == USB_SPEED_HIGH) /* uframes per NAK */
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 26fece124e0..df3c539f652 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -104,7 +104,7 @@ MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic");
#define MAX_USBFS_BUFFER_SIZE 16384
-static inline int connected(struct dev_state *ps)
+static int connected(struct dev_state *ps)
{
return (!list_empty(&ps->list) &&
ps->dev->state != USB_STATE_NOTATTACHED);
@@ -248,7 +248,7 @@ static void free_async(struct async *as)
kfree(as);
}
-static inline void async_newpending(struct async *as)
+static void async_newpending(struct async *as)
{
struct dev_state *ps = as->ps;
unsigned long flags;
@@ -258,7 +258,7 @@ static inline void async_newpending(struct async *as)
spin_unlock_irqrestore(&ps->lock, flags);
}
-static inline void async_removepending(struct async *as)
+static void async_removepending(struct async *as)
{
struct dev_state *ps = as->ps;
unsigned long flags;
@@ -268,7 +268,7 @@ static inline void async_removepending(struct async *as)
spin_unlock_irqrestore(&ps->lock, flags);
}
-static inline struct async *async_getcompleted(struct dev_state *ps)
+static struct async *async_getcompleted(struct dev_state *ps)
{
unsigned long flags;
struct async *as = NULL;
@@ -283,7 +283,7 @@ static inline struct async *async_getcompleted(struct dev_state *ps)
return as;
}
-static inline struct async *async_getpending(struct dev_state *ps,
+static struct async *async_getpending(struct dev_state *ps,
void __user *userurb)
{
unsigned long flags;
@@ -302,7 +302,7 @@ static inline struct async *async_getpending(struct dev_state *ps,
static void snoop_urb(struct urb *urb, void __user *userurb)
{
- int j;
+ unsigned j;
unsigned char *data = urb->transfer_buffer;
if (!usbfs_snoop)
@@ -311,9 +311,9 @@ static void snoop_urb(struct urb *urb, void __user *userurb)
dev_info(&urb->dev->dev, "direction=%s\n",
usb_urb_dir_in(urb) ? "IN" : "OUT");
dev_info(&urb->dev->dev, "userurb=%p\n", userurb);
- dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n",
+ dev_info(&urb->dev->dev, "transfer_buffer_length=%u\n",
urb->transfer_buffer_length);
- dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length);
+ dev_info(&urb->dev->dev, "actual_length=%u\n", urb->actual_length);
dev_info(&urb->dev->dev, "data: ");
for (j = 0; j < urb->transfer_buffer_length; ++j)
printk("%02x ", data[j]);
@@ -359,11 +359,6 @@ static void destroy_async(struct dev_state *ps, struct list_head *list)
spin_lock_irqsave(&ps->lock, flags);
}
spin_unlock_irqrestore(&ps->lock, flags);
- as = async_getcompleted(ps);
- while (as) {
- free_async(as);
- as = async_getcompleted(ps);
- }
}
static void destroy_async_on_interface(struct dev_state *ps,
@@ -381,7 +376,7 @@ static void destroy_async_on_interface(struct dev_state *ps,
destroy_async(ps, &hitlist);
}
-static inline void destroy_all_async(struct dev_state *ps)
+static void destroy_all_async(struct dev_state *ps)
{
destroy_async(ps, &ps->async_pending);
}
@@ -530,7 +525,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
{
int ret = 0;
- if (ps->dev->state != USB_STATE_ADDRESS
+ if (ps->dev->state != USB_STATE_UNAUTHENTICATED
+ && ps->dev->state != USB_STATE_ADDRESS
&& ps->dev->state != USB_STATE_CONFIGURED)
return -EHOSTUNREACH;
if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
@@ -643,6 +639,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
struct dev_state *ps = file->private_data;
struct usb_device *dev = ps->dev;
unsigned int ifnum;
+ struct async *as;
usb_lock_device(dev);
@@ -661,6 +658,12 @@ static int usbdev_release(struct inode *inode, struct file *file)
usb_unlock_device(dev);
usb_put_dev(dev);
put_pid(ps->disc_pid);
+
+ as = async_getcompleted(ps);
+ while (as) {
+ free_async(as);
+ as = async_getcompleted(ps);
+ }
kfree(ps);
return 0;
}
@@ -1700,7 +1703,7 @@ const struct file_operations usbdev_file_operations = {
.release = usbdev_release,
};
-void usb_fs_classdev_common_remove(struct usb_device *udev)
+static void usbdev_remove(struct usb_device *udev)
{
struct dev_state *ps;
struct siginfo sinfo;
@@ -1742,10 +1745,15 @@ static void usb_classdev_remove(struct usb_device *dev)
{
if (dev->usb_classdev)
device_unregister(dev->usb_classdev);
- usb_fs_classdev_common_remove(dev);
}
-static int usb_classdev_notify(struct notifier_block *self,
+#else
+#define usb_classdev_add(dev) 0
+#define usb_classdev_remove(dev) do {} while (0)
+
+#endif
+
+static int usbdev_notify(struct notifier_block *self,
unsigned long action, void *dev)
{
switch (action) {
@@ -1755,15 +1763,15 @@ static int usb_classdev_notify(struct notifier_block *self,
break;
case USB_DEVICE_REMOVE:
usb_classdev_remove(dev);
+ usbdev_remove(dev);
break;
}
return NOTIFY_OK;
}
static struct notifier_block usbdev_nb = {
- .notifier_call = usb_classdev_notify,
+ .notifier_call = usbdev_notify,
};
-#endif
static struct cdev usb_device_cdev;
@@ -1798,9 +1806,8 @@ int __init usb_devio_init(void)
* to /sys/dev
*/
usb_classdev_class->dev_kobj = NULL;
-
- usb_register_notify(&usbdev_nb);
#endif
+ usb_register_notify(&usbdev_nb);
out:
return retval;
@@ -1811,8 +1818,8 @@ error_cdev:
void usb_devio_cleanup(void)
{
-#ifdef CONFIG_USB_DEVICE_CLASS
usb_unregister_notify(&usbdev_nb);
+#ifdef CONFIG_USB_DEVICE_CLASS
class_destroy(usb_classdev_class);
#endif
cdev_del(&usb_device_cdev);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 98760553bc9..d0a21a5f820 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -284,7 +284,7 @@ static int usb_unbind_interface(struct device *dev)
* supports "soft" unbinding.
*/
if (!driver->soft_unbind)
- usb_disable_interface(udev, intf);
+ usb_disable_interface(udev, intf, false);
driver->disconnect(intf);
usb_cancel_queued_reset(intf);
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index e1710f260b4..40dee2ac013 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -66,7 +66,7 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr,
struct ep_device *ep = to_ep_device(dev);
char *type = "unknown";
- switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(ep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
type = "Control";
break;
@@ -94,7 +94,7 @@ static ssize_t show_ep_interval(struct device *dev,
in = (ep->desc->bEndpointAddress & USB_DIR_IN);
- switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(ep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */
interval = ep->desc->bInterval;
@@ -131,10 +131,9 @@ static ssize_t show_ep_direction(struct device *dev,
struct ep_device *ep = to_ep_device(dev);
char *direction;
- if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_CONTROL)
+ if (usb_endpoint_xfer_control(ep->desc))
direction = "both";
- else if (ep->desc->bEndpointAddress & USB_DIR_IN)
+ else if (usb_endpoint_dir_in(ep->desc))
direction = "in";
else
direction = "out";
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 507741ed448..a4301dc02d2 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -128,7 +128,6 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
}
pci_set_master(dev);
- device_set_wakeup_enable(&dev->dev, 1);
retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED);
if (retval != 0)
@@ -201,6 +200,7 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
struct usb_hcd *hcd = pci_get_drvdata(dev);
int retval = 0;
int wake, w;
+ int has_pci_pm;
/* Root hub suspend should have stopped all downstream traffic,
* and all bus master traffic. And done so for both the interface
@@ -230,6 +230,15 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
synchronize_irq(dev->irq);
+ /* Downstream ports from this root hub should already be quiesced, so
+ * there will be no DMA activity. Now we can shut down the upstream
+ * link (except maybe for PME# resume signaling) and enter some PCI
+ * low power state, if the hardware allows.
+ */
+ pci_disable_device(dev);
+
+ pci_save_state(dev);
+
/* Don't fail on error to enable wakeup. We rely on pci code
* to reject requests the hardware can't implement, rather
* than coding the same thing.
@@ -241,35 +250,6 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
wake = w;
dev_dbg(&dev->dev, "wakeup: %d\n", wake);
- /* Downstream ports from this root hub should already be quiesced, so
- * there will be no DMA activity. Now we can shut down the upstream
- * link (except maybe for PME# resume signaling) and enter some PCI
- * low power state, if the hardware allows.
- */
- pci_disable_device(dev);
- done:
- return retval;
-}
-EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend);
-
-/**
- * usb_hcd_pci_suspend_late - suspend a PCI-based HCD after IRQs are disabled
- * @dev: USB Host Controller being suspended
- * @message: Power Management message describing this state transition
- *
- * Store this function in the HCD's struct pci_driver as .suspend_late.
- */
-int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t message)
-{
- int retval = 0;
- int has_pci_pm;
-
- /* We might already be suspended (runtime PM -- not yet written) */
- if (dev->current_state != PCI_D0)
- goto done;
-
- pci_save_state(dev);
-
/* Don't change state if we don't need to */
if (message.event == PM_EVENT_FREEZE ||
message.event == PM_EVENT_PRETHAW) {
@@ -315,18 +295,18 @@ int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t message)
done:
return retval;
}
-EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend_late);
+EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend);
/**
- * usb_hcd_pci_resume_early - resume a PCI-based HCD before IRQs are enabled
+ * usb_hcd_pci_resume - power management resume of a PCI-based HCD
* @dev: USB Host Controller being resumed
*
- * Store this function in the HCD's struct pci_driver as .resume_early.
+ * Store this function in the HCD's struct pci_driver as .resume.
*/
-int usb_hcd_pci_resume_early(struct pci_dev *dev)
+int usb_hcd_pci_resume(struct pci_dev *dev)
{
- int retval = 0;
- pci_power_t state = dev->current_state;
+ struct usb_hcd *hcd;
+ int retval;
#ifdef CONFIG_PPC_PMAC
/* Reenable ASIC clocks for USB */
@@ -340,63 +320,7 @@ int usb_hcd_pci_resume_early(struct pci_dev *dev)
}
#endif
- /* NOTE: chip docs cover clean "real suspend" cases (what Linux
- * calls "standby", "suspend to RAM", and so on). There are also
- * dirty cases when swsusp fakes a suspend in "shutdown" mode.
- */
- if (state != PCI_D0) {
-#ifdef DEBUG
- int pci_pm;
- u16 pmcr;
-
- pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM);
- pci_read_config_word(dev, pci_pm + PCI_PM_CTRL, &pmcr);
- pmcr &= PCI_PM_CTRL_STATE_MASK;
- if (pmcr) {
- /* Clean case: power to USB and to HC registers was
- * maintained; remote wakeup is easy.
- */
- dev_dbg(&dev->dev, "resume from PCI D%d\n", pmcr);
- } else {
- /* Clean: HC lost Vcc power, D0 uninitialized
- * + Vaux may have preserved port and transceiver
- * state ... for remote wakeup from D3cold
- * + or not; HCD must reinit + re-enumerate
- *
- * Dirty: D0 semi-initialized cases with swsusp
- * + after BIOS init
- * + after Linux init (HCD statically linked)
- */
- dev_dbg(&dev->dev, "resume from previous PCI D%d\n",
- state);
- }
-#endif
-
- retval = pci_set_power_state(dev, PCI_D0);
- } else {
- /* Same basic cases: clean (powered/not), dirty */
- dev_dbg(&dev->dev, "PCI legacy resume\n");
- }
-
- if (retval < 0)
- dev_err(&dev->dev, "can't resume: %d\n", retval);
- else
- pci_restore_state(dev);
-
- return retval;
-}
-EXPORT_SYMBOL_GPL(usb_hcd_pci_resume_early);
-
-/**
- * usb_hcd_pci_resume - power management resume of a PCI-based HCD
- * @dev: USB Host Controller being resumed
- *
- * Store this function in the HCD's struct pci_driver as .resume.
- */
-int usb_hcd_pci_resume(struct pci_dev *dev)
-{
- struct usb_hcd *hcd;
- int retval;
+ pci_restore_state(dev);
hcd = pci_get_drvdata(dev);
if (hcd->state != HC_STATE_SUSPENDED) {
@@ -405,6 +329,8 @@ int usb_hcd_pci_resume(struct pci_dev *dev)
return 0;
}
+ pci_enable_wake(dev, PCI_D0, false);
+
retval = pci_enable_device(dev);
if (retval < 0) {
dev_err(&dev->dev, "can't re-enable after resume, %d!\n",
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 3c711db55d8..81fa8506825 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -279,9 +279,9 @@ static const u8 hs_rh_config_descriptor [] = {
* helper routine for returning string descriptors in UTF-16LE
* input can actually be ISO-8859-1; ASCII is its 7-bit subset
*/
-static int ascii2utf (char *s, u8 *utf, int utfmax)
+static unsigned ascii2utf(char *s, u8 *utf, int utfmax)
{
- int retval;
+ unsigned retval;
for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {
*utf++ = *s++;
@@ -304,19 +304,15 @@ static int ascii2utf (char *s, u8 *utf, int utfmax)
* Produces either a manufacturer, product or serial number string for the
* virtual root hub device.
*/
-static int rh_string (
- int id,
- struct usb_hcd *hcd,
- u8 *data,
- int len
-) {
+static unsigned rh_string(int id, struct usb_hcd *hcd, u8 *data, unsigned len)
+{
char buf [100];
// language ids
if (id == 0) {
buf[0] = 4; buf[1] = 3; /* 4 bytes string data */
buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */
- len = min (len, 4);
+ len = min_t(unsigned, len, 4);
memcpy (data, buf, len);
return len;
@@ -332,10 +328,7 @@ static int rh_string (
} else if (id == 3) {
snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname,
init_utsname()->release, hcd->driver->description);
-
- // unsupported IDs --> "protocol stall"
- } else
- return -EPIPE;
+ }
switch (len) { /* All cases fall through */
default:
@@ -360,9 +353,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
u8 tbuf [sizeof (struct usb_hub_descriptor)]
__attribute__((aligned(4)));
const u8 *bufp = tbuf;
- int len = 0;
+ unsigned len = 0;
int status;
- int n;
u8 patch_wakeup = 0;
u8 patch_protocol = 0;
@@ -456,10 +448,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
patch_wakeup = 1;
break;
case USB_DT_STRING << 8:
- n = rh_string (wValue & 0xff, hcd, ubuf, wLength);
- if (n < 0)
+ if ((wValue & 0xff) < 4)
+ urb->actual_length = rh_string(wValue & 0xff,
+ hcd, ubuf, wLength);
+ else /* unsupported IDs --> "protocol stall" */
goto error;
- urb->actual_length = n;
break;
default:
goto error;
@@ -629,7 +622,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb)
{
int retval;
unsigned long flags;
- int len = 1 + (urb->dev->maxchild / 8);
+ unsigned len = 1 + (urb->dev->maxchild / 8);
spin_lock_irqsave (&hcd_root_hub_lock, flags);
if (hcd->status_urb || urb->transfer_buffer_length < len) {
@@ -901,7 +894,7 @@ static int register_root_hub(struct usb_hcd *hcd)
mutex_lock(&usb_bus_list_lock);
- usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+ usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
if (retval != sizeof usb_dev->descriptor) {
mutex_unlock(&usb_bus_list_lock);
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 572d2cf46e8..f750eb1ab59 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -257,8 +257,6 @@ extern void usb_hcd_pci_remove(struct pci_dev *dev);
#ifdef CONFIG_PM
extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg);
-extern int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t msg);
-extern int usb_hcd_pci_resume_early(struct pci_dev *dev);
extern int usb_hcd_pci_resume(struct pci_dev *dev);
#endif /* CONFIG_PM */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 94d5ee263c2..be86ae3f408 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb)
{
struct usb_hub *hub = urb->context;
int status = urb->status;
- int i;
+ unsigned i;
unsigned long bits;
switch (status) {
@@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev,
recursively_mark_NOTATTACHED(udev);
spin_unlock_irqrestore(&device_state_lock, flags);
}
+EXPORT_SYMBOL_GPL(usb_set_device_state);
/*
* WUSB devices are simple: they have no hubs behind, so the mapping
@@ -2382,8 +2383,8 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)
void usb_ep0_reinit(struct usb_device *udev)
{
- usb_disable_endpoint(udev, 0 + USB_DIR_IN);
- usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ usb_disable_endpoint(udev, 0 + USB_DIR_IN, true);
+ usb_disable_endpoint(udev, 0 + USB_DIR_OUT, true);
usb_enable_endpoint(udev, &udev->ep0, true);
}
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
@@ -2471,20 +2472,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
*/
switch (udev->speed) {
case USB_SPEED_VARIABLE: /* fixed at 512 */
- udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512);
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
break;
case USB_SPEED_HIGH: /* fixed at 64 */
- udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
break;
case USB_SPEED_FULL: /* 8, 16, 32, or 64 */
/* to determine the ep0 maxpacket size, try to read
* the device descriptor to get bMaxPacketSize0 and
* then correct our initial guess.
*/
- udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
break;
case USB_SPEED_LOW: /* fixed at 8 */
- udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8);
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
break;
default:
goto fail;
@@ -3392,10 +3393,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
udev->descriptor = descriptor; /* for disconnect() calls */
goto re_enumerate;
}
-
+
+ /* Restore the device's previous configuration */
if (!udev->actconfig)
goto done;
-
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_SET_CONFIGURATION, 0,
udev->actconfig->desc.bConfigurationValue, 0,
@@ -3408,16 +3409,25 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
}
usb_set_device_state(udev, USB_STATE_CONFIGURED);
+ /* Put interfaces back into the same altsettings as before.
+ * Don't bother to send the Set-Interface request for interfaces
+ * that were already in altsetting 0; besides being unnecessary,
+ * many devices can't handle it. Instead just reset the host-side
+ * endpoint state.
+ */
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf = udev->actconfig->interface[i];
struct usb_interface_descriptor *desc;
- /* set_interface resets host side toggle even
- * for altsetting zero. the interface may have no driver.
- */
desc = &intf->cur_altsetting->desc;
- ret = usb_set_interface(udev, desc->bInterfaceNumber,
- desc->bAlternateSetting);
+ if (desc->bAlternateSetting == 0) {
+ usb_disable_interface(udev, intf, true);
+ usb_enable_interface(udev, intf, true);
+ ret = 0;
+ } else {
+ ret = usb_set_interface(udev, desc->bInterfaceNumber,
+ desc->bAlternateSetting);
+ }
if (ret < 0) {
dev_err(&udev->dev, "failed to restore interface %d "
"altsetting %d (error=%d)\n",
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 2a129cb7bb5..dff5760a37f 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -717,7 +717,6 @@ static void usbfs_remove_device(struct usb_device *dev)
fs_remove_file (dev->usbfs_dentry);
dev->usbfs_dentry = NULL;
}
- usb_fs_classdev_common_remove(dev);
}
static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index de51667dd64..30a0690f368 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -59,7 +59,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
dev_dbg(&urb->dev->dev,
- "%s timed out on ep%d%s len=%d/%d\n",
+ "%s timed out on ep%d%s len=%u/%u\n",
current->comm,
usb_endpoint_num(&urb->ep->desc),
usb_urb_dir_in(urb) ? "in" : "out",
@@ -653,7 +653,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type,
if (result <= 0 && result != -ETIMEDOUT)
continue;
if (result > 1 && ((u8 *)buf)[1] != type) {
- result = -EPROTO;
+ result = -ENODATA;
continue;
}
break;
@@ -696,8 +696,13 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid,
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(USB_DT_STRING << 8) + index, langid, buf, size,
USB_CTRL_GET_TIMEOUT);
- if (!(result == 0 || result == -EPIPE))
- break;
+ if (result == 0 || result == -EPIPE)
+ continue;
+ if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) {
+ result = -ENODATA;
+ continue;
+ }
+ break;
}
return result;
}
@@ -799,18 +804,16 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
dev_err(&dev->dev,
"string descriptor 0 read error: %d\n",
err);
- goto errout;
} else if (err < 4) {
dev_err(&dev->dev, "string descriptor 0 too short\n");
- err = -EINVAL;
- goto errout;
} else {
- dev->have_langid = 1;
dev->string_langid = tbuf[2] | (tbuf[3] << 8);
/* always use the first langid listed */
dev_dbg(&dev->dev, "default language 0x%04x\n",
dev->string_langid);
}
+
+ dev->have_langid = 1;
}
err = usb_string_sub(dev, dev->string_langid, index, tbuf);
@@ -1039,14 +1042,15 @@ static void remove_intf_ep_devs(struct usb_interface *intf)
* @dev: the device whose endpoint is being disabled
* @epaddr: the endpoint's address. Endpoint number for output,
* endpoint number + USB_DIR_IN for input
+ * @reset_hardware: flag to erase any endpoint state stored in the
+ * controller hardware
*
- * Deallocates hcd/hardware state for this endpoint ... and nukes all
- * pending urbs.
- *
- * If the HCD hasn't registered a disable() function, this sets the
- * endpoint's maxpacket size to 0 to prevent further submissions.
+ * Disables the endpoint for URB submission and nukes all pending URBs.
+ * If @reset_hardware is set then also deallocates hcd/hardware state
+ * for the endpoint.
*/
-void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
+void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
+ bool reset_hardware)
{
unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
struct usb_host_endpoint *ep;
@@ -1056,15 +1060,18 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
if (usb_endpoint_out(epaddr)) {
ep = dev->ep_out[epnum];
- dev->ep_out[epnum] = NULL;
+ if (reset_hardware)
+ dev->ep_out[epnum] = NULL;
} else {
ep = dev->ep_in[epnum];
- dev->ep_in[epnum] = NULL;
+ if (reset_hardware)
+ dev->ep_in[epnum] = NULL;
}
if (ep) {
ep->enabled = 0;
usb_hcd_flush_endpoint(dev, ep);
- usb_hcd_disable_endpoint(dev, ep);
+ if (reset_hardware)
+ usb_hcd_disable_endpoint(dev, ep);
}
}
@@ -1072,17 +1079,21 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
* usb_disable_interface -- Disable all endpoints for an interface
* @dev: the device whose interface is being disabled
* @intf: pointer to the interface descriptor
+ * @reset_hardware: flag to erase any endpoint state stored in the
+ * controller hardware
*
* Disables all the endpoints for the interface's current altsetting.
*/
-void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf)
+void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
+ bool reset_hardware)
{
struct usb_host_interface *alt = intf->cur_altsetting;
int i;
for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
usb_disable_endpoint(dev,
- alt->endpoint[i].desc.bEndpointAddress);
+ alt->endpoint[i].desc.bEndpointAddress,
+ reset_hardware);
}
}
@@ -1103,8 +1114,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
skip_ep0 ? "non-ep0" : "all");
for (i = skip_ep0; i < 16; ++i) {
- usb_disable_endpoint(dev, i);
- usb_disable_endpoint(dev, i + USB_DIR_IN);
+ usb_disable_endpoint(dev, i, true);
+ usb_disable_endpoint(dev, i + USB_DIR_IN, true);
}
dev->toggle[0] = dev->toggle[1] = 0;
@@ -1274,7 +1285,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
remove_intf_ep_devs(iface);
usb_remove_sysfs_intf_files(iface);
}
- usb_disable_interface(dev, iface);
+ usb_disable_interface(dev, iface, true);
iface->cur_altsetting = alt;
@@ -1353,8 +1364,8 @@ int usb_reset_configuration(struct usb_device *dev)
*/
for (i = 1; i < 16; ++i) {
- usb_disable_endpoint(dev, i);
- usb_disable_endpoint(dev, i + USB_DIR_IN);
+ usb_disable_endpoint(dev, i, true);
+ usb_disable_endpoint(dev, i + USB_DIR_IN, true);
}
config = dev->actconfig;
@@ -1706,7 +1717,8 @@ free_interfaces:
}
kfree(new_interfaces);
- if (cp->string == NULL)
+ if (cp->string == NULL &&
+ !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
/* Now that all the interfaces are set up, register them
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index c070b34b669..ab93918d920 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -54,6 +54,10 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x0638, 0x0a13), .driver_info =
USB_QUIRK_STRING_FETCH_255 },
+ /* Saitek Cyborg Gold Joystick */
+ { USB_DEVICE(0x06a3, 0x0006), .driver_info =
+ USB_QUIRK_CONFIG_INTF_STRINGS },
+
/* M-Systems Flash Disk Pioneers */
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 4cc2456ef3b..c6678919792 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/usb.h>
+#include <linux/usb/quirks.h>
#include "usb.h"
/* Active configuration fields */
@@ -813,7 +814,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
if (intf->sysfs_files_created || intf->unregistering)
return 0;
- if (alt->string == NULL)
+ if (alt->string == NULL &&
+ !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
alt->string = usb_cache_string(udev, alt->desc.iInterface);
if (alt->string)
retval = device_create_file(&intf->dev, &dev_attr_interface);
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 58bc5e3c256..3376055f36e 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -295,7 +295,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
dev = urb->dev;
- if ((!dev) || (dev->state < USB_STATE_DEFAULT))
+ if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
return -ENODEV;
/* For now, get the endpoint from the pipe. Eventually drivers
@@ -370,7 +370,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
}
/* the I/O buffer must be mapped/unmapped, except when length=0 */
- if (urb->transfer_buffer_length < 0)
+ if (urb->transfer_buffer_length > INT_MAX)
return -EMSGSIZE;
#ifdef DEBUG
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 386177867a8..79d8a9ea559 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -15,9 +15,10 @@ extern void usb_enable_endpoint(struct usb_device *dev,
struct usb_host_endpoint *ep, bool reset_toggle);
extern void usb_enable_interface(struct usb_device *dev,
struct usb_interface *intf, bool reset_toggles);
-extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr);
+extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
+ bool reset_hardware);
extern void usb_disable_interface(struct usb_device *dev,
- struct usb_interface *intf);
+ struct usb_interface *intf, bool reset_hardware);
extern void usb_release_interface_cache(struct kref *ref);
extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
extern int usb_deauthorize_device(struct usb_device *);
@@ -151,7 +152,6 @@ extern struct usb_driver usbfs_driver;
extern const struct file_operations usbfs_devices_fops;
extern const struct file_operations usbdev_file_operations;
extern void usbfs_conn_disc_event(void);
-extern void usb_fs_classdev_common_remove(struct usb_device *udev);
extern int usb_devio_init(void);
extern void usb_devio_cleanup(void);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 3219d137340..770b3eaa918 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -191,6 +191,7 @@ config USB_GADGET_OMAP
boolean "OMAP USB Device Controller"
depends on ARCH_OMAP
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
+ select USB_OTG_UTILS if ARCH_OMAP
help
Many Texas Instruments OMAP processors have flexible full
speed USB device controllers, with support for up to 30
@@ -253,6 +254,7 @@ config USB_PXA25X_SMALL
config USB_GADGET_PXA27X
boolean "PXA 27x"
depends on ARCH_PXA && PXA27x
+ select USB_OTG_UTILS
help
Intel's PXA 27x series XScale ARM v5TE processors include
an integrated full speed USB 1.1 device controller.
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index abf8192f89e..826f3adde5d 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -551,7 +551,7 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp)
dma_desc->status = AMD_ADDBITS(dma_desc->status,
UDC_DMA_STP_STS_BS_HOST_BUSY,
UDC_DMA_STP_STS_BS);
- dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE);
+ dma_desc->bufptr = cpu_to_le32(DMA_DONT_USE);
req->td_data = dma_desc;
req->td_data_last = NULL;
req->chain_len = 1;
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index ee7ebb67441..563d5727544 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1017,7 +1017,7 @@ static struct usb_endpoint_descriptor usba_ep0_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0,
.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .wMaxPacketSize = cpu_to_le16(64),
/* FIXME: I have no idea what to put here */
.bInterval = 1,
};
@@ -1207,21 +1207,21 @@ static int do_test_mode(struct usba_udc *udc)
/* Avoid overly long expressions */
static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
+ if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
return true;
return false;
}
static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE))
+ if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE))
return true;
return false;
}
static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT))
+ if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT))
return true;
return false;
}
@@ -1239,7 +1239,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
status = cpu_to_le16(udc->devstatus);
} else if (crq->bRequestType
== (USB_DIR_IN | USB_RECIP_INTERFACE)) {
- status = __constant_cpu_to_le16(0);
+ status = cpu_to_le16(0);
} else if (crq->bRequestType
== (USB_DIR_IN | USB_RECIP_ENDPOINT)) {
struct usba_ep *target;
@@ -1250,12 +1250,12 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
status = 0;
if (is_stalled(udc, target))
- status |= __constant_cpu_to_le16(1);
+ status |= cpu_to_le16(1);
} else
goto delegate;
/* Write directly to the FIFO. No queueing is done. */
- if (crq->wLength != __constant_cpu_to_le16(sizeof(status)))
+ if (crq->wLength != cpu_to_le16(sizeof(status)))
goto stall;
ep->state = DATA_STAGE_IN;
__raw_writew(status, ep->fifo);
@@ -1274,7 +1274,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
struct usba_ep *target;
- if (crq->wLength != __constant_cpu_to_le16(0)
+ if (crq->wLength != cpu_to_le16(0)
|| !feature_is_ep_halt(crq))
goto stall;
target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
@@ -1308,7 +1308,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
struct usba_ep *target;
- if (crq->wLength != __constant_cpu_to_le16(0)
+ if (crq->wLength != cpu_to_le16(0)
|| !feature_is_ep_halt(crq))
goto stall;
@@ -1514,7 +1514,7 @@ restart:
*/
ep->state = DATA_STAGE_IN;
} else {
- if (crq.crq.wLength != __constant_cpu_to_le16(0))
+ if (crq.crq.wLength != cpu_to_le16(0))
ep->state = DATA_STAGE_OUT;
else
ep->state = STATUS_STAGE_IN;
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 5495b171cf2..928137d3dbd 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -66,7 +66,7 @@ static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_COMM,
.bDeviceSubClass = 0,
@@ -74,8 +74,8 @@ static struct usb_device_descriptor device_desc = {
/* .bMaxPacketSize0 = f(hardware) */
/* Vendor and product id can be overridden by module parameters. */
- .idVendor = __constant_cpu_to_le16(CDC_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(CDC_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(CDC_VENDOR_NUM),
+ .idProduct = cpu_to_le16(CDC_PRODUCT_NUM),
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
/* .iProduct = DYNAMIC */
@@ -193,7 +193,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
gadget->name,
cdc_config_driver.label);
device_desc.bcdDevice =
- __constant_cpu_to_le16(0x0300 | 0x0099);
+ cpu_to_le16(0x0300 | 0x0099);
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index bebf911c7e5..22c65960c42 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -56,7 +56,6 @@
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
@@ -2626,7 +2625,7 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name)
INIT_LIST_HEAD(&udc->gadget.ep_list);
udc->gadget.ep0 = NULL;
- strcpy(udc->gadget.dev.bus_id, "gadget");
+ dev_set_name(&udc->gadget.dev, "gadget");
udc->gadget.dev.dma_mask = dev->dma_mask;
udc->gadget.dev.parent = dev;
udc->gadget.dev.release = udc_release;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index f2da0269e1b..59e85234fa0 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -149,16 +149,17 @@ done:
int usb_function_deactivate(struct usb_function *function)
{
struct usb_composite_dev *cdev = function->config->cdev;
+ unsigned long flags;
int status = 0;
- spin_lock(&cdev->lock);
+ spin_lock_irqsave(&cdev->lock, flags);
if (cdev->deactivations == 0)
status = usb_gadget_disconnect(cdev->gadget);
if (status == 0)
cdev->deactivations++;
- spin_unlock(&cdev->lock);
+ spin_unlock_irqrestore(&cdev->lock, flags);
return status;
}
@@ -683,6 +684,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
struct usb_request *req = cdev->req;
int value = -EOPNOTSUPP;
u16 w_index = le16_to_cpu(ctrl->wIndex);
+ u8 intf = w_index & 0xFF;
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
struct usb_function *f = NULL;
@@ -769,10 +771,10 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
goto unknown;
if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
break;
- f = cdev->config->interface[w_index];
+ f = cdev->config->interface[intf];
if (!f)
break;
- if (w_value && !f->get_alt)
+ if (w_value && !f->set_alt)
break;
value = f->set_alt(f, w_index, w_value);
break;
@@ -781,7 +783,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
goto unknown;
if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
break;
- f = cdev->config->interface[w_index];
+ f = cdev->config->interface[intf];
if (!f)
break;
/* lots of interfaces only need altsetting zero... */
@@ -808,7 +810,7 @@ unknown:
*/
if ((ctrl->bRequestType & USB_RECIP_MASK)
== USB_RECIP_INTERFACE) {
- f = cdev->config->interface[w_index];
+ f = cdev->config->interface[intf];
if (f && f->setup)
value = f->setup(f, ctrl);
else
@@ -1012,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget)
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_function *f;
- /* REVISIT: should we have config and device level
+ /* REVISIT: should we have config level
* suspend/resume callbacks?
*/
DBG(cdev, "suspend\n");
@@ -1022,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget)
f->suspend(f);
}
}
+ if (composite->suspend)
+ composite->suspend(cdev);
}
static void
@@ -1030,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget)
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_function *f;
- /* REVISIT: should we have config and device level
+ /* REVISIT: should we have config level
* suspend/resume callbacks?
*/
DBG(cdev, "resume\n");
+ if (composite->resume)
+ composite->resume(cdev);
if (cdev->config) {
list_for_each_entry(f, &cdev->config->functions, list) {
if (f->resume)
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 9064696636a..a56b24d305f 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -1437,7 +1437,7 @@ restart:
}
if (urb->transfer_buffer_length > 1)
buf [1] = 0;
- urb->actual_length = min (2,
+ urb->actual_length = min_t(u32, 2,
urb->transfer_buffer_length);
value = 0;
status = 0;
@@ -1626,7 +1626,7 @@ static int dummy_hub_control (
hub_descriptor ((struct usb_hub_descriptor *) buf);
break;
case GetHubStatus:
- *(__le32 *) buf = __constant_cpu_to_le32 (0);
+ *(__le32 *) buf = cpu_to_le32 (0);
break;
case GetPortStatus:
if (wIndex != 1)
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index a36b1175b18..cd0914ec898 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -148,7 +148,7 @@ ep_matches (
return 0;
/* BOTH: "high bandwidth" works only at high speed */
- if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) {
+ if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) {
if (!gadget->is_dualspeed)
return 0;
/* configure your hardware with enough buffering!! */
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 37252d0012a..d006dc652e0 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -156,7 +156,7 @@ static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16 (0x0200),
+ .bcdUSB = cpu_to_le16 (0x0200),
.bDeviceClass = USB_CLASS_COMM,
.bDeviceSubClass = 0,
@@ -167,8 +167,8 @@ static struct usb_device_descriptor device_desc = {
* we support. (As does bNumConfigurations.) These values can
* also be overridden by module parameters.
*/
- .idVendor = __constant_cpu_to_le16 (CDC_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16 (CDC_PRODUCT_NUM),
+ .idVendor = cpu_to_le16 (CDC_VENDOR_NUM),
+ .idProduct = cpu_to_le16 (CDC_PRODUCT_NUM),
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
/* .iProduct = DYNAMIC */
@@ -318,7 +318,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
gadget->name,
eth_config_driver.label);
device_desc.bcdDevice =
- __constant_cpu_to_le16(0x0300 | 0x0099);
+ cpu_to_le16(0x0300 | 0x0099);
}
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index c1d34df0b15..7953948bfe4 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -125,7 +125,7 @@ static struct usb_cdc_header_desc acm_header_desc __initdata = {
.bLength = sizeof(acm_header_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_call_mgmt_descriptor
@@ -159,7 +159,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+ .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
.bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL,
};
@@ -197,7 +197,7 @@ static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+ .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
.bInterval = GS_LOG2_NOTIFY_INTERVAL+4,
};
@@ -205,14 +205,14 @@ static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *acm_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index 4ae579948e5..ecf5bdd0ae0 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -130,7 +130,7 @@ static struct usb_cdc_header_desc ecm_header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_union_desc ecm_union_desc __initdata = {
@@ -148,9 +148,9 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = {
/* this descriptor actually adds value, surprise! */
/* .iMACAddress = DYNAMIC */
- .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
- .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN),
- .wNumberMCFilters = __constant_cpu_to_le16(0),
+ .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
+ .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
+ .wNumberMCFilters = cpu_to_le16(0),
.bNumberPowerFilters = 0,
};
@@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
};
@@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
};
static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
@@ -245,7 +245,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
@@ -254,7 +254,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *ecm_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 8affe1dfc2c..eb6ddfc2085 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -100,7 +100,7 @@ static struct usb_endpoint_descriptor hs_loop_source_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_loop_sink_desc = {
@@ -108,7 +108,7 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_loopback_descs[] = {
@@ -359,7 +359,7 @@ static struct usb_configuration loopback_driver = {
* loopback_add - add a loopback testing configuration to a device
* @cdev: the device to support the loopback configuration
*/
-int __init loopback_add(struct usb_composite_dev *cdev)
+int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
{
int id;
@@ -372,6 +372,10 @@ int __init loopback_add(struct usb_composite_dev *cdev)
loopback_intf.iInterface = id;
loopback_driver.iConfiguration = id;
+ /* support autoresume for remote wakeup testing */
+ if (autoresume)
+ sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+
/* support OTG systems */
if (gadget_is_otg(cdev->gadget)) {
loopback_driver.descriptors = otg_desc;
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index 80c2e7e9622..46d6266f30e 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -123,7 +123,7 @@ static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = {
.bLength = sizeof(obex_cdc_header_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0120),
+ .bcdCDC = cpu_to_le16(0x0120),
};
static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = {
@@ -138,7 +138,7 @@ static struct usb_cdc_obex_desc obex_desc __initdata = {
.bLength = sizeof(obex_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_OBEX_TYPE,
- .bcdVersion = __constant_cpu_to_le16(0x0100),
+ .bcdVersion = cpu_to_le16(0x0100),
};
/* High-Speed Support */
@@ -149,7 +149,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
@@ -158,7 +158,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_function[] __initdata = {
@@ -366,9 +366,9 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
f->hs_descriptors = usb_copy_descriptors(hs_function);
obex->hs.obex_in = usb_find_endpoint(hs_function,
- f->descriptors, &obex_hs_ep_in_desc);
+ f->hs_descriptors, &obex_hs_ep_in_desc);
obex->hs.obex_out = usb_find_endpoint(hs_function,
- f->descriptors, &obex_hs_ep_out_desc);
+ f->hs_descriptors, &obex_hs_ep_out_desc);
}
/* Avoid letting this gadget enumerate until the userspace
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index c0916c7b217..c1abeb89b41 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -79,7 +79,7 @@ pn_header_desc = {
.bLength = sizeof pn_header_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static const struct usb_cdc_header_desc
@@ -87,7 +87,7 @@ pn_phonet_desc = {
.bLength = sizeof pn_phonet_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_PHONET_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x1505), /* ??? */
+ .bcdCDC = cpu_to_le16(0x1505), /* ??? */
};
static struct usb_cdc_union_desc
@@ -138,7 +138,7 @@ pn_hs_sink_desc = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor
@@ -157,7 +157,7 @@ pn_hs_source_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *fs_pn_function[] = {
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 3a8bb53fc47..3279a472604 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -137,7 +137,7 @@ static struct usb_cdc_header_desc header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = {
@@ -187,7 +187,7 @@ static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
};
@@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
};
static struct usb_endpoint_descriptor hs_in_desc __initdata = {
@@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_out_desc __initdata = {
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *eth_hs_function[] __initdata = {
@@ -437,7 +437,7 @@ invalid:
DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
ctrl->bRequestType, ctrl->bRequest,
w_value, w_index, w_length);
- req->zero = 0;
+ req->zero = (value < w_length);
req->length = value;
value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
if (value < 0)
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index fe5674db344..db0aa93606e 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -89,14 +89,14 @@ static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *gser_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index dc84d26d283..bffe91d525f 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -59,7 +59,6 @@ struct f_sourcesink {
struct usb_ep *in_ep;
struct usb_ep *out_ep;
- struct timer_list resume;
};
static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
@@ -67,10 +66,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
return container_of(f, struct f_sourcesink, function);
}
-static unsigned autoresume;
-module_param(autoresume, uint, 0);
-MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
-
static unsigned pattern;
module_param(pattern, uint, 0);
MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
@@ -118,7 +113,7 @@ static struct usb_endpoint_descriptor hs_source_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_sink_desc = {
@@ -126,7 +121,7 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_source_sink_descs[] = {
@@ -155,21 +150,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
/*-------------------------------------------------------------------------*/
-static void sourcesink_autoresume(unsigned long _c)
-{
- struct usb_composite_dev *cdev = (void *)_c;
- struct usb_gadget *g = cdev->gadget;
-
- /* Normally the host would be woken up for something
- * more significant than just a timer firing; likely
- * because of some direct user request.
- */
- if (g->speed != USB_SPEED_UNKNOWN) {
- int status = usb_gadget_wakeup(g);
- DBG(cdev, "%s --> %d\n", __func__, status);
- }
-}
-
static int __init
sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
{
@@ -198,9 +178,6 @@ autoconf_fail:
goto autoconf_fail;
ss->out_ep->driver_data = cdev; /* claim */
- setup_timer(&ss->resume, sourcesink_autoresume,
- (unsigned long) c->cdev);
-
/* support high speed hardware */
if (gadget_is_dualspeed(c->cdev->gadget)) {
hs_source_desc.bEndpointAddress =
@@ -359,7 +336,6 @@ static void disable_source_sink(struct f_sourcesink *ss)
cdev = ss->function.config->cdev;
disable_endpoints(cdev, ss->in_ep, ss->out_ep);
- del_timer(&ss->resume);
VDBG(cdev, "%s disabled\n", ss->function.name);
}
@@ -426,30 +402,6 @@ static void sourcesink_disable(struct usb_function *f)
disable_source_sink(ss);
}
-static void sourcesink_suspend(struct usb_function *f)
-{
- struct f_sourcesink *ss = func_to_ss(f);
- struct usb_composite_dev *cdev = f->config->cdev;
-
- if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
- return;
-
- if (autoresume) {
- mod_timer(&ss->resume, jiffies + (HZ * autoresume));
- DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
- } else
- DBG(cdev, "%s\n", __func__);
-}
-
-static void sourcesink_resume(struct usb_function *f)
-{
- struct f_sourcesink *ss = func_to_ss(f);
- struct usb_composite_dev *cdev = f->config->cdev;
-
- DBG(cdev, "%s\n", __func__);
- del_timer(&ss->resume);
-}
-
/*-------------------------------------------------------------------------*/
static int __init sourcesink_bind_config(struct usb_configuration *c)
@@ -467,8 +419,6 @@ static int __init sourcesink_bind_config(struct usb_configuration *c)
ss->function.unbind = sourcesink_unbind;
ss->function.set_alt = sourcesink_set_alt;
ss->function.disable = sourcesink_disable;
- ss->function.suspend = sourcesink_suspend;
- ss->function.resume = sourcesink_resume;
status = usb_add_function(c, &ss->function);
if (status)
@@ -559,7 +509,7 @@ static struct usb_configuration sourcesink_driver = {
* sourcesink_add - add a source/sink testing configuration to a device
* @cdev: the device to support the configuration
*/
-int __init sourcesink_add(struct usb_composite_dev *cdev)
+int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
{
int id;
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index fe183287577..a9c98fdb626 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -108,7 +108,7 @@ static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
@@ -116,7 +116,7 @@ static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_MDLM_TYPE,
- .bcdVersion = __constant_cpu_to_le16(0x0100),
+ .bcdVersion = cpu_to_le16(0x0100),
.bGUID = {
0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
@@ -144,9 +144,9 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
/* this descriptor actually adds value, surprise! */
/* .iMACAddress = DYNAMIC */
- .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
- .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN),
- .wNumberMCFilters = __constant_cpu_to_le16(0),
+ .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
+ .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
+ .wNumberMCFilters = cpu_to_le16(0),
.bNumberPowerFilters = 0,
};
@@ -186,7 +186,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
@@ -194,7 +194,7 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_eth_function[] __initdata = {
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index b10fa31cc91..5c030b080d4 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -847,13 +847,13 @@ device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
/* The next three values can be overridden by module parameters */
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID),
- .bcdDevice = __constant_cpu_to_le16(0xffff),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_ID),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_ID),
+ .bcdDevice = cpu_to_le16(0xffff),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
@@ -926,7 +926,7 @@ fs_intr_in_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(2),
+ .wMaxPacketSize = cpu_to_le16(2),
.bInterval = 32, // frames -> 32 ms
};
@@ -954,7 +954,7 @@ dev_qualifier = {
.bLength = sizeof dev_qualifier,
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bNumConfigurations = 1,
@@ -967,7 +967,7 @@ hs_bulk_in_desc = {
/* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor
@@ -977,7 +977,7 @@ hs_bulk_out_desc = {
/* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
.bInterval = 1, // NAK every 1 uframe
};
@@ -988,7 +988,7 @@ hs_intr_in_desc = {
/* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(2),
+ .wMaxPacketSize = cpu_to_le16(2),
.bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms
};
@@ -1711,7 +1711,9 @@ static int do_write(struct fsg_dev *fsg)
curlun->sense_data = SS_WRITE_PROTECTED;
return -EINVAL;
}
+ spin_lock(&curlun->filp->f_lock);
curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait
+ spin_unlock(&curlun->filp->f_lock);
/* Get the starting Logical Block Address and check that it's
* not too big */
@@ -1728,8 +1730,11 @@ static int do_write(struct fsg_dev *fsg)
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
return -EINVAL;
}
- if (fsg->cmnd[1] & 0x08) // FUA
+ if (fsg->cmnd[1] & 0x08) { // FUA
+ spin_lock(&curlun->filp->f_lock);
curlun->filp->f_flags |= O_SYNC;
+ spin_unlock(&curlun->filp->f_lock);
+ }
}
if (lba >= curlun->num_sectors) {
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
@@ -2646,7 +2651,7 @@ static int send_status(struct fsg_dev *fsg)
struct bulk_cs_wrap *csw = bh->buf;
/* Store and send the Bulk-only CSW */
- csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
+ csw->Signature = cpu_to_le32(USB_BULK_CS_SIG);
csw->Tag = fsg->tag;
csw->Residue = cpu_to_le32(fsg->residue);
csw->Status = status;
@@ -3089,7 +3094,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
/* Is the CBW valid? */
if (req->actual != USB_BULK_CB_WRAP_LEN ||
- cbw->Signature != __constant_cpu_to_le32(
+ cbw->Signature != cpu_to_le32(
USB_BULK_CB_SIG)) {
DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
req->actual,
@@ -3879,7 +3884,11 @@ static int __init check_parameters(struct fsg_dev *fsg)
mod_data.protocol_type = USB_SC_SCSI;
mod_data.protocol_name = "Transparent SCSI";
- if (gadget_is_sh(fsg->gadget))
+ /* Some peripheral controllers are known not to be able to
+ * halt bulk endpoints correctly. If one of them is present,
+ * disable stalls.
+ */
+ if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
mod_data.can_stall = 0;
if (mod_data.release == 0xffff) { // Parameter wasn't set
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index d6c5bcd4006..d701bf4698d 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -1622,6 +1622,8 @@ static int qe_ep_disable(struct usb_ep *_ep)
nuke(ep, -ESHUTDOWN);
ep->desc = NULL;
ep->stopped = 1;
+ ep->tx_req = NULL;
+ qe_ep_reset(udc, ep->epnum);
spin_unlock_irqrestore(&udc->lock, flags);
cpm_muram_free(cpm_muram_offset(ep->rxbase));
@@ -1681,14 +1683,11 @@ static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req)
kfree(req);
}
-/* queues (submits) an I/O request to an endpoint */
-static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
- gfp_t gfp_flags)
+static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req)
{
struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
struct qe_req *req = container_of(_req, struct qe_req, req);
struct qe_udc *udc;
- unsigned long flags;
int reval;
udc = ep->udc;
@@ -1732,7 +1731,7 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
list_add_tail(&req->queue, &ep->queue);
dev_vdbg(udc->dev, "gadget have request in %s! %d\n",
ep->name, req->req.length);
- spin_lock_irqsave(&udc->lock, flags);
+
/* push the request to device */
if (ep_is_in(ep))
reval = ep_req_send(ep, req);
@@ -1748,11 +1747,24 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
if (ep->dir == USB_DIR_OUT)
reval = ep_req_receive(ep, req);
- spin_unlock_irqrestore(&udc->lock, flags);
-
return 0;
}
+/* queues (submits) an I/O request to an endpoint */
+static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
+ gfp_t gfp_flags)
+{
+ struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
+ struct qe_udc *udc = ep->udc;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&udc->lock, flags);
+ ret = __qe_ep_queue(_ep, _req);
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return ret;
+}
+
/* dequeues (cancels, unlinks) an I/O request from an endpoint */
static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
{
@@ -2008,7 +2020,7 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value,
udc->ep0_dir = USB_DIR_IN;
/* data phase */
- status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC);
+ status = __qe_ep_queue(&ep->ep, &req->req);
if (status == 0)
return;
@@ -2151,6 +2163,9 @@ static int reset_irq(struct qe_udc *udc)
{
unsigned char i;
+ if (udc->usb_state == USB_STATE_DEFAULT)
+ return 0;
+
qe_usb_disable();
out_8(&udc->usb_regs->usb_usadr, 0);
@@ -2442,8 +2457,12 @@ static int __devinit qe_udc_reg_init(struct qe_udc *udc)
struct usb_ctlr __iomem *qe_usbregs;
qe_usbregs = udc->usb_regs;
- /* Init the usb register */
+ /* Spec says that we must enable the USB controller to change mode. */
out_8(&qe_usbregs->usb_usmod, 0x01);
+ /* Mode changed, now disable it, since muram isn't initialized yet. */
+ out_8(&qe_usbregs->usb_usmod, 0x00);
+
+ /* Initialize the rest. */
out_be16(&qe_usbregs->usb_usbmr, 0);
out_8(&qe_usbregs->usb_uscom, 0);
out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR);
@@ -2604,6 +2623,10 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
(unsigned long)udc_controller);
/* request irq and disable DR */
udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
+ if (!udc_controller->usb_irq) {
+ ret = -EINVAL;
+ goto err_noirq;
+ }
ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
driver_name, udc_controller);
@@ -2625,6 +2648,8 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
err6:
free_irq(udc_controller->usb_irq, udc_controller);
err5:
+ irq_dispose_mapping(udc_controller->usb_irq);
+err_noirq:
if (udc_controller->nullmap) {
dma_unmap_single(udc_controller->gadget.dev.parent,
udc_controller->nullp, 256,
@@ -2648,7 +2673,7 @@ err2:
iounmap(udc_controller->usb_regs);
err1:
kfree(udc_controller);
-
+ udc_controller = NULL;
return ret;
}
@@ -2710,6 +2735,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev)
kfree(ep->txframe);
free_irq(udc_controller->usb_irq, udc_controller);
+ irq_dispose_mapping(udc_controller->usb_irq);
tasklet_kill(&udc_controller->rx_tasklet);
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index f3c6703cffd..9d7b95d4e3d 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -404,7 +404,10 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num,
}
if (zlt)
tmp |= EP_QUEUE_HEAD_ZLT_SEL;
+
p_QH->max_pkt_length = cpu_to_le32(tmp);
+ p_QH->next_dtd_ptr = 1;
+ p_QH->size_ioc_int_sts = 0;
return;
}
@@ -1799,7 +1802,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
out:
if (retval)
- printk("gadget driver register failed %d\n", retval);
+ printk(KERN_WARNING "gadget driver register failed %d\n",
+ retval);
return retval;
}
EXPORT_SYMBOL(usb_gadget_register_driver);
@@ -1844,7 +1848,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
udc_controller->gadget.dev.driver = NULL;
udc_controller->driver = NULL;
- printk("unregistered gadget driver '%s'\n", driver->driver.name);
+ printk(KERN_WARNING "unregistered gadget driver '%s'\n",
+ driver->driver.name);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -2452,7 +2457,7 @@ module_init(udc_init);
static void __exit udc_exit(void)
{
platform_driver_unregister(&udc_driver);
- printk("%s unregistered\n", driver_desc);
+ printk(KERN_WARNING "%s unregistered\n", driver_desc);
}
module_exit(udc_exit);
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h
index dd2f16ad5a8..e84b3c47ed3 100644
--- a/drivers/usb/gadget/g_zero.h
+++ b/drivers/usb/gadget/g_zero.h
@@ -19,7 +19,7 @@ void disable_endpoints(struct usb_composite_dev *cdev,
struct usb_ep *in, struct usb_ep *out);
/* configuration-specific linkup */
-int sourcesink_add(struct usb_composite_dev *cdev);
-int loopback_add(struct usb_composite_dev *cdev);
+int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume);
+int loopback_add(struct usb_composite_dev *cdev, bool autoresume);
#endif /* __G_ZERO_H */
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 60d3f9e9b51..b9312dc6e04 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -199,10 +199,10 @@ DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1);
static struct usb_device_descriptor device_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.bNumConfigurations = 1,
@@ -241,8 +241,8 @@ static const struct usb_ac_header_descriptor_1 ac_header_desc = {
.bLength = USB_DT_AC_HEADER_SIZE(1),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,
- .bcdADC = __constant_cpu_to_le16(0x0100),
- .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
+ .bcdADC = cpu_to_le16(0x0100),
+ .wTotalLength = cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
.bInCollection = 1,
.baInterfaceNr = {
[0] = GMIDI_MS_INTERFACE,
@@ -265,8 +265,8 @@ static const struct usb_ms_header_descriptor ms_header_desc = {
.bLength = USB_DT_MS_HEADER_SIZE,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,
- .bcdMSC = __constant_cpu_to_le16(0x0100),
- .wTotalLength = __constant_cpu_to_le16(USB_DT_MS_HEADER_SIZE
+ .bcdMSC = cpu_to_le16(0x0100),
+ .wTotalLength = cpu_to_le16(USB_DT_MS_HEADER_SIZE
+ 2*USB_DT_MIDI_IN_SIZE
+ 2*USB_DT_MIDI_OUT_SIZE(1)),
};
@@ -1099,10 +1099,9 @@ static int gmidi_register_card(struct gmidi_device *dev)
.dev_free = gmidi_snd_free,
};
- card = snd_card_new(index, id, THIS_MODULE, 0);
- if (!card) {
- ERROR(dev, "snd_card_new failed\n");
- err = -ENOMEM;
+ err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+ if (err < 0) {
+ ERROR(dev, "snd_card_create failed\n");
goto fail;
}
dev->card = card;
@@ -1227,7 +1226,7 @@ autoconf_fail:
*/
pr_warning("%s: controller '%s' not recognized\n",
shortname, gadget->name);
- device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+ device_desc.bcdDevice = cpu_to_le16(0x9999);
}
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 63419c4d503..de010c939db 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1472,7 +1472,7 @@ static void ep0_setup(struct goku_udc *dev)
/* active endpoint */
if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0))
goto stall;
- if (ctrl.wIndex & __constant_cpu_to_le16(
+ if (ctrl.wIndex & cpu_to_le16(
USB_DIR_IN)) {
if (!dev->ep[tmp].is_in)
goto stall;
@@ -1480,7 +1480,7 @@ static void ep0_setup(struct goku_udc *dev)
if (dev->ep[tmp].is_in)
goto stall;
}
- if (ctrl.wValue != __constant_cpu_to_le16(
+ if (ctrl.wValue != cpu_to_le16(
USB_ENDPOINT_HALT))
goto stall;
if (tmp)
@@ -1493,7 +1493,7 @@ succeed:
return;
case USB_RECIP_DEVICE:
/* device remote wakeup: always clear */
- if (ctrl.wValue != __constant_cpu_to_le16(1))
+ if (ctrl.wValue != cpu_to_le16(1))
goto stall;
VDBG(dev, "clear dev remote wakeup\n");
goto succeed;
@@ -1519,7 +1519,7 @@ succeed:
dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION
&& ctrl.bRequestType == USB_RECIP_DEVICE);
if (unlikely(dev->req_config))
- dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0));
+ dev->configured = (ctrl.wValue != cpu_to_le16(0));
/* delegate everything to the gadget driver.
* it may respond after this irq handler returns.
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index cde8fdf15d5..168658b4b4e 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1,7 +1,7 @@
/*
* driver/usb/gadget/imx_udc.c
*
- * Copyright (C) 2005 Mike Lee(eemike@gmail.com)
+ * Copyright (C) 2005 Mike Lee <eemike@gmail.com>
* Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/timer.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -51,7 +52,8 @@ void ep0_chg_stat(const char *label, struct imx_udc_struct *imx_usb,
void imx_udc_enable(struct imx_udc_struct *imx_usb)
{
int temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, imx_usb->base + USB_CTRL);
+ __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA,
+ imx_usb->base + USB_CTRL);
imx_usb->gadget.speed = USB_SPEED_FULL;
}
@@ -126,7 +128,8 @@ void imx_udc_config(struct imx_udc_struct *imx_usb)
for (j = 0; j < 5; j++) {
__raw_writeb(ep_conf[j],
imx_usb->base + USB_DDAT);
- do {} while (__raw_readl(imx_usb->base + USB_DADR)
+ do {} while (__raw_readl(imx_usb->base
+ + USB_DADR)
& DADR_BSY);
}
}
@@ -183,7 +186,8 @@ void imx_udc_init_ep(struct imx_udc_struct *imx_usb)
temp = (EP_DIR(imx_ep) << 7) | (max << 5)
| (imx_ep->bmAttributes << 3);
__raw_writel(temp, imx_usb->base + USB_EP_STAT(i));
- __raw_writel(temp | EPSTAT_FLUSH, imx_usb->base + USB_EP_STAT(i));
+ __raw_writel(temp | EPSTAT_FLUSH,
+ imx_usb->base + USB_EP_STAT(i));
D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i,
__raw_readl(imx_usb->base + USB_EP_STAT(i)));
}
@@ -278,15 +282,18 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
struct imx_udc_struct *imx_usb = imx_ep->imx_usb;
int temp, i;
- D_ERR(imx_usb->dev, "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
+ D_ERR(imx_usb->dev,
+ "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
imx_flush(imx_ep);
/* Special care for ep0 */
- if (EP_NO(imx_ep)) {
+ if (!EP_NO(imx_ep)) {
temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
- do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER);
+ __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR,
+ imx_usb->base + USB_CTRL);
+ do { } while (__raw_readl(imx_usb->base + USB_CTRL)
+ & CTRL_CMDOVER);
temp = __raw_readl(imx_usb->base + USB_CTRL);
__raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL);
}
@@ -296,12 +303,13 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
for (i = 0; i < 100; i ++) {
- temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
- if (!temp & EPSTAT_STALL)
+ temp = __raw_readl(imx_usb->base
+ + USB_EP_STAT(EP_NO(imx_ep)));
+ if (!(temp & EPSTAT_STALL))
break;
udelay(20);
}
- if (i == 50)
+ if (i == 100)
D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
__func__, imx_ep->ep.name);
}
@@ -325,7 +333,8 @@ static int imx_udc_wakeup(struct usb_gadget *_gadget)
*******************************************************************************
*/
-static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
+static void ep_add_request(struct imx_ep_struct *imx_ep,
+ struct imx_request *req)
{
if (unlikely(!req))
return;
@@ -334,7 +343,8 @@ static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req
list_add_tail(&req->queue, &imx_ep->queue);
}
-static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
+static void ep_del_request(struct imx_ep_struct *imx_ep,
+ struct imx_request *req)
{
if (unlikely(!req))
return;
@@ -343,7 +353,8 @@ static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req
req->in_use = 0;
}
-static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status)
+static void done(struct imx_ep_struct *imx_ep,
+ struct imx_request *req, int status)
{
ep_del_request(imx_ep, req);
@@ -494,7 +505,8 @@ static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req)
__func__, imx_ep->ep.name, req,
completed ? "completed" : "not completed");
if (!EP_NO(imx_ep))
- ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE);
+ ep0_chg_stat(__func__,
+ imx_ep->imx_usb, EP0_IDLE);
}
}
@@ -539,10 +551,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
struct imx_request *req = NULL;
int ret = 0;
- if (!list_empty(&imx_ep->queue))
+ if (!list_empty(&imx_ep->queue)) {
req = list_entry(imx_ep->queue.next, struct imx_request, queue);
- if (req) {
switch (imx_ep->imx_usb->ep0state) {
case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */
@@ -561,6 +572,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
}
}
+ else
+ D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n",
+ __func__, imx_ep->ep.name);
+
return ret;
}
@@ -583,7 +598,8 @@ static void handle_ep0_devreq(struct imx_udc_struct *imx_usb)
"<%s> no setup packet received\n", __func__);
goto stall;
}
- u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep)));
+ u.word[i] = __raw_readl(imx_usb->base
+ + USB_EP_FDAT(EP_NO(imx_ep)));
}
temp = imx_ep_empty(imx_ep);
@@ -759,7 +775,7 @@ static int imx_ep_queue
*/
if (imx_usb->set_config && !EP_NO(imx_ep)) {
imx_usb->set_config = 0;
- D_EPX(imx_usb->dev,
+ D_ERR(imx_usb->dev,
"<%s> gadget reply set config\n", __func__);
return 0;
}
@@ -779,28 +795,29 @@ static int imx_ep_queue
return -ESHUTDOWN;
}
- local_irq_save(flags);
-
/* Debug */
D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
__func__, EP_NO(imx_ep),
- ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
- || (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length);
+ ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
+ == EP0_IN_DATA_PHASE)
+ || (EP_NO(imx_ep) && EP_DIR(imx_ep)))
+ ? "IN" : "OUT", usb_req->length);
dump_req(__func__, imx_ep, usb_req);
if (imx_ep->stopped) {
usb_req->status = -ESHUTDOWN;
- ret = -ESHUTDOWN;
- goto out;
+ return -ESHUTDOWN;
}
if (req->in_use) {
D_ERR(imx_usb->dev,
"<%s> refusing to queue req %p (already queued)\n",
__func__, req);
- goto out;
+ return 0;
}
+ local_irq_save(flags);
+
usb_req->status = -EINPROGRESS;
usb_req->actual = 0;
@@ -810,7 +827,7 @@ static int imx_ep_queue
ret = handle_ep0(imx_ep);
else
ret = handle_ep(imx_ep);
-out:
+
local_irq_restore(flags);
return ret;
}
@@ -997,71 +1014,32 @@ static void udc_stop_activity(struct imx_udc_struct *imx_usb,
*******************************************************************************
*/
-static irqreturn_t imx_udc_irq(int irq, void *dev)
+/*
+ * Called when timer expires.
+ * Timer is started when CFG_CHG is received.
+ */
+static void handle_config(unsigned long data)
{
- struct imx_udc_struct *imx_usb = dev;
+ struct imx_udc_struct *imx_usb = (void *)data;
struct usb_ctrlrequest u;
int temp, cfg, intf, alt;
- int intr = __raw_readl(imx_usb->base + USB_INTR);
- if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
- | INTR_RESET_STOP | INTR_CFG_CHG)) {
- dump_intr(__func__, intr, imx_usb->dev);
- dump_usb_stat(__func__, imx_usb);
- }
+ local_irq_disable();
- if (!imx_usb->driver) {
- /*imx_udc_disable(imx_usb);*/
- goto end_irq;
- }
+ temp = __raw_readl(imx_usb->base + USB_STAT);
+ cfg = (temp & STAT_CFG) >> 5;
+ intf = (temp & STAT_INTF) >> 3;
+ alt = temp & STAT_ALTSET;
- if (intr & INTR_WAKEUP) {
- if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
- && imx_usb->driver && imx_usb->driver->resume)
- imx_usb->driver->resume(&imx_usb->gadget);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_FULL;
- }
-
- if (intr & INTR_SUSPEND) {
- if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
- && imx_usb->driver && imx_usb->driver->suspend)
- imx_usb->driver->suspend(&imx_usb->gadget);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
- }
-
- if (intr & INTR_RESET_START) {
- __raw_writel(intr, imx_usb->base + USB_INTR);
- udc_stop_activity(imx_usb, imx_usb->driver);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
- }
+ D_REQ(imx_usb->dev,
+ "<%s> orig config C=%d, I=%d, A=%d / "
+ "req config C=%d, I=%d, A=%d\n",
+ __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
+ cfg, intf, alt);
- if (intr & INTR_RESET_STOP)
- imx_usb->gadget.speed = USB_SPEED_FULL;
+ if (cfg == 1 || cfg == 2) {
- if (intr & INTR_CFG_CHG) {
- __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
- temp = __raw_readl(imx_usb->base + USB_STAT);
- cfg = (temp & STAT_CFG) >> 5;
- intf = (temp & STAT_INTF) >> 3;
- alt = temp & STAT_ALTSET;
-
- D_REQ(imx_usb->dev,
- "<%s> orig config C=%d, I=%d, A=%d / "
- "req config C=%d, I=%d, A=%d\n",
- __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
- cfg, intf, alt);
-
- if (cfg != 1 && cfg != 2)
- goto end_irq;
-
- imx_usb->set_config = 0;
-
- /* Config setup */
if (imx_usb->cfg != cfg) {
- D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__);
u.bRequest = USB_REQ_SET_CONFIGURATION;
u.bRequestType = USB_DIR_OUT |
USB_TYPE_STANDARD |
@@ -1070,14 +1048,10 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
u.wIndex = 0;
u.wLength = 0;
imx_usb->cfg = cfg;
- imx_usb->set_config = 1;
imx_usb->driver->setup(&imx_usb->gadget, &u);
- imx_usb->set_config = 0;
- D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__);
}
if (imx_usb->intf != intf || imx_usb->alt != alt) {
- D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__);
u.bRequest = USB_REQ_SET_INTERFACE;
u.bRequestType = USB_DIR_OUT |
USB_TYPE_STANDARD |
@@ -1087,20 +1061,92 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
u.wLength = 0;
imx_usb->intf = intf;
imx_usb->alt = alt;
- imx_usb->set_config = 1;
imx_usb->driver->setup(&imx_usb->gadget, &u);
- imx_usb->set_config = 0;
- D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__);
}
}
+ imx_usb->set_config = 0;
+
+ local_irq_enable();
+}
+
+static irqreturn_t imx_udc_irq(int irq, void *dev)
+{
+ struct imx_udc_struct *imx_usb = dev;
+ int intr = __raw_readl(imx_usb->base + USB_INTR);
+ int temp;
+
+ if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
+ | INTR_RESET_STOP | INTR_CFG_CHG)) {
+ dump_intr(__func__, intr, imx_usb->dev);
+ dump_usb_stat(__func__, imx_usb);
+ }
+
+ if (!imx_usb->driver)
+ goto end_irq;
+
if (intr & INTR_SOF) {
+ /* Copy from Freescale BSP.
+ We must enable SOF intr and set CMDOVER.
+ Datasheet don't specifiy this action, but it
+ is done in Freescale BSP, so just copy it.
+ */
if (imx_usb->ep0state == EP0_IDLE) {
temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
+ __raw_writel(temp | CTRL_CMDOVER,
+ imx_usb->base + USB_CTRL);
}
}
+ if (intr & INTR_CFG_CHG) {
+ /* A workaround of serious IMX UDC bug.
+ Handling of CFG_CHG should be delayed for some time, because
+ IMX does not NACK the host when CFG_CHG interrupt is pending.
+ There is no time to handle current CFG_CHG
+ if next CFG_CHG or SETUP packed is send immediately.
+ We have to clear CFG_CHG, start the timer and
+ NACK the host by setting CTRL_CMDOVER
+ if it sends any SETUP packet.
+ When timer expires, handler is called to handle configuration
+ changes. While CFG_CHG is not handled (set_config=1),
+ we must NACK the host to every SETUP packed.
+ This delay prevents from going out of sync with host.
+ */
+ __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
+ imx_usb->set_config = 1;
+ mod_timer(&imx_usb->timer, jiffies + 5);
+ goto end_irq;
+ }
+
+ if (intr & INTR_WAKEUP) {
+ if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
+ && imx_usb->driver && imx_usb->driver->resume)
+ imx_usb->driver->resume(&imx_usb->gadget);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_FULL;
+ }
+
+ if (intr & INTR_SUSPEND) {
+ if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
+ && imx_usb->driver && imx_usb->driver->suspend)
+ imx_usb->driver->suspend(&imx_usb->gadget);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
+ }
+
+ if (intr & INTR_RESET_START) {
+ __raw_writel(intr, imx_usb->base + USB_INTR);
+ udc_stop_activity(imx_usb, imx_usb->driver);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
+ }
+
+ if (intr & INTR_RESET_STOP)
+ imx_usb->gadget.speed = USB_SPEED_FULL;
+
end_irq:
__raw_writel(intr, imx_usb->base + USB_INTR);
return IRQ_HANDLED;
@@ -1109,6 +1155,7 @@ end_irq:
static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
{
struct imx_udc_struct *imx_usb = dev;
+ struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0];
int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0));
dump_ep_intr(__func__, 0, intr, imx_usb->dev);
@@ -1118,16 +1165,15 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
return IRQ_HANDLED;
}
- /* DEVREQ IRQ has highest priority */
+ /* DEVREQ has highest priority */
if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ))
handle_ep0_devreq(imx_usb);
/* Seem i.MX is missing EOF interrupt sometimes.
- * Therefore we monitor both EOF and FIFO_EMPTY interrups
- * when transmiting, and both EOF and FIFO_FULL when
- * receiving data.
+ * Therefore we don't monitor EOF.
+ * We call handle_ep0() only if a request is queued for ep0.
*/
- else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL))
- handle_ep0(&imx_usb->imx_ep[0]);
+ else if (!list_empty(&imx_ep->queue))
+ handle_ep0(imx_ep);
__raw_writel(intr, imx_usb->base + USB_EP_INTR(0));
@@ -1186,8 +1232,8 @@ static struct imx_udc_struct controller = {
.ep0 = &controller.imx_ep[0].ep,
.name = driver_name,
.dev = {
- .bus_id = "gadget",
- },
+ .init_name = "gadget",
+ },
},
.imx_ep[0] = {
@@ -1318,6 +1364,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
udc_stop_activity(imx_usb, driver);
imx_udc_disable(imx_usb);
+ del_timer(&imx_usb->timer);
driver->unbind(&imx_usb->gadget);
imx_usb->gadget.dev.driver = NULL;
@@ -1435,6 +1482,10 @@ static int __init imx_udc_probe(struct platform_device *pdev)
usb_init_data(imx_usb);
imx_udc_init(imx_usb);
+ init_timer(&imx_usb->timer);
+ imx_usb->timer.function = handle_config;
+ imx_usb->timer.data = (unsigned long)imx_usb;
+
return 0;
fail3:
@@ -1457,6 +1508,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
int i;
imx_udc_disable(imx_usb);
+ del_timer(&imx_usb->timer);
for (i = 0; i < IMX_USB_NB_EP + 1; i++)
free_irq(imx_usb->usbd_int[i], imx_usb);
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h
index 850076937d8..b48ad59603d 100644
--- a/drivers/usb/gadget/imx_udc.h
+++ b/drivers/usb/gadget/imx_udc.h
@@ -23,7 +23,8 @@
/* Helper macros */
#define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */
#define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0)
-#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
+#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \
+ ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
#define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0)
#define IMX_USB_NB_EP 6
@@ -58,6 +59,7 @@ struct imx_udc_struct {
struct device *dev;
struct imx_ep_struct imx_ep[IMX_USB_NB_EP];
struct clk *clk;
+ struct timer_list timer;
enum ep0_state ep0state;
struct resource *res;
void __iomem *base;
@@ -88,8 +90,8 @@ struct imx_udc_struct {
#define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */
#define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */
#define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */
-#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */
-#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */
+#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last rd f. pointer */
+#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last wr f. pointer */
#define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */
#define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */
#define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */
@@ -170,7 +172,7 @@ struct imx_udc_struct {
/* #define DEBUG_IRQ */
/* #define DEBUG_EPIRQ */
/* #define DEBUG_DUMP */
-#define DEBUG_ERR
+/* #define DEBUG_ERR */
#ifdef DEBUG_REQ
#define D_REQ(dev, args...) dev_dbg(dev, ## args)
@@ -228,7 +230,8 @@ struct imx_udc_struct {
#endif /* DEBUG_IRQ */
#ifdef DEBUG_EPIRQ
- static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev)
+ static void dump_ep_intr(const char *label, int nr, int irqreg,
+ struct device *dev)
{
dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr,
(irqreg & EPINTR_FIFO_FULL) ? " full" : "",
@@ -246,7 +249,8 @@ struct imx_udc_struct {
#endif /* DEBUG_IRQ */
#ifdef DEBUG_DUMP
- static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb)
+ static void dump_usb_stat(const char *label,
+ struct imx_udc_struct *imx_usb)
{
int temp = __raw_readl(imx_usb->base + USB_STAT);
@@ -259,12 +263,15 @@ struct imx_udc_struct {
(temp & STAT_ALTSET));
}
- static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep)
+ static void dump_ep_stat(const char *label,
+ struct imx_ep_struct *imx_ep)
{
- int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep)));
+ int temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_INTR(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n",
+ label, EP_NO(imx_ep),
(temp & EPINTR_FIFO_FULL) ? " full" : "",
(temp & EPINTR_FIFO_EMPTY) ? " fempty" : "",
(temp & EPINTR_FIFO_ERROR) ? " ferr" : "",
@@ -275,18 +282,22 @@ struct imx_udc_struct {
(temp & EPINTR_DEVREQ) ? " devreq" : "",
(temp & EPINTR_EOT) ? " eot" : "");
- temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
+ temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_STAT(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_STAT=[%s%s bcount=%d]\n",
+ label, EP_NO(imx_ep),
(temp & EPSTAT_SIP) ? " sip" : "",
(temp & EPSTAT_STALL) ? " stall" : "",
(temp & EPSTAT_BCOUNT) >> 16);
- temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep)));
+ temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_FSTAT(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n",
+ label, EP_NO(imx_ep),
(temp & FSTAT_ERR) ? " ferr" : "",
(temp & FSTAT_UF) ? " funder" : "",
(temp & FSTAT_OF) ? " fover" : "",
@@ -296,19 +307,23 @@ struct imx_udc_struct {
(temp & FSTAT_EMPTY) ? " fempty" : "");
}
- static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req)
+ static void dump_req(const char *label, struct imx_ep_struct *imx_ep,
+ struct usb_request *req)
{
int i;
if (!req || !req->buf) {
- dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label);
+ dev_dbg(imx_ep->imx_usb->dev,
+ "<%s> req or req buf is free\n", label);
return;
}
- if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
+ if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
+ == EP0_IN_DATA_PHASE)
|| (EP_NO(imx_ep) && EP_DIR(imx_ep))) {
- dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label);
+ dev_dbg(imx_ep->imx_usb->dev,
+ "<%s> request dump <", label);
for (i = 0; i < req->length; i++)
printk("%02x-", *((u8 *)req->buf + i));
printk(">\n");
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 317b48fdbf0..d20937f28a1 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1334,7 +1334,7 @@ static void make_qualifier (struct dev_data *dev)
qual.bLength = sizeof qual;
qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER;
- qual.bcdUSB = __constant_cpu_to_le16 (0x0200);
+ qual.bcdUSB = cpu_to_le16 (0x0200);
desc = dev->dev;
qual.bDeviceClass = desc->bDeviceClass;
@@ -1908,7 +1908,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|| dev->dev->bNumConfigurations != 1)
goto fail;
dev->dev->bNumConfigurations = 1;
- dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200);
+ dev->dev->bcdUSB = cpu_to_le16 (0x0200);
/* triggers gadgetfs_bind(); then we can enumerate. */
spin_unlock_irq (&dev->lock);
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index d554b089560..6cd3d54f564 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -432,8 +432,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
device_add(&dev->gadget.dev);
retval = driver->bind(&dev->gadget);
if (retval) {
- printk("%s: bind to driver %s --> error %d\n", dev->gadget.name,
- driver->driver.name, retval);
+ printk(KERN_WARNING "%s: bind to driver %s --> error %d\n",
+ dev->gadget.name, driver->driver.name, retval);
device_del(&dev->gadget.dev);
dev->driver = 0;
@@ -445,8 +445,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
* for set_configuration as well as eventual disconnect.
* NOTE: this shouldn't power up until later.
*/
- printk("%s: registered gadget driver '%s'\n", dev->gadget.name,
- driver->driver.name);
+ printk(KERN_WARNING "%s: registered gadget driver '%s'\n",
+ dev->gadget.name, driver->driver.name);
udc_enable(dev);
@@ -581,7 +581,8 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
* discard the extra data.
*/
if (req->req.status != -EOVERFLOW)
- printk("%s overflow %d\n", ep->ep.name, count);
+ printk(KERN_WARNING "%s overflow %d\n",
+ ep->ep.name, count);
req->req.status = -EOVERFLOW;
} else {
*buf++ = byte;
@@ -831,7 +832,8 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
queue);
if (!req) {
- printk("%s: NULL REQ %d\n",
+ printk(KERN_WARNING
+ "%s: NULL REQ %d\n",
__func__, ep_idx);
flush(ep);
break;
@@ -844,7 +846,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
} else {
/* Throw packet away.. */
- printk("%s: No descriptor?!?\n", __func__);
+ printk(KERN_WARNING "%s: No descriptor?!?\n", __func__);
flush(ep);
}
}
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 12c6d83b218..9498be87a72 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -142,8 +142,8 @@ static char *type_string (u8 bmAttributes)
#include "net2280.h"
-#define valid_bit __constant_cpu_to_le32 (1 << VALID_BIT)
-#define dma_done_ie __constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
+#define valid_bit cpu_to_le32 (1 << VALID_BIT)
+#define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
/*-------------------------------------------------------------------------*/
@@ -425,7 +425,7 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
return NULL;
}
td->dmacount = 0; /* not VALID */
- td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+ td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
td->dmadesc = td->dmaaddr;
req->td = td;
}
@@ -775,7 +775,7 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
fill_dma_desc (ep, req, 1);
if (!use_dma_chaining)
- req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN);
+ req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN);
start_queue (ep, tmp, req->td_dma);
}
@@ -2407,9 +2407,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
if (readl (&e->regs->ep_rsp)
& (1 << SET_ENDPOINT_HALT))
- status = __constant_cpu_to_le32 (1);
+ status = cpu_to_le32 (1);
else
- status = __constant_cpu_to_le32 (0);
+ status = cpu_to_le32 (0);
/* don't bother with a request object! */
writel (0, &dev->epregs [0].ep_irqenb);
@@ -2667,7 +2667,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
req = list_entry (ep->queue.next,
struct net2280_request, queue);
dmacount = req->td->dmacount;
- dmacount &= __constant_cpu_to_le32 (
+ dmacount &= cpu_to_le32 (
(1 << VALID_BIT)
| DMA_BYTE_COUNT_MASK);
if (dmacount && (dmacount & valid_bit) == 0)
@@ -2881,7 +2881,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
goto done;
}
td->dmacount = 0; /* not VALID */
- td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+ td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
td->dmadesc = td->dmaaddr;
dev->ep [i].dummy = td;
}
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 5a3034fdfe4..29500154d00 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -225,12 +225,12 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
- .idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.iSerialNumber = STRING_SERIALNUM,
@@ -299,20 +299,20 @@ static struct usb_endpoint_descriptor hs_ep_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512)
+ .wMaxPacketSize = cpu_to_le16(512)
};
static struct usb_endpoint_descriptor hs_ep_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512)
+ .wMaxPacketSize = cpu_to_le16(512)
};
static struct usb_qualifier_descriptor dev_qualifier = {
.bLength = sizeof dev_qualifier,
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PRINTER,
.bNumConfigurations = 1
};
@@ -1406,16 +1406,16 @@ printer_bind(struct usb_gadget *gadget)
gadget->name);
/* unrecognized, but safe unless bulk is REALLY quirky */
device_desc.bcdDevice =
- __constant_cpu_to_le16(0xFFFF);
+ cpu_to_le16(0xFFFF);
}
snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
init_utsname()->sysname, init_utsname()->release,
gadget->name);
device_desc.idVendor =
- __constant_cpu_to_le16(PRINTER_VENDOR_NUM);
+ cpu_to_le16(PRINTER_VENDOR_NUM);
device_desc.idProduct =
- __constant_cpu_to_le16(PRINTER_PRODUCT_NUM);
+ cpu_to_le16(PRINTER_PRODUCT_NUM);
/* support optional vendor/distro customization */
if (idVendor) {
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index 9b36205c575..0ce4e281984 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -904,8 +904,8 @@ static void pxa25x_ep_fifo_flush(struct usb_ep *_ep)
/* most IN status is the same, but ISO can't stall */
*ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR
- | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
- ? 0 : UDCCS_BI_SST;
+ | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
+ ? 0 : UDCCS_BI_SST);
}
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 990f40f988d..8cc676ecbb2 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -30,6 +30,7 @@
#include <linux/proc_fs.h>
#include <linux/clk.h>
#include <linux/irq.h>
+#include <linux/gpio.h>
#include <asm/byteorder.h>
#include <mach/hardware.h>
@@ -278,7 +279,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc)
goto err_queues;
eps = debugfs_create_file("epstate", 0400, root, udc,
&eps_dbg_fops);
- if (!queues)
+ if (!eps)
goto err_eps;
udc->debugfs_root = root;
@@ -747,13 +748,13 @@ static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status)
}
/**
- * ep_end_out_req - Ends control endpoint in request
+ * ep_end_out_req - Ends endpoint OUT request
* @ep: physical endpoint
* @req: pxa request
*
* Context: ep->lock held
*
- * Ends endpoint in request (completes usb request).
+ * Ends endpoint OUT request (completes usb request).
*/
static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
{
@@ -762,13 +763,13 @@ static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
}
/**
- * ep0_end_out_req - Ends control endpoint in request (ends data stage)
+ * ep0_end_out_req - Ends control endpoint OUT request (ends data stage)
* @ep: physical endpoint
* @req: pxa request
*
* Context: ep->lock held
*
- * Ends control endpoint in request (completes usb request), and puts
+ * Ends control endpoint OUT request (completes usb request), and puts
* control endpoint into idle state
*/
static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
@@ -779,13 +780,13 @@ static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
}
/**
- * ep_end_in_req - Ends endpoint out request
+ * ep_end_in_req - Ends endpoint IN request
* @ep: physical endpoint
* @req: pxa request
*
* Context: ep->lock held
*
- * Ends endpoint out request (completes usb request).
+ * Ends endpoint IN request (completes usb request).
*/
static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
{
@@ -794,20 +795,18 @@ static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
}
/**
- * ep0_end_in_req - Ends control endpoint out request (ends data stage)
+ * ep0_end_in_req - Ends control endpoint IN request (ends data stage)
* @ep: physical endpoint
* @req: pxa request
*
* Context: ep->lock held
*
- * Ends control endpoint out request (completes usb request), and puts
+ * Ends control endpoint IN request (completes usb request), and puts
* control endpoint into status state
*/
static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
{
- struct pxa_udc *udc = ep->dev;
-
- set_ep0state(udc, IN_STATUS_STAGE);
+ set_ep0state(ep->dev, IN_STATUS_STAGE);
ep_end_in_req(ep, req);
}
@@ -1167,7 +1166,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
ep_end_in_req(ep, req);
} else {
ep_err(ep, "got a request of %d bytes while"
- "in state WATI_ACK_SET_CONF_INTERF\n",
+ "in state WAIT_ACK_SET_CONF_INTERF\n",
length);
ep_del_request(ep, req);
rc = -EL2HLT;
@@ -1213,30 +1212,26 @@ static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
struct udc_usb_ep *udc_usb_ep;
struct pxa27x_request *req;
unsigned long flags;
- int rc;
+ int rc = -EINVAL;
if (!_ep)
- return -EINVAL;
+ return rc;
udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
ep = udc_usb_ep->pxa_ep;
if (!ep || is_ep0(ep))
- return -EINVAL;
+ return rc;
spin_lock_irqsave(&ep->lock, flags);
/* make sure it's actually queued on this endpoint */
list_for_each_entry(req, &ep->queue, queue) {
- if (&req->req == _req)
+ if (&req->req == _req) {
+ req_done(ep, req, -ECONNRESET);
+ rc = 0;
break;
+ }
}
- rc = -EINVAL;
- if (&req->req != _req)
- goto out;
-
- rc = 0;
- req_done(ep, req, -ECONNRESET);
-out:
spin_unlock_irqrestore(&ep->lock, flags);
return rc;
}
@@ -1471,6 +1466,32 @@ static struct usb_ep_ops pxa_ep_ops = {
.fifo_flush = pxa_ep_fifo_flush,
};
+/**
+ * dplus_pullup - Connect or disconnect pullup resistor to D+ pin
+ * @udc: udc device
+ * @on: 0 if disconnect pullup resistor, 1 otherwise
+ * Context: any
+ *
+ * Handle D+ pullup resistor, make the device visible to the usb bus, and
+ * declare it as a full speed usb device
+ */
+static void dplus_pullup(struct pxa_udc *udc, int on)
+{
+ if (on) {
+ if (gpio_is_valid(udc->mach->gpio_pullup))
+ gpio_set_value(udc->mach->gpio_pullup,
+ !udc->mach->gpio_pullup_inverted);
+ if (udc->mach->udc_command)
+ udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+ } else {
+ if (gpio_is_valid(udc->mach->gpio_pullup))
+ gpio_set_value(udc->mach->gpio_pullup,
+ udc->mach->gpio_pullup_inverted);
+ if (udc->mach->udc_command)
+ udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+ }
+ udc->pullup_on = on;
+}
/**
* pxa_udc_get_frame - Returns usb frame number
@@ -1500,21 +1521,145 @@ static int pxa_udc_wakeup(struct usb_gadget *_gadget)
return 0;
}
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+/**
+ * should_enable_udc - Tells if UDC should be enabled
+ * @udc: udc device
+ * Context: any
+ *
+ * The UDC should be enabled if :
+
+ * - the pullup resistor is connected
+ * - and a gadget driver is bound
+ * - and vbus is sensed (or no vbus sense is available)
+ *
+ * Returns 1 if UDC should be enabled, 0 otherwise
+ */
+static int should_enable_udc(struct pxa_udc *udc)
+{
+ int put_on;
+
+ put_on = ((udc->pullup_on) && (udc->driver));
+ put_on &= ((udc->vbus_sensed) || (!udc->transceiver));
+ return put_on;
+}
+
+/**
+ * should_disable_udc - Tells if UDC should be disabled
+ * @udc: udc device
+ * Context: any
+ *
+ * The UDC should be disabled if :
+ * - the pullup resistor is not connected
+ * - or no gadget driver is bound
+ * - or no vbus is sensed (when vbus sesing is available)
+ *
+ * Returns 1 if UDC should be disabled
+ */
+static int should_disable_udc(struct pxa_udc *udc)
+{
+ int put_off;
+
+ put_off = ((!udc->pullup_on) || (!udc->driver));
+ put_off |= ((!udc->vbus_sensed) && (udc->transceiver));
+ return put_off;
+}
+
+/**
+ * pxa_udc_pullup - Offer manual D+ pullup control
+ * @_gadget: usb gadget using the control
+ * @is_active: 0 if disconnect, else connect D+ pullup resistor
+ * Context: !in_interrupt()
+ *
+ * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup
+ */
+static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
+ return -EOPNOTSUPP;
+
+ dplus_pullup(udc, is_active);
+
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc))
+ udc_disable(udc);
+ return 0;
+}
+
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+/**
+ * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc
+ * @_gadget: usb gadget
+ * @is_active: 0 if should disable the udc, 1 if should enable
+ *
+ * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the
+ * udc, and deactivates D+ pullup resistor.
+ *
+ * Returns 0
+ */
+static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ udc->vbus_sensed = is_active;
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc))
+ udc_disable(udc);
+
+ return 0;
+}
+
+/**
+ * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed
+ * @_gadget: usb gadget
+ * @mA: current drawn
+ *
+ * Context: !in_interrupt()
+ *
+ * Called after a configuration was chosen by a USB host, to inform how much
+ * current can be drawn by the device from VBus line.
+ *
+ * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc
+ */
+static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
+{
+ struct pxa_udc *udc;
+
+ udc = to_gadget_udc(_gadget);
+ if (udc->transceiver)
+ return otg_set_power(udc->transceiver, mA);
+ return -EOPNOTSUPP;
+}
+
static const struct usb_gadget_ops pxa_udc_ops = {
.get_frame = pxa_udc_get_frame,
.wakeup = pxa_udc_wakeup,
- /* current versions must always be self-powered */
+ .pullup = pxa_udc_pullup,
+ .vbus_session = pxa_udc_vbus_session,
+ .vbus_draw = pxa_udc_vbus_draw,
};
/**
* udc_disable - disable udc device controller
* @udc: udc device
+ * Context: any
*
* Disables the udc device : disables clocks, udc interrupts, control endpoint
* interrupts.
*/
static void udc_disable(struct pxa_udc *udc)
{
+ if (!udc->enabled)
+ return;
+
udc_writel(udc, UDCICR0, 0);
udc_writel(udc, UDCICR1, 0);
@@ -1523,8 +1668,8 @@ static void udc_disable(struct pxa_udc *udc)
ep0_idle(udc);
udc->gadget.speed = USB_SPEED_UNKNOWN;
- if (udc->mach->udc_command)
- udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+
+ udc->enabled = 0;
}
/**
@@ -1555,10 +1700,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
}
/* USB endpoints init */
- for (i = 0; i < NR_USB_ENDPOINTS; i++)
- if (i != 0)
- list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
- &dev->gadget.ep_list);
+ for (i = 1; i < NR_USB_ENDPOINTS; i++)
+ list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
+ &dev->gadget.ep_list);
}
/**
@@ -1570,6 +1714,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
*/
static void udc_enable(struct pxa_udc *udc)
{
+ if (udc->enabled)
+ return;
+
udc_writel(udc, UDCICR0, 0);
udc_writel(udc, UDCICR1, 0);
udc_clear_mask_UDCCR(udc, UDCCR_UDE);
@@ -1598,9 +1745,7 @@ static void udc_enable(struct pxa_udc *udc)
/* enable ep0 irqs */
pio_irq_enable(&udc->pxa_ep[0]);
- dev_info(udc->dev, "UDC connecting\n");
- if (udc->mach->udc_command)
- udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+ udc->enabled = 1;
}
/**
@@ -1612,6 +1757,9 @@ static void udc_enable(struct pxa_udc *udc)
* usb traffic follows until a disconnect is reported. Then a host may connect
* again, or the driver might get unbound.
*
+ * Note that the udc is not automatically enabled. Check function
+ * should_enable_udc().
+ *
* Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
*/
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
@@ -1630,6 +1778,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
/* first hook up the driver ... */
udc->driver = driver;
udc->gadget.dev.driver = &driver->driver;
+ dplus_pullup(udc, 1);
retval = device_add(&udc->gadget.dev);
if (retval) {
@@ -1645,9 +1794,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dev_dbg(udc->dev, "registered gadget driver '%s'\n",
driver->driver.name);
- udc_enable(udc);
+ if (udc->transceiver) {
+ retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
+ if (retval) {
+ dev_err(udc->dev, "can't bind to transceiver\n");
+ goto transceiver_fail;
+ }
+ }
+
+ if (should_enable_udc(udc))
+ udc_enable(udc);
return 0;
+transceiver_fail:
+ if (driver->unbind)
+ driver->unbind(&udc->gadget);
bind_fail:
device_del(&udc->gadget.dev);
add_fail:
@@ -1699,14 +1860,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
stop_activity(udc, driver);
udc_disable(udc);
+ dplus_pullup(udc, 0);
driver->unbind(&udc->gadget);
udc->driver = NULL;
device_del(&udc->gadget.dev);
-
dev_info(udc->dev, "unregistered gadget driver '%s'\n",
driver->driver.name);
+
+ if (udc->transceiver)
+ return otg_set_peripheral(udc->transceiver, NULL);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -1823,14 +1987,14 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq)
struct pxa27x_request *req = NULL;
int completed = 0;
+ if (!list_empty(&ep->queue))
+ req = list_entry(ep->queue.next, struct pxa27x_request, queue);
+
udccsr0 = udc_ep_readl(ep, UDCCSR);
ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n",
EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR),
(fifo_irq << 1 | opc_irq));
- if (!list_empty(&ep->queue))
- req = list_entry(ep->queue.next, struct pxa27x_request, queue);
-
if (udccsr0 & UDCCSR0_SST) {
ep_dbg(ep, "clearing stall status\n");
nuke(ep, -EPIPE);
@@ -2212,7 +2376,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
{
struct resource *regs;
struct pxa_udc *udc = &memory;
- int retval;
+ int retval = 0, gpio;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs)
@@ -2223,6 +2387,20 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
udc->dev = &pdev->dev;
udc->mach = pdev->dev.platform_data;
+ udc->transceiver = otg_get_transceiver();
+
+ gpio = udc->mach->gpio_pullup;
+ if (gpio_is_valid(gpio)) {
+ retval = gpio_request(gpio, "USB D+ pullup");
+ if (retval == 0)
+ gpio_direction_output(gpio,
+ udc->mach->gpio_pullup_inverted);
+ }
+ if (retval) {
+ dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n",
+ gpio, retval);
+ return retval;
+ }
udc->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(udc->clk)) {
@@ -2240,6 +2418,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
device_initialize(&udc->gadget.dev);
udc->gadget.dev.parent = &pdev->dev;
udc->gadget.dev.dma_mask = NULL;
+ udc->vbus_sensed = 0;
the_controller = udc;
platform_set_drvdata(pdev, udc);
@@ -2273,14 +2452,21 @@ err_clk:
static int __exit pxa_udc_remove(struct platform_device *_dev)
{
struct pxa_udc *udc = platform_get_drvdata(_dev);
+ int gpio = udc->mach->gpio_pullup;
usb_gadget_unregister_driver(udc->driver);
free_irq(udc->irq, udc);
pxa_cleanup_debugfs(udc);
+ if (gpio_is_valid(gpio))
+ gpio_free(gpio);
+
+ otg_put_transceiver(udc->transceiver);
+ udc->transceiver = NULL;
platform_set_drvdata(_dev, NULL);
the_controller = NULL;
clk_put(udc->clk);
+ iounmap(udc->regs);
return 0;
}
@@ -2319,6 +2505,8 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
}
udc_disable(udc);
+ udc->pullup_resume = udc->pullup_on;
+ dplus_pullup(udc, 0);
return 0;
}
@@ -2346,7 +2534,9 @@ static int pxa_udc_resume(struct platform_device *_dev)
ep->udccsr_value, ep->udccr_value);
}
- udc_enable(udc);
+ dplus_pullup(udc, udc->pullup_resume);
+ if (should_enable_udc(udc))
+ udc_enable(udc);
/*
* We do not handle OTG yet.
*
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index 1d1b7936ee1..db58125331d 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -26,6 +26,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/io.h>
+#include <linux/usb/otg.h>
/*
* Register definitions
@@ -421,10 +422,14 @@ struct udc_stats {
* @driver: bound gadget (zero, g_ether, g_file_storage, ...)
* @dev: device
* @mach: machine info, used to activate specific GPIO
+ * @transceiver: external transceiver to handle vbus sense and D+ pullup
* @ep0state: control endpoint state machine state
* @stats: statistics on udc usage
* @udc_usb_ep: array of usb endpoints offered by the gadget
* @pxa_ep: array of pxa available endpoints
+ * @enabled: UDC was enabled by a previous udc_enable()
+ * @pullup_on: if pullup resistor connected to D+ pin
+ * @pullup_resume: if pullup resistor should be connected to D+ pin on resume
* @config: UDC active configuration
* @last_interface: UDC interface of the last SET_INTERFACE host request
* @last_alternate: UDC altsetting of the last SET_INTERFACE host request
@@ -443,6 +448,7 @@ struct pxa_udc {
struct usb_gadget_driver *driver;
struct device *dev;
struct pxa2xx_udc_mach_info *mach;
+ struct otg_transceiver *transceiver;
enum ep0_state ep0state;
struct udc_stats stats;
@@ -450,6 +456,10 @@ struct pxa_udc {
struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS];
struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS];
+ unsigned enabled:1;
+ unsigned pullup_on:1;
+ unsigned pullup_resume:1;
+ unsigned vbus_sensed:1;
unsigned config:2;
unsigned last_interface:3;
unsigned last_alternate:3;
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 8c26f5ea2b8..2b4660e08c4 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -63,7 +63,7 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging");
static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
/* Driver Version */
-static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1);
+static const __le32 rndis_driver_version = cpu_to_le32 (1);
/* Function Prototypes */
static rndis_resp_t *rndis_add_response (int configNr, u32 length);
@@ -170,7 +170,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
int i, count;
rndis_query_cmplt_type *resp;
struct net_device *net;
- struct net_device_stats *stats;
+ const struct net_device_stats *stats;
if (!r) return -ENOMEM;
resp = (rndis_query_cmplt_type *) r->buf;
@@ -190,13 +190,10 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* response goes here, right after the header */
outbuf = (__le32 *) &resp[1];
- resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
+ resp->InformationBufferOffset = cpu_to_le32 (16);
net = rndis_per_dev_params[configNr].dev;
- if (net->get_stats)
- stats = net->get_stats(net);
- else
- stats = NULL;
+ stats = dev_get_stats(net);
switch (OID) {
@@ -221,7 +218,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
* reddite ergo quae sunt Caesaris Caesari
* et quae sunt Dei Deo!
*/
- *outbuf = __constant_cpu_to_le32 (0);
+ *outbuf = cpu_to_le32 (0);
retval = 0;
break;
@@ -256,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__);
if (rndis_per_dev_params [configNr].media_state
== NDIS_MEDIA_STATE_DISCONNECTED)
- *outbuf = __constant_cpu_to_le32 (0);
+ *outbuf = cpu_to_le32 (0);
else
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].speed);
@@ -317,7 +314,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_MAXIMUM_TOTAL_SIZE:
pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
- *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
+ *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
retval = 0;
break;
@@ -332,7 +329,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
case OID_GEN_PHYSICAL_MEDIUM:
pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
- *outbuf = __constant_cpu_to_le32 (0);
+ *outbuf = cpu_to_le32 (0);
retval = 0;
break;
@@ -342,7 +339,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
*/
case OID_GEN_MAC_OPTIONS: /* from WinME */
pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__);
- *outbuf = __constant_cpu_to_le32(
+ *outbuf = cpu_to_le32(
NDIS_MAC_OPTION_RECEIVE_SERIALIZED
| NDIS_MAC_OPTION_FULL_DUPLEX);
retval = 0;
@@ -431,7 +428,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
case OID_802_3_MULTICAST_LIST:
pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
/* Multicast base address only */
- *outbuf = __constant_cpu_to_le32 (0xE0000000);
+ *outbuf = cpu_to_le32 (0xE0000000);
retval = 0;
break;
@@ -439,7 +436,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
case OID_802_3_MAXIMUM_LIST_SIZE:
pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
/* Multicast base address only */
- *outbuf = __constant_cpu_to_le32 (1);
+ *outbuf = cpu_to_le32 (1);
retval = 0;
break;
@@ -461,14 +458,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_XMIT_ONE_COLLISION:
pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
- *outbuf = __constant_cpu_to_le32 (0);
+ *outbuf = cpu_to_le32 (0);
retval = 0;
break;
/* mandatory */
case OID_802_3_XMIT_MORE_COLLISIONS:
pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
- *outbuf = __constant_cpu_to_le32 (0);
+ *outbuf = cpu_to_le32 (0);
retval = 0;
break;
@@ -572,24 +569,24 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
return -ENOMEM;
resp = (rndis_init_cmplt_type *) r->buf;
- resp->MessageType = __constant_cpu_to_le32 (
+ resp->MessageType = cpu_to_le32 (
REMOTE_NDIS_INITIALIZE_CMPLT);
- resp->MessageLength = __constant_cpu_to_le32 (52);
+ resp->MessageLength = cpu_to_le32 (52);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
- resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION);
- resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION);
- resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
- resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);
- resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);
+ resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->MajorVersion = cpu_to_le32 (RNDIS_MAJOR_VERSION);
+ resp->MinorVersion = cpu_to_le32 (RNDIS_MINOR_VERSION);
+ resp->DeviceFlags = cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
+ resp->Medium = cpu_to_le32 (RNDIS_MEDIUM_802_3);
+ resp->MaxPacketsPerTransfer = cpu_to_le32 (1);
resp->MaxTransferSize = cpu_to_le32 (
params->dev->mtu
+ sizeof (struct ethhdr)
+ sizeof (struct rndis_packet_msg_type)
+ 22);
- resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);
- resp->AFListOffset = __constant_cpu_to_le32 (0);
- resp->AFListSize = __constant_cpu_to_le32 (0);
+ resp->PacketAlignmentFactor = cpu_to_le32 (0);
+ resp->AFListOffset = cpu_to_le32 (0);
+ resp->AFListSize = cpu_to_le32 (0);
params->resp_avail(params->v);
return 0;
@@ -617,7 +614,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
return -ENOMEM;
resp = (rndis_query_cmplt_type *) r->buf;
- resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
+ resp->MessageType = cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID),
@@ -626,13 +623,13 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
le32_to_cpu(buf->InformationBufferLength),
r)) {
/* OID not supported */
- resp->Status = __constant_cpu_to_le32 (
+ resp->Status = cpu_to_le32 (
RNDIS_STATUS_NOT_SUPPORTED);
- resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp);
- resp->InformationBufferLength = __constant_cpu_to_le32 (0);
- resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
+ resp->MessageLength = cpu_to_le32 (sizeof *resp);
+ resp->InformationBufferLength = cpu_to_le32 (0);
+ resp->InformationBufferOffset = cpu_to_le32 (0);
} else
- resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
params->resp_avail(params->v);
return 0;
@@ -665,14 +662,14 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
pr_debug("\n");
#endif
- resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
- resp->MessageLength = __constant_cpu_to_le32 (16);
+ resp->MessageType = cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
+ resp->MessageLength = cpu_to_le32 (16);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID),
((u8 *) buf) + 8 + BufOffset, BufLength, r))
- resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
+ resp->Status = cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
else
- resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
params->resp_avail(params->v);
return 0;
@@ -689,11 +686,11 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
return -ENOMEM;
resp = (rndis_reset_cmplt_type *) r->buf;
- resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
- resp->MessageLength = __constant_cpu_to_le32 (16);
- resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->MessageType = cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
+ resp->MessageLength = cpu_to_le32 (16);
+ resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
/* resent information */
- resp->AddressingReset = __constant_cpu_to_le32 (1);
+ resp->AddressingReset = cpu_to_le32 (1);
params->resp_avail(params->v);
return 0;
@@ -713,11 +710,11 @@ static int rndis_keepalive_response (int configNr,
return -ENOMEM;
resp = (rndis_keepalive_cmplt_type *) r->buf;
- resp->MessageType = __constant_cpu_to_le32 (
+ resp->MessageType = cpu_to_le32 (
REMOTE_NDIS_KEEPALIVE_CMPLT);
- resp->MessageLength = __constant_cpu_to_le32 (16);
+ resp->MessageLength = cpu_to_le32 (16);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
params->resp_avail(params->v);
return 0;
@@ -742,12 +739,12 @@ static int rndis_indicate_status_msg (int configNr, u32 status)
return -ENOMEM;
resp = (rndis_indicate_status_msg_type *) r->buf;
- resp->MessageType = __constant_cpu_to_le32 (
+ resp->MessageType = cpu_to_le32 (
REMOTE_NDIS_INDICATE_STATUS_MSG);
- resp->MessageLength = __constant_cpu_to_le32 (20);
+ resp->MessageLength = cpu_to_le32 (20);
resp->Status = cpu_to_le32 (status);
- resp->StatusBufferLength = __constant_cpu_to_le32 (0);
- resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
+ resp->StatusBufferLength = cpu_to_le32 (0);
+ resp->StatusBufferOffset = cpu_to_le32 (0);
params->resp_avail(params->v);
return 0;
@@ -963,9 +960,9 @@ void rndis_add_hdr (struct sk_buff *skb)
return;
header = (void *) skb_push (skb, sizeof *header);
memset (header, 0, sizeof *header);
- header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
+ header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
header->MessageLength = cpu_to_le32(skb->len);
- header->DataOffset = __constant_cpu_to_le32 (36);
+ header->DataOffset = cpu_to_le32 (36);
header->DataLength = cpu_to_le32(skb->len - sizeof *header);
}
@@ -1029,7 +1026,7 @@ int rndis_rm_hdr(struct sk_buff *skb)
__le32 *tmp = (void *) skb->data;
/* MessageType, MessageLength */
- if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
+ if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
!= get_unaligned(tmp++))
return -EINVAL;
tmp++;
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 37879af1c43..f46a60962da 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -87,12 +87,12 @@ static struct usb_gadget_strings *dev_strings[] = {
static struct usb_device_descriptor device_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
/* .bDeviceClass = f(use_acm) */
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
/* .bMaxPacketSize0 = f(hardware) */
- .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID),
+ .idVendor = cpu_to_le16(GS_VENDOR_ID),
/* .idProduct = f(use_acm) */
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
@@ -216,7 +216,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
pr_warning("gs_bind: controller '%s' not recognized\n",
gadget->name);
device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099);
+ cpu_to_le16(GS_VERSION_NUM | 0x0099);
}
if (gadget_is_otg(cdev->gadget)) {
@@ -255,19 +255,19 @@ static int __init init(void)
serial_config_driver.bConfigurationValue = 2;
device_desc.bDeviceClass = USB_CLASS_COMM;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
+ cpu_to_le16(GS_CDC_PRODUCT_ID);
} else if (use_obex) {
serial_config_driver.label = "CDC OBEX config";
serial_config_driver.bConfigurationValue = 3;
device_desc.bDeviceClass = USB_CLASS_COMM;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
+ cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
} else {
serial_config_driver.label = "Generic Serial config";
serial_config_driver.bConfigurationValue = 1;
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_PRODUCT_ID);
+ cpu_to_le16(GS_PRODUCT_ID);
}
strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 53d59287f2b..0a4d99ab40d 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -1092,7 +1092,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count)
gs_tty_driver->init_termios.c_ispeed = 9600;
gs_tty_driver->init_termios.c_ospeed = 9600;
- coding.dwDTERate = __constant_cpu_to_le32(9600);
+ coding.dwDTERate = cpu_to_le32(9600);
coding.bCharFormat = 8;
coding.bParityType = USB_CDC_NO_PARITY;
coding.bDataBits = USB_CDC_1_STOP_BITS;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 361d9659ac4..2d772401b7a 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -102,22 +102,32 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
#ifndef CONFIG_USB_ZERO_HNPTEST
#define DRIVER_VENDOR_NUM 0x0525 /* NetChip */
#define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */
+#define DEFAULT_AUTORESUME 0
#else
#define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */
#define DRIVER_PRODUCT_NUM 0xbadd
+#define DEFAULT_AUTORESUME 5
#endif
+/* If the optional "autoresume" mode is enabled, it provides good
+ * functional coverage for the "USBCV" test harness from USB-IF.
+ * It's always set if OTG mode is enabled.
+ */
+unsigned autoresume = DEFAULT_AUTORESUME;
+module_param(autoresume, uint, S_IRUGO);
+MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
+
/*-------------------------------------------------------------------------*/
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_VENDOR_SPEC,
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.bNumConfigurations = 2,
};
@@ -212,6 +222,47 @@ void disable_endpoints(struct usb_composite_dev *cdev,
/*-------------------------------------------------------------------------*/
+static struct timer_list autoresume_timer;
+
+static void zero_autoresume(unsigned long _c)
+{
+ struct usb_composite_dev *cdev = (void *)_c;
+ struct usb_gadget *g = cdev->gadget;
+
+ /* unconfigured devices can't issue wakeups */
+ if (!cdev->config)
+ return;
+
+ /* Normally the host would be woken up for something
+ * more significant than just a timer firing; likely
+ * because of some direct user request.
+ */
+ if (g->speed != USB_SPEED_UNKNOWN) {
+ int status = usb_gadget_wakeup(g);
+ INFO(cdev, "%s --> %d\n", __func__, status);
+ }
+}
+
+static void zero_suspend(struct usb_composite_dev *cdev)
+{
+ if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
+ return;
+
+ if (autoresume) {
+ mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
+ DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
+ } else
+ DBG(cdev, "%s\n", __func__);
+}
+
+static void zero_resume(struct usb_composite_dev *cdev)
+{
+ DBG(cdev, "%s\n", __func__);
+ del_timer(&autoresume_timer);
+}
+
+/*-------------------------------------------------------------------------*/
+
static int __init zero_bind(struct usb_composite_dev *cdev)
{
int gcnum;
@@ -239,17 +290,19 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
strings_dev[STRING_SERIAL_IDX].id = id;
device_desc.iSerialNumber = id;
+ setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
+
/* Register primary, then secondary configuration. Note that
* SH3 only allows one config...
*/
if (loopdefault) {
- loopback_add(cdev);
+ loopback_add(cdev, autoresume != 0);
if (!gadget_is_sh(gadget))
- sourcesink_add(cdev);
+ sourcesink_add(cdev, autoresume != 0);
} else {
- sourcesink_add(cdev);
+ sourcesink_add(cdev, autoresume != 0);
if (!gadget_is_sh(gadget))
- loopback_add(cdev);
+ loopback_add(cdev, autoresume != 0);
}
gcnum = usb_gadget_controller_number(gadget);
@@ -265,7 +318,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
*/
pr_warning("%s: controller '%s' not recognized\n",
longname, gadget->name);
- device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+ device_desc.bcdDevice = cpu_to_le16(0x9999);
}
@@ -278,11 +331,20 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
return 0;
}
+static int zero_unbind(struct usb_composite_dev *cdev)
+{
+ del_timer_sync(&autoresume_timer);
+ return 0;
+}
+
static struct usb_composite_driver zero_driver = {
.name = "zero",
.dev = &device_desc,
.strings = dev_strings,
.bind = zero_bind,
+ .unbind = zero_unbind,
+ .suspend = zero_suspend,
+ .resume = zero_resume,
};
MODULE_AUTHOR("David Brownell");
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2b476b6b3d4..845479f7c70 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -24,10 +24,7 @@ config USB_EHCI_HCD
The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
"high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
If your USB host controller supports USB 2.0, you will likely want to
- configure this Host Controller Driver. At the time of this writing,
- the primary implementation of EHCI is a chip from NEC, widely available
- in add-on PCI cards, but implementations are in the works from other
- vendors including Intel and Philips. Motherboard support is appearing.
+ configure this Host Controller Driver.
EHCI controllers are packaged with "companion" host controllers (OHCI
or UHCI) to handle USB 1.1 devices connected to root hub ports. Ports
@@ -123,7 +120,7 @@ config USB_ISP116X_HCD
config USB_ISP1760_HCD
tristate "ISP 1760 HCD support"
- depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
+ depends on USB && EXPERIMENTAL
---help---
The ISP1760 chip is a USB 2.0 host controller.
@@ -140,6 +137,7 @@ config USB_OHCI_HCD
tristate "OHCI HCD support"
depends on USB && USB_ARCH_HAS_OHCI
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
+ select USB_OTG_UTILS if ARCH_OMAP
---help---
The Open Host Controller Interface (OHCI) is a standard for accessing
USB 1.1 host controller hardware. It does more in hardware than Intel's
@@ -238,6 +236,23 @@ config USB_UHCI_HCD
To compile this driver as a module, choose M here: the
module will be called uhci-hcd.
+config USB_FHCI_HCD
+ tristate "Freescale QE USB Host Controller support"
+ depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE
+ select FSL_GTM
+ select QE_USB
+ help
+ This driver enables support for Freescale QE USB Host Controller
+ (as found on MPC8360 and MPC8323 processors), the driver supports
+ Full and Low Speed USB.
+
+config FHCI_DEBUG
+ bool "Freescale QE USB Host Controller debug support"
+ depends on USB_FHCI_HCD && DEBUG_FS
+ help
+ Say "y" to see some FHCI debug information and statistics
+ throught debugfs.
+
config USB_U132_HCD
tristate "Elan U132 Adapter Host Controller"
depends on USB && USB_FTDI_ELAN
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index e5f3f20787e..f163571e33d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -7,6 +7,11 @@ ifeq ($(CONFIG_USB_DEBUG),y)
endif
isp1760-objs := isp1760-hcd.o isp1760-if.o
+fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \
+ fhci-tds.o fhci-sched.o
+ifeq ($(CONFIG_FHCI_DEBUG),y)
+fhci-objs += fhci-dbg.o
+endif
obj-$(CONFIG_USB_WHCI_HCD) += whci/
@@ -17,6 +22,7 @@ obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
+obj-$(CONFIG_USB_FHCI_HCD) += fhci.o
obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 4725d15d096..f2618d17710 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -110,6 +110,42 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
/*-------------------------------------------------------------------------*/
+static void
+timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
+{
+ /* Don't override timeouts which shrink or (later) disable
+ * the async ring; just the I/O watchdog. Note that if a
+ * SHRINK were pending, OFF would never be requested.
+ */
+ if (timer_pending(&ehci->watchdog)
+ && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
+ & ehci->actions))
+ return;
+
+ if (!test_and_set_bit(action, &ehci->actions)) {
+ unsigned long t;
+
+ switch (action) {
+ case TIMER_IO_WATCHDOG:
+ t = EHCI_IO_JIFFIES;
+ break;
+ case TIMER_ASYNC_OFF:
+ t = EHCI_ASYNC_JIFFIES;
+ break;
+ /* case TIMER_ASYNC_SHRINK: */
+ default:
+ /* add a jiffie since we synch against the
+ * 8 KHz uframe counter.
+ */
+ t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
+ break;
+ }
+ mod_timer(&ehci->watchdog, t + jiffies);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
/*
* handshake - spin reading hc until handshake completes or fails
* @ptr: address of hc register to be read
@@ -485,6 +521,7 @@ static int ehci_init(struct usb_hcd *hcd)
* periodic_size can shrink by USBCMD update if hcc_params allows.
*/
ehci->periodic_size = DEFAULT_I_TDPS;
+ INIT_LIST_HEAD(&ehci->cached_itd_list);
if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
return retval;
@@ -497,6 +534,7 @@ static int ehci_init(struct usb_hcd *hcd)
ehci->reclaim = NULL;
ehci->next_uframe = -1;
+ ehci->clock_frame = -1;
/*
* dedicate a qh for the async ring head, since we couldn't unlink
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 0431397836f..10d52919abb 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -128,6 +128,7 @@ static inline void qh_put (struct ehci_qh *qh)
static void ehci_mem_cleanup (struct ehci_hcd *ehci)
{
+ free_cached_itd_list(ehci);
if (ehci->async)
qh_put (ehci->async);
ehci->async = NULL;
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index bdc6e86e1f8..abb9a7706ec 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -230,7 +230,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
pci_read_config_word(pdev, 0x62, &port_wake);
if (port_wake & 0x0001) {
dev_warn(&pdev->dev, "Enabling legacy PCI PM\n");
- device_init_wakeup(&pdev->dev, 1);
+ device_set_wakeup_capable(&pdev->dev, 1);
}
}
@@ -432,8 +432,6 @@ static struct pci_driver ehci_pci_driver = {
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
- .suspend_late = usb_hcd_pci_suspend_late,
- .resume_early = usb_hcd_pci_resume_early,
.resume = usb_hcd_pci_resume,
#endif
.shutdown = usb_hcd_pci_shutdown,
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 3712b925b31..1976b1b3778 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -333,12 +333,40 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
token = hc32_to_cpu(ehci, qtd->hw_token);
/* always clean up qtds the hc de-activated */
+ retry_xacterr:
if ((token & QTD_STS_ACTIVE) == 0) {
/* on STALL, error, and short reads this urb must
* complete and all its qtds must be recycled.
*/
if ((token & QTD_STS_HALT) != 0) {
+
+ /* retry transaction errors until we
+ * reach the software xacterr limit
+ */
+ if ((token & QTD_STS_XACT) &&
+ QTD_CERR(token) == 0 &&
+ --qh->xacterrs > 0 &&
+ !urb->unlinked) {
+ ehci_dbg(ehci,
+ "detected XactErr len %zu/%zu retry %d\n",
+ qtd->length - QTD_LENGTH(token), qtd->length,
+ QH_XACTERR_MAX - qh->xacterrs);
+
+ /* reset the token in the qtd and the
+ * qh overlay (which still contains
+ * the qtd) so that we pick up from
+ * where we left off
+ */
+ token &= ~QTD_STS_HALT;
+ token |= QTD_STS_ACTIVE |
+ (EHCI_TUNE_CERR << 10);
+ qtd->hw_token = cpu_to_hc32(ehci,
+ token);
+ wmb();
+ qh->hw_token = cpu_to_hc32(ehci, token);
+ goto retry_xacterr;
+ }
stopped = 1;
/* magic dummy for some short reads; qh won't advance.
@@ -421,6 +449,9 @@ halt:
/* remove qtd; it's recycled after possible urb completion */
list_del (&qtd->qtd_list);
last = qtd;
+
+ /* reinit the xacterr counter for the next qtd */
+ qh->xacterrs = QH_XACTERR_MAX;
}
/* last urb's completion might still need calling */
@@ -862,6 +893,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
head->qh_next.qh = qh;
head->hw_next = dma;
+ qh->xacterrs = QH_XACTERR_MAX;
qh->qh_state = QH_STATE_LINKED;
/* qtd completions reported later by interrupt */
}
@@ -1095,7 +1127,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
prev->qh_next = qh->qh_next;
wmb ();
- if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) {
+ /* If the controller isn't running, we don't have to wait for it */
+ if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) {
/* if (unlikely (qh->reclaim != 0))
* this will recurse, probably not much
*/
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index a081ee65bde..ada5d2ba297 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -563,7 +563,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
// and this qh is active in the current uframe
// (and overlay token SplitXstate is false?)
// THEN
- // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */);
+ // qh->hw_info1 |= cpu_to_hc32(1 << 7 /* "ignore" */);
/* high bandwidth, or otherwise part of every microframe */
if ((period = qh->period) == 0)
@@ -1004,7 +1004,8 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
stream->bEndpointAddress &= 0x0f;
- stream->ep->hcpriv = NULL;
+ if (stream->ep)
+ stream->ep->hcpriv = NULL;
if (stream->rescheduled) {
ehci_info (ehci, "ep%d%s-iso rescheduled "
@@ -1535,7 +1536,7 @@ itd_link_urb (
struct ehci_itd, itd_list);
list_move_tail (&itd->itd_list, &stream->td_list);
itd->stream = iso_stream_get (stream);
- itd->urb = usb_get_urb (urb);
+ itd->urb = urb;
itd_init (ehci, stream, itd);
}
@@ -1644,7 +1645,7 @@ itd_complete (
(void) disable_periodic(ehci);
ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
- if (unlikely (list_empty (&stream->td_list))) {
+ if (unlikely(list_is_singular(&stream->td_list))) {
ehci_to_hcd(ehci)->self.bandwidth_allocated
-= stream->bandwidth;
ehci_vdbg (ehci,
@@ -1653,14 +1654,27 @@ itd_complete (
(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
}
iso_stream_put (ehci, stream);
- /* OK to recycle this ITD now that its completion callback ran. */
+
done:
- usb_put_urb(urb);
itd->urb = NULL;
- itd->stream = NULL;
- list_move(&itd->itd_list, &stream->free_list);
- iso_stream_put(ehci, stream);
-
+ if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
+ /* OK to recycle this ITD now. */
+ itd->stream = NULL;
+ list_move(&itd->itd_list, &stream->free_list);
+ iso_stream_put(ehci, stream);
+ } else {
+ /* HW might remember this ITD, so we can't recycle it yet.
+ * Move it to a safe place until a new frame starts.
+ */
+ list_move(&itd->itd_list, &ehci->cached_itd_list);
+ if (stream->refcount == 2) {
+ /* If iso_stream_put() were called here, stream
+ * would be freed. Instead, just prevent reuse.
+ */
+ stream->ep->hcpriv = NULL;
+ stream->ep = NULL;
+ }
+ }
return retval;
}
@@ -1934,7 +1948,7 @@ sitd_link_urb (
struct ehci_sitd, sitd_list);
list_move_tail (&sitd->sitd_list, &stream->td_list);
sitd->stream = iso_stream_get (stream);
- sitd->urb = usb_get_urb (urb);
+ sitd->urb = urb;
sitd_patch(ehci, stream, sitd, sched, packet);
sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size,
@@ -2019,7 +2033,7 @@ sitd_complete (
(void) disable_periodic(ehci);
ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
- if (list_empty (&stream->td_list)) {
+ if (list_is_singular(&stream->td_list)) {
ehci_to_hcd(ehci)->self.bandwidth_allocated
-= stream->bandwidth;
ehci_vdbg (ehci,
@@ -2030,7 +2044,6 @@ sitd_complete (
iso_stream_put (ehci, stream);
/* OK to recycle this SITD now that its completion callback ran. */
done:
- usb_put_urb(urb);
sitd->urb = NULL;
sitd->stream = NULL;
list_move(&sitd->sitd_list, &stream->free_list);
@@ -2101,6 +2114,20 @@ done:
/*-------------------------------------------------------------------------*/
+static void free_cached_itd_list(struct ehci_hcd *ehci)
+{
+ struct ehci_itd *itd, *n;
+
+ list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
+ struct ehci_iso_stream *stream = itd->stream;
+ itd->stream = NULL;
+ list_move(&itd->itd_list, &stream->free_list);
+ iso_stream_put(ehci, stream);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
static void
scan_periodic (struct ehci_hcd *ehci)
{
@@ -2115,10 +2142,17 @@ scan_periodic (struct ehci_hcd *ehci)
* Touches as few pages as possible: cache-friendly.
*/
now_uframe = ehci->next_uframe;
- if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
+ if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
clock = ehci_readl(ehci, &ehci->regs->frame_index);
- else
+ clock_frame = (clock >> 3) % ehci->periodic_size;
+ } else {
clock = now_uframe + mod - 1;
+ clock_frame = -1;
+ }
+ if (ehci->clock_frame != clock_frame) {
+ free_cached_itd_list(ehci);
+ ehci->clock_frame = clock_frame;
+ }
clock %= mod;
clock_frame = clock >> 3;
@@ -2277,6 +2311,10 @@ restart:
/* rescan the rest of this frame, then ... */
clock = now;
clock_frame = clock >> 3;
+ if (ehci->clock_frame != clock_frame) {
+ free_cached_itd_list(ehci);
+ ehci->clock_frame = clock_frame;
+ }
} else {
now_uframe++;
now_uframe %= mod;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index fb7054ccf4f..6cff195e1a3 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -87,6 +87,10 @@ struct ehci_hcd { /* one per controller */
int next_uframe; /* scan periodic, start here */
unsigned periodic_sched; /* periodic activity count */
+ /* list of itds completed while clock_frame was still active */
+ struct list_head cached_itd_list;
+ unsigned clock_frame;
+
/* per root hub port */
unsigned long reset_done [EHCI_MAX_ROOT_PORTS];
@@ -186,39 +190,7 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
clear_bit (action, &ehci->actions);
}
-static inline void
-timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
-{
- /* Don't override timeouts which shrink or (later) disable
- * the async ring; just the I/O watchdog. Note that if a
- * SHRINK were pending, OFF would never be requested.
- */
- if (timer_pending(&ehci->watchdog)
- && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
- & ehci->actions))
- return;
-
- if (!test_and_set_bit (action, &ehci->actions)) {
- unsigned long t;
-
- switch (action) {
- case TIMER_IO_WATCHDOG:
- t = EHCI_IO_JIFFIES;
- break;
- case TIMER_ASYNC_OFF:
- t = EHCI_ASYNC_JIFFIES;
- break;
- // case TIMER_ASYNC_SHRINK:
- default:
- /* add a jiffie since we synch against the
- * 8 KHz uframe counter.
- */
- t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
- break;
- }
- mod_timer(&ehci->watchdog, t + jiffies);
- }
-}
+static void free_cached_itd_list(struct ehci_hcd *ehci);
/*-------------------------------------------------------------------------*/
@@ -281,7 +253,7 @@ struct ehci_qtd {
/*
* Now the following defines are not converted using the
- * __constant_cpu_to_le32() macro anymore, since we have to support
+ * cpu_to_le32() macro anymore, since we have to support
* "dynamic" switching between be and le support, so that the driver
* can be used on one system with SoC EHCI controller using big-endian
* descriptors as well as a normal little-endian PCI EHCI controller.
@@ -370,6 +342,9 @@ struct ehci_qh {
#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */
#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */
+ u8 xacterrs; /* XactErr retry counter */
+#define QH_XACTERR_MAX 32 /* XactErr retry limit */
+
/* periodic schedule info */
u8 usecs; /* intr bandwidth */
u8 gap_uf; /* uframes split/csplit gap */
diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c
new file mode 100644
index 00000000000..ea8a4255c5d
--- /dev/null
+++ b/drivers/usb/host/fhci-dbg.c
@@ -0,0 +1,139 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er)
+{
+ int i;
+
+ if (usb_er == -1) {
+ fhci->usb_irq_stat[12]++;
+ return;
+ }
+
+ for (i = 0; i < 12; ++i) {
+ if (usb_er & (1 << i))
+ fhci->usb_irq_stat[i]++;
+ }
+}
+
+static int fhci_dfs_regs_show(struct seq_file *s, void *v)
+{
+ struct fhci_hcd *fhci = s->private;
+ struct fhci_regs __iomem *regs = fhci->regs;
+
+ seq_printf(s,
+ "mode: 0x%x\n" "addr: 0x%x\n"
+ "command: 0x%x\n" "ep0: 0x%x\n"
+ "event: 0x%x\n" "mask: 0x%x\n"
+ "status: 0x%x\n" "SOF timer: %d\n"
+ "frame number: %d\n"
+ "lines status: 0x%x\n",
+ in_8(&regs->usb_mod), in_8(&regs->usb_addr),
+ in_8(&regs->usb_comm), in_be16(&regs->usb_ep[0]),
+ in_be16(&regs->usb_event), in_be16(&regs->usb_mask),
+ in_8(&regs->usb_status), in_be16(&regs->usb_sof_tmr),
+ in_be16(&regs->usb_frame_num),
+ fhci_ioports_check_bus_state(fhci));
+
+ return 0;
+}
+
+static int fhci_dfs_irq_stat_show(struct seq_file *s, void *v)
+{
+ struct fhci_hcd *fhci = s->private;
+ int *usb_irq_stat = fhci->usb_irq_stat;
+
+ seq_printf(s,
+ "RXB: %d\n" "TXB: %d\n" "BSY: %d\n"
+ "SOF: %d\n" "TXE0: %d\n" "TXE1: %d\n"
+ "TXE2: %d\n" "TXE3: %d\n" "IDLE: %d\n"
+ "RESET: %d\n" "SFT: %d\n" "MSF: %d\n"
+ "IDLE_ONLY: %d\n",
+ usb_irq_stat[0], usb_irq_stat[1], usb_irq_stat[2],
+ usb_irq_stat[3], usb_irq_stat[4], usb_irq_stat[5],
+ usb_irq_stat[6], usb_irq_stat[7], usb_irq_stat[8],
+ usb_irq_stat[9], usb_irq_stat[10], usb_irq_stat[11],
+ usb_irq_stat[12]);
+
+ return 0;
+}
+
+static int fhci_dfs_regs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, fhci_dfs_regs_show, inode->i_private);
+}
+
+static int fhci_dfs_irq_stat_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, fhci_dfs_irq_stat_show, inode->i_private);
+}
+
+static const struct file_operations fhci_dfs_regs_fops = {
+ .open = fhci_dfs_regs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct file_operations fhci_dfs_irq_stat_fops = {
+ .open = fhci_dfs_irq_stat_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+void fhci_dfs_create(struct fhci_hcd *fhci)
+{
+ struct device *dev = fhci_to_hcd(fhci)->self.controller;
+
+ fhci->dfs_root = debugfs_create_dir(dev_name(dev), NULL);
+ if (!fhci->dfs_root) {
+ WARN_ON(1);
+ return;
+ }
+
+ fhci->dfs_regs = debugfs_create_file("regs", S_IFREG | S_IRUGO,
+ fhci->dfs_root, fhci, &fhci_dfs_regs_fops);
+
+ fhci->dfs_irq_stat = debugfs_create_file("irq_stat",
+ S_IFREG | S_IRUGO, fhci->dfs_root, fhci,
+ &fhci_dfs_irq_stat_fops);
+
+ WARN_ON(!fhci->dfs_regs || !fhci->dfs_irq_stat);
+}
+
+void fhci_dfs_destroy(struct fhci_hcd *fhci)
+{
+ if (!fhci->dfs_root)
+ return;
+
+ if (fhci->dfs_irq_stat)
+ debugfs_remove(fhci->dfs_irq_stat);
+
+ if (fhci->dfs_regs)
+ debugfs_remove(fhci->dfs_regs);
+
+ debugfs_remove(fhci->dfs_root);
+}
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
new file mode 100644
index 00000000000..0951818ef93
--- /dev/null
+++ b/drivers/usb/host/fhci-hcd.c
@@ -0,0 +1,836 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <asm/qe.h>
+#include <asm/fsl_gtm.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+void fhci_start_sof_timer(struct fhci_hcd *fhci)
+{
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ /* clear frame_n */
+ out_be16(&fhci->pram->frame_num, 0);
+
+ out_be16(&fhci->regs->usb_sof_tmr, 0);
+ setbits8(&fhci->regs->usb_mod, USB_MODE_SFTE);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+void fhci_stop_sof_timer(struct fhci_hcd *fhci)
+{
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ clrbits8(&fhci->regs->usb_mod, USB_MODE_SFTE);
+ gtm_stop_timer16(fhci->timer);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+u16 fhci_get_sof_timer_count(struct fhci_usb *usb)
+{
+ return be16_to_cpu(in_be16(&usb->fhci->regs->usb_sof_tmr) / 12);
+}
+
+/* initialize the endpoint zero */
+static u32 endpoint_zero_init(struct fhci_usb *usb,
+ enum fhci_mem_alloc data_mem,
+ u32 ring_len)
+{
+ u32 rc;
+
+ rc = fhci_create_ep(usb, data_mem, ring_len);
+ if (rc)
+ return rc;
+
+ /* inilialize endpoint registers */
+ fhci_init_ep_registers(usb, usb->ep0, data_mem);
+
+ return 0;
+}
+
+/* enable the USB interrupts */
+void fhci_usb_enable_interrupt(struct fhci_usb *usb)
+{
+ struct fhci_hcd *fhci = usb->fhci;
+
+ if (usb->intr_nesting_cnt == 1) {
+ /* initialize the USB interrupt */
+ enable_irq(fhci_to_hcd(fhci)->irq);
+
+ /* initialize the event register and mask register */
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+
+ /* enable the timer interrupts */
+ enable_irq(fhci->timer->irq);
+ } else if (usb->intr_nesting_cnt > 1)
+ fhci_info(fhci, "unbalanced USB interrupts nesting\n");
+ usb->intr_nesting_cnt--;
+}
+
+/* diable the usb interrupt */
+void fhci_usb_disable_interrupt(struct fhci_usb *usb)
+{
+ struct fhci_hcd *fhci = usb->fhci;
+
+ if (usb->intr_nesting_cnt == 0) {
+ /* diable the timer interrupt */
+ disable_irq_nosync(fhci->timer->irq);
+
+ /* disable the usb interrupt */
+ disable_irq_nosync(fhci_to_hcd(fhci)->irq);
+ out_be16(&usb->fhci->regs->usb_mask, 0);
+ }
+ usb->intr_nesting_cnt++;
+}
+
+/* enable the USB controller */
+static u32 fhci_usb_enable(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+ setbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+
+ mdelay(100);
+
+ return 0;
+}
+
+/* disable the USB controller */
+static u32 fhci_usb_disable(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ fhci_usb_disable_interrupt(usb);
+ fhci_port_disable(fhci);
+
+ /* disable the usb controller */
+ if (usb->port_status == FHCI_PORT_FULL ||
+ usb->port_status == FHCI_PORT_LOW)
+ fhci_device_disconnected_interrupt(fhci);
+
+ clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+
+ return 0;
+}
+
+/* check the bus state by polling the QE bit on the IO ports */
+int fhci_ioports_check_bus_state(struct fhci_hcd *fhci)
+{
+ u8 bits = 0;
+
+ /* check USBOE,if transmitting,exit */
+ if (!gpio_get_value(fhci->gpios[GPIO_USBOE]))
+ return -1;
+
+ /* check USBRP */
+ if (gpio_get_value(fhci->gpios[GPIO_USBRP]))
+ bits |= 0x2;
+
+ /* check USBRN */
+ if (gpio_get_value(fhci->gpios[GPIO_USBRN]))
+ bits |= 0x1;
+
+ return bits;
+}
+
+static void fhci_mem_free(struct fhci_hcd *fhci)
+{
+ struct ed *ed;
+ struct ed *next_ed;
+ struct td *td;
+ struct td *next_td;
+
+ list_for_each_entry_safe(ed, next_ed, &fhci->empty_eds, node) {
+ list_del(&ed->node);
+ kfree(ed);
+ }
+
+ list_for_each_entry_safe(td, next_td, &fhci->empty_tds, node) {
+ list_del(&td->node);
+ kfree(td);
+ }
+
+ kfree(fhci->vroot_hub);
+ fhci->vroot_hub = NULL;
+
+ kfree(fhci->hc_list);
+ fhci->hc_list = NULL;
+}
+
+static int fhci_mem_init(struct fhci_hcd *fhci)
+{
+ int i;
+
+ fhci->hc_list = kzalloc(sizeof(*fhci->hc_list), GFP_KERNEL);
+ if (!fhci->hc_list)
+ goto err;
+
+ INIT_LIST_HEAD(&fhci->hc_list->ctrl_list);
+ INIT_LIST_HEAD(&fhci->hc_list->bulk_list);
+ INIT_LIST_HEAD(&fhci->hc_list->iso_list);
+ INIT_LIST_HEAD(&fhci->hc_list->intr_list);
+ INIT_LIST_HEAD(&fhci->hc_list->done_list);
+
+ fhci->vroot_hub = kzalloc(sizeof(*fhci->vroot_hub), GFP_KERNEL);
+ if (!fhci->vroot_hub)
+ goto err;
+
+ INIT_LIST_HEAD(&fhci->empty_eds);
+ INIT_LIST_HEAD(&fhci->empty_tds);
+
+ /* initialize work queue to handle done list */
+ fhci_tasklet.data = (unsigned long)fhci;
+ fhci->process_done_task = &fhci_tasklet;
+
+ for (i = 0; i < MAX_TDS; i++) {
+ struct td *td;
+
+ td = kmalloc(sizeof(*td), GFP_KERNEL);
+ if (!td)
+ goto err;
+ fhci_recycle_empty_td(fhci, td);
+ }
+ for (i = 0; i < MAX_EDS; i++) {
+ struct ed *ed;
+
+ ed = kmalloc(sizeof(*ed), GFP_KERNEL);
+ if (!ed)
+ goto err;
+ fhci_recycle_empty_ed(fhci, ed);
+ }
+
+ fhci->active_urbs = 0;
+ return 0;
+err:
+ fhci_mem_free(fhci);
+ return -ENOMEM;
+}
+
+/* destroy the fhci_usb structure */
+static void fhci_usb_free(void *lld)
+{
+ struct fhci_usb *usb = lld;
+ struct fhci_hcd *fhci = usb->fhci;
+
+ if (usb) {
+ fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
+ fhci_ep0_free(usb);
+ kfree(usb->actual_frame);
+ kfree(usb);
+ }
+}
+
+/* initialize the USB */
+static int fhci_usb_init(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ memset_io(usb->fhci->pram, 0, FHCI_PRAM_SIZE);
+
+ usb->port_status = FHCI_PORT_DISABLED;
+ usb->max_frame_usage = FRAME_TIME_USAGE;
+ usb->sw_transaction_time = SW_FIX_TIME_BETWEEN_TRANSACTION;
+
+ usb->actual_frame = kzalloc(sizeof(*usb->actual_frame), GFP_KERNEL);
+ if (!usb->actual_frame) {
+ fhci_usb_free(usb);
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&usb->actual_frame->tds_list);
+
+ /* initializing registers on chip, clear frame number */
+ out_be16(&fhci->pram->frame_num, 0);
+
+ /* clear rx state */
+ out_be32(&fhci->pram->rx_state, 0);
+
+ /* set mask register */
+ usb->saved_msk = (USB_E_TXB_MASK |
+ USB_E_TXE1_MASK |
+ USB_E_IDLE_MASK |
+ USB_E_RESET_MASK | USB_E_SFT_MASK | USB_E_MSF_MASK);
+
+ out_8(&usb->fhci->regs->usb_mod, USB_MODE_HOST | USB_MODE_EN);
+
+ /* clearing the mask register */
+ out_be16(&usb->fhci->regs->usb_mask, 0);
+
+ /* initialing the event register */
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+
+ if (endpoint_zero_init(usb, DEFAULT_DATA_MEM, DEFAULT_RING_LEN) != 0) {
+ fhci_usb_free(usb);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* initialize the fhci_usb struct and the corresponding data staruct */
+static struct fhci_usb *fhci_create_lld(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb;
+
+ /* allocate memory for SCC data structure */
+ usb = kzalloc(sizeof(*usb), GFP_KERNEL);
+ if (!usb) {
+ fhci_err(fhci, "no memory for SCC data struct\n");
+ return NULL;
+ }
+
+ usb->fhci = fhci;
+ usb->hc_list = fhci->hc_list;
+ usb->vroot_hub = fhci->vroot_hub;
+
+ usb->transfer_confirm = fhci_transfer_confirm_callback;
+
+ return usb;
+}
+
+static int fhci_start(struct usb_hcd *hcd)
+{
+ int ret;
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+
+ ret = fhci_mem_init(fhci);
+ if (ret) {
+ fhci_err(fhci, "failed to allocate memory\n");
+ goto err;
+ }
+
+ fhci->usb_lld = fhci_create_lld(fhci);
+ if (!fhci->usb_lld) {
+ fhci_err(fhci, "low level driver config failed\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = fhci_usb_init(fhci);
+ if (ret) {
+ fhci_err(fhci, "low level driver initialize failed\n");
+ goto err;
+ }
+
+ spin_lock_init(&fhci->lock);
+
+ /* connect the virtual root hub */
+ fhci->vroot_hub->dev_num = 1; /* this field may be needed to fix */
+ fhci->vroot_hub->hub.wHubStatus = 0;
+ fhci->vroot_hub->hub.wHubChange = 0;
+ fhci->vroot_hub->port.wPortStatus = 0;
+ fhci->vroot_hub->port.wPortChange = 0;
+
+ hcd->state = HC_STATE_RUNNING;
+
+ /*
+ * From here on, khubd concurrently accesses the root
+ * hub; drivers will be talking to enumerated devices.
+ * (On restart paths, khubd already knows about the root
+ * hub and could find work as soon as we wrote FLAG_CF.)
+ *
+ * Before this point the HC was idle/ready. After, khubd
+ * and device drivers may start it running.
+ */
+ fhci_usb_enable(fhci);
+ return 0;
+err:
+ fhci_mem_free(fhci);
+ return ret;
+}
+
+static void fhci_stop(struct usb_hcd *hcd)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+
+ fhci_usb_disable_interrupt(fhci->usb_lld);
+ fhci_usb_disable(fhci);
+
+ fhci_usb_free(fhci->usb_lld);
+ fhci->usb_lld = NULL;
+ fhci_mem_free(fhci);
+}
+
+static int fhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ u32 pipe = urb->pipe;
+ int ret;
+ int i;
+ int size = 0;
+ struct urb_priv *urb_priv;
+ unsigned long flags;
+
+ switch (usb_pipetype(pipe)) {
+ case PIPE_CONTROL:
+ /* 1 td fro setup,1 for ack */
+ size = 2;
+ case PIPE_BULK:
+ /* one td for every 4096 bytes(can be upto 8k) */
+ size += urb->transfer_buffer_length / 4096;
+ /* ...add for any remaining bytes... */
+ if ((urb->transfer_buffer_length % 4096) != 0)
+ size++;
+ /* ..and maybe a zero length packet to wrap it up */
+ if (size == 0)
+ size++;
+ else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0
+ && (urb->transfer_buffer_length
+ % usb_maxpacket(urb->dev, pipe,
+ usb_pipeout(pipe))) != 0)
+ size++;
+ break;
+ case PIPE_ISOCHRONOUS:
+ size = urb->number_of_packets;
+ if (size <= 0)
+ return -EINVAL;
+ for (i = 0; i < urb->number_of_packets; i++) {
+ urb->iso_frame_desc[i].actual_length = 0;
+ urb->iso_frame_desc[i].status = (u32) (-EXDEV);
+ }
+ break;
+ case PIPE_INTERRUPT:
+ size = 1;
+ }
+
+ /* allocate the private part of the URB */
+ urb_priv = kzalloc(sizeof(*urb_priv), mem_flags);
+ if (!urb_priv)
+ return -ENOMEM;
+
+ /* allocate the private part of the URB */
+ urb_priv->tds = kzalloc(size * sizeof(struct td), mem_flags);
+ if (!urb_priv->tds) {
+ kfree(urb_priv);
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ ret = usb_hcd_link_urb_to_ep(hcd, urb);
+ if (ret)
+ goto err;
+
+ /* fill the private part of the URB */
+ urb_priv->num_of_tds = size;
+
+ urb->status = -EINPROGRESS;
+ urb->actual_length = 0;
+ urb->error_count = 0;
+ urb->hcpriv = urb_priv;
+
+ fhci_queue_urb(fhci, urb);
+err:
+ if (ret) {
+ kfree(urb_priv->tds);
+ kfree(urb_priv);
+ }
+ spin_unlock_irqrestore(&fhci->lock, flags);
+ return ret;
+}
+
+/* dequeue FHCI URB */
+static int fhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ struct fhci_usb *usb = fhci->usb_lld;
+ int ret = -EINVAL;
+ unsigned long flags;
+
+ if (!urb || !urb->dev || !urb->dev->bus)
+ goto out;
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (ret)
+ goto out2;
+
+ if (usb->port_status != FHCI_PORT_DISABLED) {
+ struct urb_priv *urb_priv;
+
+ /*
+ * flag the urb's data for deletion in some upcoming
+ * SF interrupt's delete list processing
+ */
+ urb_priv = urb->hcpriv;
+
+ if (!urb_priv || (urb_priv->state == URB_DEL))
+ goto out2;
+
+ urb_priv->state = URB_DEL;
+
+ /* already pending? */
+ urb_priv->ed->state = FHCI_ED_URB_DEL;
+ } else {
+ fhci_urb_complete_free(fhci, urb);
+ }
+
+out2:
+ spin_unlock_irqrestore(&fhci->lock, flags);
+out:
+ return ret;
+}
+
+static void fhci_endpoint_disable(struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep)
+{
+ struct fhci_hcd *fhci;
+ struct ed *ed;
+ unsigned long flags;
+
+ fhci = hcd_to_fhci(hcd);
+ spin_lock_irqsave(&fhci->lock, flags);
+ ed = ep->hcpriv;
+ if (ed) {
+ while (ed->td_head != NULL) {
+ struct td *td = fhci_remove_td_from_ed(ed);
+ fhci_urb_complete_free(fhci, td->urb);
+ }
+ fhci_recycle_empty_ed(fhci, ed);
+ ep->hcpriv = NULL;
+ }
+ spin_unlock_irqrestore(&fhci->lock, flags);
+}
+
+static int fhci_get_frame_number(struct usb_hcd *hcd)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+
+ return get_frame_num(fhci);
+}
+
+static const struct hc_driver fhci_driver = {
+ .description = "fsl,usb-fhci",
+ .product_desc = "FHCI HOST Controller",
+ .hcd_priv_size = sizeof(struct fhci_hcd),
+
+ /* generic hardware linkage */
+ .irq = fhci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+
+ /* basic lifecycle operation */
+ .start = fhci_start,
+ .stop = fhci_stop,
+
+ /* managing i/o requests and associated device resources */
+ .urb_enqueue = fhci_urb_enqueue,
+ .urb_dequeue = fhci_urb_dequeue,
+ .endpoint_disable = fhci_endpoint_disable,
+
+ /* scheduling support */
+ .get_frame_number = fhci_get_frame_number,
+
+ /* root hub support */
+ .hub_status_data = fhci_hub_status_data,
+ .hub_control = fhci_hub_control,
+};
+
+static int __devinit of_fhci_probe(struct of_device *ofdev,
+ const struct of_device_id *ofid)
+{
+ struct device *dev = &ofdev->dev;
+ struct device_node *node = ofdev->node;
+ struct usb_hcd *hcd;
+ struct fhci_hcd *fhci;
+ struct resource usb_regs;
+ unsigned long pram_addr;
+ unsigned int usb_irq;
+ const char *sprop;
+ const u32 *iprop;
+ int size;
+ int ret;
+ int i;
+ int j;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ sprop = of_get_property(node, "mode", NULL);
+ if (sprop && strcmp(sprop, "host"))
+ return -ENODEV;
+
+ hcd = usb_create_hcd(&fhci_driver, dev, dev_name(dev));
+ if (!hcd) {
+ dev_err(dev, "could not create hcd\n");
+ return -ENOMEM;
+ }
+
+ fhci = hcd_to_fhci(hcd);
+ hcd->self.controller = dev;
+ dev_set_drvdata(dev, hcd);
+
+ iprop = of_get_property(node, "hub-power-budget", &size);
+ if (iprop && size == sizeof(*iprop))
+ hcd->power_budget = *iprop;
+
+ /* FHCI registers. */
+ ret = of_address_to_resource(node, 0, &usb_regs);
+ if (ret) {
+ dev_err(dev, "could not get regs\n");
+ goto err_regs;
+ }
+
+ hcd->regs = ioremap(usb_regs.start, usb_regs.end - usb_regs.start + 1);
+ if (!hcd->regs) {
+ dev_err(dev, "could not ioremap regs\n");
+ ret = -ENOMEM;
+ goto err_regs;
+ }
+ fhci->regs = hcd->regs;
+
+ /* Parameter RAM. */
+ iprop = of_get_property(node, "reg", &size);
+ if (!iprop || size < sizeof(*iprop) * 4) {
+ dev_err(dev, "can't get pram offset\n");
+ ret = -EINVAL;
+ goto err_pram;
+ }
+
+ pram_addr = cpm_muram_alloc_fixed(iprop[2], FHCI_PRAM_SIZE);
+ if (IS_ERR_VALUE(pram_addr)) {
+ dev_err(dev, "failed to allocate usb pram\n");
+ ret = -ENOMEM;
+ goto err_pram;
+ }
+ fhci->pram = cpm_muram_addr(pram_addr);
+
+ /* GPIOs and pins */
+ for (i = 0; i < NUM_GPIOS; i++) {
+ int gpio;
+ enum of_gpio_flags flags;
+
+ gpio = of_get_gpio_flags(node, i, &flags);
+ fhci->gpios[i] = gpio;
+ fhci->alow_gpios[i] = flags & OF_GPIO_ACTIVE_LOW;
+
+ if (!gpio_is_valid(gpio)) {
+ if (i < GPIO_SPEED) {
+ dev_err(dev, "incorrect GPIO%d: %d\n",
+ i, gpio);
+ goto err_gpios;
+ } else {
+ dev_info(dev, "assuming board doesn't have "
+ "%s gpio\n", i == GPIO_SPEED ?
+ "speed" : "power");
+ continue;
+ }
+ }
+
+ ret = gpio_request(gpio, dev_name(dev));
+ if (ret) {
+ dev_err(dev, "failed to request gpio %d", i);
+ goto err_gpios;
+ }
+
+ if (i >= GPIO_SPEED) {
+ ret = gpio_direction_output(gpio, 0);
+ if (ret) {
+ dev_err(dev, "failed to set gpio %d as "
+ "an output\n", i);
+ i++;
+ goto err_gpios;
+ }
+ }
+ }
+
+ for (j = 0; j < NUM_PINS; j++) {
+ fhci->pins[j] = qe_pin_request(ofdev->node, j);
+ if (IS_ERR(fhci->pins[j])) {
+ ret = PTR_ERR(fhci->pins[j]);
+ dev_err(dev, "can't get pin %d: %d\n", j, ret);
+ goto err_pins;
+ }
+ }
+
+ /* Frame limit timer and its interrupt. */
+ fhci->timer = gtm_get_timer16();
+ if (IS_ERR(fhci->timer)) {
+ ret = PTR_ERR(fhci->timer);
+ dev_err(dev, "failed to request qe timer: %i", ret);
+ goto err_get_timer;
+ }
+
+ ret = request_irq(fhci->timer->irq, fhci_frame_limit_timer_irq,
+ IRQF_DISABLED, "qe timer (usb)", hcd);
+ if (ret) {
+ dev_err(dev, "failed to request timer irq");
+ goto err_timer_irq;
+ }
+
+ /* USB Host interrupt. */
+ usb_irq = irq_of_parse_and_map(node, 0);
+ if (usb_irq == NO_IRQ) {
+ dev_err(dev, "could not get usb irq\n");
+ ret = -EINVAL;
+ goto err_usb_irq;
+ }
+
+ /* Clocks. */
+ sprop = of_get_property(node, "fsl,fullspeed-clock", NULL);
+ if (sprop) {
+ fhci->fullspeed_clk = qe_clock_source(sprop);
+ if (fhci->fullspeed_clk == QE_CLK_DUMMY) {
+ dev_err(dev, "wrong fullspeed-clock\n");
+ ret = -EINVAL;
+ goto err_clocks;
+ }
+ }
+
+ sprop = of_get_property(node, "fsl,lowspeed-clock", NULL);
+ if (sprop) {
+ fhci->lowspeed_clk = qe_clock_source(sprop);
+ if (fhci->lowspeed_clk == QE_CLK_DUMMY) {
+ dev_err(dev, "wrong lowspeed-clock\n");
+ ret = -EINVAL;
+ goto err_clocks;
+ }
+ }
+
+ if (fhci->fullspeed_clk == QE_CLK_NONE &&
+ fhci->lowspeed_clk == QE_CLK_NONE) {
+ dev_err(dev, "no clocks specified\n");
+ ret = -EINVAL;
+ goto err_clocks;
+ }
+
+ dev_info(dev, "at 0x%p, irq %d\n", hcd->regs, usb_irq);
+
+ fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
+
+ /* Start with full-speed, if possible. */
+ if (fhci->fullspeed_clk != QE_CLK_NONE) {
+ fhci_config_transceiver(fhci, FHCI_PORT_FULL);
+ qe_usb_clock_set(fhci->fullspeed_clk, USB_CLOCK);
+ } else {
+ fhci_config_transceiver(fhci, FHCI_PORT_LOW);
+ qe_usb_clock_set(fhci->lowspeed_clk, USB_CLOCK >> 3);
+ }
+
+ /* Clear and disable any pending interrupts. */
+ out_be16(&fhci->regs->usb_event, 0xffff);
+ out_be16(&fhci->regs->usb_mask, 0);
+
+ ret = usb_add_hcd(hcd, usb_irq, IRQF_DISABLED);
+ if (ret < 0)
+ goto err_add_hcd;
+
+ fhci_dfs_create(fhci);
+
+ return 0;
+
+err_add_hcd:
+err_clocks:
+ irq_dispose_mapping(usb_irq);
+err_usb_irq:
+ free_irq(fhci->timer->irq, hcd);
+err_timer_irq:
+ gtm_put_timer16(fhci->timer);
+err_get_timer:
+err_pins:
+ while (--j >= 0)
+ qe_pin_free(fhci->pins[j]);
+err_gpios:
+ while (--i >= 0) {
+ if (gpio_is_valid(fhci->gpios[i]))
+ gpio_free(fhci->gpios[i]);
+ }
+ cpm_muram_free(pram_addr);
+err_pram:
+ iounmap(hcd->regs);
+err_regs:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int __devexit fhci_remove(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ int i;
+ int j;
+
+ usb_remove_hcd(hcd);
+ free_irq(fhci->timer->irq, hcd);
+ gtm_put_timer16(fhci->timer);
+ cpm_muram_free(cpm_muram_offset(fhci->pram));
+ for (i = 0; i < NUM_GPIOS; i++) {
+ if (!gpio_is_valid(fhci->gpios[i]))
+ continue;
+ gpio_free(fhci->gpios[i]);
+ }
+ for (j = 0; j < NUM_PINS; j++)
+ qe_pin_free(fhci->pins[j]);
+ fhci_dfs_destroy(fhci);
+ usb_put_hcd(hcd);
+ return 0;
+}
+
+static int __devexit of_fhci_remove(struct of_device *ofdev)
+{
+ return fhci_remove(&ofdev->dev);
+}
+
+static struct of_device_id of_fhci_match[] = {
+ { .compatible = "fsl,mpc8323-qe-usb", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_fhci_match);
+
+static struct of_platform_driver of_fhci_driver = {
+ .name = "fsl,usb-fhci",
+ .match_table = of_fhci_match,
+ .probe = of_fhci_probe,
+ .remove = __devexit_p(of_fhci_remove),
+};
+
+static int __init fhci_module_init(void)
+{
+ return of_register_platform_driver(&of_fhci_driver);
+}
+module_init(fhci_module_init);
+
+static void __exit fhci_module_exit(void)
+{
+ of_unregister_platform_driver(&of_fhci_driver);
+}
+module_exit(fhci_module_exit);
+
+MODULE_DESCRIPTION("USB Freescale Host Controller Interface Driver");
+MODULE_AUTHOR("Shlomi Gridish <gridish@freescale.com>, "
+ "Jerry Huang <Chang-Ming.Huang@freescale.com>, "
+ "Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/fhci-hub.c b/drivers/usb/host/fhci-hub.c
new file mode 100644
index 00000000000..0cfaedc3e12
--- /dev/null
+++ b/drivers/usb/host/fhci-hub.c
@@ -0,0 +1,345 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include <linux/gpio.h>
+#include <asm/qe.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+/* virtual root hub specific descriptor */
+static u8 root_hub_des[] = {
+ 0x09, /* blength */
+ 0x29, /* bDescriptorType;hub-descriptor */
+ 0x01, /* bNbrPorts */
+ 0x00, /* wHubCharacteristics */
+ 0x00,
+ 0x01, /* bPwrOn2pwrGood;2ms */
+ 0x00, /* bHubContrCurrent;0mA */
+ 0x00, /* DeviceRemoveable */
+ 0xff, /* PortPwrCtrlMask */
+};
+
+static void fhci_gpio_set_value(struct fhci_hcd *fhci, int gpio_nr, bool on)
+{
+ int gpio = fhci->gpios[gpio_nr];
+ bool alow = fhci->alow_gpios[gpio_nr];
+
+ if (!gpio_is_valid(gpio))
+ return;
+
+ gpio_set_value(gpio, on ^ alow);
+ mdelay(5);
+}
+
+void fhci_config_transceiver(struct fhci_hcd *fhci,
+ enum fhci_port_status status)
+{
+ fhci_dbg(fhci, "-> %s: %d\n", __func__, status);
+
+ switch (status) {
+ case FHCI_PORT_POWER_OFF:
+ fhci_gpio_set_value(fhci, GPIO_POWER, false);
+ break;
+ case FHCI_PORT_DISABLED:
+ case FHCI_PORT_WAITING:
+ fhci_gpio_set_value(fhci, GPIO_POWER, true);
+ break;
+ case FHCI_PORT_LOW:
+ fhci_gpio_set_value(fhci, GPIO_SPEED, false);
+ break;
+ case FHCI_PORT_FULL:
+ fhci_gpio_set_value(fhci, GPIO_SPEED, true);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+
+ fhci_dbg(fhci, "<- %s: %d\n", __func__, status);
+}
+
+/* disable the USB port by clearing the EN bit in the USBMOD register */
+void fhci_port_disable(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = (struct fhci_usb *)fhci->usb_lld;
+ enum fhci_port_status port_status;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_stop_sof_timer(fhci);
+
+ fhci_flush_all_transmissions(usb);
+
+ fhci_usb_disable_interrupt((struct fhci_usb *)fhci->usb_lld);
+ port_status = usb->port_status;
+ usb->port_status = FHCI_PORT_DISABLED;
+
+ /* Enable IDLE since we want to know if something comes along */
+ usb->saved_msk |= USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+
+ /* check if during the disconnection process attached new device */
+ if (port_status == FHCI_PORT_WAITING)
+ fhci_device_connected_interrupt(fhci);
+ usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_ENABLE;
+ usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE;
+ fhci_usb_enable_interrupt((struct fhci_usb *)fhci->usb_lld);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+/* enable the USB port by setting the EN bit in the USBMOD register */
+void fhci_port_enable(void *lld)
+{
+ struct fhci_usb *usb = (struct fhci_usb *)lld;
+ struct fhci_hcd *fhci = usb->fhci;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_config_transceiver(fhci, usb->port_status);
+
+ if ((usb->port_status != FHCI_PORT_FULL) &&
+ (usb->port_status != FHCI_PORT_LOW))
+ fhci_start_sof_timer(fhci);
+
+ usb->vroot_hub->port.wPortStatus |= USB_PORT_STAT_ENABLE;
+ usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE;
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+void fhci_io_port_generate_reset(struct fhci_hcd *fhci)
+{
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ gpio_direction_output(fhci->gpios[GPIO_USBOE], 0);
+ gpio_direction_output(fhci->gpios[GPIO_USBTP], 0);
+ gpio_direction_output(fhci->gpios[GPIO_USBTN], 0);
+
+ mdelay(5);
+
+ qe_pin_set_dedicated(fhci->pins[PIN_USBOE]);
+ qe_pin_set_dedicated(fhci->pins[PIN_USBTP]);
+ qe_pin_set_dedicated(fhci->pins[PIN_USBTN]);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+/* generate the RESET condition on the bus */
+void fhci_port_reset(void *lld)
+{
+ struct fhci_usb *usb = (struct fhci_usb *)lld;
+ struct fhci_hcd *fhci = usb->fhci;
+ u8 mode;
+ u16 mask;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_stop_sof_timer(fhci);
+ /* disable the USB controller */
+ mode = in_8(&fhci->regs->usb_mod);
+ out_8(&fhci->regs->usb_mod, mode & (~USB_MODE_EN));
+
+ /* disable idle interrupts */
+ mask = in_be16(&fhci->regs->usb_mask);
+ out_be16(&fhci->regs->usb_mask, mask & (~USB_E_IDLE_MASK));
+
+ fhci_io_port_generate_reset(fhci);
+
+ /* enable interrupt on this endpoint */
+ out_be16(&fhci->regs->usb_mask, mask);
+
+ /* enable the USB controller */
+ mode = in_8(&fhci->regs->usb_mod);
+ out_8(&fhci->regs->usb_mod, mode | USB_MODE_EN);
+ fhci_start_sof_timer(fhci);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+int fhci_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ int ret = 0;
+ unsigned long flags;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ if (fhci->vroot_hub->port.wPortChange & (USB_PORT_STAT_C_CONNECTION |
+ USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_SUSPEND |
+ USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_OVERCURRENT)) {
+ *buf = 1 << 1;
+ ret = 1;
+ fhci_dbg(fhci, "-- %s\n", __func__);
+ }
+
+ spin_unlock_irqrestore(&fhci->lock, flags);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+
+ return ret;
+}
+
+int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ u16 wIndex, char *buf, u16 wLength)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ int retval = 0;
+ int len = 0;
+ struct usb_hub_status *hub_status;
+ struct usb_port_status *port_status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ switch (typeReq) {
+ case ClearHubFeature:
+ switch (wValue) {
+ case C_HUB_LOCAL_POWER:
+ case C_HUB_OVER_CURRENT:
+ break;
+ default:
+ goto error;
+ }
+ break;
+ case ClearPortFeature:
+ fhci->vroot_hub->feature &= (1 << wValue);
+
+ switch (wValue) {
+ case USB_PORT_FEAT_ENABLE:
+ fhci->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_ENABLE;
+ fhci_port_disable(fhci);
+ break;
+ case USB_PORT_FEAT_C_ENABLE:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_ENABLE;
+ break;
+ case USB_PORT_FEAT_SUSPEND:
+ fhci->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_SUSPEND;
+ fhci_stop_sof_timer(fhci);
+ break;
+ case USB_PORT_FEAT_C_SUSPEND:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_SUSPEND;
+ break;
+ case USB_PORT_FEAT_POWER:
+ fhci->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_POWER;
+ fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
+ break;
+ case USB_PORT_FEAT_C_CONNECTION:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_CONNECTION;
+ break;
+ case USB_PORT_FEAT_C_OVER_CURRENT:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_OVERCURRENT;
+ break;
+ case USB_PORT_FEAT_C_RESET:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_RESET;
+ break;
+ default:
+ goto error;
+ }
+ break;
+ case GetHubDescriptor:
+ memcpy(buf, root_hub_des, sizeof(root_hub_des));
+ buf[3] = 0x11; /* per-port power, no ovrcrnt */
+ len = (buf[0] < wLength) ? buf[0] : wLength;
+ break;
+ case GetHubStatus:
+ hub_status = (struct usb_hub_status *)buf;
+ hub_status->wHubStatus =
+ cpu_to_le16(fhci->vroot_hub->hub.wHubStatus);
+ hub_status->wHubChange =
+ cpu_to_le16(fhci->vroot_hub->hub.wHubChange);
+ len = 4;
+ break;
+ case GetPortStatus:
+ port_status = (struct usb_port_status *)buf;
+ port_status->wPortStatus =
+ cpu_to_le16(fhci->vroot_hub->port.wPortStatus);
+ port_status->wPortChange =
+ cpu_to_le16(fhci->vroot_hub->port.wPortChange);
+ len = 4;
+ break;
+ case SetHubFeature:
+ switch (wValue) {
+ case C_HUB_OVER_CURRENT:
+ case C_HUB_LOCAL_POWER:
+ break;
+ default:
+ goto error;
+ }
+ break;
+ case SetPortFeature:
+ fhci->vroot_hub->feature |= (1 << wValue);
+
+ switch (wValue) {
+ case USB_PORT_FEAT_ENABLE:
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_ENABLE;
+ fhci_port_enable(fhci->usb_lld);
+ break;
+ case USB_PORT_FEAT_SUSPEND:
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_SUSPEND;
+ fhci_stop_sof_timer(fhci);
+ break;
+ case USB_PORT_FEAT_RESET:
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_RESET;
+ fhci_port_reset(fhci->usb_lld);
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_ENABLE;
+ fhci->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_RESET;
+ break;
+ case USB_PORT_FEAT_POWER:
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_POWER;
+ fhci_config_transceiver(fhci, FHCI_PORT_WAITING);
+ break;
+ default:
+ goto error;
+ }
+ break;
+ default:
+error:
+ retval = -EPIPE;
+ }
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+
+ spin_unlock_irqrestore(&fhci->lock, flags);
+
+ return retval;
+}
diff --git a/drivers/usb/host/fhci-mem.c b/drivers/usb/host/fhci-mem.c
new file mode 100644
index 00000000000..2c0736c9971
--- /dev/null
+++ b/drivers/usb/host/fhci-mem.c
@@ -0,0 +1,113 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+static void init_td(struct td *td)
+{
+ memset(td, 0, sizeof(*td));
+ INIT_LIST_HEAD(&td->node);
+ INIT_LIST_HEAD(&td->frame_lh);
+}
+
+static void init_ed(struct ed *ed)
+{
+ memset(ed, 0, sizeof(*ed));
+ INIT_LIST_HEAD(&ed->td_list);
+ INIT_LIST_HEAD(&ed->node);
+}
+
+static struct td *get_empty_td(struct fhci_hcd *fhci)
+{
+ struct td *td;
+
+ if (!list_empty(&fhci->empty_tds)) {
+ td = list_entry(fhci->empty_tds.next, struct td, node);
+ list_del(fhci->empty_tds.next);
+ } else {
+ td = kmalloc(sizeof(*td), GFP_ATOMIC);
+ if (!td)
+ fhci_err(fhci, "No memory to allocate to TD\n");
+ else
+ init_td(td);
+ }
+
+ return td;
+}
+
+void fhci_recycle_empty_td(struct fhci_hcd *fhci, struct td *td)
+{
+ init_td(td);
+ list_add(&td->node, &fhci->empty_tds);
+}
+
+struct ed *fhci_get_empty_ed(struct fhci_hcd *fhci)
+{
+ struct ed *ed;
+
+ if (!list_empty(&fhci->empty_eds)) {
+ ed = list_entry(fhci->empty_eds.next, struct ed, node);
+ list_del(fhci->empty_eds.next);
+ } else {
+ ed = kmalloc(sizeof(*ed), GFP_ATOMIC);
+ if (!ed)
+ fhci_err(fhci, "No memory to allocate to ED\n");
+ else
+ init_ed(ed);
+ }
+
+ return ed;
+}
+
+void fhci_recycle_empty_ed(struct fhci_hcd *fhci, struct ed *ed)
+{
+ init_ed(ed);
+ list_add(&ed->node, &fhci->empty_eds);
+}
+
+struct td *fhci_td_fill(struct fhci_hcd *fhci, struct urb *urb,
+ struct urb_priv *urb_priv, struct ed *ed, u16 index,
+ enum fhci_ta_type type, int toggle, u8 *data, u32 len,
+ u16 interval, u16 start_frame, bool ioc)
+{
+ struct td *td = get_empty_td(fhci);
+
+ if (!td)
+ return NULL;
+
+ td->urb = urb;
+ td->ed = ed;
+ td->type = type;
+ td->toggle = toggle;
+ td->data = data;
+ td->len = len;
+ td->iso_index = index;
+ td->interval = interval;
+ td->start_frame = start_frame;
+ td->ioc = ioc;
+ td->status = USB_TD_OK;
+
+ urb_priv->tds[index] = td;
+
+ return td;
+}
diff --git a/drivers/usb/host/fhci-q.c b/drivers/usb/host/fhci-q.c
new file mode 100644
index 00000000000..b0a1446ba29
--- /dev/null
+++ b/drivers/usb/host/fhci-q.c
@@ -0,0 +1,284 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+/* maps the hardware error code to the USB error code */
+static int status_to_error(u32 status)
+{
+ if (status == USB_TD_OK)
+ return 0;
+ else if (status & USB_TD_RX_ER_CRC)
+ return -EILSEQ;
+ else if (status & USB_TD_RX_ER_NONOCT)
+ return -EPROTO;
+ else if (status & USB_TD_RX_ER_OVERUN)
+ return -ECOMM;
+ else if (status & USB_TD_RX_ER_BITSTUFF)
+ return -EPROTO;
+ else if (status & USB_TD_RX_ER_PID)
+ return -EILSEQ;
+ else if (status & (USB_TD_TX_ER_NAK | USB_TD_TX_ER_TIMEOUT))
+ return -ETIMEDOUT;
+ else if (status & USB_TD_TX_ER_STALL)
+ return -EPIPE;
+ else if (status & USB_TD_TX_ER_UNDERUN)
+ return -ENOSR;
+ else if (status & USB_TD_RX_DATA_UNDERUN)
+ return -EREMOTEIO;
+ else if (status & USB_TD_RX_DATA_OVERUN)
+ return -EOVERFLOW;
+ else
+ return -EINVAL;
+}
+
+void fhci_add_td_to_frame(struct fhci_time_frame *frame, struct td *td)
+{
+ list_add_tail(&td->frame_lh, &frame->tds_list);
+}
+
+void fhci_add_tds_to_ed(struct ed *ed, struct td **td_list, int number)
+{
+ int i;
+
+ for (i = 0; i < number; i++) {
+ struct td *td = td_list[i];
+ list_add_tail(&td->node, &ed->td_list);
+ }
+ if (ed->td_head == NULL)
+ ed->td_head = td_list[0];
+}
+
+static struct td *peek_td_from_ed(struct ed *ed)
+{
+ struct td *td;
+
+ if (!list_empty(&ed->td_list))
+ td = list_entry(ed->td_list.next, struct td, node);
+ else
+ td = NULL;
+
+ return td;
+}
+
+struct td *fhci_remove_td_from_frame(struct fhci_time_frame *frame)
+{
+ struct td *td;
+
+ if (!list_empty(&frame->tds_list)) {
+ td = list_entry(frame->tds_list.next, struct td, frame_lh);
+ list_del_init(frame->tds_list.next);
+ } else
+ td = NULL;
+
+ return td;
+}
+
+struct td *fhci_peek_td_from_frame(struct fhci_time_frame *frame)
+{
+ struct td *td;
+
+ if (!list_empty(&frame->tds_list))
+ td = list_entry(frame->tds_list.next, struct td, frame_lh);
+ else
+ td = NULL;
+
+ return td;
+}
+
+struct td *fhci_remove_td_from_ed(struct ed *ed)
+{
+ struct td *td;
+
+ if (!list_empty(&ed->td_list)) {
+ td = list_entry(ed->td_list.next, struct td, node);
+ list_del_init(ed->td_list.next);
+
+ /* if this TD was the ED's head, find next TD */
+ if (!list_empty(&ed->td_list))
+ ed->td_head = list_entry(ed->td_list.next, struct td,
+ node);
+ else
+ ed->td_head = NULL;
+ } else
+ td = NULL;
+
+ return td;
+}
+
+struct td *fhci_remove_td_from_done_list(struct fhci_controller_list *p_list)
+{
+ struct td *td;
+
+ if (!list_empty(&p_list->done_list)) {
+ td = list_entry(p_list->done_list.next, struct td, node);
+ list_del_init(p_list->done_list.next);
+ } else
+ td = NULL;
+
+ return td;
+}
+
+void fhci_move_td_from_ed_to_done_list(struct fhci_usb *usb, struct ed *ed)
+{
+ struct td *td;
+
+ td = ed->td_head;
+ list_del_init(&td->node);
+
+ /* If this TD was the ED's head,find next TD */
+ if (!list_empty(&ed->td_list))
+ ed->td_head = list_entry(ed->td_list.next, struct td, node);
+ else {
+ ed->td_head = NULL;
+ ed->state = FHCI_ED_SKIP;
+ }
+ ed->toggle_carry = td->toggle;
+ list_add_tail(&td->node, &usb->hc_list->done_list);
+ if (td->ioc)
+ usb->transfer_confirm(usb->fhci);
+}
+
+/* free done FHCI URB resource such as ED and TD */
+static void free_urb_priv(struct fhci_hcd *fhci, struct urb *urb)
+{
+ int i;
+ struct urb_priv *urb_priv = urb->hcpriv;
+ struct ed *ed = urb_priv->ed;
+
+ for (i = 0; i < urb_priv->num_of_tds; i++) {
+ list_del_init(&urb_priv->tds[i]->node);
+ fhci_recycle_empty_td(fhci, urb_priv->tds[i]);
+ }
+
+ /* if this TD was the ED's head,find the next TD */
+ if (!list_empty(&ed->td_list))
+ ed->td_head = list_entry(ed->td_list.next, struct td, node);
+ else
+ ed->td_head = NULL;
+
+ kfree(urb_priv->tds);
+ kfree(urb_priv);
+ urb->hcpriv = NULL;
+
+ /* if this TD was the ED's head,find next TD */
+ if (ed->td_head == NULL)
+ list_del_init(&ed->node);
+ fhci->active_urbs--;
+}
+
+/* this routine called to complete and free done URB */
+void fhci_urb_complete_free(struct fhci_hcd *fhci, struct urb *urb)
+{
+ free_urb_priv(fhci, urb);
+
+ if (urb->status == -EINPROGRESS) {
+ if (urb->actual_length != urb->transfer_buffer_length &&
+ urb->transfer_flags & URB_SHORT_NOT_OK)
+ urb->status = -EREMOTEIO;
+ else
+ urb->status = 0;
+ }
+
+ usb_hcd_unlink_urb_from_ep(fhci_to_hcd(fhci), urb);
+
+ spin_unlock(&fhci->lock);
+
+ usb_hcd_giveback_urb(fhci_to_hcd(fhci), urb, urb->status);
+
+ spin_lock(&fhci->lock);
+}
+
+/*
+ * caculate transfer length/stats and update the urb
+ * Precondition: irqsafe(only for urb-?status locking)
+ */
+void fhci_done_td(struct urb *urb, struct td *td)
+{
+ struct ed *ed = td->ed;
+ u32 cc = td->status;
+
+ /* ISO...drivers see per-TD length/status */
+ if (ed->mode == FHCI_TF_ISO) {
+ u32 len;
+ if (!(urb->transfer_flags & URB_SHORT_NOT_OK &&
+ cc == USB_TD_RX_DATA_UNDERUN))
+ cc = USB_TD_OK;
+
+ if (usb_pipeout(urb->pipe))
+ len = urb->iso_frame_desc[td->iso_index].length;
+ else
+ len = td->actual_len;
+
+ urb->actual_length += len;
+ urb->iso_frame_desc[td->iso_index].actual_length = len;
+ urb->iso_frame_desc[td->iso_index].status =
+ status_to_error(cc);
+ }
+
+ /* BULK,INT,CONTROL... drivers see aggregate length/status,
+ * except that "setup" bytes aren't counted and "short" transfers
+ * might not be reported as errors.
+ */
+ else {
+ if (td->error_cnt >= 3)
+ urb->error_count = 3;
+
+ /* control endpoint only have soft stalls */
+
+ /* update packet status if needed(short may be ok) */
+ if (!(urb->transfer_flags & URB_SHORT_NOT_OK) &&
+ cc == USB_TD_RX_DATA_UNDERUN) {
+ ed->state = FHCI_ED_OPER;
+ cc = USB_TD_OK;
+ }
+ if (cc != USB_TD_OK) {
+ if (urb->status == -EINPROGRESS)
+ urb->status = status_to_error(cc);
+ }
+
+ /* count all non-empty packets except control SETUP packet */
+ if (td->type != FHCI_TA_SETUP || td->iso_index != 0)
+ urb->actual_length += td->actual_len;
+ }
+}
+
+/* there are some pedning request to unlink */
+void fhci_del_ed_list(struct fhci_hcd *fhci, struct ed *ed)
+{
+ struct td *td = peek_td_from_ed(ed);
+ struct urb *urb = td->urb;
+ struct urb_priv *urb_priv = urb->hcpriv;
+
+ if (urb_priv->state == URB_DEL) {
+ td = fhci_remove_td_from_ed(ed);
+ /* HC may have partly processed this TD */
+ if (td->status != USB_TD_INPROGRESS)
+ fhci_done_td(urb, td);
+
+ /* URB is done;clean up */
+ if (++(urb_priv->tds_cnt) == urb_priv->num_of_tds)
+ fhci_urb_complete_free(fhci, urb);
+ }
+}
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c
new file mode 100644
index 00000000000..bb63b68ddb7
--- /dev/null
+++ b/drivers/usb/host/fhci-sched.c
@@ -0,0 +1,888 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include <asm/qe.h>
+#include <asm/fsl_gtm.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+static void recycle_frame(struct fhci_usb *usb, struct packet *pkt)
+{
+ pkt->data = NULL;
+ pkt->len = 0;
+ pkt->status = USB_TD_OK;
+ pkt->info = 0;
+ pkt->priv_data = NULL;
+
+ cq_put(usb->ep0->empty_frame_Q, pkt);
+}
+
+/* confirm submitted packet */
+void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt)
+{
+ struct td *td;
+ struct packet *td_pkt;
+ struct ed *ed;
+ u32 trans_len;
+ bool td_done = false;
+
+ td = fhci_remove_td_from_frame(usb->actual_frame);
+ td_pkt = td->pkt;
+ trans_len = pkt->len;
+ td->status = pkt->status;
+ if (td->type == FHCI_TA_IN && td_pkt->info & PKT_DUMMY_PACKET) {
+ if ((td->data + td->actual_len) && trans_len)
+ memcpy(td->data + td->actual_len, pkt->data,
+ trans_len);
+ cq_put(usb->ep0->dummy_packets_Q, pkt->data);
+ }
+
+ recycle_frame(usb, pkt);
+
+ ed = td->ed;
+ if (ed->mode == FHCI_TF_ISO) {
+ if (ed->td_list.next->next != &ed->td_list) {
+ struct td *td_next =
+ list_entry(ed->td_list.next->next, struct td,
+ node);
+
+ td_next->start_frame = usb->actual_frame->frame_num;
+ }
+ td->actual_len = trans_len;
+ td_done = true;
+ } else if ((td->status & USB_TD_ERROR) &&
+ !(td->status & USB_TD_TX_ER_NAK)) {
+ /*
+ * There was an error on the transaction (but not NAK).
+ * If it is fatal error (data underrun, stall, bad pid or 3
+ * errors exceeded), mark this TD as done.
+ */
+ if ((td->status & USB_TD_RX_DATA_UNDERUN) ||
+ (td->status & USB_TD_TX_ER_STALL) ||
+ (td->status & USB_TD_RX_ER_PID) ||
+ (++td->error_cnt >= 3)) {
+ ed->state = FHCI_ED_HALTED;
+ td_done = true;
+
+ if (td->status & USB_TD_RX_DATA_UNDERUN) {
+ fhci_dbg(usb->fhci, "td err fu\n");
+ td->toggle = !td->toggle;
+ td->actual_len += trans_len;
+ } else {
+ fhci_dbg(usb->fhci, "td err f!u\n");
+ }
+ } else {
+ fhci_dbg(usb->fhci, "td err !f\n");
+ /* it is not a fatal error -retry this transaction */
+ td->nak_cnt = 0;
+ td->error_cnt++;
+ td->status = USB_TD_OK;
+ }
+ } else if (td->status & USB_TD_TX_ER_NAK) {
+ /* there was a NAK response */
+ fhci_vdbg(usb->fhci, "td nack\n");
+ td->nak_cnt++;
+ td->error_cnt = 0;
+ td->status = USB_TD_OK;
+ } else {
+ /* there was no error on transaction */
+ td->error_cnt = 0;
+ td->nak_cnt = 0;
+ td->toggle = !td->toggle;
+ td->actual_len += trans_len;
+
+ if (td->len == td->actual_len)
+ td_done = true;
+ }
+
+ if (td_done)
+ fhci_move_td_from_ed_to_done_list(usb, ed);
+}
+
+/*
+ * Flush all transmitted packets from BDs
+ * This routine is called when disabling the USB port to flush all
+ * transmissions that are allready scheduled in the BDs
+ */
+void fhci_flush_all_transmissions(struct fhci_usb *usb)
+{
+ u8 mode;
+ struct td *td;
+
+ mode = in_8(&usb->fhci->regs->usb_mod);
+ clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+
+ fhci_flush_bds(usb);
+
+ while ((td = fhci_peek_td_from_frame(usb->actual_frame)) != NULL) {
+ struct packet *pkt = td->pkt;
+
+ pkt->status = USB_TD_TX_ER_TIMEOUT;
+ fhci_transaction_confirm(usb, pkt);
+ }
+
+ usb->actual_frame->frame_status = FRAME_END_TRANSMISSION;
+
+ /* reset the event register */
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+ /* enable the USB controller */
+ out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN);
+}
+
+/*
+ * This function forms the packet and transmit the packet. This function
+ * will handle all endpoint type:ISO,interrupt,control and bulk
+ */
+static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td)
+{
+ u32 fw_transaction_time, len = 0;
+ struct packet *pkt;
+ u8 *data = NULL;
+
+ /* calcalate data address,len and toggle and then add the transaction */
+ if (td->toggle == USB_TD_TOGGLE_CARRY)
+ td->toggle = ed->toggle_carry;
+
+ switch (ed->mode) {
+ case FHCI_TF_ISO:
+ len = td->len;
+ if (td->type != FHCI_TA_IN)
+ data = td->data;
+ break;
+ case FHCI_TF_CTRL:
+ case FHCI_TF_BULK:
+ len = min(td->len - td->actual_len, ed->max_pkt_size);
+ if (!((td->type == FHCI_TA_IN) &&
+ ((len + td->actual_len) == td->len)))
+ data = td->data + td->actual_len;
+ break;
+ case FHCI_TF_INTR:
+ len = min(td->len, ed->max_pkt_size);
+ if (!((td->type == FHCI_TA_IN) &&
+ ((td->len + CRC_SIZE) >= ed->max_pkt_size)))
+ data = td->data;
+ break;
+ default:
+ break;
+ }
+
+ if (usb->port_status == FHCI_PORT_FULL)
+ fw_transaction_time = (((len + PROTOCOL_OVERHEAD) * 11) >> 4);
+ else
+ fw_transaction_time = ((len + PROTOCOL_OVERHEAD) * 6);
+
+ /* check if there's enough space in this frame to submit this TD */
+ if (usb->actual_frame->total_bytes + len + PROTOCOL_OVERHEAD >=
+ usb->max_bytes_per_frame) {
+ fhci_vdbg(usb->fhci, "not enough space in this frame: "
+ "%d %d %d\n", usb->actual_frame->total_bytes, len,
+ usb->max_bytes_per_frame);
+ return -1;
+ }
+
+ /* check if there's enough time in this frame to submit this TD */
+ if (usb->actual_frame->frame_status != FRAME_IS_PREPARED &&
+ (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION ||
+ (fw_transaction_time + usb->sw_transaction_time >=
+ 1000 - fhci_get_sof_timer_count(usb)))) {
+ fhci_dbg(usb->fhci, "not enough time in this frame\n");
+ return -1;
+ }
+
+ /* update frame object fields before transmitting */
+ pkt = cq_get(usb->ep0->empty_frame_Q);
+ if (!pkt) {
+ fhci_dbg(usb->fhci, "there is no empty frame\n");
+ return -1;
+ }
+ td->pkt = pkt;
+
+ pkt->info = 0;
+ if (data == NULL) {
+ data = cq_get(usb->ep0->dummy_packets_Q);
+ BUG_ON(!data);
+ pkt->info = PKT_DUMMY_PACKET;
+ }
+ pkt->data = data;
+ pkt->len = len;
+ pkt->status = USB_TD_OK;
+ /* update TD status field before transmitting */
+ td->status = USB_TD_INPROGRESS;
+ /* update actual frame time object with the actual transmission */
+ usb->actual_frame->total_bytes += (len + PROTOCOL_OVERHEAD);
+ fhci_add_td_to_frame(usb->actual_frame, td);
+
+ if (usb->port_status != FHCI_PORT_FULL &&
+ usb->port_status != FHCI_PORT_LOW) {
+ pkt->status = USB_TD_TX_ER_TIMEOUT;
+ pkt->len = 0;
+ fhci_transaction_confirm(usb, pkt);
+ } else if (fhci_host_transaction(usb, pkt, td->type, ed->dev_addr,
+ ed->ep_addr, ed->mode, ed->speed, td->toggle)) {
+ /* remove TD from actual frame */
+ list_del_init(&td->frame_lh);
+ td->status = USB_TD_OK;
+ if (pkt->info & PKT_DUMMY_PACKET)
+ cq_put(usb->ep0->dummy_packets_Q, pkt->data);
+ recycle_frame(usb, pkt);
+ usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD);
+ fhci_err(usb->fhci, "host transaction failed\n");
+ return -1;
+ }
+
+ return len;
+}
+
+static void move_head_to_tail(struct list_head *list)
+{
+ struct list_head *node = list->next;
+
+ if (!list_empty(list)) {
+ list_del(node);
+ list_add_tail(node, list);
+ }
+}
+
+/*
+ * This function goes through the endpoint list and schedules the
+ * transactions within this list
+ */
+static int scan_ed_list(struct fhci_usb *usb,
+ struct list_head *list, enum fhci_tf_mode list_type)
+{
+ static const int frame_part[4] = {
+ [FHCI_TF_CTRL] = MAX_BYTES_PER_FRAME,
+ [FHCI_TF_ISO] = (MAX_BYTES_PER_FRAME *
+ MAX_PERIODIC_FRAME_USAGE) / 100,
+ [FHCI_TF_BULK] = MAX_BYTES_PER_FRAME,
+ [FHCI_TF_INTR] = (MAX_BYTES_PER_FRAME *
+ MAX_PERIODIC_FRAME_USAGE) / 100
+ };
+ struct ed *ed;
+ struct td *td;
+ int ans = 1;
+ u32 save_transaction_time = usb->sw_transaction_time;
+
+ list_for_each_entry(ed, list, node) {
+ td = ed->td_head;
+
+ if (!td || (td && td->status == USB_TD_INPROGRESS))
+ continue;
+
+ if (ed->state != FHCI_ED_OPER) {
+ if (ed->state == FHCI_ED_URB_DEL) {
+ td->status = USB_TD_OK;
+ fhci_move_td_from_ed_to_done_list(usb, ed);
+ ed->state = FHCI_ED_SKIP;
+ }
+ continue;
+ }
+
+ /*
+ * if it isn't interrupt pipe or it is not iso pipe and the
+ * interval time passed
+ */
+ if ((list_type == FHCI_TF_INTR || list_type == FHCI_TF_ISO) &&
+ (((usb->actual_frame->frame_num -
+ td->start_frame) & 0x7ff) < td->interval))
+ continue;
+
+ if (add_packet(usb, ed, td) < 0)
+ continue;
+
+ /* update time stamps in the TD */
+ td->start_frame = usb->actual_frame->frame_num;
+ usb->sw_transaction_time += save_transaction_time;
+
+ if (usb->actual_frame->total_bytes >=
+ usb->max_bytes_per_frame) {
+ usb->actual_frame->frame_status =
+ FRAME_DATA_END_TRANSMISSION;
+ fhci_push_dummy_bd(usb->ep0);
+ ans = 0;
+ break;
+ }
+
+ if (usb->actual_frame->total_bytes >= frame_part[list_type])
+ break;
+ }
+
+ /* be fair to each ED(move list head around) */
+ move_head_to_tail(list);
+ usb->sw_transaction_time = save_transaction_time;
+
+ return ans;
+}
+
+static u32 rotate_frames(struct fhci_usb *usb)
+{
+ struct fhci_hcd *fhci = usb->fhci;
+
+ if (!list_empty(&usb->actual_frame->tds_list)) {
+ if ((((in_be16(&fhci->pram->frame_num) & 0x07ff) -
+ usb->actual_frame->frame_num) & 0x7ff) > 5)
+ fhci_flush_actual_frame(usb);
+ else
+ return -EINVAL;
+ }
+
+ usb->actual_frame->frame_status = FRAME_IS_PREPARED;
+ usb->actual_frame->frame_num = in_be16(&fhci->pram->frame_num) & 0x7ff;
+ usb->actual_frame->total_bytes = 0;
+
+ return 0;
+}
+
+/*
+ * This function schedule the USB transaction and will process the
+ * endpoint in the following order: iso, interrupt, control and bulk.
+ */
+void fhci_schedule_transactions(struct fhci_usb *usb)
+{
+ int left = 1;
+
+ if (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)
+ if (rotate_frames(usb) != 0)
+ return;
+
+ if (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)
+ return;
+
+ if (usb->actual_frame->total_bytes == 0) {
+ /*
+ * schedule the next available ISO transfer
+ *or next stage of the ISO transfer
+ */
+ scan_ed_list(usb, &usb->hc_list->iso_list, FHCI_TF_ISO);
+
+ /*
+ * schedule the next available interrupt transfer or
+ * the next stage of the interrupt transfer
+ */
+ scan_ed_list(usb, &usb->hc_list->intr_list, FHCI_TF_INTR);
+
+ /*
+ * schedule the next available control transfer
+ * or the next stage of the control transfer
+ */
+ left = scan_ed_list(usb, &usb->hc_list->ctrl_list,
+ FHCI_TF_CTRL);
+ }
+
+ /*
+ * schedule the next available bulk transfer or the next stage of the
+ * bulk transfer
+ */
+ if (left > 0)
+ scan_ed_list(usb, &usb->hc_list->bulk_list, FHCI_TF_BULK);
+}
+
+/* Handles SOF interrupt */
+static void sof_interrupt(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ if ((usb->port_status == FHCI_PORT_DISABLED) &&
+ (usb->vroot_hub->port.wPortStatus & USB_PORT_STAT_CONNECTION) &&
+ !(usb->vroot_hub->port.wPortChange & USB_PORT_STAT_C_CONNECTION)) {
+ if (usb->vroot_hub->port.wPortStatus & USB_PORT_STAT_LOW_SPEED)
+ usb->port_status = FHCI_PORT_LOW;
+ else
+ usb->port_status = FHCI_PORT_FULL;
+ /* Disable IDLE */
+ usb->saved_msk &= ~USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+ }
+
+ gtm_set_exact_timer16(fhci->timer, usb->max_frame_usage, false);
+
+ fhci_host_transmit_actual_frame(usb);
+ usb->actual_frame->frame_status = FRAME_IS_TRANSMITTED;
+
+ fhci_schedule_transactions(usb);
+}
+
+/* Handles device disconnected interrupt on port */
+void fhci_device_disconnected_interrupt(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_usb_disable_interrupt(usb);
+ clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+ usb->port_status = FHCI_PORT_DISABLED;
+
+ fhci_stop_sof_timer(fhci);
+
+ /* Enable IDLE since we want to know if something comes along */
+ usb->saved_msk |= USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+
+ usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_CONNECTION;
+ usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_CONNECTION;
+ usb->max_bytes_per_frame = 0;
+ fhci_usb_enable_interrupt(usb);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+/* detect a new device connected on the USB port */
+void fhci_device_connected_interrupt(struct fhci_hcd *fhci)
+{
+
+ struct fhci_usb *usb = fhci->usb_lld;
+ int state;
+ int ret;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_usb_disable_interrupt(usb);
+ state = fhci_ioports_check_bus_state(fhci);
+
+ /* low-speed device was connected to the USB port */
+ if (state == 1) {
+ ret = qe_usb_clock_set(fhci->lowspeed_clk, USB_CLOCK >> 3);
+ if (ret) {
+ fhci_warn(fhci, "Low-Speed device is not supported, "
+ "try use BRGx\n");
+ goto out;
+ }
+
+ usb->port_status = FHCI_PORT_LOW;
+ setbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+ usb->vroot_hub->port.wPortStatus |=
+ (USB_PORT_STAT_LOW_SPEED |
+ USB_PORT_STAT_CONNECTION);
+ usb->vroot_hub->port.wPortChange |=
+ USB_PORT_STAT_C_CONNECTION;
+ usb->max_bytes_per_frame =
+ (MAX_BYTES_PER_FRAME >> 3) - 7;
+ fhci_port_enable(usb);
+ } else if (state == 2) {
+ ret = qe_usb_clock_set(fhci->fullspeed_clk, USB_CLOCK);
+ if (ret) {
+ fhci_warn(fhci, "Full-Speed device is not supported, "
+ "try use CLKx\n");
+ goto out;
+ }
+
+ usb->port_status = FHCI_PORT_FULL;
+ clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+ usb->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_LOW_SPEED;
+ usb->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_CONNECTION;
+ usb->vroot_hub->port.wPortChange |=
+ USB_PORT_STAT_C_CONNECTION;
+ usb->max_bytes_per_frame = (MAX_BYTES_PER_FRAME - 15);
+ fhci_port_enable(usb);
+ }
+out:
+ fhci_usb_enable_interrupt(usb);
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+irqreturn_t fhci_frame_limit_timer_irq(int irq, void *_hcd)
+{
+ struct usb_hcd *hcd = _hcd;
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ spin_lock(&fhci->lock);
+
+ gtm_set_exact_timer16(fhci->timer, 1000, false);
+
+ if (usb->actual_frame->frame_status == FRAME_IS_TRANSMITTED) {
+ usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
+ fhci_push_dummy_bd(usb->ep0);
+ }
+
+ fhci_schedule_transactions(usb);
+
+ spin_unlock(&fhci->lock);
+
+ return IRQ_HANDLED;
+}
+
+/* Cancel transmission on the USB endpoint */
+static void abort_transmission(struct fhci_usb *usb)
+{
+ fhci_dbg(usb->fhci, "-> %s\n", __func__);
+ /* issue stop Tx command */
+ qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB, EP_ZERO, 0);
+ /* flush Tx FIFOs */
+ out_8(&usb->fhci->regs->usb_comm, USB_CMD_FLUSH_FIFO | EP_ZERO);
+ udelay(1000);
+ /* reset Tx BDs */
+ fhci_flush_bds(usb);
+ /* issue restart Tx command */
+ qe_issue_cmd(QE_USB_RESTART_TX, QE_CR_SUBBLOCK_USB, EP_ZERO, 0);
+ fhci_dbg(usb->fhci, "<- %s\n", __func__);
+}
+
+irqreturn_t fhci_irq(struct usb_hcd *hcd)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ struct fhci_usb *usb;
+ u16 usb_er = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ usb = fhci->usb_lld;
+
+ usb_er |= in_be16(&usb->fhci->regs->usb_event) &
+ in_be16(&usb->fhci->regs->usb_mask);
+
+ /* clear event bits for next time */
+ out_be16(&usb->fhci->regs->usb_event, usb_er);
+
+ fhci_dbg_isr(fhci, usb_er);
+
+ if (usb_er & USB_E_RESET_MASK) {
+ if ((usb->port_status == FHCI_PORT_FULL) ||
+ (usb->port_status == FHCI_PORT_LOW)) {
+ fhci_device_disconnected_interrupt(fhci);
+ usb_er &= ~USB_E_IDLE_MASK;
+ } else if (usb->port_status == FHCI_PORT_WAITING) {
+ usb->port_status = FHCI_PORT_DISCONNECTING;
+
+ /* Turn on IDLE since we want to disconnect */
+ usb->saved_msk |= USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_event,
+ usb->saved_msk);
+ } else if (usb->port_status == FHCI_PORT_DISABLED) {
+ if (fhci_ioports_check_bus_state(fhci) == 1 &&
+ usb->port_status != FHCI_PORT_LOW &&
+ usb->port_status != FHCI_PORT_FULL)
+ fhci_device_connected_interrupt(fhci);
+ }
+ usb_er &= ~USB_E_RESET_MASK;
+ }
+
+ if (usb_er & USB_E_MSF_MASK) {
+ abort_transmission(fhci->usb_lld);
+ usb_er &= ~USB_E_MSF_MASK;
+ }
+
+ if (usb_er & (USB_E_SOF_MASK | USB_E_SFT_MASK)) {
+ sof_interrupt(fhci);
+ usb_er &= ~(USB_E_SOF_MASK | USB_E_SFT_MASK);
+ }
+
+ if (usb_er & USB_E_TXB_MASK) {
+ fhci_tx_conf_interrupt(fhci->usb_lld);
+ usb_er &= ~USB_E_TXB_MASK;
+ }
+
+ if (usb_er & USB_E_TXE1_MASK) {
+ fhci_tx_conf_interrupt(fhci->usb_lld);
+ usb_er &= ~USB_E_TXE1_MASK;
+ }
+
+ if (usb_er & USB_E_IDLE_MASK) {
+ if (usb->port_status == FHCI_PORT_DISABLED &&
+ usb->port_status != FHCI_PORT_LOW &&
+ usb->port_status != FHCI_PORT_FULL) {
+ usb_er &= ~USB_E_RESET_MASK;
+ fhci_device_connected_interrupt(fhci);
+ } else if (usb->port_status ==
+ FHCI_PORT_DISCONNECTING) {
+ /* XXX usb->port_status = FHCI_PORT_WAITING; */
+ /* Disable IDLE */
+ usb->saved_msk &= ~USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_mask,
+ usb->saved_msk);
+ } else {
+ fhci_dbg_isr(fhci, -1);
+ }
+
+ usb_er &= ~USB_E_IDLE_MASK;
+ }
+
+ spin_unlock_irqrestore(&fhci->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * Process normal completions(error or sucess) and clean the schedule.
+ *
+ * This is the main path for handing urbs back to drivers. The only other patth
+ * is process_del_list(),which unlinks URBs by scanning EDs,instead of scanning
+ * the (re-reversed) done list as this does.
+ */
+static void process_done_list(unsigned long data)
+{
+ struct urb *urb;
+ struct ed *ed;
+ struct td *td;
+ struct urb_priv *urb_priv;
+ struct fhci_hcd *fhci = (struct fhci_hcd *)data;
+
+ disable_irq(fhci->timer->irq);
+ disable_irq(fhci_to_hcd(fhci)->irq);
+ spin_lock(&fhci->lock);
+
+ td = fhci_remove_td_from_done_list(fhci->hc_list);
+ while (td != NULL) {
+ urb = td->urb;
+ urb_priv = urb->hcpriv;
+ ed = td->ed;
+
+ /* update URB's length and status from TD */
+ fhci_done_td(urb, td);
+ urb_priv->tds_cnt++;
+
+ /*
+ * if all this urb's TDs are done, call complete()
+ * Interrupt transfers are the onley special case:
+ * they are reissued,until "deleted" by usb_unlink_urb
+ * (real work done in a SOF intr, by process_del_list)
+ */
+ if (urb_priv->tds_cnt == urb_priv->num_of_tds) {
+ fhci_urb_complete_free(fhci, urb);
+ } else if (urb_priv->state == URB_DEL &&
+ ed->state == FHCI_ED_SKIP) {
+ fhci_del_ed_list(fhci, ed);
+ ed->state = FHCI_ED_OPER;
+ } else if (ed->state == FHCI_ED_HALTED) {
+ urb_priv->state = URB_DEL;
+ ed->state = FHCI_ED_URB_DEL;
+ fhci_del_ed_list(fhci, ed);
+ ed->state = FHCI_ED_OPER;
+ }
+
+ td = fhci_remove_td_from_done_list(fhci->hc_list);
+ }
+
+ spin_unlock(&fhci->lock);
+ enable_irq(fhci->timer->irq);
+ enable_irq(fhci_to_hcd(fhci)->irq);
+}
+
+DECLARE_TASKLET(fhci_tasklet, process_done_list, 0);
+
+/* transfer complted callback */
+u32 fhci_transfer_confirm_callback(struct fhci_hcd *fhci)
+{
+ if (!fhci->process_done_task->state)
+ tasklet_schedule(fhci->process_done_task);
+ return 0;
+}
+
+/*
+ * adds urb to the endpoint descriptor list
+ * arguments:
+ * fhci data structure for the Low level host controller
+ * ep USB Host endpoint data structure
+ * urb USB request block data structure
+ */
+void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
+{
+ struct ed *ed = urb->ep->hcpriv;
+ struct urb_priv *urb_priv = urb->hcpriv;
+ u32 data_len = urb->transfer_buffer_length;
+ int urb_state = 0;
+ int toggle = 0;
+ struct td *td;
+ u8 *data;
+ u16 cnt = 0;
+
+ if (ed == NULL) {
+ ed = fhci_get_empty_ed(fhci);
+ ed->dev_addr = usb_pipedevice(urb->pipe);
+ ed->ep_addr = usb_pipeendpoint(urb->pipe);
+ switch (usb_pipetype(urb->pipe)) {
+ case PIPE_CONTROL:
+ ed->mode = FHCI_TF_CTRL;
+ break;
+ case PIPE_BULK:
+ ed->mode = FHCI_TF_BULK;
+ break;
+ case PIPE_INTERRUPT:
+ ed->mode = FHCI_TF_INTR;
+ break;
+ case PIPE_ISOCHRONOUS:
+ ed->mode = FHCI_TF_ISO;
+ break;
+ default:
+ break;
+ }
+ ed->speed = (urb->dev->speed == USB_SPEED_LOW) ?
+ FHCI_LOW_SPEED : FHCI_FULL_SPEED;
+ ed->max_pkt_size = usb_maxpacket(urb->dev,
+ urb->pipe, usb_pipeout(urb->pipe));
+ urb->ep->hcpriv = ed;
+ fhci_dbg(fhci, "new ep speed=%d max_pkt_size=%d\n",
+ ed->speed, ed->max_pkt_size);
+ }
+
+ /* for ISO transfer calculate start frame index */
+ if (ed->mode == FHCI_TF_ISO && urb->transfer_flags & URB_ISO_ASAP)
+ urb->start_frame = ed->td_head ? ed->last_iso + 1 :
+ get_frame_num(fhci);
+
+ /*
+ * OHCI handles the DATA toggle itself,we just use the USB
+ * toggle bits
+ */
+ if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+ usb_pipeout(urb->pipe)))
+ toggle = USB_TD_TOGGLE_CARRY;
+ else {
+ toggle = USB_TD_TOGGLE_DATA0;
+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+ usb_pipeout(urb->pipe), 1);
+ }
+
+ urb_priv->tds_cnt = 0;
+ urb_priv->ed = ed;
+ if (data_len > 0)
+ data = urb->transfer_buffer;
+ else
+ data = NULL;
+
+ switch (ed->mode) {
+ case FHCI_TF_BULK:
+ if (urb->transfer_flags & URB_ZERO_PACKET &&
+ urb->transfer_buffer_length > 0 &&
+ ((urb->transfer_buffer_length %
+ usb_maxpacket(urb->dev, urb->pipe,
+ usb_pipeout(urb->pipe))) == 0))
+ urb_state = US_BULK0;
+ while (data_len > 4096) {
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
+ FHCI_TA_IN,
+ cnt ? USB_TD_TOGGLE_CARRY :
+ toggle,
+ data, 4096, 0, 0, true);
+ data += 4096;
+ data_len -= 4096;
+ cnt++;
+ }
+
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT : FHCI_TA_IN,
+ cnt ? USB_TD_TOGGLE_CARRY : toggle,
+ data, data_len, 0, 0, true);
+ cnt++;
+
+ if (urb->transfer_flags & URB_ZERO_PACKET &&
+ cnt < urb_priv->num_of_tds) {
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
+ FHCI_TA_IN,
+ USB_TD_TOGGLE_CARRY, NULL, 0, 0, 0, true);
+ cnt++;
+ }
+ break;
+ case FHCI_TF_INTR:
+ urb->start_frame = get_frame_num(fhci) + 1;
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT : FHCI_TA_IN,
+ USB_TD_TOGGLE_DATA0, data, data_len,
+ urb->interval, urb->start_frame, true);
+ break;
+ case FHCI_TF_CTRL:
+ ed->dev_addr = usb_pipedevice(urb->pipe);
+ ed->max_pkt_size = usb_maxpacket(urb->dev, urb->pipe,
+ usb_pipeout(urb->pipe));
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP,
+ USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true);
+
+ if (data_len > 0) {
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
+ FHCI_TA_IN,
+ USB_TD_TOGGLE_DATA1, data, data_len, 0, 0,
+ true);
+ }
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ usb_pipeout(urb->pipe) ? FHCI_TA_IN : FHCI_TA_OUT,
+ USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true);
+ urb_state = US_CTRL_SETUP;
+ break;
+ case FHCI_TF_ISO:
+ for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
+ u16 frame = urb->start_frame;
+
+ /*
+ * FIXME scheduling should handle frame counter
+ * roll-around ... exotic case (and OHCI has
+ * a 2^16 iso range, vs other HCs max of 2^10)
+ */
+ frame += cnt * urb->interval;
+ frame &= 0x07ff;
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
+ FHCI_TA_IN,
+ USB_TD_TOGGLE_DATA0,
+ data + urb->iso_frame_desc[cnt].offset,
+ urb->iso_frame_desc[cnt].length,
+ urb->interval, frame, true);
+ }
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * set the state of URB
+ * control pipe:3 states -- setup,data,status
+ * interrupt and bulk pipe:1 state -- data
+ */
+ urb->pipe &= ~0x1f;
+ urb->pipe |= urb_state & 0x1f;
+
+ urb_priv->state = URB_INPROGRESS;
+
+ if (!ed->td_head) {
+ ed->state = FHCI_ED_OPER;
+ switch (ed->mode) {
+ case FHCI_TF_CTRL:
+ list_add(&ed->node, &fhci->hc_list->ctrl_list);
+ break;
+ case FHCI_TF_BULK:
+ list_add(&ed->node, &fhci->hc_list->bulk_list);
+ break;
+ case FHCI_TF_INTR:
+ list_add(&ed->node, &fhci->hc_list->intr_list);
+ break;
+ case FHCI_TF_ISO:
+ list_add(&ed->node, &fhci->hc_list->iso_list);
+ break;
+ default:
+ break;
+ }
+ }
+
+ fhci_add_tds_to_ed(ed, urb_priv->tds, urb_priv->num_of_tds);
+ fhci->active_urbs++;
+}
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c
new file mode 100644
index 00000000000..b4033229031
--- /dev/null
+++ b/drivers/usb/host/fhci-tds.c
@@ -0,0 +1,626 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+#define DUMMY_BD_BUFFER 0xdeadbeef
+#define DUMMY2_BD_BUFFER 0xbaadf00d
+
+/* Transaction Descriptors bits */
+#define TD_R 0x8000 /* ready bit */
+#define TD_W 0x2000 /* wrap bit */
+#define TD_I 0x1000 /* interrupt on completion */
+#define TD_L 0x0800 /* last */
+#define TD_TC 0x0400 /* transmit CRC */
+#define TD_CNF 0x0200 /* CNF - Must be always 1 */
+#define TD_LSP 0x0100 /* Low-speed transaction */
+#define TD_PID 0x00c0 /* packet id */
+#define TD_RXER 0x0020 /* Rx error or not */
+
+#define TD_NAK 0x0010 /* No ack. */
+#define TD_STAL 0x0008 /* Stall recieved */
+#define TD_TO 0x0004 /* time out */
+#define TD_UN 0x0002 /* underrun */
+#define TD_NO 0x0010 /* Rx Non Octet Aligned Packet */
+#define TD_AB 0x0008 /* Frame Aborted */
+#define TD_CR 0x0004 /* CRC Error */
+#define TD_OV 0x0002 /* Overrun */
+#define TD_BOV 0x0001 /* Buffer Overrun */
+
+#define TD_ERRORS (TD_NAK | TD_STAL | TD_TO | TD_UN | \
+ TD_NO | TD_AB | TD_CR | TD_OV | TD_BOV)
+
+#define TD_PID_DATA0 0x0080 /* Data 0 toggle */
+#define TD_PID_DATA1 0x00c0 /* Data 1 toggle */
+#define TD_PID_TOGGLE 0x00c0 /* Data 0/1 toggle mask */
+
+#define TD_TOK_SETUP 0x0000
+#define TD_TOK_OUT 0x4000
+#define TD_TOK_IN 0x8000
+#define TD_ISO 0x1000
+#define TD_ENDP 0x0780
+#define TD_ADDR 0x007f
+
+#define TD_ENDP_SHIFT 7
+
+struct usb_td {
+ __be16 status;
+ __be16 length;
+ __be32 buf_ptr;
+ __be16 extra;
+ __be16 reserved;
+};
+
+static struct usb_td __iomem *next_bd(struct usb_td __iomem *base,
+ struct usb_td __iomem *td,
+ u16 status)
+{
+ if (status & TD_W)
+ return base;
+ else
+ return ++td;
+}
+
+void fhci_push_dummy_bd(struct endpoint *ep)
+{
+ if (ep->already_pushed_dummy_bd == false) {
+ u16 td_status = in_be16(&ep->empty_td->status);
+
+ out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER);
+ /* get the next TD in the ring */
+ ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
+ ep->already_pushed_dummy_bd = true;
+ }
+}
+
+/* destroy an USB endpoint */
+void fhci_ep0_free(struct fhci_usb *usb)
+{
+ struct endpoint *ep;
+ int size;
+
+ ep = usb->ep0;
+ if (ep) {
+ if (ep->td_base)
+ cpm_muram_free(cpm_muram_offset(ep->td_base));
+
+ if (ep->conf_frame_Q) {
+ size = cq_howmany(ep->conf_frame_Q);
+ for (; size; size--) {
+ struct packet *pkt = cq_get(ep->conf_frame_Q);
+
+ kfree(pkt);
+ }
+ cq_delete(ep->conf_frame_Q);
+ }
+
+ if (ep->empty_frame_Q) {
+ size = cq_howmany(ep->empty_frame_Q);
+ for (; size; size--) {
+ struct packet *pkt = cq_get(ep->empty_frame_Q);
+
+ kfree(pkt);
+ }
+ cq_delete(ep->empty_frame_Q);
+ }
+
+ if (ep->dummy_packets_Q) {
+ size = cq_howmany(ep->dummy_packets_Q);
+ for (; size; size--) {
+ u8 *buff = cq_get(ep->dummy_packets_Q);
+
+ kfree(buff);
+ }
+ cq_delete(ep->dummy_packets_Q);
+ }
+
+ kfree(ep);
+ usb->ep0 = NULL;
+ }
+}
+
+/*
+ * create the endpoint structure
+ *
+ * arguments:
+ * usb A pointer to the data structure of the USB
+ * data_mem The data memory partition(BUS)
+ * ring_len TD ring length
+ */
+u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
+ u32 ring_len)
+{
+ struct endpoint *ep;
+ struct usb_td __iomem *td;
+ unsigned long ep_offset;
+ char *err_for = "enpoint PRAM";
+ int ep_mem_size;
+ u32 i;
+
+ /* we need at least 3 TDs in the ring */
+ if (!(ring_len > 2)) {
+ fhci_err(usb->fhci, "illegal TD ring length parameters\n");
+ return -EINVAL;
+ }
+
+ ep = kzalloc(sizeof(*ep), GFP_KERNEL);
+ if (!ep)
+ return -ENOMEM;
+
+ ep_mem_size = ring_len * sizeof(*td) + sizeof(struct fhci_ep_pram);
+ ep_offset = cpm_muram_alloc(ep_mem_size, 32);
+ if (IS_ERR_VALUE(ep_offset))
+ goto err;
+ ep->td_base = cpm_muram_addr(ep_offset);
+
+ /* zero all queue pointers */
+ ep->conf_frame_Q = cq_new(ring_len + 2);
+ ep->empty_frame_Q = cq_new(ring_len + 2);
+ ep->dummy_packets_Q = cq_new(ring_len + 2);
+ if (!ep->conf_frame_Q || !ep->empty_frame_Q || !ep->dummy_packets_Q) {
+ err_for = "frame_queues";
+ goto err;
+ }
+
+ for (i = 0; i < (ring_len + 1); i++) {
+ struct packet *pkt;
+ u8 *buff;
+
+ pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
+ if (!pkt) {
+ err_for = "frame";
+ goto err;
+ }
+
+ buff = kmalloc(1028 * sizeof(*buff), GFP_KERNEL);
+ if (!buff) {
+ kfree(pkt);
+ err_for = "buffer";
+ goto err;
+ }
+ cq_put(ep->empty_frame_Q, pkt);
+ cq_put(ep->dummy_packets_Q, buff);
+ }
+
+ /* we put the endpoint parameter RAM right behind the TD ring */
+ ep->ep_pram_ptr = (void __iomem *)ep->td_base + sizeof(*td) * ring_len;
+
+ ep->conf_td = ep->td_base;
+ ep->empty_td = ep->td_base;
+
+ ep->already_pushed_dummy_bd = false;
+
+ /* initialize tds */
+ td = ep->td_base;
+ for (i = 0; i < ring_len; i++) {
+ out_be32(&td->buf_ptr, 0);
+ out_be16(&td->status, 0);
+ out_be16(&td->length, 0);
+ out_be16(&td->extra, 0);
+ td++;
+ }
+ td--;
+ out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
+ out_be16(&td->length, 0);
+
+ /* endpoint structure has been created */
+ usb->ep0 = ep;
+
+ return 0;
+err:
+ fhci_ep0_free(usb);
+ kfree(ep);
+ fhci_err(usb->fhci, "no memory for the %s\n", err_for);
+ return -ENOMEM;
+}
+
+/*
+ * initialize the endpoint register according to the given parameters
+ *
+ * artuments:
+ * usb A pointer to the data strucutre of the USB
+ * ep A pointer to the endpoint structre
+ * data_mem The data memory partition(BUS)
+ */
+void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep,
+ enum fhci_mem_alloc data_mem)
+{
+ u8 rt;
+
+ /* set the endpoint registers according to the endpoint */
+ out_be16(&usb->fhci->regs->usb_ep[0],
+ USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE);
+ out_be16(&usb->fhci->pram->ep_ptr[0],
+ cpm_muram_offset(ep->ep_pram_ptr));
+
+ rt = (BUS_MODE_BO_BE | BUS_MODE_GBL);
+#ifdef MULTI_DATA_BUS
+ if (data_mem == MEM_SECONDARY)
+ rt |= BUS_MODE_DTB;
+#endif
+ out_8(&ep->ep_pram_ptr->rx_func_code, rt);
+ out_8(&ep->ep_pram_ptr->tx_func_code, rt);
+ out_be16(&ep->ep_pram_ptr->rx_buff_len, 1028);
+ out_be16(&ep->ep_pram_ptr->rx_base, 0);
+ out_be16(&ep->ep_pram_ptr->tx_base, cpm_muram_offset(ep->td_base));
+ out_be16(&ep->ep_pram_ptr->rx_bd_ptr, 0);
+ out_be16(&ep->ep_pram_ptr->tx_bd_ptr, cpm_muram_offset(ep->td_base));
+ out_be32(&ep->ep_pram_ptr->tx_state, 0);
+}
+
+/*
+ * Collect the submitted frames and inform the application about them
+ * It is also prepearing the TDs for new frames. If the Tx interrupts
+ * are diabled, the application should call that routine to get
+ * confirmation about the submitted frames. Otherwise, the routine is
+ * called frome the interrupt service routine during the Tx interrupt.
+ * In that case the application is informed by calling the application
+ * specific 'fhci_transaction_confirm' routine
+ */
+static void fhci_td_transaction_confirm(struct fhci_usb *usb)
+{
+ struct endpoint *ep = usb->ep0;
+ struct packet *pkt;
+ struct usb_td __iomem *td;
+ u16 extra_data;
+ u16 td_status;
+ u16 td_length;
+ u32 buf;
+
+ /*
+ * collect transmitted BDs from the chip. The routine clears all BDs
+ * with R bit = 0 and the pointer to data buffer is not NULL, that is
+ * BDs which point to the transmitted data buffer
+ */
+ while (1) {
+ td = ep->conf_td;
+ td_status = in_be16(&td->status);
+ td_length = in_be16(&td->length);
+ buf = in_be32(&td->buf_ptr);
+ extra_data = in_be16(&td->extra);
+
+ /* check if the TD is empty */
+ if (!(!(td_status & TD_R) && ((td_status & ~TD_W) || buf)))
+ break;
+ /* check if it is a dummy buffer */
+ else if ((buf == DUMMY_BD_BUFFER) && !(td_status & ~TD_W))
+ break;
+
+ /* mark TD as empty */
+ clrbits16(&td->status, ~TD_W);
+ out_be16(&td->length, 0);
+ out_be32(&td->buf_ptr, 0);
+ out_be16(&td->extra, 0);
+ /* advance the TD pointer */
+ ep->conf_td = next_bd(ep->td_base, ep->conf_td, td_status);
+
+ /* check if it is a dummy buffer(type2) */
+ if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W))
+ continue;
+
+ pkt = cq_get(ep->conf_frame_Q);
+ if (!pkt)
+ fhci_err(usb->fhci, "no frame to confirm\n");
+
+ if (td_status & TD_ERRORS) {
+ if (td_status & TD_RXER) {
+ if (td_status & TD_CR)
+ pkt->status = USB_TD_RX_ER_CRC;
+ else if (td_status & TD_AB)
+ pkt->status = USB_TD_RX_ER_BITSTUFF;
+ else if (td_status & TD_OV)
+ pkt->status = USB_TD_RX_ER_OVERUN;
+ else if (td_status & TD_BOV)
+ pkt->status = USB_TD_RX_DATA_OVERUN;
+ else if (td_status & TD_NO)
+ pkt->status = USB_TD_RX_ER_NONOCT;
+ else
+ fhci_err(usb->fhci, "illegal error "
+ "occured\n");
+ } else if (td_status & TD_NAK)
+ pkt->status = USB_TD_TX_ER_NAK;
+ else if (td_status & TD_TO)
+ pkt->status = USB_TD_TX_ER_TIMEOUT;
+ else if (td_status & TD_UN)
+ pkt->status = USB_TD_TX_ER_UNDERUN;
+ else if (td_status & TD_STAL)
+ pkt->status = USB_TD_TX_ER_STALL;
+ else
+ fhci_err(usb->fhci, "illegal error occured\n");
+ } else if ((extra_data & TD_TOK_IN) &&
+ pkt->len > td_length - CRC_SIZE) {
+ pkt->status = USB_TD_RX_DATA_UNDERUN;
+ }
+
+ if (extra_data & TD_TOK_IN)
+ pkt->len = td_length - CRC_SIZE;
+ else if (pkt->info & PKT_ZLP)
+ pkt->len = 0;
+ else
+ pkt->len = td_length;
+
+ fhci_transaction_confirm(usb, pkt);
+ }
+}
+
+/*
+ * Submitting a data frame to a specified endpoint of a USB device
+ * The frame is put in the driver's transmit queue for this endpoint
+ *
+ * Arguments:
+ * usb A pointer to the USB structure
+ * pkt A pointer to the user frame structure
+ * trans_type Transaction tyep - IN,OUT or SETUP
+ * dest_addr Device address - 0~127
+ * dest_ep Endpoint number of the device - 0~16
+ * trans_mode Pipe type - ISO,Interrupt,bulk or control
+ * dest_speed USB speed - Low speed or FULL speed
+ * data_toggle Data sequence toggle - 0 or 1
+ */
+u32 fhci_host_transaction(struct fhci_usb *usb,
+ struct packet *pkt,
+ enum fhci_ta_type trans_type,
+ u8 dest_addr,
+ u8 dest_ep,
+ enum fhci_tf_mode trans_mode,
+ enum fhci_speed dest_speed, u8 data_toggle)
+{
+ struct endpoint *ep = usb->ep0;
+ struct usb_td __iomem *td;
+ u16 extra_data;
+ u16 td_status;
+
+ fhci_usb_disable_interrupt(usb);
+ /* start from the next BD that should be filled */
+ td = ep->empty_td;
+ td_status = in_be16(&td->status);
+
+ if (td_status & TD_R && in_be16(&td->length)) {
+ /* if the TD is not free */
+ fhci_usb_enable_interrupt(usb);
+ return -1;
+ }
+
+ /* get the next TD in the ring */
+ ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
+ fhci_usb_enable_interrupt(usb);
+ pkt->priv_data = td;
+ out_be32(&td->buf_ptr, virt_to_phys(pkt->data));
+ /* sets up transaction parameters - addr,endp,dir,and type */
+ extra_data = (dest_ep << TD_ENDP_SHIFT) | dest_addr;
+ switch (trans_type) {
+ case FHCI_TA_IN:
+ extra_data |= TD_TOK_IN;
+ break;
+ case FHCI_TA_OUT:
+ extra_data |= TD_TOK_OUT;
+ break;
+ case FHCI_TA_SETUP:
+ extra_data |= TD_TOK_SETUP;
+ break;
+ }
+ if (trans_mode == FHCI_TF_ISO)
+ extra_data |= TD_ISO;
+ out_be16(&td->extra, extra_data);
+
+ /* sets up the buffer descriptor */
+ td_status = ((td_status & TD_W) | TD_R | TD_L | TD_I | TD_CNF);
+ if (!(pkt->info & PKT_NO_CRC))
+ td_status |= TD_TC;
+
+ switch (trans_type) {
+ case FHCI_TA_IN:
+ if (data_toggle)
+ pkt->info |= PKT_PID_DATA1;
+ else
+ pkt->info |= PKT_PID_DATA0;
+ break;
+ default:
+ if (data_toggle) {
+ td_status |= TD_PID_DATA1;
+ pkt->info |= PKT_PID_DATA1;
+ } else {
+ td_status |= TD_PID_DATA0;
+ pkt->info |= PKT_PID_DATA0;
+ }
+ break;
+ }
+
+ if ((dest_speed == FHCI_LOW_SPEED) &&
+ (usb->port_status == FHCI_PORT_FULL))
+ td_status |= TD_LSP;
+
+ out_be16(&td->status, td_status);
+
+ /* set up buffer length */
+ if (trans_type == FHCI_TA_IN)
+ out_be16(&td->length, pkt->len + CRC_SIZE);
+ else
+ out_be16(&td->length, pkt->len);
+
+ /* put the frame to the confirmation queue */
+ cq_put(ep->conf_frame_Q, pkt);
+
+ if (cq_howmany(ep->conf_frame_Q) == 1)
+ out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
+
+ return 0;
+}
+
+/* Reset the Tx BD ring */
+void fhci_flush_bds(struct fhci_usb *usb)
+{
+ u16 extra_data;
+ u16 td_status;
+ u32 buf;
+ struct usb_td __iomem *td;
+ struct endpoint *ep = usb->ep0;
+
+ td = ep->td_base;
+ while (1) {
+ td_status = in_be16(&td->status);
+ buf = in_be32(&td->buf_ptr);
+ extra_data = in_be16(&td->extra);
+
+ /* if the TD is not empty - we'll confirm it as Timeout */
+ if (td_status & TD_R)
+ out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
+ /* if this TD is dummy - let's skip this TD */
+ else if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER)
+ out_be32(&td->buf_ptr, DUMMY2_BD_BUFFER);
+ /* if this is the last TD - break */
+ if (td_status & TD_W)
+ break;
+
+ td++;
+ }
+
+ fhci_td_transaction_confirm(usb);
+
+ td = ep->td_base;
+ do {
+ out_be16(&td->status, 0);
+ out_be16(&td->length, 0);
+ out_be32(&td->buf_ptr, 0);
+ out_be16(&td->extra, 0);
+ td++;
+ } while (!(in_be16(&td->status) & TD_W));
+ out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
+ out_be16(&td->length, 0);
+ out_be32(&td->buf_ptr, 0);
+ out_be16(&td->extra, 0);
+
+ out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
+ in_be16(&ep->ep_pram_ptr->tx_base));
+ out_be32(&ep->ep_pram_ptr->tx_state, 0);
+ out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
+ ep->empty_td = ep->td_base;
+ ep->conf_td = ep->td_base;
+}
+
+/*
+ * Flush all transmitted packets from TDs in the actual frame.
+ * This routine is called when something wrong with the controller and
+ * we want to get rid of the actual frame and start again next frame
+ */
+void fhci_flush_actual_frame(struct fhci_usb *usb)
+{
+ u8 mode;
+ u16 tb_ptr;
+ u16 extra_data;
+ u16 td_status;
+ u32 buf_ptr;
+ struct usb_td __iomem *td;
+ struct endpoint *ep = usb->ep0;
+
+ /* disable the USB controller */
+ mode = in_8(&usb->fhci->regs->usb_mod);
+ out_8(&usb->fhci->regs->usb_mod, mode & ~USB_MODE_EN);
+
+ tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
+ td = cpm_muram_addr(tb_ptr);
+ td_status = in_be16(&td->status);
+ buf_ptr = in_be32(&td->buf_ptr);
+ extra_data = in_be16(&td->extra);
+ do {
+ if (td_status & TD_R) {
+ out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
+ } else {
+ out_be32(&td->buf_ptr, 0);
+ ep->already_pushed_dummy_bd = false;
+ break;
+ }
+
+ /* advance the TD pointer */
+ td = next_bd(ep->td_base, td, td_status);
+ td_status = in_be16(&td->status);
+ buf_ptr = in_be32(&td->buf_ptr);
+ extra_data = in_be16(&td->extra);
+ } while ((td_status & TD_R) || buf_ptr);
+
+ fhci_td_transaction_confirm(usb);
+
+ out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
+ in_be16(&ep->ep_pram_ptr->tx_base));
+ out_be32(&ep->ep_pram_ptr->tx_state, 0);
+ out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
+ ep->empty_td = ep->td_base;
+ ep->conf_td = ep->td_base;
+
+ usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
+
+ /* reset the event register */
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+ /* enable the USB controller */
+ out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN);
+}
+
+/* handles Tx confirm and Tx error interrupt */
+void fhci_tx_conf_interrupt(struct fhci_usb *usb)
+{
+ fhci_td_transaction_confirm(usb);
+
+ /*
+ * Schedule another transaction to this frame only if we have
+ * already confirmed all transaction in the frame.
+ */
+ if (((fhci_get_sof_timer_count(usb) < usb->max_frame_usage) ||
+ (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)) &&
+ (list_empty(&usb->actual_frame->tds_list)))
+ fhci_schedule_transactions(usb);
+}
+
+void fhci_host_transmit_actual_frame(struct fhci_usb *usb)
+{
+ u16 tb_ptr;
+ u16 td_status;
+ struct usb_td __iomem *td;
+ struct endpoint *ep = usb->ep0;
+
+ tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
+ td = cpm_muram_addr(tb_ptr);
+
+ if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) {
+ struct usb_td __iomem *old_td = td;
+
+ ep->already_pushed_dummy_bd = false;
+ td_status = in_be16(&td->status);
+ /* gets the next TD in the ring */
+ td = next_bd(ep->td_base, td, td_status);
+ tb_ptr = cpm_muram_offset(td);
+ out_be16(&ep->ep_pram_ptr->tx_bd_ptr, tb_ptr);
+
+ /* start transmit only if we have something in the TDs */
+ if (in_be16(&td->status) & TD_R)
+ out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
+
+ if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) {
+ out_be32(&old_td->buf_ptr, 0);
+ ep->conf_td = next_bd(ep->td_base, ep->conf_td,
+ td_status);
+ } else {
+ out_be32(&old_td->buf_ptr, DUMMY2_BD_BUFFER);
+ }
+ }
+}
diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h
new file mode 100644
index 00000000000..7116284ed21
--- /dev/null
+++ b/drivers/usb/host/fhci.h
@@ -0,0 +1,607 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.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.
+ */
+
+#ifndef __FHCI_H
+#define __FHCI_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include <asm/qe.h>
+#include "../core/hcd.h"
+
+#define USB_CLOCK 48000000
+
+#define FHCI_PRAM_SIZE 0x100
+
+#define MAX_EDS 32
+#define MAX_TDS 32
+
+
+/* CRC16 field size */
+#define CRC_SIZE 2
+
+/* USB protocol overhead for each frame transmitted from the host */
+#define PROTOCOL_OVERHEAD 7
+
+/* Packet structure, info field */
+#define PKT_PID_DATA0 0x80000000 /* PID - Data toggle zero */
+#define PKT_PID_DATA1 0x40000000 /* PID - Data toggle one */
+#define PKT_PID_SETUP 0x20000000 /* PID - Setup bit */
+#define PKT_SETUP_STATUS 0x10000000 /* Setup status bit */
+#define PKT_SETADDR_STATUS 0x08000000 /* Set address status bit */
+#define PKT_SET_HOST_LAST 0x04000000 /* Last data packet */
+#define PKT_HOST_DATA 0x02000000 /* Data packet */
+#define PKT_FIRST_IN_FRAME 0x01000000 /* First packet in the frame */
+#define PKT_TOKEN_FRAME 0x00800000 /* Token packet */
+#define PKT_ZLP 0x00400000 /* Zero length packet */
+#define PKT_IN_TOKEN_FRAME 0x00200000 /* IN token packet */
+#define PKT_OUT_TOKEN_FRAME 0x00100000 /* OUT token packet */
+#define PKT_SETUP_TOKEN_FRAME 0x00080000 /* SETUP token packet */
+#define PKT_STALL_FRAME 0x00040000 /* STALL packet */
+#define PKT_NACK_FRAME 0x00020000 /* NACK packet */
+#define PKT_NO_PID 0x00010000 /* No PID */
+#define PKT_NO_CRC 0x00008000 /* don't append CRC */
+#define PKT_HOST_COMMAND 0x00004000 /* Host command packet */
+#define PKT_DUMMY_PACKET 0x00002000 /* Dummy packet, used for mmm */
+#define PKT_LOW_SPEED_PACKET 0x00001000 /* Low-Speed packet */
+
+#define TRANS_OK (0)
+#define TRANS_INPROGRESS (-1)
+#define TRANS_DISCARD (-2)
+#define TRANS_FAIL (-3)
+
+#define PS_INT 0
+#define PS_DISCONNECTED 1
+#define PS_CONNECTED 2
+#define PS_READY 3
+#define PS_MISSING 4
+
+/* Transfer Descriptor status field */
+#define USB_TD_OK 0x00000000 /* TD transmited or received ok */
+#define USB_TD_INPROGRESS 0x80000000 /* TD is being transmitted */
+#define USB_TD_RX_ER_NONOCT 0x40000000 /* Tx Non Octet Aligned Packet */
+#define USB_TD_RX_ER_BITSTUFF 0x20000000 /* Frame Aborted-Received pkt */
+#define USB_TD_RX_ER_CRC 0x10000000 /* CRC error */
+#define USB_TD_RX_ER_OVERUN 0x08000000 /* Over - run occured */
+#define USB_TD_RX_ER_PID 0x04000000 /* wrong PID received */
+#define USB_TD_RX_DATA_UNDERUN 0x02000000 /* shorter than expected */
+#define USB_TD_RX_DATA_OVERUN 0x01000000 /* longer than expected */
+#define USB_TD_TX_ER_NAK 0x00800000 /* NAK handshake */
+#define USB_TD_TX_ER_STALL 0x00400000 /* STALL handshake */
+#define USB_TD_TX_ER_TIMEOUT 0x00200000 /* transmit time out */
+#define USB_TD_TX_ER_UNDERUN 0x00100000 /* transmit underrun */
+
+#define USB_TD_ERROR (USB_TD_RX_ER_NONOCT | USB_TD_RX_ER_BITSTUFF | \
+ USB_TD_RX_ER_CRC | USB_TD_RX_ER_OVERUN | USB_TD_RX_ER_PID | \
+ USB_TD_RX_DATA_UNDERUN | USB_TD_RX_DATA_OVERUN | \
+ USB_TD_TX_ER_NAK | USB_TD_TX_ER_STALL | \
+ USB_TD_TX_ER_TIMEOUT | USB_TD_TX_ER_UNDERUN)
+
+/* Transfer Descriptor toggle field */
+#define USB_TD_TOGGLE_DATA0 0
+#define USB_TD_TOGGLE_DATA1 1
+#define USB_TD_TOGGLE_CARRY 2
+
+/* #define MULTI_DATA_BUS */
+
+/* Bus mode register RBMR/TBMR */
+#define BUS_MODE_GBL 0x20 /* Global snooping */
+#define BUS_MODE_BO 0x18 /* Byte ordering */
+#define BUS_MODE_BO_BE 0x10 /* Byte ordering - Big-endian */
+#define BUS_MODE_DTB 0x02 /* Data bus */
+
+/* FHCI QE USB Register Description */
+
+/* USB Mode Register bit define */
+#define USB_MODE_EN 0x01
+#define USB_MODE_HOST 0x02
+#define USB_MODE_TEST 0x04
+#define USB_MODE_SFTE 0x08
+#define USB_MODE_RESUME 0x40
+#define USB_MODE_LSS 0x80
+
+/* USB Slave Address Register Mask */
+#define USB_SLVADDR_MASK 0x7F
+
+/* USB Endpoint register define */
+#define USB_EPNUM_MASK 0xF000
+#define USB_EPNUM_SHIFT 12
+
+#define USB_TRANS_MODE_SHIFT 8
+#define USB_TRANS_CTR 0x0000
+#define USB_TRANS_INT 0x0100
+#define USB_TRANS_BULK 0x0200
+#define USB_TRANS_ISO 0x0300
+
+#define USB_EP_MF 0x0020
+#define USB_EP_RTE 0x0010
+
+#define USB_THS_SHIFT 2
+#define USB_THS_MASK 0x000c
+#define USB_THS_NORMAL 0x0
+#define USB_THS_IGNORE_IN 0x0004
+#define USB_THS_NACK 0x0008
+#define USB_THS_STALL 0x000c
+
+#define USB_RHS_SHIFT 0
+#define USB_RHS_MASK 0x0003
+#define USB_RHS_NORMAL 0x0
+#define USB_RHS_IGNORE_OUT 0x0001
+#define USB_RHS_NACK 0x0002
+#define USB_RHS_STALL 0x0003
+
+#define USB_RTHS_MASK 0x000f
+
+/* USB Command Register define */
+#define USB_CMD_STR_FIFO 0x80
+#define USB_CMD_FLUSH_FIFO 0x40
+#define USB_CMD_ISFT 0x20
+#define USB_CMD_DSFT 0x10
+#define USB_CMD_EP_MASK 0x03
+
+/* USB Event and Mask Register define */
+#define USB_E_MSF_MASK 0x0800
+#define USB_E_SFT_MASK 0x0400
+#define USB_E_RESET_MASK 0x0200
+#define USB_E_IDLE_MASK 0x0100
+#define USB_E_TXE4_MASK 0x0080
+#define USB_E_TXE3_MASK 0x0040
+#define USB_E_TXE2_MASK 0x0020
+#define USB_E_TXE1_MASK 0x0010
+#define USB_E_SOF_MASK 0x0008
+#define USB_E_BSY_MASK 0x0004
+#define USB_E_TXB_MASK 0x0002
+#define USB_E_RXB_MASK 0x0001
+
+/* Freescale USB Host controller registers */
+struct fhci_regs {
+ u8 usb_mod; /* mode register */
+ u8 usb_addr; /* address register */
+ u8 usb_comm; /* command register */
+ u8 reserved1[1];
+ __be16 usb_ep[4]; /* endpoint register */
+ u8 reserved2[4];
+ __be16 usb_event; /* event register */
+ u8 reserved3[2];
+ __be16 usb_mask; /* mask register */
+ u8 reserved4[1];
+ u8 usb_status; /* status register */
+ __be16 usb_sof_tmr; /* Start Of Frame timer */
+ u8 reserved5[2];
+ __be16 usb_frame_num; /* frame number register */
+ u8 reserved6[1];
+};
+
+/* Freescale USB HOST */
+struct fhci_pram {
+ __be16 ep_ptr[4]; /* Endpoint porter reg */
+ __be32 rx_state; /* Rx internal state */
+ __be32 rx_ptr; /* Rx internal data pointer */
+ __be16 frame_num; /* Frame number */
+ __be16 rx_cnt; /* Rx byte count */
+ __be32 rx_temp; /* Rx temp */
+ __be32 rx_data_temp; /* Rx data temp */
+ __be16 rx_u_ptr; /* Rx microcode return address temp */
+ u8 reserved1[2]; /* reserved area */
+ __be32 sof_tbl; /* SOF lookup table pointer */
+ u8 sof_u_crc_temp; /* SOF micorcode CRC5 temp reg */
+ u8 reserved2[0xdb];
+};
+
+/* Freescale USB Endpoint*/
+struct fhci_ep_pram {
+ __be16 rx_base; /* Rx BD base address */
+ __be16 tx_base; /* Tx BD base address */
+ u8 rx_func_code; /* Rx function code */
+ u8 tx_func_code; /* Tx function code */
+ __be16 rx_buff_len; /* Rx buffer length */
+ __be16 rx_bd_ptr; /* Rx BD pointer */
+ __be16 tx_bd_ptr; /* Tx BD pointer */
+ __be32 tx_state; /* Tx internal state */
+ __be32 tx_ptr; /* Tx internal data pointer */
+ __be16 tx_crc; /* temp transmit CRC */
+ __be16 tx_cnt; /* Tx byte count */
+ __be32 tx_temp; /* Tx temp */
+ __be16 tx_u_ptr; /* Tx microcode return address temp */
+ __be16 reserved;
+};
+
+struct fhci_controller_list {
+ struct list_head ctrl_list; /* control endpoints */
+ struct list_head bulk_list; /* bulk endpoints */
+ struct list_head iso_list; /* isochronous endpoints */
+ struct list_head intr_list; /* interruput endpoints */
+ struct list_head done_list; /* done transfers */
+};
+
+struct virtual_root_hub {
+ int dev_num; /* USB address of the root hub */
+ u32 feature; /* indicates what feature has been set */
+ struct usb_hub_status hub;
+ struct usb_port_status port;
+};
+
+enum fhci_gpios {
+ GPIO_USBOE = 0,
+ GPIO_USBTP,
+ GPIO_USBTN,
+ GPIO_USBRP,
+ GPIO_USBRN,
+ /* these are optional */
+ GPIO_SPEED,
+ GPIO_POWER,
+ NUM_GPIOS,
+};
+
+enum fhci_pins {
+ PIN_USBOE = 0,
+ PIN_USBTP,
+ PIN_USBTN,
+ NUM_PINS,
+};
+
+struct fhci_hcd {
+ enum qe_clock fullspeed_clk;
+ enum qe_clock lowspeed_clk;
+ struct qe_pin *pins[NUM_PINS];
+ int gpios[NUM_GPIOS];
+ bool alow_gpios[NUM_GPIOS];
+
+ struct fhci_regs __iomem *regs; /* I/O memory used to communicate */
+ struct fhci_pram __iomem *pram; /* Parameter RAM */
+ struct gtm_timer *timer;
+
+ spinlock_t lock;
+ struct fhci_usb *usb_lld; /* Low-level driver */
+ struct virtual_root_hub *vroot_hub; /* the virtual root hub */
+ int active_urbs;
+ struct fhci_controller_list *hc_list;
+ struct tasklet_struct *process_done_task; /* tasklet for done list */
+
+ struct list_head empty_eds;
+ struct list_head empty_tds;
+
+#ifdef CONFIG_FHCI_DEBUG
+ int usb_irq_stat[13];
+ struct dentry *dfs_root;
+ struct dentry *dfs_regs;
+ struct dentry *dfs_irq_stat;
+#endif
+};
+
+#define USB_FRAME_USAGE 90
+#define FRAME_TIME_USAGE (USB_FRAME_USAGE*10) /* frame time usage */
+#define SW_FIX_TIME_BETWEEN_TRANSACTION 150 /* SW */
+#define MAX_BYTES_PER_FRAME (USB_FRAME_USAGE*15)
+#define MAX_PERIODIC_FRAME_USAGE 90
+
+/* transaction type */
+enum fhci_ta_type {
+ FHCI_TA_IN = 0, /* input transaction */
+ FHCI_TA_OUT, /* output transaction */
+ FHCI_TA_SETUP, /* setup transaction */
+};
+
+/* transfer mode */
+enum fhci_tf_mode {
+ FHCI_TF_CTRL = 0,
+ FHCI_TF_ISO,
+ FHCI_TF_BULK,
+ FHCI_TF_INTR,
+};
+
+enum fhci_speed {
+ FHCI_FULL_SPEED,
+ FHCI_LOW_SPEED,
+};
+
+/* endpoint state */
+enum fhci_ed_state {
+ FHCI_ED_NEW = 0, /* pipe is new */
+ FHCI_ED_OPER, /* pipe is operating */
+ FHCI_ED_URB_DEL, /* pipe is in hold because urb is being deleted */
+ FHCI_ED_SKIP, /* skip this pipe */
+ FHCI_ED_HALTED, /* pipe is halted */
+};
+
+enum fhci_port_status {
+ FHCI_PORT_POWER_OFF = 0,
+ FHCI_PORT_DISABLED,
+ FHCI_PORT_DISCONNECTING,
+ FHCI_PORT_WAITING, /* waiting for connection */
+ FHCI_PORT_FULL, /* full speed connected */
+ FHCI_PORT_LOW, /* low speed connected */
+};
+
+enum fhci_mem_alloc {
+ MEM_CACHABLE_SYS = 0x00000001, /* primary DDR,cachable */
+ MEM_NOCACHE_SYS = 0x00000004, /* primary DDR,non-cachable */
+ MEM_SECONDARY = 0x00000002, /* either secondary DDR or SDRAM */
+ MEM_PRAM = 0x00000008, /* multi-user RAM identifier */
+};
+
+/* USB default parameters*/
+#define DEFAULT_RING_LEN 8
+#define DEFAULT_DATA_MEM MEM_CACHABLE_SYS
+
+struct ed {
+ u8 dev_addr; /* device address */
+ u8 ep_addr; /* endpoint address */
+ enum fhci_tf_mode mode; /* USB transfer mode */
+ enum fhci_speed speed;
+ unsigned int max_pkt_size;
+ enum fhci_ed_state state;
+ struct list_head td_list; /* a list of all queued TD to this pipe */
+ struct list_head node;
+
+ /* read only parameters, should be cleared upon initialization */
+ u8 toggle_carry; /* toggle carry from the last TD submitted */
+ u32 last_iso; /* time stamp of last queued ISO transfer */
+ struct td *td_head; /* a pointer to the current TD handled */
+};
+
+struct td {
+ void *data; /* a pointer to the data buffer */
+ unsigned int len; /* length of the data to be submitted */
+ unsigned int actual_len; /* actual bytes transfered on this td */
+ enum fhci_ta_type type; /* transaction type */
+ u8 toggle; /* toggle for next trans. within this TD */
+ u16 iso_index; /* ISO transaction index */
+ u16 start_frame; /* start frame time stamp */
+ u16 interval; /* interval between trans. (for ISO/Intr) */
+ u32 status; /* status of the TD */
+ struct ed *ed; /* a handle to the corresponding ED */
+ struct urb *urb; /* a handle to the corresponding URB */
+ bool ioc; /* Inform On Completion */
+ struct list_head node;
+
+ /* read only parameters should be cleared upon initialization */
+ struct packet *pkt;
+ int nak_cnt;
+ int error_cnt;
+ struct list_head frame_lh;
+};
+
+struct packet {
+ u8 *data; /* packet data */
+ u32 len; /* packet length */
+ u32 status; /* status of the packet - equivalent to the status
+ * field for the corresponding structure td */
+ u32 info; /* packet information */
+ void __iomem *priv_data; /* private data of the driver (TDs or BDs) */
+};
+
+/* struct for each URB */
+#define URB_INPROGRESS 0
+#define URB_DEL 1
+
+/* URB states (state field) */
+#define US_BULK 0
+#define US_BULK0 1
+
+/* three setup states */
+#define US_CTRL_SETUP 2
+#define US_CTRL_DATA 1
+#define US_CTRL_ACK 0
+
+#define EP_ZERO 0
+
+struct urb_priv {
+ int num_of_tds;
+ int tds_cnt;
+ int state;
+
+ struct td **tds;
+ struct ed *ed;
+ struct timer_list time_out;
+};
+
+struct endpoint {
+ /* Pointer to ep parameter RAM */
+ struct fhci_ep_pram __iomem *ep_pram_ptr;
+
+ /* Host transactions */
+ struct usb_td __iomem *td_base; /* first TD in the ring */
+ struct usb_td __iomem *conf_td; /* next TD for confirm after transac */
+ struct usb_td __iomem *empty_td;/* next TD for new transaction req. */
+ struct kfifo *empty_frame_Q; /* Empty frames list to use */
+ struct kfifo *conf_frame_Q; /* frames passed to TDs,waiting for tx */
+ struct kfifo *dummy_packets_Q;/* dummy packets for the CRC overun */
+
+ bool already_pushed_dummy_bd;
+};
+
+/* struct for each 1mSec frame time */
+#define FRAME_IS_TRANSMITTED 0x00
+#define FRAME_TIMER_END_TRANSMISSION 0x01
+#define FRAME_DATA_END_TRANSMISSION 0x02
+#define FRAME_END_TRANSMISSION 0x03
+#define FRAME_IS_PREPARED 0x04
+
+struct fhci_time_frame {
+ u16 frame_num; /* frame number */
+ u16 total_bytes; /* total bytes submitted within this frame */
+ u8 frame_status; /* flag that indicates to stop fill this frame */
+ struct list_head tds_list; /* all tds of this frame */
+};
+
+/* internal driver structure*/
+struct fhci_usb {
+ u16 saved_msk; /* saving of the USB mask register */
+ struct endpoint *ep0; /* pointer for endpoint0 structure */
+ int intr_nesting_cnt; /* interrupt nesting counter */
+ u16 max_frame_usage; /* max frame time usage,in micro-sec */
+ u16 max_bytes_per_frame; /* max byte can be tx in one time frame */
+ u32 sw_transaction_time; /* sw complete trans time,in micro-sec */
+ struct fhci_time_frame *actual_frame;
+ struct fhci_controller_list *hc_list; /* main structure for hc */
+ struct virtual_root_hub *vroot_hub;
+ enum fhci_port_status port_status; /* v_rh port status */
+
+ u32 (*transfer_confirm)(struct fhci_hcd *fhci);
+
+ struct fhci_hcd *fhci;
+};
+
+/*
+ * Various helpers and prototypes below.
+ */
+
+static inline u16 get_frame_num(struct fhci_hcd *fhci)
+{
+ return in_be16(&fhci->pram->frame_num) & 0x07ff;
+}
+
+#define fhci_dbg(fhci, fmt, args...) \
+ dev_dbg(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+#define fhci_vdbg(fhci, fmt, args...) \
+ dev_vdbg(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+#define fhci_err(fhci, fmt, args...) \
+ dev_err(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+#define fhci_info(fhci, fmt, args...) \
+ dev_info(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+#define fhci_warn(fhci, fmt, args...) \
+ dev_warn(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+
+static inline struct fhci_hcd *hcd_to_fhci(struct usb_hcd *hcd)
+{
+ return (struct fhci_hcd *)hcd->hcd_priv;
+}
+
+static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci)
+{
+ return container_of((void *)fhci, struct usb_hcd, hcd_priv);
+}
+
+/* fifo of pointers */
+static inline struct kfifo *cq_new(int size)
+{
+ return kfifo_alloc(size * sizeof(void *), GFP_KERNEL, NULL);
+}
+
+static inline void cq_delete(struct kfifo *kfifo)
+{
+ kfifo_free(kfifo);
+}
+
+static inline unsigned int cq_howmany(struct kfifo *kfifo)
+{
+ return __kfifo_len(kfifo) / sizeof(void *);
+}
+
+static inline int cq_put(struct kfifo *kfifo, void *p)
+{
+ return __kfifo_put(kfifo, (void *)&p, sizeof(p));
+}
+
+static inline void *cq_get(struct kfifo *kfifo)
+{
+ void *p = NULL;
+
+ __kfifo_get(kfifo, (void *)&p, sizeof(p));
+ return p;
+}
+
+/* fhci-hcd.c */
+void fhci_start_sof_timer(struct fhci_hcd *fhci);
+void fhci_stop_sof_timer(struct fhci_hcd *fhci);
+u16 fhci_get_sof_timer_count(struct fhci_usb *usb);
+void fhci_usb_enable_interrupt(struct fhci_usb *usb);
+void fhci_usb_disable_interrupt(struct fhci_usb *usb);
+int fhci_ioports_check_bus_state(struct fhci_hcd *fhci);
+
+/* fhci-mem.c */
+void fhci_recycle_empty_td(struct fhci_hcd *fhci, struct td *td);
+void fhci_recycle_empty_ed(struct fhci_hcd *fhci, struct ed *ed);
+struct ed *fhci_get_empty_ed(struct fhci_hcd *fhci);
+struct td *fhci_td_fill(struct fhci_hcd *fhci, struct urb *urb,
+ struct urb_priv *urb_priv, struct ed *ed, u16 index,
+ enum fhci_ta_type type, int toggle, u8 *data, u32 len,
+ u16 interval, u16 start_frame, bool ioc);
+void fhci_add_tds_to_ed(struct ed *ed, struct td **td_list, int number);
+
+/* fhci-hub.c */
+void fhci_config_transceiver(struct fhci_hcd *fhci,
+ enum fhci_port_status status);
+void fhci_port_disable(struct fhci_hcd *fhci);
+void fhci_port_enable(void *lld);
+void fhci_io_port_generate_reset(struct fhci_hcd *fhci);
+void fhci_port_reset(void *lld);
+int fhci_hub_status_data(struct usb_hcd *hcd, char *buf);
+int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ u16 wIndex, char *buf, u16 wLength);
+
+/* fhci-tds.c */
+void fhci_flush_bds(struct fhci_usb *usb);
+void fhci_flush_actual_frame(struct fhci_usb *usb);
+u32 fhci_host_transaction(struct fhci_usb *usb, struct packet *pkt,
+ enum fhci_ta_type trans_type, u8 dest_addr,
+ u8 dest_ep, enum fhci_tf_mode trans_mode,
+ enum fhci_speed dest_speed, u8 data_toggle);
+void fhci_host_transmit_actual_frame(struct fhci_usb *usb);
+void fhci_tx_conf_interrupt(struct fhci_usb *usb);
+void fhci_push_dummy_bd(struct endpoint *ep);
+u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
+ u32 ring_len);
+void fhci_init_ep_registers(struct fhci_usb *usb,
+ struct endpoint *ep,
+ enum fhci_mem_alloc data_mem);
+void fhci_ep0_free(struct fhci_usb *usb);
+
+/* fhci-sched.c */
+extern struct tasklet_struct fhci_tasklet;
+void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt);
+void fhci_flush_all_transmissions(struct fhci_usb *usb);
+void fhci_schedule_transactions(struct fhci_usb *usb);
+void fhci_device_connected_interrupt(struct fhci_hcd *fhci);
+void fhci_device_disconnected_interrupt(struct fhci_hcd *fhci);
+void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb);
+u32 fhci_transfer_confirm_callback(struct fhci_hcd *fhci);
+irqreturn_t fhci_irq(struct usb_hcd *hcd);
+irqreturn_t fhci_frame_limit_timer_irq(int irq, void *_hcd);
+
+/* fhci-q.h */
+void fhci_urb_complete_free(struct fhci_hcd *fhci, struct urb *urb);
+struct td *fhci_remove_td_from_ed(struct ed *ed);
+struct td *fhci_remove_td_from_frame(struct fhci_time_frame *frame);
+void fhci_move_td_from_ed_to_done_list(struct fhci_usb *usb, struct ed *ed);
+struct td *fhci_peek_td_from_frame(struct fhci_time_frame *frame);
+void fhci_add_td_to_frame(struct fhci_time_frame *frame, struct td *td);
+struct td *fhci_remove_td_from_done_list(struct fhci_controller_list *p_list);
+void fhci_done_td(struct urb *urb, struct td *td);
+void fhci_del_ed_list(struct fhci_hcd *fhci, struct ed *ed);
+
+#ifdef CONFIG_FHCI_DEBUG
+
+void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er);
+void fhci_dfs_destroy(struct fhci_hcd *fhci);
+void fhci_dfs_create(struct fhci_hcd *fhci);
+
+#else
+
+static inline void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er) {}
+static inline void fhci_dfs_destroy(struct fhci_hcd *fhci) {}
+static inline void fhci_dfs_create(struct fhci_hcd *fhci) {}
+
+#endif /* CONFIG_FHCI_DEBUG */
+
+#endif /* __FHCI_H */
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
index 8582236e4ca..cbf30e515f2 100644
--- a/drivers/usb/host/hwa-hc.c
+++ b/drivers/usb/host/hwa-hc.c
@@ -464,8 +464,7 @@ static int __hwahc_dev_set_key(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
port_idx << 8 | iface_no,
keyd, keyd_len, 1000 /* FIXME: arbitrary */);
- memset(keyd, 0, sizeof(*keyd)); /* clear keys etc. */
- kfree(keyd);
+ kzfree(keyd); /* clear keys etc. */
return result;
}
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 4dda31b2689..a2b305477af 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -772,7 +772,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
break;
case PIPE_INTERRUPT:
urb->interval = ep->period;
- ep->length = min((int)ep->maxpacket,
+ ep->length = min_t(u32, ep->maxpacket,
urb->transfer_buffer_length);
/* urb submitted for already existing endpoint */
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
index aa211bafcff..12db961acdf 100644
--- a/drivers/usb/host/isp116x.h
+++ b/drivers/usb/host/isp116x.h
@@ -563,7 +563,7 @@ static void urb_dbg(struct urb *urb, char *msg)
*/
static inline void dump_ptd(struct ptd *ptd)
{
- printk("td: %x %d%c%d %d,%d,%d %x %x%x%x\n",
+ printk(KERN_WARNING "td: %x %d%c%d %d,%d,%d %x %x%x%x\n",
PTD_GET_CC(ptd), PTD_GET_FA(ptd),
PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
@@ -576,7 +576,7 @@ static inline void dump_ptd_out_data(struct ptd *ptd, u8 * buf)
int k;
if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) {
- printk("-> ");
+ printk(KERN_WARNING "-> ");
for (k = 0; k < PTD_GET_LEN(ptd); ++k)
printk("%02x ", ((u8 *) buf)[k]);
printk("\n");
@@ -588,13 +588,13 @@ static inline void dump_ptd_in_data(struct ptd *ptd, u8 * buf)
int k;
if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) {
- printk("<- ");
+ printk(KERN_WARNING "<- ");
for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
printk("%02x ", ((u8 *) buf)[k]);
printk("\n");
}
if (PTD_GET_LAST(ptd))
- printk("-\n");
+ printk(KERN_WARNING "-\n");
}
#else
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index b899f1a59c2..cd07ea3f0c6 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -644,7 +644,7 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh,
if (urb->dev->speed != USB_SPEED_HIGH) {
/* split */
- ptd->dw5 = __constant_cpu_to_le32(0x1c);
+ ptd->dw5 = cpu_to_le32(0x1c);
if (qh->period >= 32)
period = qh->period / 2;
@@ -819,6 +819,13 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
u32 atl_regs, payload;
u32 buffstatus;
+ /*
+ * When this function is called from the interrupt handler to enqueue
+ * a follow-up packet, the SKIP register gets written and read back
+ * almost immediately. With ISP1761, this register requires a delay of
+ * 195ns between a write and subsequent read (see section 15.1.1.3).
+ */
+ ndelay(195);
skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG);
BUG_ON(!skip_map);
@@ -853,6 +860,13 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
u32 int_regs, payload;
u32 buffstatus;
+ /*
+ * When this function is called from the interrupt handler to enqueue
+ * a follow-up packet, the SKIP register gets written and read back
+ * almost immediately. With ISP1761, this register requires a delay of
+ * 195ns between a write and subsequent read (see section 15.1.1.3).
+ */
+ ndelay(195);
skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG);
BUG_ON(!skip_map);
@@ -1054,7 +1068,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs +
atl_regs, sizeof(ptd));
- ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID);
+ ptd.dw0 |= cpu_to_le32(PTD_VALID);
priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs +
atl_regs, sizeof(ptd));
@@ -2235,9 +2249,10 @@ void deinit_kmem_cache(void)
kmem_cache_destroy(qh_cachep);
}
-struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
- u64 irqflags, struct device *dev, const char *busname,
- unsigned int devflags)
+struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
+ int irq, unsigned long irqflags,
+ struct device *dev, const char *busname,
+ unsigned int devflags)
{
struct usb_hcd *hcd;
struct isp1760_hcd *priv;
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
index a9daea58796..462f4943cb1 100644
--- a/drivers/usb/host/isp1760-hcd.h
+++ b/drivers/usb/host/isp1760-hcd.h
@@ -2,9 +2,10 @@
#define _ISP1760_HCD_H_
/* exports for if */
-struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
- u64 irqflags, struct device *dev, const char *busname,
- unsigned int devflags);
+struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
+ int irq, unsigned long irqflags,
+ struct device *dev, const char *busname,
+ unsigned int devflags);
int init_kmem_once(void);
void deinit_kmem_cache(void);
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 4cf7ca428b3..3fa3a170279 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -10,6 +10,7 @@
#include <linux/usb.h>
#include <linux/io.h>
+#include <linux/platform_device.h>
#include "../core/hcd.h"
#include "isp1760-hcd.h"
@@ -300,39 +301,101 @@ static struct pci_driver isp1761_pci_driver = {
};
#endif
+static int __devinit isp1760_plat_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct usb_hcd *hcd;
+ struct resource *mem_res;
+ struct resource *irq_res;
+ resource_size_t mem_size;
+ unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem_res) {
+ pr_warning("isp1760: Memory resource not available\n");
+ ret = -ENODEV;
+ goto out;
+ }
+ mem_size = resource_size(mem_res);
+ if (!request_mem_region(mem_res->start, mem_size, "isp1760")) {
+ pr_warning("isp1760: Cannot reserve the memory resource\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq_res) {
+ pr_warning("isp1760: IRQ resource not available\n");
+ return -ENODEV;
+ }
+ irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
+
+ hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
+ irqflags, &pdev->dev, dev_name(&pdev->dev), 0);
+ if (IS_ERR(hcd)) {
+ pr_warning("isp1760: Failed to register the HCD device\n");
+ ret = -ENODEV;
+ goto cleanup;
+ }
+
+ pr_info("ISP1760 USB device initialised\n");
+ return ret;
+
+cleanup:
+ release_mem_region(mem_res->start, mem_size);
+out:
+ return ret;
+}
+
+static int __devexit isp1760_plat_remove(struct platform_device *pdev)
+{
+ struct resource *mem_res;
+ resource_size_t mem_size;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mem_size = resource_size(mem_res);
+ release_mem_region(mem_res->start, mem_size);
+
+ return 0;
+}
+
+static struct platform_driver isp1760_plat_driver = {
+ .probe = isp1760_plat_probe,
+ .remove = isp1760_plat_remove,
+ .driver = {
+ .name = "isp1760",
+ },
+};
+
static int __init isp1760_init(void)
{
- int ret;
+ int ret, any_ret = -ENODEV;
init_kmem_once();
+ ret = platform_driver_register(&isp1760_plat_driver);
+ if (!ret)
+ any_ret = 0;
#ifdef CONFIG_PPC_OF
ret = of_register_platform_driver(&isp1760_of_driver);
- if (ret) {
- deinit_kmem_cache();
- return ret;
- }
+ if (!ret)
+ any_ret = 0;
#endif
#ifdef CONFIG_PCI
ret = pci_register_driver(&isp1761_pci_driver);
- if (ret)
- goto unreg_of;
+ if (!ret)
+ any_ret = 0;
#endif
- return ret;
-#ifdef CONFIG_PCI
-unreg_of:
-#endif
-#ifdef CONFIG_PPC_OF
- of_unregister_platform_driver(&isp1760_of_driver);
-#endif
- deinit_kmem_cache();
- return ret;
+ if (any_ret)
+ deinit_kmem_cache();
+ return any_ret;
}
module_init(isp1760_init);
static void __exit isp1760_exit(void)
{
+ platform_driver_unregister(&isp1760_plat_driver);
#ifdef CONFIG_PPC_OF
of_unregister_platform_driver(&isp1760_of_driver);
#endif
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 65a9609f4ad..25db704f3a2 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -593,12 +593,10 @@ static int ohci_run (struct ohci_hcd *ohci)
* to be checked in case boot firmware (BIOS/SMM/...) has set up
* wakeup in a way the bus isn't aware of (e.g., legacy PCI PM).
* If the bus glue detected wakeup capability then it should
- * already be enabled. Either way, if wakeup should be enabled
- * but isn't, we'll enable it now.
+ * already be enabled; if so we'll just enable it again.
*/
- if ((ohci->hc_control & OHCI_CTRL_RWC) != 0
- && !device_can_wakeup(hcd->self.controller))
- device_init_wakeup(hcd->self.controller, 1);
+ if ((ohci->hc_control & OHCI_CTRL_RWC) != 0)
+ device_set_wakeup_capable(hcd->self.controller, 1);
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_OPER:
@@ -999,7 +997,7 @@ MODULE_LICENSE ("GPL");
#define SA1111_DRIVER ohci_hcd_sa1111_driver
#endif
-#ifdef CONFIG_ARCH_S3C2410
+#if defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C64XX)
#include "ohci-s3c2410.c"
#define PLATFORM_DRIVER ohci_hcd_s3c2410_driver
#endif
@@ -1051,7 +1049,8 @@ MODULE_LICENSE ("GPL");
#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
- defined(CONFIG_CPU_SUBTYPE_SH7763)
+ defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786)
#include "ohci-sh.c"
#define PLATFORM_DRIVER ohci_hcd_sh_driver
#endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 4bbddb73abd..f3aaba35e91 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -315,14 +315,14 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
return -ENODEV;
}
- usb_host_ck = clk_get(0, "usb_hhc_ck");
+ usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck");
if (IS_ERR(usb_host_ck))
return PTR_ERR(usb_host_ck);
if (!cpu_is_omap15xx())
- usb_dc_ck = clk_get(0, "usb_dc_ck");
+ usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck");
else
- usb_dc_ck = clk_get(0, "lb_ck");
+ usb_dc_ck = clk_get(&pdev->dev, "lb_ck");
if (IS_ERR(usb_dc_ck)) {
clk_put(usb_host_ck);
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 8b28ae7865b..f9961b4c0da 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -487,8 +487,6 @@ static struct pci_driver ohci_pci_driver = {
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
- .suspend_late = usb_hcd_pci_suspend_late,
- .resume_early = usb_hcd_pci_resume_early,
.resume = usb_hcd_pci_resume,
#endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index f46af7a718d..a68af2dd55c 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -21,9 +21,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
-
-#include <mach/hardware.h>
-#include <mach/usb-control.h>
+#include <plat/usb-control.h>
#define valid_port(idx) ((idx) == 1 || (idx) == 2)
@@ -372,7 +370,7 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
usb_clk = clk_get(&dev->dev, "usb-bus-host");
if (IS_ERR(usb_clk)) {
- dev_err(&dev->dev, "cannot get usb-host clock\n");
+ dev_err(&dev->dev, "cannot get usb-bus-host clock\n");
retval = -ENOENT;
goto err_clk;
}
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 75548f7c716..5ac489ee3da 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -845,14 +845,14 @@ static inline void qh_update(struct oxu_hcd *oxu,
is_out = !(qtd->hw_token & cpu_to_le32(1 << 8));
epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f;
if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) {
- qh->hw_token &= ~__constant_cpu_to_le32(QTD_TOGGLE);
+ qh->hw_token &= ~cpu_to_le32(QTD_TOGGLE);
usb_settoggle(qh->dev, epnum, is_out, 1);
}
}
/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
wmb();
- qh->hw_token &= __constant_cpu_to_le32(QTD_TOGGLE | QTD_STS_PING);
+ qh->hw_token &= cpu_to_le32(QTD_TOGGLE | QTD_STS_PING);
}
/* If it weren't for a common silicon quirk (writing the dummy into the qh
@@ -937,7 +937,7 @@ __acquires(oxu->lock)
struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
/* S-mask in a QH means it's an interrupt urb */
- if ((qh->hw_info2 & __constant_cpu_to_le32(QH_SMASK)) != 0) {
+ if ((qh->hw_info2 & cpu_to_le32(QH_SMASK)) != 0) {
/* ... update hc-wide periodic stats (for usbfs) */
oxu_to_hcd(oxu)->self.bandwidth_int_reqs--;
@@ -981,7 +981,7 @@ static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
-#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
+#define HALT_BIT cpu_to_le32(QTD_STS_HALT)
/* Process and free completed qtds for a qh, returning URBs to drivers.
* Chases up to qh->hw_current. Returns number of completions called,
@@ -1160,7 +1160,7 @@ halt:
/* should be rare for periodic transfers,
* except maybe high bandwidth ...
*/
- if ((__constant_cpu_to_le32(QH_SMASK)
+ if ((cpu_to_le32(QH_SMASK)
& qh->hw_info2) != 0) {
intr_deschedule(oxu, qh);
(void) qh_schedule(oxu, qh);
@@ -1350,7 +1350,7 @@ static struct list_head *qh_urb_transaction(struct oxu_hcd *oxu,
}
/* by default, enable interrupt on urb completion */
- qtd->hw_token |= __constant_cpu_to_le32(QTD_IOC);
+ qtd->hw_token |= cpu_to_le32(QTD_IOC);
return head;
cleanup:
@@ -1539,7 +1539,7 @@ static void qh_link_async(struct oxu_hcd *oxu, struct ehci_qh *qh)
/* qtd completions reported later by interrupt */
}
-#define QH_ADDR_MASK __constant_cpu_to_le32(0x7f)
+#define QH_ADDR_MASK cpu_to_le32(0x7f)
/*
* For control/bulk/interrupt, return QH with these TDs appended.
@@ -2012,7 +2012,7 @@ static void qh_unlink_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh)
* and this qh is active in the current uframe
* (and overlay token SplitXstate is false?)
* THEN
- * qh->hw_info1 |= __constant_cpu_to_le32(1 << 7 "ignore");
+ * qh->hw_info1 |= cpu_to_le32(1 << 7 "ignore");
*/
/* high bandwidth, or otherwise part of every microframe */
@@ -2057,7 +2057,7 @@ static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh)
* active high speed queues may need bigger delays...
*/
if (list_empty(&qh->qtd_list)
- || (__constant_cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0)
+ || (cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0)
wait = 2;
else
wait = 55; /* worst case: 3 * 1024 */
@@ -2183,10 +2183,10 @@ static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh)
qh->start = frame;
/* reset S-frame and (maybe) C-frame masks */
- qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
+ qh->hw_info2 &= cpu_to_le32(~(QH_CMASK | QH_SMASK));
qh->hw_info2 |= qh->period
? cpu_to_le32(1 << uframe)
- : __constant_cpu_to_le32(QH_SMASK);
+ : cpu_to_le32(QH_SMASK);
qh->hw_info2 |= c_mask;
} else
oxu_dbg(oxu, "reused qh %p schedule\n", qh);
@@ -2684,7 +2684,7 @@ static int oxu_reset(struct usb_hcd *hcd)
oxu->urb_len = 0;
/* FIMXE */
- hcd->self.controller->dma_mask = 0UL;
+ hcd->self.controller->dma_mask = NULL;
if (oxu->is_otg) {
oxu->caps = hcd->regs + OXU_OTG_CAP_OFFSET;
diff --git a/drivers/usb/host/oxu210hp.h b/drivers/usb/host/oxu210hp.h
index 8910e271cc7..1c216ad9aad 100644
--- a/drivers/usb/host/oxu210hp.h
+++ b/drivers/usb/host/oxu210hp.h
@@ -235,21 +235,21 @@ struct ehci_qtd {
} __attribute__ ((aligned(32)));
/* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK __constant_cpu_to_le32 (~0x1f)
+#define QTD_MASK cpu_to_le32 (~0x1f)
#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
/* Type tag from {qh, itd, sitd, fstn}->hw_next */
-#define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1))
+#define Q_NEXT_TYPE(dma) ((dma) & cpu_to_le32 (3 << 1))
/* values for that type tag */
-#define Q_TYPE_QH __constant_cpu_to_le32 (1 << 1)
+#define Q_TYPE_QH cpu_to_le32 (1 << 1)
/* next async queue entry, or pointer to interrupt/periodic QH */
#define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH)
/* for periodic/async schedules and qtd lists, mark end of list */
-#define EHCI_LIST_END __constant_cpu_to_le32(1) /* "null pointer" to hw */
+#define EHCI_LIST_END cpu_to_le32(1) /* "null pointer" to hw */
/*
* Entries in periodic shadow table are pointers to one of four kinds
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 75b69847918..033c2846ce5 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -234,7 +234,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
*/
hcc_params = readl(base + EHCI_HCC_PARAMS);
offset = (hcc_params >> 8) & 0xff;
- while (offset && count--) {
+ while (offset && --count) {
u32 cap;
int msec;
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 319041205b5..f1626e58c14 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -660,9 +660,9 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min;
memset(array, 0, sizeof(array));
- switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(ep)) {
case USB_ENDPOINT_XFER_BULK:
- if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ if (usb_endpoint_dir_in(ep))
array[i++] = 4;
else {
array[i++] = 3;
@@ -670,7 +670,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
}
break;
case USB_ENDPOINT_XFER_INT:
- if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+ if (usb_endpoint_dir_in(ep)) {
array[i++] = 6;
array[i++] = 7;
array[i++] = 8;
@@ -678,7 +678,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
array[i++] = 9;
break;
case USB_ENDPOINT_XFER_ISOC:
- if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ if (usb_endpoint_dir_in(ep))
array[i++] = 2;
else
array[i++] = 1;
@@ -928,10 +928,9 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
info.pipenum = get_empty_pipenum(r8a66597, ep);
info.address = get_urb_to_r8a66597_addr(r8a66597, urb);
- info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ info.epnum = usb_endpoint_num(ep);
info.maxpacket = le16_to_cpu(ep->wMaxPacketSize);
- info.type = get_r8a66597_type(ep->bmAttributes
- & USB_ENDPOINT_XFERTYPE_MASK);
+ info.type = get_r8a66597_type(usb_endpoint_type(ep));
info.bufnum = get_bufnum(info.pipenum);
info.buf_bsize = get_buf_bsize(info.pipenum);
if (info.type == R8A66597_BULK) {
@@ -941,7 +940,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
info.interval = get_interval(urb, ep->bInterval);
info.timer_interval = get_timer_interval(urb, ep->bInterval);
}
- if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ if (usb_endpoint_dir_in(ep))
info.dir_in = 1;
else
info.dir_in = 0;
@@ -1014,6 +1013,9 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
+
+ if (r8a66597->bus_suspended)
+ usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
}
/* this function must be called with interrupt disabled */
@@ -1395,7 +1397,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
(int)urb->iso_frame_desc[td->iso_cnt].length);
} else {
buf = (u16 *)(urb->transfer_buffer + urb->actual_length);
- size = min((int)bufsize,
+ size = min_t(u32, bufsize,
urb->transfer_buffer_length - urb->actual_length);
}
@@ -1615,6 +1617,11 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
r8a66597_bclr(r8a66597, DTCHE, INTENB2);
r8a66597_usb_disconnect(r8a66597, 1);
}
+ if (mask2 & BCHG) {
+ r8a66597_write(r8a66597, ~BCHG, INTSTS2);
+ r8a66597_bclr(r8a66597, BCHGE, INTENB2);
+ usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
+ }
}
if (mask1) {
@@ -1630,6 +1637,12 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
r8a66597_bclr(r8a66597, DTCHE, INTENB1);
r8a66597_usb_disconnect(r8a66597, 0);
}
+ if (mask1 & BCHG) {
+ r8a66597_write(r8a66597, ~BCHG, INTSTS1);
+ r8a66597_bclr(r8a66597, BCHGE, INTENB1);
+ usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
+ }
+
if (mask1 & SIGN) {
r8a66597_write(r8a66597, ~SIGN, INTSTS1);
status = get_urb_error(r8a66597, 0);
@@ -2141,7 +2154,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
- rh->port &= (1 << USB_PORT_FEAT_POWER);
+ rh->port &= ~(1 << USB_PORT_FEAT_POWER);
break;
case USB_PORT_FEAT_SUSPEND:
break;
@@ -2213,6 +2226,68 @@ error:
return ret;
}
+#if defined(CONFIG_PM)
+static int r8a66597_bus_suspend(struct usb_hcd *hcd)
+{
+ struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+ int port;
+
+ dbg("%s", __func__);
+
+ for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+ struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+ unsigned long dvstctr_reg = get_dvstctr_reg(port);
+
+ if (!(rh->port & (1 << USB_PORT_FEAT_ENABLE)))
+ continue;
+
+ dbg("suspend port = %d", port);
+ r8a66597_bclr(r8a66597, UACT, dvstctr_reg); /* suspend */
+ rh->port |= 1 << USB_PORT_FEAT_SUSPEND;
+
+ if (rh->dev->udev->do_remote_wakeup) {
+ msleep(3); /* waiting last SOF */
+ r8a66597_bset(r8a66597, RWUPE, dvstctr_reg);
+ r8a66597_write(r8a66597, ~BCHG, get_intsts_reg(port));
+ r8a66597_bset(r8a66597, BCHGE, get_intenb_reg(port));
+ }
+ }
+
+ r8a66597->bus_suspended = 1;
+
+ return 0;
+}
+
+static int r8a66597_bus_resume(struct usb_hcd *hcd)
+{
+ struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+ int port;
+
+ dbg("%s", __func__);
+
+ for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+ struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+ unsigned long dvstctr_reg = get_dvstctr_reg(port);
+
+ if (!(rh->port & (1 << USB_PORT_FEAT_SUSPEND)))
+ continue;
+
+ dbg("resume port = %d", port);
+ rh->port &= ~(1 << USB_PORT_FEAT_SUSPEND);
+ rh->port |= 1 << USB_PORT_FEAT_C_SUSPEND;
+ r8a66597_mdfy(r8a66597, RESUME, RESUME | UACT, dvstctr_reg);
+ msleep(50);
+ r8a66597_mdfy(r8a66597, UACT, RESUME | UACT, dvstctr_reg);
+ }
+
+ return 0;
+
+}
+#else
+#define r8a66597_bus_suspend NULL
+#define r8a66597_bus_resume NULL
+#endif
+
static struct hc_driver r8a66597_hc_driver = {
.description = hcd_name,
.hcd_priv_size = sizeof(struct r8a66597),
@@ -2243,16 +2318,39 @@ static struct hc_driver r8a66597_hc_driver = {
*/
.hub_status_data = r8a66597_hub_status_data,
.hub_control = r8a66597_hub_control,
+ .bus_suspend = r8a66597_bus_suspend,
+ .bus_resume = r8a66597_bus_resume,
};
#if defined(CONFIG_PM)
static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
{
+ struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
+ int port;
+
+ dbg("%s", __func__);
+
+ disable_controller(r8a66597);
+
+ for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+ struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+
+ rh->port = 0x00000000;
+ }
+
return 0;
}
static int r8a66597_resume(struct platform_device *pdev)
{
+ struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
+ struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597);
+
+ dbg("%s", __func__);
+
+ enable_controller(r8a66597);
+ usb_root_hub_lost_power(hcd->self.root_hub);
+
return 0;
}
#else /* if defined(CONFIG_PM) */
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h
index ecacde4d69b..f49208f1bb7 100644
--- a/drivers/usb/host/r8a66597.h
+++ b/drivers/usb/host/r8a66597.h
@@ -504,6 +504,8 @@ struct r8a66597 {
struct list_head child_device;
unsigned long child_connect_map[4];
+
+ unsigned bus_suspended:1;
};
static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd)
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index e106e9d48d4..a949259f18b 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -230,7 +230,7 @@ static void in_packet(
writeb(usb_pipedevice(urb->pipe), data_reg);
sl811_write(sl811, bank + SL11H_HOSTCTLREG, control);
- ep->length = min((int)len,
+ ep->length = min_t(u32, len,
urb->transfer_buffer_length - urb->actual_length);
PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "",
!!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len);
@@ -255,7 +255,7 @@ static void out_packet(
buf = urb->transfer_buffer + urb->actual_length;
prefetch(buf);
- len = min((int)ep->maxpacket,
+ len = min_t(u32, ep->maxpacket,
urb->transfer_buffer_length - urb->actual_length);
if (!(control & SL11H_HCTLMASK_ISOCH)
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 20cc58b9780..e52b954dda4 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -118,7 +118,9 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
}
out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : ""));
- out += sprintf(out, " Actlen=%d", urbp->urb->actual_length);
+ out += sprintf(out, " Actlen=%d%s", urbp->urb->actual_length,
+ (urbp->qh->type == USB_ENDPOINT_XFER_CONTROL ?
+ "-8" : ""));
if (urbp->urb->unlinked)
out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked);
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 4e221060f58..cf5e4cf7ea4 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -942,8 +942,6 @@ static struct pci_driver uhci_pci_driver = {
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
- .suspend_late = usb_hcd_pci_suspend_late,
- .resume_early = usb_hcd_pci_resume_early,
.resume = usb_hcd_pci_resume,
#endif /* PM */
};
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 7d01c5677f9..26bd1b2bcbf 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -73,11 +73,11 @@
#define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
#define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
-#define UHCI_PTR_BITS __constant_cpu_to_le32(0x000F)
-#define UHCI_PTR_TERM __constant_cpu_to_le32(0x0001)
-#define UHCI_PTR_QH __constant_cpu_to_le32(0x0002)
-#define UHCI_PTR_DEPTH __constant_cpu_to_le32(0x0004)
-#define UHCI_PTR_BREADTH __constant_cpu_to_le32(0x0000)
+#define UHCI_PTR_BITS cpu_to_le32(0x000F)
+#define UHCI_PTR_TERM cpu_to_le32(0x0001)
+#define UHCI_PTR_QH cpu_to_le32(0x0002)
+#define UHCI_PTR_DEPTH cpu_to_le32(0x0004)
+#define UHCI_PTR_BREADTH cpu_to_le32(0x0000)
#define UHCI_NUMFRAMES 1024 /* in the frame list [array] */
#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 5631d89c873..3e5807d14ff 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -402,7 +402,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
/* Otherwise all the toggles in the URB have to be switched */
} else {
list_for_each_entry(td, &urbp->td_list, list) {
- td->token ^= __constant_cpu_to_le32(
+ td->token ^= cpu_to_le32(
TD_TOKEN_TOGGLE);
toggle ^= 1;
}
@@ -883,7 +883,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
wmb();
- qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
+ qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE);
qh->dummy_td = td;
/* Low-speed transfers get a different queue, and won't hog the bus.
@@ -899,8 +899,6 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
}
if (qh->state != QH_STATE_ACTIVE)
qh->skel = skel;
-
- urb->actual_length = -8; /* Account for the SETUP packet */
return 0;
nomem:
@@ -1003,7 +1001,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
* fast side but not enough to justify delaying an interrupt
* more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT
* flag setting. */
- td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
+ td->status |= cpu_to_le32(TD_CTRL_IOC);
/*
* Build the new dummy TD and activate the old one
@@ -1015,7 +1013,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
wmb();
- qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
+ qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE);
qh->dummy_td = td;
usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
@@ -1317,7 +1315,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
}
/* Set the interrupt-on-completion flag on the last packet. */
- td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
+ td->status |= cpu_to_le32(TD_CTRL_IOC);
/* Add the TDs to the frame list */
frame = urb->start_frame;
@@ -1494,11 +1492,10 @@ __acquires(uhci->lock)
if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
- /* urb->actual_length < 0 means the setup transaction didn't
- * complete successfully. Either it failed or the URB was
- * unlinked first. Regardless, don't confuse people with a
- * negative length. */
- urb->actual_length = max(urb->actual_length, 0);
+ /* Subtract off the length of the SETUP packet from
+ * urb->actual_length.
+ */
+ urb->actual_length -= min_t(u32, 8, urb->actual_length);
}
/* When giving back the first URB in an Isochronous queue,
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 577c0d29849..958751ccea4 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -170,12 +170,17 @@ void asl_stop(struct whc *whc)
void asl_update(struct whc *whc, uint32_t wusbcmd)
{
struct wusbhc *wusbhc = &whc->wusbhc;
+ long t;
mutex_lock(&wusbhc->mutex);
if (wusbhc->active) {
whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
- wait_event(whc->async_list_wq,
- (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0);
+ t = wait_event_timeout(
+ whc->async_list_wq,
+ (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0,
+ msecs_to_jiffies(1000));
+ if (t == 0)
+ whc_hw_error(whc, "ASL update timeout");
}
mutex_unlock(&wusbhc->mutex);
}
@@ -222,13 +227,13 @@ void scan_async_work(struct work_struct *work)
* Now that the ASL is updated, complete the removal of any
* removed qsets.
*/
- spin_lock(&whc->lock);
+ spin_lock_irq(&whc->lock);
list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) {
qset_remove_complete(whc, qset);
}
- spin_unlock(&whc->lock);
+ spin_unlock_irq(&whc->lock);
}
/**
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
index d498e720321..6afa2e37916 100644
--- a/drivers/usb/host/whci/hw.c
+++ b/drivers/usb/host/whci/hw.c
@@ -87,3 +87,18 @@ out:
return ret;
}
+
+/**
+ * whc_hw_error - recover from a hardware error
+ * @whc: the WHCI HC that broke.
+ * @reason: a description of the failure.
+ *
+ * Recover from broken hardware with a full reset.
+ */
+void whc_hw_error(struct whc *whc, const char *reason)
+{
+ struct wusbhc *wusbhc = &whc->wusbhc;
+
+ dev_err(&whc->umc->dev, "hardware error: %s\n", reason);
+ wusbhc_reset_all(wusbhc);
+}
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index 2ae5abf69a6..df8b85f0709 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -183,12 +183,17 @@ void pzl_stop(struct whc *whc)
void pzl_update(struct whc *whc, uint32_t wusbcmd)
{
struct wusbhc *wusbhc = &whc->wusbhc;
+ long t;
mutex_lock(&wusbhc->mutex);
if (wusbhc->active) {
whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
- wait_event(whc->periodic_list_wq,
- (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0);
+ t = wait_event_timeout(
+ whc->periodic_list_wq,
+ (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0,
+ msecs_to_jiffies(1000));
+ if (t == 0)
+ whc_hw_error(whc, "PZL update timeout");
}
mutex_unlock(&wusbhc->mutex);
}
@@ -250,13 +255,13 @@ void scan_periodic_work(struct work_struct *work)
* Now that the PZL is updated, complete the removal of any
* removed qsets.
*/
- spin_lock(&whc->lock);
+ spin_lock_irq(&whc->lock);
list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) {
qset_remove_complete(whc, qset);
}
- spin_unlock(&whc->lock);
+ spin_unlock_irq(&whc->lock);
}
/**
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index 0f3540f04f5..d3543a181dc 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -137,6 +137,7 @@ void whc_clean_up(struct whc *whc);
/* hw.c */
void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val);
int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
+void whc_hw_error(struct whc *whc, const char *reason);
/* wusb.c */
int whc_wusbhc_start(struct wusbhc *wusbhc);
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 878c77ca086..eca355dccf6 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -188,7 +188,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
.bDescriptorType = 0,
.bEndpointAddress = 0x01,
.bmAttributes = 0x02,
- .wMaxPacketSize = __constant_cpu_to_le16(8),
+ .wMaxPacketSize = cpu_to_le16(8),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
@@ -198,7 +198,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
.bDescriptorType = 0,
.bEndpointAddress = 0x82,
.bmAttributes = 0x03,
- .wMaxPacketSize = __constant_cpu_to_le16(8),
+ .wMaxPacketSize = cpu_to_le16(8),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
@@ -208,7 +208,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
.bDescriptorType = 0,
.bEndpointAddress = 0x03,
.bmAttributes = 0x02,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .wMaxPacketSize = cpu_to_le16(64),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
@@ -218,7 +218,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
.bDescriptorType = 0,
.bEndpointAddress = 0x84,
.bmAttributes = 0x02,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .wMaxPacketSize = cpu_to_le16(64),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
@@ -499,6 +499,7 @@ static int mdc800_usb_probe (struct usb_interface *intf,
retval = usb_register_dev(intf, &mdc800_class);
if (retval) {
dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+ mutex_unlock(&mdc800->io_lock);
return -ENODEV;
}
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index e463db5d818..a68d91a11be 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -135,45 +135,6 @@ config USB_CYTHERM
To compile this driver as a module, choose M here: the
module will be called cytherm.
-config USB_PHIDGET
- tristate "USB Phidgets drivers"
- depends on USB
- help
- Say Y here to enable the various drivers for devices from
- Phidgets inc.
-
-config USB_PHIDGETKIT
- tristate "USB PhidgetInterfaceKit support"
- depends on USB_PHIDGET
- help
- Say Y here if you want to connect a PhidgetInterfaceKit USB device
- from Phidgets Inc.
-
- To compile this driver as a module, choose M here: the
- module will be called phidgetkit.
-
-config USB_PHIDGETMOTORCONTROL
- tristate "USB PhidgetMotorControl support"
- depends on USB_PHIDGET
- help
- Say Y here if you want to connect a PhidgetMotorControl USB device
- from Phidgets Inc.
-
- To compile this driver as a module, choose M here: the
- module will be called phidgetmotorcontrol.
-
-config USB_PHIDGETSERVO
- tristate "USB PhidgetServo support"
- depends on USB_PHIDGET
- help
- Say Y here if you want to connect an 1 or 4 Motor PhidgetServo
- servo controller version 2.0 or 3.0.
-
- Phidgets Inc. has a web page at <http://www.phidgets.com/>.
-
- To compile this driver as a module, choose M here: the
- module will be called phidgetservo.
-
config USB_IDMOUSE
tristate "Siemens ID USB Mouse Fingerprint sensor support"
depends on USB
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 1334f7bdd7b..0826aab8303 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -18,10 +18,6 @@ obj-$(CONFIG_USB_LCD) += usblcd.o
obj-$(CONFIG_USB_LD) += ldusb.o
obj-$(CONFIG_USB_LED) += usbled.o
obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o
-obj-$(CONFIG_USB_PHIDGET) += phidget.o
-obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o
-obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o
-obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
obj-$(CONFIG_USB_RIO500) += rio500.o
obj-$(CONFIG_USB_TEST) += usbtest.o
obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index 7b6922e08ed..20352654201 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -376,7 +376,7 @@ static int adu_release(struct inode *inode, struct file *file)
if (dev->open_count <= 0) {
dbg(1," %s : device not opened", __func__);
retval = -ENODEV;
- goto exit;
+ goto unlock;
}
adu_release_internal(dev);
@@ -385,9 +385,9 @@ static int adu_release(struct inode *inode, struct file *file)
if (!dev->open_count) /* ... and we're the last user */
adu_delete(dev);
}
-
-exit:
+unlock:
mutex_unlock(&adutux_mutex);
+exit:
dbg(2," %s : leave, return value %d", __func__, retval);
return retval;
}
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 79a7668ef26..9d0675ed0d4 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -1568,7 +1568,7 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number,
struct u132_target *target = &ftdi->target[ed];
struct u132_command *command = &ftdi->command[
COMMAND_MASK & ftdi->command_next];
- int remaining_length = urb->transfer_buffer_length -
+ u32 remaining_length = urb->transfer_buffer_length -
urb->actual_length;
command->header = 0x82 | (ed << 5);
if (remaining_length == 0) {
@@ -1702,7 +1702,7 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number,
| (address << 0);
command->width = usb_maxpacket(urb->dev, urb->pipe,
usb_pipeout(urb->pipe));
- command->follows = min(1024,
+ command->follows = min_t(u32, 1024,
urb->transfer_buffer_length -
urb->actual_length);
command->value = 0;
@@ -1766,7 +1766,7 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number,
mutex_lock(&ftdi->u132_lock);
command_size = ftdi->command_next - ftdi->command_head;
if (command_size < COMMAND_SIZE) {
- int remaining_length = urb->transfer_buffer_length -
+ u32 remaining_length = urb->transfer_buffer_length -
urb->actual_length;
struct u132_target *target = &ftdi->target[ed];
struct u132_command *command = &ftdi->command[
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 189a9db0350..ad4fb15b5dc 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -57,7 +57,6 @@
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 /* USB Product ID of Machine Test System */
#define USB_VENDOR_ID_VERNIER 0x08f7
-#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
@@ -85,7 +84,6 @@ static struct usb_device_id ld_usb_table [] = {
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) },
- { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
diff --git a/drivers/usb/misc/phidget.c b/drivers/usb/misc/phidget.c
deleted file mode 100644
index 735ed33f4f7..00000000000
--- a/drivers/usb/misc/phidget.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * USB Phidgets class
- *
- * Copyright (C) 2006 Sean Young <sean@mess.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/device.h>
-
-struct class *phidget_class;
-
-static int __init init_phidget(void)
-{
- phidget_class = class_create(THIS_MODULE, "phidget");
-
- if (IS_ERR(phidget_class))
- return PTR_ERR(phidget_class);
-
- return 0;
-}
-
-static void __exit cleanup_phidget(void)
-{
- class_destroy(phidget_class);
-}
-
-EXPORT_SYMBOL_GPL(phidget_class);
-
-module_init(init_phidget);
-module_exit(cleanup_phidget);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sean Young <sean@mess.org>");
-MODULE_DESCRIPTION("Container module for phidget class");
-
diff --git a/drivers/usb/misc/phidget.h b/drivers/usb/misc/phidget.h
deleted file mode 100644
index c4011907d43..00000000000
--- a/drivers/usb/misc/phidget.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * USB Phidgets class
- *
- * Copyright (C) 2006 Sean Young <sean@mess.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-extern struct class *phidget_class;
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
deleted file mode 100644
index cc8e0a926f9..00000000000
--- a/drivers/usb/misc/phidgetkit.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * USB PhidgetInterfaceKit driver 1.0
- *
- * Copyright (C) 2004, 2006 Sean Young <sean@mess.org>
- * Copyright (C) 2005 Daniel Saakes <daniel@saakes.net>
- * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.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 is a driver for the USB PhidgetInterfaceKit.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#include "phidget.h"
-
-#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
-#define DRIVER_DESC "USB PhidgetInterfaceKit Driver"
-
-#define USB_VENDOR_ID_GLAB 0x06c2
-#define USB_DEVICE_ID_INTERFACEKIT004 0x0040
-#define USB_DEVICE_ID_INTERFACEKIT01616 0x0044
-#define USB_DEVICE_ID_INTERFACEKIT888 0x0045
-#define USB_DEVICE_ID_INTERFACEKIT047 0x0051
-#define USB_DEVICE_ID_INTERFACEKIT088 0x0053
-
-#define USB_VENDOR_ID_WISEGROUP 0x0925
-#define USB_DEVICE_ID_INTERFACEKIT884 0x8201
-
-#define MAX_INTERFACES 16
-
-#define URB_INT_SIZE 8
-
-struct driver_interfacekit {
- int sensors;
- int inputs;
- int outputs;
- int has_lcd;
- int amnesiac;
-};
-
-#define ifkit(_sensors, _inputs, _outputs, _lcd, _amnesiac) \
-{ \
- .sensors = _sensors, \
- .inputs = _inputs, \
- .outputs = _outputs, \
- .has_lcd = _lcd, \
- .amnesiac = _amnesiac \
-};
-
-static const struct driver_interfacekit ph_004 = ifkit(0, 0, 4, 0, 0);
-static const struct driver_interfacekit ph_888n = ifkit(8, 8, 8, 0, 1);
-static const struct driver_interfacekit ph_888o = ifkit(8, 8, 8, 0, 0);
-static const struct driver_interfacekit ph_047 = ifkit(0, 4, 7, 1, 0);
-static const struct driver_interfacekit ph_884 = ifkit(8, 8, 4, 0, 0);
-static const struct driver_interfacekit ph_088 = ifkit(0, 8, 8, 1, 0);
-static const struct driver_interfacekit ph_01616 = ifkit(0, 16, 16, 0, 0);
-
-static unsigned long device_no;
-
-struct interfacekit {
- struct usb_device *udev;
- struct usb_interface *intf;
- struct driver_interfacekit *ifkit;
- struct device *dev;
- unsigned long outputs;
- int dev_no;
- u8 inputs[MAX_INTERFACES];
- u16 sensors[MAX_INTERFACES];
- u8 lcd_files_on;
-
- struct urb *irq;
- unsigned char *data;
- dma_addr_t data_dma;
-
- struct delayed_work do_notify;
- struct delayed_work do_resubmit;
- unsigned long input_events;
- unsigned long sensor_events;
-};
-
-static struct usb_device_id id_table[] = {
- {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT004),
- .driver_info = (kernel_ulong_t)&ph_004},
- {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0, 0x814),
- .driver_info = (kernel_ulong_t)&ph_888o},
- {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0x0815, 0xffff),
- .driver_info = (kernel_ulong_t)&ph_888n},
- {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT047),
- .driver_info = (kernel_ulong_t)&ph_047},
- {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088),
- .driver_info = (kernel_ulong_t)&ph_088},
- {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT01616),
- .driver_info = (kernel_ulong_t)&ph_01616},
- {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884),
- .driver_info = (kernel_ulong_t)&ph_884},
- {}
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static int set_outputs(struct interfacekit *kit)
-{
- u8 *buffer;
- int retval;
-
- buffer = kzalloc(4, GFP_KERNEL);
- if (!buffer) {
- dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
- return -ENOMEM;
- }
- buffer[0] = (u8)kit->outputs;
- buffer[1] = (u8)(kit->outputs >> 8);
-
- dev_dbg(&kit->udev->dev, "sending data: 0x%04x\n", (u16)kit->outputs);
-
- retval = usb_control_msg(kit->udev,
- usb_sndctrlpipe(kit->udev, 0),
- 0x09, 0x21, 0x0200, 0x0000, buffer, 4, 2000);
-
- if (retval != 4)
- dev_err(&kit->udev->dev, "usb_control_msg returned %d\n",
- retval);
- kfree(buffer);
-
- if (kit->ifkit->amnesiac)
- schedule_delayed_work(&kit->do_resubmit, HZ / 2);
-
- return retval < 0 ? retval : 0;
-}
-
-static int change_string(struct interfacekit *kit, const char *display, unsigned char row)
-{
- unsigned char *buffer;
- unsigned char *form_buffer;
- int retval = -ENOMEM;
- int i,j, len, buf_ptr;
-
- buffer = kmalloc(8, GFP_KERNEL);
- form_buffer = kmalloc(30, GFP_KERNEL);
- if ((!buffer) || (!form_buffer)) {
- dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
- goto exit;
- }
-
- len = strlen(display);
- if (len > 20)
- len = 20;
-
- dev_dbg(&kit->udev->dev, "Setting LCD line %d to %s\n", row, display);
-
- form_buffer[0] = row * 0x40 + 0x80;
- form_buffer[1] = 0x02;
- buf_ptr = 2;
- for (i = 0; i<len; i++)
- form_buffer[buf_ptr++] = display[i];
-
- for (i = 0; i < (20 - len); i++)
- form_buffer[buf_ptr++] = 0x20;
- form_buffer[buf_ptr++] = 0x01;
- form_buffer[buf_ptr++] = row * 0x40 + 0x80 + strlen(display);
-
- for (i = 0; i < buf_ptr; i += 7) {
- if ((buf_ptr - i) > 7)
- len = 7;
- else
- len = (buf_ptr - i);
- for (j = 0; j < len; j++)
- buffer[j] = form_buffer[i + j];
- buffer[7] = len;
-
- retval = usb_control_msg(kit->udev,
- usb_sndctrlpipe(kit->udev, 0),
- 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
- if (retval < 0)
- goto exit;
- }
-
- retval = 0;
-exit:
- kfree(buffer);
- kfree(form_buffer);
-
- return retval;
-}
-
-#define set_lcd_line(number) \
-static ssize_t lcd_line_##number(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct interfacekit *kit = dev_get_drvdata(dev); \
- change_string(kit, buf, number - 1); \
- return count; \
-}
-
-#define lcd_line_attr(number) \
- __ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number)
-
-set_lcd_line(1);
-set_lcd_line(2);
-
-static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct interfacekit *kit = dev_get_drvdata(dev);
- int enabled;
- unsigned char *buffer;
- int retval = -ENOMEM;
-
- buffer = kzalloc(8, GFP_KERNEL);
- if (!buffer) {
- dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
- goto exit;
- }
-
- if (sscanf(buf, "%d", &enabled) < 1) {
- retval = -EINVAL;
- goto exit;
- }
- if (enabled)
- buffer[0] = 0x01;
- buffer[7] = 0x11;
-
- dev_dbg(&kit->udev->dev, "Setting backlight to %s\n", enabled ? "on" : "off");
-
- retval = usb_control_msg(kit->udev,
- usb_sndctrlpipe(kit->udev, 0),
- 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
- if (retval < 0)
- goto exit;
-
- retval = count;
-exit:
- kfree(buffer);
- return retval;
-}
-
-static struct device_attribute dev_lcd_line_attrs[] = {
- lcd_line_attr(1),
- lcd_line_attr(2),
- __ATTR(backlight, S_IWUGO, NULL, set_backlight)
-};
-
-static void remove_lcd_files(struct interfacekit *kit)
-{
- int i;
-
- if (kit->lcd_files_on) {
- dev_dbg(&kit->udev->dev, "Removing lcd files\n");
-
- for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++)
- device_remove_file(kit->dev, &dev_lcd_line_attrs[i]);
- }
-}
-
-static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct interfacekit *kit = dev_get_drvdata(dev);
- int enable;
- int i, rc;
-
- if (kit->ifkit->has_lcd == 0)
- return -ENODEV;
-
- if (sscanf(buf, "%d", &enable) < 1)
- return -EINVAL;
-
- if (enable) {
- if (!kit->lcd_files_on) {
- dev_dbg(&kit->udev->dev, "Adding lcd files\n");
- for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) {
- rc = device_create_file(kit->dev,
- &dev_lcd_line_attrs[i]);
- if (rc)
- goto out;
- }
- kit->lcd_files_on = 1;
- }
- } else {
- if (kit->lcd_files_on) {
- remove_lcd_files(kit);
- kit->lcd_files_on = 0;
- }
- }
-
- return count;
-out:
- while (i-- > 0)
- device_remove_file(kit->dev, &dev_lcd_line_attrs[i]);
-
- return rc;
-}
-
-static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files);
-
-static void interfacekit_irq(struct urb *urb)
-{
- struct interfacekit *kit = urb->context;
- unsigned char *buffer = kit->data;
- int i, level, sensor;
- int retval;
- int status = urb->status;
-
- switch (status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default: /* error */
- goto resubmit;
- }
-
- /* digital inputs */
- if (kit->ifkit->inputs == 16) {
- for (i=0; i < 8; i++) {
- level = (buffer[0] >> i) & 1;
- if (kit->inputs[i] != level) {
- kit->inputs[i] = level;
- set_bit(i, &kit->input_events);
- }
- level = (buffer[1] >> i) & 1;
- if (kit->inputs[8 + i] != level) {
- kit->inputs[8 + i] = level;
- set_bit(8 + i, &kit->input_events);
- }
- }
- }
- else if (kit->ifkit->inputs == 8) {
- for (i=0; i < 8; i++) {
- level = (buffer[1] >> i) & 1;
- if (kit->inputs[i] != level) {
- kit->inputs[i] = level;
- set_bit(i, &kit->input_events);
- }
- }
- }
-
- /* analog inputs */
- if (kit->ifkit->sensors) {
- sensor = (buffer[0] & 1) ? 4 : 0;
-
- level = buffer[2] + (buffer[3] & 0x0f) * 256;
- if (level != kit->sensors[sensor]) {
- kit->sensors[sensor] = level;
- set_bit(sensor, &kit->sensor_events);
- }
- sensor++;
- level = buffer[4] + (buffer[3] & 0xf0) * 16;
- if (level != kit->sensors[sensor]) {
- kit->sensors[sensor] = level;
- set_bit(sensor, &kit->sensor_events);
- }
- sensor++;
- level = buffer[5] + (buffer[6] & 0x0f) * 256;
- if (level != kit->sensors[sensor]) {
- kit->sensors[sensor] = level;
- set_bit(sensor, &kit->sensor_events);
- }
- sensor++;
- level = buffer[7] + (buffer[6] & 0xf0) * 16;
- if (level != kit->sensors[sensor]) {
- kit->sensors[sensor] = level;
- set_bit(sensor, &kit->sensor_events);
- }
- }
-
- if (kit->input_events || kit->sensor_events)
- schedule_delayed_work(&kit->do_notify, 0);
-
-resubmit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- err("can't resubmit intr, %s-%s/interfacekit0, retval %d",
- kit->udev->bus->bus_name,
- kit->udev->devpath, retval);
-}
-
-static void do_notify(struct work_struct *work)
-{
- struct interfacekit *kit =
- container_of(work, struct interfacekit, do_notify.work);
- int i;
- char sysfs_file[8];
-
- for (i=0; i<kit->ifkit->inputs; i++) {
- if (test_and_clear_bit(i, &kit->input_events)) {
- sprintf(sysfs_file, "input%d", i + 1);
- sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
- }
- }
-
- for (i=0; i<kit->ifkit->sensors; i++) {
- if (test_and_clear_bit(i, &kit->sensor_events)) {
- sprintf(sysfs_file, "sensor%d", i + 1);
- sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
- }
- }
-}
-
-static void do_resubmit(struct work_struct *work)
-{
- struct interfacekit *kit =
- container_of(work, struct interfacekit, do_resubmit.work);
- set_outputs(kit);
-}
-
-#define show_set_output(value) \
-static ssize_t set_output##value(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct interfacekit *kit = dev_get_drvdata(dev); \
- int enable; \
- int retval; \
- \
- if (sscanf(buf, "%d", &enable) < 1) \
- return -EINVAL; \
- \
- if (enable) \
- set_bit(value - 1, &kit->outputs); \
- else \
- clear_bit(value - 1, &kit->outputs); \
- \
- retval = set_outputs(kit); \
- \
- return retval ? retval : count; \
-} \
- \
-static ssize_t show_output##value(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct interfacekit *kit = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\
-}
-
-#define output_attr(value) \
- __ATTR(output##value, S_IWUGO | S_IRUGO, \
- show_output##value, set_output##value)
-
-show_set_output(1);
-show_set_output(2);
-show_set_output(3);
-show_set_output(4);
-show_set_output(5);
-show_set_output(6);
-show_set_output(7);
-show_set_output(8);
-show_set_output(9);
-show_set_output(10);
-show_set_output(11);
-show_set_output(12);
-show_set_output(13);
-show_set_output(14);
-show_set_output(15);
-show_set_output(16);
-
-static struct device_attribute dev_output_attrs[] = {
- output_attr(1), output_attr(2), output_attr(3), output_attr(4),
- output_attr(5), output_attr(6), output_attr(7), output_attr(8),
- output_attr(9), output_attr(10), output_attr(11), output_attr(12),
- output_attr(13), output_attr(14), output_attr(15), output_attr(16)
-};
-
-#define show_input(value) \
-static ssize_t show_input##value(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct interfacekit *kit = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \
-}
-
-#define input_attr(value) \
- __ATTR(input##value, S_IRUGO, show_input##value, NULL)
-
-show_input(1);
-show_input(2);
-show_input(3);
-show_input(4);
-show_input(5);
-show_input(6);
-show_input(7);
-show_input(8);
-show_input(9);
-show_input(10);
-show_input(11);
-show_input(12);
-show_input(13);
-show_input(14);
-show_input(15);
-show_input(16);
-
-static struct device_attribute dev_input_attrs[] = {
- input_attr(1), input_attr(2), input_attr(3), input_attr(4),
- input_attr(5), input_attr(6), input_attr(7), input_attr(8),
- input_attr(9), input_attr(10), input_attr(11), input_attr(12),
- input_attr(13), input_attr(14), input_attr(15), input_attr(16)
-};
-
-#define show_sensor(value) \
-static ssize_t show_sensor##value(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct interfacekit *kit = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \
-}
-
-#define sensor_attr(value) \
- __ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL)
-
-show_sensor(1);
-show_sensor(2);
-show_sensor(3);
-show_sensor(4);
-show_sensor(5);
-show_sensor(6);
-show_sensor(7);
-show_sensor(8);
-
-static struct device_attribute dev_sensor_attrs[] = {
- sensor_attr(1), sensor_attr(2), sensor_attr(3), sensor_attr(4),
- sensor_attr(5), sensor_attr(6), sensor_attr(7), sensor_attr(8)
-};
-
-static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct interfacekit *kit;
- struct driver_interfacekit *ifkit;
- int pipe, maxp, rc = -ENOMEM;
- int bit, value, i;
-
- ifkit = (struct driver_interfacekit *)id->driver_info;
- if (!ifkit)
- return -ENODEV;
-
- interface = intf->cur_altsetting;
- if (interface->desc.bNumEndpoints != 1)
- return -ENODEV;
-
- endpoint = &interface->endpoint[0].desc;
- if (!usb_endpoint_dir_in(endpoint))
- return -ENODEV;
- /*
- * bmAttributes
- */
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- kit = kzalloc(sizeof(*kit), GFP_KERNEL);
- if (!kit)
- goto out;
-
- kit->dev_no = -1;
- kit->ifkit = ifkit;
- kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &kit->data_dma);
- if (!kit->data)
- goto out;
-
- kit->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!kit->irq)
- goto out;
-
- kit->udev = usb_get_dev(dev);
- kit->intf = intf;
- INIT_DELAYED_WORK(&kit->do_notify, do_notify);
- INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit);
- usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data,
- maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
- interfacekit_irq, kit, endpoint->bInterval);
- kit->irq->transfer_dma = kit->data_dma;
- kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- usb_set_intfdata(intf, kit);
-
- do {
- bit = find_first_zero_bit(&device_no, sizeof(device_no));
- value = test_and_set_bit(bit, &device_no);
- } while(value);
- kit->dev_no = bit;
-
- kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0),
- kit, "interfacekit%d", kit->dev_no);
- if (IS_ERR(kit->dev)) {
- rc = PTR_ERR(kit->dev);
- kit->dev = NULL;
- goto out;
- }
-
- if (usb_submit_urb(kit->irq, GFP_KERNEL)) {
- rc = -EIO;
- goto out;
- }
-
- for (i=0; i<ifkit->outputs; i++ ) {
- rc = device_create_file(kit->dev, &dev_output_attrs[i]);
- if (rc)
- goto out2;
- }
-
- for (i=0; i<ifkit->inputs; i++ ) {
- rc = device_create_file(kit->dev, &dev_input_attrs[i]);
- if (rc)
- goto out3;
- }
-
- for (i=0; i<ifkit->sensors; i++ ) {
- rc = device_create_file(kit->dev, &dev_sensor_attrs[i]);
- if (rc)
- goto out4;
- }
-
- if (ifkit->has_lcd) {
- rc = device_create_file(kit->dev, &dev_attr_lcd);
- if (rc)
- goto out4;
-
- }
-
- dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n",
- ifkit->sensors, ifkit->inputs, ifkit->outputs);
-
- return 0;
-
-out4:
- while (i-- > 0)
- device_remove_file(kit->dev, &dev_sensor_attrs[i]);
-
- i = ifkit->inputs;
-out3:
- while (i-- > 0)
- device_remove_file(kit->dev, &dev_input_attrs[i]);
-
- i = ifkit->outputs;
-out2:
- while (i-- > 0)
- device_remove_file(kit->dev, &dev_output_attrs[i]);
-out:
- if (kit) {
- usb_free_urb(kit->irq);
- if (kit->data)
- usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
- if (kit->dev)
- device_unregister(kit->dev);
- if (kit->dev_no >= 0)
- clear_bit(kit->dev_no, &device_no);
-
- kfree(kit);
- }
-
- return rc;
-}
-
-static void interfacekit_disconnect(struct usb_interface *interface)
-{
- struct interfacekit *kit;
- int i;
-
- kit = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
- if (!kit)
- return;
-
- usb_kill_urb(kit->irq);
- usb_free_urb(kit->irq);
- usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma);
-
- cancel_delayed_work(&kit->do_notify);
- cancel_delayed_work(&kit->do_resubmit);
-
- for (i=0; i<kit->ifkit->outputs; i++)
- device_remove_file(kit->dev, &dev_output_attrs[i]);
-
- for (i=0; i<kit->ifkit->inputs; i++)
- device_remove_file(kit->dev, &dev_input_attrs[i]);
-
- for (i=0; i<kit->ifkit->sensors; i++)
- device_remove_file(kit->dev, &dev_sensor_attrs[i]);
-
- if (kit->ifkit->has_lcd) {
- device_remove_file(kit->dev, &dev_attr_lcd);
- remove_lcd_files(kit);
- }
-
- device_unregister(kit->dev);
-
- dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n",
- kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs);
-
- usb_put_dev(kit->udev);
- clear_bit(kit->dev_no, &device_no);
-
- kfree(kit);
-}
-
-static struct usb_driver interfacekit_driver = {
- .name = "phidgetkit",
- .probe = interfacekit_probe,
- .disconnect = interfacekit_disconnect,
- .id_table = id_table
-};
-
-static int __init interfacekit_init(void)
-{
- int retval = 0;
-
- retval = usb_register(&interfacekit_driver);
- if (retval)
- err("usb_register failed. Error number %d", retval);
-
- return retval;
-}
-
-static void __exit interfacekit_exit(void)
-{
- usb_deregister(&interfacekit_driver);
-}
-
-module_init(interfacekit_init);
-module_exit(interfacekit_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c
deleted file mode 100644
index 38088b44349..00000000000
--- a/drivers/usb/misc/phidgetmotorcontrol.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * USB Phidget MotorControl driver
- *
- * Copyright (C) 2006 Sean Young <sean@mess.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#include "phidget.h"
-
-#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
-#define DRIVER_DESC "USB PhidgetMotorControl Driver"
-
-#define USB_VENDOR_ID_GLAB 0x06c2
-#define USB_DEVICE_ID_MOTORCONTROL 0x0058
-
-#define URB_INT_SIZE 8
-
-static unsigned long device_no;
-
-struct motorcontrol {
- struct usb_device *udev;
- struct usb_interface *intf;
- struct device *dev;
- int dev_no;
- u8 inputs[4];
- s8 desired_speed[2];
- s8 speed[2];
- s16 _current[2];
- s8 acceleration[2];
- struct urb *irq;
- unsigned char *data;
- dma_addr_t data_dma;
-
- struct delayed_work do_notify;
- unsigned long input_events;
- unsigned long speed_events;
- unsigned long exceed_events;
-};
-
-static struct usb_device_id id_table[] = {
- { USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_MOTORCONTROL) },
- {}
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static int set_motor(struct motorcontrol *mc, int motor)
-{
- u8 *buffer;
- int speed, speed2, acceleration;
- int retval;
-
- buffer = kzalloc(8, GFP_KERNEL);
- if (!buffer) {
- dev_err(&mc->intf->dev, "%s - out of memory\n", __func__);
- return -ENOMEM;
- }
-
- acceleration = mc->acceleration[motor] * 10;
- /* -127 <= speed <= 127 */
- speed = (mc->desired_speed[motor] * 127) / 100;
- /* -0x7300 <= speed2 <= 0x7300 */
- speed2 = (mc->desired_speed[motor] * 230 * 128) / 100;
-
- buffer[0] = motor;
- buffer[1] = speed;
- buffer[2] = acceleration >> 8;
- buffer[3] = acceleration;
- buffer[4] = speed2 >> 8;
- buffer[5] = speed2;
-
- retval = usb_control_msg(mc->udev,
- usb_sndctrlpipe(mc->udev, 0),
- 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
-
- if (retval != 8)
- dev_err(&mc->intf->dev, "usb_control_msg returned %d\n",
- retval);
- kfree(buffer);
-
- return retval < 0 ? retval : 0;
-}
-
-static void motorcontrol_irq(struct urb *urb)
-{
- struct motorcontrol *mc = urb->context;
- unsigned char *buffer = mc->data;
- int i, level;
- int retval;
- int status = urb->status;;
-
- switch (status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default: /* error */
- goto resubmit;
- }
-
- /* digital inputs */
- for (i=0; i<4; i++) {
- level = (buffer[0] >> i) & 1;
- if (mc->inputs[i] != level) {
- mc->inputs[i] = level;
- set_bit(i, &mc->input_events);
- }
- }
-
- /* motor speed */
- if (buffer[2] == 0) {
- for (i=0; i<2; i++) {
- level = ((s8)buffer[4+i]) * 100 / 127;
- if (mc->speed[i] != level) {
- mc->speed[i] = level;
- set_bit(i, &mc->speed_events);
- }
- }
- } else {
- int index = buffer[3] & 1;
-
- level = ((s8)buffer[4] << 8) | buffer[5];
- level = level * 100 / 29440;
- if (mc->speed[index] != level) {
- mc->speed[index] = level;
- set_bit(index, &mc->speed_events);
- }
-
- level = ((s8)buffer[6] << 8) | buffer[7];
- mc->_current[index] = level * 100 / 1572;
- }
-
- if (buffer[1] & 1)
- set_bit(0, &mc->exceed_events);
-
- if (buffer[1] & 2)
- set_bit(1, &mc->exceed_events);
-
- if (mc->input_events || mc->exceed_events || mc->speed_events)
- schedule_delayed_work(&mc->do_notify, 0);
-
-resubmit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- dev_err(&mc->intf->dev,
- "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n",
- mc->udev->bus->bus_name,
- mc->udev->devpath, retval);
-}
-
-static void do_notify(struct work_struct *work)
-{
- struct motorcontrol *mc =
- container_of(work, struct motorcontrol, do_notify.work);
- int i;
- char sysfs_file[8];
-
- for (i=0; i<4; i++) {
- if (test_and_clear_bit(i, &mc->input_events)) {
- sprintf(sysfs_file, "input%d", i);
- sysfs_notify(&mc->dev->kobj, NULL, sysfs_file);
- }
- }
-
- for (i=0; i<2; i++) {
- if (test_and_clear_bit(i, &mc->speed_events)) {
- sprintf(sysfs_file, "speed%d", i);
- sysfs_notify(&mc->dev->kobj, NULL, sysfs_file);
- }
- }
-
- for (i=0; i<2; i++) {
- if (test_and_clear_bit(i, &mc->exceed_events))
- dev_warn(&mc->intf->dev,
- "motor #%d exceeds 1.5 Amp current limit\n", i);
- }
-}
-
-#define show_set_speed(value) \
-static ssize_t set_speed##value(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct motorcontrol *mc = dev_get_drvdata(dev); \
- int speed; \
- int retval; \
- \
- if (sscanf(buf, "%d", &speed) < 1) \
- return -EINVAL; \
- \
- if (speed < -100 || speed > 100) \
- return -EINVAL; \
- \
- mc->desired_speed[value] = speed; \
- \
- retval = set_motor(mc, value); \
- \
- return retval ? retval : count; \
-} \
- \
-static ssize_t show_speed##value(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct motorcontrol *mc = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%d\n", mc->speed[value]); \
-}
-
-#define speed_attr(value) \
- __ATTR(speed##value, S_IWUGO | S_IRUGO, \
- show_speed##value, set_speed##value)
-
-show_set_speed(0);
-show_set_speed(1);
-
-#define show_set_acceleration(value) \
-static ssize_t set_acceleration##value(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct motorcontrol *mc = dev_get_drvdata(dev); \
- int acceleration; \
- int retval; \
- \
- if (sscanf(buf, "%d", &acceleration) < 1) \
- return -EINVAL; \
- \
- if (acceleration < 0 || acceleration > 100) \
- return -EINVAL; \
- \
- mc->acceleration[value] = acceleration; \
- \
- retval = set_motor(mc, value); \
- \
- return retval ? retval : count; \
-} \
- \
-static ssize_t show_acceleration##value(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct motorcontrol *mc = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%d\n", mc->acceleration[value]); \
-}
-
-#define acceleration_attr(value) \
- __ATTR(acceleration##value, S_IWUGO | S_IRUGO, \
- show_acceleration##value, set_acceleration##value)
-
-show_set_acceleration(0);
-show_set_acceleration(1);
-
-#define show_current(value) \
-static ssize_t show_current##value(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct motorcontrol *mc = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%dmA\n", (int)mc->_current[value]); \
-}
-
-#define current_attr(value) \
- __ATTR(current##value, S_IRUGO, show_current##value, NULL)
-
-show_current(0);
-show_current(1);
-
-#define show_input(value) \
-static ssize_t show_input##value(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct motorcontrol *mc = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%d\n", (int)mc->inputs[value]); \
-}
-
-#define input_attr(value) \
- __ATTR(input##value, S_IRUGO, show_input##value, NULL)
-
-show_input(0);
-show_input(1);
-show_input(2);
-show_input(3);
-
-static struct device_attribute dev_attrs[] = {
- input_attr(0),
- input_attr(1),
- input_attr(2),
- input_attr(3),
- speed_attr(0),
- speed_attr(1),
- acceleration_attr(0),
- acceleration_attr(1),
- current_attr(0),
- current_attr(1)
-};
-
-static int motorcontrol_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct motorcontrol *mc;
- int pipe, maxp, rc = -ENOMEM;
- int bit, value, i;
-
- interface = intf->cur_altsetting;
- if (interface->desc.bNumEndpoints != 1)
- return -ENODEV;
-
- endpoint = &interface->endpoint[0].desc;
- if (!usb_endpoint_dir_in(endpoint))
- return -ENODEV;
-
- /*
- * bmAttributes
- */
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- mc = kzalloc(sizeof(*mc), GFP_KERNEL);
- if (!mc)
- goto out;
-
- mc->dev_no = -1;
- mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &mc->data_dma);
- if (!mc->data)
- goto out;
-
- mc->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!mc->irq)
- goto out;
-
- mc->udev = usb_get_dev(dev);
- mc->intf = intf;
- mc->acceleration[0] = mc->acceleration[1] = 10;
- INIT_DELAYED_WORK(&mc->do_notify, do_notify);
- usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data,
- maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
- motorcontrol_irq, mc, endpoint->bInterval);
- mc->irq->transfer_dma = mc->data_dma;
- mc->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- usb_set_intfdata(intf, mc);
-
- do {
- bit = find_first_zero_bit(&device_no, sizeof(device_no));
- value = test_and_set_bit(bit, &device_no);
- } while(value);
- mc->dev_no = bit;
-
- mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc,
- "motorcontrol%d", mc->dev_no);
- if (IS_ERR(mc->dev)) {
- rc = PTR_ERR(mc->dev);
- mc->dev = NULL;
- goto out;
- }
-
- if (usb_submit_urb(mc->irq, GFP_KERNEL)) {
- rc = -EIO;
- goto out;
- }
-
- for (i=0; i<ARRAY_SIZE(dev_attrs); i++) {
- rc = device_create_file(mc->dev, &dev_attrs[i]);
- if (rc)
- goto out2;
- }
-
- dev_info(&intf->dev, "USB PhidgetMotorControl attached\n");
-
- return 0;
-out2:
- while (i-- > 0)
- device_remove_file(mc->dev, &dev_attrs[i]);
-out:
- if (mc) {
- usb_free_urb(mc->irq);
- if (mc->data)
- usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma);
- if (mc->dev)
- device_unregister(mc->dev);
- if (mc->dev_no >= 0)
- clear_bit(mc->dev_no, &device_no);
-
- kfree(mc);
- }
-
- return rc;
-}
-
-static void motorcontrol_disconnect(struct usb_interface *interface)
-{
- struct motorcontrol *mc;
- int i;
-
- mc = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
- if (!mc)
- return;
-
- usb_kill_urb(mc->irq);
- usb_free_urb(mc->irq);
- usb_buffer_free(mc->udev, URB_INT_SIZE, mc->data, mc->data_dma);
-
- cancel_delayed_work(&mc->do_notify);
-
- for (i=0; i<ARRAY_SIZE(dev_attrs); i++)
- device_remove_file(mc->dev, &dev_attrs[i]);
-
- device_unregister(mc->dev);
-
- usb_put_dev(mc->udev);
- clear_bit(mc->dev_no, &device_no);
- kfree(mc);
-
- dev_info(&interface->dev, "USB PhidgetMotorControl detached\n");
-}
-
-static struct usb_driver motorcontrol_driver = {
- .name = "phidgetmotorcontrol",
- .probe = motorcontrol_probe,
- .disconnect = motorcontrol_disconnect,
- .id_table = id_table
-};
-
-static int __init motorcontrol_init(void)
-{
- int retval = 0;
-
- retval = usb_register(&motorcontrol_driver);
- if (retval)
- err("usb_register failed. Error number %d", retval);
-
- return retval;
-}
-
-static void __exit motorcontrol_exit(void)
-{
- usb_deregister(&motorcontrol_driver);
-}
-
-module_init(motorcontrol_init);
-module_exit(motorcontrol_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
deleted file mode 100644
index bef6fe16364..00000000000
--- a/drivers/usb/misc/phidgetservo.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * USB PhidgetServo driver 1.0
- *
- * Copyright (C) 2004, 2006 Sean Young <sean@mess.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This is a driver for the USB PhidgetServo version 2.0 and 3.0 servo
- * controllers available at: http://www.phidgets.com/
- *
- * Note that the driver takes input as: degrees.minutes
- *
- * CAUTION: Generally you should use 0 < degrees < 180 as anything else
- * is probably beyond the range of your servo and may damage it.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#include "phidget.h"
-
-#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
-#define DRIVER_DESC "USB PhidgetServo Driver"
-
-#define VENDOR_ID_GLAB 0x06c2
-#define DEVICE_ID_GLAB_PHIDGETSERVO_QUAD 0x0038
-#define DEVICE_ID_GLAB_PHIDGETSERVO_UNI 0x0039
-
-#define VENDOR_ID_WISEGROUP 0x0925
-#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD 0x8101
-#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI 0x8104
-
-#define SERVO_VERSION_30 0x01
-#define SERVO_COUNT_QUAD 0x02
-
-static struct usb_device_id id_table[] = {
- {
- USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_QUAD),
- .driver_info = SERVO_VERSION_30 | SERVO_COUNT_QUAD
- },
- {
- USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_UNI),
- .driver_info = SERVO_VERSION_30
- },
- {
- USB_DEVICE(VENDOR_ID_WISEGROUP,
- VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD),
- .driver_info = SERVO_COUNT_QUAD
- },
- {
- USB_DEVICE(VENDOR_ID_WISEGROUP,
- VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI),
- .driver_info = 0
- },
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static int unsigned long device_no;
-
-struct phidget_servo {
- struct usb_device *udev;
- struct device *dev;
- int dev_no;
- ulong type;
- int pulse[4];
- int degrees[4];
- int minutes[4];
-};
-
-static int
-change_position_v30(struct phidget_servo *servo, int servo_no, int degrees,
- int minutes)
-{
- int retval;
- unsigned char *buffer;
-
- if (degrees < -23 || degrees > 362)
- return -EINVAL;
-
- buffer = kmalloc(6, GFP_KERNEL);
- if (!buffer) {
- dev_err(&servo->udev->dev, "%s - out of memory\n",
- __func__);
- return -ENOMEM;
- }
-
- /*
- * pulse = 0 - 4095
- * angle = 0 - 180 degrees
- *
- * pulse = angle * 10.6 + 243.8
- */
- servo->pulse[servo_no] = ((degrees*60 + minutes)*106 + 2438*60)/600;
- servo->degrees[servo_no]= degrees;
- servo->minutes[servo_no]= minutes;
-
- /*
- * The PhidgetServo v3.0 is controlled by sending 6 bytes,
- * 4 * 12 bits for each servo.
- *
- * low = lower 8 bits pulse
- * high = higher 4 bits pulse
- *
- * offset bits
- * +---+-----------------+
- * | 0 | low 0 |
- * +---+--------+--------+
- * | 1 | high 1 | high 0 |
- * +---+--------+--------+
- * | 2 | low 1 |
- * +---+-----------------+
- * | 3 | low 2 |
- * +---+--------+--------+
- * | 4 | high 3 | high 2 |
- * +---+--------+--------+
- * | 5 | low 3 |
- * +---+-----------------+
- */
-
- buffer[0] = servo->pulse[0] & 0xff;
- buffer[1] = (servo->pulse[0] >> 8 & 0x0f)
- | (servo->pulse[1] >> 4 & 0xf0);
- buffer[2] = servo->pulse[1] & 0xff;
- buffer[3] = servo->pulse[2] & 0xff;
- buffer[4] = (servo->pulse[2] >> 8 & 0x0f)
- | (servo->pulse[3] >> 4 & 0xf0);
- buffer[5] = servo->pulse[3] & 0xff;
-
- dev_dbg(&servo->udev->dev,
- "data: %02x %02x %02x %02x %02x %02x\n",
- buffer[0], buffer[1], buffer[2],
- buffer[3], buffer[4], buffer[5]);
-
- retval = usb_control_msg(servo->udev,
- usb_sndctrlpipe(servo->udev, 0),
- 0x09, 0x21, 0x0200, 0x0000, buffer, 6, 2000);
-
- kfree(buffer);
-
- return retval;
-}
-
-static int
-change_position_v20(struct phidget_servo *servo, int servo_no, int degrees,
- int minutes)
-{
- int retval;
- unsigned char *buffer;
-
- if (degrees < -23 || degrees > 278)
- return -EINVAL;
-
- buffer = kmalloc(2, GFP_KERNEL);
- if (!buffer) {
- dev_err(&servo->udev->dev, "%s - out of memory\n",
- __func__);
- return -ENOMEM;
- }
-
- /*
- * angle = 0 - 180 degrees
- * pulse = angle + 23
- */
- servo->pulse[servo_no]= degrees + 23;
- servo->degrees[servo_no]= degrees;
- servo->minutes[servo_no]= 0;
-
- /*
- * The PhidgetServo v2.0 is controlled by sending two bytes. The
- * first byte is the servo number xor'ed with 2:
- *
- * servo 0 = 2
- * servo 1 = 3
- * servo 2 = 0
- * servo 3 = 1
- *
- * The second byte is the position.
- */
-
- buffer[0] = servo_no ^ 2;
- buffer[1] = servo->pulse[servo_no];
-
- dev_dbg(&servo->udev->dev, "data: %02x %02x\n", buffer[0], buffer[1]);
-
- retval = usb_control_msg(servo->udev,
- usb_sndctrlpipe(servo->udev, 0),
- 0x09, 0x21, 0x0200, 0x0000, buffer, 2, 2000);
-
- kfree(buffer);
-
- return retval;
-}
-
-#define show_set(value) \
-static ssize_t set_servo##value (struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- int degrees, minutes, retval; \
- struct phidget_servo *servo = dev_get_drvdata(dev); \
- \
- minutes = 0; \
- /* must at least convert degrees */ \
- if (sscanf(buf, "%d.%d", &degrees, &minutes) < 1) { \
- return -EINVAL; \
- } \
- \
- if (minutes < 0 || minutes > 59) \
- return -EINVAL; \
- \
- if (servo->type & SERVO_VERSION_30) \
- retval = change_position_v30(servo, value, degrees, \
- minutes); \
- else \
- retval = change_position_v20(servo, value, degrees, \
- minutes); \
- \
- return retval < 0 ? retval : count; \
-} \
- \
-static ssize_t show_servo##value (struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct phidget_servo *servo = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%d.%02d\n", servo->degrees[value], \
- servo->minutes[value]); \
-}
-
-#define servo_attr(value) \
- __ATTR(servo##value, S_IWUGO | S_IRUGO, \
- show_servo##value, set_servo##value)
-show_set(0);
-show_set(1);
-show_set(2);
-show_set(3);
-
-static struct device_attribute dev_attrs[] = {
- servo_attr(0), servo_attr(1), servo_attr(2), servo_attr(3)
-};
-
-static int
-servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(interface);
- struct phidget_servo *dev;
- int bit, value, rc;
- int servo_count, i;
-
- dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&interface->dev, "%s - out of memory\n", __func__);
- rc = -ENOMEM;
- goto out;
- }
-
- dev->udev = usb_get_dev(udev);
- dev->type = id->driver_info;
- dev->dev_no = -1;
- usb_set_intfdata(interface, dev);
-
- do {
- bit = find_first_zero_bit(&device_no, sizeof(device_no));
- value = test_and_set_bit(bit, &device_no);
- } while (value);
- dev->dev_no = bit;
-
- dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0),
- dev, "servo%d", dev->dev_no);
- if (IS_ERR(dev->dev)) {
- rc = PTR_ERR(dev->dev);
- dev->dev = NULL;
- goto out;
- }
-
- servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1;
-
- for (i=0; i<servo_count; i++) {
- rc = device_create_file(dev->dev, &dev_attrs[i]);
- if (rc)
- goto out2;
- }
-
- dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n",
- servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2);
-
- if (!(dev->type & SERVO_VERSION_30))
- dev_info(&interface->dev,
- "WARNING: v2.0 not tested! Please report if it works.\n");
-
- return 0;
-out2:
- while (i-- > 0)
- device_remove_file(dev->dev, &dev_attrs[i]);
-out:
- if (dev) {
- if (dev->dev)
- device_unregister(dev->dev);
- if (dev->dev_no >= 0)
- clear_bit(dev->dev_no, &device_no);
-
- kfree(dev);
- }
-
- return rc;
-}
-
-static void
-servo_disconnect(struct usb_interface *interface)
-{
- struct phidget_servo *dev;
- int servo_count, i;
-
- dev = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
-
- if (!dev)
- return;
-
- servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1;
-
- for (i=0; i<servo_count; i++)
- device_remove_file(dev->dev, &dev_attrs[i]);
-
- device_unregister(dev->dev);
- usb_put_dev(dev->udev);
-
- dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n",
- servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2);
-
- clear_bit(dev->dev_no, &device_no);
- kfree(dev);
-}
-
-static struct usb_driver servo_driver = {
- .name = "phidgetservo",
- .probe = servo_probe,
- .disconnect = servo_disconnect,
- .id_table = id_table
-};
-
-static int __init
-phidget_servo_init(void)
-{
- int retval;
-
- retval = usb_register(&servo_driver);
- if (retval)
- err("usb_register failed. Error number %d", retval);
-
- return retval;
-}
-
-static void __exit
-phidget_servo_exit(void)
-{
- usb_deregister(&servo_driver);
-}
-
-module_init(phidget_servo_init);
-module_exit(phidget_servo_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c
index 63dff9ba73c..f26ea8dc157 100644
--- a/drivers/usb/misc/vstusb.c
+++ b/drivers/usb/misc/vstusb.c
@@ -401,6 +401,7 @@ static ssize_t vstusb_write(struct file *file, const char __user *buffer,
}
if (copy_from_user(buf, buffer, count)) {
+ mutex_unlock(&vstdev->lock);
dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__);
retval = -EFAULT;
goto exit;
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index e06810aef2d..f8d9045d668 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -37,9 +37,13 @@
#define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
+/* #9 was MON_IOCT_SETAPI */
+#define MON_IOCX_GETX _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get)
+
#ifdef CONFIG_COMPAT
#define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32)
#define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32)
+#define MON_IOCX_GETX32 _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get32)
#endif
/*
@@ -91,7 +95,29 @@ struct mon_bin_hdr {
int status;
unsigned int len_urb; /* Length of data (submitted or actual) */
unsigned int len_cap; /* Delivered length */
- unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
+ union {
+ unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
+ struct iso_rec {
+ int error_count;
+ int numdesc;
+ } iso;
+ } s;
+ int interval;
+ int start_frame;
+ unsigned int xfer_flags;
+ unsigned int ndesc; /* Actual number of ISO descriptors */
+};
+
+/*
+ * ISO vector, packed into the head of data stream.
+ * This has to take 16 bytes to make sure that the end of buffer
+ * wrap is not happening in the middle of a descriptor.
+ */
+struct mon_bin_isodesc {
+ int iso_status;
+ unsigned int iso_off;
+ unsigned int iso_len;
+ u32 _pad;
};
/* per file statistic */
@@ -101,7 +127,7 @@ struct mon_bin_stats {
};
struct mon_bin_get {
- struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */
+ struct mon_bin_hdr __user *hdr; /* Can be 48 bytes or 64. */
void __user *data;
size_t alloc; /* Length of data (can be zero) */
};
@@ -130,6 +156,11 @@ struct mon_bin_mfetch32 {
#define PKT_ALIGN 64
#define PKT_SIZE 64
+#define PKT_SZ_API0 48 /* API 0 (2.6.20) size */
+#define PKT_SZ_API1 64 /* API 1 size: extra fields */
+
+#define ISODESC_MAX 128 /* Same number as usbfs allows, 2048 bytes. */
+
/* max number of USB bus supported */
#define MON_BIN_MAX_MINOR 128
@@ -359,12 +390,8 @@ static inline char mon_bin_get_setup(unsigned char *setupb,
const struct urb *urb, char ev_type)
{
- if (!usb_endpoint_xfer_control(&urb->ep->desc) || ev_type != 'S')
- return '-';
-
if (urb->setup_packet == NULL)
return 'Z';
-
memcpy(setupb, urb->setup_packet, SETUP_LEN);
return 0;
}
@@ -386,6 +413,26 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp,
return 0;
}
+static void mon_bin_get_isodesc(const struct mon_reader_bin *rp,
+ unsigned int offset, struct urb *urb, char ev_type, unsigned int ndesc)
+{
+ struct mon_bin_isodesc *dp;
+ struct usb_iso_packet_descriptor *fp;
+
+ fp = urb->iso_frame_desc;
+ while (ndesc-- != 0) {
+ dp = (struct mon_bin_isodesc *)
+ (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE);
+ dp->iso_status = fp->status;
+ dp->iso_off = fp->offset;
+ dp->iso_len = (ev_type == 'S') ? fp->length : fp->actual_length;
+ dp->_pad = 0;
+ if ((offset += sizeof(struct mon_bin_isodesc)) >= rp->b_size)
+ offset = 0;
+ fp++;
+ }
+}
+
static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
char ev_type, int status)
{
@@ -395,6 +442,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
unsigned int urb_length;
unsigned int offset;
unsigned int length;
+ unsigned int ndesc, lendesc;
unsigned char dir;
struct mon_bin_hdr *ep;
char data_tag = 0;
@@ -406,6 +454,19 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
/*
* Find the maximum allowable length, then allocate space.
*/
+ if (usb_endpoint_xfer_isoc(epd)) {
+ if (urb->number_of_packets < 0) {
+ ndesc = 0;
+ } else if (urb->number_of_packets >= ISODESC_MAX) {
+ ndesc = ISODESC_MAX;
+ } else {
+ ndesc = urb->number_of_packets;
+ }
+ } else {
+ ndesc = 0;
+ }
+ lendesc = ndesc*sizeof(struct mon_bin_isodesc);
+
urb_length = (ev_type == 'S') ?
urb->transfer_buffer_length : urb->actual_length;
length = urb_length;
@@ -428,10 +489,12 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
dir = 0;
}
- if (rp->mmap_active)
- offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE);
- else
- offset = mon_buff_area_alloc(rp, length + PKT_SIZE);
+ if (rp->mmap_active) {
+ offset = mon_buff_area_alloc_contiguous(rp,
+ length + PKT_SIZE + lendesc);
+ } else {
+ offset = mon_buff_area_alloc(rp, length + PKT_SIZE + lendesc);
+ }
if (offset == ~0) {
rp->cnt_lost++;
spin_unlock_irqrestore(&rp->b_lock, flags);
@@ -455,9 +518,31 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
ep->ts_usec = ts.tv_usec;
ep->status = status;
ep->len_urb = urb_length;
- ep->len_cap = length;
+ ep->len_cap = length + lendesc;
+ ep->xfer_flags = urb->transfer_flags;
+
+ if (usb_endpoint_xfer_int(epd)) {
+ ep->interval = urb->interval;
+ } else if (usb_endpoint_xfer_isoc(epd)) {
+ ep->interval = urb->interval;
+ ep->start_frame = urb->start_frame;
+ ep->s.iso.error_count = urb->error_count;
+ ep->s.iso.numdesc = urb->number_of_packets;
+ }
+
+ if (usb_endpoint_xfer_control(epd) && ev_type == 'S') {
+ ep->flag_setup = mon_bin_get_setup(ep->s.setup, urb, ev_type);
+ } else {
+ ep->flag_setup = '-';
+ }
+
+ if (ndesc != 0) {
+ ep->ndesc = ndesc;
+ mon_bin_get_isodesc(rp, offset, urb, ev_type, ndesc);
+ if ((offset += lendesc) >= rp->b_size)
+ offset -= rp->b_size;
+ }
- ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type);
if (length != 0) {
ep->flag_data = mon_bin_get_data(rp, offset, urb, length);
if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */
@@ -591,7 +676,8 @@ err_alloc:
* Returns zero or error.
*/
static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp,
- struct mon_bin_hdr __user *hdr, void __user *data, unsigned int nbytes)
+ struct mon_bin_hdr __user *hdr, unsigned int hdrbytes,
+ void __user *data, unsigned int nbytes)
{
unsigned long flags;
struct mon_bin_hdr *ep;
@@ -608,7 +694,7 @@ static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp,
ep = MON_OFF2HDR(rp, rp->b_out);
- if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) {
+ if (copy_to_user(hdr, ep, hdrbytes)) {
mutex_unlock(&rp->fetch_lock);
return -EFAULT;
}
@@ -656,6 +742,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos)
{
struct mon_reader_bin *rp = file->private_data;
+ unsigned int hdrbytes = PKT_SZ_API0;
unsigned long flags;
struct mon_bin_hdr *ep;
unsigned int offset;
@@ -673,8 +760,8 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
ep = MON_OFF2HDR(rp, rp->b_out);
- if (rp->b_read < sizeof(struct mon_bin_hdr)) {
- step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read);
+ if (rp->b_read < hdrbytes) {
+ step_len = min(nbytes, (size_t)(hdrbytes - rp->b_read));
ptr = ((char *)ep) + rp->b_read;
if (step_len && copy_to_user(buf, ptr, step_len)) {
mutex_unlock(&rp->fetch_lock);
@@ -686,13 +773,13 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
done += step_len;
}
- if (rp->b_read >= sizeof(struct mon_bin_hdr)) {
+ if (rp->b_read >= hdrbytes) {
step_len = ep->len_cap;
- step_len -= rp->b_read - sizeof(struct mon_bin_hdr);
+ step_len -= rp->b_read - hdrbytes;
if (step_len > nbytes)
step_len = nbytes;
offset = rp->b_out + PKT_SIZE;
- offset += rp->b_read - sizeof(struct mon_bin_hdr);
+ offset += rp->b_read - hdrbytes;
if (offset >= rp->b_size)
offset -= rp->b_size;
if (copy_from_buf(rp, offset, buf, step_len)) {
@@ -708,7 +795,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
/*
* Check if whole packet was read, and if so, jump to the next one.
*/
- if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) {
+ if (rp->b_read >= hdrbytes + ep->len_cap) {
spin_lock_irqsave(&rp->b_lock, flags);
mon_buff_area_free(rp, PKT_SIZE + ep->len_cap);
spin_unlock_irqrestore(&rp->b_lock, flags);
@@ -907,6 +994,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
break;
case MON_IOCX_GET:
+ case MON_IOCX_GETX:
{
struct mon_bin_get getb;
@@ -916,26 +1004,12 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
if (getb.alloc > 0x10000000) /* Want to cast to u32 */
return -EINVAL;
- ret = mon_bin_get_event(file, rp,
- getb.hdr, getb.data, (unsigned int)getb.alloc);
+ ret = mon_bin_get_event(file, rp, getb.hdr,
+ (cmd == MON_IOCX_GET)? PKT_SZ_API0: PKT_SZ_API1,
+ getb.data, (unsigned int)getb.alloc);
}
break;
-#ifdef CONFIG_COMPAT
- case MON_IOCX_GET32: {
- struct mon_bin_get32 getb;
-
- if (copy_from_user(&getb, (void __user *)arg,
- sizeof(struct mon_bin_get32)))
- return -EFAULT;
-
- ret = mon_bin_get_event(file, rp,
- compat_ptr(getb.hdr32), compat_ptr(getb.data32),
- getb.alloc32);
- }
- break;
-#endif
-
case MON_IOCX_MFETCH:
{
struct mon_bin_mfetch mfetch;
@@ -962,7 +1036,59 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
}
break;
+ case MON_IOCG_STATS: {
+ struct mon_bin_stats __user *sp;
+ unsigned int nevents;
+ unsigned int ndropped;
+
+ spin_lock_irqsave(&rp->b_lock, flags);
+ ndropped = rp->cnt_lost;
+ rp->cnt_lost = 0;
+ spin_unlock_irqrestore(&rp->b_lock, flags);
+ nevents = mon_bin_queued(rp);
+
+ sp = (struct mon_bin_stats __user *)arg;
+ if (put_user(rp->cnt_lost, &sp->dropped))
+ return -EFAULT;
+ if (put_user(nevents, &sp->queued))
+ return -EFAULT;
+
+ }
+ break;
+
+ default:
+ return -ENOTTY;
+ }
+
+ return ret;
+}
+
#ifdef CONFIG_COMPAT
+static long mon_bin_compat_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct mon_reader_bin *rp = file->private_data;
+ int ret;
+
+ switch (cmd) {
+
+ case MON_IOCX_GET32:
+ case MON_IOCX_GETX32:
+ {
+ struct mon_bin_get32 getb;
+
+ if (copy_from_user(&getb, (void __user *)arg,
+ sizeof(struct mon_bin_get32)))
+ return -EFAULT;
+
+ ret = mon_bin_get_event(file, rp, compat_ptr(getb.hdr32),
+ (cmd == MON_IOCX_GET32)? PKT_SZ_API0: PKT_SZ_API1,
+ compat_ptr(getb.data32), getb.alloc32);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+
case MON_IOCX_MFETCH32:
{
struct mon_bin_mfetch32 mfetch;
@@ -986,37 +1112,25 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
return ret;
if (put_user(ret, &uptr->nfetch32))
return -EFAULT;
- ret = 0;
}
- break;
-#endif
-
- case MON_IOCG_STATS: {
- struct mon_bin_stats __user *sp;
- unsigned int nevents;
- unsigned int ndropped;
-
- spin_lock_irqsave(&rp->b_lock, flags);
- ndropped = rp->cnt_lost;
- rp->cnt_lost = 0;
- spin_unlock_irqrestore(&rp->b_lock, flags);
- nevents = mon_bin_queued(rp);
+ return 0;
- sp = (struct mon_bin_stats __user *)arg;
- if (put_user(rp->cnt_lost, &sp->dropped))
- return -EFAULT;
- if (put_user(nevents, &sp->queued))
- return -EFAULT;
+ case MON_IOCG_STATS:
+ return mon_bin_ioctl(NULL, file, cmd,
+ (unsigned long) compat_ptr(arg));
- }
- break;
+ case MON_IOCQ_URB_LEN:
+ case MON_IOCQ_RING_SIZE:
+ case MON_IOCT_RING_SIZE:
+ case MON_IOCH_MFLUSH:
+ return mon_bin_ioctl(NULL, file, cmd, arg);
default:
- return -ENOTTY;
+ ;
}
-
- return ret;
+ return -ENOTTY;
}
+#endif /* CONFIG_COMPAT */
static unsigned int
mon_bin_poll(struct file *file, struct poll_table_struct *wait)
@@ -1094,6 +1208,9 @@ static const struct file_operations mon_fops_binary = {
/* .write = mon_text_write, */
.poll = mon_bin_poll,
.ioctl = mon_bin_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = mon_bin_compat_ioctl,
+#endif
.release = mon_bin_release,
.mmap = mon_bin_mmap,
};
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 5af7379cd9a..b66e8544d8b 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -11,6 +11,7 @@ config USB_MUSB_HDRC
depends on (USB || USB_GADGET) && HAVE_CLK
depends on !SUPERH
select TWL4030_USB if MACH_OMAP_3430SDP
+ select USB_OTG_UTILS
tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
help
Say Y here if your system has a dual role high speed USB
@@ -19,8 +20,8 @@ config USB_MUSB_HDRC
it's being used with, including the USB peripheral role,
or the USB host role, or both.
- Texas Instruments parts using this IP include DaVinci 644x,
- OMAP 243x, OMAP 343x, and TUSB 6010.
+ Texas Instruments familiies using this IP include DaVinci
+ (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010.
Analog Devices parts using this IP include Blackfin BF54x,
BF525 and BF527.
@@ -39,7 +40,7 @@ config USB_MUSB_SOC
default y if (BF54x && !BF544)
default y if (BF52x && !BF522 && !BF523)
-comment "DaVinci 644x USB support"
+comment "DaVinci 35x and 644x USB support"
depends on USB_MUSB_HDRC && ARCH_DAVINCI
comment "OMAP 243x high speed USB support"
@@ -49,7 +50,7 @@ comment "OMAP 343x high speed USB support"
depends on USB_MUSB_HDRC && ARCH_OMAP34XX
comment "Blackfin high speed USB Support"
- depends on USB_MUSB_HDRC && (BF54x && !BF544) || (BF52x && !BF522 && !BF523)
+ depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523))
config USB_TUSB6010
boolean "TUSB 6010 support"
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 5ad6d0893cb..569ef0fed0f 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -9,6 +9,7 @@
#include <linux/usb.h>
#include "musb_core.h"
+#include "musb_debug.h"
#include "cppi_dma.h"
@@ -423,6 +424,7 @@ cppi_rndis_update(struct cppi_channel *c, int is_rx,
}
}
+#ifdef CONFIG_USB_MUSB_DEBUG
static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd)
{
pr_debug("RXBD/%s %08x: "
@@ -431,10 +433,11 @@ static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd)
bd->hw_next, bd->hw_bufp, bd->hw_off_len,
bd->hw_options);
}
+#endif
static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx)
{
-#if MUSB_DEBUG > 0
+#ifdef CONFIG_USB_MUSB_DEBUG
struct cppi_descriptor *bd;
if (!_dbg_level(level))
@@ -881,12 +884,14 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)
bd->hw_options |= CPPI_SOP_SET;
tail->hw_options |= CPPI_EOP_SET;
- if (debug >= 5) {
+#ifdef CONFIG_USB_MUSB_DEBUG
+ if (_dbg_level(5)) {
struct cppi_descriptor *d;
for (d = rx->head; d; d = d->next)
cppi_dump_rxbd("S", d);
}
+#endif
/* in case the preceding transfer left some state... */
tail = rx->last_processed;
@@ -990,6 +995,7 @@ static int cppi_channel_program(struct dma_channel *ch,
cppi_ch->offset = 0;
cppi_ch->maxpacket = maxpacket;
cppi_ch->buf_len = len;
+ cppi_ch->channel.actual_len = 0;
/* TX channel? or RX? */
if (cppi_ch->transmit)
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 0d566dc5ce0..10d11ab113a 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -32,9 +32,10 @@
#include <linux/io.h>
#include <linux/gpio.h>
-#include <mach/arch/hardware.h>
-#include <mach/arch/memory.h>
-#include <mach/arch/gpio.h>
+#include <mach/hardware.h>
+#include <mach/memory.h>
+#include <mach/gpio.h>
+
#include <asm/mach-types.h>
#include "musb_core.h"
@@ -47,6 +48,9 @@
#include "cppi_dma.h"
+#define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR)
+#define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR)
+
/* REVISIT (PM) we should be able to keep the PHY in low power mode most
* of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
* and, when in host mode, autosuspending idle root ports... PHYPLLON
@@ -55,20 +59,26 @@
static inline void phy_on(void)
{
- /* start the on-chip PHY and its PLL */
- __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON,
- (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR));
- while ((__raw_readl((void __force __iomem *)
- IO_ADDRESS(USBPHY_CTL_PADDR))
- & USBPHY_PHYCLKGD) == 0)
+ u32 phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+ /* power everything up; start the on-chip PHY and its PLL */
+ phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN);
+ phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON;
+ __raw_writel(phy_ctrl, USB_PHY_CTRL);
+
+ /* wait for PLL to lock before proceeding */
+ while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0)
cpu_relax();
}
static inline void phy_off(void)
{
- /* powerdown the on-chip PHY and its oscillator */
- __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *)
- IO_ADDRESS(USBPHY_CTL_PADDR));
+ u32 phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+ /* powerdown the on-chip PHY, its PLL, and the OTG block */
+ phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON);
+ phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN;
+ __raw_writel(phy_ctrl, USB_PHY_CTRL);
}
static int dma_off = 1;
@@ -125,10 +135,6 @@ void musb_platform_disable(struct musb *musb)
}
-/* REVISIT it's not clear whether DaVinci can support full OTG. */
-
-static int vbus_state = -1;
-
#ifdef CONFIG_USB_MUSB_HDRC_HCD
#define portstate(stmt) stmt
#else
@@ -136,10 +142,19 @@ static int vbus_state = -1;
#endif
-/* VBUS SWITCHING IS BOARD-SPECIFIC */
+/*
+ * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM,
+ * which doesn't wire DRVVBUS to the FET that switches it. Unclear
+ * if that's a problem with the DM6446 chip or just with that board.
+ *
+ * In either case, the DM355 EVM automates DRVVBUS the normal way,
+ * when J10 is out, and TI documents it as handling OTG.
+ */
#ifdef CONFIG_MACH_DAVINCI_EVM
+static int vbus_state = -1;
+
/* I2C operations are always synchronous, and require a task context.
* With unloaded systems, using the shared workqueue seems to suffice
* to satisfy the 100msec A_WAIT_VRISE timeout...
@@ -149,12 +164,12 @@ static void evm_deferred_drvvbus(struct work_struct *ignored)
gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
vbus_state = !vbus_state;
}
-static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
#endif /* EVM */
static void davinci_source_power(struct musb *musb, int is_on, int immediate)
{
+#ifdef CONFIG_MACH_DAVINCI_EVM
if (is_on)
is_on = 1;
@@ -162,16 +177,17 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
return;
vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */
-#ifdef CONFIG_MACH_DAVINCI_EVM
if (machine_is_davinci_evm()) {
+ static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
+
if (immediate)
gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
else
schedule_work(&evm_vbus_work);
}
-#endif
if (immediate)
vbus_state = is_on;
+#endif
}
static void davinci_set_vbus(struct musb *musb, int is_on)
@@ -370,30 +386,14 @@ int musb_platform_set_mode(struct musb *musb, u8 mode)
return -EIO;
}
-int musb_platform_set_mode(struct musb *musb, u8 mode)
-{
- /* EVM can't do this (right?) */
- return -EIO;
-}
-
int __init musb_platform_init(struct musb *musb)
{
void __iomem *tibase = musb->ctrl_base;
u32 revision;
musb->mregs += DAVINCI_BASE_OFFSET;
-#if 0
- /* REVISIT there's something odd about clocking, this
- * didn't appear do the job ...
- */
- musb->clock = clk_get(pDevice, "usb");
- if (IS_ERR(musb->clock))
- return PTR_ERR(musb->clock);
- status = clk_enable(musb->clock);
- if (status < 0)
- return -ENODEV;
-#endif
+ clk_enable(musb->clock);
/* returns zero if e.g. not clocked */
revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
@@ -406,6 +406,17 @@ int __init musb_platform_init(struct musb *musb)
musb->board_set_vbus = davinci_set_vbus;
davinci_source_power(musb, 0, 1);
+ /* dm355 EVM swaps D+/D- for signal integrity, and
+ * is clocked from the main 24 MHz crystal.
+ */
+ if (machine_is_davinci_dm355_evm()) {
+ u32 phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+ phy_ctrl &= ~(3 << 9);
+ phy_ctrl |= USBPHY_DATAPOL;
+ __raw_writel(phy_ctrl, USB_PHY_CTRL);
+ }
+
/* reset the controller */
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
@@ -416,8 +427,7 @@ int __init musb_platform_init(struct musb *musb)
/* NOTE: irqs are in mixed mode, not bypass to pure-musb */
pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
- revision, __raw_readl((void __force __iomem *)
- IO_ADDRESS(USBPHY_CTL_PADDR)),
+ revision, __raw_readl(USB_PHY_CTRL),
musb_readb(tibase, DAVINCI_USB_CTRL_REG));
musb->isr = davinci_interrupt;
@@ -458,5 +468,8 @@ int musb_platform_exit(struct musb *musb)
}
phy_off();
+
+ clk_disable(musb->clock);
+
return 0;
}
diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h
index 7fb6238e270..046c84433ca 100644
--- a/drivers/usb/musb/davinci.h
+++ b/drivers/usb/musb/davinci.h
@@ -15,14 +15,21 @@
*/
/* Integrated highspeed/otg PHY */
-#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
-#define USBPHY_PHYCLKGD (1 << 8)
-#define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */
-#define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */
-#define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */
-#define USBPHY_CLKO1SEL (1 << 3)
-#define USBPHY_OSCPDWN (1 << 2)
-#define USBPHY_PHYPDWN (1 << 0)
+#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
+#define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */
+#define USBPHY_PHYCLKGD BIT(8)
+#define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */
+#define USBPHY_VBDTCTEN BIT(6) /* v(bus) comparator */
+#define USBPHY_VBUSSENS BIT(5) /* (dm355,ro) is vbus > 0.5V */
+#define USBPHY_PHYPLLON BIT(4) /* override pll suspend */
+#define USBPHY_CLKO1SEL BIT(3)
+#define USBPHY_OSCPDWN BIT(2)
+#define USBPHY_OTGPDWN BIT(1)
+#define USBPHY_PHYPDWN BIT(0)
+
+#define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48)
+#define DRVVBUS_FORCE BIT(2)
+#define DRVVBUS_OVERRIDE BIT(1)
/* For now include usb OTG module registers here */
#define DAVINCI_USB_VERSION_REG 0x00
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 6c7faacfb53..338cd1611ab 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -115,7 +115,7 @@
unsigned musb_debug;
-module_param(musb_debug, uint, S_IRUGO | S_IWUSR);
+module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug message level. Default = 0");
#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
@@ -767,8 +767,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
#ifdef CONFIG_USB_MUSB_HDRC_HCD
case OTG_STATE_A_HOST:
case OTG_STATE_A_SUSPEND:
+ usb_hcd_resume_root_hub(musb_to_hcd(musb));
musb_root_disconnect(musb);
- if (musb->a_wait_bcon != 0)
+ if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
musb_platform_try_idle(musb, jiffies
+ msecs_to_jiffies(musb->a_wait_bcon));
break;
@@ -1815,7 +1816,7 @@ static void musb_free(struct musb *musb)
#ifdef CONFIG_SYSFS
device_remove_file(musb->controller, &dev_attr_mode);
device_remove_file(musb->controller, &dev_attr_vbus);
-#ifdef CONFIG_USB_MUSB_OTG
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
device_remove_file(musb->controller, &dev_attr_srp);
#endif
#endif
@@ -1824,8 +1825,9 @@ static void musb_free(struct musb *musb)
musb_gadget_cleanup(musb);
#endif
- if (musb->nIrq >= 0 && musb->irq_wake) {
- disable_irq_wake(musb->nIrq);
+ if (musb->nIrq >= 0) {
+ if (musb->irq_wake)
+ disable_irq_wake(musb->nIrq);
free_irq(musb->nIrq, musb);
}
if (is_dma_capable() && musb->dma_controller) {
@@ -2062,7 +2064,7 @@ fail2:
#ifdef CONFIG_SYSFS
device_remove_file(musb->controller, &dev_attr_mode);
device_remove_file(musb->controller, &dev_attr_vbus);
-#ifdef CONFIG_USB_MUSB_OTG
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
device_remove_file(musb->controller, &dev_attr_srp);
#endif
#endif
@@ -2242,10 +2244,10 @@ static int __init musb_init(void)
return platform_driver_probe(&musb_driver, musb_probe);
}
-/* make us init after usbcore and before usb
- * gadget and host-side drivers start to register
+/* make us init after usbcore and i2c (transceivers, regulators, etc)
+ * and before usb gadget and host-side drivers start to register
*/
-subsys_initcall(musb_init);
+fs_initcall(musb_init);
static void __exit musb_cleanup(void)
{
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 630946a2d9f..efb39b5e55b 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -331,7 +331,6 @@ struct musb {
struct list_head control; /* of musb_qh */
struct list_head in_bulk; /* of musb_qh */
struct list_head out_bulk; /* of musb_qh */
- struct musb_qh *periodic[32]; /* tree of interrupt+iso */
#endif
/* called with IRQs blocked; ON/nonzero implies starting a session,
@@ -479,10 +478,11 @@ static inline void musb_configure_ep0(struct musb *musb)
static inline int musb_read_fifosize(struct musb *musb,
struct musb_hw_ep *hw_ep, u8 epnum)
{
+ void *mbase = musb->mregs;
u8 reg = 0;
/* read from core using indexed model */
- reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
+ reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE));
/* 0's returned when no more endpoints */
if (!reg)
return -ENODEV;
@@ -509,6 +509,7 @@ static inline void musb_configure_ep0(struct musb *musb)
{
musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+ musb->endpoints[0].is_shared_fifo = true;
}
#endif /* CONFIG_BLACKFIN */
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 6197daeab8f..c7ebd0867fc 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -575,7 +575,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
struct usb_request *request = &req->request;
struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
void __iomem *epio = musb->endpoints[epnum].regs;
- u16 fifo_count = 0;
+ unsigned fifo_count = 0;
u16 len = musb_ep->packet_sz;
csr = musb_readw(epio, MUSB_RXCSR);
@@ -687,7 +687,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
len, fifo_count,
musb_ep->packet_sz);
- fifo_count = min(len, fifo_count);
+ fifo_count = min_t(unsigned, len, fifo_count);
#ifdef CONFIG_USB_TUSB_OMAP_DMA
if (tusb_dma_omap() && musb_ep->dma) {
@@ -874,10 +874,10 @@ static int musb_gadget_enable(struct usb_ep *ep,
status = -EBUSY;
goto fail;
}
- musb_ep->type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ musb_ep->type = usb_endpoint_type(desc);
/* check direction and (later) maxpacket size against endpoint */
- if ((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != epnum)
+ if (usb_endpoint_num(desc) != epnum)
goto fail;
/* REVISIT this rules out high bandwidth periodic transfers */
@@ -890,7 +890,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
* packet size (or fail), set the mode, clear the fifo
*/
musb_ep_select(mbase, epnum);
- if (desc->bEndpointAddress & USB_DIR_IN) {
+ if (usb_endpoint_dir_in(desc)) {
u16 int_txe = musb_readw(mbase, MUSB_INTRTXE);
if (hw_ep->is_shared_fifo)
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 99fa6123487..499c431a6d6 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -64,11 +64,8 @@
*
* - DMA (Mentor/OMAP) ...has at least toggle update problems
*
- * - Still no traffic scheduling code to make NAKing for bulk or control
- * transfers unable to starve other requests; or to make efficient use
- * of hardware with periodic transfers. (Note that network drivers
- * commonly post bulk reads that stay pending for a long time; these
- * would make very visible trouble.)
+ * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet
+ * starvation ... nothing yet for TX, interrupt, or bulk.
*
* - Not tested with HNP, but some SRP paths seem to behave.
*
@@ -88,11 +85,8 @@
*
* CONTROL transfers all go through ep0. BULK ones go through dedicated IN
* and OUT endpoints ... hardware is dedicated for those "async" queue(s).
- *
* (Yes, bulk _could_ use more of the endpoints than that, and would even
- * benefit from it ... one remote device may easily be NAKing while others
- * need to perform transfers in that same direction. The same thing could
- * be done in software though, assuming dma cooperates.)
+ * benefit from it.)
*
* INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints.
* So far that scheduling is both dumb and optimistic: the endpoint will be
@@ -201,8 +195,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
len = urb->iso_frame_desc[0].length;
break;
default: /* bulk, interrupt */
- buf = urb->transfer_buffer;
- len = urb->transfer_buffer_length;
+ /* actual_length may be nonzero on retry paths */
+ buf = urb->transfer_buffer + urb->actual_length;
+ len = urb->transfer_buffer_length - urb->actual_length;
}
DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
@@ -335,16 +330,11 @@ musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb)
static struct musb_qh *
musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
{
- int is_in;
struct musb_hw_ep *ep = qh->hw_ep;
struct musb *musb = ep->musb;
+ int is_in = usb_pipein(urb->pipe);
int ready = qh->is_ready;
- if (ep->is_shared_fifo)
- is_in = 1;
- else
- is_in = usb_pipein(urb->pipe);
-
/* save toggle eagerly, for paranoia */
switch (qh->type) {
case USB_ENDPOINT_XFER_BULK:
@@ -400,7 +390,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
* de-allocated if it's tracked and allocated;
* and where we'd update the schedule tree...
*/
- musb->periodic[ep->epnum] = NULL;
kfree(qh);
qh = NULL;
break;
@@ -432,7 +421,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb,
else
qh = musb_giveback(qh, urb, urb->status);
- if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) {
+ if (qh != NULL && qh->is_ready) {
DBG(4, "... next ep%d %cX urb %p\n",
hw_ep->epnum, is_in ? 'R' : 'T',
next_urb(qh));
@@ -942,8 +931,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
switch (musb->ep0_stage) {
case MUSB_EP0_IN:
fifo_dest = urb->transfer_buffer + urb->actual_length;
- fifo_count = min(len, ((u16) (urb->transfer_buffer_length
- - urb->actual_length)));
+ fifo_count = min_t(size_t, len, urb->transfer_buffer_length -
+ urb->actual_length);
if (fifo_count < len)
urb->status = -EOVERFLOW;
@@ -976,10 +965,9 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
}
/* FALLTHROUGH */
case MUSB_EP0_OUT:
- fifo_count = min(qh->maxpacket, ((u16)
- (urb->transfer_buffer_length
- - urb->actual_length)));
-
+ fifo_count = min_t(size_t, qh->maxpacket,
+ urb->transfer_buffer_length -
+ urb->actual_length);
if (fifo_count) {
fifo_dest = (u8 *) (urb->transfer_buffer
+ urb->actual_length);
@@ -1051,7 +1039,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
/* NOTE: this code path would be a good place to PAUSE a
* control transfer, if another one is queued, so that
- * ep0 is more likely to stay busy.
+ * ep0 is more likely to stay busy. That's already done
+ * for bulk RX transfers.
*
* if (qh->ring.next != &musb->control), then
* we have a candidate... NAKing is *NOT* an error
@@ -1161,7 +1150,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
struct urb *urb;
struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
void __iomem *epio = hw_ep->regs;
- struct musb_qh *qh = hw_ep->out_qh;
+ struct musb_qh *qh = hw_ep->is_shared_fifo ? hw_ep->in_qh
+ : hw_ep->out_qh;
u32 status = 0;
void __iomem *mbase = musb->mregs;
struct dma_channel *dma;
@@ -1202,6 +1192,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
/* NOTE: this code path would be a good place to PAUSE a
* transfer, if there's some other (nonperiodic) tx urb
* that could use this fifo. (dma complicates it...)
+ * That's already done for bulk RX transfers.
*
* if (bulk && qh->ring.next != &musb->out_bulk), then
* we have a candidate... NAKing is *NOT* an error
@@ -1308,7 +1299,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
* packets before updating TXCSR ... other docs disagree ...
*/
/* PIO: start next packet in this URB */
- wLength = min(qh->maxpacket, (u16) wLength);
+ if (wLength > qh->maxpacket)
+ wLength = qh->maxpacket;
musb_write_fifo(hw_ep, wLength, buf);
qh->segsize = wLength;
@@ -1362,6 +1354,50 @@ finish:
#endif
+/* Schedule next QH from musb->in_bulk and move the current qh to
+ * the end; avoids starvation for other endpoints.
+ */
+static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
+{
+ struct dma_channel *dma;
+ struct urb *urb;
+ void __iomem *mbase = musb->mregs;
+ void __iomem *epio = ep->regs;
+ struct musb_qh *cur_qh, *next_qh;
+ u16 rx_csr;
+
+ musb_ep_select(mbase, ep->epnum);
+ dma = is_dma_capable() ? ep->rx_channel : NULL;
+
+ /* clear nak timeout bit */
+ rx_csr = musb_readw(epio, MUSB_RXCSR);
+ rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+ rx_csr &= ~MUSB_RXCSR_DATAERROR;
+ musb_writew(epio, MUSB_RXCSR, rx_csr);
+
+ cur_qh = first_qh(&musb->in_bulk);
+ if (cur_qh) {
+ urb = next_urb(cur_qh);
+ if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+ dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+ musb->dma_controller->channel_abort(dma);
+ urb->actual_length += dma->actual_len;
+ dma->actual_len = 0L;
+ }
+ musb_save_toggle(ep, 1, urb);
+
+ /* move cur_qh to end of queue */
+ list_move_tail(&cur_qh->ring, &musb->in_bulk);
+
+ /* get the next qh from musb->in_bulk */
+ next_qh = first_qh(&musb->in_bulk);
+
+ /* set rx_reinit and schedule the next qh */
+ ep->rx_reinit = 1;
+ musb_start_urb(musb, 1, next_qh);
+ }
+}
+
/*
* Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
* and high-bandwidth IN transfer cases.
@@ -1425,18 +1461,26 @@ void musb_host_rx(struct musb *musb, u8 epnum)
} else if (rx_csr & MUSB_RXCSR_DATAERROR) {
if (USB_ENDPOINT_XFER_ISOC != qh->type) {
- /* NOTE this code path would be a good place to PAUSE a
- * transfer, if there's some other (nonperiodic) rx urb
- * that could use this fifo. (dma complicates it...)
+ DBG(6, "RX end %d NAK timeout\n", epnum);
+
+ /* NOTE: NAKing is *NOT* an error, so we want to
+ * continue. Except ... if there's a request for
+ * another QH, use that instead of starving it.
*
- * if (bulk && qh->ring.next != &musb->in_bulk), then
- * we have a candidate... NAKing is *NOT* an error
+ * Devices like Ethernet and serial adapters keep
+ * reads posted at all times, which will starve
+ * other devices without this logic.
*/
- DBG(6, "RX end %d NAK timeout\n", epnum);
+ if (usb_pipebulk(urb->pipe)
+ && qh->mux == 1
+ && !list_is_singular(&musb->in_bulk)) {
+ musb_bulk_rx_nak_timeout(musb, hw_ep);
+ return;
+ }
musb_ep_select(mbase, epnum);
- musb_writew(epio, MUSB_RXCSR,
- MUSB_RXCSR_H_WZC_BITS
- | MUSB_RXCSR_H_REQPKT);
+ rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+ rx_csr &= ~MUSB_RXCSR_DATAERROR;
+ musb_writew(epio, MUSB_RXCSR, rx_csr);
goto finish;
} else {
@@ -1715,31 +1759,27 @@ static int musb_schedule(
/* else, periodic transfers get muxed to other endpoints */
- /* FIXME this doesn't consider direction, so it can only
- * work for one half of the endpoint hardware, and assumes
- * the previous cases handled all non-shared endpoints...
- */
-
- /* we know this qh hasn't been scheduled, so all we need to do
+ /*
+ * We know this qh hasn't been scheduled, so all we need to do
* is choose which hardware endpoint to put it on ...
*
* REVISIT what we really want here is a regular schedule tree
- * like e.g. OHCI uses, but for now musb->periodic is just an
- * array of the _single_ logical endpoint associated with a
- * given physical one (identity mapping logical->physical).
- *
- * that simplistic approach makes TT scheduling a lot simpler;
- * there is none, and thus none of its complexity...
+ * like e.g. OHCI uses.
*/
best_diff = 4096;
best_end = -1;
- for (epnum = 1; epnum < musb->nr_endpoints; epnum++) {
+ for (epnum = 1, hw_ep = musb->endpoints + 1;
+ epnum < musb->nr_endpoints;
+ epnum++, hw_ep++) {
int diff;
- if (musb->periodic[epnum])
+ if (is_in || hw_ep->is_shared_fifo) {
+ if (hw_ep->in_qh != NULL)
+ continue;
+ } else if (hw_ep->out_qh != NULL)
continue;
- hw_ep = &musb->endpoints[epnum];
+
if (hw_ep == musb->bulk_ep)
continue;
@@ -1760,6 +1800,17 @@ static int musb_schedule(
head = &musb->in_bulk;
else
head = &musb->out_bulk;
+
+ /* Enable bulk RX NAK timeout scheme when bulk requests are
+ * multiplexed. This scheme doen't work in high speed to full
+ * speed scenario as NAK interrupts are not coming from a
+ * full speed device connected to a high speed device.
+ * NAK timeout interval is 8 (128 uframe or 16ms) for HS and
+ * 4 (8 frame or 8ms) for FS device.
+ */
+ if (is_in && qh->dev)
+ qh->intv_reg =
+ (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4;
goto success;
} else if (best_end < 0) {
return -ENOSPC;
@@ -1768,7 +1819,6 @@ static int musb_schedule(
idle = 1;
qh->mux = 0;
hw_ep = musb->endpoints + best_end;
- musb->periodic[best_end] = qh;
DBG(4, "qh %p periodic slot %d\n", qh, best_end);
success:
if (head) {
@@ -1847,8 +1897,8 @@ static int musb_urb_enqueue(
goto done;
}
- qh->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- qh->type = epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ qh->epnum = usb_endpoint_num(epd);
+ qh->type = usb_endpoint_type(epd);
/* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */
qh->addr_reg = (u8) usb_pipedevice(urb->pipe);
@@ -1867,19 +1917,21 @@ static int musb_urb_enqueue(
}
qh->type_reg = type_reg;
- /* precompute rxinterval/txinterval register */
- interval = min((u8)16, epd->bInterval); /* log encoding */
+ /* Precompute RXINTERVAL/TXINTERVAL register */
switch (qh->type) {
case USB_ENDPOINT_XFER_INT:
- /* fullspeed uses linear encoding */
- if (USB_SPEED_FULL == urb->dev->speed) {
- interval = epd->bInterval;
- if (!interval)
- interval = 1;
+ /*
+ * Full/low speeds use the linear encoding,
+ * high speed uses the logarithmic encoding.
+ */
+ if (urb->dev->speed <= USB_SPEED_FULL) {
+ interval = max_t(u8, epd->bInterval, 1);
+ break;
}
/* FALLTHROUGH */
case USB_ENDPOINT_XFER_ISOC:
- /* iso always uses log encoding */
+ /* ISO always uses logarithmic encoding */
+ interval = min_t(u8, epd->bInterval, 16);
break;
default:
/* REVISIT we actually want to use NAK limits, hinting to the
@@ -1890,13 +1942,11 @@ static int musb_urb_enqueue(
*
* The downside of disabling this is that transfer scheduling
* gets VERY unfair for nonperiodic transfers; a misbehaving
- * peripheral could make that hurt. Or for reads, one that's
- * perfectly normal: network and other drivers keep reads
- * posted at all times, having one pending for a week should
- * be perfectly safe.
+ * peripheral could make that hurt. That's perfectly normal
+ * for reads from network or serial adapters ... so we have
+ * partial NAKlimit support for bulk RX.
*
- * The upside of disabling it is avoidng transfer scheduling
- * code to put this aside for while.
+ * The upside of disabling it is simpler transfer scheduling.
*/
interval = 0;
}
@@ -2037,9 +2087,9 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
goto done;
/* Any URB not actively programmed into endpoint hardware can be
- * immediately given back. Such an URB must be at the head of its
+ * immediately given back; that's any URB not at the head of an
* endpoint queue, unless someday we get real DMA queues. And even
- * then, it might not be known to the hardware...
+ * if it's at the head, it might not be known to the hardware...
*
* Otherwise abort current transfer, pending dma, etc.; urb->status
* has already been updated. This is a synchronous abort; it'd be
@@ -2078,6 +2128,15 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
qh->is_ready = 0;
__musb_giveback(musb, urb, 0);
qh->is_ready = ready;
+
+ /* If nothing else (usually musb_giveback) is using it
+ * and its URB list has emptied, recycle this qh.
+ */
+ if (ready && list_empty(&qh->hep->urb_list)) {
+ qh->hep->hcpriv = NULL;
+ list_del(&qh->ring);
+ kfree(qh);
+ }
} else
ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN);
done:
@@ -2093,15 +2152,16 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
unsigned long flags;
struct musb *musb = hcd_to_musb(hcd);
u8 is_in = epnum & USB_DIR_IN;
- struct musb_qh *qh = hep->hcpriv;
- struct urb *urb, *tmp;
+ struct musb_qh *qh;
+ struct urb *urb;
struct list_head *sched;
- if (!qh)
- return;
-
spin_lock_irqsave(&musb->lock, flags);
+ qh = hep->hcpriv;
+ if (qh == NULL)
+ goto exit;
+
switch (qh->type) {
case USB_ENDPOINT_XFER_CONTROL:
sched = &musb->control;
@@ -2135,13 +2195,28 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
/* cleanup */
musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN);
- } else
- urb = NULL;
- /* then just nuke all the others */
- list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list)
- musb_giveback(qh, urb, -ESHUTDOWN);
+ /* Then nuke all the others ... and advance the
+ * queue on hw_ep (e.g. bulk ring) when we're done.
+ */
+ while (!list_empty(&hep->urb_list)) {
+ urb = next_urb(qh);
+ urb->status = -ESHUTDOWN;
+ musb_advance_schedule(musb, urb, qh->hw_ep, is_in);
+ }
+ } else {
+ /* Just empty the queue; the hardware is busy with
+ * other transfers, and since !qh->is_ready nothing
+ * will activate any of these as it advances.
+ */
+ while (!list_empty(&hep->urb_list))
+ __musb_giveback(musb, next_urb(qh), -ESHUTDOWN);
+ hep->hcpriv = NULL;
+ list_del(&qh->ring);
+ kfree(qh);
+ }
+exit:
spin_unlock_irqrestore(&musb->lock, flags);
}
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index e0e9ce58417..bf677acc83d 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -285,7 +285,7 @@ int musb_hub_control(
desc->bDescLength = 9;
desc->bDescriptorType = 0x29;
desc->bNbrPorts = 1;
- desc->wHubCharacteristics = __constant_cpu_to_le16(
+ desc->wHubCharacteristics = cpu_to_le16(
0x0001 /* per-port power switching */
| 0x0010 /* no overcurrent reporting */
);
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 52f7f29cebd..7e073a0d7ac 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -15,8 +15,8 @@
#include <linux/usb.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <asm/arch/dma.h>
-#include <asm/arch/mux.h>
+#include <mach/dma.h>
+#include <mach/mux.h>
#include "musb_core.h"
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 8e8dbdb9b39..aa884d072f0 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -6,14 +6,14 @@
comment "OTG and related infrastructure"
-if USB || USB_GADGET
-
config USB_OTG_UTILS
bool
help
Select this to make sure the build includes objects from
the OTG infrastructure directory.
+if USB || USB_GADGET
+
#
# USB Transceiver Drivers
#
@@ -43,7 +43,7 @@ config ISP1301_OMAP
config TWL4030_USB
tristate "TWL4030 USB Transceiver Driver"
- depends on TWL4030_CORE
+ depends on TWL4030_CORE && REGULATOR_TWL4030
select USB_OTG_UTILS
help
Enable this to support the USB OTG transceiver on TWL4030
@@ -51,4 +51,12 @@ config TWL4030_USB
This transceiver supports high and full speed devices plus,
in host mode, low speed.
+config NOP_USB_XCEIV
+ tristate "NOP USB Transceiver Driver"
+ select USB_OTG_UTILS
+ help
+ this driver is to be used by all the usb transceiver which are either
+ built-in with usb ip or which are autonomous and doesn't require any
+ phy programming such as ISP1x04 etc.
+
endif # USB || OTG
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
index d73c7cf5e2f..20816785652 100644
--- a/drivers/usb/otg/Makefile
+++ b/drivers/usb/otg/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o
obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o
obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o
+obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG
ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c
index 63a6036f04b..1c26c94513e 100644
--- a/drivers/usb/otg/gpio_vbus.c
+++ b/drivers/usb/otg/gpio_vbus.c
@@ -13,6 +13,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
+#include <linux/workqueue.h>
#include <linux/regulator/consumer.h>
@@ -34,6 +35,7 @@ struct gpio_vbus_data {
struct regulator *vbus_draw;
int vbus_draw_enabled;
unsigned mA;
+ struct work_struct work;
};
@@ -76,24 +78,26 @@ static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA)
gpio_vbus->mA = mA;
}
-/* VBUS change IRQ handler */
-static irqreturn_t gpio_vbus_irq(int irq, void *data)
+static int is_vbus_powered(struct gpio_vbus_mach_info *pdata)
{
- struct platform_device *pdev = data;
- struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
- struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
- int gpio, vbus;
+ int vbus;
vbus = gpio_get_value(pdata->gpio_vbus);
if (pdata->gpio_vbus_inverted)
vbus = !vbus;
- dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n",
- vbus ? "supplied" : "inactive",
- gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none");
+ return vbus;
+}
+
+static void gpio_vbus_work(struct work_struct *work)
+{
+ struct gpio_vbus_data *gpio_vbus =
+ container_of(work, struct gpio_vbus_data, work);
+ struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data;
+ int gpio;
if (!gpio_vbus->otg.gadget)
- return IRQ_HANDLED;
+ return;
/* Peripheral controllers which manage the pullup themselves won't have
* gpio_pullup configured here. If it's configured here, we'll do what
@@ -101,7 +105,7 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data)
* that may complicate usb_gadget_{,dis}connect() support.
*/
gpio = pdata->gpio_pullup;
- if (vbus) {
+ if (is_vbus_powered(pdata)) {
gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL;
usb_gadget_vbus_connect(gpio_vbus->otg.gadget);
@@ -121,6 +125,21 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data)
usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget);
gpio_vbus->otg.state = OTG_STATE_B_IDLE;
}
+}
+
+/* VBUS change IRQ handler */
+static irqreturn_t gpio_vbus_irq(int irq, void *data)
+{
+ struct platform_device *pdev = data;
+ struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
+ struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n",
+ is_vbus_powered(pdata) ? "supplied" : "inactive",
+ gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none");
+
+ if (gpio_vbus->otg.gadget)
+ schedule_work(&gpio_vbus->work);
return IRQ_HANDLED;
}
@@ -257,6 +276,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
irq, err);
goto err_irq;
}
+ INIT_WORK(&gpio_vbus->work, gpio_vbus_work);
/* only active when a gadget is registered */
err = otg_set_transceiver(&gpio_vbus->otg);
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
new file mode 100644
index 00000000000..4b933f646f2
--- /dev/null
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -0,0 +1,180 @@
+/*
+ * drivers/usb/otg/nop-usb-xceiv.c
+ *
+ * NOP USB transceiver for all USB transceiver which are either built-in
+ * into USB IP or which are mostly autonomous.
+ *
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Author: Ajay Kumar Gupta <ajay.gupta@ti.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Current status:
+ * this is to add "nop" transceiver for all those phy which is
+ * autonomous such as isp1504 etc.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/otg.h>
+
+struct nop_usb_xceiv {
+ struct otg_transceiver otg;
+ struct device *dev;
+};
+
+static u64 nop_xceiv_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device nop_xceiv_device = {
+ .name = "nop_usb_xceiv",
+ .id = -1,
+ .dev = {
+ .dma_mask = &nop_xceiv_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ .platform_data = NULL,
+ },
+};
+
+void usb_nop_xceiv_register(void)
+{
+ if (platform_device_register(&nop_xceiv_device) < 0) {
+ printk(KERN_ERR "Unable to register usb nop transceiver\n");
+ return;
+ }
+}
+
+void usb_nop_xceiv_unregister(void)
+{
+ platform_device_unregister(&nop_xceiv_device);
+}
+
+static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x)
+{
+ return container_of(x, struct nop_usb_xceiv, otg);
+}
+
+static int nop_set_suspend(struct otg_transceiver *x, int suspend)
+{
+ return 0;
+}
+
+static int nop_set_peripheral(struct otg_transceiver *x,
+ struct usb_gadget *gadget)
+{
+ struct nop_usb_xceiv *nop;
+
+ if (!x)
+ return -ENODEV;
+
+ nop = xceiv_to_nop(x);
+
+ if (!gadget) {
+ nop->otg.gadget = NULL;
+ return -ENODEV;
+ }
+
+ nop->otg.gadget = gadget;
+ nop->otg.state = OTG_STATE_B_IDLE;
+ return 0;
+}
+
+static int nop_set_host(struct otg_transceiver *x, struct usb_bus *host)
+{
+ struct nop_usb_xceiv *nop;
+
+ if (!x)
+ return -ENODEV;
+
+ nop = xceiv_to_nop(x);
+
+ if (!host) {
+ nop->otg.host = NULL;
+ return -ENODEV;
+ }
+
+ nop->otg.host = host;
+ return 0;
+}
+
+static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
+{
+ struct nop_usb_xceiv *nop;
+ int err;
+
+ nop = kzalloc(sizeof *nop, GFP_KERNEL);
+ if (!nop)
+ return -ENOMEM;
+
+ nop->dev = &pdev->dev;
+ nop->otg.dev = nop->dev;
+ nop->otg.label = "nop-xceiv";
+ nop->otg.state = OTG_STATE_UNDEFINED;
+ nop->otg.set_host = nop_set_host;
+ nop->otg.set_peripheral = nop_set_peripheral;
+ nop->otg.set_suspend = nop_set_suspend;
+
+ err = otg_set_transceiver(&nop->otg);
+ if (err) {
+ dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
+ err);
+ goto exit;
+ }
+
+ platform_set_drvdata(pdev, nop);
+
+ return 0;
+exit:
+ kfree(nop);
+ return err;
+}
+
+static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
+{
+ struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);
+
+ otg_set_transceiver(NULL);
+
+ platform_set_drvdata(pdev, NULL);
+ kfree(nop);
+
+ return 0;
+}
+
+static struct platform_driver nop_usb_xceiv_driver = {
+ .probe = nop_usb_xceiv_probe,
+ .remove = __devexit_p(nop_usb_xceiv_remove),
+ .driver = {
+ .name = "nop_usb_xceiv",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init nop_usb_xceiv_init(void)
+{
+ return platform_driver_register(&nop_usb_xceiv_driver);
+}
+subsys_initcall(nop_usb_xceiv_init);
+
+static void __exit nop_usb_xceiv_exit(void)
+{
+ platform_driver_unregister(&nop_usb_xceiv_driver);
+}
+module_exit(nop_usb_xceiv_exit);
+
+MODULE_ALIAS("platform:nop_usb_xceiv");
+MODULE_AUTHOR("Texas Instruments Inc");
+MODULE_DESCRIPTION("NOP USB Transceiver driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 416e4410be0..d9478d0e1c8 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -34,6 +34,8 @@
#include <linux/delay.h>
#include <linux/usb/otg.h>
#include <linux/i2c/twl4030.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
/* Register defines */
@@ -246,6 +248,11 @@ struct twl4030_usb {
struct otg_transceiver otg;
struct device *dev;
+ /* TWL4030 internal USB regulator supplies */
+ struct regulator *usb1v5;
+ struct regulator *usb1v8;
+ struct regulator *usb3v1;
+
/* for vbus reporting with irqs disabled */
spinlock_t lock;
@@ -434,6 +441,18 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
if (on) {
+ regulator_enable(twl->usb3v1);
+ regulator_enable(twl->usb1v8);
+ /*
+ * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
+ * in twl4030) resets the VUSB_DEDICATED2 register. This reset
+ * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
+ * SLEEP. We work around this by clearing the bit after usv3v1
+ * is re-activated. This ensures that VUSB3V1 is really active.
+ */
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0,
+ VUSB_DEDICATED2);
+ regulator_enable(twl->usb1v5);
pwr &= ~PHY_PWR_PHYPWD;
WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
twl4030_usb_write(twl, PHY_CLK_CTRL,
@@ -443,6 +462,9 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
} else {
pwr |= PHY_PWR_PHYPWD;
WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+ regulator_disable(twl->usb1v5);
+ regulator_disable(twl->usb1v8);
+ regulator_disable(twl->usb3v1);
}
}
@@ -468,7 +490,7 @@ static void twl4030_phy_resume(struct twl4030_usb *twl)
twl->asleep = 0;
}
-static void twl4030_usb_ldo_init(struct twl4030_usb *twl)
+static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
{
/* Enable writing to power configuration registers */
twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY);
@@ -480,20 +502,45 @@ static void twl4030_usb_ldo_init(struct twl4030_usb *twl)
/* input to VUSB3V1 LDO is from VBAT, not VBUS */
twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
- /* turn on 3.1V regulator */
- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB3V1_DEV_GRP);
+ /* Initialize 3.1V regulator */
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP);
+
+ twl->usb3v1 = regulator_get(twl->dev, "usb3v1");
+ if (IS_ERR(twl->usb3v1))
+ return -ENODEV;
+
twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE);
- /* turn on 1.5V regulator */
- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V5_DEV_GRP);
+ /* Initialize 1.5V regulator */
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP);
+
+ twl->usb1v5 = regulator_get(twl->dev, "usb1v5");
+ if (IS_ERR(twl->usb1v5))
+ goto fail1;
+
twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE);
- /* turn on 1.8V regulator */
- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V8_DEV_GRP);
+ /* Initialize 1.8V regulator */
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP);
+
+ twl->usb1v8 = regulator_get(twl->dev, "usb1v8");
+ if (IS_ERR(twl->usb1v8))
+ goto fail2;
+
twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE);
/* disable access to power configuration registers */
twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY);
+
+ return 0;
+
+fail2:
+ regulator_put(twl->usb1v5);
+ twl->usb1v5 = NULL;
+fail1:
+ regulator_put(twl->usb3v1);
+ twl->usb3v1 = NULL;
+ return -ENODEV;
}
static ssize_t twl4030_usb_vbus_show(struct device *dev,
@@ -598,7 +645,7 @@ static int __init twl4030_usb_probe(struct platform_device *pdev)
{
struct twl4030_usb_data *pdata = pdev->dev.platform_data;
struct twl4030_usb *twl;
- int status;
+ int status, err;
if (!pdata) {
dev_dbg(&pdev->dev, "platform_data not available\n");
@@ -622,7 +669,12 @@ static int __init twl4030_usb_probe(struct platform_device *pdev)
/* init spinlock for workqueue */
spin_lock_init(&twl->lock);
- twl4030_usb_ldo_init(twl);
+ err = twl4030_usb_ldo_init(twl);
+ if (err) {
+ dev_err(&pdev->dev, "ldo init failed\n");
+ kfree(twl);
+ return err;
+ }
otg_set_transceiver(&twl->otg);
platform_set_drvdata(pdev, twl);
@@ -688,6 +740,9 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev)
twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
twl4030_phy_power(twl, 0);
+ regulator_put(twl->usb1v5);
+ regulator_put(twl->usb1v8);
+ regulator_put(twl->usb3v1);
kfree(twl);
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index b361f05cafa..a65f9196b0a 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -116,14 +116,14 @@ config USB_SERIAL_DIGI_ACCELEPORT
To compile this driver as a module, choose M here: the
module will be called digi_acceleport.
-config USB_SERIAL_CP2101
- tristate "USB CP2101 UART Bridge Controller"
+config USB_SERIAL_CP210X
+ tristate "USB CP210x family of UART Bridge Controllers"
help
- Say Y here if you want to use a CP2101/CP2102 based USB to RS232
- converter.
+ Say Y here if you want to use a CP2101/CP2102/CP2103 based USB
+ to RS232 converters.
To compile this driver as a module, choose M here: the
- module will be called cp2101.
+ module will be called cp210x.
config USB_SERIAL_CYPRESS_M8
tristate "USB Cypress M8 USB Serial Driver"
@@ -472,6 +472,15 @@ config USB_SERIAL_OTI6858
To compile this driver as a module, choose M here: the
module will be called oti6858.
+config USB_SERIAL_QUALCOMM
+ tristate "USB Qualcomm Serial modem"
+ help
+ Say Y here if you have a Qualcomm USB modem device. These are
+ usually wireless cellular modems.
+
+ To compile this driver as a module, choose M here: the
+ module will be called qcserial.
+
config USB_SERIAL_SPCP8X5
tristate "USB SPCP8x5 USB To Serial Driver"
help
@@ -515,6 +524,15 @@ config USB_SERIAL_SIERRAWIRELESS
To compile this driver as a module, choose M here: the
module will be called sierra.
+config USB_SERIAL_SYMBOL
+ tristate "USB Symbol Barcode driver (serial mode)"
+ help
+ Say Y here if you want to use a Symbol USB Barcode device
+ in serial emulation mode.
+
+ To compile this driver as a module, choose M here: the
+ module will be called symbolserial.
+
config USB_SERIAL_TI
tristate "USB TI 3410/5052 Serial Driver"
help
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index b75be91eb8f..66619beb6cc 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o
obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o
obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o
obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o
-obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o
+obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o
obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o
obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o
obj-$(CONFIG_USB_SERIAL_DEBUG) += usb_debug.o
@@ -45,10 +45,12 @@ obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o
obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
+obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o
obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o
obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o
obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o
+obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o
obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o
obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 537f953bd7f..6d106e74265 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -621,9 +621,9 @@ static int __init aircable_init(void)
goto failed_usb_register;
return 0;
-failed_serial_register:
- usb_serial_deregister(&aircable_device);
failed_usb_register:
+ usb_serial_deregister(&aircable_device);
+failed_serial_register:
return retval;
}
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index f61e3ca6430..ab4cc277aa6 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -1,5 +1,7 @@
/*
* Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk>
+ * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de>
+ * Copyright 2009, Boris Hajduk <boris@hajduk.org>
*
* ch341.c implements a serial port driver for the Winchiphead CH341.
*
@@ -21,9 +23,39 @@
#include <linux/usb/serial.h>
#include <linux/serial.h>
-#define DEFAULT_BAUD_RATE 2400
+#define DEFAULT_BAUD_RATE 9600
#define DEFAULT_TIMEOUT 1000
+/* flags for IO-Bits */
+#define CH341_BIT_RTS (1 << 6)
+#define CH341_BIT_DTR (1 << 5)
+
+/******************************/
+/* interrupt pipe definitions */
+/******************************/
+/* always 4 interrupt bytes */
+/* first irq byte normally 0x08 */
+/* second irq byte base 0x7d + below */
+/* third irq byte base 0x94 + below */
+/* fourth irq byte normally 0xee */
+
+/* second interrupt byte */
+#define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */
+
+/* status returned in third interrupt answer byte, inverted in data
+ from irq */
+#define CH341_BIT_CTS 0x01
+#define CH341_BIT_DSR 0x02
+#define CH341_BIT_RI 0x04
+#define CH341_BIT_DCD 0x08
+#define CH341_BITS_MODEM_STAT 0x0f /* all bits */
+
+/*******************************/
+/* baudrate calculation factor */
+/*******************************/
+#define CH341_BAUDBASE_FACTOR 1532620800
+#define CH341_BAUDBASE_DIVMAX 3
+
static int debug;
static struct usb_device_id id_table [] = {
@@ -34,9 +66,12 @@ static struct usb_device_id id_table [] = {
MODULE_DEVICE_TABLE(usb, id_table);
struct ch341_private {
- unsigned baud_rate;
- u8 dtr;
- u8 rts;
+ spinlock_t lock; /* access lock */
+ wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
+ unsigned baud_rate; /* set baud rate */
+ u8 line_control; /* set line control value RTS/DTR */
+ u8 line_status; /* active status of modem control inputs */
+ u8 multi_status_change; /* status changed multiple since last call */
};
static int ch341_control_out(struct usb_device *dev, u8 request,
@@ -72,37 +107,28 @@ static int ch341_set_baudrate(struct usb_device *dev,
{
short a, b;
int r;
+ unsigned long factor;
+ short divisor;
dbg("ch341_set_baudrate(%d)", priv->baud_rate);
- switch (priv->baud_rate) {
- case 2400:
- a = 0xd901;
- b = 0x0038;
- break;
- case 4800:
- a = 0x6402;
- b = 0x001f;
- break;
- case 9600:
- a = 0xb202;
- b = 0x0013;
- break;
- case 19200:
- a = 0xd902;
- b = 0x000d;
- break;
- case 38400:
- a = 0x6403;
- b = 0x000a;
- break;
- case 115200:
- a = 0xcc03;
- b = 0x0008;
- break;
- default:
+
+ if (!priv->baud_rate)
return -EINVAL;
+ factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate);
+ divisor = CH341_BAUDBASE_DIVMAX;
+
+ while ((factor > 0xfff0) && divisor) {
+ factor >>= 3;
+ divisor--;
}
+ if (factor > 0xfff0)
+ return -EINVAL;
+
+ factor = 0x10000 - factor;
+ a = (factor & 0xff00) | divisor;
+ b = factor & 0xff;
+
r = ch341_control_out(dev, 0x9a, 0x1312, a);
if (!r)
r = ch341_control_out(dev, 0x9a, 0x0f2c, b);
@@ -110,19 +136,18 @@ static int ch341_set_baudrate(struct usb_device *dev,
return r;
}
-static int ch341_set_handshake(struct usb_device *dev,
- struct ch341_private *priv)
+static int ch341_set_handshake(struct usb_device *dev, u8 control)
{
- dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts);
- return ch341_control_out(dev, 0xa4,
- ~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0);
+ dbg("ch341_set_handshake(0x%02x)", control);
+ return ch341_control_out(dev, 0xa4, ~control, 0);
}
-static int ch341_get_status(struct usb_device *dev)
+static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
{
char *buffer;
int r;
const unsigned size = 8;
+ unsigned long flags;
dbg("ch341_get_status()");
@@ -134,10 +159,15 @@ static int ch341_get_status(struct usb_device *dev)
if (r < 0)
goto out;
- /* Not having the datasheet for the CH341, we ignore the bytes returned
- * from the device. Return error if the device did not respond in time.
- */
- r = 0;
+ /* setup the private status if available */
+ if (r == 2) {
+ r = 0;
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT;
+ priv->multi_status_change = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ } else
+ r = -EPROTO;
out: kfree(buffer);
return r;
@@ -180,7 +210,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
goto out;
/* expect 0xff 0xee */
- r = ch341_get_status(dev);
+ r = ch341_get_status(dev, priv);
if (r < 0)
goto out;
@@ -192,12 +222,12 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
if (r < 0)
goto out;
- r = ch341_set_handshake(dev, priv);
+ r = ch341_set_handshake(dev, priv->line_control);
if (r < 0)
goto out;
/* expect 0x9f 0xee */
- r = ch341_get_status(dev);
+ r = ch341_get_status(dev, priv);
out: kfree(buffer);
return r;
@@ -216,9 +246,10 @@ static int ch341_attach(struct usb_serial *serial)
if (!priv)
return -ENOMEM;
+ spin_lock_init(&priv->lock);
+ init_waitqueue_head(&priv->delta_msr_wait);
priv->baud_rate = DEFAULT_BAUD_RATE;
- priv->dtr = 1;
- priv->rts = 1;
+ priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
r = ch341_configure(serial->dev, priv);
if (r < 0)
@@ -231,6 +262,35 @@ error: kfree(priv);
return r;
}
+static void ch341_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ unsigned int c_cflag;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /* shutdown our urbs */
+ dbg("%s - shutting down urbs", __func__);
+ usb_kill_urb(port->write_urb);
+ usb_kill_urb(port->read_urb);
+ usb_kill_urb(port->interrupt_in_urb);
+
+ if (tty) {
+ c_cflag = tty->termios->c_cflag;
+ if (c_cflag & HUPCL) {
+ /* drop DTR and RTS */
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_control = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ch341_set_handshake(port->serial->dev, 0);
+ }
+ }
+ wake_up_interruptible(&priv->delta_msr_wait);
+}
+
+
/* open this device, set default parameters */
static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp)
@@ -242,14 +302,13 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
dbg("ch341_open()");
priv->baud_rate = DEFAULT_BAUD_RATE;
- priv->dtr = 1;
- priv->rts = 1;
+ priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
r = ch341_configure(serial->dev, priv);
if (r)
goto out;
- r = ch341_set_handshake(serial->dev, priv);
+ r = ch341_set_handshake(serial->dev, priv->line_control);
if (r)
goto out;
@@ -257,6 +316,16 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
if (r)
goto out;
+ dbg("%s - submitting interrupt urb", __func__);
+ port->interrupt_in_urb->dev = serial->dev;
+ r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+ if (r) {
+ dev_err(&port->dev, "%s - failed submitting interrupt urb,"
+ " error %d\n", __func__, r);
+ ch341_close(tty, port, NULL);
+ return -EPROTO;
+ }
+
r = usb_serial_generic_open(tty, port, filp);
out: return r;
@@ -270,46 +339,224 @@ static void ch341_set_termios(struct tty_struct *tty,
{
struct ch341_private *priv = usb_get_serial_port_data(port);
unsigned baud_rate;
+ unsigned long flags;
dbg("ch341_set_termios()");
+ if (!tty || !tty->termios)
+ return;
+
baud_rate = tty_get_baud_rate(tty);
- switch (baud_rate) {
- case 2400:
- case 4800:
- case 9600:
- case 19200:
- case 38400:
- case 115200:
- priv->baud_rate = baud_rate;
- break;
- default:
- dbg("Rate %d not supported, using %d",
- baud_rate, DEFAULT_BAUD_RATE);
- priv->baud_rate = DEFAULT_BAUD_RATE;
+ priv->baud_rate = baud_rate;
+
+ if (baud_rate) {
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ch341_set_baudrate(port->serial->dev, priv);
+ } else {
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
- ch341_set_baudrate(port->serial->dev, priv);
+ ch341_set_handshake(port->serial->dev, priv->line_control);
/* Unimplemented:
* (cflag & CSIZE) : data bits [5, 8]
* (cflag & PARENB) : parity {NONE, EVEN, ODD}
* (cflag & CSTOPB) : stop bits [1, 2]
*/
+}
+
+static int ch341_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 control;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (set & TIOCM_RTS)
+ priv->line_control |= CH341_BIT_RTS;
+ if (set & TIOCM_DTR)
+ priv->line_control |= CH341_BIT_DTR;
+ if (clear & TIOCM_RTS)
+ priv->line_control &= ~CH341_BIT_RTS;
+ if (clear & TIOCM_DTR)
+ priv->line_control &= ~CH341_BIT_DTR;
+ control = priv->line_control;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return ch341_set_handshake(port->serial->dev, control);
+}
+
+static void ch341_read_int_callback(struct urb *urb)
+{
+ struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+ unsigned char *data = urb->transfer_buffer;
+ unsigned int actual_length = urb->actual_length;
+ int status;
+
+ dbg("%s (%d)", __func__, port->number);
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d", __func__,
+ urb->status);
+ goto exit;
+ }
- /* Copy back the old hardware settings */
- tty_termios_copy_hw(tty->termios, old_termios);
- /* And re-encode with the new baud */
- tty_encode_baud_rate(tty, baud_rate, baud_rate);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, urb->transfer_buffer);
+
+ if (actual_length >= 4) {
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT;
+ if ((data[1] & CH341_MULT_STAT))
+ priv->multi_status_change = 1;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ wake_up_interruptible(&priv->delta_msr_wait);
+ }
+
+exit:
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status)
+ dev_err(&urb->dev->dev,
+ "%s - usb_submit_urb failed with result %d\n",
+ __func__, status);
+}
+
+static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+{
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 prevstatus;
+ u8 status;
+ u8 changed;
+ u8 multi_change = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ prevstatus = priv->line_status;
+ priv->multi_status_change = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (!multi_change) {
+ interruptible_sleep_on(&priv->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ multi_change = priv->multi_status_change;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ changed = prevstatus ^ status;
+
+ if (((arg & TIOCM_RNG) && (changed & CH341_BIT_RI)) ||
+ ((arg & TIOCM_DSR) && (changed & CH341_BIT_DSR)) ||
+ ((arg & TIOCM_CD) && (changed & CH341_BIT_DCD)) ||
+ ((arg & TIOCM_CTS) && (changed & CH341_BIT_CTS))) {
+ return 0;
+ }
+ prevstatus = status;
+ }
+
+ return 0;
+}
+
+/*static int ch341_ioctl(struct usb_serial_port *port, struct file *file,*/
+static int ch341_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
+
+ switch (cmd) {
+ case TIOCMIWAIT:
+ dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
+ return wait_modem_info(port, arg);
+
+ default:
+ dbg("%s not supported = 0x%04x", __func__, cmd);
+ break;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+static int ch341_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 mcr;
+ u8 status;
+ unsigned int result;
+
+ dbg("%s (%d)", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ mcr = priv->line_control;
+ status = priv->line_status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ result = ((mcr & CH341_BIT_DTR) ? TIOCM_DTR : 0)
+ | ((mcr & CH341_BIT_RTS) ? TIOCM_RTS : 0)
+ | ((status & CH341_BIT_CTS) ? TIOCM_CTS : 0)
+ | ((status & CH341_BIT_DSR) ? TIOCM_DSR : 0)
+ | ((status & CH341_BIT_RI) ? TIOCM_RI : 0)
+ | ((status & CH341_BIT_DCD) ? TIOCM_CD : 0);
+
+ dbg("%s - result = %x", __func__, result);
+
+ return result;
+}
+
+
+static int ch341_reset_resume(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_serial *serial = NULL;
+ struct ch341_private *priv;
+
+ serial = usb_get_intfdata(intf);
+ priv = usb_get_serial_port_data(serial->port[0]);
+
+ /*reconfigure ch341 serial port after bus-reset*/
+ ch341_configure(dev, priv);
+
+ usb_serial_resume(intf);
+
+ return 0;
}
static struct usb_driver ch341_driver = {
.name = "ch341",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
+ .suspend = usb_serial_suspend,
+ .resume = usb_serial_resume,
+ .reset_resume = ch341_reset_resume,
.id_table = id_table,
.no_dynamic_id = 1,
+ .supports_autosuspend = 1,
};
static struct usb_serial_driver ch341_device = {
@@ -317,12 +564,17 @@ static struct usb_serial_driver ch341_device = {
.owner = THIS_MODULE,
.name = "ch341-uart",
},
- .id_table = id_table,
- .usb_driver = &ch341_driver,
- .num_ports = 1,
- .open = ch341_open,
- .set_termios = ch341_set_termios,
- .attach = ch341_attach,
+ .id_table = id_table,
+ .usb_driver = &ch341_driver,
+ .num_ports = 1,
+ .open = ch341_open,
+ .close = ch341_close,
+ .ioctl = ch341_ioctl,
+ .set_termios = ch341_set_termios,
+ .tiocmget = ch341_tiocmget,
+ .tiocmset = ch341_tiocmset,
+ .read_int_callback = ch341_read_int_callback,
+ .attach = ch341_attach,
};
static int __init ch341_init(void)
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp210x.c
index cfaf1f08553..e8d5133ce9c 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp210x.c
@@ -11,10 +11,6 @@
* thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow
* control thanks to Munir Nassar nassarmu@real-time.com
*
- * Outstanding Issues:
- * Buffers are not flushed when the port is opened.
- * Multiple calls to write() may fail with "Resource temporarily unavailable"
- *
*/
#include <linux/kernel.h>
@@ -31,7 +27,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.07"
+#define DRIVER_VERSION "v0.08"
#define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
/*
@@ -42,17 +38,21 @@ static int cp2101_open(struct tty_struct *, struct usb_serial_port *,
static void cp2101_cleanup(struct usb_serial_port *);
static void cp2101_close(struct tty_struct *, struct usb_serial_port *,
struct file*);
-static void cp2101_get_termios(struct tty_struct *);
+static void cp2101_get_termios(struct tty_struct *,
+ struct usb_serial_port *port);
+static void cp2101_get_termios_port(struct usb_serial_port *port,
+ unsigned int *cflagp, unsigned int *baudp);
static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *,
struct ktermios*);
static int cp2101_tiocmget(struct tty_struct *, struct file *);
static int cp2101_tiocmset(struct tty_struct *, struct file *,
unsigned int, unsigned int);
+static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *,
+ unsigned int, unsigned int);
static void cp2101_break_ctl(struct tty_struct *, int);
static int cp2101_startup(struct usb_serial *);
static void cp2101_shutdown(struct usb_serial *);
-
static int debug;
static struct usb_device_id id_table [] = {
@@ -79,15 +79,19 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
+ { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
+ { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */
{ USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
{ USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
+ { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
@@ -222,7 +226,7 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request,
kfree(buf);
if (result != size) {
- dev_err(&port->dev, "%s - Unable to send config request, "
+ dbg("%s - Unable to send config request, "
"request=0x%x size=%d result=%d\n",
__func__, request, size, result);
return -EPROTO;
@@ -273,7 +277,7 @@ static int cp2101_set_config(struct usb_serial_port *port, u8 request,
kfree(buf);
if ((size > 2 && result != size) || result < 0) {
- dev_err(&port->dev, "%s - Unable to send request, "
+ dbg("%s - Unable to send request, "
"request=0x%x size=%d result=%d\n",
__func__, request, size, result);
return -EPROTO;
@@ -298,6 +302,47 @@ static inline int cp2101_set_config_single(struct usb_serial_port *port,
return cp2101_set_config(port, request, &data, 2);
}
+/*
+ * cp2101_quantise_baudrate
+ * Quantises the baud rate as per AN205 Table 1
+ */
+static unsigned int cp2101_quantise_baudrate(unsigned int baud) {
+ if (baud <= 56) baud = 0;
+ else if (baud <= 300) baud = 300;
+ else if (baud <= 600) baud = 600;
+ else if (baud <= 1200) baud = 1200;
+ else if (baud <= 1800) baud = 1800;
+ else if (baud <= 2400) baud = 2400;
+ else if (baud <= 4000) baud = 4000;
+ else if (baud <= 4803) baud = 4800;
+ else if (baud <= 7207) baud = 7200;
+ else if (baud <= 9612) baud = 9600;
+ else if (baud <= 14428) baud = 14400;
+ else if (baud <= 16062) baud = 16000;
+ else if (baud <= 19250) baud = 19200;
+ else if (baud <= 28912) baud = 28800;
+ else if (baud <= 38601) baud = 38400;
+ else if (baud <= 51558) baud = 51200;
+ else if (baud <= 56280) baud = 56000;
+ else if (baud <= 58053) baud = 57600;
+ else if (baud <= 64111) baud = 64000;
+ else if (baud <= 77608) baud = 76800;
+ else if (baud <= 117028) baud = 115200;
+ else if (baud <= 129347) baud = 128000;
+ else if (baud <= 156868) baud = 153600;
+ else if (baud <= 237832) baud = 230400;
+ else if (baud <= 254234) baud = 250000;
+ else if (baud <= 273066) baud = 256000;
+ else if (baud <= 491520) baud = 460800;
+ else if (baud <= 567138) baud = 500000;
+ else if (baud <= 670254) baud = 576000;
+ else if (baud <= 1053257) baud = 921600;
+ else if (baud <= 1474560) baud = 1228800;
+ else if (baud <= 2457600) baud = 1843200;
+ else baud = 3686400;
+ return baud;
+}
+
static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp)
{
@@ -328,10 +373,12 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
}
/* Configure the termios structure */
- cp2101_get_termios(tty);
+ cp2101_get_termios(tty, port);
/* Set the DTR and RTS pins low */
- cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0);
+ cp2101_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data
+ : port,
+ NULL, TIOCM_DTR | TIOCM_RTS, 0);
return 0;
}
@@ -373,9 +420,31 @@ static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
* from the device, corrects any unsupported values, and configures the
* termios structure to reflect the state of the device
*/
-static void cp2101_get_termios (struct tty_struct *tty)
+static void cp2101_get_termios(struct tty_struct *tty,
+ struct usb_serial_port *port)
+{
+ unsigned int baud;
+
+ if (tty) {
+ cp2101_get_termios_port(tty->driver_data,
+ &tty->termios->c_cflag, &baud);
+ tty_encode_baud_rate(tty, baud, baud);
+ }
+
+ else {
+ unsigned int cflag;
+ cflag = 0;
+ cp2101_get_termios_port(port, &cflag, &baud);
+ }
+}
+
+/*
+ * cp2101_get_termios_port
+ * This is the heart of cp2101_get_termios which always uses a &usb_serial_port.
+ */
+static void cp2101_get_termios_port(struct usb_serial_port *port,
+ unsigned int *cflagp, unsigned int *baudp)
{
- struct usb_serial_port *port = tty->driver_data;
unsigned int cflag, modem_ctl[4];
unsigned int baud;
unsigned int bits;
@@ -385,12 +454,12 @@ static void cp2101_get_termios (struct tty_struct *tty)
cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
/* Convert to baudrate */
if (baud)
- baud = BAUD_RATE_GEN_FREQ / baud;
+ baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
dbg("%s - baud rate = %d", __func__, baud);
+ *baudp = baud;
- tty_encode_baud_rate(tty, baud, baud);
- cflag = tty->termios->c_cflag;
+ cflag = *cflagp;
cp2101_get_config(port, CP2101_BITS, &bits, 2);
cflag &= ~CSIZE;
@@ -496,7 +565,7 @@ static void cp2101_get_termios (struct tty_struct *tty)
cflag &= ~CRTSCTS;
}
- tty->termios->c_cflag = cflag;
+ *cflagp = cflag;
}
static void cp2101_set_termios(struct tty_struct *tty,
@@ -514,46 +583,16 @@ static void cp2101_set_termios(struct tty_struct *tty,
tty->termios->c_cflag &= ~CMSPAR;
cflag = tty->termios->c_cflag;
old_cflag = old_termios->c_cflag;
- baud = tty_get_baud_rate(tty);
+ baud = cp2101_quantise_baudrate(tty_get_baud_rate(tty));
/* If the baud rate is to be updated*/
- if (baud != tty_termios_baud_rate(old_termios)) {
- switch (baud) {
- case 0:
- case 600:
- case 1200:
- case 1800:
- case 2400:
- case 4800:
- case 7200:
- case 9600:
- case 14400:
- case 19200:
- case 28800:
- case 38400:
- case 55854:
- case 57600:
- case 115200:
- case 127117:
- case 230400:
- case 460800:
- case 921600:
- case 3686400:
- break;
- default:
- baud = 9600;
- break;
- }
-
- if (baud) {
- dbg("%s - Setting baud rate to %d baud", __func__,
- baud);
- if (cp2101_set_config_single(port, CP2101_BAUDRATE,
- (BAUD_RATE_GEN_FREQ / baud))) {
- dev_err(&port->dev, "Baud rate requested not "
- "supported by device\n");
- baud = tty_termios_baud_rate(old_termios);
- }
+ if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
+ dbg("%s - Setting baud rate to %d baud", __func__,
+ baud);
+ if (cp2101_set_config_single(port, CP2101_BAUDRATE,
+ ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
+ dbg("Baud rate requested not supported by device\n");
+ baud = tty_termios_baud_rate(old_termios);
}
}
/* Report back the resulting baud rate */
@@ -585,14 +624,14 @@ static void cp2101_set_termios(struct tty_struct *tty,
dbg("%s - data bits = 9", __func__);
break;*/
default:
- dev_err(&port->dev, "cp2101 driver does not "
+ dbg("cp2101 driver does not "
"support the number of bits requested,"
" using 8 bit mode\n");
bits |= BITS_DATA_8;
break;
}
if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
- dev_err(&port->dev, "Number of data bits requested "
+ dbg("Number of data bits requested "
"not supported by device\n");
}
@@ -609,7 +648,7 @@ static void cp2101_set_termios(struct tty_struct *tty,
}
}
if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
- dev_err(&port->dev, "Parity mode not supported "
+ dbg("Parity mode not supported "
"by device\n");
}
@@ -624,7 +663,7 @@ static void cp2101_set_termios(struct tty_struct *tty,
dbg("%s - stop bits = 1", __func__);
}
if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
- dev_err(&port->dev, "Number of stop bits requested "
+ dbg("Number of stop bits requested "
"not supported by device\n");
}
@@ -658,6 +697,12 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
struct usb_serial_port *port = tty->driver_data;
+ return cp2101_tiocmset_port(port, file, set, clear);
+}
+
+static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *file,
+ unsigned int set, unsigned int clear)
+{
unsigned int control = 0;
dbg("%s - port %d", __func__, port->number);
@@ -682,7 +727,6 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file,
dbg("%s - control = 0x%.4x", __func__, control);
return cp2101_set_config(port, CP2101_CONTROL, &control, 2);
-
}
static int cp2101_tiocmget (struct tty_struct *tty, struct file *file)
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c70a8f667d8..dcc87aaa862 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -660,6 +660,14 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
+ { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
+ { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
+ { USB_DEVICE(ATMEL_VID, STK541_PID) },
+ { USB_DEVICE(DE_VID, STB_PID) },
+ { USB_DEVICE(DE_VID, WHT_PID) },
+ { USB_DEVICE(ADI_VID, ADI_GNICE_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -1062,8 +1070,10 @@ static int set_serial_info(struct tty_struct *tty,
if (!capable(CAP_SYS_ADMIN)) {
if (((new_serial.flags & ~ASYNC_USR_MASK) !=
- (priv->flags & ~ASYNC_USR_MASK)))
+ (priv->flags & ~ASYNC_USR_MASK))) {
+ unlock_kernel();
return -EPERM;
+ }
priv->flags = ((priv->flags & ~ASYNC_USR_MASK) |
(new_serial.flags & ASYNC_USR_MASK));
priv->custom_divisor = new_serial.custom_divisor;
@@ -1928,18 +1938,16 @@ static void ftdi_process_read(struct work_struct *work)
/* Compare new line status to the old one, signal if different/
N.B. packet may be processed more than once, but differences
are only processed once. */
- if (priv != NULL) {
- char new_status = data[packet_offset + 0] &
- FTDI_STATUS_B0_MASK;
- if (new_status != priv->prev_status) {
- priv->diff_status |=
- new_status ^ priv->prev_status;
- wake_up_interruptible(&priv->delta_msr_wait);
- priv->prev_status = new_status;
- }
+ char new_status = data[packet_offset + 0] &
+ FTDI_STATUS_B0_MASK;
+ if (new_status != priv->prev_status) {
+ priv->diff_status |=
+ new_status ^ priv->prev_status;
+ wake_up_interruptible(&priv->delta_msr_wait);
+ priv->prev_status = new_status;
}
- length = min(PKTSZ, urb->actual_length-packet_offset)-2;
+ length = min_t(u32, PKTSZ, urb->actual_length-packet_offset)-2;
if (length < 0) {
dev_err(&port->dev, "%s - bad packet length: %d\n",
__func__, length+2);
@@ -2284,11 +2292,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
0, 0,
buf, 1, WDR_TIMEOUT);
- if (ret < 0) {
- dbg("%s Could not get modem status of device - err: %d", __func__,
- ret);
+ if (ret < 0)
return ret;
- }
break;
case FT8U232AM:
case FT232BM:
@@ -2303,15 +2308,11 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
0, priv->interface,
buf, 2, WDR_TIMEOUT);
- if (ret < 0) {
- dbg("%s Could not get modem status of device - err: %d", __func__,
- ret);
+ if (ret < 0)
return ret;
- }
break;
default:
return -EFAULT;
- break;
}
return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 373ee09975b..daaf63db0b5 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -844,6 +844,9 @@
#define TML_VID 0x1B91 /* Vendor ID */
#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */
+/* NDI Polaris System */
+#define FTDI_NDI_HUC_PID 0xDA70
+
/* Propox devices */
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
@@ -854,6 +857,10 @@
#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */
#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */
+/* Alti-2 products http://www.alti-2.com */
+#define ALTI2_VID 0x1BC9
+#define ALTI2_N3_PID 0x6001 /* Neptune 3 */
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
@@ -881,6 +888,31 @@
#define RATOC_PRODUCT_ID_USB60F 0xb020
/*
+ * DIEBOLD BCS SE923
+ */
+#define DIEBOLD_BCS_SE923_PID 0xfb99
+
+/*
+ * Atmel STK541
+ */
+#define ATMEL_VID 0x03eb /* Vendor ID */
+#define STK541_PID 0x2109 /* Zigbee Controller */
+
+/*
+ * Dresden Elektronic Sensor Terminal Board
+ */
+#define DE_VID 0x1cf1 /* Vendor ID */
+#define STB_PID 0x0001 /* Sensor Terminal Board */
+#define WHT_PID 0x0004 /* Wireless Handheld Terminal */
+
+/*
+ * Blackfin gnICE JTAG
+ * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice
+ */
+#define ADI_VID 0x0456
+#define ADI_GNICE_PID 0xF000
+
+/*
* BmRequestType: 1100 0000b
* bRequest: FTDI_E2_READ
* wValue: 0
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 814909f1ee6..9d57cace373 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -177,14 +177,6 @@ int usb_serial_generic_resume(struct usb_serial *serial)
struct usb_serial_port *port;
int i, c = 0, r;
-#ifdef CONFIG_PM
- /*
- * If this is an autoresume, don't submit URBs.
- * They will be submitted in the open function instead.
- */
- if (serial->dev->auto_pm)
- return 0;
-#endif
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
if (port->port.count && port->read_urb) {
@@ -196,6 +188,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
return c ? -EIO : 0;
}
+EXPORT_SYMBOL_GPL(usb_serial_generic_resume);
void usb_serial_generic_close(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp)
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 132be74d2b8..ef92095b073 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -78,6 +78,7 @@ static int ipaq_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
static void ipaq_close(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
+static int ipaq_calc_num_ports(struct usb_serial *serial);
static int ipaq_startup(struct usb_serial *serial);
static void ipaq_shutdown(struct usb_serial *serial);
static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -572,15 +573,10 @@ static struct usb_serial_driver ipaq_device = {
.description = "PocketPC PDA",
.usb_driver = &ipaq_driver,
.id_table = ipaq_id_table,
- /*
- * some devices have an extra endpoint, which
- * must be ignored as it would make the core
- * create a second port which oopses when used
- */
- .num_ports = 1,
.open = ipaq_open,
.close = ipaq_close,
.attach = ipaq_startup,
+ .calc_num_ports = ipaq_calc_num_ports,
.shutdown = ipaq_shutdown,
.write = ipaq_write,
.write_room = ipaq_write_room,
@@ -956,14 +952,49 @@ static void ipaq_destroy_lists(struct usb_serial_port *port)
}
+static int ipaq_calc_num_ports(struct usb_serial *serial)
+{
+ /*
+ * some devices have 3 endpoints, the 3rd of which
+ * must be ignored as it would make the core
+ * create a second port which oopses when used
+ */
+ int ipaq_num_ports = 1;
+
+ dbg("%s - numberofendpoints: %d", __FUNCTION__,
+ (int)serial->interface->cur_altsetting->desc.bNumEndpoints);
+
+ /*
+ * a few devices have 4 endpoints, seemingly Yakuma devices,
+ * and we need the second pair, so let them have 2 ports
+ *
+ * TODO: can we drop port 1 ?
+ */
+ if (serial->interface->cur_altsetting->desc.bNumEndpoints > 3) {
+ ipaq_num_ports = 2;
+ }
+
+ return ipaq_num_ports;
+}
+
+
static int ipaq_startup(struct usb_serial *serial)
{
dbg("%s", __func__);
if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
+ /*
+ * FIXME: HP iPaq rx3715, possibly others, have 1 config that
+ * is labeled as 2
+ */
+
dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
serial->dev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
+
+ dbg("%s - iPAQ module configured for %d ports",
+ __FUNCTION__, serial->num_ports);
+
return usb_reset_configuration(serial->dev);
}
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 9878c0fb385..00daa8f7759 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1507,7 +1507,7 @@ static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint,
} else {
dev_warn(&serial->interface->dev,
"unsupported endpoint type %x\n",
- ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+ usb_endpoint_type(ep_desc));
usb_free_urb(urb);
return NULL;
}
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index cea326f1f10..839583dc8b6 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -1,8 +1,8 @@
/*
* Opticon USB barcode to serial driver
*
- * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
- * Copyright (C) 2008 Novell Inc.
+ * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (C) 2008 - 2009 Novell Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
@@ -14,6 +14,7 @@
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
+#include <linux/serial.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
@@ -40,8 +41,12 @@ struct opticon_private {
bool throttled;
bool actually_throttled;
bool rts;
+ int outstanding_urbs;
};
+/* max number of write urbs in flight */
+#define URB_UPPER_LIMIT 4
+
static void opticon_bulk_callback(struct urb *urb)
{
struct opticon_private *priv = urb->context;
@@ -106,7 +111,6 @@ static void opticon_bulk_callback(struct urb *urb)
priv->rts = false;
else
priv->rts = true;
- /* FIXME change the RTS level */
} else {
dev_dbg(&priv->udev->dev,
"Unknown data packet received from the device:"
@@ -188,6 +192,120 @@ static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port,
usb_kill_urb(priv->bulk_read_urb);
}
+static void opticon_write_bulk_callback(struct urb *urb)
+{
+ struct opticon_private *priv = urb->context;
+ int status = urb->status;
+ unsigned long flags;
+
+ /* free up the transfer buffer, as usb_free_urb() does not do this */
+ kfree(urb->transfer_buffer);
+
+ if (status)
+ dbg("%s - nonzero write bulk status received: %d",
+ __func__, status);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ --priv->outstanding_urbs;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ usb_serial_port_softint(priv->port);
+}
+
+static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
+{
+ struct opticon_private *priv = usb_get_serial_data(port->serial);
+ struct usb_serial *serial = port->serial;
+ struct urb *urb;
+ unsigned char *buffer;
+ unsigned long flags;
+ int status;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dbg("%s - write limit hit\n", __func__);
+ return 0;
+ }
+ priv->outstanding_urbs++;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ buffer = kmalloc(count, GFP_ATOMIC);
+ if (!buffer) {
+ dev_err(&port->dev, "out of memory\n");
+ count = -ENOMEM;
+ goto error_no_buffer;
+ }
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ dev_err(&port->dev, "no more free urbs\n");
+ count = -ENOMEM;
+ goto error_no_urb;
+ }
+
+ memcpy(buffer, buf, count);
+
+ usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
+
+ usb_fill_bulk_urb(urb, serial->dev,
+ usb_sndbulkpipe(serial->dev,
+ port->bulk_out_endpointAddress),
+ buffer, count, opticon_write_bulk_callback, priv);
+
+ /* send it down the pipe */
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status) {
+ dev_err(&port->dev,
+ "%s - usb_submit_urb(write bulk) failed with status = %d\n",
+ __func__, status);
+ count = status;
+ goto error;
+ }
+
+ /* we are done with this urb, so let the host driver
+ * really free it when it is finished with it */
+ usb_free_urb(urb);
+
+ return count;
+error:
+ usb_free_urb(urb);
+error_no_urb:
+ kfree(buffer);
+error_no_buffer:
+ spin_lock_irqsave(&priv->lock, flags);
+ --priv->outstanding_urbs;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return count;
+}
+
+static int opticon_write_room(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct opticon_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /*
+ * We really can take almost anything the user throws at us
+ * but let's pick a nice big number to tell the tty
+ * layer that we have lots of free space, unless we don't.
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dbg("%s - write limit hit\n", __func__);
+ return 0;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 2048;
+}
+
static void opticon_throttle(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
@@ -223,6 +341,67 @@ static void opticon_unthrottle(struct tty_struct *tty)
__func__, result);
}
+static int opticon_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct opticon_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+ int result = 0;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->rts)
+ result = TIOCM_RTS;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ dbg("%s - %x", __func__, result);
+ return result;
+}
+
+static int get_serial_info(struct opticon_private *priv,
+ struct serial_struct __user *serial)
+{
+ struct serial_struct tmp;
+
+ if (!serial)
+ return -EFAULT;
+
+ memset(&tmp, 0x00, sizeof(tmp));
+
+ /* fake emulate a 16550 uart to make userspace code happy */
+ tmp.type = PORT_16550A;
+ tmp.line = priv->serial->minor;
+ tmp.port = 0;
+ tmp.irq = 0;
+ tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+ tmp.xmit_fifo_size = 1024;
+ tmp.baud_base = 9600;
+ tmp.close_delay = 5*HZ;
+ tmp.closing_wait = 30*HZ;
+
+ if (copy_to_user(serial, &tmp, sizeof(*serial)))
+ return -EFAULT;
+ return 0;
+}
+
+static int opticon_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct opticon_private *priv = usb_get_serial_data(port->serial);
+
+ dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
+
+ switch (cmd) {
+ case TIOCGSERIAL:
+ return get_serial_info(priv,
+ (struct serial_struct __user *)arg);
+ }
+
+ return -ENOIOCTLCMD;
+}
+
static int opticon_startup(struct usb_serial *serial)
{
struct opticon_private *priv;
@@ -306,11 +485,37 @@ static void opticon_shutdown(struct usb_serial *serial)
usb_set_serial_data(serial, NULL);
}
+static int opticon_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct usb_serial *serial = usb_get_intfdata(intf);
+ struct opticon_private *priv = usb_get_serial_data(serial);
+
+ usb_kill_urb(priv->bulk_read_urb);
+ return 0;
+}
+
+static int opticon_resume(struct usb_interface *intf)
+{
+ struct usb_serial *serial = usb_get_intfdata(intf);
+ struct opticon_private *priv = usb_get_serial_data(serial);
+ struct usb_serial_port *port = serial->port[0];
+ int result;
+
+ mutex_lock(&port->mutex);
+ if (port->port.count)
+ result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO);
+ else
+ result = 0;
+ mutex_unlock(&port->mutex);
+ return result;
+}
static struct usb_driver opticon_driver = {
.name = "opticon",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
+ .suspend = opticon_suspend,
+ .resume = opticon_resume,
.id_table = id_table,
.no_dynamic_id = 1,
};
@@ -326,9 +531,13 @@ static struct usb_serial_driver opticon_device = {
.attach = opticon_startup,
.open = opticon_open,
.close = opticon_close,
+ .write = opticon_write,
+ .write_room = opticon_write_room,
.shutdown = opticon_shutdown,
.throttle = opticon_throttle,
.unthrottle = opticon_unthrottle,
+ .ioctl = opticon_ioctl,
+ .tiocmget = opticon_tiocmget,
};
static int __init opticon_init(void)
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 5ed183477aa..d560c0b54e6 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -62,6 +62,8 @@ static int option_tiocmget(struct tty_struct *tty, struct file *file);
static int option_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port);
+static int option_suspend(struct usb_serial *serial, pm_message_t message);
+static int option_resume(struct usb_serial *serial);
/* Vendor and product IDs */
#define OPTION_VENDOR_ID 0x0AF0
@@ -89,6 +91,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041
#define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061
#define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100
+#define OPTION_PRODUCT_GTM380_MODEM 0x7201
#define HUAWEI_VENDOR_ID 0x12D1
#define HUAWEI_PRODUCT_E600 0x1001
@@ -158,6 +161,13 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define HUAWEI_PRODUCT_E143E 0x143E
#define HUAWEI_PRODUCT_E143F 0x143F
+#define QUANTA_VENDOR_ID 0x0408
+#define QUANTA_PRODUCT_Q101 0xEA02
+#define QUANTA_PRODUCT_Q111 0xEA03
+#define QUANTA_PRODUCT_GLX 0xEA04
+#define QUANTA_PRODUCT_GKE 0xEA05
+#define QUANTA_PRODUCT_GLE 0xEA06
+
#define NOVATELWIRELESS_VENDOR_ID 0x1410
/* YISO PRODUCTS */
@@ -190,16 +200,18 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
/* OVATION PRODUCTS */
#define NOVATELWIRELESS_PRODUCT_MC727 0x4100
#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400
+#define NOVATELWIRELESS_PRODUCT_U727 0x5010
/* FUTURE NOVATEL PRODUCTS */
-#define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000
-#define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000
-#define NOVATELWIRELESS_PRODUCT_EMBEDDED_1 0x8000
-#define NOVATELWIRELESS_PRODUCT_GLOBAL_1 0x9000
-#define NOVATELWIRELESS_PRODUCT_EVDO_2 0x6001
-#define NOVATELWIRELESS_PRODUCT_HSPA_2 0x7001
-#define NOVATELWIRELESS_PRODUCT_EMBEDDED_2 0x8001
-#define NOVATELWIRELESS_PRODUCT_GLOBAL_2 0x9001
+#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000
+#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
+#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000
+#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001
+#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000
+#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001
+#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000
+#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001
+#define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001
/* AMOI PRODUCTS */
#define AMOI_VENDOR_ID 0x1614
@@ -209,6 +221,27 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define DELL_VENDOR_ID 0x413C
+/* Dell modems */
+#define DELL_PRODUCT_5700_MINICARD 0x8114
+#define DELL_PRODUCT_5500_MINICARD 0x8115
+#define DELL_PRODUCT_5505_MINICARD 0x8116
+#define DELL_PRODUCT_5700_EXPRESSCARD 0x8117
+#define DELL_PRODUCT_5510_EXPRESSCARD 0x8118
+
+#define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128
+#define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129
+
+#define DELL_PRODUCT_5720_MINICARD_VZW 0x8133
+#define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134
+#define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135
+#define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136
+#define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137
+#define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138
+
+#define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180
+#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181
+#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182
+
#define KYOCERA_VENDOR_ID 0x0c88
#define KYOCERA_PRODUCT_KPC650 0x17da
#define KYOCERA_PRODUCT_KPC680 0x180a
@@ -224,7 +257,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define ONDA_VENDOR_ID 0x19d2
#define ONDA_PRODUCT_MSA501HS 0x0001
#define ONDA_PRODUCT_ET502HS 0x0002
-#define ONDA_PRODUCT_MT503HS 0x0200
+#define ONDA_PRODUCT_MT503HS 0x2000
#define BANDRICH_VENDOR_ID 0x1A8D
#define BANDRICH_PRODUCT_C100_1 0x1002
@@ -259,19 +292,13 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
/* ZTE PRODUCTS */
#define ZTE_VENDOR_ID 0x19d2
+#define ZTE_PRODUCT_MF622 0x0001
#define ZTE_PRODUCT_MF628 0x0015
#define ZTE_PRODUCT_MF626 0x0031
#define ZTE_PRODUCT_CDMA_TECH 0xfffe
-/* Ericsson products */
-#define ERICSSON_VENDOR_ID 0x0bdb
-#define ERICSSON_PRODUCT_F3507G 0x1900
-
-/* Pantech products */
-#define PANTECH_VENDOR_ID 0x106c
-#define PANTECH_PRODUCT_PC5740 0x3701
-#define PANTECH_PRODUCT_PC5750 0x3702 /* PX-500 */
-#define PANTECH_PRODUCT_UM150 0x3711
+#define BENQ_VENDOR_ID 0x04a5
+#define BENQ_PRODUCT_H10 0x4068
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -298,6 +325,12 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
@@ -383,31 +416,37 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) },
- { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
@@ -472,13 +511,12 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
{ USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
+ { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
- { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) },
- { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) },
- { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) },
- { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) },
+ { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
+ { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
@@ -487,6 +525,8 @@ static struct usb_driver option_driver = {
.name = "option",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
+ .suspend = usb_serial_suspend,
+ .resume = usb_serial_resume,
.id_table = option_ids,
.no_dynamic_id = 1,
};
@@ -515,6 +555,8 @@ static struct usb_serial_driver option_1port_device = {
.attach = option_startup,
.shutdown = option_shutdown,
.read_int_callback = option_instat_callback,
+ .suspend = option_suspend,
+ .resume = option_resume,
};
static int debug;
@@ -785,10 +827,10 @@ static void option_instat_callback(struct urb *urb)
req_pkt->bRequestType, req_pkt->bRequest);
}
} else
- dbg("%s: error %d", __func__, status);
+ err("%s: error %d", __func__, status);
/* Resubmit urb so we continue receiving IRQ data */
- if (status != -ESHUTDOWN) {
+ if (status != -ESHUTDOWN && status != -ENOENT) {
urb->dev = serial->dev;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
@@ -807,7 +849,6 @@ static int option_write_room(struct tty_struct *tty)
portdata = usb_get_serial_port_data(port);
-
for (i = 0; i < N_OUT_URB; i++) {
this_urb = portdata->out_urbs[i];
if (this_urb && !test_bit(i, &portdata->out_busy))
@@ -1069,14 +1110,12 @@ bail_out_error:
return 1;
}
-static void option_shutdown(struct usb_serial *serial)
+static void stop_read_write_urbs(struct usb_serial *serial)
{
int i, j;
struct usb_serial_port *port;
struct option_port_private *portdata;
- dbg("%s", __func__);
-
/* Stop reading/writing urbs */
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
@@ -1086,6 +1125,17 @@ static void option_shutdown(struct usb_serial *serial)
for (j = 0; j < N_OUT_URB; j++)
usb_kill_urb(portdata->out_urbs[j]);
}
+}
+
+static void option_shutdown(struct usb_serial *serial)
+{
+ int i, j;
+ struct usb_serial_port *port;
+ struct option_port_private *portdata;
+
+ dbg("%s", __func__);
+
+ stop_read_write_urbs(serial);
/* Now free them */
for (i = 0; i < serial->num_ports; ++i) {
@@ -1116,6 +1166,66 @@ static void option_shutdown(struct usb_serial *serial)
}
}
+static int option_suspend(struct usb_serial *serial, pm_message_t message)
+{
+ dbg("%s entered", __func__);
+ stop_read_write_urbs(serial);
+
+ return 0;
+}
+
+static int option_resume(struct usb_serial *serial)
+{
+ int err, i, j;
+ struct usb_serial_port *port;
+ struct urb *urb;
+ struct option_port_private *portdata;
+
+ dbg("%s entered", __func__);
+ /* get the interrupt URBs resubmitted unconditionally */
+ for (i = 0; i < serial->num_ports; i++) {
+ port = serial->port[i];
+ if (!port->interrupt_in_urb) {
+ dbg("%s: No interrupt URB for port %d\n", __func__, i);
+ continue;
+ }
+ port->interrupt_in_urb->dev = serial->dev;
+ err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
+ dbg("Submitted interrupt URB for port %d (result %d)", i, err);
+ if (err < 0) {
+ err("%s: Error %d for interrupt URB of port%d",
+ __func__, err, i);
+ return err;
+ }
+ }
+
+ for (i = 0; i < serial->num_ports; i++) {
+ /* walk all ports */
+ port = serial->port[i];
+ portdata = usb_get_serial_port_data(port);
+ mutex_lock(&port->mutex);
+
+ /* skip closed ports */
+ if (!port->port.count) {
+ mutex_unlock(&port->mutex);
+ continue;
+ }
+
+ for (j = 0; j < N_IN_URB; j++) {
+ urb = portdata->in_urbs[j];
+ err = usb_submit_urb(urb, GFP_NOIO);
+ if (err < 0) {
+ mutex_unlock(&port->mutex);
+ err("%s: Error %d for bulk URB %d",
+ __func__, err, i);
+ return err;
+ }
+ }
+ mutex_unlock(&port->mutex);
+ }
+ return 0;
+}
+
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
new file mode 100644
index 00000000000..e6d6b0c17fd
--- /dev/null
+++ b/drivers/usb/serial/qcserial.c
@@ -0,0 +1,147 @@
+/*
+ * Qualcomm Serial USB driver
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated.
+ * Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (c) 2009 Novell 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.
+ *
+ */
+
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+#define DRIVER_AUTHOR "Qualcomm Inc"
+#define DRIVER_DESC "Qualcomm USB Serial driver"
+
+static int debug;
+
+static struct usb_device_id id_table[] = {
+ {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */
+ {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
+ {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
+ {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver qcdriver = {
+ .name = "qcserial",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+ .suspend = usb_serial_suspend,
+ .resume = usb_serial_resume,
+ .supports_autosuspend = true,
+};
+
+static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
+{
+ int retval = -ENODEV;
+ __u8 nintf;
+ __u8 ifnum;
+
+ dbg("%s", __func__);
+
+ nintf = serial->dev->actconfig->desc.bNumInterfaces;
+ dbg("Num Interfaces = %d", nintf);
+ ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
+ dbg("This Interface = %d", ifnum);
+
+ switch (nintf) {
+ case 1:
+ /* QDL mode */
+ if (serial->interface->num_altsetting == 2) {
+ struct usb_host_interface *intf;
+
+ intf = &serial->interface->altsetting[1];
+ if (intf->desc.bNumEndpoints == 2) {
+ if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) &&
+ usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
+ dbg("QDL port found");
+ retval = usb_set_interface(serial->dev, ifnum, 1);
+ if (retval < 0) {
+ dev_err(&serial->dev->dev,
+ "Could not set interface, error %d\n",
+ retval);
+ retval = -ENODEV;
+ }
+ return retval;
+ }
+ }
+ }
+ break;
+
+ case 4:
+ /* Composite mode */
+ if (ifnum == 2) {
+ dbg("Modem port found");
+ retval = usb_set_interface(serial->dev, ifnum, 0);
+ if (retval < 0) {
+ dev_err(&serial->dev->dev,
+ "Could not set interface, error %d\n",
+ retval);
+ retval = -ENODEV;
+ }
+ return retval;
+ }
+ break;
+
+ default:
+ dev_err(&serial->dev->dev,
+ "unknown number of interfaces: %d\n", nintf);
+ return -ENODEV;
+ }
+
+ return retval;
+}
+
+static struct usb_serial_driver qcdevice = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "qcserial",
+ },
+ .description = "Qualcomm USB modem",
+ .id_table = id_table,
+ .usb_driver = &qcdriver,
+ .num_ports = 1,
+ .probe = qcprobe,
+};
+
+static int __init qcinit(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&qcdevice);
+ if (retval)
+ return retval;
+
+ retval = usb_register(&qcdriver);
+ if (retval) {
+ usb_serial_deregister(&qcdevice);
+ return retval;
+ }
+
+ return 0;
+}
+
+static void __exit qcexit(void)
+{
+ usb_deregister(&qcdriver);
+ usb_serial_deregister(&qcdevice);
+}
+
+module_init(qcinit);
+module_exit(qcexit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
new file mode 100644
index 00000000000..8b3cbc87adc
--- /dev/null
+++ b/drivers/usb/serial/symbolserial.c
@@ -0,0 +1,399 @@
+/*
+ * Symbol USB barcode to serial driver
+ *
+ * Copyright (C) 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (C) 2009 Novell 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+#include <linux/uaccess.h>
+
+static int debug;
+
+static struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x05e0, 0x0600) },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* This structure holds all of the individual device information */
+struct symbol_private {
+ struct usb_device *udev;
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+ unsigned char *int_buffer;
+ struct urb *int_urb;
+ int buffer_size;
+ u8 bInterval;
+ u8 int_address;
+ spinlock_t lock; /* protects the following flags */
+ bool throttled;
+ bool actually_throttled;
+ bool rts;
+};
+
+static void symbol_int_callback(struct urb *urb)
+{
+ struct symbol_private *priv = urb->context;
+ unsigned char *data = urb->transfer_buffer;
+ struct usb_serial_port *port = priv->port;
+ int status = urb->status;
+ struct tty_struct *tty;
+ int result;
+ int available_room = 0;
+ int data_length;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ switch (status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d",
+ __func__, status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d",
+ __func__, status);
+ goto exit;
+ }
+
+ usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length,
+ data);
+
+ if (urb->actual_length > 1) {
+ data_length = urb->actual_length - 1;
+
+ /*
+ * Data from the device comes with a 1 byte header:
+ *
+ * <size of data>data...
+ * This is real data to be sent to the tty layer
+ * we pretty much just ignore the size and send everything
+ * else to the tty layer.
+ */
+ tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ available_room = tty_buffer_request_room(tty,
+ data_length);
+ if (available_room) {
+ tty_insert_flip_string(tty, &data[1],
+ available_room);
+ tty_flip_buffer_push(tty);
+ }
+ tty_kref_put(tty);
+ }
+ } else {
+ dev_dbg(&priv->udev->dev,
+ "Improper ammount of data received from the device, "
+ "%d bytes", urb->actual_length);
+ }
+
+exit:
+ spin_lock(&priv->lock);
+
+ /* Continue trying to always read if we should */
+ if (!priv->throttled) {
+ usb_fill_int_urb(priv->int_urb, priv->udev,
+ usb_rcvintpipe(priv->udev,
+ priv->int_address),
+ priv->int_buffer, priv->buffer_size,
+ symbol_int_callback, priv, priv->bInterval);
+ result = usb_submit_urb(priv->int_urb, GFP_ATOMIC);
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
+ } else
+ priv->actually_throttled = true;
+ spin_unlock(&priv->lock);
+}
+
+static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct symbol_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+ int result = 0;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->throttled = false;
+ priv->actually_throttled = false;
+ priv->port = port;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /*
+ * Force low_latency on so that our tty_push actually forces the data
+ * through, otherwise it is scheduled, and with high data rates (like
+ * with OHCI) data can get lost.
+ */
+ if (tty)
+ tty->low_latency = 1;
+
+ /* Start reading from the device */
+ usb_fill_int_urb(priv->int_urb, priv->udev,
+ usb_rcvintpipe(priv->udev, priv->int_address),
+ priv->int_buffer, priv->buffer_size,
+ symbol_int_callback, priv, priv->bInterval);
+ result = usb_submit_urb(priv->int_urb, GFP_KERNEL);
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
+ return result;
+}
+
+static void symbol_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct symbol_private *priv = usb_get_serial_data(port->serial);
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /* shutdown our urbs */
+ usb_kill_urb(priv->int_urb);
+}
+
+static void symbol_throttle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct symbol_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+
+ dbg("%s - port %d", __func__, port->number);
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->throttled = true;
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void symbol_unthrottle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct symbol_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+ int result;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->throttled = false;
+ priv->actually_throttled = false;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ priv->int_urb->dev = port->serial->dev;
+ result = usb_submit_urb(priv->int_urb, GFP_ATOMIC);
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
+}
+
+static int symbol_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct device *dev = &port->dev;
+
+ /*
+ * Right now we need to figure out what commands
+ * most userspace tools want to see for this driver,
+ * so just log the things.
+ */
+ switch (cmd) {
+ case TIOCSERGETLSR:
+ dev_info(dev, "%s: TIOCSERGETLSR\n", __func__);
+ break;
+
+ case TIOCGSERIAL:
+ dev_info(dev, "%s: TIOCGSERIAL\n", __func__);
+ break;
+
+ case TIOCMIWAIT:
+ dev_info(dev, "%s: TIOCMIWAIT\n", __func__);
+ break;
+
+ case TIOCGICOUNT:
+ dev_info(dev, "%s: TIOCGICOUNT\n", __func__);
+ break;
+ default:
+ dev_info(dev, "%s: unknown (%d)\n", __func__, cmd);
+ }
+ return -ENOIOCTLCMD;
+}
+
+static int symbol_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct device *dev = &port->dev;
+
+ /* TODO */
+ /* probably just need to shadow whatever was sent to us here */
+ dev_info(dev, "%s\n", __func__);
+ return 0;
+}
+
+static int symbol_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct device *dev = &port->dev;
+
+ /* TODO */
+ /* probably just need to shadow whatever was sent to us here */
+ dev_info(dev, "%s\n", __func__);
+ return 0;
+}
+
+static int symbol_startup(struct usb_serial *serial)
+{
+ struct symbol_private *priv;
+ struct usb_host_interface *intf;
+ int i;
+ int retval = -ENOMEM;
+ bool int_in_found = false;
+
+ /* create our private serial structure */
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (priv == NULL) {
+ dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
+ return -ENOMEM;
+ }
+ spin_lock_init(&priv->lock);
+ priv->serial = serial;
+ priv->port = serial->port[0];
+ priv->udev = serial->dev;
+
+ /* find our interrupt endpoint */
+ intf = serial->interface->altsetting;
+ for (i = 0; i < intf->desc.bNumEndpoints; ++i) {
+ struct usb_endpoint_descriptor *endpoint;
+
+ endpoint = &intf->endpoint[i].desc;
+ if (!usb_endpoint_is_int_in(endpoint))
+ continue;
+
+ priv->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!priv->int_urb) {
+ dev_err(&priv->udev->dev, "out of memory\n");
+ goto error;
+ }
+
+ priv->buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;
+ priv->int_buffer = kmalloc(priv->buffer_size, GFP_KERNEL);
+ if (!priv->int_buffer) {
+ dev_err(&priv->udev->dev, "out of memory\n");
+ goto error;
+ }
+
+ priv->int_address = endpoint->bEndpointAddress;
+ priv->bInterval = endpoint->bInterval;
+
+ /* set up our int urb */
+ usb_fill_int_urb(priv->int_urb, priv->udev,
+ usb_rcvintpipe(priv->udev,
+ endpoint->bEndpointAddress),
+ priv->int_buffer, priv->buffer_size,
+ symbol_int_callback, priv, priv->bInterval);
+
+ int_in_found = true;
+ break;
+ }
+
+ if (!int_in_found) {
+ dev_err(&priv->udev->dev,
+ "Error - the proper endpoints were not found!\n");
+ goto error;
+ }
+
+ usb_set_serial_data(serial, priv);
+ return 0;
+
+error:
+ usb_free_urb(priv->int_urb);
+ kfree(priv->int_buffer);
+ kfree(priv);
+ return retval;
+}
+
+static void symbol_shutdown(struct usb_serial *serial)
+{
+ struct symbol_private *priv = usb_get_serial_data(serial);
+
+ dbg("%s", __func__);
+
+ usb_kill_urb(priv->int_urb);
+ usb_free_urb(priv->int_urb);
+ kfree(priv->int_buffer);
+ kfree(priv);
+ usb_set_serial_data(serial, NULL);
+}
+
+static struct usb_driver symbol_driver = {
+ .name = "symbol",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+ .no_dynamic_id = 1,
+};
+
+static struct usb_serial_driver symbol_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "symbol",
+ },
+ .id_table = id_table,
+ .usb_driver = &symbol_driver,
+ .num_ports = 1,
+ .attach = symbol_startup,
+ .open = symbol_open,
+ .close = symbol_close,
+ .shutdown = symbol_shutdown,
+ .throttle = symbol_throttle,
+ .unthrottle = symbol_unthrottle,
+ .ioctl = symbol_ioctl,
+ .tiocmget = symbol_tiocmget,
+ .tiocmset = symbol_tiocmset,
+};
+
+static int __init symbol_init(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&symbol_device);
+ if (retval)
+ return retval;
+ retval = usb_register(&symbol_driver);
+ if (retval)
+ usb_serial_deregister(&symbol_device);
+ return retval;
+}
+
+static void __exit symbol_exit(void)
+{
+ usb_deregister(&symbol_driver);
+ usb_serial_deregister(&symbol_device);
+}
+
+module_init(symbol_init);
+module_exit(symbol_exit);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 3cf41df302d..2620bf6fe5e 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -176,7 +176,7 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -184,16 +184,20 @@ static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -205,6 +209,9 @@ static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] =
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
{ }
};
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index 7e4752fbf23..f323c602585 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -27,7 +27,11 @@
/* Vendor and product ids */
#define TI_VENDOR_ID 0x0451
+#define IBM_VENDOR_ID 0x04b3
#define TI_3410_PRODUCT_ID 0x3410
+#define IBM_4543_PRODUCT_ID 0x4543
+#define IBM_454B_PRODUCT_ID 0x454b
+#define IBM_454C_PRODUCT_ID 0x454c
#define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */
#define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */
#define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index cfcfd5ab06c..742a5bc44be 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -204,6 +204,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
goto bailout_kref_put;
}
+ if (port->serial->disconnected) {
+ retval = -ENODEV;
+ goto bailout_kref_put;
+ }
+
if (mutex_lock_interruptible(&port->mutex)) {
retval = -ERESTARTSYS;
goto bailout_kref_put;
@@ -1067,6 +1072,8 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
struct usb_serial_port *port;
int i, r = 0;
+ serial->suspending = 1;
+
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port)
@@ -1083,10 +1090,15 @@ EXPORT_SYMBOL(usb_serial_suspend);
int usb_serial_resume(struct usb_interface *intf)
{
struct usb_serial *serial = usb_get_intfdata(intf);
+ int rv;
+ serial->suspending = 0;
if (serial->type->resume)
- return serial->type->resume(serial);
- return 0;
+ rv = serial->type->resume(serial);
+ else
+ rv = usb_serial_generic_resume(serial);
+
+ return rv;
}
EXPORT_SYMBOL(usb_serial_resume);
@@ -1222,7 +1234,6 @@ static void fixup_generic(struct usb_serial_driver *device)
set_to_generic_if_null(device, read_bulk_callback);
set_to_generic_if_null(device, write_bulk_callback);
set_to_generic_if_null(device, shutdown);
- set_to_generic_if_null(device, resume);
}
int usb_serial_register(struct usb_serial_driver *driver)
@@ -1230,6 +1241,9 @@ int usb_serial_register(struct usb_serial_driver *driver)
/* must be called with BKL held */
int retval;
+ if (usb_disabled())
+ return -ENODEV;
+
fixup_generic(driver);
if (!driver->description)
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 9df6887b91f..8a372bac0e4 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -2,8 +2,8 @@
# USB Storage driver configuration
#
-comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;"
-comment "see USB_STORAGE Help for more information"
+comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may"
+comment "also be needed; see USB_STORAGE Help for more info"
depends on USB
config USB_STORAGE
@@ -32,21 +32,25 @@ config USB_STORAGE_DEBUG
verbose debugging messages.
config USB_STORAGE_DATAFAB
- bool "Datafab Compact Flash Reader support"
+ tristate "Datafab Compact Flash Reader support"
depends on USB_STORAGE
help
Support for certain Datafab CompactFlash readers.
Datafab has a web page at <http://www.datafabusa.com/>.
+ If this driver is compiled as a module, it will be named ums-datafab.
+
config USB_STORAGE_FREECOM
- bool "Freecom USB/ATAPI Bridge support"
+ tristate "Freecom USB/ATAPI Bridge support"
depends on USB_STORAGE
help
Support for the Freecom USB to IDE/ATAPI adaptor.
Freecom has a web page at <http://www.freecom.de/>.
+ If this driver is compiled as a module, it will be named ums-freecom.
+
config USB_STORAGE_ISD200
- bool "ISD-200 USB/ATA Bridge support"
+ tristate "ISD-200 USB/ATA Bridge support"
depends on USB_STORAGE
---help---
Say Y here if you want to use USB Mass Store devices based
@@ -61,8 +65,10 @@ config USB_STORAGE_ISD200
- CyQ've CQ8060A CDRW drive
- Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U)
+ If this driver is compiled as a module, it will be named ums-isd200.
+
config USB_STORAGE_USBAT
- bool "USBAT/USBAT02-based storage support"
+ tristate "USBAT/USBAT02-based storage support"
depends on USB_STORAGE
help
Say Y here to include additional code to support storage devices
@@ -82,30 +88,38 @@ config USB_STORAGE_USBAT
- RCA LYRA MP3 portable
- Sandisk ImageMate SDDR-05b
+ If this driver is compiled as a module, it will be named ums-usbat.
+
config USB_STORAGE_SDDR09
- bool "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support"
+ tristate "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Sandisk SDDR-09
SmartMedia reader in the USB Mass Storage driver.
Also works for the Microtech Zio! CompactFlash/SmartMedia reader.
+ If this driver is compiled as a module, it will be named ums-sddr09.
+
config USB_STORAGE_SDDR55
- bool "SanDisk SDDR-55 SmartMedia support"
+ tristate "SanDisk SDDR-55 SmartMedia support"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Sandisk SDDR-55
SmartMedia reader in the USB Mass Storage driver.
+ If this driver is compiled as a module, it will be named ums-sddr55.
+
config USB_STORAGE_JUMPSHOT
- bool "Lexar Jumpshot Compact Flash Reader"
+ tristate "Lexar Jumpshot Compact Flash Reader"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Lexar Jumpshot
USB CompactFlash reader.
+ If this driver is compiled as a module, it will be named ums-jumpshot.
+
config USB_STORAGE_ALAUDA
- bool "Olympus MAUSB-10/Fuji DPC-R1 support"
+ tristate "Olympus MAUSB-10/Fuji DPC-R1 support"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Olympus MAUSB-10
@@ -114,8 +128,10 @@ config USB_STORAGE_ALAUDA
These devices are based on the Alauda chip and support both
XD and SmartMedia cards.
+ If this driver is compiled as a module, it will be named ums-alauda.
+
config USB_STORAGE_ONETOUCH
- bool "Support OneTouch Button on Maxtor Hard Drives"
+ tristate "Support OneTouch Button on Maxtor Hard Drives"
depends on USB_STORAGE
depends on INPUT=y || INPUT=USB_STORAGE
help
@@ -127,8 +143,10 @@ config USB_STORAGE_ONETOUCH
this input in any keybinding software. (e.g. gnome's keyboard short-
cuts)
+ If this driver is compiled as a module, it will be named ums-onetouch.
+
config USB_STORAGE_KARMA
- bool "Support for Rio Karma music player"
+ tristate "Support for Rio Karma music player"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Rio Karma
@@ -139,8 +157,10 @@ config USB_STORAGE_KARMA
on the resulting scsi device node returns the Karma to normal
operation.
+ If this driver is compiled as a module, it will be named ums-karma.
+
config USB_STORAGE_CYPRESS_ATACB
- bool "SAT emulation on Cypress USB/ATA Bridge with ATACB"
+ tristate "SAT emulation on Cypress USB/ATA Bridge with ATACB"
depends on USB_STORAGE
---help---
Say Y here if you want to use SAT (ata pass through) on devices based
@@ -150,6 +170,8 @@ config USB_STORAGE_CYPRESS_ATACB
If you say no here your device will still work with the standard usb
mass storage class.
+ If this driver is compiled as a module, it will be named ums-cypress.
+
config USB_LIBUSUAL
bool "The shared table of common (or usual) storage devices"
depends on USB
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index b3206931339..5be54c01966 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -10,21 +10,36 @@ EXTRA_CFLAGS := -Idrivers/scsi
obj-$(CONFIG_USB_STORAGE) += usb-storage.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_USBAT) += shuttle_usbat.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55) += sddr55.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o
usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y)
-ifneq ($(CONFIG_USB_LIBUSUAL),)
- obj-$(CONFIG_USB) += libusual.o
+ifeq ($(CONFIG_USB_LIBUSUAL),)
+ usb-storage-objs += usual-tables.o
+else
+ obj-$(CONFIG_USB) += libusual.o usual-tables.o
endif
+
+obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o
+obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += ums-cypress.o
+obj-$(CONFIG_USB_STORAGE_DATAFAB) += ums-datafab.o
+obj-$(CONFIG_USB_STORAGE_FREECOM) += ums-freecom.o
+obj-$(CONFIG_USB_STORAGE_ISD200) += ums-isd200.o
+obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += ums-jumpshot.o
+obj-$(CONFIG_USB_STORAGE_KARMA) += ums-karma.o
+obj-$(CONFIG_USB_STORAGE_ONETOUCH) += ums-onetouch.o
+obj-$(CONFIG_USB_STORAGE_SDDR09) += ums-sddr09.o
+obj-$(CONFIG_USB_STORAGE_SDDR55) += ums-sddr55.o
+obj-$(CONFIG_USB_STORAGE_USBAT) += ums-usbat.o
+
+ums-alauda-objs := alauda.o
+ums-cypress-objs := cypress_atacb.o
+ums-datafab-objs := datafab.o
+ums-freecom-objs := freecom.o
+ums-isd200-objs := isd200.o
+ums-jumpshot-objs := jumpshot.o
+ums-karma-objs := karma.o
+ums-onetouch-objs := onetouch.o
+ums-sddr09-objs := sddr09.o
+ums-sddr55-objs := sddr55.o
+ums-usbat-objs := shuttle_usbat.o
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 8d3711a7ff0..67edc65acb8 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -31,6 +31,8 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/module.h>
+
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
@@ -39,7 +41,79 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "alauda.h"
+
+MODULE_DESCRIPTION("Driver for Alauda-based card readers");
+MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>");
+MODULE_LICENSE("GPL");
+
+/*
+ * Status bytes
+ */
+#define ALAUDA_STATUS_ERROR 0x01
+#define ALAUDA_STATUS_READY 0x40
+
+/*
+ * Control opcodes (for request field)
+ */
+#define ALAUDA_GET_XD_MEDIA_STATUS 0x08
+#define ALAUDA_GET_SM_MEDIA_STATUS 0x98
+#define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a
+#define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a
+#define ALAUDA_GET_XD_MEDIA_SIG 0x86
+#define ALAUDA_GET_SM_MEDIA_SIG 0x96
+
+/*
+ * Bulk command identity (byte 0)
+ */
+#define ALAUDA_BULK_CMD 0x40
+
+/*
+ * Bulk opcodes (byte 1)
+ */
+#define ALAUDA_BULK_GET_REDU_DATA 0x85
+#define ALAUDA_BULK_READ_BLOCK 0x94
+#define ALAUDA_BULK_ERASE_BLOCK 0xa3
+#define ALAUDA_BULK_WRITE_BLOCK 0xb4
+#define ALAUDA_BULK_GET_STATUS2 0xb7
+#define ALAUDA_BULK_RESET_MEDIA 0xe0
+
+/*
+ * Port to operate on (byte 8)
+ */
+#define ALAUDA_PORT_XD 0x00
+#define ALAUDA_PORT_SM 0x01
+
+/*
+ * LBA and PBA are unsigned ints. Special values.
+ */
+#define UNDEF 0xffff
+#define SPARE 0xfffe
+#define UNUSABLE 0xfffd
+
+struct alauda_media_info {
+ unsigned long capacity; /* total media size in bytes */
+ unsigned int pagesize; /* page size in bytes */
+ unsigned int blocksize; /* number of pages per block */
+ unsigned int uzonesize; /* number of usable blocks per zone */
+ unsigned int zonesize; /* number of blocks per zone */
+ unsigned int blockmask; /* mask to get page from address */
+
+ unsigned char pageshift;
+ unsigned char blockshift;
+ unsigned char zoneshift;
+
+ u16 **lba_to_pba; /* logical to physical block map */
+ u16 **pba_to_lba; /* physical to logical block map */
+};
+
+struct alauda_info {
+ struct alauda_media_info port[2];
+ int wr_ep; /* endpoint to write data out of */
+
+ unsigned char sense_key;
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
+};
#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
#define LSB_of(s) ((s)&0xFF)
@@ -52,6 +126,48 @@
#define PBA_HI(pba) (pba >> 3)
#define PBA_ZONE(pba) (pba >> 11)
+static int init_alauda(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id alauda_usb_ids[] = {
+# include "unusual_alauda.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, alauda_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev alauda_unusual_dev_list[] = {
+# include "unusual_alauda.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
/*
* Media handling
*/
@@ -307,7 +423,8 @@ static int alauda_init_media(struct us_data *us)
data[0], data[1], data[2], data[3]);
media_info = alauda_card_find_id(data[1]);
if (media_info == NULL) {
- printk("alauda_init_media: Unrecognised media signature: "
+ printk(KERN_WARNING
+ "alauda_init_media: Unrecognised media signature: "
"%02X %02X %02X %02X\n",
data[0], data[1], data[2], data[3]);
return USB_STOR_TRANSPORT_ERROR;
@@ -518,7 +635,8 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
/* check even parity */
if (parity[data[6] ^ data[7]]) {
- printk("alauda_read_map: Bad parity in LBA for block %d"
+ printk(KERN_WARNING
+ "alauda_read_map: Bad parity in LBA for block %d"
" (%02X %02X)\n", i, data[6], data[7]);
pba_to_lba[i] = UNUSABLE;
continue;
@@ -538,13 +656,16 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
*/
if (lba_offset >= uzonesize) {
- printk("alauda_read_map: Bad low LBA %d for block %d\n",
+ printk(KERN_WARNING
+ "alauda_read_map: Bad low LBA %d for block %d\n",
lba_real, blocknum);
continue;
}
if (lba_to_pba[lba_offset] != UNDEF) {
- printk("alauda_read_map: LBA %d seen for PBA %d and %d\n",
+ printk(KERN_WARNING
+ "alauda_read_map: "
+ "LBA %d seen for PBA %d and %d\n",
lba_real, lba_to_pba[lba_offset], blocknum);
continue;
}
@@ -712,13 +833,15 @@ static int alauda_write_lba(struct us_data *us, u16 lba,
if (pba == 1) {
/* Maybe it is impossible to write to PBA 1.
Fake success, but don't do anything. */
- printk("alauda_write_lba: avoid writing to pba 1\n");
+ printk(KERN_WARNING
+ "alauda_write_lba: avoid writing to pba 1\n");
return USB_STOR_TRANSPORT_GOOD;
}
new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone);
if (!new_pba) {
- printk("alauda_write_lba: Out of unused blocks\n");
+ printk(KERN_WARNING
+ "alauda_write_lba: Out of unused blocks\n");
return USB_STOR_TRANSPORT_ERROR;
}
@@ -818,7 +941,7 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
len = min(sectors, blocksize) * (pagesize + 64);
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL) {
- printk("alauda_read_data: Out of memory\n");
+ printk(KERN_WARNING "alauda_read_data: Out of memory\n");
return USB_STOR_TRANSPORT_ERROR;
}
@@ -911,7 +1034,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
len = min(sectors, blocksize) * pagesize;
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL) {
- printk("alauda_write_data: Out of memory\n");
+ printk(KERN_WARNING "alauda_write_data: Out of memory\n");
return USB_STOR_TRANSPORT_ERROR;
}
@@ -921,7 +1044,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
*/
blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO);
if (blockbuffer == NULL) {
- printk("alauda_write_data: Out of memory\n");
+ printk(KERN_WARNING "alauda_write_data: Out of memory\n");
kfree(buffer);
return USB_STOR_TRANSPORT_ERROR;
}
@@ -991,7 +1114,7 @@ static void alauda_info_destructor(void *extra)
/*
* Initialize alauda_info struct and find the data-write endpoint
*/
-int init_alauda(struct us_data *us)
+static int init_alauda(struct us_data *us)
{
struct alauda_info *info;
struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
@@ -1013,7 +1136,7 @@ int init_alauda(struct us_data *us)
return USB_STOR_TRANSPORT_GOOD;
}
-int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int rc;
struct alauda_info *info = (struct alauda_info *) us->extra;
@@ -1121,3 +1244,48 @@ int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
return USB_STOR_TRANSPORT_FAILED;
}
+static int alauda_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - alauda_usb_ids) + alauda_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Alauda Control/Bulk";
+ us->transport = alauda_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+ us->max_lun = 1;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver alauda_driver = {
+ .name = "ums-alauda",
+ .probe = alauda_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = alauda_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init alauda_init(void)
+{
+ return usb_register(&alauda_driver);
+}
+
+static void __exit alauda_exit(void)
+{
+ usb_deregister(&alauda_driver);
+}
+
+module_init(alauda_init);
+module_exit(alauda_exit);
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h
deleted file mode 100644
index a700f87d080..00000000000
--- a/drivers/usb/storage/alauda.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Driver for Alauda-based card readers
- *
- * Current development and maintenance by:
- * (c) 2005 Daniel Drake <dsd@gentoo.org>
- *
- * See alauda.c for more explanation.
- *
- * 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, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_ALAUDA_H
-#define _USB_ALAUDA_H
-
-/*
- * Status bytes
- */
-#define ALAUDA_STATUS_ERROR 0x01
-#define ALAUDA_STATUS_READY 0x40
-
-/*
- * Control opcodes (for request field)
- */
-#define ALAUDA_GET_XD_MEDIA_STATUS 0x08
-#define ALAUDA_GET_SM_MEDIA_STATUS 0x98
-#define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a
-#define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a
-#define ALAUDA_GET_XD_MEDIA_SIG 0x86
-#define ALAUDA_GET_SM_MEDIA_SIG 0x96
-
-/*
- * Bulk command identity (byte 0)
- */
-#define ALAUDA_BULK_CMD 0x40
-
-/*
- * Bulk opcodes (byte 1)
- */
-#define ALAUDA_BULK_GET_REDU_DATA 0x85
-#define ALAUDA_BULK_READ_BLOCK 0x94
-#define ALAUDA_BULK_ERASE_BLOCK 0xa3
-#define ALAUDA_BULK_WRITE_BLOCK 0xb4
-#define ALAUDA_BULK_GET_STATUS2 0xb7
-#define ALAUDA_BULK_RESET_MEDIA 0xe0
-
-/*
- * Port to operate on (byte 8)
- */
-#define ALAUDA_PORT_XD 0x00
-#define ALAUDA_PORT_SM 0x01
-
-/*
- * LBA and PBA are unsigned ints. Special values.
- */
-#define UNDEF 0xffff
-#define SPARE 0xfffe
-#define UNUSABLE 0xfffd
-
-int init_alauda(struct us_data *us);
-int alauda_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct alauda_media_info {
- unsigned long capacity; /* total media size in bytes */
- unsigned int pagesize; /* page size in bytes */
- unsigned int blocksize; /* number of pages per block */
- unsigned int uzonesize; /* number of usable blocks per zone */
- unsigned int zonesize; /* number of blocks per zone */
- unsigned int blockmask; /* mask to get page from address */
-
- unsigned char pageshift;
- unsigned char blockshift;
- unsigned char zoneshift;
-
- u16 **lba_to_pba; /* logical to physical block map */
- u16 **pba_to_lba; /* physical to logical block map */
-};
-
-struct alauda_info {
- struct alauda_media_info port[2];
- int wr_ep; /* endpoint to write data out of */
-
- unsigned char sense_key;
- unsigned long sense_asc; /* additional sense code */
- unsigned long sense_ascq; /* additional sense code qualifier */
-};
-
-#endif
-
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c
index 898e67d30e5..c8447182118 100644
--- a/drivers/usb/storage/cypress_atacb.c
+++ b/drivers/usb/storage/cypress_atacb.c
@@ -19,6 +19,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/module.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_eh.h>
@@ -29,6 +30,49 @@
#include "scsiglue.h"
#include "debug.h"
+MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB");
+MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>");
+MODULE_LICENSE("GPL");
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id cypress_usb_ids[] = {
+# include "unusual_cypress.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, cypress_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev cypress_unusual_dev_list[] = {
+# include "unusual_cypress.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
/*
* ATACB is a protocol used on cypress usb<->ata bridge to
* send raw ATA command over mass storage
@@ -36,7 +80,7 @@
* More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf
* datasheet from cypress.com.
*/
-void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
+static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
{
unsigned char save_cmnd[MAX_COMMAND_SIZE];
@@ -133,19 +177,18 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
/* build the command for
* reading the ATA registers */
- scsi_eh_prep_cmnd(srb, &ses, NULL, 0, 0);
- srb->sdb.length = sizeof(regs);
- sg_init_one(&ses.sense_sgl, regs, srb->sdb.length);
- srb->sdb.table.sgl = &ses.sense_sgl;
- srb->sc_data_direction = DMA_FROM_DEVICE;
- srb->sdb.table.nents = 1;
+ scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sizeof(regs));
+
/* we use the same command as before, but we set
* the read taskfile bit, for not executing atacb command,
* but reading register selected in srb->cmnd[4]
*/
+ srb->cmd_len = 16;
+ srb->cmnd = ses.cmnd;
srb->cmnd[2] = 1;
usb_stor_transparent_scsi_command(srb, us);
+ memcpy(regs, srb->sense_buffer, sizeof(regs));
tmp_result = srb->result;
scsi_eh_restore_cmnd(srb, &ses);
/* we fail to get registers, report invalid command */
@@ -162,8 +205,8 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
/* XXX we should generate sk, asc, ascq from status and error
* regs
- * (see 11.1 Error translation ­ ATA device error to SCSI error map)
- * and ata_to_sense_error from libata.
+ * (see 11.1 Error translation ATA device error to SCSI error
+ * map, and ata_to_sense_error from libata.)
*/
/* Sense data is current and format is descriptor. */
@@ -198,3 +241,48 @@ end:
if (srb->cmnd[0] == ATA_12)
srb->cmd_len = 12;
}
+
+
+static int cypress_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - cypress_usb_ids) + cypress_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->protocol_name = "Transparent SCSI with Cypress ATACB";
+ us->proto_handler = cypress_atacb_passthrough;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver cypress_driver = {
+ .name = "ums-cypress",
+ .probe = cypress_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = cypress_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init cypress_init(void)
+{
+ return usb_register(&cypress_driver);
+}
+
+static void __exit cypress_exit(void)
+{
+ usb_deregister(&cypress_driver);
+}
+
+module_init(cypress_init);
+module_exit(cypress_exit);
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
index 17f1ae23291..2b6e565262c 100644
--- a/drivers/usb/storage/datafab.c
+++ b/drivers/usb/storage/datafab.c
@@ -49,6 +49,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -58,12 +59,65 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "datafab.h"
+
+MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader");
+MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>");
+MODULE_LICENSE("GPL");
+
+struct datafab_info {
+ unsigned long sectors; /* total sector count */
+ unsigned long ssize; /* sector size in bytes */
+ signed char lun; /* used for dual-slot readers */
+
+ /* the following aren't used yet */
+ unsigned char sense_key;
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
+};
static int datafab_determine_lun(struct us_data *us,
struct datafab_info *info);
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id datafab_usb_ids[] = {
+# include "unusual_datafab.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, datafab_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev datafab_unusual_dev_list[] = {
+# include "unusual_datafab.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
static inline int
datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) {
if (len == 0)
@@ -500,7 +554,7 @@ static void datafab_info_destructor(void *extra)
// Transport for the Datafab MDCFE-B
//
-int datafab_transport(struct scsi_cmnd * srb, struct us_data *us)
+static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us)
{
struct datafab_info *info;
int rc;
@@ -665,3 +719,49 @@ int datafab_transport(struct scsi_cmnd * srb, struct us_data *us)
info->sense_ascq = 0x00;
return USB_STOR_TRANSPORT_FAILED;
}
+
+static int datafab_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - datafab_usb_ids) + datafab_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Datafab Bulk-Only";
+ us->transport = datafab_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+ us->max_lun = 1;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver datafab_driver = {
+ .name = "ums-datafab",
+ .probe = datafab_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = datafab_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init datafab_init(void)
+{
+ return usb_register(&datafab_driver);
+}
+
+static void __exit datafab_exit(void)
+{
+ usb_deregister(&datafab_driver);
+}
+
+module_init(datafab_init);
+module_exit(datafab_exit);
diff --git a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h
deleted file mode 100644
index 32e3f271e58..00000000000
--- a/drivers/usb/storage/datafab.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Driver for Datafab MDCFE-B USB Compact Flash reader
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2000 Jimmie Mayfield (mayfield+datafab@sackheads.org)
- *
- * See datafab.c for more explanation
- *
- * 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, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_DATAFAB_MDCFE_B_H
-#define _USB_DATAFAB_MDCFE_B_H
-
-extern int datafab_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct datafab_info {
- unsigned long sectors; // total sector count
- unsigned long ssize; // sector size in bytes
- signed char lun; // used for dual-slot readers
-
- // the following aren't used yet
- unsigned char sense_key;
- unsigned long sense_asc; // additional sense code
- unsigned long sense_ascq; // additional sense code qualifier
-};
-
-#endif
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
index 73ac7262239..54cc94277ac 100644
--- a/drivers/usb/storage/freecom.c
+++ b/drivers/usb/storage/freecom.c
@@ -26,6 +26,7 @@
* (http://www.freecom.de/)
*/
+#include <linux/module.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -33,7 +34,10 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "freecom.h"
+
+MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor");
+MODULE_AUTHOR("David Brown <usb-storage@davidb.org>");
+MODULE_LICENSE("GPL");
#ifdef CONFIG_USB_STORAGE_DEBUG
static void pdump (void *, int);
@@ -103,6 +107,47 @@ struct freecom_status {
#define FCM_PACKET_LENGTH 64
#define FCM_STATUS_PACKET_LENGTH 4
+static int init_freecom(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id freecom_usb_ids[] = {
+# include "unusual_freecom.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, freecom_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev freecom_unusual_dev_list[] = {
+# include "unusual_freecom.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
static int
freecom_readdata (struct scsi_cmnd *srb, struct us_data *us,
unsigned int ipipe, unsigned int opipe, int count)
@@ -173,7 +218,7 @@ freecom_writedata (struct scsi_cmnd *srb, struct us_data *us,
* Transport for the Freecom USB/IDE adaptor.
*
*/
-int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
{
struct freecom_cb_wrap *fcb;
struct freecom_status *fst;
@@ -377,8 +422,7 @@ int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
return USB_STOR_TRANSPORT_GOOD;
}
-int
-freecom_init (struct us_data *us)
+static int init_freecom(struct us_data *us)
{
int result;
char *buffer = us->iobuf;
@@ -417,7 +461,7 @@ freecom_init (struct us_data *us)
return USB_STOR_TRANSPORT_GOOD;
}
-int usb_stor_freecom_reset(struct us_data *us)
+static int usb_stor_freecom_reset(struct us_data *us)
{
printk (KERN_CRIT "freecom reset called\n");
@@ -479,3 +523,48 @@ static void pdump (void *ibuffer, int length)
}
#endif
+static int freecom_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - freecom_usb_ids) + freecom_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Freecom";
+ us->transport = freecom_transport;
+ us->transport_reset = usb_stor_freecom_reset;
+ us->max_lun = 0;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver freecom_driver = {
+ .name = "ums-freecom",
+ .probe = freecom_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = freecom_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init freecom_init(void)
+{
+ return usb_register(&freecom_driver);
+}
+
+static void __exit freecom_exit(void)
+{
+ usb_deregister(&freecom_driver);
+}
+
+module_init(freecom_init);
+module_exit(freecom_exit);
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 383abf2516a..882c57b399f 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -44,6 +44,7 @@
#include <linux/jiffies.h>
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/hdreg.h>
#include <linux/scatterlist.h>
@@ -57,7 +58,53 @@
#include "protocol.h"
#include "debug.h"
#include "scsiglue.h"
-#include "isd200.h"
+
+MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC");
+MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>");
+MODULE_LICENSE("GPL");
+
+static int isd200_Initialization(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id isd200_usb_ids[] = {
+# include "unusual_isd200.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, isd200_usb_ids);
+
+#undef UNUSUAL_DEV
+#undef USUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev isd200_unusual_dev_list[] = {
+# include "unusual_isd200.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+#undef USUAL_DEV
/* Timeout defines (in Seconds) */
@@ -1518,7 +1565,7 @@ static int isd200_init_info(struct us_data *us)
* Initialization for the ISD200
*/
-int isd200_Initialization(struct us_data *us)
+static int isd200_Initialization(struct us_data *us)
{
US_DEBUGP("ISD200 Initialization...\n");
@@ -1549,7 +1596,7 @@ int isd200_Initialization(struct us_data *us)
*
*/
-void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
+static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
{
int sendToTransport = 1, orig_bufflen;
union ata_cdb ataCdb;
@@ -1570,3 +1617,47 @@ void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
isd200_srb_set_bufflen(srb, orig_bufflen);
}
+
+static int isd200_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - isd200_usb_ids) + isd200_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->protocol_name = "ISD200 ATA/ATAPI";
+ us->proto_handler = isd200_ata_command;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver isd200_driver = {
+ .name = "ums-isd200",
+ .probe = isd200_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = isd200_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init isd200_init(void)
+{
+ return usb_register(&isd200_driver);
+}
+
+static void __exit isd200_exit(void)
+{
+ usb_deregister(&isd200_driver);
+}
+
+module_init(isd200_init);
+module_exit(isd200_exit);
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
index df67f13c9e7..1c69420e3ac 100644
--- a/drivers/usb/storage/jumpshot.c
+++ b/drivers/usb/storage/jumpshot.c
@@ -46,6 +46,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -55,9 +56,61 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "jumpshot.h"
+MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader");
+MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>");
+MODULE_LICENSE("GPL");
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id jumpshot_usb_ids[] = {
+# include "unusual_jumpshot.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, jumpshot_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev jumpshot_unusual_dev_list[] = {
+# include "unusual_jumpshot.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
+struct jumpshot_info {
+ unsigned long sectors; /* total sector count */
+ unsigned long ssize; /* sector size in bytes */
+
+ /* the following aren't used yet */
+ unsigned char sense_key;
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
+};
+
static inline int jumpshot_bulk_read(struct us_data *us,
unsigned char *data,
unsigned int len)
@@ -429,7 +482,7 @@ static void jumpshot_info_destructor(void *extra)
// Transport for the Lexar 'Jumpshot'
//
-int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us)
+static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us)
{
struct jumpshot_info *info;
int rc;
@@ -592,3 +645,49 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us)
info->sense_ascq = 0x00;
return USB_STOR_TRANSPORT_FAILED;
}
+
+static int jumpshot_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - jumpshot_usb_ids) + jumpshot_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Lexar Jumpshot Control/Bulk";
+ us->transport = jumpshot_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+ us->max_lun = 1;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver jumpshot_driver = {
+ .name = "ums-jumpshot",
+ .probe = jumpshot_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = jumpshot_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init jumpshot_init(void)
+{
+ return usb_register(&jumpshot_driver);
+}
+
+static void __exit jumpshot_exit(void)
+{
+ usb_deregister(&jumpshot_driver);
+}
+
+module_init(jumpshot_init);
+module_exit(jumpshot_exit);
diff --git a/drivers/usb/storage/jumpshot.h b/drivers/usb/storage/jumpshot.h
deleted file mode 100644
index 19bac9d1558..00000000000
--- a/drivers/usb/storage/jumpshot.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Driver for Lexar "Jumpshot" USB Compact Flash reader
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2000 Jimmie Mayfield (mayfield+usb@sackheads.org)
- *
- * See jumpshot.c for more explanation
- *
- * 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, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_JUMPSHOT_H
-#define _USB_JUMPSHOT_H
-
-extern int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct jumpshot_info {
- unsigned long sectors; // total sector count
- unsigned long ssize; // sector size in bytes
-
- // the following aren't used yet
- unsigned char sense_key;
- unsigned long sense_asc; // additional sense code
- unsigned long sense_ascq; // additional sense code qualifier
-};
-
-#endif
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c
index 0d79ae5683f..7953d93a773 100644
--- a/drivers/usb/storage/karma.c
+++ b/drivers/usb/storage/karma.c
@@ -18,6 +18,8 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/module.h>
+
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
@@ -25,7 +27,10 @@
#include "usb.h"
#include "transport.h"
#include "debug.h"
-#include "karma.h"
+
+MODULE_DESCRIPTION("Driver for Rio Karma");
+MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>");
+MODULE_LICENSE("GPL");
#define RIO_PREFIX "RIOP\x00"
#define RIO_PREFIX_LEN 5
@@ -36,13 +41,53 @@
#define RIO_LEAVE_STORAGE 0x2
#define RIO_RESET 0xC
-extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data *);
-
struct karma_data {
int in_storage;
char *recv;
};
+static int rio_karma_init(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id karma_usb_ids[] = {
+# include "unusual_karma.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, karma_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev karma_unusual_dev_list[] = {
+# include "unusual_karma.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
/*
* Send commands to Rio Karma.
*
@@ -104,7 +149,7 @@ err:
* Trap START_STOP and READ_10 to leave/re-enter storage mode.
* Everything else is propagated to the normal bulk layer.
*/
-int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int ret;
struct karma_data *data = (struct karma_data *) us->extra;
@@ -133,7 +178,7 @@ static void rio_karma_destructor(void *extra)
kfree(data->recv);
}
-int rio_karma_init(struct us_data *us)
+static int rio_karma_init(struct us_data *us)
{
int ret = 0;
struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO);
@@ -153,3 +198,48 @@ int rio_karma_init(struct us_data *us)
out:
return ret;
}
+
+static int karma_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - karma_usb_ids) + karma_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Rio Karma/Bulk";
+ us->transport = rio_karma_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver karma_driver = {
+ .name = "ums-karma",
+ .probe = karma_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = karma_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init karma_init(void)
+{
+ return usb_register(&karma_driver);
+}
+
+static void __exit karma_exit(void)
+{
+ usb_deregister(&karma_driver);
+}
+
+module_init(karma_init);
+module_exit(karma_exit);
diff --git a/drivers/usb/storage/karma.h b/drivers/usb/storage/karma.h
deleted file mode 100644
index 8a60972af8c..00000000000
--- a/drivers/usb/storage/karma.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _KARMA_USB_H
-#define _KARMA_USB_H
-
-extern int rio_karma_init(struct us_data *us);
-extern int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-#endif
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c
index f970b27ba30..fe3ffe1459b 100644
--- a/drivers/usb/storage/libusual.c
+++ b/drivers/usb/storage/libusual.c
@@ -38,37 +38,6 @@ static atomic_t total_threads = ATOMIC_INIT(0);
static int usu_probe_thread(void *arg);
/*
- * The table.
- */
-#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
- vendorName, productName,useProtocol, useTransport, \
- initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
- .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
-
-#define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
- vendorName, productName, useProtocol, useTransport, \
- initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
- .driver_info = (flags) }
-
-#define USUAL_DEV(useProto, useTrans, useType) \
-{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
- .driver_info = ((useType)<<24) }
-
-struct usb_device_id storage_usb_ids [] = {
-# include "unusual_devs.h"
- { } /* Terminating entry */
-};
-
-#undef USUAL_DEV
-#undef UNUSUAL_DEV
-#undef COMPLIANT_DEV
-
-MODULE_DEVICE_TABLE(usb, storage_usb_ids);
-EXPORT_SYMBOL_GPL(storage_usb_ids);
-
-/*
* @type: the module type as an integer
*/
void usb_usual_set_present(int type)
@@ -167,7 +136,7 @@ static struct usb_driver usu_driver = {
.name = "libusual",
.probe = usu_probe,
.disconnect = usu_disconnect,
- .id_table = storage_usb_ids,
+ .id_table = usb_storage_usb_ids,
};
/*
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index c7bf8954b4e..380233bd6a3 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -35,9 +35,16 @@
#include <linux/module.h>
#include <linux/usb/input.h>
#include "usb.h"
-#include "onetouch.h"
#include "debug.h"
+MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver");
+MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>");
+MODULE_LICENSE("GPL");
+
+#define ONETOUCH_PKT_LEN 0x02
+#define ONETOUCH_BUTTON KEY_PROG1
+
+static int onetouch_connect_input(struct us_data *ss);
static void onetouch_release_input(void *onetouch_);
struct usb_onetouch {
@@ -52,6 +59,46 @@ struct usb_onetouch {
unsigned int is_open:1;
};
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id onetouch_usb_ids[] = {
+# include "unusual_onetouch.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, onetouch_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev onetouch_unusual_dev_list[] = {
+# include "unusual_onetouch.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
static void usb_onetouch_irq(struct urb *urb)
{
struct usb_onetouch *onetouch = urb->context;
@@ -127,7 +174,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action)
}
#endif /* CONFIG_PM */
-int onetouch_connect_input(struct us_data *ss)
+static int onetouch_connect_input(struct us_data *ss)
{
struct usb_device *udev = ss->pusb_dev;
struct usb_host_interface *interface;
@@ -236,3 +283,46 @@ static void onetouch_release_input(void *onetouch_)
onetouch->data, onetouch->data_dma);
}
}
+
+static int onetouch_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - onetouch_usb_ids) + onetouch_unusual_dev_list);
+ if (result)
+ return result;
+
+ /* Use default transport and protocol */
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver onetouch_driver = {
+ .name = "ums-onetouch",
+ .probe = onetouch_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = onetouch_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init onetouch_init(void)
+{
+ return usb_register(&onetouch_driver);
+}
+
+static void __exit onetouch_exit(void)
+{
+ usb_deregister(&onetouch_driver);
+}
+
+module_init(onetouch_init);
+module_exit(onetouch_exit);
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h
deleted file mode 100644
index 41c7aa8f044..00000000000
--- a/drivers/usb/storage/onetouch.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _ONETOUCH_H_
-#define _ONETOUCH_H_
-
-#define ONETOUCH_PKT_LEN 0x02
-#define ONETOUCH_BUTTON KEY_PROG1
-
-int onetouch_connect_input(struct us_data *ss);
-
-#endif
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index be441d84bc6..fc310f75ead 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -121,6 +121,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
/* send the command to the transport layer */
usb_stor_invoke_transport(srb, us);
}
+EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command);
/***********************************************************************
* Scatter-gather transfer buffer access routines
@@ -199,6 +200,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
/* Return the amount actually transferred */
return cnt;
}
+EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf);
/* Store the contents of buffer into srb's transfer buffer and set the
* SCSI residue.
@@ -215,3 +217,4 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
if (buflen < scsi_bufflen(srb))
scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
}
+EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf);
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 2a42b862aa9..4ca3b586064 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -64,6 +64,7 @@
*/
#define VENDOR_ID_NOKIA 0x0421
#define VENDOR_ID_NIKON 0x04b0
+#define VENDOR_ID_PENTAX 0x0a17
#define VENDOR_ID_MOTOROLA 0x22b8
/***********************************************************************
@@ -134,6 +135,12 @@ static int slave_configure(struct scsi_device *sdev)
if (sdev->request_queue->max_sectors > max_sectors)
blk_queue_max_sectors(sdev->request_queue,
max_sectors);
+ } else if (sdev->type == TYPE_TAPE) {
+ /* Tapes need much higher max_sector limits, so just
+ * raise it to the maximum possible (4 GB / 512) and
+ * let the queue segment size sort out the real limit.
+ */
+ blk_queue_max_sectors(sdev->request_queue, 0x7FFFFF);
}
/* Some USB host controllers can't do DMA; they have to use PIO.
@@ -158,6 +165,7 @@ static int slave_configure(struct scsi_device *sdev)
switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) {
case VENDOR_ID_NOKIA:
case VENDOR_ID_NIKON:
+ case VENDOR_ID_PENTAX:
case VENDOR_ID_MOTOROLA:
if (!(us->fflags & (US_FL_FIX_CAPACITY |
US_FL_CAPACITY_OK)))
@@ -561,4 +569,4 @@ unsigned char usb_stor_sense_invalidCDB[18] = {
[7] = 0x0a, /* additional length */
[12] = 0x24 /* Invalid Field in CDB */
};
-
+EXPORT_SYMBOL_GPL(usb_stor_sense_invalidCDB);
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index 531ae5c5abf..ab5f9f37575 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -41,6 +41,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -51,7 +52,53 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "sddr09.h"
+
+MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader");
+MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>");
+MODULE_LICENSE("GPL");
+
+static int usb_stor_sddr09_dpcm_init(struct us_data *us);
+static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
+static int usb_stor_sddr09_init(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id sddr09_usb_ids[] = {
+# include "unusual_sddr09.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, sddr09_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev sddr09_unusual_dev_list[] = {
+# include "unusual_sddr09.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
@@ -723,7 +770,7 @@ sddr09_read_data(struct us_data *us,
len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL) {
- printk("sddr09_read_data: Out of memory\n");
+ printk(KERN_WARNING "sddr09_read_data: Out of memory\n");
return -ENOMEM;
}
@@ -838,7 +885,8 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
if (pba == UNDEF) {
pba = sddr09_find_unused_pba(info, lba);
if (!pba) {
- printk("sddr09_write_lba: Out of unused blocks\n");
+ printk(KERN_WARNING
+ "sddr09_write_lba: Out of unused blocks\n");
return -ENOSPC;
}
info->pba_to_lba[pba] = lba;
@@ -849,7 +897,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
if (pba == 1) {
/* Maybe it is impossible to write to PBA 1.
Fake success, but don't do anything. */
- printk("sddr09: avoid writing to pba 1\n");
+ printk(KERN_WARNING "sddr09: avoid writing to pba 1\n");
return 0;
}
@@ -954,7 +1002,7 @@ sddr09_write_data(struct us_data *us,
blocklen = (pagelen << info->blockshift);
blockbuffer = kmalloc(blocklen, GFP_NOIO);
if (!blockbuffer) {
- printk("sddr09_write_data: Out of memory\n");
+ printk(KERN_WARNING "sddr09_write_data: Out of memory\n");
return -ENOMEM;
}
@@ -965,7 +1013,7 @@ sddr09_write_data(struct us_data *us,
len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL) {
- printk("sddr09_write_data: Out of memory\n");
+ printk(KERN_WARNING "sddr09_write_data: Out of memory\n");
kfree(blockbuffer);
return -ENOMEM;
}
@@ -1112,7 +1160,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
if (result) {
US_DEBUGP("Result of read_deviceID is %d\n", result);
- printk("sddr09: could not read card info\n");
+ printk(KERN_WARNING "sddr09: could not read card info\n");
return NULL;
}
@@ -1153,7 +1201,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
sprintf(blurbtxt + strlen(blurbtxt),
", WP");
- printk("%s\n", blurbtxt);
+ printk(KERN_WARNING "%s\n", blurbtxt);
return cardinfo;
}
@@ -1184,7 +1232,7 @@ sddr09_read_map(struct us_data *us) {
alloc_len = (alloc_blocks << CONTROL_SHIFT);
buffer = kmalloc(alloc_len, GFP_NOIO);
if (buffer == NULL) {
- printk("sddr09_read_map: out of memory\n");
+ printk(KERN_WARNING "sddr09_read_map: out of memory\n");
result = -1;
goto done;
}
@@ -1198,7 +1246,7 @@ sddr09_read_map(struct us_data *us) {
info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO);
if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) {
- printk("sddr09_read_map: out of memory\n");
+ printk(KERN_WARNING "sddr09_read_map: out of memory\n");
result = -1;
goto done;
}
@@ -1238,7 +1286,8 @@ sddr09_read_map(struct us_data *us) {
if (ptr[j] != 0)
goto nonz;
info->pba_to_lba[i] = UNUSABLE;
- printk("sddr09: PBA %d has no logical mapping\n", i);
+ printk(KERN_WARNING "sddr09: PBA %d has no logical mapping\n",
+ i);
continue;
nonz:
@@ -1251,7 +1300,8 @@ sddr09_read_map(struct us_data *us) {
nonff:
/* normal PBAs start with six FFs */
if (j < 6) {
- printk("sddr09: PBA %d has no logical mapping: "
+ printk(KERN_WARNING
+ "sddr09: PBA %d has no logical mapping: "
"reserved area = %02X%02X%02X%02X "
"data status %02X block status %02X\n",
i, ptr[0], ptr[1], ptr[2], ptr[3],
@@ -1261,7 +1311,8 @@ sddr09_read_map(struct us_data *us) {
}
if ((ptr[6] >> 4) != 0x01) {
- printk("sddr09: PBA %d has invalid address field "
+ printk(KERN_WARNING
+ "sddr09: PBA %d has invalid address field "
"%02X%02X/%02X%02X\n",
i, ptr[6], ptr[7], ptr[11], ptr[12]);
info->pba_to_lba[i] = UNUSABLE;
@@ -1270,7 +1321,8 @@ sddr09_read_map(struct us_data *us) {
/* check even parity */
if (parity[ptr[6] ^ ptr[7]]) {
- printk("sddr09: Bad parity in LBA for block %d"
+ printk(KERN_WARNING
+ "sddr09: Bad parity in LBA for block %d"
" (%02X %02X)\n", i, ptr[6], ptr[7]);
info->pba_to_lba[i] = UNUSABLE;
continue;
@@ -1289,7 +1341,8 @@ sddr09_read_map(struct us_data *us) {
*/
if (lba >= 1000) {
- printk("sddr09: Bad low LBA %d for block %d\n",
+ printk(KERN_WARNING
+ "sddr09: Bad low LBA %d for block %d\n",
lba, i);
goto possibly_erase;
}
@@ -1297,7 +1350,8 @@ sddr09_read_map(struct us_data *us) {
lba += 1000*(i/0x400);
if (info->lba_to_pba[lba] != UNDEF) {
- printk("sddr09: LBA %d seen for PBA %d and %d\n",
+ printk(KERN_WARNING
+ "sddr09: LBA %d seen for PBA %d and %d\n",
lba, info->lba_to_pba[lba], i);
goto possibly_erase;
}
@@ -1399,7 +1453,7 @@ sddr09_common_init(struct us_data *us) {
* unusual devices list but called from here then LUN 0 of the combo reader
* is not recognized. But I do not know what precisely these calls do.
*/
-int
+static int
usb_stor_sddr09_dpcm_init(struct us_data *us) {
int result;
unsigned char *data = us->iobuf;
@@ -1449,7 +1503,7 @@ usb_stor_sddr09_dpcm_init(struct us_data *us) {
/*
* Transport for the Microtech DPCM-USB
*/
-int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int ret;
@@ -1491,7 +1545,7 @@ int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
/*
* Transport for the Sandisk SDDR-09
*/
-int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
{
static unsigned char sensekey = 0, sensecode = 0;
static unsigned char havefakesense = 0;
@@ -1690,7 +1744,60 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
/*
* Initialization routine for the sddr09 subdriver
*/
-int
+static int
usb_stor_sddr09_init(struct us_data *us) {
return sddr09_common_init(us);
}
+
+static int sddr09_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - sddr09_usb_ids) + sddr09_unusual_dev_list);
+ if (result)
+ return result;
+
+ if (us->protocol == US_PR_DPCM_USB) {
+ us->transport_name = "Control/Bulk-EUSB/SDDR09";
+ us->transport = dpcm_transport;
+ us->transport_reset = usb_stor_CB_reset;
+ us->max_lun = 1;
+ } else {
+ us->transport_name = "EUSB/SDDR09";
+ us->transport = sddr09_transport;
+ us->transport_reset = usb_stor_CB_reset;
+ us->max_lun = 0;
+ }
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver sddr09_driver = {
+ .name = "ums-sddr09",
+ .probe = sddr09_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = sddr09_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init sddr09_init(void)
+{
+ return usb_register(&sddr09_driver);
+}
+
+static void __exit sddr09_exit(void)
+{
+ usb_deregister(&sddr09_driver);
+}
+
+module_init(sddr09_init);
+module_exit(sddr09_exit);
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h
deleted file mode 100644
index b701172e12e..00000000000
--- a/drivers/usb/storage/sddr09.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Driver for SanDisk SDDR-09 SmartMedia reader
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2000 Robert Baruch (autophile@dol.net)
- * (c) 2002 Andries Brouwer (aeb@cwi.nl)
- *
- * See sddr09.c for more explanation
- *
- * 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, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_SHUTTLE_EUSB_SDDR09_H
-#define _USB_SHUTTLE_EUSB_SDDR09_H
-
-/* Sandisk SDDR-09 stuff */
-
-extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_sddr09_init(struct us_data *us);
-
-/* Microtech DPCM-USB stuff */
-
-extern int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_sddr09_dpcm_init(struct us_data *us);
-
-#endif
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
index 0d8df757789..44dfed7754e 100644
--- a/drivers/usb/storage/sddr55.c
+++ b/drivers/usb/storage/sddr55.c
@@ -24,6 +24,7 @@
#include <linux/jiffies.h>
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -33,7 +34,48 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "sddr55.h"
+
+MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader");
+MODULE_AUTHOR("Simon Munton");
+MODULE_LICENSE("GPL");
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id sddr55_usb_ids[] = {
+# include "unusual_sddr55.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, sddr55_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev sddr55_unusual_dev_list[] = {
+# include "unusual_sddr55.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
@@ -513,7 +555,8 @@ static int sddr55_read_deviceID(struct us_data *us,
}
-int sddr55_reset(struct us_data *us) {
+static int sddr55_reset(struct us_data *us)
+{
return 0;
}
@@ -703,7 +746,9 @@ static int sddr55_read_map(struct us_data *us) {
if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED &&
!info->force_read_only) {
- printk("sddr55: map inconsistency at LBA %04X\n", lba + zone * 1000);
+ printk(KERN_WARNING
+ "sddr55: map inconsistency at LBA %04X\n",
+ lba + zone * 1000);
info->force_read_only = 1;
}
@@ -732,7 +777,7 @@ static void sddr55_card_info_destructor(void *extra) {
/*
* Transport for the Sandisk SDDR-55
*/
-int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int result;
static unsigned char inquiry_response[8] = {
@@ -929,3 +974,49 @@ int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer?
}
+
+static int sddr55_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - sddr55_usb_ids) + sddr55_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "SDDR55";
+ us->transport = sddr55_transport;
+ us->transport_reset = sddr55_reset;
+ us->max_lun = 0;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver sddr55_driver = {
+ .name = "ums-sddr55",
+ .probe = sddr55_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = sddr55_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init sddr55_init(void)
+{
+ return usb_register(&sddr55_driver);
+}
+
+static void __exit sddr55_exit(void)
+{
+ usb_deregister(&sddr55_driver);
+}
+
+module_init(sddr55_init);
+module_exit(sddr55_exit);
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index ae6d64810d2..b62a28814eb 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -42,6 +42,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/cdrom.h>
@@ -52,7 +53,100 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "shuttle_usbat.h"
+
+MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable");
+MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>");
+MODULE_LICENSE("GPL");
+
+/* Supported device types */
+#define USBAT_DEV_HP8200 0x01
+#define USBAT_DEV_FLASH 0x02
+
+#define USBAT_EPP_PORT 0x10
+#define USBAT_EPP_REGISTER 0x30
+#define USBAT_ATA 0x40
+#define USBAT_ISA 0x50
+
+/* Commands (need to be logically OR'd with an access type */
+#define USBAT_CMD_READ_REG 0x00
+#define USBAT_CMD_WRITE_REG 0x01
+#define USBAT_CMD_READ_BLOCK 0x02
+#define USBAT_CMD_WRITE_BLOCK 0x03
+#define USBAT_CMD_COND_READ_BLOCK 0x04
+#define USBAT_CMD_COND_WRITE_BLOCK 0x05
+#define USBAT_CMD_WRITE_REGS 0x07
+
+/* Commands (these don't need an access type) */
+#define USBAT_CMD_EXEC_CMD 0x80
+#define USBAT_CMD_SET_FEAT 0x81
+#define USBAT_CMD_UIO 0x82
+
+/* Methods of accessing UIO register */
+#define USBAT_UIO_READ 1
+#define USBAT_UIO_WRITE 0
+
+/* Qualifier bits */
+#define USBAT_QUAL_FCQ 0x20 /* full compare */
+#define USBAT_QUAL_ALQ 0x10 /* auto load subcount */
+
+/* USBAT Flash Media status types */
+#define USBAT_FLASH_MEDIA_NONE 0
+#define USBAT_FLASH_MEDIA_CF 1
+
+/* USBAT Flash Media change types */
+#define USBAT_FLASH_MEDIA_SAME 0
+#define USBAT_FLASH_MEDIA_CHANGED 1
+
+/* USBAT ATA registers */
+#define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */
+#define USBAT_ATA_FEATURES 0x11 /* set features (W) */
+#define USBAT_ATA_ERROR 0x11 /* error (R) */
+#define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */
+#define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */
+#define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */
+#define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */
+#define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */
+#define USBAT_ATA_STATUS 0x17 /* device status (R) */
+#define USBAT_ATA_CMD 0x17 /* device command (W) */
+#define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */
+
+/* USBAT User I/O Data registers */
+#define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */
+#define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */
+ /* CDT = ACKD & !UI1 & !UI0 */
+#define USBAT_UIO_1 0x20 /* I/O 1 */
+#define USBAT_UIO_0 0x10 /* I/O 0 */
+#define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */
+#define USBAT_UIO_UI1 0x04 /* Input 1 */
+#define USBAT_UIO_UI0 0x02 /* Input 0 */
+#define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */
+
+/* USBAT User I/O Enable registers */
+#define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */
+#define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */
+#define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */
+ /* If ACKD=1, set OE1 to 1 also. */
+#define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */
+#define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */
+
+/* USBAT Features */
+#define USBAT_FEAT_ETEN 0x80 /* External trigger enable */
+#define USBAT_FEAT_U1 0x08
+#define USBAT_FEAT_U0 0x04
+#define USBAT_FEAT_ET1 0x02
+#define USBAT_FEAT_ET2 0x01
+
+struct usbat_info {
+ int devicetype;
+
+ /* Used for Flash readers only */
+ unsigned long sectors; /* total sector count */
+ unsigned long ssize; /* sector size in bytes */
+
+ unsigned char sense_key;
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
+};
#define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) )
#define LSB_of(s) ((s)&0xFF)
@@ -63,6 +157,48 @@ static int transferred = 0;
static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us);
static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us);
+static int init_usbat_cd(struct us_data *us);
+static int init_usbat_flash(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id usbat_usb_ids[] = {
+# include "unusual_usbat.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, usbat_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev usbat_unusual_dev_list[] = {
+# include "unusual_usbat.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
/*
* Convenience function to produce an ATA read/write sectors command
* Use cmd=0x20 for read, cmd=0x30 for write
@@ -1684,37 +1820,61 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
return USB_STOR_TRANSPORT_FAILED;
}
-int init_usbat_cd(struct us_data *us)
+static int init_usbat_cd(struct us_data *us)
{
return init_usbat(us, USBAT_DEV_HP8200);
}
-
-int init_usbat_flash(struct us_data *us)
+static int init_usbat_flash(struct us_data *us)
{
return init_usbat(us, USBAT_DEV_FLASH);
}
-int init_usbat_probe(struct us_data *us)
+static int usbat_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
- return init_usbat(us, 0);
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - usbat_usb_ids) + usbat_unusual_dev_list);
+ if (result)
+ return result;
+
+ /* The actual transport will be determined later by the
+ * initialization routine; this is just a placeholder.
+ */
+ us->transport_name = "Shuttle USBAT";
+ us->transport = usbat_flash_transport;
+ us->transport_reset = usb_stor_CB_reset;
+ us->max_lun = 1;
+
+ result = usb_stor_probe2(us);
+ return result;
}
-/*
- * Default transport function. Attempts to detect which transport function
- * should be called, makes it the new default, and calls it.
- *
- * This function should never be called. Our usbat_init() function detects the
- * device type and changes the us->transport ptr to the transport function
- * relevant to the device.
- * However, we'll support this impossible(?) case anyway.
- */
-int usbat_transport(struct scsi_cmnd *srb, struct us_data *us)
+static struct usb_driver usbat_driver = {
+ .name = "ums-usbat",
+ .probe = usbat_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = usbat_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init usbat_init(void)
{
- struct usbat_info *info = (struct usbat_info*) (us->extra);
-
- if (usbat_set_transport(us, info, 0))
- return USB_STOR_TRANSPORT_ERROR;
+ return usb_register(&usbat_driver);
+}
- return us->transport(srb, us);
+static void __exit usbat_exit(void)
+{
+ usb_deregister(&usbat_driver);
}
+
+module_init(usbat_init);
+module_exit(usbat_exit);
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h
deleted file mode 100644
index d8bfc43e904..00000000000
--- a/drivers/usb/storage/shuttle_usbat.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Driver for SCM Microsystems USB-ATAPI cable
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2000 Robert Baruch (autophile@dol.net)
- * (c) 2004, 2005 Daniel Drake <dsd@gentoo.org>
- *
- * See shuttle_usbat.c for more explanation
- *
- * 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, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_SHUTTLE_USBAT_H
-#define _USB_SHUTTLE_USBAT_H
-
-/* Supported device types */
-#define USBAT_DEV_HP8200 0x01
-#define USBAT_DEV_FLASH 0x02
-
-#define USBAT_EPP_PORT 0x10
-#define USBAT_EPP_REGISTER 0x30
-#define USBAT_ATA 0x40
-#define USBAT_ISA 0x50
-
-/* Commands (need to be logically OR'd with an access type */
-#define USBAT_CMD_READ_REG 0x00
-#define USBAT_CMD_WRITE_REG 0x01
-#define USBAT_CMD_READ_BLOCK 0x02
-#define USBAT_CMD_WRITE_BLOCK 0x03
-#define USBAT_CMD_COND_READ_BLOCK 0x04
-#define USBAT_CMD_COND_WRITE_BLOCK 0x05
-#define USBAT_CMD_WRITE_REGS 0x07
-
-/* Commands (these don't need an access type) */
-#define USBAT_CMD_EXEC_CMD 0x80
-#define USBAT_CMD_SET_FEAT 0x81
-#define USBAT_CMD_UIO 0x82
-
-/* Methods of accessing UIO register */
-#define USBAT_UIO_READ 1
-#define USBAT_UIO_WRITE 0
-
-/* Qualifier bits */
-#define USBAT_QUAL_FCQ 0x20 /* full compare */
-#define USBAT_QUAL_ALQ 0x10 /* auto load subcount */
-
-/* USBAT Flash Media status types */
-#define USBAT_FLASH_MEDIA_NONE 0
-#define USBAT_FLASH_MEDIA_CF 1
-
-/* USBAT Flash Media change types */
-#define USBAT_FLASH_MEDIA_SAME 0
-#define USBAT_FLASH_MEDIA_CHANGED 1
-
-/* USBAT ATA registers */
-#define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */
-#define USBAT_ATA_FEATURES 0x11 /* set features (W) */
-#define USBAT_ATA_ERROR 0x11 /* error (R) */
-#define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */
-#define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */
-#define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */
-#define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */
-#define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */
-#define USBAT_ATA_STATUS 0x17 /* device status (R) */
-#define USBAT_ATA_CMD 0x17 /* device command (W) */
-#define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */
-
-/* USBAT User I/O Data registers */
-#define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */
-#define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */
- /* CDT = ACKD & !UI1 & !UI0 */
-#define USBAT_UIO_1 0x20 /* I/O 1 */
-#define USBAT_UIO_0 0x10 /* I/O 0 */
-#define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */
-#define USBAT_UIO_UI1 0x04 /* Input 1 */
-#define USBAT_UIO_UI0 0x02 /* Input 0 */
-#define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */
-
-/* USBAT User I/O Enable registers */
-#define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */
-#define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */
-#define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */
- /* If ACKD=1, set OE1 to 1 also. */
-#define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */
-#define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */
-
-/* USBAT Features */
-#define USBAT_FEAT_ETEN 0x80 /* External trigger enable */
-#define USBAT_FEAT_U1 0x08
-#define USBAT_FEAT_U0 0x04
-#define USBAT_FEAT_ET1 0x02
-#define USBAT_FEAT_ET2 0x01
-
-extern int usbat_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int init_usbat_cd(struct us_data *us);
-extern int init_usbat_flash(struct us_data *us);
-extern int init_usbat_probe(struct us_data *us);
-
-struct usbat_info {
- int devicetype;
-
- /* Used for Flash readers only */
- unsigned long sectors; /* total sector count */
- unsigned long ssize; /* sector size in bytes */
-
- unsigned char sense_key;
- unsigned long sense_asc; /* additional sense code */
- unsigned long sense_ascq; /* additional sense code qualifier */
-};
-
-#endif
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 1d5438e6363..d48c8553539 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -220,6 +220,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
status = us->current_urb->actual_length;
return status;
}
+EXPORT_SYMBOL_GPL(usb_stor_control_msg);
/* This is a version of usb_clear_halt() that allows early termination and
* doesn't read the status from the device -- this is because some devices
@@ -254,6 +255,7 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
US_DEBUGP("%s: result = %d\n", __func__, result);
return result;
}
+EXPORT_SYMBOL_GPL(usb_stor_clear_halt);
/*
@@ -352,6 +354,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
return interpret_urb_result(us, pipe, size, result,
us->current_urb->actual_length);
}
+EXPORT_SYMBOL_GPL(usb_stor_ctrl_transfer);
/*
* Receive one interrupt buffer, without timeouts, but allowing early
@@ -407,6 +410,7 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
return interpret_urb_result(us, pipe, length, result,
us->current_urb->actual_length);
}
+EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_buf);
/*
* Transfer a scatter-gather list via bulk transfer
@@ -474,6 +478,7 @@ int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe,
scsi_set_resid(srb, scsi_bufflen(srb) - partial);
return result;
}
+EXPORT_SYMBOL_GPL(usb_stor_bulk_srb);
/*
* Transfer an entire SCSI command's worth of data payload over the bulk
@@ -509,6 +514,7 @@ int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe,
*residual = length_left;
return result;
}
+EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_sg);
/***********************************************************************
* Transport routines
@@ -558,32 +564,10 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) {
- /* The command succeeded. If the capacity is odd
- * (i.e., if the sector number is even) then the
- * "always-even" heuristic would be wrong for this
- * device. Issue a WARN() so that the kerneloops.org
- * project will be notified and we will then know to
- * mark the device with a CAPACITY_OK flag. Hopefully
- * this will occur for only a few devices.
- *
- * Use the sign of us->last_sector_hacks to tell whether
- * the warning has already been issued; we don't need
- * more than one warning per device.
+ /* The command succeeded. We know this device doesn't
+ * have the last-sector bug, so stop checking it.
*/
- if (!(sector & 1) && us->use_last_sector_hacks > 0) {
- unsigned vid = le16_to_cpu(
- us->pusb_dev->descriptor.idVendor);
- unsigned pid = le16_to_cpu(
- us->pusb_dev->descriptor.idProduct);
- unsigned rev = le16_to_cpu(
- us->pusb_dev->descriptor.bcdDevice);
-
- WARN(1, "%s: Successful last sector success at %u, "
- "device %04x:%04x:%04x\n",
- sdkp->disk->disk_name, sector,
- vid, pid, rev);
- us->use_last_sector_hacks = -1;
- }
+ us->use_last_sector_hacks = 0;
} else {
/* The command failed. Allow up to 3 retries in case this
@@ -599,14 +583,6 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
srb->result = SAM_STAT_CHECK_CONDITION;
memcpy(srb->sense_buffer, record_not_found,
sizeof(record_not_found));
-
- /* In theory we might want to issue a WARN() here if the
- * capacity is even, since it could indicate the device
- * has the READ CAPACITY bug _and_ the real capacity is
- * odd. But it could also indicate that the device
- * simply can't access its last sector, a failure mode
- * which is surprisingly common. So no warning.
- */
}
done:
@@ -970,6 +946,7 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
usb_stor_clear_halt(us, pipe);
return USB_STOR_TRANSPORT_FAILED;
}
+EXPORT_SYMBOL_GPL(usb_stor_CB_transport);
/*
* Bulk only transport
@@ -1186,6 +1163,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
/* we should never get here, but if we do, we're in trouble */
return USB_STOR_TRANSPORT_ERROR;
}
+EXPORT_SYMBOL_GPL(usb_stor_Bulk_transport);
/***********************************************************************
* Reset routines
@@ -1260,6 +1238,7 @@ int usb_stor_CB_reset(struct us_data *us)
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE);
}
+EXPORT_SYMBOL_GPL(usb_stor_CB_reset);
/* This issues a Bulk-only Reset to the device in question, including
* clearing the subsequent endpoint halts that may occur.
@@ -1272,6 +1251,7 @@ int usb_stor_Bulk_reset(struct us_data *us)
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, us->ifnum, NULL, 0);
}
+EXPORT_SYMBOL_GPL(usb_stor_Bulk_reset);
/* Issue a USB port reset to the device. The caller must not hold
* us->dev_mutex.
diff --git a/drivers/usb/storage/freecom.h b/drivers/usb/storage/unusual_alauda.h
index 20d0fe6ba0c..8c412f885dd 100644
--- a/drivers/usb/storage/freecom.h
+++ b/drivers/usb/storage/unusual_alauda.h
@@ -1,13 +1,4 @@
-/* Driver for Freecom USB/IDE adaptor
- *
- * Freecom v0.1:
- *
- * First release
- *
- * Current development and maintenance by:
- * (c) 2000 David Brown <usb-storage@davidb.org>
- *
- * See freecom.c for more explanation
+/* Unusual Devices File for the Alauda-based card readers
*
* 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
@@ -24,11 +15,17 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _FREECOM_USB_H
-#define _FREECOM_USB_H
+#if defined(CONFIG_USB_STORAGE_ALAUDA) || \
+ defined(CONFIG_USB_STORAGE_ALAUDA_MODULE)
+
+UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102,
+ "Fujifilm",
+ "DPC-R1 (Alauda)",
+ US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0),
-extern int freecom_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_freecom_reset(struct us_data *us);
-extern int freecom_init (struct us_data *us);
+UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102,
+ "Olympus",
+ "MAUSB-10 (Alauda)",
+ US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0),
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_ALAUDA) || ... */
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h
new file mode 100644
index 00000000000..44be6d75dab
--- /dev/null
+++ b/drivers/usb/storage/unusual_cypress.h
@@ -0,0 +1,34 @@
+/* Unusual Devices File for devices based on the Cypress USB/ATA bridge
+ * with support for ATACB
+ *
+ * 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, 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || \
+ defined(CONFIG_USB_STORAGE_CYPRESS_ATACB_MODULE)
+
+/* CY7C68300 : support atacb */
+UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999,
+ "Cypress",
+ "Cypress AT2LP",
+ US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0),
+
+/* CY7C68310 : support atacb and atacb2 */
+UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999,
+ "Cypress",
+ "Cypress ISD-300LP",
+ US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */
diff --git a/drivers/usb/storage/unusual_datafab.h b/drivers/usb/storage/unusual_datafab.h
new file mode 100644
index 00000000000..c9298ce9f22
--- /dev/null
+++ b/drivers/usb/storage/unusual_datafab.h
@@ -0,0 +1,98 @@
+/* Unusual Devices File for the Datafab USB Compact Flash reader
+ *
+ * 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, 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_DATAFAB) || \
+ defined(CONFIG_USB_STORAGE_DATAFAB_MODULE)
+
+UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015,
+ "Datafab",
+ "MDCFE-B USB CF Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+/*
+ * The following Datafab-based devices may or may not work
+ * using the current driver...the 0xffff is arbitrary since I
+ * don't know what device versions exist for these guys.
+ *
+ * The 0xa003 and 0xa004 devices in particular I'm curious about.
+ * I'm told they exist but so far nobody has come forward to say that
+ * they work with this driver. Given the success we've had getting
+ * other Datafab-based cards operational with this driver, I've decided
+ * to leave these two devices in the list.
+ */
+UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
+ "SIIG/Datafab",
+ "SIIG/Datafab Memory Stick+CF Reader/Writer",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+/* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */
+UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff,
+ "Datafab/Unknown",
+ "MD2/MD3 Disk enclosure",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ US_FL_SINGLE_LUN),
+
+UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
+ "Datafab/Unknown",
+ "Datafab-based Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
+ "Datafab/Unknown",
+ "Datafab-based Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
+ "PNY/Datafab",
+ "PNY/Datafab CF+SM Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
+ "Simple Tech/Datafab",
+ "Simple Tech/Datafab CF+SM Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+/* Submitted by Olaf Hering <olh@suse.de> */
+UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
+ "Datafab Systems, Inc.",
+ "USB to CF + SM Combo (LC1)",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+/* Reported by Felix Moeller <felix@derklecks.de>
+ * in Germany this is sold by Hama with the productnumber 46952
+ * as "DualSlot CompactFlash(TM) & MStick Drive USB"
+ */
+UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff,
+ "DataFab Systems Inc.",
+ "USB CF+MS",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
+ "Acomdata",
+ "CF",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ US_FL_SINGLE_LUN),
+
+#endif /* defined(CONFIG_USB_STORAGE_DATAFAB) || ... */
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index a7f9513fa19..1c1f643e8a7 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -53,6 +53,11 @@
* as opposed to devices that do something strangely or wrongly.
*/
+#if !defined(CONFIG_USB_STORAGE_SDDR09) && \
+ !defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
+#define NO_SDDR09
+#endif
+
/* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
*/
UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100,
@@ -80,18 +85,6 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200,
"CD-Writer+",
US_SC_8070, US_PR_CB, NULL, 0),
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
- "HP",
- "CD-Writer+ 8200e",
- US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-
-UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
- "HP",
- "CD-Writer+ CD-4e",
- US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-#endif
-
/* Reported by Ben Efros <ben@pc-doctor.com> */
UNUSUAL_DEV( 0x03f0, 0x070c, 0x0000, 0x0000,
"HP",
@@ -226,7 +219,7 @@ UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0610,
US_FL_MAX_SECTORS_64 ),
/* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */
-UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452,
+UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999,
"Nokia",
"Nokia 6233",
US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -246,12 +239,7 @@ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
- "Microtech",
- "CameraMate (DPCM_USB)",
- US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
-#else
+#ifdef NO_SDDR09
UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
"Microtech",
"CameraMate",
@@ -288,13 +276,6 @@ UNUSUAL_DEV( 0x0457, 0x0151, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_NOT_LOCKABLE ),
-#ifdef CONFIG_USB_STORAGE_KARMA
-UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101,
- "Rio",
- "Rio Karma",
- US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),
-#endif
-
/* Reported by Tamas Kerecsen <kerecsen@bigfoot.com>
* Obviously the PROM has not been customized by the VAR;
* the Vendor and Product string descriptors are:
@@ -375,22 +356,6 @@ UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110,
US_SC_DEVICE, US_PR_CB, NULL,
US_FL_MAX_SECTORS_MIN),
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
-/* CY7C68300 : support atacb */
-UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999,
- "Cypress",
- "Cypress AT2LP",
- US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
- 0),
-
-/* CY7C68310 : support atacb and atacb2 */
-UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999,
- "Cypress",
- "Cypress ISD-300LP",
- US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
- 0),
-#endif
-
/* Reported by Simon Levitt <simon@whattf.com>
* This entry needs Sub and Proto fields */
UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100,
@@ -467,20 +432,7 @@ UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
US_FL_SCM_MULT_TARG ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999,
- "Sandisk",
- "ImageMate SDDR09",
- US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
- 0),
-
-/* This entry is from Andries.Brouwer@cwi.nl */
-UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
- "SCM Microsystems",
- "eUSB SmartMedia / CompactFlash Adapter",
- US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
- 0),
-#else
+#ifdef NO_SDDR09
UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
"SCM Microsystems",
"eUSB CompactFlash Adapter",
@@ -535,14 +487,6 @@ UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200,
"CD-RW Device",
US_SC_8020, US_PR_CB, NULL, 0),
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999,
- "Shuttle/SCM",
- "USBAT-02",
- US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
- US_FL_SINGLE_LUN),
-#endif
-
/* Reported by Dmitry Khlystov <adminimus@gmail.com> */
UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220,
"Samsung",
@@ -645,14 +589,6 @@ UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110,
- "Sony",
- "Portable USB Harddrive V2",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-#endif
-
/* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */
UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000,
"Sony",
@@ -749,13 +685,6 @@ UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999,
"Silicon Media R/W",
US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102,
- "Fujifilm",
- "DPC-R1 (Alauda)",
- US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
-#endif
-
/* Reported by RTE <raszilki@yandex.ru> */
UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141,
"JetFlash",
@@ -798,32 +727,6 @@ UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110,
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_NEED_OVERRIDE ),
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110,
- "In-System",
- "USB/IDE Bridge (ATA/ATAPI)",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-
-UNUSUAL_DEV( 0x05ab, 0x0301, 0x0100, 0x0110,
- "In-System",
- "Portable USB Harddrive V2",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-
-UNUSUAL_DEV( 0x05ab, 0x0351, 0x0100, 0x0110,
- "In-System",
- "Portable USB Harddrive V2",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-
-UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110,
- "In-System",
- "USB Storage Adapter V2",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-#endif
-
/* Submitted by Sven Anderson <sven-linux@anderson.de>
* There are at least four ProductIDs used for iPods, so I added 0x1202 and
* 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears
@@ -877,14 +780,6 @@ UNUSUAL_DEV( 0x05c6, 0x1000, 0x0000, 0x9999,
US_SC_DEVICE, US_PR_DEVICE, option_ms_init,
0),
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001,
- "Lexar",
- "Jumpshot USB CF Reader",
- US_SC_SCSI, US_PR_JUMPSHOT, NULL,
- US_FL_NEED_OVERRIDE ),
-#endif
-
/* Reported by Blake Matheny <bmatheny@purdue.edu> */
UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113,
"Lexar",
@@ -907,13 +802,13 @@ UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff,
"Genesys Logic",
"USB to IDE Optical",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
+ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ),
UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff,
"Genesys Logic",
"USB to IDE Disk",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
+ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ),
/* Reported by Ben Efros <ben@pc-doctor.com> */
UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451,
@@ -935,14 +830,6 @@ UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100,
"Floppy Drive",
US_SC_UFI, US_PR_CB, NULL, 0 ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100,
- "Olympus",
- "Camedia MAUSB-2",
- US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
- 0),
-#endif
-
/* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */
UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
"SigmaTel",
@@ -951,7 +838,9 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
US_FL_FIX_CAPACITY ),
/* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */
-UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100,
+/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by
+ * Thomas Bartosik <tbartdev@gmx-topmail.de> */
+UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100,
"Prolific Technology Inc.",
"Mass Storage Device",
US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -995,6 +884,16 @@ UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64),
+/* Reported by Jean-Baptiste Onofre <jb@nanthrax.net>
+ * Support the following product :
+ * "Dane-Elec MediaTouch"
+ */
+UNUSUAL_DEV( 0x071b, 0x32bb, 0x0000, 0x0000,
+ "RockChip",
+ "MTP",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64),
+
/* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com>
* This USB MP3/AVI player device fails and disconnects if more than 128
* sectors (64kB) are read/written in a single command, and may be present
@@ -1031,35 +930,12 @@ UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005,
- "Sandisk",
- "ImageMate SDDR-05b",
- US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
- US_FL_SINGLE_LUN ),
-#endif
-
UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100,
"Sandisk",
"ImageMate SDDR-12",
US_SC_SCSI, US_PR_CB, NULL,
US_FL_SINGLE_LUN ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999,
- "Sandisk",
- "ImageMate SDDR-09",
- US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
- 0),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999,
- "Freecom",
- "USB-IDE",
- US_SC_QIC, US_PR_FREECOM, freecom_init, 0),
-#endif
-
/* Reported by Eero Volotinen <eero@ping-viini.org> */
UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999,
"Freecom Technologies",
@@ -1079,12 +955,7 @@ UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
US_FL_SCM_MULT_TARG ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
- "Microtech",
- "CameraMate (DPCM_USB)",
- US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
-#else
+#ifdef NO_SDDR09
UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
"Microtech",
"CameraMate",
@@ -1092,108 +963,6 @@ UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
US_FL_SINGLE_LUN ),
#endif
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102,
- "Olympus",
- "MAUSB-10 (Alauda)",
- US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015,
- "Datafab",
- "MDCFE-B USB CF Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-/*
- * The following Datafab-based devices may or may not work
- * using the current driver...the 0xffff is arbitrary since I
- * don't know what device versions exist for these guys.
- *
- * The 0xa003 and 0xa004 devices in particular I'm curious about.
- * I'm told they exist but so far nobody has come forward to say that
- * they work with this driver. Given the success we've had getting
- * other Datafab-based cards operational with this driver, I've decided
- * to leave these two devices in the list.
- */
-UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
- "SIIG/Datafab",
- "SIIG/Datafab Memory Stick+CF Reader/Writer",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-/* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */
-UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff,
- "Datafab/Unknown",
- "MD2/MD3 Disk enclosure",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_SINGLE_LUN ),
-
-UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
- "Datafab/Unknown",
- "Datafab-based Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
- "Datafab/Unknown",
- "Datafab-based Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
- "PNY/Datafab",
- "PNY/Datafab CF+SM Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
- "Simple Tech/Datafab",
- "Simple Tech/Datafab CF+SM Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_SDDR55
-/* Contributed by Peter Waechtler */
-UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
- "Datafab",
- "MDSM-B reader",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_FIX_INQUIRY ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-/* Submitted by Olaf Hering <olh@suse.de> */
-UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
- "Datafab Systems, Inc.",
- "USB to CF + SM Combo (LC1)",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-/* SM part - aeb <Andries.Brouwer@cwi.nl> */
-UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
- "Datafab Systems, Inc.",
- "USB to CF + SM Combo (LC1)",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_SINGLE_LUN ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-/* Reported by Felix Moeller <felix@derklecks.de>
- * in Germany this is sold by Hama with the productnumber 46952
- * as "DualSlot CompactFlash(TM) & MStick Drive USB"
- */
-UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff,
- "DataFab Systems Inc.",
- "USB CF+MS",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-#endif
-
/* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100
* Only revision 1.13 tested (same for all of the above devices,
* based on the Datafab DF-UG-07 chip). Needed for US_FL_FIX_INQUIRY.
@@ -1204,7 +973,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
"Datafab",
"KECF-USB",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_INQUIRY ),
+ US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ),
/* Reported by Rauch Wolke <rauchwolke@gmx.net> */
UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff,
@@ -1251,6 +1020,13 @@ UNUSUAL_DEV( 0x0840, 0x0084, 0x0001, 0x0001,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY),
+/* Reported by Martijn Hijdra <martijn.hijdra@gmail.com> */
+UNUSUAL_DEV( 0x0840, 0x0085, 0x0001, 0x0001,
+ "Argosy",
+ "Storage",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY),
+
/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
* Flag will support Bulk devices which use a standards-violating 32-byte
* Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
@@ -1337,21 +1113,6 @@ UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
-
-/* Submitted by Per Winkvist <per.winkvist@uk.com> */
-UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
- "Pentax",
- "Optio S/S4",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_INQUIRY ),
-
-/* Reported by Jaak Ristioja <Ristioja@gmail.com> */
-UNUSUAL_DEV( 0x0a17, 0x006e, 0x0100, 0x0100,
- "Pentax",
- "K10D",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_CAPACITY ),
-
/* These are virtual windows driver CDs, which the zd1211rw driver
* automatically converts into WLAN devices. */
UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
@@ -1388,6 +1149,16 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
0 ),
+/* Reported by Jan Dumon <j.dumon@option.com>
+ * This device (wrongly) has a vendor-specific device descriptor.
+ * The entry is needed so usb-storage can bind to it's mass-storage
+ * interface as an interface driver */
+UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000,
+ "Option",
+ "GI 0431 SD-Card",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 0 ),
+
/* Reported by Ben Efros <ben@pc-doctor.com> */
UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000,
"Seagate",
@@ -1395,29 +1166,6 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SANE_SENSE ),
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
- "ATI",
- "USB Cable 205",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
- "Acomdata",
- "CF",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_SINGLE_LUN ),
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
- "Acomdata",
- "SM",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_SINGLE_LUN ),
-#endif
-
UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999,
"Maxtor",
"USB to SATA",
@@ -1434,23 +1182,6 @@ UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
-/* Submitted by: Nick Sillik <n.sillik@temple.edu>
- * Needed for OneTouch extension to usb-storage
- *
- */
-#ifdef CONFIG_USB_STORAGE_ONETOUCH
- UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999,
- "Maxtor",
- "OneTouch External Harddrive",
- US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
- 0),
- UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999,
- "Maxtor",
- "OneTouch External Harddrive",
- US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
- 0),
-#endif
-
/* Submitted by Joris Struyve <joris@struyve.be> */
UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
"Medion",
@@ -1589,6 +1320,13 @@ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_NO_WP_DETECT ),
+/* Reported by The Solutor <thesolutor@gmail.com> */
+UNUSUAL_DEV( 0x0fce, 0xd0e1, 0x0000, 0x0000,
+ "Sony Ericsson",
+ "MD400",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_DEVICE),
+
/* Reported by Jan Mate <mate@fiit.stuba.sk>
* and by Soeren Sonnenburg <kernel@nn7.de> */
UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000,
@@ -2031,15 +1769,11 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
-/* Reported by Mauro Andreolini <andreoli@weblab.ing.unimo.it>
- * This entry is needed to bypass the ZeroCD mechanism
- * and to properly load as a modem device.
- */
-UNUSUAL_DEV( 0x19d2, 0x2000, 0x0000, 0x0000,
- "Onda ET502HS",
- "USB MMC Storage",
+UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
+ "ST",
+ "2A",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_IGNORE_DEVICE),
+ US_FL_FIX_CAPACITY),
/* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
* and Renato Perini <rperini@email.it>
@@ -2100,14 +1834,6 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100,
"Micro Mini 1GB",
US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
-#ifdef CONFIG_USB_STORAGE_SDDR55
-UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999,
- "Sandisk",
- "ImageMate SDDR55",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_SINGLE_LUN),
-#endif
-
/* Reported by Andrew Simmons <andrew.simmons@gmail.com> */
UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001,
"DataStor",
diff --git a/drivers/usb/storage/cypress_atacb.h b/drivers/usb/storage/unusual_freecom.h
index fbada898d56..37586794239 100644
--- a/drivers/usb/storage/cypress_atacb.h
+++ b/drivers/usb/storage/unusual_freecom.h
@@ -1,8 +1,4 @@
-/*
- * Support for emulating SAT (ata pass through) on devices based
- * on the Cypress USB/ATA bridge supporting ATACB.
- *
- * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr)
+/* Unusual Devices File for the Freecom USB/IDE adaptor
*
* 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
@@ -19,7 +15,12 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _CYPRESS_ATACB_H_
-#define _CYPRESS_ATACB_H_
-extern void cypress_atacb_passthrough(struct scsi_cmnd*, struct us_data*);
-#endif
+#if defined(CONFIG_USB_STORAGE_FREECOM) || \
+ defined(CONFIG_USB_STORAGE_FREECOM_MODULE)
+
+UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999,
+ "Freecom",
+ "USB-IDE",
+ US_SC_QIC, US_PR_FREECOM, init_freecom, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_FREECOM) || ... */
diff --git a/drivers/usb/storage/unusual_isd200.h b/drivers/usb/storage/unusual_isd200.h
new file mode 100644
index 00000000000..0d99dde3382
--- /dev/null
+++ b/drivers/usb/storage/unusual_isd200.h
@@ -0,0 +1,57 @@
+/* Unusual Devices File for In-System Design, Inc. ISD200 ASIC
+ *
+ * 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, 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_ISD200) || \
+ defined(CONFIG_USB_STORAGE_ISD200_MODULE)
+
+UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110,
+ "Sony",
+ "Portable USB Harddrive V2",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110,
+ "In-System",
+ "USB/IDE Bridge (ATA/ATAPI)",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x05ab, 0x0301, 0x0100, 0x0110,
+ "In-System",
+ "Portable USB Harddrive V2",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x05ab, 0x0351, 0x0100, 0x0110,
+ "In-System",
+ "Portable USB Harddrive V2",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110,
+ "In-System",
+ "USB Storage Adapter V2",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
+ "ATI",
+ "USB Cable 205",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_ISD200) || ... */
diff --git a/drivers/usb/storage/sddr55.h b/drivers/usb/storage/unusual_jumpshot.h
index a815a0470c8..2e549b1c2c6 100644
--- a/drivers/usb/storage/sddr55.h
+++ b/drivers/usb/storage/unusual_jumpshot.h
@@ -1,10 +1,4 @@
-/* Driver for SanDisk SDDR-55 SmartMedia reader
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2002 Simon Munton
- *
- * See sddr55.c for more explanation
+/* Unusual Devices File for the Lexar "Jumpshot" Compact Flash reader
*
* 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
@@ -21,12 +15,13 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _USB_SHUTTLE_EUSB_SDDR55_H
-#define _USB_SHUTTLE_EUSB_SDDR55_H
-
-/* Sandisk SDDR-55 stuff */
+#if defined(CONFIG_USB_STORAGE_JUMPSHOT) || \
+ defined(CONFIG_USB_STORAGE_JUMPSHOT_MODULE)
-extern int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int sddr55_reset(struct us_data *us);
+UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001,
+ "Lexar",
+ "Jumpshot USB CF Reader",
+ US_SC_SCSI, US_PR_JUMPSHOT, NULL,
+ US_FL_NEED_OVERRIDE),
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_JUMPSHOT) || ... */
diff --git a/drivers/usb/storage/isd200.h b/drivers/usb/storage/unusual_karma.h
index 0a35f4fa78f..12ae3a03e80 100644
--- a/drivers/usb/storage/isd200.h
+++ b/drivers/usb/storage/unusual_karma.h
@@ -1,11 +1,4 @@
-/* Header File for In-System Design, Inc. ISD200 ASIC
- *
- * First release
- *
- * Current development and maintenance by:
- * (c) 2000 In-System Design, Inc. (support@in-system.com)
- *
- * See isd200.c for more information.
+/* Unusual Devices File for the Rio Karma
*
* 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
@@ -22,10 +15,12 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _USB_ISD200_H
-#define _USB_ISD200_H
+#if defined(CONFIG_USB_STORAGE_KARMA) || \
+ defined(CONFIG_USB_STORAGE_KARMA_MODULE)
-extern void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us);
-extern int isd200_Initialization(struct us_data *us);
+UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101,
+ "Rio",
+ "Rio Karma",
+ US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_KARMA) || ... */
diff --git a/drivers/usb/storage/unusual_onetouch.h b/drivers/usb/storage/unusual_onetouch.h
new file mode 100644
index 00000000000..bd9306b637d
--- /dev/null
+++ b/drivers/usb/storage/unusual_onetouch.h
@@ -0,0 +1,36 @@
+/* Unusual Devices File for the Maxtor OneTouch USB hard drive's button
+ *
+ * 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, 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_ONETOUCH) || \
+ defined(CONFIG_USB_STORAGE_ONETOUCH_MODULE)
+
+/* Submitted by: Nick Sillik <n.sillik@temple.edu>
+ * Needed for OneTouch extension to usb-storage
+ */
+UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999,
+ "Maxtor",
+ "OneTouch External Harddrive",
+ US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+ 0),
+
+UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999,
+ "Maxtor",
+ "OneTouch External Harddrive",
+ US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+ 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_ONETOUCH) || ... */
diff --git a/drivers/usb/storage/unusual_sddr09.h b/drivers/usb/storage/unusual_sddr09.h
new file mode 100644
index 00000000000..50cab511a4d
--- /dev/null
+++ b/drivers/usb/storage/unusual_sddr09.h
@@ -0,0 +1,56 @@
+/* Unusual Devices File for SanDisk SDDR-09 SmartMedia reader
+ *
+ * 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, 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_SDDR09) || \
+ defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
+
+UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
+ "Microtech",
+ "CameraMate (DPCM_USB)",
+ US_SC_SCSI, US_PR_DPCM_USB, NULL, 0),
+
+UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999,
+ "Sandisk",
+ "ImageMate SDDR09",
+ US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+ 0),
+
+/* This entry is from Andries.Brouwer@cwi.nl */
+UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
+ "SCM Microsystems",
+ "eUSB SmartMedia / CompactFlash Adapter",
+ US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
+ 0),
+
+UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100,
+ "Olympus",
+ "Camedia MAUSB-2",
+ US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+ 0),
+
+UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999,
+ "Sandisk",
+ "ImageMate SDDR-09",
+ US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+ 0),
+
+UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
+ "Microtech",
+ "CameraMate (DPCM_USB)",
+ US_SC_SCSI, US_PR_DPCM_USB, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_SDDR09) || ... */
diff --git a/drivers/usb/storage/unusual_sddr55.h b/drivers/usb/storage/unusual_sddr55.h
new file mode 100644
index 00000000000..ae81ef7a1cf
--- /dev/null
+++ b/drivers/usb/storage/unusual_sddr55.h
@@ -0,0 +1,44 @@
+/* Unusual Devices File for SanDisk SDDR-55 SmartMedia reader
+ *
+ * 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, 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_SDDR55) || \
+ defined(CONFIG_USB_STORAGE_SDDR55_MODULE)
+
+/* Contributed by Peter Waechtler */
+UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
+ "Datafab",
+ "MDSM-B reader",
+ US_SC_SCSI, US_PR_SDDR55, NULL,
+ US_FL_FIX_INQUIRY),
+
+/* SM part - aeb <Andries.Brouwer@cwi.nl> */
+UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
+ "Datafab Systems, Inc.",
+ "USB to CF + SM Combo (LC1)",
+ US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
+ "Acomdata",
+ "SM",
+ US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999,
+ "Sandisk",
+ "ImageMate SDDR55",
+ US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_SDDR55) || ... */
diff --git a/drivers/usb/storage/unusual_usbat.h b/drivers/usb/storage/unusual_usbat.h
new file mode 100644
index 00000000000..80e869f1018
--- /dev/null
+++ b/drivers/usb/storage/unusual_usbat.h
@@ -0,0 +1,43 @@
+/* Unusual Devices File for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
+ *
+ * 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, 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_USBAT) || \
+ defined(CONFIG_USB_STORAGE_USBAT_MODULE)
+
+UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
+ "HP",
+ "CD-Writer+ 8200e",
+ US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
+
+UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
+ "HP",
+ "CD-Writer+ CD-4e",
+ US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
+
+UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999,
+ "Shuttle/SCM",
+ "USBAT-02",
+ US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
+ US_FL_SINGLE_LUN),
+
+UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005,
+ "Sandisk",
+ "ImageMate SDDR-05b",
+ US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
+ US_FL_SINGLE_LUN),
+
+#endif /* defined(CONFIG_USB_STORAGE_USBAT) || ... */
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 4becf495ca2..8060b85fe1a 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -5,7 +5,7 @@
*
* Developed with the assistance of:
* (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
- * (c) 2003 Alan Stern (stern@rowland.harvard.edu)
+ * (c) 2003-2009 Alan Stern (stern@rowland.harvard.edu)
*
* Initial work by:
* (c) 1999 Michael Gee (michael@linuxspecific.com)
@@ -66,39 +66,6 @@
#include "debug.h"
#include "initializers.h"
-#ifdef CONFIG_USB_STORAGE_USBAT
-#include "shuttle_usbat.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
-#include "sddr09.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-#include "sddr55.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_FREECOM
-#include "freecom.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ISD200
-#include "isd200.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-#include "datafab.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#include "jumpshot.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ONETOUCH
-#include "onetouch.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-#include "alauda.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_KARMA
-#include "karma.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
-#include "cypress_atacb.h"
-#endif
#include "sierra_ms.h"
#include "option_ms.h"
@@ -118,36 +85,8 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");
/*
* The entries in this table correspond, line for line,
- * with the entries of us_unusual_dev_list[].
+ * with the entries in usb_storage_usb_ids[], defined in usual-tables.c.
*/
-#ifndef CONFIG_USB_LIBUSUAL
-
-#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
- vendorName, productName,useProtocol, useTransport, \
- initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
- .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
-
-#define COMPLIANT_DEV UNUSUAL_DEV
-
-#define USUAL_DEV(useProto, useTrans, useType) \
-{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
- .driver_info = (USB_US_TYPE_STOR<<24) }
-
-static struct usb_device_id storage_usb_ids [] = {
-
-# include "unusual_devs.h"
-#undef UNUSUAL_DEV
-#undef COMPLIANT_DEV
-#undef USUAL_DEV
- /* Terminating entry */
- { }
-};
-
-MODULE_DEVICE_TABLE (usb, storage_usb_ids);
-#endif /* CONFIG_USB_LIBUSUAL */
-
-/* This is the list of devices we recognize, along with their flag data */
/* The vendor name should be kept at eight characters or less, and
* the product name should be kept at 16 characters or less. If a device
@@ -179,18 +118,17 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
static struct us_unusual_dev us_unusual_dev_list[] = {
# include "unusual_devs.h"
-# undef UNUSUAL_DEV
-# undef COMPLIANT_DEV
-# undef USUAL_DEV
-
- /* Terminating entry */
- { NULL }
+ { } /* Terminating entry */
};
+#undef UNUSUAL_DEV
+#undef COMPLIANT_DEV
+#undef USUAL_DEV
+
#ifdef CONFIG_PM /* Minimal support for suspend and resume */
-static int storage_suspend(struct usb_interface *iface, pm_message_t message)
+int usb_stor_suspend(struct usb_interface *iface, pm_message_t message)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -207,8 +145,9 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
mutex_unlock(&us->dev_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_suspend);
-static int storage_resume(struct usb_interface *iface)
+int usb_stor_resume(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -221,8 +160,9 @@ static int storage_resume(struct usb_interface *iface)
mutex_unlock(&us->dev_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_resume);
-static int storage_reset_resume(struct usb_interface *iface)
+int usb_stor_reset_resume(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -235,6 +175,7 @@ static int storage_reset_resume(struct usb_interface *iface)
* the device */
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_reset_resume);
#endif /* CONFIG_PM */
@@ -243,7 +184,7 @@ static int storage_reset_resume(struct usb_interface *iface)
* a USB port reset, whether from this driver or a different one.
*/
-static int storage_pre_reset(struct usb_interface *iface)
+int usb_stor_pre_reset(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -253,8 +194,9 @@ static int storage_pre_reset(struct usb_interface *iface)
mutex_lock(&us->dev_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_pre_reset);
-static int storage_post_reset(struct usb_interface *iface)
+int usb_stor_post_reset(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -269,6 +211,7 @@ static int storage_post_reset(struct usb_interface *iface)
mutex_unlock(&us->dev_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_post_reset);
/*
* fill_inquiry_response takes an unsigned char array (which must
@@ -311,6 +254,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
usb_stor_set_xfer_buf(data, data_len, us->srb);
}
+EXPORT_SYMBOL_GPL(fill_inquiry_response);
static int usb_stor_control_thread(void * __us)
{
@@ -551,20 +495,13 @@ static void adjust_quirks(struct us_data *us)
vid, pid, f);
}
-/* Find an unusual_dev descriptor (always succeeds in the current code) */
-static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
-{
- const int id_index = id - storage_usb_ids;
- return &us_unusual_dev_list[id_index];
-}
-
/* Get the unusual_devs entries and the string descriptors */
-static int get_device_info(struct us_data *us, const struct usb_device_id *id)
+static int get_device_info(struct us_data *us, const struct usb_device_id *id,
+ struct us_unusual_dev *unusual_dev)
{
struct usb_device *dev = us->pusb_dev;
struct usb_interface_descriptor *idesc =
&us->pusb_intf->cur_altsetting->desc;
- struct us_unusual_dev *unusual_dev = find_unusual(id);
/* Store the entries */
us->unusual_dev = unusual_dev;
@@ -629,7 +566,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
}
/* Get the transport settings */
-static int get_transport(struct us_data *us)
+static void get_transport(struct us_data *us)
{
switch (us->protocol) {
case US_PR_CB:
@@ -651,100 +588,11 @@ static int get_transport(struct us_data *us)
us->transport = usb_stor_Bulk_transport;
us->transport_reset = usb_stor_Bulk_reset;
break;
-
-#ifdef CONFIG_USB_STORAGE_USBAT
- case US_PR_USBAT:
- us->transport_name = "Shuttle USBAT";
- us->transport = usbat_transport;
- us->transport_reset = usb_stor_CB_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
- case US_PR_EUSB_SDDR09:
- us->transport_name = "EUSB/SDDR09";
- us->transport = sddr09_transport;
- us->transport_reset = usb_stor_CB_reset;
- us->max_lun = 0;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_SDDR55
- case US_PR_SDDR55:
- us->transport_name = "SDDR55";
- us->transport = sddr55_transport;
- us->transport_reset = sddr55_reset;
- us->max_lun = 0;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DPCM
- case US_PR_DPCM_USB:
- us->transport_name = "Control/Bulk-EUSB/SDDR09";
- us->transport = dpcm_transport;
- us->transport_reset = usb_stor_CB_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
- case US_PR_FREECOM:
- us->transport_name = "Freecom";
- us->transport = freecom_transport;
- us->transport_reset = usb_stor_freecom_reset;
- us->max_lun = 0;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
- case US_PR_DATAFAB:
- us->transport_name = "Datafab Bulk-Only";
- us->transport = datafab_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
- case US_PR_JUMPSHOT:
- us->transport_name = "Lexar Jumpshot Control/Bulk";
- us->transport = jumpshot_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_ALAUDA
- case US_PR_ALAUDA:
- us->transport_name = "Alauda Control/Bulk";
- us->transport = alauda_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_KARMA
- case US_PR_KARMA:
- us->transport_name = "Rio Karma/Bulk";
- us->transport = rio_karma_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- break;
-#endif
-
- default:
- return -EIO;
}
- US_DEBUGP("Transport: %s\n", us->transport_name);
-
- /* fix for single-lun devices */
- if (us->fflags & US_FL_SINGLE_LUN)
- us->max_lun = 0;
- return 0;
}
/* Get the protocol settings */
-static int get_protocol(struct us_data *us)
+static void get_protocol(struct us_data *us)
{
switch (us->subclass) {
case US_SC_RBC:
@@ -779,26 +627,7 @@ static int get_protocol(struct us_data *us)
us->protocol_name = "Uniform Floppy Interface (UFI)";
us->proto_handler = usb_stor_ufi_command;
break;
-
-#ifdef CONFIG_USB_STORAGE_ISD200
- case US_SC_ISD200:
- us->protocol_name = "ISD200 ATA/ATAPI";
- us->proto_handler = isd200_ata_command;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
- case US_SC_CYP_ATACB:
- us->protocol_name = "Transparent SCSI with Cypress ATACB";
- us->proto_handler = cypress_atacb_passthrough;
- break;
-#endif
-
- default:
- return -EIO;
}
- US_DEBUGP("Protocol: %s\n", us->protocol_name);
- return 0;
}
/* Get the pipe settings */
@@ -846,12 +675,12 @@ static int get_pipes(struct us_data *us)
us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0);
us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev,
- ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_out));
us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev,
- ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_in));
if (ep_int) {
us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev,
- ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_int));
us->ep_bInterval = ep_int->bInterval;
}
return 0;
@@ -1012,17 +841,15 @@ static int usb_stor_scan_thread(void * __us)
}
-/* Probe to see if we can drive a newly-connected USB device */
-static int storage_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+/* First part of general USB mass-storage probing */
+int usb_stor_probe1(struct us_data **pus,
+ struct usb_interface *intf,
+ const struct usb_device_id *id,
+ struct us_unusual_dev *unusual_dev)
{
struct Scsi_Host *host;
struct us_data *us;
int result;
- struct task_struct *th;
-
- if (usb_usual_check_type(id, USB_US_TYPE_STOR))
- return -ENXIO;
US_DEBUGP("USB Mass Storage device detected\n");
@@ -1041,7 +868,7 @@ static int storage_probe(struct usb_interface *intf,
* Allow 16-byte CDBs and thus > 2TB
*/
host->max_cmd_len = 16;
- us = host_to_us(host);
+ *pus = us = host_to_us(host);
memset(us, 0, sizeof(struct us_data));
mutex_init(&(us->dev_mutex));
init_completion(&us->cmnd_ready);
@@ -1054,24 +881,46 @@ static int storage_probe(struct usb_interface *intf,
if (result)
goto BadDevice;
- /*
- * Get the unusual_devs entries and the descriptors
- *
- * id_index is calculated in the declaration to be the index number
- * of the match from the usb_device_id table, so we can find the
- * corresponding entry in the private table.
- */
- result = get_device_info(us, id);
+ /* Get the unusual_devs entries and the descriptors */
+ result = get_device_info(us, id, unusual_dev);
if (result)
goto BadDevice;
- /* Get the transport, protocol, and pipe settings */
- result = get_transport(us);
- if (result)
- goto BadDevice;
- result = get_protocol(us);
- if (result)
+ /* Get standard transport and protocol settings */
+ get_transport(us);
+ get_protocol(us);
+
+ /* Give the caller a chance to fill in specialized transport
+ * or protocol settings.
+ */
+ return 0;
+
+BadDevice:
+ US_DEBUGP("storage_probe() failed\n");
+ release_everything(us);
+ return result;
+}
+EXPORT_SYMBOL_GPL(usb_stor_probe1);
+
+/* Second part of general USB mass-storage probing */
+int usb_stor_probe2(struct us_data *us)
+{
+ struct task_struct *th;
+ int result;
+
+ /* Make sure the transport and protocol have both been set */
+ if (!us->transport || !us->proto_handler) {
+ result = -ENXIO;
goto BadDevice;
+ }
+ US_DEBUGP("Transport: %s\n", us->transport_name);
+ US_DEBUGP("Protocol: %s\n", us->protocol_name);
+
+ /* fix for single-lun devices */
+ if (us->fflags & US_FL_SINGLE_LUN)
+ us->max_lun = 0;
+
+ /* Find the endpoints and calculate pipe values */
result = get_pipes(us);
if (result)
goto BadDevice;
@@ -1080,7 +929,7 @@ static int storage_probe(struct usb_interface *intf,
result = usb_stor_acquire_resources(us);
if (result)
goto BadDevice;
- result = scsi_add_host(host, &intf->dev);
+ result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev);
if (result) {
printk(KERN_WARNING USB_STORAGE
"Unable to add the scsi host\n");
@@ -1108,9 +957,10 @@ BadDevice:
release_everything(us);
return result;
}
+EXPORT_SYMBOL_GPL(usb_stor_probe2);
-/* Handle a disconnect event from the USB core */
-static void storage_disconnect(struct usb_interface *intf)
+/* Handle a USB mass-storage disconnect */
+void usb_stor_disconnect(struct usb_interface *intf)
{
struct us_data *us = usb_get_intfdata(intf);
@@ -1118,6 +968,42 @@ static void storage_disconnect(struct usb_interface *intf)
quiesce_and_remove_host(us);
release_everything(us);
}
+EXPORT_SYMBOL_GPL(usb_stor_disconnect);
+
+/* The main probe routine for standard devices */
+static int storage_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ /*
+ * If libusual is configured, let it decide whether a standard
+ * device should be handled by usb-storage or by ub.
+ * If the device isn't standard (is handled by a subdriver
+ * module) then don't accept it.
+ */
+ if (usb_usual_check_type(id, USB_US_TYPE_STOR) ||
+ usb_usual_ignore_device(intf))
+ return -ENXIO;
+
+ /*
+ * Call the general probe procedures.
+ *
+ * The unusual_dev_list array is parallel to the usb_storage_usb_ids
+ * table, so we use the index of the id entry to find the
+ * corresponding unusual_devs entry.
+ */
+ result = usb_stor_probe1(&us, intf, id,
+ (id - usb_storage_usb_ids) + us_unusual_dev_list);
+ if (result)
+ return result;
+
+ /* No special transport or protocol settings in the main module */
+
+ result = usb_stor_probe2(us);
+ return result;
+}
/***********************************************************************
* Initialization and registration
@@ -1126,15 +1012,13 @@ static void storage_disconnect(struct usb_interface *intf)
static struct usb_driver usb_storage_driver = {
.name = "usb-storage",
.probe = storage_probe,
- .disconnect = storage_disconnect,
-#ifdef CONFIG_PM
- .suspend = storage_suspend,
- .resume = storage_resume,
- .reset_resume = storage_reset_resume,
-#endif
- .pre_reset = storage_pre_reset,
- .post_reset = storage_post_reset,
- .id_table = storage_usb_ids,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = usb_storage_usb_ids,
.soft_unbind = 1,
};
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 65e674e4be9..2609efb2bd7 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -177,4 +177,25 @@ extern void fill_inquiry_response(struct us_data *us,
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
#define scsi_lock(host) spin_lock_irq(host->host_lock)
+/* General routines provided by the usb-storage standard core */
+#ifdef CONFIG_PM
+extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message);
+extern int usb_stor_resume(struct usb_interface *iface);
+extern int usb_stor_reset_resume(struct usb_interface *iface);
+#else
+#define usb_stor_suspend NULL
+#define usb_stor_resume NULL
+#define usb_stor_reset_resume NULL
+#endif
+
+extern int usb_stor_pre_reset(struct usb_interface *iface);
+extern int usb_stor_post_reset(struct usb_interface *iface);
+
+extern int usb_stor_probe1(struct us_data **pus,
+ struct usb_interface *intf,
+ const struct usb_device_id *id,
+ struct us_unusual_dev *unusual_dev);
+extern int usb_stor_probe2(struct us_data *us);
+extern void usb_stor_disconnect(struct usb_interface *intf);
+
#endif
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c
new file mode 100644
index 00000000000..468bde7d197
--- /dev/null
+++ b/drivers/usb/storage/usual-tables.c
@@ -0,0 +1,116 @@
+/* Driver for USB Mass Storage devices
+ * Usual Tables File for usb-storage and libusual
+ *
+ * Copyright (C) 2009 Alan Stern (stern@rowland.harvard.edu)
+ *
+ * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
+ * information about this driver.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+ .driver_info = ((useType)<<24) }
+
+struct usb_device_id usb_storage_usb_ids[] = {
+# include "unusual_devs.h"
+ { } /* Terminating entry */
+};
+EXPORT_SYMBOL_GPL(usb_storage_usb_ids);
+
+MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids);
+
+#undef UNUSUAL_DEV
+#undef COMPLIANT_DEV
+#undef USUAL_DEV
+
+
+/*
+ * The table of devices to ignore
+ */
+struct ignore_entry {
+ u16 vid, pid, bcdmin, bcdmax;
+};
+
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ \
+ .vid = id_vendor, \
+ .pid = id_product, \
+ .bcdmin = bcdDeviceMin, \
+ .bcdmax = bcdDeviceMax, \
+}
+
+static struct ignore_entry ignore_ids[] = {
+# include "unusual_alauda.h"
+# include "unusual_cypress.h"
+# include "unusual_datafab.h"
+# include "unusual_freecom.h"
+# include "unusual_isd200.h"
+# include "unusual_jumpshot.h"
+# include "unusual_karma.h"
+# include "unusual_onetouch.h"
+# include "unusual_sddr09.h"
+# include "unusual_sddr55.h"
+# include "unusual_usbat.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
+/* Return an error if a device is in the ignore_ids list */
+int usb_usual_ignore_device(struct usb_interface *intf)
+{
+ struct usb_device *udev;
+ unsigned vid, pid, bcd;
+ struct ignore_entry *p;
+
+ udev = interface_to_usbdev(intf);
+ vid = le16_to_cpu(udev->descriptor.idVendor);
+ pid = le16_to_cpu(udev->descriptor.idProduct);
+ bcd = le16_to_cpu(udev->descriptor.bcdDevice);
+
+ for (p = ignore_ids; p->vid; ++p) {
+ if (p->vid == vid && p->pid == pid &&
+ p->bcdmin <= bcd && p->bcdmax >= bcd)
+ return -ENXIO;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usb_usual_ignore_device);
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index be76084c8d7..60ba631e99c 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -410,7 +410,9 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
}
/* let the user know what node this device is now attached to */
- info("USB Skeleton device now attached to USBSkel-%d", interface->minor);
+ dev_info(&interface->dev,
+ "USB Skeleton device now attached to USBSkel-%d",
+ interface->minor);
return 0;
error:
@@ -441,7 +443,7 @@ static void skel_disconnect(struct usb_interface *interface)
/* decrement our usage count */
kref_put(&dev->kref, skel_delete);
- info("USB Skeleton #%d now disconnected", minor);
+ dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
}
static void skel_draw_down(struct usb_skel *dev)
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c
index 1335cbe1191..25eae405f62 100644
--- a/drivers/usb/wusbcore/cbaf.c
+++ b/drivers/usb/wusbcore/cbaf.c
@@ -638,8 +638,7 @@ static void cbaf_disconnect(struct usb_interface *iface)
usb_put_intf(iface);
kfree(cbaf->buffer);
/* paranoia: clean up crypto keys */
- memset(cbaf, 0, sizeof(*cbaf));
- kfree(cbaf);
+ kzfree(cbaf);
}
static struct usb_device_id cbaf_id_table[] = {
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index e2e7e4bc846..f0aac0cf315 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -386,6 +386,7 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
| USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
if (wusb_dev) {
+ dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx);
if (!list_empty(&wusb_dev->cack_node))
list_del_init(&wusb_dev->cack_node);
/* For the one in cack_add() */
@@ -888,6 +889,8 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev)
if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
return; /* skip non wusb and wusb RHs */
+ usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED);
+
wusbhc = wusbhc_get_by_usb_dev(usb_dev);
if (wusbhc == NULL)
goto error_nodev;
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
index 3937bf6f8ce..9fe4246cecb 100644
--- a/drivers/usb/wusbcore/rh.c
+++ b/drivers/usb/wusbcore/rh.c
@@ -100,6 +100,9 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
struct wusb_dev *wusb_dev = port->wusb_dev;
+ if (wusb_dev == NULL)
+ return -ENOTCONN;
+
port->status |= USB_PORT_STAT_RESET;
port->change |= USB_PORT_STAT_C_RESET;
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index f4aa28eca70..8118db7f1d8 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -312,6 +312,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
result = wusb_set_dev_addr(wusbhc, wusb_dev, 0);
if (result < 0)
goto error_addr0;
+ usb_set_device_state(usb_dev, USB_STATE_DEFAULT);
usb_ep0_reinit(usb_dev);
/* Set new (authenticated) address. */
@@ -327,6 +328,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address);
if (result < 0)
goto error_addr;
+ usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
usb_ep0_reinit(usb_dev);
usb_dev->authenticated = 1;
error_addr:
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
index 238a96aee3a..613a5fc490d 100644
--- a/drivers/usb/wusbcore/wa-xfer.c
+++ b/drivers/usb/wusbcore/wa-xfer.c
@@ -921,8 +921,10 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer)
result = -ENODEV;
/* FIXME: segmentation broken -- kills DWA */
mutex_lock(&wusbhc->mutex); /* get a WUSB dev */
- if (urb->dev == NULL)
+ if (urb->dev == NULL) {
+ mutex_unlock(&wusbhc->mutex);
goto error_dev_gone;
+ }
wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
if (wusb_dev == NULL) {
mutex_unlock(&wusbhc->mutex);
diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c
index c8185e6b0cd..c13cec7dcbc 100644
--- a/drivers/uwb/allocator.c
+++ b/drivers/uwb/allocator.c
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/uwb.h>
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index 2b4f9406789..4f5ca99a04b 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -66,14 +66,14 @@ static void uwb_rc_set_drp_cmd_done(struct uwb_rc *rc, void *arg,
} else
dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n");
- spin_lock(&rc->rsvs_lock);
+ spin_lock_bh(&rc->rsvs_lock);
if (rc->set_drp_ie_pending > 1) {
rc->set_drp_ie_pending = 0;
uwb_rsv_queue_update(rc);
} else {
rc->set_drp_ie_pending = 0;
}
- spin_unlock(&rc->rsvs_lock);
+ spin_unlock_bh(&rc->rsvs_lock);
}
/**
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index ec6eecb32f3..6b76f4bb4cc 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -114,7 +114,8 @@ void uwb_rsv_dump(char *text, struct uwb_rsv *rsv)
devaddr = rsv->target.devaddr;
uwb_dev_addr_print(target, sizeof(target), &devaddr);
- dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state));
+ dev_dbg(dev, "rsv %s %s -> %s: %s\n",
+ text, owner, target, uwb_rsv_state_str(rsv->state));
}
static void uwb_rsv_release(struct kref *kref)
@@ -511,8 +512,7 @@ void uwb_rsv_remove(struct uwb_rsv *rsv)
if (uwb_rsv_is_owner(rsv))
uwb_rsv_put_stream(rsv);
-
- del_timer_sync(&rsv->timer);
+
uwb_dev_put(rsv->owner);
if (rsv->target.type == UWB_RSV_TARGET_DEV)
uwb_dev_put(rsv->target.dev);
@@ -870,7 +870,7 @@ void uwb_rsv_queue_update(struct uwb_rc *rc)
*/
void uwb_rsv_sched_update(struct uwb_rc *rc)
{
- spin_lock(&rc->rsvs_lock);
+ spin_lock_bh(&rc->rsvs_lock);
if (!delayed_work_pending(&rc->rsv_update_work)) {
if (rc->set_drp_ie_pending > 0) {
rc->set_drp_ie_pending++;
@@ -879,7 +879,7 @@ void uwb_rsv_sched_update(struct uwb_rc *rc)
uwb_rsv_queue_update(rc);
}
unlock:
- spin_unlock(&rc->rsvs_lock);
+ spin_unlock_bh(&rc->rsvs_lock);
}
/*
@@ -943,13 +943,22 @@ void uwb_rsv_remove_all(struct uwb_rc *rc)
mutex_lock(&rc->rsvs_mutex);
list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
- uwb_rsv_remove(rsv);
+ if (rsv->state != UWB_RSV_STATE_NONE)
+ uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+ del_timer_sync(&rsv->timer);
}
/* Cancel any postponed update. */
rc->set_drp_ie_pending = 0;
mutex_unlock(&rc->rsvs_mutex);
cancel_delayed_work_sync(&rc->rsv_update_work);
+ flush_workqueue(rc->rsv_workq);
+
+ mutex_lock(&rc->rsvs_mutex);
+ list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
+ uwb_rsv_remove(rsv);
+ }
+ mutex_unlock(&rc->rsvs_mutex);
}
void uwb_rsv_init(struct uwb_rc *rc)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6372f8b17b4..fb19803060c 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -41,7 +41,7 @@ menuconfig FB
You need an utility program called fbset to make full use of frame
buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
and the Framebuffer-HOWTO at
- <http://www.tahallah.demon.co.uk/programming/prog.html> for more
+ <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.2.html> for more
information.
Say Y here and to the driver for your graphics board below if you
@@ -1054,9 +1054,7 @@ config FB_RIVA_BACKLIGHT
config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI && X86_32
- select AGP
- select AGP_INTEL
+ depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1119,9 +1117,7 @@ config FB_CARILLO_RANCH
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI && X86
- select AGP
- select AGP_INTEL
+ depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -2123,6 +2119,18 @@ config FB_PRE_INIT_FB
Select this option if display contents should be inherited as set by
the bootloader.
+config FB_MX3
+ tristate "MX3 Framebuffer support"
+ depends on FB && MX3_IPU
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ default y
+ help
+ This is a framebuffer device for the i.MX31 LCD Controller. So
+ far only synchronous displays are supported. If you plan to use
+ an LCD display with your i.MX31 system, say Y here.
+
source "drivers/video/omap/Kconfig"
source "drivers/video/backlight/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index be2b657546e..2a998ca6181 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -132,6 +132,7 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o
obj-$(CONFIG_FB_OF) += offb.o
obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
+obj-$(CONFIG_FB_MX3) += mx3fb.o
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 8058572a742..018850c116c 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -841,7 +841,7 @@ static int tt_detect(void)
tt_dmasnd.ctrl = DMASND_CTRL_OFF;
udelay(20); /* wait a while for things to settle down */
}
- mono_moni = (mfp.par_dt_reg & 0x80) == 0;
+ mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
tt_get_par(&par);
tt_encode_var(&atafb_predefined[0], &par);
@@ -2035,7 +2035,7 @@ static int stste_detect(void)
tt_dmasnd.ctrl = DMASND_CTRL_OFF;
udelay(20); /* wait a while for things to settle down */
}
- mono_moni = (mfp.par_dt_reg & 0x80) == 0;
+ mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
stste_get_par(&par);
stste_encode_var(&atafb_predefined[0], &par);
@@ -2086,20 +2086,20 @@ static void st_ovsc_switch(void)
return;
local_irq_save(flags);
- mfp.tim_ct_b = 0x10;
- mfp.active_edge |= 8;
- mfp.tim_ct_b = 0;
- mfp.tim_dt_b = 0xf0;
- mfp.tim_ct_b = 8;
- while (mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */
+ st_mfp.tim_ct_b = 0x10;
+ st_mfp.active_edge |= 8;
+ st_mfp.tim_ct_b = 0;
+ st_mfp.tim_dt_b = 0xf0;
+ st_mfp.tim_ct_b = 8;
+ while (st_mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */
;
- new = mfp.tim_dt_b;
+ new = st_mfp.tim_dt_b;
do {
udelay(LINE_DELAY);
old = new;
- new = mfp.tim_dt_b;
+ new = st_mfp.tim_dt_b;
} while (old != new);
- mfp.tim_ct_b = 0x10;
+ st_mfp.tim_ct_b = 0x10;
udelay(SYNC_DELAY);
if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index db16112cf19..35e8eb02b9e 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1475,7 +1475,7 @@ static int aty128fb_set_par(struct fb_info *info)
aty128_set_pll(&par->pll, par);
aty128_set_fifo(&par->fifo_reg, par);
- config = aty_ld_le32(CONFIG_CNTL) & ~3;
+ config = aty_ld_le32(CNFG_CNTL) & ~3;
#if defined(__BIG_ENDIAN)
if (par->crtc.bpp == 32)
@@ -1484,7 +1484,7 @@ static int aty128fb_set_par(struct fb_info *info)
config |= 1; /* make aperture do 16 bit swapping */
#endif
- aty_st_le32(CONFIG_CNTL, config);
+ aty_st_le32(CNFG_CNTL, config);
aty_st_8(CRTC_EXT_CNTL + 1, 0); /* turn the video back on */
info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
@@ -1853,13 +1853,14 @@ static void aty128_bl_exit(struct backlight_device *bd)
* Initialisation
*/
-#ifdef CONFIG_PPC_PMAC
+#ifdef CONFIG_PPC_PMAC__disabled
static void aty128_early_resume(void *data)
{
struct aty128fb_par *par = data;
if (try_acquire_console_sem())
return;
+ pci_restore_state(par->pdev);
aty128_do_resume(par->pdev);
release_console_sem();
}
@@ -1875,7 +1876,7 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
u32 dac;
/* Get the chip revision */
- chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
+ chip_rev = (aty_ld_le32(CNFG_CNTL) >> 16) & 0x1F;
strcpy(video_card, "Rage128 XX ");
video_card[8] = ent->device >> 8;
@@ -1907,7 +1908,14 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
/* Indicate sleep capability */
if (par->chip_gen == rage_M3) {
pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1);
+#if 0 /* Disable the early video resume hack for now as it's causing problems, among
+ * others we now rely on the PCI core restoring the config space for us, which
+ * isn't the case with that hack, and that code path causes various things to
+ * be called with interrupts off while they shouldn't. I'm leaving the code in
+ * as it can be useful for debugging purposes
+ */
pmac_set_early_video_resume(aty128_early_resume, par);
+#endif
}
/* Find default mode */
@@ -2057,7 +2065,7 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_
/* Grab memory size from the card */
// How does this relate to the resource length from the PCI hardware?
- par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+ par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF;
/* Virtualize the framebuffer */
info->screen_base = ioremap(fb_addr, par->vram_size);
@@ -2365,7 +2373,6 @@ static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx
static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
{
u32 pmgt;
- u16 pwr_command;
struct pci_dev *pdev = par->pdev;
if (!par->pm_reg)
@@ -2374,6 +2381,8 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
/* Set the chip into the appropriate suspend mode (we use D2,
* D3 would require a complete re-initialisation of the chip,
* including PCI config registers, clocks, AGP configuration, ...)
+ *
+ * For resume, the core will have already brought us back to D0
*/
if (suspend) {
/* Make sure CRTC2 is reset. Remove that the day we decide to
@@ -2391,17 +2400,9 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
aty_st_le32(BUS_CNTL1, 0x00000010);
aty_st_le32(MEM_POWER_MISC, 0x0c830000);
mdelay(100);
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+
/* Switch PCI power management to D2 */
- pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL,
- (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
- } else {
- /* Switch back PCI power management to D0 */
- mdelay(100);
- pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
- mdelay(100);
+ pci_set_power_state(pdev, PCI_D2);
}
}
@@ -2410,6 +2411,12 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
struct fb_info *info = pci_get_drvdata(pdev);
struct aty128fb_par *par = info->par;
+ /* Because we may change PCI D state ourselves, we need to
+ * first save the config space content so the core can
+ * restore it properly on resume.
+ */
+ pci_save_state(pdev);
+
/* We don't do anything but D2, for now we return 0, but
* we may want to change that. How do we know if the BIOS
* can properly take care of D3 ? Also, with swsusp, we
@@ -2476,6 +2483,11 @@ static int aty128_do_resume(struct pci_dev *pdev)
if (pdev->dev.power.power_state.event == PM_EVENT_ON)
return 0;
+ /* PCI state will have been restored by the core, so
+ * we should be in D0 now with our config space fully
+ * restored
+ */
+
/* Wakeup chip */
aty128_set_suspend(par, 0);
par->asleep = 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index cc6b470073d..1207c208a30 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -135,7 +135,7 @@
#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \
defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)
static const u32 lt_lcd_regs[] = {
- CONFIG_PANEL_LG,
+ CNFG_PANEL_LG,
LCD_GEN_CNTL_LG,
DSTN_CONTROL_LG,
HFB_PITCH_ADDR_LG,
@@ -446,7 +446,7 @@ static int __devinit correct_chipset(struct atyfb_par *par)
par->pll_limits.ecp_max = aty_chips[i].ecp_max;
par->features = aty_chips[i].features;
- chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
+ chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
type = chip_id & CFG_CHIP_TYPE;
rev = (chip_id & CFG_CHIP_REV) >> 24;
@@ -629,7 +629,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
}
- crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
+ crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par);
crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
@@ -676,7 +676,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
/* update non-shadow registers first */
- aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
+ aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par);
aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
@@ -858,7 +858,7 @@ static int aty_var_to_crtc(const struct fb_info *info,
if (!M64_HAS(MOBIL_BUS))
crtc->lcd_index |= CRTC2_DISPLAY_DIS;
- crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
+ crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000;
crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
crtc->lcd_gen_cntl &=
@@ -1978,7 +1978,7 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par)
return timeout ? 0 : -EIO;
}
-#endif
+#endif /* CONFIG_PPC_PMAC */
static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
@@ -2002,9 +2002,15 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
par->asleep = 1;
par->lock_blank = 1;
+ /* Because we may change PCI D state ourselves, we need to
+ * first save the config space content so the core can
+ * restore it properly on resume.
+ */
+ pci_save_state(pdev);
+
#ifdef CONFIG_PPC_PMAC
/* Set chip to "suspend" mode */
- if (aty_power_mgmt(1, par)) {
+ if (machine_is(powermac) && aty_power_mgmt(1, par)) {
par->asleep = 0;
par->lock_blank = 0;
atyfb_blank(FB_BLANK_UNBLANK, info);
@@ -2047,11 +2053,15 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
acquire_console_sem();
+ /* PCI state will have been restored by the core, so
+ * we should be in D0 now with our config space fully
+ * restored
+ */
+
#ifdef CONFIG_PPC_PMAC
- if (pdev->dev.power.power_state.event == 2)
+ if (machine_is(powermac) &&
+ pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
aty_power_mgmt(0, par);
-#else
- pci_set_power_state(pdev, PCI_D0);
#endif
aty_resume_chip(info);
@@ -2254,7 +2264,7 @@ static int __devinit aty_init(struct fb_info *info)
if (!M64_HAS(INTEGRATED)) {
u32 stat0;
u8 dac_type, dac_subtype, clk_type;
- stat0 = aty_ld_le32(CONFIG_STAT0, par);
+ stat0 = aty_ld_le32(CNFG_STAT0, par);
par->bus_type = (stat0 >> 0) & 0x07;
par->ram_type = (stat0 >> 3) & 0x07;
ramname = aty_gx_ram[par->ram_type];
@@ -2324,7 +2334,7 @@ static int __devinit aty_init(struct fb_info *info)
par->dac_ops = &aty_dac_ct;
par->pll_ops = &aty_pll_ct;
par->bus_type = PCI;
- par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
+ par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07);
ramname = aty_ct_ram[par->ram_type];
/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
@@ -2433,7 +2443,7 @@ static int __devinit aty_init(struct fb_info *info)
}
if (M64_HAS(MAGIC_VRAM_SIZE)) {
- if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
+ if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000)
info->fix.smem_len += 0x400000;
}
@@ -2946,7 +2956,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
* Fix PROMs idea of MEM_CNTL settings...
*/
mem = aty_ld_le32(MEM_CNTL, par);
- chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
+ chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
switch (mem & 0x0f) {
case 3:
@@ -2964,7 +2974,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
default:
break;
}
- if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM)
+ if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM)
mem &= ~(0x00700000);
}
mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */
@@ -3572,7 +3582,7 @@ static int __init atyfb_atari_probe(void)
}
/* Fake pci_id for correct_chipset() */
- switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) {
+ switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) {
case 0x00d7:
par->pci_id = PCI_CHIP_MACH64GX;
break;
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index c50c7cf26fe..2745b853948 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -8,6 +8,9 @@
#include <asm/io.h>
#include <video/mach64.h>
#include "atyfb.h"
+#ifdef CONFIG_PPC
+#include <asm/machdep.h>
+#endif
#undef DEBUG
@@ -536,6 +539,14 @@ static int __devinit aty_init_pll_ct(const struct fb_info *info,
pll->ct.xclk_post_div_real = postdividers[xpost_div];
pll->ct.mclk_fb_div = q * pll->ct.xclk_post_div_real / 8;
+#ifdef CONFIG_PPC
+ if (machine_is(powermac)) {
+ /* Override PLL_EXT_CNTL & 0x07. */
+ pll->ct.xclk_post_div = xpost_div;
+ pll->ct.xclk_ref_div = 1;
+ }
+#endif
+
#ifdef DEBUG
pllmclk = (1000000 * pll->ct.mclk_fb_mult * pll->ct.mclk_fb_div) /
(par->ref_clk_per * pll->ct.pll_ref_div);
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index d0f1a7fc2c9..16bb7e3c031 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1936,8 +1936,8 @@ static void fixup_memory_mappings(struct radeonfb_info *rinfo)
OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
mdelay(100);
- aper_base = INREG(CONFIG_APER_0_BASE);
- aper_size = INREG(CONFIG_APER_SIZE);
+ aper_base = INREG(CNFG_APER_0_BASE);
+ aper_size = INREG(CNFG_APER_SIZE);
#ifdef SET_MC_FB_FROM_APERTURE
/* Set framebuffer to be at the same address as set in PCI BAR */
@@ -2024,11 +2024,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
~CRTC_H_CUTOFF_ACTIVE_EN);
}
} else {
- tmp = INREG(CONFIG_MEMSIZE);
+ tmp = INREG(CNFG_MEMSIZE);
}
/* mem size is bits [28:0], mask off the rest */
- rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+ rinfo->video_ram = tmp & CNFG_MEMSIZE_MASK;
/*
* Hack to get around some busted production M6's
@@ -2228,7 +2228,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
*/
rinfo->errata = 0;
if (rinfo->family == CHIP_FAMILY_R300 &&
- (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK)
+ (INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK)
== CFG_ATI_REV_A11)
rinfo->errata |= CHIP_ERRATA_R300_CG;
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 2c5567175dc..359fc64e761 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -72,7 +72,6 @@ static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name)
snprintf(chan->adapter.name, sizeof(chan->adapter.name),
"radeonfb %s", name);
chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_RADEON;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->rinfo->pdev->dev;
chan->algo.setsda = radeon_gpio_setsda;
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 675abdafc2d..c6d7cc76516 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -333,7 +333,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
if (!rinfo->has_CRTC2) {
tmp = INPLL(pllSCLK_CNTL);
- if ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13)
+ if ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13)
tmp &= ~(SCLK_CNTL__FORCE_CP | SCLK_CNTL__FORCE_RB);
tmp &= ~(SCLK_CNTL__FORCE_HDP | SCLK_CNTL__FORCE_DISP1 |
SCLK_CNTL__FORCE_TOP | SCLK_CNTL__FORCE_SE |
@@ -468,9 +468,9 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
/*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/
if ((rinfo->family == CHIP_FAMILY_RV250 &&
- ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ||
+ ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ||
((rinfo->family == CHIP_FAMILY_RV100) &&
- ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) {
+ ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) {
tmp |= SCLK_CNTL__FORCE_CP;
tmp |= SCLK_CNTL__FORCE_VIP;
}
@@ -486,7 +486,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
/* RV200::A11 A12 RV250::A11 A12 */
if (((rinfo->family == CHIP_FAMILY_RV200) ||
(rinfo->family == CHIP_FAMILY_RV250)) &&
- ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13))
+ ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13))
tmp |= SCLK_MORE_CNTL__FORCEON;
OUTPLL(pllSCLK_MORE_CNTL, tmp);
@@ -497,7 +497,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
/* RV200::A11 A12, RV250::A11 A12 */
if (((rinfo->family == CHIP_FAMILY_RV200) ||
(rinfo->family == CHIP_FAMILY_RV250)) &&
- ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) {
+ ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) {
tmp = INPLL(pllPLL_PWRMGT_CNTL);
tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE;
OUTPLL(pllPLL_PWRMGT_CNTL, tmp);
@@ -702,7 +702,7 @@ static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
- OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+ OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
@@ -1723,7 +1723,7 @@ static void radeon_reinitialize_M10(struct radeonfb_info *rinfo)
OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]);
- OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+ OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
OUTREG(BUS_CNTL, rinfo->save_regs[36]);
OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]);
@@ -1961,7 +1961,7 @@ static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo)
OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/);
OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/);
OUTREG(MC_IND_INDEX, 0);
- OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+ OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
mdelay(20);
}
@@ -2361,7 +2361,7 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249);
OUTREG(MC_IND_INDEX, 0);
- OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+ OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
radeon_pm_full_reset_sdram(rinfo);
@@ -2507,11 +2507,28 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
#endif /* CONFIG_PPC_OF */
-static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
+static void radeonfb_whack_power_state(struct radeonfb_info *rinfo, pci_power_t state)
{
u16 pwr_cmd;
+
+ for (;;) {
+ pci_read_config_word(rinfo->pdev,
+ rinfo->pm_reg+PCI_PM_CTRL,
+ &pwr_cmd);
+ if (pwr_cmd & 2)
+ break;
+ pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2;
+ pci_write_config_word(rinfo->pdev,
+ rinfo->pm_reg+PCI_PM_CTRL,
+ pwr_cmd);
+ msleep(500);
+ }
+ rinfo->pdev->current_state = state;
+}
+
+static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
+{
u32 tmp;
- int i;
if (!rinfo->pm_reg)
return;
@@ -2557,32 +2574,19 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
}
}
- for (i = 0; i < 64; ++i)
- pci_read_config_dword(rinfo->pdev, i * 4,
- &rinfo->cfg_save[i]);
-
/* Switch PCI power management to D2. */
pci_disable_device(rinfo->pdev);
- for (;;) {
- pci_read_config_word(
- rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
- &pwr_cmd);
- if (pwr_cmd & 2)
- break;
- pci_write_config_word(
- rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
- (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
- mdelay(500);
- }
+ pci_save_state(rinfo->pdev);
+ /* The chip seems to need us to whack the PM register
+ * repeatedly until it sticks. We do that -prior- to
+ * calling pci_set_power_state()
+ */
+ radeonfb_whack_power_state(rinfo, PCI_D2);
+ pci_set_power_state(rinfo->pdev, PCI_D2);
} else {
printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n",
pci_name(rinfo->pdev));
- /* Switch back PCI powermanagment to D0 */
- mdelay(200);
- pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
- mdelay(500);
-
if (rinfo->family <= CHIP_FAMILY_RV250) {
/* Reset the SDRAM controller */
radeon_pm_full_reset_sdram(rinfo);
@@ -2598,37 +2602,10 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
}
}
-static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo)
-{
- int i;
- static u32 radeon_cfg_after_resume[64];
-
- for (i = 0; i < 64; ++i)
- pci_read_config_dword(rinfo->pdev, i * 4,
- &radeon_cfg_after_resume[i]);
-
- if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4]
- == rinfo->cfg_save[PCI_BASE_ADDRESS_0/4])
- return 0; /* assume everything is ok */
-
- for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) {
- if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i])
- pci_write_config_dword(rinfo->pdev, i * 4,
- rinfo->cfg_save[i]);
- }
- pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE,
- rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]);
- pci_write_config_word(rinfo->pdev, PCI_COMMAND,
- rinfo->cfg_save[PCI_COMMAND/4]);
- return 1;
-}
-
-
int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct radeonfb_info *rinfo = info->par;
- int i;
if (mesg.event == pdev->dev.power.power_state.event)
return 0;
@@ -2674,6 +2651,11 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
pmac_suspend_agp_for_card(pdev);
#endif /* CONFIG_PPC_PMAC */
+ /* It's unclear whether or when the generic code will do that, so let's
+ * do it ourselves. We save state before we do any power management
+ */
+ pci_save_state(pdev);
+
/* If we support wakeup from poweroff, we save all regs we can including cfg
* space
*/
@@ -2698,9 +2680,6 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
mdelay(20);
OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON));
}
- // FIXME: Use PCI layer
- for (i = 0; i < 64; ++i)
- pci_read_config_dword(pdev, i * 4, &rinfo->cfg_save[i]);
pci_disable_device(pdev);
}
/* If we support D2, we go to it (should be fixed later with a flag forcing
@@ -2717,6 +2696,13 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
return 0;
}
+static int radeon_check_power_loss(struct radeonfb_info *rinfo)
+{
+ return rinfo->save_regs[4] != INPLL(CLK_PIN_CNTL) ||
+ rinfo->save_regs[2] != INPLL(MCLK_CNTL) ||
+ rinfo->save_regs[3] != INPLL(SCLK_CNTL);
+}
+
int radeonfb_pci_resume(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
@@ -2735,20 +2721,13 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n",
pci_name(pdev), pdev->dev.power.power_state.event);
-
- if (pci_enable_device(pdev)) {
- rc = -ENODEV;
- printk(KERN_ERR "radeonfb (%s): can't enable PCI device !\n",
- pci_name(pdev));
- goto bail;
- }
- pci_set_master(pdev);
-
+ /* PCI state will have been restored by the core, so
+ * we should be in D0 now with our config space fully
+ * restored
+ */
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
- /* Wakeup chip. Check from config space if we were powered off
- * (todo: additionally, check CLK_PIN_CNTL too)
- */
- if ((rinfo->pm_mode & radeon_pm_off) && radeon_restore_pci_cfg(rinfo)) {
+ /* Wakeup chip */
+ if ((rinfo->pm_mode & radeon_pm_off) && radeon_check_power_loss(rinfo)) {
if (rinfo->reinit_func != NULL)
rinfo->reinit_func(rinfo);
else {
@@ -2807,12 +2786,13 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
return rc;
}
-#ifdef CONFIG_PPC_OF
+#ifdef CONFIG_PPC_OF__disabled
static void radeonfb_early_resume(void *data)
{
struct radeonfb_info *rinfo = data;
rinfo->no_schedule = 1;
+ pci_restore_state(rinfo->pdev);
radeonfb_pci_resume(rinfo->pdev);
rinfo->no_schedule = 0;
}
@@ -2879,7 +2859,14 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis
*/
if (rinfo->pm_mode != radeon_pm_none) {
pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, rinfo->of_node, 0, 1);
+#if 0 /* Disable the early video resume hack for now as it's causing problems, among
+ * others we now rely on the PCI core restoring the config space for us, which
+ * isn't the case with that hack, and that code path causes various things to
+ * be called with interrupts off while they shouldn't. I'm leaving the code in
+ * as it can be useful for debugging purposes
+ */
pmac_set_early_video_resume(radeonfb_early_resume, rinfo);
+#endif
}
#if 0
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 3ea1b00fdd2..7351e66c7f5 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -361,8 +361,6 @@ struct radeonfb_info {
#ifdef CONFIG_FB_RADEON_I2C
struct radeon_i2c_chan i2c[4];
#endif
-
- u32 cfg_save[64];
};
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 62bd4441b5e..378f27745a1 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops =
/* AU1100 LCD controller device driver */
-static int __init au1100fb_drv_probe(struct device *dev)
+static int __init au1100fb_drv_probe(struct platform_device *dev)
{
struct au1100fb_device *fbdev = NULL;
struct resource *regs_res;
@@ -475,7 +475,7 @@ static int __init au1100fb_drv_probe(struct device *dev)
fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
- dev_set_drvdata(dev, (void*)fbdev);
+ platform_set_drvdata(dev, (void *)fbdev);
/* Allocate region for our registers and map them */
if (!(regs_res = platform_get_resource(to_platform_device(dev),
@@ -583,19 +583,19 @@ failed:
fb_dealloc_cmap(&fbdev->info.cmap);
}
kfree(fbdev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
return 0;
}
-int au1100fb_drv_remove(struct device *dev)
+int au1100fb_drv_remove(struct platform_device *dev)
{
struct au1100fb_device *fbdev = NULL;
if (!dev)
return -ENODEV;
- fbdev = (struct au1100fb_device*) dev_get_drvdata(dev);
+ fbdev = (struct au1100fb_device *) platform_get_drvdata(dev);
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
@@ -620,9 +620,9 @@ int au1100fb_drv_remove(struct device *dev)
static u32 sys_clksrc;
static struct au1100fb_regs fbregs;
-int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
+int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state)
{
- struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+ struct au1100fb_device *fbdev = platform_get_drvdata(dev);
if (!fbdev)
return 0;
@@ -641,9 +641,9 @@ int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
return 0;
}
-int au1100fb_drv_resume(struct device *dev)
+int au1100fb_drv_resume(struct platform_device *dev)
{
- struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+ struct au1100fb_device *fbdev = platform_get_drvdata(dev);
if (!fbdev)
return 0;
@@ -663,10 +663,11 @@ int au1100fb_drv_resume(struct device *dev)
#define au1100fb_drv_resume NULL
#endif
-static struct device_driver au1100fb_driver = {
- .name = "au1100-lcd",
- .bus = &platform_bus_type,
-
+static struct platform_driver au1100fb_driver = {
+ .driver = {
+ .name = "au1100-lcd",
+ .owner = THIS_MODULE,
+ },
.probe = au1100fb_drv_probe,
.remove = au1100fb_drv_remove,
.suspend = au1100fb_drv_suspend,
@@ -753,12 +754,12 @@ int __init au1100fb_init(void)
return ret;
}
- return driver_register(&au1100fb_driver);
+ return platform_driver_register(&au1100fb_driver);
}
void __exit au1100fb_cleanup(void)
{
- driver_unregister(&au1100fb_driver);
+ platform_driver_unregister(&au1100fb_driver);
kfree(drv_info.opt_mode);
}
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 03e57ef8837..0d96f1d2d4c 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1622,7 +1622,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
/* AU1200 LCD controller device driver */
-static int au1200fb_drv_probe(struct device *dev)
+static int au1200fb_drv_probe(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
unsigned long page;
@@ -1645,7 +1645,7 @@ static int au1200fb_drv_probe(struct device *dev)
/* Allocate the framebuffer to the maximum screen size */
fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
- fbdev->fb_mem = dma_alloc_noncoherent(dev,
+ fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev,
PAGE_ALIGN(fbdev->fb_len),
&fbdev->fb_phys, GFP_KERNEL);
if (!fbdev->fb_mem) {
@@ -1715,7 +1715,7 @@ failed:
return ret;
}
-static int au1200fb_drv_remove(struct device *dev)
+static int au1200fb_drv_remove(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
int plane;
@@ -1733,7 +1733,8 @@ static int au1200fb_drv_remove(struct device *dev)
/* Clean up all probe data */
unregister_framebuffer(&fbdev->fb_info);
if (fbdev->fb_mem)
- dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
+ dma_free_noncoherent(&dev->dev,
+ PAGE_ALIGN(fbdev->fb_len),
fbdev->fb_mem, fbdev->fb_phys);
if (fbdev->fb_info.cmap.len != 0)
fb_dealloc_cmap(&fbdev->fb_info.cmap);
@@ -1747,22 +1748,24 @@ static int au1200fb_drv_remove(struct device *dev)
}
#ifdef CONFIG_PM
-static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level)
+static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
{
/* TODO */
return 0;
}
-static int au1200fb_drv_resume(struct device *dev, u32 level)
+static int au1200fb_drv_resume(struct platform_device *dev)
{
/* TODO */
return 0;
}
#endif /* CONFIG_PM */
-static struct device_driver au1200fb_driver = {
- .name = "au1200-lcd",
- .bus = &platform_bus_type,
+static struct platform_driver au1200fb_driver = {
+ .driver = {
+ .name = "au1200-lcd",
+ .owner = THIS_MODULE,
+ },
.probe = au1200fb_drv_probe,
.remove = au1200fb_drv_remove,
#ifdef CONFIG_PM
@@ -1906,12 +1909,12 @@ static int __init au1200fb_init(void)
printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
#endif
- return driver_register(&au1200fb_driver);
+ return platform_driver_register(&au1200fb_driver);
}
static void __exit au1200fb_cleanup(void)
{
- driver_unregister(&au1200fb_driver);
+ platform_driver_unregister(&au1200fb_driver);
}
module_init(au1200fb_init);
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 363b3cb2f01..63d75949816 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
-obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o
+obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
diff --git a/drivers/video/backlight/da903x.c b/drivers/video/backlight/da903x_bl.c
index 93bb4340cc6..93bb4340cc6 100644
--- a/drivers/video/backlight/da903x.c
+++ b/drivers/video/backlight/da903x_bl.c
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 2a423d3a2a8..90cfddabf1f 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -447,7 +447,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __init bfin_t350mcqb_probe(struct platform_device *pdev)
+static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
{
struct bfin_t350mcqbfb_info *info;
struct fb_info *fbinfo;
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 91b78e69150..f53b9f1d6ab 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -250,10 +250,6 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
int rc, size = cmap->len * sizeof(u16);
struct fb_cmap umap;
- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
- !info->fbops->fb_setcmap))
- return -EINVAL;
-
memset(&umap, 0, sizeof(struct fb_cmap));
rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
if (rc)
@@ -262,11 +258,23 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
copy_from_user(umap.green, cmap->green, size) ||
copy_from_user(umap.blue, cmap->blue, size) ||
(cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
- fb_dealloc_cmap(&umap);
- return -EFAULT;
+ rc = -EFAULT;
+ goto out;
}
umap.start = cmap->start;
+ if (!lock_fb_info(info)) {
+ rc = -ENODEV;
+ goto out;
+ }
+ if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
+ !info->fbops->fb_setcmap)) {
+ rc = -EINVAL;
+ goto out1;
+ }
rc = fb_set_cmap(&umap, info);
+out1:
+ unlock_fb_info(info);
+out:
fb_dealloc_cmap(&umap);
return rc;
}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 756efeb91ab..cfd9dce1ce0 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1013,132 +1013,139 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
struct fb_con2fbmap con2fb;
+ struct fb_cmap cmap_from;
struct fb_cmap_user cmap;
struct fb_event event;
void __user *argp = (void __user *)arg;
long ret = 0;
- fb = info->fbops;
- if (!fb)
- return -ENODEV;
-
switch (cmd) {
case FBIOGET_VSCREENINFO:
- ret = copy_to_user(argp, &info->var,
- sizeof(var)) ? -EFAULT : 0;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ var = info->var;
+ unlock_fb_info(info);
+
+ ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;
break;
case FBIOPUT_VSCREENINFO:
- if (copy_from_user(&var, argp, sizeof(var))) {
- ret = -EFAULT;
- break;
- }
+ if (copy_from_user(&var, argp, sizeof(var)))
+ return -EFAULT;
+ if (!lock_fb_info(info))
+ return -ENODEV;
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
- if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
+ unlock_fb_info(info);
+ if (!ret && copy_to_user(argp, &var, sizeof(var)))
ret = -EFAULT;
break;
case FBIOGET_FSCREENINFO:
- ret = copy_to_user(argp, &info->fix,
- sizeof(fix)) ? -EFAULT : 0;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ fix = info->fix;
+ unlock_fb_info(info);
+
+ ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0;
break;
case FBIOPUTCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
- ret = -EFAULT;
- else
- ret = fb_set_user_cmap(&cmap, info);
+ return -EFAULT;
+ ret = fb_set_user_cmap(&cmap, info);
break;
case FBIOGETCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
- ret = -EFAULT;
- else
- ret = fb_cmap_to_user(&info->cmap, &cmap);
+ return -EFAULT;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ cmap_from = info->cmap;
+ unlock_fb_info(info);
+ ret = fb_cmap_to_user(&cmap_from, &cmap);
break;
case FBIOPAN_DISPLAY:
- if (copy_from_user(&var, argp, sizeof(var))) {
- ret = -EFAULT;
- break;
- }
+ if (copy_from_user(&var, argp, sizeof(var)))
+ return -EFAULT;
+ if (!lock_fb_info(info))
+ return -ENODEV;
acquire_console_sem();
ret = fb_pan_display(info, &var);
release_console_sem();
+ unlock_fb_info(info);
if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
- ret = -EFAULT;
+ return -EFAULT;
break;
case FBIO_CURSOR:
ret = -EINVAL;
break;
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
- ret = -EFAULT;
- else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
- ret = -EINVAL;
- else {
- con2fb.framebuffer = -1;
- event.info = info;
- event.data = &con2fb;
- fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP,
- &event);
- ret = copy_to_user(argp, &con2fb,
- sizeof(con2fb)) ? -EFAULT : 0;
- }
+ return -EFAULT;
+ if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
+ return -EINVAL;
+ con2fb.framebuffer = -1;
+ event.data = &con2fb;
+
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ event.info = info;
+ fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
+ unlock_fb_info(info);
+
+ ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
break;
case FBIOPUT_CON2FBMAP:
- if (copy_from_user(&con2fb, argp, sizeof(con2fb))) {
- ret = -EFAULT;
- break;
- }
- if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) {
- ret = -EINVAL;
- break;
- }
- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) {
- ret = -EINVAL;
- break;
- }
+ if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
+ return -EFAULT;
+ if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
+ return -EINVAL;
+ if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
+ return -EINVAL;
if (!registered_fb[con2fb.framebuffer])
request_module("fb%d", con2fb.framebuffer);
if (!registered_fb[con2fb.framebuffer]) {
ret = -EINVAL;
break;
}
- event.info = info;
event.data = &con2fb;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ event.info = info;
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
&event);
+ unlock_fb_info(info);
break;
case FBIOBLANK:
+ if (!lock_fb_info(info))
+ return -ENODEV;
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_blank(info, arg);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
- break;;
+ unlock_fb_info(info);
+ break;
default:
- if (fb->fb_ioctl == NULL)
- ret = -ENOTTY;
- else
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ fb = info->fbops;
+ if (fb->fb_ioctl)
ret = fb->fb_ioctl(info, cmd, arg);
+ else
+ ret = -ENOTTY;
+ unlock_fb_info(info);
}
return ret;
}
static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-__acquires(&info->lock)
-__releases(&info->lock)
{
struct inode *inode = file->f_path.dentry->d_inode;
int fbidx = iminor(inode);
- struct fb_info *info;
- long ret;
+ struct fb_info *info = registered_fb[fbidx];
- info = registered_fb[fbidx];
- mutex_lock(&info->lock);
- ret = do_fb_ioctl(info, cmd, arg);
- mutex_unlock(&info->lock);
- return ret;
+ return do_fb_ioctl(info, cmd, arg);
}
#ifdef CONFIG_COMPAT
@@ -1257,8 +1264,6 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd,
static long fb_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
-__acquires(&info->lock)
-__releases(&info->lock)
{
struct inode *inode = file->f_path.dentry->d_inode;
int fbidx = iminor(inode);
@@ -1266,7 +1271,6 @@ __releases(&info->lock)
struct fb_ops *fb = info->fbops;
long ret = -ENOIOCTLCMD;
- mutex_lock(&info->lock);
switch(cmd) {
case FBIOGET_VSCREENINFO:
case FBIOPUT_VSCREENINFO:
@@ -1292,7 +1296,6 @@ __releases(&info->lock)
ret = fb->fb_compat_ioctl(info, cmd, arg);
break;
}
- mutex_unlock(&info->lock);
return ret;
}
#endif
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 751e491ca8c..f20eff8c4a8 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -136,13 +136,10 @@ static int gx1fb_set_par(struct fb_info *info)
{
struct geodefb_par *par = info->par;
- if (info->var.bits_per_pixel == 16) {
+ if (info->var.bits_per_pixel == 16)
info->fix.visual = FB_VISUAL_TRUECOLOR;
- fb_dealloc_cmap(&info->cmap);
- } else {
+ else
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
- }
info->fix.line_length = gx1_line_delta(info->var.xres, info->var.bits_per_pixel);
@@ -315,6 +312,10 @@ static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
if (!par->panel_x)
par->enable_crt = 1; /* fall back to CRT if no panel is specified */
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ framebuffer_release(info);
+ return NULL;
+ }
return info;
}
@@ -374,8 +375,11 @@ static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *
release_mem_region(gx1_gx_base() + 0x8300, 0x100);
}
- if (info)
+ if (info) {
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
+ }
+
return ret;
}
@@ -395,6 +399,7 @@ static void gx1fb_remove(struct pci_dev *pdev)
iounmap(par->dc_regs);
release_mem_region(gx1_gx_base() + 0x8300, 0x100);
+ fb_dealloc_cmap(&info->cmap);
pci_set_drvdata(pdev, NULL);
framebuffer_release(info);
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 48411892631..2552cac39e1 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -171,13 +171,10 @@ static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static int gxfb_set_par(struct fb_info *info)
{
- if (info->var.bits_per_pixel > 8) {
+ if (info->var.bits_per_pixel > 8)
info->fix.visual = FB_VISUAL_TRUECOLOR;
- fb_dealloc_cmap(&info->cmap);
- } else {
+ else
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
- }
info->fix.line_length = gx_line_delta(info->var.xres, info->var.bits_per_pixel);
@@ -331,6 +328,11 @@ static struct fb_info * __init gxfb_init_fbinfo(struct device *dev)
info->var.grayscale = 0;
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ framebuffer_release(info);
+ return NULL;
+ }
+
return info;
}
@@ -443,8 +445,10 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
pci_release_region(pdev, 1);
}
- if (info)
+ if (info) {
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
+ }
return ret;
}
@@ -467,6 +471,7 @@ static void gxfb_remove(struct pci_dev *pdev)
iounmap(par->gp_regs);
pci_release_region(pdev, 1);
+ fb_dealloc_cmap(&info->cmap);
pci_set_drvdata(pdev, NULL);
framebuffer_release(info);
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index b965ecdbc60..889cbe39e58 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -278,13 +278,10 @@ static int lxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static int lxfb_set_par(struct fb_info *info)
{
- if (info->var.bits_per_pixel > 8) {
+ if (info->var.bits_per_pixel > 8)
info->fix.visual = FB_VISUAL_TRUECOLOR;
- fb_dealloc_cmap(&info->cmap);
- } else {
+ else
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
- }
info->fix.line_length = lx_get_pitch(info->var.xres,
info->var.bits_per_pixel);
@@ -451,6 +448,11 @@ static struct fb_info * __init lxfb_init_fbinfo(struct device *dev)
info->pseudo_palette = (void *)par + sizeof(struct lxfb_par);
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ framebuffer_release(info);
+ return NULL;
+ }
+
info->var.grayscale = 0;
return info;
@@ -579,8 +581,10 @@ err:
pci_release_region(pdev, 3);
}
- if (info)
+ if (info) {
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
+ }
return ret;
}
@@ -604,6 +608,7 @@ static void lxfb_remove(struct pci_dev *pdev)
iounmap(par->vp_regs);
pci_release_region(pdev, 3);
+ fb_dealloc_cmap(&info->cmap);
pci_set_drvdata(pdev, NULL);
framebuffer_release(info);
}
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 7787c3322ff..9dd55e5324a 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -90,7 +90,6 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name)
chan->adapter.owner = THIS_MODULE;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->dev->dev;
- chan->adapter.id = I2C_HW_B_I810;
chan->algo.setsda = i810i2c_setsda;
chan->algo.setscl = i810i2c_setscl;
chan->algo.getsda = i810i2c_getsda;
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index a24e680d2b9..2e940199fc8 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -993,6 +993,7 @@ static int i810_check_params(struct fb_var_screeninfo *var,
struct i810fb_par *par = info->par;
int line_length, vidmem, mode_valid = 0, retval = 0;
u32 vyres = var->yres_virtual, vxres = var->xres_virtual;
+
/*
* Memory limit
*/
@@ -1002,12 +1003,12 @@ static int i810_check_params(struct fb_var_screeninfo *var,
if (vidmem > par->fb.size) {
vyres = par->fb.size/line_length;
if (vyres < var->yres) {
- vyres = yres;
+ vyres = info->var.yres;
vxres = par->fb.size/vyres;
vxres /= var->bits_per_pixel >> 3;
line_length = get_line_length(par, vxres,
var->bits_per_pixel);
- vidmem = line_length * yres;
+ vidmem = line_length * info->var.yres;
if (vxres < var->xres) {
printk("i810fb: required video memory, "
"%d bytes, for %dx%d-%d (virtual) "
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index 5d896b81f4e..b3065492bb2 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -111,7 +111,6 @@ static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
"intelfb %s", name);
chan->adapter.class = class;
chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_INTELFB;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->dinfo->pdev->dev;
chan->algo.setsda = intelfb_gpio_setsda;
diff --git a/drivers/video/logo/logo_linux_clut224.ppm b/drivers/video/logo/logo_linux_clut224.ppm
index 3c14e43b82f..de93ff3fc1a 100644
--- a/drivers/video/logo/logo_linux_clut224.ppm
+++ b/drivers/video/logo/logo_linux_clut224.ppm
@@ -1,1604 +1,2828 @@
P3
-# Standard 224-color Linux logo
-80 80
+145 113
255
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 6 6 6 10 10 10 10 10 10
- 10 10 10 6 6 6 6 6 6 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 6 6 6 10 10 10 14 14 14
- 22 22 22 26 26 26 30 30 30 34 34 34
- 30 30 30 30 30 30 26 26 26 18 18 18
- 14 14 14 10 10 10 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 14 14 14 26 26 26 42 42 42
- 54 54 54 66 66 66 78 78 78 78 78 78
- 78 78 78 74 74 74 66 66 66 54 54 54
- 42 42 42 26 26 26 18 18 18 10 10 10
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 22 22 22 42 42 42 66 66 66 86 86 86
- 66 66 66 38 38 38 38 38 38 22 22 22
- 26 26 26 34 34 34 54 54 54 66 66 66
- 86 86 86 70 70 70 46 46 46 26 26 26
- 14 14 14 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 10 10 10 26 26 26
- 50 50 50 82 82 82 58 58 58 6 6 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 6 6 6 54 54 54 86 86 86 66 66 66
- 38 38 38 18 18 18 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 6 6 6 22 22 22 50 50 50
- 78 78 78 34 34 34 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 6 6 6 70 70 70
- 78 78 78 46 46 46 22 22 22 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 18 18 18 42 42 42 82 82 82
- 26 26 26 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 14 14 14
- 46 46 46 34 34 34 6 6 6 2 2 6
- 42 42 42 78 78 78 42 42 42 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 0 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 10 10 10 30 30 30 66 66 66 58 58 58
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 26 26 26
- 86 86 86 101 101 101 46 46 46 10 10 10
- 2 2 6 58 58 58 70 70 70 34 34 34
- 10 10 10 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 14 14 14 42 42 42 86 86 86 10 10 10
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 30 30 30
- 94 94 94 94 94 94 58 58 58 26 26 26
- 2 2 6 6 6 6 78 78 78 54 54 54
- 22 22 22 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 22 22 22 62 62 62 62 62 62 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 26 26 26
- 54 54 54 38 38 38 18 18 18 10 10 10
- 2 2 6 2 2 6 34 34 34 82 82 82
- 38 38 38 14 14 14 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 30 30 30 78 78 78 30 30 30 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 10 10 10
- 10 10 10 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 78 78 78
- 50 50 50 18 18 18 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 38 38 38 86 86 86 14 14 14 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 54 54 54
- 66 66 66 26 26 26 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 42 42 42 82 82 82 2 2 6 2 2 6
- 2 2 6 6 6 6 10 10 10 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 6 6 6
- 14 14 14 10 10 10 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 18 18 18
- 82 82 82 34 34 34 10 10 10 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 46 46 46 86 86 86 2 2 6 2 2 6
- 6 6 6 6 6 6 22 22 22 34 34 34
- 6 6 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 18 18 18 34 34 34
- 10 10 10 50 50 50 22 22 22 2 2 6
- 2 2 6 2 2 6 2 2 6 10 10 10
- 86 86 86 42 42 42 14 14 14 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 46 46 46 86 86 86 2 2 6 2 2 6
- 38 38 38 116 116 116 94 94 94 22 22 22
- 22 22 22 2 2 6 2 2 6 2 2 6
- 14 14 14 86 86 86 138 138 138 162 162 162
-154 154 154 38 38 38 26 26 26 6 6 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 86 86 86 46 46 46 14 14 14 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 46 46 46 86 86 86 2 2 6 14 14 14
-134 134 134 198 198 198 195 195 195 116 116 116
- 10 10 10 2 2 6 2 2 6 6 6 6
-101 98 89 187 187 187 210 210 210 218 218 218
-214 214 214 134 134 134 14 14 14 6 6 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 86 86 86 50 50 50 18 18 18 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 1 0 0 0
- 0 0 1 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 46 46 46 86 86 86 2 2 6 54 54 54
-218 218 218 195 195 195 226 226 226 246 246 246
- 58 58 58 2 2 6 2 2 6 30 30 30
-210 210 210 253 253 253 174 174 174 123 123 123
-221 221 221 234 234 234 74 74 74 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 70 70 70 58 58 58 22 22 22 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 46 46 46 82 82 82 2 2 6 106 106 106
-170 170 170 26 26 26 86 86 86 226 226 226
-123 123 123 10 10 10 14 14 14 46 46 46
-231 231 231 190 190 190 6 6 6 70 70 70
- 90 90 90 238 238 238 158 158 158 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 70 70 70 58 58 58 22 22 22 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 1 0 0 0
- 0 0 1 0 0 1 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 42 42 42 86 86 86 6 6 6 116 116 116
-106 106 106 6 6 6 70 70 70 149 149 149
-128 128 128 18 18 18 38 38 38 54 54 54
-221 221 221 106 106 106 2 2 6 14 14 14
- 46 46 46 190 190 190 198 198 198 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 74 74 74 62 62 62 22 22 22 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 1 0 0 0
- 0 0 1 0 0 0 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 42 42 42 94 94 94 14 14 14 101 101 101
-128 128 128 2 2 6 18 18 18 116 116 116
-118 98 46 121 92 8 121 92 8 98 78 10
-162 162 162 106 106 106 2 2 6 2 2 6
- 2 2 6 195 195 195 195 195 195 6 6 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 74 74 74 62 62 62 22 22 22 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 1 0 0 1
- 0 0 1 0 0 0 0 0 1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 38 38 38 90 90 90 14 14 14 58 58 58
-210 210 210 26 26 26 54 38 6 154 114 10
-226 170 11 236 186 11 225 175 15 184 144 12
-215 174 15 175 146 61 37 26 9 2 2 6
- 70 70 70 246 246 246 138 138 138 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 70 70 70 66 66 66 26 26 26 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 38 38 38 86 86 86 14 14 14 10 10 10
-195 195 195 188 164 115 192 133 9 225 175 15
-239 182 13 234 190 10 232 195 16 232 200 30
-245 207 45 241 208 19 232 195 16 184 144 12
-218 194 134 211 206 186 42 42 42 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 50 50 50 74 74 74 30 30 30 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 34 34 34 86 86 86 14 14 14 2 2 6
-121 87 25 192 133 9 219 162 10 239 182 13
-236 186 11 232 195 16 241 208 19 244 214 54
-246 218 60 246 218 38 246 215 20 241 208 19
-241 208 19 226 184 13 121 87 25 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 50 50 50 82 82 82 34 34 34 10 10 10
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 34 34 34 82 82 82 30 30 30 61 42 6
-180 123 7 206 145 10 230 174 11 239 182 13
-234 190 10 238 202 15 241 208 19 246 218 74
-246 218 38 246 215 20 246 215 20 246 215 20
-226 184 13 215 174 15 184 144 12 6 6 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 26 26 26 94 94 94 42 42 42 14 14 14
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 30 30 30 78 78 78 50 50 50 104 69 6
-192 133 9 216 158 10 236 178 12 236 186 11
-232 195 16 241 208 19 244 214 54 245 215 43
-246 215 20 246 215 20 241 208 19 198 155 10
-200 144 11 216 158 10 156 118 10 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 6 6 6 90 90 90 54 54 54 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 30 30 30 78 78 78 46 46 46 22 22 22
-137 92 6 210 162 10 239 182 13 238 190 10
-238 202 15 241 208 19 246 215 20 246 215 20
-241 208 19 203 166 17 185 133 11 210 150 10
-216 158 10 210 150 10 102 78 10 2 2 6
- 6 6 6 54 54 54 14 14 14 2 2 6
- 2 2 6 62 62 62 74 74 74 30 30 30
- 10 10 10 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 34 34 34 78 78 78 50 50 50 6 6 6
- 94 70 30 139 102 15 190 146 13 226 184 13
-232 200 30 232 195 16 215 174 15 190 146 13
-168 122 10 192 133 9 210 150 10 213 154 11
-202 150 34 182 157 106 101 98 89 2 2 6
- 2 2 6 78 78 78 116 116 116 58 58 58
- 2 2 6 22 22 22 90 90 90 46 46 46
- 18 18 18 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 38 38 38 86 86 86 50 50 50 6 6 6
-128 128 128 174 154 114 156 107 11 168 122 10
-198 155 10 184 144 12 197 138 11 200 144 11
-206 145 10 206 145 10 197 138 11 188 164 115
-195 195 195 198 198 198 174 174 174 14 14 14
- 2 2 6 22 22 22 116 116 116 116 116 116
- 22 22 22 2 2 6 74 74 74 70 70 70
- 30 30 30 10 10 10 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 18 18 18
- 50 50 50 101 101 101 26 26 26 10 10 10
-138 138 138 190 190 190 174 154 114 156 107 11
-197 138 11 200 144 11 197 138 11 192 133 9
-180 123 7 190 142 34 190 178 144 187 187 187
-202 202 202 221 221 221 214 214 214 66 66 66
- 2 2 6 2 2 6 50 50 50 62 62 62
- 6 6 6 2 2 6 10 10 10 90 90 90
- 50 50 50 18 18 18 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 10 10 10 34 34 34
- 74 74 74 74 74 74 2 2 6 6 6 6
-144 144 144 198 198 198 190 190 190 178 166 146
-154 121 60 156 107 11 156 107 11 168 124 44
-174 154 114 187 187 187 190 190 190 210 210 210
-246 246 246 253 253 253 253 253 253 182 182 182
- 6 6 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 62 62 62
- 74 74 74 34 34 34 14 14 14 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 10 10 10 22 22 22 54 54 54
- 94 94 94 18 18 18 2 2 6 46 46 46
-234 234 234 221 221 221 190 190 190 190 190 190
-190 190 190 187 187 187 187 187 187 190 190 190
-190 190 190 195 195 195 214 214 214 242 242 242
-253 253 253 253 253 253 253 253 253 253 253 253
- 82 82 82 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 14 14 14
- 86 86 86 54 54 54 22 22 22 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 18 18 18 46 46 46 90 90 90
- 46 46 46 18 18 18 6 6 6 182 182 182
-253 253 253 246 246 246 206 206 206 190 190 190
-190 190 190 190 190 190 190 190 190 190 190 190
-206 206 206 231 231 231 250 250 250 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-202 202 202 14 14 14 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 42 42 42 86 86 86 42 42 42 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 14 14 14 38 38 38 74 74 74 66 66 66
- 2 2 6 6 6 6 90 90 90 250 250 250
-253 253 253 253 253 253 238 238 238 198 198 198
-190 190 190 190 190 190 195 195 195 221 221 221
-246 246 246 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 82 82 82 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 78 78 78 70 70 70 34 34 34
- 14 14 14 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 34 34 34 66 66 66 78 78 78 6 6 6
- 2 2 6 18 18 18 218 218 218 253 253 253
-253 253 253 253 253 253 253 253 253 246 246 246
-226 226 226 231 231 231 246 246 246 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 178 178 178 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 18 18 18 90 90 90 62 62 62
- 30 30 30 10 10 10 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 10 10 10 26 26 26
- 58 58 58 90 90 90 18 18 18 2 2 6
- 2 2 6 110 110 110 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-250 250 250 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 231 231 231 18 18 18 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 18 18 18 94 94 94
- 54 54 54 26 26 26 10 10 10 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 6 6 6 22 22 22 50 50 50
- 90 90 90 26 26 26 2 2 6 2 2 6
- 14 14 14 195 195 195 250 250 250 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-250 250 250 242 242 242 54 54 54 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 38 38 38
- 86 86 86 50 50 50 22 22 22 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 14 14 14 38 38 38 82 82 82
- 34 34 34 2 2 6 2 2 6 2 2 6
- 42 42 42 195 195 195 246 246 246 253 253 253
-253 253 253 253 253 253 253 253 253 250 250 250
-242 242 242 242 242 242 250 250 250 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 250 250 250 246 246 246 238 238 238
-226 226 226 231 231 231 101 101 101 6 6 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 38 38 38 82 82 82 42 42 42 14 14 14
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 10 10 10 26 26 26 62 62 62 66 66 66
- 2 2 6 2 2 6 2 2 6 6 6 6
- 70 70 70 170 170 170 206 206 206 234 234 234
-246 246 246 250 250 250 250 250 250 238 238 238
-226 226 226 231 231 231 238 238 238 250 250 250
-250 250 250 250 250 250 246 246 246 231 231 231
-214 214 214 206 206 206 202 202 202 202 202 202
-198 198 198 202 202 202 182 182 182 18 18 18
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 62 62 62 66 66 66 30 30 30
- 10 10 10 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 14 14 14 42 42 42 82 82 82 18 18 18
- 2 2 6 2 2 6 2 2 6 10 10 10
- 94 94 94 182 182 182 218 218 218 242 242 242
-250 250 250 253 253 253 253 253 253 250 250 250
-234 234 234 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 246 246 246
-238 238 238 226 226 226 210 210 210 202 202 202
-195 195 195 195 195 195 210 210 210 158 158 158
- 6 6 6 14 14 14 50 50 50 14 14 14
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 6 6 6 86 86 86 46 46 46
- 18 18 18 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 22 22 22 54 54 54 70 70 70 2 2 6
- 2 2 6 10 10 10 2 2 6 22 22 22
-166 166 166 231 231 231 250 250 250 253 253 253
-253 253 253 253 253 253 253 253 253 250 250 250
-242 242 242 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 246 246 246
-231 231 231 206 206 206 198 198 198 226 226 226
- 94 94 94 2 2 6 6 6 6 38 38 38
- 30 30 30 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 62 62 62 66 66 66
- 26 26 26 10 10 10 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 30 30 30 74 74 74 50 50 50 2 2 6
- 26 26 26 26 26 26 2 2 6 106 106 106
-238 238 238 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 246 246 246 218 218 218 202 202 202
-210 210 210 14 14 14 2 2 6 2 2 6
- 30 30 30 22 22 22 2 2 6 2 2 6
- 2 2 6 2 2 6 18 18 18 86 86 86
- 42 42 42 14 14 14 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 42 42 42 90 90 90 22 22 22 2 2 6
- 42 42 42 2 2 6 18 18 18 218 218 218
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 250 250 250 221 221 221
-218 218 218 101 101 101 2 2 6 14 14 14
- 18 18 18 38 38 38 10 10 10 2 2 6
- 2 2 6 2 2 6 2 2 6 78 78 78
- 58 58 58 22 22 22 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 18 18 18
- 54 54 54 82 82 82 2 2 6 26 26 26
- 22 22 22 2 2 6 123 123 123 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 250 250 250
-238 238 238 198 198 198 6 6 6 38 38 38
- 58 58 58 26 26 26 38 38 38 2 2 6
- 2 2 6 2 2 6 2 2 6 46 46 46
- 78 78 78 30 30 30 10 10 10 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 10 10 10 30 30 30
- 74 74 74 58 58 58 2 2 6 42 42 42
- 2 2 6 22 22 22 231 231 231 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 250 250 250
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 246 246 246 46 46 46 38 38 38
- 42 42 42 14 14 14 38 38 38 14 14 14
- 2 2 6 2 2 6 2 2 6 6 6 6
- 86 86 86 46 46 46 14 14 14 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 6 6 6 14 14 14 42 42 42
- 90 90 90 18 18 18 18 18 18 26 26 26
- 2 2 6 116 116 116 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 250 250 250 238 238 238
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 94 94 94 6 6 6
- 2 2 6 2 2 6 10 10 10 34 34 34
- 2 2 6 2 2 6 2 2 6 2 2 6
- 74 74 74 58 58 58 22 22 22 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 10 10 10 26 26 26 66 66 66
- 82 82 82 2 2 6 38 38 38 6 6 6
- 14 14 14 210 210 210 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 246 246 246 242 242 242
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 144 144 144 2 2 6
- 2 2 6 2 2 6 2 2 6 46 46 46
- 2 2 6 2 2 6 2 2 6 2 2 6
- 42 42 42 74 74 74 30 30 30 10 10 10
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 14 14 14 42 42 42 90 90 90
- 26 26 26 6 6 6 42 42 42 2 2 6
- 74 74 74 250 250 250 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 242 242 242 242 242 242
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 182 182 182 2 2 6
- 2 2 6 2 2 6 2 2 6 46 46 46
- 2 2 6 2 2 6 2 2 6 2 2 6
- 10 10 10 86 86 86 38 38 38 10 10 10
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 10 10 10 26 26 26 66 66 66 82 82 82
- 2 2 6 22 22 22 18 18 18 2 2 6
-149 149 149 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 234 234 234 242 242 242
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 206 206 206 2 2 6
- 2 2 6 2 2 6 2 2 6 38 38 38
- 2 2 6 2 2 6 2 2 6 2 2 6
- 6 6 6 86 86 86 46 46 46 14 14 14
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 18 18 18 46 46 46 86 86 86 18 18 18
- 2 2 6 34 34 34 10 10 10 6 6 6
-210 210 210 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 234 234 234 242 242 242
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 221 221 221 6 6 6
- 2 2 6 2 2 6 6 6 6 30 30 30
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 82 82 82 54 54 54 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 26 26 26 66 66 66 62 62 62 2 2 6
- 2 2 6 38 38 38 10 10 10 26 26 26
-238 238 238 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 238 238 238
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 6 6 6
- 2 2 6 2 2 6 10 10 10 30 30 30
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 66 66 66 58 58 58 22 22 22
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 38 38 38 78 78 78 6 6 6 2 2 6
- 2 2 6 46 46 46 14 14 14 42 42 42
-246 246 246 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 242 242 242
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 234 234 234 10 10 10
- 2 2 6 2 2 6 22 22 22 14 14 14
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 66 66 66 62 62 62 22 22 22
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 18 18 18
- 50 50 50 74 74 74 2 2 6 2 2 6
- 14 14 14 70 70 70 34 34 34 62 62 62
-250 250 250 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 246 246 246
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 234 234 234 14 14 14
- 2 2 6 2 2 6 30 30 30 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 66 66 66 62 62 62 22 22 22
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 18 18 18
- 54 54 54 62 62 62 2 2 6 2 2 6
- 2 2 6 30 30 30 46 46 46 70 70 70
-250 250 250 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 246 246 246
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 226 226 226 10 10 10
- 2 2 6 6 6 6 30 30 30 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 66 66 66 58 58 58 22 22 22
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 22 22 22
- 58 58 58 62 62 62 2 2 6 2 2 6
- 2 2 6 2 2 6 30 30 30 78 78 78
-250 250 250 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 246 246 246
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 206 206 206 2 2 6
- 22 22 22 34 34 34 18 14 6 22 22 22
- 26 26 26 18 18 18 6 6 6 2 2 6
- 2 2 6 82 82 82 54 54 54 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 26 26 26
- 62 62 62 106 106 106 74 54 14 185 133 11
-210 162 10 121 92 8 6 6 6 62 62 62
-238 238 238 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 246 246 246
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 158 158 158 18 18 18
- 14 14 14 2 2 6 2 2 6 2 2 6
- 6 6 6 18 18 18 66 66 66 38 38 38
- 6 6 6 94 94 94 50 50 50 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 10 10 10 10 10 10 18 18 18 38 38 38
- 78 78 78 142 134 106 216 158 10 242 186 14
-246 190 14 246 190 14 156 118 10 10 10 10
- 90 90 90 238 238 238 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 250 250 250
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 246 230 190
-238 204 91 238 204 91 181 142 44 37 26 9
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 38 38 38 46 46 46
- 26 26 26 106 106 106 54 54 54 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 6 6 6 14 14 14 22 22 22
- 30 30 30 38 38 38 50 50 50 70 70 70
-106 106 106 190 142 34 226 170 11 242 186 14
-246 190 14 246 190 14 246 190 14 154 114 10
- 6 6 6 74 74 74 226 226 226 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 231 231 231 250 250 250
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 228 184 62
-241 196 14 241 208 19 232 195 16 38 30 10
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 6 6 6 30 30 30 26 26 26
-203 166 17 154 142 90 66 66 66 26 26 26
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 18 18 18 38 38 38 58 58 58
- 78 78 78 86 86 86 101 101 101 123 123 123
-175 146 61 210 150 10 234 174 13 246 186 14
-246 190 14 246 190 14 246 190 14 238 190 10
-102 78 10 2 2 6 46 46 46 198 198 198
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 234 234 234 242 242 242
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 224 178 62
-242 186 14 241 196 14 210 166 10 22 18 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 6 6 6 121 92 8
-238 202 15 232 195 16 82 82 82 34 34 34
- 10 10 10 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 14 14 14 38 38 38 70 70 70 154 122 46
-190 142 34 200 144 11 197 138 11 197 138 11
-213 154 11 226 170 11 242 186 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-225 175 15 46 32 6 2 2 6 22 22 22
-158 158 158 250 250 250 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 250 250 250 242 242 242 224 178 62
-239 182 13 236 186 11 213 154 11 46 32 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 61 42 6 225 175 15
-238 190 10 236 186 11 112 100 78 42 42 42
- 14 14 14 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 22 22 22 54 54 54 154 122 46 213 154 11
-226 170 11 230 174 11 226 170 11 226 170 11
-236 178 12 242 186 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-241 196 14 184 144 12 10 10 10 2 2 6
- 6 6 6 116 116 116 242 242 242 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 231 231 231 198 198 198 214 170 54
-236 178 12 236 178 12 210 150 10 137 92 6
- 18 14 6 2 2 6 2 2 6 2 2 6
- 6 6 6 70 47 6 200 144 11 236 178 12
-239 182 13 239 182 13 124 112 88 58 58 58
- 22 22 22 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 30 30 30 70 70 70 180 133 36 226 170 11
-239 182 13 242 186 14 242 186 14 246 186 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 232 195 16 98 70 6 2 2 6
- 2 2 6 2 2 6 66 66 66 221 221 221
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 206 206 206 198 198 198 214 166 58
-230 174 11 230 174 11 216 158 10 192 133 9
-163 110 8 116 81 8 102 78 10 116 81 8
-167 114 7 197 138 11 226 170 11 239 182 13
-242 186 14 242 186 14 162 146 94 78 78 78
- 34 34 34 14 14 14 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 30 30 30 78 78 78 190 142 34 226 170 11
-239 182 13 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 241 196 14 203 166 17 22 18 6
- 2 2 6 2 2 6 2 2 6 38 38 38
-218 218 218 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-250 250 250 206 206 206 198 198 198 202 162 69
-226 170 11 236 178 12 224 166 10 210 150 10
-200 144 11 197 138 11 192 133 9 197 138 11
-210 150 10 226 170 11 242 186 14 246 190 14
-246 190 14 246 186 14 225 175 15 124 112 88
- 62 62 62 30 30 30 14 14 14 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 30 30 30 78 78 78 174 135 50 224 166 10
-239 182 13 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 241 196 14 139 102 15
- 2 2 6 2 2 6 2 2 6 2 2 6
- 78 78 78 250 250 250 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-250 250 250 214 214 214 198 198 198 190 150 46
-219 162 10 236 178 12 234 174 13 224 166 10
-216 158 10 213 154 11 213 154 11 216 158 10
-226 170 11 239 182 13 246 190 14 246 190 14
-246 190 14 246 190 14 242 186 14 206 162 42
-101 101 101 58 58 58 30 30 30 14 14 14
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 30 30 30 74 74 74 174 135 50 216 158 10
-236 178 12 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 241 196 14 226 184 13
- 61 42 6 2 2 6 2 2 6 2 2 6
- 22 22 22 238 238 238 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 226 226 226 187 187 187 180 133 36
-216 158 10 236 178 12 239 182 13 236 178 12
-230 174 11 226 170 11 226 170 11 230 174 11
-236 178 12 242 186 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 186 14 239 182 13
-206 162 42 106 106 106 66 66 66 34 34 34
- 14 14 14 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 26 26 26 70 70 70 163 133 67 213 154 11
-236 178 12 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 241 196 14
-190 146 13 18 14 6 2 2 6 2 2 6
- 46 46 46 246 246 246 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 221 221 221 86 86 86 156 107 11
-216 158 10 236 178 12 242 186 14 246 186 14
-242 186 14 239 182 13 239 182 13 242 186 14
-242 186 14 246 186 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-242 186 14 225 175 15 142 122 72 66 66 66
- 30 30 30 10 10 10 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 26 26 26 70 70 70 163 133 67 210 150 10
-236 178 12 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-232 195 16 121 92 8 34 34 34 106 106 106
-221 221 221 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-242 242 242 82 82 82 18 14 6 163 110 8
-216 158 10 236 178 12 242 186 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 242 186 14 163 133 67
- 46 46 46 18 18 18 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 10 10 10
- 30 30 30 78 78 78 163 133 67 210 150 10
-236 178 12 246 186 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-241 196 14 215 174 15 190 178 144 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 218 218 218
- 58 58 58 2 2 6 22 18 6 167 114 7
-216 158 10 236 178 12 246 186 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 186 14 242 186 14 190 150 46
- 54 54 54 22 22 22 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 38 38 38 86 86 86 180 133 36 213 154 11
-236 178 12 246 186 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 232 195 16 190 146 13 214 214 214
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 250 250 250 170 170 170 26 26 26
- 2 2 6 2 2 6 37 26 9 163 110 8
-219 162 10 239 182 13 246 186 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 186 14 236 178 12 224 166 10 142 122 72
- 46 46 46 18 18 18 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 18 18 18
- 50 50 50 109 106 95 192 133 9 224 166 10
-242 186 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-242 186 14 226 184 13 210 162 10 142 110 46
-226 226 226 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-253 253 253 253 253 253 253 253 253 253 253 253
-198 198 198 66 66 66 2 2 6 2 2 6
- 2 2 6 2 2 6 50 34 6 156 107 11
-219 162 10 239 182 13 246 186 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 242 186 14
-234 174 13 213 154 11 154 122 46 66 66 66
- 30 30 30 10 10 10 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 22 22 22
- 58 58 58 154 121 60 206 145 10 234 174 13
-242 186 14 246 186 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 186 14 236 178 12 210 162 10 163 110 8
- 61 42 6 138 138 138 218 218 218 250 250 250
-253 253 253 253 253 253 253 253 253 250 250 250
-242 242 242 210 210 210 144 144 144 66 66 66
- 6 6 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 61 42 6 163 110 8
-216 158 10 236 178 12 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 239 182 13 230 174 11 216 158 10
-190 142 34 124 112 88 70 70 70 38 38 38
- 18 18 18 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 22 22 22
- 62 62 62 168 124 44 206 145 10 224 166 10
-236 178 12 239 182 13 242 186 14 242 186 14
-246 186 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 236 178 12 216 158 10 175 118 6
- 80 54 7 2 2 6 6 6 6 30 30 30
- 54 54 54 62 62 62 50 50 50 38 38 38
- 14 14 14 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 6 6 6 80 54 7 167 114 7
-213 154 11 236 178 12 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 190 14 242 186 14 239 182 13 239 182 13
-230 174 11 210 150 10 174 135 50 124 112 88
- 82 82 82 54 54 54 34 34 34 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 18 18 18
- 50 50 50 158 118 36 192 133 9 200 144 11
-216 158 10 219 162 10 224 166 10 226 170 11
-230 174 11 236 178 12 239 182 13 239 182 13
-242 186 14 246 186 14 246 190 14 246 190 14
-246 190 14 246 190 14 246 190 14 246 190 14
-246 186 14 230 174 11 210 150 10 163 110 8
-104 69 6 10 10 10 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 6 6 6 91 60 6 167 114 7
-206 145 10 230 174 11 242 186 14 246 190 14
-246 190 14 246 190 14 246 186 14 242 186 14
-239 182 13 230 174 11 224 166 10 213 154 11
-180 133 36 124 112 88 86 86 86 58 58 58
- 38 38 38 22 22 22 10 10 10 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 14 14 14
- 34 34 34 70 70 70 138 110 50 158 118 36
-167 114 7 180 123 7 192 133 9 197 138 11
-200 144 11 206 145 10 213 154 11 219 162 10
-224 166 10 230 174 11 239 182 13 242 186 14
-246 186 14 246 186 14 246 186 14 246 186 14
-239 182 13 216 158 10 185 133 11 152 99 6
-104 69 6 18 14 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 2 2 6 2 2 6 2 2 6
- 2 2 6 6 6 6 80 54 7 152 99 6
-192 133 9 219 162 10 236 178 12 239 182 13
-246 186 14 242 186 14 239 182 13 236 178 12
-224 166 10 206 145 10 192 133 9 154 121 60
- 94 94 94 62 62 62 42 42 42 22 22 22
- 14 14 14 6 6 6 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 18 18 18 34 34 34 58 58 58 78 78 78
-101 98 89 124 112 88 142 110 46 156 107 11
-163 110 8 167 114 7 175 118 6 180 123 7
-185 133 11 197 138 11 210 150 10 219 162 10
-226 170 11 236 178 12 236 178 12 234 174 13
-219 162 10 197 138 11 163 110 8 130 83 6
- 91 60 6 10 10 10 2 2 6 2 2 6
- 18 18 18 38 38 38 38 38 38 38 38 38
- 38 38 38 38 38 38 38 38 38 38 38 38
- 38 38 38 38 38 38 26 26 26 2 2 6
- 2 2 6 6 6 6 70 47 6 137 92 6
-175 118 6 200 144 11 219 162 10 230 174 11
-234 174 13 230 174 11 219 162 10 210 150 10
-192 133 9 163 110 8 124 112 88 82 82 82
- 50 50 50 30 30 30 14 14 14 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 14 14 14 22 22 22 34 34 34
- 42 42 42 58 58 58 74 74 74 86 86 86
-101 98 89 122 102 70 130 98 46 121 87 25
-137 92 6 152 99 6 163 110 8 180 123 7
-185 133 11 197 138 11 206 145 10 200 144 11
-180 123 7 156 107 11 130 83 6 104 69 6
- 50 34 6 54 54 54 110 110 110 101 98 89
- 86 86 86 82 82 82 78 78 78 78 78 78
- 78 78 78 78 78 78 78 78 78 78 78 78
- 78 78 78 82 82 82 86 86 86 94 94 94
-106 106 106 101 101 101 86 66 34 124 80 6
-156 107 11 180 123 7 192 133 9 200 144 11
-206 145 10 200 144 11 192 133 9 175 118 6
-139 102 15 109 106 95 70 70 70 42 42 42
- 22 22 22 10 10 10 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 6 6 6 10 10 10
- 14 14 14 22 22 22 30 30 30 38 38 38
- 50 50 50 62 62 62 74 74 74 90 90 90
-101 98 89 112 100 78 121 87 25 124 80 6
-137 92 6 152 99 6 152 99 6 152 99 6
-138 86 6 124 80 6 98 70 6 86 66 30
-101 98 89 82 82 82 58 58 58 46 46 46
- 38 38 38 34 34 34 34 34 34 34 34 34
- 34 34 34 34 34 34 34 34 34 34 34 34
- 34 34 34 34 34 34 38 38 38 42 42 42
- 54 54 54 82 82 82 94 86 76 91 60 6
-134 86 6 156 107 11 167 114 7 175 118 6
-175 118 6 167 114 7 152 99 6 121 87 25
-101 98 89 62 62 62 34 34 34 18 18 18
- 6 6 6 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 6 6 6 6 6 6 10 10 10
- 18 18 18 22 22 22 30 30 30 42 42 42
- 50 50 50 66 66 66 86 86 86 101 98 89
-106 86 58 98 70 6 104 69 6 104 69 6
-104 69 6 91 60 6 82 62 34 90 90 90
- 62 62 62 38 38 38 22 22 22 14 14 14
- 10 10 10 10 10 10 10 10 10 10 10 10
- 10 10 10 10 10 10 6 6 6 10 10 10
- 10 10 10 10 10 10 10 10 10 14 14 14
- 22 22 22 42 42 42 70 70 70 89 81 66
- 80 54 7 104 69 6 124 80 6 137 92 6
-134 86 6 116 81 8 100 82 52 86 86 86
- 58 58 58 30 30 30 14 14 14 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 6 6 6 10 10 10 14 14 14
- 18 18 18 26 26 26 38 38 38 54 54 54
- 70 70 70 86 86 86 94 86 76 89 81 66
- 89 81 66 86 86 86 74 74 74 50 50 50
- 30 30 30 14 14 14 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 18 18 18 34 34 34 58 58 58
- 82 82 82 89 81 66 89 81 66 89 81 66
- 94 86 66 94 86 76 74 74 74 50 50 50
- 26 26 26 14 14 14 6 6 6 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 6 6 6 6 6 6 14 14 14 18 18 18
- 30 30 30 38 38 38 46 46 46 54 54 54
- 50 50 50 42 42 42 30 30 30 18 18 18
- 10 10 10 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 6 6 6 14 14 14 26 26 26
- 38 38 38 50 50 50 58 58 58 58 58 58
- 54 54 54 42 42 42 30 30 30 18 18 18
- 10 10 10 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 6 6 6 10 10 10 14 14 14 18 18 18
- 18 18 18 14 14 14 10 10 10 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 6 6 6
- 14 14 14 18 18 18 22 22 22 22 22 22
- 18 18 18 14 14 14 10 10 10 6 6 6
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 3 4 4 6 7 7
+8 10 10 8 10 10 6 8 8 6 7 7 3 4 4 2 2 2
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 4 5 5 17 18 17
+27 29 28 35 37 36 40 43 41 43 45 43 40 43 41 37 39 37
+32 34 33 27 30 29 23 25 24 17 21 21 15 18 18 12 15 15
+11 13 13 8 10 10 6 7 7 3 4 4 1 1 1 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 13 13 13 32 34 33 49 51 48 60 60 56 58 59 55
+55 57 54 55 56 53 49 51 48 43 45 43 39 40 39 33 37 35
+28 31 30 23 27 26 20 23 23 17 20 20 14 17 17 13 16 16
+11 14 14 10 13 13 10 12 12 9 11 11 8 10 10 6 7 7
+2 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 6 7 7 12 15 15
+12 15 15 8 9 9 2 3 3 0 0 0 1 1 1 25 27 26
+55 56 53 68 70 65 65 66 61 65 66 61 63 64 60 63 64 60
+58 59 55 51 52 50 47 48 46 41 42 42 35 37 36 30 32 31
+26 28 27 20 24 24 18 22 22 16 19 19 14 17 17 13 16 16
+12 15 15 11 14 14 10 13 13 10 12 12 9 11 11 8 10 10
+8 9 9 6 8 8 3 3 3 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 6 7 7 20 24 24 23 27 26
+23 27 26 18 22 22 11 13 13 23 24 24 61 63 57 72 73 67
+72 73 67 68 70 65 68 70 65 68 70 65 63 64 60 58 59 55
+55 56 53 47 48 46 41 42 42 35 37 36 30 32 31 26 28 27
+20 24 24 18 22 22 16 20 20 15 19 19 14 17 17 13 16 16
+12 15 15 12 15 15 11 14 14 10 13 13 10 12 12 9 11 11
+8 10 10 8 9 9 7 9 9 6 7 7 1 2 2 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 4 5 5 5 6 5 4 5 5
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 15 19 19 40 41 39 53 55 47
+33 36 34 27 30 29 51 52 50 72 73 67 72 73 67 72 73 67
+72 73 67 68 70 65 68 70 65 63 64 60 58 59 55 51 52 50
+47 48 46 40 43 41 33 37 35 30 32 31 26 28 27 20 24 24
+18 22 22 17 21 21 16 19 19 14 18 18 14 17 17 13 17 17
+13 16 16 12 15 15 12 15 15 11 14 14 10 13 13 10 12 12
+9 11 11 8 10 10 8 9 9 7 9 9 6 8 8 3 4 4
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+2 2 2 6 8 8 10 12 12 10 12 12 10 12 12 10 12 12
+6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 20 23 23 71 71 57 131 127 93
+115 113 82 63 64 60 72 73 67 72 73 67 72 73 67 72 73 67
+68 70 65 65 66 61 61 63 57 55 57 54 49 51 48 43 45 43
+39 40 39 33 36 34 28 31 30 23 27 26 20 24 24 20 23 23
+17 21 21 16 20 20 15 19 19 15 18 18 14 18 18 14 17 17
+13 17 17 13 16 16 12 15 15 12 15 15 11 14 14 10 13 13
+10 12 12 9 11 11 8 10 10 7 9 9 7 9 9 6 8 8
+4 5 5 0 0 0 0 0 0 0 0 0 1 1 1 6 7 7
+10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12
+10 12 12 3 4 4 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 18 22 22 71 71 57 144 139 99
+84 83 72 68 70 65 72 73 67 72 73 67 68 70 65 65 66 61
+63 64 60 55 57 54 51 52 50 47 48 46 40 43 41 35 37 36
+30 32 31 27 29 28 23 27 26 20 24 24 18 22 22 17 21 21
+16 20 20 15 19 19 15 19 19 15 19 19 15 18 18 14 18 18
+14 17 17 13 17 17 13 16 16 12 15 15 12 15 15 11 14 14
+10 13 13 9 12 12 9 11 11 8 10 10 7 9 9 6 8 8
+6 8 8 3 4 4 0 0 0 2 2 2 8 10 10 10 12 12
+10 12 12 10 12 12 11 13 13 36 38 35 61 61 53 48 49 45
+10 12 12 7 9 9 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 15 19 19 61 61 53 84 83 72
+68 70 65 72 73 67 68 70 65 68 70 65 63 64 60 58 59 55
+51 52 50 47 48 46 41 42 42 37 39 37 32 35 33 28 31 30
+23 27 26 20 24 24 20 23 23 18 22 22 17 21 21 17 21 21
+17 21 21 17 21 21 17 20 20 16 20 20 16 20 20 16 19 19
+15 18 18 14 18 18 13 17 17 13 16 16 12 15 15 12 15 15
+11 14 14 10 13 13 9 12 12 9 11 11 8 10 10 7 9 9
+6 8 8 6 8 8 5 6 5 9 11 11 10 12 12 10 12 12
+19 20 18 82 81 62 149 145 103 160 154 106 142 137 94 96 95 69
+10 12 12 10 12 12 1 1 1 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 10 12 12 44 46 43 68 70 65
+72 73 67 68 70 65 68 70 65 63 64 60 55 57 54 49 51 48
+43 45 43 39 40 39 33 37 35 30 32 31 26 28 27 23 27 26
+20 24 24 18 22 22 18 22 22 18 22 22 18 22 22 20 23 23
+20 24 24 23 25 24 23 25 24 22 24 23 20 23 23 18 22 22
+17 20 20 15 19 19 15 18 18 14 17 17 13 16 16 12 15 15
+11 14 14 11 13 13 10 12 12 9 11 11 8 10 10 8 9 9
+7 9 9 7 9 9 10 12 12 10 12 12 10 12 12 71 71 57
+164 159 111 186 182 128 186 182 128 171 165 117 151 147 98 96 95 69
+10 12 12 10 12 12 3 3 3 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 8 10 10 63 64 60 68 70 65
+72 73 67 68 70 65 63 64 60 55 57 54 47 48 46 40 43 41
+33 37 35 30 32 31 27 29 28 23 27 26 20 24 24 20 23 23
+18 22 22 18 22 22 20 23 22 21 25 23 23 27 26 27 29 28
+28 31 30 31 33 31 31 33 31 31 33 31 28 31 30 26 28 27
+23 25 24 20 23 22 16 20 20 15 18 18 14 17 17 13 16 16
+12 15 15 11 14 14 10 13 13 10 12 12 9 11 11 8 10 10
+10 12 12 10 13 13 10 12 12 12 14 14 96 95 69 165 161 109
+186 182 128 192 187 134 192 187 134 176 171 126 160 154 106 103 101 77
+10 12 12 10 12 12 5 6 5 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 35 37 36 68 70 65 72 73 67
+68 70 65 65 66 61 58 59 55 49 51 48 40 43 41 33 37 35
+28 31 30 23 27 26 20 24 24 20 23 23 18 22 22 18 22 22
+18 22 22 20 23 23 23 27 26 27 30 29 32 35 33 37 39 37
+40 43 41 44 46 43 46 47 43 44 46 43 40 43 41 36 38 35
+31 33 31 27 29 28 22 24 23 17 21 21 15 18 18 14 17 17
+13 16 16 12 15 15 11 14 14 11 14 14 11 13 13 13 16 16
+13 16 16 11 14 14 10 12 12 79 78 62 142 137 94 164 159 111
+178 174 128 192 187 134 192 187 134 176 171 126 160 154 106 96 95 69
+10 12 12 10 12 12 6 7 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 55 57 54 68 70 65 72 73 67
+68 70 65 63 64 60 55 56 53 43 45 43 35 37 36 28 31 30
+23 27 26 20 24 24 18 22 22 17 21 21 17 21 21 17 21 21
+20 24 24 25 27 26 31 33 31 38 39 37 46 47 43 53 55 47
+61 61 53 66 65 55 66 65 55 66 65 55 61 61 53 53 55 47
+46 47 43 37 39 37 30 33 30 24 26 24 17 21 21 15 18 18
+13 17 17 12 15 15 12 15 15 13 16 16 14 18 18 14 18 18
+14 17 17 12 15 15 30 31 28 118 116 76 134 131 96 160 154 106
+174 170 121 178 174 128 178 174 128 171 165 117 151 147 98 96 95 69
+10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 63 64 60 68 70 65 68 70 65
+65 66 61 58 59 55 49 51 48 39 40 39 30 32 31 23 27 26
+20 24 24 18 22 22 17 21 21 16 20 20 17 21 21 20 23 23
+25 27 26 32 35 33 43 44 41 53 55 47 66 65 55 75 75 61
+82 81 62 84 83 72 87 86 72 87 86 72 82 81 62 75 75 61
+66 65 55 53 55 47 40 41 39 31 33 31 23 25 24 17 20 20
+14 18 18 13 16 16 12 15 15 12 15 15 13 17 17 14 18 18
+14 18 18 13 16 16 46 47 43 96 95 69 125 122 87 142 137 94
+160 154 106 165 161 109 164 159 111 155 149 109 142 137 94 75 75 61
+10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 60 60 56 68 70 65 68 70 65
+63 64 60 55 57 54 46 47 45 35 37 36 27 30 29 23 25 24
+18 22 22 17 21 21 16 20 20 17 21 21 18 22 22 23 27 26
+31 33 31 43 44 41 55 56 53 71 71 57 84 83 72 92 91 72
+103 101 77 92 91 72 82 81 62 82 81 62 87 86 72 92 91 72
+84 83 72 71 71 57 55 56 53 43 44 41 30 33 30 22 24 23
+16 19 19 14 17 17 12 15 15 12 15 15 13 16 16 14 18 18
+14 18 18 14 17 17 43 44 41 82 81 62 118 116 76 125 122 87
+142 137 94 144 139 99 144 139 99 134 131 96 118 116 76 53 55 47
+10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 47 48 46 63 64 60 63 64 60
+55 57 54 49 51 48 40 43 41 32 34 33 26 28 27 20 24 24
+18 22 22 16 20 20 16 20 20 17 21 21 20 24 24 28 31 30
+40 41 39 53 55 47 75 75 61 90 89 73 87 86 72 48 49 45
+14 14 13 2 2 2 1 2 2 1 1 1 1 1 1 2 2 2
+19 20 18 43 44 41 66 65 55 53 55 47 38 39 37 26 28 27
+18 22 22 14 18 18 13 16 16 12 15 15 12 15 15 13 17 17
+14 18 18 14 18 18 30 31 28 66 65 55 96 95 69 103 101 77
+118 116 76 118 116 76 118 116 76 118 116 76 103 101 77 36 38 35
+10 12 12 10 12 12 6 7 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 28 31 30 55 57 54 51 52 50
+49 51 48 41 42 42 35 37 36 28 31 30 23 27 26 20 23 23
+17 21 21 16 20 20 16 20 20 18 22 22 23 27 26 33 36 34
+48 49 45 71 71 57 82 81 62 43 44 41 8 9 9 6 7 7
+6 7 7 6 7 7 6 7 7 5 6 5 4 5 5 3 4 4
+2 3 3 1 2 2 4 5 4 36 38 35 48 49 45 32 35 33
+21 25 23 16 19 19 13 17 17 12 15 15 12 15 15 13 16 16
+14 18 18 14 18 18 16 18 16 36 38 35 61 61 53 82 81 62
+96 95 69 96 95 69 96 95 69 96 95 69 79 78 62 19 20 18
+10 12 12 10 12 12 4 5 5 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 13 13 13 46 47 45 43 45 43
+40 43 41 35 37 36 30 32 31 23 27 26 20 24 24 18 22 22
+17 21 21 16 20 20 17 21 21 20 23 23 27 30 29 40 41 39
+61 61 53 53 55 47 16 17 16 9 11 11 10 12 12 10 12 12
+10 12 12 10 12 12 10 12 12 9 11 11 8 10 10 8 9 9
+6 8 8 5 6 5 4 5 5 2 3 3 19 20 18 38 39 37
+26 28 27 17 21 21 14 17 17 13 16 16 12 15 15 12 15 15
+13 17 17 14 18 18 12 15 15 13 12 7 30 31 28 46 47 43
+53 55 47 66 65 55 66 65 55 53 55 47 36 38 35 10 12 12
+10 12 12 10 12 12 2 3 3 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 1 1 1 33 37 35 35 37 36
+32 35 33 28 31 30 23 27 26 20 24 24 18 22 22 17 21 21
+16 20 20 16 20 20 17 21 21 21 25 23 31 33 31 44 46 43
+31 33 31 11 13 13 12 14 14 12 15 15 13 16 16 14 17 17
+14 17 17 14 17 17 14 17 17 13 16 16 12 15 15 12 14 14
+11 13 13 9 11 11 8 10 10 6 8 8 4 5 5 17 18 17
+30 33 30 20 23 22 15 18 18 13 16 16 12 15 15 12 14 14
+13 16 16 14 17 17 14 18 18 11 12 11 7 7 5 16 17 12
+21 22 20 30 31 28 25 27 25 21 22 20 14 14 13 10 12 12
+10 12 12 9 11 11 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 18 22 22 27 30 29
+27 29 28 40 41 39 53 55 47 53 55 47 53 55 47 46 47 43
+25 27 25 16 20 20 17 21 21 23 25 24 31 33 31 20 20 20
+12 15 15 14 17 17 15 19 19 16 20 20 17 21 21 18 22 22
+18 22 22 18 22 22 18 22 22 17 21 21 17 21 21 16 19 19
+15 18 18 13 16 16 12 15 15 10 12 12 8 10 10 6 8 8
+21 22 21 22 24 23 15 19 19 13 17 17 13 16 16 12 15 15
+12 15 15 13 17 17 14 18 18 14 18 18 13 15 14 10 9 6
+7 7 5 7 7 5 7 7 5 9 11 11 10 12 12 10 12 12
+10 12 12 6 7 7 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 16 17 12 82 81 62
+118 116 76 118 116 76 161 156 96 161 156 96 161 156 96 118 116 76
+118 116 76 96 95 69 53 55 47 22 24 23 14 17 17 13 16 16
+15 19 19 17 21 21 18 22 22 20 24 24 20 24 24 23 27 26
+23 27 26 23 27 26 23 27 26 23 27 26 23 27 26 20 24 24
+20 23 23 17 21 21 16 19 19 14 17 17 12 15 15 10 12 12
+9 11 11 20 23 22 16 19 19 14 17 17 13 16 16 12 15 15
+11 14 14 13 16 16 14 17 17 14 18 18 14 17 17 12 15 15
+10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12
+9 11 11 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 53 55 47 161 156 96
+161 156 96 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 161 156 96 118 116 76 96 95 69 21 22 20 16 19 19
+18 22 22 20 24 24 23 27 26 23 27 26 26 28 27 27 30 29
+27 30 29 18 22 22 12 14 14 8 10 10 9 11 11 17 21 21
+23 27 26 23 27 26 20 24 24 18 22 22 16 20 20 14 17 17
+12 14 14 14 17 17 16 20 20 14 17 17 13 17 17 13 16 16
+12 15 15 12 15 15 13 17 17 14 18 18 14 17 17 13 16 16
+11 13 13 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12
+4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 13 12 7 118 116 76 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 161 156 96 118 116 76 30 31 28
+20 24 24 23 27 26 27 30 29 28 31 30 30 32 31 23 27 26
+16 19 19 17 21 21 12 15 15 9 11 11 10 12 12 9 11 11
+20 24 24 28 31 30 26 28 27 23 27 26 20 24 24 17 21 21
+15 19 19 13 16 16 16 19 19 14 18 18 14 17 17 13 16 16
+12 15 15 11 14 14 13 16 16 14 17 17 14 18 18 14 17 17
+12 15 15 10 12 12 10 12 12 10 12 12 10 12 12 8 9 9
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 82 81 62 161 156 96 230 229 82
+230 229 82 233 233 100 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 118 116 76
+27 29 28 27 30 29 30 32 31 30 32 31 23 27 26 20 24 24
+26 28 27 17 21 21 6 7 7 72 73 67 145 141 105 15 15 15
+14 17 17 33 37 35 30 32 31 28 31 30 26 28 27 23 27 26
+20 23 23 16 20 20 15 19 19 14 18 18 14 17 17 13 16 16
+12 15 15 11 14 14 12 15 15 13 17 17 14 18 18 14 17 17
+13 16 16 11 13 13 10 12 12 10 12 12 9 11 11 1 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 16 17 12 161 156 96 230 229 82 230 229 82
+243 242 120 235 234 117 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96
+82 81 62 28 31 30 28 31 30 27 30 29 28 31 30 30 32 31
+33 37 35 13 16 16 3 3 3 105 104 92 210 208 158 12 14 14
+17 21 21 33 37 35 33 37 35 32 35 33 30 32 31 27 30 29
+23 27 26 20 23 23 17 20 20 15 18 18 14 18 18 13 17 17
+13 16 16 12 15 15 11 14 14 13 16 16 14 17 17 14 18 18
+13 17 17 12 15 15 10 12 12 10 12 12 3 4 4 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 96 95 69 230 229 82 230 229 82 244 244 132
+241 241 143 243 242 120 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+161 156 96 46 47 43 32 35 33 33 37 35 33 37 35 33 37 35
+40 43 41 23 27 26 1 1 1 2 2 2 24 26 24 14 17 17
+23 27 26 33 37 35 33 37 35 33 37 35 33 37 35 30 32 31
+27 30 29 23 27 26 20 23 23 15 18 18 14 18 18 14 17 17
+13 16 16 12 15 15 11 14 14 12 15 15 13 17 17 14 17 17
+14 17 17 13 16 16 11 13 13 6 8 8 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 16 17 12 161 156 96 230 229 82 235 234 117 239 239 170
+239 239 170 236 236 101 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 118 116 76 33 37 35 33 37 35 37 39 37 37 39 37
+43 45 43 49 51 48 20 24 24 8 10 10 17 20 20 35 37 36
+33 37 35 40 43 41 37 39 37 35 37 36 33 37 35 33 37 35
+30 32 31 27 30 29 23 27 26 15 19 19 14 18 18 14 17 17
+13 17 17 13 16 16 12 15 15 11 14 14 13 16 16 14 17 17
+14 17 17 13 17 17 11 14 14 4 5 5 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 96 95 69 230 229 82 230 229 82 239 239 170 251 251 187
+241 241 143 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 161 156 96 36 38 35 33 37 35 33 37 35 33 37 35
+37 39 37 47 48 46 55 57 54 55 57 54 49 51 48 43 45 43
+43 45 43 43 45 43 40 43 41 40 43 41 37 39 37 33 37 35
+33 37 35 28 31 30 26 28 27 16 20 20 15 18 18 14 18 18
+14 17 17 13 16 16 12 15 15 11 14 14 12 15 15 13 17 17
+14 17 17 14 17 17 8 10 10 5 7 7 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+16 17 12 230 229 82 230 229 82 243 242 120 251 251 187 251 251 187
+246 246 123 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 66 65 55 30 32 31 32 35 33 33 37 35
+33 37 35 37 39 37 40 43 41 47 48 46 49 51 48 51 52 50
+55 57 54 55 57 54 51 52 50 47 48 46 43 45 43 39 40 39
+33 37 35 30 32 31 26 28 27 17 21 21 15 19 19 14 18 18
+14 17 17 13 16 16 12 15 15 12 14 14 11 14 14 13 16 16
+14 17 17 12 15 15 7 9 9 6 8 8 1 1 1 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+96 95 69 230 229 82 230 229 82 239 239 170 251 251 187 239 239 170
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 96 95 69 27 30 29 28 31 30 30 32 31
+33 37 35 40 43 41 46 47 45 55 57 54 63 64 60 72 73 67
+72 73 67 72 73 67 72 73 67 65 66 61 55 57 54 47 48 46
+39 40 39 32 35 33 27 30 29 17 21 21 15 19 19 15 18 18
+14 18 18 13 17 17 13 16 16 12 15 15 11 14 14 12 14 14
+13 16 16 9 11 11 7 9 9 9 11 11 66 65 55 115 113 82
+21 22 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 12 7
+230 229 82 230 229 82 236 236 101 251 251 187 251 251 187 246 246 123
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 118 116 76 23 27 26 26 28 27 32 35 33
+51 52 50 90 89 73 110 109 94 145 141 105 168 163 120 177 172 135
+177 172 135 188 184 146 188 184 146 181 176 137 194 191 148 188 184 146
+184 179 149 188 184 146 188 184 146 156 151 111 177 172 135 181 176 137
+177 172 135 168 163 120 168 163 120 158 153 112 156 151 111 158 153 112
+156 151 111 158 153 112 177 172 135 188 184 146 188 184 146 194 189 146
+36 38 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 82 81 62
+230 229 82 230 229 82 244 244 132 251 251 187 244 244 132 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 82 81 62
+96 95 69 230 229 82 181 178 103 110 109 94 156 151 111 188 184 146
+188 184 146 197 193 154 188 184 146 184 181 136 188 184 146 168 163 120
+168 163 120 178 174 128 156 151 111 158 153 112 174 170 121 156 151 111
+156 151 111 158 153 112 156 151 111 168 163 120 178 174 128 181 176 137
+176 171 126 178 174 128 184 181 136 176 171 126 178 174 128 184 181 136
+176 171 126 178 174 128 184 181 136 164 159 111 155 149 109 96 95 69
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 161 156 96
+230 229 82 230 229 82 244 244 132 244 244 132 236 236 101 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 46 47 43 82 81 62
+158 153 112 197 193 154 194 189 146 184 181 136 188 184 146 168 163 120
+156 151 111 137 133 100 131 127 93 137 133 100 137 133 100 158 153 112
+121 119 87 137 133 100 156 151 111 145 141 105 99 98 80 84 83 72
+63 64 60 52 53 49 40 43 41 33 36 34 36 38 35 36 38 35
+38 39 37 43 44 41 43 44 41 46 47 43 48 49 45 48 49 45
+46 47 43 36 38 35 30 31 28 19 20 18 6 7 7 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 36 38 35 230 229 82
+230 229 82 230 229 82 246 246 123 236 236 101 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 53 55 47 121 119 87
+176 171 126 171 165 117 161 156 96 82 81 62 53 55 47 33 37 35
+39 40 39 63 64 60 99 98 80 121 119 87 137 133 100 177 172 135
+176 171 126 184 181 136 131 127 93 131 127 93 110 109 94 84 83 72
+51 52 50 39 40 39 27 29 28 18 22 22 16 19 19 15 19 19
+15 19 19 14 18 18 14 17 17 13 16 16 12 15 15 11 14 14
+10 13 13 9 12 12 9 11 11 8 9 9 7 9 9 1 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 118 116 76 230 229 82
+230 229 82 230 229 82 236 236 101 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 96 95 69 71 71 57
+36 38 35 118 116 76 118 116 76 12 15 15 15 18 18 20 24 24
+33 37 35 55 56 53 84 83 72 110 109 94 145 141 105 110 109 94
+168 163 120 121 119 87 156 151 111 131 127 93 87 86 72 61 63 57
+47 48 46 28 31 30 18 22 22 15 19 19 15 18 18 15 19 19
+15 19 19 14 18 18 14 17 17 13 17 17 13 16 16 12 15 15
+11 13 13 10 12 12 9 11 11 8 10 10 7 9 9 3 3 3
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 1 1 0 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96
+161 156 96 230 229 82 118 116 76 11 14 14 14 17 17 18 22 22
+27 30 29 40 43 41 60 60 56 84 83 72 105 104 92 110 109 94
+110 109 94 110 109 94 99 98 80 90 89 73 68 70 65 47 48 46
+32 34 33 23 25 24 20 23 23 17 21 21 15 19 19 14 17 17
+15 19 19 15 18 18 14 18 18 13 17 17 13 16 16 12 15 15
+11 14 14 10 12 12 9 11 11 8 10 10 7 9 9 4 5 5
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 16 17 12 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 161 156 96 118 116 76 11 13 13 13 16 16 15 19 19
+20 24 24 30 32 31 40 43 41 51 52 50 63 64 60 72 73 67
+65 66 61 65 66 61 65 66 61 55 57 54 46 47 45 33 37 35
+27 29 28 20 24 24 17 21 21 16 20 20 16 20 20 15 19 19
+15 19 19 15 19 19 14 18 18 14 17 17 13 16 16 12 15 15
+11 14 14 10 13 13 9 12 12 8 10 10 7 9 9 6 7 7
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 53 55 47 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+161 156 96 118 116 76 53 55 47 10 13 13 12 15 15 14 17 17
+17 20 20 20 24 24 27 29 28 32 34 33 37 39 37 40 43 41
+43 45 43 41 42 42 35 37 36 30 32 31 28 31 30 23 27 26
+20 23 23 17 21 21 16 20 20 16 20 20 16 20 20 16 19 19
+15 19 19 15 19 19 14 18 18 14 17 17 13 16 16 12 15 15
+11 14 14 10 13 13 9 12 12 9 11 11 8 10 10 10 12 12
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 82 81 62 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 161 156 96
+118 116 76 82 81 62 13 14 12 10 13 13 12 15 15 13 17 17
+15 19 19 16 20 20 20 23 23 20 24 24 23 27 26 26 28 27
+26 28 27 26 28 27 23 27 26 18 22 22 20 23 23 17 21 21
+17 21 21 16 20 20 16 20 20 16 20 20 16 20 20 16 19 19
+15 19 19 15 19 19 15 18 18 14 17 17 13 17 17 13 16 16
+12 15 15 12 14 14 12 14 14 12 14 14 12 14 14 23 24 24
+6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 161 156 96 161 156 96 118 116 76
+71 71 57 13 14 12 9 12 12 10 13 13 12 15 15 13 17 17
+15 18 18 15 19 19 16 20 20 17 21 21 17 21 21 18 22 22
+18 22 22 18 22 22 17 21 21 16 19 19 15 18 18 14 18 18
+16 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+15 19 19 15 19 19 15 18 18 14 18 18 16 20 20 23 25 24
+17 21 21 25 27 26 47 48 46 47 48 46 51 52 50 72 73 67
+33 36 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 161 156 96 118 116 76 118 116 76 46 47 43
+9 11 11 9 11 11 10 12 12 11 13 13 12 15 15 14 17 17
+15 18 18 15 19 19 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+15 19 19 16 20 20 20 24 24 55 56 53 32 34 33 84 83 72
+90 89 73 110 109 94 110 109 94 105 104 92 110 109 94 110 109 94
+72 73 67 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 96 95 69 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 161 156 96 118 116 76 82 81 62 16 17 12 9 11 11
+9 11 11 9 12 12 10 13 13 12 14 14 13 16 16 14 18 18
+15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 19 19 33 36 34 99 98 80 156 151 111 145 141 105 184 179 149
+168 163 120 184 179 149 177 172 135 156 151 111 145 141 105 110 109 94
+90 89 73 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 71 71 57 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82
+230 229 82 161 156 96 230 229 82 230 229 82 230 229 82 161 156 96
+118 116 76 82 81 62 30 31 28 9 11 11 9 11 11 9 11 11
+10 12 12 10 13 13 11 14 14 13 16 16 14 17 17 15 18 18
+15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+18 22 22 58 59 55 137 133 100 197 193 154 214 212 158 210 208 158
+197 193 154 184 179 149 184 179 149 137 133 100 110 109 94 99 98 80
+84 83 72 10 10 9 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 16 17 12 230 229 82 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96
+161 156 96 161 156 96 161 156 96 161 156 96 118 116 76 71 71 57
+21 22 20 12 14 14 11 13 13 10 12 12 10 12 12 10 13 13
+11 13 13 12 15 15 13 16 16 14 17 17 14 18 18 15 19 19
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 17 21 21
+23 27 26 84 83 72 184 179 149 251 251 187 210 208 158 184 179 149
+184 179 149 156 151 111 110 109 94 84 83 72 63 64 60 51 52 50
+18 22 22 6 8 8 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 118 116 76 230 229 82
+230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 161 156 96
+161 156 96 161 156 96 118 116 76 53 55 47 20 23 22 16 19 19
+13 16 16 12 15 15 12 14 14 11 14 14 11 14 14 11 14 14
+12 15 15 13 16 16 14 17 17 15 19 19 16 20 20 17 21 21
+23 27 26 18 22 22 20 24 24 23 27 26 30 32 31 17 21 21
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+23 27 26 33 37 35 137 133 100 156 151 111 158 153 112 105 104 92
+105 104 92 68 70 65 39 40 39 18 22 22 12 14 14 12 15 15
+9 11 11 4 5 5 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 16 17 12 230 229 82
+230 229 82 230 229 82 230 229 82 161 156 96 118 116 76 118 116 76
+118 116 76 66 65 55 43 45 43 32 34 33 25 27 26 20 23 22
+17 20 20 15 18 18 14 17 17 15 18 18 13 16 16 14 17 17
+14 18 18 16 20 20 32 34 33 55 57 54 58 59 55 72 73 67
+105 104 92 55 57 54 65 66 61 63 64 60 40 43 41 33 37 35
+41 42 42 20 24 24 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+17 21 21 26 28 27 30 32 31 35 37 36 68 70 65 39 40 39
+23 27 26 15 18 18 13 16 16 11 14 14 9 12 12 8 10 10
+7 9 9 6 7 7 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 38 35
+230 229 82 230 229 82 230 229 82 96 95 69 30 31 28 49 51 48
+90 89 73 68 70 65 55 57 54 47 48 46 47 48 46 43 45 43
+32 34 33 43 45 43 43 45 43 23 27 26 25 27 26 40 43 41
+40 43 41 90 89 73 110 109 94 145 141 105 156 151 111 156 151 111
+184 179 149 184 179 149 177 172 135 184 179 149 137 133 100 84 83 72
+105 104 92 63 64 60 49 51 48 47 48 46 28 31 30 18 22 22
+16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 15 19 19 15 19 19 15 19 19 18 22 22 15 19 19
+13 16 16 12 15 15 11 14 14 10 13 13 9 12 12 9 11 11
+8 10 10 6 8 8 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+30 31 28 230 229 82 71 71 57 2 2 1 0 0 0 58 59 55
+105 104 92 84 83 72 65 66 61 84 83 72 110 109 94 110 109 94
+145 141 105 105 104 92 110 109 94 110 109 94 84 83 72 110 109 94
+158 153 112 197 193 154 197 193 154 239 239 170 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 197 193 154
+197 193 154 184 179 149 145 141 105 137 133 100 105 104 92 47 48 46
+20 23 23 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 19 19 15 19 19 15 19 19 14 18 18 14 17 17
+13 17 17 13 16 16 12 14 14 12 14 14 13 13 13 13 13 13
+13 13 13 12 12 12 10 10 9 6 7 7 2 2 2 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 65 66 61
+105 104 92 84 83 72 84 83 72 110 109 94 184 179 149 210 208 158
+210 208 158 210 208 158 214 212 158 197 193 154 214 212 158 210 208 158
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 251 251 187 239 239 170 251 251 187 184 179 149 84 83 72
+26 28 27 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 15 19 19 15 19 19 15 18 18 14 18 18
+13 17 17 13 16 16 15 15 15 14 14 13 14 14 13 14 14 13
+13 13 13 13 13 13 12 12 12 12 12 12 12 12 12 3 4 4
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 72 73 67
+105 104 92 99 98 80 84 83 72 99 98 80 177 172 135 197 193 154
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 214 212 158 197 193 154 99 98 80
+23 27 26 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 15 19 19 15 19 19 15 18 18 14 18 18
+14 17 17 16 16 16 16 16 16 16 16 16 15 15 15 14 14 13
+14 14 13 13 13 13 13 13 13 12 12 12 12 12 12 12 12 12
+3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 84 83 72
+110 109 94 99 98 80 72 73 67 63 64 60 99 98 80 177 172 135
+184 179 149 210 208 158 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 210 208 158 184 179 149 177 172 135 110 109 94 33 37 35
+17 21 21 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+16 20 20 16 20 20 15 19 19 15 19 19 15 19 19 14 18 18
+15 18 18 18 19 18 18 19 18 17 17 17 16 16 16 15 15 15
+14 14 13 13 13 13 13 13 13 12 12 12 12 12 12 12 12 12
+10 10 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 105 104 92
+108 107 93 99 98 80 72 73 67 63 64 60 51 52 50 87 86 72
+105 104 92 110 109 94 108 107 93 156 151 111 184 179 149 184 179 149
+197 193 154 197 193 154 197 193 154 184 179 149 184 179 149 177 172 135
+197 193 154 156 151 111 177 172 135 184 179 149 168 163 120 137 133 100
+145 141 105 110 109 94 99 98 80 47 48 46 55 57 54 15 19 19
+16 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20
+17 20 20 17 21 21 16 20 20 16 19 19 15 19 19 16 19 19
+20 20 20 21 22 21 20 20 20 19 20 19 18 19 18 16 16 16
+15 15 15 14 14 13 13 13 13 13 13 13 12 12 12 12 12 12
+12 12 12 4 5 5 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 58 59 55 110 109 94
+105 104 92 90 89 73 72 73 67 55 57 54 43 45 43 39 40 39
+43 45 43 46 47 45 43 45 43 68 70 65 65 66 61 63 64 60
+108 107 93 72 73 67 105 104 92 90 89 73 72 73 67 40 43 41
+72 73 67 68 70 65 68 70 65 58 59 55 63 64 60 49 51 48
+43 45 43 33 36 34 27 30 29 20 24 24 16 20 20 15 19 19
+15 19 19 15 19 19 15 19 19 16 19 19 16 20 20 16 20 20
+17 21 21 20 24 24 20 23 22 17 21 21 17 20 20 20 20 20
+21 22 21 21 22 21 21 22 21 21 22 21 20 20 20 18 19 18
+16 16 16 15 15 15 13 13 13 13 13 13 12 12 12 12 12 12
+12 12 12 10 10 9 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 21 22 21 110 109 94 110 109 94
+105 104 92 84 83 72 68 70 65 51 52 50 41 42 42 33 37 35
+28 31 30 23 27 26 20 23 23 18 22 22 17 20 20 25 27 26
+26 28 27 27 30 29 25 27 26 20 23 23 23 27 26 30 32 31
+20 24 24 17 21 21 18 22 22 15 19 19 26 28 27 20 23 23
+14 18 18 15 19 19 15 18 18 15 19 19 15 19 19 15 19 19
+15 19 19 15 19 19 15 19 19 15 19 19 15 19 19 16 19 19
+16 20 20 22 24 23 24 26 24 22 24 23 20 23 22 22 24 23
+24 26 24 24 26 24 23 24 24 22 24 23 21 22 21 19 20 19
+17 17 17 15 15 15 14 14 13 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 2 2 2 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 2 2 2 99 98 80 110 109 94 108 107 93
+105 104 92 84 83 72 63 64 60 49 51 48 39 40 39 32 34 33
+27 30 29 23 25 24 20 23 23 17 20 20 15 19 19 14 18 18
+14 17 17 13 17 17 13 17 17 13 17 17 13 17 17 13 17 17
+14 17 17 14 17 17 14 17 17 14 17 17 14 17 17 14 17 17
+14 18 18 14 18 18 14 18 18 14 18 18 15 18 18 15 19 19
+15 19 19 15 19 19 15 19 19 15 19 19 15 19 19 15 19 19
+15 19 19 17 21 21 27 29 28 26 28 27 25 27 26 25 27 26
+27 29 28 27 29 28 26 28 27 24 26 24 21 22 21 20 20 20
+18 19 18 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 4 5 5 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 51 52 50 110 109 94 110 109 94 105 104 92
+90 89 73 72 73 67 55 57 54 43 45 43 35 37 36 30 32 31
+26 28 27 20 24 24 17 21 21 16 19 19 15 18 18 14 17 17
+13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16
+13 16 16 13 16 16 13 16 16 13 17 17 13 17 17 14 17 17
+14 17 17 14 17 17 14 17 17 14 18 18 14 18 18 14 18 18
+15 18 18 15 18 18 15 19 19 15 19 19 15 19 19 15 19 19
+15 19 19 15 19 19 27 29 28 32 34 33 28 31 30 27 29 28
+30 32 31 30 32 31 30 31 28 26 28 27 23 24 24 21 22 21
+19 20 19 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 3 3 3 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 10 10 9 108 107 93 110 109 94 108 107 93 99 98 80
+84 83 72 63 64 60 49 51 48 40 43 41 33 36 34 27 30 29
+23 27 26 18 22 22 17 20 20 15 18 18 14 17 17 13 16 16
+13 16 16 13 16 16 12 15 15 12 15 15 12 15 15 12 15 15
+13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16
+13 17 17 13 17 17 14 17 17 14 17 17 14 17 17 14 18 18
+14 18 18 14 18 18 15 18 18 15 18 18 15 19 19 15 19 19
+15 19 19 15 19 19 17 21 21 33 36 34 32 34 33 31 33 31
+33 36 34 33 36 34 31 33 31 27 29 28 25 27 26 21 22 21
+19 20 19 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 63 64 60 137 133 100 43 45 43 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 68 70 65 110 109 94 110 109 94 105 104 92 84 83 72
+68 70 65 55 57 54 43 45 43 35 37 36 30 32 31 26 28 27
+20 24 24 17 21 21 16 19 19 14 17 17 13 16 16 12 15 15
+12 15 15 12 15 15 12 15 15 12 15 15 12 15 15 12 15 15
+12 15 15 12 15 15 12 15 15 12 15 15 12 15 15 13 16 16
+13 16 16 13 16 16 13 16 16 13 17 17 13 17 17 14 17 17
+14 17 17 14 17 17 14 18 18 14 18 18 14 18 18 15 18 18
+15 19 19 15 19 19 15 19 19 20 24 24 32 34 33 35 37 36
+37 39 37 35 37 36 33 36 34 30 32 31 26 28 27 22 24 23
+20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1 1 1 99 98 80 184 179 149 184 179 149 68 70 65 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+15 15 15 110 109 94 110 109 94 108 107 93 99 98 80 72 73 67
+61 63 57 49 51 48 39 40 39 33 36 34 27 30 29 23 25 24
+18 22 22 16 19 19 14 17 17 13 16 16 12 15 15 12 15 15
+11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 11 14 14
+11 14 14 11 14 14 12 14 14 12 15 15 12 15 15 12 15 15
+12 15 15 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16
+13 17 17 14 17 17 14 17 17 14 17 17 14 18 18 14 18 18
+14 18 18 15 18 18 15 19 19 15 19 19 30 32 31 38 39 37
+39 40 39 39 40 39 35 37 36 31 33 31 27 29 28 22 24 23
+20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3
+110 109 94 197 193 154 210 208 158 184 179 149 68 70 65 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+68 70 65 110 109 94 110 109 94 105 104 92 84 83 72 65 66 61
+51 52 50 43 45 43 35 37 36 30 32 31 25 27 26 20 23 23
+17 20 20 15 18 18 13 16 16 12 15 15 12 15 15 11 14 14
+11 14 14 11 14 14 11 13 13 11 13 13 11 13 13 11 13 13
+11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 11 14 14
+12 15 15 12 15 15 12 15 15 12 15 15 13 16 16 13 16 16
+13 16 16 13 16 16 13 17 17 13 17 17 14 17 17 14 17 17
+14 18 18 14 18 18 14 18 18 16 19 19 37 39 37 41 42 42
+41 42 42 41 42 42 38 39 37 32 34 33 27 29 28 23 24 24
+21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 11 11 11 137 133 100
+197 193 154 251 251 187 239 239 170 184 179 149 31 33 31 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 12 12
+110 109 94 110 109 94 105 104 92 90 89 73 72 73 67 58 59 55
+46 47 45 37 39 37 31 33 31 26 28 27 20 24 24 17 21 21
+15 18 18 13 16 16 12 15 15 12 14 14 11 13 13 11 13 13
+10 13 13 10 13 13 10 13 13 10 13 13 10 13 13 10 13 13
+10 13 13 10 13 13 11 13 13 11 13 13 11 14 14 11 14 14
+11 14 14 11 14 14 12 14 14 12 15 15 12 15 15 12 15 15
+13 16 16 13 16 16 13 16 16 13 16 16 13 17 17 13 17 17
+14 17 17 14 17 17 14 18 18 23 27 26 41 42 42 41 42 42
+43 45 43 41 42 42 39 40 39 33 36 34 27 29 28 23 24 24
+21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 27 29 28 168 163 120 210 208 158
+251 251 187 251 251 187 210 208 158 137 133 100 1 1 1 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 60 56
+110 109 94 105 104 92 105 104 92 84 83 72 65 66 61 51 52 50
+40 43 41 33 36 34 27 30 29 23 25 24 18 22 22 16 19 19
+14 17 17 12 15 15 11 14 14 11 14 14 10 13 13 10 13 13
+10 13 13 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12
+10 12 12 10 12 12 10 13 13 10 13 13 10 13 13 11 13 13
+11 13 13 11 14 14 11 14 14 11 14 14 11 14 14 12 15 15
+12 15 15 12 15 15 12 15 15 13 16 16 13 16 16 13 16 16
+13 17 17 13 17 17 14 17 17 32 34 33 43 45 43 43 45 43
+43 45 43 43 45 43 39 40 39 33 36 34 27 29 28 23 24 24
+21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 1 1 68 70 65 184 179 149 210 208 158 251 251 187
+251 251 187 214 212 158 184 179 149 37 39 37 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 6 7 7 105 104 92
+105 104 92 105 104 92 99 98 80 72 73 67 58 59 55 46 47 45
+35 37 36 30 32 31 25 27 26 20 23 23 16 19 19 14 17 17
+12 15 15 12 14 14 11 13 13 10 13 13 10 12 12 10 12 12
+10 12 12 10 12 12 9 12 12 9 12 12 9 12 12 9 12 12
+10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 13 13
+10 13 13 10 13 13 11 13 13 11 13 13 11 14 14 11 14 14
+11 14 14 12 15 15 12 15 15 12 15 15 12 15 15 13 16 16
+13 16 16 13 16 16 17 20 20 41 42 42 46 47 45 46 47 45
+46 47 45 43 45 43 40 41 39 33 36 34 27 29 28 23 24 24
+20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 4 5 5 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+15 15 15 110 109 94 197 193 154 214 212 158 251 251 187 251 251 187
+239 239 170 184 179 149 84 83 72 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 47 48 46 105 104 92
+105 104 92 99 98 80 84 83 72 68 70 65 51 52 50 40 43 41
+32 34 33 27 29 28 22 24 23 17 21 21 15 18 18 13 16 16
+12 15 15 11 13 13 10 13 13 10 12 12 9 12 12 9 12 12
+9 12 12 9 12 12 9 11 11 9 11 11 9 11 11 9 11 11
+9 12 12 9 12 12 9 12 12 9 12 12 10 12 12 10 12 12
+10 12 12 10 12 12 10 13 13 10 13 13 10 13 13 11 13 13
+11 14 14 11 14 14 11 14 14 12 14 14 12 15 15 12 15 15
+12 15 15 13 16 16 28 31 30 43 45 43 47 48 46 47 48 46
+47 48 46 43 45 43 40 41 39 33 36 34 27 29 28 22 24 23
+20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 3 4 4 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 60 60 56
+177 172 135 197 193 154 251 251 187 251 251 187 251 251 187 251 251 187
+184 179 149 110 109 94 3 4 4 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 1 1 1 99 98 80 105 104 92
+99 98 80 87 86 72 84 83 72 63 64 60 46 47 45 35 37 36
+30 32 31 25 27 26 18 22 22 16 19 19 14 17 17 12 15 15
+11 14 14 10 13 13 9 12 12 9 12 12 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 11 11 9 12 12 9 12 12
+9 12 12 10 12 12 10 12 12 10 12 12 10 13 13 10 13 13
+10 13 13 11 13 13 11 14 14 11 14 14 11 14 14 12 15 15
+12 15 15 14 17 17 41 42 42 47 48 46 49 51 48 51 52 50
+47 48 46 43 45 43 40 41 39 33 36 34 27 29 28 22 24 23
+19 20 19 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 2 2 2 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 23 24 24 137 133 100 184 179 149
+210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 184 179 149
+110 109 94 13 13 13 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 30 32 31 105 104 92 99 98 80
+84 83 72 84 83 72 72 73 67 55 57 54 41 42 42 32 34 33
+27 29 28 20 24 24 17 20 20 14 17 17 13 16 16 12 14 14
+10 13 13 10 12 12 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 12 12 9 12 12 10 12 12 10 12 12 10 12 12
+10 13 13 10 13 13 10 13 13 11 13 13 11 14 14 11 14 14
+11 14 14 27 29 28 55 56 53 72 73 67 51 52 50 51 52 50
+49 51 48 43 45 43 39 40 39 32 34 33 26 28 27 21 22 21
+19 20 19 16 16 16 18 19 17 13 13 13 12 12 12 12 12 12
+12 12 12 12 12 12 1 1 1 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 8 8 7 84 83 72 184 179 149 197 193 154 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 184 179 149 145 141 105
+19 20 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 14 14 13 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 72 73 67 105 104 92 84 83 72
+72 73 67 84 83 72 68 70 65 49 51 48 39 40 39 30 32 31
+25 27 26 18 22 22 15 18 18 13 16 16 12 15 15 11 13 13
+10 12 12 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 12 12 9 12 12 9 12 12
+10 12 12 10 12 12 10 12 12 10 13 13 10 13 13 11 13 13
+13 16 16 41 42 42 99 98 80 158 153 112 65 66 61 51 52 50
+49 51 48 43 45 43 39 40 39 31 33 31 25 27 26 21 22 21
+21 22 21 68 70 65 55 56 53 13 13 13 12 12 12 12 12 12
+12 12 12 11 11 11 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3
+63 64 60 158 153 112 184 179 149 210 208 158 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 184 179 149 137 133 100 27 29 28
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+21 22 21 110 109 94 5 6 5 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 13 13 13 105 104 92 90 89 73 72 73 67
+68 70 65 84 83 72 63 64 60 46 47 45 35 37 36 27 29 28
+22 24 23 17 20 20 14 17 17 12 15 15 11 14 14 10 12 12
+10 12 12 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 12 12 9 12 12 10 12 12 10 12 12 10 13 13 10 13 13
+30 32 31 47 48 46 177 172 135 210 208 158 137 133 100 55 56 53
+49 51 48 43 45 43 38 39 37 31 33 31 25 27 26 22 24 23
+110 109 94 184 179 149 63 64 60 13 13 13 12 12 12 12 12 12
+12 12 12 8 9 9 0 0 0 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 21 22 21 105 104 92
+184 179 149 210 208 158 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 251 251 187 184 179 149 145 141 105 23 24 24 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+68 70 65 184 179 149 105 104 92 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 51 52 50 99 98 80 84 83 72 63 64 60
+68 70 65 72 73 67 55 57 54 41 42 42 32 34 33 25 27 26
+20 23 23 16 19 19 13 16 16 12 14 14 10 13 13 10 12 12
+9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 12 12 9 12 12 10 12 12 17 20 20
+46 47 45 72 73 67 210 208 158 251 251 187 210 208 158 63 64 60
+49 51 48 43 45 43 37 39 37 30 32 31 24 26 24 105 104 92
+210 208 158 197 193 154 47 48 46 13 13 13 12 12 12 12 12 12
+12 12 12 6 7 7 33 36 34 48 49 45 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 8 8 7 23 24 24 55 56 53 110 109 94
+210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 184 179 149 110 109 94 20 20 20 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+110 109 94 251 251 187 210 208 158 47 48 46 0 0 0 0 0 0
+0 0 0 1 1 1 90 89 73 90 89 73 72 73 67 55 56 53
+72 73 67 68 70 65 51 52 50 37 39 37 28 31 30 23 25 24
+17 21 21 15 18 18 12 15 15 11 14 14 10 13 13 9 12 12
+9 11 11 9 11 11 9 11 11 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 9 12 12 13 16 16 41 42 42
+49 51 48 110 109 94 251 251 187 251 251 187 251 251 187 105 104 92
+49 51 48 43 45 43 35 37 36 30 31 28 47 48 46 197 193 154
+251 251 187 197 193 154 31 33 31 12 12 12 12 12 12 12 12 12
+12 12 12 51 52 50 184 179 149 72 73 67 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2
+11 11 11 21 22 21 30 32 31 40 41 39 60 60 56 145 141 105
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158
+184 179 149 110 109 94 13 13 13 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 4 5 4 61 61 53 48 49 45 3 4 3
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+156 151 111 251 251 187 251 251 187 184 179 149 11 11 11 0 0 0
+0 0 0 26 28 27 99 98 80 84 83 72 60 60 56 43 45 43
+72 73 67 65 66 61 49 51 48 35 37 36 27 29 28 20 24 24
+17 20 20 14 17 17 12 15 15 11 13 13 10 12 12 9 11 11
+9 11 11 9 11 11 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 9 11 11 9 11 11
+9 11 11 9 11 11 9 11 11 11 13 13 37 39 37 47 48 46
+51 52 50 184 179 149 251 251 187 251 251 187 251 251 187 145 141 105
+47 48 46 41 42 42 35 37 36 27 29 28 137 133 100 251 251 187
+251 251 187 197 193 154 19 20 19 12 12 12 12 12 12 12 12 12
+27 29 28 184 179 149 214 212 158 63 64 60 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 6 7 7 16 16 16 24 26 24
+30 32 31 38 39 37 47 48 46 55 57 54 68 70 65 110 109 94
+197 193 154 251 251 187 251 251 187 251 251 187 210 208 158 184 179 149
+105 104 92 8 8 7 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 65 66 61 184 179 149 156 151 111
+30 32 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+168 163 120 251 251 187 251 251 187 251 251 187 110 109 94 0 0 0
+0 0 0 60 60 56 84 83 72 68 70 65 51 52 50 38 39 37
+84 83 72 63 64 60 43 45 43 33 36 34 25 27 26 20 23 22
+15 18 18 13 16 16 12 14 14 10 13 13 9 12 12 9 11 11
+9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+9 11 11 9 11 11 10 12 12 33 36 34 46 47 45 51 52 50
+72 73 67 210 208 158 251 251 187 251 251 187 251 251 187 177 172 135
+47 48 46 41 42 42 35 37 36 37 39 37 184 179 149 251 251 187
+251 251 187 197 193 154 13 13 13 12 12 12 12 12 12 12 12 12
+110 109 94 251 251 187 251 251 187 37 39 37 0 0 0 0 0 0
+0 0 0 21 22 20 2 2 1 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+4 5 5 12 12 12 21 22 21 25 27 26 30 32 31 38 39 37
+46 47 45 55 56 53 60 60 56 65 66 61 68 70 65 105 104 92
+110 109 94 197 193 154 210 208 158 197 193 154 184 179 149 84 83 72
+2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 13 13 13 184 179 149 251 251 187
+197 193 154 43 44 41 0 0 0 0 0 0 0 0 0 0 0 0
+145 141 105 251 251 187 251 251 187 251 251 187 214 212 158 43 45 43
+2 2 2 84 83 72 72 73 67 58 59 55 41 42 42 38 39 37
+72 73 67 58 59 55 41 42 42 31 33 31 25 27 26 18 22 22
+14 17 17 12 15 15 12 14 14 10 12 12 9 12 12 9 11 11
+9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 9 12 12 31 33 31 43 45 43 49 51 48 55 56 53
+110 109 94 251 251 187 251 251 187 251 251 187 251 251 187 168 163 120
+47 48 46 41 42 42 33 36 34 63 64 60 197 193 154 251 251 187
+251 251 187 184 179 149 13 13 13 12 12 12 12 12 12 16 16 16
+197 193 154 251 251 187 239 239 170 20 20 20 0 0 0 2 2 1
+108 107 93 110 109 94 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 4 5 5 11 11 11 18 19 18
+22 24 23 26 28 27 32 34 33 39 40 39 46 47 45 51 52 50
+55 57 54 60 60 56 63 64 60 63 64 60 63 64 60 58 59 55
+63 64 60 99 98 80 145 141 105 137 133 100 43 45 43 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 3 4 3 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 110 109 94 251 251 187
+251 251 187 184 179 149 25 27 26 0 0 0 0 0 0 0 0 0
+99 98 80 251 251 187 251 251 187 251 251 187 251 251 187 156 151 111
+25 27 26 84 83 72 65 66 61 47 48 46 32 34 33 39 40 39
+72 73 67 55 57 54 40 41 39 30 32 31 23 25 24 18 22 22
+14 17 17 12 15 15 11 13 13 10 12 12 9 11 11 9 11 11
+9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+9 11 11 28 31 30 41 42 42 47 48 46 55 56 53 58 59 55
+137 133 100 251 251 187 251 251 187 251 251 187 210 208 158 137 133 100
+47 48 46 40 41 39 32 34 33 75 75 61 184 179 149 239 239 170
+251 251 187 177 172 135 13 13 13 12 12 12 12 12 12 43 44 41
+197 193 154 251 251 187 210 208 158 10 10 9 0 0 0 84 83 72
+251 251 187 84 83 72 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
+6 7 7 11 11 11 17 17 17 20 20 20 23 24 24 27 29 28
+32 34 33 38 39 37 43 45 43 47 48 46 51 52 50 55 56 53
+58 59 55 58 59 55 55 57 54 55 56 53 47 48 46 41 42 42
+35 37 36 31 33 31 47 48 46 14 14 13 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 66 65 55 99 98 80 20 20 20
+0 0 0 0 0 0 0 0 0 0 0 0 43 45 43 214 212 158
+251 251 187 251 251 187 145 141 105 3 3 3 0 0 0 0 0 0
+48 49 45 184 179 149 239 239 170 251 251 187 239 239 170 177 172 135
+84 83 72 72 73 67 55 56 53 39 40 39 26 28 27 39 40 39
+68 70 65 51 52 50 39 40 39 28 31 30 22 24 23 17 20 20
+14 17 17 12 14 14 10 13 13 9 11 11 9 11 11 9 11 11
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+27 29 28 40 41 39 46 47 45 51 52 50 55 57 54 63 64 60
+131 127 93 197 193 154 210 208 158 197 193 154 168 163 120 96 95 69
+47 48 46 40 41 39 32 34 33 71 71 57 145 141 105 184 179 149
+184 179 149 131 127 93 13 13 13 12 12 12 12 12 12 48 49 45
+168 163 120 184 179 149 156 151 111 6 7 7 14 14 13 177 172 135
+239 239 170 40 41 39 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 3 3 3 6 7 7 11 11 11 16 16 16
+18 19 18 21 22 21 23 24 24 27 29 28 32 34 33 37 39 37
+41 42 42 43 45 43 47 48 46 51 52 50 51 52 50 51 52 50
+51 52 50 49 51 48 46 47 45 40 41 39 32 34 33 25 27 26
+20 20 20 14 14 13 2 2 2 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 33 36 34 197 193 154 184 179 149
+41 42 42 0 0 0 0 0 0 0 0 0 3 3 3 184 179 149
+251 251 187 251 251 187 184 179 149 48 49 45 0 0 0 0 0 0
+16 17 12 121 119 87 177 172 135 194 189 146 188 184 146 145 141 105
+82 81 62 63 64 60 46 47 45 31 33 31 21 22 21 35 37 36
+68 70 65 51 52 50 37 39 37 27 30 29 22 24 23 17 20 20
+13 16 16 12 14 14 10 13 13 9 11 11 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 25 27 26
+38 39 37 43 45 43 51 52 50 55 56 53 60 60 56 63 64 60
+92 91 72 158 153 112 176 171 126 171 165 117 149 143 98 82 81 62
+44 46 43 38 39 37 30 32 31 71 71 57 131 127 93 160 154 106
+149 143 98 82 81 62 13 13 13 12 12 12 12 12 12 46 47 43
+121 119 87 134 131 96 96 95 69 7 7 6 38 39 37 131 127 93
+145 141 105 12 13 12 0 0 0 1 1 1 3 3 3 6 7 7
+10 10 9 12 12 12 14 14 13 16 16 16 18 19 18 21 22 21
+22 24 23 26 28 27 30 31 28 33 36 34 37 39 37 40 41 39
+41 42 42 43 45 43 46 47 45 46 47 45 46 47 45 43 45 43
+41 42 42 37 39 37 31 33 31 26 28 27 21 22 21 16 16 16
+6 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 177 172 135 251 251 187
+197 193 154 27 29 28 0 0 0 0 0 0 0 0 0 110 109 94
+239 239 170 239 239 170 184 179 149 87 86 72 2 2 1 0 0 0
+1 1 1 82 81 62 142 137 94 165 161 109 165 161 109 131 127 93
+75 75 61 55 56 53 37 39 37 25 27 26 19 20 19 32 34 33
+65 66 61 49 51 48 35 37 36 27 29 28 20 23 23 16 19 19
+13 16 16 13 13 13 10 12 12 9 11 11 8 10 10 8 10 10
+8 9 9 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 22 24 23 35 37 36
+41 42 42 47 48 46 55 56 53 58 59 55 63 64 60 65 66 61
+71 71 57 131 127 93 160 154 106 160 154 106 142 137 94 82 81 62
+46 47 43 40 41 39 33 36 34 66 65 55 125 122 87 149 143 98
+142 137 94 82 81 62 17 17 17 18 19 17 14 14 13 46 47 43
+118 116 76 125 122 87 96 95 69 16 17 12 71 71 57 103 101 77
+82 81 62 11 11 11 11 11 11 13 13 13 14 14 13 14 14 13
+15 15 15 16 16 16 17 17 17 19 20 19 21 22 21 23 24 24
+26 28 27 27 29 28 31 33 31 33 36 34 35 37 36 38 39 37
+39 40 39 39 40 39 38 39 37 37 39 37 35 37 36 31 33 31
+27 29 28 24 26 24 21 22 21 17 17 17 12 12 12 2 2 2
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 68 70 65 251 251 187
+251 251 187 156 151 111 2 2 1 0 0 0 0 0 0 43 44 41
+177 172 135 184 179 149 158 153 112 103 101 77 19 20 18 0 0 0
+0 0 0 46 47 43 131 127 93 160 154 106 160 154 106 131 127 93
+71 71 57 43 45 43 30 32 31 21 22 21 16 16 16 26 28 27
+63 64 60 47 48 46 35 37 36 26 28 27 20 23 23 16 19 19
+13 16 16 13 13 13 10 12 12 9 11 11 8 10 10 8 10 10
+7 9 9 7 9 9 8 9 9 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 20 20 20 33 36 34 40 41 39
+46 47 45 51 52 50 55 57 54 60 60 56 63 64 60 65 66 61
+66 65 55 118 116 76 151 147 98 165 161 109 151 147 98 121 119 87
+96 95 69 96 95 69 96 95 69 103 101 77 142 137 94 151 147 98
+142 137 94 103 101 77 82 81 62 82 81 62 82 81 62 96 95 69
+131 127 93 142 137 94 103 101 77 46 47 43 96 95 69 118 116 76
+71 71 57 14 14 13 14 14 13 15 15 15 15 15 15 16 16 16
+16 16 16 17 17 17 18 19 18 20 20 20 21 22 21 23 24 24
+25 27 26 27 29 28 30 31 28 30 32 31 31 33 31 31 33 31
+31 33 31 31 33 31 30 31 28 27 29 28 25 27 26 22 24 23
+20 20 20 16 16 16 13 13 13 6 7 7 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+58 59 55 68 70 65 8 8 7 0 0 0 10 10 9 210 208 158
+251 251 187 184 179 149 38 39 37 0 0 0 0 0 0 8 8 7
+103 101 77 149 143 98 149 143 98 118 116 76 40 41 39 25 27 25
+53 55 47 82 81 62 144 139 99 165 161 109 165 161 109 142 137 94
+71 71 57 35 37 36 24 26 24 18 19 18 15 15 15 22 24 23
+63 64 60 46 47 45 33 36 34 26 28 27 20 23 22 17 18 17
+12 15 15 11 13 13 10 12 12 9 11 11 8 10 10 8 10 10
+7 9 9 7 9 9 7 9 9 7 9 9 8 9 9 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 16 16 16 30 31 28 35 37 36 41 42 42
+47 48 46 55 56 53 58 59 55 63 64 60 65 66 61 65 66 61
+61 61 53 103 101 77 151 147 98 171 165 117 171 165 117 168 163 120
+158 153 112 158 153 112 155 149 109 151 147 98 151 147 98 160 154 106
+151 147 98 149 143 98 142 137 94 149 143 98 149 143 98 149 143 98
+155 149 109 151 147 98 131 127 93 103 101 77 125 122 87 118 116 76
+71 71 57 16 16 16 16 16 16 16 16 16 17 17 17 17 17 17
+17 17 17 17 17 17 18 19 18 19 20 19 20 20 20 21 22 21
+23 24 24 24 26 24 25 27 26 26 28 27 26 28 27 26 28 27
+25 27 26 24 26 24 22 24 23 21 22 21 19 20 19 16 16 16
+14 14 13 8 8 7 1 1 1 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+20 20 20 184 179 149 168 163 120 21 22 21 0 0 0 105 104 92
+177 172 135 145 141 105 71 71 57 0 0 0 0 0 0 0 0 0
+66 65 55 131 127 93 151 147 98 142 137 94 118 116 76 121 119 87
+145 141 105 158 153 112 176 171 126 178 174 128 176 171 126 149 145 103
+96 95 69 31 33 31 21 22 21 16 16 16 14 14 13 18 19 18
+60 60 56 46 47 45 33 36 34 25 27 26 21 22 21 15 18 18
+12 15 15 11 13 13 9 11 11 8 10 10 8 10 10 8 9 9
+7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 8 9 9
+8 9 9 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 10 12 12 26 28 27 31 33 31 38 39 37 43 45 43
+51 52 50 55 56 53 60 60 56 63 64 60 65 66 61 68 70 65
+63 64 60 96 95 69 158 153 112 178 174 128 188 184 146 194 189 146
+194 189 146 188 184 146 184 181 136 176 171 126 171 165 117 173 167 111
+173 167 111 165 161 109 171 165 117 174 170 121 176 171 126 178 174 128
+178 174 128 174 170 121 160 154 106 149 143 98 149 143 98 125 122 87
+71 71 57 16 16 16 16 16 16 17 17 17 17 17 17 17 17 17
+17 17 17 17 17 17 17 17 17 18 19 18 19 20 19 20 20 20
+21 22 21 21 22 21 21 22 21 22 24 23 21 22 21 21 22 21
+21 22 21 19 20 19 18 19 18 16 16 16 14 14 13 11 11 11
+3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 105 104 92 197 193 154 110 109 94 9 9 8 36 38 35
+121 119 87 131 127 93 96 95 69 18 19 17 30 31 28 66 65 55
+96 95 69 142 137 94 160 154 106 160 154 106 160 154 106 168 163 120
+184 181 136 194 191 148 197 193 154 197 193 154 194 189 146 168 163 120
+125 122 87 46 47 43 18 19 18 15 15 15 13 13 13 14 14 13
+55 57 54 43 45 43 32 34 33 25 27 26 18 22 22 17 17 17
+12 14 14 10 12 12 9 11 11 8 10 10 8 9 9 7 9 9
+6 8 8 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9
+7 9 9 8 9 9 8 9 9 8 10 10 8 10 10 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 32 34 33 41 42 42 35 37 36 39 40 39 37 39 37
+35 37 36 55 57 54 60 60 56 63 64 60 65 66 61 65 66 61
+61 63 57 115 113 82 168 163 120 194 191 148 204 201 155 210 208 158
+210 208 158 210 208 158 197 193 154 194 189 146 186 182 128 176 171 126
+174 170 121 176 171 126 186 182 128 190 186 136 194 191 148 197 193 154
+197 193 154 188 184 146 181 176 137 174 170 121 165 161 109 142 137 94
+82 81 62 24 26 24 16 16 16 16 16 16 16 16 16 16 16 16
+17 17 17 17 17 17 17 17 17 17 17 17 18 19 18 19 20 19
+19 20 19 19 20 19 20 20 20 19 20 19 19 20 19 18 19 18
+17 17 17 15 15 15 13 13 13 12 12 12 6 7 7 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 17 18 17 137 133 100 115 113 82 53 55 47 19 20 18
+103 101 77 144 139 99 137 133 100 115 113 82 137 133 100 156 151 111
+158 153 112 164 159 111 171 165 117 174 170 121 178 174 128 194 189 146
+204 201 155 214 212 158 214 212 158 214 212 158 210 208 158 188 184 146
+158 153 112 87 86 72 17 17 17 13 13 13 13 13 13 15 15 15
+55 56 53 43 45 43 32 34 33 24 26 24 17 20 20 16 16 16
+12 14 14 10 12 12 8 10 10 8 10 10 7 9 9 6 8 8
+6 8 8 6 8 8 6 8 8 7 9 9 7 9 9 7 9 9
+7 9 9 7 9 9 7 9 9 7 9 9 8 9 9 8 10 10
+8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10
+8 10 10 110 109 94 84 83 72 49 51 48 26 28 27 8 10 10
+8 9 9 51 52 50 58 59 55 63 64 60 63 64 60 63 64 60
+66 65 55 134 131 96 181 176 137 210 208 158 214 212 158 239 239 170
+239 239 170 224 223 159 210 208 158 204 201 155 194 189 146 186 182 128
+186 182 128 184 181 136 194 189 146 204 201 155 210 208 158 210 208 158
+210 208 158 210 208 158 197 193 154 190 186 136 176 171 126 155 149 109
+118 116 76 36 38 35 15 15 15 16 16 16 16 16 16 16 16 16
+16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 17 17 17
+17 17 17 17 17 17 17 17 17 16 16 16 16 16 16 15 15 15
+13 13 13 12 12 12 8 8 7 2 2 2 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 53 55 47 103 101 77 96 95 69 53 55 47
+103 101 77 158 153 112 177 172 135 184 179 149 188 184 146 197 193 154
+194 189 146 190 186 136 184 181 136 184 181 136 194 189 146 210 208 158
+214 212 158 239 239 170 251 251 187 251 251 187 224 223 159 204 201 155
+177 172 135 121 119 87 30 31 28 13 13 13 12 12 12 39 40 39
+60 60 56 43 45 43 32 34 33 23 25 24 18 19 18 13 16 16
+13 13 13 9 11 11 8 10 10 8 9 9 6 8 8 6 8 8
+6 8 8 6 8 8 6 8 8 6 8 8 6 8 8 7 9 9
+7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9
+7 9 9 8 9 9 8 9 9 8 10 10 8 10 10 8 10 10
+14 17 17 197 193 154 158 153 112 55 57 54 7 9 9 7 9 9
+8 10 10 51 52 50 58 59 55 60 60 56 63 64 60 63 64 60
+71 71 57 155 149 109 194 191 148 214 212 158 251 251 187 251 251 187
+251 251 187 251 251 187 239 239 170 210 208 158 197 193 154 190 186 136
+190 186 136 194 189 146 204 201 155 210 208 158 224 223 159 239 239 170
+239 239 170 224 223 159 210 208 158 204 201 155 190 186 136 164 159 111
+125 122 87 40 41 39 15 15 15 15 15 15 15 15 15 15 15 15
+16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
+16 16 16 16 16 16 15 15 15 14 14 13 13 13 13 12 12 12
+8 9 9 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 21 22 20 96 95 69 125 122 87 121 119 87
+144 139 99 177 172 135 197 193 154 210 208 158 214 212 158 214 212 158
+210 208 158 204 201 155 194 191 148 194 189 146 204 201 155 214 212 158
+239 239 170 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158
+188 184 146 145 141 105 53 55 47 12 12 12 15 15 15 63 64 60
+63 64 60 41 42 42 31 33 31 23 24 24 17 18 17 12 15 15
+11 13 13 9 11 11 8 9 9 7 9 9 6 8 8 6 8 8
+6 7 7 6 7 7 6 8 8 6 8 8 6 8 8 6 8 8
+6 8 8 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9
+7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 8 8 7
+43 45 43 251 251 187 156 151 111 8 10 10 7 9 9 7 9 9
+21 22 21 51 52 50 55 56 53 55 57 54 58 59 55 58 59 55
+75 75 61 158 153 112 197 193 154 224 223 159 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 214 212 158 204 201 155 194 189 146
+190 186 136 197 193 154 210 208 158 224 223 159 251 251 187 251 251 187
+251 251 187 251 251 187 239 239 170 210 208 158 197 193 154 176 171 126
+125 122 87 36 38 35 14 14 13 14 14 13 15 15 15 15 15 15
+15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15
+15 15 15 14 14 13 13 13 13 12 12 12 10 10 9 3 4 4
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 7 7 5 71 71 57 131 127 93 158 153 112
+177 172 135 197 193 154 214 212 158 239 239 170 251 251 187 251 251 187
+238 237 168 210 208 158 204 201 155 197 193 154 204 201 155 214 212 158
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158
+197 193 154 156 151 111 66 65 55 12 12 12 37 39 37 58 59 55
+58 59 55 41 42 42 31 33 31 22 24 23 17 17 17 12 14 14
+10 12 12 8 10 10 6 8 8 6 8 8 6 7 7 6 7 7
+6 7 7 5 7 7 6 7 7 6 7 7 6 8 8 6 8 8
+6 8 8 6 8 8 6 8 8 7 9 9 7 9 9 7 9 9
+7 9 9 6 8 8 6 8 8 6 8 8 6 8 8 6 8 8
+61 63 57 197 193 154 16 19 19 6 8 8 6 8 8 8 9 9
+41 42 42 47 48 46 51 52 50 51 52 50 55 56 53 55 56 53
+71 71 57 158 153 112 197 193 154 224 223 159 251 251 187 251 251 187
+251 251 187 251 251 187 239 239 170 214 212 158 204 201 155 194 189 146
+190 186 136 197 193 154 210 208 158 239 239 170 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 224 223 159 204 201 155 177 172 135
+121 119 87 30 31 28 13 13 13 14 14 13 14 14 13 14 14 13
+14 14 13 14 14 13 15 15 15 15 15 15 14 14 13 13 13 13
+12 12 12 12 12 12 10 10 9 4 5 5 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 48 49 45 131 127 93 174 170 121
+194 189 146 210 208 158 239 239 170 251 251 187 251 251 187 251 251 187
+251 251 187 214 212 158 204 201 155 197 193 154 204 201 155 210 208 158
+239 239 170 251 251 187 251 251 187 251 251 187 239 239 170 214 212 158
+194 191 148 156 151 111 71 71 57 19 20 19 51 52 50 51 52 50
+51 52 50 41 42 42 30 32 31 21 22 21 17 17 17 13 13 13
+9 11 11 8 9 9 6 8 8 6 7 7 6 7 7 5 7 7
+5 6 5 5 6 5 5 7 7 5 7 7 6 7 7 6 7 7
+6 8 8 6 8 8 6 8 8 6 7 7 6 7 7 6 7 7
+6 7 7 6 8 8 6 8 8 6 8 8 6 8 8 6 8 8
+55 56 53 43 45 43 6 8 8 6 8 8 6 8 8 47 48 46
+60 60 56 47 48 46 46 47 45 47 48 46 38 39 37 10 12 12
+66 65 55 145 141 105 197 193 154 214 212 158 251 251 187 251 251 187
+251 251 187 251 251 187 224 223 159 210 208 158 194 191 148 184 181 136
+184 181 136 194 189 146 204 201 155 224 223 159 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 181 176 137
+115 113 82 21 22 20 13 13 13 13 13 13 13 13 13 13 13 13
+14 14 13 13 13 13 13 13 13 13 13 13 12 12 12 11 11 11
+10 10 9 6 7 7 1 1 1 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 2 2 1 66 65 55 144 139 99 178 174 128
+204 201 155 214 212 158 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 214 212 158 204 201 155 194 191 148 197 193 154 204 201 155
+214 212 158 239 239 170 239 239 170 239 239 170 214 212 158 210 208 158
+184 181 136 149 145 103 66 65 55 41 42 42 47 48 46 46 47 45
+43 45 43 39 40 39 28 31 30 21 22 21 16 16 16 10 12 12
+8 10 10 6 8 8 6 7 7 6 7 7 5 6 5 5 6 5
+5 6 5 5 6 5 5 6 5 5 6 5 5 7 7 5 7 7
+6 7 7 6 7 7 6 7 7 5 7 7 5 7 7 5 7 7
+5 7 7 6 7 7 6 7 7 6 7 7 6 7 7 6 8 8
+6 8 8 6 8 8 6 7 7 6 7 7 46 47 45 156 151 111
+105 104 92 58 59 55 43 45 43 32 34 33 6 8 8 6 8 8
+49 51 48 125 122 87 181 176 137 204 201 155 214 212 158 239 239 170
+239 239 170 214 212 158 210 208 158 197 193 154 181 176 137 176 171 126
+176 171 126 184 181 136 197 193 154 210 208 158 239 239 170 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 177 172 135
+99 98 80 13 13 13 12 12 12 12 12 12 13 13 13 12 12 12
+12 12 12 12 12 12 11 11 11 11 11 11 8 9 9 4 5 5
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 1 1 0 61 61 53 142 137 94 181 176 137
+204 201 155 224 223 159 251 251 187 251 251 187 251 251 187 251 251 187
+251 251 187 214 212 158 197 193 154 190 186 136 184 181 136 188 184 146
+197 193 154 204 201 155 210 208 158 210 208 158 204 201 155 194 189 146
+176 171 126 134 131 96 66 65 55 43 45 43 41 42 42 39 40 39
+35 37 36 33 36 34 27 29 28 20 20 20 15 15 15 9 11 11
+8 9 9 6 7 7 5 6 5 5 6 5 4 5 5 4 5 5
+4 5 5 4 5 5 4 5 5 4 5 5 5 6 5 4 5 5
+4 5 5 5 6 5 4 5 5 5 6 5 5 6 5 5 6 5
+5 7 7 5 7 7 5 7 7 5 7 7 5 7 7 5 7 7
+6 7 7 6 7 7 6 7 7 28 31 30 184 179 149 184 179 149
+145 141 105 84 83 72 27 29 28 5 7 7 5 6 5 16 16 16
+43 44 41 96 95 69 158 153 112 188 184 146 204 201 155 210 208 158
+204 201 155 197 193 154 184 179 149 177 172 135 168 163 120 164 159 111
+164 159 111 174 170 121 184 181 136 197 193 154 214 212 158 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 177 172 135
+71 71 57 11 11 11 12 12 12 11 11 11 11 11 11 11 11 11
+10 10 9 10 10 9 8 8 7 3 4 4 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 31 33 31 121 119 87 176 171 126
+197 193 154 214 212 158 251 251 187 251 251 187 251 251 187 251 251 187
+239 239 170 210 208 158 194 189 146 178 174 128 174 170 121 176 171 126
+177 172 135 181 176 137 184 179 149 184 179 149 181 176 137 178 174 128
+158 153 112 121 119 87 53 55 47 37 39 37 33 36 34 30 32 31
+27 29 28 25 27 26 24 26 24 19 20 19 13 13 13 8 10 10
+6 8 8 6 7 7 5 6 5 4 5 5 4 5 5 4 5 5
+4 5 5 4 5 5 4 5 5 3 4 4 3 4 4 4 5 5
+4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5
+5 6 5 5 6 5 5 6 5 5 6 5 5 6 5 5 6 5
+5 6 5 5 6 5 12 14 14 145 141 105 184 179 149 177 172 135
+90 89 73 21 22 21 5 6 5 5 6 5 4 5 5 37 39 37
+38 39 37 61 61 53 134 131 96 168 163 120 184 181 136 188 184 146
+184 179 149 177 172 135 168 163 120 164 159 111 155 149 109 151 147 98
+151 147 98 164 159 111 176 171 126 184 179 149 210 208 158 239 239 170
+251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 158 153 112
+46 47 43 10 10 9 10 10 9 10 10 9 8 9 9 8 9 9
+6 7 7 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 13 12 7 82 81 62 158 153 112
+188 184 146 210 208 158 239 239 170 251 251 187 251 251 187 251 251 187
+224 223 159 204 201 155 184 181 136 171 165 117 164 159 111 160 154 106
+158 153 112 164 159 111 168 163 120 168 163 120 168 163 120 164 159 111
+142 137 94 96 95 69 43 44 41 27 29 28 26 28 27 23 24 24
+21 22 21 18 19 18 17 17 17 18 19 18 13 13 13 8 8 7
+6 7 7 5 6 5 4 5 5 3 4 4 3 4 4 3 4 4
+3 4 4 3 4 4 3 3 3 3 3 3 3 4 4 3 4 4
+3 4 4 3 4 4 4 5 5 4 5 5 4 5 5 4 5 5
+4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5
+4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5
+4 5 5 4 5 5 4 5 5 4 5 5 31 33 31 65 66 61
+37 39 37 38 39 37 96 95 69 144 139 99 168 163 120 174 170 121
+168 163 120 164 159 111 155 149 109 149 145 103 149 143 98 142 137 94
+149 143 98 151 147 98 164 159 111 177 172 135 197 193 154 210 208 158
+251 251 187 251 251 187 251 251 187 239 239 170 197 193 154 137 133 100
+24 26 24 8 9 9 8 9 9 8 8 7 6 7 7 2 2 2
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 46 47 43 125 122 87
+176 171 126 197 193 154 210 208 158 239 239 170 251 251 187 239 239 170
+214 212 158 197 193 154 181 176 137 164 159 111 151 147 98 149 143 98
+149 143 98 149 143 98 149 145 103 155 149 109 160 154 106 149 143 98
+118 116 76 82 81 62 30 31 28 21 22 21 19 20 19 17 17 17
+14 14 13 12 12 12 10 10 9 12 12 12 10 12 12 6 8 8
+4 5 5 3 4 4 3 4 4 3 4 4 3 3 3 3 3 3
+3 3 3 3 3 3 3 3 3 3 3 3 2 3 3 2 3 3
+3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 4 5 5
+4 5 5 3 4 4 3 4 4 3 4 4 3 4 4 3 4 4
+4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5
+4 5 5 3 4 4 3 4 4 23 24 24 110 109 94 72 73 67
+39 40 39 22 24 23 46 47 43 103 101 77 142 137 94 155 149 109
+160 154 106 155 149 109 149 143 98 142 137 94 142 137 94 142 137 94
+142 137 94 149 143 98 155 149 109 176 171 126 184 179 149 210 208 158
+239 239 170 251 251 187 251 251 187 214 212 158 184 179 149 105 104 92
+10 10 9 6 7 7 3 4 4 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 12 12 9 82 81 62
+149 145 103 181 176 137 197 193 154 210 208 158 214 212 158 214 212 158
+210 208 158 197 193 154 177 172 135 158 153 112 149 143 98 142 137 94
+142 137 94 142 137 94 149 143 98 151 147 98 151 147 98 131 127 93
+103 101 77 71 71 57 22 24 23 15 15 15 13 13 13 11 11 11
+8 9 9 6 7 7 6 7 7 4 5 5 8 9 9 6 7 7
+4 5 5 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2
+2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3
+2 3 3 2 3 3 2 3 3 3 4 4 3 4 4 3 4 4
+3 4 4 3 4 4 3 3 3 3 4 4 3 4 4 3 4 4
+3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 3 4 4
+3 4 4 3 4 4 21 22 21 145 141 105 145 141 105 72 73 67
+17 18 17 3 4 4 21 22 20 66 65 55 118 116 76 142 137 94
+149 143 98 151 147 98 149 143 98 142 137 94 142 137 94 142 137 94
+142 137 94 149 143 98 155 149 109 168 163 120 184 179 149 210 208 158
+239 239 170 251 251 187 251 251 187 210 208 158 177 172 135 71 71 57
+3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 38 35
+115 113 82 158 153 112 181 176 137 197 193 154 204 201 155 210 208 158
+204 201 155 188 184 146 177 172 135 164 159 111 149 145 103 142 137 94
+142 137 94 142 137 94 149 143 98 151 147 98 149 143 98 125 122 87
+96 95 69 61 61 53 16 17 12 8 9 9 8 8 7 6 7 7
+4 5 5 3 4 4 3 3 3 3 3 3 3 3 3 5 6 5
+3 4 4 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2
+2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2
+2 2 2 2 2 2 2 3 3 2 3 3 2 3 3 2 3 3
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+3 3 3 2 3 3 2 3 3 3 4 4 3 4 4 3 4 4
+3 4 4 3 4 4 3 4 4 8 9 9 8 8 7 3 3 3
+3 3 3 3 3 3 9 9 8 36 38 35 82 81 62 118 116 76
+142 137 94 151 147 98 151 147 98 151 147 98 149 143 98 149 143 98
+149 143 98 151 147 98 160 154 106 176 171 126 188 184 146 210 208 158
+239 239 170 251 251 187 239 239 170 210 208 158 156 151 111 31 33 31
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 5
+66 65 55 125 122 87 158 153 112 181 176 137 194 189 146 197 193 154
+197 193 154 184 179 149 177 172 135 168 163 120 156 151 111 151 147 98
+151 147 98 151 147 98 151 147 98 161 156 96 149 143 98 118 116 76
+82 81 62 53 55 47 12 12 9 4 5 5 3 4 4 3 3 3
+3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 2 2
+3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2
+1 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 3 3
+2 3 3 2 3 3 2 3 3 2 3 3 2 2 2 2 2 2
+2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 2 3 3
+2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 3 3 3
+3 3 3 3 3 3 72 73 67 61 61 53 53 55 47 96 95 69
+131 127 93 151 147 98 161 156 96 161 156 96 151 147 98 151 147 98
+161 156 96 160 154 106 164 159 111 177 172 135 197 193 154 210 208 158
+239 239 170 251 251 187 224 223 159 197 193 154 131 127 93 9 9 8
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+24 26 24 82 81 62 131 127 93 164 159 111 178 174 128 188 184 146
+188 184 146 188 184 146 181 176 137 176 171 126 168 163 120 164 159 111
+160 154 106 160 154 106 160 154 106 160 154 106 151 147 98 125 122 87
+82 81 62 61 61 53 12 12 9 3 3 3 3 3 3 2 2 2
+2 2 2 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 2 2 1 2 2 1 2 2 1 2 2
+1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 2 3 3
+2 3 3 30 32 31 72 73 67 31 33 31 36 38 35 82 81 62
+118 116 76 149 143 98 161 156 96 161 156 96 161 156 96 160 154 106
+165 161 109 165 161 109 176 171 126 188 184 146 204 201 155 214 212 158
+239 239 170 239 239 170 214 212 158 184 179 149 82 81 62 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+2 2 2 43 44 41 96 95 69 131 127 93 160 154 106 176 171 126
+184 181 136 184 181 136 184 181 136 181 176 137 178 174 128 174 170 121
+171 165 117 173 167 111 173 167 111 173 167 111 160 154 106 131 127 93
+96 95 69 66 65 55 16 17 12 2 2 2 1 1 1 1 1 1
+1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 2 2 2
+2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+2 2 2 2 2 2 2 2 2 10 9 6 30 31 28 71 71 57
+118 116 76 149 143 98 165 161 109 165 161 109 165 161 109 173 167 111
+173 167 111 176 171 126 184 181 136 197 193 154 210 208 158 224 223 159
+251 251 187 239 239 170 210 208 158 168 163 120 40 41 39 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 13 12 7 61 61 53 96 95 69 131 127 93 160 154 106
+176 171 126 184 181 136 184 181 136 188 184 146 184 181 136 184 181 136
+184 181 136 186 182 128 186 182 128 178 174 128 174 170 121 149 145 103
+118 116 76 82 81 62 21 22 20 1 1 1 1 1 1 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
+1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 2 2 2
+2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+2 2 2 2 2 2 2 2 2 3 3 3 30 31 28 66 65 55
+118 116 76 149 143 98 165 161 109 173 167 111 173 167 111 174 170 121
+186 182 128 190 186 136 197 193 154 210 208 158 224 223 159 251 251 187
+251 251 187 239 239 170 197 193 154 137 133 100 12 12 9 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 30 31 28 71 71 57 103 101 77 134 131 96
+164 159 111 176 171 126 184 181 136 188 184 146 194 189 146 197 193 154
+197 193 154 197 193 154 194 191 148 194 189 146 190 186 136 176 171 126
+145 141 105 103 101 77 40 41 39 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2
+1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 1 2 2
+1 2 2 1 2 2 1 2 2 1 2 2 30 31 28 71 71 57
+118 116 76 160 154 106 173 167 111 178 174 128 186 182 128 190 186 136
+194 191 148 204 201 155 210 208 158 224 223 159 251 251 187 251 251 187
+251 251 187 214 212 158 184 179 149 84 83 72 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 5 5 3 43 44 41 82 81 62 103 101 77
+142 137 94 165 161 109 178 174 128 190 186 136 197 193 154 204 201 155
+210 208 158 210 208 158 210 208 158 210 208 158 210 208 158 197 193 154
+177 172 135 145 141 105 79 78 62 5 4 3 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 2 2 1 2 2 30 31 28 82 81 62
+142 137 94 165 161 109 178 174 128 190 186 136 194 191 148 204 201 155
+210 208 158 214 212 158 239 239 170 251 251 187 251 251 187 251 251 187
+251 251 187 210 208 158 168 163 120 36 38 35 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 16 17 12 53 55 47 82 81 62
+118 116 76 151 147 98 171 165 117 184 181 136 194 191 148 210 208 158
+214 212 158 224 223 159 239 239 170 239 239 170 224 223 159 214 212 158
+197 193 154 176 171 126 115 113 82 24 26 24 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 40 41 39 103 101 77
+151 147 98 176 171 126 190 186 136 197 193 154 210 208 158 214 212 158
+239 239 170 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+239 239 170 197 193 154 110 109 94 3 4 3 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 30 31 28 66 65 55
+96 95 69 125 122 87 160 154 106 178 174 128 194 189 146 204 201 155
+214 212 158 239 239 170 251 251 187 251 251 187 251 251 187 239 239 170
+210 208 158 188 184 146 149 145 103 61 61 53 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 61 61 53 131 127 93
+164 159 111 184 181 136 197 193 154 210 208 158 224 223 159 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187
+210 208 158 168 163 120 43 44 41 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 4 3 2 36 38 35
+71 71 57 96 95 69 142 137 94 165 161 109 184 181 136 197 193 154
+210 208 158 239 239 170 251 251 187 251 251 187 251 251 187 251 251 187
+214 212 158 197 193 154 168 163 120 103 101 77 7 7 5 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 0 0 0 0 0 0 0 0 0 82 81 62 142 137 94
+174 170 121 194 189 146 210 208 158 224 223 159 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 224 223 159
+184 179 149 99 98 80 3 3 3 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 5
+43 44 41 82 81 62 118 116 76 142 137 94 171 165 117 190 186 136
+204 201 155 224 223 159 251 251 187 251 251 187 251 251 187 251 251 187
+214 212 158 197 193 154 174 170 121 125 122 87 30 31 28 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 3 4 3 82 81 62 149 143 98
+176 171 126 194 191 148 210 208 158 239 239 170 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 251 251 187 239 239 170 204 201 155
+145 141 105 30 31 28 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+10 9 6 46 47 43 82 81 62 118 116 76 149 143 98 174 170 121
+194 189 146 210 208 158 224 223 159 251 251 187 251 251 187 224 223 159
+210 208 158 194 191 148 174 170 121 134 131 96 53 55 47 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 7 7 5 96 95 69 149 143 98
+176 171 126 194 191 148 210 208 158 239 239 170 251 251 187 251 251 187
+251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 177 172 135
+75 75 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 10 9 6 46 47 43 82 81 62 118 116 76 149 143 98
+176 171 126 194 191 148 210 208 158 214 212 158 214 212 158 210 208 158
+197 193 154 184 181 136 164 159 111 131 127 93 53 55 47 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 7 7 5 96 95 69 149 143 98
+174 170 121 194 189 146 204 201 155 214 212 158 239 239 170 251 251 187
+251 251 187 251 251 187 239 239 170 210 208 158 184 179 149 110 109 94
+12 12 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 10 9 6 43 44 41 82 81 62 115 113 82
+144 139 99 168 163 120 188 184 146 197 193 154 197 193 154 194 189 146
+184 181 136 174 170 121 151 147 98 118 116 76 36 38 35 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 4 3 2 82 81 62 142 137 94
+171 165 117 186 182 128 194 191 148 210 208 158 214 212 158 224 223 159
+239 239 170 224 223 159 210 208 158 184 179 149 137 133 100 36 38 35
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 7 7 5 36 38 35 71 71 57
+103 101 77 131 127 93 155 149 109 168 163 120 168 163 120 168 163 120
+164 159 111 149 143 98 125 122 87 82 81 62 13 12 7 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 61 61 53 125 122 87
+160 154 106 174 170 121 184 181 136 194 189 146 204 201 155 210 208 158
+210 208 158 204 201 155 184 179 149 145 141 105 61 61 53 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 3 3 2 30 31 28
+61 61 53 82 81 62 103 101 77 121 119 87 125 122 87 125 122 87
+118 116 76 103 101 77 79 78 62 24 26 24 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 25 27 25 96 95 69
+142 137 94 160 154 106 171 165 117 178 174 128 184 181 136 184 181 136
+181 176 137 177 172 135 145 141 105 75 75 61 5 5 3 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+16 17 12 40 41 39 61 61 53 71 71 57 71 71 57 71 71 57
+66 65 55 43 44 41 12 12 9 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 46 47 43
+96 95 69 125 122 87 142 137 94 149 145 103 155 149 109 155 149 109
+145 141 105 121 119 87 66 65 55 7 7 5 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 1 1 16 17 12 24 26 24 25 27 25 19 20 18
+7 7 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1
+25 27 25 61 61 53 82 81 62 96 95 69 96 95 69 82 81 62
+61 61 53 25 27 25 2 2 1 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 5 6 5 13 12 7 10 9 6 3 4 3
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0
diff --git a/drivers/video/logo/logo_linux_vga16.ppm b/drivers/video/logo/logo_linux_vga16.ppm
index 1850c15e6fe..12ac3a5454c 100644
--- a/drivers/video/logo/logo_linux_vga16.ppm
+++ b/drivers/video/logo/logo_linux_vga16.ppm
@@ -1,1604 +1,2739 @@
P3
-# Standard 16-color Linux logo
-80 80
+142 114
255
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 85 85 85 85 85 85 85 85 85
- 85 85 85 85 85 85 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 85 85 85
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 85 85 85 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 170 170 170 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
-170 170 170 170 170 170 85 85 85 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 85 85 85 170 170 170 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 170 170 170 170 170
-170 170 170 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 85 85 85 170 170 170 170 170 170 170 170 170
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 170 170 170 255 255 255 255 255 255
-255 255 255 170 170 170 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 85 85 85
-170 170 170 170 170 170 255 255 255 255 255 255
- 0 0 0 0 0 0 0 0 0 0 0 0
-170 170 170 255 255 255 170 170 170 170 170 170
-255 255 255 170 170 170 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 85 85 85
-170 170 170 0 0 0 0 0 0 255 255 255
- 85 85 85 0 0 0 0 0 0 0 0 0
-255 255 255 170 170 170 0 0 0 85 85 85
-170 170 170 255 255 255 170 170 170 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 85 85 85
- 85 85 85 0 0 0 0 0 0 170 170 170
- 85 85 85 0 0 0 0 0 0 0 0 0
-255 255 255 85 85 85 0 0 0 0 0 0
- 85 85 85 255 255 255 170 170 170 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 85 85 85
-170 170 170 0 0 0 0 0 0 170 170 170
- 85 85 85 85 85 85 85 85 85 85 85 85
-255 255 255 85 85 85 0 0 0 0 0 0
- 85 85 85 255 255 255 170 170 170 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
-255 255 255 0 0 0 0 0 0 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 0 0 0 0 0 0
- 85 85 85 255 255 255 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
-170 170 170 170 170 170 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 170 170 170 170 170 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 85 85 85 0 0 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 170 85 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 85 85 85 0 0 0
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 170 85 0
-170 85 0 170 85 0 85 85 85 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 85 85 85 0 0 0
- 85 85 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 85 85 85 0 0 0
- 0 0 0 85 85 85 170 170 170 85 85 85
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 85 85 85 0 0 0
- 85 85 85 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 170 170 170 170 170 170 170 170 0 0 0
- 0 0 0 0 0 0 170 170 170 170 170 170
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 85 85 85 170 170 170 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 170 170 170 170 170
-170 170 170 170 170 170 170 170 170 85 85 85
- 0 0 0 0 0 0 85 85 85 85 85 85
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 85 85 85 170 170 170 170 170 170 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 170 170 170 170 170 170 170 170 170 170 170
-255 255 255 255 255 255 255 255 255 170 170 170
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 85 85 85
-255 255 255 255 255 255 170 170 170 170 170 170
-170 170 170 170 170 170 170 170 170 170 170 170
-170 170 170 170 170 170 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 170 170 170
-255 255 255 255 255 255 170 170 170 170 170 170
-170 170 170 170 170 170 170 170 170 170 170 170
-170 170 170 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-170 170 170 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 85 85 85 255 255 255
-255 255 255 255 255 255 255 255 255 170 170 170
-170 170 170 170 170 170 170 170 170 170 170 170
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 85 85 85 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 85 85 85 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 85 85 85 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 85 85 85 170 170 170 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 170 170 170 170 170 170 170 170 170
-255 255 255 255 255 255 255 255 255 170 170 170
-170 170 170 170 170 170 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-170 170 170 170 170 170 170 170 170 170 170 170
-170 170 170 170 170 170 170 170 170 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
-170 170 170 170 170 170 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-170 170 170 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 170 170 170
-170 170 170 170 170 170 170 170 170 85 85 85
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
-170 170 170 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 170 170 170 170 170 170
- 0 0 0 0 0 0 0 0 0 85 85 85
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 85 85 85 0 0 0 0 0 0 85 85 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 170 170 170
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 170 170 170
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-170 170 170 85 85 85 0 0 0 0 0 0
- 0 0 0 85 85 85 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 85 85 85
- 0 0 0 0 0 0 85 85 85 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 0 0 0 85 85 85
- 85 85 85 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 85 85 85
- 0 0 0 85 85 85 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 0 0 0 85 85 85
- 85 85 85 0 0 0 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 85 85 85
- 0 0 0 170 170 170 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 85 85 85 0 0 0
- 0 0 0 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 85 85 85 0 0 0
- 85 85 85 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 85 85 85 0 0 0 0 0 0
-170 170 170 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 85 85 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 85 85 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 85 85 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 0 0 0
- 85 85 85 85 85 85 85 85 85 85 85 85
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 0 0 0 170 85 0
-255 255 85 170 85 0 0 0 0 0 0 0
- 85 85 85 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 85 85 85 85 85 85 0 0 0
- 0 0 0 85 85 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 0 0 0
- 0 0 0 85 85 85 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 85 170 85 0 255 255 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 85 85 85
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
- 0 0 0 0 0 0 85 85 85 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 85
-170 85 0 255 255 85 170 85 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
-170 85 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 0 0 0 0 0 0 85 85 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 170 85 0
-255 255 85 170 85 0 255 255 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 170 85 0
-255 255 85 170 85 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 0 0 0 0 0 0 0 0 0
- 85 85 85 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 85
-170 85 0 255 255 85 170 85 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 255 255 85
-170 85 0 255 255 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 0 0 0 0 0 0
- 0 0 0 85 85 85 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 255 255 85 170 85 0
-255 255 85 170 85 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 0 0 0
- 0 0 0 0 0 0 85 85 85 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 170 170 170 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 170 170 170 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 170 170 170 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 0 0 0 0 0 0 0 0 0
- 0 0 0 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 170 170 170 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 0 0 0 0 0 0 0 0 0
- 85 85 85 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 170 170 170 85 85 85 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 85 85 85 85 85 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-170 170 170 85 85 85 85 85 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 170 170 170
- 85 85 85 0 0 0 0 0 0 170 85 0
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 85 85 85
- 0 0 0 0 0 0 0 0 0 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-170 170 170 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-170 170 170 85 85 85 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 170 85 0
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 170 85 0
-170 85 0 170 170 170 255 255 255 255 255 255
-255 255 255 255 255 255 255 255 255 255 255 255
-255 255 255 255 255 255 170 170 170 85 85 85
- 85 85 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-170 85 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 170 85 0
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 170 85 0 170 85 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 170 85 0
-170 85 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-170 85 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-170 85 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 85 85 85 170 85 0
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 170 85 0 170 85 0 170 85 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 170 85 0
-170 85 0 0 0 0 0 0 0 0 0 0
- 85 85 85 85 85 85 85 85 85 85 85 85
- 85 85 85 85 85 85 85 85 85 85 85 85
- 85 85 85 85 85 85 85 85 85 0 0 0
- 0 0 0 0 0 0 0 0 0 170 85 0
-170 85 0 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 255 255 85 170 85 0
-170 85 0 170 85 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 255 255 85 170 85 0
-255 255 85 170 85 0 170 85 0 170 85 0
- 85 85 85 85 85 85 85 85 85 85 85 85
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 85 85 85
- 85 85 85 85 85 85 85 85 85 170 85 0
-170 85 0 170 85 0 170 85 0 255 255 85
-170 85 0 255 255 85 170 85 0 170 85 0
-170 85 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 170 85 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
-170 85 0 170 85 0 170 85 0 170 85 0
-170 85 0 170 85 0 170 85 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85
+0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 170 170 170 170 85 0 170 170 170 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170
+255 255 85 170 170 170 170 170 170 170 85 0 85 255 85 170 85 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 170 85 0
+170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 170 170 170
+170 170 170 170 85 0 170 170 170 170 170 170 170 85 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 255 85
+255 85 85 85 255 85 170 170 170 170 85 0 170 170 170 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 85 85 85
+170 170 170 170 85 0 170 170 170 85 85 85 170 85 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 85 85 85 170 85 0
+85 85 85 85 85 85 170 85 0 85 255 85 85 85 85 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 170 85 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 170 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+170 85 0 85 255 85 170 85 0 170 85 0 170 85 0 85 255 85
+170 85 0 170 85 0 0 170 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 170 85 0
+255 255 85 170 85 0 255 255 85 255 255 85 255 255 85 170 85 0
+255 255 85 85 255 85 170 85 0 170 85 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85
+85 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85
+255 255 85 170 85 0 255 255 85 85 255 85 170 85 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 170 85 0
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0
+255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 85 255 85
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85
+255 255 85 255 255 85 170 85 0 255 255 85 85 255 85 255 255 85
+255 255 85 170 85 0 255 255 85 170 85 0 255 255 85 170 85 0
+170 85 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 170 85 0 255 255 85 85 255 85 255 255 85
+170 170 170 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 255 255 85
+85 255 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 255 255 85
+255 255 255 255 255 85 255 255 85 170 85 0 255 255 85 170 85 0
+255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 255 255 85
+170 85 0 170 85 0 0 170 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 170 85 0 85 255 85 255 255 85 170 170 170 255 255 255
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 170 85 0 255 255 85 85 255 85 255 255 85
+255 255 85 85 255 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 255 255 85 255 255 85 255 255 85 255 255 255 255 255 85
+255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 85 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0
+255 255 85 170 85 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+170 85 0 170 85 0 255 255 85 255 255 85 255 255 255 170 170 170
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+170 85 0 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85
+255 255 85 85 255 85 170 85 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+255 255 85 85 255 85 255 255 85 170 170 170 255 255 255 255 255 85
+255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 85 255 85 170 85 0
+255 255 85 170 85 0 170 85 0 0 0 0 85 85 85 0 0 0
+85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170
+85 255 85 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 0
+170 85 0 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 85 255 85 255 255 85 170 85 0 170 85 0
+170 85 0 85 255 85 255 255 85 85 85 85 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 85 255 85 170 170 170 170 170 170
+85 85 85 170 170 170 170 170 170 170 85 0 170 170 170 170 170 170
+85 255 85 170 170 170 170 85 0 170 170 170 85 255 85 255 85 85
+85 255 85 170 170 170 255 255 85 85 85 85 255 255 85 170 170 170
+85 255 85 170 170 170 255 255 85 170 170 170 170 170 170 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 255 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0
+255 255 85 255 255 85 255 255 85 170 85 0 0 170 0 85 85 85
+170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 85 255 85
+255 85 85 85 255 85 85 85 85 255 85 85 85 85 85 170 170 170
+170 85 0 170 170 170 85 85 85 85 255 85 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85
+170 85 0 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 170 85 0 255 255 85 85 85 85 85 85 85
+255 255 85 170 170 170 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 85 85 85 170 170 170 170 85 0 170 170 170
+170 170 170 255 255 85 170 170 170 85 85 85 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 170 85 0 170 85 0 0 170 0
+0 0 0 170 85 0 170 85 0 0 170 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 85 85 85 170 170 170 85 85 85
+170 170 170 85 85 85 85 85 85 170 170 170 170 85 0 85 85 85
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 170 85 0
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0
+255 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85
+170 85 0 255 255 85 85 255 85 255 255 85 255 255 85 170 85 0
+170 85 0 255 255 85 170 85 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 255 255 85
+255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85
+85 255 85 170 85 0 0 170 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 170 0 170 85 0 255 255 85
+85 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+170 85 0 255 255 85 85 255 85 255 255 85 255 255 85 170 85 0
+85 255 85 170 85 0 170 85 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 170 85 0
+255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 85 255 85
+170 85 0 170 85 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 170 85 0
+255 255 85 170 85 0 255 255 85 170 85 0 255 255 85 85 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 170 85 0 255 255 85 85 255 85 170 85 0 170 85 0
+0 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 85 255 85
+255 255 85 85 255 85 170 85 0 170 85 0 85 255 85 170 85 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 85 255 85
+255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 255 255 85
+255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 255 255 85
+170 85 0 170 85 0 85 255 85 170 85 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 85 85 85
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 255 255 85
+170 85 0 255 255 85 255 255 85 170 85 0 255 255 85 170 85 0
+255 255 85 85 255 85 170 85 0 255 255 85 170 85 0 85 255 85
+170 85 0 170 85 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 85 85 85
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 85 255 85
+170 85 0 255 255 85 170 85 0 85 255 85 170 85 0 170 85 0
+0 170 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 170 170 170 170 170 170 255 255 255 170 170 170
+170 170 170 170 170 170 85 85 85 85 85 85 85 85 85 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 255 85 255 255 85
+170 85 0 255 255 85 255 255 85 170 85 0 85 255 85 170 85 0
+255 255 85 170 85 0 0 170 0 170 85 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 170 170 170 170 170 170 170 170 170 85 85 85
+85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85
+255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 170 85 0
+0 170 0 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+255 255 85 255 255 85 170 85 0 0 170 0 85 85 85 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 85 85 85
+170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 170 85 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+170 170 170 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170
+170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 170 170 170
+255 255 255 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170
+255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 170 170 170
+170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170
+255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255
+255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 170 170 170
+170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+170 170 170 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85
+85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 170 170 170 85 85 85
+85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 170 170 170 85 85 85 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 170 170 170 170 170 170
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 170 170 170 85 85 85 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 255 255 255 170 170 170
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170
+170 170 170 255 255 255 170 170 170 170 170 170
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170
+255 255 255 255 255 255 170 170 170 170 170 170
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 255 255 255
+255 255 255 170 170 170 170 170 170 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+170 170 170 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 170 170 170 255 255 255 255 255 255 255 255 255
+170 170 170 170 170 170 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 170 170 170 255 255 255 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 170 170 170 255 255 255 170 170 170 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 255 255 255 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 255 255 255 255 255 255 255 255 255 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 170 170 170
+255 255 255 170 170 170 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+170 170 170 255 255 255 255 255 255 170 170 170 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 255 255 255
+255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85
+170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 170 170 170
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+170 170 170 255 255 255 255 255 255 255 255 255 85 85 85 0 0 0
+0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170
+0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 255 255 255
+255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85
+170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255
+170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0
+0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170
+85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 255 255 255
+255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0
+170 170 170 255 255 255 170 170 170 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 170 170 170 85 85 85 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170
+255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170
+0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 255 255 255
+170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 85 85 85
+170 170 170 255 255 255 255 255 255 0 0 0 0 0 0 85 85 85
+255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255
+255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 255 255 255 170 170 170 170 170 170 170 170 170
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 170 170 170 255 255 255 170 170 170 170 170 170 85 85 85
+85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 170 170 170
+170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85
+170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 170 170 170
+170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170
+255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 170 170 170 170 170 170 255 255 85 85 85 85
+85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85
+85 85 85 170 170 170 170 170 170 170 170 170 170 85 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 170 85 0
+170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+170 85 0 170 170 170 85 85 85 0 0 0 85 85 85 85 85 85
+170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255
+170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 170 85 0 170 170 170 170 170 170 85 85 85
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 170 85 0 85 255 85 170 85 0 170 170 170 85 85 85
+85 85 85 0 0 0 0 0 0 85 85 85 170 85 0 85 255 85
+170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+85 85 85 85 85 85 170 85 0 0 0 0 85 85 85 85 85 85
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255
+255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0
+170 170 170 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 170 170 170 170 85 0 170 170 170 170 85 0
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 255 85 85 170 170 170 85 255 85 170 85 0
+85 85 85 85 85 85 170 85 0 85 85 85 170 170 170 85 85 85
+170 170 170 170 85 0 85 85 85 85 85 85 85 85 85 85 85 85
+170 85 0 85 255 85 85 85 85 85 85 85 85 85 85 170 85 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 170 170 170
+255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 85 0 170 170 170 170 85 0 85 85 85 0 0 0
+85 85 85 85 85 85 85 255 85 170 170 170 170 170 170 170 85 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 85 255 85 255 85 85 170 170 170 170 170 170
+170 170 170 85 255 85 170 170 170 170 85 0 170 170 170 170 85 0
+170 170 170 85 85 85 85 255 85 170 85 0 170 170 170 170 85 0
+170 170 170 170 170 170 170 85 0 85 85 85 85 85 85 85 255 85
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 170 170 170 170 170 170 0 0 0 0 0 0 85 85 85
+170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 255 255 85 85 85 85 85 85 85 85 85 85
+85 255 85 255 85 85 170 170 170 170 85 0 170 170 170 85 255 85
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 170 85 0 170 170 170 170 170 170 255 255 85
+170 170 170 255 85 85 170 170 170 170 170 170 255 255 85 170 170 170
+85 255 85 170 170 170 255 85 85 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 170 85 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 170 170 170 85 85 85 0 0 0 85 85 85
+85 85 85 170 85 0 85 85 85 0 0 0 85 85 85 85 85 85
+85 85 85 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170
+170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 85 85
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 170 170 170 255 255 85 170 170 170 170 170 170
+170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 85 0
+170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 255 255 85
+170 170 170 255 255 85 170 170 170 170 170 170 85 255 85 170 85 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 170 170 170 85 85 85 85 85 85 0 0 0
+85 85 85 85 85 85 170 170 170 85 85 85 170 170 170 170 85 0
+170 170 170 85 255 85 170 170 170 170 85 0 170 170 170 170 170 170
+255 255 85 170 170 170 170 170 170 255 255 255 255 255 85 170 170 170
+255 255 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 255 255 255
+170 170 170 255 255 255 255 255 85 170 170 170 255 255 85 170 170 170
+255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 255 85 85 170 170 170 170 170 170
+85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 85 85 85
+85 85 85 255 255 85 170 170 170 170 170 170 170 170 170 170 170 170
+255 255 85 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170
+170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170
+170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 255 85 170 170 170 255 255 85 255 255 255 255 255 255
+255 255 255 170 170 170 255 255 255 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 255 255 85 170 170 170 255 255 85 255 255 255
+255 255 85 255 255 255 255 255 85 170 170 170 170 170 170 170 85 0
+170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170
+170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 255 255 85
+255 255 255 255 255 255 255 255 85 255 255 255 255 255 255 170 170 170
+255 255 85 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 170 170 170 170 170 170 170 170 170 255 255 255 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 255 255 85
+170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 85 170 170 170 255 255 85
+85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 170 170 170
+255 255 85 170 170 170 170 170 170 255 255 255 255 255 255 255 255 255
+170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170
+255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 255 255 255
+170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0
+85 85 85 170 85 0 255 255 255 170 170 170 255 255 255 255 255 255
+255 255 85 255 255 255 170 170 170 255 255 85 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 255 255 85 255 255 255 255 255 255
+170 170 170 255 255 255 255 255 255 170 170 170 170 170 170 170 170 170
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 255 85 170 170 170
+170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 85 170 170 170 170 170 170 255 255 255
+170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 255 255 85
+170 170 170 170 85 0 85 85 85 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 170 170 170 170 170 170 255 255 85 170 170 170 255 255 255
+255 255 255 170 170 170 255 255 255 170 170 170 170 170 170 255 255 85
+170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 255 255 85
+85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170
+255 255 85 255 255 255 170 170 170 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 85 85 85
+0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+85 85 85 85 85 85 170 170 170 170 170 170 255 255 255 170 170 170
+255 255 255 170 170 170 255 255 85 170 170 170 170 170 170 170 170 170
+255 85 85 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255
+170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 170 170 170
+255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255
+255 255 85 255 255 255 170 170 170 255 255 85 170 170 170 170 170 170
+170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 255 85
+170 170 170 170 85 0 85 85 85 0 0 0 85 85 85 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170
+170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 170 170 170 255 255 85 170 170 170 170 170 170
+255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 255 85 85
+85 255 85 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 85 170 170 170 170 170 170
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 85
+170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170
+255 255 255 170 170 170 170 170 170 170 170 170 170 170 170 255 85 85
+170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0
+85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 170 170 170
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 170 85 0 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 85 255 85
+255 85 85 170 170 170 255 255 85 170 170 170 170 170 170 255 255 255
+255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 170 170 170
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170
+170 170 170 255 255 85 170 170 170 255 255 85 255 255 255 255 255 255
+170 170 170 170 170 170 255 255 85 170 170 170 255 85 85 85 255 85
+170 170 170 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170
+170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 85 85 85 85 85 85 85 85 85 170 170 170 255 255 85
+170 170 170 170 85 0 170 170 170 170 170 170 170 85 0 85 85 85
+170 170 170 170 85 0 85 85 85 170 170 170 170 170 170 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 85 170 170 170 170 170 170
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0
+170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170
+255 255 255 170 170 170 170 170 170 170 85 0 170 170 170 85 85 85
+170 170 170 170 170 170 170 85 0 170 170 170 170 85 0 85 85 85
+85 255 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 85 85 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170
+170 85 0 170 170 170 85 255 85 170 85 0 170 170 170 85 85 85
+170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 255 255 255
+255 255 85 255 255 255 170 170 170 170 170 170 170 170 170 170 85 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85
+170 170 170 255 255 85 170 170 170 170 170 170 85 255 85 170 170 170
+170 85 0 170 85 0 170 170 170 85 255 85 85 85 85 170 170 170
+170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 85 85 85
+0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 85 85 85
+170 170 170 170 85 0 170 170 170 85 85 85 170 170 170 170 85 0
+170 170 170 85 255 85 170 85 0 170 170 170 170 170 170 170 170 170
+255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+170 85 0 170 170 170 255 255 85 170 170 170 255 255 255 170 170 170
+170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 170 85 0
+170 170 170 85 255 85 170 85 0 170 170 170 170 85 0 85 85 85
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+85 255 85 170 170 170 170 85 0 170 170 170 170 85 0 85 255 85
+170 170 170 170 85 0 170 170 170 170 170 170 170 170 170 255 255 85
+170 170 170 255 255 255 170 170 170 170 170 170 170 170 170 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 85 0 85 85 85 170 170 170 255 255 85 170 170 170
+170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 85 0
+170 170 170 85 85 85 170 170 170 170 85 0 170 170 170 85 85 85
+170 85 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 170 85 0
+85 85 85 255 85 85 85 255 85 170 85 0 170 170 170 170 170 170
+170 85 0 170 170 170 85 85 85 255 255 85 170 170 170 170 170 170
+255 255 255 170 170 170 255 255 255 255 255 85 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 170 170 170 170 85 0 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 255 255 85 85 85 85 170 170 170
+85 255 85 255 85 85 170 170 170 85 255 85 255 85 85 85 255 85
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85
+85 85 85 85 255 85 255 85 85 170 170 170 85 255 85 170 85 0
+170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 255 255
+170 170 170 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 170 170 170 85 85 85 255 255 85
+170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 255 255 85
+85 85 85 255 255 85 170 170 170 170 85 0 170 170 170 85 85 85
+170 85 0 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+170 170 170 170 85 0 170 170 170 170 85 0 170 170 170 170 170 170
+170 85 0 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170
+255 255 85 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170
+170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 170 85 0
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+170 85 0 85 255 85 170 170 170 170 170 170 255 255 85 170 170 170
+255 255 85 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 170 170 170 255 255 85 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 170 85 0
+170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85
+170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 170 85 0 170 170 170 170 85 0 170 170 170 170 170 170
+170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 255 255 255
+170 170 170 255 255 255 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85
+170 85 0 170 170 170 170 85 0 255 255 85 170 170 170 170 170 170
+170 170 170 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170
+255 255 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 85 85 85
+170 85 0 85 255 85 170 170 170 170 170 170 170 170 170 255 255 85
+255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170
+170 170 170 255 255 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+170 85 0 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85
+170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 255 255 255
+170 170 170 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 255 85
+170 170 170 255 255 85 170 170 170 255 255 85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 85 85 85 170 85 0 170 170 170 170 170 170
+255 255 85 170 170 170 255 255 255 255 255 85 255 255 255 255 255 255
+170 170 170 255 255 85 170 170 170 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0
+170 170 170 170 170 170 170 170 170 255 255 255 170 170 170 255 255 255
+170 170 170 255 255 255 170 170 170 255 255 255 255 255 85 255 255 255
+170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 170 85 0 85 85 85 170 170 170 170 170 170 170 170 170
+170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 170 170 170
+255 255 85 170 170 170 170 170 170 170 85 0 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170
+255 255 85 170 170 170 255 255 85 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 85 85 85 170 85 0 170 170 170
+255 255 85 170 170 170 255 255 85 255 255 255 170 170 170 255 255 255
+170 170 170 170 170 170 170 170 170 170 170 170 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170
+170 85 0 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170
+255 255 255 255 255 255 170 170 170 255 255 255 255 255 85 170 170 170
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170
+255 255 85 170 170 170 170 85 0 85 255 85 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0
+170 170 170 170 170 170 255 255 85 170 170 170 255 255 255 255 255 255
+255 255 85 255 255 255 170 170 170 255 255 255 170 170 170 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 85 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+255 255 85 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170
+255 255 255 170 170 170 255 255 85 170 170 170 85 85 85 85 85 85
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 170 170 170
+170 85 0 170 170 170 170 85 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85
+170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 170 170 170
+170 170 170 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+85 85 85 85 85 85 85 85 85 170 85 0 85 85 85 170 85 0
+85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 85 0
+85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 255 255 85
+170 170 170 170 170 170 170 85 0 85 85 85 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85
+85 85 85 85 255 85 170 85 0 170 170 170 170 85 0 170 170 170
+85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85
+85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
new file mode 100644
index 00000000000..8a75d05f433
--- /dev/null
+++ b/drivers/video/mx3fb.c
@@ -0,0 +1,1555 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/console.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <mach/hardware.h>
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define MX3FB_NAME "mx3_sdc_fb"
+
+#define MX3FB_REG_OFFSET 0xB4
+
+/* SDC Registers */
+#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET)
+#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET)
+#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET)
+#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET)
+#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET)
+#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET)
+#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET)
+#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET)
+#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET)
+#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET)
+#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET)
+
+/* Register bits */
+#define SDC_COM_TFT_COLOR 0x00000001UL
+#define SDC_COM_FG_EN 0x00000010UL
+#define SDC_COM_GWSEL 0x00000020UL
+#define SDC_COM_GLB_A 0x00000040UL
+#define SDC_COM_KEY_COLOR_G 0x00000080UL
+#define SDC_COM_BG_EN 0x00000200UL
+#define SDC_COM_SHARP 0x00001000UL
+
+#define SDC_V_SYNC_WIDTH_L 0x00000001UL
+
+/* Display Interface registers */
+#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET)
+#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET)
+#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET)
+#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET)
+#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET)
+#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET)
+#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET)
+#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET)
+#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET)
+#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET)
+#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET)
+#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET)
+#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET)
+#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET)
+#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET)
+#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET)
+#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET)
+#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET)
+#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET)
+#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET)
+#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET)
+#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET)
+#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET)
+#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET)
+#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET)
+#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET)
+#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET)
+#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET)
+#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET)
+#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET)
+#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET)
+#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET)
+#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET)
+#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET)
+#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET)
+#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET)
+#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET)
+#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET)
+#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET)
+
+/* DI_DISP_SIG_POL bits */
+#define DI_D3_VSYNC_POL_SHIFT 28
+#define DI_D3_HSYNC_POL_SHIFT 27
+#define DI_D3_DRDY_SHARP_POL_SHIFT 26
+#define DI_D3_CLK_POL_SHIFT 25
+#define DI_D3_DATA_POL_SHIFT 24
+
+/* DI_DISP_IF_CONF bits */
+#define DI_D3_CLK_IDLE_SHIFT 26
+#define DI_D3_CLK_SEL_SHIFT 25
+#define DI_D3_DATAMSK_SHIFT 24
+
+enum ipu_panel {
+ IPU_PANEL_SHARP_TFT,
+ IPU_PANEL_TFT,
+};
+
+struct ipu_di_signal_cfg {
+ unsigned datamask_en:1;
+ unsigned clksel_en:1;
+ unsigned clkidle_en:1;
+ unsigned data_pol:1; /* true = inverted */
+ unsigned clk_pol:1; /* true = rising edge */
+ unsigned enable_pol:1;
+ unsigned Hsync_pol:1; /* true = active high */
+ unsigned Vsync_pol:1;
+};
+
+static const struct fb_videomode mx3fb_modedb[] = {
+ {
+ /* 240x320 @ 60 Hz */
+ .name = "Sharp-QVGA",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
+ FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
+ FB_SYNC_CLK_IDLE_EN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 240x33 @ 60 Hz */
+ .name = "Sharp-CLI",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 33,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9 + 287,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
+ FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
+ FB_SYNC_CLK_IDLE_EN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 640x480 @ 60 Hz */
+ .name = "NEC-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 38255,
+ .left_margin = 144,
+ .right_margin = 0,
+ .upper_margin = 34,
+ .lower_margin = 40,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* NTSC TV output */
+ .name = "TV-NTSC",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 37538,
+ .left_margin = 38,
+ .right_margin = 858 - 640 - 38 - 3,
+ .upper_margin = 36,
+ .lower_margin = 518 - 480 - 36 - 1,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* PAL TV output */
+ .name = "TV-PAL",
+ .refresh = 50,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 37538,
+ .left_margin = 38,
+ .right_margin = 960 - 640 - 38 - 32,
+ .upper_margin = 32,
+ .lower_margin = 555 - 480 - 32 - 3,
+ .hsync_len = 32,
+ .vsync_len = 3,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* TV output VGA mode, 640x480 @ 65 Hz */
+ .name = "TV-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 40574,
+ .left_margin = 35,
+ .right_margin = 45,
+ .upper_margin = 9,
+ .lower_margin = 1,
+ .hsync_len = 46,
+ .vsync_len = 5,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+struct mx3fb_data {
+ struct fb_info *fbi;
+ int backlight_level;
+ void __iomem *reg_base;
+ spinlock_t lock;
+ struct device *dev;
+
+ uint32_t h_start_width;
+ uint32_t v_start_width;
+};
+
+struct dma_chan_request {
+ struct mx3fb_data *mx3fb;
+ enum ipu_channel id;
+};
+
+/* MX3 specific framebuffer information. */
+struct mx3fb_info {
+ int blank;
+ enum ipu_channel ipu_ch;
+ uint32_t cur_ipu_buf;
+
+ u32 pseudo_palette[16];
+
+ struct completion flip_cmpl;
+ struct mutex mutex; /* Protects fb-ops */
+ struct mx3fb_data *mx3fb;
+ struct idmac_channel *idmac_channel;
+ struct dma_async_tx_descriptor *txd;
+ dma_cookie_t cookie;
+ struct scatterlist sg[2];
+
+ u32 sync; /* preserve var->sync flags */
+};
+
+static void mx3fb_dma_done(void *);
+
+/* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */
+static const char *fb_mode;
+static unsigned long default_bpp = 16;
+
+static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg)
+{
+ return __raw_readl(mx3fb->reg_base + reg);
+}
+
+static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg)
+{
+ __raw_writel(value, mx3fb->reg_base + reg);
+}
+
+static const uint32_t di_mappings[] = {
+ 0x1600AAAA, 0x00E05555, 0x00070000, 3, /* RGB888 */
+ 0x0005000F, 0x000B000F, 0x0011000F, 1, /* RGB666 */
+ 0x0011000F, 0x000B000F, 0x0005000F, 1, /* BGR666 */
+ 0x0004003F, 0x000A000F, 0x000F003F, 1 /* RGB565 */
+};
+
+static void sdc_fb_init(struct mx3fb_info *fbi)
+{
+ struct mx3fb_data *mx3fb = fbi->mx3fb;
+ uint32_t reg;
+
+ reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+
+ mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF);
+}
+
+/* Returns enabled flag before uninit */
+static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi)
+{
+ struct mx3fb_data *mx3fb = fbi->mx3fb;
+ uint32_t reg;
+
+ reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+
+ mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF);
+
+ return reg & SDC_COM_BG_EN;
+}
+
+static void sdc_enable_channel(struct mx3fb_info *mx3_fbi)
+{
+ struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+ struct idmac_channel *ichan = mx3_fbi->idmac_channel;
+ struct dma_chan *dma_chan = &ichan->dma_chan;
+ unsigned long flags;
+ dma_cookie_t cookie;
+
+ dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi,
+ to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg);
+
+ /* This enables the channel */
+ if (mx3_fbi->cookie < 0) {
+ mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan,
+ &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
+ if (!mx3_fbi->txd) {
+ dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n",
+ dma_chan->chan_id);
+ return;
+ }
+
+ mx3_fbi->txd->callback_param = mx3_fbi->txd;
+ mx3_fbi->txd->callback = mx3fb_dma_done;
+
+ cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd);
+ dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__,
+ mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
+ } else {
+ if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) {
+ dev_err(mx3fb->dev, "Cannot enable channel %d\n",
+ dma_chan->chan_id);
+ return;
+ }
+
+ /* Just re-activate the same buffer */
+ dma_async_issue_pending(dma_chan);
+ cookie = mx3_fbi->cookie;
+ dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__,
+ mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
+ }
+
+ if (cookie >= 0) {
+ spin_lock_irqsave(&mx3fb->lock, flags);
+ sdc_fb_init(mx3_fbi);
+ mx3_fbi->cookie = cookie;
+ spin_unlock_irqrestore(&mx3fb->lock, flags);
+ }
+
+ /*
+ * Attention! Without this msleep the channel keeps generating
+ * interrupts. Next sdc_set_brightness() is going to be called
+ * from mx3fb_blank().
+ */
+ msleep(2);
+}
+
+static void sdc_disable_channel(struct mx3fb_info *mx3_fbi)
+{
+ struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+ uint32_t enabled;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mx3fb->lock, flags);
+
+ enabled = sdc_fb_uninit(mx3_fbi);
+
+ spin_unlock_irqrestore(&mx3fb->lock, flags);
+
+ mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan);
+ mx3_fbi->txd = NULL;
+ mx3_fbi->cookie = -EINVAL;
+}
+
+/**
+ * sdc_set_window_pos() - set window position of the respective plane.
+ * @mx3fb: mx3fb context.
+ * @channel: IPU DMAC channel ID.
+ * @x_pos: X coordinate relative to the top left corner to place window at.
+ * @y_pos: Y coordinate relative to the top left corner to place window at.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel,
+ int16_t x_pos, int16_t y_pos)
+{
+ x_pos += mx3fb->h_start_width;
+ y_pos += mx3fb->v_start_width;
+
+ if (channel != IDMAC_SDC_0)
+ return -EINVAL;
+
+ mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS);
+ return 0;
+}
+
+/**
+ * sdc_init_panel() - initialize a synchronous LCD panel.
+ * @mx3fb: mx3fb context.
+ * @panel: panel type.
+ * @pixel_clk: desired pixel clock frequency in Hz.
+ * @width: width of panel in pixels.
+ * @height: height of panel in pixels.
+ * @pixel_fmt: pixel format of buffer as FOURCC ASCII code.
+ * @h_start_width: number of pixel clocks between the HSYNC signal pulse
+ * and the start of valid data.
+ * @h_sync_width: width of the HSYNC signal in units of pixel clocks.
+ * @h_end_width: number of pixel clocks between the end of valid data
+ * and the HSYNC signal for next line.
+ * @v_start_width: number of lines between the VSYNC signal pulse and the
+ * start of valid data.
+ * @v_sync_width: width of the VSYNC signal in units of lines
+ * @v_end_width: number of lines between the end of valid data and the
+ * VSYNC signal for next frame.
+ * @sig: bitfield of signal polarities for LCD interface.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
+ uint32_t pixel_clk,
+ uint16_t width, uint16_t height,
+ enum pixel_fmt pixel_fmt,
+ uint16_t h_start_width, uint16_t h_sync_width,
+ uint16_t h_end_width, uint16_t v_start_width,
+ uint16_t v_sync_width, uint16_t v_end_width,
+ struct ipu_di_signal_cfg sig)
+{
+ unsigned long lock_flags;
+ uint32_t reg;
+ uint32_t old_conf;
+ uint32_t div;
+ struct clk *ipu_clk;
+
+ dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height);
+
+ if (v_sync_width == 0 || h_sync_width == 0)
+ return -EINVAL;
+
+ /* Init panel size and blanking periods */
+ reg = ((uint32_t) (h_sync_width - 1) << 26) |
+ ((uint32_t) (width + h_start_width + h_end_width - 1) << 16);
+ mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF);
+
+#ifdef DEBUG
+ printk(KERN_CONT " hor_conf %x,", reg);
+#endif
+
+ reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L |
+ ((uint32_t) (height + v_start_width + v_end_width - 1) << 16);
+ mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF);
+
+#ifdef DEBUG
+ printk(KERN_CONT " ver_conf %x\n", reg);
+#endif
+
+ mx3fb->h_start_width = h_start_width;
+ mx3fb->v_start_width = v_start_width;
+
+ switch (panel) {
+ case IPU_PANEL_SHARP_TFT:
+ mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1);
+ mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2);
+ mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF);
+ break;
+ case IPU_PANEL_TFT:
+ mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Init clocking */
+
+ /*
+ * Calculate divider: fractional part is 4 bits so simply multiple by
+ * 24 to get fractional part, as long as we stay under ~250MHz and on
+ * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz
+ */
+ dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk);
+
+ ipu_clk = clk_get(mx3fb->dev, "ipu_clk");
+ div = clk_get_rate(ipu_clk) * 16 / pixel_clk;
+ clk_put(ipu_clk);
+
+ if (div < 0x40) { /* Divider less than 4 */
+ dev_dbg(mx3fb->dev,
+ "InitPanel() - Pixel clock divider less than 4\n");
+ div = 0x40;
+ }
+
+ spin_lock_irqsave(&mx3fb->lock, lock_flags);
+
+ /*
+ * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits
+ * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing
+ * debug. DISP3_IF_CLK_UP_WR is 0
+ */
+ mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF);
+
+ /* DI settings */
+ old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF;
+ old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT |
+ sig.clksel_en << DI_D3_CLK_SEL_SHIFT |
+ sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT;
+ mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF);
+
+ old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF;
+ old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT |
+ sig.clk_pol << DI_D3_CLK_POL_SHIFT |
+ sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
+ sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
+ sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
+ mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL);
+
+ switch (pixel_fmt) {
+ case IPU_PIX_FMT_RGB24:
+ mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP);
+ mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
+ ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC);
+ break;
+ case IPU_PIX_FMT_RGB666:
+ mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP);
+ mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
+ ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC);
+ break;
+ case IPU_PIX_FMT_BGR666:
+ mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP);
+ mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
+ ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC);
+ break;
+ default:
+ mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP);
+ mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
+ ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC);
+ break;
+ }
+
+ spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
+
+ dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n",
+ mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF));
+ dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n",
+ mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL));
+ dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n",
+ mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF));
+
+ return 0;
+}
+
+/**
+ * sdc_set_color_key() - set the transparent color key for SDC graphic plane.
+ * @mx3fb: mx3fb context.
+ * @channel: IPU DMAC channel ID.
+ * @enable: boolean to enable or disable color keyl.
+ * @color_key: 24-bit RGB color to use as transparent color key.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel,
+ bool enable, uint32_t color_key)
+{
+ uint32_t reg, sdc_conf;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&mx3fb->lock, lock_flags);
+
+ sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+ if (channel == IDMAC_SDC_0)
+ sdc_conf &= ~SDC_COM_GWSEL;
+ else
+ sdc_conf |= SDC_COM_GWSEL;
+
+ if (enable) {
+ reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L;
+ mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL),
+ SDC_GW_CTRL);
+
+ sdc_conf |= SDC_COM_KEY_COLOR_G;
+ } else {
+ sdc_conf &= ~SDC_COM_KEY_COLOR_G;
+ }
+ mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF);
+
+ spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
+
+ return 0;
+}
+
+/**
+ * sdc_set_global_alpha() - set global alpha blending modes.
+ * @mx3fb: mx3fb context.
+ * @enable: boolean to enable or disable global alpha blending. If disabled,
+ * per pixel blending is used.
+ * @alpha: global alpha value.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha)
+{
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&mx3fb->lock, lock_flags);
+
+ if (enable) {
+ reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL;
+ mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL);
+
+ reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+ mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF);
+ } else {
+ reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+ mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF);
+ }
+
+ spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
+
+ return 0;
+}
+
+static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value)
+{
+ /* This might be board-specific */
+ mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL);
+ return;
+}
+
+static uint32_t bpp_to_pixfmt(int bpp)
+{
+ uint32_t pixfmt = 0;
+ switch (bpp) {
+ case 24:
+ pixfmt = IPU_PIX_FMT_BGR24;
+ break;
+ case 32:
+ pixfmt = IPU_PIX_FMT_BGR32;
+ break;
+ case 16:
+ pixfmt = IPU_PIX_FMT_RGB565;
+ break;
+ }
+ return pixfmt;
+}
+
+static int mx3fb_blank(int blank, struct fb_info *fbi);
+static int mx3fb_map_video_memory(struct fb_info *fbi);
+static int mx3fb_unmap_video_memory(struct fb_info *fbi);
+
+/**
+ * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings.
+ * @info: framebuffer information pointer
+ * @return: 0 on success or negative error code on failure.
+ */
+static int mx3fb_set_fix(struct fb_info *fbi)
+{
+ struct fb_fix_screeninfo *fix = &fbi->fix;
+ struct fb_var_screeninfo *var = &fbi->var;
+
+ strncpy(fix->id, "DISP3 BG", 8);
+
+ fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->accel = FB_ACCEL_NONE;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->xpanstep = 1;
+ fix->ypanstep = 1;
+
+ return 0;
+}
+
+static void mx3fb_dma_done(void *arg)
+{
+ struct idmac_tx_desc *tx_desc = to_tx_desc(arg);
+ struct dma_chan *chan = tx_desc->txd.chan;
+ struct idmac_channel *ichannel = to_idmac_chan(chan);
+ struct mx3fb_data *mx3fb = ichannel->client;
+ struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
+
+ dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq);
+
+ /* We only need one interrupt, it will be re-enabled as needed */
+ disable_irq(ichannel->eof_irq);
+
+ complete(&mx3_fbi->flip_cmpl);
+}
+
+/**
+ * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
+ * @fbi: framebuffer information pointer.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int mx3fb_set_par(struct fb_info *fbi)
+{
+ u32 mem_len;
+ struct ipu_di_signal_cfg sig_cfg;
+ enum ipu_panel mode = IPU_PANEL_TFT;
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+ struct idmac_channel *ichan = mx3_fbi->idmac_channel;
+ struct idmac_video_param *video = &ichan->params.video;
+ struct scatterlist *sg = mx3_fbi->sg;
+ size_t screen_size;
+
+ dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+');
+
+ mutex_lock(&mx3_fbi->mutex);
+
+ /* Total cleanup */
+ if (mx3_fbi->txd)
+ sdc_disable_channel(mx3_fbi);
+
+ mx3fb_set_fix(fbi);
+
+ mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
+ if (mem_len > fbi->fix.smem_len) {
+ if (fbi->fix.smem_start)
+ mx3fb_unmap_video_memory(fbi);
+
+ fbi->fix.smem_len = mem_len;
+ if (mx3fb_map_video_memory(fbi) < 0) {
+ mutex_unlock(&mx3_fbi->mutex);
+ return -ENOMEM;
+ }
+ }
+
+ screen_size = fbi->fix.line_length * fbi->var.yres;
+
+ sg_init_table(&sg[0], 1);
+ sg_init_table(&sg[1], 1);
+
+ sg_dma_address(&sg[0]) = fbi->fix.smem_start;
+ sg_set_page(&sg[0], virt_to_page(fbi->screen_base),
+ fbi->fix.smem_len,
+ offset_in_page(fbi->screen_base));
+
+ if (mx3_fbi->ipu_ch == IDMAC_SDC_0) {
+ memset(&sig_cfg, 0, sizeof(sig_cfg));
+ if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
+ sig_cfg.Hsync_pol = true;
+ if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
+ sig_cfg.Vsync_pol = true;
+ if (fbi->var.sync & FB_SYNC_CLK_INVERT)
+ sig_cfg.clk_pol = true;
+ if (fbi->var.sync & FB_SYNC_DATA_INVERT)
+ sig_cfg.data_pol = true;
+ if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH)
+ sig_cfg.enable_pol = true;
+ if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
+ sig_cfg.clkidle_en = true;
+ if (fbi->var.sync & FB_SYNC_CLK_SEL_EN)
+ sig_cfg.clksel_en = true;
+ if (fbi->var.sync & FB_SYNC_SHARP_MODE)
+ mode = IPU_PANEL_SHARP_TFT;
+
+ dev_dbg(fbi->device, "pixclock = %ul Hz\n",
+ (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
+
+ if (sdc_init_panel(mx3fb, mode,
+ (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
+ fbi->var.xres, fbi->var.yres,
+ (fbi->var.sync & FB_SYNC_SWAP_RGB) ?
+ IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666,
+ fbi->var.left_margin,
+ fbi->var.hsync_len,
+ fbi->var.right_margin +
+ fbi->var.hsync_len,
+ fbi->var.upper_margin,
+ fbi->var.vsync_len,
+ fbi->var.lower_margin +
+ fbi->var.vsync_len, sig_cfg) != 0) {
+ mutex_unlock(&mx3_fbi->mutex);
+ dev_err(fbi->device,
+ "mx3fb: Error initializing panel.\n");
+ return -EINVAL;
+ }
+ }
+
+ sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0);
+
+ mx3_fbi->cur_ipu_buf = 0;
+
+ video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel);
+ video->out_width = fbi->var.xres;
+ video->out_height = fbi->var.yres;
+ video->out_stride = fbi->var.xres_virtual;
+
+ if (mx3_fbi->blank == FB_BLANK_UNBLANK)
+ sdc_enable_channel(mx3_fbi);
+
+ mutex_unlock(&mx3_fbi->mutex);
+
+ return 0;
+}
+
+/**
+ * mx3fb_check_var() - check and adjust framebuffer variable parameters.
+ * @var: framebuffer variable parameters
+ * @fbi: framebuffer information pointer
+ */
+static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
+{
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ u32 vtotal;
+ u32 htotal;
+
+ dev_dbg(fbi->device, "%s\n", __func__);
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+
+ if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
+ (var->bits_per_pixel != 16))
+ var->bits_per_pixel = default_bpp;
+
+ switch (var->bits_per_pixel) {
+ case 16:
+ var->red.length = 5;
+ var->red.offset = 11;
+ var->red.msb_right = 0;
+
+ var->green.length = 6;
+ var->green.offset = 5;
+ var->green.msb_right = 0;
+
+ var->blue.length = 5;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ break;
+ case 24:
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ break;
+ case 32:
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 8;
+ var->transp.offset = 24;
+ var->transp.msb_right = 0;
+ break;
+ }
+
+ if (var->pixclock < 1000) {
+ htotal = var->xres + var->right_margin + var->hsync_len +
+ var->left_margin;
+ vtotal = var->yres + var->lower_margin + var->vsync_len +
+ var->upper_margin;
+ var->pixclock = (vtotal * htotal * 6UL) / 100UL;
+ var->pixclock = KHZ2PICOS(var->pixclock);
+ dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n",
+ var->pixclock);
+ }
+
+ var->height = -1;
+ var->width = -1;
+ var->grayscale = 0;
+
+ /* Preserve sync flags */
+ var->sync |= mx3_fbi->sync;
+ mx3_fbi->sync |= var->sync;
+
+ return 0;
+}
+
+static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int mx3fb_setcolreg(unsigned int regno, unsigned int red,
+ unsigned int green, unsigned int blue,
+ unsigned int trans, struct fb_info *fbi)
+{
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ u32 val;
+ int ret = 1;
+
+ dev_dbg(fbi->device, "%s\n", __func__);
+
+ mutex_lock(&mx3_fbi->mutex);
+ /*
+ * If greyscale is true, then we convert the RGB value
+ * to greyscale no matter what visual we are using.
+ */
+ if (fbi->var.grayscale)
+ red = green = blue = (19595 * red + 38470 * green +
+ 7471 * blue) >> 16;
+ switch (fbi->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /*
+ * 16-bit True Colour. We encode the RGB value
+ * according to the RGB bitfield information.
+ */
+ if (regno < 16) {
+ u32 *pal = fbi->pseudo_palette;
+
+ val = chan_to_field(red, &fbi->var.red);
+ val |= chan_to_field(green, &fbi->var.green);
+ val |= chan_to_field(blue, &fbi->var.blue);
+
+ pal[regno] = val;
+
+ ret = 0;
+ }
+ break;
+
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ break;
+ }
+ mutex_unlock(&mx3_fbi->mutex);
+
+ return ret;
+}
+
+/**
+ * mx3fb_blank() - blank the display.
+ */
+static int mx3fb_blank(int blank, struct fb_info *fbi)
+{
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+
+ dev_dbg(fbi->device, "%s\n", __func__);
+
+ dev_dbg(fbi->device, "blank = %d\n", blank);
+
+ if (mx3_fbi->blank == blank)
+ return 0;
+
+ mutex_lock(&mx3_fbi->mutex);
+ mx3_fbi->blank = blank;
+
+ switch (blank) {
+ case FB_BLANK_POWERDOWN:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ sdc_disable_channel(mx3_fbi);
+ sdc_set_brightness(mx3fb, 0);
+ break;
+ case FB_BLANK_UNBLANK:
+ sdc_enable_channel(mx3_fbi);
+ sdc_set_brightness(mx3fb, mx3fb->backlight_level);
+ break;
+ }
+ mutex_unlock(&mx3_fbi->mutex);
+
+ return 0;
+}
+
+/**
+ * mx3fb_pan_display() - pan or wrap the display
+ * @var: variable screen buffer information.
+ * @info: framebuffer information pointer.
+ *
+ * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+static int mx3fb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *fbi)
+{
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ u32 y_bottom;
+ unsigned long base;
+ off_t offset;
+ dma_cookie_t cookie;
+ struct scatterlist *sg = mx3_fbi->sg;
+ struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan;
+ struct dma_async_tx_descriptor *txd;
+ int ret;
+
+ dev_dbg(fbi->device, "%s [%c]\n", __func__,
+ list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+');
+
+ if (var->xoffset > 0) {
+ dev_dbg(fbi->device, "x panning not supported\n");
+ return -EINVAL;
+ }
+
+ if (fbi->var.xoffset == var->xoffset &&
+ fbi->var.yoffset == var->yoffset)
+ return 0; /* No change, do nothing */
+
+ y_bottom = var->yoffset;
+
+ if (!(var->vmode & FB_VMODE_YWRAP))
+ y_bottom += var->yres;
+
+ if (y_bottom > fbi->var.yres_virtual)
+ return -EINVAL;
+
+ mutex_lock(&mx3_fbi->mutex);
+
+ offset = (var->yoffset * var->xres_virtual + var->xoffset) *
+ (var->bits_per_pixel / 8);
+ base = fbi->fix.smem_start + offset;
+
+ dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
+ mx3_fbi->cur_ipu_buf, base);
+
+ /*
+ * We enable the End of Frame interrupt, which will free a tx-descriptor,
+ * which we will need for the next device_prep_slave_sg(). The
+ * IRQ-handler will disable the IRQ again.
+ */
+ init_completion(&mx3_fbi->flip_cmpl);
+ enable_irq(mx3_fbi->idmac_channel->eof_irq);
+
+ ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10);
+ if (ret <= 0) {
+ mutex_unlock(&mx3_fbi->mutex);
+ dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ?
+ "user interrupt" : "timeout");
+ return ret ? : -ETIMEDOUT;
+ }
+
+ mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf;
+
+ sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base;
+ sg_set_page(&sg[mx3_fbi->cur_ipu_buf],
+ virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len,
+ offset_in_page(fbi->screen_base + offset));
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg +
+ mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
+ if (!txd) {
+ dev_err(fbi->device,
+ "Error preparing a DMA transaction descriptor.\n");
+ mutex_unlock(&mx3_fbi->mutex);
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = mx3fb_dma_done;
+
+ /*
+ * Emulate original mx3fb behaviour: each new call to idmac_tx_submit()
+ * should switch to another buffer
+ */
+ cookie = txd->tx_submit(txd);
+ dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie);
+ if (cookie < 0) {
+ dev_err(fbi->device,
+ "Error updating SDC buf %d to address=0x%08lX\n",
+ mx3_fbi->cur_ipu_buf, base);
+ mutex_unlock(&mx3_fbi->mutex);
+ return -EIO;
+ }
+
+ if (mx3_fbi->txd)
+ async_tx_ack(mx3_fbi->txd);
+ mx3_fbi->txd = txd;
+
+ fbi->var.xoffset = var->xoffset;
+ fbi->var.yoffset = var->yoffset;
+
+ if (var->vmode & FB_VMODE_YWRAP)
+ fbi->var.vmode |= FB_VMODE_YWRAP;
+ else
+ fbi->var.vmode &= ~FB_VMODE_YWRAP;
+
+ mutex_unlock(&mx3_fbi->mutex);
+
+ dev_dbg(fbi->device, "Update complete\n");
+
+ return 0;
+}
+
+/*
+ * This structure contains the pointers to the control functions that are
+ * invoked by the core framebuffer driver to perform operations like
+ * blitting, rectangle filling, copy regions and cursor definition.
+ */
+static struct fb_ops mx3fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_set_par = mx3fb_set_par,
+ .fb_check_var = mx3fb_check_var,
+ .fb_setcolreg = mx3fb_setcolreg,
+ .fb_pan_display = mx3fb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_blank = mx3fb_blank,
+};
+
+#ifdef CONFIG_PM
+/*
+ * Power management hooks. Note that we won't be called from IRQ context,
+ * unlike the blank functions above, so we may sleep.
+ */
+
+/*
+ * Suspends the framebuffer and blanks the screen. Power management support
+ */
+static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct mx3fb_data *drv_data = platform_get_drvdata(pdev);
+ struct mx3fb_info *mx3_fbi = drv_data->fbi->par;
+
+ acquire_console_sem();
+ fb_set_suspend(drv_data->fbi, 1);
+ release_console_sem();
+
+ if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
+ sdc_disable_channel(mx3_fbi);
+ sdc_set_brightness(mx3fb, 0);
+
+ }
+ return 0;
+}
+
+/*
+ * Resumes the framebuffer and unblanks the screen. Power management support
+ */
+static int mx3fb_resume(struct platform_device *pdev)
+{
+ struct mx3fb_data *drv_data = platform_get_drvdata(pdev);
+ struct mx3fb_info *mx3_fbi = drv_data->fbi->par;
+
+ if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
+ sdc_enable_channel(mx3_fbi);
+ sdc_set_brightness(mx3fb, drv_data->backlight_level);
+ }
+
+ acquire_console_sem();
+ fb_set_suspend(drv_data->fbi, 0);
+ release_console_sem();
+
+ return 0;
+}
+#else
+#define mx3fb_suspend NULL
+#define mx3fb_resume NULL
+#endif
+
+/*
+ * Main framebuffer functions
+ */
+
+/**
+ * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer.
+ * @fbi: framebuffer information pointer
+ * @return: Error code indicating success or failure
+ *
+ * This buffer is remapped into a non-cached, non-buffered, memory region to
+ * allow palette and pixel writes to occur without flushing the cache. Once this
+ * area is remapped, all virtual memory access to the video memory should occur
+ * at the new region.
+ */
+static int mx3fb_map_video_memory(struct fb_info *fbi)
+{
+ int retval = 0;
+ dma_addr_t addr;
+
+ fbi->screen_base = dma_alloc_writecombine(fbi->device,
+ fbi->fix.smem_len,
+ &addr, GFP_DMA);
+
+ if (!fbi->screen_base) {
+ dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n",
+ fbi->fix.smem_len);
+ retval = -EBUSY;
+ goto err0;
+ }
+
+ fbi->fix.smem_start = addr;
+
+ dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n",
+ (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
+
+ fbi->screen_size = fbi->fix.smem_len;
+
+ /* Clear the screen */
+ memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
+
+ return 0;
+
+err0:
+ fbi->fix.smem_len = 0;
+ fbi->fix.smem_start = 0;
+ fbi->screen_base = NULL;
+ return retval;
+}
+
+/**
+ * mx3fb_unmap_video_memory() - de-allocate frame buffer memory.
+ * @fbi: framebuffer information pointer
+ * @return: error code indicating success or failure
+ */
+static int mx3fb_unmap_video_memory(struct fb_info *fbi)
+{
+ dma_free_writecombine(fbi->device, fbi->fix.smem_len,
+ fbi->screen_base, fbi->fix.smem_start);
+
+ fbi->screen_base = 0;
+ fbi->fix.smem_start = 0;
+ fbi->fix.smem_len = 0;
+ return 0;
+}
+
+/**
+ * mx3fb_init_fbinfo() - initialize framebuffer information object.
+ * @return: initialized framebuffer structure.
+ */
+static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops)
+{
+ struct fb_info *fbi;
+ struct mx3fb_info *mx3fbi;
+ int ret;
+
+ /* Allocate sufficient memory for the fb structure */
+ fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev);
+ if (!fbi)
+ return NULL;
+
+ mx3fbi = fbi->par;
+ mx3fbi->cookie = -EINVAL;
+ mx3fbi->cur_ipu_buf = 0;
+
+ fbi->var.activate = FB_ACTIVATE_NOW;
+
+ fbi->fbops = ops;
+ fbi->flags = FBINFO_FLAG_DEFAULT;
+ fbi->pseudo_palette = mx3fbi->pseudo_palette;
+
+ mutex_init(&mx3fbi->mutex);
+
+ /* Allocate colormap */
+ ret = fb_alloc_cmap(&fbi->cmap, 16, 0);
+ if (ret < 0) {
+ framebuffer_release(fbi);
+ return NULL;
+ }
+
+ return fbi;
+}
+
+static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
+{
+ struct device *dev = mx3fb->dev;
+ struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data;
+ const char *name = mx3fb_pdata->name;
+ unsigned int irq;
+ struct fb_info *fbi;
+ struct mx3fb_info *mx3fbi;
+ const struct fb_videomode *mode;
+ int ret, num_modes;
+
+ ichan->client = mx3fb;
+ irq = ichan->eof_irq;
+
+ if (ichan->dma_chan.chan_id != IDMAC_SDC_0)
+ return -EINVAL;
+
+ fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops);
+ if (!fbi)
+ return -ENOMEM;
+
+ if (!fb_mode)
+ fb_mode = name;
+
+ if (!fb_mode) {
+ ret = -EINVAL;
+ goto emode;
+ }
+
+ if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) {
+ mode = mx3fb_pdata->mode;
+ num_modes = mx3fb_pdata->num_modes;
+ } else {
+ mode = mx3fb_modedb;
+ num_modes = ARRAY_SIZE(mx3fb_modedb);
+ }
+
+ if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode,
+ num_modes, NULL, default_bpp)) {
+ ret = -EBUSY;
+ goto emode;
+ }
+
+ fb_videomode_to_modelist(mode, num_modes, &fbi->modelist);
+
+ /* Default Y virtual size is 2x panel size */
+ fbi->var.yres_virtual = fbi->var.yres * 2;
+
+ mx3fb->fbi = fbi;
+
+ /* set Display Interface clock period */
+ mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER);
+ /* Might need to trigger HSP clock change - see 44.3.3.8.5 */
+
+ sdc_set_brightness(mx3fb, 255);
+ sdc_set_global_alpha(mx3fb, true, 0xFF);
+ sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0);
+
+ mx3fbi = fbi->par;
+ mx3fbi->idmac_channel = ichan;
+ mx3fbi->ipu_ch = ichan->dma_chan.chan_id;
+ mx3fbi->mx3fb = mx3fb;
+ mx3fbi->blank = FB_BLANK_NORMAL;
+
+ init_completion(&mx3fbi->flip_cmpl);
+ disable_irq(ichan->eof_irq);
+ dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);
+ ret = mx3fb_set_par(fbi);
+ if (ret < 0)
+ goto esetpar;
+
+ mx3fb_blank(FB_BLANK_UNBLANK, fbi);
+
+ dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode);
+
+ ret = register_framebuffer(fbi);
+ if (ret < 0)
+ goto erfb;
+
+ return 0;
+
+erfb:
+esetpar:
+emode:
+ fb_dealloc_cmap(&fbi->cmap);
+ framebuffer_release(fbi);
+
+ return ret;
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ struct dma_chan_request *rq = arg;
+ struct device *dev;
+ struct mx3fb_platform_data *mx3fb_pdata;
+
+ if (!rq)
+ return false;
+
+ dev = rq->mx3fb->dev;
+ mx3fb_pdata = dev->platform_data;
+
+ return rq->id == chan->chan_id &&
+ mx3fb_pdata->dma_dev == chan->device->dev;
+}
+
+static void release_fbi(struct fb_info *fbi)
+{
+ mx3fb_unmap_video_memory(fbi);
+
+ fb_dealloc_cmap(&fbi->cmap);
+
+ unregister_framebuffer(fbi);
+ framebuffer_release(fbi);
+}
+
+static int mx3fb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int ret;
+ struct resource *sdc_reg;
+ struct mx3fb_data *mx3fb;
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+ struct dma_chan_request rq;
+
+ /*
+ * Display Interface (DI) and Synchronous Display Controller (SDC)
+ * registers
+ */
+ sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!sdc_reg)
+ return -EINVAL;
+
+ mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL);
+ if (!mx3fb)
+ return -ENOMEM;
+
+ spin_lock_init(&mx3fb->lock);
+
+ mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg));
+ if (!mx3fb->reg_base) {
+ ret = -ENOMEM;
+ goto eremap;
+ }
+
+ pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end,
+ mx3fb->reg_base);
+
+ /* IDMAC interface */
+ dmaengine_get();
+
+ mx3fb->dev = dev;
+ platform_set_drvdata(pdev, mx3fb);
+
+ rq.mx3fb = mx3fb;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+ rq.id = IDMAC_SDC_0;
+ chan = dma_request_channel(mask, chan_filter, &rq);
+ if (!chan) {
+ ret = -EBUSY;
+ goto ersdc0;
+ }
+
+ ret = init_fb_chan(mx3fb, to_idmac_chan(chan));
+ if (ret < 0)
+ goto eisdc0;
+
+ mx3fb->backlight_level = 255;
+
+ return 0;
+
+eisdc0:
+ dma_release_channel(chan);
+ersdc0:
+ dmaengine_put();
+ iounmap(mx3fb->reg_base);
+eremap:
+ kfree(mx3fb);
+ dev_err(dev, "mx3fb: failed to register fb\n");
+ return ret;
+}
+
+static int mx3fb_remove(struct platform_device *dev)
+{
+ struct mx3fb_data *mx3fb = platform_get_drvdata(dev);
+ struct fb_info *fbi = mx3fb->fbi;
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ struct dma_chan *chan;
+
+ chan = &mx3_fbi->idmac_channel->dma_chan;
+ release_fbi(fbi);
+
+ dma_release_channel(chan);
+ dmaengine_put();
+
+ iounmap(mx3fb->reg_base);
+ kfree(mx3fb);
+ return 0;
+}
+
+static struct platform_driver mx3fb_driver = {
+ .driver = {
+ .name = MX3FB_NAME,
+ },
+ .probe = mx3fb_probe,
+ .remove = mx3fb_remove,
+ .suspend = mx3fb_suspend,
+ .resume = mx3fb_resume,
+};
+
+/*
+ * Parse user specified options (`video=mx3fb:')
+ * example:
+ * video=mx3fb:bpp=16
+ */
+static int mx3fb_setup(void)
+{
+#ifndef MODULE
+ char *opt, *options = NULL;
+
+ if (fb_get_options("mx3fb", &options))
+ return -ENODEV;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+ if (!strncmp(opt, "bpp=", 4))
+ default_bpp = simple_strtoul(opt + 4, NULL, 0);
+ else
+ fb_mode = opt;
+ }
+#endif
+
+ return 0;
+}
+
+static int __init mx3fb_init(void)
+{
+ int ret = mx3fb_setup();
+
+ if (ret < 0)
+ return ret;
+
+ ret = platform_driver_register(&mx3fb_driver);
+ return ret;
+}
+
+static void __exit mx3fb_exit(void)
+{
+ platform_driver_unregister(&mx3fb_driver);
+}
+
+module_init(mx3fb_init);
+module_exit(mx3fb_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MX3 framebuffer driver");
+MODULE_ALIAS("platform:" MX3FB_NAME);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 6fd7cb8f9b8..6aaddb4f678 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -87,7 +87,6 @@ static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name,
strcpy(chan->adapter.name, name);
chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_NVIDIA;
chan->adapter.class = i2c_class;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pci_dev->dev;
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index 6e2ea751876..ab394925667 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -800,14 +800,14 @@ static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode,
/* FIXME:
* According to errata some platforms have a clock rate limitiation
*/
- lcdc.lcd_ck = clk_get(NULL, "lcd_ck");
+ lcdc.lcd_ck = clk_get(fbdev->dev, "lcd_ck");
if (IS_ERR(lcdc.lcd_ck)) {
dev_err(fbdev->dev, "unable to access LCD clock\n");
r = PTR_ERR(lcdc.lcd_ck);
goto fail0;
}
- tc_ck = clk_get(NULL, "tc_ck");
+ tc_ck = clk_get(fbdev->dev, "tc_ck");
if (IS_ERR(tc_ck)) {
dev_err(fbdev->dev, "unable to access TC clock\n");
r = PTR_ERR(tc_ck);
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index 3a3f80f6521..0573ec685a5 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -151,7 +151,7 @@ static int __init pmagbafb_probe(struct device *dev)
info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
if (!info) {
- printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
return -ENOMEM;
}
@@ -160,7 +160,7 @@ static int __init pmagbafb_probe(struct device *dev)
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
printk(KERN_ERR "%s: Cannot allocate color map\n",
- dev->bus_id);
+ dev_name(dev));
err = -ENOMEM;
goto err_alloc;
}
@@ -173,8 +173,9 @@ static int __init pmagbafb_probe(struct device *dev)
/* Request the I/O MEM resource. */
start = tdev->resource.start;
len = tdev->resource.end - start + 1;
- if (!request_mem_region(start, len, dev->bus_id)) {
- printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
+ if (!request_mem_region(start, len, dev_name(dev))) {
+ printk(KERN_ERR "%s: Cannot reserve FB region\n",
+ dev_name(dev));
err = -EBUSY;
goto err_cmap;
}
@@ -183,7 +184,7 @@ static int __init pmagbafb_probe(struct device *dev)
info->fix.mmio_start = start;
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
if (!par->mmio) {
- printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
err = -ENOMEM;
goto err_resource;
}
@@ -194,7 +195,7 @@ static int __init pmagbafb_probe(struct device *dev)
info->screen_base = ioremap_nocache(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) {
- printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
err = -ENOMEM;
goto err_mmio_map;
}
@@ -205,14 +206,14 @@ static int __init pmagbafb_probe(struct device *dev)
err = register_framebuffer(info);
if (err < 0) {
printk(KERN_ERR "%s: Cannot register framebuffer\n",
- dev->bus_id);
+ dev_name(dev));
goto err_smem_map;
}
get_device(dev);
pr_info("fb%d: %s frame buffer device at %s\n",
- info->node, info->fix.id, dev->bus_id);
+ info->node, info->fix.id, dev_name(dev));
return 0;
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 9b80597241b..98748723af9 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -258,7 +258,7 @@ static int __init pmagbbfb_probe(struct device *dev)
info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
if (!info) {
- printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
return -ENOMEM;
}
@@ -267,7 +267,7 @@ static int __init pmagbbfb_probe(struct device *dev)
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
printk(KERN_ERR "%s: Cannot allocate color map\n",
- dev->bus_id);
+ dev_name(dev));
err = -ENOMEM;
goto err_alloc;
}
@@ -280,8 +280,9 @@ static int __init pmagbbfb_probe(struct device *dev)
/* Request the I/O MEM resource. */
start = tdev->resource.start;
len = tdev->resource.end - start + 1;
- if (!request_mem_region(start, len, dev->bus_id)) {
- printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
+ if (!request_mem_region(start, len, dev_name(dev))) {
+ printk(KERN_ERR "%s: Cannot reserve FB region\n",
+ dev_name(dev));
err = -EBUSY;
goto err_cmap;
}
@@ -290,7 +291,7 @@ static int __init pmagbbfb_probe(struct device *dev)
info->fix.mmio_start = start;
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
if (!par->mmio) {
- printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
err = -ENOMEM;
goto err_resource;
}
@@ -301,7 +302,7 @@ static int __init pmagbbfb_probe(struct device *dev)
info->fix.smem_start = start + PMAGB_B_FBMEM;
par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
if (!par->smem) {
- printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
err = -ENOMEM;
goto err_mmio_map;
}
@@ -316,7 +317,7 @@ static int __init pmagbbfb_probe(struct device *dev)
err = register_framebuffer(info);
if (err < 0) {
printk(KERN_ERR "%s: Cannot register framebuffer\n",
- dev->bus_id);
+ dev_name(dev));
goto err_smem_map;
}
@@ -328,7 +329,7 @@ static int __init pmagbbfb_probe(struct device *dev)
par->osc1 / 1000, par->osc1 % 1000);
pr_info("fb%d: %s frame buffer device at %s\n",
- info->node, info->fix.id, dev->bus_id);
+ info->node, info->fix.id, dev_name(dev));
pr_info("fb%d: Osc0: %s, Osc1: %s, Osc%u selected\n",
info->node, freq0, par->osc1 ? freq1 : "disabled",
par->osc1 != 0);
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 38ac805db97..e00c1dff55d 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -1006,7 +1006,7 @@ static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
__func__, status);
return -ENXIO;
}
- dev_dbg(dev, "video:%p ioif:%lx lpar:%lx size:%lx\n",
+ dev_dbg(dev, "video:%p ioif:%lx lpar:%llx size:%lx\n",
ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
ps3fb_videomemory.size);
@@ -1133,7 +1133,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
__func__, status);
goto err;
}
- dev_dbg(&dev->core, "ddr:lpar:0x%lx\n", ddr_lpar);
+ dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar);
status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0,
&ps3fb.context_handle,
@@ -1213,7 +1213,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
dev->core.driver_data = info;
dev_info(info->device, "%s %s, using %u KiB of video memory\n",
- dev_driver_string(info->dev), info->dev->bus_id,
+ dev_driver_string(info->dev), dev_name(info->dev),
info->fix.smem_len >> 10);
task = kthread_run(ps3fbd, info, DEVICE_NAME);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 0a0fd48a856..53f8f1100e8 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -61,7 +61,7 @@
#include <mach-dreamcast/mach/sysasic.h>
#endif
-#ifdef CONFIG_SH_DMA
+#ifdef CONFIG_PVR2_DMA
#include <linux/pagemap.h>
#include <mach/dma.h>
#include <asm/dma.h>
@@ -188,7 +188,7 @@ static unsigned int is_blanked = 0; /* Is the screen blanked? */
static unsigned long pvr2fb_map;
#endif
-#ifdef CONFIG_SH_DMA
+#ifdef CONFIG_PVR2_DMA
static unsigned int shdma = PVR2_CASCADE_CHAN;
static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS;
#endif
@@ -207,7 +207,7 @@ static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id);
static int pvr2_init_cable(void);
static int pvr2_get_param(const struct pvr2_params *p, const char *s,
int val, int size);
-#ifdef CONFIG_SH_DMA
+#ifdef CONFIG_PVR2_DMA
static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
size_t count, loff_t *ppos);
#endif
@@ -218,7 +218,7 @@ static struct fb_ops pvr2fb_ops = {
.fb_blank = pvr2fb_blank,
.fb_check_var = pvr2fb_check_var,
.fb_set_par = pvr2fb_set_par,
-#ifdef CONFIG_SH_DMA
+#ifdef CONFIG_PVR2_DMA
.fb_write = pvr2fb_write,
#endif
.fb_fillrect = cfb_fillrect,
@@ -671,7 +671,7 @@ static int pvr2_init_cable(void)
return cable_type;
}
-#ifdef CONFIG_SH_DMA
+#ifdef CONFIG_PVR2_DMA
static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
size_t count, loff_t *ppos)
{
@@ -743,7 +743,7 @@ out_unmap:
return ret;
}
-#endif /* CONFIG_SH_DMA */
+#endif /* CONFIG_PVR2_DMA */
/**
* pvr2fb_common_init
@@ -893,7 +893,7 @@ static int __init pvr2fb_dc_init(void)
return -EBUSY;
}
-#ifdef CONFIG_SH_DMA
+#ifdef CONFIG_PVR2_DMA
if (request_dma(pvr2dma, "pvr2") != 0) {
free_irq(HW_EVENT_VSYNC, 0);
return -EBUSY;
@@ -915,7 +915,7 @@ static void __exit pvr2fb_dc_exit(void)
}
free_irq(HW_EVENT_VSYNC, 0);
-#ifdef CONFIG_SH_DMA
+#ifdef CONFIG_PVR2_DMA
free_dma(pvr2dma);
#endif
}
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 48ff701d3a7..2552b9f325e 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -2230,7 +2230,7 @@ static int __devexit pxafb_remove(struct platform_device *dev)
static struct platform_driver pxafb_driver = {
.probe = pxafb_probe,
- .remove = pxafb_remove,
+ .remove = __devexit_p(pxafb_remove),
.suspend = pxafb_suspend,
.resume = pxafb_resume,
.driver = {
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 783d4adffb9..574b29e9f8f 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -137,7 +137,6 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
if (chan->par) {
strcpy(chan->adapter.name, name);
chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_SAVAGE;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pcidev->dev;
chan->algo.udelay = 10;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 0e2b8fd24df..92ea0ab44ce 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -33,6 +33,8 @@ struct sh_mobile_lcdc_chan {
struct fb_info info;
dma_addr_t dma_handle;
struct fb_deferred_io defio;
+ unsigned long frame_end;
+ wait_queue_head_t frame_end_wait;
};
struct sh_mobile_lcdc_priv {
@@ -226,7 +228,10 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
{
struct sh_mobile_lcdc_priv *priv = data;
+ struct sh_mobile_lcdc_chan *ch;
unsigned long tmp;
+ int is_sub;
+ int k;
/* acknowledge interrupt */
tmp = lcdc_read(priv, _LDINTR);
@@ -234,8 +239,24 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */
lcdc_write(priv, _LDINTR, tmp);
- /* disable clocks */
- sh_mobile_lcdc_clk_off(priv);
+ /* figure out if this interrupt is for main or sub lcd */
+ is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0;
+
+ /* wake up channel and disable clocks*/
+ for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
+ ch = &priv->ch[k];
+
+ if (!ch->enabled)
+ continue;
+
+ if (is_sub == lcdc_chan_is_sublcd(ch)) {
+ ch->frame_end = 1;
+ wake_up(&ch->frame_end_wait);
+
+ sh_mobile_lcdc_clk_off(priv);
+ }
+ }
+
return IRQ_HANDLED;
}
@@ -446,22 +467,29 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
{
struct sh_mobile_lcdc_chan *ch;
struct sh_mobile_lcdc_board_cfg *board_cfg;
- unsigned long tmp;
int k;
- /* tell the board code to disable the panel */
+ /* clean up deferred io and ask board code to disable panel */
for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
ch = &priv->ch[k];
- board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->display_off)
- board_cfg->display_off(board_cfg->board_data);
- /* cleanup deferred io if SYS bus */
- tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
- if (ch->ldmt1r_value & (1 << 12) && tmp) {
+ /* deferred io mode:
+ * flush frame, and wait for frame end interrupt
+ * clean up deferred io and enable clock
+ */
+ if (ch->info.fbdefio) {
+ ch->frame_end = 0;
+ schedule_delayed_work(&ch->info.deferred_work, 0);
+ wait_event(ch->frame_end_wait, ch->frame_end);
fb_deferred_io_cleanup(&ch->info);
ch->info.fbdefio = NULL;
+ sh_mobile_lcdc_clk_on(priv);
}
+
+ board_cfg = &ch->cfg.board_cfg;
+ if (board_cfg->display_off)
+ board_cfg->display_off(board_cfg->board_data);
+
}
/* stop the lcdc */
@@ -654,6 +682,26 @@ static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
return 0;
}
+static int sh_mobile_lcdc_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ sh_mobile_lcdc_stop(platform_get_drvdata(pdev));
+ return 0;
+}
+
+static int sh_mobile_lcdc_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return sh_mobile_lcdc_start(platform_get_drvdata(pdev));
+}
+
+static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
+ .suspend = sh_mobile_lcdc_suspend,
+ .resume = sh_mobile_lcdc_resume,
+};
+
static int sh_mobile_lcdc_remove(struct platform_device *pdev);
static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
@@ -689,7 +737,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
}
error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
- pdev->dev.bus_id, priv);
+ dev_name(&pdev->dev), priv);
if (error) {
dev_err(&pdev->dev, "unable to request irq\n");
goto err1;
@@ -709,6 +757,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "unsupported interface type\n");
goto err1;
}
+ init_waitqueue_head(&priv->ch[i].frame_end_wait);
switch (pdata->ch[i].chan) {
case LCDC_CHAN_MAINLCD:
@@ -862,6 +911,7 @@ static struct platform_driver sh_mobile_lcdc_driver = {
.driver = {
.name = "sh_mobile_lcdc_fb",
.owner = THIS_MODULE,
+ .pm = &sh_mobile_lcdc_dev_pm_ops,
},
.probe = sh_mobile_lcdc_probe,
.remove = sh_mobile_lcdc_remove,
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index 7baf2dd12d5..a1eb0862255 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -751,7 +751,7 @@ static int __devinit tmiofb_probe(struct platform_device *dev)
}
retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
- dev->dev.bus_id, info);
+ dev_name(&dev->dev), info);
if (retval)
goto err_request_irq;
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 6c2d37fdd3b..74ae7589900 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -204,8 +204,11 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
} else {
v86d_started = 1;
err = cn_netlink_send(m, 0, gfp_any());
+ if (err == -ENOBUFS)
+ err = 0;
}
- }
+ } else if (err == -ENOBUFS)
+ err = 0;
if (!err && !(task->t.flags & TF_EXIT))
err = !wait_for_completion_timeout(task->done,
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index bef6b45e8a5..330aacbdec1 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -192,7 +192,7 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
drv = container_of(vp_dev->vdev.dev.driver,
struct virtio_driver, driver);
- if (drv->config_changed)
+ if (drv && drv->config_changed)
drv->config_changed(&vp_dev->vdev);
}
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index 9e1138a75e8..a411702413d 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -39,7 +39,7 @@ static u8 w1_gpio_read_bit(void *data)
{
struct w1_gpio_platform_data *pdata = data;
- return gpio_get_value(pdata->pin);
+ return gpio_get_value(pdata->pin) ? 1 : 0;
}
static int __init w1_gpio_probe(struct platform_device *pdev)
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig
index 8d0b1fb1e52..1f51366417b 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -16,6 +16,12 @@ config W1_SLAVE_SMEM
Say Y here if you want to connect 1-wire
simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire.
+config W1_SLAVE_DS2431
+ tristate "1kb EEPROM family support (DS2431)"
+ help
+ Say Y here if you want to use a 1-wire
+ 1kb EEPROM family device (DS2431)
+
config W1_SLAVE_DS2433
tristate "4kb EEPROM family support (DS2433)"
help
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile
index 990f400b6d2..f1f51f19b12 100644
--- a/drivers/w1/slaves/Makefile
+++ b/drivers/w1/slaves/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o
obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o
+obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o
obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o
obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c
index 858c16a544c..13944714882 100644
--- a/drivers/w1/slaves/w1_ds2433.c
+++ b/drivers/w1/slaves/w1_ds2433.c
@@ -156,6 +156,9 @@ out_up:
*/
static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
{
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
+ struct w1_f23_data *f23 = sl->family_data;
+#endif
u8 wrbuf[4];
u8 rdbuf[W1_PAGE_SIZE + 3];
u8 es = (addr + len - 1) & 0x1f;
@@ -196,7 +199,9 @@ static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
/* Reset the bus to wake up the EEPROM (this may not be needed) */
w1_reset_bus(sl->master);
-
+#ifdef CONFIG_W1_SLAVE_DS2433_CRC
+ f23->validcrc &= ~(1 << (addr >> W1_PAGE_BITS));
+#endif
return 0;
}
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 2c8dff9f77d..1ed3d554e37 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -115,7 +115,7 @@ static struct w1_therm_family_converter w1_therm_families[] = {
static inline int w1_DS18B20_convert_temp(u8 rom[9])
{
- s16 t = (rom[1] << 8) | rom[0];
+ int t = ((s16)rom[1] << 8) | rom[0];
t = t*1000/16;
return t;
}
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3efa12f9ee5..55f64af072a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -187,10 +187,10 @@ config EP93XX_WATCHDOG
config OMAP_WATCHDOG
tristate "OMAP Watchdog"
- depends on ARCH_OMAP16XX || ARCH_OMAP24XX
+ depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX
help
- Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog. Say 'Y' here to
- enable the OMAP1610/OMAP1710 watchdog timer.
+ Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y'
+ here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer.
config PNX4008_WATCHDOG
tristate "PNX4008 Watchdog"
@@ -406,7 +406,7 @@ config ITCO_WDT
---help---
Hardware driver for the intel TCO timer based watchdog devices.
These drivers are included in the Intel 82801 I/O Controller
- Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB
+ Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB
controller hub.
The TCO (Total Cost of Ownership) timer is a watchdog timer
@@ -940,21 +940,6 @@ config WDT
To compile this driver as a module, choose M here: the
module will be called wdt.
-config WDT_501
- bool "WDT501 features"
- depends on WDT
- help
- Saying Y here and creating a character special file /dev/temperature
- with major number 10 and minor number 131 ("man mknod") will give
- you a thermometer inside your computer: reading from
- /dev/temperature yields one byte, the temperature in degrees
- Fahrenheit. This works only if you have a WDT501P watchdog board
- installed.
-
- If you want to enable the Fan Tachometer on the WDT501P, then you
- can do this via the tachometer parameter. Only do this if you have a
- fan tachometer actually set up.
-
#
# PCI-based Watchdog Cards
#
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 3e57aa4d643..4d18c874d96 100644
--- a/drivers/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
@@ -1,7 +1,7 @@
/*
* Acquire Single Board Computer Watchdog Timer driver
*
- * Based on wdt.c. Original copyright messages:
+ * Based on wdt.c. Original copyright messages:
*
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
@@ -17,9 +17,9 @@
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*
- * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
- * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- * Can't add timeout - driver doesn't allow changing value
+ * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ * Can't add timeout - driver doesn't allow changing value
*/
/*
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index a1d7856ea6e..824d076a5cd 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -138,7 +138,9 @@ static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
void __user *argp = (void __user *)arg;
int __user *p = argp;
static struct watchdog_info ident = {
- .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
+ .options = WDIOF_KEEPALIVEPING |
+ WDIOF_SETTIMEOUT |
+ WDIOF_MAGICCLOSE,
.firmware_version = 1,
.identity = WATCHDOG_NAME,
};
@@ -259,7 +261,8 @@ static int __devinit advwdt_probe(struct platform_device *dev)
goto unreg_stop;
}
- /* Check that the heartbeat value is within it's range ; if not reset to the default */
+ /* Check that the heartbeat value is within it's range ;
+ * if not reset to the default */
if (advwdt_set_heartbeat(timeout)) {
advwdt_set_heartbeat(WATCHDOG_TIMEOUT);
printk(KERN_INFO PFX
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 2a7690ecf97..937a80fb61e 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -60,7 +60,7 @@ static void ali_start(void)
pci_read_config_dword(ali_pci, 0xCC, &val);
val &= ~0x3F; /* Mask count */
- val |= (1<<25) | ali_timeout_bits;
+ val |= (1 << 25) | ali_timeout_bits;
pci_write_config_dword(ali_pci, 0xCC, val);
spin_unlock(&ali_lock);
@@ -79,8 +79,8 @@ static void ali_stop(void)
spin_lock(&ali_lock);
pci_read_config_dword(ali_pci, 0xCC, &val);
- val &= ~0x3F; /* Mask count to zero (disabled) */
- val &= ~(1<<25);/* and for safety mask the reset enable */
+ val &= ~0x3F; /* Mask count to zero (disabled) */
+ val &= ~(1 << 25); /* and for safety mask the reset enable */
pci_write_config_dword(ali_pci, 0xCC, val);
spin_unlock(&ali_lock);
@@ -89,7 +89,7 @@ static void ali_stop(void)
/*
* ali_keepalive - send a keepalive to the watchdog
*
- * Send a keepalive to the timer (actually we restart the timer).
+ * Send a keepalive to the timer (actually we restart the timer).
*/
static void ali_keepalive(void)
@@ -109,11 +109,11 @@ static int ali_settimer(int t)
if (t < 0)
return -EINVAL;
else if (t < 60)
- ali_timeout_bits = t|(1<<6);
+ ali_timeout_bits = t|(1 << 6);
else if (t < 3600)
- ali_timeout_bits = (t/60)|(1<<7);
+ ali_timeout_bits = (t / 60)|(1 << 7);
else if (t < 18000)
- ali_timeout_bits = (t/300)|(1<<6)|(1<<7);
+ ali_timeout_bits = (t / 300)|(1 << 6)|(1 << 7);
else
return -EINVAL;
@@ -138,7 +138,7 @@ static int ali_settimer(int t)
*/
static ssize_t ali_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
+ size_t len, loff_t *ppos)
{
/* See if we got the magic character 'V' and reload the timer */
if (len) {
@@ -348,9 +348,9 @@ static int __init ali_find_watchdog(void)
/* Timer bits */
wdog &= ~0x3F;
/* Issued events */
- wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24));
+ wdog &= ~((1 << 27)|(1 << 26)|(1 << 25)|(1 << 24));
/* No monitor bits */
- wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9));
+ wdog &= ~((1 << 16)|(1 << 13)|(1 << 12)|(1 << 11)|(1 << 10)|(1 << 9));
pci_write_config_dword(pdev, 0xCC, wdog);
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index a045ef86943..90f98df5f10 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -355,7 +355,8 @@ static int __init alim7101_wdt_init(void)
alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
NULL);
if (!alim7101_pmu) {
- printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n");
+ printk(KERN_INFO PFX
+ "ALi M7101 PMU not present - WDT not set\n");
return -EBUSY;
}
@@ -399,7 +400,8 @@ static int __init alim7101_wdt_init(void)
rc = misc_register(&wdt_miscdev);
if (rc) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ printk(KERN_ERR PFX
+ "cannot register miscdev on minor=%d (err=%d)\n",
wdt_miscdev.minor, rc);
goto err_out_reboot;
}
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 993e5f52afe..e35d5458923 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -13,6 +13,7 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
@@ -106,10 +107,10 @@ static int at91_wdt_close(struct inode *inode, struct file *file)
static int at91_wdt_settimeout(int new_time)
{
/*
- * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz
+ * All counting occurs at SLOW_CLOCK / 128 = 256 Hz
*
* Since WDV is a 16-bit counter, the maximum period is
- * 65536 / 0.256 = 256 seconds.
+ * 65536 / 256 = 256 seconds.
*/
if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
return -EINVAL;
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index b1da287f90e..435b0573fb0 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -18,6 +18,7 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
@@ -200,7 +201,7 @@ static long at91_wdt_ioctl(struct file *file,
* Pat the watchdog whenever device is written to.
*/
static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len,
- loff_t *ppos)
+ loff_t *ppos)
{
if (!len)
return 0;
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 084dfe9cecf..41070e4771a 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -1,13 +1,13 @@
/* cpwd.c - driver implementation for hardware watchdog
* timers found on Sun Microsystems CP1400 and CP1500 boards.
*
- * This device supports both the generic Linux watchdog
+ * This device supports both the generic Linux watchdog
* interface and Solaris-compatible ioctls as best it is
* able.
*
* NOTE: CP1400 systems appear to have a defective intr_mask
* register on the PLD, preventing the disabling of
- * timer interrupts. We use a timer to periodically
+ * timer interrupts. We use a timer to periodically
* reset 'stopped' watchdogs on affected platforms.
*
* Copyright (c) 2000 Eric Brower (ebrower@usa.net)
@@ -28,10 +28,9 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/uaccess.h>
#include <asm/irq.h>
-#include <asm/uaccess.h>
-
#include <asm/watchdog.h>
#define DRIVER_NAME "cpwd"
@@ -43,8 +42,8 @@
#define WD_BLIMIT 0xFFFF
#define WD0_MINOR 212
-#define WD1_MINOR 213
-#define WD2_MINOR 214
+#define WD1_MINOR 213
+#define WD2_MINOR 214
/* Internal driver definitions. */
#define WD0_ID 0
@@ -91,16 +90,16 @@ struct cpwd {
static struct cpwd *cpwd_device;
-/* Sun uses Altera PLD EPF8820ATC144-4
+/* Sun uses Altera PLD EPF8820ATC144-4
* providing three hardware watchdogs:
*
- * 1) RIC - sends an interrupt when triggered
- * 2) XIR - asserts XIR_B_RESET when triggered, resets CPU
- * 3) POR - asserts POR_B_RESET when triggered, resets CPU, backplane, board
+ * 1) RIC - sends an interrupt when triggered
+ * 2) XIR - asserts XIR_B_RESET when triggered, resets CPU
+ * 3) POR - asserts POR_B_RESET when triggered, resets CPU, backplane, board
*
*** Timer register block definition (struct wd_timer_regblk)
*
- * dcntr and limit registers (halfword access):
+ * dcntr and limit registers (halfword access):
* -------------------
* | 15 | ...| 1 | 0 |
* -------------------
@@ -108,7 +107,8 @@ static struct cpwd *cpwd_device;
* -------------------
* dcntr - Current 16-bit downcounter value.
* When downcounter reaches '0' watchdog expires.
- * Reading this register resets downcounter with 'limit' value.
+ * Reading this register resets downcounter with
+ * 'limit' value.
* limit - 16-bit countdown value in 1/10th second increments.
* Writing this register begins countdown with input value.
* Reading from this register does not affect counter.
@@ -158,11 +158,11 @@ static int wd0_timeout = 0;
static int wd1_timeout = 0;
static int wd2_timeout = 0;
-module_param (wd0_timeout, int, 0);
+module_param(wd0_timeout, int, 0);
MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs");
-module_param (wd1_timeout, int, 0);
+module_param(wd1_timeout, int, 0);
MODULE_PARM_DESC(wd1_timeout, "Default watchdog1 timeout in 1/10secs");
-module_param (wd2_timeout, int, 0);
+module_param(wd2_timeout, int, 0);
MODULE_PARM_DESC(wd2_timeout, "Default watchdog2 timeout in 1/10secs");
MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
@@ -201,9 +201,9 @@ static u8 cpwd_readb(void __iomem *addr)
static void cpwd_toggleintr(struct cpwd *p, int index, int enable)
{
unsigned char curregs = cpwd_readb(p->regs + PLD_IMASK);
- unsigned char setregs =
- (index == -1) ?
- (WD0_INTR_MASK | WD1_INTR_MASK | WD2_INTR_MASK) :
+ unsigned char setregs =
+ (index == -1) ?
+ (WD0_INTR_MASK | WD1_INTR_MASK | WD2_INTR_MASK) :
(p->devs[index].intr_mask);
if (enable == WD_INTR_ON)
@@ -303,24 +303,24 @@ static int cpwd_getstatus(struct cpwd *p, int index)
unsigned char ret = WD_STOPPED;
/* determine STOPPED */
- if (!stat)
+ if (!stat)
return ret;
/* determine EXPIRED vs FREERUN vs RUNNING */
else if (WD_S_EXPIRED & stat) {
ret = WD_EXPIRED;
- } else if(WD_S_RUNNING & stat) {
+ } else if (WD_S_RUNNING & stat) {
if (intr & p->devs[index].intr_mask) {
ret = WD_FREERUN;
} else {
/* Fudge WD_EXPIRED status for defective CP1400--
- * IF timer is running
- * AND brokenstop is set
+ * IF timer is running
+ * AND brokenstop is set
* AND an interrupt has been serviced
* we are WD_EXPIRED.
*
- * IF timer is running
- * AND brokenstop is set
+ * IF timer is running
+ * AND brokenstop is set
* AND no interrupt has been serviced
* we are WD_FREERUN.
*/
@@ -329,7 +329,8 @@ static int cpwd_getstatus(struct cpwd *p, int index)
if (p->devs[index].runstatus & WD_STAT_SVCD) {
ret = WD_EXPIRED;
} else {
- /* we could as well pretend we are expired */
+ /* we could as well pretend
+ * we are expired */
ret = WD_FREERUN;
}
} else {
@@ -342,7 +343,7 @@ static int cpwd_getstatus(struct cpwd *p, int index)
if (p->devs[index].runstatus & WD_STAT_SVCD)
ret |= WD_SERVICED;
- return(ret);
+ return ret;
}
static irqreturn_t cpwd_interrupt(int irq, void *dev_id)
@@ -367,22 +368,22 @@ static int cpwd_open(struct inode *inode, struct file *f)
struct cpwd *p = cpwd_device;
lock_kernel();
- switch(iminor(inode)) {
- case WD0_MINOR:
- case WD1_MINOR:
- case WD2_MINOR:
- break;
+ switch (iminor(inode)) {
+ case WD0_MINOR:
+ case WD1_MINOR:
+ case WD2_MINOR:
+ break;
- default:
- unlock_kernel();
- return -ENODEV;
+ default:
+ unlock_kernel();
+ return -ENODEV;
}
/* Register IRQ on first open of device */
if (!p->initialized) {
- if (request_irq(p->irq, &cpwd_interrupt,
+ if (request_irq(p->irq, &cpwd_interrupt,
IRQF_SHARED, DRIVER_NAME, p)) {
- printk(KERN_ERR PFX "Cannot register IRQ %d\n",
+ printk(KERN_ERR PFX "Cannot register IRQ %d\n",
p->irq);
unlock_kernel();
return -EBUSY;
@@ -400,8 +401,7 @@ static int cpwd_release(struct inode *inode, struct file *file)
return 0;
}
-static int cpwd_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
static struct watchdog_info info = {
.options = WDIOF_SETTIMEOUT,
@@ -409,6 +409,7 @@ static int cpwd_ioctl(struct inode *inode, struct file *file,
.identity = DRIVER_NAME,
};
void __user *argp = (void __user *)arg;
+ struct inode *inode = file->f_path.dentry->d_inode;
int index = iminor(inode) - WD0_MINOR;
struct cpwd *p = cpwd_device;
int setopt = 0;
@@ -442,7 +443,7 @@ static int cpwd_ioctl(struct inode *inode, struct file *file,
cpwd_starttimer(p, index);
} else {
return -EINVAL;
- }
+ }
break;
/* Solaris-compatible IOCTLs */
@@ -458,7 +459,7 @@ static int cpwd_ioctl(struct inode *inode, struct file *file,
case WIOCSTOP:
if (p->enabled)
- return(-EINVAL);
+ return -EINVAL;
cpwd_stoptimer(p, index);
break;
@@ -481,7 +482,7 @@ static long cpwd_compat_ioctl(struct file *file, unsigned int cmd,
case WIOCSTOP:
case WIOCGSTAT:
lock_kernel();
- rval = cpwd_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
+ rval = cpwd_ioctl(file, cmd, arg);
unlock_kernel();
break;
@@ -493,7 +494,7 @@ static long cpwd_compat_ioctl(struct file *file, unsigned int cmd,
return rval;
}
-static ssize_t cpwd_write(struct file *file, const char __user *buf,
+static ssize_t cpwd_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct inode *inode = file->f_path.dentry->d_inode;
@@ -508,20 +509,20 @@ static ssize_t cpwd_write(struct file *file, const char __user *buf,
return 0;
}
-static ssize_t cpwd_read(struct file * file, char __user *buffer,
+static ssize_t cpwd_read(struct file *file, char __user *buffer,
size_t count, loff_t *ppos)
{
return -EINVAL;
}
static const struct file_operations cpwd_fops = {
- .owner = THIS_MODULE,
- .ioctl = cpwd_ioctl,
- .compat_ioctl = cpwd_compat_ioctl,
- .open = cpwd_open,
- .write = cpwd_write,
- .read = cpwd_read,
- .release = cpwd_release,
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = cpwd_ioctl,
+ .compat_ioctl = cpwd_compat_ioctl,
+ .open = cpwd_open,
+ .write = cpwd_write,
+ .read = cpwd_read,
+ .release = cpwd_release,
};
static int __devinit cpwd_probe(struct of_device *op,
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 2e136028673..c51d0b0ea0c 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -24,7 +24,7 @@
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/io.h>
-#include <mach/hardware.h>
+#include <linux/device.h>
#define MODULE_NAME "DAVINCI-WDT: "
@@ -75,9 +75,9 @@ static void wdt_service(void)
spin_lock(&io_lock);
/* put watchdog in service state */
- davinci_writel(WDKEY_SEQ0, wdt_base + WDTCR);
+ iowrite32(WDKEY_SEQ0, wdt_base + WDTCR);
/* put watchdog in active state */
- davinci_writel(WDKEY_SEQ1, wdt_base + WDTCR);
+ iowrite32(WDKEY_SEQ1, wdt_base + WDTCR);
spin_unlock(&io_lock);
}
@@ -90,29 +90,29 @@ static void wdt_enable(void)
spin_lock(&io_lock);
/* disable, internal clock source */
- davinci_writel(0, wdt_base + TCR);
+ iowrite32(0, wdt_base + TCR);
/* reset timer, set mode to 64-bit watchdog, and unreset */
- davinci_writel(0, wdt_base + TGCR);
+ iowrite32(0, wdt_base + TGCR);
tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
- davinci_writel(tgcr, wdt_base + TGCR);
+ iowrite32(tgcr, wdt_base + TGCR);
/* clear counter regs */
- davinci_writel(0, wdt_base + TIM12);
- davinci_writel(0, wdt_base + TIM34);
+ iowrite32(0, wdt_base + TIM12);
+ iowrite32(0, wdt_base + TIM34);
/* set timeout period */
timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) & 0xffffffff);
- davinci_writel(timer_margin, wdt_base + PRD12);
+ iowrite32(timer_margin, wdt_base + PRD12);
timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) >> 32);
- davinci_writel(timer_margin, wdt_base + PRD34);
+ iowrite32(timer_margin, wdt_base + PRD34);
/* enable run continuously */
- davinci_writel(ENAMODE12_PERIODIC, wdt_base + TCR);
+ iowrite32(ENAMODE12_PERIODIC, wdt_base + TCR);
/* Once the WDT is in pre-active state write to
* TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are
* write protected (except for the WDKEY field)
*/
/* put watchdog in pre-active state */
- davinci_writel(WDKEY_SEQ0 | WDEN, wdt_base + WDTCR);
+ iowrite32(WDKEY_SEQ0 | WDEN, wdt_base + WDTCR);
/* put watchdog in active state */
- davinci_writel(WDKEY_SEQ1 | WDEN, wdt_base + WDTCR);
+ iowrite32(WDKEY_SEQ1 | WDEN, wdt_base + WDTCR);
spin_unlock(&io_lock);
}
@@ -197,17 +197,16 @@ static int davinci_wdt_probe(struct platform_device *pdev)
{
int ret = 0, size;
struct resource *res;
+ struct device *dev = &pdev->dev;
if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
heartbeat = DEFAULT_HEARTBEAT;
- printk(KERN_INFO MODULE_NAME
- "DaVinci Watchdog Timer: heartbeat %d sec\n", heartbeat);
+ dev_info(dev, "heartbeat %d sec\n", heartbeat);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
- printk(KERN_INFO MODULE_NAME
- "failed to get memory region resource\n");
+ dev_err(dev, "failed to get memory region resource\n");
return -ENOENT;
}
@@ -215,20 +214,26 @@ static int davinci_wdt_probe(struct platform_device *pdev)
wdt_mem = request_mem_region(res->start, size, pdev->name);
if (wdt_mem == NULL) {
- printk(KERN_INFO MODULE_NAME "failed to get memory region\n");
+ dev_err(dev, "failed to get memory region\n");
return -ENOENT;
}
- wdt_base = (void __iomem *)(res->start);
+
+ wdt_base = ioremap(res->start, size);
+ if (!wdt_base) {
+ dev_err(dev, "failed to map memory region\n");
+ return -ENOMEM;
+ }
ret = misc_register(&davinci_wdt_miscdev);
if (ret < 0) {
- printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
+ dev_err(dev, "cannot register misc device\n");
release_resource(wdt_mem);
kfree(wdt_mem);
} else {
set_bit(WDT_DEVICE_INITED, &wdt_status);
}
+ iounmap(wdt_base);
return ret;
}
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index a171fc6ae1c..9add3541fb4 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -8,19 +8,19 @@
* Based on wdt.c.
* Original copyright messages:
*
- * (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
+ * (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
*
- * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
- * warranty for any of this software. This material is provided
- * "AS-IS" and at no charge.
+ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
*
- * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>*
+ * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>*
*/
/* Changelog:
@@ -37,7 +37,7 @@
* add expect_close support
*
* 2002.05.30 - Joel Becker <joel.becker@oracle.com>
- * Added Matt Domsch's nowayout module option.
+ * Added Matt Domsch's nowayout module option.
*/
/*
@@ -151,7 +151,7 @@ static void eurwdt_activate_timer(void)
if (irq == 0)
printk(KERN_INFO ": interrupt disabled\n");
- eurwdt_write_reg(WDT_TIMER_CFG, irq<<4);
+ eurwdt_write_reg(WDT_TIMER_CFG, irq << 4);
eurwdt_write_reg(WDT_UNIT_SEL, WDT_UNIT_SECS); /* we use seconds */
eurwdt_set_timeout(0); /* the default timeout */
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index f0c2b7a1a17..734d9806a87 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -269,7 +269,7 @@ static int __devinit gef_wdt_probe(struct of_device *dev,
bus_clk = 133; /* in MHz */
freq = fsl_get_sys_freq();
- if (freq > 0)
+ if (freq != -1)
bus_clk = freq;
/* Map devices registers into memory */
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c
index 6799a6de66f..9acf0015a1e 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -34,11 +34,15 @@
static int timeout = WATCHDOG_TIMEOUT;
module_param(timeout, int, 0);
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=131, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
+MODULE_PARM_DESC(timeout,
+ "Watchdog timeout in seconds. 1<= timeout <=131, default="
+ __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+MODULE_PARM_DESC(nowayout,
+ "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
static struct platform_device *geodewdt_platform_device;
static unsigned long wdt_flags;
@@ -269,7 +273,8 @@ static int __init geodewdt_init(void)
if (ret)
return ret;
- geodewdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
+ geodewdt_platform_device = platform_device_register_simple(DRV_NAME,
+ -1, NULL, 0);
if (IS_ERR(geodewdt_platform_device)) {
ret = PTR_ERR(geodewdt_platform_device);
goto err;
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 763c1ea5dce..6cf155d6b35 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -47,6 +47,7 @@
#define PCI_BIOS32_PARAGRAPH_LEN 16
#define PCI_ROM_BASE1 0x000F0000
#define ROM_SIZE 0x10000
+#define HPWDT_VERSION "1.01"
struct bios32_service_dir {
u32 signature;
@@ -130,17 +131,14 @@ static void *cru_rom_addr;
static struct cmn_registers cmn_regs;
static struct pci_device_id hpwdt_devices[] = {
- {
- .vendor = PCI_VENDOR_ID_COMPAQ,
- .device = 0xB203,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB203) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3306) },
{0}, /* terminate list */
};
MODULE_DEVICE_TABLE(pci, hpwdt_devices);
-extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, unsigned long *pRomEntry);
+extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
+ unsigned long *pRomEntry);
#ifndef CONFIG_X86_64
/* --32 Bit Bios------------------------------------------------------------ */
@@ -605,7 +603,7 @@ static long hpwdt_ioctl(struct file *file, unsigned int cmd,
/*
* Kernel interfaces
*/
-static struct file_operations hpwdt_fops = {
+static const struct file_operations hpwdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = hpwdt_write,
@@ -704,10 +702,11 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
}
printk(KERN_INFO
- "hp Watchdog Timer Driver: 1.00"
+ "hp Watchdog Timer Driver: %s"
", timer margin: %d seconds (nowayout=%d)"
", allow kernel dump: %s (default = 0/OFF).\n",
- soft_margin, nowayout, (allow_kdump == 0) ? "OFF" : "ON");
+ HPWDT_VERSION, soft_margin, nowayout,
+ (allow_kdump == 0) ? "OFF" : "ON");
return 0;
@@ -757,6 +756,7 @@ static int __init hpwdt_init(void)
MODULE_AUTHOR("Tom Mingarelli");
MODULE_DESCRIPTION("hp watchdog driver");
MODULE_LICENSE("GPL");
+MODULE_VERSION(HPWDT_VERSION);
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
module_param(soft_margin, int, 0);
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 74f951c18b9..2dbe83570d6 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -13,7 +13,7 @@
*
* The timer is implemented in the following I/O controller hubs:
* (See the intel documentation on http://developer.intel.com.)
- * 6300ESB chip : document number 300641-003
+ * 6300ESB chip : document number 300641-004
*
* 2004YYZZ Ross Biro
* Initial version 0.01
@@ -34,7 +34,7 @@
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/reboot.h>
+#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/ioport.h>
@@ -42,7 +42,7 @@
#include <linux/io.h>
/* Module and version information */
-#define ESB_VERSION "0.03"
+#define ESB_VERSION "0.04"
#define ESB_MODULE_NAME "i6300ESB timer"
#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
#define PFX ESB_MODULE_NAME ": "
@@ -81,6 +81,7 @@ static unsigned long timer_alive;
static struct pci_dev *esb_pci;
static unsigned short triggered; /* The status of the watchdog upon boot */
static char esb_expect_close;
+static struct platform_device *esb_platform_device;
/* module parameters */
/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
@@ -114,13 +115,18 @@ static inline void esb_unlock_registers(void)
writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
}
-static void esb_timer_start(void)
+static int esb_timer_start(void)
{
u8 val;
+ spin_lock(&esb_lock);
+ esb_unlock_registers();
+ writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
/* Enable or Enable + Lock? */
val = 0x02 | (nowayout ? 0x01 : 0x00);
pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
+ spin_unlock(&esb_lock);
+ return 0;
}
static int esb_timer_stop(void)
@@ -207,7 +213,6 @@ static int esb_open(struct inode *inode, struct file *file)
return -EBUSY;
/* Reload and activate timer */
- esb_timer_keepalive();
esb_timer_start();
return nonseekable_open(inode, file);
@@ -240,7 +245,8 @@ static ssize_t esb_write(struct file *file, const char __user *data,
* five months ago... */
esb_expect_close = 0;
- /* scan to see whether or not we got the magic character */
+ /* scan to see whether or not we got the
+ * magic character */
for (i = 0; i != len; i++) {
char c;
if (get_user(c, data + i))
@@ -292,7 +298,6 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
if (new_options & WDIOS_ENABLECARD) {
- esb_timer_keepalive();
esb_timer_start();
retval = 0;
}
@@ -319,19 +324,6 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
/*
- * Notify system
- */
-
-static int esb_notify_sys(struct notifier_block *this,
- unsigned long code, void *unused)
-{
- if (code == SYS_DOWN || code == SYS_HALT)
- esb_timer_stop(); /* Turn the WDT off */
-
- return NOTIFY_DONE;
-}
-
-/*
* Kernel Interfaces
*/
@@ -350,10 +342,6 @@ static struct miscdevice esb_miscdev = {
.fops = &esb_fops,
};
-static struct notifier_block esb_notifier = {
- .notifier_call = esb_notify_sys,
-};
-
/*
* Data for PCI driver interface
*
@@ -372,7 +360,7 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
* Init & exit routines
*/
-static unsigned char __init esb_getdevice(void)
+static unsigned char __devinit esb_getdevice(void)
{
u8 val1;
unsigned short val2;
@@ -443,7 +431,7 @@ err_devput:
return 0;
}
-static int __init watchdog_init(void)
+static int __devinit esb_probe(struct platform_device *dev)
{
int ret;
@@ -459,19 +447,13 @@ static int __init watchdog_init(void)
"heartbeat value must be 1<heartbeat<2046, using %d\n",
heartbeat);
}
- ret = register_reboot_notifier(&esb_notifier);
- if (ret != 0) {
- printk(KERN_ERR PFX
- "cannot register reboot notifier (err=%d)\n", ret);
- goto err_unmap;
- }
ret = misc_register(&esb_miscdev);
if (ret != 0) {
printk(KERN_ERR PFX
"cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, ret);
- goto err_notifier;
+ goto err_unmap;
}
esb_timer_stop();
printk(KERN_INFO PFX
@@ -479,8 +461,6 @@ static int __init watchdog_init(void)
BASEADDR, heartbeat, nowayout);
return 0;
-err_notifier:
- unregister_reboot_notifier(&esb_notifier);
err_unmap:
iounmap(BASEADDR);
/* err_release: */
@@ -492,7 +472,7 @@ err_unmap:
return ret;
}
-static void __exit watchdog_cleanup(void)
+static int __devexit esb_remove(struct platform_device *dev)
{
/* Stop the timer before we leave */
if (!nowayout)
@@ -500,11 +480,58 @@ static void __exit watchdog_cleanup(void)
/* Deregister */
misc_deregister(&esb_miscdev);
- unregister_reboot_notifier(&esb_notifier);
iounmap(BASEADDR);
pci_release_region(esb_pci, 0);
pci_disable_device(esb_pci);
pci_dev_put(esb_pci);
+ return 0;
+}
+
+static void esb_shutdown(struct platform_device *dev)
+{
+ esb_timer_stop();
+}
+
+static struct platform_driver esb_platform_driver = {
+ .probe = esb_probe,
+ .remove = __devexit_p(esb_remove),
+ .shutdown = esb_shutdown,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = ESB_MODULE_NAME,
+ },
+};
+
+static int __init watchdog_init(void)
+{
+ int err;
+
+ printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
+ ESB_VERSION);
+
+ err = platform_driver_register(&esb_platform_driver);
+ if (err)
+ return err;
+
+ esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME,
+ -1, NULL, 0);
+ if (IS_ERR(esb_platform_device)) {
+ err = PTR_ERR(esb_platform_device);
+ goto unreg_platform_driver;
+ }
+
+ return 0;
+
+unreg_platform_driver:
+ platform_driver_unregister(&esb_platform_driver);
+ return err;
+}
+
+static void __exit watchdog_cleanup(void)
+{
+ platform_device_unregister(esb_platform_device);
+ platform_driver_unregister(&esb_platform_driver);
+ printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
}
module_init(watchdog_init);
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index 2474ebca88f..d3c0f6de552 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -1,7 +1,7 @@
/*
* intel TCO vendor specific watchdog driver support
*
- * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>.
+ * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,7 +19,7 @@
/* Module and version information */
#define DRV_NAME "iTCO_vendor_support"
-#define DRV_VERSION "1.02"
+#define DRV_VERSION "1.03"
#define PFX DRV_NAME ": "
/* Includes */
@@ -47,7 +47,8 @@
static int vendorsupport;
module_param(vendorsupport, int, 0);
-MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+");
+MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default="
+ "0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+");
/*
* Vendor Specific Support
@@ -77,6 +78,26 @@ MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (n
* 20.6 seconds.
*/
+static void supermicro_old_pre_start(unsigned long acpibase)
+{
+ unsigned long val32;
+
+ /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
+ val32 = inl(SMI_EN);
+ val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
+ outl(val32, SMI_EN); /* Needed to activate watchdog */
+}
+
+static void supermicro_old_pre_stop(unsigned long acpibase)
+{
+ unsigned long val32;
+
+ /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */
+ val32 = inl(SMI_EN);
+ val32 |= 0x00002000; /* Turn on SMI clearing watchdog */
+ outl(val32, SMI_EN); /* Needed to deactivate watchdog */
+}
+
static void supermicro_old_pre_keepalive(unsigned long acpibase)
{
/* Reload TCO Timer (done in iTCO_wdt_keepalive) + */
@@ -228,14 +249,18 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat)
void iTCO_vendor_pre_start(unsigned long acpibase,
unsigned int heartbeat)
{
- if (vendorsupport == SUPERMICRO_NEW_BOARD)
+ if (vendorsupport == SUPERMICRO_OLD_BOARD)
+ supermicro_old_pre_start(acpibase);
+ else if (vendorsupport == SUPERMICRO_NEW_BOARD)
supermicro_new_pre_start(heartbeat);
}
EXPORT_SYMBOL(iTCO_vendor_pre_start);
void iTCO_vendor_pre_stop(unsigned long acpibase)
{
- if (vendorsupport == SUPERMICRO_NEW_BOARD)
+ if (vendorsupport == SUPERMICRO_OLD_BOARD)
+ supermicro_old_pre_stop(acpibase);
+ else if (vendorsupport == SUPERMICRO_NEW_BOARD)
supermicro_new_pre_stop();
}
EXPORT_SYMBOL(iTCO_vendor_pre_stop);
@@ -281,7 +306,8 @@ static void __exit iTCO_vendor_exit_module(void)
module_init(iTCO_vendor_init_module);
module_exit(iTCO_vendor_exit_module);
-MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>, R. Seretny <lkpatches@paypc.com>");
+MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>, "
+ "R. Seretny <lkpatches@paypc.com>");
MODULE_DESCRIPTION("Intel TCO Vendor Specific WatchDog Timer Driver Support");
MODULE_VERSION(DRV_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 5b395a4ddfd..648250b998c 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -1,7 +1,7 @@
/*
- * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets)
+ * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets)
*
- * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>.
+ * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -63,7 +63,7 @@
/* Module and version information */
#define DRV_NAME "iTCO_wdt"
-#define DRV_VERSION "1.04"
+#define DRV_VERSION "1.05"
#define PFX DRV_NAME ": "
/* Includes */
@@ -236,16 +236,16 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
/* Address definitions for the TCO */
/* TCO base address */
-#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
+#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
/* SMI Control and Enable Register */
-#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
+#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */
#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */
-#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
-#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
-#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
-#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
+#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
+#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
+#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
+#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */
#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */
#define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */
@@ -273,7 +273,9 @@ static struct platform_device *iTCO_wdt_platform_device;
#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */
static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO v1) or 613 (TCO v2), default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. "
+ "(2<heartbeat<39 (TCO v1) or 613 (TCO v2), default="
+ __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
@@ -338,7 +340,6 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void)
static int iTCO_wdt_start(void)
{
unsigned int val;
- unsigned long val32;
spin_lock(&iTCO_wdt_private.io_lock);
@@ -347,15 +348,11 @@ static int iTCO_wdt_start(void)
/* disable chipset's NO_REBOOT bit */
if (iTCO_wdt_unset_NO_REBOOT_bit()) {
spin_unlock(&iTCO_wdt_private.io_lock);
- printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+ printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, "
+ "reboot disabled by hardware\n");
return -EIO;
}
- /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
- val32 = inl(SMI_EN);
- val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
- outl(val32, SMI_EN);
-
/* Force the timer to its reload value by writing to the TCO_RLD
register */
if (iTCO_wdt_private.iTCO_version == 2)
@@ -378,7 +375,6 @@ static int iTCO_wdt_start(void)
static int iTCO_wdt_stop(void)
{
unsigned int val;
- unsigned long val32;
spin_lock(&iTCO_wdt_private.io_lock);
@@ -390,11 +386,6 @@ static int iTCO_wdt_stop(void)
outw(val, TCO1_CNT);
val = inw(TCO1_CNT);
- /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */
- val32 = inl(SMI_EN);
- val32 |= 0x00002000;
- outl(val32, SMI_EN);
-
/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
iTCO_wdt_set_NO_REBOOT_bit();
@@ -649,6 +640,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
int ret;
u32 base_address;
unsigned long RCBA;
+ unsigned long val32;
/*
* Find the ACPI/PM base I/O address which is the base
@@ -680,7 +672,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
/* Check chipset's NO_REBOOT bit */
if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
- printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+ printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, "
+ "reboot disabled by hardware\n");
ret = -ENODEV; /* Cannot reset NO_REBOOT bit */
goto out;
}
@@ -695,6 +688,10 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
ret = -EIO;
goto out;
}
+ /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
+ val32 = inl(SMI_EN);
+ val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
+ outl(val32, SMI_EN);
/* The TCO I/O registers reside in a 32-byte range pointed to
by the TCOBASE value */
@@ -723,8 +720,9 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
if not reset to the default */
if (iTCO_wdt_set_heartbeat(heartbeat)) {
iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
- printk(KERN_INFO PFX "heartbeat value must be 2 < heartbeat < 39 (TCO v1) or 613 (TCO v2), using %d\n",
- heartbeat);
+ printk(KERN_INFO PFX
+ "heartbeat value must be 2 < heartbeat < 39 (TCO v1) "
+ "or 613 (TCO v2), using %d\n", heartbeat);
}
ret = misc_register(&iTCO_wdt_miscdev);
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index afb8af397a9..cc133c531d0 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -188,8 +188,8 @@ static inline int superio_inb(int reg)
static inline void superio_outb(int val, int reg)
{
- outb(reg, REG);
- outb(val, VAL);
+ outb(reg, REG);
+ outb(val, VAL);
}
static inline int superio_inw(int reg)
@@ -204,10 +204,10 @@ static inline int superio_inw(int reg)
static inline void superio_outw(int val, int reg)
{
- outb(reg++, REG);
- outb(val >> 8, VAL);
- outb(reg, REG);
- outb(val, VAL);
+ outb(reg++, REG);
+ outb(val >> 8, VAL);
+ outb(reg, REG);
+ outb(val, VAL);
}
/* watchdog timer handling */
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index 0b798fdaa37..74c92d38411 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -21,6 +21,7 @@
#include <linux/watchdog.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <mach/timex.h>
#include <mach/regs-timer.h>
#define WDT_DEFAULT_TIME 5 /* seconds */
diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c
index db91892558f..465fe36adad 100644
--- a/drivers/watchdog/mpc5200_wdt.c
+++ b/drivers/watchdog/mpc5200_wdt.c
@@ -9,8 +9,8 @@
#include <asm/mpc52xx.h>
-#define GPT_MODE_WDT (1<<15)
-#define GPT_MODE_CE (1<<12)
+#define GPT_MODE_WDT (1 << 15)
+#define GPT_MODE_CE (1 << 12)
#define GPT_MODE_MS_TIMER (0x4)
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 1130ad697ce..1512ab8b175 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -5,7 +5,7 @@
*
* Based on the SoftDog driver:
* (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
- * All Rights Reserved.
+ * 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
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index 3acce623f20..539b6f6ba7f 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -5,7 +5,7 @@
* All Rights Reserved.
* http://www.4g-systems.biz
*
- * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org>
+ * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/drivers/watchdog/orion5x_wdt.c b/drivers/watchdog/orion5x_wdt.c
index 14a339f58b6..e81441f103d 100644
--- a/drivers/watchdog/orion5x_wdt.c
+++ b/drivers/watchdog/orion5x_wdt.c
@@ -16,11 +16,13 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
#include <linux/watchdog.h>
#include <linux/init.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/spinlock.h>
+#include <plat/orion5x_wdt.h>
/*
* Watchdog timer block registers.
@@ -29,12 +31,14 @@
#define WDT_EN 0x0010
#define WDT_VAL (TIMER_VIRT_BASE + 0x0024)
-#define WDT_MAX_DURATION (0xffffffff / ORION5X_TCLK)
+#define WDT_MAX_CYCLE_COUNT 0xffffffff
#define WDT_IN_USE 0
#define WDT_OK_TO_CLOSE 1
static int nowayout = WATCHDOG_NOWAYOUT;
-static int heartbeat = WDT_MAX_DURATION; /* (seconds) */
+static int heartbeat = -1; /* module parameter (seconds) */
+static unsigned int wdt_max_duration; /* (seconds) */
+static unsigned int wdt_tclk;
static unsigned long wdt_status;
static spinlock_t wdt_lock;
@@ -45,7 +49,7 @@ static void wdt_enable(void)
spin_lock(&wdt_lock);
/* Set watchdog duration */
- writel(ORION5X_TCLK * heartbeat, WDT_VAL);
+ writel(wdt_tclk * heartbeat, WDT_VAL);
/* Clear watchdog timer interrupt */
reg = readl(BRIDGE_CAUSE);
@@ -87,7 +91,7 @@ static void wdt_disable(void)
static int orion5x_wdt_get_timeleft(int *time_left)
{
spin_lock(&wdt_lock);
- *time_left = readl(WDT_VAL) / ORION5X_TCLK;
+ *time_left = readl(WDT_VAL) / wdt_tclk;
spin_unlock(&wdt_lock);
return 0;
}
@@ -157,7 +161,7 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
if (ret)
break;
- if (time <= 0 || time > WDT_MAX_DURATION) {
+ if (time <= 0 || time > wdt_max_duration) {
ret = -EINVAL;
break;
}
@@ -209,23 +213,69 @@ static struct miscdevice orion5x_wdt_miscdev = {
.fops = &orion5x_wdt_fops,
};
-static int __init orion5x_wdt_init(void)
+static int __devinit orion5x_wdt_probe(struct platform_device *pdev)
{
+ struct orion5x_wdt_platform_data *pdata = pdev->dev.platform_data;
int ret;
- spin_lock_init(&wdt_lock);
+ if (pdata) {
+ wdt_tclk = pdata->tclk;
+ } else {
+ printk(KERN_ERR "Orion5x Watchdog misses platform data\n");
+ return -ENODEV;
+ }
+
+ if (orion5x_wdt_miscdev.parent)
+ return -EBUSY;
+ orion5x_wdt_miscdev.parent = &pdev->dev;
+
+ wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk;
+ if (heartbeat <= 0 || heartbeat > wdt_max_duration)
+ heartbeat = wdt_max_duration;
ret = misc_register(&orion5x_wdt_miscdev);
- if (ret == 0)
- printk("Orion5x Watchdog Timer: heartbeat %d sec\n",
- heartbeat);
+ if (ret)
+ return ret;
+
+ printk(KERN_INFO "Orion5x Watchdog Timer: Initial timeout %d sec%s\n",
+ heartbeat, nowayout ? ", nowayout" : "");
+ return 0;
+}
+
+static int __devexit orion5x_wdt_remove(struct platform_device *pdev)
+{
+ int ret;
+
+ if (test_bit(WDT_IN_USE, &wdt_status)) {
+ wdt_disable();
+ clear_bit(WDT_IN_USE, &wdt_status);
+ }
+
+ ret = misc_deregister(&orion5x_wdt_miscdev);
+ if (!ret)
+ orion5x_wdt_miscdev.parent = NULL;
return ret;
}
+static struct platform_driver orion5x_wdt_driver = {
+ .probe = orion5x_wdt_probe,
+ .remove = __devexit_p(orion5x_wdt_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "orion5x_wdt",
+ },
+};
+
+static int __init orion5x_wdt_init(void)
+{
+ spin_lock_init(&wdt_lock);
+ return platform_driver_register(&orion5x_wdt_driver);
+}
+
static void __exit orion5x_wdt_exit(void)
{
- misc_deregister(&orion5x_wdt_miscdev);
+ platform_driver_unregister(&orion5x_wdt_driver);
}
module_init(orion5x_wdt_init);
@@ -235,8 +285,7 @@ MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
MODULE_DESCRIPTION("Orion5x Processor Watchdog");
module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default is "
- __MODULE_STRING(WDT_MAX_DURATION) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds");
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 484c215e9f3..1a2b916e3f8 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -536,7 +536,8 @@ static int __init pc87413_init(void)
ret = misc_register(&pc87413_miscdev);
if (ret != 0) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ printk(KERN_ERR PFX
+ "cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, ret);
unregister_reboot_notifier(&pc87413_notifier);
return ret;
@@ -574,7 +575,8 @@ static void __exit pc87413_exit(void)
module_init(pc87413_init);
module_exit(pc87413_exit);
-MODULE_AUTHOR("Sven Anders <anders@anduras.de>, Marcus Junker <junker@anduras.de>,");
+MODULE_AUTHOR("Sven Anders <anders@anduras.de>, "
+ "Marcus Junker <junker@anduras.de>,");
MODULE_DESCRIPTION("PC87413 WDT driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index 9e1331a3b21..aa9512321f3 100644
--- a/drivers/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
@@ -24,25 +24,25 @@
* version reporting. Added read routine for temperature.
* Removed some extra defines, added an autodetect Revision
* routine.
- * 961006 Revised some documentation, fixed some cosmetic bugs. Made
- * drivers to panic the system if it's overheating at bootup.
+ * 961006 Revised some documentation, fixed some cosmetic bugs. Made
+ * drivers to panic the system if it's overheating at bootup.
* 961118 Changed some verbiage on some of the output, tidied up
* code bits, and added compatibility to 2.1.x.
- * 970912 Enabled board on open and disable on close.
+ * 970912 Enabled board on open and disable on close.
* 971107 Took account of recent VFS changes (broke read).
- * 971210 Disable board on initialisation in case board already ticking.
- * 971222 Changed open/close for temperature handling
- * Michael Meskes <meskes@debian.org>.
- * 980112 Used minor numbers from include/linux/miscdevice.h
- * 990403 Clear reset status after reading control status register in
- * pcwd_showprevstate(). [Marc Boucher <marc@mbsi.ca>]
+ * 971210 Disable board on initialisation in case board already ticking.
+ * 971222 Changed open/close for temperature handling
+ * Michael Meskes <meskes@debian.org>.
+ * 980112 Used minor numbers from include/linux/miscdevice.h
+ * 990403 Clear reset status after reading control status register in
+ * pcwd_showprevstate(). [Marc Boucher <marc@mbsi.ca>]
* 990605 Made changes to code to support Firmware 1.22a, added
* fairly useless proc entry.
* 990610 removed said useless proc code for the merge <alan>
* 000403 Removed last traces of proc code. <davej>
* 011214 Added nowayout module option to override
* CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com>
- * Added timeout module option to override default
+ * Added timeout module option to override default
*/
/*
@@ -76,8 +76,7 @@
#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog"
#define WATCHDOG_NAME "pcwd"
#define PFX WATCHDOG_NAME ": "
-#define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION " (" WATCHDOG_DATE ")\n"
-#define WD_VER WATCHDOG_VERSION " (" WATCHDOG_DATE ")"
+#define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION "\n"
/*
* It should be noted that PCWD_REVISION_B was removed because A and B
@@ -200,7 +199,9 @@ MODULE_PARM_DESC(debug,
#define WATCHDOG_HEARTBEAT 0
static int heartbeat = WATCHDOG_HEARTBEAT;
module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2 <= heartbeat <= 7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. "
+ "(2 <= heartbeat <= 7200 or 0=delay-time from dip-switches, default="
+ __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
@@ -239,7 +240,8 @@ static int send_isa_command(int cmd)
}
if (debug >= DEBUG)
- printk(KERN_DEBUG PFX "received following data for cmd=0x%02x: port0=0x%02x last_port0=0x%02x\n",
+ printk(KERN_DEBUG PFX "received following data for "
+ "cmd=0x%02x: port0=0x%02x last_port0=0x%02x\n",
cmd, port0, last_port0);
return port0;
@@ -339,10 +341,12 @@ static void pcwd_show_card_info(void)
pcwd_private.io_addr);
else if (pcwd_private.revision == PCWD_REVISION_C) {
pcwd_get_firmware();
- printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n",
+ printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port "
+ "0x%04x (Firmware version: %s)\n",
pcwd_private.io_addr, pcwd_private.fw_ver_str);
option_switches = pcwd_get_option_switches();
- printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
+ printk(KERN_INFO PFX "Option switches (0x%02x): "
+ "Temperature Reset Enable=%s, Power On Delay=%s\n",
option_switches,
((option_switches & 0x10) ? "ON" : "OFF"),
((option_switches & 0x08) ? "ON" : "OFF"));
@@ -358,7 +362,8 @@ static void pcwd_show_card_info(void)
printk(KERN_INFO PFX "Temperature Option Detected\n");
if (pcwd_private.boot_status & WDIOF_CARDRESET)
- printk(KERN_INFO PFX "Previous reboot was caused by the card\n");
+ printk(KERN_INFO PFX
+ "Previous reboot was caused by the card\n");
if (pcwd_private.boot_status & WDIOF_OVERHEAT) {
printk(KERN_EMERG PFX
@@ -871,7 +876,7 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
cards_found++;
if (cards_found == 1)
printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n",
- WD_VER);
+ WATCHDOG_VERSION);
if (cards_found > 1) {
printk(KERN_ERR PFX "This driver only supports 1 device\n");
@@ -1026,7 +1031,8 @@ static void __exit pcwd_cleanup_module(void)
module_init(pcwd_init_module);
module_exit(pcwd_cleanup_module);
-MODULE_AUTHOR("Ken Hollis <kenji@bitgate.com>, Wim Van Sebroeck <wim@iguana.be>");
+MODULE_AUTHOR("Ken Hollis <kenji@bitgate.com>, "
+ "Wim Van Sebroeck <wim@iguana.be>");
MODULE_DESCRIPTION("Berkshire ISA-PC Watchdog driver");
MODULE_VERSION(WATCHDOG_VERSION);
MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index 5d76422c402..698f51bff1b 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -24,7 +24,8 @@
* A bells and whistles driver is available from:
* http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/
*
- * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
+ * More info available at
+ * http://www.berkprod.com/ or http://www.pcwatchdog.com/
*/
/*
@@ -51,11 +52,10 @@
/* Module and version information */
#define WATCHDOG_VERSION "1.03"
-#define WATCHDOG_DATE "21 Jan 2007"
#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
#define WATCHDOG_NAME "pcwd_pci"
#define PFX WATCHDOG_NAME ": "
-#define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION " (" WATCHDOG_DATE ")\n"
+#define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION "\n"
/* Stuff for the PCI ID's */
#ifndef PCI_VENDOR_ID_QUICKLOGIC
@@ -76,7 +76,8 @@
#define WD_PCI_TTRP 0x04 /* Temperature Trip status */
#define WD_PCI_RL2A 0x08 /* Relay 2 Active */
#define WD_PCI_RL1A 0x10 /* Relay 1 Active */
-#define WD_PCI_R2DS 0x40 /* Relay 2 Disable Temperature-trip/reset */
+#define WD_PCI_R2DS 0x40 /* Relay 2 Disable Temperature-trip /
+ reset */
#define WD_PCI_RLY2 0x80 /* Activate Relay 2 on the board */
/* Port 2 : Control Status #2 */
#define WD_PCI_WDIS 0x10 /* Watchdog Disable */
@@ -114,12 +115,18 @@ static int cards_found;
static int temp_panic;
static unsigned long is_active;
static char expect_release;
-static struct { /* this is private data for each PCI-PC watchdog card */
- int supports_temp; /* Wether or not the card has a temperature device */
- int boot_status; /* The card's boot status */
- unsigned long io_addr; /* The cards I/O address */
- spinlock_t io_lock; /* the lock for io operations */
- struct pci_dev *pdev; /* the PCI-device */
+/* this is private data for each PCI-PC watchdog card */
+static struct {
+ /* Wether or not the card has a temperature device */
+ int supports_temp;
+ /* The card's boot status */
+ int boot_status;
+ /* The cards I/O address */
+ unsigned long io_addr;
+ /* the lock for io operations */
+ spinlock_t io_lock;
+ /* the PCI-device */
+ struct pci_dev *pdev;
} pcipcwd_private;
/* module parameters */
@@ -130,14 +137,18 @@ static int debug = QUIET;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
-#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
+#define WATCHDOG_HEARTBEAT 0 /* default heartbeat =
+ delay-time from dip-switches */
static int heartbeat = WATCHDOG_HEARTBEAT;
module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. "
+ "(0<heartbeat<65536 or 0=delay-time from dip-switches, default="
+ __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
/*
* Internal functions
@@ -148,8 +159,8 @@ static int send_command(int cmd, int *msb, int *lsb)
int got_response, count;
if (debug >= DEBUG)
- printk(KERN_DEBUG PFX "sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x\n",
- cmd, *msb, *lsb);
+ printk(KERN_DEBUG PFX "sending following data "
+ "cmd=0x%02x msb=0x%02x lsb=0x%02x\n", cmd, *msb, *lsb);
spin_lock(&pcipcwd_private.io_lock);
/* If a command requires data it should be written first.
@@ -166,17 +177,20 @@ static int send_command(int cmd, int *msb, int *lsb)
* the WRSP bit in port 2 and give it a max. timeout of
* PCI_COMMAND_TIMEOUT to process */
got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP;
- for (count = 0; (count < PCI_COMMAND_TIMEOUT) && (!got_response); count++) {
+ for (count = 0; (count < PCI_COMMAND_TIMEOUT) && (!got_response);
+ count++) {
mdelay(1);
got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP;
}
if (debug >= DEBUG) {
if (got_response) {
- printk(KERN_DEBUG PFX "time to process command was: %d ms\n",
+ printk(KERN_DEBUG PFX
+ "time to process command was: %d ms\n",
count);
} else {
- printk(KERN_DEBUG PFX "card did not respond on command!\n");
+ printk(KERN_DEBUG PFX
+ "card did not respond on command!\n");
}
}
@@ -189,7 +203,8 @@ static int send_command(int cmd, int *msb, int *lsb)
inb_p(pcipcwd_private.io_addr + 6);
if (debug >= DEBUG)
- printk(KERN_DEBUG PFX "received following data for cmd=0x%02x: msb=0x%02x lsb=0x%02x\n",
+ printk(KERN_DEBUG PFX "received following data for "
+ "cmd=0x%02x: msb=0x%02x lsb=0x%02x\n",
cmd, *msb, *lsb);
}
@@ -218,7 +233,8 @@ static void pcipcwd_show_card_info(void)
char fw_ver_str[20]; /* The cards firmware version */
int option_switches;
- got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
+ got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major,
+ &fw_rev_minor);
if (got_fw_rev)
sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
else
@@ -227,23 +243,27 @@ static void pcipcwd_show_card_info(void)
/* Get switch settings */
option_switches = pcipcwd_get_option_switches();
- printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n",
+ printk(KERN_INFO PFX "Found card at port "
+ "0x%04x (Firmware: %s) %s temp option\n",
(int) pcipcwd_private.io_addr, fw_ver_str,
(pcipcwd_private.supports_temp ? "with" : "without"));
- printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
+ printk(KERN_INFO PFX "Option switches (0x%02x): "
+ "Temperature Reset Enable=%s, Power On Delay=%s\n",
option_switches,
((option_switches & 0x10) ? "ON" : "OFF"),
((option_switches & 0x08) ? "ON" : "OFF"));
if (pcipcwd_private.boot_status & WDIOF_CARDRESET)
- printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n");
+ printk(KERN_INFO PFX
+ "Previous reset was caused by the Watchdog card\n");
if (pcipcwd_private.boot_status & WDIOF_OVERHEAT)
printk(KERN_INFO PFX "Card sensed a CPU Overheat\n");
if (pcipcwd_private.boot_status == 0)
- printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
+ printk(KERN_INFO PFX
+ "No previous trip detected - Cold boot or reset\n");
}
static int pcipcwd_start(void)
@@ -283,7 +303,8 @@ static int pcipcwd_stop(void)
spin_unlock(&pcipcwd_private.io_lock);
if (!(stat_reg & WD_PCI_WDIS)) {
- printk(KERN_ERR PFX "Card did not acknowledge disable attempt\n");
+ printk(KERN_ERR PFX
+ "Card did not acknowledge disable attempt\n");
return -1;
}
@@ -364,7 +385,8 @@ static int pcipcwd_clear_status(void)
}
/* clear trip status & LED and keep mode of relay 2 */
- outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1);
+ outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP,
+ pcipcwd_private.io_addr + 1);
/* clear reset counter */
msb = 0;
@@ -437,7 +459,8 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data,
* five months ago... */
expect_release = 0;
- /* scan to see whether or not we got the magic character */
+ /* scan to see whether or not we got the
+ * magic character */
for (i = 0; i != len; i++) {
char c;
if (get_user(c, data + i))
@@ -531,7 +554,7 @@ static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
if (pcipcwd_set_heartbeat(new_heartbeat))
- return -EINVAL;
+ return -EINVAL;
pcipcwd_keepalive();
/* Fall */
@@ -560,7 +583,8 @@ static int pcipcwd_open(struct inode *inode, struct file *file)
/* /dev/watchdog can only be opened once */
if (test_and_set_bit(0, &is_active)) {
if (debug >= VERBOSE)
- printk(KERN_ERR PFX "Attempt to open already opened device.\n");
+ printk(KERN_ERR PFX
+ "Attempt to open already opened device.\n");
return -EBUSY;
}
@@ -578,7 +602,8 @@ static int pcipcwd_release(struct inode *inode, struct file *file)
if (expect_release == 42) {
pcipcwd_stop();
} else {
- printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+ printk(KERN_CRIT PFX
+ "Unexpected close, not stopping watchdog!\n");
pcipcwd_keepalive();
}
expect_release = 0;
@@ -621,7 +646,8 @@ static int pcipcwd_temp_release(struct inode *inode, struct file *file)
* Notify system
*/
-static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
{
if (code == SYS_DOWN || code == SYS_HALT)
pcipcwd_stop(); /* Turn the WDT off */
@@ -722,34 +748,38 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
/* If heartbeat = 0 then we use the heartbeat from the dip-switches */
if (heartbeat == 0)
- heartbeat = heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
+ heartbeat =
+ heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
- /* Check that the heartbeat value is within it's range ; if not reset to the default */
+ /* Check that the heartbeat value is within it's range ;
+ * if not reset to the default */
if (pcipcwd_set_heartbeat(heartbeat)) {
pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
- printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n",
+ printk(KERN_INFO PFX
+ "heartbeat value must be 0<heartbeat<65536, using %d\n",
WATCHDOG_HEARTBEAT);
}
ret = register_reboot_notifier(&pcipcwd_notifier);
if (ret != 0) {
- printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
- ret);
+ printk(KERN_ERR PFX
+ "cannot register reboot notifier (err=%d)\n", ret);
goto err_out_release_region;
}
if (pcipcwd_private.supports_temp) {
ret = misc_register(&pcipcwd_temp_miscdev);
if (ret != 0) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
- TEMP_MINOR, ret);
+ printk(KERN_ERR PFX "cannot register miscdev on "
+ "minor=%d (err=%d)\n", TEMP_MINOR, ret);
goto err_out_unregister_reboot;
}
}
ret = misc_register(&pcipcwd_miscdev);
if (ret != 0) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ printk(KERN_ERR PFX
+ "cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, ret);
goto err_out_misc_deregister;
}
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index afb089695da..052fe451851 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -51,12 +51,11 @@
/* Use our own dbg macro */
#undef dbg
-#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG PFX format "\n" , ## arg); } while (0)
-
+#define dbg(format, arg...) \
+ do { if (debug) printk(KERN_DEBUG PFX format "\n" , ## arg); } while (0)
/* Module and Version Information */
#define DRIVER_VERSION "1.02"
-#define DRIVER_DATE "21 Jan 2007"
#define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
#define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
#define DRIVER_LICENSE "GPL"
@@ -73,14 +72,18 @@ MODULE_ALIAS_MISCDEV(TEMP_MINOR);
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
+#define WATCHDOG_HEARTBEAT 0 /* default heartbeat =
+ delay-time from dip-switches */
static int heartbeat = WATCHDOG_HEARTBEAT;
module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. "
+ "(0<heartbeat<65536 or 0=delay-time from dip-switches, default="
+ __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
/* The vendor and product id's for the USB-PC Watchdog card */
#define USB_PCWD_VENDOR_ID 0x0c98
@@ -91,20 +94,21 @@ static struct usb_device_id usb_pcwd_table[] = {
{ USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, usb_pcwd_table);
+MODULE_DEVICE_TABLE(usb, usb_pcwd_table);
/* according to documentation max. time to process a command for the USB
* watchdog card is 100 or 200 ms, so we give it 250 ms to do it's job */
#define USB_COMMAND_TIMEOUT 250
/* Watchdog's internal commands */
-#define CMD_READ_TEMP 0x02 /* Read Temperature; Re-trigger Watchdog */
+#define CMD_READ_TEMP 0x02 /* Read Temperature;
+ Re-trigger Watchdog */
#define CMD_TRIGGER CMD_READ_TEMP
#define CMD_GET_STATUS 0x04 /* Get Status Information */
#define CMD_GET_FIRMWARE_VERSION 0x08 /* Get Firmware Version */
#define CMD_GET_DIP_SWITCH_SETTINGS 0x0c /* Get Dip Switch Settings */
#define CMD_READ_WATCHDOG_TIMEOUT 0x18 /* Read Current Watchdog Time */
-#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 /* Write Current Watchdog Time */
+#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 /* Write Current WatchdogTime */
#define CMD_ENABLE_WATCHDOG 0x30 /* Enable / Disable Watchdog */
#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG
@@ -129,23 +133,36 @@ static char expect_release;
/* Structure to hold all of our device specific stuff */
struct usb_pcwd_private {
- struct usb_device *udev; /* save off the usb device pointer */
- struct usb_interface *interface; /* the interface for this device */
-
- unsigned int interface_number; /* the interface number used for cmd's */
-
- unsigned char *intr_buffer; /* the buffer to intr data */
- dma_addr_t intr_dma; /* the dma address for the intr buffer */
- size_t intr_size; /* the size of the intr buffer */
- struct urb *intr_urb; /* the urb used for the intr pipe */
-
- unsigned char cmd_command; /* The command that is reported back */
- unsigned char cmd_data_msb; /* The data MSB that is reported back */
- unsigned char cmd_data_lsb; /* The data LSB that is reported back */
- atomic_t cmd_received; /* true if we received a report after a command */
-
- int exists; /* Wether or not the device exists */
- struct mutex mtx; /* locks this structure */
+ /* save off the usb device pointer */
+ struct usb_device *udev;
+ /* the interface for this device */
+ struct usb_interface *interface;
+
+ /* the interface number used for cmd's */
+ unsigned int interface_number;
+
+ /* the buffer to intr data */
+ unsigned char *intr_buffer;
+ /* the dma address for the intr buffer */
+ dma_addr_t intr_dma;
+ /* the size of the intr buffer */
+ size_t intr_size;
+ /* the urb used for the intr pipe */
+ struct urb *intr_urb;
+
+ /* The command that is reported back */
+ unsigned char cmd_command;
+ /* The data MSB that is reported back */
+ unsigned char cmd_data_msb;
+ /* The data LSB that is reported back */
+ unsigned char cmd_data_lsb;
+ /* true if we received a report after a command */
+ atomic_t cmd_received;
+
+ /* Wether or not the device exists */
+ int exists;
+ /* locks this structure */
+ struct mutex mtx;
};
static struct usb_pcwd_private *usb_pcwd_device;
@@ -153,7 +170,8 @@ static struct usb_pcwd_private *usb_pcwd_device;
static DEFINE_MUTEX(disconnect_mutex);
/* local function prototypes */
-static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_device_id *id);
+static int usb_pcwd_probe(struct usb_interface *interface,
+ const struct usb_device_id *id);
static void usb_pcwd_disconnect(struct usb_interface *interface);
/* usb specific object needed to register this driver with the usb subsystem */
@@ -167,7 +185,8 @@ static struct usb_driver usb_pcwd_driver = {
static void usb_pcwd_intr_done(struct urb *urb)
{
- struct usb_pcwd_private *usb_pcwd = (struct usb_pcwd_private *)urb->context;
+ struct usb_pcwd_private *usb_pcwd =
+ (struct usb_pcwd_private *)urb->context;
unsigned char *data = usb_pcwd->intr_buffer;
int retval;
@@ -178,11 +197,13 @@ static void usb_pcwd_intr_done(struct urb *urb)
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __func__, urb->status);
+ dbg("%s - urb shutting down with status: %d", __func__,
+ urb->status);
return;
/* -EPIPE: should clear the halt */
default: /* error */
- dbg("%s - nonzero urb status received: %d", __func__, urb->status);
+ dbg("%s - nonzero urb status received: %d", __func__,
+ urb->status);
goto resubmit;
}
@@ -199,22 +220,23 @@ static void usb_pcwd_intr_done(struct urb *urb)
resubmit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- printk(KERN_ERR PFX "can't resubmit intr, usb_submit_urb failed with result %d\n",
- retval);
+ printk(KERN_ERR PFX "can't resubmit intr, "
+ "usb_submit_urb failed with result %d\n", retval);
}
-static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned char cmd,
- unsigned char *msb, unsigned char *lsb)
+static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd,
+ unsigned char cmd, unsigned char *msb, unsigned char *lsb)
{
int got_response, count;
unsigned char buf[6];
- /* We will not send any commands if the USB PCWD device does not exist */
+ /* We will not send any commands if the USB PCWD device does
+ * not exist */
if ((!usb_pcwd) || (!usb_pcwd->exists))
return -1;
- /* The USB PC Watchdog uses a 6 byte report format. The board currently uses
- * only 3 of the six bytes of the report. */
+ /* The USB PC Watchdog uses a 6 byte report format.
+ * The board currently uses only 3 of the six bytes of the report. */
buf[0] = cmd; /* Byte 0 = CMD */
buf[1] = *msb; /* Byte 1 = Data MSB */
buf[2] = *lsb; /* Byte 2 = Data LSB */
@@ -229,12 +251,14 @@ static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned cha
HID_REQ_SET_REPORT, HID_DT_REPORT,
0x0200, usb_pcwd->interface_number, buf, sizeof(buf),
USB_COMMAND_TIMEOUT) != sizeof(buf)) {
- dbg("usb_pcwd_send_command: error in usb_control_msg for cmd 0x%x 0x%x 0x%x\n", cmd, *msb, *lsb);
+ dbg("usb_pcwd_send_command: error in usb_control_msg for "
+ "cmd 0x%x 0x%x 0x%x\n", cmd, *msb, *lsb);
}
/* wait till the usb card processed the command,
* with a max. timeout of USB_COMMAND_TIMEOUT */
got_response = 0;
- for (count = 0; (count < USB_COMMAND_TIMEOUT) && (!got_response); count++) {
+ for (count = 0; (count < USB_COMMAND_TIMEOUT) && (!got_response);
+ count++) {
mdelay(1);
if (atomic_read(&usb_pcwd->cmd_received))
got_response = 1;
@@ -256,10 +280,12 @@ static int usb_pcwd_start(struct usb_pcwd_private *usb_pcwd)
int retval;
/* Enable Watchdog */
- retval = usb_pcwd_send_command(usb_pcwd, CMD_ENABLE_WATCHDOG, &msb, &lsb);
+ retval = usb_pcwd_send_command(usb_pcwd, CMD_ENABLE_WATCHDOG,
+ &msb, &lsb);
if ((retval == 0) || (lsb == 0)) {
- printk(KERN_ERR PFX "Card did not acknowledge enable attempt\n");
+ printk(KERN_ERR PFX
+ "Card did not acknowledge enable attempt\n");
return -1;
}
@@ -273,10 +299,12 @@ static int usb_pcwd_stop(struct usb_pcwd_private *usb_pcwd)
int retval;
/* Disable Watchdog */
- retval = usb_pcwd_send_command(usb_pcwd, CMD_DISABLE_WATCHDOG, &msb, &lsb);
+ retval = usb_pcwd_send_command(usb_pcwd, CMD_DISABLE_WATCHDOG,
+ &msb, &lsb);
if ((retval == 0) || (lsb != 0)) {
- printk(KERN_ERR PFX "Card did not acknowledge disable attempt\n");
+ printk(KERN_ERR PFX
+ "Card did not acknowledge disable attempt\n");
return -1;
}
@@ -308,7 +336,8 @@ static int usb_pcwd_set_heartbeat(struct usb_pcwd_private *usb_pcwd, int t)
return 0;
}
-static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temperature)
+static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd,
+ int *temperature)
{
unsigned char msb, lsb;
@@ -323,7 +352,8 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temp
return 0;
}
-static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left)
+static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd,
+ int *time_left)
{
unsigned char msb, lsb;
@@ -341,7 +371,7 @@ static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_le
*/
static ssize_t usb_pcwd_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
+ size_t len, loff_t *ppos)
{
/* See if we got the magic character 'V' and reload the timer */
if (len) {
@@ -352,7 +382,8 @@ static ssize_t usb_pcwd_write(struct file *file, const char __user *data,
* five months ago... */
expect_release = 0;
- /* scan to see whether or not we got the magic character */
+ /* scan to see whether or not we got the
+ * magic character */
for (i = 0; i != len; i++) {
char c;
if (get_user(c, data + i))
@@ -431,7 +462,7 @@ static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat))
- return -EINVAL;
+ return -EINVAL;
usb_pcwd_keepalive(usb_pcwd_device);
/* Fall */
@@ -475,7 +506,8 @@ static int usb_pcwd_release(struct inode *inode, struct file *file)
if (expect_release == 42) {
usb_pcwd_stop(usb_pcwd_device);
} else {
- printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+ printk(KERN_CRIT PFX
+ "Unexpected close, not stopping watchdog!\n");
usb_pcwd_keepalive(usb_pcwd_device);
}
expect_release = 0;
@@ -515,7 +547,8 @@ static int usb_pcwd_temperature_release(struct inode *inode, struct file *file)
* Notify system
*/
-static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
{
if (code == SYS_DOWN || code == SYS_HALT)
usb_pcwd_stop(usb_pcwd_device); /* Turn the WDT off */
@@ -578,7 +611,8 @@ static inline void usb_pcwd_delete(struct usb_pcwd_private *usb_pcwd)
* Called by the usb core when a new device is connected that it thinks
* this driver might be interested in.
*/
-static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_device_id *id)
+static int usb_pcwd_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
struct usb_host_interface *iface_desc;
@@ -602,16 +636,15 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
/* check out that we have a HID device */
if (!(iface_desc->desc.bInterfaceClass == USB_CLASS_HID)) {
- printk(KERN_ERR PFX "The device isn't a Human Interface Device\n");
+ printk(KERN_ERR PFX
+ "The device isn't a Human Interface Device\n");
return -ENODEV;
}
/* check out the endpoint: it has to be Interrupt & IN */
endpoint = &iface_desc->endpoint[0].desc;
- if (!((endpoint->bEndpointAddress & USB_DIR_IN) &&
- ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_INT))) {
+ if (!usb_endpoint_is_int_in(endpoint)) {
/* we didn't find a Interrupt endpoint with direction IN */
printk(KERN_ERR PFX "Couldn't find an INTR & IN endpoint\n");
return -ENODEV;
@@ -634,10 +667,12 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
usb_pcwd->udev = udev;
usb_pcwd->interface = interface;
usb_pcwd->interface_number = iface_desc->desc.bInterfaceNumber;
- usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8);
+ usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ?
+ le16_to_cpu(endpoint->wMaxPacketSize) : 8);
/* set up the memory buffer's */
- usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma);
+ usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size,
+ GFP_ATOMIC, &usb_pcwd->intr_dma);
if (!usb_pcwd->intr_buffer) {
printk(KERN_ERR PFX "Out of memory\n");
goto error;
@@ -671,7 +706,8 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
usb_pcwd_stop(usb_pcwd);
/* Get the Firmware Version */
- got_fw_rev = usb_pcwd_send_command(usb_pcwd, CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
+ got_fw_rev = usb_pcwd_send_command(usb_pcwd, CMD_GET_FIRMWARE_VERSION,
+ &fw_rev_major, &fw_rev_minor);
if (got_fw_rev)
sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
else
@@ -681,9 +717,11 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
fw_ver_str);
/* Get switch settings */
- usb_pcwd_send_command(usb_pcwd, CMD_GET_DIP_SWITCH_SETTINGS, &dummy, &option_switches);
+ usb_pcwd_send_command(usb_pcwd, CMD_GET_DIP_SWITCH_SETTINGS, &dummy,
+ &option_switches);
- printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
+ printk(KERN_INFO PFX "Option switches (0x%02x): "
+ "Temperature Reset Enable=%s, Power On Delay=%s\n",
option_switches,
((option_switches & 0x10) ? "ON" : "OFF"),
((option_switches & 0x08) ? "ON" : "OFF"));
@@ -692,30 +730,35 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
if (heartbeat == 0)
heartbeat = heartbeat_tbl[(option_switches & 0x07)];
- /* Check that the heartbeat value is within it's range ; if not reset to the default */
+ /* Check that the heartbeat value is within it's range ;
+ * if not reset to the default */
if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) {
usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT);
- printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n",
+ printk(KERN_INFO PFX
+ "heartbeat value must be 0<heartbeat<65536, using %d\n",
WATCHDOG_HEARTBEAT);
}
retval = register_reboot_notifier(&usb_pcwd_notifier);
if (retval != 0) {
- printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+ printk(KERN_ERR PFX
+ "cannot register reboot notifier (err=%d)\n",
retval);
goto error;
}
retval = misc_register(&usb_pcwd_temperature_miscdev);
if (retval != 0) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ printk(KERN_ERR PFX
+ "cannot register miscdev on minor=%d (err=%d)\n",
TEMP_MINOR, retval);
goto err_out_unregister_reboot;
}
retval = misc_register(&usb_pcwd_miscdev);
if (retval != 0) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ printk(KERN_ERR PFX
+ "cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, retval);
goto err_out_misc_deregister;
}
@@ -801,7 +844,7 @@ static int __init usb_pcwd_init(void)
return result;
}
- printk(KERN_INFO PFX DRIVER_DESC " v" DRIVER_VERSION " (" DRIVER_DATE ")\n");
+ printk(KERN_INFO PFX DRIVER_DESC " v" DRIVER_VERSION "\n");
return 0;
}
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 6d9f3d4a998..64135195f82 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -54,22 +54,22 @@
/* WDTIM_CTRL bit definitions */
#define COUNT_ENAB 1
-#define RESET_COUNT (1<<1)
-#define DEBUG_EN (1<<2)
+#define RESET_COUNT (1 << 1)
+#define DEBUG_EN (1 << 2)
/* WDTIM_MCTRL bit definitions */
#define MR0_INT 1
#undef RESET_COUNT0
-#define RESET_COUNT0 (1<<2)
-#define STOP_COUNT0 (1<<2)
-#define M_RES1 (1<<3)
-#define M_RES2 (1<<4)
-#define RESFRC1 (1<<5)
-#define RESFRC2 (1<<6)
+#define RESET_COUNT0 (1 << 2)
+#define STOP_COUNT0 (1 << 2)
+#define M_RES1 (1 << 3)
+#define M_RES2 (1 << 4)
+#define RESFRC1 (1 << 5)
+#define RESFRC2 (1 << 6)
/* WDTIM_EMR bit definitions */
#define EXT_MATCH0 1
-#define MATCH_OUTPUT_HIGH (2<<4) /*a MATCH_CTRL setting */
+#define MATCH_OUTPUT_HIGH (2 << 4) /*a MATCH_CTRL setting */
/* WDTIM_RES bit definitions */
#define WDOG_RESET 1 /* read only */
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index 57027f4653c..f6cccc9df02 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -17,121 +17,127 @@
*
*/
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/reboot.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-
-#include <asm/bootinfo.h>
-#include <asm/time.h>
-#include <asm/mach-rc32434/integ.h>
-
-#define MAX_TIMEOUT 20
-#define RC32434_WDT_INTERVAL (15 * HZ)
-
-#define VERSION "0.2"
+#include <linux/module.h> /* For module specific items */
+#include <linux/moduleparam.h> /* For new moduleparam's */
+#include <linux/types.h> /* For standard types (like size_t) */
+#include <linux/errno.h> /* For the -ENODEV/... values */
+#include <linux/kernel.h> /* For printk/panic/... */
+#include <linux/fs.h> /* For file operations */
+#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV
+ (WATCHDOG_MINOR) */
+#include <linux/watchdog.h> /* For the watchdog specific items */
+#include <linux/init.h> /* For __init/__exit/... */
+#include <linux/platform_device.h> /* For platform_driver framework */
+#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
+#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
+
+#include <asm/mach-rc32434/integ.h> /* For the Watchdog registers */
+
+#define PFX KBUILD_MODNAME ": "
+
+#define VERSION "1.0"
static struct {
- struct completion stop;
- int running;
- struct timer_list timer;
- int queue;
- int default_ticks;
unsigned long inuse;
+ spinlock_t io_lock;
} rc32434_wdt_device;
static struct integ __iomem *wdt_reg;
-static int ticks = 100 * HZ;
static int expect_close;
-static int timeout;
+
+/* Board internal clock speed in Hz,
+ * the watchdog timer ticks at. */
+extern unsigned int idt_cpu_freq;
+
+/* translate wtcompare value to seconds and vice versa */
+#define WTCOMP2SEC(x) (x / idt_cpu_freq)
+#define SEC2WTCOMP(x) (x * idt_cpu_freq)
+
+/* Use a default timeout of 20s. This should be
+ * safe for CPU clock speeds up to 400MHz, as
+ * ((2 ^ 32) - 1) / (400MHz / 2) = 21s. */
+#define WATCHDOG_TIMEOUT 20
+
+static int timeout = WATCHDOG_TIMEOUT;
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout value, in seconds (default="
+ WATCHDOG_TIMEOUT ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+/* apply or and nand masks to data read from addr and write back */
+#define SET_BITS(addr, or, nand) \
+ writel((readl(&addr) | or) & ~nand, &addr)
-static void rc32434_wdt_start(void)
+static int rc32434_wdt_set(int new_timeout)
{
- u32 val;
-
- if (!rc32434_wdt_device.inuse) {
- writel(0, &wdt_reg->wtcount);
+ int max_to = WTCOMP2SEC((u32)-1);
- val = RC32434_ERR_WRE;
- writel(readl(&wdt_reg->errcs) | val, &wdt_reg->errcs);
-
- val = RC32434_WTC_EN;
- writel(readl(&wdt_reg->wtc) | val, &wdt_reg->wtc);
+ if (new_timeout < 0 || new_timeout > max_to) {
+ printk(KERN_ERR PFX "timeout value must be between 0 and %d",
+ max_to);
+ return -EINVAL;
}
- rc32434_wdt_device.running++;
+ timeout = new_timeout;
+ spin_lock(&rc32434_wdt_device.io_lock);
+ writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare);
+ spin_unlock(&rc32434_wdt_device.io_lock);
+
+ return 0;
}
-static void rc32434_wdt_stop(void)
+static void rc32434_wdt_start(void)
{
- u32 val;
+ u32 or, nand;
- if (rc32434_wdt_device.running) {
+ spin_lock(&rc32434_wdt_device.io_lock);
- val = ~RC32434_WTC_EN;
- writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc);
+ /* zero the counter before enabling */
+ writel(0, &wdt_reg->wtcount);
- val = ~RC32434_ERR_WRE;
- writel(readl(&wdt_reg->errcs) & val, &wdt_reg->errcs);
+ /* don't generate a non-maskable interrupt,
+ * do a warm reset instead */
+ nand = 1 << RC32434_ERR_WNE;
+ or = 1 << RC32434_ERR_WRE;
- rc32434_wdt_device.running = 0;
- }
-}
+ /* reset the ERRCS timeout bit in case it's set */
+ nand |= 1 << RC32434_ERR_WTO;
-static void rc32434_wdt_set(int new_timeout)
-{
- u32 cmp = new_timeout * HZ;
- u32 state, val;
+ SET_BITS(wdt_reg->errcs, or, nand);
- timeout = new_timeout;
- /*
- * store and disable WTC
- */
- state = (u32)(readl(&wdt_reg->wtc) & RC32434_WTC_EN);
- val = ~RC32434_WTC_EN;
- writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc);
+ /* set the timeout (either default or based on module param) */
+ rc32434_wdt_set(timeout);
- writel(0, &wdt_reg->wtcount);
- writel(cmp, &wdt_reg->wtcompare);
+ /* reset WTC timeout bit and enable WDT */
+ nand = 1 << RC32434_WTC_TO;
+ or = 1 << RC32434_WTC_EN;
- /*
- * restore WTC
- */
+ SET_BITS(wdt_reg->wtc, or, nand);
- writel(readl(&wdt_reg->wtc) | state, &wdt_reg);
+ spin_unlock(&rc32434_wdt_device.io_lock);
+ printk(KERN_INFO PFX "Started watchdog timer.\n");
}
-static void rc32434_wdt_reset(void)
+static void rc32434_wdt_stop(void)
{
- ticks = rc32434_wdt_device.default_ticks;
+ spin_lock(&rc32434_wdt_device.io_lock);
+
+ /* Disable WDT */
+ SET_BITS(wdt_reg->wtc, 0, 1 << RC32434_WTC_EN);
+
+ spin_unlock(&rc32434_wdt_device.io_lock);
+ printk(KERN_INFO PFX "Stopped watchdog timer.\n");
}
-static void rc32434_wdt_update(unsigned long unused)
+static void rc32434_wdt_ping(void)
{
- if (rc32434_wdt_device.running)
- ticks--;
-
+ spin_lock(&rc32434_wdt_device.io_lock);
writel(0, &wdt_reg->wtcount);
-
- if (rc32434_wdt_device.queue && ticks)
- mod_timer(&rc32434_wdt_device.timer,
- jiffies + RC32434_WDT_INTERVAL);
- else
- complete(&rc32434_wdt_device.stop);
+ spin_unlock(&rc32434_wdt_device.io_lock);
}
static int rc32434_wdt_open(struct inode *inode, struct file *file)
@@ -142,19 +148,22 @@ static int rc32434_wdt_open(struct inode *inode, struct file *file)
if (nowayout)
__module_get(THIS_MODULE);
+ rc32434_wdt_start();
+ rc32434_wdt_ping();
+
return nonseekable_open(inode, file);
}
static int rc32434_wdt_release(struct inode *inode, struct file *file)
{
- if (expect_close && nowayout == 0) {
+ if (expect_close == 42) {
rc32434_wdt_stop();
- printk(KERN_INFO KBUILD_MODNAME ": disabling watchdog timer\n");
module_put(THIS_MODULE);
- } else
- printk(KERN_CRIT KBUILD_MODNAME
- ": device closed unexpectedly. WDT will not stop !\n");
-
+ } else {
+ printk(KERN_CRIT PFX
+ "device closed unexpectedly. WDT will not stop!\n");
+ rc32434_wdt_ping();
+ }
clear_bit(0, &rc32434_wdt_device.inuse);
return 0;
}
@@ -174,10 +183,10 @@ static ssize_t rc32434_wdt_write(struct file *file, const char *data,
if (get_user(c, data + i))
return -EFAULT;
if (c == 'V')
- expect_close = 1;
+ expect_close = 42;
}
}
- rc32434_wdt_update(0);
+ rc32434_wdt_ping();
return len;
}
return 0;
@@ -196,19 +205,16 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
.identity = "RC32434_WDT Watchdog",
};
switch (cmd) {
- case WDIOC_KEEPALIVE:
- rc32434_wdt_reset();
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user(argp, &ident, sizeof(ident)))
+ return -EFAULT;
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- value = readl(&wdt_reg->wtcount);
+ value = 0;
if (copy_to_user(argp, &value, sizeof(int)))
return -EFAULT;
break;
- case WDIOC_GETSUPPORT:
- if (copy_to_user(argp, &ident, sizeof(ident)))
- return -EFAULT;
- break;
case WDIOC_SETOPTIONS:
if (copy_from_user(&value, argp, sizeof(int)))
return -EFAULT;
@@ -218,18 +224,20 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
break;
case WDIOS_DISABLECARD:
rc32434_wdt_stop();
+ break;
default:
return -EINVAL;
}
break;
+ case WDIOC_KEEPALIVE:
+ rc32434_wdt_ping();
+ break;
case WDIOC_SETTIMEOUT:
if (copy_from_user(&new_timeout, argp, sizeof(int)))
return -EFAULT;
- if (new_timeout < 1)
+ if (rc32434_wdt_set(new_timeout))
return -EINVAL;
- if (new_timeout > MAX_TIMEOUT)
- return -EINVAL;
- rc32434_wdt_set(new_timeout);
+ /* Fall through */
case WDIOC_GETTIMEOUT:
return copy_to_user(argp, &timeout, sizeof(int));
default:
@@ -239,7 +247,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
return 0;
}
-static struct file_operations rc32434_wdt_fops = {
+static const struct file_operations rc32434_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = rc32434_wdt_write,
@@ -254,47 +262,46 @@ static struct miscdevice rc32434_wdt_miscdev = {
.fops = &rc32434_wdt_fops,
};
-static char banner[] = KERN_INFO KBUILD_MODNAME
- ": Watchdog Timer version " VERSION ", timer margin: %d sec\n";
+static char banner[] __devinitdata = KERN_INFO PFX
+ "Watchdog Timer version " VERSION ", timer margin: %d sec\n";
-static int rc32434_wdt_probe(struct platform_device *pdev)
+static int __devinit rc32434_wdt_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
- r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb500_wdt_res");
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb532_wdt_res");
if (!r) {
- printk(KERN_ERR KBUILD_MODNAME
- "failed to retrieve resources\n");
+ printk(KERN_ERR PFX "failed to retrieve resources\n");
return -ENODEV;
}
wdt_reg = ioremap_nocache(r->start, r->end - r->start);
if (!wdt_reg) {
- printk(KERN_ERR KBUILD_MODNAME
- "failed to remap I/O resources\n");
+ printk(KERN_ERR PFX "failed to remap I/O resources\n");
return -ENXIO;
}
- ret = misc_register(&rc32434_wdt_miscdev);
+ spin_lock_init(&rc32434_wdt_device.io_lock);
+
+ /* Make sure the watchdog is not running */
+ rc32434_wdt_stop();
+
+ /* Check that the heartbeat value is within it's range;
+ * if not reset to the default */
+ if (rc32434_wdt_set(timeout)) {
+ rc32434_wdt_set(WATCHDOG_TIMEOUT);
+ printk(KERN_INFO PFX
+ "timeout value must be between 0 and %d\n",
+ WTCOMP2SEC((u32)-1));
+ }
+ ret = misc_register(&rc32434_wdt_miscdev);
if (ret < 0) {
- printk(KERN_ERR KBUILD_MODNAME
- "failed to register watchdog device\n");
+ printk(KERN_ERR PFX "failed to register watchdog device\n");
goto unmap;
}
- init_completion(&rc32434_wdt_device.stop);
- rc32434_wdt_device.queue = 0;
-
- clear_bit(0, &rc32434_wdt_device.inuse);
-
- setup_timer(&rc32434_wdt_device.timer, rc32434_wdt_update, 0L);
-
- rc32434_wdt_device.default_ticks = ticks;
-
- rc32434_wdt_start();
-
printk(banner, timeout);
return 0;
@@ -304,35 +311,35 @@ unmap:
return ret;
}
-static int rc32434_wdt_remove(struct platform_device *pdev)
+static int __devexit rc32434_wdt_remove(struct platform_device *pdev)
{
- if (rc32434_wdt_device.queue) {
- rc32434_wdt_device.queue = 0;
- wait_for_completion(&rc32434_wdt_device.stop);
- }
misc_deregister(&rc32434_wdt_miscdev);
-
iounmap(wdt_reg);
-
return 0;
}
-static struct platform_driver rc32434_wdt = {
- .probe = rc32434_wdt_probe,
- .remove = rc32434_wdt_remove,
- .driver = {
- .name = "rc32434_wdt",
+static void rc32434_wdt_shutdown(struct platform_device *pdev)
+{
+ rc32434_wdt_stop();
+}
+
+static struct platform_driver rc32434_wdt_driver = {
+ .probe = rc32434_wdt_probe,
+ .remove = __devexit_p(rc32434_wdt_remove),
+ .shutdown = rc32434_wdt_shutdown,
+ .driver = {
+ .name = "rc32434_wdt",
}
};
static int __init rc32434_wdt_init(void)
{
- return platform_driver_register(&rc32434_wdt);
+ return platform_driver_register(&rc32434_wdt_driver);
}
static void __exit rc32434_wdt_exit(void)
{
- platform_driver_unregister(&rc32434_wdt);
+ platform_driver_unregister(&rc32434_wdt_driver);
}
module_init(rc32434_wdt_init);
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index 09cb1833ea2..1e8f02f440e 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -14,9 +14,8 @@
#include <linux/watchdog.h>
#include <linux/of.h>
#include <linux/of_device.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
/* RIO uses the NatSemi Super I/O power management logical device
@@ -86,8 +85,7 @@ static int riowd_release(struct inode *inode, struct file *filp)
return 0;
}
-static int riowd_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
static struct watchdog_info info = {
.options = WDIOF_SETTIMEOUT,
@@ -147,7 +145,8 @@ static int riowd_ioctl(struct inode *inode, struct file *filp,
return 0;
}
-static ssize_t riowd_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+static ssize_t riowd_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
{
struct riowd *p = riowd_device;
@@ -160,12 +159,12 @@ static ssize_t riowd_write(struct file *file, const char __user *buf, size_t cou
}
static const struct file_operations riowd_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .ioctl = riowd_ioctl,
- .open = riowd_open,
- .write = riowd_write,
- .release = riowd_release,
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .unlocked_ioctl = riowd_ioctl,
+ .open = riowd_open,
+ .write = riowd_write,
+ .release = riowd_release,
};
static struct miscdevice riowd_miscdev = {
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index f1ae3729a19..cce1982a1b5 100644
--- a/drivers/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
@@ -59,8 +59,8 @@ static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long);
static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *);
static const struct resource *wdt_gpi_get_resource(struct platform_device *,
const char *, unsigned int);
-static int __init wdt_gpi_probe(struct device *);
-static int __exit wdt_gpi_remove(struct device *);
+static int __init wdt_gpi_probe(struct platform_device *);
+static int __exit wdt_gpi_remove(struct platform_device *);
static const char wdt_gpi_name[] = "wdt_gpi";
@@ -346,10 +346,9 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
}
/* No hotplugging on the platform bus - use __init */
-static int __init wdt_gpi_probe(struct device *dev)
+static int __init wdt_gpi_probe(struct platform_device *pdv)
{
int res;
- struct platform_device * const pdv = to_platform_device(dev);
const struct resource
* const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS,
IORESOURCE_MEM),
@@ -374,7 +373,7 @@ static int __init wdt_gpi_probe(struct device *dev)
return res;
}
-static int __exit wdt_gpi_remove(struct device *dev)
+static int __exit wdt_gpi_remove(struct platform_device *dev)
{
int res;
@@ -387,15 +386,13 @@ static int __exit wdt_gpi_remove(struct device *dev)
/* Device driver init & exit */
-static struct device_driver wdt_gpi_driver = {
- .name = (char *) wdt_gpi_name,
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
+static struct platform_driver wgt_gpi_driver = {
+ .driver = {
+ .name = wdt_gpi_name,
+ .owner = THIS_MODULE,
+ },
.probe = wdt_gpi_probe,
- .remove = __exit_p(wdt_gpi_remove),
- .shutdown = NULL,
- .suspend = NULL,
- .resume = NULL,
+ .remove = __devexit_p(wdt_gpi_remove),
};
static int __init wdt_gpi_init_module(void)
@@ -403,12 +400,12 @@ static int __init wdt_gpi_init_module(void)
atomic_set(&opencnt, 1);
if (timeout > MAX_TIMEOUT_SECONDS)
timeout = MAX_TIMEOUT_SECONDS;
- return driver_register(&wdt_gpi_driver);
+ return platform_driver_register(&wdt_gpi_driver);
}
static void __exit wdt_gpi_cleanup_module(void)
{
- driver_unregister(&wdt_gpi_driver);
+ platform_driver_unregister(&wdt_gpi_driver);
}
module_init(wdt_gpi_init_module);
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index e19b4579471..5bd782f2783 100644
--- a/drivers/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -1,8 +1,8 @@
/*
* Watchdog driver for the SA11x0/PXA2xx
*
- * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
- * Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
+ * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
+ * Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -15,7 +15,7 @@
*
* (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
*
- * 27/11/2000 Initial release
+ * 27/11/2000 Initial release
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c
index 3266daaaecf..d1c390c7155 100644
--- a/drivers/watchdog/sbc60xxwdt.c
+++ b/drivers/watchdog/sbc60xxwdt.c
@@ -1,7 +1,7 @@
/*
* 60xx Single Board Computer Watchdog Timer driver for Linux 2.2.x
*
- * Based on acquirewdt.c by Alan Cox.
+ * Based on acquirewdt.c by Alan Cox.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c
index ae74f6bcfa2..b6e6799ec45 100644
--- a/drivers/watchdog/sbc8360.c
+++ b/drivers/watchdog/sbc8360.c
@@ -4,12 +4,12 @@
* (c) Copyright 2005 Webcon, Inc.
*
* Based on ib700wdt.c, which is based on advantechwdt.c which is based
- * on acquirewdt.c which is based on wdt.c.
+ * on acquirewdt.c which is based on wdt.c.
*
* (c) Copyright 2001 Charles Howes <chowes@vsol.net>
*
- * Based on advantechwdt.c which is based on acquirewdt.c which
- * is based on wdt.c.
+ * Based on advantechwdt.c which is based on acquirewdt.c which
+ * is based on wdt.c.
*
* (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
*
@@ -30,9 +30,9 @@
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*
- * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
- * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- * Added timeout module option to override default
+ * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ * Added timeout module option to override default
*
*/
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c
index 06553debc7b..e467ddcf796 100644
--- a/drivers/watchdog/sbc_epx_c3.c
+++ b/drivers/watchdog/sbc_epx_c3.c
@@ -35,7 +35,8 @@ static int epx_c3_alive;
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
#define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */
#define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c
index 23da3ccd832..b5e19c1820a 100644
--- a/drivers/watchdog/sc1200wdt.c
+++ b/drivers/watchdog/sc1200wdt.c
@@ -71,7 +71,7 @@
#define UART2_IRQ 0x04 /* Serial1 */
/* 5 -7 are reserved */
-static char banner[] __initdata = KERN_INFO PFX SC1200_MODULE_VER;
+static char banner[] __initdata = PFX SC1200_MODULE_VER;
static int timeout = 1;
static int io = -1;
static int io_len = 2; /* for non plug and play */
@@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void)
{
int ret;
- printk("%s\n", banner);
+ printk(KERN_INFO "%s\n", banner);
#if defined CONFIG_PNP
if (isapnp) {
@@ -477,6 +477,7 @@ module_init(sc1200wdt_init);
module_exit(sc1200wdt_exit);
MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
-MODULE_DESCRIPTION("Driver for National Semiconductor PC87307/PC97307 watchdog component");
+MODULE_DESCRIPTION(
+ "Driver for National Semiconductor PC87307/PC97307 watchdog component");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
index a2b6c1067ec..52b63f2f0da 100644
--- a/drivers/watchdog/sc520_wdt.c
+++ b/drivers/watchdog/sc520_wdt.c
@@ -1,8 +1,8 @@
/*
* AMD Elan SC520 processor Watchdog Timer driver
*
- * Based on acquirewdt.c by Alan Cox,
- * and sbc60xxwdt.c by Jakob Oestergaard <jakob@unthought.net>
+ * Based on acquirewdt.c by Alan Cox,
+ * and sbc60xxwdt.c by Jakob Oestergaard <jakob@unthought.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -11,7 +11,7 @@
*
* The authors do NOT admit liability nor provide warranty for
* any of this software. This material is provided "AS-IS" in
- * the hope that it may be useful for others.
+ * the hope that it may be useful for others.
*
* (c) Copyright 2001 Scott Jennings <linuxdrivers@oro.net>
* 9/27 - 2001 [Initial release]
@@ -438,6 +438,7 @@ module_init(sc520_wdt_init);
module_exit(sc520_wdt_unload);
MODULE_AUTHOR("Scott and Bill Jennings");
-MODULE_DESCRIPTION("Driver for watchdog timer in AMD \"Elan\" SC520 uProcessor");
+MODULE_DESCRIPTION(
+ "Driver for watchdog timer in AMD \"Elan\" SC520 uProcessor");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c
index 2e56cad77d1..8a1f0bc3e27 100644
--- a/drivers/watchdog/smsc37b787_wdt.c
+++ b/drivers/watchdog/smsc37b787_wdt.c
@@ -2,7 +2,7 @@
* SMsC 37B787 Watchdog Timer driver for Linux 2.6.x.x
*
* Based on acquirewdt.c by Alan Cox <alan@lxorguk.ukuu.org.uk>
- * and some other existing drivers
+ * and some other existing drivers
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -11,7 +11,7 @@
*
* The authors do NOT admit liability nor provide warranty for
* any of this software. This material is provided "AS-IS" in
- * the hope that it may be useful for others.
+ * the hope that it may be useful for others.
*
* (C) Copyright 2003-2006 Sven Anders <anders@anduras.de>
*
@@ -22,19 +22,19 @@
*
* Theory of operation:
*
- * A Watchdog Timer (WDT) is a hardware circuit that can
- * reset the computer system in case of a software fault.
- * You probably knew that already.
+ * A Watchdog Timer (WDT) is a hardware circuit that can
+ * reset the computer system in case of a software fault.
+ * You probably knew that already.
*
- * Usually a userspace daemon will notify the kernel WDT driver
- * via the /dev/watchdog special device file that userspace is
- * still alive, at regular intervals. When such a notification
- * occurs, the driver will usually tell the hardware watchdog
- * that everything is in order, and that the watchdog should wait
- * for yet another little while to reset the system.
- * If userspace fails (RAM error, kernel bug, whatever), the
- * notifications cease to occur, and the hardware watchdog will
- * reset the system (causing a reboot) after the timeout occurs.
+ * Usually a userspace daemon will notify the kernel WDT driver
+ * via the /dev/watchdog special device file that userspace is
+ * still alive, at regular intervals. When such a notification
+ * occurs, the driver will usually tell the hardware watchdog
+ * that everything is in order, and that the watchdog should wait
+ * for yet another little while to reset the system.
+ * If userspace fails (RAM error, kernel bug, whatever), the
+ * notifications cease to occur, and the hardware watchdog will
+ * reset the system (causing a reboot) after the timeout occurs.
*
* Create device with:
* mknod /dev/watchdog c 10 130
@@ -485,7 +485,7 @@ static long wb_smsc_wdt_ioctl(struct file *file,
case WDIOC_GETTIMEOUT:
new_timeout = timeout;
if (unit == UNIT_MINUTE)
- new_timeout *= 60;
+ new_timeout *= 60;
return put_user(new_timeout, uarg.i);
default:
return -ENOTTY;
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index 7204f966211..ebcc9cea5e9 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -1,7 +1,8 @@
/*
* SoftDog 0.07: A Software Watchdog Device
*
- * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>, All Rights Reserved.
+ * (c) Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>,
+ * 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
@@ -32,7 +33,7 @@
* Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
*
* 20020530 Joel Becker <joel.becker@oracle.com>
- * Added Matt Domsch's nowayout module option.
+ * Added Matt Domsch's nowayout module option.
*/
#include <linux/module.h>
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
index 3c7aa412b1f..a9c7f352fcb 100644
--- a/drivers/watchdog/w83697hf_wdt.c
+++ b/drivers/watchdog/w83697hf_wdt.c
@@ -462,6 +462,7 @@ module_init(wdt_init);
module_exit(wdt_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marcus Junker <junker@anduras.de>, Samuel Tardieu <sam@rfc1149.net>");
+MODULE_AUTHOR("Marcus Junker <junker@anduras.de>, "
+ "Samuel Tardieu <sam@rfc1149.net>");
MODULE_DESCRIPTION("w83697hf/hg WDT driver");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/w83697ug_wdt.c b/drivers/watchdog/w83697ug_wdt.c
index ada8ad82d99..883b5f79673 100644
--- a/drivers/watchdog/w83697ug_wdt.c
+++ b/drivers/watchdog/w83697ug_wdt.c
@@ -2,7 +2,7 @@
* w83697ug/uf WDT driver
*
* (c) Copyright 2008 Flemming Fransen <ff@nrvissing.net>
- * reused original code to supoprt w83697ug/uf.
+ * reused original code to support w83697ug/uf.
*
* Based on w83627hf_wdt.c which is based on advantechwdt.c
* which is based on wdt.c.
@@ -79,7 +79,7 @@ MODULE_PARM_DESC(nowayout,
(same as EFER) */
#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */
-static void w83697ug_select_wd_register(void)
+static int w83697ug_select_wd_register(void)
{
unsigned char c;
unsigned char version;
@@ -102,7 +102,7 @@ static void w83697ug_select_wd_register(void)
} else {
printk(KERN_ERR PFX "No W83697UG/UF could be found\n");
- return;
+ return -ENODEV;
}
outb_p(0x07, WDT_EFER); /* point to logical device number reg */
@@ -110,6 +110,8 @@ static void w83697ug_select_wd_register(void)
outb_p(0x30, WDT_EFER); /* select CR30 */
c = inb_p(WDT_EFDR);
outb_p(c || 0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */
+
+ return 0;
}
static void w83697ug_unselect_wd_register(void)
@@ -117,11 +119,14 @@ static void w83697ug_unselect_wd_register(void)
outb_p(0xAA, WDT_EFER); /* Leave extended function mode */
}
-static void w83697ug_init(void)
+static int w83697ug_init(void)
{
+ int ret;
unsigned char t;
- w83697ug_select_wd_register();
+ ret = w83697ug_select_wd_register();
+ if (ret != 0)
+ return ret;
outb_p(0xF6, WDT_EFER); /* Select CRF6 */
t = inb_p(WDT_EFDR); /* read CRF6 */
@@ -137,13 +142,15 @@ static void w83697ug_init(void)
outb_p(t, WDT_EFDR); /* Write back to CRF5 */
w83697ug_unselect_wd_register();
+ return 0;
}
static void wdt_ctrl(int timeout)
{
spin_lock(&io_lock);
- w83697ug_select_wd_register();
+ if (w83697ug_select_wd_register() < 0)
+ return;
outb_p(0xF4, WDT_EFER); /* Select CRF4 */
outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */
@@ -347,7 +354,9 @@ static int __init wdt_init(void)
goto out;
}
- w83697ug_init();
+ ret = w83697ug_init();
+ if (ret != 0)
+ goto unreg_regions;
ret = register_reboot_notifier(&wdt_notifier);
if (ret != 0) {
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c
index 2525da5080c..0560182a1d0 100644
--- a/drivers/watchdog/w83977f_wdt.c
+++ b/drivers/watchdog/w83977f_wdt.c
@@ -426,7 +426,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -EFAULT;
if (wdt_set_timeout(new_timeout))
- return -EINVAL;
+ return -EINVAL;
wdt_keepalive();
/* Fall */
diff --git a/drivers/watchdog/wd501p.h b/drivers/watchdog/wd501p.h
index db34853c28a..0e3a497d562 100644
--- a/drivers/watchdog/wd501p.h
+++ b/drivers/watchdog/wd501p.h
@@ -11,9 +11,9 @@
*
* http://www.cymru.net
*
- * This driver is provided under the GNU General Public License, incorporated
- * herein by reference. The driver is provided without warranty or
- * support.
+ * This driver is provided under the GNU General Public License,
+ * incorporated herein by reference. The driver is provided without
+ * warranty or support.
*
* Release 0.04.
*
@@ -39,13 +39,13 @@
/* programmable outputs: */
#define WDT_PROGOUT (io+15) /* wr=enable, rd=disable */
- /* FAN 501 500 */
-#define WDC_SR_WCCR 1 /* Active low */ /* X X X */
-#define WDC_SR_TGOOD 2 /* X X - */
-#define WDC_SR_ISOI0 4 /* X X X */
-#define WDC_SR_ISII1 8 /* X X X */
-#define WDC_SR_FANGOOD 16 /* X - - */
-#define WDC_SR_PSUOVER 32 /* Active low */ /* X X - */
-#define WDC_SR_PSUUNDR 64 /* Active low */ /* X X - */
-#define WDC_SR_IRQ 128 /* Active low */ /* X X X */
+ /* FAN 501 500 */
+#define WDC_SR_WCCR 1 /* Active low */ /* X X X */
+#define WDC_SR_TGOOD 2 /* X X - */
+#define WDC_SR_ISOI0 4 /* X X X */
+#define WDC_SR_ISII1 8 /* X X X */
+#define WDC_SR_FANGOOD 16 /* X - - */
+#define WDC_SR_PSUOVER 32 /* Active low */ /* X X - */
+#define WDC_SR_PSUUNDR 64 /* Active low */ /* X X - */
+#define WDC_SR_IRQ 128 /* Active low */ /* X X X */
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c
index eddb9187e7b..3bbefe9a263 100644
--- a/drivers/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
@@ -1,5 +1,5 @@
/*
- * Industrial Computer Source WDT500/501 driver
+ * Industrial Computer Source WDT501 driver
*
* (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
* All Rights Reserved.
@@ -82,14 +82,16 @@ MODULE_PARM_DESC(io, "WDT io port (default=0x240)");
module_param(irq, int, 0);
MODULE_PARM_DESC(irq, "WDT irq (default=11)");
-#ifdef CONFIG_WDT_501
/* Support for the Fan Tachometer on the WDT501-P */
static int tachometer;
-
module_param(tachometer, int, 0);
MODULE_PARM_DESC(tachometer,
"WDT501-P Fan Tachometer support (0=disable, default=0)");
-#endif /* CONFIG_WDT_501 */
+
+static int type = 500;
+module_param(type, int, 0);
+MODULE_PARM_DESC(type,
+ "WDT501-P Card type (500 or 501 , default=500)");
/*
* Programming support
@@ -158,7 +160,7 @@ static int wdt_stop(void)
* reloading the cascade counter.
*/
-static int wdt_ping(void)
+static void wdt_ping(void)
{
unsigned long flags;
spin_lock_irqsave(&wdt_lock, flags);
@@ -169,7 +171,6 @@ static int wdt_ping(void)
wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */
outb_p(0, WDT_DC); /* Enable watchdog */
spin_unlock_irqrestore(&wdt_lock, flags);
- return 0;
}
/**
@@ -193,7 +194,6 @@ static int wdt_set_heartbeat(int t)
/**
* wdt_get_status:
- * @status: the new status.
*
* Extract the status information from a WDT watchdog device. There are
* several board variants so we have to know which bits are valid. Some
@@ -202,36 +202,35 @@ static int wdt_set_heartbeat(int t)
* we then map the bits onto the status ioctl flags.
*/
-static int wdt_get_status(int *status)
+static int wdt_get_status(void)
{
unsigned char new_status;
+ int status = 0;
unsigned long flags;
spin_lock_irqsave(&wdt_lock, flags);
new_status = inb_p(WDT_SR);
spin_unlock_irqrestore(&wdt_lock, flags);
- *status = 0;
if (new_status & WDC_SR_ISOI0)
- *status |= WDIOF_EXTERN1;
+ status |= WDIOF_EXTERN1;
if (new_status & WDC_SR_ISII1)
- *status |= WDIOF_EXTERN2;
-#ifdef CONFIG_WDT_501
- if (!(new_status & WDC_SR_TGOOD))
- *status |= WDIOF_OVERHEAT;
- if (!(new_status & WDC_SR_PSUOVER))
- *status |= WDIOF_POWEROVER;
- if (!(new_status & WDC_SR_PSUUNDR))
- *status |= WDIOF_POWERUNDER;
- if (tachometer) {
- if (!(new_status & WDC_SR_FANGOOD))
- *status |= WDIOF_FANFAULT;
+ status |= WDIOF_EXTERN2;
+ if (type == 501) {
+ if (!(new_status & WDC_SR_TGOOD))
+ status |= WDIOF_OVERHEAT;
+ if (!(new_status & WDC_SR_PSUOVER))
+ status |= WDIOF_POWEROVER;
+ if (!(new_status & WDC_SR_PSUUNDR))
+ status |= WDIOF_POWERUNDER;
+ if (tachometer) {
+ if (!(new_status & WDC_SR_FANGOOD))
+ status |= WDIOF_FANFAULT;
+ }
}
-#endif /* CONFIG_WDT_501 */
- return 0;
+ return status;
}
-#ifdef CONFIG_WDT_501
/**
* wdt_get_temperature:
*
@@ -239,7 +238,7 @@ static int wdt_get_status(int *status)
* farenheit. It was designed by an imperial measurement luddite.
*/
-static int wdt_get_temperature(int *temperature)
+static int wdt_get_temperature(void)
{
unsigned short c;
unsigned long flags;
@@ -247,10 +246,18 @@ static int wdt_get_temperature(int *temperature)
spin_lock_irqsave(&wdt_lock, flags);
c = inb_p(WDT_RT);
spin_unlock_irqrestore(&wdt_lock, flags);
- *temperature = (c * 11 / 15) + 7;
- return 0;
+ return (c * 11 / 15) + 7;
+}
+
+static void wdt_decode_501(int status)
+{
+ if (!(status & WDC_SR_TGOOD))
+ printk(KERN_CRIT "Overheat alarm.(%d)\n", inb_p(WDT_RT));
+ if (!(status & WDC_SR_PSUOVER))
+ printk(KERN_CRIT "PSU over voltage.\n");
+ if (!(status & WDC_SR_PSUUNDR))
+ printk(KERN_CRIT "PSU under voltage.\n");
}
-#endif /* CONFIG_WDT_501 */
/**
* wdt_interrupt:
@@ -275,18 +282,13 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id)
printk(KERN_CRIT "WDT status %d\n", status);
-#ifdef CONFIG_WDT_501
- if (!(status & WDC_SR_TGOOD))
- printk(KERN_CRIT "Overheat alarm.(%d)\n", inb_p(WDT_RT));
- if (!(status & WDC_SR_PSUOVER))
- printk(KERN_CRIT "PSU over voltage.\n");
- if (!(status & WDC_SR_PSUUNDR))
- printk(KERN_CRIT "PSU under voltage.\n");
- if (tachometer) {
- if (!(status & WDC_SR_FANGOOD))
- printk(KERN_CRIT "Possible fan fault.\n");
+ if (type == 501) {
+ wdt_decode_501(status);
+ if (tachometer) {
+ if (!(status & WDC_SR_FANGOOD))
+ printk(KERN_CRIT "Possible fan fault.\n");
+ }
}
-#endif /* CONFIG_WDT_501 */
if (!(status & WDC_SR_WCCR)) {
#ifdef SOFTWARE_REBOOT
#ifdef ONLY_TESTING
@@ -366,17 +368,18 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
/* Add options according to the card we have */
ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2);
-#ifdef CONFIG_WDT_501
- ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER);
- if (tachometer)
- ident.options |= WDIOF_FANFAULT;
-#endif /* CONFIG_WDT_501 */
+ if (type == 501) {
+ ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|
+ WDIOF_POWEROVER);
+ if (tachometer)
+ ident.options |= WDIOF_FANFAULT;
+ }
switch (cmd) {
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
- wdt_get_status(&status);
+ status = wdt_get_status();
return put_user(status, p);
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
@@ -446,7 +449,6 @@ static int wdt_release(struct inode *inode, struct file *file)
return 0;
}
-#ifdef CONFIG_WDT_501
/**
* wdt_temp_read:
* @file: file handle to the watchdog board
@@ -461,10 +463,7 @@ static int wdt_release(struct inode *inode, struct file *file)
static ssize_t wdt_temp_read(struct file *file, char __user *buf,
size_t count, loff_t *ptr)
{
- int temperature;
-
- if (wdt_get_temperature(&temperature))
- return -EFAULT;
+ int temperature = wdt_get_temperature();
if (copy_to_user(buf, &temperature, 1))
return -EFAULT;
@@ -497,7 +496,6 @@ static int wdt_temp_release(struct inode *inode, struct file *file)
{
return 0;
}
-#endif /* CONFIG_WDT_501 */
/**
* notify_sys:
@@ -539,7 +537,6 @@ static struct miscdevice wdt_miscdev = {
.fops = &wdt_fops,
};
-#ifdef CONFIG_WDT_501
static const struct file_operations wdt_temp_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -553,7 +550,6 @@ static struct miscdevice temp_miscdev = {
.name = "temperature",
.fops = &wdt_temp_fops,
};
-#endif /* CONFIG_WDT_501 */
/*
* The WDT card needs to learn about soft shutdowns in order to
@@ -577,9 +573,8 @@ static struct notifier_block wdt_notifier = {
static void __exit wdt_exit(void)
{
misc_deregister(&wdt_miscdev);
-#ifdef CONFIG_WDT_501
- misc_deregister(&temp_miscdev);
-#endif /* CONFIG_WDT_501 */
+ if (type == 501)
+ misc_deregister(&temp_miscdev);
unregister_reboot_notifier(&wdt_notifier);
free_irq(irq, NULL);
release_region(io, 8);
@@ -597,12 +592,17 @@ static int __init wdt_init(void)
{
int ret;
+ if (type != 500 && type != 501) {
+ printk(KERN_ERR "wdt: unknown card type '%d'.\n", type);
+ return -ENODEV;
+ }
+
/* Check that the heartbeat value is within it's range;
if not reset to the default */
if (wdt_set_heartbeat(heartbeat)) {
wdt_set_heartbeat(WD_TIMO);
- printk(KERN_INFO "wdt: heartbeat value must be 0 < heartbeat < 65536, using %d\n",
- WD_TIMO);
+ printk(KERN_INFO "wdt: heartbeat value must be "
+ "0 < heartbeat < 65536, using %d\n", WD_TIMO);
}
if (!request_region(io, 8, "wdt501p")) {
@@ -625,15 +625,14 @@ static int __init wdt_init(void)
goto outirq;
}
-#ifdef CONFIG_WDT_501
- ret = misc_register(&temp_miscdev);
- if (ret) {
- printk(KERN_ERR
- "wdt: cannot register miscdev on minor=%d (err=%d)\n",
- TEMP_MINOR, ret);
- goto outrbt;
+ if (type == 501) {
+ ret = misc_register(&temp_miscdev);
+ if (ret) {
+ printk(KERN_ERR "wdt: cannot register miscdev "
+ "on minor=%d (err=%d)\n", TEMP_MINOR, ret);
+ goto outrbt;
+ }
}
-#endif /* CONFIG_WDT_501 */
ret = misc_register(&wdt_miscdev);
if (ret) {
@@ -643,28 +642,25 @@ static int __init wdt_init(void)
goto outmisc;
}
- ret = 0;
- printk(KERN_INFO "WDT500/501-P driver 0.10 at 0x%04x (Interrupt %d). heartbeat=%d sec (nowayout=%d)\n",
+ printk(KERN_INFO "WDT500/501-P driver 0.10 "
+ "at 0x%04x (Interrupt %d). heartbeat=%d sec (nowayout=%d)\n",
io, irq, heartbeat, nowayout);
-#ifdef CONFIG_WDT_501
- printk(KERN_INFO "wdt: Fan Tachometer is %s\n",
+ if (type == 501)
+ printk(KERN_INFO "wdt: Fan Tachometer is %s\n",
(tachometer ? "Enabled" : "Disabled"));
-#endif /* CONFIG_WDT_501 */
-
-out:
- return ret;
+ return 0;
outmisc:
-#ifdef CONFIG_WDT_501
- misc_deregister(&temp_miscdev);
+ if (type == 501)
+ misc_deregister(&temp_miscdev);
outrbt:
-#endif /* CONFIG_WDT_501 */
unregister_reboot_notifier(&wdt_notifier);
outirq:
free_irq(irq, NULL);
outreg:
release_region(io, 8);
- goto out;
+out:
+ return ret;
}
module_init(wdt_init);
diff --git a/drivers/watchdog/wdt977.c b/drivers/watchdog/wdt977.c
index 60e28d49ff5..90ef70eb47d 100644
--- a/drivers/watchdog/wdt977.c
+++ b/drivers/watchdog/wdt977.c
@@ -401,7 +401,7 @@ static long wdt977_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
if (wdt977_set_timeout(new_timeout))
- return -EINVAL;
+ return -EINVAL;
wdt977_keepalive();
/* Fall */
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 8dc7109d61b..efa4b363ce7 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -298,6 +298,14 @@ static int decrease_reservation(unsigned long nr_pages)
frame_list[i] = pfn_to_mfn(pfn);
scrub_page(page);
+
+ if (!PageHighMem(page)) {
+ ret = HYPERVISOR_update_va_mapping(
+ (unsigned long)__va(pfn << PAGE_SHIFT),
+ __pte_ma(0), 0);
+ BUG_ON(ret);
+ }
+
}
/* Ensure that ballooned highmem pages don't have kmaps. */
@@ -490,7 +498,7 @@ static ssize_t store_target_kb(struct sys_device *dev,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- target_bytes = memparse(buf, &endchar);
+ target_bytes = simple_strtoull(buf, &endchar, 0) * 1024;
balloon_set_new_target(target_bytes >> PAGE_SHIFT);
@@ -500,8 +508,39 @@ static ssize_t store_target_kb(struct sys_device *dev,
static SYSDEV_ATTR(target_kb, S_IRUGO | S_IWUSR,
show_target_kb, store_target_kb);
+
+static ssize_t show_target(struct sys_device *dev, struct sysdev_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%llu\n",
+ (u64)balloon_stats.target_pages << PAGE_SHIFT);
+}
+
+static ssize_t store_target(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ char *endchar;
+ unsigned long long target_bytes;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ target_bytes = memparse(buf, &endchar);
+
+ balloon_set_new_target(target_bytes >> PAGE_SHIFT);
+
+ return count;
+}
+
+static SYSDEV_ATTR(target, S_IRUGO | S_IWUSR,
+ show_target, store_target);
+
+
static struct sysdev_attribute *balloon_attrs[] = {
&attr_target_kb,
+ &attr_target,
};
static struct attribute *balloon_info_attrs[] = {
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 9b91617b958..56892a142ee 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -45,6 +45,13 @@ static int xen_suspend(void *data)
err);
return err;
}
+ err = sysdev_suspend(PMSG_SUSPEND);
+ if (err) {
+ printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
+ err);
+ device_power_up(PMSG_RESUME);
+ return err;
+ }
xen_mm_pin_all();
gnttab_suspend();
@@ -61,6 +68,7 @@ static int xen_suspend(void *data)
gnttab_resume();
xen_mm_unpin_all();
+ sysdev_resume();
device_power_up(PMSG_RESUME);
if (!*cancelled) {
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c
index 875a4c59c59..a9592d981b1 100644
--- a/drivers/xen/xenfs/xenbus.c
+++ b/drivers/xen/xenfs/xenbus.c
@@ -291,7 +291,7 @@ static void watch_fired(struct xenbus_watch *watch,
static int xenbus_write_transaction(unsigned msg_type,
struct xenbus_file_priv *u)
{
- int rc, ret;
+ int rc;
void *reply;
struct xenbus_transaction_holder *trans = NULL;
LIST_HEAD(staging_q);
@@ -326,15 +326,14 @@ static int xenbus_write_transaction(unsigned msg_type,
}
mutex_lock(&u->reply_mutex);
- ret = queue_reply(&staging_q, &u->u.msg, sizeof(u->u.msg));
- if (!ret)
- ret = queue_reply(&staging_q, reply, u->u.msg.len);
- if (!ret) {
+ rc = queue_reply(&staging_q, &u->u.msg, sizeof(u->u.msg));
+ if (!rc)
+ rc = queue_reply(&staging_q, reply, u->u.msg.len);
+ if (!rc) {
list_splice_tail(&staging_q, &u->read_buffers);
wake_up(&u->read_waitq);
} else {
queue_cleanup(&staging_q);
- rc = ret;
}
mutex_unlock(&u->reply_mutex);
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index a1585d6f648..d45fb34e2d2 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -140,7 +140,7 @@ static int __init zorro_init(void)
/* Initialize the Zorro bus */
INIT_LIST_HEAD(&zorro_bus.devices);
- strcpy(zorro_bus.dev.bus_id, "zorro");
+ dev_set_name(&zorro_bus.dev, "zorro");
error = device_register(&zorro_bus.dev);
if (error) {
pr_err("Zorro: Error registering zorro_bus\n");
@@ -167,7 +167,7 @@ static int __init zorro_init(void)
if (request_resource(zorro_find_parent_resource(z), &z->resource))
pr_err("Zorro: Address space collision on device %s %pR\n",
z->name, &z->resource);
- sprintf(z->dev.bus_id, "%02x", i);
+ dev_set_name(&z->dev, "%02x", i);
z->dev.parent = &zorro_bus.dev;
z->dev.bus = &zorro_bus_type;
error = device_register(&z->dev);